diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 00000000000..816d95814b3 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,3 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +remote_config: + url: "http://open.zstack.ai:20001/code-reviews/zstack-cloud.yaml" diff --git a/.gitconfig/hooks/commit-msg b/.gitconfig/hooks/commit-msg index 4269b1b8398..26e2a97ba80 100755 --- a/.gitconfig/hooks/commit-msg +++ b/.gitconfig/hooks/commit-msg @@ -41,6 +41,15 @@ class bcolors: WARNS = 0 REPO_NAME ="" + +# default open function(python3) +open = open +# using python2 codecs.open func if python version is 2 +if sys.version_info.major == 2: + import codecs + open = codecs.open + + def main(): try: if not check_commit_msg_enabled(): @@ -61,7 +70,7 @@ def backup_and_exit(file_path): lines = [] useful = ["\n\n"] - with open(file_path, 'r') as f: + with open(file_path, 'r', encoding='utf8') as f: lines = f.readlines() for l in lines: if l.startswith("# Please enter the commit") or \ @@ -87,7 +96,7 @@ def fix_commit_msg(file_path): # see: https://superuser.com/questions/1367811/sometimes-git-includes-the-diff-to-commit-message-when-using-verbose fixed_commit_msg = [] - with open(file_path, 'r') as f: + with open(file_path, 'r', encoding='utf8') as f: lines = f.readlines() for no, line in enumerate(lines): if "# Everything below it will be ignored." in line.strip() or \ @@ -96,7 +105,7 @@ def fix_commit_msg(file_path): break if len(fixed_commit_msg) == 0: return - with open(file_path, 'w') as f: + with open(file_path, 'w', encoding='utf8') as f: f.writelines(fixed_commit_msg) @@ -123,8 +132,8 @@ def check_commit_msg(file_path): FAIL = False jira_patterns = [r"\bZSTAC-\d+\b", r"\bZSTACK-\d+\b", r"\bMINI-\d+\b", - r"\bZOPS-\d+\b", r"\bZHCI-\d+\b"] - with open(file_path, 'r') as f: + r"\bZOPS-\d+\b", r"\bZHCI-\d+\b", r"\bZSV-\d+\b"] + with open(file_path, 'r', encoding='utf8') as f: lines = f.readlines() full_lines = len(lines) @@ -135,7 +144,7 @@ def check_commit_msg(file_path): header_contains_nonsense = True if "revert" in lines[0].lower(): revert_commit = True - if "merge branch" in lines[0].lower(): + if "merge branch" in lines[0].lower() or "merge remote" in lines[0].lower(): merge_commit = True if full_lines > 1 and "" == lines[1].strip(): second_line_is_blank = True @@ -265,4 +274,4 @@ if __name__ == "__main__": #} # #grep '' $1 && echo "\033[33mdescription in commit msg header not filed!" -#grep -E 'ZSTAC-' \ No newline at end of file +#grep -E 'ZSTAC-' diff --git a/.gitconfig/hooks/prepare-commit-msg b/.gitconfig/hooks/prepare-commit-msg index 3e30f755051..28656de1be6 100755 --- a/.gitconfig/hooks/prepare-commit-msg +++ b/.gitconfig/hooks/prepare-commit-msg @@ -31,6 +31,13 @@ import traceback from collections import Counter +# default open function(python3) +open = open +# using python2 codecs.open func if python version is 2 +if sys.version_info.major == 2: + import codecs + open = codecs.open + def main(): try: if not auto_commit_msg_enabled(): @@ -73,7 +80,7 @@ def write_commit_msg(commit_msg_filepath, type, scope, tags, jiras): # 3. Are there any side effects?\n ''' - with open(commit_msg_filepath, 'r+') as msg: + with open(commit_msg_filepath, 'r+', encoding='utf8') as msg: in_usable_content = False useable_contents = [] for line in msg.readlines(): @@ -102,7 +109,7 @@ def write_commit_msg(commit_msg_filepath, type, scope, tags, jiras): real_commit_msg.append("\nChange-Id: %s\n" % get_change_id()) - with open(commit_msg_filepath, 'w') as msg: + with open(commit_msg_filepath, 'w', encoding='utf8') as msg: real_commit_msg.extend(useable_contents) msg.writelines(real_commit_msg) @@ -118,7 +125,7 @@ def process_metadata(commit_msg_filepath): changed_folders = [] changed_paths = {} - with open(commit_msg_filepath, 'r+') as msg: + with open(commit_msg_filepath, 'r+', encoding='utf8') as msg: content = msg.readlines() for no, line in enumerate(content): line = line.strip() @@ -222,6 +229,10 @@ def get_scope(changed_folders, changed_paths): break if not found_magic: scopes.append("conf") + elif "pom.xml" in p: + # eg. header/pom.xml + # eg. pom.xml + scopes.append("dependencies") scope_counter = Counter(scopes) most_common = scope_counter.most_common(1)[0][0] @@ -275,7 +286,7 @@ def get_tags(changed_folders, changed_paths): def get_jiras(): jiras = [] jira_patterns = [r"\bZSTAC-\d+\b", r"\bZSTACK-\d+\b", r"\bMINI-\d+\b", - r"\bZOPS-\d+\b", r"\bZHCI-\d+\b"] + r"\bZOPS-\d+\b", r"\bZHCI-\d+\b", r"\bZSV-\d+\b"] bashCommand = "git rev-parse --abbrev-ref HEAD" process = subprocess.Popen(bashCommand.split(), stdout=subprocess.PIPE) diff --git a/.gitignore b/.gitignore index 5072f02b6a5..641f731fe03 100755 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ test-premium/zstack-integration-test-result/ envDSLTree test/zstack-integration-test-result/ premium/test-premium/zstack-api.log +**/bin/ diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 214cca6aae5..eeaaefdfb48 100755 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,9 +1,90 @@ -#Authors ordered by first contribution. +#Authors ordered by name. # # Names should be added to this file like: # Name -Frank Zhang -Yongkang You -Matt Yen -Nan Su +AlanJager ye.zou@zstack.io +anquan.wu anquan.wu@zstack.io +baijiewen 15364719037@163.com +boce.wang boce.wang@zstack.io +Chu Kun luchukun@sjtu.edu.cn +Cui,xingxing xingxing.cui@zstack.io +David Lee live4thee@gmail.com +dengsong.yang dengsong.yang@zstack.io +FuBang bang.fu@zstack.io +fuwei fuwei@sugon.com +fuyi fuyi@sugon.com +gantao tao.gan@zstack.io +Guo Yi yi.guo@zstack.io +haibiao.xiao haibiao.xiao@zstack.io +hanyu.liang hanyu.liang@zstack.io +jialong.dong jialong.dong@zstack.io +JianAZhang jianzhang_pro@foxmail.com +Jianfeng Wu jianfeng.wu@zstack.io +jianzhang jianzhang@zstack.io +jingjing.zhou jingjing.zhou@zstack.io +jin.ma jin.ma@zstack.io +jintao.chen jintao.chen@zstack.io +junfei.wang junfei.wang@zstack.io +kaicai.hu kaicai.hu@zstack.io +kefeng.wang kefeng.wang@zstack.io +Lei Liu lei.liu@zstack.io +le.jin le.jin@zstack.io +liangbo.zhou liangbo.zhou@zstack.io +lianghy hanyu.liang@zstack.io +lining 2313806311@qq.com +lining yaoning.li@zstack.io +lin.ma lin.ma@zstack.io +li.wang li.wang@zstack.io +mahaibin haibin_ma@qq.com +Mei Lei meilei007@gmail.com +miao.DengSheng xuexuemiao@yeah.net +mingjian.deng mingjian.deng@zstack.io +mingmin.wen mingmin.wen@zstack.io +Ning,GuoHui guohui.ning@zstack.io +pengchao.liu pengchao.liu@zstack.io +pengchao.zhang pengchao.zhang@zstack.io +Qi Le qi.le@zstack.io +Qilin.Wang qilin.wang@zstack.io +QiRaining 804470533@qq.com +qiuyu.zhang qiuyu.zhang@zstack.io +Rickylss xiaohaibiao331@outlook.com +Ruan Shixin shixin.ruan@zstack.io +shanshan.ning shanshan.ning@zstack.io +shan.wu shan.wu@zstack.io +Shaohui Liu liushaohui@xiaomi.com +shengyan.zhao shengyan.zhao@zstack.io +shenjin jin.shen@zstack.io +ShiXiao, Chen shixiao.chen@zstack.io +Shixin Ruan shixin.ruan@zstack.io +shuang.he shuang.he@zstack.io +siying.huang siying.huang@zstack.io +sulin.sheng sulin.sheng@zstack.io +Sun, Yu yu.sun@zstack.io +tao.gan tao.gan@zstack.io +tao.yang tao.yang@zstack.io +Tao Yang tao.yang@zstack.io +tianyang tianyang@fusionstack.com +ting.su ting.su@zstack.io +wangjie jie.wang@zstack.io +Wang Jing jing.wang@zstack.io +Wang,Qilin qilin.wang@zstack.io +Wei Wang wei.wang@zstack.io +Wenhao, Zhang wenhao.zhang@zstack.io +Wen, Yubo yubo.wen@zstack.io +Xingwei Yu xingwei.yu@zstack.io +xingxing.cui xingxing.cui@zstack.io +xinhao.huang xinhao.huang@zstack.io +yang.yu yang.yu@zstack.io +yaohua.wu pandawuu@163.com +ye.tian ye.tian@zstack.io +yingzhe.hu yingzhe.hu@zstack.io +zaifeng.wang zaifeng.wang@zstack.io +zhangjf zhangjunfeng@huayunwangji.com +zhangjianjun jianjun.zhang@zstack.io +zhangjunfeng zhangjunfeng@huayunwangji.com +Zhang Wenhao wenhao.zhang@zstack.io +zhanyong.miao zhanyong.miao@zstack.io +Zhou Jingjing jingjing.zhou@zstack.io +zhutianhao zhutianhao75@hotmail.com +zxwing xing5820@gmail.com diff --git a/PJNUM b/PJNUM new file mode 100644 index 00000000000..828582c78b1 --- /dev/null +++ b/PJNUM @@ -0,0 +1 @@ +PJNUM=001 \ No newline at end of file diff --git a/README.md b/README.md index 83e9e93a60d..dd0510d77f0 100755 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ZStack: the IaaS software you have been looking for. [http://zstack.org](http://zstack.org) +# ZStack: the IaaS software you have been looking for. [https://zstack.org](https://zstack.org) ZStack is open source IaaS(infrastructure as a service) software aiming to automate datacenters, managing resources of compute, storage, and networking all by APIs. Users can setup ZStack environments in a download-and-run manner, spending 5 minutes building a POC environment @@ -88,7 +88,10 @@ Installation and upgrade are as simple as deploying a **Java WAR file**. A POC e a bootstrap script; A multi-node production environment can be deployed in **30 minutes** including the time you read the documentation. - >> [root@localhost ~]# curl http://download.zstack.org/install.sh | bash -s -- -a +Quick access: + +* [Product download page(CN)](https://www.zstack.io/product/product_downloads/) +* [Product download page(EN)](https://www.zstack-cloud.com/product/product_downloads/) #### Full automation @@ -110,53 +113,53 @@ that adding or removing features will not impact the core orchestration, promisi Installation of ZStack is super easy; users can choose different methods depending on their needs to install the first ZStack environment: -* For users wanting to try out quickly, see [Quick Installation](http://en.zstack.io/installation/index.html). +* For users wanting to try out quickly, see [Quick Installation](https://www.zstack-cloud.com/help/en/tutorials/quick_install_guide/v4/). -* For users wanting to deploy a production environment, see [Manual Installation](http://en.zstack.io/installation/manual.html). +* For users wanting to deploy a production environment, see [Manual Installation](https://zstack.org/installation/manual.html). -* For users wanting to deploy a multi-node environment, see [Multi-node Installation](http://en.zstack.io/installation/multi-node.html). +* For users wanting to deploy a multi-node environment, see [Multi-node Installation](https://www.zstack-cloud.com/help/en/tutorials/double_mn_ha_solution/v4/). Once the installation is done, users can follow one of getting started guides: -* [Getting Started With Quick Installation](http://en.zstack.io/documentation/getstart-quick.html). +* [Getting Started With Quick Installation](https://www.zstack-cloud.com/help/en/tutorials/quick_install_guide/v4/3.html). -* [Getting Started With Manual Installation](http://en.zstack.io/documentation/getstart-manual.html). +* [Getting Started With Manual Installation](https://zstack.org/documentation/getstart-manual.html). -* [Getting Started With Multi-node Installation](http://en.zstack.io/documentation/getstart-multi.html). +* [Getting Started With Multi-node Installation](https://www.zstack-cloud.com/help/en/tutorials/double_mn_ha_solution/v4/2.html). ## Tutorials Six tutorials are prepared for your first journey in ZStack, building classic cloud deployments all on one single Linux machine: -##### Amazon EC2 classic EIP zone: +##### Elastic IP: -* [Web UI](http://en.zstack.io/tutorials/ec2-ui.html) -* [Command Line Tool](http://en.zstack.io/tutorials/ec2-cli.html) +* [Web UI](https://www.zstack-cloud.com/help/en/tutorials/vpc_tutorial/v4/3.html#chapter-3-7-Elastic-IP) +* [Command Line Tool](https://zstack.org/tutorials/ec2-cli.html) ##### Flat Network: -* [Web UI](http://en.zstack.io/tutorials/flat-network-ui.html) -* [Command Line Tool](http://en.zstack.io/tutorials/flat-network-cli.html) +* [Web UI](https://www.zstack-cloud.com/help/en/tutorials/flat_tutorial/v4/) +* [Command Line Tool](https://zstack.org/tutorials/flat-network-cli.html) ##### Three Tiered Network: -* [Web UI](http://en.zstack.io/tutorials/three-tiered-ui.html) -* [Command Line Tool](http://en.zstack.io/tutorials/three-tiered-cli.html) +* [Web UI](https://zstack.org/tutorials/three-tiered-ui.html) +* [Command Line Tool](https://zstack.org/tutorials/three-tiered-cli.html) ##### Security Group: -* [Web UI](http://en.zstack.io/tutorials/security-group-ui.html) -* [Command Line Tool](http://en.zstack.io/tutorials/security-group-cli.html) +* [Web UI](https://www.zstack-cloud.com/help/en/tutorials/vpc_tutorial/v4/3.html#chapter-3-6-Security-Group) +* [Command Line Tool](https://zstack.org/tutorials/security-group-cli.html) -##### Elastic Port Forwarding: +##### Port Forwarding: -* [Web UI](http://en.zstack.io/tutorials/elastic-port-forwarding-ui.html) -* [Command Line Tool](http://en.zstack.io/tutorials/elastic-port-forwarding-cli.html) +* [Web UI](https://www.zstack-cloud.com/help/en/tutorials/vpc_tutorial/v4/3.html#chapter-3-8-Port-Forwarding) +* [Command Line Tool](https://zstack.org/tutorials/elastic-port-forwarding-cli.html) ##### Snapshots: -* [Web UI](http://en.zstack.io/tutorials/snapshot-ui.html) -* [Command Line Tool](http://en.zstack.io/tutorials/snapshot-cli.html) +* [Web UI](https://www-zstack-io.translate.goog/help/tutorials/volume_snapshot_tutorial/v4/1.html?_x_tr_sl=zh-CN&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp) +* [Command Line Tool](https://zstack.org/tutorials/snapshot-cli.html) ## Under the hood @@ -164,54 +167,58 @@ Under the hood, ZStack is built on an architecture explained by following articl ##### Scalability: -[ZStack's Scalability Secrets Part 1: Asynchronous Architecture](http://en.zstack.io/blog/asynchronous-architecture.html) +[ZStack's Scalability Secrets Part 1: Asynchronous Architecture](https://zstack.org/blog/asynchronous-architecture.html) -[ZStack's Scalability Secrets Part 2: Stateless Services](http://en.zstack.io/blog/stateless-clustering.html) +[ZStack's Scalability Secrets Part 2: Stateless Services](https://zstack.org/blog/stateless-clustering.html) -[ZStack's Scalability Secrets Part 3: Lock-free Architecture](http://en.zstack.io/blog/lock-free.html) +[ZStack's Scalability Secrets Part 3: Lock-free Architecture](https://zstack.org/blog/lock-free.html) ##### Plugin Architecture: -[The In-Process Microservices Architecture](http://en.zstack.io/blog/microservices.html) +[The In-Process Microservices Architecture](https://zstack.org/blog/microservices.html) -[The Versatile Plugin System](http://en.zstack.io/blog/plugin.html) +[The Versatile Plugin System](https://zstack.org/blog/plugin.html) -[The Tag System](http://en.zstack.io/blog/tag.html) +[The Tag System](https://zstack.org/blog/tag.html) -[The Workflow Engine](http://en.zstack.io/blog/workflow.html) +[The Workflow Engine](https://zstack.org/blog/workflow.html) -[The Cascade Framework](http://en.zstack.io/blog/cascade.html) +[The Cascade Framework](https://zstack.org/blog/cascade.html) ##### Query API: -[The Query API](http://en.zstack.io/blog/query.html) +[The Query API](https://zstack.org/blog/query.html) ##### Automation: -[Full Automation By Ansible](http://en.zstack.io/blog/ansible.html) +[Full Automation By Ansible](https://zstack.org/blog/ansible.html) ##### Storage And Network: -[Networking Model 1: L2 and L3 Network](http://en.zstack.io/blog/network-l2.html) +[Networking Model 1: L2 and L3 Network](https://zstack.org/blog/network-l2.html) -[Networking Model 2: Virtual Router Network Service Provider](http://en.zstack.io/blog/virtual-router.html) +[Networking Model 2: Virtual Router Network Service Provider](https://zstack.org/blog/virtual-router.html) -[Storage Model: Primary Storage and Backup Storage](http://en.zstack.io/blog/storage.html) +[Storage Model: Primary Storage and Backup Storage](https://zstack.org/blog/storage.html) ##### Testing: -[The Automation Testing System 1: Integration Testing](http://en.zstack.io/blog/integration-testing.html) +[The Automation Testing System 1: Integration Testing](https://zstack.org/blog/integration-testing.html) + +[The Automation Testing System 2: System Testing](https://zstack.org/blog/system-testing.html) + +[The Automation Testing System 3: Model-based Testing](https://zstack.org/blog/model-based-testing.html) -[The Automation Testing System 2: System Testing](http://en.zstack.io/blog/system-testing.html) +## More Documentation Resources -[The Automation Testing System 3: Model-based Testing](http://en.zstack.io/blog/model-based-testing.html) +[ZStack documentation](https://www.zstack-cloud.com/help/en/product_manuals/index.html) ## License 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 +https://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. diff --git a/README.zh-CN.md b/README.zh-CN.md index fab094389f7..1559431bad6 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -87,91 +87,57 @@ ZStack采用与OSGi和Eclipse类似的插件系统方式作为核心架构基础 ZStack提供**3套全自动化的严密测试系统**,确保每个功能的代码质量。 -## 安装 +## 安装和使用 安装ZStack极为便捷。用户可按需选择不同的安装模式安装首套ZStack环境。 -* 如需快速尝试,请参阅[快速安装手册](http://en.zstack.io/installation/index.html)。 -* 如需部署生产环境,请参阅[手动安装手册](http://en.zstack.io/installation/manual.html)。 -* 如需部署多管理节点环境,请参阅[多管理节点安装手册](http://en.zstack.io/installation/multi-node.html)。 +* 如需快速尝试,请参阅[快速安装手册](https://www.zstack.io/help/tutorials/quick_install_guide/v5/)。 +* 如需部署生产环境,请参阅[手动安装手册](https://www.zstack.io/help/product_manuals/user_guide/v5/)。 +* 如需部署多管理节点环境,请参阅[多管理节点安装手册](https://www.zstack.io/help/tutorials/double_mn_ha_solution/v5/)。 -安装完成之后,可参考以下手册快速使用云平台: - -* [快速使用云平台(快速安装)](http://en.zstack.io/documentation/getstart-quick.html) -* [快速使用云平台(手动安装)](http://en.zstack.io/documentation/getstart-manual.html) -* [快速使用云平台(多管理节点安装)](http://en.zstack.io/documentation/getstart-multi.html) - -## 教程 - -对于首次使用All in One方式在单台Linux机器上搭建使用ZStack云平台的用户,ZStack提供以下6本教程可供参阅: - -#### Amazon EC2经典弹性IP域: - -* [UI界面](http://en.zstack.io/tutorials/ec2-ui.html) -* [命令行工具](http://en.zstack.io/tutorials/ec2-cli.html) - -#### 扁平网络: - -* [UI界面](http://en.zstack.io/tutorials/flat-network-ui.html) -* [命令行工具](http://en.zstack.io/tutorials/flat-network-cli.html) - -#### 三层网络: - -* [UI界面](http://en.zstack.io/tutorials/three-tiered-ui.html) -* [命令行工具](http://en.zstack.io/tutorials/three-tiered-cli.html) - -#### 安全组: - -* [UI界面](http://en.zstack.io/tutorials/security-group-ui.html) -* [命令行工具](http://en.zstack.io/tutorials/security-group-cli.html) - -#### 弹性端口转发: - -* [UI界面](http://en.zstack.io/tutorials/elastic-port-forwarding-ui.html) -* [命令行工具](http://en.zstack.io/tutorials/elastic-port-forwarding-cli.html) - -#### 快照: - -* [UI界面](http://en.zstack.io/tutorials/snapshot-ui.html) -* [命令行工具](http://en.zstack.io/tutorials/snapshot-cli.html) - -#### 更多 - -关于ZStack架构设计的更多解读,请参阅以下文章: +## ZStack架构设计 #### 伸缩性 -* [ZStack弹性架构揭秘 1:异构架构](http://en.zstack.io/blog/asynchronous-architecture.html) -* [ZStack弹性架构揭秘 2:无状态服务架构](http://en.zstack.io/blog/stateless-clustering.html) -* [ZStack弹性架构揭秘 3:无锁架构](http://en.zstack.io/blog/lock-free.html) +* [ZStack弹性架构揭秘](https://res.zstack.io/assets/pdf/08.pdf) + - 异构架构 + - 无状态服务架构 + - 无锁架构 #### 插件架构 -* [进程内微服务架构](http://en.zstack.io/blog/microservices.html) -* [通用插件系统](http://en.zstack.io/blog/plugin.html) -* [标签系统](http://en.zstack.io/blog/tag.html) -* [工作流引擎](http://en.zstack.io/blog/workflow.html) -* [瀑布流架构](http://en.zstack.io/blog/cascade.html) +* [ZStack插件架构](https://res.zstack.io/assets/pdf/09.pdf) + - 进程内微服务架构 + - 通用插件系统 + - 工作流引擎 -#### 查询API: +#### 资源操作框架 -* [查询API](http://en.zstack.io/blog/query.html) +* [标签系统/级联框架/查询API](https://res.zstack.io/assets/pdf/10.pdf) -#### 自动化: +#### 整体技术架构概述 +* [技术架构概述](https://www.zstack.io/help/product_manuals/white_paper/v5/) -* [全自动化Ansible部署](http://en.zstack.io/blog/ansible.html) +## 社区交流 +* 加入QQ群,共同探讨和分享对ZStack的建议、使用心得、发展方向等。QQ群号:一群(410185063)、二群(443027683)、三群(741300236)、四群(1046295840)、五群(1071894823)、六群(1012034825) -#### 存储与网络: +## 参与贡献 +#### 问题反馈 +1. 提交Issue或通过QQ群反馈问题 +2. 描述如何重现该问题(可选) +3. 可提供解决方案(可选) +4. 提交PR以解决问题(可选) -* [网络模型 1:二层网络和三层网络](http://en.zstack.io/blog/network-l2.html) -* [网络模型 2:云路由器网络服务提供商](http://en.zstack.io/blog/virtual-router.html) -* [存储模型:主存储与镜像服务器](http://en.zstack.io/blog/storage.html) +#### 功能需求 +1. 提交Issue或通过QQ群反馈新功能需求及原因 +2. 指出这个功能的实现方案(可选) +3. 提出PR实现这个新的功能(可选) -#### 测试 +#### 代码贡献 +1. 参考[快速编译手册](https://gitee.com/zstackio/zstack-utility/blob/master/zstackbuild/README.md) 准备一个开发环境 +2. 提交PR请求根据社区反馈进行完善 -* [自动化测试系统 1:综合测试](http://en.zstack.io/blog/integration-testing.html) -* [自动化测试系统2:系统测试](http://en.zstack.io/blog/system-testing.html) -* [自动化测试系统3:模型测试](http://en.zstack.io/blog/model-based-testing.html) +感谢以下小伙伴对本仓库的贡献和反馈[社区贡献榜](https://gitee.com/zstackio/zstack/blob/master/CONTRIBUTORS)! ## 许可证 diff --git a/VERSION b/VERSION index e1206fb1306..8577c9efcfb 100755 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ -MAJOR=4 +MAJOR=5 MINOR=4 -UPDATE=0 +UPDATE=6 diff --git a/abstraction/pom.xml b/abstraction/pom.xml new file mode 100644 index 00000000000..4e18325c587 --- /dev/null +++ b/abstraction/pom.xml @@ -0,0 +1,39 @@ + + + zstack + org.zstack + 5.4.0 + .. + + 4.0.0 + abstraction + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + + diff --git a/abstraction/src/main/java/org/zstack/abstraction/InvalidPluginDefinitionException.java b/abstraction/src/main/java/org/zstack/abstraction/InvalidPluginDefinitionException.java new file mode 100644 index 00000000000..4f83b5629da --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/InvalidPluginDefinitionException.java @@ -0,0 +1,4 @@ +package org.zstack.abstraction; + +public class InvalidPluginDefinitionException extends RuntimeException { +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/OptionType.java b/abstraction/src/main/java/org/zstack/abstraction/OptionType.java new file mode 100644 index 00000000000..019fe354b98 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/OptionType.java @@ -0,0 +1,689 @@ +package org.zstack.abstraction; +/** + * A Model representation of an input / option that is represented either in a UI or CLI. + * This allows an Integration to specify custom inputs for various configuration screens where custom data may need to be provided. + * This could include provisioning options. + * There are several input types as well as display orders. + * this must be provided by the relevant provider interface. + */ +public class OptionType { + protected String uuid; + protected String name; + protected String code; + protected String category; + protected Boolean required = false; // Indicates if the field is mandatory + protected Boolean editable = true; // Indicates if the field is editable + protected Boolean enabled = true; // Indicates if the field is enabled + protected Integer displayOrder; // Specifies the display order of the field + protected InputType inputType = InputType.TEXT; // Input type, refer to the InputType enum for possible values + protected String placeHolderText; // Placeholder text, displayed as a hint + protected String defaultValue; // Default value for the field + protected String noSelection; // Indicates if no selection is allowed by default + protected Boolean noBlank = false; // Indicates if the field can have an empty value + protected Boolean secretField = false; // Indicates if the field contains sensitive information + protected Long minVal; // Minimum allowed value + protected Long maxVal; // Maximum allowed value + protected Long minLength; // Minimum allowed length for input + protected Long maxLength; // Maximum allowed length for input + + protected String fieldContext = "config"; + protected String fieldClass; // CSS class for styling the field + protected String fieldLabel; // Label for the field, displayed in the UI + protected String fieldCode; // Internationalization (i18n) code for the field + protected String fieldName; // The key used by the backend to identify this field + protected String fieldGetName; // Key for retrieving the value from a different property + protected String fieldSetName; // Key for setting the value from a different property + protected String fieldGetContext; // Context for retrieving the field's value + protected String fieldSetContext; // Context for setting the field's value + + protected String fieldGroup; // Specifies the group to which the field belongs + protected String fieldGroupI18nCode; // i18n code for the field group heading + + protected String helpText; // Help text providing guidance to users + protected String helpTextI18nCode; // i18n code for the help text + + protected String optionSourceType; // Source type for dynamic options (e.g., database or API) + protected String optionSource; // Source for dynamic options, such as a method name + protected String dependsOn; // Fields this field depends on; updates when dependent field values change + + protected Boolean showOnEdit = true; // Indicates if the field is displayed during editing + protected Boolean displayValueOnDetails = false; // Indicates if the field value is displayed on details page + protected Boolean showOnCreate = true; // Indicates if the field is displayed during creation + protected String verifyPattern; // Validation pattern for input value, specified as a regular expression + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + /** + * Gets the Unique code representation of the option type. This is used for tracking changes and should be globally unique. It also + * allows for multiple provider types to reuse the same input field if they share the same option set. + * + * @return unique String code identifier for this particular Option Type + */ + public String getCode() { + return code; + } + + /** + * Sets the Unique code representation of the option type. This is used for tracking changes and should be globally unique. It also + * allows for multiple provider types to reuse the same input field if they share the same option set. + * + * @param code unique String code identifier for this particular Option Type + */ + public void setCode(String code) { + this.code = code; + } + + /** + * Gets the field label of the current Option Type. The Field Label is the human readable label that is typically displayed left of the + * input prompt in most UI representations. + * + * @return Human readable Field Label + */ + public String getFieldLabel() { + return fieldLabel; + } + + /** + * Sets the field label of the current Option Type. The Field Label is the human readable label that is typically displayed left of the + * input prompt in most UI representations. + * + * @param fieldLabel Human readable Field Label + */ + public void setFieldLabel(String fieldLabel) { + this.fieldLabel = fieldLabel; + } + + /** + * Gets the field name of the current option type. The Field Name is typically the actual property name the field correlates to. + * It can be period seperated for referencing nested objects and is typically combined with the fieldContext. + * (example: config.provider.name). + * + * @return the field name of the property being saved + */ + public String getFieldName() { + return fieldName; + } + + /** + * Sets the field name of the current option type. The Field Name is typically the actual property name the field correlates to. + * It can be period seperated for referencing nested objects and is typically combined with the fieldContext. + * (example: config.provider.name). + * + * @param fieldName the field name of the property being saved + */ + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + /** + * Gets the field context which is the primary object the field is being saved onto. This could be something like + * 'instance' or 'config'. It typically gets combined with field names such as a fieldName of 'name' with a context + * of 'instance' would get combined to save onto 'instance.name' within Morpheus data model. + * + * @return the field context to be used for determining where the value is saved + */ + public String getFieldContext() { + return fieldContext; + } + + /** + * Sets the field context which is the primary object the field is being saved onto. This could be something like + * 'instance' or 'config'. It typically gets combined with field names such as a fieldName of 'name' with a context + * of 'instance' would get combined to save onto 'instance.name' within Morpheus data model. + * + * @param fieldContext the field context to be used for determining where the value is saved + */ + public void setFieldContext(String fieldContext) { + this.fieldContext = fieldContext; + } + + /** + * Gets the field group which is the name that is used to group fields together in the user interface. + * To have all fields at the same level, do not specify a field group. + * + * @return the field group to be used for grouping fields together + */ + public String getFieldGroup() { + return fieldGroup; + } + + /** + * Sets the field group which is the name that is used to group fields together in the user interface. + * To have all fields at the same level, do not specify a field group. + * + * @param fieldGroup the field group to be used for grouping fields together + */ + public void setFieldGroup(String fieldGroup) { + this.fieldGroup = fieldGroup; + } + + /** + * Gets the type of Input this option type represents. This could range in type and be anything from a free form + * text field to a dropdown with remote loaded data from an {@link #getOptionSource()}. + * + * @return the type of input this option type correlates to. + */ + public InputType getInputType() { + return inputType; + } + + /** + * Sets the type of Input this option type represents. This could range in type and be anything from a free form + * text field to a dropdown with remote loaded data from an {@link #getOptionSource()}. + * + * @param inputType the type of input this option type correlates to. + */ + public void setInputType(InputType inputType) { + this.inputType = inputType; + } + + /** + * Gets the display order position of the following Option Type. The Display order is sorted ascending numerically. Sometimes + * it may be advised to use multiples when incrementing the display order to allow for injection points between them. + * + * @return the Numerical display order (typically starting at 0) of the input. + */ + public Integer getDisplayOrder() { + return displayOrder; + } + + /** + * Sets the display order position of the following Option Type. The Display order is sorted ascending numerically. Sometimes + * it may be advised to use multiples when incrementing the display order to allow for injection points between them. + * + * @param displayOrder the Numerical display order (typically starting at 0) of the input. + */ + public void setDisplayOrder(Integer displayOrder) { + this.displayOrder = displayOrder; + + } + + /** + * Gets an inputs placeholder text for helpful display when awaiting input on a field. A placeholder text can be + * helpful hint to the user as to what type of input should go in the associated field. + * + * @return the place holder input text + */ + public String getPlaceHolderText() { + return placeHolderText; + } + + /** + * Convenience method for binding data, see {@link #getPlaceHolderText() getPlaceHolderText} + */ + public String getPlaceHolder() { + return getPlaceHolderText(); + } + + /** + * Sets an inputs placeholder text for helpful display when awaiting input on a field. A placeholder text can be + * helpful hint to the user as to what type of input should go in the associated field. + * + * @param placeHolderText the place holder input text + */ + public void setPlaceHolderText(String placeHolderText) { + this.placeHolderText = placeHolderText; + + } + + /** + * Convenience method for binding data, see {@link #setPlaceHolderText(String) setPlaceHolderText} + */ + public void setPlaceHolder(String placeHolderText) { + setPlaceHolderText(placeHolderText); + } + + /** + * Returns a String representation of the default value for the current Input. When a user first is prompted for input + * if no input is given by the user, this default value is used. + * + * @return the default value of the following input option + */ + public String getDefaultValue() { + return defaultValue; + } + + /** + * Sets a String representation of the default value for the current Input. When a user first is prompted for input + * if no input is given by the user, this default value is used. + * + * @param defaultValue the default value of the following input option + */ + public void setDefaultValue(String defaultValue) { + this.defaultValue = defaultValue; + } + + /** + * Gets the required flag off of the option type. This determines if an input is user required or not. The CLI and UI will use + * this flag as an initial validation step to ensure a user has at least entered a value. + * + * @return the required flag to determine if an input requires a value or not + */ + public Boolean getRequired() { + return required; + } + + /** + * Sets the required flag off of the option type. This determines if an input is user required or not. The CLI and UI will use + * this flag as an initial validation step to ensure a user has at least entered a value. + * + * @param required the required flag to determine if an input requires a value or not + */ + public void setRequired(Boolean required) { + this.required = required; + } + + /** + * Gets the help text pertaining to an input. Some inputs have help text that display below them to give better + * context for the user when determining what value to enter. This data is optional. + * + * @return the descriptive help block of text for an input + */ + public String getHelpText() { + return helpText; + } + + public String getHelpBlock() { + return helpText; + } + + /** + * Gets the help text pertaining to an input. Some inputs have help text that display below them to give better + * context for the user when determining what value to enter. This data is optional. + * + * @param helpText the descriptive help block of text for an input + */ + public void setHelpText(String helpText) { + this.helpText = helpText; + + } + + public void setHelpBlock(String helpText) { + this.helpText = helpText; + + } + + /** + * Gets the option source api method endpoint to hit when using the {@link InputType#SELECT} option. This allows a remote + * data source query to be queried for loading dynamic data. It also can take a POST request with the values of previously entered + * inputs to use as a way to filter the available options. This should be globally unique. + * + * @return option source api method for loading dynamic options + */ + public String getOptionSource() { + return optionSource; + } + + /** + * Sets the option source api method endpoint to hit when using the {@link InputType#SELECT} option. This allows a remote + * data source query to be queried for loading dynamic data. It also can take a POST request with the values of previously entered + * inputs to use as a way to filter the available options. This should be globally unique. + * + * @param optionSource option source api method for loading dynamic options + */ + public void setOptionSource(String optionSource) { + this.optionSource = optionSource; + + } + + /** + * Gets the code of an option type that this option type depends on. Some option types depend on input from previous option types. By placing the code or fieldName representation of that field into this + * input, this field will refresh upon changes made to that previous input + * + * @return the code of the parent option type + */ + public String getDependsOn() { + return dependsOn; + } + + /** + * Convenience method for binding data, see {@link #getDependsOn() getDependsOn} + */ + public String getDependsOnCode() { + return getDependsOn(); + } + + /** + * Sets the code of an option type that this option type depends on. Some option types depend on input from previous option types. By placing the code or fieldName representation of that field into this + * input, this field will refresh upon changes made to that previous input + * + * @param dependsOn the code of the parent option type + */ + public void setDependsOn(String dependsOn) { + this.dependsOn = dependsOn; + + } + + /** + * Convenience method for binding data, see {@link #setDependsOn(String) setDependsOn} + */ + public void setDependsOnCode(String dependsOn) { + setDependsOn(dependsOn); + } + + /** + * Specifies whether this option type is editable on edit. This sometimes is the case where a field can be set on create + * but not changed later + * + * @return whether or not this option type value is editable + */ + public Boolean getEditable() { + return editable; + } + + /** + * Sets whether or not this option type is editable. This sometimes is the case where a field can be set on create + * but not changed later + * + * @param editable whether or not this field is editable upon edit and not just create + */ + public void setEditable(Boolean editable) { + this.editable = editable; + } + + /** + * Specifies whether this option type is visible on create forms. This sometimes is the case where a field can be set on create + * but not changed later nor does it make sense to display it after create. + * + * @return whether or not this option type is visible upon create + */ + public Boolean getShowOnCreate() { + return showOnCreate; + } + + /** + * Sets whether or not this option type is visible on create forms. This sometimes is the case where a field can be set on create + * but not changed later, nor does it make sense to display it after create. + * + * @param showOnCreate whether or not this option type is visible upon create + */ + public void setShowOnCreate(Boolean showOnCreate) { + this.showOnCreate = showOnCreate; + + } + + /** + * Specifies if this option type is visible on edit forms. This sometimes is the case where a field can be set on create + * but not changed later nor does it make sense to display it after create. + * + * @return determines if this option type is visible upon edit + */ + public Boolean getShowOnEdit() { + return showOnEdit; + } + + /** + * Sets if this option type is visible on edit forms. This sometimes is the case where a field can be set on create + * but not changed later, nor does it make sense to display it after create. + * + * @param showOnEdit determines if this option type is visible upon edit + */ + public void setShowOnEdit(Boolean showOnEdit) { + this.showOnEdit = showOnEdit; + } + + public String getFieldClass() { + return fieldClass; + } + + public void setFieldClass(String fieldClass) { + this.fieldClass = fieldClass; + } + + /** + * Specifies if this option type is visible on resource detail views. + * + * @return determines if this option type is visible upon edit + */ + public Boolean getDisplayValueOnDetails() { + return displayValueOnDetails; + } + + /** + * Sets if this option type is visible on resource detail views. + * + * @param displayValueOnDetails determines if this option type is visible on resource detail views + */ + public void setDisplayValueOnDetails(Boolean displayValueOnDetails) { + this.displayValueOnDetails = displayValueOnDetails; + + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + + } + + /** + * returns the uuid + * + * @return the uuid of the current record + */ + public String getUuid() { + return uuid; + } + + /** + * Sets the uuid. In this class this should not be called directly + * + * @param uuid the uuid of the current record + */ + public void setUuid(String uuid) { + this.uuid = uuid; + + } + + public String getNoSelection() { + return noSelection; + } + + public void setNoSelection(String noSelection) { + this.noSelection = noSelection; + + } + + public Long getMinVal() { + return minVal; + } + + public void setMinVal(Long minVal) { + this.minVal = minVal; + + } + + public Long getMaxVal() { + return maxVal; + } + + public void setMaxVal(Long maxVal) { + this.maxVal = maxVal; + + } + + public Long getMinLength() { + return minLength; + } + + public void setMinLength(Long minLength) { + this.minLength = minLength; + + } + + public Long getMaxLength() { + return maxLength; + } + + public void setMaxLength(Long maxLength) { + this.maxLength = maxLength; + + } + + public String getFieldCode() { + return fieldCode; + } + + public void setFieldCode(String fieldCode) { + this.fieldCode = fieldCode; + + } + + public String getFieldGetName() { + return fieldGetName; + } + + public void setFieldGetName(String fieldGetName) { + this.fieldGetName = fieldGetName; + + } + + public String getFieldSetName() { + return fieldSetName; + } + + public void setFieldSetName(String fieldSetName) { + this.fieldSetName = fieldSetName; + + } + + public String getFieldGetContext() { + return fieldGetContext; + } + + public void setFieldGetContext(String fieldGetContext) { + this.fieldGetContext = fieldGetContext; + + } + + public String getFieldSetContext() { + return fieldSetContext; + } + + public void setFieldSetContext(String fieldSetContext) { + this.fieldSetContext = fieldSetContext; + + } + + public String getFieldGroupI18nCode() { + return fieldGroupI18nCode; + } + + /** + * Convenience method for binding data, see {@link #getFieldGroupI18nCode() getFieldGroupI18nCode} + */ + public String getFieldGroupCode() { + return getFieldGroupI18nCode(); + } + + public void setFieldGroupI18nCode(String fieldGroupI18nCode) { + this.fieldGroupI18nCode = fieldGroupI18nCode; + + } + + /** + * Convenience method for binding data, see {@link #setFieldGroupI18nCode(String) setFieldGroupI18nCode} + */ + public void setFieldGroupCode(String fieldGroupI18nCode) { + setFieldGroupI18nCode(fieldGroupI18nCode); + } + + public String getHelpTextI18nCode() { + return helpTextI18nCode; + } + + /** + * Convenience method for binding data, see {@link #getHelpTextI18nCode() getHelpTextI18nCode} + */ + public String getHelpBlockCode() { + return getHelpTextI18nCode(); + } + + public void setHelpTextI18nCode(String helpTextI18nCode) { + this.helpTextI18nCode = helpTextI18nCode; + + } + + /** + * Convenience method for binding data, see {@link #setHelpTextI18nCode(String) setHelpTextI18nCode} + */ + public void setHelpBlockCode(String helpTextI18nCode) { + setHelpTextI18nCode(helpTextI18nCode); + } + + public String getOptionSourceType() { + return optionSourceType; + } + + public void setOptionSourceType(String optionSourceType) { + this.optionSourceType = optionSourceType; + + } + + public Boolean getNoBlank() { + return noBlank; + } + + public void setNoBlank(Boolean noBlank) { + this.noBlank = noBlank; + } + + public Boolean getSecretField() { + return secretField; + } + + public void setSecretField(Boolean secretField) { + this.secretField = secretField; + } + + public String getVerifyPattern() { + return verifyPattern; + } + + public void setVerifyPattern(String verifyPattern) { + this.verifyPattern = verifyPattern; + } + + public enum InputType { + TEXT("text"), + PASSWORD("password"), + NUMBER("number"), + TEXTAREA("textarea"), + SELECT("select"), + MULTI_SELECT("multiSelect"), + CHECKBOX("checkbox"), + RADIO("radio"), + CREDENTIAL("credential"), + TYPEAHEAD("typeahead"), + MULTI_TYPEAHEAD("multiTypeahead"), + CODE_EDITOR("code-editor"), + HIDDEN("hidden"); + + private final String value; + + InputType(String value) { + this.value = value; + } + + public String toString() { + return this.value; + } + } +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/PluginCapabilityState.java b/abstraction/src/main/java/org/zstack/abstraction/PluginCapabilityState.java new file mode 100644 index 00000000000..49b3846c29f --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/PluginCapabilityState.java @@ -0,0 +1,13 @@ +package org.zstack.abstraction; + +/** + * PluginCapabilityState offers two states of plugin capabilities. + *

+ * SUPPORTED: means plugin support the capability + * UNSUPPORTED: means plugin do not support the capability + *

+ */ +public enum PluginCapabilityState { + SUPPORTED, + UNSUPPORTED +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/PluginDriver.java b/abstraction/src/main/java/org/zstack/abstraction/PluginDriver.java new file mode 100644 index 00000000000..61a812f06c3 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/PluginDriver.java @@ -0,0 +1,73 @@ +package org.zstack.abstraction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +/** + * PluginRegister defines the specific requirements for plugin. + *

+ * by PluginRegister we should get all metadata of the plugin. + *

+ */ +public interface PluginDriver { + String type(); + + /** + * product name of your plugin + * @return a String of name + */ + String name(); + + /** + * unique product key from distribution + * @return the key of current environment + */ + String uuid(); + + /** + * plugin version + * @return version of current plugin + */ + String version(); + + /** + * capabilities map describe current plugin's whole + * capabilities + * @return map of feature + */ + Map features(); + + /** + * plugin's description + * @return description of current plugin + */ + String description(); + + /** + * plugin's vendor + * @return vendor of current plugin + */ + String vendor(); + + /** + * plugin's url + * @return url of current plugin + */ + String url(); + + /** + * plugin's license + * @return license of current plugin + */ + String license(); + + /** + * Provides a Collection of OptionType inputs that define the required input fields for defining a plugin integration + * + * @return Collection of OptionType + */ + default Collection optionTypes() { + return new ArrayList<>(); + } +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/PluginEndpointValidator.java b/abstraction/src/main/java/org/zstack/abstraction/PluginEndpointValidator.java new file mode 100644 index 00000000000..b76d8e6c382 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/PluginEndpointValidator.java @@ -0,0 +1,36 @@ +package org.zstack.abstraction; + +import org.zstack.abstraction.sns.EndpointDriver; + +import java.util.List; +import java.util.stream.Collectors; + +public class PluginEndpointValidator implements PluginValidator { + @Override + public Class pluginClass() { + return EndpointDriver.class; + } + + @Override + public void validate(PluginDriver register) { + if (register.type() == null) { + throw new InvalidPluginDefinitionException(); + } + } + + @Override + public void validateAllPlugins(List pluginDriverList) { + int pluginNumber = pluginDriverList.size(); + + int distinctPluginByEndpointTypeNumber = pluginDriverList + .stream() + .map(PluginDriver::type) + .collect(Collectors.toSet()).size(); + + if (pluginNumber == distinctPluginByEndpointTypeNumber) { + return; + } + + throw new InvalidPluginDefinitionException(); + } +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/PluginMethod.java b/abstraction/src/main/java/org/zstack/abstraction/PluginMethod.java new file mode 100644 index 00000000000..cd371c05499 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/PluginMethod.java @@ -0,0 +1,5 @@ +package org.zstack.abstraction; + +public @interface PluginMethod { + boolean required() default true; +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/PluginValidator.java b/abstraction/src/main/java/org/zstack/abstraction/PluginValidator.java new file mode 100644 index 00000000000..ac41e00705e --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/PluginValidator.java @@ -0,0 +1,11 @@ +package org.zstack.abstraction; + +import java.util.List; + +public interface PluginValidator { + Class pluginClass(); + + void validate(PluginDriver register); + + void validateAllPlugins(List pluginRegisterList); +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/crypto/CryptoClientDriver.java b/abstraction/src/main/java/org/zstack/abstraction/crypto/CryptoClientDriver.java new file mode 100644 index 00000000000..7602905bb85 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/crypto/CryptoClientDriver.java @@ -0,0 +1,70 @@ +package org.zstack.abstraction.crypto; + +import org.zstack.abstraction.OptionType; +import org.zstack.abstraction.PluginDriver; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public interface CryptoClientDriver extends PluginDriver { + boolean initialize(Map properties); + /** + * Test client connectivity + * + * @return true means test connection succeed else false + */ + boolean connect(Map properties); + + /** + * Parse original text and certificate base64 string + * + * @param input Signature string representation + * @return A 2D byte array where Result[0] contains the original text and Result[1] contains the certificate base64 string + */ + byte[][] attachedVerify(String input); + + /** + * Retrieves additional signature properties. + * + * @return A map containing additional signature properties, + * where each key-value pair represents a signature-related configuration or metadata. + */ + default Map additionSignatureProperties(){ + return new HashMap<>(); + }; + + /** + * Return SM3 encrypted cipher text + * + * @param plain the original text + * @return encrypt result + */ + String sm3Encrypt(String plain); + + /** + * SM4 encryption of the string + * + * @param plain the original text + * @return SM4 encrypted text + */ + String sm4Encrypt(String plain); + + /** + * SM4 decryption of the string + * + * @param plain the encrypted text + * @return sSM4 decrypted text + */ + String sm4Decrypt(String plain); + + /** + * Encrypt the string with hmac + * + * @param plain the original text + * @return hmac encrypted text + */ + String hmac(String plain); + + Collection optionTypes(); +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/sns/EndpointDriver.java b/abstraction/src/main/java/org/zstack/abstraction/sns/EndpointDriver.java new file mode 100644 index 00000000000..ce8e54c4070 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/sns/EndpointDriver.java @@ -0,0 +1,11 @@ +package org.zstack.abstraction.sns; + +import org.zstack.abstraction.PluginDriver; + +/** + * PluginEndpointSender extends PluginRegister and contains sender + * of sns endpoint. + */ +public interface EndpointDriver extends PluginDriver { + boolean send(PluginEndpointData message); +} \ No newline at end of file diff --git a/abstraction/src/main/java/org/zstack/abstraction/sns/PluginEndpointData.java b/abstraction/src/main/java/org/zstack/abstraction/sns/PluginEndpointData.java new file mode 100755 index 00000000000..b3e523e473a --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/sns/PluginEndpointData.java @@ -0,0 +1,36 @@ +package org.zstack.abstraction.sns; + +import java.util.Map; + +/** + * PluginEndpointData used to copy sns message data for plugin. + */ +public class PluginEndpointData { + private Map metadata; + private String message; + private Map properties; + + public Map getMetadata() { + return metadata; + } + + public void setMetadata(Map metadata) { + this.metadata = metadata; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/sso/OAuth2PluginConstants.java b/abstraction/src/main/java/org/zstack/abstraction/sso/OAuth2PluginConstants.java new file mode 100644 index 00000000000..087bbd5129e --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/sso/OAuth2PluginConstants.java @@ -0,0 +1,49 @@ +package org.zstack.abstraction.sso; + +/** + * @Author: DaoDao + * @Date: 2022/8/24 + */ +public interface OAuth2PluginConstants { + //default use OIDC, + public static final String AUTH_SCOPE_VALUE= "openid"; + + public static final int AUTH_RESPONSE_SUCCESS = 200; + public static final int AUTH_RESPONSE_ERROR = 500; + + public static final String OAUTH2_REDIRECT = "/sso/oauth2"; + public static final String TOKEN_INTROSPECT_PATH= "/introspect"; + public static final String TOKEN_Authorization = "Authorization"; + public static final String OAUTH2_TOKEN = "token"; + public static final String TOKEN_INTROSPECT_ACTIVE = "active"; + public static final String GRANT_TYPE_NAME = "grant_type"; + public static final String GRANT_TYPE_OCDE_VALUE = "authorization_code"; + public static final String REFRESH_TOKEN_VALUE = "refresh_token"; + public static final String GRANT_TYPE_PASSWORD_VALUE = "password"; + public static final String AUTH_REDIRECT_URL_NAME= "redirect_uri"; + public static final String CLIENT_ID_NAME = "client_id"; + public static final String CLIENT_SECRET_NAME = "client_secret"; + public static final String OAUTH2_CODE = "code"; + public static final String AUTH_SCOPE_NAME= "scope"; + public static final String RESPONSE_TYPE_NAME = "response_type"; + public static final String AUTH2_STATE = "state"; + + public static final String OAUTH2_USER_NAME = "username"; + public static final String OAUTH2_PASSWORD = "password"; + + public static final String OIDC_GET_USERNAME = "preferred_username"; + public static final String IAM2_ORGANIZATIONS = "organization"; + + public static final String OIDC_SSO_CLIENT_TYPE = "OIDC"; + public static final String OAUTH2_SSO_CLIENT_TYPE = "OAuth2"; + + public static final String ID_TOKEN_VALUE = "id_token"; + public static final String ACCESS_TOKEN_VALUE = "access_token"; + public static final String TOKEN_EXPIRE_TIME_NAME = "exp"; + + String DEFAULT_PROVIDER_NAME = "default"; + String PLUGIN_PROVIDER_NAME = "plugin"; + String ZF_PROVIDER_NAME = "zf"; + String ALI_PROVIDER_NAME = "ali_idaas_private"; + String MAX_KEY_PROVIDER_NAME = "max_key"; +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/sso/OAuth2ProviderDriver.java b/abstraction/src/main/java/org/zstack/abstraction/sso/OAuth2ProviderDriver.java new file mode 100644 index 00000000000..d6bbeada4f2 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/sso/OAuth2ProviderDriver.java @@ -0,0 +1,65 @@ +package org.zstack.abstraction.sso; + +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; +import org.springframework.web.util.UriComponentsBuilder; +import org.zstack.abstraction.PluginDriver; + +import java.util.Map; + +public interface OAuth2ProviderDriver extends PluginDriver { + default String type() { + return "sso"; + } + + default String prepareUrl(String requestUrl, MultiValueMap map, HttpHeaders headers) { + return UriComponentsBuilder.fromHttpUrl(requestUrl).toUriString(); + } + + default HttpEntity> prepareReq(MultiValueMap map, HttpHeaders headers) { + return new HttpEntity<>(map, headers); + } + + default MultiValueMap generateRequestCode(String code, String thirdPartyRedirectUrl, Map client) { + MultiValueMap map = new LinkedMultiValueMap<>(); + map.add(OAuth2PluginConstants.GRANT_TYPE_NAME, OAuth2PluginConstants.GRANT_TYPE_OCDE_VALUE); + map.add(OAuth2PluginConstants.AUTH_REDIRECT_URL_NAME, thirdPartyRedirectUrl); + map.add(OAuth2PluginConstants.CLIENT_ID_NAME, client.get("clientId")); + map.add(OAuth2PluginConstants.CLIENT_SECRET_NAME, client.get("clientSecret")); + map.add(OAuth2PluginConstants.OAUTH2_CODE, code); + map.add(OAuth2PluginConstants.AUTH_SCOPE_NAME, StringUtils.isEmpty(client.get("scope")) ? OAuth2PluginConstants.AUTH_SCOPE_VALUE : client.get("scope").replace("::", " ")); + return map; + } + + default RequestData buildRequestTokenData(MultiValueMap map, String requestUrl) { + return new RequestData(requestUrl, map, HttpMethod.POST, new HttpHeaders()); + } + + default RequestData buildRequestLogOutData(MultiValueMap map, String requestUrl) { + return new RequestData(requestUrl, map, HttpMethod.POST, new HttpHeaders()); + } + + default boolean skipRefreshToken() { + return false; + } + + default RequestData buildRequestRefreshTokenData(MultiValueMap map, String requestUrl) { + return new RequestData(requestUrl, map, HttpMethod.POST, new HttpHeaders()); + } + + default RequestData buildRequestTokenIntrospectData(MultiValueMap map, String requestUrl, HttpHeaders headers) { + return new RequestData(requestUrl, map, HttpMethod.POST, headers); + } + + default Map parseUserInfo(Map response) { + return response; + } + + default RequestData buildRequestUserInfoData(MultiValueMap map, String requestUrl, HttpHeaders headers) { + return new RequestData(requestUrl, map, HttpMethod.POST, headers); + } +} diff --git a/abstraction/src/main/java/org/zstack/abstraction/sso/RequestData.java b/abstraction/src/main/java/org/zstack/abstraction/sso/RequestData.java new file mode 100644 index 00000000000..be2828b0725 --- /dev/null +++ b/abstraction/src/main/java/org/zstack/abstraction/sso/RequestData.java @@ -0,0 +1,19 @@ +package org.zstack.abstraction.sso; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.util.MultiValueMap; + +public class RequestData { + public String requestUrl; + public HttpMethod method; + public MultiValueMap map; + public HttpHeaders headers; + + public RequestData(String requestUrl, MultiValueMap map, HttpMethod method, HttpHeaders headers) { + this.requestUrl = requestUrl; + this.method = method; + this.map = map; + this.headers = headers; + } +} diff --git a/build/bump_version.py b/build/bump_version.py new file mode 100644 index 00000000000..5b4ffec093b --- /dev/null +++ b/build/bump_version.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +import subprocess +import sys +import re +import os + + +def get_files(paths=['.', 'premium']): + all_files = [] + for path in paths: + if os.path.exists(path): + result = subprocess.run(['git', 'ls-files'], + cwd=path, + capture_output=True, + text=True) + files = result.stdout.splitlines() + path_files = [(os.path.join(path, f), + 'pom' if 'pom.xml' in f else 'global') + for f in files + if 'pom.xml' in f or 'GlobalProperty' in f] + all_files.extend(path_files) + return all_files + + +def update_version_in_pom(file_path, new_version): + try: + # 使用 'rb' 模式读取,保留原始字节 + with open(file_path, 'rb') as f: + content = f.read() + + # 将字节转换为字符串进行处理 + str_content = content.decode('utf-8') + pattern = r'(.*?)(.*?)(.*?)' + regex = re.compile(pattern, re.DOTALL) + + if not regex.search(str_content): + print(f"Skipped {file_path} - no matching parent version found") + return + + def replace_version(match): + old_version = match.group(2) + print(f"In {file_path}: Changing version from { + old_version} to {new_version}") + return f'{match.group(1)}{new_version}{match.group(3)}' + + new_content = regex.sub(replace_version, str_content) + + if new_content != str_content: + # 使用 'wb' 模式写入,确保字节级别的一致性 + with open(file_path, 'wb') as f: + f.write(new_content.encode('utf-8')) + print(f"Updated {file_path}") + + except Exception as e: + print(f"Error processing {file_path}: {str(e)}") + + +def update_version_in_global_property(file_path, old_version, new_version): + try: + # 使用 'rb' 模式读取,保留原始字节 + with open(file_path, 'rb') as f: + content = f.read() + + # 将字节转换为字符串进行处理 + str_content = content.decode('utf-8') + pattern = r'(@GlobalProperty\s*\([^)]*defaultValue\s*=\s*"[^"]*?)' + \ + re.escape(old_version) + r'(\.tar\.gz"[^)]*\))' + regex = re.compile(pattern) + + if not regex.search(str_content): + print( + f"Skipped {file_path} - no matching version in GlobalProperty") + return + + def replace_version(match): + print(f"In {file_path}: Changing version from { + old_version} to {new_version}") + return f'{match.group(1)}{new_version}{match.group(2)}' + + new_content = regex.sub(replace_version, str_content) + + if new_content != str_content: + # 使用 'wb' 模式写入,确保字节级别的一致性 + with open(file_path, 'wb') as f: + f.write(new_content.encode('utf-8')) + print(f"Updated {file_path}") + + except Exception as e: + print(f"Error processing {file_path}: {str(e)}") + + +def main(): + if len(sys.argv) != 3: + print("Usage: python script.py ") + print("Example: python script.py 5.2.0 5.3.0") + sys.exit(1) + + old_version = sys.argv[1] + new_version = sys.argv[2] + files = get_files() + + print(f"Found {len(files)} files to process") + for file_path, file_type in files: + if file_type == 'pom': + update_version_in_pom(file_path, new_version) + else: + update_version_in_global_property( + file_path, old_version, new_version) + + +if __name__ == "__main__": + main() diff --git a/build/deploydb.sh b/build/deploydb.sh index 49964c58754..b0d922475bc 100755 --- a/build/deploydb.sh +++ b/build/deploydb.sh @@ -12,6 +12,13 @@ if [[ `id -u` -ne 0 ]] && [[ x"$user" = x"root" ]]; then MYSQL='sudo mysql' fi +if command -v greatdb &> /dev/null; then + MYSQL='greatdb' + if [[ `id -u` -ne 0 ]] && [[ x"$user" = x"root" ]]; then + MYSQL='sudo greatdb' + fi +fi + base=`dirname $0` if [[ ! -n $host ]] || [[ ! -n $port ]];then @@ -20,17 +27,33 @@ else loginCmd="--user=$user --password=$password --host=$host --port=$port" fi -${MYSQL} ${loginCmd} << EOF -set global log_bin_trust_function_creators=1; -DROP DATABASE IF EXISTS zstack; -CREATE DATABASE zstack; -DROP DATABASE IF EXISTS zstack_rest; -CREATE DATABASE zstack_rest; -grant all privileges on zstack.* to root@'%' identified by "${password}"; -grant all privileges on zstack_rest.* to root@'%' identified by "${password}"; -grant all privileges on zstack.* to root@'127.0.0.1' identified by "${password}"; -grant all privileges on zstack_rest.* to root@'127.0.0.1' identified by "${password}"; +if command -v greatdb &> /dev/null; then + ${MYSQL} ${loginCmd} << EOF + set global log_bin_trust_function_creators=1; + DROP DATABASE IF EXISTS zstack; + CREATE DATABASE zstack; + DROP DATABASE IF EXISTS zstack_rest; + CREATE DATABASE zstack_rest; + CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY "${password}"; + CREATE USER IF NOT EXISTS 'root'@'127.0.0.1' IDENTIFIED BY "${password}"; + grant all privileges on zstack.* to root@'%'; + grant all privileges on zstack_rest.* to root@'%'; + grant all privileges on zstack.* to root@'127.0.0.1'; + grant all privileges on zstack_rest.* to root@'127.0.0.1'; EOF +else + ${MYSQL} ${loginCmd} << EOF + set global log_bin_trust_function_creators=1; + DROP DATABASE IF EXISTS zstack; + CREATE DATABASE zstack; + DROP DATABASE IF EXISTS zstack_rest; + CREATE DATABASE zstack_rest; + grant all privileges on zstack.* to root@'%' identified by "${password}"; + grant all privileges on zstack_rest.* to root@'%' identified by "${password}"; + grant all privileges on zstack.* to root@'127.0.0.1' identified by "${password}"; + grant all privileges on zstack_rest.* to root@'127.0.0.1' identified by "${password}"; +EOF +fi # assign flyway version if not defined : "${flywayver:=3.2.1}" diff --git a/build/pom.xml b/build/pom.xml index bbb7b1f2e59..504841e00b9 100755 --- a/build/pom.xml +++ b/build/pom.xml @@ -4,7 +4,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. build @@ -21,7 +21,7 @@ 2.3 - WEB-INF/lib/maven*.jar, + %regex[WEB-INF/lib/maven(?!-artifact).*.jar], WEB-INF/lib/plexus*.jar, WEB-INF/lib/cvsclient*.jar, WEB-INF/lib/classworlds*.jar, @@ -32,8 +32,11 @@ WEB-INF/lib/c3p0-0.9.1.1.jar, WEB-INF/lib/reflections-0.9.8.jar, WEB-INF/lib/groovy-2.4.7.jar, - WEB-INF/lib/okhttp-2.7.5.jar, WEB-INF/lib/sisu-guava-0.9.9.jar, + WEB-INF/lib/groovy-sandbox-1.19.jar, + WEB-INF/lib/bcpkix-jdk18on-1.72.jar, + WEB-INF/lib/bcprov-jdk18on-1.72.jar, + WEB-INF/lib/bcutil-jdk18on-1.72.jar, @@ -77,43 +80,8 @@ context.xml - - ../premium/plugin-premium/externalapiadapter/ext-libs - WEB-INF/lib - - *.jar - - - - ../premium/plugin-premium/cas-plugin/ext-libs - WEB-INF/lib - - *.jar - - - - ../premium/crypto/ext-libs - WEB-INF/lib - - *.jar - - - - ../search/ext-libs - WEB-INF/lib - - *.jar - - - + ../premium/conf/cas-web.xml @@ -181,7 +149,7 @@ search ${project.version} - + org.zstack applianceVm @@ -217,6 +185,41 @@ localstorage ${project.version} + + org.zstack + externalStorage + ${project.version} + + + org.zstack + zbs + ${project.version} + + + org.zstack + cbd + ${project.version} + + + org.zstack + expon + ${project.version} + + + org.zstack + xinfini + ${project.version} + + + org.zstack + vhost + ${project.version} + + + org.zstack + iscsi + ${project.version} + org.zstack mediator @@ -302,7 +305,7 @@ hybrid ${project.version} - + org.zstack zwatch ${project.version} @@ -372,6 +375,11 @@ sanyuan ${project.version} + + org.zstack + proxy + ${project.version} + org.zstack zstack-ticket @@ -382,6 +390,16 @@ aliyun-storage ${project.version} + + org.zstack + block-primary-storage + ${project.version} + + + org.zstack + memory-balloon + ${project.version} + org.zstack sdk @@ -432,6 +450,11 @@ v2v ${project.version} + + org.zstack + upgrade-hack + ${project.version} + org.zstack yunshan @@ -444,7 +467,7 @@ org.zstack - ceph-ha-plugin + storage-ha-plugin ${project.version} @@ -558,6 +581,66 @@ cas-plugin ${project.version} + + org.zstack + sugonSdnController + ${project.version} + + + org.zstack + ovf + ${project.version} + + + org.zstack + sso-plugin + ${project.version} + + + org.zstack + cube + ${project.version} + + + org.zstack + zops-plugin + ${project.version} + + + org.zstack + zsv + ${project.version} + + + org.zstack + virtualSwitchNetwork + ${project.version} + + + org.zstack + hostNetworkInterface + ${project.version} + + + org.zstack + ovn + ${project.version} + + + org.zstack + observabilityServer + ${project.version} + + + org.zstack + zdfs + ${project.version} + + + org.zstack + huawei-imaster + ${project.version} + @@ -580,7 +663,7 @@ 2.3 - WEB-INF/lib/maven*.jar, + %regex[WEB-INF/lib/maven(?!-artifact).*.jar], WEB-INF/lib/plexus*.jar, WEB-INF/lib/cvsclient*.jar, WEB-INF/lib/classworlds*.jar, @@ -591,7 +674,6 @@ WEB-INF/lib/c3p0-0.9.1.1.jar, WEB-INF/lib/reflections-0.9.8.jar, WEB-INF/lib/groovy-2.4.7.jar, - WEB-INF/lib/okhttp-2.7.5.jar, @@ -713,6 +795,41 @@ localstorage ${project.version} + + org.zstack + externalStorage + ${project.version} + + + org.zstack + zbs + ${project.version} + + + org.zstack + cbd + ${project.version} + + + org.zstack + expon + ${project.version} + + + org.zstack + xinfini + ${project.version} + + + org.zstack + vhost + ${project.version} + + + org.zstack + iscsi + ${project.version} + org.zstack mediator @@ -783,5 +900,60 @@ acl ${project.version} + + org.zstack + directory + ${project.version} + + + org.zstack + macvlan + ${project.version} + + + org.zstack + pvlan + ${project.version} + + + org.zstack + sshKeyPair + ${project.version} + + + org.zstack + ai + ${project.version} + + + org.zstack + container + ${project.version} + + + org.zstack + iam2-container + ${project.version} + + + org.zstack + snmp + ${project.version} + + + org.zstack + hostNetworkInterface + ${project.version} + + + org.zstack + observabilityServer + ${project.version} + + + org.zstack + huawei-imaster + ${project.version} + diff --git a/build/zsi18n b/build/zsi18n index 4b9a3706abb..af7d05baf0f 100755 Binary files a/build/zsi18n and b/build/zsi18n differ diff --git a/compute/pom.xml b/compute/pom.xml index 80e8e1e0a00..e87ed4a4b12 100755 --- a/compute/pom.xml +++ b/compute/pom.xml @@ -4,7 +4,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. compute @@ -123,5 +123,19 @@ resourceconfig ${project.version} + + org.yaml + snakeyaml + + + org.zstack + directory + ${project.version} + + + org.zstack + configuration + ${project.version} + diff --git a/compute/src/main/java/org/zstack/compute/VmNicUtils.java b/compute/src/main/java/org/zstack/compute/VmNicUtils.java new file mode 100644 index 00000000000..6d001bdfb86 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/VmNicUtils.java @@ -0,0 +1,67 @@ +package org.zstack.compute; + +import org.apache.commons.lang.StringUtils; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.vm.VmNicParam; +import org.zstack.header.vm.VmNicState; +import org.zstack.utils.CollectionUtils; + +import java.util.List; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.argerr; +import static org.zstack.header.vm.VmInstanceConstant.VM_NIC_QOS_MAX; +import static org.zstack.header.vm.VmInstanceConstant.VM_NIC_QOS_MIN; + +public class VmNicUtils { + public static void validateVmParms(List vmNicParms, List l3Uuids, List supportNicDriverTypes) { + if (CollectionUtils.isEmpty(vmNicParms)) { + return; + } + + List l3UuidsInParms = vmNicParms.stream().map(VmNicParam::getL3NetworkUuid).distinct().collect(Collectors.toList()); + if (l3UuidsInParms.size() != vmNicParms.size()) { + throw new ApiMessageInterceptionException(argerr("duplicate nic params")); + } + + for (VmNicParam nic : vmNicParms) { + String l3 = nic.getL3NetworkUuid(); + if (StringUtils.isEmpty(l3)) { + throw new ApiMessageInterceptionException(argerr("l3NetworkUuid of vm nic can not be null")); + } + if (!CollectionUtils.isEmpty(l3Uuids) && !l3Uuids.contains(nic.getL3NetworkUuid())) { + throw new ApiMessageInterceptionException(argerr("l3NetworkUuid of vm nic is not in l3[%s]", l3Uuids)); + } + + if (nic.getOutboundBandwidth() != null) { + if (nic.getOutboundBandwidth() < VM_NIC_QOS_MIN || nic.getOutboundBandwidth() > VM_NIC_QOS_MAX) { + throw new ApiMessageInterceptionException(argerr("outbound bandwidth[%d] of vm nic is out of [8192, 32212254720]", nic.getOutboundBandwidth())); + } + } + + if (nic.getInboundBandwidth() != null) { + if (nic.getInboundBandwidth() < VM_NIC_QOS_MIN || nic.getInboundBandwidth() > VM_NIC_QOS_MAX) { + throw new ApiMessageInterceptionException(argerr("inbound bandwidth[%d] of vm nic is out of [8192, 32212254720]", nic.getInboundBandwidth())); + } + } + + if (nic.getMultiQueueNum() != null ) { + if (nic.getMultiQueueNum() < 1 || nic.getMultiQueueNum() > 256) { + throw new ApiMessageInterceptionException(argerr("multi queue num[%d] of vm nic is out of [1,256]", nic.getMultiQueueNum())); + } + } + + if (nic.getState() != null) { + if (!asList(VmNicState.enable.toString(), VmNicState.disable.toString()).contains(nic.getState())) { + throw new ApiMessageInterceptionException(argerr("vm nic of l3[uuid:%s] state[%s] is not %s or %s ", nic.getL3NetworkUuid(), nic.getState(), VmNicState.enable.toString(), VmNicState.disable.toString())); + } + } + + String driverType = nic.getDriverType(); + if (!StringUtils.isEmpty(driverType) && !CollectionUtils.isEmpty(supportNicDriverTypes) && !supportNicDriverTypes.contains(driverType)){ + throw new ApiMessageInterceptionException(argerr("vm nic driver %s not support yet", driverType)); + } + } + } +} diff --git a/compute/src/main/java/org/zstack/compute/allocator/AbstractHostAllocatorStrategyFactory.java b/compute/src/main/java/org/zstack/compute/allocator/AbstractHostAllocatorStrategyFactory.java index c2dfa1d046f..8117e0afaa2 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/AbstractHostAllocatorStrategyFactory.java +++ b/compute/src/main/java/org/zstack/compute/allocator/AbstractHostAllocatorStrategyFactory.java @@ -52,7 +52,7 @@ public void marshalSpec(HostAllocatorSpec spec, AllocateHostMsg msg) { if (msg instanceof DesignatedAllocateHostMsg) { DesignatedAllocateHostMsg dmsg = (DesignatedAllocateHostMsg)msg; spec.getExtraData().put(HostAllocatorConstant.LocationSelector.zone, dmsg.getZoneUuid()); - spec.getExtraData().put(HostAllocatorConstant.LocationSelector.cluster, dmsg.getClusterUuid()); + spec.getExtraData().put(HostAllocatorConstant.LocationSelector.cluster, dmsg.getClusterUuids()); spec.getExtraData().put(HostAllocatorConstant.LocationSelector.host, dmsg.getHostUuid()); } } diff --git a/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorExtensionPoint.java b/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorExtensionPoint.java new file mode 100644 index 00000000000..28e89c931c7 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.compute.allocator; + +import java.util.List; + +public interface AttachedL2NetworkAllocatorExtensionPoint { + List filter(List hostUuids, List l2Uuids); +} diff --git a/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java old mode 100755 new mode 100644 index 1f3a030d0d1..cd986023bd1 --- a/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java @@ -4,22 +4,33 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; -import org.zstack.core.CoreGlobalProperty; import org.zstack.core.Platform; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.header.allocator.AbstractHostAllocatorFlow; -import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostVO; -import org.zstack.header.network.l2.L2NetworkClusterRefVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.L3NetworkInventory; +import javax.persistence.Tuple; import javax.persistence.TypedQuery; import java.util.*; +import java.util.stream.Collectors; + +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.Utils; + @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class AttachedL2NetworkAllocatorFlow extends AbstractHostAllocatorFlow { + private static final CLogger logger = Utils.getLogger(AttachedL2NetworkAllocatorFlow.class); @Autowired private DatabaseFacade dbf; + @Autowired + private PluginRegistry pluginRgty; @Transactional(readOnly = true) private List allocate(Collection l3NetworkUuids, Collection hostUuids) { @@ -56,47 +67,108 @@ private List allocate(Collection l3NetworkUuids, Collection(); } + List retHostUuids; if (hostUuids.isEmpty()) { - sql = "select h from HostVO h where h.clusterUuid in (:cuuids)"; - TypedQuery hq = dbf.getEntityManager().createQuery(sql, HostVO.class); - hq.setParameter("cuuids", clusterUuids); + retHostUuids = Q.New(HostVO.class).select(HostVO_.uuid) + .in(HostVO_.clusterUuid, clusterUuids).listValues(); + } else { + retHostUuids = Q.New(HostVO.class).select(HostVO_.uuid) + .in(HostVO_.clusterUuid, clusterUuids) + .in(HostVO_.uuid, hostUuids).listValues(); + } - if (usePagination()) { - hq.setFirstResult(paginationInfo.getOffset()); - hq.setMaxResults(paginationInfo.getLimit()); - } + if (retHostUuids.isEmpty()){ + return new ArrayList<>(); + } - return hq.getResultList(); - } else { - sql = "select h from HostVO h where h.clusterUuid in (:cuuids) and h.uuid in (:huuids)"; - TypedQuery hq = dbf.getEntityManager().createQuery(sql, HostVO.class); - hq.setParameter("cuuids", clusterUuids); - hq.setParameter("huuids", hostUuids); - - if (usePagination()) { - hq.setFirstResult(paginationInfo.getOffset()); - hq.setMaxResults(paginationInfo.getLimit()); - } + /* in normal case, there is no L2NetworkHostRefVO */ + List excludeHostUuids = Q.New(L2NetworkHostRefVO.class).in(L2NetworkHostRefVO_.l2NetworkUuid, l2uuids) + .notEq(L2NetworkHostRefVO_.attachStatus, L2NetworkAttachStatus.Attached) + .select(L2NetworkHostRefVO_.hostUuid).listValues(); + retHostUuids.removeAll(excludeHostUuids); + if (retHostUuids.isEmpty()){ + return new ArrayList<>(); + } - return hq.getResultList(); + for (AttachedL2NetworkAllocatorExtensionPoint extp : pluginRgty.getExtensionList(AttachedL2NetworkAllocatorExtensionPoint.class)) { + retHostUuids = extp.filter(retHostUuids, l2uuids); } + + if (retHostUuids.isEmpty()){ + return new ArrayList<>(); + } + + sql = "select h from HostVO h where h.uuid in (:huuids)"; + TypedQuery hq = dbf.getEntityManager().createQuery(sql, HostVO.class); + hq.setParameter("huuids", retHostUuids); + + if (usePagination()) { + hq.setFirstResult(paginationInfo.getOffset()); + hq.setMaxResults(paginationInfo.getLimit()); + } + + return hq.getResultList(); } @Override public void allocate() { if (spec.getL3NetworkUuids().isEmpty()) { - if (CoreGlobalProperty.UNIT_TEST_ON || spec.isAllowNoL3Networks()) { + if (spec.isAllowNoL3Networks()) { skip(); return; } else { - throw new CloudRuntimeException("l3Network uuids can not be empty AttachedL2NetworkAllocatorFlow"); + spec.setAllowNoL3Networks(true); + + String sql; + Set clusterUuids = new HashSet<>(); + clusterUuids.add(spec.getVmInstance().getClusterUuid()); + List hostUuids = null; + if (!amITheFirstFlow()) { + hostUuids = candidates.stream().map(HostVO::getUuid).collect(Collectors.toList()); + } + + if (hostUuids == null || hostUuids.isEmpty()) { + sql = "select h from HostVO h where h.clusterUuid in (:cuuids)"; + TypedQuery hq = dbf.getEntityManager().createQuery(sql, HostVO.class); + hq.setParameter("cuuids", clusterUuids); + if (usePagination()) { + hq.setFirstResult(paginationInfo.getOffset()); + hq.setMaxResults(paginationInfo.getLimit()); + } + candidates = hq.getResultList(); + } else { + sql = "select h from HostVO h where h.clusterUuid in (:cuuids) and h.uuid in (:huuids)"; + TypedQuery hq = dbf.getEntityManager().createQuery(sql, HostVO.class); + hq.setParameter("cuuids", clusterUuids); + hq.setParameter("huuids", hostUuids); + + if (usePagination()) { + hq.setFirstResult(paginationInfo.getOffset()); + hq.setMaxResults(paginationInfo.getLimit()); + } + candidates = hq.getResultList(); + } + + next(candidates); + logger.debug(String.format("vm clusteruuid:%s, candidates size:%s", spec.getVmInstance().getClusterUuid(), candidates.size())); + return; } } + List l3Uuids = spec.getL3NetworkUuids(); + List serviceL3s = new ArrayList<>(); + for (GetL3NetworkForVmNetworkService extp : pluginRgty.getExtensionList(GetL3NetworkForVmNetworkService.class)) { + serviceL3s.addAll(extp.getL3NetworkForVmNetworkService(spec.getVmInstance())); + } + if (!serviceL3s.isEmpty()) { + l3Uuids.addAll(serviceL3s.stream().map(L3NetworkInventory::getUuid).distinct().collect(Collectors.toList())); + } + + if (amITheFirstFlow()) { - candidates = allocate(spec.getL3NetworkUuids(), new ArrayList<>()); + candidates = allocate(l3Uuids, new ArrayList<>()); } else { - candidates = allocate(spec.getL3NetworkUuids(), getHostUuidsFromCandidates()); + candidates = allocate(l3Uuids, getHostUuidsFromCandidates()); } if (candidates.isEmpty()) { diff --git a/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java index 5248ea5792a..ed8ff7c9e05 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java @@ -14,6 +14,7 @@ import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeStatus; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; @@ -36,6 +37,10 @@ public void allocate() { } VmInstanceInventory vm = spec.getVmInstance(); + if (vm.getRootVolume() == null || !VolumeStatus.Ready.toString().equals(vm.getRootVolume().getStatus())) { + fail(Platform.operr("cannot find root volume of vm[uuid:%s]", vm.getUuid())); + } + List requiredPsUuids = CollectionUtils.transformToList(vm.getAllVolumes(), new Function() { @Override public String call(VolumeInventory arg) { diff --git a/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java index a0dc1a3b575..869f09b81c0 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java @@ -1,5 +1,6 @@ package org.zstack.compute.allocator; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; @@ -25,14 +26,14 @@ public class DesignatedHostAllocatorFlow extends AbstractHostAllocatorFlow { private DatabaseFacade dbf; @Transactional(readOnly = true) - private List allocate(String zoneUuid, String clusterUuid, String hostUuid, String hypervisorType) { + private List allocate(String zoneUuid, List clusterUuids, String hostUuid, String hypervisorType) { StringBuilder sql = new StringBuilder(); sql.append("select h from HostVO h where "); if (zoneUuid != null) { sql.append(String.format("h.zoneUuid = '%s' and ", zoneUuid)); } - if (clusterUuid != null) { - sql.append(String.format("h.clusterUuid = '%s' and ", clusterUuid)); + if (!CollectionUtils.isEmpty(clusterUuids)) { + sql.append(String.format("h.clusterUuid in ('%s') and ", String.join("','", clusterUuids))); } if (hostUuid != null) { sql.append(String.format("h.uuid = '%s' and ", hostUuid)); @@ -53,13 +54,13 @@ private List allocate(String zoneUuid, String clusterUuid, String hostUu } - private List allocate(List candidates, String zoneUuid, String clusterUuid, String hostUuid, String hypervisorType) { + private List allocate(List candidates, String zoneUuid, List clusterUuids, String hostUuid, String hypervisorType) { List ret = new ArrayList(candidates.size()); for (HostVO h : candidates) { if (zoneUuid != null && !h.getZoneUuid().equals(zoneUuid)) { continue; } - if (clusterUuid != null && !h.getClusterUuid().equals(clusterUuid)) { + if (!CollectionUtils.isEmpty(clusterUuids) && !clusterUuids.contains(h.getClusterUuid())) { continue; } if (hostUuid != null && !h.getUuid().equals(hostUuid)) { @@ -76,18 +77,18 @@ private List allocate(List candidates, String zoneUuid, String c @Override public void allocate() { String zoneUuid = (String) spec.getExtraData().get(HostAllocatorConstant.LocationSelector.zone); - String clusterUuid = (String) spec.getExtraData().get(HostAllocatorConstant.LocationSelector.cluster); + List clusterUuids = (List) spec.getExtraData().get(HostAllocatorConstant.LocationSelector.cluster); String hostUuid = (String) spec.getExtraData().get(HostAllocatorConstant.LocationSelector.host); - if (zoneUuid == null && clusterUuid == null && hostUuid == null && spec.getHypervisorType() == null) { + if (zoneUuid == null && CollectionUtils.isEmpty(clusterUuids) && hostUuid == null && spec.getHypervisorType() == null) { next(candidates); return; } if (amITheFirstFlow()) { - candidates = allocate(zoneUuid, clusterUuid, hostUuid, spec.getHypervisorType()); + candidates = allocate(zoneUuid, clusterUuids, hostUuid, spec.getHypervisorType()); } else { - candidates = allocate(candidates, zoneUuid, clusterUuid, hostUuid, spec.getHypervisorType()); + candidates = allocate(candidates, zoneUuid, clusterUuids, hostUuid, spec.getHypervisorType()); } if (candidates.isEmpty()) { @@ -95,8 +96,8 @@ public void allocate() { if (zoneUuid != null) { args.append(String.format("zoneUuid=%s", zoneUuid)).append(" "); } - if (clusterUuid != null) { - args.append(String.format("clusterUuid=%s", clusterUuid)).append(" "); + if (!clusterUuids.isEmpty()) { + args.append(String.format("clusterUuid in %s", clusterUuids)).append(" "); } if (hostUuid != null) { args.append(String.format("hostUuid=%s", hostUuid)).append(" "); diff --git a/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorStrategyFactory.java b/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorStrategyFactory.java index 2a79e7f3671..3442f493018 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorStrategyFactory.java +++ b/compute/src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorStrategyFactory.java @@ -14,7 +14,7 @@ public HostAllocatorStrategyType getHostAllocatorStrategyType() { public void marshalSpec(HostAllocatorSpec spec, AllocateHostMsg msg) { DesignatedAllocateHostMsg dmsg = (DesignatedAllocateHostMsg)msg; spec.getExtraData().put(HostAllocatorConstant.LocationSelector.zone, dmsg.getZoneUuid()); - spec.getExtraData().put(HostAllocatorConstant.LocationSelector.cluster, dmsg.getClusterUuid()); + spec.getExtraData().put(HostAllocatorConstant.LocationSelector.cluster, dmsg.getClusterUuids()); spec.getExtraData().put(HostAllocatorConstant.LocationSelector.host, dmsg.getHostUuid()); } } diff --git a/compute/src/main/java/org/zstack/compute/allocator/FilterFlow.java b/compute/src/main/java/org/zstack/compute/allocator/FilterFlow.java index 108edec633f..9aae0ea18f8 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/FilterFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/FilterFlow.java @@ -6,7 +6,6 @@ import org.zstack.header.allocator.AbstractHostAllocatorFlow; import org.zstack.header.allocator.HostAllocatorFilterExtensionPoint; import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.exception.CloudRuntimeException; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -21,9 +20,7 @@ public class FilterFlow extends AbstractHostAllocatorFlow { @Override public void allocate() { - if (amITheFirstFlow()) { - throw new CloudRuntimeException(String.format("FilterFlow cannot be the first flow in the host allocator chains")); - } + throwExceptionIfIAmTheFirstFlow(); for (HostAllocatorFilterExtensionPoint filter : pluginRgty.getExtensionList(HostAllocatorFilterExtensionPoint.class)) { logger.debug(String.format("before being filtered by HostAllocatorFilterExtensionPoint[%s], candidates num: %s", filter.getClass(), candidates.size())); diff --git a/compute/src/main/java/org/zstack/compute/allocator/GetL3NetworkForVmNetworkService.java b/compute/src/main/java/org/zstack/compute/allocator/GetL3NetworkForVmNetworkService.java new file mode 100644 index 00000000000..47d42ea8242 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/allocator/GetL3NetworkForVmNetworkService.java @@ -0,0 +1,10 @@ +package org.zstack.compute.allocator; + +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmInstanceInventory; + +import java.util.List; + +public interface GetL3NetworkForVmNetworkService { + List getL3NetworkForVmNetworkService(VmInstanceInventory vm); +} diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorChain.java b/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorChain.java index 2e622e3ab82..a334126224b 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorChain.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorChain.java @@ -145,7 +145,7 @@ private void runFlow(AbstractHostAllocatorFlow flow) { } } catch (Throwable t) { logger.warn("unhandled throwable", t); - completion.fail(inerr(t.getMessage())); + completion.fail(inerr(t.toString())); } } @@ -220,7 +220,8 @@ public boolean isFirstFlow(AbstractHostAllocatorFlow flow) { return flows.indexOf(flow) == skipCounter; } - private void fail(ErrorCode errorCode) { + @Override + public void fail(ErrorCode errorCode) { result = null; if (seriesErrorWhenPagination.isEmpty()) { logger.debug(String.format("[Host Allocation] flow[%s] failed to allocate host; %s", diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorGlobalConfig.java b/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorGlobalConfig.java index 3d43aaa45f6..d323e5676f5 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorGlobalConfig.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorGlobalConfig.java @@ -28,4 +28,6 @@ public class HostAllocatorGlobalConfig { public static GlobalConfig HOST_ALLOCATOR_CONCURRENT_LEVEL = new GlobalConfig(CATEGORY, "hostAllocator.concurrent.level"); @GlobalConfigValidation public static GlobalConfig HOST_ALLOCATOR_MAX_MEMORY = new GlobalConfig(CATEGORY, "hostAllocator.checkHostMem"); + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig MIGRATION_BETWEEN_DIFFERENT_OS = new GlobalConfig(CATEGORY, "migration.differentOs"); } diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorManagerImpl.java b/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorManagerImpl.java index 4fd1b23e230..814cf91b83a 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostAllocatorManagerImpl.java @@ -286,6 +286,7 @@ private void handle(ReportHostCapacityMessage msg) { vo.setAvailablePhysicalMemory(availMem); vo.setCpuNum(msg.getCpuNum()); vo.setCpuSockets(msg.getCpuSockets()); + vo.setCpuCoreNum(msg.getCpuCoreNum()); HostCapacityStruct s = new HostCapacityStruct(); s.setCpuSockets(vo.getCpuSockets()); @@ -308,6 +309,7 @@ private void handle(ReportHostCapacityMessage msg) { vo.setAvailablePhysicalMemory(availMem); vo.setTotalMemory(msg.getTotalMemory()); vo.setCpuSockets(msg.getCpuSockets()); + vo.setCpuCoreNum(msg.getCpuCoreNum()); HostCapacityStruct s = new HostCapacityStruct(); s.setCapacityVO(vo); @@ -327,10 +329,10 @@ private void handle(ReportHostCapacityMessage msg) { } private boolean needUpdateCapacity(HostCapacityVO vo, ReportHostCapacityMessage msg, long totalCpu, long avaliCpu, long availMem) { - return vo.getCpuNum() != msg.getCpuNum() || vo.getTotalCpu() != totalCpu + return vo.getCpuNum() != msg.getCpuNum() || vo.getTotalCpu() != totalCpu || vo.getAvailableCpu() != avaliCpu || vo.getTotalPhysicalMemory() != msg.getTotalMemory() || vo.getAvailablePhysicalMemory() != availMem || vo.getTotalMemory() != msg.getTotalMemory() - || vo.getCpuSockets() != msg.getCpuSockets(); + || vo.getCpuSockets() != msg.getCpuSockets() || vo.getCpuCoreNum() != msg.getCpuCoreNum(); } private void handle(final AllocateHostMsg msg) { @@ -407,8 +409,10 @@ private void doHandleAllocateHost(final AllocateHostMsg msg, Completion completi DesignatedAllocateHostMsg dmsg = (DesignatedAllocateHostMsg) msg; if (dmsg.getHostUuid() != null) { hvType = Q.New(HostVO.class).eq(HostVO_.uuid, dmsg.getHostUuid()).select(HostVO_.hypervisorType).findValue(); - } else if (dmsg.getClusterUuid() != null) { - hvType = Q.New(ClusterVO.class).eq(ClusterVO_.uuid, dmsg.getClusterUuid()).select(ClusterVO_.hypervisorType).findValue(); + } else if (!org.apache.commons.collections.CollectionUtils.isEmpty(dmsg.getClusterUuids())) { + List hvTypes = Q.New(ClusterVO.class).in(ClusterVO_.uuid, dmsg.getClusterUuids()) + .groupBy(ClusterVO_.hypervisorType).select(ClusterVO_.hypervisorType).listValues(); + hvType = hvTypes.size() == 1 ? hvTypes.get(0) : null; } } @@ -623,9 +627,9 @@ private void calcElementCap(List tuples, CpuMemCapacity res) { if (msg.getHostUuids() != null) { rc = reserveMgr.getReservedHostCapacityByHosts(list(eUuid)); } else if (msg.getClusterUuids() != null) { - rc = reserveMgr.getReservedHostCapacityByClusters(list(eUuid)); + rc = reserveMgr.getReservedHostCapacityByClusters(list(eUuid), msg.getHypervisorType()); } else if (msg.getZoneUuids() != null) { - rc = reserveMgr.getReservedHostCapacityByZones(list(eUuid)); + rc = reserveMgr.getReservedHostCapacityByZones(list(eUuid), msg.getHypervisorType()); } else { throw new CloudRuntimeException("should not be here"); } @@ -872,6 +876,8 @@ public void run(FlowTrigger trigger, Map data) { vmMigrateToAnotherHost(trigger); } else if (operation == VmAbnormalLifeCycleOperation.VmRunningFromIntermediateState) { vmRunningFromIntermediateState(trigger); + } else if (operation == VmAbnormalLifeCycleOperation.VmNoStateFromIntermediateState) { + vmRunningFromIntermediateState(trigger); } else if (operation == VmAbnormalLifeCycleOperation.VmStoppedOnTheSameHost) { vmStoppedOnTheSameHost(trigger); } else if (operation == VmAbnormalLifeCycleOperation.VmRunningFromUnknownStateHostChanged) { diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java index 45b1ef6d27f..906901b20eb 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java @@ -8,7 +8,6 @@ import org.zstack.header.allocator.AbstractHostAllocatorFlow; import org.zstack.header.allocator.HostCapacityOverProvisioningManager; import org.zstack.header.allocator.HostCpuOverProvisioningManager; -import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostVO; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -41,11 +40,9 @@ private boolean memoryCheck(long vmMemSize, long oldMemory, HostVO hvo) { private List allocate(List vos, long cpu, long memory, long oldMemory) { - List ret = vos.stream() + return vos.parallelStream() .filter(hvo -> (cpu == 0 || hvo.getCapacity().getAvailableCpu() >= cpu) && (memory == 0 || memoryCheck(memory, oldMemory, hvo))).collect(Collectors.toList()); - - return ret; } private boolean isNoCpu(int cpu) { @@ -58,13 +55,10 @@ private boolean isNoMemory(long mem) { @Override public void allocate() { - List ret; - if (amITheFirstFlow()) { - throw new CloudRuntimeException("HostCapacityAllocatorFlow cannot be the first allocator flow"); - } else { - ret = allocate(candidates, spec.getCpuCapacity(), spec.getMemoryCapacity(), spec.getOldMemoryCapacity()); - } + throwExceptionIfIAmTheFirstFlow(); + List ret = + allocate(candidates, spec.getCpuCapacity(), spec.getMemoryCapacity(), spec.getOldMemoryCapacity()); ret = reserveMgr.filterOutHostsByReservedCapacity(ret, spec.getCpuCapacity(), spec.getMemoryCapacity()); if (ret.isEmpty()) { diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManager.java b/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManager.java index b42a36dbffa..83a3ec82ae0 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManager.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManager.java @@ -10,9 +10,9 @@ public interface HostCapacityReserveManager { List filterOutHostsByReservedCapacity(List candidates, long requiredCpu, long requiredMemory); - ReservedHostCapacity getReservedHostCapacityByZones(List zoneUuids); + ReservedHostCapacity getReservedHostCapacityByZones(List zoneUuids, String hypervisorType); - ReservedHostCapacity getReservedHostCapacityByClusters(List clusterUuids); + ReservedHostCapacity getReservedHostCapacityByClusters(List clusterUuids, String hypervisorType); ReservedHostCapacity getReservedHostCapacityByHosts(List hostUuids); diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManagerImpl.java b/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManagerImpl.java index 82cc33e2b5e..aa4a0a6de31 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostCapacityReserveManagerImpl.java @@ -6,19 +6,26 @@ import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.header.Component; -import org.zstack.header.allocator.*; +import org.zstack.header.allocator.HostCapacityOverProvisioningManager; +import org.zstack.header.allocator.HostReservedCapacityExtensionPoint; +import org.zstack.header.allocator.ReservedHostCapacity; +import org.zstack.header.allocator.UnableToReserveHostCapacityException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostState; import org.zstack.header.host.HostStatus; import org.zstack.header.host.HostVO; import org.zstack.header.host.HostVO_; -import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; -import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; import javax.persistence.Tuple; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** */ @@ -58,35 +65,48 @@ public boolean stop() { } private class ReservedCapacityFinder { + String hypervisorType; List hostUuids; - Map result = new HashMap<>(); + Map result = new ConcurrentHashMap<>(); private void findReservedCapacityByHypervisorType() { + if (hypervisorType != null && !exts.containsKey(hypervisorType)) { + logger.debug(String.format("cannot find HostReservedCapacityExtensionPoint for hypervisor type[%s], skip to find reserved capacity", hypervisorType)); + return; + } + SimpleQuery hq = dbf.createQuery(HostVO.class); hq.select(HostVO_.uuid, HostVO_.hypervisorType); hq.add(HostVO_.uuid, Op.IN, hostUuids); hq.add(HostVO_.state,Op.EQ, HostState.Enabled); hq.add(HostVO_.status,Op.EQ, HostStatus.Connected); - List tuples = hq.listTuple(); + List tuples = hq.listTuple(); + Map> hypervisorTypeMap = new HashMap<>(); for (Tuple t : tuples) { String huuid = t.get(0, String.class); - String hvType = t.get(1, String.class); + String htype = t.get(1, String.class); + List lst = hypervisorTypeMap.computeIfAbsent(htype, k -> new ArrayList<>()); + lst.add(huuid); + } + + if (logger.isTraceEnabled()) { + logger.trace(String.format("find reserved capacity for hypervisor type[%s], hosts: %s", hypervisorType, hypervisorTypeMap)); + } - HostReservedCapacityExtensionPoint ext = exts.get(hvType); + hypervisorTypeMap.keySet().forEach(key -> { + HostReservedCapacityExtensionPoint ext = exts.get(key); if (ext == null) { - continue; + return; } - ReservedHostCapacity hc = result.get(huuid); - ReservedHostCapacity extHc = ext.getReservedHostCapacity(huuid); - if (hc.getReservedMemoryCapacity() == -1) { - hc.setReservedMemoryCapacity(extHc.getReservedMemoryCapacity()); - } - if (hc.getReservedCpuCapacity() == -1) { - hc.setReservedCpuCapacity(extHc.getReservedCpuCapacity()); + if (logger.isTraceEnabled()) { + logger.trace(String.format("find reserved capacity for hypervisor type[%s], hosts: %s", key, hypervisorTypeMap.get(key))); } - } + + Map results = ext.getReservedHostsCapacity(hypervisorTypeMap.get(key)); + result.putAll(results); + }); } private void squeeze() { @@ -128,42 +148,36 @@ Map find() { @Override public List filterOutHostsByReservedCapacity(List candidates, long requiredCpu, long requiredMemory) { ReservedCapacityFinder finder = new ReservedCapacityFinder(); - finder.hostUuids = CollectionUtils.transformToList(candidates, new Function() { - @Override - public String call(HostVO arg) { - return arg.getUuid(); - } - }); + finder.hostUuids = candidates.stream().map(HostVO::getUuid).collect(Collectors.toList()); Map reserves = finder.find(); - List ret = new ArrayList<>(candidates.size()); - for (HostVO hvo : candidates) { - ReservedHostCapacity hc = reserves.get(hvo.getUuid()); - if (requiredMemory == 0 || hvo.getCapacity().getAvailableMemory() - hc.getReservedMemoryCapacity() >= ratioMgr.calculateMemoryByRatio(hvo.getUuid(), requiredMemory)) { - ret.add(hvo); - } else { - if (logger.isTraceEnabled()) { - if (hvo.getCapacity().getAvailableMemory() - hc.getReservedMemoryCapacity() < requiredMemory) { - logger.trace(String.format("remove host[uuid:%s] from candidates;because after subtracting reserved memory[%s bytes]," + - " it cannot provide required memory[%s bytes]", - hvo.getUuid(), hc.getReservedMemoryCapacity(), requiredMemory)); + return candidates.parallelStream() + .filter(hvo -> { + ReservedHostCapacity hc = reserves.get(hvo.getUuid()); + if (requiredMemory == 0 || hvo.getCapacity().getAvailableMemory() - hc.getReservedMemoryCapacity() >= ratioMgr.calculateMemoryByRatio(hvo.getUuid(), requiredMemory)) { + return true; + } else { + if (logger.isTraceEnabled()) { + if (hvo.getCapacity().getAvailableMemory() - hc.getReservedMemoryCapacity() < requiredMemory) { + logger.trace(String.format("remove host[uuid:%s] from candidates;because after subtracting reserved memory[%s bytes]," + + " it cannot provide required memory[%s bytes]", + hvo.getUuid(), hc.getReservedMemoryCapacity(), requiredMemory)); + } + + if (hvo.getCapacity().getAvailableCpu() - hc.getReservedCpuCapacity() < requiredCpu) { + logger.trace(String.format("remove host[uuid:%s] from candidates;because after subtracting reserved cpu[%s]," + + " it cannot provide required cpu[%s]", + hvo.getUuid(), hc.getReservedCpuCapacity(), requiredCpu)); + } + } + return false; } - - if (hvo.getCapacity().getAvailableCpu() - hc.getReservedCpuCapacity() < requiredCpu) { - logger.trace(String.format("remove host[uuid:%s] from candidates;because after subtracting reserved cpu[%s]," + - " it cannot provide required cpu[%s]", - hvo.getUuid(), hc.getReservedCpuCapacity(), requiredCpu)); - } - } - } - - } - - return ret; + }) + .collect(Collectors.toList()); } @Override - public ReservedHostCapacity getReservedHostCapacityByZones(List zoneUuids) { + public ReservedHostCapacity getReservedHostCapacityByZones(List zoneUuids, String hypervisorType) { ReservedHostCapacity ret = new ReservedHostCapacity(); ret.setReservedCpuCapacity(0); ret.setReservedMemoryCapacity(0); @@ -171,6 +185,9 @@ public ReservedHostCapacity getReservedHostCapacityByZones(List zoneUuid SimpleQuery q = dbf.createQuery(HostVO.class); q.select(HostVO_.uuid); q.add(HostVO_.zoneUuid, Op.IN, zoneUuids); + if (hypervisorType != null) { + q.add(HostVO_.hypervisorType, Op.EQ, hypervisorType); + } List huuids = q.listValue(); if (huuids.isEmpty()) { return ret; @@ -188,7 +205,7 @@ public ReservedHostCapacity getReservedHostCapacityByZones(List zoneUuid } @Override - public ReservedHostCapacity getReservedHostCapacityByClusters(List clusterUuids) { + public ReservedHostCapacity getReservedHostCapacityByClusters(List clusterUuids, String hypervisorType) { ReservedHostCapacity ret = new ReservedHostCapacity(); ret.setReservedCpuCapacity(0); ret.setReservedMemoryCapacity(0); @@ -196,6 +213,9 @@ public ReservedHostCapacity getReservedHostCapacityByClusters(List clust SimpleQuery q = dbf.createQuery(HostVO.class); q.select(HostVO_.uuid); q.add(HostVO_.clusterUuid, Op.IN, clusterUuids); + if (hypervisorType != null) { + q.add(HostVO_.hypervisorType, Op.EQ, hypervisorType); + } List huuids = q.listValue(); if (huuids.isEmpty()) { return ret; @@ -203,6 +223,7 @@ public ReservedHostCapacity getReservedHostCapacityByClusters(List clust ReservedCapacityFinder finder = new ReservedCapacityFinder(); finder.hostUuids = huuids; + finder.hypervisorType = hypervisorType; Collection col = finder.find().values(); for (ReservedHostCapacity rc : col) { ret.setReservedMemoryCapacity(ret.getReservedMemoryCapacity() + rc.getReservedMemoryCapacity()); @@ -245,7 +266,7 @@ private void reserveCapacityWithChecking(String hostUuid, long requestCpu, long updater.run(cap -> { long availCpu = cap.getAvailableCpu() - requestCpu; - if (requestCpu != 0 && availCpu < 0) { + if (requestCpu != 0 && availCpu - ret.getReservedCpuCapacity() < 0) { throw new UnableToReserveHostCapacityException( String.format("no enough CPU[%s] on the host[uuid:%s]", requestCpu, hostUuid)); } diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java index 13712a8702f..30ac288c8dd 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java @@ -1,67 +1,100 @@ package org.zstack.compute.allocator; import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.compute.host.HostSystemTags; +import org.zstack.compute.host.HostManager; import org.zstack.core.Platform; +import org.zstack.core.db.Q; import org.zstack.header.allocator.AbstractHostAllocatorFlow; -import org.zstack.header.host.HostVO; +import org.zstack.header.allocator.HostAllocatorConstant; +import org.zstack.header.host.*; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vo.ResourceVO; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.zstack.utils.CollectionUtils.*; /** + * Filter out hosts that do not match the operating system of the specific host */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class HostOsVersionAllocatorFlow extends AbstractHostAllocatorFlow { + @Autowired + private HostManager manager; + private static CLogger logger = Utils.getLogger(HostOsVersionAllocatorFlow.class); + @Override public void allocate() { + if (HostAllocatorConstant.MIGRATE_VM_ALLOCATOR_TYPE.equals(spec.getAllocatorStrategy()) && + HostAllocatorGlobalConfig.MIGRATION_BETWEEN_DIFFERENT_OS.value(Boolean.class)) { + logger.debug("allow migration between hosts with different os, skip checking the target host os"); + next(candidates); + return; + } throwExceptionIfIAmTheFirstFlow(); - Map hostMap = new HashMap(); - for (HostVO h : candidates) { - hostMap.put(h.getUuid(), h); + Map hostMap = toMap(candidates, HostVO::getUuid, Function.identity()); + final VmInstanceInventory vm = spec.getVmInstance(); + String currentHostUuid = vm.getHostUuid() == null ? vm.getLastHostUuid() : vm.getHostUuid(); + if (currentHostUuid == null) { + logger.debug(String.format("VM[uuid:%s] never started on any host, skip host OS checker", vm.getUuid())); + next(candidates); + return; } - List hostUuids = new ArrayList(); - hostUuids.addAll(hostMap.keySet()); + List allHostList = new ArrayList<>(candidates); + final HostVO currentHost = Q.New(HostVO.class) + .eq(HostVO_.uuid, currentHostUuid) + .find(); + allHostList.add(currentHost); + final Map hostOsMap = generateHostUuidOsMap(allHostList); - String distro = HostSystemTags.OS_DISTRIBUTION.getTokenByResourceUuid(spec.getVmInstance().getHostUuid(), HostSystemTags.OS_DISTRIBUTION_TOKEN); - String release = HostSystemTags.OS_RELEASE.getTokenByResourceUuid(spec.getVmInstance().getHostUuid(), HostSystemTags.OS_RELEASE_TOKEN); - String version = HostSystemTags.OS_VERSION.getTokenByResourceUuid(spec.getVmInstance().getHostUuid(), HostSystemTags.OS_VERSION_TOKEN); - String currentVersion = String.format("%s;%s;%s", distro, release, version); + final HostOperationSystem currentHostOs = hostOsMap.get(currentHostUuid); + allHostList.remove(currentHost); - Map> distroMap = HostSystemTags.OS_DISTRIBUTION.getTags(hostUuids); - Map> releaseMap = HostSystemTags.OS_RELEASE.getTags(hostUuids); - Map> versionMap = HostSystemTags.OS_VERSION.getTags(hostUuids); + List matchedHosts = allHostList.stream() + .map(HostVO::getUuid) + .filter(hostUuid -> { + final HostOperationSystem hostOs = hostOsMap.get(hostUuid); + return hostOs == null ? true : hostOs.equals(currentHostOs); + }) + .map(hostMap::get) + .collect(Collectors.toList()); - Map candidateVersions = new HashMap(); - for (String huuid : hostUuids) { - List ds = distroMap.get(huuid); - String d = ds == null ? null : HostSystemTags.OS_DISTRIBUTION.getTokenByTag(ds.get(0), HostSystemTags.OS_DISTRIBUTION_TOKEN); - List rs = releaseMap.get(huuid); - String r = rs == null ? null : HostSystemTags.OS_RELEASE.getTokenByTag(rs.get(0), HostSystemTags.OS_RELEASE_TOKEN); - List vs = versionMap.get(huuid); - String v = vs == null ? null : HostSystemTags.OS_VERSION.getTokenByTag(vs.get(0), HostSystemTags.OS_VERSION_TOKEN); - candidateVersions.put(huuid, String.format("%s;%s;%s", d, r, v)); + if (matchedHosts.isEmpty()) { + fail(Platform.operr("no candidate host has version[%s]", currentHostOs)); + } else { + next(matchedHosts); } + } - List ret = new ArrayList(); - for (Entry e : candidateVersions.entrySet()) { - String huuid = e.getKey(); - String ver = e.getValue(); - if (ver.equals(currentVersion)) { - ret.add(hostMap.get(huuid)); + private Map generateHostUuidOsMap(List hostList) { + final Map hostHypervisorTypeMap = hostList.stream() + .collect(Collectors.toMap(ResourceVO::getUuid, HostAO::getHypervisorType, + (existing, replacement) -> replacement)); + final Set hypervisorTypeSet = new HashSet<>(hostHypervisorTypeMap.values()); + + final Map results = new HashMap<>(hostList.size()); + for (String hypervisorTypeString : hypervisorTypeSet) { + final HypervisorFactory factory = manager.getHypervisorFactory( + HypervisorType.valueOf(hypervisorTypeString)); + final List hostsWithThisHypervisorType = hostHypervisorTypeMap.entrySet().stream() + .filter(entry -> hypervisorTypeString.equals(entry.getValue())) + .map(Entry::getKey) + .collect(Collectors.toList()); + + if (factory.supportGetHostOs()) { + results.putAll(factory.getHostOsMap(hostsWithThisHypervisorType)); } } - if (ret.isEmpty()) { - fail(Platform.operr("no candidate host has version[%s]", currentVersion)); - } else { - next(ret); - } + return results; } } diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java index 5e72b3a1ecf..b2ace6d403b 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java @@ -9,11 +9,12 @@ import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.header.allocator.AbstractHostAllocatorFlow; -import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.allocator.HostAllocatorSpec; import org.zstack.header.host.HostVO; import org.zstack.header.storage.primary.*; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.vo.ResourceVO; +import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -30,15 +31,36 @@ public class HostPrimaryStorageAllocatorFlow extends AbstractHostAllocatorFlow { @Autowired private PrimaryStorageOverProvisioningManager ratioMgr; - private List filterHostHavingAccessiblePrimaryStorage(List huuids, Set requiredPsUuids, String vmOperation){ - String sqlappend = ""; + private List filterHostHavingAccessiblePrimaryStorage(List huuids, HostAllocatorSpec spec){ + String vmOperation = spec.getVmOperation(); + Set requiredPsUuids = spec.getRequiredPrimaryStorageUuids(); + List> optionalPrimaryStorageUuidList = spec.getOptionalPrimaryStorageUuids(); + StringBuilder sqlappend = new StringBuilder(); if (!requiredPsUuids.isEmpty()) { - sqlappend = requiredPsUuids.size() == 1 ? + sqlappend.append(requiredPsUuids.size() == 1 ? String.format(" and ps.uuid = '%s'", requiredPsUuids.iterator().next()) : String.format(" and ps.uuid in ('%s')" + " group by ref.clusterUuid" + " having count(distinct ref.primaryStorageUuid) = %d", - String.join("','", requiredPsUuids), requiredPsUuids.size()); + String.join("','", requiredPsUuids), requiredPsUuids.size())); + } + + List clusterUuids = null; + for (Set optionalPrimaryStorageUuids : optionalPrimaryStorageUuidList) { + if (CollectionUtils.isEmpty(optionalPrimaryStorageUuids)) { + continue; + } + List tmpClusterUuids = Q.New(PrimaryStorageClusterRefVO.class).select(PrimaryStorageClusterRefVO_.clusterUuid) + .in(PrimaryStorageClusterRefVO_.primaryStorageUuid, optionalPrimaryStorageUuids) + .listValues(); + clusterUuids = clusterUuids != null ? clusterUuids.stream().filter(tmpClusterUuids::contains).collect(Collectors.toList()) + : tmpClusterUuids; + if (clusterUuids.isEmpty()) { + return Collections.emptyList(); + } + } + if (clusterUuids != null) { + sqlappend.append(String.format(" and ref.clusterUuid in ('%s')", String.join("','", clusterUuids))); } String psStatus = ""; @@ -88,8 +110,30 @@ private List filterHostHavingAccessiblePrimaryStorage(List huuid " and host[uuids:%s], remove these hosts", requiredPsUuids, disconnectHostUuids)); Set discHostSet = new HashSet<>(disconnectHostUuids); hosts.removeIf(it -> discHostSet.contains(it.getUuid())); + hostUuids = hosts.stream().map(HostVO::getUuid).collect(Collectors.toList()); } + List connectedHostUuids = null; + for (Set optionalPrimaryStorageUuids : optionalPrimaryStorageUuidList) { + if (CollectionUtils.isEmpty(optionalPrimaryStorageUuids)) { + continue; + } + + List tmpHostUuids = Q.New(PrimaryStorageHostRefVO.class).select(PrimaryStorageHostRefVO_.hostUuid) + .in(PrimaryStorageHostRefVO_.primaryStorageUuid, optionalPrimaryStorageUuids) + .eq(PrimaryStorageHostRefVO_.status, PrimaryStorageHostStatus.Connected) + .in(PrimaryStorageHostRefVO_.hostUuid, hostUuids) + .listValues(); + connectedHostUuids = connectedHostUuids == null ? tmpHostUuids : connectedHostUuids.stream().filter(tmpHostUuids::contains) + .collect(Collectors.toList()); + if (connectedHostUuids.isEmpty()) { + return Collections.emptyList(); + } + } + if (connectedHostUuids != null) { + List finalConnectedHostUuids = connectedHostUuids; + hosts = hosts.stream().filter(h -> finalConnectedHostUuids.contains(h.getUuid())).collect(Collectors.toList()); + } return hosts; } @@ -98,12 +142,16 @@ private List allocateFromCandidates() { List huuids = getHostUuidsFromCandidates(); Set requiredPsUuids = spec.getRequiredPrimaryStorageUuids(); if (!VmOperation.NewCreate.toString().equals(spec.getVmOperation())) { - return filterHostHavingAccessiblePrimaryStorage(huuids, requiredPsUuids, spec.getVmOperation()); + return filterHostHavingAccessiblePrimaryStorage(huuids, spec); } else { - huuids = filterHostHavingAccessiblePrimaryStorage(huuids, requiredPsUuids, spec.getVmOperation()) + huuids = filterHostHavingAccessiblePrimaryStorage(huuids, spec) .stream().map(ResourceVO::getUuid).collect(Collectors.toList()); } + if (huuids.isEmpty()) { + return Collections.emptyList(); + } + // for new created vm String sql = "select ps.uuid" + " from PrimaryStorageClusterRefVO ref, PrimaryStorageVO ps, HostVO h" + @@ -229,9 +277,7 @@ private boolean hasCapablePS(String psUuid, Long cap, Map psIma @Override public void allocate() { - if (amITheFirstFlow()) { - throw new CloudRuntimeException("HostPrimaryStorageAllocatorFlow cannot be the first flow in the chain"); - } + throwExceptionIfIAmTheFirstFlow(); candidates = allocateFromCandidates(); diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostSortorChain.java b/compute/src/main/java/org/zstack/compute/allocator/HostSortorChain.java index 680b3bd7880..a96ac0db751 100644 --- a/compute/src/main/java/org/zstack/compute/allocator/HostSortorChain.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostSortorChain.java @@ -3,7 +3,6 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.errorcode.ErrorFacade; @@ -25,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import static org.zstack.core.Platform.operr; @@ -46,6 +46,7 @@ public class HostSortorChain implements HostSortorStrategy { private List flows; private boolean isDryRun = false; + private boolean skipReserveCapacity = false; private ReturnValueCompletion completion; private ReturnValueCompletion> dryRunCompletion; @@ -57,6 +58,10 @@ public void setFlows(List flows) { this.flows = flows; } + public void setSkipReserveCapacity(boolean skipReserveCapacity) { + this.skipReserveCapacity = skipReserveCapacity; + } + @Override public void sort(HostAllocatorSpec spec, List hosts, ReturnValueCompletion completion) { allocationSpec = spec; @@ -166,40 +171,36 @@ public void handle(ErrorCode errCode, Map data) { private void done(List hosts) { if (isDryRun) { dryRunCompletion.success(hosts); - } else { - try { - List selectedHosts = new ArrayList<>(); - List errs = new ArrayList<>(); - new While<>(hosts).each((h, wcmpl) -> { - reserveHost(h, new Completion(wcmpl) { - @Override - public void success() { - selectedHosts.add(h); - /* alldone() will break the new While loop */ - wcmpl.allDone(); - } + return; + } + if (skipReserveCapacity) { + completion.success(hosts.iterator().next()); + return; + } - @Override - public void fail(ErrorCode errorCode) { - errs.add(errorCode); - wcmpl.done(); - } - }); - }).run(new WhileDoneCompletion(completion) { - @Override - public void done(ErrorCodeList errorCodeList) { - if (!selectedHosts.isEmpty()) { - completion.success(selectedHosts.get(0)); - } else { - /* return the error of last host */ - completion.fail(errs.get(errs.size() - 1)); - } - } - }); - } catch (Throwable t) { - completion.fail(Platform.inerr(t.getMessage())); + AtomicReference selectedHost = new AtomicReference<>(); + new While<>(hosts).each((host, whileCompletion) -> reserveHost(host, new Completion(whileCompletion) { + @Override + public void success() { + selectedHost.set(host); + whileCompletion.allDone(); // break the new While loop: we only need one host } - } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.done(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (selectedHost.get() == null) { + completion.fail(errorCodeList); + return; + } + completion.success(selectedHost.get()); + } + }); } private void reserveCapacity(final HostInventory host) { diff --git a/compute/src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java index 6bdd828ff0f..2eac9c8abd8 100755 --- a/compute/src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java @@ -83,6 +83,7 @@ public void allocate() { if (CollectionUtils.isEmpty(candidates)) { fail(operr("no host having state=Enabled status=Connected hypervisorType=%s found", spec.getHypervisorType())); + return; } ErrorCode error; diff --git a/compute/src/main/java/org/zstack/compute/allocator/QuotaAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/QuotaAllocatorFlow.java index 7e4a0b61a50..4d9d469c796 100644 --- a/compute/src/main/java/org/zstack/compute/allocator/QuotaAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/QuotaAllocatorFlow.java @@ -8,10 +8,48 @@ import org.zstack.identity.Account; import org.zstack.identity.QuotaUtil; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.db.DatabaseFacade; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.utils.logging.CLogger; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.core.db.Q; +import org.zstack.utils.Utils; +import org.zstack.core.db.SimpleQuery; +import org.zstack.header.host.*; +import javax.persistence.TypedQuery; +import java.util.*; + + @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class QuotaAllocatorFlow extends AbstractHostAllocatorFlow { + private static final CLogger logger = Utils.getLogger(QuotaAllocatorFlow.class); + + @Autowired + private DatabaseFacade dbf; + @Override public void allocate() { + if (CoreGlobalProperty.UNIT_TEST_ON) { + if (candidates == null || candidates.isEmpty()) { + String sql = "select h from HostVO h where h.clusterUuid in (:cuuids)"; + Set clusterUuids = new HashSet<>(); + clusterUuids.add(spec.getVmInstance().getClusterUuid()); + + TypedQuery hq = dbf.getEntityManager().createQuery(sql, HostVO.class); + hq.setParameter("cuuids", clusterUuids); + if (usePagination()) { + hq.setFirstResult(paginationInfo.getOffset()); + hq.setMaxResults(paginationInfo.getLimit()); + } + candidates = hq.getResultList(); + logger.debug(String.format("vm clusteruuid:%s, candidates size:%s", spec.getVmInstance().getClusterUuid(), candidates.size())); + next(candidates); + } + } + throwExceptionIfIAmTheFirstFlow(); final String vmInstanceUuid = spec.getVmInstance().getUuid(); diff --git a/compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java b/compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java index 9135e6d25db..5cb565683f4 100644 --- a/compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java +++ b/compute/src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java @@ -13,7 +13,6 @@ import org.zstack.header.allocator.AllocationScene; import org.zstack.header.allocator.ResourceBindingCollector; import org.zstack.header.allocator.ResourceBindingStrategy; -import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostVO; import org.zstack.resourceconfig.ResourceConfigFacade; @@ -43,9 +42,10 @@ public class ResourceBindingAllocatorFlow extends AbstractHostAllocatorFlow { } } - private Map> getBindedResources() { + private Map> getBindedResourcesFromTag() { String resources = VmSystemTags.VM_RESOURCE_BINGDING .getTokenByResourceUuid(spec.getVmInstance().getUuid(), VmSystemTags.VM_RESOURCE_BINGDING_TOKEN); + if (StringUtils.isEmpty(resources)) { return null; } @@ -76,17 +76,35 @@ private boolean validateAllocationScene() { @Override public void allocate() { - if (amITheFirstFlow()) { - throw new CloudRuntimeException("ResourceBindingAllocatorFlow cannot be the first flow in the chain"); - } + throwExceptionIfIAmTheFirstFlow(); - if (!validateAllocationScene() || !VmSystemTags.VM_RESOURCE_BINGDING.hasTag(spec.getVmInstance().getUuid())) { + Boolean resourceConfig = rcf.getResourceConfigValue(VmGlobalConfig.VM_HA_ACROSS_CLUSTERS, spec.getVmInstance().getUuid(), Boolean.class); + if (!validateAllocationScene() || (!VmSystemTags.VM_RESOURCE_BINGDING.hasTag(spec.getVmInstance().getUuid()) && resourceConfig)) { next(candidates); return; } - Map> resources = getBindedResources(); - if (resources == null || resources.isEmpty()) { + // get bind resources from system tag + Map> resources = getBindedResourcesFromTag(); + resources = resources != null ? resources : new HashMap<>(); + // get bind resources from config + ResourceBindingClusterCollector clusterCollector = new ResourceBindingClusterCollector(); + if (!resourceConfig) { + //remove bind cluster uuid from system tag, use current cluster uuid from config + if (resources.containsKey(clusterCollector.getType())) { + List uuids = resources.get(clusterCollector.getType()); + if (!uuids.contains(spec.getVmInstance().getClusterUuid())) { + String tag = String.format("Cluster:%s", spec.getVmInstance().getClusterUuid()); + VmSystemTags.VM_RESOURCE_BINGDING.updateTagByToken(spec.getVmInstance().getUuid(), + VmSystemTags.VM_RESOURCE_BINGDING_TOKEN, tag); + } + resources.remove(clusterCollector.getType()); + } + + resources.computeIfAbsent(clusterCollector.getType(), k -> new ArrayList<>()).add(spec.getVmInstance().getClusterUuid()); + } + + if (resources.isEmpty()) { next(candidates); return; } diff --git a/compute/src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java b/compute/src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java index f99bdc2e153..e835cdaf27a 100755 --- a/compute/src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java +++ b/compute/src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java @@ -73,6 +73,18 @@ protected void scripts() { )); } + if (msg.getHostUuid() != null && + !q(HostVO.class) + .eq(HostVO_.clusterUuid, msg.getUuid()) + .eq(HostVO_.uuid, msg.getHostUuid()) + .isExists()) { + throw new ApiMessageInterceptionException(Platform.argerr( + "The host[uuid: %s] is not part of the cluster[uuid: %s]. Please verify the host uuid and ensure it belongs to this cluster.", + msg.getHostUuid(), + msg.getUuid() + )); + } + // all hosts in the cluster must not be in the premaintenance state Long premaintain = q(HostVO.class) .eq(HostVO_.clusterUuid, msg.getUuid()) diff --git a/compute/src/main/java/org/zstack/compute/cluster/ClusterBase.java b/compute/src/main/java/org/zstack/compute/cluster/ClusterBase.java index 385987d6168..5d3da5d0ab6 100755 --- a/compute/src/main/java/org/zstack/compute/cluster/ClusterBase.java +++ b/compute/src/main/java/org/zstack/compute/cluster/ClusterBase.java @@ -1,5 +1,6 @@ package org.zstack.compute.cluster; +import edu.emory.mathcs.backport.java.util.Collections; import org.apache.logging.log4j.ThreadContext; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; @@ -37,13 +38,16 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.backup.AddBackupStorageStruct; import org.zstack.identity.AccountManager; import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.tag.TagManager; import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -120,8 +124,16 @@ private void handle(APIUpdateClusterOSMsg msg) { excludePackages = msg.getExcludePackages() == null ? "" :String.join(",", msg.getExcludePackages()); updatePackages = msg.getUpdatePackages() == null ? "" :String.join(",", msg.getUpdatePackages()); releaseVersion = msg.getReleaseVersion() == null ? "" :msg.getReleaseVersion(); - jobData = String.format("{'uuid':'%s', 'excludePackages':'%s', 'updatePackages':'%s', 'releaseVersion':'%s'}", - msg.getUuid(), excludePackages, updatePackages, releaseVersion); + LinkedHashMap jobDataMap = new LinkedHashMap<>(); + jobDataMap.put("uuid", msg.getUuid()); + jobDataMap.put("excludePackages", excludePackages); + jobDataMap.put("updatePackages", updatePackages); + jobDataMap.put("releaseVersion", releaseVersion); + if (msg.getHostUuid() != null) { + jobDataMap.put("hostUuid", msg.getHostUuid()); + } + jobDataMap.put("force", Boolean.toString(msg.isForce())); + jobData = JSONObjectUtil.toJsonString(jobDataMap); SubmitLongJobMsg smsg = new SubmitLongJobMsg(); smsg.setJobName(APIUpdateClusterOSMsg.class.getSimpleName()); @@ -294,8 +306,14 @@ protected void handleLocalMessage(Message msg) { private void handle(UpdateClusterOSMsg msg) { UpdateClusterOSReply reply = new UpdateClusterOSReply(); reply.setResults(new ConcurrentHashMap<>()); - - ErrorCode error = extpEmitter.preUpdateOS(self); + UpdateClusterOSStruct updateClusterOSStruct = new UpdateClusterOSStruct(); + updateClusterOSStruct.setCluster(self); + updateClusterOSStruct.setForce(msg.isForce()); + updateClusterOSStruct.setUpdatePackages(msg.getUpdatePackages()); + updateClusterOSStruct.setExcludePackages(msg.getExcludePackages()); + updateClusterOSStruct.setReleaseVersion(msg.getReleaseVersion()); + + ErrorCode error = extpEmitter.preUpdateOS(updateClusterOSStruct); if (error != null) { reply.setError(error); bus.reply(msg, reply); @@ -320,10 +338,16 @@ public void run(SyncTaskChain chain) { extpEmitter.beforeUpdateOS(self); // update each hosts os in the cluster - List hostUuids = Q.New(HostVO.class) - .select(HostVO_.uuid) - .eq(HostVO_.clusterUuid, msg.getUuid()) - .listValues(); + List hostUuids; + if (msg.getHostUuid() != null) { + hostUuids = Collections.singletonList(msg.getHostUuid()); + } else { + hostUuids = Q.New(HostVO.class) + .select(HostVO_.uuid) + .eq(HostVO_.clusterUuid, msg.getUuid()) + .listValues(); + } + Boolean enableExpRepo = rcf.getResourceConfigValue( ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_REPO, msg.getUuid(), Boolean.class); new While<>(hostUuids).all((hostUuid, completion) -> { diff --git a/compute/src/main/java/org/zstack/compute/cluster/ClusterExtensionPointEmitter.java b/compute/src/main/java/org/zstack/compute/cluster/ClusterExtensionPointEmitter.java index a43210c6a67..7f975ac3e97 100755 --- a/compute/src/main/java/org/zstack/compute/cluster/ClusterExtensionPointEmitter.java +++ b/compute/src/main/java/org/zstack/compute/cluster/ClusterExtensionPointEmitter.java @@ -100,13 +100,13 @@ public void run(ClusterDeleteExtensionPoint arg) { }); } - ErrorCode preUpdateOS(final ClusterVO cls) { + ErrorCode preUpdateOS(UpdateClusterOSStruct updateClusterOSStruct) { if (updateOSExts == null || updateOSExts.isEmpty()) { return null; } for (ClusterUpdateOSExtensionPoint ext : updateOSExts) { - String error = ext.preUpdateClusterOS(cls); + String error = ext.preUpdateClusterOS(updateClusterOSStruct); if (error != null) { return operr(error); } diff --git a/compute/src/main/java/org/zstack/compute/cluster/ClusterManagerImpl.java b/compute/src/main/java/org/zstack/compute/cluster/ClusterManagerImpl.java index 9841c69f83e..306d73e6088 100755 --- a/compute/src/main/java/org/zstack/compute/cluster/ClusterManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/cluster/ClusterManagerImpl.java @@ -1,6 +1,7 @@ package org.zstack.compute.cluster; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.cluster.arch.ClusterResourceConfigInitializer; import org.zstack.core.Platform; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.MessageSafe; @@ -17,8 +18,6 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.NeedReplyMessage; -import org.zstack.search.GetQuery; -import org.zstack.search.SearchQuery; import org.zstack.tag.TagManager; import org.zstack.utils.ObjectUtils; import org.zstack.utils.Utils; @@ -41,7 +40,8 @@ public class ClusterManagerImpl extends AbstractService implements ClusterManage private DbEntityLister dl; @Autowired private TagManager tagMgr; - + @Autowired + private ClusterResourceConfigInitializer crci; private Map clusterFactories = Collections.synchronizedMap(new HashMap()); private static final Set allowedMessageAfterSoftDeletion = new HashSet(); @@ -109,6 +109,8 @@ private void doCreateCluster(CreateClusterMessage msg, ReturnValueCompletion resourceConfigDefaultValueMap = new HashMap<>(); + private Map> resourceConfigValidValuesMap = new HashMap<>(); + + public void registerDefaultValue(String identity, String defaultValue) { + resourceConfigDefaultValueMap.put(identity, defaultValue); + } + + public void registerValidaValues(String identity, List validValues) { + resourceConfigValidValuesMap.put(identity, validValues); + } + + public Map getResourceConfigDefaultValueMap() { + return resourceConfigDefaultValueMap; + } + + public Map> getResourceConfigValidValuesMap() { + return resourceConfigValidValuesMap; + } + + public abstract String getArchitecture(); + + public Set getAutoSetIfNotConfiguredClusterResourceConfigSet() { + return resourceConfigDefaultValueMap.keySet(); + } + + public boolean clusterArchitectureMatched(String clusterUuid) { + String architecture = Q.New(ClusterVO.class) + .select(ClusterVO_.architecture) + .eq(ClusterVO_.uuid, clusterUuid) + .findValue(); + + return getArchitecture().equals(architecture); + } +} diff --git a/compute/src/main/java/org/zstack/compute/cluster/arch/ClusterResourceConfigInitializer.java b/compute/src/main/java/org/zstack/compute/cluster/arch/ClusterResourceConfigInitializer.java new file mode 100644 index 00000000000..c1a224d4194 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/cluster/arch/ClusterResourceConfigInitializer.java @@ -0,0 +1,11 @@ +package org.zstack.compute.cluster.arch; + +import org.zstack.header.cluster.ClusterInventory; + +/** + * @author Lei Liu lei.liu@zstack.io + * @date 2022/2/7 14:20 + */ +public interface ClusterResourceConfigInitializer { + public void initClusterResourceConfigValue(ClusterInventory cluster); +} diff --git a/compute/src/main/java/org/zstack/compute/cluster/arch/ClusterResourceConfigInitializerImpl.java b/compute/src/main/java/org/zstack/compute/cluster/arch/ClusterResourceConfigInitializerImpl.java new file mode 100644 index 00000000000..03b1f176837 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/cluster/arch/ClusterResourceConfigInitializerImpl.java @@ -0,0 +1,171 @@ +package org.zstack.compute.cluster.arch; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.config.GlobalConfigException; +import org.zstack.core.db.Q; +import org.zstack.header.Component; +import org.zstack.header.cluster.ClusterInventory; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.cluster.ClusterVO_; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; +import org.zstack.resourceconfig.*; +import org.zstack.utils.BeanUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.Tuple; +import java.util.*; + +/** + * @author Lei Liu lei.liu@zstack.io + * @date 2022/1/26 13:19 + */ + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class ClusterResourceConfigInitializerImpl implements ClusterResourceConfigInitializer, Component { + protected static final CLogger logger = Utils.getLogger(ClusterResourceConfigInitializerImpl.class); + protected Map> architectureClusterConfigValueMap = new HashMap<>(); + protected Map> autoSetClusterResourceConfigs = new HashMap<>(); + + @Autowired + private ResourceConfigFacade rcf; + + @Override + public boolean start() { + initClusterResourceConfig(); + autoSetClusterResourceConfigForConfigMissingCluster(); + return true; + } + + @Override + public boolean stop() { + return true; + } + + private void initClusterResourceConfig() { + for (Class clz : BeanUtils.reflections.getSubTypesOf(ClusterArchitectureResourceConfig.class)) { + logger.debug("init cluster resource config: " + clz.toString()); + try { + ClusterArchitectureResourceConfig instance = clz.getConstructor().newInstance(); + String architecture = instance.getArchitecture(); + Map configValueMap = instance.getResourceConfigDefaultValueMap(); + architectureClusterConfigValueMap.putIfAbsent(architecture, configValueMap); + if (autoSetClusterResourceConfigs.containsKey(architecture)) { + logger.debug(String.format("The [architecture:%s] has already configured by other class, do not do this", architecture)); + return; + } + Set emptySet = new HashSet<>(); + autoSetClusterResourceConfigs.put(architecture, emptySet); + instance.getAutoSetIfNotConfiguredClusterResourceConfigSet().forEach(configName -> { + if (!autoSetClusterResourceConfigs.get(architecture).contains(configName)) { + autoSetClusterResourceConfigs.get(architecture).add(configName); + } + }); + + Map> resourceConfigValidValuesMap = instance.getResourceConfigValidValuesMap(); + if (resourceConfigValidValuesMap != null) { + resourceConfigValidValuesMap.forEach((identity, validValues) -> + registerClusterResourceConfigValidator(instance, identity, validValues)); + } + } catch (Exception e) { + throw new CloudRuntimeException(e); + } + } + }; + + private void registerClusterResourceConfigValidator(ClusterArchitectureResourceConfig instance, String identity, List validValues) { + if (validValues == null) { + throw new CloudRuntimeException(String.format("missing validValues for resource config" + + "[identity: %s, architecture: %s]", identity, instance.getArchitecture())); + } + + logger.debug(String.format("install validator for resource config[identity: %s]", identity)); + + ResourceConfig rf = rcf.getResourceConfig(identity); + if (rf == null) { + logger.debug(String.format("resource config[identity: %s] not supported, skip validator installation", identity)); + return; + } + + rf.installValidatorExtension((resourceUuid, oldValue, newValue) -> { + if (!instance.clusterArchitectureMatched(resourceUuid)) { + return; + } + + if (!validValues.contains(newValue)) { + throw new GlobalConfigException(String.format("cluster[uuid: %s, architecture: %s]" + + " supported values for resource config[identity: %s] are %s", + resourceUuid, instance.getArchitecture(), identity, validValues)); + } + }); + } + + private Map getArchitectureClusterConfigValueMap(String architecture) { + return architectureClusterConfigValueMap.get(architecture); + } + + public void initClusterResourceConfigValue(ClusterInventory cluster){ + String architecture = cluster.getArchitecture(); + logger.debug(String.format("start to init cluster resource config cluster[uuid:%s, architecture:%s]", cluster.getUuid(), architecture)); + if (architecture == null) { + logger.debug(String.format("cluster[uuid:%s] architecture is none just skip this cluster", cluster.getUuid())); + return; + } + Map clusterConfigValueMap = getArchitectureClusterConfigValueMap(architecture); + if (clusterConfigValueMap == null) { + logger.debug("None of cluster resource config is found just skip"); + return; + } + clusterConfigValueMap.forEach((configName, value) -> { + logger.debug(String.format("start to set cluster resource [config:%s, value:%s]", configName, value)); + ResourceConfig rc = rcf.getResourceConfig(configName); + if (rc == null) { + logger.debug(String.format("fail to resource config %s, please check its identity", configName)); + return; + } + rc.updateValue(cluster.getUuid(), value); + logger.debug(String.format("update cluster resource config," + + " config[name:%s, value:%s, architecture:%s], cluster[uuid:%s]", + configName, value, cluster.getArchitecture(), cluster.getUuid())); + }); + }; + + private void autoSetClusterResourceConfigForConfigMissingCluster() { + List clusters = Q.New(ClusterVO.class) + .select(ClusterVO_.uuid, ClusterVO_.architecture) + .listTuple(); + + if (clusters == null) { + return; + } + + for (Tuple cluster : clusters) { + String clusterUuid = cluster.get(0, String.class); + String clusterArchitecture = cluster.get(1, String.class); + Set configNameList = autoSetClusterResourceConfigs.get(clusterArchitecture); + + if (configNameList == null) { + continue; + } + + for (String configName : configNameList) { + ResourceConfig rc = rcf.getResourceConfig(configName); + + if (rc == null) { + continue; + } + + if (rc.resourceConfigCreated(clusterUuid)) { + continue; + } + + Map configMap = getArchitectureClusterConfigValueMap(clusterArchitecture); + String value = configMap.get(configName); + rc.updateValue(clusterUuid, value); + } + } + } +} diff --git a/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java b/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java index c90752d3155..cc21cfb257a 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java +++ b/compute/src/main/java/org/zstack/compute/host/HostApiInterceptor.java @@ -1,6 +1,7 @@ package org.zstack.compute.host; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.CoreGlobalProperty; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; @@ -12,6 +13,8 @@ import org.zstack.header.apimediator.StopRoutingException; import org.zstack.header.host.*; import org.zstack.header.message.APIMessage; +import org.zstack.utils.ShellResult; +import org.zstack.utils.ShellUtils; import org.zstack.utils.network.NetworkUtils; import static org.zstack.core.Platform.argerr; @@ -50,11 +53,54 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIDeleteHostMsg) msg); } else if (msg instanceof APIChangeHostStateMsg){ validate((APIChangeHostStateMsg) msg); + } else if (msg instanceof APIGetHostWebSshUrlMsg) { + validate((APIGetHostWebSshUrlMsg) msg); + } else if (msg instanceof APICreateHostNetworkServiceTypeMsg) { + validate((APICreateHostNetworkServiceTypeMsg) msg); + } else if (msg instanceof APIDeleteHostNetworkServiceTypeMsg) { + validate((APIDeleteHostNetworkServiceTypeMsg) msg); + } else if (msg instanceof APIUpdateHostNetworkServiceTypeMsg) { + validate((APIUpdateHostNetworkServiceTypeMsg) msg); } return msg; } + private void validate(APIDeleteHostNetworkServiceTypeMsg msg) { + if (Q.New(HostNetworkLabelVO.class).eq(HostNetworkLabelVO_.uuid, msg.getUuid()) + .eq(HostNetworkLabelVO_.system, Boolean.TRUE).isExists()) { + throw new ApiMessageInterceptionException(argerr("system host network service type[%s] cannot be deleted", msg.getUuid())); + } + } + + private void validate(APIUpdateHostNetworkServiceTypeMsg msg) { + if (Q.New(HostNetworkLabelVO.class).eq(HostNetworkLabelVO_.uuid, msg.getUuid()) + .eq(HostNetworkLabelVO_.system, Boolean.TRUE).isExists()) { + throw new ApiMessageInterceptionException(argerr("system host network service type[%s] cannot be updated", msg.getUuid())); + } + } + + private void validate(APICreateHostNetworkServiceTypeMsg msg) { + if (Q.New(HostNetworkLabelVO.class).eq(HostNetworkLabelVO_.serviceType, msg.getServiceType()).isExists()) { + throw new ApiMessageInterceptionException(argerr("there has been a host network service type[%s]", msg.getServiceType())); + } + } + + private void validate(APIGetHostWebSshUrlMsg msg) { + String ZOPS_CONTAINER_NAME = "zops-controller"; + ShellResult ret; + if (!CoreGlobalProperty.UNIT_TEST_ON) { + ret = ShellUtils.runAndReturn(String.format("docker exec %s systemctl is-active webssh", ZOPS_CONTAINER_NAME)); + } else { + ret = new ShellResult(); + ret.setCommand(String.format("docker exec %s systemctl is-active webssh", ZOPS_CONTAINER_NAME)); + ret.setRetCode(0); + } + if (!ret.isReturnCode(0)) { + throw new ApiMessageInterceptionException(operr("webssh server is not running.")); + } + } + private void validate(APIDeleteHostMsg msg) { if (!dbf.isExist(msg.getUuid(), HostVO.class)) { APIDeleteHostEvent evt = new APIDeleteHostEvent(msg.getId()); diff --git a/compute/src/main/java/org/zstack/compute/host/HostBase.java b/compute/src/main/java/org/zstack/compute/host/HostBase.java index c2e529c8e73..2d2d3ed64ce 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostBase.java +++ b/compute/src/main/java/org/zstack/compute/host/HostBase.java @@ -3,7 +3,9 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.springframework.beans.factory.annotation.Qualifier; +import org.zstack.compute.vm.VmSchedHistoryRecorder; +import org.zstack.core.upgrade.UpgradeChecker; +import org.zstack.core.upgrade.UpgradeGlobalConfig; import org.zstack.core.asyncbatch.While; import org.zstack.core.cascade.CascadeConstant; import org.zstack.core.cascade.CascadeFacade; @@ -17,18 +19,15 @@ import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.core.singleflight.TaskSingleFlight; -import org.zstack.core.thread.ChainTask; -import org.zstack.core.thread.SyncTaskChain; -import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.thread.*; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.allocator.AllocationScene; import org.zstack.header.allocator.HostAllocatorConstant; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; -import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; @@ -48,17 +47,16 @@ import org.zstack.header.tag.SystemTagVO_; import org.zstack.header.vm.*; import org.zstack.tag.SystemTagCreator; -import org.zstack.utils.CollectionUtils; -import org.zstack.utils.DebugUtils; -import org.zstack.utils.Utils; +import org.zstack.utils.*; +import org.zstack.utils.data.Pair; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.logging.CLogger; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; -import static org.zstack.core.Platform.err; -import static org.zstack.core.Platform.operr; +import static org.zstack.core.Platform.*; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -92,8 +90,7 @@ public abstract class HostBase extends AbstractHost { @Autowired protected HostMaintenancePolicyManager hostMaintenancePolicyMgr; @Autowired - @Qualifier("HostSingleFlight") - protected TaskSingleFlight singleFlight; + protected UpgradeChecker upgradeChecker; public static class HostDisconnectedCanonicalEvent extends CanonicalEventEmitter { HostCanonicalEvents.HostDisconnectedData data; @@ -109,6 +106,20 @@ public void fire() { } } + public static class HostHardwareChangedCanonicalEvent extends CanonicalEventEmitter { + HostCanonicalEvents.HostHardwareChangedData data; + + public HostHardwareChangedCanonicalEvent(String hostUuid, ErrorCodeList reason) { + data = new HostCanonicalEvents.HostHardwareChangedData(); + data.hostUuid = hostUuid; + data.reason = reason; + } + + public void fire() { + fire(HostCanonicalEvents.HOST_HARDWARE_CHANGED_PATH, data); + } + } + protected final String id; protected abstract void pingHook(Completion completion); @@ -119,6 +130,10 @@ public void fire() { protected abstract void changeStateHook(HostState current, HostStateEvent stateEvent, HostState next); + protected void checkConnectConditions(ConnectHostInfo info, Completion complete) { + complete.success(); + } + protected abstract void connectHook(ConnectHostInfo info, Completion complete); protected abstract void updateOsHook(UpdateHostOSMsg msg, Completion completion); @@ -162,11 +177,152 @@ protected void handleApiMessage(APIMessage msg) { handle((APIReconnectHostMsg) msg); } else if (msg instanceof APIUpdateHostMsg) { handle((APIUpdateHostMsg) msg); + } else if (msg instanceof APIUpdateHostIpmiMsg) { + handle((APIUpdateHostIpmiMsg) msg); + } else if (msg instanceof APIShutdownHostMsg) { + handle((APIShutdownHostMsg) msg); + } else if (msg instanceof APIPowerOnHostMsg ) { + handle((APIPowerOnHostMsg) msg); + } else if (msg instanceof APIPowerResetHostMsg) { + handle((APIPowerResetHostMsg) msg); + } else if (msg instanceof APIGetHostPowerStatusMsg) { + handle((APIGetHostPowerStatusMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } + private void handle(APIGetHostPowerStatusMsg msg) { + APIGetHostPowerStatusEvent event = new APIGetHostPowerStatusEvent(msg.getId()); + GetHostPowerStatusMsg getPowerStatusMsg = new GetHostPowerStatusMsg(); + getPowerStatusMsg.setUuid(msg.getUuid()); + getPowerStatusMsg.setMethod(HostPowerManagementMethod.valueOf(msg.getMethod())); + bus.makeTargetServiceIdByResourceUuid(getPowerStatusMsg, HostConstant.SERVICE_ID, msg.getHostUuid()); + bus.send(getPowerStatusMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + GetHostPowerStatusReply r = reply.castReply(); + if (!r.isSuccess()) { + event.setSuccess(false); + event.setError(r.getError()); + } else { + event.setInventory(r.getInventory()); + } + bus.publish(event); + } + }); + } + + private void handle(APIPowerResetHostMsg msg) { + final APIPowerResetHostEvent event = new APIPowerResetHostEvent(msg.getId()); + RebootHostMsg rebootHostMsg = new RebootHostMsg(); + rebootHostMsg.setUuid(msg.getHostUuid()); + rebootHostMsg.setReturnEarly(msg.isReturnEarly()); + rebootHostMsg.setMethod(HostPowerManagementMethod.valueOf(msg.getMethod())); + bus.makeTargetServiceIdByResourceUuid(rebootHostMsg, HostConstant.SERVICE_ID, msg.getHostUuid()); + bus.send(rebootHostMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + RebootHostReply rebootReply = reply.castReply(); + if (!rebootReply.isSuccess()) { + event.setError(rebootReply.getError()); + event.setSuccess(rebootReply.isSuccess()); + } else { + self = dbf.findByUuid(msg.getUuid(), HostVO.class); + event.setInventory(getSelfInventory()); + } + bus.publish(event); + } + }); + } + + private void handle(APIPowerOnHostMsg msg) { + final APIPowerOnHostEvent event = new APIPowerOnHostEvent(msg.getId()); + PowerOnHostMsg powerOnHostMsg = new PowerOnHostMsg(); + powerOnHostMsg.setUuid(msg.getHostUuid()); + powerOnHostMsg.setReturnEarly(msg.isReturnEarly()); + bus.makeTargetServiceIdByResourceUuid(powerOnHostMsg, HostConstant.SERVICE_ID, powerOnHostMsg.getHostUuid()); + bus.send(powerOnHostMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + PowerOnHostReply powerOnHostReply = reply.castReply(); + if (null != powerOnHostReply.getError()) { + event.setError(powerOnHostReply.getError()); + event.setSuccess(powerOnHostReply.isSuccess()); + } else { + self = dbf.findByUuid(msg.getUuid(), HostVO.class); + event.setInventory(getSelfInventory()); + } + bus.publish(event); + } + }); + } + + private void handle(APIShutdownHostMsg msg) { + final APIShutdownHostEvent event = new APIShutdownHostEvent(msg.getId()); + ShutdownHostMsg shutdownHostMsg = new ShutdownHostMsg(); + shutdownHostMsg.setMethod(HostPowerManagementMethod.valueOf(msg.getMethod())); + shutdownHostMsg.setReturnEarly(msg.isReturnEarly()); + shutdownHostMsg.setUuid(msg.getUuid()); + shutdownHostMsg.setForce(msg.isForce()); + bus.makeTargetServiceIdByResourceUuid(shutdownHostMsg, HostConstant.SERVICE_ID, shutdownHostMsg.getUuid()); + bus.send(shutdownHostMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + ShutdownHostReply shutdownHostReply = reply.castReply(); + if (null != shutdownHostReply.getError()) { + event.setError(shutdownHostReply.getError()); + event.setSuccess(false); + } else { + self = dbf.findByUuid(msg.getUuid(), HostVO.class); + event.setInventory(getSelfInventory()); + } + bus.publish(event); + } + }); + } + + private void handle(APIUpdateHostIpmiMsg msg) { + final APIUpdateHostIpmiEvent event = new APIUpdateHostIpmiEvent(msg.getId()); + HostIpmiVO ipmi = dbf.findByUuid(msg.getHostUuid(), HostIpmiVO.class); + if (null == ipmi.getIpmiAddress()) { + event.setSuccess(false); + event.setError(operr("host[%s] does not have ipmi device or ipmi does not have address." + + "After config ipmi address, please reconnect host to refresh " + + "host ipmi information", msg.getHostUuid())); + bus.publish(event); + return; + } + + if (null != msg.getIpmiAddress()) { + ipmi.setIpmiAddress(msg.getIpmiAddress()); + } + if (null != msg.getIpmiUsername()) { + ipmi.setIpmiUsername(msg.getIpmiUsername()); + } + if (null != msg.getIpmiPassword()) { + ipmi.setIpmiPassword(msg.getIpmiPassword()); + } + if (0 != msg.getIpmiPort()) { + ipmi.setIpmiPort(msg.getIpmiPort()); + } + + Pair pair = HostIpmiPowerExecutor.getPowerStatusWithErrorCode(ipmi); + ErrorCode err = pair.second(); + if (err != null) { + event.setSuccess(false); + event.setError(err); + bus.publish(event); + return; + } + + HostPowerStatus status = pair.first(); + ipmi.setIpmiPowerStatus(status); + ipmi = dbf.updateAndRefresh(ipmi); + event.setHostIpmiInventory(HostIpmiInventory.valueOf(ipmi)); + bus.publish(event); + } + protected HostVO updateHost(APIUpdateHostMsg msg) { boolean update = false; if (msg.getName() != null) { @@ -195,6 +351,13 @@ private void handle(APIUpdateHostMsg msg) { bus.publish(evt); } + private String getVmHostUuid(String vmUuid) { + return Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, vmUuid) + .select(VmInstanceVO_.hostUuid) + .findValue(); + } + protected void maintenanceHook(ChangeHostStateMsg changeHostStateMsg, final Completion completion) { FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("maintenance-mode-host-%s-ip-%s", self.getUuid(), self.getManagementIp())); @@ -265,6 +428,9 @@ public void run(final FlowTrigger trigger, Map data) { } new While<>(vmUuids).step((vmUuid, compl) -> { + VmSchedHistoryRecorder recorder = VmSchedHistoryRecorder.ofHostMaintenance(vmUuid) + .withSchedReason(i18n("Host[%s] is in maintenance state, VM on this host should be migrated", host.getName())) + .begin(); MigrateVmMsg msg = new MigrateVmMsg(); msg.setVmInstanceUuid(vmUuid); msg.setAllocationScene(AllocationScene.Auto); @@ -274,6 +440,10 @@ public void run(final FlowTrigger trigger, Map data) { public void run(MessageReply reply) { if (!reply.isSuccess()) { vmFailedToMigrate.put(msg.getVmInstanceUuid(), reply.getError()); + recorder.withFailReason(reply.getError().getDetails()) + .end(null); + } else { + recorder.end(getVmHostUuid(vmUuid)); } compl.done(); } @@ -419,6 +589,7 @@ public void handle(ErrorCode errCode, Map data) { private void handle(final APIReconnectHostMsg msg) { ReconnectHostMsg rmsg = new ReconnectHostMsg(); rmsg.setHostUuid(self.getUuid()); + rmsg.setCalledByAPI(true); bus.makeTargetServiceIdByResourceUuid(rmsg, HostConstant.SERVICE_ID, self.getUuid()); bus.send(rmsg, new CloudBusCallBack(msg) { @Override @@ -623,6 +794,8 @@ protected void handleLocalMessage(Message msg) { handle((ScanVmPortMsg) msg); } else if (msg instanceof UpdateHostOSMsg) { handle((UpdateHostOSMsg) msg); + } else if (msg instanceof ChangeHostStatusMsg) { + handle((ChangeHostStatusMsg) msg); } else { HostBaseExtensionFactory ext = hostMgr.getHostBaseExtensionFactory(msg); if (ext != null) { @@ -637,6 +810,28 @@ protected void handleLocalMessage(Message msg) { } } + private void handle(ChangeHostStatusMsg msg) { + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + ChangeHostStatusReply reply = new ChangeHostStatusReply(); + changeConnectionState(HostStatusEvent.valueOf(msg.getStatusEvent())); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public String getSyncSignature() { + return String.format("change-host-%s-status", self.getUuid()); + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + private void handle(UpdateHostOSMsg msg) { UpdateHostOSReply reply = new UpdateHostOSReply(); @@ -694,13 +889,9 @@ private void doPingHost(final PingHostMsg msg, ReturnValueCompletion stepCount = new ArrayList<>(); - for (int i = 1; i <= MAX_PING_CNT; i++) { - stepCount.add(i); - } final List errs = new ArrayList<>(); - new While<>(stepCount).each((currentStep, compl) -> pingHook(new Completion(compl) { + While.makeRetryWhile(MAX_PING_CNT).each((currentStep, compl) -> pingHook(new Completion(compl) { @Override public void success() { compl.allDone(); @@ -711,12 +902,13 @@ public void fail(ErrorCode errorCode) { logger.warn(String.format("ping host failed (%d/%d): %s", currentStep, MAX_PING_CNT, errorCode.toString())); errs.add(errorCode); - if (errs.size() != stepCount.size()) { + if (errs.size() != MAX_PING_CNT) { int sleep = HostGlobalConfig.SLEEP_TIME_AFTER_PING_FAILURE.value(Integer.class); if (sleep > 0) { try { TimeUnit.SECONDS.sleep(sleep); } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); } } } @@ -726,7 +918,7 @@ public void fail(ErrorCode errorCode) { })).run(new WhileDoneCompletion(msg) { @Override public void done(ErrorCodeList errorCodeList) { - if (errs.size() == stepCount.size()) { + if (errs.size() == MAX_PING_CNT) { final ErrorCode errorCode = errs.get(0); reply.setConnected(false); reply.setCurrentHostStatus(self.getStatus().toString()); @@ -747,7 +939,6 @@ public void done(ErrorCodeList errorCodeList) { } changeConnectionState(HostStatusEvent.disconnected); - completion.success(reply); } else { reply.setConnected(true); @@ -828,6 +1019,25 @@ public String getName() { }); } + private boolean skipReconnectHost(final ReconnectHostMsg msg) { + if (msg.isSkipIfHostConnected() && HostStatus.Connected == self.getStatus()) { + return true; + } + + if (msg.isCalledByAPI()) { + return false; + } + + return upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(self.getUuid()); + } + + private boolean skipConnectHost(final ConnectHostMsg msg) { + if (msg.isNewAdd() || msg.isCalledByAPI()) { + return false; + } + return upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(self.getUuid()); + } + private void reconnectHost(final ReconnectHostMsg msg, final NoErrorCompletion completion) { thdf.chainSubmit(new ChainTask(msg, completion) { @Override @@ -843,13 +1053,16 @@ private void finish(SyncTaskChain chain) { @Override public void run(final SyncTaskChain chain) { checkState(); - if (msg.isSkipIfHostConnected() && HostStatus.Connected == self.getStatus()) { + + if (skipReconnectHost(msg)) { + bus.reply(msg, new ReconnectHostReply()); finish(chain); return; } ConnectHostMsg connectMsg = new ConnectHostMsg(self.getUuid()); connectMsg.setNewAdd(false); + connectMsg.setCalledByAPI(msg.isCalledByAPI()); bus.makeTargetServiceIdByResourceUuid(connectMsg, HostConstant.SERVICE_ID, self.getUuid()); bus.send(connectMsg, new CloudBusCallBack(msg, chain, completion) { @Override @@ -878,12 +1091,8 @@ public String getName() { } private void updateHostConnectedTime(HostStatus hostStatus) { - String tag = Q.New(SystemTagVO.class).select(SystemTagVO_.tag) - .eq(SystemTagVO_.resourceUuid, self.getUuid()) - .eq(SystemTagVO_.resourceType, HostVO.class.getSimpleName()) - .like(SystemTagVO_.tag, "ConnectedTime::%") - .findValue(); - if (hostStatus == HostStatus.Connected && tag == null) { + boolean tagExists = HostSystemTags.HOST_CONNECTED_TIME.hasTag(self.getUuid()); + if (hostStatus == HostStatus.Connected && !tagExists) { long connectedTime = System.currentTimeMillis(); String token = HostSystemTags.HOST_CONNECTED_TIME_TOKEN; SystemTagCreator creator = HostSystemTags.HOST_CONNECTED_TIME.newSystemTagCreator(self.getUuid()); @@ -895,10 +1104,10 @@ private void updateHostConnectedTime(HostStatus hostStatus) { } if (hostStatus == HostStatus.Disconnected) { SQL.New(SystemTagVO.class) - .eq(SystemTagVO_.resourceUuid, self.getUuid()) - .eq(SystemTagVO_.resourceType, HostVO.class.getSimpleName()) - .like(SystemTagVO_.tag, "ConnectedTime::%") - .hardDelete(); + .eq(SystemTagVO_.resourceUuid, self.getUuid()) + .eq(SystemTagVO_.resourceType, HostVO.class.getSimpleName()) + .like(SystemTagVO_.tag, "ConnectedTime::%") + .hardDelete(); } } @@ -983,7 +1192,7 @@ protected boolean changeConnectionState(final HostStatusEvent event) { return changeConnectionState(event, null); } - protected boolean changeConnectionState(final HostStatusEvent event, Runnable runnable) { + protected boolean changeConnectionState(final HostStatusEvent event, Consumer consumer) { String hostUuid = self.getUuid(); self = dbf.reload(self); if (self == null) { @@ -997,7 +1206,7 @@ protected boolean changeConnectionState(final HostStatusEvent event, Runnable ru } self.setStatus(next); - Optional.ofNullable(runnable).ifPresent(Runnable::run); + Optional.ofNullable(consumer).ifPresent(it -> it.accept(self)); self = dbf.updateAndRefresh(self); logger.debug(String.format("Host %s [uuid:%s] changed connection state from %s to %s", self.getName(), self.getUuid(), before, next)); @@ -1021,41 +1230,55 @@ public void run(AfterChangeHostStatusExtensionPoint arg) { } private void handle(final ConnectHostMsg msg) { - singleFlight.execute( - connectHostSignature(), - (comp) -> this.connect(msg, comp), - new ReturnValueCompletion(msg) { + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("connect-host-%s-single-flight", msg.getHostUuid())) + .run((completion) -> connect(msg, new Completion(completion) { @Override - public void success(ConnectHostReply returnValue) { - ConnectHostReply coped = new ConnectHostReply(); - bus.reply(msg, coped); + public void success() { + completion.success(null); } @Override public void fail(ErrorCode errorCode) { - ConnectHostReply coped = new ConnectHostReply(); - coped.setError(errorCode); - bus.reply(msg, coped); + completion.fail(errorCode); } - } - ); + })) + .done(((result) -> { + ConnectHostReply reply = new ConnectHostReply(); + + if (!result.isSuccess()) { + reply.setError(result.getErrorCode()); + } + + bus.reply(msg, reply); + }))); } private String connectHostSignature() { return String.format("connect-host-%s", self.getUuid()); } - private void connect(final ConnectHostMsg msg, ReturnValueCompletion completion) { + private void connect(final ConnectHostMsg msg, Completion completion) { thdf.chainSubmit(new ChainTask(completion) { @Override public String getSyncSignature() { return connectHostSignature(); } + @Override + public int getSyncLevel() { + return getHostSyncLevel(); + } + @Override public void run(SyncTaskChain chain) { checkState(); - final ConnectHostReply reply = new ConnectHostReply(); + + if(skipConnectHost(msg)){ + completion.success(); + chain.next(); + return; + } final FlowChain flowChain = FlowChainBuilder.newShareFlowChain(); flowChain.setName(String.format("connect-host-%s", self.getUuid())); @@ -1063,6 +1286,25 @@ public void run(SyncTaskChain chain) { flowChain.then(new ShareFlow() { @Override public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "check-conditions-of-connection"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + checkConnectConditions(ConnectHostInfo.fromConnectHostMsg(msg), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + flow(new NoRollbackFlow() { String __name__ = "connect-host"; @@ -1168,7 +1410,7 @@ public void handle(Map data) { CollectionUtils.safeForEach(pluginRgty.getExtensionList(HostAfterConnectedExtensionPoint.class), ext -> ext.afterHostConnected(getSelfInventory())); - completion.success(reply); + completion.success(); } }); @@ -1177,8 +1419,7 @@ public void handle(Map data) { public void handle(ErrorCode errCode, Map data) { changeConnectionState(HostStatusEvent.disconnected); if (!msg.isNewAdd()) { - tracker.trackHost(self.getUuid()); - new HostDisconnectedCanonicalEvent(self.getUuid(), errCode).fire(); + connectHostFailHook(errCode); } completion.fail(errCode); } @@ -1206,6 +1447,11 @@ protected String getDeduplicateString() { }); } + protected void connectHostFailHook(ErrorCode errorCode) { + tracker.trackHost(self.getUuid()); + new HostDisconnectedCanonicalEvent(self.getUuid(), errorCode).fire(); + } + private void handle(final ChangeHostStateMsg msg) { ChangeHostStateReply reply = new ChangeHostStateReply(); diff --git a/compute/src/main/java/org/zstack/compute/host/HostCascadeExtension.java b/compute/src/main/java/org/zstack/compute/host/HostCascadeExtension.java index 785055cae16..6b25e517edc 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostCascadeExtension.java +++ b/compute/src/main/java/org/zstack/compute/host/HostCascadeExtension.java @@ -1,17 +1,26 @@ package org.zstack.compute.host; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cascade.*; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.CloudBusListCallBack; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.cluster.ClusterInventory; import org.zstack.header.cluster.ClusterVO; import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.host.*; import org.zstack.header.message.MessageReply; +import org.zstack.header.volume.VolumeHostRefVO; +import org.zstack.header.volume.VolumeHostRefVO_; +import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.VolumeVO_; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; @@ -20,6 +29,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import static org.zstack.core.Platform.inerr; @@ -76,6 +87,8 @@ private void handleDeletion(final CascadeAction action, final Completion complet return; } + detachDataVolume(hinvs); + List msgs = new ArrayList(); for (HostInventory hinv : hinvs) { HostDeletionMsg msg = new HostDeletionMsg(); @@ -173,4 +186,51 @@ public CascadeAction createActionForChildResource(CascadeAction action) { return null; } + + private void detachDataVolume(List hinvs) { + List dmsgs = hinvs.stream().map(hostInv -> { + VolumeHostRefVO refVO = Q.New(VolumeHostRefVO.class).eq(VolumeHostRefVO_.hostUuid, hostInv.getUuid()).find(); + if (refVO == null) { + return null; + } + String volumeInstallPath = Q.New(VolumeVO.class).select(VolumeVO_.installPath) + .eq(VolumeVO_.uuid, refVO.getVolumeUuid()).findValue(); + return new VolumeHostRef(refVO, volumeInstallPath); + }).filter(Objects::nonNull).map(volumeHostRef -> { + DetachDataVolumeFromHostMsg dmsg = new DetachDataVolumeFromHostMsg(); + dmsg.setHostUuid(volumeHostRef.refVO.getHostUuid()); + dmsg.setMountPath(volumeHostRef.refVO.getMountPath()); + dmsg.setDevice(volumeHostRef.refVO.getDevice()); + dmsg.setVolumeUuid(volumeHostRef.refVO.getVolumeUuid()); + dmsg.setVolumeInstallPath(volumeHostRef.volumeInstallPath); + bus.makeTargetServiceIdByResourceUuid(dmsg, HostConstant.SERVICE_ID, volumeHostRef.refVO.getHostUuid()); + return dmsg; + }).collect(Collectors.toList()); + if (dmsgs.isEmpty()) { + return; + } + new While<>(dmsgs).each((umsg, com) -> bus.send(umsg, new CloudBusCallBack(com) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to detach volume on host, %s", reply.getError())); + } + com.done(); + } + })).run(new WhileDoneCompletion(null) { + @Override + public void done(ErrorCodeList errorCodeList) { + } + }); + } + + static class VolumeHostRef { + private final VolumeHostRefVO refVO; + private final String volumeInstallPath; + + VolumeHostRef(VolumeHostRefVO refVO, String volumeInstallPath) { + this.refVO = refVO; + this.volumeInstallPath = volumeInstallPath; + } + } } diff --git a/compute/src/main/java/org/zstack/compute/host/HostGlobalConfig.java b/compute/src/main/java/org/zstack/compute/host/HostGlobalConfig.java index 6750319d8c8..b13f95673c7 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostGlobalConfig.java +++ b/compute/src/main/java/org/zstack/compute/host/HostGlobalConfig.java @@ -1,6 +1,7 @@ package org.zstack.compute.host; import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; import org.zstack.resourceconfig.BindResourceConfig; @@ -49,4 +50,13 @@ public class HostGlobalConfig { public static GlobalConfig REPORT_HOST_CAPACITY_INTERVAL = new GlobalConfig(CATEGORY, "reportHostCapacityInterval"); @GlobalConfigValidation(numberGreaterThan = 0, numberLessThan = 65535) public static GlobalConfig HOST_PORT_ALLOCATION_START_PORT = new GlobalConfig(CATEGORY, "host.port.allocate.start.port"); + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig HOST_POWER_REFRESH_INTERVAL = new GlobalConfig(CATEGORY, "host.power.refresh.interval"); + + @GlobalConfigValidation(numberGreaterThan = 1) + public static GlobalConfig SYNC_HOST_HW_MONITOR_INTERVAL = new GlobalConfig(CATEGORY, "sync.host.hw.monitor.interval"); + + @GlobalConfigValidation + @GlobalConfigDef(type = String.class, defaultValue = "10501:10999", description = "nbd port range") + public static GlobalConfig NBD_PORT_RANGE = new GlobalConfig(CATEGORY, "nbd.port.range"); } diff --git a/compute/src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java b/compute/src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java new file mode 100644 index 00000000000..f81aaa0eaf7 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java @@ -0,0 +1,297 @@ +package org.zstack.compute.host; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.defer.Defer; +import org.zstack.core.defer.Deferred; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostIpmiVO; +import org.zstack.header.host.HostPowerStatus; +import org.zstack.header.host.HostVO; +import org.zstack.utils.DebugUtils; +import org.zstack.utils.ShellResult; +import org.zstack.utils.ShellUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.data.Pair; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.path.PathUtil; + +import static org.zstack.core.Platform.operr; + +/** + * @Author : jingwang + * @create 2023/5/5 6:56 PM + */ +public abstract class HostIpmiPowerExecutor implements HostPowerExecutor { + @Autowired + DatabaseFacade dbf; + + protected static HostPowerStatus mockedPowerStatus; + protected static boolean mockFail = false; + + private static final CLogger logger = Utils.getLogger(HostIpmiPowerExecutor.class); + + @Override + public void powerOff(HostVO host, Boolean force, Completion completion, boolean returnEarly) { + if (HostPowerStatus.POWER_OFF.equals(refreshHostPowerStatus(host).getIpmiPowerStatus())) { + logger.debug(String.format("host[%s:%d] is already powered off", + host.getIpmi().getIpmiAddress(), host.getIpmi().getIpmiPort())); + completion.success(); + return; + } + + if (returnEarly) { + completion.success(); + powerOff(host, force); + return; + } + + ErrorCode err = powerOff(host, force); + if (err == null) { + completion.success(); + } else { + completion.fail(err); + } + } + + private ErrorCode powerOff(HostVO host, Boolean force) { + if (CoreGlobalProperty.UNIT_TEST_ON) { + if (mockFail) { + return operr("mock power off host[%s] by ipmi failed.", host.getUuid()); + } + return null; + } + + final IPMIToolCaller caller = IPMIToolCaller.fromHostVo(host); + int ret; + if (force) { + ret = caller.powerOff(); + } else { + ret = caller.powerSoft(); + } + + if (0 == ret) { + return null; + } else { + return operr("power off host[%s] by ipmi failed.", host.getUuid()); + } + } + + public HostIpmiVO refreshHostPowerStatus(HostVO host) { + HostIpmiVO ipmi = host.getIpmi(); + return refreshHostPowerStatus(ipmi); + } + + public HostIpmiVO refreshHostPowerStatus(HostIpmiVO ipmi) { + HostPowerStatus status = getPowerStatus(ipmi); + if (status == ipmi.getIpmiPowerStatus()) { + return ipmi; + } + return updateIpmiPowerStatusInDB(ipmi, status); + } + + public HostIpmiVO updateIpmiPowerStatusInDB(HostIpmiVO ipmi, HostPowerStatus status) { + ipmi.setIpmiPowerStatus(status); + return dbf.updateAndRefresh(ipmi); + } + + @Override + public void powerOn(HostVO host, Completion completion) { + if (HostPowerStatus.POWER_ON.equals(refreshHostPowerStatus(host).getIpmiPowerStatus())) { + logger.debug(String.format("host[%s:%d] is already powered on", + host.getIpmi().getIpmiAddress(), host.getIpmi().getIpmiPort())); + completion.success(); + return; + } + + ErrorCode err = powerOn(host); + if (err == null) { + completion.success(); + } else { + completion.fail(err); + } + } + + private ErrorCode powerOn(HostVO host) { + if (CoreGlobalProperty.UNIT_TEST_ON) { + if (mockFail) { + return operr("mock power on host[%s] by ipmi failed.", host.getUuid()); + } + return null; + } + + final IPMIToolCaller caller = IPMIToolCaller.fromHostVo(host); + int ret = caller.powerOn(); + if (0 == ret) { + return null; + } else { + return operr("power on host[%s] by ipmi failed.", host.getUuid()); + } + } + + @Override + public void powerReset(HostVO host, Completion completion, boolean returnEarly) { + if (HostPowerStatus.POWER_OFF.equals(refreshHostPowerStatus(host).getIpmiPowerStatus())) { + ErrorCode err = operr(String.format("reboot host[%s:%d] failed. because host is already powered off", + host.getIpmi().getIpmiAddress(), host.getIpmi().getIpmiPort())); + completion.fail(err); + return; + } + + if (returnEarly) { + completion.success(); + powerReset(host); + return; + } + + ErrorCode err = powerReset(host); + if (err == null) { + completion.success(); + } else { + completion.fail(err); + } + } + + private ErrorCode powerReset(HostVO host) { + if (CoreGlobalProperty.UNIT_TEST_ON) { + if (mockFail) { + return operr("mock power reset host[%s] by ipmi failed.", host.getUuid()); + } + return null; + } + + final IPMIToolCaller caller = IPMIToolCaller.fromHostVo(host); + int ret = caller.powerReset(); + if (0 == ret) { + return null; + } else { + return operr("power reset host[%s] by ipmi failed.", host.getUuid()); + } + } + + @Override + public HostPowerStatus getPowerStatus(HostVO host) { + HostIpmiVO ipmi = host.getIpmi(); + return getPowerStatus(ipmi); + } + + public static HostPowerStatus getPowerStatus(HostIpmiVO ipmi) { + return getPowerStatusWithErrorCode(ipmi).first(); + } + + public static Pair getPowerStatusWithErrorCode(HostIpmiVO ipmi) { + if (mockedPowerStatus != null) { + return new Pair(mockedPowerStatus, null); + } + + if (isIpmiUnConfigured(ipmi)) { + return new Pair(HostPowerStatus.UN_CONFIGURED, + operr("ipmi information is not complete.")); + } + + ShellResult rst = IPMIToolCaller.fromHostIpmiVo(ipmi).status(); + if (rst.getRetCode() == 0) { + if (rst.getStdout().trim().equals("Chassis Power is on")) { + return new Pair(HostPowerStatus.POWER_ON, null); + } else if (rst.getStdout().trim().equals("Chassis Power is off")) { + return new Pair(HostPowerStatus.POWER_OFF, null); + } else { + return new Pair(HostPowerStatus.POWER_UNKNOWN, operr("host[%s] got unexpected return value", ipmi.getUuid())); + } + } else { + return new Pair(HostPowerStatus.POWER_UNKNOWN, operr("host[%s] can not connect ipmi[%s], because:%s", + ipmi.getUuid(), + ipmi.getIpmiAddress(), + rst.getStderr())); + } + } + + public static boolean isIpmiUnConfigured(HostIpmiVO ipmi) { + return null == ipmi || null == ipmi.getIpmiAddress() + || null == ipmi.getIpmiUsername() + || null == ipmi.getIpmiPassword(); + } + + public static ErrorCode isIpmiReachable(HostIpmiVO ipmi) { + ShellResult rst = IPMIToolCaller.fromHostIpmiVo(ipmi).status(); + if (rst.getRetCode() == 0) { + return null; + } else { + return operr("host ipmi[%s] is not reachable.because %s", + ipmi.getIpmiAddress(), + rst.getStderr()); + } + } + + public static void setMockedPowerStatus(HostPowerStatus mockedPowerStatus) { + HostIpmiPowerExecutor.mockedPowerStatus = mockedPowerStatus; + } + + public static void setMockFail(boolean mockFail) { + HostIpmiPowerExecutor.mockFail = mockFail; + } + + protected static class IPMIToolCaller { + private final String interfaceToUse = "lanplus"; + public String hostname; + public int port; + public String username; + public String password; + public String passFile; + + public static IPMIToolCaller fromHostIpmiVo(HostIpmiVO ipmiVo) { + IPMIToolCaller caller = new IPMIToolCaller(); + caller.hostname = ipmiVo.getIpmiAddress(); + caller.port = ipmiVo.getIpmiPort(); + caller.username = ipmiVo.getIpmiUsername(); + caller.password = ipmiVo.getIpmiPassword(); + return caller; + } + + public static IPMIToolCaller fromHostVo(HostVO hostVO) { + return fromHostIpmiVo(hostVO.getIpmi()); + } + + private String buildBaseCmd() { + passFile = PathUtil.createTempFileWithContent(password); + return String.format("ipmitool -I %s -H '%s' -p '%d' -U '%s' -f '%s'", + interfaceToUse, hostname, port, username, passFile); + } + + private ShellResult status() { + return runWithResult("chassis power status"); + } + + public int powerOff() { + return runWithReturnCode("chassis power off"); + } + + public int powerSoft() { + return runWithReturnCode("chassis power soft"); + } + + public int powerOn() { + return runWithReturnCode("chassis power on"); + } + + public int powerReset() { + return runWithReturnCode("chassis power reset"); + } + + @Deferred + public ShellResult runWithResult(String command) { + DebugUtils.Assert(command != null, "command should be set before execution"); + Defer.defer(() -> PathUtil.forceRemoveFile(passFile)); + return ShellUtils.runAndReturn(String.format("%s %s", buildBaseCmd(), command)); + } + + @Deferred + public int runWithReturnCode(String command) { + DebugUtils.Assert(command != null, "command should be set before execution"); + Defer.defer(() -> PathUtil.forceRemoveFile(passFile)); + return ShellUtils.runAndReturn(String.format("%s %s", buildBaseCmd(), command)).getRetCode(); + } + } +} diff --git a/compute/src/main/java/org/zstack/compute/host/HostManager.java b/compute/src/main/java/org/zstack/compute/host/HostManager.java index c512b08ac79..a16985ab0f1 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostManager.java +++ b/compute/src/main/java/org/zstack/compute/host/HostManager.java @@ -7,8 +7,8 @@ public interface HostManager { HypervisorFactory getHypervisorFactory(HypervisorType type); - - void handleMessage(Message msg); - HostBaseExtensionFactory getHostBaseExtensionFactory(Message msg); + void handleMessage(Message msg); + + HostBaseExtensionFactory getHostBaseExtensionFactory(Message msg); } diff --git a/compute/src/main/java/org/zstack/compute/host/HostManagerImpl.java b/compute/src/main/java/org/zstack/compute/host/HostManagerImpl.java index 7479c6d908d..10dfe6049d1 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/host/HostManagerImpl.java @@ -18,6 +18,7 @@ import org.zstack.header.AbstractService; import org.zstack.header.allocator.HostAllocatorConstant; import org.zstack.header.allocator.HostCpuOverProvisioningManager; +import org.zstack.header.cluster.ClusterInventory; import org.zstack.header.cluster.ClusterVO; import org.zstack.header.cluster.ClusterVO_; import org.zstack.header.core.*; @@ -40,13 +41,11 @@ import org.zstack.header.vo.FindSameNodeExtensionPoint; import org.zstack.header.vo.ResourceInventory; import org.zstack.header.zone.ZoneVO; +import org.zstack.compute.cluster.arch.ClusterResourceConfigInitializer; import org.zstack.resourceconfig.ResourceConfig; import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.tag.TagManager; -import org.zstack.utils.Bucket; -import org.zstack.utils.CollectionUtils; -import org.zstack.utils.ObjectUtils; -import org.zstack.utils.Utils; +import org.zstack.utils.*; import org.zstack.utils.data.Pair; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.logging.CLogger; @@ -90,6 +89,8 @@ public class HostManagerImpl extends AbstractService implements HostManager, Man private EventFacade evtf; @Autowired private ResourceConfigFacade rcf; + @Autowired + private ClusterResourceConfigInitializer crci; private Map hostBaseExtensionFactories = new HashMap<>(); private List hostExtensionManagers = new ArrayList<>(); @@ -98,6 +99,7 @@ public class HostManagerImpl extends AbstractService implements HostManager, Man private Map hypervisorFactories = Collections.synchronizedMap(new HashMap()); private static final Set allowedMessageAfterSoftDeletion = new HashSet(); private Future reportHostCapacityTask; + private Future refreshHostPowerStatusTask; static { allowedMessageAfterSoftDeletion.add(HostDeletionMsg.class); @@ -108,63 +110,152 @@ private void handleApiMessage(APIMessage msg) { handle((APIAddHostMsg) msg); } else if (msg instanceof APIGetHypervisorTypesMsg) { handle((APIGetHypervisorTypesMsg) msg); - } else if (msg instanceof APIGetHostTaskMsg) { - handle((APIGetHostTaskMsg) msg); + } else if (msg instanceof APIGetHostWebSshUrlMsg){ + handle((APIGetHostWebSshUrlMsg) msg); } else if (msg instanceof HostMessage) { HostMessage hmsg = (HostMessage) msg; passThrough(hmsg); + } else if (msg instanceof APICreateHostNetworkServiceTypeMsg) { + handle((APICreateHostNetworkServiceTypeMsg) msg); + } else if (msg instanceof APIUpdateHostNetworkServiceTypeMsg) { + handle((APIUpdateHostNetworkServiceTypeMsg) msg); + } else if (msg instanceof APIDeleteHostNetworkServiceTypeMsg) { + handle((APIDeleteHostNetworkServiceTypeMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } - private void handle(APIGetHypervisorTypesMsg msg) { - APIGetHypervisorTypesReply reply = new APIGetHypervisorTypesReply(); - List res = new ArrayList<>(HypervisorType.getAllTypeNames()); - reply.setHypervisorTypes(res); - bus.reply(msg, reply); + + private void handle(APIDeleteHostNetworkServiceTypeMsg msg) { + APIDeleteHostNetworkServiceTypeEvent event = new APIDeleteHostNetworkServiceTypeEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + deleteHostNetworkLabel(msg, new Completion(msg, chain){ + @Override + public void success() { + HostNetworkLabelVO vo = dbf.findByUuid(msg.getUuid(), HostNetworkLabelVO.class); + dbf.remove(vo); + logger.debug(String.format("delete host network service type[uuid:%s]", vo.getUuid())); + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getSyncSignature() { + return String.format("delete-host-network-label[uuid:%s]", msg.getUuid()); + } + + @Override + public String getName() { + return "delete-host-network-label"; + } + }); } - private void handle(APIGetHostTaskMsg msg) { - APIGetHostTaskReply reply = new APIGetHostTaskReply(); - Map> mnIds = msg.getHostUuids().stream().collect( - Collectors.groupingBy(huuid -> destMaker.makeDestination(huuid)) - ); - - new While<>(mnIds.entrySet()).all((e, compl) -> { - GetHostTaskMsg gmsg = new GetHostTaskMsg(); - gmsg.setHostUuids(e.getValue()); - bus.makeServiceIdByManagementNodeId(gmsg, HostConstant.SERVICE_ID, e.getKey()); - bus.send(gmsg, new CloudBusCallBack(compl) { - @Override - public void run(MessageReply r) { - if (r.isSuccess()) { - GetHostTaskReply gr = r.castReply(); - reply.getResults().putAll(gr.getResults()); - } else { - logger.error("get host task fail, because " + r.getError().getDetails()); + private void handle(APIUpdateHostNetworkServiceTypeMsg msg) { + APIUpdateHostNetworkServiceTypeEvent event = new APIUpdateHostNetworkServiceTypeEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + updateHostNetworkLabel(msg, new Completion(msg, chain){ + @Override + public void success() { + HostNetworkLabelVO vo = dbf.findByUuid(msg.getUuid(), HostNetworkLabelVO.class); + vo.setServiceType(msg.getServiceType()); + vo.setSystem(msg.isSystem()); + dbf.updateAndRefresh(vo); + logger.debug(String.format("update host network service type[uuid:%s, serviceType:%s, system:%s]", + vo.getUuid(), vo.getServiceType(), vo.getSystem())); + event.setInventory(HostNetworkLabelInventory.valueOf(vo)); + bus.publish(event); + chain.next(); } - compl.done(); - } - }); + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } - }).run(new WhileDoneCompletion(msg) { @Override - public void done(ErrorCodeList errorCodeList) { - bus.reply(msg, reply); + public String getSyncSignature() { + return String.format("update-host-network-label[uuid:%s]", msg.getUuid()); + } + + @Override + public String getName() { + return "update-host-network-label"; } }); } - private void handle(GetHostTaskMsg msg) { - GetHostTaskReply reply = new GetHostTaskReply(); - List vos = Q.New(HostVO.class).in(HostVO_.uuid, msg.getHostUuids()).list(); - vos.forEach(vo -> { - HypervisorFactory factory = this.getHypervisorFactory(HypervisorType.valueOf(vo.getHypervisorType())); - Host host = factory.getHost(vo); - reply.putResults(vo.getUuid(), thdf.getChainTaskInfo(host.getId())); + private void handle(APICreateHostNetworkServiceTypeMsg msg) { + HostNetworkLabelVO vo = new HostNetworkLabelVO(); + vo.setUuid(Platform.getUuid()); + vo.setServiceType(msg.getServiceType()); + vo.setSystem(msg.isSystem()); + dbf.persist(vo); + logger.debug(String.format("create host network service type[uuid:%s, serviceType:%s, system:%s]", + vo.getUuid(), vo.getServiceType(), vo.getSystem())); + APICreateHostNetworkServiceTypeEvent event = new APICreateHostNetworkServiceTypeEvent(msg.getId()); + event.setInventory(HostNetworkLabelInventory.valueOf(vo)); + bus.publish(event); + } + + private void deleteHostNetworkLabel(APIDeleteHostNetworkServiceTypeMsg msg, Completion completion) { + HostNetworkLabelVO vo = dbf.findByUuid(msg.getUuid(), HostNetworkLabelVO.class); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(HostNetworkLabelExtensionPoint.class), + arg -> arg.deleteHostNetworkLabel(vo.toInventory(), completion)); + } + + private void updateHostNetworkLabel(APIUpdateHostNetworkServiceTypeMsg msg, Completion completion) { + HostNetworkLabelVO vo = dbf.findByUuid(msg.getUuid(), HostNetworkLabelVO.class); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(HostNetworkLabelExtensionPoint.class), + arg -> arg.updateHostNetworkLabel(vo.toInventory(), msg.getServiceType(), completion)); + } + + private void handle(APIGetHostWebSshUrlMsg msg) { + APIGetHostWebSshUrlEvent event = new APIGetHostWebSshUrlEvent(msg.getId()); + GetHostWebSshUrlMsg getHostWebSshUrlMsg = new GetHostWebSshUrlMsg(); + getHostWebSshUrlMsg.setUuid(msg.getUuid()); + getHostWebSshUrlMsg.setHttps(msg.getHttps()); + getHostWebSshUrlMsg.setUserName(msg.getUserName()); + getHostWebSshUrlMsg.setPassword(msg.getPassword()); + bus.makeLocalServiceId(getHostWebSshUrlMsg ,HostConstant.SERVICE_ID); + bus.send(getHostWebSshUrlMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + event.setError(r.getError()); + bus.publish(event); + return; + } + + GetHostWebSshUrlReply getUrlReply = r.castReply(); + event.setUrl(getUrlReply.getUrl()); + bus.publish(event); + } }); + } + + private void handle(APIGetHypervisorTypesMsg msg) { + APIGetHypervisorTypesReply reply = new APIGetHypervisorTypesReply(); + List res = new ArrayList<>(HypervisorType.getAllTypeNames()); + reply.setHypervisorTypes(res); bus.reply(msg, reply); } @@ -204,8 +295,6 @@ private void handleLocalMessage(Message msg) { passThrough((HostMessage) msg); } else if (msg instanceof AddHostMsg){ handle((AddHostMsg) msg); - } else if (msg instanceof GetHostTaskMsg) { - handle((GetHostTaskMsg) msg); } else if (msg instanceof CancelHostTasksMsg) { handle((CancelHostTasksMsg) msg); } else { @@ -281,17 +370,27 @@ public String getName() { } private void doAddHost(final AddHostMessage msg, ReturnValueCompletion completion) { - if (Q.New(HostVO.class).eq(HostVO_.managementIp, msg.getManagementIp()).isExists()) { - completion.fail(argerr("there has been a host having managementIp[%s]", msg.getManagementIp())); - return; - } - final ClusterVO cluster = findClusterByUuid(msg.getClusterUuid()); if (cluster == null) { completion.fail(argerr("cluster[uuid:%s] is not existing", msg.getClusterUuid())); return; } + String hvType = cluster.getHypervisorType(); + if (hvType == null) { + completion.fail(argerr("cluster[uuid:%s] has null hypervisorType", msg.getClusterUuid())); + return; + } + + if (Q.New(HostVO.class) + .eq(HostVO_.managementIp, msg.getManagementIp()) + .eq(HostVO_.hypervisorType, hvType) + .isExists()) { + completion.fail(argerr("there has been a host having managementIp[%s] for hypervisor[%s]", + msg.getManagementIp(), hvType)); + return; + } + final HostVO hvo = new HostVO(); if (msg.getResourceUuid() != null) { hvo.setUuid(msg.getResourceUuid()); @@ -390,6 +489,8 @@ public void run(FlowTrigger trigger, Map data) { if (cluster.getArchitecture() == null) { cluster.setArchitecture(arch); dbf.update(cluster); + ClusterInventory clusterInventory = ClusterInventory.valueOf(cluster); + crci.initClusterResourceConfigValue(clusterInventory); trigger.next(); return; } @@ -407,47 +508,11 @@ public void run(FlowTrigger trigger, Map data) { @Override public void run(FlowTrigger trigger, Map data) { - String distro = HostSystemTags.OS_DISTRIBUTION.getTokenByResourceUuid(vo.getUuid(), HostSystemTags.OS_DISTRIBUTION_TOKEN); - String release = HostSystemTags.OS_RELEASE.getTokenByResourceUuid(vo.getUuid(), HostSystemTags.OS_RELEASE_TOKEN); - String version = HostSystemTags.OS_VERSION.getTokenByResourceUuid(vo.getUuid(), HostSystemTags.OS_VERSION_TOKEN); - - if (distro == null || release == null || version == null) { - trigger.fail(operr("after connecting, host[name:%s, ip:%s] returns a null os version", vo.getName(), vo.getManagementIp())); - return; - } - - SimpleQuery q = dbf.createQuery(HostVO.class); - q.select(HostVO_.uuid); - q.add(HostVO_.clusterUuid, Op.EQ, vo.getClusterUuid()); - q.add(HostVO_.uuid, Op.NOT_EQ, vo.getUuid()); - q.add(HostVO_.status, Op.NOT_EQ, HostStatus.Connecting); - q.setLimit(1); - List huuids = q.listValue(); - if (huuids.isEmpty()) { - // this the first host in cluster - trigger.next(); - return; - } - - String otherHostUuid = huuids.get(0); - String cdistro = HostSystemTags.OS_DISTRIBUTION.getTokenByResourceUuid(otherHostUuid, HostSystemTags.OS_DISTRIBUTION_TOKEN); - String crelease = HostSystemTags.OS_RELEASE.getTokenByResourceUuid(otherHostUuid, HostSystemTags.OS_RELEASE_TOKEN); - String cversion = HostSystemTags.OS_VERSION.getTokenByResourceUuid(otherHostUuid, HostSystemTags.OS_VERSION_TOKEN); - if (cdistro == null || crelease == null || cversion == null) { - // this the first host in cluster - trigger.next(); + final ErrorCode errorCode = factory.checkNewAddedHost(vo); + if (errorCode != null) { + trigger.fail(errorCode); return; } - - String mineVersion = String.format("%s;%s;%s", distro, release, version); - String currentVersion = String.format("%s;%s;%s", cdistro, crelease, cversion); - - if (!mineVersion.equals(currentVersion)) { - trigger.fail(operr("cluster[uuid:%s] already has host with os version[%s], but new added host[name:%s ip:%s] has host os version[%s]", - vo.getClusterUuid(), currentVersion, vo.getName(), vo.getManagementIp(), mineVersion)); - return; - } - trigger.next(); } }).then(new NoRollbackFlow() { @@ -551,6 +616,8 @@ private void handle(CancelHostTasksMsg msg) { nmsg.setHostUuids(msg.getHostUuids()); nmsg.setSearchedMnIds(msg.getSearchedMnIds()); nmsg.setCancellationApiId(msg.getCancellationApiId()); + nmsg.setInterval(msg.getInterval()); + nmsg.setTimes(msg.getTimes()); bus.makeServiceIdByManagementNodeId(nmsg, HostConstant.SERVICE_ID, restMnIds.get(0)); bus.send(nmsg, new CloudBusCallBack(msg) { @Override @@ -575,6 +642,8 @@ public void run(MessageReply r) { CancelHostTaskMsg cmsg = new CancelHostTaskMsg(); cmsg.setHostUuid(hostUuid); cmsg.setCancellationApiId(msg.getCancellationApiId()); + cmsg.setInterval(msg.getInterval()); + cmsg.setTimes(msg.getTimes()); bus.makeLocalServiceId(cmsg, HostConstant.SERVICE_ID); bus.send(cmsg, new CloudBusCallBack(compl) { @Override @@ -643,10 +712,70 @@ public boolean start() { private void startPeriodTasks() { HostGlobalConfig.REPORT_HOST_CAPACITY_INTERVAL.installUpdateExtension((oldConfig, newConfig) -> startReportHostCapacityTask()); + HostGlobalConfig.HOST_POWER_REFRESH_INTERVAL.installUpdateExtension((oldConfig, newConfig) -> startRefreshHostPowerStatusTask()); startReportHostCapacityTask(); + startRefreshHostPowerStatusTask(); } - private void startReportHostCapacityTask() { + private synchronized void startRefreshHostPowerStatusTask() { + if (refreshHostPowerStatusTask != null) { + refreshHostPowerStatusTask.cancel(true); + } + refreshHostPowerStatusTask = thdf.submitPeriodicTask(new PeriodicTask() { + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + public long getInterval() { + return HostGlobalConfig.HOST_POWER_REFRESH_INTERVAL.value(Integer.class).longValue(); + } + + @Override + public String getName() { + return "update-host-ipmi-power-status"; + } + + @Override + public void run() { + List ipmis = Q.New(HostIpmiVO.class) + .list(); + + ipmis = ipmis.stream().filter(i -> destMaker.isManagedByUs(i.getUuid())).collect(Collectors.toList()); + new While<>(ipmis).step((ipmi, comp) -> { + refreshHostPowerStatus(ipmi); + comp.done(); + },10).run(new NopeWhileDoneCompletion()); + } + + private void refreshHostPowerStatus(HostIpmiVO ipmi) { + if (ipmi == null) { + return; + } + + HostPowerStatus status = HostIpmiPowerExecutor.getPowerStatus(ipmi); + if (HostPowerStatus.POWER_BOOTING == ipmi.getIpmiPowerStatus() + && HostPowerStatus.POWER_OFF == status) { + return; + } + + if (HostPowerStatus.POWER_SHUTDOWN == ipmi.getIpmiPowerStatus() + && HostPowerStatus.POWER_ON == status) { + return; + } + + if (ipmi.getIpmiPowerStatus() != status) { + SQL.New(HostIpmiVO.class) + .set(HostIpmiVO_.ipmiPowerStatus, status) + .eq(HostIpmiVO_.uuid, ipmi.getUuid()) + .update(); + } + } + }); + } + + private synchronized void startReportHostCapacityTask() { if (reportHostCapacityTask != null) { reportHostCapacityTask.cancel(true); } @@ -736,9 +865,9 @@ protected void run(Map tokens, Object data) { private boolean noStorageAccessible(String hostUuid){ // detach ps will delete PrimaryStorageClusterRefVO first. List attachedPsUuids = SQL.New("select distinct ref.primaryStorageUuid" + - " from PrimaryStorageClusterRefVO ref, HostVO h" + - " where h.uuid =:hostUuid" + - " and ref.clusterUuid = h.clusterUuid", String.class) + " from PrimaryStorageClusterRefVO ref, HostVO h" + + " where h.uuid =:hostUuid" + + " and ref.clusterUuid = h.clusterUuid", String.class) .param("hostUuid", hostUuid) .list(); @@ -910,18 +1039,18 @@ private void loadHost(boolean skipConnected) { bus.send(msgs, HostGlobalConfig.HOST_LOAD_PARALLELISM_DEGREE.value(Integer.class), new CloudBusSteppingCallback(null) { - @Override - public void run(NeedReplyMessage msg, MessageReply reply) { - ConnectHostMsg cmsg = (ConnectHostMsg) msg; - if (reply.isSuccess()) { - logger.debug(String.format("host[uuid:%s] load successfully", cmsg.getHostUuid())); - } else if (reply.isCanceled()) { - logger.warn(String.format("canceled connect kvm host[uuid:%s], because it connecting now", cmsg.getHostUuid())); - } else { - logger.warn(String.format("failed to load host[uuid:%s], %s", cmsg.getHostUuid(), reply.getError())); - } - } - }); + @Override + public void run(NeedReplyMessage msg, MessageReply reply) { + ConnectHostMsg cmsg = (ConnectHostMsg) msg; + if (reply.isSuccess()) { + logger.debug(String.format("host[uuid:%s] load successfully", cmsg.getHostUuid())); + } else if (reply.isCanceled()) { + logger.warn(String.format("canceled connect kvm host[uuid:%s], because it connecting now", cmsg.getHostUuid())); + } else { + logger.warn(String.format("failed to load host[uuid:%s], %s", cmsg.getHostUuid(), reply.getError())); + } + } + }); } @Override diff --git a/compute/src/main/java/org/zstack/compute/host/HostPowerExecutor.java b/compute/src/main/java/org/zstack/compute/host/HostPowerExecutor.java new file mode 100644 index 00000000000..46b4bf1faed --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/host/HostPowerExecutor.java @@ -0,0 +1,16 @@ +package org.zstack.compute.host; + +import org.zstack.header.core.Completion; +import org.zstack.header.host.HostPowerStatus; +import org.zstack.header.host.HostVO; + +/** + * @Author : jingwang + * @create 2023/4/13 10:01 AM + */ +public interface HostPowerExecutor { + void powerOff(HostVO host, Boolean force, Completion completion, boolean returnEarly); + void powerOn(HostVO host, Completion completion); + void powerReset(HostVO host, Completion completion, boolean returnEarly); + HostPowerStatus getPowerStatus(HostVO host); +} diff --git a/compute/src/main/java/org/zstack/compute/host/HostReconnectTask.java b/compute/src/main/java/org/zstack/compute/host/HostReconnectTask.java index b111bee0ab9..f9b6b094271 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostReconnectTask.java +++ b/compute/src/main/java/org/zstack/compute/host/HostReconnectTask.java @@ -19,7 +19,7 @@ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public abstract class HostReconnectTask extends AsyncTimer { protected String uuid; - private NoErrorCompletion completion; + protected NoErrorCompletion completion; @Autowired protected CloudBus bus; @@ -69,8 +69,7 @@ public void success() { @Override public void fail(ErrorCode errorCode) { - // still fail to reconnect the host, continue this reconnect task - continueToRunThisTimer(); + whenConnectFail(errorCode); } }); } else if (answer == CanDoAnswer.NotReady) { @@ -82,4 +81,9 @@ public void fail(ErrorCode errorCode) { throw new CloudRuntimeException(String.format("should not be here[%s]", answer)); } } + + protected void whenConnectFail(ErrorCode errorCode) { + // still fail to reconnect the host, continue this reconnect task + continueToRunThisTimer(); + } } diff --git a/compute/src/main/java/org/zstack/compute/host/HostReconnectTaskFactory.java b/compute/src/main/java/org/zstack/compute/host/HostReconnectTaskFactory.java index bb3c548f6dd..7bd9ceb06e1 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostReconnectTaskFactory.java +++ b/compute/src/main/java/org/zstack/compute/host/HostReconnectTaskFactory.java @@ -1,9 +1,16 @@ package org.zstack.compute.host; import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.errorcode.ErrorCode; public interface HostReconnectTaskFactory { HostReconnectTask createTask(String uuid, NoErrorCompletion completion); + default HostReconnectTask createTaskWithLastConnectError(String uuid, + ErrorCode errorCode, + NoErrorCompletion completion) { + return createTask(uuid, completion); + } + String getHypervisorType(); } diff --git a/compute/src/main/java/org/zstack/compute/host/HostSystemTags.java b/compute/src/main/java/org/zstack/compute/host/HostSystemTags.java index 1c386de71c8..8de3693633c 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostSystemTags.java +++ b/compute/src/main/java/org/zstack/compute/host/HostSystemTags.java @@ -17,13 +17,19 @@ public class HostSystemTags { public static SystemTag LIVE_SNAPSHOT = new SystemTag("capability::liveSnapshot", HostVO.class); + @Deprecated public static String OS_DISTRIBUTION_TOKEN = "distribution"; + @Deprecated public static PatternedSystemTag OS_DISTRIBUTION = new PatternedSystemTag(String.format("os::distribution::{%s}", OS_DISTRIBUTION_TOKEN), HostVO.class); + @Deprecated public static String OS_RELEASE_TOKEN = "release"; + @Deprecated public static PatternedSystemTag OS_RELEASE = new PatternedSystemTag(String.format("os::release::{%s}", OS_RELEASE_TOKEN), HostVO.class); + @Deprecated public static String OS_VERSION_TOKEN = "version"; + @Deprecated public static PatternedSystemTag OS_VERSION = new PatternedSystemTag(String.format("os::version::{%s}", OS_VERSION_TOKEN), HostVO.class); public static String EXTRA_IPS_TOKEN = "extraips"; @@ -41,6 +47,27 @@ public class HostSystemTags { public static final String CPU_GHZ_TOKEN = "cpuGHz"; public static PatternedSystemTag CPU_GHZ = new PatternedSystemTag(String.format("cpuGHz::{%s}", CPU_GHZ_TOKEN), HostVO.class); + public static final String CPU_PROCESSOR_NUM_TOKEN = "cpuProcessorNum"; + public static PatternedSystemTag CPU_PROCESSOR_NUM = new PatternedSystemTag(String.format("cpuProcessorNum::{%s}", CPU_PROCESSOR_NUM_TOKEN), HostVO.class); + + public static final String CPU_CACHE_TOKEN = "cpuCache"; + public static PatternedSystemTag CPU_CACHE = new PatternedSystemTag(String.format("cpuCache::{%s}", CPU_CACHE_TOKEN), HostVO.class); + + public static final String POWER_SUPPLY_MODEL_NAME_TOKEN = "powerSupplyModelName"; + public static PatternedSystemTag POWER_SUPPLY_MODEL_NAME = new PatternedSystemTag(String.format("powerSupplyModelName::{%s}", POWER_SUPPLY_MODEL_NAME_TOKEN), HostVO.class); + + public static final String POWER_SUPPLY_MAX_POWER_CAPACITY_TOKEN = "powerSupplyMaxPowerCapacity"; + public static PatternedSystemTag POWER_SUPPLY_MAX_POWER_CAPACITY = new PatternedSystemTag(String.format("powerSupplyMaxPowerCapacity::{%s}", POWER_SUPPLY_MAX_POWER_CAPACITY_TOKEN), HostVO.class); + + public static final String POWER_SUPPLY_MANUFACTURER_TOKEN = "powerSupplyManufacturer"; + public static PatternedSystemTag POWER_SUPPLY_MANUFACTURER = new PatternedSystemTag(String.format("powerSupplyManufacturer::{%s}", POWER_SUPPLY_MANUFACTURER_TOKEN), HostVO.class); + + public static final String IPMI_ADDRESS_TOKEN = "ipmiAddress"; + public static PatternedSystemTag IPMI_ADDRESS = new PatternedSystemTag(String.format("ipmiAddress::{%s}", IPMI_ADDRESS_TOKEN), HostVO.class); + + public static final String ISCSI_INITIATOR_NAME_TOKEN = "iscsiInitiatorName"; + public static PatternedSystemTag ISCSI_INITIATOR_NAME = new PatternedSystemTag(String.format("iscsiInitiatorName::{%s}", ISCSI_INITIATOR_NAME_TOKEN), HostVO.class); + public static final String PAGE_TABLE_EXTENSION_DISABLED_TOKEN = "pageTableExtensionDisabled"; public static PatternedSystemTag PAGE_TABLE_EXTENSION_DISABLED = new PatternedSystemTag(PAGE_TABLE_EXTENSION_DISABLED_TOKEN, HostVO.class); @@ -48,7 +75,38 @@ public class HostSystemTags { public static PatternedSystemTag HOST_GUEST_TOOLS = new PatternedSystemTag(String.format("GuestTools::{%s}", HOST_GUEST_TOOLS_VERSION_TOKEN), HostVO.class); + public static String HOST_LINUX_GUEST_TOOLS_VERSION_TOKEN = "guestToolsLinuxVersion"; + public static PatternedSystemTag HOST_LINUX_GUEST_TOOLS = + new PatternedSystemTag(String.format("GuestToolsLinux::{%s}", HOST_LINUX_GUEST_TOOLS_VERSION_TOKEN), HostVO.class); + public static String HOST_CONNECTED_TIME_TOKEN = "hostConnectedTime"; public static PatternedSystemTag HOST_CONNECTED_TIME = new PatternedSystemTag(String.format("ConnectedTime::{%s}", HOST_CONNECTED_TIME_TOKEN), HostVO.class); + + public static String SYSTEM_MANUFACTURER_TOKEN = "systemManufacturer"; + public static PatternedSystemTag SYSTEM_MANUFACTURER = new PatternedSystemTag(String.format("systemManufacturer::{%s}", SYSTEM_MANUFACTURER_TOKEN), HostVO.class); + + public static String SYSTEM_UUID_TOKEN = "systemUUID"; + public static PatternedSystemTag SYSTEM_UUID = new PatternedSystemTag(String.format("systemUUID::{%s}", SYSTEM_UUID_TOKEN), HostVO.class); + + public static String BIOS_VENDOR_TOKEN = "biosVendor"; + public static PatternedSystemTag BIOS_VENDOR = new PatternedSystemTag(String.format("biosVendor::{%s}", BIOS_VENDOR_TOKEN), HostVO.class); + + public static String BIOS_VERSION_TOKEN = "biosVersion"; + public static PatternedSystemTag BIOS_VERSION = new PatternedSystemTag(String.format("biosVersion::{%s}", BIOS_VERSION_TOKEN), HostVO.class); + + public static String BIOS_RELEASE_DATE_TOKEN = "biosReleaseDate"; + public static PatternedSystemTag BIOS_RELEASE_DATE = new PatternedSystemTag(String.format("biosReleaseDate::{%s}", BIOS_RELEASE_DATE_TOKEN), HostVO.class); + + public static String BMC_VERSION_TOKEN = "bmcVersion"; + public static PatternedSystemTag BMC_VERSION = new PatternedSystemTag(String.format("bmcVersion::{%s}", BMC_VERSION_TOKEN), HostVO.class); + + public static String UPTIME_TOKEN = "uptime"; + public static PatternedSystemTag UPTIME = new PatternedSystemTag(String.format("uptime::{%s}", UPTIME_TOKEN), HostVO.class); + + public static String MEMORY_SLOTS_MAXIMUM_TOKEN = "memorySlotsMaximum"; + public static PatternedSystemTag MEMORY_SLOTS_MAXIMUM = new PatternedSystemTag(String.format("memorySlotsMaximum::{%s}", MEMORY_SLOTS_MAXIMUM_TOKEN), HostVO.class); + + public static String DEPLOY_MODE_TOKEN = "deployMode"; + public static PatternedSystemTag DEPLOY_MODE = new PatternedSystemTag(String.format("deployMode::{%s}", DEPLOY_MODE_TOKEN), HostVO.class); } diff --git a/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java b/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java index e147e0807a3..49394e88b78 100755 --- a/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java +++ b/compute/src/main/java/org/zstack/compute/host/HostTrackImpl.java @@ -1,5 +1,7 @@ package org.zstack.compute.host; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.cloudbus.*; @@ -33,7 +35,9 @@ public class HostTrackImpl implements HostTracker, ManagementNodeChangeListener, Component, ManagementNodeReadyExtensionPoint { private final static CLogger logger = Utils.getLogger(HostTrackImpl.class); - private Map trackers = new HashMap<>(); + private Map trackers = new ConcurrentHashMap<>(); + private static boolean alwaysStartRightNow = false; + private static final Cache skippedPingHostDeadline = CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.HOURS).build(); @Autowired private DatabaseFacade dbf; @@ -123,6 +127,12 @@ private void track() { return; } + if (skippedPingHostDeadline.getIfPresent(uuid) != null && System.currentTimeMillis() / 1000 <= skippedPingHostDeadline.getIfPresent(uuid)) { + logger.debug(String.format("skip tracking host[uuid:%s] this time, deadline %s", uuid, skippedPingHostDeadline.getIfPresent(uuid))); + continueToRunThisTimer(); + return; + } + PingHostMsg msg = new PingHostMsg(); msg.setHostUuid(uuid); bus.makeLocalServiceId(msg, HostConstant.SERVICE_ID); @@ -188,19 +198,19 @@ public void success() { @Override public void fail(ErrorCode errorCode) { - submitReconnectTask(); + submitReconnectTask(errorCode); } }); } else if (decision == ReconnectDecision.StopPing) { cancel(); } else if (decision == ReconnectDecision.SubmitReconnectTask) { - submitReconnectTask(); + submitReconnectTask(null); } else { throw new CloudRuntimeException("should not be here"); } } - private void submitReconnectTask() { + private void submitReconnectTask(ErrorCode lastConnectError) { if (isCanceled()) { return; } @@ -209,14 +219,22 @@ private void submitReconnectTask() { reconnectTask.cancel(); } - reconnectTask = getHostReconnectTaskFactory(hypervisorType).createTask(uuid, new NoErrorCompletion() { + reconnectTask = createTask(lastConnectError); + reconnectTask.start(); + } + + HostReconnectTask createTask(ErrorCode lastConnectError) { + final HostReconnectTaskFactory factory = getHostReconnectTaskFactory(hypervisorType); + NoErrorCompletion completion = new NoErrorCompletion() { @Override public void done() { continueToRunThisTimer(); } - }); + }; - reconnectTask.start(); + return lastConnectError == null ? + factory.createTask(uuid, completion) : + factory.createTaskWithLastConnectError(uuid, lastConnectError, completion); } @Override @@ -241,7 +259,7 @@ public void trackHost(String hostUuid) { t = new Tracker(hostUuid); trackers.put(hostUuid, t); - if (CoreGlobalProperty.UNIT_TEST_ON) { + if (CoreGlobalProperty.UNIT_TEST_ON && !alwaysStartRightNow) { t.start(); } else { t.startRightNow(); @@ -332,6 +350,7 @@ private HostReconnectTaskFactory getHostReconnectTaskFactory(String hvType) { public boolean start() { populateExtensions(); onHostStatusChange(); + onHostPingSkip(); HostGlobalConfig.PING_HOST_INTERVAL.installUpdateExtension((oldConfig, newConfig) -> { logger.debug(String.format("%s change from %s to %s, restart host trackers", @@ -377,6 +396,24 @@ protected void run(Map tokens, Object data) { }); } + private void onHostPingSkip() { + evtf.on(HostCanonicalEvents.HOST_PING_SKIP, new EventCallback() { + @Override + protected void run(Map tokens, Object data) { + HostCanonicalEvents.HostPingSkipData d = (HostCanonicalEvents.HostPingSkipData) data; + Long deadline = System.currentTimeMillis() / 1000 + d.getSkipTimeInSec(); + skippedPingHostDeadline.put(d.getHostUuid(), deadline); + } + }); + evtf.on(HostCanonicalEvents.HOST_PING_CANCEL_SKIP, new EventCallback() { + @Override + protected void run(Map tokens, Object data) { + HostCanonicalEvents.HostPingSkipData d = (HostCanonicalEvents.HostPingSkipData) data; + skippedPingHostDeadline.invalidate(d.getHostUuid()); + } + }); + } + @Override public boolean stop() { return true; diff --git a/compute/src/main/java/org/zstack/compute/host/PostHostExtensionPointForNuma.java b/compute/src/main/java/org/zstack/compute/host/PostHostExtensionPointForNuma.java index c8a0bc0f4d0..ffa2f6a56e7 100644 --- a/compute/src/main/java/org/zstack/compute/host/PostHostExtensionPointForNuma.java +++ b/compute/src/main/java/org/zstack/compute/host/PostHostExtensionPointForNuma.java @@ -4,18 +4,28 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.SimpleQuery; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; -import org.zstack.header.host.*; +import org.zstack.header.host.GetHostNumaTopologyMsg; +import org.zstack.header.host.GetHostNumaTopologyReply; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostNUMANode; +import org.zstack.header.host.HostNumaNodeVO; +import org.zstack.header.host.HostNumaNodeVO_; import org.zstack.header.message.MessageReply; import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; public class PostHostExtensionPointForNuma implements PostHostConnectExtensionPoint { @Autowired @@ -44,28 +54,64 @@ public void run(MessageReply kreply) { GetHostNumaTopologyReply rpy = (GetHostNumaTopologyReply) kreply; Map nodes = rpy.getNuma(); if (nodes == null || nodes.isEmpty()) { + SQL.New(HostNumaNodeVO.class).eq(HostNumaNodeVO_.hostUuid, host.getUuid()).hardDelete(); trigger.next(); return; } - SimpleQuery nodesQuery = dbf.createQuery(HostNumaNodeVO.class); - nodesQuery.add(HostNumaNodeVO_.hostUuid, SimpleQuery.Op.EQ, host.getUuid()); - List numaNodes = nodesQuery.list(); - if (!numaNodes.isEmpty()) { - dbf.removeCollection(numaNodes, HostNumaNodeVO.class); - } - + // {"0":{"distance":["10"],"cpus":["0","1","2","3"],"free":16717463552,"size":21474275328} + List oldHostNumaNodes = Q.New(HostNumaNodeVO.class) + .eq(HostNumaNodeVO_.hostUuid, host.getUuid()) + .list(); + + List newHostNumaNodes = new ArrayList<>(); Iterator> nodeEntries = nodes.entrySet().iterator(); while (nodeEntries.hasNext()) { Map.Entry node = nodeEntries.next(); HostNUMANode nodeInfo = node.getValue(); - HostNumaNodeVO hntvo = new HostNumaNodeVO(nodeInfo); hntvo.setHostUuid(host.getUuid()); hntvo.setNodeID(node.getKey()); - - dbf.persist(hntvo); + newHostNumaNodes.add(hntvo); } + + oldHostNumaNodes.stream() + .filter(oldNumaNode -> newHostNumaNodes.stream() + .noneMatch(newNumaNode -> { + logger.trace(String.format("oldNumaNode.getNodeCPUs(): %s, newNumaNode.getNodeCPUs(): %s, equals: %s", oldNumaNode.getNodeCPUs(), newNumaNode.getNodeCPUs(), newNumaNode.getNodeCPUs().equals(oldNumaNode.getNodeCPUs()))); + logger.trace(String.format("oldNumaNode.getNodeDistance(): %s, newNumaNode.getNodeDistance(): %s, equals: %s", oldNumaNode.getNodeDistance(), newNumaNode.getNodeDistance(), newNumaNode.getNodeDistance().equals(oldNumaNode.getNodeDistance()))); + logger.trace(String.format("oldNumaNode.getNodeMemSize(): %s, newNumaNode.getNodeMemSize(): %s, equals: %s", oldNumaNode.getNodeMemSize(), newNumaNode.getNodeMemSize(), Objects.equals(newNumaNode.getNodeMemSize(), oldNumaNode.getNodeMemSize()))); + logger.trace(String.format("oldNumaNode.getNodeID(): %s, newNumaNode.getNodeID(): %s, equals: %s", oldNumaNode.getNodeID(), newNumaNode.getNodeID(), Objects.equals(newNumaNode.getNodeID(), oldNumaNode.getNodeID()))); + + return newNumaNode.getNodeCPUs().equals(oldNumaNode.getNodeCPUs()) + && newNumaNode.getNodeDistance().equals(oldNumaNode.getNodeDistance()) + && Objects.equals(newNumaNode.getNodeMemSize(), oldNumaNode.getNodeMemSize()) + && Objects.equals(newNumaNode.getNodeID(), oldNumaNode.getNodeID()); + })) + .forEach(oldNumaNode -> { + logger.trace("remove old numa node: " + JSONObjectUtil.toJsonString(oldNumaNode)); + + dbf.removeByPrimaryKey(oldNumaNode.getId(), HostNumaNodeVO.class); + }); + + newHostNumaNodes.stream() + .filter(newNumaNode -> oldHostNumaNodes.stream() + .noneMatch(oldNumaNode -> { + logger.trace(String.format("oldNumaNode.getNodeCPUs(): %s, newNumaNode.getNodeCPUs(): %s, equals: %s", oldNumaNode.getNodeCPUs(), newNumaNode.getNodeCPUs(), newNumaNode.getNodeCPUs().equals(oldNumaNode.getNodeCPUs()))); + logger.trace(String.format("oldNumaNode.getNodeDistance(): %s, newNumaNode.getNodeDistance(): %s, equals: %s", oldNumaNode.getNodeDistance(), newNumaNode.getNodeDistance(), newNumaNode.getNodeDistance().equals(oldNumaNode.getNodeDistance()))); + logger.trace(String.format("oldNumaNode.getNodeMemSize(): %s, newNumaNode.getNodeMemSize(): %s, equals: %s", oldNumaNode.getNodeMemSize(), newNumaNode.getNodeMemSize(), Objects.equals(newNumaNode.getNodeMemSize(), oldNumaNode.getNodeMemSize()))); + logger.trace(String.format("oldNumaNode.getNodeID(): %s, newNumaNode.getNodeID(): %s, equals: %s", oldNumaNode.getNodeID(), newNumaNode.getNodeID(), Objects.equals(newNumaNode.getNodeID(), oldNumaNode.getNodeID()))); + + return oldNumaNode.getNodeCPUs().equals(newNumaNode.getNodeCPUs()) + && oldNumaNode.getNodeDistance().equals(newNumaNode.getNodeDistance()) + && Objects.equals(oldNumaNode.getNodeMemSize(), newNumaNode.getNodeMemSize()) + && Objects.equals(oldNumaNode.getNodeID(), newNumaNode.getNodeID()); + })) + .forEach(newNumaNode -> { + logger.trace("persist newNumaNode: " + JSONObjectUtil.toJsonString(newNumaNode)); + dbf.persist(newNumaNode); + }); + logger.info(String.format("Update Host[%s] NUMA Topology Successfully!", host.getUuid())); trigger.next(); } diff --git a/compute/src/main/java/org/zstack/compute/vm/AbstractVmInstance.java b/compute/src/main/java/org/zstack/compute/vm/AbstractVmInstance.java index f0763e792e6..100bdb2bc86 100755 --- a/compute/src/main/java/org/zstack/compute/vm/AbstractVmInstance.java +++ b/compute/src/main/java/org/zstack/compute/vm/AbstractVmInstance.java @@ -12,6 +12,7 @@ import java.util.Set; +import static org.zstack.core.Platform.canerr; import static org.zstack.core.Platform.err; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) @@ -29,6 +30,13 @@ public abstract class AbstractVmInstance implements VmInstance { StartVmInstanceMsg.class.getName() ); + allowedOperations.addState(VmInstanceState.NoState, + APIStopVmInstanceMsg.class.getName(), + APIRebootVmInstanceMsg.class.getName(), + RebootVmInstanceMsg.class.getName(), + StopVmInstanceMsg.class.getName() + ); + allowedOperations.addState(VmInstanceState.Running, APIStopVmInstanceMsg.class.getName(), StopVmInstanceMsg.class.getName(), @@ -51,6 +59,7 @@ public abstract class AbstractVmInstance implements VmInstance { APIChangeInstanceOfferingMsg.class.getName(), APIGetVmMigrationCandidateHostsMsg.class.getName(), APIDetachL3NetworkFromVmMsg.class.getName(), + APIChangeVmNicStateMsg.class.getName(), DetachNicFromVmMsg.class.getName(), APIAttachIsoToVmInstanceMsg.class.getName(), AttachIsoToVmInstanceMsg.class.getName(), @@ -58,9 +67,15 @@ public abstract class AbstractVmInstance implements VmInstance { APIGetVmConsoleAddressMsg.class.getName(), APIDeleteVmStaticIpMsg.class.getName(), APIPauseVmInstanceMsg.class.getName(), - CreateTemplateFromVmRootVolumeMsg.class.getName(), + CreateTemplateFromRootVolumeSnapShotVmMsg.class.getName(), + CreateTemplateFromRootVolumeVmMsg.class.getName(), AddL3NetworkToVmNicMsg.class.getName(), - DeleteL3NetworkFromVmNicMsg.class.getName() + DeleteL3NetworkFromVmNicMsg.class.getName(), + APIChangeVmNicNetworkMsg.class.getName(), + FlattenVmInstanceMsg.class.getName(), + APIFlattenVmInstanceMsg.class.getName(), + CancelFlattenVmInstanceMsg.class.getName(), + APISetVmStaticIpMsg.class.getName() ); allowedOperations.addState(VmInstanceState.Stopped, @@ -71,7 +86,8 @@ public abstract class AbstractVmInstance implements VmInstance { StartVmInstanceMsg.class.getName(), AttachDataVolumeToVmMsg.class.getName(), DetachDataVolumeFromVmMsg.class.getName(), - CreateTemplateFromVmRootVolumeMsg.class.getName(), + CreateTemplateFromRootVolumeSnapShotVmMsg.class.getName(), + CreateTemplateFromRootVolumeVmMsg.class.getName(), VmAttachNicMsg.class.getName(), APIAttachL3NetworkToVmMsg.class.getName(), APIChangeVmNicNetworkMsg.class.getName(), @@ -79,6 +95,7 @@ public abstract class AbstractVmInstance implements VmInstance { APIChangeInstanceOfferingMsg.class.getName(), StopVmInstanceMsg.class.getName(), APIDetachL3NetworkFromVmMsg.class.getName(), + APIChangeVmNicStateMsg.class.getName(), DetachNicFromVmMsg.class.getName(), APIAttachIsoToVmInstanceMsg.class.getName(), AttachIsoToVmInstanceMsg.class.getName(), @@ -92,6 +109,9 @@ public abstract class AbstractVmInstance implements VmInstance { DeleteVmCdRomMsg.class.getName(), CreateVmCdRomMsg.class.getName(), RestoreVmInstanceMsg.class.getName(), + FlattenVmInstanceMsg.class.getName(), + APIFlattenVmInstanceMsg.class.getName(), + CancelFlattenVmInstanceMsg.class.getName(), APISetVmBootVolumeMsg.class.getName() ); @@ -164,11 +184,16 @@ public abstract class AbstractVmInstance implements VmInstance { APIChangeInstanceOfferingMsg.class.getName(), APIGetVmMigrationCandidateHostsMsg.class.getName(), APIDetachL3NetworkFromVmMsg.class.getName(), + APIChangeVmNicStateMsg.class.getName(), DetachNicFromVmMsg.class.getName(), APIAttachIsoToVmInstanceMsg.class.getName(), AttachIsoToVmInstanceMsg.class.getName(), APIDetachIsoFromVmInstanceMsg.class.getName(), - CreateTemplateFromVmRootVolumeMsg.class.getName(), + CreateTemplateFromRootVolumeSnapShotVmMsg.class.getName(), + CreateTemplateFromRootVolumeVmMsg.class.getName(), + FlattenVmInstanceMsg.class.getName(), + APIFlattenVmInstanceMsg.class.getName(), + CancelFlattenVmInstanceMsg.class.getName(), APIDeleteVmStaticIpMsg.class.getName()); allowedOperations.addState(VmInstanceState.Pausing, diff --git a/compute/src/main/java/org/zstack/compute/vm/ApplianceVmAllocatePrimaryStorageFlow.java b/compute/src/main/java/org/zstack/compute/vm/ApplianceVmAllocatePrimaryStorageFlow.java index eb80d66c156..eab79d8e1dd 100644 --- a/compute/src/main/java/org/zstack/compute/vm/ApplianceVmAllocatePrimaryStorageFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/ApplianceVmAllocatePrimaryStorageFlow.java @@ -73,7 +73,7 @@ public void run(final FlowTrigger trigger, final Map data) { } AllocatePrimaryStorageSpaceMsg rmsg = new AllocatePrimaryStorageSpaceMsg(); - rmsg.setRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForRootVolume()); + rmsg.setCandidatePrimaryStorageUuids(spec.getCandidatePrimaryStorageUuidsForRootVolume()); rmsg.setVmInstanceUuid(spec.getVmInventory().getUuid()); if (spec.getImageSpec() != null) { rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); @@ -85,6 +85,7 @@ public void run(final FlowTrigger trigger, final Map data) { rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateNewVm.toString()); rmsg.setPossiblePrimaryStorageTypes(primaryStorageTypes); rmsg.setAllocationStrategy(allocatorStrategyType); + rmsg.setSystemTags(spec.getRootVolumeSystemTags()); bus.makeLocalServiceId(rmsg, PrimaryStorageConstant.SERVICE_ID); msgs.add(rmsg); @@ -127,6 +128,7 @@ public void run(MessageReply reply) { volumeSpec.setPrimaryStorageInventory(ar.getPrimaryStorageInventory()); volumeSpec.setSize(ar.getSize()); volumeSpec.setType(msg.getImageUuid() != null ? VolumeType.Root.toString() : VolumeType.Data.toString()); + volumeSpec.setTags(spec.getRootVolumeSystemTags()); spec.getVolumeSpecs().add(volumeSpec); completion.success(); diff --git a/compute/src/main/java/org/zstack/compute/vm/AttachIsoOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/AttachIsoOnHypervisorFlow.java index d49b670bf2f..ea4639458cc 100755 --- a/compute/src/main/java/org/zstack/compute/vm/AttachIsoOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/AttachIsoOnHypervisorFlow.java @@ -31,7 +31,7 @@ public void run(final FlowTrigger trigger, Map data) { final VmInstanceSpec.IsoSpec isoSpec = spec.getDestIsoList().stream() .filter(s -> s.getImageUuid().equals(iso.getUuid())) .findAny() - .get(); + .orElse(null); AttachIsoOnHypervisorMsg msg = new AttachIsoOnHypervisorMsg(); msg.setHostUuid(spec.getDestHost().getUuid()); diff --git a/compute/src/main/java/org/zstack/compute/vm/CpuTopology.java b/compute/src/main/java/org/zstack/compute/vm/CpuTopology.java new file mode 100644 index 00000000000..c8cdabc5d09 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/CpuTopology.java @@ -0,0 +1,104 @@ +package org.zstack.compute.vm; + +import org.zstack.header.errorcode.OperationFailureException; + +import static org.zstack.core.Platform.operr; + +public class CpuTopology { + int cpuNum; + Integer cpuSockets; + Integer cpuCores; + Integer cpuThreads; + + public CpuTopology(int cpuNum, String cpuSockets, String cpuCores, String cpuThreads) { + this.cpuNum = cpuNum; + + this.cpuSockets = cpuSockets == null ? null : Integer.valueOf(cpuSockets); + this.cpuCores = cpuCores == null ? null : Integer.valueOf(cpuCores); + this.cpuThreads = cpuThreads == null ? null : Integer.valueOf(cpuThreads); + } + + public String calculateValidTopologyWithoutException() { + return calculateValidTopology(false); + } + + public String calculateValidTopology(boolean throwException) { + if (cpuSockets == null && cpuCores == null && cpuThreads == null) { + return null; + } + + int socketNum, coreNum, threadNum; + if (cpuSockets == null) { + if (cpuCores != null && cpuThreads != null) { + socketNum = cpuNum / cpuCores / cpuThreads; + coreNum = cpuCores; + threadNum = cpuThreads; + } else if (cpuCores != null) { + socketNum = cpuNum / cpuCores; + coreNum = cpuCores; + threadNum = 1; + } else { + socketNum = cpuNum / cpuThreads; + coreNum = 1; + threadNum = cpuThreads; + } + } else { + socketNum = cpuSockets; + if (cpuThreads == null && cpuCores != null) { + threadNum = cpuNum / cpuCores / cpuSockets; + coreNum = cpuCores; + } else if (cpuThreads == null) { + coreNum = cpuNum / cpuSockets; + threadNum = 1; + } else if (cpuCores == null) { + coreNum = cpuNum / cpuSockets / cpuThreads; + threadNum = cpuThreads; + } else { + coreNum = cpuCores; + threadNum = cpuThreads; + } + } + + // check the topology is valid + if (cpuNum >= socketNum * coreNum * threadNum) { + cpuSockets = socketNum; + cpuCores = coreNum; + cpuThreads = threadNum; + return null; + } + + if (throwException) { + throw new OperationFailureException(operr("cpu topology is not correct, cpuNum[%s], configured cpuSockets[%s], cpuCores[%s], cpuThreads[%s];" + + " Calculated cpuSockets[%s], cpuCores[%s], cpuThreads[%s]", + cpuNum, cpuSockets, cpuCores, cpuThreads, socketNum, coreNum, threadNum)); + } else { + return String.format("cpu topology is not correct, cpuNum[%s], configured cpuSockets[%s], cpuCores[%s], cpuThreads[%s];" + + " Calculated cpuSockets[%s], cpuCores[%s], cpuThreads[%s]", + cpuNum, cpuSockets, cpuCores, cpuThreads, socketNum, coreNum, threadNum); + } + } + + public Integer getCpuSockets() { + return cpuSockets; + } + + public void setCpuSockets(Integer cpuSockets) { + this.cpuSockets = cpuSockets; + } + + public Integer getCpuCores() { + return cpuCores; + } + + public void setCpuCores(Integer cpuCores) { + this.cpuCores = cpuCores; + } + + public Integer getCpuThreads() { + return cpuThreads; + } + + public void setCpuThreads(Integer cpuThreads) { + this.cpuThreads = cpuThreads; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/CustomNicOperator.java b/compute/src/main/java/org/zstack/compute/vm/CustomNicOperator.java new file mode 100644 index 00000000000..7bf90f03688 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/CustomNicOperator.java @@ -0,0 +1,79 @@ +package org.zstack.compute.vm; + +import org.apache.commons.lang.StringUtils; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.TagUtils; + +import java.util.List; +import java.util.Map; + +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +public class CustomNicOperator { + private final String vmUuid; + private final String l3Uuid; + public CustomNicOperator(String vmUuid,String l3Uuid){ + this.vmUuid = vmUuid; + this.l3Uuid = l3Uuid; + } + public String getCustomNicId() { + List> tokenList = VmSystemTags.CUSTOM_NIC_UUID.getTokensOfTagsByResourceUuid(vmUuid); + for (Map tokens : tokenList) { + if (StringUtils.equals(tokens.get(VmSystemTags.STATIC_IP_L3_UUID_TOKEN), l3Uuid)) { + return tokens.get(VmSystemTags.NIC_UUID_TOKEN); + } + } + return null; + } + + public void deleteNicTags() { + VmSystemTags.CUSTOM_MAC.delete(vmUuid, TagUtils.tagPatternToSqlPattern(VmSystemTags.CUSTOM_MAC.instantiateTag( + map(e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, l3Uuid)) + ))); + VmSystemTags.STATIC_IP.delete(vmUuid, TagUtils.tagPatternToSqlPattern(VmSystemTags.STATIC_IP.instantiateTag( + map(e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, l3Uuid)) + ))); + VmSystemTags.CUSTOM_NIC_UUID.delete(vmUuid, TagUtils.tagPatternToSqlPattern(VmSystemTags.CUSTOM_NIC_UUID.instantiateTag( + map(e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, l3Uuid)) + ))); + } + + public void updateNicTags(String mac ,String ip,String nicUuid){ + this.deleteNicTags(); + // set the results to system tag + // because MacOperator doesn't provide a set mac method , so we set it here using SystemTagCreator + if (mac != null) { + SystemTagCreator macCreator = VmSystemTags.CUSTOM_MAC.newSystemTagCreator(vmUuid); + macCreator.ignoreIfExisting = false; + macCreator.inherent = false; + macCreator.setTagByTokens(map( + e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.MAC_TOKEN, mac) + )); + macCreator.create(); + } + + if (ip != null) { + SystemTagCreator ipTagCreator = VmSystemTags.STATIC_IP.newSystemTagCreator(vmUuid); + ipTagCreator.ignoreIfExisting = false; + ipTagCreator.inherent = false; + ipTagCreator.setTagByTokens(map( + e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.STATIC_IP_TOKEN, ip) + )); + ipTagCreator.create(); + } + + if (nicUuid != null) { + SystemTagCreator nicIdCreator = VmSystemTags.CUSTOM_NIC_UUID.newSystemTagCreator(vmUuid); + nicIdCreator.ignoreIfExisting = false; + nicIdCreator.inherent = false; + nicIdCreator.setTagByTokens(map( + e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.NIC_UUID_TOKEN, nicUuid) + )); + nicIdCreator.create(); + } + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/FlattenVmLongJob.java b/compute/src/main/java/org/zstack/compute/vm/FlattenVmLongJob.java new file mode 100644 index 00000000000..e68097e3aaa --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/FlattenVmLongJob.java @@ -0,0 +1,74 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.longjob.LongJob; +import org.zstack.header.longjob.LongJobFor; +import org.zstack.header.longjob.LongJobVO; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.*; +import org.zstack.utils.gson.JSONObjectUtil; + +@LongJobFor(APIFlattenVmInstanceMsg.class) +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class FlattenVmLongJob implements LongJob { + @Autowired + private CloudBus bus; + + private String vmInstanceUuid; + + @Override + public void start(LongJobVO job, ReturnValueCompletion completion) { + FlattenVmInstanceMsg msg = JSONObjectUtil.toObject(job.getJobData(), FlattenVmInstanceMsg.class); + vmInstanceUuid = msg.getUuid(); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, msg.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + APIFlattenVmInstanceEvent event = new APIFlattenVmInstanceEvent(job.getApiId()); + event.setInventory(((FlattenVmInstanceReply) reply).getInventory()); + completion.success(event); + } + }); + } + + @Override + public void cancel(LongJobVO job, ReturnValueCompletion completion) { + FlattenVmInstanceMsg msg = JSONObjectUtil.toObject(job.getJobData(), FlattenVmInstanceMsg.class); + CancelFlattenVmInstanceMsg cmsg = new CancelFlattenVmInstanceMsg(); + cmsg.setCancellationApiId(job.getApiId()); + cmsg.setUuid(msg.getUuid()); + bus.makeTargetServiceIdByResourceUuid(cmsg, VmInstanceConstant.SERVICE_ID, msg.getUuid()); + bus.send(cmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + completion.success(false); + } + }); + } + + @Override + public Class getAuditType() { + return VmInstanceVO.class; + } + + @Override + public String getAuditResourceUuid() { + return vmInstanceUuid; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/GetInterdependentL3NetworksExtensionPoint.java b/compute/src/main/java/org/zstack/compute/vm/GetInterdependentL3NetworksExtensionPoint.java index 16f9e40ca86..351e469d78b 100644 --- a/compute/src/main/java/org/zstack/compute/vm/GetInterdependentL3NetworksExtensionPoint.java +++ b/compute/src/main/java/org/zstack/compute/vm/GetInterdependentL3NetworksExtensionPoint.java @@ -1,5 +1,6 @@ package org.zstack.compute.vm; +import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.L3NetworkVO; import java.util.List; @@ -8,5 +9,5 @@ * Created by kayo on 2018/10/29. */ public interface GetInterdependentL3NetworksExtensionPoint { - List afterFilterByImage(List l3s, List bsUuids, String imageUuid); + List afterFilterByImage(List l3s, List bsUuids, String imageUuid); } diff --git a/compute/src/main/java/org/zstack/compute/vm/GetVmNicQosMsg.java b/compute/src/main/java/org/zstack/compute/vm/GetVmNicQosMsg.java new file mode 100644 index 00000000000..ea487add009 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/GetVmNicQosMsg.java @@ -0,0 +1,38 @@ +package org.zstack.compute.vm; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.vm.VmInstanceMessage; + +/** + * Created by LiangHanYu on 2022/7/1 14:10 + */ +public class GetVmNicQosMsg extends NeedReplyMessage implements VmInstanceMessage { + private String uuid; + private Boolean forceSync = false; + private String vmInstanceUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Boolean getForceSync() { + return forceSync; + } + + public void setForceSync(Boolean forceSync) { + this.forceSync = forceSync; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/GetVmNicQosReply.java b/compute/src/main/java/org/zstack/compute/vm/GetVmNicQosReply.java new file mode 100644 index 00000000000..9fa4fd83078 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/GetVmNicQosReply.java @@ -0,0 +1,27 @@ +package org.zstack.compute.vm; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2022/7/1 14:10 + */ +public class GetVmNicQosReply extends MessageReply { + private long outboundBandwidth = -1; + private long inboundBandwidth = -1; + + public long getOutboundBandwidth() { + return outboundBandwidth; + } + + public void setOutboundBandwidth(long outboundBandwidth) { + this.outboundBandwidth = outboundBandwidth; + } + + public long getInboundBandwidth() { + return inboundBandwidth; + } + + public void setInboundBandwidth(long inboundBandwidth) { + this.inboundBandwidth = inboundBandwidth; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/InitializeResourceConfigExtensionPoint.java b/compute/src/main/java/org/zstack/compute/vm/InitializeResourceConfigExtensionPoint.java new file mode 100644 index 00000000000..a2a380910a9 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/InitializeResourceConfigExtensionPoint.java @@ -0,0 +1,69 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.config.GlobalConfigException; +import org.zstack.header.core.Completion; +import org.zstack.header.vm.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import static org.zstack.core.Platform.operr; + +public class InitializeResourceConfigExtensionPoint implements PreVmInstantiateResourceExtensionPoint { + private static final CLogger logger = Utils.getLogger(InitializeResourceConfigExtensionPoint.class); + + @Autowired + private VmFactoryManager vmFactoryManager; + + @Override + public void preBeforeInstantiateVmResource(VmInstanceSpec spec) throws VmInstantiateResourceException { + // pass + } + + /** + * vm is almost allocated all resources including host so + * use vm's type and hypervisor to initialize its resource + * configs + * @param spec allocated vm spec before creation + * @param completion callback + */ + @Override + public void preInstantiateVmResource(VmInstanceSpec spec, Completion completion) { + // factory only requested by new create vm + if (spec.getCurrentVmOperation() != VmInstanceConstant.VmOperation.NewCreate) { + completion.success(); + return; + } + + // if no dest host specified, means this vm do not have available + // hypervisor, record and complete with success + if (spec.getDestHost() == null) { + logger.debug(String.format("create vm[uuid: %s] but no host found, skip create configuration", spec.getVmInventory().getUuid())); + completion.success(); + return; + } + + HypervisorBasedVmConfigurationFactory vicf = vmFactoryManager.getVmInstanceConfigurationFactory(spec.getDestHost().getHypervisorType()); + if (vicf == null) { + logger.debug(String.format("no available VmInstanceConfigurationFactory found for vm[uuid: %s, hypervisor: %s]," + + " skip vm configuration", spec.getVmInventory().getUuid(), spec.getDestHost().getHypervisorType())); + completion.success(); + return; + } + + try { + vicf.createVmConfigurations(spec); + } catch (GlobalConfigException e) { + logger.warn(String.format("create vm[uuid: %s] configuration failed, %s", spec.getVmInventory().getUuid(), e.getMessage()), e); + completion.fail(operr(e.getMessage())); + return; + } + + completion.success(); + } + + @Override + public void preReleaseVmResource(VmInstanceSpec spec, Completion completion) { + completion.success(); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/InstantiateVmFromNewCreatedStruct.java b/compute/src/main/java/org/zstack/compute/vm/InstantiateVmFromNewCreatedStruct.java index d75e93a1c75..4a0d2ba9627 100644 --- a/compute/src/main/java/org/zstack/compute/vm/InstantiateVmFromNewCreatedStruct.java +++ b/compute/src/main/java/org/zstack/compute/vm/InstantiateVmFromNewCreatedStruct.java @@ -1,11 +1,16 @@ package org.zstack.compute.vm; -import org.zstack.header.vm.*; +import org.zstack.header.vm.APICreateVmInstanceMsg; +import org.zstack.header.vm.CreateVmInstanceMsg; +import org.zstack.header.vm.InstantiateNewCreatedVmInstanceMsg; +import org.zstack.header.vm.VmCreationStrategy; +import org.zstack.header.vm.VmNicSpec; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import java.util.Map; + /** * Created by xing5 on 2016/9/13. */ @@ -15,14 +20,49 @@ public class InstantiateVmFromNewCreatedStruct { private Map> dataVolumeFromTemplateSystemTags; private List l3NetworkUuids; private String rootDiskOfferingUuid; - private String primaryStorageUuidForRootVolume; - private String primaryStorageUuidForDataVolume; private VmCreationStrategy strategy = VmCreationStrategy.InstantStart; private List rootVolumeSystemTags; private List dataVolumeSystemTags; private String requiredHostUuid; private List softAvoidHostUuids; private List avoidHostUuids; + private Map> dataVolumeSystemTagsOnIndex; + private List disableL3Networks; + private List sshKeyPairUuids; + private final List candidatePrimaryStorageUuidsForRootVolume = new ArrayList<>(); + private final List candidatePrimaryStorageUuidsForDataVolume = new ArrayList<>(); + + public List getCandidatePrimaryStorageUuidsForRootVolume() { + return candidatePrimaryStorageUuidsForRootVolume; + } + + public void setCandidatePrimaryStorageUuidsForRootVolume(List candidatePrimaryStorageUuidsForRootVolume) { + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (candidatePrimaryStorageUuidsForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.addAll(candidatePrimaryStorageUuidsForRootVolume); + } + } + + public List getCandidatePrimaryStorageUuidsForDataVolume() { + return candidatePrimaryStorageUuidsForDataVolume; + } + + public void setCandidatePrimaryStorageUuidsForDataVolume(List candidatePrimaryStorageUuidsForDataVolume) { + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (candidatePrimaryStorageUuidsForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.addAll(candidatePrimaryStorageUuidsForDataVolume); + } + } + + private List diskAOs; + + public List getDiskAOs() { + return diskAOs; + } + + public void setDiskAOs(List diskAOs) { + this.diskAOs = diskAOs; + } public List getRootVolumeSystemTags() { return rootVolumeSystemTags; @@ -91,14 +131,17 @@ public static InstantiateVmFromNewCreatedStruct fromMessage(InstantiateNewCreate struct.setDataVolumeFromTemplateSystemTags(msg.getDataVolumeFromTemplateSystemTags()); struct.setL3NetworkUuids(msg.getL3NetworkUuids()); struct.setRootDiskOfferingUuid(msg.getRootDiskOfferingUuid()); - struct.setPrimaryStorageUuidForRootVolume(msg.getPrimaryStorageUuidForRootVolume()); - struct.setPrimaryStorageUuidForDataVolume(msg.getPrimaryStorageUuidForDataVolume()); + struct.setCandidatePrimaryStorageUuidsForRootVolume(msg.getCandidatePrimaryStorageUuidsForRootVolume()); + struct.setCandidatePrimaryStorageUuidsForDataVolume(msg.getCandidatePrimaryStorageUuidsForDataVolume()); struct.strategy = VmCreationStrategy.valueOf(msg.getStrategy()); struct.setRootVolumeSystemTags(msg.getRootVolumeSystemTags()); struct.setDataVolumeSystemTags(msg.getDataVolumeSystemTags()); struct.setRequiredHostUuid(msg.getHostUuid()); struct.setSoftAvoidHostUuids(msg.getSoftAvoidHostUuids()); struct.setAvoidHostUuids(msg.getAvoidHostUuids()); + struct.setDataVolumeSystemTagsOnIndex(msg.getDataVolumeSystemTagsOnIndex()); + struct.setDisableL3Networks(msg.getDisableL3Networks()); + struct.setDiskAOs(msg.getDiskAOs()); return struct; } @@ -109,30 +152,40 @@ public static InstantiateVmFromNewCreatedStruct fromMessage(CreateVmInstanceMsg struct.setDataVolumeFromTemplateSystemTags(msg.getDataVolumeFromTemplateSystemTags()); struct.setL3NetworkUuids(msg.getL3NetworkSpecs()); struct.setRootDiskOfferingUuid(msg.getRootDiskOfferingUuid()); - struct.setPrimaryStorageUuidForRootVolume(msg.getPrimaryStorageUuidForRootVolume()); - struct.setPrimaryStorageUuidForDataVolume(msg.getPrimaryStorageUuidForDataVolume()); + struct.setCandidatePrimaryStorageUuidsForRootVolume(msg.getCandidatePrimaryStorageUuidsForRootVolume()); + struct.setCandidatePrimaryStorageUuidsForDataVolume(msg.getCandidatePrimaryStorageUuidsForDataVolume()); struct.strategy = VmCreationStrategy.valueOf(msg.getStrategy()); struct.setRootVolumeSystemTags(msg.getRootVolumeSystemTags()); struct.setDataVolumeSystemTags(msg.getDataVolumeSystemTags()); struct.setRequiredHostUuid(msg.getHostUuid()); + struct.setDataVolumeSystemTagsOnIndex(msg.getDataVolumeSystemTagsOnIndex()); + struct.setDisableL3Networks(msg.getDisableL3Networks()); + struct.setDiskAOs(msg.getDiskAOs()); return struct; } - + @Deprecated public String getPrimaryStorageUuidForRootVolume() { - return primaryStorageUuidForRootVolume; + return this.candidatePrimaryStorageUuidsForRootVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForRootVolume.get(0); } public void setPrimaryStorageUuidForRootVolume(String primaryStorageUuidForRootVolume) { - this.primaryStorageUuidForRootVolume = primaryStorageUuidForRootVolume; + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (primaryStorageUuidForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.add(primaryStorageUuidForRootVolume); + } } + @Deprecated public String getPrimaryStorageUuidForDataVolume() { - return primaryStorageUuidForDataVolume; + return this.candidatePrimaryStorageUuidsForDataVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForDataVolume.get(0); } public void setPrimaryStorageUuidForDataVolume(String primaryStorageUuidForDataVolume) { - this.primaryStorageUuidForDataVolume = primaryStorageUuidForDataVolume; + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (primaryStorageUuidForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.add(primaryStorageUuidForDataVolume); + } } public String getRequiredHostUuid() { @@ -166,4 +219,28 @@ public Map> getDataVolumeFromTemplateSystemTags() { public void setDataVolumeFromTemplateSystemTags(Map> dataVolumeFromTemplateSystemTags) { this.dataVolumeFromTemplateSystemTags = dataVolumeFromTemplateSystemTags; } + + public Map> getDataVolumeSystemTagsOnIndex() { + return dataVolumeSystemTagsOnIndex; + } + + public void setDataVolumeSystemTagsOnIndex(Map> dataVolumeSystemTagsOnIndex) { + this.dataVolumeSystemTagsOnIndex = dataVolumeSystemTagsOnIndex; + } + + public List getDisableL3Networks() { + return disableL3Networks; + } + + public void setDisableL3Networks(List disableL3Networks) { + this.disableL3Networks = disableL3Networks; + } + + public List getSshKeyPairUuids() { + return sshKeyPairUuids; + } + + public void setSshKeyPairUuids(List sshKeyPairUuids) { + this.sshKeyPairUuids = sshKeyPairUuids; + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/MacOperator.java b/compute/src/main/java/org/zstack/compute/vm/MacOperator.java index bbb2a7f022f..5d500f451b5 100644 --- a/compute/src/main/java/org/zstack/compute/vm/MacOperator.java +++ b/compute/src/main/java/org/zstack/compute/vm/MacOperator.java @@ -3,18 +3,22 @@ import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.vm.VmNicVO; -import org.zstack.header.vm.VmNicVO_; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.vm.*; import org.zstack.tag.PatternedSystemTag; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; import java.math.BigInteger; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -28,6 +32,7 @@ public class MacOperator { private static final CLogger logger = Utils.getLogger(MacOperator.class); private static final Pattern pattern = Pattern.compile("([a-f0-9]{2}:){5}[a-f0-9]{2}"); + private static final Random random = new Random(); class VmMacStruct { private String l3Uuid; @@ -39,9 +44,6 @@ public VmMacStruct(String l3Uuid, String mac) { } } - @Autowired - private DatabaseFacade dbf; - private PatternedSystemTag that = VmSystemTags.CUSTOM_MAC; public List getMacInfobyVmUuid(String vmUuid) { @@ -94,10 +96,110 @@ public void validateAvailableMac(String mac) { } } - public boolean checkDuplicateMac(String hypervisorType, String mac) { + public boolean checkDuplicateMac(String hypervisorType, String l3Uuid, String mac) { + if (!VmInstanceConstant.KVM_HYPERVISOR_TYPE.equals(hypervisorType)) { + return false; + } + + L3NetworkVO l3vo = Q.New(L3NetworkVO.class) + .eq(L3NetworkVO_.uuid, l3Uuid).find(); + if (l3vo == null) { + return false; + } + + List l3Uuids = Q.New(L3NetworkVO.class) + .select(L3NetworkVO_.uuid) + .eq(L3NetworkVO_.l2NetworkUuid, l3vo.getL2NetworkUuid()) + .listValues(); + + if (l3Uuids.isEmpty()) { + return false; + } + return Q.New(VmNicVO.class) .eq(VmNicVO_.hypervisorType, hypervisorType) .eq(VmNicVO_.mac, mac.toLowerCase()) + .in(VmNicVO_.l3NetworkUuid, l3Uuids) + .notEq(VmNicVO_.state, VmNicState.disable) .isExists(); } + + public static String generateMacWithDeviceId(short deviceId) { + VmMacAddressSchemaType type; + try { + type = VmMacAddressSchemaType.valueOf(VmGlobalProperty.vmMacAddressSchema); + } catch (Exception e) { + type = VmMacAddressSchemaType.Random; + } + + switch (type) { + case Ip: + return generateMacWithDeviceIdIp(deviceId); + case Random: + default: + return generateMacWithDeviceIdRandom(deviceId); + } + } + + public static String generateMacWithDeviceIdIp(short deviceId) { + String mgtIp = Platform.getManagementServerIp(); + if (!NetworkUtils.isIpv4Address(mgtIp)) { + return generateMacWithDeviceIdRandom(deviceId); + } + + /* encode mgt ip address into mac address: for example, + * mgt ip is: 172.24.0.81, its hex string: AC 18 00 51, + * so mac address will look like: fa:00:51:xx:xx:yy + * xx:xx are random. yy is device ID */ + int mgtIpL = (int)NetworkUtils.ipv4StringToLong(mgtIp); + String mgtIpStr = Integer.toHexString(mgtIpL); + if (mgtIpStr.length() < 8) { + String compensate = StringUtils.repeat("0", 8 - mgtIpStr.length()); + mgtIpStr = compensate + mgtIpStr; + } + + StringBuilder sb = new StringBuilder("fa").append(":"); + sb.append(mgtIpStr, 4, 6).append(":"); + sb.append(mgtIpStr, 6, 8).append(":"); + + int seed = random.nextInt(); + String seedStr = Integer.toHexString(seed); + if (seedStr.length() < 4) { + String compensate = StringUtils.repeat("0", 4 - seedStr.length()); + seedStr = compensate + seedStr; + } + + sb.append(seedStr, 0, 2).append(":"); + sb.append(seedStr, 2, 4).append(":"); + String deviceIdStr = Integer.toHexString(deviceId); + if (deviceIdStr.length() < 2) { + deviceIdStr = "0" + deviceIdStr; + } + sb.append(deviceIdStr); + return sb.toString(); + } + + public static String generateMacWithDeviceIdRandom(short deviceId) { + int seed = random.nextInt(); + String seedStr = Integer.toHexString(seed); + if (seedStr.length() < 8) { + String compensate = StringUtils.repeat("0", 8 - seedStr.length()); + seedStr = compensate + seedStr; + } + String octet2 = seedStr.substring(0, 2); + String octet3 = seedStr.substring(2, 4); + String octet4 = seedStr.substring(4, 6); + String octet5 = seedStr.substring(6, 8); + StringBuilder sb = new StringBuilder("fa").append(":"); + sb.append(octet2).append(":"); + sb.append(octet3).append(":"); + sb.append(octet4).append(":"); + sb.append(octet5).append(":"); + String deviceIdStr = Integer.toHexString(deviceId); + if (deviceIdStr.length() < 2) { + deviceIdStr = "0" + deviceIdStr; + } + sb.append(deviceIdStr); + return sb.toString(); + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/NewVmInstanceMsgBuilder.java b/compute/src/main/java/org/zstack/compute/vm/NewVmInstanceMsgBuilder.java index 22b50262266..124f1fb5e9b 100644 --- a/compute/src/main/java/org/zstack/compute/vm/NewVmInstanceMsgBuilder.java +++ b/compute/src/main/java/org/zstack/compute/vm/NewVmInstanceMsgBuilder.java @@ -1,5 +1,6 @@ package org.zstack.compute.vm; +import org.apache.commons.lang.StringUtils; import org.zstack.core.db.Q; import org.zstack.header.configuration.InstanceOfferingVO; import org.zstack.header.configuration.InstanceOfferingVO_; @@ -7,32 +8,62 @@ import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.l3.L3NetworkVO_; -import org.zstack.header.vm.CreateVmInstanceMsg; -import org.zstack.header.vm.NewVmInstanceMessage; -import org.zstack.header.vm.NewVmInstanceMessage2; -import org.zstack.header.vm.VmNicSpec; +import org.zstack.header.vm.*; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.gson.JSONObjectUtil; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; /** * Created by MaJin on 2020/10/10. */ public class NewVmInstanceMsgBuilder { private static List getVmNicSpecsFromNewVmInstanceMsg(NewVmInstanceMessage msg) { - List nicSpecs = new ArrayList<>(); + if (CollectionUtils.isEmpty(msg.getL3NetworkUuids())) { + return Collections.EMPTY_LIST; + } + List vmNicParms = Collections.emptyList(); + if (msg.getVmNicParams() != null && !msg.getVmNicParams().isEmpty()) { + vmNicParms = JSONObjectUtil.toCollection(msg.getVmNicParams(), ArrayList.class, VmNicParam.class); + } + List nicSpecs = new ArrayList<>(); for (String l3Uuid : msg.getL3NetworkUuids()) { List l3Invs = new ArrayList<>(); L3NetworkVO l3vo = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, l3Uuid).find(); L3NetworkInventory inv = L3NetworkInventory.valueOf(l3vo); l3Invs.add(inv); - nicSpecs.add(new VmNicSpec(l3Invs)); + + VmNicSpec vmNicSpec = new VmNicSpec(l3Invs); + + + if (!vmNicParms.isEmpty()) { + List nicParmOfL3 = vmNicParms.stream().filter(vmNicParm -> vmNicParm.getL3NetworkUuid().equals(l3Uuid)).distinct().collect(Collectors.toList()); + if (!nicParmOfL3.isEmpty()) { + vmNicSpec.setVmNicParams(nicParmOfL3); + vmNicSpec.setNicDriverType(nicParmOfL3.get(0).getDriverType()); + } + } + nicSpecs.add(vmNicSpec); +// nicSpecs.add(new VmNicSpec(l3Invs, +// vmNicParms != null && !vmNicParms.isEmpty() ? vmNicParms.get(i) : null)); } + return nicSpecs; } + private static List getDisableL3FromNewVmInstanceMsg(NewVmInstanceMessage msg) { + if (StringUtils.isEmpty(msg.getVmNicParams())) { + return Collections.EMPTY_LIST; + } + List vmNicParms = JSONObjectUtil.toCollection(msg.getVmNicParams(), ArrayList.class, VmNicParam.class); + return vmNicParms.stream().filter(nic -> VmNicState.disable.toString().equals(nic.getState())).map(VmNicParam::getL3NetworkUuid).collect(Collectors.toList()); + } + public static CreateVmInstanceMsg fromAPINewVmInstanceMsg(NewVmInstanceMessage2 msg) { CreateVmInstanceMsg cmsg = new CreateVmInstanceMsg(); APICreateMessage api = (APICreateMessage) msg; @@ -40,11 +71,13 @@ public static CreateVmInstanceMsg fromAPINewVmInstanceMsg(NewVmInstanceMessage2 if(msg.getZoneUuid() != null){ cmsg.setZoneUuid(msg.getZoneUuid()); }else{ - String zoneUuid = Q.New(L3NetworkVO.class) - .select(L3NetworkVO_.zoneUuid) - .eq(L3NetworkVO_.uuid, msg.getL3NetworkUuids().get(0)) - .findValue(); - cmsg.setZoneUuid(zoneUuid); + if (!CollectionUtils.isEmpty(msg.getL3NetworkUuids())) { + String zoneUuid = Q.New(L3NetworkVO.class) + .select(L3NetworkVO_.zoneUuid) + .eq(L3NetworkVO_.uuid, msg.getL3NetworkUuids().get(0)) + .findValue(); + cmsg.setZoneUuid(zoneUuid); + } } final String instanceOfferingUuid = msg.getInstanceOfferingUuid(); @@ -57,10 +90,12 @@ public static CreateVmInstanceMsg fromAPINewVmInstanceMsg(NewVmInstanceMessage2 cmsg.setCpuNum(msg.getCpuNum()); cmsg.setMemorySize(msg.getMemorySize()); + cmsg.setReservedMemorySize(msg.getReservedMemorySize() == null ? 0 : msg.getReservedMemorySize()); cmsg.setAccountUuid(api.getSession().getAccountUuid()); cmsg.setName(msg.getName()); cmsg.setL3NetworkSpecs(getVmNicSpecsFromNewVmInstanceMsg(msg)); + cmsg.setDisableL3Networks(getDisableL3FromNewVmInstanceMsg(msg)); cmsg.setType(msg.getType()); cmsg.setClusterUuid(msg.getClusterUuid()); diff --git a/compute/src/main/java/org/zstack/compute/vm/SetVmNicQosMsg.java b/compute/src/main/java/org/zstack/compute/vm/SetVmNicQosMsg.java new file mode 100644 index 00000000000..620e672dcb0 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/SetVmNicQosMsg.java @@ -0,0 +1,47 @@ +package org.zstack.compute.vm; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.vm.VmInstanceMessage; + +/** + * Created by LiangHanYu on 2022/7/1 15:32 + */ +public class SetVmNicQosMsg extends NeedReplyMessage implements VmInstanceMessage { + private String uuid; + private Long outboundBandwidth; + private Long inboundBandwidth; + private String vmInstanceUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Long getOutboundBandwidth() { + return outboundBandwidth; + } + + public void setOutboundBandwidth(Long outboundBandwidth) { + this.outboundBandwidth = outboundBandwidth; + } + + public Long getInboundBandwidth() { + return inboundBandwidth; + } + + public void setInboundBandwidth(Long inboundBandwidth) { + this.inboundBandwidth = inboundBandwidth; + } + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/SetVmNicQosReply.java b/compute/src/main/java/org/zstack/compute/vm/SetVmNicQosReply.java new file mode 100644 index 00000000000..b77ff007829 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/SetVmNicQosReply.java @@ -0,0 +1,9 @@ +package org.zstack.compute.vm; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2022/7/1 15:32 + */ +public class SetVmNicQosReply extends MessageReply { +} diff --git a/compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java b/compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java index 9431ee5d12c..0fe152196f5 100755 --- a/compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java +++ b/compute/src/main/java/org/zstack/compute/vm/StaticIpOperator.java @@ -1,16 +1,29 @@ package org.zstack.compute.vm; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l3.*; +import org.zstack.header.tag.SystemTagCreateMessageValidator; import org.zstack.header.tag.SystemTagVO; import org.zstack.header.tag.SystemTagVO_; +import org.zstack.header.tag.SystemTagValidator; import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmNicVO; import org.zstack.tag.SystemTagCreator; +import org.zstack.tag.TagManager; import org.zstack.utils.TagUtils; +import org.zstack.utils.network.NicIpAddressInfo; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; @@ -21,6 +34,7 @@ import java.util.List; import java.util.Map; +import static org.zstack.core.Platform.*; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -28,9 +42,13 @@ * Created by xing5 on 2016/5/25. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class StaticIpOperator { +public class StaticIpOperator implements SystemTagCreateMessageValidator, SystemTagValidator { @Autowired private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + private TagManager tagMgr; public Map> getStaticIpbyVmUuid(String vmUuid) { Map> ret = new HashMap>(); @@ -46,6 +64,80 @@ public Map> getStaticIpbyVmUuid(String vmUuid) { return ret; } + public Map getNicNetworkInfoByVmUuid(String vmUuid) { + return getNicNetworkInfoBySystemTag(Q.New(SystemTagVO.class).select(SystemTagVO_.tag) + .eq(SystemTagVO_.resourceUuid, vmUuid).listValues()); + } + + public Map getNicNetworkInfoBySystemTag(List systemTags) { + Map ret = new HashMap<>(); + if (systemTags == null || systemTags.isEmpty()) { + return ret; + } + + for (String sysTag : systemTags) { + if(VmSystemTags.STATIC_IP.isMatch(sysTag)) { + Map token = TagUtils.parse(VmSystemTags.STATIC_IP.getTagFormat(), sysTag); + String l3Uuid = token.get(VmSystemTags.STATIC_IP_L3_UUID_TOKEN); + NicIpAddressInfo nicIpAddressInfo = ret.get(l3Uuid); + if (nicIpAddressInfo == null) { + ret.put(l3Uuid, new NicIpAddressInfo("", "", "", + "", "", "")); + } + String ip = token.get(VmSystemTags.STATIC_IP_TOKEN); + ip = IPv6NetworkUtils.ipv6TagValueToAddress(ip); + if (NetworkUtils.isIpv4Address(ip)) { + ret.get(l3Uuid).ipv4Address = ip; + } else if (IPv6NetworkUtils.isIpv6Address(ip)) { + ret.get(l3Uuid).ipv6Address = ip; + } else { + throw new ApiMessageInterceptionException(argerr("the static IP[%s] format error", ip)); + } + } + } + + if (ret.isEmpty()) { + return ret; + } + + for (String sysTag : systemTags) { + if(VmSystemTags.IPV4_GATEWAY.isMatch(sysTag)) { + Map token = TagUtils.parse(VmSystemTags.IPV4_GATEWAY.getTagFormat(), sysTag); + String l3Uuid = token.get(VmSystemTags.IPV4_GATEWAY_L3_UUID_TOKEN); + if (ret.get(l3Uuid) == null) { + continue; + } + ret.get(l3Uuid).ipv4Gateway = token.get(VmSystemTags.IPV4_GATEWAY_TOKEN); + } + if(VmSystemTags.IPV4_NETMASK.isMatch(sysTag)) { + Map token = TagUtils.parse(VmSystemTags.IPV4_NETMASK.getTagFormat(), sysTag); + String l3Uuid = token.get(VmSystemTags.IPV4_NETMASK_L3_UUID_TOKEN); + if (ret.get(l3Uuid) == null) { + continue; + } + ret.get(l3Uuid).ipv4Netmask = token.get(VmSystemTags.IPV4_NETMASK_TOKEN); + } + if(VmSystemTags.IPV6_GATEWAY.isMatch(sysTag)) { + Map token = TagUtils.parse(VmSystemTags.IPV6_GATEWAY.getTagFormat(), sysTag); + String l3Uuid = token.get(VmSystemTags.IPV6_GATEWAY_L3_UUID_TOKEN); + if (ret.get(l3Uuid) == null) { + continue; + } + ret.get(l3Uuid).ipv6Gateway = IPv6NetworkUtils.ipv6TagValueToAddress(token.get(VmSystemTags.IPV6_GATEWAY_TOKEN)); + } + if(VmSystemTags.IPV6_PREFIX.isMatch(sysTag)) { + Map token = TagUtils.parse(VmSystemTags.IPV6_PREFIX.getTagFormat(), sysTag); + String l3Uuid = token.get(VmSystemTags.IPV6_PREFIX_L3_UUID_TOKEN); + if (ret.get(l3Uuid) == null) { + continue; + } + ret.get(l3Uuid).ipv6Prefix = token.get(VmSystemTags.IPV6_PREFIX_TOKEN); + } + } + + return ret; + } + public Map> getStaticIpbySystemTag(List systemTags) { Map> ret = new HashMap<>(); @@ -169,4 +261,167 @@ public boolean isIpChange(String vmUuid, String l3Uuid) { return false; } + + public Boolean checkIpRangeConflict(VmNicVO nicVO){ + if (Q.New(IpRangeVO.class).eq(IpRangeVO_.l3NetworkUuid, nicVO.getL3NetworkUuid()).list().isEmpty()) { + return Boolean.FALSE; + } + if (getIpRangeUuid(nicVO.getL3NetworkUuid(), nicVO.getIp()) == null) { + return Boolean.TRUE; + } + return Boolean.FALSE; + } + + public String getIpRangeUuid(String l3Uuid, String ip) { + if (IPv6NetworkUtils.isIpv6Address(ip)) { + List ipRangeVOS = Q.New(IpRangeVO.class) + .eq(IpRangeVO_.l3NetworkUuid, l3Uuid) + .eq(IpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); + for (IpRangeVO ipr : ipRangeVOS) { + if (IPv6NetworkUtils.isIpv6InRange(ip, ipr.getStartIp(), ipr.getEndIp())) { + return ipr.getUuid(); + } + } + } else if (NetworkUtils.isIpv4Address(ip)) { + List ipRangeVOS = Q.New(IpRangeVO.class) + .eq(IpRangeVO_.l3NetworkUuid, l3Uuid) + .eq(IpRangeVO_.ipVersion, IPv6Constants.IPv4).list(); + for (IpRangeVO ipr : ipRangeVOS) { + if (NetworkUtils.isInRange(ip, ipr.getStartIp(), ipr.getEndIp())) { + return ipr.getUuid(); + } + } + } + + return null; + } + + public void checkIpAvailability(String l3Uuid, String ip) { + CheckIpAvailabilityMsg cmsg = new CheckIpAvailabilityMsg(); + cmsg.setIp(ip); + cmsg.setL3NetworkUuid(l3Uuid); + bus.makeLocalServiceId(cmsg, L3NetworkConstant.SERVICE_ID); + MessageReply r = bus.call(cmsg); + if (!r.isSuccess()) { + throw new ApiMessageInterceptionException(argerr(r.getError().getDetails())); + } + + CheckIpAvailabilityReply cr = r.castReply(); + if (!cr.isAvailable()) { + throw new ApiMessageInterceptionException(argerr("IP[%s] is not available on the L3 network[uuid:%s] because: %s", ip, l3Uuid, cr.getReason())); + } + } + + + @Override + public void validateSystemTagInCreateMessage(APICreateMessage msg) { + validateSystemTagInApiMessage(msg); + } + + public List fillUpStaticIpInfoToVmNics(Map staticIps) { + List newSystags = new ArrayList<>(); + for (Map.Entry e : staticIps.entrySet()) { + String l3Uuid = e.getKey(); + NicIpAddressInfo nicIp = e.getValue(); + + if (!StringUtils.isEmpty(nicIp.ipv4Address)) { + checkIpAvailability(l3Uuid, nicIp.ipv4Address); + } + + if (!StringUtils.isEmpty(nicIp.ipv6Address)) { + checkIpAvailability(l3Uuid, nicIp.ipv6Address); + } + + if (!StringUtils.isEmpty(nicIp.ipv4Address)) { + NormalIpRangeVO ipRangeVO = Q.New(NormalIpRangeVO.class) + .eq(NormalIpRangeVO_.l3NetworkUuid, l3Uuid) + .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv4) + .limit(1).find(); + if (ipRangeVO == null) { + if (StringUtils.isEmpty(nicIp.ipv4Netmask)) { + throw new ApiMessageInterceptionException(operr("netmask must be set")); + } + } else { + if (StringUtils.isEmpty(nicIp.ipv4Netmask)) { + newSystags.add(VmSystemTags.IPV4_NETMASK.instantiateTag( + map(e(VmSystemTags.IPV4_NETMASK_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.IPV4_NETMASK_TOKEN, ipRangeVO.getNetmask())) + )); + } else if (!nicIp.ipv4Netmask.equals(ipRangeVO.getNetmask())) { + throw new ApiMessageInterceptionException(operr("netmask error, expect: %s, got: %s", + ipRangeVO.getNetmask(), nicIp.ipv4Netmask)); + } + + if (StringUtils.isEmpty(nicIp.ipv4Gateway)) { + newSystags.add(VmSystemTags.IPV4_GATEWAY.instantiateTag( + map(e(VmSystemTags.IPV4_GATEWAY_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.IPV4_GATEWAY_TOKEN, ipRangeVO.getGateway())) + )); + } else if (!nicIp.ipv4Gateway.equals(ipRangeVO.getGateway())) { + throw new ApiMessageInterceptionException(operr("gateway error, expect: %s, got: %s", + ipRangeVO.getGateway(), nicIp.ipv4Gateway)); + } + } + } + + if (!StringUtils.isEmpty(nicIp.ipv6Address)) { + NormalIpRangeVO ipRangeVO = Q.New(NormalIpRangeVO.class) + .eq(NormalIpRangeVO_.l3NetworkUuid, l3Uuid) + .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6) + .limit(1).find(); + if (ipRangeVO == null) { + if (StringUtils.isEmpty(nicIp.ipv6Prefix)) { + throw new ApiMessageInterceptionException(operr("ipv6 prefix length must be set")); + } + } else { + if (StringUtils.isEmpty(nicIp.ipv6Prefix)) { + newSystags.add(VmSystemTags.IPV6_PREFIX.instantiateTag( + map(e(VmSystemTags.IPV6_PREFIX_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.IPV6_PREFIX_TOKEN, ipRangeVO.getPrefixLen())) + )); + } else if (!nicIp.ipv6Prefix.equals(ipRangeVO.getPrefixLen().toString())) { + throw new ApiMessageInterceptionException(operr("ipv6 prefix length error, expect: %s, got: %s", + ipRangeVO.getPrefixLen(), nicIp.ipv6Prefix)); + } + + if (StringUtils.isEmpty(nicIp.ipv6Gateway)) { + newSystags.add(VmSystemTags.IPV6_GATEWAY.instantiateTag( + map(e(VmSystemTags.IPV6_GATEWAY_L3_UUID_TOKEN, l3Uuid), + e(VmSystemTags.IPV6_GATEWAY_TOKEN, + IPv6NetworkUtils.ipv6AddressToTagValue(ipRangeVO.getGateway()))) + )); + } else if (!nicIp.ipv6Gateway.equals(ipRangeVO.getGateway())) { + throw new ApiMessageInterceptionException(operr("gateway error, expect: %s, got: %s", + ipRangeVO.getGateway(), nicIp.ipv6Gateway)); + } + } + } + } + + return newSystags; + } + + public void validateSystemTagInApiMessage(APIMessage msg) { + Map staticIps = getNicNetworkInfoBySystemTag(msg.getSystemTags()); + List newSystags = fillUpStaticIpInfoToVmNics(staticIps); + if (!newSystags.isEmpty()) { + msg.getSystemTags().addAll(newSystags); + } + } + + @Override + public void validateSystemTag(String resourceUuid, Class resourceType, String systemTag) { + if (VmSystemTags.STATIC_IP.isMatch(systemTag)) { + Map token = TagUtils.parse(VmSystemTags.STATIC_IP.getTagFormat(), systemTag); + String l3Uuid = token.get(VmSystemTags.STATIC_IP_L3_UUID_TOKEN); + String ip = token.get(VmSystemTags.STATIC_IP_TOKEN); + checkIpAvailability(l3Uuid, IPv6NetworkUtils.ipv6TagValueToAddress(ip)); + } + } + + public void installStaticIpValidator() { + StaticIpOperator staticIpValidator = new StaticIpOperator(); + tagMgr.installCreateMessageValidator(VmInstanceVO.class.getSimpleName(), staticIpValidator); + //VmSystemTags.STATIC_IP.installValidator(staticIpValidator); + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/TfVmNicFactory.java b/compute/src/main/java/org/zstack/compute/vm/TfVmNicFactory.java new file mode 100644 index 00000000000..89631335ea4 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/TfVmNicFactory.java @@ -0,0 +1,52 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.workflow.FlowException; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.VSwitchType; +import org.zstack.header.vm.*; +import org.zstack.identity.Account; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + + +import static org.zstack.core.Platform.err; + + +public class TfVmNicFactory extends VmNicFactory { + private static final CLogger logger = Utils.getLogger(TfVmNicFactory.class); + private static final VSwitchType vSwitchType = new VSwitchType(VmInstanceConstant.L2_TF_VSWITCH_TYPE); + private static final VmNicType type = new VmNicType(VmInstanceConstant.TF_VIRTUAL_NIC_TYPE); + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + + @Override + public VmNicType getType() { + type.setHasAddon(true); + vSwitchType.addVmNicType(VmNicType.VmNicSubType.NONE, type); + + return type; + } + + public VmNicVO createVmNic(VmNicInventory nic, VmInstanceSpec spec) { + String acntUuid = Account.getAccountUuidOfResource(spec.getVmInventory().getUuid()); + + VmNicVO vnic = VmInstanceNicFactory.createVmNic(nic); + vnic.setType(type.toString()); + vnic.setAccountUuid(acntUuid); + vnic = persistAndRetryIfMacCollision(vnic); + if (vnic == null) { + throw new FlowException(err(VmErrors.ALLOCATE_MAC_ERROR, "unable to find an available mac address after re-try 5 times, too many collisions")); + } + + vnic = dbf.reload(vnic); + spec.getDestNics().add(VmNicInventory.valueOf(vnic)); + logger.debug(String.format("Create TFVNIC [%s] success.", vnic.getUuid())); + return vnic; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/UnknownVmGC.java b/compute/src/main/java/org/zstack/compute/vm/UnknownVmGC.java index 61598e01fbe..3a64dfb5e73 100644 --- a/compute/src/main/java/org/zstack/compute/vm/UnknownVmGC.java +++ b/compute/src/main/java/org/zstack/compute/vm/UnknownVmGC.java @@ -36,7 +36,7 @@ protected void triggerNow(GCCompletion completion) { } if (vo.getState() == VmInstanceState.Unknown) { - logger.debug(String.format("vm is already been set to Unknow, cancel job %s", NAME)); + logger.debug(String.format("vm is already been set to Unknown, cancel job %s", NAME)); completion.cancel(); return; } diff --git a/compute/src/main/java/org/zstack/compute/vm/UserdataBuilder.java b/compute/src/main/java/org/zstack/compute/vm/UserdataBuilder.java index 802d21661ba..d673d5be3ef 100755 --- a/compute/src/main/java/org/zstack/compute/vm/UserdataBuilder.java +++ b/compute/src/main/java/org/zstack/compute/vm/UserdataBuilder.java @@ -15,13 +15,21 @@ public class UserdataBuilder { @Autowired private DatabaseFacade dbf; - private String sshkeyRootPassword(String sshKey, String rootPassword) { + @Autowired + protected VmInstanceExtensionPointEmitter extEmitter; + + private String sshkeyRootPassword(List sshKeys, String rootPassword) { StringBuilder sb = new StringBuilder(); - if (sshKey != null) { + if (!sshKeys.isEmpty()) { sb.append("\nssh_authorized_keys:"); - sb.append(String.format("\n - %s", sshKey)); + sshKeys.forEach(sshKey -> { + if (sshKey != null) { + sb.append(String.format("\n - %s", sshKey)); + } + }); sb.append("\ndisable_root: false"); } + if (rootPassword != null) { sb.append("\nchpasswd:"); sb.append("\n list: |"); @@ -41,10 +49,15 @@ public List buildByVmUuid(String vmUuid) { userdataList.add(userdata); } + List sshKeys = extEmitter.fetchAssociatedSshKeyPairs(vmUuid); + String sshKey = VmSystemTags.SSHKEY.getTokenByResourceUuid(vmUuid, VmSystemTags.SSHKEY_TOKEN); + if (sshKey != null) { + sshKeys.add(sshKey); + } String rootPassword = VmSystemTags.ROOT_PASSWORD.getTokenByResourceUuid(vmUuid, VmSystemTags.ROOT_PASSWORD_TOKEN); - if (sshKey != null || rootPassword != null) { - userdataList.add(String.format("#cloud-config%s", sshkeyRootPassword(sshKey, rootPassword))); + if (!sshKeys.isEmpty() || rootPassword != null) { + userdataList.add(String.format("#cloud-config%s", sshkeyRootPassword(sshKeys, rootPassword))); } return userdataList; @@ -55,7 +68,6 @@ public Map> buildByVmUuids(List vmUuids) { for (String vmUuid : vmUuids) { ret.put(vmUuid, buildByVmUuid(vmUuid)); } - return ret; } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAfterInstantiateVolumeInAttachingVolumeFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAfterInstantiateVolumeInAttachingVolumeFlow.java index ad443b78960..b463cca81b0 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAfterInstantiateVolumeInAttachingVolumeFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAfterInstantiateVolumeInAttachingVolumeFlow.java @@ -6,60 +6,40 @@ import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.SimpleQuery; -import org.zstack.core.db.SimpleQuery.Od; -import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.header.core.workflow.Flow; -import org.zstack.header.core.workflow.FlowRollback; +import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.workflow.FlowTrigger; -import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.errorcode.SysErrors; -import org.zstack.header.vm.VmAttachVolumeExtensionPoint; +import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.volume.VolumeInventory; -import org.zstack.header.volume.VolumeVO; -import org.zstack.header.volume.VolumeVO_; -import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; -import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.logging.CLogger; -import java.util.BitSet; -import java.util.List; import java.util.Map; -import static org.zstack.core.Platform.err; - @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class VmAfterInstantiateVolumeInAttachingVolumeFlow implements Flow { - CLogger logger = Utils.getLogger(VmAfterInstantiateVolumeInAttachingVolumeFlow.class); +public class VmAfterInstantiateVolumeInAttachingVolumeFlow extends NoRollbackFlow { + private static final CLogger logger = Utils.getLogger(VmAfterInstantiateVolumeInAttachingVolumeFlow.class); @Autowired private DatabaseFacade dbf; @Autowired private PluginRegistry pluginRegistry; @Autowired ErrorFacade errf; + @Autowired + protected VmInstanceExtensionPointEmitter extEmitter; @Override public void run(FlowTrigger chain, Map ctx) { - List exts = pluginRegistry.getExtensionList( - VmAttachVolumeExtensionPoint.class); final VolumeInventory volume = (VolumeInventory) ctx.get(VmInstanceConstant.Params.AttachingVolumeInventory.toString()); final VmInstanceSpec spec = (VmInstanceSpec) ctx.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - CollectionUtils.safeForEach(exts, new ForEachFunction() { + extEmitter.afterInstantiateVolume(spec.getVmInventory(), volume, new NoErrorCompletion() { @Override - public void run(VmAttachVolumeExtensionPoint arg) { - arg.afterInstantiateVolume(spec.getVmInventory(), volume); + public void done() { + chain.next(); } }); - chain.next(); - } - - @Override - public void rollback(FlowRollback chain, Map data) { - chain.rollback(); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java index 6dffeada5b3..6aeaaac09aa 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java @@ -1,8 +1,10 @@ package org.zstack.compute.vm; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.componentloader.PluginRegistry; @@ -29,11 +31,15 @@ import org.zstack.header.network.l3.L3NetworkVO_; import org.zstack.header.storage.primary.*; import org.zstack.header.vm.*; +import org.zstack.header.vo.ResourceVO; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import javax.persistence.Tuple; import java.util.*; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; /** * Create by lining at 2020/08/17 @@ -56,8 +62,22 @@ public class VmAllocateHostAndPrimaryStorageFlow implements Flow { public void run(final FlowTrigger trigger, final Map data) { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + if (spec.getImageSpec().relyOnImageCache()) { + String imageUuid = spec.getImageSpec().getInventory().getUuid(); + List requirdPsUuids = spec.getCandidatePrimaryStorageUuidsForRootVolume(); + List cachedPsUuids = Q.New(ImageCacheVO.class).select(ImageCacheVO_.primaryStorageUuid) + .eq(ImageCacheVO_.imageUuid, imageUuid) + .listValues(); + if (!CollectionUtils.isEmpty(requirdPsUuids) && Collections.disjoint(requirdPsUuids, cachedPsUuids)) { + trigger.fail(operr("creation rely on image cache[uuid:%s, locate ps uuids: [%s]], cannot create other places.", imageUuid, cachedPsUuids)); + return; + } else if (!CollectionUtils.isEmpty(requirdPsUuids)) { + requirdPsUuids.retainAll(cachedPsUuids); + } + } + // The creation parameter specifies the primary storage, no need to automatically allocate the primary storage - if (!needAutoAllocatePS(spec)) { + if (rootVolumePsUnique(spec) && (!needCreateDataVolume(spec) || dataVolumePsUnique(spec))) { allocate(trigger, spec); return; } @@ -65,6 +85,7 @@ public void run(final FlowTrigger trigger, final Map data) { List possibleClusterUuids = getPossibleClusterUuids(spec); List possiblePsUuids = getPossiblePrimaryStorageUuids(spec); + spec.setRequiredClusterUuids(possibleClusterUuids); // Multiple clusters, and each cluster has a different primary storage // Do not automatically allocate the primary storage, specifying primary storage impacts cluster selection if (possibleClusterUuids.size() > 1) { @@ -119,83 +140,28 @@ public void run(final FlowTrigger trigger, final Map data) { return; } - boolean autoAllocateRootVolumePs = needAutoAllocateRootVolumePS(spec); - boolean autoAllocateDataVolumePs = needAutoAllocateDataVolumePS(spec); - List errorCodes = new ArrayList<>(); - - if (autoAllocateRootVolumePs && autoAllocateDataVolumePs) { - // First priority:root local, data non-local - // Second priority:root local, data local / root non-local, data non-local - // Third priority:root non-local, data local - List psCombos1 = new ArrayList<>(); - List psCombos2 = new ArrayList<>(); - List psCombos3 = new ArrayList<>(); - - for (String rootVolumePsUuid : availablePsUuids) { - for (String dataVolumePsUuid : availablePsUuids) { - String[] combo = {rootVolumePsUuid, dataVolumePsUuid}; - - if (localPsUuids.contains(rootVolumePsUuid) && nonLocalPsUuids.contains(dataVolumePsUuid)) { - psCombos1.add(combo); - } else if (nonLocalPsUuids.contains(rootVolumePsUuid) && localPsUuids.contains(dataVolumePsUuid)) { - psCombos3.add(combo); - } else { - psCombos2.add(combo); - } - } + if (!CollectionUtils.isEmpty(spec.getCandidatePrimaryStorageUuidsForRootVolume())) { + List filterPsUuids = spec.getCandidatePrimaryStorageUuidsForRootVolume().stream().filter(availablePsUuids::contains).collect(Collectors.toList()); + if (filterPsUuids.isEmpty()) { + trigger.fail(Platform.operr(String.format("none of the specified primary storages%s are available", spec.getCandidatePrimaryStorageUuidsForRootVolume()))); + return; } - - List psCombos = new ArrayList<>(); - psCombos.addAll(psCombos1); - psCombos.addAll(psCombos2); - psCombos.addAll(psCombos3); - - new While<>(psCombos).each((psCombo, whileCompletion) -> { - spec.setRequiredPrimaryStorageUuidForRootVolume(psCombo[0]); - spec.setRequiredPrimaryStorageUuidForDataVolume(psCombo[1]); - - FlowChain chain = buildAllocateHostAndPrimaryStorageFlowChain(trigger, spec); - chain.done(new FlowDoneHandler(whileCompletion) { - @Override - public void handle(Map data) { - whileCompletion.allDone(); - } - }).error(new FlowErrorHandler(whileCompletion) { - @Override - public void handle(ErrorCode errCode, Map data) { - errorCodes.add(errCode); - whileCompletion.done(); - } - }).start(); - }).run(new WhileDoneCompletion(trigger) { - @Override - public void done(ErrorCodeList errorCodeList) { - if (errorCodes.size() == availablePsUuids.size()) { - trigger.fail(errorCodes.get(0)); - return; - } - - trigger.next(); - } - }); - return; + spec.setCandidatePrimaryStorageUuidsForRootVolume(filterPsUuids); } - - availablePsUuids.clear(); - if (autoAllocateRootVolumePs) { - availablePsUuids.addAll(localPsUuids); - availablePsUuids.addAll(nonLocalPsUuids); - } else { - availablePsUuids.addAll(nonLocalPsUuids); - availablePsUuids.addAll(localPsUuids); + if (needCreateDataVolume(spec) && !CollectionUtils.isEmpty(spec.getCandidatePrimaryStorageUuidsForDataVolume())) { + List filterPsUuids = spec.getCandidatePrimaryStorageUuidsForDataVolume().stream().filter(availablePsUuids::contains).collect(Collectors.toList()); + if (filterPsUuids.isEmpty()) { + trigger.fail(Platform.operr(String.format("none of the specified primary storages%s are available", spec.getCandidatePrimaryStorageUuidsForDataVolume()))); + return; + } + spec.setCandidatePrimaryStorageUuidsForDataVolume(filterPsUuids); } - new While<>(availablePsUuids).each((psUuid, whileCompletion) -> { - if (autoAllocateRootVolumePs) { - spec.setRequiredPrimaryStorageUuidForRootVolume(psUuid); - } else { - spec.setRequiredPrimaryStorageUuidForDataVolume(psUuid); - } + // local + non-local, need to automatically allocate the primary storage + List> psCombos = getPrimaryStorageCombinationFromSpec(spec, localPsUuids, nonLocalPsUuids); + new While<>(psCombos).each((combo, whileCompletion) -> { + spec.setRequiredPrimaryStorageUuidForRootVolume(combo.get(0)); + spec.setRequiredPrimaryStorageUuidForDataVolume(combo.get(1)); FlowChain chain = buildAllocateHostAndPrimaryStorageFlowChain(trigger, spec); chain.done(new FlowDoneHandler(whileCompletion) { @@ -206,15 +172,15 @@ public void handle(Map data) { }).error(new FlowErrorHandler(whileCompletion) { @Override public void handle(ErrorCode errCode, Map data) { - errorCodes.add(errCode); + whileCompletion.addError(errCode); whileCompletion.done(); } }).start(); }).run(new WhileDoneCompletion(trigger) { @Override public void done(ErrorCodeList errorCodeList) { - if (errorCodes.size() == availablePsUuids.size()) { - trigger.fail(errorCodes.get(0)); + if (errorCodeList.getCauses().size() == psCombos.size()) { + trigger.fail(errorCodeList.getCauses().get(0)); return; } @@ -332,99 +298,49 @@ private boolean isMixPrimaryStorage(VmInstanceSpec spec) { return !(!psTypes.contains(PrimaryStorageConstants.LOCAL_STORAGE_TYPE) || psTypes.size() <= 1); } - private String getTargetCluster(VmInstanceSpec spec) { + private List getPossibleClusterUuids(VmInstanceSpec spec) { VmInstanceInventory vm = spec.getVmInventory(); + String hostUuid = spec.getRequiredHostUuid(); String clusterUuid = vm.getClusterUuid() != null ? vm.getClusterUuid() : spec.getRequiredClusterUuid(); if (clusterUuid != null) { - return clusterUuid; + return Collections.singletonList(clusterUuid); } - String hostUuid = spec.getRequiredHostUuid(); - String l3Uuid = vm.getDefaultL3NetworkUuid(); - String zoneUuid = vm.getZoneUuid(); - String rootVolumePsUuid = spec.getRequiredPrimaryStorageUuidForRootVolume(); - String dataVolumePsUuid = spec.getRequiredPrimaryStorageUuidForDataVolume(); - if (hostUuid != null) { clusterUuid = Q.New(HostVO.class) .select(HostVO_.clusterUuid) .eq(HostVO_.uuid, hostUuid) .findValue(); - return clusterUuid; - } - - if (rootVolumePsUuid != null) { - List clusters = Q.New(PrimaryStorageClusterRefVO.class) - .select(PrimaryStorageClusterRefVO_.clusterUuid) - .eq(PrimaryStorageClusterRefVO_.primaryStorageUuid, rootVolumePsUuid) - .listValues(); - if (clusters.size() == 1) { - return clusters.get(0); - } - } - - if (dataVolumePsUuid != null) { - List clusters = Q.New(PrimaryStorageClusterRefVO.class) - .select(PrimaryStorageClusterRefVO_.clusterUuid) - .eq(PrimaryStorageClusterRefVO_.primaryStorageUuid, dataVolumePsUuid) - .listValues(); - if (clusters.size() == 1) { - return clusters.get(0); - } - } - - if (l3Uuid != null) { - String l2Uuid = Q.New(L3NetworkVO.class) - .select(L3NetworkVO_.l2NetworkUuid) - .eq(L3NetworkVO_.uuid, l3Uuid) - .findValue(); - List clusters = Q.New(L2NetworkClusterRefVO.class) - .select(L2NetworkClusterRefVO_.clusterUuid) - .eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2Uuid) - .listValues(); - if (clusters.size() == 1) { - return clusters.get(0); - } - } - - if (zoneUuid != null) { - List clusters = Q.New(ClusterVO.class) - .select(ClusterVO_.uuid) - .eq(ClusterVO_.zoneUuid, zoneUuid) - .listValues(); - if (clusters.size() == 1) { - return clusters.get(0); - } - } - - return null; - } - - private List getPossibleClusterUuids(VmInstanceSpec spec) { - String clusterUuid = getTargetCluster(spec); - if (clusterUuid != null) { return Collections.singletonList(clusterUuid); } - VmInstanceInventory vm = spec.getVmInventory(); String l3Uuid = vm.getDefaultL3NetworkUuid(); String zoneUuid = vm.getZoneUuid(); - String rootVolumePsUuid = spec.getRequiredPrimaryStorageUuidForRootVolume(); - String dataVolumePsUuid = spec.getRequiredPrimaryStorageUuidForDataVolume(); - if (rootVolumePsUuid != null) { - return Q.New(PrimaryStorageClusterRefVO.class) + Q q = Q.New(ClusterVO.class).select(ClusterVO_.uuid); + if (zoneUuid != null) { + q.eq(ClusterVO_.zoneUuid, zoneUuid); + } + List possibleClusterUuids = q.listValues(); + List needClusterUuids; + if (!CollectionUtils.isEmpty(spec.getCandidatePrimaryStorageUuidsForRootVolume())) { + needClusterUuids = Q.New(PrimaryStorageClusterRefVO.class) .select(PrimaryStorageClusterRefVO_.clusterUuid) - .eq(PrimaryStorageClusterRefVO_.primaryStorageUuid, rootVolumePsUuid) + .in(PrimaryStorageClusterRefVO_.primaryStorageUuid, spec.getCandidatePrimaryStorageUuidsForRootVolume()) .listValues(); + possibleClusterUuids.retainAll(needClusterUuids); } - - if (dataVolumePsUuid != null) { - return Q.New(PrimaryStorageClusterRefVO.class) + if (!CollectionUtils.isEmpty(spec.getCandidatePrimaryStorageUuidsForDataVolume())) { + needClusterUuids = Q.New(PrimaryStorageClusterRefVO.class) .select(PrimaryStorageClusterRefVO_.clusterUuid) - .eq(PrimaryStorageClusterRefVO_.primaryStorageUuid, dataVolumePsUuid) + .in(PrimaryStorageClusterRefVO_.primaryStorageUuid, spec.getCandidatePrimaryStorageUuidsForDataVolume()) .listValues(); + possibleClusterUuids.retainAll(needClusterUuids); + } + + if (possibleClusterUuids.size() < 2) { + return possibleClusterUuids; } if (l3Uuid != null) { @@ -432,20 +348,14 @@ private List getPossibleClusterUuids(VmInstanceSpec spec) { .select(L3NetworkVO_.l2NetworkUuid) .eq(L3NetworkVO_.uuid, l3Uuid) .findValue(); - return Q.New(L2NetworkClusterRefVO.class) + needClusterUuids = Q.New(L2NetworkClusterRefVO.class) .select(L2NetworkClusterRefVO_.clusterUuid) .eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2Uuid) .listValues(); + possibleClusterUuids.retainAll(needClusterUuids); } - if (zoneUuid != null) { - return Q.New(ClusterVO.class) - .select(ClusterVO_.uuid) - .eq(ClusterVO_.zoneUuid, zoneUuid) - .listValues(); - } - - return Collections.emptyList(); + return possibleClusterUuids; } private List getPossiblePrimaryStorageUuids(VmInstanceSpec spec) { @@ -461,25 +371,17 @@ private List getPossiblePrimaryStorageUuids(VmInstanceSpec spec) { .list(); } - private boolean needAutoAllocatePS(VmInstanceSpec spec) { - boolean autoAllocateRootVolumePs = needAutoAllocateRootVolumePS(spec); - boolean autoAllocateDataVolumePs = needAutoAllocateDataVolumePS(spec); - return autoAllocateRootVolumePs || autoAllocateDataVolumePs; - } - private boolean needAutoAllocateRootVolumePS(VmInstanceSpec spec) { - return spec.getRequiredPrimaryStorageUuidForRootVolume() == null; + private boolean rootVolumePsUnique(VmInstanceSpec spec) { + return spec.getCandidatePrimaryStorageUuidsForRootVolume().size() == 1; } - private boolean needAutoAllocateDataVolumePS(VmInstanceSpec spec) { - if (spec.getRequiredPrimaryStorageUuidForDataVolume() == null) { - if (spec.getDataDiskOfferings() != null && - spec.getDataDiskOfferings().size() > 0) { - return true; - } - } + private boolean dataVolumePsUnique(VmInstanceSpec spec) { + return spec.getCandidatePrimaryStorageUuidsForDataVolume().size() == 1; + } - return false; + private boolean needCreateDataVolume(VmInstanceSpec spec) { + return !CollectionUtils.isEmpty(spec.getDataDiskOfferings()); } private FlowChain buildAllocateHostAndPrimaryStorageFlowChain(final FlowTrigger trigger, VmInstanceSpec spec) { @@ -514,4 +416,66 @@ public void handle(ErrorCode errCode, Map data) { }); chain.start(); } + + private List> getPrimaryStorageCombinationFromSpec(VmInstanceSpec spec, List localPsUuids, List nonLocalPsUuids) { + List availPsForRootVolume = new ArrayList() {{addAll(localPsUuids); addAll(nonLocalPsUuids);}}; + List availPsForDataVolume = new ArrayList() {{addAll(nonLocalPsUuids); addAll(localPsUuids);}}; + + boolean autoAllocateRootVolumePs = false; + boolean autoAllocateDataVolumePs = false; + List rootPs = new ArrayList<>(); + List dataPs = new ArrayList<>(); + if (!CollectionUtils.isEmpty(spec.getCandidatePrimaryStorageUuidsForRootVolume())) { + rootPs.addAll(spec.getCandidatePrimaryStorageUuidsForRootVolume()); + } else { + autoAllocateRootVolumePs = true; + rootPs.addAll(availPsForRootVolume); + } + + String rootVolumeStrategy = spec.getRootDiskOffering() == null ? null : spec.getRootDiskOffering().getAllocatorStrategy(); + sortPrimaryStorages(rootPs, rootVolumeStrategy, spec.getImageSpec()); + + if (needCreateDataVolume(spec)) { + if (!CollectionUtils.isEmpty(spec.getCandidatePrimaryStorageUuidsForDataVolume())) { + dataPs.addAll(spec.getCandidatePrimaryStorageUuidsForDataVolume()); + } else { + autoAllocateDataVolumePs = true; + dataPs.addAll(availPsForDataVolume); + } + String dataVolumeStrategy = spec.getDataDiskOfferings().get(0).getAllocatorStrategy(); + sortPrimaryStorages(dataPs, dataVolumeStrategy, null); + } else { + dataPs.add(null); + } + + List> finalPsCombos = new ArrayList<>(); + if (autoAllocateRootVolumePs && autoAllocateDataVolumePs) { + // First priority:root local, data non-local + // Second priority:root local, data local / root non-local, data non-local + // Third priority:root non-local, data local + List tmpLocalPsUuids = rootPs.stream().filter(localPsUuids::contains).collect(Collectors.toList()); + List tmpNonLocalPsUuids = rootPs.stream().filter(nonLocalPsUuids::contains).collect(Collectors.toList()); + rootPs.clear(); + rootPs.addAll(tmpLocalPsUuids); + rootPs.addAll(tmpNonLocalPsUuids); + + tmpLocalPsUuids = dataPs.stream().filter(localPsUuids::contains).collect(Collectors.toList()); + tmpNonLocalPsUuids = dataPs.stream().filter(nonLocalPsUuids::contains).collect(Collectors.toList()); + dataPs.clear(); + dataPs.addAll(tmpNonLocalPsUuids); + dataPs.addAll(tmpLocalPsUuids); + } + + rootPs.forEach(r -> dataPs.forEach(d -> finalPsCombos.add(Arrays.asList(r, d)))); + return finalPsCombos; + } + + private void sortPrimaryStorages(final List psUuids, String strategy, VmInstanceSpec.ImageSpec imageSpec) { + List primaryStorageVOS = psUuids.stream().map(uuid -> dbf.findByUuid(uuid, PrimaryStorageVO.class)).collect(Collectors.toList()); + for (PrimaryStorageSortExtensionPoint ext : pluginRgty.getExtensionList(PrimaryStorageSortExtensionPoint.class)) { + ext.sort(primaryStorageVOS, imageSpec, strategy); + } + psUuids.clear(); + psUuids.addAll(primaryStorageVOS.stream().map(ResourceVO::getUuid).collect(Collectors.toList())); + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java index 8423aff570c..ee542fe36ee 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostFlow.java @@ -6,6 +6,7 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.allocator.*; @@ -14,6 +15,7 @@ import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostInventory; import org.zstack.header.host.HostVO; @@ -21,6 +23,8 @@ import org.zstack.header.image.ImageInventory; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO; +import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO_; import org.zstack.header.vm.*; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.utils.CollectionUtils; @@ -29,9 +33,13 @@ import org.zstack.utils.logging.CLogger; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; +import static org.zstack.core.Platform.operr; import static org.zstack.core.progress.ProgressReportService.taskProgress; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) @@ -61,7 +69,7 @@ protected AllocateHostMsg prepareMsg(VmInstanceSpec spec) { List diskOfferings = new ArrayList<>(); ImageInventory image = spec.getImageSpec().getInventory(); long diskSize; - if (image.getMediaType() != null && image.getMediaType().equals(ImageMediaType.ISO.toString())) { + if (image == null || (image.getMediaType() != null && image.getMediaType().equals(ImageMediaType.ISO.toString()))) { DiskOfferingVO dvo = dbf.findByUuid(spec.getRootDiskOffering().getUuid(), DiskOfferingVO.class); diskSize = dvo.getDiskSize(); diskOfferings.add(DiskOfferingInventory.valueOf(dvo)); @@ -76,6 +84,7 @@ protected AllocateHostMsg prepareMsg(VmInstanceSpec spec) { msg.setDiskSize(diskSize); msg.setCpuCapacity(spec.getVmInventory().getCpuNum()); msg.setMemoryCapacity(spec.getVmInventory().getMemorySize()); + msg.setClusterUuids(spec.getRequiredClusterUuids()); List l3Invs = VmNicSpec.getL3NetworkInventoryOfSpec(spec.getL3Networks()); msg.setL3NetworkUuids(CollectionUtils.transformToList(l3Invs, new Function() { @@ -99,11 +108,21 @@ public String call(L3NetworkInventory arg) { } else { msg.setAllocatorStrategy(spec.getVmInventory().getAllocatorStrategy()); } - if (spec.getRequiredPrimaryStorageUuidForRootVolume() != null) { - msg.addRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForRootVolume()); + + if (msg.getAllocatorStrategy() == null && + (!CollectionUtils.isEmpty(msg.getClusterUuids()) || msg.getHostUuid() != null)) { + msg.setAllocatorStrategy(HostAllocatorConstant.DESIGNATED_HOST_ALLOCATOR_STRATEGY_TYPE); + } + + if (spec.getCandidatePrimaryStorageUuidsForRootVolume().size() == 1) { + msg.addRequiredPrimaryStorageUuid(spec.getCandidatePrimaryStorageUuidsForRootVolume().get(0)); + } else if (spec.getCandidatePrimaryStorageUuidsForRootVolume().size() > 1) { + msg.addOptionalPrimaryStorageUuids(new HashSet<>(spec.getCandidatePrimaryStorageUuidsForRootVolume())); } - if (spec.getRequiredPrimaryStorageUuidForDataVolume() != null) { - msg.addRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForDataVolume()); + if (spec.getCandidatePrimaryStorageUuidsForDataVolume().size() == 1) { + msg.addRequiredPrimaryStorageUuid(spec.getCandidatePrimaryStorageUuidsForDataVolume().get(0)); + } else if (spec.getCandidatePrimaryStorageUuidsForDataVolume().size() > 1) { + msg.addOptionalPrimaryStorageUuids(new HashSet<>(spec.getCandidatePrimaryStorageUuidsForDataVolume())); } msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); msg.setVmInstance(spec.getVmInventory()); @@ -111,6 +130,12 @@ public String call(L3NetworkInventory arg) { if (spec.getImageSpec() != null && spec.getImageSpec().getSelectedBackupStorage() != null) { msg.setRequiredBackupStorageUuid(spec.getImageSpec().getSelectedBackupStorage().getBackupStorageUuid()); } + msg.setAllowNoL3Networks(true); + + if (!CollectionUtils.isEmpty(spec.getDiskAOs())) { + msg.getRequiredPrimaryStorageUuids().addAll(spec.getDiskAOs().stream() + .map(APICreateVmInstanceMsg.DiskAO::getPrimaryStorageUuid).filter(Objects::nonNull).collect(Collectors.toList())); + } return msg; } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForMigrateVmFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForMigrateVmFlow.java index b9ed2973dc8..8984957008e 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForMigrateVmFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForMigrateVmFlow.java @@ -57,9 +57,10 @@ public void run(final FlowTrigger chain, final Map data) { msg.getAvoidHostUuids().addAll(migrateVmMsg.getAvoidHostUuids()); } } - if (spec.getImageSpec() != null) { + if (spec.getImageSpec() != null && spec.getImageSpec().getInventory() != null) { msg.setImage(spec.getImageSpec().getInventory()); } + msg.setZoneUuid(spec.getVmInventory().getZoneUuid()); msg.setVmInstance(spec.getVmInventory()); msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); msg.setAllocatorStrategy(HostAllocatorConstant.MIGRATE_VM_ALLOCATOR_TYPE); @@ -74,6 +75,7 @@ public String call(L3NetworkInventory arg) { return arg.getUuid(); } })); + msg.setAllowNoL3Networks(true); bus.send(msg, new CloudBusCallBack(chain) { @Override public void run(MessageReply reply) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java index 99d1f7d9a76..98f39b01372 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateHostForStoppedVmFlow.java @@ -49,12 +49,12 @@ public void run(final FlowTrigger chain, final Map data) { msg.setCpuCapacity(spec.getVmInventory().getCpuNum()); msg.setMemoryCapacity(spec.getVmInventory().getMemorySize()); msg.setVmOperation(spec.getCurrentVmOperation().toString()); - if (spec.getImageSpec() != null) { + if (spec.getImageSpec() != null && spec.getImageSpec().getInventory() != null) { msg.setImage(spec.getImageSpec().getInventory()); } if ((spec.getRequiredClusterUuid() != null && !spec.getRequiredClusterUuid().equals(msg.getVmInstance().getClusterUuid())) - || spec.getRequiredHostUuid() != null) { + || spec.getRequiredHostUuid() != null || CollectionUtils.isEmpty(spec.getVmInventory().getVmNics())) { msg.setAllocatorStrategy(HostAllocatorConstant.DESIGNATED_HOST_ALLOCATOR_STRATEGY_TYPE); msg.setHostUuid(spec.getRequiredHostUuid()); } else { @@ -65,6 +65,10 @@ public void run(final FlowTrigger chain, final Map data) { msg.setAllocatorStrategy(HostAllocatorConstant.LEAST_VM_PREFERRED_HOST_ALLOCATOR_STRATEGY_TYPE); } } + if (CollectionUtils.isEmpty(spec.getVmInventory().getVmNics())) { + msg.setAllowNoL3Networks(true); + } + msg.setL3NetworkUuids(CollectionUtils.transformToList(VmNicSpec.getL3NetworkInventoryOfSpec(spec.getL3Networks()), new Function() { @Override @@ -72,7 +76,13 @@ public String call(L3NetworkInventory arg) { return arg.getUuid(); } })); - msg.setClusterUuid(spec.getRequiredClusterUuid()); + if (spec.getRequiredClusterUuid() == null) { + if (CollectionUtils.isEmpty(spec.getVmInventory().getVmNics())) { + msg.setClusterUuid(spec.getVmInventory().getClusterUuid()); + } + } else { + msg.setClusterUuid(spec.getRequiredClusterUuid()); + } msg.setRequiredPrimaryStorageUuids(spec.getVmInventory().getAllVolumes().stream() .map(VolumeInventory::getPrimaryStorageUuid) .collect(Collectors.toSet())); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java index d0dead44e88..3589d8c7307 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java @@ -1,15 +1,14 @@ package org.zstack.compute.vm; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; -import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.cloudbus.CloudBusListCallBack; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.Q; import org.zstack.core.db.SQLBatch; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.WhileDoneCompletion; @@ -18,19 +17,17 @@ import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; -import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.image.ImagePlatform; -import org.zstack.header.message.MessageReply; -import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.l3.*; -import org.zstack.header.tag.SystemTagVO; -import org.zstack.header.tag.SystemTagVO_; import org.zstack.header.vm.*; import org.zstack.network.l3.L3NetworkManager; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NicIpAddressInfo; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.NetworkUtils; @@ -55,19 +52,34 @@ public class VmAllocateNicFlow implements Flow { private VmNicManager nicManager; @Autowired protected VmInstanceManager vmMgr; + @Autowired + protected PluginRegistry pluginRgty; + + @Autowired + protected ResourceConfigFacade rcf; @Override public void run(final FlowTrigger trigger, final Map data) { taskProgress("create nics"); final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - - if (spec.isSkipIpAllocation()) { - trigger.next(); - return; + List l3Networks = spec.getL3Networks(); + for (VmNicSpec l3Network : l3Networks) { + for (VmPreAttachL3NetworkExtensionPoint ext : pluginRgty.getExtensionList(VmPreAttachL3NetworkExtensionPoint.class)) { + for (L3NetworkInventory l3Inv : l3Network.getL3Invs()) { + ext.vmPreAttachL3Network(spec.getVmInventory(), l3Inv); + } + } } + final Map nicNetworkInfoMap = + Optional.ofNullable(data.get(VmInstanceConstant.Params.VmAllocateNicFlow_nicNetworkInfo.toString())) + .map(obj -> (Map) obj) + .orElse(new StaticIpOperator().getNicNetworkInfoByVmUuid(spec.getVmInventory().getUuid())); - Boolean allowDuplicatedAddress = (Boolean)data.get(VmInstanceConstant.Params.VmAllocateNicFlow_allowDuplicatedAddress.toString()); + final List disableL3Networks = new ArrayList<>(); + if (spec.getDisableL3Networks() != null && !spec.getDisableL3Networks().isEmpty()) { + disableL3Networks.addAll(spec.getDisableL3Networks()); + } // it's unlikely a vm having more than 512 nics final BitSet deviceIdBitmap = new BitSet(512); @@ -75,23 +87,11 @@ public void run(final FlowTrigger trigger, final Map data) { deviceIdBitmap.set(nic.getDeviceId()); } - List ips = new ArrayList<>(); List nics = new ArrayList<>(); - data.put(VmInstanceConstant.Params.VmAllocateNicFlow_ips.toString(), ips); data.put(VmInstanceConstant.Params.VmAllocateNicFlow_nics.toString(), nics); List errs = new ArrayList<>(); - Map> vmStaticIps = new StaticIpOperator().getStaticIpbyVmUuid(spec.getVmInventory().getUuid()); - List firstL3s = VmNicSpec.getFirstL3NetworkInventoryOfSpec(spec.getL3Networks()) - .stream() - .peek(v -> { - if (!Q.New(NormalIpRangeVO.class) - .eq(NormalIpRangeVO_.l3NetworkUuid, v.getL3Invs().get(0).getUuid()) - .isExists()) { - throw new OperationFailureException(Platform.operr("there is no available ipRange on L3 network [%s]", v.getL3Invs().get(0).getUuid())); - } - }) - .collect(Collectors.toList()); - new While<>(firstL3s).each((nicSpec, wcomp) -> { + + new While<>(VmNicSpec.getFirstL3NetworkInventoryOfSpec(spec.getL3Networks())).each((nicSpec, wcomp) -> { L3NetworkInventory nw = nicSpec.getL3Invs().get(0); int deviceId = deviceIdBitmap.nextClearBit(0); deviceIdBitmap.set(deviceId); @@ -101,119 +101,103 @@ public void run(final FlowTrigger trigger, final Map data) { mo.deleteCustomMacSystemTag(spec.getVmInventory().getUuid(), nw.getUuid(), customMac); customMac = customMac.toLowerCase(); } else { - customMac = NetworkUtils.generateMacWithDeviceId((short) deviceId); + customMac = MacOperator.generateMacWithDeviceId((short) deviceId); } final String mac = customMac; + CustomNicOperator nicOperator = new CustomNicOperator(spec.getVmInventory().getUuid(),nw.getUuid()); + final String customNicUuid = nicOperator.getCustomNicId(); - // choose vnic factory based on enableSRIOV system tag - VmInstanceNicFactory vnicFactory; - boolean enableSriov = Q.New(SystemTagVO.class) - .eq(SystemTagVO_.resourceType, VmInstanceVO.class.getSimpleName()) - .eq(SystemTagVO_.resourceUuid, spec.getVmInventory().getUuid()) - .eq(SystemTagVO_.tag, String.format("enableSRIOV::%s", nw.getUuid())) - .isExists(); - logger.debug(String.format("create %s on l3 network[uuid:%s] inside VmAllocateNicFlow", - enableSriov ? "vf nic" : "vnic", nw.getUuid())); + // choose vnic factory based on enableSRIOV system tag & enableVhostUser globalConfig + VmNicType type = nicManager.getVmNicType(spec.getVmInventory().getUuid(), nw); + if (type == null) { + errs.add(Platform.operr("there is no available nicType on L3 network [%s]", nw.getUuid())); + wcomp.allDone(); + } + VmInstanceNicFactory vnicFactory = vmMgr.getVmInstanceNicFactory(type); - L2NetworkVO l2nw = dbf.findByUuid(nw.getL2NetworkUuid(), L2NetworkVO.class); - VSwitchType vSwitchType = new VSwitchType(l2nw.getvSwitchType()); - VmNicType type = VmNicType.valueOf(vSwitchType, enableSriov); - vnicFactory = vmMgr.getVmInstanceNicFactory(type); + VmNicInventory nic = new VmNicInventory(); + if (customNicUuid != null) { + nic.setUuid(customNicUuid); + } else { + nic.setUuid(Platform.getUuid()); + } + /* the first ip is ipv4 address for dual stack nic */ + nic.setVmInstanceUuid(spec.getVmInventory().getUuid()); + nic.setL3NetworkUuid(nw.getUuid()); + nic.setMac(mac); + nic.setHypervisorType(spec.getDestHost() == null ? + spec.getVmInventory().getHypervisorType() : spec.getDestHost().getHypervisorType()); + if (mo.checkDuplicateMac(nic.getHypervisorType(), nic.getL3NetworkUuid(), nic.getMac())) { + trigger.fail(operr("Duplicate mac address [%s]", nic.getMac())); + return; + } - List ipVersions = nw.getIpVersions(); - Map nicStaticIpMap = new StaticIpOperator().getNicStaticIpMap(vmStaticIps.get(nw.getUuid())); - List msgs = new ArrayList<>(); - for (int ipversion : ipVersions) { - AllocateIpMsg msg = new AllocateIpMsg(); - msg.setL3NetworkUuid(nw.getUuid()); - msg.setAllocateStrategy(spec.getIpAllocatorStrategy()); - String staticIp = nicStaticIpMap.get(ipversion); - if (staticIp != null) { - msg.setRequiredIp(staticIp); - } else { - if (ipversion == IPv6Constants.IPv6) { - l3nm.updateIpAllocationMsg(msg, customMac); - } - } - if (allowDuplicatedAddress != null) { - msg.setDuplicatedIpAllowed(allowDuplicatedAddress); - } - msg.setIpVersion(ipversion); - bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, nw.getUuid()); - msgs.add(msg); + if (!StringUtils.isEmpty(nicSpec.getNicDriverType())) { + nic.setDriverType(nicSpec.getNicDriverType()); + } else { + boolean vmImageHasVirtio = VmSystemTags.VIRTIO.hasTag(spec.getVmInventory().getUuid()); + nicManager.setNicDriverType(nic, vmImageHasVirtio, + ImagePlatform.valueOf(spec.getVmInventory().getPlatform()).isParaVirtualization(), + spec.getVmInventory()); } - List ipErrs = new ArrayList<>(); - List nicIps = new ArrayList<>(); - new While<>(msgs).each((msg, wcompl) -> { - bus.send(msg, new CloudBusCallBack(wcompl) { - @Override - public void run(MessageReply reply) { - if (reply.isSuccess()) { - AllocateIpReply areply = reply.castReply(); - ips.add(areply.getIpInventory()); - nicIps.add(areply.getIpInventory()); - wcompl.done(); - } else { - ipErrs.add(reply.getError()); - wcompl.allDone(); - } - } - }); - }).run(new WhileDoneCompletion(wcomp) { + + nic.setDeviceId(deviceId); + nic.setInternalName(VmNicVO.generateNicInternalName(spec.getVmInventory().getInternalId(), nic.getDeviceId())); + nic.setState(disableL3Networks.contains(nic.getL3NetworkUuid()) ? VmNicState.disable.toString() : VmNicState.enable.toString()); + new SQLBatch() { @Override - public void done(ErrorCodeList errorCodeList) { - if (ipErrs.size() > 0) { - errs.add(ipErrs.get(0)); - wcomp.allDone(); - } else { - VmNicInventory nic = new VmNicInventory(); - nic.setUuid(Platform.getUuid()); - /* the first ip is ipv4 address for dual stack nic */ - UsedIpInventory ip = nicIps.get(0); - nic.setIp(ip.getIp()); - nic.setIpVersion(ip.getIpVersion()); - nic.setUsedIpUuid(ip.getUuid()); - nic.setVmInstanceUuid(spec.getVmInventory().getUuid()); - nic.setL3NetworkUuid(ip.getL3NetworkUuid()); - nic.setMac(mac); - nic.setHypervisorType(spec.getDestHost() == null ? - spec.getVmInventory().getHypervisorType() : spec.getDestHost().getHypervisorType()); - if (mo.checkDuplicateMac(nic.getHypervisorType(), nic.getMac())) { - trigger.fail(operr("Duplicate mac address [%s]", nic.getMac())); - return; + protected void scripts() { + VmNicVO nicVO = vnicFactory.createVmNic(nic, spec); + if (!nw.enableIpAddressAllocation() && nicNetworkInfoMap != null + && nicNetworkInfoMap.containsKey(nw.getUuid()) + && spec.getVmInventory().getType().equals(VmInstanceConstant.USER_VM_TYPE)) { + NicIpAddressInfo nicNicIpAddressInfo = nicNetworkInfoMap.get(nic.getL3NetworkUuid()); + if (!nicNicIpAddressInfo.ipv6Address.isEmpty()) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIp(IPv6NetworkUtils.getIpv6AddressCanonicalString(nicNicIpAddressInfo.ipv6Address)); + vo.setNetmask(IPv6NetworkUtils.getFormalNetmaskOfNetworkCidr(nicNicIpAddressInfo.ipv6Address+"/"+ nicNicIpAddressInfo.ipv6Prefix)); + vo.setGateway(nicNicIpAddressInfo.ipv6Gateway.isEmpty() ? "" : IPv6NetworkUtils.getIpv6AddressCanonicalString(nicNicIpAddressInfo.ipv6Gateway)); + vo.setIpVersion(IPv6Constants.IPv6); + vo.setVmNicUuid(nic.getUuid()); + vo.setL3NetworkUuid(nic.getL3NetworkUuid()); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setIpRangeUuid(new StaticIpOperator().getIpRangeUuid(nic.getL3NetworkUuid(), vo.getIp())); + nic.setUsedIpUuid(vo.getUuid()); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(vo.getIp()); + nicVO.setNetmask(vo.getNetmask()); + nicVO.setGateway(vo.getGateway()); + dbf.persist(vo); } - - if (nicSpec.getNicDriverType() != null) { - nic.setDriverType(nicSpec.getNicDriverType()); - } else { - boolean imageHasVirtio = false; - try { - imageHasVirtio = spec.getImageSpec().getInventory().getVirtio(); - } catch (Exception e) { - logger.debug(String.format("there is no image spec for vm %s", spec.getVmInventory().getUuid())); - } - - nicManager.setNicDriverType(nic, imageHasVirtio, - ImagePlatform.valueOf(spec.getVmInventory().getPlatform()).isParaVirtualization()); + if (!nicNicIpAddressInfo.ipv4Address.isEmpty()) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIp(nicNicIpAddressInfo.ipv4Address); + vo.setGateway(nicNicIpAddressInfo.ipv4Gateway); + vo.setNetmask(nicNicIpAddressInfo.ipv4Netmask); + vo.setIpVersion(IPv6Constants.IPv4); + vo.setVmNicUuid(nic.getUuid()); + vo.setL3NetworkUuid(nic.getL3NetworkUuid()); + vo.setIpInLong(NetworkUtils.ipv4StringToLong(vo.getIp())); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setIpRangeUuid(new StaticIpOperator().getIpRangeUuid(nic.getL3NetworkUuid(), vo.getIp())); + nic.setUsedIpUuid(vo.getUuid()); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(vo.getIp()); + nicVO.setNetmask(vo.getNetmask()); + nicVO.setGateway(vo.getGateway()); + dbf.persist(vo); } - - nic.setDeviceId(deviceId); - nic.setNetmask(ip.getNetmask()); - nic.setGateway(ip.getGateway()); - nic.setInternalName(VmNicVO.generateNicInternalName(spec.getVmInventory().getInternalId(), nic.getDeviceId())); - - new SQLBatch() { - @Override - protected void scripts() { - vnicFactory.createVmNic(nic, spec, nicIps); - nics.add(nic); - } - }.execute(); - wcomp.done(); } + nics.add(nic); + nicVO = dbf.updateAndRefresh(nicVO); + addVmNicConfig(nicVO, spec, nicSpec); } - }); + }.execute(); + wcomp.done(); + }).run(new WhileDoneCompletion(trigger) { @Override public void done(ErrorCodeList errorCodeList) { @@ -226,33 +210,52 @@ public void done(ErrorCodeList errorCodeList) { }); } - @Override - public void rollback(final FlowRollback chain, Map data) { - final List destNics = (List) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_nics.toString()); - final List nicUuids = destNics.stream().map(VmNicInventory::getUuid).collect(Collectors.toList()); + private void addVmNicConfig(VmNicVO vmNicVO, VmInstanceSpec vmSpec, VmNicSpec nicSpec) { + if (nicSpec == null) { + return; + } + + List vmNicParms = nicSpec.getVmNicParams(); + if (CollectionUtils.isEmpty(vmNicParms)) { + return; + } + + VmNicParam vmNicParm = vmNicParms.get(0); - List ips = (List) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_ips.toString()); - List msgs = new ArrayList(); - for (UsedIpInventory ip : ips) { - ReturnIpMsg msg = new ReturnIpMsg(); - msg.setL3NetworkUuid(ip.getL3NetworkUuid()); - msg.setUsedIpUuid(ip.getUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, ip.getL3NetworkUuid()); - msgs.add(msg); + // add vmnic bandwidth systemtag + if (vmNicParm.getInboundBandwidth() != null || vmNicParm.getOutboundBandwidth() != null) { + VmNicQosConfigBackend backend = vmMgr.getVmNicQosConfigBackend(vmSpec.getVmInventory().getType()); + backend.addNicQos(vmSpec.getVmInventory().getUuid(), vmNicVO.getUuid(), vmNicParm.getInboundBandwidth(), vmNicParm.getOutboundBandwidth()); } - if (msgs.isEmpty()) { - dbf.removeByPrimaryKeys(nicUuids, VmNicVO.class); + //add vmnic multiqueue config + if (vmNicParm.getMultiQueueNum() != null) { + ResourceConfig multiQueues = rcf.getResourceConfig(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM.getIdentity()); + Integer queues = vmNicParm.getMultiQueueNum(); + multiQueues.updateValue(vmNicVO.getUuid(), queues.toString()); + } + } + + @Override + public void rollback(final FlowRollback chain, Map data) { + final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + final List destNics = spec.getDestNics(); + if (destNics == null || destNics.isEmpty()) { chain.rollback(); return; } - - bus.send(msgs, 1, new CloudBusListCallBack(chain) { - @Override - public void run(List replies) { - dbf.removeByPrimaryKeys(nicUuids, VmNicVO.class); - chain.rollback(); + logger.debug(String.format("%s nic need for delete", destNics.size())); + for (VmNicInventory vmNic : destNics) { + for (VmDetachNicExtensionPoint ext : pluginRgty.getExtensionList(VmDetachNicExtensionPoint.class)) { + ext.afterDetachNic(vmNic); } - }); + + VmNicType type = VmNicType.valueOf(vmNic.getType()); + VmInstanceNicFactory vnicFactory = vmMgr.getVmInstanceNicFactory(type); + vnicFactory.releaseVmNic(vmNic); + } + dbf.removeByPrimaryKeys(destNics.stream().map(VmNicInventory::getUuid).collect(Collectors.toList()), VmNicVO.class); + chain.rollback(); + return; } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicForStartingVmFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicForStartingVmFlow.java index a2bc5ecf3ed..6af0ed00313 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicForStartingVmFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicForStartingVmFlow.java @@ -25,9 +25,7 @@ import org.zstack.utils.function.Function; import org.zstack.utils.network.IPv6Constants; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmAllocateNicForStartingVmFlow implements Flow { @@ -55,6 +53,10 @@ public void run(final FlowTrigger trigger, Map data) { final List nicsNeedNewIp = new ArrayList(vm.getVmNics().size()); final List usedIpNics = new ArrayList(); for (VmNicInventory nic : vm.getVmNics()) { + L3NetworkVO l3VO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, nic.getL3NetworkUuid()).find(); + if (!l3VO.enableIpAddressAllocation()) { + continue; + } if (nic.getUsedIpUuid() == null) { nic.getUsedIps().clear(); nicsNeedNewIp.add(nic); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicIpFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicIpFlow.java new file mode 100644 index 00000000000..bb0fdafcb01 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateNicIpFlow.java @@ -0,0 +1,216 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.CloudBusListCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.core.workflow.FlowRollback; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l3.*; +import org.zstack.header.vm.*; +import org.zstack.network.l3.L3NetworkManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; +import static org.zstack.core.progress.ProgressReportService.taskProgress; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmAllocateNicIpFlow implements Flow { + private static final CLogger logger = Utils.getLogger(VmAllocateNicIpFlow.class); + @Autowired + protected DatabaseFacade dbf; + @Autowired + protected CloudBus bus; + @Autowired + protected ErrorFacade errf; + @Autowired + protected L3NetworkManager l3nm; + @Autowired + private VmNicManager nicManager; + @Autowired + protected VmInstanceManager vmMgr; + + @Override + public void run(final FlowTrigger trigger, final Map data) { + taskProgress("allocate nics ip"); + + final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + final List nics = (List) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_nics.toString()); + Boolean allowDuplicatedAddress = (Boolean) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_allowDuplicatedAddress.toString()); + Map> vmStaticIps = new StaticIpOperator().getStaticIpbyVmUuid(spec.getVmInventory().getUuid()); + List errs = new ArrayList<>(); + Set ipVOS = new HashSet<>(); + List nicsWithIp = new ArrayList<>(); + List ips = new ArrayList<>(); + data.put(VmInstanceConstant.Params.VmAllocateNicFlow_nics.toString(), nicsWithIp); + data.put(VmInstanceConstant.Params.VmAllocateNicFlow_ips.toString(), ips); + + final Map nicsL3 = new HashMap<>(); + nics.forEach(nic -> { + nicsL3.put(nic.getL3NetworkUuid(), nic); + }); + if (spec.isSkipIpAllocation()) { + trigger.next(); + return; + } + List firstL3s = VmNicSpec.getFirstL3NetworkInventoryOfSpec(spec.getL3Networks()) + .stream() + .filter(v -> { + if (v.getL3Invs().get(0).enableIpAddressAllocation()) { + return true; + } + + /* if dhcp is disabled, will not allocate ip address for user vm + * allocated ip to appliance vm based on following conditions */ + if (spec.getVmInventory().getType().equals(VmInstanceConstant.USER_VM_TYPE)) { + return false; + } else { + L3NetworkInventory nw = v.getL3Invs().get(0); + VmNicInventory nicUuid = nicsL3.get(nw.getUuid()); + VmNicVO nic = dbf.findByUuid(nicUuid.getUuid(), VmNicVO.class); + + /* if there is no ip range, or created ip in VmAllocateNicFlow from systemTags */ + if (!nic.getUsedIps().isEmpty() || nw.getIpRanges().isEmpty()) { + return false; + } else { + return true; + } + } + }) + .peek(v -> { + if (!Q.New(NormalIpRangeVO.class) + .eq(NormalIpRangeVO_.l3NetworkUuid, v.getL3Invs().get(0).getUuid()) + .isExists()) { + throw new OperationFailureException(Platform.operr("there is no available ipRange on L3 network [%s]", v.getL3Invs().get(0).getUuid())); + } + }) + .collect(Collectors.toList()); + + new While<>(firstL3s).each((nicSpec, wcomp) -> { + L3NetworkInventory nw = nicSpec.getL3Invs().get(0); + VmNicInventory nicUuid = nicsL3.get(nw.getUuid()); + VmNicVO nic = dbf.findByUuid(nicUuid.getUuid(), VmNicVO.class); + List ipVersions = nw.getIpVersions(); + Map nicStaticIpMap = new StaticIpOperator().getNicStaticIpMap(vmStaticIps.get(nw.getUuid())); + List msgs = new ArrayList<>(); + for (int ipversion : ipVersions) { + AllocateIpMsg msg = new AllocateIpMsg(); + msg.setL3NetworkUuid(nw.getUuid()); + msg.setAllocateStrategy(spec.getIpAllocatorStrategy()); + String staticIp = nicStaticIpMap.get(ipversion); + if (staticIp != null) { + msg.setRequiredIp(staticIp); + } else { + if (ipversion == IPv6Constants.IPv6) { + l3nm.updateIpAllocationMsg(msg, nic.getMac()); + } + } + if (allowDuplicatedAddress != null) { + msg.setDuplicatedIpAllowed(allowDuplicatedAddress); + } + msg.setIpVersion(ipversion); + bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, nw.getUuid()); + msgs.add(msg); + } + List ipErrs = new ArrayList<>(); + List nicIps = new ArrayList<>(); + new While<>(msgs).each((msg, wcompl) -> { + bus.send(msg, new CloudBusCallBack(wcompl) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + AllocateIpReply areply = reply.castReply(); + ips.add(areply.getIpInventory()); + nicIps.add(areply.getIpInventory()); + wcompl.done(); + } else { + ipErrs.add(reply.getError()); + wcompl.allDone(); + } + } + }); + }).run(new WhileDoneCompletion(wcomp) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (ipErrs.size() > 0) { + errs.add(ipErrs.get(0)); + wcomp.allDone(); + } else { + List sortedNicsIps = nicIps.stream() + .sorted(Comparator.comparingInt(UsedIpInventory::getIpVersion)) + .collect(Collectors.toList()); + UsedIpInventory ip = sortedNicsIps.get(0); + nic.setIp(ip.getIp()); + nic.setIpVersion(ip.getIpVersion()); + nic.setUsedIpUuid(ip.getUuid()); + nic.setNetmask(ip.getNetmask()); + nic.setGateway(ip.getGateway()); + for (UsedIpInventory usedIp : sortedNicsIps) { + /* update usedIpVo */ + UsedIpVO ipVO = Q.New(UsedIpVO.class).eq(UsedIpVO_.uuid, usedIp.getUuid()).find(); + ipVO.setVmNicUuid(nic.getUuid()); + ipVOS.add(ipVO); + nic.getUsedIps().add(ipVO); + } + nicsWithIp.add(nic); + spec.getDestNics().removeIf(inv -> nic.getUuid().equals(inv.getUuid())); + spec.getDestNics().add(VmNicInventory.valueOf(nic)); + wcomp.done(); + } + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errs.size() > 0) { + trigger.fail(errs.get(0)); + } else { + dbf.updateCollection(nicsWithIp); + dbf.updateCollection(ipVOS); + trigger.next(); + } + } + }); + } + + @Override + public void rollback(final FlowRollback chain, Map data) { + List ips = (List) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_ips.toString()); + List msgs = new ArrayList<>(); + for (UsedIpInventory ip : ips) { + ReturnIpMsg msg = new ReturnIpMsg(); + msg.setL3NetworkUuid(ip.getL3NetworkUuid()); + msg.setUsedIpUuid(ip.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, ip.getL3NetworkUuid()); + msgs.add(msg); + } + if (msgs.isEmpty()) { + chain.rollback(); + return; + } + bus.send(msgs, 1, new CloudBusListCallBack(chain) { + @Override + public void run(List replies) { + chain.rollback(); + } + }); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageFlow.java index b194d599b51..3fe184ac48d 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageFlow.java @@ -1,16 +1,15 @@ package org.zstack.compute.vm; -import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.compute.allocator.HostAllocatorManager; +import org.zstack.core.Platform; import org.zstack.core.asyncbatch.AsyncLoop; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; -import org.zstack.core.db.SimpleQuery; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.configuration.DiskOfferingInventory; import org.zstack.header.core.Completion; @@ -19,12 +18,15 @@ import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.host.HostInventory; -import org.zstack.header.image.ImageConstant.ImageMediaType; import org.zstack.header.image.ImageInventory; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.backup.BackupStorageVO; import org.zstack.header.storage.backup.BackupStorageVO_; -import org.zstack.header.storage.primary.*; +import org.zstack.header.storage.primary.AllocatePrimaryStorageSpaceMsg; +import org.zstack.header.storage.primary.AllocatePrimaryStorageSpaceReply; +import org.zstack.header.storage.primary.PrimaryStorageAllocationPurpose; +import org.zstack.header.storage.primary.PrimaryStorageConstant; +import org.zstack.header.storage.primary.ReleasePrimaryStorageSpaceMsg; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmInstanceSpec.VolumeSpec; @@ -33,8 +35,11 @@ import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; -import java.util.*; -import static org.zstack.core.Platform.operr; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmAllocatePrimaryStorageFlow implements Flow { @@ -53,29 +58,28 @@ public void run(final FlowTrigger trigger, final Map data) { final List msgs = new ArrayList<>(); final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); HostInventory destHost = spec.getDestHost(); - final ImageInventory iminv = spec.getImageSpec().getInventory(); // allocate ps for root volume AllocatePrimaryStorageSpaceMsg rmsg = new AllocatePrimaryStorageSpaceMsg(); - rmsg.setRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForRootVolume()); + rmsg.setCandidatePrimaryStorageUuids(spec.getCandidatePrimaryStorageUuidsForRootVolume()); rmsg.setVmInstanceUuid(spec.getVmInventory().getUuid()); if (spec.getImageSpec() != null) { - rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); + if (spec.getImageSpec().getInventory() != null) { + rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); + } Optional.ofNullable(spec.getImageSpec().getSelectedBackupStorage()) .ifPresent(it -> rmsg.setBackupStorageUuid(it.getBackupStorageUuid())); } - if (ImageMediaType.ISO.toString().equals(iminv.getMediaType())) { - rmsg.setSize(spec.getRootDiskOffering().getDiskSize()); - rmsg.setAllocationStrategy(spec.getRootDiskOffering().getAllocatorStrategy()); + rmsg.setSize(spec.getRootDiskAllocateSize()); + if (spec.getRootDiskOffering() != null) { rmsg.setDiskOfferingUuid(spec.getRootDiskOffering().getUuid()); - } else { - //TODO: find a way to allow specifying strategy for root disk - rmsg.setSize(iminv.getSize()); + rmsg.setAllocationStrategy(spec.getRootDiskOffering().getAllocatorStrategy()); } rmsg.setRequiredHostUuid(destHost.getUuid()); rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateNewVm.toString()); rmsg.setPossiblePrimaryStorageTypes(selectPsTypesFromSpec(spec)); + rmsg.setSystemTags(spec.getRootVolumeSystemTags()); bus.makeLocalServiceId(rmsg, PrimaryStorageConstant.SERVICE_ID); msgs.add(rmsg); @@ -83,11 +87,13 @@ public void run(final FlowTrigger trigger, final Map data) { // allocate ps for data volumes for (DiskOfferingInventory dinv : spec.getDataDiskOfferings()) { AllocatePrimaryStorageSpaceMsg amsg = new AllocatePrimaryStorageSpaceMsg(); - amsg.setRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForDataVolume()); + amsg.setCandidatePrimaryStorageUuids(spec.getCandidatePrimaryStorageUuidsForDataVolume()); amsg.setSize(dinv.getDiskSize()); amsg.setRequiredHostUuid(destHost.getUuid()); amsg.setAllocationStrategy(dinv.getAllocatorStrategy()); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); amsg.setDiskOfferingUuid(dinv.getUuid()); + amsg.setSystemTags(spec.getDataVolumeSystemTags()); bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); msgs.add(amsg); } @@ -113,11 +119,14 @@ public void run(MessageReply reply) { volumeSpec.setAllocatedInstallUrl(ar.getAllocatedInstallUrl()); volumeSpec.setPrimaryStorageInventory(ar.getPrimaryStorageInventory()); volumeSpec.setSize(ar.getSize()); - volumeSpec.setType(msg.getImageUuid() != null ? VolumeType.Root.toString() : VolumeType.Data.toString()); + volumeSpec.setType(PrimaryStorageAllocationPurpose.CreateNewVm.toString().equals(msg.getPurpose()) ? + VolumeType.Root.toString() : VolumeType.Data.toString()); volumeSpec.setDiskOfferingUuid(msg.getDiskOfferingUuid()); if (VolumeType.Root.toString().equals(volumeSpec.getType())) { + spec.setAllocatedPrimaryStorageUuidForRootVolume(ar.getPrimaryStorageInventory().getUuid()); volumeSpec.setTags(spec.getRootVolumeSystemTags()); } else { + spec.setAllocatedPrimaryStorageUuidForDataVolume(ar.getPrimaryStorageInventory().getUuid()); volumeSpec.setTags(spec.getDataVolumeSystemTags()); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java index 811d833b767..bc2f59d6cdc 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java @@ -1,15 +1,11 @@ package org.zstack.compute.vm; -import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.Q; -import org.zstack.core.db.SQL; -import org.zstack.core.db.SimpleQuery; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowRollback; @@ -23,10 +19,8 @@ import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.volume.VolumeInventory; -import java.util.Arrays; -import java.util.List; +import java.util.Collections; import java.util.Map; -import java.util.stream.Collectors; import static org.zstack.core.Platform.operr; @@ -39,7 +33,7 @@ public class VmAllocatePrimaryStorageForAttachingDiskFlow implements Flow { @Autowired protected ErrorFacade errf; - private String allocatedInstallUrl; + private final String ALLOCATED_INSTALL_URL = "allocated_install_url"; @Override public void run(final FlowTrigger chain, final Map data) { @@ -58,31 +52,14 @@ public void run(final FlowTrigger chain, final Map data) { AllocatePrimaryStorageSpaceMsg amsg = new AllocatePrimaryStorageSpaceMsg(); amsg.setSize(volume.getSize()); - amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString()); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); amsg.setDiskOfferingUuid(volume.getDiskOfferingUuid()); amsg.setServiceId(bus.makeLocalServiceId(PrimaryStorageConstant.SERVICE_ID)); if (volume.isShareable()) { String clusterUuid = spec.getVmInventory().getClusterUuid(); - List vos = SQL.New("select pri" + - " from PrimaryStorageVO pri, PrimaryStorageClusterRefVO ref" + - " where ref.clusterUuid = :clusterUuid" + - " and ref.primaryStorageUuid = pri.uuid" + - " and pri.status = :status" + - " and pri.state = :priState") - .param("clusterUuid", clusterUuid) - .param("status", PrimaryStorageStatus.Connected) - .param("priState", PrimaryStorageState.Enabled) - .list(); - - if (CollectionUtils.isNotEmpty(vos)) { - amsg.setPossiblePrimaryStorageTypes(vos.stream() - .filter(v -> PrimaryStorageType.valueOf(v.getType()).isSupportSharedVolume()) - .map(PrimaryStorageVO::getType) - .collect(Collectors.toList())); - } - - amsg.setRequiredClusterUuids(Arrays.asList(clusterUuid)); + amsg.setRequiredClusterUuids(Collections.singletonList(clusterUuid)); + amsg.setRequiredFeatures(Collections.singleton(PrimaryStorageFeature.SHARED_VOLUME)); } else { amsg.setRequiredHostUuid(hinv.getUuid()); } @@ -92,8 +69,9 @@ public void run(final FlowTrigger chain, final Map data) { public void run(MessageReply reply) { if (reply.isSuccess()) { AllocatePrimaryStorageSpaceReply ar = (AllocatePrimaryStorageSpaceReply) reply; - allocatedInstallUrl = ar.getAllocatedInstallUrl(); + data.put(ALLOCATED_INSTALL_URL, ar.getAllocatedInstallUrl()); data.put(VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString(), ar.getPrimaryStorageInventory()); + data.put(VmInstanceConstant.Params.AllocatedUrlForAttachingVolume.toString(), ar.getAllocatedInstallUrl()); data.put(VmAllocatePrimaryStorageForAttachingDiskFlow.class, ar.getSize()); chain.next(); } else { @@ -109,7 +87,7 @@ public void rollback(FlowRollback chain, Map data) { if (size != null) { PrimaryStorageInventory pri = (PrimaryStorageInventory) data.get(VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString()); ReleasePrimaryStorageSpaceMsg rmsg = new ReleasePrimaryStorageSpaceMsg(); - rmsg.setAllocatedInstallUrl(allocatedInstallUrl); + rmsg.setAllocatedInstallUrl((String)data.get(ALLOCATED_INSTALL_URL)); rmsg.setPrimaryStorageUuid(pri.getUuid()); rmsg.setDiskSize(size); bus.makeTargetServiceIdByResourceUuid(rmsg, PrimaryStorageConstant.SERVICE_ID, pri.getUuid()); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAllocateVolumeFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAllocateVolumeFlow.java index 26ebe202711..dc8da3fae8a 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAllocateVolumeFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAllocateVolumeFlow.java @@ -1,5 +1,6 @@ package org.zstack.compute.vm; +import org.apache.commons.collections.MapUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; @@ -36,6 +37,8 @@ import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.zstack.core.progress.ProgressReportService.taskProgress; @@ -62,13 +65,29 @@ protected List prepareMsg(Map ctx) { throw new CloudRuntimeException(String.format("accountUuid for vm[uuid:%s] is null", spec.getVmInventory().getUuid())); } + if (!MapUtils.isEmpty(spec.getDataVolumeSystemTagsOnIndex()) && !CollectionUtils.isEmpty(spec.getDataDiskOfferings())) { + List dataVolumeSpecs = spec.getVolumeSpecs().stream() + .filter(s -> s.getType().equals(VolumeType.Data.toString())).collect(Collectors.toList()); + + IntStream.range(0, dataVolumeSpecs.size()).forEach(index -> { + List systemTags = spec.getDataVolumeSystemTagsOnIndex().get(String.valueOf(index)); + if (!CollectionUtils.isEmpty(systemTags)) { + dataVolumeSpecs.get(index).setTags(systemTags); + } + }); + } + List volumeSpecs = spec.getVolumeSpecs(); List msgs = new ArrayList<>(volumeSpecs.size()); for (VolumeSpec vspec : volumeSpecs) { CreateVolumeMsg msg = new CreateVolumeMsg(); Set tags = new HashSet<>(); - if (vspec != null && vspec.getTags() != null) { - tags.addAll(vspec.getTags()); + if (vspec != null) { + if (vspec.getTags() != null) { + tags.addAll(vspec.getTags()); + } + } else { + continue; } DebugUtils.Assert(vspec.getType() != null, "VolumeType can not be null!"); @@ -77,18 +96,16 @@ protected List prepareMsg(Map ctx) { msg.setResourceUuid((String) ctx.get("uuid")); msg.setName("ROOT-for-" + spec.getVmInventory().getName()); msg.setDescription(String.format("Root volume for VM[uuid:%s]", spec.getVmInventory().getUuid())); - msg.setRootImageUuid(spec.getImageSpec().getInventory().getUuid()); + + if (spec.getImageSpec().relayOnImage()) { + msg.setRootImageUuid(spec.getImageSpec().getInventory().getUuid()); + } + + msg.setFormat(spec.getVolumeFormatFromImage()); + if (spec.getRootVolumeSystemTags() != null) { tags.addAll(spec.getRootVolumeSystemTags()); } - if (ImageMediaType.ISO.toString().equals(spec.getImageSpec().getInventory().getMediaType())) { - msg.setFormat(VolumeFormat.getVolumeFormatByMasterHypervisorType(spec.getDestHost().getHypervisorType()).toString()); - } else if (spec.getImageSpec().getInventory().getFormat() != null) { - VolumeFormat imageFormat = VolumeFormat.valueOf(spec.getImageSpec().getInventory().getFormat()); - msg.setFormat(imageFormat.getOutputFormat(spec.getDestHost().getHypervisorType())); - } else { - msg.setFormat(ImageConstant.QCOW2_FORMAT_STRING); - } } else if (VolumeType.Data.toString().equals(vspec.getType())) { msg.setName(String.format("DATA-for-%s", spec.getVmInventory().getName())); msg.setDescription(String.format("DataVolume-%s", spec.getVmInventory().getUuid())); @@ -140,6 +157,7 @@ public void run(List replies) { spec.getDestDataVolumes().add(inv); } + vspec.setAssociatedVolumeUuid(inv.getUuid()); vspec.setIsVolumeCreated(true); } else { err = r.getError(); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmApplyNetworkServiceOnChangeIPFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmApplyNetworkServiceOnChangeIPFlow.java new file mode 100644 index 00000000000..9ea2fc5b834 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmApplyNetworkServiceOnChangeIPFlow.java @@ -0,0 +1,69 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.core.workflow.FlowException; +import org.zstack.header.core.workflow.FlowRollback; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.network.service.NetworkServiceExtensionPoint; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceConstant.VmOperation; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmNicSpec; +import org.zstack.header.vm.VmNicVO; +import org.zstack.network.service.NetworkServiceManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import static org.zstack.utils.CollectionDSL.*; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmApplyNetworkServiceOnChangeIPFlow implements Flow { + private static final CLogger logger = Utils.getLogger(VmApplyNetworkServiceOnChangeIPFlow.class); + @Autowired + private NetworkServiceManager nsMgr; + + @Override + public void run(FlowTrigger trigger, Map data) { + VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + VmNicVO vmNicVO = (VmNicVO) data.get(VmInstanceConstant.Params.VmNicInventory.toString()); + + if (spec.getCurrentVmOperation() == VmOperation.ChangeNicNetwork) { + L3NetworkInventory l3Inv = (L3NetworkInventory) data.get(VmInstanceConstant.Params.L3NetworkInventory.toString()); + VmInstanceInventory vm = (VmInstanceInventory) data.get(VmInstanceConstant.Params.vmInventory.toString()); + + spec.setVmInventory(vm); + spec.setL3Networks(list(new VmNicSpec(l3Inv))); + } + + spec.setDestNics(list(VmNicInventory.valueOf(vmNicVO))); + + nsMgr.applyNetworkServiceOnChangeIP(spec, null, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + trigger.rollback(); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAssignDeviceIdToAttachingVolumeFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAssignDeviceIdToAttachingVolumeFlow.java index 3a2fbee2e41..28fd645f421 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAssignDeviceIdToAttachingVolumeFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAssignDeviceIdToAttachingVolumeFlow.java @@ -31,7 +31,7 @@ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmAssignDeviceIdToAttachingVolumeFlow implements Flow { - CLogger logger = Utils.getLogger(VmAssignDeviceIdToAttachingVolumeFlow.class); + private static final CLogger logger = Utils.getLogger(VmAssignDeviceIdToAttachingVolumeFlow.class); @Autowired private DatabaseFacade dbf; @Autowired @@ -58,7 +58,7 @@ public void run(FlowTrigger chain, Map ctx) { final VmInstanceSpec spec = (VmInstanceSpec) ctx.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); VolumeVO dvol = dbf.findByUuid(volume.getUuid(), VolumeVO.class); - dvol.setDeviceId(new NextVolumeDeviceIdGetter().getNextVolumeDeviceId(spec.getVmInventory().getUuid())); + dvol.setDeviceId(volume.getDeviceId() != null ? volume.getDeviceId() : new NextVolumeDeviceIdGetter().getNextVolumeDeviceId(spec.getVmInventory().getUuid())); dvol = dbf.updateAndRefresh(dvol); ctx.put(VmInstanceConstant.Params.AttachingVolumeInventory.toString(), VolumeInventory.valueOf(dvol)); chain.next(); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAttachNicOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAttachNicOnHypervisorFlow.java index c2f70031f38..5f154b829b9 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAttachNicOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAttachNicOnHypervisorFlow.java @@ -6,7 +6,6 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.host.HostConstant; @@ -15,6 +14,8 @@ import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmNicInventory; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; import java.util.Map; @@ -22,6 +23,7 @@ */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmAttachNicOnHypervisorFlow extends NoRollbackFlow { + protected static final CLogger logger = Utils.getLogger(VmAttachNicOnHypervisorFlow.class); @Autowired private CloudBus bus; @@ -32,11 +34,20 @@ public class VmAttachNicOnHypervisorFlow extends NoRollbackFlow { public void run(final FlowTrigger trigger, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); VmNicInventory nic = spec.getDestNics().get(0); + final String hostUuid = spec.getVmInventory().getHostUuid() == null ? + spec.getVmInventory().getLastHostUuid() : + spec.getVmInventory().getHostUuid(); + if (hostUuid == null) { + logger.info(String.format("Skip attaching nic on hypervisor: host of VM[uuid=%s] is not set", + spec.getVmInventory().getUuid())); + trigger.next(); + return; + } VmAttachNicOnHypervisorMsg msg = new VmAttachNicOnHypervisorMsg(); - msg.setHostUuid(spec.getVmInventory().getHostUuid()); + msg.setHostUuid(hostUuid); msg.setNicInventory(nic); - bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, msg.getHostUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); bus.send(msg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeOnHypervisorFlow.java index c3cf78e646a..55665a08a6e 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeOnHypervisorFlow.java @@ -1,21 +1,26 @@ package org.zstack.compute.vm; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.compute.host.HostManager; +import org.zstack.core.db.Q; +import org.zstack.header.host.*; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.header.core.ExceptionSafe; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; -import org.zstack.header.host.HostConstant; +import org.zstack.header.host.*; import org.zstack.header.message.MessageReply; -import org.zstack.header.vm.AttachVolumeToVmOnHypervisorMsg; -import org.zstack.header.vm.VmInstanceConstant; -import org.zstack.header.vm.VmInstanceSpec; -import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.*; +import org.zstack.header.vm.devices.VirtualDeviceInfo; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; import org.zstack.header.volume.VolumeInventory; import java.util.List; @@ -29,7 +34,11 @@ public class VmAttachVolumeOnHypervisorFlow implements Flow { protected CloudBus bus; @Autowired private ErrorFacade errf; - + @Autowired + private VmInstanceDeviceManager vidm; + @Autowired + private HostManager hostManager; + @Override public void run(final FlowTrigger chain, Map ctx) { final VolumeInventory volume = (VolumeInventory) ctx.get(VmInstanceConstant.Params.AttachingVolumeInventory.toString()); @@ -39,15 +48,14 @@ public void run(final FlowTrigger chain, Map ctx) { assert spec != null; assert attachedDataVolumes != null; - String vmState = spec.getVmInventory().getState(); - if (VmInstanceState.Stopped.toString().equals(vmState)) { + String hostUuid = spec.getVmInventory().getHostUuid(); + hostUuid = hostUuid == null ? spec.getVmInventory().getLastHostUuid() : hostUuid; + HostVO hostVO = Q.New(HostVO.class).eq(HostVO_.uuid, hostUuid).find(); + if (hostVO == null) { chain.next(); return; } - assert VmInstanceState.Running.toString().equals(vmState) || VmInstanceState.Paused.toString().equals(vmState); - - String hostUuid = spec.getVmInventory().getHostUuid(); AttachVolumeToVmOnHypervisorMsg msg = new AttachVolumeToVmOnHypervisorMsg(); msg.setHostUuid(hostUuid); @@ -59,6 +67,8 @@ public void run(final FlowTrigger chain, Map ctx) { @Override public void run(MessageReply reply) { if (reply.isSuccess()) { + processDeviceAddressInfo(reply.castReply(), spec); + chain.next(); } else { chain.fail(reply.getError()); @@ -67,6 +77,19 @@ public void run(MessageReply reply) { }); } + @ExceptionSafe + private void processDeviceAddressInfo(AttachVolumeToVmOnHypervisorReply reply, final VmInstanceSpec spec) { + if (CollectionUtils.isEmpty(reply.getVirtualDeviceInfoList())) { + return; + } + + for (VirtualDeviceInfo info : reply.getVirtualDeviceInfoList()) { + if (info.isValid()) { + vidm.createOrUpdateVmDeviceAddress(info, spec.getVmInventory().getUuid()); + } + } + } + @Override public void rollback(FlowRollback chain, Map data) { chain.rollback(); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeValidator.java b/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeValidator.java index bcebdeb8f7a..c587f2a92f4 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeValidator.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmAttachVolumeValidator.java @@ -2,6 +2,7 @@ import org.zstack.core.ScatteredValidator; import org.zstack.header.vm.VmAttachVolumeValidatorMethod; +import org.zstack.header.vm.VmInstanceInventory; import java.lang.reflect.Method; import java.util.List; @@ -14,10 +15,10 @@ public class VmAttachVolumeValidator extends ScatteredValidator { static { // method signature: static void xxx(String vmUuid, String volumeUuid) - methods = collectValidatorMethods(VmAttachVolumeValidatorMethod.class, String.class, String.class); + methods = collectValidatorMethods(VmAttachVolumeValidatorMethod.class, VmInstanceInventory.class, String.class); } - public void validate(String vmUuid, String volumeUuid) { - invokeValidatorMethods(methods, vmUuid, volumeUuid); + public void validate(VmInstanceInventory vmInv, String volumeUuid) { + invokeValidatorMethods(methods, vmInv, volumeUuid); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java b/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java index 791b88217f8..5b2dd2f399a 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmCascadeExtension.java @@ -10,11 +10,8 @@ import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.CloudBusListCallBack; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.Q; -import org.zstack.core.db.SimpleQuery; +import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; -import org.zstack.core.db.UpdateQuery; import org.zstack.header.cluster.ClusterInventory; import org.zstack.header.cluster.ClusterVO; import org.zstack.header.configuration.InstanceOfferingInventory; @@ -48,7 +45,9 @@ import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; import javax.persistence.Query; import javax.persistence.Tuple; @@ -147,10 +146,10 @@ private VmNicDetachResult getVmNicDetachMsgs(List structs List dmsgs = new ArrayList<>(); for (L2NetworkDetachStruct s : structs) { - String sql = "select vm.uuid, nic.uuid from VmInstanceVO vm, VmNicVO nic, L3NetworkVO l3, UsedIpVO ip" + String sql = "select vm.uuid, nic.uuid from VmInstanceVO vm, VmNicVO nic, L3NetworkVO l3" + " where vm.clusterUuid = :clusterUuid" + " and l3.l2NetworkUuid = :l2NetworkUuid" - + " and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = l3.uuid " + + " and nic.l3NetworkUuid = l3.uuid" + " and nic.vmInstanceUuid = vm.uuid"; TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); q.setParameter("clusterUuid", s.getClusterUuid()); @@ -286,6 +285,49 @@ private void handleDeletionCleanup(CascadeAction action, Completion completion) completion.success(); } + protected List handleDeletionForIpRange(List vminvs, List iprs) { + List msgs = new ArrayList<>(); + List uuids = iprs.stream().map(IpRangeInventory::getUuid).collect(Collectors.toList()); + for (VmDeletionStruct vm : vminvs) { + for (VmNicInventory nic : vm.getInventory().getVmNics()) { + UsedIpInventory ip4 = null, ip6 = null; + for (UsedIpInventory ip : nic.getUsedIps()) { + if (ip.getIpVersion() == IPv6Constants.IPv4) { + ip4 = ip; + } else if (ip.getIpVersion() == IPv6Constants.IPv6) { + ip6 = ip; + } + } + + /* both ipv4 and ipv6 has been deleted or deleting, then delete nic */ + if ((ip4 == null || uuids.contains(ip4.getIpRangeUuid())) + && (ip6 == null || uuids.contains(ip6.getIpRangeUuid()))) { + DetachNicFromVmMsg msg = new DetachNicFromVmMsg(); + msg.setVmInstanceUuid(nic.getVmInstanceUuid()); + msg.setVmNicUuid(nic.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vm.getInventory().getUuid()); + msgs.add(msg); + } else { + boolean deleteIp4 = false, hasIp6 = false; + if (ip4 != null && uuids.contains(ip4.getIpRangeUuid())) { + deleteIp4 = true; + } + if (ip6 != null && !uuids.contains(ip6.getIpRangeUuid())) { + hasIp6 = true; + } + + /* ipv4 is deleted and ipv6 is not deleted, move ipv6 address to nic ip */ + if (deleteIp4 && hasIp6) { + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, nic.getUuid()) + .set(VmNicVO_.ip, ip6.getIp()).set(VmNicVO_.gateway, ip6.getGateway()).update(); + } + } + } + } + + return msgs; + } + protected void handleDeletion(final CascadeAction action, final Completion completion) { int op = toDeletionOpCode(action); if (op == OP_NOPE) { @@ -448,19 +490,8 @@ public void done(ErrorCodeList errorCodeList) { } } else if (IpRangeVO.class.getSimpleName().equals(action.getParentIssuer())) { List iprs = action.getParentIssuerContext(); - List uuids = iprs.stream().map(IpRangeInventory::getUuid).collect(Collectors.toList()); - for (VmDeletionStruct vm : vminvs) { - for (VmNicInventory nic : vm.getInventory().getVmNics()) { - /* if any ip of the nic is in the rang of delete, then delete the nic */ - if (nic.getUsedIps().stream().anyMatch(ip -> uuids.contains(ip.getIpRangeUuid()))) { - DetachNicFromVmMsg msg = new DetachNicFromVmMsg(); - msg.setVmInstanceUuid(vm.getInventory().getUuid()); - msg.setVmNicUuid(nic.getUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vm.getInventory().getUuid()); - msgs.add(msg); - } - } - } + List dmsgs = handleDeletionForIpRange(vminvs, iprs); + msgs.addAll(dmsgs); } detachVmNicCascade(msgs, true, completion); @@ -623,11 +654,11 @@ public String call(L3NetworkInventory arg) { @Override @Transactional(readOnly = true) public List call() { - String sql = "select vm from VmInstanceVO vm, L3NetworkVO l3, VmNicVO nic, UsedIpVO ip" + + String sql = "select vm from VmInstanceVO vm, L3NetworkVO l3, VmNicVO nic" + " where vm.type = :vmType" + " and vm.uuid = nic.vmInstanceUuid" + " and vm.state in (:vmStates)" + - " and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = l3.uuid" + + " and nic.l3NetworkUuid = l3.uuid" + " and l3.uuid in (:uuids)" + " group by vm.uuid"; TypedQuery q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmClockSyncConstant.java b/compute/src/main/java/org/zstack/compute/vm/VmClockSyncConstant.java new file mode 100644 index 00000000000..dc06fac054b --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmClockSyncConstant.java @@ -0,0 +1,5 @@ +package org.zstack.compute.vm; + +public interface VmClockSyncConstant { + Integer DISABLE_VM_CLOCK_SYNC = 0; +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmCpuVendor.java b/compute/src/main/java/org/zstack/compute/vm/VmCpuVendor.java new file mode 100644 index 00000000000..546be3dbe78 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmCpuVendor.java @@ -0,0 +1,6 @@ +package org.zstack.compute.vm; + +public enum VmCpuVendor { + None, + AuthenticAMD; +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java index 51668d6dc0b..5b054dede75 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmCreateOnHypervisorFlow.java @@ -33,11 +33,7 @@ public class VmCreateOnHypervisorFlow implements Flow { @Autowired private EventFacade evtf; - private List exts; - - public VmCreateOnHypervisorFlow() { - exts = pluginRgty.getExtensionList(VmBeforeCreateOnHypervisorExtensionPoint.class); - } + private final List exts = pluginRgty.getExtensionList(VmBeforeCreateOnHypervisorExtensionPoint.class); private void fireExtensions(VmInstanceSpec spec) { for (VmBeforeCreateOnHypervisorExtensionPoint ext : exts) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmDeleteVolumeFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmDeleteVolumeFlow.java index 0086726e7ff..8acb64f9bc3 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmDeleteVolumeFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmDeleteVolumeFlow.java @@ -123,9 +123,10 @@ public String call(VolumeInventory arg) { //NOTE(weiw): not using batch sql to avoid deadlock for (String volumeUuid: dataVolumeUuids) { - String sql = "update VolumeVO vol set vol.vmInstanceUuid = null where vol.uuid in (:uuids)"; + String sql = "update VolumeVO vol set vol.vmInstanceUuid = null, vol.lastVmInstanceUuid = :vmUuid where vol.uuid in (:uuids)"; Query q = dbf.getEntityManager().createQuery(sql); q.setParameter("uuids", volumeUuid); + q.setParameter("vmUuid", spec.getVmInventory().getUuid()); q.executeUpdate(); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmDetachNicFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmDetachNicFlow.java index fd57a3c1e5e..a175e7d11e4 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmDetachNicFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmDetachNicFlow.java @@ -16,6 +16,7 @@ import org.zstack.header.network.l3.L3NetworkConstant; import org.zstack.header.network.l3.ReturnIpMsg; import org.zstack.header.vm.*; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; @@ -30,6 +31,8 @@ public class VmDetachNicFlow extends NoRollbackFlow { private DatabaseFacade dbf; @Autowired private CloudBus bus; + @Autowired + private VmInstanceDeviceManager vidm; @Override public void run(FlowTrigger trigger, Map data) { @@ -51,6 +54,8 @@ public String call(VmNicInventory arg) { dbf.update(vm); } + vidm.deleteVmDeviceAddress(nic.getUuid(), spec.getVmInventory().getUuid()); + boolean releaseNic = (boolean) data.get(VmInstanceConstant.Params.ReleaseNicAfterDetachNic.toString()); if (!releaseNic) { UpdateQuery.New(VmNicVO.class) diff --git a/compute/src/main/java/org/zstack/compute/vm/VmDetachNicOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmDetachNicOnHypervisorFlow.java index 6e05ade7d01..ab091644154 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmDetachNicOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmDetachNicOnHypervisorFlow.java @@ -12,6 +12,8 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; import java.util.Map; @@ -20,18 +22,28 @@ */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmDetachNicOnHypervisorFlow extends NoRollbackFlow { + protected static final CLogger logger = Utils.getLogger(VmDetachNicOnHypervisorFlow.class); @Autowired private CloudBus bus; @Override public void run(final FlowTrigger trigger, Map data) { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + final String hostUuid = spec.getVmInventory().getHostUuid() == null ? + spec.getVmInventory().getLastHostUuid() : + spec.getVmInventory().getHostUuid(); + if (hostUuid == null) { + logger.info(String.format("Skip detaching nic on hypervisor: host of VM[uuid=%s] is not set", + spec.getVmInventory().getUuid())); + trigger.next(); + return; + } DetachNicFromVmOnHypervisorMsg msg = new DetachNicFromVmOnHypervisorMsg(); - msg.setHostUuid(spec.getVmInventory().getHostUuid()); + msg.setHostUuid(hostUuid); msg.setVmInstanceUuid(spec.getVmInventory().getUuid()); msg.setNic(spec.getDestNics().get(0)); - bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, msg.getHostUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); bus.send(msg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java index ae9e68558ac..b060a48e3c6 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java @@ -6,8 +6,6 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.SimpleQuery; -import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; @@ -23,8 +21,6 @@ import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmInstanceSpec.ImageSpec; -import org.zstack.header.volume.VolumeVO; -import org.zstack.header.volume.VolumeVO_; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; @@ -51,12 +47,9 @@ public void run(final FlowTrigger trigger, Map data) { final VmInstanceSpec.IsoSpec isoSpec = spec.getDestIsoList().stream() .filter(s -> s.getImageUuid().equals(iso.getUuid())) .findAny() - .get(); + .orElse(null); - SimpleQuery q = dbf.createQuery(VolumeVO.class); - q.select(VolumeVO_.primaryStorageUuid); - q.add(VolumeVO_.uuid, Op.EQ, spec.getVmInventory().getRootVolumeUuid()); - final String psUuid = q.findValue(); + final String psUuid = spec.getVmInventory().getRootVolume().getPrimaryStorageUuid(); final HostInventory host = spec.getDestHost(); ImageBackupStorageSelector selector = new ImageBackupStorageSelector(); @@ -98,9 +91,12 @@ public void run(MessageReply reply) { return; } - DownloadIsoToPrimaryStorageReply r = reply.castReply(); - isoSpec.setInstallPath(r.getInstallPath()); - isoSpec.setPrimaryStorageUuid(psUuid); + if (isoSpec != null) { + DownloadIsoToPrimaryStorageReply r = reply.castReply(); + isoSpec.setInstallPath(r.getInstallPath()); + isoSpec.setPrimaryStorageUuid(psUuid); + isoSpec.setProtocol(r.getProtocol()); + } trigger.next(); } }); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmFactoryManager.java b/compute/src/main/java/org/zstack/compute/vm/VmFactoryManager.java new file mode 100644 index 00000000000..e86c4db9364 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmFactoryManager.java @@ -0,0 +1,18 @@ +package org.zstack.compute.vm; + +import org.zstack.header.vm.VmInstanceBaseExtensionFactory; +import org.zstack.header.vm.HypervisorBasedVmConfigurationFactory; +import org.zstack.header.vm.VmInstanceFactory; +import org.zstack.header.vm.VmInstanceNicFactory; + +public interface VmFactoryManager { + VmInstanceFactory getVmInstanceFactory(String vmInstanceType); + + VmInstanceBaseExtensionFactory getVmInstanceBaseExtensionFactory(Class vmInstanceClass); + + VmInstanceNicFactory getVmInstanceNicFactory(String vmNicType); + + VmNicQosConfigBackend getVmNicQosConfigBackend(String vmInstanceType); + + HypervisorBasedVmConfigurationFactory getVmInstanceConfigurationFactory(String hypervisorType); +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmFactoryManagerImpl.java b/compute/src/main/java/org/zstack/compute/vm/VmFactoryManagerImpl.java new file mode 100644 index 00000000000..e6ec07e9c7f --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmFactoryManagerImpl.java @@ -0,0 +1,110 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.Component; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.vm.VmInstanceBaseExtensionFactory; +import org.zstack.header.vm.HypervisorBasedVmConfigurationFactory; +import org.zstack.header.vm.VmInstanceFactory; +import org.zstack.header.vm.VmInstanceNicFactory; + +import java.util.HashMap; +import java.util.Map; + +public class VmFactoryManagerImpl implements VmFactoryManager, Component { + @Autowired + private PluginRegistry pluginRgty; + + private final Map vmInstanceFactories = new HashMap<>(); + private final Map vmInstanceBaseExtensionFactories = new HashMap<>(); + private final Map vmInstanceNicFactories = new HashMap<>(); + private final Map vmNicQosConfigMap = new HashMap<>(); + private final Map vmInstanceConfigurationFactoryMap = new HashMap<>(); + + @Override + public VmInstanceFactory getVmInstanceFactory(String vmInstanceType) { + return vmInstanceFactories.get(vmInstanceType); + } + + @Override + public VmInstanceBaseExtensionFactory getVmInstanceBaseExtensionFactory(Class vmInstanceClass) { + return vmInstanceBaseExtensionFactories.get(vmInstanceClass); + } + + @Override + public VmInstanceNicFactory getVmInstanceNicFactory(String vmNicType) { + return vmInstanceNicFactories.get(vmNicType); + } + + @Override + public VmNicQosConfigBackend getVmNicQosConfigBackend(String vmInstanceType) { + return vmNicQosConfigMap.get(vmInstanceType); + } + + @Override + public HypervisorBasedVmConfigurationFactory getVmInstanceConfigurationFactory(String hypervisorType) { + return vmInstanceConfigurationFactoryMap.get(hypervisorType); + } + + private void populateExtensions() { + for (VmInstanceFactory ext : pluginRgty.getExtensionList(VmInstanceFactory.class)) { + VmInstanceFactory old = vmInstanceFactories.get(ext.getType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VmInstanceFactory[%s, %s] for type[%s]", + old.getClass().getName(), ext.getClass().getName(), ext.getType())); + } + vmInstanceFactories.put(ext.getType().toString(), ext); + } + + for (VmInstanceBaseExtensionFactory ext : pluginRgty.getExtensionList(VmInstanceBaseExtensionFactory.class)) { + for (Class clz : ext.getMessageClasses()) { + VmInstanceBaseExtensionFactory old = vmInstanceBaseExtensionFactories.get(clz); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VmInstanceBaseExtensionFactory[%s, %s] for the" + + " message[%s]", old.getClass(), ext.getClass(), clz)); + } + + vmInstanceBaseExtensionFactories.put(clz, ext); + } + } + + for (VmInstanceNicFactory ext : pluginRgty.getExtensionList(VmInstanceNicFactory.class)) { + VmInstanceNicFactory old = vmInstanceNicFactories.get(ext.getType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VmInstanceNicFactory[%s, %s] for type[%s]", + old.getClass().getName(), ext.getClass().getName(), ext.getType())); + } + vmInstanceNicFactories.put(ext.getType().toString(), ext); + } + + for (VmNicQosConfigBackend ext : pluginRgty.getExtensionList(VmNicQosConfigBackend.class)) { + VmNicQosConfigBackend old = vmNicQosConfigMap.get(ext.getVmInstanceType()); + if (old != null) { + throw new CloudRuntimeException(String.format("can not add VmNicQosConfigBackend, because duplicate VmNicQosConfigBackend [%s, %s] for type[%s]", + old.getClass().getName(), ext.getClass().getName(), ext.getVmInstanceType())); + } + vmNicQosConfigMap.put(ext.getVmInstanceType(), ext); + } + + for (HypervisorBasedVmConfigurationFactory ext : pluginRgty.getExtensionList(HypervisorBasedVmConfigurationFactory.class)) { + HypervisorBasedVmConfigurationFactory old = vmInstanceConfigurationFactoryMap.get(ext.getHypervisorType()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VmInstanceFactory[%s, %s] for vm on hypervisor[%s]", + old.getClass().getName(), ext.getClass().getName(), ext.getHypervisorType())); + } + vmInstanceConfigurationFactoryMap.put(ext.getHypervisorType(), ext); + } + } + + @Override + public boolean start() { + populateExtensions(); + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmGlobalConfig.java b/compute/src/main/java/org/zstack/compute/vm/VmGlobalConfig.java index 4263e1286bf..bd79900c13c 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmGlobalConfig.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmGlobalConfig.java @@ -5,6 +5,7 @@ import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.vm.VmNicVO; import org.zstack.resourceconfig.BindResourceConfig; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceVO; @@ -25,20 +26,31 @@ public class VmGlobalConfig { public static GlobalConfig VM_EXPUNGE_INTERVAL = new GlobalConfig(CATEGORY, "expungeInterval"); @GlobalConfigValidation(validValues = {"true", "false"}) public static GlobalConfig VM_CLEAN_TRAFFIC = new GlobalConfig(CATEGORY, "cleanTraffic"); - @GlobalConfigValidation(validValues = {"cirrus","vga", "qxl"}) + @GlobalConfigValidation(validValues = {"cirrus","vga", "qxl", "virtio"}) @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig VM_VIDEO_TYPE = new GlobalConfig(CATEGORY, "videoType"); + @GlobalConfigValidation(validValues = {"ich6","ich9", "ac97"}) + @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) + public static GlobalConfig VM_SOUND_TYPE = new GlobalConfig(CATEGORY, "soundType"); @GlobalConfigValidation(validValues = {"off","all", "filter"}) + @BindResourceConfig(value = {VmInstanceVO.class}) public static GlobalConfig VM_SPICE_STREAMING_MODE= new GlobalConfig(CATEGORY, "spiceStreamingMode"); @GlobalConfigValidation @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig NUMA = new GlobalConfig(CATEGORY, "numa"); @GlobalConfigValidation + @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) + public static GlobalConfig VM_MAX_VCPU = new GlobalConfig(CATEGORY, "vm.max.vcpu"); + @GlobalConfigValidation public static GlobalConfig VM_BOOT_MENU = new GlobalConfig(CATEGORY, "bootMenu"); + @GlobalConfigValidation(numberGreaterThan = 0, numberLessThan = 65535) + @BindResourceConfig(value = {VmInstanceVO.class}) + public static GlobalConfig VM_BOOT_MENU_SPLASH_TIMEOUT = new GlobalConfig(CATEGORY, "bootMenuSplashTimeout"); @GlobalConfigValidation(validValues = {"true", "false"}) @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig KVM_HIDDEN_STATE = new GlobalConfig(CATEGORY, "kvmHiddenState"); @GlobalConfigValidation(validValues = {"true", "false"}) + @BindResourceConfig(value = {VmInstanceVO.class}) public static GlobalConfig VM_PORT_OFF = new GlobalConfig(CATEGORY, "vmPortOff"); @GlobalConfigValidation(validValues = {"true", "false"}) @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) @@ -63,7 +75,7 @@ public class VmGlobalConfig { public static GlobalConfig RESOURCE_BINDING_STRATEGY = new GlobalConfig(CATEGORY, "resourceBinding.strategy"); @GlobalConfigValidation(validValues = {"None", "Preserve","Reboot","Shutdown"}) - @BindResourceConfig({VmInstanceVO.class}) + @BindResourceConfig({VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig VM_CRASH_STRATEGY = new GlobalConfig(CATEGORY, "crash.strategy"); @GlobalConfigValidation(numberGreaterThan = 0) @@ -73,11 +85,11 @@ public class VmGlobalConfig { public static GlobalConfig VM_REBOOT_THRESHOLD_TIMES = new GlobalConfig(CATEGORY, "crash.rebootThreshold.times"); @GlobalConfigValidation(validValues = {"Auto", "All"}) - @BindResourceConfig({VmInstanceVO.class}) + @BindResourceConfig({VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig RESOURCE_BINDING_SCENE = new GlobalConfig(CATEGORY, "resourceBinding.Scene"); @GlobalConfigValidation(inNumberRange = {1, 256}) - @BindResourceConfig({VmInstanceVO.class, ClusterVO.class}) + @BindResourceConfig({VmNicVO.class, VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig VM_NIC_MULTIQUEUE_NUM = new GlobalConfig(CATEGORY, "nicMultiQueueNum"); @GlobalConfigValidation(numberGreaterThan = 1) @@ -90,4 +102,35 @@ public class VmGlobalConfig { @BindResourceConfig(value = {VmInstanceVO.class}) @GlobalConfigValidation(validValues = {"guest", "host"}) public static GlobalConfig VM_CLOCK_TRACK = new GlobalConfig(CATEGORY, "vm.clock.track"); + + @BindResourceConfig(value = {VmInstanceVO.class}) + @GlobalConfigValidation(validValues = {"0", "60", "600", "1800", "3600", "7200", "21600", "43200", "86400"}) + @GlobalConfigDef(defaultValue = "0", type = Integer.class, description = "vm clock sync interval in seconds") + public static GlobalConfig VM_CLOCK_SYNC_INTERVAL_IN_SECONDS = new GlobalConfig(CATEGORY, "vm.clock.sync.interval.in.seconds"); + + @BindResourceConfig(value = {VmInstanceVO.class}) + @GlobalConfigValidation(validValues = {"true", "false"}) + @GlobalConfigDef(defaultValue = "false", type = Boolean.class, description = "sync clock after vm resume") + public static GlobalConfig VM_CLOCK_SYNC_AFTER_VM_RESUME = new GlobalConfig(CATEGORY, "vm.clock.sync.after.vm.resume"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig ENABLE_UEFI_SECURE_BOOT = new GlobalConfig(CATEGORY, "enable.uefi.secure.boot"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig ENABLE_VM_DEVICE_ADDRESS_RECORDING = new GlobalConfig(CATEGORY, "enable.vm.address.recording"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig ENABLE_VM_INTERNAL_IP_OVERWRITE = new GlobalConfig(CATEGORY, "enable.vm.internal.ip.overwrite"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig UNIQUE_VM_NAME = new GlobalConfig(CATEGORY, "uniqueVmName"); + + @BindResourceConfig(value = {VmInstanceVO.class, ClusterVO.class}) + @GlobalConfigValidation(validValues = {"true", "false"}) + @GlobalConfigDef(defaultValue = "true", type = Boolean.class, description = "vm.ha.across.clusters") + public static GlobalConfig VM_HA_ACROSS_CLUSTERS = new GlobalConfig(CATEGORY, "vm.ha.across.clusters"); + @GlobalConfigDef(defaultValue = "AuthenticAMD", type = String.class, description = "set vm cpuid vendor") + @GlobalConfigValidation(validValues = {"None", "AuthenticAMD"}) + @BindResourceConfig(value = {VmInstanceVO.class}) + public static GlobalConfig VM_CPUID_VENDOR = new GlobalConfig(CATEGORY, "vm.cpuid.vendor"); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmGlobalProperty.java b/compute/src/main/java/org/zstack/compute/vm/VmGlobalProperty.java new file mode 100644 index 00000000000..0aace3b05b1 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmGlobalProperty.java @@ -0,0 +1,19 @@ +package org.zstack.compute.vm; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +/** + * @ Author : yh.w + * @ Date : Created in 14:22 2019/9/24 + */ +@GlobalPropertyDefinition +public class VmGlobalProperty { + + @GlobalProperty(name="initRunningVmPriority", defaultValue = "false") + public static boolean initRunningVmPriority; + @GlobalProperty(name="initRunningApplianceVmPriority", defaultValue = "false") + public static boolean initRunningApplianceVmPriority; + @GlobalProperty(name="vmMacAddressSchema", defaultValue = "random") + public static String vmMacAddressSchema; +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmHardwareExtensionPoint.java b/compute/src/main/java/org/zstack/compute/vm/VmHardwareExtensionPoint.java new file mode 100644 index 00000000000..479969b46dd --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmHardwareExtensionPoint.java @@ -0,0 +1,82 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceStartExtensionPoint; +import org.zstack.header.vm.VmInstanceStartNewCreatedVmExtensionPoint; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +public class VmHardwareExtensionPoint implements VmInstanceStartExtensionPoint, VmInstanceStartNewCreatedVmExtensionPoint { + private static final CLogger logger = Utils.getLogger(VmHardwareExtensionPoint.class); + + @Autowired + private ResourceConfigFacade rcf; + + @Override + public String preStartVm(VmInstanceInventory inv) { + return verifyCpuTopology(inv); + } + + private String verifyCpuTopology(VmInstanceInventory inv) { + String sockets = VmHardwareSystemTags.CPU_SOCKETS.getTokenByResourceUuid(inv.getUuid(), VmHardwareSystemTags.CPU_SOCKETS_TOKEN); + String cores = VmHardwareSystemTags.CPU_CORES.getTokenByResourceUuid(inv.getUuid(), VmHardwareSystemTags.CPU_CORES_TOKEN); + String threads = VmHardwareSystemTags.CPU_THREADS.getTokenByResourceUuid(inv.getUuid(), VmHardwareSystemTags.CPU_THREADS_TOKEN); + + // skip if no topology + if (sockets == null && cores == null && threads == null) { + return null; + } + + Integer cpuNum = inv.getCpuNum(); + Integer maxVcpuNum = null; + Boolean isNuma = rcf.getResourceConfigValue(VmGlobalConfig.NUMA, inv.getUuid(), Boolean.class); + if (isNuma != null && isNuma) { + maxVcpuNum = rcf.getResourceConfigValue(VmGlobalConfig.VM_MAX_VCPU, inv.getUuid(), Integer.class); + } + + CpuTopology topology = new CpuTopology(maxVcpuNum != null ? maxVcpuNum : cpuNum, sockets, cores, threads); + return topology.calculateValidTopologyWithoutException(); + } + + @Override + public void beforeStartVm(VmInstanceInventory inv) { + + } + + @Override + public void afterStartVm(VmInstanceInventory inv) { + + } + + @Override + public void failedToStartVm(VmInstanceInventory inv, ErrorCode reason) { + + } + + @Override + public String preStartNewCreatedVm(VmInstanceInventory inv) { + return verifyCpuTopology(inv); + } + + @Override + public void beforeStartNewCreatedVm(VmInstanceInventory inv) { + + } + + @Override + public void afterStartNewCreatedVm(VmInstanceInventory inv) { + + } + + @Override + public void failedToStartNewCreatedVm(VmInstanceInventory inv, ErrorCode reason) { + + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmHardwareSystemTags.java b/compute/src/main/java/org/zstack/compute/vm/VmHardwareSystemTags.java new file mode 100644 index 00000000000..67c5c646f10 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmHardwareSystemTags.java @@ -0,0 +1,19 @@ +package org.zstack.compute.vm; + +import org.zstack.header.tag.TagDefinition; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.tag.PatternedSystemTag; + +@TagDefinition +public class VmHardwareSystemTags { + // cpu topology + public static String CPU_SOCKETS_TOKEN = "cpuSockets"; + public static PatternedSystemTag CPU_SOCKETS = new PatternedSystemTag( + String.format("cpuSockets::{%s}", CPU_SOCKETS_TOKEN), VmInstanceVO.class); + public static String CPU_CORES_TOKEN = "cpuCores"; + public static PatternedSystemTag CPU_CORES = new PatternedSystemTag( + String.format("cpuCores::{%s}", CPU_CORES_TOKEN), VmInstanceVO.class); + public static String CPU_THREADS_TOKEN = "cpuThreads"; + public static PatternedSystemTag CPU_THREADS = new PatternedSystemTag( + String.format("cpuThreads::{%s}", CPU_THREADS_TOKEN), VmInstanceVO.class); +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmHostNameHelper.java b/compute/src/main/java/org/zstack/compute/vm/VmHostNameHelper.java index e3da161a024..4730d07cb9b 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmHostNameHelper.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmHostNameHelper.java @@ -1,13 +1,23 @@ package org.zstack.compute.vm; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmNicInventory; import org.zstack.header.vm.VmNicVO; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmHostNameHelper { + + @Autowired + DatabaseFacade dbf; -public class VmHostNameHelper { public String getHostName(VmInstanceInventory vm) { String hostName = VmSystemTags.HOSTNAME.getTokenByResourceUuid(vm.getUuid(), VmSystemTags.HOSTNAME_TOKEN); @@ -32,7 +42,7 @@ public String getHostName(VmInstanceVO vm) { if (hostName == null) { for (VmNicVO nic : vm.getVmNics()) { if (nic.getL3NetworkUuid().equals(vm.getDefaultL3NetworkUuid()) && nic.getIp() != null) { - if (nic.getIpVersion() == IPv6Constants.IPv4) { + if (NetworkUtils.isIpv4Address(nic.getIp())) { hostName = nic.getIp().replaceAll("\\.", "-"); } else { hostName = IPv6NetworkUtils.ipv6AddessToHostname(nic.getIp()); @@ -43,4 +53,9 @@ public String getHostName(VmInstanceVO vm) { return hostName; } + + public String getHostName(String vmUuid) { + VmInstanceVO vm = dbf.findByUuid(vmUuid, VmInstanceVO.class); + return getHostName(vm); + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java index 4f5c589e3bf..098b0b5ace5 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java @@ -7,8 +7,6 @@ import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; -import org.zstack.core.db.SimpleQuery; -import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; @@ -20,12 +18,13 @@ import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.vm.VmInstanceSpec; -import org.zstack.header.vm.VmInstanceSpec.VolumeSpec; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.function.Function; import javax.persistence.TypedQuery; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; @@ -92,22 +91,24 @@ private String findBackupStorage(VmInstanceSpec spec, String imageUuid) { } private boolean imageNeedDownload(VmInstanceSpec spec, String imageUuid) { - String psUuid; + List psUuid; if (VmOperation.NewCreate == spec.getCurrentVmOperation()) { - psUuid = spec.getVolumeSpecs().isEmpty() ? spec.getRequiredPrimaryStorageUuidForRootVolume() : - spec.getVolumeSpecs().get(0).getPrimaryStorageInventory().getUuid(); + psUuid = spec.getVolumeSpecs().isEmpty() ? spec.getCandidatePrimaryStorageUuidsForRootVolume() : + Collections.singletonList(spec.getVolumeSpecs().get(0).getPrimaryStorageInventory().getUuid()); } else { - psUuid = spec.getVmInventory().getRootVolume().getPrimaryStorageUuid(); + psUuid = Collections.singletonList(spec.getVmInventory().getRootVolume().getPrimaryStorageUuid()); } - if (psUuid == null) { + if (psUuid.isEmpty()) { return true; } - SimpleQuery q = dbf.createQuery(ImageCacheVO.class); - q.add(ImageCacheVO_.imageUuid, Op.EQ, imageUuid); - q.add(ImageCacheVO_.primaryStorageUuid, Op.EQ, psUuid); - return !q.isExists(); + List hasImageCachePsUuids = Q.New(ImageCacheVO.class).eq(ImageCacheVO_.imageUuid, imageUuid) + .in(ImageCacheVO_.primaryStorageUuid, psUuid) + .select(ImageCacheVO_.primaryStorageUuid) + .listValues(); + + return new HashSet<>(hasImageCachePsUuids).size() < psUuid.size(); } @Transactional(readOnly = true) @@ -137,6 +138,11 @@ public void run(FlowTrigger trigger, Map data) { if (VmOperation.NewCreate == spec.getCurrentVmOperation() || VmOperation.ChangeImage == spec.getCurrentVmOperation()) { + if (spec.getImageSpec().getInventory() == null) { + trigger.next(); + return; + } + final String bsUuid = findBackupStorage(spec, spec.getImageSpec().getInventory().getUuid()); spec.getImageSpec().setSelectedBackupStorage(CollectionUtils.find( spec.getImageSpec().getInventory().getBackupStorageRefs(), diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java index 3b55102ac31..fe1f33f104c 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java @@ -1,8 +1,12 @@ package org.zstack.compute.vm; +import com.google.gson.JsonSyntaxException; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.Platform; +import org.zstack.compute.VmNicUtils; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.*; @@ -22,25 +26,30 @@ import org.zstack.header.image.ImageConstant.ImageMediaType; import org.zstack.header.image.*; import org.zstack.header.message.APIMessage; -import org.zstack.header.network.l2.L2NetworkClusterRefVO; -import org.zstack.header.network.l2.L2NetworkClusterRefVO_; +import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.*; import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO; import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO_; +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO; +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO_; import org.zstack.header.vm.*; import org.zstack.header.vm.cdrom.*; +import org.zstack.header.vm.devices.VmInstanceDeviceAddressGroupVO; +import org.zstack.header.vm.devices.VmInstanceDeviceAddressGroupVO_; import org.zstack.header.volume.*; import org.zstack.header.zone.ZoneState; import org.zstack.header.zone.ZoneVO; import org.zstack.header.zone.ZoneVO_; +import org.zstack.network.l3.IpRangeHelper; import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.tag.SystemTagUtils; -import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; +import org.zstack.utils.network.NicIpAddressInfo; import javax.persistence.Tuple; import javax.persistence.TypedQuery; @@ -50,6 +59,7 @@ import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; import static org.zstack.utils.CollectionDSL.list; +import static org.zstack.utils.CollectionUtils.getDuplicateElementsOfList; /** * Created with IntelliJ IDEA. @@ -93,6 +103,8 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIGetVmAttachableDataVolumeMsg) msg); } else if (msg instanceof APIDetachL3NetworkFromVmMsg) { validate((APIDetachL3NetworkFromVmMsg) msg); + } else if (msg instanceof APIChangeVmNicStateMsg) { + validate((APIChangeVmNicStateMsg) msg); } else if (msg instanceof APIAttachL3NetworkToVmMsg) { validate((APIAttachL3NetworkToVmMsg) msg); } else if (msg instanceof APIChangeVmNicNetworkMsg) { @@ -119,6 +131,8 @@ else if (msg instanceof APIAttachVmNicToVmMsg) { validate((APIStartVmInstanceMsg) msg); } else if (msg instanceof APIGetInterdependentL3NetworksImagesMsg) { validate((APIGetInterdependentL3NetworksImagesMsg) msg); + } else if (msg instanceof APIGetInterdependentL3NetworksBackupStoragesMsg) { + validate((APIGetInterdependentL3NetworksBackupStoragesMsg) msg); } else if (msg instanceof APIUpdateVmInstanceMsg) { validate((APIUpdateVmInstanceMsg) msg); } else if (msg instanceof APISetVmConsolePasswordMsg) { @@ -143,12 +157,30 @@ else if (msg instanceof APIAttachVmNicToVmMsg) { validate((APIUpdateVmNicDriverMsg) msg); } else if (msg instanceof APIGetCandidateZonesClustersHostsForCreatingVmMsg) { validate((APIGetCandidateZonesClustersHostsForCreatingVmMsg) msg); + } else if (msg instanceof APIFstrimVmMsg) { + validate((APIFstrimVmMsg) msg); + } else if (msg instanceof APITakeVmConsoleScreenshotMsg) { + validate((APITakeVmConsoleScreenshotMsg) msg); } setServiceId(msg); return msg; } + private void validate(APITakeVmConsoleScreenshotMsg msg) { + VmInstanceVO vm = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).find(); + if (!vm.getState().equals(VmInstanceState.Running)) { + throw new ApiMessageInterceptionException(operr( + "can not take vm console screenshot for vm[uuid:%s] which is not Running", msg.getVmInstanceUuid())); + } + } + + private void validate(APIGetInterdependentL3NetworksBackupStoragesMsg msg) { + if (msg.getL3NetworkUuids() == null && msg.getBackupStorageUuid() == null) { + throw new ApiMessageInterceptionException(argerr("either l3NetworkUuids or backupStorageUuid must be set")); + } + } + private void validate(APIGetCandidateL3NetworksForChangeVmNicNetworkMsg msg) { String vmUuid = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).select(VmNicVO_.vmInstanceUuid).findValue(); msg.setVmInstanceUuid(vmUuid); @@ -157,6 +189,16 @@ private void validate(APIGetCandidateL3NetworksForChangeVmNicNetworkMsg msg) { private void validate(APIChangeVmNicNetworkMsg msg) { List> networkServices = new ArrayList<>(); VmNicVO nicVO = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).find(); + + //l2 must use same vswitch + long count = SQL.New("select count(distinct l2.vSwitchType) from L2NetworkVO l2, L3NetworkVO l3 where l2.uuid = l3.l2NetworkUuid" + + " and l3.uuid in :l3Uuids") + .param("l3Uuids", Arrays.asList(nicVO.getL3NetworkUuid(), msg.getDestL3NetworkUuid())) + .find(); + if (count > 1) { + throw new ApiMessageInterceptionException(operr("could not change to L3 network, the l2 of l3[uuid:%s, %s] use different vswitch", + nicVO.getL3NetworkUuid(), msg.getDestL3NetworkUuid())); + } for (VmNicChangeNetworkExtensionPoint extension : pluginRgty.getExtensionList(VmNicChangeNetworkExtensionPoint.class)) { Map ret = extension.getVmNicAttachedNetworkService(VmNicInventory.valueOf(nicVO)); if (ret == null) { @@ -180,13 +222,13 @@ private void validate(APIChangeVmNicNetworkMsg msg) { String srcL3Uuid = t.get(3, String.class); msg.setVmInstanceUuid(vmUuid); - if (!VmInstanceState.Stopped.equals(state)) { - throw new ApiMessageInterceptionException(operr("unable to change to L3 network. The vm[uuid: %s] is not Stopped; the current state is %s", + if (!VmInstanceState.Stopped.equals(state) && !VmInstanceState.Running.equals(state)) { + throw new ApiMessageInterceptionException(operr("unable to change to L3 network. The vm[uuid: %s] is not Running or Stopped; the current state is %s", msg.getVmInstanceUuid(), state)); } L3NetworkVO l3NetworkVO = dbf.findByUuid(msg.getDestL3NetworkUuid(), L3NetworkVO.class); - if (l3NetworkVO.getIpRanges().isEmpty()) { + if (l3NetworkVO.enableIpAddressAllocation() && l3NetworkVO.getIpRanges().isEmpty()) { throw new ApiMessageInterceptionException(operr("unable to change to L3 network. The L3 network[uuid:%s] doesn't has have ip range", msg.getDestL3NetworkUuid())); } @@ -239,6 +281,7 @@ private void validate(APIChangeVmNicNetworkMsg msg) { } } + new StaticIpOperator().validateSystemTagInApiMessage(msg); Map> staticIps = new StaticIpOperator().getStaticIpbySystemTag(msg.getSystemTags()); if (msg.getRequiredIpMap() != null) { staticIps.computeIfAbsent(msg.getDestL3NetworkUuid(), k -> new ArrayList<>()).add(msg.getStaticIp()); @@ -258,6 +301,10 @@ private void validate(APIChangeVmNicNetworkMsg msg) { } } + if (!l3NetworkVO.enableIpAddressAllocation()) { + found = true; + } + if (!found) { throw new ApiMessageInterceptionException(argerr("the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", msg.getStaticIp(), msg.getDestL3NetworkUuid())); } @@ -297,6 +344,10 @@ private void validate(APIChangeVmNicNetworkMsg msg) { } } + if (!l3NetworkVO.enableIpAddressAllocation()) { + found = true; + } + if (!found) { throw new ApiMessageInterceptionException(argerr("the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", staticIp, l3Uuid)); } @@ -315,6 +366,17 @@ private void validate(APIChangeVmNicNetworkMsg msg) { for (Map.Entry> e : staticIps.entrySet()) { msg.getRequiredIpMap().put(e.getKey(), e.getValue()); } + + final Map nicNetworkInfo = new StaticIpOperator().getNicNetworkInfoBySystemTag(msg.getSystemTags()); + NicIpAddressInfo nicIpAddressInfo = nicNetworkInfo.get(msg.getDestL3NetworkUuid()); + if (nicIpAddressInfo != null) { + if (!nicIpAddressInfo.ipv4Address.isEmpty() && Q.New(UsedIpVO.class).eq(UsedIpVO_.ip, nicIpAddressInfo.ipv4Address).eq(UsedIpVO_.l3NetworkUuid, msg.getDestL3NetworkUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("the static IP[%s] has been occupied on the L3 network[uuid:%s]", nicIpAddressInfo.ipv4Address, msg.getDestL3NetworkUuid())); + } + if (!nicIpAddressInfo.ipv6Address.isEmpty() && Q.New(UsedIpVO.class).eq(UsedIpVO_.ip, IPv6NetworkUtils.getIpv6AddressCanonicalString(nicIpAddressInfo.ipv6Address)).eq(UsedIpVO_.l3NetworkUuid, msg.getDestL3NetworkUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("the static IP[%s] has been occupied on the L3 network[uuid:%s]", nicIpAddressInfo.ipv6Address, msg.getDestL3NetworkUuid())); + } + } } private void validate(APIGetCandidateZonesClustersHostsForCreatingVmMsg msg) { @@ -380,6 +442,11 @@ protected void scripts() { "the vm[uuid:%s] is already on host[uuid:%s]", msg.getVmInstanceUuid(), msg.getHostUuid() )); } + + if (vo.getState() == VmInstanceState.Paused && VmSystemTags.VM_STATE_PAUSED_AFTER_MIGRATE.hasTag(msg.getVmInstanceUuid())) { + throw new ApiMessageInterceptionException(argerr( + "the vm[uuid:%s] is still paused after the last migration, please resume it before migrate.", msg.getVmInstanceUuid())); + } } }.execute(); } @@ -394,7 +461,7 @@ protected void scripts() { boolean numa = rcf.getResourceConfigValue(VmGlobalConfig.NUMA, msg.getVmInstanceUuid(), Boolean.class); if (!numa && !VmInstanceState.Stopped.equals(vo.getState())) { throw new ApiMessageInterceptionException(argerr( - "the VM cannot do online cpu/memory update because it is not of NUMA architecture. Please stop the VM then do the cpu/memory update again" + "the VM cannot do online cpu/memory update because of disabling Instance Offering Online Modification. Please stop the VM then do the cpu/memory update again" )); } @@ -422,19 +489,43 @@ private void validate(APIUpdateVmInstanceMsg msg) { new SQLBatch() { @Override protected void scripts() { - VmInstanceVO vo = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).find(); - Integer cpuSum = msg.getCpuNum(); - Long memorySize = msg.getMemorySize(); - if ((cpuSum == null && memorySize == null)) { + VmInstanceVO vo = q(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).find(); + if (msg.getReservedMemorySize() != null) { + Long memorySize = msg.getMemorySize() == null ? vo.getMemorySize() : msg.getMemorySize(); + if (msg.getReservedMemorySize() > memorySize) { + throw new ApiMessageInterceptionException(argerr( + "reservedMemorySize[%s] is greater than memorySize[%s]", msg.getReservedMemorySize(), memorySize + )); + } + } + + if (msg.getCpuNum() == null && msg.getMemorySize() == null) { return; } - VmInstanceState vmState = Q.New(VmInstanceVO.class).select(VmInstanceVO_.state).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).findValue(); + boolean uniqueVmName = VmGlobalConfig.UNIQUE_VM_NAME.value(Boolean.class); + if (uniqueVmName && Q.New(VmInstanceVO.class).eq(VmInstanceVO_.name, msg.getName()).notEq(VmInstanceVO_.uuid, msg.getUuid()).isExists()) { + throw new ApiMessageInterceptionException(operr("could not create vm, a vm with the name [%s] already exists", + msg.getName())); + } + + Integer cpuSum = msg.getCpuNum(); + Long memorySize = msg.getMemorySize(); + + VmInstanceState vmState = q(VmInstanceVO.class).select(VmInstanceVO_.state).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).findValue(); boolean numa = rcf.getResourceConfigValue(VmGlobalConfig.NUMA, msg.getUuid(), Boolean.class); if (!numa && !VmInstanceState.Stopped.equals(vmState)) { - throw new ApiMessageInterceptionException(argerr( - "the VM cannot do online cpu/memory update because it is not of NUMA architecture. Please stop the VM then do the cpu/memory update again" - )); + if (cpuSum != null && cpuSum != vo.getCpuNum()) { + throw new ApiMessageInterceptionException(argerr( + "the VM cannot do cpu hot plug because of disabling cpu hot plug. Please stop the VM then do the cpu hot plug again" + )); + } + + if (memorySize != null && memorySize != vo.getMemorySize()) { + throw new ApiMessageInterceptionException(argerr( + "the VM cannot do memory hot plug because of disabling memory hot plug. Please stop the VM then do the memory hot plug again" + )); + } } if (!VmInstanceState.Stopped.equals(vo.getState()) && !VmInstanceState.Running.equals(vo.getState())) { @@ -443,7 +534,6 @@ protected void scripts() { StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), ","))); } - if (VmInstanceState.Stopped.equals(vmState)) { return; } @@ -465,11 +555,6 @@ protected void scripts() { private void validate(APIGetInterdependentL3NetworksImagesMsg msg) { - if (msg.getL3NetworkUuids() == null && msg.getImageUuid() == null) { - throw new ApiMessageInterceptionException(argerr( - "either l3NetworkUuids or imageUuid must be set" - )); - } } private void validate(APIStartVmInstanceMsg msg) { @@ -490,11 +575,15 @@ private void validateStaticIPv4(VmNicVO vmNicVO, L3NetworkVO l3NetworkVO, String } if (ipVo.getL3NetworkUuid().equals(l3NetworkVO.getUuid())) { - NormalIpRangeVO rangeVO = dbf.findByUuid(ipVo.getIpRangeUuid(), NormalIpRangeVO.class); if (ipVo.getIp().equals(ip)) { throw new ApiMessageInterceptionException(argerr("ip address [%s] already set to vmNic [uuid:%s]", ip, vmNicVO.getUuid())); } + if (!l3NetworkVO.enableIpAddressAllocation()) { + continue; + } + // check if the ip is in the ip range when ipam is enabled + NormalIpRangeVO rangeVO = dbf.findByUuid(ipVo.getIpRangeUuid(), NormalIpRangeVO.class); if (!NetworkUtils.isIpv4InCidr(ip, rangeVO.getNetworkCidr())) { throw new ApiMessageInterceptionException(argerr("ip address [%s] is not in ip range [%s]", ip, rangeVO.getNetworkCidr())); @@ -518,6 +607,9 @@ private void validateStaticIPv6(VmNicVO vmNicVO, L3NetworkVO l3NetworkVO, String throw new ApiMessageInterceptionException(argerr("ip address [%s] already set to vmNic [uuid:%s]", ip, vmNicVO.getUuid())); } + if (!l3NetworkVO.enableIpAddressAllocation()) { + continue; + } NormalIpRangeVO rangeVO = dbf.findByUuid(ipVo.getIpRangeUuid(), NormalIpRangeVO.class); if (!IPv6NetworkUtils.isIpv6InRange(ip, rangeVO.getStartIp(), rangeVO.getEndIp())) { throw new ApiMessageInterceptionException(argerr("ip address [%s] is not in ip range [startIp %s, endIp %s]", @@ -528,35 +620,78 @@ private void validateStaticIPv6(VmNicVO vmNicVO, L3NetworkVO l3NetworkVO, String } private void validate(APISetVmStaticIpMsg msg) { + L3NetworkVO l3NetworkVO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); if (msg.getIp() == null && msg.getIp6() == null) { - throw new ApiMessageInterceptionException(argerr("could not set ip address, due to no ip address is specified")); + if(l3NetworkVO.enableIpAddressAllocation()) { + throw new ApiMessageInterceptionException(argerr("could not set ip address, due to no ip address is specified")); + } } - - L3NetworkVO l3NetworkVO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + List ipv4Ranges = Q.New(NormalIpRangeVO.class) + .eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv4).list(); + List ipv6Ranges = Q.New(NormalIpRangeVO.class) + .eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); List vmNics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, msg.getVmInstanceUuid()).list(); boolean l3Found = false; for (VmNicVO nic : vmNics) { - for (UsedIpVO ipvo: nic.getUsedIps()) { - if (ipvo.getL3NetworkUuid().equals(msg.getL3NetworkUuid())) { - l3Found = true; - if (msg.getIp() != null) { - String ip = IPv6NetworkUtils.ipv6TagValueToAddress(msg.getIp()); - if (NetworkUtils.isIpv4Address(ip)) { - validateStaticIPv4(nic, l3NetworkVO, ip); - } else if (IPv6NetworkUtils.isIpv6Address(ip)) { - validateStaticIPv6(nic, l3NetworkVO, ip); - msg.setIp(ip); - } else { - throw new ApiMessageInterceptionException(argerr("static ip [%s] format error", msg.getIp())); - } - } - if (msg.getIp6() != null) { - String ip6 = IPv6NetworkUtils.ipv6TagValueToAddress(msg.getIp6()); - validateStaticIPv6(nic, l3NetworkVO, ip6); - msg.setIp6(ip6); - } + l3Found = true; + if (msg.getIp() != null) { + String ip = IPv6NetworkUtils.ipv6TagValueToAddress(msg.getIp()); + if (NetworkUtils.isIpv4Address(ip)) { + validateStaticIPv4(nic, l3NetworkVO, ip); + } else if (IPv6NetworkUtils.isIpv6Address(ip)) { + validateStaticIPv6(nic, l3NetworkVO, ip); + msg.setIp(ip); + } else { + throw new ApiMessageInterceptionException(argerr("static ip [%s] format error", msg.getIp())); + } + } + if (msg.getIp6() != null) { + String ip6 = IPv6NetworkUtils.ipv6TagValueToAddress(msg.getIp6()); + validateStaticIPv6(nic, l3NetworkVO, ip6); + msg.setIp6(ip6); + } + } + if (msg.getIp() != null && !l3NetworkVO.enableIpAddressAllocation()) { + l3Found = true; + if (msg.getNetmask() == null) { + if (ipv4Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("ipv4 address need a netmask")); + } else { + msg.setNetmask(ipv4Ranges.get(0).getNetmask()); + } + } + if (msg.getGateway() == null) { + if (ipv4Ranges.isEmpty()) { + msg.setGateway(""); + } else { + msg.setGateway(ipv4Ranges.get(0).getGateway()); + } + } + if (Q.New(UsedIpVO.class).eq(UsedIpVO_.ip, msg.getIp()).eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("ip address [%s] already set to vmNic", msg.getIp())); + } + } + if (msg.getIp6() != null && !l3NetworkVO.enableIpAddressAllocation()) { + l3Found = true; + if (msg.getIpv6Prefix() == null) { + if (ipv6Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("ipv6 address need a prefix")); + } else { + msg.setIpv6Prefix(ipv6Ranges.get(0).getPrefixLen().toString()); + } + } + if (msg.getIpv6Gateway() == null) { + if (ipv6Ranges.isEmpty()) { + msg.setIpv6Gateway(""); + } else { + msg.setIpv6Gateway(ipv6Ranges.get(0).getGateway()); } } + if (Q.New(UsedIpVO.class).eq(UsedIpVO_.ip, msg.getIp6()).eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("ip address [%s] already set to vmNic", msg.getIp6())); + } } if (!l3Found) { throw new ApiMessageInterceptionException(argerr("the VM[uuid:%s] has no nic on the L3 network[uuid:%s]", msg.getVmInstanceUuid(), @@ -594,16 +729,34 @@ private void validate(APISetVmBootOrderMsg msg) { } } + private boolean isVmHasMemorySnapshotGroup(String vmUuid) { + List snapShotGroupUuids = Q.New(VmInstanceDeviceAddressGroupVO.class) + .select(VmInstanceDeviceAddressGroupVO_.resourceUuid) + .eq(VmInstanceDeviceAddressGroupVO_.vmInstanceUuid, vmUuid) + .listValues(); + if (snapShotGroupUuids.isEmpty()) { + return false; + } + return Q.New(VolumeSnapshotGroupVO.class) + .eq(VolumeSnapshotGroupVO_.vmInstanceUuid, vmUuid) + .in(VolumeSnapshotGroupVO_.uuid, snapShotGroupUuids) + .isExists(); + } + private void validate(APISetVmBootVolumeMsg msg) { VolumeVO volume = Q.New(VolumeVO.class).eq(VolumeVO_.uuid, msg.getVolumeUuid()).find(); if (volume.isShareable()) { throw new ApiMessageInterceptionException(argerr("boot volume cannot be shareable.")); } - if (!volume.getVmInstanceUuid().equals(msg.getVmInstanceUuid())) { + if (!msg.getVmInstanceUuid().equals(volume.getVmInstanceUuid())) { throw new ApiMessageInterceptionException(argerr("volume[uuid:%s] must be attached to vm[uuid:%s]", msg.getVolumeUuid(), msg.getVmInstanceUuid())); } + + if (isVmHasMemorySnapshotGroup(msg.getVmInstanceUuid())) { + throw new ApiMessageInterceptionException(argerr("the vm %s with memory snapshots do not support setting boot volume", msg.getVmInstanceUuid())); + } } @@ -661,13 +814,8 @@ private void validate(APIDetachIsoFromVmInstanceMsg msg) { } private void validate(APICreateVmNicMsg msg) { - SimpleQuery l3q = dbf.createQuery(L3NetworkVO.class); - l3q.select(L3NetworkVO_.state, L3NetworkVO_.system, L3NetworkVO_.category, L3NetworkVO_.type); - l3q.add(L3NetworkVO_.uuid, Op.EQ, msg.getL3NetworkUuid()); - Tuple t = l3q.findTuple(); - L3NetworkState l3state = t.get(0, L3NetworkState.class); - - if (l3state == L3NetworkState.Disabled) { + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + if (l3VO.getState() == L3NetworkState.Disabled) { throw new ApiMessageInterceptionException(operr("unable to attach a L3 network. The L3 network[uuid:%s] is disabled", msg.getL3NetworkUuid())); } @@ -684,6 +832,10 @@ private void validate(APICreateVmNicMsg msg) { } } + if (!l3VO.enableIpAddressAllocation()) { + found = true; + } + if (!found) { throw new ApiMessageInterceptionException(argerr("the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", msg.getIp(), msg.getL3NetworkUuid())); } @@ -711,7 +863,7 @@ private void validate(APIAttachL3NetworkToVmMsg msg) { } L3NetworkVO l3NetworkVO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); - if (l3NetworkVO.getIpRanges().isEmpty()) { + if (l3NetworkVO.getIpRanges().isEmpty() && l3NetworkVO.enableIpAddressAllocation()) { throw new ApiMessageInterceptionException(operr("unable to attach a L3 network. The L3 network[uuid:%s] doesn't has have ip range", msg.getL3NetworkUuid())); } @@ -726,14 +878,21 @@ private void validate(APIAttachL3NetworkToVmMsg msg) { newAddedL3Uuids, l2Uuids)); } - List clusterUuids = Q.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2Uuids.get(0)) - .select(L2NetworkClusterRefVO_.clusterUuid).listValues(); - if (clusterUuids.isEmpty()) { - throw new ApiMessageInterceptionException(operr("unable to attach a L3 network. The L3 network[uuid:%s] are belonged to l2 networks [uuids:%s] that have not been attached to any cluster", - newAddedL3Uuids, l2Uuids)); + List l2NetworkVOS = Q.New(L2NetworkVO.class).in(L2NetworkVO_.uuid, l2Uuids).list(); + List ovnL2Networks = l2NetworkVOS.stream().filter(vo -> + vo.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVN_DPDK)).collect(Collectors.toList()); + l2NetworkVOS = l2NetworkVOS.stream().filter(vo -> + !vo.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVN_DPDK)).collect(Collectors.toList()); + if (!l2NetworkVOS.isEmpty()) { + List clusterUuids = Q.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2Uuids.get(0)) + .select(L2NetworkClusterRefVO_.clusterUuid).listValues(); + if (clusterUuids.isEmpty()) { + throw new ApiMessageInterceptionException(operr("unable to attach a L3 network. The L3 network[uuid:%s] are belonged to l2 networks [uuids:%s] that have not been attached to any cluster", + newAddedL3Uuids, l2Uuids)); + } } - String sql = "select ip.l3NetworkUuid from UsedIpVO ip, VmNicVO nic where ip.vmNicUuid = nic.uuid and nic.vmInstanceUuid = :vmUuid and ip.l3NetworkUuid in (:l3Uuids)"; + String sql = "select nic.l3NetworkUuid from VmNicVO nic where nic.vmInstanceUuid = :vmUuid and nic.l3NetworkUuid in (:l3Uuids)"; List attachedL3Uuids = SQL.New(sql, String.class) .param("vmUuid", msg.getVmInstanceUuid()) .param("l3Uuids", newAddedL3Uuids) @@ -764,7 +923,12 @@ private void validate(APIAttachL3NetworkToVmMsg msg) { } } + new StaticIpOperator().validateSystemTagInApiMessage(msg); Map> staticIps = new StaticIpOperator().getStaticIpbySystemTag(msg.getSystemTags()); + msg.setNicNetworkInfo(new StaticIpOperator().getNicNetworkInfoBySystemTag(msg.getSystemTags()).entrySet() + .stream() + .filter(entry -> !IpRangeHelper.isIpAddressAllocationEnableOnL3(entry.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); if (msg.getStaticIp() != null) { staticIps.computeIfAbsent(msg.getL3NetworkUuid(), k -> new ArrayList<>()).add(msg.getStaticIp()); SimpleQuery iprq = dbf.createQuery(NormalIpRangeVO.class); @@ -783,6 +947,10 @@ private void validate(APIAttachL3NetworkToVmMsg msg) { } } + if (!l3NetworkVO.enableIpAddressAllocation()) { + found = true; + } + if (!found) { throw new ApiMessageInterceptionException(argerr("the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", msg.getStaticIp(), msg.getL3NetworkUuid())); } @@ -822,13 +990,17 @@ private void validate(APIAttachL3NetworkToVmMsg msg) { } } + if (!l3NetworkVO.enableIpAddressAllocation()) { + found = true; + } + if (!found) { throw new ApiMessageInterceptionException(argerr("the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", staticIp, l3Uuid)); } SimpleQuery uq = dbf.createQuery(UsedIpVO.class); uq.add(UsedIpVO_.l3NetworkUuid, Op.EQ, msg.getL3NetworkUuid()); - uq.add(UsedIpVO_.ip, Op.EQ, msg.getStaticIp()); + uq.add(UsedIpVO_.ip, Op.EQ, staticIp); if (uq.isExists()) { throw new ApiMessageInterceptionException(operr("the static IP[%s] has been occupied on the L3 network[uuid:%s]", staticIp, l3Uuid)); } @@ -846,6 +1018,19 @@ private void validate(APIAttachL3NetworkToVmMsg msg) { for (Map.Entry> e : staticIps.entrySet()) { msg.getStaticIpMap().put(e.getKey(), e.getValue()); } + + if (!StringUtils.isEmpty(msg.getVmNicParams())) { + List supportNicDriverTypes = nicManager.getSupportNicDriverTypes(); + + VmNicParam vmNicParam; + try { + vmNicParam = JSONObjectUtil.toObject(msg.getVmNicParams(), VmNicParam.class); + } catch (JsonSyntaxException e) { + throw new OperationFailureException(operr("invalid json format, causes: %s", e.getMessage())); + } + + VmNicUtils.validateVmParms(Arrays.asList(vmNicParam), Arrays.asList(msg.getL3NetworkUuid()), supportNicDriverTypes); + } } private void validate(APIAttachVmNicToVmMsg msg) { @@ -901,6 +1086,25 @@ private void validate(APIAttachVmNicToVmMsg msg) { } } + @Transactional(readOnly = true) + private void validate(APIChangeVmNicStateMsg msg) { + VmNicVO nicVO = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).find(); + if (msg.getState().equals(VmNicState.enable.toString()) && !msg.getState().equals(nicVO.getState().toString())) { + MacOperator mo = new MacOperator(); + if (mo.checkDuplicateMac(nicVO.getHypervisorType(), nicVO.getL3NetworkUuid(), + nicVO.getMac())) { + throw new ApiMessageInterceptionException(Platform.argerr("Duplicate mac address [%s]", nicVO.getMac())); + } + } + + if (!nicVO.getType().equals(VmInstanceConstant.VIRTUAL_NIC_TYPE)) { + throw new ApiMessageInterceptionException(operr("could not update nic[uuid: %s] state, due to nic type[%s] not support", + msg.getVmNicUuid(), nicVO.getType())); + } + msg.setVmInstanceUuid(nicVO.getVmInstanceUuid()); + msg.l3Uuid = nicVO.getL3NetworkUuid(); + } + @Transactional(readOnly = true) private void validate(APIDetachL3NetworkFromVmMsg msg) { String sql = "select vm.uuid, vm.state from VmInstanceVO vm, VmNicVO nic where vm.uuid = nic.vmInstanceUuid and nic.uuid = :uuid"; @@ -963,63 +1167,112 @@ private void validatePsWhetherSameCluster(APICreateVmInstanceMsg msg) { } } - private void validateInstanceSettings(NewVmInstanceMessage2 msg) { - final String instanceOfferingUuid = msg.getInstanceOfferingUuid(); + private void validateZoneOrClusterOrHostOrL3Exist(NewVmInstanceMessage2 msg) { + if (CollectionUtils.isEmpty(msg.getL3NetworkUuids()) && StringUtils.isEmpty(msg.getZoneUuid()) + && StringUtils.isEmpty(msg.getClusterUuid()) && StringUtils.isEmpty(msg.getHostUuid())) { + throw new ApiMessageInterceptionException(operr("could not create vm, because at least one of field (l3NetworkUuids,zoneUuid,clusterUuid,hostUuid) should be set")); + } + } - if (instanceOfferingUuid == null) { - if (msg.getCpuNum() == null || msg.getMemorySize() == null) { - throw new ApiMessageInterceptionException(operr("Missing CPU/memory settings")); + private void validateDataDiskSizes(APICreateVmInstanceMsg msg) throws ApiMessageInterceptionException { + if (CollectionUtils.isEmpty(msg.getDataDiskSizes())) { + return; + } + msg.getDataDiskSizes().forEach(dataDiskSize -> { + if (dataDiskSize <= 0) { + throw new ApiMessageInterceptionException(operr("Unexpected data disk settings. dataDiskSizes need to be greater than 0")); } + }); + } - if (msg.getCpuNum() <= 0 || msg.getMemorySize() <= 0) { - throw new ApiMessageInterceptionException(operr("Unexpected CPU/memory settings")); - } + private void validate(APICreateVmInstanceMsg msg) { + validate((NewVmInstanceMessage2) msg); - return; + if (CollectionUtils.isNotEmpty(msg.getDiskAOs())) { + APICreateVmInstanceMsg.DiskAO rootDiskAO = msg.getDiskAOs().stream() + .filter(APICreateVmInstanceMsg.DiskAO::isBoot).findFirst().orElse(null); + if (rootDiskAO == null) { + throw new ApiMessageInterceptionException(argerr("missing root disk")); + } + msg.setPlatform(rootDiskAO.getPlatform()); + msg.setGuestOsType(rootDiskAO.getGuestOsType()); + msg.setArchitecture(rootDiskAO.getArchitecture()); + if (CollectionUtils.isNotEmpty(rootDiskAO.getSystemTags())) { + if (rootDiskAO.getSystemTags().contains(VmSystemTags.VIRTIO.getTagFormat())) { + msg.setVirtio(true); + } + } else { + msg.setVirtio(false); + } } - // InstanceOffering takes precedence over CPU/memory settings. - InstanceOfferingVO ivo = dbf.findByUuid(instanceOfferingUuid, InstanceOfferingVO.class); - if (ivo.getState() == InstanceOfferingState.Disabled) { - throw new ApiMessageInterceptionException(operr("instance offering[uuid:%s] is Disabled, can't create vm from it", instanceOfferingUuid)); - } + ImageVO image = Q.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).find(); + if (image == null) { + String err = ""; + if (msg.getPlatform() == null) { + err = Platform.missingVariables("platform"); + } - if (!ivo.getType().equals(VmInstanceConstant.USER_VM_TYPE)){ - throw new ApiMessageInterceptionException(operr("instance offering[uuid:%s, type:%s] is not UserVm type, can't create vm from it", instanceOfferingUuid, ivo.getType())); - } + if (msg.getGuestOsType() == null) { + err += Platform.missingVariables("guestOsType"); + } - msg.setCpuNum(ivo.getCpuNum()); - msg.setMemorySize(ivo.getMemorySize()); - } + if (msg.getArchitecture() == null) { + err += Platform.missingVariables("architecture"); + } - private void validate(APICreateVmInstanceMsg msg) { - validate((NewVmInstanceMessage2) msg); + if (msg.getRootDiskOfferingUuid() == null && msg.getRootDiskSize() == null) { + err += "rootDiskOfferingUuid or rootDiskSize cannot be all null"; + } - SimpleQuery imgq = dbf.createQuery(ImageVO.class); - imgq.select(ImageVO_.state, ImageVO_.system, ImageVO_.mediaType, ImageVO_.status); - imgq.add(ImageVO_.uuid, Op.EQ, msg.getImageUuid()); - Tuple imgt = imgq.findTuple(); - ImageState imgState = imgt.get(0, ImageState.class); - if (imgState == ImageState.Disabled) { - throw new ApiMessageInterceptionException(operr("image[uuid:%s] is Disabled, can't create vm from it", msg.getImageUuid())); - } + if (!err.isEmpty()) { + throw new ApiMessageInterceptionException(argerr(String.format("when imageUuid is null, %s", err))); + } + } else { + ImageState imgState = image.getState(); + if (imgState == ImageState.Disabled) { + throw new ApiMessageInterceptionException(operr("image[uuid:%s] is Disabled, can't create vm from it", msg.getImageUuid())); + } - ImageStatus imgStatus = imgt.get(3, ImageStatus.class); - if (imgStatus != ImageStatus.Ready) { - throw new ApiMessageInterceptionException(operr("image[uuid:%s] is not ready yet, can't create vm from it", msg.getImageUuid())); - } + ImageStatus imgStatus = image.getStatus(); + if (imgStatus != ImageStatus.Ready) { + throw new ApiMessageInterceptionException(operr("image[uuid:%s] is not ready yet, can't create vm from it", msg.getImageUuid())); + } - ImageMediaType imgFormat = imgt.get(2, ImageMediaType.class); - if (imgFormat != ImageMediaType.RootVolumeTemplate && imgFormat != ImageMediaType.ISO) { - throw new ApiMessageInterceptionException(argerr("image[uuid:%s] is of mediaType: %s, only RootVolumeTemplate and ISO can be used to create vm", msg.getImageUuid(), imgFormat)); - } + ImageMediaType imgFormat = image.getMediaType(); + if (imgFormat != ImageMediaType.RootVolumeTemplate && imgFormat != ImageMediaType.ISO) { + throw new ApiMessageInterceptionException(argerr("image[uuid:%s] is of mediaType: %s, only RootVolumeTemplate and ISO can be used to create vm", msg.getImageUuid(), imgFormat)); + } + + boolean isSystemImage = image.isSystem(); + if (isSystemImage && (msg.getType() == null || VmInstanceConstant.USER_VM_TYPE.equals(msg.getType()))) { + throw new ApiMessageInterceptionException(argerr("image[uuid:%s] is system image, can't be used to create user vm", msg.getImageUuid())); + } + + if (msg.getPlatform() == null && image.getPlatform() == null) { + throw new ApiMessageInterceptionException(operr("at least one of field platform in msg or image[uuid:%s] should be set", msg.getImageUuid())); + } + + if (msg.getGuestOsType() == null && image.getGuestOsType() == null) { + throw new ApiMessageInterceptionException(operr("at least one of field guestOsType in msg or image[uuid:%s] should be set", msg.getImageUuid())); + } + + if (msg.getArchitecture() == null && image.getArchitecture() == null) { + throw new ApiMessageInterceptionException(operr("at least one of field architecture in msg or image[uuid:%s] should be set", msg.getImageUuid())); + } - boolean isSystemImage = imgt.get(1, Boolean.class); - if (isSystemImage && (msg.getType() == null || VmInstanceConstant.USER_VM_TYPE.equals(msg.getType()))) { - throw new ApiMessageInterceptionException(argerr("image[uuid:%s] is system image, can't be used to create user vm", msg.getImageUuid())); + validateRootDiskOffering(imgFormat, msg); + + if (msg.getVirtio() == null) { + if (image.getVirtio() != null) { + msg.setVirtio(image.getVirtio()); + } else { + msg.setVirtio(false); + } + } } - validateRootDiskOffering(imgFormat, msg); + validateDataDiskSizes(msg); List allDiskOfferingUuids = new ArrayList(); if (msg.getRootDiskOfferingUuid() != null) { @@ -1041,6 +1294,47 @@ private void validate(APICreateVmInstanceMsg msg) { } validatePsWhetherSameCluster(msg); + validateDataDiskAOs(msg); + } + + private void validateDataDiskAOs(APICreateVmInstanceMsg msg) { + if (CollectionUtils.isEmpty(msg.getDiskAOs())) { + return; + } + for (APICreateVmInstanceMsg.DiskAO diskAO : msg.getDiskAOs()) { + if (diskAO.isBoot()) { + continue; + } + checkMutualExclusion(diskAO); + } + } + + public void checkMutualExclusion(APICreateVmInstanceMsg.DiskAO diskAO) { + Map map = new HashMap<>(); + map.put("size", diskAO.getSize() > 0); + map.put("templateUuid", diskAO.getTemplateUuid() != null); + map.put("diskOfferingUuid", diskAO.getDiskOfferingUuid() != null); + map.put("sourceUuid", diskAO.getSourceUuid() != null); + int count = 0; + StringBuilder errorMsg = new StringBuilder(); + for (Map.Entry entry : map.entrySet()) { + if (entry.getValue()) { + count++; + errorMsg.append(entry.getKey()).append(", "); + } + } + + if (count > 1) { + throw new ApiMessageInterceptionException(operr("Cannot set the following properties at the same time: %s", errorMsg)); + } + + if (count == 0) { + StringJoiner properties = new StringJoiner(", "); + for (String key : map.keySet()) { + properties.add(key); + } + throw new ApiMessageInterceptionException(operr("Need to set one of the following properties, and can only be one of them: %s", properties)); + } } private void validate(APICreateVmInstanceFromVolumeMsg msg) { @@ -1069,7 +1363,13 @@ private void validate(APICreateVmInstanceFromVolumeSnapshotGroupMsg msg) { } private void validate(NewVmInstanceMessage2 msg) { - validateInstanceSettings(msg); + VmInstanceUtils.validateInstanceSettings(msg); + + boolean uniqueVmName = VmGlobalConfig.UNIQUE_VM_NAME.value(Boolean.class); + if (uniqueVmName && Q.New(VmInstanceVO.class).eq(VmInstanceVO_.name, msg.getName()).isExists()) { + throw new ApiMessageInterceptionException(operr("could not create vm, a vm with the name [%s] already exists", + msg.getName())); + } Set macs = new HashSet<>(); if (null != msg.getSystemTags()) { @@ -1084,25 +1384,43 @@ private void validate(NewVmInstanceMessage2 msg) { } } - SimpleQuery l3q = dbf.createQuery(L3NetworkVO.class); - l3q.select(L3NetworkVO_.uuid, L3NetworkVO_.system, L3NetworkVO_.state); - List uuids = new ArrayList<>(msg.getL3NetworkUuids()); - List duplicateElements = CollectionUtils.getDuplicateElementsOfList(uuids); - if (duplicateElements.size() > 0) { - throw new ApiMessageInterceptionException(operr("Can't add same uuid in the l3Network,uuid: %s", duplicateElements.get(0))); + if (msg.getVmNicParams() != null && !msg.getVmNicParams().isEmpty()) { + List supportNicDriverTypes = nicManager.getSupportNicDriverTypes(); + if (msg.getL3NetworkUuids() == null || msg.getL3NetworkUuids().isEmpty()) { + throw new ApiMessageInterceptionException(argerr("l3NetworkUuids and vmNicInventories mustn't both be empty or both be set")); + } + + List vmNicInventories; + try { + vmNicInventories = JSONObjectUtil.toCollection(msg.getVmNicParams(), ArrayList.class, VmNicParam.class); + } catch (JsonSyntaxException e) { + throw new OperationFailureException(operr("invalid json format, causes: %s", e.getMessage())); + } + + VmNicUtils.validateVmParms(vmNicInventories, msg.getL3NetworkUuids(), supportNicDriverTypes); } - l3q.add(L3NetworkVO_.uuid, Op.IN, msg.getL3NetworkUuids()); - List l3ts = l3q.listTuple(); - for (Tuple t : l3ts) { - String l3Uuid = t.get(0, String.class); - Boolean system = t.get(1, Boolean.class); - L3NetworkState state = t.get(2, L3NetworkState.class); - if (state != L3NetworkState.Enabled) { - throw new ApiMessageInterceptionException(operr("l3Network[uuid:%s] is Disabled, can not create vm on it", l3Uuid)); + if (!CollectionUtils.isEmpty(msg.getL3NetworkUuids())) { + SimpleQuery l3q = dbf.createQuery(L3NetworkVO.class); + l3q.select(L3NetworkVO_.uuid, L3NetworkVO_.system, L3NetworkVO_.state); + List uuids = new ArrayList<>(msg.getL3NetworkUuids()); + List duplicateElements = getDuplicateElementsOfList(uuids); + if (duplicateElements.size() > 0) { + throw new ApiMessageInterceptionException(operr("Can't add same uuid in the l3Network,uuid: %s", duplicateElements.get(0))); } - if (system && (msg.getType() == null || VmInstanceConstant.USER_VM_TYPE.equals(msg.getType()))) { - throw new ApiMessageInterceptionException(operr("l3Network[uuid:%s] is system network, can not create user vm on it", l3Uuid)); + + l3q.add(L3NetworkVO_.uuid, Op.IN, msg.getL3NetworkUuids()); + List l3ts = l3q.listTuple(); + for (Tuple t : l3ts) { + String l3Uuid = t.get(0, String.class); + Boolean system = t.get(1, Boolean.class); + L3NetworkState state = t.get(2, L3NetworkState.class); + if (state != L3NetworkState.Enabled) { + throw new ApiMessageInterceptionException(operr("l3Network[uuid:%s] is Disabled, can not create vm on it", l3Uuid)); + } + if (system && (msg.getType() == null || VmInstanceConstant.USER_VM_TYPE.equals(msg.getType()))) { + throw new ApiMessageInterceptionException(operr("l3Network[uuid:%s] is system network, can not create user vm on it", l3Uuid)); + } } } @@ -1155,9 +1473,9 @@ private void validate(NewVmInstanceMessage2 msg) { } if (VmInstanceConstant.USER_VM_TYPE.equals(msg.getType())) { - if (msg.getDefaultL3NetworkUuid() == null && msg.getL3NetworkUuids().size() != 1) { + if (msg.getDefaultL3NetworkUuid() == null && (!CollectionUtils.isEmpty(msg.getL3NetworkUuids()) && msg.getL3NetworkUuids().size() != 1)) { throw new ApiMessageInterceptionException(argerr("there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null")); - } else if (msg.getDefaultL3NetworkUuid() == null && msg.getL3NetworkUuids().size() == 1) { + } else if (msg.getDefaultL3NetworkUuid() == null && (msg.getL3NetworkUuids()!= null &&msg.getL3NetworkUuids().size() == 1)) { msg.setDefaultL3NetworkUuid(msg.getL3NetworkUuids().get(0)); } else if (msg.getDefaultL3NetworkUuid() != null && !msg.getL3NetworkUuids().contains(msg.getDefaultL3NetworkUuid())) { throw new ApiMessageInterceptionException(argerr("defaultL3NetworkUuid[uuid:%s] is not in l3NetworkUuids%s", msg.getDefaultL3NetworkUuid(), msg.getL3NetworkUuids())); @@ -1165,6 +1483,7 @@ private void validate(NewVmInstanceMessage2 msg) { } validateCdRomsTag(msg); + validateZoneOrClusterOrHostOrL3Exist(msg); } private void validateCdRomsTag(NewVmInstanceMessage msg) { @@ -1236,4 +1555,16 @@ private void validate(APISetVmInstanceDefaultCdRomMsg msg) { } } + private void validate(APIFstrimVmMsg msg) { + Tuple t = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getUuid()) + .select(VmInstanceVO_.state, VmInstanceVO_.hostUuid) + .findTuple(); + VmInstanceState state = t.get(0, VmInstanceState.class); + + if (state != VmInstanceState.Running) { + throw new ApiMessageInterceptionException(operr( + "vm[uuid:%s] can only fstrim when state is Running, current state is %s", msg.getUuid(), state)); + } + msg.setHostUuid(t.get(1, String.class)); + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java index d545cb8308c..ed98aef34e0 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java @@ -1,7 +1,7 @@ package org.zstack.compute.vm; - import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.util.Strings; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; @@ -19,6 +19,7 @@ import org.zstack.core.defer.Deferred; import org.zstack.core.jsonlabel.JsonLabel; import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.RunInQueue; import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; @@ -32,6 +33,7 @@ import org.zstack.header.cluster.ClusterVO_; import org.zstack.header.configuration.*; import org.zstack.header.core.*; +import org.zstack.header.core.progress.TaskProgressRange; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; @@ -48,6 +50,7 @@ import org.zstack.header.vm.ChangeVmMetaDataMsg.AtomicHostUuid; import org.zstack.header.vm.ChangeVmMetaDataMsg.AtomicVmState; import org.zstack.header.vm.VmAbnormalLifeCycleStruct.VmAbnormalLifeCycleOperation; +import org.zstack.header.vm.VmCanonicalEvents.VmStateChangedData; import org.zstack.header.vm.VmInstanceConstant.Params; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.vm.VmInstanceDeletionPolicyManager.VmInstanceDeletionPolicy; @@ -55,6 +58,8 @@ import org.zstack.header.vm.VmInstanceSpec.HostName; import org.zstack.header.vm.VmInstanceSpec.IsoSpec; import org.zstack.header.vm.cdrom.*; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; +import org.zstack.header.vo.ResourceVO; import org.zstack.header.volume.*; import org.zstack.identity.Account; import org.zstack.identity.AccountManager; @@ -69,11 +74,11 @@ import org.zstack.utils.ExceptionDSL; import org.zstack.utils.ObjectUtils; import org.zstack.utils.Utils; -import org.zstack.utils.data.SizeUnit; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.function.Function; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NicIpAddressInfo; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; @@ -86,12 +91,10 @@ import java.util.stream.Collectors; import static java.util.Arrays.asList; -import static org.zstack.core.Platform.err; -import static org.zstack.core.Platform.operr; -import static org.zstack.core.progress.ProgressReportService.reportProgress; +import static org.zstack.core.Platform.*; +import static org.zstack.core.progress.ProgressReportService.*; import static org.zstack.utils.CollectionDSL.*; - public class VmInstanceBase extends AbstractVmInstance { protected static final CLogger logger = Utils.getLogger(VmInstanceBase.class); @@ -129,6 +132,8 @@ public class VmInstanceBase extends AbstractVmInstance { private ResourceConfigFacade rcf; @Autowired private TagManager tagMgr; + @Autowired + private VmInstanceDeviceManager vidm; protected VmInstanceVO self; protected VmInstanceVO originalCopy; @@ -391,6 +396,14 @@ public void run(VmStateChangedExtensionPoint ext) { @Override @MessageSafe public void handleMessage(final Message msg) { + if (msg instanceof CheckAttachedVolumesMessage) { + handle((CheckAttachedVolumesMessage) msg); + } else { + handleMsg(msg); + } + } + + private void handleMsg(final Message msg) { if (msg instanceof APIMessage) { handleApiMessage((APIMessage) msg); } else { @@ -398,6 +411,35 @@ public void handleMessage(final Message msg) { } } + private void handle(CheckAttachedVolumesMessage msg) { + GetVolumeTaskMsg gmsg = new GetVolumeTaskMsg(); + List volUuids = self.getAllVolumes().stream().map(ResourceVO::getUuid).collect(Collectors.toList()); + gmsg.setVolumeUuids(volUuids); + bus.makeLocalServiceId(gmsg, VolumeConstant.SERVICE_ID); + bus.send(gmsg, new CloudBusCallBack((NeedReplyMessage) msg) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + bus.replyErrorByMessageType((Message) msg, r.getError()); + return; + } + + GetVolumeTaskReply gr = r.castReply(); + List hasTaskVols = gr.getResults().entrySet().stream() + .filter(it -> !it.getValue().getRunningTask().isEmpty()) + .map(it -> String.format("attached volume[uuid:%s] has running task[name:%s]", + it.getKey(), it.getValue().getRunningTask().get(0).getName())) + .collect(Collectors.toList()); + if (!hasTaskVols.isEmpty()) { + bus.replyErrorByMessageType((Message) msg, operr(Strings.join(hasTaskVols, ';'))); + return; + } + + handleMsg((Message) msg); + } + }); + } + protected void handleLocalMessage(Message msg) { if (msg instanceof InstantiateNewCreatedVmInstanceMsg) { handle((InstantiateNewCreatedVmInstanceMsg) msg); @@ -417,8 +459,8 @@ protected void handleLocalMessage(Message msg) { handle((RecoverVmInstanceMsg) msg); } else if (msg instanceof AttachNicToVmMsg) { handle((AttachNicToVmMsg) msg); - } else if (msg instanceof CreateTemplateFromVmRootVolumeMsg) { - handle((CreateTemplateFromVmRootVolumeMsg) msg); + } else if (msg instanceof CreateTemplateFromRootVolumeVmMsg) { + handle((CreateTemplateFromRootVolumeVmMsg) msg); } else if (msg instanceof VmInstanceDeletionMsg) { handle((VmInstanceDeletionMsg) msg); } else if (msg instanceof VmAttachNicMsg) { @@ -471,6 +513,22 @@ protected void handleLocalMessage(Message msg) { handle((AttachIsoToVmInstanceMsg) msg); } else if (msg instanceof GetVmCapabilitiesMsg) { handle((GetVmCapabilitiesMsg) msg); + } else if (msg instanceof SetVmStaticIpMsg) { + handle((SetVmStaticIpMsg) msg); + } else if (msg instanceof ChangeVmNicNetworkMsg) { + handle((ChangeVmNicNetworkMsg) msg); + } else if (msg instanceof UpdateVmInstanceMsg) { + handle((UpdateVmInstanceMsg) msg); + } else if (msg instanceof FlattenVmInstanceMsg) { + handle((FlattenVmInstanceMsg) msg); + } else if (msg instanceof CancelFlattenVmInstanceMsg) { + handle((CancelFlattenVmInstanceMsg) msg); + } else if (msg instanceof KvmReportVmShutdownEventMsg) { + handle((KvmReportVmShutdownEventMsg) msg); + } else if (msg instanceof KvmReportVmShutdownFromGuestEventMsg) { + handle((KvmReportVmShutdownFromGuestEventMsg) msg); + } else if (msg instanceof CheckAndStartVmInstanceMsg) { + handle((CheckAndStartVmInstanceMsg) msg); } else { VmInstanceBaseExtensionFactory ext = vmMgr.getVmInstanceBaseExtensionFactory(msg); if (ext != null) { @@ -482,6 +540,74 @@ protected void handleLocalMessage(Message msg) { } } + private void handle(KvmReportVmShutdownFromGuestEventMsg msg) { + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + KvmReportVmShutdownFromGuestEventReply reply = new KvmReportVmShutdownFromGuestEventReply(); + for (KvmReportVmShutdownFromGuestEventExtensionPoint ext : pluginRgty.getExtensionList(KvmReportVmShutdownFromGuestEventExtensionPoint.class)) { + ext.kvmReportVmShutdownEvent(msg.getVmInstanceUuid()); + } + bus.reply(msg, reply); + chain.next(); + } + + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public String getName() { + return syncThreadName; + } + }); + } + + protected void handle(final CheckAndStartVmInstanceMsg msg) { + thdf.chainSubmit(new ChainTask(msg) { + + @Override + public String getSyncSignature() { + return String.format("check-and-start-vm-%s", msg.getVmInstanceUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + checkStateAndStartVmInstance(msg, chain); + } + + @Override + public String getName() { + return String.format("check-and-start-vm-%s", msg.getVmInstanceUuid()); + } + }); + } + + private void handle(KvmReportVmShutdownEventMsg msg) { + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + KvmReportVmShutdownEventReply reply = new KvmReportVmShutdownEventReply(); + for (KvmReportVmShutdownEventExtensionPoint ext : pluginRgty.getExtensionList(KvmReportVmShutdownEventExtensionPoint.class)) { + ext.kvmReportVmShutdownEvent(msg.getVmInstanceUuid()); + } + bus.reply(msg, reply); + chain.next(); + } + + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public String getName() { + return syncThreadName; + } + }); + } + private void handle(ExecuteCrashStrategyMsg msg) { thdf.chainSubmit(new ChainTask(msg) { @Override @@ -560,6 +686,7 @@ public void run(MessageReply reply) { StopVmInstanceMsg smsg = new StopVmInstanceMsg(); smsg.setVmInstanceUuid(vmInv.getUuid()); smsg.setType(StopVmType.cold.toString()); + smsg.setDebug(true); stopVm(smsg, new Completion(completion) { @Override public void success() { @@ -581,6 +708,7 @@ public void fail(ErrorCode errorCode) { RebootVmInstanceMsg smsg = new RebootVmInstanceMsg(); smsg.setVmInstanceUuid(vmInv.getUuid()); smsg.setType(StopVmType.cold.toString()); + smsg.setDebug(true); rebootVm(smsg, new Completion(completion) { @Override public void success() { @@ -839,6 +967,15 @@ public void run(final SyncTaskChain chain) { return; } + // It is better to monitor HaStartVmInstanceMsg and HaStartVmInstanceReply, + // instead of intrusively recording the scheduling record here. + // The problem is, we have two early exits: + // 1. throwing exception; + // 2. judges no need to start VM. + // thus, with monitoring, there might be false records. + final VmSchedHistoryRecorder recorder = VmSchedHistoryRecorder.ofHA(msg.getVmInstanceUuid()) + .withSchedReason(msg.getHaReason()) + .begin(); ErrorCodeList errList = new ErrorCodeList(); new While<>(pluginRgty.getExtensionList(BeforeHaStartVmInstanceExtensionPoint.class)).each((ext, whileCompletion) -> { ext.beforeHaStartVmInstance(msg.getVmInstanceUuid(), msg.getJudgerClassName(), msg.getSoftAvoidHostUuids(), new Completion(msg) { @@ -859,6 +996,8 @@ public void done(ErrorCodeList errorCodeList) { if (!errList.getCauses().isEmpty()) { reply.setError(errList.getCauses().get(0)); bus.reply(msg, reply); + recorder.withFailReason(reply.getError().getDetails()) + .end(null); chain.next(); return; } @@ -881,6 +1020,7 @@ public void done(ErrorCodeList errorCodeList) { public void success() { reply.setInventory(getSelfInventory()); bus.reply(msg, reply); + recorder.end(reply.getInventory().getHostUuid()); chain.next(); } @@ -888,6 +1028,8 @@ public void success() { public void fail(ErrorCode errorCode) { reply.setError(errorCode); bus.reply(msg, reply); + recorder.withFailReason(errorCode.getDetails()) + .end(null); chain.next(); } }); @@ -942,6 +1084,11 @@ public VmNicVO call(VmNicVO arg) { final FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("change-vm-ip-l3-%s-vm-%s", l3Uuid, self.getUuid())); + final VmInstanceSpec spec = buildSpecFromInventory(getSelfInventory(), VmOperation.ChangeNicIp); + spec.setDestNics(list(VmNicInventory.valueOf(targetNic))); + L3NetworkVO l3VO = dbf.findByUuid(l3Uuid, L3NetworkVO.class); + spec.setL3Networks(list(new VmNicSpec(L3NetworkInventory.valueOf(l3VO)))); + chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); chain.then(new ShareFlow() { @Override public void setup() { @@ -1010,6 +1157,10 @@ public void done(ErrorCodeList errorCodeList) { } }); + if (self.getState() == VmInstanceState.Running) { + flow(new VmReleaseNetworkServiceOnChangeIPFlow()); + } + flow(new NoRollbackFlow() { String __name__ = "change-ip-in-database"; @@ -1021,6 +1172,7 @@ public void run(FlowTrigger trigger, Map data) { ext.afterAddIpAddress(targetNic.getUuid(), ip.getUuid()); } } + trigger.next(); } }); @@ -1047,6 +1199,9 @@ public void run(MessageReply reply) { }).run(new WhileDoneCompletion(trigger) { @Override public void done(ErrorCodeList errorCodeList) { + VmNicVO nicVO = dbf.findByUuid(targetNic.getUuid(), VmNicVO.class); + data.put(VmInstanceConstant.Params.VmNicInventory.toString(), nicVO); + trigger.next(); } }); @@ -1054,9 +1209,11 @@ public void done(ErrorCodeList errorCodeList) { } }); - done(new FlowDoneHandler(completion) { + flow(new NoRollbackFlow() { + String __name__ = "post-change-nic-ip"; + @Override - public void handle(Map data) { + public void run(FlowTrigger trigger, Map data) { final VmInstanceInventory vm = getSelfInventory(); final VmNicInventory nic = VmNicInventory.valueOf(targetNic); CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmIpChangedExtensionPoint.class), @@ -1066,7 +1223,17 @@ public void run(VmIpChangedExtensionPoint ext) { ext.vmIpChanged(vm, nic, oldIpMap, newIpMap); } }); + trigger.next(); + } + }); + + if (self.getState() == VmInstanceState.Running) { + flow(new VmApplyNetworkServiceOnChangeIPFlow()); + } + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { completion.success(); } }); @@ -1224,135 +1391,30 @@ public String getName() { private void handle(final VmStateChangedOnHostMsg msg) { logger.debug(String.format("get VmStateChangedOnHostMsg for vm[uuid:%s], on host[uuid:%s], which tracing state is [%s]" + " and current state on host is [%s]", msg.getVmInstanceUuid(), msg.getHostUuid(), msg.getVmStateAtTracingMoment(), msg.getStateOnHost())); - thdf.chainSubmit(new ChainTask(msg) { - @Override - public String getSyncSignature() { - if (msg.isFromSync()) { - return syncThreadName; - } else { - return String.format("change-vm-state-%s", syncThreadName); - } - } - - @Override - public void run(final SyncTaskChain chain) { - logger.debug(String.format("running sync task %s with sync signature %s", getName(), getSyncSignature())); - vmStateChangeOnHost(msg, new NoErrorCompletion(chain) { - @Override - public void done() { - chain.next(); - } - }); - } - - @Override - public String getName() { - return String.format("vm-%s-state-change-on-the-host-%s", msg.getVmInstanceUuid(), msg.getHostUuid()); - } - }); - } - - private VmAbnormalLifeCycleOperation getVmAbnormalLifeCycleOperation(String originalHostUuid, - String currentHostUuid, - VmInstanceState originalState, - VmInstanceState currentState) { - if (originalState == VmInstanceState.Stopped && currentState == VmInstanceState.Running) { - return VmAbnormalLifeCycleOperation.VmRunningOnTheHost; - } - - // c.f. ZSTAC-25974 - if ((originalState == VmInstanceState.Running || originalState == VmInstanceState.Starting) - && currentState == VmInstanceState.Stopped - && currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmStoppedOnTheSameHost; - } - - if (VmInstanceState.intermediateStates.contains(originalState) && currentState == VmInstanceState.Running) { - return VmAbnormalLifeCycleOperation.VmRunningFromIntermediateState; - } - - if (VmInstanceState.intermediateStates.contains(originalState) && currentState == VmInstanceState.Stopped) { - return VmAbnormalLifeCycleOperation.VmStoppedFromIntermediateState; - } - - if (originalState == VmInstanceState.Running && currentState == VmInstanceState.Paused && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmPausedFromRunningStateHostNotChanged; - } - if (originalState == VmInstanceState.Unknown && currentState == VmInstanceState.Paused && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmPausedFromUnknownStateHostNotChanged; - } - - if (originalState == VmInstanceState.Stopped && currentState == VmInstanceState.Paused && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmPausedFromStoppedStateHostNotChanged; - } - - if (originalState == VmInstanceState.Migrating && currentState == VmInstanceState.Paused && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmPausedFromMigratingStateHostNotChanged; - } - - if (originalState == VmInstanceState.Unknown && currentState == VmInstanceState.Running && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmRunningFromUnknownStateHostNotChanged; - } - - if (originalState == VmInstanceState.Unknown && currentState == VmInstanceState.Running && - !currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmRunningFromUnknownStateHostChanged; - } - - if (originalState == VmInstanceState.Unknown && currentState == VmInstanceState.Stopped && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmStoppedOnTheSameHost; - } - - if (originalState == VmInstanceState.Unknown && currentState == VmInstanceState.Stopped - && originalHostUuid == null && currentHostUuid.equals(self.getLastHostUuid())) { - return VmAbnormalLifeCycleOperation.VmStoppedFromUnknownStateHostNotChanged; - } - - if (originalState == VmInstanceState.Running && - originalState == currentState && - !currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmMigrateToAnotherHost; - } - - if (originalState == VmInstanceState.Paused && currentState == VmInstanceState.Running && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmRunningFromPausedStateHostNotChanged; - } - - if (originalState == VmInstanceState.Paused && currentState == VmInstanceState.Stopped && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmStoppedFromPausedStateHostNotChanged; - } - - if (originalState == VmInstanceState.Destroyed && - (currentState == VmInstanceState.Running || currentState == VmInstanceState.Paused)) { - return VmAbnormalLifeCycleOperation.VmRunningFromDestroyed; - } - - if (originalState == VmInstanceState.Running && currentState == VmInstanceState.Crashed && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmCrashedFromRunningStateHostNotChanged; - } - - if (originalState == VmInstanceState.Crashed && currentState == VmInstanceState.Running && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmRunningFromCrashedStateHostNotChanged; - } - if (originalState == VmInstanceState.Crashed && currentState == VmInstanceState.Stopped && - currentHostUuid.equals(originalHostUuid)) { - return VmAbnormalLifeCycleOperation.VmStoppedFromCrashedStateHostNotChanged; + String syncSignature; + // note: use vm as outer queue name to avoid + // abnormal vm issue blocks the queue's execution + if (msg.isFromSync()) { + syncSignature = syncThreadName; + } else { + syncSignature = String.format("change-vm-state-%s", syncThreadName); } - throw new CloudRuntimeException(String.format("unknown VM[uuid:%s] abnormal state combination[original state: %s," + - " current state: %s, original host:%s, current host:%s]", - self.getUuid(), originalState, currentState, originalHostUuid, currentHostUuid)); + RunInQueue queue = new RunInQueue(syncSignature, thdf, 1); + queue.name(syncSignature) + .asyncBackup(msg) + .run(outer -> new RunInQueue(String.format("vm-state-change-on-host-%s", msg.getHostUuid()), thdf, 1) + .name(String.format("vm-%s-state-change-on-the-host-%s", msg.getVmInstanceUuid(), msg.getHostUuid())) + .asyncBackup(msg) + .asyncBackup(outer) + .run(chain -> vmStateChangeOnHost(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + outer.next(); + } + }))); } private void vmStateChangeOnHost(final VmStateChangedOnHostMsg msg, final NoErrorCompletion completion) { @@ -1413,17 +1475,50 @@ private void vmStateChangeOnHost(final VmStateChangedOnHostMsg msg, final NoErro return; } - VmAbnormalLifeCycleOperation operation = getVmAbnormalLifeCycleOperation(originalHostUuid, - currentHostUuid, originalState, currentState); + VmAbnormalLifeCycleStruct struct = new VmAbnormalLifeCycleStruct(); + struct.setCurrentHostUuid(currentHostUuid); + struct.setCurrentState(currentState); + struct.setOriginalHostUuid(originalHostUuid); + struct.setOriginalState(originalState); + struct.setVmLastHostUuid(self.getLastHostUuid()); + + VmAbnormalLifeCycleOperation operation = VmAbnormalLifeCycleStruct + .getVmAbnormalLifeCycleOperationFromStruct(struct); + + if (operation == null) { + throw new CloudRuntimeException(String.format("unknown VM[uuid:%s] abnormal" + + " state combination[original state: %s," + + " current state: %s, original host:%s, current host:%s]", + self.getUuid(), + struct.getOriginalState(), + struct.getCurrentState(), + struct.getOriginalHostUuid(), + struct.getCurrentHostUuid())); + } + + struct.setVmInstance(getSelfInventory()); + struct.setOperation(operation); if (operation == VmAbnormalLifeCycleOperation.VmRunningFromUnknownStateHostNotChanged - || operation == VmAbnormalLifeCycleOperation.VmRunningFromCrashedStateHostNotChanged) { + || operation == VmAbnormalLifeCycleOperation.VmRunningFromCrashedStateHostNotChanged + || operation == VmAbnormalLifeCycleOperation.VmRunningWithoutOriginalHost) { // the vm is detected on the host again. It's largely because the host disconnected before // and now reconnected + // or vm is running without host info update in db when VmRunningWithoutOriginalHost happened changeVmStateInDb(VmInstanceStateEvent.running, () -> self.setHostUuid(msg.getHostUuid())); fireEvent.run(); bus.reply(msg, reply); completion.done(); return; + } else if (operation == VmAbnormalLifeCycleOperation.VmNoStateFromRunningStateHostNotChanged + || operation == VmAbnormalLifeCycleOperation.VmNoStateFromCrashedStateHostNotChanged + || operation == VmAbnormalLifeCycleOperation.VmNoStateFromUnknownStateHostNotChanged) { + // the vm is detected on the host again. It's largely because the host disconnected before + // and now reconnected + changeVmStateInDb(VmInstanceStateEvent.noState, () -> self.setHostUuid(msg.getHostUuid())); + fireEvent.run(); + bus.reply(msg, reply); + completion.done(); + return; } else if (operation == VmAbnormalLifeCycleOperation.VmStoppedFromUnknownStateHostNotChanged) { // the vm comes out of the unknown state to the stopped state // it happens when an operation failure led the vm from the stopped state to the unknown state, @@ -1440,8 +1535,7 @@ private void vmStateChangeOnHost(final VmStateChangedOnHostMsg msg, final NoErro bus.reply(msg, reply); completion.done(); return; - } else if (operation == VmAbnormalLifeCycleOperation.VmPausedFromUnknownStateHostNotChanged - || operation == VmAbnormalLifeCycleOperation.VmPausedFromStoppedStateHostNotChanged) { + } else if (operation == VmAbnormalLifeCycleOperation.VmPausedFromUnknownStateHostNotChanged) { //some reason led vm to unknown state and the paused vm are detected on the host again changeVmStateInDb(VmInstanceStateEvent.paused, () -> self.setHostUuid(msg.getHostUuid())); fireEvent.run(); @@ -1485,14 +1579,6 @@ private void vmStateChangeOnHost(final VmStateChangedOnHostMsg msg, final NoErro List exts = pluginRgty.getExtensionList(VmAbnormalLifeCycleExtensionPoint.class); - VmAbnormalLifeCycleStruct struct = new VmAbnormalLifeCycleStruct(); - struct.setCurrentHostUuid(currentHostUuid); - struct.setCurrentState(currentState); - struct.setOriginalHostUuid(originalHostUuid); - struct.setOriginalState(originalState); - struct.setVmInstance(getSelfInventory()); - struct.setOperation(operation); - logger.debug(String.format("the vm[uuid:%s]'s state changed abnormally on the host[uuid:%s]," + " ZStack is going to take the operation[%s]," + "[original state: %s, current state: %s, original host: %s, current host:%s]", @@ -1511,6 +1597,8 @@ private void vmStateChangeOnHost(final VmStateChangedOnHostMsg msg, final NoErro public void handle(Map data) { if (currentState == VmInstanceState.Running) { changeVmStateInDb(VmInstanceStateEvent.running, () -> self.setHostUuid(currentHostUuid)); + } else if (currentState == VmInstanceState.Paused) { + changeVmStateInDb(VmInstanceStateEvent.paused, () -> self.setHostUuid(currentHostUuid)); } else if (currentState == VmInstanceState.Stopped) { changeVmStateInDb(VmInstanceStateEvent.stopped); } @@ -1962,10 +2050,19 @@ public String getSyncSignature() { @Override public void run(final SyncTaskChain chain) { - detachVolume(msg, new NoErrorCompletion(chain) { + detachVolume(msg, new Completion(chain) { @Override - public void done() { + public void success() { chain.next(); + bus.reply(msg, new DetachDataVolumeFromVmReply()); + } + + @Override + public void fail(ErrorCode errorCode) { + chain.next(); + DetachDataVolumeFromVmReply reply = new DetachDataVolumeFromVmReply(); + reply.setError(errorCode); + bus.reply(msg, reply); } }); } @@ -2012,6 +2109,7 @@ public String getName() { } @Deferred + @SuppressWarnings({"rawtypes", "unchecked"}) private void attachNic(final Message msg, final List l3Uuids, final ReturnValueCompletion completion) { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); @@ -2043,11 +2141,13 @@ class SetStaticIp { private boolean isSet = false; private boolean allowDupicatedAddress = false; Map> staticIpMap = null; + Map nicNetworkInfo = null; void set() { if (msg instanceof APIAttachL3NetworkToVmMsg) { APIAttachL3NetworkToVmMsg amsg = (APIAttachL3NetworkToVmMsg) msg; staticIpMap = amsg.getStaticIpMap(); + nicNetworkInfo = amsg.getNicNetworkInfo(); } else if (msg instanceof VmAttachNicMsg) { VmAttachNicMsg nicMsg = (VmAttachNicMsg) msg; staticIpMap = nicMsg.getStaticIpMap(); @@ -2086,7 +2186,7 @@ void set () { APIAttachL3NetworkToVmMsg amsg = (APIAttachL3NetworkToVmMsg) msg; if (amsg.hasSystemTag(VmSystemTags.L3_NETWORK_SECURITY_GROUP_UUIDS_REF::isMatch)) { - tagMgr.createInherentSystemTags(amsg.getSystemTags(), self.getUuid(), VmInstanceVO.class.getSimpleName()); + tagMgr.createNonInherentSystemTags(amsg.getSystemTags(), self.getUuid(), VmInstanceVO.class.getSimpleName()); isSet = true; } } @@ -2099,28 +2199,43 @@ void rollback() { } } + class SetCustomMacSystemTag { + private boolean isSet = false; + + void set () { + if (msg instanceof VmAttachNicMsg) { + VmAttachNicMsg amsg = (VmAttachNicMsg) msg; + + if (amsg.hasSystemTag(VmSystemTags.CUSTOM_MAC::isMatch)) { + tagMgr.createNonInherentSystemTags(amsg.getSystemTags(), self.getUuid(), VmInstanceVO.class.getSimpleName()); + isSet = true; + } + } + } + + void rollback() { + if (isSet) { + VmSystemTags.CUSTOM_MAC.delete(self.getUuid()); + } + } + } + final SetDefaultL3Network setDefaultL3Network = new SetDefaultL3Network(); setDefaultL3Network.set(); - Defer.guard(new Runnable() { - @Override - public void run() { - setDefaultL3Network.rollback(); - } - }); + Defer.guard(setDefaultL3Network::rollback); final SetStaticIp setStaticIp = new SetStaticIp(); setStaticIp.set(); - Defer.guard(new Runnable() { - @Override - public void run() { - setStaticIp.rollback(); - } - }); + Defer.guard(setStaticIp::rollback); final SetL3SecurityGroupSystemTag setSystemTag = new SetL3SecurityGroupSystemTag(); setSystemTag.set(); Defer.guard(setSystemTag::rollback); + final SetCustomMacSystemTag setCustomMacSystemTag = new SetCustomMacSystemTag(); + setCustomMacSystemTag.set(); + Defer.guard(setCustomMacSystemTag::rollback); + final VmInstanceSpec spec = buildSpecFromInventory(getSelfInventory(), VmOperation.AttachNic); final VmInstanceInventory vm = spec.getVmInventory(); List l3s = new ArrayList<>(); @@ -2128,56 +2243,54 @@ public void run() { L3NetworkVO l3vo = dbf.findByUuid(l3Uuid, L3NetworkVO.class); final L3NetworkInventory l3 = L3NetworkInventory.valueOf(l3vo); l3s.add(l3); - for (VmPreAttachL3NetworkExtensionPoint ext : pluginRgty.getExtensionList(VmPreAttachL3NetworkExtensionPoint.class)) { - ext.vmPreAttachL3Network(vm, l3); - } } - spec.setL3Networks(list(new VmNicSpec(l3s))); - spec.setDestNics(new ArrayList()); - + spec.setDisableL3Networks(new ArrayList<>()); + VmNicSpec nicSpec = new VmNicSpec(l3s); if (msg instanceof APIAttachL3NetworkToVmMsg) { APIAttachL3NetworkToVmMsg msg1 = (APIAttachL3NetworkToVmMsg) msg; - for (VmNicSpec vmNicSpec : spec.getL3Networks()) { - vmNicSpec.setNicDriverType(msg1.getDriverType()); + nicSpec.setNicDriverType(msg1.getDriverType()); + + String vmNicParams = msg1.getVmNicParams(); + if (!StringUtils.isEmpty(vmNicParams)) { + VmNicParam nicParams = JSONObjectUtil.toObject(vmNicParams, VmNicParam.class); + nicSpec.setVmNicParams(Arrays.asList(nicParams)); + if (VmNicState.disable.toString().equals(nicParams.getState())) { + spec.getDisableL3Networks().add(nicParams.getL3NetworkUuid()); + } } } + spec.setL3Networks(list(nicSpec)); + spec.setDestNics(new ArrayList()); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmBeforeAttachL3NetworkExtensionPoint.class), - new ForEachFunction() { - @Override - public void run(VmBeforeAttachL3NetworkExtensionPoint arg) { - for (L3NetworkInventory l3 : l3s) { - arg.vmBeforeAttachL3Network(vm, l3); - } - } - }); + arg -> l3s.forEach(l3 -> arg.vmBeforeAttachL3Network(vm, l3))); FlowChain flowChain = FlowChainBuilder.newSimpleFlowChain(); setFlowMarshaller(flowChain); flowChain.setName(String.format("attachNic-vm-%s-l3-%s", self.getUuid(), l3Uuids.get(0))); flowChain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); flowChain.getData().put(VmInstanceConstant.Params.VmAllocateNicFlow_allowDuplicatedAddress.toString(), setStaticIp.allowDupicatedAddress); + flowChain.getData().put(VmInstanceConstant.Params.VmAllocateNicFlow_nicNetworkInfo.toString(), setStaticIp.nicNetworkInfo); + for (VmNicPrepareResourceExtensionPoint exp : pluginRgty.getExtensionList(VmNicPrepareResourceExtensionPoint.class)) { + flowChain.then(exp.getPreparationFlow()); + } + flowChain.then(new VmAllocateNicFlow()); + flowChain.then(new VmAllocateNicIpFlow()); flowChain.then(new VmSetDefaultL3NetworkOnAttachingFlow()); setAdditionalFlow(flowChain, spec); if (self.getState() == VmInstanceState.Running) { flowChain.then(new VmInstantiateResourceOnAttachingNicFlow()); - flowChain.then(new VmAttachNicOnHypervisorFlow()); } + flowChain.then(new VmAttachNicOnHypervisorFlow()); flowChain.done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmAfterAttachL3NetworkExtensionPoint.class), - new ForEachFunction() { - @Override - public void run(VmAfterAttachL3NetworkExtensionPoint arg) { - for (L3NetworkInventory l3 : l3s) { - arg.vmAfterAttachL3Network(vm, l3); - } - } - }); + arg -> l3s.forEach(l3 -> arg.vmAfterAttachL3Network(vm, l3))); VmNicInventory nic = spec.getDestNics().get(0); completion.success(nic); } @@ -2185,14 +2298,7 @@ public void run(VmAfterAttachL3NetworkExtensionPoint arg) { @Override public void handle(final ErrorCode errCode, Map data) { CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmFailToAttachL3NetworkExtensionPoint.class), - new ForEachFunction() { - @Override - public void run(VmFailToAttachL3NetworkExtensionPoint arg) { - for (L3NetworkInventory l3 : l3s) { - arg.vmFailToAttachL3Network(vm, l3, errCode); - } - } - }); + arg -> l3s.forEach(l3 -> arg.vmFailToAttachL3Network(vm, l3, errCode))); setDefaultL3Network.rollback(); setStaticIp.rollback(); setSystemTag.rollback(); @@ -2250,12 +2356,21 @@ void rollback() { L3NetworkVO l3vo = dbf.findByUuid(l3Uuid, L3NetworkVO.class); final L3NetworkInventory l3 = L3NetworkInventory.valueOf(l3vo); final VmInstanceInventory vm = getSelfInventory(); + List nics = vm.getVmNics(); + VmNicInventory nicToAttach = VmNicInventory.valueOf(vmNicVO); + nicToAttach.setMetaData("attachNic"); + if (nics == null) { + vm.setVmNics(new ArrayList(Arrays.asList(nicToAttach))); + }else { + nics.add(nicToAttach); + } for (VmPreAttachL3NetworkExtensionPoint ext : pluginRgty.getExtensionList(VmPreAttachL3NetworkExtensionPoint.class)) { ext.vmPreAttachL3Network(vm, l3); } spec.setL3Networks(list(new VmNicSpec(l3))); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmBeforeAttachL3NetworkExtensionPoint.class), new ForEachFunction() { @Override @@ -2394,6 +2509,11 @@ public void fail(ErrorCode errorCode) { public void rollback(FlowRollback trigger, Map data) { refreshVO(); VmNicInventory nic = (VmNicInventory) data.get(vmNicInvKey); + if (nic == null) { + trigger.rollback(); + return; + } + doDetachNic(nic, true, true, new Completion(trigger) { @Override public void success() { @@ -2698,7 +2818,7 @@ public void run(SyncTaskChain chain) { }); } - private void createTemplateFromRootVolume(final CreateTemplateFromVmRootVolumeMsg msg, final SyncTaskChain chain) { + private void createTemplateFromRootVolume(final CreateTemplateFromRootVolumeVmMsg msg, final SyncTaskChain chain) { boolean callNext = true; try { refreshVO(); @@ -2708,9 +2828,15 @@ private void createTemplateFromRootVolume(final CreateTemplateFromVmRootVolumeMs return; } - final CreateTemplateFromVmRootVolumeReply reply = new CreateTemplateFromVmRootVolumeReply(); + final CreateTemplateFromRootVolumeVmReply reply = new CreateTemplateFromRootVolumeVmReply(); CreateTemplateFromVolumeOnPrimaryStorageMsg cmsg = new CreateTemplateFromVolumeOnPrimaryStorageMsg(); + if (msg instanceof CreateTemplateFromRootVolumeSnapShotVmMsg) { + cmsg = new CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg(); + ((CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg) cmsg).setSnapshotUuid( + ((CreateTemplateFromRootVolumeSnapShotVmMsg) msg).getSnapshotUuid()); + } + cmsg.setVolumeInventory(msg.getRootVolumeInventory()); cmsg.setBackupStorageUuid(msg.getBackupStorageUuid()); cmsg.setImageInventory(msg.getImageInventory()); @@ -2746,7 +2872,7 @@ public void run(MessageReply r) { } } - private void handle(final CreateTemplateFromVmRootVolumeMsg msg) { + private void handle(final CreateTemplateFromRootVolumeVmMsg msg) { thdf.chainSubmit(new ChainTask(msg) { @Override public String getName() { @@ -2992,6 +3118,11 @@ protected void selectBootOrder(VmInstanceSpec spec) { } } + private void createVmButNotStart(InstantiateNewCreatedVmInstanceMsg msg, VmInstanceInventory inv) { + InstantiateVmFromNewCreatedStruct struct = InstantiateVmFromNewCreatedStruct.fromMessage(msg); + new JsonLabel().create(InstantiateVmFromNewCreatedStruct.makeLabelKey(inv.getUuid()), struct, inv.getUuid()); + } + protected void instantiateVmFromNewCreate(final InstantiateNewCreatedVmInstanceMsg msg, final SyncTaskChain taskChain) { refreshVO(); ErrorCode error = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); @@ -2999,12 +3130,20 @@ protected void instantiateVmFromNewCreate(final InstantiateNewCreatedVmInstanceM throw new OperationFailureException(error); } + InstantiateNewCreatedVmInstanceReply reply = new InstantiateNewCreatedVmInstanceReply(); + if (VmCreationStrategy.JustCreate.toString().equals(msg.getStrategy())) { + createVmButNotStart(msg, msg.getVmInstanceInventory()); + reply.setVmInventory(msg.getVmInstanceInventory()); + bus.reply(msg, reply); + taskChain.next(); + return; + } + error = extEmitter.preStartNewCreatedVm(msg.getVmInstanceInventory()); if (error != null) { throw new OperationFailureException(error); } - InstantiateNewCreatedVmInstanceReply reply = new InstantiateNewCreatedVmInstanceReply(); instantiateVmFromNewCreate(InstantiateVmFromNewCreatedStruct.fromMessage(msg), new Completion(msg, taskChain) { @Override public void success() { @@ -3075,7 +3214,7 @@ protected List getImageCandidatesForVm(ImageMediaType type) { } q.setParameter("state", ImageState.Enabled); q.setParameter("status", ImageStatus.Ready); - q.setParameter("system", false); + q.setParameter("system", Objects.equals(self.getType(), VmInstanceConstant.APPLIANCE_VM_TYPE)); q.setParameter("arch", architecture); q.setParameter("bsUuids", bsUuids); List candidates = ImageInventory.valueOf(q.getResultList()); @@ -3116,6 +3255,8 @@ protected void handleApiMessage(APIMessage msg) { handle((APIChangeInstanceOfferingMsg) msg); } else if (msg instanceof APIDetachL3NetworkFromVmMsg) { handle((APIDetachL3NetworkFromVmMsg) msg); + } else if (msg instanceof APIChangeVmNicStateMsg) { + handle((APIChangeVmNicStateMsg) msg); } else if (msg instanceof APIGetVmAttachableL3NetworkMsg) { handle((APIGetVmAttachableL3NetworkMsg) msg); } else if (msg instanceof APIGetCandidateL3NetworksForChangeVmNicNetworkMsg) { @@ -3194,6 +3335,12 @@ protected void handleApiMessage(APIMessage msg) { handle((APISetVmInstanceDefaultCdRomMsg) msg); } else if (msg instanceof APIUpdateVmNicDriverMsg) { handle((APIUpdateVmNicDriverMsg) msg); + } else if (msg instanceof APIFlattenVmInstanceMsg) { + handle((APIFlattenVmInstanceMsg) msg); + } else if (msg instanceof APIFstrimVmMsg) { + handle((APIFstrimVmMsg) msg); + } else if (msg instanceof APITakeVmConsoleScreenshotMsg) { + handle((APITakeVmConsoleScreenshotMsg) msg); } else { VmInstanceBaseExtensionFactory ext = vmMgr.getVmInstanceBaseExtensionFactory(msg); if (ext != null) { @@ -3205,11 +3352,32 @@ protected void handleApiMessage(APIMessage msg) { } } - private void handle(APIGetCandidateIsoForAttachingVmMsg msg) { - APIGetCandidateIsoForAttachingVmReply reply = new APIGetCandidateIsoForAttachingVmReply(); - if (self.getState() != VmInstanceState.Running && self.getState() != VmInstanceState.Stopped) { - reply.setInventories(new ArrayList<>()); - bus.reply(msg, reply); + private void handle(APITakeVmConsoleScreenshotMsg msg) { + APITakeVmConsoleScreenshotEvent event = new APITakeVmConsoleScreenshotEvent(msg.getId()); + TakeVmConsoleScreenshotMsg gmsg = new TakeVmConsoleScreenshotMsg(); + gmsg.setVmInstanceUuid(self.getUuid()); + gmsg.setHostUuid(self.getHostUuid()); + bus.makeTargetServiceIdByResourceUuid(gmsg, HostConstant.SERVICE_ID, self.getHostUuid()); + bus.send(gmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + event.setSuccess(false); + event.setError(reply.getError()); + } else { + TakeVmConsoleScreenshotReply re = (TakeVmConsoleScreenshotReply) reply; + event.setImageData(re.getImageData()); + } + bus.publish(event); + } + }); + } + + private void handle(APIGetCandidateIsoForAttachingVmMsg msg) { + APIGetCandidateIsoForAttachingVmReply reply = new APIGetCandidateIsoForAttachingVmReply(); + if (self.getState() != VmInstanceState.Running && self.getState() != VmInstanceState.Stopped) { + reply.setInventories(new ArrayList<>()); + bus.reply(msg, reply); return; } @@ -3288,6 +3456,37 @@ public String getName() { } private void handle(final APISetVmStaticIpMsg msg) { + final APISetVmStaticIpEvent evt = new APISetVmStaticIpEvent(msg.getId()); + refreshVO(); + ErrorCode error = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); + if (error != null) { + throw new OperationFailureException(error); + } + SetVmStaticIpMsg cmsg = new SetVmStaticIpMsg(); + cmsg.setIp(msg.getIp()); + cmsg.setIp6(msg.getIp6()); + cmsg.setL3NetworkUuid(msg.getL3NetworkUuid()); + cmsg.setVmInstanceUuid(msg.getVmInstanceUuid()); + cmsg.setGateway(msg.getGateway()); + cmsg.setNetmask(msg.getNetmask()); + cmsg.setIpv6Gateway(msg.getIpv6Gateway()); + cmsg.setIpv6Prefix(msg.getIpv6Prefix()); + bus.makeTargetServiceIdByResourceUuid(cmsg, VmInstanceConstant.SERVICE_ID, cmsg.getVmInstanceUuid()); + bus.send(cmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + bus.publish(evt); + return; + } + bus.publish(evt); + } + }); + } + + private void handle(final SetVmStaticIpMsg msg) { + SetVmStaticIpReply reply = new SetVmStaticIpReply(); thdf.chainSubmit(new ChainTask(msg) { @Override public String getSyncSignature() { @@ -3296,12 +3495,39 @@ public String getSyncSignature() { @Override public void run(final SyncTaskChain chain) { - setStaticIp(msg, new NoErrorCompletion(msg, chain) { - @Override - public void done() { - chain.next(); - } - }); + + L3NetworkVO l3NetworkVO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if (!l3NetworkVO.enableIpAddressAllocation()) { + setNoIpamStaticIp(msg, new Completion(reply) { + @Override + public void success() { + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } else { + setIpamStaticIp(msg, new Completion(reply) { + @Override + public void success() { + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } } @Override @@ -3311,14 +3537,127 @@ public String getName() { }); } - private void setStaticIp(final APISetVmStaticIpMsg msg, final NoErrorCompletion completion) { - refreshVO(); - ErrorCode error = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); - if (error != null) { - throw new OperationFailureException(error); - } + private void setNoIpamStaticIp(final SetVmStaticIpMsg msg, final Completion completion) { + final FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("change-vm-ip-l3-%s-vm-%s", msg.getL3NetworkUuid(), self.getUuid())); + final VmInstanceSpec spec = buildSpecFromInventory(getSelfInventory(), VmOperation.ChangeNicIp); + final VmNicVO vmNicVO = self.getVmNics().stream().filter( + nic -> nic.getL3NetworkUuid().equals(msg.getL3NetworkUuid())).findFirst().get(); + spec.setL3Networks(list(new VmNicSpec( + L3NetworkInventory.valueOf(dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class))))); + chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); + chain.getData().put(VmInstanceConstant.Params.VmNicInventory.toString(), vmNicVO); + chain.then(new ShareFlow() { + @Override + public void setup() { - final APISetVmStaticIpEvent evt = new APISetVmStaticIpEvent(msg.getId()); + if (self.getState() == VmInstanceState.Running) { + flow(new VmReleaseNetworkServiceOnChangeIPFlow()); + } + + flow(new NoRollbackFlow() { + String __name__ = "change-ip-in-database"; + + @Override + public void run(FlowTrigger trigger, Map data) { + VmNicVO nicVO = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, msg.getVmInstanceUuid()) + .eq(VmNicVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .limit(1).find(); + List voNewList = new ArrayList<>(); + // in dual stack l3 , keep the old ip which not set in msg + List voRemoveList = new ArrayList<>(); + List voOldList = Q.New(UsedIpVO.class).eq(UsedIpVO_.vmNicUuid, nicVO.getUuid()).list(); + if (msg.getIp() == null && msg.getIp6() == null) { + voRemoveList.addAll(voOldList); + nicVO.setUsedIpUuid(null); + nicVO.setIp(null); + nicVO.setGateway(null); + nicVO.setNetmask(null); + } + if (msg.getIp6() != null) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIp(IPv6NetworkUtils.getIpv6AddressCanonicalString(msg.getIp6())); + vo.setNetmask(IPv6NetworkUtils.getFormalNetmaskOfNetworkCidr(msg.getIp6()+"/"+msg.getIpv6Prefix())); + vo.setGateway(msg.getIpv6Gateway().isEmpty() ? "" : IPv6NetworkUtils.getIpv6AddressCanonicalString(msg.getIpv6Gateway())); + vo.setIpVersion(IPv6Constants.IPv6); + vo.setVmNicUuid(nicVO.getUuid()); + vo.setL3NetworkUuid(nicVO.getL3NetworkUuid()); + vo.setIpRangeUuid(new StaticIpOperator().getIpRangeUuid(vo.getL3NetworkUuid(), vo.getIp())); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(vo.getIp()); + nicVO.setNetmask(vo.getNetmask()); + nicVO.setGateway(vo.getGateway()); + voNewList.add(vo); + voRemoveList.addAll(voOldList.stream().filter(voOld -> voOld.getIpVersion() == IPv6Constants.IPv6).collect(Collectors.toList())); + } + // Ip and ip6 set at same time means dual stack network, nic will set UsedIpUuid with ipv4 + if (msg.getIp() != null) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + if (NetworkUtils.isIpv4Address(msg.getIp())) { + vo.setIp(msg.getIp()); + vo.setNetmask(msg.getNetmask()); + vo.setGateway(msg.getGateway().isEmpty() ? "" : msg.getGateway()); + vo.setIpVersion(IPv6Constants.IPv4); + vo.setVmNicUuid(nicVO.getUuid()); + vo.setL3NetworkUuid(nicVO.getL3NetworkUuid()); + vo.setIpInLong(NetworkUtils.ipv4StringToLong(vo.getIp())); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setIpRangeUuid(new StaticIpOperator().getIpRangeUuid(vo.getL3NetworkUuid(), vo.getIp())); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(vo.getIp()); + nicVO.setNetmask(vo.getNetmask()); + nicVO.setGateway(vo.getGateway()); + voNewList.add(vo); + voRemoveList.addAll(voOldList.stream().filter(voOld -> voOld.getIpVersion() == IPv6Constants.IPv4).collect(Collectors.toList())); + } else { + vo.setIp(IPv6NetworkUtils.getIpv6AddressCanonicalString(msg.getIp())); + vo.setNetmask(IPv6NetworkUtils.getFormalNetmaskOfNetworkCidr(msg.getIp()+"/"+msg.getIpv6Prefix())); + vo.setGateway(msg.getIpv6Gateway().isEmpty() ? "" : IPv6NetworkUtils.getIpv6AddressCanonicalString(msg.getIpv6Gateway())); + vo.setIpVersion(IPv6Constants.IPv6); + vo.setVmNicUuid(nicVO.getUuid()); + vo.setL3NetworkUuid(nicVO.getL3NetworkUuid()); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(vo.getIp()); + nicVO.setNetmask(vo.getNetmask()); + nicVO.setGateway(vo.getGateway()); + voNewList.add(vo); + voRemoveList.addAll(voOldList.stream().filter(voOld -> voOld.getIpVersion() == IPv6Constants.IPv6).collect(Collectors.toList())); + } + } + dbf.persistCollection(voNewList); + dbf.update(nicVO); + dbf.removeCollection(voRemoveList, UsedIpVO.class); + trigger.next(); + } + }); + + if (self.getState() == VmInstanceState.Running) { + flow(new VmApplyNetworkServiceOnChangeIPFlow()); + } + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + + private void setIpamStaticIp(final SetVmStaticIpMsg msg, final Completion completion) { Map staticIpMap = new HashMap<>(); if (msg.getIp() != null) { if (NetworkUtils.isIpv4Address(msg.getIp())) { @@ -3341,20 +3680,19 @@ public void success() { new StaticIpOperator().setStaticIp(self.getUuid(), msg.getL3NetworkUuid(), msg.getIp6()); } new StaticIpOperator().setIpChange(self.getUuid(), msg.getL3NetworkUuid()); - bus.publish(evt); - completion.done(); + completion.success(); } @Override public void fail(ErrorCode errorCode) { - evt.setError(errorCode); - bus.publish(evt); - completion.done(); + completion.fail(errorCode); } }); } private void handle(APISetVmBootModeMsg msg) { + final boolean[] bootModeChanged = {false}; + FlowChain chain = new SimpleFlowChain(); chain.then(new Flow() { String __name__ = "set-vm-boot-mode"; @@ -3363,14 +3701,29 @@ private void handle(APISetVmBootModeMsg msg) { @Override public void run(FlowTrigger trigger, Map data) { - SystemTagCreator creator = VmSystemTags.BOOT_MODE.newSystemTagCreator(self.getUuid()); - creator.setTagByTokens(map( - e(VmSystemTags.BOOT_MODE_TOKEN, msg.getBootMode()) - )); - creator.recreate = true; - creator.create(); + String bootMode = VmSystemTags.BOOT_MODE + .getTokenByResourceUuid(self.getUuid(), + VmSystemTags.BOOT_MODE_TOKEN); + + originLevel = bootMode; + + if (bootMode != null && bootMode.equals(msg.getBootMode())) { + trigger.next(); + return; + } + + if (msg.getBootMode() == null) { + VmSystemTags.BOOT_MODE.delete(self.getUuid()); + } else { + SystemTagCreator creator = VmSystemTags.BOOT_MODE.newSystemTagCreator(self.getUuid()); + creator.tag = VmSystemTags.BOOT_MODE.instantiateTag(map( + e(VmSystemTags.BOOT_MODE_TOKEN, msg.getBootMode()) + )); + creator.recreate = true; + creator.create(); + } - originLevel = msg.getBootMode(); + bootModeChanged[0] = true; trigger.next(); } @@ -3407,6 +3760,10 @@ public void handle(ErrorCode errCode, Map data) { public void handle(Map data) { APISetVmBootModeEvent evt = new APISetVmBootModeEvent(msg.getId()); bus.publish(evt); + + if (bootModeChanged[0]) { + vidm.deleteAllDeviceAddressesByVm(self.getUuid()); + } } }).start(); } @@ -3417,14 +3774,63 @@ private void handle(APIDeleteVmBootModeMsg msg) { bus.publish(evt); } + private void setVmHostName(String vmInstanceUuid, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain().setName(String.format("set-hostname-%s", vmInstanceUuid)); + chain.allowEmptyFlow(); + chain.getData().put(VmInstanceConstant.Params.VmInstanceUuid.toString(), vmInstanceUuid); + + final List exts = pluginRgty.getExtensionList(SetVmHostNameFlowInterface.class); + for (SetVmHostNameFlowInterface ext : exts) { + chain.then(ext.getSetVmHostNameFlow()); + } + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + private void handle(APIDeleteVmHostnameMsg msg) { APIDeleteVmHostnameEvent evt = new APIDeleteVmHostnameEvent(msg.getId()); + String hostname = VmSystemTags.HOSTNAME.getTokenByResourceUuid(self.getUuid(), VmSystemTags.HOSTNAME_TOKEN); + if (hostname == null || hostname.isEmpty()) { + bus.publish(evt); + return; + } + VmSystemTags.HOSTNAME.delete(self.getUuid()); - bus.publish(evt); + setVmHostName(msg.getVmInstanceUuid(), new Completion(msg) { + @Override + public void success() { + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + /* recover the hostName */ + SystemTagCreator creator = VmSystemTags.HOSTNAME.newSystemTagCreator(self.getUuid()); + creator.setTagByTokens(map( + e(VmSystemTags.HOSTNAME_TOKEN, hostname) + )); + creator.create(); + + evt.setError(errorCode); + bus.publish(evt); + } + }); + + } private void handle(APISetVmHostnameMsg msg) { - if (!VmSystemTags.HOSTNAME.hasTag(self.getUuid())) { + String hostname = VmSystemTags.HOSTNAME.getTokenByResourceUuid(self.getUuid(), VmSystemTags.HOSTNAME_TOKEN); + if (hostname == null || hostname.isEmpty()) { SystemTagCreator creator = VmSystemTags.HOSTNAME.newSystemTagCreator(self.getUuid()); creator.setTagByTokens(map( e(VmSystemTags.HOSTNAME_TOKEN, msg.getHostname()) @@ -3437,7 +3843,26 @@ private void handle(APISetVmHostnameMsg msg) { } APISetVmHostnameEvent evt = new APISetVmHostnameEvent(msg.getId()); - bus.publish(evt); + setVmHostName(msg.getVmInstanceUuid(), new Completion(msg) { + @Override + public void success() { + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + if (hostname != null && !hostname.isEmpty()) { + VmSystemTags.HOSTNAME.update(self.getUuid(), VmSystemTags.HOSTNAME.instantiateTag( + map(e(VmSystemTags.HOSTNAME_TOKEN, hostname)) + )); + } else { + VmSystemTags.HOSTNAME.delete(self.getUuid()); + } + + evt.setError(errorCode); + bus.publish(evt); + } + }); } private void handle(final APIGetVmConsoleAddressMsg msg) { @@ -3463,6 +3888,7 @@ public void run(MessageReply reply) { creply.setPort(hr.getPort()); creply.setProtocol(hr.getProtocol()); creply.setVdiPortInfo(hr.getVdiPortInfo()); + creply.setPath(hr.getPath()); } bus.reply(msg, creply); @@ -3489,6 +3915,8 @@ private void handle(APIGetVmDeviceAddressMsg msg) { GetVmDeviceAddressMsg gmsg = new GetVmDeviceAddressMsg(); if (self.getHostUuid() == null || self.getState() != VmInstanceState.Running) { reply.setError(operr("VM[uuid:%s] state is not Running.", msg.getUuid())); + bus.reply(msg, reply); + return; } gmsg.setHostUuid(self.getHostUuid()); @@ -3516,11 +3944,100 @@ public void run(MessageReply r) { } private void handle(APISetVmClockTrackMsg msg) { - APISetVmClockTrackEvent evt = new APISetVmClockTrackEvent(msg.getId()); - ResourceConfig rc = rcf.getResourceConfig(VmGlobalConfig.VM_CLOCK_TRACK.getIdentity()); - rc.updateValue(msg.getVmInstanceUuid(), msg.getTrack()); - evt.setInventory(getSelfInventory()); - bus.publish(evt); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format("set-vm-clock-track-%s", msg.getUuid()); + } + + @Override + public void run(final SyncTaskChain chain) { + APISetVmClockTrackEvent event = new APISetVmClockTrackEvent(msg.getId()); + setVmClockTrack(msg, new Completion(chain) { + @Override + public void success() { + refreshVO(); + event.setInventory(getSelfInventory()); + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + + @SuppressWarnings("rawtypes") + private void setVmClockTrack(APISetVmClockTrackMsg msg, Completion completion) { + FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("set-vm-clock-track-for-%s", msg.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "set-QGA-sync-clock-task"; + + @Override + public boolean skip(Map data) { + return msg.isSyncAfterVMResume() == null && msg.getIntervalInSeconds() == null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + // sync clock by QGA + SetVmQgaSyncClockTaskMsg syncMsg = new SetVmQgaSyncClockTaskMsg(); + syncMsg.setVmInstanceUuid(msg.getVmInstanceUuid()); + if (msg.isSyncAfterVMResume() != null) { + syncMsg.setSyncAfterVMResume(msg.isSyncAfterVMResume()); + } + if (msg.getIntervalInSeconds() != null) { + syncMsg.setIntervalInSeconds(msg.getIntervalInSeconds()); + } + + bus.makeTargetServiceIdByResourceUuid(syncMsg, VmInstanceConstant.SERVICE_ID, syncMsg.getVmInstanceUuid()); + bus.send(syncMsg, new CloudBusCallBack(trigger, msg) { + @Override + public void run(MessageReply r) { + if (r.isSuccess()) { + trigger.next(); + return; + } + + trigger.fail(r.getError()); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "set-vm-clock-track"; + + @Override + public void run(FlowTrigger trigger, Map data) { + // sync clock (Real-time Clock) + ResourceConfig rc = rcf.getResourceConfig(VmGlobalConfig.VM_CLOCK_TRACK.getIdentity()); + rc.updateValue(msg.getVmInstanceUuid(), msg.getTrack()); + trigger.next(); + } + }); + + chain.error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + completion.success(); + } + }).start(); } private void handle(APISetVmBootOrderMsg msg) { @@ -4191,9 +4708,9 @@ private List getAttachableL3Network(String accountUuid) { q.setParameter("l3State", L3NetworkState.Enabled); q.setParameter("uuid", self.getUuid()); - + List attachedL3Uuids = Q.New(VmNicVO.class).select(VmNicVO_.l3NetworkUuid).eq(VmNicVO_.vmInstanceUuid, self.getUuid()).listValues(); List l3s = q.getResultList(); - l3s = l3s.stream().filter(l3 -> !IpRangeHelper.getNormalIpRanges(l3).isEmpty()).collect(Collectors.toList()); + l3s = l3s.stream().filter(l3 -> !IpRangeHelper.getNormalIpRanges(l3).isEmpty() || (!l3.enableIpAddressAllocation() && !attachedL3Uuids.contains(l3.getUuid()))).collect(Collectors.toList()); return L3NetworkInventory.valueOf(l3s); } @@ -4256,7 +4773,7 @@ protected List scripts() { l3s = l3s.stream().filter(l3 -> !vmL3Uuids.contains(l3.getUuid())).collect(Collectors.toList()); } - l3s = l3s.stream().filter(l3 -> !IpRangeHelper.getNormalIpRanges(l3).isEmpty()).collect(Collectors.toList()); + l3s = l3s.stream().filter(l3 -> !IpRangeHelper.getNormalIpRanges(l3).isEmpty() || !l3.enableIpAddressAllocation()).collect(Collectors.toList()); return L3NetworkInventory.valueOf(l3s); } @@ -4427,9 +4944,16 @@ public void handle(Map data) { final VmInstanceSpec.IsoSpec isoSpec = spec.getDestIsoList().stream() .filter(s -> s.getImageUuid().equals(isoUuid)) .findAny() - .get(); + .orElse(null); targetVmCdRomVO.setIsoUuid(isoUuid); - targetVmCdRomVO.setIsoInstallPath(isoSpec.getInstallPath()); + if (isoSpec != null) { + targetVmCdRomVO.setIsoInstallPath(isoSpec.getInstallPath()); + targetVmCdRomVO.setProtocol(isoSpec.getProtocol()); + } else { + targetVmCdRomVO.setIsoInstallPath(null); + targetVmCdRomVO.setProtocol(null); + } + dbf.update(targetVmCdRomVO); new IsoOperator().syncVmIsoSystemTag(self.getUuid()); completion.success(); @@ -4596,6 +5120,55 @@ public String getName() { }); } + private void handle(final APIChangeVmNicStateMsg msg) { + final APIChangeVmNicStateEvent evt = new APIChangeVmNicStateEvent(msg.getId()); + final VmInstanceSpec spec = buildSpecFromInventory(getSelfInventory(), VmOperation.ChangeNicState); + + if (Q.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).eq(VmNicVO_.state, VmNicState.fromState(msg.getState())).isExists()) { + evt.setInventory(VmInstanceInventory.valueOf(self)); + bus.publish(evt); + return; + } + + if (VmInstanceState.Stopped.toString().equals(spec.getVmInventory().getState())) { + if (msg.getState().equals(VmNicState.enable.toString())) { + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).set(VmNicVO_.state, VmNicState.enable).update(); + } else { + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).set(VmNicVO_.state, VmNicState.disable).update(); + } + self = dbf.reload(self); + evt.setInventory(VmInstanceInventory.valueOf(self)); + bus.publish(evt); + return; + } + + ChangeVmNicStateOnHypervisorMsg dmsg = new ChangeVmNicStateOnHypervisorMsg(); + dmsg.setHostUuid(spec.getVmInventory().getHostUuid()); + dmsg.setVmInstanceUuid(spec.getVmInventory().getUuid()); + dmsg.setNic(spec.getDestNics().stream().filter(nic -> nic.getUuid().equals(msg.getVmNicUuid())).collect(Collectors.toList()).get(0)); + dmsg.setState(msg.getState()); + bus.makeTargetServiceIdByResourceUuid(dmsg, HostConstant.SERVICE_ID, spec.getVmInventory().getHostUuid()); + bus.send(dmsg, new CloudBusCallBack(null) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + if (msg.getState().equals(VmNicState.enable.toString())) { + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).set(VmNicVO_.state, VmNicState.enable).update(); + } else { + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).set(VmNicVO_.state, VmNicState.disable).update(); + } + self = dbf.reload(self); + extEmitter.afterChangeVmNicState(msg.getVmNicUuid(), msg.getState()); + evt.setInventory(VmInstanceInventory.valueOf(self)); + bus.publish(evt); + } else { + evt.setError(reply.getError()); + bus.publish(evt); + } + } + }); + } + private void handle(final APIDetachL3NetworkFromVmMsg msg) { final APIDetachL3NetworkFromVmEvent evt = new APIDetachL3NetworkFromVmEvent(msg.getId()); detachNicInQueue(msg, msg.getVmNicUuid(), new ReturnValueCompletion(msg) { @@ -4674,24 +5247,17 @@ public void run(VmDefaultL3NetworkChangedExtensionPoint ext) { self = dbf.updateAndRefresh(self); } + @SuppressWarnings({"rawtypes", "unchecked"}) private void detachNic(final String nicUuid, boolean releaseNic, boolean isRollback, boolean dbOnly, final Completion completion) { - VmNicVO vmNicVO = CollectionUtils.find(self.getVmNics(), new Function() { - @Override - public VmNicVO call(VmNicVO arg) { - return arg.getUuid().equals(nicUuid) ? arg : null; - } - }); + VmNicVO vmNicVO = CollectionUtils.find(self.getVmNics(), arg -> arg.getUuid().equals(nicUuid) ? arg : null); if (vmNicVO == null) { completion.success(); return; } final VmNicInventory nic = VmNicInventory.valueOf( - CollectionUtils.find(self.getVmNics(), new Function() { - @Override - public VmNicVO call(VmNicVO arg) { - return arg.getUuid().equals(nicUuid) ? arg : null; - } - }) + CollectionUtils.find( + self.getVmNics(), + (Function) arg -> arg.getUuid().equals(nicUuid) ? arg : null) ); for (VmDetachNicExtensionPoint ext : pluginRgty.getExtensionList(VmDetachNicExtensionPoint.class)) { @@ -4699,12 +5265,7 @@ public VmNicVO call(VmNicVO arg) { } CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmDetachNicExtensionPoint.class), - new ForEachFunction() { - @Override - public void run(VmDetachNicExtensionPoint arg) { - arg.beforeDetachNic(nic); - } - }); + arg -> arg.beforeDetachNic(nic)); final VmInstanceSpec spec = buildSpecFromInventory(getSelfInventory(), VmOperation.DetachNic); spec.setVmInventory(VmInstanceInventory.valueOf(self)); @@ -4723,7 +5284,7 @@ public void run(VmDetachNicExtensionPoint arg) { flowChain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); flowChain.getData().put(Params.ReleaseNicAfterDetachNic.toString(), releaseNic); setAdditionalFlow(flowChain, spec); - if (!dbOnly && self.getState() == VmInstanceState.Running && nic.getL3NetworkUuid() != null) { + if (!dbOnly) { flowChain.then(new VmDetachNicOnHypervisorFlow()); } flowChain.then(new VmReleaseResourceOnDetachingNicFlow()); @@ -4750,12 +5311,7 @@ public void handle(Map data) { selectDefaultL3(nic); removeStaticIp(); CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmDetachNicExtensionPoint.class), - new ForEachFunction() { - @Override - public void run(VmDetachNicExtensionPoint arg) { - arg.afterDetachNic(nic); - } - }); + arg -> arg.afterDetachNic(nic)); completion.success(); } @@ -4770,12 +5326,7 @@ private void removeStaticIp() { @Override public void handle(final ErrorCode errCode, Map data) { CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmDetachNicExtensionPoint.class), - new ForEachFunction() { - @Override - public void run(VmDetachNicExtensionPoint arg) { - arg.failedToDetachNic(nic, errCode); - } - }); + arg -> arg.failedToDetachNic(nic, errCode)); completion.fail(errCode); } }).start(); @@ -4827,217 +5378,72 @@ public String getName() { } private void changeOffering(APIChangeInstanceOfferingMsg msg, final Completion completion) { - final InstanceOfferingVO newOfferingVO = dbf.findByUuid(msg.getInstanceOfferingUuid(), InstanceOfferingVO.class); - final InstanceOfferingInventory inv = InstanceOfferingInventory.valueOf(newOfferingVO); - final VmInstanceInventory vm = getSelfInventory(); - - List exts = pluginRgty.getExtensionList(ChangeInstanceOfferingExtensionPoint.class); - exts.forEach(ext -> ext.preChangeInstanceOffering(vm, inv)); - CollectionUtils.safeForEach(exts, ext -> ext.beforeChangeInstanceOffering(vm, inv)); - - changeCpuAndMemory(inv.getCpuNum(), inv.getMemorySize(), new Completion(completion) { - @Override - public void success() { - self.setAllocatorStrategy(inv.getAllocatorStrategy()); - self.setInstanceOfferingUuid(msg.getInstanceOfferingUuid()); - self = dbf.updateAndRefresh(self); - CollectionUtils.safeForEach(exts, ext -> ext.afterChangeInstanceOffering(vm, inv)); - completion.success(); - } - - @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); - } - }); - } - - private void changeCpuAndMemory(final int cpuNum, final long memorySize, final Completion completion) { - if (self.getState() == VmInstanceState.Stopped) { - self.setCpuNum(cpuNum); - self.setMemorySize(memorySize); - self = dbf.updateAndRefresh(self); - completion.success(); - return; - } - - final int oldCpuNum = self.getCpuNum(); - final long oldMemorySize = self.getMemorySize(); - - class AlignmentStruct { - long alignedMemory; - } - - final AlignmentStruct struct = new AlignmentStruct(); - struct.alignedMemory = memorySize; - - FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); - chain.setName(String.format("change-cpu-and-memory-of-vm-%s", self.getUuid())); - chain.then(new NoRollbackFlow() { - String __name__ = "align-memory"; - - @Override - public void run(FlowTrigger chain, Map data) { - // align memory - long increaseMemory = memorySize - oldMemorySize; - long remainderMemory = increaseMemory % SizeUnit.MEGABYTE.toByte(128); - if (increaseMemory != 0 && remainderMemory != 0) { - if (remainderMemory < SizeUnit.MEGABYTE.toByte(128) / 2) { - increaseMemory = increaseMemory / SizeUnit.MEGABYTE.toByte(128) * SizeUnit.MEGABYTE.toByte(128); - } else { - increaseMemory = (increaseMemory / SizeUnit.MEGABYTE.toByte(128) + 1) * SizeUnit.MEGABYTE.toByte(128); - } - - if (increaseMemory == 0) { - struct.alignedMemory = oldMemorySize + SizeUnit.MEGABYTE.toByte(128); - } else { - struct.alignedMemory = oldMemorySize + increaseMemory; - } - - logger.debug(String.format("automatically align memory from %s to %s", memorySize, struct.alignedMemory)); - } - chain.next(); - } - }).then(new Flow() { - String __name__ = String.format("allocate-host-capacity-on-host-%s", self.getHostUuid()); - boolean result = false; - - @Override - public void run(FlowTrigger chain, Map data) { - DesignatedAllocateHostMsg msg = new DesignatedAllocateHostMsg(); - msg.setCpuCapacity(cpuNum - oldCpuNum); - msg.setMemoryCapacity(struct.alignedMemory - oldMemorySize); - msg.setOldMemoryCapacity(oldMemorySize); - msg.setAllocatorStrategy(HostAllocatorConstant.DESIGNATED_HOST_ALLOCATOR_STRATEGY_TYPE); - msg.setVmInstance(VmInstanceInventory.valueOf(self)); - if (self.getImageUuid() != null && dbf.isExist(self.getImageUuid(), ImageVO.class)) { - msg.setImage(ImageInventory.valueOf(dbf.findByUuid(self.getImageUuid(), ImageVO.class))); - } - msg.setHostUuid(self.getHostUuid()); - msg.setFullAllocate(false); - msg.setL3NetworkUuids(VmNicHelper.getL3Uuids(VmNicInventory.valueOf(self.getVmNics()))); - msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); - bus.send(msg, new CloudBusCallBack(chain) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - ErrorCode err = operr("host[uuid:%s] capacity is not enough to offer cpu[%s], memory[%s bytes]", - self.getHostUuid(), cpuNum - oldCpuNum, struct.alignedMemory - oldMemorySize); - err.setCause(reply.getError()); - chain.fail(err); - } else { - result = true; - logger.debug(String.format("reserve memory %s bytes and cpu %s on host[uuid:%s]", memorySize - self.getMemorySize(), cpuNum - self.getCpuNum(), self.getHostUuid())); - chain.next(); - } - } - }); - } - - @Override - public void rollback(FlowRollback chain, Map data) { - if (result) { - ReturnHostCapacityMsg msg = new ReturnHostCapacityMsg(); - msg.setCpuCapacity(cpuNum - oldCpuNum); - msg.setMemoryCapacity(struct.alignedMemory - oldMemorySize); - msg.setHostUuid(self.getHostUuid()); - msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); - bus.send(msg); - } - - chain.rollback(); - } - }).then(new NoRollbackFlow() { - String __name__ = String.format("change-cpu-of-vm-%s", self.getUuid()); - - @Override - public void run(FlowTrigger chain, Map data) { - if (cpuNum != self.getCpuNum()) { - IncreaseVmCpuMsg msg = new IncreaseVmCpuMsg(); - msg.setVmInstanceUuid(self.getUuid()); - msg.setHostUuid(self.getHostUuid()); - msg.setCpuNum(cpuNum); - bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, self.getHostUuid()); - bus.send(msg, new CloudBusCallBack(chain) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - logger.error("failed to update cpu"); - chain.fail(reply.getError()); - } else { - IncreaseVmCpuReply r = reply.castReply(); - self.setCpuNum(r.getCpuNum()); - chain.next(); - } - } - }); - } else { - chain.next(); - } - } - }).then(new NoRollbackFlow() { - String __name__ = String.format("change-memory-of-vm-%s", self.getUuid()); - - @Override - public void run(FlowTrigger chain, Map data) { - if (struct.alignedMemory != self.getMemorySize()) { - IncreaseVmMemoryMsg msg = new IncreaseVmMemoryMsg(); - msg.setVmInstanceUuid(self.getUuid()); - msg.setHostUuid(self.getHostUuid()); - msg.setMemorySize(struct.alignedMemory); - bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, self.getHostUuid()); - bus.send(msg, new CloudBusCallBack(chain) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - logger.error("failed to update memory"); - chain.fail(reply.getError()); - } else { - IncreaseVmMemoryReply r = reply.castReply(); - self.setMemorySize(r.getMemorySize()); - chain.next(); - } - } - }); - } else { - chain.next(); - } - } - }).done(new FlowDoneHandler(completion) { - @Override - public void handle(Map data) { - dbf.update(self); - VmCanonicalEvents.VmConfigChangedData d = new VmCanonicalEvents.VmConfigChangedData(); - d.setVmUuid(self.getUuid()); - d.setInv(getSelfInventory()); - d.setAccoundUuid(acntMgr.getOwnerAccountUuidOfResource(self.getUuid())); - evtf.fire(VmCanonicalEvents.VM_CONFIG_CHANGED_PATH, d); - completion.success(); - } - }).error(new FlowErrorHandler(completion) { + final InstanceOfferingVO newOfferingVO = dbf.findByUuid(msg.getInstanceOfferingUuid(), InstanceOfferingVO.class); + final InstanceOfferingInventory inv = InstanceOfferingInventory.valueOf(newOfferingVO); + final VmInstanceInventory vm = getSelfInventory(); + + List exts = pluginRgty.getExtensionList(ChangeInstanceOfferingExtensionPoint.class); + exts.forEach(ext -> ext.preChangeInstanceOffering(vm, inv)); + CollectionUtils.safeForEach(exts, ext -> ext.beforeChangeInstanceOffering(vm, inv)); + + UpdateVmOnHypervisorMsg innerMsg = new UpdateVmOnHypervisorMsg(); + innerMsg.setSpec(VmInstanceUtils.convertToSpec(msg, inv, self)); + bus.makeTargetServiceIdByResourceUuid(innerMsg, HostConstant.SERVICE_ID, innerMsg.getSpec().getHostUuid()); + bus.send(innerMsg, new CloudBusCallBack(msg) { @Override - public void handle(ErrorCode errCode, Map data) { - completion.fail(errCode); + public void run(MessageReply innerReply) { + if (!innerReply.isSuccess()) { + completion.fail(Platform.operr(innerReply.getError(), + "Failed to update vm[uuid=%s] on hypervisor.", self.getUuid())); + return; + } + final UpdateVmOnHypervisorReply casedReply = innerReply.castReply(); + updateVmInstanceFromHypervisorReply(casedReply); + self.setAllocatorStrategy(inv.getAllocatorStrategy()); + self.setInstanceOfferingUuid(msg.getInstanceOfferingUuid()); + self = dbf.updateAndRefresh(self); + fireVmConfigChangedEvent(getSelfInventory()); + CollectionUtils.safeForEach(exts, ext -> ext.afterChangeInstanceOffering(vm, inv)); + + if (casedReply.getIgnoredErrors().isEmpty()) { + completion.success(); + return; + } + final ErrorCodeList list = new ErrorCodeList(); + list.getCauses().addAll(casedReply.getIgnoredErrors()); + completion.fail(Platform.operr(list, + "Failed to update vm[uuid=%s] on hypervisor: The modification of some properties failed", + self.getUuid())); } - }).start(); + }); } - private void doVmInstanceUpdate(final APIUpdateVmInstanceMsg msg, Completion completion) { + @SuppressWarnings({"rawtypes", "unchecked"}) + private void doVmInstanceUpdate(final UpdateVmInstanceMsg msg, Completion completion) { refreshVO(); - List extensions = new ArrayList(); + List extensions = new ArrayList<>(); final VmInstanceInventory vm = getSelfInventory(); VmInstanceSpec spec = new VmInstanceSpec(); spec.setVmInventory(vm); spec.setCurrentVmOperation(VmOperation.Update); FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("update-vm-instance-%s-in-database", self.getUuid())); + chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); chain.then(new NoRollbackFlow() { + String __name__ = "update-vm-properties-without-cpu-and-memory"; @Override public void run(FlowTrigger trigger, Map data) { boolean update = false; if (msg.getName() != null) { + Boolean unique = VmGlobalConfig.UNIQUE_VM_NAME.value(Boolean.class); + boolean exists = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.name, msg.getName()).notEq(VmInstanceVO_.uuid, self.getUuid()).isExists(); + if (unique && exists) { + trigger.fail(operr("could not create vm, a vm with the name [%s] already exists", msg.getName())); + return; + } self.setName(msg.getName()); update = true; } @@ -5049,20 +5455,7 @@ public void run(FlowTrigger trigger, Map data) { self.setState(VmInstanceState.valueOf(msg.getState())); update = true; if (!vm.getState().equals(msg.getState())) { - extensions.add(new Runnable() { - @Override - public void run() { - logger.debug(String.format("vm[uuid:%s] changed state from %s to %s", self.getUuid(), - vm.getState(), msg.getState())); - - VmCanonicalEvents.VmStateChangedData data = new VmCanonicalEvents.VmStateChangedData(); - data.setVmUuid(self.getUuid()); - data.setOldState(vm.getState()); - data.setNewState(msg.getState()); - data.setInventory(getSelfInventory()); - evtf.fire(VmCanonicalEvents.VM_FULL_STATE_CHANGED_PATH, data); - } - }); + extensions.add(this::onStateUpdated); } } @@ -5070,15 +5463,7 @@ public void run() { self.setDefaultL3NetworkUuid(msg.getDefaultL3NetworkUuid()); update = true; if (!msg.getDefaultL3NetworkUuid().equals(vm.getDefaultL3NetworkUuid())) { - extensions.add(new Runnable() { - @Override - public void run() { - for (VmDefaultL3NetworkChangedExtensionPoint ext : - pluginRgty.getExtensionList(VmDefaultL3NetworkChangedExtensionPoint.class)) { - ext.vmDefaultL3NetworkChanged(vm, vm.getDefaultL3NetworkUuid(), msg.getDefaultL3NetworkUuid()); - } - } - }); + extensions.add(this::onDefaultL3NetworkUpdated); } } @@ -5086,15 +5471,7 @@ public void run() { self.setPlatform(msg.getPlatform()); update = true; if (!msg.getPlatform().equals(vm.getPlatform())) { - extensions.add(new Runnable() { - @Override - public void run() { - for (VmPlatformChangedExtensionPoint ext : - pluginRgty.getExtensionList(VmPlatformChangedExtensionPoint.class)) { - ext.vmPlatformChange(vm, vm.getPlatform(), msg.getPlatform()); - } - } - }); + extensions.add(this::onPlatformUpdated); } } @@ -5103,6 +5480,11 @@ public void run() { update = true; } + if (msg.getReservedMemorySize() != null) { + self.setReservedMemorySize(msg.getReservedMemorySize()); + update = true; + } + if (update) { dbf.update(self); } @@ -5111,23 +5493,73 @@ public void run() { CollectionUtils.safeForEach(extensions, Runnable::run); - if (msg.getCpuNum() != null || msg.getMemorySize() != null) { - int cpuNum = msg.getCpuNum() == null ? self.getCpuNum() : msg.getCpuNum(); - long memory = msg.getMemorySize() == null ? self.getMemorySize() : msg.getMemorySize(); - changeCpuAndMemory(cpuNum, memory, new Completion(trigger) { - @Override - public void success() { - trigger.next(); + trigger.next(); + } + + private void onStateUpdated() { + logger.debug(String.format("vm[uuid:%s] changed state from %s to %s", self.getUuid(), + vm.getState(), msg.getState())); + + VmStateChangedData canonicalEventsData = new VmStateChangedData(); + canonicalEventsData.setVmUuid(self.getUuid()); + canonicalEventsData.setOldState(vm.getState()); + canonicalEventsData.setNewState(msg.getState()); + canonicalEventsData.setInventory(getSelfInventory()); + evtf.fire(VmCanonicalEvents.VM_FULL_STATE_CHANGED_PATH, canonicalEventsData); + } + + private void onDefaultL3NetworkUpdated() { + for (VmDefaultL3NetworkChangedExtensionPoint ext : + pluginRgty.getExtensionList(VmDefaultL3NetworkChangedExtensionPoint.class)) { + ext.vmDefaultL3NetworkChanged(vm, vm.getDefaultL3NetworkUuid(), msg.getDefaultL3NetworkUuid()); + } + } + + private void onPlatformUpdated() { + for (VmPlatformChangedExtensionPoint ext : + pluginRgty.getExtensionList(VmPlatformChangedExtensionPoint.class)) { + ext.vmPlatformChange(vm, vm.getPlatform(), msg.getPlatform()); + } + } + }); + + chain.then(new NoRollbackFlow() { + String __name__ = "update-vm-properties-on-hypervisor"; + + @Override + public boolean skip(Map data) { + final VmInstanceType type = VmInstanceType.valueOf(self.getType()); + return !type.isSupportUpdateOnHypervisor(); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + UpdateVmOnHypervisorMsg innerMsg = new UpdateVmOnHypervisorMsg(); + innerMsg.setSpec(VmInstanceUtils.convertToSpec(msg, self)); + bus.makeTargetServiceIdByResourceUuid(innerMsg, HostConstant.SERVICE_ID, innerMsg.getSpec().getHostUuid()); + bus.send(innerMsg, new CloudBusCallBack(innerMsg) { + @Override + public void run(MessageReply innerReply) { + if (!innerReply.isSuccess()) { + trigger.fail(Platform.operr(innerReply.getError(), + "failed to update vm[uuid=%s] on hypervisor", self.getUuid())); + return; } + final UpdateVmOnHypervisorReply casedReply = innerReply.castReply(); + updateVmInstanceFromHypervisorReply(casedReply); + fireVmConfigChangedEvent(getSelfInventory()); - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + if (casedReply.getIgnoredErrors().isEmpty()) { + trigger.next(); + return; } - }); - } else { - trigger.next(); - } + final ErrorCodeList list = new ErrorCodeList(); + list.getCauses().addAll(casedReply.getIgnoredErrors()); + trigger.fail(Platform.operr(list, + "failed to update vm[uuid=%s] on hypervisor: The modification of some properties failed", + self.getUuid())); + } + }); } }); @@ -5147,6 +5579,35 @@ public void handle(Map data) { } private void handle(final APIUpdateVmInstanceMsg msg) { + APIUpdateVmInstanceEvent evt = new APIUpdateVmInstanceEvent(msg.getId()); + UpdateVmInstanceMsg umsg = new UpdateVmInstanceMsg(); + umsg.setUuid(msg.getUuid()); + umsg.setName(msg.getName()); + umsg.setDescription(msg.getDescription()); + umsg.setDefaultL3NetworkUuid(msg.getDefaultL3NetworkUuid()); + umsg.setCpuNum(msg.getCpuNum()); + umsg.setMemorySize(msg.getMemorySize()); + umsg.setReservedMemorySize(msg.getReservedMemorySize()); + umsg.setPlatform(msg.getPlatform()); + umsg.setState(msg.getState()); + umsg.setGuestOsType(msg.getGuestOsType()); + umsg.setSystemTags(msg.getSystemTags()); + bus.makeTargetServiceIdByResourceUuid(umsg, VmInstanceConstant.SERVICE_ID, umsg.getVmInstanceUuid()); + bus.send(umsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + bus.publish(evt); + return; + } + evt.setInventory(((UpdateVmInstanceReply) reply.castReply()).getInventory()); + bus.publish(evt); + } + }); + } + + private void handle(UpdateVmInstanceMsg msg) { thdf.chainSubmit(new ChainTask(msg) { @Override public String getSyncSignature() { @@ -5155,21 +5616,20 @@ public String getSyncSignature() { @Override public void run(SyncTaskChain chain) { - APIUpdateVmInstanceEvent evt = new APIUpdateVmInstanceEvent(msg.getId()); - + UpdateVmInstanceReply reply = new UpdateVmInstanceReply(); doVmInstanceUpdate(msg, new Completion(msg) { @Override public void success() { refreshVO(); - evt.setInventory(getSelfInventory()); - bus.publish(evt); + reply.setInventory(getSelfInventory()); + bus.reply(msg, reply); chain.next(); } @Override public void fail(ErrorCode errorCode) { - evt.setError(errorCode); - bus.publish(evt); + reply.setError(errorCode); + bus.reply(msg, reply); chain.next(); } }); @@ -5182,9 +5642,17 @@ public String getName() { }); } + private void fireVmConfigChangedEvent(VmInstanceInventory inventory) { + VmCanonicalEvents.VmConfigChangedData d = new VmCanonicalEvents.VmConfigChangedData(); + d.setVmUuid(self.getUuid()); + d.setInv(inventory); + d.setAccoundUuid(acntMgr.getOwnerAccountUuidOfResource(self.getUuid())); + evtf.fire(VmCanonicalEvents.VM_CONFIG_CHANGED_PATH, d); + } + // Specify an iso as the first one, restart vm effective private void updateVmIsoFirstOrder(List systemTags) { - if (systemTags == null || systemTags.isEmpty()) { + if (CollectionUtils.isEmpty(systemTags)) { return; } @@ -5220,10 +5688,14 @@ private void updateVmIsoFirstOrder(List systemTags) { VmCdRomVO targetCdRomVO = cdRomVOS.get(0); String targetCdRomIsoUuid = targetCdRomVO.getIsoUuid(); String path = targetCdRomVO.getIsoInstallPath(); + String protocol = targetCdRomVO.getProtocol(); targetCdRomVO.setIsoUuid(sourceCdRomVO.getIsoUuid()); targetCdRomVO.setIsoInstallPath(sourceCdRomVO.getIsoInstallPath()); + targetCdRomVO.setProtocol(sourceCdRomVO.getProtocol()); + sourceCdRomVO.setIsoUuid(targetCdRomIsoUuid); sourceCdRomVO.setIsoInstallPath(path); + sourceCdRomVO.setIsoInstallPath(protocol); new SQLBatch() { @Override @@ -5234,6 +5706,23 @@ protected void scripts() { }.execute(); } + private void updateVmInstanceFromHypervisorReply(UpdateVmOnHypervisorReply reply) { + if (!reply.hasAnythingUpdated()) { + return; + } + refreshVO(); + if (reply.isCpuUpdated()) { + self.setCpuNum(reply.getCpuUpdatedTo()); + } + if (reply.isMemoryUpdated()) { + self.setMemorySize(reply.getMemoryUpdatedTo()); + } + if (reply.isNameUpdated()) { + self.setName(reply.getNameUpdatedTo()); + } + dbf.update(self); + } + @Transactional(readOnly = true) private List getAttachableVolume(String accountUuid) { if (!self.getState().equals(VmInstanceState.Stopped) && self.getPlatform().equals(ImagePlatform.Other.toString())) { @@ -5520,7 +6009,51 @@ public void handle(ErrorCode errCode, Map data) { } protected void afterAttachNic(VmNicInventory nicInventory, boolean applyToBackend, Completion completion) { - completion.success(); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain().setName(String.format("vm-after-attach-nic-%s", nicInventory.getUuid())); + chain.allowEmptyFlow(); + for (final VmAfterAttachNicExtensionPoint ns : pluginRgty.getExtensionList(VmAfterAttachNicExtensionPoint.class)) { + Flow flow = new Flow() { + @Override + public void run(final FlowTrigger chain, Map data) { + logger.debug(String.format("VmAfterAttachNicExtensionPoint[%s] starts executing", ns.getClass().getName())); + ns.afterAttachNic(nicInventory.getUuid(), getSelfInventory(), new Completion(chain) { + @Override + public void success() { + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + chain.fail(errorCode); + } + }); + } + + @Override + public void rollback(final FlowRollback chain, Map data) { + logger.debug(String.format("VmAfterAttachNicExtensionPoint[%s] started rolling back", ns.getClass().getName())); + ns.afterAttachNicRollback(nicInventory.getUuid(), getSelfInventory(), new NoErrorCompletion(chain) { + @Override + public void done() { + chain.rollback(); + } + }); + } + }; + + chain.then(flow); + } + chain.error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode err, Map data) { + completion.fail(err); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).start(); } protected void afterAttachNic(VmNicInventory nicInventory, Completion completion) { @@ -5531,30 +6064,64 @@ protected void afterDetachNic(VmNicInventory nicInventory, boolean isRollback, C completion.success(); } - private void handle(APIChangeVmNicNetworkMsg msg) { - final APIChangeVmNicNetworkEvent evt = new APIChangeVmNicNetworkEvent(msg.getId()); - + private void handle(ChangeVmNicNetworkMsg msg) { + ChangeVmNicNetworkReply reply = new ChangeVmNicNetworkReply(); VmNicVO vmNicVO = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); - L3NetworkVO destL3NetowrkVO = dbf.findByUuid(msg.getDestL3NetworkUuid(), L3NetworkVO.class); + L3NetworkVO destL3NetworkVO = dbf.findByUuid(msg.getDestL3NetworkUuid(), L3NetworkVO.class); VmNicInventory nic = VmNicInventory.valueOf(vmNicVO); - L3NetworkInventory destL3 = L3NetworkInventory.valueOf(destL3NetowrkVO); + L3NetworkInventory destL3 = L3NetworkInventory.valueOf(destL3NetworkVO); changeVmNicNetwork(msg, nic, destL3, new ReturnValueCompletion(msg) { @Override public void success(VmNicInventory returnValue) { - evt.setInventory(returnValue); - bus.publish(evt); + String originalL3Uuid = nic.getL3NetworkUuid(); + new StaticIpOperator().deleteStaticIpByVmUuidAndL3Uuid(self.getUuid(), originalL3Uuid); + reply.setInventory(returnValue); + bus.reply(msg, reply); } @Override public void fail(ErrorCode errorCode) { - evt.setError(errorCode); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(APIChangeVmNicNetworkMsg msg) { + final APIChangeVmNicNetworkEvent evt = new APIChangeVmNicNetworkEvent(msg.getId()); + + refreshVO(); + ErrorCode allowed = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); + if (allowed != null) { + evt.setError(allowed); + bus.publish(evt); + return; + } + + ChangeVmNicNetworkMsg cmsg = new ChangeVmNicNetworkMsg(); + cmsg.setDestL3NetworkUuid(msg.getDestL3NetworkUuid()); + cmsg.setVmNicUuid(msg.getVmNicUuid()); + cmsg.setStaticIp(msg.getStaticIp()); + cmsg.setVmInstanceUuid(msg.getVmInstanceUuid()); + cmsg.setRequiredIpMap(msg.getRequiredIpMap()); + cmsg.setSystemTags(msg.getSystemTags()); + bus.makeTargetServiceIdByResourceUuid(cmsg, VmInstanceConstant.SERVICE_ID, cmsg.getVmInstanceUuid()); + bus.send(cmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + bus.publish(evt); + return; + } + evt.setInventory(((ChangeVmNicNetworkReply) reply.castReply()).getInventory()); bus.publish(evt); } }); } - private void changeVmNicNetwork(APIChangeVmNicNetworkMsg msg, VmNicInventory nic, L3NetworkInventory destL3, final ReturnValueCompletion completion) { + private void changeVmNicNetwork(ChangeVmNicNetworkMsg msg, VmNicInventory nic, L3NetworkInventory destL3, final ReturnValueCompletion completion) { thdf.chainSubmit(new ChainTask(completion) { @Override public String getSyncSignature() { @@ -5564,23 +6131,12 @@ public String getSyncSignature() { @Override @Deferred public void run(final SyncTaskChain chain) { - refreshVO(); - ErrorCode allowed = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); - if (allowed != null) { - completion.fail(allowed); - chain.next(); - return; - } - class SetStaticIp { private boolean isSet = false; Map> staticIpMap = null; void set() { - if (msg instanceof APIChangeVmNicNetworkMsg) { - APIChangeVmNicNetworkMsg amsg = (APIChangeVmNicNetworkMsg) msg; - staticIpMap = amsg.getRequiredIpMap(); - } + staticIpMap = msg.getRequiredIpMap(); if (staticIpMap == null || staticIpMap.isEmpty()) { return; @@ -5620,13 +6176,31 @@ public void run() { final VmInstanceSpec spec = buildSpecFromInventory(getSelfInventory(), VmOperation.ChangeNicNetwork); spec.setVmInventory(VmInstanceInventory.valueOf(self)); spec.setDestNics(list(nic)); + L3NetworkVO l3VO = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + spec.setL3Networks(list(new VmNicSpec(L3NetworkInventory.valueOf(l3VO)))); flowChain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); + flowChain.getData().put(VmInstanceConstant.Params.L3NetworkInventory.toString(), destL3); + + flowChain.then(new NoRollbackFlow() { + String __name__ = "before-change-nic-network-extension"; + + @Override + public void run(FlowTrigger trigger, Map data) { + CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmUpdateNicExtensionPoint.class), + arg -> arg.beforeUpdateNic(spec, nic, destL3)); + trigger.next(); + } + }); flowChain.then(new NoRollbackFlow() { String __name__ = "allocate-ip-for-change-nic-network"; @Override public void run(FlowTrigger trigger, Map data) { + if (!destL3.enableIpAddressAllocation()) { + trigger.next(); + return; + } allocateIp(destL3, nic, new ReturnValueCompletion>(chain) { @Override public void success(List returnValue) { @@ -5635,15 +6209,208 @@ public void success(List returnValue) { } @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + if (self.getState() == VmInstanceState.Running) { + flowChain.then(new VmReleaseNetworkServiceOnChangeIPFlow()); + } + + flowChain.then(new Flow() { + String __name__ = "update-nic-old-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + SQL.New(UsedIpVO.class).eq(UsedIpVO_.vmNicUuid, nic.getUuid()) + .set(UsedIpVO_.vmNicUuid, null).update(); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + for (UsedIpInventory ip : nic.getUsedIps()) { + SQL.New(UsedIpVO.class).eq(UsedIpVO_.uuid, ip.getUuid()) + .set(UsedIpVO_.vmNicUuid, nic.getUuid()).update(); + } + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, nic.getUuid()) + .set(VmNicVO_.l3NetworkUuid, nic.getL3NetworkUuid()) + .set(VmNicVO_.usedIpUuid, nic.getUsedIpUuid()) + .set(VmNicVO_.ip, nic.getIp()) + .set(VmNicVO_.gateway, nic.getGateway()) + .set(VmNicVO_.netmask, nic.getNetmask()).update(); + trigger.rollback(); + } + }); + + flowChain.then(new NoRollbackFlow() { + String __name__ = "update-nic-ip-for-disable-ipam"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (destL3.enableIpAddressAllocation()) { + trigger.next(); + return; + } + if (self.getDefaultL3NetworkUuid().equals(nic.getL3NetworkUuid())) { + self.setDefaultL3NetworkUuid(destL3.getUuid()); + } + self = dbf.updateAndRefresh(self); + VmNicVO nicVO = dbf.findByUuid(nic.getUuid(), VmNicVO.class); + final Map nicNetworkInfo = new StaticIpOperator().getNicNetworkInfoBySystemTag(msg.getSystemTags()); + List voNewList = new ArrayList<>(); + List voOldList = Q.New(UsedIpVO.class).eq(UsedIpVO_.vmNicUuid, nicVO.getUuid()).list(); + NicIpAddressInfo nicIpAddressInfo = nicNetworkInfo.get(msg.getDestL3NetworkUuid()); + if (nicIpAddressInfo == null) { + nicVO.setUsedIpUuid(null); + nicVO.setIp(null); + nicVO.setGateway(null); + nicVO.setNetmask(null); + nicVO.setL3NetworkUuid(msg.getDestL3NetworkUuid()); + } else { + if (nicIpAddressInfo.ipv6Address != null && !nicIpAddressInfo.ipv6Address.isEmpty()) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIp(IPv6NetworkUtils.getIpv6AddressCanonicalString(nicIpAddressInfo.ipv6Address)); + vo.setNetmask(IPv6NetworkUtils.getFormalNetmaskOfNetworkCidr(nicIpAddressInfo.ipv6Address + "/" + nicIpAddressInfo.ipv6Prefix)); + vo.setGateway(nicIpAddressInfo.ipv6Gateway.isEmpty() ? "" : IPv6NetworkUtils.getIpv6AddressCanonicalString(nicIpAddressInfo.ipv6Gateway)); + vo.setIpVersion(IPv6Constants.IPv6); + vo.setVmNicUuid(msg.getVmNicUuid()); + vo.setL3NetworkUuid(msg.getDestL3NetworkUuid()); + vo.setIpRangeUuid(new StaticIpOperator().getIpRangeUuid(vo.getL3NetworkUuid(), vo.getIp())); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(nicIpAddressInfo.ipv4Address); + nicVO.setGateway(nicIpAddressInfo.ipv4Gateway); + nicVO.setNetmask(nicIpAddressInfo.ipv4Netmask); + nicVO.setL3NetworkUuid(msg.getDestL3NetworkUuid()); + voNewList.add(vo); + } + if (nicIpAddressInfo.ipv4Address != null && !nicIpAddressInfo.ipv4Address.isEmpty()) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + if (NetworkUtils.isIpv4Address(nicIpAddressInfo.ipv4Address)) { + vo.setIpInLong(NetworkUtils.ipv4StringToLong(nicIpAddressInfo.ipv4Address)); + vo.setIp(nicIpAddressInfo.ipv4Address); + vo.setNetmask(nicIpAddressInfo.ipv4Netmask); + vo.setGateway(nicIpAddressInfo.ipv4Gateway); + vo.setIpVersion(IPv6Constants.IPv4); + vo.setVmNicUuid(msg.getVmNicUuid()); + vo.setL3NetworkUuid(msg.getDestL3NetworkUuid()); + vo.setIpInLong(NetworkUtils.ipv4StringToLong(vo.getIp())); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setIpRangeUuid(new StaticIpOperator().getIpRangeUuid(vo.getL3NetworkUuid(), vo.getIp())); + nicVO.setUsedIpUuid(vo.getUuid()); + nicVO.setIp(nicIpAddressInfo.ipv4Address); + nicVO.setGateway(nicIpAddressInfo.ipv4Gateway); + nicVO.setNetmask(nicIpAddressInfo.ipv4Netmask); + nicVO.setL3NetworkUuid(msg.getDestL3NetworkUuid()); + voNewList.add(vo); + } + } + } + dbf.persistCollection(voNewList); + dbf.updateAndRefresh(nicVO); + dbf.removeCollection(voOldList, UsedIpVO.class); + data.put(VmInstanceConstant.Params.VmNicInventory.toString(), nicVO); + data.put(VmInstanceConstant.Params.vmInventory.toString(), getSelfInventory()); + trigger.next(); + } + }); + + flowChain.then(new NoRollbackFlow() { + String __name__ = "update-nic-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (!destL3.enableIpAddressAllocation()) { + trigger.next(); + return; + } + if (self.getDefaultL3NetworkUuid().equals(nic.getL3NetworkUuid())) { + self.setDefaultL3NetworkUuid(destL3.getUuid()); + } + self = dbf.updateAndRefresh(self); + VmNicVO nicVO = dbf.findByUuid(nic.getUuid(), VmNicVO.class); + List allocateIps = (List) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_ips.toString()); + List ipVOS = new ArrayList<>(); + for (UsedIpInventory ip : allocateIps) { + /* update usedIpVo */ + UsedIpVO ipVO = dbf.findByUuid(ip.getUuid(), UsedIpVO.class); + ipVO.setVmNicUuid(nic.getUuid()); + ipVOS.add(ipVO); + if (allocateIps.size() == 2) { + if (ip.getIpVersion() == IPv6Constants.IPv4) { + nicVO.setIp(ip.getIp()); + nicVO.setGateway(ip.getGateway()); + nicVO.setNetmask(ip.getNetmask()); + nicVO.setL3NetworkUuid(ip.getL3NetworkUuid()); + nicVO.setUsedIpUuid(ip.getUuid()); + } + } else { + nicVO.setIp(ip.getIp()); + nicVO.setGateway(ip.getGateway()); + nicVO.setNetmask(ip.getNetmask()); + nicVO.setL3NetworkUuid(ip.getL3NetworkUuid()); + nicVO.setUsedIpUuid(ip.getUuid()); + } + } + dbf.updateAndRefresh(nicVO); + dbf.updateCollection(ipVOS); + data.put(VmInstanceConstant.Params.VmNicInventory.toString(), nicVO); + data.put(VmInstanceConstant.Params.vmInventory.toString(), getSelfInventory()); + trigger.next(); + } + }); + + flowChain.then(new NoRollbackFlow() { + String __name__ = "update-nic-bridge"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (self.getState() != VmInstanceState.Running) { + logger.debug(String.format("vm[uuid:%s] state is %s, no need to update nic's bridge", self.getUuid(), self.getState())); + trigger.next(); + return; + } + + VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + HostInventory dest = spec.getDestHost(); + VmInstanceInventory vm = getSelfInventory(); + + if (dest == null) { + trigger.next(); + return; + } + + VmUpdateNicOnHypervisorMsg cmsg = new VmUpdateNicOnHypervisorMsg(); + cmsg.setVmInstanceUuid(vm.getUuid()); + cmsg.setHostUuid(dest.getUuid()); + cmsg.setNicsUuid(list(nic.getUuid())); + bus.makeTargetServiceIdByResourceUuid(cmsg, HostConstant.SERVICE_ID, vm.getUuid()); + bus.send(cmsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + + trigger.next(); } }); - } }); + + if (self.getState() == VmInstanceState.Running) { + flowChain.then(new VmApplyNetworkServiceOnChangeIPFlow()); + } + flowChain.then(new NoRollbackFlow() { - String __name__ = "update-nic-ip"; + String __name__ = "return-old-ip"; @Override public void run(FlowTrigger trigger, Map data) { @@ -5658,45 +6425,26 @@ public void run(MessageReply reply) { comp.done(); } }); - }).run(new WhileDoneCompletion(trigger) { + }).run(new WhileDoneCompletion(chain) { @Override public void done(ErrorCodeList errorCodeList) { - if (self.getDefaultL3NetworkUuid().equals(nic.getL3NetworkUuid())) { - self.setDefaultL3NetworkUuid(destL3.getUuid()); - } - self = dbf.updateAndRefresh(self); - VmNicVO nicVO = dbf.findByUuid(nic.getUuid(), VmNicVO.class); - List allocateIps = (List) data.get(VmInstanceConstant.Params.VmAllocateNicFlow_ips.toString()); - List ipVOS = new ArrayList<>(); - for (UsedIpInventory ip : allocateIps) { - /* update usedIpVo */ - UsedIpVO ipVO = dbf.findByUuid(ip.getUuid(), UsedIpVO.class); - ipVO.setVmNicUuid(nic.getUuid()); - ipVOS.add(ipVO); - if (allocateIps.size() == 2) { - if (ip.getIpVersion() == IPv6Constants.IPv4) { - nicVO.setIp(ip.getIp()); - nicVO.setGateway(ip.getGateway()); - nicVO.setNetmask(ip.getNetmask()); - nicVO.setL3NetworkUuid(ip.getL3NetworkUuid()); - nicVO.setUsedIpUuid(ip.getUuid()); - } - } else { - nicVO.setIp(ip.getIp()); - nicVO.setGateway(ip.getGateway()); - nicVO.setNetmask(ip.getNetmask()); - nicVO.setL3NetworkUuid(ip.getL3NetworkUuid()); - nicVO.setUsedIpUuid(ip.getUuid()); - } - } - dbf.updateAndRefresh(nicVO); - dbf.updateCollection(ipVOS); - data.put(VmInstanceConstant.Params.VmNicInventory.toString(), nicVO); trigger.next(); } }); } }); + + flowChain.then(new NoRollbackFlow() { + String __name__ = "after-change-nic-network-extension"; + + @Override + public void run(FlowTrigger trigger, Map data) { + CollectionUtils.safeForEach(pluginRgty.getExtensionList(VmUpdateNicExtensionPoint.class), + arg -> arg.afterUpdateNic(spec, nic, destL3)); + trigger.next(); + } + }); + flowChain.done(new FlowDoneHandler(chain) { @Override public void handle(Map data) { @@ -5822,20 +6570,21 @@ public void run(List replies) { }); } - private void detachVolume(final DetachDataVolumeFromVmMsg msg, final NoErrorCompletion completion) { - final DetachDataVolumeFromVmReply reply = new DetachDataVolumeFromVmReply(); + @SuppressWarnings("rawtypes") + private void detachVolume(final DetachDataVolumeFromVmMsg msg, final Completion completion) { refreshVO(true); if (self == null || VmInstanceState.Destroyed == self.getState()) { // the vm is destroyed, the data volume must have been detached - bus.reply(msg, reply); - completion.done(); + completion.success(); return; } ErrorCode allowed = validateOperationByState(msg, self.getState(), VmErrors.DETACH_VOLUME_ERROR); if (allowed != null) { - throw new OperationFailureException(allowed); + completion.fail(operr("Detaching volume is not allowed when VM[uuid=%s] is in state[%s]", + self.getUuid(), self.getState())); + return; } final VolumeInventory volume = msg.getVolume(); @@ -5845,83 +6594,116 @@ private void detachVolume(final DetachDataVolumeFromVmMsg msg, final NoErrorComp extEmitter.afterDetachVolume(getSelfInventory(), volume, new Completion(completion) { @Override public void success() { - bus.reply(msg, reply); - completion.done(); + completion.success(); } @Override public void fail(ErrorCode errorCode) { - reply.setError(errorCode); - bus.reply(msg, reply); - completion.done(); + completion.fail(errorCode); } }); return; } - extEmitter.preDetachVolume(getSelfInventory(), volume); - extEmitter.beforeDetachVolume(getSelfInventory(), volume); - - if (self.getState() == VmInstanceState.Stopped) { - extEmitter.afterDetachVolume(getSelfInventory(), volume, new Completion(completion) { - @Override - public void success() { - bus.reply(msg, reply); - SQL.New(VolumeVO.class).eq(VolumeVO_.uuid, volume.getUuid()) - .set(VolumeVO_.lastDetachDate, Timestamp.valueOf(LocalDateTime.now())) - .set(VolumeVO_.lastVmInstanceUuid, msg.getVmInstanceUuid()) - .update(); - completion.done(); - } + FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("detach-volume-%s-from-vm-%s", self.getUuid(), msg.getVmInstanceUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "pre-detach-volume"; + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.beforeDetachVolume(getSelfInventory(), volume); + trigger.next(); + } + }).then(new NoRollbackFlow() { + String __name__ = "before-detaching-volume"; + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.preDetachVolume(getSelfInventory(), volume, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } - @Override - public void fail(ErrorCode errorCode) { - reply.setError(errorCode); - bus.reply(msg, reply); - completion.done(); - } - }); - return; - } + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new Flow() { + String __name__ = "detach-volume-from-vm-on-hypervisor"; - // VmInstanceState.Running - String hostUuid = self.getHostUuid(); - DetachVolumeFromVmOnHypervisorMsg dmsg = new DetachVolumeFromVmOnHypervisorMsg(); - dmsg.setVmInventory(VmInstanceInventory.valueOf(self)); - dmsg.setInventory(volume); - dmsg.setHostUuid(hostUuid); - bus.makeTargetServiceIdByResourceUuid(dmsg, HostConstant.SERVICE_ID, hostUuid); - bus.send(dmsg, new CloudBusCallBack(msg, completion) { @Override - public void run(final MessageReply r) { - if (!r.isSuccess()) { - reply.setError(r.getError()); - extEmitter.failedToDetachVolume(getSelfInventory(), volume, r.getError()); - bus.reply(msg, reply); - completion.done(); - } else { - vvo.setLastDetachDate(Timestamp.valueOf(LocalDateTime.now())); - vvo.setLastVmInstanceUuid(msg.getVmInstanceUuid()); - dbf.update(vvo); + public boolean skip(Map data) { + return self.getHostUuid() == null && self.getLastHostUuid() == null; + } - extEmitter.afterDetachVolume(getSelfInventory(), volume, new Completion(completion) { - @Override - public void success() { - bus.reply(msg, reply); - completion.done(); + @Override + public void run(FlowTrigger trigger, Map data) { + String hostUuid = self.getHostUuid() == null ? self.getLastHostUuid() : self.getHostUuid(); + + DetachVolumeFromVmOnHypervisorMsg innerMsg = new DetachVolumeFromVmOnHypervisorMsg(); + innerMsg.setVmInventory(VmInstanceInventory.valueOf(self)); + innerMsg.setInventory(volume); + innerMsg.setHostUuid(hostUuid); + bus.makeTargetServiceIdByResourceUuid(innerMsg, HostConstant.SERVICE_ID, hostUuid); + bus.send(innerMsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply innerReply) { + if (innerReply.isSuccess()) { + trigger.next(); + return; } + trigger.fail(innerReply.getError()); + } + }); + } - @Override - public void fail(ErrorCode errorCode) { - reply.setError(errorCode); - bus.reply(msg, reply); - completion.done(); - } - }); - } + @Override + public void rollback(FlowRollback trigger, Map data) { + extEmitter.failedToDetachVolume(getSelfInventory(), volume, trigger.getErrorCode()); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "update-volume-in-database"; + @Override + public void run(FlowTrigger trigger, Map data) { + vvo.setLastDetachDate(Timestamp.valueOf(LocalDateTime.now())); + vvo.setLastVmInstanceUuid(msg.getVmInstanceUuid()); + dbf.update(vvo); + trigger.next(); + } + }).then(new NoRollbackFlow() { + String __name__ = "after-detaching-volume"; + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.afterDetachVolume(getSelfInventory(), volume, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); } }); + + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(operr(errCode, "Failed to detach volume[uuid=%s] of VM[uuid=%s]", + msg.getVolume().getUuid(), self.getUuid())); + } + }).start(); } protected void attachDataVolume(final AttachDataVolumeToVmMsg msg, final NoErrorCompletion completion) { @@ -5932,17 +6714,14 @@ protected void attachDataVolume(final AttachDataVolumeToVmMsg msg, final NoError throw new OperationFailureException(err); } - Map data = new HashMap(); - final VolumeInventory volume = msg.getVolume(); + final VmInstanceInventory vmInv = VmInstanceInventory.valueOf(self); - new VmAttachVolumeValidator().validate(msg.getVmInstanceUuid(), volume.getUuid()); - extEmitter.preAttachVolume(getSelfInventory(), volume); - extEmitter.beforeAttachVolume(getSelfInventory(), volume, data); + new VmAttachVolumeValidator().validate(vmInv, volume.getUuid()); VmInstanceSpec spec = new VmInstanceSpec(); spec.setMessage(msg); - spec.setVmInventory(VmInstanceInventory.valueOf(self)); + spec.setVmInventory(vmInv); spec.setCurrentVmOperation(VmOperation.AttachVolume); spec.setDestDataVolumes(list(volume)); FlowChain chain; @@ -5955,6 +6734,34 @@ protected void attachDataVolume(final AttachDataVolumeToVmMsg msg, final NoError } setFlowMarshaller(chain); + chain.insert(new NoRollbackFlow() { + final String __name__ = "call-pre-attach-volume-extension"; + + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.preAttachVolume(getSelfInventory(), volume, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + chain.insert(1, new NoRollbackFlow() { + final String __name__ = "call-before-attach-volume-extension"; + + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.beforeAttachVolume(getSelfInventory(), volume, data); + trigger.next(); + } + }); List attachedVolumes = getAllDataVolumes(getSelfInventory()); attachedVolumes.removeIf(it -> it.getDeviceId() == null || it.getUuid().equals(volume.getUuid())); @@ -6001,6 +6808,7 @@ protected void migrateVm(final MigrateVmMessage msg, final Completion completion } VmInstanceInventory inv = VmInstanceInventory.valueOf(self); + String originState = inv.getState(); FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName(String.format("migrate-vm-%s", self.getUuid())); @@ -6009,7 +6817,7 @@ protected void migrateVm(final MigrateVmMessage msg, final Completion completion @Override public void run(FlowTrigger trigger, Map data) { new While<>(pluginRgty.getExtensionList(VmPreMigrationExtensionPoint.class)) - .each((extension, whileCompletion) -> extension.preVmMigration(inv, new Completion(whileCompletion) { + .each((extension, whileCompletion) -> extension.preVmMigration(inv, VmMigrationType.HostMigration, msg.getHostUuid(), new Completion(whileCompletion) { @Override public void success() { whileCompletion.done(); @@ -6053,6 +6861,9 @@ public void fail(ErrorCode errorCode) { chain.done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { + if (Objects.equals(VmInstanceState.Paused.toString(), originState)) { + tagMgr.createNonInherentSystemTag(inv.getUuid(), VmSystemTags.VM_STATE_PAUSED_AFTER_MIGRATE.getTagFormat(), VmInstanceVO.class.getSimpleName()); + } completion.success(); } }).error(new FlowErrorHandler(completion) { @@ -6078,38 +6889,62 @@ private void doMigrateVm(final MigrateVmMessage msg, final Completion completion String lastHostUuid = self.getHostUuid(); chain.setName(String.format("do-migrate-vm-%s", self.getUuid())); chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); + chain.then(new NoRollbackFlow() { + final String __name__ = String.format("sync-vm-%s-stat-after-migrate", self.getUuid()); - chain.done(new FlowDoneHandler(completion) { @Override - public void handle(final Map data) { + public void run(FlowTrigger trigger, Map data) { HostInventory host = spec.getDestHost(); - self = changeVmStateInDb(VmInstanceStateEvent.running, () -> { - self.setZoneUuid(host.getZoneUuid()); - self.setClusterUuid(host.getClusterUuid()); - self.setLastHostUuid(lastHostUuid); - self.setHostUuid(host.getUuid()); + checkState(host.getUuid(), new NoErrorCompletion(completion) { + @Override + public void done() { + SQL.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, self.getUuid()) + .set(VmInstanceVO_.zoneUuid, host.getZoneUuid()) + .set(VmInstanceVO_.clusterUuid, host.getClusterUuid()) + .set(VmInstanceVO_.lastHostUuid, lastHostUuid) + .set(VmInstanceVO_.hostUuid, host.getUuid()) + .update(); + self = dbf.reload(self); + trigger.next(); + } }); + } + }); + + chain.then(new VmMigratePostCallExtensionFlow()); + + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(final Map data) { VmInstanceInventory vm = VmInstanceInventory.valueOf(self); - extEmitter.afterMigrateVm(vm, vm.getLastHostUuid()); - completion.success(); + extEmitter.afterMigrateVm(vm, vm.getLastHostUuid(), new NoErrorCompletion(completion) { + @Override + public void done() { + completion.success(); + } + }); } }).error(new FlowErrorHandler(completion) { @Override public void handle(final ErrorCode errCode, Map data) { String destHostUuid = spec.getDestHost().getUuid().equals(lastHostUuid) ? null : spec.getDestHost().getUuid(); - extEmitter.failedToMigrateVm(VmInstanceInventory.valueOf(self), destHostUuid, errCode); - if (HostErrors.FAILED_TO_MIGRATE_VM_ON_HYPERVISOR.isEqual(errCode.getCode())) { - checkState(originalCopy.getHostUuid(), new NoErrorCompletion(completion) { - @Override - public void done() { + extEmitter.failedToMigrateVm(VmInstanceInventory.valueOf(self), destHostUuid, errCode, new NoErrorCompletion(completion) { + @Override + public void done() { + if (!HostErrors.FAILED_TO_MIGRATE_VM_ON_HYPERVISOR.isEqual(errCode.getCode())) { + changeVmStateInDb(originState.getDrivenEvent()); completion.fail(errCode); + return; } - }); - } else { - self.setState(originState); - self = dbf.updateAndRefresh(self); - completion.fail(errCode); - } + + checkState(originalCopy.getHostUuid(), new NoErrorCompletion(completion) { + @Override + public void done() { + completion.fail(errCode); + } + }); + } + }); } }).start(); } @@ -6119,6 +6954,8 @@ protected void handle(CancelMigrateVmMsg msg) { CancelHostTasksMsg cmsg = new CancelHostTasksMsg(); cmsg.setCancellationApiId(msg.getCancellationApiId()); + cmsg.setInterval(1); + cmsg.setTimes(3); bus.makeLocalServiceId(cmsg, HostConstant.SERVICE_ID); bus.send(cmsg, new CloudBusCallBack(msg) { @Override @@ -6168,6 +7005,10 @@ public void fail(ErrorCode errorCode) { }); } + protected void provisionAfterStartVm(VmInstanceSpec spec, NoErrorCompletion completion) { + completion.done(); + } + protected void startVm(final Message msg, final Completion completion) { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), null); @@ -6212,6 +7053,8 @@ protected void startVm(final Message msg, final Completion completion) { spec.setUsbRedirect(Boolean.parseBoolean(VmSystemTags.USB_REDIRECT.getTokenByResourceUuid(self.getUuid(), VmSystemTags.USB_REDIRECT_TOKEN))); spec.setEnableRDP(VmSystemTags.RDP_ENABLE.getTokenByResourceUuid(self.getUuid(), VmSystemTags.RDP_ENABLE_TOKEN)); spec.setVDIMonitorNumber(VmSystemTags.VDI_MONITOR_NUMBER.getTokenByResourceUuid(self.getUuid(), VmSystemTags.VDI_MONITOR_NUMBER_TOKEN)); + spec.setEnableSecurityElement(Boolean.parseBoolean(VmSystemTags.SECURITY_ELEMENT_ENABLE.getTokenByResourceUuid(self.getUuid(), VmSystemTags.SECURITY_ELEMENT_ENABLE_TOKEN))); + spec.setAllocationScene(AllocationScene.Auto); } if (msg instanceof HaStartVmInstanceMsg) { @@ -6229,11 +7072,6 @@ protected void startVm(final Message msg, final Completion completion) { spec.setMemorySnapshotUuid(((RestoreVmInstanceMsg) msg).getMemorySnapshotUuid()); } - if (spec.getDestNics().isEmpty()) { - throw new OperationFailureException(operr("unable to start the vm[uuid:%s]." + - " It doesn't have any nic, please attach a nic and try again", self.getUuid())); - } - final VmInstanceState originState = self.getState(); changeVmStateInDb(VmInstanceStateEvent.starting); @@ -6255,27 +7093,32 @@ protected void startVm(final Message msg, final Completion completion) { chain.done(new FlowDoneHandler(completion) { @Override public void handle(final Map data) { - VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - self = changeVmStateInDb(VmInstanceStateEvent.running, () -> new SQLBatch() { + provisionAfterStartVm(spec, new NoErrorCompletion(completion) { @Override - protected void scripts() { - // reload self because some nics may have been deleted in start phase because a former L3Network deletion. - // reload to avoid JPA EntityNotFoundException - self = findByUuid(self.getUuid(), VmInstanceVO.class); - if (q(HostVO.class).eq(HostVO_.uuid, recentHostUuid).isExists()) { - self.setLastHostUuid(recentHostUuid); - } else { - self.setLastHostUuid(null); - } - self.setHostUuid(spec.getDestHost().getUuid()); - self.setClusterUuid(spec.getDestHost().getClusterUuid()); - self.setZoneUuid(spec.getDestHost().getZoneUuid()); + public void done() { + VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + self = changeVmStateInDb(VmInstanceStateEvent.running, () -> new SQLBatch() { + @Override + protected void scripts() { + // reload self because some nics may have been deleted in start phase because a former L3Network deletion. + // reload to avoid JPA EntityNotFoundException + self = findByUuid(self.getUuid(), VmInstanceVO.class); + if (q(HostVO.class).eq(HostVO_.uuid, recentHostUuid).isExists()) { + self.setLastHostUuid(recentHostUuid); + } else { + self.setLastHostUuid(null); + } + self.setHostUuid(spec.getDestHost().getUuid()); + self.setClusterUuid(spec.getDestHost().getClusterUuid()); + self.setZoneUuid(spec.getDestHost().getZoneUuid()); + } + }.execute()); + logger.debug(String.format("vm[uuid:%s] is running ..", self.getUuid())); + VmInstanceInventory inv = VmInstanceInventory.valueOf(self); + extEmitter.afterStartVm(inv); + completion.success(); } - }.execute()); - logger.debug(String.format("vm[uuid:%s] is running ..", self.getUuid())); - VmInstanceInventory inv = VmInstanceInventory.valueOf(self); - extEmitter.afterStartVm(inv); - completion.success(); + }); } }).error(new FlowErrorHandler(completion) { @Override @@ -6316,11 +7159,14 @@ public void done() { private VmInstanceSpec buildVmInstanceSpecFromStruct(InstantiateVmFromNewCreatedStruct struct) { final VmInstanceSpec spec = new VmInstanceSpec(); - spec.setRequiredPrimaryStorageUuidForRootVolume(struct.getPrimaryStorageUuidForRootVolume()); - spec.setRequiredPrimaryStorageUuidForDataVolume(struct.getPrimaryStorageUuidForDataVolume()); + spec.setCandidatePrimaryStorageUuidsForRootVolume(struct.getCandidatePrimaryStorageUuidsForRootVolume()); + spec.setCandidatePrimaryStorageUuidsForDataVolume(struct.getCandidatePrimaryStorageUuidsForDataVolume()); spec.setDataVolumeSystemTags(struct.getDataVolumeSystemTags()); spec.setRootVolumeSystemTags(struct.getRootVolumeSystemTags()); spec.setRequiredHostUuid(struct.getRequiredHostUuid()); + spec.setDataVolumeSystemTagsOnIndex(struct.getDataVolumeSystemTagsOnIndex()); + spec.setDisableL3Networks(struct.getDisableL3Networks()); + spec.setStrategy(struct.getStrategy()); spec.setVmInventory(getSelfInventory()); if (struct.getL3NetworkUuids() != null && !struct.getL3NetworkUuids().isEmpty()) { @@ -6351,6 +7197,7 @@ public L3NetworkInventory call(L3NetworkInventory arg) { if (!l3s.isEmpty()) { VmNicSpec nicSpec1 = new VmNicSpec(l3s); nicSpec1.setNicDriverType(nicSpec.getNicDriverType()); + nicSpec1.setVmNicParams(nicSpec.getVmNicParams()); nicSpecs.add(nicSpec1); } } @@ -6388,44 +7235,18 @@ public DiskOfferingVO call(DiskOfferingVO arg) { spec.setDataDiskOfferings(new ArrayList<>()); } - if (struct.getRootDiskOfferingUuid() != null) { - DiskOfferingVO rootDisk = dbf.findByUuid(struct.getRootDiskOfferingUuid(), DiskOfferingVO.class); - spec.setRootDiskOffering(DiskOfferingInventory.valueOf(rootDisk)); - } - - ImageVO imvo = dbf.findByUuid(spec.getVmInventory().getImageUuid(), ImageVO.class); - List cdRomSpecs = buildVmCdRomSpecsForNewCreated(spec); - spec.setCdRomSpecs(cdRomSpecs); - - if (imvo != null) { - spec.getImageSpec().setInventory(ImageInventory.valueOf(imvo)); - } else { - ImageInventory image = new ImageInventory(); - image.setUuid(spec.getVmInventory().getImageUuid()); - image.setSize(spec.getRootDiskOffering().getDiskSize()); - - List resultList = Q.New(ImageCacheVO.class) - .select(ImageCacheVO_.size) - .eq(ImageCacheVO_.imageUuid, spec.getVmInventory().getImageUuid()) - .limit(1) - .listValues(); - if (resultList.isEmpty()) { - resultList = Q.New(ImageCacheShadowVO.class) - .select(ImageCacheShadowVO_.size) - .eq(ImageCacheShadowVO_.imageUuid, spec.getVmInventory().getImageUuid()) - .limit(1) - .listValues(); - - if (resultList.isEmpty()) { - throw new OperationFailureException(operr("no way to get image size of %s, report exception.", spec.getVmInventory().getImageUuid())); - } - } - - image.setActualSize(resultList.get(0)); - spec.getImageSpec().setInventory(image); + if (struct.getRootDiskOfferingUuid() != null) { + DiskOfferingVO rootDisk = dbf.findByUuid(struct.getRootDiskOfferingUuid(), DiskOfferingVO.class); + spec.setRootDiskOffering(DiskOfferingInventory.valueOf(rootDisk)); } + + spec.setDiskAOs(struct.getDiskAOs()); + + List cdRomSpecs = buildVmCdRomSpecsForNewCreated(spec); + spec.setCdRomSpecs(cdRomSpecs); + buildImageSpec(spec); spec.setCurrentVmOperation(VmOperation.NewCreate); - if (struct.getRequiredHostUuid() != null) { + if (struct.getRequiredHostUuid() != null || CollectionUtils.isEmpty(struct.getL3NetworkUuids())) { spec.setHostAllocatorStrategy(HostAllocatorConstant.DESIGNATED_HOST_ALLOCATOR_STRATEGY_TYPE); } buildHostname(spec); @@ -6435,6 +7256,7 @@ public DiskOfferingVO call(DiskOfferingVO arg) { spec.setConsolePassword(VmSystemTags.CONSOLE_PASSWORD. getTokenByResourceUuid(self.getUuid(), VmSystemTags.CONSOLE_PASSWORD_TOKEN)); spec.setUsbRedirect(Boolean.parseBoolean(VmSystemTags.USB_REDIRECT.getTokenByResourceUuid(self.getUuid(), VmSystemTags.USB_REDIRECT_TOKEN))); + spec.setEnableSecurityElement(Boolean.parseBoolean(VmSystemTags.SECURITY_ELEMENT_ENABLE.getTokenByResourceUuid(self.getUuid(), VmSystemTags.SECURITY_ELEMENT_ENABLE_TOKEN))); if (struct.getStrategy() == VmCreationStrategy.CreateStopped || struct.getStrategy() == VmCreationStrategy.CreatedPaused) { spec.setCreatePaused(true); } @@ -6767,6 +7589,44 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } + protected void buildImageSpec(VmInstanceSpec spec) { + if (spec.getVmInventory().getImageUuid() == null) { + // create vm without image, skip downloading image + spec.getImageSpec().setNeedDownload(false); + return; + } + + ImageVO imvo = dbf.findByUuid(spec.getVmInventory().getImageUuid(), ImageVO.class); + + if (imvo != null) { + spec.getImageSpec().setInventory(ImageInventory.valueOf(imvo)); + } else { + ImageInventory image = new ImageInventory(); + image.setUuid(spec.getVmInventory().getImageUuid()); + image.setSize(spec.getRootDiskOffering().getDiskSize()); + + List resultList = Q.New(ImageCacheVO.class) + .select(ImageCacheVO_.size) + .eq(ImageCacheVO_.imageUuid, spec.getVmInventory().getImageUuid()) + .limit(1) + .listValues(); + if (resultList.isEmpty()) { + resultList = Q.New(ImageCacheShadowVO.class) + .select(ImageCacheShadowVO_.size) + .eq(ImageCacheShadowVO_.imageUuid, spec.getVmInventory().getImageUuid()) + .limit(1) + .listValues(); + + if (resultList.isEmpty()) { + throw new OperationFailureException(operr("no way to get image size of %s, report exception.", spec.getVmInventory().getImageUuid())); + } + } + + image.setActualSize(resultList.get(0)); + spec.getImageSpec().setInventory(image); + } + } + protected void buildHostname(VmInstanceSpec spec) { String defaultHostname = VmSystemTags.HOSTNAME.getTag(self.getUuid()); if (defaultHostname == null) { @@ -6868,6 +7728,7 @@ public String call(VmNicInventory arg) { if (dbf.isExist(isoUuid, ImageVO.class)) { cdRomSpec.setImageUuid(isoUuid); cdRomSpec.setInstallPath(cdRomVO.getIsoInstallPath()); + cdRomSpec.setProtocol(cdRomVO.getProtocol()); } else { //TODO logger.warn(String.format("iso[uuid:%s] is deleted, however, the VM[uuid:%s] still has it attached", @@ -6885,6 +7746,7 @@ public String call(VmNicInventory arg) { getTokenByResourceUuid(self.getUuid(), VmSystemTags.CONSOLE_PASSWORD_TOKEN)); spec.setVDIMonitorNumber(VmSystemTags.VDI_MONITOR_NUMBER.getTokenByResourceUuid(self.getUuid(), VmSystemTags.VDI_MONITOR_NUMBER_TOKEN)); spec.setUsbRedirect(Boolean.parseBoolean(VmSystemTags.USB_REDIRECT.getTokenByResourceUuid(self.getUuid(), VmSystemTags.USB_REDIRECT_TOKEN))); + spec.setEnableSecurityElement(Boolean.parseBoolean(VmSystemTags.SECURITY_ELEMENT_ENABLE.getTokenByResourceUuid(self.getUuid(), VmSystemTags.SECURITY_ELEMENT_ENABLE_TOKEN))); for (BuildVmSpecExtensionPoint ext : pluginRgty.getExtensionList(BuildVmSpecExtensionPoint.class)) { ext.afterBuildVmSpec(spec); @@ -6903,6 +7765,10 @@ protected List getAllDataVolumes(VmInstanceInventory inv) { return dataVols; } + protected void provisionAfterRebootVm(VmInstanceSpec spec, NoErrorCompletion completion) { + completion.done(); + } + protected void rebootVm(final Message msg, final Completion completion) { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), null); @@ -6938,11 +7804,17 @@ protected void rebootVm(final Message msg, final Completion completion) { chain.done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { - self = changeVmStateInDb(VmInstanceStateEvent.running); - VmInstanceInventory inv = VmInstanceInventory.valueOf(self); - extEmitter.afterRebootVm(inv); - new StaticIpOperator().deleteIpChange(self.getUuid()); - completion.success(); + provisionAfterRebootVm(spec, new NoErrorCompletion(completion) { + @Override + public void done() { + self = changeVmStateInDb(VmInstanceStateEvent.running, + () -> self.setHostUuid(originalCopy.getHostUuid())); + VmInstanceInventory inv = VmInstanceInventory.valueOf(self); + extEmitter.afterRebootVm(inv); + new StaticIpOperator().deleteIpChange(self.getUuid()); + completion.success(); + } + }); } }).error(new FlowErrorHandler(completion) { @Override @@ -6961,20 +7833,28 @@ public void done() { completion.fail(errCode); } }); - } else { - VmInstanceState currentState = Q.New(VmInstanceVO.class) - .select(VmInstanceVO_.state) - .eq(VmInstanceVO_.uuid, self.getUuid()) - .findValue(); - if (currentState == VmInstanceState.Rebooting) { - SQL.New(VmInstanceVO.class) - .set(VmInstanceVO_.state, originState) - .eq(VmInstanceVO_.uuid, self.getUuid()) - .update(); - } + return; + } - completion.fail(errCode); + VmInstanceState currentState = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.state) + .eq(VmInstanceVO_.uuid, self.getUuid()) + .findValue(); + + if (currentState == VmInstanceState.Rebooting) { + if (data.containsKey(VmStopOnHypervisorFlow.class.getName())) { + currentState = currentState.nextState(VmInstanceStateEvent.stopped); + } + if (data.containsKey(VmStartOnHypervisorFlow.class.getName())) { + currentState = currentState.nextState(VmInstanceStateEvent.running); + } + SQL.New(VmInstanceVO.class) + .set(VmInstanceVO_.state, currentState) + .eq(VmInstanceVO_.uuid, self.getUuid()) + .update(); } + + completion.fail(errCode); } }).start(); } @@ -7254,6 +8134,7 @@ public void success() { VmInstanceInventory inv = VmInstanceInventory.valueOf(self); evt.setInventory(inv); bus.publish(evt); + extEmitter.afterResumeVm(inv); taskChain.next(); } @@ -7267,6 +8148,61 @@ public void fail(ErrorCode errorCode) { }); } + protected void checkStateAndStartVmInstance(final CheckAndStartVmInstanceMsg msg, final SyncTaskChain taskChain) { + checkStateAndStartVmInstance(new Completion(taskChain) { + @Override + public void success() { + VmInstanceInventory inv = VmInstanceInventory.valueOf(self); + CheckAndStartVmInstanceReply reply = new CheckAndStartVmInstanceReply(); + reply.setInventory(inv); + bus.reply(msg, reply); + taskChain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + CheckAndStartVmInstanceReply reply = new CheckAndStartVmInstanceReply(); + reply.setError(err(VmErrors.START_ERROR, errorCode, errorCode.getDetails())); + bus.reply(msg, reply); + taskChain.next(); + } + }); + } + + private NeedReplyMessage fillMsg(VmInstanceState vmState) { + if (vmState == VmInstanceState.Running) { + RebootVmInstanceMsg msg = new RebootVmInstanceMsg(); + msg.setVmInstanceUuid(self.getUuid()); + return msg; + } else if (vmState == VmInstanceState.Stopped) { + StartVmInstanceMsg msg = new StartVmInstanceMsg(); + msg.setVmInstanceUuid(self.getUuid()); + return msg; + } else { + throw new RuntimeException(String.format("support vm instance states are [Running, Stopped], current vm instance state is %s", vmState)); + } + } + + private void checkStateAndStartVmInstance(Completion completion) { + VmInstanceState vmState = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.state) + .eq(VmInstanceVO_.uuid, self.getUuid()) + .findValue(); + + NeedReplyMessage msg = fillMsg(vmState); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, self.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + completion.success(); + } else { + completion.fail(reply.getError()); + } + } + }); + } + protected void resumeVm(final Message msg, Completion completion) { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), null); @@ -7468,6 +8404,41 @@ private void doCreateVmCdRom(CreateVmCdRomMsg msg, ReturnValueCompletion(msg, chain) { + @Override + public void success(VmInstanceInventory inv) { + reply.setInventory(inv); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } + + @Override + public String getName() { + return "faltten-vm-" + self.getUuid(); + } + }); + } + + private void handle(CancelFlattenVmInstanceMsg msg) { + CancelFlattenVmInstanceReply reply = new CancelFlattenVmInstanceReply(); + ErrorCode err = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); + if (err != null) { + reply.setError(err); + bus.reply(msg, reply); + return; + } + + Completion completion = new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }; + + if (self.getState() == VmInstanceState.Stopped) { + cancelFlattenOffline(msg.getCancellationApiId(), completion); + } else { + cancelFlattenOnline(msg.getCancellationApiId(), completion); + } + } + + private void flattenVm(FlattenVmInstanceMsg msg, ReturnValueCompletion completion) { + refreshVO(); + ErrorCode err = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); + if (err != null) { + completion.fail(err); + return; + } + + TaskProgressRange parentStage = getTaskStage(); + + List vols = new ArrayList<>(); + List weights = self.getAllDiskVolumes().stream().map(it -> 1L).collect(Collectors.toList()); + List stages = splitTaskStage(parentStage, weights); + new While<>(self.getAllDiskVolumes()).each((vol, compl) -> { + TaskProgressRange stage = markTaskStage(stages.remove(0)); + if (vol.isShareable()) { + vols.add(vol.toInventory()); + reportProgress(stage.getEnd().toString()); + compl.done(); + return; + } + + FlattenVolumeMsg fmsg = new FlattenVolumeMsg(); + fmsg.setUuid(vol.getUuid()); + fmsg.setDryRun(msg.isDryRun()); + bus.makeTargetServiceIdByResourceUuid(fmsg, VolumeConstant.SERVICE_ID, fmsg.getVolumeUuid()); + bus.send(fmsg, new CloudBusCallBack(compl) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + compl.addError(reply.getError()); + compl.allDone(); + return; + } + + vols.add(((FlattenVolumeReply) reply).getInventory()); + reportProgress(stage.getEnd().toString()); + compl.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList.getCauses().get(0)); + return; + } + + if (!msg.isDryRun()) { + refreshVO(); + completion.success(getSelfInventory()); + return; + } + + VmInstanceInventory inv = getSelfInventory(); + inv.setAllVolumes(vols); + completion.success(inv); + } + }); + } + + private void cancelFlattenOnline(String apiId, Completion completion) { + CancelHostTaskMsg cmsg = new CancelHostTaskMsg(); + cmsg.setHostUuid(self.getHostUuid()); + cmsg.setCancellationApiId(apiId); + bus.makeTargetServiceIdByResourceUuid(cmsg, HostConstant.SERVICE_ID, self.getUuid()); + bus.send(cmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + completion.success(); + } + }); + } + + private void cancelFlattenOffline(String apiId, Completion completion) { + Set volPsUuids = self.getAllDiskVolumes().stream().map(VolumeVO::getPrimaryStorageUuid).collect(Collectors.toSet()); + new While<>(volPsUuids).all((psUuid, compl) ->{ + CancelJobOnPrimaryStorageMsg cmsg = new CancelJobOnPrimaryStorageMsg(); + cmsg.setPrimaryStorageUuid(psUuid); + cmsg.setCancellationApiId(apiId); + bus.makeTargetServiceIdByResourceUuid(cmsg, PrimaryStorageConstant.SERVICE_ID, psUuid); + bus.send(cmsg, new CloudBusCallBack(compl) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + compl.addError(reply.getError()); + compl.done(); + return; + } + + compl.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList.getCauses().get(0)); + return; + } + + completion.success(); + } + }); + } + private void handle(OverlayMessage msg) { thdf.chainSubmit(new ChainTask(msg) { @Override @@ -7801,7 +8969,7 @@ public void done() { @Override public String getName() { - return "overlay-message"; + return msg.getTaskName(); } }); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java index 1973b3ef5cf..e45294b5fa3 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java @@ -1,14 +1,17 @@ package org.zstack.compute.vm; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.Component; import org.zstack.header.core.Completion; -import org.zstack.header.core.ExceptionSafe; +import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.vm.*; import org.zstack.header.volume.VolumeInventory; @@ -32,6 +35,7 @@ public class VmInstanceExtensionPointEmitter implements Component { private ErrorFacade errf; private List VmInstanceBeforeStartExtensions; + private List VmInstanceResumeExtensionPoints; private List startNewCreatedVmExtensions; private List beforeVmStopExtensions; private List stopVmExtensions; @@ -44,6 +48,8 @@ public class VmInstanceExtensionPointEmitter implements Component { private List capabilitiesExtensionPoints; private List cleanUpAfterVmFailedToStartExtensionPoints; private List cleanUpAfterVmChangeImageExtensionPoints; + private List vmNicChangeStateExtensionPoints; + private List sshKeyPairAssociateExtensionPoints; public List handleSystemTag(String vmUuid, List tags){ List errorCodes = new ArrayList<>(); @@ -266,6 +272,15 @@ public void run(VmInstanceDestroyExtensionPoint arg) { }); } + public void afterResumeVm(VmInstanceInventory inv) { + CollectionUtils.safeForEach(VmInstanceResumeExtensionPoints, new ForEachFunction() { + @Override + public void run(VmInstanceResumeExtensionPoint arg) { + arg.afterResumeVm(inv); + } + }); + } + public ErrorCode preStartVm(VmInstanceInventory inv) { for (VmInstanceStartExtensionPoint ext : startVmExtensions) { try { @@ -309,36 +324,108 @@ public void run(VmInstanceStartExtensionPoint arg) { }); } - public void preMigrateVm(final VmInstanceInventory inv, final String dstHostUuid) { - CollectionUtils.safeForEach(migrateVmExtensions, arg -> arg.preMigrateVm(inv, dstHostUuid)); + public void preMigrateVm(final VmInstanceInventory inv, final String dstHostUuid, Completion completion) { + new While<>(migrateVmExtensions).each((ext, comp) -> ext.preMigrateVm(inv, dstHostUuid, new Completion(comp) { + @Override + public void success() { + comp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + comp.addError(errorCode); + comp.allDone(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().size() > 0) { + completion.fail(errorCodeList.getCauses().get(0)); + } else { + completion.success(); + } + } + }); } public void beforeMigrateVm(final VmInstanceInventory inv, final String dstHostUuid) { CollectionUtils.safeForEach(migrateVmExtensions, arg -> arg.beforeMigrateVm(inv, dstHostUuid)); } - public void afterMigrateVm(final VmInstanceInventory inv, final String srcHostUuid) { - CollectionUtils.safeForEach(migrateVmExtensions, new ForEachFunction() { + public void postMigrateVm(final VmInstanceInventory inv, final String dstHostUuid, Completion completion) { + new While<>(migrateVmExtensions).each((ext, comp) -> ext.postMigrateVm(inv, dstHostUuid, new Completion(comp) { + @Override + public void success() { + comp.done(); + } + @Override - public void run(VmInstanceMigrateExtensionPoint arg) { - arg.afterMigrateVm(inv, srcHostUuid); + public void fail(ErrorCode errorCode) { + comp.addError(errorCode); + comp.allDone(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().size() > 0) { + completion.fail(errorCodeList.getCauses().get(0)); + } else { + completion.success(); + } } }); } - public void failedToMigrateVm(final VmInstanceInventory inv, final String dstHostUuid, final ErrorCode reason) { - CollectionUtils.safeForEach(migrateVmExtensions, new ForEachFunction() { + public void afterMigrateVm(final VmInstanceInventory inv, final String srcHostUuid, NoErrorCompletion completion) { + new While<>(migrateVmExtensions).each((ext, comp) -> ext.afterMigrateVm(inv, srcHostUuid, new NoErrorCompletion(comp) { @Override - public void run(final VmInstanceMigrateExtensionPoint arg) { - arg.failedToMigrateVm(inv, dstHostUuid, reason); + public void done() { + comp.done(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.done(); } }); } - public void preAttachVolume(VmInstanceInventory vm, VolumeInventory volume) { - for (VmAttachVolumeExtensionPoint ext : attachVolumeExtensions) { - ext.preAttachVolume(vm, volume); - } + public void failedToMigrateVm(final VmInstanceInventory inv, final String dstHostUuid, final ErrorCode reason, NoErrorCompletion completion) { + new While<>(migrateVmExtensions).each((ext, comp) -> ext.failedToMigrateVm(inv, dstHostUuid, reason, new NoErrorCompletion(comp) { + @Override + public void done() { + comp.done(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.done(); + } + }); + } + + public void preAttachVolume(VmInstanceInventory vm, VolumeInventory volume, Completion completion) { + new While<>(attachVolumeExtensions).each((ext, comp) -> ext.preAttachVolume(vm, volume, new Completion(comp) { + @Override + public void success() { + comp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + comp.addError(errorCode); + comp.allDone(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().size() > 0) { + completion.fail(errorCodeList.getCauses().get(0)); + } else { + completion.success(); + } + } + }); } public void beforeAttachVolume(final VmInstanceInventory vm, final VolumeInventory volume, Map data) { @@ -368,10 +455,47 @@ public void run(VmAttachVolumeExtensionPoint arg) { }); } - public void preDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume) { - for (VmDetachVolumeExtensionPoint ext : detachVolumeExtensions) { - ext.preDetachVolume(vm, volume); - } + public void afterInstantiateVolume(VmInstanceInventory inv, VolumeInventory volume, NoErrorCompletion completion) { + new While<>(attachVolumeExtensions).each((ext, comp) -> ext.afterInstantiateVolume(inv, volume, new Completion(comp) { + @Override + public void success() { + comp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + comp.done(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.done(); + } + }); + } + + public void preDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume, Completion completion) { + new While<>(detachVolumeExtensions).each((ext, comp) -> ext.preDetachVolume(vm, volume, new Completion(comp) { + @Override + public void success() { + comp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + comp.addError(errorCode); + comp.allDone(); + } + })).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().size() > 0) { + completion.fail(errorCodeList.getCauses().get(0)); + } else { + completion.success(); + } + } + }); } public void beforeDetachVolume(final VmInstanceInventory vm, final VolumeInventory volume) { @@ -403,7 +527,9 @@ public void success() { @Override public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + logger.debug(String.format("found a error when calling afterDetachVolume[volumeUuid:%s] extension point" + + ":%s, ignore it", volume.getUuid(), errorCode.getDetails())); + trigger.next(); } }); } @@ -450,8 +576,41 @@ public void cleanUpAfterVmChangeImage(final VmInstanceInventory vm) { CollectionUtils.safeForEach(cleanUpAfterVmChangeImageExtensionPoints, arg -> arg.cleanUpAfterVmChangeImage(vm)); } + public void afterChangeVmNicState(final String vmNic, final String state) { + CollectionUtils.safeForEach(vmNicChangeStateExtensionPoints, arg -> arg.afterChangeVmNicState(vmNic, state)); + } + + public List associateSshKeyPair(String vmUuid, List sshKeyUuids) { + List errorCodes = new ArrayList<>(); + CollectionUtils.safeForEach(sshKeyPairAssociateExtensionPoints, extension -> { + ErrorCode errorCode = extension.associateSshKeyPair(vmUuid, sshKeyUuids); + if (errorCode != null) { + errorCodes.add(errorCode); + } + }); + return errorCodes; + } + + public List fetchAssociatedSshKeyPairs(String vmUuid) { + List sshKeyPairs = new ArrayList<>(); + CollectionUtils.safeForEach(sshKeyPairAssociateExtensionPoints, extension -> { + List keyPairs = extension.fetchAssociatedSshKeyPairs(vmUuid); + if (!keyPairs.isEmpty()) { + sshKeyPairs.addAll(keyPairs); + } + }); + return sshKeyPairs; + } + + public void cloneSshKeyPairsToVm(String originVmUuid, String destVmUuid) { + CollectionUtils.safeForEach(sshKeyPairAssociateExtensionPoints, extension -> { + extension.cloneSshKeyPairsToVm(originVmUuid, destVmUuid); + }); + } + private void populateExtensions() { VmInstanceBeforeStartExtensions = pluginRgty.getExtensionList(VmInstanceBeforeStartExtensionPoint.class); + VmInstanceResumeExtensionPoints = pluginRgty.getExtensionList(VmInstanceResumeExtensionPoint.class); startNewCreatedVmExtensions = pluginRgty.getExtensionList(VmInstanceStartNewCreatedVmExtensionPoint.class); beforeVmStopExtensions = pluginRgty.getExtensionList(BeforeVmInstanceStopExtensionPoint.class); stopVmExtensions = pluginRgty.getExtensionList(VmInstanceStopExtensionPoint.class); @@ -464,6 +623,8 @@ private void populateExtensions() { capabilitiesExtensionPoints = pluginRgty.getExtensionList(VmCapabilitiesExtensionPoint.class); cleanUpAfterVmFailedToStartExtensionPoints = pluginRgty.getExtensionList(CleanUpAfterVmFailedToStartExtensionPoint.class); cleanUpAfterVmChangeImageExtensionPoints = pluginRgty.getExtensionList(CleanUpAfterVmChangeImageExtensionPoint.class); + vmNicChangeStateExtensionPoints = pluginRgty.getExtensionList(VmNicChangeStateExtensionPoint.class); + sshKeyPairAssociateExtensionPoints = pluginRgty.getExtensionList(SshKeyPairAssociateExtensionPoint.class); } @Override diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceHookManagerImpl.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceHookManagerImpl.java index 831e0e84b8a..798f0e33006 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceHookManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceHookManagerImpl.java @@ -1,6 +1,5 @@ package org.zstack.compute.vm; -import edu.emory.mathcs.backport.java.util.Collections; import org.zstack.core.defer.Defer; import org.zstack.core.defer.Deferred; import org.zstack.header.core.ExceptionSafe; @@ -9,6 +8,7 @@ import org.zstack.header.vm.hooks.*; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java index 7c5ac7e2e67..8ed1ba2e943 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java @@ -1,18 +1,19 @@ package org.zstack.compute.vm; import com.google.common.collect.Maps; -import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException; import org.apache.commons.lang.StringUtils; import org.apache.commons.validator.routines.DomainValidator; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.allocator.HostAllocatorManager; +import org.zstack.compute.vm.quota.*; +import org.zstack.configuration.DiskOfferingSystemTags; +import org.zstack.configuration.InstanceOfferingSystemTags; +import org.zstack.configuration.OfferingUserConfigUtils; import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; -import org.zstack.core.cloudbus.CloudBus; -import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.cloudbus.CloudBusListCallBack; -import org.zstack.core.cloudbus.ResourceDestinationMaker; +import org.zstack.core.cloudbus.*; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.config.GlobalConfig; import org.zstack.core.config.GlobalConfigBeforeUpdateExtensionPoint; @@ -23,6 +24,8 @@ import org.zstack.core.jsonlabel.JsonLabel; import org.zstack.core.thread.*; import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.directory.ResourceDirectoryRefVO; import org.zstack.header.AbstractService; import org.zstack.header.allocator.AllocateHostDryRunReply; import org.zstack.header.allocator.DesignatedAllocateHostMsg; @@ -32,30 +35,28 @@ import org.zstack.header.cluster.ClusterInventory; import org.zstack.header.cluster.ClusterVO; import org.zstack.header.configuration.*; -import org.zstack.header.core.Completion; -import org.zstack.header.core.NopeWhileDoneCompletion; -import org.zstack.header.core.ReturnValueCompletion; -import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.configuration.userconfig.DiskOfferingUserConfig; +import org.zstack.header.configuration.userconfig.InstanceOfferingUserConfig; +import org.zstack.header.core.*; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudConfigureFailException; import org.zstack.header.exception.CloudRuntimeException; -import org.zstack.header.host.AfterChangeHostStatusExtensionPoint; -import org.zstack.header.host.HostConstant; -import org.zstack.header.host.HostInventory; -import org.zstack.header.host.HostStatus; +import org.zstack.header.host.*; import org.zstack.header.identity.*; -import org.zstack.header.identity.Quota.QuotaOperator; import org.zstack.header.identity.Quota.QuotaPair; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.image.*; import org.zstack.header.image.ImageConstant.ImageMediaType; import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; import org.zstack.header.message.*; import org.zstack.header.network.l3.*; +import org.zstack.header.storage.backup.BackupStorageInventory; import org.zstack.header.storage.backup.BackupStorageType; import org.zstack.header.storage.backup.BackupStorageVO; +import org.zstack.header.storage.backup.BackupStorageVO_; import org.zstack.header.storage.primary.*; import org.zstack.header.tag.SystemTagCreateMessageValidator; import org.zstack.header.tag.SystemTagVO; @@ -71,10 +72,8 @@ import org.zstack.identity.AccountManager; import org.zstack.identity.QuotaUtil; import org.zstack.network.l3.L3NetworkManager; -import org.zstack.resourceconfig.ResourceConfigFacade; -import org.zstack.tag.SystemTagCreator; -import org.zstack.tag.SystemTagUtils; -import org.zstack.tag.TagManager; +import org.zstack.resourceconfig.*; +import org.zstack.tag.*; import org.zstack.utils.*; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; @@ -84,16 +83,21 @@ import javax.persistence.PersistenceException; import javax.persistence.Tuple; import javax.persistence.TypedQuery; +import java.sql.SQLIntegrityConstraintViolationException; import java.sql.Timestamp; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import static java.lang.Integer.parseInt; +import static java.lang.Integer.valueOf; import static java.util.Arrays.asList; import static org.zstack.core.Platform.*; import static org.zstack.utils.CollectionDSL.*; +import static org.zstack.utils.CollectionUtils.merge; +import static org.zstack.utils.CollectionUtils.transformToList; public class VmInstanceManagerImpl extends AbstractService implements VmInstanceManager, @@ -103,9 +107,9 @@ public class VmInstanceManagerImpl extends AbstractService implements ResourceOwnerAfterChangeExtensionPoint, GlobalApiMessageInterceptor, AfterChangeHostStatusExtensionPoint, - VmInstanceMigrateExtensionPoint { + VmInstanceMigrateExtensionPoint, + VmInstanceBeforeStartExtensionPoint { private static final CLogger logger = Utils.getLogger(VmInstanceManagerImpl.class); - private final Map vmInstanceFactories = new ConcurrentHashMap<>(); private List createVmWorkFlowElements; private List stopVmWorkFlowElements; private List rebootVmWorkFlowElements; @@ -132,9 +136,6 @@ public class VmInstanceManagerImpl extends AbstractService implements private FlowChainBuilder resumeVmFlowBuilder; private static final Set allowedMessageAfterSoftDeletion = new HashSet<>(); private Future expungeVmTask; - private Map vmInstanceBaseExtensionFactories = new HashMap<>(); - private Map vmInstanceNicFactories = new HashMap<>(); - private Map vmNicQosConfigMap = new HashMap<>(); static { allowedMessageAfterSoftDeletion.add(VmInstanceDeletionMsg.class); @@ -168,6 +169,10 @@ public class VmInstanceManagerImpl extends AbstractService implements protected L3NetworkManager l3nm; @Autowired private ResourceConfigFacade rcf; + @Autowired + private VmFactoryManager vmFactoryManager; + @Autowired + protected EventFacade evtf; private List vmExtensionManagers = new ArrayList<>(); @@ -227,6 +232,8 @@ private void handleApiMessage(APIMessage msg) { handle((APIGetCandidatePrimaryStoragesForCreatingVmMsg) msg); } else if (msg instanceof APIGetInterdependentL3NetworksImagesMsg) { handle((APIGetInterdependentL3NetworksImagesMsg) msg); + } else if (msg instanceof APIGetInterdependentL3NetworksBackupStoragesMsg) { + handle((APIGetInterdependentL3NetworksBackupStoragesMsg) msg); } else if (msg instanceof APIGetCandidateVmForAttachingIsoMsg) { handle((APIGetCandidateVmForAttachingIsoMsg) msg); } else if (msg instanceof APIUpdatePriorityConfigMsg) { @@ -242,9 +249,29 @@ private void handleApiMessage(APIMessage msg) { } } + private void handle(APIGetInterdependentL3NetworksBackupStoragesMsg msg) { + final String accountUuid = msg.getSession().getAccountUuid(); + APIGetInterdependentL3NetworksBackupStoragesReply reply = + new APIGetInterdependentL3NetworksBackupStoragesReply(); + if (msg.getBackupStorageUuid() != null) { + BackupStorageVO bsvo = Q.New(BackupStorageVO.class) + .eq(BackupStorageVO_.uuid, msg.getBackupStorageUuid()) + .find(); + if (bsvo == null) { + reply.setInventories(new ArrayList<>()); + } else { + reply.setInventories(getInterdependentL3NetworksByBackupStorageUuids(Collections.singletonList(bsvo), + msg.getZoneUuid(), accountUuid, false)); + } + } else { + reply.setInventories(getInterdependentBackupStoragesByL3NetworkUuids(msg.getL3NetworkUuids())); + } + + bus.reply(msg, reply); + } + private void handle(final APIGetVmsCapabilitiesMsg msg) { - APIGetVmsCapabilitiesEvent evt = new APIGetVmsCapabilitiesEvent(msg.getId()); - ErrorCodeList err = new ErrorCodeList(); + APIGetVmsCapabilitiesReply reply = new APIGetVmsCapabilitiesReply(); Map vmsCaps = Maps.newConcurrentMap(); msg.getVmUuids() .parallelStream() @@ -252,8 +279,8 @@ private void handle(final APIGetVmsCapabilitiesMsg msg) { vmsCaps.put(v, new VmCapabilitiesJudger().judge(v)); }); - evt.setVmsCaps(vmsCaps); - bus.publish(evt); + reply.setVmsCaps(vmsCaps); + bus.reply(msg, reply); } private void handle(final APIUpdatePriorityConfigMsg msg) { @@ -353,9 +380,38 @@ private void handle(APIGetCandidateVmForAttachingIsoMsg msg) { private void handle(APIGetInterdependentL3NetworksImagesMsg msg) { final String accountUuid = msg.getSession().getAccountUuid(); if (msg.getImageUuid() != null) { - getInterdependentL3NetworksByImageUuid(msg, accountUuid); - } else { + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("get-interdependent-l3-by-image-%s-in-zone-%s", + msg.getImageUuid(), + msg.getZoneUuid())) + .run((completion) -> completion.success(getInterdependentL3NetworksByImageUuid(msg, accountUuid))) + .done(((result) -> { + APIGetInterdependentL3NetworkImageReply reply = new APIGetInterdependentL3NetworkImageReply(); + if (!result.isSuccess()) { + reply.setError(result.getErrorCode()); + } else { + reply.setInventories((List) result.getResult()); + } + + bus.reply(msg, reply); + }))); + } else if (msg.getL3NetworkUuids() != null) { getInterdependentImagesByL3NetworkUuids(msg); + } else { + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("get-interdependent-l3-by-zone-%s", + msg.getZoneUuid())) + .run((completion) -> completion.success(getInterdependentL3NetworksByImageUuid(msg, accountUuid))) + .done(((result) -> { + APIGetInterdependentL3NetworkImageReply reply = new APIGetInterdependentL3NetworkImageReply(); + if (!result.isSuccess()) { + reply.setError(result.getErrorCode()); + } else { + reply.setInventories((List) result.getResult()); + } + + bus.reply(msg, reply); + }))); } } @@ -371,11 +427,9 @@ private List listIntersection(List a, List getInterdependentBackupStoragesByL3NetworkUuids(List l3s) { List> bss = new ArrayList<>(); - for (String l3uuid : msg.getL3NetworkUuids()) { + for (String l3uuid : l3s) { String sql = "select ps" + " from PrimaryStorageVO ps, L2NetworkClusterRefVO l2ref," + " L3NetworkVO l3, PrimaryStorageClusterRefVO psref" + @@ -416,13 +470,22 @@ private void getInterdependentImagesByL3NetworkUuids(APIGetInterdependentL3Netwo selectedBss = listIntersection(selectedBss, l); } - if (selectedBss.isEmpty()) { - reply.setInventories(new ArrayList()); + return BackupStorageInventory.valueOf(selectedBss); + } + + @Transactional(readOnly = true) + private void getInterdependentImagesByL3NetworkUuids(APIGetInterdependentL3NetworksImagesMsg msg) { + APIGetInterdependentL3NetworkImageReply reply = new APIGetInterdependentL3NetworkImageReply(); + + List bss = getInterdependentBackupStoragesByL3NetworkUuids(msg.getL3NetworkUuids()); + + if (bss.isEmpty()) { + reply.setInventories(new ArrayList<>()); bus.reply(msg, reply); return; } - List bsUuids = selectedBss.stream().map(BackupStorageVO::getUuid).collect(Collectors.toList()); + List bsUuids = bss.stream().map(BackupStorageInventory::getUuid).collect(Collectors.toList()); String sql = "select img" + " from ImageVO img, ImageBackupStorageRefVO iref, BackupStorageZoneRefVO zref, BackupStorageVO bs" + " where img.uuid = iref.imageUuid" + @@ -440,24 +503,47 @@ private void getInterdependentImagesByL3NetworkUuids(APIGetInterdependentL3Netwo } @Transactional(readOnly = true) - private void getInterdependentL3NetworksByImageUuid(APIGetInterdependentL3NetworksImagesMsg msg, String accountUuid) { - APIGetInterdependentL3NetworkImageReply reply = new APIGetInterdependentL3NetworkImageReply(); + private List getInterdependentL3NetworksByImageUuid(APIGetInterdependentL3NetworksImagesMsg msg, String accountUuid) { + List bss = null; + if (msg.getImageUuid() != null) { + String sql = "select bs" + + " from BackupStorageVO bs, ImageBackupStorageRefVO ref, BackupStorageZoneRefVO zref" + + " where bs.uuid = ref.backupStorageUuid" + + " and ref.imageUuid = :imgUuid" + + " and ref.backupStorageUuid = zref.backupStorageUuid" + + " and zref.zoneUuid = :zoneUuid"; + TypedQuery bsq = dbf.getEntityManager().createQuery(sql, BackupStorageVO.class); + bsq.setParameter("imgUuid", msg.getImageUuid()); + bsq.setParameter("zoneUuid", msg.getZoneUuid()); + bss = bsq.getResultList(); + } else { + String sql = "select bs" + + " from BackupStorageVO bs, BackupStorageZoneRefVO zref" + + " where bs.uuid = zref.backupStorageUuid" + + " and zref.zoneUuid = :zoneUuid"; + TypedQuery bsq = dbf.getEntityManager().createQuery(sql, BackupStorageVO.class); + bsq.setParameter("zoneUuid", msg.getZoneUuid()); + bss = bsq.getResultList(); + } - String sql = "select bs" + - " from BackupStorageVO bs, ImageBackupStorageRefVO ref, BackupStorageZoneRefVO zref" + - " where bs.uuid = ref.backupStorageUuid" + - " and ref.imageUuid = :imgUuid" + - " and ref.backupStorageUuid = zref.backupStorageUuid" + - " and zref.zoneUuid = :zoneUuid"; - TypedQuery bsq = dbf.getEntityManager().createQuery(sql, BackupStorageVO.class); - bsq.setParameter("imgUuid", msg.getImageUuid()); - bsq.setParameter("zoneUuid", msg.getZoneUuid()); - List bss = bsq.getResultList(); if (bss.isEmpty()) { throw new OperationFailureException(argerr("the image[uuid:%s] is not on any backup storage that has been attached to the zone[uuid:%s]", msg.getImageUuid(), msg.getZoneUuid())); } + List l3s = getInterdependentL3NetworksByBackupStorageUuids(bss, msg.getZoneUuid(), accountUuid, msg.getRaiseException()); + + List bsUuids = bss.stream().map(BackupStorageVO::getUuid).collect(Collectors.toList()); + for (GetInterdependentL3NetworksExtensionPoint ext : pluginRgty.getExtensionList(GetInterdependentL3NetworksExtensionPoint.class)) { + l3s = ext.afterFilterByImage(l3s, bsUuids, msg.getImageUuid()); + } + + return l3s; + } + + @Transactional(readOnly = true) + private List getInterdependentL3NetworksByBackupStorageUuids(List bss, String zoneUuid, String accountUuid, boolean raiseException) { + List psUuids = new ArrayList<>(); List l3s = new ArrayList<>(); for (BackupStorageVO bs : bss) { BackupStorageType bsType = BackupStorageType.valueOf(bs.getType()); @@ -465,56 +551,115 @@ private void getInterdependentL3NetworksByImageUuid(APIGetInterdependentL3Networ if (relatedPrimaryStorageUuids == null) { // the backup storage has no strongly-bound primary storage List psTypes = hostAllocatorMgr.getPrimaryStorageTypesByBackupStorageTypeFromMetrics(bs.getType()); - sql = "select l3" + - " from L3NetworkVO l3, L2NetworkClusterRefVO l2ref," + - " PrimaryStorageClusterRefVO psref, PrimaryStorageVO ps" + - " where l3.l2NetworkUuid = l2ref.l2NetworkUuid" + - " and l2ref.clusterUuid = psref.clusterUuid" + - " and psref.primaryStorageUuid = ps.uuid" + - " and ps.type in (:psTypes)" + - " and ps.zoneUuid = l3.zoneUuid" + - " and l3.zoneUuid = :zoneUuid" + - " group by l3.uuid"; - TypedQuery l3q = dbf.getEntityManager().createQuery(sql, L3NetworkVO.class); - l3q.setParameter("psTypes", psTypes); - l3q.setParameter("zoneUuid", msg.getZoneUuid()); - l3s.addAll(l3q.getResultList()); + psUuids.addAll(Q.New(PrimaryStorageVO.class) + .select(PrimaryStorageVO_.uuid) + .in(PrimaryStorageVO_.type, psTypes) + .eq(PrimaryStorageVO_.zoneUuid, zoneUuid) + .listValues()); + l3s.addAll(SQL.New("select l3" + + " from L3NetworkVO l3, L2NetworkClusterRefVO l2ref," + + " PrimaryStorageClusterRefVO psref, PrimaryStorageVO ps" + + " where l3.l2NetworkUuid = l2ref.l2NetworkUuid" + + " and l2ref.clusterUuid = psref.clusterUuid" + + " and psref.primaryStorageUuid = ps.uuid" + + " and ps.type in (:psTypes)" + + " and ps.zoneUuid = l3.zoneUuid" + + " and l3.zoneUuid = :zoneUuid" + + " group by l3.uuid") + .param("psTypes", psTypes) + .param("zoneUuid", zoneUuid) + .list()); } else if (!relatedPrimaryStorageUuids.isEmpty()) { // the backup storage has strongly-bound primary storage, e.g. ceph - sql = "select l3" + - " from L3NetworkVO l3, L2NetworkClusterRefVO l2ref," + - " PrimaryStorageClusterRefVO psref, PrimaryStorageVO ps" + - " where l3.l2NetworkUuid = l2ref.l2NetworkUuid" + - " and l2ref.clusterUuid = psref.clusterUuid" + - " and psref.primaryStorageUuid = ps.uuid" + - " and ps.uuid in (:psUuids)" + - " and ps.zoneUuid = l3.zoneUuid" + - " and l3.zoneUuid = :zoneUuid" + - " group by l3.uuid"; - TypedQuery l3q = dbf.getEntityManager().createQuery(sql, L3NetworkVO.class); - l3q.setParameter("psUuids", relatedPrimaryStorageUuids); - l3q.setParameter("zoneUuid", msg.getZoneUuid()); - l3s.addAll(l3q.getResultList()); + psUuids.addAll(Q.New(PrimaryStorageVO.class) + .select(PrimaryStorageVO_.uuid) + .in(PrimaryStorageVO_.uuid, relatedPrimaryStorageUuids) + .eq(PrimaryStorageVO_.zoneUuid, zoneUuid) + .listValues()); + l3s.addAll(SQL.New("select l3" + + " from L3NetworkVO l3, L2NetworkClusterRefVO l2ref," + + " PrimaryStorageClusterRefVO psref, PrimaryStorageVO ps" + + " where l3.l2NetworkUuid = l2ref.l2NetworkUuid" + + " and l2ref.clusterUuid = psref.clusterUuid" + + " and psref.primaryStorageUuid = ps.uuid" + + " and ps.uuid in (:psUuids)" + + " and ps.zoneUuid = l3.zoneUuid" + + " and l3.zoneUuid = :zoneUuid" + + " group by l3.uuid") + .param("psUuids", relatedPrimaryStorageUuids) + .param("zoneUuid", zoneUuid) + .list()); } else { + // relatedPrimaryStorageUuids is not null, but size is 0 logger.warn(String.format("the backup storage[uuid:%s, type: %s] needs a strongly-bound primary storage," + " but seems the primary storage is not added", bs.getUuid(), bs.getType())); } } - List bsUuids = bss.stream().map(BackupStorageVO::getUuid).collect(Collectors.toList()); - for (GetInterdependentL3NetworksExtensionPoint ext : pluginRgty.getExtensionList(GetInterdependentL3NetworksExtensionPoint.class)) { - l3s = ext.afterFilterByImage(l3s, bsUuids, msg.getImageUuid()); + if (l3s.isEmpty()) { + if (psUuids.isEmpty()) { + if (raiseException) { + throw new OperationFailureException(argerr("no primary storage accessible to the backup storage[uuid:%s, type:%s] is found", + bss.get(0).getUuid(), bss.get(0).getType())); + } + logger.warn(String.format("no primary storage accessible to the backup storage[uuid:%s, type:%s] is found", + bss.get(0).getUuid(), bss.get(0).getType())); + return new ArrayList<>(); + } + + Long clusterNum = SQL.New("select count(distinct cl)" + + " from ClusterVO cl, PrimaryStorageClusterRefVO psref, PrimaryStorageVO ps" + + " where cl.uuid = psref.clusterUuid" + + " and psref.primaryStorageUuid in (:psUuids)" + + " and ps.zoneUuid = cl.zoneUuid" + + " and cl.zoneUuid = :zoneUuid" + + " group by cl.uuid", Long.class) + .param("psUuids", psUuids) + .param("zoneUuid", zoneUuid) + .find(); + + if (clusterNum == null || clusterNum == 0) { + if (raiseException) { + throw new OperationFailureException(argerr("the primary storages[uuids:%s] has not attached any cluster on the zone[uuid:%s]", + psUuids, zoneUuid)); + } + logger.warn(String.format("the primary storages[uuids:%s] has not attached any cluster on the zone[uuid:%s]", psUuids, zoneUuid)); + return new ArrayList<>(); + } + + Long l2Num = SQL.New("select count(distinct l2)" + + " from L2NetworkVO l2, L2NetworkClusterRefVO l2ref, PrimaryStorageClusterRefVO psref, PrimaryStorageVO ps" + + " where l2.uuid = l2ref.l2NetworkUuid" + + " and psref.primaryStorageUuid in (:psUuids)" + + " and l2ref.clusterUuid = psref.clusterUuid" + + " and ps.zoneUuid = l2.zoneUuid" + + " and l2.zoneUuid = :zoneUuid", Long.class) + .param("psUuids", psUuids) + .param("zoneUuid", zoneUuid) + .find(); + if (l2Num == null || l2Num == 0) { + if (raiseException) { + throw new OperationFailureException(argerr("no l2Networks found in clusters that have attached to primary storages[uuids:%s]", + psUuids)); + } + logger.warn(String.format("no l2Networks found in clusters that have attached to primary storages[uuids:%s]", psUuids)); + return new ArrayList<>(); + } } - List l3sFromAccount = acntMgr.getResourceUuidsCanAccessByAccount(accountUuid, L3NetworkVO.class); - if (l3sFromAccount == null) { - reply.setInventories(L3NetworkInventory.valueOf(l3s)); + List l3UuidListOfCurrentAccount; + if (!AccountConstant.isAdminPermission(accountUuid)) { + l3UuidListOfCurrentAccount = acntMgr.getResourceUuidsCanAccessByAccount(accountUuid, L3NetworkVO.class); } else { - reply.setInventories(L3NetworkInventory.valueOf(l3s.stream() - .filter(vo -> l3sFromAccount.contains(vo.getUuid())) - .collect(Collectors.toList()))); + l3UuidListOfCurrentAccount = null; } - bus.reply(msg, reply); + + if (l3UuidListOfCurrentAccount == null) { + return L3NetworkInventory.valueOf(l3s); + } + return L3NetworkInventory.valueOf(l3s.stream() + .filter(vo -> l3UuidListOfCurrentAccount.contains(vo.getUuid())) + .collect(Collectors.toList())); } private void handle(APIGetCandidateZonesClustersHostsForCreatingVmMsg msg) { @@ -608,12 +753,13 @@ public void run(MessageReply reply) { if (!re.getHosts().isEmpty()) { areply.setHosts(re.getHosts()); - List clusterUuids = re.getHosts().stream(). - map(HostInventory::getClusterUuid).collect(Collectors.toList()); - areply.setClusters(ClusterInventory.valueOf(dbf.listByPrimaryKeys(clusterUuids, ClusterVO.class))); + Set clusterUuids = re.getHosts().stream(). + map(HostInventory::getClusterUuid).collect(Collectors.toSet()); + List clusters = ClusterInventory.valueOf(dbf.listByPrimaryKeys(clusterUuids, ClusterVO.class)); + areply.setClusters(clusters); - List zoneUuids = re.getHosts().stream(). - map(HostInventory::getZoneUuid).collect(Collectors.toList()); + Set zoneUuids = clusters.stream(). + map(ClusterInventory::getZoneUuid).collect(Collectors.toSet()); areply.setZones(ZoneInventory.valueOf(dbf.listByPrimaryKeys(zoneUuids, ZoneVO.class))); } else { areply.setHosts(new ArrayList<>()); @@ -681,6 +827,7 @@ protected ImageInventory scripts() { } else { Tuple t = Q.New(DiskOfferingVO.class).eq(DiskOfferingVO_.uuid, msg.getRootDiskOfferingUuid()) .select(DiskOfferingVO_.diskSize, DiskOfferingVO_.allocatorStrategy).findTuple(); + rmsg.setSize((long) t.get(0)); rmsg.setAllocationStrategy((String) t.get(1)); rmsg.setDiskOfferingUuid(msg.getRootDiskOfferingUuid()); @@ -688,6 +835,23 @@ protected ImageInventory scripts() { } else { rmsg.setSize(imageInv.getSize()); } + + if (msg.getRootDiskOfferingUuid() != null && DiskOfferingSystemTags.DISK_OFFERING_USER_CONFIG.hasTag(msg.getRootDiskOfferingUuid())) { + DiskOfferingUserConfig config = OfferingUserConfigUtils.getDiskOfferingConfig(msg.getRootDiskOfferingUuid(), DiskOfferingUserConfig.class); + if (config.getAllocate() != null && config.getAllocate().getPrimaryStorage() != null) { + String psUuid = config.getAllocate().getPrimaryStorage().getUuid(); + rmsg.setRequiredPrimaryStorageUuid(psUuid); + } + } + + if (msg.getInstanceOfferingUuid() != null && InstanceOfferingSystemTags.INSTANCE_OFFERING_USER_CONFIG.hasTag(msg.getInstanceOfferingUuid())) { + InstanceOfferingUserConfig config = OfferingUserConfigUtils.getInstanceOfferingConfig(msg.getInstanceOfferingUuid(), InstanceOfferingUserConfig.class); + if (config.getAllocate() != null && config.getAllocate().getPrimaryStorage() != null) { + String psUuid = config.getAllocate().getPrimaryStorage().getUuid(); + rmsg.setRequiredPrimaryStorageUuid(psUuid); + } + } + rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateNewVm.toString()); rmsg.setPossiblePrimaryStorageTypes(new ArrayList<>(psTypes)); bus.makeLocalServiceId(rmsg, PrimaryStorageConstant.SERVICE_ID); @@ -701,6 +865,14 @@ protected ImageInventory scripts() { amsg.setRequiredClusterUuids(clusterUuids); amsg.setAllocationStrategy(dinv.getAllocatorStrategy()); amsg.setDiskOfferingUuid(dinv.getUuid()); + if (DiskOfferingSystemTags.DISK_OFFERING_USER_CONFIG.hasTag(dinv.getUuid())) { + DiskOfferingUserConfig config = OfferingUserConfigUtils.getDiskOfferingConfig(dinv.getUuid(), DiskOfferingUserConfig.class); + if (config.getAllocate() != null && config.getAllocate().getPrimaryStorage() != null) { + String psUuid = config.getAllocate().getPrimaryStorage().getUuid(); + amsg.setRequiredPrimaryStorageUuid(psUuid); + } + } + bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); msgs.add(amsg); } @@ -756,16 +928,20 @@ private void handle(APICreateVmNicMsg msg) { @Override public void run(FlowTrigger trigger, Map data) { int deviceId = 1; - String mac = NetworkUtils.generateMacWithDeviceId((short) deviceId); + String mac = MacOperator.generateMacWithDeviceId((short) deviceId); nic.setUuid(Platform.getUuid()); nic.setMac(mac); nic.setDeviceId(deviceId); + nic.setType(VmInstanceConstant.VIRTUAL_NIC_TYPE); + for (NicManageExtensionPoint ext : pluginRgty.getExtensionList(NicManageExtensionPoint.class)) { + ext.beforeCreateNic(nic, msg); + } nicVO.setUuid(nic.getUuid()); nicVO.setDeviceId(deviceId); - nicVO.setMac(mac); + nicVO.setMac(nic.getMac()); nicVO.setAccountUuid(msg.getSession().getAccountUuid()); - nicVO.setType(VmInstanceConstant.VIRTUAL_NIC_TYPE); + nicVO.setType(nic.getType()); int tries = 5; while (tries-- > 0) { @@ -778,12 +954,12 @@ protected void scripts() { }.execute(); break; } catch (PersistenceException e) { - if (ExceptionDSL.isCausedBy(e, MySQLIntegrityConstraintViolationException.class, "Duplicate entry")) { + if (ExceptionDSL.isCausedBy(e, SQLIntegrityConstraintViolationException.class, "Duplicate entry")) { logger.debug(String.format("Concurrent mac allocation. Mac[%s] has been allocated, try allocating another one. " + "The error[Duplicate entry] printed by jdbc.spi.SqlExceptionHelper is no harm, " + "we will try finding another mac", nicVO.getMac())); logger.trace("", e); - nicVO.setMac(NetworkUtils.generateMacWithDeviceId((short) nicVO.getDeviceId())); + nicVO.setMac(MacOperator.generateMacWithDeviceId((short) nicVO.getDeviceId())); } else { throw e; } @@ -803,6 +979,9 @@ public void run(FlowTrigger trigger, Map data) { AllocateIpMsg allocateIpMsg = new AllocateIpMsg(); allocateIpMsg.setL3NetworkUuid(msg.getL3NetworkUuid()); allocateIpMsg.setRequiredIp(msg.getIp()); + if (msg.getIp() == null) { + allocateIpMsg.setRequiredIp(nic.getIp()); + } allocateIpMsg.setIpVersion(version); l3nm.updateIpAllocationMsg(allocateIpMsg, nic.getMac()); bus.makeTargetServiceIdByResourceUuid(allocateIpMsg, L3NetworkConstant.SERVICE_ID, msg.getL3NetworkUuid()); @@ -911,13 +1090,88 @@ private void handle(APIGetVmNicAttachedNetworkServiceMsg msg) { bus.reply(msg, reply); } + private void instantiateTagsForCreateMessage(final CreateVmInstanceMsg msg, final APICreateMessage cmsg, VmInstanceVO finalVo) { + if (cmsg != null) { + tagMgr.createTagsFromAPICreateMessage(cmsg, finalVo.getUuid(), VmInstanceVO.class.getSimpleName()); + } else { + tagMgr.createTags(msg.getSystemTags(), msg.getUserTags(), finalVo.getUuid(), VmInstanceVO.class.getSimpleName()); + } + + boolean isVirtio = false; + if (!CollectionUtils.isEmpty(msg.getDiskAOs())) { + isVirtio = msg.getVirtio(); + } else { + if (Q.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).eq(ImageVO_.virtio, true).isExists()) { + isVirtio = true; + } + } + if (isVirtio) { + SystemTagCreator creator = VmSystemTags.VIRTIO.newSystemTagCreator(finalVo.getUuid()); + creator.recreate = true; + creator.inherent = false; + creator.tag = VmSystemTags.VIRTIO.getTagFormat(); + creator.create(); + } + + if (finalVo.getInstanceOfferingUuid() != null) { + tagMgr.copySystemTag( + finalVo.getInstanceOfferingUuid(), + InstanceOfferingVO.class.getSimpleName(), + finalVo.getUuid(), + VmInstanceVO.class.getSimpleName(), false); + } + + if (msg.getImageUuid() != null) { + tagMgr.copySystemTag( + msg.getImageUuid(), + ImageVO.class.getSimpleName(), + finalVo.getUuid(), + VmInstanceVO.class.getSimpleName(), false); + } + + if (ImageArchitecture.aarch64.toString().equals(finalVo.getArchitecture())) { + SystemTagCreator creator = VmSystemTags.MACHINE_TYPE.newSystemTagCreator(finalVo.getUuid()); + creator.setTagByTokens(map(e(VmSystemTags.MACHINE_TYPE_TOKEN, VmMachineType.virt.toString()))); + creator.recreate = true; + creator.create(); + } + + SystemTagCreator creator = VmSystemTags.SYNC_PORTS.newSystemTagCreator(finalVo.getUuid()); + creator.recreate = true; + creator.setTagByTokens(map(e(VmSystemTags.SYNC_PORTS_TOKEN, finalVo.getUuid()))); + creator.create(); + } + + private List extEmitterHandleSystemTag(final CreateVmInstanceMsg msg, final APICreateMessage cmsg, VmInstanceVO finalVo) { + List result = Collections.emptyList(); + if (msg == null) { + result.add(operr("CreateVmInstanceMsg cannot be null")); + return result; + } else if (cmsg != null && cmsg.getSystemTags() != null && !cmsg.getSystemTags().isEmpty()) { + return extEmitter.handleSystemTag(finalVo.getUuid(), cmsg.getSystemTags()); + } else if (cmsg == null && msg.getSystemTags() != null && !msg.getSystemTags().isEmpty()) { + return extEmitter.handleSystemTag(finalVo.getUuid(), msg.getSystemTags()); + } + return result; + } + + private List extEmitterHandleSshKeyPair(final CreateVmInstanceMsg msg, final APICreateMessage cmsg, VmInstanceVO finalVo) { + List result = Collections.emptyList(); + if (msg == null) { + result.add(operr("CreateVmInstanceMsg cannot be null")); + return result; + } else if (msg.getSshKeyPairUuids() != null && !msg.getSshKeyPairUuids().isEmpty()) { + return extEmitter.associateSshKeyPair(finalVo.getUuid(), msg.getSshKeyPairUuids()); + } + return result; + } + protected void doCreateVmInstance(final CreateVmInstanceMsg msg, final APICreateMessage cmsg, ReturnValueCompletion completion) { pluginRgty.getExtensionList(VmInstanceCreateExtensionPoint.class).forEach(extensionPoint -> { extensionPoint.preCreateVmInstance(msg); }); - final String instanceOfferingUuid = msg.getInstanceOfferingUuid(); - final String architecture = dbf.findByUuid(msg.getImageUuid(), ImageVO.class).getArchitecture(); + final ImageVO image = Q.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).find(); VmInstanceVO vo = new VmInstanceVO(); if (msg.getResourceUuid() != null) { vo.setUuid(msg.getResourceUuid()); @@ -928,24 +1182,19 @@ protected void doCreateVmInstance(final CreateVmInstanceMsg msg, final APICreate vo.setClusterUuid(msg.getClusterUuid()); vo.setDescription(msg.getDescription()); vo.setImageUuid(msg.getImageUuid()); - vo.setInstanceOfferingUuid(instanceOfferingUuid); + vo.setInstanceOfferingUuid(msg.getInstanceOfferingUuid()); vo.setState(VmInstanceState.Created); vo.setZoneUuid(msg.getZoneUuid()); vo.setInternalId(dbf.generateSequenceNumber(VmInstanceSequenceNumberVO.class)); vo.setDefaultL3NetworkUuid(msg.getDefaultL3NetworkUuid()); - vo.setArchitecture(architecture); - - SimpleQuery imgq = dbf.createQuery(ImageVO.class); - imgq.select(ImageVO_.platform); - imgq.add(ImageVO_.uuid, Op.EQ, msg.getImageUuid()); - ImagePlatform platform = imgq.findValue(); - vo.setPlatform(platform.toString()); - vo.setCpuNum(msg.getCpuNum()); vo.setCpuSpeed(msg.getCpuSpeed()); vo.setMemorySize(msg.getMemorySize()); + vo.setReservedMemorySize(msg.getReservedMemorySize()); vo.setAllocatorStrategy(msg.getAllocatorStrategy()); - vo.setGuestOsType(Q.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).select(ImageVO_.guestOsType).findValue()); + vo.setPlatform(msg.getPlatform() != null ? msg.getPlatform() : image.getPlatform().toString()); + vo.setGuestOsType(msg.getGuestOsType() != null ? msg.getGuestOsType() : image.getGuestOsType()); + vo.setArchitecture(msg.getArchitecture() != null ? msg.getArchitecture() : image.getArchitecture()); String vmType = msg.getType() == null ? VmInstanceConstant.USER_VM_TYPE : msg.getType(); VmInstanceType type = VmInstanceType.valueOf(vmType); VmInstanceFactory factory = getVmInstanceFactory(type); @@ -961,122 +1210,255 @@ protected VmInstanceVO scripts() { } }.execute(); - if (cmsg != null) { - tagMgr.createTagsFromAPICreateMessage(cmsg, vo.getUuid(), VmInstanceVO.class.getSimpleName()); - } else { - tagMgr.createTags(msg.getSystemTags(), msg.getUserTags(), vo.getUuid(), VmInstanceVO.class.getSimpleName()); - } + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("do-create-vmInstance-%s", vo.getUuid())); + chain.then(new ShareFlow() { + VmInstanceInventory instantiateVm; + List otherDisks = new ArrayList<>(); + boolean attachOtherDisk = false; - if ((boolean) Q.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).select(ImageVO_.virtio).findValue()) { - SystemTagCreator creator = VmSystemTags.VIRTIO.newSystemTagCreator(vo.getUuid()); - creator.recreate = true; - creator.inherent = false; - creator.tag = VmSystemTags.VIRTIO.getTagFormat(); - creator.create(); - } + @Override + public void setup() { + if (!CollectionUtils.isEmpty(msg.getDiskAOs())) { + otherDisks = msg.getDiskAOs().stream().filter(diskAO -> !diskAO.isBoot()).collect(Collectors.toList()); + setDiskAOsName(otherDisks); + attachOtherDisk = !otherDisks.isEmpty(); + } - if (instanceOfferingUuid != null) { - tagMgr.copySystemTag( - instanceOfferingUuid, - InstanceOfferingVO.class.getSimpleName(), - vo.getUuid(), - VmInstanceVO.class.getSimpleName(), false); - } + flow(new Flow() { + List errorCodes = new ArrayList<>(); + String __name__ = String.format("instantiate-systemTag-for-vm-%s", finalVo.getUuid()); - if (msg.getImageUuid() != null) { - tagMgr.copySystemTag( - msg.getImageUuid(), - ImageVO.class.getSimpleName(), - vo.getUuid(), - VmInstanceVO.class.getSimpleName(), false); + @Override + public void run(FlowTrigger trigger, Map data) { + try { + instantiateTagsForCreateMessage(msg, cmsg, finalVo); + } catch (Exception e) { + errorCodes.add(operr("instantiate system tag for vm failed because %s", e.getMessage())); + } + if (!errorCodes.isEmpty()) { + trigger.fail(errorCodes.get(0)); + return; + } - if (ImageArchitecture.aarch64.toString().equals(architecture)) { - SystemTagCreator creator = VmSystemTags.MACHINE_TYPE.newSystemTagCreator(vo.getUuid()); - creator.setTagByTokens(map(e(VmSystemTags.MACHINE_TYPE_TOKEN, VmMachineType.virt.toString()))); - creator.recreate = true; - creator.create(); - } - } + errorCodes = extEmitterHandleSystemTag(msg, cmsg, finalVo); + if (!errorCodes.isEmpty()) { + trigger.fail(operr("handle system tag fail when creating vm because [%s]", + StringUtils.join(errorCodes.stream().map(ErrorCode::getDescription).collect(Collectors.toList()), + ", "))); + return; + } + trigger.next(); + } - List errorCodes = Collections.emptyList(); - if (cmsg != null && cmsg.getSystemTags() != null && !cmsg.getSystemTags().isEmpty()) { - errorCodes = extEmitter.handleSystemTag(vo.getUuid(), cmsg.getSystemTags()); - } else if (cmsg == null && msg.getSystemTags() != null && !msg.getSystemTags().isEmpty()) { - errorCodes = extEmitter.handleSystemTag(vo.getUuid(), msg.getSystemTags()); - } + @Override + public void rollback(FlowRollback trigger, Map data) { + if (Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, finalVo.getUuid()).isExists()) { + dbf.removeByPrimaryKey(finalVo.getUuid(), VmInstanceVO.class); + } + trigger.rollback(); + } + }); - if (!errorCodes.isEmpty()) { - completion.fail(operr("handle system tag fail when creating vm because [%s]", - StringUtils.join(errorCodes.stream().map(ErrorCode::getDescription).collect(Collectors.toList()), - ", "))); - } + flow(new Flow() { + List errorCodes = Collections.emptyList(); + String __name__ = String.format("instantiate-ssh-key-pair-for-vm-%s", finalVo.getUuid()); - InstantiateNewCreatedVmInstanceMsg smsg = new InstantiateNewCreatedVmInstanceMsg(); - if (VmCreationStrategy.JustCreate == VmCreationStrategy.valueOf(msg.getStrategy())) { - VmInstanceInventory inv = VmInstanceInventory.valueOf(vo); - createVmButNotStart(msg, inv); - completion.success(inv); - return; - } + @Override + public void run(FlowTrigger trigger, Map data) { + errorCodes = extEmitterHandleSshKeyPair(msg, cmsg, finalVo); + if (!errorCodes.isEmpty()) { + trigger.fail(operr("handle sshkeypair fail when creating vm because [%s]", + StringUtils.join(errorCodes.stream().map(ErrorCode::getDetails).collect(Collectors.toList()), + ", "))); + return; + } + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, finalVo.getUuid()).isExists()) { + dbf.removeByPrimaryKey(finalVo.getUuid(), VmInstanceVO.class); + } + trigger.rollback(); + } + }); - smsg.setHostUuid(msg.getHostUuid()); - smsg.setDataDiskOfferingUuids(msg.getDataDiskOfferingUuids()); - smsg.setDataVolumeTemplateUuids(msg.getDataVolumeTemplateUuids()); - smsg.setDataVolumeFromTemplateSystemTags(msg.getDataVolumeFromTemplateSystemTags()); - smsg.setL3NetworkUuids(msg.getL3NetworkSpecs()); + flow(new Flow() { + String __name__ = "instantiate-new-created-vmInstance"; - if (msg.getRootDiskOfferingUuid() != null) { - smsg.setRootDiskOfferingUuid(msg.getRootDiskOfferingUuid()); - } else if (msg.getRootDiskSize() > 0) { - DiskOfferingVO dvo = new DiskOfferingVO(); - dvo.setUuid(Platform.getUuid()); - dvo.setAccountUuid(msg.getAccountUuid()); - dvo.setDiskSize(msg.getRootDiskSize()); - dvo.setName("for-create-vm-" + vo.getUuid()); - dvo.setType("DefaultDiskOfferingType"); - dvo.setState(DiskOfferingState.Enabled); - dvo.setAllocatorStrategy(PrimaryStorageConstant.DEFAULT_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE); - dbf.persist(dvo); - smsg.setRootDiskOfferingUuid(dvo.getUuid()); - } - - smsg.setVmInstanceInventory(VmInstanceInventory.valueOf(vo)); - smsg.setPrimaryStorageUuidForRootVolume(msg.getPrimaryStorageUuidForRootVolume()); - smsg.setPrimaryStorageUuidForDataVolume(msg.getPrimaryStorageUuidForDataVolume()); - smsg.setStrategy(msg.getStrategy()); - smsg.setTimeout(msg.getTimeout()); - smsg.setRootVolumeSystemTags(msg.getRootVolumeSystemTags()); - smsg.setDataVolumeSystemTags(msg.getDataVolumeSystemTags()); - bus.makeTargetServiceIdByResourceUuid(smsg, VmInstanceConstant.SERVICE_ID, vo.getUuid()); - bus.send(smsg, new CloudBusCallBack(smsg) { - @Override - public void run(MessageReply reply) { - try { - if (msg.getRootDiskOfferingUuid() == null && smsg.getRootDiskOfferingUuid() != null) { - dbf.removeByPrimaryKey(smsg.getRootDiskOfferingUuid(), DiskOfferingVO.class); + @Override + public void run(FlowTrigger trigger, Map data) { + InstantiateNewCreatedVmInstanceMsg smsg = new InstantiateNewCreatedVmInstanceMsg(); + smsg.setDisableL3Networks(msg.getDisableL3Networks()); + smsg.setHostUuid(msg.getHostUuid()); + List temporaryDiskOfferingUuids = createDiskOfferingUuidsFromDataDiskSizes(msg, finalVo.getUuid()); + smsg.setDataDiskOfferingUuids(merge(msg.getDataDiskOfferingUuids(), temporaryDiskOfferingUuids)); + smsg.setDataVolumeTemplateUuids(msg.getDataVolumeTemplateUuids()); + smsg.setDataVolumeFromTemplateSystemTags(msg.getDataVolumeFromTemplateSystemTags()); + smsg.setL3NetworkUuids(msg.getL3NetworkSpecs()); + + if (msg.getRootDiskOfferingUuid() != null) { + smsg.setRootDiskOfferingUuid(msg.getRootDiskOfferingUuid()); + } else if (msg.getRootDiskSize() > 0) { + DiskOfferingVO dvo = getDiskOfferingVO(); + dbf.persist(dvo); + smsg.setRootDiskOfferingUuid(dvo.getUuid()); + temporaryDiskOfferingUuids.add(dvo.getUuid()); + } + + smsg.setVmInstanceInventory(VmInstanceInventory.valueOf(finalVo)); + smsg.setCandidatePrimaryStorageUuidsForDataVolume(msg.getCandidatePrimaryStorageUuidsForDataVolume()); + smsg.setCandidatePrimaryStorageUuidsForRootVolume(msg.getCandidatePrimaryStorageUuidsForRootVolume()); + if (Objects.equals(msg.getStrategy(), VmCreationStrategy.InstantStart.toString()) && attachOtherDisk) { + smsg.setStrategy(VmCreationStrategy.CreateStopped.toString()); + } else { + smsg.setStrategy(msg.getStrategy()); + } + + smsg.setTimeout(msg.getTimeout()); + smsg.setRootVolumeSystemTags(msg.getRootVolumeSystemTags()); + smsg.setDataVolumeSystemTags(msg.getDataVolumeSystemTags()); + smsg.setDataVolumeSystemTagsOnIndex(msg.getDataVolumeSystemTagsOnIndex()); + smsg.setDiskAOs(msg.getDiskAOs()); + bus.makeTargetServiceIdByResourceUuid(smsg, VmInstanceConstant.SERVICE_ID, finalVo.getUuid()); + bus.send(smsg, new CloudBusCallBack(smsg) { + @Override + public void run(MessageReply reply) { + if (!temporaryDiskOfferingUuids.isEmpty()) { + dbf.removeByPrimaryKeys(temporaryDiskOfferingUuids, DiskOfferingVO.class); + } + + if (reply.isSuccess()) { + InstantiateNewCreatedVmInstanceReply r = (InstantiateNewCreatedVmInstanceReply) reply; + instantiateVm = r.getVmInventory(); + data.put(VmInstanceInventory.class.getSimpleName(), instantiateVm); + trigger.next(); + return; + } + trigger.fail(reply.getError()); + } + }); } - if (reply.isSuccess()) { - InstantiateNewCreatedVmInstanceReply r = (InstantiateNewCreatedVmInstanceReply) reply; - completion.success(r.getVmInventory()); - } else { - completion.fail(reply.getError()); + @NotNull + private DiskOfferingVO getDiskOfferingVO() { + DiskOfferingVO dvo = new DiskOfferingVO(); + dvo.setUuid(Platform.getUuid()); + dvo.setAccountUuid(msg.getAccountUuid()); + dvo.setDiskSize(msg.getRootDiskSize()); + dvo.setName("for-create-vm-" + finalVo.getUuid()); + dvo.setType("TemporaryDiskOfferingType"); + dvo.setState(DiskOfferingState.Enabled); + dvo.setAllocatorStrategy(PrimaryStorageConstant.DEFAULT_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE); + return dvo; + } + + @Override + public void rollback(FlowRollback chain, Map data) { + if (instantiateVm == null) { + chain.rollback(); + return; + } + DestroyVmInstanceMsg dmsg = new DestroyVmInstanceMsg(); + dmsg.setVmInstanceUuid(finalVo.getUuid()); + dmsg.setDeletionPolicy(VmInstanceDeletionPolicyManager.VmInstanceDeletionPolicy.Direct); + bus.makeTargetServiceIdByResourceUuid(dmsg, VmInstanceConstant.SERVICE_ID, finalVo.getUuid()); + bus.send(dmsg, new CloudBusCallBack(null) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to delete vm [%s]", instantiateVm.getUuid())); + } + chain.rollback(); + } + }); } - } catch (Exception e) { - bus.logExceptionWithMessageDump(msg, e); - bus.replyErrorByMessageType(msg, e); + }); + + + if (!CollectionUtils.isEmpty(otherDisks)) { + otherDisks.forEach(diskAO -> flow(new VmInstantiateOtherDiskFlow(diskAO))); + } + + if (Objects.equals(msg.getStrategy(), VmCreationStrategy.InstantStart.toString()) && attachOtherDisk) { + flow(new NoRollbackFlow() { + String __name__ = "start-vm"; + + @Override + public void run(FlowTrigger trigger, Map data) { + StartVmInstanceMsg smsg = new StartVmInstanceMsg(); + smsg.setVmInstanceUuid(instantiateVm.getUuid()); + smsg.setHostUuid(instantiateVm.getLastHostUuid()); + bus.makeTargetServiceIdByResourceUuid(smsg, VmInstanceConstant.SERVICE_ID, finalVo.getUuid()); + bus.send(smsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + trigger.next(); + } + }); + } + }); } + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(instantiateVm); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); } - }); + + private void setDiskAOsName(List diskAOs) { + AtomicInteger count = new AtomicInteger(1); + diskAOs.stream().filter(diskAO -> diskAO.getSourceUuid() == null).filter(diskAO -> diskAO.getName() == null) + .forEach(diskAO -> { + diskAO.setName(String.format("DATA-for-%s-%d", finalVo.getName(), count.get())); + count.getAndIncrement(); + }); + } + }).start(); } - private void createVmButNotStart(CreateVmInstanceMsg msg, VmInstanceInventory inv) { - InstantiateVmFromNewCreatedStruct struct = InstantiateVmFromNewCreatedStruct.fromMessage(msg); - new JsonLabel().create(InstantiateVmFromNewCreatedStruct.makeLabelKey(inv.getUuid()), struct, inv.getUuid()); + private List createDiskOfferingUuidsFromDataDiskSizes(final CreateVmInstanceMsg msg, String vmUuid) { + if (CollectionUtils.isEmpty(msg.getDataDiskSizes())){ + return new ArrayList(); + } + List diskOfferingUuids = new ArrayList<>(); + List diskOfferingVos = new ArrayList<>(); + List volumeSizes = msg.getDataDiskSizes().stream().distinct().collect(Collectors.toList()); + Map sizeDiskOfferingMap = new HashMap<>(); + for (Long size : volumeSizes) { + DiskOfferingVO dvo = new DiskOfferingVO(); + dvo.setUuid(Platform.getUuid()); + dvo.setAccountUuid(msg.getAccountUuid()); + dvo.setDiskSize(size); + dvo.setName(String.format("create-data-volume-for-vm-%s", vmUuid)); + dvo.setType("TemporaryDiskOfferingType"); + dvo.setState(DiskOfferingState.Enabled); + dvo.setAllocatorStrategy(PrimaryStorageConstant.DEFAULT_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE); + diskOfferingVos.add(dvo); + sizeDiskOfferingMap.put(size, dvo.getUuid()); + } + msg.getDataDiskSizes().forEach(size -> diskOfferingUuids.add(sizeDiskOfferingMap.get(size))); + dbf.persistCollection(diskOfferingVos); + return diskOfferingUuids; } private void handle(final CreateVmInstanceMsg msg) { - if(msg.getZoneUuid() == null){ + if(msg.getZoneUuid() == null && !CollectionUtils.isEmpty(msg.getL3NetworkSpecs())){ String l3Uuid = VmNicSpec.getL3UuidsOfSpec(msg.getL3NetworkSpecs()).get(0); String zoneUuid = Q.New(L3NetworkVO.class) .select(L3NetworkVO_.zoneUuid) @@ -1102,34 +1484,8 @@ public void fail(ErrorCode errorCode) { }); } - private CreateVmInstanceMsg fromAPICreateVmInstanceMsg(APICreateVmInstanceMsg msg) { - CreateVmInstanceMsg cmsg = NewVmInstanceMsgBuilder.fromAPINewVmInstanceMsg(msg); - cmsg.setImageUuid(msg.getImageUuid()); - cmsg.setRootDiskOfferingUuid(msg.getRootDiskOfferingUuid()); - if (msg.getRootDiskSize() != null) { - cmsg.setRootDiskSize(msg.getRootDiskSize()); - } - cmsg.setDataDiskOfferingUuids(msg.getDataDiskOfferingUuids()); - cmsg.setRootVolumeSystemTags(msg.getRootVolumeSystemTags()); - cmsg.setDataVolumeSystemTags(msg.getDataVolumeSystemTags()); - - cmsg.setPrimaryStorageUuidForRootVolume(msg.getPrimaryStorageUuidForRootVolume()); - if (msg.getDataDiskOfferingUuids() != null && !msg.getDataDiskOfferingUuids().isEmpty()) { - cmsg.setPrimaryStorageUuidForDataVolume(getPSUuidForDataVolume(msg.getSystemTags())); - } - return cmsg; - } - - private String getPSUuidForDataVolume(List systemTags){ - if(systemTags == null || systemTags.isEmpty()){ - return null; - } - - return SystemTagUtils.findTagValue(systemTags, VmSystemTags.PRIMARY_STORAGE_UUID_FOR_DATA_VOLUME, VmSystemTags.PRIMARY_STORAGE_UUID_FOR_DATA_VOLUME_TOKEN); - } - private void handle(final APICreateVmInstanceMsg msg) { - doCreateVmInstance(fromAPICreateVmInstanceMsg(msg), msg, new ReturnValueCompletion(msg) { + doCreateVmInstance(VmInstanceUtils.fromAPICreateVmInstanceMsg(msg), msg, new ReturnValueCompletion(msg) { APICreateVmInstanceEvent evt = new APICreateVmInstanceEvent(msg.getId()); @Override @@ -1157,26 +1513,20 @@ public String getSyncSignature() { public void run(SyncTaskChain chain) { if (nic.getVmInstanceUuid() == null) { FlowChain fchain = FlowChainBuilder.newSimpleFlowChain(); - fchain.setName(String.format("detach-eip-from-vmnic-%s", nic.getUuid())); - fchain.then(new NoRollbackFlow() { - @Override - public void run(FlowTrigger trigger, Map data) { - for (ReleaseNetworkServiceOnDeletingNicExtensionPoint extp : pluginRgty.getExtensionList(ReleaseNetworkServiceOnDeletingNicExtensionPoint.class)) { - extp.releaseNetworkServiceOnDeletingNic(nic, new Completion(trigger) { + fchain.setName(String.format("detach-network-service-from-vmnic-%s", nic.getUuid())); + for (ReleaseNetworkServiceOnDeletingNicExtensionPoint ext : pluginRgty.getExtensionList(ReleaseNetworkServiceOnDeletingNicExtensionPoint.class)) { + fchain.then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + ext.releaseNetworkServiceOnDeletingNic(nic, new NoErrorCompletion(trigger) { @Override - public void success() { - logger.debug(String.format("release eip from vmnic[%s]",nic.getUuid())); + public void done() { trigger.next(); } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } }); } - } - }); + }); + } fchain.then(new NoRollbackFlow() { @Override public void run(FlowTrigger trigger, Map data) { @@ -1199,6 +1549,9 @@ public void run(MessageReply reply) { })).run(new WhileDoneCompletion(trigger) { @Override public void done(ErrorCodeList errorCodeList) { + for (NicManageExtensionPoint ext : pluginRgty.getExtensionList(NicManageExtensionPoint.class)) { + ext.beforeDeleteNic(nic); + } dbf.removeByPrimaryKey(nic.getUuid(), VmNicVO.class); trigger.next(); } @@ -1283,52 +1636,10 @@ private void createVmFlowChainBuilder() throws InstantiationException, IllegalAc resumeVmFlowBuilder = FlowChainBuilder.newBuilder().setFlowClassNames(resumeVmWorkFlowElements).construct(); } - private void populateExtensions() { - for (VmInstanceFactory ext : pluginRgty.getExtensionList(VmInstanceFactory.class)) { - VmInstanceFactory old = vmInstanceFactories.get(ext.getType().toString()); - if (old != null) { - throw new CloudRuntimeException(String.format("duplicate VmInstanceFactory[%s, %s] for type[%s]", - old.getClass().getName(), ext.getClass().getName(), ext.getType())); - } - vmInstanceFactories.put(ext.getType().toString(), ext); - } - - for (VmInstanceBaseExtensionFactory ext : pluginRgty.getExtensionList(VmInstanceBaseExtensionFactory.class)) { - for (Class clz : ext.getMessageClasses()) { - VmInstanceBaseExtensionFactory old = vmInstanceBaseExtensionFactories.get(clz); - if (old != null) { - throw new CloudRuntimeException(String.format("duplicate VmInstanceBaseExtensionFactory[%s, %s] for the" + - " message[%s]", old.getClass(), ext.getClass(), clz)); - } - - vmInstanceBaseExtensionFactories.put(clz, ext); - } - } - - for (VmInstanceNicFactory ext : pluginRgty.getExtensionList(VmInstanceNicFactory.class)) { - VmInstanceNicFactory old = vmInstanceNicFactories.get(ext.getType().toString()); - if (old != null) { - throw new CloudRuntimeException(String.format("duplicate VmInstanceNicFactory[%s, %s] for type[%s]", - old.getClass().getName(), ext.getClass().getName(), ext.getType())); - } - vmInstanceNicFactories.put(ext.getType().toString(), ext); - } - - for (VmNicQosConfigBackend ext : pluginRgty.getExtensionList(VmNicQosConfigBackend.class)) { - VmNicQosConfigBackend old = vmNicQosConfigMap.get(ext.getVmInstanceType()); - if (old != null) { - throw new CloudRuntimeException(String.format("can not add VmNicQosConfigBackend, because duplicate VmNicQosConfigBackend [%s, %s] for type[%s]", - old.getClass().getName(), ext.getClass().getName(), ext.getVmInstanceType())); - } - vmNicQosConfigMap.put(ext.getVmInstanceType(), ext); - } - } - @Override public boolean start() { try { createVmFlowChainBuilder(); - populateExtensions(); installSystemTagValidator(); installGlobalConfigUpdater(); vmExtensionManagers.addAll(pluginRgty.getExtensionList(VmInstanceExtensionManager.class)); @@ -1354,6 +1665,15 @@ public void beforeDeliveryMessage(Message msg) { } } }, StartVmInstanceMsg.class); + + deleteMigrateSystemTagWhenVmStateChangedToRunning(); + pluginRgty.saveExtensionAsMap(VmAttachOtherDiskExtensionPoint.class, new Function() { + @Override + public Object call(VmAttachOtherDiskExtensionPoint arg) { + return arg.getDiskType(); + } + }); + return true; } catch (Exception e) { throw new CloudConfigureFailException(VmInstanceManagerImpl.class, e.getMessage(), e); @@ -1401,6 +1721,27 @@ public void beforeUpdateExtensionPoint(GlobalConfig oldConfig, String newValue) } } }); + + ResourceConfig resourceConfig = rcf.getResourceConfig(VmGlobalConfig.VM_HA_ACROSS_CLUSTERS.getIdentity()); + resourceConfig.installUpdateExtension(new ResourceConfigUpdateExtensionPoint() { + @Override + public void updateResourceConfig(ResourceConfig config, String resourceUuid, String resourceType, String oldValue, String newValue) { + if (!VmInstanceVO.class.getSimpleName().equals(resourceType)) + return; + // keep back-compatibility create or delete resource binding tag if needed + if (newValue.equals("false")) { + String clusterUuid = Q.New(VmInstanceVO.class).select(VmInstanceVO_.clusterUuid) + .eq(VmInstanceVO_.uuid, resourceUuid).findValue(); + String token = String.format("Cluster:%s", clusterUuid); + SystemTagCreator creator = VmSystemTags.VM_RESOURCE_BINGDING.newSystemTagCreator(resourceUuid); + creator.recreate = true; + creator.setTagByTokens(map(e(VmSystemTags.VM_RESOURCE_BINGDING_TOKEN, token))); + creator.create(); + } else { + VmSystemTags.VM_RESOURCE_BINGDING.delete(resourceUuid); + } + } + }); } private void installHostnameValidator() { @@ -1426,41 +1767,7 @@ public void validateSystemTagInCreateMessage(APICreateMessage cmsg) { String hostname = VmSystemTags.HOSTNAME.getTokenByTag(sysTag, VmSystemTags.HOSTNAME_TOKEN); validateHostname(sysTag, hostname); - List l3NetworkUuids = msg.getL3NetworkUuids(); - l3NetworkUuids.forEach(it->validateHostNameOnDefaultL3Network(sysTag, hostname, it)); - } else if (VmSystemTags.STATIC_IP.isMatch(sysTag)) { - validateStaticIp(sysTag); - } - } - } - - private void validateStaticIp(String sysTag) { - Map token = TagUtils.parse(VmSystemTags.STATIC_IP.getTagFormat(), sysTag); - String l3Uuid = token.get(VmSystemTags.STATIC_IP_L3_UUID_TOKEN); - if (!dbf.isExist(l3Uuid, L3NetworkVO.class)) { - throw new ApiMessageInterceptionException(argerr("L3 network[uuid:%s] not found. Please correct your system tag[%s] of static IP", - l3Uuid, sysTag)); - } - - String ip = token.get(VmSystemTags.STATIC_IP_TOKEN); - ip = IPv6NetworkUtils.ipv6TagValueToAddress(ip); - if (!NetworkUtils.isIpv4Address(ip) && !IPv6NetworkUtils.isIpv6Address(ip)) { - throw new ApiMessageInterceptionException(argerr("%s is not a valid ip address. Please correct your system tag[%s] of static IP", - ip, sysTag)); - } - - CheckIpAvailabilityMsg cmsg = new CheckIpAvailabilityMsg(); - cmsg.setIp(ip); - cmsg.setL3NetworkUuid(l3Uuid); - bus.makeLocalServiceId(cmsg, L3NetworkConstant.SERVICE_ID); - MessageReply r = bus.call(cmsg); - if (!r.isSuccess()) { - throw new ApiMessageInterceptionException(inerr(r.getError().getDetails())); - } - - CheckIpAvailabilityReply cr = r.castReply(); - if (!cr.isAvailable()) { - throw new ApiMessageInterceptionException(operr("IP[%s] is not available on the L3 network[uuid:%s] because: %s", ip, l3Uuid, cr.getReason())); + } } } @@ -1499,10 +1806,6 @@ public void validateSystemTag(String resourceUuid, Class resourceType, String sy q.select(VmInstanceVO_.defaultL3NetworkUuid); q.add(VmInstanceVO_.uuid, Op.EQ, resourceUuid); String defaultL3Uuid = q.findValue(); - - validateHostNameOnDefaultL3Network(systemTag, hostname, defaultL3Uuid); - } else if (VmSystemTags.STATIC_IP.isMatch(systemTag)) { - validateStaticIp(systemTag); } else if (VmSystemTags.BOOT_ORDER.isMatch(systemTag)) { validateBootOrder(systemTag); } @@ -1524,6 +1827,33 @@ private void validateBootOrder(String systemTag) { tagMgr.installCreateMessageValidator(VmInstanceVO.class.getSimpleName(), hostnameValidator); VmSystemTags.HOSTNAME.installValidator(hostnameValidator); + // TODO: system tags should support token format validation + VmHardwareSystemTags.CPU_SOCKETS.installValidator((resourceUuid, resourceType, systemTag) -> { + String sockets = VmHardwareSystemTags.CPU_SOCKETS.getTokenByTag(systemTag, VmHardwareSystemTags.CPU_SOCKETS_TOKEN); + try { + Integer.valueOf(sockets); + } catch (NumberFormatException e) { + throw new ApiMessageInterceptionException(argerr("cpuSockets must be an integer")); + } + }); + + VmHardwareSystemTags.CPU_CORES.installValidator((resourceUuid, resourceType, systemTag) -> { + String cores = VmHardwareSystemTags.CPU_CORES.getTokenByTag(systemTag, VmHardwareSystemTags.CPU_CORES_TOKEN); + try { + Integer.valueOf(cores); + } catch (NumberFormatException e) { + throw new ApiMessageInterceptionException(argerr("cpuCores must be an integer")); + } + }); + + VmHardwareSystemTags.CPU_THREADS.installValidator((resourceUuid, resourceType, systemTag) -> { + String threads = VmHardwareSystemTags.CPU_THREADS.getTokenByTag(systemTag, VmHardwareSystemTags.CPU_THREADS_TOKEN); + try { + Integer.valueOf(threads); + } catch (NumberFormatException e) { + throw new ApiMessageInterceptionException(argerr("cpuThreads must be an integer")); + } + }); } private void installUserdataValidator() { @@ -1543,6 +1873,12 @@ private void checkUserdataDecode(String systemTag) { Base64.getDecoder().decode(userdata.getBytes()); } + private void validUserdataFormat(String systemTag) { + VmSystemTags.UserdataTagOutputHandler handler = new VmSystemTags.UserdataTagOutputHandler(); + handler.desensitizeTag(VmSystemTags.USERDATA, systemTag); + } + + @Override public void validateSystemTag(String resourceUuid, Class resourceType, String systemTag) { if (!VmSystemTags.USERDATA.isMatch(systemTag)) { @@ -1550,6 +1886,7 @@ public void validateSystemTag(String resourceUuid, Class resourceType, String sy } check(resourceUuid, resourceType); checkUserdataDecode(systemTag); + validUserdataFormat(systemTag); } @Override @@ -1565,6 +1902,13 @@ public void validateSystemTagInCreateMessage(APICreateMessage msg) { check(msg.getResourceUuid(), VmInstanceVO.class); checkUserdataDecode(sysTag); + String tagValue = SystemTagUtils.findTagValue(msg.getSystemTags(), VmSystemTags.USERDATA); + if (tagValue == null) { + return; + } + + validUserdataFormat(tagValue); + } } } @@ -1734,6 +2078,26 @@ private void validateL3NetworkAttachSecurityGroup(String l3Uuid, List se VmSystemTags.L3_NETWORK_SECURITY_GROUP_UUIDS_REF.installValidator(validator); } + private void installSeDeviceValidator() { + VmSystemTags.SECURITY_ELEMENT_ENABLE.installValidator(new SystemTagValidator() { + @Override + public void validateSystemTag(String resourceUuid, Class resourceType, String systemTag) { + String SecurityElementEnableTokenByTag = null; + if (VmSystemTags.SECURITY_ELEMENT_ENABLE.isMatch(systemTag)) { + SecurityElementEnableTokenByTag = VmSystemTags.SECURITY_ELEMENT_ENABLE.getTokenByTag(systemTag, VmSystemTags.SECURITY_ELEMENT_ENABLE_TOKEN); + } else { + throw new OperationFailureException(argerr("invalid securityElementEnable[%s], %s is not securityElementEnable tag", systemTag, SecurityElementEnableTokenByTag)); + } + if (!isBoolean(SecurityElementEnableTokenByTag)) { + throw new OperationFailureException(argerr("invalid securityElementEnable[%s], %s is not boolean class", systemTag, SecurityElementEnableTokenByTag)); + } + } + private boolean isBoolean(String param) { + return "true".equalsIgnoreCase(param) || "false".equalsIgnoreCase(param); + } + }); + } + private void installSystemTagValidator() { installHostnameValidator(); installUserdataValidator(); @@ -1742,8 +2106,9 @@ private void installSystemTagValidator() { installMachineTypeValidator(); installUsbRedirectValidator(); installL3NetworkSecurityGroupValidator(); + installSeDeviceValidator(); + new StaticIpOperator().installStaticIpValidator(); } - private void installUsbRedirectValidator() { VmSystemTags.USB_REDIRECT.installValidator(new SystemTagValidator() { @Override @@ -1771,7 +2136,7 @@ public boolean stop() { @Override public VmInstanceFactory getVmInstanceFactory(VmInstanceType type) { - VmInstanceFactory factory = vmInstanceFactories.get(type.toString()); + VmInstanceFactory factory = vmFactoryManager.getVmInstanceFactory(type.toString()); if (factory == null) { throw new CloudRuntimeException(String.format("No VmInstanceFactory of type[%s] found", type)); } @@ -1780,12 +2145,12 @@ public VmInstanceFactory getVmInstanceFactory(VmInstanceType type) { @Override public VmInstanceBaseExtensionFactory getVmInstanceBaseExtensionFactory(Message msg) { - return vmInstanceBaseExtensionFactories.get(msg.getClass()); + return vmFactoryManager.getVmInstanceBaseExtensionFactory(msg.getClass()); } @Override public VmInstanceNicFactory getVmInstanceNicFactory(VmNicType type) { - VmInstanceNicFactory factory = vmInstanceNicFactories.get(type.toString()); + VmInstanceNicFactory factory = vmFactoryManager.getVmInstanceNicFactory(type.toString()); if (factory == null) { throw new CloudRuntimeException(String.format("No VmInstanceNicFactory of type[%s] found", type)); } @@ -1901,51 +2266,183 @@ public void setResumeVmWorkFlowElements(List resumeVmWorkFlowElements) { @Override public List reportQuota() { - QuotaOperator checker = new VmQuotaOperator() ; - Quota quota = new Quota(); - QuotaPair p; - - p = new QuotaPair(); - p.setName(VmQuotaConstant.VM_TOTAL_NUM); - p.setValue(VmQuotaGlobalConfig.VM_TOTAL_NUM.defaultValue(Long.class)); - quota.addPair(p); - - p = new QuotaPair(); - p.setName(VmQuotaConstant.VM_RUNNING_NUM); - p.setValue(VmQuotaGlobalConfig.VM_RUNNING_NUM.defaultValue(Long.class)); - quota.addPair(p); - - p = new QuotaPair(); - p.setName(VmQuotaConstant.VM_RUNNING_CPU_NUM); - p.setValue(VmQuotaGlobalConfig.VM_RUNNING_CPU_NUM.defaultValue(Long.class)); - quota.addPair(p); - - p = new QuotaPair(); - p.setName(VmQuotaConstant.VM_RUNNING_MEMORY_SIZE); - p.setValue(VmQuotaGlobalConfig.VM_RUNNING_MEMORY_SIZE.defaultValue(Long.class)); - quota.addPair(p); - - p = new QuotaPair(); - p.setName(VmQuotaConstant.DATA_VOLUME_NUM); - p.setValue(VmQuotaGlobalConfig.DATA_VOLUME_NUM.defaultValue(Long.class)); - quota.addPair(p); - - p = new QuotaPair(); - p.setName(VmQuotaConstant.VOLUME_SIZE); - p.setValue(VmQuotaGlobalConfig.VOLUME_SIZE.defaultValue(Long.class)); - quota.addPair(p); - - quota.addMessageNeedValidation(APICreateVmInstanceMsg.class); - quota.addMessageNeedValidation(APIRecoverVmInstanceMsg.class); - quota.addMessageNeedValidation(APICreateDataVolumeMsg.class); - quota.addMessageNeedValidation(APIRecoverDataVolumeMsg.class); - quota.addMessageNeedValidation(APIStartVmInstanceMsg.class); - quota.addMessageNeedValidation(APIChangeResourceOwnerMsg.class); - quota.addMessageNeedValidation(StartVmInstanceMsg.class); - - quota.setOperator(checker); + quota.defineQuota(new VmTotalNumQuotaDefinition()); + quota.defineQuota(new VmRunningNumQuotaDefinition()); + quota.defineQuota(new VmRunningCpuNumQuotaDefinition()); + quota.defineQuota(new VmRunningMemoryNumQuotaDefinition()); + quota.defineQuota(new DataVolumeNumQuotaDefinition()); + quota.defineQuota(new VolumeSizeQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateVmInstanceMsg.class) + .addCounterQuota(VmQuotaConstant.VM_TOTAL_NUM) + .addCounterQuota(VmQuotaConstant.VM_RUNNING_NUM) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_CPU_NUM, (msg) -> { + if (msg.getCpuNum() != null) { + return Integer.toUnsignedLong(msg.getCpuNum()); + } + + Integer cpuNum = Q.New(InstanceOfferingVO.class) + .select(InstanceOfferingVO_.cpuNum) + .eq(InstanceOfferingVO_.uuid, msg.getInstanceOfferingUuid()) + .findValue(); + return Integer.toUnsignedLong(cpuNum); + }).addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_MEMORY_SIZE, (msg) -> { + if (msg.getMemorySize() != null) { + return msg.getMemorySize(); + } + + return Q.New(InstanceOfferingVO.class) + .select(InstanceOfferingVO_.memorySize) + .eq(InstanceOfferingVO_.uuid, msg.getInstanceOfferingUuid()) + .findValue(); + }).addMessageRequiredQuotaHandler(VmQuotaConstant.DATA_VOLUME_NUM, (msg) -> { + if (msg.getDataDiskOfferingUuids() == null || msg.getDataDiskOfferingUuids().isEmpty()) { + return 0L; + } + + return (long) (msg.getDataDiskOfferingUuids().size()); + }).addMessageRequiredQuotaHandler(VmQuotaConstant.VOLUME_SIZE, (msg) -> { + long allVolumeSizeAsked = 0; + + String sql; + Long imgSize; + ImageConstant.ImageMediaType imgType = null; + if (msg.getImageUuid() != null) { + sql = "select img.size, img.mediaType" + + " from ImageVO img" + + " where img.uuid = :iuuid"; + TypedQuery iq = dbf.getEntityManager().createQuery(sql, Tuple.class); + iq.setParameter("iuuid", msg.getImageUuid()); + Tuple it = iq.getSingleResult(); + imgSize = it.get(0, Long.class); + imgType = it.get(1, ImageConstant.ImageMediaType.class); + } else { + imgSize = 0L; + } + List diskOfferingUuids = new ArrayList<>(); + if (msg.getDataDiskOfferingUuids() != null && !msg.getDataDiskOfferingUuids().isEmpty()) { + diskOfferingUuids.addAll(msg.getDataDiskOfferingUuids()); + } + if (imgType == ImageConstant.ImageMediaType.RootVolumeTemplate) { + if (msg.getRootDiskOfferingUuid() != null) { + diskOfferingUuids.add(msg.getRootDiskOfferingUuid()); + } else { + allVolumeSizeAsked += imgSize; + } + } else if (imgType == ImageConstant.ImageMediaType.ISO) { + if (msg.getRootDiskOfferingUuid() != null) { + diskOfferingUuids.add(msg.getRootDiskOfferingUuid()); + } else if (msg.getRootDiskSize() != null) { + allVolumeSizeAsked += msg.getRootDiskSize(); + } else { + throw new ApiMessageInterceptionException(argerr("rootDiskOfferingUuid cannot be null when image mediaType is ISO")); + } + } else { + if (msg.getRootDiskOfferingUuid() != null) { + diskOfferingUuids.add(msg.getRootDiskOfferingUuid()); + } else if (msg.getRootDiskSize() != null) { + allVolumeSizeAsked += msg.getRootDiskSize(); + } else { + throw new ApiMessageInterceptionException(argerr("rootDiskOfferingUuid cannot be null when create vm without image")); + } + } + + HashMap diskOfferingCountMap = new HashMap<>(); + if (!diskOfferingUuids.isEmpty()) { + for (String diskOfferingUuid : diskOfferingUuids) { + if (diskOfferingCountMap.containsKey(diskOfferingUuid)) { + diskOfferingCountMap.put(diskOfferingUuid, diskOfferingCountMap.get(diskOfferingUuid) + 1); + } else { + diskOfferingCountMap.put(diskOfferingUuid, 1L); + } + } + for (String diskOfferingUuid : diskOfferingCountMap.keySet()) { + sql = "select diskSize from DiskOfferingVO where uuid = :uuid"; + TypedQuery dq = dbf.getEntityManager().createQuery(sql, Long.class); + dq.setParameter("uuid", diskOfferingUuid); + Long dsize = dq.getSingleResult(); + dsize = dsize == null ? 0 : dsize; + allVolumeSizeAsked += dsize * diskOfferingCountMap.get(diskOfferingUuid); + } + } + + return allVolumeSizeAsked; + }).addCheckCondition((msg) -> !msg.getStrategy().equals(VmCreationStrategy.JustCreate.toString()))); + + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIRecoverVmInstanceMsg.class) + .addCounterQuota(VmQuotaConstant.VM_TOTAL_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIStartVmInstanceMsg.class) + .addCounterQuota(VmQuotaConstant.VM_RUNNING_NUM) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_CPU_NUM, (msg) -> new VmQuotaUtil().getRequiredCpu(msg.getVmInstanceUuid())) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_MEMORY_SIZE, (msg) -> new VmQuotaUtil().getRequiredMemory(msg.getVmInstanceUuid()))); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(StartVmInstanceMsg.class) + .addCounterQuota(VmQuotaConstant.VM_RUNNING_NUM) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_CPU_NUM, (msg) -> new VmQuotaUtil().getRequiredCpu(msg.getVmInstanceUuid())) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_MEMORY_SIZE, (msg) -> new VmQuotaUtil().getRequiredMemory(msg.getVmInstanceUuid()))); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateDataVolumeMsg.class) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VOLUME_SIZE, (msg) -> { + if (msg.getDiskOfferingUuid() == null) { + return msg.getDiskSize(); + } + + String sql = "select diskSize from DiskOfferingVO where uuid = :uuid "; + TypedQuery dq = dbf.getEntityManager().createQuery(sql, Long.class); + dq.setParameter("uuid", msg.getDiskOfferingUuid()); + Long dsize = dq.getSingleResult(); + dsize = dsize == null ? 0 : dsize; + return dsize; + }) + .addCounterQuota(VmQuotaConstant.DATA_VOLUME_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIRecoverDataVolumeMsg.class) + .addCounterQuota(VmQuotaConstant.DATA_VOLUME_NUM)); + + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, msg.getResourceUuid()) + .notEq(VmInstanceVO_.type, "baremetal2") + .isExists()) + .addCounterQuota(VmQuotaConstant.VM_TOTAL_NUM) + .addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_CPU_NUM, (msg) -> { + VmInstanceState state = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.state) + .eq(VmInstanceVO_.uuid, msg.getResourceUuid()) + .findValue(); + + // vm is running + if (list(VmInstanceState.Stopped, VmInstanceState.Destroying, + VmInstanceState.Destroyed, VmInstanceState.Created).contains(state)) { + return 0L; + } + + return new VmQuotaUtil().getRequiredCpu(msg.getResourceUuid()); + }).addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_MEMORY_SIZE, (msg) -> { + VmInstanceState state = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.state) + .eq(VmInstanceVO_.uuid, msg.getResourceUuid()) + .findValue(); + + // vm is running + if (list(VmInstanceState.Stopped, VmInstanceState.Destroying, + VmInstanceState.Destroyed, VmInstanceState.Created).contains(state)) { + return 0L; + } + + return new VmQuotaUtil().getRequiredMemory(msg.getResourceUuid()); + }).addMessageRequiredQuotaHandler(VmQuotaConstant.VM_RUNNING_NUM, (msg) -> { + VmInstanceState state = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.state) + .eq(VmInstanceVO_.uuid, msg.getResourceUuid()) + .findValue(); + + // vm is running + if (list(VmInstanceState.Stopped, VmInstanceState.Destroying, + VmInstanceState.Destroyed, VmInstanceState.Created).contains(state)) { + return 0L; + } + + return 1L; + })); return list(quota); } @@ -2002,7 +2499,7 @@ public synchronized boolean run() { final Timestamp current = dbf.getCurrentSqlTime(); - final List msgs = CollectionUtils.transformToList(vms, new Function() { + final List msgs = transformToList(vms, new Function() { @Override public ExpungeVmMsg call(Tuple t) { String uuid = t.get(0, String.class); @@ -2215,14 +2712,8 @@ public void run(MessageReply reply) { } } - @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { - - } - @Override public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } @Override @@ -2257,6 +2748,65 @@ public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, Erro @Override public VmNicQosConfigBackend getVmNicQosConfigBackend(String type) { - return vmNicQosConfigMap.get(type); + return vmFactoryManager.getVmNicQosConfigBackend(type); + } + + @Override + public ErrorCode handleSystemTag(String vmUuid, List tags) { + ErrorCode errorCode = handleResourceDirectorySystemTag(vmUuid, tags); + if (errorCode != null) { + return errorCode; + } + + errorCode = handleNumaSystemTag(vmUuid, tags); + + if (errorCode != null) { + return errorCode; + } + + return null; + } + + private ErrorCode handleNumaSystemTag(String vmUuid, List tags) { + if (!VmSystemTags.NUMA.hasTag(vmUuid)) { + return null; + } + ResourceConfig rc = rcf.getResourceConfig(VmGlobalConfig.NUMA.getIdentity()); + rc.updateValue(vmUuid, Boolean.TRUE.toString()); + VmSystemTags.NUMA.delete(vmUuid); + + return null; + + } + + //todo move to directory + private ErrorCode handleResourceDirectorySystemTag(String vmUuid, List tags) { + PatternedSystemTag tag = VmSystemTags.DIRECTORY_UUID; + String token = VmSystemTags.DIRECTORY_UUID_TOKEN; + + String directoryUuid = SystemTagUtils.findTagValue(tags, tag, token); + if (StringUtils.isEmpty(directoryUuid)) { + return null; + } + ResourceDirectoryRefVO refVO = new ResourceDirectoryRefVO(); + refVO.setResourceUuid(vmUuid); + refVO.setDirectoryUuid(directoryUuid); + refVO.setResourceType(VmInstanceVO.class.getSimpleName()); + refVO.setLastOpDate(new Timestamp(new Date().getTime())); + refVO.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(refVO); + return null; + } + + public void deleteMigrateSystemTagWhenVmStateChangedToRunning() { + evtf.onLocal(VmCanonicalEvents.VM_FULL_STATE_CHANGED_PATH, new EventCallback() { + @Override + protected void run(Map tokens, Object data) { + VmCanonicalEvents.VmStateChangedData d = (VmCanonicalEvents.VmStateChangedData) data; + if (!Objects.equals(d.getOldState(), VmInstanceState.Migrating.toString()) && Objects.equals(d.getNewState(), VmInstanceState.Running.toString())) { + VmSystemTags.VM_STATE_PAUSED_AFTER_MIGRATE.delete(d.getVmUuid()); + } + } + }); } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstanceUtils.java b/compute/src/main/java/org/zstack/compute/vm/VmInstanceUtils.java new file mode 100644 index 00000000000..ab72be07771 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstanceUtils.java @@ -0,0 +1,185 @@ +package org.zstack.compute.vm; + +import org.apache.commons.collections.CollectionUtils; +import org.springframework.util.StringUtils; +import org.zstack.core.Platform; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.configuration.InstanceOfferingInventory; +import org.zstack.header.configuration.InstanceOfferingState; +import org.zstack.header.configuration.InstanceOfferingVO; +import org.zstack.header.configuration.InstanceOfferingVO_; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.image.ImageVO; +import org.zstack.header.image.ImageVO_; +import org.zstack.header.vm.*; +import org.zstack.tag.SystemTagUtils; + +import java.util.List; +import java.util.Objects; + +import static java.util.Objects.requireNonNull; +import static org.zstack.core.Platform.operr; + +/** + * Created by Wenhao.Zhang on 22/03/10 + */ +public class VmInstanceUtils { + public static CreateVmInstanceMsg fromAPICreateVmInstanceMsg(APICreateVmInstanceMsg msg) { + CreateVmInstanceMsg cmsg = NewVmInstanceMsgBuilder.fromAPINewVmInstanceMsg(msg); + + boolean useVirtioSettingOfImage = msg.getVirtio() == null; + + cmsg.setImageUuid(msg.getImageUuid()); + // create vm without image is supported + if (!StringUtils.isEmpty(msg.getImageUuid())) { + ImageVO image = Q.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).find(); + cmsg.setPlatform(msg.getPlatform() == null ? image.getPlatform().toString() : msg.getPlatform()); + cmsg.setGuestOsType(msg.getGuestOsType() == null ? image.getGuestOsType() : msg.getGuestOsType()); + cmsg.setArchitecture(msg.getArchitecture() == null ? image.getArchitecture() : msg.getArchitecture()); + + if (useVirtioSettingOfImage) { + cmsg.setVirtio(image.getVirtio()); + } + } else { + cmsg.setPlatform(msg.getPlatform()); + cmsg.setArchitecture(msg.getArchitecture()); + cmsg.setGuestOsType(msg.getGuestOsType()); + } + + if (!useVirtioSettingOfImage) { + cmsg.setVirtio(msg.isVirtio()); + } + + cmsg.setRootDiskOfferingUuid(msg.getRootDiskOfferingUuid()); + if (msg.getRootDiskSize() != null) { + cmsg.setRootDiskSize(msg.getRootDiskSize()); + } + cmsg.setDataDiskSizes(msg.getDataDiskSizes()); + cmsg.setDataDiskOfferingUuids(msg.getDataDiskOfferingUuids()); + cmsg.setRootVolumeSystemTags(msg.getRootVolumeSystemTags()); + cmsg.setDataVolumeSystemTags(msg.getDataVolumeSystemTags()); + cmsg.setPrimaryStorageUuidForRootVolume(msg.getPrimaryStorageUuidForRootVolume()); + cmsg.setDataVolumeSystemTagsOnIndex(msg.getDataVolumeSystemTagsOnIndex()); + cmsg.setStrategy(msg.getStrategy()); + + cmsg.setDiskAOs(msg.getDiskAOs()); + + if (CollectionUtils.isNotEmpty(msg.getDataDiskOfferingUuids()) || CollectionUtils.isNotEmpty(msg.getDataDiskSizes())) { + cmsg.setPrimaryStorageUuidForDataVolume(getPSUuidForDataVolume(msg.getSystemTags())); + } + + cmsg.setSshKeyPairUuids(msg.getSshKeyPairUuids()); + + return cmsg; + } + + private static String getPSUuidForDataVolume(List systemTags){ + if (systemTags == null || systemTags.isEmpty()){ + return null; + } + + return SystemTagUtils.findTagValue(systemTags, VmSystemTags.PRIMARY_STORAGE_UUID_FOR_DATA_VOLUME, VmSystemTags.PRIMARY_STORAGE_UUID_FOR_DATA_VOLUME_TOKEN); + } + + public static UpdateVmInstanceSpec convertToSpec(UpdateVmInstanceMsg message, VmInstanceVO vm) { + requireNonNull(message); + String vmUuid = requireNonNull(requireNonNull(vm).getUuid()); + + UpdateVmInstanceSpec spec = new UpdateVmInstanceSpec(); + spec.setVmInstanceUuid(vmUuid); + + if (vm.getHostUuid() != null) { + spec.setHostUuid(vm.getHostUuid()); + } else if (vm.getLastHostUuid() != null) { + spec.setHostUuid(vm.getLastHostUuid()); + } else { + throw new OperationFailureException(Platform.operr("failed to find host of vm[uuid=%s]", vmUuid)); + } + + if (!Objects.equals(vm.getName(), message.getName())) { + spec.setName(message.getName()); + } + if (!Objects.equals(vm.getCpuNum(), message.getCpuNum())) { + spec.setCpuNum(message.getCpuNum()); + } + if (!Objects.equals(vm.getMemorySize(), message.getMemorySize())) { + spec.setMemorySize(message.getMemorySize()); + } + if (!Objects.equals(vm.getReservedMemorySize(), message.getReservedMemorySize())) { + spec.setReservedMemorySize(message.getReservedMemorySize()); + } + + return spec; + } + + public static UpdateVmInstanceSpec convertToSpec(APIChangeInstanceOfferingMsg message, + InstanceOfferingInventory inv, + VmInstanceVO vm) { + requireNonNull(message); + final String vmUuid = requireNonNull(vm.getUuid()); + + UpdateVmInstanceSpec spec = new UpdateVmInstanceSpec(); + spec.setVmInstanceUuid(vmUuid); + + if (vm.getHostUuid() != null) { + spec.setHostUuid(vm.getHostUuid()); + } else if (vm.getLastHostUuid() != null) { + spec.setHostUuid(vm.getLastHostUuid()); + } else { + throw new OperationFailureException(Platform.operr("failed to find host of vm[uuid=%s]", vmUuid)); + } + + if (!Objects.equals(vm.getCpuNum(), inv.getCpuNum())) { + spec.setCpuNum(inv.getCpuNum()); + } + if (!Objects.equals(vm.getMemorySize(), inv.getMemorySize())) { + spec.setMemorySize(inv.getMemorySize()); + } + + return spec; + } + + public static void validateInstanceSettings(NewVmInstanceMessage2 msg) { + final String instanceOfferingUuid = msg.getInstanceOfferingUuid(); + + if (instanceOfferingUuid == null) { + if (msg.getCpuNum() == null || msg.getMemorySize() == null) { + throw new ApiMessageInterceptionException(operr("Missing CPU/memory settings")); + } + + if (msg.getCpuNum() <= 0 || msg.getMemorySize() <= 0) { + throw new ApiMessageInterceptionException(operr("Unexpected CPU/memory settings")); + } + + if (msg.getReservedMemorySize() != null) { + if (msg.getReservedMemorySize() > msg.getMemorySize()) { + throw new ApiMessageInterceptionException(operr("reserved memory[%s] is greater than memory size[%s]", msg.getReservedMemorySize(), msg.getMemorySize())); + } + } else { + msg.setReservedMemorySize(0L); + } + + return; + } + + // InstanceOffering takes precedence over CPU/memory settings. + InstanceOfferingVO ivo = Q.New(InstanceOfferingVO.class).eq(InstanceOfferingVO_.uuid, instanceOfferingUuid).find(); + + if (ivo.getState() == InstanceOfferingState.Disabled) { + throw new ApiMessageInterceptionException(operr("instance offering[uuid:%s] is Disabled, can't create vm from it", instanceOfferingUuid)); + } + + if (!ivo.getType().equals(VmInstanceConstant.USER_VM_TYPE)){ + throw new ApiMessageInterceptionException(operr("instance offering[uuid:%s, type:%s] is not UserVm type, can't create vm from it", instanceOfferingUuid, ivo.getType())); + } + + msg.setCpuNum(ivo.getCpuNum()); + msg.setMemorySize(ivo.getMemorySize()); + + // Reserved memory should support customize. + if (msg.getReservedMemorySize() == null) { + msg.setReservedMemorySize(ivo.getReservedMemorySize()); + } + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java index 062ef259479..c4a42c3c551 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java @@ -7,9 +7,13 @@ import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.primary.PrimaryStorageHostRefVO; +import org.zstack.header.storage.primary.PrimaryStorageHostRefVO_; +import org.zstack.header.storage.primary.PrimaryStorageHostStatus; import org.zstack.header.storage.primary.PrimaryStorageInventory; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; @@ -20,6 +24,8 @@ import java.util.Map; +import static org.zstack.core.Platform.operr; + @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmInstantiateAttachingVolumeFlow extends NoRollbackFlow { @Autowired @@ -37,12 +43,26 @@ public void run(final FlowTrigger chain, final Map ctx) { assert spec != null; final PrimaryStorageInventory pinv = (PrimaryStorageInventory) ctx.get(VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString()); + final String allocatedUrl = (String) ctx.get(VmInstanceConstant.Params.AllocatedUrlForAttachingVolume.toString()); + + PrimaryStorageHostStatus status = Q.New(PrimaryStorageHostRefVO.class) + .eq(PrimaryStorageHostRefVO_.hostUuid, spec.getDestHost().getUuid()) + .eq(PrimaryStorageHostRefVO_.primaryStorageUuid, pinv.getUuid()) + .select(PrimaryStorageHostRefVO_.status) + .findValue(); + if (status != null && !PrimaryStorageHostStatus.Connected.equals(status)) { + chain.fail(operr("Failed to instantiate volume. Because vm's" + + " host[uuid: %s] and allocated primary storage[uuid: %s] is not connected.", + spec.getDestHost().getUuid(), pinv.getUuid())); + return; + } InstantiateVolumeMsg msg = new InstantiateVolumeMsg(); msg.setPrimaryStorageAllocated(true); msg.setPrimaryStorageUuid(pinv.getUuid()); msg.setVolumeUuid(volume.getUuid()); msg.setHostUuid(spec.getDestHost().getUuid()); + msg.setAllocatedInstallUrl(allocatedUrl); bus.makeTargetServiceIdByResourceUuid(msg, VolumeConstant.SERVICE_ID, volume.getUuid()); bus.send(msg, new CloudBusCallBack(chain) { @Override diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateOtherDiskFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateOtherDiskFlow.java new file mode 100644 index 00000000000..26b6ce34560 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateOtherDiskFlow.java @@ -0,0 +1,459 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.compute.allocator.HostAllocatorManager; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.header.configuration.DiskOfferingVO; +import org.zstack.header.configuration.DiskOfferingVO_; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.image.ImageBackupStorageRefVO; +import org.zstack.header.image.ImageVO; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.backup.BackupStorageVO; +import org.zstack.header.storage.backup.BackupStorageVO_; +import org.zstack.header.storage.primary.*; +import org.zstack.header.vm.*; +import org.zstack.header.volume.*; +import org.zstack.identity.AccountManager; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.sql.Array; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmInstantiateOtherDiskFlow implements Flow { + private static final CLogger logger = Utils.getLogger(VmInstantiateOtherDiskFlow.class); + + @Autowired + private CloudBus bus; + @Autowired + private AccountManager acntMgr; + @Autowired + private DatabaseFacade dbf; + @Autowired + private PluginRegistry pluginRgty; + @Autowired + protected HostAllocatorManager hostAllocatorMgr; + + APICreateVmInstanceMsg.DiskAO diskAO; + VolumeInventory volumeInventory; + + VmInstantiateOtherDiskFlow(APICreateVmInstanceMsg.DiskAO diskAO) { + this.diskAO = diskAO; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + VmInstanceInventory instantiateVm = (VmInstanceInventory) data.get(VmInstanceInventory.class.getSimpleName()); + String vmUuid = instantiateVm.getUuid(); + String hostUuid = instantiateVm.getLastHostUuid(); + String accountUuid = acntMgr.getOwnerAccountUuidOfResource(instantiateVm.getUuid()); + + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("instantiate-other-disk-from-vm-%s", vmUuid)); + chain.then(new ShareFlow() { + String allocatedInstallUrl; + String allocatedPrimaryStorageUuid; + + @Override + public void setup() { + if (diskAO.getSize() != 0) { + setupCreateVolumeFromDiskSizeFlows(diskAO.getSize()); + setupAttachVolumeFlows(); + } else if (diskAO.getDiskOfferingUuid() != null) { + Long size = Q.New(DiskOfferingVO.class).eq(DiskOfferingVO_.uuid, diskAO.getDiskOfferingUuid()) + .select(DiskOfferingVO_.diskSize).findValue(); + setupCreateVolumeFromDiskSizeFlows(size); + setupAttachVolumeFlows(); + } else if (diskAO.getTemplateUuid() != null) { + setupVolumeFromTemplateUuidFlows(); + setupAttachVolumeFlows(); + } else if (isAttachDataVolume()) { + VolumeVO volume = Q.New(VolumeVO.class).eq(VolumeVO_.uuid, diskAO.getSourceUuid()).find(); + volumeInventory = VolumeInventory.valueOf(volume); + setupAttachVolumeFlows(); + } else if (diskAO.getSourceUuid() != null && diskAO.getSourceType() != null) { + setupAttachOtherDiskFlows(); + } else { + trigger.fail(operr("the diskAO parameter is incorrect. need to set one of the following properties, " + + "and can only be one of them: size, templateUuid, diskOfferingUuid, sourceUuid-sourceType")); + } + + done(new FlowDoneHandler(trigger) { + @Override + public void handle(Map data) { + trigger.next(); + } + }); + + error(new FlowErrorHandler(trigger) { + @Override + public void handle(ErrorCode errCode, Map data) { + trigger.fail(errCode); + } + }); + } + + private boolean isAttachDataVolume() { + return diskAO.getSourceUuid() != null && diskAO.getSourceType() != null && Objects.equals(diskAO.getSourceType(), VolumeVO.class.getSimpleName()); + } + + private void setupCreateVolumeFromDiskSizeFlows(Long diskSize) { + flow(new Flow() { + String __name__ = "allocate-primaryStorage"; + + boolean isSuccessAllocatePS = false; + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + AllocatePrimaryStorageSpaceMsg amsg = new AllocatePrimaryStorageSpaceMsg(); + amsg.setSize(diskSize); + amsg.setVmInstanceUuid(vmUuid); + amsg.setRequiredHostUuid(hostUuid); + amsg.setDiskOfferingUuid(diskAO.getDiskOfferingUuid()); + amsg.setRequiredPrimaryStorageUuid(diskAO.getPrimaryStorageUuid()); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); + bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); + bus.send(amsg, new CloudBusCallBack(innerTrigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + innerTrigger.fail(reply.getError()); + return; + } + AllocatePrimaryStorageSpaceReply ar = (AllocatePrimaryStorageSpaceReply) reply; + allocatedInstallUrl = ar.getAllocatedInstallUrl(); + allocatedPrimaryStorageUuid = ar.getPrimaryStorageInventory().getUuid(); + isSuccessAllocatePS = true; + innerTrigger.next(); + } + }); + } + + @Override + public void rollback(FlowRollback chain, Map data) { + if (!isSuccessAllocatePS) { + chain.rollback(); + return; + } + ReleasePrimaryStorageSpaceMsg msg = new ReleasePrimaryStorageSpaceMsg(); + msg.setDiskSize(diskAO.getSize()); + msg.setAllocatedInstallUrl(allocatedInstallUrl); + msg.setPrimaryStorageUuid(allocatedPrimaryStorageUuid); + bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, allocatedPrimaryStorageUuid); + bus.send(msg); + chain.rollback(); + } + }); + + flow(new Flow() { + String __name__ = "create-data-volume"; + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + String volumeFormat = VolumeFormat.getVolumeFormatByMasterHypervisorType(instantiateVm.getHypervisorType()).toString(); + + CreateVolumeMsg msg = new CreateVolumeMsg(); + msg.setAccountUuid(accountUuid); + msg.setVmInstanceUuid(vmUuid); + msg.setSize(diskSize); + msg.setName(diskAO.getName()); + msg.setFormat(volumeFormat); + msg.setSystemTags(diskAO.getSystemTags()); + msg.setVolumeType(VolumeType.Data.toString()); + msg.setDiskOfferingUuid(diskAO.getDiskOfferingUuid()); + msg.setPrimaryStorageUuid(allocatedPrimaryStorageUuid); + msg.setDescription(String.format("vm-%s-data-volume", vmUuid)); + bus.makeLocalServiceId(msg, VolumeConstant.SERVICE_ID); + bus.send(msg, new CloudBusCallBack(innerTrigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + innerTrigger.fail(reply.getError()); + return; + } + CreateVolumeReply cr = reply.castReply(); + volumeInventory = cr.getInventory(); + innerTrigger.next(); + } + }); + } + + @Override + public void rollback(FlowRollback chain, Map data) { + if (volumeInventory == null) { + chain.rollback(); + return; + } + DeleteVolumeMsg msg = new DeleteVolumeMsg(); + msg.setUuid(volumeInventory.getUuid()); + msg.setDeletionPolicy(VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct.toString()); + bus.makeTargetServiceIdByResourceUuid(msg, VolumeConstant.SERVICE_ID, volumeInventory.getUuid()); + bus.send(msg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + chain.rollback(); + return; + } + + DeleteVolumeGC gc = new DeleteVolumeGC(); + gc.NAME = String.format("gc-volume-%s", volumeInventory.getUuid()); + gc.deletionPolicy = VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct.toString(); + gc.volumeUuid = volumeInventory.getUuid(); + gc.submit(TimeUnit.HOURS.toSeconds(8), TimeUnit.SECONDS); + + chain.rollback(); + } + }); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "instantiate-data-volume"; + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + InstantiateVolumeMsg imsg = new InstantiateVolumeMsg(); + imsg.setHostUuid(hostUuid); + imsg.setSkipIfExisting(true); + imsg.setPrimaryStorageAllocated(true); + imsg.setVolumeUuid(volumeInventory.getUuid()); + imsg.setAllocatedInstallUrl(allocatedInstallUrl); + imsg.setPrimaryStorageUuid(allocatedPrimaryStorageUuid); + bus.makeLocalServiceId(imsg, VolumeConstant.SERVICE_ID); + bus.send(imsg, new CloudBusCallBack(innerTrigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + innerTrigger.fail(reply.getError()); + return; + } + innerTrigger.next(); + } + }); + } + }); + } + + private void setupVolumeFromTemplateUuidFlows() { + final String[] allocatedPrimaryStorageUuid = new String[1]; + + flow(new NoRollbackFlow() { + String __name__ = String.format("dryrun-allocate-primary-storage-for-templateUuid-%s", diskAO.getTemplateUuid()); + + @Override + public boolean skip(Map data) { + return diskAO.getPrimaryStorageUuid() != null; + } + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + ImageVO template = dbf.findByUuid(diskAO.getTemplateUuid(), ImageVO.class); + + AllocatePrimaryStorageSpaceMsg amsg = new AllocatePrimaryStorageSpaceMsg(); + amsg.setDryRun(true); + amsg.setSize(template.getSize()); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); + amsg.setRequiredHostUuid(instantiateVm.getLastHostUuid()); + amsg.setRequiredClusterUuids(Collections.singletonList(instantiateVm.getClusterUuid())); + List bsUuids = template.getBackupStorageRefs().stream() + .map(ImageBackupStorageRefVO::getBackupStorageUuid).collect(Collectors.toList()); + amsg.setPossiblePrimaryStorageTypes(possiblePrimaryStorageTypes(bsUuids)); + + bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); + bus.send(amsg, new CloudBusCallBack(innerTrigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + innerTrigger.fail(reply.getError()); + return; + } + AllocatePrimaryStorageDryRunReply ar = (AllocatePrimaryStorageDryRunReply) reply; + allocatedPrimaryStorageUuid[0] = ar.getPrimaryStorageInventories().get(0).getUuid(); + innerTrigger.next(); + } + }); + } + + private List possiblePrimaryStorageTypes(List bsUuids) { + if (CollectionUtils.isEmpty(bsUuids)) { + return Collections.emptyList(); + } + List imageBsTypes = Q.New(BackupStorageVO.class).select(BackupStorageVO_.type) + .in(BackupStorageVO_.uuid, bsUuids).listValues(); + List possiblePrimaryStorageTypes = new ArrayList<>(); + imageBsTypes.forEach(imageBsType -> possiblePrimaryStorageTypes + .addAll(hostAllocatorMgr.getBackupStoragePrimaryStorageMetrics().get(imageBsType))); + return possiblePrimaryStorageTypes.stream().distinct().collect(Collectors.toList()); + } + }); + + flow(new Flow() { + String __name__ = String.format("instantiate-data-volume-from-template-%s", diskAO.getTemplateUuid()); + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + CreateDataVolumeFromVolumeTemplateMsg cmsg = new CreateDataVolumeFromVolumeTemplateMsg(); + cmsg.setHostUuid(instantiateVm.getLastHostUuid()); + cmsg.setImageUuid(diskAO.getTemplateUuid()); + cmsg.setName(diskAO.getName()); + cmsg.setAccountUuid(accountUuid); + cmsg.setSystemTags(diskAO.getSystemTags()); + cmsg.setDescription(String.format("vm-%s-data-volume", vmUuid)); + if (diskAO.getPrimaryStorageUuid() != null) { + cmsg.setPrimaryStorageUuid(diskAO.getPrimaryStorageUuid()); + } else { + cmsg.setPrimaryStorageUuid(allocatedPrimaryStorageUuid[0]); + } + + bus.makeLocalServiceId(cmsg, VolumeConstant.SERVICE_ID); + bus.send(cmsg, new CloudBusCallBack(innerTrigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + innerTrigger.fail(reply.getError()); + return; + } + VolumeInventory inv = ((CreateDataVolumeFromVolumeTemplateReply) reply).getInventory(); + String volumeUuid = inv.getUuid(); + VolumeVO vo = dbf.findByUuid(volumeUuid, VolumeVO.class); + vo.setVmInstanceUuid(vmUuid); + vo.setActualSize(vo.getActualSize() == null ? 0L : vo.getActualSize()); + vo = dbf.updateAndRefresh(vo); + volumeInventory = VolumeInventory.valueOf(vo); + innerTrigger.next(); + } + }); + } + + @Override + public void rollback(FlowRollback chain, Map data) { + if (volumeInventory == null) { + chain.rollback(); + return; + } + DeleteVolumeMsg msg = new DeleteVolumeMsg(); + msg.setDeletionPolicy(VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct.toString()); + msg.setUuid(volumeInventory.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, VolumeConstant.SERVICE_ID, volumeInventory.getUuid()); + bus.send(msg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + chain.rollback(); + return; + } + + DeleteVolumeGC gc = new DeleteVolumeGC(); + gc.NAME = String.format("gc-volume-%s", msg.getVolumeUuid()); + gc.deletionPolicy = VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct.toString(); + gc.volumeUuid = msg.getVolumeUuid(); + gc.submit(TimeUnit.HOURS.toSeconds(8), TimeUnit.SECONDS); + + chain.rollback(); + } + }); + } + }); + } + + private void setupAttachVolumeFlows() { + flow(new NoRollbackFlow() { + String __name__ = String.format("attach-volume-to-vm-%s", vmUuid); + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + AttachDataVolumeToVmMsg amsg = new AttachDataVolumeToVmMsg(); + amsg.setVmInstanceUuid(vmUuid); + amsg.setVolume(volumeInventory); + bus.makeTargetServiceIdByResourceUuid(amsg, VmInstanceConstant.SERVICE_ID, vmUuid); + bus.send(amsg, new CloudBusCallBack(innerTrigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + innerTrigger.fail(reply.getError()); + return; + } + innerTrigger.next(); + } + }); + } + }); + } + + private void setupAttachOtherDiskFlows() { + flow(new NoRollbackFlow() { + String __name__ = String.format("attach-other-Disk-to-vm-%s", vmUuid); + + @Override + public void run(final FlowTrigger innerTrigger, Map data) { + VmAttachOtherDiskExtensionPoint vmAttachOtherDiskExtensionPoint = pluginRgty + .getExtensionFromMap(diskAO.getSourceType(), VmAttachOtherDiskExtensionPoint.class); + if (vmAttachOtherDiskExtensionPoint == null) { + innerTrigger.fail(operr("the disk does not support attachment. disk type is %s", diskAO.getSourceType())); + return; + } + vmAttachOtherDiskExtensionPoint.attachOtherDiskToVm(diskAO, vmUuid, new Completion(innerTrigger) { + @Override + public void success() { + innerTrigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + innerTrigger.fail(errorCode); + } + }); + } + }); + } + }).start(); + } + + @Override + public void rollback(FlowRollback chain, Map data) { + if (volumeInventory == null) { + chain.rollback(); + return; + } + + DeleteVolumeMsg msg = new DeleteVolumeMsg(); + msg.setDeletionPolicy(VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct.toString()); + msg.setUuid(volumeInventory.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, VolumeConstant.SERVICE_ID, volumeInventory.getUuid()); + bus.send(msg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + chain.rollback(); + return; + } + DeleteVolumeGC gc = new DeleteVolumeGC(); + gc.NAME = String.format("gc-volume-%s", msg.getVolumeUuid()); + gc.deletionPolicy = VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct.toString(); + gc.volumeUuid = msg.getVolumeUuid(); + gc.submit(TimeUnit.HOURS.toSeconds(8), TimeUnit.SECONDS); + chain.rollback(); + } + }); + } +} + diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java index f84c0c59577..bbdb2978036 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourceForChangeImageFlow.java @@ -25,14 +25,9 @@ public class VmInstantiateResourceForChangeImageFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private static List extensions = null; + private final List extensions = pluginRgty.getExtensionList(ChangeVmImageExtensionPoint.class); + - public VmInstantiateResourceForChangeImageFlow() { - if (extensions == null) { - extensions = pluginRgty.getExtensionList(ChangeVmImageExtensionPoint.class); - } - } - private void runExtensions(final Iterator it, final VmInstanceSpec spec, final FlowTrigger chain) { if (!it.hasNext()) { chain.next(); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java index 07914db1903..e6a7f14c34d 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePostFlow.java @@ -28,13 +28,8 @@ public class VmInstantiateResourcePostFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private static List extensions; + private final List extensions = pluginRgty.getExtensionList(PostVmInstantiateResourceExtensionPoint.class); - public VmInstantiateResourcePostFlow() { - if (extensions == null) { - extensions = pluginRgty.getExtensionList(PostVmInstantiateResourceExtensionPoint.class); - } - } public void run(FlowTrigger trigger, Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java index 22ba9b17ba5..4c7b6eee38f 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmInstantiateResourcePreFlow.java @@ -15,6 +15,7 @@ import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmInstantiateResourceException; import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import java.util.Iterator; @@ -28,14 +29,9 @@ public class VmInstantiateResourcePreFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private static List extensions = null; - - public VmInstantiateResourcePreFlow() { - if (extensions == null) { - extensions = pluginRgty.getExtensionList(PreVmInstantiateResourceExtensionPoint.class); - } - } + private final List extensions = pluginRgty.getExtensionList(PreVmInstantiateResourceExtensionPoint.class); + private void runExtensions(final Iterator it, final VmInstanceSpec spec, final FlowTrigger chain) { if (!it.hasNext()) { spec.setInstantiateResourcesSuccess(true); @@ -48,6 +44,10 @@ private void runExtensions(final Iterator() { @Override - public void run(VmInstanceMigrateExtensionPoint ext) { - ext.beforeMigrateVm(spec.getVmInventory(), destHost.getUuid()); + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); } }); - - trigger.next(); } @Override diff --git a/compute/src/main/java/org/zstack/compute/vm/VmMigrateOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmMigrateOnHypervisorFlow.java index 433e212aaea..24529a31df3 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmMigrateOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmMigrateOnHypervisorFlow.java @@ -38,10 +38,12 @@ public void run(final FlowTrigger chain, Map data) { boolean migrateFromDest = false; String strategy = null; + Integer downTime = null; if (spec.getMessage() instanceof MigrateVmMessage) { MigrateVmMessage vmMessage = (MigrateVmMessage) spec.getMessage(); migrateFromDest = vmMessage.isMigrateFromDestination(); strategy = vmMessage.getStrategy(); + downTime = vmMessage.getDownTime(); } MigrateVmOnHypervisorMsg msg = new MigrateVmOnHypervisorMsg(); @@ -50,6 +52,7 @@ public void run(final FlowTrigger chain, Map data) { msg.setSrcHostUuid(spec.getVmInventory().getHostUuid()); msg.setMigrateFromDestination(migrateFromDest); msg.setStrategy(strategy); + msg.setDownTime(downTime); bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, msg.getHostUuid()); bus.send(msg, new CloudBusCallBack(chain) { @Override diff --git a/compute/src/main/java/org/zstack/compute/vm/VmMigratePostCallExtensionFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmMigratePostCallExtensionFlow.java new file mode 100644 index 00000000000..dbb27ccd11c --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmMigratePostCallExtensionFlow.java @@ -0,0 +1,49 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.core.workflow.FlowRollback; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostInventory; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceSpec; + +import java.util.Map; + +/** + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmMigratePostCallExtensionFlow implements Flow { + @Autowired + protected PluginRegistry pluginRgty; + @Autowired + private VmInstanceExtensionPointEmitter extEmitter; + + @Override + public void run(FlowTrigger trigger, Map data) { + final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + + final HostInventory destHost = spec.getDestHost(); + extEmitter.postMigrateVm(spec.getVmInventory(), destHost.getUuid(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + trigger.rollback(); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmMigrationCheckL2NetworkOnHostFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmMigrationCheckL2NetworkOnHostFlow.java index a0ad92e81d6..98a343691a6 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmMigrationCheckL2NetworkOnHostFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmMigrationCheckL2NetworkOnHostFlow.java @@ -5,19 +5,21 @@ import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusListCallBack; +import org.zstack.core.db.DatabaseFacade; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.CheckL2NetworkOnHostMsg; import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.vm.*; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** */ @@ -25,6 +27,8 @@ public class VmMigrationCheckL2NetworkOnHostFlow implements Flow { @Autowired private CloudBus bus; + @Autowired + private DatabaseFacade dbf; @Override public void run(final FlowTrigger trigger, Map data) { @@ -34,6 +38,11 @@ public void run(final FlowTrigger trigger, Map data) { List cmsgs = new ArrayList(); for (L3NetworkInventory l3 : VmNicSpec.getL3NetworkInventoryOfSpec(spec.getL3Networks())) { CheckL2NetworkOnHostMsg msg = new CheckL2NetworkOnHostMsg(); + L2NetworkVO l2NetworkVO = dbf.findByUuid(l3.getL2NetworkUuid(), L2NetworkVO.class); + VSwitchType switchType = VSwitchType.valueOf(l2NetworkVO.getvSwitchType()); + if (!switchType.isAttachToCluster()) { + continue; + } msg.setL2NetworkUuid(l3.getL2NetworkUuid()); msg.setHostUuid(spec.getDestHost().getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, l3.getL2NetworkUuid()); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmMigrationMetric.java b/compute/src/main/java/org/zstack/compute/vm/VmMigrationMetric.java new file mode 100644 index 00000000000..5e9f8414148 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmMigrationMetric.java @@ -0,0 +1,6 @@ +package org.zstack.compute.vm; + +public interface VmMigrationMetric { + boolean isCapable(String rootVolumePrimaryStorageType); + boolean isSupportWithSharedBlock(); +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmNicFactory.java b/compute/src/main/java/org/zstack/compute/vm/VmNicFactory.java index 9b78694c121..73193da3c37 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmNicFactory.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmNicFactory.java @@ -1,16 +1,10 @@ package org.zstack.compute.vm; -import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException; -import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.orm.jpa.JpaSystemException; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.SQL; import org.zstack.header.core.workflow.FlowException; import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l3.UsedIpInventory; -import org.zstack.header.network.l3.UsedIpVO; -import org.zstack.header.network.l3.UsedIpVO_; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.vm.*; import org.zstack.identity.Account; import org.zstack.utils.ExceptionDSL; @@ -19,25 +13,28 @@ import org.zstack.utils.network.NetworkUtils; import javax.persistence.PersistenceException; -import java.util.ArrayList; -import java.util.List; +import java.sql.SQLIntegrityConstraintViolationException; import static org.zstack.core.Platform.err; public class VmNicFactory implements VmInstanceNicFactory { private static final CLogger logger = Utils.getLogger(VmNicFactory.class); - private static final VmNicType type = new VmNicType(VmInstanceConstant.VIRTUAL_NIC_TYPE, L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + private static final VSwitchType vSwitchType = new VSwitchType(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + private static final VmNicType type = new VmNicType(VmInstanceConstant.VIRTUAL_NIC_TYPE); @Autowired private DatabaseFacade dbf; @Override public VmNicType getType() { + type.setHasAddon(true); + vSwitchType.addVmNicType(VmNicType.VmNicSubType.NONE, type); + return type; } @Override - public VmNicVO createVmNic(VmNicInventory nic, VmInstanceSpec spec, List ips) { + public VmNicVO createVmNic(VmNicInventory nic, VmInstanceSpec spec) { String acntUuid = Account.getAccountUuidOfResource(spec.getVmInventory().getUuid()); VmNicVO vnic = VmInstanceNicFactory.createVmNic(nic); @@ -47,33 +44,23 @@ public VmNicVO createVmNic(VmNicInventory nic, VmInstanceSpec spec, List ipVOS = new ArrayList<>(); - for (UsedIpInventory ip : ips) { - /* update usedIpVo */ - UsedIpVO ipVO = dbf.findByUuid(ip.getUuid(), UsedIpVO.class); - ipVO.setVmNicUuid(vnic.getUuid()); - ipVOS.add(ipVO); - } - dbf.updateCollection(ipVOS); - vnic = dbf.reload(vnic); spec.getDestNics().add(VmNicInventory.valueOf(vnic)); return vnic; } - private VmNicVO persistAndRetryIfMacCollision(VmNicVO vo) { + public VmNicVO persistAndRetryIfMacCollision(VmNicVO vo) { int tries = 5; while (tries-- > 0) { try { return dbf.persistAndRefresh(vo); } catch (PersistenceException e) { - if (ExceptionDSL.isCausedBy(e, MySQLIntegrityConstraintViolationException.class, "Duplicate entry")) { + if (ExceptionDSL.isCausedBy(e, SQLIntegrityConstraintViolationException.class, "Duplicate entry")) { logger.debug(String.format("Concurrent mac allocation. Mac[%s] has been allocated, try allocating another one. " + "The error[Duplicate entry] printed by jdbc.spi.SqlExceptionHelper is no harm, " + "we will try finding another mac", vo.getMac())); logger.trace("", e); - vo.setMac(NetworkUtils.generateMacWithDeviceId((short) vo.getDeviceId())); + vo.setMac(MacOperator.generateMacWithDeviceId((short) vo.getDeviceId())); } else { throw e; } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmNicManager.java b/compute/src/main/java/org/zstack/compute/vm/VmNicManager.java index 18ede8f135f..ab6cc8d749d 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmNicManager.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmNicManager.java @@ -1,6 +1,9 @@ package org.zstack.compute.vm; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.vm.VmNicType; import java.util.List; @@ -12,5 +15,9 @@ public interface VmNicManager { String getDefaultNicDriver(); - void setNicDriverType(VmNicInventory nic, boolean isImageSupportVirtIo, boolean isParaVirtualization); + String getPcNetNicDriver(); + + void setNicDriverType(VmNicInventory nic, boolean isImageSupportVirtIo, boolean isParaVirtualization, VmInstanceInventory vm); + + VmNicType getVmNicType(String vmUuid, L3NetworkInventory l3nw); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java b/compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java index 5cf48249d6f..df2bc6bcaf7 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java @@ -3,35 +3,53 @@ import com.google.common.collect.Maps; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.db.SimpleQuery; import org.zstack.header.Component; + +import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.image.ImagePlatform; import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.VSwitchType; +import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.UsedIpVO; import org.zstack.header.network.l3.UsedIpVO_; -import org.zstack.header.tag.SystemTagInventory; -import org.zstack.header.tag.SystemTagLifeCycleListener; +import org.zstack.header.tag.*; import org.zstack.header.vm.*; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; +import org.zstack.network.service.NetworkServiceGlobalConfig; import org.zstack.utils.Utils; -import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import javax.persistence.Tuple; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; +import static org.zstack.core.Platform.argerr; + @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmNicManagerImpl implements VmNicManager, VmNicExtensionPoint, PrepareDbInitialValueExtensionPoint, VmPlatformChangedExtensionPoint, Component { private static final CLogger logger = Utils.getLogger(VmNicManagerImpl.class); + @Autowired + private VmInstanceDeviceManager vidm; + @Autowired + private PluginRegistry pluginRegistry; + @Autowired + private DatabaseFacade dbf; + private List supportNicDriverTypes; private String defaultPVNicDriver; private String defaultNicDriver; + private String pcNetNicDriver; @Override public void afterAddIpAddress(String vmNicUUid, String usedIpUuid) { @@ -55,7 +73,7 @@ public void afterAddIpAddress(String vmNicUUid, String usedIpUuid) { } } - if (!temp.getUuid().equals(nic.getUsedIpUuid())) { + if (temp != null && !temp.getUuid().equals(nic.getUsedIpUuid())) { SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, vmNicUUid) .set(VmNicVO_.ip, temp.getIp()) .set(VmNicVO_.netmask, temp.getNetmask()) @@ -162,7 +180,20 @@ public boolean skipPlatformChange(VmInstanceInventory vm, String previousPlatfor @Override public void vmPlatformChange(VmInstanceInventory vm, String previousPlatform, String nowPlatform) { - if (ImagePlatform.valueOf(nowPlatform).isParaVirtualization()) { + String driver = null; + for (VmNicSetDriverExtensionPoint ext : pluginRegistry.getExtensionList(VmNicSetDriverExtensionPoint.class)) { + driver = ext.getPreferredVmNicDriver(vm); + if (driver != null) { + break; + } + } + + if (driver != null) { + resetVmNicDriverType(vm.getUuid(), driver); + return; + } + + if (ImagePlatform.valueOf(nowPlatform).isParaVirtualization() || VmSystemTags.VIRTIO.hasTag(vm.getUuid())) { resetVmNicDriverType(vm.getUuid(), defaultPVNicDriver); return; } @@ -212,25 +243,74 @@ public String getDefaultNicDriver() { } @Override - public void setNicDriverType(VmNicInventory nic, boolean isImageSupportVirtIo, boolean isParaVirtualization) { - if (isImageSupportVirtIo || isParaVirtualization || VmSystemTags.VIRTIO.hasTag(nic.getVmInstanceUuid())) { + public String getPcNetNicDriver() { + return pcNetNicDriver; + } + + public void setPcNetNicDriver(String pcNetNicDriver) { + this.pcNetNicDriver = pcNetNicDriver; + } + + @Override + public void setNicDriverType(VmNicInventory nic, boolean isImageSupportVirtIo, boolean isParaVirtualization, VmInstanceInventory vm) { + String driver = null; + for (VmNicSetDriverExtensionPoint ext : pluginRegistry.getExtensionList(VmNicSetDriverExtensionPoint.class)) { + driver = ext.getPreferredVmNicDriver(vm); + if (driver != null) { + break; + } + } + + if (driver != null) { + nic.setDriverType(driver); + return; + } + + if (isImageSupportVirtIo || isParaVirtualization || VmSystemTags.VIRTIO.hasTag(vm.getUuid())) { nic.setDriverType(getDefaultPVNicDriver()); } else { nic.setDriverType(getDefaultNicDriver()); } } + @Override + public VmNicType getVmNicType(String vmUuid, L3NetworkInventory l3nw) { + List tags = new ArrayList<>(); + tags.add(String.format("enableSRIOV::%s", l3nw.getUuid())); + tags.add(String.format("enableVFHA::%s", l3nw.getUuid())); + boolean enableSriov = Q.New(SystemTagVO.class) + .eq(SystemTagVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .eq(SystemTagVO_.resourceUuid, vmUuid) + .in(SystemTagVO_.tag, tags) + .isExists(); + logger.debug(String.format("create %s on l3 network[uuid:%s] inside VmAllocateNicFlow", + enableSriov ? "vf nic" : "vnic", l3nw.getUuid())); + boolean enableVhostUser = NetworkServiceGlobalConfig.ENABLE_VHOSTUSER.value(Boolean.class); + VmNicType.VmNicSubType subType = VmNicType.VmNicSubType.NONE; + if (enableSriov) { + subType = VmNicType.VmNicSubType.SRIOV; + } else if (enableVhostUser) { + subType = VmNicType.VmNicSubType.VHOSTUSER; + } + L2NetworkVO l2nw = dbf.findByUuid(l3nw.getL2NetworkUuid(), L2NetworkVO.class); + VSwitchType vSwitchType = VSwitchType.valueOf(l2nw.getvSwitchType()); + + return vSwitchType.getVmNicType(subType); + } + @Override public boolean start() { VmSystemTags.VIRTIO.installLifeCycleListener(new SystemTagLifeCycleListener() { @Override public void tagCreated(SystemTagInventory tag) { resetVmNicDriverType(tag.getResourceUuid(), defaultPVNicDriver); + vidm.deleteDeviceAddressesByVmModifyVirtIO(tag.getResourceUuid()); } @Override public void tagDeleted(SystemTagInventory tag) { resetVmNicDriverType(tag.getResourceUuid(), defaultNicDriver); + vidm.deleteDeviceAddressesByVmModifyVirtIO(tag.getResourceUuid()); } @Override @@ -238,6 +318,22 @@ public void tagUpdated(SystemTagInventory old, SystemTagInventory newTag) { } }); + + VmSystemTags.VIRTIO.installValidator(new SystemTagValidator() { + @Override + public void validateSystemTag(String resourceUuid, Class resourceType, String systemTag) { + VmInstanceState state = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, resourceUuid) + .select(VmInstanceVO_.state) + .findValue(); + + if (state == VmInstanceState.Running || state == VmInstanceState.Unknown) { + throw new OperationFailureException(argerr("vm current state[%s], " + + "modify virtio requires the vm state[%s]", state, VmInstanceState.Stopped)); + } + } + }); + return true; } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmNicPrepareResourceExtensionPoint.java b/compute/src/main/java/org/zstack/compute/vm/VmNicPrepareResourceExtensionPoint.java new file mode 100644 index 00000000000..ca9a1aca5c5 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmNicPrepareResourceExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.compute.vm; + +import org.zstack.header.core.workflow.Flow; + +public interface VmNicPrepareResourceExtensionPoint { + Flow getPreparationFlow(); +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmNicQosStruct.java b/compute/src/main/java/org/zstack/compute/vm/VmNicQosStruct.java index b2fc09d36f5..20dc50c7f7f 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmNicQosStruct.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmNicQosStruct.java @@ -4,6 +4,7 @@ public class VmNicQosStruct { public String hostUuid; public String vmUuid; public String vmNicUuid; + public String l2Uuid; public String internalName; public Long outboundBandwidth; public Long inboundBandwidth; diff --git a/compute/src/main/java/org/zstack/compute/vm/VmPostReleaseNicFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmPostReleaseNicFlow.java new file mode 100644 index 00000000000..97d18a3dc9b --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmPostReleaseNicFlow.java @@ -0,0 +1,34 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.workflow.NoRollbackFlow; +import org.zstack.header.vm.VmDetachNicExtensionPoint; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.Map; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmPostReleaseNicFlow extends NoRollbackFlow { + private static final CLogger logger = Utils.getLogger(VmPostReleaseNicFlow.class); + @Autowired + protected PluginRegistry pluginRgty; + + @Override + public void run(final FlowTrigger trigger, final Map data) { + final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + for (VmNicInventory vmNic : spec.getVmInventory().getVmNics()) { + for (VmDetachNicExtensionPoint ext : pluginRgty.getExtensionList(VmDetachNicExtensionPoint.class)) { + ext.afterDetachNic(vmNic); + } + } + trigger.next(); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmPriorityGlobalProperty.java b/compute/src/main/java/org/zstack/compute/vm/VmPriorityGlobalProperty.java deleted file mode 100644 index 1e1ce074c68..00000000000 --- a/compute/src/main/java/org/zstack/compute/vm/VmPriorityGlobalProperty.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.zstack.compute.vm; - -import org.zstack.core.GlobalProperty; -import org.zstack.core.GlobalPropertyDefinition; - -/** - * @ Author : yh.w - * @ Date : Created in 14:22 2019/9/24 - */ -@GlobalPropertyDefinition -public class VmPriorityGlobalProperty { - - @GlobalProperty(name="initRunningVmPriority", defaultValue = "false") - public static boolean initRunningVmPriority; - @GlobalProperty(name="initRunningApplianceVmPriority", defaultValue = "false") - public static boolean initRunningApplianceVmPriority; -} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmPriorityUpgradeExtension.java b/compute/src/main/java/org/zstack/compute/vm/VmPriorityUpgradeExtension.java index 11f1253b0db..f182c443925 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmPriorityUpgradeExtension.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmPriorityUpgradeExtension.java @@ -9,14 +9,12 @@ import org.zstack.header.tag.SystemTagVO; import org.zstack.header.tag.SystemTagVO_; import org.zstack.header.vm.*; -import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * @ Author : yh.w @@ -96,7 +94,7 @@ public void run(MessageReply reply) { } private void initRunningVmPriority() { - if (!VmPriorityGlobalProperty.initRunningVmPriority) { + if (!VmGlobalProperty.initRunningVmPriority) { return; } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmQuotaOperator.java b/compute/src/main/java/org/zstack/compute/vm/VmQuotaOperator.java index 3c65df5ffbf..52e10ec6cfd 100644 --- a/compute/src/main/java/org/zstack/compute/vm/VmQuotaOperator.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmQuotaOperator.java @@ -502,21 +502,32 @@ private void check(APICreateVmInstanceMsg msg, Map pair // check all volume size long allVolumeSizeAsked = 0; - String sql = "select img.size, img.mediaType" + - " from ImageVO img" + - " where img.uuid = :iuuid"; - TypedQuery iq = dbf.getEntityManager().createQuery(sql, Tuple.class); - iq.setParameter("iuuid", msg.getImageUuid()); - Tuple it = iq.getSingleResult(); - Long imgSize = it.get(0, Long.class); - ImageConstant.ImageMediaType imgType = it.get(1, ImageConstant.ImageMediaType.class); + String sql; + Long imgSize; + ImageConstant.ImageMediaType imgType = null; + if (msg.getImageUuid() != null) { + sql = "select img.size, img.mediaType" + + " from ImageVO img" + + " where img.uuid = :iuuid"; + TypedQuery iq = dbf.getEntityManager().createQuery(sql, Tuple.class); + iq.setParameter("iuuid", msg.getImageUuid()); + Tuple it = iq.getSingleResult(); + imgSize = it.get(0, Long.class); + imgType = it.get(1, ImageConstant.ImageMediaType.class); + } else { + imgSize = null; + } List diskOfferingUuids = new ArrayList<>(); if (msg.getDataDiskOfferingUuids() != null && !msg.getDataDiskOfferingUuids().isEmpty()) { diskOfferingUuids.addAll(msg.getDataDiskOfferingUuids()); } if (imgType == ImageConstant.ImageMediaType.RootVolumeTemplate) { - allVolumeSizeAsked += imgSize; + if (msg.getRootDiskOfferingUuid() != null) { + diskOfferingUuids.add(msg.getRootDiskOfferingUuid()); + } else { + allVolumeSizeAsked += imgSize; + } } else if (imgType == ImageConstant.ImageMediaType.ISO) { if (msg.getRootDiskOfferingUuid() != null) { diskOfferingUuids.add(msg.getRootDiskOfferingUuid()); @@ -525,6 +536,14 @@ private void check(APICreateVmInstanceMsg msg, Map pair } else { throw new ApiMessageInterceptionException(argerr("rootDiskOfferingUuid cannot be null when image mediaType is ISO")); } + } else { + if (msg.getRootDiskOfferingUuid() != null) { + diskOfferingUuids.add(msg.getRootDiskOfferingUuid()); + } else if (msg.getRootDiskSize() != null) { + allVolumeSizeAsked += msg.getRootDiskSize(); + } else { + throw new ApiMessageInterceptionException(argerr("rootDiskOfferingUuid cannot be null when create vm without image")); + } } HashMap diskOfferingCountMap = new HashMap<>(); diff --git a/compute/src/main/java/org/zstack/compute/vm/VmQuotaUtil.java b/compute/src/main/java/org/zstack/compute/vm/VmQuotaUtil.java index 092a037ebe5..dd76200386b 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmQuotaUtil.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmQuotaUtil.java @@ -5,9 +5,11 @@ import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.volume.VolumeStatus; import org.zstack.header.volume.VolumeType; import org.zstack.header.volume.VolumeVO; @@ -108,7 +110,8 @@ public VmQuota getUsedVmCpuMemory(String accountUUid, String excludeVmUuid) { " where vm.uuid = ref.resourceUuid" + " and ref.accountUuid = :auuid" + " and ref.resourceType = :rtype" + - " and not (vm.hostUuid is null and vm.lastHostUuid is null)" + + // for vm without host and volume info, treat them as new creating vm + " and not (vm.hostUuid is null and vm.lastHostUuid is null and vm.rootVolumeUuid is null)" + " and vm.state not in (:states)" + " and vm.type != :vmtype"; TypedQuery q2 = dbf.getEntityManager().createQuery(sql2, Long.class); @@ -118,7 +121,6 @@ public VmQuota getUsedVmCpuMemory(String accountUUid, String excludeVmUuid) { q2.setParameter("vmtype", "baremetal2"); Long totalVmNum = q2.getSingleResult(); quota.totalVmNum = totalVmNum == null ? 0 : totalVmNum; - return quota; } @@ -137,4 +139,22 @@ public long getVmInstanceRootVolumeSize(String vmInstanceUuid) { rootVolumeSize = rootVolumeSize == null ? 0 : rootVolumeSize; return rootVolumeSize; } + + @Transactional(readOnly = true) + public Long getRequiredCpu(String vmInstanceUuid) { + Integer cpuNum = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.cpuNum) + .eq(VmInstanceVO_.uuid, vmInstanceUuid) + .findValue(); + + return Integer.toUnsignedLong(cpuNum); + } + + @Transactional(readOnly = true) + public Long getRequiredMemory(String vmInstanceUuid) { + return Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.memorySize) + .eq(VmInstanceVO_.uuid, vmInstanceUuid) + .findValue(); + } } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmReleaseNetworkServiceOnChangeIPFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmReleaseNetworkServiceOnChangeIPFlow.java new file mode 100644 index 00000000000..3be2f23c64c --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmReleaseNetworkServiceOnChangeIPFlow.java @@ -0,0 +1,51 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.core.workflow.FlowRollback; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.NoRollbackFlow; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceDeletionPolicyManager; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.network.service.NetworkServiceManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmReleaseNetworkServiceOnChangeIPFlow implements Flow { + private static final CLogger logger = Utils.getLogger(VmReleaseNetworkServiceOnChangeIPFlow.class); + + @Autowired + private NetworkServiceManager nsMgr; + + @Override + public void run(FlowTrigger trigger, Map data) { + VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + nsMgr.releaseNetworkServiceOnChangeIP(spec, null, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + trigger.rollback(); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java index 56fe116c3ca..a57b93acde1 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmReleaseResourceFlow.java @@ -27,13 +27,7 @@ public class VmReleaseResourceFlow implements Flow { @Autowired private PluginRegistry pluginRgty; - private static List extensions = null; - - public VmReleaseResourceFlow() { - if (extensions == null) { - extensions = pluginRgty.getExtensionList(VmReleaseResourceExtensionPoint.class); - } - } + private final List extensions = pluginRgty.getExtensionList(VmReleaseResourceExtensionPoint.class); private void fireExtensions(final Iterator it, final VmInstanceSpec spec, final Map ctx, final FlowTrigger chain) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmReturnReleaseNicFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmReturnReleaseNicFlow.java index bc916297625..0fd0e2aa068 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmReturnReleaseNicFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmReturnReleaseNicFlow.java @@ -3,17 +3,21 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkConstant; import org.zstack.header.network.l3.ReturnIpMsg; import org.zstack.header.network.l3.UsedIpInventory; import org.zstack.header.vm.*; import org.zstack.header.vm.VmInstanceDeletionPolicyManager.VmInstanceDeletionPolicy; import org.zstack.utils.Utils; -import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import java.util.ArrayList; @@ -39,7 +43,7 @@ public void run(FlowTrigger chain, Map data) { return; } - List msgs = new ArrayList(spec.getVmInventory().getVmNics().size()); + List msgs = new ArrayList<>(spec.getVmInventory().getVmNics().size()); for (VmNicInventory nic : spec.getVmInventory().getVmNics()) { for (UsedIpInventory ip : nic.getUsedIps()) { ReturnIpMsg msg = new ReturnIpMsg(); @@ -48,27 +52,40 @@ public void run(FlowTrigger chain, Map data) { bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, ip.getL3NetworkUuid()); msgs.add(msg); } + } - VmNicVO vo = dbf.findByUuid(nic.getUuid(), VmNicVO.class); - if (VmInstanceConstant.USER_VM_TYPE.equals(spec.getVmInventory().getType())) { - VmInstanceDeletionPolicy deletionPolicy = getDeletionPolicy(spec, data); - if (deletionPolicy == VmInstanceDeletionPolicy.Direct) { - dbf.remove(vo); - } else { - vo.setUsedIpUuid(null); - vo.setIp(null); - vo.setGateway(null); - vo.setNetmask(null); - dbf.update(vo); + new While<>(msgs).each((returnIpMsg, completion) -> bus.send(returnIpMsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to release ip[usedIpUuid:%s] for vm[uuid:%s], but continue anyway", + returnIpMsg.getUsedIpUuid(), spec.getVmInventory().getUuid())); } - } else { - dbf.remove(vo); + completion.done(); } - } - - bus.send(msgs); - - chain.next(); + })).run(new WhileDoneCompletion(chain) { + @Override + public void done(ErrorCodeList errorCodeList) { + for (VmNicInventory nic : spec.getVmInventory().getVmNics()) { + VmNicVO vo = dbf.findByUuid(nic.getUuid(), VmNicVO.class); + if (VmInstanceConstant.USER_VM_TYPE.equals(spec.getVmInventory().getType())) { + VmInstanceDeletionPolicy deletionPolicy = getDeletionPolicy(spec, data); + if (deletionPolicy == VmInstanceDeletionPolicy.Direct) { + dbf.remove(vo); + } else { + vo.setUsedIpUuid(null); + vo.setIp(null); + vo.setGateway(null); + vo.setNetmask(null); + dbf.update(vo); + } + } else { + dbf.remove(vo); + } + } + chain.next(); + } + }); } private VmInstanceDeletionPolicy getDeletionPolicy(VmInstanceSpec spec, Map data) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmSchedHistoryRecorder.java b/compute/src/main/java/org/zstack/compute/vm/VmSchedHistoryRecorder.java new file mode 100644 index 00000000000..42bf69104b2 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/VmSchedHistoryRecorder.java @@ -0,0 +1,107 @@ +package org.zstack.compute.vm; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SQL; +import org.zstack.core.db.SQLBatchWithReturn; +import org.zstack.header.vm.*; +import org.zstack.identity.AccountManager; +import org.zstack.utils.DebugUtils; +import org.zstack.utils.data.Pair; + +import javax.persistence.Tuple; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VmSchedHistoryRecorder { + public static final String TYPE_HA = "VMHA"; + public static final String TYPE_HOST_MAINTENANCE = "HMT"; + + private final String vmInstanceUuid; + private final String schedType; + private final String hostUuid; + private final String zoneUuid; + private String schedReason; + private String failReason; + private VmSchedHistoryVO vo; + + @Autowired + private AccountManager accountManager; + @Autowired + private DatabaseFacade dbf; + + public static VmSchedHistoryRecorder ofHostMaintenance(String vmUuid) { + return new VmSchedHistoryRecorder(TYPE_HOST_MAINTENANCE, vmUuid); + } + + public static VmSchedHistoryRecorder ofHA(String vmUuid) { + return new VmSchedHistoryRecorder(TYPE_HA, vmUuid); + } + + public static VmSchedHistoryRecorder ofHA(VmInstanceInventory vmInv) { + return new VmSchedHistoryRecorder(TYPE_HA, vmInv); + } + + private VmSchedHistoryRecorder(String schedType, String vmUuid) { + this.schedType = schedType; + this.vmInstanceUuid = vmUuid; + final Pair p = new SQLBatchWithReturn>() { + @Override + protected Pair scripts() { + Tuple t = q(VmInstanceVO.class).eq(VmInstanceVO_.uuid, vmInstanceUuid) + .select(VmInstanceVO_.hostUuid, VmInstanceVO_.lastHostUuid, VmInstanceVO_.zoneUuid) + .findTuple(); + String huuid = t.get(0, String.class); + if (huuid == null) { + huuid = t.get(1, String.class); + } + return new Pair<>(huuid, t.get(2, String.class)); + } + }.execute(); + this.hostUuid = p.first(); + this.zoneUuid = p.second(); + } + + private VmSchedHistoryRecorder(String schedType, VmInstanceInventory vmInv) { + this.schedType = schedType; + this.vmInstanceUuid = vmInv.getUuid(); + this.hostUuid = vmInv.getHostUuid() == null ? vmInv.getLastHostUuid() : vmInv.getHostUuid(); + this.zoneUuid = vmInv.getZoneUuid(); + } + + public VmSchedHistoryRecorder begin() { + String acntUuid = accountManager.getOwnerAccountUuidOfResource(vmInstanceUuid); + vo = new VmSchedHistoryVO(); + vo.setVmInstanceUuid(vmInstanceUuid); + vo.setSchedType(schedType); + vo.setAccountUuid(acntUuid); + vo.setZoneUuid(zoneUuid); + vo.setLastHostUuid(hostUuid); + vo.setSchedReason(schedReason); + vo = dbf.persistAndRefresh(vo); + return this; + } + + public VmSchedHistoryRecorder withSchedReason(String schedReason) { + this.schedReason = schedReason; + return this; + } + + public VmSchedHistoryRecorder withFailReason(String failReason) { + this.failReason = failReason; + return this; + } + + public int end(String currentHostUuid) { + DebugUtils.Assert(this.vo != null, "Recorder not started."); + + return SQL.New(VmSchedHistoryVO.class) + .eq(VmSchedHistoryVO_.id, vo.getId()) + .eq(VmSchedHistoryVO_.vmInstanceUuid, vmInstanceUuid) + .set(VmSchedHistoryVO_.destHostUuid, currentHostUuid) + .set(VmSchedHistoryVO_.success, currentHostUuid != null) + .set(VmSchedHistoryVO_.failReason, failReason) + .update(); + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/VmStartOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmStartOnHypervisorFlow.java index f2ced4d90da..20965f61655 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmStartOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmStartOnHypervisorFlow.java @@ -19,18 +19,14 @@ import java.util.Map; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmStartOnHypervisorFlow implements Flow { - private static CLogger logger = Utils.getLogger(VmStartOnHypervisorFlow.class); + private static final CLogger logger = Utils.getLogger(VmStartOnHypervisorFlow.class); @Autowired private CloudBus bus; @Autowired private PluginRegistry pluginRgty; - private List exts; - - public VmStartOnHypervisorFlow() { - exts = pluginRgty.getExtensionList(VmBeforeStartOnHypervisorExtensionPoint.class); - } + private final List exts = pluginRgty.getExtensionList(VmBeforeStartOnHypervisorExtensionPoint.class);; private void fireExtensions(VmInstanceSpec spec) { for (VmBeforeStartOnHypervisorExtensionPoint ext : exts) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmStopOnHypervisorFlow.java b/compute/src/main/java/org/zstack/compute/vm/VmStopOnHypervisorFlow.java index 3cd962725cd..96120fbb7a5 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmStopOnHypervisorFlow.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmStopOnHypervisorFlow.java @@ -39,6 +39,7 @@ public void run(final FlowTrigger chain, Map data) { } else if (spec.getMessage() instanceof RebootVmInstanceMsg) { msg.setType(((RebootVmInstanceMsg) spec.getMessage()).getType()); } + msg.setDebug(spec.isDebug()); for (BeforeStopVmOnHypervisorExtensionPoint ext : pluginRegistry.getExtensionList(BeforeStopVmOnHypervisorExtensionPoint.class)) { ext.beforeStopVmOnHypervisor(spec, msg); @@ -49,6 +50,7 @@ public void run(final FlowTrigger chain, Map data) { @Override public void run(MessageReply reply) { if (reply.isSuccess()) { + data.put(VmStopOnHypervisorFlow.class.getName(), true); chain.next(); } else { if (spec.isGcOnStopFailure() && reply.getError().isError(HostErrors.OPERATION_FAILURE_GC_ELIGIBLE)) { diff --git a/compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java b/compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java index ce61cd3842b..21c9668175a 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmSystemTags.java @@ -1,10 +1,20 @@ package org.zstack.compute.vm; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.zstack.header.tag.AdminOnlyTag; import org.zstack.header.tag.TagDefinition; import org.zstack.header.vm.VmInstanceVO; import org.zstack.tag.PatternedSystemTag; +import org.zstack.tag.SensitiveTagOutputHandler; import org.zstack.tag.SensitiveTag; import org.zstack.tag.SystemTag; +import org.zstack.utils.YamlUtils; + +import java.util.Base64; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.regex.Pattern; /** */ @@ -13,19 +23,47 @@ public class VmSystemTags { public static String HOSTNAME_TOKEN = "hostname"; public static PatternedSystemTag HOSTNAME = new PatternedSystemTag(String.format("hostname::{%s}", HOSTNAME_TOKEN), VmInstanceVO.class); + public static String SYNC_PORTS_TOKEN = "syncPorts"; + public static PatternedSystemTag SYNC_PORTS = new PatternedSystemTag(String.format("syncPorts::{%s}", SYNC_PORTS_TOKEN), VmInstanceVO.class); + + public static String SYNC_HOSTNAME_TOKEN = "syncHostname"; + public static PatternedSystemTag SYNC_HOSTNAME = new PatternedSystemTag(String.format("syncHostname::{%s}", SYNC_HOSTNAME_TOKEN), VmInstanceVO.class); + public static String STATIC_IP_L3_UUID_TOKEN = "l3NetworkUuid"; public static String STATIC_IP_TOKEN = "staticIp"; public static PatternedSystemTag STATIC_IP = new PatternedSystemTag(String.format("staticIp::{%s}::{%s}", STATIC_IP_L3_UUID_TOKEN, STATIC_IP_TOKEN), VmInstanceVO.class); + public static String IPV4_GATEWAY_L3_UUID_TOKEN = "l3NetworkUuid"; + public static String IPV4_GATEWAY_TOKEN = "ipv4Gateway"; + public static PatternedSystemTag IPV4_GATEWAY = new PatternedSystemTag(String.format("ipv4Gateway::{%s}::{%s}", IPV4_GATEWAY_L3_UUID_TOKEN, IPV4_GATEWAY_TOKEN), VmInstanceVO.class); + + public static String IPV6_GATEWAY_L3_UUID_TOKEN = "l3NetworkUuid"; + public static String IPV6_GATEWAY_TOKEN = "ipv6Gateway"; + public static PatternedSystemTag IPV6_GATEWAY = new PatternedSystemTag(String.format("ipv6Gateway::{%s}::{%s}", IPV6_GATEWAY_L3_UUID_TOKEN, IPV6_GATEWAY_TOKEN), VmInstanceVO.class); + + public static String IPV4_NETMASK_L3_UUID_TOKEN = "l3NetworkUuid"; + public static String IPV4_NETMASK_TOKEN = "ipv4Netmask"; + public static PatternedSystemTag IPV4_NETMASK = new PatternedSystemTag(String.format("ipv4Netmask::{%s}::{%s}", IPV4_NETMASK_L3_UUID_TOKEN, IPV4_NETMASK_TOKEN), VmInstanceVO.class); + + public static String IPV6_PREFIX_L3_UUID_TOKEN = "l3NetworkUuid"; + public static String IPV6_PREFIX_TOKEN = "ipv6Prefix"; + public static PatternedSystemTag IPV6_PREFIX = new PatternedSystemTag(String.format("ipv6Prefix::{%s}::{%s}", IPV6_PREFIX_L3_UUID_TOKEN, IPV6_PREFIX_TOKEN), VmInstanceVO.class); + public static String MAC_TOKEN = "customMac"; public static PatternedSystemTag CUSTOM_MAC = new PatternedSystemTag(String.format("customMac::{%s}::{%s}", STATIC_IP_L3_UUID_TOKEN, MAC_TOKEN), VmInstanceVO.class); + public static String NIC_UUID_TOKEN = "customNicUuid"; + public static PatternedSystemTag CUSTOM_NIC_UUID = new PatternedSystemTag(String.format("customNicUuid::{%s}::{%s}", STATIC_IP_L3_UUID_TOKEN, NIC_UUID_TOKEN), VmInstanceVO.class); + public static PatternedSystemTag WINDOWS_VOLUME_ON_VIRTIO = new PatternedSystemTag("windows::virtioVolume", VmInstanceVO.class); public static String USERDATA_TOKEN = "userdata"; + @SensitiveTag(tokens = {"userdata"}, customizeOutput = UserdataTagOutputHandler.class) public static PatternedSystemTag USERDATA = new PatternedSystemTag(String.format("userdata::{%s}", USERDATA_TOKEN), VmInstanceVO.class); + @Deprecated public static String SSHKEY_TOKEN = "sshkey"; + @Deprecated public static PatternedSystemTag SSHKEY = new PatternedSystemTag(String.format("sshkey::{%s}", SSHKEY_TOKEN), VmInstanceVO.class); public static String ROOT_PASSWORD_TOKEN = "rootPassword"; @@ -39,6 +77,7 @@ public class VmSystemTags { public static PatternedSystemTag ISO = new PatternedSystemTag(String.format("iso::{%s}::{%s}", ISO_TOKEN, ISO_DEVICEID_TOKEN), VmInstanceVO.class); public static String BOOT_ORDER_TOKEN = "bootOrder"; + @AdminOnlyTag public static PatternedSystemTag BOOT_ORDER = new PatternedSystemTag(String.format("bootOrder::{%s}", BOOT_ORDER_TOKEN), VmInstanceVO.class); //this tag is deprecated. @@ -56,6 +95,10 @@ public class VmSystemTags { public static String USB_REDIRECT_TOKEN = "usbRedirect"; public static PatternedSystemTag USB_REDIRECT = new PatternedSystemTag(String.format("usbRedirect::{%s}",USB_REDIRECT_TOKEN),VmInstanceVO.class); + // set securityElementEnable::true to enable se redirect + public static String SECURITY_ELEMENT_ENABLE_TOKEN = "securityElementEnable"; + public static PatternedSystemTag SECURITY_ELEMENT_ENABLE = new PatternedSystemTag(String.format("securityElementEnable::{%s}", SECURITY_ELEMENT_ENABLE_TOKEN),VmInstanceVO.class); + // set rdpEnable::true to enable RDP tag public static String RDP_ENABLE_TOKEN = "RDPEnable"; public static PatternedSystemTag RDP_ENABLE = new PatternedSystemTag(String.format("RDPEnable::{%s}",RDP_ENABLE_TOKEN),VmInstanceVO.class); @@ -92,6 +135,9 @@ public class VmSystemTags { public static String BOOT_VOLUME_TOKEN = "bootVolume"; public static PatternedSystemTag BOOT_VOLUME = new PatternedSystemTag(String.format("bootVolume::{%s}", BOOT_VOLUME_TOKEN), VmInstanceVO.class); + public static String MAX_INSTANCE_PER_HOST_TOKEN = "maxInstancePerHost"; + public static PatternedSystemTag MAX_INSTANCE_PER_HOST = new PatternedSystemTag(String.format("maxInstancePerHost::{%s}", MAX_INSTANCE_PER_HOST_TOKEN), VmInstanceVO.class); + public static PatternedSystemTag ADDITIONAL_QMP_ADDED = new PatternedSystemTag("additionalQmp", VmInstanceVO.class); public static String CLEAN_TRAFFIC_TOKEN = "cleanTraffic"; @@ -113,9 +159,12 @@ public class VmSystemTags { public static String CD_ROM_UUID_TOKEN = "cdromUuid"; public static PatternedSystemTag CD_ROM = new PatternedSystemTag(String.format("cdromUuid::{%s}", CD_ROM_UUID_TOKEN), VmInstanceVO.class); + public static String VM_NIC_MULTIQUEUE_TOKEN = "nicMultiQueueNum"; + public static String VM_NIC_MULTIQUEUE_L3_TOKEN = "l3Uuid"; + public static PatternedSystemTag VM_NIC_MULTIQUEUE = new PatternedSystemTag(String.format("nicMultiQueueNum::{%s}::{%s}", VM_NIC_MULTIQUEUE_L3_TOKEN, VM_NIC_MULTIQUEUE_TOKEN), VmInstanceVO.class); + @Deprecated public static final String V2V_VM_CDROMS_TOKEN = "v2vVmCdroms"; - @Deprecated public static PatternedSystemTag V2V_VM_CDROMS = new PatternedSystemTag( String.format("v2vVmCdroms::{%s}", V2V_VM_CDROMS_TOKEN), VmInstanceVO.class @@ -129,8 +178,7 @@ public class VmSystemTags { public static PatternedSystemTag PACKER_BUILD = new PatternedSystemTag("packer", VmInstanceVO.class); public static final String VM_PRIORITY_TOKEN = "vmPriority"; - public static PatternedSystemTag VM_PRIORITY = new PatternedSystemTag(String.format("vmPriority::{%s}", VM_PRIORITY_TOKEN), VmInstanceVO.class - ); + public static PatternedSystemTag VM_PRIORITY = new PatternedSystemTag(String.format("vmPriority::{%s}", VM_PRIORITY_TOKEN), VmInstanceVO.class); public static String SOUND_TYPE_TOKEN = "soundType"; public static PatternedSystemTag SOUND_TYPE = new PatternedSystemTag(String.format("soundType::{%s}", SOUND_TYPE_TOKEN), VmInstanceVO.class); @@ -147,6 +195,10 @@ public class VmSystemTags { public static PatternedSystemTag VM_GUEST_TOOLS = new PatternedSystemTag(String.format("GuestTools::{%s}", VM_GUEST_TOOLS_VERSION_TOKEN), VmInstanceVO.class); + public static String VM_GUEST_TOOLS_PREVIEW_STATE_TOKEN = "guestToolsPreviewState"; + public static PatternedSystemTag VM_GUEST_TOOLS_PREVIEW_STATE = + new PatternedSystemTag(String.format("GuestToolsPreviewState::{%s}", VM_GUEST_TOOLS_PREVIEW_STATE_TOKEN), VmInstanceVO.class); + public static String VM_RESOURCE_BINGDING_TOKEN = "resourceUUids"; public static PatternedSystemTag VM_RESOURCE_BINGDING = new PatternedSystemTag(String.format("resourceBindings::{%s}", VM_RESOURCE_BINGDING_TOKEN), VmInstanceVO.class); @@ -157,6 +209,8 @@ public class VmSystemTags { public static SystemTag VIRTIO = new SystemTag("driver::virtio", VmInstanceVO.class); + public static SystemTag NUMA = new SystemTag("numa", VmInstanceVO.class); + public static String VM_IP_CHANGED_TOKEN = "ipChanged"; public static PatternedSystemTag VM_IP_CHANGED = new PatternedSystemTag(String.format("ipChanged::{%s}", VM_IP_CHANGED_TOKEN), VmInstanceVO.class); @@ -166,4 +220,94 @@ public class VmSystemTags { public static PatternedSystemTag L3_NETWORK_SECURITY_GROUP_UUIDS_REF = new PatternedSystemTag(String.format("l3::{%s}::SecurityGroupUuids::{%s}", L3_UUID_TOKEN, SECURITY_GROUP_UUIDS_TOKEN), VmInstanceVO.class); + + public static String SECURITY_GROUP_INGRESS_POLICY_TOKEN = "securityGroupIngressPolicy"; + public static String SECURITY_GROUP_EGRESS_POLICY_TOKEN = "securityGroupEgressPolicy"; + public static PatternedSystemTag SECURITY_GROUP_POLICY = + new PatternedSystemTag(String.format("l3::{%s}::securityGroupIngressPolicy::{%s}::securityGroupEgressPolicy::{%s}", + L3_UUID_TOKEN, SECURITY_GROUP_INGRESS_POLICY_TOKEN, SECURITY_GROUP_EGRESS_POLICY_TOKEN), + VmInstanceVO.class); + + public static String DIRECTORY_UUID_TOKEN = "directoryUuid"; + public static PatternedSystemTag DIRECTORY_UUID = new PatternedSystemTag(String.format("directoryUuid::{%s}", DIRECTORY_UUID_TOKEN), VmInstanceVO.class); + + public static String USBDEVICE_UUID_TOKEN = "usbDeviceUuid"; + public static String usbDevice_attach_type_token = "attachType"; + public static PatternedSystemTag VM_ATTACH_USB = new PatternedSystemTag(String.format("usbDeviceUuid::{%s}::attachType::{%s}", + USBDEVICE_UUID_TOKEN, usbDevice_attach_type_token), VmInstanceVO.class); + public static final String XML_HOOK_TOKEN = "xmlHook"; + public static PatternedSystemTag XML_HOOK = new PatternedSystemTag(String.format("xmlHook::{%s}", XML_HOOK_TOKEN), VmInstanceVO.class); + + public static final String MARKET_PLACE_TOKEN = "marketplace::true"; + public static PatternedSystemTag CREATED_BY_MARKETPLACE = new PatternedSystemTag( + MARKET_PLACE_TOKEN, VmInstanceVO.class + ); + + public static class UserdataTagOutputHandler implements SensitiveTagOutputHandler { + private final String chpasswd = "chpasswd"; + private final String list = "list"; + + @Override + public String desensitizeTag(SystemTag systemTag, String tag) { + if (!(systemTag instanceof PatternedSystemTag)) { + return tag; + } + PatternedSystemTag patternedSystemTag = (PatternedSystemTag) systemTag; + + String[] sensitiveTokens = patternedSystemTag.annotation.tokens(); + if (sensitiveTokens == null || sensitiveTokens.length == 0) { + return tag; + } + + Map tokens = patternedSystemTag.getTokensByTag(tag); + if (tokens == null || tokens.isEmpty()) { + return tag; + } + + for (String t : sensitiveTokens) { + String base64Pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$"; + String userdata = tokens.get(t); + if (Pattern.matches(base64Pattern, userdata)) { + userdata = new String(Base64.getDecoder().decode(userdata.getBytes())); + } + + Object obj = YamlUtils.load(userdata); + if (!(obj instanceof LinkedHashMap)) { + return tag; + } + LinkedHashMap userdataMap = (LinkedHashMap) obj; + if (userdataMap.isEmpty()) { + return tag; + } + + Object chpasswdValue = userdataMap.get(chpasswd); + if (!(chpasswdValue instanceof LinkedHashMap)) { + return tag; + } + LinkedHashMap chpasswdMap = (LinkedHashMap) chpasswdValue; + + Object listValue = chpasswdMap.get(list); + if (!(listValue instanceof String) || listValue.equals("")) { + return tag; + } + /* + * #cloud-config + * chpasswd: + * list: | + * root:password ——> *****:***** + * expire: False + * */ + chpasswdMap.replace(list, "*****:*****\n"); + + String maskedUserdata = YamlUtils.dump(userdataMap); + maskedUserdata = "#cloud-config\n" + maskedUserdata; + tokens.put(t, new String(Base64.getEncoder().encode(maskedUserdata.getBytes()))); + } + return patternedSystemTag.instantiateTag(tokens); + } + } + + public static PatternedSystemTag VM_STATE_PAUSED_AFTER_MIGRATE = new PatternedSystemTag(("vmPausedAfterMigrate"), VmInstanceVO.class); + + public static PatternedSystemTag VM_MEMORY_ACCESS_MODE_SHARED = new PatternedSystemTag(("vmMemoryAccessModeShared"), VmInstanceVO.class); } diff --git a/compute/src/main/java/org/zstack/compute/vm/VmTracer.java b/compute/src/main/java/org/zstack/compute/vm/VmTracer.java index 2fb2090792f..e76ee3da398 100755 --- a/compute/src/main/java/org/zstack/compute/vm/VmTracer.java +++ b/compute/src/main/java/org/zstack/compute/vm/VmTracer.java @@ -88,7 +88,9 @@ private void handleAnonymousVm(final String vmUuid, final VmInstanceState actual logger.debug(String.format("[Vm Tracer] detects stranger vm[identity:%s, state:%s]", vmUuid, actualState)); String cachedHostUuid = strangeVms.get(vmUuid); - if (cachedHostUuid != null) { + // only report stranger vm once for each host + // but if hostUuid changed, report it again + if (cachedHostUuid != null && cachedHostUuid.equals(hostUuid)) { logger.debug(String.format("[Vm Tracer] detects stranger vm[identity:%s, state:%s] but it's already in cache, skip firing event", vmUuid, actualState)); return; } @@ -179,7 +181,11 @@ protected void reportVmState(final String hostUuid, final Map deleteVmDeviceAddress(vmNic.getUuid(), vmInstanceUuid)); + inventory.getAllVolumes().forEach(volume -> deleteVmDeviceAddress(volume.getUuid(), vmInstanceUuid)); + return null; + } + + @Override + public VmInstanceDeviceAddressGroupVO archiveCurrentDeviceAddress(String vmInstanceUuid, String archiveForResourceUuid) { + if (deviceAddressRecordingDisabled()) { + return null; + } + + return new SQLBatchWithReturn() { + @Override + protected VmInstanceDeviceAddressGroupVO scripts() { + List deviceAddressVOList = q(VmInstanceDeviceAddressVO.class) + .eq(VmInstanceDeviceAddressVO_.vmInstanceUuid, vmInstanceUuid) + .list(); + + VmInstanceDeviceAddressGroupVO group = new VmInstanceDeviceAddressGroupVO(); + group.setResourceUuid(archiveForResourceUuid); + group.setUuid(Platform.getUuid()); + group.setVmInstanceUuid(vmInstanceUuid); + group = persist(group); + + for (VmInstanceDeviceAddressVO vo : deviceAddressVOList) { + VmInstanceDeviceAddressArchiveVO archiveVO = new VmInstanceDeviceAddressArchiveVO(); + archiveVO.setDeviceAddress(vo.getDeviceAddress()); + archiveVO.setResourceUuid(vo.getResourceUuid()); + archiveVO.setVmInstanceUuid(vmInstanceUuid); + archiveVO.setAddressGroupUuid(group.getUuid()); + archiveVO.setMetadata(vo.getMetadata()); + archiveVO.setMetadataClass(vo.getMetadataClass()); + persist(archiveVO); + } + + return reload(group); + } + }.execute(); + } + + @Override + public List revertDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid) { + if (deviceAddressRecordingDisabled()) { + return Collections.emptyList(); + } + + VmInstanceDeviceAddressGroupVO group = Q.New(VmInstanceDeviceAddressGroupVO.class) + .eq(VmInstanceDeviceAddressGroupVO_.resourceUuid, archiveForResourceUuid) + .find(); + + List createdAddressList = new ArrayList<>(); + if (group == null) { + return createdAddressList; + } + + for (VmInstanceDeviceAddressArchiveVO archive : group.getAddressList()) { + VmInstanceDeviceAddressVO vo = createOrUpdateVmDeviceAddress(archive.getResourceUuid(), DeviceAddress.fromString(archive.getDeviceAddress()), vmInstanceUuid, archive.getMetadata(), archive.getMetadataClass()); + createdAddressList.add(vo); + } + + return createdAddressList; + } + + @Override + public List revertExistingDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid) { + VmInstanceDeviceAddressGroupVO group = Q.New(VmInstanceDeviceAddressGroupVO.class) + .eq(VmInstanceDeviceAddressGroupVO_.resourceUuid, archiveForResourceUuid) + .find(); + + List createdAddressList = new ArrayList<>(); + if (group == null) { + return createdAddressList; + } + + for (VmInstanceDeviceAddressArchiveVO archive : group.getAddressList()) { + if (!vmDeviceExists(archive.getResourceUuid())) { + continue; + } + + VmInstanceDeviceAddressVO vo = createOrUpdateVmDeviceAddress(archive.getResourceUuid(), DeviceAddress.fromString(archive.getDeviceAddress()), vmInstanceUuid, archive.getMetadata(), archive.getMetadataClass()); + createdAddressList.add(vo); + } + + return createdAddressList; + } + + @Override + public List revertRequestedDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid, List needRevertResourceUuidList) { + VmInstanceDeviceAddressGroupVO group = Q.New(VmInstanceDeviceAddressGroupVO.class) + .eq(VmInstanceDeviceAddressGroupVO_.resourceUuid, archiveForResourceUuid) + .find(); + + List createdAddressList = new ArrayList<>(); + if (group == null) { + return createdAddressList; + } + + for (VmInstanceDeviceAddressArchiveVO archive : group.getAddressList()) { + if (!needRevertResourceUuidList.contains(archive.getResourceUuid())) { + continue; + } + + VmInstanceDeviceAddressVO vo = createOrUpdateVmDeviceAddress(archive.getResourceUuid(), DeviceAddress.fromString(archive.getDeviceAddress()), vmInstanceUuid, archive.getMetadata(), archive.getMetadataClass()); + createdAddressList.add(vo); + } + + return createdAddressList; + } + + @Override + public List createDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid, Map resourceMap) { + if (deviceAddressRecordingDisabled()) { + return Collections.emptyList(); + } + + VmInstanceDeviceAddressGroupVO group = Q.New(VmInstanceDeviceAddressGroupVO.class) + .eq(VmInstanceDeviceAddressGroupVO_.resourceUuid, archiveForResourceUuid) + .find(); + + List createdAddressList = new ArrayList<>(); + if (group == null) { + return createdAddressList; + } + + for (VmInstanceDeviceAddressArchiveVO archive : group.getAddressList()) { + String matchedResourceUuid = resourceMap.get(archive.getResourceUuid()); + + // create device address request new resourceUuid if not found skip pci address create + if (matchedResourceUuid == null) { + continue; + } + + VmInstanceDeviceAddressVO vo = createOrUpdateVmDeviceAddress(matchedResourceUuid, DeviceAddress.fromString(archive.getDeviceAddress()), vmInstanceUuid, archive.getMetadata(), archive.getMetadataClass()); + createdAddressList.add(vo); + } + + return createdAddressList; + } + + @Override + public void deleteArchiveVmInstanceDeviceAddressGroup(String archiveForResourceUuid) { + SQL.New(VmInstanceDeviceAddressGroupVO.class).eq(VmInstanceDeviceAddressGroupVO_.resourceUuid, archiveForResourceUuid).hardDelete(); + } + + @Override + public List getAddressArchiveInfoFromArchiveForResourceUuid(String vmInstanceUuid, String archiveForResourceUuid, String metadataClass) { + if (deviceAddressRecordingDisabled()) { + return Collections.emptyList(); + } + + String VmInstanceDeviceAddressGroupUuid = Q.New(VmInstanceDeviceAddressGroupVO.class) + .select(VmInstanceDeviceAddressGroupVO_.uuid) + .eq(VmInstanceDeviceAddressGroupVO_.resourceUuid, archiveForResourceUuid) + .findValue(); + + if (VmInstanceDeviceAddressGroupUuid == null) { + return new ArrayList<>(); + } + + return Q.New(VmInstanceDeviceAddressArchiveVO.class) + .eq(VmInstanceDeviceAddressArchiveVO_.addressGroupUuid, VmInstanceDeviceAddressGroupUuid) + .eq(VmInstanceDeviceAddressArchiveVO_.vmInstanceUuid, vmInstanceUuid) + .eq(VmInstanceDeviceAddressArchiveVO_.metadataClass, metadataClass) + .list(); + } + + private boolean vmExists(String vmInstanceUuid) { + return dbf.isExist(vmInstanceUuid, VmInstanceVO.class); + } + + private boolean vmDeviceExists(String resourceUuid) { + return new SQLBatchWithReturn() { + + @Override + protected Boolean scripts() { + boolean volumeExists = q(VolumeVO.class).eq(VolumeVO_.uuid, resourceUuid).isExists(); + boolean nicExists = q(VmNicVO.class).eq(VmNicVO_.uuid, resourceUuid).isExists(); + boolean cdRomExists = q(VmCdRomVO.class).eq(VmCdRomVO_.uuid, resourceUuid).isExists(); + + return volumeExists || nicExists || cdRomExists || vmExists(resourceUuid); + } + }.execute(); + } + + private ErrorCode checkParams(String vmInstanceUuid, String resourceUuid) { + if (MEM_BALLOON_UUID.equals(resourceUuid)) { + return null; + } + + if (RESOURCE_CONFIG_UUID.equals(resourceUuid)) { + return null; + } + + if (!vmExists(vmInstanceUuid)) { + return operr("cannot find vm with uuid: %s", vmInstanceUuid); + } + + if (!vmDeviceExists(resourceUuid)) { + return operr("cannot find vm device with uuid: %s", resourceUuid); + } + + return null; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/quota/DataVolumeNumQuotaDefinition.java b/compute/src/main/java/org/zstack/compute/vm/quota/DataVolumeNumQuotaDefinition.java new file mode 100644 index 00000000000..786ad485017 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/quota/DataVolumeNumQuotaDefinition.java @@ -0,0 +1,39 @@ +package org.zstack.compute.vm.quota; + +import org.zstack.compute.vm.VmQuotaConstant; +import org.zstack.compute.vm.VmQuotaGlobalConfig; +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.volume.VolumeStatus; +import org.zstack.header.volume.VolumeType; +import org.zstack.header.volume.VolumeVO; + +public class DataVolumeNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VmQuotaConstant.DATA_VOLUME_NUM; + } + + @Override + public Long getDefaultValue() { + return VmQuotaGlobalConfig.DATA_VOLUME_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(vol)" + + " from VolumeVO vol, AccountResourceRefVO ref " + + " where vol.type = :vtype" + + " and ref.resourceUuid = vol.uuid " + + " and ref.accountUuid = :auuid" + + " and ref.resourceType = :rtype" + + " and vol.status != :status "; + Long used = SQL.New(sql, Long.class) + .param("auuid", accountUuid) + .param("rtype", VolumeVO.class.getSimpleName()) + .param("vtype", VolumeType.Data) + .param("status", VolumeStatus.Deleted) + .find(); + return used == null ? 0L : used; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningCpuNumQuotaDefinition.java b/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningCpuNumQuotaDefinition.java new file mode 100644 index 00000000000..4b1f111c9b9 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningCpuNumQuotaDefinition.java @@ -0,0 +1,44 @@ +package org.zstack.compute.vm.quota; + +import org.zstack.compute.vm.VmQuotaConstant; +import org.zstack.compute.vm.VmQuotaGlobalConfig; +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.VmInstanceVO; + +import static org.zstack.utils.CollectionDSL.list; + +public class VmRunningCpuNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VmQuotaConstant.VM_RUNNING_CPU_NUM; + } + + @Override + public Long getDefaultValue() { + return VmQuotaGlobalConfig.VM_RUNNING_CPU_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select sum(vm.cpuNum)" + + " from VmInstanceVO vm, AccountResourceRefVO ref" + + " where vm.uuid = ref.resourceUuid" + + " and ref.accountUuid = :auuid" + + " and ref.resourceType = :rtype" + + " and not (vm.state = :starting and vm.hostUuid is null)" + + " and vm.state not in (:states)" + + " and vm.type != :vmtype"; + + Long used = SQL.New(sql, Long.class) + .param("auuid", accountUuid) + .param("rtype", VmInstanceVO.class.getSimpleName()) + .param("starting", VmInstanceState.Starting) + .param("states", list(VmInstanceState.Stopped, VmInstanceState.Destroying, + VmInstanceState.Destroyed, VmInstanceState.Created)) + .param("vmtype", "baremetal2") + .find(); + return used == null ? 0L : used; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningMemoryNumQuotaDefinition.java b/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningMemoryNumQuotaDefinition.java new file mode 100644 index 00000000000..2945d2a0ead --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningMemoryNumQuotaDefinition.java @@ -0,0 +1,45 @@ +package org.zstack.compute.vm.quota; + +import org.zstack.compute.vm.VmQuotaConstant; +import org.zstack.compute.vm.VmQuotaGlobalConfig; +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.VmInstanceVO; + +import static org.zstack.utils.CollectionDSL.list; + +public class VmRunningMemoryNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VmQuotaConstant.VM_RUNNING_MEMORY_SIZE; + } + + @Override + public Long getDefaultValue() { + return VmQuotaGlobalConfig.VM_RUNNING_MEMORY_SIZE.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select sum(vm.memorySize)" + + " from VmInstanceVO vm, AccountResourceRefVO ref" + + " where vm.uuid = ref.resourceUuid" + + " and ref.accountUuid = :auuid" + + " and ref.resourceType = :rtype" + + " and not (vm.state = :starting and vm.hostUuid is null)" + + " and vm.state not in (:states)" + + " and vm.type != :vmtype"; + + Long used = SQL.New(sql, Long.class) + .param("auuid", accountUuid) + .param("rtype", VmInstanceVO.class.getSimpleName()) + .param("starting", VmInstanceState.Starting) + .param("states", list(VmInstanceState.Stopped, VmInstanceState.Destroying, + VmInstanceState.Destroyed, VmInstanceState.Created)) + .param("vmtype", "baremetal2") + .find(); + return used == null ? 0L : used; + } +} + diff --git a/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningNumQuotaDefinition.java b/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningNumQuotaDefinition.java new file mode 100644 index 00000000000..9f5c3b65a97 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/quota/VmRunningNumQuotaDefinition.java @@ -0,0 +1,44 @@ +package org.zstack.compute.vm.quota; + +import org.zstack.compute.vm.VmQuotaConstant; +import org.zstack.compute.vm.VmQuotaGlobalConfig; +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.VmInstanceVO; + +import static org.zstack.utils.CollectionDSL.list; + +public class VmRunningNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VmQuotaConstant.VM_RUNNING_NUM; + } + + @Override + public Long getDefaultValue() { + return VmQuotaGlobalConfig.VM_RUNNING_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(vm)" + + " from VmInstanceVO vm, AccountResourceRefVO ref" + + " where vm.uuid = ref.resourceUuid" + + " and ref.accountUuid = :auuid" + + " and ref.resourceType = :rtype" + + " and not (vm.state = :starting and vm.hostUuid is null)" + + " and vm.state not in (:states)" + + " and vm.type != :vmtype"; + + Long used = SQL.New(sql, Long.class) + .param("auuid", accountUuid) + .param("rtype", VmInstanceVO.class.getSimpleName()) + .param("starting", VmInstanceState.Starting) + .param("states", list(VmInstanceState.Stopped, VmInstanceState.Destroying, + VmInstanceState.Destroyed, VmInstanceState.Created)) + .param("vmtype", "baremetal2") + .find(); + return used == null ? 0L : used; + } +} \ No newline at end of file diff --git a/compute/src/main/java/org/zstack/compute/vm/quota/VmTotalNumQuotaDefinition.java b/compute/src/main/java/org/zstack/compute/vm/quota/VmTotalNumQuotaDefinition.java new file mode 100644 index 00000000000..1c982e3cd43 --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/quota/VmTotalNumQuotaDefinition.java @@ -0,0 +1,42 @@ +package org.zstack.compute.vm.quota; + +import org.zstack.compute.vm.VmQuotaConstant; +import org.zstack.compute.vm.VmQuotaGlobalConfig; +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.VmInstanceVO; + +import static org.zstack.utils.CollectionDSL.list; + +public class VmTotalNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VmQuotaConstant.VM_TOTAL_NUM; + } + + @Override + public Long getDefaultValue() { + return VmQuotaGlobalConfig.VM_TOTAL_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(vm)" + + " from VmInstanceVO vm, AccountResourceRefVO ref" + + " where vm.uuid = ref.resourceUuid" + + " and ref.accountUuid = :auuid" + + " and ref.resourceType = :rtype" + + " and not (vm.hostUuid is null and vm.lastHostUuid is null and vm.rootVolumeUuid is null)" + + " and vm.state not in (:states)" + + " and vm.type != :vmtype"; + + Long used = SQL.New(sql, Long.class) + .param("auuid", accountUuid) + .param("rtype", VmInstanceVO.class.getSimpleName()) + .param("states", list(VmInstanceState.Destroyed)) + .param("vmtype", "baremetal2") + .find(); + return used == null ? 0L : used; + } +} diff --git a/compute/src/main/java/org/zstack/compute/vm/quota/VolumeSizeQuotaDefinition.java b/compute/src/main/java/org/zstack/compute/vm/quota/VolumeSizeQuotaDefinition.java new file mode 100644 index 00000000000..689ae9e797e --- /dev/null +++ b/compute/src/main/java/org/zstack/compute/vm/quota/VolumeSizeQuotaDefinition.java @@ -0,0 +1,33 @@ +package org.zstack.compute.vm.quota; + +import org.zstack.compute.vm.VmQuotaConstant; +import org.zstack.compute.vm.VmQuotaGlobalConfig; +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.volume.VolumeVO; + +public class VolumeSizeQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VmQuotaConstant.VOLUME_SIZE; + } + + @Override + public Long getDefaultValue() { + return VmQuotaGlobalConfig.VOLUME_SIZE.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select sum(vol.size)" + + " from VolumeVO vol, AccountResourceRefVO ref" + + " where ref.resourceUuid = vol.uuid" + + " and ref.accountUuid = :auuid" + + " and ref.resourceType = :rtype"; + Long used = SQL.New(sql, Long.class) + .param("auuid", accountUuid) + .param("rtype", VolumeVO.class.getSimpleName()) + .find(); + return used == null ? 0L : used; + } +} \ No newline at end of file diff --git a/compute/src/main/java/org/zstack/compute/zone/BaseZoneFactory.java b/compute/src/main/java/org/zstack/compute/zone/BaseZoneFactory.java index ba2ab032d66..8b653611b4c 100755 --- a/compute/src/main/java/org/zstack/compute/zone/BaseZoneFactory.java +++ b/compute/src/main/java/org/zstack/compute/zone/BaseZoneFactory.java @@ -21,7 +21,6 @@ public ZoneType getType() { @Override public ZoneVO createZone(ZoneVO vo, APICreateZoneMsg msg) { vo.setType(type.toString()); - vo = dbf.persistAndRefresh(vo); return vo; } diff --git a/compute/src/main/java/org/zstack/compute/zone/ZoneBase.java b/compute/src/main/java/org/zstack/compute/zone/ZoneBase.java index 204cc5c08b5..378aa44ac94 100755 --- a/compute/src/main/java/org/zstack/compute/zone/ZoneBase.java +++ b/compute/src/main/java/org/zstack/compute/zone/ZoneBase.java @@ -7,8 +7,13 @@ import org.zstack.core.cascade.CascadeFacade; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SQL; +import org.zstack.core.db.SQLBatch; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.job.JobQueueFacade; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.core.Completion; import org.zstack.header.core.NopeCompletion; @@ -47,6 +52,8 @@ public class ZoneBase extends AbstractZone { protected CascadeFacade casf; @Autowired protected ErrorFacade errf; + @Autowired + protected ThreadFacade thdf; ZoneBase(ZoneVO self) { this.self = self; @@ -87,23 +94,82 @@ protected void handleApiMessage(APIMessage msg) { } } - private void handle(APIUpdateZoneMsg msg) { - boolean update = false; - if (msg.getName() != null) { - self.setName(msg.getName()); - update = true; - } - if (msg.getDescription() != null) { - self.setDescription(msg.getDescription()); - update = true; - } - if (update) { - self = dbf.updateAndRefresh(self); + private void doUpdateZone(APIUpdateZoneMsg msg) { + new SQLBatch() { + @Override + protected void scripts() { + boolean update = false; + + if (msg.getName() != null) { + self.setName(msg.getName()); + update = true; + } + if (msg.getDescription() != null) { + self.setDescription(msg.getDescription()); + update = true; + } + if (msg.getDefault() != null) { + if (msg.getDefault()) { + sql(ZoneVO.class) + .notEq(ZoneVO_.uuid, self.getUuid()) + .set(ZoneVO_.isDefault, false) + .update(); + } + + self.setDefault(msg.getDefault()); + update = true; + } + + if (update) { + reload(merge(self)); + } + } + }.execute(); + } + + private void updateZone(APIUpdateZoneMsg msg, Completion completion) { + if (msg.getDefault() == null || !msg.getDefault()) { + doUpdateZone(msg); + completion.success(); + return; } + // queue default zone operation + thdf.chainSubmit(new ChainTask(completion) { + @Override + public String getSyncSignature() { + return "default-zone-operation-queue"; + } + + @Override + public void run(SyncTaskChain chain) { + doUpdateZone(msg); + completion.success(); + chain.next(); + } + + @Override + public String getName() { + return String.format("update-zone-%s", self.getUuid()); + } + }); + } + + private void handle(APIUpdateZoneMsg msg) { APIUpdateZoneEvent evt = new APIUpdateZoneEvent(msg.getId()); - evt.setInventory(ZoneInventory.valueOf(self)); - bus.publish(evt); + updateZone(msg, new Completion(msg) { + @Override + public void success() { + evt.setInventory(ZoneInventory.valueOf(self)); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } protected void handle(APIDeleteZoneMsg msg) { diff --git a/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java b/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java index 03ae165724c..794c34a92fa 100755 --- a/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java +++ b/compute/src/main/java/org/zstack/compute/zone/ZoneManagerImpl.java @@ -7,8 +7,14 @@ import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.DbEntityLister; +import org.zstack.core.db.SQL; +import org.zstack.core.db.SQLBatch; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; import org.zstack.header.AbstractService; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; @@ -42,6 +48,8 @@ public class ZoneManagerImpl extends AbstractService implements ZoneManager { private ErrorFacade errf; @Autowired private TagManager tagMgr; + @Autowired + private ThreadFacade thdf; private Map zoneFactories = Collections.synchronizedMap(new HashMap()); private static final Set allowedMessageAfterSoftDeletion = new HashSet(); @@ -110,13 +118,12 @@ private void passThrough(ZoneMessage msg) { zone.handleMessage((Message)msg); } - private void handle(APICreateZoneMsg msg) { + private ZoneInventory createZoneFromApiMessage(APICreateZoneMsg msg) { String zoneType = msg.getType(); if (zoneType == null) { zoneType = BaseZoneFactory.type.toString(); } ZoneFactory factory = this.getZoneFactory(ZoneType.valueOf(zoneType)); - APICreateZoneEvent evt = new APICreateZoneEvent(msg.getId()); ZoneVO vo = new ZoneVO(); if (msg.getResourceUuid() != null) { vo.setUuid(msg.getResourceUuid()); @@ -125,13 +132,77 @@ private void handle(APICreateZoneMsg msg) { } vo.setName(msg.getName()); vo.setDescription(msg.getDescription()); - vo = factory.createZone(vo, msg); - tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), ZoneVO.class.getSimpleName()); + if (msg.getDefault() != null) { + vo.setDefault(msg.getDefault()); + } else { + vo.setDefault(false); + } + + final ZoneVO finalVO = factory.createZone(vo, msg); + new SQLBatch() { + @Override + protected void scripts() { + if (finalVO.isDefault()) { + sql(ZoneVO.class) + .set(ZoneVO_.isDefault, false) + .update(); + } + + persist(finalVO); + reload(finalVO); + } + }.execute(); + + tagMgr.createTagsFromAPICreateMessage(msg, finalVO.getUuid(), ZoneVO.class.getSimpleName()); + + return ZoneInventory.valueOf(finalVO); + } + + private void createZone(APICreateZoneMsg msg, ReturnValueCompletion completion) { + if (msg.getDefault() == null || !msg.getDefault()) { + completion.success(createZoneFromApiMessage(msg)); + return; + } - evt.setInventory(ZoneInventory.valueOf(vo)); - logger.debug("Created zone: " + vo.getName() + " uuid:" + vo.getUuid()); - bus.publish(evt); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return "default-zone-operation-queue"; + } + + @Override + public void run(SyncTaskChain chain) { + completion.success(createZoneFromApiMessage(msg)); + chain.next(); + } + + @Override + public String getName() { + return "create-zone"; + } + }); + } + + private void handle(APICreateZoneMsg msg) { + APICreateZoneEvent evt = new APICreateZoneEvent(msg.getId()); + createZone(msg, new ReturnValueCompletion(msg) { + @Override + public void success(ZoneInventory returnValue) { + evt.setInventory(returnValue); + logger.debug(String.format("Created zone: %s uuid: %s", + evt.getInventory().getName(), + evt.getInventory().getUuid()) + ); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } @Override diff --git a/compute/src/main/java/org/zstack/header/vm/SshKeyPairAssociateExtensionPoint.java b/compute/src/main/java/org/zstack/header/vm/SshKeyPairAssociateExtensionPoint.java new file mode 100644 index 00000000000..a20c7cb8d92 --- /dev/null +++ b/compute/src/main/java/org/zstack/header/vm/SshKeyPairAssociateExtensionPoint.java @@ -0,0 +1,13 @@ +package org.zstack.header.vm; + +import org.zstack.header.errorcode.ErrorCode; + +import java.util.List; + +public interface SshKeyPairAssociateExtensionPoint { + ErrorCode associateSshKeyPair(String vmUuid, List keyPairUuids); + + List fetchAssociatedSshKeyPairs(String vmUuid); + + void cloneSshKeyPairsToVm(String originVmUuid, String destVmUuid); +} diff --git a/conf/db/V0.6__schema.sql b/conf/db/V0.6__schema.sql index 87d0461af1e..7e956f3d195 100755 --- a/conf/db/V0.6__schema.sql +++ b/conf/db/V0.6__schema.sql @@ -1327,7 +1327,7 @@ CREATE INDEX idxZoneEOname ON ZoneEO (name); CREATE VIEW `zstack`.`VmInstanceVO` AS SELECT uuid, name, description, zoneUuid, clusterUuid, imageUuid, hostUuid, internalId, lastHostUuid, instanceOfferingUuid, rootVolumeUuid, defaultL3NetworkUuid, type, hypervisorType, cpuNum, cpuSpeed, memorySize, allocatorStrategy, createDate, lastOpDate, state FROM `zstack`.`VmInstanceEO` WHERE deleted IS NULL; -CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, md5Sum, platform, type, format, url, system, mediaType, createDate, lastOpDate, guestOsType FROM `zstack`.`ImageEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, md5Sum, platform, type, format, url, `system`, mediaType, createDate, lastOpDate, guestOsType FROM `zstack`.`ImageEO` WHERE deleted IS NULL; CREATE VIEW `zstack`.`VolumeVO` AS SELECT uuid, name, description, primaryStorageUuid, vmInstanceUuid, diskOfferingUuid, rootImageUuid, installPath, type, status, size, deviceId, format, state, createDate, lastOpDate FROM `zstack`.`VolumeEO` WHERE deleted IS NULL; @@ -1343,7 +1343,7 @@ CREATE VIEW `zstack`.`VolumeSnapshotTreeVO` AS SELECT uuid, volumeUuid, current, CREATE VIEW `zstack`.`BackupStorageVO` AS SELECT uuid, name, url, description, totalCapacity, availableCapacity, type, state, status, createDate, lastOpDate FROM `zstack`.`BackupStorageEO` WHERE deleted IS NULL; -CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, system, dnsDomain, createDate, lastOpDate FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, `system`, dnsDomain, createDate, lastOpDate FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; CREATE VIEW `zstack`.`IpRangeVO` AS SELECT uuid, l3NetworkUuid, name, description, startIp, endIp, netmask, gateway, networkCidr, createDate, lastOpDate FROM `zstack`.`IpRangeEO` WHERE deleted IS NULL; diff --git a/conf/db/upgrade/V1.3__schema.sql b/conf/db/upgrade/V1.3__schema.sql index 33bb3a47ce2..54afa7d0b55 100755 --- a/conf/db/upgrade/V1.3__schema.sql +++ b/conf/db/upgrade/V1.3__schema.sql @@ -70,7 +70,7 @@ ALTER TABLE FusionstorPrimaryStorageVO ADD CONSTRAINT fkFusionstorPrimaryStorage ALTER TABLE ImageEO ADD actualSize bigint unsigned DEFAULT NULL; DROP VIEW IF EXISTS `zstack`.`ImageVO`; -CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, actualSize, md5Sum, platform, type, format, url, system, mediaType, createDate, lastOpDate, guestOsType FROM `zstack`.`ImageEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, actualSize, md5Sum, platform, type, format, url, `system`, mediaType, createDate, lastOpDate, guestOsType FROM `zstack`.`ImageEO` WHERE deleted IS NULL; UPDATE ImageEO set actualSize = size; ALTER TABLE VolumeEO ADD actualSize bigint unsigned DEFAULT NULL; diff --git a/conf/db/upgrade/V1.7__schema.sql b/conf/db/upgrade/V1.7__schema.sql index 2eadc6e4b7d..a6fc8b56c0f 100644 --- a/conf/db/upgrade/V1.7__schema.sql +++ b/conf/db/upgrade/V1.7__schema.sql @@ -5,7 +5,7 @@ ALTER TABLE `zstack`.`ImageEO` modify column description varchar(2048) DEFAULT N ALTER TABLE `zstack`.`ImageEO` add column exportUrl varchar(2048) DEFAULT NULL COMMENT 'exported image URL'; DROP VIEW IF EXISTS `zstack`.`ImageVO`; -CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, actualSize, md5Sum, platform, type, format, url, system, mediaType, createDate, lastOpDate, guestOsType, exportUrl FROM `zstack`.`ImageEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, actualSize, md5Sum, platform, type, format, url, `system`, mediaType, createDate, lastOpDate, guestOsType, exportUrl FROM `zstack`.`ImageEO` WHERE deleted IS NULL; ALTER TABLE `zstack`.`InstanceOfferingEO` modify column description varchar(2048) DEFAULT NULL COMMENT 'instance offering description'; ALTER TABLE `zstack`.`DiskOfferingEO` modify column description varchar(2048) DEFAULT NULL COMMENT 'disk offering description'; diff --git a/conf/db/upgrade/V2.1.0__schema.sql b/conf/db/upgrade/V2.1.0__schema.sql index edb0e637067..4938319b066 100755 --- a/conf/db/upgrade/V2.1.0__schema.sql +++ b/conf/db/upgrade/V2.1.0__schema.sql @@ -395,7 +395,7 @@ SET FOREIGN_KEY_CHECKS = 1; ALTER TABLE `zstack`.`ImageEO` ADD COLUMN exportMd5Sum varchar(255) DEFAULT NULL; DROP VIEW IF EXISTS `zstack`.`ImageVO`; -CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, actualSize, md5Sum, exportMd5Sum, platform, type, format, url, system, mediaType, createDate, lastOpDate, guestOsType, exportUrl FROM `zstack`.`ImageEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`ImageVO` AS SELECT uuid, name, description, status, state, size, actualSize, md5Sum, exportMd5Sum, platform, type, format, url, `system`, mediaType, createDate, lastOpDate, guestOsType, exportUrl FROM `zstack`.`ImageEO` WHERE deleted IS NULL; ALTER TABLE HostCapacityVO MODIFY availableCpu bigint(20) NOT NULL COMMENT 'used cpu of host in HZ'; diff --git a/conf/db/upgrade/V2.2.0__schema.sql b/conf/db/upgrade/V2.2.0__schema.sql index 624caf6dbc0..15238f7bdf9 100644 --- a/conf/db/upgrade/V2.2.0__schema.sql +++ b/conf/db/upgrade/V2.2.0__schema.sql @@ -1,7 +1,7 @@ ALTER TABLE `L3NetworkEO` ADD COLUMN `category` varchar(255) NOT NULL DEFAULT 'Private' COMMENT 'the type network used for'; DROP VIEW IF EXISTS `zstack`.`L3NetworkVO`; -CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, system, dnsDomain, createDate, lastOpDate, category FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, `system`, dnsDomain, createDate, lastOpDate, category FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; # add network category for ZSTAC-6844 DELIMITER $$ @@ -10,7 +10,7 @@ CREATE PROCEDURE generateNetworkCategory() DECLARE l3Uuid varchar(32); DECLARE l3System tinyint(3) unsigned; DECLARE done INT DEFAULT FALSE; - DECLARE cur CURSOR FOR SELECT uuid, system FROM zstack.L3NetworkEO; + DECLARE cur CURSOR FOR SELECT uuid, `system` FROM zstack.L3NetworkEO; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP @@ -21,7 +21,7 @@ CREATE PROCEDURE generateNetworkCategory() IF l3System = 1 THEN - UPDATE zstack.L3NetworkEO SET system = 0 WHERE uuid = l3Uuid; + UPDATE zstack.L3NetworkEO SET `system` = 0 WHERE uuid = l3Uuid; UPDATE zstack.L3NetworkEO SET category = 'Public' WHERE uuid = l3Uuid; ELSE UPDATE zstack.L3NetworkEO SET category = 'Private' WHERE uuid = l3Uuid; diff --git a/conf/db/upgrade/V3.1.0__schema.sql b/conf/db/upgrade/V3.1.0__schema.sql index 40311d767f4..26df49be25c 100644 --- a/conf/db/upgrade/V3.1.0__schema.sql +++ b/conf/db/upgrade/V3.1.0__schema.sql @@ -208,7 +208,7 @@ ALTER TABLE `zstack`.`UsedIpVO` ADD CONSTRAINT fkUsedIpVOVmNicVO FOREIGN KEY (vm ALTER TABLE `zstack`.`L3NetworkEO` ADD COLUMN `ipVersion` int(10) unsigned DEFAULT 4; DROP VIEW IF EXISTS `zstack`.`L3NetworkVO`; -CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, system, dnsDomain, createDate, lastOpDate, category, ipVersion FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; +CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, `system`, dnsDomain, createDate, lastOpDate, category, ipVersion FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; ALTER TABLE `zstack`.`VmNicVO` ADD COLUMN `ipVersion` int(10) unsigned DEFAULT 4; diff --git a/conf/db/upgrade/V4.3.25__schema.sql b/conf/db/upgrade/V4.3.25__schema.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/conf/db/upgrade/V4.3.28__schema.sql b/conf/db/upgrade/V4.3.28__schema.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/conf/db/upgrade/V4.3.35__schema.sql b/conf/db/upgrade/V4.3.35__schema.sql new file mode 100644 index 00000000000..1e138fca6c2 --- /dev/null +++ b/conf/db/upgrade/V4.3.35__schema.sql @@ -0,0 +1,8 @@ +ALTER TABLE `zstack`.`HostNumaNodeVO` DROP FOREIGN KEY `HostNumaNodeVO_HostEO_uuid_fk`; +ALTER TABLE `zstack`.`HostNumaNodeVO` ADD CONSTRAINT `HostNumaNodeVO_HostEO_uuid_fk` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE ; + +ALTER TABLE `zstack`.`VmInstanceNumaNodeVO` DROP FOREIGN KEY `VmInstanceNumaNodeVO_VmInstanceEO_uuid_fk`; +ALTER TABLE `zstack`.`VmInstanceNumaNodeVO` ADD CONSTRAINT `VmInstanceNumaNodeVO_VmInstanceEO_uuid_fk` FOREIGN KEY (`vmUuid`) REFERENCES `VmInstanceEO` (`uuid`) ON DELETE CASCADE ; + +ALTER TABLE `zstack`.`HostAllocatedCpuVO` DROP FOREIGN KEY `HostAllocatedCpuVO_HostEO_uuid_fk`; +ALTER TABLE `zstack`.`HostAllocatedCpuVO` ADD CONSTRAINT `HostAllocatedCpuVO_HostEO_uuid_fk` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE ; \ No newline at end of file diff --git a/conf/db/upgrade/V4.3.8.0.10__schema.sql b/conf/db/upgrade/V4.3.8.0.10__schema.sql new file mode 100644 index 00000000000..b6d24791f02 --- /dev/null +++ b/conf/db/upgrade/V4.3.8.0.10__schema.sql @@ -0,0 +1,42 @@ +DROP PROCEDURE IF EXISTS syncSnatDefaultL3ConfigForVpcHa; +DELIMITER $$ +CREATE PROCEDURE syncSnatDefaultL3ConfigForVpcHa() +BEGIN + DECLARE thisVpcHaRouterUuid VARCHAR(32); + DECLARE vpcHaRouterDefaultPublicNetworkUuid VARCHAR(32); + DECLARE defaultL3NetworkUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT DISTINCT vgsr.vpcHaRouterUuid FROM `zstack`.`VpcHaGroupNetworkServiceRefVO` vgsr WHERE networkServiceName='SNAT'; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO thisVpcHaRouterUuid; + IF done THEN + LEAVE read_loop; + END IF; + + SELECT `networkServiceUuid` + FROM `zstack`.`VpcHaGroupNetworkServiceRefVO` + WHERE `vpcHaRouterUuid` = thisVpcHaRouterUuid + AND `networkServiceName` = 'SNAT' + LIMIT 1 INTO vpcHaRouterDefaultPublicNetworkUuid; + + SELECT `defaultRouteL3NetworkUuid` + FROM `zstack`.`ApplianceVmVO` + WHERE uuid IN (SELECT uuid FROM `zstack`.`VpcHaGroupApplianceVmRefVO` WHERE `vpcHaRouterUuid` = thisVpcHaRouterUuid) + AND `haStatus` != 'NoHa' + LIMIT 1 INTO defaultL3NetworkUuid; + + IF STRCMP(defaultL3NetworkUuid, vpcHaRouterDefaultPublicNetworkUuid) THEN + UPDATE `zstack`.`VpcHaGroupNetworkServiceRefVO` + SET `networkServiceUuid` = defaultL3NetworkUuid + WHERE `vpcHaRouterUuid` = thisVpcHaRouterUuid + AND `networkServiceName` = 'SNAT'; + END IF; + END LOOP; + CLOSE cur; + SELECT CURTIME(); +END $$ +DELIMITER ; +CALL syncSnatDefaultL3ConfigForVpcHa(); +DROP PROCEDURE IF EXISTS syncSnatDefaultL3ConfigForVpcHa; \ No newline at end of file diff --git a/conf/db/upgrade/V4.3.8.1__schema.sql b/conf/db/upgrade/V4.3.8.1__schema.sql index 92010334d14..812152b26f6 100644 --- a/conf/db/upgrade/V4.3.8.1__schema.sql +++ b/conf/db/upgrade/V4.3.8.1__schema.sql @@ -1,5 +1,3 @@ -ALTER TABLE `zstack`.`VpcSnatStateVO` ADD CONSTRAINT uqVpcL3NetworkRefVO UNIQUE (vpcUuid, l3NetworkUuid); - DROP PROCEDURE IF EXISTS syncSnatDefaultL3ConfigForVirtualRouter; DELIMITER $$ CREATE PROCEDURE syncSnatDefaultL3ConfigForVirtualRouter() @@ -18,7 +16,9 @@ BEGIN END IF; SELECT `defaultRouteL3NetworkUuid` INTO defaultL3NetworkUuid FROM `zstack`.`ApplianceVmVO` WHERE `uuid` = virtualRouterUuid; IF STRCMP(defaultL3NetworkUuid, publicNetworkUuid) THEN - UPDATE `zstack`.`VpcSnatStateVO` SET `l3NetworkUuid` = defaultL3NetworkUuid WHERE `vpcUuid` = virtualRouterUuid AND `l3NetworkUuid` = publicNetworkUuid; + IF (select count(*) from `zstack`.`VpcSnatStateVO` where `l3NetworkUuid` = defaultL3NetworkUuid and `vpcUuid` = virtualRouterUuid) < 1 THEN + UPDATE `zstack`.`VpcSnatStateVO` SET `l3NetworkUuid` = defaultL3NetworkUuid WHERE `vpcUuid` = virtualRouterUuid AND `l3NetworkUuid` = publicNetworkUuid; + END IF; END IF; END LOOP; CLOSE cur; @@ -28,6 +28,8 @@ DELIMITER ; CALL syncSnatDefaultL3ConfigForVirtualRouter(); DROP PROCEDURE IF EXISTS syncSnatDefaultL3ConfigForVirtualRouter; +ALTER TABLE `zstack`.`VpcSnatStateVO` ADD CONSTRAINT uqVpcL3NetworkRefVO UNIQUE (vpcUuid, l3NetworkUuid); + DROP PROCEDURE IF EXISTS syncSnatDefaultL3ConfigForVpcHa; DELIMITER $$ @@ -59,7 +61,7 @@ BEGIN LIMIT 1 INTO defaultL3NetworkUuid; IF STRCMP(defaultL3NetworkUuid, vpcHaRouterDefaultPublicNetworkUuid) THEN - UPDATE `zstack`.`VpcHaGroupNetworkServiceRefVO` SET `networkServiceUuid` = defaultL3NetworkUuid WHERE `vpcHaRouterUuid` = thisVpcHaRouterUuid; + UPDATE `zstack`.`VpcHaGroupNetworkServiceRefVO` SET `networkServiceUuid` = defaultL3NetworkUuid WHERE `vpcHaRouterUuid` = thisVpcHaRouterUuid AND `networkServiceName` = 'SNAT'; END IF; END LOOP; CLOSE cur; diff --git a/conf/db/upgrade/V4.4.0__schema.sql b/conf/db/upgrade/V4.4.0__schema.sql index d6ac5c72dd4..9164cfccd75 100644 --- a/conf/db/upgrade/V4.4.0__schema.sql +++ b/conf/db/upgrade/V4.4.0__schema.sql @@ -1,3 +1,4 @@ +UPDATE `zstack`.`LicenseHistoryVO` SET `hash` = 'unknown' WHERE `hash` IS NULL; ALTER TABLE `zstack`.`LicenseHistoryVO` MODIFY COLUMN `hash` char(32) NOT NULL DEFAULT 'unknown'; ALTER TABLE `zstack`.`LicenseHistoryVO` ADD COLUMN `source` varchar(16) DEFAULT 'Legacy'; ALTER TABLE `zstack`.`LicenseHistoryVO` MODIFY COLUMN `source` varchar(16) NOT NULL; diff --git a/conf/db/upgrade/V4.4.24__schema.sql b/conf/db/upgrade/V4.4.24__schema.sql new file mode 100644 index 00000000000..bd4fa1c07af --- /dev/null +++ b/conf/db/upgrade/V4.4.24__schema.sql @@ -0,0 +1,178 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`SharedBlockCapacityVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'shared block uuid', + `totalCapacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'total capacity of shared block in bytes', + `availableCapacity` bigint unsigned NOT NULL DEFAULT 0 COMMENT 'available capacity of shared block in bytes', + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkSharedBlockCapacityVOSharedBlockVO` FOREIGN KEY (`uuid`) REFERENCES `zstack`.`SharedBlockVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`CdpPolicyEO` ADD COLUMN `dailyRPSinceDay` int unsigned DEFAULT 0; +ALTER TABLE `zstack`.`CdpPolicyEO` ADD COLUMN `expireTime` int unsigned DEFAULT 0; +ALTER TABLE `zstack`.`CdpPolicyEO` ADD COLUMN `fullBackupInterval` int unsigned DEFAULT 1; + +DROP VIEW IF EXISTS `zstack`.`CdpPolicyVO`; +CREATE VIEW `zstack`.`CdpPolicyVO` AS SELECT uuid, name, description, retentionTimePerDay, dailyRPSinceDay, expireTime, recoveryPointPerSecond, fullBackupInterval, state, lastOpDate, createDate FROM `zstack`.`CdpPolicyEO` WHERE deleted IS NULL; + +ALTER TABLE `zstack`.`CdpTaskVO` ADD COLUMN `maxLatency` bigint(20) unsigned DEFAULT 600000; +ALTER TABLE `zstack`.`CdpTaskVO` ADD COLUMN `lastLatency` bigint(20) unsigned DEFAULT 0; + +DROP PROCEDURE IF EXISTS `Alter_SCSI_Table`; +DELIMITER $$ +CREATE PROCEDURE Alter_SCSI_Table() + BEGIN + IF NOT EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'ScsiLunHostRefVO' + AND table_schema = 'zstack' + AND column_name = 'path') THEN + + ALTER TABLE `zstack`.`ScsiLunHostRefVO` + ADD COLUMN `hctl` VARCHAR(64) DEFAULT NULL, + ADD COLUMN `path` VARCHAR(128) DEFAULT NULL; + + UPDATE `zstack`.`ScsiLunHostRefVO` ref + INNER JOIN `zstack`.`ScsiLunVO` lun ON ref.scsiLunUuid = lun.uuid + SET ref.path = lun.path, ref.hctl = lun.hctl; + + END IF; + END $$ +DELIMITER ; + +CALL Alter_SCSI_Table(); +DROP PROCEDURE Alter_SCSI_Table; + +DELIMITER $$ +CREATE PROCEDURE Update_Vip_Account() + BEGIN + DECLARE vipUuid VARCHAR(32); + DECLARE eipAccountUuid VARCHAR(32); + DECLARE vipAccountUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT v.uuid, a.accountUuid, b.accountUuid FROM zstack.EipVO e, zstack.VipVO v, zstack.AccountResourceRefVO a, zstack.AccountResourceRefVO b + WHERE e.vipUuid = v.uuid AND a.resourceUuid = e.uuid AND b.resourceUuid = v.uuid AND a.accountUuid != b.accountUuid; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO vipUuid, eipAccountUuid, vipAccountUuid; + IF done THEN + LEAVE read_loop; + END IF; + UPDATE zstack.AccountResourceRefVO set accountUuid = eipAccountUuid WHERE accountUuid = vipAccountUuid AND resourceUuid = vipUuid; + END LOOP; + CLOSE cur; + END $$ +DELIMITER ; + +CALL Update_Vip_Account(); +DROP PROCEDURE IF EXISTS Update_Vip_Account; + +UPDATE `zstack`.`VmInstanceVO` t1, `zstack`.`HostVO` t2 set t1.`architecture` = t2.`architecture` where t1.`type` = 'ApplianceVm' and t1.`hostUuid` = t2.`uuid`; +UPDATE `zstack`.`VmInstanceVO` t1, `zstack`.`HostVO` t2 set t1.`architecture` = t2.`architecture` where t1.`type` = 'ApplianceVm' and t1.`architecture` IS NULL and t1.`lastHostUuid` = t2.`uuid`; + +CREATE TABLE `zstack`.`BareMetal2BondingVO` ( + `uuid` varchar(32) NOT NULL, + `name` varchar(255) NOT NULL, + `slaves` varchar(255) NOT NULL, + `opts` varchar(255) DEFAULT NULL, + `chassisUuid` varchar(32) NOT NULL, + `mode` varchar(255) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + KEY `fkchassisUuid` (`chassisUuid`), + CONSTRAINT `fkchassisUuid` FOREIGN KEY (`chassisUuid`) REFERENCES `BareMetal2ChassisVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `zstack`.`BareMetal2BondingNicRefVO` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `nicUuid` varchar(32) NOT NULL, + `instanceUuid` varchar(32) NOT NULL, + `bondingUuid` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + KEY `fkinstance` (`instanceUuid`), + KEY `fknic` (`nicUuid`), + KEY `fkbonding` (`bondingUuid`), + CONSTRAINT `fkinstance` FOREIGN KEY (`instanceUuid`) REFERENCES `BareMetal2InstanceVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fknic` FOREIGN KEY (`nicUuid`) REFERENCES `VmNicVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkbonding` FOREIGN KEY (`bondingUuid`) REFERENCES `BareMetal2BondingVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`BareMetal2InstanceVO` add column agentVersion varchar(32) DEFAULT NULL; +ALTER TABLE `zstack`.`BareMetal2InstanceVO` add column isLatestAgent tinyint(1) unsigned DEFAULT 0; +ALTER TABLE `zstack`.`BareMetal2ChassisNicVO` add column nicName varchar(255) DEFAULT NULL; + +ALTER TABLE `zstack`.`IPsecConnectionVO` ADD COLUMN `ikeVersion` varchar(16) NOT NULL DEFAULT 'ikev1'; +ALTER TABLE `zstack`.`IPsecConnectionVO` ADD COLUMN `idType` varchar(16) DEFAULT NULL; +ALTER TABLE `zstack`.`IPsecConnectionVO` ADD COLUMN `remoteId` varchar(128) DEFAULT NULL; +ALTER TABLE `zstack`.`IPsecConnectionVO` ADD COLUMN `localId` varchar(128) DEFAULT NULL; +ALTER TABLE `zstack`.`IPsecConnectionVO` ADD COLUMN `ikeLifeTime` int(10) DEFAULT 0; +ALTER TABLE `zstack`.`IPsecConnectionVO` ADD COLUMN `lifeTime` int(10) DEFAULT 0; + +CREATE TABLE IF NOT EXISTS `zstack`.`VirtualRouterSoftwareVersionVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `softwareName` varchar(32) NOT NULL, + `currentVersion` varchar(32) DEFAULT NULL, + `latestVersion` varchar(32) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkVirtualRouterSoftwareVersionVOVirtualRouterVmVO` FOREIGN KEY (`uuid`) REFERENCES `VirtualRouterVmVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmSchedHistoryVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `vmInstanceUuid` char(32) NOT NULL, + `zoneUuid` char(32) DEFAULT NULL, + `accountUuid` char(32) NOT NULL, + `schedType` varchar(32) NOT NULL, + `success` tinyint(1), + `lastHostUuid` char(32) DEFAULT NULL, + `destHostUuid` char(32) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + INDEX idxVmSchedHistoryVOVmInstanceUuid (vmInstanceUuid), + INDEX idxVmSchedHistoryVOZoneUuid (zoneUuid), + INDEX idxVmSchedHistoryVOSchedType (schedType), + CONSTRAINT fkVmSchedHistoryVOZoneEO FOREIGN KEY (zoneUuid) REFERENCES ZoneEO (uuid) ON DELETE SET NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmInstanceDeviceAddressVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `resourceUuid` char(32) NOT NULL, + `vmInstanceUuid` char(32) NOT NULL, + `deviceAddress` varchar(128) DEFAULT NULL, + `metadata` text DEFAULT NULL, + `metadataClass` varchar(128) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkVmInstanceDeviceAddressVOVmInstanceEO` FOREIGN KEY (`vmInstanceUuid`) REFERENCES VmInstanceEO(`uuid`) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmInstanceDeviceAddressGroupVO` ( + `uuid` char(32) NOT NULL UNIQUE, + `resourceUuid` char(32) NOT NULL, + `vmInstanceUuid` char(32) NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkVmInstanceDeviceAddressGroupVOVmInstanceEO` FOREIGN KEY (`vmInstanceUuid`) REFERENCES VmInstanceEO(`uuid`) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmInstanceDeviceAddressArchiveVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `resourceUuid` char(32) NOT NULL, + `vmInstanceUuid` char(32) NOT NULL, + `addressGroupUuid` char(32) NOT NULL, + `deviceAddress` varchar(128) DEFAULT NULL, + `metadata` text DEFAULT NULL, + `metadataClass` varchar(128) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkVmInstanceDeviceAddressArchiveVOVmInstanceEO` FOREIGN KEY (`vmInstanceUuid`) REFERENCES VmInstanceEO(`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkVmInstanceDeviceAddressArchiveVOVmInstanceDeviceAddressGroupVO` FOREIGN KEY (`addressGroupUuid`) REFERENCES VmInstanceDeviceAddressGroupVO (uuid) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8; diff --git a/conf/db/upgrade/V4.4.26__schema.sql b/conf/db/upgrade/V4.4.26__schema.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/conf/db/upgrade/V4.4.27.1__schema.sql b/conf/db/upgrade/V4.4.27.1__schema.sql new file mode 100644 index 00000000000..d0357c0ca93 --- /dev/null +++ b/conf/db/upgrade/V4.4.27.1__schema.sql @@ -0,0 +1 @@ +ALTER TABLE HostPhysicalMemoryVO ADD COLUMN type varchar(32) DEFAULT NULL; diff --git a/conf/db/upgrade/V4.4.27__schema.sql b/conf/db/upgrade/V4.4.27__schema.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/conf/db/upgrade/V4.4.40.2__schema.sql b/conf/db/upgrade/V4.4.40.2__schema.sql new file mode 100644 index 00000000000..9eb45ccd19a --- /dev/null +++ b/conf/db/upgrade/V4.4.40.2__schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`AgentVersionVO` ( + `uuid` varchar(32) NOT NULL PRIMARY KEY, + `agentType` varchar(255) DEFAULT NULL, + `currentVersion` varchar(255) DEFAULT NULL, + `expectVersion` varchar(255) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/conf/db/upgrade/V4.4.46__schema.sql b/conf/db/upgrade/V4.4.46__schema.sql new file mode 100644 index 00000000000..09c260a5f4c --- /dev/null +++ b/conf/db/upgrade/V4.4.46__schema.sql @@ -0,0 +1,25 @@ +DELIMITER $$ +CREATE PROCEDURE splitHybridLicenseRecords() +BEGIN + IF EXISTS ( SELECT 1 + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'LicenseHistoryVO' + AND table_schema = 'zstack' + AND column_name = 'capacity') THEN + insert into `zstack`.`LicenseHistoryVO` (`uuid`, `cpuNum`, `hostNum`, `vmNum`, `expiredDate`, `issuedDate`, `uploadDate`, `licenseType`, `userName`, `prodInfo`, `createDate`, `lastOpDate`, `hash`, `source`, `managementNodeUuid`, `mergedTo`, `capacity`) + select `uuid`, `cpuNum`, `hostNum`, `vmNum`, `expiredDate`, `issuedDate`, `uploadDate`, 'AddOn' as `licenseType`, `userName`, 'hybrid' as `prodInfo`, `createDate`, `lastOpDate`, `hash`, `source`, `managementNodeUuid`, `mergedTo`, `capacity` + from `zstack`.`LicenseHistoryVO` + where `licenseType`='Hybrid'; + ELSE + insert into `zstack`.`LicenseHistoryVO` (`uuid`, `cpuNum`, `hostNum`, `vmNum`, `expiredDate`, `issuedDate`, `uploadDate`, `licenseType`, `userName`, `prodInfo`, `createDate`, `lastOpDate`, `hash`, `source`, `managementNodeUuid`, `mergedTo`) + select `uuid`, `cpuNum`, `hostNum`, `vmNum`, `expiredDate`, `issuedDate`, `uploadDate`, 'AddOn' as `licenseType`, `userName`, 'hybrid' as `prodInfo`, `createDate`, `lastOpDate`, `hash`, `source`, `managementNodeUuid`, `mergedTo` + from `zstack`.`LicenseHistoryVO` + where `licenseType`='Hybrid'; + END IF; + update `zstack`.`LicenseHistoryVO` set `licenseType`='Paid' where `licenseType`='Hybrid'; + SELECT CURTIME(); +END $$ +DELIMITER ; + +CALL splitHybridLicenseRecords(); +DROP PROCEDURE IF EXISTS splitHybridLicenseRecords; diff --git a/conf/db/upgrade/V4.4.48.1__schema.sql b/conf/db/upgrade/V4.4.48.1__schema.sql new file mode 100644 index 00000000000..782269a0617 --- /dev/null +++ b/conf/db/upgrade/V4.4.48.1__schema.sql @@ -0,0 +1,3 @@ +UPDATE `zstack`.`LicenseHistoryVO` + SET prodInfo = 'Enterprise.Cloud' + WHERE LOWER(prodInfo) = 'zstack' and licenseType = 'Paid'; diff --git a/conf/db/upgrade/V4.4.6__schema.sql b/conf/db/upgrade/V4.4.6__schema.sql new file mode 100644 index 00000000000..004352cd94a --- /dev/null +++ b/conf/db/upgrade/V4.4.6__schema.sql @@ -0,0 +1,17 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`ImagePackageVO` ( + `uuid` char(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `vmUuid` char(32), + `backupStorageUuid` char(32) NOT NULL, + `state` varchar(32) NOT NULL, + `exportUrl` varchar(2048) DEFAULT NULL, + `md5Sum` char(32) DEFAULT NULL, + `format` varchar(16) DEFAULT NULL, + `size` bigint unsigned DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkImagePackageVOVmInstanceEO` FOREIGN KEY (`vmUuid`) REFERENCES VmInstanceEO(`uuid`) ON DELETE SET NULL, + CONSTRAINT `fkImagePackageVOBackupStorageEO` FOREIGN KEY (`backupStorageUuid`) REFERENCES BackupStorageEO(`uuid`) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8; \ No newline at end of file diff --git a/conf/db/upgrade/V4.4.8__schema.sql b/conf/db/upgrade/V4.4.8__schema.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/conf/db/upgrade/V4.4.9__schema.sql b/conf/db/upgrade/V4.4.9__schema.sql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/conf/db/upgrade/V4.5.0__schema.sql b/conf/db/upgrade/V4.5.0__schema.sql new file mode 100644 index 00000000000..410ef280979 --- /dev/null +++ b/conf/db/upgrade/V4.5.0__schema.sql @@ -0,0 +1,137 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`AiSiNoSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `managementIp` varchar(32) NOT NULL, + `port` int unsigned NOT NULL, + `route` varchar(32) NOT NULL, + `clientID` varchar(32) NOT NULL, + `clientSecrete` varchar(32) NOT NULL, + `appId` varchar(8) NOT NULL, + `keyNumSM2` varchar(8) NOT NULL, + `keyNumSM4` varchar(8) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkAiSiNoSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +ALTER TABLE SecretResourcePoolVO ADD COLUMN status VARCHAR(32) NOT NULL DEFAULT 'Connected'; +ALTER TABLE `zstack`.`TicketStatusHistoryVO` ADD COLUMN `flowName` VARCHAR(255) DEFAULT NULL; +ALTER TABLE `zstack`.`ArchiveTicketStatusHistoryVO` ADD COLUMN `flowName` VARCHAR(255) DEFAULT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`CephOsdGroupVO` ( + `uuid` varchar(32) NOT NULL, + `primaryStorageUuid` varchar(32) NOT NULL, + `osds` varchar(1024) NOT NULL, + `availableCapacity` bigint(20) DEFAULT NULL, + `availablePhysicalCapacity` bigint(20) unsigned NOT NULL DEFAULT 0, + `totalPhysicalCapacity` bigint(20) unsigned NOT NULL DEFAULT 0, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + KEY `fkPrimaryStorageUuid` (`primaryStorageUuid`), + CONSTRAINT `fkPrimaryStorageUuid` FOREIGN KEY (`primaryStorageUuid`) REFERENCES `PrimaryStorageEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`CephPrimaryStoragePoolVO` ADD COLUMN `osdGroupUuid` VARCHAR(32) DEFAULT NULL; +ALTER TABLE `zstack`.`CephPrimaryStoragePoolVO` ADD CONSTRAINT fkCephPrimaryStoragePoolVOOsdGroupVO FOREIGN KEY (osdGroupUuid) REFERENCES CephOsdGroupVO (uuid) ON DELETE SET NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`VxlanHostMappingVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `vxlanUuid` varchar(32) NOT NULL, + `hostUuid` varchar(32) NOT NULL, + `vlanId` int, + `physicalInterface` varchar(32), + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkVxlanHostMappingVOVxlanNetworkVO` FOREIGN KEY (`vxlanUuid`) REFERENCES `VxlanNetworkVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT `fkVxlanHostMappingVOHostEO` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VxlanClusterMappingVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `vxlanUuid` varchar(32) NOT NULL, + `clusterUuid` varchar(32) NOT NULL, + `vlanId` int, + `physicalInterface` varchar(32), + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkVxlanClusterMappingVOVxlanNetworkVO` FOREIGN KEY (`vxlanUuid`) REFERENCES `VxlanNetworkVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT `fkVxlanClusterMappingVOClusterEO` FOREIGN KEY (`clusterUuid`) REFERENCES `ClusterEO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`RegisterLicenseApplicationVO` ( + `appId` VARCHAR(32) NOT NULL UNIQUE, + `licenseRequestCode` text NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`appId`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE `zstack`.`VolumeHostRefVO` ( + `volumeUuid` varchar(32) NOT NULL UNIQUE, + `hostUuid` varchar(32) NOT NULL, + `mountPath` varchar(512) NOT NULL, + `device` varchar(512) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`volumeUuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +ALTER TABLE `zstack`.`VolumeHostRefVO` ADD CONSTRAINT `fkVolumeHostRefVOHostEO` +FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE; + +CREATE TABLE IF NOT EXISTS `zstack`.`SSOClientVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `clientType` varchar(255) NOT NULL, + `loginType` varchar(255) NOT NULL, + `loginMNUrl` varchar(255) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`OAuth2ClientVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `clientId` varchar(255) NOT NULL, + `clientSecret` varchar(255), + `authorizationUrl` varchar(255), + `grantType` varchar(64) NOT NULL, + `tokenUrl` varchar(255) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkOAuth2ClientVOSSOClientVO` FOREIGN KEY (`uuid`) REFERENCES `SSOClientVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`CasClientVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `casServerLoginUrl` varchar(255) NOT NULL, + `casServerUrlPrefix` varchar(255) NOT NULL, + `serverName` varchar(255) NOT NULL, + `state` varchar(128) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkCasClientVOSSOClientVO` FOREIGN KEY (`uuid`) REFERENCES `SSOClientVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ThirdClientAccountRefVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `clientUuid` varchar(255) NOT NULL, + `resourceUuid` varchar(255) NOT NULL, + `resourceType` varchar(255) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkThirdClientAccountRefVOSSOClientVO` FOREIGN KEY (`clientUuid`) REFERENCES `SSOClientVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SSORedirectTemplateVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `clientUuid` varchar(255) NOT NULL, + `redirectTemplate` varchar(2048) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkSSORedirectTemplateClientVO` FOREIGN KEY (`clientUuid`) REFERENCES `SSOClientVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`V2VConversionCacheVO` ADD COLUMN `deviceAddress` varchar(128) DEFAULT NULL; diff --git a/conf/db/upgrade/V4.5.1.1__schema.sql b/conf/db/upgrade/V4.5.1.1__schema.sql new file mode 100644 index 00000000000..bc854ab7832 --- /dev/null +++ b/conf/db/upgrade/V4.5.1.1__schema.sql @@ -0,0 +1,2 @@ +ALTER TABLE `zstack`.`InfoSecSecretResourcePoolVO` ADD COLUMN `encryptPublicKey` text DEFAULT NULL; +ALTER TABLE `zstack`.`InfoSecSecretResourcePoolVO` ADD COLUMN `encryptSubjectDN` varchar(128) DEFAULT NULL; \ No newline at end of file diff --git a/conf/db/upgrade/V4.5.1.2__schema.sql b/conf/db/upgrade/V4.5.1.2__schema.sql new file mode 100644 index 00000000000..19c73e40162 --- /dev/null +++ b/conf/db/upgrade/V4.5.1.2__schema.sql @@ -0,0 +1,37 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`PluginDriverVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(64) NOT NULL, + `type` varchar(64) NOT NULL, + `vendor` varchar(64) NOT NULL, + `features` varchar(1024) NOT NULL, + `optionTypes` text DEFAULT NULL, + `description` varchar(1024) DEFAULT NULL, + `deleted` BOOLEAN NOT NULL, + `license` varchar(1024) DEFAULT NULL, + `version` varchar(1024) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SNSPluginEndpointVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `timeoutInSeconds` int NOT NULL, + `properties` varchar(1024) NOT NULL, + `pluginDriverUuid` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkPluginEndpointVOSNSApplicationEndpointVO FOREIGN KEY (uuid) REFERENCES SNSApplicationEndpointVO (uuid) ON DELETE CASCADE, + CONSTRAINT fkPluginEndpointVOPluginDriverVO FOREIGN KEY (pluginDriverUuid) REFERENCES PluginDriverVO (uuid) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`PluginSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `properties` varchar(1024) NOT NULL, + `pluginDriverUuid` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkPluginSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON DELETE CASCADE, + CONSTRAINT fkPluginSecretResourcePoolVOPluginDriverVO FOREIGN KEY (pluginDriverUuid) REFERENCES PluginDriverVO (uuid) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +update EventSubscriptionVO set name='Cryptographic Resource Status Abnormal' where uuid='eecc7b576c05391bb01fd956964d3ba4'; +update SystemTagVO set tag='name::cn::密码资源状态异常' where resourceUuid='eecc7b576c05391bb01fd956964d3ba4'; diff --git a/conf/db/upgrade/V4.5.11__schema.sql b/conf/db/upgrade/V4.5.11__schema.sql new file mode 100644 index 00000000000..5aacffbe970 --- /dev/null +++ b/conf/db/upgrade/V4.5.11__schema.sql @@ -0,0 +1,66 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`BlockPrimaryStorageVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `vendorName` varchar(256) NOt NULL, + `metadata` text DEFAULT NULL, + `encryptGatewayIp` varchar(64) DEFAULT NULL, + `encryptGatewayPort` smallint unsigned DEFAULT 8443, + `encryptGatewayUsername` varchar(256) DEFAULT NULL, + `encryptGatewayPassword` varchar(256) DEFAULT NULL, + PRIMARY KEY (`uuid`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`BlockScsiLunVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `target` varchar(256) DEFAULT NULL, + `name` VARCHAR(256) DEFAULT NULL, + `id` smallint unsigned NOT NULL, + `wwn` VARCHAR(256) DEFAULT NULL, + `type` VARCHAR(128) NOT NULL, + `size` bigint unsigned NOT NULL, + `lunMapId` smallint unsigned DEFAULT 0, + `lunInitSnapshotID` bigint unsigned DEFAULT 0, + `usedSize` bigint(20) unsigned DEFAULT 0, + `encryptedId` smallint unsigned DEFAULT 0, + `encryptedWwn` varchar(256) DEFAULT NULL, + `lunType` varchar(256) NOT NULL, + `volumeUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkScsiLunVOVolumeVO` FOREIGN KEY (`volumeUuid`) REFERENCES `zstack`.`VolumeEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostInitiatorRefVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `hostUuid` varchar(32) NOT NULL UNIQUE, + `initiatorName` varchar(256) NOT NULL, + `metadata` text DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHostInitiatorRefVOHostVo` FOREIGN KEY (`hostUuid`) REFERENCES `zstack`.`HostEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ----------------------------------- +-- BEGIN OF MTTY DEVICE VIRTUALIZATION +-- ----------------------------------- +CREATE TABLE IF NOT EXISTS `zstack`.`MttyDeviceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'uuid', + `name` VARCHAR(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `hostUuid` varchar(32) NOT NULL, + `type` varchar(32) NOT NULL, + `state` varchar(32) NOT NULL, + `virtStatus` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT fkDeviceVOHostEO FOREIGN KEY (`hostUuid`) REFERENCES `zstack`.`HostEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`MdevDeviceVO` MODIFY `parentUuid` varchar(32) DEFAULT NULL; +ALTER TABLE `zstack`.`MdevDeviceVO` ADD COLUMN `mttyUuid` VARCHAR(32) DEFAULT NULL; +ALTER TABLE `zstack`.`MdevDeviceVO` ADD CONSTRAINT `fkMdevDeviceVOMttyDeviceVO` FOREIGN KEY (`mttyUuid`) REFERENCES `MttyDeviceVO` (`uuid`) ON DELETE CASCADE; +-- --------------------------------- +-- END OF MTTY DEVICE VIRTUALIZATION +-- --------------------------------- diff --git a/conf/db/upgrade/V4.5.3__schema.sql b/conf/db/upgrade/V4.5.3__schema.sql new file mode 100644 index 00000000000..e7cc58776e7 --- /dev/null +++ b/conf/db/upgrade/V4.5.3__schema.sql @@ -0,0 +1,3 @@ +alter table LicenseHistoryVO modify COLUMN `userName` varchar(64) NOT NULL; + +ALTER TABLE LicenseHistoryVO ADD COLUMN capacity int(10) NOT NULL; diff --git a/conf/db/upgrade/V4.6.0__schema.sql b/conf/db/upgrade/V4.6.0__schema.sql new file mode 100644 index 00000000000..4d83d3169a7 --- /dev/null +++ b/conf/db/upgrade/V4.6.0__schema.sql @@ -0,0 +1,277 @@ +ALTER TABLE `zstack`.`HostNetworkBondingVO` ADD COLUMN `type` char(32) DEFAULT 'unknown'; + +DROP PROCEDURE IF EXISTS addLongJobVOIndex; + +DELIMITER $$ +CREATE PROCEDURE addLongJobVOIndex() +BEGIN + IF NOT EXISTS (SELECT * FROM information_schema.statistics WHERE table_schema = 'zstack' AND table_name = "LongJobVO" AND index_name = "idxLongJobVOtargetResourceUuid") THEN + CREATE INDEX idxLongJobVOtargetResourceUuid ON LongJobVO (targetResourceUuid); + END IF; +END $$ +DELIMITER ; + +CALL addLongJobVOIndex(); + +CREATE TABLE IF NOT EXISTS `zstack`.`VmVdpaNicVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `pciDeviceUuid` varchar(32) DEFAULT NULL, + `lastPciDeviceUuid` varchar(32) DEFAULT NULL, + `srcPath` varchar(128) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkVmVdpaNicVOPciDeviceVO` FOREIGN KEY (`pciDeviceUuid`) REFERENCES `zstack`.`PciDeviceVO` (`uuid`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`VipNetworkServicesRefVO` DROP INDEX `uuid`; +ALTER TABLE `zstack`.`VipNetworkServicesRefVO` DROP PRIMARY KEY, ADD PRIMARY KEY(`uuid`,`serviceType`,`vipUuid`); + +UPDATE `zstack`.`GlobalConfigVO` SET value="enable", defaultValue="enable" WHERE category="storageDevice" AND name="enable.multipath" AND value="true"; +UPDATE `zstack`.`GlobalConfigVO` SET value="ignore", defaultValue="enable" WHERE category="storageDevice" AND name="enable.multipath" AND value="false"; + +ALTER TABLE `zstack`.`PriceVO` MODIFY COLUMN price DOUBLE(14,5); + +CREATE TABLE IF NOT EXISTS `zstack`.`VmSchedulingRuleVO`( + `uuid` varchar(32) not null unique, + `rule` varchar (64) not null, + `mode` varchar (64) not null, + PRIMARY KEY (`uuid`), + CONSTRAINT fkVmSchedulingRuleVOAffinityGroupVO FOREIGN KEY (uuid) REFERENCES AffinityGroupVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmSchedulingRuleGroupVO`( + `uuid` varchar(32) not null unique, + `name` varchar(255) not null, + `appliance` varchar(128) not null, + `zoneUuid` varchar(32) DEFAULT null, + `description` varchar(2048) DEFAULT NULL, + `srcUuid` varchar(255) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmSchedulingRuleGroupRefVO`( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `vmGroupUuid` varchar(32) not null, + `vmUuid` varchar(32) not null, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + UNIQUE KEY `vmGroupUuid_vmUuid` (`vmGroupUuid`, `vmUuid`) USING BTREE, + CONSTRAINT `fkVmSchedulingPolicyGroupRefVO` FOREIGN KEY (`vmGroupUuid`) REFERENCES `VmSchedulingRuleGroupVO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT `fkVmInstanceVORefVO` FOREIGN KEY (`vmUuid`) REFERENCES `VmInstanceEO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostSchedulingRuleGroupVO`( + `uuid` varchar(32) not null unique, + `name` varchar(255) not null, + `description` varchar(2048) DEFAULT NULL, + `zoneUuid` varchar(32) not null, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostSchedulingRuleGroupRefVO`( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `hostGroupUuid` varchar(32) not null, + `hostUuid` varchar(32) not null, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + UNIQUE KEY `hostGroupUuid_hostUuid` (`hostGroupUuid`, `hostUuid`) USING BTREE, + CONSTRAINT `fkHostSchedulingRuleGroupRefVO` FOREIGN KEY (`hostGroupUuid`) REFERENCES `HostSchedulingRuleGroupVO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT `fkHostVORefVO` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VmSchedulingRuleRefVO`( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `vmSchedulingRuleUuid` varchar(32) NOT NULL, + `vmGroupUuid` varchar(32) NOT NULL, + `hostGroupUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + UNIQUE KEY `ruleUuid_vmGroupUuid_hostGroupUuid` (`vmSchedulingRuleUuid`, `vmGroupUuid`, `hostGroupUuid`) USING BTREE, + CONSTRAINT `fkVmSchedulingRuleVORefVO` FOREIGN KEY (`vmSchedulingRuleUuid`) REFERENCES `VmSchedulingRuleVO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT `fkVmSchedulingRuleGroupVORefVO` FOREIGN KEY (`vmGroupUuid`) REFERENCES `VmSchedulingRuleGroupVO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT `fkHostSchedulingRuleGroupVORefVO` FOREIGN KEY (`hostGroupUuid`) REFERENCES `HostSchedulingRuleGroupVO`(`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +alter table `zstack`.`AffinityGroupVO` add column `zoneUuid` varchar(32) default null; + +DELIMITER $$ +CREATE PROCEDURE addZoneUuidOnAffinityGroupVO() + BEGIN + DECLARE agUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE agZoneUuid VARCHAR(32); + DECLARE vmCursor CURSOR FOR SELECT uuid name from `zstack`.`AffinityGroupVO`; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN vmCursor; + read_loop: LOOP + FETCH vmCursor INTO agUuid; + IF done THEN + LEAVE read_loop; + END IF; + + select zoneUuid INTO agZoneUuid from VmInstanceVO where uuid in (select resourceUuid from AffinityGroupUsageVO where affinityGroupUuid = agUuid) group by zoneUuid order by count(zoneUuid) desc limit 1; + IF agZoneUuid is null THEN + select uuid into agZoneUuid from ZoneVO limit 1; + END IF; + + UPDATE `zstack`.`AffinityGroupVO` SET `zoneUuid`=agZoneUuid WHERE `uuid`= agUuid; + END LOOP; + CLOSE vmCursor; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call addZoneUuidOnAffinityGroupVO(); +DROP PROCEDURE IF EXISTS addZoneUuidOnAffinityGroupVO; + +DELIMITER $$ +CREATE PROCEDURE createVmSchedulingRule() + BEGIN + DECLARE agUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE policyType VARCHAR(128); + DECLARE ruleType VARCHAR(64); + DECLARE ruleLevel VARCHAR(64); + DECLARE ruleZoneUuid VARCHAR(32); + DECLARE ruleAppliance VARCHAR(128); + DECLARE ruleName VARCHAR(255); + DECLARE ruleAccountUuid VARCHAR(32); + DECLARE vmRuleGroupUuid VARCHAR(32); + DECLARE vmCursor CURSOR FOR SELECT uuid, policy, zoneUuid, appliance, name from `zstack`.`AffinityGroupVO` order by createDate desc; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN vmCursor; + read_loop: LOOP + FETCH vmCursor INTO agUuid, policyType, ruleZoneUuid, ruleAppliance, ruleName; + IF done THEN + LEAVE read_loop; + END IF; + + IF (policyType = "AFFINITYSOFT") THEN + set ruleType = "AFFINITY"; + set ruleLevel = "SOFT"; + ELSEIF (policyType = "AFFINITYHARD") THEN + set ruleType = "AFFINITY"; + set ruleLevel = "HARD"; + ELSEIF (policyType = "ANTISOFT") THEN + set ruleType = "ANTIAFFINITY"; + set ruleLevel ="SOFT"; + ELSE + set ruleType = "ANTIAFFINITY"; + set ruleLevel ="HARD"; + END IF; + set vmRuleGroupUuid = REPLACE(UUID(),'-',''); + + INSERT INTO `zstack`.`VmSchedulingRuleVO`(`uuid`, `rule`, `mode`) VALUES (agUuid, ruleType, ruleLevel); + INSERT INTO `zstack`.`VmSchedulingRuleGroupVO`(`uuid`, `name`, `appliance`, `zoneUuid`, `srcUuid`, `lastOpDate`,`createDate`) + VALUES (vmRuleGroupUuid, ruleName, ruleAppliance, ruleZoneUuid, agUuid, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + INSERT INTO `zstack`.`ResourceVO` (`uuid`, `resourceName`, `resourceType`, `concreteResourceType`) VALUES (vmRuleGroupUuid, ruleName, 'VmSchedulingRuleGroupVO', 'org.zstack.header.vmscheduling.VmSchedulingRuleGroupVO'); + select accountUuid INTO ruleAccountUuid from AccountResourceRefVO where resourceUuid = agUuid and resourceType = 'AffinityGroupVO'; + INSERT INTO `zstack`.`VmSchedulingRuleRefVO`(`vmGroupUuid`, `vmSchedulingRuleUuid`, `lastOpDate`,`createDate`) VALUES (vmRuleGroupUuid, agUuid, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + IF (ruleName <> 'zstack.affinity.group.for.virtual.router' and ruleAccountUuid is not null) THEN + INSERT INTO `zstack`.`AccountResourceRefVO` ( `accountUuid`, `ownerAccountUuid`, `resourceUuid`, `resourceType`, `permission`, `isShared`, `lastOpDate`, `createDate`, `concreteResourceType`) VALUES (ruleAccountUuid, ruleAccountUuid, vmRuleGroupUuid, 'VmSchedulingRuleGroupVO', 2, 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), 'org.zstack.header.vmscheduling.VmSchedulingRuleGroupVO'); + END IF; + END LOOP; + CLOSE vmCursor; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call createVmSchedulingRule(); +DROP PROCEDURE IF EXISTS createVmSchedulingRule; + +DELIMITER $$ +CREATE PROCEDURE createVmSchedulingRuleGroupRef() + BEGIN + DECLARE agUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE vmUuid VARCHAR(128); + DECLARE vmGroupUUid VARCHAR(32); + DECLARE vmCursor CURSOR FOR SELECT affinityGroupUuid, resourceUuid name from `zstack`.`AffinityGroupUsageVO`; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN vmCursor; + read_loop: LOOP + FETCH vmCursor INTO agUuid, vmUuid; + IF done THEN + LEAVE read_loop; + END IF; + + select uuid INTO vmGroupUUid from VmSchedulingRuleGroupVO where srcUuid = agUuid; + INSERT INTO `zstack`.`VmSchedulingRuleGroupRefVO`(`vmGroupUuid`, `vmUuid`, `lastOpDate`,`createDate`) VALUES(vmGroupUUid, vmUuid, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + END LOOP; + CLOSE vmCursor; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call createVmSchedulingRuleGroupRef(); +DROP PROCEDURE IF EXISTS createVmSchedulingRuleGroupRef; + +DELIMITER $$ +CREATE PROCEDURE createAutoScalingVmTemplate() + BEGIN + DECLARE agUuid VARCHAR(32); + DECLARE vmGroupUUid VARCHAR(32); + DECLARE autoReleaseTagUuid VARCHAR(32); + DECLARE autoScalingVmTemplateUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE vmCursor CURSOR FOR select SUBSTRING(tag, 20), resourceUuid from SystemTagVO where resourceType ='AutoScalingVmTemplateVO' and tag like 'affinityGroupUuid::%'; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN vmCursor; + read_loop: LOOP + FETCH vmCursor INTO agUuid, autoScalingVmTemplateUuid; + IF done THEN + LEAVE read_loop; + END IF; + + SET autoReleaseTagUuid = REPLACE(UUID(), '-', ''); + select uuid into vmGroupUUid from VmSchedulingRuleGroupVO where srcUuid = agUuid; + INSERT INTO `zstack`.`SystemTagVO`(`uuid`, `resourceUuid`, `resourceType`, `inherent`, `type`, `tag`, `createDate`, `lastOpDate`) + VALUES(autoReleaseTagUuid, autoScalingVmTemplateUuid, 'AutoScalingVmTemplateVO', 0, 'System', concat('vmSchedulingRuleGroupUuid::', vmGroupUUid), CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + END LOOP; + CLOSE vmCursor ; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call createAutoScalingVmTemplate(); +DROP PROCEDURE IF EXISTS createAutoScalingVmTemplate; + +CREATE TABLE IF NOT EXISTS `zstack`.`DirectoryVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(256) NOT NULL, + `groupName` varchar(2048) NOT NULL COMMENT 'equivalent to a path', + `parentUuid` varchar(32), + `rootDirectoryUuid` varchar(32) NOT NULL, + `zoneUuid` varchar(32) NOT NULL, + `type` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkDirectoryVOZoneEO` FOREIGN KEY (`zoneUuid`) REFERENCES `zstack`.`ZoneEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ResourceDirectoryRefVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `resourceUuid` varchar(32) NOT NULL, + `directoryUuid` varchar(32) NOT NULL, + `resourceType` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + UNIQUE KEY `id` (`id`), + KEY `fkResourceDirectoryRefVOResourceVO` (`resourceUuid`), + KEY `fkResourceDirectoryRefVODirectoryVO` (`directoryUuid`), + CONSTRAINT `fkResourceDirectoryRefVO` FOREIGN KEY (`resourceUuid`) REFERENCES `ResourceVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkResourceDirectoryRefVO1` FOREIGN KEY (`directoryUuid`) REFERENCES `DirectoryVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE SlbOfferingVO ADD CONSTRAINT fkSlbOfferingVOInstanceOfferingEO FOREIGN KEY (uuid) REFERENCES InstanceOfferingEO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE; diff --git a/conf/db/upgrade/V4.6.11__schema.sql b/conf/db/upgrade/V4.6.11__schema.sql new file mode 100644 index 00000000000..bd5e6058f1b --- /dev/null +++ b/conf/db/upgrade/V4.6.11__schema.sql @@ -0,0 +1,68 @@ +ALTER TABLE `zstack`.`L2NetworkEO` MODIFY `vSwitchType` varchar(32) NOT NULL DEFAULT 'LinuxBridge' AFTER `type`; +ALTER TABLE `zstack`.`L2NetworkEO` ADD COLUMN `virtualNetworkId` int unsigned NOT NULL DEFAULT 0 AFTER `vSwitchType`; +UPDATE `zstack`.`L2NetworkEO` l2 INNER JOIN `zstack`.`L2VlanNetworkVO` vlan ON l2.uuid = vlan.uuid SET l2.virtualNetworkId = vlan.vlan; +UPDATE `zstack`.`L2NetworkEO` l2 INNER JOIN `zstack`.`VxlanNetworkVO` vxlan ON l2.uuid = vxlan.uuid SET l2.virtualNetworkId = vxlan.vni; +DROP VIEW IF EXISTS `zstack`.L2NetworkVO; +CREATE VIEW `zstack`.`L2NetworkVO` AS SELECT uuid, name, description, type, vSwitchType, virtualNetworkId, zoneUuid, physicalInterface, createDate, lastOpDate FROM `zstack`.`L2NetworkEO` WHERE deleted IS NULL; + +DELIMITER $$ +CREATE PROCEDURE addColumnsToSNSTextTemplateVO() + BEGIN + IF NOT EXISTS( SELECT 1 + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'SNSTextTemplateVO' + AND table_schema = 'zstack' + AND column_name = 'subject') THEN + + ALTER TABLE `zstack`.`SNSTextTemplateVO` ADD COLUMN `subject` VARCHAR(2048); + END IF; + IF NOT EXISTS( SELECT 1 + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'SNSTextTemplateVO' + AND table_schema = 'zstack' + AND column_name = 'recoverySubject') THEN + + ALTER TABLE `zstack`.`SNSTextTemplateVO` ADD COLUMN `recoverySubject` VARCHAR(2048); + END IF; + END $$ +DELIMITER ; + +call addColumnsToSNSTextTemplateVO(); +DROP PROCEDURE IF EXISTS addColumnsToSNSTextTemplateVO; + +CREATE TABLE IF NOT EXISTS `zstack`.`FlkSecSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `encryptResult` varchar(64) DEFAULT NULL, + `activatedToken` varchar(32) DEFAULT NULL, + `protectToken` varchar(32) DEFAULT NULL, + `hmacToken` varchar(32) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkFlkSecSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`FlkSecSecurityMachineVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `port` int unsigned NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkFlkSecSecurityMachineVOSecurityMachineVO FOREIGN KEY (uuid) REFERENCES SecurityMachineVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`CCSCertificateVO` MODIFY COLUMN issuerDN varchar(255) NOT NULL; +ALTER TABLE `zstack`.`CCSCertificateVO` MODIFY COLUMN subjectDN varchar(255) NOT NULL; +ALTER TABLE `zstack`.`CCSCertificateVO` MODIFY COLUMN serNumber varchar(128) NOT NULL; + +ALTER TABLE `zstack`.`ESXHostVO` ADD COLUMN `esxiVersion` varchar(32); + +ALTER TABLE `zstack`.`CephOsdGroupVO` MODIFY COLUMN `osds` text NOT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`GuestToolsStateVO` ( + `vmInstanceUuid` varchar(32) NOT NULL UNIQUE, + `state` varchar(32) NOT NULL DEFAULT 'NotInstalled', + `version` varchar(32), + `platform` varchar(32), + `osType` varchar(32), + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`vmInstanceUuid`), + CONSTRAINT `fkGuestToolsStateVOVmInstanceEO` FOREIGN KEY (`vmInstanceUuid`) REFERENCES `VmInstanceEO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V4.6.21.1__schema.sql b/conf/db/upgrade/V4.6.21.1__schema.sql new file mode 100644 index 00000000000..65ec27379f2 --- /dev/null +++ b/conf/db/upgrade/V4.6.21.1__schema.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`LicenseAppIdRefVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `licenseId` varchar(32) NOT NULL, + `appId` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/conf/db/upgrade/V4.6.21__schema.sql b/conf/db/upgrade/V4.6.21__schema.sql new file mode 100644 index 00000000000..b8fc01611a1 --- /dev/null +++ b/conf/db/upgrade/V4.6.21__schema.sql @@ -0,0 +1,108 @@ +ALTER TABLE `zstack`.`SNSTopicVO` ADD COLUMN `locale` varchar(32); + +ALTER TABLE `zstack`.`HostNumaNodeVO` MODIFY COLUMN `nodeCPUs` TEXT NOT NULL; +ALTER TABLE `zstack`.`VmInstanceNumaNodeVO` MODIFY COLUMN `vNodeCPUs` TEXT NOT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostOsCategoryVO` ( + `uuid` char(32) NOT NULL UNIQUE COMMENT 'uuid', + `architecture` varchar(32) NOT NULL, + `osReleaseVersion` varchar(64) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`KvmHostHypervisorMetadataVO` ( + `uuid` char(32) NOT NULL UNIQUE COMMENT 'uuid', + `categoryUuid` char(32) NOT NULL, + `managementNodeUuid` char(32) NOT NULL, + `hypervisor` varchar(32) NOT NULL, + `version` varchar(64) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + CONSTRAINT `KvmHostHypervisorMetadataVOHostOsCategoryVO` FOREIGN KEY (`categoryUuid`) REFERENCES `zstack`.`HostOsCategoryVO` (`uuid`) ON DELETE CASCADE, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`KvmHypervisorInfoVO` ( + `uuid` char(32) NOT NULL UNIQUE COMMENT 'uuid', + `hypervisor` varchar(32) NOT NULL, + `version` varchar(64) NOT NULL, + `matchState` char(10) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + CONSTRAINT `KvmHypervisorInfoVOResourceVO` FOREIGN KEY (`uuid`) REFERENCES `zstack`.`ResourceVO` (`uuid`) ON DELETE CASCADE, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`UsedIpVO` MODIFY COLUMN `ipRangeUuid` varchar(32) DEFAULT NULL; + +ALTER TABLE `zstack`.`L3NetworkEO` ADD COLUMN `enableIPAM` boolean NOT NULL DEFAULT TRUE; +DROP VIEW IF EXISTS `zstack`.`L3NetworkVO`; +CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, `system`, dnsDomain, createDate, lastOpDate, category, ipVersion, enableIPAM FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; +ALTER TABLE `zstack`.`UsedIpVO` DROP FOREIGN KEY fkUsedIpVOVmNicVO; +ALTER TABLE `zstack`.`UsedIpVO` ADD CONSTRAINT fkUsedIpVOVmNicVO FOREIGN KEY (vmNicUuid) REFERENCES VmNicVO (uuid) ON DELETE CASCADE; + +INSERT INTO SystemTagVO (`uuid`, `resourceUuid`, `resourceType`, `inherent`, `type`, `tag`, `createDate`, `lastOpDate`) +SELECT REPLACE(UUID(),'-',''), vm.uuid, 'VmInstanceVO', 0, 'System', 'vRingBufferSize::256::256', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP() +FROM VmInstanceVO vm LEFT JOIN SystemTagVO st ON st.resourceUuid = vm.uuid AND st.tag LIKE 'vRingBufferSize::%' WHERE vm.state = 'running' AND st.uuid IS NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`SSOTokenVO`( + `uuid` varchar(32) not null unique, + `clientUuid` varchar(32) DEFAULT NULL, + `userUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkSSOTokenVOClientVO` FOREIGN KEY (`clientUuid`) REFERENCES `SSOClientVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`OAuth2TokenVO`( + `uuid` varchar(32) not null unique, + `accessToken` text not null, + `idToken` text not null, + `refreshToken` text not null, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkOAuth2TokenVOSSOTokenVO` FOREIGN KEY (`uuid`) REFERENCES `SSOTokenVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`GuestToolsStateVO` ADD COLUMN `zwatchState` varchar(32) NOT NULL DEFAULT 'NotInstalled'; +ALTER TABLE `zstack`.`GuestToolsStateVO` CHANGE `state` `qgaState` varchar(32) NOT NULL DEFAULT 'NotInstalled'; + +CREATE TABLE IF NOT EXISTS `NvmeTargetVO` ( + `name` VARCHAR(256) DEFAULT NULL, + `uuid` VARCHAR(32) NOT NULL, + `nqn` VARCHAR(256) NOT NULL, + `state` VARCHAR(64) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `NvmeLunVO` ( + `uuid` VARCHAR(32) NOT NULL, + `nvmeTargetUuid` VARCHAR(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkNvmeLunVONvmeTargetVO` FOREIGN KEY (`nvmeTargetUuid`) REFERENCES NvmeTargetVO (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `NvmeLunHostRefVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `hostUuid` varchar(32) NOT NULL, + `nvmeLunUuid` varchar(32) NOT NULL, + `hctl` VARCHAR(64) DEFAULT NULL, + `path` VARCHAR(128) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkNvmeLunHostRefVONvmeLunVO` FOREIGN KEY (`nvmeLunUuid`) REFERENCES `NvmeLunVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkNvmeLunHostRefVOHostVO` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `ScsiLunVO` RENAME AS LunVO; + +# for compatibility +CREATE VIEW `ScsiLunVO` AS SELECT uuid, name, wwid, vendor, model, wwn, serial, type, hctl, path, size, state, source, multipathDeviceUuid, createDate, lastOpDate FROM `LunVO` WHERE source IN ('iSCSI', 'fiberChannel'); +INSERT INTO `NvmeLunHostRefVO` (hostUuid, nvmeLunUuid, hctl, path, lastOpDate, createDate) SELECT hostUuid, scsiLunUuid, hctl, path, lastOpDate, createDate FROM `ScsiLunHostRefVO` WHERE scsiLunUuid NOT IN (SELECT uuid FROM `ScsiLunVO`); +DELETE FROM `ScsiLunHostRefVO` WHERE scsiLunUuid not in (SELECT uuid FROM `ScsiLunVO`); + diff --git a/conf/db/upgrade/V4.6.31__schema.sql b/conf/db/upgrade/V4.6.31__schema.sql new file mode 100644 index 00000000000..986646fda1b --- /dev/null +++ b/conf/db/upgrade/V4.6.31__schema.sql @@ -0,0 +1,66 @@ +ALTER TABLE `zstack`.`KVMHostVO` ADD COLUMN `osDistribution` varchar(64) DEFAULT NULL; +ALTER TABLE `zstack`.`KVMHostVO` ADD COLUMN `osRelease` varchar(64) DEFAULT NULL; +ALTER TABLE `zstack`.`KVMHostVO` ADD COLUMN `osVersion` varchar(64) DEFAULT NULL; + +DELIMITER $$ +CREATE PROCEDURE moveOsInfoToKVMHostVO() + BEGIN + DECLARE hostUuid CHAR(32); + DECLARE osInfo VARCHAR(64); + DECLARE done INT DEFAULT FALSE; + DECLARE curDistribution CURSOR FOR + SELECT resourceUuid, SUBSTRING(tag, 19) FROM `zstack`.`SystemTagVO` WHERE tag LIKE 'os::distribution::%'; + DECLARE curRelease CURSOR FOR + SELECT resourceUuid, SUBSTRING(tag, 14) FROM `zstack`.`SystemTagVO` WHERE tag LIKE 'os::release::%'; + DECLARE curVersion CURSOR FOR + SELECT resourceUuid, SUBSTRING(tag, 14) FROM `zstack`.`SystemTagVO` WHERE tag LIKE 'os::version::%'; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN curDistribution; + read_loop1: LOOP + FETCH curDistribution INTO hostUuid, osInfo; + IF done THEN + LEAVE read_loop1; + END IF; + + UPDATE `zstack`.`KVMHostVO` SET osDistribution = osInfo WHERE uuid = hostUuid; + END LOOP; + CLOSE curDistribution; + SET done = FALSE; + + OPEN curRelease; + read_loop2: LOOP + FETCH curRelease INTO hostUuid, osInfo; + IF done THEN + LEAVE read_loop2; + END IF; + + UPDATE `zstack`.`KVMHostVO` SET osRelease = osInfo WHERE uuid = hostUuid; + END LOOP; + CLOSE curRelease; + SET done = FALSE; + + OPEN curVersion; + read_loop3: LOOP + FETCH curVersion INTO hostUuid, osInfo; + IF done THEN + LEAVE read_loop3; + END IF; + + UPDATE `zstack`.`KVMHostVO` SET osVersion = osInfo WHERE uuid = hostUuid; + END LOOP; + CLOSE curVersion; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call moveOsInfoToKVMHostVO(); +DROP PROCEDURE IF EXISTS moveOsInfoToKVMHostVO; + +# add default zone and recreate ZoneVO +ALTER TABLE `zstack`.`ZoneEO` ADD COLUMN `isDefault` tinyint(1) unsigned DEFAULT 0; +DROP VIEW IF EXISTS `zstack`.`ZoneVO`; +CREATE VIEW `zstack`.`ZoneVO` AS SELECT uuid, name, type, description, state, isDefault, createDate, lastOpDate FROM `zstack`.`ZoneEO` WHERE deleted IS NULL; + +UPDATE SNSTextTemplateVO SET subject = replace('报警器 %{ALARM_METRIC} %{ALARM_COMPARISON_OPERATOR} %{ALARM_THRESHOLD} %{ALARM_CURRENT_STATUS}','%','$') WHERE subject IS NULL or subject = ''; +UPDATE SNSTextTemplateVO SET recoverySubject = replace('报警器 %{ALARM_NAME} %{TITLE_ALARM_RESOURCE_NAME} %{ALARM_CURRENT_STATUS}','%','$') WHERE recoverySubject IS NULL or subject = ''; diff --git a/conf/db/upgrade/V4.7.0.1__schema.sql b/conf/db/upgrade/V4.7.0.1__schema.sql new file mode 100644 index 00000000000..27a3eac30dc --- /dev/null +++ b/conf/db/upgrade/V4.7.0.1__schema.sql @@ -0,0 +1 @@ +UPDATE LicenseHistoryVO SET prodInfo='Enterprise.XinChuang.Cloud' WHERE prodInfo='XinChuang.Cloud'; diff --git a/conf/db/upgrade/V4.7.0.2__schema.sql b/conf/db/upgrade/V4.7.0.2__schema.sql new file mode 100644 index 00000000000..278055ca81c --- /dev/null +++ b/conf/db/upgrade/V4.7.0.2__schema.sql @@ -0,0 +1,23 @@ +ALTER TABLE `zstack`.`VmNicSecurityGroupRefVO` +ADD COLUMN `priority` INT DEFAULT -1 AFTER `securityGroupUuid`; + +ALTER TABLE `zstack`.`SecurityGroupRuleVO` +ADD COLUMN `srcPortRange` varchar(255) DEFAULT NULL AFTER `protocol`, +ADD COLUMN `dstPortRange` varchar(255) DEFAULT NULL AFTER `protocol`, +ADD COLUMN `srcIpRange` varchar(1024) DEFAULT NULL AFTER `protocol`, +ADD COLUMN `dstIpRange` varchar(1024) DEFAULT NULL AFTER `protocol`, +ADD COLUMN `description` varchar(255) DEFAULT NULL AFTER `protocol`, +ADD COLUMN `action` varchar(32) NOT NULL DEFAULT 'ACCEPT' AFTER `protocol`, +ADD COLUMN `priority` INT DEFAULT -1 AFTER `protocol`; + + +CREATE TABLE IF NOT EXISTS `zstack`.`VmNicSecurityPolicyVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `vmNicUuid` varchar(32) NOT NULL, + `ingressPolicy` varchar(32) NOT NULL DEFAULT 'DENY', + `egressPolicy` varchar(32) NOT NULL DEFAULT 'ALLOW', + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkVmNicSecurityPolicyVOVmNicVO` FOREIGN KEY (vmNicUuid) REFERENCES VmNicVO (uuid) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V4.7.0.3__schema.sql b/conf/db/upgrade/V4.7.0.3__schema.sql new file mode 100644 index 00000000000..13d9375266e --- /dev/null +++ b/conf/db/upgrade/V4.7.0.3__schema.sql @@ -0,0 +1,9 @@ +ALTER TABLE `zstack`.`GuestOsCategoryVO` MODIFY COLUMN osRelease varchar(64) NOT NULL; + +ALTER TABLE VolumeEO ADD COLUMN lastAttachDate varchar(32) DEFAULT NULL; +DROP VIEW IF EXISTS `zstack`.`VolumeVO`; +CREATE VIEW `zstack`.`VolumeVO` AS SELECT uuid, name, description, primaryStorageUuid, vmInstanceUuid, diskOfferingUuid, +rootImageUuid, installPath, type, status, size, actualSize, deviceId, format, state, createDate, lastOpDate, isShareable, +volumeQos, lastVmInstanceUuid, lastDetachDate, lastAttachDate FROM `zstack`.`VolumeEO` WHERE deleted IS NULL; + +ALTER TABLE `zstack`.`VolumeSnapshotGroupRefVO` ADD COLUMN volumeLastAttachDate varchar(32) DEFAULT NULL; \ No newline at end of file diff --git a/conf/db/upgrade/V4.7.0.4__schema.sql b/conf/db/upgrade/V4.7.0.4__schema.sql new file mode 100644 index 00000000000..0347ed2f688 --- /dev/null +++ b/conf/db/upgrade/V4.7.0.4__schema.sql @@ -0,0 +1,31 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`L2VirtualSwitchNetworkVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `isDistributed` boolean NOT NULL DEFAULT TRUE, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`L2PortGroupNetworkVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `vSwitchUuid` varchar(32) NOT NULL, + `vlanMode` varchar(32) NOT NULL default 'ACCESS', + `vlanId` int unsigned NOT NULL, + `vlanRanges` varchar(256) default NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkL2PortGroupNetworkVOL2VirtualSwitchNetworkVO` FOREIGN KEY (`vSwitchUuid`) REFERENCES L2VirtualSwitchNetworkVO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`L2NetworkHostRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `l2NetworkUuid` varchar(32) NOT NULL, + `hostUuid` varchar(32) NOT NULL, + `l2ProviderType` varchar(32) default NULL, + `attachStatus` varchar(32) default NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + CONSTRAINT `fkL2NetworkHostRefVOHostEO` FOREIGN KEY (`hostUuid`) REFERENCES HostEO (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkL2NetworkHostRefVOL2NetworkEO` FOREIGN KEY (`l2NetworkUuid`) REFERENCES L2NetworkEO (`uuid`) ON DELETE CASCADE, + UNIQUE KEY `ukL2NetworkHost` (`l2NetworkUuid`,`hostUuid`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`L2NetworkClusterRefVO` ADD COLUMN `l2ProviderType` varchar(32) default NULL; \ No newline at end of file diff --git a/conf/db/upgrade/V4.7.0__schema.sql b/conf/db/upgrade/V4.7.0__schema.sql new file mode 100644 index 00000000000..1e5b4368c1b --- /dev/null +++ b/conf/db/upgrade/V4.7.0__schema.sql @@ -0,0 +1,376 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`FileIntegrityVerificationVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `path` varchar(256) NOT NULL, + `nodeType` varchar(16) NOT NULL, + `nodeUuid` varchar(64) NOT NULL, + `hexType` varchar(16) NOT NULL, + `digest` varchar(256) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + UNIQUE KEY `node` (`nodeUuid`,`nodeType`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HaiTaiSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `managementIp` varchar(32) NOT NULL, + `port` int unsigned NOT NULL, + `realm` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkHaiTaiSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`EncryptEntityMetadataVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `entityName` varchar(255) NOT NULL, + `columnName` varchar(255) NOT NULL, + `state` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT IGNORE INTO `zstack`.`EncryptEntityMetadataVO` (`entityName`, `columnName`, `state`, `lastOpDate`, `createDate`) + VALUES ('IAM2VirtualIDVO', 'password', 'NeedDecrypt', NOW(), NOW()); + +CREATE TABLE IF NOT EXISTS `zstack`.`CpuFeaturesHistoryVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `srcHostUuid` varchar(32) NOT NULL, + `dstHostUuid` varchar(32) NOT NULL, + `srcCpuModelName` varchar(64), + `supportLiveMigration` boolean NOT NULL DEFAULT FALSE, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT CpuFeaturesHistoryVOHostVO FOREIGN KEY (srcHostUuid) REFERENCES HostEO (uuid) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DELETE FROM HostOsCategoryVO; + +DELIMITER $$ +CREATE PROCEDURE CheckAndCreateResourceConfig() + BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE resouce_uuid VARCHAR(32); + DECLARE config_uuid varchar(32); + DECLARE config_name varchar(255); + DECLARE config_category varchar(64); + DECLARE config_resource_type varchar(64); + DECLARE config_value varchar(64); + DECLARE config_description varchar(255); + DECLARE cur CURSOR FOR SELECT uuid FROM zstack.IAM2ProjectVO; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + SET config_name = 'iam2.force.enable.securityGroup'; + SET config_category = 'iam2'; + SET config_resource_type = 'IAM2ProjectVO'; + SET config_value = 'false'; + SET config_description = 'instances under the project need to bind the security group switch'; + + OPEN cur; + + read_loop: LOOP + FETCH cur INTO resouce_uuid; + + IF done THEN + LEAVE read_loop; + END IF; + + SELECT COUNT(*) INTO @count FROM ResourceConfigVO WHERE resourceUuid = resouce_uuid AND name = config_name; + + IF @count = 0 THEN + SET config_uuid = REPLACE(UUID(),'-',''); + INSERT INTO ResourceConfigVO (uuid, name, description, category, value, resourceUuid, resourceType) + VALUES (config_uuid, config_name, config_description, config_category, config_value, resouce_uuid, config_resource_type); + END IF; + END LOOP; + + CLOSE cur; + END $$ +DELIMITER ; +CALL CheckAndCreateResourceConfig(); +DROP PROCEDURE IF EXISTS CheckAndCreateResourceConfig; + + +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `gateway` varchar(128) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `callBackIp` varchar(128) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `description` varchar(2048) DEFAULT NULL; + +ALTER TABLE `zstack`.`HostNetworkBondingVO` ADD COLUMN `speed` BIGINT UNSIGNED DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkBondingVO` ADD COLUMN `bondingType` varchar(32) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkBondingVO` ADD COLUMN `gateway` varchar(128) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkBondingVO` ADD COLUMN `callBackIp` varchar(128) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkBondingVO` ADD COLUMN `description` varchar(2048) DEFAULT NULL; + +CREATE TABLE IF NOT EXISTS `HostIpmiVO` +( + `uuid` varchar(32) NOT NULL UNIQUE, + `ipmiAddress` varchar(32), + `ipmiPort` int unsigned, + `ipmiUsername` varchar(255), + `ipmiPassword` varchar(255), + `ipmiPowerStatus` varchar(255), + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHostIpmiVO` FOREIGN KEY (`uuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +DELIMITER $$ + +DROP FUNCTION IF EXISTS `Json_simpleGetKeyValue` $$ + +CREATE FUNCTION `Json_simpleGetKeyValue`( + in_JsonArray text, + in_KeyName VARCHAR(64) +) RETURNS VARCHAR(4096) CHARSET utf8 + +BEGIN + DECLARE vs_return, vs_KeyName VARCHAR(4096); + DECLARE vs_JsonArray, vs_JsonString, vs_Json text; + DECLARE vi_pos1, vi_pos2 SMALLINT UNSIGNED; + + SET vs_JsonArray = TRIM(in_JsonArray); + SET vs_KeyName = TRIM(in_KeyName); + + IF vs_JsonArray = '' OR vs_JsonArray IS NULL + OR vs_KeyName = '' OR vs_KeyName IS NULL + THEN + SET vs_return = NULL; + ELSE + SET vs_JsonArray = REPLACE(REPLACE(vs_JsonArray, '[', ''), ']', ''); + SET vs_json = REPLACE(REPLACE(vs_JsonArray, '{', ''), '}', ''); + SET vs_JsonString = CONCAT("'", vs_JsonArray, "'"); + + IF vs_json = '' OR vs_json IS NULL THEN + SET vs_return = NULL; + ELSE + SET vs_KeyName = CONCAT('"', vs_KeyName, '":'); + SET vi_pos1 = INSTR(vs_json, vs_KeyName); + + IF vi_pos1 > 0 THEN + SET vi_pos1 = vi_pos1 + CHAR_LENGTH(vs_KeyName); + SET vi_pos2 = LOCATE('","', vs_json, vi_pos1); + + IF vi_pos2 = 0 THEN + SET vi_pos2 = CHAR_LENGTH(vs_json) + 1; + END IF; + + SET vs_return = REPLACE(MID(vs_json, vi_pos1, vi_pos2 - vi_pos1), '"', ''); + END IF; + END IF; + END IF; + + RETURN(vs_return); +END$$ + +DELIMITER ; + +DELIMITER $$ +CREATE PROCEDURE UpdateVolumeBackupVmInstanceUuid() + BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE backup_data text; + DECLARE backup_uuid VARCHAR(32); + DECLARE cur CURSOR FOR SELECT metadata, uuid FROM `zstack`.`VolumeBackupVO`; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + IF NOT EXISTS( SELECT 1 + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'VolumeBackupVO' + AND table_schema = 'zstack' + AND column_name = 'vmInstanceUuid') THEN + + ALTER TABLE `zstack`.`VolumeBackupVO` ADD COLUMN `vmInstanceUuid` varchar(32) DEFAULT NULL; + + OPEN cur; + read_loop: LOOP + FETCH cur INTO backup_data, backup_uuid; + IF done THEN + LEAVE read_loop; + END IF; + + UPDATE `zstack`.`VolumeBackupVO` SET `vmInstanceUuid`= Json_simpleGetKeyValue(backup_data, "vmInstanceUuid") WHERE `uuid`= backup_uuid; + END LOOP; + CLOSE cur; + END IF; + END $$ +DELIMITER ; +CALL UpdateVolumeBackupVmInstanceUuid(); +DROP PROCEDURE IF EXISTS UpdateVolumeBackupVmInstanceUuid; + +CREATE TABLE IF NOT EXISTS `zstack`.`HaStrategyConditionVO` ( + `uuid` varchar(32) NOT NULL, + `name` varchar(256), + `fencerName` varchar(256) NOT NULL, + `state` varchar(64) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +INSERT INTO HaStrategyConditionVO(`uuid`, `name`, `fencerName`, `state`, `lastOpDate`, `createDate`) +values ((REPLACE(UUID(), '-', '')), 'ha strategy condition', 'hostBusinessNic', 'Disable', current_timestamp(), current_timestamp()); + +DELIMITER $$ +CREATE PROCEDURE addHaStrategyConditionOnVmHaLevel() + BEGIN + DECLARE isHaEnable VARCHAR(32); + DECLARE fencerStrategy VARCHAR(32); + DECLARE resourceUuid VARCHAR(32); + DECLARE current_time_stamp timestamp; + DECLARE done INT DEFAULT FALSE; + DECLARE haCursor CURSOR FOR select value from GlobalConfigVO where category = 'ha' and name = 'enable'; + DECLARE fencerCursor CURSOR for select value from GlobalConfigVO where category = 'ha' and name = 'self.fencer.strategy'; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN haCursor; + OPEN fencerCursor; + read_loop: LOOP + FETCH haCursor INTO isHaEnable; + FETCH fencerCursor INTO fencerStrategy; + IF done THEN + LEAVE read_loop; + END IF; + + SET resourceUuid = (REPLACE(UUID(), '-', '')); + SET current_time_stamp = current_timestamp(); + IF (LOWER(isHaEnable) = 'false' OR fencerStrategy = 'Permissive') THEN + INSERT INTO HaStrategyConditionVO(`uuid`, `name`, `fencerName`, `state`, `lastOpDate`, `createDate`) values (resourceUuid, 'ha strategy condition', 'hostStorageState', 'Disable', current_time_stamp, current_time_stamp); + ELSE + INSERT INTO HaStrategyConditionVO(`uuid`, `name`, `fencerName`, `state`, `lastOpDate`, `createDate`) values (resourceUuid, 'ha strategy condition', 'hostStorageState', 'Enable', current_time_stamp, current_time_stamp); + END IF; + END LOOP; + CLOSE haCursor; + CLOSE fencerCursor; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call addHaStrategyConditionOnVmHaLevel(); +DROP PROCEDURE IF EXISTS addHaStrategyConditionOnVmHaLevel; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostHaStateVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'host uuid', + `state` varchar(32), + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DELIMITER $$ +CREATE PROCEDURE addHostHaStatus() + BEGIN + DECLARE isHaEnable VARCHAR(32); + DECLARE hostUuid VARCHAR(32); + DECLARE current_time_stamp timestamp; + DECLARE done INT DEFAULT FALSE; + DECLARE haCursor CURSOR FOR select uuid from HostVO; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN haCursor; + read_loop: LOOP + FETCH haCursor INTO hostUuid; + IF done THEN + LEAVE read_loop; + END IF; + + SET current_time_stamp = current_timestamp(); + insert into HostHaStateVO(`uuid`, `state`,`lastOpDate`, `createDate`)values (hostUuid, 'None', current_time_stamp, current_time_stamp); + END LOOP; + CLOSE haCursor; + SELECT CURTIME(); + END $$ +DELIMITER ; + +call addHostHaStatus(); +DROP PROCEDURE IF EXISTS addHostHaStatus; + +CREATE TABLE IF NOT EXISTS `VolumeSnapshotReferenceTreeVO` ( + `uuid` varchar(32) NOT NULL, + `rootImageUuid` varchar(32) DEFAULT NULL, + `rootVolumeUuid` VARCHAR(32) DEFAULT NULL, + `rootInstallUrl` VARCHAR(1024) DEFAULT NULL, + `rootVolumeSnapshotUuid` VARCHAR(32) DEFAULT NULL, + `rootVolumeSnapshotTreeUuid` VARCHAR(32) DEFAULT NULL, + `primaryStorageUuid` VARCHAR(32) DEFAULT NULL, + `hostUuid` VARCHAR(32) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `VolumeSnapshotReferenceVO` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `parentId` bigint(20) DEFAULT NULL, + `volumeUuid` varchar(32) DEFAULT NULL, + `volumeSnapshotUuid` varchar(32) DEFAULT NULL, + `directSnapshotUuid` VARCHAR(32) DEFAULT NULL, + `volumeSnapshotInstallUrl` varchar(1024) DEFAULT NULL, + `directSnapshotInstallUrl` VARCHAR(1024) DEFAULT NULL, + `treeUuid` VARCHAR(32) DEFAULT NULL, + `referenceUuid` varchar(32) DEFAULT NULL, + `referenceType` varchar(32) DEFAULT NULL, + `referenceInstallUrl` varchar(1024) DEFAULT NULL, + `referenceVolumeUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + + INDEX `idxVolumeSnapshotReferenceVOVolumeUuid` (`volumeUuid`), + INDEX `idxVolumeSnapshotReferenceVOVolumeSnapshotUuid` (`volumeSnapshotUuid`), + INDEX `idxVolumeSnapshotReferenceVOReferenceUuid` (`referenceUuid`), + CONSTRAINT `fkVolumeSnapshotReferenceReferenceVolumeUuid` FOREIGN KEY (`referenceVolumeUuid`) REFERENCES `VolumeEO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkVolumeSnapshotReferenceReferenceParentId` FOREIGN KEY (`parentId`) REFERENCES `VolumeSnapshotReferenceVO` (`id`) ON DELETE SET NULL, + CONSTRAINT `fkVolumeSnapshotReferenceReferenceTreeUuid` FOREIGN KEY (`treeUuid`) REFERENCES `VolumeSnapshotReferenceTreeVO` (`uuid`) ON DELETE SET NULL +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +DROP PROCEDURE IF EXISTS `Alter_Volume_Snapshot_Tree_Table`; +DELIMITER $$ +CREATE PROCEDURE Alter_Volume_Snapshot_Tree_Table() + BEGIN + IF NOT EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'VolumeSnapshotTreeEO' + AND table_schema = 'zstack' + AND column_name = 'rootImageUuid') THEN + + ALTER TABLE `VolumeSnapshotTreeEO` ADD `rootImageUuid` VARCHAR(32) DEFAULT NULL; + END IF; + END $$ +DELIMITER ; + +CALL Alter_Volume_Snapshot_Tree_Table(); +DROP PROCEDURE Alter_Volume_Snapshot_Tree_Table; + +DROP VIEW IF EXISTS `zstack`.`VolumeSnapshotTreeVO`; +CREATE VIEW `zstack`.`VolumeSnapshotTreeVO` AS SELECT uuid, volumeUuid, rootImageUuid, current, status, createDate, lastOpDate FROM `zstack`.`VolumeSnapshotTreeEO` WHERE deleted IS NULL; + +DROP PROCEDURE IF EXISTS upgradeVolumeSnapshotRefSystemTags; +DELIMITER $$ +CREATE PROCEDURE upgradeVolumeSnapshotRefSystemTags() +BEGIN + DECLARE refTag VARCHAR(51); + DECLARE snapshotUuid VARCHAR(32); + DECLARE snapshotInstallUrl VARCHAR(1024); + DECLARE volUuid VARCHAR(32); + DECLARE refVolumeUuid VARCHAR(32); + DECLARE refVolumeInstallUrl VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT systemTag.tag, systemTag.resourceUuid FROM `zstack`.`SystemTagVO` systemTag where systemTag.tag like 'backingTo::%'; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO refTag, snapshotUuid; + IF done THEN + LEAVE read_loop; + END IF; + + SET refVolumeUuid = SUBSTRING_INDEX(refTag, '::', 2); + SELECT `volumeUuid`, `primaryStorageInstallPath` INTO volUuid, snapshotInstallUrl FROM `VolumeSnapshotVO` WHERE `uuid` = snapshotUuid; + SELECT `installPath` INTO refVolumeInstallUrl FROM `VolumeVO` WHERE `uuid` = refVolumeUuid; + INSERT INTO `VolumeSnapshotReferenceVO` (`volumeUuid`, `volumeSnapshotUuid`, `volumeSnapshotInstallUrl`, `referenceUuid`, `referenceType`, `referenceInstallUrl`, `referenceVolumeUuid`, `lastOpDate`, `createDate`) + VALUES (volUuid, snapshotUuid, snapshotInstallUrl, refVolumeUuid, 'VolumeVO', refVolumeInstallUrl, refVolumeUuid, NOW(), NOW()); + + END LOOP; + CLOSE cur; + SELECT CURTIME(); +END $$ +DELIMITER ; +CALL upgradeVolumeSnapshotRefSystemTags(); + +UPDATE GlobalConfigVO set `value` = 'InfoSec' where `value` = 'infoSec' and category ='encrypt' and name = 'encrypt.driver'; diff --git a/conf/db/upgrade/V4.7.11__schema.sql b/conf/db/upgrade/V4.7.11__schema.sql new file mode 100644 index 00000000000..1f7567b949d --- /dev/null +++ b/conf/db/upgrade/V4.7.11__schema.sql @@ -0,0 +1,53 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`LicenseAppIdRefVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `licenseId` varchar(32) NOT NULL, + `appId` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `interfaceModel` VARCHAR(255) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `vendorId` VARCHAR(64) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `deviceId` VARCHAR(64) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `subvendorId` VARCHAR(64) DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `subdeviceId` VARCHAR(64) DEFAULT NULL; +ALTER TABLE `zstack`.`MonitorGroupTemplateRefVO` + ADD COLUMN `isApplied` boolean not null DEFAULT TRUE; + +CALL DELETE_INDEX('VmNicVO', 'ukVmNicVO'); + +CALL DELETE_INDEX('QuotaVO', 'idxIdentityUuid'); +ALTER TABLE `QuotaVO` ADD INDEX `idxIdentityUuid` (`identityUuid`); + +CREATE TABLE IF NOT EXISTS `zstack`.`HostNetworkInterfaceServiceRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `interfaceUuid` varchar(32) NOT NULL, + `vlanId` int(32) NOT NULL DEFAULT 0, + `serviceType` varchar(128) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkHostNetworkInterfaceServiceRefVOHostNetworkInterfaceVO` FOREIGN KEY (`interfaceUuid`) REFERENCES HostNetworkInterfaceVO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostNetworkBondingServiceRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `bondingUuid` varchar(32) NOT NULL, + `vlanId` int(32) NOT NULL DEFAULT 0, + `serviceType` varchar(128) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkHostNetworkBodnuingServiceRefVOHostNetworkBondingVO` FOREIGN KEY (`bondingUuid`) REFERENCES HostNetworkBondingVO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`VtepVO` ADD COLUMN `physicalInterface` VARCHAR(32) DEFAULT NULL AFTER `poolUuid`; +UPDATE AlarmVO +SET NAME = 'Host Memory Used Capacity Per Host alarm' +WHERE uuid = 'ue0x30t7wfyuba87nwk6ywu3ub5svtwk'; + +CALL CREATE_INDEX('SchedulerJobHistoryVO', 'idxSchedulerJobHistoryVOExecuteTime', 'executeTime'); + +ALTER TABLE `zstack`.`AlarmRecordsVO` + MODIFY COLUMN `resourceUuid` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL AFTER `resourceType`; diff --git a/conf/db/upgrade/V4.7.13__schema.sql b/conf/db/upgrade/V4.7.13__schema.sql new file mode 100644 index 00000000000..7e29e429e01 --- /dev/null +++ b/conf/db/upgrade/V4.7.13__schema.sql @@ -0,0 +1,27 @@ +ALTER TABLE `zstack`.`FlkSecSecretResourcePoolVO` ADD COLUMN `ukeyType` VARCHAR(32) DEFAULT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`BlockVolumeVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `iscsiPath` varchar(1024) NOT NULL, + `vendor` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkBlockVolumeVOVolumeVO FOREIGN KEY (uuid) REFERENCES VolumeEO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`XskyBlockVolumeVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `accessPathId` int NOT NULL, + `accessPathIqn` varchar(128) NOT NULL, + `xskyStatus` varchar(32) NULL, + `xskyBlockVolumeId` int NULL, + `burstTotalBw` bigint NULL, + `burstTotalIops` bigint NULL, + `maxTotalBw` bigint NULL, + `maxTotalIops` bigint NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkXskyBlockVolumeVOBlockVolumeVO FOREIGN KEY (uuid) REFERENCES BlockVolumeVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`BareMetal2BondingNicRefVO` modify column nicUuid varchar(32) DEFAULT NULL; +CALL ADD_COLUMN('BareMetal2BondingNicRefVO', 'provisionNicUuid', 'VARCHAR(32)', 1, NULL); +CALL ADD_CONSTRAINT('BareMetal2BondingNicRefVO', 'fkBareMetal2BondingNicRefVOProvisionNicVO', 'provisionNicUuid', 'BareMetal2InstanceProvisionNicVO', 'uuid', 'CASCADE'); diff --git a/conf/db/upgrade/V4.7.21__schema.sql b/conf/db/upgrade/V4.7.21__schema.sql new file mode 100644 index 00000000000..b1f9f4e6f99 --- /dev/null +++ b/conf/db/upgrade/V4.7.21__schema.sql @@ -0,0 +1,143 @@ +CREATE TABLE `NvmeServerVO` ( + `uuid` VARCHAR(32) NOT NULL, + `name` VARCHAR(256) NOT NULL, + `ip` VARCHAR(64) NOT NULL, + `port` int unsigned DEFAULT 4420, + `transport` VARCHAR(32) NOT NULL, + `state` VARCHAR(32) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `NvmeServerClusterRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `clusterUuid` VARCHAR(32) NOT NULL, + `nvmeServerUuid` VARCHAR(32) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkNvmeServerClusterRefVONvmeServerVO` FOREIGN KEY (`nvmeServerUuid`) REFERENCES NvmeServerVO (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkNvmeServerClusterRefVOClusterEO` FOREIGN KEY (`clusterUuid`) REFERENCES ClusterEO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`NvmeTargetVO` ADD COLUMN `nvmeServerUuid` varchar(32); +ALTER TABLE `zstack`.`NvmeTargetVO` ADD CONSTRAINT `fkNvmeTargetVONvmeServerVO` FOREIGN KEY (nvmeServerUuid) REFERENCES NvmeServerVO(uuid) ON DELETE SET NULL; + +ALTER TABLE `zstack`.`OAuth2ClientVO` ADD COLUMN `userinfoUrl` varchar(256) DEFAULT NULL; +ALTER TABLE `zstack`.`SSOClientVO` ADD COLUMN `redirectUrl` varchar(256) DEFAULT NULL; +ALTER TABLE `zstack`.`OAuth2ClientVO` ADD COLUMN `logoutUrl` varchar(256) DEFAULT NULL; +ALTER TABLE `zstack`.`OAuth2TokenVO` MODIFY COLUMN `accessToken` text DEFAULT NULL; +ALTER TABLE `zstack`.`OAuth2TokenVO` MODIFY COLUMN `idToken` text DEFAULT NULL; +ALTER TABLE `zstack`.`OAuth2TokenVO` MODIFY COLUMN `refreshToken` text DEFAULT NULL; +CALL CREATE_INDEX('SSOTokenVO', 'idxSSOTokenVOUserUuid', 'userUuid'); + +CREATE TABLE IF NOT EXISTS `zstack`.SshKeyPairVO ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(128) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `publicKey` varchar(4096) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`uuid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.SshKeyPairRefVO ( + `id` int(11) NOT NULL UNIQUE AUTO_INCREMENT, + `resourceUuid` varchar(32) NOT NULL, + `sshKeyPairUuid` varchar(32) NOT NULL, + `resourceType` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + CONSTRAINT `fkSshKeyPairRefVOVmInstanceEO` FOREIGN KEY (`resourceUuid`) REFERENCES `ResourceVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkSshKeyPairRefVOSshKey` FOREIGN KEY (`sshKeyPairUuid`) REFERENCES `SshKeyPairVO` (`uuid`) ON DELETE CASCADE, + PRIMARY KEY(`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SnmpAgentVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'uuid', + `version` varchar(32) NOT NULL COMMENT 'snmp authentication version', + `readCommunity` varchar(32) DEFAULT NULL, + `userName` varchar(32) DEFAULT NULL, + `authAlgorithm` varchar(32) DEFAULT NULL, + `authPassword` varchar(32) DEFAULT NULL, + `privacyAlgorithm` varchar(32) DEFAULT NULL, + `privacyPassword` varchar(32) DEFAULT NULL, + `status` varchar(32) NOT NULL COMMENT 'SNMP agent status. status is enable which means start snmp with mn start.', + `port` int(10) DEFAULT NULL, + `securityLevel` varchar(32) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SNSSnmpPlatformVO` +( + `uuid` varchar(32) NOT NULL, + `snmpAddress` varchar(128) NOT NULL, + `snmpPort` smallint unsigned NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + UNIQUE KEY `ukipAddrPort` (`snmpAddress`, `snmpPort`) USING BTREE, + PRIMARY KEY (`uuid`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +DELETE FROM `CpuFeaturesHistoryVO`; + +CREATE TABLE IF NOT EXISTS `zstack`.`RemoteVtepVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `vtepIp` varchar(32) NOT NULL, + `port` int NOT NULL, + `clusterUuid` varchar(32) NOT NULL, + `type` varchar(32) NOT NULL, + `poolUuid` varchar(32) NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT fkRemoteVtepVOClusterEO FOREIGN KEY (clusterUuid) REFERENCES ClusterEO (uuid) ON DELETE CASCADE, + UNIQUE KEY `ukRemoteVtepIpPoolUuidClusterUuid` (`vtepIp`,`poolUuid`,`clusterUuid`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT IGNORE INTO `zstack`.`EncryptEntityMetadataVO` (`entityName`, `columnName`, `state`, `lastOpDate`, `createDate`) + VALUES ('IAM2ProjectAttributeVO', 'value', 'NeedDecrypt', NOW(), NOW()); + +CREATE TABLE IF NOT EXISTS `zstack`.`PrimaryStorageHistoricalUsageBaseVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `primaryStorageUuid` varchar(32) NOT NULL, + `resourceUuid` varchar(32), + `resourceType` varchar(32) NOT NULL, + `totalPhysicalCapacity` bigint unsigned DEFAULT 0, + `usedPhysicalCapacity` bigint unsigned DEFAULT 0, + `recordDate` timestamp DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp DEFAULT '0000-00-00 00:00:00', + CONSTRAINT `fkUsageVOPrimaryStorageEO` FOREIGN KEY (`primaryStorageUuid`) REFERENCES PrimaryStorageEO (`uuid`) ON DELETE CASCADE, + INDEX (primaryStorageUuid), + INDEX (resourceUuid), + INDEX (resourceType), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP VIEW IF EXISTS `zstack`.PrimaryStorageHistoricalUsageVO; +CREATE VIEW `zstack`.`PrimaryStorageHistoricalUsageVO` AS SELECT +id, primaryStorageUuid, resourceType, totalPhysicalCapacity, usedPhysicalCapacity, recordDate, createDate, lastOpDate +FROM `zstack`.`PrimaryStorageHistoricalUsageBaseVO` WHERE resourceType = 'PrimaryStorageVO'; + +DROP VIEW IF EXISTS `zstack`.CephOsdGroupHistoricalUsageVO; +CREATE VIEW `zstack`.`CephOsdGroupHistoricalUsageVO` AS SELECT +id, primaryStorageUuid, resourceUuid as osdGroupUuid, resourceType, totalPhysicalCapacity, usedPhysicalCapacity, recordDate, createDate, lastOpDate +FROM `zstack`.`PrimaryStorageHistoricalUsageBaseVO` WHERE resourceType = 'CephOsdGroupVO'; + +DROP VIEW IF EXISTS `zstack`.LocalStorageHostHistoricalUsageVO; +CREATE VIEW `zstack`.`LocalStorageHostHistoricalUsageVO` AS SELECT +id, primaryStorageUuid, resourceUuid as hostUuid, resourceType, totalPhysicalCapacity, usedPhysicalCapacity, recordDate, createDate, lastOpDate +FROM `zstack`.`PrimaryStorageHistoricalUsageBaseVO` WHERE resourceType = 'LocalStorageHostRefVO'; + +ALTER TABLE `zstack`.`InstanceOfferingEO` ADD COLUMN `reservedMemorySize` bigint unsigned DEFAULT 0; +ALTER TABLE `zstack`.`VmInstanceEO` ADD COLUMN `reservedMemorySize` bigint unsigned DEFAULT 0; + +DROP VIEW IF EXISTS `zstack`.`VmInstanceVO`; +CREATE VIEW `zstack`.`VmInstanceVO` AS SELECT uuid, name, description, zoneUuid, clusterUuid, imageUuid, hostUuid, internalId, lastHostUuid, instanceOfferingUuid, rootVolumeUuid, defaultL3NetworkUuid, type, hypervisorType, cpuNum, cpuSpeed, memorySize, reservedMemorySize, platform, guestOsType, allocatorStrategy, createDate, lastOpDate, state, architecture FROM `zstack`.`VmInstanceEO` WHERE deleted IS NULL; +DROP VIEW IF EXISTS `zstack`.`InstanceOfferingVO`; +CREATE VIEW `zstack`.`InstanceOfferingVO` AS SELECT uuid, name, description, cpuNum, cpuSpeed, memorySize, reservedMemorySize, allocatorStrategy, sortKey, state, createDate, lastOpDate, type, duration FROM `zstack`.`InstanceOfferingEO` WHERE deleted IS NULL; diff --git a/conf/db/upgrade/V4.8.0.2__schema.sql b/conf/db/upgrade/V4.8.0.2__schema.sql new file mode 100644 index 00000000000..31a5c88bc50 --- /dev/null +++ b/conf/db/upgrade/V4.8.0.2__schema.sql @@ -0,0 +1,11 @@ +-- in version zsv_4.1.6 + +ALTER TABLE AuditsVO ADD COLUMN `resourceName` varchar(255) DEFAULT NULL; + +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `deviceName` VARCHAR(64) DEFAULT NULL AFTER `deviceId`; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `vendorName` VARCHAR(64) DEFAULT NULL AFTER `deviceName`; +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `subvendorName` VARCHAR(64) DEFAULT NULL AFTER `subdeviceId`; + +-- from issue: (feature) ZSV-4408 +ALTER TABLE `zstack`.`VmSchedHistoryVO` ADD COLUMN `schedReason` text DEFAULT NULL; +ALTER TABLE `zstack`.`VmSchedHistoryVO` ADD COLUMN `failReason` text DEFAULT NULL; diff --git a/conf/db/upgrade/V4.8.0.3__schema.sql b/conf/db/upgrade/V4.8.0.3__schema.sql new file mode 100644 index 00000000000..18f3ff5fd93 --- /dev/null +++ b/conf/db/upgrade/V4.8.0.3__schema.sql @@ -0,0 +1,31 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`HostNetworkInterfaceLldpVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `interfaceUuid` varchar(32) NOT NULL UNIQUE, + `mode` varchar(32) NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHostNetworkInterfaceLldpVOHostNetworkInterfaceVO` FOREIGN KEY (`interfaceUuid`) REFERENCES HostNetworkInterfaceVO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostNetworkInterfaceLldpRefVO` ( + `lldpUuid` varchar(32) NOT NULL, + `chassisId` varchar(32) NOT NULL, + `timeToLive` int(32) NOT NULL, + `managementAddress` varchar(32) DEFAULT NULL, + `systemName` varchar(32) NOT NULL, + `systemDescription` varchar(255) NOT NULL, + `systemCapabilities` varchar(32) NOT NULL, + `portId` varchar(32) NOT NULL, + `portDescription` varchar(255) DEFAULT NULL, + `vlanId` int(32) DEFAULT NULL, + `aggregationPortId` bigint unsigned DEFAULT NULL, + `mtu` varchar(128) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`lldpUuid`), + CONSTRAINT `fkHostNetworkInterfaceLldpRefVOHostNetworkInterfaceLldpVO` FOREIGN KEY (`lldpUuid`) REFERENCES HostNetworkInterfaceLldpVO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT IGNORE INTO `zstack`.`HostNetworkInterfaceLldpVO` (`uuid`, `interfaceUuid`, `mode`, `createDate`, `lastOpDate`) +SELECT REPLACE(UUID(),'-',''), t.uuid, 'rx_only', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP() FROM `zstack`.`HostNetworkInterfaceVO` t; \ No newline at end of file diff --git a/conf/db/upgrade/V4.8.0.6__schema.sql b/conf/db/upgrade/V4.8.0.6__schema.sql new file mode 100644 index 00000000000..5546e3de871 --- /dev/null +++ b/conf/db/upgrade/V4.8.0.6__schema.sql @@ -0,0 +1,8 @@ +ALTER TABLE `zstack`.`L2NetworkEO` ADD COLUMN `isolated` boolean NOT NULL DEFAULT FALSE AFTER `virtualNetworkId`; +ALTER TABLE `zstack`.`L2NetworkEO` ADD COLUMN `pvlan` varchar(128) DEFAULT NULL AFTER `virtualNetworkId`; +DROP VIEW IF EXISTS `zstack`.L2NetworkVO; +CREATE VIEW `zstack`.`L2NetworkVO` AS SELECT uuid, name, description, type, vSwitchType, virtualNetworkId, zoneUuid, physicalInterface, isolated, pvlan, createDate, lastOpDate FROM `zstack`.`L2NetworkEO` WHERE deleted IS NULL; + +ALTER TABLE `zstack`.`L3NetworkEO` ADD COLUMN `isolated` boolean NOT NULL DEFAULT FALSE AFTER `enableIPAM`; +DROP VIEW IF EXISTS `zstack`.`L3NetworkVO`; +CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, description, state, type, zoneUuid, l2NetworkUuid, `system`, dnsDomain, createDate, lastOpDate, category, ipVersion, enableIPAM, isolated FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; \ No newline at end of file diff --git a/conf/db/upgrade/V4.8.0__schema.sql b/conf/db/upgrade/V4.8.0__schema.sql new file mode 100644 index 00000000000..191c25da599 --- /dev/null +++ b/conf/db/upgrade/V4.8.0__schema.sql @@ -0,0 +1,198 @@ +DROP PROCEDURE IF EXISTS AddFkPciDeviceVOVmInstanceEO; +DELIMITER $$ +CREATE PROCEDURE AddFkPciDeviceVOVmInstanceEO() +BEGIN + IF (SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = 'PciDeviceVO' AND CONSTRAINT_NAME = 'fkPciDeviceVOVmInstanceEO') = 0 THEN +ALTER TABLE PciDeviceVO + ADD CONSTRAINT fkPciDeviceVOVmInstanceEO FOREIGN KEY (vmInstanceUuid) REFERENCES VmInstanceEO(uuid) ON DELETE SET NULL; +END IF; +END $$ +DELIMITER ; +CALL AddFkPciDeviceVOVmInstanceEO(); + +update AlarmVO set name = 'Monitor IP Unreachable' where uuid='065f9609dce141bb952c80f729f58af4'; +update EventSubscriptionVO set name = 'Management Node Connected' where uuid='10d9c4e69fc2456bb8c6c6d456bb5038'; +update EventSubscriptionVO set name = 'SMS Message Sending Failed' where uuid='14a991d4d7d54a66b14e398ffc510bd6'; +update EventSubscriptionVO set name = 'Host Connected' where uuid='1a7a3eb433904df89f5c42a1fa4e0716'; +update EventSubscriptionVO set name = 'VPC vRouter Disk Space is Occupied by Abnormal Files' where uuid='33de14ed204948daa850f9b9a3a02e89'; +update AlarmVO set name = 'VPC vRouter CPU Utilization Average' where uuid='369eef54655548eab2a4d2d7ef061c79'; +update EventSubscriptionVO set name = 'VPC vRouter Connected' where uuid='39d2b6689efa4e4a96c239716cb6f3ea'; +update AlarmVO set name = 'Backup Storage Available Capacity' where uuid='44e6f054a59a451fb1b535accff64fc2'; +update EventSubscriptionVO set name = 'CDP Task Status Abnormally Changed' where uuid='47388fa83669736d6ed8776d7ed384g4'; +update EventSubscriptionVO set name = 'NIC IP Configured in VM Instance Has Been Occupied on Cloud (GuestTools Required)' where uuid='4a3494bcdbac4eaab9e9e56e27d74a2a'; +update EventSubscriptionVO set name = 'Host Disconnected' where uuid='4a3cb114b10d41e19545ab693222c134'; +update EventSubscriptionVO set name = 'Backup Storage Connected' where uuid='55365763fed244c39b4642bef6c5daf9'; +update EventSubscriptionVO set name = 'QEMU Version of Hosts in Cluster Needs to be Updated' where uuid='559ca06aa8bba6990d10c255e4c9ab5b'; +update AlarmVO set name = 'VPC vRouter Memory Percent Used' where uuid='582ea79cb57d45a8bfd4d2030244c1c4'; +update AlarmVO set name = 'Host Root Volume Utilization' where uuid='5d3bb9d271a349b283893317f531f723'; +update EventSubscriptionVO set name = 'Primary Storage Disconnected' where uuid='5e75230bd2ea4f47abf6ff92fa816a20'; +update AlarmVO set name = 'Average CPU Utilization of Hosts' where uuid='5z6gsgkc5kccpylj9ocgbd647p2700b7'; +update AlarmVO set name = 'License Expiration' where uuid='65e8f1a4892231b692cc7a881581f3da'; +update AlarmVO set name = 'CDP Task RPO Latency' where uuid='66898fa836694f7665d49b74dedf7631'; +update AlarmVO set name = 'Primary Storage Available Capacity' where uuid='66dfdee6fd314aac96ca3779774ad977'; +update EventSubscriptionVO set name = 'VM HA Started On Host' where uuid='6nz3vn2e0rdwu5hzmuetzv37ak0nj248'; +update AlarmVO set name = 'Dual Management Node Database Needs Synchronization' where uuid='712c3dec6aa94ed2b3bcd32192c22f69'; +update AlarmVO set name = 'Capacity Used by CDP Task' where uuid='78898fa836694f769ed89b74ded006f1'; +update EventSubscriptionVO set name = 'LB Instance Disk Space is Occupied by Abnormal Files' where uuid='79b0dad6607a429cb235ad2f701718a0'; +update EventSubscriptionVO set name = 'LB Instance Disconnected' where uuid='842e20d7d9844ee3a3c2a4224235a7df'; +update EventSubscriptionVO set name = 'Management Node Disconnected' where uuid='8eca1096feb34419913087d2b281ecec'; +update EventSubscriptionVO set name = 'Failed to Detect Connection Between Primary Storage and Host' where uuid='8tlwqj65mus1gdolu3w61yy35pvwinhz'; +update EventSubscriptionVO set name = 'VM NIC IP Changed (GuestTools Required)' where uuid='98536fa94e3f4481a38331a989132b7c'; +update EventSubscriptionVO set name = 'Backup Storage Disconnected' where uuid='98f9c802604e4852bd84716f66cf4f73'; +update EventSubscriptionVO set name = 'CDP Task Failed' where uuid='98h262f95c1987fg2ba1be4a3562765f'; +update EventSubscriptionVO set name = 'Host NIC Disconnected' where uuid='9a593ad138bf44138b72e0f0dd989f27'; +update EventSubscriptionVO set name = 'VM Crashed' where uuid='a391bb01fd954ed3b6c0569ecc7b5764'; +update EventSubscriptionVO set name = 'VPC vRouter State Changed to Paused' where uuid='a3d9fd893fbb4468867a7880b6b91ba6'; +update AlarmVO set name = 'System Data Directory Disk Capacity' where uuid='b632652cc16044cdb6b4f516ed93a118'; +update EventSubscriptionVO set name = 'VPC vRouter Failover' where uuid='bd0163e7028644a5b482534c2711d2d9'; +update AlarmVO set name = 'Host Memory Utilization' where uuid='d0b35ac37c58e358cb74e664532f1044'; +update EventSubscriptionVO set name = 'Host NIC Connected' where uuid='d1d122f95c194c958ba1be4a3568ebd0'; +update EventSubscriptionVO set name = 'VPC vRouter Disconnected' where uuid='d59397479d2548d7abfe4ad31a575390'; +update AlarmVO set name = 'Primary Storage Available Physical Capacity' where uuid='ded02f9786444c6296e9bc3efb8eb484'; +update EventSubscriptionVO set name = 'VM Host Abnormally Changed' where uuid='eccfc93109cd4c71b56a2612d84a2773'; +update EventSubscriptionVO set name = 'LB Instance Connected' where uuid='eef29da3aff8486093d6afabb05cddbf'; +update AlarmVO set name = 'VPC vRouter Disk Capacity Percent Used Sum' where uuid='f3389a28b7d64e35875992d254ff4f96'; +update EventSubscriptionVO set name = 'Primary Storage Connected' where uuid='f56795b8c34b452f84bcf25cb89bded2'; +update AlarmVO set name = 'VM Memory Utilization' where uuid='fuz2p4fa71urf4fd7cknoxsalvj60ynk'; +update EventSubscriptionVO set name = 'Host Mount Path Faulted' where uuid='g0eviogong06nubt1kj54z63pcka81sw'; +update EventSubscriptionVO set name = 'VM Migration Failed as Host in Maintenance Mode' where uuid='krdu1hs2314kt18ttgqndaynxchs2ufc'; +update EventSubscriptionVO set name = 'VM in Shutdown State for a Long Time' where uuid='ppfazo1y3tjvup4jfetxz36y3su98ngc'; +update EventSubscriptionVO set name = 'Unknown VM Detected On Host' where uuid='rlwalvvqyoujj3ign3o309p2zulwbhwm'; +update AlarmVO set name = 'Host Memory Used Capacity Per Host alarm' where uuid='ue0x30t7wfyuba87nwk6ywu3ub5svtwk'; +update AlarmVO set name = 'Average CPU Utilization of VM Instances' where uuid='uhgfoh0soh6e1qai005elfa9c6h2s2y0'; +update EventSubscriptionVO set name = 'HSM Exception Notification' where uuid='d3ba391bb01fd954eecc7b576c056964'; +update EventSubscriptionVO set name = '3rd-Party Cryptographic Service Error' where uuid='eecc7b576c05391bb01fd956964d3ba4'; + +update AlarmVO set name = 'CPU Temperature' where uuid = '10908b6b7b8741139a5efc2b1d461a16'; +update AlarmVO set name = 'SSD Remaining Life Expectancy' where uuid = 'a3905b37d5e8477dbe0fb75a30b8f21c'; +update AlarmVO set name = 'SSD Temperature' where uuid = '33198a88f22e4d19b5ff8ebaebb6ujm7'; +update EventSubscriptionVO set name = 'Host Physical Memory Ecc Error Triggered' where uuid = '258ac24eba3443dea73cbcb7758e6759'; +update EventSubscriptionVO set name = 'Host Physical Memory Status Abnormal' where uuid = '03c7c6a8ab4f492bbe06c8b03ba25f27'; +update EventSubscriptionVO set name = 'Host Physical Disk Remove Triggered' where uuid = '226da68a97b94b7f9f918f8ac7138873'; +update EventSubscriptionVO set name = 'Host Physical Disk Insert Triggered' where uuid = '4c230269620e4e739ebc5ab2a6b0f0a4'; +update EventSubscriptionVO set name = 'Host Physical Disk Status Abnormal' where uuid = '4b04f06e4ba24231ad67bd6f06093ba2'; +update EventSubscriptionVO set name = 'Host Physical Cpu Status Abnormal' where uuid = '8186fbbeab1d449b93e7be78d6045c7f'; +update EventSubscriptionVO set name = 'Host Physical Fan Status Abnormal' where uuid = '37e5bdfa2eaf49538931113ddaecf927'; + +CALL ADD_COLUMN('VmNicVO', 'state', 'varchar(255)', 0, 'enable'); + +CREATE TABLE IF NOT EXISTS `zstack`.`BlockPrimaryStorageHostRefVO` ( + `id` BIGINT UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, + `initiatorName` varchar(256) DEFAULT NULL, + `metadata` text DEFAULT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fkBlockPrimaryStorageHostRefVOPrimaryStorageHostRefVO` FOREIGN KEY (`id`) REFERENCES `zstack`.`PrimaryStorageHostRefVO` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL DROP_COLUMN('BlockPrimaryStorageVO', 'encryptGatewayIp'); +CALL DROP_COLUMN('BlockPrimaryStorageVO', 'encryptGatewayPort'); +CALL DROP_COLUMN('BlockPrimaryStorageVO', 'encryptGatewayUsername'); +CALL DROP_COLUMN('BlockPrimaryStorageVO', 'encryptGatewayPassword'); +CALL DROP_COLUMN('BlockScsiLunVO', 'type'); + +DROP PROCEDURE IF EXISTS `AlterBlockScsiLunTable`; +DELIMITER $$ +CREATE PROCEDURE AlterBlockScsiLunTable() + BEGIN + IF EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'BlockScsiLunVO' + AND table_schema = 'zstack' + AND column_name = 'id' + AND column_type like 'smallint%') THEN + ALTER TABLE `zstack`.`BlockScsiLunVO` MODIFY COLUMN `id` int unsigned default 0; + END IF; + IF EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'BlockScsiLunVO' + AND table_schema = 'zstack' + AND column_name = 'lunType' + AND is_nullable = 'NO') THEN + ALTER TABLE `zstack`.`BlockScsiLunVO` MODIFY COLUMN lunType varchar(256) DEFAULT NULL; + END IF; + IF EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'BlockScsiLunVO' + AND table_schema = 'zstack' + AND column_name = 'lunMapId' + AND column_type like 'smallint%') THEN + ALTER TABLE `zstack`.`BlockScsiLunVO` MODIFY COLUMN `lunMapId` int unsigned default 0; + END IF; + END $$ +DELIMITER ; +call AlterBlockScsiLunTable; +DROP PROCEDURE IF EXISTS `AlterBlockScsiLunTable`; + +DELIMITER $$ +CREATE PROCEDURE checkAllBlockHostInPrimaryHostRef() + BEGIN + DECLARE hostUuid VARCHAR(32); + DECLARE primaryStorageUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT hiref.hostUuid, hiref.primaryStorageUuid FROM HostInitiatorRefVO hiref; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN cur; + read_loop: LOOP + FETCH cur INTO hostUuid, primaryStorageUuid; + IF done THEN + LEAVE read_loop; + END IF; + IF (select count(*) from PrimaryStorageHostRefVO pshref where pshref.hostUuid = hostUuid and pshref.primaryStorageUuid = primaryStorageUuid) = 0 THEN + BEGIN + INSERT INTO zstack.PrimaryStorageHostRefVO (`primaryStorageUuid`, `hostUuid`, `status`, `lastOpDate`, `createDate`) values (primaryStorageUuid, hostUuid, 'Disconnected', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + END; + END IF; + END LOOP; + CLOSE cur; + SELECT CURTIME(); + END $$ +DELIMITER ; + +DELIMITER $$ +CREATE PROCEDURE migrateBlockPrimaryHostRef() + BEGIN + DECLARE initiatorName VARCHAR(256); + DECLARE psId BIGINT(20); + DECLARE metadata text; + DECLARE psUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT hostInitiatorRef.initiatorName, hostInitiatorRef.metadata, primaryStorageHostRef.id + FROM zstack.HostInitiatorRefVO hostInitiatorRef, zstack.PrimaryStorageHostRefVO primaryStorageHostRef + where hostInitiatorRef.hostUuid = primaryStorageHostRef.hostUuid and hostInitiatorRef.primaryStorageUuid = primaryStorageHostRef.primaryStorageUuid; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done =TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO initiatorName, metadata, psId; + IF done THEN + LEAVE read_loop; + END IF; + IF (select count(*) from BlockPrimaryStorageHostRefVO bpshref where id = psId) = 0 THEN + BEGIN + INSERT INTO zstack.BlockPrimaryStorageHostRefVO(id, initiatorName, metadata) values(psId, initiatorName, metadata); + END; + END IF; + END LOOP; + CLOSE cur; + SELECT CURTIME(); + END $$ +DELIMITER ; + +DELIMITER $$ +CREATE PROCEDURE checkHostInitiatorRefVO() + BEGIN + IF (SELECT count(*) FROM information_schema.columns WHERE table_name = 'HostInitiatorRefVO' AND column_name = 'primaryStorageUuid') != 0 THEN + call checkAllBlockHostInPrimaryHostRef(); + call migrateBlockPrimaryHostRef(); + END IF; + END $$ +DELIMITER ; +call checkHostInitiatorRefVO(); +DROP PROCEDURE IF EXISTS migrateBlockPrimaryHostRef; +DROP PROCEDURE IF EXISTS checkAllBlockHostInPrimaryHostRef; +DROP PROCEDURE IF EXISTS checkHostInitiatorRefVO; +DROP TABLE IF EXISTS HostInitiatorRefVO; + +UPDATE ResourceConfigVO SET createDate = CURRENT_TIMESTAMP where name='iam2.force.enable.securityGroup' and createDate='0000-00-00 00:00:00'; + +update AlarmLabelVO set value='/var/lib/zstack/' where alarmUuid='b632652cc16044cdb6b4f516ed93a118' and value='/var/lib/zstack'; \ No newline at end of file diff --git a/conf/db/upgrade/V5.0.0__schema.sql b/conf/db/upgrade/V5.0.0__schema.sql new file mode 100644 index 00000000000..ea0063e493c --- /dev/null +++ b/conf/db/upgrade/V5.0.0__schema.sql @@ -0,0 +1,125 @@ +UPDATE ImageEO SET md5sum = NULL where md5sum != 'not calculated'; + +ALTER TABLE `zstack`.`LoadBalancerVO` DROP FOREIGN KEY `fkLoadBalancerVOVipVO`; +ALTER TABLE `zstack`.`LoadBalancerVO` MODIFY COLUMN vipUuid varchar(32) DEFAULT NULL; +ALTER TABLE `zstack`.`LoadBalancerVO` ADD CONSTRAINT `fkLoadBalancerVOVipVO` FOREIGN KEY (`vipUuid`) REFERENCES `zstack`.`VipVO` (`uuid`) ON DELETE SET NULL; + +ALTER TABLE `zstack`.`LoadBalancerVO` ADD COLUMN `ipv6VipUuid` varchar(32) DEFAULT null; +ALTER TABLE `zstack`.`LoadBalancerVO` ADD CONSTRAINT `fkLoadBalancerVOIpv6VipVO` FOREIGN KEY (`ipv6VipUuid`) REFERENCES `zstack`.`VipVO` (`uuid`) ON DELETE SET NULL; + +ALTER TABLE `zstack`.`LoadBalancerServerGroupVmNicRefVO` ADD COLUMN `ipVersion` int(10) unsigned DEFAULT 4; + +UPDATE `zstack`.`VipVO` SET `system` = 0 where `uuid` in (select lb.vipUuid from `zstack`.`LoadBalancerVO` lb, `zstack`.`SlbLoadBalancerVO` slb where lb.uuid = slb.uuid); + +update EventSubscriptionVO set name = 'Host Hardware Changed' where uuid = '829d96de006043c3b34202861ca82078'; + +CREATE TABLE `zstack`.`SNSWeComEndpointVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `url` varchar(1024) NOT NULL, + `atAll` int(1) unsigned NOT NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `zstack`.`SNSWeComAtPersonVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `userId` varchar(64) NOT NULL, + `endpointUuid` varchar(32) NOT NULL, + `remark` varchar(128) default '' null, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `zstack`.`SNSFeiShuEndpointVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `url` varchar(1024) NOT NULL, + `atAll` int(1) unsigned NOT NULL, + `secret` varchar(128) default '' null, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `zstack`.`SNSFeiShuAtPersonVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `userId` varchar(64) NOT NULL, + `endpointUuid` varchar(32) NOT NULL, + `remark` varchar(128) default '' null, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +alter table SNSDingTalkEndpointVO + add secret varchar(128) default '' null; + +alter table SNSDingTalkAtPersonVO + add lastOpDate timestamp ON UPDATE CURRENT_TIMESTAMP; + +alter table SNSDingTalkAtPersonVO + add createDate timestamp NULL DEFAULT '0000-00-00 00:00:00'; + +UPDATE SNSDingTalkAtPersonVO +SET createDate = CURRENT_TIMESTAMP, + lastOpDate = CURRENT_TIMESTAMP; + +alter table SNSDingTalkAtPersonVO + add remark varchar(128) default '' null; + +CREATE TABLE IF NOT EXISTS `zstack`.`EthernetVfPciDeviceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `hostDevUuid` varchar(32) DEFAULT NULL, + `interfaceName` varchar(32) DEFAULT NULL, + `vmUuid` varchar(32) DEFAULT NULL, + `l3NetworkUuid` varchar(32) DEFAULT NULL, + `vfStatus` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkEthernetVfPciDeviceVOVmInstanceEO` FOREIGN KEY (`vmUuid`) REFERENCES `VmInstanceEO` (`uuid`) ON DELETE SET NULL, + CONSTRAINT `fkEthernetVfPciDeviceVOHostEO` FOREIGN KEY (`hostDevUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkEthernetVfPciDeviceVO` FOREIGN KEY (`uuid`) REFERENCES `PciDeviceVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkEthernetVfPciDeviceVOL3NetworkEO` FOREIGN KEY (`l3NetworkUuid`) REFERENCES `L3NetworkEO` (`uuid`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE ConsoleProxyVO ADD COLUMN `expiredDate` timestamp NOT NULL; + +delete from EncryptEntityMetadataVO where entityName = 'IAM2VirtualIDVO' and state = 'NeedDecrypt'; + +ALTER TABLE `SecretResourcePoolVO` ADD COLUMN `ability` varchar(256) NOT NULL DEFAULT 'All'; + +CREATE TABLE IF NOT EXISTS `zstack`.`JitSecurityMachineVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `port` int unsigned NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkJitSecurityMachineVOSecurityMachineVO FOREIGN KEY (uuid) REFERENCES SecurityMachineVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`AgentVersionVO` ADD CONSTRAINT fkAgentVersionVOResourceVO FOREIGN KEY (uuid) REFERENCES ResourceVO (uuid) ON DELETE CASCADE; + +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` ADD COLUMN `virtStatus` VARCHAR(32) DEFAULT NULL AFTER `offloadStatus`; + +CREATE TABLE IF NOT EXISTS `zstack`.`ExternalPrimaryStorageVO` ( + `uuid` varchar(32) NOT NULL, + `identity` varchar(32) NOT NULL, + `config` varchar(255) DEFAULT NULL, + `password` varchar(255) DEFAULT NULL, + `addonInfo` varchar(2048) DEFAULT NULL, + `defaultProtocol` varchar(255) NOT NULL, + PRIMARY KEY (`uuid`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`PrimaryStorageOutputProtocolRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `primaryStorageUuid` varchar(32) NOT NULL, + `outputProtocol` varchar(255) NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + CONSTRAINT `fkPrimaryStorageOutputProtocolRefVOExternalPrimaryStorageVO` FOREIGN KEY (`primaryStorageUuid`) REFERENCES ExternalPrimaryStorageVO (`uuid`) ON DELETE CASCADE +) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +ALTER TABLE VolumeEO ADD COLUMN protocol VARCHAR(32) DEFAULT NULL; + +DROP VIEW IF EXISTS `zstack`.`VolumeVO`; +CREATE VIEW `zstack`.`VolumeVO` AS SELECT uuid, name, description, primaryStorageUuid, vmInstanceUuid, diskOfferingUuid, + rootImageUuid, installPath, type, status, size, actualSize, deviceId, format, state, createDate, lastOpDate, + isShareable, volumeQos, lastVmInstanceUuid, lastDetachDate, lastAttachDate, protocol FROM `zstack`.`VolumeEO` WHERE deleted IS NULL; + +ALTER TABLE VmCdRomVO ADD COLUMN protocol VARCHAR(32) DEFAULT NULL; diff --git a/conf/db/upgrade/V5.1.0__schema.sql b/conf/db/upgrade/V5.1.0__schema.sql new file mode 100644 index 00000000000..484cfc9d0bd --- /dev/null +++ b/conf/db/upgrade/V5.1.0__schema.sql @@ -0,0 +1,68 @@ +DELETE FROM `SystemTagVO` WHERE `resourceUuid` IN (SELECT uuid FROM HostCapacityVO WHERE cpuSockets != 1) AND tag LIKE "cpuProcessorNum::%"; + +CREATE TABLE IF NOT EXISTS `zstack`.`SlbGroupMonitorIpVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `slbGroupUuid` varchar(32) NOT NULL, + `monitorIp` varchar(128) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkSlbGroupConfigTaskVOSlbGroupVO` FOREIGN KEY (`slbGroupUuid`) REFERENCES `SlbGroupVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SlbVmInstanceConfigTaskVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `vmInstanceUuid` varchar(32) NOT NULL, + `configVersion` bigint unsigned DEFAULT 0 UNIQUE, + `taskName` varchar(32) NOT NULL, + `taskData` text NOT NULL, + `lastFailedReason` varchar(1024) NOT NULL, + `retryNumber` bigint unsigned DEFAULT 0, + `status` varchar(32) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkSlbVmInstanceConfigTaskVOSlbVmInstanceVO` FOREIGN KEY (`vmInstanceUuid`) REFERENCES `SlbVmInstanceVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`SlbGroupVO` ADD COLUMN `configVersion` bigint unsigned DEFAULT 0; +ALTER TABLE `zstack`.`SlbVmInstanceVO` ADD COLUMN `configVersion` bigint unsigned DEFAULT 0; +UPDATE `zstack`.`SlbGroupVO` SET deployType = "NoHA"; + +ALTER TABLE `zstack`.`LoadBalancerServerGroupVO` ADD COLUMN `ipVersion` int(10) unsigned NOT NULL DEFAULT 4 AFTER `loadBalancerUuid`; +UPDATE `zstack`.`VipVO` set serviceProvider='SLB' where uuid in (select vipUuid from LoadBalancerVO where type='SLB'); +UPDATE `zstack`.`VipVO` set serviceProvider='SLB' where uuid in (select ipv6VipUuid from LoadBalancerVO where type='SLB'); + +ALTER TABLE `zstack`.`VmVfNicVO` ADD COLUMN `haState` varchar(32) NOT NULL DEFAULT "Disabled" AFTER `pciDeviceUuid`; + +CREATE TABLE IF NOT EXISTS `zstack`.`VpcSharedQosVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(255) DEFAULT NULL, + `l3NetworkUuid` varchar(32) NOT NULL, + `vpcUuid` varchar(32) DEFAULT NULL, + `bandwidth` bigint unsigned, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT fkVpcSharedQosVOL3NetworkEO FOREIGN KEY (l3NetworkUuid) REFERENCES L3NetworkEO (uuid) ON DELETE CASCADE, + CONSTRAINT fkVpcSharedQosVOApplianceVmVO FOREIGN KEY (vpcUuid) REFERENCES ApplianceVmVO (uuid) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`VpcSharedQosRefVipVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `sharedQosUuid` varchar(32) NOT NULL, + `vipUuid` varchar(32) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT fkVpcSharedQosRefVipVOVpcSharedQosVO FOREIGN KEY (sharedQosUuid) REFERENCES VpcSharedQosVO (uuid) ON DELETE CASCADE, + CONSTRAINT fkVpcSharedQosRefVipVOVipVO FOREIGN KEY (vipUuid) REFERENCES VipVO (uuid) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ExponBlockVolumeVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `exponStatus` varchar(32) NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkExponBlockVolumeVOBlockVolumeVO FOREIGN KEY (uuid) REFERENCES BlockVolumeVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V5.1.19__schema.sql b/conf/db/upgrade/V5.1.19__schema.sql new file mode 100644 index 00000000000..44a1030ae40 --- /dev/null +++ b/conf/db/upgrade/V5.1.19__schema.sql @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`SSOServerTokenVO`( + `uuid` varchar(32) not null unique, + `accessToken` text DEFAULT NULL, + `idToken` text DEFAULT NULL, + `refreshToken` text DEFAULT NULL, + `userUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V5.1.20__schema.sql b/conf/db/upgrade/V5.1.20__schema.sql new file mode 100644 index 00000000000..a4a9aa3c531 --- /dev/null +++ b/conf/db/upgrade/V5.1.20__schema.sql @@ -0,0 +1,44 @@ +ALTER TABLE `zstack`.`ModelCenterVO` ADD COLUMN containerStorageNetwork varchar(2048) DEFAULT NULL; +ALTER TABLE `zstack`.`ModelServiceInstanceVO` ADD COLUMN internalUrl varchar(2048) DEFAULT NULL; +ALTER TABLE `zstack`.`ModelServiceInstanceVO` ADD COLUMN k8sResourceYaml mediumtext DEFAULT NULL; +ALTER TABLE `zstack`.`ModelServiceInstanceVO` ADD COLUMN urlMaps mediumtext DEFAULT NULL; + +DROP PROCEDURE IF EXISTS UpdateK8sResourceYaml; +DELIMITER // +CREATE PROCEDURE UpdateK8sResourceYaml() +BEGIN + -- 开始事务 + START TRANSACTION; + + UPDATE ModelServiceInstanceVO + SET k8sResourceYaml = yaml + WHERE vmInstanceUuid IS NULL AND k8sResourceYaml IS NULL AND yaml IS NOT NULL; + + -- 提交事务 + COMMIT; +END // +DELIMITER ; +CALL UpdateK8sResourceYaml(); + +CREATE TABLE IF NOT EXISTS `zstack`.`ApplicationDevelopmentServiceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NULL, + `modelServiceGroupUuid` varchar(32) NULL, + `modelServiceUuid` varchar(32) NULL, + `deploymentStatus` varchar(255) NOT NULL, + CONSTRAINT fkApplicationDevelopmentServiceVOModelServiceGroupVO FOREIGN KEY (modelServiceGroupUuid) REFERENCES ModelServiceInstanceGroupVO (uuid) ON DELETE SET NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelCenterCapacityVO` ( + `uuid` varchar(32) NOT NULL, + `modelUsedCapacity` bigint NULL, + `modelServiceUsedCapacity` bigint NULL, + `datasetUsedCapacity` bigint NULL, + `fineTuneUsedCapacity` bigint NULL, + `modelEvaluationUsedCapacity` bigint NULL, + `installationUsedCapacity` bigint NULL, + `temporaryUsedCapacity` bigint NULL, + `cacheUsedCapacity` bigint NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V5.1.4__schema.sql b/conf/db/upgrade/V5.1.4__schema.sql new file mode 100644 index 00000000000..9e40ddae1c2 --- /dev/null +++ b/conf/db/upgrade/V5.1.4__schema.sql @@ -0,0 +1,3 @@ +ALTER TABLE `zstack`.`OAuth2ClientVO` ADD COLUMN `scope` varchar(255) default 'openid'; + +ALTER TABLE `zstack`.`OAuth2ClientVO` ADD COLUMN `identityProvider` varchar(32) default 'default'; \ No newline at end of file diff --git a/conf/db/upgrade/V5.1.8.1__schema.sql b/conf/db/upgrade/V5.1.8.1__schema.sql new file mode 100644 index 00000000000..175e60beae7 --- /dev/null +++ b/conf/db/upgrade/V5.1.8.1__schema.sql @@ -0,0 +1,232 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`ModelCenterVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(128) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `url` varchar(2048) DEFAULT NULL, + `parameters` varchar(128) DEFAULT NULL, + `status` varchar(255) NOT NULL, + `managementIp` varchar(128) NOT NULL, + `managementPort` int(16) not NULL, + `storageNetworkUuid` varchar(32) DEFAULT NULL, + `serviceNetworkUuid` varchar(32) DEFAULT NULL, + `containerRegistry` varchar(2048) DEFAULT NULL, + `containerNetwork` varchar(2048) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `modelCenterUuid` varchar(32) NOT NULL, + `parameters` mediumtext DEFAULT NULL, + `installPath` varchar(2048) DEFAULT NULL, + `introduction` mediumtext DEFAULT NULL, + `logo` mediumtext DEFAULT NULL, + `version` varchar(255) DEFAULT NULL, + `vendor` varchar(255) DEFAULT NULL, + `type` varchar(32) NOT NULL, + `size` bigint(20) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT fkModelVOModelCenterVO FOREIGN KEY (modelCenterUuid) REFERENCES ModelCenterVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `type` varchar(32) NOT NULL, + `yaml` mediumtext NOT NULL, + `requestCpu` int(10) NOT NULL, + `requestMemory` bigint(20) NOT NULL, + `framework` varchar(255) DEFAULT 'Other', + `condaVersion` varchar(32) DEFAULT NULL, + `dockerImage` varchar(255) DEFAULT NULL, + `size` bigint(20) DEFAULT 0, + `gpuComputeCapability` varchar(32) DEFAULT NULL, + `system` tinyint(1) DEFAULT 0, + `modelCenterUuid` varchar(32) NOT NULL, + `vmImageUuid` varchar(32) DEFAULT NULL, + `installPath` varchar(512) NOT NULL, + `startCommand` varchar(1024) NOT NULL, + `pythonVersion` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceRefVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `modelUuid` varchar(32) NOT NULL, + `modelServiceUuid` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkModelRefVO FOREIGN KEY (modelUuid) REFERENCES ModelVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT fkModelServiceRefVO FOREIGN KEY (modelServiceUuid) REFERENCES ModelServiceVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `zstack`.`ModelServiceInstanceGroupVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `modelServiceUuid` varchar(32) DEFAULT NULL, + `modelUuid` varchar(32) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `status` varchar(255) NOT NULL, + `modelServiceType` varchar(62) NOT NULL, + `type` varchar(128) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + CONSTRAINT fkModelServiceInstanceGroupVOModelServiceModelServiceVO FOREIGN KEY (modelServiceUuid) REFERENCES ModelServiceVO (uuid) ON DELETE SET NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceInstanceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `description` varchar(2048) DEFAULT NULL, + `yaml` mediumtext DEFAULT NULL, + `status` varchar(255) NOT NULL, + `url` varchar(2048) NOT NULL, + `modelServiceGroupUuid` varchar(32) NOT NULL, + `vmInstanceUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT fkModelServiceInstanceVOVmInstanceVO FOREIGN KEY (vmInstanceUuid) REFERENCES VmInstanceEO (uuid) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +--CREATE TABLE `zstack`.`VmModelServiceInstanceVO` ( +-- `uuid` varchar(32) NOT NULL UNIQUE, +-- `modelServiceInstanceGroupUuid` varchar(32) DEFAULT NULL, +-- PRIMARY KEY (`uuid`) +--) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SSOServerTokenVO`( + `uuid` varchar(32) not null unique, + `accessToken` text DEFAULT NULL, + `idToken` text DEFAULT NULL, + `refreshToken` text DEFAULT NULL, + `userUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ContainerManagementVmVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `managementIp` varchar(255) DEFAULT NULL, + `vendor` varchar(64) DEFAULT NULL, + `managementPort` int unsigned DEFAULT NULL, + `vmInstanceUuid` varchar(32) NOT NULL, + `accessKeyId` VARCHAR(128) NOT NULL, + `accessKeySecret` VARCHAR(128) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`DatasetVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NULL, + `url` varchar(2048) NULL, + `code` varchar(255) DEFAULT NULL, + `installPath` varchar(2048) NULL, + `description` varchar(2048) NULL, + `modelCenterUuid` varchar(32) NOT NULL, + `system` tinyint(1) DEFAULT 0, + `size` bigint(20) DEFAULT 0, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT fkDatasetVOModelCenterVO FOREIGN KEY (modelCenterUuid) REFERENCES ModelCenterVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceGroupDatasetRefVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `datasetUuid` varchar(32) NOT NULL, + `modelServiceInstanceGroupUuid` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkDatasetRefVO FOREIGN KEY (datasetUuid) REFERENCES DatasetVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT fkModelServiceInstanceGroupVORefVO FOREIGN KEY (modelServiceInstanceGroupUuid) REFERENCES ModelServiceInstanceGroupVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceGroupModelServiceRefVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `modelServiceInstanceGroupUuid` varchar(32) NOT NULL, + `dependModelServiceInstanceGroupUuid` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkModelServiceGroupModelServiceRefVOModelServicePrimary FOREIGN KEY (dependModelServiceInstanceGroupUuid) REFERENCES ModelServiceInstanceGroupVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT fkModelServiceGroupModelServiceRefVOModelServiceDepend FOREIGN KEY (modelServiceInstanceGroupUuid) REFERENCES ModelServiceInstanceGroupVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelEvalServiceInstanceGroupVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `temperature` FLOAT NULL, + `topK` INT NULL, + `topP` FLOAT NULL, + `maxLength` INT NULL, + `maxNewTokens` INT NULL, + `repetitionPenalty` FLOAT NULL, + `limits` INT, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`UserProxyConfigVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `proxyType` varchar(255) NULL, + `proxyHost` varchar(255) NULL, + `proxyPort` int NULL, + `proxyUsername` varchar(255) NULL, + `proxyPassword` varchar(255) NULL, + `isEnabled` boolean NULL, + `proxyProtocolVersion` varchar(255) NULL, + `useSsl` boolean NULL, + `noProxy` varchar(255) NULL, + `createDate` timestamp NULL, + `lastOpDate` timestamp NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`UserProxyConfigResourceRefVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `resourceUuid` varchar(32) NOT NULL, + `proxyUuid` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + UNIQUE KEY `id` (`id`), + KEY `fkUserProxyConfigResourceRefVOResourceVO` (`resourceUuid`), + KEY `fkUserProxyConfigResourceRefVOUserProxyConfigVO` (`proxyUuid`), + CONSTRAINT `fUserProxyConfigResourceRefVO` FOREIGN KEY (`resourceUuid`) REFERENCES `ResourceVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkUserProxyConfigResourceRefVO1` FOREIGN KEY (`proxyUuid`) REFERENCES `UserProxyConfigVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelEvaluationTaskVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) DEFAULT NULL, + `description` varchar(2048) DEFAULT NULL, + `percentage` int(3) DEFAULT 0, + `status` varchar(64) NOT NULL, + `modelServiceGroupUuid` varchar(32) NOT NULL, + `evaluatedServiceGroupUuid` varchar(32) NOT NULL, + `datasetUuid` varchar(32) NOT NULL, + `limits` int(3) DEFAULT 0, + `opaque` mediumtext DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`TrainedModelRecordVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `modelUuid` varchar(32) NOT NULL, + `sourceModelUuid` varchar(32) DEFAULT NULL, + `modelServiceInstanceGroupUuid` varchar(32) NOT NULL, + `datasetUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V5.1.8__schema.sql b/conf/db/upgrade/V5.1.8__schema.sql new file mode 100644 index 00000000000..b14a671c600 --- /dev/null +++ b/conf/db/upgrade/V5.1.8__schema.sql @@ -0,0 +1,274 @@ +ALTER TABLE `zstack`.`AuditsVO` ADD COLUMN `startTime` bigint(20); + +CREATE INDEX idx_startTime ON AuditsVO (startTime); +CREATE INDEX id_id_resourceType ON AuditsVO (id, resourceType); +CREATE INDEX idx_id_resourceType_startTime ON AuditsVO (id, resourceType, startTime); + +UPDATE AuditsVO set startTime = createTime WHERE startTime IS NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`SanSecSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `keyIndex` varchar(128) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkSanSecSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SanSecSecurityMachineVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `port` int unsigned NOT NULL, + `password` varchar(255) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkSanSecurityMachineVOSecurityMachineVO FOREIGN KEY (uuid) REFERENCES SecurityMachineVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`FiSecSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `keyNum` varchar(128) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkFiSecSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`FiSecSecurityMachineVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `port` int unsigned NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkFiSecSecurityMachineVOSecurityMachineVO FOREIGN KEY (uuid) REFERENCES SecurityMachineVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`CSPSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `managementIp` varchar(32) NOT NULL, + `port` int unsigned NOT NULL, + `appId` varchar(128) NOT NULL, + `appKey` varchar(128) NOT NULL, + `keyId` varchar(128) NOT NULL, + `userId` varchar(128) DEFAULT NULL, + `protocol` varchar(8) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkCSPSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`SNSApplicationEndpointVO` ADD COLUMN `connectionStatus` varchar(10) DEFAULT 'UP' COMMENT 'UP or DOWN'; + +CREATE TABLE IF NOT EXISTS `zstack`.`SNSUniversalSmsEndpointVO` +( + `uuid` varchar(32) NOT NULL UNIQUE, + `smsAccessKeyId` varchar(128) NOT NULL, + `smsAccessKeySecret` varchar(128) NOT NULL, + `supplier` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkSNSUniversalSmsEndpointVOSNSApplicationEndpointVO FOREIGN KEY (uuid) REFERENCES SNSApplicationEndpointVO (uuid) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SNSEmaySmsEndpointVO` +( + `uuid` varchar(32) NOT NULL UNIQUE, + `requestUrl` varchar(128) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkSNSEmaySmsEndpointVOSNSApplicationEndpointVO FOREIGN KEY (uuid) REFERENCES SNSApplicationEndpointVO (uuid) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`SNSSmsEndpointVO` RENAME TO `zstack`.`SNSAliyunSmsEndpointVO`; +ALTER TABLE `zstack`.`SNSAliyunSmsEndpointVO` DROP FOREIGN KEY fkSNSSmsEndpointVOSNSApplicationEndpointVO; +ALTER TABLE `zstack`.`SNSAliyunSmsEndpointVO` + ADD CONSTRAINT fkSNSAliyunSmsEndpointVOSNSApplicationEndpointVO FOREIGN KEY (uuid) REFERENCES `zstack`.`SNSApplicationEndpointVO` (uuid) ON DELETE CASCADE; +ALTER TABLE `zstack`.`SNSSmsReceiverVO` DROP FOREIGN KEY fkSNSSmsReceiverVOSNSSmsEndpointVO; +ALTER TABLE `zstack`.`SNSSmsReceiverVO` + ADD CONSTRAINT fkSNSSmsReceiverVOSNSUniversalSmsEndpointVO FOREIGN KEY (endpointUuid) REFERENCES `zstack`.`SNSUniversalSmsEndpointVO` (uuid) ON DELETE CASCADE; + +DROP PROCEDURE IF EXISTS UpgradeSNSAliyunSmsEndpointVO; +DELIMITER $$ +CREATE PROCEDURE UpgradeSNSAliyunSmsEndpointVO() +BEGIN + IF (SELECT COUNT(*) FROM SNSUniversalSmsEndpointVO u JOIN SNSAliyunSmsEndpointVO a ON u.uuid = a.uuid) = 0 THEN + INSERT INTO SNSUniversalSmsEndpointVO (uuid, smsAccessKeyId, smsAccessKeySecret, supplier) SELECT uuid, '', '', 'Aliyun' FROM SNSAliyunSmsEndpointVO; +END IF; +END $$ +DELIMITER ; +CALL UpgradeSNSAliyunSmsEndpointVO(); + +DROP PROCEDURE IF EXISTS check_and_insert_encrypt_metadata; +DELIMITER $$ +CREATE PROCEDURE check_and_insert_encrypt_metadata() +BEGIN + IF (select count(*) from GlobalConfigVO gconfig where gconfig.name = 'enable.password.encrypt' and gconfig.category = 'encrypt' and value != 'None') > 0 THEN + UPDATE EncryptEntityMetadataVO SET state = 'NewAdded' WHERE entityName = 'IAM2VirtualIDAttributeVO' AND state = 'Encrypted'; + INSERT INTO EncryptEntityMetadataVO (entityName, columnName, state, lastOpDate, createDate) VALUES ('IAM2OrganizationAttributeVO', 'value', 'NeedDecrypt', NOW(), NOW()); + INSERT INTO EncryptEntityMetadataVO (entityName, columnName, state, lastOpDate, createDate) VALUES ('IAM2ProjectAttributeVO', 'value', 'NeedDecrypt', NOW(), NOW()); + INSERT INTO EncryptEntityMetadataVO (entityName, columnName, state, lastOpDate, createDate) VALUES ('IAM2VirtualIDAttributeVO', 'value', 'NeedDecrypt', NOW(), NOW()); + INSERT INTO EncryptEntityMetadataVO (entityName, columnName, state, lastOpDate, createDate) VALUES ('IAM2VirtualIDGroupAttributeVO', 'value', 'NeedDecrypt', NOW(), NOW()); + END IF; +END $$ +DELIMITER ; +CALL check_and_insert_encrypt_metadata(); + +UPDATE SystemTagVO SET resourceType='SNSAliyunSmsEndpointVO' where resourceType='SNSSmsEndpointVO'; + + +UPDATE IAM2VirtualIDAttributeVO attr JOIN IAM2VirtualIDVO vid ON attr.virtualIDUuid = vid.uuid SET attr.createDate = vid.createDate WHERE attr.createDate = '0000-00-00 00:00:00'; +UPDATE IAM2VirtualIDAttributeVO attr JOIN IAM2VirtualIDVO vid ON attr.virtualIDUuid = vid.uuid SET attr.lastOpDate = vid.lastOpDate WHERE attr.lastOpDate = '0000-00-00 00:00:00'; + +UPDATE IAM2OrganizationAttributeVO attr JOIN IAM2OrganizationVO vid ON attr.organizationUuid = vid.uuid SET attr.createDate = vid.createDate WHERE attr.createDate = '0000-00-00 00:00:00'; +UPDATE IAM2OrganizationAttributeVO attr JOIN IAM2OrganizationVO vid ON attr.organizationUuid = vid.uuid SET attr.lastOpDate = vid.lastOpDate WHERE attr.lastOpDate = '0000-00-00 00:00:00'; + +UPDATE IAM2ProjectAttributeVO attr JOIN IAM2ProjectVO vid ON attr.projectUuid = vid.uuid SET attr.createDate = vid.createDate WHERE attr.createDate = '0000-00-00 00:00:00'; +UPDATE IAM2ProjectAttributeVO attr JOIN IAM2ProjectVO vid ON attr.projectUuid = vid.uuid SET attr.lastOpDate = vid.lastOpDate WHERE attr.lastOpDate = '0000-00-00 00:00:00'; + +UPDATE IAM2VirtualIDGroupAttributeVO attr JOIN IAM2VirtualIDGroupVO vid ON attr.groupUuid = vid.uuid SET attr.createDate = vid.createDate WHERE attr.createDate = '0000-00-00 00:00:00'; +UPDATE IAM2VirtualIDGroupAttributeVO attr JOIN IAM2VirtualIDGroupVO vid ON attr.groupUuid = vid.uuid SET attr.lastOpDate = vid.lastOpDate WHERE attr.lastOpDate = '0000-00-00 00:00:00'; + +CREATE TABLE IF NOT EXISTS `zstack`.`ReservedIpRangeVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'uuid', + `l3NetworkUuid` varchar(32) NOT NULL COMMENT 'l3 network uuid', + `name` varchar(255) DEFAULT NULL COMMENT 'name', + `description` varchar(2048) DEFAULT NULL COMMENT 'description', + `ipVersion` int(10) unsigned DEFAULT 4 COMMENT 'ip range version', + `startIp` varchar(64) NOT NULL COMMENT 'start ip', + `endIp` varchar(64) NOT NULL COMMENT 'end ip', + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP COMMENT 'last operation date', + `createDate` timestamp, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`PciDeviceVO` ADD `rev` varchar(32) DEFAULT ''; + +DELETE FROM `zstack`.`ResourceConfigVO` WHERE `category`='sharedblock' AND `name`='qcow2.allocation'; + +CREATE TABLE IF NOT EXISTS `zstack`.`GpuDeviceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `serialNumber` varchar(255), + `memory` bigint unsigned NULL DEFAULT 0, + `power` bigint unsigned NULL DEFAULT 0, + `isDriverLoaded` TINYINT(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkGpuDeviceInfoVOPciDeviceVO` FOREIGN KEY (`uuid`) REFERENCES `PciDeviceVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('PciDeviceVO', 'vendor', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('PciDeviceVO', 'device', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('PciDeviceSpecVO', 'vendor', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('PciDeviceSpecVO', 'device', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('MdevDeviceVO', 'vendor', 'VARCHAR(128)', 1, NULL); + +DROP PROCEDURE IF EXISTS `MdevDeviceAddVendor`; +DELIMITER $$ +CREATE PROCEDURE MdevDeviceAddVendor() + BEGIN + DECLARE vendor VARCHAR(128); + DECLARE pciDeviceUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT pci.uuid, pci.vendor FROM PciDeviceVO pci; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN cur; + read_loop: LOOP + FETCH cur INTO vendor, pciDeviceUuid; + IF done THEN + LEAVE read_loop; + END IF; + UPDATE MdevDeviceVO SET vendor = vendor WHERE parentUuid = pciDeviceUuid; + END LOOP; + CLOSE cur; + SELECT CURTIME(); + END $$ +DELIMITER ; +call MdevDeviceAddVendor; +DROP PROCEDURE IF EXISTS `MdevDeviceAddVendor`; + +CREATE TABLE IF NOT EXISTS `HostHwMonitorStatusVO` +( + `uuid` varchar(32) NOT NULL UNIQUE, + `cpuStatus` varchar(32) NOT NULL, + `memoryStatus` varchar(32) NOT NULL, + `diskStatus` varchar(32) NOT NULL, + `nicStatus` varchar(32) NOT NULL, + `gpuStatus` varchar(32) NOT NULL, + `powerSupplyStatus` varchar(32) NOT NULL, + `fanStatus` varchar(32) NOT NULL, + `raidStatus` varchar(32) NOT NULL, + `temperatureStatus` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHostHwMonitorStatusVO` FOREIGN KEY (`uuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE + ) ENGINE = InnoDB DEFAULT CHARSET = utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`BareMetal2ChassisPciDeviceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'uuid', + `chassisUuid` varchar(32) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `type` varchar(32) NOT NULL, + `pciDeviceAddress` varchar(32) NOT NULL, + `vendorId` varchar(64) NOT NULL, + `deviceId` varchar(64) NOT NULL, + `subvendorId` varchar(64) DEFAULT NULL, + `subdeviceId` varchar(64) DEFAULT NULL, + `iommuGroup` varchar(255) DEFAULT NULL, + `name` varchar(255) NOT NULL, + `vendor` varchar(128) DEFAULT NULL, + `device` varchar(128) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkBareMetal2ChassisPciDeviceVOChassisVO` FOREIGN KEY (`chassisUuid`) REFERENCES `BareMetal2ChassisVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`BareMetal2ChassisGpuDeviceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `serialNumber` varchar(255), + `memory` varchar(255), + `power` varchar(255), + PRIMARY KEY (`uuid`), + CONSTRAINT `fkBm2ChassisGpuDeviceVOBm2ChassisPciDeviceVO` FOREIGN KEY (`uuid`) REFERENCES `BareMetal2ChassisPciDeviceVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP PROCEDURE IF EXISTS `CreateGpuDeviceVO`; +DELIMITER $$ +CREATE PROCEDURE CreateGpuDeviceVO() + BEGIN + DECLARE uuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT pci.uuid FROM PciDeviceVO pci where pci.type in ('GPU_Video_Controller', 'GPU_3D_Controller'); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO uuid; + IF done THEN + LEAVE read_loop; + END IF; + insert into GpuDeviceVO (uuid) values (uuid); + END LOOP; + CLOSE cur; + SELECT CURTIME(); + END $$ +DELIMITER ; +call CreateGpuDeviceVO; +DROP PROCEDURE IF EXISTS `CreateGpuDeviceVO`; + +DROP PROCEDURE IF EXISTS `addPciDeviceVendor`; +DELIMITER $$ +CREATE PROCEDURE addPciDeviceVendor() + BEGIN + DECLARE pciUuid VARCHAR(32); + DECLARE vendorId VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + DECLARE cur CURSOR FOR SELECT pci.uuid, pci.vendorId FROM PciDeviceVO pci where pci.type in ('GPU_Video_Controller', 'GPU_3D_Controller'); + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO pciUuid, vendorId; + IF done THEN + LEAVE read_loop; + END IF; + IF vendorId = '1d94' then + update PciDeviceVO set vendor = 'Haiguang' where uuid = pciUuid; + ELSEIF vendorId = '10de' then + update PciDeviceVO set vendor = 'NVIDIA' where uuid = pciUuid; + ELSEIF vendorId = '1002' then + update PciDeviceVO set vendor = 'AMD' where uuid = pciUuid; + END IF; + END LOOP; + CLOSE cur; + SELECT CURTIME(); + END $$ +DELIMITER ; +call addPciDeviceVendor; +DROP PROCEDURE IF EXISTS `addPciDeviceVendor`; diff --git a/conf/db/upgrade/V5.2.0__schema.sql b/conf/db/upgrade/V5.2.0__schema.sql new file mode 100644 index 00000000000..a4a2b406995 --- /dev/null +++ b/conf/db/upgrade/V5.2.0__schema.sql @@ -0,0 +1,226 @@ +ALTER TABLE `zstack`.`HostNetworkInterfaceVO` MODIFY COLUMN `mac` varchar(128) DEFAULT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`XmlHookVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) UNIQUE NOT NULL, + `description` varchar(2048) NULL, + `type` varchar(32) NOT NULL, + `hookScript` text NOT NULL, + `libvirtVersion` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`XmlHookVmInstanceRefVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `xmlHookUuid` varchar(32) NOT NULL, + `vmInstanceUuid` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + UNIQUE KEY `id` (`id`), + KEY `fkXmlHookVmInstanceRefVOXmlHookVO` (`xmlHookUuid`), + KEY `fkXmlHookVmInstanceRefVOVmInstanceVO` (`vmInstanceUuid`), + CONSTRAINT `fkXmlHookVmInstanceRefVO` FOREIGN KEY (`xmlHookUuid`) REFERENCES `XmlHookVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkXmlHookVmInstanceRefVO1` FOREIGN KEY (`vmInstanceUuid`) REFERENCES `ResourceVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`SSOServerTokenVO`( + `uuid` varchar(32) not null unique, + `accessToken` text DEFAULT NULL, + `idToken` text DEFAULT NULL, + `refreshToken` text DEFAULT NULL, + `userUuid` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP PROCEDURE IF EXISTS migrateJsonLabelToXmlHookVO; +DELIMITER $$ +CREATE PROCEDURE migrateJsonLabelToXmlHookVO() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE hookUuid VARCHAR(32); + DECLARE vmUuid VARCHAR(32); + DECLARE hookValue TEXT; + DECLARE cur CURSOR FOR SELECT DISTINCT REPLACE(labelKey,'user-defined-xml-hook-script-',''),labelValue FROM zstack.JsonLabelVO WHERE labelKey like 'user-defined-xml-hook-script-%%'; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + OPEN cur; + read_loop: LOOP + FETCH cur INTO vmUuid, hookValue; + IF done THEN + LEAVE read_loop; + END IF; + + IF NOT EXISTS(SELECT * from XmlHookVO where hookScript = hookValue) THEN + SET hookUuid = (REPLACE(UUID(), '-', '')); + + INSERT zstack.ResourceVO(uuid, resourceName, resourceType, concreteResourceType) + VALUES (hookUuid, 'xml-hook', 'XmlHookVO', 'org.zstack.header.tag.XmlHookVO'); + + INSERT zstack.XmlHookVO (uuid, name, description, type, hookScript, lastOpDate, createDate) + VALUES(hookUuid, concat('xml-hook', hookUuid), 'xml-hook', 'Customization', hookValue, NOW(), NOW()); + + INSERT zstack.XmlHookVmInstanceRefVO(xmlHookUuid, vmInstanceUuid, lastOpDate, createDate) + VALUES (hookUuid, vmUuid, NOW(), NOW()); + + ELSEIF NOT EXISTS(SELECT * from XmlHookVmInstanceRefVO where vmInstanceUuid = vmUuid) THEN + SET hookUuid = (select uuid from XmlHookVO where hookScript = hookValue); + INSERT zstack.XmlHookVmInstanceRefVO(xmlHookUuid, vmInstanceUuid, lastOpDate, createDate) + VALUES (hookUuid, vmUuid, NOW(), NOW()); + END IF; + + DELETE FROM zstack.JsonLabelVO WHERE labelKey = CONCAT('user-defined-xml-hook-script-', vmUuid) AND labelValue = hookValue; + END LOOP; + CLOSE cur; + + SELECT CURTIME(); +END $$ +DELIMITER ; +call migrateJsonLabelToXmlHookVO(); +DROP PROCEDURE IF EXISTS migrateJsonLabelToXmlHookVO; + +DELETE b FROM HostNetworkInterfaceLldpVO b LEFT JOIN ResourceVO a ON b.uuid = a.uuid WHERE a.uuid IS NULL; + +ALTER TABLE BareMetal2InstanceProvisionNicVO MODIFY mac varchar(17) NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`GuestVmScriptEO` ( + `uuid` VARCHAR(32) NOT NULL UNIQUE, + `name` VARCHAR(256) NOT NULL, + `description` VARCHAR(256), + `platform` VARCHAR(255) NOT NULL, + `scriptContent` MEDIUMTEXT, + `renderParams` MEDIUMTEXT, + `scriptType` VARCHAR(32) NOT NULL, + `scriptTimeout` INT UNSIGNED NOT NULL, + `version` INT UNSIGNED NOT NULL, + `deleted` VARCHAR(255) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP VIEW IF EXISTS `zstack`.`GuestVmScriptVO`; +CREATE VIEW `zstack`.`GuestVmScriptVO` AS SELECT uuid, name, description, platform, scriptContent, renderParams, scriptType, scriptTimeout, version, createDate, lastOpDate FROM `zstack`.`GuestVmScriptEO` WHERE deleted IS NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`GuestVmScriptExecutedRecordVO` ( + `uuid` VARCHAR(32) NOT NULL UNIQUE, + `recordName` VARCHAR(255) NOT NULL, + `scriptUuid` VARCHAR(32) NOT NULL, + `scriptTimeout` INT UNSIGNED NOT NULL, + `status` VARCHAR(256) NOT NULL, + `version` INT UNSIGNED NOT NULL, + `Executor` VARCHAR(256) NOT NULL , + `ExecutionCount` INT UNSIGNED NOT NULL, + `scriptContent` MEDIUMTEXT, + `renderParams` MEDIUMTEXT, + `startTime` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + `endTime` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + INDEX `idxScriptUuid` (`scriptUuid`, `version`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`GuestVmScriptExecutedRecordDetailVO` ( + `recordUuid` VARCHAR(32) NOT NULL, + `vmInstanceUuid` VARCHAR(32) NOT NULL, + `vmName` VARCHAR(255) NOT NULL, + `status` VARCHAR(128) NOT NULL, + `exitCode` INT UNSIGNED, + `stdout` MEDIUMTEXT, + `errCause` MEDIUMTEXT, + `stderr` MEDIUMTEXT, + `startTime` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + `endTime` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`recordUuid`, `vmInstanceUuid`), + CONSTRAINT `fkGuestVmScriptExecutedRecordDetailVOScriptExecutedRecordVO` FOREIGN KEY (`recordUuid`) REFERENCES `GuestVmScriptExecutedRecordVO` (`uuid`) ON DELETE CASCADE +)ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('SanSecSecretResourcePoolVO', 'managementIp', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('SanSecSecretResourcePoolVO', 'port', 'int unsigned', 1, NULL); +CALL ADD_COLUMN('SanSecSecretResourcePoolVO', 'username', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('SanSecSecretResourcePoolVO', 'password', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('SanSecSecretResourcePoolVO', 'sm3Key', 'VARCHAR(128)', 1, NULL); +CALL ADD_COLUMN('SanSecSecretResourcePoolVO', 'sm4Key', 'VARCHAR(128)', 1, NULL); + +ALTER TABLE `zstack`.`AuditsVO` MODIFY COLUMN requestDump MEDIUMTEXT, MODIFY COLUMN responseDump MEDIUMTEXT; + +update EventSubscriptionVO set name = 'VM NIC IP Changed (GuestTools Is Required)' where uuid='98536fa94e3f4481a38331a989132b7c'; +update EventSubscriptionVO set name = 'NIC IP Configured in VM has been Occupied or in the Reserved Range (GuestTools Is Required)' where uuid='4a3494bcdbac4eaab9e9e56e27d74a2a'; + +CALL ADD_COLUMN('MdevDeviceSpecVO', 'vendor', 'VARCHAR(128)', 1, NULL); + +CALL ADD_COLUMN('BareMetal2ChassisGpuDeviceVO', 'isDriverLoaded', 'TINYINT(1)', 0, 0); + +DELIMITER $$ +DROP FUNCTION IF EXISTS `INET6_ATON` $$ +CREATE FUNCTION `INET6_ATON`( + ip VARCHAR(128) +) RETURNS BINARY(16) +BEGIN + DECLARE binary_ip BINARY(16); + DECLARE hextet VARCHAR(5); + DECLARE i INT DEFAULT 1; + DECLARE segment_position INT DEFAULT 1; + DECLARE segment_count INT; + DECLARE expanded_ip VARCHAR(45); + IF INSTR(ip, '.') > 0 THEN + SET binary_ip = CONCAT(REPEAT(UNHEX('00'), 10), UNHEX('FFFF'), UNHEX(LPAD(HEX(INET_ATON(ip)), 8, '0'))); + ELSE + IF INSTR(ip, '::') > 0 THEN + SET segment_count = LENGTH(ip) - LENGTH(REPLACE(ip, ':', '')) + 1; + SET expanded_ip = REPLACE(ip, '::', CONCAT(':', REPEAT(':0000', 8 - segment_count), ':')); + IF LEFT(expanded_ip, 1) = ':' THEN + SET expanded_ip = SUBSTRING(expanded_ip, 2); + END IF; + IF RIGHT(expanded_ip, 1) = ':' THEN + SET expanded_ip = SUBSTRING(expanded_ip, 1, LENGTH(expanded_ip) - 1); + END IF; + ELSE + SET expanded_ip = ip; + END IF; + SET binary_ip = 0x00000000000000000000000000000000; + WHILE i <= 8 DO + SET hextet = SUBSTRING_INDEX(SUBSTRING_INDEX(expanded_ip, ':', i), ':', -1); + IF LENGTH(hextet) > 0 THEN + SET binary_ip = INSERT(binary_ip, segment_position, 4, UNHEX(LPAD(hextet, 4, '0'))); + END IF; + SET segment_position = segment_position + 2; + SET i = i + 1; + END WHILE; + END IF; + RETURN binary_ip; +END$$ +DELIMITER ; +DELIMITER $$ + +DELIMITER $$ +CREATE PROCEDURE upgradeIpInLongColumn() +BEGIN + DECLARE columnExists BOOLEAN DEFAULT FALSE; + + SELECT COUNT(*) INTO columnExists + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = 'UsedIpVO' + AND COLUMN_NAME = 'ipInBinary' + AND TABLE_SCHEMA = 'zstack'; + + IF columnExists = FALSE THEN + ALTER TABLE `zstack`.`UsedIpVO` ADD COLUMN `ipInBinary` VARBINARY(16) NOT NULL AFTER `ipInLong`; + END IF; + + UPDATE `zstack`.`UsedIpVO` + SET `ipInBinary` = CASE + WHEN `ipInLong` != 0 THEN UNHEX(LPAD(HEX(`ipInLong`), 8, '0')) + ELSE INET6_ATON(`ip`) + END; + SELECT CURTIME(); +END $$ +DELIMITER ; +CALL upgradeIpInLongColumn(); + +ALTER TABLE BareMetal2ChassisGpuDeviceVO MODIFY COLUMN memory bigint unsigned NULL, MODIFY COLUMN power bigint unsigned NULL; +ALTER TABLE GpuDeviceVO MODIFY COLUMN memory bigint unsigned NULL, MODIFY COLUMN power bigint unsigned NULL; + +UPDATE `zstack`.`GlobalConfigVO` SET value="64", defaultValue="64" WHERE category="volumeSnapshot" AND name="incrementalSnapshot.maxNum" AND value > 120; \ No newline at end of file diff --git a/conf/db/upgrade/V5.2.1__schema.sql b/conf/db/upgrade/V5.2.1__schema.sql new file mode 100644 index 00000000000..1468bd788a3 --- /dev/null +++ b/conf/db/upgrade/V5.2.1__schema.sql @@ -0,0 +1 @@ +ALTER TABLE `zstack`.`ExternalPrimaryStorageVO` modify column config varchar(2048) DEFAULT NULL; \ No newline at end of file diff --git a/conf/db/upgrade/V5.3.0__schema.sql b/conf/db/upgrade/V5.3.0__schema.sql new file mode 100644 index 00000000000..6877d9cca7f --- /dev/null +++ b/conf/db/upgrade/V5.3.0__schema.sql @@ -0,0 +1,53 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`HbaDeviceVO` ( + `uuid` varchar(32) not null unique, + `hostUuid` varchar(32) default null, + `name` varchar(255) default null, + `hbaType` varchar(64) default null, + `createDate` timestamp not null default '0000-00-00 00:00:00', + `lastOpDate` timestamp not null default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + CONSTRAINT fkHBADeviceVOHostVO FOREIGN KEY (hostUuid) REFERENCES HostEO (uuid) ON DELETE CASCADE, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`FcHbaDeviceVO` ( + `uuid` varchar(32) not null unique, + `portName` varchar(255) default null, + `portState` varchar(64) default null, + `supportedSpeeds` varchar(255) default null, + `speed` varchar(255) default null, + `symbolicName` varchar(255) default null, + `supportedClasses` varchar(255) default null, + `nodeName` varchar(255) default null, + CONSTRAINT fkFcHbaDeviceVO FOREIGN KEY (uuid) REFERENCES HbaDeviceVO (uuid) ON DELETE CASCADE, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +UPDATE `zstack`.`ImageEO` SET guestOsType = 'VyOS 1.1.7' WHERE architecture = 'x86_64' and guestOsType = 'Linux' and `system` = TRUE; +UPDATE `zstack`.`ImageEO` SET guestOsType = 'VyOS 1.2.0' WHERE architecture = 'aarch64' and guestOsType = 'Linux' and `system` = TRUE; +UPDATE `zstack`.`ImageEO` SET guestOsType = 'Kylin 10' WHERE architecture = 'loongarch64' and guestOsType = 'Linux' and `system` = TRUE; + +UPDATE `zstack`.`VmInstanceEO` SET guestOsType = 'VyOS 1.1.7' WHERE architecture = 'x86_64' and guestOsType = 'Linux' and type = 'ApplianceVm'; +UPDATE `zstack`.`VmInstanceEO` SET guestOsType = 'VyOS 1.2.0' WHERE architecture = 'aarch64' and guestOsType = 'Linux' and type = 'ApplianceVm'; +UPDATE `zstack`.`VmInstanceEO` SET guestOsType = 'Kylin 10' WHERE architecture = 'loongarch64' and guestOsType = 'Linux' and type = 'ApplianceVm'; + +CREATE TABLE IF NOT EXISTS `zstack`.`HostNetworkLabelVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `serviceType` varchar(255) NOT NULL, + `system` boolean NOT NULL DEFAULT TRUE, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +INSERT IGNORE INTO `zstack`.`HostNetworkLabelVO` (`uuid`, `serviceType`, `system`, `createDate`, `lastOpDate`) + VALUES (REPLACE(UUID(),'-',''),'ManagementNetwork', TRUE, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); +INSERT IGNORE INTO `zstack`.`HostNetworkLabelVO` (`uuid`, `serviceType`, `system`, `createDate`, `lastOpDate`) + VALUES (REPLACE(UUID(),'-',''),'StorageNetwork', TRUE, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); +INSERT IGNORE INTO `zstack`.`HostNetworkLabelVO` (`uuid`, `serviceType`, `system`, `createDate`, `lastOpDate`) + VALUES (REPLACE(UUID(),'-',''),'TenantNetwork', TRUE, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); +INSERT IGNORE INTO `zstack`.`HostNetworkLabelVO` (`uuid`, `serviceType`, `system`, `createDate`, `lastOpDate`) + VALUES (REPLACE(UUID(),'-',''),'BackupNetwork', TRUE, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); +INSERT IGNORE INTO `zstack`.`HostNetworkLabelVO` (`uuid`, `serviceType`, `system`, `createDate`, `lastOpDate`) + VALUES (REPLACE(UUID(),'-',''),'MigrationNetwork', TRUE, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + +CREATE INDEX idx_schedType_createDate ON `zstack`.`VmSchedHistoryVO` (schedType, createDate); \ No newline at end of file diff --git a/conf/db/upgrade/V5.3.20__schema.sql b/conf/db/upgrade/V5.3.20__schema.sql new file mode 100644 index 00000000000..081413f4b89 --- /dev/null +++ b/conf/db/upgrade/V5.3.20__schema.sql @@ -0,0 +1,186 @@ +ALTER TABLE AutoScalingRuleSchedulerJobTriggerVO DROP FOREIGN KEY fkAutoScalingRuleSchedulerJobTriggerVO; +CALL ADD_CONSTRAINT('AutoScalingRuleSchedulerJobTriggerVO', 'fkAutoScalingRuleSchedulerJobTriggerVO', 'schedulerJobUuid', 'SchedulerJobVO', 'uuid', 'CASCADE'); + +ALTER TABLE `zstack`.`ExternalPrimaryStorageVO` MODIFY COLUMN `config` TEXT DEFAULT NULL; +ALTER TABLE `zstack`.`HostNetworkInterfaceLldpRefVO` MODIFY COLUMN `systemName` VARCHAR(255) NOT NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`ExternalPrimaryStorageHostRefVO` ( + `id` BIGINT UNSIGNED UNIQUE, + `hostId` INT DEFAULT NULL, + `protocol` varchar(128) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8; + +SET @row_number = 0; +INSERT INTO ExternalPrimaryStorageHostRefVO (id, hostId, protocol) +SELECT + p.id, + (@row_number := @row_number + 1) as hostId, + e.defaultProtocol as protocol +FROM PrimaryStorageHostRefVO p LEFT JOIN ExternalPrimaryStorageVO e ON p.primaryStorageUuid = e.uuid +ORDER BY p.id; + +-- Delete old UserTagVO of AI::Image-Generation +DELETE FROM UserTagVO WHERE uuid = 'a7ec68923efe447d9119ba7b6df2b54c'; + +DELETE ref FROM `zstack`.`VolumeSnapshotReferenceVO` ref + INNER JOIN `zstack`.`VolumeEO` vol ON vol.uuid = ref.referenceVolumeUuid +WHERE ref.referenceType = 'VolumeVO' + AND ref.referenceVolumeUuid = ref.referenceUuid + AND ref.referenceInstallUrl NOT LIKE CONCAT('%', SUBSTRING_INDEX(vol.installPath, '/', -1), '%'); + +DROP PROCEDURE IF EXISTS ModifyApplicationDevelopmentServiceVO; +DELIMITER $$ + +CREATE PROCEDURE ModifyApplicationDevelopmentServiceVO() +BEGIN + START TRANSACTION; + + CREATE TABLE IF NOT EXISTS `zstack`.`ApplicationDevelopmentServiceVO_temp` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `deploymentStatus` varchar(255) NOT NULL, + PRIMARY KEY (`uuid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + INSERT INTO `zstack`.`ApplicationDevelopmentServiceVO_temp` (uuid, deploymentStatus) + SELECT modelServiceGroupUuid, deploymentStatus + FROM `zstack`.`ApplicationDevelopmentServiceVO` + WHERE modelServiceGroupUuid IS NOT NULL; + + DROP TABLE `zstack`.`ApplicationDevelopmentServiceVO`; + + RENAME TABLE `zstack`.`ApplicationDevelopmentServiceVO_temp` TO `zstack`.`ApplicationDevelopmentServiceVO`; + + COMMIT; + SELECT CURTIME(); +END $$ + +DELIMITER ; + +CALL ModifyApplicationDevelopmentServiceVO(); + +CALL ADD_COLUMN('ModelVO', 'modelId', 'VARCHAR(255)', 1, NULL); +CALL ADD_COLUMN('ModelServiceInstanceGroupVO', 'description', 'VARCHAR(2048)', 1, NULL); +CALL ADD_COLUMN('ModelServiceVO', 'source', 'VARCHAR(32)', 1, NULL); +CALL ADD_COLUMN('ModelServiceVO', 'readme', 'TEXT', 1, NULL); + +# Delete ZStack-default-inference-template +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = '97e66447fa4246649dcc41b72b412407'; +# Delete qwen chat +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = '0446d8fd9487403cc12e7645f5r68d04'; +# Delete xtts +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = 'e944c98c4a154f53a86f34eb0fcd093c'; +# Delete sdxl +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = '80fab6f2f3d444e1a0b39702dcc62bac'; +# Delete blip image +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = '2ad69dc6cebf405f9e0d750bb50e120c'; +# Delete stable video +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = 'c65d3019cb3f400f80e5e2a10dcaf861'; +# Delete yolo +DELETE FROM `zstack`.`ModelServiceVO` WHERE `uuid` = '0b714f4d8c5c43ca86c3a6caa58358a7'; + +ALTER TABLE `zstack`.`BaremetalNicVO` modify column mac varchar(255) DEFAULT NULL; + +# framework field changed to LLM frameworks not service sources +# 1. Change the origin framework value to source field +# 2. If source is Bentoml change framework to BentoML +# 3. Else change framework to Other + +UPDATE `zstack`.`ModelServiceVO` SET source = framework WHERE source is NULL + AND framework in ('HuggingFace', 'Bentoml', 'Other'); + +UPDATE `zstack`.`ModelServiceVO` SET source = 'Other' WHERE source is NULL + AND framework not in ('HuggingFace', 'Bentoml', 'Other'); + +UPDATE `zstack`.`ModelServiceVO` SET source = 'Bentoml' WHERE source = 'BentoML'; +UPDATE `zstack`.`ModelServiceVO` SET framework = 'BentoML' WHERE source = 'Bentoml' + AND framework not in ('vLLM', 'Diffusers', 'Transformers', 'sentence_transformers', 'llama.cpp', 'BentoML', 'Other', 'Ollama'); + +Update ModelServiceVO set framework = 'Other' where framework not in + ('vLLM', 'Diffusers', 'Transformers', 'sentence_transformers', 'llama.cpp', 'BentoML', 'Other', 'Ollama') + AND source != 'Bentoml'; +Update ModelServiceVO set framework = 'Other' where framework is NULL; + +DROP PROCEDURE IF EXISTS CreateResourceConfigForBindingVms; +DELIMITER $$ +CREATE PROCEDURE CreateResourceConfigForBindingVms() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE vmUuid VARCHAR(128); + + DECLARE vmCursor CURSOR FOR + SELECT resourceUuid + FROM SystemTagVO + WHERE resourceType = 'VmInstanceVO' + AND tag LIKE 'resourceBindings::Cluster:%'; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN vmCursor; + + read_loop: LOOP + FETCH vmCursor INTO vmUuid; + + IF done THEN + LEAVE read_loop; + END IF; + + IF NOT EXISTS ( + SELECT 1 + FROM ResourceConfigVO + WHERE resourceType = 'VmInstanceVO' + AND resourceUuid = vmUuid + AND category = 'vm' + AND name = 'vm.ha.across.clusters' + ) THEN + INSERT INTO ResourceConfigVO (uuid, name, category, value, resourceUuid, resourceType, lastOpDate, createDate) + VALUES (REPLACE(UUID(),'-',''), 'vm.ha.across.clusters', 'vm', 'false', vmUuid, 'VmInstanceVO', NOW(), NOW()); + END IF; + END LOOP; + + CLOSE vmCursor; +END $$ +DELIMITER ; +call CreateResourceConfigForBindingVms(); +DROP PROCEDURE IF EXISTS CreateResourceConfigForBindingVms; + +DELETE FROM `SSOServerTokenVO`; +ALTER TABLE `zstack`.`SSOServerTokenVO` ADD sessionUuid VARCHAR(32) DEFAULT NULL; +ALTER TABLE `zstack`.`SSOServerTokenVO` ADD CONSTRAINT `fkSSOServerTokenVOSessionVO` FOREIGN KEY (`sessionUuid`) REFERENCES `SessionVO` (`uuid`) ON DELETE CASCADE; + +CALL ADD_COLUMN('SdnControllerVO', 'status', 'VARCHAR(32)', 0, 'Connected'); +CALL ADD_COLUMN('HostNetworkInterfaceVO', 'driverType', 'VARCHAR(32)', 1, NULL); + +CREATE TABLE IF NOT EXISTS `zstack`.`SdnControllerHostRefVO` ( + `id` BIGINT UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, + `sdnControllerUuid` varchar(32) NOT NULL, + `hostUuid` varchar(32) NOT NULL, + `vSwitchType` varchar(255) NOT NULL, + `vtepIp` varchar(128) DEFAULT NULL, + `netmask` varchar(128) DEFAULT NULL, + `nicPciAddresses` varchar(1024) DEFAULT NULL, + `nicDrivers` varchar(1024) DEFAULT NULL, + `bondMode` varchar(64) DEFAULT NULL, + `lacpMode` varchar(64) DEFAULT NULL, + CONSTRAINT fkSdnControllerHostRefVOSdnControllerVO FOREIGN KEY (sdnControllerUuid) REFERENCES SdnControllerVO (uuid) ON DELETE CASCADE, + CONSTRAINT fkSdnControllerHostRefVOHostEO FOREIGN KEY (hostUuid) REFERENCES HostEO (uuid) ON DELETE CASCADE, + CONSTRAINT ukSdnControllerHostRefVO UNIQUE (`sdnControllerUuid`,`hostUuid`, `vSwitchType`), + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`OvnControllerVmOfferingVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `managementNetworkUuid` varchar(32) NOT NULL, + `imageUuid` varchar(32) NOT NULL, + `zoneUuid` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkOvnControllerVmOfferingVOL3NetworkEO FOREIGN KEY (managementNetworkUuid) REFERENCES `zstack`.`L3NetworkEO` (uuid) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`OvnControllerVmInstanceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +UPDATE `zstack`.`L2NetworkVO` set vSwitchType='TfL2Network' where type='TfL2Network'; diff --git a/conf/db/upgrade/V5.3.22__schema.sql b/conf/db/upgrade/V5.3.22__schema.sql new file mode 100644 index 00000000000..9e8012b8158 --- /dev/null +++ b/conf/db/upgrade/V5.3.22__schema.sql @@ -0,0 +1,55 @@ +CALL ADD_COLUMN('ModelServiceInstanceVO', 'clusterId', 'INT', 1, NULL); + +CALL ADD_COLUMN('ModelServiceInstanceGroupVO', 'yaml', 'mediumtext', 1, NULL); + +DROP PROCEDURE IF EXISTS update_instance_group_yaml; + +DELIMITER $$ + +CREATE PROCEDURE update_instance_group_yaml() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE group_uuid VARCHAR(255); + DECLARE group_yaml TEXT; + DECLARE instance_yaml TEXT; + + DECLARE group_cursor CURSOR FOR + SELECT uuid, yaml FROM ModelServiceInstanceGroupVO; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN group_cursor; + + group_loop: LOOP + FETCH group_cursor INTO group_uuid, group_yaml; + + IF done THEN + LEAVE group_loop; + END IF; + + IF group_yaml IS NULL OR group_yaml = '' THEN + SELECT yaml INTO instance_yaml + FROM ModelServiceInstanceVO + WHERE modelServiceGroupUuid = group_uuid + LIMIT 1; + + IF instance_yaml IS NOT NULL AND instance_yaml != '' THEN + UPDATE ModelServiceInstanceGroupVO + SET yaml = instance_yaml + WHERE uuid = group_uuid; + + SELECT CONCAT('updated group_uuid: ', group_uuid, ' yaml'); + END IF; + ELSE + SELECT CONCAT('group_uuid: ', group_uuid, ' yaml is not null, skip'); + END IF; + END LOOP; + + CLOSE group_cursor; + + SELECT 'update_instance_group_yaml done'; +END$$ + +DELIMITER ; + +CALL update_instance_group_yaml(); \ No newline at end of file diff --git a/conf/db/upgrade/V5.3.28__schema.sql b/conf/db/upgrade/V5.3.28__schema.sql new file mode 100644 index 00000000000..171950ac050 --- /dev/null +++ b/conf/db/upgrade/V5.3.28__schema.sql @@ -0,0 +1,181 @@ +DROP PROCEDURE IF EXISTS createThickProvisionVolumeTag; +DELIMITER $$ +CREATE PROCEDURE createThickProvisionVolumeTag() +BEGIN + DECLARE volUuid VARCHAR(32); + DECLARE newTagUuid VARCHAR(32); + DECLARE done INT DEFAULT FALSE; + + DECLARE volCursor CURSOR FOR + SELECT uuid + FROM zstack.VolumeVO + WHERE type = 'Memory' + AND primaryStorageUuid IN ( + SELECT uuid + FROM zstack.PrimaryStorageVO + WHERE type = 'SharedBlock' + ) + AND uuid NOT IN ( + SELECT resourceUuid + FROM zstack.SystemTagVO + WHERE resourceType = 'VolumeVO' + AND tag = 'volumeProvisioningStrategy::ThickProvisioning' + ); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN volCursor; + + read_loop: + LOOP + FETCH volCursor INTO volUuid; + IF done THEN + LEAVE read_loop; + END IF; + + SET newTagUuid = REPLACE(UUID(), '-', ''); + + INSERT INTO zstack.SystemTagVO (uuid, resourceUuid, resourceType, inherent, type, tag, createDate, lastOpDate) + VALUES (newTagUuid, volUuid, 'VolumeVO', 0, 'System', 'volumeProvisioningStrategy::ThickProvisioning', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()); + END LOOP; + + CLOSE volCursor; + SELECT CURTIME() AS finishTime; +END $$ +DELIMITER ; + +CALL createThickProvisionVolumeTag(); +DROP PROCEDURE IF EXISTS createThickProvisionVolumeTag; + +ALTER TABLE `zstack`.`EncryptionIntegrityVO` MODIFY COLUMN `resourceUuid` varchar(128) NOT NULL; + +ALTER TABLE `zstack`.`OAuth2ClientVO` ADD COLUMN `pluginUuid` varchar(32) DEFAULT NULL; + +CREATE TABLE `zstack`.`ObservabilityServerOfferingVO`( + `uuid` varchar(32) NOT NULL UNIQUE, + `managementNetworkUuid` varchar(32) DEFAULT NULL, + `publicNetworkUuid` varchar(32) DEFAULT NULL, + `imageUuid` varchar(32) NOT NULL, + `zoneUuid` varchar(32) NOT NULL, + `isDefault` tinyint(1) unsigned DEFAULT 0, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE ObservabilityServerOfferingVO ADD CONSTRAINT fkObservabilityServerOfferingVOImageEO FOREIGN KEY (imageUuid) REFERENCES ImageEO (uuid) ON DELETE CASCADE; +ALTER TABLE ObservabilityServerOfferingVO ADD CONSTRAINT fkObservabilityServerOfferingVOInstanceOfferingEO FOREIGN KEY (uuid) REFERENCES InstanceOfferingEO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE; +ALTER TABLE ObservabilityServerOfferingVO ADD CONSTRAINT fkObservabilityServerOfferingVOL3NetworkEO FOREIGN KEY (managementNetworkUuid) REFERENCES L3NetworkEO (uuid) ON DELETE CASCADE; +ALTER TABLE ObservabilityServerOfferingVO ADD CONSTRAINT fkObservabilityServerOfferingVOL3NetworkEO1 FOREIGN KEY (publicNetworkUuid) REFERENCES L3NetworkEO (uuid) ON DELETE CASCADE; +ALTER TABLE ObservabilityServerOfferingVO ADD CONSTRAINT fkObservabilityServerOfferingVOZoneEO FOREIGN KEY (zoneUuid) REFERENCES ZoneEO (uuid) ON DELETE CASCADE; + +CREATE TABLE `zstack`.`ObservabilityServerVmVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `publicNetworkUuid` varchar(32) DEFAULT NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE ObservabilityServerVmVO ADD CONSTRAINT fkObservabilityServerVmVOVmInstanceEO FOREIGN KEY (uuid) REFERENCES VmInstanceEO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE; + +CREATE TABLE `zstack`.`ObservabilityServerServiceRefVO`( + `id` BIGINT UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, + `observabilityServerOfferingUuid` varchar(32) DEFAULT NULL, + `observabilityServerUuid` varchar(32) NOT NULL, + `serviceUuid` varchar(32) NOT NULL, + `serviceType` varchar(32) NOT NULL, + `observabilityServerPublicIp` varchar(32) DEFAULT NULL, + `servicePublicIp` varchar(32) DEFAULT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', +PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE ObservabilityServerServiceRefVO ADD CONSTRAINT fkObservabilityServerServiceRefVOResourceVO FOREIGN KEY (serviceUuid) REFERENCES ResourceVO (uuid) ON DELETE CASCADE; + +CREATE TABLE IF NOT EXISTS `zstack`.`CbtTaskVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `status` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`CbtTaskResourceRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `taskUuid` varchar(32) NOT NULL, + `resourceUuid` varchar(32) NOT NULL, + `resourceType` varchar(255) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + INDEX `idxCbtTaskResourceRefVOtaskUuid` (`taskUuid`), + INDEX `idxCbtTaskResourceRefVOresourceUuid` (`resourceUuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`LogServerVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) NULL, + `category` varchar(255) NOT NULL, + `type` varchar(255) NOT NULL, + `level` varchar(255) NULL, + `configuration` text NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('GuestVmScriptEO', 'encodingType', 'VARCHAR(32)', 1, 'PlainText'); +CALL ADD_COLUMN('GuestVmScriptExecutedRecordVO', 'encodingType', 'VARCHAR(32)', 1, 'PlainText'); +DROP VIEW IF EXISTS `zstack`.`GuestVmScriptVO`; +CREATE VIEW `zstack`.`GuestVmScriptVO` AS SELECT uuid, name, description, platform, encodingType, scriptContent, renderParams, scriptType, scriptTimeout, version, createDate, lastOpDate FROM `zstack`.`GuestVmScriptEO` WHERE deleted IS NULL; + +UPDATE `zstack`.`VolumeSnapshotTreeVO` t JOIN `zstack`.`VolumeVO` v ON t.volumeUuid = v.uuid +SET t.rootImageUuid = v.rootImageUuid +WHERE t.current = true + AND v.rootImageUuid IS NOT NULL + AND t.rootImageUuid IS NULL; + +CALL ADD_COLUMN('SecurityGroupVO', 'vSwitchType', 'VARCHAR(32)', 0, 'LinuxBridge'); + +DROP TABLE IF EXISTS HostHaStateVO; +CREATE TABLE `HostHaStateVO` ( + `id` BIGINT UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, + `hostUuid` VARCHAR(32) NOT NULL, + `primaryStorageUuid` VARCHAR(32) NOT NULL, + `state` varchar(32), + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `HostHaStateVO_HostEO_uuid_fk` FOREIGN KEY (`hostUuid`) REFERENCES `HostEO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `HostHaStateVO_PrimaryStorageEO_uuid_fk` FOREIGN KEY (`primaryStorageUuid`) REFERENCES `PrimaryStorageEO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ZdfsVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `zoneUuid` varchar(32) NULL, + `url` varchar(255) NOT NULL, + `hostName` varchar(255) NOT NULL, + `sshPort` int(16) not NULL, + `status` varchar(32) NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ZdfsStorageVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `endPoint` varchar(255) NOT NULL, + `type` varchar(32) NOT NULL, + `accessKey` varchar(255) NULL, + `secretKey` varchar(255) NULL, + `usedCapacity` bigint(20) unsigned NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('ModelCenterVO', 'zoneUuid', 'VARCHAR(32)', 1, NULL); +CALL ADD_COLUMN('ModelCenterVO', 'zdfsUuid', 'VARCHAR(32)', 1, NULL); +ALTER TABLE ModelCenterVO ADD CONSTRAINT fkModelCenterVOZoneVO FOREIGN KEY (zoneUuid) REFERENCES ZoneEO (uuid) ON DELETE CASCADE; +ALTER TABLE ModelCenterVO ADD CONSTRAINT fkModelCenterVOZdfsVO FOREIGN KEY (zdfsUuid) REFERENCES ZdfsVO (uuid) ON DELETE SET NULL; \ No newline at end of file diff --git a/conf/db/upgrade/V5.3.36__schema.sql b/conf/db/upgrade/V5.3.36__schema.sql new file mode 100644 index 00000000000..d7a568582ea --- /dev/null +++ b/conf/db/upgrade/V5.3.36__schema.sql @@ -0,0 +1,13 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`VolumeCbtBackupRecordVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `taskUuid` varchar(32) NOT NULL, + `volumeUuid` varchar(32) NOT NULL, + `mode` varchar(255) NOT NULL, + `target` varchar(2048) NOT NULL, + `scratchNodeName` varchar(255) NOT NULL, + `bitmapName` varchar(255) NOT NULL, + `lastBitmapName` varchar(255), + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/conf/db/upgrade/V5.3.40__schema.sql b/conf/db/upgrade/V5.3.40__schema.sql new file mode 100644 index 00000000000..2310be14e45 --- /dev/null +++ b/conf/db/upgrade/V5.3.40__schema.sql @@ -0,0 +1,223 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceImageVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `modelServiceUuid` varchar(32) NOT NULL, + `cpuArchitecture` varchar(32) NOT NULL, + `vmImageUuid` varchar(32) NULL, + `dockerImage` varchar(255) NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + UNIQUE KEY `ukModelServiceCpuArch` (`modelServiceUuid`,`cpuArchitecture`) USING BTREE, + CONSTRAINT `fkModelServiceImageVOModelServiceVO` FOREIGN KEY (`modelServiceUuid`) REFERENCES `ModelServiceVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('ModelServiceVO', 'gpuVendors', 'varchar(255)', 1, 'NULL'); +CALL ADD_COLUMN('ModelServiceVO', 'cpuArchitectures', 'varchar(255)', 1, 'NULL'); + +DROP PROCEDURE IF EXISTS migrate_model_service_image_data; +DELIMITER $$ +CREATE PROCEDURE migrate_model_service_image_data() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE service_uuid VARCHAR(32); + DECLARE vm_image_uuid VARCHAR(32); + DECLARE docker_image VARCHAR(255); + DECLARE model_service_image_uuid VARCHAR(32); + DECLARE cpu_arch VARCHAR(32); + DECLARE existing_uuid VARCHAR(32); + + DECLARE all_services_cursor CURSOR FOR + SELECT uuid FROM ModelServiceVO; + + DECLARE vm_cursor CURSOR FOR + SELECT ms.uuid, ms.vmImageUuid + FROM ModelServiceVO ms + WHERE ms.vmImageUuid IS NOT NULL; + + DECLARE docker_cursor CURSOR FOR + SELECT ms.uuid, ms.dockerImage + FROM ModelServiceVO ms + WHERE ms.dockerImage IS NOT NULL; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN all_services_cursor; + all_services_loop: LOOP + FETCH all_services_cursor INTO service_uuid; + IF done THEN + SET done = FALSE; + LEAVE all_services_loop; + END IF; + + IF NOT EXISTS (SELECT 1 FROM ModelServiceImageVO WHERE modelServiceUuid = service_uuid) THEN + SET model_service_image_uuid = REPLACE(UUID(),'-',''); + INSERT INTO ModelServiceImageVO (uuid, modelServiceUuid, cpuArchitecture, createDate, lastOpDate) + VALUES (model_service_image_uuid, service_uuid, 'x86_64', NOW(), NOW()); + END IF; + END LOOP; + CLOSE all_services_cursor; + + OPEN vm_cursor; + vm_read_loop: LOOP + FETCH vm_cursor INTO service_uuid, vm_image_uuid; + IF done THEN + SET done = FALSE; + LEAVE vm_read_loop; + END IF; + + SELECT IFNULL(img.architecture, 'x86_64') INTO cpu_arch + FROM ImageVO img + WHERE img.uuid = vm_image_uuid + LIMIT 1; + + IF cpu_arch IS NULL THEN + SET cpu_arch = 'x86_64'; + END IF; + + SELECT uuid INTO existing_uuid + FROM ModelServiceImageVO + WHERE modelServiceUuid = service_uuid AND cpuArchitecture = cpu_arch + LIMIT 1; + + IF existing_uuid IS NULL THEN + SET model_service_image_uuid = REPLACE(UUID(),'-',''); + INSERT INTO ModelServiceImageVO (uuid, modelServiceUuid, cpuArchitecture, vmImageUuid, createDate, lastOpDate) + VALUES (model_service_image_uuid, service_uuid, cpu_arch, vm_image_uuid, NOW(), NOW()); + ELSE + UPDATE ModelServiceImageVO + SET vmImageUuid = vm_image_uuid, lastOpDate = NOW() + WHERE uuid = existing_uuid; + END IF; + + SET existing_uuid = NULL; + END LOOP; + CLOSE vm_cursor; + + OPEN docker_cursor; + docker_read_loop: LOOP + FETCH docker_cursor INTO service_uuid, docker_image; + IF done THEN + LEAVE docker_read_loop; + END IF; + + SET cpu_arch = 'x86_64'; + + SELECT uuid INTO existing_uuid + FROM ModelServiceImageVO + WHERE modelServiceUuid = service_uuid AND cpuArchitecture = cpu_arch + LIMIT 1; + + IF existing_uuid IS NULL THEN + SET model_service_image_uuid = REPLACE(UUID(),'-',''); + INSERT INTO ModelServiceImageVO (uuid, modelServiceUuid, cpuArchitecture, dockerImage, createDate, lastOpDate) + VALUES (model_service_image_uuid, service_uuid, cpu_arch, docker_image, NOW(), NOW()); + ELSE + UPDATE ModelServiceImageVO + SET dockerImage = docker_image, lastOpDate = NOW() + WHERE uuid = existing_uuid; + END IF; + + SET existing_uuid = NULL; + END LOOP; + CLOSE docker_cursor; +END$$ +DELIMITER ; + +CALL migrate_model_service_image_data(); + +DROP PROCEDURE IF EXISTS ensure_model_service_image_completeness; +DELIMITER $$ +CREATE PROCEDURE ensure_model_service_image_completeness() +BEGIN + INSERT INTO ModelServiceImageVO (uuid, modelServiceUuid, cpuArchitecture, createDate, lastOpDate) + SELECT REPLACE(UUID(),'-',''), ms.uuid, 'x86_64', NOW(), NOW() + FROM ModelServiceVO ms + WHERE NOT EXISTS ( + SELECT 1 FROM ModelServiceImageVO msi WHERE msi.modelServiceUuid = ms.uuid + ); +END$$ +DELIMITER ; + +CALL ensure_model_service_image_completeness(); +DROP PROCEDURE IF EXISTS ensure_model_service_image_completeness; +DROP PROCEDURE IF EXISTS migrate_model_service_image_data; + +-- 确认数据完整后再删除字段 +CALL DROP_COLUMN('ModelServiceVO', 'vmImageUuid'); +CALL DROP_COLUMN('ModelServiceVO', 'dockerImage'); + +DROP PROCEDURE IF EXISTS update_model_service_cpu_arch; +DELIMITER $$ +CREATE PROCEDURE update_model_service_cpu_arch() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE service_uuid VARCHAR(32); + DECLARE vm_image_uuid VARCHAR(32); + DECLARE cpu_arch VARCHAR(32); + DECLARE model_service_image_uuid VARCHAR(32); + DECLARE img_cursor CURSOR FOR + SELECT ms.uuid, msi.vmImageUuid, img.architecture + FROM ModelServiceVO ms + JOIN ModelServiceImageVO msi ON ms.uuid = msi.modelServiceUuid + JOIN ImageVO img ON msi.vmImageUuid = img.uuid + WHERE msi.vmImageUuid IS NOT NULL; + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN img_cursor; + + read_loop: LOOP + FETCH img_cursor INTO service_uuid, vm_image_uuid, cpu_arch; + IF done THEN + LEAVE read_loop; + END IF; + + UPDATE ModelServiceVO + SET cpuArchitectures = cpu_arch + WHERE uuid = service_uuid; + END LOOP; + + CLOSE img_cursor; +END$$ +DELIMITER ; + +CALL update_model_service_cpu_arch(); +DROP PROCEDURE IF EXISTS update_model_service_cpu_arch; + +CREATE TABLE IF NOT EXISTS `zstack`.`ContainerBackupStorageVO` ( + `uuid` varchar(32) NOT NULL, + `endpointUuid` varchar(32) NOT NULL, + `id` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkContainerBackupStorageVOBackupStorageEO` FOREIGN KEY (`uuid`) REFERENCES `BackupStorageEO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkContainerBackupStorageVOContainerManagementEndpointVO` FOREIGN KEY (`endpointUuid`) REFERENCES `ContainerManagementEndpointVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceCpuArchitectureVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `modelServiceUuid` varchar(32) NOT NULL, + `architecture` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkModelServiceCpuArchitectureVOModelServiceVO` FOREIGN KEY (`modelServiceUuid`) REFERENCES `ModelServiceVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceGpuVendorVO` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `modelServiceUuid` varchar(32) NOT NULL, + `gpuVendor` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkModelServiceGpuVendorVOModelServiceVO` FOREIGN KEY (`modelServiceUuid`) REFERENCES `ModelServiceVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ContainerImageVO` ( + `uuid` varchar(32) NOT NULL, + `registryUrl` varchar(255) DEFAULT NULL, + `endpointUuid` varchar(32) NOT NULL, + `imageTag` varchar(64) DEFAULT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkContainerImageVOImageEO` FOREIGN KEY (`uuid`) REFERENCES `ImageEO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkContainerImageVOContainerManagementEndpointVO` FOREIGN KEY (`endpointUuid`) REFERENCES `ContainerManagementEndpointVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/conf/db/upgrade/V5.3.46__schema.sql b/conf/db/upgrade/V5.3.46__schema.sql new file mode 100644 index 00000000000..717fc5dcf4b --- /dev/null +++ b/conf/db/upgrade/V5.3.46__schema.sql @@ -0,0 +1,80 @@ +-- Migration script to update AuditVO table from AccountId to ProjectId. +-- This script efficiently migrates data using a single JOIN operation. + +DELIMITER $$ +DROP PROCEDURE IF EXISTS changeAccountIdToProjectIdForAuditVO$$ +CREATE PROCEDURE changeAccountIdToProjectIdForAuditVO() + pro_label: BEGIN + DECLARE v_total_updated INT DEFAULT 0; + + IF (SELECT COUNT(*) FROM IAM2ProjectAccountRefVO) = 0 THEN +SELECT 'No IAM2ProjectAccountRefVO records found, skipping migration.' AS message; +LEAVE pro_label; +END IF; + +SELECT 'Starting migration of AuditsVO records from AccountUuid to ProjectUuid...' AS message; + +UPDATE AuditsVO a + JOIN IAM2ProjectAccountRefVO i +ON a.resourceUuid = i.accountUuid + SET a.resourceUuid = i.projectUuid, + a.resourceType = CASE + WHEN a.resourceType = 'AccountVO' THEN 'IAM2ProjectVO' + ELSE a.resourceType +END +WHERE a.apiName = 'org.zstack.header.identity.APIUpdateQuotaMsg'; + SET v_total_updated = ROW_COUNT(); +SELECT CONCAT('Migration completed successfully. Total records updated: ', v_total_updated) AS message; + +END$$ + +DELIMITER ; +CALL changeAccountIdToProjectIdForAuditVO(); +DROP PROCEDURE IF EXISTS changeAccountIdToProjectIdForAuditVO; + +CALL ADD_COLUMN('SdnControllerVO', 'vendorVersion', 'VARCHAR(32)', 0, 'V1'); + +CREATE TABLE IF NOT EXISTS `zstack`.`H3cSdnControllerTenantVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `sdnControllerUuid` varchar(32) NOT NULL, + `tenantUuid` varchar(255) DEFAULT NULL, + `vdsUuid` varchar(255) DEFAULT NULL, + `tenantName` varchar(255) DEFAULT NULL, + `vdsName` varchar(255) DEFAULT NULL, + `cloudDomainName` varchar(255) DEFAULT NULL, + `state` varchar(32) NOT NULL DEFAULT "Enabled", + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkH3cSdnControllerTenantVOSdnControllerVO` FOREIGN KEY (`sdnControllerUuid`) REFERENCES `SdnControllerVO` (`uuid`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`H3cSdnSubnetIpRangeRefVO` ( + `id` BIGINT UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, + `sdnControllerUuid` varchar(32) NOT NULL, + `ipRangeUuid` varchar(32) NOT NULL, + `subnetUuid` varchar(255) NOT NULL, + `l2NetworkUuid` varchar(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`), + CONSTRAINT `fkH3cSdnSubnetIpRangeRefVOSdnControllerVO` FOREIGN KEY (`sdnControllerUuid`) REFERENCES `SdnControllerVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkH3cSdnSubnetIpRangeRefVOIpRangeVO` FOREIGN KEY (`ipRangeUuid`) REFERENCES `IpRangeEO` (`uuid`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DELETE FROM UserTagVO WHERE uuid = 'a4de80903e57422699fb05bd367a3cb4'; + +CALL ADD_COLUMN('PciDeviceSpecVO', 'allowResourceConfigWithMultipleDevices', 'tinyint(1)', 0, '1'); + +CALL ADD_COLUMN('GpuDeviceVO', 'opaque', 'MEDIUMTEXT', 1, NULL); + +CALL ADD_COLUMN('ModelServiceInstanceVO', 'nodeRank', 'int', 1, 0); + +CREATE TABLE IF NOT EXISTS `zstack`.`GpuDeviceSpecVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `memory` bigint unsigned NULL DEFAULT 0, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkGpuDeviceSpecVOPciDeviceSpecVO` FOREIGN KEY (`uuid`) REFERENCES `PciDeviceSpecVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('ModelServiceVO', 'supportDistributed', 'tinyint(1)', 0, 0); diff --git a/conf/db/upgrade/V5.3.52__schema.sql b/conf/db/upgrade/V5.3.52__schema.sql new file mode 100644 index 00000000000..919a97c0afe --- /dev/null +++ b/conf/db/upgrade/V5.3.52__schema.sql @@ -0,0 +1,79 @@ +CALL ADD_COLUMN('ModelServiceInstanceVO', 'name', 'VARCHAR(255)', 1, NULL); +CALL ADD_COLUMN('ModelServiceInstanceVO', 'namespace', 'VARCHAR(255)', 1, NULL); + +-- Delete old vm records for pod and resync will be done after node started +DELETE FROM `ResourceVO` where resourceType = 'VmInstanceVO' and uuid in (SELECT uuid FROM `VmInstanceEO` where hypervisorType = 'Native'); +DELETE FROM `VmInstanceEO` where hypervisorType = 'Native'; + +CREATE TABLE `zstack`.`PodVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `status` varchar(64) NOT NULL, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('GpuDeviceVO', 'gpuType', 'VARCHAR(255)', 1, NULL); +CALL ADD_COLUMN('GpuDeviceSpecVO', 'gpuType', 'VARCHAR(255)', 1, NULL); + +DROP PROCEDURE IF EXISTS update_gpu_type_from_pci; + +DELIMITER $$ + +CREATE PROCEDURE update_gpu_type_from_pci() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE pci_uuid_val VARCHAR(32); + DECLARE pci_host_uuid_val VARCHAR(32); + DECLARE pci_description_val VARCHAR(2048); + DECLARE kvm_host_count INT; + + DECLARE cur CURSOR FOR + SELECT pd.uuid, pd.hostUuid, pd.description + FROM PciDeviceVO pd + INNER JOIN GpuDeviceVO gd ON pd.uuid = gd.uuid; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN cur; + + read_loop: LOOP + FETCH cur INTO pci_uuid_val, pci_host_uuid_val, pci_description_val; + + IF done THEN + LEAVE read_loop; + END IF; + + SELECT COUNT(*) INTO kvm_host_count FROM KVMHostVO WHERE uuid = pci_host_uuid_val; + + IF kvm_host_count > 0 THEN + UPDATE GpuDeviceVO + SET gpuType = pci_description_val + WHERE uuid = pci_uuid_val; + END IF; + + END LOOP; + + SELECT CURTIME(); + + CLOSE cur; +END$$ + +DELIMITER ; + +CALL update_gpu_type_from_pci(); + +UPDATE ModelCenterVO m +LEFT JOIN L3NetworkEO l ON m.storageNetworkUuid = l.uuid +SET m.storageNetworkUuid = NULL +WHERE m.storageNetworkUuid IS NOT NULL AND l.uuid IS NULL; + +UPDATE ModelCenterVO m +LEFT JOIN L3NetworkEO l ON m.serviceNetworkUuid = l.uuid +SET m.serviceNetworkUuid = NULL +WHERE m.serviceNetworkUuid IS NOT NULL AND l.uuid IS NULL; + +ALTER TABLE ModelCenterVO + MODIFY COLUMN storageNetworkUuid VARCHAR(32) NULL, + MODIFY COLUMN serviceNetworkUuid VARCHAR(32) NULL; + +CALL ADD_CONSTRAINT('ModelCenterVO', 'fkModelCenterVOStorageNetworkUuid', 'storageNetworkUuid', 'L3NetworkEO', 'uuid', 'SET NULL'); +CALL ADD_CONSTRAINT('ModelCenterVO', 'fkModelCenterVOServiceNetworkUuid', 'serviceNetworkUuid', 'L3NetworkEO', 'uuid', 'SET NULL'); diff --git a/conf/db/upgrade/V5.3.6__schema.sql b/conf/db/upgrade/V5.3.6__schema.sql new file mode 100644 index 00000000000..4f19bb82cda --- /dev/null +++ b/conf/db/upgrade/V5.3.6__schema.sql @@ -0,0 +1,65 @@ +CREATE TABLE IF NOT EXISTS `zstack`.`KoAlSecretResourcePoolVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `managementIp` varchar(32) NOT NULL, + `port` int unsigned NOT NULL, + `secretKey` varchar(255) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkKoAlSecretResourcePoolVOSecretResourcePoolVO FOREIGN KEY (uuid) REFERENCES SecretResourcePoolVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`ModelEvaluationTaskVO` ADD taskRequestInJson VARCHAR(8192) DEFAULT NULL; +ALTER TABLE `zstack`.`ModelEvaluationTaskVO` ADD type VARCHAR(32) DEFAULT NULL; +ALTER TABLE `zstack`.`ModelEvaluationTaskVO` MODIFY `evaluatedServiceGroupUuid` varchar(32) DEFAULT NULL; +ALTER TABLE `zstack`.`ModelEvaluationTaskVO` MODIFY datasetUuid VARCHAR(32) DEFAULT NULL; + +INSERT INTO SystemTagVO +(`uuid`, `resourceUuid`, `resourceType`, `inherent`, `type`, `tag`, `createDate`, `lastOpDate`) +SELECT + REPLACE(UUID(), '-', ''), -- 生成不含连字符的uuid + uuid, -- 使用DatasetVO的uuid作为resourceUuid + 'DatasetVO', -- resourceType + 1, -- inherent + 'System', -- type + 'dataset::usage::scenarios::ModelEval', -- tag + CURRENT_TIMESTAMP(), -- createDate + CURRENT_TIMESTAMP() -- lastOpDate +FROM DatasetVO +WHERE `system` = true; + +INSERT INTO SystemTagVO +(`uuid`, `resourceUuid`, `resourceType`, `inherent`, `type`, `tag`, `createDate`, `lastOpDate`) +SELECT + REPLACE(UUID(), '-', ''), -- 生成不含连字符的uuid + uuid, -- 使用DatasetVO的uuid作为resourceUuid + 'DatasetVO', -- resourceType + 1, -- inherent + 'System', -- type + 'dataset::datatype::Text', -- tag + CURRENT_TIMESTAMP(), -- createDate + CURRENT_TIMESTAMP() -- lastOpDate +FROM DatasetVO +WHERE `system` = true; + +CALL RENAME_TABLE('ContainerManagementVmVO', 'ContainerManagementEndpointVO'); + +CALL DROP_COLUMN('ContainerManagementEndpointVO', 'vmInstanceUuid'); + +CREATE TABLE IF NOT EXISTS `zstack`.`NativeClusterVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'native cluster uuid', + `endpointUuid` varchar(32) NOT NULL COMMENT 'container endpoint uuid', + `bizUrl` varchar(255) DEFAULT NULL COMMENT 'business network url', + `masterUrl` varchar(255) DEFAULT NULL COMMENT 'management network url', + `kubeConfig` text COMMENT 'kubernetes configuration', + `id` bigint(20) DEFAULT NULL COMMENT 'kubernetes cluster id', + `prometheusURL` varchar(255) DEFAULT NULL COMMENT 'prometheus monitoring url', + `version` varchar(64) DEFAULT NULL COMMENT 'kubernetes version', + `nodeCount` int DEFAULT NULL COMMENT 'number of nodes', + `createType` varchar(32) DEFAULT NULL COMMENT 'cluster creation type', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`NativeHostVO` ( + `uuid` varchar(32) NOT NULL UNIQUE COMMENT 'host uuid', + `endpointUuid` varchar(32) NOT NULL COMMENT 'container endpoint uuid', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/conf/db/upgrade/V5.4.0__schema.sql b/conf/db/upgrade/V5.4.0__schema.sql new file mode 100644 index 00000000000..693b0f60b6a --- /dev/null +++ b/conf/db/upgrade/V5.4.0__schema.sql @@ -0,0 +1,221 @@ +CREATE TABLE `SSOClientAttributeVO` ( + `uuid` VARCHAR(32) NOT NULL, + `name` TEXT NOT NULL, + `value` TEXT DEFAULT NULL, + `type` VARCHAR(32) NOT NULL, + `purpose` VARCHAR(32) NOT NULL, + `ssoClientUuid` VARCHAR(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`), + CONSTRAINT `fkSSOClientAttributeVOSSOClientVO` FOREIGN KEY (`ssoClientUuid`) REFERENCES SSOClientVO (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`LicenseAuthorizedNodeVO` ( + `uuid` char(32) NOT NULL UNIQUE, + `appId` char(32) NOT NULL, + `ip` varchar(255) NOT NULL, + `lastSyncDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59', + `status` varchar(64) NOT NULL, + `type` varchar(64) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59', + PRIMARY KEY (`uuid`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`LicenseAuthorizedCapacityVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `nodeUuid` char(32) NOT NULL, + `resourceUuid` char(32) DEFAULT NULL, + `quotaType` varchar(64) NOT NULL, + `quota` bigint unsigned DEFAULT 0, + `licenseType` varchar(64) NOT NULL, + `type` varchar(64) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59' ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59', + PRIMARY KEY (`id`), + CONSTRAINT `fkLicenseAuthorizedCapacityLicenseAuthorizedNode` FOREIGN KEY (`nodeUuid`) REFERENCES `LicenseAuthorizedNodeVO` (`uuid`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`LicenseAuthorizeHistoryVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `nodeUuid` char(32) NOT NULL, + `resourceUuid` char(32) DEFAULT NULL, + `quotaType` varchar(64) NOT NULL, + `usageFrom` bigint unsigned DEFAULT 0, + `usageTo` bigint unsigned DEFAULT NULL, + `quota` bigint unsigned DEFAULT 0, + `licenseType` varchar(64) NOT NULL, + `type` varchar(64) NOT NULL, + `action` varchar(255) NOT NULL, + `result` varchar(64) DEFAULT NULL, + `error` text DEFAULT NULL, + `requestUuid` char(32) NOT NULL, + `createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59', + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`LicenseHistoryVO` ADD COLUMN `quotaType` varchar(64) DEFAULT 'None'; +ALTER TABLE HostCapacityVO ADD cpuCoreNum int unsigned NOT NULL DEFAULT 0; + +CREATE TABLE `zstack`.`L3NetworkSequenceNumberVO` ( + `id` int unsigned NOT NULL UNIQUE AUTO_INCREMENT, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `zstack`.`L3NetworkEO` ADD COLUMN `internalId` INT(32) unsigned DEFAULT 0; +DROP VIEW IF EXISTS `zstack`.`L3NetworkVO`; +CREATE VIEW `zstack`.`L3NetworkVO` AS SELECT uuid, name, internalId, description, state, type, zoneUuid, l2NetworkUuid, `system`, dnsDomain, createDate, lastOpDate, category, ipVersion, enableIPAM, isolated FROM `zstack`.`L3NetworkEO` WHERE deleted IS NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`ImageGroupVO` ( + `uuid` VARCHAR(32) NOT NULL UNIQUE, + `name` VARCHAR(255) NOT NULL, + `status` varchar(32) NOT NULL, + `description` VARCHAR(2048) DEFAULT NULL, + `imageCount` int unsigned NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`ImageGroupRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `imageUuid` VARCHAR(32) NOT NULL, + `imageGroupUuid` VARCHAR(32) NOT NULL, + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE SecurityGroupRuleVO MODIFY COLUMN `dstPortRange` varchar(1024) DEFAULT NULL; +ALTER TABLE SecurityGroupRuleVO MODIFY COLUMN `srcPortRange` varchar(1024) DEFAULT NULL; + +# Delete data with blank lines at the end (Reconnect host added again) +DELETE FROM `zstack`.`HostNetworkInterfaceVO` WHERE `pciDeviceAddress` LIKE '%\n'; + +CREATE TABLE IF NOT EXISTS `zstack`.`SAML2ClientVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `idpMetadataBase64` TEXT, + `spX509Certificate` TEXT, + `spPrivateKey` TEXT, + `spMetadataUrl` varchar(256) DEFAULT NULL, + `state` varchar(32) NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkSAMLClientVOSSOClientVO` FOREIGN KEY (`uuid`) REFERENCES `SSOClientVO` (`uuid`) ON UPDATE RESTRICT ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`PhysicalSwitchVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `ip` varchar(64) NOT NULL, + `mac` varchar(32) NOT NULL, + `mode` varchar(128) NOT NULL, + `softwareVersion` varchar(128) NOT NULL, + `sdnControllerUuid` varchar(32) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`PhysicalSwitchPortVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `ethTrunkName` varchar(255) DEFAULT NULL, + `portType` varchar(64) NOT NULL, + `peerInterfaceUuid` varchar(32) DEFAULT NULL, + `switchUuid` varchar(32) NOT NULL, + `sdnControllerUuid` varchar(32) DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkPhysicalSwitchPortVOHostNetworkInterfaceVO` FOREIGN KEY (`peerInterfaceUuid`) REFERENCES `HostNetworkInterfaceVO` (`uuid`) ON DELETE SET NULL, + CONSTRAINT `fkPhysicalSwitchPortVOPhysicalSwitchVO` FOREIGN KEY (`switchUuid`) REFERENCES `PhysicalSwitchVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HuaweiIMasterFabricVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `sdnControllerUuid` varchar(32) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `state` varchar(32) NOT NULL DEFAULT "Enabled", + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHuaweiIMasterFabricVOSdnControllerVO` FOREIGN KEY (`sdnControllerUuid`) REFERENCES `SdnControllerVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HuaweiIMasterTenantVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `sdnControllerUuid` varchar(32) NOT NULL, + `state` varchar(32) NOT NULL DEFAULT "Enabled", + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHuaweiIMasterTenantVOSdnControllerVO` FOREIGN KEY (`sdnControllerUuid`) REFERENCES `SdnControllerVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HuaweiIMasterVpcVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `tenantId` varchar(32) NOT NULL, + `fabricId` varchar(2048) NOT NULL, + `sdnControllerUuid` varchar(32) NOT NULL, + `isVpcDeployed` BOOLEAN NOT NULL DEFAULT TRUE, + `state` varchar(32) NOT NULL DEFAULT "Enabled", + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHuaweiIMasterVpcVOTenantVO` FOREIGN KEY (`tenantId`) REFERENCES `HuaweiIMasterTenantVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkHuaweiIMasterVpcVOSdnControllerVO` FOREIGN KEY (`sdnControllerUuid`) REFERENCES `SdnControllerVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HuaweiIMasterVRouterVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(255) NOT NULL, + `description` varchar(2048) DEFAULT NULL, + `logicalNetworkId` varchar(32) NOT NULL, + `tenantId` varchar(32) NOT NULL, + `fabricUuid` varchar(32) NOT NULL, + `sdnControllerUuid` varchar(32) NOT NULL, + `state` varchar(32) NOT NULL DEFAULT "Enabled", + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`), + CONSTRAINT `fkHuaweiIMasterVRouterVOLogicalNetworkVO` FOREIGN KEY (`logicalNetworkId`) REFERENCES `HuaweiIMasterVpcVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkHuaweiIMasterVRouterVOTenantVO` FOREIGN KEY (`tenantId`) REFERENCES `HuaweiIMasterTenantVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkHuaweiIMasterVRouterVOHuaweiIMasterFabricVO` FOREIGN KEY (`fabricUuid`) REFERENCES `HuaweiIMasterFabricVO` (`uuid`) ON DELETE CASCADE, + CONSTRAINT `fkHuaweiIMasterVRouterVOSdnControllerVO` FOREIGN KEY (`sdnControllerUuid`) REFERENCES `SdnControllerVO` (`uuid`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HardwareL2VxlanNetworkVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `vlan` int unsigned NOT NULL, + PRIMARY KEY (`uuid`), + CONSTRAINT fkHardwareL2VxlanNetworkVOL2NetworkEO FOREIGN KEY (uuid) REFERENCES L2NetworkEO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HuaweiIMasterSdnControllerVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + PRIMARY KEY (`uuid`), + CONSTRAINT fkHuaweiIMasterSdnControllerVOSdnControllerVO FOREIGN KEY (uuid) REFERENCES SdnControllerVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `zstack`.`HuaweiIMasterTenantFabricRefVO` ( + `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT, + `tenantUuid` varchar(32) NOT NULL, + `fabricUuid` varchar(32) NOT NULL, + `lastOpDate` timestamp ON UPDATE CURRENT_TIMESTAMP, + `createDate` timestamp, + PRIMARY KEY (`id`), + UNIQUE KEY `uk_tenant_fabric` (`tenantUuid`, `fabricUuid`), + CONSTRAINT fkHuaweiIMasterTenantFabricRefVOHuaweiIMasterFabricVO FOREIGN KEY (fabricUuid) REFERENCES HuaweiIMasterFabricVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE, + CONSTRAINT fkHuaweiIMasterTenantFabricRefVOHuaweiIMasterTenantVO FOREIGN KEY (tenantUuid) REFERENCES HuaweiIMasterTenantVO (uuid) ON UPDATE RESTRICT ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('HardwareL2VxlanNetworkPoolVO', 'startVlan', 'int unsigned', 1, NULL); +CALL ADD_COLUMN('HardwareL2VxlanNetworkPoolVO', 'endVlan', 'int unsigned', 1, NULL); \ No newline at end of file diff --git a/conf/db/upgrade/V5.4.2__schema.sql b/conf/db/upgrade/V5.4.2__schema.sql new file mode 100644 index 00000000000..476304fd72d --- /dev/null +++ b/conf/db/upgrade/V5.4.2__schema.sql @@ -0,0 +1,267 @@ +ALTER TABLE `zstack`.`MdevDeviceSpecVO` modify column name varchar(128) NOT NULL; +ALTER TABLE `zstack`.`MdevDeviceVO` modify column name varchar(128) NOT NULL; + +CALL ADD_COLUMN('ModelVO', 'framework', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'versionSemver', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'isLatestVersion', 'tinyint(1)', 1, '0'); +CALL ADD_COLUMN('ModelVO', 'artifactChecksum', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'artifactSizeBytes', 'bigint', 1, '0'); +CALL ADD_COLUMN('ModelVO', 'architectureType', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'frameworkVersion', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'requiredAccelerator', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'quantizationType', 'varchar(255)', 1, NULL); + +CALL RENAME_TABLE('ModelServiceImageVO', 'ModelServiceTemplateVO'); + +CALL ADD_COLUMN('ModelServiceTemplateVO', 'pythonVersionSemver', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelServiceTemplateVO', 'cudaVersion', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelServiceTemplateVO', 'cannVersion', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelServiceTemplateVO', 'frameworkVersionSemver', 'varchar(255)', 1, NULL); +CALL ADD_COLUMN('ModelServiceTemplateVO', 'gpuVendor', 'varchar(255)', 1, NULL); + +CALL ADD_COLUMN('PodVO', 'namespace', 'varchar(64)', 1, NULL); + +CREATE TABLE IF NOT EXISTS `zstack`.`KubernetesServiceVO` ( + `uuid` varchar(32) NOT NULL UNIQUE, + `name` varchar(64) NOT NULL, + `description` varchar(255) DEFAULT NULL, + `namespace` varchar(64) NOT NULL, + `type` varchar(20) NOT NULL, + `clusterIp` varchar(64) DEFAULT NULL, + `externalIp` varchar(64) DEFAULT NULL, + `ports` text, + `endpointUuid` varchar(32) NOT NULL, + `clusterId` INT DEFAULT NULL, + `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `lastOpDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CALL ADD_COLUMN('PodVO', 'clusterId', 'INT', 1, NULL); + +DELETE FROM `AccountResourceRefVO` +WHERE `concreteResourceType` = 'org.zstack.header.vm.VmInstanceVO' + AND `resourceUuid` NOT IN (SELECT `uuid` FROM `VmInstanceVO`); + +CALL DROP_COLUMN('ModelCenterCapacityVO', 'installationUsedCapacity'); +CALL ADD_COLUMN('NativeClusterVO', 'status', 'varchar(32)', 1, NULL); + +UPDATE `NativeClusterVO` SET `status` = 'Status_Cluster_Running' WHERE `status` IS NULL; + +CREATE TABLE IF NOT EXISTS `zstack`.`ModelServiceGpuVendorSpecRefVO` ( + `id` bigint NOT NULL AUTO_INCREMENT, + `refUuid` bigint UNSIGNED NOT NULL, + `specUuid` varchar(32) NOT NULL, + CONSTRAINT `pkModelServiceGpuVendorSpecRef` PRIMARY KEY (`id`), + CONSTRAINT `ukModelServiceGpuVendorSpecRefRefSpec` UNIQUE (`refUuid`, `specUuid`), + CONSTRAINT `fkModelServiceGpuVendorSpecRefRefUuid` FOREIGN KEY (`refUuid`) + REFERENCES `ModelServiceGpuVendorVO`(`id`) + ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE OR REPLACE VIEW PodGpuStatsVO AS +SELECT + p.uuid AS podUuid, + COUNT(g.uuid) AS gpuCount, + COALESCE(CAST(ROUND(AVG(g.memory)) AS SIGNED), 0) AS avgAllocatedMb, + COALESCE(CAST(SUM(g.memory) AS SIGNED), 0) AS totalGpuMemMb +FROM PodVO p + LEFT JOIN PciDeviceVO pci ON pci.vmInstanceUuid = p.uuid + LEFT JOIN GpuDeviceVO g ON g.uuid = pci.uuid +GROUP BY p.uuid; + +CALL ADD_COLUMN('GpuDeviceVO', 'allocateStatus', 'varchar(32)', 1, NULL); + +-- Upgrade GpuDeviceVO.allocateStatus based vmInstanceUuid +UPDATE GpuDeviceVO gpuDevice +JOIN PciDeviceVO pciDevice ON gpuDevice.uuid = pciDevice.uuid +SET gpuDevice.allocateStatus = + CASE + WHEN pciDevice.vmInstanceUuid IS NOT NULL THEN 'Allocated' + ELSE 'Unallocated' + END; + +DELIMITER $$ +CREATE PROCEDURE update_system_model_service_gpu_vendors() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE service_uuid VARCHAR(32); + DECLARE model_name VARCHAR(255); + DECLARE gpu_vendor_name VARCHAR(32); + + -- Cursor to iterate over the models + DECLARE models_cursor CURSOR FOR + SELECT name, vendor FROM system_models_to_update; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + -- Temporary table to hold the data + CREATE TEMPORARY TABLE IF NOT EXISTS system_models_to_update ( + name VARCHAR(255), + vendor VARCHAR(32) + ); + + -- Populate the temporary table + INSERT INTO system_models_to_update (name, vendor) VALUES + ('vLLM-0.7.2', 'NVIDIA'), + ('vLLM-0.8.5', 'NVIDIA'), + ('vLLM-0.9.2', 'NVIDIA'), + ('vLLM-0.11.0', 'NVIDIA'), + ('SGLang-0.4.9.post1', 'NVIDIA'), + ('SGLang-0.5.2', 'NVIDIA'), + ('Transformers-4.48.3', 'NVIDIA'), + ('Transformers-4.56.2', 'NVIDIA'), + ('sentence_transformers-3.1.1', 'NVIDIA'), + ('Diffusers-0.30.0', 'NVIDIA'), + ('Diffusers-0.35.1', 'NVIDIA'), + ('MindIE-2.0.RC1-910B', 'HUAWEI'), + ('MindIE-2.1.RC1-910B', 'HUAWEI'), + ('MindIE-1.0.0-310P', 'HUAWEI'), + ('vLLM-Ascend-0.11.0.rc0', 'HUAWEI'), + ('vLLM-0.5.0-HYGON-Z100L', 'HAIGUANG'), + ('vLLM-0.8.5-HYGON-K100-AI', 'HAIGUANG'), + ('vLLM-0.9.2-HYGON-K100-AI', 'HAIGUANG'), + ('vLLM-0.7.2-HYGON-K100-AI', 'HAIGUANG'), + ('MinerU2.5-2509', 'NVIDIA'); + + OPEN models_cursor; + update_loop: LOOP + FETCH models_cursor INTO model_name, gpu_vendor_name; + IF done THEN + LEAVE update_loop; + END IF; + + -- Find the model service uuid, only for system services + SELECT COUNT(*) INTO @cnt FROM `zstack`.`ModelServiceVO` WHERE name = model_name AND system = 1; + IF @cnt > 0 THEN + SELECT uuid INTO service_uuid FROM `zstack`.`ModelServiceVO` WHERE name = model_name AND system = 1 LIMIT 1; + ELSE + SET service_uuid = NULL; + END IF; + + -- If the model service exists, ensure the GPU vendor is associated + IF service_uuid IS NOT NULL THEN + SELECT CONCAT('INFO: Processing model=', model_name, ', service_uuid=', service_uuid, ', desired_vendor=', gpu_vendor_name) AS msg; + -- delete different gpu vendors + DELETE FROM `zstack`.`ModelServiceGpuVendorVO` + WHERE modelServiceUuid = service_uuid + AND gpuVendor <> gpu_vendor_name; + SELECT CONCAT('INFO: Deleted different GPU vendors for service_uuid=', service_uuid, ', deleted_rows=', ROW_COUNT()) AS msg; + IF NOT EXISTS (SELECT 1 FROM `zstack`.`ModelServiceGpuVendorVO` WHERE modelServiceUuid = service_uuid AND gpuVendor = gpu_vendor_name) THEN + INSERT INTO `zstack`.`ModelServiceGpuVendorVO` (modelServiceUuid, gpuVendor, createDate, lastOpDate) + VALUES (service_uuid, gpu_vendor_name, NOW(), NOW()); + SELECT CONCAT('INFO: Inserted GPU vendor=', gpu_vendor_name, ' for service_uuid=', service_uuid, ', inserted_rows=', ROW_COUNT()) AS msg; + ELSE + SELECT CONCAT('INFO: GPU vendor=', gpu_vendor_name, ' already exists for service_uuid=', service_uuid) AS msg; + END IF; + ELSE + SELECT CONCAT('WARN: Service not found for model=', model_name) AS msg; + END IF; + + SET service_uuid = NULL; + + END LOOP; + CLOSE models_cursor; + + -- Clean up + DROP TEMPORARY TABLE system_models_to_update; + +END $$ +DELIMITER ; + +CALL update_system_model_service_gpu_vendors(); +DROP PROCEDURE IF EXISTS update_system_model_service_gpu_vendors; + +DELIMITER $$ +CREATE PROCEDURE update_system_model_service_templates() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE service_uuid VARCHAR(32); + DECLARE model_name VARCHAR(255); + DECLARE gpu_vendor_name VARCHAR(32); + DECLARE py_version VARCHAR(255); + DECLARE cuda_version VARCHAR(255); + DECLARE cann_version VARCHAR(255); + DECLARE fw_version VARCHAR(255); + + DECLARE templates_cursor CURSOR FOR + SELECT name, vendor, pythonVersion, cudaVersion, cannVersion, frameworkVersion FROM system_models_templates_to_update; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + CREATE TEMPORARY TABLE IF NOT EXISTS system_models_templates_to_update ( + name VARCHAR(255), + vendor VARCHAR(32), + pythonVersion VARCHAR(255), + cudaVersion VARCHAR(255), + cannVersion VARCHAR(255), + frameworkVersion VARCHAR(255) + ); + + INSERT INTO system_models_templates_to_update (name, vendor, pythonVersion, cudaVersion, cannVersion, frameworkVersion) VALUES + ('vLLM-0.7.2', 'NVIDIA', '3.10', '12.5', NULL, '0.7.2'), + ('vLLM-0.8.5', 'NVIDIA', '3.10', '12.5', NULL, '0.8.5'), + ('vLLM-0.9.2', 'NVIDIA', '3.10', '12.5', NULL, '0.9.2'), + ('vLLM-0.11.0', 'NVIDIA', '3.10', '12.5', NULL, '0.11.0'), + ('SGLang-0.4.9.post1', 'NVIDIA', '3.10', '12.5', NULL, '0.4.9.post1'), + ('SGLang-0.5.2', 'NVIDIA', '3.10', '12.5', NULL, '0.5.2'), + ('Transformers-4.48.3', 'NVIDIA', '3.10', '12.5', NULL, '4.48.3'), + ('Transformers-4.56.2', 'NVIDIA', '3.10', '12.5', NULL, '4.56.2'), + ('sentence_transformers-3.1.1', 'NVIDIA', '3.10', '12.5', NULL, '3.1.1'), + ('Diffusers-0.30.0', 'NVIDIA', '3.10', '12.5', NULL, '0.30.0'), + ('Diffusers-0.35.1', 'NVIDIA', '3.10', '12.5', NULL, '0.35.1'), + ('MindIE-2.0.RC1-910B', 'HUAWEI', '3.9', NULL, '8.0', '2.0.RC1'), + ('MindIE-2.1.RC1-910B', 'HUAWEI', '3.9', NULL, '8.0', '2.1.RC1'), + ('MindIE-1.0.0-310P', 'HUAWEI', '3.9', NULL, '7.0', '1.0.0'), + ('vLLM-Ascend-0.11.0.rc0', 'HUAWEI', '3.9', NULL, '8.0', '0.11.0.rc0'), + ('vLLM-0.5.0-HYGON-Z100L', 'HAIGUANG', '3.10', NULL, NULL, '0.5.0'), + ('vLLM-0.8.5-HYGON-K100-AI', 'HAIGUANG', '3.10', NULL, NULL, '0.8.5'), + ('vLLM-0.9.2-HYGON-K100-AI', 'HAIGUANG', '3.10', NULL, NULL, '0.9.2'), + ('vLLM-0.7.2-HYGON-K100-AI', 'HAIGUANG', '3.10', NULL, NULL, '0.7.2'), + ('MinerU2.5-2509', 'NVIDIA', '3.10', '12.5', NULL, '2.5'); + + OPEN templates_cursor; + update_template_loop: LOOP + FETCH templates_cursor INTO model_name, gpu_vendor_name, py_version, cuda_version, cann_version, fw_version; + IF done THEN + LEAVE update_template_loop; + END IF; + + SELECT COUNT(*) INTO @cnt FROM `zstack`.`ModelServiceVO` WHERE name = model_name AND system = 1; + IF @cnt > 0 THEN + SELECT uuid INTO service_uuid FROM `zstack`.`ModelServiceVO` WHERE name = model_name AND system = 1 LIMIT 1; + ELSE + SET service_uuid = NULL; + END IF; + + IF service_uuid IS NOT NULL THEN + UPDATE `zstack`.`ModelServiceTemplateVO` + SET + `pythonVersionSemver` = py_version, + `cudaVersion` = cuda_version, + `cannVersion` = cann_version, + `frameworkVersionSemver` = fw_version, + `gpuVendor` = gpu_vendor_name + WHERE `modelServiceUuid` = service_uuid; + SELECT CONCAT('INFO: Updated ModelServiceTemplateVO for service_uuid=', service_uuid, ', updated_rows=', ROW_COUNT()) AS msg; + ELSE + SELECT CONCAT('WARN: Service not found for model=', model_name, ', skipping template update.') AS msg; + END IF; + + SET service_uuid = NULL; + END LOOP; + CLOSE templates_cursor; + + DROP TEMPORARY TABLE system_models_templates_to_update; +END $$ +DELIMITER ; + +CALL update_system_model_service_templates(); +DROP PROCEDURE IF EXISTS update_system_model_service_templates; + +-- Delete unexpected ModelServiceTemplateVO entries of MindIE-1.0.0-310P +DELETE FROM `zstack`.`ModelServiceTemplateVO` +WHERE `modelServiceUuid` = 'fe4ed042ac074c55ba1e76921b175ba5' and `cpuArchitecture` = 'x86_64'; + +DELETE FROM `zstack`.`ModelServiceCpuArchitectureVO` +WHERE `modelServiceUuid` = 'fe4ed042ac074c55ba1e76921b175ba5' and `architecture` = 'x86_64'; diff --git a/conf/db/upgrade/V5.4.6__schema.sql b/conf/db/upgrade/V5.4.6__schema.sql new file mode 100644 index 00000000000..c487fde82d6 --- /dev/null +++ b/conf/db/upgrade/V5.4.6__schema.sql @@ -0,0 +1,353 @@ +-- Fix UsedIpVO gateway and netmask from empty strings +DROP PROCEDURE IF EXISTS fixUsedIpGatewayAndNetmask; + +DELIMITER $$ + +CREATE PROCEDURE fixUsedIpGatewayAndNetmask() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE v_usedIpUuid VARCHAR(32); + DECLARE v_ipRangeUuid VARCHAR(32); + DECLARE v_gateway VARCHAR(64); + DECLARE v_netmask VARCHAR(64); + + -- Cursor for UsedIpVO records with empty gateway or netmask + DECLARE cur CURSOR FOR + SELECT uuid, ipRangeUuid + FROM UsedIpVO + WHERE (gateway = '' OR netmask = '' OR gateway IS NULL OR netmask IS NULL) + AND ipRangeUuid IS NOT NULL; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + OPEN cur; + + read_loop: LOOP + FETCH cur INTO v_usedIpUuid, v_ipRangeUuid; + + IF done THEN + LEAVE read_loop; + END IF; + + -- Get gateway and netmask from IpRangeVO + SELECT gateway, netmask + INTO v_gateway, v_netmask + FROM IpRangeVO + WHERE uuid = v_ipRangeUuid; + + -- Update UsedIpVO with correct gateway and netmask + IF v_gateway IS NOT NULL AND v_netmask IS NOT NULL THEN + UPDATE UsedIpVO + SET gateway = v_gateway, netmask = v_netmask + WHERE uuid = v_usedIpUuid; + END IF; + + END LOOP; + + CLOSE cur; + +END$$ + +DELIMITER ; + +-- Execute the procedure +CALL fixUsedIpGatewayAndNetmask(); + +-- Drop the procedure after use +DROP PROCEDURE IF EXISTS fixUsedIpGatewayAndNetmask; + + +-- Update ModelServiceVO framework values +DROP PROCEDURE IF EXISTS updateModelServiceFramework; + +DELIMITER $$ + +CREATE PROCEDURE updateModelServiceFramework() +BEGIN + DECLARE v_table_exists INT DEFAULT 0; + + -- Check if ModelServiceVO table and framework column exist + SELECT COUNT(*) INTO v_table_exists + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'ModelServiceVO' + AND COLUMN_NAME = 'framework'; + + IF v_table_exists > 0 THEN + -- Update llama.cpp to LlamaCpp + UPDATE ModelServiceVO + SET framework = 'LlamaCpp' + WHERE framework = 'llama.cpp'; + + -- Update sentence_transformers to SentenceTransformers + UPDATE ModelServiceVO + SET framework = 'SentenceTransformers' + WHERE framework = 'sentence_transformers'; + END IF; +END$$ + +DELIMITER ; + +-- Execute the procedure +CALL updateModelServiceFramework(); + +-- Drop the procedure after use +DROP PROCEDURE IF EXISTS updateModelServiceFramework; + +UPDATE ModelVO SET architectureType = 'xtts-v2' WHERE uuid = '39280569b4e0490fb581f6ab98e76400'; +UPDATE ModelVO SET architectureType = 'sdxl-turbo' WHERE uuid = '6a720c01935f4f9ea09f81bde722ee42'; + +CALL ADD_COLUMN('ModelServiceVO', 'containerArgs', 'TEXT', 1, NULL); +CALL ADD_COLUMN('ModelServiceVO', 'containerCommand', 'TEXT', 1, NULL); + +-- Upgrade gpuVendor field in ModelServiceGpuVendorVO +Update ModelServiceGpuVendorVO set gpuVendor = 'Huawei' where gpuVendor = 'HUAWEI'; +Update ModelServiceGpuVendorVO set gpuVendor = 'Haiguang' where gpuVendor = 'HAIGUANG'; +Update ModelServiceGpuVendorVO set gpuVendor = 'TianShu' where gpuVendor = 'TIANSHU'; +Update ModelServiceGpuVendorVO set gpuVendor = 'Intel' where gpuVendor = 'INTEL'; + +CALL ADD_COLUMN('GpuDeviceVO', 'isolated', 'TINYINT(1)', 1, NULL); +CALL ADD_COLUMN('GpuDeviceSpecVO', 'isolated', 'TINYINT(1)', 1, NULL); + +DELIMITER $$ + +DROP PROCEDURE IF EXISTS fix_missing_architecture_records$$ + +CREATE PROCEDURE fix_missing_architecture_records() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE v_model_service_uuid VARCHAR(32); + DECLARE v_architecture VARCHAR(32); + DECLARE v_exists INT; + + -- Cursor to find all model services that have templates but missing architecture records + DECLARE service_cursor CURSOR FOR + SELECT DISTINCT mst.modelServiceUuid, mst.cpuArchitecture + FROM ModelServiceTemplateVO mst + WHERE NOT EXISTS ( + SELECT 1 + FROM ModelServiceCpuArchitectureVO msca + WHERE msca.modelServiceUuid = mst.modelServiceUuid + AND msca.architecture = mst.cpuArchitecture + ) + ORDER BY mst.modelServiceUuid, mst.cpuArchitecture; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + -- Start transaction + START TRANSACTION; + + -- Create a temporary table to store statistics + CREATE TEMPORARY TABLE IF NOT EXISTS fix_stats ( + total_services INT DEFAULT 0, + total_records_added INT DEFAULT 0 + ); + + INSERT INTO fix_stats VALUES (0, 0); + + -- Open cursor and process each missing architecture record + OPEN service_cursor; + + read_loop: LOOP + FETCH service_cursor INTO v_model_service_uuid, v_architecture; + + IF done THEN + LEAVE read_loop; + END IF; + + -- Double check if the record doesn't exist (to avoid duplicates) + SELECT COUNT(*) INTO v_exists + FROM ModelServiceCpuArchitectureVO + WHERE modelServiceUuid = v_model_service_uuid + AND architecture = v_architecture; + + IF v_exists = 0 THEN + -- Insert the missing architecture record + INSERT INTO ModelServiceCpuArchitectureVO (modelServiceUuid, architecture, lastOpDate, createDate) + VALUES ( + v_model_service_uuid, + v_architecture, + CURRENT_TIMESTAMP(3), + CURRENT_TIMESTAMP(3) + ); + + -- Update statistics + UPDATE fix_stats SET total_records_added = total_records_added + 1; + + -- Log the fix + SELECT CONCAT('Fixed: Added architecture record [', v_architecture, '] for model service [', v_model_service_uuid, ']') AS log_message; + END IF; + + END LOOP; + + CLOSE service_cursor; + + -- Count total affected services + UPDATE fix_stats SET total_services = ( + SELECT COUNT(DISTINCT modelServiceUuid) + FROM ModelServiceCpuArchitectureVO + WHERE createDate >= (SELECT MIN(createDate) FROM (SELECT createDate FROM ModelServiceCpuArchitectureVO ORDER BY createDate DESC LIMIT 1000) AS recent) + ); + + -- Display summary + SELECT + total_records_added AS 'Total Architecture Records Added', + (SELECT COUNT(DISTINCT modelServiceUuid) FROM ModelServiceTemplateVO) AS 'Total Model Services with Templates', + (SELECT COUNT(DISTINCT modelServiceUuid) FROM ModelServiceCpuArchitectureVO) AS 'Total Model Services with Architecture Records' + FROM fix_stats; + + -- Cleanup + DROP TEMPORARY TABLE IF EXISTS fix_stats; + + -- Commit transaction + COMMIT; + + SELECT 'Fix completed successfully!' AS status; +END$$ + +DELIMITER ; + +CALL fix_missing_architecture_records(); + +-- Add new gpu constraint fields +CALL ADD_COLUMN('ModelVO', 'recommendedGpuNum', 'VARCHAR(256)', 1, NULL); +CALL ADD_COLUMN('ModelVO', 'gpuConstraintDescription', 'VARCHAR(512)', 1, NULL); + +DELIMITER $$ + +CREATE PROCEDURE update_system_model_service_templates() +BEGIN + DECLARE done INT DEFAULT FALSE; + DECLARE model_name VARCHAR(255); + DECLARE gpu_vendor_name VARCHAR(32); + DECLARE py_version VARCHAR(255); + DECLARE cuda_version VARCHAR(255); + DECLARE cann_version VARCHAR(255); + DECLARE fw_version VARCHAR(255); + DECLARE service_uuid VARCHAR(32); + + DECLARE templates_cursor CURSOR FOR + SELECT name, vendor, pythonVersion, cudaVersion, cannVersion, frameworkVersion FROM system_models_templates_to_update; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; + + CREATE TEMPORARY TABLE IF NOT EXISTS system_models_templates_to_update ( + name VARCHAR(255), + vendor VARCHAR(32), + pythonVersion VARCHAR(255), + cudaVersion VARCHAR(255), + cannVersion VARCHAR(255), + frameworkVersion VARCHAR(255) + ); + + INSERT INTO system_models_templates_to_update (name, vendor, pythonVersion, cudaVersion, cannVersion, frameworkVersion) VALUES + ('vLLM-0.7.2', 'NVIDIA', '3.10', '12.5', NULL, '0.7.2'), + ('vLLM-0.8.5', 'NVIDIA', '3.10', '12.5', NULL, '0.8.5'), + ('vLLM-0.9.2', 'NVIDIA', '3.10', '12.5', NULL, '0.9.2'), + ('vLLM-0.11.0', 'NVIDIA', '3.10', '12.5', NULL, '0.11.0'), + ('SGLang-0.4.9.post1', 'NVIDIA', '3.10', '12.5', NULL, '0.4.9.post1'), + ('SGLang-0.5.2', 'NVIDIA', '3.10', '12.5', NULL, '0.5.2'), + ('SGLang-0.5.4', 'NVIDIA', '3.10', '12.5', NULL, '0.5.4'), + ('Transformers-4.48.3', 'NVIDIA', '3.10', '12.5', NULL, '4.48.3'), + ('Transformers-4.57.1', 'NVIDIA', '3.10', '12.5', NULL, '4.57.1'), + ('Transformers-4.56.2', 'NVIDIA', '3.10', '12.5', NULL, '4.56.2'), + ('sentence_transformers-3.1.1', 'NVIDIA', '3.10', '12.5', NULL, '3.1.1'), + ('Diffusers-0.30.0', 'NVIDIA', '3.10', '12.5', NULL, '0.30.0'), + ('Diffusers-0.35.1', 'NVIDIA', '3.10', '12.5', NULL, '0.35.1'), + ('MindIE-2.0.RC1-910B', 'Huawei', '3.9', NULL, '8.0', '2.0.RC1'), + ('MindIE-2.1.RC1-910B', 'Huawei', '3.9', NULL, '8.0', '2.1.RC1'), + ('MindIE-2.1.RC2-910B', 'Huawei', '3.9', NULL, '8.0', '2.1.RC2'), + ('MindIE-1.0.0-310P', 'Huawei', '3.9', NULL, '7.0', '1.0.0'), + ('vLLM-Ascend-0.11.0.rc0', 'Huawei', '3.9', NULL, '8.0', '0.11.0.rc0'), + ('vLLM-0.5.0-HYGON-Z100L', 'Haiguang', '3.10', NULL, NULL, '0.5.0'), + ('vLLM-0.8.5-HYGON-K100-AI', 'Haiguang', '3.10', NULL, NULL, '0.8.5'), + ('vLLM-0.9.2-HYGON-K100-AI', 'Haiguang', '3.10', NULL, NULL, '0.9.2'), + ('vLLM-0.7.2-HYGON-K100-AI', 'Haiguang', '3.10', NULL, NULL, '0.7.2'), + ('MinerU2.5-2509', 'NVIDIA', '3.10', '12.5', NULL, '2.5'); + + OPEN templates_cursor; + update_template_loop: LOOP + FETCH templates_cursor INTO model_name, gpu_vendor_name, py_version, cuda_version, cann_version, fw_version; + IF done THEN + LEAVE update_template_loop; + END IF; + + SELECT COUNT(*) INTO @cnt FROM `zstack`.`ModelServiceVO` WHERE name = model_name AND system = 1; + IF @cnt > 0 THEN + SELECT uuid INTO service_uuid FROM `zstack`.`ModelServiceVO` WHERE name = model_name AND system = 1 LIMIT 1; + ELSE + SET service_uuid = NULL; + END IF; + + IF service_uuid IS NOT NULL THEN + SELECT COUNT(*) INTO @tmpl_cnt FROM `zstack`.`ModelServiceTemplateVO` WHERE `modelServiceUuid` = service_uuid; + IF @tmpl_cnt > 0 THEN + UPDATE `zstack`.`ModelServiceTemplateVO` SET + `pythonVersionSemver` = py_version, + `cudaVersion` = cuda_version, + `cannVersion` = cann_version, + `frameworkVersionSemver` = fw_version, + `gpuVendor` = gpu_vendor_name + WHERE `modelServiceUuid` = service_uuid; + SELECT CONCAT('INFO: Updated ModelServiceTemplateVO for service_uuid=', service_uuid, ', updated_rows=', ROW_COUNT()) AS msg; + ELSE + INSERT INTO `zstack`.`ModelServiceTemplateVO` (`uuid`, `modelServiceUuid`, `pythonVersionSemver`, `cudaVersion`, `cannVersion`, `frameworkVersionSemver`, `gpuVendor`) + VALUES (REPLACE(UUID(),'-',''), service_uuid, py_version, cuda_version, cann_version, fw_version, gpu_vendor_name); + SELECT CONCAT('INFO: Inserted ModelServiceTemplateVO for service_uuid=', service_uuid, ', inserted_rows=', ROW_COUNT()) AS msg; + END IF; + + -- Ensure ModelServiceGpuVendorVO record exists with the corresponding gpuVendor for this modelServiceUuid + SELECT COUNT(*) INTO @gv_cnt FROM `zstack`.`ModelServiceGpuVendorVO` + WHERE `modelServiceUuid` = service_uuid AND `gpuVendor` = gpu_vendor_name; + IF @gv_cnt = 0 THEN + INSERT INTO `zstack`.`ModelServiceGpuVendorVO` (`modelServiceUuid`, `gpuVendor`) + VALUES (service_uuid, gpu_vendor_name); + SELECT CONCAT('INFO: Inserted ModelServiceGpuVendorVO for service_uuid=', service_uuid, ', gpuVendor=', gpu_vendor_name) AS msg; + ELSE + SELECT CONCAT('INFO: ModelServiceGpuVendorVO exists for service_uuid=', service_uuid, ', gpuVendor=', gpu_vendor_name) AS msg; + END IF; + ELSE + SELECT CONCAT('WARN: Service not found for model=', model_name, ', skipping template and gpuVendor update.') AS msg; + END IF; + + SET service_uuid = NULL; + END LOOP; + CLOSE templates_cursor; + + DROP TEMPORARY TABLE IF EXISTS system_models_templates_to_update; +END $$ +DELIMITER ; + +CALL update_system_model_service_templates(); +DROP PROCEDURE IF EXISTS update_system_model_service_templates; + +Update ModelServiceTemplateVO set gpuVendor = 'Huawei' where gpuVendor = 'HUAWEI'; +Update ModelServiceTemplateVO set gpuVendor = 'Haiguang' where gpuVendor = 'HAIGUANG'; +Update ModelServiceTemplateVO set gpuVendor = 'TianShu' where gpuVendor = 'TIANSHU'; +Update ModelServiceTemplateVO set gpuVendor = 'Intel' where gpuVendor = 'INTEL'; + +CALL ADD_COLUMN('GpuDeviceVO', 'gpuStatus', 'varchar(16)', 1, NULL); + +UPDATE `zstack`.`GpuDeviceVO` SET `gpuStatus`='NOMINAL' WHERE `gpuStatus` IS NULL; + +-- Add supportMetrics column to ModelServiceInstanceGroupVO +DROP PROCEDURE IF EXISTS addModelServiceInstanceGroupSupportMetricsColumn; +DELIMITER $$ +CREATE PROCEDURE addModelServiceInstanceGroupSupportMetricsColumn() +BEGIN + DECLARE columnExists BOOLEAN DEFAULT FALSE; + + SELECT COUNT(*) INTO columnExists + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = 'ModelServiceInstanceGroupVO' + AND COLUMN_NAME = 'supportMetrics' + AND TABLE_SCHEMA = 'zstack'; + + IF columnExists = FALSE THEN + ALTER TABLE `zstack`.`ModelServiceInstanceGroupVO` ADD COLUMN `supportMetrics` TEXT DEFAULT NULL; + END IF; +END $$ +DELIMITER ; + +CALL addModelServiceInstanceGroupSupportMetricsColumn(); +DROP PROCEDURE IF EXISTS addModelServiceInstanceGroupSupportMetricsColumn; diff --git a/conf/db/upgrade/beforeMigrate.sql b/conf/db/upgrade/beforeMigrate.sql index 71c8229eb27..d53d98d8646 100755 --- a/conf/db/upgrade/beforeMigrate.sql +++ b/conf/db/upgrade/beforeMigrate.sql @@ -89,3 +89,172 @@ BEGIN SELECT CURTIME(); END $$ DELIMITER ; + +DROP PROCEDURE IF EXISTS `DELETE_INDEX`; + +DELIMITER $$ +CREATE PROCEDURE `DELETE_INDEX`( + IN tb_name VARCHAR(64), + IN idx_name VARCHAR(64) +) +DETERMINISTIC +READS SQL DATA +begin_label: BEGIN + IF idx_name = '' OR idx_name IS NULL THEN + LEAVE begin_label; + END IF; + + IF EXISTS ( SELECT * FROM information_schema.statistics + WHERE table_schema = DATABASE() + AND table_name = tb_name + AND index_name = idx_name ) THEN + SET @sql = CONCAT('ALTER TABLE ', tb_name, ' DROP INDEX ', idx_name); + PREPARE stmt FROM @sql; + EXECUTE stmt; + END IF; + + SELECT CURTIME(); +END$$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS `CREATE_INDEX`; + +DELIMITER $$ +CREATE PROCEDURE `CREATE_INDEX`( + IN tb_name VARCHAR(64), + IN idx_name VARCHAR(64), + IN col_name VARCHAR(64) +) + DETERMINISTIC + READS SQL DATA +begin_label: BEGIN + IF idx_name = '' OR idx_name IS NULL THEN + LEAVE begin_label; + END IF; + + IF NOT EXISTS ( SELECT * FROM information_schema.statistics + WHERE table_schema = DATABASE() + AND table_name = tb_name + AND index_name = idx_name ) THEN + SET @sql = CONCAT('ALTER TABLE ', tb_name, ' ADD INDEX ', idx_name, ' (`', col_name, '`)'); + PREPARE stmt FROM @sql; + EXECUTE stmt; + END IF; + + SELECT CURTIME(); +END$$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS `ADD_COLUMN`; + +DELIMITER $$ +CREATE PROCEDURE `ADD_COLUMN`( + IN tb_name VARCHAR(64), + IN col_name VARCHAR(64), + IN col_data_type VARCHAR(64), + IN allow_null BOOL, + IN default_value VARCHAR(255) +) +BEGIN + DECLARE alter_sql VARCHAR(1000); + IF NOT EXISTS( SELECT 1 + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = tb_name + AND table_schema = 'zstack' + AND column_name = col_name) THEN + SET @alter_sql = CONCAT('ALTER TABLE zstack.', tb_name, ' ADD COLUMN ', col_name, ' ', col_data_type); + IF NOT allow_null THEN + SET @alter_sql = CONCAT(@alter_sql, ' NOT NULL'); + END IF; + IF default_value IS NOT NULL THEN + SET @alter_sql = CONCAT(@alter_sql, ' DEFAULT ''', default_value, ''''); + ELSE + SET @alter_sql = CONCAT(@alter_sql, ' DEFAULT NULL'); + END IF; + SELECT @alter_sql; + PREPARE stmt FROM @alter_sql; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + END IF; + +SELECT CURTIME(); +END$$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS `ADD_CONSTRAINT`; + +DELIMITER $$ +CREATE PROCEDURE `ADD_CONSTRAINT`( + IN tb_name VARCHAR(64), + IN cons_name VARCHAR(255), + IN references_col VARCHAR(64), + IN referencing_table VARCHAR(64), + IN referencing_col VARCHAR(64), + IN on_delete VARCHAR(64) +) +BEGIN + DECLARE alter_sql VARCHAR(1000); + IF NOT EXISTS( SELECT 1 + FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS + WHERE table_name = tb_name + AND table_schema = 'zstack' + AND CONSTRAINT_NAME = cons_name) THEN + SET @alter_sql = CONCAT('ALTER TABLE zstack.', tb_name, ' ADD CONSTRAINT ', cons_name, + ' FOREIGN KEY (', references_col, ') REFERENCES ', 'zstack.', referencing_table, ' (', referencing_col, + ') ON DELETE ', on_delete); + SELECT @alter_sql; + PREPARE stmt FROM @alter_sql; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + END IF; + +SELECT CURTIME(); +END$$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS `DROP_COLUMN`; +DELIMITER $$ +CREATE PROCEDURE `DROP_COLUMN`( + IN tb_name VARCHAR(64), + IN col_name VARCHAR(64) +) +BEGIN + DECLARE alter_sql VARCHAR(1000); + IF EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = tb_name + AND table_schema = 'zstack' + AND column_name = col_name) THEN + SET @alter_sql = CONCAT('ALTER TABLE zstack.', tb_name, ' DROP ', col_name); + SELECT @alter_sql; + PREPARE stmt FROM @alter_sql; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + END IF; + +SELECT CURTIME(); +END$$ +DELIMITER ; + +DROP PROCEDURE IF EXISTS `RENAME_TABLE`; +DELIMITER $$ +CREATE PROCEDURE `RENAME_TABLE`( + IN old_name VARCHAR(64), + IN new_name VARCHAR(64) +) +BEGIN + DECLARE alter_sql VARCHAR(1000); + IF EXISTS( SELECT NULL + FROM INFORMATION_SCHEMA.TABLES + WHERE table_name = old_name + AND table_schema = 'zstack') THEN + SET @alter_sql = CONCAT('RENAME TABLE zstack.', old_name, ' TO ', new_name); + SELECT @alter_sql; + PREPARE stmt FROM @alter_sql; + EXECUTE stmt; + DEALLOCATE PREPARE stmt; + END IF; + + SELECT CURTIME(); +END$$ +DELIMITER ; \ No newline at end of file diff --git a/conf/db/upgrade/beforeValidate.sql b/conf/db/upgrade/beforeValidate.sql index 3466df5993e..0de10ef5711 100644 --- a/conf/db/upgrade/beforeValidate.sql +++ b/conf/db/upgrade/beforeValidate.sql @@ -22,6 +22,23 @@ BEGIN update `zstack`.`schema_version` set `checksum`=-143027462 where `script`='V3.9.1__schema.sql' and `checksum` <> -143027462; update `zstack`.`schema_version` set `checksum`=514679307 where `script`='V3.10.0__schema.sql' and `checksum` <> 514679307; update `zstack`.`schema_version` set `checksum`=-1316015634 where `script`='V4.0.0__schema.sql' and `checksum` <> -1316015634; + update `zstack`.`schema_version` set `checksum`=1243948617 where `script`='V4.3.8.1__schema.sql' and `checksum` <> 1243948617; + update `zstack`.`schema_version` set `checksum`=-395682061 where `script`='V4.3.35__schema.sql' and `checksum` <> -395682061; + update `zstack`.`schema_version` set `checksum`=-540021638 where `script`='V4.4.6__schema.sql' and `checksum` <> -540021638; + update `zstack`.`schema_version` set `checksum`=-698734653 where `script`='V4.5.11__schema.sql' and `checksum` <> -698734653; + update `zstack`.`schema_version` set `checksum`=-2137714083 where `script`='V4.7.0__schema.sql' and `checksum` <> -2137714083; + update `zstack`.`schema_version` set `checksum`=-1493191986 where `script`='V0.6__schema.sql' and `checksum` <> -1493191986; + update `zstack`.`schema_version` set `checksum`=286222955 where `script`='V1.3__schema.sql' and `checksum` <> 286222955; + update `zstack`.`schema_version` set `checksum`=390362109 where `script`='V1.7__schema.sql' and `checksum` <> 390362109; + update `zstack`.`schema_version` set `checksum`=-1453565511 where `script`='V2.1.0__schema.sql' and `checksum` <> -1453565511; + update `zstack`.`schema_version` set `checksum`=672814727 where `script`='V2.2.0__schema.sql' and `checksum` <> 672814727; + update `zstack`.`schema_version` set `checksum`=271601676 where `script`='V3.1.0__schema.sql' and `checksum` <> 271601676; + update `zstack`.`schema_version` set `checksum`=-294520100 where `script`='V4.6.21__schema.sql' and `checksum` <> -294520100; + update `zstack`.`schema_version` set `checksum`=1170348213 where `script`='V4.8.0.6__schema.sql' and `checksum` <> 1170348213; + update `zstack`.`schema_version` set `checksum`=1298863127 where `script`='V5.3.0__schema.sql' and `checksum` <> 1298863127; + update `zstack`.`schema_version` set `checksum`=613548663 where `script`='V5.3.6__schema.sql' and `checksum` <> 613548663; + update `zstack`.`schema_version` set `checksum`=1489363540 where `script`='V5.3.22__schema.sql' and `checksum` <> 1489363540; + update `zstack`.`schema_version` set `checksum`=1648524318 where `script`='V4.4.0__schema.sql' and `checksum` <> 1648524318; END IF; END $$ diff --git a/conf/deploydb.sh b/conf/deploydb.sh index 2d64b098420..033da079954 100755 --- a/conf/deploydb.sh +++ b/conf/deploydb.sh @@ -22,20 +22,44 @@ if [[ `id -u` -ne 0 ]] && [[ x"$user" = x"root" ]]; then MYSQL='sudo mysql' fi +if command -v greatdb &> /dev/null; then + MYSQL='greatdb' + if [[ `id -u` -ne 0 ]] && [[ x"$user" = x"root" ]]; then + MYSQL='sudo greatdb' + fi +fi + mysql_run() { $MYSQL --user=$user --password=$password --host=$host --port=$port "$@" } -mysql_run << EOF -DROP DATABASE IF EXISTS zstack; -CREATE DATABASE zstack; -DROP DATABASE IF EXISTS zstack_rest; -CREATE DATABASE zstack_rest; -grant all privileges on zstack.* to root@'%' identified by "$password"; -grant all privileges on zstack_rest.* to root@'%' identified by "$password"; -grant all privileges on zstack.* to root@'localhost' identified by "$password"; -grant all privileges on zstack_rest.* to root@'localhost' identified by "$password"; +if command -v greatdb &> /dev/null; then + mysql_run << EOF + set global log_bin_trust_function_creators=1; + DROP DATABASE IF EXISTS zstack; + CREATE DATABASE zstack; + DROP DATABASE IF EXISTS zstack_rest; + CREATE DATABASE zstack_rest; + CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY "${password}"; + CREATE USER IF NOT EXISTS 'root'@'127.0.0.1' IDENTIFIED BY "${password}"; + grant all privileges on zstack.* to root@'%'; + grant all privileges on zstack_rest.* to root@'%'; + grant all privileges on zstack.* to root@'127.0.0.1'; + grant all privileges on zstack_rest.* to root@'127.0.0.1'; +EOF +else + mysql_run << EOF + set global log_bin_trust_function_creators=1; + DROP DATABASE IF EXISTS zstack; + CREATE DATABASE zstack; + DROP DATABASE IF EXISTS zstack_rest; + CREATE DATABASE zstack_rest; + grant all privileges on zstack.* to root@'%' identified by "${password}"; + grant all privileges on zstack_rest.* to root@'%' identified by "${password}"; + grant all privileges on zstack.* to root@'127.0.0.1' identified by "${password}"; + grant all privileges on zstack_rest.* to root@'127.0.0.1' identified by "${password}"; EOF +fi rm -rf $flyway_sql mkdir -p $flyway_sql @@ -67,34 +91,50 @@ hostname=`hostname` [ -z $zstack_user_password ] && zstack_user_password='' -db_version=`mysql --version | awk '/Distrib/{print $5}' |awk -F'.' '{print $1}'` -if [ $db_version -ge 10 ];then - mysql --user=$user --password=$password --host=$host --port=$port << EOF -drop user if exists zstack; -drop user if exists zstack_rest; -create user 'zstack' identified by "$zstack_user_password"; -create user 'zstack_rest' identified by "$zstack_user_password"; -grant all privileges on zstack.* to zstack@'localhost' identified by "$zstack_user_password"; -grant all privileges on zstack.* to zstack@'%' identified by "$zstack_user_password"; -grant all privileges on zstack.* to zstack@"$hostname" identified by "$zstack_user_password"; -grant all privileges on zstack_rest.* to zstack@'localhost' identified by "$zstack_user_password"; -grant all privileges on zstack_rest.* to zstack@"$hostname" identified by "$zstack_user_password"; -grant all privileges on zstack_rest.* to zstack@'%' identified by "$zstack_user_password"; -flush privileges; +if command -v greatdb &> /dev/null; then + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + drop user if exists zstack; + drop user if exists zstack_rest; + create user if not exists 'zstack'@'localhost' identified by "$zstack_user_password"; + create user if not exists 'zstack'@'%' identified by "$zstack_user_password"; + create user if not exists 'zstack_rest'@'localhost' identified by "$zstack_user_password"; + create user if not exists 'zstack_rest'@'%' identified by "$zstack_user_password"; + grant all privileges on zstack.* to zstack@'localhost'; + grant all privileges on zstack.* to zstack@'%'; + grant system_user on *.* to zstack@'localhost'; + grant system_user on *.* to zstack@'%'; + grant all privileges on zstack_rest.* to zstack@'localhost'; + grant all privileges on zstack_rest.* to zstack@'%'; + flush privileges; EOF else - mysql --user=$user --password=$password --host=$host --port=$port << EOF -grant usage on *.* to 'zstack'@'localhost'; -grant usage on *.* to 'zstack'@'%'; -drop user zstack; -create user 'zstack' identified by "$zstack_user_password"; -grant all privileges on zstack.* to zstack@'localhost' identified by "$zstack_user_password"; -grant all privileges on zstack.* to zstack@'%' identified by "$zstack_user_password"; -grant all privileges on zstack.* to zstack@"$hostname" identified by "$zstack_user_password"; -grant all privileges on zstack_rest.* to zstack@'localhost' identified by "$zstack_user_password"; -grant all privileges on zstack_rest.* to zstack@"$hostname" identified by "$zstack_user_password"; -grant all privileges on zstack_rest.* to zstack@'%' identified by "$zstack_user_password"; -flush privileges; + db_version=`$MYSQL --version | awk '/Distrib/{print $5}' |awk -F'.' '{print $1}'` + if [ $db_version -ge 10 ];then + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + drop user if exists zstack; + drop user if exists zstack_rest; + create user 'zstack' identified by "$zstack_user_password"; + create user 'zstack_rest' identified by "$zstack_user_password"; + grant all privileges on zstack.* to zstack@'localhost' identified by "$zstack_user_password"; + grant all privileges on zstack.* to zstack@'%' identified by "$zstack_user_password"; + grant all privileges on zstack_rest.* to zstack@'localhost' identified by "$zstack_user_password"; + grant all privileges on zstack_rest.* to zstack@'%' identified by "$zstack_user_password"; + flush privileges; +EOF + else + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + grant usage on *.* to 'zstack'@'localhost'; + grant usage on *.* to 'zstack'@'%'; + drop user zstack; + create user 'zstack' identified by "$zstack_user_password"; + grant all privileges on zstack.* to zstack@'localhost' identified by "$zstack_user_password"; + grant all privileges on zstack.* to zstack@'%' identified by "$zstack_user_password"; + grant all privileges on zstack.* to zstack@"$hostname" identified by "$zstack_user_password"; + grant all privileges on zstack_rest.* to zstack@'localhost' identified by "$zstack_user_password"; + grant all privileges on zstack_rest.* to zstack@"$hostname" identified by "$zstack_user_password"; + grant all privileges on zstack_rest.* to zstack@'%' identified by "$zstack_user_password"; + flush privileges; EOF + fi fi diff --git a/conf/deployuidb.sh b/conf/deployuidb.sh index fc30aadd5aa..16a7e659576 100755 --- a/conf/deployuidb.sh +++ b/conf/deployuidb.sh @@ -7,24 +7,59 @@ host="$3" port="$4" zstack_ui_db_password="$5" +MYSQL='mysql' + +if [[ `id -u` -ne 0 ]] && [[ x"$user" = x"root" ]]; then + MYSQL='sudo mysql' +fi + +if command -v greatdb &> /dev/null; then + MYSQL='greatdb' + if [[ `id -u` -ne 0 ]] && [[ x"$user" = x"root" ]]; then + MYSQL='sudo greatdb' + fi +fi + base=`dirname $0` flyway="$base/tools/flyway-3.2.1/flyway" flyway_sql="$base/tools/flyway-3.2.1/sql/" # give grant option to the new management ip after `zstack-ctl change_ip` -mysql --user=$user --password=$password --port=$port << EOF -grant all privileges on *.* to root@"$host" identified by "$password" with grant option; +if command -v greatdb &> /dev/null; then + $MYSQL --user=$user --password=$password --port=$port << EOF + grant all privileges on *.* to 'root'@"$host" with grant option; + FLUSH PRIVILEGES; +EOF +else + $MYSQL --user=$user --password=$password --port=$port << EOF + grant all privileges on *.* to 'root'@"$host" identified by "$password" with grant option; + FLUSH PRIVILEGES; EOF +fi -mysql --user=$user --password=$password --host=$host --port=$port << EOF -grant usage on *.* to 'root'@'localhost'; -grant usage on *.* to 'root'@'%'; -DROP DATABASE IF EXISTS zstack_ui; -CREATE DATABASE zstack_ui; -grant all privileges on zstack_ui.* to root@'%' identified by "$password"; -grant all privileges on zstack_ui.* to root@'localhost' identified by "$password"; -flush privileges; +if command -v greatdb &> /dev/null; then + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + grant usage on *.* to 'root'@'localhost'; + grant usage on *.* to 'root'@'%'; + DROP DATABASE IF EXISTS zstack_ui; + CREATE DATABASE zstack_ui; + create user if not exists 'root'@'%' identified by "$password"; + create user if not exists 'root'@'localhost' identified by "$password"; + grant all privileges on zstack_ui.* to 'root'@'%'; + grant all privileges on zstack_ui.* to 'root'@'localhost'; + flush privileges; +EOF +else + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + grant usage on *.* to 'root'@'localhost'; + grant usage on *.* to 'root'@'%'; + DROP DATABASE IF EXISTS zstack_ui; + CREATE DATABASE zstack_ui; + grant all privileges on zstack_ui.* to 'root'@'%' identified by "$password"; + grant all privileges on zstack_ui.* to 'root'@'localhost' identified by "$password"; + flush privileges; EOF +fi rm -rf $flyway_sql mkdir -p $flyway_sql @@ -39,25 +74,37 @@ if [ -d $ui_schema_path ]; then fi hostname=`hostname` -db_version=`mysql --version | awk '/Distrib/{print $5}' |awk -F'.' '{print $1}'` -if [ $db_version -ge 10 ];then - mysql --user=$user --password=$password --host=$host --port=$port << EOF -drop user if exists zstack_ui; -create user 'zstack_ui' identified by "$zstack_ui_db_password"; -grant all privileges on zstack_ui.* to zstack_ui@'localhost' identified by "$zstack_ui_db_password"; -grant all privileges on zstack_ui.* to zstack_ui@'%' identified by "$zstack_ui_db_password"; -grant all privileges on zstack_ui.* to zstack_ui@"$hostname" identified by "$zstack_ui_db_password"; -flush privileges; + +if command -v greatdb &> /dev/null; then + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + drop user if exists zstack_ui; + create user 'zstack_ui' identified by "$zstack_ui_db_password"; + create user if not exists 'zstack_ui'@'localhost' identified by "$zstack_ui_db_password"; + create user if not exists 'zstack_ui'@'%' identified by "$zstack_ui_db_password"; + grant all privileges on zstack_ui.* to zstack_ui@'localhost'; + grant all privileges on zstack_ui.* to zstack_ui@'%'; + flush privileges; EOF else - mysql --user=$user --password=$password --host=$host --port=$port << EOF -grant usage on *.* to 'zstack_ui'@'localhost'; -grant usage on *.* to 'zstack_ui'@'%'; -drop user zstack_ui; -create user 'zstack_ui' identified by "$zstack_ui_db_password"; -grant all privileges on zstack_ui.* to zstack_ui@'localhost' identified by "$zstack_ui_db_password"; -grant all privileges on zstack_ui.* to zstack_ui@'%' identified by "$zstack_ui_db_password"; -grant all privileges on zstack_ui.* to zstack_ui@"$hostname" identified by "$zstack_ui_db_password"; -flush privileges; + db_version=`$MYSQL --version | awk '/Distrib/{print $5}' |awk -F'.' '{print $1}'` + if [ $db_version -ge 10 ];then + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + drop user if exists zstack_ui; + create user 'zstack_ui' identified by "$zstack_ui_db_password"; + grant all privileges on zstack_ui.* to zstack_ui@'localhost' identified by "$zstack_ui_db_password"; + grant all privileges on zstack_ui.* to zstack_ui@'%' identified by "$zstack_ui_db_password"; + flush privileges; +EOF + else + $MYSQL --user=$user --password=$password --host=$host --port=$port << EOF + grant usage on *.* to 'zstack_ui'@'localhost'; + grant usage on *.* to 'zstack_ui'@'%'; + drop user zstack_ui; + create user 'zstack_ui' identified by "$zstack_ui_db_password"; + grant all privileges on zstack_ui.* to zstack_ui@'localhost' identified by "$zstack_ui_db_password"; + grant all privileges on zstack_ui.* to zstack_ui@'%' identified by "$zstack_ui_db_password"; + grant all privileges on zstack_ui.* to zstack_ui@"$hostname" identified by "$zstack_ui_db_password"; + flush privileges; EOF + fi fi diff --git a/conf/errorCodes/baremetal2.xml b/conf/errorCodes/baremetal2.xml new file mode 100644 index 00000000000..1696eee09b6 --- /dev/null +++ b/conf/errorCodes/baremetal2.xml @@ -0,0 +1,8 @@ + + BM + + 1001 + nginx connection error, check the nginx configuration and upstream server, as well as if the agent is installed + + + diff --git a/conf/errorCodes/datacrypto.xml b/conf/errorCodes/datacrypto.xml new file mode 100644 index 00000000000..50a8e2c0aa1 --- /dev/null +++ b/conf/errorCodes/datacrypto.xml @@ -0,0 +1,7 @@ + + DATA_CRYPTO + + 1001 + The data integrity has been compromised. + + \ No newline at end of file diff --git a/conf/errorCodes/host.xml b/conf/errorCodes/host.xml index 8eb43075f52..57be27bf542 100755 --- a/conf/errorCodes/host.xml +++ b/conf/errorCodes/host.xml @@ -60,5 +60,10 @@ 1011 Unable to perform an operation on the host, however, the failure is eligible for garbage collector + + + 1012 + The host password has been changed + diff --git a/conf/errorCodes/license.xml b/conf/errorCodes/license.xml index 05637f0ece7..fa1db7d837a 100755 --- a/conf/errorCodes/license.xml +++ b/conf/errorCodes/license.xml @@ -40,5 +40,100 @@ 1007 License capacity policy mismatch + + + 1008 + The current Primary License does not allow using Addon licenses to add plus services + + + + 2000 + Generic license component error + + + + 2001 + Missing license request code + + + + 3000 + Generic license server error + + + + 3002 + Unsupported license key-store type + + + + 3003 + License key-store error + + + + 3004 + License public key error + + + + 3100 + License server generic error + + + + 3101 + Missing license server file + + + + 3102 + Connect to license client error + + + + 3104 + License server call license client API error + + + + 3111 + Invalid license capacity application + + + + 3112 + License quota exceeded + + + + 3200 + License client generic error + + + + 3201 + Missing license client file + + + + 3202 + Connect to license server error + + + + 3203 + Log in license server error + + + + 3204 + License client call license server API error + + + + 3205 + Invalid license capacity response from license server + diff --git a/conf/errorCodes/loginControl.xml b/conf/errorCodes/loginControl.xml index 25066de9d3d..e31eae034da 100644 --- a/conf/errorCodes/loginControl.xml +++ b/conf/errorCodes/loginControl.xml @@ -25,4 +25,9 @@ 1004 Request refused + + + 1005 + Missing captcha + \ No newline at end of file diff --git a/conf/errorCodes/lun.xml b/conf/errorCodes/lun.xml new file mode 100644 index 00000000000..a8cb629c553 --- /dev/null +++ b/conf/errorCodes/lun.xml @@ -0,0 +1,13 @@ + + LUN + + + 1000 + lun has been created + + + + 1001 + lun cannot be found + + diff --git a/conf/errorCodes/ovf.xml b/conf/errorCodes/ovf.xml new file mode 100644 index 00000000000..520ae8a51b1 --- /dev/null +++ b/conf/errorCodes/ovf.xml @@ -0,0 +1,24 @@ + + OVF + + + 1001 + Failed to parse OVF template XML text + + + + 1002 + OVF template XML is invalid + + + + 1003 + Failed to parse image info JSON text + + + + 1004 + Image info is invalid + + + diff --git a/conf/errorCodes/securityGroup.xml b/conf/errorCodes/securityGroup.xml index a84e0247e2e..650fc27fbba 100755 --- a/conf/errorCodes/securityGroup.xml +++ b/conf/errorCodes/securityGroup.xml @@ -5,5 +5,41 @@ 1000 Unable to add vm's nic to security group + + + 1001 + Resource does not exist + + + + 1002 + Duplicate security group rules + + + + 1003 + Rule fields conflict + + + + 1004 + Rule fields are not supported + + + + 1005 + Rule's port field is invalid + + + + 1006 + Rule's port field is invalid + + + + 2000 + Rule check ok + + diff --git a/conf/errorCodes/securityMachine.xml b/conf/errorCodes/securityMachine.xml index 68f5dce5fc8..d1996272224 100644 --- a/conf/errorCodes/securityMachine.xml +++ b/conf/errorCodes/securityMachine.xml @@ -5,5 +5,35 @@ 3001 No available security machine + + + 3002 + Failed to connect to client + + + + 3003 + Client digest service failed + + + + 3004 + Client sm4 service failed + + + + 3005 + Client hmac service failed + + + + 3006 + The crypto service is not enabled + + + + 3007 + Operation not supported + diff --git a/conf/errorCodes/vmSchedulingRule.xml b/conf/errorCodes/vmSchedulingRule.xml new file mode 100644 index 00000000000..3cac9cbdf74 --- /dev/null +++ b/conf/errorCodes/vmSchedulingRule.xml @@ -0,0 +1,57 @@ + + vmSchedulingRule + + 3001 + The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. Attaching another one is not allowed. + + + + 3002 + The VM scheduling group has already had a VM Affinitive to Each Other scheduling policy attached. Attaching a VM Exclusive from Each Other scheduling policy is not allowed. + + + + 3003 + The VM scheduling group has already had a VM Affinitive to Each Other scheduling policy attached. Attaching another one is not allowed. + + + + 3004 + The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. Attaching a VM Affinitive to Each Other scheduling policy is not allowed. + + + + 3005 + The VM scheduling group has already had a VMs Affinitive to Hosts scheduling policy attached. You cannot attach another one to the group again. + + + + 3006 + The VM scheduling group has already had a VMs Exclusive from Hosts scheduling policy attached. You cannot attach a VMs Affinitive to Hosts scheduling policy to the group. + + + + 3007 + The VM scheduling group has already had a VMs Affinitive to Hosts scheduling policy attached. You cannot attach a VMs Exclusive from Hosts scheduling policy to the group. + + + + 3008 + The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VMs Affinitive to Hosts scheduling policy to the group. + + + + 3009 + The VM scheduling group has already had a VMs Affinitive to Hosts scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VM Exclusive from Each Other scheduling policy to the group again. + + + + 3010 + The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VMs Exclusive from Hosts scheduling policy to the group. + + + + 3011 + The VM scheduling group has already had a VMs Exclusive from Hosts scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VM Exclusive from Each Other scheduling policy to the group. + + diff --git a/conf/errorCodes/volume.xml b/conf/errorCodes/volume.xml index a5af757e949..fcac4c08eba 100644 --- a/conf/errorCodes/volume.xml +++ b/conf/errorCodes/volume.xml @@ -5,4 +5,9 @@ 1000 Unable to deactivate a volume in use + + + 1001 + fail to flatten volume + \ No newline at end of file diff --git a/conf/errorCodes/volumeSnapshot.xml b/conf/errorCodes/volumeSnapshot.xml index f9ad74d6f4e..c060a5815b2 100755 --- a/conf/errorCodes/volumeSnapshot.xml +++ b/conf/errorCodes/volumeSnapshot.xml @@ -10,4 +10,9 @@ 1001 Delete error while full snapshot is creating. + + + 1002 + Failed to delete volume snapshots in batch. + diff --git a/conf/errorElaborations/Elaboration.json b/conf/errorElaborations/Elaboration.json index eabdbfd1eb3..ec236629bbe 100644 --- a/conf/errorElaborations/Elaboration.json +++ b/conf/errorElaborations/Elaboration.json @@ -92,7 +92,7 @@ "code": "1005", "method": "regex", "regex": "failed to download bits from the imagestore backup storage\\[hostname:.*, path:.*] to the local primary storage\\[uuid:.*, path:.*].*", - "message_cn": "无法从镜像仓库服务器 [主机名:%2$s,路径:%3$s] 下载资源到本地主存储 [uuid:%4$s,路径:%5$s]。", + "message_cn": "无法从镜像仓库服务器 [物理机名:%2$s,路径:%3$s] 下载资源到本地存储 [uuid:%4$s,路径:%5$s]。", "message_en": "Could not download resources from the ImageStore backup storage [hostname: %2$s, path: %3$s] to the local primary storage [uuid: %4$s, path: %5$s]." }, { @@ -116,7 +116,7 @@ "code": "1008", "method": "regex", "regex": ".*, because:cannot find pool\\[.*] in the ceph cluster, you must create it manually", - "message_cn": "未能在 Ceph 集群中找到存储池 [%1$s],您需要先手动创建。", + "message_cn": "未能在 分布式存储 集群中找到存储池 [%1$s],您需要先手动创建。", "message_en": "Could not find pool [%1$s] in Ceph cluster. You need to create one manually." }, { @@ -132,7 +132,7 @@ "code": "1000", "method": "regex", "regex": ".*cannot add ceph primary storage, there has been some ceph primary storage using mon\\[hostnames:.*].*", - "message_cn": "无法添加 Ceph 主存储,监控节点 [%1$s] 已被占用。", + "message_cn": "无法添加 分布式存储,监控节点 [%1$s] 已被占用。", "message_en": "Could not add Ceph primary storage. The mon [%1$s] is occupied." }, { @@ -140,7 +140,7 @@ "code": "1001", "method": "regex", "regex": "cannot find any Connected ceph mon for the primary storage.*", - "message_cn": "无法为 Ceph 主存储找到一个已连接的监控节点。", + "message_cn": "无法为 Ceph主存储找到一个已连接的监控节点。", "message_en": "Could not find any connected Ceph mon for the Ceph primary storage." }, { @@ -148,7 +148,7 @@ "code": "1002", "method": "regex", "regex": "operation error, because:The ceph storage type to be added does not support auto initialize pool, please create it manually", - "message_cn": "要添加的 Ceph 存储类型不支持自动创建存储池,请手动创建。", + "message_cn": "要添加的 Ceph主存储类型不支持自动创建存储池,请手动创建。", "message_en": "The Ceph storage type to be added does not support auto creation of storage pools. Please create one manually." }, { @@ -156,7 +156,7 @@ "code": "1003", "method": "regex", "regex": "there is another CEPH primary storage.* with the same FSID.*, you cannot add the same CEPH setup as two different primary storage", - "message_cn": "已经存在一个 FSID 为 [%3$s] 的 Ceph 主存储,您不能将同一个 Ceph 集群设置为两个不同的主存储。", + "message_cn": "已经存在一个 FSID 为 [%3$s] 的 Ceph主存储,您不能将同一个 Ceph主存储 集群设置为两个不同的主存储。", "message_en": "A Ceph primary storage with the FSID [%3$s] already exists. You could not add a Ceph cluster as two different primary storages." }, { @@ -332,7 +332,7 @@ "code": "1010", "method": "regex", "regex": ".*failed to start vm\\[uuid:.* name:.*] on kvm host\\[uuid:.*, ip:.*], because No enough physical memory for guest.*", - "message_cn": "在物理机上启动云主机失败,因为物理机已经没有足够的物理内存可供虚拟机使用。", + "message_cn": "在物理机上启动云主机失败,因为物理机已经没有足够的物理内存可供云主机使用。", "message_en": "Failed to start VM on KVM host, because host does not have enough physical memory for VM." }, { @@ -421,7 +421,7 @@ "method": "regex", "regex": "host\\[.*] capacity is not enough to offer cpu\\[[0-9]], memory\\[[0-9] bytes]", "message_cn": "物理机无法提供足够的资源 [CPU:%1$s,内存:%2$s 字节]。", - "message_en": "Host could not provide enough resources [CPU: %1$s, memory: %2$s bytes]." + "message_en": "Host could not provide enough resources [CPU: %2$s, memory: %3$s bytes]." }, { "category": "HOST", @@ -495,6 +495,14 @@ "message_cn": "物理机己失联,不能执行相应操作。", "message_en": "Could not perform this operation, because the host is disconnected." }, + { + "category": "HOST", + "code": "1031", + "method": "regex", + "regex": ".*failed to migrate vm\\[uuid:.*] from kvm host\\[uuid:.*, ip:.*] to dest host\\[ip:.*].*.No enough physical memory for guest.*", + "message_cn": "在物理机上迁移云主机失败,因为物理机已经没有足够的物理内存可供云主机使用。", + "message_en": "Failed to migrate VM on KVM host, because host does not have enough physical memory for VM." + }, { "category": "IAM2", "code": "1000", @@ -692,7 +700,7 @@ "code": "1008", "method": "regex", "regex": ".*overlap with ip range\\[uuid:.*, start ip:.*, end ip: .*].*", - "message_cn": "与己有的网络段范围 [uuid:%1$s,开始:%2$s,结束:%3$s] 重叠。", + "message_cn": "与已有的网络段范围 [uuid:%1$s,开始:%2$s,结束:%3$s] 重叠。", "message_en": "Overlapped with the existing IP range [uuid: %1$s, start ip: %2$s, end ip: %3$s]." }, { @@ -740,7 +748,7 @@ "code": "1001", "method": "regex", "regex": ".*hijacked detected. Your license.* permits .* hosts, but consumed .*, request additional .*. You can either apply a new license or delete additional hosts.*", - "message_cn": "强制检测,您的许可证 [%1$s] 允许 %2$s 台主机,目前己用 %3$s 台。您可以申请新的许可证,也可以删除已添加的主机。", + "message_cn": "强制检测,您的许可证 [%1$s] 允许 %2$s 台物理机,目前己用 %3$s 台。您可以申请新的许可证,也可以删除已添加的物理机。", "message_en": "Your license [%1$s] permits %2$s hosts, but consumed %3$s. You can either apply for a new license or delete extra hosts." }, { @@ -748,7 +756,7 @@ "code": "1002", "method": "regex", "regex": ".*you can only add .* hosts with the trail license; please apply for a commercial license if you want to add more hosts.*", - "message_cn": "您当前的许可证只允许添加 %1$s 台物理主机,如果您想要添加更多物理主机,请申请商业许可证。", + "message_cn": "您当前的许可证只允许添加 %1$s 台物理物理机,如果您想要添加更多物理物理机,请申请商业许可证。", "message_en": "You can only add %1$s hosts with the trial license. Please apply for a commercial license if you want to add more hosts." }, { @@ -756,7 +764,7 @@ "code": "1003", "method": "regex", "regex": "you can only add [0-9]* hosts with current license; please upgrade the license if you want to add more hosts", - "message_cn": "您当前的许可证只允许添加 %1$s 台物理主机,如果您想要添加更多物理主机,请更新或申请商业许可证。", + "message_cn": "您当前的许可证只允许添加 %1$s 台物理物理机,如果您想要添加更多物理物理机,请更新或申请商业许可证。", "message_en": "You can only add %1$s hosts with the current license. Please upgrade the license or apply for a commercial one if you want to add more hosts." }, { @@ -812,7 +820,7 @@ "code": "1002", "method": "regex", "regex": "required local primary storage.* cannot satisfy conditions.*, or hosts providing the primary storage don't satisfy conditions\\[.*, size \u003e .*]", - "message_cn": "本地主存储的状态不是 Enabled/Connected,或者主存储内的物理机状态不满足条件:[状态为 Enabled/Connected,存储容量 \u003e %6$s 字节]。", + "message_cn": "本地存储的状态不是 Enabled/Connected,或者主存储内的物理机状态不满足条件:[状态为 Enabled/Connected,存储容量 \u003e %6$s 字节]。", "message_en": "Status/State of the local primary storage is not Enabled/Connected. Or hosts providing the primary storage do not satisfy conditions: [Status/State: Enabled/Connected, storage capacity: \u003e %6$s bytes]." }, { @@ -820,7 +828,7 @@ "code": "1003", "method": "regex", "regex": "the required host.*, size \u003e .* or doesn't belong to a local primary storage satisfying conditions.* or its cluster doesn't attach to any local primary storage", - "message_cn": "所需要的物理机都不满足以下条件:1 状态为 Enabled/Connected,并且存储容量 \u003e %4$s 字节; 2 所属于的本地主存储状态为 Enabled/Connected; 3 有符合条件的本地主存储加载到物理机所属的集群上。", + "message_cn": "所需要的物理机都不满足以下条件:1 状态为 Enabled/Connected,并且存储容量 \u003e %4$s 字节; 2 所属于的本地存储状态为 Enabled/Connected; 3 有符合条件的本地存储加载到物理机所属的集群上。", "message_en": "The required host does not meet the following requirements: 1 Status/State: Enabled/Connected, size: \u003e %4$s bytes. 2 Status/State of the local primary storages: Enabled/Connected. 3 The cluster is attached to a local primary storage." }, { @@ -828,7 +836,7 @@ "code": "1004", "method": "regex", "regex": "no local primary storage in zone.* or contain hosts satisfying conditions.*", - "message_cn": "该区域内所有的本地主存储都不满足以下条件:1 状态为 Enabled/Connected;2 没有包含任何状态为 Enabled/Connected,并且存储容量 \u003e %6$s 字节的物理机。", + "message_cn": "该区域内所有的本地存储都不满足以下条件:1 状态为 Enabled/Connected;2 没有包含任何状态为 Enabled/Connected,并且存储容量 \u003e %6$s 字节的物理机。", "message_en": "No local primary storage in the zone meets the following requirements: 1 Status/State: Enabled/Connected. 2 The zone has hosts with the status/state Enabled/Connected and storage capacity \u003e %6$s bytes." }, { @@ -836,7 +844,7 @@ "code": "1005", "method": "regex", "regex": "no local primary storage can satisfy conditions.* or contain hosts satisfying conditions.*, size .*", - "message_cn": "所有的本地主存储都不满足以下条件:1 状态为 Enabled/Connected;2 没有包含任何状态为 Enabled/Connected,并且存储容量 \u003e %6$s 字节的物理机。", + "message_cn": "所有的本地存储都不满足以下条件:1 状态为 Enabled/Connected;2 没有包含任何状态为 Enabled/Connected,并且存储容量 \u003e %6$s 字节的物理机。", "message_en": "No local primary storage meets the following requirements: 1 Status/State: Enabled/Connected. 2 The zone has hosts with the status/state Enabled/Connected and storage capacity \u003e %6$s bytes." }, { @@ -868,7 +876,7 @@ "code": "1009", "method": "regex", "regex": ".*unable to connect the shared block group primary storage\\[uuid:.*, name:.*] to the cluster\\[uuid:.*], Can't access shared block group primary storage on host\\[uuid:.*].*", - "message_cn": "无法将主机上的 SharedBlock 主存储加载到集群。", + "message_cn": "无法将物理机上的 SharedBlock 主存储加载到集群。", "message_en": "Could not attach SharedBlock storage to cluster." }, { @@ -892,7 +900,7 @@ "code": "1012", "method": "regex", "regex": ".*the NFS primary storage\\[uuid:.*, name:.*] has not attached to any clusters, or no hosts in the attached clusters are connected.*", - "message_cn": "NFS 主存储没有连接到任何集群,或者没有连接到所连接集群中的主机。", + "message_cn": "NFS 主存储没有连接到任何集群,或者没有连接到所连接集群中的物理机。", "message_en": "The NFS primary storage is not attached to any clusters, or no hosts in the attached clusters are connected." }, { @@ -940,7 +948,7 @@ "code": "1018", "method": "regex", "regex": "There is no LocalStorage primary storage.*when the cluster mounts multiple primary storage, the system uses the local primary storage.*", - "message_cn": "集群内没有正处于已启用且已连接状态的本地主存储,请检查集群内主存储的启用和就绪状态。", + "message_cn": "集群内没有正处于已启用且已连接状态的本地存储,请检查集群内主存储的启用和就绪状态。", "message_en": "Mo local primary storages with [state: Enabled, status: Connected] available in the cluster. Please check the state/status of the local primary storages." }, { @@ -948,7 +956,7 @@ "code": "1019", "method": "regex", "regex": ".*can not find vg .* and create vg with forceWipw=.*", - "message_cn": "无法将主机上的共享块主存储加载到集群,因为存在原有数据,请勾选清理块设备并重试。", + "message_cn": "无法将物理机上的共享块主存储加载到集群,因为存在原有数据,请勾选清理块设备并重试。", "message_en": "Could not attach shared block storage to cluster, because device is not empty. Please select the checkbox \"Clear LUN\" and try again." }, { @@ -959,7 +967,14 @@ "message_cn": "减去保留容量 [%1$s] 后,主存储 [%2$s] 没有所需的容量大小 [%3$s bytes],可能是主存储使用阈值设置较低。", "message_en": "primary storage [%1$s] don't have required size [%2$s] after subtracting reserved capacity. Possible reason: threshold of the primary storage usage is relatively low." }, - + { + "category": "PS", + "code": "1021", + "method": "regex", + "regex": "Cannot shrink .* volume\\[uuid:.*]'s size", + "message_cn": "不能缩小云盘 [uuid:%2$s] 的大小。", + "message_en": "Could not shrink volume [uuid: %2$s]'s size." + }, { "category": "QUOTA", "code": "1000", @@ -980,9 +995,9 @@ "category": "QUOTA", "code": "1002", "method": "regex", - "regex": ".*quota exceeding.The resource owner\\(or target resource owner\\) account\\[uuid:.*] exceeds a quota\\[name:.*, value: .*], Current used:.*, Request:.*. Please contact the administrator.", - "message_cn": "请求资源超出配额。资源所有者或目标资源所有者帐户 [uuid:%1$s] 超出配额 [配额名称:%2$s,配额总量:%3$s],当前已使用:%4$s,本次请求数量:%5$s。如需继续操作请联系管理员。", - "message_en": "Quota [name: %2$s, amount: %3$s] of the resource owner or target resource owner account [uuid: %1$s] exceeds the limit. Current used: %4$s, requests: %5$s. Please contact the administrator." + "regex": ".*quota exceeding.The resource owner\\(or target resource owner\\) account\\[uuid:.* name:.*] exceeds a quota\\[name:.*, value: .*], Current used:.*, Request:.*. Please contact the administrator.", + "message_cn": "请求资源超出配额。资源所有者或目标资源所有者帐户 [uuid:%1$s,帐户名称:%2$s] 超出配额 [配额名称:%3$s,配额总量:%4$s],当前已使用:%5$s,本次请求数量:%6$s。如需继续操作请联系管理员。", + "message_en": "Quota [name: %3$s, amount: %4$s] of the resource owner or target resource owner account [uuid: %1$s, name: %2$s] exceeds the limit. Current used: %5$s, requests: %6$s. Please contact the administrator." }, { "category": "QUOTA", @@ -1008,20 +1023,12 @@ "message_cn": "超出容量限制。", "message_en": "Disk quota exceeded." }, - { - "category": "SHAREDBLOCK", - "code": "1000", - "method": "regex", - "regex": "Cannot shrink .* volume\\[uuid:.*]'s size", - "message_cn": "不能缩小卷 [uuid:%2$s] 的大小。", - "message_en": "Could not shrink volume [uuid: %2$s]'s size." - }, { "category": "SNS", "code": "1000", "method": "regex", "regex": ".*Couldn't connect to host, port: .* The problem may be caused by an incorrect smtpServer or smtpPort.*", - "message_cn": "无法连接到主机,这个问题可能是 SMTP 服务器或者端口配置不正确导致的。", + "message_cn": "无法连接到物理机,这个问题可能是 SMTP 服务器或者端口配置不正确导致的。", "message_en": "Could not connect to host. Possible reason: incorrect SMTP server or SMTP port." }, { @@ -1045,7 +1052,7 @@ "code": "1000", "method": "regex", "regex": ".*failed to run virt-v2v command, because .*... for more details, please see log in conversion host: /tmp/v2v_log/.*", - "message_cn": "执行 virt-v2v 命令失败,详细内容请登录宿主机查找日志:/tmp/v2v_log/。", + "message_cn": "执行 virt-v2v 命令失败,详细内容请登录宿物理机查找日志:/tmp/v2v_log/。", "message_en": "Failed to run the virt-v2v command. For more details, please see log in conversion host: /tmp/v2v_log/." }, { @@ -1104,14 +1111,6 @@ "message_cn": "无法连接到 vCenter,请确保vCenter处于运行状态。", "message_en": "Failed to connect to vCenter. Please ensure vCenter host is running." }, - { - "category": "VCENTER", - "code": "1005", - "method": "regex", - "regex": "Detected .* MAC address conflict, current mac address conflicting strategy is: strict, .*", - "message_cn": "与当前已纳管的 vCenter 环境存在重复的 MAC 地址,当前的 MAC 地址冲突处理策略是“strict”。", - "message_en": "Duplicated MAC address with that in the currently managed vCenter environment, and current mac address conflicting strategy is 'strict'." - }, { "category": "VCENTER", "code": "1006", @@ -1189,8 +1188,8 @@ "code": "1007", "method": "regex", "regex": "after filtering, .* returns zero candidate host, it means: .*", - "message_cn": "创建云主机失败,未找到合适的物理机。", - "message_en": "Failed to create VM, because no qualified host found." + "message_cn": "创建/启动云主机失败,未找到合适的物理机。", + "message_en": "Failed to create/start VM, because no qualified host found." }, { "category": "VM", @@ -1213,7 +1212,7 @@ "code": "1010", "method": "regex", "regex": "The vm's root volume is on the local storage.* however, the host on which the root volume is has been deleted", - "message_cn": "云主机的根盘在本地主存储上,但该根盘所在的物理机己经下线。", + "message_cn": "云主机的根盘在本地存储上,但该根盘所在的物理机己经下线。", "message_en": "The VM's root volume is on the local primary storage. However, the host where the root volume resides is deleted." }, { @@ -1244,16 +1243,16 @@ "category": "VM", "code": "1014", "method": "regex", - "regex": ".*requested vcpus is greater than max allowable vcpus for the live domain: .* make NUMA take effect.*", - "message_cn": "请求的 vCPU 超过允许最大 vCPU 的范围,请尝试重新启动云主机以使 NUMA 生效。", - "message_en": "Requested vCPU count exceeds the upper limit. Please reboot the VM to make NUMA take effect." + "regex": ".*requested vcpus is greater than max allowable vcpus for the live domain: .* make Instance Offering Online Modification take effect.*", + "message_cn": "请求的 vCPU 超过允许最大 vCPU 的范围,请尝试重新启动云主机以使 计算规格在线修改 生效。", + "message_en": "Requested vCPU count exceeds the upper limit. Please reboot the VM to make Instance Offering Online Modification take effect." }, { "category": "VM", "code": "1015", "method": "regex", "regex": ".*host\\[uuid: .*] of local primary storage\\[uuid: .*] doesn't have enough capacity\\[current: .*bytes, needed: .*]", - "message_cn": "在物理机 [uuid:%1$s] 的本地主存储 [%2$s] 上没有足够的容量 [当前:%3$s 字节,需要:%4$s 字节]。", + "message_cn": "在物理机 [uuid:%1$s] 的本地存储 [%2$s] 上没有足够的容量 [当前:%3$s 字节,需要:%4$s 字节]。", "message_en": "Host [uuid: %1$s] of local primary storage [%2$s] does not have enough capacity [current: %3$s bytes, needed: %4$s bytes]." }, { @@ -1293,7 +1292,7 @@ "code": "1020", "method": "regex", "regex": "unable to recover the vm.*. The vm's root volume is on the local storage.* however, the host on which the root volume is has been deleted", - "message_cn": "无法恢复云主机,因为虚拟机的根盘处于物理机的本地存储上,但该物理机已经下线。", + "message_cn": "无法恢复云主机,因为云主机的根盘处于物理机的本地存储上,但该物理机已经下线。", "message_en": "Could not recover VM. The VN's root volume is on a local storage; however, the host where the root volume resides is deleted." }, { @@ -1301,7 +1300,7 @@ "code": "1021", "method": "regex", "regex": "the vm\\[uuid:.*] doesn't support to online attach volume\\[.*] on the basis of that the image platform type of the vm is other.*", - "message_cn": "该虚拟机不支持在线添加云盘,因为这台虚拟机的基础镜像平台类型为“其他”。", + "message_cn": "该云主机不支持在线添加云盘,因为这台云主机的基础镜像平台类型为“其他”。", "message_en": "Could not attach volume to the VM online, because the image platform type of the VM is \"Other\"." }, { @@ -1453,7 +1452,7 @@ "code": "1040", "method": "regex", "regex": "failed to start vm\\[uuid:.* name:.*] on kvm host\\[uuid:.*, ip:.* error reading header from .*: Operation not permitted.*", - "message_cn": "无法启动云主机,因为云盘对应的 Ceph 文件读取失败。", + "message_cn": "无法启动云主机,因为云盘对应的 Ceph主存储 文件读取失败。", "message_en": "Failed to start VM, because failed to read the Ceph file of the volume." }, { @@ -1623,5 +1622,101 @@ "regex": "the SSH port is not open after.*Failed to login the vyos router.*", "message_cn": "启动虚拟路由器超时,经过 %1$s 秒等待,虚拟路由器的 SSH 端口仍未开放。", "message_en": "Virtual router start timeout. The SSH port of the virtual router is not open after %1$s seconds." + }, + { + "category": "vmSchedulingRule", + "code": "3001", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vm antiaffinity from each other scheduling rule attached.* attaching another one is not allowed.", + "message_cn": "该云主机调度组已绑定互斥云主机调度策略,不可重复绑定。", + "message_en": "The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. Attaching another one is not allowed." + }, + { + "category": "vmSchedulingRule", + "code": "3002", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vm affinitive to each other scheduling rule attached. Attaching a vm antiaffinity from each other scheduling rule is not allowed.", + "message_cn": "该云主机调度组已绑定聚集云主机调度策略,不可绑定互斥云主机调度策略。", + "message_en": "The VM scheduling group has already had a VM Affinitive to Each Other scheduling policy attached. Attaching a VM Exclusive from Each Other scheduling policy is not allowed." + }, + { + "category": "vmSchedulingRule", + "code": "3003", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vm affinitive to each other scheduling rule attached.attaching another one is not allowed.", + "message_cn": "该云主机调度组已绑定聚集云主机调度策略,不可重复绑定。", + "message_en": "The VM scheduling group has already had a VM Affinitive to Each Other scheduling policy attached. Attaching another one is not allowed." + }, + { + "category": "vmSchedulingRule", + "code": "3004", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vm exclusive from each other scheduling rule attached.* Attaching a vm affinitive to each other scheduling policy is not allowed.", + "message_cn": "该云主机调度组已绑定互斥云主机调度策略,不可绑定聚集云主机调度策略。", + "message_en": "The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. Attaching a VM Affinitive to Each Other scheduling policy is not allowed." + }, + { + "category": "vmSchedulingRule", + "code": "3005", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vms affinitive to hosts scheduling rule attached.* you cannot attach another one to the group again.", + "message_cn": "该云主机调度组已绑定云主机亲和物理机调度策略,不可重复绑定。", + "message_en": "The VM scheduling group has already had a VMs Affinitive to Hosts scheduling policy attached. You cannot attach another one to the group again." + }, + { + "category": "vmSchedulingRule", + "code": "3006", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vm antiaffinity from host scheduling rule attached.* you cannot attach a vms affinitive to host scheduling rule to the group.", + "message_cn": "该云主机调度组已绑定云主机互斥物理机调度策略,不可绑定云主机亲和物理机调度策略。", + "message_en": "The VM scheduling group has already had a VMs Exclusive from Hosts scheduling policy attached. You cannot attach a VMs Affinitive to Hosts scheduling policy to the group." + }, + { + "category": "vmSchedulingRule", + "code": "3007", + "method": "regex", + "regex": "the vm scheduling group.* has already had a vm affinitive to hosts scheduling rule attached.* you cannot attach a vm antiaffinity from hosts scheduling rule to the group.", + "message_cn": "该云主机调度组已绑定云主机亲和物理机调度策略,不可绑定云主机互斥物理机调度策略。", + "message_en": "The VM scheduling group has already had a VMs Affinitive to Hosts scheduling policy attached. You cannot attach a VMs Exclusive from Hosts scheduling policy to the group." + }, + { + "category": "vmSchedulingRule", + "code": "3008", + "method": "regex", + "regex": "the vm scheduling group has already had a vm antiaffinity from each other scheduling rule attached. the number of hosts available for the vm in the scheduling group to run is less than that of the vm in the group. you cannot attach a vms affinitive to hosts scheduling policy to the group.", + "message_cn": "该云主机调度组已绑定互斥云主机调度策略,若再绑定云主机亲和物理机调度策略,当前可供组内云主机运行的物理机数量将少于云主机数量,导致部分云主机无法分配物理机。请按需调整物理机/云主机数量后重试。", + "message_en": "The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VMs Affinitive to Hosts scheduling policy to the group." + }, + { + "category": "vmSchedulingRule", + "code": "3009", + "method": "regex", + "regex": "the vm scheduling group has already had a vms Affinitive to Hosts scheduling policy attached. the number of hosts available for the vm in the scheduling group to run is less than that of the vm in the group. you cannot attach a vm antiaffinity from each other scheduling rule to the group again.", + "message_cn": "该云主机调度组已绑定云主机亲和物理机调度策略,若再绑定互斥云主机调度策略,当前可供组内云主机运行的物理机数量将少于云主机数量,导致部分云主机无法分配物理机。请按需调整物理机/云主机数量后重试。", + "message_en": "The VM scheduling group has already had a VMs Affinitive to Hosts scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VM Exclusive from Each Other scheduling policy to the group again." + }, + { + "category": "vmSchedulingRule", + "code": "3010", + "method": "regex", + "regex": "the vm scheduling group has already had a vm antiaffinity from each other scheduling rule attached. the number of hosts available for the vm in the scheduling group to run is less than that of the vm in the group. you cannot attach a vms antiaffinity from Hosts scheduling policy to the group.", + "message_cn": "该云主机调度组已绑定互斥云主机调度策略,若再绑定云主机互斥物理机调度策略,当前可供组内云主机运行的物理机数量将少于云主机数量,导致部分云主机无法分配物理机。请按需调整物理机/云主机数量后重试。", + "message_en": "The VM scheduling group has already had a VM Exclusive from Each Other scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VMs Exclusive from Hosts scheduling policy to the group." + }, + { + "category": "vmSchedulingRule", + "code": "3011", + "method": "regex", + "regex": "the vm scheduling group has already had a vms antiaffinity from hosts scheduling rule attached. the number of hosts available for the vm in the scheduling group to run is less than that of the vm in the group. you cannot attach a vm antiaffinity from Each Other scheduling rule to the group", + "message_cn": "该云主机调度组已绑定云主机互斥物理机调度策略,若再绑定互斥云主机调度策略,当前可供组内云主机运行的物理机数量将少于云主机数量,导致部分云主机无法分配物理机。请按需调整物理机/云主机数量后重试。", + "message_en": "The VM scheduling group has already had a VMs Exclusive from Hosts scheduling policy attached. The number of hosts available for the VM instances in the scheduling group to run is less than that of the VM instances in the group. You cannot attach a VM Exclusive from Each Other scheduling policy to the group." + }, + { + "category": "logServer", + "code": "1001", + "method": "regex", + "regex": "The creation of the log server failed, incorrect newly passed configuration parameters may have caused the Fluent Bit service to be in an inactive state. Please double-check the configuration for accuracy", + "message_cn": "创建日志服务器失败,新传入配置参数有误会导致fluent-bit服务处于非活跃状态,请再次检查配置是否正确。", + "message_en": "The creation of the log server failed, incorrect newly passed configuration parameters may have caused the Fluent Bit service to be in an inactive state. Please double-check the configuration for accuracy" } ] diff --git a/conf/globalConfig/applianceVm.xml b/conf/globalConfig/applianceVm.xml index c988fff8ff6..8bde73d1077 100755 --- a/conf/globalConfig/applianceVm.xml +++ b/conf/globalConfig/applianceVm.xml @@ -47,4 +47,28 @@ java.lang.Boolean true + + + auto.rollback + auto delete applianceVm when created failed, auto stop applianceVm when start/reboot failed. + true + applianceVm + java.lang.Boolean + + + + enableAbnormalFileReporter + enable abnormal file reporter to report abnormal files in applianceVm + true + applianceVm + java.lang.Boolean + + + + abnormalFileMaxSize + the max size of abnormal file that will not report abnormal files in applianceVm + 100 + applianceVm + java.lang.Long + diff --git a/conf/globalConfig/ceph.xml b/conf/globalConfig/ceph.xml index 28be0e9460c..ccde2ee2806 100755 --- a/conf/globalConfig/ceph.xml +++ b/conf/globalConfig/ceph.xml @@ -16,6 +16,22 @@ java.lang.Long + + trash.cleanup.interval + interval to cleanup image trash on primary storage, in seconds. + ceph + 43200 + java.lang.Long + + + + image.expiration.time + the expiration time in seconds of an image so it can be purged when it is stale. + ceph + 604800 + java.lang.Long + + primaryStorage.deletePool delete all primary storage related pools when deleting the ceph primary storage @@ -91,7 +107,7 @@ sds.admin.password the password of ceph admin user - password + Admin@123 ceph java.lang.String diff --git a/conf/globalConfig/cluster.xml b/conf/globalConfig/cluster.xml index 73a310ccc47..88926fe516d 100755 --- a/conf/globalConfig/cluster.xml +++ b/conf/globalConfig/cluster.xml @@ -4,7 +4,7 @@ cluster update.os.parallelismDegree The maximum count of cluster that can update operating system at the same time - 2 + 10 java.lang.Integer diff --git a/conf/globalConfig/consoleConfig.xml b/conf/globalConfig/consoleConfig.xml index 2d3c9468ab7..1617fc4434b 100755 --- a/conf/globalConfig/consoleConfig.xml +++ b/conf/globalConfig/consoleConfig.xml @@ -8,6 +8,14 @@ java.lang.Integer + + console + proxy.tls.version + The tls version proxy to use + NONE + java.lang.String + + console agent.ping.interval @@ -31,4 +39,12 @@ 4900,4901 java.lang.String + + + console + delete.consoleproxy.gc.delay + the delay delete does the next try for a console proxy if the previous delete operation failed, in seconds + java.lang.Integer + 60 + diff --git a/conf/globalConfig/host.xml b/conf/globalConfig/host.xml index 6135a71ec35..ac15a50e580 100755 --- a/conf/globalConfig/host.xml +++ b/conf/globalConfig/host.xml @@ -81,7 +81,7 @@ host update.os.parallelismDegree The maximum count of host that can update operating system at the same time - 2 + 10 java.lang.Integer @@ -119,4 +119,20 @@ 10000 java.lang.Integer + + host + host.power.refresh.interval + The interval to refresh host power status, in seconds + 60 + java.lang.Integer + + + + host + sync.host.hw.monitor.interval + The interval to sync host hw monitor, in seconds + 60 + java.lang.Integer + + diff --git a/conf/globalConfig/hostAllocator.xml b/conf/globalConfig/hostAllocator.xml index e5dde83e614..296b0c4c97b 100755 --- a/conf/globalConfig/hostAllocator.xml +++ b/conf/globalConfig/hostAllocator.xml @@ -56,4 +56,12 @@ java.lang.Boolean + + migration.differentOs + true allows vm to migrate between hosts with different operating systems + hostAllocator + false + java.lang.Boolean + + diff --git a/conf/globalConfig/image.xml b/conf/globalConfig/image.xml index b19be1f36f4..dc76e29ce4b 100755 --- a/conf/globalConfig/image.xml +++ b/conf/globalConfig/image.xml @@ -70,4 +70,20 @@ blacklist java.lang.String + + + upload.failure.tolerance.count + number of errors can be tolerated when uploading images + image + 3 + java.lang.Long + + + + upload.max.idle.duration.in.seconds + the max duration can be tolerated when uploading images, in seconds + image + 30 + java.lang.Long + diff --git a/conf/globalConfig/kvm.xml b/conf/globalConfig/kvm.xml index 36ae6ad8dc7..76d53a5453a 100755 --- a/conf/globalConfig/kvm.xml +++ b/conf/globalConfig/kvm.xml @@ -28,7 +28,7 @@ kvm reservedCpu The CPU capacity reserved on all KVM hosts. ZStack KVM agent is a python web server that needs some CPU capacity to run, this value reserve a portion of CPU for the agent as well as other host applications. The value can be overriden by system tag on individual host, cluster and zone level - 512 + 0 @@ -109,7 +109,7 @@ kvm vm.cpuMode - the cpu mode option, which could be used to enable nested virtualization, options are [none, host-model, host-passthrough, Haswell, Haswell-noTSX, Broadwell, Broadwell-noTSX, SandyBridge, IvyBridge, Conroe, Penryn, Nehalem, Westmere, Opteron_G1, Opteron_G2, Opteron_G3, Opteron_G4]. none: not use nested virtualization; host-model/host-passthrough will enable nested virtualization. When using host-passthrough, VM will see same CPU model in Host /proc/cpuinfo. When using host-model or host-passthrough, VM migration might be failed, due to mismatched CPU model. To use nested virtualization, user need to do some pre-configuration. Firstly, the /sys/module/kvm_intel/parameters/nested should be set as 'Y'; Secondly, the /usr/libexec/qemu-kvm binary should support nested feature as well. + the cpu mode option, which could be used to enable nested virtualization, options are [none, host-model, host-passthrough, Haswell, Haswell-noTSX, Broadwell, Broadwell-noTSX, SandyBridge, IvyBridge, Conroe, Penryn, Nehalem, Westmere, Opteron_G1, Opteron_G2, Opteron_G3, Opteron_G4, pentium, pentium2, pentium3]. none: not use nested virtualization; host-model/host-passthrough will enable nested virtualization. When using host-passthrough, VM will see same CPU model in Host /proc/cpuinfo. When using host-model or host-passthrough, VM migration might be failed, due to mismatched CPU model. To use nested virtualization, user need to do some pre-configuration. Firstly, the /sys/module/kvm_intel/parameters/nested should be set as 'Y'; Secondly, the /usr/libexec/qemu-kvm binary should support nested feature as well. java.lang.String none @@ -201,4 +201,76 @@ 3 java.lang.Long + + + kvm + enable.vm.migration.host.cpu.function.check + Check whether the CPU function of the dstHost is compatible with the CPU function of the srcHost. + true + java.lang.Boolean + + + + kvm + redirect.vm.log.to.file + Redirect vm console log to file + false + java.lang.Boolean + + + + kvm + vm.cpu.hypervisor.feature + enable or disable hypervisor feature in guest cpuid + true + java.lang.Boolean + + + + kvm + vm.hyperv.clock.feature + Enable or disable hypervclock + true + java.lang.Boolean + + + + kvm + vm.suspend.to.ram + Enable vm suspend to ram + false + java.lang.Boolean + + + + kvm + vm.suspend.to.disk + Enable vm suspend to disk + false + java.lang.Boolean + + + + kvm + webssh.idleTimeout + WebSSH timeout in seconds duration starts counting after the user has stopped interacting. + 1800 + java.lang.Integer + + + + kvm + kvmagent.physicalmemory.usage.alarm.threshold + The threshold for the physical memory usage of the kvmagent process, exceeding which an alarm will be triggered. + 2147483648 + java.lang.Long + + + + kvm + kvmagent.physicalmemory.usage.hardlimit + The hard limit for the physical memory usage of the kvmagent process, exceeding this value will trigger a kvmagent restart. + 10737418240 + java.lang.Long + diff --git a/conf/globalConfig/l2Network.xml b/conf/globalConfig/l2Network.xml index b41d61025c9..f6032411257 100644 --- a/conf/globalConfig/l2Network.xml +++ b/conf/globalConfig/l2Network.xml @@ -7,4 +7,25 @@ l2Network java.lang.Boolean + + l2.isolated + l2 isolated with physical switch + false + l2Network + java.lang.Boolean + + + igmp.version + igmp version used for linux bridge igmp snooping, 0 means does not change host OS value + 0 + l2Network + java.lang.Integer + + + mld.version + mld version used for linux bridge igmp snooping, 0 means does not change host OS value + 0 + l2Network + java.lang.Integer + \ No newline at end of file diff --git a/conf/globalConfig/l3Network.xml b/conf/globalConfig/l3Network.xml new file mode 100644 index 00000000000..299e71b965c --- /dev/null +++ b/conf/globalConfig/l3Network.xml @@ -0,0 +1,10 @@ + + + + basic.network.enable.ra + enable ipv6 RA for basic network + false + l3Network + java.lang.Boolean + + \ No newline at end of file diff --git a/conf/globalConfig/lb.xml b/conf/globalConfig/lb.xml index 88a235ef253..5b3a9e3f5d9 100755 --- a/conf/globalConfig/lb.xml +++ b/conf/globalConfig/lb.xml @@ -81,7 +81,7 @@ loadBalancer httpMode - When mode http is turned on, HAProxy processes HTTP protocol for each request and response passing through. to choose from http-keep-alive,http-server-close,http-tunnel,httpclose,forceclose + When mode http is turned on, HAProxy processes HTTP protocol for each request and response passing through. to choose from http-keep-alive,http-server-close,httpclose http-server-close java.lang.String diff --git a/conf/globalConfig/networkService.xml b/conf/globalConfig/networkService.xml index 5d10fdcf346..73459682a13 100755 --- a/conf/globalConfig/networkService.xml +++ b/conf/globalConfig/networkService.xml @@ -35,4 +35,11 @@ quota java.lang.Long + + enableVHostUser + use vHostUser instead of vDpa + false + networkService + java.lang.Boolean + diff --git a/conf/globalConfig/primaryStorage.xml b/conf/globalConfig/primaryStorage.xml index a8587e48201..13d78277f75 100755 --- a/conf/globalConfig/primaryStorage.xml +++ b/conf/globalConfig/primaryStorage.xml @@ -63,4 +63,20 @@ java.lang.Integer primaryStorage + + + trash.expiration.time + Volume that have been in trash more than expiration time in seconds will be automatically deleted. + 604800 + java.lang.Integer + primaryStorage + + + + primarystorage.host.status.refresh.interval + primaryStorage + The interval to refresh ps and host connection status, in seconds + 60 + java.lang.Integer + diff --git a/conf/globalConfig/snapshot.xml b/conf/globalConfig/snapshot.xml index 7e0be2676ef..d0a9ada1bc6 100755 --- a/conf/globalConfig/snapshot.xml +++ b/conf/globalConfig/snapshot.xml @@ -4,7 +4,7 @@ volumeSnapshot incrementalSnapshot.maxNum The length of a volume snapshot chain. When the lenght of a volume snapshot chain reaches this value, the next volume snapshot will be a full snapshot - 128 + 64 java.lang.Integer @@ -40,4 +40,19 @@ java.lang.Boolean + + volumeSnapshot + enable.fast.revert + Enable fast revert for volume snapshot + false + java.lang.Boolean + + + + volumeSnapshot + snapshot.group.revert.concurrency + The maximum number of snapshots that are permitted to revert concurrently. + 1 + java.lang.Integer + \ No newline at end of file diff --git a/conf/globalConfig/upgrade.xml b/conf/globalConfig/upgrade.xml new file mode 100644 index 00000000000..8b3dfca5ac4 --- /dev/null +++ b/conf/globalConfig/upgrade.xml @@ -0,0 +1,18 @@ + + + + upgradeControl + grayscaleUpgrade + A switch to control grayscale upgrade + false + java.lang.Boolean + + + + upgradeControl + allowedApiListGrayscaleUpgrading + Allowed operations when grayscale upgrade + MigrateVmLongJob,UpdateClusterOSJob,APILocalStorageMigrateVolumeMsg + java.lang.String + + diff --git a/conf/globalConfig/vm.xml b/conf/globalConfig/vm.xml index 4bb59984d50..0d4a1744e1d 100755 --- a/conf/globalConfig/vm.xml +++ b/conf/globalConfig/vm.xml @@ -65,9 +65,17 @@ videoType - video type for VM. "cirrus" supply basic video type, the resolution is not high. "vga" supply more high resolution for VM. "qxl" supply high performance when use SPICE protocal. Options:[vga, cirrus, qxl] + video type for VM. "virtio" supply basic video type. "vga" supply more high resolution for VM. "qxl" supply high performance when use SPICE protocal. "cirrus" mark as deprecated, reserved for compatibility. Options:[vga, cirrus, qxl, virtio] vm - cirrus + virtio + java.lang.String + + + + soundType + sound type for VM. "ich6" supply basic sound typen for VM. Options:[ich6, ich9, ac97] + vm + ich6 java.lang.String @@ -79,6 +87,14 @@ false + + vm + vm.max.vcpu + vm's maximum vcpu number + java.lang.Integer + 128 + + bootMenu whether to enable boot menu @@ -87,6 +103,14 @@ java.lang.Boolean + + bootMenuSplashTimeout + splash timeout of boot menu in milliseconds + vm + 3000 + java.lang.Integer + + kvmHiddenState hide KVM hypervisor signature to guest @@ -261,4 +285,36 @@ vm java.lang.String + + + enable.uefi.secure.boot + enable uefi secure boot + true + vm + java.lang.Boolean + + + + vm + enable.vm.address.recording + enable vm device address record + java.lang.Boolean + true + + + + vm + enable.vm.internal.ip.overwrite + enable vm internal ip address overwrite db record + java.lang.Boolean + false + + + + vm + uniqueVmName + enable vm name unique + java.lang.Boolean + false + diff --git a/conf/globalConfig/volume.xml b/conf/globalConfig/volume.xml index d9755119e74..cd34bfe4129 100755 --- a/conf/globalConfig/volume.xml +++ b/conf/globalConfig/volume.xml @@ -46,4 +46,20 @@ false java.lang.Boolean + + + refreshVolumeSize.scope + sync volume size scope, options are [AllActive, Monitored, None]. AllActive: sync all active volumes, Monitored: sync all monitored volumes + volume + AllActive + + + + refreshVolumeSize.hostCountPerBatch + the host count for per batching refresh volumes + volume + 10 + java.lang.Integer + + diff --git a/conf/globalConfig/vyos.xml b/conf/globalConfig/vyos.xml index 975ac099d5c..6d341d58a50 100755 --- a/conf/globalConfig/vyos.xml +++ b/conf/globalConfig/vyos.xml @@ -21,4 +21,32 @@ java.lang.Boolean false - \ No newline at end of file + + vyos + enable.haproxy.log + enable or disable haproxy log + java.lang.Boolean + true + + + vyos + enable.loadbalancer.full.log + open full haproxy log + java.lang.Boolean + false + + + vyos + enable.loadbalancer.stats.log + open haproxy stats log + java.lang.Boolean + false + + + vyos + enable.vyos.cmd + enable or disable vyos command + java.lang.Boolean + true + + diff --git a/conf/guestOs/guestOsCategory.xml b/conf/guestOs/guestOsCategory.xml index fe1962195fa..b444d32cecc 100644 --- a/conf/guestOs/guestOsCategory.xml +++ b/conf/guestOs/guestOsCategory.xml @@ -24,6 +24,18 @@ 8 CentOS 8 + + Linux + CentOS Stream + 9 + CentOS Stream 9 + + + Linux + CentOS Stream + 10 + CentOS Stream 10 + Linux RedHat @@ -48,6 +60,18 @@ 8 RHEL 8 + + Linux + RedHat + 9 + RHEL 9 + + + Linux + RedHat + 10 + RHEL 10 + Linux Ubuntu @@ -66,6 +90,18 @@ 20 Ubuntu 20 + + Linux + Ubuntu + 22 + Ubuntu 22 + + + Linux + Ubuntu + 24 + Ubuntu 24 + Linux Debian @@ -90,12 +126,36 @@ 10 Debian 10 + + Linux + Debian + 11 + Debian 11 + + + Linux + Debian + 12 + Debian 12 + + + Linux + Debian + 13 + Debian 13 + Linux Fedora Fedora + + Linux + Fedora + 42 + Fedora 42 + Linux Kylin @@ -114,6 +174,12 @@ 10 Kylin 10 + + Linux + Kylin + 11 + Kylin 11 + Linux UOS @@ -126,13 +192,115 @@ 20.03 openEuler 20.03 + + Linux + openEuler + 22.03 + openEuler 22.03 + + + Linux + openEuler + 24.03 + openEuler 24.03 + + + Linux + VyOS + 1.1.7 + VyOS 1.1.7 + + + Linux + VyOS + 1.2.0 + VyOS 1.2.0 + + + Linux + SUSE + 12 + SUSE Linux 12 + + + Linux + SUSE + 15 + SUSE Linux 15 + Linux Linux Linux + + Linux + Oracle + 7 + Oracle Linux 7 + + + Linux + Oracle + 8 + Oracle Linux 8 + + + Linux + Oracle + 9 + Oracle Linux 9 + + + Linux + Rocky Linux + 8 + Rocky Linux 8 + + + Linux + Rocky Linux + 9 + Rocky Linux 9 + + + Linux + Rocky Linux + 10 + Rocky Linux 10 + + + Linux + AlmaLinux + 9 + AlmaLinux 9 + + + Linux + AnolisOS + 8 + AnolisOS 8 + + + Linux + Linux + + Other Kernel ≥ 4.20 or Hygon Linux + + + Windows + Windows + 4.0 + Windows NT 4.0 + + + Windows + Windows + 2003 + WindowsServer 2003 + Windows Windows @@ -157,6 +325,18 @@ 2019 WindowsServer 2019 + + Windows + Windows + 2022 + WindowsServer 2022 + + + Windows + Windows + 2025 + WindowsServer 2025 + Windows Windows @@ -175,6 +355,12 @@ 10 Windows 10 + + Windows + Windows + 11 + Windows 11 + Windows Windows @@ -194,6 +380,12 @@ FreeBSD + + Other + Solaris + 10 + Solaris 10 + Other Other diff --git a/conf/guestOs/guestOsCharacter.xml b/conf/guestOs/guestOsCharacter.xml index 74be3efda77..2714496712c 100644 --- a/conf/guestOs/guestOsCharacter.xml +++ b/conf/guestOs/guestOsCharacter.xml @@ -4,202 +4,340 @@ aarch64 Linux - Kylin 10 - true + Kylin 4 + false + + - aarch64 + loongarch64 Linux - openEuler 20.03 - true + Kylin 4 + false - + + x86_64 + Linux + Other Kernel ≥ 4.20 or Hygon Linux + false + x86_64 Linux CentOS 5 - true x86_64 Linux CentOS 6 - true x86_64 Linux CentOS 7 - true x86_64 Linux CentOS 8 - true + + + x86_64 + Linux + CentOS Stream 9 + + + x86_64 + Linux + CentOS Stream 10 x86_64 Linux RHEL 5 - true x86_64 Linux RHEL 6 - true x86_64 Linux RHEL 7 - true x86_64 Linux RHEL 8 - true + + + x86_64 + Linux + RHEL 9 + + + x86_64 + Linux + RHEL 10 x86_64 Linux Ubuntu 16 - true x86_64 Linux Ubuntu 18 - true x86_64 Linux Ubuntu 20 - true + + + x86_64 + Linux + Ubuntu 22 + + + x86_64 + Linux + Ubuntu 24 x86_64 Linux Debian 7 - true x86_64 Linux Debian 8 - true x86_64 Linux Debian 9 - true x86_64 Linux Debian 10 - true + + + x86_64 + Linux + Debian 11 + + + x86_64 + Linux + Debian 12 + + + x86_64 + Linux + Debian 13 x86_64 Linux Fedora - true + + + x86_64 + Linux + Fedora 42 x86_64 Linux Kylin 4 - true x86_64 Linux Kylin 7 - true x86_64 Linux Kylin 10 - true + + + x86_64 + Linux + Kylin 11 x86_64 Linux UOS 20 - true x86_64 Linux openEuler 20.03 - true + + + x86_64 + Linux + openEuler 22.03 + + + x86_64 + Linux + openEuler 24.03 + + + x86_64 + Linux + VyOS 1.1.7 + + + x86_64 + Linux + VyOS 1.2.0 + + + x86_64 + Linux + Oracle Linux 7 + + + x86_64 + Linux + Oracle Linux 8 + + + x86_64 + Linux + Oracle Linux 9 + + + x86_64 + Linux + SUSE Linux 12 + + + x86_64 + Linux + SUSE Linux 15 + + + x86_64 + Linux + Rocky Linux 8 + + + x86_64 + Linux + Rocky Linux 9 + + + x86_64 + Linux + Rocky Linux 10 + + + x86_64 + Linux + AlmaLinux 9 + + + x86_64 + Linux + AnolisOS 8 x86_64 Linux Linux - true x86_64 Windows - true + WindowsServer 2003 + + + x86_64 + Windows WindowsServer 2008 x86_64 Windows - true WindowsServer 2012 x86_64 Windows - true + Windows NT 4.0 + pentium + pcnet + + + x86_64 + Windows WindowsServer 2016 x86_64 Windows - false WindowsServer 2019 + false + + + x86_64 + Windows + WindowsServer 2022 + false + + + x86_64 + Windows + WindowsServer 2025 + false x86_64 Windows - true Windows 7 x86_64 Windows - true Windows 8 x86_64 Windows - false Windows 10 + false + + + x86_64 + Windows + Windows 11 x86_64 Windows - true Windows xp x86_64 Windows - true Windows - \ No newline at end of file + + x86_64 + Other + Solaris 10 + false + + diff --git a/conf/i18n.json b/conf/i18n.json index 857e2bad7dc..29c50620912 100755 --- a/conf/i18n.json +++ b/conf/i18n.json @@ -2,42 +2,42 @@ { "raw": "no pemission to do the operation for [accountUuid:%s, userUuid:%s]", "en_US": "no pemission to do the operation for [accountUuid:{0}, userUuid:{1}]", - "zh_CN": "", + "zh_CN": "没有可对[AccountUuId:{0},UserUuId:{1}]执行操作的pEmission", "arguments": [ "accountUuid", "userUuid" ], - "line": 44, + "line": 43, "fileName": "src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java" }, { "raw": "If a specified Accesskey is expected, the AccesskeyId and the AccesskeySecret must be provided at the same time.", "en_US": "If a specified Accesskey is expected, the AccesskeyId and the AccesskeySecret must be provided at the same time.", - "zh_CN": "", + "zh_CN": "如果需要指定的AccessKey,则必须同时提供AccessKeyId和AccessKeySecret。", "arguments": [], - "line": 51, + "line": 50, "fileName": "src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java" }, { "raw": "[accountId: %s, userID: %s] is not valid account or iam2 porject/user", "en_US": "[accountId: {0}, userID: {1}] is not valid account or iam2 porject/user", - "zh_CN": "", + "zh_CN": "[帐户ID:{0},用户ID:{1}]不是有效的帐户或IAM2对象/用户", "arguments": [ "msg.getAccountUuid()", "msg.getUserUuid()" ], - "line": 65, + "line": 72, "fileName": "src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java" }, { "raw": "accessKey number for [accountId: %s, userID: %s]exceeds the max", "en_US": "accessKey number for [accountId: {0}, userID: {1}]exceeds the max", - "zh_CN": "", + "zh_CN": "[AccountId:{0},UserId:{1}]的AccessKey编号超出最大值", "arguments": [ "msg.getAccountUuid()", "msg.getUserUuid()" ], - "line": 77, + "line": 91, "fileName": "src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java" }, { @@ -85,6 +85,16 @@ "line": 109, "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" }, + { + "raw": "the access-control-list groups[%s] already own redirect rule, can not add IP Entry", + "en_US": "the access-control-list groups[{0}] already own redirect rule, can not add IP Entry", + "zh_CN": "访问控制列表组[{0}]已拥有重定向规则,无法添加IP条目", + "arguments": [ + "acl.getUuid()" + ], + "line": 127, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, { "raw": "the access-control-list groups[%s] can\u0027t be added more than %d ip entries", "en_US": "the access-control-list groups[{0}] can\u0027t be added more than {1} ip entries", @@ -93,13 +103,71 @@ "acl.getUuid()", "AccessControlListConstants.MAX_ENTRY_COUNT_PER_GROUP" ], - "line": 127, + "line": 133, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, + { + "raw": "the access-control-list groups[%s] already own redirect rule, can not add ip entry", + "en_US": "the access-control-list groups[{0}] already own redirect rule, can not add ip entry", + "zh_CN": "访问控制列表组[{0}]已拥有重定向规则,无法添加IP条目", + "arguments": [ + "acl.getUuid()" + ], + "line": 138, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, + { + "raw": "the access-control-list groups[%s] already own ip entry, can not add redirect rule", + "en_US": "the access-control-list groups[{0}] already own ip entry, can not add redirect rule", + "zh_CN": "访问控制列表组[{0}]已拥有IP条目,无法添加重定向规则", + "arguments": [ + "acl.getUuid()" + ], + "line": 154, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, + { + "raw": "the access-control-list groups[%s] already own one redirect rule, can not add redirect rule", + "en_US": "the access-control-list groups[{0}] already own one redirect rule, can not add redirect rule", + "zh_CN": "访问控制列表组[{0}]已拥有一个重定向规则,无法添加重定向规则", + "arguments": [ + "acl.getUuid()" + ], + "line": 158, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, + { + "raw": "domain and url can not both empty", + "en_US": "domain and url can not both empty", + "zh_CN": "域和URL不能同时为空", + "arguments": [], + "line": 162, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, + { + "raw": "url[%s] is not validate url", + "en_US": "url[{0}] is not validate url", + "zh_CN": "URL[{0}]不是验证URL", + "arguments": [ + "msg.getUrl()" + ], + "line": 178, + "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" + }, + { + "raw": "domain[%s] is not validate domain", + "en_US": "domain[{0}] is not validate domain", + "zh_CN": "域[{0}]不是验证域", + "arguments": [ + "msg.getDomain()" + ], + "line": 167, "fileName": "src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java" }, { "raw": "cannot connect to [%s] in %d milliseconds, so aliyun openapi is unreachable.", "en_US": "cannot connect to [{0}] in {1} milliseconds, so aliyun openapi is unreachable.", - "zh_CN": "", + "zh_CN": "无法在{1}毫秒内连接到[{0}],因此无法访问阿里云OpenAPI。", "arguments": [ "builder.deleteCharAt(builder.length() - 1)", "timeout" @@ -112,7 +180,7 @@ "en_US": "no bucket found for backup", "zh_CN": "没有可用的Bucket执行备份", "arguments": [], - "line": 465, + "line": 466, "fileName": "src/main/java/org/zstack/aliyun/backup/BackupToAliyunBase.java" }, { @@ -126,7 +194,7 @@ { "raw": "ocean api endpoint must not be null", "en_US": "ocean api endpoint must not be null", - "zh_CN": "", + "zh_CN": "Ocean API端点不能为空", "arguments": [], "line": 73, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunEbsClient.java" @@ -134,7 +202,7 @@ { "raw": "accessKey and keySecret must be set!", "en_US": "accessKey and keySecret must be set!", - "zh_CN": "", + "zh_CN": "必须设置AccessKey和KeySecret!", "arguments": [], "line": 33, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunNasClient.java" @@ -142,19 +210,11 @@ { "raw": "regionId must be set!", "en_US": "regionId must be set!", - "zh_CN": "", + "zh_CN": "必须设置RegionID!", "arguments": [], "line": 40, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunNasClient.java" }, - { - "raw": "cannot find key / secret from msg", - "en_US": "cannot find key / secret from msg", - "zh_CN": "", - "arguments": [], - "line": 238, - "fileName": "src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java" - }, { "raw": "entry is still existed after %s ms", "en_US": "entry is still existed after {0} ms", @@ -162,17 +222,17 @@ "arguments": [ "AliyunConstant.DEFAULT_ENTRY_WAIT_STATUS_TIMEOUT" ], - "line": 2131, + "line": 2162, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java" }, { "raw": "cannot find EcsInstance[%s], please check if it exists in Aliyun console", "en_US": "cannot find EcsInstance[{0}], please check if it exists in Aliyun console", - "zh_CN": "", + "zh_CN": "找不到ECSInstance[{0}],请检查阿里云控制台是否存在", "arguments": [ "request.getInstanceIds()" ], - "line": 2637, + "line": 2648, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java" }, { @@ -180,15 +240,7 @@ "en_US": "image already existed remote, please use sync first.", "zh_CN": "镜像已经存在阿里云服务器上,请尝试同步数据", "arguments": [], - "line": 2697, - "fileName": "src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java" - }, - { - "raw": "no identity zones can be used now", - "en_US": "no identity zones can be used now", - "zh_CN": "没有可用区能使用", - "arguments": [], - "line": 2883, + "line": 2708, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java" }, { @@ -198,95 +250,103 @@ "arguments": [ "request.getRegionId()" ], - "line": 3019, + "line": 3015, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java" }, { "raw": "Not a valid message!", "en_US": "Not a valid message!", - "zh_CN": "", + "zh_CN": "无效消息!", "arguments": [], - "line": 63, + "line": 61, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java" }, { "raw": "%s failed, ErrorCode: %s, ErrorMessage: %s", "en_US": "{0} failed, ErrorCode: {1}, ErrorMessage: {2}", - "zh_CN": "", + "zh_CN": "{0}失败,错误代码:{1},错误消息:{2}", "arguments": [ "action", "result.ErrorCode", "result.ErrorMessage" ], - "line": 159, + "line": 177, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java" }, { "raw": "Device Not Ready in %d milli seconds", "en_US": "Device Not Ready in {0} milli seconds", - "zh_CN": "", + "zh_CN": "设备在{0}毫秒内未就绪", "arguments": [ "15000" ], - "line": 282, + "line": 301, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java" }, { "raw": "snapshot task status is finished %s", "en_US": "snapshot task status is finished {0}", - "zh_CN": "", + "zh_CN": "快照任务状态为已完成{0}", "arguments": [ "result.Content.TaskStatus" ], - "line": 476, + "line": 497, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java" }, { "raw": "snapshot task cannot finished in %d milliseconds, now progress is %d, status is %s", "en_US": "snapshot task cannot finished in {0} milliseconds, now progress is {1}, status is {2}", - "zh_CN": "", + "zh_CN": "快照任务无法在{0}毫秒内完成,当前进度为{1},状态为{2}", "arguments": [ "msg.getTimeout()", "result.Content.Progress", "result.Content.TaskStatus" ], - "line": 472, + "line": 493, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java" }, { "raw": "not supported HybridClient", "en_US": "not supported HybridClient", - "zh_CN": "", + "zh_CN": "不支持HybridClient", "arguments": [], - "line": 877, + "line": 898, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java" }, { "raw": "add endpoint to sdk failed, due to: %s", "en_US": "add endpoint to sdk failed, due to: {0}", - "zh_CN": "", + "zh_CN": "将端点添加到SDK失败,原因是:{0}", "arguments": [ "e.getMessage()" ], - "line": 263, + "line": 259, "fileName": "src/main/java/org/zstack/aliyun/core/AliyunUtils.java" }, + { + "raw": "cannot find key / secret from msg", + "en_US": "cannot find key / secret from msg", + "zh_CN": "无法从消息中找到密钥/机密", + "arguments": [], + "line": 86, + "fileName": "src/main/java/org/zstack/aliyun/core/OssSdkImpl.java" + }, { "raw": "cannot input 0-length file as vm images!", "en_US": "cannot input 0-length file as vm images!", - "zh_CN": "", + "zh_CN": "无法将长度为0的文件作为云主机镜像输入!", "arguments": [], - "line": 407, + "line": 410, "fileName": "src/main/java/org/zstack/aliyun/core/OssSdkImpl.java" }, { "raw": "Permission denied for: %s", "en_US": "Permission denied for: {0}", - "zh_CN": "", + "zh_CN": "权限被拒绝:{0}", "arguments": [ "e.getMessage()" ], - "line": 496, + "line": 499, "fileName": "src/main/java/org/zstack/aliyun/core/OssSdkImpl.java" }, { @@ -296,13 +356,13 @@ "arguments": [ "e.getRequestId()" ], - "line": 585, + "line": 588, "fileName": "src/main/java/org/zstack/aliyun/core/OssSdkImpl.java" }, { "raw": "arg \u0027endpoint\u0027 must be set in %s type", "en_US": "arg \u0027endpoint\u0027 must be set in {0} type", - "zh_CN": "", + "zh_CN": "必须在{0}类型中设置参数“ endpoint ”", "arguments": [ "HybridType.AliyunEBS.toString()" ], @@ -312,7 +372,7 @@ { "raw": "not supported datacenter [%s] type here!", "en_US": "not supported datacenter [{0}] type here!", - "zh_CN": "", + "zh_CN": "此处不支持数据中心[{0}]类型!", "arguments": [ "type.toString()" ], @@ -322,15 +382,15 @@ { "raw": "must indicate zoneId in private aliyun.", "en_US": "must indicate zoneId in private aliyun.", - "zh_CN": "", + "zh_CN": "必须在私有阿里云中注明ZoneID。", "arguments": [], - "line": 252, + "line": 175, "fileName": "src/main/java/org/zstack/aliyun/core/identityzone/AliyunPrivateIdentityZoneBase.java" }, { "raw": "make ocean api signature string failed: %s", "en_US": "make ocean api signature string failed: {0}", - "zh_CN": "", + "zh_CN": "生成Ocean API签名字符串失败:{0}", "arguments": [ "e.getMessage()" ], @@ -340,7 +400,7 @@ { "raw": "url(ocean endpoint) must be set for aliyun ebs backupstorage", "en_US": "url(ocean endpoint) must be set for aliyun ebs backupstorage", - "zh_CN": "", + "zh_CN": "阿里云EBS备份存储必须设置URL(海洋端点)", "arguments": [], "line": 30, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/backup/AliyunEbsBackupStorageApiInterceptor.java" @@ -348,7 +408,7 @@ { "raw": "aliyun ebs backup storage do not support to cancel download image", "en_US": "aliyun ebs backup storage do not support to cancel download image", - "zh_CN": "", + "zh_CN": "阿里云EBS备份存储不支持取消下载镜像", "arguments": [], "line": 376, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/backup/AliyunEbsBackupStorageBase.java" @@ -356,7 +416,7 @@ { "raw": "no such object %s found in bucket %s", "en_US": "no such object {0} found in bucket {1}", - "zh_CN": "", + "zh_CN": "在存储桶{1}中找不到此类对象{0}", "arguments": [ "objectFile", "ovo.getBucketName()" @@ -367,7 +427,7 @@ { "raw": "cannot delete oss bucket [%s], Aliyun Ebs BackupStorage [%s] still existed, please delete it first.", "en_US": "cannot delete oss bucket [{0}], Aliyun Ebs BackupStorage [{1}] still existed, please delete it first.", - "zh_CN": "", + "zh_CN": "无法删除OSS Bucket[{0}],Aliyun EBS BackupStorage[{1}]仍然存在,请先将其删除。", "arguments": [ "oss.getUuid()", "evo.getUuid()" @@ -378,7 +438,7 @@ { "raw": "cannot find device path from volume: %s", "en_US": "cannot find device path from volume: {0}", - "zh_CN": "", + "zh_CN": "无法从卷中找到设备路径:{0}", "arguments": [ "vol.getUuid()" ], @@ -388,7 +448,7 @@ { "raw": "aliyun ebs not support resize on running vm now.", "en_US": "aliyun ebs not support resize on running vm now.", - "zh_CN": "", + "zh_CN": "阿里云EBS现在不支持在运行的云主机上调整大小。", "arguments": [], "line": 490, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsKvmFactory.java" @@ -396,7 +456,7 @@ { "raw": "iso [%s] has been attached, we can not attach it until detach it", "en_US": "iso [{0}] has been attached, we can not attach it until detach it", - "zh_CN": "", + "zh_CN": "已附加ISO[{0}],在分离它之前无法附加它", "arguments": [ "isoUuid" ], @@ -406,7 +466,7 @@ { "raw": "url must starts with http:// or https://, but got %s", "en_US": "url must starts with http:// or https://, but got {0}", - "zh_CN": "", + "zh_CN": "URL必须以HTTP://或HTTPS://开头,但获得了{0}", "arguments": [ "msg.getUrl()" ], @@ -416,7 +476,7 @@ { "raw": "url(ocean endpoint) must be set for aliyun ebs primarystorage", "en_US": "url(ocean endpoint) must be set for aliyun ebs primarystorage", - "zh_CN": "", + "zh_CN": "阿里云EBS PrimaryStorage必须设置URL(海洋端点)", "arguments": [], "line": 35, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java" @@ -424,7 +484,7 @@ { "raw": "panguPartitionUuid or identityZoneUuid must be set.", "en_US": "panguPartitionUuid or identityZoneUuid must be set.", - "zh_CN": "", + "zh_CN": "必须设置PangUpartitionUuid或IdentityZoneUuid。", "arguments": [], "line": 43, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java" @@ -432,7 +492,7 @@ { "raw": "panguPartitionUuid [%s] not be matched with identityZoneUuid [%s]", "en_US": "panguPartitionUuid [{0}] not be matched with identityZoneUuid [{1}]", - "zh_CN": "", + "zh_CN": "panguPartitionUuid[{0}]与identityZoneUuid[{1}]不匹配", "arguments": [ "msg.getPanguPartitionUuid()", "msg.getIdentityZoneUuid()" @@ -440,79 +500,59 @@ "line": 49, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java" }, - { - "raw": "image [uuid:%s] has been deleted", - "en_US": "image [uuid:{0}] has been deleted", - "zh_CN": "镜像[uuid:{0}]已经被删除", - "arguments": [ - "imageVO.getUuid()" - ], - "line": 3189, - "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" - }, - { - "raw": "resource[uuid: %s] cannot found", - "en_US": "resource[uuid: {0}] cannot found", - "zh_CN": "", - "arguments": [ - "msg.getResourceUuid()" - ], - "line": 3762, - "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" - }, { "raw": "the aliyun ebs primary storage[uuid:%s, name:%s] cannot find any available host in attached clusters for instantiating the volume", "en_US": "the aliyun ebs primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume", - "zh_CN": "", + "zh_CN": "阿里云EBS主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机", "arguments": [ "self.getUuid()", "self.getName()" ], - "line": 674, + "line": 669, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" }, { "raw": "create snapshot timeout, progress is %d", "en_US": "create snapshot timeout, progress is {0}", - "zh_CN": "", + "zh_CN": "创建快照超时,进度为{0}", "arguments": [ "reply1.getProgress()" ], - "line": 2829, + "line": 2888, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" }, { "raw": "cannot find snapshot from image: %s, maybe the image has been deleted", "en_US": "cannot find snapshot from image: {0}, maybe the image has been deleted", - "zh_CN": "", + "zh_CN": "无法从镜像中找到快照:{0},该镜像可能已被删除", "arguments": [ "msg.getVolume().getRootImageUuid()" ], - "line": 1925, + "line": 1971, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" }, { "raw": "ebs primarystorage cannot support decrease size now", "en_US": "ebs primarystorage cannot support decrease size now", - "zh_CN": "", + "zh_CN": "EBS主存储现在无法支持减小大小", "arguments": [], - "line": 2687, + "line": 2746, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" }, { "raw": "aliyun ebs primarystorage only support aliyun ebs bs, actually get type: %s", "en_US": "aliyun ebs primarystorage only support aliyun ebs bs, actually get type: {0}", - "zh_CN": "", + "zh_CN": "阿里云EBS PrimaryStorage仅支持阿里云EBS BS,实际获取类型:{0}", "arguments": [ "bsvo.getType()" ], - "line": 3089, + "line": 3134, "fileName": "src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java" }, { "raw": "cannot delete identity zone [%s], Aliyun Ebs PrimaryStorage [%s] still existed, please delete it first.", "en_US": "cannot delete identity zone [{0}], Aliyun Ebs PrimaryStorage [{1}] still existed, please delete it first.", - "zh_CN": "", + "zh_CN": "无法删除标识区[{0}],阿里云EBS PrimaryStorage[{1}]仍然存在,请先删除。", "arguments": [ "iz.getUuid()", "evo.getUuid()" @@ -523,7 +563,7 @@ { "raw": "invalid install path: %s", "en_US": "invalid install path: {0}", - "zh_CN": "", + "zh_CN": "安装路径无效:{0}", "arguments": [ "installPath" ], @@ -533,7 +573,7 @@ { "raw": "append volumeId: %s, but another volumeId existed in url: %s", "en_US": "append volumeId: {0}, but another volumeId existed in url: {1}", - "zh_CN": "", + "zh_CN": "附加VolumeID:{0},但URL中存在另一个VolumeID:{1}", "arguments": [ "volumeId", "url" @@ -544,7 +584,7 @@ { "raw": "invalid install url: %s", "en_US": "invalid install url: {0}", - "zh_CN": "", + "zh_CN": "无效的安装URL:{0}", "arguments": [ "url" ], @@ -554,7 +594,7 @@ { "raw": "hostUuid [%s] already existed in url: %s", "en_US": "hostUuid [{0}] already existed in url: {1}", - "zh_CN": "", + "zh_CN": "URL{1}中已存在HostUuid[{0}]", "arguments": [ "hostUuid", "url" @@ -565,7 +605,7 @@ { "raw": "cannot find devicePath on host: %s", "en_US": "cannot find devicePath on host: {0}", - "zh_CN": "", + "zh_CN": "在物理机上找不到DevicePath:{0}", "arguments": [ "hostUuid" ], @@ -575,7 +615,7 @@ { "raw": "invalid snapshot install path: %s", "en_US": "invalid snapshot install path: {0}", - "zh_CN": "", + "zh_CN": "快照安装路径无效:{0}", "arguments": [ "installPath" ], @@ -610,7 +650,18 @@ "en_US": "No Available instance types now.", "zh_CN": "没有可用的实例类型", "arguments": [], - "line": 181, + "line": 184, + "fileName": "src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java" + }, + { + "raw": "This region [%s] cannot produce instance type [%s] now, please select another instance type or another region", + "en_US": "This region [{0}] cannot produce instance type [{1}] now, please select another instance type or another region", + "zh_CN": "此地区[{0}]现在无法生成实例类型[{1}],请选择其他实例类型或其他地区", + "arguments": [ + "regionId", + "data1.get(\"type\")" + ], + "line": 253, "fileName": "src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java" }, { @@ -621,7 +672,7 @@ "ecs.getUuid()", "ecs.getEcsInstanceId()" ], - "line": 304, + "line": 344, "fileName": "src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java" }, { @@ -728,24 +779,24 @@ "arguments": [ "rly1.getVncUrl()" ], - "line": 384, + "line": 517, "fileName": "src/main/java/org/zstack/aliyun/ecs/EcsInstanceManagerImpl.java" }, { "raw": "image has been deleted!", "en_US": "image has been deleted!", - "zh_CN": "", + "zh_CN": "图像已删除!", "arguments": [], "line": 52, "fileName": "src/main/java/org/zstack/aliyun/ecs/ExportImageFromBSFlow.java" }, { - "raw": "no identity chosen, may be stock problems", - "en_US": "no identity chosen, may be stock problems", - "zh_CN": "没有可用区选择,可能是存储问题", + "raw": "no identity found", + "en_US": "no identity found", + "zh_CN": "找不到身份", "arguments": [], - "line": 50, - "fileName": "src/main/java/org/zstack/aliyun/identityzone/SelectValidIdentityZoneFlow.java" + "line": 187, + "fileName": "src/main/java/org/zstack/aliyun/identityzone/AliyunIdentityZoneBase.java" }, { "raw": "the operation only custom image", @@ -774,7 +825,7 @@ { "raw": "Only support ImageStoreBackupStorage", "en_US": "Only support ImageStoreBackupStorage", - "zh_CN": "用本地镜像创建阿里云上的镜像只支持ImageStore镜像存储", + "zh_CN": "用本地镜像创建阿里云上的镜像只支持ImageStore镜像服务器", "arguments": [], "line": 142, "fileName": "src/main/java/org/zstack/aliyun/image/EcsImageApiInterceptor.java" @@ -852,7 +903,7 @@ { "raw": "PrimaryStorage [%s] still running, can not delete access group", "en_US": "PrimaryStorage [{0}] still running, can not delete access group", - "zh_CN": "", + "zh_CN": "PrimaryStorage[{0}]仍在运行,无法删除访问组", "arguments": [ "psUuids.toString()" ], @@ -862,7 +913,7 @@ { "raw": "access group rule [%s] already existed in access group [%s]", "en_US": "access group rule [{0}] already existed in access group [{1}]", - "zh_CN": "", + "zh_CN": "访问组规则[{0}]已存在于访问组[{1}]中", "arguments": [ "msg.getSourceCidrIp()", "msg.getAccessGroupUuid()" @@ -873,7 +924,7 @@ { "raw": "access group [%s] already existed in datacenter [%s]", "en_US": "access group [{0}] already existed in datacenter [{1}]", - "zh_CN": "", + "zh_CN": "数据中心[{1}]中已存在访问组[{0}]", "arguments": [ "msg.getName()", "msg.getDataCenterUuid()" @@ -884,7 +935,7 @@ { "raw": "no filesystem [%s] found in region: %s", "en_US": "no filesystem [{0}] found in region: {1}", - "zh_CN": "", + "zh_CN": "在数据中心{1}中找不到文件系统[{0}]", "arguments": [ "self.getFileSystemId()", "regionId" @@ -895,7 +946,7 @@ { "raw": "nas filesystem existed in datacenter: %s", "en_US": "nas filesystem existed in datacenter: {0}", - "zh_CN": "", + "zh_CN": "NAS文件系统存在于数据中心:{0}", "arguments": [ "msg.getDataCenterUuid()" ], @@ -905,7 +956,7 @@ { "raw": "some primary storage [%s] used this nas, can not delete it until delete the primary storage.", "en_US": "some primary storage [{0}] used this nas, can not delete it until delete the primary storage.", - "zh_CN": "", + "zh_CN": "某个主存储[{0}]使用了此NAS,在删除主存储之前无法将其删除。", "arguments": [ "refs.toString()" ], @@ -915,7 +966,7 @@ { "raw": "mount domain not valid after %d milliseconds, delete it...", "en_US": "mount domain not valid after {0} milliseconds, delete it...", - "zh_CN": "", + "zh_CN": "装载域在{0}毫秒后无效,请将其删除..", "arguments": [ "cmsg.getWait()" ], @@ -925,7 +976,7 @@ { "raw": "there are no nas access group existed, please create at least one", "en_US": "there are no nas access group existed, please create at least one", - "zh_CN": "", + "zh_CN": "不存在NAS访问组,请至少创建一个", "arguments": [], "line": 422, "fileName": "src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java" @@ -933,7 +984,7 @@ { "raw": "no such mount target [%s] in nas: %s", "en_US": "no such mount target [{0}] in nas: {1}", - "zh_CN": "", + "zh_CN": "NAS中没有这样的装载目标[{0}]:{1}", "arguments": [ "self.getMountDomain()", "self.getNasFileSystemUuid()" @@ -944,7 +995,7 @@ { "raw": "nas mount target [%s] existed in filesystem: %s", "en_US": "nas mount target [{0}] existed in filesystem: {1}", - "zh_CN": "", + "zh_CN": "文件系统{1}中存在NAS装载目标[{0}]", "arguments": [ "msg.getMountDomain()", "msg.getNasFSUuid()" @@ -955,107 +1006,107 @@ { "raw": "the access group attached is already: %s", "en_US": "the access group attached is already: {0}", - "zh_CN": "", + "zh_CN": "附加的访问组已为:{0}", "arguments": [ "self.getAccessGroupUuid()" ], "line": 512, "fileName": "src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java" }, + { + "raw": "image [uuid:%s] has been deleted", + "en_US": "image [uuid:{0}] has been deleted", + "zh_CN": "镜像[uuid:{0}]已经被删除", + "arguments": [ + "imageVO.getUuid()" + ], + "line": 2907, + "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" + }, { "raw": "EcsVSwitchVO[%s] is not existed, may be it has been deleted!", "en_US": "EcsVSwitchVO[{0}] is not existed, may be it has been deleted!", - "zh_CN": "", + "zh_CN": "ECSVSwitchVO[{0}]不存在,可能已被删除!", "arguments": [ "vSwitchUuid" ], - "line": 534, + "line": 535, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "AliyunNasAccessGroupVO[%s] is not existed, may be it has been deleted!", "en_US": "AliyunNasAccessGroupVO[{0}] is not existed, may be it has been deleted!", - "zh_CN": "", + "zh_CN": "AliyunNASAccessGroupVO[{0}]不存在,可能已被删除!", "arguments": [ "accessGroupUuid" ], - "line": 527, + "line": 528, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "cannot find an available host to operation in primary storage: %s", "en_US": "cannot find an available host to operation in primary storage: {0}", - "zh_CN": "", + "zh_CN": "在主存储中找不到可用于操作的物理机:{0}", "arguments": [ "self.getUuid()" ], - "line": 826, + "line": 827, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "failed to ping aliyun nas primary storage[uuid:%s] from host[uuid:%s],because %s. disconnect this host-ps connection", "en_US": "failed to ping aliyun nas primary storage[uuid:{0}] from host[uuid:{1}],because {2}. disconnect this host-ps connection", - "zh_CN": "", + "zh_CN": "无法从物理机[uuid:{1}]Ping Aliyun NAS主存储[uuid:{0}],因为{2}。断开此物理机-PS连接", "arguments": [ "self.getUuid()", "hostUuid", "rsp.error" ], - "line": 905, + "line": 906, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "nas primary storage not mounted, please init it first!", "en_US": "nas primary storage not mounted, please init it first!", - "zh_CN": "", + "zh_CN": "NAS主存储未装载,请先将其初始化!", "arguments": [], - "line": 1393, - "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" - }, - { - "raw": "cannot find any BackupStorageKvmFactory for the type[%s]", - "en_US": "cannot find any BackupStorageKvmFactory for the type[{0}]", - "zh_CN": "", - "arguments": [ - "bsType" - ], - "line": 1577, + "line": 1394, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "cannot find host to operate volume: [%s]", "en_US": "cannot find host to operate volume: [{0}]", - "zh_CN": "", + "zh_CN": "找不到操作卷[{0}]的物理机", "arguments": [ "vol.getUuid()" ], - "line": 2003, + "line": 2004, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "cannot find and host to sync volume size in primary: %s", "en_US": "cannot find and host to sync volume size in primary: {0}", - "zh_CN": "", + "zh_CN": "在主节点中找不到要同步卷大小的物理机:{0}", "arguments": [ "self.getUuid()" ], - "line": 2240, + "line": 2241, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "image [%s] has been deleted, cannot reinit root volume from it", "en_US": "image [{0}] has been deleted, cannot reinit root volume from it", - "zh_CN": "", + "zh_CN": "镜像[{0}]已删除,无法从中重新初始化根卷", "arguments": [], - "line": 2267, + "line": 2268, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "no available host could check mountPath!", "en_US": "no available host could check mountPath!", - "zh_CN": "", + "zh_CN": "没有可用的物理机可以检查装载路径!", "arguments": [], - "line": 2422, + "line": 2423, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { @@ -1066,17 +1117,17 @@ "String.join(\",\", msg.getBackupStorageUuids())", "errorCodes.getCauses().get(0).getDetails()" ], - "line": 2649, + "line": 2653, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { "raw": "aliyun nas primarystorage only support imagestore bs, actually get type: %s", "en_US": "aliyun nas primarystorage only support imagestore bs, actually get type: {0}", - "zh_CN": "", + "zh_CN": "阿里云NAS PrimaryStorage仅支持ImageStore BS,实际获取类型:{0}", "arguments": [ "bsvo.getType()" ], - "line": 2817, + "line": 2795, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java" }, { @@ -1092,66 +1143,76 @@ "QCOW3_QEMU_IMG_VERSION", "QCOW3_QEMU_IMG_VERSION" ], - "line": 158, + "line": 161, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java" }, { "raw": "no available host could download imagecache!", "en_US": "no available host could download imagecache!", - "zh_CN": "", + "zh_CN": "没有可用的物理机可以下载ImageCache!", "arguments": [], - "line": 342, + "line": 344, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java" }, + { + "raw": "resource[uuid: %s] cannot found", + "en_US": "resource[uuid: {0}] cannot found", + "zh_CN": "找不到资源[uuid:{0}]", + "arguments": [ + "msg.getResourceUuid()" + ], + "line": 1147, + "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java" + }, { "raw": "the aliyun nas primary storage[uuid:%s, name:%s] cannot find any available host in attached clusters for instantiating the volume", "en_US": "the aliyun nas primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume", - "zh_CN": "", + "zh_CN": "Aliyun NAS主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机", "arguments": [ "self.getUuid()", "self.getName()" ], - "line": 69, + "line": 75, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java" }, { "raw": "the aliyun nas primary storage[uuid:%s, name:%s] cannot find any available host in attached clusters for delete bits on primarystorage", "en_US": "the aliyun nas primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for delete bits on primarystorage", - "zh_CN": "", + "zh_CN": "Aliyun NAS主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于主存储删除位的物理机", "arguments": [ "self.getUuid()", "self.getName()" ], - "line": 192, + "line": 208, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java" }, { "raw": "the Aliyun Nas primary storage[uuid:%s, name:%s] has not attached to any clusters, or no hosts in the attached clusters are connected", "en_US": "the Aliyun Nas primary storage[uuid:{0}, name:{1}] has not attached to any clusters, or no hosts in the attached clusters are connected", - "zh_CN": "", + "zh_CN": "阿里云NAS主存储[uuid:{0},名称:{1}]未挂接任何集群,或挂接的集群中没有物理机", "arguments": [ "self.getUuid()", "self.getName()" ], - "line": 555, + "line": 619, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java" }, { "raw": "failed to check mount path on host: %s", "en_US": "failed to check mount path on host: {0}", - "zh_CN": "", + "zh_CN": "无法检查物理机上的装载路径:{0}", "arguments": [ "hostUuid" ], - "line": 856, + "line": 936, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java" }, { "raw": "cannot find a host to cleanup image cache.", "en_US": "cannot find a host to cleanup image cache.", - "zh_CN": "", + "zh_CN": "找不到用于清除镜像缓存的物理机。", "arguments": [], - "line": 943, + "line": 1023, "fileName": "src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java" }, { @@ -1248,7 +1309,7 @@ "arguments": [ "msg.getL3networkUuid()" ], - "line": 50, + "line": 51, "fileName": "src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java" }, { @@ -1258,7 +1319,7 @@ "arguments": [ "msg.getL3networkUuid()" ], - "line": 40, + "line": 42, "fileName": "src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java" }, { @@ -1380,7 +1441,7 @@ { "raw": "domain, key, secret must be set all", "en_US": "domain, key, secret must be set all", - "zh_CN": "", + "zh_CN": "域、密钥、机密必须全部设置", "arguments": [], "line": 114, "fileName": "src/main/java/org/zstack/aliyun/oss/EcsOssManagerImpl.java" @@ -1390,13 +1451,13 @@ "en_US": "oss bucket is not empty!", "zh_CN": "oss Bucket不为空", "arguments": [], - "line": 106, + "line": 107, "fileName": "src/main/java/org/zstack/aliyun/oss/OssBucketCascadeExtension.java" }, { "raw": "appName: %s, partitionName: %s is existed in identityZone: %s", "en_US": "appName: {0}, partitionName: {1} is existed in identityZone: {2}", - "zh_CN": "", + "zh_CN": "AppName:{0},PartitionName:{1}存在于IdentityZone:{2}中", "arguments": [ "appName", "partitionName", @@ -1408,7 +1469,7 @@ { "raw": "Root volume cannot be deleted", "en_US": "Root volume cannot be deleted", - "zh_CN": "根云盘不能被删除", + "zh_CN": "云盘不能被删除", "arguments": [], "line": 62, "fileName": "src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java" @@ -1452,7 +1513,7 @@ { "raw": "Only data disk can be mounted on ecs", "en_US": "Only data disk can be mounted on ecs", - "zh_CN": "只有数据云盘可以挂装到云主机上", + "zh_CN": "只有云盘可以挂装到云主机上", "arguments": [], "line": 105, "fileName": "src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java" @@ -1495,7 +1556,7 @@ { "raw": "Only data disk can attach to ecs", "en_US": "Only data disk can attach to ecs", - "zh_CN": "只有数据云盘能加载到云服务器", + "zh_CN": "只有云盘能加载到云服务器", "arguments": [], "line": 135, "fileName": "src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java" @@ -1519,7 +1580,7 @@ { "raw": "Not allowed create disk on root volume snapshot", "en_US": "Not allowed create disk on root volume snapshot", - "zh_CN": "不允许在根云盘快照上创建云盘", + "zh_CN": "不允许在云盘快照上创建云盘", "arguments": [], "line": 167, "fileName": "src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java" @@ -1543,7 +1604,7 @@ { "raw": "More than one BackupStorage on the same host identified by hostname. There has been a SftpBackupStorage [hostname:%s] existing. The BackupStorage type to be added is %s. ", "en_US": "More than one BackupStorage on the same host identified by hostname. There has been a SftpBackupStorage [hostname:{0}] existing. The BackupStorage type to be added is {1}. ", - "zh_CN": "有超过一个镜像服务器拥有相同的主机名,已经存在一个 SFTP 镜像服务器 [主机名:{0}],被添加的镜像存储类型为 {1}", + "zh_CN": "有超过一个镜像服务器拥有相同的物理机名,已经存在一个 SFTP 镜像服务器 [物理机名:{0}],被添加的镜像服务器类型为 {1}", "arguments": [ "hostname", "newBS" @@ -1554,7 +1615,7 @@ { "raw": "More than one BackupStorage on the same host identified by hostname. There has been an ImageStoreBackupStorage [hostname:%s] existing. The BackupStorage type to be added is %s. ", "en_US": "More than one BackupStorage on the same host identified by hostname. There has been an ImageStoreBackupStorage [hostname:{0}] existing. The BackupStorage type to be added is {1}. ", - "zh_CN": "有超过一个镜像服务器拥有相同的主机名,已经存在一个镜像服务器 [主机名:{0}],被添加的镜像存储类型为 {1}", + "zh_CN": "有超过一个镜像服务器拥有相同的物理机名,已经存在一个镜像服务器 [物理机名:{0}],被添加的镜像服务器类型为 {1}", "arguments": [ "hostname", "newBS" @@ -1563,590 +1624,835 @@ "fileName": "src/main/java/org/zstack/apimediator/ApiValidator.java" }, { - "raw": "appliance vm[uuid:%s] is in status of %s that cannot make http call to %s", - "en_US": "appliance vm[uuid:{0}] is in status of {1} that cannot make http call to {2}", - "zh_CN": "系统虚拟机[uuid:{0}]处于{1}状态,无法对[{2}]执行HTTP RPC调用", + "raw": "PublishAppVO[uuid: %s] is not existed", + "en_US": "PublishAppVO[uuid: {0}] is not existed", + "zh_CN": "PublishAppVO[uuid:{0}]不存在", "arguments": [ - "self.getUuid()", - "getSelf().getStatus()", - "msg.getPath()" + "msg.getAppUuid()" ], - "line": 129, - "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" + "line": 486, + "fileName": "src/main/java/org/zstack/appcenter/AppCenterManagerImpl.java" }, { - "raw": "appliance vm %s stopped", - "en_US": "appliance vm {0} stopped", - "zh_CN": "", - "arguments": [ - "getSelf().getUuid()" - ], - "line": 413, - "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" + "raw": "[appcenter] filterName must be appcenter:true or appcenter:false", + "en_US": "[appcenter] filterName must be appcenter:true or appcenter:false", + "zh_CN": "[appCenter]FilterName必须为appCenter:true或appCenter:false", + "arguments": [], + "line": 588, + "fileName": "src/main/java/org/zstack/appcenter/AppCenterManagerImpl.java" }, { - "raw": "appliance vm %s destroyed", - "en_US": "appliance vm {0} destroyed", - "zh_CN": "", + "raw": "%s is in preParameters, but not be set", + "en_US": "{0} is in preParameters, but not be set", + "zh_CN": "{0}在前参数中,但未设置", "arguments": [ - "getSelf().getUuid()" + "struct.getParamName()" ], - "line": 482, - "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" + "line": 127, + "fileName": "src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java" }, { - "raw": "appliance vm %s reboot", - "en_US": "appliance vm {0} reboot", - "zh_CN": "", - "arguments": [ - "getSelf().getUuid()" - ], - "line": 543, - "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" + "raw": "%s need Number value, but got wrong type", + "en_US": "{0} need Number value, but got wrong type", + "zh_CN": "{0}需要数值,但类型错误", + "arguments": [], + "line": 131, + "fileName": "src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java" }, { - "raw": "appliance vm %s reboot failed", - "en_US": "appliance vm {0} reboot failed", - "zh_CN": "", - "arguments": [ - "getSelf().getUuid()" - ], - "line": 553, - "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" + "raw": "%s need Boolean value, but got wrong type", + "en_US": "{0} need Boolean value, but got wrong type", + "zh_CN": "{0}需要布尔值,但类型错误", + "arguments": [], + "line": 136, + "fileName": "src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java" }, { - "raw": "appliance vm %s start failed", - "en_US": "appliance vm {0} start failed", - "zh_CN": "", - "arguments": [ - "getSelf().getUuid()" - ], - "line": 606, - "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" + "raw": "%s need String value, but got wrong type", + "en_US": "{0} need String value, but got wrong type", + "zh_CN": "{0}需要字符串值,但获取的类型错误", + "arguments": [], + "line": 141, + "fileName": "src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java" }, { - "raw": "listener[uuid:%s] are being used by the autoScalingVmTemplate[%s] and cannot be deleted", - "en_US": "listener[uuid:{0}] are being used by the autoScalingVmTemplate[{1}] and cannot be deleted", - "zh_CN": "", + "raw": "cannot find build system [%s]", + "en_US": "cannot find build system [{0}]", + "zh_CN": "找不到生成系统[{0}]", "arguments": [ - "msg.getUuid()", - "uuid" + "msg.getBuildSystemUuid()" ], - "line": 116, - "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" + "line": 389, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "alarm[uuid:%s] are being used by the autoScalingGroup[%s] which cannot be deleted", - "en_US": "alarm[uuid:{0}] are being used by the autoScalingGroup[{1}] which cannot be deleted", - "zh_CN": "", + "raw": "build system[uuid: %s] has been attached to zone[uuid: %s]", + "en_US": "build system[uuid: {0}] has been attached to zone[uuid: {1}]", + "zh_CN": "生成系统[uuid:{0}]已附加到区域[uuid:{1}]", "arguments": [ - "msg.getAlarmUuid()", - "ruleVO.getScalingGroupUuid()" + "msg.getBuildSystemUuid()", + "msg.getZoneUuid()" ], - "line": 148, - "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" + "line": 339, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "rule[%s] state is Disabled", - "en_US": "rule[{0}] state is Disabled", - "zh_CN": "", + "raw": "build system[uuid: %s] has not been attached to zone[uuid: %s]", + "en_US": "build system[uuid: {0}] has not been attached to zone[uuid: {1}]", + "zh_CN": "生成系统[uuid:{0}]尚未附加到区域[uuid:{1}]", "arguments": [ - "msg.getUuid()" + "msg.getBuildSystemUuid()", + "msg.getZoneUuid()" ], - "line": 158, - "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" + "line": 396, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "invalid l3 network uuids[%s] for listener that belongs lb[%s], all the networks must be attached the LB service and be attached with the same vRouter with LB", - "en_US": "invalid l3 network uuids[{0}] for listener that belongs lb[{1}], all the networks must be attached the LB service and be attached with the same vRouter with LB", - "zh_CN": "", + "raw": "cannot find build application: [%s]", + "en_US": "cannot find build application: [{0}]", + "zh_CN": "找不到生成应用程序:[{0}]", "arguments": [ - "l3Uuids", - "uuid" + "appUuid" ], - "line": 314, - "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java" + "line": 620, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "detach autoScalingTemplate[%s] from AutoScalingGroup failed, errors are %s", - "en_US": "detach autoScalingTemplate[{0}] from AutoScalingGroup failed, errors are {1}", - "zh_CN": "", - "arguments": [ - "msg.getTemplateUuid()", - "JSONObjectUtil.toJsonString(errors)" - ], - "line": 626, - "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java" + "raw": "imageStore is not Enabled", + "en_US": "imageStore is not Enabled", + "zh_CN": "未启用ImageStore", + "arguments": [], + "line": 989, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "rootDiskOfferingUuid cannot be null when image mediaType is ISO", - "en_US": "rootDiskOfferingUuid cannot be null when image mediaType is ISO", - "zh_CN": "根云盘规格不能为空在镜像类型为ISO时", + "raw": "imageStore is not Connected", + "en_US": "imageStore is not Connected", + "zh_CN": "ImageStore未连接", "arguments": [], - "line": 933, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 993, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "instance offering[uuid:%s] is Disabled, can\u0027t create vm from it", - "en_US": "instance offering[uuid:{0}] is Disabled, can\u0027t create vm from it", - "zh_CN": "计算规格[uuid:{0}]没有被启用,不能根据该规格创建云主机", + "raw": "cannot find imageUuid for image[%s]", + "en_US": "cannot find imageUuid for image[{0}]", + "zh_CN": "找不到镜像[{0}]的ImageUuid", "arguments": [ - "instanceOfferingVO.getUuid()" + "p.getDefaultValue()" ], - "line": 913, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 1147, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "instance offering[uuid:%s, type:%s] is not UserVm type, can\u0027t create vm from it", - "en_US": "instance offering[uuid:{0}, type:{1}] is not UserVm type, can\u0027t create vm from it", - "zh_CN": "计算规格[uuid:{0}, type:{1}]不是UserVm类型,不能通过它创建虚拟机", + "raw": "cannot find build-app[uuid: %s], or it was in Deleting status", + "en_US": "cannot find build-app[uuid: {0}], or it was in Deleting status", + "zh_CN": "找不到Build-App[uuid:{0}],或者它处于删除状态", "arguments": [ - "instanceOfferingVO.getUuid()", - "instanceOfferingVO.getType()" + "msg.getUuid()" ], - "line": 916, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 1159, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java" }, { - "raw": "image[uuid:%s] is Disabled, can\u0027t create vm from it", - "en_US": "image[uuid:{0}] is Disabled, can\u0027t create vm from it", - "zh_CN": "镜像[uuid:{0}]没被启用,不能根据该镜像创建云主机", + "raw": "build-app[%s] is exported or is exporting, please delete it first", + "en_US": "build-app[{0}] is exported or is exporting, please delete it first", + "zh_CN": "Build-App[{0}]已导出或正在导出,请先删除它", "arguments": [ - "imageVO.getUuid()" + "msg.getUuid()" ], - "line": 924, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 50, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "image[uuid:%s] is not ready yet, can\u0027t create vm from it", - "en_US": "image[uuid:{0}] is not ready yet, can\u0027t create vm from it", - "zh_CN": "", + "raw": "another build system[uuid: %s, name: %s] in this host[%s] used the url[%s]", + "en_US": "another build system[uuid: {0}, name: {1}] in this host[{2}] used the url[{3}]", + "zh_CN": "此物理机[{2}]中的另一个生成系统[uuid:{0},名称:{1}]使用了URL[{3}]", "arguments": [ - "imageVO.getUuid()" + "build.getUuid()", + "build.getName()", + "build.getHostname()", + "build.getUrl()" ], - "line": 927, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 63, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "image[uuid:%s] is of mediaType: %s, only RootVolumeTemplate and ISO can be used to create vm", - "en_US": "image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate and ISO can be used to create vm", - "zh_CN": "镜像[uuid:{0}] 类型为{1},只能用RootVolumeTemplate和ISO来创建云主机", + "raw": "dataPath must start with \u0027/\u0027, actually got [%s]", + "en_US": "dataPath must start with \u0027/\u0027, actually got [{0}]", + "zh_CN": "数据路径必须以“/”开头,实际获得[{0}]", "arguments": [ - "imageVO.getUuid()", - "imageVO.getMediaType()" + "msg.getDataPath()" ], - "line": 930, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 74, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "image[uuid:%s] is system image, can\u0027t be used to create user vm", - "en_US": "image[uuid:{0}] is system image, can\u0027t be used to create user vm", - "zh_CN": "镜像[uuid:{0}] 是系统镜像,不能使用它创建用户虚拟机", - "arguments": [ - "imageVO.getUuid()" - ], - "line": 937, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "raw": "both backupStorageUuid and hostname are null", + "en_US": "both backupStorageUuid and hostname are null", + "zh_CN": "backupStorageUuid和hostname均为空", + "arguments": [], + "line": 88, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "disk offerings[uuids:%s] are Disabled, can not create vm from it", - "en_US": "disk offerings[uuids:{0}] are Disabled, can not create vm from it", - "zh_CN": "云盘规格[uuids:{0}]没有被启用,不能使用它创建云主机", + "raw": "cannot find imageStore which hostname is :%s", + "en_US": "cannot find imageStore which hostname is :{0}", + "zh_CN": "找不到物理机名为{0}的ImageStore", "arguments": [ - "diskOfferingVO.getUuid()" + "msg.getHostname()" ], - "line": 949, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 95, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "l3Network[uuid:%s] is Disabled, can not create vm on it", - "en_US": "l3Network[uuid:{0}] is Disabled, can not create vm on it", - "zh_CN": "L3网络[uuid:{0}]没有被启用,不能从这个L3网络创建云主机", + "raw": "find more than one imageStore which hostname is: %s, please use backupStorageUuid instead", + "en_US": "find more than one imageStore which hostname is: {0}, please use backupStorageUuid instead", + "zh_CN": "找到多个物理机名为{0}的ImageStore,请改用BackupStorageUuid", "arguments": [ - "l3Uuid" + "msg.getHostname()" ], - "line": 963, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 98, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "l3Network[uuid:%s] is system network, can not create user vm on it", - "en_US": "l3Network[uuid:{0}] is system network, can not create user vm on it", - "zh_CN": "L3网络[uuid:{0}]是系统网络,不能在这上面创建云主机", - "arguments": [ - "l3Uuid" - ], - "line": 966, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "raw": "both backupStorageUuid and hostname are set, but they are not the same host", + "en_US": "both backupStorageUuid and hostname are set, but they are not the same host", + "zh_CN": "同时设置了backupStorageuuid和hostname,但它们不是同一物理机", + "arguments": [], + "line": 102, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null", - "en_US": "there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null", - "zh_CN": "在L3网络uuid们中有很多L3网络被指定了,但是默认L3网络的uuid是空的", + "raw": "buildAppUuid and exportId cannot both be null", + "en_US": "buildAppUuid and exportId cannot both be null", + "zh_CN": "BuildAppuuid和ExportId不能同时为空", "arguments": [], - "line": 970, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 116, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "Only one scaling activity can be executed in the same scaling group at the same time.", - "en_US": "Only one scaling activity can be executed in the same scaling group at the same time.", - "zh_CN": "", + "raw": "buildAppUuid and buildSystemUuid cannot both be null", + "en_US": "buildAppUuid and buildSystemUuid cannot both be null", + "zh_CN": "BuildAppUuid和BuildSystemUuid不能同时为空", "arguments": [], - "line": 409, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 120, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "The number of instances exceeds the limit", - "en_US": "The number of instances exceeds the limit", - "zh_CN": "", + "raw": "no such exportId in build export history", + "en_US": "no such exportId in build export history", + "zh_CN": "在生成导出历史记录中没有这样的导出ID", "arguments": [], - "line": 1330, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 126, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" }, { - "raw": "autoScalingGroup[%s] create vms failed completely, errors are %s", - "en_US": "autoScalingGroup[{0}] create vms failed completely, errors are {1}", - "zh_CN": "", + "raw": "both exportId and buildAppUuid are set but they are not equal", + "en_US": "both exportId and buildAppUuid are set but they are not equal", + "zh_CN": "同时设置了ExportId和BuildAppUuid,但它们不相等", + "arguments": [], + "line": 130, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java" + }, + { + "raw": "unable to do the operation because the build system is in status of %s", + "en_US": "unable to do the operation because the build system is in status of {0}", + "zh_CN": "无法执行该操作,因为生成系统处于{0}状态", "arguments": [ - "msg.getAutoScalingGroupUuid()", - "JSONObjectUtil.toJsonString(errors)" + "self.getStatus()" ], - "line": 637, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 108, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "add vm nic to loadBalancer failed, No loadBalancer[uuids\u003d%s] can be found.", - "en_US": "add vm nic to loadBalancer failed, No loadBalancer[uuids\u003d{0}] can be found.", - "zh_CN": "", + "raw": "cannot find the build app by uuid[%s]", + "en_US": "cannot find the build app by uuid[{0}]", + "zh_CN": "按uuid[{0}]找不到生成应用程序", "arguments": [ - "loadBalancerListenerUuidListStr" + "msg.getBuildAppUuid()" ], - "line": 685, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 121, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "autoScalingGroup[%s] add newly created vm to loadBalancer failed completely, errors are %s", - "en_US": "autoScalingGroup[{0}] add newly created vm to loadBalancer failed completely, errors are {1}", - "zh_CN": "", + "raw": "build app is in %s status, which can not support the current operation.", + "en_US": "build app is in {0} status, which can not support the current operation.", + "zh_CN": "生成应用程序处于{0}状态,无法支持当前操作。", "arguments": [ - "msg.getAutoScalingGroupUuid()", - "JSONObjectUtil.toJsonString(addVmNicToLoadBalancerErrorCodes)" + "status.toString()" ], - "line": 724, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 126, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "add vm nic to securityGroup failed, No securityGroup[uuid\u003d%s] can be found.", - "en_US": "add vm nic to securityGroup failed, No securityGroup[uuid\u003d{0}] can be found.", - "zh_CN": "", + "raw": "rest call %s failed, because: %s", + "en_US": "rest call {0} failed, because: {1}", + "zh_CN": "REST调用{0}失败,因为:{1}", "arguments": [ - "securityGroupUuid" + "buildUrl(path)", + "rsp.error" ], - "line": 759, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 156, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "autoScalingGroup[%s] add newly created vm to securityGroup failed completely, errors are %s", - "en_US": "autoScalingGroup[{0}] add newly created vm to securityGroup failed completely, errors are {1}", - "zh_CN": "", + "raw": "build application is disabled because build system is in \u0027Disabled\u0027 state", + "en_US": "build application is disabled because build system is in \u0027Disabled\u0027 state", + "zh_CN": "生成应用程序已禁用,因为生成系统处于“禁用”状态", + "arguments": [], + "line": 353, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" + }, + { + "raw": "create BuildApp failed, because appId[%s: %s] is duplicated by another BuildApp", + "en_US": "create BuildApp failed, because appId[{0}: {1}] is duplicated by another BuildApp", + "zh_CN": "创建BuildApp失败,因为AppId[{0}:{1}]与另一个BuildApp重复", "arguments": [ - "msg.getAutoScalingGroupUuid()", - "JSONObjectUtil.toJsonString(addVmNicToSecurityGroupErrorCodes)" + "meta.getAppId()", + "meta.getVersion().getVersion()" ], - "line": 795, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 506, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "A resource can not be found, details: resource[uuid:%s, type:AutoScalingVmTemplateVO] not found", - "en_US": "A resource can not be found, details: resource[uuid:{0}, type:AutoScalingVmTemplateVO] not found", - "zh_CN": "", + "raw": "unable to connect to localstorage build system[url:%s], because %s", + "en_US": "unable to connect to localstorage build system[url:{0}], because {1}", + "zh_CN": "无法连接到localStorage生成系统[URL:{0}],因为{1}", "arguments": [ - "templateGroupRefVO.getTemplateUuid()" + "buildUrl(CONNECT_BUILDSYSTEM_PATH)", + "errorCode" ], - "line": 905, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 659, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "A resource can not be found, details: resource[uuid:%s, type:InstanceOfferingVO] not found", - "en_US": "A resource can not be found, details: resource[uuid:{0}, type:InstanceOfferingVO] not found", - "zh_CN": "", + "raw": "add BuildApp failed, because appId[%s:%s] is duplicated by another BuildApp", + "en_US": "add BuildApp failed, because appId[{0}:{1}] is duplicated by another BuildApp", + "zh_CN": "添加BuildApp失败,因为AppId[{0}:{1}]与另一个BuildApp重复", "arguments": [ - "vmTemplateVO.getVmInstanceOfferingUuid()" + "struct.getAppId()", + "struct.getVersion().getVersion()" ], - "line": 910, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 762, + "fileName": "src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java" }, { - "raw": "A resource can not be found, details: resource[uuid:%s, type:ImageVO] not found", - "en_US": "A resource can not be found, details: resource[uuid:{0}, type:ImageVO] not found", - "zh_CN": "", + "raw": "cannot find raw-template json file at: %s", + "en_US": "cannot find raw-template json file at: {0}", + "zh_CN": "在{0}处找不到原始模板JSON文件", "arguments": [ - "vmTemplateVO.getImageUuid()" + "file" ], - "line": 921, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 48, + "fileName": "src/main/java/org/zstack/appcenter/utils/AppCenterUtils.java" }, { - "raw": "A resource can not be found, details: resource[uuid:%s, type:DiskOfferingVO] not found", - "en_US": "A resource can not be found, details: resource[uuid:{0}, type:DiskOfferingVO] not found", - "zh_CN": "", + "raw": "Unable to create json template", + "en_US": "Unable to create json template", + "zh_CN": "无法创建JSON模板", "arguments": [ - "diskOfferingVO.getUuid()" + "e" ], - "line": 945, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 61, + "fileName": "src/main/java/org/zstack/appcenter/utils/AppCenterUtils.java" }, { - "raw": "A resource can not be found, details: resource[uuid:%s, type:L3NetworkVO] not found", - "en_US": "A resource can not be found, details: resource[uuid:{0}, type:L3NetworkVO] not found", - "zh_CN": "", + "raw": "there is no available nicType on L2 network [%s]", + "en_US": "there is no available nicType on L2 network [{0}]", + "zh_CN": "二层网络[{0}]上没有可用的nicType", "arguments": [ - "l3Uuid" + "l2NetworkVO.getUuid()" ], - "line": 958, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 108, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java" }, { - "raw": "defaultL3NetworkUuid[uuid:%s] is not in l3NetworkUuids %s", - "en_US": "defaultL3NetworkUuid[uuid:{0}] is not in l3NetworkUuids {1}", - "zh_CN": "", + "raw": "appliance vm[uuid:%s] is in status of %s that cannot make http call to %s", + "en_US": "appliance vm[uuid:{0}] is in status of {1} that cannot make http call to {2}", + "zh_CN": "系统云主机[uuid:{0}]处于{1}状态,无法对[{2}]执行HTTP RPC调用", "arguments": [ - "vmTemplateVO.getDefaultL3NetworkUuid()", - "l3Uuids" + "self.getUuid()", + "getSelf().getStatus()", + "msg.getPath()" ], - "line": 974, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 136, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" }, { - "raw": "the auto scaling group[%s] state error, expected: %s state", - "en_US": "the auto scaling group[{0}] state error, expected: {1} state", - "zh_CN": "", + "raw": "appliance vm %s stopped", + "en_US": "appliance vm {0} stopped", + "zh_CN": "应用装置VM{0}已停止", "arguments": [ - "self.getUuid()", - "AutoScalingGroupState.Enabled.toString()" + "getSelf().getUuid()" ], - "line": 1047, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 430, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" }, { - "raw": "The autoScalingGroup[%s] not attach any vm template", - "en_US": "The autoScalingGroup[{0}] not attach any vm template", - "zh_CN": "", + "raw": "appliance vm %s reboot", + "en_US": "appliance vm {0} reboot", + "zh_CN": "应用装置云主机{0}重新启动", "arguments": [ - "self.getUuid()" + "getSelf().getUuid()" ], - "line": 1084, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 709, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" }, { - "raw": "autoScalingGroup[%s] destroy vms[%s] failed completely, errors are %s", - "en_US": "autoScalingGroup[{0}] destroy vms[{1}] failed completely, errors are {2}", - "zh_CN": "", + "raw": "appliance vm %s reboot failed", + "en_US": "appliance vm {0} reboot failed", + "zh_CN": "应用装置云主机{0}重新启动失败", "arguments": [ - "self.getUuid()", - "vmInstanceUuids", - "JSONObjectUtil.toJsonString(errors)" + "getSelf().getUuid()" ], - "line": 1138, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" - }, - { - "raw": "Cannot find deleted target instance list", - "en_US": "Cannot find deleted target instance list", - "zh_CN": "", - "arguments": [], - "line": 1343, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" - }, - { - "raw": "need skip autoScalingGroup activity", - "en_US": "need skip autoScalingGroup activity", - "zh_CN": "", - "arguments": [], - "line": 1569, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 719, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" }, { - "raw": "delete autoScalingRule[%s] triggers failed, errors are %s", - "en_US": "delete autoScalingRule[{0}] triggers failed, errors are {1}", - "zh_CN": "", + "raw": "appliance vm %s start failed", + "en_US": "appliance vm {0} start failed", + "zh_CN": "应用装置VM{0}启动失败", "arguments": [ - "ruleUuid", - "JSONObjectUtil.toJsonString(errors)" + "getSelf().getUuid()" ], - "line": 1820, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 781, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmBase.java" }, { - "raw": "Unsupported RemovalPolicy[%s] type", - "en_US": "Unsupported RemovalPolicy[{0}] type", - "zh_CN": "", + "raw": "set appliance bootstrapinfo error, because:%s", + "en_US": "set appliance bootstrapinfo error, because:{0}", + "zh_CN": "设置装置BootstrapInfo错误,原因:{0}", "arguments": [ - "removalPolicy.toString()" + "rsp.getError()" ], - "line": 2437, - "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + "line": 64, + "fileName": "src/main/java/org/zstack/appliancevm/ApplianceVmKvmBootstrapFlow.java" }, { - "raw": "IPMI Address %s is not valid", - "en_US": "IPMI Address {0} is not valid", - "zh_CN": "IPMI地址{0}是无效的", + "raw": "listener[uuid:%s] are being used by the autoScalingVmTemplate[%s] and cannot be deleted", + "en_US": "listener[uuid:{0}] are being used by the autoScalingVmTemplate[{1}] and cannot be deleted", + "zh_CN": "侦听器[uuid:{0}]正由AutoScalingVMTemplate[{1}]使用,无法删除", "arguments": [ - "address" + "msg.getUuid()", + "uuid" ], - "line": 63, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" - }, - { - "raw": "Failed to reach the bare-metal chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS.", - "en_US": "Failed to reach the bare-metal chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS.", - "zh_CN": "无法连通裸金属设备,请确认:1,管理节点与裸金属设备远程控制口连通;2,IPMI地址、端口、账号、密码是正确的;3,BIOS中启用LAN上的IPMI功能。", - "arguments": [], - "line": 69, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 120, + "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" }, { - "raw": "Baremetal Chassis of IPMI address %s and IPMI port %d has already been created.", - "en_US": "Baremetal Chassis of IPMI address {0} and IPMI port {1} has already been created.", - "zh_CN": "IPMI地址为{0},端口为{1}的裸金属设备已经被创建", + "raw": "The instance[%s] does not exist in the scaling group[%s]", + "en_US": "The instance[{0}] does not exist in the scaling group[{1}]", + "zh_CN": "缩放组[{1}]中不存在实例[{0}]", "arguments": [ - "address", - "port" + "msg.getInstanceUuid()", + "msg.getGroupUuid()" ], - "line": 84, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 131, + "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" }, { - "raw": "Cluster[uuid:%s] does not exists.", - "en_US": "Cluster[uuid:{0}] does not exists.", - "zh_CN": "集群[uuid:{0}]不存在", + "raw": "alarm[uuid:%s] are being used by the autoScalingGroup[%s] which cannot be deleted", + "en_US": "alarm[uuid:{0}] are being used by the autoScalingGroup[{1}] which cannot be deleted", + "zh_CN": "无法删除的AutoScalingGroup[{1}]正在使用报警[uuid:{0}]", "arguments": [ - "msg.getClusterUuid()" + "msg.getAlarmUuid()", + "ruleVO.getScalingGroupUuid()" ], - "line": 95, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 163, + "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" }, { - "raw": "Cluster[uuid:%s] is not a baremetal cluster.", - "en_US": "Cluster[uuid:{0}] is not a baremetal cluster.", - "zh_CN": "集群[uuid:{0}]不是一个裸金属集群", + "raw": "rule[%s] state is Disabled", + "en_US": "rule[{0}] state is Disabled", + "zh_CN": "规则[{0}]状态已禁用", "arguments": [ - "msg.getClusterUuid()" + "msg.getUuid()" ], - "line": 102, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 173, + "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java" }, { - "raw": "Cluster[uuid:%s] is not Enabled.", - "en_US": "Cluster[uuid:{0}] is not Enabled.", - "zh_CN": "集群[uuid:{0}]处于停用状态", + "raw": "invalid l3 network uuids[%s] for listener that belongs lb[%s], all the networks must be attached the LB service and be attached with the same vRouter with LB", + "en_US": "invalid l3 network uuids[{0}] for listener that belongs lb[{1}], all the networks must be attached the LB service and be attached with the same vRouter with LB", + "zh_CN": "属于LB[{1}]的侦听器的三层网络uuid[{0}]无效,所有网络都必须附加到LB服务,并且必须附加到与LB相同的VRouter", "arguments": [ - "msg.getClusterUuid()" + "l3Uuids", + "uuid" ], - "line": 108, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 386, + "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java" }, { - "raw": "IPMI Address and Port %s:%d already exists.", - "en_US": "IPMI Address and Port {0}:{1} already exists.", - "zh_CN": "IPMI地址为{0},端口为{1}的裸金属设备已经存在", + "raw": "detach autoScalingTemplate[%s] from AutoScalingGroup failed, errors are %s", + "en_US": "detach autoScalingTemplate[{0}] from AutoScalingGroup failed, errors are {1}", + "zh_CN": "从AutoScalingGroup分离AutoScalingTemplate[{0}]失败,错误为{1}", "arguments": [ - "address", - "port" + "msg.getTemplateUuid()", + "JSONObjectUtil.toJsonString(errors)" ], - "line": 146, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 744, + "fileName": "src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java" }, { - "raw": "no usable baremetal pxeserver attached to cluster[uuid:%s]", - "en_US": "no usable baremetal pxeserver attached to cluster[uuid:{0}]", - "zh_CN": "裸金属集群[uuid:{0}]中没有可用的部署服务器", + "raw": "image[uuid:%s] is of mediaType: %s, only RootVolumeTemplate and ISO can be used to create vm", + "en_US": "image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate and ISO can be used to create vm", + "zh_CN": "镜像[uuid:{0}] 类型为{1},只能用RootVolumeTemplate和ISO来创建云主机", "arguments": [ - "clusterUuid" + "imageVO.getUuid()", + "imageVO.getMediaType()" ], - "line": 211, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + "line": 890, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "baremetal chassis[uuid:%s] is supposed to using pxeserver[uuid:%s], but it was pxeserver[uuid:%s] that actually handled the DHCP request", - "en_US": "baremetal chassis[uuid:{0}] is supposed to using pxeserver[uuid:{1}], but it was pxeserver[uuid:{2}] that actually handled the DHCP request", - "zh_CN": "裸金属设备[uuid:{0}]应当由部署服务器[uuid:{1}]提供DHCP服务,但实际情况是部署服务器[uuid:{2}]提供的DHCP服务", - "arguments": [ - "chassis.getUuid()", - "chassis.getPxeServerUuid()", - "cmd.content" - ], - "line": 153, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "raw": "rootDiskOfferingUuid cannot be null when image mediaType is ISO", + "en_US": "rootDiskOfferingUuid cannot be null when image mediaType is ISO", + "zh_CN": "云盘规格不能为空在镜像类型为ISO时", + "arguments": [], + "line": 893, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "failed to delete baremetal chassis %s", - "en_US": "failed to delete baremetal chassis {0}", - "zh_CN": "", - "arguments": [ - "msg.getUuid()" - ], - "line": 639, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "raw": "Only one scaling activity can be executed in the same scaling group at the same time.", + "en_US": "Only one scaling activity can be executed in the same scaling group at the same time.", + "zh_CN": "同一伸缩组中同一时间只能执行一个伸缩活动。", + "arguments": [], + "line": 367, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "Failed to remotely power on baremetal chassis[uuid:%s]", - "en_US": "Failed to remotely power on baremetal chassis[uuid:{0}]", - "zh_CN": "无法远程启动裸金属设备[uuid:{0}]", - "arguments": [ - "bmc.getUuid()" - ], - "line": 706, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "raw": "The number of instances exceeds the limit", + "en_US": "The number of instances exceeds the limit", + "zh_CN": "实例数超过限制", + "arguments": [], + "line": 1317, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "Failed to remotely power reset baremetal chassis[uuid:%s]", - "en_US": "Failed to remotely power reset baremetal chassis[uuid:{0}]", - "zh_CN": "无法远程重启裸金属设备[uuid:{0}]", + "raw": "add vm nic to loadBalancer failed, No loadBalancer[uuids\u003d%s] can be found.", + "en_US": "add vm nic to loadBalancer failed, No loadBalancer[uuids\u003d{0}] can be found.", + "zh_CN": "将VM NIC添加到LoadBalancer失败,找不到LoadBalancer[uuid\u003d{0}]。", "arguments": [ - "bmc.getUuid()" + "loadBalancerListenerUuidListStr" ], - "line": 722, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "line": 645, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "Failed to remotely pxe boot chassis[uuid:%s]", - "en_US": "Failed to remotely pxe boot chassis[uuid:{0}]", - "zh_CN": "无法远程设置裸金属设备[uuid:{0}]从网卡启动", + "raw": "autoScalingGroup[%s] add newly created vm to loadBalancer failed completely, errors are %s", + "en_US": "autoScalingGroup[{0}] add newly created vm to loadBalancer failed completely, errors are {1}", + "zh_CN": "AutoScalingGroup[{0}]将新创建的VM添加到LoadBalancer完全失败,错误为{1}", "arguments": [ - "bmc.getUuid()" + "msg.getAutoScalingGroupUuid()", + "JSONObjectUtil.toJsonString(addVmNicToLoadBalancerErrorCodes)" ], - "line": 733, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "line": 684, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "failed to connect to chassis [uuid:%s], please check ipmi connection.", - "en_US": "failed to connect to chassis [uuid:{0}], please check ipmi connection.", - "zh_CN": "无法连接到裸金属设备[uuid:{0}], 请确认IPMI连接可用", + "raw": "add vm nic to securityGroup failed, No securityGroup[uuid\u003d%s] can be found.", + "en_US": "add vm nic to securityGroup failed, No securityGroup[uuid\u003d{0}] can be found.", + "zh_CN": "将VM NIC添加到SecurityGroup失败,找不到SecurityGroup[uuid\u003d{0}]。", "arguments": [ - "bmc.getUuid()" + "securityGroupUuid" ], - "line": 901, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "line": 719, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "fail to load chassis info from file, because: %s", - "en_US": "fail to load chassis info from file, because: {0}", - "zh_CN": "无法从文件中读取裸金属设备信息,因为:{0}", + "raw": "autoScalingGroup[%s] add newly created vm to securityGroup failed completely, errors are %s", + "en_US": "autoScalingGroup[{0}] add newly created vm to securityGroup failed completely, errors are {1}", + "zh_CN": "AutoScalingGroup[{0}]将新创建的VM添加到SecurityGroup完全失败,错误为{1}", "arguments": [ - "e.getMessage()" + "msg.getAutoScalingGroupUuid()", + "JSONObjectUtil.toJsonString(addVmNicToSecurityGroupErrorCodes)" ], - "line": 987, - "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + "line": 755, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" }, { - "raw": "Baremetal chassis[uuid:%s] does not exist", - "en_US": "Baremetal chassis[uuid:{0}] does not exist", - "zh_CN": "", + "raw": "A resource can not be found, details: resource[uuid:%s, type:AutoScalingVmTemplateVO] not found", + "en_US": "A resource can not be found, details: resource[uuid:{0}, type:AutoScalingVmTemplateVO] not found", + "zh_CN": "找不到资源,详细信息:找不到资源[uuid:{0},类型:AutoScalingVMTemplateVo]", "arguments": [ - "msg.getChassisUuid()" + "templateGroupRefVO.getTemplateUuid()" ], - "line": 66, - "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" + "line": 865, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "A resource can not be found, details: resource[uuid:%s, type:InstanceOfferingVO] not found", + "en_US": "A resource can not be found, details: resource[uuid:{0}, type:InstanceOfferingVO] not found", + "zh_CN": "找不到资源,详细信息:找不到资源[uuid:{0},类型:InstanceOfferingVO]", + "arguments": [ + "vmTemplateVO.getVmInstanceOfferingUuid()" + ], + "line": 870, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "A resource can not be found, details: resource[uuid:%s, type:ImageVO] not found", + "en_US": "A resource can not be found, details: resource[uuid:{0}, type:ImageVO] not found", + "zh_CN": "找不到资源,详细信息:找不到资源[uuid:{0},类型:ImageVO]", + "arguments": [ + "vmTemplateVO.getImageUuid()" + ], + "line": 881, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "A resource can not be found, details: resource[uuid:%s, type:DiskOfferingVO] not found", + "en_US": "A resource can not be found, details: resource[uuid:{0}, type:DiskOfferingVO] not found", + "zh_CN": "找不到资源,详细信息:找不到资源[uuid:{0},类型:DiskOfferingVO]", + "arguments": [ + "diskOffering" + ], + "line": 905, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "A resource can not be found, details: resource[uuid:%s, type:L3NetworkVO] not found", + "en_US": "A resource can not be found, details: resource[uuid:{0}, type:L3NetworkVO] not found", + "zh_CN": "找不到资源,详细信息:找不到资源[uuid:{0},类型:L3NetworkVO]", + "arguments": [ + "l3Uuid" + ], + "line": 918, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "defaultL3NetworkUuid[uuid:%s] is not in l3NetworkUuids %s", + "en_US": "defaultL3NetworkUuid[uuid:{0}] is not in l3NetworkUuids {1}", + "zh_CN": "默认L3NetworkUuid[Uuid:{0}]不在L3NetworkUuids{1}中", + "arguments": [ + "vmTemplateVO.getDefaultL3NetworkUuid()", + "l3Uuids" + ], + "line": 934, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "the auto scaling group[%s] state error, expected: %s state", + "en_US": "the auto scaling group[{0}] state error, expected: {1} state", + "zh_CN": "自动缩放组[{0}]状态错误,应为:{1}状态", + "arguments": [ + "self.getUuid()", + "AutoScalingGroupState.Enabled.toString()" + ], + "line": 1018, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "The autoScalingGroup[%s] not attach any vm template", + "en_US": "The autoScalingGroup[{0}] not attach any vm template", + "zh_CN": "AutoScalingGroup[{0}]未附加任何VM模板", + "arguments": [ + "self.getUuid()" + ], + "line": 1055, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "autoScalingGroup[%s] destroy vms[%s] failed completely, errors are %s", + "en_US": "autoScalingGroup[{0}] destroy vms[{1}] failed completely, errors are {2}", + "zh_CN": "AutoScalingGroup[{0}]销毁云主机[{1}]完全失败,错误为{2}", + "arguments": [ + "self.getUuid()", + "vmInstanceUuids", + "JSONObjectUtil.toJsonString(errors)" + ], + "line": 1123, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "Cannot find deleted target instance list", + "en_US": "Cannot find deleted target instance list", + "zh_CN": "找不到已删除的目标实例列表", + "arguments": [], + "line": 1330, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "need skip autoScalingGroup activity", + "en_US": "need skip autoScalingGroup activity", + "zh_CN": "需要跳过自动缩放组活动", + "arguments": [], + "line": 1569, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "delete autoScalingRule[%s] triggers failed, errors are %s", + "en_US": "delete autoScalingRule[{0}] triggers failed, errors are {1}", + "zh_CN": "删除AutoScalingRule[{0}]触发器失败,错误为{1}", + "arguments": [ + "ruleUuid", + "JSONObjectUtil.toJsonString(errors)" + ], + "line": 1835, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "Unsupported RemovalPolicy[%s] type", + "en_US": "Unsupported RemovalPolicy[{0}] type", + "zh_CN": "不支持RemovalPolicy[{0}]类型", + "arguments": [ + "removalPolicy.toString()" + ], + "line": 2452, + "fileName": "src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java" + }, + { + "raw": "AutoScalingRuleSchedulerJobTriggerVO[uuid:%s] is %s, state change is not allowed", + "en_US": "AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}] is {1}, state change is not allowed", + "zh_CN": "AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}]为{1},不允许更改状态", + "arguments": [ + "triggerVO.getUuid()", + "triggerVO.getState()" + ], + "line": 183, + "fileName": "src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java" + }, + { + "raw": "AutoScalingRuleSchedulerJobTriggerVO[uuid:%s] is be in cooldownDate", + "en_US": "AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}] is be in cooldownDate", + "zh_CN": "AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}]在CooldownDate中", + "arguments": [ + "ruleUuid" + ], + "line": 192, + "fileName": "src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java" + }, + { + "raw": "AutoScalingRuleVO[uuid:%s] is %s, state change is not allowed", + "en_US": "AutoScalingRuleVO[uuid:{0}] is {1}, state change is not allowed", + "zh_CN": "AutoScalingRuleVO[uuid:{0}]为{1},不允许更改状态", + "arguments": [ + "ruleUuid", + "AutoScalingRuleState.Disabled.toString()" + ], + "line": 250, + "fileName": "src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java" + }, + { + "raw": "Failed to reach the bare-metal chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS.", + "en_US": "Failed to reach the bare-metal chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS.", + "zh_CN": "无法连通裸金属设备,请确认:1,管理节点与裸金属设备远程控制口连通;2,IPMI地址、端口、账号、密码是正确的;3,BIOS中启用LAN上的IPMI功能。", + "arguments": [], + "line": 64, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + }, + { + "raw": "Cluster[uuid:%s] is not a baremetal cluster.", + "en_US": "Cluster[uuid:{0}] is not a baremetal cluster.", + "zh_CN": "集群[uuid:{0}]不是一个裸金属集群", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 111, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + }, + { + "raw": "IPMI Address and Port %s:%d already exists.", + "en_US": "IPMI Address and Port {0}:{1} already exists.", + "zh_CN": "IPMI地址为{0},端口为{1}的裸金属设备已经存在", + "arguments": [ + "address", + "port" + ], + "line": 155, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + }, + { + "raw": "no usable baremetal pxeserver attached to cluster[uuid:%s]", + "en_US": "no usable baremetal pxeserver attached to cluster[uuid:{0}]", + "zh_CN": "裸金属集群[uuid:{0}]中没有可用的部署服务器", + "arguments": [ + "clusterUuid" + ], + "line": 220, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java" + }, + { + "raw": "baremetal chassis[uuid:%s] is supposed to using pxeserver[uuid:%s], but it was pxeserver[uuid:%s] that actually handled the DHCP request", + "en_US": "baremetal chassis[uuid:{0}] is supposed to using pxeserver[uuid:{1}], but it was pxeserver[uuid:{2}] that actually handled the DHCP request", + "zh_CN": "裸金属设备[uuid:{0}]应当由部署服务器[uuid:{1}]提供DHCP服务,但实际情况是部署服务器[uuid:{2}]提供的DHCP服务", + "arguments": [ + "chassis.getUuid()", + "chassis.getPxeServerUuid()", + "cmd.content" + ], + "line": 175, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "failed to delete baremetal chassis %s", + "en_US": "failed to delete baremetal chassis {0}", + "zh_CN": "无法删除裸机机箱{0}", + "arguments": [ + "msg.getUuid()" + ], + "line": 671, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "Failed to remotely power on baremetal chassis[uuid:%s]", + "en_US": "Failed to remotely power on baremetal chassis[uuid:{0}]", + "zh_CN": "无法远程启动裸金属设备[uuid:{0}]", + "arguments": [ + "bmc.getUuid()" + ], + "line": 737, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "Failed to remotely power reset baremetal chassis[uuid:%s]", + "en_US": "Failed to remotely power reset baremetal chassis[uuid:{0}]", + "zh_CN": "无法远程重启裸金属设备[uuid:{0}]", + "arguments": [ + "bmc.getUuid()" + ], + "line": 753, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "Failed to remotely pxe boot chassis[uuid:%s]", + "en_US": "Failed to remotely pxe boot chassis[uuid:{0}]", + "zh_CN": "无法远程设置裸金属设备[uuid:{0}]从网卡启动", + "arguments": [ + "bmc.getUuid()" + ], + "line": 764, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "failed to connect to chassis [uuid:%s], please check ipmi connection.", + "en_US": "failed to connect to chassis [uuid:{0}], please check ipmi connection.", + "zh_CN": "无法连接到裸金属设备[uuid:{0}], 请确认IPMI连接可用", + "arguments": [ + "bmc.getUuid()" + ], + "line": 924, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "fail to load chassis info from file, because: %s", + "en_US": "fail to load chassis info from file, because: {0}", + "zh_CN": "无法从文件中读取裸金属设备信息,因为:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 1010, + "fileName": "src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java" + }, + { + "raw": "Baremetal chassis[uuid:%s] does not exist", + "en_US": "Baremetal chassis[uuid:{0}] does not exist", + "zh_CN": "裸机机箱[uuid:{0}]不存在", + "arguments": [ + "msg.getChassisUuid()" + ], + "line": 59, + "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "Baremetal chassis[uuid:%s] is not Enabled or Available, please choose another one.", @@ -2155,7 +2461,7 @@ "arguments": [ "chassis.getUuid()" ], - "line": 72, + "line": 65, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2165,7 +2471,7 @@ "arguments": [ "chassis.getUuid()" ], - "line": 78, + "line": 71, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2175,17 +2481,17 @@ "arguments": [ "chassis.getUuid()" ], - "line": 91, + "line": 84, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "baremetal pxeserver[uuid:%s] is neither Enabled nor Connected, please check", "en_US": "baremetal pxeserver[uuid:{0}] is neither Enabled nor Connected, please check", - "zh_CN": "", + "zh_CN": "Baremetal Pxeserver[uuid:{0}]既未启用也未连接,请检查", "arguments": [ "chassis.getPxeServerUuid()" ], - "line": 102, + "line": 95, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2195,7 +2501,7 @@ "arguments": [ "mac" ], - "line": 119, + "line": 112, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2206,49 +2512,49 @@ "chassis.getUuid()", "mac" ], - "line": 125, + "line": 118, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "duplicated bm bonding uuid detacted", "en_US": "duplicated bm bonding uuid detacted", - "zh_CN": "", + "zh_CN": "已分离重复的BM绑定uuid", "arguments": [], - "line": 143, + "line": 136, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "Baremetal Bonding does not exist", "en_US": "Baremetal Bonding does not exist", - "zh_CN": "", + "zh_CN": "裸机焊接不存在", "arguments": [], - "line": 147, + "line": 140, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "duplicated l3 network uuid detacted", "en_US": "duplicated l3 network uuid detacted", - "zh_CN": "", + "zh_CN": "已分离重复的三层网络uuid", "arguments": [], - "line": 155, + "line": 148, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "the selected l3 network doesn\u0027t exist", "en_US": "the selected l3 network doesn\u0027t exist", - "zh_CN": "", + "zh_CN": "选定的三层网络不存在", "arguments": [], - "line": 159, + "line": 152, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "the selected l3 network cannot be assigned to chassis[uuid:%s]", "en_US": "the selected l3 network cannot be assigned to chassis[uuid:{0}]", - "zh_CN": "", + "zh_CN": "无法将选定的三层网络分配给机箱[uuid:{0}]", "arguments": [ "chassis.getUuid()" ], - "line": 172, + "line": 165, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2256,7 +2562,7 @@ "en_US": "only iso image is supported in zstack baremetal service", "zh_CN": "目前仅支持为裸机部署ISO镜像", "arguments": [], - "line": 184, + "line": 177, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2264,23 +2570,23 @@ "en_US": "only ImageStoreBackupStorage is supported in zstack baremetal service", "zh_CN": "目前仅支持从镜像仓库中为裸机选择ISO镜像", "arguments": [], - "line": 193, + "line": 186, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "cannot recover baremetal instance that\u0027s not in Destroyed state", "en_US": "cannot recover baremetal instance that\u0027s not in Destroyed state", - "zh_CN": "只能恢复处于Destroyed状态的裸金属主机", + "zh_CN": "只能恢复处于Destroyed状态的裸金属物理机", "arguments": [], - "line": 207, + "line": 200, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { "raw": "cannot expunge baremetal instance that\u0027s not in Destroyed state", "en_US": "cannot expunge baremetal instance that\u0027s not in Destroyed state", - "zh_CN": "只能彻底删除处于Destroyed状态的裸金属主机", + "zh_CN": "只能彻底删除处于Destroyed状态的裸金属物理机", "arguments": [], - "line": 219, + "line": 212, "fileName": "src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java" }, { @@ -2306,7 +2612,7 @@ { "raw": "Failed to remotely power %s baremetal chassis[uuid:%s]", "en_US": "Failed to remotely power {0} baremetal chassis[uuid:{1}]", - "zh_CN": "", + "zh_CN": "无法远程启动{0}裸机机箱[uuid:{1}]", "arguments": [ "reboot ? \"reset\" : \"on\"", "bmc.getUuid()" @@ -2317,7 +2623,7 @@ { "raw": "there are bm instances using ip address allocated from l2[uuid:%s]", "en_US": "there are bm instances using ip address allocated from l2[uuid:{0}]", - "zh_CN": "", + "zh_CN": "存在使用从L2[uuid:{0}]分配的IP地址的BM实例", "arguments": [ "msg.getL2NetworkUuid()" ], @@ -2327,7 +2633,7 @@ { "raw": "there are bm instances using ip address allocated from l3[uuid:%s]", "en_US": "there are bm instances using ip address allocated from l3[uuid:{0}]", - "zh_CN": "", + "zh_CN": "存在使用从L3[uuid:{0}]分配的IP地址的BM实例", "arguments": [ "msg.getL3NetworkUuid()" ], @@ -2337,7 +2643,7 @@ { "raw": "there are bm instances using ip address allocated from ip range[uuid:%s]", "en_US": "there are bm instances using ip address allocated from ip range[uuid:{0}]", - "zh_CN": "", + "zh_CN": "存在使用从IP范围[uuid:{0}]分配的IP地址的BM实例", "arguments": [ "msg.getIpRangeUuid()" ], @@ -2347,7 +2653,7 @@ { "raw": "creating bm bonding is only allowed before creating bm instance", "en_US": "creating bm bonding is only allowed before creating bm instance", - "zh_CN": "", + "zh_CN": "只能在创建BM实例之前创建BM绑定", "arguments": [], "line": 39, "fileName": "src/main/java/org/zstack/baremetal/network/BaremetalNetworkApiInterceptor.java" @@ -2355,7 +2661,7 @@ { "raw": "bond name %s already exists", "en_US": "bond name {0} already exists", - "zh_CN": "", + "zh_CN": "结合名称{0}已存在", "arguments": [ "msg.getName()" ], @@ -2365,7 +2671,7 @@ { "raw": "Slave address %s is invalid. It should be like 6c:b3:11:1b:0b:1e,6c:b3:11:1b:0b:1f", "en_US": "Slave address {0} is invalid. It should be like 6c:b3:11:1b:0b:1e,6c:b3:11:1b:0b:1f", - "zh_CN": "", + "zh_CN": "从属地址{0}无效。它应该类似于6C:B3:11:1B:0B:1E,6C:B3:11:1B:0B:1F", "arguments": [ "slave" ], @@ -2375,7 +2681,7 @@ { "raw": "mac address %s does not belong to chassis[uuid:%s]", "en_US": "mac address {0} does not belong to chassis[uuid:{1}]", - "zh_CN": "", + "zh_CN": "MAC地址{0}不属于机箱[uuid:{1}]", "arguments": [ "slave", "msg.getChassisUuid()" @@ -2386,7 +2692,7 @@ { "raw": "mac address %s is already a bond slave", "en_US": "mac address {0} is already a bond slave", - "zh_CN": "", + "zh_CN": "MAC地址{0}已是绑定从属地址", "arguments": [ "slave" ], @@ -2396,7 +2702,7 @@ { "raw": "cannot update predefined preconfiguration templates", "en_US": "cannot update predefined preconfiguration templates", - "zh_CN": "", + "zh_CN": "无法更新预定义的预配置模板", "arguments": [], "line": 43, "fileName": "src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationApiInterceptor.java" @@ -2404,7 +2710,7 @@ { "raw": "cannot delete predefined preconfiguration templates", "en_US": "cannot delete predefined preconfiguration templates", - "zh_CN": "", + "zh_CN": "无法删除预定义的预配置模板", "arguments": [], "line": 55, "fileName": "src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationApiInterceptor.java" @@ -2412,7 +2718,7 @@ { "raw": "cannot change state of predefined preconfiguration templates", "en_US": "cannot change state of predefined preconfiguration templates", - "zh_CN": "", + "zh_CN": "无法更改预定义的预配置模板的状态", "arguments": [], "line": 63, "fileName": "src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationApiInterceptor.java" @@ -2420,23 +2726,13 @@ { "raw": "cannot find PreconfigurationTemplateVO[uuid:%s], it may have been deleted", "en_US": "cannot find PreconfigurationTemplateVO[uuid:{0}], it may have been deleted", - "zh_CN": "", + "zh_CN": "找不到PreConfigurationTemplateVo[uuid:{0}],它可能已被删除", "arguments": [ "msg.getTemplateUuid()" ], - "line": 65, + "line": 66, "fileName": "src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationManagerImpl.java" }, - { - "raw": "%s can only be called by admin account", - "en_US": "{0} can only be called by admin account", - "zh_CN": "{0}只能被admin账户调用", - "arguments": [ - "msg.getClass().getSimpleName()" - ], - "line": 44, - "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" - }, { "raw": "PXE Server DHCP Range Netmask %s is invalid.", "en_US": "PXE Server DHCP Range Netmask {0} is invalid.", @@ -2444,7 +2740,7 @@ "arguments": [ "netmask" ], - "line": 74, + "line": 69, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2455,7 +2751,7 @@ "begin", "end" ], - "line": 80, + "line": 75, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2465,7 +2761,17 @@ "arguments": [ "msg.getHostname()" ], - "line": 88, + "line": 92, + "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" + }, + { + "raw": "there is already a baremetal2 gateway with management ip %s, do not use it to create baremetal pxe server", + "en_US": "there is already a baremetal2 gateway with management ip {0}, do not use it to create baremetal pxe server", + "zh_CN": "已存在管理IP为{0}的BareMetal2网关,请不要使用它来创建BareMetal PXE服务器", + "arguments": [ + "msg.getHostname()" + ], + "line": 103, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2473,7 +2779,7 @@ "en_US": "storagePath should be an absolute path", "zh_CN": "部署服务器的存储路径必须是绝对路径", "arguments": [], - "line": 95, + "line": 110, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2483,7 +2789,7 @@ "arguments": [ "msg.getHostname()" ], - "line": 113, + "line": 126, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2493,7 +2799,7 @@ "arguments": [ "msg.getHostname()" ], - "line": 127, + "line": 136, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2503,7 +2809,7 @@ "arguments": [ "msg.getDhcpInterface()" ], - "line": 141, + "line": 146, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2515,7 +2821,7 @@ "msg.getDhcpRangeEnd()", "msg.getDhcpInterface()" ], - "line": 150, + "line": 155, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2526,7 +2832,7 @@ "msg.getClusterUuid()", "msg.getPxeServerUuid()" ], - "line": 187, + "line": 192, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2536,7 +2842,7 @@ "arguments": [ "msg.getClusterUuid()" ], - "line": 196, + "line": 201, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2547,13 +2853,13 @@ "msg.getPxeServerUuid()", "msg.getClusterUuid()" ], - "line": 207, + "line": 212, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { "raw": "baremetal pxeserver[uuid:%s] is not compatible with baremetal instances in cluster[uuid:%s], existing nic ip %s is out of pxeserver dhcp range %s ~ %s.", "en_US": "baremetal pxeserver[uuid:{0}] is not compatible with baremetal instances in cluster[uuid:{1}], existing nic ip {2} is out of pxeserver dhcp range {3} ~ {4}.", - "zh_CN": "部署服务器[uuid:{0}]不适合于集群[uuid:{1}],因为集群中已有的裸金属主机网卡地址{2}超出了部署服务器的DHCP范围{3} ~ {4}", + "zh_CN": "部署服务器[uuid:{0}]不适合于集群[uuid:{1}],因为集群中已有的裸金属物理机网卡地址{2}超出了部署服务器的DHCP范围{3} ~ {4}", "arguments": [ "msg.getPxeServerUuid()", "msg.getClusterUuid()", @@ -2561,7 +2867,7 @@ "begin", "end" ], - "line": 233, + "line": 238, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2572,7 +2878,7 @@ "msg.getPxeServerUuid()", "msg.getClusterUuid()" ], - "line": 250, + "line": 255, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java" }, { @@ -2582,67 +2888,67 @@ "arguments": [ "self.getUuid()" ], - "line": 286, + "line": 295, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to create bm instance configs on baremetal pxeserver[uuid:%s]", "en_US": "failed to create bm instance configs on baremetal pxeserver[uuid:{0}]", - "zh_CN": "在部署服务器[uuid:{0}]上创建裸金属主机相关配置失败", + "zh_CN": "在部署服务器[uuid:{0}]上创建裸金属物理机相关配置失败", "arguments": [ "self.getUuid()" ], - "line": 423, + "line": 432, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to delete bm instance configs on baremetal pxeserver[uuid:%s]", "en_US": "failed to delete bm instance configs on baremetal pxeserver[uuid:{0}]", - "zh_CN": "在部署服务器[uuid:{0}]上删除裸金属主机相关配置失败", + "zh_CN": "在部署服务器[uuid:{0}]上删除裸金属物理机相关配置失败", "arguments": [ "self.getUuid()" ], - "line": 454, + "line": 463, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to create bm instance novnc proxy on baremetal pxeserver[uuid:%s]", "en_US": "failed to create bm instance novnc proxy on baremetal pxeserver[uuid:{0}]", - "zh_CN": "在部署服务器[uuid:{0}]上创建裸金属主机NoVNC代理失败", + "zh_CN": "在部署服务器[uuid:{0}]上创建裸金属物理机NoVNC代理失败", "arguments": [ "self.getUuid()" ], - "line": 485, + "line": 494, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to delete bm instance novnc proxy on baremetal pxeserver[uuid:%s]", "en_US": "failed to delete bm instance novnc proxy on baremetal pxeserver[uuid:{0}]", - "zh_CN": "在部署服务器[uuid:{0}]上删除裸金属主机NoVNC代理失败", + "zh_CN": "在部署服务器[uuid:{0}]上删除裸金属物理机NoVNC代理失败", "arguments": [ "self.getUuid()" ], - "line": 516, + "line": 525, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to create bm instance nginx proxy on baremetal pxeserver[uuid:%s]", "en_US": "failed to create bm instance nginx proxy on baremetal pxeserver[uuid:{0}]", - "zh_CN": "在部署服务器[uuid:{0}]上创建裸金属主机Nginx代理失败", + "zh_CN": "在部署服务器[uuid:{0}]上创建裸金属物理机Nginx代理失败", "arguments": [ "self.getUuid()" ], - "line": 549, + "line": 558, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to delete bm instance nginx proxy on baremetal pxeserver[uuid:%s]", "en_US": "failed to delete bm instance nginx proxy on baremetal pxeserver[uuid:{0}]", - "zh_CN": "在部署服务器[uuid:{0}]上删除裸金属主机Nginx代理失败", + "zh_CN": "在部署服务器[uuid:{0}]上删除裸金属物理机Nginx代理失败", "arguments": [ "self.getUuid()" ], - "line": 580, + "line": 589, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { @@ -2652,7 +2958,7 @@ "arguments": [ "self.getUuid()" ], - "line": 611, + "line": 620, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { @@ -2662,40 +2968,40 @@ "arguments": [ "self.getUuid()" ], - "line": 644, + "line": 653, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to create dhcp config of chassis[uuid:%s] on pxeserver[uuid:%s]", "en_US": "failed to create dhcp config of chassis[uuid:{0}] on pxeserver[uuid:{1}]", - "zh_CN": "", + "zh_CN": "无法在Pxeserver[uuid:{1}]上创建机箱[uuid:{0}]的DHCP配置", "arguments": [ "msg.getChassisUuid()", "self.getUuid()" ], - "line": 959, + "line": 968, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "failed to delete dhcp config of chassis[uuid:%s] on pxeserver[uuid:%s]", "en_US": "failed to delete dhcp config of chassis[uuid:{0}] on pxeserver[uuid:{1}]", - "zh_CN": "", + "zh_CN": "无法删除机箱[uuid:{0}](在Pxeserver[uuid:{1}]上)的DHCP配置", "arguments": [ "msg.getChassisUuid()", "self.getUuid()" ], - "line": 988, + "line": 997, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "the uuid of baremtal pxeserver agent changed[expected:%s, actual:%s], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", "en_US": "the uuid of baremtal pxeserver agent changed[expected:{0}, actual:{1}], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", - "zh_CN": "", + "zh_CN": "Baremtal PXEServer代理的uuid已更改[应为:{0},实际为:{1}],代理很可能已手动重新启动。发出重新连接以同步状态", "arguments": [ "self.getUuid()", "ret.uuid" ], - "line": 1046, + "line": 1055, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { @@ -2706,7 +3012,7 @@ "url", "rsp.error" ], - "line": 1229, + "line": 1270, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { @@ -2716,7 +3022,7 @@ "arguments": [ "cache.getImageUuid()" ], - "line": 1320, + "line": 1362, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { @@ -2726,15747 +3032,27295 @@ "arguments": [ "msg.getImageUuid()" ], - "line": 1430, + "line": 1467, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { "raw": "unsupported backup storage type for baremetal", "en_US": "unsupported backup storage type for baremetal", - "zh_CN": "裸金属管理所不支持的镜像存储类型", + "zh_CN": "裸金属管理所不支持的镜像服务器类型", "arguments": [], - "line": 1526, + "line": 1563, "fileName": "src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java" }, { - "raw": "the start date must be greater than the end date", - "en_US": "the start date must be greater than the end date", - "zh_CN": "开始时间必须早于结束时间", - "arguments": [], - "line": 104, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" - }, - { - "raw": "resourceType and resourceUuid cannot be empty at the same time", - "en_US": "resourceType and resourceUuid cannot be empty at the same time", - "zh_CN": "", - "arguments": [], - "line": 108, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "bond name %s has been existed", + "en_US": "bond name {0} has been existed", + "zh_CN": "债券名称{0}已存在", + "arguments": [ + "msg.getName()" + ], + "line": 59, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "the minimal resource unit is megabyte, cannot be byte", - "en_US": "the minimal resource unit is megabyte, cannot be byte", - "zh_CN": "资源的最小单位必须为MB,而不是byte", - "arguments": [], - "line": 226, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "nic with mac:%s has been bonded", + "en_US": "nic with mac:{0} has been bonded", + "zh_CN": "已绑定具有MAC:{0}的NIC", + "arguments": [ + "mac" + ], + "line": 71, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "price must be 0 and 9999.99", - "en_US": "price must be 0 and 9999.99", - "zh_CN": "价格必须在0和9999.99之间", - "arguments": [], - "line": 234, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "cannot find the cluster of baremetal2 chassis[uuid:%s], maybe it doesn\u0027t exist", + "en_US": "cannot find the cluster of baremetal2 chassis[uuid:{0}], maybe it doesn\u0027t exist", + "zh_CN": "找不到BareMetal2机箱[uuid:{0}]的集群,该集群可能不存在", + "arguments": [ + "chassisUuid" + ], + "line": 98, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "gpu price must be bound to gpu uuid empty", - "en_US": "gpu price must be bound to gpu uuid empty", - "zh_CN": "GPU类型的价格必须绑定一个GPU设备", - "arguments": [], - "line": 241, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "there is no baremetal2 gateway found in cluster[uuid:%s]", + "en_US": "there is no baremetal2 gateway found in cluster[uuid:{0}]", + "zh_CN": "在集群[uuid:{0}]中找不到BareMetal2网关", + "arguments": [ + "clusterUuid" + ], + "line": 107, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "gpu price must be bound to gpu uuid %s", - "en_US": "gpu price must be bound to gpu uuid {0}", - "zh_CN": "GPU类型的价格必须绑定一个正确的GPU设备{0}", + "raw": "there is no usable baremetal2 gateway found in cluster[uuid:%s]", + "en_US": "there is no usable baremetal2 gateway found in cluster[uuid:{0}]", + "zh_CN": "在集群[uuid:{0}]中找不到可用的Baremetal2网关", "arguments": [ - "price.getSystemTags()" + "clusterUuid" ], - "line": 248, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "line": 116, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "resourceName[%s] is invalid", - "en_US": "resourceName[{0}] is invalid", - "zh_CN": "", + "raw": "there is no baremetal2 provision network found in cluster[uuid:%s]", + "en_US": "there is no baremetal2 provision network found in cluster[uuid:{0}]", + "zh_CN": "在集群[uuid:{0}]中找不到BareMetal2配置网络", "arguments": [ - "resourceName" + "clusterUuid" ], - "line": 208, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "line": 124, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "The account[uuid\u003d%s] has attach price table", - "en_US": "The account[uuid\u003d{0}] has attach price table", - "zh_CN": "", + "raw": "baremetal2 provision network[uuid:%s] is not usable, make sure it\u0027s Enabled", + "en_US": "baremetal2 provision network[uuid:{0}] is not usable, make sure it\u0027s Enabled", + "zh_CN": "Baremetal2配置网络[uuid:{0}]不可用,请确保它已启用", "arguments": [ - "msg.getAccountUuid()" + "provisionNetworkUuid" ], - "line": 260, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "line": 132, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java" }, { - "raw": "This priceTable[uuid\u003d%s] is not allowed to delete", - "en_US": "This priceTable[uuid\u003d{0}] is not allowed to delete", - "zh_CN": "", + "raw": "wrong baremetal2 chassis hardware info format: %s", + "en_US": "wrong baremetal2 chassis hardware info format: {0}", + "zh_CN": "错误的Baremetal2机箱硬件信息格式:{0}", "arguments": [ - "msg.getUuid()" + "hardwareInfo" ], - "line": 266, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "line": 78, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "accountUuid/tableUuid only one of them is allowed to be set", - "en_US": "accountUuid/tableUuid only one of them is allowed to be set", - "zh_CN": "", - "arguments": [], - "line": 280, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "the cpu architecture of the chassis[arch:%s] and the cluster[arch:%s] don\u0027t match", + "en_US": "the cpu architecture of the chassis[arch:{0}] and the cluster[arch:{1}] don\u0027t match", + "zh_CN": "机箱[arch:{0}]和集群[arch:{1}]的CPU体系结构不匹配", + "arguments": [ + "info.architecture", + "clusterArchitecture" + ], + "line": 87, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "endDateInLong is not allowed to be negative", - "en_US": "endDateInLong is not allowed to be negative", - "zh_CN": "", - "arguments": [], - "line": 286, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "only baremetal2 chassis with boot mode %s is supported", + "en_US": "only baremetal2 chassis with boot mode {0} is supported", + "zh_CN": "仅支持引导模式为{0}的BareMetal2机箱", + "arguments": [ + "BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE" + ], + "line": 97, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "endDateInLong and setEndDateInLongBaseOnCurrentTime are not allowed to set at the same time", - "en_US": "endDateInLong and setEndDateInLongBaseOnCurrentTime are not allowed to set at the same time", - "zh_CN": "", - "arguments": [], - "line": 290, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "wrong baremetal2 chassis nic hardware info format: %s", + "en_US": "wrong baremetal2 chassis nic hardware info format: {0}", + "zh_CN": "错误的Baremetal2机箱NIC硬件信息格式:{0}", + "arguments": [ + "hardwareInfo" + ], + "line": 108, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "endDateInLong is set, no modification allowed", - "en_US": "endDateInLong is set, no modification allowed", - "zh_CN": "", + "raw": "there must be one and only one provision nic in a baremetal2 chassis", + "en_US": "there must be one and only one provision nic in a baremetal2 chassis", + "zh_CN": "Baremetal2机箱中必须有且只有一个配置NIC", "arguments": [], - "line": 303, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "line": 114, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "endDateInLong cannot be earlier than dateInLong", - "en_US": "endDateInLong cannot be earlier than dateInLong", - "zh_CN": "", - "arguments": [], - "line": 311, - "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + "raw": "wrong baremetal2 chassis disk hardware info format: %s", + "en_US": "wrong baremetal2 chassis disk hardware info format: {0}", + "zh_CN": "错误的Baremetal2机箱磁盘硬件信息格式:{0}", + "arguments": [ + "hardwareInfo" + ], + "line": 124, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "priceKeyName is null", - "en_US": "priceKeyName is null", - "zh_CN": "", + "raw": "other chassis has nics with the same mac address, which is impossible", + "en_US": "other chassis has nics with the same mac address, which is impossible", + "zh_CN": "其他机箱具有相同MAC地址的NIC,这是不可能的", "arguments": [], - "line": 254, - "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" + "line": 167, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java" }, { - "raw": "dateInLong is less than %s", - "en_US": "dateInLong is less than {0}", - "zh_CN": "", + "raw": "BareMetal2 Chassis[uuid:%s] doesn\u0027t exist or is disabled", + "en_US": "BareMetal2 Chassis[uuid:{0}] doesn\u0027t exist or is disabled", + "zh_CN": "Baremetal2机箱[uuid:{0}]不存在或已禁用", "arguments": [ - "currentPriceVO.getDateInLong()" + "msg.getClusterUuid()" ], - "line": 879, - "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" + "line": 372, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java" }, { - "raw": "Already have one userdata systemTag for instanceOffering[uuid: %s].", - "en_US": "Already have one userdata systemTag for instanceOffering[uuid: {0}].", - "zh_CN": "", + "raw": "no available baremetal2 chassis found in baremetal2 clusters[uuids:%s]", + "en_US": "no available baremetal2 chassis found in baremetal2 clusters[uuids:{0}]", + "zh_CN": "在Baremetal2集群中找不到可用的Baremetal2机箱[uuid:{0}]", "arguments": [ - "resourceUuid" + "msg.getRequiredClusterUuids()" ], - "line": 1281, - "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" + "line": 438, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java" }, { - "raw": "Shouldn\u0027t be more than one systemTag for one instanceOffering.", - "en_US": "Shouldn\u0027t be more than one systemTag for one instanceOffering.", - "zh_CN": "", + "raw": "no available baremetal2 chassis found", + "en_US": "no available baremetal2 chassis found", + "zh_CN": "找不到可用的Baremetal2机箱", "arguments": [], - "line": 1346, - "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" + "line": 430, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java" }, { - "raw": "Already have one userdata systemTag for diskOffering[uuid: %s].", - "en_US": "Already have one userdata systemTag for diskOffering[uuid: {0}].", - "zh_CN": "", + "raw": "IPMI Address %s is not valid", + "en_US": "IPMI Address {0} is not valid", + "zh_CN": "IPMI地址{0}是无效的", "arguments": [ - "resourceUuid" + "address" ], - "line": 1323, - "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" + "line": 82, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "unsupported billing resource type [%s]", - "en_US": "unsupported billing resource type [{0}]", - "zh_CN": "", + "raw": "Baremetal Chassis of IPMI address %s and IPMI port %d has already been created.", + "en_US": "Baremetal Chassis of IPMI address {0} and IPMI port {1} has already been created.", + "zh_CN": "IPMI地址为{0},端口为{1}的裸金属设备已经被创建", "arguments": [ - "resourceType" + "address", + "port" ], - "line": 50, - "fileName": "src/main/java/org/zstack/billing/ResourceSpendingHelper.java" + "line": 121, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "cannot find such ResourceStackVO by uuid [%s]", - "en_US": "cannot find such ResourceStackVO by uuid [{0}]", - "zh_CN": "", + "raw": "BareMetal2 Chassis of IPMI address %s and IPMI port %d has already been created.", + "en_US": "BareMetal2 Chassis of IPMI address {0} and IPMI port {1} has already been created.", + "zh_CN": "已创建IPMI地址为{0}、IPMI端口为{1}的BareMetal2机箱。", "arguments": [ - "msg.getUuid()" + "address", + "port" ], - "line": 63, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "line": 111, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "restart resource stack only support %s status!", - "en_US": "restart resource stack only support {0} status!", - "zh_CN": "", + "raw": "Cluster[uuid:%s] does not exists.", + "en_US": "Cluster[uuid:{0}] does not exists.", + "zh_CN": "集群[uuid:{0}]不存在", "arguments": [ - "validStatus" + "msg.getClusterUuid()" ], - "line": 67, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "line": 133, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "templateContent and uuid mustn\u0027t both be empty or both be set!", - "en_US": "templateContent and uuid mustn\u0027t both be empty or both be set!", - "zh_CN": "", - "arguments": [], - "line": 175, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "raw": "Cluster[uuid:%s] is not Enabled.", + "en_US": "Cluster[uuid:{0}] is not Enabled.", + "zh_CN": "集群[uuid:{0}]处于停用状态", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 146, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "expect %s status!", - "en_US": "expect {0} status!", - "zh_CN": "", + "raw": "Bare Metal IPMI 2 Chassis %s:%d already exists", + "en_US": "Bare Metal IPMI 2 Chassis {0}:{1} already exists", + "zh_CN": "裸机IPMI 2机箱{0}:{1}已存在", "arguments": [ - "validStatus" + "address", + "port" ], - "line": 98, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "line": 74, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "templateContent and templateUuid mustn\u0027t both be empty!", - "en_US": "templateContent and templateUuid mustn\u0027t both be empty!", - "zh_CN": "", + "raw": "Failed to reach the baremetal2 chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS.", + "en_US": "Failed to reach the baremetal2 chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS.", + "zh_CN": "无法访问Baremetal2机箱,请确保:1.IPMI连接处于活动状态;2.IPMI地址、端口、用户名和密码正确;3.在BIOS中启用了IPMI over LAN。", "arguments": [], - "line": 118, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "line": 93, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "templateContent and url mustn\u0027t both be empty or both be set!", - "en_US": "templateContent and url mustn\u0027t both be empty or both be set!", - "zh_CN": "", - "arguments": [], - "line": 129, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "raw": "Cluster[uuid:%s] is not a BareMetal2 Cluster.", + "en_US": "Cluster[uuid:{0}] is not a BareMetal2 Cluster.", + "zh_CN": "集群[uuid:{0}]不是BareMetal2集群。", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 140, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "only admin could enable/disable system StackTemplate", - "en_US": "only admin could enable/disable system StackTemplate", - "zh_CN": "", - "arguments": [], - "line": 145, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" + "raw": "no usable baremetal2 gateway in cluster[uuid:%s]", + "en_US": "no usable baremetal2 gateway in cluster[uuid:{0}]", + "zh_CN": "集群[uuid:{0}]中没有可用的Baremetal2网关", + "arguments": [ + "clusterUuid" + ], + "line": 178, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java" }, { - "raw": "cannot delete or update system template: %s", - "en_US": "cannot delete or update system template: {0}", - "zh_CN": "", + "raw": "failed to power on baremetal2 ipmi chassis[uuid:%s]", + "en_US": "failed to power on baremetal2 ipmi chassis[uuid:{0}]", + "zh_CN": "无法打开BareMetal2 IPMI机箱[uuid:{0}]", "arguments": [ - "vo.getName()" + "self.getUuid()" ], - "line": 856, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 134, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java" }, { - "raw": "ResourceStackVO: [%s] has been deleted...", - "en_US": "ResourceStackVO: [{0}] has been deleted...", - "zh_CN": "", + "raw": "failed to power off baremetal2 ipmi chassis[uuid:%s]", + "en_US": "failed to power off baremetal2 ipmi chassis[uuid:{0}]", + "zh_CN": "无法关闭BareMetal2 IPMI机箱[uuid:{0}]", "arguments": [ - "msg.getUuid()" + "self.getUuid()" ], - "line": 385, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 206, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java" }, { - "raw": "ResourceStackVO [%s] already been deleted!", - "en_US": "ResourceStackVO [{0}] already been deleted!", - "zh_CN": "", + "raw": "failed to power reset baremetal2 ipmi chassis[uuid:%s]", + "en_US": "failed to power reset baremetal2 ipmi chassis[uuid:{0}]", + "zh_CN": "无法重新启动BareMetal2 IPMI机箱[uuid:{0}]", "arguments": [ - "uuid" + "self.getUuid()" ], - "line": 415, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 249, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java" }, { - "raw": "templateContent must be set!", - "en_US": "templateContent must be set!", - "zh_CN": "", - "arguments": [], - "line": 641, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "raw": "Failed to remotely ipxe boot chassis[uuid:%s]", + "en_US": "Failed to remotely ipxe boot chassis[uuid:{0}]", + "zh_CN": "无法远程IPXE引导机箱[uuid:{0}]", + "arguments": [ + "self.getUuid()" + ], + "line": 340, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java" }, { - "raw": "template [%s] chosen is disabled", - "en_US": "template [{0}] chosen is disabled", - "zh_CN": "", + "raw": "fail to load baremetal2 ipmi chassis info from file, because: %s", + "en_US": "fail to load baremetal2 ipmi chassis info from file, because: {0}", + "zh_CN": "无法从文件加载BareMetal2 IPMI机箱信息,原因是:{0}", "arguments": [ - "template.getUuid()" + "e.getMessage()" ], - "line": 636, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 76, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java" }, { - "raw": "cannot find parameters for %s, which is %s type, please check parameters", - "en_US": "cannot find parameters for {0}, which is {1} type, please check parameters", - "zh_CN": "", + "raw": "the api message\u0027s chassis type is ipmi, but it\u0027s not an APICreateBareMetal2ChassisHardwareInfoMsg", + "en_US": "the api message\u0027s chassis type is ipmi, but it\u0027s not an APICreateBareMetal2ChassisHardwareInfoMsg", + "zh_CN": "API消息的机箱类型为IPMI,但它不是APICreateBareMetal2ChassisHardwareInfoMsg", + "arguments": [], + "line": 94, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java" + }, + { + "raw": "received hardware info for unknown baremetal2 chassis[ipmi_addr:%s, ipmi_port:%d]", + "en_US": "received hardware info for unknown baremetal2 chassis[ipmi_addr:{0}, ipmi_port:{1}]", + "zh_CN": "收到未知Baremetal2机箱的硬件信息[IPMI_地址:{0},IPMI_端口:{1}]", "arguments": [ - "p.getParamName()", - "p.getResourceType()" + "imsg.getIpmiAddress()", + "imsg.getIpmiPort()" ], - "line": 779, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 104, + "fileName": "src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java" }, { - "raw": "StackTemplateVO has been deleted...", - "en_US": "StackTemplateVO has been deleted...", - "zh_CN": "", + "raw": "cluster type and hypervisor type should all be baremetal2 or all not", + "en_US": "cluster type and hypervisor type should all be baremetal2 or all not", + "zh_CN": "集群类型和云主机管理程序类型应全部为BareMetal2或全部为非BareMetal2", "arguments": [], - "line": 849, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 84, + "fileName": "src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java" }, { - "raw": "content must be set by templateContent or url!", - "en_US": "content must be set by templateContent or url!", - "zh_CN": "", + "raw": "the architecture must be set when create new baremetal2 clusters", + "en_US": "the architecture must be set when create new baremetal2 clusters", + "zh_CN": "创建新的Baremetal2集群时必须设置体系结构", "arguments": [], - "line": 872, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 90, + "fileName": "src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java" }, { - "raw": "get null content input", - "en_US": "get null content input", - "zh_CN": "", + "raw": "do not add host into baremetal2 cluster", + "en_US": "do not add host into baremetal2 cluster", + "zh_CN": "不要将物理机添加到BareMetal2集群中", "arguments": [], - "line": 890, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "line": 101, + "fileName": "src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java" }, { - "raw": "invalid cloudformation template version: %s", - "en_US": "invalid cloudformation template version: {0}", - "zh_CN": "", - "arguments": [ - "result.getTemplateVersion()" - ], - "line": 897, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "raw": "l2 network should not have the same interface name with provision network that\u0027s already attached to the cluster", + "en_US": "l2 network should not have the same interface name with provision network that\u0027s already attached to the cluster", + "zh_CN": "二层网络不应与已连接到集群的Provision网络具有相同的接口名称", + "arguments": [], + "line": 123, + "fileName": "src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java" }, { - "raw": "StackTemplateVO: [%s] has been deleted...", - "en_US": "StackTemplateVO: [{0}] has been deleted...", - "zh_CN": "", - "arguments": [ - "msg.getUuid()" - ], - "line": 911, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" + "raw": "Can not attach third-party ceph with token into aarch64 cluster.", + "en_US": "Can not attach third-party ceph with token into aarch64 cluster.", + "zh_CN": "无法使用令牌将第三方 分布式存储 附加到Aarch64集群。", + "arguments": [], + "line": 29, + "fileName": "src/main/java/org/zstack/baremetal2/cluster/CephStorageAttachBm2ClusterMetric.java" }, { - "raw": "get null element in template content", - "en_US": "get null element in template content", - "zh_CN": "", + "raw": "Can not attach local storage into baremetal2 cluster.", + "en_US": "Can not attach local storage into baremetal2 cluster.", + "zh_CN": "无法将本地存储连接到BareMetal2集群。", "arguments": [], - "line": 20, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationUtils.java" + "line": 12, + "fileName": "src/main/java/org/zstack/baremetal2/cluster/LocalStorageAttachBm2ClusterMetric.java" }, { - "raw": "template must contain [ZStackTemplateFormatVersion]", - "en_US": "template must contain [ZStackTemplateFormatVersion]", - "zh_CN": "", - "arguments": [], - "line": 24, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationUtils.java" + "raw": "no provision nic found for baremetal2 instance[uuid:%s]", + "en_US": "no provision nic found for baremetal2 instance[uuid:{0}]", + "zh_CN": "未找到BareMetal2实例[uuid:{0}]的配置NIC", + "arguments": [ + "msg.getInstanceUuid()" + ], + "line": 1328, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "invalid ZStackTemplateFormatVersion: %s, %s", - "en_US": "invalid ZStackTemplateFormatVersion: {0}, {1}", - "zh_CN": "", + "raw": "failed to delete convert volume to chassis local disk configurations in gateway[uuid:%s] for baremetal2 instance[uuid:%s]", + "en_US": "failed to delete convert volume to chassis local disk configurations in gateway[uuid:{0}] for baremetal2 instance[uuid:{1}]", + "zh_CN": "无法删除将网关[uuid:{0}]中的卷转换为机箱本地磁盘配置(对于BareMetal2实例[uuid:{1}])", "arguments": [ - "result.getTemplateVersion()", - "CloudFormationConstant.version" + "self.getUuid()", + "msg.getInstanceUuid()" ], - "line": 27, - "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationUtils.java" + "line": 269, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "verb must contain \u0027::\u0027!", - "en_US": "verb must contain \u0027::\u0027!", - "zh_CN": "", - "arguments": [], - "line": 156, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + "raw": "failed to create provision configurations for baremetal2 instance[uuid:%s] in gateway[uuid:%s], because %s", + "en_US": "failed to create provision configurations for baremetal2 instance[uuid:{0}] in gateway[uuid:{1}], because {2}", + "zh_CN": "无法为网关[uuid:{1}]中的BareMetal2实例[uuid:{0}]创建设置配置,因为{2}", + "arguments": [ + "msg.getInstanceUuid()", + "self.getUuid()", + "ret.getError()" + ], + "line": 1342, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "need List for resource [%s] output here, but got %s.", - "en_US": "need List for resource [{0}] output here, but got {1}.", - "zh_CN": "", + "raw": "chassis:%s disk does not have wwn info, please inspect chassis and try again", + "en_US": "chassis:{0} disk does not have wwn info, please inspect chassis and try again", + "zh_CN": "机箱:{0}磁盘没有WWN信息,请检查机箱并重试", "arguments": [ - "t[0]", - "last.getClass().getName()" + "chassis.getUuid()" ], - "line": 197, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + "line": 418, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "invalid dynamic variables, which must contained ${: %s", - "en_US": "invalid dynamic variables, which must contained ${: {0}", - "zh_CN": "", + "raw": "failed to power on baremetal2 chassis[uuid:%s] using ipmitool", + "en_US": "failed to power on baremetal2 chassis[uuid:{0}] using ipmitool", + "zh_CN": "无法使用ipmitool打开Baremetal2机箱[uuid:{0}]的电源", "arguments": [ - "value" + "chassis.getUuid()" ], - "line": 221, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + "line": 1809, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "cannot find resource of properties set before!", - "en_US": "cannot find resource of properties set before!", - "zh_CN": "", + "raw": "convert image data to local disk failed", + "en_US": "convert image data to local disk failed", + "zh_CN": "将图像数据转换到本地磁盘失败", "arguments": [], - "line": 283, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + "line": 567, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Some actions are invalid", - "en_US": "Some actions are invalid", - "zh_CN": "", - "arguments": [], - "line": 359, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + "raw": "baremetal2 instance[uuid:%s] convert volume failed on baremetal2 chassis[uuid:%s] , timeout after %s minutes ", + "en_US": "baremetal2 instance[uuid:{0}] convert volume failed on baremetal2 chassis[uuid:{1}] , timeout after {2} minutes ", + "zh_CN": "Baremetal2实例[uuid:{0}]转换卷在Baremetal2机箱[uuid:{1}]上失败,{2}分钟后超时", + "arguments": [ + "instanceVO.getUuid()", + "chassis.getUuid()", + "BareMetal2GlobalConfig.CONVERT_VOLUME_TO_LOCAL_DISK_TIMEOUT.value(Integer.class)" + ], + "line": 576, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Unable to create json template", - "en_US": "Unable to create json template", - "zh_CN": "", + "raw": "failed to prepare provision network in gateway[uuid:%s], because %s", + "en_US": "failed to prepare provision network in gateway[uuid:{0}], because {1}", + "zh_CN": "无法在网关[uuid:{0}]中准备设置网络,因为{1}", "arguments": [ - "e" + "self.getUuid()", + "ret.getError()" ], - "line": 128, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java" + "line": 1235, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "cannot find such template file: %s", - "en_US": "cannot find such template file: {0}", - "zh_CN": "", + "raw": "failed to destroy provision network in gateway[uuid:%s], because %s", + "en_US": "failed to destroy provision network in gateway[uuid:{0}], because {1}", + "zh_CN": "无法销毁网关[uuid:{0}]中的设置网络,因为{1}", "arguments": [ - "jsonFile" + "self.getUuid()", + "ret.getError()" ], - "line": 116, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java" + "line": 1304, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "no root element found, please check your cfn formation!", - "en_US": "no root element found, please check your cfn formation!", - "zh_CN": "", - "arguments": [], - "line": 233, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java" + "raw": "failed to delete provision configurations for baremetal2 instance[uuid:%s] in gateway[uuid:%s], because %s", + "en_US": "failed to delete provision configurations for baremetal2 instance[uuid:{0}] in gateway[uuid:{1}], because {2}", + "zh_CN": "无法删除Baremetal2实例[uuid:{0}](在网关[uuid:{1}]中)的设置配置,因为{2}", + "arguments": [ + "msg.getInstanceUuid()", + "self.getUuid()", + "ret.getError()" + ], + "line": 1391, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Wrong json format, causes: %s", - "en_US": "Wrong json format, causes: {0}", - "zh_CN": "", + "raw": "failed to create console proxy for baremetal2 instance[uuid:%s] in gateway[uuid:%s], because %s", + "en_US": "failed to create console proxy for baremetal2 instance[uuid:{0}] in gateway[uuid:{1}], because {2}", + "zh_CN": "无法为网关[uuid:{1}]中的BareMetal2实例[uuid:{0}]创建控制台代理,因为{2}", "arguments": [ - "e.getMessage()" + "msg.getInstanceUuid()", + "self.getUuid()", + "ret.getError()" ], - "line": 365, - "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java" + "line": 1435, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Mappings root body must be json object!", - "en_US": "Mappings root body must be json object!", - "zh_CN": "", - "arguments": [], - "line": 59, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + "raw": "failed to change default network from l3[uuid:%s] to l3[uuid:%s] for baremetal2 instance[uuid:%s], because %s", + "en_US": "failed to change default network from l3[uuid:{0}] to l3[uuid:{1}] for baremetal2 instance[uuid:{2}], because {3}", + "zh_CN": "无法将默认网络从第3层[uuid:{0}]更改为第3层[uuid:{1}](对于BareMetal2实例[UUid:{2}]),因为{3}", + "arguments": [ + "msg.getOldDefaultL3Uuid()", + "msg.getNewDefaultL3Uuid()", + "msg.getInstanceUuid()", + "ret.getError()" + ], + "line": 1492, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Condition body cannot support json null or array!", - "en_US": "Condition body cannot support json null or array!", - "zh_CN": "", - "arguments": [], - "line": 45, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + "raw": "failed to ping baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to ping baremetal2 instance[uuid:{0}] through gateway[uuid:{1}], because {2}", + "zh_CN": "无法通过网关[uuid:{1}]Ping BareMetal2实例[uuid:{0}],因为{2}", + "arguments": [ + "msg.getInstanceUuid()", + "msg.getGatewayUuid()", + "ret.getError()" + ], + "line": 1531, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Only support ZStack Template Functions in \u0027Condition\u0027 field!", - "en_US": "Only support ZStack Template Functions in \u0027Condition\u0027 field!", - "zh_CN": "", - "arguments": [], - "line": 41, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + "raw": "failed to change the password of baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to change the password of baremetal2 instance[uuid:{0}] through gateway[uuid:{1}], because {2}", + "zh_CN": "无法通过网关[uuid:{1}]更改BareMetal2实例[uuid:{0}]的密码,因为{2}", + "arguments": [ + "msg.getInstanceUuid()", + "msg.getGatewayUuid()", + "ret.getError()" + ], + "line": 1578, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Value must be boolean in \u0027Condition\u0027 field", - "en_US": "Value must be boolean in \u0027Condition\u0027 field", - "zh_CN": "", + "raw": "third party ceph with token not support local disk yet", + "en_US": "third party ceph with token not support local disk yet", + "zh_CN": "带有令牌的第三方 分布式存储 尚不支持本地磁盘", "arguments": [], - "line": 37, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + "line": 1677, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Condition key: %s only support 1 element in the json object of value, but got %d elements!", - "en_US": "Condition key: {0} only support 1 element in the json object of value, but got {1} elements!", - "zh_CN": "", + "raw": "failed to power off baremetal2 chassis[uuid:%s] using ipmitool", + "en_US": "failed to power off baremetal2 chassis[uuid:{0}] using ipmitool", + "zh_CN": "无法使用ipmitool关闭Baremetal2机箱[uuid:{0}]的电源", "arguments": [ - "key", - "es.size()" + "chassis.getUuid()" ], - "line": 30, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + "line": 1838, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "cannot find such msg: %s for create", - "en_US": "cannot find such msg: {0} for create", - "zh_CN": "", + "raw": "baremetal2 chassis[uuid:%s] is still not POWER_OFF %d seconds later", + "en_US": "baremetal2 chassis[uuid:{0}] is still not POWER_OFF {1} seconds later", + "zh_CN": "Baremetal2机箱[uuid:{0}]在{1}秒后仍未关闭电源_。", "arguments": [ - "msg" + "chassis.getUuid()", + "timeout" ], - "line": 87, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/DecoderUtils.java" + "line": 1923, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Mapping value body cannot support null!", - "en_US": "Mapping value body cannot support null!", - "zh_CN": "", - "arguments": [], - "line": 56, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java" + "raw": "failed to power off baremetal2 instance[uuid:%s] by bm agent, because %s", + "en_US": "failed to power off baremetal2 instance[uuid:{0}] by bm agent, because {1}", + "zh_CN": "无法通过BM代理关闭BareMetal2实例[uuid:{0}],因为{1}", + "arguments": [ + "bm.getUuid()", + "ret.getError()" + ], + "line": 1896, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Mapping value body cannot support json array!", - "en_US": "Mapping value body cannot support json array!", - "zh_CN": "", + "raw": "vmInstanceUuids is empty", + "en_US": "vmInstanceUuids is empty", + "zh_CN": "VMInstanceUuids为空", "arguments": [], - "line": 54, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java" + "line": 2103, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "mappingName must be found in result, or it is invalid cfn json.", - "en_US": "mappingName must be found in result, or it is invalid cfn json.", - "zh_CN": "", - "arguments": [], - "line": 66, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java" + "raw": "the baremetal2 gateway[uuid:%s, status:%s] is not Connected", + "en_US": "the baremetal2 gateway[uuid:{0}, status:{1}] is not Connected", + "zh_CN": "Baremetal2网关[uuid:{0},状态:{1}]未连接", + "arguments": [ + "self.getUuid()", + "self.getStatus()" + ], + "line": 2109, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Mapping body cannot support json null!", - "en_US": "Mapping body cannot support json null!", - "zh_CN": "", - "arguments": [], - "line": 83, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + "raw": "baremetal2 instance[uuid:%s] not connected, cannot attach nic to it", + "en_US": "baremetal2 instance[uuid:{0}] not connected, cannot attach nic to it", + "zh_CN": "BareMetal2实例[uuid:{0}]未连接,无法将NIC连接到该实例", + "arguments": [ + "bmUuid" + ], + "line": 2186, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Mapping body cannot support non map value!", - "en_US": "Mapping body cannot support non map value!", - "zh_CN": "", - "arguments": [], - "line": 81, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + "raw": "failed to attach nic[uuid:%s] to baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to attach nic[uuid:{0}] to baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3}", + "zh_CN": "无法通过网关[uuid:{2}]将NIC[uuid:{0}]连接到BareMetal2实例[Uuid:{1}],因为{3}", + "arguments": [ + "nicUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" + ], + "line": 2209, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Description in Outputs must be String type!", - "en_US": "Description in Outputs must be String type!", - "zh_CN": "", - "arguments": [], - "line": 70, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + "raw": "baremetal2 instance[uuid:%s] is not connected, cannot detach nic from it", + "en_US": "baremetal2 instance[uuid:{0}] is not connected, cannot detach nic from it", + "zh_CN": "BareMetal2实例[uuid:{0}]未连接,无法将NIC与其分离", + "arguments": [ + "bmUuid" + ], + "line": 2252, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "paramName must be found in result, or it is invalid cfn json.", - "en_US": "paramName must be found in result, or it is invalid cfn json.", - "zh_CN": "", - "arguments": [], - "line": 59, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java" + "raw": "failed to detach nic[uuid:%s] from baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to detach nic[uuid:{0}] from baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3}", + "zh_CN": "无法通过网关[uuid:{2}]从BareMetal2实例[uuid:{1}]分离NIC[Uuid:{0}],因为{3}", + "arguments": [ + "nicUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" + ], + "line": 2275, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Parameters root body must be json object!", - "en_US": "Parameters root body must be json object!", - "zh_CN": "", - "arguments": [], - "line": 129, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java" + "raw": "baremetal2 instance[uuid:%s] is not connected, cannot attach volume to it", + "en_US": "baremetal2 instance[uuid:{0}] is not connected, cannot attach volume to it", + "zh_CN": "BareMetal2实例[uuid:{0}]未连接,无法将卷附加到该实例", + "arguments": [ + "bmUuid" + ], + "line": 2441, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "resourceName must be found in result, or it is invalid cfn json.", - "en_US": "resourceName must be found in result, or it is invalid cfn json.", - "zh_CN": "", - "arguments": [], - "line": 112, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + "raw": "failed to prepare volume[uuid:%s] for baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to prepare volume[uuid:{0}] for baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3}", + "zh_CN": "无法通过网关[uuid:{2}]为BareMetal2实例[uuid:{1}]准备卷[Uuid:{0}],因为{3}", + "arguments": [ + "volumeUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" + ], + "line": 2338, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Parameters body cannot support null!", - "en_US": "Parameters body cannot support null!", - "zh_CN": "", - "arguments": [], - "line": 123, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + "raw": "failed to attach volume[uuid:%s] to baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to attach volume[uuid:{0}] to baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3}", + "zh_CN": "无法通过网关[uuid:{2}]将卷[uuid:{0}]附加到BareMetal2实例[Uuid:{1}],因为{3}", + "arguments": [ + "volumeUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" + ], + "line": 2399, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Resource value body cannot support null!", - "en_US": "Resource value body cannot support null!", - "zh_CN": "", - "arguments": [], - "line": 68, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + "raw": "failed to get volume[uuid:%s] lunid for baremetal2 instance[uuid:%s] in gateway[uuid:%s], because %s", + "en_US": "failed to get volume[uuid:{0}] lunid for baremetal2 instance[uuid:{1}] in gateway[uuid:{2}], because {3}", + "zh_CN": "无法获取卷[uuid:{0}]的lunid(针对网关[uuid:{2}]中的BareMetal2实例[Uuid:{1}]),因为{3}", + "arguments": [ + "volumeUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" + ], + "line": 2480, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Resource %s cannot depends on itself, please check %s in Resource [%s]", - "en_US": "Resource {0} cannot depends on itself, please check {1} in Resource [{2}]", - "zh_CN": "", + "raw": "failed to detach volume[uuid:%s] from baremetal2 instance[uuid:%s] through gateway[uuid:%s], because %s", + "en_US": "failed to detach volume[uuid:{0}] from baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3}", + "zh_CN": "无法通过网关[uuid:{2}]分离卷[uuid:{0}](从BareMetal2实例[Uuid:{1}]),因为{3}", "arguments": [ - "resource.getResourceName()", - "e.getKey()", - "resource.getResourceName()" + "volumeUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" ], - "line": 48, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + "line": 2535, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Resource root body must be json object!", - "en_US": "Resource root body must be json object!", - "zh_CN": "", - "arguments": [], - "line": 254, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + "raw": "failed to destroy volume[uuid:%s] for baremetal2 instance[uuid:%s] in gateway[uuid:%s], because %s", + "en_US": "failed to destroy volume[uuid:{0}] for baremetal2 instance[uuid:{1}] in gateway[uuid:{2}], because {3}", + "zh_CN": "无法销毁网关[uuid:{2}]中BareMetal2实例[uuid:{1}]的卷[Uuid:{0}],因为{3}", + "arguments": [ + "volumeUuid", + "bmUuid", + "gatewayUuid", + "ret.getError()" + ], + "line": 2570, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java" }, { - "raw": "Resource Type must be String!", - "en_US": "Resource Type must be String!", - "zh_CN": "", - "arguments": [], - "line": 216, - "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + "raw": "there has been a baremetal2 gateway having management ip %s", + "en_US": "there has been a baremetal2 gateway having management ip {0}", + "zh_CN": "存在管理IP为{0}的BareMetal2网关", + "arguments": [ + "msg.getManagementIp()" + ], + "line": 100, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "cannot find condition[%s] in \u0027Conditions\u0027", - "en_US": "cannot find condition[{0}] in \u0027Conditions\u0027", - "zh_CN": "", + "raw": "there is already a baremetal pxe server with management ip %s, do not use it to create baremetal2 gateway", + "en_US": "there is already a baremetal pxe server with management ip {0}, do not use it to create baremetal2 gateway", + "zh_CN": "已存在管理IP为{0}的Baremetal PXE服务器,请不要使用它来创建Baremetal2网关", "arguments": [ - "cond" + "msg.getManagementIp()" ], - "line": 42, - "fileName": "src/main/java/org/zstack/cloudformation/template/function/IfTemplateFunction.java" + "line": 66, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "expect \u0027true\u0027, \u0027false\u0027 for the object, but got %s", - "en_US": "expect \u0027true\u0027, \u0027false\u0027 for the object, but got {0}", - "zh_CN": "", + "raw": "there has been a host having management ip %s", + "en_US": "there has been a host having management ip {0}", + "zh_CN": "已存在管理IP为{0}的物理机", "arguments": [ - "e.getAsString()" + "msg.getManagementIp()" ], - "line": 42, - "fileName": "src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java" + "line": 107, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "expect \u0027true\u0027, \u0027false\u0027 or an other Condition, current Conditions include: %s, but got %s", - "en_US": "expect \u0027true\u0027, \u0027false\u0027 or an other Condition, current Conditions include: {0}, but got {1}", - "zh_CN": "", + "raw": "management ip[%s] is neither an IPv4 address nor a valid hostname", + "en_US": "management ip[{0}] is neither an IPv4 address nor a valid hostname", + "zh_CN": "管理IP[{0}]既不是IPv4地址也不是有效的物理机名", "arguments": [ - "keys", - "e.getAsString()" + "msg.getManagementIp()" ], - "line": 35, - "fileName": "src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java" + "line": 80, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "Fn::Select out of range, please check your json file!", - "en_US": "Fn::Select out of range, please check your json file!", - "zh_CN": "", - "arguments": [], - "line": 83, - "fileName": "src/main/java/org/zstack/cloudformation/template/function/SelectTemplateFunction.java" + "raw": "cannot add baremetal2 gateway in non-baremetal2 cluster[uuid:%s]", + "en_US": "cannot add baremetal2 gateway in non-baremetal2 cluster[uuid:{0}]", + "zh_CN": "无法在非Baremetal2集群[uuid:{0}]中添加Baremetal2网关", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 90, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "only functions can in Function, but found %s", - "en_US": "only functions can in Function, but found {0}", - "zh_CN": "", + "raw": "cannot attach baremetal2 gateway[uuid:%s] to non-baremetal2 cluster[uuid:%s]", + "en_US": "cannot attach baremetal2 gateway[uuid:{0}] to non-baremetal2 cluster[uuid:{1}]", + "zh_CN": "无法将Baremetal2网关[uuid:{0}]连接到非Baremetal2集群[uuid:{1}]", "arguments": [ - "e.getKey()" + "msg.getGatewayUuid()", + "msg.getClusterUuid()" ], - "line": 75, - "fileName": "src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java" + "line": 120, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "element is null!", - "en_US": "element is null!", - "zh_CN": "", - "arguments": [], - "line": 90, - "fileName": "src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java" + "raw": "baremetal2 gateway[uuid:%s] already attached to cluster[uuid:%s]", + "en_US": "baremetal2 gateway[uuid:{0}] already attached to cluster[uuid:{1}]", + "zh_CN": "Baremetal2网关[uuid:{0}]已连接到集群[uuid:{1}]", + "arguments": [ + "msg.getGatewayUuid()", + "msg.getClusterUuid()" + ], + "line": 131, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "VM [uuid: %s] has already been added to affinityGroup [uuid: %s]", - "en_US": "VM [uuid: {0}] has already been added to affinityGroup [uuid: {1}]", - "zh_CN": "VM[uuid:{0}已经被添加到亲和组[uuid:{1}]中。]", + "raw": "baremetal2 gateway[uuid:%s] can only attach to one cluster", + "en_US": "baremetal2 gateway[uuid:{0}] can only attach to one cluster", + "zh_CN": "Baremetal2网关[uuid:{0}]只能连接到一个集群", "arguments": [ - "resourceUuid", - "affinityGroupUuid" + "msg.getGatewayUuid()" ], - "line": 317, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + "line": 140, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "There are other VMs on this host [uuid: %s] belonging to same affinityGroup [%s]", - "en_US": "There are other VMs on this host [uuid: {0}] belonging to same affinityGroup [{1}]", - "zh_CN": "在物理机[uuid:{0}]上的虚拟机属于同一个亲和组中[{1}]", + "raw": "baremetal2 gateway[uuid:%s] not attached to cluster[uuid:%s], no need to detach", + "en_US": "baremetal2 gateway[uuid:{0}] not attached to cluster[uuid:{1}], no need to detach", + "zh_CN": "Baremetal2网关[uuid:{0}]未连接到集群[uuid:{1}],无需分离", "arguments": [ - "hostUuid", - "affinityGroupUuid" + "msg.getGatewayUuid()", + "msg.getClusterUuid()" ], - "line": 334, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + "line": 151, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "affinityGroup [uuid:%s] reserve host [uuid:%s] for vm [uuid: %s] failed", - "en_US": "affinityGroup [uuid:{0}] reserve host [uuid:{1}] for vm [uuid: {2}] failed", - "zh_CN": "亲和组[uuid:{0}]为虚拟机[uuid:{2}]预分配物理机资源[uuid:{1}]失败", + "raw": "baremetal2 gateway[uuid:%s] is attached to only one cluster now, do not detach it", + "en_US": "baremetal2 gateway[uuid:{0}] is attached to only one cluster now, do not detach it", + "zh_CN": "BareMetal2网关[uuid:{0}]现在仅连接到一个集群,请不要将其分离", "arguments": [ - "self.getUuid()", - "host.getUuid()", - "vmUuid" + "msg.getGatewayUuid()" ], - "line": 363, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + "line": 156, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "vm [uuid:%s] doesn\u0027t satisfy the affinityGroup [uuid:%s]", - "en_US": "vm [uuid:{0}] doesn\u0027t satisfy the affinityGroup [uuid:{1}]", - "zh_CN": "虚拟机[uuid:{1}]不满足亲和组[uuid:{2}]的要求", + "raw": "cluster[uuid:%s] does not exist", + "en_US": "cluster[uuid:{0}] does not exist", + "zh_CN": "集群[uuid:{0}]不存在", "arguments": [ - "inv.getResourceUuid()", - "self.getUuid()" + "msg.getClusterUuid()" ], - "line": 433, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + "line": 164, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "can not satisfied affinity group conditions", - "en_US": "can not satisfied affinity group conditions", - "zh_CN": "不能满足亲和组的条件", - "arguments": [], - "line": 136, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupFilterFlow.java" + "raw": "cluster[uuid:%s] is not a baremetal2 cluster", + "en_US": "cluster[uuid:{0}] is not a baremetal2 cluster", + "zh_CN": "集群[uuid:{0}]不是BareMetal2集群", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 168, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "Vm can change its affinityGroup only in state [%s,%s], but vm is in state [%s]", - "en_US": "Vm can change its affinityGroup only in state [{0},{1}], but vm is in state [{2}]", - "zh_CN": "只有状态为[{0},{1}]的虚拟机可以改变亲和组,但是现在虚拟机的状态为[{2}]", + "raw": "gateway[uuid:%s] does not exist", + "en_US": "gateway[uuid:{0}] does not exist", + "zh_CN": "网关[uuid:{0}]不存在", "arguments": [ - "VmInstanceState.Running.toString()", - "VmInstanceState.Stopped.toString()", - "state.toString()" + "msg.getGatewayUuid()" ], - "line": 42, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + "line": 173, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "Vm [uuid: %s] is already added to affinityGroup [uuid: %s]", - "en_US": "Vm [uuid: {0}] is already added to affinityGroup [uuid: {1}]", - "zh_CN": "云主机[uuid:{0}]已经被添加至亲和组[uuid:{1}]中", + "raw": "baremetal2 gateway[uuid:%s] is already in cluster[uuid:%s]", + "en_US": "baremetal2 gateway[uuid:{0}] is already in cluster[uuid:{1}]", + "zh_CN": "Baremetal2网关[uuid:{0}]已在集群[uuid:{1}]中", "arguments": [ - "msg.getUuid()", - "agUuid" + "msg.getGatewayUuid()", + "msg.getClusterUuid()" ], - "line": 52, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + "line": 177, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "AffinityGroup [uuid: %s] does not existed", - "en_US": "AffinityGroup [uuid: {0}] does not existed", - "zh_CN": "亲和组[uuid:{0}]不存在", + "raw": "baremetal2 gateway[uuid:%s] is not in the same zone as cluster[uuid:%s]", + "en_US": "baremetal2 gateway[uuid:{0}] is not in the same zone as cluster[uuid:{1}]", + "zh_CN": "Baremetal2网关[uuid:{0}]与集群[uuid:{1}]不在同一个区域中", "arguments": [ - "affinityGroupUuid" + "msg.getGatewayUuid()", + "msg.getClusterUuid()" ], - "line": 77, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + "line": 181, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" }, { - "raw": "Can not operate on affinity group created by system", - "en_US": "Can not operate on affinity group created by system", - "zh_CN": "不能对系统创建的亲和组进行操作", + "raw": "cannot change the cluster of baremetal2 gateway[uuid:%s] when there are running instances depending on it", + "en_US": "cannot change the cluster of baremetal2 gateway[uuid:{0}] when there are running instances depending on it", + "zh_CN": "存在依赖于Baremetal2网关[uuid:{0}]的正在运行的实例时,无法更改该集群", + "arguments": [ + "msg.getGatewayUuid()" + ], + "line": 191, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java" + }, + { + "raw": "baremetal2 instance[uuid:%s] doesn\u0027t exist, cannot generate its console url", + "en_US": "baremetal2 instance[uuid:{0}] doesn\u0027t exist, cannot generate its console url", + "zh_CN": "Baremetal2实例[uuid:{0}]不存在,无法生成其控制台URL", "arguments": [], - "line": 81, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + "line": 45, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayConsoleHypervisorBackend.java" }, { - "raw": "Can not operate on affinityGroup [uuid: %s] which is not enabled", - "en_US": "Can not operate on affinityGroup [uuid: {0}] which is not enabled", - "zh_CN": "不能对不是enabled状态的亲和组操作", + "raw": "baremetal2 gateway[uuid:%s] is not Connected, cannot generate console url for instance[uuid:%s]", + "en_US": "baremetal2 gateway[uuid:{0}] is not Connected, cannot generate console url for instance[uuid:{1}]", + "zh_CN": "Baremetal2网关[uuid:{0}]未连接,无法为实例[uuid:{1}]生成控制台URL", "arguments": [ - "affinityGroupUuid" + "bm.getGatewayUuid()", + "bm.getUuid()" ], - "line": 88, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + "line": 54, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayConsoleHypervisorBackend.java" }, { - "raw": "cannot find the affinity group[uuid:%s], it may have been deleted", - "en_US": "cannot find the affinity group[uuid:{0}], it may have been deleted", - "zh_CN": "未找到亲和组[uuid:{0}],它可能已经被删除", + "raw": "cluster[%s] is not baremetal2 type", + "en_US": "cluster[{0}] is not baremetal2 type", + "zh_CN": "集群[{0}]不是BareMetal2类型", "arguments": [ - "msg.getAffinityGroupUuid()" + "resourceUuid" ], - "line": 98, - "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupManagerImpl.java" + "line": 258, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayManagerImpl.java" }, { - "raw": "no host found in clusters that has attached to L2Networks which have L3Networks%s", - "en_US": "no host found in clusters that has attached to L2Networks which have L3Networks{0}", - "zh_CN": "", + "raw": "failed to allocate baremetal2 gateway", + "en_US": "failed to allocate baremetal2 gateway", + "zh_CN": "无法分配Baremetal2网关", + "arguments": [], + "line": 102, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/allocator/AbstractGatewayAllocatorStrategy.java" + }, + { + "raw": "no available baremetal2 gateway found", + "en_US": "no available baremetal2 gateway found", + "zh_CN": "找不到可用的Baremetal2网关", + "arguments": [], + "line": 62, + "fileName": "src/main/java/org/zstack/baremetal2/gateway/allocator/BareMetal2GatewayMainAllocatorFlow.java" + }, + { + "raw": "only baremetal2 image with boot mode %s is supported", + "en_US": "only baremetal2 image with boot mode {0} is supported", + "zh_CN": "仅支持引导模式为{0}的BareMetal2镜像", "arguments": [ - "spec.getL3NetworkUuids()" + "BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE" ], - "line": 103, - "fileName": "src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java" + "line": 166, + "fileName": "src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java" }, { - "raw": "no host found in clusters that have attached to primary storage %s", - "en_US": "no host found in clusters that have attached to primary storage {0}", - "zh_CN": "", + "raw": "only one baremetal2 system tag is allowed, but %d was got", + "en_US": "only one baremetal2 system tag is allowed, but {0} was got", + "zh_CN": "只允许一个Baremetal2系统标记,但获得了{0}", "arguments": [ - "psuuids" + "bm2ImageCount" ], - "line": 79, - "fileName": "src/main/java/org/zstack/compute/allocator/AttachedPrimaryStorageAllocatorFlow.java" + "line": 138, + "fileName": "src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java" }, { - "raw": "no host found in clusters which have attached to all primary storage %s where vm[uuid:%s]\u0027s volumes locate", - "en_US": "no host found in clusters which have attached to all primary storage {0} where vm[uuid:{1}]\u0027s volumes locate", - "zh_CN": "", + "raw": "only root volume template of format raw/qcow2 can be tagged with baremetal2", + "en_US": "only root volume template of format raw/qcow2 can be tagged with baremetal2", + "zh_CN": "只有RAW/QCOW2格式的根卷模板才能使用BareMetal2进行标记", + "arguments": [], + "line": 158, + "fileName": "src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java" + }, + { + "raw": "the bootMode tag is mandatory for baremetal2 images", + "en_US": "the bootMode tag is mandatory for baremetal2 images", + "zh_CN": "对于BareMetal2镜像,bootmode标记是必需的", + "arguments": [], + "line": 162, + "fileName": "src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java" + }, + { + "raw": "required chassis disk[%s] not belong to chassis[%s]", + "en_US": "required chassis disk[{0}] not belong to chassis[{1}]", + "zh_CN": "所需的机箱磁盘[{0}]不属于机箱[{1}]", "arguments": [ - "requiredPsUuids", - "vm.getUuid()" + "spec.getRequiredChassisDiskUuid()", + "chassis.getUuid()" ], - "line": 79, - "fileName": "src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java" + "line": 76, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateChassisFlow.java" }, { - "raw": "after rule out avoided host%s, there is no host left in candidates", - "en_US": "after rule out avoided host{0}, there is no host left in candidates", - "zh_CN": "", + "raw": "chassis not have engouh capacity for image[%s]", + "en_US": "chassis not have engouh capacity for image[{0}]", + "zh_CN": "机箱没有足够的容量用于镜像[{0}]", "arguments": [ - "spec.getAvoidHostUuids()" + "chassis.getUuid()", + "spec.getImageSpec().getInventory().getUuid()" ], - "line": 30, - "fileName": "src/main/java/org/zstack/compute/allocator/AvoidHostAllocatorFlow.java" + "line": 88, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateChassisFlow.java" }, { - "raw": "the backup storage[uuid:%s, type:%s] requires bound primary storage, however, the primary storage has not been added", - "en_US": "the backup storage[uuid:{0}, type:{1}] requires bound primary storage, however, the primary storage has not been added", - "zh_CN": "无法找到跟镜像服务器[uuid:{0}, type:{1}]配对的主存储。一些镜像服务器必须跟配对的主存储共同使用,例如Ceph镜像服务器只能搭配Ceph主存储使用。请检查你主存储的设置", + "raw": "not enough information to determine which baremetal2 cluster should be used", + "en_US": "not enough information to determine which baremetal2 cluster should be used", + "zh_CN": "没有足够的信息来确定应使用哪个BareMetal2集群", + "arguments": [], + "line": 85, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" + }, + { + "raw": "no baremetal2 cluster found", + "en_US": "no baremetal2 cluster found", + "zh_CN": "未找到BareMetal2集群", + "arguments": [], + "line": 100, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" + }, + { + "raw": "failed to allocate primary storage in clusters[uuids:%s] for baremetal2 instance[uuid:%s]", + "en_US": "failed to allocate primary storage in clusters[uuids:{0}] for baremetal2 instance[uuid:{1}]", + "zh_CN": "无法在集群[uuid:{0}]中为Baremetal2实例[uuid:{1}]分配主存储", "arguments": [ - "spec.getRequiredBackupStorageUuid()", - "bsType" + "spec.getRequiredClusterUuids()", + "spec.getVmInventory().getUuid()" ], - "line": 87, - "fileName": "src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java" + "line": 217, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" }, { - "raw": "The image[uuid:%s] is on the backup storage[uuid:%s, type:%s] that requires to work with primary storage[uuids:%s],however, no host found suitable to work with those primary storage", - "en_US": "The image[uuid:{0}] is on the backup storage[uuid:{1}, type:{2}] that requires to work with primary storage[uuids:{3}],however, no host found suitable to work with those primary storage", - "zh_CN": "镜像[uuid:{0}]所在的镜像服务器[uuid:{1}, type:{2}]必须跟主存储[uuid:{3}]配对使用,但无法找到可以跟满足条件并可以访问该主存储的物理机", + "raw": "failed to allocate gateway in clusters[uuids:%s] for baremetal2 instance[uuid:%s]", + "en_US": "failed to allocate gateway in clusters[uuids:{0}] for baremetal2 instance[uuid:{1}]", + "zh_CN": "无法在集群[uuid:{0}]中为BareMetal2实例[uuid:{1}]分配网关", "arguments": [ - "spec.getImage().getUuid()", - "spec.getRequiredBackupStorageUuid()", - "type", - "psUuids" + "spec.getRequiredClusterUuids()", + "spec.getVmInventory().getUuid()" ], - "line": 80, - "fileName": "src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java" + "line": 224, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" }, { - "raw": "The image[uuid:%s, name:%s] is on the backup storage[uuid:%s, type:%s] that requires to work with primary storage[types:%s],however, no host found suitable to work with those primary storage", - "en_US": "The image[uuid:{0}, name:{1}] is on the backup storage[uuid:{2}, type:{3}] that requires to work with primary storage[types:{4}],however, no host found suitable to work with those primary storage", - "zh_CN": "镜像[uuid:{0},name:{1}]所在的镜像服务器[uuid:{2}, type:{3}]必须跟主存储[uuid:{4}]一起使用,但无法找到可以跟满足条件并可以访问该主存储的物理机", + "raw": "failed to allocate chassis in clusters[uuids:%s] for baremetal2 instance[uuid:%s]", + "en_US": "failed to allocate chassis in clusters[uuids:{0}] for baremetal2 instance[uuid:{1}]", + "zh_CN": "无法在集群[uuid:{0}]中为Baremetal2实例[uuid:{1}]分配机箱", "arguments": [ - "spec.getImage().getUuid()", - "name", - "spec.getRequiredBackupStorageUuid()", - "spec.getImage().getType()", - "possiblePrimaryStorageTypes" + "spec.getRequiredClusterUuids()", + "spec.getVmInventory().getUuid()" ], - "line": 71, - "fileName": "src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java" + "line": 231, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" }, { - "raw": "No host with %s found", - "en_US": "No host with {0} found", - "zh_CN": "", + "raw": "only baremetal2 clusters[uuid:%s] meet the needs for chassis and gateway, but they have no provision network attached", + "en_US": "only baremetal2 clusters[uuid:{0}] meet the needs for chassis and gateway, but they have no provision network attached", + "zh_CN": "只有BareMetal2集群[uuid:{0}]满足机箱和网关的需求,但它们没有连接的配置网络", "arguments": [ - "args" + "clusterUuids" ], - "line": 107, - "fileName": "src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java" + "line": 262, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" }, { - "raw": "after filtering, HostAllocatorFilterExtensionPoint[%s] returns zero candidate host, it means: %s", - "en_US": "after filtering, HostAllocatorFilterExtensionPoint[{0}] returns zero candidate host, it means: {1}", - "zh_CN": "", + "raw": "no baremetal2 cluster found in clusters[uuid:%s]", + "en_US": "no baremetal2 cluster found in clusters[uuid:{0}]", + "zh_CN": "在集群[uuid:{0}]中找不到BareMetal2集群", "arguments": [ - "filter.getClass().getSimpleName()", - "filter.filterErrorReason()" + "spec.getRequiredClusterUuids()" ], - "line": 33, - "fileName": "src/main/java/org/zstack/compute/allocator/FilterFlow.java" + "line": 253, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java" }, { - "raw": "either volumeUuid or volumeSnapshotUuid must be set", - "en_US": "either volumeUuid or volumeSnapshotUuid must be set", - "zh_CN": "云盘uuid或者快照uuid必须被设置", + "raw": "the primary storage[%s] of the root volume and the primary storage[%s] of the data volume are not in the same cluster", + "en_US": "the primary storage[{0}] of the root volume and the primary storage[{1}] of the data volume are not in the same cluster", + "zh_CN": "根卷的主存储[{0}]和数据云盘的主存储[{1}]不在同一集群中", + "arguments": [ + "msg.getPrimaryStorageUuidForRootVolume()", + "msg.getPrimaryStorageUuidForDataVolume()" + ], + "line": 881, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" + }, + { + "raw": "make sure all baremetal2 gateways on provision network[uuid:%s] are Connected", + "en_US": "make sure all baremetal2 gateways on provision network[uuid:{0}] are Connected", + "zh_CN": "确保配置网络[uuid:{0}]上的所有Baremetal2网关均已连接", + "arguments": [ + "networkUuid" + ], + "line": 244, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" + }, + { + "raw": "neither chassisUuid nor chassisOfferingUuid is set when create baremetal2 instance", + "en_US": "neither chassisUuid nor chassisOfferingUuid is set when create baremetal2 instance", + "zh_CN": "创建BareMetal2实例时,Chassisuuid和ChassisOfferuuid均未设置", "arguments": [], - "line": 56, - "fileName": "src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java" + "line": 707, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "zoneUuids, clusterUuids, hostUuids must at least have one be none-empty list, or all is set to true", - "en_US": "zoneUuids, clusterUuids, hostUuids must at least have one be none-empty list, or all is set to true", - "zh_CN": "区域uuid,集群uuid,物理机uuid必须有一个不为空,或者全部都填写", + "raw": "only support vpc network support attach eip on baremetal2 instance", + "en_US": "only support vpc network support attach eip on baremetal2 instance", + "zh_CN": "仅支持VPC网络支持在Baremetal2实例上附加EIP", "arguments": [], - "line": 75, - "fileName": "src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java" + "line": 169, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no host having cpu[%s], memory[%s bytes] found", - "en_US": "no host having cpu[{0}], memory[{1} bytes] found", - "zh_CN": "", + "raw": "bare metal instance not allowed to change vm nic network", + "en_US": "bare metal instance not allowed to change vm nic network", + "zh_CN": "不允许裸机实例更改VM NIC网络", + "arguments": [], + "line": 179, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" + }, + { + "raw": "current operation is not supported on local baremetal instance", + "en_US": "current operation is not supported on local baremetal instance", + "zh_CN": "本地裸机实例不支持当前操作", + "arguments": [], + "line": 190, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" + }, + { + "raw": "not supported by baremetal2 instance", + "en_US": "not supported by baremetal2 instance", + "zh_CN": "BareMetal2实例不支持", + "arguments": [], + "line": 201, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" + }, + { + "raw": "baremetal2 instance[uuid:%s] is not Connected", + "en_US": "baremetal2 instance[uuid:{0}] is not Connected", + "zh_CN": "BareMetal2实例[uuid:{0}]未连接", "arguments": [ - "spec.getCpuCapacity()", - "spec.getMemoryCapacity()" + "bm.getUuid()" ], - "line": 71, - "fileName": "src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java" + "line": 207, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no candidate host has version[%s]", - "en_US": "no candidate host has version[{0}]", - "zh_CN": "", + "raw": "baremetal2 instance[uuid:%s] is not stopped", + "en_US": "baremetal2 instance[uuid:{0}] is not stopped", + "zh_CN": "Baremetal2实例[uuid:{0}]未停止", "arguments": [ - "currentVersion" + "bm.getUuid()" ], - "line": 62, - "fileName": "src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java" + "line": 215, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "cannot find available primary storage[state: %s or %s, status: %s]. Check the state/status of primary storage and make sure they have been attached to clusters", - "en_US": "cannot find available primary storage[state: {0} or {1}, status: {2}]. Check the state/status of primary storage and make sure they have been attached to clusters", - "zh_CN": "", + "raw": "baremetal2 instance[uuid:%s] is running but its agent is not Connected", + "en_US": "baremetal2 instance[uuid:{0}] is running but its agent is not Connected", + "zh_CN": "Baremetal2实例[uuid:{0}]正在运行,但其代理未连接", "arguments": [ - "PrimaryStorageState.Enabled", - "PrimaryStorageState.Disabled", - "PrimaryStorageStatus.Connected" + "bm.getUuid()" ], "line": 221, - "fileName": "src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java" + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "cannot find available primary storage[state: %s, status: %s, available capacity %s bytes]. Check the state/status of primary storage and make sure they have been attached to clusters", - "en_US": "cannot find available primary storage[state: {0}, status: {1}, available capacity {2} bytes]. Check the state/status of primary storage and make sure they have been attached to clusters", - "zh_CN": "", + "raw": "baremetal2 chassis offering[uuid:%s] does not exist", + "en_US": "baremetal2 chassis offering[uuid:{0}] does not exist", + "zh_CN": "Baremetal2机箱产品[uuid:{0}]不存在", "arguments": [ - "PrimaryStorageState.Enabled", - "PrimaryStorageStatus.Connected", - "spec.getDiskSize()" + "msg.getChassisOfferingUuid()" ], - "line": 217, - "fileName": "src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java" + "line": 607, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "[Host Allocation]: %s on host[uuid:%s]. try next one. %s", - "en_US": "[Host Allocation]: {0} on host[uuid:{1}]. try next one. {2}", - "zh_CN": "", + "raw": "baremetal2 instance[uuid:%s] is not stopped can not change its chassis offering", + "en_US": "baremetal2 instance[uuid:{0}] is not stopped can not change its chassis offering", + "zh_CN": "Baremetal2实例[uuid:{0}]未停止,无法更改其机箱产品", "arguments": [ - "e.getMessage()", - "host.getUuid()", - "e.getMessage()" + "msg.getInstanceUuid()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/compute/allocator/HostSortorChain.java" + "line": 318, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no host having state\u003dEnabled status\u003dConnected hypervisorType\u003d%s found", - "en_US": "no host having state\u003dEnabled status\u003dConnected hypervisorType\u003d{0} found", - "zh_CN": "", + "raw": "baremetal2 instance[uuid:%s] has not been allocated a chassis, start the instance and try again", + "en_US": "baremetal2 instance[uuid:{0}] has not been allocated a chassis, start the instance and try again", + "zh_CN": "尚未为BareMetal2实例[uuid:{0}]分配机箱,请启动该实例并重试", "arguments": [ - "spec.getHypervisorType()" + "msg.getVmInstanceUuid()" ], - "line": 97, - "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + "line": 337, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no host having state\u003dEnabled status\u003dConnected found", - "en_US": "no host having state\u003dEnabled status\u003dConnected found", - "zh_CN": "", - "arguments": [], - "line": 99, - "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + "raw": "only l3 network with ip version %d is supported by baremetal2 instance", + "en_US": "only l3 network with ip version {0} is supported by baremetal2 instance", + "zh_CN": "Baremetal2实例仅支持IP版本为{0}的三层网络", + "arguments": [ + "ipVersion" + ], + "line": 343, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no Enabled hosts found in the [%s] candidate hosts having the hypervisor type [%s]", - "en_US": "no Enabled hosts found in the [{0}] candidate hosts having the hypervisor type [{1}]", - "zh_CN": "", + "raw": "l2 network type %s not supported by baremetal2 instance", + "en_US": "l2 network type {0} not supported by baremetal2 instance", + "zh_CN": "二层网络类型{0}不受Baremetal2实例支持", "arguments": [ - "candidates.size()", - "spec.getHypervisorType()" + "l2Type" ], - "line": 94, - "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + "line": 349, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no Enabled hosts found in the [%s] candidate hosts", - "en_US": "no Enabled hosts found in the [{0}] candidate hosts", - "zh_CN": "", - "arguments": [ - "candidates.size()" - ], - "line": 92, - "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + "raw": "customMac is mandatory when attaching l3 network to baremetal2 instance", + "en_US": "customMac is mandatory when attaching l3 network to baremetal2 instance", + "zh_CN": "将三层网络连接到Baremetal2实例时,CustomMAC是必需的", + "arguments": [], + "line": 355, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no Connected hosts found in the [%s] candidate hosts", - "en_US": "no Connected hosts found in the [{0}] candidate hosts", - "zh_CN": "", + "raw": "%s is not valid mac address", + "en_US": "{0} is not valid mac address", + "zh_CN": "{0}不是有效的MAC地址", "arguments": [ - "candidates.size()" + "msg.getCustomMac()" ], - "line": 90, - "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + "line": 359, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "the image[uuid:%s, name:%s] is deleted on all backup storage", - "en_US": "the image[uuid:{0}, name:{1}] is deleted on all backup storage", - "zh_CN": "镜像[uuid:{0}, name:{1}]已经从所有镜像服务器上删除,无法执行相应操作", + "raw": "duplicated mac address %s", + "en_US": "duplicated mac address {0}", + "zh_CN": "重复的MAC地址{0}", "arguments": [ - "spec.getImage().getUuid()", - "spec.getImage().getName()" + "msg.getCustomMac()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java" + "line": 364, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no host found in zones[uuids:%s] that attaches to backup storage where image[%s] is on", - "en_US": "no host found in zones[uuids:{0}] that attaches to backup storage where image[{1}] is on", - "zh_CN": "", + "raw": "baremetal2 instance[uuid:%s] running on chassis[uuid:%s], which doesn\u0027t have non-provisioning nic with mac address %s", + "en_US": "baremetal2 instance[uuid:{0}] running on chassis[uuid:{1}], which doesn\u0027t have non-provisioning nic with mac address {2}", + "zh_CN": "机箱[uuid:{1}]上运行的Baremetal2实例[uuid:{0}]没有MAC地址为{2}的非配置NIC", "arguments": [ - "zoneUuids", - "spec.getImage().getUuid()" + "bm.getUuid()", + "bm.getChassisUuid()", + "msg.getCustomMac()" ], - "line": 126, - "fileName": "src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java" + "line": 373, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "resource binding not support type %s yet", - "en_US": "resource binding not support type {0} yet", - "zh_CN": "", + "raw": "mac address %s has already been used, try another one", + "en_US": "mac address {0} has already been used, try another one", + "zh_CN": "MAC地址{0}已被使用,请尝试其他地址", "arguments": [ - "entry.getKey()" + "msg.getCustomMac()" ], - "line": 98, - "fileName": "src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java" + "line": 382, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no available host found with binded resource %s", - "en_US": "no available host found with binded resource {0}", - "zh_CN": "", + "raw": "nic with mac:%s cannot be attached l3Network, because it has been bonded", + "en_US": "nic with mac:{0} cannot be attached l3Network, because it has been bonded", + "zh_CN": "MAC为{0}的NIC无法连接到L3Network,因为它已绑定", "arguments": [ - "resources" + "msg.getCustomMac()" ], - "line": 117, - "fileName": "src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java" + "line": 399, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "InstanceOfferingTagAllocatorExtensionPoint[%s] return zero candidate host", - "en_US": "InstanceOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host", - "zh_CN": "", - "arguments": [ - "extp.getClass().getName()" - ], - "line": 68, - "fileName": "src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java" + "raw": "third party ceph cannot mixed with other primary storage", + "en_US": "third party ceph cannot mixed with other primary storage", + "zh_CN": "第三方 分布式存储 不能与其他主存储混合", + "arguments": [], + "line": 448, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "DiskOfferingTagAllocatorExtensionPoint[%s] return zero candidate host", - "en_US": "DiskOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host", - "zh_CN": "", + "raw": "cluster[uuid:%s] is not an Enabled baremetal2 cluster, cannot start instance[uuid:%s] in it", + "en_US": "cluster[uuid:{0}] is not an Enabled baremetal2 cluster, cannot start instance[uuid:{1}] in it", + "zh_CN": "集群[uuid:{0}]不是已启用的BareMetal2集群,无法在其中启动实例[uuid:{1}]", "arguments": [ - "extp.getClass().getName()" + "msg.getClusterUuid()", + "msg.getUuid()" ], - "line": 104, - "fileName": "src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java" - }, - { - "raw": "if cluster type is baremetal, then hypervisorType must be baremetal too, or vice versa", - "en_US": "if cluster type is baremetal, then hypervisorType must be baremetal too, or vice versa", - "zh_CN": "", - "arguments": [], - "line": 55, - "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + "line": 571, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "only kvm hosts\u0027 operating system can be updated, for now", - "en_US": "only kvm hosts\u0027 operating system can be updated, for now", - "zh_CN": "目前只支持升级KVM物理机操作系统", - "arguments": [], - "line": 71, - "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + "raw": "baremetal2 gateway[uuid:%s] does not exist or is not Enabled or Connected", + "en_US": "baremetal2 gateway[uuid:{0}] does not exist or is not Enabled or Connected", + "zh_CN": "Baremetal2网关[uuid:{0}]不存在,或者未启用或未连接", + "arguments": [ + "msg.getGatewayUuid()" + ], + "line": 583, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "there are hosts in cluster[uuid:%s] in the PreMaintenance state, cannot update cluster os right now", - "en_US": "there are hosts in cluster[uuid:{0}] in the PreMaintenance state, cannot update cluster os right now", - "zh_CN": "集群[uuid:{0}] 中存在处于预维护模式的物理机,无法执行操作系统升级操作", + "raw": "baremetal2 gateway[uuid:%s] is not in cluster [uuid:%s]", + "en_US": "baremetal2 gateway[uuid:{0}] is not in cluster [uuid:{1}]", + "zh_CN": "Baremetal2网关[uuid:{0}]不在集群[uuid:{1}]中", "arguments": [ - "msg.getUuid()" + "msg.getGatewayUuid()", + "msg.getClusterUuid()" ], - "line": 82, - "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + "line": 594, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "not all hosts in cluster[uuid:%s] are in the Connected status, cannot update cluster os right now", - "en_US": "not all hosts in cluster[uuid:{0}] are in the Connected status, cannot update cluster os right now", - "zh_CN": "集群[uuid:{0}] 中存在未处于已连接状态的物理机,无法执行操作系统升级操作", + "raw": "please specify chassis uuid or chassis offering uuid to start baremetal2 instance[uuid:%s]", + "en_US": "please specify chassis uuid or chassis offering uuid to start baremetal2 instance[uuid:{0}]", + "zh_CN": "请指定机箱uuid或机箱提供uuid以启动BareMetal2实例[uuid:{0}]", "arguments": [ "msg.getUuid()" ], - "line": 94, - "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + "line": 600, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "invalid cpu pinning ref[%s]. correct example is [1,3:3-6,^5]", - "en_US": "invalid cpu pinning ref[{0}]. correct example is [1,3:3-6,^5]", - "zh_CN": "", + "raw": "baremetal2 chassis offering[uuid:%s] is not Enabled", + "en_US": "baremetal2 chassis offering[uuid:{0}] is not Enabled", + "zh_CN": "未启用Baremetal2机箱产品[uuid:{0}]", "arguments": [ - "r" + "msg.getChassisOfferingUuid()" ], - "line": 45, - "fileName": "src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java" + "line": 611, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "the host vm located only have % CPUs", - "en_US": "the host vm located only have % CPUs", - "zh_CN": "", - "arguments": [ - "pCpuNum" - ], - "line": 82, - "fileName": "src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java" + "raw": "do not set chassisUuid and chassisOfferingUuid at the same time", + "en_US": "do not set chassisUuid and chassisOfferingUuid at the same time", + "zh_CN": "不要同时设置Chassisuuid和ChassisOfferuuid", + "arguments": [], + "line": 711, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "vcpu pinning pcpu id \u003e host cores", - "en_US": "vcpu pinning pcpu id \u003e host cores", - "zh_CN": "vcpu要绑定的pcpu id大于了物理机实际核数", + "raw": "no need to set chassisOfferingUuid because the instance has been assigned an chassis already", + "en_US": "no need to set chassisOfferingUuid because the instance has been assigned an chassis already", + "zh_CN": "无需设置Chassisofferinguuid,因为实例已分配机箱", "arguments": [], - "line": 48, - "fileName": "src/main/java/org/zstack/compute/cpuPinning/CpuPinningFilterFlow.java" + "line": 619, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "Invalid cpuset [%s]", - "en_US": "Invalid cpuset [{0}]", - "zh_CN": "", - "arguments": [ - "word" - ], - "line": 58, - "fileName": "src/main/java/org/zstack/compute/cpuPinning/CpuRangeSet.java" + "raw": "no need to set chassisOfferingUuid because the instance has been assigned an chassis offering already", + "en_US": "no need to set chassisOfferingUuid because the instance has been assigned an chassis offering already", + "zh_CN": "无需设置ChassisOfferinguuid,因为已为实例分配了机箱产品", + "arguments": [], + "line": 623, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "managementIp[%s] is neither an IPv4 address nor a valid hostname", - "en_US": "managementIp[{0}] is neither an IPv4 address nor a valid hostname", - "zh_CN": "管理IP[{0}]既不是有效的IPv4地址也不是有效的物理机名", + "raw": "baremetal2 chassis[uuid:%s] does not exist", + "en_US": "baremetal2 chassis[uuid:{0}] does not exist", + "zh_CN": "Baremetal2机箱[uuid:{0}]不存在", "arguments": [ - "msg.getManagementIp()" + "msg.getChassisUuid()" ], - "line": 78, - "fileName": "src/main/java/org/zstack/compute/host/HostApiInterceptor.java" + "line": 631, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "can not maintain host[uuid:%s, status:%s]which is not Connected", - "en_US": "can not maintain host[uuid:{0}, status:{1}]which is not Connected", - "zh_CN": "只能对已连接状态的物理机[uuid:{0}, status:{1}]进行维护操作", + "raw": "baremetal2 chassis[uuid:%s] is not belonging to chassis offering[uuid:%s]", + "en_US": "baremetal2 chassis[uuid:{0}] is not belonging to chassis offering[uuid:{1}]", + "zh_CN": "Baremetal2机箱[uuid:{0}]不属于机箱产品[uuid:{1}]", "arguments": [ - "msg.getHostUuid()", - "hostStatus" + "msg.getChassisUuid()", + "bm.getChassisOfferingUuid()" ], - "line": 88, - "fileName": "src/main/java/org/zstack/compute/host/HostApiInterceptor.java" + "line": 636, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "failed to migrate vm[uuids:%s] on host[uuid:%s, name:%s, ip:%s], will try stopping it.", - "en_US": "failed to migrate vm[uuids:{0}] on host[uuid:{1}, name:{2}, ip:{3}], will try stopping it.", - "zh_CN": "", + "raw": "baremetal2 chassis[uuid:%s] is not Enabled", + "en_US": "baremetal2 chassis[uuid:{0}] is not Enabled", + "zh_CN": "未启用Baremetal2机箱[uuid:{0}]", "arguments": [ - "vmFailedToMigrate", - "self.getUuid()", - "self.getName()", - "self.getManagementIp()" + "msg.getChassisUuid()" ], - "line": 259, - "fileName": "src/main/java/org/zstack/compute/host/HostBase.java" + "line": 641, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "host is connecting, ping failed", - "en_US": "host is connecting, ping failed", - "zh_CN": "物理机正在连接, 不能进行ping操作", - "arguments": [], - "line": 609, - "fileName": "src/main/java/org/zstack/compute/host/HostBase.java" + "raw": "baremetal2 chassis[uuid:%s] has already been allocated", + "en_US": "baremetal2 chassis[uuid:{0}] has already been allocated", + "zh_CN": "已分配Baremetal2机箱[uuid:{0}]", + "arguments": [ + "msg.getChassisUuid()" + ], + "line": 645, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "an other connect host task is running, cancel the new task and wait return", - "en_US": "an other connect host task is running, cancel the new task and wait return", - "zh_CN": "", - "arguments": [], - "line": 1085, - "fileName": "src/main/java/org/zstack/compute/host/HostBase.java" + "raw": "baremetal2 gateway[uuid:%s] is not in the same cluster with chassis[uuid:%s]", + "en_US": "baremetal2 gateway[uuid:{0}] is not in the same cluster with chassis[uuid:{1}]", + "zh_CN": "Baremetal2网关[uuid:{0}]与机箱[uuid:{1}]不在同一集群中", + "arguments": [ + "msg.getGatewayUuid()", + "msg.getChassisUuid()" + ], + "line": 763, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "there has been a host having managementIp[%s]", - "en_US": "there has been a host having managementIp[{0}]", - "zh_CN": "已经存在一个管理IP是[{0}]的物理机", + "raw": "zone[uuid:%s] is specified but it\u0027s not Enabled, can not create baremetal2 instance from it", + "en_US": "zone[uuid:{0}] is specified but it\u0027s not Enabled, can not create baremetal2 instance from it", + "zh_CN": "区域[uuid:{0}]已指定但未启用,无法从中创建BareMetal2实例", "arguments": [ - "msg.getManagementIp()" + "msg.getZoneUuid()" ], - "line": 282, - "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + "line": 685, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "cluster[uuid:%s] is not existing", - "en_US": "cluster[uuid:{0}] is not existing", - "zh_CN": "", + "raw": "cluster[uuid:%s] is specified but it\u0027s not an Enabled baremetal2 cluster, can not create baremetal2 instance from it", + "en_US": "cluster[uuid:{0}] is specified but it\u0027s not an Enabled baremetal2 cluster, can not create baremetal2 instance from it", + "zh_CN": "指定了集群[uuid:{0}],但它不是启用的BareMetal2集群,无法从中创建BareMetal2实例", "arguments": [ "msg.getClusterUuid()" ], - "line": 288, - "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + "line": 699, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "after connecting, host[name:%s, ip:%s] returns a null os version", - "en_US": "after connecting, host[name:{0}, ip:{1}] returns a null os version", - "zh_CN": "在连接操作后,物理机[name:{0}, ip:{1}]没有返回操作系统版本信息", + "raw": "baremetal2 chassis[uuid:%s] is not Enabled, can\u0027t create baremetal2 instance from it", + "en_US": "baremetal2 chassis[uuid:{0}] is not Enabled, can\u0027t create baremetal2 instance from it", + "zh_CN": "Baremetal2机箱[uuid:{0}]未启用,无法从中创建Baremetal2实例", "arguments": [ - "vo.getName()", - "vo.getManagementIp()" + "msg.getChassisUuid()" ], - "line": 378, - "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + "line": 717, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "cluster[uuid:%s] already has host with os version[%s], but new added host[name:%s ip:%s] has host os version[%s]", - "en_US": "cluster[uuid:{0}] already has host with os version[{1}], but new added host[name:{2} ip:{3}] has host os version[{4}]", - "zh_CN": "集群[uuid:{0}]中物理机使用的操作系统版本是[{1}],但是新的物理机[name:{2} ip:{3}]的操作系统版本是 [{4}]", + "raw": "baremetal2 chassis[uuid:%s] is not Available, can\u0027t create baremetal2 instance from it", + "en_US": "baremetal2 chassis[uuid:{0}] is not Available, can\u0027t create baremetal2 instance from it", + "zh_CN": "Baremetal2机箱[uuid:{0}]不可用,无法从中创建Baremetal2实例", "arguments": [ - "vo.getClusterUuid()", - "currentVersion", - "vo.getName()", - "vo.getManagementIp()", - "mineVersion" + "msg.getChassisUuid()" ], - "line": 409, - "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + "line": 722, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "no running api[%s] task on hosts", - "en_US": "no running api[{0}] task on hosts", - "zh_CN": "", + "raw": "baremetal2 chassis offering[uuid:%s] is not Enabled, can\u0027t create baremetal2 instance from it", + "en_US": "baremetal2 chassis offering[uuid:{0}] is not Enabled, can\u0027t create baremetal2 instance from it", + "zh_CN": "Baremetal2机箱产品[uuid:{0}]未启用,无法从中创建Baremetal2实例", "arguments": [ - "msg.getCancellationApiId()" + "msg.getChassisOfferingUuid()" ], - "line": 531, - "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + "line": 732, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "primary storage[uuid:%s] becomes disconnected, the host has no connected primary storage attached", - "en_US": "primary storage[uuid:{0}] becomes disconnected, the host has no connected primary storage attached", - "zh_CN": "主存储[uuid:{0}]失联,物理机没有关联的主存储", + "raw": "baremetal2 gateway[uuid:%s] is not Enabled, can\u0027t create baremetal2 instance from it", + "en_US": "baremetal2 gateway[uuid:{0}] is not Enabled, can\u0027t create baremetal2 instance from it", + "zh_CN": "Baremetal2网关[uuid:{0}]未启用,无法从中创建Baremetal2实例", "arguments": [ - "d.getPrimaryStorageUuid()" + "msg.getGatewayUuid()" ], - "line": 624, - "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + "line": 743, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "host(s) [%s] is not Connected, not support to power off", - "en_US": "host(s) [{0}] is not Connected, not support to power off", - "zh_CN": "", + "raw": "baremetal2 gateway[uuid:%s] is not Connected, can\u0027t create baremetal2 instance from it", + "en_US": "baremetal2 gateway[uuid:{0}] is not Connected, can\u0027t create baremetal2 instance from it", + "zh_CN": "Baremetal2网关[uuid:{0}]未连接,无法从中创建Baremetal2实例", "arguments": [ - "nameips.stream().map( it -\u003e it.get(1, String.class) + \"/\" + it.get(0, String.class)).collect(Collectors.joining(\", \"))" + "msg.getGatewayUuid()" ], - "line": 38, - "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + "line": 748, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "vm security level not consistent with vms running on host", - "en_US": "vm security level not consistent with vms running on host", - "zh_CN": "", + "raw": "image cannot be empty unless chassis is in direct mode", + "en_US": "image cannot be empty unless chassis is in direct mode", + "zh_CN": "除非机箱处于直接模式,否则镜像不能为空", "arguments": [], - "line": 68, - "fileName": "src/main/java/org/zstack/compute/host/HostSecurityLevelAllocatorFilterExtensionPoint.java" + "line": 780, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "host[uuid:%s, name:%s] is in state[%s], cannot perform required operation", - "en_US": "host[uuid:{0}, name:{1}] is in state[{2}], cannot perform required operation", - "zh_CN": "物理机[uuid:{0}, name:{1}]处于状态[{2}]中,不能处理该请求", + "raw": "direct mode not support choose image", + "en_US": "direct mode not support choose image", + "zh_CN": "直接模式不支持选择镜像", + "arguments": [], + "line": 787, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] does not exist", + "en_US": "image[uuid:{0}] does not exist", + "zh_CN": "镜像[uuid:{0}]不存在", "arguments": [ - "host.getUuid()", - "host.getName()", - "host.getState()" + "msg.getImageUuid()" ], - "line": 204, - "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + "line": 794, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "operation error, because %s", - "en_US": "operation error, because {0}", - "zh_CN": "操作错误,因为{0}", + "raw": "Chassis disk[%s] not have enough capacity for image[%s]", + "en_US": "Chassis disk[{0}] not have enough capacity for image[{1}]", + "zh_CN": "机箱磁盘[{0}]没有足够的容量用于镜像[{1}]", "arguments": [ - "ret.getError()" + "disk.getUuid()", + "image.getUuid()" ], - "line": 485, - "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + "line": 800, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "only support do live snapshot on vm state[%s], but vm is on [%s] state", - "en_US": "only support do live snapshot on vm state[{0}], but vm is on [{1}] state", - "zh_CN": "", + "raw": "image[uuid:%s] is not Enabled, can\u0027t create baremetal2 instance from it", + "en_US": "image[uuid:{0}] is not Enabled, can\u0027t create baremetal2 instance from it", + "zh_CN": "镜像[uuid:{0}]未启用,无法从中创建BareMetal2实例", "arguments": [ - "vmInstanceVO.getUuid()", - "vmInstanceVO.getState()" + "msg.getImageUuid()" ], - "line": 377, - "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + "line": 805, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "host[uuid:%s] has multi ips in cidr[%s]", - "en_US": "host[uuid:{0}] has multi ips in cidr[{1}]", - "zh_CN": "物理机[uuid:{0}]在cidr[{1}]中有多个ip", + "raw": "image[uuid:%s] is not Ready, can\u0027t create baremetal2 instance from it", + "en_US": "image[uuid:{0}] is not Ready, can\u0027t create baremetal2 instance from it", + "zh_CN": "镜像[uuid:{0}]未就绪,无法从中创建BareMetal2实例", "arguments": [ - "huuid", - "cidr" + "msg.getImageUuid()" ], - "line": 71, - "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBaseFactory.java" + "line": 810, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "host[uuid:%s] can not find", - "en_US": "host[uuid:{0}] can not find", - "zh_CN": "", + "raw": "image[uuid:%s] is of mediaType: %s, only RootVolumeTemplate can be used to create baremetal2 instance", + "en_US": "image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate can be used to create baremetal2 instance", + "zh_CN": "镜像[uuid:{0}]的媒体类型为:{1},只有RootVolumeTemplate可用于创建BareMetal2实例", "arguments": [ - "msg.getHostUuid()" + "msg.getImageUuid()", + "image.getMediaType()" ], - "line": 344, - "fileName": "src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java" + "line": 815, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "cluster[uuids:%s, hypervisorType:%s] are not exist!", - "en_US": "cluster[uuids:{0}, hypervisorType:{1}] are not exist!", - "zh_CN": "", + "raw": "image[uuid:%s] is of format: %s, only %s can be used to create baremetal2 instance", + "en_US": "image[uuid:{0}] is of format: {1}, only {2} can be used to create baremetal2 instance", + "zh_CN": "镜像[uuid:{0}]的格式为:{1},只有{2}可用于创建BareMetal2实例", "arguments": [ - "clusterUuids", - "hypervisorType" + "image.getFormat()", + "BareMetal2InstanceConstant.IMAGE_FORMAT_FOR_BM" ], - "line": 336, - "fileName": "src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java" - }, - { - "raw": "not dest host found in db, can\u0027t send change password cmd to the host!", - "en_US": "not dest host found in db, can\u0027t send change password cmd to the host!", - "zh_CN": "没有在物理机上发现数据库,不能发送更改密码的指令到这个物理机上", - "arguments": [], - "line": 50, - "fileName": "src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java" - }, - { - "raw": "not system tag found on vm, vm must have the following system tag: qemuga, if you installed qemu-ga yourself, please use CreateSystemTag first.", - "en_US": "not system tag found on vm, vm must have the following system tag: qemuga, if you installed qemu-ga yourself, please use CreateSystemTag first.", - "zh_CN": "没有发现系统标签在云主机上,云主机必须有系统标签: qemuga。如果你已经安装了qemu-ga,请先使用 CreateSystemTag", - "arguments": [], - "line": 51, - "fileName": "src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java" - }, - { - "raw": "not account preference found, send change password cmd to the host!", - "en_US": "not account preference found, send change password cmd to the host!", - "zh_CN": "没有优先级账户去发送改变密码的指令到物理机", - "arguments": [], - "line": 54, - "fileName": "src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java" + "line": 820, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "the host[uuid:%s] is not connected", - "en_US": "the host[uuid:{0}] is not connected", - "zh_CN": "物理机[uuid:{0}]不是Connected状态", + "raw": "image[uuid:%s] is not baremetal2 image, can\u0027t create baremetal2 instance from it", + "en_US": "image[uuid:{0}] is not baremetal2 image, can\u0027t create baremetal2 instance from it", + "zh_CN": "镜像[uuid:{0}]不是BareMetal2镜像,无法从中创建BareMetal2实例", "arguments": [ - "hostUuid" + "image.getUuid()" ], - "line": 50, - "fileName": "src/main/java/org/zstack/compute/vm/DeleteVmGC.java" + "line": 826, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "VM[uuid:%s] has attached ISO[uuid:%s]", - "en_US": "VM[uuid:{0}] has attached ISO[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]已经加载了ISO[uuid:{1}]", + "raw": "only image with boot mode %s is supported to create baremetal2 instance", + "en_US": "only image with boot mode {0} is supported to create baremetal2 instance", + "zh_CN": "仅支持引导模式为{0}的镜像来创建BareMetal2实例", "arguments": [ - "vmUuid", - "isoUuid" + "BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE" ], - "line": 40, - "fileName": "src/main/java/org/zstack/compute/vm/IsoOperator.java" + "line": 832, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "All vm[uuid:%s] CD-ROMs have mounted ISO", - "en_US": "All vm[uuid:{0}] CD-ROMs have mounted ISO", - "zh_CN": "", - "arguments": [ - "vmUuid" - ], - "line": 48, - "fileName": "src/main/java/org/zstack/compute/vm/IsoOperator.java" + "raw": "different boot mode between the image and chassis/offering", + "en_US": "different boot mode between the image and chassis/offering", + "zh_CN": "镜像和机箱/产品之间的引导模式不同", + "arguments": [], + "line": 841, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "This is not a valid MAC address [%s]", - "en_US": "This is not a valid MAC address [{0}]", - "zh_CN": "这是一个无效的MAC地址", + "raw": "the architecture of baremetal2 cluster[arch:%s] and image[arch:%s] don\u0027t match", + "en_US": "the architecture of baremetal2 cluster[arch:{0}] and image[arch:{1}] don\u0027t match", + "zh_CN": "BareMetal2集群[arch:{0}]的体系结构与镜像[arch:{1}]不匹配", "arguments": [ - "mac" + "clusterArchitecture", + "image.getArchitecture()" ], - "line": 77, - "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + "line": 851, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "Not a valid MAC address [%s]", - "en_US": "Not a valid MAC address [{0}]", - "zh_CN": "这是一个无效的MAC地址[{0}]", + "raw": "not all disk offerings[uuids:%s] are Enabled, can not create baremetal2 instance from them", + "en_US": "not all disk offerings[uuids:{0}] are Enabled, can not create baremetal2 instance from them", + "zh_CN": "并非所有磁盘产品[uuid:{0}]都已启用,无法从中创建BareMetal2实例", "arguments": [ - "mac" + "msg.getDataDiskOfferingUuids()" ], - "line": 87, - "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + "line": 863, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "Disallowed address", - "en_US": "Disallowed address", - "zh_CN": "不被允许的MAC地址", + "raw": "cannot decide which zone the baremetal2 instance should be created in", + "en_US": "cannot decide which zone the baremetal2 instance should be created in", + "zh_CN": "无法确定应在哪个区域中创建BareMetal2实例", "arguments": [], - "line": 90, - "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" - }, - { - "raw": "Expected unicast mac address, found multicast MAC address [%s]", - "en_US": "Expected unicast mac address, found multicast MAC address [{0}]", - "zh_CN": "期望的是一个单播的MAC地址,但找到的是一个组播的MAC地址[{0}]", - "arguments": [ - "mac" - ], - "line": 93, - "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + "line": 890, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java" }, { - "raw": "vm[uuid: %s]\u0027s state is not Stopped now, cannot operate \u0027changevmimage\u0027 action", - "en_US": "vm[uuid: {0}]\u0027s state is not Stopped now, cannot operate \u0027changevmimage\u0027 action", - "zh_CN": "", + "raw": "baremetal2 instance[uuid:%s] is either not exist or not Connected, cannot change its password", + "en_US": "baremetal2 instance[uuid:{0}] is either not exist or not Connected, cannot change its password", + "zh_CN": "Baremetal2实例[uuid:{0}]不存在或未连接,无法更改其密码", "arguments": [], - "line": 192, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 476, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceBase.java" }, { - "raw": "can not find image store backup storage, unable to commit volume snapshot as image", - "en_US": "can not find image store backup storage, unable to commit volume snapshot as image", - "zh_CN": "", - "arguments": [], - "line": 602, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "raw": "%s can only be created or deleted", + "en_US": "{0} can only be created or deleted", + "zh_CN": "只能创建或删除{0}", + "arguments": [ + "releaseTag" + ], + "line": 386, + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceManagerImpl.java" }, { - "raw": "cannot find backupStorage for volume: %s", - "en_US": "cannot find backupStorage for volume: {0}", - "zh_CN": "", + "raw": "%s can only be created or deleted when the baremetal2 instance is Running", + "en_US": "{0} can only be created or deleted when the baremetal2 instance is Running", + "zh_CN": "只能在运行BareMetal2实例时创建或删除{0}", "arguments": [ - "vivo.getRootVolumeUuid()" + "releaseTag" ], "line": 397, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "fileName": "src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceManagerImpl.java" }, { - "raw": "vm running on local storage %s state is %s not running/stopped/paused, can not attach volume", - "en_US": "vm running on local storage {0} state is {1} not running/stopped/paused, can not attach volume", - "zh_CN": "", + "raw": "there already exists a baremetal2 provision network with dhcpInterface \u003d %s, dhcpRangeStartIp \u003d %s, dhcpRangeEndIp \u003d %s, dhcpRangeNetmask \u003d %s, dhcpRangeGateway \u003d %s", + "en_US": "there already exists a baremetal2 provision network with dhcpInterface \u003d {0}, dhcpRangeStartIp \u003d {1}, dhcpRangeEndIp \u003d {2}, dhcpRangeNetmask \u003d {3}, dhcpRangeGateway \u003d {4}", + "zh_CN": "已存在DHCPINTERFACE\u003d{0}、DHCPRANGESTARTIP\u003d{1}、DHCPRANGEENDIP\u003d{2}、DhcpRangeNetMask\u003d{3}、DhcpRangeGateway\u003d{4}的BareMetal2配置网络", "arguments": [ - "inv.getInventory().getUuid()", - "state" + "dhcpInterface", + "dhcpRangeStartIp", + "dhcpRangeEndIp", + "dhcpRangeNetmask", + "dhcpRangeGateway" ], - "line": 898, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 112, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "Destination PrimaryStorageType is %s, but the selected BackupStorageType for source Volume is %s, which cannot be matched", - "en_US": "Destination PrimaryStorageType is {0}, but the selected BackupStorageType for source Volume is {1}, which cannot be matched", - "zh_CN": "", + "raw": "cannot update baremetal2 provision network[uuid:%s] dhcp configuration when there are instances depending on it", + "en_US": "cannot update baremetal2 provision network[uuid:{0}] dhcp configuration when there are instances depending on it", + "zh_CN": "当有实例依赖于网络[uuid:{0}]DHCP配置时,无法更新该配置", "arguments": [ - "pvo.getType()", - "bsType" + "msg.getNetworkUuid()" ], - "line": 1120, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" - }, - { - "raw": "direction must be set to in or out", - "en_US": "direction must be set to in or out", - "zh_CN": "方法必须设置in或者out", - "arguments": [], - "line": 1507, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 123, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "inboundBandwidth must be set no more than %s.", - "en_US": "inboundBandwidth must be set no more than {0}.", - "zh_CN": "下行带宽不能超过{0}", + "raw": "baremetal2 provision network dhcp range netmask %s is invalid", + "en_US": "baremetal2 provision network dhcp range netmask {0} is invalid", + "zh_CN": "Baremetal2设置网络DHCP范围网络掩码{0}无效", "arguments": [ - "inbound" + "netmask" ], - "line": 1549, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 141, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "outboundBandwidth must be set no more than %s.", - "en_US": "outboundBandwidth must be set no more than {0}.", - "zh_CN": "上行带宽不能超过{0}", + "raw": "baremetal2 provision network start ip %s and stop ip %s do not belong to the same subnet", + "en_US": "baremetal2 provision network start ip {0} and stop ip {1} do not belong to the same subnet", + "zh_CN": "Baremetal2配置网络启动IP{0}和停止IP{1}不属于同一子网", "arguments": [ - "outbound" + "begin", + "end" ], - "line": 1560, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 147, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "vm [%s]\u0027 state must be Running or Paused to sync nic qos", - "en_US": "vm [{0}]\u0027 state must be Running or Paused to sync nic qos", - "zh_CN": "", + "raw": "cannot delete baremetal2 provision network[uuid:%s] when there are instances depending on it", + "en_US": "cannot delete baremetal2 provision network[uuid:{0}] when there are instances depending on it", + "zh_CN": "有实例依赖于BareMetal2配置网络[uuid:{0}]时,无法删除该网络", "arguments": [ - "self.getUuid()" + "msg.getNetworkUuid()" ], - "line": 1651, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" - }, - { - "raw": "vm [%s]\u0027s HostUuid is null, cannot sync nic qos", - "en_US": "vm [{0}]\u0027s HostUuid is null, cannot sync nic qos", - "zh_CN": "", - "arguments": [], - "line": 1656, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 157, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "not dest host found in db by uuid: %s, can\u0027t send change password cmd to the host!", - "en_US": "not dest host found in db by uuid: {0}, can\u0027t send change password cmd to the host!", - "zh_CN": "没有在物理机{0}上发现数据库,不能发送更改密码的指令到这个物理机上", + "raw": "cannot attach baremetal2 provision network[uuid:%s] to non-baremetal2 cluster[uuid:%s]", + "en_US": "cannot attach baremetal2 provision network[uuid:{0}] to non-baremetal2 cluster[uuid:{1}]", + "zh_CN": "无法将BareMetal2设置网络[uuid:{0}]连接到非BareMetal2集群[uuid:{1}]", "arguments": [ - "amsg.getVmInstanceUuid()" + "msg.getNetworkUuid()", + "msg.getClusterUuid()" ], - "line": 2056, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" - }, - { - "raw": "state is not correct while change password.", - "en_US": "state is not correct while change password.", - "zh_CN": "该状态不支持修改密码", - "arguments": [], - "line": 2084, - "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + "line": 171, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "vm[uuid:%s] cdRom deviceId repetition", - "en_US": "vm[uuid:{0}] cdRom deviceId repetition", - "zh_CN": "", + "raw": "baremetal2 provision network[uuid:%s] is already attached to cluster[uuid:%s]", + "en_US": "baremetal2 provision network[uuid:{0}] is already attached to cluster[uuid:{1}]", + "zh_CN": "Baremetal2配置网络[uuid:{0}]已连接到集群[uuid:{1}]", "arguments": [ - "spec.getVmInventory().getUuid()" + "msg.getNetworkUuid()", + "msg.getClusterUuid()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/compute/vm/VmAllocateCdRomFlow.java" + "line": 182, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "there is no available ipRange on L3 network [%s]", - "en_US": "there is no available ipRange on L3 network [{0}]", - "zh_CN": "L3网络[{0}]中没有可用的网络段", + "raw": "cannot attach baremetal2 provision network[uuid:%s] to cluster[uuid:%s] because the cluster already have one", + "en_US": "cannot attach baremetal2 provision network[uuid:{0}] to cluster[uuid:{1}] because the cluster already have one", + "zh_CN": "无法将BareMetal2设置网络[uuid:{0}]附加到集群[uuid:{1}],因为该集群已有一个网络", "arguments": [ - "v.getUuid()" + "msg.getNetworkUuid()", + "msg.getClusterUuid()" ], - "line": 81, - "fileName": "src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java" + "line": 188, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": " Can not find the vm\u0027s host, please start the vm[%s], then mount the disk", - "en_US": " Can not find the vm\u0027s host, please start the vm[{0}], then mount the disk", - "zh_CN": "未找到虚拟机的物理机,请重启虚拟机[{0}],然后挂载云盘", + "raw": "cannot attach baremetal2 provision network[uuid:%s] to cluster[uuid:%s] because they are not in the same zone", + "en_US": "cannot attach baremetal2 provision network[uuid:{0}] to cluster[uuid:{1}] because they are not in the same zone", + "zh_CN": "无法将BareMetal2配置网络[uuid:{0}]附加到集群[uuid:{1}],因为它们不在同一区域中", "arguments": [ - "spec.getVmInventory().getUuid()" + "msg.getNetworkUuid()", + "msg.getClusterUuid()" ], - "line": 49, - "fileName": "src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java" + "line": 198, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "cannot find the iso[uuid:%s] in any connected backup storage attached to the zone[uuid:%s]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is running\\n2. if the backup storage is in connected status, if not, try reconnecting it", - "en_US": "cannot find the iso[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is running\\n2. if the backup storage is in connected status, if not, try reconnecting it", - "zh_CN": "不能发现iso[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \\n1. 镜像服务器是否已经挂载到区域中的任何运行状态的云主机[name: {2}, uuid:{3}]上;\\n2. 如果镜像服务器不是处于连接状态,请尝试重连", + "raw": "cannot attach baremetal2 provision network[uuid:%s] to cluster[uuid:%s], because we need to make sure that every gateway attached to the clusters that have the same provision network attached", + "en_US": "cannot attach baremetal2 provision network[uuid:{0}] to cluster[uuid:{1}], because we need to make sure that every gateway attached to the clusters that have the same provision network attached", + "zh_CN": "无法将BareMetal2配置网络[uuid:{0}]连接到集群[uuid:{1}],因为我们需要确保连接到具有相同配置网络的集群的每个网关", "arguments": [ - "iso.getUuid()", - "host.getZoneUuid()", - "spec.getVmInventory().getName()", - "spec.getVmInventory().getUuid()" + "msg.getNetworkUuid()", + "msg.getClusterUuid()" ], - "line": 68, - "fileName": "src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java" + "line": 219, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "cannot find the image[uuid:%s] in any connected backup storage. check below:\\n1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", - "en_US": "cannot find the image[uuid:{0}] in any connected backup storage. check below:\\n1. if the backup storage is attached to the zone where the VM[name: {1}, uuid:{2}] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", - "zh_CN": "不能发现镜像[uuid:{0}]在任何处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \\n1. 镜像服务器是否已经过载到区域中的云主机[name: {1}, uuid:{2}]中;\\n2. 如果镜像服务器不是处于连接状态,请尝试重连", - "arguments": [ - "imageUuid", - "spec.getVmInventory().getName()", - "spec.getVmInventory().getUuid()" - ], - "line": 92, - "fileName": "src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java" + "raw": "provision network should not have the same interface name with l2 networks that are already attached to the cluster", + "en_US": "provision network should not have the same interface name with l2 networks that are already attached to the cluster", + "zh_CN": "设置网络不应与已连接到集群的二层网络具有相同的接口名称", + "arguments": [], + "line": 241, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "cannot find the image[uuid:%s] in any connected backup storage attached to the zone[uuid:%s]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", - "en_US": "cannot find the image[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", - "zh_CN": "不能发现镜像[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \\n1. 镜像服务器是否已经过载到区域中的云主机[name: {2}, uuid:{3}]中;\\n2. 如果镜像服务器不是处于Connected状态,请尝试重连", + "raw": "cannot detach baremetal2 provision network[uuid:%s] when there are running instances depending on it", + "en_US": "cannot detach baremetal2 provision network[uuid:{0}] when there are running instances depending on it", + "zh_CN": "存在依赖于Baremetal2配置网络[uuid:{0}]的正在运行的实例时,无法分离该网络", "arguments": [ - "imageUuid", - "spec.getVmInventory().getZoneUuid()", - "spec.getVmInventory().getName()", - "spec.getVmInventory().getUuid()" + "msg.getNetworkUuid()" ], - "line": 86, - "fileName": "src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java" + "line": 251, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "no backup storage attached to the zone[uuid:%s] contains the ISO[uuid:%s]", - "en_US": "no backup storage attached to the zone[uuid:{0}] contains the ISO[uuid:{1}]", - "zh_CN": "没有包含着ISO[uuid:{1}]的镜像服务器添加到区域[uuid:{0}]", + "raw": "networkUuids is empty", + "en_US": "networkUuids is empty", + "zh_CN": "网络uuid为空", + "arguments": [], + "line": 258, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" + }, + { + "raw": "not all baremetal2 provision networks exist in %s", + "en_US": "not all baremetal2 provision networks exist in {0}", + "zh_CN": "{0}中并不存在所有BareMetal2配置网络", "arguments": [ - "zoneUuid", - "isoImageUuid" + "msg.getNetworkUuids()" ], - "line": 114, - "fileName": "src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java" + "line": 265, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java" }, { - "raw": "VM[uuid:%s] already has an ISO[uuid:%s] attached", - "en_US": "VM[uuid:{0}] already has an ISO[uuid:{1}] attached", - "zh_CN": "云主机[uuid:{0}]已经挂载了ISO[uuid:{1}]", + "raw": "failed to prepare provision network[uuid:%s] in gateway[uuid:%s]: %s", + "en_US": "failed to prepare provision network[uuid:{0}] in gateway[uuid:{1}]: {2}", + "zh_CN": "无法准备设置网络[uuid:{0}](在网关[uuid:{1}]中):{2}", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getIsoUuid()" + "networkUuid", + "gatewayUuid", + "reply.getError()" ], - "line": 341, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 496, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java" }, { - "raw": "there are %d ipv4 network on same nic", - "en_US": "there are {0} ipv4 network on same nic", - "zh_CN": "", + "raw": "failed to update provision network[uuid:%s] in gateway[uuid:%s]: %s", + "en_US": "failed to update provision network[uuid:{0}] in gateway[uuid:{1}]: {2}", + "zh_CN": "无法更新设置网络[uuid:{0}](在网关[uuid:{1}]中):{2}", "arguments": [ - "ipv4Count" + "networkUuid", + "gatewayUuid", + "reply.getError()" ], - "line": 500, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 308, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java" }, { - "raw": "Can not create CD-ROM for vm[uuid:%s] which is in state[%s] ", - "en_US": "Can not create CD-ROM for vm[uuid:{0}] which is in state[{1}] ", - "zh_CN": "", + "raw": "failed to allocate ip from baremetal2 provision network[uuid:%s]", + "en_US": "failed to allocate ip from baremetal2 provision network[uuid:{0}]", + "zh_CN": "无法从BareMetal2配置网络[uuid:{0}]分配IP", "arguments": [ - "msg.getVmInstanceUuid()", - "vo.getState().toString()" + "msg.getNetworkUuid()" ], - "line": 133, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 650, + "fileName": "src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java" }, { - "raw": "rootDiskSize is needed when image media type is ISO", - "en_US": "rootDiskSize is needed when image media type is ISO", - "zh_CN": "当镜像类型是ISO时根云盘大小需要设置", + "raw": "billing is disabled", + "en_US": "billing is disabled", + "zh_CN": "已禁用计费", "arguments": [], - "line": 141, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 73, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "the vm[uuid:%s] is already on host[uuid:%s]", - "en_US": "the vm[uuid:{0}] is already on host[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]已经运行于物理机[uuid:{1}]上", - "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getHostUuid()" - ], - "line": 151, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "the start date must be greater than the end date", + "en_US": "the start date must be greater than the end date", + "zh_CN": "开始时间必须早于结束时间", + "arguments": [], + "line": 120, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "the VM cannot do online cpu/memory update because it is not of NUMA architecture. Please stop the VM then do the cpu/memory update again", - "en_US": "the VM cannot do online cpu/memory update because it is not of NUMA architecture. Please stop the VM then do the cpu/memory update again", - "zh_CN": "云主机无法执行在线升级CPU/内存,因为不是NUMA架构。请关闭该云主机再尝试", + "raw": "resourceType and resourceUuid cannot be empty at the same time", + "en_US": "resourceType and resourceUuid cannot be empty at the same time", + "zh_CN": "ResourceType和Resourceuuid不能同时为空", "arguments": [], - "line": 207, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 124, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "The state of vm[uuid:%s] is %s. Only these state[%s] is allowed to update cpu or memory.", - "en_US": "The state of vm[uuid:{0}] is {1}. Only these state[{2}] is allowed to update cpu or memory.", - "zh_CN": "云主机[uuid:{0}]的状态为{1}。只有这些状态[{2}]允许在线升级CPU/内存", + "raw": "the minimal resource unit is megabyte, cannot be byte", + "en_US": "the minimal resource unit is megabyte, cannot be byte", + "zh_CN": "资源的最小单位必须为MB,而不是byte", + "arguments": [], + "line": 244, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + }, + { + "raw": "price must be 0 and 999999999.99", + "en_US": "price must be 0 and 999999999.99", + "zh_CN": "价格必须为0和999999999.99", + "arguments": [], + "line": 252, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + }, + { + "raw": "gpu price must be bound to gpu uuid empty", + "en_US": "gpu price must be bound to gpu uuid empty", + "zh_CN": "GPU类型的价格必须绑定一个GPU设备", + "arguments": [], + "line": 259, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" + }, + { + "raw": "gpu price must be bound to gpu uuid %s", + "en_US": "gpu price must be bound to gpu uuid {0}", + "zh_CN": "GPU类型的价格必须绑定一个正确的GPU设备{0}", "arguments": [ - "vo.getUuid()", - "vo.getState()", - "StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), \",\")" + "price.getSystemTags()" ], - "line": 213, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 266, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "can\u0027t decrease capacity when vm[uuid:%s] is running", - "en_US": "can\u0027t decrease capacity when vm[uuid:{0}] is running", - "zh_CN": "无法在云主机[uuid:{0}]运行时减少容量", + "raw": "resourceName[%s] is invalid", + "en_US": "resourceName[{0}] is invalid", + "zh_CN": "资源名称[{0}]无效", "arguments": [ - "vo.getUuid()" + "resourceName" ], - "line": 184, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 226, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "can\u0027t decrease cpu of vm[uuid:%s] when it is running", - "en_US": "can\u0027t decrease cpu of vm[uuid:{0}] when it is running", - "zh_CN": "无法在云主机[uuid:{0}]运行时减少CPU数目", + "raw": "The account[uuid\u003d%s] has attach price table", + "en_US": "The account[uuid\u003d{0}] has attach price table", + "zh_CN": "帐户[uuid\u003d{0}]具有附加价格表", "arguments": [ - "vo.getUuid()" + "msg.getAccountUuid()" ], - "line": 224, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 278, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "can\u0027t decrease memory size of vm[uuid:%s] when it is running", - "en_US": "can\u0027t decrease memory size of vm[uuid:{0}] when it is running", - "zh_CN": "无法在云主机[uuid:{0}]运行时减少容量", + "raw": "This priceTable[uuid\u003d%s] is not allowed to delete", + "en_US": "This priceTable[uuid\u003d{0}] is not allowed to delete", + "zh_CN": "不允许删除此价格表[uuid\u003d{0}]", "arguments": [ - "vo.getUuid()" + "msg.getUuid()" ], - "line": 230, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 284, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "either l3NetworkUuids or imageUuid must be set", - "en_US": "either l3NetworkUuids or imageUuid must be set", - "zh_CN": "L3网络的uuid们或者镜像的uuid必须被设置", + "raw": "accountUuid/tableUuid only one of them is allowed to be set", + "en_US": "accountUuid/tableUuid only one of them is allowed to be set", + "zh_CN": "Accountuuid/Tableuuid只允许设置其中一个", "arguments": [], - "line": 241, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 298, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "%s is not a valid IPv4 address", - "en_US": "{0} is not a valid IPv4 address", - "zh_CN": "{0}不是有效的IPv4地址", - "arguments": [ - "ip" - ], - "line": 256, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "endDateInLong is not allowed to be negative", + "en_US": "endDateInLong is not allowed to be negative", + "zh_CN": "EndDateInLong不允许为负数", + "arguments": [], + "line": 304, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "ip address [%s] already set to vmNic [uuid:%s]", - "en_US": "ip address [{0}] already set to vmNic [uuid:{1}]", - "zh_CN": "IP地址[{0}]已经设置到网卡[uuid:{1}]", - "arguments": [ - "ip", - "vmNicVO.getUuid()" - ], - "line": 282, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "endDateInLong and setEndDateInLongBaseOnCurrentTime are not allowed to set at the same time", + "en_US": "endDateInLong and setEndDateInLongBaseOnCurrentTime are not allowed to set at the same time", + "zh_CN": "不允许同时设置EndDateInLong和SetEndDateInLongBaseOnCurrentTime", + "arguments": [], + "line": 308, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "ip address [%s] is not in ip range [%s]", - "en_US": "ip address [{0}] is not in ip range [{1}]", - "zh_CN": "IP地址[{0}]不在IP地址段[{1}]范围内", - "arguments": [ - "ip", - "rangeVO.getNetworkCidr()" - ], - "line": 267, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "endDateInLong is set, no modification allowed", + "en_US": "endDateInLong is set, no modification allowed", + "zh_CN": "EndDateInLong已设置,不允许修改", + "arguments": [], + "line": 321, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "%s is not a valid IPv6 address", - "en_US": "{0} is not a valid IPv6 address", - "zh_CN": "{0}不是有效的IPv6地址", - "arguments": [ - "ip" - ], - "line": 276, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "endDateInLong cannot be earlier than dateInLong", + "en_US": "endDateInLong cannot be earlier than dateInLong", + "zh_CN": "EndDateInlong不能早于DateInlong", + "arguments": [], + "line": 329, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "ip address [%s] is not in ip range [startIp %s, endIp %s]", - "en_US": "ip address [{0}] is not in ip range [startIp {1}, endIp {2}]", - "zh_CN": "IP地址[{0}]不在IP地址段[{1}-{2}]范围内", - "arguments": [ - "ip", - "rangeVO.getStartIp()", - "rangeVO.getEndIp()" - ], - "line": 287, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "billing is enable, This operation is only allowed in the disabled state", + "en_US": "billing is enable, This operation is only allowed in the disabled state", + "zh_CN": "计费已启用,只有在禁用状态下才能执行此操作", + "arguments": [], + "line": 336, + "fileName": "src/main/java/org/zstack/billing/BillingApiInterceptor.java" }, { - "raw": "the VM[uuid:%s] has no nic on the L3 network[uuid:%s]", - "en_US": "the VM[uuid:{0}] has no nic on the L3 network[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]在L3网络[uuid:{1}]上没有任何网卡", - "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getL3NetworkUuid()" - ], - "line": 321, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "priceKeyName is null", + "en_US": "priceKeyName is null", + "zh_CN": "PriceKeyName为空", + "arguments": [], + "line": 451, + "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" }, { - "raw": "invalid boot device[%s] in boot order%s", - "en_US": "invalid boot device[{0}] in boot order{1}", - "zh_CN": "在启动列表{1}中的设备[{0}]启动失败", + "raw": "dateInLong is less than %s", + "en_US": "dateInLong is less than {0}", + "zh_CN": "DateInLong小于{0}", "arguments": [ - "o", - "msg.getBootOrder()" + "currentPriceVO.getDateInLong()" ], - "line": 332, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1084, + "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" }, { - "raw": "The cdRom[uuid:%s] does not exist", - "en_US": "The cdRom[uuid:{0}] does not exist", - "zh_CN": "", - "arguments": [ - "cdRomUuid" - ], - "line": 356, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "please set the correct priceUserConfig, for example: priceUserConfig:{\\nrootVolume:{\\npriceKeyName:\\\"priceKeyName\\\"}}", + "en_US": "please set the correct priceUserConfig, for example: priceUserConfig:{\\nrootVolume:{\\npriceKeyName:\\\"priceKeyName\\\"}}", + "zh_CN": "请设置正确的priceUserConfig,例如:priceUserConfig:{\\nRootVolume:{\\nPriceKeyName:\\“ priceKeyName\\”}}", + "arguments": [], + "line": 3090, + "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" }, { - "raw": "VM[uuid:%s] cdRom[uuid:%s] has mounted the ISO", - "en_US": "VM[uuid:{0}] cdRom[uuid:{1}] has mounted the ISO", - "zh_CN": "", - "arguments": [ - "msg.getVmInstanceUuid()", - "cdRomUuid" - ], - "line": 360, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "please set the correct priceUserConfig, for example: priceUserConfig:{\\nvolume:{\\npriceKeyName:\\\"priceKeyName\\\"}}", + "en_US": "please set the correct priceUserConfig, for example: priceUserConfig:{\\nvolume:{\\npriceKeyName:\\\"priceKeyName\\\"}}", + "zh_CN": "请设置正确的priceUserConfig,例如:priceUserConfig:{\\nVolume:{\\nPriceKeyName:\\“ priceKeyName\\”}}", + "arguments": [], + "line": 3105, + "fileName": "src/main/java/org/zstack/billing/BillingManagerImpl.java" }, { - "raw": "VM[uuid:%s] has multiple ISOs attached, specify the isoUuid when detaching", - "en_US": "VM[uuid:{0}] has multiple ISOs attached, specify the isoUuid when detaching", - "zh_CN": "云主机[uuid:{0}]已经加载了多个ISO,卸载ISO时需要指定ISO的Uuid", + "raw": "unsupported billing resource type [%s]", + "en_US": "unsupported billing resource type [{0}]", + "zh_CN": "不支持的计费资源类型[{0}]", "arguments": [ - "msg.getVmInstanceUuid()" + "resourceType" ], - "line": 378, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 49, + "fileName": "src/main/java/org/zstack/billing/ResourceSpendingHelper.java" }, { - "raw": "unable to attach a L3 network. The L3 network[uuid:%s] is disabled", - "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] is disabled", - "zh_CN": "不能挂载L3网络,因为该L3网络[uuid:{0}]处于未启动状态", + "raw": "there is no such type[%s] in CAS", + "en_US": "there is no such type[{0}] in CAS", + "zh_CN": "CAS中没有此类型[{0}]", "arguments": [ - "l3Uuid" + "type" ], - "line": 482, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 31, + "fileName": "src/main/java/org/zstack/cas/CasInterceptor.java" }, { - "raw": "the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", - "en_US": "the static IP[{0}] is not in any IP range of the L3 network[uuid:{1}]", - "zh_CN": "该静态IP[{0}]不在L3网络[uuid:{1}]的任何IP段", + "raw": "wrong virtual ID[name:%s], not existing or wrong password", + "en_US": "wrong virtual ID[name:{0}], not existing or wrong password", + "zh_CN": "错误的virtual ID[名称:{0}], 密码不存在或者密码错误", "arguments": [ - "staticIp", - "l3Uuid" + "loginContext.getUsername()" ], - "line": 553, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 76, + "fileName": "src/main/java/org/zstack/cas/CasLoginBackend.java" }, { - "raw": "the static IP[%s] has been occupied on the L3 network[uuid:%s]", - "en_US": "the static IP[{0}] has been occupied on the L3 network[uuid:{1}]", - "zh_CN": "该静态IP[{0}]已经存在在L3网络[uuid:{1}]中", + "raw": "missing property of cas driver", + "en_US": "missing property of cas driver", + "zh_CN": "缺少CAS驱动程序的属性", + "arguments": [], + "line": 57, + "fileName": "src/main/java/org/zstack/cas/CasLoginBackend.java" + }, + { + "raw": "Unsupported cas driver: %s", + "en_US": "Unsupported cas driver: {0}", + "zh_CN": "不支持的CAS驱动程序:{0}", "arguments": [ - "staticIp", - "l3Uuid" + "casDriverType" ], - "line": 560, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 64, + "fileName": "src/main/java/org/zstack/cas/CasLoginBackend.java" }, { - "raw": "unable to attach a L3 network. The vm[uuid: %s] is not Running or Stopped; the current state is %s", - "en_US": "unable to attach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", - "zh_CN": "无法挂载L3网络。云主机[uuid: {0}]既不处于Running也不处于Stopped状态中,当前状态为{1}", + "raw": "cannot find such ResourceStackVO by uuid [%s]", + "en_US": "cannot find such ResourceStackVO by uuid [{0}]", + "zh_CN": "无法通过uuid[{0}]找到此类ResourceStackVO", "arguments": [ - "msg.getVmInstanceUuid()", - "state" + "msg.getUuid()" ], - "line": 432, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 63, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "unable to attach a L3 network. The L3 network[uuid:%s] are belonged to different l2 networks [uuids:%s]", - "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to different l2 networks [uuids:{1}]", - "zh_CN": "不能挂载L3网络,L3网络[uuid:{0}]属于不同的L2网络", + "raw": "restart resource stack only support %s status!", + "en_US": "restart resource stack only support {0} status!", + "zh_CN": "重新启动资源堆栈仅支持{0}状态!", "arguments": [ - "newAddedL3Uuids", - "l2Uuids" - ], - "line": 446, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" - }, - { - "raw": "unable to attach a L3 network. The L3 network[uuid:%s] are belonged to l2 networks [uuids:%s] that have not been attached to any cluster", - "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to l2 networks [uuids:{1}] that have not been attached to any cluster", - "zh_CN": "", - "arguments": [ - "newAddedL3Uuids", - "l2Uuids" - ], - "line": 453, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" - }, - { - "raw": "unable to attach a L3 network. The L3 network[uuid:%s] is already attached to the vm[uuid: %s]", - "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", - "zh_CN": "不能挂载L3网络,l3网络[uuid:{0}]已经挂载到云主机[uuid: {1}]上了", - "arguments": [ - "attachedL3Uuids", - "msg.getVmInstanceUuid()" - ], - "line": 465, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" - }, - { - "raw": "unable to attach a non-guest L3 network. The L3 network[uuid:%s] is already attached to the vm[uuid: %s]", - "en_US": "unable to attach a non-guest L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", - "zh_CN": "", - "arguments": [ - "attachedL3Uuids", - "msg.getVmInstanceUuid()" + "validStatus" ], - "line": 472, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 67, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "unable to attach a L3 network. The L3 network[uuid:%s] is a system network and vm is a user vm", - "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] is a system network and vm is a user vm", - "zh_CN": "不能连接三层网络。这个三层网络[uuid:{0}]是系统网络,但虚拟机是一个用户虚拟机", - "arguments": [ - "l3Uuid" - ], - "line": 485, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "templateContent and uuid mustn\u0027t both be empty or both be set!", + "en_US": "templateContent and uuid mustn\u0027t both be empty or both be set!", + "zh_CN": "TemplateContent和uuid不能同时为空或同时设置!", + "arguments": [], + "line": 173, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "there are %d ipv6 stateful or stateless network on same nic", - "en_US": "there are {0} ipv6 stateful or stateless network on same nic", - "zh_CN": "不能挂载L3网络,有{0}个Stateful-DHCP类型或者Stateless-DHCP类型的网络属于同一个网卡", + "raw": "expect %s status!", + "en_US": "expect {0} status!", + "zh_CN": "预期{0}状态!", "arguments": [ - "statefulIpv6" + "validStatus" ], - "line": 503, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 98, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "static ip l3 uuid[%s] is not included in nic l3 [%s]", - "en_US": "static ip l3 uuid[{0}] is not included in nic l3 [{1}]", - "zh_CN": "静态IP的L3网络[uuid:{0}]不在网卡的L3列表[uuid:{1}]中", - "arguments": [ - "e.getKey()", - "newAddedL3Uuids" - ], - "line": 535, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "templateContent and templateUuid mustn\u0027t both be empty!", + "en_US": "templateContent and templateUuid mustn\u0027t both be empty!", + "zh_CN": "TemplateContent和TemplateUuid不能同时为空!", + "arguments": [], + "line": 118, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "unable to attach the nic. The vm[uuid: %s] is not Running or Stopped; the current state is %s", - "en_US": "unable to attach the nic. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", - "zh_CN": "", - "arguments": [ - "msg.getVmInstanceUuid()", - "state" - ], - "line": 583, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "templateContent and url mustn\u0027t both be empty or both be set!", + "en_US": "templateContent and url mustn\u0027t both be empty or both be set!", + "zh_CN": "TemplateContent和URL不能同时为空或同时设置!", + "arguments": [], + "line": 129, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "unable to attach the nic. The nic has been attached with vm[uuid: %s]", - "en_US": "unable to attach the nic. The nic has been attached with vm[uuid: {0}]", - "zh_CN": "", - "arguments": [ - "vmNicVO.getVmInstanceUuid()" - ], - "line": 590, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "only admin could enable/disable system StackTemplate", + "en_US": "only admin could enable/disable system StackTemplate", + "zh_CN": "只有管理员才能启用/禁用系统堆栈模板", + "arguments": [], + "line": 145, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java" }, { - "raw": "unable to attach the nic. Its L3 network[uuid:%s] is already attached to the vm[uuid: %s]", - "en_US": "unable to attach the nic. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", - "zh_CN": "", + "raw": "cannot delete or update system template: %s", + "en_US": "cannot delete or update system template: {0}", + "zh_CN": "无法删除或更新系统模板:{0}", "arguments": [ - "vmNicVO.getL3NetworkUuid()", - "msg.getVmInstanceUuid()" + "vo.getName()" ], - "line": 601, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1032, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "unable to attach the nic with a non-guest L3 network. Its L3 network[uuid:%s] is already attached to the vm[uuid: %s]", - "en_US": "unable to attach the nic with a non-guest L3 network. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", - "zh_CN": "", + "raw": "no stackUuid found for the vmInstance[%s]", + "en_US": "no stackUuid found for the vmInstance[{0}]", + "zh_CN": "找不到VMInstance[{0}]stackUuid", "arguments": [ - "vmNicVO.getL3NetworkUuid()", "msg.getVmInstanceUuid()" ], - "line": 606, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 322, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "unable to attach the nic. Its L3 network[uuid:%s] is disabled", - "en_US": "unable to attach the nic. Its L3 network[uuid:{0}] is disabled", - "zh_CN": "", + "raw": "ResourceStackVO: [%s] has been deleted...", + "en_US": "ResourceStackVO: [{0}] has been deleted...", + "zh_CN": "ResourceStackVO:[{0}]已被删除..", "arguments": [ - "l3NetworkVO.getUuid()" + "msg.getUuid()" ], - "line": 615, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 612, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "unable to attach the nic. Its L3 network[uuid:%s] is a system network and vm is a user vm", - "en_US": "unable to attach the nic. Its L3 network[uuid:{0}] is a system network and vm is a user vm", - "zh_CN": "", + "raw": "ResourceStackVO [%s] already been deleted!", + "en_US": "ResourceStackVO [{0}] already been deleted!", + "zh_CN": "ResourceStackVO[{0}]已被删除!", "arguments": [ - "l3NetworkVO.getUuid()" + "uuid" ], - "line": 618, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 642, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "unable to attach the nic. Its l2 network [uuid:%s] that have not been attached to any cluster", - "en_US": "unable to attach the nic. Its l2 network [uuid:{0}] that have not been attached to any cluster", - "zh_CN": "", - "arguments": [ - "l3NetworkVO.getL2NetworkUuid()" - ], - "line": 625, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "templateContent must be set!", + "en_US": "templateContent must be set!", + "zh_CN": "必须设置TemplateContent!", + "arguments": [], + "line": 871, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "unable to detach a L3 network. The vm[uuid: %s] is not Running or Stopped; the current state is %s", - "en_US": "unable to detach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", - "zh_CN": "不能卸载L3网络,云主机[uuid: {0}]不是运行状态或者暂停状态,状态为{1}", + "raw": "template [%s] chosen is disabled", + "en_US": "template [{0}] chosen is disabled", + "zh_CN": "所选模板[{0}]已禁用", "arguments": [ - "msg.getVmInstanceUuid()", - "state" + "template.getUuid()" ], - "line": 640, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 865, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "vm[uuid:%s] can only attach volume when state is Running or Stopped, current state is %s", - "en_US": "vm[uuid:{0}] can only attach volume when state is Running or Stopped, current state is {1}", - "zh_CN": "云主机[uuid:{0}]挂载盘时状态只能是运行或者暂停状态,而现在的状态是{1}", + "raw": "cannot find parameters for %s, which is %s type, please check parameters", + "en_US": "cannot find parameters for {0}, which is {1} type, please check parameters", + "zh_CN": "找不到{1}类型的{0}的参数,请检查参数", "arguments": [ - "msg.getVmInstanceUuid()", - "state" + "p.getParamName()", + "p.getResourceType()" ], - "line": 666, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 955, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "image mediaType is ISO but missing root disk settings", - "en_US": "image mediaType is ISO but missing root disk settings", - "zh_CN": "", + "raw": "StackTemplateVO has been deleted...", + "en_US": "StackTemplateVO has been deleted...", + "zh_CN": "StackTemplateVo已被删除..", "arguments": [], - "line": 674, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1025, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "Unexpected root disk settings", - "en_US": "Unexpected root disk settings", - "zh_CN": "", + "raw": "content must be set by templateContent or url!", + "en_US": "content must be set by templateContent or url!", + "zh_CN": "必须通过TemplateContent或URL设置内容!", "arguments": [], - "line": 678, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1048, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "Missing CPU/memory settings", - "en_US": "Missing CPU/memory settings", - "zh_CN": "", + "raw": "get null content input", + "en_US": "get null content input", + "zh_CN": "获取空内容输入", "arguments": [], - "line": 689, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1066, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "Unexpected CPU/memory settings", - "en_US": "Unexpected CPU/memory settings", - "zh_CN": "", - "arguments": [], - "line": 693, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "invalid cloudformation template version: %s", + "en_US": "invalid cloudformation template version: {0}", + "zh_CN": "CloudFormation模板版本无效:{0}", + "arguments": [ + "result.getTemplateVersion()" + ], + "line": 1073, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "The image[uuid\u003d%s] does not exist", - "en_US": "The image[uuid\u003d{0}] does not exist", - "zh_CN": "", + "raw": "StackTemplateVO: [%s] has been deleted...", + "en_US": "StackTemplateVO: [{0}] has been deleted...", + "zh_CN": "StackTemplateVo:[{0}]已删除..", "arguments": [ - "cdRomIsoUuid" + "msg.getUuid()" ], - "line": 881, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1087, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "Do not allow to mount duplicate ISO", - "en_US": "Do not allow to mount duplicate ISO", - "zh_CN": "", + "raw": "[cloudformation] filterName must be cloudformation:true or cloudformation:false", + "en_US": "[cloudformation] filterName must be cloudformation:true or cloudformation:false", + "zh_CN": "[cloudFormation]FilterName必须为cloudFormation:true或cloudFormat:false", "arguments": [], - "line": 886, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 1385, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java" }, { - "raw": "The console password cannot start with \u0027password\u0027 which may trigger a VNC security issue", - "en_US": "The console password cannot start with \u0027password\u0027 which may trigger a VNC security issue", - "zh_CN": "控制台密码不能以password开头,这样可能导致一个VNC安全问题", + "raw": "get null element in template content", + "en_US": "get null element in template content", + "zh_CN": "获取模板内容中的空元素", "arguments": [], - "line": 901, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 31, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationUtils.java" }, { - "raw": "vmNic[uuid:%s] is not attached to vmInstance", - "en_US": "vmNic[uuid:{0}] is not attached to vmInstance", - "zh_CN": "网卡[uuid{0}]还没有绑定到云主机", - "arguments": [ - "msg.getVmNicUuid()" - ], - "line": 910, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "template must contain [ZStackTemplateFormatVersion]", + "en_US": "template must contain [ZStackTemplateFormatVersion]", + "zh_CN": "模板必须包含[ZStackTemplateFormatVersion]", + "arguments": [], + "line": 35, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationUtils.java" }, { - "raw": "L3 network[uuid:%s] has already been to attached vmNic[uuid:%s]", - "en_US": "L3 network[uuid:{0}] has already been to attached vmNic[uuid:{1}]", - "zh_CN": "三层网络[uuid:{0}]已经绑定到网卡[uuid:{1}]", + "raw": "invalid ZStackTemplateFormatVersion: [%s, expected: %s]", + "en_US": "invalid ZStackTemplateFormatVersion: [{0}, expected: {1}]", + "zh_CN": "无效的ZStackTemplateFormatVersion:[{0},应为:{1}]", "arguments": [ - "msg.getL3NetworkUuid()", - "msg.getVmNicUuid()" + "result.getTemplateVersion()", + "CloudFormationConstant.version" ], - "line": 917, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 38, + "fileName": "src/main/java/org/zstack/cloudformation/CloudFormationUtils.java" }, { - "raw": "there is another IPv6 stateful-dhcp network[uuid:%s] attached vmNic[uuid:%s]", - "en_US": "there is another IPv6 stateful-dhcp network[uuid:{0}] attached vmNic[uuid:{1}]", - "zh_CN": "已经有另外一个有状态的IPv6网络[uuid:{0}]绑定到网卡[uuid:{1}]", + "raw": "cannot find l2_bridge_name of l2[%s] from systemTag", + "en_US": "cannot find l2_bridge_name of l2[{0}] from systemTag", + "zh_CN": "在系统标记中找不到L2[{0}]的L 2_Bridge_名称", "arguments": [ - "ipVO.getL3NetworkUuid()", - "msg.getVmNicUuid()" + "l2Uuid" ], - "line": 937, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 124, + "fileName": "src/main/java/org/zstack/cloudformation/VmPortMonitorTask.java" }, { - "raw": "there is another IPv4 network[uuid:%s] attached vmNic[uuid:%s]", - "en_US": "there is another IPv4 network[uuid:{0}] attached vmNic[uuid:{1}]", - "zh_CN": "已经有另外一个IPv4网络[uuid:{0}]绑定到网卡[uuid:{1}]", + "raw": "cannot find default ip on vm[%s]", + "en_US": "cannot find default ip on vm[{0}]", + "zh_CN": "在云主机[{0}]上找不到默认IP", "arguments": [ - "ipVO.getL3NetworkUuid()", - "msg.getVmNicUuid()" + "vm.getUuid()" ], - "line": 926, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 135, + "fileName": "src/main/java/org/zstack/cloudformation/VmPortMonitorTask.java" }, { - "raw": "l2Network [uuid:%s] to be attached is different from l2Network [uuid:%s] of the nic", - "en_US": "l2Network [uuid:{0}] to be attached is different from l2Network [uuid:{1}] of the nic", - "zh_CN": "将被添加的二层网络[uuid:{0}]和网卡当前的二层网络[uuid:{1}]不同", - "arguments": [ - "l3Vo.getL2NetworkUuid()", - "oldL3.getL2NetworkUuid()" + "raw": "cannot find resource of properties set before!", + "en_US": "cannot find resource of properties set before!", + "zh_CN": "找不到以前设置的属性的资源!", + "arguments": [], + "line": 97, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + }, + { + "raw": "invalid dynamic variables, which must contained ${: %s", + "en_US": "invalid dynamic variables, which must contained ${: {0}", + "zh_CN": "动态变量无效,必须包含${:{0}", + "arguments": [ + "value" + ], + "line": 152, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + }, + { + "raw": "verb must contain \u0027::\u0027!", + "en_US": "verb must contain \u0027::\u0027!", + "zh_CN": "谓词必须包含“::”!", + "arguments": [], + "line": 174, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + }, + { + "raw": "need List for resource [%s] output here, but got %s.", + "en_US": "need List for resource [{0}] output here, but got {1}.", + "zh_CN": "此处需要资源[{0}]输出的列表,但获得了{1}。", + "arguments": [ + "t[0]", + "last.getClass().getName()" + ], + "line": 218, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + }, + { + "raw": "Some actions are invalid", + "en_US": "Some actions are invalid", + "zh_CN": "某些操作无效", + "arguments": [], + "line": 380, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java" + }, + { + "raw": "no root element found, please check your cfn formation!", + "en_US": "no root element found, please check your cfn formation!", + "zh_CN": "找不到根元素,请检查您的CFN结构!", + "arguments": [], + "line": 253, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java" + }, + { + "raw": "Wrong json format, causes: %s", + "en_US": "Wrong json format, causes: {0}", + "zh_CN": "错误的JSON格式,导致:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 432, + "fileName": "src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java" + }, + { + "raw": "CfnRootDecoder\u0027s weight must between 0-100, 0 means decode first, default is 50", + "en_US": "CfnRootDecoder\u0027s weight must between 0-100, 0 means decode first, default is 50", + "zh_CN": "cfnRootDecoder的权重必须介于0-100之间,0表示先解码,默认值为50", + "arguments": [], + "line": 14, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/AbstractCfnRootDecoder.java" + }, + { + "raw": "Condition body cannot support json null or array!", + "en_US": "Condition body cannot support json null or array!", + "zh_CN": "条件体不支持JSON NULL或数组!", + "arguments": [], + "line": 45, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + }, + { + "raw": "Only support ZStack Template Functions in \u0027Condition\u0027 field!", + "en_US": "Only support ZStack Template Functions in \u0027Condition\u0027 field!", + "zh_CN": "仅支持“条件”字段中的ZStack模板函数!", + "arguments": [], + "line": 41, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + }, + { + "raw": "Value must be boolean in \u0027Condition\u0027 field", + "en_US": "Value must be boolean in \u0027Condition\u0027 field", + "zh_CN": "“条件”字段中的值必须为布尔值", + "arguments": [], + "line": 37, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + }, + { + "raw": "Condition key: %s only support 1 element in the json object of value, but got %d elements!", + "en_US": "Condition key: {0} only support 1 element in the json object of value, but got {1} elements!", + "zh_CN": "条件键:{0}在值为的JSON对象中只支持1个元素,但得到了{1}个元素!", + "arguments": [ + "key", + "es.size()" + ], + "line": 30, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java" + }, + { + "raw": "cannot find such msg: %s for create", + "en_US": "cannot find such msg: {0} for create", + "zh_CN": "无法为创建找到这样的消息:{0}", + "arguments": [ + "msg" + ], + "line": 91, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/DecoderUtils.java" + }, + { + "raw": "Mapping value body cannot support null!", + "en_US": "Mapping value body cannot support null!", + "zh_CN": "映射值正文不能支持Null!", + "arguments": [], + "line": 56, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java" + }, + { + "raw": "Mapping value body cannot support json array!", + "en_US": "Mapping value body cannot support json array!", + "zh_CN": "映射值主体不支持JSON数组!", + "arguments": [], + "line": 54, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java" + }, + { + "raw": "mappingName must be found in result, or it is invalid cfn json.", + "en_US": "mappingName must be found in result, or it is invalid cfn json.", + "zh_CN": "必须在结果中找到MappingName,否则它是无效的CFN JSON。", + "arguments": [], + "line": 66, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java" + }, + { + "raw": "Mapping body cannot support json null!", + "en_US": "Mapping body cannot support json null!", + "zh_CN": "映射体不支持JSON NULL!", + "arguments": [], + "line": 84, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + }, + { + "raw": "Mapping body cannot support non map value!", + "en_US": "Mapping body cannot support non map value!", + "zh_CN": "映射体不支持非映射值!", + "arguments": [], + "line": 82, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + }, + { + "raw": "Output body cannot support json null!", + "en_US": "Output body cannot support json null!", + "zh_CN": "输出正文不支持JSON NULL!", + "arguments": [], + "line": 57, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + }, + { + "raw": "Description in Outputs must be String type!", + "en_US": "Description in Outputs must be String type!", + "zh_CN": "输出中的描述必须是字符串类型!", + "arguments": [], + "line": 70, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java" + }, + { + "raw": "paramName must be found in result, or it is invalid cfn json.", + "en_US": "paramName must be found in result, or it is invalid cfn json.", + "zh_CN": "必须在结果中找到ParamName,否则它是无效的CFN JSON。", + "arguments": [], + "line": 59, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java" + }, + { + "raw": "Parameters root body must be json object!", + "en_US": "Parameters root body must be json object!", + "zh_CN": "参数根体必须是JSON对象!", + "arguments": [], + "line": 53, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/PreParameterDecoder.java" + }, + { + "raw": "Mappings root body must be json object!", + "en_US": "Mappings root body must be json object!", + "zh_CN": "映射根体必须是JSON对象!", + "arguments": [], + "line": 145, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "resourceName must be found in result, or it is invalid cfn json.", + "en_US": "resourceName must be found in result, or it is invalid cfn json.", + "zh_CN": "ResourceName必须在结果中找到,或者它是无效的CFN JSON。", + "arguments": [], + "line": 112, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "Parameters body cannot support null!", + "en_US": "Parameters body cannot support null!", + "zh_CN": "参数体不支持NULL!", + "arguments": [], + "line": 123, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "Resource value body cannot support null!", + "en_US": "Resource value body cannot support null!", + "zh_CN": "资源值体不能支持null!", + "arguments": [], + "line": 68, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "Resource %s cannot depends on itself, please check %s in Resource [%s]", + "en_US": "Resource {0} cannot depends on itself, please check {1} in Resource [{2}]", + "zh_CN": "资源{0}不能依赖自身,请检查资源[{2}]中的{1}", + "arguments": [ + "resource.getResourceName()", + "e.getKey()", + "resource.getResourceName()" + ], + "line": 48, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "Resource root body must be json object!", + "en_US": "Resource root body must be json object!", + "zh_CN": "资源根体必须是JSON对象!", + "arguments": [], + "line": 254, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "Resource Type must be String!", + "en_US": "Resource Type must be String!", + "zh_CN": "资源类型必须是字符串!", + "arguments": [], + "line": 216, + "fileName": "src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java" + }, + { + "raw": "cannot find condition[%s] in \u0027Conditions\u0027", + "en_US": "cannot find condition[{0}] in \u0027Conditions\u0027", + "zh_CN": "在“条件”中找不到条件[{0}]", + "arguments": [ + "cond" + ], + "line": 42, + "fileName": "src/main/java/org/zstack/cloudformation/template/function/IfTemplateFunction.java" + }, + { + "raw": "expect \u0027true\u0027, \u0027false\u0027 for the object, but got %s", + "en_US": "expect \u0027true\u0027, \u0027false\u0027 for the object, but got {0}", + "zh_CN": "该对象应为“ true ”和“ false ”,但得到了{0}", + "arguments": [ + "e.getAsString()" + ], + "line": 42, + "fileName": "src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java" + }, + { + "raw": "expect \u0027true\u0027, \u0027false\u0027 or an other Condition, current Conditions include: %s, but got %s", + "en_US": "expect \u0027true\u0027, \u0027false\u0027 or an other Condition, current Conditions include: {0}, but got {1}", + "zh_CN": "应为“ true ”、“ false ”或其他条件,当前条件包括:{0},但得到了{1}", + "arguments": [ + "keys", + "e.getAsString()" + ], + "line": 35, + "fileName": "src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java" + }, + { + "raw": "Fn::Select out of range, please check your json file!", + "en_US": "Fn::Select out of range, please check your json file!", + "zh_CN": "FN::选择超出范围,请检查您的JSON文件!", + "arguments": [], + "line": 83, + "fileName": "src/main/java/org/zstack/cloudformation/template/function/SelectTemplateFunction.java" + }, + { + "raw": "only functions can in Function, but found %s", + "en_US": "only functions can in Function, but found {0}", + "zh_CN": "只能在函数中使用函数,但找到了{0}", + "arguments": [ + "e.getKey()" + ], + "line": 75, + "fileName": "src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java" + }, + { + "raw": "element is null!", + "en_US": "element is null!", + "zh_CN": "元素为空!", + "arguments": [], + "line": 90, + "fileName": "src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java" + }, + { + "raw": "duplicate nic params", + "en_US": "duplicate nic params", + "zh_CN": "复制NIC参数", + "arguments": [], + "line": 26, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "l3NetworkUuid of vm nic can not be null", + "en_US": "l3NetworkUuid of vm nic can not be null", + "zh_CN": "云主机NIC的L3Networkuuid不能为空", + "arguments": [], + "line": 32, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "l3NetworkUuid of vm nic is not in l3[%s]", + "en_US": "l3NetworkUuid of vm nic is not in l3[{0}]", + "zh_CN": "云主机NIC的l3NetworkUuid不在L3[{0}]中", + "arguments": [ + "l3Uuids" + ], + "line": 35, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "outbound bandwidth[%d] of vm nic is out of [8192, 32212254720]", + "en_US": "outbound bandwidth[{0}] of vm nic is out of [8192, 32212254720]", + "zh_CN": "VM NIC的出站带宽[{0}]超出[8192,32212254720]", + "arguments": [ + "nic.getOutboundBandwidth()" + ], + "line": 40, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "inbound bandwidth[%d] of vm nic is out of [8192, 32212254720]", + "en_US": "inbound bandwidth[{0}] of vm nic is out of [8192, 32212254720]", + "zh_CN": "VM NIC的入站带宽[{0}]超出[8192,32212254720]", + "arguments": [ + "nic.getInboundBandwidth()" + ], + "line": 46, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "multi queue num[%d] of vm nic is out of [1,256]", + "en_US": "multi queue num[{0}] of vm nic is out of [1,256]", + "zh_CN": "VM NIC的多队列数[{0}]超出[1,256]", + "arguments": [ + "nic.getMultiQueueNum()" + ], + "line": 52, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "vm nic of l3[uuid:%s] state[%s] is not %s or %s ", + "en_US": "vm nic of l3[uuid:{0}] state[{1}] is not {2} or {3} ", + "zh_CN": "L3[uuid:{0}]状态[{1}]的VM NIC不是{2}或{3}", + "arguments": [ + "nic.getL3NetworkUuid()", + "nic.getState()", + "VmNicState.enable.toString()", + "VmNicState.disable.toString()" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "vm nic driver %s not support yet", + "en_US": "vm nic driver {0} not support yet", + "zh_CN": "VM NIC驱动程序{0}尚不支持", + "arguments": [ + "driverType" + ], + "line": 64, + "fileName": "src/main/java/org/zstack/compute/VmNicUtils.java" + }, + { + "raw": "VM [uuid: %s] has already been added to affinityGroup [uuid: %s]", + "en_US": "VM [uuid: {0}] has already been added to affinityGroup [uuid: {1}]", + "zh_CN": "VM[uuid:{0}已经被添加到亲和组[uuid:{1}]中。]", + "arguments": [ + "resourceUuid", + "affinityGroupUuid" + ], + "line": 420, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + }, + { + "raw": "There are other VMs on this host [uuid: %s] belonging to same affinityGroup [%s]", + "en_US": "There are other VMs on this host [uuid: {0}] belonging to same affinityGroup [{1}]", + "zh_CN": "在物理机[uuid:{0}]上的云主机属于同一个亲和组中[{1}]", + "arguments": [ + "hostUuid", + "affinityGroupUuid" + ], + "line": 437, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + }, + { + "raw": "affinityGroup [uuid:%s] reserve host [uuid:%s] for vm [uuid: %s] failed", + "en_US": "affinityGroup [uuid:{0}] reserve host [uuid:{1}] for vm [uuid: {2}] failed", + "zh_CN": "亲和组[uuid:{0}]为云主机[uuid:{2}]预分配物理机资源[uuid:{1}]失败", + "arguments": [ + "self.getUuid()", + "host.getUuid()", + "vmUuid" + ], + "line": 468, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + }, + { + "raw": "vm [uuid:%s] doesn\u0027t satisfy the affinityGroup [uuid:%s]", + "en_US": "vm [uuid:{0}] doesn\u0027t satisfy the affinityGroup [uuid:{1}]", + "zh_CN": "云主机[uuid:{1}]不满足亲和组[uuid:{2}]的要求", + "arguments": [ + "inv.getResourceUuid()", + "self.getUuid()" + ], + "line": 538, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java" + }, + { + "raw": "can not satisfied affinity group conditions", + "en_US": "can not satisfied affinity group conditions", + "zh_CN": "不能满足亲和组的条件", + "arguments": [], + "line": 139, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupFilterFlow.java" + }, + { + "raw": "Vm can change its affinityGroup only in state [%s,%s], but vm is in state [%s]", + "en_US": "Vm can change its affinityGroup only in state [{0},{1}], but vm is in state [{2}]", + "zh_CN": "只有状态为[{0},{1}]的云主机可以改变亲和组,但是现在云主机的状态为[{2}]", + "arguments": [ + "VmInstanceState.Running.toString()", + "VmInstanceState.Stopped.toString()", + "state.toString()" + ], + "line": 42, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + }, + { + "raw": "Vm [uuid: %s] is already added to affinityGroup [uuid: %s]", + "en_US": "Vm [uuid: {0}] is already added to affinityGroup [uuid: {1}]", + "zh_CN": "云主机[uuid:{0}]已经被添加至亲和组[uuid:{1}]中", + "arguments": [ + "msg.getUuid()", + "agUuid" + ], + "line": 52, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + }, + { + "raw": "AffinityGroup [uuid: %s] does not existed", + "en_US": "AffinityGroup [uuid: {0}] does not existed", + "zh_CN": "亲和组[uuid:{0}]不存在", + "arguments": [ + "affinityGroupUuid" + ], + "line": 77, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + }, + { + "raw": "Can not operate on affinity group created by system", + "en_US": "Can not operate on affinity group created by system", + "zh_CN": "不能对系统创建的亲和组进行操作", + "arguments": [], + "line": 81, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + }, + { + "raw": "Can not operate on affinityGroup [uuid: %s] which is not enabled", + "en_US": "Can not operate on affinityGroup [uuid: {0}] which is not enabled", + "zh_CN": "不能对不是enabled状态的亲和组操作", + "arguments": [ + "affinityGroupUuid" + ], + "line": 88, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java" + }, + { + "raw": "cannot find the affinity group[uuid:%s], it may have been deleted", + "en_US": "cannot find the affinity group[uuid:{0}], it may have been deleted", + "zh_CN": "未找到亲和组[uuid:{0}],它可能已经被删除", + "arguments": [ + "msg.getAffinityGroupUuid()" + ], + "line": 219, + "fileName": "src/main/java/org/zstack/compute/affinityGroup/AffinityGroupManagerImpl.java" + }, + { + "raw": "no host found in clusters that has attached to L2Networks which have L3Networks%s", + "en_US": "no host found in clusters that has attached to L2Networks which have L3Networks{0}", + "zh_CN": "在连接到具有L3Networks{0}的L2Networks的集群中找不到物理机", + "arguments": [ + "spec.getL3NetworkUuids()" + ], + "line": 118, + "fileName": "src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java" + }, + { + "raw": "no host found in clusters that have attached to primary storage %s", + "en_US": "no host found in clusters that have attached to primary storage {0}", + "zh_CN": "在已连接到主存储{0}的集群中找不到物理机", + "arguments": [ + "psuuids" + ], + "line": 79, + "fileName": "src/main/java/org/zstack/compute/allocator/AttachedPrimaryStorageAllocatorFlow.java" + }, + { + "raw": "cannot find root volume of vm[uuid:%s]", + "en_US": "cannot find root volume of vm[uuid:{0}]", + "zh_CN": "找不到VM[uuid:{0}]的根卷", + "arguments": [ + "vm.getUuid()" + ], + "line": 41, + "fileName": "src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java" + }, + { + "raw": "no host found in clusters which have attached to all primary storage %s where vm[uuid:%s]\u0027s volumes locate", + "en_US": "no host found in clusters which have attached to all primary storage {0} where vm[uuid:{1}]\u0027s volumes locate", + "zh_CN": "在已连接到VM[uuid:{1}]的卷所在的所有主存储{0}的集群中找不到物理机", + "arguments": [ + "requiredPsUuids", + "vm.getUuid()" + ], + "line": 84, + "fileName": "src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java" + }, + { + "raw": "after rule out avoided host%s, there is no host left in candidates", + "en_US": "after rule out avoided host{0}, there is no host left in candidates", + "zh_CN": "在排除避免的物理机{0}后,候选物理机中没有剩余的物理机", + "arguments": [ + "spec.getAvoidHostUuids()" + ], + "line": 30, + "fileName": "src/main/java/org/zstack/compute/allocator/AvoidHostAllocatorFlow.java" + }, + { + "raw": "the backup storage[uuid:%s, type:%s] requires bound primary storage, however, the primary storage has not been added", + "en_US": "the backup storage[uuid:{0}, type:{1}] requires bound primary storage, however, the primary storage has not been added", + "zh_CN": "无法找到跟镜像服务器[uuid:{0}, type:{1}]配对的主存储。一些镜像服务器必须跟配对的主存储共同使用,例如Ceph镜像服务器监控节点只能搭配分布式存储使用。请检查你主存储的设置", + "arguments": [ + "spec.getRequiredBackupStorageUuid()", + "bsType" + ], + "line": 87, + "fileName": "src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java" + }, + { + "raw": "The image[uuid:%s] is on the backup storage[uuid:%s, type:%s] that requires to work with primary storage[uuids:%s],however, no host found suitable to work with those primary storage", + "en_US": "The image[uuid:{0}] is on the backup storage[uuid:{1}, type:{2}] that requires to work with primary storage[uuids:{3}],however, no host found suitable to work with those primary storage", + "zh_CN": "镜像[uuid:{0}]所在的镜像服务器[uuid:{1}, type:{2}]必须跟主存储[uuid:{3}]配对使用,但无法找到可以跟满足条件并可以访问该主存储的物理机", + "arguments": [ + "spec.getImage().getUuid()", + "spec.getRequiredBackupStorageUuid()", + "type", + "psUuids" + ], + "line": 80, + "fileName": "src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java" + }, + { + "raw": "The image[uuid:%s, name:%s] is on the backup storage[uuid:%s, type:%s] that requires to work with primary storage[types:%s],however, no host found suitable to work with those primary storage", + "en_US": "The image[uuid:{0}, name:{1}] is on the backup storage[uuid:{2}, type:{3}] that requires to work with primary storage[types:{4}],however, no host found suitable to work with those primary storage", + "zh_CN": "镜像[uuid:{0},name:{1}]所在的镜像服务器[uuid:{2}, type:{3}]必须跟主存储[uuid:{4}]一起使用,但无法找到可以跟满足条件并可以访问该主存储的物理机", + "arguments": [ + "spec.getImage().getUuid()", + "name", + "spec.getRequiredBackupStorageUuid()", + "spec.getImage().getType()", + "possiblePrimaryStorageTypes" + ], + "line": 71, + "fileName": "src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java" + }, + { + "raw": "No host with %s found", + "en_US": "No host with {0} found", + "zh_CN": "找不到具有{0}的物理机", + "arguments": [ + "args" + ], + "line": 107, + "fileName": "src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java" + }, + { + "raw": "after filtering, HostAllocatorFilterExtensionPoint[%s] returns zero candidate host, it means: %s", + "en_US": "after filtering, HostAllocatorFilterExtensionPoint[{0}] returns zero candidate host, it means: {1}", + "zh_CN": "过滤后,HostAllocatorFilterExtensionPoint[{0}]返回零候选物理机,表示:{1}", + "arguments": [ + "filter.getClass().getSimpleName()", + "filter.filterErrorReason()" + ], + "line": 39, + "fileName": "src/main/java/org/zstack/compute/allocator/FilterFlow.java" + }, + { + "raw": "either volumeUuid or volumeSnapshotUuid must be set", + "en_US": "either volumeUuid or volumeSnapshotUuid must be set", + "zh_CN": "云盘uuid或者快照uuid必须被设置", + "arguments": [], + "line": 56, + "fileName": "src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java" + }, + { + "raw": "zoneUuids, clusterUuids, hostUuids must at least have one be none-empty list, or all is set to true", + "en_US": "zoneUuids, clusterUuids, hostUuids must at least have one be none-empty list, or all is set to true", + "zh_CN": "区域uuid,集群uuid,物理机uuid必须有一个不为空,或者全部都填写", + "arguments": [], + "line": 75, + "fileName": "src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java" + }, + { + "raw": "no host having cpu[%s], memory[%s bytes] found", + "en_US": "no host having cpu[{0}], memory[{1} bytes] found", + "zh_CN": "未找到CPU为[{0}]、内存为[{1}字节]的物理机", + "arguments": [ + "spec.getCpuCapacity()", + "spec.getMemoryCapacity()" + ], + "line": 69, + "fileName": "src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java" + }, + { + "raw": "no candidate host has version[%s]", + "en_US": "no candidate host has version[{0}]", + "zh_CN": "没有版本为[{0}]的候选物理机", + "arguments": [ + "currentHostOs" + ], + "line": 52, + "fileName": "src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java" + }, + { + "raw": "cannot find available primary storage[state: %s or %s, status: %s]. Check the state/status of primary storage and make sure they have been attached to clusters", + "en_US": "cannot find available primary storage[state: {0} or {1}, status: {2}]. Check the state/status of primary storage and make sure they have been attached to clusters", + "zh_CN": "找不到可用的主存储[状态:{0}或{1},状态:{2}]。检查主存储的状态,并确保它们已连接到集群", + "arguments": [ + "PrimaryStorageState.Enabled", + "PrimaryStorageState.Disabled", + "PrimaryStorageStatus.Connected" + ], + "line": 248, + "fileName": "src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java" + }, + { + "raw": "cannot find available primary storage[state: %s, status: %s, available capacity %s bytes]. Check the state/status of primary storage and make sure they have been attached to clusters", + "en_US": "cannot find available primary storage[state: {0}, status: {1}, available capacity {2} bytes]. Check the state/status of primary storage and make sure they have been attached to clusters", + "zh_CN": "找不到可用的主存储[状态:{0},状态:{1},可用容量为{2}字节]。检查主存储的状态,并确保它们已连接到集群", + "arguments": [ + "PrimaryStorageState.Enabled", + "PrimaryStorageStatus.Connected", + "spec.getDiskSize()" + ], + "line": 244, + "fileName": "src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java" + }, + { + "raw": "[Host Allocation]: %s on host[uuid:%s]. try next one. %s", + "en_US": "[Host Allocation]: {0} on host[uuid:{1}]. try next one. {2}", + "zh_CN": "[物理机分配]:物理机[uuid:{1}]上的{0}。请尝试下一个。{2}", + "arguments": [ + "e.getMessage()", + "host.getUuid()", + "e.getMessage()" + ], + "line": 130, + "fileName": "src/main/java/org/zstack/compute/allocator/HostSortorChain.java" + }, + { + "raw": "no host having state\u003dEnabled status\u003dConnected hypervisorType\u003d%s found", + "en_US": "no host having state\u003dEnabled status\u003dConnected hypervisorType\u003d{0} found", + "zh_CN": "未找到状态为“已启用”、状态为“已连接”、管理程序类型为“{0}”的物理机", + "arguments": [ + "spec.getHypervisorType()" + ], + "line": 97, + "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + }, + { + "raw": "no host having state\u003dEnabled status\u003dConnected found", + "en_US": "no host having state\u003dEnabled status\u003dConnected found", + "zh_CN": "未找到状态\u003d已启用、状态\u003d已连接的物理机", + "arguments": [], + "line": 99, + "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + }, + { + "raw": "no Enabled hosts found in the [%s] candidate hosts having the hypervisor type [%s]", + "en_US": "no Enabled hosts found in the [{0}] candidate hosts having the hypervisor type [{1}]", + "zh_CN": "在具有云主机监控程序类型[{1}]的[{0}]候选物理机中未找到已启用的物理机", + "arguments": [ + "candidates.size()", + "spec.getHypervisorType()" + ], + "line": 94, + "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + }, + { + "raw": "no Enabled hosts found in the [%s] candidate hosts", + "en_US": "no Enabled hosts found in the [{0}] candidate hosts", + "zh_CN": "在[{0}]个候选物理机中找不到已启用的物理机", + "arguments": [ + "candidates.size()" + ], + "line": 92, + "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + }, + { + "raw": "no Connected hosts found in the [%s] candidate hosts", + "en_US": "no Connected hosts found in the [{0}] candidate hosts", + "zh_CN": "在[{0}]个候选物理机中找不到已连接的物理机", + "arguments": [ + "candidates.size()" + ], + "line": 90, + "fileName": "src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java" + }, + { + "raw": "the image[uuid:%s, name:%s] is deleted on all backup storage", + "en_US": "the image[uuid:{0}, name:{1}] is deleted on all backup storage", + "zh_CN": "镜像[uuid:{0}, name:{1}]已经从所有镜像服务器上删除,无法执行相应操作", + "arguments": [ + "spec.getImage().getUuid()", + "spec.getImage().getName()" + ], + "line": 110, + "fileName": "src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java" + }, + { + "raw": "no host found in zones[uuids:%s] that attaches to backup storage where image[%s] is on", + "en_US": "no host found in zones[uuids:{0}] that attaches to backup storage where image[{1}] is on", + "zh_CN": "在区域[uuid:{0}]中找不到连接到镜像[{1}]所在的备份存储的物理机", + "arguments": [ + "zoneUuids", + "spec.getImage().getUuid()" + ], + "line": 144, + "fileName": "src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java" + }, + { + "raw": "resource binding not support type %s yet", + "en_US": "resource binding not support type {0} yet", + "zh_CN": "资源绑定尚不支持类型{0}", + "arguments": [ + "entry.getKey()" + ], + "line": 114, + "fileName": "src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java" + }, + { + "raw": "no available host found with binded resource %s", + "en_US": "no available host found with binded resource {0}", + "zh_CN": "未找到具有绑定资源{0}的可用物理机", + "arguments": [ + "resources" + ], + "line": 133, + "fileName": "src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java" + }, + { + "raw": "InstanceOfferingTagAllocatorExtensionPoint[%s] return zero candidate host", + "en_US": "InstanceOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host", + "zh_CN": "InstanceOfferingTagAllocatorExtensionPoint[{0}]返回零个候选物理机", + "arguments": [ + "extp.getClass().getName()" + ], + "line": 68, + "fileName": "src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java" + }, + { + "raw": "DiskOfferingTagAllocatorExtensionPoint[%s] return zero candidate host", + "en_US": "DiskOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host", + "zh_CN": "DiskOfferingTagAllocatorExtensionPoint[{0}]返回零候选物理机", + "arguments": [ + "extp.getClass().getName()" + ], + "line": 104, + "fileName": "src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java" + }, + { + "raw": "cannot bind with interface configured with vtep ip", + "en_US": "cannot bind with interface configured with vtep ip", + "zh_CN": "无法与配置了VTEP IP的接口绑定", + "arguments": [], + "line": 108, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "invalid bonding name[%s], it must be shorter than [%s] characters", + "en_US": "invalid bonding name[{0}], it must be shorter than [{1}] characters", + "zh_CN": "绑定名称[{0}]无效,它必须少于[{1}]个字符", + "arguments": [ + "bondingName", + "HostNetworkBondingConstant.BONDING_NAME_MAX" + ], + "line": 64, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "invalid bonding name[%s], it must only contains letters, numbers and underscores", + "en_US": "invalid bonding name[{0}], it must only contains letters, numbers and underscores", + "zh_CN": "绑定名称[{0}]无效,它只能包含字母、数字和下划线", + "arguments": [ + "bondingName" + ], + "line": 68, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "bonding card can not have occupied bondingName:[%s], which was already been used by host[%s].", + "en_US": "bonding card can not have occupied bondingName:[{0}], which was already been used by host[{1}].", + "zh_CN": "绑定卡不能占用BondingName:[{0}],它已被物理机[{1}]使用。", + "arguments": [ + "bondingName", + "hostUuid" + ], + "line": 77, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "cannot bind with interface corresponding to the management network", + "en_US": "cannot bind with interface corresponding to the management network", + "zh_CN": "无法与管理网络对应的接口绑定", + "arguments": [], + "line": 103, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "bonding card can not have interfaces which is not on the same host[%s].", + "en_US": "bonding card can not have interfaces which is not on the same host[{0}].", + "zh_CN": "绑定卡不能具有不在同一物理机[{0}]上的接口。", + "arguments": [ + "hostUuid" + ], + "line": 115, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "bonding card can not have occupied interfaces, which was already been used by host[%s].", + "en_US": "bonding card can not have occupied interfaces, which was already been used by host[{0}].", + "zh_CN": "绑定卡不能占用接口,该接口已被物理机[{0}]使用。", + "arguments": [ + "hostUuid" + ], + "line": 120, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "bonding card can not have interfaces that has been used as a network bridge, which was already been used by host[%s].", + "en_US": "bonding card can not have interfaces that has been used as a network bridge, which was already been used by host[{0}].", + "zh_CN": "绑定卡不能具有已用作网桥的接口,该接口已被物理机[{0}]使用。", + "arguments": [ + "hostUuid" + ], + "line": 125, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "bonding card can not have interface[%s] which have been sriov virtualized.", + "en_US": "bonding card can not have interface[{0}] which have been sriov virtualized.", + "zh_CN": "绑定卡不能具有已被SRIOV虚拟化的接口[{0}]。", + "arguments": [ + "interfaceVO.getUuid()" + ], + "line": 152, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "bonding card can not have interfaces with different speed, which is on the host[%s].", + "en_US": "bonding card can not have interfaces with different speed, which is on the host[{0}].", + "zh_CN": "绑定卡不能有不同速度的接口,在物理机[{0}]上。", + "arguments": [ + "hostUuid" + ], + "line": 161, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "[%s] bonding card can not designate [%s], Only mode 802.3ad support specifying different xmit_hash_policys", + "en_US": "[{0}] bonding card can not designate [{1}], Only mode 802.3ad support specifying different xmit_hash_policys", + "zh_CN": "[{0}]绑定卡无法指定[{1}],只有模式802.3ad支持指定不同的xmit_哈希_策略", + "arguments": [ + "mode", + "xmitHashPolicy" + ], + "line": 168, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "[%s] bonding can not have [%s] interfaces, it must be the number between[1~2].", + "en_US": "[{0}] bonding can not have [{1}] interfaces, it must be the number between[1~2].", + "zh_CN": "[{0}]绑定不能有[{1}]个接口,其数量必须在[1~2]之间。", + "arguments": [ + "mode", + "size" + ], + "line": 181, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "[%s] bonding card can not have [%s] interfaces, it must be the number between[1~8].", + "en_US": "[{0}] bonding card can not have [{1}] interfaces, it must be the number between[1~8].", + "zh_CN": "[{0}]个绑定卡不能有[{1}]个接口,必须在[1~8]之间。", + "arguments": [ + "mode", + "size" + ], + "line": 177, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "invalid bonding type[%s]", + "en_US": "invalid bonding type[{0}]", + "zh_CN": "绑定类型[{0}]无效", + "arguments": [ + "msg.getType()" + ], + "line": 214, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "cannot delete bonding corresponding to the management network", + "en_US": "cannot delete bonding corresponding to the management network", + "zh_CN": "无法删除与管理网络对应的绑定", + "arguments": [], + "line": 242, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "cannot delete bonding configured with vtep ip", + "en_US": "cannot delete bonding configured with vtep ip", + "zh_CN": "无法删除使用VTEP IP配置的绑定", + "arguments": [], + "line": 247, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java" + }, + { + "raw": "failed to add linux bonding to host[uuid:%s] : %s", + "en_US": "failed to add linux bonding to host[uuid:{0}] : {1}", + "zh_CN": "无法将Linux绑定添加到物理机[uuid:{0}]:{1}", + "arguments": [ + "bondingInv.getHostUuid()", + "reply.getError()" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java" + }, + { + "raw": "failed to update linux bonding on host[uuid:%s] : %s", + "en_US": "failed to update linux bonding on host[uuid:{0}] : {1}", + "zh_CN": "无法更新物理机[uuid:{0}]上的Linux绑定:{1}", + "arguments": [ + "bondingInv.getHostUuid()", + "reply.getError()" + ], + "line": 97, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java" + }, + { + "raw": "failed to remove linux bonding from host[uuid:%s] : %s", + "en_US": "failed to remove linux bonding from host[uuid:{0}] : {1}", + "zh_CN": "无法从物理机[uuid:{0}]中删除Linux绑定:{1}", + "arguments": [ + "bondingInv.getHostUuid()", + "reply.getError()" + ], + "line": 132, + "fileName": "src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java" + }, + { + "raw": "if cluster type is baremetal, then hypervisorType must be baremetal too, or vice versa", + "en_US": "if cluster type is baremetal, then hypervisorType must be baremetal too, or vice versa", + "zh_CN": "如果集群类型为裸机,则hypervisorType也必须为裸机,反之亦然", + "arguments": [], + "line": 55, + "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + }, + { + "raw": "only kvm hosts\u0027 operating system can be updated, for now", + "en_US": "only kvm hosts\u0027 operating system can be updated, for now", + "zh_CN": "目前只支持升级KVM物理机操作系统", + "arguments": [], + "line": 71, + "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + }, + { + "raw": "there are hosts in cluster[uuid:%s] in the PreMaintenance state, cannot update cluster os right now", + "en_US": "there are hosts in cluster[uuid:{0}] in the PreMaintenance state, cannot update cluster os right now", + "zh_CN": "集群[uuid:{0}] 中存在处于预维护模式的物理机,无法执行操作系统升级操作", + "arguments": [ + "msg.getUuid()" + ], + "line": 82, + "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + }, + { + "raw": "not all hosts in cluster[uuid:%s] are in the Connected status, cannot update cluster os right now", + "en_US": "not all hosts in cluster[uuid:{0}] are in the Connected status, cannot update cluster os right now", + "zh_CN": "集群[uuid:{0}] 中存在未处于已连接状态的物理机,无法执行操作系统升级操作", + "arguments": [ + "msg.getUuid()" + ], + "line": 94, + "fileName": "src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java" + }, + { + "raw": "invalid cpu pinning ref[%s]. correct example is [1,3:3-6,^5]", + "en_US": "invalid cpu pinning ref[{0}]. correct example is [1,3:3-6,^5]", + "zh_CN": "CPU固定引用[{0}]无效。正确的例子是[1,3:3-6,^5]", + "arguments": [ + "r" + ], + "line": 45, + "fileName": "src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java" + }, + { + "raw": "Invalid cpuset [%s]", + "en_US": "Invalid cpuset [{0}]", + "zh_CN": "无效的CPUSet[{0}]", + "arguments": [ + "word" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/compute/cpuPinning/CpuRangeSet.java" + }, + { + "raw": "the host vm located only have % CPUs", + "en_US": "the host vm located only have % CPUs", + "zh_CN": "所定位的物理机云主机只有%的CPU", + "arguments": [ + "pCpuNum" + ], + "line": 53, + "fileName": "src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningBasicFactory.java" + }, + { + "raw": "incorrect input format, only accept \u0027^[0-9,]+$\u0027", + "en_US": "incorrect input format, only accept \u0027^[0-9,]+$\u0027", + "zh_CN": "输入格式不正确,只接受\u0027^[0-9,]+$\u0027", + "arguments": [], + "line": 46, + "fileName": "src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningBasicFactory.java" + }, + { + "raw": "vcpu pinning pcpu id \u003e host cores", + "en_US": "vcpu pinning pcpu id \u003e host cores", + "zh_CN": "vcpu要绑定的pcpu id大于了物理机实际核数", + "arguments": [], + "line": 37, + "fileName": "src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningFilterFlow.java" + }, + { + "raw": "webssh server is not running.", + "en_US": "webssh server is not running.", + "zh_CN": "WebSSH服务器未运行。", + "arguments": [], + "line": 81, + "fileName": "src/main/java/org/zstack/compute/host/HostApiInterceptor.java" + }, + { + "raw": "managementIp[%s] is neither an IPv4 address nor a valid hostname", + "en_US": "managementIp[{0}] is neither an IPv4 address nor a valid hostname", + "zh_CN": "管理IP[{0}]既不是有效的IPv4地址也不是有效的物理机名", + "arguments": [ + "msg.getManagementIp()" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/compute/host/HostApiInterceptor.java" + }, + { + "raw": "can not maintain host[uuid:%s, status:%s]which is not Connected", + "en_US": "can not maintain host[uuid:{0}, status:{1}]which is not Connected", + "zh_CN": "只能对已连接状态的物理机[uuid:{0}, status:{1}]进行维护操作", + "arguments": [ + "msg.getHostUuid()", + "hostStatus" + ], + "line": 115, + "fileName": "src/main/java/org/zstack/compute/host/HostApiInterceptor.java" + }, + { + "raw": "host[%s] does not have ipmi device or ipmi does not have address.After config ipmi address, please reconnect host to refresh host ipmi information", + "en_US": "host[{0}] does not have ipmi device or ipmi does not have address.After config ipmi address, please reconnect host to refresh host ipmi information", + "zh_CN": "物理机[{0}]没有IPMI设备或IPMI没有地址。配置IPMI地址后,请重新连接物理机以刷新物理机IPMI信息", + "arguments": [ + "msg.getHostUuid()" + ], + "line": 272, + "fileName": "src/main/java/org/zstack/compute/host/HostBase.java" + }, + { + "raw": "failed to migrate vm[uuids:%s] on host[uuid:%s, name:%s, ip:%s], will try stopping it.", + "en_US": "failed to migrate vm[uuids:{0}] on host[uuid:{1}, name:{2}, ip:{3}], will try stopping it.", + "zh_CN": "无法迁移物理机[uuid:{1},名称:{2},IP:{3}]上的VM[uuid:{0}],将尝试停止它。", + "arguments": [ + "vmFailedToMigrate.keySet()", + "self.getUuid()", + "self.getName()", + "self.getManagementIp()" + ], + "line": 435, + "fileName": "src/main/java/org/zstack/compute/host/HostBase.java" + }, + { + "raw": "host is connecting, ping failed", + "en_US": "host is connecting, ping failed", + "zh_CN": "物理机正在连接, 不能进行ping操作", + "arguments": [], + "line": 841, + "fileName": "src/main/java/org/zstack/compute/host/HostBase.java" + }, + { + "raw": "mock power off host[%s] by ipmi failed.", + "en_US": "mock power off host[{0}] by ipmi failed.", + "zh_CN": "通过IPMI模拟物理机[{0}]断电失败。", + "arguments": [ + "host.getUuid()" + ], + "line": 63, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "power off host[%s] by ipmi failed.", + "en_US": "power off host[{0}] by ipmi failed.", + "zh_CN": "通过IPMI关闭物理机[{0}]失败。", + "arguments": [ + "host.getUuid()" + ], + "line": 79, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "mock power on host[%s] by ipmi failed.", + "en_US": "mock power on host[{0}] by ipmi failed.", + "zh_CN": "通过IPMI模拟物理机[{0}]上的电源失败。", + "arguments": [ + "host.getUuid()" + ], + "line": 121, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "power on host[%s] by ipmi failed.", + "en_US": "power on host[{0}] by ipmi failed.", + "zh_CN": "通过IPMI打开物理机[{0}]电源失败。", + "arguments": [ + "host.getUuid()" + ], + "line": 131, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "mock power reset host[%s] by ipmi failed.", + "en_US": "mock power reset host[{0}] by ipmi failed.", + "zh_CN": "通过IPMI模拟电源重置物理机[{0}]失败。", + "arguments": [ + "host.getUuid()" + ], + "line": 161, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "power reset host[%s] by ipmi failed.", + "en_US": "power reset host[{0}] by ipmi failed.", + "zh_CN": "通过IPMI对物理机[{0}]进行电源重置失败。", + "arguments": [ + "host.getUuid()" + ], + "line": 171, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "ipmi information is not complete.", + "en_US": "ipmi information is not complete.", + "zh_CN": "IPMI信息不完整。", + "arguments": [], + "line": 192, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "host[%s] can not connect ipmi[%s], because:%s", + "en_US": "host[{0}] can not connect ipmi[{1}], because:{2}", + "zh_CN": "物理机[{0}]无法连接IPMI[{1}],因为:{2}", + "arguments": [ + "ipmi.getUuid()", + "rst.getStderr()" + ], + "line": 205, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "host[%s] got unexpected return value", + "en_US": "host[{0}] got unexpected return value", + "zh_CN": "物理机[{0}]获得意外的返回值", + "arguments": [ + "ipmi.getUuid()" + ], + "line": 202, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "host ipmi[%s] is not reachable.because %s", + "en_US": "host ipmi[{0}] is not reachable.because {1}", + "zh_CN": "无法访问物理机IPMI[{0}]。原因是{1}", + "arguments": [ + "ipmi.getIpmiAddress()", + "rst.getStderr()" + ], + "line": 222, + "fileName": "src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java" + }, + { + "raw": "there has been a host having managementIp[%s]", + "en_US": "there has been a host having managementIp[{0}]", + "zh_CN": "已经存在一个管理IP是[{0}]的物理机", + "arguments": [ + "msg.getManagementIp()" + ], + "line": 264, + "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + }, + { + "raw": "cluster[uuid:%s] is not existing", + "en_US": "cluster[uuid:{0}] is not existing", + "zh_CN": "集群[uuid:{0}]不存在", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 270, + "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + }, + { + "raw": "after connecting, host[name:%s, ip:%s] returns a null architecture", + "en_US": "after connecting, host[name:{0}, ip:{1}] returns a null architecture", + "zh_CN": "连接后,物理机[名称:{0},IP:{1}]返回空体系结构", + "arguments": [ + "vo.getName()", + "vo.getManagementIp()" + ], + "line": 364, + "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + }, + { + "raw": "cluster[uuid:%s]\u0027s architecture is %s, not match the host[name:%s, ip:%s] architecture %s", + "en_US": "cluster[uuid:{0}]\u0027s architecture is {1}, not match the host[name:{2}, ip:{3}] architecture {4}", + "zh_CN": "集群[uuid:{0}]的体系结构为{1},与物理机[名称:{2},IP:{3}]的体系结构{4}不匹配", + "arguments": [ + "vo.getClusterUuid()", + "cluster.getArchitecture()", + "vo.getName()", + "vo.getManagementIp()", + "arch" + ], + "line": 379, + "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + }, + { + "raw": "no running api[%s] task on hosts", + "en_US": "no running api[{0}] task on hosts", + "zh_CN": "物理机上没有正在运行的API[{0}]任务", + "arguments": [ + "msg.getCancellationApiId()" + ], + "line": 515, + "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + }, + { + "raw": "primary storage[uuid:%s] becomes disconnected, the host has no connected primary storage attached", + "en_US": "primary storage[uuid:{0}] becomes disconnected, the host has no connected primary storage attached", + "zh_CN": "主存储[uuid:{0}]失联,物理机没有关联的主存储", + "arguments": [ + "d.getPrimaryStorageUuid()" + ], + "line": 733, + "fileName": "src/main/java/org/zstack/compute/host/HostManagerImpl.java" + }, + { + "raw": "host(s) [%s] is not Connected, not support to power off", + "en_US": "host(s) [{0}] is not Connected, not support to power off", + "zh_CN": "物理机[{0}]未连接,不支持关机", + "arguments": [ + "nameips.stream().map( it -\u003e it.get(1, String.class) + \"/\" + it.get(0, String.class)).collect(Collectors.joining(\", \"))" + ], + "line": 59, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "invalid ip address format[%s]", + "en_US": "invalid ip address format[{0}]", + "zh_CN": "IP地址格式[{0}]无效", + "arguments": [ + "ipAddress" + ], + "line": 67, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "invalid netmask format[%s]", + "en_US": "invalid netmask format[{0}]", + "zh_CN": "网络掩码格式[{0}]无效", + "arguments": [ + "netmask" + ], + "line": 71, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "invalid ip set, it must be set with netmask", + "en_US": "invalid ip set, it must be set with netmask", + "zh_CN": "设置的IP无效,必须使用网络掩码进行设置", + "arguments": [], + "line": 75, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "cannot set ip on interface corresponding to the management network", + "en_US": "cannot set ip on interface corresponding to the management network", + "zh_CN": "无法在与管理网络对应的接口上设置IP", + "arguments": [], + "line": 91, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "cannot set ip which has been set on the other interfaces", + "en_US": "cannot set ip which has been set on the other interfaces", + "zh_CN": "无法设置已在其他接口上设置的IP", + "arguments": [], + "line": 192, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "cannot set ip on bonding slaves", + "en_US": "cannot set ip on bonding slaves", + "zh_CN": "无法在绑定从属服务器上设置IP", + "arguments": [], + "line": 126, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "cannot set ip on bridge slaves", + "en_US": "cannot set ip on bridge slaves", + "zh_CN": "无法在网桥从属服务器上设置IP", + "arguments": [], + "line": 203, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "invalid interface uuid", + "en_US": "invalid interface uuid", + "zh_CN": "接口uuid无效", + "arguments": [ + "msg.getInterfaceUuid()" + ], + "line": 151, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "cannot set ip on bonding corresponding to the management network", + "en_US": "cannot set ip on bonding corresponding to the management network", + "zh_CN": "无法在与管理网络对应的绑定上设置IP", + "arguments": [], + "line": 168, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "invalid bonding uuid", + "en_US": "invalid bonding uuid", + "zh_CN": "绑定uuid无效", + "arguments": [ + "msg.getBondingUuid()" + ], + "line": 213, + "fileName": "src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java" + }, + { + "raw": "no available network interface on the host to start the vm", + "en_US": "no available network interface on the host to start the vm", + "zh_CN": "物理机上没有可用于启动云主机的网络接口", + "arguments": [], + "line": 141, + "fileName": "src/main/java/org/zstack/compute/host/HostNetworkInterfaceStateAllocatorFlow.java" + }, + { + "raw": "vm security level not consistent with vms running on host", + "en_US": "vm security level not consistent with vms running on host", + "zh_CN": "云主机安全级别与物理机上运行的云主机不一致", + "arguments": [], + "line": 68, + "fileName": "src/main/java/org/zstack/compute/host/HostSecurityLevelAllocatorFilterExtensionPoint.java" + }, + { + "raw": "host[uuid:%s, name:%s] is in state[%s], cannot perform required operation", + "en_US": "host[uuid:{0}, name:{1}] is in state[{2}], cannot perform required operation", + "zh_CN": "物理机[uuid:{0}, name:{1}]处于状态[{2}]中,不能处理该请求", + "arguments": [ + "host.getUuid()", + "host.getName()", + "host.getState()" + ], + "line": 280, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "operation error, because %s", + "en_US": "operation error, because {0}", + "zh_CN": "操作错误,因为{0}", + "arguments": [ + "ret.getError()" + ], + "line": 917, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "failed to allocate pci device for l3[uuid:%s] on host[uuid:%s]", + "en_US": "failed to allocate pci device for l3[uuid:{0}] on host[uuid:{1}]", + "zh_CN": "无法为物理机[uuid:{1}]上的L3[uuid:{0}]分配PCI设备", + "arguments": [ + "l3Uuid", + "msg.getHostUuid()" + ], + "line": 370, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "networkInterface[name:%s] of host[uuid:%s] can not find", + "en_US": "networkInterface[name:{0}] of host[uuid:{1}] can not find", + "zh_CN": "找不到物理机[uuid:{1}]的网络接口[名称:{0}]", + "arguments": [ + "msg.getNetworkInterfaceName()", + "msg.getHostUuid()" + ], + "line": 622, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "only support do live snapshot on vm state[%s], but vm is on [%s] state", + "en_US": "only support do live snapshot on vm state[{0}], but vm is on [{1}] state", + "zh_CN": "仅支持在VM状态[{0}]上执行实时快照,但VM处于[{1}]状态", + "arguments": [ + "vmInstanceVO.getUuid()", + "vmInstanceVO.getState()" + ], + "line": 805, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "sync vm port config failed: %s", + "en_US": "sync vm port config failed: {0}", + "zh_CN": "同步云主机端口配置失败:{0}", + "arguments": [ + "ret.getError()" + ], + "line": 1389, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "set vm hostname failed: %s", + "en_US": "set vm hostname failed: {0}", + "zh_CN": "设置VM物理机名失败:{0}", + "arguments": [ + "ret.getError()" + ], + "line": 1423, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBase.java" + }, + { + "raw": "host[uuid:%s] has multi ips in cidr[%s]", + "en_US": "host[uuid:{0}] has multi ips in cidr[{1}]", + "zh_CN": "物理机[uuid:{0}]在CIDR[{1}]中具有多个IP", + "arguments": [ + "huuid", + "cidr" + ], + "line": 84, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostBaseFactory.java" + }, + { + "raw": "host[uuid:%s] can not find", + "en_US": "host[uuid:{0}] can not find", + "zh_CN": "找不到物理机[uuid:{0}]", + "arguments": [ + "msg.getHostUuid()" + ], + "line": 1058, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java" + }, + { + "raw": "failed to update interface ip, because %s", + "en_US": "failed to update interface ip, because {0}", + "zh_CN": "无法更新接口IP,因为{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 408, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java" + }, + { + "raw": "failed to update bonding ip, because %s", + "en_US": "failed to update bonding ip, because {0}", + "zh_CN": "无法更新绑定IP,因为{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 510, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java" + }, + { + "raw": "cluster[uuids:%s, hypervisorType:%s] are not exist!", + "en_US": "cluster[uuids:{0}, hypervisorType:{1}] are not exist!", + "zh_CN": "集群[uuid:{0},HypervisorType:{1}]不存在!", + "arguments": [ + "clusterUuids", + "hypervisorType" + ], + "line": 1024, + "fileName": "src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java" + }, + { + "raw": "ovs cpu pinning resource config:[%s] format error.", + "en_US": "ovs cpu pinning resource config:[{0}] format error.", + "zh_CN": "OVS CPU固定资源配置:[{0}]格式错误。", + "arguments": [ + "newValue" + ], + "line": 72, + "fileName": "src/main/java/org/zstack/compute/ovs/VSwitchOvsManagerImpl.java" + }, + { + "raw": "vm nic[uuid:%s] doesn\u0027t exist", + "en_US": "vm nic[uuid:{0}] doesn\u0027t exist", + "zh_CN": "VM NIC[uuid:{0}]不存在", + "arguments": [ + "msg.getVmNicUuid()" + ], + "line": 136, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "only %s support sriov", + "en_US": "only {0} support sriov", + "zh_CN": "仅{0}支持SRIOV", + "arguments": [ + "VmVfNicConstant.SRIOVABLE_L2_NETWORK_TYPES" + ], + "line": 77, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "%s don\u0027t support sriov", + "en_US": "{0} don\u0027t support sriov", + "zh_CN": "{0}不支持SRIOV", + "arguments": [ + "L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK" + ], + "line": 83, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "L3 Network [uuid:%s] doesn\u0027t exist", + "en_US": "L3 Network [uuid:{0}] doesn\u0027t exist", + "zh_CN": "三层网络[uuid:{0}]不存在", + "arguments": [ + "l3Uuid" + ], + "line": 93, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "related l2 network[uuid:%s] of l3 network[uuid:%s] is not sriov enabled", + "en_US": "related l2 network[uuid:{0}] of l3 network[uuid:{1}] is not sriov enabled", + "zh_CN": "三层网络[uuid:{1}]的相关二层网络[uuid:{0}]未启用SRIOV", + "arguments": [ + "l2Uuid", + "l3Uuid" + ], + "line": 97, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "vm nic[uuid:%s] is already of type %s, no need to change", + "en_US": "vm nic[uuid:{0}] is already of type {1}, no need to change", + "zh_CN": "VM NIC[uuid:{0}]已属于类型{1},无需更改", + "arguments": [ + "msg.getVmNicUuid()", + "msg.getVmNicType()" + ], + "line": 140, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "change vm nic type only when the vm is stopped", + "en_US": "change vm nic type only when the vm is stopped", + "zh_CN": "仅在VM停止时更改VM NIC类型", + "arguments": [], + "line": 146, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "cant not change vf nic to normal type", + "en_US": "cant not change vf nic to normal type", + "zh_CN": "无法将VF NIC更改为正常类型", + "arguments": [], + "line": 190, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "cant not change nic to vf type", + "en_US": "cant not change nic to vf type", + "zh_CN": "无法将NIC更改为VF类型", + "arguments": [], + "line": 197, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java" + }, + { + "raw": "no candidate host with enough vf nic pci devices", + "en_US": "no candidate host with enough vf nic pci devices", + "zh_CN": "没有具有足够VF NIC PCI设备的候选物理机", + "arguments": [], + "line": 89, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicFilterFlow.java" + }, + { + "raw": "enableSRIOV tag is not supported for vm type [%s]", + "en_US": "enableSRIOV tag is not supported for vm type [{0}]", + "zh_CN": "云主机类型[{0}]不支持EnableSriov标记", + "arguments": [ + "vmType" + ], + "line": 275, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java" + }, + { + "raw": "vm[uuid:%s] needs to be running when attach vf nics, but no hostUuid found", + "en_US": "vm[uuid:{0}] needs to be running when attach vf nics, but no hostUuid found", + "zh_CN": "连接VF NIC时需要运行VM[uuid:{0}],但未找到HOSTuuid", + "arguments": [ + "vmUuid" + ], + "line": 476, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java" + }, + { + "raw": "cannot find available vf nic pci device on host[uuid:%s] for l3[uuid:%s]", + "en_US": "cannot find available vf nic pci device on host[uuid:{0}] for l3[uuid:{1}]", + "zh_CN": "对于L3[uuid:{1}],在物理机[uuid:{0}]上找不到可用的VF NIC PCI设备", + "arguments": [ + "hostUuid", + "l3Uuid" + ], + "line": 499, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java" + }, + { + "raw": "reserve pci address for on host[uuid] for vm [uuid:%s] failed,", + "en_US": "reserve pci address for on host[uuid] for vm [uuid:{0}] failed,", + "zh_CN": "在物理机[uuid]上为云主机[uuid:{0}]保留的PCI地址失败,", + "arguments": [ + "hostUuid", + "vmUuid" + ], + "line": 88, + "fileName": "src/main/java/org/zstack/compute/sriov/VmVfNicReserveFlow.java" + }, + { + "raw": "failed to delete vHost User Client in host[uuid:%s] for vm[uuid:%s] : %s", + "en_US": "failed to delete vHost User Client in host[uuid:{0}] for vm[uuid:{1}] : {2}", + "zh_CN": "无法删除云主机[uuid:{1}]的物理机[uuid:{0}]中的vhost用户客户端:{2}", + "arguments": [ + "hostUuid", + "vmUuid", + "reply.getError()" + ], + "line": 49, + "fileName": "src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicKvmBackend.java" + }, + { + "raw": "failed to generate vHost User Client in host[uuid:%s] for vm[uuid:%s] : %s", + "en_US": "failed to generate vHost User Client in host[uuid:{0}] for vm[uuid:{1}] : {2}", + "zh_CN": "无法在物理机[uuid:{0}]中为VM[uuid:{1}]生成vhost用户客户端:{2}", + "arguments": [ + "hostUuid", + "vmUuid", + "reply.getError()" + ], + "line": 85, + "fileName": "src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicKvmBackend.java" + }, + { + "raw": "cannot generate vhost user client for vm[uuid:%s] on the destination host[uuid:%s]", + "en_US": "cannot generate vhost user client for vm[uuid:{0}] on the destination host[uuid:{1}]", + "zh_CN": "无法为目标物理机[uuid:{1}]上的云主机[uuid:{0}]生成vhost用户客户端", + "arguments": [ + "inv.getUuid()", + "destHostUuid" + ], + "line": 309, + "fileName": "src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicManagerImpl.java" + }, + { + "raw": "only %s support vdpa", + "en_US": "only {0} support vdpa", + "zh_CN": "仅{0}支持VDPA", + "arguments": [ + "VmVdpaNicConstant.VDPA_L2_NETWORK_TYPES" + ], + "line": 66, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java" + }, + { + "raw": "can not create %s with physical interface:[%s] which was already been used by another vSwitch type.", + "en_US": "can not create {0} with physical interface:[{1}] which was already been used by another vSwitch type.", + "zh_CN": "无法创建物理接口为[{1}]的{0},该接口已由另一个vSwitch类型使用。", + "arguments": [ + "l2Vo.getvSwitchType()", + "l2Vo.getPhysicalInterface()" + ], + "line": 106, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java" + }, + { + "raw": "cluster[uuid:%s] do not support ovs-dpdk", + "en_US": "cluster[uuid:{0}] do not support ovs-dpdk", + "zh_CN": "集群[uuid:{0}]不支持OVS-DPDK", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 131, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java" + }, + { + "raw": "physical interface[%s] in host[uuid:%s] is not sriov virtualized, please perform sriov cutting operation on physical interface[%s].", + "en_US": "physical interface[{0}] in host[uuid:{1}] is not sriov virtualized, please perform sriov cutting operation on physical interface[{2}].", + "zh_CN": "物理机[uuid:{1}]中的物理接口[{0}]未进行SRIOV虚拟化,请对物理接口[{2}]进行SRIOV裁剪操作。", + "arguments": [ + "l2NicName", + "hostUuid", + "l2NicName" + ], + "line": 147, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java" + }, + { + "raw": "failed to delete vdpas in host[uuid:%s] for vm[uuid:%s] : %s", + "en_US": "failed to delete vdpas in host[uuid:{0}] for vm[uuid:{1}] : {2}", + "zh_CN": "无法删除物理机[uuid:{0}]中VM[uuid:{1}]的VDPA:{2}", + "arguments": [ + "hostUuid", + "vmUuid", + "reply.getError()" + ], + "line": 49, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicKvmBackend.java" + }, + { + "raw": "failed to generate vdpas in host[uuid:%s] for vm[uuid:%s] : %s", + "en_US": "failed to generate vdpas in host[uuid:{0}] for vm[uuid:{1}] : {2}", + "zh_CN": "无法在物理机[uuid:{0}]中为VM[uuid:{1}]生成VDPA:{2}", + "arguments": [ + "hostUuid", + "vmUuid", + "reply.getError()" + ], + "line": 86, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicKvmBackend.java" + }, + { + "raw": "cannot find available vdpa nic pci device on host[uuid:%s] for l3[uuid:%s]", + "en_US": "cannot find available vdpa nic pci device on host[uuid:{0}] for l3[uuid:{1}]", + "zh_CN": "在物理机[uuid:{0}]上找不到可用于L3[uuid:{1}]的VDPA NIC PCI设备", + "arguments": [ + "hostUuid", + "l3Uuid" + ], + "line": 650, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java" + }, + { + "raw": "vm[uuid:%s] needs to be running when attach vdpa nics, but no hostUuid found", + "en_US": "vm[uuid:{0}] needs to be running when attach vdpa nics, but no hostUuid found", + "zh_CN": "连接VDPA NIC时需要运行VM[uuid:{0}],但未找到HOSTuuid", + "arguments": [ + "vmUuid" + ], + "line": 263, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java" + }, + { + "raw": "cannot generate vdpa for vm[uuid:%s] on the destination host[uuid:%s]", + "en_US": "cannot generate vdpa for vm[uuid:{0}] on the destination host[uuid:{1}]", + "zh_CN": "无法为目标物理机[uuid:{1}]上的云主机[uuid:{0}]生成VDPA", + "arguments": [ + "inv.getUuid()", + "destHostUuid" + ], + "line": 688, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java" + }, + { + "raw": "no candidate host with enough vdpa resource", + "en_US": "no candidate host with enough vdpa resource", + "zh_CN": "没有具有足够VDPA资源的候选物理机", + "arguments": [], + "line": 835, + "fileName": "src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java" + }, + { + "raw": "not dest host found in db, can\u0027t send change password cmd to the host!", + "en_US": "not dest host found in db, can\u0027t send change password cmd to the host!", + "zh_CN": "没有在物理机上发现数据库,不能发送更改密码的指令到这个物理机上", + "arguments": [], + "line": 63, + "fileName": "src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java" + }, + { + "raw": "not account preference found, send change password cmd to the host!", + "en_US": "not account preference found, send change password cmd to the host!", + "zh_CN": "没有优先级账户去发送改变密码的指令到物理机", + "arguments": [], + "line": 64, + "fileName": "src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java" + }, + { + "raw": "fail to attach virtio driver because read md5 of file[%s] fail in mn[uuid:%s]: file not found on classpath", + "en_US": "fail to attach virtio driver because read md5 of file[{0}] fail in mn[uuid:{1}]: file not found on classpath", + "zh_CN": "无法附加virtio驱动程序,因为在Mn[uuid:{1}]中读取文件[{0}]的MD5失败:在类路径中找不到文件", + "arguments": [ + "srcPath", + "getManagementServerId()" + ], + "line": 160, + "fileName": "src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java" + }, + { + "raw": "fail to attach virtio driver because read md5 of file[%s] fail in mn[uuid:%s]: %s", + "en_US": "fail to attach virtio driver because read md5 of file[{0}] fail in mn[uuid:{1}]: {2}", + "zh_CN": "无法附加virtio驱动程序,因为在Mn[uuid:{1}]中读取文件[{0}]的MD5失败:{2}", + "arguments": [ + "srcPath", + "getManagementServerId()", + "e.getMessage()" + ], + "line": 172, + "fileName": "src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java" + }, + { + "raw": "fail to attach virtio driver because of invalid md5 of file[%s] in mn[uuid:%s]", + "en_US": "fail to attach virtio driver because of invalid md5 of file[{0}] in mn[uuid:{1}]", + "zh_CN": "无法附加virtio驱动程序,因为Mn[uuid:{1}]中文件[{0}]的MD5无效", + "arguments": [ + "srcPath", + "getManagementServerId()" + ], + "line": 167, + "fileName": "src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java" + }, + { + "raw": "only host(s)[uuid(s): %s] can access data volume.", + "en_US": "only host(s)[uuid(s): {0}] can access data volume.", + "zh_CN": "只有物理机[uuid:{0}]可以访问数据云盘。", + "arguments": [ + "spec.getDataVolumeRequiredHostUuids()" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/compute/vm/CheckIfCreateTemporaryTemplateFlow.java" + }, + { + "raw": "cpu topology is not correct, cpuNum[%s], configured cpuSockets[%s], cpuCores[%s], cpuThreads[%s]; Calculated cpuSockets[%s], cpuCores[%s], cpuThreads[%s]", + "en_US": "cpu topology is not correct, cpuNum[{0}], configured cpuSockets[{1}], cpuCores[{2}], cpuThreads[{3}]; Calculated cpuSockets[{4}], cpuCores[{5}], cpuThreads[{6}]", + "zh_CN": "CPU拓扑结构不正确,cpunum[{0}],已配置的cpusockets[{1}],cpuCore[{2}],cpuThreads[{3}]。计算的CPU套接字[{4}],CPU核心[{5}],CPU线程[{6}]", + "arguments": [ + "cpuNum", + "cpuSockets", + "cpuCores", + "cpuThreads", + "socketNum", + "coreNum", + "threadNum" + ], + "line": 71, + "fileName": "src/main/java/org/zstack/compute/vm/CpuTopology.java" + }, + { + "raw": "VM[uuid:%s] has attached ISO[uuid:%s]", + "en_US": "VM[uuid:{0}] has attached ISO[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已经加载了ISO[uuid:{1}]", + "arguments": [ + "vmUuid", + "isoUuid" + ], + "line": 40, + "fileName": "src/main/java/org/zstack/compute/vm/IsoOperator.java" + }, + { + "raw": "All vm[uuid:%s] CD-ROMs have mounted ISO", + "en_US": "All vm[uuid:{0}] CD-ROMs have mounted ISO", + "zh_CN": "所有VM[uuid:{0}]CD-ROM都已装载ISO", + "arguments": [ + "vmUuid" + ], + "line": 48, + "fileName": "src/main/java/org/zstack/compute/vm/IsoOperator.java" + }, + { + "raw": "invalid virtio driver device format: %s", + "en_US": "invalid virtio driver device format: {0}", + "zh_CN": "无效的virtio驱动程序设备格式:{0}", + "arguments": [ + "driverFormat" + ], + "line": 142, + "fileName": "src/main/java/org/zstack/compute/vm/KvmUserVmVirtIODriverExtension.java" + }, + { + "raw": "This is not a valid MAC address [%s]", + "en_US": "This is not a valid MAC address [{0}]", + "zh_CN": "这是一个无效的MAC地址", + "arguments": [ + "mac" + ], + "line": 77, + "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + }, + { + "raw": "Not a valid MAC address [%s]", + "en_US": "Not a valid MAC address [{0}]", + "zh_CN": "这是一个无效的MAC地址[{0}]", + "arguments": [ + "mac" + ], + "line": 87, + "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + }, + { + "raw": "Disallowed address", + "en_US": "Disallowed address", + "zh_CN": "不被允许的MAC地址", + "arguments": [], + "line": 90, + "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + }, + { + "raw": "Expected unicast mac address, found multicast MAC address [%s]", + "en_US": "Expected unicast mac address, found multicast MAC address [{0}]", + "zh_CN": "期望的是一个单播的MAC地址,但找到的是一个组播的MAC地址[{0}]", + "arguments": [ + "mac" + ], + "line": 93, + "fileName": "src/main/java/org/zstack/compute/vm/MacOperator.java" + }, + { + "raw": "state of vm[uuid:%s] is not in Running state, can not sync clock", + "en_US": "state of vm[uuid:{0}] is not in Running state, can not sync clock", + "zh_CN": "VM[uuid:{0}]的状态未处于运行状态,无法同步时钟", + "arguments": [], + "line": 251, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "hot plug is not turned off,can not open vm numa", + "en_US": "hot plug is not turned off,can not open vm numa", + "zh_CN": "热插拔未关闭,无法打开VM NUMA", + "arguments": [], + "line": 442, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "vm[uuid: %s]\u0027s state is not Stopped now, cannot operate \u0027changevmimage\u0027 action", + "en_US": "vm[uuid: {0}]\u0027s state is not Stopped now, cannot operate \u0027changevmimage\u0027 action", + "zh_CN": "VM[uuid:{0}]的状态现在未停止,无法执行“ ChangeVMImage ”操作", + "arguments": [ + "self.getUuid()" + ], + "line": 609, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "vm[uuid:%s] cluster uuid is null, cannot change image for it", + "en_US": "vm[uuid:{0}] cluster uuid is null, cannot change image for it", + "zh_CN": "VM[uuid:{0}]集群uuid为空,无法更改其镜像", + "arguments": [ + "self.getUuid()" + ], + "line": 662, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "vm[uuid:%s] is in cluster[uuid:%s], but there is no available host in the cluster, cannot change image for the vm", + "en_US": "vm[uuid:{0}] is in cluster[uuid:{1}], but there is no available host in the cluster, cannot change image for the vm", + "zh_CN": "云主机[uuid:{0}]位于集群[uuid:{1}]中,但集群中没有可用的物理机,无法更改云主机的镜像", + "arguments": [ + "self.getUuid()", + "self.getClusterUuid()" + ], + "line": 675, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "cannot find backupStorage for volume[uuid: %s, psUuid: %s], required primary storage uuid:%s", + "en_US": "cannot find backupStorage for volume[uuid: {0}, psUuid: {1}], required primary storage uuid:{2}", + "zh_CN": "找不到卷[uuid:{0},PSuuid:{1}]的BackupStorage,所需的主存储uuid为{2}", + "arguments": [ + "vivo.getRootVolumeUuid()", + "vivo.getRootVolume().getPrimaryStorageUuid()", + "msg.getPrimaryStorageUuidForRootVolume()" + ], + "line": 967, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "can not find backup storage, unable to commit volume snapshot[psUuid:%s] as image, destination required PS uuid:%s", + "en_US": "can not find backup storage, unable to commit volume snapshot[psUuid:{0}] as image, destination required PS uuid:{1}", + "zh_CN": "找不到备份存储,无法将卷快照[PSuuid:{0}]作为镜像提交,目标需要PS uuid:{1}", + "arguments": [ + "vol.getPrimaryStorageUuid()", + "requiredPsUuid" + ], + "line": 1152, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "direction must be set to in or out", + "en_US": "direction must be set to in or out", + "zh_CN": "方法必须设置in或者out", + "arguments": [], + "line": 2052, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "inboundBandwidth must be set no more than %s.", + "en_US": "inboundBandwidth must be set no more than {0}.", + "zh_CN": "下行带宽不能超过{0}", + "arguments": [ + "struct.inboundBandwidthUpthreshold" + ], + "line": 2132, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "outboundBandwidth must be set no more than %s.", + "en_US": "outboundBandwidth must be set no more than {0}.", + "zh_CN": "上行带宽不能超过{0}", + "arguments": [ + "struct.outboundBandwidthUpthreshold" + ], + "line": 2142, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "vm [%s]\u0027 state must be Running or Paused to sync nic qos", + "en_US": "vm [{0}]\u0027 state must be Running or Paused to sync nic qos", + "zh_CN": "VM[{0}]状态必须为“正在运行”或“已暂停”才能同步NIC QoS", + "arguments": [ + "self.getUuid()" + ], + "line": 2199, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "vm [%s]\u0027s HostUuid is null, cannot sync nic qos", + "en_US": "vm [{0}]\u0027s HostUuid is null, cannot sync nic qos", + "zh_CN": "VM[{0}]的Hostuuid为空,无法同步NIC QoS", + "arguments": [], + "line": 2204, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "not dest host found in db by uuid: %s, can\u0027t send change password cmd to the host!", + "en_US": "not dest host found in db by uuid: {0}, can\u0027t send change password cmd to the host!", + "zh_CN": "没有在物理机{0}上发现数据库,不能发送更改密码的指令到这个物理机上", + "arguments": [ + "amsg.getVmInstanceUuid()" + ], + "line": 2661, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "state is not correct while change password.", + "en_US": "state is not correct while change password.", + "zh_CN": "该状态不支持修改密码", + "arguments": [], + "line": 2691, + "fileName": "src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java" + }, + { + "raw": "vm[uuid:%s] cdRom deviceId repetition", + "en_US": "vm[uuid:{0}] cdRom deviceId repetition", + "zh_CN": "VM[uuid:{0}]CDROM DeviceID重复", + "arguments": [ + "spec.getVmInventory().getUuid()" + ], + "line": 56, + "fileName": "src/main/java/org/zstack/compute/vm/VmAllocateCdRomFlow.java" + }, + { + "raw": "creation rely on image cache[uuid:%s, locate ps uuids: [%s]], cannot create other places.", + "en_US": "creation rely on image cache[uuid:{0}, locate ps uuids: [{1}]], cannot create other places.", + "zh_CN": "创建依赖于镜像缓存[uuid:{0},定位PS uuid:[{1}]],无法创建其他位置。", + "arguments": [ + "imageUuid", + "cachedPsUuids" + ], + "line": 69, + "fileName": "src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java" + }, + { + "raw": "there is no available ipRange on L3 network [%s]", + "en_US": "there is no available ipRange on L3 network [{0}]", + "zh_CN": "三层网络[{0}]中没有可用的网络段", + "arguments": [ + "v.getL3Invs().get(0).getUuid()" + ], + "line": 83, + "fileName": "src/main/java/org/zstack/compute/vm/VmAllocateNicIpFlow.java" + }, + { + "raw": " Can not find the vm\u0027s host, please start the vm[%s], then mount the disk", + "en_US": " Can not find the vm\u0027s host, please start the vm[{0}], then mount the disk", + "zh_CN": "未找到云主机的物理机,请重启云主机[{0}],然后挂载云盘", + "arguments": [ + "spec.getVmInventory().getUuid()" + ], + "line": 50, + "fileName": "src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java" + }, + { + "raw": "cannot find the iso[uuid:%s] in any connected backup storage attached to the zone[uuid:%s]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is running\\n2. if the backup storage is in connected status, if not, try reconnecting it", + "en_US": "cannot find the iso[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is running\\n2. if the backup storage is in connected status, if not, try reconnecting it", + "zh_CN": "不能发现iso[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \\n1. 镜像服务器是否已经挂载到区域中的任何运行状态的云主机[name: {2}, uuid:{3}]上;\\n2. 如果镜像服务器不是处于连接状态,请尝试重连", + "arguments": [ + "iso.getUuid()", + "host.getZoneUuid()", + "spec.getVmInventory().getName()", + "spec.getVmInventory().getUuid()" + ], + "line": 68, + "fileName": "src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java" + }, + { + "raw": "VM[uuid:%s] already has an ISO[uuid:%s] attached", + "en_US": "VM[uuid:{0}] already has an ISO[uuid:{1}] attached", + "zh_CN": "云主机[uuid:{0}]已经挂载了ISO[uuid:{1}]", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getIsoUuid()" + ], + "line": 713, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "either l3NetworkUuids or backupStorageUuid must be set", + "en_US": "either l3NetworkUuids or backupStorageUuid must be set", + "zh_CN": "必须设置L3Networkuuid或BackupStorageuuid", + "arguments": [], + "line": 169, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The vm[uuid: %s] is not Running or Stopped; the current state is %s", + "en_US": "unable to change to L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", + "zh_CN": "无法更改为三层网络。VM[uuid:{0}]未运行或已停止。当前状态为{1}", + "arguments": [ + "msg.getVmInstanceUuid()", + "state" + ], + "line": 205, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The L3 network[uuid:%s] doesn\u0027t has have ip range", + "en_US": "unable to change to L3 network. The L3 network[uuid:{0}] doesn\u0027t has have ip range", + "zh_CN": "无法更改为三层网络。三层网络[uuid:{0}]没有IP范围", + "arguments": [ + "msg.getDestL3NetworkUuid()" + ], + "line": 211, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The L3 network[uuid:%s] are belonged to different l2 networks [uuids:%s]", + "en_US": "unable to change to L3 network. The L3 network[uuid:{0}] are belonged to different l2 networks [uuids:{1}]", + "zh_CN": "无法更改为三层网络。三层网络[uuid:{0}]属于不同的二层网络[uuid:{1}]", + "arguments": [ + "newAddedL3Uuids", + "l2Uuids" + ], + "line": 221, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The L3 network[uuid:%s] are belonged to l2 networks [uuids:%s] that have not been attached to any cluster", + "en_US": "unable to change to L3 network. The L3 network[uuid:{0}] are belonged to l2 networks [uuids:{1}] that have not been attached to any cluster", + "zh_CN": "无法更改为三层网络。三层网络[uuid:{0}]属于尚未连接到任何集群的二层网络[uuid:{1}]", + "arguments": [ + "newAddedL3Uuids", + "l2Uuids" + ], + "line": 228, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The L3 network[uuid:%s] is already attached to the vm[uuid: %s]", + "en_US": "unable to change to L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", + "zh_CN": "无法更改为三层网络。三层网络[uuid:{0}]已连接到云主机[uuid:{1}]", + "arguments": [ + "attachedL3Uuids", + "msg.getVmInstanceUuid()" + ], + "line": 240, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to a non-guest L3 network. The L3 network[uuid:%s] is already attached to the vm[uuid: %s]", + "en_US": "unable to change to a non-guest L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", + "zh_CN": "无法更改为非来宾三层网络。三层网络[uuid:{0}]已连接到云主机[uuid:{1}]", + "arguments": [ + "attachedL3Uuids", + "msg.getVmInstanceUuid()" + ], + "line": 247, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The L3 network[uuid:%s] is disabled", + "en_US": "unable to change to L3 network. The L3 network[uuid:{0}] is disabled", + "zh_CN": "无法更改为三层网络。三层网络[uuid:{0}]已禁用", + "arguments": [ + "l3Uuid" + ], + "line": 255, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to change to L3 network. The L3 network[uuid:%s] is a system network and vm is a user vm", + "en_US": "unable to change to L3 network. The L3 network[uuid:{0}] is a system network and vm is a user vm", + "zh_CN": "无法更改为三层网络。三层网络[uuid:{0}]是系统网络,VM是用户VM", + "arguments": [ + "l3Uuid" + ], + "line": 258, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the static IP[%s] is not in any IP range of the L3 network[uuid:%s]", + "en_US": "the static IP[{0}] is not in any IP range of the L3 network[uuid:{1}]", + "zh_CN": "该静态IP[{0}]不在三层网络[uuid:{1}]的任何IP段", + "arguments": [ + "staticIp", + "l3Uuid" + ], + "line": 942, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the static IP[%s] has been occupied on the L3 network[uuid:%s]", + "en_US": "the static IP[{0}] has been occupied on the L3 network[uuid:{1}]", + "zh_CN": "该静态IP[{0}]已经存在在三层网络[uuid:{1}]中", + "arguments": [ + "staticIp", + "l3Uuid" + ], + "line": 949, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "static ip l3 uuid[%s] is not included in nic l3 [%s]", + "en_US": "static ip l3 uuid[{0}] is not included in nic l3 [{1}]", + "zh_CN": "静态IP的三层网络[uuid:{0}]不在网卡的L3列表[uuid:{1}]中", + "arguments": [ + "e.getKey()", + "newAddedL3Uuids" + ], + "line": 912, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the image[name:%s, uuid:%s] is an ISO, rootDiskSize must be set", + "en_US": "the image[name:{0}, uuid:{1}] is an ISO, rootDiskSize must be set", + "zh_CN": "镜像[name:{0}, uuid:{1}]是一个IOS, 必须设置云盘大小", + "arguments": [ + "image.getName()", + "image.getUuid()" + ], + "line": 373, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Can not create CD-ROM for vm[uuid:%s] which is in state[%s] ", + "en_US": "Can not create CD-ROM for vm[uuid:{0}] which is in state[{1}] ", + "zh_CN": "无法为处于状态[{1}]的VM[uuid:{0}]创建CD-ROM", + "arguments": [ + "msg.getVmInstanceUuid()", + "vo.getState().toString()" + ], + "line": 383, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Current platform %s not support update nic driver yet", + "en_US": "Current platform {0} not support update nic driver yet", + "zh_CN": "当前平台{0}尚不支持更新NIC驱动程序", + "arguments": [ + "vo.getPlatform()" + ], + "line": 391, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "rootDiskSize is needed when image media type is ISO", + "en_US": "rootDiskSize is needed when image media type is ISO", + "zh_CN": "当镜像类型是ISO时云盘大小需要设置", + "arguments": [], + "line": 407, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the vm[uuid:%s] is already on host[uuid:%s]", + "en_US": "the vm[uuid:{0}] is already on host[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已经运行于物理机[uuid:{1}]上", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getHostUuid()" + ], + "line": 419, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the VM cannot do online cpu/memory update because of disabling Instance Offering Online Modification. Please stop the VM then do the cpu/memory update again", + "en_US": "the VM cannot do online cpu/memory update because of disabling Instance Offering Online Modification. Please stop the VM then do the cpu/memory update again", + "zh_CN": "云主机无法执行在线升级CPU/内存,因为未启用计算规格在线修改。请关闭该云主机再尝试", + "arguments": [], + "line": 436, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "The state of vm[uuid:%s] is %s. Only these state[%s] is allowed to update cpu or memory.", + "en_US": "The state of vm[uuid:{0}] is {1}. Only these state[{2}] is allowed to update cpu or memory.", + "zh_CN": "云主机[uuid:{0}]的状态为{1}。只有这些状态[{2}]允许在线升级CPU/内存", + "arguments": [ + "vo.getUuid()", + "vo.getState()", + "StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), \",\")" + ], + "line": 495, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "can\u0027t decrease capacity when vm[uuid:%s] is running", + "en_US": "can\u0027t decrease capacity when vm[uuid:{0}] is running", + "zh_CN": "无法在云主机[uuid:{0}]运行时减少容量", + "arguments": [ + "vo.getUuid()" + ], + "line": 452, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the VM cannot do cpu hot plug because of disabling cpu hot plug. Please stop the VM then do the cpu hot plug again", + "en_US": "the VM cannot do cpu hot plug because of disabling cpu hot plug. Please stop the VM then do the cpu hot plug again", + "zh_CN": "云主机无法执行在线添加CPU,因为未启用CPU热插拔。请关闭该云主机再尝试", + "arguments": [], + "line": 482, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the VM cannot do memory hot plug because of disabling memory hot plug. Please stop the VM then do the memory hot plug again", + "en_US": "the VM cannot do memory hot plug because of disabling memory hot plug. Please stop the VM then do the memory hot plug again", + "zh_CN": "云主机无法执行在线添加内存,因为未启用内存热插拔。请关闭该云主机再尝试", + "arguments": [], + "line": 488, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "can\u0027t decrease cpu of vm[uuid:%s] when it is running", + "en_US": "can\u0027t decrease cpu of vm[uuid:{0}] when it is running", + "zh_CN": "无法在云主机[uuid:{0}]运行时减少CPU数目", + "arguments": [ + "vo.getUuid()" + ], + "line": 506, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "can\u0027t decrease memory size of vm[uuid:%s] when it is running", + "en_US": "can\u0027t decrease memory size of vm[uuid:{0}] when it is running", + "zh_CN": "无法在云主机[uuid:{0}]运行时减少容量", + "arguments": [ + "vo.getUuid()" + ], + "line": 512, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "either l3NetworkUuids or imageUuid must be set", + "en_US": "either l3NetworkUuids or imageUuid must be set", + "zh_CN": "三层网络的uuid们或者镜像的uuid必须被设置", + "arguments": [], + "line": 523, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "%s is not a valid IPv4 address", + "en_US": "{0} is not a valid IPv4 address", + "zh_CN": "{0}不是有效的IPv4地址", + "arguments": [ + "ip" + ], + "line": 538, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "ip address [%s] already set to vmNic [uuid:%s]", + "en_US": "ip address [{0}] already set to vmNic [uuid:{1}]", + "zh_CN": "IP地址[{0}]已经设置到网卡[uuid:{1}]", + "arguments": [ + "ip", + "vmNicVO.getUuid()" + ], + "line": 576, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "ip address [%s] is not in ip range [%s]", + "en_US": "ip address [{0}] is not in ip range [{1}]", + "zh_CN": "IP地址[{0}]不在IP地址段[{1}]范围内", + "arguments": [ + "ip", + "rangeVO.getNetworkCidr()" + ], + "line": 557, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "%s is not a valid IPv6 address", + "en_US": "{0} is not a valid IPv6 address", + "zh_CN": "{0}不是有效的IPv6地址", + "arguments": [ + "ip" + ], + "line": 566, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "ip address [%s] is not in ip range [startIp %s, endIp %s]", + "en_US": "ip address [{0}] is not in ip range [startIp {1}, endIp {2}]", + "zh_CN": "IP地址[{0}]不在IP地址段[{1}-{2}]范围内", + "arguments": [ + "ip", + "rangeVO.getStartIp()", + "rangeVO.getEndIp()" + ], + "line": 584, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "could not set ip address, due to no ip address is specified", + "en_US": "could not set ip address, due to no ip address is specified", + "zh_CN": "无法设置IP地址,因为未指定IP地址", + "arguments": [], + "line": 595, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "static ip [%s] format error", + "en_US": "static ip [{0}] format error", + "zh_CN": "静态IP[{0}]格式错误", + "arguments": [ + "msg.getIp()" + ], + "line": 610, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "ipv4 address need a netmask", + "en_US": "ipv4 address need a netmask", + "zh_CN": "IPv4地址需要网络掩码", + "arguments": [], + "line": 622, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "ip address [%s] already set to vmNic", + "en_US": "ip address [{0}] already set to vmNic", + "zh_CN": "IP地址[{0}]已设置为vmnic", + "arguments": [ + "msg.getIp6()" + ], + "line": 640, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "ipv6 address need a prefix", + "en_US": "ipv6 address need a prefix", + "zh_CN": "IPv6地址需要前缀", + "arguments": [], + "line": 634, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the VM[uuid:%s] has no nic on the L3 network[uuid:%s]", + "en_US": "the VM[uuid:{0}] has no nic on the L3 network[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]在三层网络[uuid:{1}]上没有任何网卡", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getL3NetworkUuid()" + ], + "line": 654, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "could not delete static ip [%s] for vm [uuid:%s] because it doesn\u0027t existed", + "en_US": "could not delete static ip [{0}] for vm [uuid:{1}] because it doesn\u0027t existed", + "zh_CN": "无法删除VM[uuid:{1}]的静态IP[{0}],因为它不存在", + "arguments": [ + "msg.getStaticIp()", + "msg.getVmInstanceUuid()" + ], + "line": 661, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "invalid boot device[%s] in boot order%s", + "en_US": "invalid boot device[{0}] in boot order{1}", + "zh_CN": "在启动列表{1}中的设备[{0}]启动失败", + "arguments": [ + "o", + "msg.getBootOrder()" + ], + "line": 673, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "boot volume cannot be shareable.", + "en_US": "boot volume cannot be shareable.", + "zh_CN": "启动卷无法共享。", + "arguments": [], + "line": 696, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "volume[uuid:%s] must be attached to vm[uuid:%s]", + "en_US": "volume[uuid:{0}] must be attached to vm[uuid:{1}]", + "zh_CN": "卷[uuid:{0}]必须连接到云主机[uuid:{1}]", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getVmInstanceUuid()" + ], + "line": 700, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "the vm %s with memory snapshots do not support setting boot volume", + "en_US": "the vm {0} with memory snapshots do not support setting boot volume", + "zh_CN": "具有内存快照的云主机{0}不支持设置启动卷", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 705, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Unsupported Image Media Type: [%s] ", + "en_US": "Unsupported Image Media Type: [{0}] ", + "zh_CN": "不支持的镜像媒体类型:[{0}]", + "arguments": [ + "type" + ], + "line": 718, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "The cdRom[uuid:%s] does not exist", + "en_US": "The cdRom[uuid:{0}] does not exist", + "zh_CN": "CDROM[uuid:{0}]不存在", + "arguments": [ + "cdRomUuid" + ], + "line": 733, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "VM[uuid:%s] cdRom[uuid:%s] has mounted the ISO", + "en_US": "VM[uuid:{0}] cdRom[uuid:{1}] has mounted the ISO", + "zh_CN": "VM[uuid:{0}]CDROM[uuid:{1}]已装载ISO", + "arguments": [ + "msg.getVmInstanceUuid()", + "cdRomUuid" + ], + "line": 737, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "VM[uuid:%s] has multiple ISOs attached, specify the isoUuid when detaching", + "en_US": "VM[uuid:{0}] has multiple ISOs attached, specify the isoUuid when detaching", + "zh_CN": "云主机[uuid:{0}]已经加载了多个ISO,卸载ISO时需要指定isoUuid", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 755, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The L3 network[uuid:%s] is disabled", + "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] is disabled", + "zh_CN": "不能挂载三层网络,因为该三层网络[uuid:{0}]处于未启动状态", + "arguments": [ + "l3Uuid" + ], + "line": 863, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The vm[uuid: %s] is not Running or Stopped; the current state is %s", + "en_US": "unable to attach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", + "zh_CN": "无法挂载三层网络。云主机[uuid: {0}]既不处于Running也不处于Stopped状态中,当前状态为{1}", + "arguments": [ + "msg.getVmInstanceUuid()", + "state" + ], + "line": 813, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The L3 network[uuid:%s] doesn\u0027t has have ip range", + "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] doesn\u0027t has have ip range", + "zh_CN": "无法连接三层网络。三层网络[uuid:{0}]没有IP范围", + "arguments": [ + "msg.getL3NetworkUuid()" + ], + "line": 819, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The L3 network[uuid:%s] are belonged to different l2 networks [uuids:%s]", + "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to different l2 networks [uuids:{1}]", + "zh_CN": "不能挂载三层网络,三层网络[uuid:{0}]属于不同的二层网络", + "arguments": [ + "newAddedL3Uuids", + "l2Uuids" + ], + "line": 829, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The L3 network[uuid:%s] are belonged to l2 networks [uuids:%s] that have not been attached to any cluster", + "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to l2 networks [uuids:{1}] that have not been attached to any cluster", + "zh_CN": "无法连接三层网络。三层网络[uuid:{0}]属于尚未连接到任何集群的二层网络[uuid:{1}]", + "arguments": [ + "newAddedL3Uuids", + "l2Uuids" + ], + "line": 836, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The L3 network[uuid:%s] is already attached to the vm[uuid: %s]", + "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", + "zh_CN": "不能挂载三层网络,三层网络[uuid:{0}]已经挂载到云主机[uuid: {1}]上了", + "arguments": [ + "attachedL3Uuids", + "msg.getVmInstanceUuid()" + ], + "line": 848, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a non-guest L3 network. The L3 network[uuid:%s] is already attached to the vm[uuid: %s]", + "en_US": "unable to attach a non-guest L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", + "zh_CN": "无法连接非来宾三层网络。三层网络[uuid:{0}]已连接到云主机[uuid:{1}]", + "arguments": [ + "attachedL3Uuids", + "msg.getVmInstanceUuid()" + ], + "line": 855, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach a L3 network. The L3 network[uuid:%s] is a system network and vm is a user vm", + "en_US": "unable to attach a L3 network. The L3 network[uuid:{0}] is a system network and vm is a user vm", + "zh_CN": "不能连接三层网络。这个三层网络[uuid:{0}]是系统网络,但云主机是一个用户云主机", + "arguments": [ + "l3Uuid" + ], + "line": 866, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "invalid json format, causes: %s", + "en_US": "invalid json format, causes: {0}", + "zh_CN": "无效的JSON格式,原因:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 1300, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic. The vm[uuid: %s] is not Running or Stopped; the current state is %s", + "en_US": "unable to attach the nic. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", + "zh_CN": "无法连接NIC。VM[uuid:{0}]未运行或已停止。当前状态为{1}", + "arguments": [ + "msg.getVmInstanceUuid()", + "state" + ], + "line": 986, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic. The nic has been attached with vm[uuid: %s]", + "en_US": "unable to attach the nic. The nic has been attached with vm[uuid: {0}]", + "zh_CN": "无法连接NIC。已使用VM[uuid:{0}]连接NIC", + "arguments": [ + "vmNicVO.getVmInstanceUuid()" + ], + "line": 993, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic. Its L3 network[uuid:%s] is already attached to the vm[uuid: %s]", + "en_US": "unable to attach the nic. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", + "zh_CN": "无法连接NIC。其三层网络[uuid:{0}]已连接到云主机[uuid:{1}]", + "arguments": [ + "vmNicVO.getL3NetworkUuid()", + "msg.getVmInstanceUuid()" + ], + "line": 1004, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic with a non-guest L3 network. Its L3 network[uuid:%s] is already attached to the vm[uuid: %s]", + "en_US": "unable to attach the nic with a non-guest L3 network. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}]", + "zh_CN": "无法将NIC连接到非来宾三层网络。其三层网络[uuid:{0}]已连接到云主机[uuid:{1}]", + "arguments": [ + "vmNicVO.getL3NetworkUuid()", + "msg.getVmInstanceUuid()" + ], + "line": 1009, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic. Its L3 network[uuid:%s] is disabled", + "en_US": "unable to attach the nic. Its L3 network[uuid:{0}] is disabled", + "zh_CN": "无法连接NIC。其三层网络[uuid:{0}]已禁用", + "arguments": [ + "l3NetworkVO.getUuid()" + ], + "line": 1018, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic. Its L3 network[uuid:%s] is a system network and vm is a user vm", + "en_US": "unable to attach the nic. Its L3 network[uuid:{0}] is a system network and vm is a user vm", + "zh_CN": "无法连接NIC。其三层网络[uuid:{0}]是系统网络,VM是用户VM", + "arguments": [ + "l3NetworkVO.getUuid()" + ], + "line": 1021, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to attach the nic. Its l2 network [uuid:%s] that have not been attached to any cluster", + "en_US": "unable to attach the nic. Its l2 network [uuid:{0}] that have not been attached to any cluster", + "zh_CN": "无法连接NIC。其二层网络[uuid:{0}]尚未连接到任何集群", + "arguments": [ + "l3NetworkVO.getL2NetworkUuid()" + ], + "line": 1028, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "could not update nic[uuid: %s] state, due to nic type[%s] not support", + "en_US": "could not update nic[uuid: {0}] state, due to nic type[{1}] not support", + "zh_CN": "无法更新NIC[uuid:{0}]状态,因为不支持NIC类型[{1}]", + "arguments": [ + "msg.getVmNicUuid()", + "nicVO.getType()" + ], + "line": 1037, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "could not update nic[uuid: %s] state, due to vm not support", + "en_US": "could not update nic[uuid: {0}] state, due to vm not support", + "zh_CN": "无法更新NIC[uuid:{0}]状态,因为VM不支持", + "arguments": [ + "msg.getVmNicUuid()" + ], + "line": 1043, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "unable to detach a L3 network. The vm[uuid: %s] is not Running or Stopped; the current state is %s", + "en_US": "unable to detach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1}", + "zh_CN": "不能卸载三层网络,云主机[uuid: {0}]不是运行状态或者暂停状态,状态为{1}", + "arguments": [ + "vmUuid", + "state" + ], + "line": 1060, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "vm[uuid:%s] can only attach volume when state is Running or Stopped, current state is %s", + "en_US": "vm[uuid:{0}] can only attach volume when state is Running or Stopped, current state is {1}", + "zh_CN": "云主机[uuid:{0}]挂载盘时状态只能是运行或者暂停状态,而现在的状态是{1}", + "arguments": [ + "msg.getVmInstanceUuid()", + "state" + ], + "line": 1075, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "image mediaType is ISO but missing root disk settings", + "en_US": "image mediaType is ISO but missing root disk settings", + "zh_CN": "镜像媒体类型为ISO,但缺少根磁盘设置", + "arguments": [], + "line": 1083, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Unexpected root disk settings", + "en_US": "Unexpected root disk settings", + "zh_CN": "意外的根磁盘设置", + "arguments": [], + "line": 1087, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Unexpected data disk settings. dataDiskSizes need to be greater than 0", + "en_US": "Unexpected data disk settings. dataDiskSizes need to be greater than 0", + "zh_CN": "意外的数据磁盘设置。DataDiskSizes需要大于0", + "arguments": [], + "line": 1154, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "at least one of field platform in msg or image[uuid:%s] should be set", + "en_US": "at least one of field platform in msg or image[uuid:{0}] should be set", + "zh_CN": "至少应设置消息或镜像[uuid:{0}]中的一个字段平台", + "arguments": [ + "msg.getImageUuid()" + ], + "line": 1206, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "at least one of field guestOsType in msg or image[uuid:%s] should be set", + "en_US": "at least one of field guestOsType in msg or image[uuid:{0}] should be set", + "zh_CN": "至少应设置邮件或镜像[uuid:{0}]中的一个字段GuestOsType", + "arguments": [ + "msg.getImageUuid()" + ], + "line": 1210, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "at least one of field architecture in msg or image[uuid:%s] should be set", + "en_US": "at least one of field architecture in msg or image[uuid:{0}] should be set", + "zh_CN": "至少应设置消息或镜像[uuid:{0}]中的一个字段体系结构", + "arguments": [ + "msg.getImageUuid()" + ], + "line": 1214, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Cannot set the following properties at the same time: %s", + "en_US": "Cannot set the following properties at the same time: {0}", + "zh_CN": "不能同时设置以下属性:{0}", + "arguments": [ + "errorMsg" + ], + "line": 1349, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Need to set one of the following properties, and can only be one of them: %s", + "en_US": "Need to set one of the following properties, and can only be one of them: {0}", + "zh_CN": "需要设置以下属性之一,且只能是其中一个:{0}", + "arguments": [ + "properties" + ], + "line": 1357, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "cannot create vm instance from a shareable volume.", + "en_US": "cannot create vm instance from a shareable volume.", + "zh_CN": "无法从可共享云盘创建VM实例。", + "arguments": [], + "line": 1249, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "could not create vm instance from a attached volume.", + "en_US": "could not create vm instance from a attached volume.", + "zh_CN": "无法从连接的卷创建VM实例。", + "arguments": [], + "line": 1253, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "volume[uuid:%s] could not satisfy conditions[state:Enabled status:Ready]", + "en_US": "volume[uuid:{0}] could not satisfy conditions[state:Enabled status:Ready]", + "zh_CN": "卷[uuid:{0}]无法满足条件[状态:已启用状态:就绪]", + "arguments": [ + "msg.getVolumeUuid()" + ], + "line": 1257, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "l3NetworkUuids and vmNicInventories mustn\u0027t both be empty or both be set", + "en_US": "l3NetworkUuids and vmNicInventories mustn\u0027t both be empty or both be set", + "zh_CN": "l3NetworkUuids和vmnicinventory不能同时为空或同时设置", + "arguments": [], + "line": 1293, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "The image[uuid\u003d%s] does not exist", + "en_US": "The image[uuid\u003d{0}] does not exist", + "zh_CN": "镜像[uuid\u003d{0}]不存在", + "arguments": [ + "cdRomIsoUuid" + ], + "line": 1415, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "Do not allow to mount duplicate ISO", + "en_US": "Do not allow to mount duplicate ISO", + "zh_CN": "不允许装载重复的ISO", + "arguments": [], + "line": 1420, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "The console password cannot start with \u0027password\u0027 which may trigger a VNC security issue", + "en_US": "The console password cannot start with \u0027password\u0027 which may trigger a VNC security issue", + "zh_CN": "控制台密码不能以password开头,这样可能导致一个VNC安全问题", + "arguments": [], + "line": 1435, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "can not call this api because it\u0027s Deprecated", + "en_US": "can not call this api because it\u0027s Deprecated", + "zh_CN": "无法调用此API,因为它已被弃用", + "arguments": [], + "line": 1440, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "The CdRom[%s] Already the default", + "en_US": "The CdRom[{0}] Already the default", + "zh_CN": "CDROM[{0}]已经是默认的", + "arguments": [ + "vmCdRomVO.getUuid()" + ], + "line": 1457, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + }, + { + "raw": "vm[uuid:%s, name:%s] has been deleted", + "en_US": "vm[uuid:{0}, name:{1}] has been deleted", + "zh_CN": "云主机[uuid:{0}, name:{1}]已经被删除了", + "arguments": [ + "vo.getUuid()", + "vo.getName()" + ], + "line": 271, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "failed to check state of the vm[uuid:%s] on the host[uuid:%s], %s", + "en_US": "failed to check state of the vm[uuid:{0}] on the host[uuid:{1}], {2}", + "zh_CN": "无法检查物理机[uuid:{1}]上的VM[uuid:{0}]的状态,{2}", + "arguments": [ + "vmInv.getUuid()", + "vmInv.getHostUuid()", + "reply.getError()" + ], + "line": 595, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "got an unrecognized state of the vm[uuid:%s] on the host[uuid:%s]", + "en_US": "got an unrecognized state of the vm[uuid:{0}] on the host[uuid:{1}]", + "zh_CN": "物理机[uuid:{1}]上的VM[uuid:{0}]的状态无法识别", + "arguments": [ + "vmInv.getUuid()", + "vmInv.getHostUuid()" + ], + "line": 602, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "the vm[uuid:%s] has no nic on the L3 network[uuid:%s]", + "en_US": "the vm[uuid:{0}] has no nic on the L3 network[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}] 没有网卡在三层网络[uuid:{1}]上", + "arguments": [ + "self.getUuid()", + "l3Uuid" + ], + "line": 984, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "the vm has been deleted", + "en_US": "the vm has been deleted", + "zh_CN": "云主机已经被删除了", + "arguments": [], + "line": 1382, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "VM[uuid:%s] state is not Running.", + "en_US": "VM[uuid:{0}] state is not Running.", + "zh_CN": "VM[uuid:{0}]状态未运行。", + "arguments": [ + "msg.getUuid()" + ], + "line": 3758, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "the ISO[uuid:%s] is on backup storage that is not compatible of the primary storage[uuid:%s] where the VM[name:%s, uuid:%s] is on", + "en_US": "the ISO[uuid:{0}] is on backup storage that is not compatible of the primary storage[uuid:{1}] where the VM[name:{2}, uuid:{3}] is on", + "zh_CN": "ISO[uuid:{0}]在镜像服务器上,这个ISO不能兼容主存储[uuid:{1}]在云主机[name:{2}, uuid:{3}]上", + "arguments": [ + "isoUuid", + "psUuid", + "self.getName()", + "self.getUuid()" + ], + "line": 4837, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "host[uuid:%s] capacity is not enough to offer cpu[%s], memory[%s bytes]", + "en_US": "host[uuid:{0}] capacity is not enough to offer cpu[{1}], memory[{2} bytes]", + "zh_CN": "物理机[uuid:{0}]无法提供CPU: [{1}],内存: [{2} bytes]", + "arguments": [ + "self.getHostUuid()", + "cpuNum - oldCpuNum", + "struct.alignedMemory - oldMemorySize" + ], + "line": 5325, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "ISO[uuid:%s] is not attached to VM[uuid:%s]", + "en_US": "ISO[uuid:{0}] is not attached to VM[uuid:{1}]", + "zh_CN": "ISO[uuid:{0}]未被加载到云主机[uuid:{1}]", + "arguments": [ + "isoUuid", + "self.getUuid()" + ], + "line": 5633, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "One vm cannot create %s CDROMs, vm can only add %s CDROMs", + "en_US": "One vm cannot create {0} CDROMs, vm can only add {1} CDROMs", + "zh_CN": "一个VM无法创建{0}个CDROM,VM只能添加{1}个CDROM", + "arguments": [ + "cdRomSpecs.size()", + "max" + ], + "line": 7168, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "VM[uuid:%s] can only add %s CDROMs", + "en_US": "VM[uuid:{0}] can only add {1} CDROMs", + "zh_CN": "VM[uuid:{0}]只能添加{1}个CDROM", + "arguments": [ + "msg.getVmInstanceUuid()", + "max" + ], + "line": 8150, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "update vm[%s] priority to [%s] failed,because %s", + "en_US": "update vm[{0}] priority to [{1}] failed,because {2}", + "zh_CN": "将云主机[{0}]的优先级更新为[{1}]失败,原因是{2}", + "arguments": [ + "self.getUuid()", + "msg.getPriority()", + "reply.getError()" + ], + "line": 8219, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + }, + { + "raw": "VmInstanceStartNewCreatedVmExtensionPoint[%s] refuses to create vm[uuid:%s] because %s", + "en_US": "VmInstanceStartNewCreatedVmExtensionPoint[{0}] refuses to create vm[uuid:{1}] because {2}", + "zh_CN": "VmInstanceStartNewCreatedVmExtensionPoint[{0}] 因为{2} 拒绝创建云主机[uuid:{1}]", + "arguments": [ + "ext.getClass().getName()", + "inv.getUuid()", + "err" + ], + "line": 65, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + }, + { + "raw": "VmInstanceRebootExtensionPoint[%s] refuses to reboot vm[uuid:%s] because %s", + "en_US": "VmInstanceRebootExtensionPoint[{0}] refuses to reboot vm[uuid:{1}] because {2}", + "zh_CN": "VmInstanceRebootExtensionPoint[{0}] 因为{2} 拒绝重启云主机[uuid:{1}]", + "arguments": [ + "ext.getClass().getName()", + "inv.getUuid()", + "err" + ], + "line": 192, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + }, + { + "raw": "VmInstanceDestroyVmExtensionPoint[%s] refuses to destroy vm[uuid:%s] because %s", + "en_US": "VmInstanceDestroyVmExtensionPoint[{0}] refuses to destroy vm[uuid:{1}] because {2}", + "zh_CN": "VmInstanceDestroyVmExtensionPoint[{0}] 因为{2} 拒绝删除云主机[uuid:{1}]", + "arguments": [ + "ext.getClass().getName()", + "inv.getUuid()", + "err" + ], + "line": 234, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + }, + { + "raw": "VmInstanceStartExtensionPoint[%s] refuses to start vm[uuid:%s] because %s", + "en_US": "VmInstanceStartExtensionPoint[{0}] refuses to start vm[uuid:{1}] because {2}", + "zh_CN": "VmInstanceStartExtensionPoint[{0}] 因为{2} 拒绝启动云主机[uuid:{1}]", + "arguments": [ + "ext.getClass().getName()", + "inv.getUuid()", + "err" + ], + "line": 284, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + }, + { + "raw": "could not create vm, a vm with the name [%s] already exists", + "en_US": "could not create vm, a vm with the name [{0}] already exists", + "zh_CN": "无法创建VM,已存在名为[{0}]的VM", + "arguments": [ + "msg.getName()" + ], + "line": 1136, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "rootDiskOfferingUuid cannot be null when create vm without image", + "en_US": "rootDiskOfferingUuid cannot be null when create vm without image", + "zh_CN": "在不使用镜像的情况下创建VM时,RootDiskOfferInGuuid不能为空", + "arguments": [], + "line": 2245, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "Spice certificate does not exist, Please check if spice tls is enabled", + "en_US": "Spice certificate does not exist, Please check if spice tls is enabled", + "zh_CN": "SPICE证书不存在,请检查是否启用了SPICE TLS", + "arguments": [], + "line": 308, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "the image[uuid:%s] is not on any backup storage that has been attached to the zone[uuid:%s]", + "en_US": "the image[uuid:{0}] is not on any backup storage that has been attached to the zone[uuid:{1}]", + "zh_CN": "镜像[uuid:{0}]不在任何加载到区域[uuid:{1}]的镜像服务器上", + "arguments": [ + "msg.getImageUuid()", + "msg.getZoneUuid()" + ], + "line": 492, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "no primary storage accessible to the backup storage[uuid:%s, type:%s] is found", + "en_US": "no primary storage accessible to the backup storage[uuid:{0}, type:{1}] is found", + "zh_CN": "未找到镜像服务器[uuid:{0}, type:{1}]可访问的主存储", + "arguments": [ + "bss.get(0).getUuid()", + "bss.get(0).getType()" + ], + "line": 565, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "the primary storages[uuids:%s] has not attached any cluster on the zone[uuid:%s]", + "en_US": "the primary storages[uuids:{0}] has not attached any cluster on the zone[uuid:{1}]", + "zh_CN": "主存储[uuids:{0}]尚未加载区域[uuid:{1}]上的任何集群", + "arguments": [ + "psUuids", + "zoneUuid" + ], + "line": 586, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "no l2Networks found in clusters that have attached to primary storages[uuids:%s]", + "en_US": "no l2Networks found in clusters that have attached to primary storages[uuids:{0}]", + "zh_CN": "在已加载到主存储[uuids:{0}]的集群中未找到二层网络", + "arguments": [ + "psUuids" + ], + "line": 605, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "zoneUuid must be set because the image[name:%s, uuid:%s] is on multiple backup storage", + "en_US": "zoneUuid must be set because the image[name:{0}, uuid:{1}] is on multiple backup storage", + "zh_CN": "zoneUuid必须被设置,因为image[name:{0}, uuid:{1}]在多个镜像服务器上", + "arguments": [ + "image.getName()", + "image.getUuid()" + ], + "line": 672, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "CreateVmInstanceMsg cannot be null", + "en_US": "CreateVmInstanceMsg cannot be null", + "zh_CN": "CreateVmInstanceMsg不能为空", + "arguments": [], + "line": 1067, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "handle system tag fail when creating vm because [%s]", + "en_US": "handle system tag fail when creating vm because [{0}]", + "zh_CN": "由于[{0}],在创建VM时处理系统标记失败", + "arguments": [ + "StringUtils.join(errorCodes.stream().map(ErrorCode::getDescription).collect(Collectors.toList()), \", \")" + ], + "line": 1158, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "unable to enable this function. There are multi nics of L3 network[uuid:%s] in the vm[uuid: %s]", + "en_US": "unable to enable this function. There are multi nics of L3 network[uuid:{0}] in the vm[uuid: {1}]", + "zh_CN": "无法启用此功能。云主机[uuid:{1}]中存在多个三层网络[uuid:{0}]的NIC", + "arguments": [ + "tuple.get(0, String.class)", + "tuple.get(1, String.class)" + ], + "line": 1589, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "hostname[%s] specified in system tag[%s] is not a valid domain name", + "en_US": "hostname[{0}] specified in system tag[{1}] is not a valid domain name", + "zh_CN": "在系统标签[{1}]中特别声明的物理机名[{0}]不是一个有效的域名", + "arguments": [ + "hostname", + "tag" + ], + "line": 1623, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "only one hostname system tag is allowed, but %s got", + "en_US": "only one hostname system tag is allowed, but {0} got", + "zh_CN": "只允许通过系统标签设置一个物理机名,但是实际上有{0}", + "arguments": [ + "hostnameCount" + ], + "line": 1635, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "%s is not a valid ip address. Please correct your system tag[%s] of static IP", + "en_US": "{0} is not a valid ip address. Please correct your system tag[{1}] of static IP", + "zh_CN": "{0}不是有效的IP地址。请更正静态IP的系统标记[{1}]", + "arguments": [ + "ip", + "sysTag" + ], + "line": 1660, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "IP[%s] is already used on the L3 network[uuid:%s]. Please correct your system tag[%s] of static IP", + "en_US": "IP[{0}] is already used on the L3 network[uuid:{1}]. Please correct your system tag[{2}] of static IP", + "zh_CN": "IP[{0}]已在三层网络[uuid:{1}]上使用。请更正静态IP的系统标记[{2}]", + "arguments": [ + "ip", + "l3Uuid", + "sysTag" + ], + "line": 1666, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "IP[%s] is not available on the L3 network[uuid:%s] because: %s", + "en_US": "IP[{0}] is not available on the L3 network[uuid:{1}] because: {2}", + "zh_CN": "在三层网络[uuid:{1}]中,IP[{0}]不可用, 因为{2}", + "arguments": [ + "ip", + "l3Uuid", + "cr.getReason()" + ], + "line": 1683, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "conflict hostname in system tag[%s]; there has been a VM[uuid:%s] having hostname[%s] on L3 network[uuid:%s]", + "en_US": "conflict hostname in system tag[{0}]; there has been a VM[uuid:{1}] having hostname[{2}] on L3 network[uuid:{3}]", + "zh_CN": "系统标签的物理机名存在冲突[{0}];已经存在以一个物理机名为[{2}]的VM[uuid:{1}]出现在三层网络[uuid:{3}]中", + "arguments": [ + "tag", + "sameTag.getResourceUuid()", + "hostname", + "l3Uuid" + ], + "line": 1706, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "invalid boot device[%s] in boot order[%s]", + "en_US": "invalid boot device[{0}] in boot order[{1}]", + "zh_CN": "在引导顺序[{1}]中存在无效的引导设备[{0}]", + "arguments": [ + "o", + "order" + ], + "line": 1737, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "cpuSockets must be an integer", + "en_US": "cpuSockets must be an integer", + "zh_CN": "CPUSockets必须为整数", + "arguments": [], + "line": 1753, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "cpuCores must be an integer", + "en_US": "cpuCores must be an integer", + "zh_CN": "cpucores必须为整数", + "arguments": [], + "line": 1762, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "cpuThreads must be an integer", + "en_US": "cpuThreads must be an integer", + "zh_CN": "CPUThreads必须为整数", + "arguments": [], + "line": 1771, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "Already have one userdata systemTag for vm[uuid: %s].", + "en_US": "Already have one userdata systemTag for vm[uuid: {0}].", + "zh_CN": "在云主机[uuid:{0}]已经存在一个userdata的系统标签", + "arguments": [ + "resourceUuid" + ], + "line": 1782, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "Shouldn\u0027t be more than one userdata systemTag for one vm.", + "en_US": "Shouldn\u0027t be more than one userdata systemTag for one vm.", + "zh_CN": "在一个云主机中不能存在多个userdata的系统标签", + "arguments": [], + "line": 1808, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "vm machine type requires [q35, pc, virt], but get [%s]", + "en_US": "vm machine type requires [q35, pc, virt], but get [{0}]", + "zh_CN": "VM计算机类型需要[q35,PC,virt],但得到[{0}]", + "arguments": [ + "type" + ], + "line": 1932, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "invalid securityElementEnable[%s], %s is not securityElementEnable tag", + "en_US": "invalid securityElementEnable[{0}], {1} is not securityElementEnable tag", + "zh_CN": "SecurityElementEnable[{0}]无效,{1}不是SecurityElementEnable标记", + "arguments": [ + "systemTag", + "SecurityElementEnableTokenByTag" + ], + "line": 1992, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "invalid securityElementEnable[%s], %s is not boolean class", + "en_US": "invalid securityElementEnable[{0}], {1} is not boolean class", + "zh_CN": "SecurityElementEnable[{0}]无效,{1}不是布尔类", + "arguments": [ + "systemTag", + "SecurityElementEnableTokenByTag" + ], + "line": 1995, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "invalid usbRedirect[%s], %s is not usbRedirect tag", + "en_US": "invalid usbRedirect[{0}], {1} is not usbRedirect tag", + "zh_CN": "usbRedirect[{0}]无效,{1}不是usbRedirect标记", + "arguments": [ + "systemTag", + "usbRedirectTokenByTag" + ], + "line": 2022, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "invalid usbRedirect[%s], %s is not boolean class", + "en_US": "invalid usbRedirect[{0}], {1} is not boolean class", + "zh_CN": "usbRedirect[{0}]无效,{1}不是布尔类", + "arguments": [ + "systemTag", + "usbRedirectTokenByTag" + ], + "line": 2025, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "the resource[uuid:%s] is a ROOT volume, you cannot change its owner, instead,change the owner of the VM the root volume belongs to", + "en_US": "the resource[uuid:{0}] is a ROOT volume, you cannot change its owner, instead,change the owner of the VM the root volume belongs to", + "zh_CN": "当前资源[uuid:{0}]是一个云盘,你不能改变它的所有者,但是你能够修改对应VM的所有者", + "arguments": [ + "ref.getResourceUuid()" + ], + "line": 2561, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + }, + { + "raw": "Failed to instantiate volume. Because vm\u0027s host[uuid: %s] and allocated primary storage[uuid: %s] is not connected.", + "en_US": "Failed to instantiate volume. Because vm\u0027s host[uuid: {0}] and allocated primary storage[uuid: {1}] is not connected.", + "zh_CN": "无法实例化卷。因为VM的物理机[uuid:{0}]和分配的主存储[uuid:{1}]未连接。", + "arguments": [ + "spec.getDestHost().getUuid()", + "pinv.getUuid()" + ], + "line": 54, + "fileName": "src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java" + }, + { + "raw": "Duplicate mac address [%s]", + "en_US": "Duplicate mac address [{0}]", + "zh_CN": "重复的MAC地址[{0}]", + "arguments": [ + "msg.getMac()" + ], + "line": 211, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "clean traffic is not supported for vm type [%s]", + "en_US": "clean traffic is not supported for vm type [{0}]", + "zh_CN": "VM类型[{0}]不支持清理流量", + "arguments": [ + "vmType" + ], + "line": 221, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "The number of data volumes exceeds the limit[num: %s], please reduce the number of data volumes during vm creation.", + "en_US": "The number of data volumes exceeds the limit[num: {0}], please reduce the number of data volumes during vm creation.", + "zh_CN": "数据云盘的数量超过限制[数量:{0}],请在创建云主机期间减少数据云盘的数量。", + "arguments": [ + "KVMGlobalConfig.MAX_DATA_VOLUME_NUM.value(int.class)" + ], + "line": 100, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "Can not set security level to not %s vm [uuid:%s]", + "en_US": "Can not set security level to not {0} vm [uuid:{1}]", + "zh_CN": "设置密级失败,无法对不处于{0}状态的云主机操作[uuid:{1}]", + "arguments": [ + "VmInstanceState.Stopped", + "msg.getVmInstanceUuid()" + ], + "line": 130, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "The operation only allows on user vm", + "en_US": "The operation only allows on user vm", + "zh_CN": "该操作仅允许在用户云主机上执行", + "arguments": [], + "line": 147, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "there are not enough capacity for full vm clone to vm[uuid: %s], volumes[uuid: %s] on primary storage[uuid: %s] required: %s bytes, current available capacity is %s bytes", + "en_US": "there are not enough capacity for full vm clone to vm[uuid: {0}], volumes[uuid: {1}] on primary storage[uuid: {2}] required: {3} bytes, current available capacity is {4} bytes", + "zh_CN": "没有足够的空间对云主机[uuid: {0}]做整机克隆,主存储[uuid: {2}]上的云盘[uuid: {1}]共需要[{3}]字节的空间,目前主存储的可用空间为[{4}]字节", + "arguments": [ + "msg.getVmInstanceUuid()", + "volumeVOS.stream().map(VolumeVO::getUuid).collect(Collectors.toList())", + "primaryStorageUuid", + "(totalCapacity - snapshotsCapacity) * msg.getNames().size()", + "primaryStorageVO.getCapacity().getAvailableCapacity()" + ], + "line": 177, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "The nic [%s%s] is not mounted on the VM", + "en_US": "The nic [{0}{1}] is not mounted on the VM", + "zh_CN": "网卡[{0}]不能被挂载到云主机上", + "arguments": [ + "msg.getVmNicUuid()" + ], + "line": 191, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "The operation only allows on user vm ", + "en_US": "The operation only allows on user vm ", + "zh_CN": "该操作只能在用户云主机上进行", + "arguments": [], + "line": 197, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "The operation only allows when vm [%s] state is stopped ", + "en_US": "The operation only allows when vm [{0}] state is stopped ", + "zh_CN": "该操作只有云主机[{0}]状态为已停止才能进行", + "arguments": [ + "vmInstanceVO.getUuid()" + ], + "line": 202, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "user has no privilege to change image of vm %s", + "en_US": "user has no privilege to change image of vm {0}", + "zh_CN": "当前用户不能修改云主机{0}的镜像", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 231, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "do not change vm image when it\u0027s not stopped", + "en_US": "do not change vm image when it\u0027s not stopped", + "zh_CN": "当云主机镜像未停止时,不要更改它", + "arguments": [], + "line": 243, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "make sure the primary storage vm[uuid:%s] was on is Enabled and Connected", + "en_US": "make sure the primary storage vm[uuid:{0}] was on is Enabled and Connected", + "zh_CN": "确认主存储[uuid:{0}]是可用的且已连接", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 260, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "make sure the last host vm[uuid:%s] was on is Enabled and Connected", + "en_US": "make sure the last host vm[uuid:{0}] was on is Enabled and Connected", + "zh_CN": "确定物理机[uuid:{0}]是可用的且已连接", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 275, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "vm[uuid:%s] has no default l3, cannot change image for it", + "en_US": "vm[uuid:{0}] has no default l3, cannot change image for it", + "zh_CN": "VM[uuid:{0}]没有默认的L3,无法为其更改镜像", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 285, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "instance[uuid:%s] cannot be changed image to image[uuid:%s]", + "en_US": "instance[uuid:{0}] cannot be changed image to image[uuid:{1}]", + "zh_CN": "无法将实例[uuid:{0}]的镜像更改为镜像[uuid:{1}]", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getImageUuid()" + ], + "line": 305, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "either uuid or account or password must be set", + "en_US": "either uuid or account or password must be set", + "zh_CN": "uuid或者账户或者密码需要被设置", + "arguments": [], + "line": 314, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "direction must be set in (in, out), but was %s", + "en_US": "direction must be set in (in, out), but was {0}", + "zh_CN": "方向必须设置在(in, out),但是输入的是{0}", + "arguments": [ + "msg.getDirection()" + ], + "line": 327, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "Monitor number must be 1 or 2 or 4.", + "en_US": "Monitor number must be 1 or 2 or 4.", + "zh_CN": "监听器数量必须是1、2或4", + "arguments": [], + "line": 333, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "outboundBandwidth and inboundBandwidth must be set at lease one.", + "en_US": "outboundBandwidth and inboundBandwidth must be set at lease one.", + "zh_CN": "上行带宽和下行带宽至少有一个需要被设置", + "arguments": [], + "line": 341, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "the nic can\u0027t apply Qos with the port mirror service at same time.", + "en_US": "the nic can\u0027t apply Qos with the port mirror service at same time.", + "zh_CN": "NIC不能同时对端口镜像服务应用QoS。", + "arguments": [], + "line": 350, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "nic id: %s does not exist...", + "en_US": "nic id: {0} does not exist...", + "zh_CN": "网卡id: {0}不存在", + "arguments": [ + "msg.getUuid()" + ], + "line": 359, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "The \u0027uuids\u0027 parameter must belong to the VmInstanceVO or HostVO", + "en_US": "The \u0027uuids\u0027 parameter must belong to the VmInstanceVO or HostVO", + "zh_CN": "“ uuids ”参数必须属于vminstancevo或hostvo", + "arguments": [], + "line": 370, + "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + }, + { + "raw": "vm current state[%s], modify virtio requires the vm state[%s]", + "en_US": "vm current state[{0}], modify virtio requires the vm state[{1}]", + "zh_CN": "VM当前状态[{0}],修改virtio需要VM状态[{1}]", + "arguments": [ + "state", + "VmInstanceState.Stopped" + ], + "line": 261, + "fileName": "src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java" + }, + { + "raw": "wrong format of password strength config", + "en_US": "wrong format of password strength config", + "zh_CN": "密码强度配置的格式错误", + "arguments": [], + "line": 111, + "fileName": "src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java" + }, + { + "raw": "minimum can not be larger than maximum", + "en_US": "minimum can not be larger than maximum", + "zh_CN": "最小值不能大于最大值", + "arguments": [], + "line": 114, + "fileName": "src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java" + }, + { + "raw": "password length must be [%s-%s]", + "en_US": "password length must be [{0}-{1}]", + "zh_CN": "密码长度必须为[{0}-{1}]", + "arguments": [ + "minimum", + "maximum" + ], + "line": 74, + "fileName": "src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java" + }, + { + "raw": "password does not match numbers, uppercase and lowercase, and special character combinations", + "en_US": "password does not match numbers, uppercase and lowercase, and special character combinations", + "zh_CN": "密码与数字、大小写和特殊字符组合不匹配", + "arguments": [], + "line": 93, + "fileName": "src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java" + }, + { + "raw": "missing parameter, resourceUuid: %s, vmInstanceUuid: %s is requested", + "en_US": "missing parameter, resourceUuid: {0}, vmInstanceUuid: {1} is requested", + "zh_CN": "缺少参数,ResourceUuid:{0},请求vmInstanceUuid:{1}", + "arguments": [ + "resourceUuid", + "vmInstanceUuid" + ], + "line": 117, + "fileName": "src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java" + }, + { + "raw": "missing parameter, vmInstanceUuid: %s is requested", + "en_US": "missing parameter, vmInstanceUuid: {0} is requested", + "zh_CN": "缺少参数,请求了vmInstanceUuid:{0}", + "arguments": [ + "vmInstanceUuid" + ], + "line": 153, + "fileName": "src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java" + }, + { + "raw": "cannot find vm with uuid: %s", + "en_US": "cannot find vm with uuid: {0}", + "zh_CN": "找不到uuid为{0}的云主机", + "arguments": [ + "vmInstanceUuid" + ], + "line": 334, + "fileName": "src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java" + }, + { + "raw": "cannot find vm device with uuid: %s", + "en_US": "cannot find vm device with uuid: {0}", + "zh_CN": "找不到uuid为{0}的VM设备", + "arguments": [ + "resourceUuid" + ], + "line": 338, + "fileName": "src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java" + }, + { + "raw": "vm[%s] start fail,because numa is enable but host[%s] not have numa node", + "en_US": "vm[{0}] start fail,because numa is enable but host[{1}] not have numa node", + "zh_CN": "VM[{0}]启动失败,因为已启用NUMA,但物理机[{1}]没有NUMA节点", + "arguments": [ + "vmUuid", + "hostUuid" + ], + "line": 38, + "fileName": "src/main/java/org/zstack/compute/vm/numa/CommonVmNumaBasicFactory.java" + }, + { + "raw": "vm[%s] start fail,because numa is enable but cpu not pin", + "en_US": "vm[{0}] start fail,because numa is enable but cpu not pin", + "zh_CN": "VM[{0}]启动失败,因为NUMA已启用,但CPU未pin", + "arguments": [ + "vmUuid" + ], + "line": 41, + "fileName": "src/main/java/org/zstack/compute/vm/numa/CommonVmNumaBasicFactory.java" + }, + { + "raw": "hot plug not close", + "en_US": "hot plug not close", + "zh_CN": "热插拔未关闭", + "arguments": [], + "line": 45, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java" + }, + { + "raw": "vm cpu not all pinning", + "en_US": "vm cpu not all pinning", + "zh_CN": "云主机CPU未完全固定", + "arguments": [], + "line": 49, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java" + }, + { + "raw": "cpu[%s] not pin in a same host numa node", + "en_US": "cpu[{0}] not pin in a same host numa node", + "zh_CN": "CPU[{0}]未固定在同一物理机NUMA节点中", + "arguments": [ + "entry.getKey().toString()" + ], + "line": 53, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java" + }, + { + "raw": "vm[%s] start fail,because numa is enable but: %s", + "en_US": "vm[{0}] start fail,because numa is enable but: {1}", + "zh_CN": "VM[{0}]启动失败,因为NUMA已启用,但:{1}", + "arguments": [ + "vmUuid", + "String.join(VmNumaConstant.RULES_SEPARATOR, errors)" + ], + "line": 57, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java" + }, + { + "raw": "No host is available to create vm Instance.Because vNuma vms need to be created on hosts with same numa, but no hosts is available after filter primary vm\u0027s host", + "en_US": "No host is available to create vm Instance.Because vNuma vms need to be created on hosts with same numa, but no hosts is available after filter primary vm\u0027s host", + "zh_CN": "没有物理机可用于创建VM实例。因为需要在具有相同NUMA的物理机上创建vNUMA VM,但在筛选主VM的物理机后没有可用的物理机", + "arguments": [], + "line": 52, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaFilterFlow.java" + }, + { + "raw": "fail to set vm numa, incorrect input format,only accept true or false", + "en_US": "fail to set vm numa, incorrect input format,only accept true or false", + "zh_CN": "无法设置VM NUMA,输入格式不正确,仅接受TRUE或FALSE", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaManagerImpl.java" + }, + { + "raw": "invalid cpu set [%s]", + "en_US": "invalid cpu set [{0}]", + "zh_CN": "CPU集[{0}]无效", + "arguments": [ + "word" + ], + "line": 46, + "fileName": "src/main/java/org/zstack/compute/vm/numa/VmNumaUtils.java" + }, + { + "raw": "the host[uuid:%s] already attached to host scheduling group[uuid:%s]", + "en_US": "the host[uuid:{0}] already attached to host scheduling group[uuid:{1}]", + "zh_CN": "物理机[uuid:{0}]已连接到物理机调度组[uuid:{1}]", + "arguments": [ + "msg.getHostUuid()", + "refVO.getHostGroupUuid()" + ], + "line": 98, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "host clusterUuid is null", + "en_US": "host clusterUuid is null", + "zh_CN": "物理机Clusteruuid为空", + "arguments": [], + "line": 107, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "hosts that you can add to a host scheduling group must be enabled and connected to the MN.", + "en_US": "hosts that you can add to a host scheduling group must be enabled and connected to the MN.", + "zh_CN": "您可以添加到物理机调度组的物理机必须启用并连接到Mn。", + "arguments": [], + "line": 111, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "unmatched zone detected, host[uuid: %s, zone uuid: %s]\u0027s zone is different from host sheduling rule group[uuid: %s, zone uuid: %s]", + "en_US": "unmatched zone detected, host[uuid: {0}, zone uuid: {1}]\u0027s zone is different from host sheduling rule group[uuid: {2}, zone uuid: {3}]", + "zh_CN": "检测到不匹配的区域,物理机[uuid:{0},区域uuid:{1}]的区域不同于物理机计划规则组[UUId:{2},区域UUId:{3}]", + "arguments": [ + "hostVO.getUuid()", + "hostVO.getZoneUuid()", + "hostGroup.getUuid()", + "hostGroup.getZoneUuid()" + ], + "line": 117, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "vm[uuid:%s] already attached to vm scheduling group[uuid:%s]", + "en_US": "vm[uuid:{0}] already attached to vm scheduling group[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已连接到云主机调度组[uuid:{1}]", + "arguments": [ + "msg.getVmUuid()", + "refVO.getVmGroupUuid()" + ], + "line": 132, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "unmatched zone detected, vm[uuid: %s, zone uuid: %s]\u0027s zone is different from vm sheduling rule group[uuid: %s, zone uuid: %s]", + "en_US": "unmatched zone detected, vm[uuid: {0}, zone uuid: {1}]\u0027s zone is different from vm sheduling rule group[uuid: {2}, zone uuid: {3}]", + "zh_CN": "检测到不匹配的区域,VM[uuid:{0},区域uuid:{1}]的区域不同于VM调度规则组[UUId:{2},区域UUId:{3}]", + "arguments": [ + "vm.getUuid()", + "vm.getZoneUuid()", + "groupVO.getUuid()", + "groupVO.getZoneUuid()" + ], + "line": 145, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "vm can change its vm scheduling group only in state [%s,%s], but vm is in state [%s]", + "en_US": "vm can change its vm scheduling group only in state [{0},{1}], but vm is in state [{2}]", + "zh_CN": "VM只能在状态[{0},{1}]下更改其VM调度组,但VM处于状态[{2}]", + "arguments": [ + "VmInstanceState.Running.toString()", + "VmInstanceState.Stopped.toString()", + "vm.getState().toString()" + ], + "line": 161, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "cannot operate vpc vm scheduling group", + "en_US": "cannot operate vpc vm scheduling group", + "zh_CN": "无法运行VPC云主机调度组", + "arguments": [], + "line": 171, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "zoneUuid is not null", + "en_US": "zoneUuid is not null", + "zh_CN": "zoneUuid不为空", + "arguments": [], + "line": 209, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "the vm scheduling group[uuid:%s] has already had a executed exclusive vm or affinitive vm scheduling policy attached. you cannot attach either of the two scheduling policies that require execution to the group again", + "en_US": "the vm scheduling group[uuid:{0}] has already had a executed exclusive vm or affinitive vm scheduling policy attached. you cannot attach either of the two scheduling policies that require execution to the group again", + "zh_CN": "VM调度组[uuid:{0}]已附加已执行的独占VM或关联VM调度策略。您不能再次将需要执行的两个计划策略中的任何一个附加到组", + "arguments": [], + "line": 399, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java" + }, + { + "raw": "can not satisfied vm scheduling rule group conditions", + "en_US": "can not satisfied vm scheduling rule group conditions", + "zh_CN": "无法满足VM调度规则组条件", + "arguments": [], + "line": 132, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleFilterFlow.java" + }, + { + "raw": "vm scheduling group[uuid:%s] reserve host [uuid:%s] for vm [uuid: %s] failed", + "en_US": "vm scheduling group[uuid:{0}] reserve host [uuid:{1}] for vm [uuid: {2}] failed", + "zh_CN": "云主机调度组[uuid:{0}]为云主机[uuid:{2}]保留物理机[UuId:{1}]失败", + "arguments": [ + "self.getUuid()", + "host.getUuid()", + "vmUuid" + ], + "line": 158, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java" + }, + { + "raw": "vm[uuid:%s] is now running on host[uuid:%s],which does not comply with the scheduling rule associated with vm scheduling group[uuid:%s].", + "en_US": "vm[uuid:{0}] is now running on host[uuid:{1}],which does not comply with the scheduling rule associated with vm scheduling group[uuid:{2}].", + "zh_CN": "云主机[uuid:{0}]现在正在物理机[uuid:{1}]上运行,该物理机不符合与云主机调度组[uuid:{2}]关联的调度规则。", + "arguments": [ + "vmInv.getUuid()", + "hostUuid", + "refVO.getVmGroupUuid()" + ], + "line": 392, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java" + }, + { + "raw": "hostGroup[uuid:%s] is no host", + "en_US": "hostGroup[uuid:{0}] is no host", + "zh_CN": "物理机组[uuid:{0}]不是物理机", + "arguments": [ + "msg.getVmGroupUuid()" + ], + "line": 402, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java" + }, + { + "raw": "vm[uuid:%s] is now running on host[uuid:%s], which does not comply with the scheduling rule[%s] associated with vm scheduling group[uuid:%s].", + "en_US": "vm[uuid:{0}] is now running on host[uuid:{1}], which does not comply with the scheduling rule[{2}] associated with vm scheduling group[uuid:{3}].", + "zh_CN": "云主机[uuid:{0}]现在正在物理机[uuid:{1}]上运行,该物理机不符合与云主机调度组[uuid:{3}]关联的调度规则[{2}]。", + "arguments": [ + "msg.getVmUuid()", + "hostUuid", + "VMSchedulingRuleType.AFFINITY.toString()", + "msg.getVmGroupUuid()" + ], + "line": 407, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java" + }, + { + "raw": "vm[uuid:%s] is now running on host[uuid:%s],which does not comply with the scheduling rule[%s] associated with vm scheduling group[uuid:%s].", + "en_US": "vm[uuid:{0}] is now running on host[uuid:{1}],which does not comply with the scheduling rule[{2}] associated with vm scheduling group[uuid:{3}].", + "zh_CN": "云主机[uuid:{0}]现在正在物理机[uuid:{1}]上运行,该物理机不符合与云主机调度组[UuId:{3}]关联的调度规则[{2}]。", + "arguments": [ + "msg.getVmUuid()", + "hostUuid", + "VMSchedulingRuleType.ANTIAFFINITY.toString()", + "msg.getVmGroupUuid()" + ], + "line": 414, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java" + }, + { + "raw": "cannot find the host scheduling group[uuid:%s], it may have been deleted", + "en_US": "cannot find the host scheduling group[uuid:{0}], it may have been deleted", + "zh_CN": "找不到物理机调度组[uuid:{0}],它可能已被删除", + "arguments": [ + "msg.getHostGroupUuid()" + ], + "line": 82, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java" + }, + { + "raw": "cannot find the vm scheduling rule[uuid:%s], it may have been deleted", + "en_US": "cannot find the vm scheduling rule[uuid:{0}], it may have been deleted", + "zh_CN": "找不到VM计划规则[uuid:{0}],它可能已被删除", + "arguments": [ + "msg.getVmSchedulingRuleUuid()" + ], + "line": 95, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java" + }, + { + "raw": "cannot find the vm scheduling group[uuid:%s], it may have been deleted", + "en_US": "cannot find the vm scheduling group[uuid:{0}], it may have been deleted", + "zh_CN": "找不到VM调度组[uuid:{0}],它可能已被删除", + "arguments": [ + "msg.getVmSchedulingRuleGroupUuid()" + ], + "line": 108, + "fileName": "src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java" + }, + { + "raw": "unsupported host allocation strategy[%s]", + "en_US": "unsupported host allocation strategy[{0}]", + "zh_CN": "不被支持的物理机分配策略[{0}]", + "arguments": [ + "msg.getAllocatorStrategy()" + ], + "line": 86, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + }, + { + "raw": "unsupported instance offering type[%s]", + "en_US": "unsupported instance offering type[{0}]", + "zh_CN": "不被支持的计算规格类型[{0}]", + "arguments": [ + "msg.getType()" + ], + "line": 72, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + }, + { + "raw": "cpu num[%s] is less than 1", + "en_US": "cpu num[{0}] is less than 1", + "zh_CN": "cpu数量[{0}]少于1", + "arguments": [ + "msg.getCpuNum()" + ], + "line": 76, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + }, + { + "raw": "memory size[%s bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size", + "en_US": "memory size[{0} bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size", + "zh_CN": "内存大小[{0} bytes]少于16M,没有一个现代操作系统能够在如此小的内存里被引导", + "arguments": [ + "msg.getMemorySize()" + ], + "line": 80, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + }, + { + "raw": "unsupported primary storage allocation strategy[%s]", + "en_US": "unsupported primary storage allocation strategy[{0}]", + "zh_CN": "不被支持的主存储分配策略[{0}]", + "arguments": [ + "msg.getAllocationStrategy()" + ], + "line": 92, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + }, + { + "raw": "Already have one userdata systemTag for instanceOffering[uuid: %s].", + "en_US": "Already have one userdata systemTag for instanceOffering[uuid: {0}].", + "zh_CN": "实例[uuid:{0}]已有一个用户数据系统标记。", + "arguments": [ + "resourceUuid" + ], + "line": 1043, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java" + }, + { + "raw": "Shouldn\u0027t be more than one systemTag for one instanceOffering.", + "en_US": "Shouldn\u0027t be more than one systemTag for one instanceOffering.", + "zh_CN": "对于一个实例提供,不应超过一个系统标记。", + "arguments": [], + "line": 1108, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java" + }, + { + "raw": "Already have one userdata systemTag for diskOffering[uuid: %s].", + "en_US": "Already have one userdata systemTag for diskOffering[uuid: {0}].", + "zh_CN": "DiskOffering[uuid:{0}]已有一个UserData系统标记。", + "arguments": [ + "resourceUuid" + ], + "line": 1085, + "fileName": "src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java" + }, + { + "raw": "the console agent is not connected; it\u0027s mostly like the management node just starts, please wait for the console agent connected, or you can reconnect it manually if disconnected for a long time.", + "en_US": "the console agent is not connected; it\u0027s mostly like the management node just starts, please wait for the console agent connected, or you can reconnect it manually if disconnected for a long time.", + "zh_CN": "控制台代理失联,很有可能管理节点刚刚启动,请等待控制台代理的连接,如果长时间没有连上可以尝试手动重连控制台代理。", + "arguments": [], + "line": 104, + "fileName": "src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java" + }, + { + "raw": "cannot find host IP of the vm[uuid:%s], is the vm running???", + "en_US": "cannot find host IP of the vm[uuid:{0}], is the vm running???", + "zh_CN": "无法找到vm[uuid:{0}]的物理机IP,请确认该vm是否在运行???", + "arguments": [ + "vm.getUuid()" + ], + "line": 125, + "fileName": "src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java" + }, + { + "raw": "Console is only available when the VM[uuid:%s] is Running or Crashed, but the current state is %s", + "en_US": "Console is only available when the VM[uuid:{0}] is Running or Crashed, but the current state is {1}", + "zh_CN": "控制台仅在VM[uuid:{0}]正在运行或崩溃时可用,但当前状态为{1}", + "arguments": [ + "msg.getVmInstanceUuid()", + "state" + ], + "line": 49, + "fileName": "src/main/java/org/zstack/console/ConsoleApiInterceptor.java" + }, + { + "raw": "establish VNC: unexpected uri: %s", + "en_US": "establish VNC: unexpected uri: {0}", + "zh_CN": "建立VNC:意外的URI:{0}", + "arguments": [ + "uri.toString()" + ], + "line": 133, + "fileName": "src/main/java/org/zstack/console/ConsoleProxyBase.java" + }, + { + "raw": "unable to check console proxy availability, because %s", + "en_US": "unable to check console proxy availability, because {0}", + "zh_CN": "无法检查控制台代理是否可用,因为{0}", + "arguments": [ + "ret.getError()" + ], + "line": 198, + "fileName": "src/main/java/org/zstack/console/ConsoleProxyBase.java" + }, + { + "raw": "Ansible private key not found.", + "en_US": "Ansible private key not found.", + "zh_CN": "找不到Ansible私钥。", + "arguments": [], + "line": 189, + "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + }, + { + "raw": "invalid management node uuid[%s]", + "en_US": "invalid management node uuid[{0}]", + "zh_CN": "非法的管理节点uuid[{0}]", + "arguments": [ + "uuid" + ], + "line": 387, + "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + }, + { + "raw": "failed to configure consoleProxyOverriddenIp[code:%d] or consoleProxyPort[code:%d]", + "en_US": "failed to configure consoleProxyOverriddenIp[code:{0}] or consoleProxyPort[code:{1}]", + "zh_CN": "无法配置ConsoleProxyOverriddeNip[代码:{0}]或ConsoleProxyPort[代码:{1}]", + "arguments": [], + "line": 520, + "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + }, + { + "raw": "failed to reconnect console proxy", + "en_US": "failed to reconnect console proxy", + "zh_CN": "重连控制台代理失败", + "arguments": [], + "line": 543, + "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + }, + { + "raw": "User name or password or port number may be problematic", + "en_US": "User name or password or port number may be problematic", + "zh_CN": "用户名、密码或者端口可能是错误的", + "arguments": [], + "line": 426, + "fileName": "src/main/java/org/zstack/core/ansible/AnsibleRunner.java" + }, + { + "raw": "cannot check md5sum of files in the folder[%s].\\nstdout:%s\\nstderr:%s", + "en_US": "cannot check md5sum of files in the folder[{0}].\\nstdout:{1}\\nstderr:{2}", + "zh_CN": "无法检查文件夹[{0}]下文件的md5sum.\\nstdout:{1}\\nstderr:{2}", + "arguments": [ + "srcFolder", + "srcRes.getStdout()", + "srcRes.getStderr()" + ], + "line": 106, + "fileName": "src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java" + }, + { + "raw": "cannot check md5sum of files in the folder[%s] on the host[ip:%s].\\nstdout:%s\\nstderr:%s", + "en_US": "cannot check md5sum of files in the folder[{0}] on the host[ip:{1}].\\nstdout:{2}\\nstderr:{3}", + "zh_CN": "无法检查物理机[ip:{1}]的文件夹[{0}]下文件的md5sum.\\nstdout:{2}\\nstderr:{3}", + "arguments": [ + "dstFolder", + "hostname", + "dstRes.getStdout()", + "dstRes.getStderr()" + ], + "line": 121, + "fileName": "src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java" + }, + { + "raw": "message is not in corrected JSON mediaType, %s", + "en_US": "message is not in corrected JSON mediaType, {0}", + "zh_CN": "消息是错误的JSON格式,{0}", + "arguments": [ + "errMsg" + ], + "line": 684, + "fileName": "src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java" + }, + { + "raw": "for webhooks with type[%s], the field opaque cannot be null", + "en_US": "for webhooks with type[{0}], the field opaque cannot be null", + "zh_CN": "对于[{0}]类型的webhooks,opaque字段不能为null", + "arguments": [ + "EventFacade.WEBHOOK_TYPE" + ], + "line": 69, + "fileName": "src/main/java/org/zstack/core/cloudbus/EventFacadeImpl.java" + }, + { + "raw": "do not allow skip verification", + "en_US": "do not allow skip verification", + "zh_CN": "不允许跳过验证", + "arguments": [], + "line": 430, + "fileName": "src/main/java/org/zstack/core/config/GlobalConfig.java" + }, + { + "raw": "Unable to find GlobalConfig[category: %s, name: %s]", + "en_US": "Unable to find GlobalConfig[category: {0}, name: {1}]", + "zh_CN": "无法找到全局变量[category:{0}, name:{1}]", + "arguments": [ + "msg.getCategory()", + "msg.getName()" + ], + "line": 118, + "fileName": "src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java" + }, + { + "raw": "taskInfo was not found", + "en_US": "taskInfo was not found", + "zh_CN": "未找到TaskInfo", + "arguments": [], + "line": 93, + "fileName": "src/main/java/org/zstack/core/debug/DebugManagerImpl.java" + }, + { + "raw": "Encryption error : %s", + "en_US": "Encryption error : {0}", + "zh_CN": "加密错误:{0}", + "arguments": [ + "encrypt.error" + ], + "line": 204, + "fileName": "src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java" + }, + { + "raw": "non file or jsoncontent input", + "en_US": "non file or jsoncontent input", + "zh_CN": "非文件或JSON内容输入", + "arguments": [], + "line": 71, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "file or jsoncontent cannot both nonempty", + "en_US": "file or jsoncontent cannot both nonempty", + "zh_CN": "文件或JSONContent不能同时为非空", + "arguments": [], + "line": 76, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "Unable to scan folder: %s", + "en_US": "Unable to scan folder: {0}", + "zh_CN": "无法扫描文件夹:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 108, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "%s is not existed or is empty folder", + "en_US": "{0} is not existed or is empty folder", + "zh_CN": "{0}不存在或为空文件夹", + "arguments": [ + "filename" + ], + "line": 112, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "elaboration code must be number!", + "en_US": "elaboration code must be number!", + "zh_CN": "精化代码必须为数字!", + "arguments": [], + "line": 249, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "%s: %s", + "en_US": "{0}: {1}", + "zh_CN": "{0}: {1}", + "arguments": [ + "returnValue.get(0).getContent()", + "returnValue.get(0).getReason()" + ], + "line": 318, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "input args \u0027regex\u0027 or \u0027category\u0027 must be set", + "en_US": "input args \u0027regex\u0027 or \u0027category\u0027 must be set", + "zh_CN": "必须设置输入参数“ regex ”或“ category ”", + "arguments": [], + "line": 415, + "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + }, + { + "raw": "service[%s] has been registered", + "en_US": "service[{0}] has been registered", + "zh_CN": "服务(service)[{0}]已经被注册", + "arguments": [ + "service.getName()" + ], + "line": 32, + "fileName": "src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java" + }, + { + "raw": "service[%s] is not registered", + "en_US": "service[{0}] is not registered", + "zh_CN": "服务[{0}]未注册", + "arguments": [ + "msg.getName()" + ], + "line": 93, + "fileName": "src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java" + }, + { + "raw": "service[%s] does not support reload config", + "en_US": "service[{0}] does not support reload config", + "zh_CN": "服务[{0}]不支持重新加载配置", + "arguments": [ + "msg.getName()" + ], + "line": 99, + "fileName": "src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java" + }, + { + "raw": "service[%s] is not running", + "en_US": "service[{0}] is not running", + "zh_CN": "服务[{0}]未运行", + "arguments": [ + "msg.getName()" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java" + }, + { + "raw": "cannot trigger a finished GC job[uuid:%s, name:%s]", + "en_US": "cannot trigger a finished GC job[uuid:{0}, name:{1}]", + "zh_CN": "无法触发一个完成过的GC任务", + "arguments": [ + "vo.getUuid()", + "vo.getName()" + ], + "line": 315, + "fileName": "src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java" + }, + { + "raw": "parameter apiId[%s] is not a valid uuid.", + "en_US": "parameter apiId[{0}] is not a valid uuid.", + "zh_CN": "参数apiId[{0}]不是一个有效的uuid", + "arguments": [ + "msg.getApiId()" + ], + "line": 38, + "fileName": "src/main/java/org/zstack/core/progress/ProgressApiInterceptor.java" + }, + { + "raw": "unable to echo %s in %sms", + "en_US": "unable to echo {0} in {1}ms", + "zh_CN": "无法在{1}ms内返回{0}", + "arguments": [ + "url", + "finalTimeout" + ], + "line": 656, + "fileName": "src/main/java/org/zstack/core/rest/RESTFacadeImpl.java" + }, + { + "raw": "an operation[%s] fails after retrying %s times with the interval %s seconds", + "en_US": "an operation[{0}] fails after retrying {1} times with the interval {2} seconds", + "zh_CN": "在重试{1}次间隔时间为{2}后操作[{0}]失败", + "arguments": [ + "__name__", + "times", + "interval" + ], + "line": 103, + "fileName": "src/main/java/org/zstack/core/retry/Retry.java" + }, + { + "raw": "failed to run salt state[%s] on system[%s], failed after %s retries", + "en_US": "failed to run salt state[{0}] on system[{1}], failed after {2} retries", + "zh_CN": "重试{2}次之后,在系统[{1}]上运行加盐状态[{0}]失败", + "arguments": [ + "stateName", + "targetIp", + "retry" + ], + "line": 297, + "fileName": "src/main/java/org/zstack/core/salt/SaltRunner.java" + }, + { + "raw": "scp is not found on system[%s], unable to setup salt", + "en_US": "scp is not found on system[{0}], unable to setup salt", + "zh_CN": "在系统[{0}]上找不到SCP,无法设置销售", + "arguments": [ + "targetIp" + ], + "line": 84, + "fileName": "src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java" + }, + { + "raw": "api timeout cannot be set smaller than %s", + "en_US": "api timeout cannot be set smaller than {0}", + "zh_CN": "API超时不能设置为小于{0}", + "arguments": [ + "ApiTimeoutGlobalProperty.MINIMAL_TIMEOUT" + ], + "line": 76, + "fileName": "src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java" + }, + { + "raw": "Invalid url[%s]", + "en_US": "Invalid url[{0}]", + "zh_CN": "无效的URL[{0}]", + "arguments": [ + "url" + ], + "line": 28, + "fileName": "src/main/java/org/zstack/core/webhook/WebhookApiInterceptor.java" + }, + { + "raw": "the identity authentication does not specify the resource pool to provide the service", + "en_US": "the identity authentication does not specify the resource pool to provide the service", + "zh_CN": "身份认证未指定提供服务的资源池", + "arguments": [], + "line": 72, + "fileName": "src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java" + }, + { + "raw": "wrong secret resource pool model, expect %s, actual %s", + "en_US": "wrong secret resource pool model, expect {0}, actual {1}", + "zh_CN": "机密资源池模型错误,应为{0},实际为{1}", + "arguments": [ + "setting.resourcePoolType", + "model" + ], + "line": 83, + "fileName": "src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java" + }, + { + "raw": "failed to find model for secretResourcePool [%s]", + "en_US": "failed to find model for secretResourcePool [{0}]", + "zh_CN": "找不到SecretResourcePool[{0}]的模型", + "arguments": [ + "resourceUuid" + ], + "line": 81, + "fileName": "src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java" + }, + { + "raw": "failed to find certificate info", + "en_US": "failed to find certificate info", + "zh_CN": "找不到证书信息", + "arguments": [], + "line": 121, + "fileName": "src/main/java/org/zstack/crypto/auth/CryptoAuthenticationHelper.java" + }, + { + "raw": "failed to parse plain text in encryption param to json object: %s, %s", + "en_US": "failed to parse plain text in encryption param to json object: {0}, {1}", + "zh_CN": "无法将加密参数中的纯文本解析为JSON对象:{0},{1}", + "arguments": [ + "plainText", + "e.getMessage()" + ], + "line": 57, + "fileName": "src/main/java/org/zstack/crypto/auth/CryptoEncryptionParamParser.java" + }, + { + "raw": "operation not supported", + "en_US": "operation not supported", + "zh_CN": "不支持的操作", + "arguments": [], + "line": 73, + "fileName": "src/main/java/org/zstack/crypto/auth/UKeyCryptoAuthenticationFacade.java" + }, + { + "raw": "user[uuid\u003d%s] not found", + "en_US": "user[uuid\u003d{0}] not found", + "zh_CN": "找不到用户[uuid\u003d{0}]", + "arguments": [ + "userUuid" + ], + "line": 200, + "fileName": "src/main/java/org/zstack/crypto/ccs/CCSCertificateInterceptor.java" + }, + { + "raw": "certificate uuid is empty and UKey system tag does not exist", + "en_US": "certificate uuid is empty and UKey system tag does not exist", + "zh_CN": "证书uuid为空,且UKEY系统标记不存在", + "arguments": [], + "line": 204, + "fileName": "src/main/java/org/zstack/crypto/ccs/CCSCertificateInterceptor.java" + }, + { + "raw": "certificate[uuid\u003d%s] not found", + "en_US": "certificate[uuid\u003d{0}] not found", + "zh_CN": "未找到证书[uuid\u003d{0}]", + "arguments": [ + "msg.getCertificateUuid()" + ], + "line": 217, + "fileName": "src/main/java/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java" + }, + { + "raw": "check batch data integrity fail, unsupported resourceType: %s", + "en_US": "check batch data integrity fail, unsupported resourceType: {0}", + "zh_CN": "检查批处理数据完整性失败,不支持的资源类型:{0}", + "arguments": [ + "msg.getResourceType()" + ], + "line": 47, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java" + }, + { + "raw": "add integrity resource fail, unsupported resourceType: %s", + "en_US": "add integrity resource fail, unsupported resourceType: {0}", + "zh_CN": "添加完整性资源失败,不支持的资源类型:{0}", + "arguments": [ + "msg.getResourceType()" + ], + "line": 57, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java" + }, + { + "raw": "start data protection encryptType[%s] is error", + "en_US": "start data protection encryptType[{0}] is error", + "zh_CN": "启动数据保护加密类型[{0}]出错", + "arguments": [ + "msg.getEncryptType()" + ], + "line": 65, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java" + }, + { + "raw": "the snapshot[uuid:%s] is not encrypted", + "en_US": "the snapshot[uuid:{0}] is not encrypted", + "zh_CN": "快照[uuid:{0}]未加密", + "arguments": [ + "inventory.getUuid()" + ], + "line": 240, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "verify volume snapshot[%s] consistency failed", + "en_US": "verify volume snapshot[{0}] consistency failed", + "zh_CN": "验证卷快照[{0}]一致性失败", + "arguments": [ + "inventory.getUuid()" + ], + "line": 249, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "encryption image cache[id:%s] error: %s", + "en_US": "encryption image cache[id:{0}] error: {1}", + "zh_CN": "加密镜像缓存[ID:{0}]错误:{1}", + "arguments": [ + "inventory.getId()", + "exception.getMessage()" + ], + "line": 311, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "the image cache[id:%s] is not encrypted", + "en_US": "the image cache[id:{0}] is not encrypted", + "zh_CN": "镜像缓存[ID:{0}]未加密", + "arguments": [ + "inventory.getId()" + ], + "line": 375, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "verify image cache[%s] consistency failed", + "en_US": "verify image cache[{0}] consistency failed", + "zh_CN": "验证镜像缓存[{0}]一致性失败", + "arguments": [ + "inventory.getId()" + ], + "line": 388, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "nodeType %s integrity file[path:%s] already exists", + "en_US": "nodeType {0} integrity file[path:{1}] already exists", + "zh_CN": "NodeType{0}完整性文件[路径:{1}]已存在", + "arguments": [ + "msg.getNodeType()", + "msg.getPath()" + ], + "line": 668, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "invalid nodeType[%s]", + "en_US": "invalid nodeType[{0}]", + "zh_CN": "节点类型[{0}]无效", + "arguments": [ + "msg.getNodeType()" + ], + "line": 682, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "filed to add integrity file[%s.%s], it\u0027s a directory now.", + "en_US": "filed to add integrity file[{0}.{1}], it\u0027s a directory now.", + "zh_CN": "已归档以添加完整性文件[{0}.{1}],它现在是一个目录。", + "arguments": [ + "msg.getNodeType()", + "msg.getPath()" + ], + "line": 694, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "integrity file[%s.%s] is not exists", + "en_US": "integrity file[{0}.{1}] is not exists", + "zh_CN": "完整性文件[{0}.{1}]不存在", + "arguments": [ + "msg.getNodeType()", + "msg.getPath()" + ], + "line": 699, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "host %s is not exists", + "en_US": "host {0} is not exists", + "zh_CN": "物理机{0}不存在", + "arguments": [ + "msg.getNodeUuid()" + ], + "line": 716, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "Shell fail, because %s", + "en_US": "Shell fail, because {0}", + "zh_CN": "Shell失败,原因是{0}", + "arguments": [ + "res.getStderr()" + ], + "line": 724, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "add integrity file[%s.%s] fail, because %s", + "en_US": "add integrity file[{0}.{1}] fail, because {2}", + "zh_CN": "添加完整性文件[{0}.{1}]失败,原因是{2}", + "arguments": [ + "msg.getNodeType()", + "msg.getPath()", + "exception.getMessage()" + ], + "line": 747, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java" + }, + { + "raw": "unsupported operation for EncryptColumnIntegrityFactory", + "en_US": "unsupported operation for EncryptColumnIntegrityFactory", + "zh_CN": "不支持对EncryptColumnIntegrityFactory的操作", + "arguments": [], + "line": 141, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/integrity/EncryptColumnIntegrityFactory.java" + }, + { + "raw": "virtualID attribute encryption error, because:%s", + "en_US": "virtualID attribute encryption error, because:{0}", + "zh_CN": "VirtualID属性加密错误,原因:{0}", + "arguments": [ + "encrypt.error" + ], + "line": 138, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java" + }, + { + "raw": "IAM2VirtualIDAttributeVO %s does not exists", + "en_US": "IAM2VirtualIDAttributeVO {0} does not exists", + "zh_CN": "IAM2VirtualIDAttributeVO{0}不存在", + "arguments": [ + "resourceUuid" + ], + "line": 187, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java" + }, + { + "raw": "virtualID attribute check error, because:%s", + "en_US": "virtualID attribute check error, because:{0}", + "zh_CN": "VirtualID属性检查错误,原因:{0}", + "arguments": [ + "encrypt.error" + ], + "line": 194, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java" + }, + { + "raw": "rolePolicy encryption error, because:%s", + "en_US": "rolePolicy encryption error, because:{0}", + "zh_CN": "RolePolicy加密错误,原因:{0}", + "arguments": [ + "encrypt.error" + ], + "line": 115, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/integrity/RolePolicyIntegrityFactory.java" + }, + { + "raw": "the shared mount point primary storage[uuid:%s, name:%s] cannot find any available host in attached clusters", + "en_US": "the shared mount point primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters", + "zh_CN": "共享装入点主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用物理机", + "arguments": [ + "self.getUuid()", + "self.getName()" + ], + "line": 40, + "fileName": "src/main/java/org/zstack/crypto/datacrypto/smp/SMPCryptoBase.java" + }, + { + "raw": "originText or certificateText can not be null", + "en_US": "originText or certificateText can not be null", + "zh_CN": "原始文本或证书文本不能为空", + "arguments": [], + "line": 26, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/AttachVerifyPair.java" + }, + { + "raw": "the security machine [%s] does not exist", + "en_US": "the security machine [{0}] does not exist", + "zh_CN": "密码机[{0}]不存在", + "arguments": [ + "msg.getSecurityMachineUuid()" + ], + "line": 60, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java" + }, + { + "raw": "managementIp[%s] is not in IPV4 format", + "en_US": "managementIp[{0}] is not in IPV4 format", + "zh_CN": "ManagementIP[{0}]不是IPv4格式", + "arguments": [ + "msg.getManagementIp()" + ], + "line": 86, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java" + }, + { + "raw": "failed to connect to the security machine %s[%s], because %s", + "en_US": "failed to connect to the security machine {0}[{1}], because {2}", + "zh_CN": "无法连接到密码机{0}[{1}],因为{2}", + "arguments": [ + "msg.getName()", + "msg.getManagementIp()", + "error" + ], + "line": 92, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java" + }, + { + "raw": "after the crypto function is enabled, at least one security machine should be reserved in the corresponding resource pool", + "en_US": "after the crypto function is enabled, at least one security machine should be reserved in the corresponding resource pool", + "zh_CN": "启用加密功能后,应在相应的资源池中至少保留一台密码机", + "arguments": [ + "msg.getSecurityMachineUuid()" + ], + "line": 112, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java" + }, + { + "raw": "invalid algType %s, supported types: %s.", + "en_US": "invalid algType {0}, supported types: {1}.", + "zh_CN": "AlgType{0}无效,支持的类型:{1}。", + "arguments": [ + "msg.getAlgType()", + "StringUtils.join(EncryptType.values(), \u0027,\u0027)" + ], + "line": 123, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java" + }, + { + "raw": "the resource pool[%s] specified by data protection does not exist", + "en_US": "the resource pool[{0}] specified by data protection does not exist", + "zh_CN": "数据保护指定的资源池[{0}]不存在", + "arguments": [ + "poolForProtect" + ], + "line": 127, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java" + }, + { + "raw": "cannot be deleted. after the encryption function is enabled, the number of synced security machines in the resource pool that provides the service is at least 1", + "en_US": "cannot be deleted. after the encryption function is enabled, the number of synced security machines in the resource pool that provides the service is at least 1", + "zh_CN": "无法删除。启用加密功能后,提供该服务的资源池中同步的密码机至少为1台", + "arguments": [], + "line": 145, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java" + }, + { + "raw": "securityMachine is disabled, failed to detect heartbeat", + "en_US": "securityMachine is disabled, failed to detect heartbeat", + "zh_CN": "SecurityMachine已禁用,无法检测心跳", + "arguments": [], + "line": 444, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java" + }, + { + "raw": "an other connect security machine task is running, cancel the new task and wait return", + "en_US": "an other connect security machine task is running, cancel the new task and wait return", + "zh_CN": "其他连接密码机任务正在运行,请取消新任务并等待返回", + "arguments": [], + "line": 584, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java" + }, + { + "raw": "encrypt data[%s] or algType[%s] is null", + "en_US": "encrypt data[{0}] or algType[{1}] is null", + "zh_CN": "加密数据[{0}]或AlgType[{1}]为空", + "arguments": [ + "data", + "algType" + ], + "line": 183, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "cannot find model for secretResourcePool [%s]", + "en_US": "cannot find model for secretResourcePool [{0}]", + "zh_CN": "找不到SecretResourcePool[{0}]的模型", + "arguments": [ + "resourceUuid" + ], + "line": 165, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "the crypto function is enabled but the resource pool[%s] for auto login is not set.", + "en_US": "the crypto function is enabled but the resource pool[{0}] for auto login is not set.", + "zh_CN": "已启用加密功能,但未设置用于自动登录的资源池[{0}]。", + "arguments": [ + "poolForAuth" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "the crypto function is enabled but the resource pool[%s] for data protect is not set.", + "en_US": "the crypto function is enabled but the resource pool[{0}] for data protect is not set.", + "zh_CN": "已启用加密功能,但未设置数据保护的资源池[{0}]。", + "arguments": [ + "poolForProtect" + ], + "line": 113, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "the current state[%s] does not allow manual modification of the state", + "en_US": "the current state[{0}] does not allow manual modification of the state", + "zh_CN": "当前状态[{0}]不允许手动修改状态", + "arguments": [ + "state.toString()" + ], + "line": 122, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "cannot disable all security machines when the crypto function is enabled", + "en_US": "cannot disable all security machines when the crypto function is enabled", + "zh_CN": "启用加密功能时,无法禁用所有密码机", + "arguments": [], + "line": 149, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "check whether the resource pool uuid is set for authentication", + "en_US": "check whether the resource pool uuid is set for authentication", + "zh_CN": "检查是否为身份验证设置了资源池uuid", + "arguments": [], + "line": 159, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "unknown encryptType[%s]", + "en_US": "unknown encryptType[{0}]", + "zh_CN": "未知的加密类型[{0}]", + "arguments": [ + "algType" + ], + "line": 202, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "decrypt data[%s] or algType[%s] is null", + "en_US": "decrypt data[{0}] or algType[{1}] is null", + "zh_CN": "解密数据[{0}]或AlgType[{1}]为空", + "arguments": [ + "data", + "algType" + ], + "line": 216, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "invalid decrypt algType: %s", + "en_US": "invalid decrypt algType: {0}", + "zh_CN": "无效的解密AlgType:{0}", + "arguments": [ + "algType" + ], + "line": 225, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java" + }, + { + "raw": "there has been a security machine having managementIp[%s]", + "en_US": "there has been a security machine having managementIp[{0}]", + "zh_CN": "已存在具有ManagementIP[{0}]的密码机", + "arguments": [ + "msg.getManagementIp()" + ], + "line": 280, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java" + }, + { + "raw": "no client for security machine[type\u003d%s]", + "en_US": "no client for security machine[type\u003d{0}]", + "zh_CN": "密码机[类型\u003d{0}]没有客户端", + "arguments": [ + "securityMachineType" + ], + "line": 82, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java" + }, + { + "raw": "no security machine client factory for security machine[type\u003d%s]", + "en_US": "no security machine client factory for security machine[type\u003d{0}]", + "zh_CN": "密码机[类型\u003d{0}]没有密码机客户端工厂", + "arguments": [ + "securityMachineType" + ], + "line": 101, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java" + }, + { + "raw": "there is no security machine that can be activated", + "en_US": "there is no security machine that can be activated", + "zh_CN": "没有可以激活的密码机。", + "arguments": [], + "line": 50, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java" + }, + { + "raw": "invalid token type %s, only supports %s.", + "en_US": "invalid token type {0}, only supports {1}.", + "zh_CN": "令牌类型{0}无效,仅支持{1}。", + "arguments": [ + "msg.getType()", + "StringUtils.join(SecurityMachineKeyType.values(), \u0027,\u0027)" + ], + "line": 54, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java" + }, + { + "raw": "the identity authentication function is enabled but the corresponding resource pool is not set, please re-enable the function and try again", + "en_US": "the identity authentication function is enabled but the corresponding resource pool is not set, please re-enable the function and try again", + "zh_CN": "身份认证功能已启用,但未设置相应的资源池,请重新启用后再试", + "arguments": [ + "msg.getSecretResourcePoolUuid()" + ], + "line": 68, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java" + }, + { + "raw": "cannot delete the resource pool %s when in use", + "en_US": "cannot delete the resource pool {0} when in use", + "zh_CN": "无法删除正在使用的资源池{0}", + "arguments": [ + "msg.getSecretResourcePoolUuid()" + ], + "line": 72, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java" + }, + { + "raw": "generate certificate failed", + "en_US": "generate certificate failed", + "zh_CN": "生成证书失败", + "arguments": [], + "line": 237, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java" + }, + { + "raw": "flkSec securityMachine unhealthy: %s", + "en_US": "flkSec securityMachine unhealthy: {0}", + "zh_CN": "FlkSec SecurityMachine不正常:{0}", + "arguments": [ + "rsp.getData()" + ], + "line": 134, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java" + }, + { + "raw": "keyLabel %s and encryptResult %s are inconsistent", + "en_US": "keyLabel {0} and encryptResult {1} are inconsistent", + "zh_CN": "KeyLabel{0}和EncryptResult{1}不一致", + "arguments": [ + "keyLabel", + "sm4EncryptResponse.result" + ], + "line": 161, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java" + }, + { + "raw": "the connection to the security machine %s failed during the process of generating the test key because %s", + "en_US": "the connection to the security machine {0} failed during the process of generating the test key because {1}", + "zh_CN": "在生成测试密钥的过程中,与密码机{0}的连接失败,原因是{1}", + "arguments": [ + "vo.getUuid()", + "response.error" + ], + "line": 168, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java" + }, + { + "raw": "failed to generate dataProtect token for the security machine %s because %s", + "en_US": "failed to generate dataProtect token for the security machine {0} because {1}", + "zh_CN": "无法为密码机{0}生成DataProtect令牌,因为{1}", + "arguments": [ + "vo.getUuid()", + "dataProtectTokenRes.error" + ], + "line": 185, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java" + }, + { + "raw": "failed to generate hmac token for the security machine %s because %s", + "en_US": "failed to generate hmac token for the security machine {0} because {1}", + "zh_CN": "无法为密码机{0}生成HMAC令牌,因为{1}", + "arguments": [ + "vo.getUuid()", + "hmacTokenTokenRes.error" + ], + "line": 196, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java" + }, + { + "raw": "failed to get encrypt result for the security machine %s because %s", + "en_US": "failed to get encrypt result for the security machine {0} because {1}", + "zh_CN": "无法获取密码机{0}的加密结果,因为{1}", + "arguments": [ + "vo.getUuid()", + "encryptRes.error" + ], + "line": 208, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java" + }, + { + "raw": "the security machine [%s] failed to manually detect synchronization, please confirm whether the security machine has synchronized the key!", + "en_US": "the security machine [{0}] failed to manually detect synchronization, please confirm whether the security machine has synchronized the key!", + "zh_CN": "密码机[{0}]手动检测同步失败,请确认密码机是否已同步密钥!", + "arguments": [ + "self.getManagementIp()" + ], + "line": 123, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecurityMachineBase.java" + }, + { + "raw": "security machine[uuid:%s] model is not %s", + "en_US": "security machine[uuid:{0}] model is not {1}", + "zh_CN": "密码机[uuid:{0}]型号不是{1}", + "arguments": [ + "msg.getName()", + "vo.getModel()" + ], + "line": 32, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecurityMachineFactory.java" + }, + { + "raw": "currently does not support the creation of %s resource pools", + "en_US": "currently does not support the creation of {0} resource pools", + "zh_CN": "当前不支持创建{0}资源池", + "arguments": [ + "msg.getModel()" + ], + "line": 52, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/haitai/HaiTaiSecretResourcePoolApiInterceptor.java" + }, + { + "raw": "secretResourcePool[uuid:%s] model is not %s", + "en_US": "secretResourcePool[uuid:{0}] model is not {1}", + "zh_CN": "SecretResourcePool[uuid:{0}]模型不是{1}", + "arguments": [ + "msg.getResourceUuid()", + "vo.getModel()" + ], + "line": 33, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/haitai/HaiTaiSecretResourcePoolFactory.java" + }, + { + "raw": "large file hmac encrypt failed, code: %s, detail: %s", + "en_US": "large file hmac encrypt failed, code: {0}, detail: {1}", + "zh_CN": "大文件HMAC加密失败,代码:{0},详细信息:{1}", + "arguments": [ + "agentBasic.INSMGetReturnCode()", + "agentBasic.INSMGetErrMsg()" + ], + "line": 409, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "failed to find secret key", + "en_US": "failed to find secret key", + "zh_CN": "找不到密钥", + "arguments": [], + "line": 457, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "failed to parse secret key, error: %s", + "en_US": "failed to parse secret key, error: {0}", + "zh_CN": "无法分析密钥,错误:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 465, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "cipherText can not be null", + "en_US": "cipherText can not be null", + "zh_CN": "密文不能为空", + "arguments": [], + "line": 500, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "encryptSubjectDN can not be null", + "en_US": "encryptSubjectDN can not be null", + "zh_CN": "EncryptSubjectDN不能为空", + "arguments": [], + "line": 503, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "failed to parse MS Envelope", + "en_US": "failed to parse MS Envelope", + "zh_CN": "解析MS信封失败", + "arguments": [], + "line": 508, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "failed to export secret key", + "en_US": "failed to export secret key", + "zh_CN": "无法导出密钥", + "arguments": [], + "line": 533, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "import secret key fail", + "en_US": "import secret key fail", + "zh_CN": "导入密钥失败", + "arguments": [], + "line": 550, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java" + }, + { + "raw": "failed to generate activated token for the security machine %s because %s", + "en_US": "failed to generate activated token for the security machine {0} because {1}", + "zh_CN": "无法为密码机{0}生成激活的令牌,因为{1}", + "arguments": [ + "vo.getUuid()", + "activateTokenRes.error" + ], + "line": 196, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java" + }, + { + "raw": "failed to generate dataProtect token %s for the security machine %s because %s", + "en_US": "failed to generate dataProtect token {0} for the security machine {1} because {2}", + "zh_CN": "无法为密码机{1}生成DataProtect令牌{0},因为{2}", + "arguments": [ + "dataProtectTokenName", + "vo.getUuid()", + "dataProtectTokenRes.error" + ], + "line": 206, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java" + }, + { + "raw": "failed to generate hmac token %s for the security machine %s because %s", + "en_US": "failed to generate hmac token {0} for the security machine {1} because {2}", + "zh_CN": "无法为密码机{1}生成HMAC令牌{0},因为{2}", + "arguments": [ + "hmacTokenName", + "vo.getUuid()", + "hmacTokenTokenRes.error" + ], + "line": 216, + "fileName": "src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java" + }, + { + "raw": "host[uuid: %s] memory ecc triggered, detail: %s", + "en_US": "host[uuid: {0}] memory ecc triggered, detail: {1}", + "zh_CN": "物理机[uuid:{0}]内存ECC已触发,详细信息:{1}", + "arguments": [ + "cmd.host", + "cmd.detail" + ], + "line": 505, + "fileName": "src/main/java/org/zstack/cube/CubeManagerImpl.java" + }, + { + "raw": "parameters [accountUuid] only can be used by admin user!", + "en_US": "parameters [accountUuid] only can be used by admin user!", + "zh_CN": "参数[accountUuid]必须被admin用户设置", + "arguments": [], + "line": 99, + "fileName": "src/main/java/org/zstack/daho/core/DahoApiInterceptor.java" + }, + { + "raw": "expire policy: %s is not valid", + "en_US": "expire policy: {0} is not valid", + "zh_CN": "无效的过期策略:{0}", + "arguments": [ + "msg.getExpirePolicy()" + ], + "line": 54, + "fileName": "src/main/java/org/zstack/daho/core/DahoApiInterceptor.java" + }, + { + "raw": "vlanId[%s] has been existed!", + "en_US": "vlanId[{0}] has been existed!", + "zh_CN": "VlanId[{0}]已存在!", + "arguments": [ + "msg.getVlan()" + ], + "line": 57, + "fileName": "src/main/java/org/zstack/daho/core/DahoApiInterceptor.java" + }, + { + "raw": "create daho vll task failed!", + "en_US": "create daho vll task failed!", + "zh_CN": "创建daho vll任务失败", + "arguments": [], + "line": 128, + "fileName": "src/main/java/org/zstack/daho/core/DahoSdkImpl.java" + }, + { + "raw": "no aliyun account found for accountUuid: %s", + "en_US": "no aliyun account found for accountUuid: {0}", + "zh_CN": "找不到当前账户{0}对应的阿里云账户", + "arguments": [ + "msg.getAccountUuid()" + ], + "line": 169, + "fileName": "src/main/java/org/zstack/daho/core/DahoSdkImpl.java" + }, + { + "raw": "resources %s has already been bound to directory uuid[%s] , multiple paths are not supported", + "en_US": "resources {0} has already been bound to directory uuid[{1}] , multiple paths are not supported", + "zh_CN": "资源{0}已绑定到目录uuid[{1}],不支持多个路径", + "arguments": [ + "list", + "msg.getDirectoryUuid()" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/directory/DirectoryApiInterceptor.java" + }, + { + "raw": "resource types %s are not supported by directory, allowed types are %s", + "en_US": "resource types {0} are not supported by directory, allowed types are {1}", + "zh_CN": "目录不支持资源类型{0},允许的类型为{1}", + "arguments": [ + "list", + "ALLOW_RESOURCE_TYPES" + ], + "line": 112, + "fileName": "src/main/java/org/zstack/directory/DirectoryApiInterceptor.java" + }, + { + "raw": "name contains unsupported characters, name can only contain Chinese characters, English letters, numbers, spaces, and the following characters: ()()【】@._-+ ", + "en_US": "name contains unsupported characters, name can only contain Chinese characters, English letters, numbers, spaces, and the following characters: ()()【】@._-+ ", + "zh_CN": "名称包含不支持的字符,名称只能包含中文字符、英文字母、数字、空格和以下字符:()()[]@._-+", + "arguments": [], + "line": 129, + "fileName": "src/main/java/org/zstack/directory/DirectoryApiInterceptor.java" + }, + { + "raw": "circular dependency detected, directory %s and directory %s will cause circular dependency", + "en_US": "circular dependency detected, directory {0} and directory {1} will cause circular dependency", + "zh_CN": "检测到循环依赖,目录{0}和目录{1}将导致循环依赖", + "arguments": [ + "msg.getDirectoryUuid()", + "msg.getTargetParentUuid()" + ], + "line": 356, + "fileName": "src/main/java/org/zstack/directory/DirectoryBase.java" + }, + { + "raw": "duplicate directory name, directory[uuid: %s] with name %s already exists", + "en_US": "duplicate directory name, directory[uuid: {0}] with name {1} already exists", + "zh_CN": "已存在名称为{1}的重复目录名、目录[uuid:{0}]", + "arguments": [ + "list.get(0).getUuid()", + "msg.getName()" + ], + "line": 147, + "fileName": "src/main/java/org/zstack/directory/DirectoryManagerImpl.java" + }, + { + "raw": "fail to create directory, directories are up to four levels", + "en_US": "fail to create directory, directories are up to four levels", + "zh_CN": "创建目录失败,目录最多有四层", + "arguments": [], + "line": 154, + "fileName": "src/main/java/org/zstack/directory/DirectoryManagerImpl.java" + }, + { + "raw": "the type of directory %s is not supported, the supported directory types are %s", + "en_US": "the type of directory {0} is not supported, the supported directory types are {1}", + "zh_CN": "不支持目录{0}的类型,支持的目录类型为{1}", + "arguments": [ + "msg.getType()", + "DIRECTORY_TYPES" + ], + "line": 158, + "fileName": "src/main/java/org/zstack/directory/DirectoryManagerImpl.java" + }, + { + "raw": "all resources zoneUuid must be consistent with the directory zoneUuid[%s]", + "en_US": "all resources zoneUuid must be consistent with the directory zoneUuid[{0}]", + "zh_CN": "所有资源的zoneuuid必须与目录zoneuuid[{0}]一致", + "arguments": [ + "vo.getZoneUuid()" + ], + "line": 27, + "fileName": "src/main/java/org/zstack/directory/VmDirectoryChecker.java" + }, + { + "raw": "Advice not allowed while scheduling", + "en_US": "Advice not allowed while scheduling", + "zh_CN": "计划时不允许通知", + "arguments": [], + "line": 216, + "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + }, + { + "raw": "delete DRS is not allowed while the vm is being migrated", + "en_US": "delete DRS is not allowed while the vm is being migrated", + "zh_CN": "迁移云主机时不允许删除DRS", + "arguments": [], + "line": 277, + "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + }, + { + "raw": "Scheduling is not allowed while the vm is being migrated", + "en_US": "Scheduling is not allowed while the vm is being migrated", + "zh_CN": "迁移云主机时不允许计划", + "arguments": [], + "line": 370, + "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + }, + { + "raw": "Lack of host CPU, memory monitoring data", + "en_US": "Lack of host CPU, memory monitoring data", + "zh_CN": "缺少物理机CPU、内存监控数据", + "arguments": [], + "line": 481, + "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + }, + { + "raw": "The cluster[%s] has created DRS", + "en_US": "The cluster[{0}] has created DRS", + "zh_CN": "集群[{0}]已创建DRS", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 55, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "DRS is disabled", + "en_US": "DRS is disabled", + "zh_CN": "DRS已禁用", + "arguments": [], + "line": 59, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "thresholds can not be empty", + "en_US": "thresholds can not be empty", + "zh_CN": "阈值不能为空", + "arguments": [], + "line": 64, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "illegal thresholdName[%s]", + "en_US": "illegal thresholdName[{0}]", + "zh_CN": "阈值名称[{0}]非法", + "arguments": [ + "threshold.getThresholdName()" + ], + "line": 73, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "illegal threshold operator[%s]", + "en_US": "illegal threshold operator[{0}]", + "zh_CN": "阈值运算符[{0}]非法", + "arguments": [ + "threshold.getOperator()" + ], + "line": 77, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "thresholdValue can not be empty", + "en_US": "thresholdValue can not be empty", + "zh_CN": "阈值不能为空", + "arguments": [], + "line": 81, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "illegal thresholdValue, valid range: (0, 100]", + "en_US": "illegal thresholdValue, valid range: (0, 100]", + "zh_CN": "阈值非法,有效范围:([0,100]", + "arguments": [], + "line": 86, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "GlobalConfig ENABLE_DRS is closed", + "en_US": "GlobalConfig ENABLE_DRS is closed", + "zh_CN": "GlobalConfig启用_DRS已关闭", + "arguments": [], + "line": 103, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "The DRS[%s] state is %s", + "en_US": "The DRS[{0}] state is {1}", + "zh_CN": "DRS[{0}]状态为{1}", + "arguments": [ + "msg.getUuid()", + "vo.getState().toString()" + ], + "line": 107, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "The DRS[%s] automation level is not manual", + "en_US": "The DRS[{0}] automation level is not manual", + "zh_CN": "DRS[{0}]自动化级别不是手动的", + "arguments": [ + "adviceVO.getDrsUuid()" + ], + "line": 122, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "advice[%s] has expired", + "en_US": "advice[{0}] has expired", + "zh_CN": "建议[{0}]已过期", + "arguments": [ + "msg.getAdviceUuid()" + ], + "line": 136, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "Successfully executed, no repeated executions allowed", + "en_US": "Successfully executed, no repeated executions allowed", + "zh_CN": "执行成功,不允许重复执行", + "arguments": [], + "line": 145, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "The vm[%s] has been deleted", + "en_US": "The vm[{0}] has been deleted", + "zh_CN": "云主机[{0}]已删除", + "arguments": [ + "adviceVO.getVmUuid()" + ], + "line": 152, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "The vm[%s] state is not running", + "en_US": "The vm[{0}] state is not running", + "zh_CN": "VM[{0}]状态未运行", + "arguments": [ + "adviceVO.getVmUuid()" + ], + "line": 155, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "The vm[%s] is no longer on the source host[%s]", + "en_US": "The vm[{0}] is no longer on the source host[{1}]", + "zh_CN": "VM[{0}]不再位于源物理机[{1}]上", + "arguments": [ + "adviceVO.getVmUuid()", + "adviceVO.getVmSourceHostUuid()" + ], + "line": 158, + "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + }, + { + "raw": "The cluster[%s] does not support DRS.", + "en_US": "The cluster[{0}] does not support DRS.", + "zh_CN": "集群[{0}]不支持DRS。", + "arguments": [ + "msg.getClusterUuid()" + ], + "line": 273, + "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + }, + { + "raw": "Can not create DRS, %s", + "en_US": "Can not create DRS, {0}", + "zh_CN": "无法创建DRS,{0}", + "arguments": [ + "reasons" + ], + "line": 290, + "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + }, + { + "raw": "hostUuids is empty", + "en_US": "hostUuids is empty", + "zh_CN": "HOSTuuidS为空", + "arguments": [], + "line": 323, + "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + }, + { + "raw": "query hosts utilization data failed", + "en_US": "query hosts utilization data failed", + "zh_CN": "查询物理机利用率数据失败", + "arguments": [], + "line": 330, + "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + }, + { + "raw": "failed to parse API message: can not parse encryption param with type %s", + "en_US": "failed to parse API message: can not parse encryption param with type {0}", + "zh_CN": "未能分析API消息:无法分析类型为{0}的加密参数", + "arguments": [ + "bundle.getEncryptionType()" + ], + "line": 83, + "fileName": "src/main/java/org/zstack/encrypt/EncryptionParamApiInterceptor.java" + }, + { + "raw": "failed to parse API message: found %d encryption param system tags, expect 1", + "en_US": "failed to parse API message: found {0} encryption param system tags, expect 1", + "zh_CN": "未能分析API消息:找到{0}个加密参数系统标记,应为1个", + "arguments": [ + "matchTags.size()" + ], + "line": 128, + "fileName": "src/main/java/org/zstack/encrypt/EncryptionParamApiInterceptor.java" + }, + { + "raw": "some volume[uuids:%s] recover failed. you can trigger it again by reconnect it.", + "en_US": "some volume[uuids:{0}] recover failed. you can trigger it again by reconnect it.", + "zh_CN": "某些卷[uuid:{0}]恢复失败。您可以通过重新连接来再次触发它。", + "arguments": [ + "volumeUuids" + ], + "line": 142, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/HostZBoxBackupRecoverGC.java" + }, + { + "raw": "there is another external backup[uuid: %s] recovering", + "en_US": "there is another external backup[uuid: {0}] recovering", + "zh_CN": "另一个外部备份[uuid:{0}]正在恢复", + "arguments": [ + "externalBackupUuid" + ], + "line": 34, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupApiInterceptor.java" + }, + { + "raw": "both hostUuids and backupStorageUuids are empty. you must specify one or both of them.", + "en_US": "both hostUuids and backupStorageUuids are empty. you must specify one or both of them.", + "zh_CN": "Hostuuid和BackupStorageuuid均为空。您必须指定其中一个或两个。", + "arguments": [], + "line": 38, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupApiInterceptor.java" + }, + { + "raw": "please insert zbox to management node.", + "en_US": "please insert zbox to management node.", + "zh_CN": "请将ZBOX插入管理节点。", + "arguments": [], + "line": 691, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java" + }, + { + "raw": "cannot find recover.conf under zbox backup install dir.", + "en_US": "cannot find recover.conf under zbox backup install dir.", + "zh_CN": "在ZBOX备份安装目录下找不到recover.conf。", + "arguments": [], + "line": 219, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java" + }, + { + "raw": "fail to backup database: %s", + "en_US": "fail to backup database: {0}", + "zh_CN": "无法备份数据库:{0}", + "arguments": [ + "result.getExecutionLog()" + ], + "line": 741, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java" + }, + { + "raw": "zbox should be inserted to a host first.", + "en_US": "zbox should be inserted to a host first.", + "zh_CN": "应首先将ZBox插入物理机。", + "arguments": [], + "line": 591, + "fileName": "src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java" + }, + { + "raw": "crond is not running", + "en_US": "crond is not running", + "zh_CN": "crond任务未在运行", + "arguments": [], + "line": 81, + "fileName": "src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java" + }, + { + "raw": "Missing CPU/memory settings", + "en_US": "Missing CPU/memory settings", + "zh_CN": "缺少CPU/内存设置", + "arguments": [], + "line": 485, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Unexpected CPU/memory settings", + "en_US": "Unexpected CPU/memory settings", + "zh_CN": "意外的CPU/内存设置", + "arguments": [], + "line": 489, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "instance offering[uuid:%s] is Disabled, can\u0027t create vm from it", + "en_US": "instance offering[uuid:{0}] is Disabled, can\u0027t create vm from it", + "zh_CN": "计算规格[uuid:{0}]没有被启用,不能根据该规格创建云主机", + "arguments": [ + "instanceOfferingUuid" + ], + "line": 498, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "instance offering[uuid:%s, type:%s] is not UserVm type, can\u0027t create vm from it", + "en_US": "instance offering[uuid:{0}, type:{1}] is not UserVm type, can\u0027t create vm from it", + "zh_CN": "计算规格[uuid:{0}, type:{1}]不是UserVm类型,不能通过它创建云主机", + "arguments": [ + "instanceOfferingUuid", + "ivo.getType()" + ], + "line": 502, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] is Disabled, can\u0027t create vm from it", + "en_US": "image[uuid:{0}] is Disabled, can\u0027t create vm from it", + "zh_CN": "镜像[uuid:{0}]没被启用,不能根据该镜像创建云主机", + "arguments": [ + "msg.getImageUuid()" + ], + "line": 539, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] is not ready yet, can\u0027t create vm from it", + "en_US": "image[uuid:{0}] is not ready yet, can\u0027t create vm from it", + "zh_CN": "镜像[uuid:{0}]尚未就绪,无法从中创建VM", + "arguments": [ + "msg.getImageUuid()" + ], + "line": 544, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] is system image, can\u0027t be used to create user vm", + "en_US": "image[uuid:{0}] is system image, can\u0027t be used to create user vm", + "zh_CN": "镜像[uuid:{0}] 是系统镜像,不能使用它创建用户云主机", + "arguments": [ + "msg.getImageUuid()" + ], + "line": 559, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "disk offerings[uuids:%s] are Disabled, can not create vm from it", + "en_US": "disk offerings[uuids:{0}] are Disabled, can not create vm from it", + "zh_CN": "云盘规格[uuids:{0}]没有被启用,不能使用它创建云主机", + "arguments": [ + "diskUuids" + ], + "line": 575, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "current operation is not supported on ft secondary vm[uuid:%s]", + "en_US": "current operation is not supported on ft secondary vm[uuid:{0}]", + "zh_CN": "FT辅助云主机[uuid:{0}]不支持当前操作", + "arguments": [ + "vmInstanceUuid" + ], + "line": 450, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "pvm[uuid:%s] and svm[uuid:%s] volume number not matches, do not allowed to start", + "en_US": "pvm[uuid:{0}] and svm[uuid:{1}] volume number not matches, do not allowed to start", + "zh_CN": "PVM[uuid:{0}]和SVM[uuid:{1}]卷号不匹配,不允许启动", + "arguments": [ + "group.getPrimaryVmInstanceUuid()", + "group.getSecondaryVmInstanceUuid()" + ], + "line": 126, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "volume with index: %d, of pvm[uuid:%s] and svm[uuid:%s] have different size, do not allowed to start", + "en_US": "volume with index: {0}, of pvm[uuid:{1}] and svm[uuid:{2}] have different size, do not allowed to start", + "zh_CN": "PVM[uuid:{1}]和SVM[uuid:{2}]中索引为{0}的卷大小不同,不允许启动", + "arguments": [ + "i", + "group.getPrimaryVmInstanceUuid()", + "group.getSecondaryVmInstanceUuid()" + ], + "line": 135, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "volume with index: %d, of pvm[uuid:%s] and svm[uuid:%s]\u0027s cache volume have different size, do not allowed to start", + "en_US": "volume with index: {0}, of pvm[uuid:{1}] and svm[uuid:{2}]\u0027s cache volume have different size, do not allowed to start", + "zh_CN": "PVM[uuid:{1}]和SVM[uuid:{2}]的缓存卷的索引为{0}的卷大小不同,不允许启动", + "arguments": [ + "i", + "group.getPrimaryVmInstanceUuid()", + "group.getSecondaryVmInstanceUuid()" + ], + "line": 146, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] is still used by fault tolerance vm[uuid:%s]", + "en_US": "image[uuid:{0}] is still used by fault tolerance vm[uuid:{1}]", + "zh_CN": "容错云主机[uuid:{1}]仍在使用镜像[uuid:{0}]", + "arguments": [ + "msg.getUuid()", + "faultToleranceVmGroupUuid" + ], + "line": 169, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "could not delete l3 network[uuid:%s]. Fault tolerance vm[%s] in states[%s, %s] still using it. Stop related fault tolerance vms before delete l3 network", + "en_US": "could not delete l3 network[uuid:{0}]. Fault tolerance vm[{1}] in states[{2}, {3}] still using it. Stop related fault tolerance vms before delete l3 network", + "zh_CN": "无法删除三层网络[uuid:{0}]。状态为[{2},{3}]的容错VM[{1}]仍在使用。在删除三层网络之前停止相关的容错云主机", + "arguments": [ + "msg.getL3NetworkUuid()", + "String.join(\",\", vmInstanceUuids)", + "VmInstanceState.Paused", + "VmInstanceState.Running" + ], + "line": 212, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Can not fail-over vm[uuid:%s], please enable ft in GlobalConfig", + "en_US": "Can not fail-over vm[uuid:{0}], please enable ft in GlobalConfig", + "zh_CN": "无法对VM[uuid:{0}]进行故障转移,请在GlobalConfig中启用FT", + "arguments": [ + "msg.getFaultToleranceVmUuid()" + ], + "line": 266, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Can not fail-over vm[uuid:%s], please confirm it is a fault tolerance vm group", + "en_US": "Can not fail-over vm[uuid:{0}], please confirm it is a fault tolerance vm group", + "zh_CN": "无法对VM[uuid:{0}]进行故障转移,请确认它是容错VM组", + "arguments": [ + "msg.getFaultToleranceVmUuid()" + ], + "line": 270, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Can not fail-over vm[uuid:%s], because fault tolerance vm group is not in status of [%s, %s]", + "en_US": "Can not fail-over vm[uuid:{0}], because fault tolerance vm group is not in status of [{1}, {2}]", + "zh_CN": "无法对VM[uuid:{0}]进行故障转移,因为容错VM组的状态不是[{1},{2}]", + "arguments": [ + "msg.getFaultToleranceVmUuid()", + "FaultToleranceStatus.Protected", + "FaultToleranceStatus.Unknown" + ], + "line": 276, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Can not maintain host, because ft vms[%s] are under recovering", + "en_US": "Can not maintain host, because ft vms[{0}] are under recovering", + "zh_CN": "无法维护物理机,因为正在恢复FT VM[{0}]", + "arguments": [ + "Joiner.on(\",\").join(vmUuids)" + ], + "line": 301, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "current operation[api:%s] is not supported when ft vm[uuid:%s, state:%s] is not stopped", + "en_US": "current operation[api:{0}] is not supported when ft vm[uuid:{1}, state:{2}] is not stopped", + "zh_CN": "未停止FT VM[uuid:{1},状态:{2}]时,不支持当前操作[API:{0}]", + "arguments": [ + "msg.getClass()", + "msg.getVmInstanceUuid()", + "state" + ], + "line": 319, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Can not set vm level to %s, please enable ft in GlobalConfig", + "en_US": "Can not set vm level to {0}, please enable ft in GlobalConfig", + "zh_CN": "无法将VM级别设置为{0},请在GlobalConfig中启用FT", + "arguments": [ + "VmHaLevel.FaultTolerance.toString()" + ], + "line": 367, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Ft network is not set", + "en_US": "Ft network is not set", + "zh_CN": "未设置FT网络", + "arguments": [], + "line": 515, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "can not update ft vm[uuid:%s] cpu number, need to stop both of the vms", + "en_US": "can not update ft vm[uuid:{0}] cpu number, need to stop both of the vms", + "zh_CN": "无法更新FT VM[uuid:{0}]CPU编号,需要停止两个VM", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 423, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "can not update ft vm[uuid:%s] memory size, need to stop both of the vms", + "en_US": "can not update ft vm[uuid:{0}] memory size, need to stop both of the vms", + "zh_CN": "无法更新FT VM[uuid:{0}]内存大小,需要停止两个VM", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 427, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "can not update ft vm[uuid:%s] platform, need to stop both of the vms", + "en_US": "can not update ft vm[uuid:{0}] platform, need to stop both of the vms", + "zh_CN": "无法更新FT VM[uuid:{0}]平台,需要停止两个VM", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 431, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "current operation is not supported on ft group vm[uuid:%s]", + "en_US": "current operation is not supported on ft group vm[uuid:{0}]", + "zh_CN": "FT组VM[uuid:{0}]不支持当前操作", + "arguments": [ + "vmInstanceUuid" + ], + "line": 442, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "current operation is not supported on ft primary vm[uuid:%s]", + "en_US": "current operation is not supported on ft primary vm[uuid:{0}]", + "zh_CN": "FT主VM[uuid:{0}]不支持当前操作", + "arguments": [ + "vmInstanceUuid" + ], + "line": 446, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "current operation is not supported on secondary vm[uuid:%s]", + "en_US": "current operation is not supported on secondary vm[uuid:{0}]", + "zh_CN": "辅助云主机[uuid:{0}]不支持当前操作", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 466, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "can not migrate FT primary vm", + "en_US": "can not migrate FT primary vm", + "zh_CN": "无法迁移FT主云主机", + "arguments": [], + "line": 472, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "can not migrate FT secondary vm", + "en_US": "can not migrate FT secondary vm", + "zh_CN": "无法迁移FT辅助云主机", + "arguments": [], + "line": 476, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "Failed to create ft vm, please enable ft in GlobalConfig", + "en_US": "Failed to create ft vm, please enable ft in GlobalConfig", + "zh_CN": "无法创建FT VM,请在GlobalConfig中启用FT", + "arguments": [], + "line": 511, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] is of mediaType: %s, only RootVolumeTemplate can be used to create vm", + "en_US": "image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate can be used to create vm", + "zh_CN": "镜像[uuid:{0}]的媒体类型为:{1},只能使用RootVolumeTemplate创建VM", + "arguments": [ + "msg.getImageUuid()", + "imgFormat" + ], + "line": 549, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "image[uuid:%s] is of format: %s, only %s can be used to create vm", + "en_US": "image[uuid:{0}] is of format: {1}, only {2} can be used to create vm", + "zh_CN": "镜像[uuid:{0}]的格式为:{1},只有{2}可用于创建VM", + "arguments": [ + "msg.getImageUuid()", + "imageFileFmt", + "ImageConstant.QCOW2_FORMAT_STRING" + ], + "line": 554, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java" + }, + { + "raw": "failed to allocate port on host[uuid: %s]", + "en_US": "failed to allocate port on host[uuid: {0}]", + "zh_CN": "无法在物理机[uuid:{0}]上分配端口", + "arguments": [ + "hostUuid" + ], + "line": 364, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java" + }, + { + "raw": "allocated port num less than requested on host[uuid: %s]", + "en_US": "allocated port num less than requested on host[uuid: {0}]", + "zh_CN": "物理机[uuid:{0}]上分配的端口号小于请求的端口号", + "arguments": [ + "hostUuid" + ], + "line": 369, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java" + }, + { + "raw": "could not get hostUuid of primary vm[uuid:%s]", + "en_US": "could not get hostUuid of primary vm[uuid:{0}]", + "zh_CN": "无法获取主云主机[uuid:{0}]的Hostuuid", + "arguments": [ + "smsg.getPrimaryVmInstanceUuid()" + ], + "line": 524, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java" + }, + { + "raw": "can not start secondary vm, because primary vm is still stopped", + "en_US": "can not start secondary vm, because primary vm is still stopped", + "zh_CN": "无法启动辅助云主机,因为主云主机仍处于停止状态", + "arguments": [], + "line": 892, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java" + }, + { + "raw": "Can not migrate ft secondary vm[uuid:%s]", + "en_US": "Can not migrate ft secondary vm[uuid:{0}]", + "zh_CN": "无法迁移FT辅助云主机[uuid:{0}]", + "arguments": [ + "vm.getUuid()" + ], + "line": 1322, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java" + }, + { + "raw": "Can not migrate ft primary vm[uuid:%s]", + "en_US": "Can not migrate ft primary vm[uuid:{0}]", + "zh_CN": "无法迁移FT主云主机[uuid:{0}]", + "arguments": [ + "vm.getUuid()" + ], + "line": 1327, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java" + }, + { + "raw": "Current ft vm is in unknown status, can not stop it, please try to fail-over it manually", + "en_US": "Current ft vm is in unknown status, can not stop it, please try to fail-over it manually", + "zh_CN": "当前FT云主机处于未知状态,无法停止,请尝试手动故障转移", + "arguments": [], + "line": 546, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmInstanceBase.java" + }, + { + "raw": "unable to start the vm[uuid:%s]. It doesn\u0027t have any nic, please attach a nic and try again", + "en_US": "unable to start the vm[uuid:{0}]. It doesn\u0027t have any nic, please attach a nic and try again", + "zh_CN": "无法启动云主机[uuid:{0}]。该云主机没有网卡,请添加网卡后再试", + "arguments": [ + "self.getUuid()" + ], + "line": 596, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmInstanceBase.java" + }, + { + "raw": "failed to allocate port of nic[uuid: %s] on host[uuid: %s]", + "en_US": "failed to allocate port of nic[uuid: {0}] on host[uuid: {1}]", + "zh_CN": "无法分配物理机[uuid:{1}]上的NIC[uuid:{0}]的端口", + "arguments": [ + "nicUuid", + "pvm.getHostUuid()" + ], + "line": 3110, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "allocated port num less than requested of nic[uuid: %s] on host[uuid: %s]", + "en_US": "allocated port num less than requested of nic[uuid: {0}] on host[uuid: {1}]", + "zh_CN": "分配的端口数小于物理机[uuid:{1}]上的NIC[uuid:{0}]请求的端口数", + "arguments": [ + "nicUuid", + "pvm.getHostUuid()" + ], + "line": 3115, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "can not create secondary vm, because primary vm is stopped", + "en_US": "can not create secondary vm, because primary vm is stopped", + "zh_CN": "无法创建辅助云主机,因为主云主机已停止", + "arguments": [], + "line": 727, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "an other fault tolerance gc task is running, cancel the new task and wait return", + "en_US": "an other fault tolerance gc task is running, cancel the new task and wait return", + "zh_CN": "其他容错GC任务正在运行,请取消新任务并等待返回", + "arguments": [], + "line": 641, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "can not start secondary vm, because primary vm is stopped", + "en_US": "can not start secondary vm, because primary vm is stopped", + "zh_CN": "无法启动辅助云主机,因为主云主机已停止", + "arguments": [], + "line": 2256, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "created svm found, report error for this start secondary vm request", + "en_US": "created svm found, report error for this start secondary vm request", + "zh_CN": "找到已创建的SVM,报告此启动辅助云主机请求的错误", + "arguments": [], + "line": 1212, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "could not failover vm[uuid:%s]. Related fault tolerance vm group not exists", + "en_US": "could not failover vm[uuid:{0}]. Related fault tolerance vm group not exists", + "zh_CN": "无法对云主机[uuid:{0}]进行故障切换。相关容错云主机组不存在", + "arguments": [ + "vmInstanceUuid" + ], + "line": 1468, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "pvm[uuid:%s] not exists", + "en_US": "pvm[uuid:{0}] not exists", + "zh_CN": "PVM[uuid:{0}]不存在", + "arguments": [ + "group.getPrimaryVmInstanceUuid()" + ], + "line": 1484, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "unexpected exception", + "en_US": "unexpected exception", + "zh_CN": "意外异常", + "arguments": [], + "line": 1596, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "could not failover. Secondary vm is unknown but no fault tolerance network address available", + "en_US": "could not failover. Secondary vm is unknown but no fault tolerance network address available", + "zh_CN": "无法进行故障转移。辅助云主机未知,但没有可用的容错网络地址", + "arguments": [], + "line": 1556, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "could not failover. Primary vm is unknown but no fault tolerance network address available", + "en_US": "could not failover. Primary vm is unknown but no fault tolerance network address available", + "zh_CN": "无法进行故障转移。主云主机未知,但没有可用的容错网络地址", + "arguments": [], + "line": 1495, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "cannot found available ip from current ft network. Check whether global config[category:ft name:fault.tolerance.network.cidr] is correctly set, and confirm that host[uuid:%s] own ip address in the CIDR", + "en_US": "cannot found available ip from current ft network. Check whether global config[category:ft name:fault.tolerance.network.cidr] is correctly set, and confirm that host[uuid:{0}] own ip address in the CIDR", + "zh_CN": "在当前FT网络中找不到可用的IP。e.检查是否正确设置了全局配置[Category:FT Name:Fault.TolerancNetwork.CIDR],并确认物理机[uuid:{0}]在CIDR中拥有IP地址", + "arguments": [ + "hostUuid" + ], + "line": 1669, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "not fault tolerance vm port found", + "en_US": "not fault tolerance vm port found", + "zh_CN": "未找到容错VM端口", + "arguments": [], + "line": 3009, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java" + }, + { + "raw": "cannot find the image[uuid:%s] in any connected backup storage. check below:\\n1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", + "en_US": "cannot find the image[uuid:{0}] in any connected backup storage. check below:\\n1. if the backup storage is attached to the zone where the VM[name: {1}, uuid:{2}] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", + "zh_CN": "不能发现镜像[uuid:{0}]在任何处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \\n1. 镜像服务器是否已经过载到区域中的云主机[name: {1}, uuid:{2}]中;\\n2. 如果镜像服务器不是处于连接状态,请尝试重连", + "arguments": [ + "imageUuid", + "spec.getVmInventory().getName()", + "spec.getVmInventory().getUuid()" + ], + "line": 95, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java" + }, + { + "raw": "cannot find the image[uuid:%s] in any connected backup storage attached to the zone[uuid:%s]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", + "en_US": "cannot find the image[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is in\\n2. if the backup storage is in connected status, if not, try reconnecting it", + "zh_CN": "不能发现镜像[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \\n1. 镜像服务器是否已经过载到区域中的云主机[name: {2}, uuid:{3}]中;\\n2. 如果镜像服务器不是处于Connected状态,请尝试重连", + "arguments": [ + "imageUuid", + "spec.getVmInventory().getZoneUuid()", + "spec.getVmInventory().getName()", + "spec.getVmInventory().getUuid()" + ], + "line": 89, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java" + }, + { + "raw": "no backup storage attached to the zone[uuid:%s] contains the ISO[uuid:%s]", + "en_US": "no backup storage attached to the zone[uuid:{0}] contains the ISO[uuid:{1}]", + "zh_CN": "没有包含着ISO[uuid:{1}]的镜像服务器添加到区域[uuid:{0}]", + "arguments": [ + "zoneUuid", + "isoImageUuid" + ], + "line": 117, + "fileName": "src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java" + }, + { + "raw": "missing fault tolerance vm group", + "en_US": "missing fault tolerance vm group", + "zh_CN": "缺少容错VM组", + "arguments": [], + "line": 63, + "fileName": "src/main/java/org/zstack/faulttolerance/ShadowVmCloneTagsFlow.java" + }, + { + "raw": "The network[%s] have been added into the flow meter[%s]", + "en_US": "The network[{0}] have been added into the flow meter[{1}]", + "zh_CN": "网络[{0}]已添加到流量计[{1}]中", + "arguments": [ + "vo.getL3NetworkUuid()", + "vo.getFlowMeterUuid()" + ], + "line": 63, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "The virtual router have been added into other flow meter", + "en_US": "The virtual router have been added into other flow meter", + "zh_CN": "已将虚拟路由器添加到其他流量计中", + "arguments": [], + "line": 71, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "invalid type parameter is %s and should be in %s", + "en_US": "invalid type parameter is {0} and should be in {1}", + "zh_CN": "无效的类型参数为{0},应位于{1}中", + "arguments": [ + "msg.getVersion()", + "FlowMeterConstants.TYPE.NetFlow.toString()" + ], + "line": 77, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "[%s] is not formatted as IP address", + "en_US": "[{0}] is not formatted as IP address", + "zh_CN": "[{0}]的格式不是IP地址", + "arguments": [ + "msg.getServer()" + ], + "line": 154, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "Collector duplicate with %s", + "en_US": "Collector duplicate with {0}", + "zh_CN": "收集器与{0}重复", + "arguments": [ + "collector.getUuid()" + ], + "line": 143, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "FlowMeter[%s] doesn\u0027t exist", + "en_US": "FlowMeter[{0}] doesn\u0027t exist", + "zh_CN": "流量计[{0}]不存在", + "arguments": [ + "collectorVO.getFlowMeterUuid()" + ], + "line": 164, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "FlowMeter[%s] IPv6 doesn\u0027t support version[%s]", + "en_US": "FlowMeter[{0}] IPv6 doesn\u0027t support version[{1}]", + "zh_CN": "流量计[{0}]IPv6不支持版本[{1}]", + "arguments": [ + "collectorVO.getFlowMeterUuid()", + "vo.getVersion().toString()" + ], + "line": 168, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "no specify parameter", + "en_US": "no specify parameter", + "zh_CN": "没有指定参数", + "arguments": [], + "line": 150, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "Flow collector[%s] doesn\u0027t exist", + "en_US": "Flow collector[{0}] doesn\u0027t exist", + "zh_CN": "流收集器[{0}]不存在", + "arguments": [ + "msg.getUuid()" + ], + "line": 159, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "Collector [%s %d] duplicate with %s", + "en_US": "Collector [{0} {1}] duplicate with {2}", + "zh_CN": "收集器[{0}{1}]与{2}重复", + "arguments": [ + "server", + "port", + "collector.getUuid()" + ], + "line": 183, + "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + }, + { + "raw": "unable to set vm hostname. the vm[uuid:%s] do not have default L3 network", + "en_US": "unable to set vm hostname. the vm[uuid:{0}] do not have default L3 network", + "zh_CN": "无法设置云主机物理机名。VM[uuid:{0}]没有默认的三层网络", + "arguments": [ + "vmUuid" + ], + "line": 88, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "conflict hostname, there has been a VM[uuid:%s] having hostname[%s] on L3 network[uuid:%s]", + "en_US": "conflict hostname, there has been a VM[uuid:{0}] having hostname[{1}] on L3 network[uuid:{2}]", + "zh_CN": "物理机名冲突,在三层网络[uuid:{2}]上存在物理机名为[{1}]的云主机[uuid:{0}]", + "arguments": [ + "sameTag.getResourceUuid()", + "hostname", + "defaultL3uuid" + ], + "line": 103, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "update vm[uuid:%s] network config failed, because vm not running.", + "en_US": "update vm[uuid:{0}] network config failed, because vm not running.", + "zh_CN": "更新VM[uuid:{0}]网络配置失败,因为VM未运行。", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 111, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "update vm[uuid:%s] network config failed, because the vm type %s is not supported.", + "en_US": "update vm[uuid:{0}] network config failed, because the vm type {1} is not supported.", + "zh_CN": "更新VM[uuid:{0}]网络配置失败,因为不支持VM类型{1}。", + "arguments": [ + "msg.getVmInstanceUuid()", + "vm.getType()" + ], + "line": 116, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "update vm[uuid:%s] network config failed, because guesttools not running.", + "en_US": "update vm[uuid:{0}] network config failed, because guesttools not running.", + "zh_CN": "更新VM[uuid:{0}]网络配置失败,因为guestTools未运行。", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 129, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "update vm[uuid:%s] network config failed, because the guesttools version is too low for this feature.", + "en_US": "update vm[uuid:{0}] network config failed, because the guesttools version is too low for this feature.", + "zh_CN": "更新VM[uuid:{0}]网络配置失败,因为GuestTools版本太低,无法使用此功能。", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 125, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "sync nic[uuid:%s] network config failed, the current qga tools only support manual ipv6 configuration and do not support automatic sync", + "en_US": "sync nic[uuid:{0}] network config failed, the current qga tools only support manual ipv6 configuration and do not support automatic sync", + "zh_CN": "同步NIC[uuid:{0}]网络配置失败,当前QGA工具仅支持手动IPv6配置,不支持自动同步", + "arguments": [ + "nic.getUuid()" + ], + "line": 136, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it\u0027s hypervisor type is not supported", + "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it\u0027s hypervisor type is not supported", + "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为其虚拟化层目前不支持增强工具", + "arguments": [ + "msg.getUuid()" + ], + "line": 147, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it\u0027s not running", + "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it\u0027s not running", + "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为它目前并未处于运行状态", + "arguments": [ + "msg.getUuid()" + ], + "line": 154, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it\u0027s not user vm", + "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it\u0027s not user vm", + "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为它不是用户云主机", + "arguments": [ + "msg.getUuid()" + ], + "line": 161, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it has no cdrom", + "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it has no cdrom", + "zh_CN": "无法为云主机[uuid:{0}挂载增强工具镜像,因为它没有配备光驱", + "arguments": [ + "msg.getUuid()" + ], + "line": 168, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot get guest-tools info from vm[uuid:%s] because it\u0027s not running", + "en_US": "cannot get guest-tools info from vm[uuid:{0}] because it\u0027s not running", + "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为它目前并未处于运行状态", + "arguments": [ + "vmUuid" + ], + "line": 191, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot get guest-tools info from vm[uuid:%s] because it\u0027s not user vm", + "en_US": "cannot get guest-tools info from vm[uuid:{0}] because it\u0027s not user vm", + "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为它不是用户云主机", + "arguments": [ + "vmUuid" + ], + "line": 197, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "invalid debug parameter: %s", + "en_US": "invalid debug parameter: {0}", + "zh_CN": "无效的调试参数:{0}", + "arguments": [ + "invalidSet" + ], + "line": 219, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "can not update guest tools state for vm [uuid:%s] because vm is deleted", + "en_US": "can not update guest tools state for vm [uuid:{0}] because vm is deleted", + "zh_CN": "无法更新VM[uuid:{0}]的来宾工具状态,因为VM已删除", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 227, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "can not update guest tools state for vm[uuid:%s] because it\u0027s not user vm", + "en_US": "can not update guest tools state for vm[uuid:{0}] because it\u0027s not user vm", + "zh_CN": "无法更新VM[uuid:{0}]的来宾工具状态,因为它不是用户VM", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 232, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + }, + { + "raw": "cannot get latest guest-tools for vm[uuid:%s] because it\u0027s hypervisor type is not supported", + "en_US": "cannot get latest guest-tools for vm[uuid:{0}] because it\u0027s hypervisor type is not supported", + "zh_CN": "无法为云主机[uuid:{0}获取最新可用的增强工具镜像,因为其虚拟化层目前不支持增强工具", + "arguments": [ + "msg.getUuid()" + ], + "line": 704, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java" + }, + { + "raw": "cannot get latest guest-tools for vm[uuid:%s] because it\u0027s not running or volume recovering.", + "en_US": "cannot get latest guest-tools for vm[uuid:{0}] because it\u0027s not running or volume recovering.", + "zh_CN": "无法获取VM[uuid:{0}]的最新来宾工具,因为它未运行或卷正在恢复。", + "arguments": [ + "msg.getUuid()" + ], + "line": 713, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java" + }, + { + "raw": "cannot get latest guest-tools for vm[uuid:%s] because it\u0027s not user vm", + "en_US": "cannot get latest guest-tools for vm[uuid:{0}] because it\u0027s not user vm", + "zh_CN": "无法为云主机[uuid:{0}]获取最新可用的增强工具镜像,因为它不是用户云主机", + "arguments": [ + "msg.getUuid()" + ], + "line": 722, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java" + }, + { + "raw": "no proper guest tools iso found in management node[uuid:%s] for host[uuid:%s]", + "en_US": "no proper guest tools iso found in management node[uuid:{0}] for host[uuid:{1}]", + "zh_CN": "无法在管理节点[uuid:{0}]上为物理机[uuid:{1}]寻找到合适的增强工具镜像", + "arguments": [ + "Platform.getManagementServerId()", + "msg.getHostUuid()" + ], + "line": 1067, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java" + }, + { + "raw": "failed to set vm[uuid: %s, name: %s] hostname, because qga state is not running and there is no dhcp service", + "en_US": "failed to set vm[uuid: {0}, name: {1}] hostname, because qga state is not running and there is no dhcp service", + "zh_CN": "无法设置VM[uuid:{0},名称:{1}]物理机名,因为QGA状态未在运行,并且没有DHCP服务", + "arguments": [ + "vm.getUuid()", + "vm.getName()" + ], + "line": 2042, + "fileName": "src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java" + }, + { + "raw": "failed to get guest tools info from vm[uuid:%s], because:%s", + "en_US": "failed to get guest tools info from vm[uuid:{0}], because:{1}", + "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为:{1}", + "arguments": [ + "vmUuid", + "rsp.getError()" + ], + "line": 144, + "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java" + }, + { + "raw": "failed to download guest tools iso because no kvm host[uuid:%s] found", + "en_US": "failed to download guest tools iso because no kvm host[uuid:{0}] found", + "zh_CN": "KVM物理机[uuid:{0}]不存在,无法为其下载增强工具镜像", + "arguments": [ + "host.getUuid()" + ], + "line": 244, + "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java" + }, + { + "raw": "failed to attach guest tools iso to vm[uuid:%s], because:%s", + "en_US": "failed to attach guest tools iso to vm[uuid:{0}], because:{1}", + "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为:{1}", + "arguments": [ + "vm.getUuid()", + "rsp.getError()" + ], + "line": 313, + "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java" + }, + { + "raw": "failed to detach guest tools iso from vm[uuid:%s], because:%s", + "en_US": "failed to detach guest tools iso from vm[uuid:{0}], because:{1}", + "zh_CN": "无法从VM[uuid:{0}]分离来宾工具ISO,因为:{1}", + "arguments": [ + "vm.getUuid()", + "rsp.getError()" + ], + "line": 358, + "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java" + }, + { + "raw": "can not be here", + "en_US": "can not be here", + "zh_CN": "不能在这里。", + "arguments": [ + "errCode" + ], + "line": 200, + "fileName": "src/main/java/org/zstack/guesttools/pvpanic/PVPanicCrashStrategyManagerImpl.java" + }, + { + "raw": "can not set FT on vm[uuid:%s] because it is not stopped", + "en_US": "can not set FT on vm[uuid:{0}] because it is not stopped", + "zh_CN": "无法在VM[uuid:{0}]上设置FT,因为它未停止", + "arguments": [ + "vm.getUuid()" + ], + "line": 90, + "fileName": "src/main/java/org/zstack/ha/HaInterceptor.java" + }, + { + "raw": "can not set FT on vm[uuid:%s] because some data volume is still attached", + "en_US": "can not set FT on vm[uuid:{0}] because some data volume is still attached", + "zh_CN": "无法在VM[uuid:{0}]上设置FT,因为某些数据云盘仍处于挂接状态", + "arguments": [ + "vm.getUuid()" + ], + "line": 94, + "fileName": "src/main/java/org/zstack/ha/HaInterceptor.java" + }, + { + "raw": "can not set FT on vm[uuid:%s] since pci device attached", + "en_US": "can not set FT on vm[uuid:{0}] since pci device attached", + "zh_CN": "由于连接了PCI设备,无法在VM[uuid:{0}]上设置FT", + "arguments": [ + "msg.getUuid()" + ], + "line": 102, + "fileName": "src/main/java/org/zstack/ha/HaInterceptor.java" + }, + { + "raw": "can not set FT on vm[uuid:%s] because there are usb devices attached by passthrough", + "en_US": "can not set FT on vm[uuid:{0}] because there are usb devices attached by passthrough", + "zh_CN": "无法在VM[uuid:{0}]上设置FT,因为存在通过passthrough连接的USB设备", + "arguments": [ + "msg.getUuid()" + ], + "line": 108, + "fileName": "src/main/java/org/zstack/ha/HaInterceptor.java" + }, + { + "raw": "can not set FT on vmm[uuid:%s] since mdev device attached", + "en_US": "can not set FT on vmm[uuid:{0}] since mdev device attached", + "zh_CN": "无法在VMM[uuid:{0}]上设置FT,因为已连接MDEV设备", + "arguments": [ + "msg.getUuid()" + ], + "line": 119, + "fileName": "src/main/java/org/zstack/ha/HaInterceptor.java" + }, + { + "raw": "hosts failed to port scan the failure host[uuid:%s, ip:%s], errors are %s", + "en_US": "hosts failed to port scan the failure host[uuid:{0}, ip:{1}], errors are {2}", + "zh_CN": "扫描物理机失败[uuid:{0}, ip:{1}],错误原因是 {2}", + "arguments": [ + "struct.getHostUuid()", + "struct.getHostIp()", + "errors" + ], + "line": 237, + "fileName": "src/main/java/org/zstack/ha/HaKvmHostSiblingChecker.java" + }, + { + "raw": "(%d/%d) start HaHostChecker %s: predict time is [%d] seconds", + "en_US": "({0}/{1}) start HaHostChecker {2}: predict time is [{3}] seconds", + "zh_CN": "({0}/{1})启动HaHostChecker{2}:预测时间为[{3}]秒", + "arguments": [ + "checkers.indexOf(checker) + 1", + "checkers.size()", + "checker.getClass().getSimpleName()", + "s.getSuccessTimes() * s.getSuccessInterval()" + ], + "line": 96, + "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + }, + { + "raw": "cannot find the host of the vm[name:%s, uuid:%s], hostUuid is null", + "en_US": "cannot find the host of the vm[name:{0}, uuid:{1}], hostUuid is null", + "zh_CN": "找不到vm[name:{0}, uuid:{1}]的物理机, 因为hostUuid为null", + "arguments": [ + "self.getName()", + "self.getUuid()" + ], + "line": 160, + "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + }, + { + "raw": "no HaHostChecker found, cannot do HA", + "en_US": "no HaHostChecker found, cannot do HA", + "zh_CN": "找不到HaHostChecker,无法执行HA", + "arguments": [], + "line": 167, + "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + }, + { + "raw": "the management node fails to scan the host", + "en_US": "the management node fails to scan the host", + "zh_CN": "管理节点扫描物理机失败", + "arguments": [], + "line": 102, + "fileName": "src/main/java/org/zstack/ha/HaManagementNodeChecker.java" + }, + { + "raw": "the VM[uuid:%s] volume stored location primary storage is in a state of maintenance", + "en_US": "the VM[uuid:{0}] volume stored location primary storage is in a state of maintenance", + "zh_CN": "云主机[{0}]云盘所在主存储处于维护状态", + "arguments": [ + "vmUuid" + ], + "line": 1873, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "VM is started successfully", + "en_US": "VM is started successfully", + "zh_CN": "云主机已成功启动", + "arguments": [], + "line": 1615, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "Failed to start the NeverStop VM", + "en_US": "Failed to start the NeverStop VM", + "zh_CN": "无法启动NeverStop云主机", + "arguments": [], + "line": 1618, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "the value[%s] is lesser than 0 or greater than 1 ", + "en_US": "the value[{0}] is lesser than 0 or greater than 1 ", + "zh_CN": "值[{0}]小于0或大于1", + "arguments": [ + "newValue" + ], + "line": 394, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "A GC job is submitted to HA the VM[retry delay: %s seconds]", + "en_US": "A GC job is submitted to HA the VM[retry delay: {0} seconds]", + "zh_CN": "提交GC任务来高可用VM[重试间隔: {0} 秒]", + "arguments": [ + "HaGlobalConfig.NEVER_STOP_VM_FAILURE_RETRY_DELAY.value(Long.class)" + ], + "line": 699, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "HA is successfully completed", + "en_US": "HA is successfully completed", + "zh_CN": "HA已成功完成", + "arguments": [], + "line": 1301, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "Failed to HA the VM", + "en_US": "Failed to HA the VM", + "zh_CN": "高可用VM失败", + "arguments": [], + "line": 1309, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "vm stopped unexpectedly, double check state", + "en_US": "vm stopped unexpectedly, double check state", + "zh_CN": "VM意外停止,请再次检查状态", + "arguments": [], + "line": 1195, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "cannot determine VM[%s] status on host[%s], try to start it", + "en_US": "cannot determine VM[{0}] status on host[{1}], try to start it", + "zh_CN": "无法确定物理机[{1}]上的VM[{0}]状态,尝试启动虚拟机", + "arguments": [ + "vmUuid", + "hostUuid" + ], + "line": 1204, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "vm state is stopped, try to start it", + "en_US": "vm state is stopped, try to start it", + "zh_CN": "云主机状态为“已停止”,尝试启动虚拟机", + "arguments": [], + "line": 1601, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "VM[%s] is running on host[%s]", + "en_US": "VM[{0}] is running on host[{1}]", + "zh_CN": "VM[{0}]正在物理机[{1}]上运行", + "arguments": [ + "vmUuid", + "hostUuid" + ], + "line": 1227, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "VM[%s] is paused on host[%s]", + "en_US": "VM[{0}] is paused on host[{1}]", + "zh_CN": "物理机[{1}]上的云主机[{0}]已暂停", + "arguments": [ + "vmUuid", + "hostUuid" + ], + "line": 1240, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "the hypervisor[%s] does not support VM HA", + "en_US": "the hypervisor[{0}] does not support VM HA", + "zh_CN": "当前云主机监视器(hypervisor)[{0}]不支持VM HA", + "arguments": [ + "vm.getHypervisorType()" + ], + "line": 1268, + "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + }, + { + "raw": "the host[uuid:%s] is alive, no HA required. The host will be reconnected soon", + "en_US": "the host[uuid:{0}] is alive, no HA required. The host will be reconnected soon", + "zh_CN": "UUID为{0}的主机将被重连,其上的虚拟机暂时不触发高可用", + "arguments": [ + "hostUuid" + ], + "line": 89, + "fileName": "src/main/java/org/zstack/ha/HostCheckResult.java" + }, + { + "raw": "the host[uuid:%s] is dead. (%s) The vm on this host start HA", + "en_US": "the host[uuid:{0}] is dead. error is {1}. The vm on this host start HA", + "zh_CN": "UUID为{0}的主机短时间无法重连上,错误是{1}。现在上面的虚拟机触发高可用", + "arguments": [ + "hostUuid", + "errors" + ], + "line": 92, + "fileName": "src/main/java/org/zstack/ha/HostCheckResult.java" + }, + { + "raw": "VM state is not running, try to start it", + "en_US": "VM state is not running, try to start it", + "zh_CN": "云主机状态为未运行,尝试启动虚拟机", + "arguments": [], + "line": 102, + "fileName": "src/main/java/org/zstack/ha/NeverStopVmGC.java" + }, + { + "raw": "enter the new value here, empty means no change.", + "en_US": "enter the new value here, empty means no change.", + "zh_CN": "在此输入新值,空表示不变。", + "arguments": [], + "line": 14, + "fileName": "src/main/java/org/zstack/header/backup/NonBackupInfo.java" + }, + { + "raw": "keyType not supported type [%s]", + "en_US": "keyType not supported type [{0}]", + "zh_CN": "KeyType不支持类型[{0}]", + "arguments": [ + "type" + ], + "line": 44, + "fileName": "src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java" + }, + { + "raw": "key: [%s] with type: [%s] already existed by accountUuid: [%s]", + "en_US": "key: [{0}] with type: [{1}] already existed by accountUuid: [{2}]", + "zh_CN": "AccountUuId[{2}]已存在类型为[{1}]的项[{0}]", + "arguments": [ + "msg.getKey()", + "msg.getType()", + "accountUuid" + ], + "line": 60, + "fileName": "src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java" + }, + { + "raw": "key: [%s] already existed by accountUuid: [%s]", + "en_US": "key: [{0}] already existed by accountUuid: [{1}]", + "zh_CN": "key: [{0}]已经存在于accountUuid: [{1}]", + "arguments": [ + "msg.getKey()", + "accountUuid" + ], + "line": 84, + "fileName": "src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java" + }, + { + "raw": "regionId [%s] already created by ak [%s]", + "en_US": "regionId [{0}] already created by ak [{1}]", + "zh_CN": "区域ID[{0}]已经被AccessKey[{1}]创建", + "arguments": [ + "msg.getRegionId()", + "ak" + ], + "line": 63, + "fileName": "src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java" + }, + { + "raw": "dcType not supported type [%s]", + "en_US": "dcType not supported type [{0}]", + "zh_CN": "DCType不支持类型[{0}]", + "arguments": [ + "type" + ], + "line": 46, + "fileName": "src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java" + }, + { + "raw": "DataCenter [%s] is still in sync progress, please wait.", + "en_US": "DataCenter [{0}] is still in sync progress, please wait.", + "zh_CN": "区域[{0}]仍在同步进程中,请稍后", + "arguments": [ + "msg.getUuid()" + ], + "line": 96, + "fileName": "src/main/java/org/zstack/hybrid/datacenter/DataCenterManagerImpl.java" + }, + { + "raw": "identity zone [%s] already existed, uuid is: %s", + "en_US": "identity zone [{0}] already existed, uuid is: {1}", + "zh_CN": "可用区[{0}]已经存在,uuid是{1}", + "arguments": [ + "msg.getZoneId()", + "izo.getUuid()" + ], + "line": 55, + "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java" + }, + { + "raw": "type [%s] is not matched datacenter type [%s]", + "en_US": "type [{0}] is not matched datacenter type [{1}]", + "zh_CN": "类型[{0}]与区域类型[{1}]不匹配", + "arguments": [ + "type", + "dvo.getDcType().toString()" + ], + "line": 72, + "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java" + }, + { + "raw": "either dataCenterUuid or regionId should be set, please check the parameters.", + "en_US": "either dataCenterUuid or regionId should be set, please check the parameters.", + "zh_CN": "dataCenterUuid和regionId应该被设置,请检查参数", + "arguments": [], + "line": 82, + "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java" + }, + { + "raw": "IdentityZone [%s] is still in sync progress, please wait.", + "en_US": "IdentityZone [{0}] is still in sync progress, please wait.", + "zh_CN": "可用区[{0}]仍在同步进程中,请稍后", + "arguments": [ + "msg.getUuid()" + ], + "line": 111, + "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneManagerImpl.java" + }, + { + "raw": "EcsInstance must be running or stopped while deleting eip ", + "en_US": "EcsInstance must be running or stopped while deleting eip ", + "zh_CN": "删除弹性IP时云主机必须时允许中或者已停止", + "arguments": [], + "line": 88, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridEipCascadeExtension.java" + }, + { + "raw": "router interface must be in the same datacenter, but ri[%s] is in dc[%s] and ri[%s] is in dc[%s]", + "en_US": "router interface must be in the same datacenter, but ri[{0}] is in dc[{1}] and ri[{2}] is in dc[{3}]", + "zh_CN": "路由接口必须在相同的区域,但是接口[{0}]在区域[{1}]而接口[{2}]在区域[{3}]", + "arguments": [ + "vbri.getUuid()", + "vbri.getDataCenterUuid()", + "vrouteri.getUuid()", + "vrouteri.getDataCenterUuid()" + ], + "line": 83, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "router interface[%s] status is not idle, it is %s", + "en_US": "router interface[{0}] status is not idle, it is {1}", + "zh_CN": "路由接口[{0}]并非闲置状态,当前状态为{1}", + "arguments": [ + "vrouteri.getUuid()", + "vrouteri.getStatus()" + ], + "line": 93, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "router interface[%s] already has a connection, it is %s", + "en_US": "router interface[{0}] already has a connection, it is {1}", + "zh_CN": "路由接口[{0}]已经有链接{1}", + "arguments": [ + "vrouteri.getUuid()", + "vrouteri.getOppositeInterfaceUuid()" + ], + "line": 101, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "accessPointUuid cannot be null if the router interface on VBR type router", + "en_US": "accessPointUuid cannot be null if the router interface on VBR type router", + "zh_CN": "当路由接口的类型为VBR路由时,accessPointUuid不能为空", + "arguments": [], + "line": 109, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "cannot delete system entry", + "en_US": "cannot delete system entry", + "zh_CN": "不能删除系统路由条目", + "arguments": [], + "line": 183, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "only support intranet rule in vpc", + "en_US": "only support intranet rule in vpc", + "zh_CN": "在VPC中仅仅支持内网规则", + "arguments": [], + "line": 189, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "%s is not a valid cidr", + "en_US": "{0} is not a valid cidr", + "zh_CN": "{0}是一个无效的CIDR", + "arguments": [ + "msg.getCidr()" + ], + "line": 194, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "security group rule already existed", + "en_US": "security group rule already existed", + "zh_CN": "安全组已经存在了", + "arguments": [], + "line": 204, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "dstCidrBlock[%s] is not a valid cidr", + "en_US": "dstCidrBlock[{0}] is not a valid cidr", + "zh_CN": "dstCidrBlock[{0}]是一个无效的CIDR", + "arguments": [ + "msg.getDstCidrBlock()" + ], + "line": 210, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "next hop type [%s] not supported create route entry now!", + "en_US": "next hop type [{0}] not supported create route entry now!", + "zh_CN": "不支持下一个跃点类型[{0}],请立即创建路由条目!", + "arguments": [ + "msg.getNextHopType()" + ], + "line": 239, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "no such vpn gateway: %s", + "en_US": "no such vpn gateway: {0}", + "zh_CN": "没有这样的VPN网关: {0}", + "arguments": [ + "msg.getNextHopUuid()" + ], + "line": 235, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "nexthop routerInterface belongs to %s, but the entry belongs to %s", + "en_US": "nexthop routerInterface belongs to {0}, but the entry belongs to {1}", + "zh_CN": "下一跳路由接口类型是{0},但是该路由类型是{1}", + "arguments": [ + "rivo.getvRouterType().toString()", + "msg.getvRouterType()" + ], + "line": 224, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "no such ecs instance: %s", + "en_US": "no such ecs instance: {0}", + "zh_CN": "没有这样的ESC云主机: {0}", + "arguments": [ + "msg.getNextHopUuid()" + ], + "line": 217, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "virtual border router only support routerinterface as next hop type", + "en_US": "virtual border router only support routerinterface as next hop type", + "zh_CN": "作为下一跳类型,虚拟边界路由只支持路由接口", + "arguments": [], + "line": 249, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "vswitch\u0027s cidr [%s] not in the vpc\u0027s [%s]", + "en_US": "vswitch\u0027s cidr [{0}] not in the vpc\u0027s [{1}]", + "zh_CN": "虚拟交换机的CIDR没有在VPC[{1}]中", + "arguments": [ + "msg.getCidrBlock()", + "vpcCidr" + ], + "line": 269, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "cidr is overlap by another vswitch: %s", + "en_US": "cidr is overlap by another vswitch: {0}", + "zh_CN": "CIDR和其他的虚拟交换机{0}有重叠", + "arguments": [ + "old.getUuid()" + ], + "line": 276, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "invalid CidrBlock: %s, which must subnet in \u002710.0.0.0/8\u0027, \u0027172.16.0.0/12\u0027, \u0027192.168.0.0/16\u0027", + "en_US": "invalid CidrBlock: {0}, which must subnet in \u002710.0.0.0/8\u0027, \u0027172.16.0.0/12\u0027, \u0027192.168.0.0/16\u0027", + "zh_CN": "无效的CIDR块: {0},CIDR必须在10.0.0.0/8、172.16.0.0/12和192.168.0.0/16子网内", + "arguments": [ + "msg.getCidrBlock()" + ], + "line": 289, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "no such virtual router: %s", + "en_US": "no such virtual router: {0}", + "zh_CN": "没有这个的虚拟路由: {0}", + "arguments": [ + "msg.getvRouterUuid()" + ], + "line": 305, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "no such virtual border router: %s", + "en_US": "no such virtual border router: {0}", + "zh_CN": "没有这个虚拟边界路由器: {0}", + "arguments": [ + "msg.getvRouterUuid()" + ], + "line": 300, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "localGateway is not IPv4: %s", + "en_US": "localGateway is not IPv4: {0}", + "zh_CN": "本地网关地址不是IPV4: {0}", + "arguments": [ + "msg.getLocalGatewayIp()" + ], + "line": 312, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "peerGateway is not IPv4: %s", + "en_US": "peerGateway is not IPv4: {0}", + "zh_CN": "对端网关地址不是IPV4: {0}", + "arguments": [ + "msg.getPeerGatewayIp()" + ], + "line": 315, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "peerGateway is not subnet mask: %s", + "en_US": "peerGateway is not subnet mask: {0}", + "zh_CN": "对端网关地址不是在子网掩码{0}中", + "arguments": [ + "msg.getPeeringSubnetMask()" + ], + "line": 318, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "vlanId is not number: %s", + "en_US": "vlanId is not number: {0}", + "zh_CN": "vlanId不是一个数字:{0}", + "arguments": [ + "msg.getVlanId()" + ], + "line": 322, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "couldn\u0027t attach eip to ecs: [%s] , eip :[%s] already attached ecs:[%s] ", + "en_US": "couldn\u0027t attach eip to ecs: [{0}] , eip :[{1}] already attached ecs:[{2}] ", + "zh_CN": "不能绑定弹性IP到ECS云主机[{0}],弹性IP[{1}]已经绑定到ECS云主机[{2}]", + "arguments": [ + "msg.getEcsUuid()", + "msg.getEipUuid()", + "hevo.getAllocateResourceUuid()" + ], + "line": 332, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "ecs [%s] already has public ip now", + "en_US": "ecs [{0}] already has public ip now", + "zh_CN": "ECS云主机[{0}]已经拥有IP", + "arguments": [ + "msg.getEcsUuid()" + ], + "line": 337, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "couldn\u0027t attach eip [%s] to ecs: [%s] , ecs is already attached", + "en_US": "couldn\u0027t attach eip [{0}] to ecs: [{1}] , ecs is already attached", + "zh_CN": "不能绑定弹性IP[{0}]到ECS云主机[{1}],ECS云主机已经绑定了弹性IP", + "arguments": [ + "msg.getEipUuid()", + "msg.getEcsUuid()" + ], + "line": 343, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "eip[%s] and ecs[%s] should be in the same dataCenter ", + "en_US": "eip[{0}] and ecs[{1}] should be in the same dataCenter ", + "zh_CN": "弹性IP[{0}]和ECS云主机[{1}]应该在同一个区域", + "arguments": [ + "msg.getEipUuid()", + "msg.getEcsUuid()" + ], + "line": 350, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "couldn\u0027t detach eip :[%s], it is not attached on any instance ", + "en_US": "couldn\u0027t detach eip :[{0}], it is not attached on any instance ", + "zh_CN": "不能解绑弹性IP[{0}],因为它没有绑定任何云主机", + "arguments": [ + "msg.getEipUuid()" + ], + "line": 359, + "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + }, + { + "raw": "%s is not a valid ipv4 address", + "en_US": "{0} is not a valid ipv4 address", + "zh_CN": "{0}是一个无效的IPV4地址", + "arguments": [ + "msg.getId()" + ], + "line": 45, + "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + }, + { + "raw": "localCidr must be Cidr!", + "en_US": "localCidr must be Cidr!", + "zh_CN": "本地CIDR必须是CIDR", + "arguments": [], + "line": 51, + "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + }, + { + "raw": "remoteCidr must be Cidr!", + "en_US": "remoteCidr must be Cidr!", + "zh_CN": "远程CIDR必须是CIDR", + "arguments": [], + "line": 55, + "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + }, + { + "raw": "localCidr and remoteCidr must be Cidr!", + "en_US": "localCidr and remoteCidr must be Cidr!", + "zh_CN": "本地CIDR和远程CIDR必须是CIDR", + "arguments": [], + "line": 62, + "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + }, + { + "raw": "vpngateway [%s] existed, cannot delete remote", + "en_US": "vpngateway [{0}] existed, cannot delete remote", + "zh_CN": "VPN网关[{0}]已经存在,不能删除远程的", + "arguments": [ + "gateways.get(0).getUuid()" + ], + "line": 80, + "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnGatewayCascadeExtension.java" + }, + { + "raw": "The user[%s] is not a platform user", + "en_US": "The user[{0}] is not a platform user", + "zh_CN": "用户[{0}]不是平台用户", + "arguments": [ + "oldSession.getUserUuid()" + ], + "line": 343, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "There are %d problems with the file. ", + "en_US": "There are {0} problems with the file. ", + "zh_CN": "文件中包含{0}个错误", + "arguments": [ + "results.size()" + ], + "line": 994, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "fail to load VirtualID info from file. because\\n%s", + "en_US": "fail to load VirtualID info from file. because\\n{0}", + "zh_CN": "解析文件内容出错,{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 1011, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "name cannot be empty. ", + "en_US": "name cannot be empty. ", + "zh_CN": "名称不能为空", + "arguments": [], + "line": 1022, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "userName[%s] is repeated. ", + "en_US": "userName[{0}] is repeated. ", + "zh_CN": "用户名[{0}]重复", + "arguments": [ + "cmsg.getUsername()" + ], + "line": 1030, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "name exceeds max length of string. expected was \u003c\u003d 255, actual was %s. ", + "en_US": "name exceeds max length of string. expected was \u003c\u003d 255, actual was {0}. ", + "zh_CN": "名称字符数量不能超过255", + "arguments": [ + "cmsg.username.length()" + ], + "line": 1028, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "username cannot be empty. ", + "en_US": "username cannot be empty. ", + "zh_CN": "用户名不能为空", + "arguments": [], + "line": 1026, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "Incorrect password length. expected was \u003e\u003d 6 and \u003c\u003d 255, actual was %s. ", + "en_US": "Incorrect password length. expected was \u003e\u003d 6 and \u003c\u003d 255, actual was {0}. ", + "zh_CN": "密码长度错误,应该大于等于6个字符,小于等于255字符", + "arguments": [ + "cmsg.password.length()" + ], + "line": 1036, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "password cannot be empty. ", + "en_US": "password cannot be empty. ", + "zh_CN": "密码不能为空", + "arguments": [], + "line": 1034, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "email format does not match. ", + "en_US": "email format does not match. ", + "zh_CN": "邮箱格式错误", + "arguments": [], + "line": 1044, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "organization[%s] is not exist. ", + "en_US": "organization[{0}] is not exist. ", + "zh_CN": "部门[{0}]不存在", + "arguments": [ + "noMatchNames" + ], + "line": 1100, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "organization[%s] in line is repeated. ", + "en_US": "organization[{0}] in line is repeated. ", + "zh_CN": "部门[{0}]出现重复", + "arguments": [ + "repeatNames" + ], + "line": 1108, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "organization[%s] is repeated. ", + "en_US": "organization[{0}] is repeated. ", + "zh_CN": "部门[{0}]出现重复", + "arguments": [ + "repeatNames" + ], + "line": 1116, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "project[%s] is not exist. ", + "en_US": "project[{0}] is not exist. ", + "zh_CN": "项目[{0}]不存在", + "arguments": [ + "noMatchName" + ], + "line": 1146, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "fail to build VirtualID info from file. ", + "en_US": "fail to build VirtualID info from file. ", + "zh_CN": "不能解析文件内容", + "arguments": [], + "line": 1340, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "virtualID[uuid:%s] not in project[uuid:%s]", + "en_US": "virtualID[uuid:{0}] not in project[uuid:{1}]", + "zh_CN": "VirtualID[uuid:{0}]不在项目[uuid:{1}]中", + "arguments": [ + "resourceUuid", + "projectUuid" + ], + "line": 1469, + "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + }, + { + "raw": "Can not do operations, because current organization[uuid:%s] is staled, please enable it", + "en_US": "Can not do operations, because current organization[uuid:{0}] is staled, please enable it", + "zh_CN": "无法进行操作,因为当前组织[uuid:{0}]已过时,请启用该组织", + "arguments": [ + "self.getUuid()" + ], + "line": 144, + "fileName": "src/main/java/org/zstack/iam2/IAM2OrganizationBase.java" + }, + { + "raw": "organization[uuid:%s] is parent of the organization[uuid:%s], cannot set it as a child organization", + "en_US": "organization[uuid:{0}] is parent of the organization[uuid:{1}], cannot set it as a child organization", + "zh_CN": "部门[uuid:{0}]是部门[uuid:{1}]的上级部门,无法被设置为子部门", + "arguments": [ + "puuid", + "self.getUuid()" + ], + "line": 688, + "fileName": "src/main/java/org/zstack/iam2/IAM2OrganizationBase.java" + }, + { + "raw": "the project[uuid: %s, name:%s] is in state of %s which disallows the operation[%s]", + "en_US": "the project[uuid: {0}, name:{1}] is in state of {2} which disallows the operation[{3}]", + "zh_CN": "项目[[uuid: {0}, 名称:{1}]]是{2}状态,不允许执行[{3}]操作", + "arguments": [ + "self.getUuid()", + "self.getName()", + "self.getState()", + "msg.getClass()" + ], + "line": 130, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectBase.java" + }, + { + "raw": "can not parse the cron expression", + "en_US": "can not parse the cron expression", + "zh_CN": "无法分析Cron表达式", + "arguments": [], + "line": 910, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectBase.java" + }, + { + "raw": "project[name:%s] not existing", + "en_US": "project[name:{0}] not existing", + "zh_CN": "项目[name:{0}]不存在", + "arguments": [ + "loginContext.getUsername()" + ], + "line": 43, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java" + }, + { + "raw": "no account found for project[uuid:%s, name:%s]", + "en_US": "no account found for project[uuid:{0}, name:{1}]", + "zh_CN": "未找到项目[uuid:{0},名称:{1}]的帐户", + "arguments": [ + "puuid", + "loginContext.getUsername()" + ], + "line": 51, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java" + }, + { + "raw": "wrong virtual ID[uuid:%s], not existing or wrong password", + "en_US": "wrong virtual ID[uuid:{0}], not existing or wrong password", + "zh_CN": "错误的virtual ID[uuid:{0}], 密码不存在或者密码错误", + "arguments": [ + "loginContext.getOperatorSession().getUserUuid()" + ], + "line": 57, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java" + }, + { + "raw": "virtual ID[name:%s] is disabled", + "en_US": "virtual ID[name:{0}] is disabled", + "zh_CN": "virtual ID[名称:{0}]不可用", + "arguments": [ + "vid.getName()" + ], + "line": 62, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java" + }, + { + "raw": "virtual ID[name:%s] not belonging to the project[name:%s]", + "en_US": "virtual ID[name:{0}] not belonging to the project[name:{1}]", + "zh_CN": "virtual ID[名称:{0}]不属于项目[name:{1}]", + "arguments": [ + "vid.getName()", + "loginContext.getUsername()" + ], + "line": 72, + "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java" + }, + { + "raw": "the quota[name:%s] of Account[uuid:%s] can not be %d, otherwise it will exceeds the quota of organization[uuid:%s]", + "en_US": "the quota[name:{0}] of Account[uuid:{1}] can not be {2}, otherwise it will exceeds the quota of organization[uuid:{3}]", + "zh_CN": "帐户[uuid:{1}]的配额[名称:{0}]不能为{2},否则将超过组织[uuid:{3}]的配额", + "arguments": [ + "quota.getName()", + "quota.getIdentityUuid()", + "updatedValue", + "organizationUuid" + ], + "line": 75, + "fileName": "src/main/java/org/zstack/iam2/IAM2QuotaUpdateChecker.java" + }, + { + "raw": "Can not do operations, because Current virtualID[uuid:%s] is staled, please enable it", + "en_US": "Can not do operations, because Current virtualID[uuid:{0}] is staled, please enable it", + "zh_CN": "无法执行操作,因为当前VirtualID[uuid:{0}]已过时,请启用它", + "arguments": [ + "self.getUuid()" + ], + "line": 256, + "fileName": "src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java" + }, + { + "raw": "only admin and the virtual ID itself can do the update", + "en_US": "only admin and the virtual ID itself can do the update", + "zh_CN": "只有admin和virtual ID本身可以执行更新操作", + "arguments": [], + "line": 649, + "fileName": "src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java" + }, + { + "raw": "old password is not equal to the original password, cannot update the password of virtual ID[uuid:%s]", + "en_US": "old password is not equal to the original password, cannot update the password of virtual ID[uuid:{0}]", + "zh_CN": "旧密码不等于原始密码,无法更新虚拟ID[uuid:{0}]的密码", + "arguments": [ + "msg.getVirtualIDUuid()" + ], + "line": 653, + "fileName": "src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java" + }, + { + "raw": "attribute name cannot be null, value[%s]", + "en_US": "attribute name cannot be null, value[{0}]", + "zh_CN": "属性不能为null,输入值[{0}]", + "arguments": [ + "attr.getValue()" + ], + "line": 50, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute name[%s] exceed the max length of 2048 chars", + "en_US": "attribute name[{0}] exceed the max length of 2048 chars", + "zh_CN": "属性名称[{0}]不能超过2048个字符", + "arguments": [ + "attr.getName()" + ], + "line": 54, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute[name:%s] value[%s] exceed the max length of 2048 chars", + "en_US": "attribute[name:{0}] value[{1}] exceed the max length of 2048 chars", + "zh_CN": "属性[name:{0}] value[{1}]不能超过2048个字符", + "arguments": [ + "attr.getName()", + "attr.getValue()" + ], + "line": 57, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "The Organization[uuid: %s] used [name: %s, usedValue: %s] exceeds Request:%s.", + "en_US": "The Organization[uuid: {0}] used [name: {1}, usedValue: {2}] exceeds Request:{3}.", + "zh_CN": "组织[uuid:{0}]使用的[名称:{1},UsedValue:{2}]超出请求:{3}。", + "arguments": [ + "msg.getOrganizationUuid()", + "msg.getName()", + "projectUsed", + "msg.getValue()" + ], + "line": 173, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "%s is not a valid value. Valid values are allow/rejection xxx to xxx", + "en_US": "{0} is not a valid value. Valid values are allow/rejection xxx to xxx", + "zh_CN": "{0}不是有效值。有效值为允许/拒绝XXX至XXX", + "arguments": [ + "msg.getLoginExpired()" + ], + "line": 186, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "The default organization[%s] cannot be deleted", + "en_US": "The default organization[{0}] cannot be deleted", + "zh_CN": "无法删除默认组织[{0}]", + "arguments": [ + "msg.getUuid()" + ], + "line": 192, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "duplicate template name[%s]", + "en_US": "duplicate template name[{0}]", + "zh_CN": "重复的模板名称[{0}]", + "arguments": [ + "msg.getName()" + ], + "line": 201, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "illegal operation, cannot add Role[%s]", + "en_US": "illegal operation, cannot add Role[{0}]", + "zh_CN": "非法操作,无法添加角色[{0}]", + "arguments": [ + "IAM2RolePolicyStatementHelper.PROJECT_ADMIN_ROLE_NAME" + ], + "line": 652, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "admin is a reserved name, please use another name", + "en_US": "admin is a reserved name, please use another name", + "zh_CN": "admin是保留名称,请使用其他名称", + "arguments": [], + "line": 265, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "invalid name[%s], there has been a project or account with the same name", + "en_US": "invalid name[{0}], there has been a project or account with the same name", + "zh_CN": "无效的名称[{0}],已经存在同名的项目或账户", + "arguments": [ + "msg.getName()" + ], + "line": 273, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute[uuid:%s] is not for any group", + "en_US": "attribute[uuid:{0}] is not for any group", + "zh_CN": "属性[uuid:{0}]不适用于任何组", + "arguments": [ + "msg.getUuid()" + ], + "line": 281, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute[uuid:%s] is not for any organization", + "en_US": "attribute[uuid:{0}] is not for any organization", + "zh_CN": "属性[uuid:{0}]不适用于任何组织", + "arguments": [ + "msg.getUuid()" + ], + "line": 289, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute[uuid:%s] is not for any project", + "en_US": "attribute[uuid:{0}] is not for any project", + "zh_CN": "属性[uuid:{0}]不适用于任何项目", + "arguments": [ + "msg.getUuid()" + ], + "line": 297, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute[uuid:%s] is not for any virtual ID", + "en_US": "attribute[uuid:{0}] is not for any virtual ID", + "zh_CN": "属性[uuid:{0}]不适用于任何虚拟ID", + "arguments": [ + "msg.getUuid()" + ], + "line": 305, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "retire policy must be deleted before pull the project out of Retired state", + "en_US": "retire policy must be deleted before pull the project out of Retired state", + "zh_CN": "在将项目从已停用状态拉出之前,必须删除停用策略", + "arguments": [], + "line": 325, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "login is prohibited because the project is in state of %s", + "en_US": "login is prohibited because the project is in state of {0}", + "zh_CN": "禁止登录,因为项目处于{0}状态", + "arguments": [ + "state" + ], + "line": 337, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "no quota[name:%s] found", + "en_US": "no quota[name:{0}] found", + "zh_CN": "未找到配额[名称:{0}]", + "arguments": [ + "name" + ], + "line": 347, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "organization[uuid:%s] is a Company that cannot have parent organization", + "en_US": "organization[uuid:{0}] is a Company that cannot have parent organization", + "zh_CN": "组织[uuid:{0}]是不能有上级组织的公司", + "arguments": [ + "msg.getUuid()" + ], + "line": 371, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "parent organization[uuid:%s] cannot be a child organization[uuid:%s] of a childOrganization", + "en_US": "parent organization[uuid:{0}] cannot be a child organization[uuid:{1}] of a childOrganization", + "zh_CN": "父组织[uuid:{0}]不能是子组织[uuid:{1}]的子组织", + "arguments": [ + "msg.getUuid()", + "msg.getParentUuid()" + ], + "line": 381, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "duplicate virtualID name[%s]", + "en_US": "duplicate virtualID name[{0}]", + "zh_CN": "重复的用户名[{0}]", + "arguments": [ + "msg.getName()" + ], + "line": 400, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "duplicate project name[%s]", + "en_US": "duplicate project name[{0}]", + "zh_CN": "重复的项目名[{0}]", + "arguments": [ + "msg.getName()" + ], + "line": 418, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "invalid project name[%s], an account or project with the same name exists", + "en_US": "invalid project name[{0}], an account or project with the same name exists", + "zh_CN": "无效的项目名[{0}],已有账户或项目使用了相同的名称", + "arguments": [ + "msg.getName()" + ], + "line": 426, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "IAM2OrganizationVO[uuid:%s] is not exists", + "en_US": "IAM2OrganizationVO[uuid:{0}] is not exists", + "zh_CN": "Iam2OrganizationVO[uuid:{0}]不存在", + "arguments": [ + "msg.getOrganizationUuid()" + ], + "line": 432, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "The project[uuid\u003d%s] has been attached to the organization[uuid\u003d%s]", + "en_US": "The project[uuid\u003d{0}] has been attached to the organization[uuid\u003d{1}]", + "zh_CN": "项目[uuid\u003d{0}]已附加到组织[uuid\u003d{1}]", + "arguments": [ + "refVO.getProjectUuid()", + "refVO.getOrganizationUuid()" + ], + "line": 515, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "The project[uuid\u003d%s] is not attached", + "en_US": "The project[uuid\u003d{0}] is not attached", + "zh_CN": "未附加项目[uuid\u003d{0}]", + "arguments": [ + "msg.getProjectUuid()" + ], + "line": 557, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "organizations%s are company that cannot be children of other organization", + "en_US": "organizations{0} are company that cannot be children of other organization", + "zh_CN": "组织{0}类型是子公司,不能设置为其它组织的部门", + "arguments": [ + "uuids" + ], + "line": 568, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "virtual id[uuid: %s] is not in project[uuid: %s]", + "en_US": "virtual id[uuid: {0}] is not in project[uuid: {1}]", + "zh_CN": "虚拟ID[uuid:{0}]不在项目[uuid:{1}]中", + "arguments": [ + "msg.getVirtualIDUuid()", + "msg.getProjectUuid()" + ], + "line": 582, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "can not operate stale virtual ids: %s", + "en_US": "can not operate stale virtual ids: {0}", + "zh_CN": "无法操作无效的用户: {0}", + "arguments": [ + "staleVirtualIDs" + ], + "line": 679, + "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + }, + { + "raw": "attribute[name:%s] is a system attribute that cannot be updated", + "en_US": "attribute[name:{0}] is a system attribute that cannot be updated", + "zh_CN": "属性[名称:{0}]是一个系统属性,无法被更新", + "arguments": [], + "line": 69, + "fileName": "src/main/java/org/zstack/iam2/attribute/SystemAttributes.java" + }, + { + "raw": "virtual ID[uuid:%s] not existing", + "en_US": "virtual ID[uuid:{0}] not existing", + "zh_CN": "用户[uuid:{0}]不存在", + "arguments": [ + "inv.getValue()" + ], + "line": 38, + "fileName": "src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java" + }, + { + "raw": "virtual ID[uuid:%s] not in organization[uuid:%s]", + "en_US": "virtual ID[uuid:{0}] not in organization[uuid:{1}]", + "zh_CN": "虚拟ID[uuid:{0}]不在组织中[uuid:{1}]", + "arguments": [ + "inv.getValue()", + "((IAM2OrganizationAttributeInventory) inv).getOrganizationUuid()" + ], + "line": 45, + "fileName": "src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java" + }, + { + "raw": "organization[uuid:%s] already has a supervisor", + "en_US": "organization[uuid:{0}] already has a supervisor", + "zh_CN": "组织[uuid:{0}]已经设置了负责人", + "arguments": [ + "oinv.getOrganizationUuid()" + ], + "line": 50, + "fileName": "src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java" + }, + { + "raw": "the project[uuid:%s, name:%s] already has a login expired strategy", + "en_US": "the project[uuid:{0}, name:{1}] already has a login expired strategy", + "zh_CN": "项目[uuid:{0},名称:{1}]已有登录过期策略", + "arguments": [ + "pinv.getUuid()", + "pinv.getName()" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/LoginExpired.java" + }, + { + "raw": "IAM2ProjectVO[uuid:%s] is not %s, state change is not allowed", + "en_US": "IAM2ProjectVO[uuid:{0}] is not {1}, state change is not allowed", + "zh_CN": "Iam2ProjectVO[uuid:{0}]不是{1},不允许更改状态", + "arguments": [ + "projectUuid", + "ProjectState.Enabled.toString()" + ], + "line": 109, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/LoginExpired.java" + }, + { + "raw": "the project[uuid:%s, name:%s] already has a retire policy", + "en_US": "the project[uuid:{0}, name:{1}] already has a retire policy", + "zh_CN": "项目[uuid:{0}, name:{1}]已经设置了回收策略", + "arguments": [ + "pinv.getUuid()", + "pinv.getName()" + ], + "line": 65, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/Retire.java" + }, + { + "raw": "invalid value, no \u0027at\u0027, \u0027after\u0027 or \u0027exceed\u0027 found", + "en_US": "invalid value, no \u0027at\u0027, \u0027after\u0027 or \u0027exceed\u0027 found", + "zh_CN": "无效的值,找不到关键字no \u0027at\u0027, \u0027after\u0027 or \u0027exceed\u0027", + "arguments": [], + "line": 53, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid value, %s", + "en_US": "invalid value, {0}", + "zh_CN": "无效的值, {0}", + "arguments": [ + "value" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid means[%s], allowed means are %s", + "en_US": "invalid means[{0}], allowed means are {1}", + "zh_CN": "无效的回收方法[{0}],允许的方法是{1}", + "arguments": [ + "ss[0]", + "Arrays.asList(Means.values()).toString()" + ], + "line": 64, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid spending value[%s], it should be in format of for example 10.001", + "en_US": "invalid spending value[{0}], it should be in format of for example 10.001", + "zh_CN": "无效的费用[{0}], 费用格式应该符合例如:10.001", + "arguments": [ + "policyValue" + ], + "line": 100, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid spending value[%s], spending value should between 0 and %f", + "en_US": "invalid spending value[{0}], spending value should between 0 and {1}", + "zh_CN": "无效的费用[{0}], 费用范围应该在0到{1}之间", + "arguments": [ + "policyValue", + "Double.MAX_VALUE" + ], + "line": 94, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid time[%s], it should be in format of for example 10m, 1h, 2d", + "en_US": "invalid time[{0}], it should be in format of for example 10m, 1h, 2d", + "zh_CN": "无效的时间[{0}],时间格式需要符合例如:10m, 1h, 2d", + "arguments": [ + "policyValue" + ], + "line": 87, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid date[%s], it should be in format of yyyy-MM-dd HH:mm:ss", + "en_US": "invalid date[{0}], it should be in format of yyyy-MM-dd HH:mm:ss", + "zh_CN": "无效的日期,日期格式需要符合:yyyy-MM-dd HH:mm:ss", + "arguments": [ + "policyValue" + ], + "line": 78, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "invalid date or time[%s], it cannot be before current time[%s]", + "en_US": "invalid date or time[{0}], it cannot be before current time[{1}]", + "zh_CN": "无效的日期或时间,回收时间不能在当前时间之前[{1}]", + "arguments": [ + "policyValue", + "dateFormat.format(new Timestamp(System.currentTimeMillis()))" + ], + "line": 107, + "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + }, + { + "raw": "virtual ID[uuid:%s] already has admin related attributes, can not add %s", + "en_US": "virtual ID[uuid:{0}] already has admin related attributes, can not add {1}", + "zh_CN": "用户[uuid:{0}]已经有管理员属性了,无法继续添加属性{1}", + "arguments": [ + "vid", + "attributeName" + ], + "line": 17, + "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/AbstractAdminAttribute.java" + }, + { + "raw": "organiztion ID[uuid:%s] already has opoeration attributes, can not add %s", + "en_US": "organiztion ID[uuid:{0}] already has opoeration attributes, can not add {1}", + "zh_CN": "组织ID[uuid:{0}]已具有Poeration属性,无法添加{1}", + "arguments": [ + "inv.getValue()", + "IAM2_ORGANIZATION_OPERATION.getName()" + ], + "line": 29, + "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/IAM2OrganizationOperator.java" + }, + { + "raw": "virtual id[uuid:%s] already has a project operator attribute", + "en_US": "virtual id[uuid:{0}] already has a project operator attribute", + "zh_CN": "虚拟ID[uuid:{0}]已具有项目运算符属性", + "arguments": [ + "idinv.getVirtualIDUuid()" + ], + "line": 35, + "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/IAM2ProjectOperator.java" + }, + { + "raw": "cannot find zone[uuid:%s]", + "en_US": "cannot find zone[uuid:{0}]", + "zh_CN": "找不到区域[uuid:{0}]", + "arguments": [ + "inv.getValue()" + ], + "line": 36, + "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/PlatformAdminZoneRelation.java" + }, + { + "raw": "project[uuid:%s] already has a project admin", + "en_US": "project[uuid:{0}] already has a project admin", + "zh_CN": "项目[uuid:{0}]已经设置过项目管理员了", + "arguments": [ + "inv.getValue()" + ], + "line": 71, + "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java" + }, + { + "raw": "project[uuid:%s] not existing", + "en_US": "project[uuid:{0}] not existing", + "zh_CN": "项目[uuid:{0}]不存在", + "arguments": [ + "inv.getValue()" + ], + "line": 83, + "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java" + }, + { + "raw": "the operations[%s] is denied", + "en_US": "the operations[{0}] is denied", + "zh_CN": "操作[{0}]被拒绝", + "arguments": [ + "deniedApis" + ], + "line": 133, + "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2AuthorizationBackend.java" + }, + { + "raw": "since the project starts the force securityGroup, systemtag is required for VM operation", + "en_US": "since the project starts the force securityGroup, systemtag is required for VM operation", + "zh_CN": "由于项目启动了Force SecurityGroup,因此VM操作需要SystemTag", + "arguments": [], + "line": 114, + "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2OperationTargetAPIRequestChecker.java" + }, + { + "raw": "project of account[uuid:%s] not exists", + "en_US": "project of account[uuid:{0}] not exists", + "zh_CN": "账户为[uuid:{0}]的项目不存在", + "arguments": [ + "session.getAccountUuid()" + ], + "line": 28, + "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java" + }, + { + "raw": "project[uuid:%s] is retired, reject all operations", + "en_US": "project[uuid:{0}] is retired, reject all operations", + "zh_CN": "项目[uuid:{0}]已经过期,无法操作", + "arguments": [ + "projectUuid" + ], + "line": 37, + "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java" + }, + { + "raw": "system tag requested. need specify default security group for vm nic by system tag L3_NETWORK_SECURITY_GROUP_uuidS_REF with format l3::{%s}::SecurityGroupUuids::{%s}, because force security group is enabled", + "en_US": "system tag requested. need specify default security group for vm nic by system tag L3_NETWORK_SECURITY_GROUP_uuidS_REF with format l3::{{0}}::SecurityGroupUuids::{{1}}, because force security group is enabled", + "zh_CN": "已请求系统标记。需要按系统标记L为VM NIC指定默认安全组3_网络_安全_组_uuid_引用,格式为L3:{0}:SecurityGroupUUIds:{1},因为启用了强制安全组", + "arguments": [], + "line": 107, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "the l3Uuid[%s] in the label is inconsistent with the l3Uuid[%s] in the parameter", + "en_US": "the l3Uuid[{0}] in the label is inconsistent with the l3Uuid[{1}] in the parameter", + "zh_CN": "标签中的L3uuid[{0}]与参数中的L3uuid[{1}]不一致", + "arguments": [ + "l3Uuid", + "msg.getL3NetworkUuid()" + ], + "line": 114, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "since force security group is enabled, securityGroupUuid in the tag must be in the project[%s]", + "en_US": "since force security group is enabled, securityGroupUuid in the tag must be in the project[{0}]", + "zh_CN": "由于启用了强制安全组,因此标记中的SecurityGroupuuid必须在项目[{0}]中", + "arguments": [ + "projectUuid" + ], + "line": 124, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "nics on the l3Network[uuid:%s] are attached to the securityGroup. before you can detach the l3Network from the securityGroup, you need to detach the nics from the securityGroup.", + "en_US": "nics on the l3Network[uuid:{0}] are attached to the securityGroup. before you can detach the l3Network from the securityGroup, you need to detach the nics from the securityGroup.", + "zh_CN": "三层网络[uuid:{0}]上的NIC已连接到SecurityGroup。在将L3Network与SecurityGroup分离之前,需要将NIC与SecurityGroup分离。", + "arguments": [ + "msg.getL3NetworkUuid()", + "msg.getSecurityGroupUuid()" + ], + "line": 145, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "the default security group %s cannot be deleted by enabling the enforced security group function", + "en_US": "the default security group {0} cannot be deleted by enabling the enforced security group function", + "zh_CN": "无法通过启用强制安全组功能来删除默认安全组{0}", + "arguments": [ + "msg.getUuid()" + ], + "line": 161, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "this security group %s is bound to vm, please try again after unbinding", + "en_US": "this security group {0} is bound to vm, please try again after unbinding", + "zh_CN": "此安全组{0}已绑定到VM,请在解除绑定后重试", + "arguments": [ + "msg.getUuid()" + ], + "line": 165, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "account[%s] cannot operation the default securityGroup[%s]", + "en_US": "account[{0}] cannot operation the default securityGroup[{1}]", + "zh_CN": "帐户[{0}]无法操作默认SecurityGroup[{1}]", + "arguments": [ + "sessionInventory.getAccountUuid()", + "securityGroupUuid" + ], + "line": 175, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "account[%s] not allowed to operate on default securityGroup", + "en_US": "account[{0}] not allowed to operate on default securityGroup", + "zh_CN": "不允许帐户[{0}]对默认的SecurityGroup进行操作", + "arguments": [ + "msg.getSession().getAccountUuid()" + ], + "line": 187, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "vm\u0027s nic[uuid:%s] only has one security group, can not delete the nic from security group[uuid:%s]", + "en_US": "vm\u0027s nic[uuid:{0}] only has one security group, can not delete the nic from security group[uuid:{1}]", + "zh_CN": "VM的NIC[uuid:{0}]只有一个安全组,无法从安全组[uuid:{1}]中删除NIC", + "arguments": [ + "refVOS.stream().map(VmNicSecurityGroupRefVO::getVmNicUuid).collect(Collectors.joining(\",\"))", + "msg.getSecurityGroupUuid()" + ], + "line": 241, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java" + }, + { + "raw": "can\u0027t find the quota for the security group for the corresponding project %s", + "en_US": "can\u0027t find the quota for the security group for the corresponding project {0}", + "zh_CN": "找不到对应项目{0}的安全组的配额", + "arguments": [ + "projectUuid" + ], + "line": 60, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupFactory.java" + }, + { + "raw": "security group quota cannot less than 1", + "en_US": "security group quota cannot less than 1", + "zh_CN": "安全组配额不能小于1", + "arguments": [], + "line": 64, + "fileName": "src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupFactory.java" + }, + { + "raw": "The iam2 script function is not enabled.", + "en_US": "The iam2 script function is not enabled.", + "zh_CN": "未启用IAM2脚本函数。", + "arguments": [], + "line": 35, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java" + }, + { + "raw": "Script doesn\u0027t have any content.", + "en_US": "Script doesn\u0027t have any content.", + "zh_CN": "脚本没有任何内容。", + "arguments": [], + "line": 39, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java" + }, + { + "raw": "The amount of params exceeds the limit.", + "en_US": "The amount of params exceeds the limit.", + "zh_CN": "参数数量超过限制。", + "arguments": [], + "line": 45, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java" + }, + { + "raw": "Specified script executor are not supported.", + "en_US": "Specified script executor are not supported.", + "zh_CN": "不支持指定的脚本执行程序。", + "arguments": [], + "line": 61, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java" + }, + { + "raw": "Decode script content failed.", + "en_US": "Decode script content failed.", + "zh_CN": "解码脚本内容失败。", + "arguments": [], + "line": 139, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java" + }, + { + "raw": "Script content is blank.", + "en_US": "Script content is blank.", + "zh_CN": "脚本内容为空。", + "arguments": [], + "line": 147, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java" + }, + { + "raw": "Run iam2 script failed.", + "en_US": "Run iam2 script failed.", + "zh_CN": "运行IAM2脚本失败。", + "arguments": [], + "line": 179, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java" + }, + { + "raw": "Cannot read the result of the script running.", + "en_US": "Cannot read the result of the script running.", + "zh_CN": "无法读取脚本运行的结果。", + "arguments": [], + "line": 244, + "fileName": "src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java" + }, + { + "raw": "the user group[uuid:%s] does not belong to the account[uuid:%s]", + "en_US": "the user group[uuid:{0}] does not belong to the account[uuid:{1}]", + "zh_CN": "这个用户组[uuid:{0}]不属于当前账户[uuid:{1}]", + "arguments": [ + "group.getUuid()", + "msg.getAccountUuid()" + ], + "line": 327, + "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + }, + { + "raw": "the account[uuid: %s] doesn\u0027t have a resource[uuid: %s]", + "en_US": "the account[uuid: {0}] doesn\u0027t have a resource[uuid: {1}]", + "zh_CN": "账户[uuid: {0}]没有资源[uuid: {1}]", + "arguments": [ + "self.getUuid()", + "ruuid" + ], + "line": 528, + "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + }, + { + "raw": "the user[uuid:%s] does not belong to the account[uuid:%s]", + "en_US": "the user[uuid:{0}] does not belong to the account[uuid:{1}]", + "zh_CN": "当前用户[uuid:{0}]不属于当前账户[uuid:{1}]", + "arguments": [ + "user.getUuid()", + "msg.getAccountUuid()" + ], + "line": 590, + "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + }, + { + "raw": "old password is not equal to the original password, cannot update the password of user[uuid:%s]", + "en_US": "old password is not equal to the original password, cannot update the password of user[uuid:{0}]", + "zh_CN": "旧密码不等于原始密码,无法更新用户[uuid:{0}]的密码", + "arguments": [ + "user.getUuid()" + ], + "line": 595, + "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + }, + { + "raw": "wrong password", + "en_US": "wrong password", + "zh_CN": "密码错误", + "arguments": [], + "line": 55, + "fileName": "src/main/java/org/zstack/identity/AccountInterceptor.java" + }, + { + "raw": "a statement must have effect field. Invalid statement[%s]", + "en_US": "a statement must have effect field. Invalid statement[{0}]", + "zh_CN": "声明必须含有\u0027effect\u0027字段。 无效的声明", + "arguments": [ + "JSONObjectUtil.toJsonString(s)" + ], + "line": 1660, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "a statement must have action field. Invalid statement[%s]", + "en_US": "a statement must have action field. Invalid statement[{0}]", + "zh_CN": "声明必须含有\u0027action\u0027字段。 无效的声明", + "arguments": [ + "JSONObjectUtil.toJsonString(s)" + ], + "line": 1663, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "a statement must have a non-empty action field. Invalid statement[%s]", + "en_US": "a statement must have a non-empty action field. Invalid statement[{0}]", + "zh_CN": "声明必须含有不为空的\u0027action\u0027字段。 无效的声明", + "arguments": [ + "JSONObjectUtil.toJsonString(s)" + ], + "line": 1666, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "cannot find the resource[uuid:%s]; wrong resourceUuid or the resource is admin resource", + "en_US": "cannot find the resource[uuid:{0}]; wrong resourceUuid or the resource is admin resource", + "zh_CN": "无法找到资源[uuid:{0}]: 错误的资源uuid或者资源是管理员资源", + "arguments": [ + "resourceUuid" + ], + "line": 175, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "the user specified by the userUuid[%s] does not belong to the current account, and the current account is not an admin account, so it has no permission to check the user\u0027spermissions", + "en_US": "the user specified by the userUuid[{0}] does not belong to the current account, and the current account is not an admin account, so it has no permission to check the user\u0027spermissions", + "zh_CN": "当前通过userUuid获得的user不属于当前账户,而且当前账户不是管理员账户", + "arguments": [ + "msg.getUserUuid()" + ], + "line": 405, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "cannot find the account[uuid:%s]", + "en_US": "cannot find the account[uuid:{0}]", + "zh_CN": "找不到账户[uuid:{0}]", + "arguments": [ + "accountUuid" + ], + "line": 1055, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "accountName and accountUuid cannot both be null, you must specify at least one", + "en_US": "accountName and accountUuid cannot both be null, you must specify at least one", + "zh_CN": "accountName和accountUuid不能同时为空,您必须定义至少一个", + "arguments": [], + "line": 1495, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "unable to create a group. A group called %s is already under the account[uuid:%s]", + "en_US": "unable to create a group. A group called {0} is already under the account[uuid:{1}]", + "zh_CN": "不能创建用户组,用户组“{0}”已经在账户“{0}”下了", + "arguments": [ + "msg.getName()", + "msg.getAccountUuid()" + ], + "line": 1506, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "unable to create a user. A user called %s is already under the account[uuid:%s]", + "en_US": "unable to create a user. A user called {0} is already under the account[uuid:{1}]", + "zh_CN": "不能创建用户,用户“{0}”已经在账户“{0}”下了", + "arguments": [ + "msg.getName()", + "msg.getAccountUuid()" + ], + "line": 1516, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "unable to create an account. An account already called %s", + "en_US": "unable to create an account. An account already called {0}", + "zh_CN": "不能创建账户,“{0}”已经被使用", + "arguments": [ + "msg.getName()" + ], + "line": 1525, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "account cannot delete itself", + "en_US": "account cannot delete itself", + "zh_CN": "账户不能删除自己", + "arguments": [], + "line": 1532, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "cannot delete builtin admin account.", + "en_US": "cannot delete builtin admin account.", + "zh_CN": "无法删除内置管理员帐户。", + "arguments": [], + "line": 1538, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "Only admin can delete account.", + "en_US": "Only admin can delete account.", + "zh_CN": "只有admin能删除账户", + "arguments": [], + "line": 1544, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "the current session is an account session. You need to specify the field \u0027uuid\u0027 of the user you want to update", + "en_US": "the current session is an account session. You need to specify the field \u0027uuid\u0027 of the user you want to update", + "zh_CN": "当前会话是一个账户会话,你需要定义一个\u0027uuid\u0027字段来指定你要更新的用户", + "arguments": [], + "line": 1552, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "your are login as a user, you cannot another user[uuid:%s]", + "en_US": "your are login as a user, you cannot another user[uuid:{0}]", + "zh_CN": "你已经登录为一个用户,不能成为另一个用户[uuid:{0}]", + "arguments": [ + "msg.getUuid()" + ], + "line": 1567, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "all is set to false, accountUuids cannot be null or empty", + "en_US": "all is set to false, accountUuids cannot be null or empty", + "zh_CN": "all参数被设为false时,账户uuid不能为空", + "arguments": [], + "line": 1575, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "toPublic is set to false, accountUuids cannot be null or empty", + "en_US": "toPublic is set to false, accountUuids cannot be null or empty", + "zh_CN": "toPublic参数被设为false时,账户uuid不能为空", + "arguments": [], + "line": 1583, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "policy[name: %s, uuid: %s] doesn\u0027t belong to the account[uuid: %s]", + "en_US": "policy[name: {0}, uuid: {1}] doesn\u0027t belong to the account[uuid: {2}]", + "zh_CN": "策略[名称: {0}, uuid: {1}]不属于账户[uuid: {2}]", + "arguments": [ + "policy.getName()", + "policy.getUuid()", + "msg.getSession().getAccountUuid()" + ], + "line": 1632, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "user[name: %s, uuid: %s] doesn\u0027t belong to the account[uuid: %s]", + "en_US": "user[name: {0}, uuid: {1}] doesn\u0027t belong to the account[uuid: {2}]", + "zh_CN": "用户[名称: {0}, uuid: {1}]不属于账户[uuid: {2}]", + "arguments": [ + "user.getName()", + "user.getUuid()", + "msg.getSession().getAccountUuid()" + ], + "line": 1646, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "group[name: %s, uuid: %s] doesn\u0027t belong to the account[uuid: %s]", + "en_US": "group[name: {0}, uuid: {1}] doesn\u0027t belong to the account[uuid: {2}]", + "zh_CN": "用户组[名称: {0}, uuid: {1}]不属于账户[uuid: {2}]", + "arguments": [ + "group.getName()", + "group.getUuid()", + "msg.getSession().getAccountUuid()" + ], + "line": 1650, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "unable to update name. An account already called %s", + "en_US": "unable to update name. An account already called {0}", + "zh_CN": "无法更新名称。已有一个名为{0}的帐户", + "arguments": [ + "msg.getName()" + ], + "line": 1691, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "old password is not equal to the original password, cannot update the password of account[uuid: %s]", + "en_US": "old password is not equal to the original password, cannot update the password of account[uuid: {0}]", + "zh_CN": "旧密码不等于原始密码,无法更新帐户[uuid:{0}]的密码", + "arguments": [ + "msg.getUuid()" + ], + "line": 1702, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "the name of admin account cannot be updated", + "en_US": "the name of admin account cannot be updated", + "zh_CN": "不能更改管理员账户名称", + "arguments": [], + "line": 1707, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "only admin account can update it\u0027s password", + "en_US": "only admin account can update it\u0027s password", + "zh_CN": "只有管理员帐户才能更新其密码", + "arguments": [], + "line": 1713, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "account[uuid: %s, name: %s] is a normal account, it cannot reset the password of another account[uuid: %s]", + "en_US": "account[uuid: {0}, name: {1}] is a normal account, it cannot reset the password of another account[uuid: {2}]", + "zh_CN": "[uuid: {0}, 名称: {1}]是一个普通账户,不能被其他普通账户重设密码", + "arguments": [ + "account.getUuid()", + "account.getName()", + "msg.getUuid()" + ], + "line": 1720, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "cannot find Quota[name: %s] for the account[uuid: %s]", + "en_US": "cannot find Quota[name: {0}] for the account[uuid: {1}]", + "zh_CN": "无法为当前账户[uuid: {1}]找到Quota", + "arguments": [ + "msg.getName()", + "msg.getIdentityUuid()" + ], + "line": 1731, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "can not find quota update checker for quota[uuid:%s, type:%s]", + "en_US": "can not find quota update checker for quota[uuid:{0}, type:{1}]", + "zh_CN": "找不到配额[uuid:{0},类型:{1}]的配额更新检查器", + "arguments": [ + "quota.getIdentityUuid()", + "quota.getIdentityType()" + ], + "line": 1738, + "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + }, + { + "raw": "the quota[name:%s] of account[uuid:%s] can not be %d", + "en_US": "the quota[name:{0}] of account[uuid:{1}] can not be {2}", + "zh_CN": "帐户[uuid:{1}]的配额[名称:{0}]不能为{2}", + "arguments": [ + "quota.getName()", + "quota.getIdentityUuid()", + "updatedValue" + ], + "line": 32, + "fileName": "src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java" + }, + { + "raw": "the account[uuid:%s] used [name:%s, usedValue:%s] exceeds request quota: %d", + "en_US": "the account[uuid:{0}] used [name:{1}, usedValue:{2}] exceeds request quota: {3}", + "zh_CN": "帐户[uuid:{0}]使用的[名称:{1},UsedValue:{2}]超过了请求配额:{3}", + "arguments": [ + "accountUuid", + "quotaName", + "used", + "updatedValue" + ], + "line": 54, + "fileName": "src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java" + }, + { + "raw": "unsupported login type %s", + "en_US": "unsupported login type {0}", + "zh_CN": "不支持的登录类型{0}", + "arguments": [ + "loginType" + ], + "line": 46, + "fileName": "src/main/java/org/zstack/identity/login/LoginManagerImpl.java" + }, + { + "raw": "permission denied, the account[uuid:%s] is not the owner of the resource[uuid:%s, type:%s]", + "en_US": "permission denied, the account[uuid:{0}] is not the owner of the resource[uuid:{1}, type:{2}]", + "zh_CN": "操作错误,账户[uuid:{0}]不是资源[uuid:{1}, type:{2}]的所有者", + "arguments": [ + "rbacEntity.getApiMessage().getSession().getAccountUuid()", + "uuid", + "resourceType.getSimpleName()" + ], + "line": 180, + "fileName": "src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java" + }, + { + "raw": "permission denied, the account[uuid:%s] is not the owner of the tagged resource[uuid:%s, type:%s]", + "en_US": "permission denied, the account[uuid:{0}] is not the owner of the tagged resource[uuid:{1}, type:{2}]", + "zh_CN": "权限被拒绝,帐户[uuid:{0}]不是已标记资源[uuid:{1},类型:{2}]的所有者", + "arguments": [ + "rbacEntity.getApiMessage().getSession().getAccountUuid()", + "uuid", + "type" + ], + "line": 228, + "fileName": "src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java" + }, + { + "raw": "the account[uuid:%s] has no access to the resources[uuid:%s, type:%s]", + "en_US": "the account[uuid:{0}] has no access to the resources[uuid:{1}, type:{2}]", + "zh_CN": "账户[uuid:{0}]无法使用资源[uuid:{1}, type:{2}]", + "arguments": [ + "rbacEntity.getApiMessage().getSession().getAccountUuid()", + "resourceWithNoAccess", + "resourceType.getSimpleName()" + ], + "line": 251, + "fileName": "src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java" + }, + { + "raw": "operation[API:%s] is denied by default, please contact admin to correct it", + "en_US": "operation[API:{0}] is denied by default, please contact admin to correct it", + "zh_CN": "默认情况下拒绝操作[API:{0}],请与管理员联系以更正", + "arguments": [ + "rbacEntity.getApiMessage().getClass().getName()" + ], + "line": 80, + "fileName": "src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java" + }, + { + "raw": "the operation is denied by the policy[name:%s uuid:%s]", + "en_US": "the operation is denied by the policy[name:{0} uuid:{1}]", + "zh_CN": "操作被策略[名称:{0}uuid:{1}]拒绝", + "arguments": [ + "p.getName()", + "p.getUuid()" + ], + "line": 187, + "fileName": "src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java" + }, + { + "raw": "the operation is denied by the policy[name:%s, uuid:%s], field[%s] is not permitted to set", + "en_US": "the operation is denied by the policy[name:{0}, uuid:{1}], field[{2}] is not permitted to set", + "zh_CN": "策略[名称:{0},uuid:{1}]拒绝该操作,不允许设置字段[{2}]", + "arguments": [ + "p.getName()", + "p.getUuid()", + "fname" + ], + "line": 200, + "fileName": "src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java" + }, + { + "raw": "cannot update a system or predefined role", + "en_US": "cannot update a system or predefined role", + "zh_CN": "无法更新系统角色或预定义角色", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java" + }, + { + "raw": "cannot delete a system or predefined role", + "en_US": "cannot delete a system or predefined role", + "zh_CN": "无法删除系统角色或预定义角色", + "arguments": [], + "line": 108, + "fileName": "src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java" + }, + { + "raw": "Failed because management node restarted.", + "en_US": "Failed because management node restarted.", + "zh_CN": "失败,因为管理节点已重新启动。", + "arguments": [], + "line": 187, + "fileName": "src/main/java/org/zstack/image/AddImageLongJob.java" + }, + { + "raw": "the backup storage[uuid:%s] is not in status of Connected, current status is %s", + "en_US": "the backup storage[uuid:{0}] is not in status of Connected, current status is {1}", + "zh_CN": "镜像服务器[uuid:{0}]不是Connected状态,当前状态为{1}", + "arguments": [ + "backupStorageUuid", + "bsStatus" + ], + "line": 35, + "fileName": "src/main/java/org/zstack/image/BackupStorageDeleteBitGC.java" + }, + { + "raw": "The aarch64 architecture does not support legacy.", + "en_US": "The aarch64 architecture does not support legacy.", + "zh_CN": "AARCH64体系结构不支持旧版。", + "arguments": [], + "line": 101, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "volume[uuid:%s] is not Ready, it\u0027s %s", + "en_US": "volume[uuid:{0}] is not Ready, it\u0027s {1}", + "zh_CN": "云盘[uuid:{0}]未Ready,它现在为{1}", + "arguments": [ + "vol.getUuid()", + "vol.getStatus()" + ], + "line": 108, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "volume[uuid:%s] is not Enabled, it\u0027s %s", + "en_US": "volume[uuid:{0}] is not Enabled, it\u0027s {1}", + "zh_CN": "云盘[uuid:{0}]未Enabled,它现在为{1}", + "arguments": [ + "vol.getUuid()", + "vol.getState()" + ], + "line": 112, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "volume snapshot[uuid:%s] is not Ready, it\u0027s %s", + "en_US": "volume snapshot[uuid:{0}] is not Ready, it\u0027s {1}", + "zh_CN": "卷快照[uuid:{0}]未就绪,它是{1}", + "arguments": [ + "vsvo.getUuid()", + "vsvo.getStatus()" + ], + "line": 119, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "volume snapshot[uuid:%s] is not Enabled, it\u0027s %s", + "en_US": "volume snapshot[uuid:{0}] is not Enabled, it\u0027s {1}", + "zh_CN": "卷快照[uuid:{0}]未启用,它是{1}", + "arguments": [ + "vsvo.getUuid()", + "vsvo.getState()" + ], + "line": 123, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "ISO cannot be used as system image", + "en_US": "ISO cannot be used as system image", + "zh_CN": "ISO不能被作为一个系统标签", + "arguments": [], + "line": 142, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "unknown format[%s]", + "en_US": "unknown format[{0}]", + "zh_CN": "未知格式[{0}]", + "arguments": [ + "msg.getFormat()" + ], + "line": 148, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "unsupported image type[%s]", + "en_US": "unsupported image type[{0}]", + "zh_CN": "不支持的镜像类型[{0}]", + "arguments": [ + "msg.getType()" + ], + "line": 152, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "no backup storage specified in uuids%s is available for adding this image; they are not in status %s or not in state %s, or the uuid is invalid backup storage uuid", + "en_US": "no backup storage specified in uuids{0} is available for adding this image; they are not in status {1} or not in state {2}, or the uuid is invalid backup storage uuid", + "zh_CN": "镜像服务器uuids{0}不满足添加镜像的条件;它们的状态不同时满足{1}和{2},亦或者是无效的uuid", + "arguments": [ + "msg.getBackupStorageUuids()", + "BackupStorageStatus.Connected", + "BackupStorageState.Enabled" + ], + "line": 169, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "url must starts with \u0027file:///\u0027, \u0027http://\u0027, \u0027https://\u0027, \u0027ftp://\u0027, \u0027sftp://\u0027 or \u0027/\u0027", + "en_US": "url must starts with \u0027file:///\u0027, \u0027http://\u0027, \u0027https://\u0027, \u0027ftp://\u0027, \u0027sftp://\u0027 or \u0027/\u0027", + "zh_CN": "url必须以下列格式开头\u0027file:///\u0027, \u0027http://\u0027, \u0027https://\u0027, \u0027ftp://\u0027, \u0027sftp://\u0027 or \u0027/\u0027", + "arguments": [], + "line": 180, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "absolute path must be used", + "en_US": "absolute path must be used", + "zh_CN": "必须使用绝对路径", + "arguments": [ + "path" + ], + "line": 191, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "image path [%s] is in black list %s", + "en_US": "image path [{0}] is in black list {1}", + "zh_CN": "镜像路径[{0}]在黑名单{1}中", + "arguments": [ + "path", + "blackList.value()" + ], + "line": 214, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "all images on this server cannot be used", + "en_US": "all images on this server cannot be used", + "zh_CN": "无法使用此服务器上的所有镜像", + "arguments": [], + "line": 223, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "image path is not in white list: %s", + "en_US": "image path is not in white list: {0}", + "zh_CN": "镜像路径不在白名单中:{0}", + "arguments": [ + "whiteList.value()" + ], + "line": 228, + "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + }, + { + "raw": "the image[uuid:%s, name:%s] is not on any backup storage", + "en_US": "the image[uuid:{0}, name:{1}] is not on any backup storage", + "zh_CN": "镜像[uuid:{0}, 名称:{1}]不在任一镜像服务器上", + "arguments": [ + "self.getUuid()", + "self.getName()" + ], + "line": 214, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "No connected backup storage found for image[uuid:%s, name:%s]", + "en_US": "No connected backup storage found for image[uuid:{0}, name:{1}]", + "zh_CN": "在所有 Connected 状态的镜像服务器上都找不到镜像[uuid:{0}, name:{1}]", + "arguments": [ + "self.getUuid()", + "self.getName()" + ], + "line": 224, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "detach iso[uuid\u003d%s] from vm failed, errors are %s", + "en_US": "detach iso[uuid\u003d{0}] from vm failed, errors are {1}", + "zh_CN": "从VM分离ISO[uuid\u003d{0}]失败,错误为{1}", + "arguments": [ + "msg.getImageUuid()", + "JSONObjectUtil.toJsonString(errors)" + ], + "line": 416, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "the image[uuid:%s, name:%s] is not on the backup storage[uuid:%s]", + "en_US": "the image[uuid:{0}, name:{1}] is not on the backup storage[uuid:{2}]", + "zh_CN": "镜像[uuid:{0}, 名称:{1}]不在镜像服务器[uuid:{2}]上", + "arguments": [ + "self.getUuid()", + "self.getName()", + "bsUuid" + ], + "line": 782, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "the image[uuid:%s, name:%s]\u0027s status[%s] is not Deleted on the backup storage[uuid:%s]", + "en_US": "the image[uuid:{0}, name:{1}]\u0027s status[{2}] is not Deleted on the backup storage[uuid:{3}]", + "zh_CN": "镜像[uuid:{0}, 名称:{1}]的状态[{2}]在镜像服务器[uuid:{3}]上不是Deleled", + "arguments": [ + "self.getUuid()", + "self.getName()", + "ref.getStatus()", + "bsUuid" + ], + "line": 724, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "the image[uuid:%s, name:%s] is not deleted on any backup storage", + "en_US": "the image[uuid:{0}, name:{1}] is not deleted on any backup storage", + "zh_CN": "镜像[uuid:{0}, 名称:{1}]未在任一镜像服务器上被删除", + "arguments": [ + "self.getUuid()", + "self.getName()" + ], + "line": 766, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "the image[uuid:%s, name:%s] is not deleted on the backup storage[uuid:%s]", + "en_US": "the image[uuid:{0}, name:{1}] is not deleted on the backup storage[uuid:{2}]", + "zh_CN": "镜像[uuid:{0}, 名称:{1}]未在镜像服务器[uuid:{2}]上被删除", + "arguments": [ + "self.getUuid()", + "self.getName()", + "bsUuid" + ], + "line": 787, + "fileName": "src/main/java/org/zstack/image/ImageBase.java" + }, + { + "raw": "only one bootMode system tag is allowed, but %d got", + "en_US": "only one bootMode system tag is allowed, but {0} got", + "zh_CN": "只允许一个Bootmode系统标记,但{0}获得了", + "arguments": [ + "bootModeCount" + ], + "line": 812, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "[%s] specified in system tag [%s] is not a valid boot mode", + "en_US": "[{0}] specified in system tag [{1}] is not a valid boot mode", + "zh_CN": "系统标记[{1}]中指定的[{0}]不是有效的启动模式", + "arguments": [ + "bootMode", + "systemTag" + ], + "line": 830, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "unable to allocate backup storage specified by uuids%s, list errors are: %s", + "en_US": "unable to allocate backup storage specified by uuids{0}, list errors are: {1}", + "zh_CN": "不能根据[uuids:{0}]分配镜像服务器,错误清单为: {1}", + "arguments": [ + "msgData.getBackupStorageUuids()", + "JSONObjectUtil.toJsonString(errs)" + ], + "line": 1455, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "failed to create image from root volume[uuid:%s] on all backup storage, see cause for one of errors", + "en_US": "failed to create image from root volume[uuid:{0}] on all backup storage, see cause for one of errors", + "zh_CN": "在所有镜像服务器上从云盘[uuid:{0}]创建镜像失败,查看错误原因", + "arguments": [ + "rootVolumeUuid" + ], + "line": 1581, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "failed to allocate all backup storage[uuid:%s], a list of error: %s", + "en_US": "failed to allocate all backup storage[uuid:{0}], a list of error: {1}", + "zh_CN": "镜像服务器[uuid:{0}]分配失败,错误清单:{1}", + "arguments": [ + "msgData.getBackupStorageUuids()", + "JSONObjectUtil.toJsonString(errs)" + ], + "line": 1809, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "cannot find proper backup storage", + "en_US": "cannot find proper backup storage", + "zh_CN": "找不到适当的备份存储", + "arguments": [], + "line": 1779, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "failed to create data volume template from volume[uuid:%s] on all backup storage%s. See cause for one of errors", + "en_US": "failed to create data volume template from volume[uuid:{0}] on all backup storage{1}. See cause for one of errors", + "zh_CN": "在所有镜像服务器[uuid:{1}]上创建云盘[uuid:{0}]的云盘模版失败,查看错误原因", + "arguments": [ + "volumeUuid", + "msgData.getBackupStorageUuids()" + ], + "line": 1922, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "image[uuid:%s] is not on creating, please wait for it to cancel itself.", + "en_US": "image[uuid:{0}] is not on creating, please wait for it to cancel itself.", + "zh_CN": "镜像[uuid:{0}]未处于创建状态,请等待其自行取消。", + "arguments": [ + "imageUuid" + ], + "line": 1999, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "volume[uuid:%s] has been deleted. no need to cancel", + "en_US": "volume[uuid:{0}] has been deleted. no need to cancel", + "zh_CN": "卷[uuid:{0}]已删除。不需要取消。", + "arguments": [ + "volumeUuid" + ], + "line": 2005, + "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + }, + { + "raw": "Failed to set security level, because security level is disabled.", + "en_US": "Failed to set security level, because security level is disabled.", + "zh_CN": "设置密级失败,因为密级功能已禁用", + "arguments": [], + "line": 48, + "fileName": "src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java" + }, + { + "raw": "Unknown security level code[%s], supported values are %s", + "en_US": "Unknown security level code[{0}], supported values are {1}", + "zh_CN": "未知的密级[{0}],支持的值有[{1}]", + "arguments": [ + "msg.getSecurityLevel()", + "Arrays.stream(SecurityLevel.values()).map(SecurityLevel::getCode).collect(Collectors.toList())" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java" + }, + { + "raw": "upload session expired", + "en_US": "upload session expired", + "zh_CN": "上传session失效了", + "arguments": [], + "line": 197, + "fileName": "src/main/java/org/zstack/image/UploadImageTracker.java" + }, + { + "raw": "target backup storage[uuid:%s] became unavailable", + "en_US": "target backup storage[uuid:{0}] became unavailable", + "zh_CN": "目标备份存储[uuid:{0}]变得不可用", + "arguments": [ + "targetBsUuid" + ], + "line": 366, + "fileName": "src/main/java/org/zstack/imagereplicator/ImageReplicatorImpl.java" + }, + { + "raw": "One or more backup storage[uuids:%s] has been added to replication group[uuid:%s]", + "en_US": "One or more backup storage[uuids:{0}] has been added to replication group[uuid:{1}]", + "zh_CN": "已将一个或多个备份存储[uuid:{0}]添加到复制组[uuid:{1}]", + "arguments": [ + "String.join(\",\", msg.getBackupStorageUuids())", + "msg.getReplicationGroupUuid()" + ], + "line": 30, + "fileName": "src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java" + }, + { + "raw": "Backup storage[uuids:%s] is not of type ImageStore", + "en_US": "Backup storage[uuids:{0}] is not of type ImageStore", + "zh_CN": "备份存储[uuid:{0}]不属于ImageStore类型", + "arguments": [ + "bsUuid" + ], + "line": 41, + "fileName": "src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java" + }, + { + "raw": "Backup storage[uuids:%s] is not attached to any Zone", + "en_US": "Backup storage[uuids:{0}] is not attached to any Zone", + "zh_CN": "备份存储[uuid:{0}]未连接到任何区域", + "arguments": [ + "bsUuid" + ], + "line": 51, + "fileName": "src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java" + }, + { + "raw": "Network [uuid: %s] does\u0027t not have IPsec service", + "en_US": "Network [uuid: {0}] does\u0027t not have IPsec service", + "zh_CN": "网络[uuid: {0}]没有IPsec服务", + "arguments": [ + "l3NetworkUuid" + ], + "line": 65, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the remote CIDR[%s] is same to existed cidrs", + "en_US": "the remote CIDR[{0}] is same to existed cidrs", + "zh_CN": "远程CIDR[{0}]与现有的CIDR相同", + "arguments": [ + "rcidr" + ], + "line": 74, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the remote CIDR[%s] and remote CIDR[%s] are overlaped", + "en_US": "the remote CIDR[{0}] and remote CIDR[{1}] are overlaped", + "zh_CN": "远程的CIDR[{0}]和远端CIDR[{1}]存在覆盖", + "arguments": [ + "rcidr", + "tempCidr" + ], + "line": 86, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the CIDR[%s] of local router and remote CIDR[%s] are overlaped", + "en_US": "the CIDR[{0}] of local router and remote CIDR[{1}] are overlaped", + "zh_CN": "本地路由的CIDR[{0}]和远端CIDR存在覆盖", + "arguments": [ + "lcidr", + "tempCidr" + ], + "line": 109, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "all networks in same IPsecConnection should be same type", + "en_US": "all networks in same IPsecConnection should be same type", + "zh_CN": "在相同的IPsec连接中的所有连接应该是相同类型", + "arguments": [], + "line": 122, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "IPsecConnection can ONLY have 1 network for %s", + "en_US": "IPsecConnection can ONLY have 1 network for {0}", + "zh_CN": "IPsec连接只能有一个网络服务", + "arguments": [ + "L3NetworkConstant.L3_BASIC_NETWORK_TYPE" + ], + "line": 128, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "L3Network [uuid: %s] has not been attached to vpc router", + "en_US": "L3Network [uuid: {0}] has not been attached to vpc router", + "zh_CN": "三层网络[uuid:{0}]还没有绑定VPC路由", + "arguments": [ + "l3Uuid" + ], + "line": 140, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "there is no master vpc for ha group %s", + "en_US": "there is no master vpc for ha group {0}", + "zh_CN": "高可用性组{0}没有主VPC", + "arguments": [ + "vrUuids.toArray()[0]" + ], + "line": 162, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "all networks in same IPsecConnection must be attached to same VPC router", + "en_US": "all networks in same IPsecConnection must be attached to same VPC router", + "zh_CN": "在相同的IPsec连接中的所有网络必须绑定在相同的VPC路由", + "arguments": [], + "line": 159, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "there is a vpc[%s] using old ipsec plugin, upgrade it to create ipsec", + "en_US": "there is a vpc[{0}] using old ipsec plugin, upgrade it to create ipsec", + "zh_CN": "存在使用旧IPSec插件的VPC[{0}],请升级该插件以创建IPSec", + "arguments": [ + "masterUuid" + ], + "line": 172, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "there already have ipsec connection[uuid:%s, name:%s] with the same vrouter and peerAddress", + "en_US": "there already have ipsec connection[uuid:{0}, name:{1}] with the same vrouter and peerAddress", + "zh_CN": "这里已经有相同云路由和对端地址的IPsec连接[uuid:{0}, name:{1}]", + "arguments": [ + "tuples.get(0).get(0, String.class)", + "tuples.get(0).get(1, String.class)" + ], + "line": 185, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the vip[uuid:%s] has been used for %s", + "en_US": "the vip[uuid:{0}] has been used for {1}", + "zh_CN": "虚拟IP[uuid:{0}]已经用作网络服务 {1}", + "arguments": [ + "msg.getVipUuid()", + "useForList.toString()" + ], + "line": 209, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the peerAddress[%s] cannot be the same to the VIP address", + "en_US": "the peerAddress[{0}] cannot be the same to the VIP address", + "zh_CN": "对端地址[{0}]不能和虚拟IP地址相同", + "arguments": [ + "msg.getPeerAddress()" + ], + "line": 214, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the peerAddress[%s] is not an IPv4 address", + "en_US": "the peerAddress[{0}] is not an IPv4 address", + "zh_CN": "对端地址[{0}]不是一个IPv4地址", + "arguments": [ + "msg.getPeerAddress()" + ], + "line": 218, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "the authKey cannot contain white space and special characters of \u0027\\\"`\\\\", + "en_US": "the authKey cannot contain white space and special characters of \u0027\\\"`\\\\", + "zh_CN": "验证码不能包含空格和以下字符:\u0027\\\"`\\\\", + "arguments": [], + "line": 230, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "Ipsec VIP [%s] cannot be the first or the last IP of the CIDR with the public address pool type", + "en_US": "Ipsec VIP [{0}] cannot be the first or the last IP of the CIDR with the public address pool type", + "zh_CN": "IPSec VIP[{0}]不能是具有公用地址池类型的CIDR的第一个或最后一个IP", + "arguments": [ + "vipVO.getIp()" + ], + "line": 249, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "must include l3 networks in APIAttachL3NetworksToIPsecConnectionMsg", + "en_US": "must include l3 networks in APIAttachL3NetworksToIPsecConnectionMsg", + "zh_CN": "参数中缺少三层网络的uuid", + "arguments": [], + "line": 281, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "L3 network [%s] is not vpc network, can not be attached or detached to ipsec", + "en_US": "L3 network [{0}] is not vpc network, can not be attached or detached to ipsec", + "zh_CN": "三层网络[{0}]不是VPC网络,不能绑定或解绑IPsec", + "arguments": [ + "l3NetworkUuid" + ], + "line": 288, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "L3 network [%s] can not be attached to ipsec [uuid :%s]twice", + "en_US": "L3 network [{0}] can not be attached to ipsec [uuid :{1}]twice", + "zh_CN": "三层网络[{0}]不能绑定IPsec[uuid :{1}]两次", + "arguments": [ + "l3NetworkUuid", + "msg.getIPsecConnectionUuid()" + ], + "line": 269, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "L3 network [%s] is not be attached to ipsec [uuid :%s]", + "en_US": "L3 network [{0}] is not be attached to ipsec [uuid :{1}]", + "zh_CN": "三层网络[{0}]不能绑定IPsec[uuid :{1}]", + "arguments": [ + "l3NetworkUuid", + "msg.getIPsecConnectionUuid()" + ], + "line": 292, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "Cidr [%s] is already in the Cidrs of ipsec [uuid :%s]", + "en_US": "Cidr [{0}] is already in the Cidrs of ipsec [uuid :{1}]", + "zh_CN": "CIDR[{0}]已经在IPsec[uuid :{1}]的CIDR中", + "arguments": [ + "cidr", + "msg.getIPsecConnectionUuid()" + ], + "line": 302, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "Cidr [%s] is not in Cidrs of ipsec [uuid :%s]", + "en_US": "Cidr [{0}] is not in Cidrs of ipsec [uuid :{1}]", + "zh_CN": "CIDR[{0}]没有在IPsec[uuid :{1}]的CIDR中", + "arguments": [ + "cidr", + "msg.getIPsecConnectionUuid()" + ], + "line": 316, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "can not change state because ipsec [uuid:%s] status is not ready", + "en_US": "can not change state because ipsec [uuid:{0}] status is not ready", + "zh_CN": "不能修改IPsec的状态,因为IPsec的状态没有准备", + "arguments": [ + "msg.getUuid()" + ], + "line": 324, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "could not reconnect this ipsec [uuid:%s], please upgrade ipsec version", + "en_US": "could not reconnect this ipsec [uuid:{0}], please upgrade ipsec version", + "zh_CN": "无法重新连接此IPSec[uuid:{0}],请升级IPSec版本", + "arguments": [ + "msg.getUuid()" + ], + "line": 330, + "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + }, + { + "raw": "cannot find the IPsecconnection[uuid:%s], it may have been deleted", + "en_US": "cannot find the IPsecconnection[uuid:{0}], it may have been deleted", + "zh_CN": "未找到IPsec连接[uuid:{0}],它可能会被删除了", + "arguments": [ + "msg.getIPsecConnectionUuid()" + ], + "line": 133, + "fileName": "src/main/java/org/zstack/ipsec/IPsecManagerImpl.java" + }, + { + "raw": "Current port range[%s, %s] is conflicted with used port range [%s, %s] with vip[uuid: %s] protocol: UDP", + "en_US": "Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: UDP", + "zh_CN": "当前的端口范围以UDP使用的端口范围冲突了", + "arguments": [ + "Long.toString(range2.getStart())", + "Long.toString(range2.getEnd())", + "Long.toString(cur.getStart())", + "Long.toString(cur.getEnd())", + "msg.getVipUuid()" + ], + "line": 466, + "fileName": "src/main/java/org/zstack/ipsec/IPsecManagerImpl.java" + }, + { + "raw": "cidr[%s] of attached L3Network [uuid:%s] is overlapped with ipsec [uuid:%s] remote cidr[%s]", + "en_US": "cidr[{0}] of attached L3Network [uuid:{1}] is overlapped with ipsec [uuid:{2}] remote cidr[{3}]", + "zh_CN": "已绑定在三层网络[uuid:{1}]的CIDR与IPSec[uuid:{2}]远程CIDR存在重叠", + "arguments": [ + "cidr", + "l3Inv.getUuid()", + "uuid", + "rCidr" + ], + "line": 504, + "fileName": "src/main/java/org/zstack/ipsec/IPsecManagerImpl.java" + }, + { + "raw": "create ipsec to ha route failed, because %s", + "en_US": "create ipsec to ha route failed, because {0}", + "zh_CN": "创建IPSec到HA路由失败,因为{0}", + "arguments": [ + "errorCode.getDescription()" + ], + "line": 69, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosCreateIPsecFlow.java" + }, + { + "raw": "delete ipsec from ha group failed because %s", + "en_US": "delete ipsec from ha group failed because {0}", + "zh_CN": "从HA组中删除IPSec失败,原因是{0}", + "arguments": [ + "errorCode.getDescription()" + ], + "line": 55, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosDeleteIPsecFlow.java" + }, + { + "raw": "the remoteCidr[%s] is overlaped with VirtualRouter interface cidr[%s]", + "en_US": "the remoteCidr[{0}] is overlaped with VirtualRouter interface cidr[{1}]", + "zh_CN": "RemoteCidR[{0}]与VirtualRouter接口CIDR[{1}]重叠", + "arguments": [ + "rcidr", + "cidr" + ], + "line": 178, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "vyos doesn\u0027t support aes-192 as IkeEncryptionAlgorithm, available options aes-128, aes-256, 3des", + "en_US": "vyos doesn\u0027t support aes-192 as IkeEncryptionAlgorithm, available options aes-128, aes-256, 3des", + "zh_CN": "vyos不支持aes-192作为密钥交换加密算法,可用选择为aes-128, aes-256, 3des", + "arguments": [], + "line": 293, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "vyos doesn\u0027t support aes-192 as PolicyEncryptionAlgorithm, available options aes-128, aes-256, 3des", + "en_US": "vyos doesn\u0027t support aes-192 as PolicyEncryptionAlgorithm, available options aes-128, aes-256, 3des", + "zh_CN": "vyos不支持aes-192作为加密算法协议,可用选择为aes-128, aes-256, 3des", + "arguments": [], + "line": 299, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "vyos doesn\u0027t support %d as Ike DhGroup ", + "en_US": "vyos doesn\u0027t support {0} as Ike DhGroup ", + "zh_CN": "vyos不支持[{0}]作为Ike DhGroup", + "arguments": [ + "msg.getIkeDhGroup()" + ], + "line": 305, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "sync to ha group failed, because:%s", + "en_US": "sync to ha group failed, because:{0}", + "zh_CN": "与高可用性组同步失败,原因:{0}", + "arguments": [ + "errorCode.getDescription()" + ], + "line": 788, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "apply to ha group failed, because %s", + "en_US": "apply to ha group failed, because {0}", + "zh_CN": "应用到HA组失败,原因是{0}", + "arguments": [ + "errorCode.getDescription()" + ], + "line": 675, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "update ipsec version failed, because:vpc[%s] not exist", + "en_US": "update ipsec version failed, because:vpc[{0}] not exist", + "zh_CN": "更新IPSec版本失败,因为:VPC[{0}]不存在", + "arguments": [ + "vrUuid" + ], + "line": 768, + "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + }, + { + "raw": "there has been a kvm host having management ip[%s]", + "en_US": "there has been a kvm host having management ip[{0}]", + "zh_CN": "已经存在一个拥有管理节点IP[{0}]的物理机", + "arguments": [ + "msg.getManagementIp()" + ], + "line": 46, + "fileName": "src/main/java/org/zstack/kvm/KVMApiInterceptor.java" + }, + { + "raw": "unexpected VNC port number[%d] for VM [uuid:%s]", + "en_US": "unexpected VNC port number[{0}] for VM [uuid:{1}]", + "zh_CN": "VM[uuid:{1}]的意外VNC端口号[{0}]", + "arguments": [ + "rsp.getPort()", + "vm.getUuid()" + ], + "line": 70, + "fileName": "src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java" + }, + { + "raw": "host[uuid:%s] has been deleted", + "en_US": "host[uuid:{0}] has been deleted", + "zh_CN": "物理机[uuid:{0}]已经被删除了", + "arguments": [ + "self.getUuid()" + ], + "line": 465, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "vm[uuid:%s] is not Running or Stopped, current state[%s]", + "en_US": "vm[uuid:{0}] is not Running or Stopped, current state[{1}]", + "zh_CN": "云主机[uuid:{0}]未处在Running或Stopped状态, 现在状态为[{1}]", + "arguments": [ + "msg.getVmUuid()", + "vmState" + ], + "line": 2499, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "after block commit, new volume path still use %s", + "en_US": "after block commit, new volume path still use {0}", + "zh_CN": "块提交后,新卷路径仍使用{0}", + "arguments": [ + "ret.getNewVolumeInstallPath()" + ], + "line": 745, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "create connection to host[%s] failed, because %s", + "en_US": "create connection to host[{0}] failed, because {1}", + "zh_CN": "创建到物理机[{0}]的连接失败,原因是{1}", + "arguments": [ + "host.getUuid()", + "webSsh.status" + ], + "line": 877, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "check host capacity failed, because:%s", + "en_US": "check host capacity failed, because:{0}", + "zh_CN": "检查物理机容量失败,原因:{0}", + "arguments": [ + "reply.getError()" + ], + "line": 1326, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "The host[uuid:%s]\u0027s available memory capacity[%s] is lower than the reserved capacity[%s]", + "en_US": "The host[uuid:{0}]\u0027s available memory capacity[{1}] is lower than the reserved capacity[{2}]", + "zh_CN": "物理机[uuid:{0}]的可用内存[{1}]少于保留内存[{2}]", + "arguments": [ + "msg.getHostUuid()", + "rsp.getTotalMemory()", + "reservedSize" + ], + "line": 1337, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to register colo heartbeat for vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", + "en_US": "unable to register colo heartbeat for vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3}", + "zh_CN": "无法为KVM物理机[uuid:{1},IP:{2}]上的VM[uuid:{0}]注册COLO检测信号,因为{3}", + "arguments": [ + "msg.getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 1392, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to start colo sync vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", + "en_US": "unable to start colo sync vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3}", + "zh_CN": "无法在KVM物理机[uuid:{1},IP:{2}]上启动Colo Sync VM[uuid:{0}],原因是{3}", + "arguments": [ + "msg.getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 1448, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to config secondary vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", + "en_US": "unable to config secondary vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3}", + "zh_CN": "无法在KVM物理机[uuid:{1},IP:{2}]上配置辅助云主机[uuid:{0}],原因是{3}", + "arguments": [ + "msg.getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 1503, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to config primary vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", + "en_US": "unable to config primary vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3}", + "zh_CN": "无法在KVM物理机[uuid:{1},IP:{2}]上配置主VM[uuid:{0}],原因是{3}", + "arguments": [ + "msg.getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 1535, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to get first boot dev of vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", + "en_US": "unable to get first boot dev of vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3}", + "zh_CN": "无法获取KVM物理机[uuid:{1},IP:{2}]上的VM[uuid:{0}]的第一个引导设备,因为{3}", + "arguments": [ + "msg.getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 1576, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to get vm[uuid:%s] device address, because:%s", + "en_US": "failed to get vm[uuid:{0}] device address, because:{1}", + "zh_CN": "无法获取VM[uuid:{0}]设备地址,因为:{1}", + "arguments": [ + "msg.getVmInstanceUuid()", + "rsp.getError()" + ], + "line": 1625, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to get host[uuid:%s] virtualizer info, because:%s", + "en_US": "failed to get host[uuid:{0}] virtualizer info, because:{1}", + "zh_CN": "无法获取物理机[uuid:{0}]虚拟化程序信息,因为:{1}", + "arguments": [ + "msg.getHostUuid()", + "rsp.getError()" + ], + "line": 1680, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to increase vm cpu, error details: %s", + "en_US": "failed to increase vm cpu, error details: {0}", + "zh_CN": "无法增加VM CPU,错误详细信息:{0}", + "arguments": [ + "ret.getError()" + ], + "line": 1762, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to connect to KVM[ip:%s, username:%s, sshPort:%d ] to do DNS check, please check if username/password is wrong; %s", + "en_US": "unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2} ] to do DNS check, please check if username/password is wrong; {3}", + "zh_CN": "无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3}", + "arguments": [ + "self.getManagementIp()", + "getSelf().getUsername()", + "getSelf().getPort()", + "result.getExitErrorMessage()" + ], + "line": 1860, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "the host[uuid:%s, status:%s] is not Connected", + "en_US": "the host[uuid:{0}, status:{1}] is not Connected", + "zh_CN": "物理机[uuid:{0}, 状态:{1}]不是Connected状态", + "arguments": [ + "self.getUuid()", + "self.getStatus()" + ], + "line": 1942, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "cannot do volume snapshot merge when vm[uuid:%s] is in state of %s. The operation is only allowed when vm is Running or Stopped", + "en_US": "cannot do volume snapshot merge when vm[uuid:{0}] is in state of {1}. The operation is only allowed when vm is Running or Stopped", + "zh_CN": "当云主机[uuid:{0}]处于{1}状态的时候不能做云盘快照合并。此操作只能在云主机处在Running和Stopped状态时进行", + "arguments": [ + "volume.getUuid()", + "state" + ], + "line": 2280, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "live volume snapshot merge needs libvirt version greater than %s, current libvirt version is %s. Please stop vm and redo the operation or detach the volume if it\u0027s data volume", + "en_US": "live volume snapshot merge needs libvirt version greater than {0}, current libvirt version is {1}. Please stop vm and redo the operation or detach the volume if it\u0027s data volume", + "zh_CN": "实时云盘快照合并需要libvirt版本高于{0},现在libvirt版本为{1}。请停止云主机后重试或卸载云盘(仅当为云盘时)", + "arguments": [ + "KVMConstant.MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION", + "libvirtVersion" + ], + "line": 2287, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to update nic[vm:%s] on kvm host[uuid:%s, ip:%s],because %s", + "en_US": "failed to update nic[vm:{0}] on kvm host[uuid:{1}, ip:{2}],because {3}", + "zh_CN": "无法更新KVM物理机[uuid:{1},IP:{2}]上的NIC[VM:{0}],因为{3}", + "arguments": [ + "msg.getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 2911, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to attach nic[uuid:%s, vm:%s] on kvm host[uuid:%s, ip:%s],because %s", + "en_US": "failed to attach nic[uuid:{0}, vm:{1}] on kvm host[uuid:{2}, ip:{3}],because {4}", + "zh_CN": "在物理机[uuid:{2},IP:{3}]上加载网卡[uuid:{0},云主机:{1}]失败,因为:{4}", + "arguments": [ + "msg.getNicInventory().getUuid()", + "msg.getNicInventory().getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()" + ], + "line": 2963, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to attach nic[uuid:%s, vm:%s] on kvm host[uuid:%s, ip:%s],because %s, please try again or delete device[%s] by yourself", + "en_US": "failed to attach nic[uuid:{0}, vm:{1}] on kvm host[uuid:{2}, ip:{3}],because {4}, please try again or delete device[{5}] by yourself", + "zh_CN": "无法在KVM物理机[uuid:{2},IP:{3}]上连接NIC[uuid:{0},VM:{1}],因为{4},请重试或自行删除设备[{5}", + "arguments": [ + "msg.getNicInventory().getUuid()", + "msg.getNicInventory().getVmInstanceUuid()", + "self.getUuid()", + "self.getManagementIp()", + "ret.getError()", + "msg.getNicInventory().getInternalName()" + ], + "line": 2959, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to detach data volume[uuid:%s, installPath:%s] from vm[uuid:%s, name:%s] on kvm host[uuid:%s, ip:%s], because %s", + "en_US": "failed to detach data volume[uuid:{0}, installPath:{1}] from vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6}", + "zh_CN": "无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]卸载云盘[uuid:{0}, installPath:{1}],因为: {6}", + "arguments": [ + "vol.getUuid()", + "vol.getInstallPath()", + "vm.getUuid()", + "vm.getName()", + "getSelf().getUuid()", + "getSelf().getManagementIp()", + "ret.getError()" + ], + "line": 3018, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to attach data volume[uuid:%s, installPath:%s] to vm[uuid:%s, name:%s] on kvm host[uuid:%s, ip:%s], because %s", + "en_US": "failed to attach data volume[uuid:{0}, installPath:{1}] to vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6}", + "zh_CN": "无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]挂载云盘[uuid:{0}, installPath:{1}],因为: {6}", + "arguments": [ + "vol.getUuid()", + "vol.getInstallPath()", + "vm.getUuid()", + "vm.getName()", + "getSelf().getUuid()", + "getSelf().getManagementIp()", + "ret.getError()" + ], + "line": 3105, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to destroy vm[uuid:%s name:%s] on kvm host[uuid:%s, ip:%s], because %s", + "en_US": "failed to destroy vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4}", + "zh_CN": "无法在物理机[uuid:{2}, ip:{3}]上删除云主机[uuid:{0} name:{1}],原因: {4}", + "arguments": [ + "vminv.getUuid()", + "vminv.getName()", + "self.getUuid()", + "self.getManagementIp()", + "e.getMessage()" + ], + "line": 3149, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to stop vm[uuid:%s name:%s] on kvm host[uuid:%s, ip:%s], because %s", + "en_US": "failed to stop vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4}", + "zh_CN": "在物理机[uuid:{2}, ip:{3}]上停止云主机[uuid:{0} 名称:{1}]失败,因为:{4}", + "arguments": [ + "vminv.getUuid()", + "vminv.getName()", + "self.getUuid()", + "self.getManagementIp()", + "e.getMessage()" + ], + "line": 3281, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "Host[%s] update spice channel config faild, because %s", + "en_US": "Host[{0}] update spice channel config faild, because {1}", + "zh_CN": "物理机[{0}]更新SPICE通道配置失败,原因是{1}", + "arguments": [ + "msg.getHostUuid()", + "ret.getError()" + ], + "line": 3386, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "when the vm platform is Other, the number of dataVolumes and cdroms cannot exceed 3, currently %s", + "en_US": "when the vm platform is Other, the number of dataVolumes and cdroms cannot exceed 3, currently {0}", + "zh_CN": "当VM平台为OTHER时,DataVolumes和CDROM的数量不能超过3个,目前为{0}", + "arguments": [ + "total" + ], + "line": 3505, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to check physical network interfaces[names : %s] on kvm host[uuid:%s, ip:%s]", + "en_US": "failed to check physical network interfaces[names : {0}] on kvm host[uuid:{1}, ip:{2}]", + "zh_CN": "无法检查KVM物理机[uuid:{1},IP:{2}]上的物理网络接口[名称:{0}]", + "arguments": [ + "msg.getPhysicalInterface()", + "context.getInventory().getUuid()", + "context.getInventory().getManagementIp()" + ], + "line": 3997, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "detected abnormal status[host uuid change, expected: %s but: %s or agent version change, expected: %s but: %s] of kvmagent,it\u0027s mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon", + "en_US": "detected abnormal status[host uuid change, expected: {0} but: {1} or agent version change, expected: {2} but: {3}] of kvmagent,it\u0027s mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon", + "zh_CN": "检测到KVMAgent的异常状态[物理机uuid更改,预期:{0}但是:{1}或代理版本更改,预期:{2}但是:{3}],这主要是由KVMAgent在ZStack管理服务器后面重新启动引起的。将此报告给ping任务,它将很快发出重新连接", + "arguments": [ + "self.getUuid()", + "ret.getHostUuid()", + "dbf.getDbVersion()", + "ret.getVersion()" + ], + "line": 4128, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to connect to kvm host[uuid:%s, ip:%s, url:%s], because %s", + "en_US": "unable to connect to kvm host[uuid:{0}, ip:{1}, url:{2}], because {3}", + "zh_CN": "连接物理机[uuid:{0}, ip:{1},url:{2}]失败,因为:{3}", + "arguments": [ + "self.getUuid()", + "self.getManagementIp()", + "connectPath", + "rsp.getError()" + ], + "line": 4283, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host can not access any primary storage, %s", + "en_US": "host can not access any primary storage, {0}", + "zh_CN": "物理机无法访问任何主存储,{0}", + "arguments": [ + "errorCodeList !\u003d null \u0026\u0026 StringUtils.isNotEmpty(errorCodeList.getReadableDetails()) ? errorCodeList.getReadableDetails() : \"please check network\"" + ], + "line": 4342, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "the host[%s] ssh port[%s] not open after %s seconds, connect timeout", + "en_US": "the host[{0}] ssh port[{1}] not open after {2} seconds, connect timeout", + "zh_CN": "物理机[{0}]SSH端口[{1}]在{2}秒后未打开,连接超时", + "arguments": [ + "getSelf().getManagementIp()", + "getSelf().getPort()", + "TimeUnit.MILLISECONDS.toSeconds(sshTimeout)" + ], + "line": 4482, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to ping all DNS/IP in %s; please check /etc/resolv.conf to make sure your host is able to reach public internet", + "en_US": "failed to ping all DNS/IP in {0}; please check /etc/resolv.conf to make sure your host is able to reach public internet", + "zh_CN": "在{0}中的所有DNS/IP都ping失败了,请检查 /etc/resolv.conf 来确保你的物理机能连接到公网", + "arguments": [ + "checkList" + ], + "line": 4542, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to connect to KVM[ip:%s, username:%s, sshPort: %d, ] to do DNS check, please check if username/password is wrong; %s", + "en_US": "unable to connect to KVM[ip:{0}, username:{1}, sshPort: {2}, ] to do DNS check, please check if username/password is wrong; {3}", + "zh_CN": "无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3}", + "arguments": [ + "self.getManagementIp()", + "getSelf().getUsername()", + "getSelf().getPort()", + "ret.getExitErrorMessage()" + ], + "line": 4540, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "the KVM host[ip:%s] cannot access the management node\u0027s callback url. It seems that the KVM host cannot reach the management IP[%s]. %s %s", + "en_US": "the KVM host[ip:{0}] cannot access the management node\u0027s callback url. It seems that the KVM host cannot reach the management IP[{1}]. {2} {3}", + "zh_CN": "物理机[ip:{0}] 无法连接到管理节点IP [{1}]. {2} {3}", + "arguments": [ + "self.getManagementIp()", + "restf.getHostName()", + "ret.getStderr()", + "ret.getExitErrorMessage()" + ], + "line": 4585, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to connect to KVM[ip:%s, username:%s, sshPort:%d] to check the management node connectivity,please check if username/password is wrong; %s", + "en_US": "unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2}] to check the management node connectivity,please check if username/password is wrong; {3}", + "zh_CN": "不能连接到物理机[ip:{0}, username:{1}, sshPort:{2}] 去检查与管理节点是否连通 ,请检查您的用户名或者密码是否有误; {3}", + "arguments": [ + "self.getManagementIp()", + "getSelf().getUsername()", + "getSelf().getPort()", + "ret.getExitErrorMessage()" + ], + "line": 4582, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to Check whether the host is taken over, because %s", + "en_US": "unable to Check whether the host is taken over, because {0}", + "zh_CN": "无法检查物理机是否已被接管,因为{0}", + "arguments": [ + "hostRet.getExitErrorMessage()" + ], + "line": 4611, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "Unable to get the timestamp of the flag, because %s", + "en_US": "Unable to get the timestamp of the flag, because {0}", + "zh_CN": "无法获取标志的时间戳,因为{0}", + "arguments": [ + "timeRet.getExitErrorMessage()" + ], + "line": 4625, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "the host[ip:%s] has been taken over, because the takeover flag[HostUuid:%s] already exists and utime[%d] has not exceeded host ping interval[%d]", + "en_US": "the host[ip:{0}] has been taken over, because the takeover flag[HostUuid:{1}] already exists and utime[{2}] has not exceeded host ping interval[{3}]", + "zh_CN": "物理机[IP:{0}]已被接管,因为接管标志[HOSTuuid:{1}]已存在,并且UTIME[{2}]未超过物理机ping间隔[{3}]", + "arguments": [ + "self.getManagementIp()", + "hostOutput", + "diff", + "HostGlobalConfig.PING_HOST_INTERVAL.value(int.class)" + ], + "line": 4634, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "the host[ip:%s] has been taken over, because flag[HostUuid:%s] exists in the database", + "en_US": "the host[ip:{0}] has been taken over, because flag[HostUuid:{1}] exists in the database", + "zh_CN": "物理机[IP:{0}]已被接管,因为数据库中存在标志[HOSTuuid:{1}]", + "arguments": [ + "self.getManagementIp()", + "lastHostInv.getUuid()" + ], + "line": 4643, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "unable to get host cpu architecture, please check if username/password is wrong; %s", + "en_US": "unable to get host cpu architecture, please check if username/password is wrong; {0}", + "zh_CN": "无法获取物理机CPU架构,请检查用户名/密码是否错误;{0}", + "arguments": [ + "ret.getExitErrorMessage()" + ], + "line": 4666, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host cpu architecture[%s] is not matched the cluster[%s]", + "en_US": "host cpu architecture[{0}] is not matched the cluster[{1}]", + "zh_CN": "物理机CPU体系结构[{0}]与集群[{1}]不匹配", + "arguments": [ + "hostArchitecture", + "cluster.getArchitecture()" + ], + "line": 4693, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "cannot find either \u0027vmx\u0027 or \u0027svm\u0027 in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting", + "en_US": "cannot find either \u0027vmx\u0027 or \u0027svm\u0027 in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting", + "zh_CN": "不能发现以下任意一个 \u0027vmx\u0027 or \u0027svm\u0027 在路径 /proc/cpuinfo 里, 请检查你是否在你的BIOS设置里开启了virtualization选项", + "arguments": [], + "line": 4997, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match", + "en_US": "host [uuid:{0}] cannot be added to cluster [uuid:{1}] because qemu/libvirt version does not match", + "zh_CN": "物理机[uuid:{0}]不能添加到集群[uuid:{1}]中,因为qemu/libvirt不匹配", + "arguments": [ + "self.getUuid()", + "self.getClusterUuid()" + ], + "line": 5064, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", + "en_US": "host [uuid:{0}] cannot be added to cluster [uuid:{1}] because cpu model name does not match", + "zh_CN": "物理机[uuid:{0}]无法被添加到集群[uuid:{1}]因为cpu型号不一致", + "arguments": [ + "self.getUuid()", + "self.getClusterUuid()" + ], + "line": 5084, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host[%s] not shutdown in %d seconds", + "en_US": "host[{0}] not shutdown in {1} seconds", + "zh_CN": "物理机[{0}]未在{1}秒内关闭", + "arguments": [ + "msg.getHostUuid()", + "ctimeout" + ], + "line": 5217, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host is not in the connected status, cannot update os", + "en_US": "host is not in the connected status, cannot update os", + "zh_CN": "物理机当前并不是已连接状态,不能升级操作系统", + "arguments": [], + "line": 5374, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "host is in the premaintenance state, cannot update os", + "en_US": "host is in the premaintenance state, cannot update os", + "zh_CN": "物理机正处于预维护状态,不能升级操作系统", + "arguments": [], + "line": 5372, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to attach volume to host, because:%s", + "en_US": "failed to attach volume to host, because:{0}", + "zh_CN": "无法将卷附加到物理机,因为:{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 5666, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "failed to detach volume from host, because:%s", + "en_US": "failed to detach volume from host, because:{0}", + "zh_CN": "无法从物理机分离卷,因为:{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 5727, + "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + }, + { + "raw": "cannot adapt version for the bellow rpm: libvirt / qemu / cpumodel", + "en_US": "cannot adapt version for the bellow rpm: libvirt / qemu / cpumodel", + "zh_CN": "源和目的之间的以下组件版本不兼容:libvirt、qemu、cpumodel", + "arguments": [], + "line": 201, + "fileName": "src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java" + }, + { + "raw": "fail to load host info from file. because\\n%s", + "en_US": "fail to load host info from file. because\\n{0}", + "zh_CN": "无法从文件加载物理机信息。因为\\n{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 164, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "the operation system[%s] of host[name:%s, ip:%s] is invalid", + "en_US": "the operation system[{0}] of host[name:{1}, ip:{2}] is invalid", + "zh_CN": "物理机[名称:{1},IP:{2}]的操作系统[{0}]无效", + "arguments": [ + "os", + "vo.getName()", + "vo.getManagementIp()" + ], + "line": 290, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "cluster[uuid:%s] already has host with os version[%s], but new added host[name:%s ip:%s] has different host os version[%s]", + "en_US": "cluster[uuid:{0}] already has host with os version[{1}], but new added host[name:{2} ip:{3}] has different host os version[{4}]", + "zh_CN": "集群[uuid:{0}]已具有操作系统版本为[{1}]的物理机,但新添加的物理机[名称:{2}IP:{3}]具有不同的物理机操作系统版本[{4}]", + "arguments": [ + "vo.getClusterUuid()", + "otherOs", + "vo.getName()", + "vo.getManagementIp()", + "os" + ], + "line": 316, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "vm[uuid:%s] crashes due to kernel error", + "en_US": "vm[uuid:{0}] crashes due to kernel error", + "zh_CN": "VM[uuid:{0}]因内核错误而崩溃", + "arguments": [ + "cmd.vmUuid" + ], + "line": 461, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "there are still hosts not have the same cpu model, details: %s", + "en_US": "there are still hosts not have the same cpu model, details: {0}", + "zh_CN": "仍存在host有不同的cpu模型,详细信息:{0}", + "arguments": [ + "str.toString()" + ], + "line": 500, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "pci bridge need a value greater than 0 and lower than 32", + "en_US": "pci bridge need a value greater than 0 and lower than 32", + "zh_CN": "PCI桥需要大于0且小于32的值", + "arguments": [ + "KVMSystemTags.VM_PREDEFINED_PCI_BRIDGE_NUM_TOKEN" + ], + "line": 514, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "vm current state[%s], modify virtioSCSI requires the vm state[%s]", + "en_US": "vm current state[{0}], modify virtioSCSI requires the vm state[{1}]", + "zh_CN": "VM当前状态[{0}],修改VirtiosCsi需要VM状态[{1}]", + "arguments": [ + "vm.getState()", + "VmInstanceState.Stopped" + ], + "line": 557, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "host[uuid:%s] does not have cpu model information, you can reconnect the host to fix it", + "en_US": "host[uuid:{0}] does not have cpu model information, you can reconnect the host to fix it", + "zh_CN": "物理机[uuid:{0}]无cpu模型信息,你可以尝试重连来解决这个问题", + "arguments": [ + "hostUuid" + ], + "line": 759, + "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + }, + { + "raw": "invalid format string %s", + "en_US": "invalid format string {0}", + "zh_CN": "格式字符串{0}无效", + "arguments": [ + "format" + ], + "line": 35, + "fileName": "src/main/java/org/zstack/kvm/KVMHostUtils.java" + }, + { + "raw": "failed to create bridge[%s] for l2Network[uuid:%s, type:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}] on kvm host[uuid:{3}], because {4}", + "zh_CN": "在物理机[uuid:{3}]上为二层网络[uuid:{1}, type:{2}]创建网桥[{0}]失败,原因: {4}", + "arguments": [ + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "hostUuid", + "rsp.getError()" + ], + "line": 70, + "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java" + }, + { + "raw": "failed to check bridge[%s] for l2NoVlanNetwork[uuid:%s, name:%s] on kvm host[uuid: %s], %s", + "en_US": "failed to check bridge[{0}] for l2NoVlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid: {3}], {4}", + "zh_CN": "在二层网络[uuid:{1}中检查网桥[{0}]失败,名字为[{2}]在物理机t[uuid: {3}]上, {4}", + "arguments": [ + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getName()", + "hostUuid", + "rsp.getError()" + ], + "line": 129, + "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java" + }, + { + "raw": "failed to delete bridge[%s] for l2Network[uuid:%s, type:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to delete bridge[{0}] for l2Network[uuid:{1}, type:{2}] on kvm host[uuid:{3}], because {4}", + "zh_CN": "无法在KVM物理机[uuid:{3}]上删除二层网络[uuid:{1},类型:{2}]的网桥[{0}],因为{4}", + "arguments": [ + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "hostUuid", + "rsp.getError()" + ], + "line": 211, + "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java" + }, + { + "raw": "failed to create bridge[%s] for l2Network[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5}", + "zh_CN": "创建二层网络[uuid:{1}中的网桥[{0}]失败 , 类型为: {2}, vlan:{3}] 在物理机[uuid:{4}]上, 原因: {5}", + "arguments": [ + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "l2vlan.getVlan()", + "hostUuid", + "rsp.getError()" + ], + "line": 82, + "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java" + }, + { + "raw": "failed to check bridge[%s] for l2VlanNetwork[uuid:%s, name:%s] on kvm host[uuid:%s], %s", + "en_US": "failed to check bridge[{0}] for l2VlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", + "zh_CN": "检查在物理机[uuid:{3}]上二层网络[uuid:{1}, name:{2}]中的网桥[{0}]失败, {4}", + "arguments": [ + "cmd.getBridgeName()", + "l2vlan.getUuid()", + "l2vlan.getName()", + "hostUuid", + "rsp.getError()" + ], + "line": 142, + "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java" + }, + { + "raw": "failed to delete bridge[%s] for l2Network[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to delete bridge[{0}] for l2Network[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5}", + "zh_CN": "无法在KVM物理机[uuid:{4}]上删除二层网络[uuid:{1},类型:{2},VLAN:{3}]的网桥[{0}],因为{5}", + "arguments": [ + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "l2vlan.getVlan()", + "hostUuid", + "rsp.getError()" + ], + "line": 239, + "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java" + }, + { + "raw": "failed to apply rules of security group rules to kvm host[uuid:%s], because %s", + "en_US": "failed to apply rules of security group rules to kvm host[uuid:{0}], because {1}", + "zh_CN": "不能应用安全组规则在物理机t[uuid:{0}]上, 因为 {1}", + "arguments": [ + "hto.getHostUuid()", + "rsp.getError()" + ], + "line": 109, + "fileName": "src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java" + }, + { + "raw": "failed to check default rules of security group on kvm host[uuid:%s], because %s", + "en_US": "failed to check default rules of security group on kvm host[uuid:{0}], because {1}", + "zh_CN": "在host[uuid:{0}]上检查默认安全组规则失败", + "arguments": [ + "hostUuid", + "rsp.getError()" + ], + "line": 152, + "fileName": "src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java" + }, + { + "raw": "Failed to start vm, because can not disable vm.cpu.hypervisor.feature with vm.cpuMode none", + "en_US": "Failed to start vm, because can not disable vm.cpu.hypervisor.feature with vm.cpuMode none", + "zh_CN": "无法启动VM,因为无法使用VM.CPUMode None禁用VM.CPU.Hypervisor.Feature", + "arguments": [], + "line": 31, + "fileName": "src/main/java/org/zstack/kvm/KvmVmHardwareVerifyExtensionPoint.java" + }, + { + "raw": "cannot get vmUuid from msg %s", + "en_US": "cannot get vmUuid from msg {0}", + "zh_CN": "无法从消息{0}获取VMuuid", + "arguments": [ + "msg.getMessageName()" + ], + "line": 95, + "fileName": "src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java" + }, + { + "raw": "unable to do vm sync on host[uuid:%s, ip:%s] because %s", + "en_US": "unable to do vm sync on host[uuid:{0}, ip:{1}] because {2}", + "zh_CN": "不能在物理机[uuid:{0}, ip:{1}]上执行云主机状态同步操作,因为{2}", + "arguments": [ + "host.getUuid()", + "host.getManagementIp()", + "ret.getError()" + ], + "line": 258, + "fileName": "src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java" + }, + { + "raw": "The vm[%s] state is in shutdown for a long time, check whether the vm is normal", + "en_US": "The vm[{0}] state is in shutdown for a long time, check whether the vm is normal", + "zh_CN": "云主机[{0}]长时间处于关闭状态,请检查云主机是否正常", + "arguments": [ + "vmUuid" + ], + "line": 287, + "fileName": "src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java" + }, + { + "raw": "unsupported LDAP/AD server scope", + "en_US": "unsupported LDAP/AD server scope", + "zh_CN": "不支持的LDAP/AD服务器作用域", + "arguments": [], + "line": 67, + "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + }, + { + "raw": "Wrong LdapServerType[%s], valid values: [%,%s]", + "en_US": "Wrong LdapServerType[{0}], valid values: [%,{1}]", + "zh_CN": "错误的LDAP服务类型[{0}],有效的值: [%,{1}]", + "arguments": [ + "type", + "LdapConstant.OpenLdap.TYPE", + "LdapConstant.WindowsAD.TYPE" + ], + "line": 128, + "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + }, + { + "raw": "Cannot connect to LDAP/AD server, Invalid Credentials, please checkout User DN and password", + "en_US": "Cannot connect to LDAP/AD server, Invalid Credentials, please checkout User DN and password", + "zh_CN": "无法连接到LDAP/AD服务器,凭据无效,请签出用户DN和密码", + "arguments": [], + "line": 153, + "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + }, + { + "raw": "Cannot connect to LDAP/AD server, communication false, please checkout IP, port and Base DN", + "en_US": "Cannot connect to LDAP/AD server, communication false, please checkout IP, port and Base DN", + "zh_CN": "无法连接到LDAP/AD服务器,通信错误,请检查IP、端口和基本DN", + "arguments": [], + "line": 156, + "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + }, + { + "raw": "Cannot connect to LDAP/AD server, %s", + "en_US": "Cannot connect to LDAP/AD server, {0}", + "zh_CN": "不能连接LDAP服务,{0}", + "arguments": [ + "e.toString()" + ], + "line": 159, + "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + }, + { + "raw": "Account[uuid:%s] Not Found!!!", + "en_US": "Account[uuid:{0}] Not Found!!!", + "zh_CN": "未找到帐户[uuid:{0}]!", + "arguments": [ + "vo.getAccountUuid()" + ], + "line": 560, + "fileName": "src/main/java/org/zstack/ldap/LdapManagerImpl.java" + }, + { + "raw": "query ldap entry[filter: %s] fail, because %s", + "en_US": "query ldap entry[filter: {0}] fail, because {1}", + "zh_CN": "查询LDAP条目[筛选器:{0}]失败,原因是{1}", + "arguments": [ + "filter", + "errorMessage" + ], + "line": 581, + "fileName": "src/main/java/org/zstack/ldap/LdapUtil.java" + }, + { + "raw": "query ldap entry fail, %s", + "en_US": "query ldap entry fail, {0}", + "zh_CN": "查询LDAP条目失败,{0}", + "arguments": [ + "e.toString()" + ], + "line": 52, + "fileName": "src/main/java/org/zstack/ldap/externalSearch/AggregateSearch.java" + }, + { + "raw": "Parse license error,\\n1. check your private key and application code is correct\\n2. check your license is not corrupted\\n3. use zstack-ctl clear_license to clear your licenses and try to reinstall\\n", + "en_US": "Parse license error,\\n1. check your private key and application code is correct\\n2. check your license is not corrupted\\n3. use zstack-ctl clear_license to clear your licenses and try to reinstall\\n", + "zh_CN": "解析许可证错误,\\N1。检查您的私钥和应用程序代码是否正确\\N2。检查您的许可证是否已损坏\\N3。使用zstack-CTL清除_许可证清除您的许可证并尝试重新安装\\n", + "arguments": [], + "line": 167, + "fileName": "src/main/java/org/zstack/license/LicenseChecker.java" + }, + { + "raw": "the licenseRequestCode is illegal", + "en_US": "the licenseRequestCode is illegal", + "zh_CN": "许可证请求代码不合法", + "arguments": [], + "line": 229, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "Decode fail because %s", + "en_US": "Decode fail because {0}", + "zh_CN": "解码失败,因为{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 242, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "Unexpected decoded license file length: %d", + "en_US": "Unexpected decoded license file length: {0}", + "zh_CN": "意外的解码许可证文件长度:{0}", + "arguments": [ + "bytes.length" + ], + "line": 239, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "Licensed VM number overrun", + "en_US": "Licensed VM number overrun", + "zh_CN": "VM数量超过云主机授权上限", + "arguments": [], + "line": 791, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "unexpected host vendor for MINI", + "en_US": "unexpected host vendor for MINI", + "zh_CN": "Mini的意外物理机供应商", + "arguments": [], + "line": 857, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "not supported: delete license[%s] from USB-key", + "en_US": "not supported: delete license[{0}] from USB-key", + "zh_CN": "不支持:从USB-KEY删除许可证[{0}]", + "arguments": [ + "info.getUuid()" + ], + "line": 1216, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "UKey not supported (arch: %s)", + "en_US": "UKey not supported (arch: {0})", + "zh_CN": "不支持UKey(Arch:{0})", + "arguments": [ + "System.getProperty(\"os.arch\")" + ], + "line": 1271, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "update local ukey license: %s", + "en_US": "update local ukey license: {0}", + "zh_CN": "更新本地UKEY许可证:{0}", + "arguments": [ + "ex.getLocalizedMessage()" + ], + "line": 1351, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "No local ukey license updated", + "en_US": "No local ukey license updated", + "zh_CN": "没有本地UKEY许可证更新", + "arguments": [], + "line": 1347, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "No node available to update UKey", + "en_US": "No node available to update UKey", + "zh_CN": "没有节点可用于更新UKEY", + "arguments": [], + "line": 1377, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "Multiple MN exists but only supplied licenses for %s", + "en_US": "Multiple MN exists but only supplied licenses for {0}", + "zh_CN": "管理节点有多个,但是仅提供了节点{0}的许可证", + "arguments": [ + "Platform.getManagementServerIp()" + ], + "line": 1519, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "MN[uuid:%s]: %s", + "en_US": "MN[uuid:{0}]: {1}", + "zh_CN": "Mn[uuid:{0}]:{1}", + "arguments": [ + "mnUuid", + "reply.getError().getDetails()" + ], + "line": 1493, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "MN HA environment, but only updated license for %s", + "en_US": "MN HA environment, but only updated license for {0}", + "zh_CN": "管理节点有多个,但是仅更新了节点{0}的许可证", + "arguments": [ + "msg.getManagementUuids()" + ], + "line": 1521, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "can not find license[uuid:%s, type:%s] file on path %s", + "en_US": "can not find license[uuid:{0}, type:{1}] file on path {2}", + "zh_CN": "在路径{2}上找不到许可证[uuid:{0},类型:{1}]文件", + "arguments": [ + "newLicenseInfo.getUuid()", + "newLicenseInfo.getLicenseType().toString()", + "path" + ], + "line": 1724, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "License expired", + "en_US": "License expired", + "zh_CN": "许可证已过期", + "arguments": [], + "line": 2263, + "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + }, + { + "raw": "%s is not existed", + "en_US": "{0} is not existed", + "zh_CN": "{0}不存在", + "arguments": [ + "sdsInfoPath" ], - "line": 955, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "line": 50, + "fileName": "src/main/java/org/zstack/license/cube/CubeLicenseFactory.java" + }, + { + "raw": "context cannot be null in license", + "en_US": "context cannot be null in license", + "zh_CN": "许可证中的上下文不能为空", + "arguments": [], + "line": 61, + "fileName": "src/main/java/org/zstack/license/cube/XmsCli.java" + }, + { + "raw": "No factory found for type:%s", + "en_US": "No factory found for type:{0}", + "zh_CN": "未找到类型为{0}的工厂", + "arguments": [ + "struct.getType()" + ], + "line": 247, + "fileName": "src/main/java/org/zstack/log/LogConfigurationManagerImpl.java" + }, + { + "raw": "Unknown log configuration type %s", + "en_US": "Unknown log configuration type {0}", + "zh_CN": "未知的日志配置类型{0}", + "arguments": [ + "msg.getType()" + ], + "line": 462, + "fileName": "src/main/java/org/zstack/log/LogConfigurationManagerImpl.java" + }, + { + "raw": "No factory found for log4j2 appender type:%s.", + "en_US": "No factory found for log4j2 appender type:{0}.", + "zh_CN": "找不到Log4j2附加器类型的工厂:{0}。", + "arguments": [ + "lstruct.getAppenderType()" + ], + "line": 60, + "fileName": "src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java" + }, + { + "raw": "Unknown log4j2 appender type %s", + "en_US": "Unknown log4j2 appender type {0}", + "zh_CN": "未知的Log4j2 Appender类型{0}", + "arguments": [ + "lstruct.getAppenderType()" + ], + "line": 134, + "fileName": "src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java" + }, + { + "raw": "facility can not be null", + "en_US": "facility can not be null", + "zh_CN": "设备不能为空", + "arguments": [], + "line": 33, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "invalid facility %s", + "en_US": "invalid facility {0}", + "zh_CN": "工具{0}无效", + "arguments": [ + "configuration.facility" + ], + "line": 37, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "hostname can not be null", + "en_US": "hostname can not be null", + "zh_CN": "物理机名不能为空", + "arguments": [], + "line": 41, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "port can not be null", + "en_US": "port can not be null", + "zh_CN": "端口不能为空", + "arguments": [], + "line": 45, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "protocol can not be null", + "en_US": "protocol can not be null", + "zh_CN": "协议不能为空", + "arguments": [], + "line": 49, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "unsupported protocol %s", + "en_US": "unsupported protocol {0}", + "zh_CN": "不支持的协议{0}", + "arguments": [ + "configuration.protocol" + ], + "line": 55, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "syslog server[address: %s:%s] is not available", + "en_US": "syslog server[address: {0}:{1}] is not available", + "zh_CN": "Syslog服务器[地址:{0}:{1}]不可用", + "arguments": [ + "configuration.hostname", + "configuration.port" + ], + "line": 69, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "syslog server[address: %s] is not available", + "en_US": "syslog server[address: {0}] is not available", + "zh_CN": "Syslog服务器[地址:{0}]不可用", + "arguments": [ + "configuration.hostname" + ], + "line": 61, + "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + }, + { + "raw": "There is no LDAP/AD server in the system, Please add a LDAP/AD server first.", + "en_US": "There is no LDAP/AD server in the system, Please add a LDAP/AD server first.", + "zh_CN": "在系统中没有LDAP服务,请先添加一个LDAP服务", + "arguments": [], + "line": 74, + "fileName": "src/main/java/org/zstack/login/LdapLoginInterceptor.java" + }, + { + "raw": "Can not bind this ldap uid %s to virtual id [uuid:%s]", + "en_US": "Can not bind this ldap uid {0} to virtual id [uuid:{1}]", + "zh_CN": "无法将此LDAP UID{0}绑定到虚拟ID[uuid:{1}]", + "arguments": [ + "msg.getLdapUid()", + "msg.getVirtualIDUuid()" + ], + "line": 68, + "fileName": "src/main/java/org/zstack/login/LdapLoginInterceptor.java" + }, + { + "raw": "This uid is already used", + "en_US": "This uid is already used", + "zh_CN": "此UID已被使用", + "arguments": [], + "line": 82, + "fileName": "src/main/java/org/zstack/login/LdapLoginInterceptor.java" + }, + { + "raw": "ZStack is loading ldap organizations from DB now, can not execute sync operation", + "en_US": "ZStack is loading ldap organizations from DB now, can not execute sync operation", + "zh_CN": "ZStack正在从数据库加载LDAP组织,无法执行同步操作", + "arguments": [], + "line": 228, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Failed to sync ldap entry[], because %s", + "en_US": "Failed to sync ldap entry[], because {0}", + "zh_CN": "无法同步LDAP条目[],因为{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 390, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Failed to sync organizations, because %s", + "en_US": "Failed to sync organizations, because {0}", + "zh_CN": "无法同步组织,因为{0}", + "arguments": [ + "reply.getError().getReadableDetails()" + ], + "line": 1021, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Failed to transform ldap entry to organization ndoe", + "en_US": "Failed to transform ldap entry to organization ndoe", + "zh_CN": "无法将LDAP条目转换为组织ndoe", + "arguments": [], + "line": 969, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "failed to sync ldap organization", + "en_US": "failed to sync ldap organization", + "zh_CN": "无法同步LDAP组织", + "arguments": [], + "line": 958, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Can not sync LDAP/AD server whose scope is not %s", + "en_US": "Can not sync LDAP/AD server whose scope is not {0}", + "zh_CN": "无法同步范围不是{0}的LDAP/AD服务器", + "arguments": [ + "scope.toString()" + ], + "line": 1441, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Failed to validate uid[%s], maybe it has been deleted", + "en_US": "Failed to validate uid[{0}], maybe it has been deleted", + "zh_CN": "无法验证UID[{0}],它可能已被删除", + "arguments": [ + "uid" + ], + "line": 1575, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Failed to create iam2 virtual id for uid[%s], because %s", + "en_US": "Failed to create iam2 virtual id for uid[{0}], because {1}", + "zh_CN": "无法为UID[{0}]创建IAM2虚拟ID,因为{1}", + "arguments": [ + "uid", + "reply.getError().getReadableDetails()" + ], + "line": 1616, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Failed to validate dn [%s], maybe it has been deleted", + "en_US": "Failed to validate dn [{0}], maybe it has been deleted", + "zh_CN": "无法验证DN[{0}],它可能已被删除", + "arguments": [ + "ldapUid" + ], + "line": 1751, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "invalid json format", + "en_US": "invalid json format", + "zh_CN": "无效的JSON格式", + "arguments": [], + "line": 2195, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "name is mandatory field %", + "en_US": "name is mandatory field %", + "zh_CN": "名称是必填字段%", + "arguments": [], + "line": 2206, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "attribute is mandatory field %", + "en_US": "attribute is mandatory field %", + "zh_CN": "属性是强制字段%", + "arguments": [], + "line": 2210, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "type is mandatory field %", + "en_US": "type is mandatory field %", + "zh_CN": "类型为必填字段%", + "arguments": [], + "line": 2214, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "optional is mandatory field %", + "en_US": "optional is mandatory field %", + "zh_CN": "可选为必填字段%", + "arguments": [], + "line": 2218, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "name should use values in %s", + "en_US": "name should use values in {0}", + "zh_CN": "名称应使用{0}中的值", + "arguments": [ + "fieldNames" + ], + "line": 2222, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "Invalid attribute. Attribute[%s] is required, but found there are some record not matched", + "en_US": "Invalid attribute. Attribute[{0}] is required, but found there are some record not matched", + "zh_CN": "无效属性。属性[{0}]是必需的,但发现有一些记录不匹配", + "arguments": [ + "rule.getAttribute()" + ], + "line": 2254, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + }, + { + "raw": "strategy is mandatory field %", + "en_US": "strategy is mandatory field %", + "zh_CN": "策略为必填字段%", + "arguments": [], + "line": 2199, + "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" }, { - "raw": "The CdRom[%s] Already the default", - "en_US": "The CdRom[{0}] Already the default", - "zh_CN": "", - "arguments": [ - "vmCdRomVO.getUuid()" - ], - "line": 974, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java" + "raw": "missing loginPluginName", + "en_US": "missing loginPluginName", + "zh_CN": "缺少LoginPluginName", + "arguments": [], + "line": 54, + "fileName": "src/main/java/org/zstack/login/plugin/LoginPluginBackend.java" }, { - "raw": "vm[uuid:%s, name:%s] has been deleted", - "en_US": "vm[uuid:{0}, name:{1}] has been deleted", - "zh_CN": "云主机[uuid:{0}, name:{1}]已经被删除了", + "raw": "no login plugin named %s", + "en_US": "no login plugin named {0}", + "zh_CN": "没有名为{0}的登录插件", "arguments": [ - "vo.getUuid()", - "vo.getName()" + "loginContext.getLoginPluginName()" ], - "line": 235, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 59, + "fileName": "src/main/java/org/zstack/login/plugin/LoginPluginBackend.java" }, { - "raw": "the vm[uuid:%s] has no nic on the L3 network[uuid:%s]", - "en_US": "the vm[uuid:{0}] has no nic on the L3 network[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}] 没有网卡在L3网络[uuid:{1}]上", + "raw": "missing LoginUserInfo when use plugin login", + "en_US": "missing LoginUserInfo when use plugin login", + "zh_CN": "使用插件登录时缺少LoginUserInfo", "arguments": [ - "self.getUuid()", - "l3Uuid" + "loginContext.getLoginPluginName()" ], - "line": 766, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 64, + "fileName": "src/main/java/org/zstack/login/plugin/LoginPluginBackend.java" }, { - "raw": "the vm has been deleted", - "en_US": "the vm has been deleted", - "zh_CN": "云主机已经被删除了", - "arguments": [], - "line": 1154, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "raw": "Invalid rule expression, add access control rule fail because: %s", + "en_US": "Invalid rule expression, add access control rule fail because: {0}", + "zh_CN": "规则表达式无效,添加访问控制规则失败,原因是:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 40, + "fileName": "src/main/java/org/zstack/loginControl/LoginControlApiInterceptor.java" }, { - "raw": "the ISO[uuid:%s] is on backup storage that is not compatible of the primary storage[uuid:%s] where the VM[name:%s, uuid:%s] is on", - "en_US": "the ISO[uuid:{0}] is on backup storage that is not compatible of the primary storage[uuid:{1}] where the VM[name:{2}, uuid:{3}] is on", - "zh_CN": "ISO[uuid:{0}]在镜像服务器上,这个ISO不能兼容主存储[uuid:{1}]在云主机[name:{2}, uuid:{3}]上", + "raw": "unrecognized key: %s", + "en_US": "unrecognized key: {0}", + "zh_CN": "无法识别的键:{0}", "arguments": [ - "isoUuid", - "psUuid", - "self.getName()", - "self.getUuid()" + "key" ], - "line": 3822, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 107, + "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" }, { - "raw": "host[uuid:%s] capacity is not enough to offer cpu[%s], memory[%s bytes]", - "en_US": "host[uuid:{0}] capacity is not enough to offer cpu[{1}], memory[{2} bytes]", - "zh_CN": "物理机[uuid:{0}]无法提供CPU: [{1}],内存: [{2} bytes]", + "raw": "missing key:value of %s", + "en_US": "missing key:value of {0}", + "zh_CN": "缺少键:{0}的值", "arguments": [ - "self.getHostUuid()", - "cpuNum - oldCpuNum", - "struct.alignedMemory - oldMemorySize" + "opt.get()" ], - "line": 4224, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 113, + "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" }, { - "raw": "ISO[uuid:%s] is not attached to VM[uuid:%s]", - "en_US": "ISO[uuid:{0}] is not attached to VM[uuid:{1}]", - "zh_CN": "ISO[uuid:{0}]未被加载到云主机[uuid:{1}]", + "raw": "No available user with name: %s, type: %s", + "en_US": "No available user with name: {0}, type: {1}", + "zh_CN": "没有名称为{0}、类型为{1}的可用用户", "arguments": [ - "isoUuid", - "self.getUuid()" + "msg.getResourceName()", + "msg.getLoginType()" ], - "line": 4444, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 291, + "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" }, { - "raw": "unable to start the vm[uuid:%s]. It doesn\u0027t have any nic, please attach a nic and try again", - "en_US": "unable to start the vm[uuid:{0}]. It doesn\u0027t have any nic, please attach a nic and try again", - "zh_CN": "无法启动虚拟机[uuid:{0}]。该虚拟机没有网卡,请添加网卡后再试", + "raw": "%s is not an API", + "en_US": "{0} is not an API", + "zh_CN": "{0}不是一个API", "arguments": [ - "self.getUuid()" + "msg.getJobName()" ], - "line": 5174, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 90, + "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" }, { - "raw": "One vm cannot create %s CDROMs, vm can only add %s CDROMs", - "en_US": "One vm cannot create {0} CDROMs, vm can only add {1} CDROMs", - "zh_CN": "", + "raw": "cannot cancel longjob that is succeeded", + "en_US": "cannot cancel longjob that is succeeded", + "zh_CN": "不能取消已经成功的longjob", + "arguments": [], + "line": 152, + "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + }, + { + "raw": "cannot cancel longjob that is failed", + "en_US": "cannot cancel longjob that is failed", + "zh_CN": "不能取消已经失败的longjob", + "arguments": [], + "line": 155, + "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + }, + { + "raw": "delete longjob only when it\u0027s succeeded, canceled, or failed", + "en_US": "delete longjob only when it\u0027s succeeded, canceled, or failed", + "zh_CN": "只能删除已经成功、取消、失败的longjob", + "arguments": [], + "line": 166, + "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + }, + { + "raw": "rerun longjob only when it\u0027s succeeded, canceled, or failed", + "en_US": "rerun longjob only when it\u0027s succeeded, canceled, or failed", + "zh_CN": "仅在成功、取消或失败时重新运行LongJob", + "arguments": [], + "line": 177, + "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + }, + { + "raw": "can only resume longjob that is Suspended", + "en_US": "can only resume longjob that is Suspended", + "zh_CN": "只能恢复挂起的LongJob", + "arguments": [], + "line": 206, + "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + }, + { + "raw": "%s has no corresponding longjob", + "en_US": "{0} has no corresponding longjob", + "zh_CN": "{0}没有与之对应的longjob", "arguments": [ - "cdRomSpecs.size()", - "max" + "jobName" ], - "line": 5411, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 39, + "fileName": "src/main/java/org/zstack/longjob/LongJobFactoryImpl.java" }, { - "raw": "VM[uuid:%s] can only add %s CDROMs", - "en_US": "VM[uuid:{0}] can only add {1} CDROMs", - "zh_CN": "", + "raw": "unable to attach a L3 network. The cidr of l3[%s] to attach overlapped with l3[%s] already attached to vm", + "en_US": "unable to attach a L3 network. The cidr of l3[{0}] to attach overlapped with l3[{1}] already attached to vm", + "zh_CN": "不能绑定这个三层网络。这个云主机上已经绑定的三层网络[{1}]和这个三层网络[{0}]的CIDR存在重叠", "arguments": [ - "msg.getVmInstanceUuid()", - "max" + "l3NetworkUuid", + "vmNicVO.getL3NetworkUuid()" ], - "line": 6301, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 123, + "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" }, { - "raw": "update vm[%s] priority to [%s] failed,because %s", - "en_US": "update vm[{0}] priority to [{1}] failed,because {2}", - "zh_CN": "", + "raw": "the vm[name:%s, uuid:%s] already has some port forwarding rules%s attached", + "en_US": "the vm[name:{0}, uuid:{1}] already has some port forwarding rules{2} attached", + "zh_CN": "云主机[name:{0}, uuid:{1}] 已经设置了一些端口转发规则{2}", "arguments": [ - "self.getUuid()", - "msg.getPriority()", - "reply.getError()" + "vm.getName()", + "vm.getUuid()", + "StringUtils.join(pfStr, \",\")" ], - "line": 6371, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceBase.java" + "line": 155, + "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" }, { - "raw": "VmInstanceStartNewCreatedVmExtensionPoint[%s] refuses to create vm[uuid:%s] because %s", - "en_US": "VmInstanceStartNewCreatedVmExtensionPoint[{0}] refuses to create vm[uuid:{1}] because {2}", - "zh_CN": "VmInstanceStartNewCreatedVmExtensionPoint[{0}] 因为{2} 拒绝创建虚拟机[uuid:{1}]", + "raw": "the vm[name:%s, uuid:%s] already has some EIPs%s attached", + "en_US": "the vm[name:{0}, uuid:{1}] already has some EIPs{2} attached", + "zh_CN": "云主机[name:{0}, uuid:{1}] 已经配置了弹性IP{2}", "arguments": [ - "ext.getClass().getName()", - "inv.getUuid()", - "err" + "vm.getName()", + "vm.getUuid()", + "StringUtils.join(eipStr, \",\")" ], - "line": 58, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + "line": 176, + "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" }, { - "raw": "VmInstanceRebootExtensionPoint[%s] refuses to reboot vm[uuid:%s] because %s", - "en_US": "VmInstanceRebootExtensionPoint[{0}] refuses to reboot vm[uuid:{1}] because {2}", - "zh_CN": "VmInstanceRebootExtensionPoint[{0}] 因为{2} 拒绝重启虚拟机[uuid:{1}]", + "raw": "the vip[uuid:%s] already has bound to other service[%s]", + "en_US": "the vip[uuid:{0}] already has bound to other service[{1}]", + "zh_CN": "该虚拟IP[uuid:{0}]已经绑定了其他服务", "arguments": [ - "ext.getClass().getName()", - "inv.getUuid()", - "err" + "msg.getVipUuid()", + "useForList.toString()" ], - "line": 176, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + "line": 191, + "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" }, { - "raw": "VmInstanceDestroyVmExtensionPoint[%s] refuses to destroy vm[uuid:%s] because %s", - "en_US": "VmInstanceDestroyVmExtensionPoint[{0}] refuses to destroy vm[uuid:{1}] because {2}", - "zh_CN": "VmInstanceDestroyVmExtensionPoint[{0}] 因为{2} 拒绝删除虚拟机[uuid:{1}]", + "raw": "Current port range[%s, %s] is conflicted with used port range [%s, %s] with vip[uuid: %s] protocol: %s ", + "en_US": "Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} ", + "zh_CN": "当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的端口范围[{2}, {3}]冲突", "arguments": [ - "ext.getClass().getName()", - "inv.getUuid()", - "err" + "Long.toString(range.getStart())", + "Long.toString(range.getEnd())", + "Long.toString(cur.getStart())", + "Long.toString(cur.getEnd())", + "vipUuid", + "protocol" ], - "line": 218, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + "line": 231, + "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" }, { - "raw": "VmInstanceStartExtensionPoint[%s] refuses to start vm[uuid:%s] because %s", - "en_US": "VmInstanceStartExtensionPoint[{0}] refuses to start vm[uuid:{1}] because {2}", - "zh_CN": "VmInstanceStartExtensionPoint[{0}] 因为{2} 拒绝启动虚拟机[uuid:{1}]", + "raw": "Current port range[%s, %s] is conflicted with system service port range [%s, %s] with vip[uuid: %s] protocol: %s ", + "en_US": "Current port range[{0}, {1}] is conflicted with system service port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} ", + "zh_CN": "当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的系统服务端口范围[{2}, {3}]冲突", "arguments": [ - "ext.getClass().getName()", - "inv.getUuid()", - "err" + "Long.toString(range.getStart())", + "Long.toString(range.getEnd())", + "Long.toString(cur.getStart())", + "Long.toString(cur.getEnd())", + "vipUuid", + "protocol" ], - "line": 259, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java" + "line": 228, + "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" }, { - "raw": "Spice certificate does not exist, Please check if spice tls is enabled", - "en_US": "Spice certificate does not exist, Please check if spice tls is enabled", - "zh_CN": "", - "arguments": [], - "line": 251, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "raw": "L3 network[uuid:%s] not found. Please correct your system tag[%s] of static IP", + "en_US": "L3 network[uuid:{0}] not found. Please correct your system tag[{1}] of static IP", + "zh_CN": "找不到三层网络[uuid:0]。请确认静态IP的系统标签", + "arguments": [ + "l3Uuid", + "systemTag" + ], + "line": 851, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "the image[uuid:%s] is not on any backup storage that has been attached to the zone[uuid:%s]", - "en_US": "the image[uuid:{0}] is not on any backup storage that has been attached to the zone[uuid:{1}]", - "zh_CN": "镜像[uuid:{0}]不在任何加载到区域[uuid:{1}]的镜像服务器上", + "raw": "for shareable volume, the only supported primary storage type is %s, current is %s", + "en_US": "for shareable volume, the only supported primary storage type is {0}, current is {1}", + "zh_CN": "共享云盘仅支持在主存储类型为{0}的主存储上使用,当前的类型为{1}", "arguments": [ - "msg.getImageUuid()", - "msg.getZoneUuid()" + "supportSharedVolumePrimaryStorage", + "psType" ], - "line": 434, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 327, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "the image[name:%s, uuid:%s] is an ISO, rootDiskSize must be set", - "en_US": "the image[name:{0}, uuid:{1}] is an ISO, rootDiskSize must be set", - "zh_CN": "镜像[name:{0}, uuid:{1}]是一个IOS, 必须设置根云盘大小", + "raw": "invalid volume bandwidth[%s] is larger than %d", + "en_US": "invalid volume bandwidth[{0}] is larger than {1}", + "zh_CN": "云盘带宽[{0}]大于{1}是无效的", "arguments": [ - "image.getName()", - "image.getUuid()" + "bandwidth", + "Long.MAX_VALUE" ], - "line": 502, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 795, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "zoneUuid must be set because the image[name:%s, uuid:%s] is on multiple backup storage", - "en_US": "zoneUuid must be set because the image[name:{0}, uuid:{1}] is on multiple backup storage", - "zh_CN": "zoneUuid必须被设置,因为image[name:{0}, uuid:{1}]在多个镜像服务器上", + "raw": "invalid network bandwidth[%s], it must be greater than or equal to 8192", + "en_US": "invalid network bandwidth[{0}], it must be greater than or equal to 8192", + "zh_CN": "错误的网络带宽[{0}],这个数字必须大于等于8K", "arguments": [ - "image.getName()", - "image.getUuid()" + "bandwidth" ], - "line": 542, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 745, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "unable to enable this function. There are multi nics of L3 network[uuid:%s] in the vm[uuid: %s]", - "en_US": "unable to enable this function. There are multi nics of L3 network[uuid:{0}] in the vm[uuid: {1}]", - "zh_CN": "", + "raw": "invalid volume bandwidth[%s] is not a number", + "en_US": "invalid volume bandwidth[{0}] is not a number", + "zh_CN": "错误的云盘带宽 ,[{0}] 这个不是数字", "arguments": [ - "tuple.get(0, String.class)", - "tuple.get(1, String.class)" + "bandwidth" ], - "line": 1453, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 793, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "hostname[%s] specified in system tag[%s] is not a valid domain name", - "en_US": "hostname[{0}] specified in system tag[{1}] is not a valid domain name", - "zh_CN": "在系统标签[{1}]中特别声明的主机名[{0}]不是一个有效的域名", + "raw": "invalid volume bandwidth[%s], it must be greater than 1024 (include 1024)", + "en_US": "invalid volume bandwidth[{0}], it must be greater than 1024 (include 1024)", + "zh_CN": "无效的云盘带宽,它必须大于等于1M", "arguments": [ - "hostname", - "tag" + "bandwidth" ], - "line": 1466, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 790, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "only one hostname system tag is allowed, but %s got", - "en_US": "only one hostname system tag is allowed, but {0} got", - "zh_CN": "只允许通过系统标签设置一个主机名,但是实际上有{0}", + "raw": "invalid volume IOPS[%s] is not a number", + "en_US": "invalid volume IOPS[{0}] is not a number", + "zh_CN": "错误的云盘每秒读写速度[{0}],它应该是个数字", "arguments": [ - "hostnameCount" + "iops" ], - "line": 1478, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 832, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "%s is not a valid IPv6 address. Please correct your system tag[%s] of static IP", - "en_US": "{0} is not a valid IPv6 address. Please correct your system tag[{1}] of static IP", - "zh_CN": "", + "raw": "invalid volume IOPS[%s] is larger than %d", + "en_US": "invalid volume IOPS[{0}] is larger than {1}", + "zh_CN": "云盘IOPS[{0}]大于{1}是无效的", "arguments": [ - "ip", - "sysTag" + "iops", + "Long.MAX_VALUE" ], - "line": 1514, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 834, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "%s is not a valid IPv4 address. Please correct your system tag[%s] of static IP", - "en_US": "{0} is not a valid IPv4 address. Please correct your system tag[{1}] of static IP", - "zh_CN": "{0}不是一个有效的IPv4地址。请修改你关于静态IP的系统标签", + "raw": "invalid volume IOPS[%s], it must be greater than 1 (include 1)", + "en_US": "invalid volume IOPS[{0}], it must be greater than 1 (include 1)", + "zh_CN": "卷IOPS[{0}]无效,它必须大于1(包括1)", "arguments": [ - "ip", - "sysTag" + "iops" ], - "line": 1508, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 829, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "IP[%s] is not available on the L3 network[uuid:%s] because: %s", - "en_US": "IP[{0}] is not available on the L3 network[uuid:{1}] because: {2}", - "zh_CN": "在L3网络[uuid:{1}]中,IP[{0}]不可用, 因为{2}", - "arguments": [ - "ip", - "l3Uuid", - "cr.getReason()" - ], - "line": 1530, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "raw": " usb device can only be called by admin account", + "en_US": " usb device can only be called by admin account", + "zh_CN": "USB设备只能由管理员帐户调用", + "arguments": [], + "line": 865, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "l3 network [uuid: %s] is added to vm more than once", - "en_US": "l3 network [uuid: {0}] is added to vm more than once", - "zh_CN": "", + "raw": "Unknown code[%s] of Security Level", + "en_US": "Unknown code[{0}] of Security Level", + "zh_CN": "安全级别的未知代码[{0}]", "arguments": [ - "uuid" + "level" ], - "line": 1573, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 901, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "there are %d ipv6 stateful network on same nic", - "en_US": "there are {0} ipv6 stateful network on same nic", - "zh_CN": "", + "raw": "[%s] is not a standard cidr", + "en_US": "[{0}] is not a standard cidr", + "zh_CN": "[{0}]不是标准CIDR", "arguments": [ - "statefulIpv6Count" + "cidr" ], - "line": 1567, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 918, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "L3 network[uuid:%s] not found. Please correct your system tag[%s] of dualStackNic", - "en_US": "L3 network[uuid:{0}] not found. Please correct your system tag[{1}] of dualStackNic", - "zh_CN": "", + "raw": "the host[uuid:%s]\u0027s operating system %s %s is too old, the QEMU doesn\u0027t support QoS of network or disk IO. Please choose another instance offering with no QoS configuration", + "en_US": "the host[uuid:{0}]\u0027s operating system {1} {2} is too old, the QEMU doesn\u0027t support QoS of network or disk IO. Please choose another instance offering with no QoS configuration", + "zh_CN": "物理机[uuid:{0}] 的操作系统{1} {2} 过老, QEMU 不支持云盘的QOS IO设置 。 请选择别的没有Qos的计算规格", "arguments": [ - "primaryL3Uuid", - "sysTag" + "hostUuid", + "os.distribution", + "os.version" ], - "line": 1590, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 939, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "L3 networks[primaryL3Uuid:%s, secondaryL3Uuid:%s] of dualStackNic is not on same l2 network", - "en_US": "L3 networks[primaryL3Uuid:{0}, secondaryL3Uuid:{1}] of dualStackNic is not on same l2 network", - "zh_CN": "", + "raw": "invalid value[%s], it\u0027s not a double", + "en_US": "invalid value[{0}], it\u0027s not a double", + "zh_CN": "错误的值[{0}],这个不是双精度值", "arguments": [ - "primaryL3Uuid", - "secondaryL3Uuid" + "newValue" ], - "line": 1595, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 1186, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "L3 networks[uuid:%s] does not have ip range", - "en_US": "L3 networks[uuid:{0}] does not have ip range", - "zh_CN": "", + "raw": "invalid value[%s], it must be a double greater than 0", + "en_US": "invalid value[{0}], it must be a double greater than 0", + "zh_CN": "错误的值[{0}],必须是一个大于0的双精度值", "arguments": [ - "secondaryL3Uuid" + "newValue" ], - "line": 1606, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 1154, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "conflict hostname in system tag[%s]; there has been a VM[uuid:%s] having hostname[%s] on L3 network[uuid:%s]", - "en_US": "conflict hostname in system tag[{0}]; there has been a VM[uuid:{1}] having hostname[{2}] on L3 network[uuid:{3}]", - "zh_CN": "系统标签的主机名存在冲突[{0}];已经存在以一个主机名为[{2}]的VM[uuid:{1}]出现在L3网络[uuid:{3}]中", + "raw": "invalid value[%s], it must be a double between (0, 1]", + "en_US": "invalid value[{0}], it must be a double between (0, 1]", + "zh_CN": "错误的值[{0}],这个必须在0~1之间的双精度值", "arguments": [ - "tag", - "sameTag.getResourceUuid()", - "hostname", - "l3Uuid" + "newValue" ], - "line": 1629, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 1183, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "invalid boot device[%s] in boot order[%s]", - "en_US": "invalid boot device[{0}] in boot order[{1}]", - "zh_CN": "在引导顺序[{1}]中存在无效的引导设备[{0}]", + "raw": "invalid value[%s], ZStack doesn\u0027t have such host allocator type", + "en_US": "invalid value[{0}], ZStack doesn\u0027t have such host allocator type", + "zh_CN": "错误值[{0}],Zstack没有这样的分配器类型", "arguments": [ - "o", - "order" + "newValue" ], - "line": 1662, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 1197, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "Already have one userdata systemTag for vm[uuid: %s].", - "en_US": "Already have one userdata systemTag for vm[uuid: {0}].", - "zh_CN": "在虚拟机[uuid:{0}]已经存在一个userdata的系统标签", + "raw": "%s value is[%s], which is conflict with %s value [%s]", + "en_US": "{0} value is[{1}], which is conflict with {2} value [{3}]", + "zh_CN": "{0}值为[{1}],与{2}值[{3}]冲突", "arguments": [ - "resourceUuid" + "MevocoGlobalConfig.AIO_NATIVE.getCanonicalName()", + "MevocoGlobalConfig.AIO_NATIVE.value()", + "KVMGlobalConfig.LIBVIRT_CACHE_MODE.getCanonicalName()", + "KVMGlobalConfig.LIBVIRT_CACHE_MODE.value()" ], - "line": 1680, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 1219, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "Shouldn\u0027t be more than one userdata systemTag for one vm.", - "en_US": "Shouldn\u0027t be more than one userdata systemTag for one vm.", - "zh_CN": "在一个虚拟机中不能存在多个userdata的系统标签", + "raw": "obj is not instanceof NicQos!", + "en_US": "obj is not instanceof NicQos!", + "zh_CN": "OBJ不是NICQoS的实例!", "arguments": [], - "line": 1700, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 1489, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "vm machine type requires [q35, pc], but get [%s]", - "en_US": "vm machine type requires [q35, pc], but get [{0}]", - "zh_CN": "", + "raw": "unexpected host management IPs: [%s]", + "en_US": "unexpected host management IPs: [{0}]", + "zh_CN": "意外的物理机管理IP:[{0}]", "arguments": [ - "type" + "String.join(\",\", ips)" ], - "line": 1823, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "line": 2054, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "the resource[uuid:%s] is a ROOT volume, you cannot change its owner, instead,change the owner of the VM the root volume belongs to", - "en_US": "the resource[uuid:{0}] is a ROOT volume, you cannot change its owner, instead,change the owner of the VM the root volume belongs to", - "zh_CN": "当前资源[uuid:{0}]是一个根云盘,你不能改变它的所有者,但是你能够修改对应VM的所有者", - "arguments": [ - "ref.getResourceUuid()" - ], - "line": 2235, - "fileName": "src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java" + "raw": "can not set local and configure at same time", + "en_US": "can not set local and configure at same time", + "zh_CN": "不能同时设置本地和配置", + "arguments": [], + "line": 2190, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "clean traffic is not supported for vm type [%s]", - "en_US": "clean traffic is not supported for vm type [{0}]", - "zh_CN": "", - "arguments": [ - "vmType" - ], - "line": 182, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "raw": "can not find node A config info", + "en_US": "can not find node A config info", + "zh_CN": "找不到节点A配置信息", + "arguments": [], + "line": 2242, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "Duplicate mac address [%s]", - "en_US": "Duplicate mac address [{0}]", - "zh_CN": "重复的MAC地址[{0}]", - "arguments": [ - "msg.getMac()" - ], - "line": 172, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "raw": "can not find node A address info from bootstrap agent", + "en_US": "can not find node A address info from bootstrap agent", + "zh_CN": "无法从启动代理中找到节点A地址信息", + "arguments": [], + "line": 2252, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "Can not set security level to not %s vm [uuid:%s]", - "en_US": "Can not set security level to not {0} vm [uuid:{1}]", - "zh_CN": "设置密级失败,无法对不处于{0}状态的虚拟机操作[uuid:{1}]", + "raw": "can not get bootstrap job %s result after 900s", + "en_US": "can not get bootstrap job {0} result after 900s", + "zh_CN": "无法在900秒后获取引导程序作业{0}结果", "arguments": [ - "VmInstanceState.Stopped", - "msg.getVmInstanceUuid()" + "s.getJobUuid()" ], - "line": 91, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" - }, - { - "raw": "The operation only allows on user vm", - "en_US": "The operation only allows on user vm", - "zh_CN": "", - "arguments": [], - "line": 108, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2314, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "there are not enough capacity for full vm clone to vm[uuid: %s], volumes[uuid: %s] on primary storage[uuid: %s] required: %s bytes, current available capacity is %s bytes", - "en_US": "there are not enough capacity for full vm clone to vm[uuid: {0}], volumes[uuid: {1}] on primary storage[uuid: {2}] required: {3} bytes, current available capacity is {4} bytes", - "zh_CN": "没有足够的空间对虚拟机[uuid: {0}]做整机克隆,主存储[uuid: {2}]上的云盘[uuid: {1}]共需要[{3}]字节的空间,目前主存储的可用空间为[{4}]字节", + "raw": "curl bootstrap agent finished, return code: %s, stdout: %s, stderr: %s", + "en_US": "curl bootstrap agent finished, return code: {0}, stdout: {1}, stderr: {2}", + "zh_CN": "cURL引导代理已完成,返回代码:{0},标准输出:{1},标准错误:{2}", "arguments": [ - "msg.getVmInstanceUuid()", - "volumeVOS.stream().map(VolumeVO::getUuid).collect(Collectors.toList())", - "primaryStorageUuid", - "(totalCapacity - snapshotsCapacity) * msg.getNames().size()", - "primaryStorageVO.getCapacity().getAvailableCapacity()" + "ret.getRetCode()", + "ret.getStdout()", + "ret.getStderr()" ], - "line": 138, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2322, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "The nic [%s%s] is not mounted on the VM", - "en_US": "The nic [{0}{1}] is not mounted on the VM", - "zh_CN": "网卡[{0}]不能被挂载到虚拟机上", + "raw": "node A update factory mode failed, details: %s", + "en_US": "node A update factory mode failed, details: {0}", + "zh_CN": "节点A更新工厂模式失败,详细信息:{0}", "arguments": [ - "msg.getVmNicUuid()" + "errorOfNodeA.getCauses().get(0)" ], - "line": 152, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2686, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "The operation only allows on user vm ", - "en_US": "The operation only allows on user vm ", - "zh_CN": "该操作只能在用户虚拟机上进行", - "arguments": [], - "line": 158, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "raw": "all management node update factory mode failed, details: %s", + "en_US": "all management node update factory mode failed, details: {0}", + "zh_CN": "所有管理节点更新工厂模式失败,详细信息:{0}", + "arguments": [ + "errorCodeList.getCauses().get(0)" + ], + "line": 2684, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "The operation only allows when vm [%s] state is stopped ", - "en_US": "The operation only allows when vm [{0}] state is stopped ", - "zh_CN": "该操作只有虚拟机[{0}]状态为已停止才能进行", + "raw": "management node status is not %s", + "en_US": "management node status is not {0}", + "zh_CN": "管理节点状态不是{0}", "arguments": [ - "vmInstanceVO.getUuid()" + "ManagementNodeState.RUNNING" ], - "line": 163, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2790, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "user has no privilege to change image of vm %s", - "en_US": "user has no privilege to change image of vm {0}", - "zh_CN": "当前用户不能修改虚拟机{0}的镜像", + "raw": "some node on factory mode exists, detail of arping: %s", + "en_US": "some node on factory mode exists, detail of arping: {0}", + "zh_CN": "工厂模式上的某些节点存在,ARPING的详细信息:{0}", "arguments": [ - "msg.getVmInstanceUuid()" + "r.getStdout()" ], - "line": 192, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2720, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "Can\u0027t change vm image when it\u0027s not stopped", - "en_US": "Can\u0027t change vm image when it\u0027s not stopped", - "zh_CN": "", + "raw": "set address on node A failed", + "en_US": "set address on node A failed", + "zh_CN": "在节点A上设置地址失败", "arguments": [], - "line": 205, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2741, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "Can\u0027t change vm image without L3 network", - "en_US": "Can\u0027t change vm image without L3 network", - "zh_CN": "", + "raw": "this node is not node A", + "en_US": "this node is not node A", + "zh_CN": "此节点不是节点A", "arguments": [], - "line": 211, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" - }, - { - "raw": "make sure the primary storage vm[uuid:%s] was on is Enabled and Connected", - "en_US": "make sure the primary storage vm[uuid:{0}] was on is Enabled and Connected", - "zh_CN": "确认主存储[uuid:{0}]是可用的且已连接", - "arguments": [ - "msg.getVmInstanceUuid()" - ], - "line": 226, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2738, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "make sure the last host vm[uuid:%s] was on is Enabled and Connected", - "en_US": "make sure the last host vm[uuid:{0}] was on is Enabled and Connected", - "zh_CN": "确定物理机[uuid:{0}]是可用的且已连接", + "raw": "networkInboundBandwidth format error %s", + "en_US": "networkInboundBandwidth format error {0}", + "zh_CN": "下行网络带宽格式错误{0}", "arguments": [ - "msg.getVmInstanceUuid()" + "bandwidth" ], - "line": 241, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2875, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "user has no privilege to change root volume of vm %s using image %s", - "en_US": "user has no privilege to change root volume of vm {0} using image {1}", - "zh_CN": "当前用户不能修改使用镜像{1}的虚拟机{0}的根云盘", + "raw": "networkOutboundBandwidth format error %s", + "en_US": "networkOutboundBandwidth format error {0}", + "zh_CN": "上行网络带宽超格式错误{0}", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getImageUuid()" + "bandwidth" ], - "line": 260, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2887, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "either uuid or account or password must be set", - "en_US": "either uuid or account or password must be set", - "zh_CN": "uuid或者账户或者密码需要被设置", + "raw": "networkOutboundBandwidth execeds the max value 32G bps", + "en_US": "networkOutboundBandwidth execeds the max value 32G bps", + "zh_CN": "超过上行网络带宽超过最大值32G bps", "arguments": [], - "line": 271, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 2884, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "direction must be set in (in, out), but was %s", - "en_US": "direction must be set in (in, out), but was {0}", - "zh_CN": "方向必须设置在(in, out),但是输入的是{0}", + "raw": "Shareable Volume[uuid:%s] has already been attached to VM[uuid:%s]", + "en_US": "Shareable Volume[uuid:{0}] has already been attached to VM[uuid:{1}]", + "zh_CN": "共享云盘[uuid:{0}]已经挂载到云主机[uuid:{1}]上", "arguments": [ - "msg.getDirection()" + "volume.getUuid()", + "vm.getUuid()" ], - "line": 279, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" - }, - { - "raw": "Monitor number must be 1 or 2 or 4.", - "en_US": "Monitor number must be 1 or 2 or 4.", - "zh_CN": "监听器数量必须是1、2或4", - "arguments": [], - "line": 285, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 3060, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "outboundBandwidth and inboundBandwidth must be set at lease one.", - "en_US": "outboundBandwidth and inboundBandwidth must be set at lease one.", - "zh_CN": "上行带宽和下行带宽至少有一个需要被设置", + "raw": "shareable disk only support virtio-scsi type for now", + "en_US": "shareable disk only support virtio-scsi type for now", + "zh_CN": "目前共享盘只支持virtio-scsi", "arguments": [], - "line": 293, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 3078, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "the nic can\u0027t apply Qos with the port mirror service at same time.", - "en_US": "the nic can\u0027t apply Qos with the port mirror service at same time.", - "zh_CN": "", - "arguments": [], - "line": 302, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "raw": "shareable volume(s)[uuid: %s] attached, not support to group snapshot.", + "en_US": "shareable volume(s)[uuid: {0}] attached, not support to group snapshot.", + "zh_CN": "可共享云盘[uuid:{0}]已连接,但不支持组快照。", + "arguments": [ + "sharedVolUuids" + ], + "line": 3213, + "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" }, { - "raw": "nic id: %s does not exist...", - "en_US": "nic id: {0} does not exist...", - "zh_CN": "网卡id: {0}不存在", + "raw": "invalid volume qos mode: %s", + "en_US": "invalid volume qos mode: {0}", + "zh_CN": "无效的卷QoS模式:{0}", "arguments": [ - "msg.getUuid()" + "msg.getMode()" ], - "line": 311, - "fileName": "src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java" + "line": 1811, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "unsupported host allocation strategy[%s]", - "en_US": "unsupported host allocation strategy[{0}]", - "zh_CN": "不被支持的主机分配策略[{0}]", + "raw": "Failed set iothread[%d] pin[%s] on vm[%s]: %s.", + "en_US": "Failed set iothread[{0}] pin[{1}] on vm[{2}]: {3}.", + "zh_CN": "无法在VM[{2}]上设置IOThread[{0}]Pin[{1}]:{3}。", "arguments": [ - "msg.getAllocatorStrategy()" + "msg.getIoThreadId()", + "msg.getPin()", + "vm.getUuid()", + "rsp.getError()" ], - "line": 86, - "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + "line": 284, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "unsupported instance offering type[%s]", - "en_US": "unsupported instance offering type[{0}]", - "zh_CN": "不被支持的计算规格类型[{0}]", + "raw": "can not found in used snapshot tree of volume[uuid: %s]. Maybe no snapshot chain need to validate.", + "en_US": "can not found in used snapshot tree of volume[uuid: {0}]. Maybe no snapshot chain need to validate.", + "zh_CN": "在卷[uuid:{0}]的已使用快照树中找不到。可能不需要验证快照链。", "arguments": [ - "msg.getType()" + "msg.getUuid()" ], - "line": 72, - "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + "line": 339, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "cpu num[%s] is less than 1", - "en_US": "cpu num[{0}] is less than 1", - "zh_CN": "cpu数量[{0}]少于1", + "raw": "can not found latest snapshot from tree[uuid: %s] of volume[uuid: %s]. Maybe no snapshot chain need to validate.", + "en_US": "can not found latest snapshot from tree[uuid: {0}] of volume[uuid: {1}]. Maybe no snapshot chain need to validate.", + "zh_CN": "从树[uuid:{0}](属于卷[uuid:{1}])中找不到最新快照。可能不需要验证快照链。", "arguments": [ - "msg.getCpuNum()" + "currentTreeUuid", + "msg.getUuid()" ], - "line": 76, - "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + "line": 352, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "memory size[%s bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size", - "en_US": "memory size[{0} bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size", - "zh_CN": "内存大小[{0} bytes]少于16M,没有一个现代操作系统能够在如此小的内存里被引导", + "raw": "can not found snapshots from tree[uuid: %s] of volume[uuid: %s]. Maybe no snapshot chain need to validate.", + "en_US": "can not found snapshots from tree[uuid: {0}] of volume[uuid: {1}]. Maybe no snapshot chain need to validate.", + "zh_CN": "从树[uuid:{0}](属于卷[uuid:{1}])中找不到快照。可能不需要验证快照链。", "arguments": [ - "msg.getMemorySize()" + "currentTreeUuid", + "msg.getUuid()" ], - "line": 80, - "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + "line": 368, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "unsupported primary storage allocation strategy[%s]", - "en_US": "unsupported primary storage allocation strategy[{0}]", - "zh_CN": "不被支持的主存储分配策略[{0}]", + "raw": "How can a Running VM[uuid:%s] has no hostUuid?", + "en_US": "How can a Running VM[uuid:{0}] has no hostUuid?", + "zh_CN": "正在运行的VM[uuid:{0}]怎么会没有HOSTuuid?", "arguments": [ - "msg.getAllocationStrategy()" + "vmInstanceVO.getUuid()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java" + "line": 678, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "the console agent is not connected; it\u0027s mostly like the management node just starts, please wait for the console agent connected, or you can reconnect it manually if disconnected for a long time.", - "en_US": "the console agent is not connected; it\u0027s mostly like the management node just starts, please wait for the console agent connected, or you can reconnect it manually if disconnected for a long time.", - "zh_CN": "控制台代理失联,很有可能管理节点刚刚启动,请等待控制台代理的连接,如果长时间没有连上可以尝试手动重连控制台代理。", - "arguments": [], - "line": 101, - "fileName": "src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java" + "raw": "Unexpectedly, VM[uuid:%s] is not running any more, please try again later", + "en_US": "Unexpectedly, VM[uuid:{0}] is not running any more, please try again later", + "zh_CN": "意外的是,VM[uuid:{0}]不再运行,请稍后再试", + "arguments": [ + "vmInstanceVO.getUuid()" + ], + "line": 676, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "cannot find host IP of the vm[uuid:%s], is the vm running???", - "en_US": "cannot find host IP of the vm[uuid:{0}], is the vm running???", - "zh_CN": "无法找到vm[uuid:{0}]的主机IP,请确认该vm是否在运行???", + "raw": "after subtracting reserved capacity[%s], primary storage[%s] don\u0027t have required size[%s bytes], may be the threshold of primary storage physical capacity setting is lower", + "en_US": "after subtracting reserved capacity[{0}], primary storage[{1}] don\u0027t have required size[{2} bytes], may be the threshold of primary storage physical capacity setting is lower", + "zh_CN": "减去保留容量[{0}]后,主存储[{1}]没有所需的大小[{2}字节],可能是主存储物理容量设置的阈值较低", "arguments": [ - "vm.getUuid()" + "PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value()", + "errorInfoMap.keySet()", + "errorInfoMap.values()" ], - "line": 122, - "fileName": "src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java" + "line": 842, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "Console is only available when the VM[uuid:%s] is Running, but the current state is %s", - "en_US": "Console is only available when the VM[uuid:{0}] is Running, but the current state is {1}", - "zh_CN": "仅当VM[uuid:{0}]处于运行状态时控制台可用,但是现在的状态为{1}", + "raw": "can not take snapshot for volumes[%s] while volume[uuid: %s] not attached", + "en_US": "can not take snapshot for volumes[{0}] while volume[uuid: {1}] not attached", + "zh_CN": "当云盘[uuid:{1}]未加载时,无法给云盘[{0}]创建快照", "arguments": [ - "msg.getVmInstanceUuid()", - "state" + "msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList())", + "job.getVolumeUuid()" ], - "line": 52, - "fileName": "src/main/java/org/zstack/console/ConsoleApiInterceptor.java" + "line": 1231, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "establish VNC: unexpected uri: %s", - "en_US": "establish VNC: unexpected uri: {0}", - "zh_CN": "", + "raw": "can not take snapshot for volumes[%s] while volume[uuid: %s] appears twice", + "en_US": "can not take snapshot for volumes[{0}] while volume[uuid: {1}] appears twice", + "zh_CN": "当云盘[uuid:{1}]出现多次时,无法给云盘[{0}]创建快照", "arguments": [ - "uri.toString()" + "msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList())", + "job.getVolumeUuid()" ], - "line": 62, - "fileName": "src/main/java/org/zstack/console/ConsoleProxyBase.java" + "line": 1237, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "unable to check console proxy availability, because %s", - "en_US": "unable to check console proxy availability, because {0}", - "zh_CN": "无法检查控制台代理是否可用,因为{0}", + "raw": "can not take snapshot for volumes[%s] attached multiple vms[%s, %s]", + "en_US": "can not take snapshot for volumes[{0}] attached multiple vms[{1}, {2}]", + "zh_CN": "当云盘[uuid:{1}]加载到多个云主机上时,无法给云盘[{0}]创建快照", "arguments": [ - "ret.getError()" + "msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList())", + "job.getVolumeUuid()", + "volumeVOS.get(0).getVmInstanceUuid()" ], - "line": 148, - "fileName": "src/main/java/org/zstack/console/ConsoleProxyBase.java" + "line": 1244, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "Ansible private key not found.", - "en_US": "Ansible private key not found.", - "zh_CN": "", + "raw": "no volumes found", + "en_US": "no volumes found", + "zh_CN": "找不到云盘", "arguments": [], - "line": 153, - "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + "line": 1251, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "invalid management node UUID[%s]", - "en_US": "invalid management node UUID[{0}]", - "zh_CN": "非法的管理节点UUID[{0}]", + "raw": "this snapshot recording the volume state before resize to %fG is created automatically", + "en_US": "this snapshot recording the volume state before resize to {0}G is created automatically", + "zh_CN": "该快照记录云盘扩容到{0}G之前的状态,由系统自动创建", "arguments": [ - "uuid" + "SizeUnit.BYTE.toGigaByte((double) resize)" ], - "line": 347, - "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + "line": 1516, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "failed to configure consoleProxyOverriddenIp", - "en_US": "failed to configure consoleProxyOverriddenIp", - "zh_CN": "设置consoleProxyOverriddenIp失败", - "arguments": [], - "line": 468, - "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + "raw": "DeleteVolumeQos [%s] ignore because of account privilege.", + "en_US": "DeleteVolumeQos [{0}] ignore because of account privilege.", + "zh_CN": "DeleteVolumeQoS[{0}]由于帐户权限而忽略。", + "arguments": [ + "msg.getUuid()" + ], + "line": 1823, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + }, + { + "raw": "Cannot delete vm\u0027s volume qos on host %s, because the current vm is in state of %s, but support expect states are [%s, %s]", + "en_US": "Cannot delete vm\u0027s volume qos on host {0}, because the current vm is in state of {1}, but support expect states are [{2}, {3}]", + "zh_CN": "无法在物理机{0}上删除VM的卷QoS,因为当前VM的状态为{1},但支持的预期状态为[{2},{3}]", + "arguments": [ + "ivo.getHostUuid()", + "ivo.getState()", + "VmInstanceState.Running.toString()", + "VmInstanceState.Stopped.toString()" + ], + "line": 1891, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + }, + { + "raw": "non admin account cannot set bandwidth more than %s", + "en_US": "non admin account cannot set bandwidth more than {0}", + "zh_CN": "非管理员帐户无法设置大于{0}的带宽", + "arguments": [ + "VolumeQos.getVolumeQosByMode(self.getVolumeQos(), mode)" + ], + "line": 2039, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "failed to reconnect console proxy", - "en_US": "failed to reconnect console proxy", - "zh_CN": "重连控制台代理失败", + "raw": "unknown message version.", + "en_US": "unknown message version.", + "zh_CN": "未知消息版本。", "arguments": [], - "line": 491, - "fileName": "src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java" + "line": 2051, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "User name or password or port number may be problematic", - "en_US": "User name or password or port number may be problematic", - "zh_CN": "用户名、密码或者端口可能是错误的", + "raw": "unknown qos limit type.", + "en_US": "unknown qos limit type.", + "zh_CN": "未知的QoS限制类型。", "arguments": [], - "line": 397, - "fileName": "src/main/java/org/zstack/core/ansible/AnsibleRunner.java" + "line": 2068, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "cannot nmap from agent: %s to callback address: %s:%s", - "en_US": "cannot nmap from agent: {0} to callback address: {1}:{2}", - "zh_CN": "", + "raw": "Non-admin account is only allowed to set the total %s limit.", + "en_US": "Non-admin account is only allowed to set the total {0} limit.", + "zh_CN": "仅允许非管理员帐户设置总{0}限制。", "arguments": [ - "targetIp", - "callbackIp", - "callBackPort" + "limitType" ], - "line": 70, - "fileName": "src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java" + "line": 2082, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "cannot check md5sum of files in the folder[%s].\\nstdout:%s\\nstderr:%s", - "en_US": "cannot check md5sum of files in the folder[{0}].\\nstdout:{1}\\nstderr:{2}", - "zh_CN": "无法检查文件夹[{0}]下文件的md5sum.\\nstdout:{1}\\nstderr:{2}", + "raw": "Non-admin account cannot set the total %s limits as unlimited.", + "en_US": "Non-admin account cannot set the total {0} limits as unlimited.", + "zh_CN": "非管理员帐户无法将总{0}限制设置为无限制。", "arguments": [ - "srcFolder", - "srcRes.getStdout()", - "srcRes.getStderr()" + "limitType.getType()" ], - "line": 106, - "fileName": "src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java" + "line": 2091, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "cannot check md5sum of files in the folder[%s] on the host[ip:%s].\\nstdout:%s\\nstderr:%s", - "en_US": "cannot check md5sum of files in the folder[{0}] on the host[ip:{1}].\\nstdout:{2}\\nstderr:{3}", - "zh_CN": "无法检查主机[ip:{1}]的文件夹[{0}]下文件的md5sum.\\nstdout:{2}\\nstderr:{3}", + "raw": "Non-admin account cannot set the total %s limit greater than: %s", + "en_US": "Non-admin account cannot set the total {0} limit greater than: {1}", + "zh_CN": "非管理员帐户无法将总{0}限制设置为大于:{1}", "arguments": [ - "dstFolder", - "hostname", - "dstRes.getStdout()", - "dstRes.getStderr()" + "limitType.getType()", + "totalLimit" ], - "line": 121, - "fileName": "src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java" + "line": 2095, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "message is not in corrected JSON mediaType, %s", - "en_US": "message is not in corrected JSON mediaType, {0}", - "zh_CN": "消息是错误的JSON格式,{0}", + "raw": "Non-admin account is only allowed to set the read/write %s limits.", + "en_US": "Non-admin account is only allowed to set the read/write {0} limits.", + "zh_CN": "仅允许非管理员帐户设置读/写{0}限制。", "arguments": [ - "errMsg" + "limitType.getType()" ], - "line": 681, - "fileName": "src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java" + "line": 2102, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "HTTP ERROR, status code: %s, body: %s", - "en_US": "HTTP ERROR, status code: {0}, body: {1}", - "zh_CN": "", + "raw": "Non-admin account cannot set the read %s limits as unlimited.", + "en_US": "Non-admin account cannot set the read {0} limits as unlimited.", + "zh_CN": "非管理员帐户无法将读取{0}限制设置为无限制。", "arguments": [ - "rsp.getStatusCode()", - "rsp.getBody()" + "limitType.getType()" ], - "line": 543, - "fileName": "src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java" + "line": 2108, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "for webhooks with type[%s], the field opaque cannot be null", - "en_US": "for webhooks with type[{0}], the field opaque cannot be null", - "zh_CN": "对于[{0}]类型的webhooks,opaque字段不能为null", + "raw": "Non-admin account cannot set the write %s limits as unlimited.", + "en_US": "Non-admin account cannot set the write {0} limits as unlimited.", + "zh_CN": "非管理员帐户无法将写入{0}限制设置为无限制。", "arguments": [ - "EventFacade.WEBHOOK_TYPE" + "limitType.getType()" ], - "line": 68, - "fileName": "src/main/java/org/zstack/core/cloudbus/EventFacadeImpl.java" + "line": 2119, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "Unable to find GlobalConfig[category: %s, name: %s]", - "en_US": "Unable to find GlobalConfig[category: {0}, name: {1}]", - "zh_CN": "无法找到全局变量[category:{0}, name:{1}]", + "raw": "Non-admin account cannot set the read/write %s limits greater than: %s/%s", + "en_US": "Non-admin account cannot set the read/write {0} limits greater than: {1}/{2}", + "zh_CN": "非管理员帐户无法将读/写{0}限制设置为大于:{1}/{2}", "arguments": [ - "msg.getCategory()", - "msg.getName()" + "limitType.getType()", + "readLimit", + "writeLimit" ], - "line": 90, - "fileName": "src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java" - }, - { - "raw": "non file or jsoncontent input", - "en_US": "non file or jsoncontent input", - "zh_CN": "", - "arguments": [], - "line": 77, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" - }, - { - "raw": "file or jsoncontent cannot both nonempty", - "en_US": "file or jsoncontent cannot both nonempty", - "zh_CN": "", - "arguments": [], - "line": 82, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "line": 2128, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "Unable to scan folder: %s", - "en_US": "Unable to scan folder: {0}", - "zh_CN": "", + "raw": "volume [%s] isn\u0027t attached to any vm, cannot get qos by forceSync", + "en_US": "volume [{0}] isn\u0027t attached to any vm, cannot get qos by forceSync", + "zh_CN": "卷[{0}]未连接到任何VM,无法通过ForceSync获得QoS", "arguments": [ - "e.getMessage()" + "self.getUuid()" ], - "line": 114, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "line": 2215, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "%s is not existed or is empty folder", - "en_US": "{0} is not existed or is empty folder", - "zh_CN": "", + "raw": "volume [%s] isn\u0027t attached to any vm (or vm is not existed now), cannot sync volume qos", + "en_US": "volume [{0}] isn\u0027t attached to any vm (or vm is not existed now), cannot sync volume qos", + "zh_CN": "卷[{0}]未连接到任何VM(或VM现在不存在),无法同步卷QoS", "arguments": [ - "filename" + "self.getUuid()" ], - "line": 118, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "line": 2221, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "elaboration code must be number!", - "en_US": "elaboration code must be number!", - "zh_CN": "", - "arguments": [], - "line": 255, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "raw": "vm [%s]\u0027 state must be Running or Paused to sync volume qos", + "en_US": "vm [{0}]\u0027 state must be Running or Paused to sync volume qos", + "zh_CN": "VM[{0}]状态必须为“正在运行”或“已暂停”才能同步卷QoS", + "arguments": [ + "vm.getUuid()" + ], + "line": 2226, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "arg \u0027startTime\u0027 should format like \u0027yyyy-MM-dd HH:mm:ss\u0027 or \u00271545380003000\u0027", - "en_US": "arg \u0027startTime\u0027 should format like \u0027yyyy-MM-dd HH:mm:ss\u0027 or \u00271545380003000\u0027", - "zh_CN": "", + "raw": "vm [%s]\u0027s HostUuid is null, cannot sync volume qos", + "en_US": "vm [{0}]\u0027s HostUuid is null, cannot sync volume qos", + "zh_CN": "VM[{0}]的HostUuid为空,无法同步卷QoS", "arguments": [], - "line": 328, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "line": 2231, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "%s is not a Long value Number", - "en_US": "{0} is not a Long value Number", - "zh_CN": "", + "raw": "failed to detach shareable volume[uuid:%s] from VmInstance[uuid:%s]", + "en_US": "failed to detach shareable volume[uuid:{0}] from VmInstance[uuid:{1}]", + "zh_CN": "不能卸载云主机[uuid:{1}]上的共享盘[uuid:{0}]", "arguments": [ - "from" + "msg.getVolume().getUuid()", + "msg.getVmInstanceUuid()" ], - "line": 325, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "line": 2377, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "%s: %s", - "en_US": "{0}: {1}", - "zh_CN": "", + "raw": "failed to detach shareable volume from VmInstance:[\\n%s]", + "en_US": "failed to detach shareable volume from VmInstance because:[\\n{0}]", + "zh_CN": "不能卸载云主机上的共享盘,原因是{0}", "arguments": [ - "returnValue.get(0).getContent()", - "returnValue.get(0).getReason()" + "StringUtils.join(errors, \"\\n\\n\")" ], - "line": 368, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "line": 2389, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" }, { - "raw": "input args \u0027regex\u0027 or \u0027category\u0027 must be set", - "en_US": "input args \u0027regex\u0027 or \u0027category\u0027 must be set", - "zh_CN": "", - "arguments": [], - "line": 476, - "fileName": "src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java" + "raw": "unsupported operation for setting root volume[%s] multiQueues.", + "en_US": "unsupported operation for setting root volume[{0}] multiQueues.", + "zh_CN": "不支持设置根卷[{0}]多队列的操作。", + "arguments": [ + "resourceUuid" + ], + "line": 89, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeFactoryImpl.java" }, { - "raw": "service[%s] has been registered", - "en_US": "service[{0}] has been registered", - "zh_CN": "服务(service)[{0}]已经被注册", + "raw": "unsupported operation for setting virtio-scsi volume[%s] multiQueues.", + "en_US": "unsupported operation for setting virtio-scsi volume[{0}] multiQueues.", + "zh_CN": "不支持设置virtio-SCSI卷[{0}]多队列的操作。", "arguments": [ - "service.getName()" + "resourceUuid" ], - "line": 17, - "fileName": "src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java" + "line": 93, + "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeFactoryImpl.java" }, { - "raw": "cannot trigger a finished GC job[uuid:%s, name:%s]", - "en_US": "cannot trigger a finished GC job[uuid:{0}, name:{1}]", - "zh_CN": "无法触发一个完成过的GC任务", + "raw": "ZStack has been paused, reject all API which are not read only. If you really want to call it and known the consequence, add \u0027%s\u0027 into systemTags.", + "en_US": "ZStack has been paused, reject all API which are not read only. If you really want to call it and known the consequence, add \u0027{0}\u0027 into systemTags.", + "zh_CN": "ZStack已暂停,拒绝所有非只读API。如果您确实想调用它并且知道结果,请将“{0}”添加到SystemTags中。", "arguments": [ - "vo.getUuid()", - "vo.getName()" + "MevocoSystemTags.CONFIRM_CALL_API.getTagFormat()" ], - "line": 244, - "fileName": "src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java" + "line": 46, + "fileName": "src/main/java/org/zstack/mevoco/PauseWorldApiInterceptor.java" }, { - "raw": "parameter apiId[%s] is not a valid uuid.", - "en_US": "parameter apiId[{0}] is not a valid uuid.", - "zh_CN": "参数apiId[{0}]不是一个有效的UUID", + "raw": "the current version of license does not support modifying this global config [name:%s]", + "en_US": "the current version of license does not support modifying this global config [name:{0}]", + "zh_CN": "当前license版本不支持修改此全局设置[name:{0}]", "arguments": [ - "msg.getApiId()" + "getName()" ], - "line": 38, - "fileName": "src/main/java/org/zstack/core/progress/ProgressApiInterceptor.java" + "line": 27, + "fileName": "src/main/java/org/zstack/mevoco/PremiumGlobalConfig.java" }, { - "raw": "failed to %s to %s, status code: %s, response body: %s", - "en_US": "failed to {0} to {1}, status code: {2}, response body: {3}", - "zh_CN": "访问{1}时执行{0}方法失败,状态码: {2},响应体: {3}", + "raw": "the current version of license does not support modifying this resource config [name:%s]", + "en_US": "the current version of license does not support modifying this resource config [name:{0}]", + "zh_CN": "当前版本的许可证不支持修改此资源配置[名称:{0}]", "arguments": [ - "method.toString().toLowerCase()", - "url", - "rsp.getStatusCode()", - "rsp.getBody()" + "globalConfig.getName()" ], - "line": 526, - "fileName": "src/main/java/org/zstack/core/rest/RESTFacadeImpl.java" + "line": 22, + "fileName": "src/main/java/org/zstack/mevoco/PremiumResourceConfig.java" }, { - "raw": "failed to %s to %s, IO Error: %s", - "en_US": "failed to {0} to {1}, IO Error: {2}", - "zh_CN": "访问{1}时执行{0}方法失败,IO错误: {2}", + "raw": "cannot find mode from null VolumeQos", + "en_US": "cannot find mode from null VolumeQos", + "zh_CN": "无法从NULL卷中找到模式QoS", + "arguments": [], + "line": 331, + "fileName": "src/main/java/org/zstack/mevoco/VolumeQos.java" + }, + { + "raw": "cannot find monitor trigger[uuid:%s], it may have been deleted", + "en_US": "cannot find monitor trigger[uuid:{0}], it may have been deleted", + "zh_CN": "不能找到触发监控器[uuid:{0}],它可能已经被删除了", "arguments": [ - "method.toString().toLowerCase()", - "url", - "e.getMessage()" + "msg.getMonitorTriggerUuid()" ], - "line": 513, - "fileName": "src/main/java/org/zstack/core/rest/RESTFacadeImpl.java" + "line": 190, + "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" }, { - "raw": "unable to echo %s in %sms", - "en_US": "unable to echo {0} in {1}ms", - "zh_CN": "无法在{1}ms内返回{0}", + "raw": "cannot find monitor trigger action[uuid:%s], it may have been deleted", + "en_US": "cannot find monitor trigger action[uuid:{0}], it may have been deleted", + "zh_CN": "为找到这个监控触发行为[uuid:{0}],它可能已经被删除了", "arguments": [ - "url", - "finalTimeout" + "msg.getMonitorTriggerActionUuid()" ], - "line": 569, - "fileName": "src/main/java/org/zstack/core/rest/RESTFacadeImpl.java" + "line": 199, + "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" }, { - "raw": "an operation[%s] fails after retrying %s times with the interval %s seconds", - "en_US": "an operation[{0}] fails after retrying {1} times with the interval {2} seconds", - "zh_CN": "在重试{1}次间隔时间为{2}后操作[{0}]失败", + "raw": "the resource[type:%s] doesn\u0027t have any monitoring items", + "en_US": "the resource[type:{0}] doesn\u0027t have any monitoring items", + "zh_CN": "该资源[type:{0}]没有任何监控条目", "arguments": [ - "__name__", - "times", - "interval" + "msg.getResourceType()" ], - "line": 102, - "fileName": "src/main/java/org/zstack/core/retry/Retry.java" + "line": 243, + "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" }, { - "raw": "failed to run salt state[%s] on system[%s], failed after %s retries", - "en_US": "failed to run salt state[{0}] on system[{1}], failed after {2} retries", - "zh_CN": "重试{2}次之后,在系统[{1}]上运行加盐状态[{0}]失败", + "raw": "the resource[uuid:%s] doesn\u0027t belong to the account[uuid:%s]", + "en_US": "the resource[uuid:{0}] doesn\u0027t belong to the account[uuid:{1}]", + "zh_CN": "该资源[uuid:{0}]不属于账户[uuid:{1}]", "arguments": [ - "stateName", - "targetIp", - "retry" + "msg.getTargetResourceUuid()", + "msg.getSession().getAccountUuid()" ], - "line": 296, - "fileName": "src/main/java/org/zstack/core/salt/SaltRunner.java" + "line": 335, + "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" }, { - "raw": "scp is not found on system[%s], unable to setup salt", - "en_US": "scp is not found on system[{0}], unable to setup salt", - "zh_CN": "", + "raw": "cannot find type for the resource[uuid:%s]", + "en_US": "cannot find type for the resource[uuid:{0}]", + "zh_CN": "未找到资源[uuid:{0}]这种类型", "arguments": [ - "targetIp" + "resourceUuid" ], - "line": 84, - "fileName": "src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java" + "line": 386, + "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" }, { - "raw": "api timeout cannot be set smaller than %s", - "en_US": "api timeout cannot be set smaller than {0}", - "zh_CN": "", + "raw": "no monitoring item found for the resourceType[%s] and item[%s]", + "en_US": "no monitoring item found for the resourceType[{0}] and item[{1}]", + "zh_CN": "未找到资源类型[{0}]和条目[{1}]这种监控条目", "arguments": [ - "ApiTimeoutGlobalProperty.MINIMAL_TIMEOUT" + "resourceType", + "triggerExpression.getItem()" ], - "line": 81, - "fileName": "src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java" + "line": 391, + "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" }, { - "raw": "Invalid url[%s]", - "en_US": "Invalid url[{0}]", - "zh_CN": "无效的URL[{0}]", + "raw": "A resource[name:{resourceName}, uuid:{resourceUuid}, type:{resourceType}]\u0027s monitoring trigger[uuid:{triggerUuid}] changes status to {triggerStatus}", + "en_US": "A resource[name:{resourceName}, uuid:{resourceUuid}, type:{resourceType}]\u0027s monitoring trigger[uuid:{triggerUuid}] changes status to {triggerStatus}", + "zh_CN": "资源[name:{resourceName}, uuid:{resourceUuid}, type:{resourceType}]的监听触发器[uuid:{triggerUuid}]修改状态为{triggerStatus}", "arguments": [ - "url" + "args" ], - "line": 28, - "fileName": "src/main/java/org/zstack/core/webhook/WebhookApiInterceptor.java" + "line": 50, + "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" }, { - "raw": "parameters [accountUuid] only can be used by admin user!", - "en_US": "parameters [accountUuid] only can be used by admin user!", - "zh_CN": "参数[accountUuid]必须被admin用户设置", + "raw": "\\n\u003d\u003d\u003d BELOW ARE DETAILS OF THE PREVIOUS ALERT \u003d\u003d\u003d", + "en_US": "\\n\u003d\u003d\u003d BELOW ARE DETAILS OF THE PREVIOUS ALERT \u003d\u003d\u003d", + "zh_CN": "\\n\u003d\u003d\u003d 以下是上一次警告内容 \u003d\u003d\u003d", "arguments": [], - "line": 99, - "fileName": "src/main/java/org/zstack/daho/core/DahoApiInterceptor.java" + "line": 55, + "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" }, { - "raw": "expire policy: %s is not valid", - "en_US": "expire policy: {0} is not valid", - "zh_CN": "无效的过期策略:{0}", - "arguments": [ - "msg.getExpirePolicy()" - ], - "line": 54, - "fileName": "src/main/java/org/zstack/daho/core/DahoApiInterceptor.java" + "raw": "\\nalert details:", + "en_US": "\\nalert details:", + "zh_CN": "\\n警告内容: ", + "arguments": [], + "line": 58, + "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" }, { - "raw": "vlanId[%s] has been existed!", - "en_US": "vlanId[{0}] has been existed!", - "zh_CN": "", + "raw": "\\ncondition: {itemName} {operator} {threshold}", + "en_US": "\\ncondition: {itemName} {operator} {threshold}", + "zh_CN": "\\n环境: {itemName} {operator} {threshold}", "arguments": [ - "msg.getVlan()" + "args" ], - "line": 57, - "fileName": "src/main/java/org/zstack/daho/core/DahoApiInterceptor.java" - }, - { - "raw": "create daho vll task failed!", - "en_US": "create daho vll task failed!", - "zh_CN": "创建daho vll任务失败", - "arguments": [], - "line": 129, - "fileName": "src/main/java/org/zstack/daho/core/DahoSdkImpl.java" + "line": 59, + "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" }, { - "raw": "no aliyun account found for accountUuid: %s", - "en_US": "no aliyun account found for accountUuid: {0}", - "zh_CN": "找不到当前账户{0}对应的阿里云账户", + "raw": "\\ncurrent value: {value}", + "en_US": "\\ncurrent value: {value}", + "zh_CN": "\\n当前值: {value}", "arguments": [ - "msg.getAccountUuid()" + "args" ], - "line": 170, - "fileName": "src/main/java/org/zstack/daho/core/DahoSdkImpl.java" + "line": 60, + "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" }, { - "raw": "Advice not allowed while scheduling", - "en_US": "Advice not allowed while scheduling", - "zh_CN": "", + "raw": "Host CPU utilization", + "en_US": "Host CPU utilization", + "zh_CN": "CPU使用率", "arguments": [], - "line": 201, - "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + "line": 31, + "fileName": "src/main/java/org/zstack/monitoring/items/host/HostCpuUtilItem.java" }, { - "raw": "delete DRS is not allowed while the vm is being migrated", - "en_US": "delete DRS is not allowed while the vm is being migrated", - "zh_CN": "", + "raw": "VM CPU utilization", + "en_US": "VM CPU utilization", + "zh_CN": "云主机CPU使用率", "arguments": [], - "line": 264, - "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + "line": 29, + "fileName": "src/main/java/org/zstack/monitoring/items/vm/VmCpuUtilItem.java" }, { - "raw": "Scheduling is not allowed while the vm is being migrated", - "en_US": "Scheduling is not allowed while the vm is being migrated", - "zh_CN": "", - "arguments": [], - "line": 324, - "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + "raw": "fail to create new File[%s]", + "en_US": "fail to create new File[{0}]", + "zh_CN": "无法创建新文件[{0}]", + "arguments": [ + "ruleFile" + ], + "line": 98, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java" }, { - "raw": "Lack of host CPU, memory monitoring data", - "en_US": "Lack of host CPU, memory monitoring data", - "zh_CN": "", - "arguments": [], - "line": 435, - "fileName": "src/main/java/org/zstack/drs/DRSBase.java" + "raw": "conflict alert rule[%s], there has been a rule[%s] with the same name", + "en_US": "conflict alert rule[{0}], there has been a rule[{1}] with the same name", + "zh_CN": "冲突提示规则[{0}],这里已经存在和它一样名称的规则", + "arguments": [ + "rb.name", + "r" + ], + "line": 143, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java" }, { - "raw": "The cluster[%s] has created DRS", - "en_US": "The cluster[{0}] has created DRS", - "zh_CN": "", + "raw": "ALERT:\\n resource[name: %s, uuid: %s, type: %s]\\nevent: %s %s %s\\ncurrent value: %s\\nduration: %s seconds\\n", + "en_US": "ALERT:\\n resource[name: {0}, uuid: {1}, type: {2}]\\nevent: {3} {4} {5}\\ncurrent value: {6}\\nduration: {7} seconds\\n", + "zh_CN": "警告:\\n 资源[名称: {0}, uuid: {1}, 类型: {2}]\\n 事件: {3} {4} {5}\\n 周期: {7}\\n", "arguments": [ - "msg.getClusterUuid()" + "resourceName", + "resourceUuid", + "toI18nString(resourceType)", + "itemName", + "toI18nString(expression.getOperator())", + "expression.getConstant()", + "value", + "tvo.getDuration()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 79, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusAlert.java" }, { - "raw": "DRS is disabled", - "en_US": "DRS is disabled", - "zh_CN": "", - "arguments": [], - "line": 59, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "raw": "the relativeTime[%s] is invalid, it must be in format of, for example, 10s, 1h", + "en_US": "the relativeTime[{0}] is invalid, it must be in format of, for example, 10s, 1h", + "zh_CN": "相关时间[{0}]不合法,格式必须例如10s,1h", + "arguments": [ + "msg.getRelativeTime()" + ], + "line": 40, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java" }, { - "raw": "thresholds can not be empty", - "en_US": "thresholds can not be empty", - "zh_CN": "", + "raw": "the relativeTime[%s] is invalid, it\u0027s too big", + "en_US": "the relativeTime[{0}] is invalid, it\u0027s too big", + "zh_CN": "相关时间[{0}]不合法,值\u0027s 过大", + "arguments": [ + "msg.getRelativeTime()" + ], + "line": 44, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java" + }, + { + "raw": "CPU number", + "en_US": "CPU number", + "zh_CN": "CPU数量", "arguments": [], - "line": 64, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 95, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilAlertWriter.java" }, { - "raw": "illegal thresholdName[%s]", - "en_US": "illegal thresholdName[{0}]", - "zh_CN": "", + "raw": "invalid cpu[%s], the host[uuid:%s] doesn\u0027t have a CPU numbered by %s", + "en_US": "invalid cpu[{0}], the host[uuid:{1}] doesn\u0027t have a CPU numbered by {2}", + "zh_CN": "无效CPU数目[{0}],物理机[uuid:{1}]存在的CPU数目是{2}", "arguments": [ - "threshold.getThresholdName()" + "cpu", + "trigger.getTargetResourceUuid()", + "cpuNum" ], - "line": 73, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 70, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilItem.java" }, { - "raw": "illegal threshold operator[%s]", - "en_US": "illegal threshold operator[{0}]", - "zh_CN": "", - "arguments": [ - "threshold.getOperator()" - ], - "line": 77, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "raw": "Host Disk Capacity", + "en_US": "Host Disk Capacity", + "zh_CN": "物理机磁盘容量", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java" }, { - "raw": "thresholdValue can not be empty", - "en_US": "thresholdValue can not be empty", - "zh_CN": "", + "raw": "Host Disk Capacity type", + "en_US": "Host Disk Capacity type", + "zh_CN": "物理机磁盘容量类型", "arguments": [], - "line": 81, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 98, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java" }, { - "raw": "illegal thresholdValue, valid range: (0, 100]", - "en_US": "illegal thresholdValue, valid range: (0, 100]", - "zh_CN": "", + "raw": "Host devices", + "en_US": "Host devices", + "zh_CN": "物理机服务", "arguments": [], - "line": 86, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 100, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java" + }, + { + "raw": "Host", + "en_US": "Host", + "zh_CN": "物理机", + "arguments": [], + "line": 77, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostNetworkIOAlertWriter.java" + }, + { + "raw": "query failure, errorType:%s, error: %s", + "en_US": "query failure, errorType:{0}, error: {1}", + "zh_CN": "查询失败,错误类型: {0}, 错误: {1}", + "arguments": [ + "ret.get(\"errorType\")", + "ret.get(\"error\")" + ], + "line": 124, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusMonitorProviderFactory.java" }, { - "raw": "GlobalConfig ENABLE_DRS is closed", - "en_US": "GlobalConfig ENABLE_DRS is closed", - "zh_CN": "", + "raw": "CPU Utilization", + "en_US": "CPU Utilization", + "zh_CN": "CPU使用率", "arguments": [], - "line": 103, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 81, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java" }, { - "raw": "The DRS[%s] state is %s", - "en_US": "The DRS[{0}] state is {1}", - "zh_CN": "", - "arguments": [ - "msg.getUuid()", - "vo.getState().toString()" - ], - "line": 107, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "raw": "CPU utilization type", + "en_US": "CPU utilization type", + "zh_CN": "CPU使用类型", + "arguments": [], + "line": 84, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java" }, { - "raw": "The DRS[%s] automation level is not manual", - "en_US": "The DRS[{0}] automation level is not manual", - "zh_CN": "", - "arguments": [ - "adviceVO.getDrsUuid()" - ], - "line": 122, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "raw": "Disk IO", + "en_US": "Disk IO", + "zh_CN": "磁盘IO", + "arguments": [], + "line": 86, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java" }, { - "raw": "advice[%s] has expired", - "en_US": "advice[{0}] has expired", - "zh_CN": "", - "arguments": [ - "msg.getAdviceUuid()" - ], - "line": 136, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "raw": "Disk IO direction", + "en_US": "Disk IO direction", + "zh_CN": "磁盘IO方向", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java" }, { - "raw": "Successfully executed, no repeated executions allowed", - "en_US": "Successfully executed, no repeated executions allowed", - "zh_CN": "", + "raw": "Disk IO type", + "en_US": "Disk IO type", + "zh_CN": "磁盘IO类型", "arguments": [], - "line": 145, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 93, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java" }, { - "raw": "The vm[%s] has been deleted", - "en_US": "The vm[{0}] has been deleted", - "zh_CN": "", + "raw": "invalid type[%s], only %s are allowed", + "en_US": "invalid type[{0}], only {1} are allowed", + "zh_CN": "无效类型[{0}],只有{1}被允许", "arguments": [ - "adviceVO.getVmUuid()" + "type", + "ALLOWED_TYPES" ], - "line": 152, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 19, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOItem.java" }, { - "raw": "The vm[%s] state is not running", - "en_US": "The vm[{0}] state is not running", - "zh_CN": "", - "arguments": [ - "adviceVO.getVmUuid()" - ], - "line": 155, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "raw": "Memory Utilization", + "en_US": "Memory Utilization", + "zh_CN": "内存使用率", + "arguments": [], + "line": 77, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilAlertWriter.java" }, { - "raw": "The vm[%s] is no longer on the source host[%s]", - "en_US": "The vm[{0}] is no longer on the source host[{1}]", - "zh_CN": "", + "raw": "invalid right value[%s], it must be a float or double number", + "en_US": "invalid right value[{0}], it must be a float or double number", + "zh_CN": "无效的参数值[{0}],它必须是一个float或者double类型的数值", "arguments": [ - "adviceVO.getVmUuid()", - "adviceVO.getVmSourceHostUuid()" + "expression.getConstant()" ], - "line": 158, - "fileName": "src/main/java/org/zstack/drs/DRSInterceptor.java" + "line": 57, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java" }, { - "raw": "The cluster[%s] does not support DRS.", - "en_US": "The cluster[{0}] does not support DRS.", - "zh_CN": "", + "raw": "invalid right value[%s], it must be float or double number greater than zero and lesser than one", + "en_US": "invalid right value[{0}], it must be float or double number greater than zero and lesser than one", + "zh_CN": "无效参数值[{0}],它必须是一个float或者double类型的大于0小于1的数值", "arguments": [ - "msg.getClusterUuid()" + "expression.getConstant()" ], - "line": 242, - "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + "line": 53, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java" }, { - "raw": "Can not create DRS, %s", - "en_US": "Can not create DRS, {0}", - "zh_CN": "", + "raw": "invalid arguments %s, no argument is allowed", + "en_US": "invalid arguments {0}, no argument is allowed", + "zh_CN": "无效参数列表{0},没有被参数被允许", "arguments": [ - "reasons" + "expression.getArguments().keySet()" ], - "line": 258, - "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + "line": 47, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java" }, { - "raw": "hostUuids is empty", - "en_US": "hostUuids is empty", - "zh_CN": "", + "raw": "Network IO", + "en_US": "Network IO", + "zh_CN": "网络IO", "arguments": [], - "line": 290, - "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + "line": 84, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java" }, { - "raw": "query hosts utilization data failed", - "en_US": "query hosts utilization data failed", - "zh_CN": "", + "raw": "Network IO direction", + "en_US": "Network IO direction", + "zh_CN": "网络IO方向", "arguments": [], - "line": 297, - "fileName": "src/main/java/org/zstack/drs/DRSManagerImpl.java" + "line": 89, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java" }, { - "raw": "crond is not running", - "en_US": "crond is not running", - "zh_CN": "crond任务未在运行", + "raw": "Virtual Machine", + "en_US": "Virtual Machine", + "zh_CN": "云主机器", "arguments": [], - "line": 54, - "fileName": "src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java" + "line": 77, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java" }, { - "raw": "All the networks should be in the virtual router[%s]", - "en_US": "All the networks should be in the virtual router[{0}]", - "zh_CN": "", + "raw": "invalid right value[%s], it must be a number(int, long, float, double)", + "en_US": "invalid right value[{0}], it must be a number(int, long, float, double)", + "zh_CN": "无效参数值[{0}],他应该是一个数字(int, long, float, double)", "arguments": [ - "msg.getvRouterUuid()" + "expression.getConstant()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 22, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java" }, { - "raw": "The network[%s] have been added into the flow meter[%s]", - "en_US": "The network[{0}] have been added into the flow meter[{1}]", - "zh_CN": "", + "raw": "invalid direction[%s], only %s are allowed", + "en_US": "invalid direction[{0}], only {1} are allowed", + "zh_CN": "无效direction[{0}],只有{1}被允许", "arguments": [ - "vo.getL3NetworkUuid()", - "vo.getFlowMeterUuid()" + "dir", + "ALLOWED_DIRECTION" ], - "line": 63, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" - }, - { - "raw": "The virtual router have been added into other flow meter", - "en_US": "The virtual router have been added into other flow meter", - "zh_CN": "", - "arguments": [], - "line": 71, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 18, + "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java" }, { - "raw": "invalid type parameter is %s and should be in %s", - "en_US": "invalid type parameter is {0} and should be in {1}", - "zh_CN": "", + "raw": "invalid expression: %s, %s", + "en_US": "invalid expression: {0}, {1}", + "zh_CN": "无效的语句: {0}, {1}", "arguments": [ - "msg.getVersion()", - "FlowMeterConstants.TYPE.NetFlow.toString()" + "expr", + "e.getMessage()" ], - "line": 77, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 106, + "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" }, { - "raw": "[%s] is not formatted as IP address", - "en_US": "[{0}] is not formatted as IP address", - "zh_CN": "", + "raw": "invalid expression: %s, no expression found", + "en_US": "invalid expression: {0}, no expression found", + "zh_CN": "无效的语句: {0},未找到该语句", "arguments": [ - "msg.getServer()" + "expr" ], - "line": 154, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 110, + "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" }, { - "raw": "Collector duplicate with %s", - "en_US": "Collector duplicate with {0}", - "zh_CN": "", + "raw": "missing parameter \u0027%s\u0027 in the expression", + "en_US": "missing parameter \u0027{0}\u0027 in the expression", + "zh_CN": "在语句中缺失参数{0}", "arguments": [ - "collector.getUuid()" + "key" ], - "line": 143, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 127, + "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" }, { - "raw": "FlowMeter[%s] doesn\u0027t exist", - "en_US": "FlowMeter[{0}] doesn\u0027t exist", - "zh_CN": "", + "raw": "wrong type of parameter \u0027%s\u0027 in the expression, it must be type of %s, but got %s", + "en_US": "wrong type of parameter \u0027{0}\u0027 in the expression, it must be type of {1}, but got {2}", + "zh_CN": "在语句中{0}参数类型错误,它必须是{1}这种类型,但是获得的是{2}", "arguments": [ - "collectorVO.getFlowMeterUuid()" + "key", + "clz", + "value.getClass()" ], - "line": 164, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 131, + "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" }, { - "raw": "FlowMeter[%s] IPv6 doesn\u0027t support version[%s]", - "en_US": "FlowMeter[{0}] IPv6 doesn\u0027t support version[{1}]", - "zh_CN": "", + "raw": "The number[value:%s] is not a valid part number.", + "en_US": "The number[value:{0}] is not a valid part number.", + "zh_CN": "编号[值:{0}]不是有效的物料编号。", "arguments": [ - "collectorVO.getFlowMeterUuid()", - "vo.getVersion().toString()" + "partNum" ], - "line": 168, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 58, + "fileName": "src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java" }, { - "raw": "no specify parameter", - "en_US": "no specify parameter", - "zh_CN": "", - "arguments": [], - "line": 150, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "raw": "The quantity exceeded. The device[uuid: %s] required se devices number exceeds a quantiry[value: %s].", + "en_US": "The quantity exceeded. The device[uuid: {0}] required se devices number exceeds a quantiry[value: {1}].", + "zh_CN": "数量超出。设备[uuid:{0}]所需的SE设备数量超过数量[值:{1}]。", + "arguments": [ + "mttyDeviceUuid", + "accu" + ], + "line": 69, + "fileName": "src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java" }, { - "raw": "Flow collector[%s] doesn\u0027t exist", - "en_US": "Flow collector[{0}] doesn\u0027t exist", - "zh_CN": "", + "raw": "failed to generate se devices, because:%s", + "en_US": "failed to generate se devices, because:{0}", + "zh_CN": "无法生成SE设备,因为:{0}", "arguments": [ - "msg.getUuid()" + "rsp.getError()" ], - "line": 159, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 93, + "fileName": "src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java" }, { - "raw": "Collector [%s %d] duplicate with %s", - "en_US": "Collector [{0} {1}] duplicate with {2}", - "zh_CN": "", + "raw": "failed to ungenerate se devices, because:%s", + "en_US": "failed to ungenerate se devices, because:{0}", + "zh_CN": "无法取消生成SE设备,因为:{0}", "arguments": [ - "server", - "port", - "collector.getUuid()" + "rsp.getError()" ], - "line": 183, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java" + "line": 152, + "fileName": "src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java" }, { - "raw": "%s must be a number", - "en_US": "{0} must be a number", - "zh_CN": "{0}必须是一个数字", + "raw": "mtty device[uuid:%s] is not virtualized into mdevs", + "en_US": "mtty device[uuid:{0}] is not virtualized into mdevs", + "zh_CN": "MTTY设备[uuid:{0}]未虚拟化为MDEV", "arguments": [ - "FlowMeterSystemTags.FLOW_EXPIRE_INTERVAL_TOKEN" + "msg.getMttyDeviceUuid()" ], - "line": 148, - "fileName": "src/main/java/org/zstack/flowMeter/FlowMeterManagerImpl.java" + "line": 41, + "fileName": "src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java" }, { - "raw": "cannot get latest guest-tools for vm[uuid:%s] because it\u0027s hypervisor type is not supported", - "en_US": "cannot get latest guest-tools for vm[uuid:{0}] because it\u0027s hypervisor type is not supported", - "zh_CN": "无法为云主机[uuid:{0}获取最新可用的增强工具镜像,因为其虚拟化层目前不支持增强工具", + "raw": "mdev devices generated from mtty device[uuid:%s] still attached to vm", + "en_US": "mdev devices generated from mtty device[uuid:{0}] still attached to vm", + "zh_CN": "从MTTY设备[uuid:{0}]生成的MDEV设备仍连接到云主机", "arguments": [ - "msg.getUuid()" + "msg.getMttyDeviceUuid()" ], - "line": 43, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 58, + "fileName": "src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java" }, { - "raw": "cannot get latest guest-tools for vm[uuid:%s] because it\u0027s not running", - "en_US": "cannot get latest guest-tools for vm[uuid:{0}] because it\u0027s not running", - "zh_CN": "无法为云主机[uuid:{0}]获取最新可用的增强工具镜像,因为它目前并未处于运行状态", + "raw": "the host[uuid:%s] that mtty device[uuid:%s] in is not Connected", + "en_US": "the host[uuid:{0}] that mtty device[uuid:{1}] in is not Connected", + "zh_CN": "未连接MTTY设备[uuid:{1}]所在的物理机[uuid:{0}]", "arguments": [ - "msg.getUuid()" + "mtty.getHostUuid()", + "mtty.getUuid()" ], - "line": 50, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 87, + "fileName": "src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java" }, { - "raw": "cannot get latest guest-tools for vm[uuid:%s] because it\u0027s not user vm", - "en_US": "cannot get latest guest-tools for vm[uuid:{0}] because it\u0027s not user vm", - "zh_CN": "无法为云主机[uuid:{0}]获取最新可用的增强工具镜像,因为它不是用户云主机", + "raw": "mtty device[uuid:%s] cannot be virtualized into mdevs", + "en_US": "mtty device[uuid:{0}] cannot be virtualized into mdevs", + "zh_CN": "MTTY设备[uuid:{0}]无法虚拟化为MDEV", "arguments": [ - "msg.getUuid()" + "msg.getMttyDeviceUuid()" ], - "line": 57, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 78, + "fileName": "src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java" }, { - "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it\u0027s hypervisor type is not supported", - "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it\u0027s hypervisor type is not supported", - "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为其虚拟化层目前不支持增强工具", + "raw": "Rendezvous Point [%s] is not a unicast address", + "en_US": "Rendezvous Point [{0}] is not a unicast address", + "zh_CN": "组播聚合点地址[{0}]不是单播地址", "arguments": [ - "msg.getUuid()" + "rpAddress" ], - "line": 67, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 59, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" }, { - "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it\u0027s not running", - "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it\u0027s not running", - "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为它目前并未处于运行状态", + "raw": "group address [%s] is not a multicast address", + "en_US": "group address [{0}] is not a multicast address", + "zh_CN": "地址 [{0}] 不是组播地址", "arguments": [ - "msg.getUuid()" + "multicastGroup" ], - "line": 74, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 63, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" }, { - "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it\u0027s not user vm", - "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it\u0027s not user vm", - "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为它不是用户云主机", + "raw": "rp address pair [%s: %s] already existed for multicast router [uuid:%s]", + "en_US": "rp address pair [{0}: {1}] already existed for multicast router [uuid:{2}]", + "zh_CN": "组播聚合点地址对[{0}: {1}]已经存在于组播路由器[uuid:{2}]的配置中", "arguments": [ + "msg.getRpAddress()", + "msg.getGroupAddress()", "msg.getUuid()" ], - "line": 81, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 75, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" }, { - "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it has no cdrom", - "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it has no cdrom", - "zh_CN": "无法为云主机[uuid:{0}挂载增强工具镜像,因为它没有配备光驱", + "raw": "rp address tuple [%s : %s] is not existed for multicast router [uuid:%s]", + "en_US": "rp address tuple [{0} : {1}] is not existed for multicast router [uuid:{2}]", + "zh_CN": "组播聚合点地址对[{0}: {1}]不存于组播路由器[uuid:{2}]的配置中", "arguments": [ + "msg.getRpAddress()", + "msg.getGroupAddress()", "msg.getUuid()" ], - "line": 88, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 89, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" }, { - "raw": "cannot attach guest-tools iso to vm[uuid:%s] because it has VirtioSCSI data volume attached", - "en_US": "cannot attach guest-tools iso to vm[uuid:{0}] because it has VirtioSCSI data volume attached", - "zh_CN": "无法为云主机[uuid:{0}挂载增强工具镜像,因为它挂载了VirtioSCSI云盘", + "raw": "multicastRouter[uuid:%s] has not been attached to vpc router", + "en_US": "multicastRouter[uuid:{0}] has not been attached to vpc router", + "zh_CN": "组播路由器[uuid:{0}]没有关联到VPC路由器", "arguments": [ "msg.getUuid()" ], "line": 98, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" }, { - "raw": "cannot get guest-tools info from vm[uuid:%s] because it\u0027s hypervisor type is not supported", - "en_US": "cannot get guest-tools info from vm[uuid:{0}] because it\u0027s hypervisor type is not supported", - "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为其虚拟化层目前不支持增强工具", + "raw": "multicast already enabled on vpc router uuid[:%s]", + "en_US": "multicast already enabled on vpc router uuid[:{0}]", + "zh_CN": "VPC路由器[uuid:{0}]的组播路功能已经打开", "arguments": [ - "msg.getUuid()" + "msg.getVpcRouterVmUuid()" ], - "line": 109, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 124, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" }, { - "raw": "cannot get guest-tools info from vm[uuid:%s] because it\u0027s not running", - "en_US": "cannot get guest-tools info from vm[uuid:{0}] because it\u0027s not running", - "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为它目前并未处于运行状态", + "raw": "vpc router for multicast router [uuid:%s] has been deleted", + "en_US": "vpc router for multicast router [uuid:{0}] has been deleted", + "zh_CN": "组播路由器[uuid:{0}]关联的VPC路由器已经被删除", "arguments": [ "msg.getUuid()" ], - "line": 116, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 317, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" }, { - "raw": "cannot get guest-tools info from vm[uuid:%s] because it\u0027s not user vm", - "en_US": "cannot get guest-tools info from vm[uuid:{0}] because it\u0027s not user vm", - "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为它不是用户云主机", + "raw": "multicast router [uuid:%s] is not attached to Vpc Router", + "en_US": "multicast router [uuid:{0}] is not attached to Vpc Router", + "zh_CN": "组播路由器[uuid:{0}]没有关联到VPC路由器", "arguments": [ "msg.getUuid()" ], - "line": 123, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java" + "line": 760, + "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" }, { - "raw": "no proper guest tools iso found in management node[uuid:%s] for host[uuid:%s]", - "en_US": "no proper guest tools iso found in management node[uuid:{0}] for host[uuid:{1}]", - "zh_CN": "无法在管理节点[uuid:{0}]上为物理机[uuid:{1}]寻找到合适的增强工具镜像", + "raw": "multicast router [uuid:%s] has been delete during enable multilcast on backend", + "en_US": "multicast router [uuid:{0}] has been delete during enable multilcast on backend", + "zh_CN": "组播路由器[uuid:{0}]已经被删除", "arguments": [ - "Platform.getManagementServerId()", - "msg.getHostUuid()" + "vrUuid" ], - "line": 243, - "fileName": "src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java" + "line": 95, + "fileName": "src/main/java/org/zstack/multicast/router/backend/MulticastRouterVyosBackendImpl.java" }, { - "raw": "The vmInstance [uuid] zwatch agent version was not found", - "en_US": "The vmInstance [uuid] zwatch agent version was not found", - "zh_CN": "", + "raw": "nas file system [%s] is not existed yet", + "en_US": "nas file system [{0}] is not existed yet", + "zh_CN": "NAS文件系统[{0}]尚不存在", "arguments": [ - "vm.getUuid()" + "msg.getNasFileSystemUuid()" ], - "line": 93, - "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsForLinuxOnKvmBackend.java" + "line": 91, + "fileName": "src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java" }, { - "raw": "failed to download guest tools iso because no kvm host[uuid:%s] found", - "en_US": "failed to download guest tools iso because no kvm host[uuid:{0}] found", - "zh_CN": "KVM物理机[uuid:{0}]不存在,无法为其下载增强工具镜像", + "raw": "cannot find nas factory for type: %s", + "en_US": "cannot find nas factory for type: {0}", + "zh_CN": "找不到类型为{0}的NAS工厂", "arguments": [ - "host.getUuid()" + "type" ], - "line": 59, - "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java" + "line": 139, + "fileName": "src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java" }, { - "raw": "failed to attach guest tools iso to vm[uuid:%s], because:%s", - "en_US": "failed to attach guest tools iso to vm[uuid:{0}], because:{1}", - "zh_CN": "无法为云主机[uuid:{0}]挂载增强工具镜像,因为:{1}", + "raw": "duplicate NasFileSystemFactory[%s, %s] for type[%s]", + "en_US": "duplicate NasFileSystemFactory[{0}, {1}] for type[{2}]", + "zh_CN": "类型[{2}]的NASFileSystemFactory[{0},{1}]重复", "arguments": [ - "vm.getUuid()", - "rsp.getError()" + "f.getClass().getSimpleName()", + "old.getClass().getSimpleName()", + "f.getNasFileSystemType()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java" + "line": 164, + "fileName": "src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java" }, { - "raw": "failed to get guest tools info from vm[uuid:%s], because:%s", - "en_US": "failed to get guest tools info from vm[uuid:{0}], because:{1}", - "zh_CN": "无法从云主机[uuid:{0}]内部获取增强工具信息,因为:{1}", + "raw": "l2Network[uuid:%s] has attached to cluster[uuid:%s], can\u0027t attach again", + "en_US": "l2Network[uuid:{0}] has attached to cluster[uuid:{1}], can\u0027t attach again", + "zh_CN": "不能再次挂载二层网络[uuid:{0}],因为已经挂载到集群[uuid:{1}]上了", "arguments": [ - "vm.getUuid()", - "rsp.getError()" + "msg.getL2NetworkUuid()", + "msg.getClusterUuid()" ], - "line": 160, - "fileName": "src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java" + "line": 63, + "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" }, { - "raw": "hosts failed to port scan the failure host[uuid:%s, ip:%s], errors are %s", - "en_US": "hosts failed to port scan the failure host[uuid:{0}, ip:{1}], errors are {2}", - "zh_CN": "扫描物理机失败[uuid:{0}, ip:{1}],错误原因是 {2}", + "raw": "could not attach l2 network, because there is another network [uuid:%] on physical interface [%s] with different vswitch type", + "en_US": "could not attach l2 network, because there is another network [uuid:%] on physical interface [{0}] with different vswitch type", + "zh_CN": "无法连接二层网络,因为物理接口[{0}]上存在另一个具有不同vSwitch类型的网络[uuid:%]", "arguments": [ - "struct.getHostUuid()", - "struct.getHostIp()", - "errors" + "otherL2s.get(0)", + "l2.getPhysicalInterface()" ], - "line": 236, - "fileName": "src/main/java/org/zstack/ha/HaKvmHostSiblingChecker.java" + "line": 75, + "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" }, { - "raw": "(%d/%d) start HaHostChecker %s: predict time is [%d] seconds", - "en_US": "({0}/{1}) start HaHostChecker {2}: predict time is [{3}] seconds", - "zh_CN": "", + "raw": "l2Network[uuid:%s] has not attached to cluster[uuid:%s]", + "en_US": "l2Network[uuid:{0}] has not attached to cluster[uuid:{1}]", + "zh_CN": "二层网络[uuid:{0}]没有挂载到集群上[uuid:{1}]", "arguments": [ - "checkers.indexOf(checker) + 1", - "checkers.size()", - "checker.getClass().getSimpleName()", - "s.getSuccessTimes() * s.getSuccessInterval()" + "msg.getL2NetworkUuid()", + "msg.getClusterUuid()" ], - "line": 88, - "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + "line": 87, + "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" }, { - "raw": "cannot find the host of the vm[name:%s, uuid:%s], hostUuid is null", - "en_US": "cannot find the host of the vm[name:{0}, uuid:{1}], hostUuid is null", - "zh_CN": "找不到vm[name:{0}, uuid:{1}]的物理机, 因为hostUuid为null", + "raw": "unsupported l2Network type[%s]", + "en_US": "unsupported l2Network type[{0}]", + "zh_CN": "不支持的网络类型[{0}]", "arguments": [ - "self.getName()", - "self.getUuid()" + "msg.getType()" ], - "line": 144, - "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + "line": 101, + "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" }, { - "raw": "no HaHostChecker found, cannot do HA", - "en_US": "no HaHostChecker found, cannot do HA", - "zh_CN": "找不到HaHostChecker,无法执行HA", - "arguments": [], - "line": 151, - "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + "raw": "unsupported vSwitch type[%s]", + "en_US": "unsupported vSwitch type[{0}]", + "zh_CN": "不支持的vSwitch类型[{0}]", + "arguments": [ + "msg.getvSwitchType()" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" }, { - "raw": "can not ha because device still attached to vm[%s]", - "en_US": "can not ha because device still attached to vm[{0}]", - "zh_CN": "", + "raw": "There has been a L2VlanNetwork[uuid:%s, name:%s] attached to cluster[uuid:%s] that has physical interface[%s], vlan[%s]. Failed to attach L2VlanNetwork[uuid:%s]", + "en_US": "There has been a L2VlanNetwork[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}], vlan[{4}]. Failed to attach L2VlanNetwork[uuid:{5}]", + "zh_CN": "二层网络挂载失败[uuid:{5}]: 二层网络[uuid:{0}, name:{1}]的物理接口[{3}], vlan[{4}]已经挂载到集群[uuid:{2}]上", "arguments": [ - "self.getUuid()" + "vl2.getUuid()", + "vl2.getName()", + "msg.getClusterUuid()", + "vl2.getPhysicalInterface()", + "vl2.getVlan()", + "tl2.getUuid()" ], - "line": 158, - "fileName": "src/main/java/org/zstack/ha/HaKvmWorker.java" + "line": 626, + "fileName": "src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java" }, { - "raw": "the management node fails to scan the host", - "en_US": "the management node fails to scan the host", - "zh_CN": "管理节点扫描物理机失败", - "arguments": [], - "line": 99, - "fileName": "src/main/java/org/zstack/ha/HaManagementNodeChecker.java" + "raw": "There has been a l2Network[uuid:%s, name:%s] attached to cluster[uuid:%s] that has physical interface[%s]. Failed to attach l2Network[uuid:%s]", + "en_US": "There has been a l2Network[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}]. Failed to attach l2Network[uuid:{4}]", + "zh_CN": "二层网络挂载失败[uuid:{4}]: 二层网络[uuid:{0}, name:{1}]的物理接口[{3}]]已经挂载到集群[uuid:{2}]上", + "arguments": [ + "l2.getUuid()", + "l2.getName()", + "msg.getClusterUuid()", + "l2.getPhysicalInterface()", + "tl2.getUuid()" + ], + "line": 608, + "fileName": "src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java" }, { - "raw": "the VM[uuid:%s] volume stored location primary storage is in a state of maintenance", - "en_US": "the VM[uuid:{0}] volume stored location primary storage is in a state of maintenance", - "zh_CN": "虚拟机[{0}]云盘所在主存储处于维护状态", + "raw": "could not create L2PortGroupNetwork, because L2VirtualSwitchNetwork[uuid:%s] already has L2PortGroupNetworks with the same vlanId[%s]", + "en_US": "could not create L2PortGroupNetwork, because L2VirtualSwitchNetwork[uuid:{0}] already has L2PortGroupNetworks with the same vlanId[{1}]", + "zh_CN": "创建端口组失败,因为虚拟交换机[uuid:{0}]已经存在vlanId[{1}]的端口组", "arguments": [ - "vmUuid" + "msg.getvSwitchUuid()", + "msg.getVlan()" ], - "line": 1363, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 84, + "fileName": "src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java" }, { - "raw": "the value[%s] is lesser than 0", - "en_US": "the value[{0}] is lesser than 0", - "zh_CN": "值[{0}]比0小", + "raw": "could not attach L2VirtualSwitchNetwork, because interface[%s] in cluster[uuid:%s] is already used for another L2VirtualSwitchNetwork", + "en_US": "could not attach L2VirtualSwitchNetwork, because interface[{0}] in cluster[uuid:{1}] is already used for another L2VirtualSwitchNetwork", + "zh_CN": "挂载虚拟交换机失败,因为集群[uuid:{1}]中的网卡[{0}]已被其他虚拟交换机使用", "arguments": [ - "newValue" + "vswitchVO.getPhysicalInterface()", + "msg.getClusterUuid()" ], - "line": 232, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 106, + "fileName": "src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java" }, { - "raw": "host[uuid:%s] is not %s, but still have vm on it, please resolve hosts\u0027 problems before enable ha", - "en_US": "host[uuid:{0}] is not {1}, but still have vm on it, please resolve hosts\u0027 problems before enable ha", - "zh_CN": "", + "raw": "could not attach L2VirtualSwitchNetwork, because there are no hosts in cluster[uuid:%s]", + "en_US": "could not attach L2VirtualSwitchNetwork, because there are no hosts in cluster[uuid:{0}]", + "zh_CN": "挂载虚拟交换机失败,因为集群[uuid:{0}]中不存在任何物理机", "arguments": [ - "hostUuids", - "HostStatus.Connected" + "msg.getClusterUuid()" ], - "line": 247, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 113, + "fileName": "src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java" }, { - "raw": "host[uuid:%s] is not %s, but still have vm on it, please resolve hosts\u0027 problems before update fencer strategy", - "en_US": "host[uuid:{0}] is not {1}, but still have vm on it, please resolve hosts\u0027 problems before update fencer strategy", - "zh_CN": "", + "raw": "could not attach L2VirtualSwitchNetwork, because interface[%s] should be created on host[uuid:%s]", + "en_US": "could not attach L2VirtualSwitchNetwork, because interface[{0}] should be created on host[uuid:{1}]", + "zh_CN": "挂载虚拟交换机失败,因为网卡[{0}]应当在物理机[uuid:{1}]上创建", "arguments": [ - "hostUuids", - "HostStatus.Connected" + "vswitchVO.getPhysicalInterface()", + "hostUuid" ], - "line": 255, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 126, + "fileName": "src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java" }, { - "raw": "there is already a HA GC job for the VM, wait it to run", - "en_US": "there is already a HA GC job for the VM, wait it to run", - "zh_CN": "VM已经有一个HA GC任务,等待运行", - "arguments": [], - "line": 472, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "raw": "cannot configure vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", + "en_US": "cannot configure vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}]", + "zh_CN": "无法为云主机[uuid:{0}]在目标物理机[uuid:{1}]上配置VXLAN网络", + "arguments": [ + "inv.getUuid()", + "destHostUuid" + ], + "line": 231, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java" }, { - "raw": "A GC job is submitted to HA the VM[retry delay: %s seconds]", - "en_US": "A GC job is submitted to HA the VM[retry delay: {0} seconds]", - "zh_CN": "提交GC任务来高可用VM[重试间隔: {0} 秒]", + "raw": "find multiple vtep ips[%s] for one host[uuid:%s], need to delete host and add again", + "en_US": "find multiple vtep ips[{0}] for one host[uuid:{1}], need to delete host and add again", + "zh_CN": "在一个物理机[uuid:{1}]发现多个VTEP IP,需要删除物理机在进行添加", "arguments": [ - "HaGlobalConfig.NEVER_STOP_VM_FAILURE_RETRY_DELAY.value(Long.class)" + "vtepIps", + "hostUuid" ], - "line": 480, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 77, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" }, { - "raw": "HA is successfully completed", - "en_US": "HA is successfully completed", - "zh_CN": "", - "arguments": [], - "line": 998, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "raw": "failed to find vtep on host[uuid: %s], please re-attach vxlanpool[uuid: %s] to cluster.", + "en_US": "failed to find vtep on host[uuid: {0}], please re-attach vxlanpool[uuid: {1}] to cluster.", + "zh_CN": "无法在物理机[uuid:{0}]上找到VTEP,请将vxlanpool[uuid:{1}]重新挂接到集群。", + "arguments": [ + "hostUuid", + "l2vxlan.getPoolUuid()" + ], + "line": 82, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" }, { - "raw": "Failed to HA the VM", - "en_US": "Failed to HA the VM", - "zh_CN": "高可用VM失败", - "arguments": [], - "line": 1006, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "raw": "failed to create bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vni:{3}] on kvm host[uuid:{4}], because {5}", + "zh_CN": "为二层网络[uuid:{1}, type:{2}, vni:{3}]在KVM物理机[uuid:{4}]上创建网桥[{0}]失败,错误细节: {5}", + "arguments": [ + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "l2vxlan.getVni()", + "hostUuid", + "rsp.getError()" + ], + "line": 133, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" }, { - "raw": "vm stopped unexpectedly, double check state", - "en_US": "vm stopped unexpectedly, double check state", - "zh_CN": "", - "arguments": [], - "line": 908, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "raw": "failed to check cidr[%s] for l2VxlanNetwork[uuid:%s, name:%s] on kvm host[uuid:%s], %s", + "en_US": "failed to check cidr[{0}] for l2VxlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", + "zh_CN": "为KVM物理机[uuid:{3}]上的L2 VXLAN 网络[uuid:{1}, name:{2}]检查CIDR[{0}]失败,错误细节: {4}", + "arguments": [ + "cmd.getCidr()", + "l2vxlan.getUuid()", + "l2vxlan.getName()", + "hostUuid", + "rsp.getError()" + ], + "line": 197, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" }, { - "raw": "cannot determine VM[%s] status on host[%s], try to start it", - "en_US": "cannot determine VM[{0}] status on host[{1}], try to start it", - "zh_CN": "", + "raw": "failed to delete bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to delete bridge[{0}] for l2Network[uuid:{1}, type:{2}, vni:{3}] on kvm host[uuid:{4}], because {5}", + "zh_CN": "无法删除KVM物理机[uuid:{4}]上的二层网络[uuid:{1},类型:{2},VNI:{3}]的网桥[{0}],因为{5}", "arguments": [ - "vmUuid", - "hostUuid" + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "l2vxlan.getVni()", + "hostUuid", + "rsp.getError()" ], - "line": 917, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 474, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" }, { - "raw": "vm state is stopped, try to start it", - "en_US": "vm state is stopped, try to start it", - "zh_CN": "", - "arguments": [], - "line": 1112, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "raw": "failed to realize vxlan network pool[uuid:%s, type:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to realize vxlan network pool[uuid:{0}, type:{1}] on kvm host[uuid:{2}], because {3}", + "zh_CN": "无法在KVM物理机[uuid:{2}]上实现VXLAN网络池[uuid:{0},类型:{1}],因为{3}", + "arguments": [ + "l2Network.getUuid()", + "l2Network.getType()", + "hostUuid", + "rsp.getError()" + ], + "line": 261, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java" }, { - "raw": "VM[%s] is running on host[%s]", - "en_US": "VM[{0}] is running on host[{1}]", - "zh_CN": "", + "raw": "failed to check cidr[%s] for l2VxlanNetworkPool[uuid:%s, name:%s] on kvm host[uuid:%s], %s", + "en_US": "failed to check cidr[{0}] for l2VxlanNetworkPool[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", + "zh_CN": "检查在kvm物理机[uuid:{3}]上的l2VxlanNetworkPool[uuid:{1}, name:{2}]的CIDR[{0}]失败,{4}", "arguments": [ - "vmUuid", - "hostUuid" + "cmd.getCidr()", + "vxlanPool.getUuid()", + "vxlanPool.getName()", + "hostUuid", + "rsp.getError()" ], - "line": 934, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 111, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java" }, { - "raw": "VM[%s] is paused on host[%s]", - "en_US": "VM[{0}] is paused on host[{1}]", - "zh_CN": "", + "raw": "need to input one system tag like : [%s]", + "en_US": "need to input one system tag like : [{0}]", + "zh_CN": "需要输入一个系统标签,格式为:[{0}]", "arguments": [ - "vmUuid", - "hostUuid" + "VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat()" ], - "line": 947, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 37, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java" }, { - "raw": "the hypervisor[%s] does not support VM HA", - "en_US": "the hypervisor[{0}] does not support VM HA", - "zh_CN": "当前虚拟机监视器(hypervisor)[{0}]不支持VM HA", + "raw": "wrong system tag [%s], should be like : [%s]", + "en_US": "wrong system tag [{0}], should be like : [{1}]", + "zh_CN": "错误的系统标签[{0}],格式应该为:[{1}]", "arguments": [ - "vm.getHypervisorType()" + "tag", + "VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat()" ], - "line": 975, - "fileName": "src/main/java/org/zstack/ha/HaManagerImpl.java" + "line": 49, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java" }, { - "raw": "[HA Worker]: the success ratio[%s] below the threshold[%s], the host[uuid:%s] is judged as dead, errors are %s. Start HA all the vms on this host before", - "en_US": "[HA Worker]: the success ratio[{0}] below the threshold[{1}], the host[uuid:{2}] is judged as dead, errors are {3}. Start HA all the vms on this host before", - "zh_CN": "", + "raw": "wrong cidr format in system tag [%s]", + "en_US": "wrong cidr format in system tag [{0}]", + "zh_CN": "系统标签[{0}]中的cidr格式错误", "arguments": [ - "ratio", - "threshold", - "hostUuid", - "errors" + "tag" ], - "line": 49, - "fileName": "src/main/java/org/zstack/ha/HostCheckResult.java" + "line": 55, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java" }, { - "raw": "[HA worker]: all host checkers are finished and the success ratio is %s that is greater than the threshold[%s]; no HA need for the vms on this host before. Please wait for the host reconnected", - "en_US": "[HA worker]: all host checkers are finished and the success ratio is {0} that is greater than the threshold[{1}]; no HA need for the vms on this host before. Please wait for the host reconnected", - "zh_CN": "", + "raw": "overlap vni range with %s [%s]", + "en_US": "overlap vni range with {0} [{1}]", + "zh_CN": "与{0}[{1}]的vni范围重叠", "arguments": [ - "ratio", - "threshold" + "inv.getType()", + "overlappedPool" ], - "line": 46, - "fileName": "src/main/java/org/zstack/ha/HostCheckResult.java" + "line": 64, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java" }, { - "raw": "Failed to start the NeverStop VM", - "en_US": "Failed to start the NeverStop VM", - "zh_CN": "", + "raw": "vxlan network pool doesn\u0027t support create l3 network", + "en_US": "vxlan network pool doesn\u0027t support create l3 network", + "zh_CN": "vxlan network pool不支持创建三层网络", "arguments": [], - "line": 89, - "fileName": "src/main/java/org/zstack/ha/NeverStopVmGC.java" + "line": 99, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java" }, { - "raw": "VM is started successfully", - "en_US": "VM is started successfully", - "zh_CN": "", + "raw": "vxlan vtep address for host [uuid : %s] and pool [uuid : %s] pair already existed", + "en_US": "vxlan vtep address for host [uuid : {0}] and pool [uuid : {1}] pair already existed", + "zh_CN": "物理机[uuid : {0}]在vxlan资源池[uuid : {1}]中隧道端点地址已经配置", + "arguments": [ + "msg.getHostUuid()", + "msg.getPoolUuid()" + ], + "line": 56, + "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java" + }, + { + "raw": "it is used", + "en_US": "it is used", + "zh_CN": "被占用", "arguments": [], - "line": 80, - "fileName": "src/main/java/org/zstack/ha/NeverStopVmGC.java" + "line": 27, + "fileName": "src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java" }, { - "raw": "VM state is not running, try to start it", - "en_US": "VM state is not running, try to start it", - "zh_CN": "", + "raw": "it is not in this range", + "en_US": "it is not in this range", + "zh_CN": "不在IP地址范围内", "arguments": [], - "line": 74, - "fileName": "src/main/java/org/zstack/ha/NeverStopVmGC.java" + "line": 25, + "fileName": "src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java" }, { - "raw": "keyType not supported type [%s]", - "en_US": "keyType not supported type [{0}]", - "zh_CN": "", - "arguments": [ - "type" - ], - "line": 45, - "fileName": "src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java" + "raw": "it is gateway", + "en_US": "it is gateway", + "zh_CN": "网关不能分配", + "arguments": [], + "line": 23, + "fileName": "src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java" }, { - "raw": "key: [%s] already existed by accountUuid: [%s]", - "en_US": "key: [{0}] already existed by accountUuid: [{1}]", - "zh_CN": "key: [{0}]已经存在于accountUuid: [{1}]", + "raw": "could not set mtu because l2 network[uuid:%s] of l3 network [uuid:%s] mtu can not be bigger than the novlan network", + "en_US": "could not set mtu because l2 network[uuid:{0}] of l3 network [uuid:{1}] mtu can not be bigger than the novlan network", + "zh_CN": "无法设置MTU,因为三层网络[uuid:{1}]MTU的二层网络[uuid:{0}]不能大于NoVLAN网络", "arguments": [ - "msg.getKey()", - "accountUuid" + "l2VO.getUuid()", + "msg.getL3NetworkUuid()" ], - "line": 85, - "fileName": "src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java" + "line": 159, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "regionId [%s] already created by ak [%s]", - "en_US": "regionId [{0}] already created by ak [{1}]", - "zh_CN": "区域ID[{0}]已经被AccessKey[{1}]创建", - "arguments": [ - "msg.getRegionId()", - "ak" - ], - "line": 63, - "fileName": "src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java" + "raw": "can not delete the last normal ip range because there is still has address pool", + "en_US": "can not delete the last normal ip range because there is still has address pool", + "zh_CN": "无法删除最后一个正常IP范围,因为仍有地址池", + "arguments": [], + "line": 175, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "dcType not supported type [%s]", - "en_US": "dcType not supported type [{0}]", - "zh_CN": "", - "arguments": [ - "type" - ], - "line": 46, - "fileName": "src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java" + "raw": "you must update system and category both", + "en_US": "you must update system and category both", + "zh_CN": "必须同时更行system属性和category属性", + "arguments": [], + "line": 190, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "DataCenter [%s] is still in sync progress, please wait.", - "en_US": "DataCenter [{0}] is still in sync progress, please wait.", - "zh_CN": "数据中心[{0}]仍在同步进程中,请稍后", + "raw": "not valid combination of system and category,only %s are valid", + "en_US": "not valid combination of system and category,only {0} are valid", + "zh_CN": "无效的system属性和category属性的组合,只有{0}是有效的", "arguments": [ - "msg.getUuid()" + "L3NetworkCategory.validCombination" ], - "line": 96, - "fileName": "src/main/java/org/zstack/hybrid/datacenter/DataCenterManagerImpl.java" + "line": 474, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "identity zone [%s] already existed, uuid is: %s", - "en_US": "identity zone [{0}] already existed, uuid is: {1}", - "zh_CN": "可用区[{0}]已经存在,uuid是{1}", + "raw": "invalid IP[%s]", + "en_US": "invalid IP[{0}]", + "zh_CN": "错误的IP值[{0}]", "arguments": [ - "msg.getZoneId()", - "izo.getUuid()" + "msg.getIp()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java" + "line": 237, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "type [%s] is not matched datacenter type [%s]", - "en_US": "type [{0}] is not matched datacenter type [{1}]", - "zh_CN": "", + "raw": "no ip range in l3[%s]", + "en_US": "no ip range in l3[{0}]", + "zh_CN": "没有IP在三层网络范围中", "arguments": [ - "type", - "dvo.getDcType().toString()" + "msg.getL3NetworkUuid()" ], - "line": 72, - "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java" + "line": 221, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "either dataCenterUuid or regionId should be set, please check the parameters.", - "en_US": "either dataCenterUuid or regionId should be set, please check the parameters.", - "zh_CN": "数据中心Uuid和区域Id应该被设置,请检查参数", - "arguments": [], - "line": 82, - "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java" + "raw": "ip[%s] is not in the cidr of ip range[uuid:%s, cidr:%s] which l3 network[%s] attached", + "en_US": "ip[{0}] is not in the cidr of ip range[uuid:{1}, cidr:{2}] which l3 network[{3}] attached", + "zh_CN": "IP[{0}]没有在三层网络[{3}]的CIDR的IP范围内[uuid:{1}, cidr:{2}]", + "arguments": [ + "msg.getRouterInterfaceIp()", + "ipr.getUuid()", + "ipr.getNetworkCidr()", + "msg.getL3NetworkUuid()" + ], + "line": 225, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "IdentityZone [%s] is still in sync progress, please wait.", - "en_US": "IdentityZone [{0}] is still in sync progress, please wait.", - "zh_CN": "可用区[{0}]仍在同步进程中,请稍后", + "raw": "ip[%s] in ip range[uuid:%s, startIp:%s, endIp:%s] which l3 network[%s] attached, this is not allowed", + "en_US": "ip[{0}] in ip range[uuid:{1}, startIp:{2}, endIp:{3}] which l3 network[{4}] attached, this is not allowed", + "zh_CN": "IP[{0}]在三层网络[{4}]绑定的IP范围内[uuid:{1}, startIp:{2}, endIp:{3}],这是不被允许的", "arguments": [ - "msg.getUuid()" + "msg.getRouterInterfaceIp()", + "ipr.getUuid()", + "ipr.getStartIp()", + "ipr.getEndIp()", + "msg.getL3NetworkUuid()" ], - "line": 111, - "fileName": "src/main/java/org/zstack/hybrid/identityzone/IdentityZoneManagerImpl.java" + "line": 229, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "EcsInstance must be running or stopped while deleting eip ", - "en_US": "EcsInstance must be running or stopped while deleting eip ", - "zh_CN": "删除弹性IP时云主机必须时允许中或者已停止", + "raw": "ipRangeUuid and l3NetworkUuid cannot both be null; you must set either one.", + "en_US": "ipRangeUuid and l3NetworkUuid cannot both be null; you must set either one.", + "zh_CN": "IP段和L3的uuid不能都为空,您必须选择一个填上", "arguments": [], - "line": 88, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridEipCascadeExtension.java" + "line": 243, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "router interface must be in the same datacenter, but ri[%s] is in dc[%s] and ri[%s] is in dc[%s]", - "en_US": "router interface must be in the same datacenter, but ri[{0}] is in dc[{1}] and ri[{2}] is in dc[{3}]", - "zh_CN": "路由接口必须在相同的数据中心,但是接口[{0}]在数据中心[{1}]而接口[{2}]在数据中心[{3}]", + "raw": "could not get free ip with start[ip:%s],because start[ip:%s] is not a correct ipv6 address", + "en_US": "could not get free ip with start[ip:{0}],because start[ip:{1}] is not a correct ipv6 address", + "zh_CN": "无法使用start[IP:{0}]获取可用IP,因为start[IP:{1}]不是正确的IPv6地址", "arguments": [ - "vbri.getUuid()", - "vbri.getDataCenterUuid()", - "vrouteri.getUuid()", - "vrouteri.getDataCenterUuid()" + "msg.getStart()", + "msg.getStart()" ], - "line": 86, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 276, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "router interface[%s] status is not idle, it is %s", - "en_US": "router interface[{0}] status is not idle, it is {1}", - "zh_CN": "路由接口[{0}]并非闲置状态,当前状态为{1}", + "raw": "could not get free ip with start[ip:%s],because start[ip:%s] is not a correct ipv4 address", + "en_US": "could not get free ip with start[ip:{0}],because start[ip:{1}] is not a correct ipv4 address", + "zh_CN": "无法使用start[IP:{0}]获取可用IP,因为start[IP:{1}]不是正确的IPv4地址", "arguments": [ - "vrouteri.getUuid()", - "vrouteri.getStatus()" + "msg.getStart()", + "msg.getStart()" ], - "line": 96, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 274, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "router interface[%s] already has a connection, it is %s", - "en_US": "router interface[{0}] already has a connection, it is {1}", - "zh_CN": "路由接口[{0}]已经有链接{1}", + "raw": "could not get free ip with start[ip:%s],because l3Network[uuid:%s] is dual stack", + "en_US": "could not get free ip with start[ip:{0}],because l3Network[uuid:{1}] is dual stack", + "zh_CN": "无法使用start[IP:{0}]获取可用IP,因为L3Network[uuid:{1}]是双堆栈", "arguments": [ - "vrouteri.getUuid()", - "vrouteri.getOppositeInterfaceUuid()" + "msg.getStart()", + "msg.getL3NetworkUuid()" ], - "line": 104, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" - }, - { - "raw": "accessPointUuid cannot be null if the router interface on VBR type router", - "en_US": "accessPointUuid cannot be null if the router interface on VBR type router", - "zh_CN": "当路由接口的类型为VBR路由时,accessPointUuid不能为空", - "arguments": [], - "line": 112, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 272, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "cannot delete system entry", - "en_US": "cannot delete system entry", - "zh_CN": "不能删除系统路由条目", - "arguments": [], - "line": 186, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "raw": "%s is not a valid network cidr", + "en_US": "{0} is not a valid network cidr", + "zh_CN": "{0}不是有效的无类别域间路由", + "arguments": [ + "msg.getNetworkCidr()" + ], + "line": 408, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "only support intranet rule in vpc", - "en_US": "only support intranet rule in vpc", - "zh_CN": "在VPC中仅仅支持内网规则", - "arguments": [], - "line": 192, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "raw": "%s is not a valid ipv6 address", + "en_US": "{0} is not a valid ipv6 address", + "zh_CN": "{0}不是有效的IPv6地址", + "arguments": [ + "msg.getGateway()" + ], + "line": 304, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "%s is not a valid cidr", - "en_US": "{0} is not a valid cidr", - "zh_CN": "{0}是一个无效的CIDR", + "raw": "[startIp %s, endIp %s, prefixLen %d, gateway %s] is not a valid ipv6 range", + "en_US": "[startIp {0}, endIp {1}, prefixLen {2}, gateway {3}] is not a valid ipv6 range", + "zh_CN": "IPv6地址段{0}-{1}/{2}, 网关{3}不是有效的IPv6地址段", "arguments": [ - "msg.getCidr()" + "msg.getStartIp()", + "msg.getEndIp()", + "msg.getPrefixLen()", + "msg.getGateway()" ], - "line": 197, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 308, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "security group rule already existed", - "en_US": "security group rule already existed", - "zh_CN": "安全组已经存在了", + "raw": "adding normal ip range must specify gateway ip address", + "en_US": "adding normal ip range must specify gateway ip address", + "zh_CN": "添加正常IP范围必须指定网关IP地址", "arguments": [], - "line": 207, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 633, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "dstCidrBlock[%s] is not a valid cidr", - "en_US": "dstCidrBlock[{0}] is not a valid cidr", - "zh_CN": "dstCidrBlock[{0}]是一个无效的CIDR", - "arguments": [ - "msg.getDstCidrBlock()" - ], - "line": 213, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "raw": "can not add ip range, because ipv6 address pool is not supported", + "en_US": "can not add ip range, because ipv6 address pool is not supported", + "zh_CN": "无法添加IP范围,因为不支持IPv6地址池", + "arguments": [], + "line": 324, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "next hop type [%s] not supported create route entry now!", - "en_US": "next hop type [{0}] not supported create route entry now!", - "zh_CN": "", + "raw": "ip range prefix length is out of range [%d - %d] ", + "en_US": "ip range prefix length is out of range [{0} - {1}] ", + "zh_CN": "IPv6地址前缀长度不在有效范围内[{0}-{1}]", "arguments": [ - "msg.getNextHopType()" + "IPv6Constants.IPV6_PREFIX_LEN_MIN", + "IPv6Constants.IPV6_PREFIX_LEN_MAX" ], - "line": 242, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 335, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "no such vpn gateway: %s", - "en_US": "no such vpn gateway: {0}", - "zh_CN": "没有这样的VPN网关: {0}", - "arguments": [ - "msg.getNextHopUuid()" - ], - "line": 238, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "raw": "can not add ip range, because system network doesn\u0027t support ipv6 yet", + "en_US": "can not add ip range, because system network doesn\u0027t support ipv6 yet", + "zh_CN": "无法添加IP范围,因为系统网络尚不支持IPv6", + "arguments": [], + "line": 342, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "nexthop routerInterface belongs to %s, but the entry belongs to %s", - "en_US": "nexthop routerInterface belongs to {0}, but the entry belongs to {1}", - "zh_CN": "下一跳路由接口类型是{0},但是该路由类型是{1}", + "raw": "addressMode[%s] is different from L3Netowork address mode[%s]", + "en_US": "addressMode[{0}] is different from L3Netowork address mode[{1}]", + "zh_CN": "地址模式[{0}]和三层网络的地址模式[{1}]不同", "arguments": [ - "rivo.getvRouterType().toString()", - "msg.getvRouterType()" + "ipr.getAddressMode()", + "rangeVOS.get(0).getAddressMode()" ], - "line": 227, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 348, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "no such ecs instance: %s", - "en_US": "no such ecs instance: {0}", - "zh_CN": "没有这样的ESC云主机: {0}", + "raw": "ipv6 prefix length must be %d for Stateless-DHCP or SLAAC", + "en_US": "ipv6 prefix length must be {0} for Stateless-DHCP or SLAAC", + "zh_CN": "Stateless-DHCP or SLAAC地址模式IPv6网络前缀长度必须是{0}", "arguments": [ - "msg.getNextHopUuid()" + "IPv6Constants.IPV6_STATELESS_PREFIX_LEN" ], - "line": 220, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" - }, - { - "raw": "virtual border router only support routerinterface as next hop type", - "en_US": "virtual border router only support routerinterface as next hop type", - "zh_CN": "作为下一跳类型,虚拟边界路由只支持路由接口", - "arguments": [], - "line": 252, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 354, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "vswitch\u0027s cidr [%s] not in the vpc\u0027s [%s]", - "en_US": "vswitch\u0027s cidr [{0}] not in the vpc\u0027s [{1}]", - "zh_CN": "虚拟交换机的CIDR没有在VPC[{1}]中", + "raw": "new ip range [startip :%s, endip :%s] is overlaped with old ip range[startip :%s, endip :%s]", + "en_US": "new ip range [startip :{0}, endip :{1}] is overlaped with old ip range[startip :{2}, endip :{3}]", + "zh_CN": "新的IP地址段[{0}-{1}]和旧的IP地址段[{2}-{3}]冲突", "arguments": [ - "msg.getCidrBlock()", - "vpcCidr" + "ipr.getStartIp()", + "ipr.getEndIp()", + "r.getStartIp()", + "r.getEndIp()" ], - "line": 272, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 364, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "cidr is overlap by another vswitch: %s", - "en_US": "cidr is overlap by another vswitch: {0}", - "zh_CN": "CIDR和其他的虚拟交换机{0}有重叠", + "raw": "new network CIDR [%s] is different from old network cidr [%s]", + "en_US": "new network CIDR [{0}] is different from old network cidr [{1}]", + "zh_CN": "同一三层网络上不能加载多个CIDR。", "arguments": [ - "old.getUuid()" + "r.getNetworkCidr()", + "ipr.getNetworkCidr()" ], - "line": 279, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 374, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "invalid CidrBlock: %s, which must subnet in \u002710.0.0.0/8\u0027, \u0027172.16.0.0/12\u0027, \u0027192.168.0.0/16\u0027", - "en_US": "invalid CidrBlock: {0}, which must subnet in \u002710.0.0.0/8\u0027, \u0027172.16.0.0/12\u0027, \u0027192.168.0.0/16\u0027", - "zh_CN": "无效的CIDR块: {0},CIDR必须在10.0.0.0/8、172.16.0.0/12和192.168.0.0/16子网内", + "raw": "new add ip range gateway %s is different from old gateway %s", + "en_US": "new add ip range gateway {0} is different from old gateway {1}", + "zh_CN": "新ip段的网关地址{0}和已有ip段的网关地址{1}冲突", "arguments": [ - "msg.getCidrBlock()" + "ipr.getGateway()", + "r.getGateway()" ], - "line": 292, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 618, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "no such virtual router: %s", - "en_US": "no such virtual router: {0}", - "zh_CN": "没有这个的虚拟路由: {0}", + "raw": "gateway[%s] can not be part of range[%s, %s]", + "en_US": "gateway[{0}] can not be part of range[{1}, {2}]", + "zh_CN": "网关[{0}]不能是IP段[{1}, {2}]的一部分", "arguments": [ - "msg.getvRouterUuid()" + "ipr.getGateway()", + "ipr.getStartIp()", + "ipr.getEndIp()" ], - "line": 308, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 611, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "no such virtual border router: %s", - "en_US": "no such virtual border router: {0}", - "zh_CN": "没有这个虚拟边界路由器: {0}", + "raw": "%s is not an allowed network cidr, because it doesn\u0027t have usable ip range", + "en_US": "{0} is not an allowed network cidr, because it doesn\u0027t have usable ip range", + "zh_CN": "{0}是不允许的无类别域间路由,因为它不支持可用的IP段", "arguments": [ - "msg.getvRouterUuid()" + "msg.getNetworkCidr()" ], - "line": 303, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 401, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "localGateway is not IPv4: %s", - "en_US": "localGateway is not IPv4: {0}", - "zh_CN": "本地网关地址不是IPV4: {0}", + "raw": "%s is not the first or last address of the cidr %s", + "en_US": "{0} is not the first or last address of the cidr {1}", + "zh_CN": "{0}不是CIDR{1}的第一个或最后一个地址", "arguments": [ - "msg.getLocalGatewayIp()" + "msg.getGateway()", + "msg.getNetworkCidr()" ], - "line": 315, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 405, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "peerGateway is not IPv4: %s", - "en_US": "peerGateway is not IPv4: {0}", - "zh_CN": "对端网关地址不是IPV4: {0}", + "raw": "ipRangeUuids, L3NetworkUuids, zoneUuids must have at least one be none-empty list, or all is set to true", + "en_US": "ipRangeUuids, L3NetworkUuids, zoneUuids must have at least one be none-empty list, or all is set to true", + "zh_CN": "ipRangeUuids, L3NetworkUuids, zoneUuids 至少一个不是为空列表,或者全部不为空", + "arguments": [], + "line": 432, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + }, + { + "raw": "unsupported l3network type[%s]", + "en_US": "unsupported l3network type[{0}]", + "zh_CN": "不支持的三层网络类型[{0}]", "arguments": [ - "msg.getPeerGatewayIp()" + "msg.getType()" ], - "line": 318, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 453, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "peerGateway is not subnet mask: %s", - "en_US": "peerGateway is not subnet mask: {0}", - "zh_CN": "对端网关地址不是在子网掩码{0}中", + "raw": "%s is not a valid domain name", + "en_US": "{0} is not a valid domain name", + "zh_CN": "{0}不是有效的域名", "arguments": [ - "msg.getPeeringSubnetMask()" + "msg.getDnsDomain()" ], - "line": 321, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 459, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "vlanId is not number: %s", - "en_US": "vlanId is not number: {0}", - "zh_CN": "vlanId不是一个数字:{0}", + "raw": "overlap with ip range[uuid:%s, start ip:%s, end ip: %s]", + "en_US": "overlap with ip range[uuid:{0}, start ip:{1}, end ip: {2}]", + "zh_CN": "重叠的IP段[uuid:{0}, 起始ip:{1}, 尾ip: {2}]", "arguments": [ - "msg.getVlanId()" + "r.getUuid()", + "r.getStartIp()", + "r.getEndIp()" ], - "line": 325, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 580, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "couldn\u0027t attach eip to ecs: [%s] , eip :[%s] already attached ecs:[%s] ", - "en_US": "couldn\u0027t attach eip to ecs: [{0}] , eip :[{1}] already attached ecs:[{2}] ", - "zh_CN": "不能绑定弹性IP到ECS云主机[{0}],弹性IP[{1}]已经绑定到ECS云主机[{2}]", + "raw": "l3 network [uuid %s: name %s] is not a public network, address pool range can not be added", + "en_US": "l3 network [uuid {0}: name {1}] is not a public network, address pool range can not be added", + "zh_CN": "三层网络[uuid{0}:名称{1}]不是公用网络,无法添加地址池范围", "arguments": [ - "msg.getEcsUuid()", - "msg.getEipUuid()", - "hevo.getAllocateResourceUuid()" + "l3Vo.getUuid()", + "l3Vo.getName()" ], - "line": 335, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 523, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "ecs [%s] already has public ip now", - "en_US": "ecs [{0}] already has public ip now", - "zh_CN": "ECS云主机[{0}]已经拥有IP", + "raw": "the IP range[%s ~ %s] contains D class addresses which are for multicast", + "en_US": "the IP range[{0} ~ {1}] contains D class addresses which are for multicast", + "zh_CN": "这个IP段[{0} ~ {1}]包含了D类的组播地址", "arguments": [ - "msg.getEcsUuid()" + "ipr.getStartIp()", + "ipr.getEndIp()" ], - "line": 340, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 527, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "couldn\u0027t attach eip [%s] to ecs: [%s] , ecs is already attached", - "en_US": "couldn\u0027t attach eip [{0}] to ecs: [{1}] , ecs is already attached", - "zh_CN": "不能绑定弹性IP[{0}]到ECS云主机[{1}],ECS云主机已经绑定了弹性IP", + "raw": "the IP range[%s ~ %s] contains E class addresses which are reserved", + "en_US": "the IP range[{0} ~ {1}] contains E class addresses which are reserved", + "zh_CN": "这个IP段[{0} ~ {1}]包含了E类的保留地址", "arguments": [ - "msg.getEipUuid()", - "msg.getEcsUuid()" + "ipr.getStartIp()", + "ipr.getEndIp()" ], - "line": 346, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 531, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "eip[%s] and ecs[%s] should be in the same dataCenter ", - "en_US": "eip[{0}] and ecs[{1}] should be in the same dataCenter ", - "zh_CN": "弹性IP[{0}]和ECS云主机[{1}]应该在同一个数据中心", + "raw": "the IP range[%s ~ %s] contains link local addresses which are reserved", + "en_US": "the IP range[{0} ~ {1}] contains link local addresses which are reserved", + "zh_CN": "这个IP段[{0} ~ {1}]包含了本地的保留地址", "arguments": [ - "msg.getEipUuid()", - "msg.getEcsUuid()" + "ipr.getStartIp()", + "ipr.getEndIp()" ], - "line": 353, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 535, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "couldn\u0027t detach eip :[%s], it is not attached on any instance ", - "en_US": "couldn\u0027t detach eip :[{0}], it is not attached on any instance ", - "zh_CN": "不能解绑弹性IP[{0}],因为它没有绑定任何云主机", + "raw": "the gateway[%s] is not in the subnet %s/%s", + "en_US": "the gateway[{0}] is not in the subnet {1}/{2}", + "zh_CN": "网关[{0}]不在子网{1}/{2}", "arguments": [ - "msg.getEipUuid()" + "ipr.getGateway()", + "ipr.getStartIp()", + "ipr.getNetmask()" ], - "line": 362, - "fileName": "src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java" + "line": 541, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "%s is not a valid ipv4 address", - "en_US": "{0} is not a valid ipv4 address", - "zh_CN": "{0}是一个无效的IPV4地址", + "raw": "ip allocation can not contain network address or broadcast address", + "en_US": "ip allocation can not contain network address or broadcast address", + "zh_CN": "ip 地址分配不能包含网络地址或广播的地址", + "arguments": [], + "line": 545, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + }, + { + "raw": "start ip[%s] is not a IPv4 address", + "en_US": "start ip[{0}] is not a IPv4 address", + "zh_CN": "开始的ip[{0}] 不是IPV4的地址", "arguments": [ - "msg.getId()" + "ipr.getStartIp()" ], - "line": 45, - "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + "line": 551, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "localCidr must be Cidr!", - "en_US": "localCidr must be Cidr!", - "zh_CN": "本地CIDR必须是CIDR", - "arguments": [], - "line": 51, - "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + "raw": "end ip[%s] is not a IPv4 address", + "en_US": "end ip[{0}] is not a IPv4 address", + "zh_CN": "结束的ip[{0}] 不是IPV4的地址", + "arguments": [ + "ipr.getEndIp()" + ], + "line": 555, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "remoteCidr must be Cidr!", - "en_US": "remoteCidr must be Cidr!", - "zh_CN": "远程CIDR必须是CIDR", - "arguments": [], - "line": 55, - "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + "raw": "gateway[%s] is not a IPv4 address", + "en_US": "gateway[{0}] is not a IPv4 address", + "zh_CN": "网关[{0}]不是IPV4的地址", + "arguments": [ + "ipr.getGateway()" + ], + "line": 559, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "localCidr and remoteCidr must be Cidr!", - "en_US": "localCidr and remoteCidr must be Cidr!", - "zh_CN": "本地CIDR和远程CIDR必须是CIDR", - "arguments": [], - "line": 62, - "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java" + "raw": "netmask[%s] is not a netmask, and the IP range netmask cannot be 0.0.0.0", + "en_US": "netmask[{0}] is not a netmask, and the IP range netmask cannot be 0.0.0.0", + "zh_CN": "子网掩码[{0}]不是子网掩码,并且IP段的子网掩码不能是0.0.0.0", + "arguments": [ + "ipr.getNetmask()" + ], + "line": 563, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "vpngateway [%s] existed, cannot delete remote", - "en_US": "vpngateway [{0}] existed, cannot delete remote", - "zh_CN": "VPN网关[{0}]已经存在,不能删除远程的", + "raw": "start ip[%s] is behind end ip[%s]", + "en_US": "start ip[{0}] is behind end ip[{1}]", + "zh_CN": "起始ip[{0}]在尾ip[{1}]后", "arguments": [ - "gateways.get(0).getUuid()" + "ipr.getStartIp()", + "ipr.getEndIp()" ], - "line": 80, - "fileName": "src/main/java/org/zstack/hybrid/network/vpn/VpcVpnGatewayCascadeExtension.java" + "line": 569, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "virtual id[uuid:%s] is platform user can not be added to project[uuid:%s]", - "en_US": "virtual id[uuid:{0}] is platform user can not be added to project[uuid:{1}]", - "zh_CN": "", + "raw": "multiple CIDR on the same L3 network is not allowed. There has been a IP range[uuid:%s, CIDR:%s], the new IP range[CIDR:%s] is not in the CIDR with the existing one", + "en_US": "multiple CIDR on the same L3 network is not allowed. There has been a IP range[uuid:{0}, CIDR:{1}], the new IP range[CIDR:{2}] is not in the CIDR with the existing one", + "zh_CN": "在相同的三层网络上多个CIDR是不允许的,已有的IP范围 [uuid: {0},CIDR: {1}]。新的IP范围 [CIDR: {2}] 不在现有的一个CIDR", "arguments": [ - "vid", - "msg.getProjectUuid()" + "r.getUuid()", + "rcidr", + "cidr" ], - "line": 420, - "fileName": "src/main/java/org/zstack/iam2/IAM2AttributeHelper.java" + "line": 596, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "Can not add both platform role and project role to virtual id", - "en_US": "Can not add both platform role and project role to virtual id", - "zh_CN": "", - "arguments": [], - "line": 450, - "fileName": "src/main/java/org/zstack/iam2/IAM2AttributeHelper.java" + "raw": "the endip[%s] is not in the subnet %s/%s", + "en_US": "the endip[{0}] is not in the subnet {1}/{2}", + "zh_CN": "IP段结束地址不在子网{1}/{2}范围内", + "arguments": [ + "ipr.getEndIp()", + "ipr.getStartIp()", + "ipr.getNetmask()" + ], + "line": 606, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "Can not add project role to platform virtual id[uuid:%s]", - "en_US": "Can not add project role to platform virtual id[uuid:{0}]", - "zh_CN": "", + "raw": "there has been a DNS[%s] on L3 network[uuid:%s]", + "en_US": "there has been a DNS[{0}] on L3 network[uuid:{1}]", + "zh_CN": "在三层网络[uuid:{1}]上已经存在一个DNS[{0}]", "arguments": [ - "virtualIDUuid" + "msg.getDns()", + "msg.getL3NetworkUuid()" ], - "line": 458, - "fileName": "src/main/java/org/zstack/iam2/IAM2AttributeHelper.java" + "line": 659, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "wrong virtual ID[name:%s], not existing or wrong password", - "en_US": "wrong virtual ID[name:{0}], not existing or wrong password", - "zh_CN": "错误的virtual ID[名称:{0}], 密码不存在或者密码错误", + "raw": "prefix [%s] is not a IPv4 network cidr", + "en_US": "prefix [{0}] is not a IPv4 network cidr", + "zh_CN": "网络段{0}不是合法的网络段", "arguments": [ - "msg.getName()" + "msg.getL3NetworkUuid()" ], - "line": 319, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" - }, - { - "raw": "additional authentication failed", - "en_US": "additional authentication failed", - "zh_CN": "附加认证失败", - "arguments": [], - "line": 326, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 692, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "project[name:%s] not existing", - "en_US": "project[name:{0}] not existing", - "zh_CN": "项目[name:{0}]不存在", + "raw": "nexthop[%s] is not a IPv4 address", + "en_US": "nexthop[{0}] is not a IPv4 address", + "zh_CN": "下一跳{0}不是有效的IP地址", "arguments": [ - "msg.getProjectName()" + "msg.getNexthop()" ], - "line": 366, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 679, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "no account found for project[uuid:%s, name:%s]", - "en_US": "no account found for project[uuid:{0}, name:{1}]", - "zh_CN": "", + "raw": "there has been a hostroute for prefix[%s] on L3 network[uuid:%s]", + "en_US": "there has been a hostroute for prefix[{0}] on L3 network[uuid:{1}]", + "zh_CN": "三层网络{1}已配置物理机路由{0}", "arguments": [ - "puuid", - "msg.getProjectName()" + "msg.getPrefix()", + "msg.getL3NetworkUuid()" ], - "line": 374, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 686, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "wrong virtual ID[uuid:%s], not existing or wrong password", - "en_US": "wrong virtual ID[uuid:{0}], not existing or wrong password", - "zh_CN": "错误的virtual ID[uuid:{0}], 密码不存在或者密码错误", + "raw": "there is no hostroute for prefix[%s] on L3 network[uuid:%s]", + "en_US": "there is no hostroute for prefix[{0}] on L3 network[uuid:{1}]", + "zh_CN": "三层网络{1}没有物理机路由{0}", "arguments": [ - "msg.getSession().getUserUuid()" + "msg.getPrefix()", + "msg.getL3NetworkUuid()" ], - "line": 380, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 699, + "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" }, { - "raw": "virtual ID[name:%s] is disabled", - "en_US": "virtual ID[name:{0}] is disabled", - "zh_CN": "virtual ID[名称:{0}]不可用", + "raw": "apply gratuitous arp error, because:%s", + "en_US": "apply gratuitous arp error, because:{0}", + "zh_CN": "应用无故ARP错误,原因:{0}", "arguments": [ - "vid.getName()" + "rsp.getError()" ], - "line": 385, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 286, + "fileName": "src/main/java/org/zstack/network/plugin/FlatGratuitousARPBackend.java" }, { - "raw": "virtual ID[name:%s] not belonging to the project[name:%s]", - "en_US": "virtual ID[name:{0}] not belonging to the project[name:{1}]", - "zh_CN": "virtual ID[名称:{0}]不属于项目[name:{1}]", + "raw": "release gratuitous arp error, because:%s", + "en_US": "release gratuitous arp error, because:{0}", + "zh_CN": "释放无端的ARP错误,原因:{0}", "arguments": [ - "vid.getName()", - "msg.getProjectName()" + "rsp.getError()" ], - "line": 391, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 329, + "fileName": "src/main/java/org/zstack/network/plugin/FlatGratuitousARPBackend.java" }, { - "raw": "There are %d problems with the file. ", - "en_US": "There are {0} problems with the file. ", - "zh_CN": "文件中包含{0}个错误", + "raw": "could no set vm nic security group, because vm nic[uuid:%s] not found", + "en_US": "could no set vm nic security group, because vm nic[uuid:{0}] not found", + "zh_CN": "无法设置VM NIC安全组,因为找不到VM NIC[uuid:{0}]", "arguments": [ - "results.size()" + "msg.getVmNicUuid()" ], - "line": 647, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 248, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "fail to load VirtualID info from file. because\\n%s", - "en_US": "fail to load VirtualID info from file. because\\n{0}", - "zh_CN": "解析文件内容出错,{0}", + "raw": "could no set vm nic security group, because the vm nic[uuid:%s] not attached to any security group", + "en_US": "could no set vm nic security group, because the vm nic[uuid:{0}] not attached to any security group", + "zh_CN": "无法设置VM NIC安全组,因为VM NIC[uuid:{0}]未连接到任何安全组", "arguments": [ - "e.getMessage()" + "msg.getVmNicUuid()" ], - "line": 664, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" - }, - { - "raw": "name cannot be empty. ", - "en_US": "name cannot be empty. ", - "zh_CN": "名称不能为空", - "arguments": [], - "line": 675, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 254, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "userName[%s] is repeated. ", - "en_US": "userName[{0}] is repeated. ", - "zh_CN": "用户名[{0}]重复", + "raw": "could no set vm nic security group, because security group[uuid:%s] not found", + "en_US": "could no set vm nic security group, because security group[uuid:{0}] not found", + "zh_CN": "无法设置VM NIC安全组,因为找不到安全组[uuid:{0}]", "arguments": [ - "cmsg.getUsername()" + "ao.getSecurityGroupUuid()" ], - "line": 683, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 261, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "name exceeds max length of string. expected was \u003c\u003d 255, actual was %s. ", - "en_US": "name exceeds max length of string. expected was \u003c\u003d 255, actual was {0}. ", - "zh_CN": "名称字符数量不能超过255", + "raw": "could no set vm nic security group, because invalid priority, priority[%d] cannot be less than 1", + "en_US": "could no set vm nic security group, because invalid priority, priority[{0}] cannot be less than 1", + "zh_CN": "无法设置VM NIC安全组,因为优先级无效,优先级[{0}]不能小于1", "arguments": [ - "cmsg.username.length()" + "priority" ], - "line": 681, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" - }, - { - "raw": "username cannot be empty. ", - "en_US": "username cannot be empty. ", - "zh_CN": "用户名不能为空", - "arguments": [], - "line": 679, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 266, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Incorrect password length. expected was \u003e\u003d 6 and \u003c\u003d 255, actual was %s. ", - "en_US": "Incorrect password length. expected was \u003e\u003d 6 and \u003c\u003d 255, actual was {0}. ", - "zh_CN": "密码长度错误,应该大于等于6个字符,小于等于255字符", + "raw": "could no set vm nic security group, because duplicate priority, both security group %s and %s have priority[%d]", + "en_US": "could no set vm nic security group, because duplicate priority, both security group {0} and {1} have priority[{2}]", + "zh_CN": "无法设置VM NIC安全组,因为优先级重复,安全组{0}和{1}都具有优先级[{2}]", "arguments": [ - "cmsg.password.length()" + "aoMap.get(priority)", + "ao.getSecurityGroupUuid()", + "priority" ], - "line": 689, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" - }, - { - "raw": "password cannot be empty. ", - "en_US": "password cannot be empty. ", - "zh_CN": "密码不能为空", - "arguments": [], - "line": 687, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" - }, - { - "raw": "email format does not match. ", - "en_US": "email format does not match. ", - "zh_CN": "邮箱格式错误", - "arguments": [], - "line": 697, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 270, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organization[%s] is not exist. ", - "en_US": "organization[{0}] is not exist. ", - "zh_CN": "部门[{0}]不存在", + "raw": "could no set vm nic security group, because duplicate security group[uuid:%s]", + "en_US": "could no set vm nic security group, because duplicate security group[uuid:{0}]", + "zh_CN": "无法设置VM NIC安全组,因为安全组[uuid:{0}]重复", "arguments": [ - "noMatchNames" + "ao.getSecurityGroupUuid()" ], - "line": 753, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 273, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organization[%s] in line is repeated. ", - "en_US": "organization[{0}] in line is repeated. ", - "zh_CN": "部门[{0}]出现重复", + "raw": "could no set vm nic security group, because invalid priority, priority expects to start at 1, but [%d]", + "en_US": "could no set vm nic security group, because invalid priority, priority expects to start at 1, but [{0}]", + "zh_CN": "无法设置VM NIC安全组,因为优先级无效,优先级应从1开始,但[{0}]", "arguments": [ - "repeatNames" + "priorities[0]" ], - "line": 761, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 285, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organization[%s] is repeated. ", - "en_US": "organization[{0}] is repeated. ", - "zh_CN": "部门[{0}]出现重复", + "raw": "could no set vm nic security group, because invalid priority, priority[%d] and priority[%d] expected to be consecutive", + "en_US": "could no set vm nic security group, because invalid priority, priority[{0}] and priority[{1}] expected to be consecutive", + "zh_CN": "无法设置VM NIC安全组,因为优先级无效,优先级[{0}]和优先级[{1}]应是连续的", "arguments": [ - "repeatNames" + "priorities[i]", + "priorities[i + 1]" ], - "line": 769, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 289, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "project[%s] is not exist. ", - "en_US": "project[{0}] is not exist. ", - "zh_CN": "项目[{0}]不存在", + "raw": "could no set vm nic security Group, because securityGroup[uuid:%s] is already attached on this nic by account[uuid:%s], current user does not have permission to delete", + "en_US": "could no set vm nic security Group, because securityGroup[uuid:{0}] is already attached on this nic by account[uuid:{1}], current user does not have permission to delete", + "zh_CN": "无法设置VM NIC安全组,因为SecurityGroup[uuid:{0}]已由帐户[uuid:{1}]附加在此NIC上,当前用户没有删除权限", "arguments": [ - "noMatchName" + "ref.getSecurityGroupUuid()", + "sgOwnerAccountUuid" ], - "line": 799, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 301, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "fail to build VirtualID info from file. ", - "en_US": "fail to build VirtualID info from file. ", - "zh_CN": "不能解析文件内容", + "raw": "could no change security group rule state, because ruleUuids is empty", + "en_US": "could no change security group rule state, because ruleUuids is empty", + "zh_CN": "无法更改安全组规则状态,因为RuleUIds为空", "arguments": [], - "line": 963, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 310, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "virtualID[uuid:%s] not in project[uuid:%s]", - "en_US": "virtualID[uuid:{0}] not in project[uuid:{1}]", - "zh_CN": "", + "raw": "could no change security group rule state, because security group[uuid:%s] not found", + "en_US": "could no change security group rule state, because security group[uuid:{0}] not found", + "zh_CN": "无法更改安全组规则状态,因为找不到安全组[uuid:{0}]", "arguments": [ - "resourceUuid", - "projectUuid" + "msg.getSecurityGroupUuid()" ], - "line": 1034, - "fileName": "src/main/java/org/zstack/iam2/IAM2ManagerImpl.java" + "line": 314, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Can not do operations, because current organization[uuid:%s] is staled, please enable it", - "en_US": "Can not do operations, because current organization[uuid:{0}] is staled, please enable it", - "zh_CN": "", + "raw": "could no change security group rule state, because security group rule[uuid:%s] not found", + "en_US": "could no change security group rule state, because security group rule[uuid:{0}] not found", + "zh_CN": "无法更改安全组规则状态,因为找不到安全组规则[uuid:{0}]", "arguments": [ - "self.getUuid()" + "r" ], - "line": 86, - "fileName": "src/main/java/org/zstack/iam2/IAM2OrganizationBase.java" + "line": 322, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organization[uuid:%s] is parent of the organization[uuid:%s], cannot set it as a child organization", - "en_US": "organization[uuid:{0}] is parent of the organization[uuid:{1}], cannot set it as a child organization", - "zh_CN": "部门[uuid:{0}]是部门[uuid:{1}]的上级部门,无法被设置为子部门", - "arguments": [ - "puuid", - "self.getUuid()" - ], - "line": 192, - "fileName": "src/main/java/org/zstack/iam2/IAM2OrganizationBase.java" + "raw": "could no change security group rule state, because no security group rule state need to change", + "en_US": "could no change security group rule state, because no security group rule state need to change", + "zh_CN": "无法更改安全组规则状态,因为无需更改安全组规则状态", + "arguments": [], + "line": 331, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the project[uuid: %s, name:%s] is in state of %s which disallows the operation[%s]", - "en_US": "the project[uuid: {0}, name:{1}] is in state of {2} which disallows the operation[{3}]", - "zh_CN": "项目[[uuid: {0}, 名称:{1}]]是{2}状态,不允许执行[{3}]操作", - "arguments": [ - "self.getUuid()", - "self.getName()", - "self.getState()", - "msg.getClass()" - ], - "line": 106, - "fileName": "src/main/java/org/zstack/iam2/IAM2ProjectBase.java" + "raw": "could no change vm nic security policy, because ingress policy and egress policy cannot be both null", + "en_US": "could no change vm nic security policy, because ingress policy and egress policy cannot be both null", + "zh_CN": "无法更改VM NIC安全策略,因为入口策略和出口策略不能同时为空", + "arguments": [], + "line": 339, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Can not do operations, because Current virtualID[uuid:%s] is staled, please enable it", - "en_US": "Can not do operations, because Current virtualID[uuid:{0}] is staled, please enable it", - "zh_CN": "", + "raw": "could no change vm nic security policy, because invalid ingress policy[%s]", + "en_US": "could no change vm nic security policy, because invalid ingress policy[{0}]", + "zh_CN": "无法更改VM NIC安全策略,因为入口策略[{0}]无效", "arguments": [ - "self.getUuid()" + "msg.getIngressPolicy()" ], - "line": 132, - "fileName": "src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java" + "line": 342, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "only admin and the virtual ID itself can do the update", - "en_US": "only admin and the virtual ID itself can do the update", - "zh_CN": "只有admin和virtual ID本身可以执行更新操作", - "arguments": [], - "line": 554, - "fileName": "src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java" + "raw": "could no change vm nic security policy, because invalid egress policy[%s]", + "en_US": "could no change vm nic security policy, because invalid egress policy[{0}]", + "zh_CN": "无法更改VM NIC安全策略,因为出口策略[{0}]无效", + "arguments": [ + "msg.getEgressPolicy()" + ], + "line": 346, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "old password is not equal to the original password, cannot update the password of virtual ID[uuid:%s]", - "en_US": "old password is not equal to the original password, cannot update the password of virtual ID[uuid:{0}]", - "zh_CN": "", + "raw": "could no change vm nic security policy, because vm nic[uuid:%s] not found", + "en_US": "could no change vm nic security policy, because vm nic[uuid:{0}] not found", + "zh_CN": "无法更改VM NIC安全策略,因为找不到VM NIC[uuid:{0}]", "arguments": [ - "msg.getVirtualIDUuid()" + "msg.getVmNicUuid()" ], - "line": 558, - "fileName": "src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java" + "line": 350, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute name cannot be null, value[%s]", - "en_US": "attribute name cannot be null, value[{0}]", - "zh_CN": "属性不能为null,输入值[{0}]", + "raw": "could no change vm nic security policy, because vm nic[uuid:%s] has no security policy", + "en_US": "could no change vm nic security policy, because vm nic[uuid:{0}] has no security policy", + "zh_CN": "无法更改VM NIC安全策略,因为VM NIC[uuid:{0}]没有安全策略", + "arguments": [ + "msg.getVmNicUuid()" + ], + "line": 355, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "could not update security group rule priority, because invalid type[%s]", + "en_US": "could not update security group rule priority, because invalid type[{0}]", + "zh_CN": "无法更新安全组规则优先级,因为类型[{0}]无效", "arguments": [ - "attr.getValue()" + "msg.getType()" ], - "line": 43, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 369, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute name[%s] exceed the max length of 2048 chars", - "en_US": "attribute name[{0}] exceed the max length of 2048 chars", - "zh_CN": "属性名称[{0}]不能超过2048个字符", + "raw": "could not update security group rule priority, because security group[uuid:%s] is not exist", + "en_US": "could not update security group rule priority, because security group[uuid:{0}] is not exist", + "zh_CN": "无法更新安全组规则优先级,因为安全组[uuid:{0}]不存在", "arguments": [ - "attr.getName()" + "msg.getSecurityGroupUuid()" ], - "line": 47, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 374, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute[name:%s] value[%s] exceed the max length of 2048 chars", - "en_US": "attribute[name:{0}] value[{1}] exceed the max length of 2048 chars", - "zh_CN": "属性[name:{0}] value[{1}]不能超过2048个字符", + "raw": "could not update security group rule priority, because rules is empty", + "en_US": "could not update security group rule priority, because rules is empty", + "zh_CN": "无法更新安全组规则优先级,因为规则为空", + "arguments": [], + "line": 378, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "could not update security group rule priority, because security group[uuid:%s] rules size not match", + "en_US": "could not update security group rule priority, because security group[uuid:{0}] rules size not match", + "zh_CN": "无法更新安全组规则优先级,因为安全组[uuid:{0}]规则大小不匹配", "arguments": [ - "attr.getName()", - "attr.getValue()" + "msg.getSecurityGroupUuid()" ], - "line": 50, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 388, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "admin is a reserved name, please use another name", - "en_US": "admin is a reserved name, please use another name", - "zh_CN": "admin是保留名称,请使用其他名称", - "arguments": [], - "line": 151, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "raw": "could not update security group rule priority, because rule priority[%d] is invalid", + "en_US": "could not update security group rule priority, because rule priority[{0}] is invalid", + "zh_CN": "无法更新安全组规则优先级,因为规则优先级[{0}]无效", + "arguments": [ + "ao.getPriority()" + ], + "line": 393, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid name[%s], there has been a project or account with the same name", - "en_US": "invalid name[{0}], there has been a project or account with the same name", - "zh_CN": "无效的名称[{0}],已经存在同名的项目或账户", + "raw": "could not update security group rule priority, because priority[%d] has duplicate", + "en_US": "could not update security group rule priority, because priority[{0}] has duplicate", + "zh_CN": "无法更新安全组规则优先级,因为优先级[{0}]重复", "arguments": [ - "msg.getName()" + "ao.getPriority()" ], - "line": 159, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 396, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute[uuid:%s] is not for any group", - "en_US": "attribute[uuid:{0}] is not for any group", - "zh_CN": "", + "raw": "could not update security group rule priority, because rule[uuid:%s] not in security group[uuid:%s]", + "en_US": "could not update security group rule priority, because rule[uuid:{0}] not in security group[uuid:{1}]", + "zh_CN": "无法更新安全组规则优先级,因为规则[uuid:{0}]不在安全组[uuid:{1}]中", "arguments": [ - "msg.getUuid()" + "ao.getRuleUuid()", + "msg.getSecurityGroupUuid()" ], - "line": 167, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 402, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute[uuid:%s] is not for any organization", - "en_US": "attribute[uuid:{0}] is not for any organization", - "zh_CN": "", + "raw": "could not update security group rule priority, because priority[%d] not in security group[uuid:%s]", + "en_US": "could not update security group rule priority, because priority[{0}] not in security group[uuid:{1}]", + "zh_CN": "无法更新安全组规则优先级,因为优先级[{0}]不在安全组[uuid:{1}]中", "arguments": [ - "msg.getUuid()" + "ao.getPriority()", + "msg.getSecurityGroupUuid()" ], - "line": 175, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 405, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute[uuid:%s] is not for any project", - "en_US": "attribute[uuid:{0}] is not for any project", - "zh_CN": "", + "raw": "could not update security group rule priority, because rule uuid duplicate", + "en_US": "could not update security group rule priority, because rule uuid duplicate", + "zh_CN": "无法更新安全组规则优先级,因为规则uuid重复", + "arguments": [], + "line": 410, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "could not change security group rule, because security group rule uuid[%s] is not exist", + "en_US": "could not change security group rule, because security group rule uuid[{0}] is not exist", + "zh_CN": "无法更改安全组规则,因为安全组规则uuid[{0}]不存在", "arguments": [ "msg.getUuid()" ], - "line": 183, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 417, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute[uuid:%s] is not for any virtual ID", - "en_US": "attribute[uuid:{0}] is not for any virtual ID", - "zh_CN": "", + "raw": "could not change security group rule, because security group rule[%s] is default rule, only the description and status can be set", + "en_US": "could not change security group rule, because security group rule[{0}] is default rule, only the description and status can be set", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]是默认规则,只能设置描述和状态", "arguments": [ "msg.getUuid()" ], - "line": 191, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 423, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "retire policy must be deleted before pull the project out of Retired state", - "en_US": "retire policy must be deleted before pull the project out of Retired state", - "zh_CN": "", - "arguments": [], - "line": 211, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "raw": "could not change security group rule, because security group rule[%s] priority cannot be set to default rule priority[%d]", + "en_US": "could not change security group rule, because security group rule[{0}] priority cannot be set to default rule priority[{1}]", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]优先级无法设置为默认规则优先级[{1}]", + "arguments": [ + "msg.getUuid()", + "SecurityGroupConstant.DEFAULT_RULE_PRIORITY" + ], + "line": 429, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "login is prohibited because the project is in state of %s", - "en_US": "login is prohibited because the project is in state of {0}", - "zh_CN": "", + "raw": "could not change security group rule, because security group %s rules number[%d] is out of max limit[%d]", + "en_US": "could not change security group rule, because security group {0} rules number[{1}] is out of max limit[{2}]", + "zh_CN": "无法更改安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}]", "arguments": [ - "state" + "vo.getType()", + "count.intValue()", + "SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)" ], - "line": 223, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 438, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "no quota[name:%s] found", - "en_US": "no quota[name:{0}] found", - "zh_CN": "", + "raw": "could not change security group rule, because the maximum priority of %s rule is [%d]", + "en_US": "could not change security group rule, because the maximum priority of {0} rule is [{1}]", + "zh_CN": "无法更改安全组规则,因为{0}规则的最高优先级为[{1}]", "arguments": [ - "name" + "vo.getType().toString()", + "count.intValue()" ], - "line": 237, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 441, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organization[uuid:%s] is a Company that cannot have parent organization", - "en_US": "organization[uuid:{0}] is a Company that cannot have parent organization", - "zh_CN": "", + "raw": "could not change security group rule, because invalid state[%s]", + "en_US": "could not change security group rule, because invalid state[{0}]", + "zh_CN": "无法更改安全组规则,因为状态[{0}]无效", "arguments": [ - "msg.getUuid()" + "msg.getState()" ], - "line": 261, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 450, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "duplicate virtualID name[%s]", - "en_US": "duplicate virtualID name[{0}]", - "zh_CN": "重复的用户名[{0}]", + "raw": "could not change security group rule, because invalid action[%s]", + "en_US": "could not change security group rule, because invalid action[{0}]", + "zh_CN": "无法更改安全组规则,因为操作[{0}]无效", "arguments": [ - "msg.getName()" + "msg.getAction()" ], - "line": 273, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 458, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "duplicate project name[%s]", - "en_US": "duplicate project name[{0}]", - "zh_CN": "重复的项目名[{0}]", + "raw": "could not change security group rule, because invalid protocol[%s]", + "en_US": "could not change security group rule, because invalid protocol[{0}]", + "zh_CN": "无法更改安全组规则,因为协议[{0}]无效", "arguments": [ - "msg.getName()" + "msg.getProtocol()" ], - "line": 291, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 466, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid project name[%s], an account or project with the same name exists", - "en_US": "invalid project name[{0}], an account or project with the same name exists.", - "zh_CN": "无效的项目名[{0}],已有账户或项目使用了相同的名称", + "raw": "could not change security group rule, because security group rule[%s] type is Egress, srcIpRange[%s] cannot be set", + "en_US": "could not change security group rule, because security group rule[{0}] type is Egress, srcIpRange[{1}] cannot be set", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]类型为出口,无法设置SrcIPRange[{1}]", "arguments": [ - "msg.getName()" + "msg.getUuid()", + "msg.getSrcIpRange()" ], - "line": 299, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 498, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "The project[uuid\u003d%s] has been attached to the organization[uuid\u003d%s]", - "en_US": "The project[uuid\u003d{0}] has been attached to the organization[uuid\u003d{1}]", - "zh_CN": "", + "raw": "could not change security group rule, because security group rule[%s] type is Ingress, dstIpRange[%s] cannot be set", + "en_US": "could not change security group rule, because security group rule[{0}] type is Ingress, dstIpRange[{1}] cannot be set", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]类型为入口,无法设置DSTIPRange[{1}]", "arguments": [ - "refVO.getProjectUuid()", - "refVO.getOrganizationUuid()" + "msg.getUuid()", + "msg.getDstIpRange()" ], - "line": 315, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 495, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "The project[uuid\u003d%s] is not attached", - "en_US": "The project[uuid\u003d{0}] is not attached", - "zh_CN": "", + "raw": "could not change security group rule, because srcIpRange[%s] is set, remoteSecurityGroupUuid[%s] must be empty", + "en_US": "could not change security group rule, because srcIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty", + "zh_CN": "无法更改安全组规则,因为已设置SrcIPRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空", "arguments": [ - "msg.getProjectUuid()" + "msg.getSrcIpRange()", + "msg.getRemoteSecurityGroupUuid()" ], - "line": 325, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 488, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organizations%s are company that cannot be children of other organization", - "en_US": "organizations{0} are company that cannot be children of other organization", - "zh_CN": "组织{0}类型是子公司,不能设置为其它组织的部门", + "raw": "could not change security group rule, because dstIpRange[%s] is set, remoteSecurityGroupUuid[%s] must be empty", + "en_US": "could not change security group rule, because dstIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty", + "zh_CN": "无法更改安全组规则,因为已设置DSTIPRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空", "arguments": [ - "uuids" + "msg.getDstIpRange()", + "msg.getRemoteSecurityGroupUuid()" ], - "line": 336, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 501, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not operate stale virtual ids: %s", - "en_US": "can not operate stale virtual ids: {0}", - "zh_CN": "无法操作无效的用户: {0}", + "raw": "could not change security group rule, because remote security group[uuid:%s] not found", + "en_US": "could not change security group rule, because remote security group[uuid:{0}] not found", + "zh_CN": "无法更改安全组规则,因为找不到远程安全组[uuid:{0}]", "arguments": [ - "staleVirtualIDs" + "msg.getRemoteSecurityGroupUuid()" ], - "line": 398, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 508, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "virtual ids%s not in the project the group[uuid:%s] belongs to", - "en_US": "virtual ids{0} not in the project the group[uuid:{1}] belongs to", - "zh_CN": "用户{0}不在用户组[uuid:{1}]所在的项目中", + "raw": "could not change security group rule, because remote security group[uuid:%s] is set, srcIpRange and dstIpRange must be empty", + "en_US": "could not change security group rule, because remote security group[uuid:{0}] is set, srcIpRange and dstIpRange must be empty", + "zh_CN": "无法更改安全组规则,因为已设置远程安全组[uuid:{0}],SrcIPRange和DstIPRange必须为空", "arguments": [ - "wrong", - "msg.getGroupUuid()" + "msg.getRemoteSecurityGroupUuid()" ], - "line": 417, - "fileName": "src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java" + "line": 511, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "attribute[name:%s] is a system attribute that cannot be updated", - "en_US": "attribute[name:{0}] is a system attribute that cannot be updated", - "zh_CN": "属性[名称:{0}]是一个系统属性,无法被更新", - "arguments": [], - "line": 69, - "fileName": "src/main/java/org/zstack/iam2/attribute/SystemAttributes.java" + "raw": "could not change security group rule, because rule protocol is [%s], dstPortRange must be set", + "en_US": "could not change security group rule, because rule protocol is [{0}], dstPortRange must be set", + "zh_CN": "无法更改安全组规则,因为规则协议为[{0}],必须设置DSTPortRange", + "arguments": [ + "msg.getProtocol()" + ], + "line": 564, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "virtual ID[uuid:%s] not existing", - "en_US": "virtual ID[uuid:{0}] not existing", - "zh_CN": "用户[uuid:{0}]不存在", + "raw": "could not change security group rule, because rule protocol is [%s], dstPortRange cannot be empty", + "en_US": "could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be empty", + "zh_CN": "无法更改安全组规则,因为规则协议为[{0}],DstPortRange不能为空", "arguments": [ - "inv.getValue()" + "msg.getProtocol()" ], - "line": 37, - "fileName": "src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java" + "line": 556, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "virtual ID[uuid:%s] not in organization[uuid:%s]", - "en_US": "virtual ID[uuid:{0}] not in organization[uuid:{1}]", - "zh_CN": "", + "raw": "could not change security group rule, because rule protocol is [%s], dstPortRange cannot be set", + "en_US": "could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be set", + "zh_CN": "无法更改安全组规则,因为规则协议为[{0}],无法设置目标映射", "arguments": [ - "inv.getValue()", - "((IAM2OrganizationAttributeInventory) inv).getOrganizationUuid()" + "msg.getProtocol()" ], - "line": 44, - "fileName": "src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java" + "line": 551, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "organization[uuid:%s] already has a supervisor", - "en_US": "organization[uuid:{0}] already has a supervisor", - "zh_CN": "组织[uuid:{0}]已经设置了负责人", + "raw": "could not change security group rule, because rule[%s] is duplicated to rule[uuid:%s] in datebase", + "en_US": "could not change security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase", + "zh_CN": "无法更改安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复", "arguments": [ - "oinv.getOrganizationUuid()" + "JSONObjectUtil.toJsonString(sao)", + "o.getUuid()" ], - "line": 49, - "fileName": "src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java" + "line": 595, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the project[uuid:%s, name:%s] already has a retire policy", - "en_US": "the project[uuid:{0}, name:{1}] already has a retire policy", - "zh_CN": "项目[uuid:{0}, name:{1}]已经设置了回收策略", + "raw": "security group[uuid:%s] has not attached to l3Network[uuid:%s], can\u0027t detach", + "en_US": "security group[uuid:{0}] has not attached to l3Network[uuid:{1}], can\u0027t detach", + "zh_CN": "不能卸载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为还未挂载", "arguments": [ - "pinv.getUuid()", - "pinv.getName()" + "msg.getSecurityGroupUuid()", + "msg.getL3NetworkUuid()" ], - "line": 65, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/Retire.java" + "line": 721, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid value, no \u0027at\u0027, \u0027after\u0027 or \u0027exceed\u0027 found", - "en_US": "invalid value, no \u0027at\u0027, \u0027after\u0027 or \u0027exceed\u0027 found", - "zh_CN": "无效的值,找不到关键字no \u0027at\u0027, \u0027after\u0027 or \u0027exceed\u0027", + "raw": "can\u0027t delete rules of different security group", + "en_US": "can\u0027t delete rules of different security group", + "zh_CN": "无法删除不同安全组的规则", "arguments": [], - "line": 52, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 757, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid value, %s", - "en_US": "invalid value, {0}", - "zh_CN": "无效的值, {0}", + "raw": "can\u0027t delete default rule[uuid:%s]", + "en_US": "can\u0027t delete default rule[uuid:{0}]", + "zh_CN": "无法删除默认规则[uuid:{0}]", "arguments": [ - "value" + "vo.getUuid()" ], - "line": 57, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 760, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid means[%s], allowed means are %s", - "en_US": "invalid means[{0}], allowed means are {1}", - "zh_CN": "无效的回收方法[{0}],允许的方法是{1}", + "raw": "security group[uuid:%s] has attached to l3Network[uuid:%s], can\u0027t attach again", + "en_US": "security group[uuid:{0}] has attached to l3Network[uuid:{1}], can\u0027t attach again", + "zh_CN": "不能再次挂载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为已经挂载了", "arguments": [ - "ss[0]", - "Means.values()" + "msg.getSecurityGroupUuid()", + "msg.getL3NetworkUuid()" ], - "line": 63, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 780, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "the L3 network[uuid:%s] doesn\u0027t have the network service type[%s] enabled", + "en_US": "the L3 network[uuid:{0}] doesn\u0027t have the network service type[{1}] enabled", + "zh_CN": "三层网络[uuid:{0}]没有开启[{1}]类型的网络服务", + "arguments": [ + "msg.getL3NetworkUuid()", + "SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE" + ], + "line": 788, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid spending value[%s], it should be in format of for example 10.001", - "en_US": "invalid spending value[{0}], it should be in format of for example 10.001", - "zh_CN": "无效的费用[{0}], 费用格式应该符合例如:10.001", + "raw": "VM nics[uuids:%s] are not on L3 networks that have been attached to the security group[uuid:%s]", + "en_US": "VM nics[uuids:{0}] are not on L3 networks that have been attached to the security group[uuid:{1}]", + "zh_CN": "云主机网卡[uuids:{0}]不在安全组[uuid:{1}]挂载的三层网络上", "arguments": [ - "policyValue" + "wrongUuids", + "securityGroupUuid" ], - "line": 98, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 850, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid spending value[%s], spending value should between 0 and %f", - "en_US": "invalid spending value[{0}], spending value should between 0 and {1}", - "zh_CN": "无效的费用[{0}], 费用范围应该在0到{1}之间", + "raw": "could not add security group rule, because security group[uuid:%s] does not exist", + "en_US": "could not add security group rule, because security group[uuid:{0}] does not exist", + "zh_CN": "无法添加安全组规则,因为安全组[uuid:{0}]不存在", "arguments": [ - "policyValue", - "Double.MAX_VALUE" + "uuid" ], - "line": 92, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 886, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid time[%s], it should be in format of for example 10m, 1h, 2d", - "en_US": "invalid time[{0}], it should be in format of for example 10m, 1h, 2d", - "zh_CN": "无效的时间[{0}],时间格式需要符合例如:10m, 1h, 2d", + "raw": "could not add security group rule, because the rules cannot be empty or exceed the max number %d", + "en_US": "could not add security group rule, because the rules cannot be empty or exceed the max number {0}", + "zh_CN": "无法添加安全组规则,因为规则不能为空或超过最大数量{0}", "arguments": [ - "policyValue" + "SecurityGroupConstant.ONE_API_RULES_MAX_NUM" ], - "line": 85, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 875, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid date[%s], it should be in format of yyyy-MM-dd HH:mm:ss", - "en_US": "invalid date[{0}], it should be in format of yyyy-MM-dd HH:mm:ss", - "zh_CN": "无效的日期,日期格式需要符合:yyyy-MM-dd HH:mm:ss", + "raw": "could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: %s", + "en_US": "could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: {0}", + "zh_CN": "无法添加安全组规则,因为RemoteSecurityGroupuuid中存在重复的uuid:{0}", "arguments": [ - "policyValue" + "msg.getRemoteSecurityGroupUuids()" ], - "line": 76, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "line": 880, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid date or time[%s], it cannot be before current time[%s]", - "en_US": "invalid date or time[{0}], it cannot be before current time[{1}]", - "zh_CN": "无效的日期或时间,回收时间不能在当前时间之前[{1}]", - "arguments": [ - "policyValue", - "dateFormat.format(new Timestamp(System.currentTimeMillis()))" - ], - "line": 105, - "fileName": "src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java" + "raw": "could not add security group rule, because the remote security group uuid is conflict", + "en_US": "could not add security group rule, because the remote security group uuid is conflict", + "zh_CN": "无法添加安全组规则,因为远程安全组uuid冲突", + "arguments": [], + "line": 891, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "virtual ID[uuid:%s] already has admin related attributes, can not add %s", - "en_US": "virtual ID[uuid:{0}] already has admin related attributes, can not add {1}", - "zh_CN": "用户[uuid:{0}]已经有管理员属性了,无法继续添加属性{1}", + "raw": "could not add security group rule, because rule priority must greater than %d or equals %d", + "en_US": "could not add security group rule, because rule priority must greater than {0} or equals {1}", + "zh_CN": "无法添加安全组规则,因为规则优先级必须大于{0}或等于{1}", "arguments": [ - "vid", - "attributeName" + "SecurityGroupConstant.DEFAULT_RULE_PRIORITY", + "SecurityGroupConstant.LOWEST_RULE_PRIORITY" ], - "line": 17, - "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/AbstractAdminAttribute.java" + "line": 927, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "virtual id[uuid:%s] already has a project operator attribute", - "en_US": "virtual id[uuid:{0}] already has a project operator attribute", - "zh_CN": "", + "raw": "could not add security group rule, because invalid rule type[%s], valid types are %s", + "en_US": "could not add security group rule, because invalid rule type[{0}], valid types are {1}", + "zh_CN": "无法添加安全组规则,因为规则类型[{0}]无效,有效类型为{1}", "arguments": [ - "idinv.getVirtualIDUuid()" + "ao.getType()", + "SecurityGroupRuleType.getAllType()" ], - "line": 35, - "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/IAM2ProjectOperator.java" + "line": 935, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find zone[uuid:%s]", - "en_US": "cannot find zone[uuid:{0}]", - "zh_CN": "找不到区域[uuid:{0}]", + "raw": "could not add security group rule, because invalid rule state[%s], valid states are %s", + "en_US": "could not add security group rule, because invalid rule state[{0}], valid states are {1}", + "zh_CN": "无法添加安全组规则,因为规则状态[{0}]无效,有效状态为{1}", "arguments": [ - "inv.getValue()" + "ao.getState()", + "SecurityGroupRuleState.getAllState()" ], - "line": 36, - "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/PlatformAdminZoneRelation.java" + "line": 942, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "project[uuid:%s] already has a project admin", - "en_US": "project[uuid:{0}] already has a project admin", - "zh_CN": "项目[uuid:{0}]已经设置过项目管理员了", + "raw": "could not add security group rule, because invalid rule protocol[%s], valid protocols are %s", + "en_US": "could not add security group rule, because invalid rule protocol[{0}], valid protocols are {1}", + "zh_CN": "无法添加安全组规则,因为规则协议[{0}]无效,有效协议为{1}", "arguments": [ - "inv.getValue()" + "ao.getProtocol()", + "SecurityGroupRuleProtocolType.getAllProtocol()" ], - "line": 71, - "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java" + "line": 947, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "project[uuid:%s] not existing", - "en_US": "project[uuid:{0}] not existing", - "zh_CN": "项目[uuid:{0}]不存在", + "raw": "could not add security group rule, because invalid rule action[%s], valid actions are %s", + "en_US": "could not add security group rule, because invalid rule action[{0}], valid actions are {1}", + "zh_CN": "无法添加安全组规则,因为规则操作[{0}]无效,有效操作为{1}", "arguments": [ - "inv.getValue()" + "ao.getAction()", + "SecurityGroupRuleAction.getAllAction()" ], - "line": 83, - "fileName": "src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java" + "line": 954, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the operations[%s] is denied", - "en_US": "the operations[{0}] is denied", - "zh_CN": "", + "raw": "could not add security group rule, because invalid rule ipVersion[%d], valid ipVersions are %d/%d", + "en_US": "could not add security group rule, because invalid rule ipVersion[{0}], valid ipVersions are {1}/{2}", + "zh_CN": "无法添加安全组规则,因为规则IPVersion[{0}]无效,有效的IPVersion为{1}/{2}", "arguments": [ - "deniedApis" + "ao.getIpVersion()", + "IPv6Constants.IPv4", + "IPv6Constants.IPv6" ], - "line": 130, - "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2AuthorizationBackend.java" + "line": 962, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "project of account[uuid:%s] not exists", - "en_US": "project of account[uuid:{0}] not exists", - "zh_CN": "账户为[uuid:{0}]的项目不存在", + "raw": "could not add security group rule, because the dstIpRange[%s] is not allowed to set for ingress rule", + "en_US": "could not add security group rule, because the dstIpRange[{0}] is not allowed to set for ingress rule", + "zh_CN": "无法添加安全组规则,因为不允许为入口规则设置DSTIPRange[{0}]", "arguments": [ - "session.getAccountUuid()" + "ao.getDstIpRange()" ], - "line": 28, - "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java" + "line": 990, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "project[uuid:%s] is retired, reject all operations", - "en_US": "project[uuid:{0}] is retired, reject all operations", - "zh_CN": "项目[uuid:{0}]已经过期,无法操作", + "raw": "could not add security group rule, because the allowedCidr[%s] and srcIpRange[%s] are in conflict", + "en_US": "could not add security group rule, because the allowedCidr[{0}] and srcIpRange[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为allowedcidr[{0}]和srciprange[{1}]冲突", "arguments": [ - "projectUuid" + "ao.getAllowedCidr()", + "ao.getSrcIpRange()" ], - "line": 37, - "fileName": "src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java" + "line": 995, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the user group[uuid:%s] does not belong to the account[uuid:%s]", - "en_US": "the user group[uuid:{0}] does not belong to the account[uuid:{1}]", - "zh_CN": "这个用户组[uuid:{0}]不属于当前账户[uuid:{1}]", + "raw": "could not add security group rule, because the ip range[%s] and remoteSecurityGroupUuid[%s] are in conflict", + "en_US": "could not add security group rule, because the ip range[{0}] and remoteSecurityGroupUuid[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为IP范围[{0}]和RemoteSecurityGroupuuid[{1}]冲突", "arguments": [ - "group.getUuid()", - "msg.getAccountUuid()" + "ao.getDstIpRange()", + "ao.getRemoteSecurityGroupUuid()" ], - "line": 323, - "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + "line": 984, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find Quota[name: %s] for the account[uuid: %s]", - "en_US": "cannot find Quota[name: {0}] for the account[uuid: {1}]", - "zh_CN": "无法为当前账户[uuid: {1}]找到Quota", + "raw": "could not add security group rule, because the srcIpRange[%s] is not allowed to set for egress rule", + "en_US": "could not add security group rule, because the srcIpRange[{0}] is not allowed to set for egress rule", + "zh_CN": "无法添加安全组规则,因为不允许为出口规则设置SrcIPRange[{0}]", "arguments": [ - "msg.getName()", - "msg.getIdentityUuid()" + "ao.getSrcIpRange()" ], - "line": 425, - "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + "line": 972, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the account[uuid: %s] doesn\u0027t have a resource[uuid: %s]", - "en_US": "the account[uuid: {0}] doesn\u0027t have a resource[uuid: {1}]", - "zh_CN": "账户[uuid: {0}]没有资源[uuid: {1}]", + "raw": "could not add security group rule, because the allowedCidr[%s] and dstIpRange[%s] are in conflict", + "en_US": "could not add security group rule, because the allowedCidr[{0}] and dstIpRange[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为AllowedCidr[{0}]和DSTIPRange[{1}]冲突", "arguments": [ - "self.getUuid()", - "ruuid" + "ao.getAllowedCidr()", + "ao.getDstIpRange()" ], - "line": 504, - "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + "line": 977, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the user[uuid:%s] does not belong to the account[uuid:%s]", - "en_US": "the user[uuid:{0}] does not belong to the account[uuid:{1}]", - "zh_CN": "当前用户[uuid:{0}]不属于当前账户[uuid:{1}]", + "raw": "could not add security group rule, because invalid rule endPort[%d], endPort must be greater than or equal to startPort[%d]", + "en_US": "could not add security group rule, because invalid rule endPort[{0}], endPort must be greater than or equal to startPort[{1}]", + "zh_CN": "无法添加安全组规则,因为规则endPort[{0}]无效,endPort必须大于或等于startPort[{1}]", "arguments": [ - "user.getUuid()", - "msg.getAccountUuid()" + "ao.getEndPort()", + "ao.getStartPort()" ], - "line": 561, - "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + "line": 1026, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "old password is not equal to the original password, cannot update the password of user[uuid:%s]", - "en_US": "old password is not equal to the original password, cannot update the password of user[uuid:{0}]", - "zh_CN": "", + "raw": "could not add security group rule, because dstPortRange[%s] and starPort[%s] are in conflict", + "en_US": "could not add security group rule, because dstPortRange[{0}] and starPort[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为DstPortRange[{0}]和StarPort[{1}]冲突", "arguments": [ - "user.getUuid()" + "ao.getDstPortRange()", + "ao.getStartPort()" ], - "line": 566, - "fileName": "src/main/java/org/zstack/identity/AccountBase.java" + "line": 1029, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "wrong password", - "en_US": "wrong password", - "zh_CN": "", + "raw": "could not add security group rule, because the protocol type TCP/UDP must set dstPortRange", + "en_US": "could not add security group rule, because the protocol type TCP/UDP must set dstPortRange", + "zh_CN": "无法添加安全组规则,因为协议类型TCP/UDP必须设置DSTPortRange", "arguments": [], - "line": 55, - "fileName": "src/main/java/org/zstack/identity/AccountInterceptor.java" + "line": 1040, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "a statement must have effect field. Invalid statement[%s]", - "en_US": "a statement must have effect field. Invalid statement[{0}]", - "zh_CN": "声明必须含有\u0027effect\u0027字段。 无效的声明", + "raw": "could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[%s]", + "en_US": "could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[{0}]", + "zh_CN": "无法添加安全组规则,因为协议类型ALL或ICMP无法设置DstPortRange[{0}]", "arguments": [ - "JSONObjectUtil.toJsonString(s)" + "ao.getDstPortRange()" ], - "line": 1612, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1018, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "a statement must have action field. Invalid statement[%s]", - "en_US": "a statement must have action field. Invalid statement[{0}]", - "zh_CN": "声明必须含有\u0027action\u0027字段。 无效的声明", - "arguments": [ - "JSONObjectUtil.toJsonString(s)" - ], - "line": 1615, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "raw": "could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort", + "en_US": "could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort", + "zh_CN": "无法添加安全组规则,因为协议类型ALL或ICMP无法设置StartPort或EndPort", + "arguments": [], + "line": 1021, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "a statement must have a non-empty action field. Invalid statement[%s]", - "en_US": "a statement must have a non-empty action field. Invalid statement[{0}]", - "zh_CN": "声明必须含有不为空的\u0027action\u0027字段。 无效的声明", + "raw": "could not add security group rule, because rule[%s] and rule[%s] are dupilicated", + "en_US": "could not add security group rule, because rule[{0}] and rule[{1}] are dupilicated", + "zh_CN": "无法添加安全组规则,因为规则[{0}]和规则[{1}]重复", "arguments": [ - "JSONObjectUtil.toJsonString(s)" + "JSONObjectUtil.toJsonString(newRules.get(i))", + "JSONObjectUtil.toJsonString(newRules.get(j))" ], - "line": 1618, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1050, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find the resource[uuid:%s]; wrong resourceUuid or the resource is admin resource", - "en_US": "cannot find the resource[uuid:{0}]; wrong resourceUuid or the resource is admin resource", - "zh_CN": "无法找到资源[uuid:{0}]: 错误的资源uuid或者资源是管理员资源", + "raw": "could not add security group rule, because rule[%s] is duplicated to rule[uuid:%s] in datebase", + "en_US": "could not add security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase", + "zh_CN": "无法添加安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复", "arguments": [ - "resourceUuid" + "JSONObjectUtil.toJsonString(sao)", + "vo.getUuid()" ], - "line": 165, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1074, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the user specified by the userUuid[%s] does not belong to the current account, and the current account is not an admin account, so it has no permission to check the user\u0027spermissions", - "en_US": "the user specified by the userUuid[{0}] does not belong to the current account, and the current account is not an admin account, so it has no permission to check the user\u0027spermissions", - "zh_CN": "当前通过userUuid获得的user不属于当前账户,而且当前账户不是管理员账户", + "raw": "could not add security group rule, because security group %s rules has reached the maximum limit[%d]", + "en_US": "could not add security group rule, because security group {0} rules has reached the maximum limit[{1}]", + "zh_CN": "无法添加安全组规则,因为安全组{0}规则已达到最大限制[{1}]", "arguments": [ - "msg.getUserUuid()" + "SecurityGroupRuleType.Egress", + "SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)" ], - "line": 399, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1089, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find the account[uuid:%s]", - "en_US": "cannot find the account[uuid:{0}]", - "zh_CN": "找不到账户[uuid:{0}]", + "raw": "could not add security group rule, because security group %s rules number[%d] is out of max limit[%d]", + "en_US": "could not add security group rule, because security group {0} rules number[{1}] is out of max limit[{2}]", + "zh_CN": "无法添加安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}]", "arguments": [ - "accountUuid" + "SecurityGroupRuleType.Egress", + "(egressRuleCount + toCreateEgressRuleCount)", + "SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)" ], - "line": 1009, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" - }, - { - "raw": "accountName and accountUuid cannot both be null, you must specify at least one", - "en_US": "accountName and accountUuid cannot both be null, you must specify at least one", - "zh_CN": "账户名和账户Uuid不能同时为空,您必须定义至少一个", - "arguments": [], - "line": 1447, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1097, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "unable to create a group. A group called %s is already under the account[uuid:%s]", - "en_US": "unable to create a group. A group called {0} is already under the account[uuid:{1}]", - "zh_CN": "不能创建用户组,用户组“{0}”已经在账户“{0}”下了", + "raw": "could not add security group rule, because priority[%d] must be consecutive, the ingress rule maximum priority is [%d]", + "en_US": "could not add security group rule, because priority[{0}] must be consecutive, the ingress rule maximum priority is [{1}]", + "zh_CN": "无法添加安全组规则,因为优先级[{0}]必须连续,入口规则最大优先级为[{1}]", "arguments": [ - "msg.getName()", - "msg.getAccountUuid()" + "msg.getPriority()", + "ingressRuleCount" ], - "line": 1458, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1101, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "unable to create a user. A user called %s is already under the account[uuid:%s]", - "en_US": "unable to create a user. A user called {0} is already under the account[uuid:{1}]", - "zh_CN": "不能创建用户,用户“{0}”已经在账户“{0}”下了", + "raw": "could not add security group rule, because priority[%d] must be consecutive, the egress rule maximum priority is [%d]", + "en_US": "could not add security group rule, because priority[{0}] must be consecutive, the egress rule maximum priority is [{1}]", + "zh_CN": "无法添加安全组规则,因为优先级[{0}]必须是连续的,出口规则最大优先级为[{1}]", "arguments": [ - "msg.getName()", - "msg.getAccountUuid()" + "msg.getPriority()", + "egressRuleCount" ], - "line": 1468, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1104, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "unable to create an account. An account already called %s", - "en_US": "unable to create an account. An account already called {0}", - "zh_CN": "不能创建账户,“{0}”已经被使用", + "raw": "vm nic[uuid:%s] has been attach to security group[uuid:%s]", + "en_US": "vm nic[uuid:{0}] has been attach to security group[uuid:{1}]", + "zh_CN": "VM NIC[uuid:{0}]已连接到安全组[uuid:{1}]", "arguments": [ - "msg.getName()" + "ref.getVmNicUuid()", + "msg.getSecurityGroupUuid()" ], - "line": 1477, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" - }, - { - "raw": "account cannot delete itself", - "en_US": "account cannot delete itself", - "zh_CN": "账户不能删除自己", - "arguments": [], - "line": 1484, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 1908, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java" }, { - "raw": "cannot delete builtin admin account.", - "en_US": "cannot delete builtin admin account.", - "zh_CN": "", - "arguments": [], - "line": 1490, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "raw": "the netwotk service[type:%s] not enabled on the l3Network[uuid:%s] of nic[uuid:%s]", + "en_US": "the netwotk service[type:{0}] not enabled on the l3Network[uuid:{1}] of nic[uuid:{2}]", + "zh_CN": "网络服务[类型:{0}]未在NIC[uuid:{2}]的L3网络[uuid:{1}]上启用", + "arguments": [ + "SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE", + "nic.getL3NetworkUuid()", + "nic.getUuid()" + ], + "line": 1917, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java" }, { - "raw": "Only admin can delete account.", - "en_US": "Only admin can delete account.", - "zh_CN": "只有admin能删除账户", - "arguments": [], - "line": 1496, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "raw": "the netwotk service[type:%s] not enabled on the l3Network[uuid:%s]", + "en_US": "the netwotk service[type:{0}] not enabled on the l3Network[uuid:{1}]", + "zh_CN": "未在L3网络[uuid:{1}]上启用网络服务[类型:{0}]", + "arguments": [ + "SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE", + "l3Uuid" + ], + "line": 153, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java" }, { - "raw": "the current session is an account session. You need to specify the field \u0027uuid\u0027 of the user you want to update", - "en_US": "the current session is an account session. You need to specify the field \u0027uuid\u0027 of the user you want to update", - "zh_CN": "当前会话是一个账户会话,你需要定义一个\u0027uuid\u0027字段来指定你要更新的用户", - "arguments": [], - "line": 1504, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "raw": "failed to chenge rule[uuid:%s] priority, beacuse it\u0027s not found", + "en_US": "failed to chenge rule[uuid:{0}] priority, beacuse it\u0027s not found", + "zh_CN": "无法更改规则[uuid:{0}]的优先级,因为找不到该优先级", + "arguments": [ + "ao.getRuleUuid()" + ], + "line": 1051, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java" }, { - "raw": "your are login as a user, you cannot another user[uuid:%s]", - "en_US": "your are login as a user, you cannot another user[uuid:{0}]", - "zh_CN": "你已经登录为一个用户,不能成为另一个用户[uuid:{0}]", + "raw": "L3Network [uuid: %s] provide type null", + "en_US": "L3Network [uuid: {0}] provide type null", + "zh_CN": "三层网络{0}后端为空", "arguments": [ - "msg.getUuid()" + "msg.getL3NetworkUuid()" ], - "line": 1519, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 88, + "fileName": "src/main/java/org/zstack/network/service/HostRouteExtension.java" }, { - "raw": "all is set to false, accountUuids cannot be null or empty", - "en_US": "all is set to false, accountUuids cannot be null or empty", - "zh_CN": "all参数被设为false时,账户uuid不能为空", - "arguments": [], - "line": 1527, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "raw": "L3Network [uuid: %s] does not have host route service", + "en_US": "L3Network [uuid: {0}] does not have host route service", + "zh_CN": "三层网络{0}没有物理机路由功能", + "arguments": [ + "msg.getL3NetworkUuid()" + ], + "line": 113, + "fileName": "src/main/java/org/zstack/network/service/HostRouteExtension.java" }, { - "raw": "toPublic is set to false, accountUuids cannot be null or empty", - "en_US": "toPublic is set to false, accountUuids cannot be null or empty", - "zh_CN": "toPublic参数被设为false时,账户uuid不能为空", + "raw": "networkServices cannot be empty", + "en_US": "networkServices cannot be empty", + "zh_CN": "网络服务(networkServices)不能为空", "arguments": [], - "line": 1535, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 107, + "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" }, { - "raw": "policy[name: %s, uuid: %s] doesn\u0027t belong to the account[uuid: %s]", - "en_US": "policy[name: {0}, uuid: {1}] doesn\u0027t belong to the account[uuid: {2}]", - "zh_CN": "策略[名称: {0}, uuid: {1}]不属于账户[uuid: {2}]", + "raw": "network service for provider[uuid:%s] must be specified", + "en_US": "network service for provider[uuid:{0}] must be specified", + "zh_CN": "服务提供器[uuid:{0}]的网络服务必须被指定", "arguments": [ - "policy.getName()", - "policy.getUuid()", - "msg.getSession().getAccountUuid()" + "puuid" ], - "line": 1584, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 68, + "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" }, { - "raw": "user[name: %s, uuid: %s] doesn\u0027t belong to the account[uuid: %s]", - "en_US": "user[name: {0}, uuid: {1}] doesn\u0027t belong to the account[uuid: {2}]", - "zh_CN": "用户[名称: {0}, uuid: {1}]不属于账户[uuid: {2}]", + "raw": "cannot find network service provider[uuid:%s] or it provides no services", + "en_US": "cannot find network service provider[uuid:{0}] or it provides no services", + "zh_CN": "无法找到网络服务提供器[uuid:{0}]或它没有提供任何服务", "arguments": [ - "user.getName()", - "user.getUuid()", - "msg.getSession().getAccountUuid()" + "puuid" ], - "line": 1598, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 73, + "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" }, { - "raw": "group[name: %s, uuid: %s] doesn\u0027t belong to the account[uuid: %s]", - "en_US": "group[name: {0}, uuid: {1}] doesn\u0027t belong to the account[uuid: {2}]", - "zh_CN": "用户组[名称: {0}, uuid: {1}]不属于账户[uuid: {2}]", + "raw": "network service provider[uuid:%s] doesn\u0027t provide services%s", + "en_US": "network service provider[uuid:{0}] doesn\u0027t provide services{1}", + "zh_CN": "网络服务提供器[uuid:{0}]无法提供服务{1}", "arguments": [ - "group.getName()", - "group.getUuid()", - "msg.getSession().getAccountUuid()" + "puuid", + "notSupported" ], - "line": 1602, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 87, + "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" }, { - "raw": "unable to update name. An account already called %s", - "en_US": "unable to update name. An account already called {0}", - "zh_CN": "", + "raw": "there has been a network service[%s] attached to L3 network[uuid:%s]", + "en_US": "there has been a network service[{0}] attached to L3 network[uuid:{1}]", + "zh_CN": "已经有一个网络服务[{0}]被挂载到三层网络[uuid:{1}]", "arguments": [ - "msg.getName()" + "type", + "msg.getL3NetworkUuid()" ], - "line": 1643, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 99, + "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" }, { - "raw": "old password is not equal to the original password, cannot update the password of account[uuid: %s]", - "en_US": "old password is not equal to the original password, cannot update the password of account[uuid: {0}]", - "zh_CN": "", + "raw": "L3Network[uuid:%s] doesn\u0027t have network service[type:%s] enabled or no provider provides this network service", + "en_US": "L3Network[uuid:{0}] doesn\u0027t have network service[type:{1}] enabled or no provider provides this network service", + "zh_CN": "三层网络[uuid:{0}]上没有网络服务[type:{1}]被启用或没有服务提供器提供该网络服务", "arguments": [ - "msg.getUuid()" + "l3NetworkUuid", + "serviceType" ], - "line": 1654, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 332, + "fileName": "src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java" }, { - "raw": "the name of admin account cannot be updated", - "en_US": "the name of admin account cannot be updated", - "zh_CN": "不能更改管理员账户名称", - "arguments": [], - "line": 1659, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "raw": "vmNic[uuid:%s] is not attached to vmInstance, cannot get attachable eips", + "en_US": "vmNic[uuid:{0}] is not attached to vmInstance, cannot get attachable eips", + "zh_CN": "vmnic[uuid:{0}]未连接到VMInstance,无法获取可连接的EIP", + "arguments": [ + "msg.getVmNicUuid()" + ], + "line": 87, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "only admin account can update it\u0027s password", - "en_US": "only admin account can update it\u0027s password", - "zh_CN": "", + "raw": "either eipUuid or vipUuid must be set", + "en_US": "either eipUuid or vipUuid must be set", + "zh_CN": "eipUuid或vipUuid必须有一个被指定", "arguments": [], - "line": 1665, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 93, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "account[uuid: %s, name: %s] is a normal account, it cannot reset the password of another account[uuid: %s]", - "en_US": "account[uuid: {0}, name: {1}] is a normal account, it cannot reset the password of another account[uuid: {2}]", - "zh_CN": "[uuid: {0}, 名称: {1}]是一个普通账户,不能被其他普通账户重设密码", + "raw": "eip[uuid:%s] is not in state of Enabled, cannot get attachable vm nic", + "en_US": "eip[uuid:{0}] is not in state of Enabled, cannot get attachable vm nic", + "zh_CN": "eip[uuid:{0}]没有被启用,无法获取可挂载的云主机网卡", "arguments": [ - "account.getUuid()", - "account.getName()", - "msg.getUuid()" + "msg.getEipUuid()" ], - "line": 1672, - "fileName": "src/main/java/org/zstack/identity/AccountManagerImpl.java" + "line": 99, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "permission denied, the account[uuid:%s] is not the owner of the resource[uuid:%s, type:%s]", - "en_US": "permission denied, the account[uuid:{0}] is not the owner of the resource[uuid:{1}, type:{2}]", - "zh_CN": "操作错误,账户[uuid:{0}]不是资源[uuid:{1}, type:{2}]的所有者", + "raw": "ip [uuid:%s] is attached to vm nic [%s]", + "en_US": "ip [uuid:{0}] is attached to vm nic [{1}]", + "zh_CN": "IP地址[uuid:{0}]已经绑定到网卡[{1}]", "arguments": [ - "rbacEntity.getApiMessage().getSession().getAccountUuid()", - "uuid", - "resourceType.getSimpleName()" + "guestIpUuid", + "vmNicUuid" ], - "line": 190, - "fileName": "src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java" + "line": 137, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "the account[uuid:%s] has no access to the resources[uuid:%s, type:%s]", - "en_US": "the account[uuid:{0}] has no access to the resources[uuid:{1}, type:{2}]", - "zh_CN": "账户[uuid:{0}]无法使用资源[uuid:{1}, type:{2}]", + "raw": "eip[uuid:%s] has attached to another vm nic[uuid:%s], can\u0027t attach again", + "en_US": "eip[uuid:{0}] has attached to another vm nic[uuid:{1}], can\u0027t attach again", + "zh_CN": "eip[uuid:{0}]已经被挂载到另外一台云主机网卡[uuid:{1}],无法再次挂载", "arguments": [ - "rbacEntity.getApiMessage().getSession().getAccountUuid()", - "resourceWithNoAccess", - "resourceType.getSimpleName()" + "msg.getEipUuid()", + "vmNicUuid" ], - "line": 210, - "fileName": "src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java" + "line": 148, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "operation[API:%s] is denied by default, please contact admin to correct it", - "en_US": "operation[API:{0}] is denied by default, please contact admin to correct it", - "zh_CN": "", + "raw": "eip[uuid: %s] can only be attached when state is %s, current state is %s", + "en_US": "eip[uuid: {0}] can only be attached when state is {1}, current state is {2}", + "zh_CN": "eip[uuid:{0}]只有在状态(state)为{1}的情况下可以被挂载,当前状态是{2}", "arguments": [ - "rbacEntity.getApiMessage().getClass().getName()" + "msg.getEipUuid()", + "EipState.Enabled", + "state" ], - "line": 80, - "fileName": "src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java" + "line": 154, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "the operation is denied by the policy[name:%s uuid:%s]", - "en_US": "the operation is denied by the policy[name:{0} uuid:{1}]", - "zh_CN": "", + "raw": "guest l3Network of vm nic[uuid:%s] and vip l3Network of EIP[uuid:%s] are the same network", + "en_US": "guest l3Network of vm nic[uuid:{0}] and vip l3Network of EIP[uuid:{1}] are the same network", + "zh_CN": "云主机网卡[uuid:{0}]的客户三层网络,和EIP[uuid:{1}]的虚拟ip 三层网络是同一个网络", "arguments": [ - "p.getName()", - "p.getUuid()" + "msg.getVmNicUuid()", + "msg.getEipUuid()" ], - "line": 187, - "fileName": "src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java" + "line": 184, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "the operation is denied by the policy[name:%s, uuid:%s], field[%s] is not permitted to set", - "en_US": "the operation is denied by the policy[name:{0}, uuid:{1}], field[{2}] is not permitted to set", - "zh_CN": "", + "raw": "Ip address [uuid:%s] is not belonged to nic [uuid:%s]", + "en_US": "Ip address [uuid:{0}] is not belonged to nic [uuid:{1}]", + "zh_CN": "IP地址[uuid:{0}]没有绑定到网卡[uuid:{1}]", "arguments": [ - "p.getName()", - "p.getUuid()", - "fname" + "msg.getEipUuid()", + "msg.getVmNicUuid()" ], - "line": 200, - "fileName": "src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java" - }, - { - "raw": "cannot update a system or predefined role", - "en_US": "cannot update a system or predefined role", - "zh_CN": "", - "arguments": [], - "line": 92, - "fileName": "src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java" - }, - { - "raw": "cannot delete a system or predefined role", - "en_US": "cannot delete a system or predefined role", - "zh_CN": "", - "arguments": [], - "line": 108, - "fileName": "src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java" + "line": 203, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "the backup storage[uuid:%s] is not in status of Connected, current status is %s", - "en_US": "the backup storage[uuid:{0}] is not in status of Connected, current status is {1}", - "zh_CN": "镜像服务器[uuid:{0}]不是Connected状态,当前状态为{1}", + "raw": "eip[uuid:%s] has not attached to any vm nic", + "en_US": "eip[uuid:{0}] has not attached to any vm nic", + "zh_CN": "eip[uuid:{0}]还没有被挂载到任意云主机网卡", "arguments": [ - "backupStorageUuid", - "bsStatus" + "msg.getUuid()" ], - "line": 35, - "fileName": "src/main/java/org/zstack/image/BackupStorageDeleteBitGC.java" + "line": 216, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "volume[uuid:%s] is not Ready, it\u0027s %s", - "en_US": "volume[uuid:{0}] is not Ready, it\u0027s {1}", - "zh_CN": "云盘[uuid:{0}]未Ready,它现在为{1}", + "raw": "vip ipVersion [%d] is different from guestIp ipVersion [%d].", + "en_US": "vip ipVersion [{0}] is different from guestIp ipVersion [{1}].", + "zh_CN": "虚拟IP的协议号[{0}]和网卡的IP协议号[{1}]不同", "arguments": [ - "vol.getUuid()", - "vol.getStatus()" + "vipIp.getIpVersion()", + "guestIp.getIpVersion()" ], - "line": 88, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 239, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "volume[uuid:%s] is not Enabled, it\u0027s %s", - "en_US": "volume[uuid:{0}] is not Enabled, it\u0027s {1}", - "zh_CN": "云盘[uuid:{0}]未Enabled,它现在为{1}", + "raw": "Vip[%s] is in the guest ip range [%s, %s]", + "en_US": "Vip[{0}] is in the guest ip range [{1}, {2}]", + "zh_CN": "虚拟IP[{0}]和网卡的IP不能在相同地址段[{1}-{2}]", "arguments": [ - "vol.getUuid()", - "vol.getState()" + "vipIp.getIp()", + "guestRange.getStartIp()", + "guestRange.getEndIp()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 246, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "volume snapshot[uuid:%s] is not Ready, it\u0027s %s", - "en_US": "volume snapshot[uuid:{0}] is not Ready, it\u0027s {1}", - "zh_CN": "", + "raw": "the vm[uuid:%s] that the EIP is about to attach is already on the public network[uuid:%s] from which the vip[uuid:%s, name:%s, ip:%s] comes", + "en_US": "the vm[uuid:{0}] that the EIP is about to attach is already on the public network[uuid:{1}] from which the vip[uuid:{2}, name:{3}, ip:{4}] comes", + "zh_CN": "EIP将要挂载到的云主机[uuid:{0}]已经处于公共网络[uuid:{1}]上,该网络上已有vip[uuid:{2}, name:{3}, ip:{4}]", "arguments": [ - "vsvo.getUuid()", - "vsvo.getStatus()" + "vmUuid", + "vip.getL3NetworkUuid()", + "vip.getUuid()", + "vip.getName()", + "vip.getIp()" ], - "line": 99, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 266, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "volume snapshot[uuid:%s] is not Enabled, it\u0027s %s", - "en_US": "volume snapshot[uuid:{0}] is not Enabled, it\u0027s {1}", - "zh_CN": "", + "raw": "vip[uuid:%s] has been occupied other network service entity[%s]", + "en_US": "vip[uuid:{0}] has been occupied other network service entity[{1}]", + "zh_CN": "vip[uuid:{0}]已经被其他网络服务实体[{1}]占用", "arguments": [ - "vsvo.getUuid()", - "vsvo.getState()" + "msg.getVipUuid()", + "useForList.toString()" ], - "line": 103, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 277, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "ISO cannot be used as system image", - "en_US": "ISO cannot be used as system image", - "zh_CN": "ISO不能被作为一个系统标签", + "raw": "eip can not be created on system vip", + "en_US": "eip can not be created on system vip", + "zh_CN": "无法在系统VIP上创建EIP", "arguments": [], - "line": 174, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 282, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "unknown format[%s]", - "en_US": "unknown format[{0}]", - "zh_CN": "未知格式[{0}]", + "raw": "vip[uuid:%s] is not in state[%s], current state is %s", + "en_US": "vip[uuid:{0}] is not in state[{1}], current state is {2}", + "zh_CN": "vip[uuid:{0}]不处于状态[{1}]中,当前状态[{2}]", "arguments": [ - "msg.getFormat()" + "msg.getVipUuid()", + "VipState.Enabled", + "vip.getState()" ], - "line": 180, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 286, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "unsupported image type[%s]", - "en_US": "unsupported image type[{0}]", - "zh_CN": "不支持的镜像类型[{0}]", + "raw": "vm state[%s] is not allowed to operate eip, maybe you should wait the vm process complete", + "en_US": "vm state[{0}] is not allowed to operate eip, maybe you should wait the vm process complete", + "zh_CN": "云主机状态[{0}]不允许进行弹性IP操作,你可能需要等待云主机操作完成", "arguments": [ - "msg.getType()" + "state.toString()" ], - "line": 184, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 323, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "no backup storage specified in uuids%s is available for adding this image; they are not in status %s or not in state %s, or the uuid is invalid backup storage uuid", - "en_US": "no backup storage specified in uuids{0} is available for adding this image; they are not in status {1} or not in state {2}, or the uuid is invalid backup storage uuid", - "zh_CN": "镜像服务器uuids{0}不满足添加镜像的条件;它们的状态不同时满足{1}和{2},亦或者是无效的uuid", + "raw": "vmNic uuid[%s] is not allowed add eip, because vmNic exist portForwarding with allowedCidr rule", + "en_US": "vmNic uuid[{0}] is not allowed add eip, because vmNic exist portForwarding with allowedCidr rule", + "zh_CN": "不允许vmnic uuid[{0}]添加EIP,因为vmnic存在具有AllowedCIDR规则的端口转发", "arguments": [ - "msg.getBackupStorageUuids()", - "BackupStorageStatus.Connected", - "BackupStorageState.Enabled" + "vmNicUuid" ], - "line": 203, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" - }, - { - "raw": "url must starts with \u0027file:///\u0027, \u0027http://\u0027, \u0027https://\u0027, \u0027ftp://\u0027, \u0027sftp://\u0027 or \u0027/\u0027", - "en_US": "url must starts with \u0027file:///\u0027, \u0027http://\u0027, \u0027https://\u0027, \u0027ftp://\u0027, \u0027sftp://\u0027 or \u0027/\u0027", - "zh_CN": "url必须以下列格式开头\u0027file:///\u0027, \u0027http://\u0027, \u0027https://\u0027, \u0027ftp://\u0027, \u0027sftp://\u0027 or \u0027/\u0027", - "arguments": [], - "line": 214, - "fileName": "src/main/java/org/zstack/image/ImageApiInterceptor.java" + "line": 337, + "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" }, { - "raw": "the image[uuid:%s, name:%s] is not on any backup storage", - "en_US": "the image[uuid:{0}, name:{1}] is not on any backup storage", - "zh_CN": "镜像[uuid:{0}, 名称:{1}]不在任一镜像服务器上", + "raw": "eip [uuid:%s] is deleted", + "en_US": "eip [uuid:{0}] is deleted", + "zh_CN": "已删除EIP[uuid:{0}]", "arguments": [ - "self.getUuid()", - "self.getName()" + "struct.getEip().getUuid()" ], - "line": 168, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "line": 1463, + "fileName": "src/main/java/org/zstack/network/service/eip/EipManagerImpl.java" }, { - "raw": "No connected backup storage found for image[uuid:%s, name:%s]", - "en_US": "No connected backup storage found for image[uuid:{0}, name:{1}]", - "zh_CN": "在所有 Connected 状态的镜像服务器上都找不到镜像[uuid:{0}, name:{1}]", + "raw": "cannot find Eip guest ip: %s in vmNic ips :%s", + "en_US": "cannot find Eip guest ip: {0} in vmNic ips :{1}", + "zh_CN": "在vmnic IP{1}中找不到EIP来宾IP{0}", "arguments": [ - "self.getUuid()", - "self.getName()" + "eip.getGuestIp()", + "nicIps" ], - "line": 178, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "line": 1316, + "fileName": "src/main/java/org/zstack/network/service/eip/EipManagerImpl.java" }, { - "raw": "detach iso[uuid\u003d%s] from vm failed, errors are %s", - "en_US": "detach iso[uuid\u003d{0}] from vm failed, errors are {1}", - "zh_CN": "", + "raw": "unable to attach the L3 network[uuid:%s, name:%s] to the vm[uuid:%s, name:%s], because the L3 network is providing EIP to one of the vm\u0027s nic", + "en_US": "unable to attach the L3 network[uuid:{0}, name:{1}] to the vm[uuid:{2}, name:{3}], because the L3 network is providing EIP to one of the vm\u0027s nic", + "zh_CN": "无法将三层网络[uuid:{0}, name:{1}]挂载到云主机[uuid:{2}, name:{3}],因为三层网络正在为云主机上的一块网卡提供EIP", "arguments": [ - "msg.getImageUuid()", - "JSONObjectUtil.toJsonString(errors)" + "l3.getUuid()", + "l3.getName()", + "vm.getUuid()", + "vm.getName()" ], - "line": 366, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "line": 1622, + "fileName": "src/main/java/org/zstack/network/service/eip/EipManagerImpl.java" }, { - "raw": "the image[uuid:%s, name:%s] is not on the backup storage[uuid:%s]", - "en_US": "the image[uuid:{0}, name:{1}] is not on the backup storage[uuid:{2}]", - "zh_CN": "镜像[uuid:{0}, 名称:{1}]不在镜像服务器[uuid:{2}]上", + "raw": "could not get dhcp4 server ip for l3 network [uuid:%s]", + "en_US": "could not get dhcp4 server ip for l3 network [uuid:{0}]", + "zh_CN": "无法获取三层网络[uuid:{0}]的DHCP4服务器IP", "arguments": [ - "self.getUuid()", - "self.getName()", - "bsUuid" + "msg.getL3NetworkUuid()" ], - "line": 713, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "line": 73, + "fileName": "src/main/java/org/zstack/network/service/flat/DhcpApply.java" }, { - "raw": "the image[uuid:%s, name:%s]\u0027s status[%s] is not Deleted on the backup storage[uuid:%s]", - "en_US": "the image[uuid:{0}, name:{1}]\u0027s status[{2}] is not Deleted on the backup storage[uuid:{3}]", - "zh_CN": "镜像[uuid:{0}, 名称:{1}]的状态[{2}]在镜像服务器[uuid:{3}]上不是Deleled", + "raw": "could not get dhcp6 server ip for l3 network [uuid:%s]", + "en_US": "could not get dhcp6 server ip for l3 network [uuid:{0}]", + "zh_CN": "无法获取三层网络[uuid:{0}]的DHCP6服务器IP", "arguments": [ - "self.getUuid()", - "self.getName()", - "ref.getStatus()", - "bsUuid" + "msg.getL3NetworkUuid()" ], - "line": 655, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "line": 77, + "fileName": "src/main/java/org/zstack/network/service/flat/DhcpApply.java" }, { - "raw": "the image[uuid:%s, name:%s] is not deleted on any backup storage", - "en_US": "the image[uuid:{0}, name:{1}] is not deleted on any backup storage", - "zh_CN": "镜像[uuid:{0}, 名称:{1}]未在任一镜像服务器上被删除", - "arguments": [ - "self.getUuid()", - "self.getName()" - ], - "line": 697, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "raw": "Session/account uuid is not valid.", + "en_US": "Session/account uuid is not valid.", + "zh_CN": "会话/帐户uuid无效。", + "arguments": [], + "line": 39, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java" }, { - "raw": "the image[uuid:%s, name:%s] is not deleted on the backup storage[uuid:%s]", - "en_US": "the image[uuid:{0}, name:{1}] is not deleted on the backup storage[uuid:{2}]", - "zh_CN": "镜像[uuid:{0}, 名称:{1}]未在镜像服务器[uuid:{2}]上被删除", + "raw": "the account[uuid:%s] has no access to the resource[uuid:%s, type:L3NetworkVO]", + "en_US": "the account[uuid:{0}] has no access to the resource[uuid:{1}, type:L3NetworkVO]", + "zh_CN": "帐户[uuid:{0}]无权访问资源[uuid:{1},类型:L3NetworkVO]", "arguments": [ - "self.getUuid()", - "self.getName()", - "bsUuid" + "accountUuid", + "msg.getL3NetworkUuid()" ], - "line": 718, - "fileName": "src/main/java/org/zstack/image/ImageBase.java" + "line": 43, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java" }, { - "raw": "only one bootMode system tag is allowed, but %d got", - "en_US": "only one bootMode system tag is allowed, but {0} got", - "zh_CN": "", + "raw": "l3 network uuid cannot be null", + "en_US": "l3 network uuid cannot be null", + "zh_CN": "三层网络的uuid不能为空", + "arguments": [], + "line": 647, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + }, + { + "raw": "Cannot find DhcpIp for l3 network[uuid:%s]", + "en_US": "Cannot find DhcpIp for l3 network[uuid:{0}]", + "zh_CN": "无法为三层网络[uuid:{0}]找到DHCP IP", "arguments": [ - "bootModeCount" + "msg.getL3NetworkUuid()" ], - "line": 524, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 654, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "[%s] specified in system tag [%s] is not a valid boot mode", - "en_US": "[{0}] specified in system tag [{1}] is not a valid boot mode", - "zh_CN": "", + "raw": "cannot configure DHCP for vm[uuid:%s] on the destination host[uuid:%s]", + "en_US": "cannot configure DHCP for vm[uuid:{0}] on the destination host[uuid:{1}]", + "zh_CN": "无法为目标物理机[uuid:{1}]上的云主机[uuid:{0}]配置DHCP", "arguments": [ - "bootMode", - "systemTag" + "inv.getUuid()", + "destHostUuid" ], - "line": 542, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 998, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "upload session expired", - "en_US": "upload session expired", - "zh_CN": "上传session失效了", - "arguments": [], - "line": 1032, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "raw": "minimum ip range prefix length of flat network is %d", + "en_US": "minimum ip range prefix length of flat network is {0}", + "zh_CN": "三层网络的最小IP范围前缀长度为{0}", + "arguments": [ + "IPv6Constants.IPV6_PREFIX_LEN_MIN_DNSMASQ" + ], + "line": 1751, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "unable to allocate backup storage specified by uuids%s, list errors are: %s", - "en_US": "unable to allocate backup storage specified by uuids{0}, list errors are: {1}", - "zh_CN": "不能根据[uuids:{0}]分配镜像服务器,错误清单为: {1}", + "raw": "DHCP server ip [%s] is not a IPv6 address", + "en_US": "DHCP server ip [{0}] is not a IPv6 address", + "zh_CN": "DHCP服务器地址[{0}]不是一个正确的IPv6地址", "arguments": [ - "msgData.getBackupStorageUuids()", - "JSONObjectUtil.toJsonString(errs)" + "dhcpServerIp" ], - "line": 1534, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 1780, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "failed to create image from root volume[uuid:%s] on all backup storage, see cause for one of errors", - "en_US": "failed to create image from root volume[uuid:{0}] on all backup storage, see cause for one of errors", - "zh_CN": "在所有镜像服务器上从根云盘[uuid:{0}]创建镜像失败,查看错误原因", + "raw": "DHCP server ip [%s] is not in the cidr [%s]", + "en_US": "DHCP server ip [{0}] is not in the cidr [{1}]", + "zh_CN": "DHCP服务器地址[{0}]不在网络段[{1}]的范围内", "arguments": [ - "msgData.getRootVolumeUuid()" + "dhcpServerIp", + "inv.getNetworkCidr()" ], - "line": 1645, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 1776, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "failed to allocate all backup storage[uuid:%s], a list of error: %s", - "en_US": "failed to allocate all backup storage[uuid:{0}], a list of error: {1}", - "zh_CN": "镜像服务器[uuid:{0}]分配失败,错误清单:{1}", + "raw": "DHCP server ip [%s] is not a IPv4 address", + "en_US": "DHCP server ip [{0}] is not a IPv4 address", + "zh_CN": "DHCP服务器地址[{0}]不是一个正确的IPv4地址", "arguments": [ - "msgData.getBackupStorageUuids()", - "JSONObjectUtil.toJsonString(errs)" + "dhcpServerIp" ], - "line": 1916, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 1772, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "failed to create data volume template from volume[uuid:%s] on all backup storage%s. See cause for one of errors", - "en_US": "failed to create data volume template from volume[uuid:{0}] on all backup storage{1}. See cause for one of errors", - "zh_CN": "在所有镜像服务器[uuid:{1}]上创建云盘[uuid:{0}]的云盘模版失败,查看错误原因", + "raw": "DHCP server ip [%s] is already existed in l3 network [%s]", + "en_US": "DHCP server ip [{0}] is already existed in l3 network [{1}]", + "zh_CN": "三层网络[{1}]已经配置了DHCP服务器地址[{0}]", "arguments": [ - "msgData.getVolumeUuid()", - "msgData.getBackupStorageUuids()" + "entry.getKey()", + "inv.getL3NetworkUuid()" ], - "line": 2018, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 1791, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "image[uuid:%s] is not on creating, please wait for it to cancel itself.", - "en_US": "image[uuid:{0}] is not on creating, please wait for it to cancel itself.", - "zh_CN": "", + "raw": "DHCP server ip [%s] can not be equaled to gateway ip", + "en_US": "DHCP server ip [{0}] can not be equaled to gateway ip", + "zh_CN": "DHCP服务器地址[{0}]不能等于网关地址", "arguments": [ - "imageUuid" + "dhcpServerIp" ], - "line": 2104, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 1796, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "volume[uuid:%s] has been deleted. no need to cancel", - "en_US": "volume[uuid:{0}] has been deleted. no need to cancel", - "zh_CN": "", + "raw": "DHCP server ip [%s] can not be configured to system l3", + "en_US": "DHCP server ip [{0}] can not be configured to system l3", + "zh_CN": "系统网络不能配置DHCP服务器地址[{0}]", "arguments": [ - "volumeUuid" + "dhcpServerIp" ], - "line": 2110, - "fileName": "src/main/java/org/zstack/image/ImageManagerImpl.java" + "line": 1802, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" }, { - "raw": "Failed to set security level, because security level is disabled.", - "en_US": "Failed to set security level, because security level is disabled.", - "zh_CN": "设置密级失败,因为密级功能已禁用", + "raw": "could not attach eip because ipv6 eip can ONLY be attached to flat network", + "en_US": "could not attach eip because ipv6 eip can ONLY be attached to flat network", + "zh_CN": "无法附加EIP,因为IPv6 EIP只能附加到三层网络", "arguments": [], - "line": 35, - "fileName": "src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java" + "line": 80, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java" }, { - "raw": "Unknown security level code[%s], supported values are %s", - "en_US": "Unknown security level code[{0}], supported values are {1}", - "zh_CN": "未知的密级[{0}],支持的值有[{1}]", + "raw": "L2Network where vip\u0027s L3Network based hasn\u0027t attached the cluster where vmNic[uuid:%s] located", + "en_US": "L2Network where vip\u0027s L3Network based hasn\u0027t attached the cluster where vmNic[uuid:{0}] located", + "zh_CN": "基于虚拟IP三层网络的二层网络没有绑定到云主机网卡所在的集群", "arguments": [ - "msg.getSecurityLevel()", - "Arrays.stream(SecurityLevel.values()).map(SecurityLevel::getCode).collect(Collectors.toList())" + "vmNicUuid" ], - "line": 45, - "fileName": "src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java" + "line": 109, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java" }, { - "raw": "target backup storage[uuid:%s] became unavailable", - "en_US": "target backup storage[uuid:{0}] became unavailable", - "zh_CN": "", + "raw": "can not bound more than 1 %s eip to a vm nic[uuid:%s] of flat ", + "en_US": "can not bound more than 1 {0} eip to a vm nic[uuid:{1}] of flat ", + "zh_CN": "无法将1个以上的{0}EIP绑定到平面的VM NIC[uuid:{1}]", "arguments": [ - "targetBsUuid" + "version", + "vmNicUuid" ], - "line": 318, - "fileName": "src/main/java/org/zstack/imagereplicator/ImageReplicatorImpl.java" + "line": 134, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java" }, { - "raw": "One or more backup storage[uuids:%s] has been added to replication group[uuid:%s]", - "en_US": "One or more backup storage[uuids:{0}] has been added to replication group[uuid:{1}]", - "zh_CN": "", + "raw": "unable to apply the EIP operation for the the vm[uuid:%s, state:%s], because cannot find the VM\u0027s hostUUid", + "en_US": "unable to apply the EIP operation for the the vm[uuid:{0}, state:{1}], because cannot find the VM\u0027s hostUUid", + "zh_CN": "无法为云主机[uuid:{0}, state:{1}]应用EIP操作,因为无法找到该云主机的物理机uuid(hostUuid)", "arguments": [ - "String.join(\",\", msg.getBackupStorageUuids())", - "msg.getReplicationGroupUuid()" + "vmUuid", + "vm.getState()" ], - "line": 30, - "fileName": "src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java" + "line": 614, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatEipBackend.java" }, { - "raw": "Backup storage[uuids:%s] is not of type ImageStore", - "en_US": "Backup storage[uuids:{0}] is not of type ImageStore", - "zh_CN": "", + "raw": "host[uuid:%s] is not connected", + "en_US": "host[uuid:{0}] is not connected", + "zh_CN": "物理机[uuid:{0}]未连接", "arguments": [ - "bsUuid" + "struct.getHostUuid()" ], - "line": 41, - "fileName": "src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java" + "line": 374, + "fileName": "src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java" }, { - "raw": "Backup storage[uuids:%s] is not attached to any Zone", - "en_US": "Backup storage[uuids:{0}] is not attached to any Zone", - "zh_CN": "", + "raw": "Invalid rule expression, the detail: %s", + "en_US": "Invalid rule expression, the detail: {0}", + "zh_CN": "规则表达式无效,详细信息:{0}", "arguments": [ - "bsUuid" + "e.getMessage()" ], - "line": 51, - "fileName": "src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java" + "line": 306, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Network [uuid: %s] does\u0027t not have IPsec service", - "en_US": "Network [uuid: {0}] does\u0027t not have IPsec service", - "zh_CN": "网络[uuid: {0}]没有IPsec服务", - "arguments": [ - "l3NetworkUuid" - ], - "line": 63, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "raw": "could not get candidate vmnic, because both load balancer uuid and server group uuid are not specified", + "en_US": "could not get candidate vmnic, because both load balancer uuid and server group uuid are not specified", + "zh_CN": "无法获取候选vmnic,因为未指定负载平衡器uuid和服务器组uuid", + "arguments": [], + "line": 180, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the remote CIDR[%s] and remote CIDR[%s] are overlaped", - "en_US": "the remote CIDR[{0}] and remote CIDR[{1}] are overlaped", - "zh_CN": "远程的CIDR[{0}]和远端CIDR[{1}]存在覆盖", - "arguments": [ - "rcidr", - "tempCidr" - ], - "line": 73, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "raw": "could not get candidate l3 network, because both load balancer uuid and server group uuid are not specified", + "en_US": "could not get candidate l3 network, because both load balancer uuid and server group uuid are not specified", + "zh_CN": "无法获取候选三层网络,因为未指定负载平衡器uuid和服务器组uuid", + "arguments": [], + "line": 198, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the CIDR[%s] of local router and remote CIDR[%s] are overlaped", - "en_US": "the CIDR[{0}] of local router and remote CIDR[{1}] are overlaped", - "zh_CN": "本地路由的CIDR[{0}]和远端CIDR存在覆盖", + "raw": "could not detach vm nic to load balancer listener[uuid:%s], because default server group for listener has been deleted", + "en_US": "could not detach vm nic to load balancer listener[uuid:{0}], because default server group for listener has been deleted", + "zh_CN": "无法将VM NIC与负载平衡器侦听器[uuid:{0}]分离,因为已删除侦听器的默认服务器组", "arguments": [ - "lcidr", - "tempCidr" + "msg.getListenerUuid()" ], - "line": 97, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" - }, - { - "raw": "all networks in same IPsecConnection should be same type", - "en_US": "all networks in same IPsecConnection should be same type", - "zh_CN": "在相同的IPsec连接中的所有连接应该是相同类型", - "arguments": [], - "line": 110, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 222, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "IPsecConnection can ONLY have 1 network for %s", - "en_US": "IPsecConnection can ONLY have 1 network for {0}", - "zh_CN": "IPsec连接只能有一个网络服务", + "raw": "Load balancer VIP [%s] cannot be the first or the last IP of the CIDR with the public address pool type", + "en_US": "Load balancer VIP [{0}] cannot be the first or the last IP of the CIDR with the public address pool type", + "zh_CN": "负载平衡器VIP[{0}]不能是具有公共地址池类型的CIDR的第一个或最后一个IP", "arguments": [ - "L3NetworkConstant.L3_BASIC_NETWORK_TYPE" + "vipVO.getIp()" ], - "line": 116, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 251, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "L3Network [uuid: %s] has not been attached to vpc router", - "en_US": "L3Network [uuid: {0}] has not been attached to vpc router", - "zh_CN": "三层网络[uuid:{0}]还没有绑定VPC路由", + "raw": "operation failure, not support the ip version %d", + "en_US": "operation failure, not support the ip version {0}", + "zh_CN": "操作失败,不支持IPv{0}", "arguments": [ - "l3Uuid" + "ipVer" ], - "line": 127, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 282, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "all networks in same IPsecConnection must be attached to same VPC router", - "en_US": "all networks in same IPsecConnection must be attached to same VPC router", - "zh_CN": "在相同的IPsec连接中的所有网络必须绑定在相同的VPC路由", - "arguments": [], - "line": 133, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "raw": "operation failure, duplicate/overlap ip entry in %s of accesscontrol list group:%s", + "en_US": "operation failure, duplicate/overlap ip entry in {0} of accesscontrol list group:{1}", + "zh_CN": "操作失败,在访问控制组:{1}中有重复/重叠ip{0}", + "arguments": [ + "ips", + "acl.getUuid()" + ], + "line": 288, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "there already have ipsec connection[uuid:%s, name:%s] with the same vrouter and peerAddress", - "en_US": "there already have ipsec connection[uuid:{0}, name:{1}] with the same vrouter and peerAddress", - "zh_CN": "这里已经有相同云路由和对端地址的IPsec连接[uuid:{0}, name:{1}]", + "raw": "operation failure, ip format only supports ip/iprange/cidr, but find %s", + "en_US": "operation failure, ip format only supports ip/iprange/cidr, but find {0}", + "zh_CN": "操作失败,只支持IP地址/IP段/IP网络格式的参数,不支持{0}", "arguments": [ - "tuples.get(0).get(0, String.class)", - "tuples.get(0).get(1, String.class)" + "ips" ], - "line": 150, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 295, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the vip[uuid:%s] has been used for %s", - "en_US": "the vip[uuid:{0}] has been used for {1}", - "zh_CN": "虚拟IP[uuid:{0}]已经用作网络服务 {1}", + "raw": "ip range[%s, %s] is overlap with start ip:%s, end ip: %s of access-control-list group:%s", + "en_US": "ip range[{0}, {1}] is overlap with start ip:{2}, end ip: {3} of access-control-list group:{4}", + "zh_CN": "ip段[{0}, {1}]和访问控制列表组:{4}中的ip段[{2},{3}]重叠", "arguments": [ - "msg.getVipUuid()", - "useForList.toString()" + "startIp", + "endIp", + "NetworkUtils.longToIpv4String(r.lowerEndpoint())", + "NetworkUtils.longToIpv4String(r.upperEndpoint())", + "acl.getUuid()" ], - "line": 174, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 299, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the peerAddress[%s] cannot be the same to the VIP address", - "en_US": "the peerAddress[{0}] cannot be the same to the VIP address", - "zh_CN": "对端地址[{0}]不能和虚拟IP地址相同", + "raw": "Can\u0027t attach the type access-control-list group[%s] whose ip version is different with LoadBalancer[%s]", + "en_US": "Can\u0027t attach the type access-control-list group[{0}] whose ip version is different with LoadBalancer[{1}]", + "zh_CN": "负载均衡器[{1}]不能添加IP版本不一致的访问控制列表组[{0}]", "arguments": [ - "msg.getPeerAddress()" + "aclUuids", + "lbUuid" ], - "line": 179, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 321, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the peerAddress[%s] is not an IPv4 address", - "en_US": "the peerAddress[{0}] is not an IPv4 address", - "zh_CN": "对端地址[{0}]不是一个IPv4地址", + "raw": "domian[%s], url[%s] duplicate/overlap redirect rule with access-control-list group:%s", + "en_US": "domian[{0}], url[{1}] duplicate/overlap redirect rule with access-control-list group:{2}", + "zh_CN": "域[{0}],URL[{1}]与访问控制列表组{2}重复/重叠重定向规则", "arguments": [ - "msg.getPeerAddress()" + "aclEntry.getDomain()", + "aclEntry.getUrl()", + "acl.getUuid()" ], - "line": 183, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 396, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the authKey cannot contain white space and special characters of \u0027\\\"`\\\\", - "en_US": "the authKey cannot contain white space and special characters of \u0027\\\"`\\\\", - "zh_CN": "验证码不能包含空格和以下字符:\u0027\\\"`\\\\", - "arguments": [], - "line": 195, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "raw": "access-control-list groups[uuid:%s] use to %s, but there some access-control-list not has ip entry but redirect rule", + "en_US": "access-control-list groups[uuid:{0}] use to {1}, but there some access-control-list not has ip entry but redirect rule", + "zh_CN": "访问控制列表组[uuid:{0}]用于{1},但某些访问控制列表没有IP条目,但有重定向规则", + "arguments": [ + "msg.getAclType()", + "msg.getAclUuids()" + ], + "line": 506, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "must include l3 networks in APIAttachL3NetworksToIPsecConnectionMsg", - "en_US": "must include l3 networks in APIAttachL3NetworksToIPsecConnectionMsg", - "zh_CN": "参数中缺少三层网络的uuid", - "arguments": [], - "line": 229, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "raw": "the access-control-list groups[uuid:%s] are already on the load balancer listener[uuid:%s]", + "en_US": "the access-control-list groups[uuid:{0}] are already on the load balancer listener[uuid:{1}]", + "zh_CN": "负载均衡监听器[uuid:{1}]已经添加了访问控制列表组[uuid:{0}]", + "arguments": [ + "existingAcls", + "msg.getListenerUuid()" + ], + "line": 515, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "L3 network [%s] is not vpc network, can not be attached or detached to ipsec", - "en_US": "L3 network [{0}] is not vpc network, can not be attached or detached to ipsec", - "zh_CN": "三层网络[{0}]不是VPC网络,不能绑定或解绑IPsec", + "raw": "the load balancer listener[uuid:%s] just only attach the %s type access-control-list group", + "en_US": "the load balancer listener[uuid:{0}] just only attach the {1} type access-control-list group", + "zh_CN": "负载均衡监听器[uuid:{0}]只能以{1}方式添加访问控制列表组", "arguments": [ - "l3NetworkUuid" + "msg.getListenerUuid()", + "type.toString()" ], - "line": 236, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 521, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "L3 network [%s] can not be attached to ipsec [uuid :%s]twice", - "en_US": "L3 network [{0}] can not be attached to ipsec [uuid :{1}]twice", - "zh_CN": "三层网络[{0}]不能绑定IPsec[uuid :{1}]两次", + "raw": "the load balancer listener[uuid:%s] can\u0027t attach more than %d access-control-list groups", + "en_US": "the load balancer listener[uuid:{0}] can\u0027t attach more than {1} access-control-list groups", + "zh_CN": "负载均衡监听器[uuid:{0}]最多只能添加{1}个访问控制列表组", "arguments": [ - "l3NetworkUuid", - "msg.getIPsecConnectionUuid()" + "msg.getListenerUuid()", + "LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class)" ], - "line": 217, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 526, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "L3 network [%s] is not be attached to ipsec [uuid :%s]", - "en_US": "L3 network [{0}] is not be attached to ipsec [uuid :{1}]", - "zh_CN": "三层网络[{0}]不能绑定IPsec[uuid :{1}]", + "raw": "access-control-list groups[uuid:%s] use to redirect, but there some access-control-list not has redirect rule but ip entry", + "en_US": "access-control-list groups[uuid:{0}] use to redirect, but there some access-control-list not has redirect rule but ip entry", + "zh_CN": "Access-Control-List组[uuid:{0}]用于重定向,但某些Access-Control-List没有重定向规则,只有IP条目", "arguments": [ - "l3NetworkUuid", - "msg.getIPsecConnectionUuid()" + "msg.getAclUuids()" ], - "line": 240, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 414, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Cidr [%s] is already in the Cidrs of ipsec [uuid :%s]", - "en_US": "Cidr [{0}] is already in the Cidrs of ipsec [uuid :{1}]", - "zh_CN": "CIDR[{0}]已经在IPsec[uuid :{1}]的CIDR中", + "raw": "redirect access-control-list groups[uuid:%s] cannot only attach to load balancer listener, must assign server group", + "en_US": "redirect access-control-list groups[uuid:{0}] cannot only attach to load balancer listener, must assign server group", + "zh_CN": "重定向访问控制列表组[uuid:{0}]不能仅连接到负载平衡器侦听器,必须分配服务器组", "arguments": [ - "cidr", - "msg.getIPsecConnectionUuid()" + "msg.getAclUuids()" ], - "line": 250, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 419, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Cidr [%s] is not in Cidrs of ipsec [uuid :%s]", - "en_US": "Cidr [{0}] is not in Cidrs of ipsec [uuid :{1}]", - "zh_CN": "CIDR[{0}]没有在IPsec[uuid :{1}]的CIDR中", + "raw": "access-control-list groups[uuid:%s] attach to load balancer listener[uuid:%s] not https or http", + "en_US": "access-control-list groups[uuid:{0}] attach to load balancer listener[uuid:{1}] not https or http", + "zh_CN": "访问控制列表组[uuid:{0}]连接到负载平衡器侦听器[uuid:{1}]而不是HTTPS或HTTP", "arguments": [ - "cidr", - "msg.getIPsecConnectionUuid()" + "msg.getAclUuids()", + "msg.getListenerUuid()" ], - "line": 264, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 424, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "can not change state because ipsec [uuid:%s] status is not ready", - "en_US": "can not change state because ipsec [uuid:{0}] status is not ready", - "zh_CN": "不能修改IPsec的状态,因为IPsec的状态没有准备", + "raw": "server group[%s] not attach to load balancer listener[%s]", + "en_US": "server group[{0}] not attach to load balancer listener[{1}]", + "zh_CN": "服务器组[{0}]未连接到负载平衡器侦听器[{1}]", "arguments": [ - "msg.getUuid()" + "msg.getServerGroupUuids()", + "msg.getListenerUuid()" ], - "line": 272, - "fileName": "src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java" + "line": 547, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "cannot find the IPsecconnection[uuid:%s], it may have been deleted", - "en_US": "cannot find the IPsecconnection[uuid:{0}], it may have been deleted", - "zh_CN": "未找到IPsec连接[uuid:{0}],它可能会被删除了", + "raw": "access-control-list groups[uuid:%s] has no redirect rule", + "en_US": "access-control-list groups[uuid:{0}] has no redirect rule", + "zh_CN": "访问控制列表组[uuid:{0}]没有重定向规则", "arguments": [ - "msg.getIPsecConnectionUuid()" + "msg.getAclUuids()" ], - "line": 132, - "fileName": "src/main/java/org/zstack/ipsec/IPsecManagerImpl.java" + "line": 443, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Current port range[%s, %s] is conflicted with used port range [%s, %s] with vip[uuid: %s] protocol: UDP", - "en_US": "Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: UDP", - "zh_CN": "当前的端口范围以UDP使用的端口范围冲突了", + "raw": "access-control-list groups[uuid:%s] has attach to another load balancer listener[uuid:%s]", + "en_US": "access-control-list groups[uuid:{0}] has attach to another load balancer listener[uuid:{1}]", + "zh_CN": "访问控制列表组[uuid:{0}]已连接到另一个负载平衡器侦听器[uuid:{1}]", "arguments": [ - "Long.toString(range2.getStart())", - "Long.toString(range2.getEnd())", - "Long.toString(cur.getStart())", - "Long.toString(cur.getEnd())", - "msg.getVipUuid()" + "msg.getAclUuids()", + "msg.getListenerUuid()" ], - "line": 336, - "fileName": "src/main/java/org/zstack/ipsec/IPsecManagerImpl.java" + "line": 456, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "cidr[%s] of attached L3Network [uuid:%s] is overlapped with ipsec [uuid:%s] remote cidr[%s]", - "en_US": "cidr[{0}] of attached L3Network [uuid:{1}] is overlapped with ipsec [uuid:{2}] remote cidr[{3}]", - "zh_CN": "已绑定在三层网络[uuid:{1}]的CIDR与IPSec[uuid:{2}]远程CIDR存在重叠", + "raw": "the load balancer listener[uuid:%s] can\u0027t attach more than %d redirect rule access-control-list groups", + "en_US": "the load balancer listener[uuid:{0}] can\u0027t attach more than {1} redirect rule access-control-list groups", + "zh_CN": "负载平衡器侦听器[uuid:{0}]无法附加{1}个以上的重定向规则访问控制列表组", "arguments": [ - "cidr", - "l3Inv.getUuid()", - "uuid", - "rCidr" + "msg.getListenerUuid()", + "LoadBalancerGlobalConfig.ACL_REDIRECT_MAX_COUNT.value(Long.class)" ], - "line": 373, - "fileName": "src/main/java/org/zstack/ipsec/IPsecManagerImpl.java" + "line": 468, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "create ipsec to ha route failed, because %s", - "en_US": "create ipsec to ha route failed, because {0}", - "zh_CN": "", + "raw": "load balancer listener [uuid:%s] had redirect rule of access-control-list groups[uuid:%s]", + "en_US": "load balancer listener [uuid:{0}] had redirect rule of access-control-list groups[uuid:{1}]", + "zh_CN": "负载平衡器侦听器[uuid:{0}]具有访问控制列表组的重定向规则[uuid:{1}]", "arguments": [ - "errorCode.getDescription()" + "msg.getListenerUuid()", + "redireRuleExistAclUuid" ], - "line": 90, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosCreateIPsecFlow.java" + "line": 494, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "delete ipsec from ha group failed because %s", - "en_US": "delete ipsec from ha group failed because {0}", - "zh_CN": "", + "raw": "acl[%s] not attach to load balancer listener[%s]", + "en_US": "acl[{0}] not attach to load balancer listener[{1}]", + "zh_CN": "ACL[{0}]未附加到负载平衡器侦听器[{1}]", "arguments": [ - "errorCode.getDescription()" + "msg.getAclUuid()", + "msg.getListenerUuid()" ], - "line": 80, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosDeleteIPsecFlow.java" + "line": 555, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "operation error, because:%s", - "en_US": "operation error, because:{0}", - "zh_CN": "操作错误,因为{0}", + "raw": "L3 networks[uuids:%s] of the vm nics has no network service[%s] enabled", + "en_US": "L3 networks[uuids:{0}] of the vm nics has no network service[{1}] enabled", + "zh_CN": "云主机网卡的三层网络没有可用的网络服务", "arguments": [ - "rsp.getError()" + "l3Uuids", + "LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING" ], - "line": 607, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "line": 1294, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the remoteCidr[%s] is overlaped with VirtualRouter interface cidr[%s]", - "en_US": "the remoteCidr[{0}] is overlaped with VirtualRouter interface cidr[{1}]", - "zh_CN": "", + "raw": "could not attach vm nic to load balancer listener, because the vm nic[uuid:%s] are already on the default server group [uuid:%s]", + "en_US": "could not attach vm nic to load balancer listener, because the vm nic[uuid:{0}] are already on the default server group [uuid:{1}]", + "zh_CN": "无法将VM NIC附加到负载平衡器侦听器,因为VM NIC[uuid:{0}]已位于默认服务器组[uuid:{1}]上", "arguments": [ - "rcidr", - "cidr" + "nicUuid", + "groupVO.getUuid()" ], - "line": 162, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "line": 587, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "vyos doesn\u0027t support aes-192 as IkeEncryptionAlgorithm, available options aes-128, aes-256, 3des", - "en_US": "vyos doesn\u0027t support aes-192 as IkeEncryptionAlgorithm, available options aes-128, aes-256, 3des", - "zh_CN": "vyos不支持aes-192作为密钥交换加密算法,可用选择为aes-128, aes-256, 3des", - "arguments": [], - "line": 279, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "raw": "the listener with protocol [%s] doesn\u0027t support this health check:[%s]", + "en_US": "the listener with protocol [{0}] doesn\u0027t support this health check:[{1}]", + "zh_CN": "[{0}]类型的监听器不支持此类型[{1}]的健康检查", + "arguments": [ + "listenerVO.getProtocol()", + "msg.getHealthCheckProtocol()" + ], + "line": 1176, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "vyos doesn\u0027t support aes-192 as PolicyEncryptionAlgorithm, available options aes-128, aes-256, 3des", - "en_US": "vyos doesn\u0027t support aes-192 as PolicyEncryptionAlgorithm, available options aes-128, aes-256, 3des", - "zh_CN": "vyos不支持aes-192作为加密算法协议,可用选择为aes-128, aes-256, 3des", + "raw": "the http health check protocol must be specified its healthy checking parameter healthCheckURI", + "en_US": "the http health check protocol must be specified its healthy checking parameter healthCheckURI", + "zh_CN": "http类型的健康检查必须提供healthCheckURI参数", "arguments": [], - "line": 285, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "line": 1145, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "vyos doesn\u0027t support %d as Ike DhGroup ", - "en_US": "vyos doesn\u0027t support {0} as Ike DhGroup ", - "zh_CN": "vyos不支持[{0}]作为Ike DhGroup", + "raw": "the http health check protocol\u0027s expecting code [%s] is invalidate", + "en_US": "the http health check protocol\u0027s expecting code [{0}] is invalidate", + "zh_CN": "http健康检查协议的expeting-code参数非法", "arguments": [ - "msg.getIkeDhGroup()" + "msg.getHealthCheckHttpCode()" ], - "line": 291, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "line": 1152, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "sync to ha group failed, because:%s", - "en_US": "sync to ha group failed, because:{0}", - "zh_CN": "", + "raw": "Can\u0027t attach more than %d access-control-list groups to a listener", + "en_US": "Can\u0027t attach more than {0} access-control-list groups to a listener", + "zh_CN": "一个监听器加载的访问控制组不能超过{0}", "arguments": [ - "errorCode.getDescription()" + "LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class)" ], - "line": 424, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "line": 697, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "apply to ha group failed, because %s", - "en_US": "apply to ha group failed, because {0}", - "zh_CN": "", + "raw": "l4[%s] loadBalancer listener[%s] doesn\u0027t support assigning session persistence state", + "en_US": "l4[{0}] loadBalancer listener[{1}] doesn\u0027t support assigning session persistence state", + "zh_CN": "L4[{0}]LoadBalancer侦听器[{1}]不支持分配会话持久性状态", "arguments": [ - "errorCode.getDescription()" + "msg.getProtocol()", + "msg.getName()" ], - "line": 646, - "fileName": "src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java" + "line": 787, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "there has been a kvm host having management ip[%s]", - "en_US": "there has been a kvm host having management ip[{0}]", - "zh_CN": "已经存在一个拥有管理节点IP[{0}]的物理机", + "raw": "loadBalancer[%s] listener[%s] %s algorithm doesn\u0027t support assigning session persistence state except assigning disable explicitly", + "en_US": "loadBalancer[{0}] listener[{1}] {2} algorithm doesn\u0027t support assigning session persistence state except assigning disable explicitly", + "zh_CN": "LoadBalancer[{0}]Listener[{1}]{2}算法不支持分配会话持久性状态,但显式分配Disable时除外", "arguments": [ - "msg.getManagementIp()" + "msg.getLoadBalancerUuid()", + "msg.getName()", + "algorithm" ], - "line": 37, - "fileName": "src/main/java/org/zstack/kvm/KVMApiInterceptor.java" + "line": 808, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "KVMConnectExtensionForL2Network wont\u0027s support L2Network[type:%s]", - "en_US": "KVMConnectExtensionForL2Network wont\u0027s support L2Network[type:{0}]", - "zh_CN": "物理机二层网络连接插件不支持二层网络[类型:{0}]", + "raw": "loadBalancer[%s] listener[%s] %s algorithm doesn\u0027t support assigning session persistence state except assigning iphash explicitly", + "en_US": "loadBalancer[{0}] listener[{1}] {2} algorithm doesn\u0027t support assigning session persistence state except assigning iphash explicitly", + "zh_CN": "LoadBalancer[{0}]Listener[{1}]{2}算法不支持分配会话持久性状态,但显式分配IPHASH除外", "arguments": [ - "l2.getType()" + "msg.getLoadBalancerUuid()", + "msg.getName()", + "algorithm" ], - "line": 127, - "fileName": "src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java" + "line": 823, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unexpected VNC port number[%d] for VM [uuid:%s]", - "en_US": "unexpected VNC port number[{0}] for VM [uuid:{1}]", - "zh_CN": "", + "raw": "invalid session persistence type[%s], it only support %s", + "en_US": "invalid session persistence type[{0}], it only support {1}", + "zh_CN": "会话持久性类型[{0}]无效,它仅支持{1}", "arguments": [ - "rsp.getPort()", - "vm.getUuid()" + "enableSession", + "Arrays.toString(LoadBalancerSessionPersistence.values())" ], - "line": 68, - "fileName": "src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java" + "line": 849, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host[uuid:%s] has been deleted", - "en_US": "host[uuid:{0}] has been deleted", - "zh_CN": "物理机[uuid:{0}]已经被删除了", + "raw": "invalid session idle timeout[%s], it must be the number between[%s~%s] ", + "en_US": "invalid session idle timeout[{0}], it must be the number between[{1}~{2}] ", + "zh_CN": "会话空闲超时[{0}]无效,它必须是介于[{1}~{2}]之间的数字", "arguments": [ - "self.getUuid()" + "timeout", + "LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN", + "LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX" ], - "line": 333, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 856, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unable to get first boot dev of vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", - "en_US": "unable to get first boot dev of vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3}", - "zh_CN": "", + "raw": "invalid session cookie name[%s], it must be shorter than [%s] characters", + "en_US": "invalid session cookie name[{0}], it must be shorter than [{1}] characters", + "zh_CN": "会话Cookie名称[{0}]无效,必须少于[{1}]个字符", "arguments": [ - "msg.getVmInstanceUuid()", - "self.getUuid()", - "self.getManagementIp()", - "ret.getError()" + "cookieName", + "COOKIE_NAME_MAX" ], - "line": 499, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 863, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unable to connect to KVM[ip:%s, username:%s, sshPort:%d ] to do DNS check, please check if username/password is wrong; %s", - "en_US": "unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2} ] to do DNS check, please check if username/password is wrong; {3}", - "zh_CN": "无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3}", + "raw": "invalid session cookie name[%s], it must only contains letters, numbers and underscores", + "en_US": "invalid session cookie name[{0}], it must only contains letters, numbers and underscores", + "zh_CN": "会话Cookie名称[{0}]无效,它只能包含字母、数字和下划线", "arguments": [ - "self.getManagementIp()", - "getSelf().getUsername()", - "getSelf().getPort()", - "result.getExitErrorMessage()" + "cookieName" ], - "line": 713, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 866, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the host[uuid:%s, status:%s] is not Connected", - "en_US": "the host[uuid:{0}, status:{1}] is not Connected", - "zh_CN": "物理机[uuid:{0}, 状态:{1}]不是Connected状态", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning idle timeout and cookie name at the same time", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning idle timeout and cookie name at the same time", + "zh_CN": "LoadBalancer[{0}]Listener[{1}]不支持同时分配空闲超时和Cookie名称", "arguments": [ - "self.getUuid()", - "self.getStatus()" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 795, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 870, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "cannot do volume snapshot merge when vm[uuid:%s] is in state of %s. The operation is only allowed when vm is Running or Stopped", - "en_US": "cannot do volume snapshot merge when vm[uuid:{0}] is in state of {1}. The operation is only allowed when vm is Running or Stopped", - "zh_CN": "当云主机[uuid:{0}]处于{1}状态的时候不能做云盘快照合并。此操作只能在云主机处在Running和Stopped状态时进行", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning idle timeout and cookie name, it must specify session persistence", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning idle timeout and cookie name, it must specify session persistence", + "zh_CN": "LoadBalancer[{0}]Listener[{1}]不支持分配空闲超时和Cookie名称,它必须指定会话持久性", "arguments": [ - "volume.getUuid()", - "state" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1121, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 876, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "live volume snapshot merge needs libvirt version greater than %s, current libvirt version is %s. Please stop vm and redo the operation or detach the volume if it\u0027s data volume", - "en_US": "live volume snapshot merge needs libvirt version greater than {0}, current libvirt version is {1}. Please stop vm and redo the operation or detach the volume if it\u0027s data volume", - "zh_CN": "实时云盘快照合并需要libvirt版本高于{0},现在libvirt版本为{1}。请停止云主机后重试或卸载云盘(仅当为数据云盘时)", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning idle timeout and cookie name when the session persistence is disabled", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning idle timeout and cookie name when the session persistence is disabled", + "zh_CN": "禁用会话持久性时,LoadBalancer[{0}]Listener[{1}]不支持分配空闲超时和Cookie名称", "arguments": [ - "KVMConstant.MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION", - "libvirtVersion" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1128, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 880, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "vm[uuid:%s] is not Running or Stopped, current state[%s]", - "en_US": "vm[uuid:{0}] is not Running or Stopped, current state[{1}]", - "zh_CN": "云主机[uuid:{0}]未处在Running或Stopped状态, 现在状态为[{1}]", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning session persistence rewrite without assigning cookie name", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning session persistence rewrite without assigning cookie name", + "zh_CN": "LoadBalancer[{0}]侦听器[{1}]不支持在不分配Cookie名称的情况下分配会话持久性重写", "arguments": [ - "msg.getVmUuid()", - "vmState" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1217, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 894, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to update nic[vm:%s] on kvm host[uuid:%s, ip:%s],because %s", - "en_US": "failed to update nic[vm:{0}] on kvm host[uuid:{1}, ip:{2}],because {3}", - "zh_CN": "", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning session persistence idle timeout without assigning rewrite mode", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning session persistence idle timeout without assigning rewrite mode", + "zh_CN": "LoadBalancer[{0}]侦听器[{1}]不支持在不分配重写模式的情况下分配会话持久性空闲超时", "arguments": [ - "msg.getVmInstanceUuid()", - "self.getUuid()", - "self.getManagementIp()", - "ret.getError()" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1578, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 899, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to attach nic[uuid:%s, vm:%s] on kvm host[uuid:%s, ip:%s],because %s", - "en_US": "failed to attach nic[uuid:{0}, vm:{1}] on kvm host[uuid:{2}, ip:{3}],because {4}", - "zh_CN": "在物理机[uuid:{2},IP:{3}]上加载网卡[uuid:{0},云主机:{1}]失败,因为:{4}", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning session persistence cookieName without assigning insert mode", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning session persistence cookieName without assigning insert mode", + "zh_CN": "LoadBalancer[{0}]侦听器[{1}]不支持在不分配插入模式的情况下分配会话持久性CookieName", "arguments": [ - "msg.getNicInventory().getUuid()", - "msg.getNicInventory().getVmInstanceUuid()", - "self.getUuid()", - "self.getManagementIp()", - "ret.getError()" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1625, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 904, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to detach data volume[uuid:%s, installPath:%s] from vm[uuid:%s, name:%s] on kvm host[uuid:%s, ip:%s], because %s", - "en_US": "failed to detach data volume[uuid:{0}, installPath:{1}] from vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6}", - "zh_CN": "无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]卸载数据云盘[uuid:{0}, installPath:{1}],因为: {6}", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning session persistence rewrite when the http mode is http-tunnel", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning session persistence rewrite when the http mode is http-tunnel", + "zh_CN": "当HTTP模式为HTTP隧道时,LoadBalancer[{0}]Listener[{1}]不支持分配会话持久性重写", "arguments": [ - "vol.getUuid()", - "vol.getInstallPath()", - "vm.getUuid()", - "vm.getName()", - "getSelf().getUuid()", - "getSelf().getManagementIp()", - "ret.getError()" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1672, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 909, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to attach data volume[uuid:%s, installPath:%s] to vm[uuid:%s, name:%s] on kvm host[uuid:%s, ip:%s], because %s", - "en_US": "failed to attach data volume[uuid:{0}, installPath:{1}] to vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6}", - "zh_CN": "无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]挂载数据云盘[uuid:{0}, installPath:{1}],因为: {6}", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning other session persistence when the source balancer algorithm is source", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning other session persistence when the source balancer algorithm is source", + "zh_CN": "当源平衡器算法为源时,LoadBalancer[{0}]侦听器[{1}]不支持分配其他会话持久性", "arguments": [ - "vol.getUuid()", - "vol.getInstallPath()", - "vm.getUuid()", - "vm.getName()", - "getSelf().getUuid()", - "getSelf().getManagementIp()", - "ret.getError()" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1759, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 920, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to destroy vm[uuid:%s name:%s] on kvm host[uuid:%s, ip:%s], because %s", - "en_US": "failed to destroy vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4}", - "zh_CN": "无法在物理机[uuid:{2}, ip:{3}]上删除云主机[uuid:{0} name:{1}],原因: {4}", + "raw": "loadBalancer[%s] listener[%s] doesn\u0027t support assigning session persistence iphash", + "en_US": "loadBalancer[{0}] listener[{1}] doesn\u0027t support assigning session persistence iphash", + "zh_CN": "LoadBalancer[{0}]侦听器[{1}]不支持分配会话持久性IPHASH", "arguments": [ - "vminv.getUuid()", - "vminv.getName()", - "self.getUuid()", - "self.getManagementIp()", - "e.getMessage()" + "msg.getLoadBalancerUuid()", + "msg.getName()" ], - "line": 1799, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 932, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to stop vm[uuid:%s name:%s] on kvm host[uuid:%s, ip:%s], because %s", - "en_US": "failed to stop vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4}", - "zh_CN": "在物理机[uuid:{2}, ip:{3}]上停止云主机[uuid:{0} 名称:{1}]失败,因为:{4}", + "raw": "invalid max connection[%s], %s is larger than upper threshold %d", + "en_US": "invalid max connection[{0}], {1} is larger than upper threshold {2}", + "zh_CN": "非法的最大连接数标签[{0}],因为其值{1}大于上限值{2}", "arguments": [ - "vminv.getUuid()", - "vminv.getName()", - "self.getUuid()", - "self.getManagementIp()", - "e.getMessage()" + "tag", + "s", + "LoadBalancerConstants.MAX_CONNECTION_LIMIT" ], - "line": 1928, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 950, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Host[%s] update spice channel config faild, because %s", - "en_US": "Host[{0}] update spice channel config faild, because {1}", - "zh_CN": "", + "raw": "conflict loadBalancerPort[%s], a listener[uuid:%s] has used that port", + "en_US": "conflict loadBalancerPort[{0}], a listener[uuid:{1}] has used that port", + "zh_CN": "冲突的负载均衡器端口(loadBalancerPort)[{0}],一个监听器[uuid:{1}]已经使用了该端口", "arguments": [ - "msg.getHostUuid()", - "ret.getError()" + "msg.getLoadBalancerPort()", + "luuid" ], - "line": 2015, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 972, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to check physical network interfaces[names : %s] on kvm host[uuid:%s, ip:%s]", - "en_US": "failed to check physical network interfaces[names : {0}] on kvm host[uuid:{1}, ip:{2}]", - "zh_CN": "", + "raw": "the listener with protocol [%s] doesn\u0027t support select security policy", + "en_US": "the listener with protocol [{0}] doesn\u0027t support select security policy", + "zh_CN": "具有协议[{0}]的侦听器不支持选择安全策略", "arguments": [ - "msg.getPhysicalInterface()", - "context.getInventory().getUuid()", - "context.getInventory().getManagementIp()" + "listenerVO.getProtocol()", + "msg.getHealthCheckProtocol()" ], - "line": 2414, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1161, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "detected abnormal status[host uuid change, expected: %s but: %s] of kvmagent,it\u0027s mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon", - "en_US": "detected abnormal status[host uuid change, expected: {0} but: {1}] of kvmagent,it\u0027s mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon", - "zh_CN": "监测到kvmagent异常的状态[host uuid改变,期望: {0}, 实际: {1}], 这很有可能是kvmagent重启导致的, 报告这个情况给ping, 它会触发重连", + "raw": "loadbalancer listener with type %s does not need certificate", + "en_US": "loadbalancer listener with type {0} does not need certificate", + "zh_CN": "[{0}]类型证书不需要证书", "arguments": [ - "self.getUuid()", - "ret.getHostUuid()" + "vo.getProtocol()" ], - "line": 2477, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1005, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unable to connect to kvm host[uuid:%s, ip:%s, url:%s], because %s", - "en_US": "unable to connect to kvm host[uuid:{0}, ip:{1}, url:{2}], because {3}", - "zh_CN": "连接物理机[uuid:{0}, ip:{1},url:{2}]失败,因为:{3}", + "raw": "loadbalancer listener [uuid:%s] already had certificate[uuid:%s]", + "en_US": "loadbalancer listener [uuid:{0}] already had certificate[uuid:{1}]", + "zh_CN": "LoadBalancer侦听器[uuid:{0}]已具有证书[uuid:{1}]", "arguments": [ - "self.getUuid()", - "self.getManagementIp()", - "connectPath", - "rsp.getError()" + "msg.getListenerUuid()", + "msg.getCertificateUuid()" ], - "line": 2602, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1009, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host can not access any primary storage, please check network", - "en_US": "host can not access any primary storage, please check network", - "zh_CN": "物理机无法访问任何主存储,请检查网络", - "arguments": [], - "line": 2660, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "raw": "certificate [uuid:%s] is not added to loadbalancer listener [uuid:%s]", + "en_US": "certificate [uuid:{0}] is not added to loadbalancer listener [uuid:{1}]", + "zh_CN": "证书[uuid:{0}]未添加到负载均衡监听器[uuid:{1}]", + "arguments": [ + "msg.getCertificateUuid()", + "msg.getListenerUuid()" + ], + "line": 1019, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the host\u0027 ssh port[%s] not open after %s seconds, connect timeout", - "en_US": "the host\u0027 ssh port[{0}] not open after {1} seconds, connect timeout", - "zh_CN": "物理机的ssh端口[{0}]在{1}秒后仍未开启,连接超时", + "raw": "healthCheck target [%s] error, it must be \u0027default\u0027 or number between[1~65535] ", + "en_US": "healthCheck target [{0}] error, it must be \u0027default\u0027 or number between[1~65535] ", + "zh_CN": "健康检查端口[{0}]错误,值必须是\u0027default\u0027或者数字[1~65535]", "arguments": [ - "getSelf().getPort()", - "KVMGlobalConfig.TEST_SSH_PORT_ON_OPEN_TIMEOUT.value(Long.class)" + "target" ], - "line": 2836, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1034, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to ping all DNS/IP in %s; please check /etc/resolv.conf to make sure your host is able to reach public internet", - "en_US": "failed to ping all DNS/IP in {0}; please check /etc/resolv.conf to make sure your host is able to reach public internet", - "zh_CN": "在{0}中的所有DNS/IP都ping失败了,请检查 /etc/resolv.conf 来确保你的主机能连接到公网", + "raw": "l4[%s] loadBalancer listener[%s] doesn\u0027t support modifying session persistence state", + "en_US": "l4[{0}] loadBalancer listener[{1}] doesn\u0027t support modifying session persistence state", + "zh_CN": "L4[{0}]LoadBalancer侦听器[{1}]不支持修改会话持久性状态", "arguments": [ - "checkList" + "listener.getProtocol()", + "listener.getName()" ], - "line": 2891, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1050, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unable to connect to KVM[ip:%s, username:%s, sshPort: %d, ] to do DNS check, please check if username/password is wrong; %s", - "en_US": "unable to connect to KVM[ip:{0}, username:{1}, sshPort: {2}, ] to do DNS check, please check if username/password is wrong; {3}", - "zh_CN": "无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3}", + "raw": "listener[%s] can not modifying session persistence rewrite when the http mode is http-tunnel", + "en_US": "listener[{0}] can not modifying session persistence rewrite when the http mode is http-tunnel", + "zh_CN": "当HTTP模式为HTTP隧道时,侦听器[{0}]无法修改会话持久性重写", "arguments": [ - "self.getManagementIp()", - "getSelf().getUsername()", - "getSelf().getPort()", - "ret.getExitErrorMessage()" + "msg.getUuid()" ], - "line": 2889, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1064, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "the KVM host[ip:%s] cannot access the management node\u0027s callback url. It seems that the KVM host cannot reach the management IP[%s]. %s %s", - "en_US": "the KVM host[ip:{0}] cannot access the management node\u0027s callback url. It seems that the KVM host cannot reach the management IP[{1}]. {2} {3}", - "zh_CN": "物理机[ip:{0}] 不能连接到管理节点 。 看起来是这个物理机无法到达管理节点的IP [{1}]. {2} {3}", + "raw": "listener[%s] can not modifying httpMode http-tunnel when the session persistence is rewrite", + "en_US": "listener[{0}] can not modifying httpMode http-tunnel when the session persistence is rewrite", + "zh_CN": "重写会话持久性时,侦听器[{0}]无法修改httpmode HTTP-tunnel", "arguments": [ - "self.getManagementIp()", - "restf.getHostName()", - "ret.getStderr()", - "ret.getExitErrorMessage()" + "msg.getUuid()" ], - "line": 2917, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1072, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unable to connect to KVM[ip:%s, username:%s, sshPort:%d] to check the management node connectivity,please check if username/password is wrong; %s", - "en_US": "unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2}] to check the management node connectivity,please check if username/password is wrong; {3}", - "zh_CN": "不能连接到物理机[ip:{0}, username:{1}, sshPort:{2}] 去检查与管理节点是否连通 ,请检查您的用户名或者密码是否有误; {3}", + "raw": "listener[%s] changes session persistence to iphash, it must specify source balancer algorithm", + "en_US": "listener[{0}] changes session persistence to iphash, it must specify source balancer algorithm", + "zh_CN": "侦听器[{0}]将会话持久性更改为IPHASH,它必须指定源平衡器算法", "arguments": [ - "self.getManagementIp()", - "getSelf().getUsername()", - "getSelf().getPort()", - "ret.getExitErrorMessage()" + "msg.getUuid()" ], - "line": 2914, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1079, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "cannot find either \u0027vmx\u0027 or \u0027svm\u0027 in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting", - "en_US": "cannot find either \u0027vmx\u0027 or \u0027svm\u0027 in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting", - "zh_CN": "不能发现以下任意一个 \u0027vmx\u0027 or \u0027svm\u0027 在路径 /proc/cpuinfo 里, 请检查你是否在你的BIOS设置里开启了virtualization选项", - "arguments": [], - "line": 3123, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "raw": "listener[%s] modifies session persistence, it must specify balancer algorithm", + "en_US": "listener[{0}] modifies session persistence, it must specify balancer algorithm", + "zh_CN": "侦听器[{0}]修改会话持久性,它必须指定平衡器算法", + "arguments": [ + "msg.getUuid()" + ], + "line": 1084, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match", - "en_US": "host [uuid:{0}] cannot be added to cluster [uuid:{1}] because qemu/libvirt version does not match", - "zh_CN": "物理机[uuid:{0}]不能添加到集群[uuid:{1}]中,因为qemu/libvirt不匹配", + "raw": "listener[%s] %s algorithm doesn\u0027t support modifying session persistence except assigning iphash explicitly", + "en_US": "listener[{0}] {1} algorithm doesn\u0027t support modifying session persistence except assigning iphash explicitly", + "zh_CN": "侦听器[{0}]{1}算法不支持修改会话持久性,除非显式分配IPHASH", "arguments": [ - "self.getUuid()", - "self.getClusterUuid()" + "msg.getUuid()", + "msg.getBalancerAlgorithm()" ], - "line": 2748, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1090, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", - "en_US": "host [uuid:{0}] cannot be added to cluster [uuid:{1}] because cpu model name does not match", - "zh_CN": "物理机[uuid:{0}]无法被添加到集群[uuid:{1}]因为cpu型号不一致", + "raw": "listener[%s] %s algorithm doesn\u0027t support modifying session persistence except assigning disable explicitly", + "en_US": "listener[{0}] {1} algorithm doesn\u0027t support modifying session persistence except assigning disable explicitly", + "zh_CN": "侦听器[{0}]{1}算法不支持修改会话持久性,除非显式指定禁用", "arguments": [ - "self.getUuid()", - "self.getClusterUuid()" + "msg.getUuid()", + "msg.getBalancerAlgorithm()" ], - "line": 2769, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "line": 1098, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host is not in the connected status, cannot update os", - "en_US": "host is not in the connected status, cannot update os", - "zh_CN": "物理机当前并不是已连接状态,不能升级操作系统", - "arguments": [], - "line": 3402, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "raw": "listener[%s] doesn\u0027t support modifying idle timeout and cookie name, it must specify session persistence", + "en_US": "listener[{0}] doesn\u0027t support modifying idle timeout and cookie name, it must specify session persistence", + "zh_CN": "侦听器[{0}]不支持修改空闲超时和cookie名称,它必须指定会话持久性", + "arguments": [ + "msg.getUuid()" + ], + "line": 1106, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host is in the premaintenance state, cannot update os", - "en_US": "host is in the premaintenance state, cannot update os", - "zh_CN": "物理机正处于预维护状态,不能升级操作系统", - "arguments": [], - "line": 3400, - "fileName": "src/main/java/org/zstack/kvm/KVMHost.java" + "raw": "listener[%s] doesn\u0027t support modifying idle timeout when the session persistence is not insert", + "en_US": "listener[{0}] doesn\u0027t support modifying idle timeout when the session persistence is not insert", + "zh_CN": "当会话持久性不是INSERT时,侦听器[{0}]不支持修改空闲超时", + "arguments": [ + "msg.getUuid()" + ], + "line": 1110, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "cannot adapt version for the bellow rpm: livirt / qemu / cpumodel", - "en_US": "cannot adapt version for the bellow rpm: livirt / qemu / cpumodel", - "zh_CN": "源和目的之间的以下组件版本不兼容:livirt、qemu、cpumodel", - "arguments": [], - "line": 63, - "fileName": "src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java" + "raw": "listener[%s] doesn\u0027t support modifying cookie name when the session persistence is not rewrite", + "en_US": "listener[{0}] doesn\u0027t support modifying cookie name when the session persistence is not rewrite", + "zh_CN": "侦听器[{0}]不支持在会话持久性未重写时修改cookie名称", + "arguments": [ + "msg.getUuid()" + ], + "line": 1114, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "The host[uuid:%s]\u0027s available memory capacity[%s] is lower than the reserved capacity[%s]", - "en_US": "The host[uuid:{0}]\u0027s available memory capacity[{1}] is lower than the reserved capacity[{2}]", - "zh_CN": "物理机[uuid:{0}]的可用内存[{1}]少于保留内存[{2}]", + "raw": "listener[%s] doesn\u0027t support modifying session rewrite without modifying cookie name", + "en_US": "listener[{0}] doesn\u0027t support modifying session rewrite without modifying cookie name", + "zh_CN": "侦听器[{0}]不支持在不修改Cookie名称的情况下修改会话重写", "arguments": [ - "host.getUuid()", - "rsp.getTotalMemory()", - "reservedSize" + "msg.getUuid()" ], - "line": 57, - "fileName": "src/main/java/org/zstack/kvm/KVMHostCapacityExtension.java" + "line": 1118, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "fail to load host info from file. because\\n%s", - "en_US": "fail to load host info from file. because\\n{0}", - "zh_CN": "", + "raw": "invalid session idle timeout[%s], it must be the number between[%s~%s]", + "en_US": "invalid session idle timeout[{0}], it must be the number between[{1}~{2}]", + "zh_CN": "会话空闲超时[{0}]无效,它必须是介于[{1}~{2}]之间的数字", "arguments": [ - "e.getMessage()" + "timeout", + "LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN", + "LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX" ], - "line": 111, - "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + "line": 1132, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "there are still hosts not have the same cpu model, details: %s", - "en_US": "there are still hosts not have the same cpu model, details: {0}", - "zh_CN": "仍存在host有不同的cpu模型,详细信息:{0}", + "raw": "the http health check protocol must be specified its healthy checking parameters including healthCheckMethod and healthCheckURI", + "en_US": "the http health check protocol must be specified its healthy checking parameters including healthCheckMethod and healthCheckURI", + "zh_CN": "http类型的健康检查协议必须提供healthCheckMethod和healthCheckURI参数", + "arguments": [], + "line": 1181, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + }, + { + "raw": "could not allow to delete default serverGroup[uuid:%s]", + "en_US": "could not allow to delete default serverGroup[uuid:{0}]", + "zh_CN": "无法允许删除默认服务器组[uuid:{0}]", "arguments": [ - "str.toString()" + "msg.getUuid()" ], - "line": 329, - "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + "line": 1204, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "pci bridge need a value greater than 0 and lower than 32", - "en_US": "pci bridge need a value greater than 0 and lower than 32", - "zh_CN": "", + "raw": "loadbalacerServerGroup [%s] is non-existent", + "en_US": "loadbalacerServerGroup [{0}] is non-existent", + "zh_CN": "LoadBalacerServerGroup[{0}]不存在", "arguments": [ - "KVMSystemTags.VM_PREDEFINED_PCI_BRIDGE_NUM_TOKEN" + "msg.getServerGroupUuid()" ], - "line": 343, - "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + "line": 1429, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "host[uuid:%s] does not have cpu model information, you can reconnect the host to fix it", - "en_US": "host[uuid:{0}] does not have cpu model information, you can reconnect the host to fix it", - "zh_CN": "物理机[uuid:{0}]无cpu模型信息,你可以尝试重连来解决这个问题", + "raw": "could not add backend server vmnic[uuid:%s] to serverGroup[uuid:%s],because vmnic uuid is not exist", + "en_US": "could not add backend server vmnic[uuid:{0}] to serverGroup[uuid:{1}],because vmnic uuid is not exist", + "zh_CN": "无法将后端服务器vmnic[uuid:{0}]添加到ServerGroup[uuid:{1}],因为vmnic uuid不存在", "arguments": [ - "hostUuid" + "vmNic.get(\"uuid\")", + "msg.getServerGroupUuid()" ], - "line": 364, - "fileName": "src/main/java/org/zstack/kvm/KVMHostFactory.java" + "line": 1263, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to create bridge[%s] for l2Network[uuid:%s, type:%s] on kvm host[uuid:%s], because %s", - "en_US": "failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}] on kvm host[uuid:{3}], because {4}", - "zh_CN": "在物理机[uuid:{3}]上为L2网络[uuid:{1}, type:{2}]创建网桥[{0}]失败,原因: {4}", + "raw": "could not add backend server vmnic to serverGroup[uuid:%s] ,because vmnic weight[%s] not a correct number", + "en_US": "could not add backend server vmnic to serverGroup[uuid:{0}] ,because vmnic weight[{1}] not a correct number", + "zh_CN": "无法将后端服务器vmnic添加到ServerGroup[uuid:{0}],因为vmnic权重[{1}]不是正确的数字", "arguments": [ - "cmd.getBridgeName()", - "l2Network.getUuid()", - "l2Network.getType()", - "hostUuid", - "rsp.getError()" + "vmNic.get(\"weight\")" ], - "line": 69, - "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java" + "line": 1274, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to check bridge[%s] for l2NoVlanNetwork[uuid:%s, name:%s] on kvm host[uuid: %s], %s", - "en_US": "failed to check bridge[{0}] for l2NoVlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid: {3}], {4}", - "zh_CN": "在L2网络[uuid:{1}中检查网桥[{0}]失败,名字为[{2}]在物理机t[uuid: {3}]上, {4}", + "raw": "invalid balancer weight[vimNic:%s,weight:%s], weight is not in the range [%d, %d]", + "en_US": "invalid balancer weight[vimNic:{0},weight:{1}], weight is not in the range [{2}, {3}]", + "zh_CN": "无效的平衡器重量[vimnic:{0},重量:{1}],重量不在范围[{2},{3}]内", "arguments": [ - "cmd.getBridgeName()", - "l2Network.getUuid()", - "l2Network.getName()", - "hostUuid", - "rsp.getError()" + "vmNic.get(\"uuid\")", + "vmNicWeight", + "LoadBalancerConstants.BALANCER_WEIGHT_MIN", + "LoadBalancerConstants.BALANCER_WEIGHT_MAX" ], - "line": 119, - "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java" + "line": 1552, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to create bridge[%s] for l2Network[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", - "en_US": "failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5}", - "zh_CN": "创建L2网络[uuid:{1}中的网桥[{0}]失败 , 类型为: {2}, vlan:{3}] 在物理机[uuid:{4}]上, 原因: {5}", + "raw": "the vm nics[uuid:%s] are already on the load balancer servegroup [uuid:%s]", + "en_US": "the vm nics[uuid:{0}] are already on the load balancer servegroup [uuid:{1}]", + "zh_CN": "VM NIC[uuid:{0}]已位于负载平衡器ServerGroup[uuid:{1}]上", "arguments": [ - "cmd.getBridgeName()", - "l2Network.getUuid()", - "l2Network.getType()", - "l2vlan.getVlan()", - "hostUuid", - "rsp.getError()" + "existingNics", + "msg.getServerGroupUuid()" ], - "line": 66, - "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java" + "line": 1304, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to check bridge[%s] for l2VlanNetwork[uuid:%s, name:%s] on kvm host[uuid:%s], %s", - "en_US": "failed to check bridge[{0}] for l2VlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", - "zh_CN": "检查在物理机[uuid:{3}]上L2网络[uuid:{1}, name:{2}]中的网桥[{0}]失败, {4}", + "raw": "could not add backend server vmnic to serverGroup [uuid:%s], because vmnic ip [ipAddress:%s] is repeated", + "en_US": "could not add backend server vmnic to serverGroup [uuid:{0}], because vmnic ip [ipAddress:{1}] is repeated", + "zh_CN": "无法将后端服务器vmnic添加到ServerGroup[uuid:{0}],因为vmnic IP[IPAddress:{1}]重复", "arguments": [ - "cmd.getBridgeName()", - "l2vlan.getUuid()", - "l2vlan.getName()", - "hostUuid", - "rsp.getError()" + "msg.getServerGroupUuid()", + "vmNicIps" ], - "line": 117, - "fileName": "src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java" + "line": 1313, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to apply rules of security group rules to kvm host[uuid:%s], because %s", - "en_US": "failed to apply rules of security group rules to kvm host[uuid:{0}], because {1}", - "zh_CN": "不能应用安全组规则在物理机t[uuid:{0}]上, 因为 {1}", + "raw": "could not add vm nic [uuid:%s] to server group [uuid:%s] because listener [uuid:%s] attached this server group already the nic to be added", + "en_US": "could not add vm nic [uuid:{0}] to server group [uuid:{1}] because listener [uuid:{2}] attached this server group already the nic to be added", + "zh_CN": "无法将VM NIC[uuid:{0}]添加到服务器组[uuid:{1}],因为侦听程序[uuid:{2}]已将此服务器组连接到要添加的NIC", "arguments": [ - "hto.getHostUuid()", - "rsp.getError()" + "vmNicUuids", + "msg.getServerGroupUuid()", + "listenerVO.getUuid()" ], - "line": 111, - "fileName": "src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java" + "line": 1325, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "failed to check default rules of security group on kvm host[uuid:%s], because %s", - "en_US": "failed to check default rules of security group on kvm host[uuid:{0}], because {1}", - "zh_CN": "在host[uuid:{0}]上检查默认安全组规则失败", + "raw": "could not add backend server ip to serverGroup [uuid:%s], because ip [ipAddress:%s] is invalid", + "en_US": "could not add backend server ip to serverGroup [uuid:{0}], because ip [ipAddress:{1}] is invalid", + "zh_CN": "无法将后端服务器IP添加到ServerGroup[uuid:{0}],因为IP[IPAddress:{1}]无效", "arguments": [ - "hostUuid", - "rsp.getError()" + "msg.getServerGroupUuid()", + "serverIps" ], - "line": 154, - "fileName": "src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java" + "line": 1606, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unable to do vm sync on host[uuid:%s, ip:%s] because %s", - "en_US": "unable to do vm sync on host[uuid:{0}, ip:{1}] because {2}", - "zh_CN": "不能在物理机[uuid:{0}, ip:{1}]上执行云主机状态同步操作,因为{2}", + "raw": "could not add backend server ip to serverGroup [uuid:%s], because ip [ipAddress:%s] is repeated", + "en_US": "could not add backend server ip to serverGroup [uuid:{0}], because ip [ipAddress:{1}] is repeated", + "zh_CN": "无法将后端服务器IP添加到ServerGroup[uuid:{0}],因为IP[IPAddress:{1}]重复", "arguments": [ - "host.getUuid()", - "host.getManagementIp()", - "ret.getError()" + "msg.getServerGroupUuid()", + "server.get(\"ipAddress\")" ], - "line": 162, - "fileName": "src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java" + "line": 1341, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "The vm[%s] state is in shutdown for a long time, check whether the vm is normal", - "en_US": "The vm[{0}] state is in shutdown for a long time, check whether the vm is normal", - "zh_CN": "", + "raw": "could not add backend server ip to serverGroup[uuid:%s] ,because vmnic weight[%s] not a correct number", + "en_US": "could not add backend server ip to serverGroup[uuid:{0}] ,because vmnic weight[{1}] not a correct number", + "zh_CN": "无法将后端服务器IP添加到ServerGroup[uuid:{0}],因为vmnic权重[{1}]不是正确的数字", "arguments": [ - "vmUuid" + "server.get(\"weight\")" ], - "line": 191, - "fileName": "src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java" + "line": 1599, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unsupported LDAP/AD server scope", - "en_US": "unsupported LDAP/AD server scope", - "zh_CN": "", - "arguments": [], - "line": 67, - "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + "raw": "invalid weight[serverIp:%s,weight:%s], weight is not in the range [%d, %d]", + "en_US": "invalid weight[serverIp:{0},weight:{1}], weight is not in the range [{2}, {3}]", + "zh_CN": "权重[服务器IP:{0},权重:{1}]无效,权重不在范围[{2},{3}]内", + "arguments": [ + "server.get(\"ipAddress\")", + "serverIpWeight", + "LoadBalancerConstants.BALANCER_WEIGHT_MIN", + "LoadBalancerConstants.BALANCER_WEIGHT_MAX" + ], + "line": 1352, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Wrong LdapServerType[%s], valid values: [%,%s]", - "en_US": "Wrong LdapServerType[{0}], valid values: [%,{1}]", - "zh_CN": "错误的LDAP服务类型[{0}],有效的值: [%,{1}]", + "raw": "the server ips [uuid:%s] are already on the load balancer servegroup [uuid:%s]", + "en_US": "the server ips [uuid:{0}] are already on the load balancer servegroup [uuid:{1}]", + "zh_CN": "服务器IP[uuid:{0}]已在负载平衡器ServerGroup[uuid:{1}]上", "arguments": [ - "type", - "LdapConstant.OpenLdap.TYPE", - "LdapConstant.WindowsAD.TYPE" + "existingServerIps", + "msg.getServerGroupUuid()" ], - "line": 117, - "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + "line": 1367, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Cannot connect to LDAP/AD server, Invalid Credentials, please checkout User DN and password", - "en_US": "Cannot connect to LDAP/AD server, Invalid Credentials, please checkout User DN and password", - "zh_CN": "", + "raw": "could not add server ip to share load balancer server group", + "en_US": "could not add server ip to share load balancer server group", + "zh_CN": "无法将服务器IP添加到共享负载平衡器服务器组", "arguments": [], - "line": 142, - "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + "line": 1611, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Cannot connect to LDAP/AD server, communication false, please checkout IP, port and Base DN", - "en_US": "Cannot connect to LDAP/AD server, communication false, please checkout IP, port and Base DN", - "zh_CN": "", + "raw": "vmnic or ip is null", + "en_US": "vmnic or ip is null", + "zh_CN": "vmnic或IP为空", "arguments": [], - "line": 145, - "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + "line": 1433, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Cannot connect to LDAP/AD server, %s", - "en_US": "Cannot connect to LDAP/AD server, {0}", - "zh_CN": "不能连接LDAP服务,{0}", + "raw": "vmnics are all not in servergroup [%s]", + "en_US": "vmnics are all not in servergroup [{0}]", + "zh_CN": "VMNIC均不在ServerGroup[{0}]中", "arguments": [ - "e.toString()" + "msg.getServerGroupUuid()" ], - "line": 148, - "fileName": "src/main/java/org/zstack/ldap/LdapApiInterceptor.java" + "line": 1397, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Account[uuid:%s] Not Found!!!", - "en_US": "Account[uuid:{0}] Not Found!!!", - "zh_CN": "", + "raw": "serverips are all not in servergroup [%s]", + "en_US": "serverips are all not in servergroup [{0}]", + "zh_CN": "ServerIP全部不在ServerGroup[{0}]中", "arguments": [ - "vo.getAccountUuid()" + "msg.getServerGroupUuid()" ], - "line": 181, - "fileName": "src/main/java/org/zstack/ldap/LdapManagerImpl.java" + "line": 1414, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "query ldap entry[filter: %s] fail, because %s", - "en_US": "query ldap entry[filter: {0}] fail, because {1}", - "zh_CN": "", + "raw": "could not add server group[uuid:%s} to listener [uuid:%s] because it is already added ", + "en_US": "could not add server group[uuid:{0}} to listener [uuid:{1}] because it is already added ", + "zh_CN": "无法将服务器组[uuid:{0}}添加到侦听器[uuid:{1}],因为它已添加", "arguments": [ - "filter", - "errorMessage" + "msg.getServerGroupUuid()", + "msg.getlistenerUuid()" ], - "line": 456, - "fileName": "src/main/java/org/zstack/ldap/LdapUtil.java" + "line": 1444, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "query ldap entry fail, %s", - "en_US": "query ldap entry fail, {0}", - "zh_CN": "查询LDAP条目失败,{0}", + "raw": "could not add server group[uuid:%s} to listener [uuid:%s] because nic [uuid:%s] is already added", + "en_US": "could not add server group[uuid:{0}} to listener [uuid:{1}] because nic [uuid:{2}] is already added", + "zh_CN": "无法将服务器组[uuid:{0}}添加到侦听器[uuid:{1}],因为已经添加了NIC[uuid:{2}]", "arguments": [ - "e.toString()" + "msg.getServerGroupUuid()", + "msg.getlistenerUuid()", + "nicUuid" ], - "line": 52, - "fileName": "src/main/java/org/zstack/ldap/externalSearch/AggregateSearch.java" + "line": 1461, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Parse license error,\\n1. check your private key and application code is correct\\n2. check your license is not corrupted\\n3. use zstack-ctl clear_license to clear your licenses and try to reinstall\\n", - "en_US": "Parse license error,\\n1. check your private key and application code is correct\\n2. check your license is not corrupted\\n3. use zstack-ctl clear_license to clear your licenses and try to reinstall\\n", - "zh_CN": "", - "arguments": [], - "line": 129, - "fileName": "src/main/java/org/zstack/license/LicenseChecker.java" + "raw": "could not add server group[uuid:%s} to listener [uuid:%s] because server ip [%s] is already added", + "en_US": "could not add server group[uuid:{0}} to listener [uuid:{1}] because server ip [{2}] is already added", + "zh_CN": "无法将服务器组[uuid:{0}}添加到侦听器[uuid:{1}],因为已添加服务器IP[{2}]", + "arguments": [ + "msg.getServerGroupUuid()", + "msg.getlistenerUuid()", + "ipAddress" + ], + "line": 1476, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Decode fail because %s", - "en_US": "Decode fail because {0}", - "zh_CN": "解码失败,因为{0}", + "raw": "could not remove server group[uuid:%s} from listener [uuid:%s] because it is not added", + "en_US": "could not remove server group[uuid:{0}} from listener [uuid:{1}] because it is not added", + "zh_CN": "由于未添加服务器组[uuid:{1}],因此无法将其从侦听器[uuid:{1}]中删除", "arguments": [ - "e.getMessage()" + "msg.getServerGroupUuid()", + "msg.getListenerUuid()" ], - "line": 220, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 1496, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Unexpected decoded license file length: %d", - "en_US": "Unexpected decoded license file length: {0}", - "zh_CN": "", + "raw": "loadbalacerUuid [%s] is non-existent", + "en_US": "loadbalacerUuid [{0}] is non-existent", + "zh_CN": "LoadBalaceRuuid[{0}]不存在", "arguments": [ - "bytes.length" + "loadBalancerUuid" ], - "line": 217, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 1511, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Licensed VM number overrun", - "en_US": "Licensed VM number overrun", - "zh_CN": "VM数量超过云主机授权上限", - "arguments": [], - "line": 846, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "raw": "could not find loadBalancer with serverGroup [uuid:%s]", + "en_US": "could not find loadBalancer with serverGroup [uuid:{0}]", + "zh_CN": "找不到ServerGroup为[uuid:{0}]的LoadBalancer", + "arguments": [ + "msg.getServerGroupUuid()" + ], + "line": 1526, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "unexpected license policy: %d %s.", - "en_US": "unexpected license policy: {0} {1}.", - "zh_CN": "", + "raw": "could not update backend server vmnic of serverGroup[uuid:%s],because vmnic uuid is null", + "en_US": "could not update backend server vmnic of serverGroup[uuid:{0}],because vmnic uuid is null", + "zh_CN": "无法更新ServerGroup[uuid:{0}]的后端服务器vmnic,因为vmnic uuid为空", "arguments": [ - "addonLicBy.first()", - "addonLicBy.second()" + "msg.getServerGroupUuid()" ], - "line": 1144, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 1567, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Addon[%s] licensed %d %s, but platform is licensed with VM number", - "en_US": "Addon[{0}] licensed {1} {2}, but platform is licensed with VM number", - "zh_CN": "", + "raw": "could not update backend server vmnic of serverGroup,because serverGroup[uuid:%s] don not have vmnic [uuid:%s] ", + "en_US": "could not update backend server vmnic of serverGroup,because serverGroup[uuid:{0}] don not have vmnic [uuid:{1}] ", + "zh_CN": "无法更新ServerGroup的后端服务器vmnic,因为ServerGroup[uuid:{0}]没有vmnic[uuid:{1}]", "arguments": [ - "info.getProdInfo()", - "addonLicBy.first()", - "addonLicBy.second()" + "msg.getServerGroupUuid()", + "vmNic.containsKey(\"uuid\")" ], - "line": 1195, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 1542, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Addon[%s] licensed %d %s, but platform is licensed with host", - "en_US": "Addon[{0}] licensed {1} {2}, but platform is licensed with host", - "zh_CN": "", + "raw": "invalid balancer weight[vimNic:%s], weight is null", + "en_US": "invalid balancer weight[vimNic:{0}], weight is null", + "zh_CN": "平衡器权重[vimnic:{0}]无效,权重为空", "arguments": [ - "info.getProdInfo()", - "addonLicBy.first()", - "addonLicBy.second()" + "vmNic.get(\"uuid\")" ], - "line": 1191, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 1564, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Addon[%s] licensed %d %s, but platform is licensed with CPU socket", - "en_US": "Addon[{0}] licensed {1} {2}, but platform is licensed with CPU socket", - "zh_CN": "", + "raw": "could not change backend server vmnic to serverGroup[uuid:%s] ,because vmnic weight[%s] not a correct number", + "en_US": "could not change backend server vmnic to serverGroup[uuid:{0}] ,because vmnic weight[{1}] not a correct number", + "zh_CN": "无法将后端服务器vmnic更改为ServerGroup[uuid:{0}],因为vmnic权重[{1}]不是正确的数字", "arguments": [ - "info.getProdInfo()", - "addonLicBy.first()", - "addonLicBy.second()" + "vmNic.get(\"weight\")" ], - "line": 1187, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 1559, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Add-on license is not supported when license type is Community", - "en_US": "Add-on license is not supported when license type is Community", - "zh_CN": "", - "arguments": [], - "line": 1507, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "raw": "could not update backend server ip of serverGroup,because serverGroup[uuid:%s] don not have ip [ipAddress:%s] ", + "en_US": "could not update backend server ip of serverGroup,because serverGroup[uuid:{0}] don not have ip [ipAddress:{1}] ", + "zh_CN": "无法更新ServerGroup的后端服务器IP,因为ServerGroup[uuid:{0}]没有IP[IP地址:{1}]", + "arguments": [ + "msg.getServerGroupUuid()", + "ipAddress" + ], + "line": 1583, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "License expired", - "en_US": "License expired", - "zh_CN": "", - "arguments": [], - "line": 1682, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "raw": "invalid balancer weight[serverIp:%s], weight is null", + "en_US": "invalid balancer weight[serverIp:{0}], weight is null", + "zh_CN": "无效的平衡器权重[ServerIP:{0}],权重为空", + "arguments": [ + "server.get(\"ipAddress\")" + ], + "line": 1602, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "No factory found for type:%s", - "en_US": "No factory found for type:{0}", - "zh_CN": "", + "raw": "invalid balancer weight[serverIp:%s,weight:%s], weight is not in the range [%d, %d]", + "en_US": "invalid balancer weight[serverIp:{0},weight:{1}], weight is not in the range [{2}, {3}]", + "zh_CN": "无效的平衡器权重[服务器IP:{0},权重:{1}],权重不在范围[{2},{3}]内", "arguments": [ - "struct.getType()" + "server.get(\"ipAddress\")", + "serverIpWeight", + "LoadBalancerConstants.BALANCER_WEIGHT_MIN", + "LoadBalancerConstants.BALANCER_WEIGHT_MAX" ], - "line": 249, - "fileName": "src/main/java/org/zstack/log/LogConfigurationManagerImpl.java" + "line": 1592, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" }, { - "raw": "Unknown log configuration type %s", - "en_US": "Unknown log configuration type {0}", - "zh_CN": "", + "raw": "could not change backendserver, beacause vmincs and serverips is null", + "en_US": "could not change backendserver, beacause vmincs and serverips is null", + "zh_CN": "无法更改后端服务器,因为VMINCS和ServerIPS为空", + "arguments": [], + "line": 1618, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + }, + { + "raw": "can not get service providerType for load balancer listener [uuid:%s]", + "en_US": "can not get service providerType for load balancer listener [uuid:{0}]", + "zh_CN": "无法获取负载平衡器侦听器[uuid:{0}]的Service ProviderType", "arguments": [ - "msg.getType()" + "struct.listenerUuid" ], - "line": 464, - "fileName": "src/main/java/org/zstack/log/LogConfigurationManagerImpl.java" + "line": 1355, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" }, { - "raw": "No factory found for log4j2 appender type:%s.", - "en_US": "No factory found for log4j2 appender type:{0}.", - "zh_CN": "", + "raw": "service provider type mismatching. The load balancer[uuid:%s] is provided by the service provider[type:%s], but new service provider is [type: %s]", + "en_US": "service provider type mismatching. The load balancer[uuid:{0}] is provided by the service provider[type:{1}], but new service provider is [type: {2}]", + "zh_CN": "服务提供商类型不匹配。负载平衡器[uuid:{0}]由服务提供程序[类型:{1}]提供,但新服务提供程序为[类型:{2}]", "arguments": [ - "lstruct.getAppenderType()" + "self.getUuid()", + "self.getProviderType()", + "providerType" ], - "line": 60, - "fileName": "src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java" + "line": 1384, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" }, { - "raw": "Unknown log4j2 appender type %s", - "en_US": "Unknown log4j2 appender type {0}", - "zh_CN": "", + "raw": "there is listener with same port [%s] and same load balancer [uuid:%s]", + "en_US": "there is listener with same port [{0}] and same load balancer [uuid:{1}]", + "zh_CN": "存在具有相同端口[{0}]和相同负载平衡器[uuid:{1}]的侦听器", "arguments": [ - "lstruct.getAppenderType()" + "msg.getLoadBalancerPort()", + "msg.getLoadBalancerUuid()" ], - "line": 134, - "fileName": "src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java" + "line": 1486, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" }, { - "raw": "facility can not be null", - "en_US": "facility can not be null", - "zh_CN": "", - "arguments": [], - "line": 44, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "raw": "invalid health checking parameters[%s], the format is method:URI:code, for example, GET:/index.html:http_2xx", + "en_US": "invalid health checking parameters[{0}], the format is method:URI:code, for example, GET:/index.html:http_2xx", + "zh_CN": "无效的健康检查参数[{0}],正确格式:method:URI:code,例如 GET:/index.html:http_2xx", + "arguments": [ + "param" + ], + "line": 2011, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" }, { - "raw": "invalid facility %s", - "en_US": "invalid facility {0}", - "zh_CN": "", + "raw": "invalid health target[%s], the format is targetCheckProtocol:port, for example, tcp:default", + "en_US": "invalid health target[{0}], the format is targetCheckProtocol:port, for example, tcp:default", + "zh_CN": "无效的健康检查目标[{0}],格式为[目标检查协议(targetCheckProtocol):端口(port)], 例如[tcp:default]", "arguments": [ - "configuration.facility" + "systemTag" ], - "line": 48, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "line": 699, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "hostname can not be null", - "en_US": "hostname can not be null", - "zh_CN": "", - "arguments": [], - "line": 52, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "raw": "cannot find the load balancer[uuid:%s]", + "en_US": "cannot find the load balancer[uuid:{0}]", + "zh_CN": "无法找到负载均衡器[uuid:{0}]", + "arguments": [ + "msg.getLoadBalancerUuid()" + ], + "line": 100, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "port can not be null", - "en_US": "port can not be null", - "zh_CN": "", - "arguments": [], - "line": 56, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "raw": "cannot delete the system tag[%s]. The load balancer plugin relies on it, you can only update it", + "en_US": "cannot delete the system tag[{0}]. The load balancer plugin relies on it, you can only update it", + "zh_CN": "无法删除系统标签[{0}]。负载均衡器插件依赖于该标签,该标签只能被更新", + "arguments": [ + "tag.getTag()" + ], + "line": 483, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "protocol can not be null", - "en_US": "protocol can not be null", - "zh_CN": "", - "arguments": [], - "line": 60, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "raw": "nic[uuid:%s] not found. Please correct your system tag[%s] of loadbalancer", + "en_US": "nic[uuid:{0}] not found. Please correct your system tag[{1}] of loadbalancer", + "zh_CN": "找不到网卡[uuid:{0}]。请检查负载均衡器的系统标签[{1}]", + "arguments": [ + "nicUuid", + "systemTag" + ], + "line": 502, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "MN HA environment, but only updated license for %s", - "en_US": "MN HA environment, but only updated license for {0}", - "zh_CN": "管理节点有多个,但是仅更新了节点{0}的许可证", + "raw": "invalid balancer weight[%s], %s is not a number", + "en_US": "invalid balancer weight[{0}], {1} is not a number", + "zh_CN": "无效的权重值[{0}], {1}不是一个数字", "arguments": [ - "Platform.getManagementServerIp()" + "systemTag", + "s" ], - "line": 1456, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 514, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "Multiple MN exists but only supplied licenses for %s", - "en_US": "Multiple MN exists but only supplied licenses for {0}", - "zh_CN": "管理节点有多个,但是仅提供了节点{0}的许可证", + "raw": "invalid balancer weight[%s], %s is not in the range [%d, %d]", + "en_US": "invalid balancer weight[{0}], {1} is not in the range [{2}, {3}]", + "zh_CN": "无效的权重值[{0}], {1}不在允许范围[{2}, {3}]中", "arguments": [ - "Platform.getManagementServerIp()" + "systemTag", + "s", + "LoadBalancerConstants.BALANCER_WEIGHT_MIN", + "LoadBalancerConstants.BALANCER_WEIGHT_MAX" ], - "line": 1454, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "line": 510, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "unexpected license file", - "en_US": "unexpected license file", - "zh_CN": "许可证错误", - "arguments": [], - "line": 1569, - "fileName": "src/main/java/org/zstack/license/LicenseManagerImpl.java" + "raw": "invalid balance algorithm[%s], valid algorithms are %s", + "en_US": "invalid balance algorithm[{0}], valid algorithms are {1}", + "zh_CN": "无效的均衡算法[{0}],有效的为[{1}]", + "arguments": [ + "algorithm", + "LoadBalancerConstants.BALANCE_ALGORITHMS" + ], + "line": 526, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "unsupported protocol %s", - "en_US": "unsupported protocol {0}", - "zh_CN": "", + "raw": "invalid unhealthy threshold[%s], %s is not a number", + "en_US": "invalid unhealthy threshold[{0}], {1} is not a number", + "zh_CN": "无效的不健康阈值[{0}],[{1}]不是一个数字", "arguments": [ - "configuration.protocol" + "systemTag", + "s" ], - "line": 66, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "line": 602, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "syslog server[address: %s:%s] is not available", - "en_US": "syslog server[address: {0}:{1}] is not available", - "zh_CN": "", + "raw": "invalid healthy threshold[%s], %s is not a number", + "en_US": "invalid healthy threshold[{0}], {1} is not a number", + "zh_CN": "无效的健康阈值[{0}],[{1}]不是一个数字", "arguments": [ - "configuration.hostname", - "configuration.port" + "systemTag", + "s" ], - "line": 80, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "line": 616, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "syslog server[address: %s] is not available", - "en_US": "syslog server[address: {0}] is not available", - "zh_CN": "", + "raw": "invalid healthy timeout[%s], %s is not a number", + "en_US": "invalid healthy timeout[{0}], {1} is not a number", + "zh_CN": "无效的健康超时[{0}],[{1}]不是一个数字", "arguments": [ - "configuration.hostname" + "systemTag", + "s" ], - "line": 72, - "fileName": "src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java" + "line": 630, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "There is no LDAP/AD server in the system, Please add a LDAP/AD server first.", - "en_US": "There is no LDAP/AD server in the system, Please add a LDAP/AD server first.", - "zh_CN": "在系统中没有LDAP服务,请先添加一个LDAP服务", - "arguments": [], - "line": 45, - "fileName": "src/main/java/org/zstack/login/LdapLoginInterceptor.java" + "raw": "invalid connection idle timeout[%s], %s is not a number", + "en_US": "invalid connection idle timeout[{0}], {1} is not a number", + "zh_CN": "无效的连接空闲超时[{0}],[{1}]不是一个数字", + "arguments": [ + "systemTag", + "s" + ], + "line": 644, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "Can not bind this ldap uid %s to virtual id [uuid:%s]", - "en_US": "Can not bind this ldap uid {0} to virtual id [uuid:{1}]", - "zh_CN": "", + "raw": "invalid health check interval[%s], %s is not a number", + "en_US": "invalid health check interval[{0}], {1} is not a number", + "zh_CN": "无效的健康检查间隔[{0}],[{1}]不是一个数字", "arguments": [ - "msg.getLdapUid()", - "msg.getVirtualIDUuid()" + "systemTag", + "s" ], - "line": 39, - "fileName": "src/main/java/org/zstack/login/LdapLoginInterceptor.java" + "line": 658, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "This uid is already used", - "en_US": "This uid is already used", - "zh_CN": "", - "arguments": [], - "line": 53, - "fileName": "src/main/java/org/zstack/login/LdapLoginInterceptor.java" + "raw": "invalid max connection[%s], %s is not a number", + "en_US": "invalid max connection[{0}], {1} is not a number", + "zh_CN": "无效的最大连接[{0}],[{1}]不是一个数字", + "arguments": [ + "systemTag", + "s" + ], + "line": 672, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "ZStack is loading ldap organizations from DB now, can not execute sync operation", - "en_US": "ZStack is loading ldap organizations from DB now, can not execute sync operation", - "zh_CN": "", - "arguments": [], - "line": 230, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "invalid process number[%s], %s is not a number", + "en_US": "invalid process number[{0}], {1} is not a number", + "zh_CN": "进程编号[{0}]无效,{1}不是数字", + "arguments": [ + "systemTag", + "s" + ], + "line": 686, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "Failed to sync ldap entry[], because %s", - "en_US": "Failed to sync ldap entry[], because {0}", - "zh_CN": "", + "raw": "invalid health target[%s], the target checking protocol[%s] is invalid, valid protocols are %s", + "en_US": "invalid health target[{0}], the target checking protocol[{1}] is invalid, valid protocols are {2}", + "zh_CN": "无效的健康检查目标[{0}],目标检查协议无效[{1}],有效的为[{2}]", "arguments": [ - "e.getMessage()" + "systemTag", + "protocol", + "LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCOLS" ], - "line": 352, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 704, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "Failed to sync organizations, because %s", - "en_US": "Failed to sync organizations, because {0}", - "zh_CN": "", + "raw": "invalid invalid health target[%s], port[%s] is not a number", + "en_US": "invalid invalid health target[{0}], port[{1}] is not a number", + "zh_CN": "无效的健康检查目标[{0}],端口[{1}]不是一个数字", "arguments": [ - "reply.getError().getReadableDetails()" + "systemTag", + "port" ], - "line": 975, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 716, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "Failed to transform ldap entry to organization ndoe", - "en_US": "Failed to transform ldap entry to organization ndoe", - "zh_CN": "", - "arguments": [], - "line": 923, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "invalid invalid health target[%s], port[%s] is not in the range of [1, 65535]", + "en_US": "invalid invalid health target[{0}], port[{1}] is not in the range of [1, 65535]", + "zh_CN": "无效的无效健康检查目标[{0}],端口[{1}]不在范围[1, 65535]内", + "arguments": [ + "systemTag", + "port" + ], + "line": 713, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" }, { - "raw": "failed to sync ldap organization", - "en_US": "failed to sync ldap organization", - "zh_CN": "", - "arguments": [], - "line": 912, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "invalid balancer weight for nic:%s, %d is not in the range [%d, %d]", + "en_US": "invalid balancer weight for nic:{0}, {1} is not in the range [{2}, {3}]", + "zh_CN": "无效的网卡:{0}权重值{1},不在有效范围[{2}, {3}]内", + "arguments": [ + "nicUuid", + "weight", + "LoadBalancerConstants.BALANCER_WEIGHT_MIN", + "LoadBalancerConstants.BALANCER_WEIGHT_MAX" + ], + "line": 89, + "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java" }, { - "raw": "Can not sync LDAP/AD server whose scope is not %s", - "en_US": "Can not sync LDAP/AD server whose scope is not {0}", - "zh_CN": "", + "raw": "guest l3Network of vm nic[uuid:%s] and vip l3Network of vip[uuid: %s] are the same network", + "en_US": "guest l3Network of vm nic[uuid:{0}] and vip l3Network of vip[uuid: {1}] are the same network", + "zh_CN": "云主机网卡[uuid:{0}]的客户三层网络和虚拟IP[uuid:{1}]的虚拟IP 三层网络是同一个网络", "arguments": [ - "scope.toString()" + "msg.getVmNicUuid()", + "msg.getVipUuid()" ], - "line": 1380, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 226, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "Failed to validate uid[%s], maybe it has been deleted", - "en_US": "Failed to validate uid[{0}], maybe it has been deleted", - "zh_CN": "", + "raw": "the vip[uuid:%s] has been occupied other network service entity[%s]", + "en_US": "the vip[uuid:{0}] has been occupied other network service entity[{1}]", + "zh_CN": "虚拟IP[uuid:{0}]已经被其他网络服务占用", "arguments": [ - "uid" + "msg.getVipUuid()", + "useForList.toString()" ], - "line": 1503, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 201, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "Failed to create iam2 virtual id for uid[%s], because %s", - "en_US": "Failed to create iam2 virtual id for uid[{0}], because {1}", - "zh_CN": "", + "raw": "Port forwarding rule[uuid:%s] is not in state of Enabled, current state is %s", + "en_US": "Port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1}", + "zh_CN": "端口转发规则[uuid:{0}]未启用,当前状态[{1}]", "arguments": [ - "uid", - "reply.getError().getReadableDetails()" + "msg.getRuleUuid()", + "state" ], - "line": 1544, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 68, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "Failed to validate dn [%s], maybe it has been deleted", - "en_US": "Failed to validate dn [{0}], maybe it has been deleted", - "zh_CN": "", + "raw": "port forwarding rule rule[uuid:%s] has not been attached to any vm nic, can\u0027t detach", + "en_US": "port forwarding rule rule[uuid:{0}] has not been attached to any vm nic, can\u0027t detach", + "zh_CN": "端口转发规则[uuid:{0}]尚未被挂载到任何云主机网卡,无法卸载", "arguments": [ - "ldapUid" + "msg.getUuid()" ], - "line": 1679, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 83, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "invalid json format", - "en_US": "invalid json format", - "zh_CN": "", - "arguments": [], - "line": 2097, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "port forwarding rule[uuid:%s] has been attached to vm nic[uuid:%s], can\u0027t attach again", + "en_US": "port forwarding rule[uuid:{0}] has been attached to vm nic[uuid:{1}], can\u0027t attach again", + "zh_CN": "端口转发规则[uuid:{0}]已经被挂载到云主机网卡[uuid:{1}],无法再次挂载", + "arguments": [ + "msg.getRuleUuid()", + "vmNicUuid" + ], + "line": 99, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "name is mandatory field %", - "en_US": "name is mandatory field %", - "zh_CN": "", - "arguments": [], - "line": 2108, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "port forwarding rule[uuid:%s] is not in state of Enabled, current state is %s. A rule can only be attached when its state is Enabled", + "en_US": "port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1}. A rule can only be attached when its state is Enabled", + "zh_CN": "端口转发规则[uuid:{0}]没有启用,当前状态为{1}。一个规则只能在启用时被挂载", + "arguments": [ + "msg.getRuleUuid()", + "state" + ], + "line": 104, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "attribute is mandatory field %", - "en_US": "attribute is mandatory field %", - "zh_CN": "", - "arguments": [], - "line": 2112, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "guest l3Network of vm nic[uuid:%s] and vip l3Network of port forwarding rule[uuid:%s] are the same network", + "en_US": "guest l3Network of vm nic[uuid:{0}] and vip l3Network of port forwarding rule[uuid:{1}] are the same network", + "zh_CN": "云主机网卡[uuid:{0}]的客户三层网络和端口转发规则[uuid:{1}]的VIP 三层网络是同一个网络", + "arguments": [ + "msg.getVmNicUuid()", + "msg.getRuleUuid()" + ], + "line": 123, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "type is mandatory field %", - "en_US": "type is mandatory field %", - "zh_CN": "", - "arguments": [], - "line": 2116, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "could not create port forwarding rule, because vip port range[vipStartPort:%s, vipEndPort:%s] is incompatible with private port range[privateStartPort:%s, privateEndPort:%s]", + "en_US": "could not create port forwarding rule, because vip port range[vipStartPort:{0}, vipEndPort:{1}] is incompatible with private port range[privateStartPort:{2}, privateEndPort:{3}]", + "zh_CN": "无法创建端口转发规则,因为VIP端口范围[vipStartPort:{0},vipEndPort:{1}]与专用端口范围[PrivateStartPort:[2},PrivateEndPport:{3}]不兼容", + "arguments": [ + "msg.getVipPortStart()", + "msg.getVipPortEnd()", + "msg.getPrivatePortStart()", + "msg.getPrivatePortEnd()" + ], + "line": 167, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "optional is mandatory field %", - "en_US": "optional is mandatory field %", - "zh_CN": "", - "arguments": [], - "line": 2120, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "for range port forwarding, the port range size must match; vip range[%s, %s]\u0027s size doesn\u0027t match range[%s, %s]\u0027s size", + "en_US": "for range port forwarding, the port range size must match; vip range[{0}, {1}]\u0027s size doesn\u0027t match range[{2}, {3}]\u0027s size", + "zh_CN": "对于范围端口转发,端口范围大小必须匹配;VIP范围[{0}, {1}]的大小不匹配范围[{2}, {3}]的大小", + "arguments": [ + "msg.getVipPortStart()", + "msg.getVipPortEnd()", + "msg.getPrivatePortStart()", + "msg.getPrivatePortEnd()" + ], + "line": 184, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "name should use values in %s", - "en_US": "name should use values in {0}", - "zh_CN": "", + "raw": "invalid CIDR[%s], only ipv4 is supported", + "en_US": "invalid CIDR[{0}], only ipv4 is supported", + "zh_CN": "无效的CIDR[{0}],仅支持ipv4", "arguments": [ - "fieldNames" + "msg.getAllowedCidr()" ], - "line": 2124, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 193, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "Invalid attribute. Attribute[%s] is required, but found there are some record not matched", - "en_US": "Invalid attribute. Attribute[{0}] is required, but found there are some record not matched", - "zh_CN": "", + "raw": "invalid CIDR[%s]", + "en_US": "invalid CIDR[{0}]", + "zh_CN": "无效的CIDR[{0}]", "arguments": [ - "rule.getAttribute()" + "msg.getAllowedCidr()" ], - "line": 2150, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "line": 191, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "strategy is mandatory field %", - "en_US": "strategy is mandatory field %", - "zh_CN": "", - "arguments": [], - "line": 2101, - "fileName": "src/main/java/org/zstack/login/LdapLoginManagerImpl.java" + "raw": "vip port range[vipStartPort:%s, vipEndPort:%s] overlaps with rule[uuid:%s, vipStartPort:%s, vipEndPort:%s]", + "en_US": "vip port range[vipStartPort:{0}, vipEndPort:{1}] overlaps with rule[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}]", + "zh_CN": "虚拟IP(vip)端口范围[vipStartPort:{0}, vipEndPort:{1}]与规则[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}]重叠", + "arguments": [ + "vipStart", + "vipEnd", + "vo.getUuid()", + "vo.getVipPortStart()", + "vo.getVipPortEnd()" + ], + "line": 211, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "Invalid rule expression, add access control rule fail because: %s", - "en_US": "Invalid rule expression, add access control rule fail because: {0}", - "zh_CN": "", + "raw": "the VM[name:%s uuid:%s] already has port forwarding rules that have different VIPs than the one[uuid:%s]", + "en_US": "the VM[name:{0} uuid:{1}] already has port forwarding rules that have different VIPs than the one[uuid:{2}]", + "zh_CN": "云主机[name:{0} uuid:{1}]已经有端口转发规则,且与[uuid:{2}]有不同的VIPs", "arguments": [ - "e.getMessage()" + "vm.getName()", + "vm.getUuid()", + "vipUuid" ], - "line": 40, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlApiInterceptor.java" + "line": 269, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "wrong format of password strength config", - "en_US": "wrong format of password strength config", - "zh_CN": "", - "arguments": [], - "line": 154, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "raw": "vmNic uuid[%s] is not allowed add portForwarding with allowedCidr rule, because vmNic exist eip", + "en_US": "vmNic uuid[{0}] is not allowed add portForwarding with allowedCidr rule, because vmNic exist eip", + "zh_CN": "不允许vmnic uuid[{0}]使用AllowedCIDR规则添加PortForwarding,因为vmnic存在EIP", + "arguments": [ + "vmNicUuid" + ], + "line": 282, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "unrecognized key: %s", - "en_US": "unrecognized key: {0}", - "zh_CN": "", + "raw": "could not attach port forwarding rule, because vmNic[uuid:%s] already has a rule that overlaps the target private port ranges[%s, %s], has the same protocol type[%s] and has AllowedCidr", + "en_US": "could not attach port forwarding rule, because vmNic[uuid:{0}] already has a rule that overlaps the target private port ranges[{1}, {2}], has the same protocol type[{3}] and has AllowedCidr", + "zh_CN": "无法挂载端口转发规则,因为云主机网卡[uuid:{0}]已经有与目标规则的云主机端口范围[{1}, {2}]重叠、协议类型[{3}]相同且设置有允许CIDR的规则", "arguments": [ - "key" + "vmNicUuid", + "privatePortStart", + "privatePortEnd", + "protocolType" ], - "line": 143, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "line": 316, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "missing key:value of %s", - "en_US": "missing key:value of {0}", - "zh_CN": "", + "raw": "could not attach port forwarding rule with allowedCidr, because vmNic[uuid:%s] already has rules that overlap the target private port ranges[%s, %s] and have the same protocol type[%s]", + "en_US": "could not attach port forwarding rule with allowedCidr, because vmNic[uuid:{0}] already has rules that overlap the target private port ranges[{1}, {2}] and have the same protocol type[{3}]", + "zh_CN": "无法挂载设置有允许CIDR的端口转发规则,因为云主机网卡[uuid:{0}]已经有与目标规则的云主机端口范围[{1}, {2}]重叠且协议类型[{3}]相同的规则", "arguments": [ - "opt.get()" + "vmNicUuid", + "privatePortStart", + "privatePortEnd", + "protocolType" ], - "line": 149, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "line": 306, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" }, { - "raw": "minimum can not be larger than maximum", - "en_US": "minimum can not be larger than maximum", - "zh_CN": "", - "arguments": [], - "line": 158, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "raw": "port forwarding rule [uuid:%s] is deleted", + "en_US": "port forwarding rule [uuid:{0}] is deleted", + "zh_CN": "端口转发规则[uuid:{0}]已删除", + "arguments": [ + "struct.getRule().getUuid()" + ], + "line": 1222, + "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java" }, { - "raw": "Consult result expect to be 1, but actually %s", - "en_US": "Consult result expect to be 1, but actually {0}", - "zh_CN": "查询结果期望是1,但是实际上是{0}", + "raw": "could not add backend server vmnic to serverGroup[uuid:%s],because vmnic uuid is null", + "en_US": "could not add backend server vmnic to serverGroup[uuid:{0}],because vmnic uuid is null", + "zh_CN": "无法将后端服务器vmnic添加到ServerGroup[uuid:{0}],因为vmnic uuid为空", "arguments": [ - "results.size()" + "msg.getServerGroupUuid()" ], - "line": 321, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "line": 375, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "No available processor for %s", - "en_US": "No available processor for {0}", - "zh_CN": "", + "raw": "could not create slb instance because there is no load balancer slb group [uuid:%s]", + "en_US": "could not create slb instance because there is no load balancer slb group [uuid:{0}]", + "zh_CN": "无法创建SLB实例,因为没有负载平衡器SLB组[uuid:{0}]", "arguments": [ - "msg.getResourceName()" + "msg.getSlbGroupUuid()" ], - "line": 505, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "line": 88, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "can not get suitable captcha with[uuid:%s], related to resourceName[uuid:%s]", - "en_US": "can not get suitable captcha with[uuid:{0}], related to resourceName[uuid:{1}]", - "zh_CN": "找不到和名称[uuid:{1}]对应的验证码[uuid:{0}]", + "raw": "could not create slb instance because there is no slb offering configured for slb group [uuid:%s]", + "en_US": "could not create slb instance because there is no slb offering configured for slb group [uuid:{0}]", + "zh_CN": "无法创建SLB实例,因为没有为SLB组[uuid:{0}]配置SLB产品", "arguments": [ - "msg.getCaptchaUuid()", - "msg.getResourceName()" + "msg.getSlbGroupUuid()" ], - "line": 529, - "fileName": "src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java" + "line": 93, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "%s is not an API", - "en_US": "{0} is not an API", - "zh_CN": "{0}不是一个API", + "raw": "could not create slb instance because image uuid of slb offering [uuid:%s] is null", + "en_US": "could not create slb instance because image uuid of slb offering [uuid:{0}] is null", + "zh_CN": "无法创建SLB实例,因为SLB产品[uuid:{0}]的镜像uuid为空", "arguments": [ - "msg.getJobName()" + "msg.getSlbGroupUuid()" ], - "line": 69, - "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + "line": 99, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "cannot cancel longjob that is succeeded", - "en_US": "cannot cancel longjob that is succeeded", - "zh_CN": "不能取消已经成功的longjob", - "arguments": [], - "line": 127, - "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + "raw": "could not create slb instance because image [uuid:%s] is deleted", + "en_US": "could not create slb instance because image [uuid:{0}] is deleted", + "zh_CN": "无法创建SLB实例,因为镜像[uuid:{0}]已删除", + "arguments": [ + "slbOfferingVO.getImageUuid()" + ], + "line": 104, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "cannot cancel longjob that is failed", - "en_US": "cannot cancel longjob that is failed", - "zh_CN": "不能取消已经失败的longjob", - "arguments": [], - "line": 130, - "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + "raw": "could not create slb group because invalid front l3 network type %s", + "en_US": "could not create slb group because invalid front l3 network type {0}", + "zh_CN": "无法创建SLB组,因为前端三层网络类型{0}无效", + "arguments": [ + "frontL3.getCategory()" + ], + "line": 112, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "delete longjob only when it\u0027s succeeded, canceled, or failed", - "en_US": "delete longjob only when it\u0027s succeeded, canceled, or failed", - "zh_CN": "只能删除已经成功、取消、失败的longjob", + "raw": "could not create slb group, because front network doesn\u0027t support ipv6 yet", + "en_US": "could not create slb group, because front network doesn\u0027t support ipv6 yet", + "zh_CN": "无法创建SLB组,因为前端网络尚不支持IPv6", "arguments": [], - "line": 141, - "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" - }, - { - "raw": "rerun longjob only when it\u0027s succeeded, canceled, or failed", - "en_US": "rerun longjob only when it\u0027s succeeded, canceled, or failed", - "zh_CN": "", + "line": 127, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" + }, + { + "raw": "could not create slb group, because backend network doesn\u0027t support ipv6 yet", + "en_US": "could not create slb group, because backend network doesn\u0027t support ipv6 yet", + "zh_CN": "无法创建SLB组,因为后端网络尚不支持IPv6", "arguments": [], - "line": 152, - "fileName": "src/main/java/org/zstack/longjob/LongJobApiInterceptor.java" + "line": 142, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "%s has no corresponding longjob", - "en_US": "{0} has no corresponding longjob", - "zh_CN": "{0}没有与之对应的longjob", + "raw": "could not change resource owner, because the resource[uuid:%s, type:VmInstance] has already attached security group", + "en_US": "could not change resource owner, because the resource[uuid:{0}, type:VmInstance] has already attached security group", + "zh_CN": "无法更改资源所有者,因为资源[uuid:{0}, 类型:VmInstance] 已加载安全组", "arguments": [ - "jobName" + "msg.getResourceUuid()" ], - "line": 31, - "fileName": "src/main/java/org/zstack/longjob/LongJobFactoryImpl.java" + "line": 143, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "unable to attach a L3 network. The cidr of l3[%s] to attach overlapped with l3[%s] already attached to vm", - "en_US": "unable to attach a L3 network. The cidr of l3[{0}] to attach overlapped with l3[{1}] already attached to vm", - "zh_CN": "不能绑定这个三层网络。这个虚拟机上已经绑定的三层网络[{1}]和这个三层网络[{0}]的CIDR存在重叠", + "raw": "could no set vm nic security group, because vm nic[uuid:%s] not found", + "en_US": "could no set vm nic security group, because vm nic[uuid:{0}] not found", + "zh_CN": "无法设置VM NIC安全组,因为找不到VM NIC[uuid:{0}]", "arguments": [ - "l3NetworkUuid", - "vmNicVO.getL3NetworkUuid()" + "msg.getVmNicUuid()" ], - "line": 109, - "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" + "line": 250, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the vm[name:%s, uuid:%s] already has some port forwarding rules%s attached", - "en_US": "the vm[name:{0}, uuid:{1}] already has some port forwarding rules{2} attached", - "zh_CN": "云主机[name:{0}, uuid:{1}] 已经设置了一些端口转发规则{2}", + "raw": "could no set vm nic security group, because the vm nic[uuid:%s] not attached to any security group", + "en_US": "could no set vm nic security group, because the vm nic[uuid:{0}] not attached to any security group", + "zh_CN": "无法设置VM NIC安全组,因为VM NIC[uuid:{0}]未挂载到任何安全组", "arguments": [ - "vm.getName()", - "vm.getUuid()", - "StringUtils.join(pfStr, \",\")" + "msg.getVmNicUuid()" ], - "line": 141, - "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" + "line": 256, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the vm[name:%s, uuid:%s] already has some EIPs%s attached", - "en_US": "the vm[name:{0}, uuid:{1}] already has some EIPs{2} attached", - "zh_CN": "云主机[name:{0}, uuid:{1}] 已经配置了弹性IP{2}", + "raw": "could no set vm nic security group, because security group[uuid:%s] not found", + "en_US": "could no set vm nic security group, because security group[uuid:{0}] not found", + "zh_CN": "无法设置VM NIC安全组,因为找不到安全组[uuid:{0}]", "arguments": [ - "vm.getName()", - "vm.getUuid()", - "StringUtils.join(eipStr, \",\")" + "ao.getSecurityGroupUuid()" ], - "line": 162, - "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" + "line": 266, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the vip[uuid:%s] already has bound to other service[%s]", - "en_US": "the vip[uuid:{0}] already has bound to other service[{1}]", - "zh_CN": "该虚拟IP[uuid:{0}]已经绑定了其他服务", + "raw": "could no set vm nic security group, because invalid priority, priority[%d] cannot be less than 1", + "en_US": "could no set vm nic security group, because invalid priority, priority[{0}] cannot be less than 1", + "zh_CN": "无法设置VM NIC安全组,因为优先级无效,优先级[{0}]不能小于1", "arguments": [ - "msg.getVipUuid()", - "useForList.toString()" + "priority" ], - "line": 177, - "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" + "line": 271, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Current port range[%s, %s] is conflicted with used port range [%s, %s] with vip[uuid: %s] protocol: %s ", - "en_US": "Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} ", - "zh_CN": "当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的端口范围[{2}, {3}]冲突", + "raw": "could no set vm nic security group, because duplicate priority, both security group %s and %s have priority[%d]", + "en_US": "could no set vm nic security group, because duplicate priority, both security group {0} and {1} have priority[{2}]", + "zh_CN": "无法设置VM NIC安全组,因为优先级重复,安全组{0}和{1}都具有相同的优先级[{2}]", "arguments": [ - "Long.toString(range.getStart())", - "Long.toString(range.getEnd())", - "Long.toString(cur.getStart())", - "Long.toString(cur.getEnd())", - "vipUuid", - "protocol" + "aoMap.get(priority)", + "ao.getSecurityGroupUuid()", + "priority" ], - "line": 213, - "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" + "line": 275, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Current port range[%s, %s] is conflicted with system service port range [%s, %s] with vip[uuid: %s] protocol: %s ", - "en_US": "Current port range[{0}, {1}] is conflicted with system service port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} ", - "zh_CN": "当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的系统服务端口范围[{2}, {3}]冲突", + "raw": "could no set vm nic security group, because duplicate security group[uuid:%s]", + "en_US": "could no set vm nic security group, because duplicate security group[uuid:{0}]", + "zh_CN": "无法设置VM NIC安全组,因为安全组[uuid:{0}]重复", "arguments": [ - "Long.toString(range.getStart())", - "Long.toString(range.getEnd())", - "Long.toString(cur.getStart())", - "Long.toString(cur.getEnd())", - "vipUuid", - "protocol" + "ao.getSecurityGroupUuid()" ], - "line": 225, - "fileName": "src/main/java/org/zstack/mediator/ApiValidator.java" + "line": 278, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "L3 network[uuid:%s] not found. Please correct your system tag[%s] of static IP", - "en_US": "L3 network[uuid:{0}] not found. Please correct your system tag[{1}] of static IP", - "zh_CN": "找不到L3网络[uuid:0]。请确认静态IP的系统标签", + "raw": "could no set vm nic security group, because security group[uuid:%s] is not owned by account[uuid:%s] or admin", + "en_US": "could no set vm nic security group, because security group[uuid:{0}] is not owned by account[uuid:{1}] or admin", + "zh_CN": "无法设置 VM NIC 安全组,因为安全组 [uuid:{0}] 不属于帐户[uuid:{1}] 或管理员", "arguments": [ - "l3Uuid", - "systemTag" + "ao.getSecurityGroupUuid()", + "vmAccountUuid" ], - "line": 772, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 288, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "for shareable volume, the only supported primary storage type is %s, current is %s", - "en_US": "for shareable volume, the only supported primary storage type is {0}, current is {1}", - "zh_CN": "共享云盘仅支持在主存储类型为{0}的主存储上使用,当前的类型为{1}", + "raw": "could no set vm nic security group, because invalid priority, priority expects to start at 1, but [%d]", + "en_US": "could no set vm nic security group, because invalid priority, priority expects to start at 1, but [{0}]", + "zh_CN": "无法设置VM NIC安全组,因为优先级无效,优先级应从1开始,而不是[{0}]", "arguments": [ - "supportSharedVolumePrimaryStorage", - "psType" + "priorities[0]" ], - "line": 304, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 298, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume bandwidth[%s] is larger than %d", - "en_US": "invalid volume bandwidth[{0}] is larger than {1}", - "zh_CN": "云盘带宽[{0}]大于{1}是无效的", + "raw": "could no set vm nic security group, because invalid priority, priority[%d] and priority[%d] expected to be consecutive", + "en_US": "could no set vm nic security group, because invalid priority, priority[{0}] and priority[{1}] expected to be consecutive", + "zh_CN": "无法设置VM NIC安全组,因为优先级无效,优先级[{0}]和优先级[{1}]应是连续的", "arguments": [ - "bandwidth", - "Long.MAX_VALUE" + "priorities[i]", + "priorities[i + 1]" ], - "line": 734, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 302, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume bandwidth[%s] is not a number", - "en_US": "invalid volume bandwidth[{0}] is not a number", - "zh_CN": "错误的云盘带宽 ,[{0}] 这个不是数字", + "raw": "could no set vm nic security group, because admin security group priority[%d] must be higher than users", + "en_US": "could no set vm nic security group, because admin security group priority[{0}] must be higher than users", + "zh_CN": "无法设置VM NIC安全组,因为管理员安全组优先级[{0}]必须高于用户安全组", "arguments": [ - "bandwidth" + "priorities[i + 1]" ], - "line": 732, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 348, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume bandwidth[%s], it must be greater than 1024 (include 1024)", - "en_US": "invalid volume bandwidth[{0}], it must be greater than 1024 (include 1024)", - "zh_CN": "无效的云盘带宽,它必须大于等于1M", - "arguments": [ - "bandwidth" - ], - "line": 729, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could no change security group rule state, because ruleUuids is empty", + "en_US": "could no change security group rule state, because ruleUuids is empty", + "zh_CN": "无法更改安全组规则状态,因为RuleUIds为空", + "arguments": [], + "line": 357, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume IOPS[%s] is not a number", - "en_US": "invalid volume IOPS[{0}] is not a number", - "zh_CN": "错误的云盘每秒读写速度[{0}],它应该是个数字", + "raw": "could no change security group rule state, because security group[uuid:%s] not found", + "en_US": "could no change security group rule state, because security group[uuid:{0}] not found", + "zh_CN": "无法更改安全组规则状态,因为找不到安全组[uuid:{0}]", "arguments": [ - "bandwidth" + "msg.getSecurityGroupUuid()" ], - "line": 753, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 361, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume IOPS[%s] is larger than %d", - "en_US": "invalid volume IOPS[{0}] is larger than {1}", - "zh_CN": "云盘IOPS[{0}]大于{1}是无效的", + "raw": "could no change security group rule state, because security group rule[uuid:%s] not found", + "en_US": "could no change security group rule state, because security group rule[uuid:{0}] not found", + "zh_CN": "无法更改安全组规则状态,因为找不到安全组规则[uuid:{0}]", "arguments": [ - "bandwidth", - "Long.MAX_VALUE" + "r" ], - "line": 755, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 369, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume IOPS[%s], it must be greater than 0", - "en_US": "invalid volume IOPS[{0}], it must be greater than 0", - "zh_CN": "错误的云盘每秒读写速度[{0}],它应该大于0", - "arguments": [ - "bandwidth" - ], - "line": 750, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could no change security group rule state, because no security group rule state need to change", + "en_US": "could no change security group rule state, because no security group rule state need to change", + "zh_CN": "无法更改安全组规则状态,因为没有安全组规则需要修改状态", + "arguments": [], + "line": 378, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Unknown code[%s] of Security Level", - "en_US": "Unknown code[{0}] of Security Level", - "zh_CN": "", + "raw": "could no change vm nic security policy, because ingress policy and egress policy cannot be both null", + "en_US": "could no change vm nic security policy, because ingress policy and egress policy cannot be both null", + "zh_CN": "无法更改VM NIC安全策略,因为入口策略和出口策略不能同时为空", + "arguments": [], + "line": 386, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "could no change vm nic security policy, because invalid ingress policy[%s]", + "en_US": "could no change vm nic security policy, because invalid ingress policy[{0}]", + "zh_CN": "无法更改VM NIC安全策略,因为入口策略[{0}]无效", "arguments": [ - "level" + "msg.getIngressPolicy()" ], - "line": 810, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 389, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "[%s] is not a standard cidr", - "en_US": "[{0}] is not a standard cidr", - "zh_CN": "", + "raw": "could no change vm nic security policy, because invalid egress policy[%s]", + "en_US": "could no change vm nic security policy, because invalid egress policy[{0}]", + "zh_CN": "无法更改VM NIC安全策略,因为出口策略[{0}]无效", "arguments": [ - "cidr" + "msg.getEgressPolicy()" ], - "line": 832, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 393, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the host[uuid:%s]\u0027s operating system %s %s is too old, the QEMU doesn\u0027t support QoS of network or disk IO. Please choose another instance offering with no QoS configuration", - "en_US": "the host[uuid:{0}]\u0027s operating system {1} {2} is too old, the QEMU doesn\u0027t support QoS of network or disk IO. Please choose another instance offering with no QoS configuration", - "zh_CN": "物理机[uuid:{0}] 的操作系统{1} {2} 过老, QEMU 不支持云盘的QOS IO设置 。 请选择别的没有Qos的计算规格", + "raw": "could no change vm nic security policy, because vm nic[uuid:%s] not found", + "en_US": "could no change vm nic security policy, because vm nic[uuid:{0}] not found", + "zh_CN": "无法更改VM NIC安全策略,因为找不到VM NIC[uuid:{0}]", "arguments": [ - "hostUuid", - "distro", - "version" + "msg.getVmNicUuid()" ], - "line": 849, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 397, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid value[%s], it\u0027s not a double", - "en_US": "invalid value[{0}], it\u0027s not a double", - "zh_CN": "错误的值[{0}],这个不是双精度值", + "raw": "could no change vm nic security policy, because vm nic[uuid:%s] has no security policy", + "en_US": "could no change vm nic security policy, because vm nic[uuid:{0}] has no security policy", + "zh_CN": "无法更改VM NIC安全策略,因为VM NIC[uuid:{0}]没有安全策略", "arguments": [ - "newValue" + "msg.getVmNicUuid()" ], - "line": 1082, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 402, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid value[%s], it must be a double greater than 0", - "en_US": "invalid value[{0}], it must be a double greater than 0", - "zh_CN": "错误的值[{0}],必须是一个大于0的双精度值", + "raw": "could not update security group rule priority, because invalid type[%s]", + "en_US": "could not update security group rule priority, because invalid type[{0}]", + "zh_CN": "无法更新安全组规则优先级,因为类型[{0}]无效", "arguments": [ - "newValue" + "msg.getType()" ], - "line": 1050, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 416, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid value[%s], it must be a double between (0, 1]", - "en_US": "invalid value[{0}], it must be a double between (0, 1]", - "zh_CN": "错误的值[{0}],这个必须在0~1之间的双精度值", + "raw": "could not update security group rule priority, because security group[uuid:%s] is not exist", + "en_US": "could not update security group rule priority, because security group[uuid:{0}] is not exist", + "zh_CN": "无法更新安全组规则优先级,因为安全组[uuid:{0}]不存在", "arguments": [ - "newValue" + "msg.getSecurityGroupUuid()" ], - "line": 1079, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 421, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid value[%s], ZStack doesn\u0027t have such host allocator type", - "en_US": "invalid value[{0}], ZStack doesn\u0027t have such host allocator type", - "zh_CN": "错误值[{0}],Zstack没有这样的分配器类型", + "raw": "could not update security group rule priority, because rules is empty", + "en_US": "could not update security group rule priority, because rules is empty", + "zh_CN": "无法更新安全组规则优先级,因为规则为空", + "arguments": [], + "line": 425, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "could not update security group rule priority, because security group[uuid:%s] rules size not match", + "en_US": "could not update security group rule priority, because security group[uuid:{0}] rules size not match", + "zh_CN": "无法更新安全组规则优先级,因为安全组[uuid:{0}]规则大小不匹配", "arguments": [ - "newValue" + "msg.getSecurityGroupUuid()" ], - "line": 1093, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 435, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "%s value is[%s], which is conflict with %s value [%s]", - "en_US": "{0} value is[{1}], which is conflict with {2} value [{3}]", - "zh_CN": "", + "raw": "could not update security group rule priority, because rule priority[%d] is invalid", + "en_US": "could not update security group rule priority, because rule priority[{0}] is invalid", + "zh_CN": "无法更新安全组规则优先级,因为规则优先级[{0}]无效", "arguments": [ - "MevocoGlobalConfig.AIO_NATIVE.getCanonicalName()", - "MevocoGlobalConfig.AIO_NATIVE.value()", - "KVMGlobalConfig.LIBVIRT_CACHE_MODE.getCanonicalName()", - "KVMGlobalConfig.LIBVIRT_CACHE_MODE.value()" + "ao.getPriority()" ], - "line": 1115, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 440, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "obj is not instanceof NicQos!", - "en_US": "obj is not instanceof NicQos!", - "zh_CN": "", - "arguments": [], - "line": 1371, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not update security group rule priority, because priority[%d] has duplicate", + "en_US": "could not update security group rule priority, because priority[{0}] has duplicate", + "zh_CN": "无法更新安全组规则优先级,因为优先级[{0}]重复", + "arguments": [ + "ao.getPriority()" + ], + "line": 443, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "unexpected host management IPs: [%s]", - "en_US": "unexpected host management IPs: [{0}]", - "zh_CN": "", + "raw": "could not update security group rule priority, because rule[uuid:%s] not in security group[uuid:%s]", + "en_US": "could not update security group rule priority, because rule[uuid:{0}] not in security group[uuid:{1}]", + "zh_CN": "无法更新安全组规则优先级,因为规则[uuid:{0}]不在安全组[uuid:{1}]中", "arguments": [ - "String.join(\",\", ips)" + "ao.getRuleUuid()", + "msg.getSecurityGroupUuid()" ], - "line": 1732, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 449, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not set local and configure at same time", - "en_US": "can not set local and configure at same time", - "zh_CN": "", - "arguments": [], - "line": 1864, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not update security group rule priority, because priority[%d] not in security group[uuid:%s]", + "en_US": "could not update security group rule priority, because priority[{0}] not in security group[uuid:{1}]", + "zh_CN": "无法更新安全组规则优先级,因为优先级[{0}]不在安全组[uuid:{1}]中", + "arguments": [ + "ao.getPriority()", + "msg.getSecurityGroupUuid()" + ], + "line": 452, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not find node A config info", - "en_US": "can not find node A config info", - "zh_CN": "", + "raw": "could not update security group rule priority, because rule uuid duplicate", + "en_US": "could not update security group rule priority, because rule uuid duplicate", + "zh_CN": "无法更新安全组规则优先级,因为规则uuid重复", "arguments": [], - "line": 1916, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 457, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not find node A address info from bootstrap agent", - "en_US": "can not find node A address info from bootstrap agent", - "zh_CN": "", - "arguments": [], - "line": 1926, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not change security group rule, because security group rule uuid[%s] is not exist", + "en_US": "could not change security group rule, because security group rule uuid[{0}] is not exist", + "zh_CN": "无法更改安全组规则,因为安全组规则uuid[{0}]不存在", + "arguments": [ + "msg.getUuid()" + ], + "line": 464, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not get bootstrap job %s result after 900s", - "en_US": "can not get bootstrap job {0} result after 900s", - "zh_CN": "", + "raw": "could not change security group rule, because security group rule[%s] is default rule, only the description and status can be set", + "en_US": "could not change security group rule, because security group rule[{0}] is default rule, only the description and status can be set", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]是默认规则,只能设置描述和状态", "arguments": [ - "s.getJobUuid()" + "msg.getUuid()" ], - "line": 1987, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 470, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "curl bootstrap agent finished, return code: %s, stdout: %s, stderr: %s", - "en_US": "curl bootstrap agent finished, return code: {0}, stdout: {1}, stderr: {2}", - "zh_CN": "", + "raw": "could not change security group rule, because security group rule[%s] priority cannot be set to default rule priority[%d]", + "en_US": "could not change security group rule, because security group rule[{0}] priority cannot be set to default rule priority[{1}]", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]优先级无法设置为默认规则优先级[{1}]", "arguments": [ - "ret.getRetCode()", - "ret.getStdout()", - "ret.getStderr()" + "msg.getUuid()", + "SecurityGroupConstant.DEFAULT_RULE_PRIORITY" ], - "line": 1995, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 476, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "node A update factory mode failed, details: %s", - "en_US": "node A update factory mode failed, details: {0}", - "zh_CN": "", + "raw": "could not change security group rule, because security group %s rules number[%d] is out of max limit[%d]", + "en_US": "could not change security group rule, because security group {0} rules number[{1}] is out of max limit[{2}]", + "zh_CN": "无法更改安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}]", "arguments": [ - "errorOfNodeA.getCauses().get(0)" + "vo.getType()", + "count.intValue()", + "SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)" ], - "line": 2459, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 485, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "all management node update factory mode failed, details: %s", - "en_US": "all management node update factory mode failed, details: {0}", - "zh_CN": "", + "raw": "could not change security group rule, because the maximum priority of %s rule is [%d]", + "en_US": "could not change security group rule, because the maximum priority of {0} rule is [{1}]", + "zh_CN": "无法更改安全组规则,因为{0}规则的最高优先级为[{1}]", "arguments": [ - "errorCodeList.getCauses().get(0)" + "vo.getType().toString()", + "count.intValue()" ], - "line": 2457, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 488, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "management node status is not %s", - "en_US": "management node status is not {0}", - "zh_CN": "", + "raw": "could not change security group rule, because invalid state[%s]", + "en_US": "could not change security group rule, because invalid state[{0}]", + "zh_CN": "无法更改安全组规则,因为状态[{0}]无效", "arguments": [ - "ManagementNodeState.RUNNING" + "msg.getState()" ], - "line": 2566, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 497, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "some node on factory mode exists, detail of arping: %s", - "en_US": "some node on factory mode exists, detail of arping: {0}", - "zh_CN": "", + "raw": "could not change security group rule, because invalid action[%s]", + "en_US": "could not change security group rule, because invalid action[{0}]", + "zh_CN": "无法更改安全组规则,因为协议[{0}]无效", "arguments": [ - "r.getStdout()" + "msg.getAction()" ], - "line": 2493, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 505, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "set address on node A failed", - "en_US": "set address on node A failed", - "zh_CN": "", - "arguments": [], - "line": 2514, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not change security group rule, because invalid protocol[%s]", + "en_US": "could not change security group rule, because invalid protocol[{0}]", + "zh_CN": "无法更改安全组规则,因为协议[{0}]无效", + "arguments": [ + "msg.getProtocol()" + ], + "line": 513, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "this node is not node A", - "en_US": "this node is not node A", - "zh_CN": "", - "arguments": [], - "line": 2511, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not change security group rule, because security group rule[%s] type is Egress, srcIpRange[%s] cannot be set", + "en_US": "could not change security group rule, because security group rule[{0}] type is Egress, srcIpRange[{1}] cannot be set", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]类型为出口,无法设置SrcIPRange[{1}]", + "arguments": [ + "msg.getUuid()", + "msg.getSrcIpRange()" + ], + "line": 545, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "networkInboundBandwidth format error %s", - "en_US": "networkInboundBandwidth format error {0}", - "zh_CN": "下行网络带宽格式错误{0}", + "raw": "could not change security group rule, because security group rule[%s] type is Ingress, dstIpRange[%s] cannot be set", + "en_US": "could not change security group rule, because security group rule[{0}] type is Ingress, dstIpRange[{1}] cannot be set", + "zh_CN": "无法更改安全组规则,因为安全组规则[{0}]类型为入口,无法设置dstIpRange[{1}]", "arguments": [ - "bandwidth" + "msg.getUuid()", + "msg.getDstIpRange()" ], - "line": 2651, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 542, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "networkOutboundBandwidth format error %s", - "en_US": "networkOutboundBandwidth format error {0}", - "zh_CN": "上行网络带宽超格式错误{0}", + "raw": "could not change security group rule, because srcIpRange[%s] is set, remoteSecurityGroupUuid[%s] must be empty", + "en_US": "could not change security group rule, because srcIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty", + "zh_CN": "无法更改安全组规则,因为已设置SrcIPRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空", "arguments": [ - "bandwidth" + "msg.getSrcIpRange()", + "msg.getRemoteSecurityGroupUuid()" ], - "line": 2663, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 535, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "networkOutboundBandwidth execeds the max value 32G bps", - "en_US": "networkOutboundBandwidth execeds the max value 32G bps", - "zh_CN": "超过上行网络带宽超过最大值32G bps", - "arguments": [], - "line": 2660, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not change security group rule, because dstIpRange[%s] is set, remoteSecurityGroupUuid[%s] must be empty", + "en_US": "could not change security group rule, because dstIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty", + "zh_CN": "无法更改安全组规则,因为已设置dstIpRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空", + "arguments": [ + "msg.getDstIpRange()", + "msg.getRemoteSecurityGroupUuid()" + ], + "line": 548, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Shareable Volume[uuid:%s] has already been attached to VM[uuid:%s]", - "en_US": "Shareable Volume[uuid:{0}] has already been attached to VM[uuid:{1}]", - "zh_CN": "共享云盘[uuid:{0}]已经挂载到云主机[uuid:{1}]上", + "raw": "could not change security group rule, because remote security group[uuid:%s] not found", + "en_US": "could not change security group rule, because remote security group[uuid:{0}] not found", + "zh_CN": "无法更改安全组规则,因为找不到远程安全组[uuid:{0}]", "arguments": [ - "volume.getUuid()", - "vm.getUuid()" + "msg.getRemoteSecurityGroupUuid()" ], - "line": 2855, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 555, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "shareable disk only support virtio-scsi type for now", - "en_US": "shareable disk only support virtio-scsi type for now", - "zh_CN": "目前共享盘只支持virtio-scsi", - "arguments": [], - "line": 2873, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "raw": "could not change security group rule, because remote security group[uuid:%s] is set, srcIpRange and dstIpRange must be empty", + "en_US": "could not change security group rule, because remote security group[uuid:{0}] is set, srcIpRange and dstIpRange must be empty", + "zh_CN": "无法更改安全组规则,因为已设置远端安全组[uuid:{0}],SrcIPRange和DstIPRange必须为空", + "arguments": [ + "msg.getRemoteSecurityGroupUuid()" + ], + "line": 558, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "shareable volume(s)[uuid: %s] attached, not support to group snapshot.", - "en_US": "shareable volume(s)[uuid: {0}] attached, not support to group snapshot.", - "zh_CN": "", + "raw": "could not change security group rule, because rule protocol is [%s], dstPortRange must be set", + "en_US": "could not change security group rule, because rule protocol is [{0}], dstPortRange must be set", + "zh_CN": "无法更改安全组规则,因为规则协议为[{0}],必须设置dstPortRange", "arguments": [ - "sharedVolUuids" + "msg.getProtocol()" ], - "line": 3279, - "fileName": "src/main/java/org/zstack/mevoco/MevocoManagerImpl.java" + "line": 611, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "How can a Running VM[uuid:%s] has no hostUuid?", - "en_US": "How can a Running VM[uuid:{0}] has no hostUuid?", - "zh_CN": "", + "raw": "could not change security group rule, because rule protocol is [%s], dstPortRange cannot be empty", + "en_US": "could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be empty", + "zh_CN": "无法更改安全组规则,因为规则协议为[{0}],dstPortRange不能为空", "arguments": [ - "vmInstanceVO.getUuid()" + "msg.getProtocol()" ], - "line": 331, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 603, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "Unexpectedly, VM[uuid:%s] is not running any more, please try again later", - "en_US": "Unexpectedly, VM[uuid:{0}] is not running any more, please try again later", - "zh_CN": "", + "raw": "could not change security group rule, because rule protocol is [%s], dstPortRange cannot be set", + "en_US": "could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be set", + "zh_CN": "无法更改安全组规则,因为规则协议为[{0}],无法设置dstPortRange", "arguments": [ - "vmInstanceVO.getUuid()" + "msg.getProtocol()" ], - "line": 329, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 598, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not take snapshot for volumes[%s] while volume[uuid: %s] not attached", - "en_US": "can not take snapshot for volumes[{0}] while volume[uuid: {1}] not attached", - "zh_CN": "当云盘[uuid:{1}]未加载时,无法给云盘[{0}]创建快照", + "raw": "could not change security group rule, because rule[%s] is duplicated to rule[uuid:%s] in datebase", + "en_US": "could not change security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase", + "zh_CN": "无法更改安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复", "arguments": [ - "msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList())", - "job.getVolumeUuid()" + "JSONObjectUtil.toJsonString(sao)", + "o.getUuid()" ], - "line": 719, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 642, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "can not take snapshot for volumes[%s] while volume[uuid: %s] appears twice", - "en_US": "can not take snapshot for volumes[{0}] while volume[uuid: {1}] appears twice", - "zh_CN": "当云盘[uuid:{1}]出现多次时,无法给云盘[{0}]创建快照", + "raw": "could not execute the api operation. backend network [uuid:%s] cidr [%s] is overlapped with frond l3 network[uuid:%s] cidr [%s]", + "en_US": "could not execute the api operation. backend network [uuid:{0}] cidr [{1}] is overlapped with frond l3 network[uuid:{2}] cidr [{3}]", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]CIDR[{1}]与前端三层网络[uuid:{2}]CIDR[{3}]重叠", "arguments": [ - "msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList())", - "job.getVolumeUuid()" + "uuid", + "backendL3Cidr", + "frontL3Uuid", + "frontL3Cidr" ], - "line": 725, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 145, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "can not take snapshot for volumes[%s] attached multiple vms[%s, %s]", - "en_US": "can not take snapshot for volumes[{0}] attached multiple vms[{1}, {2}]", - "zh_CN": "当云盘[uuid:{1}]加载到多个虚拟机上时,无法给云盘[{0}]创建快照", + "raw": "could not execute the api operation. backend network [uuid:%s] can not be vpc network because other backend network is not vpc network", + "en_US": "could not execute the api operation. backend network [uuid:{0}] can not be vpc network because other backend network is not vpc network", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]不能是VPC网络,因为其他后端网络不是VPC网络", "arguments": [ - "msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList())", - "job.getVolumeUuid()", - "volumeVOS.get(0).getVmInstanceUuid()" + "uuid" ], - "line": 732, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 768, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "no volumes found", - "en_US": "no volumes found", - "zh_CN": "找不到云盘", + "raw": "can\u0027t delete rules of different security group", + "en_US": "can\u0027t delete rules of different security group", + "zh_CN": "无法删除不同安全组的规则", "arguments": [], - "line": 739, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 804, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "this snapshot recording the volume state before resize to %fG is created automatically", - "en_US": "this snapshot recording the volume state before resize to {0}G is created automatically", - "zh_CN": "该快照记录云盘扩容到{0}G之前的状态,由系统自动创建", + "raw": "can\u0027t delete default rule[uuid:%s]", + "en_US": "can\u0027t delete default rule[uuid:{0}]", + "zh_CN": "无法删除默认规则[uuid:{0}]", "arguments": [ - "SizeUnit.BYTE.toGigaByte((double) resize)" + "vo.getUuid()" ], - "line": 971, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 807, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "DeleteVolumeQos [%s] ingor because of account privilege.", - "en_US": "DeleteVolumeQos [{0}] ingor because of account privilege.", - "zh_CN": "", + "raw": "could not execute the api operation. backend network [uuid:%s] is not connected vpc router", + "en_US": "could not execute the api operation. backend network [uuid:{0}] is not connected vpc router", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]未连接到VPC路由器", "arguments": [ - "msg.getUuid()" + "uuid" ], - "line": 1238, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 170, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Cannot delete vm\u0027s volume qos on host %s, because the current vm is in state of %s, but support expect states are [%s, %s]", - "en_US": "Cannot delete vm\u0027s volume qos on host {0}, because the current vm is in state of {1}, but support expect states are [{2}, {3}]", - "zh_CN": "", + "raw": "could not execute the api operation. backend network [uuid:%s] is connected vpc router [uuid:%s] which is not connect to front network[uuid:%s]", + "en_US": "could not execute the api operation. backend network [uuid:{0}] is connected vpc router [uuid:{1}] which is not connect to front network[uuid:{2}]", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]连接了VPC路由器[uuid:{1}],而该路由器未连接到前端网络[uuid:{2}]", "arguments": [ - "ivo.getHostUuid()", - "ivo.getState()", - "VmInstanceState.Running.toString()", - "VmInstanceState.Stopped.toString()" + "backendL3Uuids.get(0)", + "firstBackendVrUuids.get(0)", + "frontL3Uuid" ], - "line": 1270, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 835, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "non admin account cannot set bandwidth more than %s", - "en_US": "non admin account cannot set bandwidth more than {0}", - "zh_CN": "", + "raw": "VM nics[uuids:%s] are not on L3 networks that have been attached to the security group[uuid:%s]", + "en_US": "VM nics[uuids:{0}] are not on L3 networks that have been attached to the security group[uuid:{1}]", + "zh_CN": "云物理机网卡[uuids:{0}]不在安全组[uuid:{1}]挂载的L3网络上", "arguments": [ - "VolumeQos.getVolumeQosByMode(self.getVolumeQos(), msg.getMode())" + "wrongUuids", + "securityGroupUuid" ], - "line": 1428, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 897, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "volume [%s] isn\u0027t attached to any vm, cannot get qos by forceSync", - "en_US": "volume [{0}] isn\u0027t attached to any vm, cannot get qos by forceSync", - "zh_CN": "", + "raw": "could not add security group rule, because security group[uuid:%s] does not exist", + "en_US": "could not add security group rule, because security group[uuid:{0}] does not exist", + "zh_CN": "无法添加安全组规则,因为安全组[uuid:{0}]不存在", "arguments": [ - "self.getUuid()" + "uuid" ], - "line": 1469, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 933, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "volume [%s] isn\u0027t attached to any vm (or vm is not existed now), cannot sync volume qos", - "en_US": "volume [{0}] isn\u0027t attached to any vm (or vm is not existed now), cannot sync volume qos", - "zh_CN": "", + "raw": "could not add security group rule, because the rules cannot be empty or exceed the max number %d", + "en_US": "could not add security group rule, because the rules cannot be empty or exceed the max number {0}", + "zh_CN": "无法添加安全组规则,因为规则不能为空或超过最大数量{0}", "arguments": [ - "self.getUuid()" + "SecurityGroupConstant.ONE_API_RULES_MAX_NUM" ], - "line": 1475, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 922, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "vm [%s]\u0027 state must be Running or Paused to sync volume qos", - "en_US": "vm [{0}]\u0027 state must be Running or Paused to sync volume qos", - "zh_CN": "", + "raw": "could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: %s", + "en_US": "could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: {0}", + "zh_CN": "无法添加安全组规则,因为RemoteSecurityGroupuuid中存在重复的uuid:{0}", "arguments": [ - "vm.getUuid()" + "msg.getRemoteSecurityGroupUuids()" ], - "line": 1480, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 927, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "vm [%s]\u0027s HostUuid is null, cannot sync volume qos", - "en_US": "vm [{0}]\u0027s HostUuid is null, cannot sync volume qos", - "zh_CN": "", + "raw": "could not add security group rule, because the remote security group uuid is conflict", + "en_US": "could not add security group rule, because the remote security group uuid is conflict", + "zh_CN": "无法添加安全组规则,因为远端安全组uuid冲突", "arguments": [], - "line": 1485, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 938, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "failed to detach shareable volume[uuid:%s] from VmInstance[uuid:%s]", - "en_US": "failed to detach shareable volume[uuid:{0}] from VmInstance[uuid:{1}]", - "zh_CN": "不能卸载云主机[uuid:{1}]上的共享盘[uuid:{0}]", + "raw": "could not add security group rule, because rule priority must greater than %d or equals %d", + "en_US": "could not add security group rule, because rule priority must greater than {0} or equals {1}", + "zh_CN": "无法添加安全组规则,因为规则优先级必须大于{0}或等于{1}", "arguments": [ - "msg.getVolume().getUuid()", - "msg.getVmInstanceUuid()" + "SecurityGroupConstant.DEFAULT_RULE_PRIORITY", + "SecurityGroupConstant.LOWEST_RULE_PRIORITY" ], - "line": 1595, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 974, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "failed to detach shareable volume from VmInstance:[\\n%s]", - "en_US": "failed to detach shareable volume from VmInstance:[\\n{0}]", - "zh_CN": "不能卸载云主机[uuid:{0}]上的共享盘", + "raw": "could not add security group rule, because invalid rule type[%s], valid types are %s", + "en_US": "could not add security group rule, because invalid rule type[{0}], valid types are {1}", + "zh_CN": "无法添加安全组规则,因为规则类型[{0}]无效,有效类型为{1}", "arguments": [ - "StringUtils.join(errors, \"\\n\\n\")" + "ao.getType()", + "SecurityGroupRuleType.getAllType()" ], - "line": 1607, - "fileName": "src/main/java/org/zstack/mevoco/MevocoVolumeBase.java" + "line": 982, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the current version of license does not support modifying this global config [name:%s]", - "en_US": "the current version of license does not support modifying this global config [name:{0}]", - "zh_CN": "当前license版本不支持修改此全局设置[name:{0}]", + "raw": "could not add security group rule, because invalid rule state[%s], valid states are %s", + "en_US": "could not add security group rule, because invalid rule state[{0}], valid states are {1}", + "zh_CN": "无法添加安全组规则,因为规则状态[{0}]无效,有效状态为{1}", "arguments": [ - "getName()" + "ao.getState()", + "SecurityGroupRuleState.getAllState()" ], - "line": 27, - "fileName": "src/main/java/org/zstack/mevoco/PremiumGlobalConfig.java" + "line": 989, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the current version of license does not support modifying this resource config [name:%s]", - "en_US": "the current version of license does not support modifying this resource config [name:{0}]", - "zh_CN": "", + "raw": "could not add security group rule, because invalid rule protocol[%s], valid protocols are %s", + "en_US": "could not add security group rule, because invalid rule protocol[{0}], valid protocols are {1}", + "zh_CN": "无法添加安全组规则,因为规则协议[{0}]无效,有效协议为{1}", "arguments": [ - "globalConfig.getName()" + "ao.getProtocol()", + "SecurityGroupRuleProtocolType.getAllProtocol()" ], - "line": 22, - "fileName": "src/main/java/org/zstack/mevoco/PremiumResourceConfig.java" + "line": 994, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "invalid volume qos mode: %s", - "en_US": "invalid volume qos mode: {0}", - "zh_CN": "", + "raw": "could not add security group rule, because invalid rule action[%s], valid actions are %s", + "en_US": "could not add security group rule, because invalid rule action[{0}], valid actions are {1}", + "zh_CN": "无法添加安全组规则,因为规则动作[{0}]无效,有效动作为{1}", "arguments": [ - "mode" + "ao.getAction()", + "SecurityGroupRuleAction.getAllAction()" ], - "line": 229, - "fileName": "src/main/java/org/zstack/mevoco/VolumeQos.java" + "line": 1001, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find mode from null VolumeQos", - "en_US": "cannot find mode from null VolumeQos", - "zh_CN": "", - "arguments": [], - "line": 199, - "fileName": "src/main/java/org/zstack/mevoco/VolumeQos.java" + "raw": "could not add security group rule, because invalid rule ipVersion[%d], valid ipVersions are %d/%d", + "en_US": "could not add security group rule, because invalid rule ipVersion[{0}], valid ipVersions are {1}/{2}", + "zh_CN": "无法添加安全组规则,因为规则IPVersion[{0}]无效,有效的IPVersion为{1}/{2}", + "arguments": [ + "ao.getIpVersion()", + "IPv6Constants.IPv4", + "IPv6Constants.IPv6" + ], + "line": 1009, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find monitor trigger[uuid:%s], it may have been deleted", - "en_US": "cannot find monitor trigger[uuid:{0}], it may have been deleted", - "zh_CN": "不能找到触发监控器[uuid:{0}],它可能已经被删除了", + "raw": "could not add security group rule, because the dstIpRange[%s] is not allowed to set for ingress rule", + "en_US": "could not add security group rule, because the dstIpRange[{0}] is not allowed to set for ingress rule", + "zh_CN": "无法添加安全组规则,因为不允许为入口规则设置dstIpRange[{0}]", "arguments": [ - "msg.getMonitorTriggerUuid()" + "ao.getDstIpRange()" ], - "line": 190, - "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" + "line": 1037, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find monitor trigger action[uuid:%s], it may have been deleted", - "en_US": "cannot find monitor trigger action[uuid:{0}], it may have been deleted", - "zh_CN": "为找到这个监控触发行为[uuid:{0}],它可能已经被删除了", + "raw": "could not add security group rule, because the allowedCidr[%s] and srcIpRange[%s] are in conflict", + "en_US": "could not add security group rule, because the allowedCidr[{0}] and srcIpRange[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为allowedcidr[{0}]和srciprange[{1}]冲突", "arguments": [ - "msg.getMonitorTriggerActionUuid()" + "ao.getAllowedCidr()", + "ao.getSrcIpRange()" ], - "line": 199, - "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" + "line": 1042, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the resource[type:%s] doesn\u0027t have any monitoring items", - "en_US": "the resource[type:{0}] doesn\u0027t have any monitoring items", - "zh_CN": "该资源[type:{0}]没有任何监控条目", + "raw": "could not add security group rule, because the ip range[%s] and remoteSecurityGroupUuid[%s] are in conflict", + "en_US": "could not add security group rule, because the ip range[{0}] and remoteSecurityGroupUuid[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为IP范围[{0}]和RemoteSecurityGroupuuid[{1}]冲突", "arguments": [ - "msg.getResourceType()" + "ao.getDstIpRange()", + "ao.getRemoteSecurityGroupUuid()" ], - "line": 243, - "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" + "line": 1031, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the resource[uuid:%s] doesn\u0027t belong to the account[uuid:%s]", - "en_US": "the resource[uuid:{0}] doesn\u0027t belong to the account[uuid:{1}]", - "zh_CN": "该资源[uuid:{0}]不属于账户[uuid:{1}]", + "raw": "could not add security group rule, because the srcIpRange[%s] is not allowed to set for egress rule", + "en_US": "could not add security group rule, because the srcIpRange[{0}] is not allowed to set for egress rule", + "zh_CN": "无法添加安全组规则,因为不允许为出口规则设置SrcIPRange[{0}]", "arguments": [ - "msg.getTargetResourceUuid()", - "msg.getSession().getAccountUuid()" + "ao.getSrcIpRange()" ], - "line": 335, - "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" + "line": 1019, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "cannot find type for the resource[uuid:%s]", - "en_US": "cannot find type for the resource[uuid:{0}]", - "zh_CN": "未找到资源[uuid:{0}]这种类型", + "raw": "could not add security group rule, because the allowedCidr[%s] and dstIpRange[%s] are in conflict", + "en_US": "could not add security group rule, because the allowedCidr[{0}] and dstIpRange[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为AllowedCidr[{0}]和dstIpRange[{1}]冲突", "arguments": [ - "resourceUuid" + "ao.getAllowedCidr()", + "ao.getDstIpRange()" ], - "line": 386, - "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" + "line": 1024, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "no monitoring item found for the resourceType[%s] and item[%s]", - "en_US": "no monitoring item found for the resourceType[{0}] and item[{1}]", - "zh_CN": "未找到资源类型[{0}]和条目[{1}]这种监控条目", + "raw": "could not add security group rule, because invalid rule endPort[%d], endPort must be greater than or equal to startPort[%d]", + "en_US": "could not add security group rule, because invalid rule endPort[{0}], endPort must be greater than or equal to startPort[{1}]", + "zh_CN": "无法添加安全组规则,因为规则endPort[{0}]无效,endPort必须大于或等于startPort[{1}]", "arguments": [ - "resourceType", - "triggerExpression.getItem()" + "ao.getEndPort()", + "ao.getStartPort()" ], - "line": 391, - "fileName": "src/main/java/org/zstack/monitoring/MonitorManagerImpl.java" + "line": 1073, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "A resource[name:{resourceName}, uuid:{resourceUuid}, type:{resourceType}]\u0027s monitoring trigger[uuid:{triggerUuid}] changes status to {triggerStatus}", - "en_US": "A resource[name:{resourceName}, uuid:{resourceUuid}, type:{resourceType}]\u0027s monitoring trigger[uuid:{triggerUuid}] changes status to {triggerStatus}", - "zh_CN": "资源[name:{resourceName}, uuid:{resourceUuid}, type:{resourceType}]的监听触发器[uuid:{triggerUuid}]修改状态为{triggerStatus}", + "raw": "could not add security group rule, because dstPortRange[%s] and starPort[%s] are in conflict", + "en_US": "could not add security group rule, because dstPortRange[{0}] and starPort[{1}] are in conflict", + "zh_CN": "无法添加安全组规则,因为DstPortRange[{0}]和StarPort[{1}]冲突", "arguments": [ - "args" + "ao.getDstPortRange()", + "ao.getStartPort()" ], - "line": 50, - "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" + "line": 1076, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "\\n\u003d\u003d\u003d BELOW ARE DETAILS OF THE PREVIOUS ALERT \u003d\u003d\u003d", - "en_US": "\\n\u003d\u003d\u003d BELOW ARE DETAILS OF THE PREVIOUS ALERT \u003d\u003d\u003d", - "zh_CN": "\\n\u003d\u003d\u003d 以下是上一次警告内容 \u003d\u003d\u003d", + "raw": "could not add security group rule, because the protocol type TCP/UDP must set dstPortRange", + "en_US": "could not add security group rule, because the protocol type TCP/UDP must set dstPortRange", + "zh_CN": "无法添加安全组规则,因为协议类型TCP/UDP必须设置dstPortRange", "arguments": [], - "line": 55, - "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" + "line": 1087, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "\\nalert details:", - "en_US": "\\nalert details:", - "zh_CN": "\\n警告内容: ", + "raw": "could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[%s]", + "en_US": "could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[{0}]", + "zh_CN": "无法添加安全组规则,因为协议类型ALL或ICMP无法设置DstPortRange[{0}]", + "arguments": [ + "ao.getDstPortRange()" + ], + "line": 1065, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + }, + { + "raw": "could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort", + "en_US": "could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort", + "zh_CN": "无法添加安全组规则,因为协议类型ALL或ICMP无法设置StartPort或EndPort", "arguments": [], - "line": 58, - "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" + "line": 1068, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "\\ncondition: {itemName} {operator} {threshold}", - "en_US": "\\ncondition: {itemName} {operator} {threshold}", - "zh_CN": "\\n环境: {itemName} {operator} {threshold}", + "raw": "could not add security group rule, because rule[%s] and rule[%s] are dupilicated", + "en_US": "could not add security group rule, because rule[{0}] and rule[{1}] are dupilicated", + "zh_CN": "无法添加安全组规则,因为规则[{0}]和规则[{1}]重复", "arguments": [ - "args" + "JSONObjectUtil.toJsonString(newRules.get(i))", + "JSONObjectUtil.toJsonString(newRules.get(j))" ], - "line": 59, - "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" + "line": 1097, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "\\ncurrent value: {value}", - "en_US": "\\ncurrent value: {value}", - "zh_CN": "\\n当前值: {value}", + "raw": "could not add security group rule, because rule[%s] is duplicated to rule[uuid:%s] in datebase", + "en_US": "could not add security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase", + "zh_CN": "无法添加安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复", "arguments": [ - "args" + "JSONObjectUtil.toJsonString(sao)", + "vo.getUuid()" ], - "line": 60, - "fileName": "src/main/java/org/zstack/monitoring/items/AlertText.java" - }, - { - "raw": "Host CPU utilization", - "en_US": "Host CPU utilization", - "zh_CN": "CPU使用率", - "arguments": [], - "line": 31, - "fileName": "src/main/java/org/zstack/monitoring/items/host/HostCpuUtilItem.java" + "line": 1121, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "VM CPU utilization", - "en_US": "VM CPU utilization", - "zh_CN": "虚拟机CPU使用率", - "arguments": [], - "line": 29, - "fileName": "src/main/java/org/zstack/monitoring/items/vm/VmCpuUtilItem.java" + "raw": "could not add security group rule, because security group %s rules has reached the maximum limit[%d]", + "en_US": "could not add security group rule, because security group {0} rules has reached the maximum limit[{1}]", + "zh_CN": "无法添加安全组规则,因为安全组{0}规则已达到最大限制[{1}]", + "arguments": [ + "SecurityGroupRuleType.Egress", + "SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)" + ], + "line": 1136, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "conflict alert rule[%s], there has been a rule[%s] with the same name", - "en_US": "conflict alert rule[{0}], there has been a rule[{1}] with the same name", - "zh_CN": "冲突提示规则[{0}],这里已经存在和它一样名称的规则", + "raw": "could not add security group rule, because security group %s rules number[%d] is out of max limit[%d]", + "en_US": "could not add security group rule, because security group {0} rules number[{1}] is out of max limit[{2}]", + "zh_CN": "无法添加安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}]", "arguments": [ - "rb.name", - "r" + "SecurityGroupRuleType.Egress", + "(egressRuleCount + toCreateEgressRuleCount)", + "SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)" ], - "line": 141, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java" + "line": 1144, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "ALERT:\\n resource[name: %s, uuid: %s, type: %s]\\nevent: %s %s %s\\ncurrent value: %s\\nduration: %s seconds\\n", - "en_US": "ALERT:\\n resource[name: {0}, uuid: {1}, type: {2}]\\nevent: {3} {4} {5}\\ncurrent value: {6}\\nduration: {7} seconds\\n", - "zh_CN": "警告:\\n 资源[名称: {0}, uuid: {1}, 类型: {2}]\\n 事件: {3} {4} {5}\\n 周期: {7}\\n", + "raw": "could not add security group rule, because priority[%d] must be consecutive, the ingress rule maximum priority is [%d]", + "en_US": "could not add security group rule, because priority[{0}] must be consecutive, the ingress rule maximum priority is [{1}]", + "zh_CN": "无法添加安全组规则,因为优先级[{0}]必须连续,入口规则最大优先级为[{1}]", "arguments": [ - "resourceName", - "resourceUuid", - "toI18nString(resourceType)", - "itemName", - "toI18nString(expression.getOperator())", - "expression.getConstant()", - "value", - "tvo.getDuration()" + "msg.getPriority()", + "ingressRuleCount" ], - "line": 79, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusAlert.java" + "line": 1148, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the relativeTime[%s] is invalid, it must be in format of, for example, 10s, 1h", - "en_US": "the relativeTime[{0}] is invalid, it must be in format of, for example, 10s, 1h", - "zh_CN": "相关时间[{0}]不合法,格式必须例如10s,1h", + "raw": "could not add security group rule, because priority[%d] must be consecutive, the egress rule maximum priority is [%d]", + "en_US": "could not add security group rule, because priority[{0}] must be consecutive, the egress rule maximum priority is [{1}]", + "zh_CN": "无法添加安全组规则,因为优先级[{0}]必须是连续的,出口规则最大优先级为[{1}]", "arguments": [ - "msg.getRelativeTime()" + "msg.getPriority()", + "egressRuleCount" ], - "line": 40, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java" + "line": 1151, + "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" }, { - "raw": "the relativeTime[%s] is invalid, it\u0027s too big", - "en_US": "the relativeTime[{0}] is invalid, it\u0027s too big", - "zh_CN": "相关时间[{0}]不合法,值\u0027s 过大", + "raw": "could not execute the api operation. backend network [uuid:%s] must be vpc network because other backend network is vpc network", + "en_US": "could not execute the api operation. backend network [uuid:{0}] must be vpc network because other backend network is vpc network", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]必须是VPC网络,因为其他后端网络是VPC网络", "arguments": [ - "msg.getRelativeTime()" + "uuid" ], - "line": 44, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java" + "line": 217, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "CPU number", - "en_US": "CPU number", - "zh_CN": "CPU数量", - "arguments": [], - "line": 95, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilAlertWriter.java" + "raw": "could not execute the api operation. backend network [uuid:%s] is connected vpc router [uuid:%s] while other backend network is connected to vpc router[uuid:%s]", + "en_US": "could not execute the api operation. backend network [uuid:{0}] is connected vpc router [uuid:{1}] while other backend network is connected to vpc router[uuid:{2}]", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]连接到VPC路由器[uuid:{1}],而另一个后端网络连接到VPC路由器[uuid:{2}]", + "arguments": [ + "uuid", + "bVrUuids.get(0)", + "firstBackendVrUuids.get(0)" + ], + "line": 228, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "invalid cpu[%s], the host[uuid:%s] doesn\u0027t have a CPU numbered by %s", - "en_US": "invalid cpu[{0}], the host[uuid:{1}] doesn\u0027t have a CPU numbered by {2}", - "zh_CN": "无效CPU数目[{0}],物理机[uuid:{1}]存在的CPU数目是{2}", + "raw": "could not execute the api operation. backend network [uuid:%s] must be private flat network because frond l3 network is private flat network", + "en_US": "could not execute the api operation. backend network [uuid:{0}] must be private flat network because frond l3 network is private flat network", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]必须是专用三层网络,因为前端三层网络是专用三层网络", "arguments": [ - "cpu", - "trigger.getTargetResourceUuid()", - "cpuNum" + "uuid" ], - "line": 70, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilItem.java" + "line": 186, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Host Disk Capacity", - "en_US": "Host Disk Capacity", - "zh_CN": "物理机磁盘容量", - "arguments": [], - "line": 92, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java" + "raw": "could not execute the api operation. frontend network [uuid:%s] is not connected vpc router", + "en_US": "could not execute the api operation. frontend network [uuid:{0}] is not connected vpc router", + "zh_CN": "无法执行API操作。前端网络[uuid:{0}]未连接VPC路由器", + "arguments": [ + "frontL3.getUuid()" + ], + "line": 156, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Host Disk Capacity type", - "en_US": "Host Disk Capacity type", - "zh_CN": "物理机磁盘容量类型", - "arguments": [], - "line": 98, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java" + "raw": "could not execute the api operation. backend network [uuid:%s] must be vpc network because frond l3 network is vpc network", + "en_US": "could not execute the api operation. backend network [uuid:{0}] must be vpc network because frond l3 network is vpc network", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]必须是VPC网络,因为前端三层网络是VPC网络", + "arguments": [ + "uuid" + ], + "line": 164, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Host devices", - "en_US": "Host devices", - "zh_CN": "物理机服务", - "arguments": [], - "line": 100, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java" + "raw": "could not execute the api operation. backend network [uuid:%s] is connected vpc router [uuid:%s] while front network is connected to vpc router[uuid:%s]", + "en_US": "could not execute the api operation. backend network [uuid:{0}] is connected vpc router [uuid:{1}] while front network is connected to vpc router[uuid:{2}]", + "zh_CN": "无法执行API操作。后端网络[uuid:{0}]连接到VPC路由器[uuid:{1}],前端网络连接到VPC路由器[uuid:{2}]", + "arguments": [ + "uuid", + "backendVrUuids.get(0)", + "frontVrUuids.get(0)" + ], + "line": 175, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "invalid type[%s], only %s are allowed", - "en_US": "invalid type[{0}], only {1} are allowed", - "zh_CN": "无效类型[{0}],只有{1}被允许", + "raw": "could not create slb group because invalid deploy type %s", + "en_US": "could not create slb group because invalid deploy type {0}", + "zh_CN": "无法创建SLB组,因为部署类型{0}无效", "arguments": [ - "type", - "ALLOWED_TYPES" + "msg.getDeployType()" ], - "line": 22, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityItem.java" + "line": 254, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Host", - "en_US": "Host", - "zh_CN": "物理机", - "arguments": [], - "line": 77, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusHostNetworkIOAlertWriter.java" + "raw": "could not create slb group because invalid backend type %s", + "en_US": "could not create slb group because invalid backend type {0}", + "zh_CN": "无法创建SLB组,因为后端类型{0}无效", + "arguments": [ + "msg.getBackendType()" + ], + "line": 263, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "query failure, errorType:%s, error: %s", - "en_US": "query failure, errorType:{0}, error: {1}", - "zh_CN": "查询失败,错误类型: {0}, 错误: {1}", + "raw": "can not detach front end l3 network [uuid:%s] from SLB instance", + "en_US": "can not detach front end l3 network [uuid:{0}] from SLB instance", + "zh_CN": "无法从SLB实例分离前端三层网络[uuid:{0}]", "arguments": [ - "ret.get(\"errorType\")", - "ret.get(\"error\")" + "frontL3Uuid", + "slbVO.getUuid()" ], - "line": 124, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusMonitorProviderFactory.java" + "line": 298, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "CPU Utilization", - "en_US": "CPU Utilization", - "zh_CN": "CPU使用率", - "arguments": [], - "line": 81, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java" + "raw": "can not detach management l3 network [uuid:%s] from SLB instance", + "en_US": "can not detach management l3 network [uuid:{0}] from SLB instance", + "zh_CN": "无法从SLB实例分离管理三层网络[uuid:{0}]", + "arguments": [ + "slbVO.getManagementNetworkUuid()", + "slbVO.getUuid()" + ], + "line": 303, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "CPU utilization type", - "en_US": "CPU utilization type", - "zh_CN": "CPU使用类型", - "arguments": [], - "line": 84, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java" + "raw": "can not detach nic [uuid:%s] from SLB instance, because it is the last backend l3 network nic", + "en_US": "can not detach nic [uuid:{0}] from SLB instance, because it is the last backend l3 network nic", + "zh_CN": "无法从SLB实例分离NIC[uuid:{0}],因为它是最后一个后端三层网络NIC", + "arguments": [ + "msg.getVmNicUuid()" + ], + "line": 315, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, - { - "raw": "Disk IO", - "en_US": "Disk IO", - "zh_CN": "磁盘IO", - "arguments": [], - "line": 86, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java" + { + "raw": "can not create load balancer because vip [uuid:%s] has attached other network service [%s]", + "en_US": "can not create load balancer because vip [uuid:{0}] has attached other network service [{1}]", + "zh_CN": "无法创建负载平衡器,因为VIP[uuid:{0}]已附加其他网络服务[{1}]", + "arguments": [ + "msg.getVipUuid()", + "vipVO.getServicesTypes()" + ], + "line": 343, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Disk IO direction", - "en_US": "Disk IO direction", - "zh_CN": "磁盘IO方向", - "arguments": [], - "line": 92, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java" + "raw": "can not create load balancer because vip [uuid:%s] has attached to vpc router [%s]", + "en_US": "can not create load balancer because vip [uuid:{0}] has attached to vpc router [{1}]", + "zh_CN": "无法创建负载平衡器,因为VIP[uuid:{0}]已连接到VPC路由器[{1}]", + "arguments": [ + "msg.getVipUuid()", + "vrUuids" + ], + "line": 350, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Disk IO type", - "en_US": "Disk IO type", - "zh_CN": "磁盘IO类型", - "arguments": [], - "line": 93, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java" + "raw": "can not create load balancer because invalid slb group [uuid:%s]", + "en_US": "can not create load balancer because invalid slb group [uuid:{0}]", + "zh_CN": "无法创建负载平衡器,因为SLB组[uuid:{0}]无效", + "arguments": [ + "slbGroupUuid" + ], + "line": 356, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "Memory Utilization", - "en_US": "Memory Utilization", - "zh_CN": "内存使用率", + "raw": "could not add vmnic to load balancer server group because l3 network is not connected slb instance", + "en_US": "could not add vmnic to load balancer server group because l3 network is not connected slb instance", + "zh_CN": "无法将vmnic添加到负载平衡器服务器组,因为三层网络未连接到SLB实例", "arguments": [], - "line": 77, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilAlertWriter.java" + "line": 407, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "invalid right value[%s], it must be a float or double number", - "en_US": "invalid right value[{0}], it must be a float or double number", - "zh_CN": "无效的参数值[{0}],它必须是一个float或者double类型的数值", + "raw": "could not add vmnic to load balancer server group because l3 network [uuid:%s] is connected any vpc router", + "en_US": "could not add vmnic to load balancer server group because l3 network [uuid:{0}] is connected any vpc router", + "zh_CN": "无法将vmnic添加到负载平衡器服务器组,因为三层网络[uuid:{0}]已连接到任何VPC路由器", "arguments": [ - "expression.getConstant()" + "uuid" ], - "line": 57, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java" + "line": 389, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "invalid right value[%s], it must be float or double number greater than zero and lesser than one", - "en_US": "invalid right value[{0}], it must be float or double number greater than zero and lesser than one", - "zh_CN": "无效参数值[{0}],它必须是一个float或者double类型的大于0小于1的数值", + "raw": "could not add vmnic to load balancer server group because l3 network[uuid:%s] is connected to different vpc router", + "en_US": "could not add vmnic to load balancer server group because l3 network[uuid:{0}] is connected to different vpc router", + "zh_CN": "无法将vmnic添加到负载平衡器服务器组,因为三层网络[uuid:{0}]已连接到不同的VPC路由器", "arguments": [ - "expression.getConstant()" + "uuid" ], - "line": 53, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java" + "line": 396, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java" }, { - "raw": "invalid arguments %s, no argument is allowed", - "en_US": "invalid arguments {0}, no argument is allowed", - "zh_CN": "无效参数列表{0},没有被参数被允许", + "raw": "can not find nic of slb instance [uuid:%s] which is attached to slb group front l3 network [uuid:%s]", + "en_US": "can not find nic of slb instance [uuid:{0}] which is attached to slb group front l3 network [uuid:{1}]", + "zh_CN": "找不到SLB实例[uuid:{0}]的网卡,该网卡挂接在SLB组前三层网络[uuid:{1}]上", "arguments": [ - "expression.getArguments().keySet()" + "slbInstance.getUuid()", + "frontL3Uuid" ], - "line": 47, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java" - }, - { - "raw": "Network IO", - "en_US": "Network IO", - "zh_CN": "网络IO", - "arguments": [], - "line": 84, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java" + "line": 60, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbCreatePublicVipFlow.java" }, { - "raw": "Network IO direction", - "en_US": "Network IO direction", - "zh_CN": "网络IO方向", + "raw": "can not find slb vm instance", + "en_US": "can not find slb vm instance", + "zh_CN": "找不到SLB云主机实例", "arguments": [], - "line": 89, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java" + "line": 38, + "fileName": "src/main/java/org/zstack/network/service/slb/SlbVyosBackend.java" }, { - "raw": "Virtual Machine", - "en_US": "Virtual Machine", - "zh_CN": "虚拟机器", + "raw": "system vip can not be deleted by API message", + "en_US": "system vip can not be deleted by API message", + "zh_CN": "API消息无法删除系统VIP", "arguments": [], - "line": 77, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java" + "line": 48, + "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" }, { - "raw": "invalid right value[%s], it must be a number(int, long, float, double)", - "en_US": "invalid right value[{0}], it must be a number(int, long, float, double)", - "zh_CN": "无效参数值[{0}],他应该是一个数字(int, long, float, double)", + "raw": "unsupported ip allocation strategy[%s]", + "en_US": "unsupported ip allocation strategy[{0}]", + "zh_CN": "不支持的ip分配策略[{0}]", "arguments": [ - "expression.getConstant()" + "msg.getAllocatorStrategy()" ], - "line": 22, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java" + "line": 54, + "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" }, { - "raw": "invalid direction[%s], only %s are allowed", - "en_US": "invalid direction[{0}], only {1} are allowed", - "zh_CN": "无效direction[{0}],只有{1}被允许", + "raw": "requiredIp[%s] is not in valid IPv4 mediaType", + "en_US": "requiredIp[{0}] is not in valid IPv4 mediaType", + "zh_CN": "请求的ip[{0}]不是有效的IPv4地址", "arguments": [ - "dir", - "ALLOWED_DIRECTION" + "msg.getRequiredIp()" ], - "line": 18, - "fileName": "src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java" + "line": 63, + "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" }, { - "raw": "invalid expression: %s, %s", - "en_US": "invalid expression: {0}, {1}", - "zh_CN": "无效的语句: {0}, {1}", + "raw": "there is already a vip[%s] on l3Network[uuid:%s]", + "en_US": "there is already a vip[{0}] on l3Network[uuid:{1}]", + "zh_CN": "已有一个vip[{0}]在三层网络[uuid:{1}]上", "arguments": [ - "expr", - "e.getMessage()" + "msg.getRequiredIp()", + "msg.getL3NetworkUuid()" ], - "line": 106, - "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" + "line": 70, + "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" }, { - "raw": "invalid expression: %s, no expression found", - "en_US": "invalid expression: {0}, no expression found", - "zh_CN": "无效的语句: {0},未找到该语句", + "raw": "required ip address [%s] is already used", + "en_US": "required ip address [{0}] is already used", + "zh_CN": "所需的IP地址[{0}]已被使用", "arguments": [ - "expr" + "msg.getRequiredIp()" ], - "line": 110, - "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" + "line": 76, + "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" }, { - "raw": "missing parameter \u0027%s\u0027 in the expression", - "en_US": "missing parameter \u0027{0}\u0027 in the expression", - "zh_CN": "在语句中缺失参数{0}", + "raw": "could not create vip, because can not determine the vip version", + "en_US": "could not create vip, because can not determine the vip version", + "zh_CN": "无法创建VIP,因为无法确定VIP版本", + "arguments": [], + "line": 100, + "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" + }, + { + "raw": "service provider of the vip[uuid:%s, name:%s, ip: %s] has been set to %s", + "en_US": "service provider of the vip[uuid:{0}, name:{1}, ip: {2}] has been set to {3}", + "zh_CN": "vip[uuid:{0}, name:{1}, ip: {2}]的服务提供器已经被设置成[{3}]", "arguments": [ - "key" + "self.getUuid()", + "self.getName()", + "self.getIp()", + "self.getServiceProvider()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" + "line": 155, + "fileName": "src/main/java/org/zstack/network/service/vip/VipBase.java" }, { - "raw": "wrong type of parameter \u0027%s\u0027 in the expression, it must be type of %s, but got %s", - "en_US": "wrong type of parameter \u0027{0}\u0027 in the expression, it must be type of {1}, but got {2}", - "zh_CN": "在语句中{0}参数类型错误,它必须是{1}这种类型,但是获得的是{2}", + "raw": "VipQos for ipv6 wil be added soon", + "en_US": "VipQos for ipv6 wil be added soon", + "zh_CN": "IPv6的VIPQoS将很快添加", + "arguments": [], + "line": 43, + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + }, + { + "raw": "VipQos for Vip [uuid: %s] already existed", + "en_US": "VipQos for Vip [uuid: {0}] already existed", + "zh_CN": "虚拟IP[uuid: {0}]的Qos已经存在了", "arguments": [ - "key", - "clz", - "value.getClass()" + "msg.getVipUuid()" ], - "line": 131, - "fileName": "src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java" + "line": 53, + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" }, { - "raw": "Rendezvous Point [%s] is not a unicast address", - "en_US": "Rendezvous Point [{0}] is not a unicast address", - "zh_CN": "组播聚合点地址[{0}]不是单播地址", + "raw": "VipQos for Vip [uuid: %s] port %s already existed", + "en_US": "VipQos for Vip [uuid: {0}] port {1} already existed", + "zh_CN": "虚拟IP[uuid: {0}]的Qos端口{1}已经存在", "arguments": [ - "rpAddress" + "msg.getVipUuid()", + "Integer.toString(msg.getPort())" ], + "line": 48, + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + }, + { + "raw": "SetVipQos MUST set InboundBandwidth or OutboundBandwidth", + "en_US": "SetVipQos MUST set InboundBandwidth or OutboundBandwidth", + "zh_CN": "设置虚拟IP的Qos是必须设置上行网络带宽和下行网络带宽", + "arguments": [], "line": 59, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" }, { - "raw": "group address [%s] is not a multicast address", - "en_US": "group address [{0}] is not a multicast address", - "zh_CN": "地址 [{0}] 不是组播地址", + "raw": "Cannot set Qos for this Vip. Not all peer l3networks provide VipQos service.", + "en_US": "Cannot set Qos for this Vip. Not all peer l3networks provide VipQos service.", + "zh_CN": "无法设置此VIP的QoS。并非所有对等三层网络都提供VIPQoS服务。", + "arguments": [], + "line": 67, + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + }, + { + "raw": "VipQos for Vip [uuid: %s] does not exist", + "en_US": "VipQos for Vip [uuid: {0}] does not exist", + "zh_CN": "虚拟IP[uuid: {0}]的Qos不存在", "arguments": [ - "multicastGroup" + "msg.getUuid()" ], - "line": 63, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" + "line": 80, + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" }, { - "raw": "rp address pair [%s: %s] already existed for multicast router [uuid:%s]", - "en_US": "rp address pair [{0}: {1}] already existed for multicast router [uuid:{2}]", - "zh_CN": "组播聚合点地址对[{0}: {1}]已经存在于组播路由器[uuid:{2}]的配置中", + "raw": "VipQos for Vip [uuid: %s] port %s does not exist", + "en_US": "VipQos for Vip [uuid: {0}] port {1} does not exist", + "zh_CN": "虚拟IP[uuid: {0}]的Qos端口{1}不存在", "arguments": [ - "msg.getRpAddress()", - "msg.getGroupAddress()", - "msg.getUuid()" + "msg.getUuid()", + "Integer.toString(msg.getPort())" ], "line": 75, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" }, { - "raw": "rp address tuple [%s : %s] is not existed for multicast router [uuid:%s]", - "en_US": "rp address tuple [{0} : {1}] is not existed for multicast router [uuid:{2}]", - "zh_CN": "组播聚合点地址对[{0}: {1}]不存于组播路由器[uuid:{2}]的配置中", + "raw": "Can not find VipQos backend for Vip [uuid:%s]", + "en_US": "Can not find VipQos backend for Vip [uuid:{0}]", + "zh_CN": "未找到虚拟IP的Qos后端", "arguments": [ - "msg.getRpAddress()", - "msg.getGroupAddress()", - "msg.getUuid()" + "vipUuid" ], - "line": 89, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java" + "line": 129, + "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosManagerImpl.java" }, { - "raw": "multicastRouter[uuid:%s] has not been attached to vpc router", - "en_US": "multicastRouter[uuid:{0}] has not been attached to vpc router", - "zh_CN": "组播路由器[uuid:{0}]没有关联到VPC路由器", + "raw": "operation error, vip %s has not bind to vm", + "en_US": "operation error, vip {0} has not bind to vm", + "zh_CN": "操作失败,虚拟IP{0}没有绑定云主机", "arguments": [ - "msg.getUuid()" + "hostUuid" ], - "line": 98, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" + "line": 198, + "fileName": "src/main/java/org/zstack/network/service/vipQos/flat/FlatVipQosBackend.java" }, { - "raw": "multicast already enabled on vpc router uuid[:%s]", - "en_US": "multicast already enabled on vpc router uuid[:{0}]", - "zh_CN": "VPC路由器[uuid:{0}]的组播路功能已经打开", + "raw": "the virtual router[name:%s, uuid:%s, current state:%s] is not running,and cannot perform required operation. Please retry your operation later once it is running", + "en_US": "the virtual router[name:{0}, uuid:{1}, current state:{2}] is not running,and cannot perform required operation. Please retry your operation later once it is running", + "zh_CN": "云路由[name:{0}, uuid:{1}, current state:{2}]没有运行,无法执行请求的操作。请在其启动后重试", "arguments": [ - "msg.getVpcRouterVmUuid()" + "self.getName()", + "self.getUuid()", + "self.getState()" + ], + "line": 656, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + }, + { + "raw": "virtual router[uuid:%s] is in status of %s that cannot make http call to %s", + "en_US": "virtual router[uuid:{0}] is in status of {1} that cannot make http call to {2}", + "zh_CN": "云路由[uuid:{0}]处于状态{1}中,无法向{2}发送http调用", + "arguments": [ + "self.getUuid()", + "getSelf().getStatus()", + "msg.getPath()" ], - "line": 124, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" + "line": 661, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" }, { - "raw": "vpc router for multicast router [uuid:%s] has been deleted", - "en_US": "vpc router for multicast router [uuid:{0}] has been deleted", - "zh_CN": "组播路由器[uuid:{0}]关联的VPC路由器已经被删除", + "raw": "virtual router[uuid:%s] has no management nic that cannot make http call to %s", + "en_US": "virtual router[uuid:{0}] has no management nic that cannot make http call to {1}", + "zh_CN": "虚拟路由器[uuid:{0}]没有无法对{1}进行HTTP调用的管理NIC", "arguments": [ - "msg.getUuid()" + "self.getUuid()", + "msg.getPath()" ], - "line": 316, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" + "line": 666, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" }, { - "raw": "multicast router [uuid:%s] is not attached to Vpc Router", - "en_US": "multicast router [uuid:{0}] is not attached to Vpc Router", - "zh_CN": "组播路由器[uuid:{0}]没有关联到VPC路由器", + "raw": "unable to add nic[ip:%s, mac:%s] to virtual router vm[uuid:%s ip:%s], because %s", + "en_US": "unable to add nic[ip:{0}, mac:{1}] to virtual router vm[uuid:{2} ip:{3}], because {4}", + "zh_CN": "不能添加网卡[ip:{0}, mac:{1}]到虚拟路由设备[uuid:{2} ip:{3}],因为{4}", "arguments": [ - "msg.getUuid()" + "info.getIp()", + "info.getMac()", + "vr.getUuid()", + "vr.getManagementNic().getIp()", + "rsp.getError()" ], - "line": 759, - "fileName": "src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java" + "line": 995, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" }, { - "raw": "multicast router [uuid:%s] has been delete during enable multilcast on backend", - "en_US": "multicast router [uuid:{0}] has been delete during enable multilcast on backend", - "zh_CN": "组播路由器[uuid:{0}]已经被删除", + "raw": "l3 uuid[:%s] is same to default network of virtual router [uuid:%s]", + "en_US": "l3 uuid[:{0}] is same to default network of virtual router [uuid:{1}]", + "zh_CN": "L3 uuid[:{0}]与虚拟路由器[uuid:{1}]的默认网络相同", "arguments": [ - "vrUuid" + "msg.getDefaultRouteL3NetworkUuid()", + "msg.getVmInstanceUuid()" ], - "line": 86, - "fileName": "src/main/java/org/zstack/multicast/router/backend/MulticastRouterVyosBackendImpl.java" + "line": 94, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "nas file system [%s] is not existed yet", - "en_US": "nas file system [{0}] is not existed yet", - "zh_CN": "", + "raw": "l3 uuid[:%s] is not attached to virtual router [uuid:%s]", + "en_US": "l3 uuid[:{0}] is not attached to virtual router [uuid:{1}]", + "zh_CN": "L3 uuid[:{0}]未连接到虚拟路由器[uuid:{1}]", "arguments": [ - "msg.getNasFileSystemUuid()" + "msg.getDefaultRouteL3NetworkUuid()", + "msg.getVmInstanceUuid()" ], - "line": 91, - "fileName": "src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java" + "line": 107, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "cannot find nas factory for type: %s", - "en_US": "cannot find nas factory for type: {0}", - "zh_CN": "", + "raw": "could not set the default network, because l3 uuid[:%s] is not public network", + "en_US": "could not set the default network, because l3 uuid[:{0}] is not public network", + "zh_CN": "设置默认网络失败,因为三层网路[:{0}] 不是公有网络", "arguments": [ - "type" + "msg.getDefaultRouteL3NetworkUuid()" ], - "line": 139, - "fileName": "src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java" + "line": 114, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "duplicate NasFileSystemFactory[%s, %s] for type[%s]", - "en_US": "duplicate NasFileSystemFactory[{0}, {1}] for type[{2}]", - "zh_CN": "", + "raw": "could not set the default network, because l3 uuid[:%s] is management network", + "en_US": "could not set the default network, because l3 uuid[:{0}] is management network", + "zh_CN": "设置默认网络失败,因为三层网路[:{0}] 是管理网络", "arguments": [ - "f.getClass().getSimpleName()", - "old.getClass().getSimpleName()", - "f.getNasFileSystemType()" + "msg.getDefaultRouteL3NetworkUuid()" ], - "line": 164, - "fileName": "src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java" + "line": 112, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "l2Network[uuid:%s] has attached to cluster[uuid:%s], can\u0027t attach again", - "en_US": "l2Network[uuid:{0}] has attached to cluster[uuid:{1}], can\u0027t attach again", - "zh_CN": "不能再次挂载l2网络[uuid:{0}],因为已经挂载到集群[uuid:{1}]上了", + "raw": "image[uuid:%s]\u0027s mediaType is %s, the mediaType of a virtual router image must be %s", + "en_US": "image[uuid:{0}]\u0027s mediaType is {1}, the mediaType of a virtual router image must be {2}", + "zh_CN": "镜像[uuid:{0}]的mediaType为{1},云路由的mediaType必须为{2}", "arguments": [ - "msg.getL2NetworkUuid()", - "msg.getClusterUuid()" + "msg.getImageUuid()", + "type", + "ImageMediaType.RootVolumeTemplate" ], - "line": 66, - "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" + "line": 219, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "l2Network[uuid:%s] has not attached to cluster[uuid:%s]", - "en_US": "l2Network[uuid:{0}] has not attached to cluster[uuid:{1}]", - "zh_CN": "L2网络[uuid:{0}]没有挂载到集群上[uuid:{1}]", + "raw": "image[uuid:%s] is of format %s, cannot be used for virtual router", + "en_US": "image[uuid:{0}] is of format {1}, cannot be used for virtual router", + "zh_CN": "镜像[uuid:{0}]的格式为{1},无法被用于云路由", "arguments": [ - "msg.getL2NetworkUuid()", - "msg.getClusterUuid()" + "msg.getImageUuid()", + "format" ], - "line": 75, - "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" + "line": 225, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "unsupported l2Network type[%s]", - "en_US": "unsupported l2Network type[{0}]", - "zh_CN": "不支持的网络类型[{0}]", + "raw": "management network[uuid:%s] is not in the same zone[uuid:%s] this offering is going to create", + "en_US": "management network[uuid:{0}] is not in the same zone[uuid:{1}] this offering is going to create", + "zh_CN": "管理网络[uuid:{0}]和将要创建的规格不处于同一个区域(zone)[uuid:{1}]中", "arguments": [ - "msg.getType()" + "msg.getManagementNetworkUuid()", + "msg.getZoneUuid()" ], - "line": 89, - "fileName": "src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java" + "line": 191, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "There has been a L2VlanNetwork[uuid:%s, name:%s] attached to cluster[uuid:%s] that has physical interface[%s], vlan[%s]. Failed to attach L2VlanNetwork[uuid:%s]", - "en_US": "There has been a L2VlanNetwork[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}], vlan[{4}]. Failed to attach L2VlanNetwork[uuid:{5}]", - "zh_CN": "L2网络挂载失败[uuid:{5}]: L2网络[uuid:{0}, name:{1}]的物理接口[{3}], vlan[{4}]已经挂载到集群[uuid:{2}]上", - "arguments": [ - "vl2.getUuid()", - "vl2.getName()", - "msg.getClusterUuid()", - "vl2.getPhysicalInterface()", - "vl2.getVlan()", - "tl2.getUuid()" - ], - "line": 558, - "fileName": "src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java" + "raw": "can not create virtual router offering, because management network doesn\u0027t support ipv6 yet", + "en_US": "can not create virtual router offering, because management network doesn\u0027t support ipv6 yet", + "zh_CN": "无法创建虚拟路由器产品,因为管理网络尚不支持IPv6", + "arguments": [], + "line": 196, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "There has been a l2Network[uuid:%s, name:%s] attached to cluster[uuid:%s] that has physical interface[%s]. Failed to attach l2Network[uuid:%s]", - "en_US": "There has been a l2Network[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}]. Failed to attach l2Network[uuid:{4}]", - "zh_CN": "L2网络挂载失败[uuid:{4}]: L2网络[uuid:{0}, name:{1}]的物理接口[{3}]]已经挂载到集群[uuid:{2}]上", + "raw": "public network[uuid:%s] is not in the same zone[uuid:%s] this offering is going to create", + "en_US": "public network[uuid:{0}] is not in the same zone[uuid:{1}] this offering is going to create", + "zh_CN": "公共网络[uuid:{0}]和将要创建的规格不处于同一个区域(zone)[uuid:{1}]中", "arguments": [ - "l2.getUuid()", - "l2.getName()", - "msg.getClusterUuid()", - "l2.getPhysicalInterface()", - "tl2.getUuid()" + "msg.getManagementNetworkUuid()", + "msg.getZoneUuid()" ], - "line": 540, - "fileName": "src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java" + "line": 208, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "cannot configure vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", - "en_US": "cannot configure vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}]", - "zh_CN": "无法为云主机[uuid:{0}]在目标物理机[uuid:{1}]上配置VXLAN网络", + "raw": "the L3 network[uuid: %s] has the SNAT service enabled, it cannot be used as a public network", + "en_US": "the L3 network[uuid: {0}] has the SNAT service enabled, it cannot be used as a public network", + "zh_CN": "三层网络[uuid: {0}]启用了SNAT服务,无法被用作公共网络", "arguments": [ - "inv.getUuid()", - "destHostUuid" + "msg.getPublicNetworkUuid()" ], - "line": 218, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java" + "line": 236, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "find multiple vtep ips[%s] for one host[uuid:%s], need to delete host and add again", - "en_US": "find multiple vtep ips[{0}] for one host[uuid:{1}], need to delete host and add again", - "zh_CN": "在一个物理机[uuid:{1}]发现多个VTEP IP,需要删除物理机在进行添加", + "raw": "the L3 network[uuid: %s] has the SNAT service enabled, it cannot be used as a management network", + "en_US": "the L3 network[uuid: {0}] has the SNAT service enabled, it cannot be used as a management network", + "zh_CN": "三层网络[uuid: {0}]启用了SNAT服务,无法被用作管理网络", "arguments": [ - "vtepIps", - "hostUuid" + "msg.getManagementNetworkUuid()" ], - "line": 79, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" + "line": 234, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "failed to create bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s], because %s", - "en_US": "failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vni:{3}] on kvm host[uuid:{4}], because {5}", - "zh_CN": "为L2网络[uuid:{1}, type:{2}, vni:{3}]在KVM物理机[uuid:{4}]上创建网桥[{0}]失败,错误细节: {5}", + "raw": "the L3 network[uuid: %s] is same network address with [uuid: %s], it cannot be used for virtual router", + "en_US": "the L3 network[uuid: {0}] is same network address with [uuid: {1}], it cannot be used for virtual router", + "zh_CN": "三层网络[uuid: {0}] 和 网络 [uuid: {1}] 具有相同的网络地址,无法被用于云路由", "arguments": [ - "cmd.getBridgeName()", - "l2Network.getUuid()", - "l2Network.getType()", - "l2vxlan.getVni()", - "hostUuid", - "rsp.getError()" + "msg.getManagementNetworkUuid()", + "msg.getPublicNetworkUuid()" ], - "line": 119, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" + "line": 243, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "failed to check cidr[%s] for l2VxlanNetwork[uuid:%s, name:%s] on kvm host[uuid:%s], %s", - "en_US": "failed to check cidr[{0}] for l2VxlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", - "zh_CN": "为KVM物理机[uuid:{3}]上的L2 VXLAN 网络[uuid:{1}, name:{2}]检查CIDR[{0}]失败,错误细节: {4}", + "raw": "the management network[uuid:%s] doesn\u0027t have any IP range", + "en_US": "the management network[uuid:{0}] doesn\u0027t have any IP range", + "zh_CN": "管理网络[uuid:{0}]不包含任何的IP范围", "arguments": [ - "cmd.getCidr()", - "l2vxlan.getUuid()", - "l2vxlan.getName()", - "hostUuid", - "rsp.getError()" + "managementNetworkUuid" ], - "line": 183, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java" + "line": 253, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "failed to realize vxlan network pool[uuid:%s, type:%s, vnis:%s] on kvm host[uuid:%s], because %s", - "en_US": "failed to realize vxlan network pool[uuid:{0}, type:{1}, vnis:{2}] on kvm host[uuid:{3}], because {4}", - "zh_CN": "在kvm物理机[uuid:{3}]实现vxlan network pool[uuid:{0}, type:{1}, vnis:{2}]失败,因为{4}", + "raw": "the management network[uuid:%s, gateway:%s] is not reachable", + "en_US": "the management network[uuid:{0}, gateway:{1}] is not reachable", + "zh_CN": "管理网络[uuid:{0}, gateway:{1}]不可抵达", "arguments": [ - "l2Network.getUuid()", - "l2Network.getType()", - "l2networks", - "hostUuid", - "rsp.getError()" + "managementNetworkUuid", + "gateway" ], - "line": 251, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java" + "line": 274, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" }, { - "raw": "failed to check cidr[%s] for l2VxlanNetworkPool[uuid:%s, name:%s] on kvm host[uuid:%s], %s", - "en_US": "failed to check cidr[{0}] for l2VxlanNetworkPool[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", - "zh_CN": "检查在kvm物理机[uuid:{3}]上的l2VxlanNetworkPool[uuid:{1}, name:{2}]的CIDR[{0}]失败,{4}", + "raw": "failed to create VirtualRouterBootstrapIso[%s] on kvm host[uuid:%s, ip:%s] for virtual router[uuid:%s], because %s", + "en_US": "failed to create VirtualRouterBootstrapIso[{0}] on kvm host[uuid:{1}, ip:{2}] for virtual router[uuid:{3}], because {4}", + "zh_CN": "创建云路由引导镜像(VirtualRouterBootstrapIso)[{0}]失败,该操作是在KVM物理机[uuid:{1}, ip:{2}]上为云路由[uuid:{3}]执行的,原因为{4}", "arguments": [ - "cmd.getCidr()", - "vxlanPool.getUuid()", - "vxlanPool.getName()", - "hostUuid", + "iso.getIsoPath()", + "vrSpec.getDestHost().getUuid()", + "vrSpec.getDestHost().getManagementIp()", + "iso.getVirtualRouterUuid()", "rsp.getError()" ], - "line": 110, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java" + "line": 103, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java" }, { - "raw": "vxlan vtep address for host [uuid : %s] and pool [uuid : %s] pair already existed", - "en_US": "vxlan vtep address for host [uuid : {0}] and pool [uuid : {1}] pair already existed", - "zh_CN": "物理机[uuid : {0}]在vxlan资源池[uuid : {1}]中隧道端点地址已经配置", + "raw": "failed to delete VirtualRouterBootstrapIso[%s] on kvm host[uuid:%s] for virtual router[uuid:%s], because %s", + "en_US": "failed to delete VirtualRouterBootstrapIso[{0}] on kvm host[uuid:{1}] for virtual router[uuid:{2}], because {3}", + "zh_CN": "删除云路由引导镜像(VirtualRouterBootstrapIso)[{0}]失败,该操作是在KVM物理机[uuid:{1}]上为云路由[uuid:{2}]执行的,原因为{3}", "arguments": [ - "msg.getHostUuid()", - "msg.getPoolUuid()" + "iso.getIsoPath()", + "hostUuid", + "iso.getVirtualRouterUuid()", + "rsp.getError()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java" - }, - { - "raw": "it is used", - "en_US": "it is used", - "zh_CN": "被占用", - "arguments": [], - "line": 27, - "fileName": "src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java" + "line": 136, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java" }, { - "raw": "it is not in this range", - "en_US": "it is not in this range", - "zh_CN": "不在IP地址范围内", + "raw": "cannot create virtual Router vm while virtual router network overlaps with private network in ip ", + "en_US": "cannot create virtual Router vm while virtual router network overlaps with private network in ip ", + "zh_CN": "当云路由规格的网络和私有网络IP范围有重叠时,无法创建云路由设备", "arguments": [], - "line": 25, - "fileName": "src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java" + "line": 289, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "it is gateway", - "en_US": "it is gateway", - "zh_CN": "网关不能分配", - "arguments": [], - "line": 23, - "fileName": "src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java" + "raw": "No virtual router instance offering with uuid:%s is found", + "en_US": "No virtual router instance offering with uuid:{0} is found", + "zh_CN": "找不到uuid为{0}的虚拟路由器实例产品", + "arguments": [ + "offeringUuid" + ], + "line": 716, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "you must update system and category both", - "en_US": "you must update system and category both", - "zh_CN": "必须同时更行system属性和category属性", - "arguments": [], - "line": 116, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "raw": "the network of virtual router instance offering with uuid:%s can\u0027t be same with private l3 network uuid:%s", + "en_US": "the network of virtual router instance offering with uuid:{0} can\u0027t be same with private l3 network uuid:{1}", + "zh_CN": "uuid为{0}的虚拟路由器实例提供的网络不能与uuid为{1}的专用三层网络相同", + "arguments": [ + "offeringUuid", + "resourceUuid" + ], + "line": 720, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "not valid combination of system and category,only %s are valid", - "en_US": "not valid combination of system and category,only {0} are valid", - "zh_CN": "无效的system属性和category属性的组合,只有{0}是有效的", + "raw": "cannot add ip range, because l3 network[uuid:%s] is management network of virtual router offering", + "en_US": "cannot add ip range, because l3 network[uuid:{0}] is management network of virtual router offering", + "zh_CN": "无法添加IP范围,因为三层网络[uuid:{0}]是虚拟路由器产品的管理网络", "arguments": [ - "L3NetworkCategory.validCombination" + "l3NetworkUuid" ], - "line": 355, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1434, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "invalid IP[%s]", - "en_US": "invalid IP[{0}]", - "zh_CN": "错误的IP值[{0}]", + "raw": "cannot add ip range, because l3 network[uuid:%s] is management network of virtual router", + "en_US": "cannot add ip range, because l3 network[uuid:{0}] is management network of virtual router", + "zh_CN": "无法添加IP范围,因为三层网络[uuid:{0}]是虚拟路由器的管理网络", "arguments": [ - "msg.getIp()" + "l3NetworkUuid" ], - "line": 161, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1439, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "no ip range in l3[%s]", - "en_US": "no ip range in l3[{0}]", - "zh_CN": "没有IP在三层网络范围中", + "raw": "couldn\u0027t add image, because systemTag [%s] includes invalid appliance image type [%s]", + "en_US": "couldn\u0027t add image, because systemTag [{0}] includes invalid appliance image type [{1}]", + "zh_CN": "无法添加镜像,因为系统标记[{0}]包含无效的装置镜像类型[{1}]", "arguments": [ - "msg.getL3NetworkUuid()" + "tag", + "type" ], - "line": 145, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1466, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "ip[%s] is not in the cidr of ip range[uuid:%s, cidr:%s] which l3 network[%s] attached", - "en_US": "ip[{0}] is not in the cidr of ip range[uuid:{1}, cidr:{2}] which l3 network[{3}] attached", - "zh_CN": "IP[{0}]没有在三层网络[{3}]的CIDR的IP范围内[uuid:{1}, cidr:{2}]", + "raw": "failed tot attach virtual router network services to l3Network[uuid:%s]. When eip is selected, snat must be selected too", + "en_US": "failed tot attach virtual router network services to l3Network[uuid:{0}]. When eip is selected, snat must be selected too", + "zh_CN": "挂载虚拟路由网络服务到三层网络[uuid:{0}]失败。选中EIP服务时,SNAT服务也必须被选中", "arguments": [ - "msg.getRouterInterfaceIp()", - "ipRangeVO.getUuid()", - "ipRangeVO.getNetworkCidr()", "msg.getL3NetworkUuid()" ], - "line": 149, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1504, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "ip[%s] in ip range[uuid:%s, startIp:%s, endIp:%s] which l3 network[%s] attached, this is not allowed", - "en_US": "ip[{0}] in ip range[uuid:{1}, startIp:{2}, endIp:{3}] which l3 network[{4}] attached, this is not allowed", - "zh_CN": "IP[{0}]在三层网络[{4}]绑定的IP范围内[uuid:{1}, startIp:{2}, endIp:{3}],这是不被允许的", + "raw": "failed tot attach virtual router network services to l3Network[uuid:%s]. When port forwarding is selected, snat must be selected too", + "en_US": "failed tot attach virtual router network services to l3Network[uuid:{0}]. When port forwarding is selected, snat must be selected too", + "zh_CN": "挂载虚拟路由网络服务到三层网络[uuid:{0}]失败。选中端口转发服务时,SNAT服务也必须被选中", "arguments": [ - "msg.getRouterInterfaceIp()", - "ipRangeVO.getUuid()", - "ipRangeVO.getStartIp()", - "ipRangeVO.getEndIp()", "msg.getL3NetworkUuid()" ], - "line": 153, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" - }, - { - "raw": "ipRangeUuid and l3NetworkUuid cannot both be null; you must set either one.", - "en_US": "ipRangeUuid and l3NetworkUuid cannot both be null; you must set either one.", - "zh_CN": "IP段和L3的uuid不能都为空,您必须选择一个填上", - "arguments": [], - "line": 167, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1508, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "%s is not a valid network cidr", - "en_US": "{0} is not a valid network cidr", - "zh_CN": "{0}不是有效的无类别域间路由", + "raw": "update virtual router [uuid:%s] default network failed, because %s", + "en_US": "update virtual router [uuid:{0}] default network failed, because {1}", + "zh_CN": "更新虚拟路由器[uuid:{0}]默认网络失败,原因是{1}", "arguments": [ - "msg.getNetworkCidr()" + "vrUuid", + "ret.getError()" ], - "line": 293, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 2445, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "%s is not a valid ipv6 address", - "en_US": "{0} is not a valid ipv6 address", - "zh_CN": "{0}不是有效的IPv6地址", + "raw": "invalid ApplianceVmType %s", + "en_US": "invalid ApplianceVmType {0}", + "zh_CN": "无效的设备VMType{0}", "arguments": [ - "msg.getGateway()" + "ss[1]" ], - "line": 214, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 2541, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" }, { - "raw": "[startIp %s, endIp %s, prefixLen %d, gateway %s] is not a valid ipv6 range", - "en_US": "[startIp {0}, endIp {1}, prefixLen {2}, gateway {3}] is not a valid ipv6 range", - "zh_CN": "IPv6地址段{0}-{1}/{2}, 网关{3}不是有效的IPv6地址段", + "raw": "unable to add dhcp entries to virtual router vm[uuid:%s ip:%s], because %s, dhcp entry[%s]", + "en_US": "unable to add dhcp entries to virtual router vm[uuid:{0} ip:{1}], because {2}, dhcp entry[{3}]", + "zh_CN": "无法向云路由[uuid:{0} ip:{1}]添加DHCP条目,因为{2},DHCP条目为[{3}]", "arguments": [ - "msg.getStartIp()", - "msg.getEndIp()", - "msg.getPrefixLen()", - "msg.getGateway()" + "vr.getUuid()", + "vr.getManagementNic().getIp()", + "rsp.getError()", + "JSONObjectUtil.toJsonString(info)" ], - "line": 218, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 93, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java" }, { - "raw": "ip range prefix length is out of range [%d - %d] ", - "en_US": "ip range prefix length is out of range [{0} - {1}] ", - "zh_CN": "IPv6地址前缀长度不在有效范围内[{0}-{1}]", + "raw": "no virtual router is configured for vyos dhcp", + "en_US": "no virtual router is configured for vyos dhcp", + "zh_CN": "没有为VyOS DHCP配置虚拟路由器", + "arguments": [], + "line": 375, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java" + }, + { + "raw": "unable to program dhcp entries served by virtual router[uuid:%s, ip:%s], %s", + "en_US": "unable to program dhcp entries served by virtual router[uuid:{0}, ip:{1}], {2}", + "zh_CN": "无法执行由云路由[uuid:{0}, ip:{1}]提供的DHCP条目{2}.", "arguments": [ - "IPv6Constants.IPV6_PREFIX_LEN_MIN", - "IPv6Constants.IPV6_PREFIX_LEN_MAX" + "vr.getUuid()", + "vr.getManagementNic().getIp()", + "ret.getError()" ], - "line": 228, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 208, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterSyncDHCPOnStartFlow.java" }, { - "raw": "l3 network [uuid %s: name %s] is not a ipv6 network", - "en_US": "l3 network [uuid {0}: name {1}] is not a ipv6 network", - "zh_CN": "三层网络[uuid:{0},名称{1}]不是IPv6网络", + "raw": "virtual router[uuid:%s, ip:%s] failed to configure dns%s for L3Network[uuid:%s, name:%s], %s", + "en_US": "virtual router[uuid:{0}, ip:{1}] failed to configure dns{2} for L3Network[uuid:{3}, name:{4}], {5}", + "zh_CN": "云路由[uuid:{0}, ip:{1}]未能为三层网络[uuid:{3}, name:{4}]配置DNS{2},错误细节: {5}", "arguments": [ - "l3Vo.getUuid()", - "l3Vo.getName()" + "vr.getUuid()", + "vr.getManagementNic().getIp()", + "struct", + "l3.getUuid()", + "l3.getName()", + "ret.getError()" ], - "line": 234, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 210, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterDnsBackend.java" }, { - "raw": "addressMode[%s] is different from L3Netowork address mode[%s]", - "en_US": "addressMode[{0}] is different from L3Netowork address mode[{1}]", - "zh_CN": "地址模式[{0}]和三层网络的地址模式[{1}]不同", + "raw": "virtual router[name: %s, uuid: %s] failed to configure dns%s, %s ", + "en_US": "virtual router[name: {0}, uuid: {1}] failed to configure dns{2}, {3} ", + "zh_CN": "云路由[name: {0}, uuid: {1}]未能配置DNS{2},错误细节: {3}", "arguments": [ - "ipr.getAddressMode()", - "rangeVOS.get(0).getAddressMode()" + "vr.getName()", + "vr.getUuid()", + "JSONObjectUtil.toJsonString(dns)", + "ret.getError()" ], - "line": 240, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 127, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java" }, { - "raw": "ipv6 prefix length must be %d for Stateless-DHCP or SLAAC", - "en_US": "ipv6 prefix length must be {0} for Stateless-DHCP or SLAAC", - "zh_CN": "Stateless-DHCP or SLAAC地址模式IPv6网络前缀长度必须是{0}", + "raw": "failed to create eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s", + "en_US": "failed to create eip[uuid:{0}, name:{1}, ip:{2}] for vm nic[uuid:{3}] on virtual router[uuid:{4}], {5}", + "zh_CN": "无法为云主机网卡[uuid:{3}]在云路由[uuid:{4}]上创建EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5}", "arguments": [ - "IPv6Constants.IPV6_STATELESS_PREFIX_LEN" + "struct.getEip().getUuid()", + "struct.getEip().getName()", + "struct.getVip().getIp()", + "struct.getNic().getUuid()", + "vr.getUuid()", + "ret.getError()" ], - "line": 246, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 168, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" }, { - "raw": "new ip range [startip :%s, endip :%s] is overlaped with old ip range[startip :%s, endip :%s]", - "en_US": "new ip range [startip :{0}, endip :{1}] is overlaped with old ip range[startip :{2}, endip :{3}]", - "zh_CN": "新的IP地址段[{0}-{1}]和旧的IP地址段[{2}-{3}]冲突", + "raw": "found a virtual router offering[uuid:%s] for L3Network[uuid:%s] in zone[uuid:%s]; however, the network\u0027s public network[uuid:%s] is not the same to EIP[uuid:%s]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", + "en_US": "found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network\u0027s public network[uuid:{3}] is not the same to EIP[uuid:{4}]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", + "zh_CN": "在区域(zone)[uuid:{2}]上为三层网络[uuid:{1}]找到了云路由规格[uuid:{0}];但是,其公共网络[uuid:{3}]和EIP[uuid:{4}]的公共网络不是同一个三层网络。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该三层网络指定一个特定的云路有规格", "arguments": [ - "ipr.getStartIp()", - "ipr.getEndIp()", - "r.getStartIp()", - "r.getEndIp()" + "offering.getUuid()", + "l3inv.getUuid()", + "l3inv.getZoneUuid()", + "struct.getVip().getL3NetworkUuid()", + "struct.getEip().getUuid()" ], - "line": 256, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 226, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" }, { - "raw": "new network CIDR [%s] is different from old network cidr [%s]", - "en_US": "new network CIDR [{0}] is different from old network cidr [{1}]", - "zh_CN": "同一L3网络上不能加载多个CIDR。", + "raw": "failed to remove eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s", + "en_US": "failed to remove eip[uuid:{0}, name:{1}, ip:{2}] for vm nic[uuid:{3}] on virtual router[uuid:{4}], {5}", + "zh_CN": "未能在云路由[uuid:{4}]上为云主机网卡[uuid:{3}]移除EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5}", "arguments": [ - "r.getNetworkCidr()", - "ipr.getNetworkCidr()" + "struct.getEip().getUuid()", + "struct.getEip().getName()", + "struct.getVip().getIp()", + "struct.getNic().getUuid()", + "vr.getUuid()", + "ret.getError()" ], - "line": 266, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 318, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" }, { - "raw": "new add ip range gateway %s is different from old gateway %s", - "en_US": "new add ip range gateway {0} is different from old gateway {1}", - "zh_CN": "新ip段的网关地址{0}和已有ip段的网关地址{1}冲突", + "raw": "failed to sync eip on virtual router[uuid:%s], %s", + "en_US": "failed to sync eip on virtual router[uuid:{0}], {1}", + "zh_CN": "未能在云路由[uuid:{0}]上同步EIP,错误细节: {1}", "arguments": [ - "ipr.getGateway()", - "r.getGateway()" + "vr.getUuid()", + "ret.getError()" ], - "line": 468, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 214, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java" }, { - "raw": "%s is not an allowed network cidr, because it doesn\u0027t have usable ip range", - "en_US": "{0} is not an allowed network cidr, because it doesn\u0027t have usable ip range", - "zh_CN": "{0}是不允许的无类别域间路由,因为它不支持可用的IP段", + "raw": "ha group extension point nil", + "en_US": "ha group extension point nil", + "zh_CN": "HA组扩展点Nil", + "arguments": [], + "line": 63, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaBackendImpl.java" + }, + { + "raw": "new add vm nics[uuids:%s] and attached vmnics are not on the same vrouter, they are on vrouters[uuids:%s]", + "en_US": "new add vm nics[uuids:{0}] and attached vmnics are not on the same vrouter, they are on vrouters[uuids:{1}]", + "zh_CN": "新添加的虚拟网卡[uuids:{0}]和绑定云主机的网卡没有在一个云路由上,它们分别在云路由[uuids:{1}]上", "arguments": [ - "msg.getNetworkCidr()" + "msg.getVmNicUuids()", + "vrUuids" ], - "line": 286, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 170, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" }, { - "raw": "%s is not the first or last address of the cidr %s", - "en_US": "{0} is not the first or last address of the cidr {1}", - "zh_CN": "", + "raw": "new add vm nics[uuids:%s] and peer l3s[uuids:%s] of loadbalancer[uuid: %s]\u0027s vip are not on the same vrouter, they are on vrouters[uuids:%s]", + "en_US": "new add vm nics[uuids:{0}] and peer l3s[uuids:{1}] of loadbalancer[uuid: {2}]\u0027s vip are not on the same vrouter, they are on vrouters[uuids:{3}]", + "zh_CN": "新添加的云主机网卡[uuids:{0}]和负载均衡器[uuid: {2}]的弹性IP的三层网络[uuids:{1}]没有在相同的云路由上,它们分别在云路由[uuids:{3}]上", "arguments": [ - "msg.getGateway()", - "msg.getNetworkCidr()" + "msg.getVmNicUuids()", + "peerL3NetworkUuids", + "msg.getLoadBalancerUuid()", + "vrUuids" ], - "line": 290, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 200, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" }, { - "raw": "ipRangeUuids, L3NetworkUuids, zoneUuids must have at least one be none-empty list, or all is set to true", - "en_US": "ipRangeUuids, L3NetworkUuids, zoneUuids must have at least one be none-empty list, or all is set to true", - "zh_CN": "ipRangeUuids, L3NetworkUuids, zoneUuids 至少一个不是为空列表,或者全部不为空", + "raw": "vmnic must be specified for share loadbalancer", + "en_US": "vmnic must be specified for share loadbalancer", + "zh_CN": "必须为Share LoadBalancer指定vmnic", "arguments": [], - "line": 313, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1320, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" }, { - "raw": "unsupported l3network type[%s]", - "en_US": "unsupported l3network type[{0}]", - "zh_CN": "不支持的L3网络类型[{0}]", + "raw": "cannot find virtual router for load balancer [uuid:%s]", + "en_US": "cannot find virtual router for load balancer [uuid:{0}]", + "zh_CN": "未能为负载均衡器[uuid:{0}]找到云路由", "arguments": [ - "msg.getType()" + "struct.getLb().getUuid()" ], - "line": 334, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 1778, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" }, { - "raw": "%s is not a valid domain name", - "en_US": "{0} is not a valid domain name", - "zh_CN": "{0}不是有效的域名", + "raw": "guest l3Network[uuid:%s, name:%s] needs SNAT service provided by virtual router, but public l3Network[uuid:%s] of virtual router offering[uuid: %s, name:%s] is the same to this guest l3Network", + "en_US": "guest l3Network[uuid:{0}, name:{1}] needs SNAT service provided by virtual router, but public l3Network[uuid:{2}] of virtual router offering[uuid: {3}, name:{4}] is the same to this guest l3Network", + "zh_CN": "用户三层网络[uuid:{0}, name:{1}]需要云路由提供的SNAT服务,但是云路由规格[uuid: {3}, name:{4}]的公共三层网络[uuid:{2}]与该客户三层网络相同", "arguments": [ - "msg.getDnsDomain()" + "guestL3.getUuid()", + "guestL3.getName()", + "offering.getPublicNetworkUuid()", + "offering.getUuid()", + "offering.getName()" ], - "line": 340, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 91, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java" }, { - "raw": "l3 network [uuid %s: name %s] is not a ipv4 network", - "en_US": "l3 network [uuid {0}: name {1}] is not a ipv4 network", - "zh_CN": "三层网络[uuid:{0},name:{1}]不是IPv4网络", + "raw": "virtual router[name: %s, uuid: %s] failed to sync snat%s, %s", + "en_US": "virtual router[name: {0}, uuid: {1}] failed to sync snat{2}, {3}", + "zh_CN": "云路由[name: {0}, uuid: {1}]未能同步SNAT{2},错误细节: {3}", "arguments": [ - "l3Vo.getUuid()", - "l3Vo.getName()" + "vr.getName()", + "vr.getUuid()", + "JSONObjectUtil.toJsonString(snatInfo)", + "ret.getError()" ], - "line": 382, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 144, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java" }, { - "raw": "the IP range[%s ~ %s] contains D class addresses which are for multicast", - "en_US": "the IP range[{0} ~ {1}] contains D class addresses which are for multicast", - "zh_CN": "这个IP段[{0} ~ {1}]包含了D类的组播地址", + "raw": "failed to create port forwarding rule[vip ip: %s, private ip: %s, vip start port: %s, vip end port: %s, private start port: %s, private end port: %s], because %s", + "en_US": "failed to create port forwarding rule[vip ip: {0}, private ip: {1}, vip start port: {2}, vip end port: {3}, private start port: {4}, private end port: {5}], because {6}", + "zh_CN": "无法创建端口转发规则[vip ip: {0}, private ip: {1}, vip start port: {2}, vip end port: {3}, private start port: {4}, private end port: {5}],错误细节: {6}", "arguments": [ - "ipr.getStartIp()", - "ipr.getEndIp()" + "to.getVipIp()", + "to.getPrivateIp()", + "to.getVipPortStart()", + "to.getVipPortEnd()", + "to.getPrivatePortStart()", + "to.getPrivatePortEnd()", + "ret.getError()" ], - "line": 386, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 85, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ApplyPortforwardingRuleOnVirtualRouterVmFlow.java" }, { - "raw": "the IP range[%s ~ %s] contains E class addresses which are reserved", - "en_US": "the IP range[{0} ~ {1}] contains E class addresses which are reserved", - "zh_CN": "这个IP段[{0} ~ {1}]包含了E类的保留地址", + "raw": "failed to revoke port forwarding rules %s, because %s", + "en_US": "failed to revoke port forwarding rules {0}, because {1}", + "zh_CN": "未能解除端口转发规则{0},原因: {1}", "arguments": [ - "ipr.getStartIp()", - "ipr.getEndIp()" + "JSONObjectUtil.toJsonString(to)", + "ret.getError()" ], - "line": 390, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 82, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ReleasePortForwardingRuleOnVirtualRouterVmFlow.java" }, { - "raw": "the IP range[%s ~ %s] contains link local addresses which are reserved", - "en_US": "the IP range[{0} ~ {1}] contains link local addresses which are reserved", - "zh_CN": "这个IP段[{0} ~ {1}]包含了本地的保留地址", + "raw": "found a virtual router offering[uuid:%s] for L3Network[uuid:%s] in zone[uuid:%s]; however, the network\u0027s public network[uuid:%s] is not the same to PortForwarding rule[uuid:%s]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", + "en_US": "found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network\u0027s public network[uuid:{3}] is not the same to PortForwarding rule[uuid:{4}]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", + "zh_CN": "在区域(zone)[uuid:{2}]内为三层网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和端口转发规则[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该三层网络指定一个特定的云路有规格", "arguments": [ - "ipr.getStartIp()", - "ipr.getEndIp()" + "offering.getUuid()", + "struct.getGuestL3Network().getUuid()", + "struct.getGuestL3Network().getZoneUuid()", + "struct.getVip().getL3NetworkUuid()", + "struct.getRule().getUuid()" ], - "line": 394, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 184, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" }, { - "raw": "the gateway[%s] is not in the subnet %s/%s", - "en_US": "the gateway[{0}] is not in the subnet {1}/{2}", - "zh_CN": "网关[{0}]不在子网{1}/{2}", + "raw": "virtual router doesn\u0027t support port forwarding range redirection, the vipPortStart must be equals to privatePortStart and vipPortEnd must be equals to privatePortEnd;but this rule rule has a mismatching range: vip port[%s, %s], private port[%s, %s]", + "en_US": "virtual router doesn\u0027t support port forwarding range redirection, the vipPortStart must be equals to privatePortStart and vipPortEnd must be equals to privatePortEnd;but this rule rule has a mismatching range: vip port[{0}, {1}], private port[{2}, {3}]", + "zh_CN": "云路由不支持范围性的端口转发重定向,vipPortStart和privatePortStart必须一致,vipPortEnd和privatePortEnd必须一致,但这条规则有个不匹配的范围: vip端口范围[{0}, {1}],私有端口范围[{2}, {3}]", "arguments": [ - "ipr.getGateway()", - "ipr.getStartIp()", - "ipr.getNetmask()" + "rule.getVipPortStart()", + "rule.getVipPortEnd()", + "rule.getPrivatePortStart()", + "rule.getPrivatePortEnd()" ], - "line": 400, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 249, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" }, { - "raw": "the endip[%s] is not in the subnet %s/%s", - "en_US": "the endip[{0}] is not in the subnet {1}/{2}", - "zh_CN": "IP段结束地址不在子网{1}/{2}范围内", + "raw": "failed to add portforwardings on virtual router[uuid:%s], %s", + "en_US": "failed to add portforwardings on virtual router[uuid:{0}], {1}", + "zh_CN": "在云路由[uuid:{0}]添加端口转发失败,{1}", "arguments": [ - "ipr.getEndIp()", - "ipr.getStartIp()", - "ipr.getNetmask()" + "vrVO.getUuid()", + "ret.getError()" ], - "line": 404, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 408, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" }, { - "raw": "start ip[%s] is not a IPv4 address", - "en_US": "start ip[{0}] is not a IPv4 address", - "zh_CN": "开始的ip[{0}] 不是IPV4的地址", + "raw": "failed to revoke port forwardings on virtual router[uuid:%s], %s", + "en_US": "failed to revoke port forwardings on virtual router[uuid:{0}], {1}", + "zh_CN": "取消在云路由[uuid:{0}]上端口转发服务失败,{1}", "arguments": [ - "ipr.getStartIp()" + "vrVO.getUuid()", + "ret.getError()" ], - "line": 408, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 484, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" }, { - "raw": "end ip[%s] is not a IPv4 address", - "en_US": "end ip[{0}] is not a IPv4 address", - "zh_CN": "结束的ip[{0}] 不是IPV4的地址", + "raw": "failed to sync port forwarding rules served by virtual router[name: %s, uuid: %s], because %s", + "en_US": "failed to sync port forwarding rules served by virtual router[name: {0}, uuid: {1}], because {2}", + "zh_CN": "未能同步由云路由[name: {0}, uuid: {1}]提供的端口转发规则,因为: {2}", "arguments": [ - "ipr.getEndIp()" + "vr.getName()", + "vr.getUuid()", + "ret.getError()" ], - "line": 412, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 212, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java" }, { - "raw": "gateway[%s] is not a IPv4 address", - "en_US": "gateway[{0}] is not a IPv4 address", - "zh_CN": "网关[{0}]不是IPV4的地址", + "raw": "failed to remove vip%s, because %s", + "en_US": "failed to remove vip{0}, because {1}", + "zh_CN": "未能移除VIP{0},因为{1}", "arguments": [ - "ipr.getGateway()" + "tos", + "ret.getError()" ], - "line": 416, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 179, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java" }, { - "raw": "netmask[%s] is not a netmask, and the IP range netmask cannot be 0.0.0.0", - "en_US": "netmask[{0}] is not a netmask, and the IP range netmask cannot be 0.0.0.0", - "zh_CN": "子网掩码[{0}]不是子网掩码,并且IP段的子网掩码不能是0.0.0.0", + "raw": "failed to create vip%s on virtual router[uuid:%s], because %s", + "en_US": "failed to create vip{0} on virtual router[uuid:{1}], because {2}", + "zh_CN": "未能在云路由[uuid:{1}]上创建VIP{0},因为{2}", "arguments": [ - "ipr.getNetmask()" + "tos", + "vr.getUuid()", + "ret.getError()" ], - "line": 420, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 125, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java" }, { - "raw": "ip allocation can not contain network address or broadcast address", - "en_US": "ip allocation can not contain network address or broadcast address", - "zh_CN": "ip 地址分配不能包含网络地址或广播的地址", - "arguments": [], - "line": 424, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "raw": "failed to sync vips[ips: %s] on virtual router[uuid:%s] for attaching nic[uuid: %s, ip: %s], because %s", + "en_US": "failed to sync vips[ips: {0}] on virtual router[uuid:{1}] for attaching nic[uuid: {2}, ip: {3}], because {4}", + "zh_CN": "为了绑定网卡[uuid: {2}, ip: {3}]在云路由[uuid:{1}]上同步虚拟IP[ips: {0}]失败,因为{4}", + "arguments": [ + "vips.stream().map(VipTO::getIp).collect(Collectors.toList())", + "nic.getVmInstanceUuid()", + "nic.getUuid()", + "nic.getIp()", + "ret.getError()" + ], + "line": 245, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java" }, { - "raw": "start ip[%s] is behind end ip[%s]", - "en_US": "start ip[{0}] is behind end ip[{1}]", - "zh_CN": "起始ip[{0}]在尾ip[{1}]后", + "raw": "virtual router[uuid:%s, state:%s] is not running", + "en_US": "virtual router[uuid:{0}, state:{1}] is not running", + "zh_CN": "云路由[uuid:{0}, state:{1}]没有运行", "arguments": [ - "ipr.getStartIp()", - "ipr.getEndIp()" + "vrUuid", + "vrState" ], - "line": 432, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 240, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java" }, { - "raw": "gateway[%s] can not be part of range[%s, %s]", - "en_US": "gateway[{0}] can not be part of range[{1}, {2}]", - "zh_CN": "网关[{0}]不能是IP段[{1}, {2}]的一部分", + "raw": "found a virtual router offering[uuid:%s] for L3Network[uuid:%s] in zone[uuid:%s]; however, the network\u0027s public network[uuid:%s] is not the same to VIP[uuid:%s]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", + "en_US": "found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network\u0027s public network[uuid:{3}] is not the same to VIP[uuid:{4}]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", + "zh_CN": "在区域(zone)[uuid:{2}]内为三层网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和VIP[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该三层网络指定一个特定的云路有规格", "arguments": [ - "ipr.getGateway()", - "ipr.getStartIp()", - "ipr.getEndIp()" + "offering.getUuid()", + "s.getL3Network().getUuid()", + "s.getL3Network().getZoneUuid()", + "self.getL3NetworkUuid()", + "self.getUuid()" ], - "line": 437, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 281, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java" }, { - "raw": "overlap with ip range[uuid:%s, start ip:%s, end ip: %s]", - "en_US": "overlap with ip range[uuid:{0}, start ip:{1}, end ip: {2}]", - "zh_CN": "重叠的IP段[uuid:{0}, 起始ip:{1}, 尾ip: {2}]", + "raw": "failed to change nic[ip:%s, mac:%s] firewall default action of virtual router vm[uuid:%s], because %s", + "en_US": "failed to change nic[ip:{0}, mac:{1}] firewall default action of virtual router vm[uuid:{2}], because {3}", + "zh_CN": "修改云路由[uuid:{2}]的网卡[ip:{0}, mac:{1}]的默认防火墙规则失败,因为{3}", "arguments": [ - "r.getUuid()", - "r.getStartIp()", - "r.getEndIp()" + "nic.getIp()", + "nic.getMac()", + "nic.getVmInstanceUuid()", + "rsp.getError()" ], - "line": 448, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 67, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosChangePrivateL3FirewallDefaultActionExtensionPoint.java" }, { - "raw": "multiple CIDR on the same L3 network is not allowed. There has been a IP range[uuid:%s, CIDR:%s], the new IP range[CIDR:%s] is not in the CIDR with the existing one", - "en_US": "multiple CIDR on the same L3 network is not allowed. There has been a IP range[uuid:{0}, CIDR:{1}], the new IP range[CIDR:{2}] is not in the CIDR with the existing one", - "zh_CN": "在相同的三层网络上多个CIDR是不允许的,已有的IP范围 [uuid: {0},CIDR: {1}]。新的IP范围 [CIDR: {2}] 不在现有的一个CIDR", + "raw": "unable to ssh in to the virtual router[%s] after configure ssh", + "en_US": "unable to ssh in to the virtual router[{0}] after configure ssh", + "zh_CN": "配置SSH后,无法通过SSH连接到虚拟路由器[{0}]", "arguments": [ - "r.getUuid()", - "rcidr", - "cidr" + "mgmtNicIp" ], - "line": 458, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 156, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java" }, { - "raw": "%s[%s] is not a IPv6 address", - "en_US": "{0}[{1}] is not a IPv6 address", - "zh_CN": "{0}[{1}]不是IPv6地址", + "raw": "vyos init command failed, because:%s", + "en_US": "vyos init command failed, because:{0}", + "zh_CN": "vyos init命令失败,原因是:{0}", "arguments": [ - "manner", - "ip" + "ret.getError()" ], - "line": 490, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 214, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java" }, { - "raw": "%s[%s] is not a IPv4 address", - "en_US": "{0}[{1}] is not a IPv4 address", - "zh_CN": "{0}[{1}]不是IPv4地址", + "raw": "unable to start dhcp server on virtual router vm[uuid:%s], because %s", + "en_US": "unable to start dhcp server on virtual router vm[uuid:{0}], because {1}", + "zh_CN": "无法在虚拟路由器VM[uuid:{0}]上启动DHCP服务器,因为{1}", "arguments": [ - "manner", - "ip" + "nic.getVmInstanceUuid()", + "rsp.getError()" ], - "line": 486, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 246, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDhcpBackend.java" }, { - "raw": "there has been a DNS[%s] on L3 network[uuid:%s]", - "en_US": "there has been a DNS[{0}] on L3 network[uuid:{1}]", - "zh_CN": "在L3网络[uuid:{1}]上已经存在一个DNS[{0}]", + "raw": "unable to stop dhcp server on virtual router vm[uuid:%s], because %s", + "en_US": "unable to stop dhcp server on virtual router vm[uuid:{0}], because {1}", + "zh_CN": "无法停止虚拟路由器VM[uuid:{0}]上的DHCP服务器,因为{1}", "arguments": [ - "msg.getDns()", - "msg.getL3NetworkUuid()" + "nic.getVmInstanceUuid()", + "rsp.getError()" ], - "line": 502, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 282, + "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDhcpBackend.java" }, { - "raw": "prefix [%s] is not a IPv4 network cidr", - "en_US": "prefix [{0}] is not a IPv4 network cidr", - "zh_CN": "网络段{0}不是合法的网络段", + "raw": "File reference not fount for disk %s", + "en_US": "File reference not fount for disk {0}", + "zh_CN": "找不到磁盘{0}的文件引用", "arguments": [ - "msg.getL3NetworkUuid()" + "id" ], - "line": 525, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 104, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "nexthop[%s] is not a IPv4 address", - "en_US": "nexthop[{0}] is not a IPv4 address", - "zh_CN": "下一跳{0}不是有效的IP地址", + "raw": "Illegal disk capacity: %s", + "en_US": "Illegal disk capacity: {0}", + "zh_CN": "非法磁盘容量:{0}", "arguments": [ - "msg.getNexthop()" + "capacity" ], - "line": 512, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 117, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "there has been a hostroute for prefix[%s] on L3 network[uuid:%s]", - "en_US": "there has been a hostroute for prefix[{0}] on L3 network[uuid:{1}]", - "zh_CN": "三层网络{1}已配置主机路由{0}", + "raw": "Illegal disk populated size: %s", + "en_US": "Illegal disk populated size: {0}", + "zh_CN": "非法的磁盘填充大小:{0}", "arguments": [ - "msg.getPrefix()", - "msg.getL3NetworkUuid()" + "pSize" ], - "line": 519, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 127, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "there is no hostroute for prefix[%s] on L3 network[uuid:%s]", - "en_US": "there is no hostroute for prefix[{0}] on L3 network[uuid:{1}]", - "zh_CN": "三层网络{1}没有主机路由{0}", + "raw": "Volume controller not found.", + "en_US": "Volume controller not found.", + "zh_CN": "未找到卷控制器。", + "arguments": [], + "line": 288, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" + }, + { + "raw": "CD Driver controller not found.", + "en_US": "CD Driver controller not found.", + "zh_CN": "找不到光驱控制器。", + "arguments": [], + "line": 320, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" + }, + { + "raw": "Ethernet Adapter: %s do not connect to a network.", + "en_US": "Ethernet Adapter: {0} do not connect to a network.", + "zh_CN": "以太网适配器:{0}不要连接到网络。", "arguments": [ - "msg.getPrefix()", - "msg.getL3NetworkUuid()" + "name" ], - "line": 532, - "fileName": "src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java" + "line": 368, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "VM nics[uuids:%s] are not on L3 networks that have been attached to the security group[uuid:%s]", - "en_US": "VM nics[uuids:{0}] are not on L3 networks that have been attached to the security group[uuid:{1}]", - "zh_CN": "云主机网卡[uuids:{0}]不在安全组[uuid:{1}]挂载的L3网络上", + "raw": "Memory \u0027InstanceID\u0027 not found", + "en_US": "Memory \u0027InstanceID\u0027 not found", + "zh_CN": "未找到内存“ instanceId ”", + "arguments": [], + "line": 380, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" + }, + { + "raw": "Memory \u0027VirtualQuantity\u0027 not found", + "en_US": "Memory \u0027VirtualQuantity\u0027 not found", + "zh_CN": "未找到内存“ virtualQuantity ”", + "arguments": [], + "line": 387, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" + }, + { + "raw": "Illegal Memory \u0027VirtualQuantity\u0027 value: %s", + "en_US": "Illegal Memory \u0027VirtualQuantity\u0027 value: {0}", + "zh_CN": "非法内存“ virtualQuantity ”值:{0}", "arguments": [ - "wrongUuids", - "securityGroupUuid" + "quantity" ], - "line": 171, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 392, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "security group[uuid:%s] has not attached to l3Network[uuid:%s], can\u0027t detach", - "en_US": "security group[uuid:{0}] has not attached to l3Network[uuid:{1}], can\u0027t detach", - "zh_CN": "不能卸载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为还未挂载", + "raw": "CPU \u0027InstanceID\u0027 not found", + "en_US": "CPU \u0027InstanceID\u0027 not found", + "zh_CN": "未找到CPU “ instanceId ”", + "arguments": [], + "line": 401, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" + }, + { + "raw": "CPU \u0027VirtualQuantity\u0027 not found", + "en_US": "CPU \u0027VirtualQuantity\u0027 not found", + "zh_CN": "未找到CPU \u0027 virtualQuantity \u0027", + "arguments": [], + "line": 407, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" + }, + { + "raw": "Illegal CPU \u0027VirtualQuantity\u0027 value: %s", + "en_US": "Illegal CPU \u0027VirtualQuantity\u0027 value: {0}", + "zh_CN": "非法的CPU “ VirtualQuantity ”值:{0}", "arguments": [ - "msg.getSecurityGroupUuid()", - "msg.getL3NetworkUuid()" + "quantity" ], - "line": 69, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 412, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "security group[uuid:%s] has attached to l3Network[uuid:%s], can\u0027t attach again", - "en_US": "security group[uuid:{0}] has attached to l3Network[uuid:{1}], can\u0027t attach again", - "zh_CN": "不能再次挂载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为已经挂载了", + "raw": "Illegal CPU \u0027CoresPerSocket\u0027 value: %s", + "en_US": "Illegal CPU \u0027CoresPerSocket\u0027 value: {0}", + "zh_CN": "非法的CPU “ CoreSperSocket ”值:{0}", "arguments": [ - "msg.getSecurityGroupUuid()", - "msg.getL3NetworkUuid()" + "cps" ], - "line": 117, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 422, + "fileName": "src/main/java/org/zstack/ovf/OvfHelper.java" }, { - "raw": "the L3 network[uuid:%s] doesn\u0027t have the network service type[%s] enabled", - "en_US": "the L3 network[uuid:{0}] doesn\u0027t have the network service type[{1}] enabled", - "zh_CN": "L3网络[uuid:{0}]没有开启[{1}]类型的网络服务", + "raw": "long job[uuid:%s] execute fail", + "en_US": "long job[uuid:{0}] execute fail", + "zh_CN": "长作业[uuid:{0}]执行失败", "arguments": [ - "msg.getL3NetworkUuid()", - "SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE" + "failLongJobUuids" ], - "line": 125, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 156, + "fileName": "src/main/java/org/zstack/ovf/OvfImageUploadTracker.java" }, { - "raw": "the L3 network[uuid:%s] ipVersion [%d] is different from securityGroup [uuid:%s] ipVersion [%d]", - "en_US": "the L3 network[uuid:{0}] ipVersion [{1}] is different from securityGroup [uuid:{2}] ipVersion [{3}]", - "zh_CN": "", + "raw": "Vm[uuid: %s] is already exported as the ova package[uuid: %s], please delete the package and try again.", + "en_US": "Vm[uuid: {0}] is already exported as the ova package[uuid: {1}], please delete the package and try again.", + "zh_CN": "VM[uuid:{0}]已作为OVA程序包[uuid:{1}]导出,请删除该程序包,然后重试。", "arguments": [ - "msg.getL3NetworkUuid()", - "l3Vo.getIpVersion()", - "msg.getSecurityGroupUuid()", - "sgVo.getIpVersion()" + "msg.getVmUuid()", + "ovaUuid" ], - "line": 131, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 69, + "fileName": "src/main/java/org/zstack/ovf/OvfInterceptor.java" }, { - "raw": "rule type can not be null. rule dump: %s", - "en_US": "rule type can not be null. rule dump: {0}", - "zh_CN": "规则类型(rule type)不能为空(null)。规则内容为: {0}", + "raw": "Export vm requires an ImageStore backup storage, but given backupStorageUuid: %s is not an ImageStore backup storage.", + "en_US": "Export vm requires an ImageStore backup storage, but given backupStorageUuid: {0} is not an ImageStore backup storage.", + "zh_CN": "导出VM需要ImageStore备份存储,但给定的BackupStorageUuid{0}不是ImageStore备份存储。", "arguments": [ - "JSONObjectUtil.toJsonString(ao)" + "msg.getBackupStorageUuid()" ], - "line": 214, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 77, + "fileName": "src/main/java/org/zstack/ovf/OvfInterceptor.java" }, { - "raw": "unknown rule type[%s], rule can only be Ingress/Egress. rule dump: %s", - "en_US": "unknown rule type[{0}], rule can only be Ingress/Egress. rule dump: {1}", - "zh_CN": "未知的规则类型(rule type)[{0}],规则类型只能为Ingress/Egress。规则内容为: {1}", + "raw": "Not found the vm to be exported with the uuid: %s", + "en_US": "Not found the vm to be exported with the uuid: {0}", + "zh_CN": "未找到uuid为{0}的要导出的VM", "arguments": [ - "ao.getType()", - "JSONObjectUtil.toJsonString(ao)" + "msg.getVmUuid()" ], - "line": 219, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 84, + "fileName": "src/main/java/org/zstack/ovf/OvfInterceptor.java" }, { - "raw": "protocol can not be null. rule dump: %s", - "en_US": "protocol can not be null. rule dump: {0}", - "zh_CN": "协议(protocol)不能为空(null)。规则内容为: {0}", + "raw": "Only vm in state: %s can be exported.", + "en_US": "Only vm in state: {0} can be exported.", + "zh_CN": "只能导出状态为{0}的云主机。", "arguments": [ - "JSONObjectUtil.toJsonString(ao)" + "VmInstanceState.Stopped.toString()" ], - "line": 225, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 89, + "fileName": "src/main/java/org/zstack/ovf/OvfInterceptor.java" + }, + { + "raw": "failed to parse jsonCreateVmParam in APICreateVmInstanceFromOvfMsg", + "en_US": "failed to parse jsonCreateVmParam in APICreateVmInstanceFromOvfMsg", + "zh_CN": "无法分析APICreateVmInstanceFromOvFMsg中的JsonCreateVmParam", + "arguments": [], + "line": 114, + "fileName": "src/main/java/org/zstack/ovf/OvfInterceptor.java" }, { - "raw": "invalid protocol[%s]. Valid protocols are [TCP, UDP, ICMP, ALL]. rule dump: %s", - "en_US": "invalid protocol[{0}]. Valid protocols are [TCP, UDP, ICMP, ALL]. rule dump: {1}", - "zh_CN": "无效的协议(protocol)[{0}]。有效的协议类型为[TCP,UDP,ICMP,ALL]。规则内容为: {1}", + "raw": "backup storage[uuid: %s] does not have enough available capacity for exporting vm[uuid: %s], required capacity is: %d", + "en_US": "backup storage[uuid: {0}] does not have enough available capacity for exporting vm[uuid: {1}], required capacity is: {2}", + "zh_CN": "备份存储[uuid:{0}]没有足够的可用容量来导出云主机[uuid:{1}],所需容量为:{2}", "arguments": [ - "ao.getProtocol()", - "JSONObjectUtil.toJsonString(ao)" + "msg.getBackupStorageUuid()", + "msg.getVmUuid()", + "totalSize" ], - "line": 231, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 229, + "fileName": "src/main/java/org/zstack/ovf/OvfManagerImpl.java" }, { - "raw": "can not set port for protocol [type:ALL]. rule dump: %s", - "en_US": "can not set port for protocol [type:ALL]. rule dump: {0}", - "zh_CN": "不能为协议类型为 ALL 的规则指定端口号,规则为:{0}", + "raw": "ova package[uuid: %s] not found.", + "en_US": "ova package[uuid: {0}] not found.", + "zh_CN": "未找到OVA程序包[uuid:{0}]。", "arguments": [ - "JSONObjectUtil.toJsonString(ao)" + "msg.getUuid()" ], - "line": 238, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 629, + "fileName": "src/main/java/org/zstack/ovf/OvfManagerImpl.java" }, { - "raw": "startPort can not be null. rule dump: %s", - "en_US": "startPort can not be null. rule dump: {0}", - "zh_CN": "起始端口(startPort)不能为空(null)。规则内容为: {0}", + "raw": "Failed to read ovf file.", + "en_US": "Failed to read ovf file.", + "zh_CN": "无法读取OVF文件。", + "arguments": [], + "line": 757, + "fileName": "src/main/java/org/zstack/ovf/OvfManagerImpl.java" + }, + { + "raw": "failed to create VM from OVF because the root disk of the VM cannot be found", + "en_US": "failed to create VM from OVF because the root disk of the VM cannot be found", + "zh_CN": "无法从OVF创建VM,因为找不到VM的根磁盘", + "arguments": [], + "line": 1028, + "fileName": "src/main/java/org/zstack/ovf/OvfManagerImpl.java" + }, + { + "raw": "pci device[uuid:%s] doesn\u0027t exist", + "en_US": "pci device[uuid:{0}] doesn\u0027t exist", + "zh_CN": "PCI设备[uuid:{0}]不存在", "arguments": [ - "JSONObjectUtil.toJsonString(ao)" + "msg.getPciDeviceUuid()" ], - "line": 236, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 417, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "invalid startPort[%s]. Valid range is [0, 65535]. rule dump: %s", - "en_US": "invalid startPort[{0}]. Valid range is [0, 65535]. rule dump: {1}", - "zh_CN": "无效的起始端口(startPort)[{0}]。有效的范围为[0,65535]。规则内容为: {1}", + "raw": "could not enable sriov for device because iommu is disabled on host[uuid:%s]", + "en_US": "could not enable sriov for device because iommu is disabled on host[uuid:{0}]", + "zh_CN": "无法为设备启用SRIOV,因为已在物理机[uuid:{0}]上禁用IOMMU", "arguments": [ - "ao.getStartPort()", - "JSONObjectUtil.toJsonString(ao)" + "pci.getHostUuid()" ], - "line": 250, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 422, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "invalid ICMP type[%s]. Valid type is [-1, 255]. rule dump: %s", - "en_US": "invalid ICMP type[{0}]. Valid type is [-1, 255]. rule dump: {1}", - "zh_CN": "无效的ICMP类型[{0}]。有效的类型为[-1,255]。规则内容为: {1}", + "raw": "pci devices in host[uuid:%s] already sriov virtualized", + "en_US": "pci devices in host[uuid:{0}] already sriov virtualized", + "zh_CN": "物理机[uuid:{0}]上的PCI设备已经SRIOV虚拟化,无法再次切分", "arguments": [ - "ao.getStartPort()", - "JSONObjectUtil.toJsonString(ao)" + "pci.getHostUuid()" ], - "line": 243, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 468, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "invalid endPort[%s]. Valid range is [0, 65535]. rule dump: %s", - "en_US": "invalid endPort[{0}]. Valid range is [0, 65535]. rule dump: {1}", - "zh_CN": "无效的结束端口(endPort)[{0}]。有效的范围为[0,65535]。规则内容为: {1}", + "raw": "cannot sr-iov virtualize pci devices in host[uuid:%s] that are attached to vm", + "en_US": "cannot sr-iov virtualize pci devices in host[uuid:{0}] that are attached to vm", + "zh_CN": "物理机[uuid:{0}]上的PCI设备已经挂载到云主机,无法SRIOV虚拟化", "arguments": [ - "ao.getEndPort()", - "JSONObjectUtil.toJsonString(ao)" + "pci.getHostUuid()" ], - "line": 269, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 473, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "invalid ICMP code[%s]. Valid range is [-1, 3]. rule dump: %s", - "en_US": "invalid ICMP code[{0}]. Valid range is [-1, 3]. rule dump: {1}", - "zh_CN": "无效的ICMP编码[{0}]。有效的范围为[-1,3]。规则内容为: {1}", + "raw": "only %d virtual pci devices can be generated by %ss in host[uuid:%s]", + "en_US": "only {0} virtual pci devices can be generated by {1}s in host[uuid:{2}]", + "zh_CN": "物理机[uuid:{2}]上的{1}类型PCI设备最多被切分出{0}个虚拟PCI设备", "arguments": [ - "ao.getEndPort()", - "JSONObjectUtil.toJsonString(ao)" + "minIns", + "pci.getType()", + "pci.getHostUuid()" ], - "line": 262, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 487, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "invalid CIDR[%s]. rule dump: %s", - "en_US": "invalid CIDR[{0}]. rule dump: {1}", - "zh_CN": "无效的CIDR[{0}]。规则内容为: {1}", + "raw": "the host[uuid:%s] that pci device[uuid:%s] in is not Connected", + "en_US": "the host[uuid:{0}] that pci device[uuid:{1}] in is not Connected", + "zh_CN": "PCI设备[uuid:{1}]所在物理机[uuid:{0}]已失联", "arguments": [ - "ao.getAllowedCidr()", - "JSONObjectUtil.toJsonString(ao)" + "pci.getHostUuid()", + "pci.getUuid()" ], - "line": 279, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 609, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "security group rule ipVersion [%d] is different from security group version [%d]", - "en_US": "security group rule ipVersion [{0}] is different from security group version [{1}]", - "zh_CN": "远端安全组IP协议号[{0}]和本地安全组的IP协议号[{1}]", + "raw": "cannot sr-iov virtualize pci devices on interface[uuid:%s] that are been bonded", + "en_US": "cannot sr-iov virtualize pci devices on interface[uuid:{0}] that are been bonded", + "zh_CN": "SR-IOV无法虚拟化已绑定的接口[uuid:{0}]上的PCI设备", "arguments": [ - "sgVo.getIpVersion()", - "ao.getIpVersion()" + "interfaceVO.getUuid()" ], - "line": 283, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 505, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "rule should not be duplicated. rule dump: %s", - "en_US": "rule should not be duplicated. rule dump: {0}", - "zh_CN": "规则不应该重复。规则内容为: {0}", + "raw": "pci device[uuid:%s] doesn\u0027t exist or is not sriov virtualized", + "en_US": "pci device[uuid:{0}] doesn\u0027t exist or is not sriov virtualized", + "zh_CN": "PCI设备[uuid:{0}]不存在,或者未处于SRIOV虚拟化状态", "arguments": [ - "JSONObjectUtil.toJsonString(msg.getRules().get(j))" + "msg.getPciDeviceUuid()" ], - "line": 292, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 513, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "rule exist. rule dump: %s, remoteSecurityGroupUuid:[%s]", - "en_US": "rule exist. rule dump: {0}, remoteSecurityGroupUuid:[{1}]", - "zh_CN": "规则已存在,规则内容为:{0},源安全组[uuid:{1}]", + "raw": "virtual pci devices generated from pci devices in host[uuid:%s] still attached to vm", + "en_US": "virtual pci devices generated from pci devices in host[uuid:{0}] still attached to vm", + "zh_CN": "物理机[uuid:{0}]上存在仍处于已挂载状态的虚拟PCI设备,无法执行虚拟化还原操作", "arguments": [ - "JSONObjectUtil.toJsonString(sao)", - "svo.getRemoteSecurityGroupUuid()" + "pci.getHostUuid()" ], - "line": 318, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 528, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "remote security group ipVersion [%d] is different from security group version [%d]", - "en_US": "remote security group ipVersion [{0}] is different from security group version [{1}]", - "zh_CN": "远端安全组IP协议号[{0}]和安全组协议号[{1}]不一致", + "raw": "pci device[uuid:%s] cannot be virtualized into mdevs, make sure it\u0027s enabled and un-attached", + "en_US": "pci device[uuid:{0}] cannot be virtualized into mdevs, make sure it\u0027s enabled and un-attached", + "zh_CN": "PCI设备[uuid:{0}]无法被切分为MDEV设备,请确保它处于启用状态,并且没有挂载到云主机", "arguments": [ - "rsgVo.getIpVersion()", - "sgVo.getIpVersion()" + "msg.getPciDeviceUuid()" ], - "line": 345, - "fileName": "src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java" + "line": 550, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "L3Network [uuid: %s] provide type null", - "en_US": "L3Network [uuid: {0}] provide type null", - "zh_CN": "三层网络{0}后端为空", + "raw": "pci device[uuid:%s] cannot be virtualized by mdev spec[uuid:%s]", + "en_US": "pci device[uuid:{0}] cannot be virtualized by mdev spec[uuid:{1}]", + "zh_CN": "PCI设备[uuid:{0}]无法使用MDEV设备规格[uuid:{1}]进行虚拟化切分", "arguments": [ - "msg.getL3NetworkUuid()" + "msg.getPciDeviceUuid()", + "msg.getMdevSpecUuid()" ], - "line": 88, - "fileName": "src/main/java/org/zstack/network/service/HostRouteExtension.java" + "line": 561, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "L3Network [uuid: %s] does not have host route service", - "en_US": "L3Network [uuid: {0}] does not have host route service", - "zh_CN": "三层网络{0}没有主机路由功能", + "raw": "pci device[uuid:%s] is not virtualized into mdevs", + "en_US": "pci device[uuid:{0}] is not virtualized into mdevs", + "zh_CN": "PCI设备[uuid:{0}]未处于VFIO_MDEV虚拟化状态", "arguments": [ - "msg.getL3NetworkUuid()" + "msg.getPciDeviceUuid()" ], - "line": 113, - "fileName": "src/main/java/org/zstack/network/service/HostRouteExtension.java" + "line": 583, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "networkServices cannot be empty", - "en_US": "networkServices cannot be empty", - "zh_CN": "网络服务(networkServices)不能为空", - "arguments": [], - "line": 41, - "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" + "raw": "mdev devices generated from pci device[uuid:%s] still attached to vm", + "en_US": "mdev devices generated from pci device[uuid:{0}] still attached to vm", + "zh_CN": "PCI设备[uuid:{0}]切分出的MDEV设备仍处于已挂载状态,无法执行虚拟化还原操作", + "arguments": [ + "msg.getPciDeviceUuid()" + ], + "line": 600, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "network service for provider[uuid:%s] must be specified", - "en_US": "network service for provider[uuid:{0}] must be specified", - "zh_CN": "服务提供器[uuid:{0}]的网络服务必须被指定", + "raw": "please umount all GPU devices of the vm[%s] and try again", + "en_US": "please umount all GPU devices of the vm[{0}] and try again", + "zh_CN": "请卸载云主机[{0}]的所有GPU设备,然后重试", "arguments": [ - "puuid" + "VmInstanceUuid" ], - "line": 62, - "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" + "line": 624, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "cannot find network service provider[uuid:%s] or it provides no services", - "en_US": "cannot find network service provider[uuid:{0}] or it provides no services", - "zh_CN": "无法找到网络服务提供器[uuid:{0}]或它没有提供任何服务", + "raw": "please umount all vGPU devices of the vm[%s] and try again", + "en_US": "please umount all vGPU devices of the vm[{0}] and try again", + "zh_CN": "请卸载云主机[{0}]的所有vGPU设备,然后重试", "arguments": [ - "puuid" + "VmInstanceUuid" ], - "line": 67, - "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" + "line": 628, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "network service provider[uuid:%s] doesn\u0027t provide services%s", - "en_US": "network service provider[uuid:{0}] doesn\u0027t provide services{1}", - "zh_CN": "网络服务提供器[uuid:{0}]无法提供服务{1}", + "raw": "please umount other pci devices of the vm[%s] and try again", + "en_US": "please umount other pci devices of the vm[{0}] and try again", + "zh_CN": "请卸载VM[{0}]的其他PCI设备,然后重试", "arguments": [ - "puuid", - "notSupported" + "VmInstanceUuid" ], - "line": 81, - "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" + "line": 635, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" }, { - "raw": "there has been a network service[%s] attached to L3 network[uuid:%s]", - "en_US": "there has been a network service[{0}] attached to L3 network[uuid:{1}]", - "zh_CN": "已经有一个网络服务[{0}]被挂载到L3网络[uuid:{1}]", + "raw": "specified pci devices not on same host: pci device[uuid: %s] on host[uuid: %s] while pci device[uuid: %s] on host[uuid: %s]", + "en_US": "specified pci devices not on same host: pci device[uuid: {0}] on host[uuid: {1}] while pci device[uuid: {2}] on host[uuid: {3}]", + "zh_CN": "云主机试图挂载来自不同物理机的PCI设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}]", "arguments": [ - "type", - "msg.getL3NetworkUuid()" + "vo.getUuid()", + "vo.getHostUuid()", + "attachedPciUuid", + "dstHostUuid" ], - "line": 93, - "fileName": "src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java" + "line": 59, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java" }, { - "raw": "L3Network[uuid:%s] doesn\u0027t have network service[type:%s] enabled or no provider provides this network service", - "en_US": "L3Network[uuid:{0}] doesn\u0027t have network service[type:{1}] enabled or no provider provides this network service", - "zh_CN": "L3网络[uuid:{0}]上没有网络服务[type:{1}]被启用或没有服务提供器提供该网络服务", + "raw": "no candidate host with enough pci devices", + "en_US": "no candidate host with enough pci devices", + "zh_CN": "没有具有足够PCI设备的候选物理机", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java" + }, + { + "raw": "failed to start vm[uuid:%s] because not all pci specs[uuids:%s] exist", + "en_US": "failed to start vm[uuid:{0}] because not all pci specs[uuids:{1}] exist", + "zh_CN": "云主机[uuid:{0}]启动失败,因为所设置的PCI设备规格[uuids:{1}]中有部分不存在", "arguments": [ - "l3NetworkUuid", - "serviceType" + "vmUuid", + "specMap.keySet()" ], - "line": 342, - "fileName": "src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java" + "line": 123, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java" }, { - "raw": "either eipUuid or vipUuid must be set", - "en_US": "either eipUuid or vipUuid must be set", - "zh_CN": "eipUuid或vipUuid必须有一个被指定", - "arguments": [], - "line": 82, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "raw": "illegal type[%s] for pci device, only %s are legal", + "en_US": "illegal type[{0}] for pci device, only {1} are legal", + "zh_CN": "PCI设备的类型[{0}]非法,只有{1}是合法的", + "arguments": [ + "vo.getType()", + "PciDeviceType.leagalPciDeviceCandidateTypes" + ], + "line": 1319, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "eip[uuid:%s] is not in state of Enabled, cannot get attachable vm nic", - "en_US": "eip[uuid:{0}] is not in state of Enabled, cannot get attachable vm nic", - "zh_CN": "eip[uuid:{0}]没有被启用,无法获取可挂载的虚拟机网卡", + "raw": "failed to find enough pci device of spec[uuid:%s] in dest host[uuid:%s] for vm[uuid:%s]", + "en_US": "failed to find enough pci device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}]", + "zh_CN": "无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的PCI设备", "arguments": [ - "msg.getEipUuid()" + "specUuid", + "hostUuid", + "vmUuid" ], - "line": 88, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 719, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "ip [uuid:%s] is attached to vm nic [%s]", - "en_US": "ip [uuid:{0}] is attached to vm nic [{1}]", - "zh_CN": "IP地址[uuid:{0}]已经绑定到网卡[{1}]", + "raw": "something wrong with iommu group of pci device[uuid:%s]", + "en_US": "something wrong with iommu group of pci device[uuid:{0}]", + "zh_CN": "PCI设备[uuid:{0}]的IOMMU组出现问题", "arguments": [ - "guestIpUuid", - "vmNicUuid" + "pciUuid" ], - "line": 103, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 782, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "eip[uuid:%s] has attached to another vm nic[uuid:%s], can\u0027t attach again", - "en_US": "eip[uuid:{0}] has attached to another vm nic[uuid:{1}], can\u0027t attach again", - "zh_CN": "eip[uuid:{0}]已经被挂载到另外一台虚拟机网卡[uuid:{1}],无法再次挂载", + "raw": "pci devices [%s] are not all available", + "en_US": "pci devices [{0}] are not all available", + "zh_CN": "PCI设备[{0}]并非全部可用", "arguments": [ - "msg.getEipUuid()", - "vmNicUuid" + "pciUuids" ], - "line": 114, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 795, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "eip[uuid: %s] can only be attached when state is %s, current state is %s", - "en_US": "eip[uuid: {0}] can only be attached when state is {1}, current state is {2}", - "zh_CN": "eip[uuid:{0}]只有在状态(state)为{1}的情况下可以被挂载,当前状态是{2}", + "raw": "can not attach this pci device[uuid:%s] to vm[uuid:%s] due to host allocation", + "en_US": "can not attach this pci device[uuid:{0}] to vm[uuid:{1}] due to host allocation", + "zh_CN": "由于物理机分配问题导致不能将PCI设备[uuid:{0}]绑定云主机[uuid:{1}]", "arguments": [ - "msg.getEipUuid()", - "EipState.Enabled", - "state" + "msg.getPciDeviceUuid()", + "msg.getVmInstanceUuid()" ], - "line": 120, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 928, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "guest l3Network of vm nic[uuid:%s] and vip l3Network of EIP[uuid:%s] are the same network", - "en_US": "guest l3Network of vm nic[uuid:{0}] and vip l3Network of EIP[uuid:{1}] are the same network", - "zh_CN": "虚拟机网卡[uuid:{0}]的客户L3网络,和EIP[uuid:{1}]的虚拟ip L3网络是同一个网络", + "raw": "can not migrate vm[uuid:%s] since pci device attached", + "en_US": "can not migrate vm[uuid:{0}] since pci device attached", + "zh_CN": "当PCI设备绑定后不能迁移云主机[uuid:{0}]", "arguments": [ - "msg.getVmNicUuid()", - "msg.getEipUuid()" + "msg.getVmInstanceUuid()" ], - "line": 150, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 1221, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "Ip address [uuid:%s] is not belonged to nic [uuid:%s]", - "en_US": "Ip address [uuid:{0}] is not belonged to nic [uuid:{1}]", - "zh_CN": "IP地址[uuid:{0}]没有绑定到网卡[uuid:{1}]", + "raw": "cannot migrate root volume[uuid:%s] because there are pci devices attached", + "en_US": "cannot migrate root volume[uuid:{0}] because there are pci devices attached", + "zh_CN": "不能迁移云盘[uuid:{0}],因为它所在的云主机挂载了PCI设备", "arguments": [ - "msg.getEipUuid()", - "msg.getVmNicUuid()" + "msg.getVolumeUuid()" ], - "line": 167, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 1270, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "eip[uuid:%s] has not attached to any vm nic", - "en_US": "eip[uuid:{0}] has not attached to any vm nic", - "zh_CN": "eip[uuid:{0}]还没有被挂载到任意虚拟机网卡", + "raw": "pci device[uuid:%s] doesn\u0027t exists", + "en_US": "pci device[uuid:{0}] doesn\u0027t exists", + "zh_CN": "PCI设备[uuid:{0}]不存在", "arguments": [ - "msg.getUuid()" + "pciDeviceUuid" ], - "line": 180, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 1316, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "vip ipVersion [%d] is different from guestIp ipVersion [%d].", - "en_US": "vip ipVersion [{0}] is different from guestIp ipVersion [{1}].", - "zh_CN": "虚拟IP的协议号[{0}]和网卡的IP协议号[{1}]不同", + "raw": "pci device spec[uuid:%s] doesn\u0027t exists", + "en_US": "pci device spec[uuid:{0}] doesn\u0027t exists", + "zh_CN": "PCI设备规范[uuid:{0}]不存在", "arguments": [ - "vipIp.getIpVersion()", - "guestIp.getIpVersion()" + "pciSpecUuid" ], - "line": 203, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 1330, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "Vip[%s] is in the guest ip range [%s, %s]", - "en_US": "Vip[{0}] is in the guest ip range [{1}, {2}]", - "zh_CN": "虚拟IP[{0}]和网卡的IP不能在相同地址段[{1}-{2}]", + "raw": "pci device[uuid:%s] doesn\u0027t exist or is disabled for vm[uuid:%s]", + "en_US": "pci device[uuid:{0}] doesn\u0027t exist or is disabled for vm[uuid:{1}]", + "zh_CN": "PCI设备[uuid:{0}]不存在或已为云主机[uuid:{1}]禁用", "arguments": [ - "vipIp.getIp()", - "guestRange.getStartIp()", - "guestRange.getEndIp()" + "pciUuid", + "vmUuid" ], - "line": 210, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 1511, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" }, { - "raw": "the vm[uuid:%s] that the EIP is about to attach is already on the public network[uuid:%s] from which the vip[uuid:%s, name:%s, ip:%s] comes", - "en_US": "the vm[uuid:{0}] that the EIP is about to attach is already on the public network[uuid:{1}] from which the vip[uuid:{2}, name:{3}, ip:{4}] comes", - "zh_CN": "EIP将要挂载到的虚拟机[uuid:{0}]已经处于公共网络[uuid:{1}]上,该网络上已有vip[uuid:{2}, name:{3}, ip:{4}]", + "raw": "pci device[uuid:%s] can not attach to vm[uuid:%s] due to wrong status", + "en_US": "pci device[uuid:{0}] can not attach to vm[uuid:{1}] due to wrong status", + "zh_CN": "由于状态错误,PCI设备[uuid:{0}]无法连接到云主机[uuid:{1}]", "arguments": [ - "vmUuid", - "vip.getL3NetworkUuid()", - "vip.getUuid()", - "vip.getName()", - "vip.getIp()" + "wrongStatusPciUuids", + "vmUuid" ], - "line": 230, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 161, + "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceReserveFlow.java" }, { - "raw": "vip[uuid:%s] has been occupied other network service entity[%s]", - "en_US": "vip[uuid:{0}] has been occupied other network service entity[{1}]", - "zh_CN": "vip[uuid:{0}]已经被其他网络服务实体[{1}]占用", + "raw": "The host [%s] has failed to enter the maintenance, The vm [%s] cannot migrate automatically because it contains the PCI device", + "en_US": "The host [{0}] has failed to enter the maintenance, The vm [{1}] cannot migrate automatically because it contains the PCI device", + "zh_CN": "物理机[{0}]进入维护状态失败,这个云主机[{1}]不能自动迁移,因为云主机包含了PCI设备", "arguments": [ - "msg.getVipUuid()", - "useForList.toString()" + "inventory.getUuid()", + "hasPciVmUuids.toString()" ], - "line": 241, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 69, + "fileName": "src/main/java/org/zstack/pciDevice/PciHostChangeStateExtension.java" }, { - "raw": "vip[uuid:%s] is not in state[%s], current state is %s", - "en_US": "vip[uuid:{0}] is not in state[{1}], current state is {2}", - "zh_CN": "vip[uuid:{0}]不处于状态[{1}]中,当前状态[{2}]", + "raw": "illegal type[%s] for pci device spec, only %s are legal", + "en_US": "illegal type[{0}] for pci device spec, only {1} are legal", + "zh_CN": "PCI设备规范的类型[{0}]非法,只有{1}合法", "arguments": [ - "msg.getVipUuid()", - "VipState.Enabled", - "vip.getState()" + "vo.getType()", + "PciDeviceType.leagalPciDeviceCandidateTypes" ], - "line": 246, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 185, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "vm state[%s] is not allowed to operate eip, maybe you should wait the vm process complete", - "en_US": "vm state[{0}] is not allowed to operate eip, maybe you should wait the vm process complete", - "zh_CN": "云主机状态[{0}]不允许进行弹性IP操作,你可能需要等待云主机操作完成", + "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to set pci device spec", + "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to set pci device spec", + "zh_CN": "云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以设置PCI设备规格", "arguments": [ - "state.toString()" + "vmUuid", + "state" ], - "line": 281, - "fileName": "src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java" + "line": 258, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "cannot find Eip guest ip: %s in vmNic ips :%s", - "en_US": "cannot find Eip guest ip: {0} in vmNic ips :{1}", - "zh_CN": "", + "raw": "vm[uuid:%s] already has pci device spec[uuid:%s]", + "en_US": "vm[uuid:{0}] already has pci device spec[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已经设置过了PCI设备规格[uuid:{1}]", "arguments": [ - "eip.getGuestIp()", - "nicIps" + "msg.getVmInstanceUuid()", + "msg.getPciSpecUuid()" ], - "line": 944, - "fileName": "src/main/java/org/zstack/network/service/eip/EipManagerImpl.java" + "line": 169, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "unable to attach the L3 network[uuid:%s, name:%s] to the vm[uuid:%s, name:%s], because the L3 network is providing EIP to one of the vm\u0027s nic", - "en_US": "unable to attach the L3 network[uuid:{0}, name:{1}] to the vm[uuid:{2}, name:{3}], because the L3 network is providing EIP to one of the vm\u0027s nic", - "zh_CN": "无法将L3网络[uuid:{0}, name:{1}]挂载到虚拟机[uuid:{2}, name:{3}],因为L3网络正在为虚拟机上的一块网卡提供EIP", + "raw": "vm[uuid:%s] doesn\u0027t have pci device spec[uuid:%s]", + "en_US": "vm[uuid:{0}] doesn\u0027t have pci device spec[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]未设置PCI设备规格[uuid:{1}]", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getPciSpecUuid()" + ], + "line": 197, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + }, + { + "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to remove pci device spec[uuid:%s]", + "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to remove pci device spec[uuid:{2}]", + "zh_CN": "云主机[uuid:{0}], state:{1}需要处于关机状态下才可以取消PCI设备规格[uuid:{2}]", "arguments": [ - "l3.getUuid()", - "l3.getName()", "vm.getUuid()", - "vm.getName()" + "vm.getState()", + "msg.getPciSpecUuid()" ], - "line": 1305, - "fileName": "src/main/java/org/zstack/network/service/eip/EipManagerImpl.java" + "line": 204, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "Session/account uuid is not valid.", - "en_US": "Session/account uuid is not valid.", - "zh_CN": "", - "arguments": [], - "line": 39, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java" + "raw": "vm[uuid:%s] already has mdev device spec[uuid:%s]", + "en_US": "vm[uuid:{0}] already has mdev device spec[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已经设置过了MDEV设备规格[uuid:{1}]", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getMdevSpecUuid()" + ], + "line": 285, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "the account[uuid:%s] has no access to the resource[uuid:%s, type:L3NetworkVO]", - "en_US": "the account[uuid:{0}] has no access to the resource[uuid:{1}, type:L3NetworkVO]", - "zh_CN": "", + "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to set mdev device spec", + "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to set mdev device spec", + "zh_CN": "云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以设置MDEV设备规格", "arguments": [ - "accountUuid", - "msg.getL3NetworkUuid()" + "vm.getUuid()", + "vm.getState()" ], - "line": 43, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java" + "line": 293, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "l3 network uuid cannot be null", - "en_US": "l3 network uuid cannot be null", - "zh_CN": "L3网络的uuid不能为空", - "arguments": [], - "line": 712, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "raw": "vm[uuid:%s] doesn\u0027t have mdev device spec[uuid:%s]", + "en_US": "vm[uuid:{0}] doesn\u0027t have mdev device spec[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]未设置过MDEV设备规格[uuid:{1}]", + "arguments": [ + "msg.getVmInstanceUuid()", + "msg.getMdevSpecUuid()" + ], + "line": 306, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "Cannot find DhcpIp for l3 network[uuid:%s]", - "en_US": "Cannot find DhcpIp for l3 network[uuid:{0}]", - "zh_CN": "无法为L3网络[uuid:{0}]找到DHCP IP", + "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to remove mdev device spec[uuid:%s]", + "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to remove mdev device spec[uuid:{2}]", + "zh_CN": "云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以取消MDEV设备规格[uuid:{2}]", "arguments": [ - "msg.getL3NetworkUuid()" + "vm.getUuid()", + "vm.getState()", + "msg.getMdevSpecUuid()" ], - "line": 728, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 313, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" }, { - "raw": "L3 network[uuid:%s] does not have any iprange", - "en_US": "L3 network[uuid:{0}] does not have any iprange", - "zh_CN": "三层网络[{0}]没有配置ip段", + "raw": "pci device spec[uuid:%s] is not available for vm[uuid:%s]", + "en_US": "pci device spec[uuid:{0}] is not available for vm[uuid:{1}]", + "zh_CN": "云主机[uuid:{1}]无法设置PCI设备规格[uuid:{0}]", "arguments": [ - "msg.getL3NetworkUuid()" + "msg.getPciSpecUuid()", + "msg.getVmInstanceUuid()" ], - "line": 823, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 374, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "cannot configure DHCP for vm[uuid:%s] on the destination host[uuid:%s]", - "en_US": "cannot configure DHCP for vm[uuid:{0}] on the destination host[uuid:{1}]", - "zh_CN": "无法为目标物理机[uuid:{1}]上的虚拟机[uuid:{0}]配置DHCP", + "raw": "no pci device spec available for vm[uuid:%s]", + "en_US": "no pci device spec available for vm[uuid:{0}]", + "zh_CN": "云主机[uuid:{0}]无可用的PCI设备规格", "arguments": [ - "inv.getUuid()", - "destHostUuid" + "msg.getVmInstanceUuid()" ], - "line": 1089, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 372, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "DHCP server ip [%s] is not a IPv6 address", - "en_US": "DHCP server ip [{0}] is not a IPv6 address", - "zh_CN": "DHCP服务器地址[{0}]不是一个正确的IPv6地址", + "raw": "failed to get pci device spec available for vm[uuid:%s]: %s", + "en_US": "failed to get pci device spec available for vm[uuid:{0}]: {1}", + "zh_CN": "无法获取可用于VM[uuid:{0}]的PCI设备规范:{1}", "arguments": [ - "dhcpServerIp" + "msg.getVmInstanceUuid()", + "rly.getError()" ], - "line": 1959, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 367, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "DHCP server ip [%s] is not in the cidr [%s]", - "en_US": "DHCP server ip [{0}] is not in the cidr [{1}]", - "zh_CN": "DHCP服务器地址[{0}]不在网络段[{1}]的范围内", + "raw": "mdev device spec[uuid:%s] is not available for vm[uuid:%s]", + "en_US": "mdev device spec[uuid:{0}] is not available for vm[uuid:{1}]", + "zh_CN": "云主机[uuid:{1}]无法设置MDEV设备规格[uuid:{0}]", "arguments": [ - "dhcpServerIp", - "inv.getNetworkCidr()" + "msg.getMdevSpecUuid()", + "msg.getVmInstanceUuid()" ], - "line": 1955, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 557, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "DHCP server ip [%s] is not a IPv4 address", - "en_US": "DHCP server ip [{0}] is not a IPv4 address", - "zh_CN": "DHCP服务器地址[{0}]不是一个正确的IPv4地址", + "raw": "no mdev device spec available for vm[uuid:%s]", + "en_US": "no mdev device spec available for vm[uuid:{0}]", + "zh_CN": "云主机[uuid:{0}]无可用的MDEV设备规格", "arguments": [ - "dhcpServerIp" + "msg.getVmInstanceUuid()" ], - "line": 1951, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 550, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "DHCP server ip [%s] is already existed in l3 network [%s]", - "en_US": "DHCP server ip [{0}] is already existed in l3 network [{1}]", - "zh_CN": "三层网络[{1}]已经配置了DHCP服务器地址[{0}]", + "raw": "pci device spec[uuid:%s] doesn\u0027t exist", + "en_US": "pci device spec[uuid:{0}] doesn\u0027t exist", + "zh_CN": "PCI设备规格[uuid:{0}]不存在", "arguments": [ - "IPv6NetworkUtils.ipv6TagValueToAddress(oldDhcpServer)", - "inv.getL3NetworkUuid()" + "specUuid", + "systemTag" ], - "line": 1970, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 751, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "DHCP server ip [%s] can not be equaled to gateway ip", - "en_US": "DHCP server ip [{0}] can not be equaled to gateway ip", - "zh_CN": "DHCP服务器地址[{0}]不能等于网关地址", + "raw": "mdev device spec[uuid:%s] doesn\u0027t exist", + "en_US": "mdev device spec[uuid:{0}] doesn\u0027t exist", + "zh_CN": "MDEV设备规格[uuid:{0}]不存在", "arguments": [ - "dhcpServerIp" + "specUuid", + "systemTag" ], - "line": 1975, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 764, + "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" }, { - "raw": "DHCP server ip [%s] can not be configured to system l3", - "en_US": "DHCP server ip [{0}] can not be configured to system l3", - "zh_CN": "系统网络不能配置DHCP服务器地址[{0}]", + "raw": "cluster uuids or host uuid or vm uuid can not be set at same time", + "en_US": "cluster uuids or host uuid or vm uuid can not be set at same time", + "zh_CN": "获取候选规格列表时不要同时指定集群uuids、物理机uuid或云主机uuid", + "arguments": [], + "line": 191, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + }, + { + "raw": "clusters not exist or disabled", + "en_US": "clusters not exist or disabled", + "zh_CN": "集群不存在或已禁用", + "arguments": [], + "line": 198, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + }, + { + "raw": "illegal mdev device type [%s], only %s are legal", + "en_US": "illegal mdev device type [{0}], only {1} are legal", + "zh_CN": "非法的MDEV设备类型[{0}],只有{1}才是合法的", "arguments": [ - "dhcpServerIp" + "type", + "legalTypes" ], - "line": 1981, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java" + "line": 232, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "L2Network where vip\u0027s L3Network based hasn\u0027t attached the cluster where vmNic[uuid:%s] located", - "en_US": "L2Network where vip\u0027s L3Network based hasn\u0027t attached the cluster where vmNic[uuid:{0}] located", - "zh_CN": "基于虚拟IP三层网络的二层网络没有绑定到虚拟机网卡所在的集群", + "raw": "cannot change the state of mdev device that\u0027s in attached status", + "en_US": "cannot change the state of mdev device that\u0027s in attached status", + "zh_CN": "MDEV设备处于已挂载状态,无法修改其状态", + "arguments": [], + "line": 69, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + }, + { + "raw": "cannot attach mdev device[uuid:%s] to vm, make sure it\u0027s enabled and un-attached", + "en_US": "cannot attach mdev device[uuid:{0}] to vm, make sure it\u0027s enabled and un-attached", + "zh_CN": "无法为云主机挂载MDEV设备[uuid:{0}],因为该设备处于禁用状态或已被挂载", "arguments": [ - "vmNicUuid" + "msg.getMdevDeviceUuid()" ], - "line": 99, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java" + "line": 77, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "unable to apply the EIP operation for the the vm[uuid:%s, state:%s], because cannot find the VM\u0027s hostUUid", - "en_US": "unable to apply the EIP operation for the the vm[uuid:{0}, state:{1}], because cannot find the VM\u0027s hostUUid", - "zh_CN": "无法为虚拟机[uuid:{0}, state:{1}]应用EIP操作,因为无法找到该虚拟机的物理机uuid(hostUuid)", + "raw": "cannot attach mdev device to vm instance that\u0027s not stopped", + "en_US": "cannot attach mdev device to vm instance that\u0027s not stopped", + "zh_CN": "云主机需要处于关机状态下才可以挂载MDEV设备", + "arguments": [], + "line": 220, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + }, + { + "raw": "vm[uuid:%s] has pci devices attached that are in different host with mdev device[uuid:%s]", + "en_US": "vm[uuid:{0}] has pci devices attached that are in different host with mdev device[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已经挂载了PCI设备,并且它们和MDEV设备[uuid:{1}]不在同一台物理机上", "arguments": [ - "vmUuid", - "vm.getState()" + "msg.getVmInstanceUuid()", + "msg.getMdevDeviceUuid()" ], - "line": 573, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatEipBackend.java" + "line": 103, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "host[uuid:%s] is not connected", - "en_US": "host[uuid:{0}] is not connected", - "zh_CN": "物理机[uuid:{0}]未连接", + "raw": "vm[uuid:%s] has mdev devices attached that are in different host with mdev device[uuid:%s]", + "en_US": "vm[uuid:{0}] has mdev devices attached that are in different host with mdev device[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]已经挂载了MDEV设备,并且它们和MDEV设备[uuid:{1}]不在同一台物理机上", "arguments": [ - "struct.getHostUuid()" + "msg.getVmInstanceUuid()", + "msg.getMdevDeviceUuid()" ], - "line": 353, - "fileName": "src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java" + "line": 113, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "invalid health target[%s], the format is targetCheckProtocol:port, for example, tcp:default", - "en_US": "invalid health target[{0}], the format is targetCheckProtocol:port, for example, tcp:default", - "zh_CN": "无效的健康检查目标[{0}],格式为[目标检查协议(targetCheckProtocol):端口(port)], 例如[tcp:default]", + "raw": "the host[uuid:%s] that holds mdev device[uuid:%s] is not [%s] and [%s]", + "en_US": "the host[uuid:{0}] that holds mdev device[uuid:{1}] is not [{2}] and [{3}]", + "zh_CN": "拥有MDEV设备[uuid:{1}]的物理机[uuid:{0}]不是[{2}]和[{3}]", "arguments": [ - "target" + "mdev.getHostUuid()", + "mdev.getUuid()", + "HostState.Enabled", + "HostStatus.Connected" ], - "line": 672, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 168, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "the access control list group[%s] is being used by the load balancer listeners[%s]", - "en_US": "the access control list group[{0}] is being used by the load balancer listeners[{1}]", - "zh_CN": "访问控制组[{0}]正在被监听器[{1}]使用", + "raw": "the vm[uuid:%s] that holds se mdev device can not attach more se mdev[%s]", + "en_US": "the vm[uuid:{0}] that holds se mdev device can not attach more se mdev[{1}]", + "zh_CN": "拥有SE MDEV设备的VM[uuid:{0}]无法附加更多SE MDEV[{1}]", "arguments": [ - "msg.getUuid()", - "refs" + "msg.getVmInstanceUuid()", + "mdev.getUuid()" ], - "line": 121, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 132, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "operation failure, not support the ip version %d", - "en_US": "operation failure, not support the ip version {0}", - "zh_CN": "操作失败,不支持IPv{0}", + "raw": "IOMMU of the host[uuid:%s] that hosts pci device[uuid:%s] is not [%s] and [%s]", + "en_US": "IOMMU of the host[uuid:{0}] that hosts pci device[uuid:{1}] is not [{2}] and [{3}]", + "zh_CN": "托管PCI设备[uuid:{1}]的物理机[uuid:{0}]的IOMMU不是[{2}]和[{3}]", "arguments": [ - "ipVer" + "mdev.getHostUuid()", + "mdev.getUuid()", + "HostState.Enabled", + "HostStatus.Connected" ], - "line": 203, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 143, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "operation failure, duplicate/overlap ip entry in %s of accesscontrol list group:%s", - "en_US": "operation failure, duplicate/overlap ip entry in {0} of accesscontrol list group:{1}", - "zh_CN": "操作失败,在访问控制组:{1}中有重复/重叠ip{0}", + "raw": "mdev device [uuid:%s] is not attached to vm[uuid:%s]", + "en_US": "mdev device [uuid:{0}] is not attached to vm[uuid:{1}]", + "zh_CN": "MDEV设备[uuid:{0}]没有挂载到云主机[uuid:{1}]", "arguments": [ - "ips", - "acl.getUuid()" + "msg.getMdevDeviceUuid()", + "msg.getVmInstanceUuid()" ], - "line": 209, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 156, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + }, + { + "raw": "cannot detach mdev device from vm instance when it\u0027s not stopped", + "en_US": "cannot detach mdev device from vm instance when it\u0027s not stopped", + "zh_CN": "云主机需要处于关机状态下才可以卸载MDEV设备", + "arguments": [], + "line": 181, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "operation failure, ip format only supports ip/iprange/cidr, but find %s", - "en_US": "operation failure, ip format only supports ip/iprange/cidr, but find {0}", - "zh_CN": "操作失败,只支持IP地址/IP段/IP网络格式的参数,不支持{0}", - "arguments": [ - "ips" - ], - "line": 216, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "raw": "cannot delete mdev device when it\u0027s attached", + "en_US": "cannot delete mdev device when it\u0027s attached", + "zh_CN": "无法删除已连接的MDEV设备", + "arguments": [], + "line": 245, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" }, { - "raw": "ip range[%s, %s] is overlap with start ip:%s, end ip: %s of access-control-list group:%s", - "en_US": "ip range[{0}, {1}] is overlap with start ip:{2}, end ip: {3} of access-control-list group:{4}", - "zh_CN": "ip段[{0}, {1}]和访问控制列表组:{4}中的ip段[{2},{3}]重叠", + "raw": "failed to get candidate hosts to start vm[uuid:%s], %s", + "en_US": "failed to get candidate hosts to start vm[uuid:{0}], {1}", + "zh_CN": "无法为云主机[uuid:{0}]寻找到可启动的物理机:{1}", "arguments": [ - "startIp", - "endIp", - "NetworkUtils.longToIpv4String(r.lowerEndpoint())", - "NetworkUtils.longToIpv4String(r.upperEndpoint())", - "acl.getUuid()" + "msg.getVmInstanceUuid()", + "reply.getError()" ], - "line": 220, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 379, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java" }, { - "raw": "Can\u0027t attach the type access-control-list group[%s] whose ip version is different with LoadBalancer[%s]", - "en_US": "Can\u0027t attach the type access-control-list group[{0}] whose ip version is different with LoadBalancer[{1}]", - "zh_CN": "负载均衡器[{1}]不能添加IP版本不一致的访问控制列表组[{0}]", + "raw": "mdev device [%s] is not available", + "en_US": "mdev device [{0}] is not available", + "zh_CN": "MDEV设备[{0}]不可用", "arguments": [ - "aclUuids", - "lbUuid" + "mdevUuid" ], - "line": 242, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 100, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java" }, { - "raw": "the access-control-list groups[uuid:%s] are already on the load balancer listener[uuid:%s]", - "en_US": "the access-control-list groups[uuid:{0}] are already on the load balancer listener[uuid:{1}]", - "zh_CN": "负载均衡监听器[uuid:{1}]已经添加了访问控制列表组[uuid:{0}]", + "raw": "failed to hot plug mdev device to running vm, because:%s", + "en_US": "failed to hot plug mdev device to running vm, because:{0}", + "zh_CN": "无法将MDEV设备热插拔到正在运行的云主机,因为:{0}", "arguments": [ - "existingAcls", - "msg.getListenerUuid()" + "rsp.getError()" ], - "line": 302, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 217, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java" }, { - "raw": "the load balancer listener[uuid:%s] just only attach the %s type access-control-list group", - "en_US": "the load balancer listener[uuid:{0}] just only attach the {1} type access-control-list group", - "zh_CN": "负载均衡监听器[uuid:{0}]只能以{1}方式添加访问控制列表组", + "raw": "vm[uuid:%s] cannot start in host that hold mdev device[uuid:%s]", + "en_US": "vm[uuid:{0}] cannot start in host that hold mdev device[uuid:{1}]", + "zh_CN": "云主机[uuid:{0}]无法在MDEV设备[uuid:{1}]所在的物理机上启动", "arguments": [ - "msg.getListenerUuid()", - "type.toString()" + "msg.getVmInstanceUuid()", + "msg.getMdevDeviceUuid()" ], - "line": 308, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 278, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java" }, { - "raw": "the load balancer listener[uuid:%s] can\u0027t attach more than %d access-control-list groups", - "en_US": "the load balancer listener[uuid:{0}] can\u0027t attach more than {1} access-control-list groups", - "zh_CN": "负载均衡监听器[uuid:{0}]最多只能添加{1}个访问控制列表组", + "raw": "failed to hot unplug mdev device to running vm, because:%s", + "en_US": "failed to hot unplug mdev device to running vm, because:{0}", + "zh_CN": "无法将MDEV设备热拔出到正在运行的云主机,原因是:{0}", "arguments": [ - "msg.getListenerUuid()", - "LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class)" + "rsp.getError()" ], - "line": 313, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 353, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java" }, { - "raw": "L3 networks[uuids:%s] of the vm nics has no network service[%s] enabled", - "en_US": "L3 networks[uuids:{0}] of the vm nics has no network service[{1}] enabled", - "zh_CN": "虚拟机网卡的三层网络没有可用的网络服务", + "raw": "pci device[uuid:%s] is known as %s, but cannot find it\u0027s mdev spec, so abort.", + "en_US": "pci device[uuid:{0}] is known as {1}, but cannot find it\u0027s mdev spec, so abort.", + "zh_CN": "PCI设备[uuid:{0}]是{1},但无法找到可用的MDEV设备规格", "arguments": [ - "l3Uuids", - "LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING" + "pciDevice.getUuid()", + "PciDeviceVirtStatus.VFIO_MDEV_VIRTUALIZED" ], - "line": 339, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 68, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFactory.java" }, { - "raw": "the vm nics[uuid:%s] are already on the load balancer listener[uuid:%s]", - "en_US": "the vm nics[uuid:{0}] are already on the load balancer listener[uuid:{1}]", - "zh_CN": "虚拟机网卡[uuid:{0}]已经处于负载均衡监听器[uuid:{1}]上", + "raw": "failed to start vm[uuid:%s] because not all mdev specs[uuids:%s] exist", + "en_US": "failed to start vm[uuid:{0}] because not all mdev specs[uuids:{1}] exist", + "zh_CN": "云主机[uuid:{0}]启动失败,由于所设置的MDEV设备规格[uuids:{1}]中有部分不存在", "arguments": [ - "existingNics", - "msg.getListenerUuid()" + "vmUuid", + "specMap.keySet()" ], - "line": 349, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 48, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java" }, { - "raw": "the listener with protocol [%s] doesn\u0027t support this health check:[%s]", - "en_US": "the listener with protocol [{0}] doesn\u0027t support this health check:[{1}]", - "zh_CN": "[{0}]类型的监听器不支持此类型[{1}]的健康检查", + "raw": "specified mdev devices not on same host: mdev device[uuid: %s] on host[uuid: %s] while mdev device[uuid: %s] on host[uuid: %s]", + "en_US": "specified mdev devices not on same host: mdev device[uuid: {0}] on host[uuid: {1}] while mdev device[uuid: {2}] on host[uuid: {3}]", + "zh_CN": "云主机试图挂载来自不同物理机的MDEV设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}]", "arguments": [ - "listenerVO.getProtocol()", - "msg.getHealthCheckProtocol()" + "mdev.getUuid()", + "mdev.getHostUuid()", + "attachedMdevUuid", + "dstHostUuid" ], - "line": 678, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 145, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java" }, { - "raw": "the http health check protocol must be specified its healthy checking parameter healthCheckURI", - "en_US": "the http health check protocol must be specified its healthy checking parameter healthCheckURI", - "zh_CN": "http类型的健康检查必须提供healthCheckURI参数", + "raw": "no candidate host with enough mdev devices", + "en_US": "no candidate host with enough mdev devices", + "zh_CN": "没有物理机满足mdev device设备的条件", "arguments": [], - "line": 652, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 184, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java" }, { - "raw": "the http health check protocol\u0027s expecting code [%s] is invalidate", - "en_US": "the http health check protocol\u0027s expecting code [{0}] is invalidate", - "zh_CN": "http健康检查协议的expeting-code参数非法", + "raw": "The host [%s] has failed to enter the maintenance, because vm[%s] has mdev devices attached and cannot migrate automatically", + "en_US": "The host [{0}] has failed to enter the maintenance, because vm[{1}] has mdev devices attached and cannot migrate automatically", + "zh_CN": "物理机[{0}]无法进入维护模式,因为云主机[{1}]挂载了MDEV设备导致无法迁移", "arguments": [ - "msg.getHealthCheckHttpCode()" + "inventory.getUuid()", + "hasMdevVmUuids.toString()" ], - "line": 659, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 55, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceHostChangeStateExtension.java" }, { - "raw": "Can\u0027t attach more than %d access-control-list groups to a listener", - "en_US": "Can\u0027t attach more than {0} access-control-list groups to a listener", - "zh_CN": "一个监听器加载的访问控制组不能超过{0}", + "raw": "failed to find enough mdev device of spec[uuid:%s] in dest host[uuid:%s] for vm[uuid:%s]", + "en_US": "failed to find enough mdev device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}]", + "zh_CN": "无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的MDEV设备", "arguments": [ - "LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class)" + "specUuid", + "hostUuid", + "vmUuid" ], - "line": 457, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 308, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" }, { - "raw": "invalid max connection[%s], %s is larger than upper threshold %d", - "en_US": "invalid max connection[{0}], {1} is larger than upper threshold {2}", - "zh_CN": "非法的最大连接数标签[{0}],因为其值{1}大于上限值{2}", + "raw": "cannot find mdev device[uuid:%s], it may have been deleted", + "en_US": "cannot find mdev device[uuid:{0}], it may have been deleted", + "zh_CN": "找不到MDEV设备[uuid:{0}]", "arguments": [ - "tag", - "s", - "LoadBalancerConstants.MAX_CONNECTION_LIMIT" + "msg.getMdevDeviceUuid()" ], - "line": 537, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 352, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" }, { - "raw": "conflict loadBalancerPort[%s], a listener[uuid:%s] has used that port", - "en_US": "conflict loadBalancerPort[{0}], a listener[uuid:{1}] has used that port", - "zh_CN": "冲突的负载均衡器端口(loadBalancerPort)[{0}],一个监听器[uuid:{1}]已经使用了该端口", + "raw": "mdev device[uuid:%s] doesn\u0027t exist or is disabled for vm[uuid:%s]", + "en_US": "mdev device[uuid:{0}] doesn\u0027t exist or is disabled for vm[uuid:{1}]", + "zh_CN": "MDEV设备[uuid:{0}]不存在或已为VM[uuid:{1}]禁用", "arguments": [ - "msg.getLoadBalancerPort()", - "luuid" + "vo.getUuid()", + "vmUuid" ], - "line": 559, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 555, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" }, { - "raw": "udp port 53 is used by dns daemon", - "en_US": "udp port 53 is used by dns daemon", - "zh_CN": "udp端口53已经被dns进程使用", - "arguments": [], - "line": 564, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "raw": "can not migrate vm[uuid:%s] since mdev device attached", + "en_US": "can not migrate vm[uuid:{0}] since mdev device attached", + "zh_CN": "无法迁移云主机[uuid:{0}],因为它挂载了MDEV设备", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 644, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" }, { - "raw": "tcp port 22, 7272 is used by vrouter", - "en_US": "tcp port 22, 7272 is used by vrouter", - "zh_CN": "tcp端口22,7272已经被vrouter管理进程进程使用", - "arguments": [], - "line": 577, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "raw": "cannot migrate root volume[uuid:%s] because there are mdev devices attached", + "en_US": "cannot migrate root volume[uuid:{0}] because there are mdev devices attached", + "zh_CN": "无法迁移跟云盘[uuid:{0}],因为它所在云主机挂载了MDEV设备", + "arguments": [ + "msg.getVolumeUuid()" + ], + "line": 673, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" }, { - "raw": "loadbalancer listener with type %s does not need certificate", - "en_US": "loadbalancer listener with type {0} does not need certificate", - "zh_CN": "[{0}]类型证书不需要证书", + "raw": "cannot migrate vm[uuid:%s] because there are mdev devices attached", + "en_US": "cannot migrate vm[uuid:{0}] because there are mdev devices attached", + "zh_CN": "无法迁移云主机[uuid:{0}],因为它挂载了MDEV设备", "arguments": [ - "vo.getProtocol()" + "msg.getVmInstanceUuid()" ], - "line": 604, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 688, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" }, { - "raw": "loadbalancer listener [uuid:%s] already had certificate[uuid:%s]", - "en_US": "loadbalancer listener [uuid:{0}] already had certificate[uuid:{1}]", - "zh_CN": "", + "raw": "mdev device[uuid:%s] can not attach to vm[uuid:%s] due to wrong status", + "en_US": "mdev device[uuid:{0}] can not attach to vm[uuid:{1}] due to wrong status", + "zh_CN": "由于状态错误,MDEV设备[uuid:{0}]无法连接到VM[uuid:{1}]", "arguments": [ - "msg.getListenerUuid()", - "msg.getCertificateUuid()" + "wrongStatusMdevUuids", + "vmUuid" ], - "line": 608, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 129, + "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceReserveFlow.java" }, { - "raw": "certificate [uuid:%s] is not added to loadbalancer listener [uuid:%s]", - "en_US": "certificate [uuid:{0}] is not added to loadbalancer listener [uuid:{1}]", - "zh_CN": "证书[uuid:{0}]未添加到负载均衡监听器[uuid:{1}]", + "raw": "No host with fewer than %s vms found", + "en_US": "No host with fewer than {0} vms found", + "zh_CN": "找不到VM少于{0}的物理机", "arguments": [ - "msg.getCertificateUuid()", - "msg.getListenerUuid()" + "String.format(\"maxInstancePerHost \u003d %d\", maxInstancePerHost)" ], - "line": 618, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 71, + "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostAllocatorFlow.java" }, { - "raw": "healthCheck target [%s] error, it must be \u0027default\u0027 or number between[1~65535] ", - "en_US": "healthCheck target [{0}] error, it must be \u0027default\u0027 or number between[1~65535] ", - "zh_CN": "健康检查端口[{0}]错误,值必须是\u0027default\u0027或者数字[1~65535]", + "raw": "%s must be a number", + "en_US": "{0} must be a number", + "zh_CN": "{0}必须是一个数字", "arguments": [ - "target" + "HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN" ], - "line": 633, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "line": 76, + "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java" }, { - "raw": "the http health check protocol must be specified its healthy checking parameters including healthCheckMethod and healthCheckURI", - "en_US": "the http health check protocol must be specified its healthy checking parameters including healthCheckMethod and healthCheckURI", - "zh_CN": "http类型的健康检查协议必须提供healthCheckMethod和healthCheckURI参数", - "arguments": [], - "line": 683, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java" + "raw": "Select %s strategy, you must set %s", + "en_US": "Select {0} strategy, you must set {1}", + "zh_CN": "选择策略{0},你必须设置{1}", + "arguments": [ + "HostAllocatorConstant.MAX_INSTANCE_PER_HOST_HOST_ALLOCATOR_STRATEGY_TYPE", + "HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN" + ], + "line": 58, + "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java" }, { - "raw": "the L3 network of vm nic[uuid:%s] doesn\u0027t have load balancer service enabled", - "en_US": "the L3 network of vm nic[uuid:{0}] doesn\u0027t have load balancer service enabled", - "zh_CN": "虚拟机网卡[uuid:{0}]的L3网络没有启用负载均衡服务", + "raw": "Incorrect %s settings, valid value is %s", + "en_US": "Incorrect {0} settings, valid value is {1}", + "zh_CN": "不正确的设置{0},有效的值是{1}", "arguments": [ - "msg.getVmNicUuids().get(0)" + "HostAllocatorSystemTags.MINIMUM_MEMORY_USAGE_HOST_ALLOCATOR_STRATEGY_MODE_TOKEN", + "modes" ], - "line": 1113, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" + "line": 58, + "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MinimumMemoryUsageHostAllocatorStrategyFactory.java" + }, + { + "raw": "default route network can not be changed when system policy route is enabled", + "en_US": "default route network can not be changed when system policy route is enabled", + "zh_CN": "启用系统策略路由时,无法更改默认路由网络", + "arguments": [], + "line": 93, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "service provider type mismatching. The load balancer[uuid:%s] is provided by the service provider[type:%s], but the L3 network of vm nic[uuid:%s] is enabled with the service provider[type: %s]", - "en_US": "service provider type mismatching. The load balancer[uuid:{0}] is provided by the service provider[type:{1}], but the L3 network of vm nic[uuid:{2}] is enabled with the service provider[type: {3}]", - "zh_CN": "网络服务提供器的类型不匹配。负载均衡器[uuid:{0}]由服务提供器[type:{1}]提供,但虚拟机网卡[uuid:{2}]的L3网络启用服务器类型为[type: {3}]", - "arguments": [ - "self.getUuid()", - "self.getProviderType()", - "msg.getVmNicUuids().get(0)", - "providerType" - ], - "line": 1140, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" + "raw": "can not find related virtual router", + "en_US": "can not find related virtual router", + "zh_CN": "找不到相关的虚拟路由器", + "arguments": [], + "line": 382, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid health checking parameters[%s], the format is method:URI:code, for example, GET:/index.html:http_2xx", - "en_US": "invalid health checking parameters[{0}], the format is method:URI:code, for example, GET:/index.html:http_2xx", - "zh_CN": "无效的健康检查参数[{0}],正确格式:method:URI:code,例如 GET:/index.html:http_2xx", + "raw": "l3[%s] already attached a policy route ruleSet", + "en_US": "l3[{0}] already attached a policy route ruleSet", + "zh_CN": "L3[{0}]已附加策略路由规则集", "arguments": [ - "param" + "msg.getL3Uuid()" ], - "line": 1670, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java" + "line": 132, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "cannot find the load balancer[uuid:%s]", - "en_US": "cannot find the load balancer[uuid:{0}]", - "zh_CN": "无法找到负载均衡器[uuid:{0}]", + "raw": "VRouter[%s] already has a ruleSet named %s", + "en_US": "VRouter[{0}] already has a ruleSet named {1}", + "zh_CN": "VRouter[{0}]已具有名为{1}的规则集", "arguments": [ - "msg.getLoadBalancerUuid()" + "msg.getvRouterUuid()", + "msg.getName()" ], - "line": 99, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 192, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "cannot delete the system tag[%s]. The load balancer plugin relies on it, you can only update it", - "en_US": "cannot delete the system tag[{0}]. The load balancer plugin relies on it, you can only update it", - "zh_CN": "无法删除系统标签[{0}]。负载均衡器插件依赖于该标签,该标签只能被更新", - "arguments": [ - "tag.getTag()" - ], - "line": 381, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "raw": "can not update system policy route set", + "en_US": "can not update system policy route set", + "zh_CN": "无法更新系统策略路由集", + "arguments": [], + "line": 283, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "nic[uuid:%s] not found. Please correct your system tag[%s] of loadbalancer", - "en_US": "nic[uuid:{0}] not found. Please correct your system tag[{1}] of loadbalancer", - "zh_CN": "找不到网卡[uuid:{0}]。请检查负载均衡器的系统标签[{1}]", + "raw": "DestinationCidr must be in cidr format but found [%s]", + "en_US": "DestinationCidr must be in cidr format but found [{0}]", + "zh_CN": "DestinationCIDR必须为CIDR格式,但找到[{0}]", "arguments": [ - "nicUuid", - "systemTag" + "msg.getDestinationCidr()" ], - "line": 399, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 198, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid balancer weight[%s], %s is not a number", - "en_US": "invalid balancer weight[{0}], {1} is not a number", - "zh_CN": "无效的权重值[{0}], {1}不是一个数字", + "raw": "NextHopIp must be in ipv4 format but found [%s]", + "en_US": "NextHopIp must be in ipv4 format but found [{0}]", + "zh_CN": "NextHopIP必须为IPv4格式,但找到[{0}]", "arguments": [ - "systemTag", - "s" + "msg.getNextHopIp()" ], - "line": 411, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 202, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid balancer weight[%s], %s is not in the range [%d, %d]", - "en_US": "invalid balancer weight[{0}], {1} is not in the range [{2}, {3}]", - "zh_CN": "无效的权重值[{0}], {1}不在允许范围[{2}, {3}]中", - "arguments": [ - "systemTag", - "s", - "LoadBalancerConstants.BALANCER_WEIGHT_MIN", - "LoadBalancerConstants.BALANCER_WEIGHT_MAX" - ], - "line": 407, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "raw": "can not find related vRouter", + "en_US": "can not find related vRouter", + "zh_CN": "找不到相关的VRouter", + "arguments": [], + "line": 278, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid balance algorithm[%s], valid algorithms are %s", - "en_US": "invalid balance algorithm[{0}], valid algorithms are {1}", - "zh_CN": "无效的均衡算法[{0}],有效的为[{1}]", - "arguments": [ - "algorithm", - "LoadBalancerConstants.BALANCE_ALGORITHMS" - ], - "line": 423, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "raw": "can not update system policy route table", + "en_US": "can not update system policy route table", + "zh_CN": "无法更新系统策略路由表", + "arguments": [], + "line": 288, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid unhealthy threshold[%s], %s is not a number", - "en_US": "invalid unhealthy threshold[{0}], {1} is not a number", - "zh_CN": "无效的不健康阈值[{0}],[{1}]不是一个数字", + "raw": "operation failure, ip format only supports ipv4/iprange/cidr, but find %s", + "en_US": "operation failure, ip format only supports ipv4/iprange/cidr, but find {0}", + "zh_CN": "操作失败,IP格式仅支持IPv4/IPRange/CIDR,但找到{0}", "arguments": [ - "systemTag", - "s" + "ip" ], - "line": 497, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 237, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid healthy threshold[%s], %s is not a number", - "en_US": "invalid healthy threshold[{0}], {1} is not a number", - "zh_CN": "无效的健康阈值[{0}],[{1}]不是一个数字", + "raw": "illegal protocol type %s", + "en_US": "illegal protocol type {0}", + "zh_CN": "非法的协议类型{0}", "arguments": [ - "systemTag", - "s" + "protocol" ], - "line": 511, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 245, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid healthy timeout[%s], %s is not a number", - "en_US": "invalid healthy timeout[{0}], {1} is not a number", - "zh_CN": "无效的健康超时[{0}],[{1}]不是一个数字", + "raw": "RuleSet[%s] already has a rule with rule number %s.", + "en_US": "RuleSet[{0}] already has a rule with rule number {1}.", + "zh_CN": "规则集[{0}]已具有规则编号为{1}的规则。", "arguments": [ - "systemTag", - "s" + "msg.getRuleSetUuid()", + "msg.getRuleNumber()" ], - "line": 525, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 254, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid connection idle timeout[%s], %s is not a number", - "en_US": "invalid connection idle timeout[{0}], {1} is not a number", - "zh_CN": "无效的连接空闲超时[{0}],[{1}]不是一个数字", + "raw": "VRouter[%s] already has a policy route table [%s]", + "en_US": "VRouter[{0}] already has a policy route table [{1}]", + "zh_CN": "VRouter[{0}]已具有策略路由表[{1}]", "arguments": [ - "systemTag", - "s" + "msg.getvRouterUuid()", + "msg.getNumber()" ], - "line": 539, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 310, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid health check interval[%s], %s is not a number", - "en_US": "invalid health check interval[{0}], {1} is not a number", - "zh_CN": "无效的健康检查间隔[{0}],[{1}]不是一个数字", - "arguments": [ - "systemTag", - "s" - ], - "line": 553, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "raw": "can not delete system policy route table", + "en_US": "can not delete system policy route table", + "zh_CN": "无法删除系统策略路由表", + "arguments": [], + "line": 387, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid max connection[%s], %s is not a number", - "en_US": "invalid max connection[{0}], {1} is not a number", - "zh_CN": "无效的最大连接[{0}],[{1}]不是一个数字", - "arguments": [ - "systemTag", - "s" - ], - "line": 567, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "raw": "can not delete system policy route set", + "en_US": "can not delete system policy route set", + "zh_CN": "无法删除系统策略路由集", + "arguments": [], + "line": 371, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid health target[%s], the target checking protocol[%s] is invalid, valid protocols are %s", - "en_US": "invalid health target[{0}], the target checking protocol[{1}] is invalid, valid protocols are {2}", - "zh_CN": "无效的健康检查目标[{0}],目标检查协议无效[{1}],有效的为[{2}]", + "raw": "ruleSet[%s] is still attached to nic", + "en_US": "ruleSet[{0}] is still attached to nic", + "zh_CN": "规则集[{0}]仍连接到NIC", "arguments": [ - "systemTag", - "protocol", - "LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCOLS" + "msg.getUuid()" ], - "line": 585, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 360, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" }, { - "raw": "invalid invalid health target[%s], port[%s] is not a number", - "en_US": "invalid invalid health target[{0}], port[{1}] is not a number", - "zh_CN": "无效的健康检查目标[{0}],端口[{1}]不是一个数字", + "raw": "virtual router[uuid:%s] can not find", + "en_US": "virtual router[uuid:{0}] can not find", + "zh_CN": "云路由[uuid:{0}]未找到", "arguments": [ - "systemTag", - "port" + "vrouterVmUuid" ], - "line": 597, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 958, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java" }, { - "raw": "invalid invalid health target[%s], port[%s] is not in the range of [1, 65535]", - "en_US": "invalid invalid health target[{0}], port[{1}] is not in the range of [1, 65535]", - "zh_CN": "无效的无效健康检查目标[{0}],端口[{1}]不在范围[1, 65535]内", + "raw": "can not find service factory for virtual router type[%s]", + "en_US": "can not find service factory for virtual router type[{0}]", + "zh_CN": "未找到云路由类型为[{0}]的服务工厂", "arguments": [ - "systemTag", - "port" + "vo.getApplianceVmType()" ], - "line": 594, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java" + "line": 963, + "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java" }, { - "raw": "invalid balancer weight for nic:%s, %d is not in the range [%d, %d]", - "en_US": "invalid balancer weight for nic:{0}, {1} is not in the range [{2}, {3}]", - "zh_CN": "无效的网卡:{0}权重值{1},不在有效范围[{2}, {3}]内", + "raw": "Invalid parameter [%s], make sure it\u0027s PortMirror Network", + "en_US": "Invalid parameter [{0}], make sure it\u0027s PortMirror Network", + "zh_CN": "参数[{0}]无效,请确保它是PortMirror网络", "arguments": [ - "nicUuid", - "weight", - "LoadBalancerConstants.BALANCER_WEIGHT_MIN", - "LoadBalancerConstants.BALANCER_WEIGHT_MAX" + "msg.getMirrorNetworkUuid()" ], - "line": 74, - "fileName": "src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java" + "line": 54, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "guest l3Network of vm nic[uuid:%s] and vip l3Network of vip[uuid: %s] are the same network", - "en_US": "guest l3Network of vm nic[uuid:{0}] and vip l3Network of vip[uuid: {1}] are the same network", - "zh_CN": "虚拟机网卡[uuid:{0}]的客户L3网络和虚拟IP[uuid:{1}]的虚拟IP L3网络是同一个网络", + "raw": "The network[%s] has been attached with a PortMirror service", + "en_US": "The network[{0}] has been attached with a PortMirror service", + "zh_CN": "网络[{0}]已附加PortMirror服务", "arguments": [ - "msg.getVmNicUuid()", - "msg.getVipUuid()" + "msg.getMirrorNetworkUuid()" ], - "line": 206, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 62, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "the vip[uuid:%s] has been occupied other network service entity[%s]", - "en_US": "the vip[uuid:{0}] has been occupied other network service entity[{1}]", - "zh_CN": "虚拟IP[uuid:{0}]已经被其他网络服务占用", + "raw": "The PortMirror service[%s] has not been created", + "en_US": "The PortMirror service[{0}] has not been created", + "zh_CN": "尚未创建PortMirror服务[{0}]", "arguments": [ - "msg.getVipUuid()", - "useForList.toString()" + "msg.getUuid()" ], - "line": 181, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 70, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "Port forwarding rule[uuid:%s] is not in state of Enabled, current state is %s", - "en_US": "Port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1}", - "zh_CN": "端口转发规则[uuid:{0}]未启用,当前状态[{1}]", + "raw": "The nic[%s, %s] has been mirrored by service[%s]", + "en_US": "The nic[{0}, {1}] has been mirrored by service[{2}]", + "zh_CN": "NIC[{0},{1}]已由服务[{2}]镜像", "arguments": [ - "msg.getRuleUuid()", - "state" + "msg.getSrcEndPoint()", + "msg.getDstEndPoint()", + "mirror.getUuid()" ], - "line": 66, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 86, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "port forwarding rule rule[uuid:%s] has not been attached to any vm nic, can\u0027t detach", - "en_US": "port forwarding rule rule[uuid:{0}] has not been attached to any vm nic, can\u0027t detach", - "zh_CN": "端口转发规则[uuid:{0}]尚未被挂载到任何虚拟机网卡,无法卸载", + "raw": "The nic[%s] can\u0027t been mirrored for service[%s] using", + "en_US": "The nic[{0}] can\u0027t been mirrored for service[{1}] using", + "zh_CN": "无法使用为服务[{1}]镜像NIC[{0}]", "arguments": [ - "msg.getUuid()" + "msg.getSrcEndPoint()", + "mirror.getUuid()" ], - "line": 81, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 92, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "port forwarding rule[uuid:%s] has been attached to vm nic[uuid:%s], can\u0027t attach again", - "en_US": "port forwarding rule[uuid:{0}] has been attached to vm nic[uuid:{1}], can\u0027t attach again", - "zh_CN": "端口转发规则[uuid:{0}]已经被挂载到虚拟机网卡[uuid:{1}],无法再次挂载", + "raw": "The PortMirror service doesn\u0027t support to mirror the nic[%s]", + "en_US": "The PortMirror service doesn\u0027t support to mirror the nic[{0}]", + "zh_CN": "PortMirror服务不支持镜像网卡[{0}]", "arguments": [ - "msg.getRuleUuid()", - "vmNicUuid" + "msg.getSrcEndPoint()" ], - "line": 95, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 109, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "port forwarding rule[uuid:%s] is not in state of Enabled, current state is %s. A rule can only be attached when its state is Enabled", - "en_US": "port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1}. A rule can only be attached when its state is Enabled", - "zh_CN": "端口转发规则[uuid:{0}]没有启用,当前状态为{1}。一个规则只能在启用时被挂载", + "raw": "The PortMirror service doesn\u0027t support the nic[%s] because of its hypervisor type", + "en_US": "The PortMirror service doesn\u0027t support the nic[{0}] because of its hypervisor type", + "zh_CN": "由于其云主机监控程序类型,PortMirror服务不支持NIC[{0}]", "arguments": [ - "msg.getRuleUuid()", - "state" + "msg.getDstEndPoint()" ], - "line": 100, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 114, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "guest l3Network of vm nic[uuid:%s] and vip l3Network of port forwarding rule[uuid:%s] are the same network", - "en_US": "guest l3Network of vm nic[uuid:{0}] and vip l3Network of port forwarding rule[uuid:{1}] are the same network", - "zh_CN": "虚拟机网卡[uuid:{0}]的客户L3网络和端口转发规则[uuid:{1}]的VIP L3网络是同一个网络", + "raw": "The PortMirror service can\u0027t mirror to the nic[%s] that is not a non-default interface of a vm", + "en_US": "The PortMirror service can\u0027t mirror to the nic[{0}] that is not a non-default interface of a vm", + "zh_CN": "PortMirror服务无法镜像到不是VM的非默认接口的NIC[{0}]", "arguments": [ - "msg.getVmNicUuid()", - "msg.getRuleUuid()" + "msg.getDstEndPoint()" ], - "line": 119, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 121, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "for range port forwarding, the port range size must match; vip range[%s, %s]\u0027s size doesn\u0027t match range[%s, %s]\u0027s size", - "en_US": "for range port forwarding, the port range size must match; vip range[{0}, {1}]\u0027s size doesn\u0027t match range[{2}, {3}]\u0027s size", - "zh_CN": "对于范围端口转发,端口范围大小必须匹配;VIP范围[{0}, {1}]的大小不匹配范围[{2}, {3}]的大小", + "raw": "The PortMirror service can\u0027t mirror the nic[%s] that is not an interface of any vm", + "en_US": "The PortMirror service can\u0027t mirror the nic[{0}] that is not an interface of any vm", + "zh_CN": "PortMirror服务无法镜像不是任何VM接口的NIC[{0}]", "arguments": [ - "msg.getVipPortStart()", - "msg.getVipPortEnd()", - "msg.getPrivatePortStart()", - "msg.getPrivatePortEnd()" + "msg.getSrcEndPoint()" ], - "line": 166, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 128, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "invalid CIDR[%s]", - "en_US": "invalid CIDR[{0}]", - "zh_CN": "无效的CIDR[{0}]", + "raw": "The PortMirror service can\u0027t mirror the nic[%s] to nic[%s] because the mirror network[%s] can\u0027t setup the mirror tunnel", + "en_US": "The PortMirror service can\u0027t mirror the nic[{0}] to nic[{1}] because the mirror network[{2}] can\u0027t setup the mirror tunnel", + "zh_CN": "PortMirror服务无法将NIC[{0}]镜像到NIC[{1}],因为镜像网络[{2}]无法设置镜像隧道", "arguments": [ - "msg.getAllowedCidr()" + "msg.getSrcEndPoint()", + "msg.getDstEndPoint()", + "vo.getMirrorNetworkUuid()" ], - "line": 173, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 138, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "vip port range[vipStartPort:%s, vipEndPort:%s] overlaps with rule[uuid:%s, vipStartPort:%s, vipEndPort:%s]", - "en_US": "vip port range[vipStartPort:{0}, vipEndPort:{1}] overlaps with rule[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}]", - "zh_CN": "虚拟IP(vip)端口范围[vipStartPort:{0}, vipEndPort:{1}]与规则[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}]重叠", + "raw": "The PortMirror service can\u0027t mirror the nic[%s] to itself", + "en_US": "The PortMirror service can\u0027t mirror the nic[{0}] to itself", + "zh_CN": "PortMirror服务无法将NIC[{0}]镜像到其自身", "arguments": [ - "vipStart", - "vipEnd", - "vo.getUuid()", - "vo.getVipPortStart()", - "vo.getVipPortEnd()" + "msg.getSrcEndPoint()" ], - "line": 191, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "line": 144, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "the VM[name:%s uuid:%s] already has port forwarding rules that have different VIPs than the one[uuid:%s]", - "en_US": "the VM[name:{0} uuid:{1}] already has port forwarding rules that have different VIPs than the one[uuid:{2}]", - "zh_CN": "虚拟机[name:{0} uuid:{1}]已经有端口转发规则,且与[uuid:{2}]有不同的VIPs", - "arguments": [ - "vm.getName()", - "vm.getUuid()", - "vipUuid" - ], - "line": 243, - "fileName": "src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java" + "raw": "The PortMirror service can\u0027t work at the nic with configured Qos", + "en_US": "The PortMirror service can\u0027t work at the nic with configured Qos", + "zh_CN": "PortMirror服务无法在配置了QoS的NIC上工作", + "arguments": [], + "line": 153, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" }, { - "raw": "unsupported ip allocation strategy[%s]", - "en_US": "unsupported ip allocation strategy[{0}]", - "zh_CN": "不支持的ip分配策略[{0}]", + "raw": "failed to delete portMirror session[%s] from hypervisor, detail: %s", + "en_US": "failed to delete portMirror session[{0}] from hypervisor, detail: {1}", + "zh_CN": "无法从云主机监控程序中删除PortMirror会话[{0}],详细信息:{1}", "arguments": [ - "msg.getAllocatorStrategy()" + "sessionVO.getUuid()", + "errorCode.getDetails()" ], - "line": 49, - "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" + "line": 761, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java" }, { - "raw": "requiredIp[%s] is not in valid IPv6 mediaType", - "en_US": "requiredIp[{0}] is not in valid IPv6 mediaType", - "zh_CN": "请求的ip[{0}]不是有效的IPv6地址", + "raw": "failed to release portMirror session[%s] from hypervisor, detail: %s", + "en_US": "failed to release portMirror session[{0}] from hypervisor, detail: {1}", + "zh_CN": "无法从云主机监控程序释放PortMirror会话[{0}],详细信息:{1}", "arguments": [ - "msg.getRequiredIp()" + "sessionVO.getUuid()", + "errorCode.getDetails()" ], - "line": 61, - "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" + "line": 794, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java" }, { - "raw": "requiredIp[%s] is not in valid IPv4 mediaType", - "en_US": "requiredIp[{0}] is not in valid IPv4 mediaType", - "zh_CN": "请求的ip[{0}]不是有效的IPv4地址", + "raw": "cannot find internal id of the session[uuid:%s], are there too many sessions in a host???", + "en_US": "cannot find internal id of the session[uuid:{0}], are there too many sessions in a host???", + "zh_CN": "找不到会话[uuid:{0}]的内部ID,物理机中是否有太多会话??", "arguments": [ - "msg.getRequiredIp()" + "vo.getUuid()" ], - "line": 56, - "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" + "line": 912, + "fileName": "src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java" }, { - "raw": "there is already a vip[%s] on l3Network[uuid:%s]", - "en_US": "there is already a vip[{0}] on l3Network[uuid:{1}]", - "zh_CN": "已有一个vip[{0}]在L3网络[uuid:{1}]上", + "raw": "resourceUuid[%s] is not a valid uuid. A valid uuid is a uuid(v4 recommended) with \u0027-\u0027 stripped. see http://en.wikipedia.org/wiki/Universally_unique_identifier for format of uuid, the regular expression uses to validate a uuid is \u0027[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}\u0027", + "en_US": "resourceUuid[{0}] is not a valid uuid. A valid uuid is a uuid(v4 recommended) with \u0027-\u0027 stripped. see http://en.wikipedia.org/wiki/Universally_unique_identifier for format of uuid, the regular expression uses to validate a uuid is \u0027[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}\u0027", + "zh_CN": "Resourceuuid[{0}]不是有效的uuid。有效的uuid是去除了“-”的uuid(建议使用v4)。a.请参阅http://en.wikipediorg/wiki/Universally_unique_identifier for format of uuid,用于验证uuid的正则表达式是“[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9A-f){3}[89ab][O-9A-F]{3}[O-9A-F]{12}”", "arguments": [ - "msg.getRequiredIp()", - "msg.getL3NetworkUuid()" + "cmsg.getResourceUuid()" ], - "line": 70, - "fileName": "src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java" + "line": 276, + "fileName": "src/main/java/org/zstack/portal/apimediator/ApiMediatorImpl.java" }, { - "raw": "service provider of the vip[uuid:%s, name:%s, ip: %s] has been set to %s", - "en_US": "service provider of the vip[uuid:{0}, name:{1}, ip: {2}] has been set to {3}", - "zh_CN": "vip[uuid:{0}, name:{1}, ip: {2}]的服务提供器已经被设置成[{3}]", + "raw": "non support method: %s", + "en_US": "non support method: {0}", + "zh_CN": "不支持方法:{0}", "arguments": [ - "self.getUuid()", - "self.getName()", - "self.getIp()", - "self.getServiceProvider()" + "method" ], - "line": 152, - "fileName": "src/main/java/org/zstack/network/service/vip/VipBase.java" + "line": 122, + "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java" }, { - "raw": "Vip [uuid %s, ip %s] of router public interface can not be deleted", - "en_US": "Vip [uuid {0}, ip {1}] of router public interface can not be deleted", - "zh_CN": "路由公共接口的虚拟IP[uuid {0}, ip {1}]不能删除", + "raw": "http request error! status_code: %s, error: %s", + "en_US": "http request error! status_code: {0}, error: {1}", + "zh_CN": "HTTP请求错误!状态_代码:{0},错误:{1}", "arguments": [ - "self.getUuid()", - "self.getIp()" + "statusCode", + "response.getStatusLine().getReasonPhrase()" ], - "line": 712, - "fileName": "src/main/java/org/zstack/network/service/vip/VipBase.java" - }, - { - "raw": "VipQos for ipv6 wil be added soon", - "en_US": "VipQos for ipv6 wil be added soon", - "zh_CN": "", - "arguments": [], - "line": 43, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "line": 134, + "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java" }, { - "raw": "VipQos for Vip [uuid: %s] already existed", - "en_US": "VipQos for Vip [uuid: {0}] already existed", - "zh_CN": "虚拟IP[uuid: {0}]的Qos已经存在了", + "raw": "sqlite3 execute failed, because: %s", + "en_US": "sqlite3 execute failed, because: {0}", + "zh_CN": "SQLite3执行失败,因为:{0}", "arguments": [ - "msg.getVipUuid()" + "r.getStderr()" ], - "line": 53, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "line": 24, + "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaDB.java" }, { - "raw": "VipQos for Vip [uuid: %s] port %s already existed", - "en_US": "VipQos for Vip [uuid: {0}] port {1} already existed", - "zh_CN": "虚拟IP[uuid: {0}]的Qos端口{1}已经存在", + "raw": "cannot find folder: %s in dashboard", + "en_US": "cannot find folder: {0} in dashboard", + "zh_CN": "在仪表板中找不到文件夹:{0}", "arguments": [ - "msg.getVipUuid()", - "Integer.toString(msg.getPort())" + "GrafanaDB.folderTitle" ], - "line": 48, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "line": 34, + "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaDashboard.java" }, { - "raw": "SetVipQos MUST set InboundBandwidth or OutboundBandwidth", - "en_US": "SetVipQos MUST set InboundBandwidth or OutboundBandwidth", - "zh_CN": "设置虚拟IP的Qos是必须设置上行网络带宽和下行网络带宽", - "arguments": [], - "line": 59, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "raw": "cannot copy %s to %s, caused: %s", + "en_US": "cannot copy {0} to {1}, caused: {2}", + "zh_CN": "无法将{0}复制到{1},原因:{2}", + "arguments": [ + "src.getAbsolutePath()", + "dst.getAbsolutePath()", + "rst.getStderr()" + ], + "line": 84, + "fileName": "src/main/java/org/zstack/premium/externalservice/loki/LokiFactory.java" }, { - "raw": "Cannot set Qos for this Vip. Not all peer l3networks provide VipQos service.", - "en_US": "Cannot set Qos for this Vip. Not all peer l3networks provide VipQos service.", - "zh_CN": "", + "raw": "ssh failed", + "en_US": "ssh failed", + "zh_CN": "SSH失败", "arguments": [], - "line": 67, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "line": 103, + "fileName": "src/main/java/org/zstack/premium/externalservice/loki/PromtailFactory.java" }, { - "raw": "VipQos for Vip [uuid: %s] does not exist", - "en_US": "VipQos for Vip [uuid: {0}] does not exist", - "zh_CN": "虚拟IP[uuid: {0}]的Qos不存在", + "raw": "unknown value type %s, key \u003d %s", + "en_US": "unknown value type {0}, key \u003d {1}", + "zh_CN": "未知的值类型{0},键\u003d{1}", "arguments": [ - "msg.getUuid()" + "v.getClass().getSimpleName()", + "k" ], - "line": 80, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "line": 124, + "fileName": "src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java" }, { - "raw": "VipQos for Vip [uuid: %s] port %s does not exist", - "en_US": "VipQos for Vip [uuid: {0}] port {1} does not exist", - "zh_CN": "虚拟IP[uuid: {0}]的Qos端口{1}不存在", - "arguments": [ - "msg.getUuid()", - "Integer.toString(msg.getPort())" - ], - "line": 75, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java" + "raw": "failed to HTTP call all prometheus instances", + "en_US": "failed to HTTP call all prometheus instances", + "zh_CN": "无法对所有Prometheus实例进行HTTP调用", + "arguments": [], + "line": 153, + "fileName": "src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java" }, { - "raw": "Can not find VipQos backend for Vip [uuid:%s]", - "en_US": "Can not find VipQos backend for Vip [uuid:{0}]", - "zh_CN": "未找到虚拟IP的Qos后端", + "raw": "the operation is not permitted by white list of virtual-id[uuid:%s]", + "en_US": "the operation is not permitted by white list of virtual-id[uuid:{0}]", + "zh_CN": "无法操作,操作不存在用户[uuid:{0}]白名单中", "arguments": [ - "vipUuid" + "rbacEntity.getApiMessage().getSession().getUserUuid()" ], - "line": 129, - "fileName": "src/main/java/org/zstack/network/service/vipQos/VipQosManagerImpl.java" + "line": 48, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminAPIRequestChecker.java" }, { - "raw": "operation error, vip %s has not bind to vm", - "en_US": "operation error, vip {0} has not bind to vm", - "zh_CN": "操作失败,虚拟IP{0}没有绑定虚拟机", + "raw": "the operation is denied by black list of virtual-id[uuid:%s]", + "en_US": "the operation is denied by black list of virtual-id[uuid:{0}]", + "zh_CN": "无法操作,操作被用户[uuid:{0}]黑名单拒绝", "arguments": [ - "hostUuid" + "rbacEntity.getApiMessage().getSession().getUserUuid()" ], - "line": 197, - "fileName": "src/main/java/org/zstack/network/service/vipQos/flat/FlatVipQosBackend.java" + "line": 60, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminAPIRequestChecker.java" }, { - "raw": "the virtual router[name:%s, uuid:%s, current state:%s] is not running,and cannot perform required operation. Please retry your operation later once it is running", - "en_US": "the virtual router[name:{0}, uuid:{1}, current state:{2}] is not running,and cannot perform required operation. Please retry your operation later once it is running", - "zh_CN": "云路由[name:{0}, uuid:{1}, current state:{2}]没有运行,无法执行请求的操作。请在其启动后重试", + "raw": "action: %s, is not supported for role identity: %s", + "en_US": "action: {0}, is not supported for role identity: {1}", + "zh_CN": "角色标识{1}不支持操作{0}", "arguments": [ - "self.getName()", - "self.getUuid()", - "self.getState()" + "unmatchedApis", + "identity.toString()" ], - "line": 277, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + "line": 199, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "virtual router[uuid:%s] is in status of %s that cannot make http call to %s", - "en_US": "virtual router[uuid:{0}] is in status of {1} that cannot make http call to {2}", - "zh_CN": "云路由[uuid:{0}]处于状态{1}中,无法向{2}发送http调用", + "raw": "%s is a reserved name, please use another name", + "en_US": "{0} is a reserved name, please use another name", + "zh_CN": "{0}是保留名称,请使用其他名称", "arguments": [ - "self.getUuid()", - "getSelf().getStatus()", - "msg.getPath()" + "msg.getName()" ], - "line": 282, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + "line": 372, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "virtual router[uuid:%s] has no management nic that cannot make http call to %s", - "en_US": "virtual router[uuid:{0}] has no management nic that cannot make http call to {1}", - "zh_CN": "", - "arguments": [ - "self.getUuid()", - "msg.getPath()" - ], - "line": 287, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + "raw": "the name of initial user can not be updated", + "en_US": "the name of initial user can not be updated", + "zh_CN": "无法更新初始用户的名称", + "arguments": [], + "line": 370, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "appliance vm %s reconnect failed", - "en_US": "appliance vm {0} reconnect failed", - "zh_CN": "", - "arguments": [ - "getSelf().getUuid()" - ], - "line": 397, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + "raw": "cannot remove builtin system admin role from builtin system admin.", + "en_US": "cannot remove builtin system admin role from builtin system admin.", + "zh_CN": "无法从内置系统管理员中删除内置系统管理员角色。", + "arguments": [], + "line": 407, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "unable to add nic[ip:%s, mac:%s] to virtual router vm[uuid:%s ip:%s], because %s", - "en_US": "unable to add nic[ip:{0}, mac:{1}] to virtual router vm[uuid:{2} ip:{3}], because {4}", - "zh_CN": "不能添加网卡[ip:{0}, mac:{1}]到虚拟路由设备[uuid:{2} ip:{3}],因为{4}", - "arguments": [ - "info.getIp()", - "info.getMac()", - "vr.getUuid()", - "vr.getManagementNic().getIp()", - "rsp.getError()" - ], - "line": 473, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + "raw": "cannot remove builtin security admin role from builtin security admin.", + "en_US": "cannot remove builtin security admin role from builtin security admin.", + "zh_CN": "无法从内置安全管理员中删除内置安全管理员角色。", + "arguments": [], + "line": 405, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "unable to detach nic[%s] from virtual router vm[uuid:%s ip:%s], because %s", - "en_US": "unable to detach nic[{0}] from virtual router vm[uuid:{1} ip:{2}], because {3}", - "zh_CN": "无法从云路由设备[uuid:{1} ip:{2}]上卸载网卡[{0}],错误细节: {3}", - "arguments": [ - "info", - "vr.getUuid()", - "vr.getManagementNic().getIp()", - "rsp.getError()" - ], - "line": 750, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java" + "raw": "cannot remove builtin audit admin role from builtin audit admin.", + "en_US": "cannot remove builtin audit admin role from builtin audit admin.", + "zh_CN": "无法从内置审核管理员中删除内置审核管理员角色。", + "arguments": [], + "line": 403, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "could not set the default network, because l3 uuid[:%s] is management network", - "en_US": "could not set the default network, because l3 uuid[:{0}] is management network", - "zh_CN": "设置默认网络失败,因为三层网路[:{0}] 是管理网络", + "raw": "cannot delete builtin system admin.", + "en_US": "cannot delete builtin system admin.", + "zh_CN": "无法删除内置系统管理员。", + "arguments": [], + "line": 417, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + }, + { + "raw": "cannot delete builtin security admin.", + "en_US": "cannot delete builtin security admin.", + "zh_CN": "无法删除内置安全管理员。", + "arguments": [], + "line": 415, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + }, + { + "raw": "cannot delete builtin audit admin.", + "en_US": "cannot delete builtin audit admin.", + "zh_CN": "无法删除内置审核管理员。", + "arguments": [], + "line": 413, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + }, + { + "raw": "Confirm the roles you want to add have same identity", + "en_US": "Confirm the roles you want to add have same identity", + "zh_CN": "确认要添加的角色具有相同的身份", + "arguments": [], + "line": 430, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + }, + { + "raw": "Cannot add role: %s with identity: %s to virtualID[uuid:%s]", + "en_US": "Cannot add role: {0} with identity: {1} to virtualID[uuid:{2}]", + "zh_CN": "无法将标识为{1}的角色{0}添加到VirtualID[uuid:{2}]", "arguments": [ - "msg.getDefaultRouteL3NetworkUuid()" + "msg.getRoleUuids()", + "identitySet", + "msg.getVirtualIDUuid()" ], - "line": 106, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 444, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "could not set the default network, because l3 uuid[:%s] is not public network", - "en_US": "could not set the default network, because l3 uuid[:{0}] is not public network", - "zh_CN": "设置默认网络失败,因为三层网路[:{0}] 不是公有网络", + "raw": "can not add privilege admin[uuids:%s] to project[uuid:%s]", + "en_US": "can not add privilege admin[uuids:{0}] to project[uuid:{1}]", + "zh_CN": "无法将特殊管理员用户[uuids:{0}]加入到项目中去", "arguments": [ - "msg.getDefaultRouteL3NetworkUuid()" + "String.join(\",\", privilegeAdminUuids)", + "msg.getProjectUuid()" ], - "line": 108, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 456, + "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" }, { - "raw": "image[uuid:%s]\u0027s mediaType is %s, the mediaType of a virtual router image must be %s", - "en_US": "image[uuid:{0}]\u0027s mediaType is {1}, the mediaType of a virtual router image must be {2}", - "zh_CN": "镜像[uuid:{0}]的mediaType为{1},云路由的mediaType必须为{2}", + "raw": "condition name[%s] is invalid, no such field on inventory class[%s]", + "en_US": "condition name[{0}] is invalid, no such field on inventory class[{1}]", + "zh_CN": "条件名[{0}]非法,在清单类里面没有这个阈", "arguments": [ - "msg.getImageUuid()", - "type", - "ImageMediaType.RootVolumeTemplate" + "attr", + "inventoryClass.getName()" ], - "line": 149, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 432, + "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" }, { - "raw": "image[uuid:%s] is of format %s, cannot be used for virtual router", - "en_US": "image[uuid:{0}] is of format {1}, cannot be used for virtual router", - "zh_CN": "镜像[uuid:{0}]的格式为{1},无法被用于云路由", + "raw": "condition name[%s] is invalid, field[%s] of inventory[%s] is annotated as @Unqueryable field", + "en_US": "condition name[{0}] is invalid, field[{1}] of inventory[{2}] is annotated as @Unqueryable field", + "zh_CN": "条件名[{0}]非法,清单[{2}]的值[{1}]不是被标记为@Unqueryable的值", "arguments": [ - "msg.getImageUuid()", - "format" + "attr", + "attr", + "inventoryClass.getName()" ], - "line": 155, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 437, + "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" }, { - "raw": "management network[uuid:%s] is not in the same zone[uuid:%s] this offering is going to create", - "en_US": "management network[uuid:{0}] is not in the same zone[uuid:{1}] this offering is going to create", - "zh_CN": "管理网络[uuid:{0}]和将要创建的规格不处于同一个区域(zone)[uuid:{1}]中", + "raw": "entity meta class[%s] has no field[%s]", + "en_US": "entity meta class[{0}] has no field[{1}]", + "zh_CN": "实体元类[{0}]中没有值[{1}]", "arguments": [ - "msg.getManagementNetworkUuid()", - "msg.getZoneUuid()" + "info.jpaMetaClass.getName()", + "attr" ], - "line": 125, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 448, + "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" }, { - "raw": "public network[uuid:%s] is not in the same zone[uuid:%s] this offering is going to create", - "en_US": "public network[uuid:{0}] is not in the same zone[uuid:{1}] this offering is going to create", - "zh_CN": "公共网络[uuid:{0}]和将要创建的规格不处于同一个区域(zone)[uuid:{1}]中", + "raw": "field[%s] is not a primitive of the inventory %s; you cannot specify it in the parameter \u0027fields\u0027;valid fields are %s", + "en_US": "field[{0}] is not a primitive of the inventory {1}; you cannot specify it in the parameter \u0027fields\u0027;valid fields are {2}", + "zh_CN": "值[{0}]不是清单{1}的原语;你不能在参数\u0027域\u0027中指定该参数;非法的域{2}", "arguments": [ - "msg.getManagementNetworkUuid()", - "msg.getZoneUuid()" + "f", + "info.inventoryClass.getSimpleName()", + "info.premitiveFieldNames" ], - "line": 138, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 1000, + "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" }, { - "raw": "the L3 network[uuid: %s] has the SNAT service enabled, it cannot be used as a public network", - "en_US": "the L3 network[uuid: {0}] has the SNAT service enabled, it cannot be used as a public network", - "zh_CN": "L3网络[uuid: {0}]启用了SNAT服务,无法被用作公共网络", + "raw": "filterName must be formatted as [filterType:condition(s)]", + "en_US": "filterName must be formatted as [filterType:condition(s)]", + "zh_CN": "FilterName的格式必须为[filterType:条件]", + "arguments": [], + "line": 519, + "fileName": "src/main/java/org/zstack/query/QueryFacadeImpl.java" + }, + { + "raw": "\u0027value\u0027 of query condition %s cannot be null", + "en_US": "\u0027value\u0027 of query condition {0} cannot be null", + "zh_CN": "查询条件中{0}的\u0027值\u0027不能为空", "arguments": [ - "msg.getPublicNetworkUuid()" + "JSONObjectUtil.toJsonString(cond)" ], - "line": 166, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 659, + "fileName": "src/main/java/org/zstack/query/QueryFacadeImpl.java" }, { - "raw": "the L3 network[uuid: %s] has the SNAT service enabled, it cannot be used as a management network", - "en_US": "the L3 network[uuid: {0}] has the SNAT service enabled, it cannot be used as a management network", - "zh_CN": "L3网络[uuid: {0}]启用了SNAT服务,无法被用作管理网络", + "raw": "resources has inconsistent resourceTypes. Details: %s", + "en_US": "resources has inconsistent resourceTypes. Details: {0}", + "zh_CN": "资源具有不一致的资源类型。详细信息:{0}", "arguments": [ - "msg.getManagementNetworkUuid()" + "typeByResourceUuids.toString()" ], - "line": 164, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 273, + "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfig.java" }, { - "raw": "the L3 network[uuid: %s] is same network address with [uuid: %s], it cannot be used for virtual router", - "en_US": "the L3 network[uuid: {0}] is same network address with [uuid: {1}], it cannot be used for virtual router", - "zh_CN": "L3网络[uuid: {0}] 和 网络 [uuid: {1}] 具有相同的网络地址,无法被用于云路由", + "raw": "cannot find resource[uuid: %s]", + "en_US": "cannot find resource[uuid: {0}]", + "zh_CN": "找不到资源[uuid:{0}]", "arguments": [ - "msg.getManagementNetworkUuid()", - "msg.getPublicNetworkUuid()" + "resourceUuid" ], - "line": 173, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 433, + "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfig.java" }, { - "raw": "the management network[uuid:%s] doesn\u0027t have any IP range", - "en_US": "the management network[uuid:{0}] doesn\u0027t have any IP range", - "zh_CN": "管理网络[uuid:{0}]不包含任何的IP范围", + "raw": "ResourceConfig [category:%s, name:%s] cannot bind to resourceType: %s", + "en_US": "ResourceConfig [category:{0}, name:{1}] cannot bind to resourceType: {2}", + "zh_CN": "ResourceConfig[类别:{0},名称:{1}]无法绑定到资源类型:{2}", "arguments": [ - "managementNetworkUuid" + "globalConfig.getCategory()", + "globalConfig.getName()", + "resourceType" ], - "line": 183, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 437, + "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfig.java" }, { - "raw": "the management network[uuid:%s, gateway:%s] is not reachable", - "en_US": "the management network[uuid:{0}, gateway:{1}] is not reachable", - "zh_CN": "管理网络[uuid:{0}, gateway:{1}]不可抵达", + "raw": "no global config[category:%s, name:%s] found", + "en_US": "no global config[category:{0}, name:{1}] found", + "zh_CN": "找不到全局配置[类别:{0},名称:{1}]", "arguments": [ - "managementNetworkUuid", - "gateway" + "msg.getCategory()", + "identity" ], - "line": 200, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java" + "line": 85, + "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java" }, { - "raw": "failed to create VirtualRouterBootstrapIso[%s] on kvm host[uuid:%s, ip:%s] for virtual router[uuid:%s], because %s", - "en_US": "failed to create VirtualRouterBootstrapIso[{0}] on kvm host[uuid:{1}, ip:{2}] for virtual router[uuid:{3}], because {4}", - "zh_CN": "创建云路由引导镜像(VirtualRouterBootstrapIso)[{0}]失败,该操作是在KVM物理机[uuid:{1}, ip:{2}]上为云路由[uuid:{3}]执行的,原因为{4}", + "raw": "global config[category:%s, name:%s] cannot bind resource", + "en_US": "global config[category:{0}, name:{1}] cannot bind resource", + "zh_CN": "全局配置[类别:{0},名称:{1}]无法绑定资源", "arguments": [ - "iso.getIsoPath()", - "vrSpec.getDestHost().getUuid()", - "vrSpec.getDestHost().getManagementIp()", - "iso.getVirtualRouterUuid()", - "rsp.getError()" + "msg.getCategory()", + "identity" ], - "line": 107, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java" + "line": 91, + "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java" }, { - "raw": "failed to delete VirtualRouterBootstrapIso[%s] on kvm host[uuid:%s] for virtual router[uuid:%s], because %s", - "en_US": "failed to delete VirtualRouterBootstrapIso[{0}] on kvm host[uuid:{1}] for virtual router[uuid:{2}], because {3}", - "zh_CN": "删除云路由引导镜像(VirtualRouterBootstrapIso)[{0}]失败,该操作是在KVM物理机[uuid:{1}]上为云路由[uuid:{2}]执行的,原因为{3}", + "raw": "account has no access to the resource[uuid: %s]", + "en_US": "account has no access to the resource[uuid: {0}]", + "zh_CN": "账号没有访问资源[uuid:{0}]的权限", "arguments": [ - "iso.getIsoPath()", - "hostUuid", - "iso.getVirtualRouterUuid()", - "rsp.getError()" + "msg.getResourceUuid()" ], - "line": 140, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java" + "line": 114, + "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java" }, { - "raw": "cannot create virtual Router vm while virtual router network overlaps with private network in ip ", - "en_US": "cannot create virtual Router vm while virtual router network overlaps with private network in ip ", - "zh_CN": "当云路由规格的网络和私有网络IP范围有重叠时,无法创建云路由设备", - "arguments": [], - "line": 280, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" + "raw": "[%s] field is excepted an int or long, but was [%s].", + "en_US": "[{0}] field is excepted an int or long, but was [{1}].", + "zh_CN": "[{0}] 属性期望是一个整数,但是得到的是 [{1}]", + "arguments": [ + "f.getName()", + "source" + ], + "line": 22, + "fileName": "src/main/java/org/zstack/rest/TypeVerifier.java" }, { - "raw": "No virtual router instance offering with uuid:%s is found", - "en_US": "No virtual router instance offering with uuid:{0} is found", - "zh_CN": "", + "raw": "Invalid value for boolean field [%s], [%s] is not a valid boolean string[true, false].", + "en_US": "Invalid value for boolean field [{0}], [{1}] is not a valid boolean string[true, false].", + "zh_CN": "boolean属性字段[{0}]无效,[{1}]不是一个有效的boolean字符串[true, false]", "arguments": [ - "offeringUuid" + "f.getName()", + "source" ], - "line": 585, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" + "line": 31, + "fileName": "src/main/java/org/zstack/rest/TypeVerifier.java" }, { - "raw": "failed tot attach virtual router network services to l3Network[uuid:%s]. When eip is selected, snat must be selected too", - "en_US": "failed tot attach virtual router network services to l3Network[uuid:{0}]. When eip is selected, snat must be selected too", - "zh_CN": "挂载虚拟路由网络服务到L3网络[uuid:{0}]失败。选中EIP服务时,SNAT服务也必须被选中", + "raw": "All the networks should be in the virtual router[%s]", + "en_US": "All the networks should be in the virtual router[{0}]", + "zh_CN": "所有网络都应位于虚拟路由器[{0}]中", "arguments": [ - "msg.getL3NetworkUuid()" + "msg.getvRouterUuid()" ], - "line": 1182, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" + "line": 141, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "failed tot attach virtual router network services to l3Network[uuid:%s]. When port forwarding is selected, snat must be selected too", - "en_US": "failed tot attach virtual router network services to l3Network[uuid:{0}]. When port forwarding is selected, snat must be selected too", - "zh_CN": "挂载虚拟路由网络服务到L3网络[uuid:{0}]失败。选中端口转发服务时,SNAT服务也必须被选中", + "raw": "[%s] is not formatted as IPv4 address", + "en_US": "[{0}] is not formatted as IPv4 address", + "zh_CN": "[{0}]的格式不是IPv4地址", "arguments": [ - "msg.getL3NetworkUuid()" + "msg.getAreaId()" ], - "line": 1186, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" + "line": 69, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "can not detach nic [uuid:%s]", - "en_US": "can not detach nic [uuid:{0}]", - "zh_CN": "无法卸载网卡nic[uuid:{0}]", + "raw": "KeyID \u0026 password must be not null when authentication type is %s", + "en_US": "KeyID \u0026 password must be not null when authentication type is {0}", + "zh_CN": "当身份验证类型为{0}时,密钥ID和密码不能为Null", "arguments": [ - "toDeleteNics.stream().map( n -\u003e n.getUuid()).collect(Collectors.toList())" + "msg.getAreaAuth()" ], - "line": 1698, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java" + "line": 108, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "unable to add dhcp entries to virtual router vm[uuid:%s ip:%s], because %s, dhcp entry[%s]", - "en_US": "unable to add dhcp entries to virtual router vm[uuid:{0} ip:{1}], because {2}, dhcp entry[{3}]", - "zh_CN": "无法向云路由[uuid:{0} ip:{1}]添加DHCP条目,因为{2},DHCP条目为[{3}]", + "raw": "password must be not null when authentication type is %s", + "en_US": "password must be not null when authentication type is {0}", + "zh_CN": "当身份验证类型为{0}时,密码不能为null", "arguments": [ - "vr.getUuid()", - "vr.getManagementNic().getIp()", - "rsp.getError()", - "struct" + "msg.getAreaAuth()" ], - "line": 126, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java" + "line": 114, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "unable to program dhcp entries served by virtual router[uuid:%s, ip:%s], %s", - "en_US": "unable to program dhcp entries served by virtual router[uuid:{0}, ip:{1}], {2}", - "zh_CN": "无法执行由云路由[uuid:{0}, ip:{1}]提供的DHCP条目{2}.", + "raw": "the length of password is at most than 8Bytes when authentication type is %s", + "en_US": "the length of password is at most than 8Bytes when authentication type is {0}", + "zh_CN": "当身份验证类型为{0}时,密码长度不超过8个字节", "arguments": [ - "vr.getUuid()", - "vr.getManagementNic().getIp()", - "ret.getError()" + "msg.getAreaAuth()" ], - "line": 208, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterSyncDHCPOnStartFlow.java" + "line": 118, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "virtual router[uuid:%s, ip:%s] failed to configure dns%s for L3Network[uuid:%s, name:%s], %s", - "en_US": "virtual router[uuid:{0}, ip:{1}] failed to configure dns{2} for L3Network[uuid:{3}, name:{4}], {5}", - "zh_CN": "云路由[uuid:{0}, ip:{1}]未能为L3网络[uuid:{3}, name:{4}]配置DNS{2},错误细节: {5}", + "raw": "AreaId[%s] type must be %s", + "en_US": "AreaId[{0}] type must be {1}", + "zh_CN": "AreaID[{0}]类型必须为{1}", "arguments": [ - "vr.getUuid()", - "vr.getManagementNic().getIp()", - "struct", - "l3.getUuid()", - "l3.getName()", - "ret.getError()" + "vo.getAreaId()", + "RouterAreaType.Standard.toString()" ], - "line": 210, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterDnsBackend.java" + "line": 127, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "virtual router[name: %s, uuid: %s] failed to configure dns%s, %s ", - "en_US": "virtual router[name: {0}, uuid: {1}] failed to configure dns{2}, {3} ", - "zh_CN": "云路由[name: {0}, uuid: {1}]未能配置DNS{2},错误细节: {3}", + "raw": "AreaId[%s] has been created", + "en_US": "AreaId[{0}] has been created", + "zh_CN": "已创建Area ID[{0}]", "arguments": [ - "vr.getName()", - "vr.getUuid()", - "JSONObjectUtil.toJsonString(dns)", - "ret.getError()" + "msg.getAreaId()" ], - "line": 124, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java" + "line": 97, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "failed to sync eip on virtual router[uuid:%s], %s", - "en_US": "failed to sync eip on virtual router[uuid:{0}], {1}", - "zh_CN": "未能在云路由[uuid:{0}]上同步EIP,错误细节: {1}", + "raw": "The network[%s] have been added into the haGroup[%s]", + "en_US": "The network[{0}] have been added into the haGroup[{1}]", + "zh_CN": "网络[{0}]已添加到HAG组[{1}]", "arguments": [ - "vr.getUuid()", - "ret.getError()" + "vo.getL3NetworkUuid()", + "haUuid" ], - "line": 496, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" + "line": 158, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "failed to create eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s", - "en_US": "failed to create eip[uuid:{0}, name:{1}, ip:{2}] for vm nic[uuid:{3}] on virtual router[uuid:{4}], {5}", - "zh_CN": "无法为虚拟机网卡[uuid:{3}]在云路由[uuid:{4}]上创建EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5}", + "raw": "The network[%s] have been added into the virtual routerArea[%s]", + "en_US": "The network[{0}] have been added into the virtual routerArea[{1}]", + "zh_CN": "网络[{0}]已添加到虚拟路由器区域[{1}]", "arguments": [ - "struct.getEip().getUuid()", - "struct.getEip().getName()", - "struct.getVip().getIp()", - "struct.getNic().getUuid()", - "vr.getUuid()", - "ret.getError()" + "vo.getL3NetworkUuid()", + "vo.getRouterAreaUuid()" ], - "line": 165, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" + "line": 150, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "found a virtual router offering[uuid:%s] for L3Network[uuid:%s] in zone[uuid:%s]; however, the network\u0027s public network[uuid:%s] is not the same to EIP[uuid:%s]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", - "en_US": "found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network\u0027s public network[uuid:{3}] is not the same to EIP[uuid:{4}]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", - "zh_CN": "在区域(zone)[uuid:{2}]上为L3网络[uuid:{1}]找到了云路由规格[uuid:{0}];但是,其公共网络[uuid:{3}]和EIP[uuid:{4}]的公共网络不是同一个L3网络。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该L3网络指定一个特定的云路有规格", + "raw": "Router ID[%s] is not formatted as IPv4 address", + "en_US": "Router ID[{0}] is not formatted as IPv4 address", + "zh_CN": "路由器ID[{0}]的格式不是IPv4地址", "arguments": [ - "offering.getUuid()", - "l3inv.getUuid()", - "l3inv.getZoneUuid()", - "struct.getVip().getL3NetworkUuid()", - "struct.getEip().getUuid()" + "msg.getRouterId()" ], - "line": 246, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" + "line": 181, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" }, { - "raw": "failed to remove eip[uuid:%s, name:%s, ip:%s] for vm nic[uuid:%s] on virtual router[uuid:%s], %s", - "en_US": "failed to remove eip[uuid:{0}, name:{1}, ip:{2}] for vm nic[uuid:{3}] on virtual router[uuid:{4}], {5}", - "zh_CN": "未能在云路由[uuid:{4}]上为虚拟机网卡[uuid:{3}]移除EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5}", + "raw": "Router ID[%s] is not unique in this system", + "en_US": "Router ID[{0}] is not unique in this system", + "zh_CN": "路由器ID[{0}]在此系统中不唯一", "arguments": [ - "struct.getEip().getUuid()", - "struct.getEip().getName()", - "struct.getVip().getIp()", - "struct.getNic().getUuid()", - "vr.getUuid()", - "ret.getError()" + "msg.getRouterId()" ], - "line": 336, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java" + "line": 193, + "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + }, + { + "raw": "the last job is not completed. skip this job", + "en_US": "the last job is not completed. skip this job", + "zh_CN": "上一个作业未完成。跳过这份工作", + "arguments": [], + "line": 235, + "fileName": "src/main/java/org/zstack/scheduler/AbstractSchedulerJob.java" + }, + { + "raw": "cron must be set when use cron scheduler", + "en_US": "cron must be set when use cron scheduler", + "zh_CN": "当使用定时器任务时,必须设置cron", + "arguments": [], + "line": 189, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + }, + { + "raw": "cron task must follow format like this : \\\"0 0/3 17-23 * * ?\\\" ", + "en_US": "cron task must follow format like this : \\\"0 0/3 17-23 * * ?\\\" ", + "zh_CN": "定时器任务必须符合以下格式: \\\"0 0/3 17-23 * * ?\\\" ", + "arguments": [], + "line": 195, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + }, + { + "raw": "cron scheduler only need to specify cron task", + "en_US": "cron scheduler only need to specify cron task", + "zh_CN": "定时调度器(Cron Scheduler)仅需要指定定时任务(Cron Task)", + "arguments": [], + "line": 198, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + }, + { + "raw": "startTime out of range", + "en_US": "startTime out of range", + "zh_CN": "开始时间超出范围", + "arguments": [], + "line": 207, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + }, + { + "raw": "startTime must be positive integer or 0", + "en_US": "startTime must be positive integer or 0", + "zh_CN": "开始时间必须是正整数或者0", + "arguments": [], + "line": 203, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + }, + { + "raw": "stopTime has been passed", + "en_US": "stopTime has been passed", + "zh_CN": "截止时间已经过去了", + "arguments": [], + "line": 184, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "new add vm nics[uuids:%s] and attached vmnics are not on the same vrouter, they are on vrouters[uuids:%s]", - "en_US": "new add vm nics[uuids:{0}] and attached vmnics are not on the same vrouter, they are on vrouters[uuids:{1}]", - "zh_CN": "新添加的虚拟网卡[uuids:{0}]和绑定虚拟机的网卡没有在一个云路由上,它们分别在云路由[uuids:{1}]上", - "arguments": [ - "msg.getVmNicUuids()", - "vrUuids" - ], - "line": 152, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" + "raw": "stopTime out of mysql timestamp range", + "en_US": "stopTime out of mysql timestamp range", + "zh_CN": "定时任务停止时间超出mysql的timestamp的范围", + "arguments": [], + "line": 182, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "new add vm nics[uuids:%s] and peer l3s[uuids:%s] of loadbalancer[uuid: %s]\u0027s vip are not on the same vrouter, they are on vrouters[uuids:%s]", - "en_US": "new add vm nics[uuids:{0}] and peer l3s[uuids:{1}] of loadbalancer[uuid: {2}]\u0027s vip are not on the same vrouter, they are on vrouters[uuids:{3}]", - "zh_CN": "新添加的虚拟机网卡[uuids:{0}]和负载均衡器[uuid: {2}]的弹性IP的三层网络[uuids:{1}]没有在相同的云路由上,它们分别在云路由[uuids:{3}]上", - "arguments": [ - "msg.getVmNicUuids()", - "peerL3NetworkUuids", - "msg.getLoadBalancerUuid()", - "vrUuids" - ], - "line": 182, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" + "raw": "duration time out of range", + "en_US": "duration time out of range", + "zh_CN": "任务需要的时间超出范围", + "arguments": [], + "line": 180, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "cannot find virtual router for load balancer [uuid:%s]", - "en_US": "cannot find virtual router for load balancer [uuid:{0}]", - "zh_CN": "未能为负载均衡器[uuid:{0}]找到云路由", - "arguments": [ - "struct.getLb().getUuid()" - ], - "line": 1318, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java" + "raw": "interval must be set when use simple scheduler when repeat more than once", + "en_US": "interval must be set when use simple scheduler when repeat more than once", + "zh_CN": "当简单定时任务执行超过一次时,必须设置间隔时间", + "arguments": [], + "line": 99, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "virtual router[name: %s, uuid: %s] failed to sync snat%s, %s", - "en_US": "virtual router[name: {0}, uuid: {1}] failed to sync snat{2}, {3}", - "zh_CN": "云路由[name: {0}, uuid: {1}]未能同步SNAT{2},错误细节: {3}", + "raw": "Can not add job[uuid:%s] twice to the same trigger[uuid:%s]", + "en_US": "Can not add job[uuid:{0}] twice to the same trigger[uuid:{1}]", + "zh_CN": "不能两次添加任务[uuid:{0}]到相同的触发器[uuid:{1}]", "arguments": [ - "vr.getName()", - "vr.getUuid()", - "JSONObjectUtil.toJsonString(snatInfo)", - "ret.getError()" + "msg.getSchedulerJobUuid()", + "msg.getSchedulerTriggerUuid()" ], - "line": 331, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java" + "line": 134, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "guest l3Network[uuid:%s, name:%s] needs SNAT service provided by virtual router, but public l3Network[uuid:%s] of virtual router offering[uuid: %s, name:%s] is the same to this guest l3Network", - "en_US": "guest l3Network[uuid:{0}, name:{1}] needs SNAT service provided by virtual router, but public l3Network[uuid:{2}] of virtual router offering[uuid: {3}, name:{4}] is the same to this guest l3Network", - "zh_CN": "用户L3网络[uuid:{0}, name:{1}]需要云路由提供的SNAT服务,但是云路由规格[uuid: {3}, name:{4}]的公共L3网络[uuid:{2}]与该客户L3网络相同", + "raw": "Can not add job[uuid:%s] to a out of time trigger[uuid:%s]", + "en_US": "Can not add job[uuid:{0}] to a out of time trigger[uuid:{1}]", + "zh_CN": "不能添加任务[uuid:{0}]到一个已经过时的触发器[uuid:{1}]", "arguments": [ - "guestL3.getUuid()", - "guestL3.getName()", - "offering.getPublicNetworkUuid()", - "offering.getUuid()", - "offering.getName()" + "msg.getSchedulerJobUuid()", + "msg.getSchedulerTriggerUuid()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java" + "line": 139, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "failed to create port forwarding rule[vip ip: %s, private ip: %s, vip start port: %s, vip end port: %s, private start port: %s, private end port: %s], because %s", - "en_US": "failed to create port forwarding rule[vip ip: {0}, private ip: {1}, vip start port: {2}, vip end port: {3}, private start port: {4}, private end port: {5}], because {6}", - "zh_CN": "无法创建端口转发规则[vip ip: {0}, private ip: {1}, vip start port: {2}, vip end port: {3}, private start port: {4}, private end port: {5}],错误细节: {6}", + "raw": "There are [%d] triggers added to job[uuid:%s], cannot add any more.", + "en_US": "There are [{0}] triggers added to job[uuid:{1}], cannot add any more.", + "zh_CN": "有[{0}]个触发器已添加到作业[uuid:{1}],无法再添加更多触发器。", "arguments": [ - "to.getVipIp()", - "to.getPrivateIp()", - "to.getVipPortStart()", - "to.getVipPortEnd()", - "to.getPrivatePortStart()", - "to.getPrivatePortEnd()", - "ret.getError()" + "count", + "msg.getSchedulerJobUuid()" ], - "line": 80, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ApplyPortforwardingRuleOnVirtualRouterVmFlow.java" + "line": 147, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "failed to revoke port forwarding rules %s, because %s", - "en_US": "failed to revoke port forwarding rules {0}, because {1}", - "zh_CN": "未能解除端口转发规则{0},原因: {1}", + "raw": "There are [%d] triggers added to job group[uuid:%s], cannot add any more.", + "en_US": "There are [{0}] triggers added to job group[uuid:{1}], cannot add any more.", + "zh_CN": "有[{0}]个触发器已添加到作业组[uuid:{1}],无法添加更多触发器。", "arguments": [ - "JSONObjectUtil.toJsonString(to)", - "ret.getError()" + "count", + "msg.getSchedulerJobGroupUuid()" ], - "line": 74, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ReleasePortForwardingRuleOnVirtualRouterVmFlow.java" + "line": 162, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "found a virtual router offering[uuid:%s] for L3Network[uuid:%s] in zone[uuid:%s]; however, the network\u0027s public network[uuid:%s] is not the same to PortForwarding rule[uuid:%s]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", - "en_US": "found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network\u0027s public network[uuid:{3}] is not the same to PortForwarding rule[uuid:{4}]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", - "zh_CN": "在区域(zone)[uuid:{2}]内为L3网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和端口转发规则[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该L3网络指定一个特定的云路有规格", - "arguments": [ - "offering.getUuid()", - "struct.getGuestL3Network().getUuid()", - "struct.getGuestL3Network().getZoneUuid()", - "struct.getVip().getL3NetworkUuid()", - "struct.getRule().getUuid()" - ], - "line": 184, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" + "raw": "invalid cron expression", + "en_US": "invalid cron expression", + "zh_CN": "无效的cron表达式", + "arguments": [], + "line": 192, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "virtual router doesn\u0027t support port forwarding range redirection, the vipPortStart must be equals to privatePortStart and vipPortEnd must be equals to privatePortEnd;but this rule rule has a mismatching range: vip port[%s, %s], private port[%s, %s]", - "en_US": "virtual router doesn\u0027t support port forwarding range redirection, the vipPortStart must be equals to privatePortStart and vipPortEnd must be equals to privatePortEnd;but this rule rule has a mismatching range: vip port[{0}, {1}], private port[{2}, {3}]", - "zh_CN": "云路由不支持范围性的端口转发重定向,vipPortStart和privatePortStart必须一致,vipPortEnd和privatePortEnd必须一致,但这条规则有个不匹配的范围: vip端口范围[{0}, {1}],私有端口范围[{2}, {3}]", - "arguments": [ - "rule.getVipPortStart()", - "rule.getVipPortEnd()", - "rule.getPrivatePortStart()", - "rule.getPrivatePortEnd()" - ], - "line": 249, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" + "raw": "startTime must be set for simple scheduler", + "en_US": "startTime must be set for simple scheduler", + "zh_CN": "simple类型的定时任务必须设置开始时间[startTime]", + "arguments": [], + "line": 172, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "failed to add portforwardings on virtual router[uuid:%s], %s", - "en_US": "failed to add portforwardings on virtual router[uuid:{0}], {1}", - "zh_CN": "在云路由[uuid:{0}]添加端口转发失败,{1}", - "arguments": [ - "vrVO.getUuid()", - "ret.getError()" - ], - "line": 402, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" + "raw": "schedulerInterval must be set for simple scheduler", + "en_US": "schedulerInterval must be set for simple scheduler", + "zh_CN": "simple类型的定时任务必须设置执行间隔[schedulerInterval]", + "arguments": [], + "line": 176, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "failed to revoke port forwardings on virtual router[uuid:%s], %s", - "en_US": "failed to revoke port forwardings on virtual router[uuid:{0}], {1}", - "zh_CN": "取消在云路由[uuid:{0}]上端口转发服务失败,{1}", + "raw": "No SchedulerJobFactory of type[%s] found", + "en_US": "No SchedulerJobFactory of type[{0}] found", + "zh_CN": "未找到类型为[{0}]的SchedulerJobFactory", "arguments": [ - "vrVO.getUuid()", - "ret.getError()" + "msg.getType()" ], - "line": 471, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java" + "line": 226, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "failed to sync port forwarding rules served by virtual router[name: %s, uuid: %s], because %s", - "en_US": "failed to sync port forwarding rules served by virtual router[name: {0}, uuid: {1}], because {2}", - "zh_CN": "未能同步由云路由[name: {0}, uuid: {1}]提供的端口转发规则,因为: {2}", + "raw": "%d jobs have different job type with job group", + "en_US": "{0} jobs have different job type with job group", + "zh_CN": "{0}个作业的作业类型与作业组不同", "arguments": [ - "vr.getName()", - "vr.getUuid()", - "ret.getError()" + "n" ], - "line": 197, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java" + "line": 253, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "virtual router[name: %s, uuid: %s] failed to create vip for public ip %s because no ip range for l3NetworkUuid %s", - "en_US": "virtual router[name: {0}, uuid: {1}] failed to create vip for public ip {2} because no ip range for l3NetworkUuid {3}", - "zh_CN": "虚拟路由[name: {0}, uuid: {1}]为公有IP创建虚拟IP失败,因为三层网络[uuid:{3}]的没有IP段", + "raw": "job group has contained %d job, only %d seats left", + "en_US": "job group has contained {0} job, only {1} seats left", + "zh_CN": "作业组已包含{0}个作业,只剩下{1}个席位", "arguments": [ - "vr.getName()", - "vr.getUuid()", - "nic.getIp()", - "nic.getL3NetworkUuid()" + "count", + "limit - count" ], - "line": 66, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreateVipForPublicIpFlow.java" + "line": 262, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" }, { - "raw": "failed to remove vip%s, because %s", - "en_US": "failed to remove vip{0}, because {1}", - "zh_CN": "未能移除VIP{0},因为{1}", + "raw": "invalid time unit: %s", + "en_US": "invalid time unit: {0}", + "zh_CN": "无效时间单位:{0}", "arguments": [ - "tos", - "ret.getError()" + "timeUnitInStr" ], - "line": 136, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java" + "line": 794, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java" }, { - "raw": "failed to create vip%s on virtual router[uuid:%s], because %s", - "en_US": "failed to create vip{0} on virtual router[uuid:{1}], because {2}", - "zh_CN": "未能在云路由[uuid:{1}]上创建VIP{0},因为{2}", + "raw": "trigger job[uuid: %s] failed, because %s", + "en_US": "trigger job[uuid: {0}] failed, because {1}", + "zh_CN": "触发器作业[uuid:{0}]失败,原因是{1}", "arguments": [ - "tos", - "vr.getUuid()", - "ret.getError()" + "jobUuid", + "e.getMessage()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java" + "line": 921, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java" }, { - "raw": "failed to sync vips[ips: %s] on virtual router[uuid:%s] for attaching nic[uuid: %s, ip: %s], because %s", - "en_US": "failed to sync vips[ips: {0}] on virtual router[uuid:{1}] for attaching nic[uuid: {2}, ip: {3}], because {4}", - "zh_CN": "为了绑定网卡[uuid: {2}, ip: {3}]在云路由[uuid:{1}]上同步虚拟IP[ips: {0}]失败,因为{4}", + "raw": "field[%s] cannot be empty", + "en_US": "field[{0}] cannot be empty", + "zh_CN": "字段[{0}]不能为空", "arguments": [ - "vips.stream().map( v -\u003e v.getIp()).collect(Collectors.toList())", - "nic.getVmInstanceUuid()", - "nic.getUuid()", - "nic.getIp()", - "ret.getError()" + "field.getName()" ], - "line": 201, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java" + "line": 86, + "fileName": "src/main/java/org/zstack/scheduler/SchedulerJobParamCascadeUpdater.java" }, { - "raw": "virtual router[uuid:%s, state:%s] is not running", - "en_US": "virtual router[uuid:{0}, state:{1}] is not running", - "zh_CN": "云路由[uuid:{0}, state:{1}]没有运行", + "raw": "the volume[%s] is not available. check if the volume exists.", + "en_US": "the volume[{0}] is not available. check if the volume exists.", + "zh_CN": "卷[{0}]不可用。检查卷是否存在。", "arguments": [ - "vrUuid", - "vrState" + "msg.getTargetResourceUuid()" ], - "line": 262, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java" + "line": 54, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java" }, { - "raw": "found a virtual router offering[uuid:%s] for L3Network[uuid:%s] in zone[uuid:%s]; however, the network\u0027s public network[uuid:%s] is not the same to VIP[uuid:%s]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", - "en_US": "found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network\u0027s public network[uuid:{3}] is not the same to VIP[uuid:{4}]\u0027s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network", - "zh_CN": "在区域(zone)[uuid:{2}]内为L3网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和VIP[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该L3网络指定一个特定的云路有规格", + "raw": "the volume[%s] is not root volume", + "en_US": "the volume[{0}] is not root volume", + "zh_CN": "卷[{0}]不是根卷", "arguments": [ - "offering.getUuid()", - "s.getL3Network().getUuid()", - "s.getL3Network().getZoneUuid()", - "self.getL3NetworkUuid()", - "self.getUuid()" + "msg.getTargetResourceUuid()" ], - "line": 303, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java" + "line": 58, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java" }, { - "raw": "failed to change nic[ip:%s, mac:%s] firewall default action of virtual router vm[uuid:%s], because %s", - "en_US": "failed to change nic[ip:{0}, mac:{1}] firewall default action of virtual router vm[uuid:{2}], because {3}", - "zh_CN": "修改云路由[uuid:{2}]的网卡[ip:{0}, mac:{1}]的默认防火墙规则失败,因为{3}", + "raw": "the vm of the root volume[%s] is not available. check if the vm exists.", + "en_US": "the vm of the root volume[{0}] is not available. check if the vm exists.", + "zh_CN": "根卷[{0}]的VM不可用。检查云主机是否存在。", "arguments": [ - "nic.getIp()", - "nic.getMac()", - "nic.getVmInstanceUuid()", - "rsp.getError()" + "msg.getTargetResourceUuid()" ], - "line": 67, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosChangePrivateL3FirewallDefaultActionExtensionPoint.java" + "line": 63, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java" + }, + { + "raw": "The primary storage of volumes don not support create volume snapshot group job.", + "en_US": "The primary storage of volumes don not support create volume snapshot group job.", + "zh_CN": "卷的主存储不支持创建卷快照组作业。", + "arguments": [], + "line": 70, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java" }, { - "raw": "virtual router[uuid: %s] failed to get version because %s ", - "en_US": "virtual router[uuid: {0}] failed to get version because {1} ", - "zh_CN": "获取云路由[uuid: {0}]版本失败,因为{1}", + "raw": "snapshotGroupMaxNumber : %s format error because %s", + "en_US": "snapshotGroupMaxNumber : {0} format error because {1}", + "zh_CN": "SnapshotGroupMaxNumber:{0}格式错误,原因是{1}", "arguments": [ - "vrUuid", - "ret.getError()" + "msg.getParameters().get(SchedulerJobParameters.snapshotGroupMax)", + "e.getMessage()" ], - "line": 56, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java" + "line": 77, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java" }, { - "raw": "virtual router[uuid: %s] doesn\u0027t have version", - "en_US": "virtual router[uuid: {0}] doesn\u0027t have version", - "zh_CN": "云路由[uuid: {0}]没有版本信息", + "raw": "the volume[%s] does not support snapshots retention", + "en_US": "the volume[{0}] does not support snapshots retention", + "zh_CN": "卷[{0}]不支持快照保留", "arguments": [ - "vrUuid" + "msg.getTargetResourceUuid()" ], - "line": 63, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java" + "line": 58, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotJobFactory.java" }, { - "raw": "virtual router[uuid: %s] version [%s] format error", - "en_US": "virtual router[uuid: {0}] version [{1}] format error", - "zh_CN": "云路由[uuid{0}]版本号[{1}]格式错误", + "raw": "snapshotMaxNumber : %s format error because %s", + "en_US": "snapshotMaxNumber : {0} format error because {1}", + "zh_CN": "snapshotMaxNumber : {0} 转换类型失败,因为{1}", "arguments": [ - "vrUuid", - "ret.getVersion()" + "msg.getParameters().get(SchedulerJobParameters.snapshotMax)", + "e.getMessage()" ], - "line": 69, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java" + "line": 70, + "fileName": "src/main/java/org/zstack/scheduler/VolumeSnapshotJobFactory.java" }, { - "raw": "virtual router[uuid: %s] version [%s] is older than management node version [%s]", - "en_US": "virtual router[uuid: {0}] version [{1}] is older than management node version [{2}]", - "zh_CN": "云路由[uuid: {0}]版本[{1}]比管理节点的版本[{2}]旧", + "raw": "the vm of the root volume[%s] state in Destroyed. job state change is not allowed", + "en_US": "the vm of the root volume[{0}] state in Destroyed. job state change is not allowed", + "zh_CN": "根卷[{0}]的VM处于已销毁状态。不允许更改作业状态", "arguments": [ - "vrUuid", - "ret.getVersion()", - "managementVersion" + "getTargetResourceUuid()" ], - "line": 75, - "fileName": "src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java" + "line": 125, + "fileName": "src/main/java/org/zstack/scheduler/snapshot/CreateVolumeSnapshotGroupJob.java" }, { - "raw": "failed to start vm[uuid:%s] because not all pci specs[uuids:%s] exist", - "en_US": "failed to start vm[uuid:{0}] because not all pci specs[uuids:{1}] exist", - "zh_CN": "云主机[uuid:{0}]启动失败,因为所设置的PCI设备规格[uuids:{1}]中有部分不存在", - "arguments": [ - "vmUuid", - "specMap.keySet()" - ], - "line": 79, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "raw": "The primary storage of volumes don not support create volume snapshot group job", + "en_US": "The primary storage of volumes don not support create volume snapshot group job", + "zh_CN": "卷的主存储不支持创建卷快照组作业", + "arguments": [], + "line": 189, + "fileName": "src/main/java/org/zstack/scheduler/snapshot/CreateVolumeSnapshotGroupJob.java" }, { - "raw": "no candidate host with enough spec related pci devices for vm[uuid:%s]", - "en_US": "no candidate host with enough spec related pci devices for vm[uuid:{0}]", - "zh_CN": "", + "raw": "vm[uuid:%s] is destroyed, state change is not allowed", + "en_US": "vm[uuid:{0}] is destroyed, state change is not allowed", + "zh_CN": "VM[uuid:{0}]已销毁,不允许更改状态", "arguments": [ - "vmUuid" + "getTargetResourceUuid()" ], - "line": 132, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "line": 83, + "fileName": "src/main/java/org/zstack/scheduler/vm/StopVmInstanceJob.java" }, { - "raw": "failed to start vm[uuid:%s] because not all mdev specs[uuids:%s] exist", - "en_US": "failed to start vm[uuid:{0}] because not all mdev specs[uuids:{1}] exist", - "zh_CN": "云主机[uuid:{0}]启动失败,由于所设置的MDEV设备规格[uuids:{1}]中有部分不存在", + "raw": "Sdn controller type: %s in not in the supported list: %s ", + "en_US": "Sdn controller type: {0} in not in the supported list: {1} ", + "zh_CN": "SDN控制器类型:{0}不在支持的列表中:{1}", "arguments": [ - "vmUuid", - "specMap.keySet()" + "msg.getVendorType()", + "SdnControllerType.getAllTypeNames()" ], - "line": 154, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "line": 75, + "fileName": "src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java" }, { - "raw": "no candidate host with enough spec related mdev devices for vm[uuid:%s]", - "en_US": "no candidate host with enough spec related mdev devices for vm[uuid:{0}]", - "zh_CN": "", + "raw": "unable create vni range, because l2 uuid[%s] is not vxlan network pool", + "en_US": "unable create vni range, because l2 uuid[{0}] is not vxlan network pool", + "zh_CN": "无法创建VNI范围,因为L2 uuid[{0}]不是VXLAN网络池", "arguments": [ - "vmUuid" + "msg.getL2NetworkUuid()" ], - "line": 205, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "line": 102, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java" }, { - "raw": "failed to find enough pci device of spec[uuid:%s] in dest host[uuid:%s] for vm[uuid:%s]", - "en_US": "failed to find enough pci device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}]", - "zh_CN": "无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的PCI设备", + "raw": "the vni range:[%s.%s} is illegal, because h3c\u0027s controller uses vni as vlan id", + "en_US": "the vni range:[{0}.{1}} is illegal, because h3c\u0027s controller uses vni as vlan id", + "zh_CN": "VNI范围[{0}.{1}}非法,因为H3C的控制器使用VNI作为VLAN ID", "arguments": [ - "specUuid", - "hostUuid", - "vmUuid" + "msg.getStartVni()", + "msg.getEndVni()" ], - "line": 260, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "line": 117, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java" }, { - "raw": "failed to find enough mdev device of spec[uuid:%s] in dest host[uuid:%s] for vm[uuid:%s]", - "en_US": "failed to find enough mdev device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}]", - "zh_CN": "无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的MDEV设备", + "raw": "the vni range:[%s.%s} is illegal, must covered by a sdn\u0027s vniRange", + "en_US": "the vni range:[{0}.{1}} is illegal, must covered by a sdn\u0027s vniRange", + "zh_CN": "VNI范围[{0}.{1}}非法,必须由SDN的VNI范围覆盖", "arguments": [ - "specUuid", - "hostUuid", - "vmUuid" + "userVniRange.startVni", + "userVniRange.endVni" ], - "line": 337, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "line": 132, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java" }, { - "raw": "failed to sort host candidates for vm [uuid:%s] in HostDeviceAllocatorFlow: %s", - "en_US": "failed to sort host candidates for vm [uuid:{0}] in HostDeviceAllocatorFlow: {1}", - "zh_CN": "", + "raw": "H3C VCFC controller must include systemTags vdsUuid::{%s}", + "en_US": "H3C VCFC controller must include systemTags vdsUuid::{{0}}", + "zh_CN": "H3C VCFC控制器必须包含系统标签VDSuuid::{{0}}", + "arguments": [], + "line": 178, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java" + }, + { + "raw": "get sdn controller [ip:%s] vni range failed because %s", + "en_US": "get sdn controller [ip:{0}] vni range failed because {1}", + "zh_CN": "获取SDN控制器[IP:{0}]VNI范围失败,原因是{1}", "arguments": [ - "vmUuid", - "errorCode" + "self.getIp()", + "e.getLocalizedMessage()" ], - "line": 411, - "fileName": "src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java" + "line": 116, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "specified pci devices not on same host: pci device[uuid: %s] on host[uuid: %s] while pci device[uuid: %s] on host[uuid: %s]", - "en_US": "specified pci devices not on same host: pci device[uuid: {0}] on host[uuid: {1}] while pci device[uuid: {2}] on host[uuid: {3}]", - "zh_CN": "云主机试图挂载来自不同物理机的PCI设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}]", + "raw": "get vni range on sdn controller [ip:%s] failed", + "en_US": "get vni range on sdn controller [ip:{0}] failed", + "zh_CN": "在SDN控制器[IP:{0}]上获取VNI范围失败", "arguments": [ - "vo.getUuid()", - "vo.getHostUuid()", - "attachedPciUuid", - "dstHostUuid" + "self.getIp()" ], - "line": 87, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceAllocatorFactory.java" + "line": 86, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "cannot find required pci device on hosts", - "en_US": "cannot find required pci device on hosts", - "zh_CN": "没有物理机满足需要的pci 设备条件", - "arguments": [], - "line": 140, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceAllocatorFactory.java" + "raw": "there is no vni range on sdn controller [ip:%s]", + "en_US": "there is no vni range on sdn controller [ip:{0}]", + "zh_CN": "SDN控制器[IP:{0}]上没有VNI范围", + "arguments": [ + "self.getIp()" + ], + "line": 148, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "pci device[uuid:%s] doesn\u0027t exist", - "en_US": "pci device[uuid:{0}] doesn\u0027t exist", - "zh_CN": "PCI设备[uuid:{0}]不存在", + "raw": "there is no default tenant on sdn controller [ip:%s]", + "en_US": "there is no default tenant on sdn controller [ip:{0}]", + "zh_CN": "SDN控制器[IP:{0}]上没有默认租户", "arguments": [ - "msg.getPciDeviceUuid()" + "self.getIp()" ], - "line": 416, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 154, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "pci devices in host[uuid:%s] already sriov virtualized", - "en_US": "pci devices in host[uuid:{0}] already sriov virtualized", - "zh_CN": "物理机[uuid:{0}]上的PCI设备已经SRIOV虚拟化,无法再次切分", + "raw": "create vxlan network on sdn controller [ip:%s] failed because %s", + "en_US": "create vxlan network on sdn controller [ip:{0}] failed because {1}", + "zh_CN": "在SDN控制器[IP:{0}]上创建VXLAN网络失败,原因是{1}", "arguments": [ - "pci.getHostUuid()" + "self.getIp()", + "e.getMessage()" ], - "line": 426, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 299, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "cannot sr-iov virtualize pci devices in host[uuid:%s] that are attached to vm", - "en_US": "cannot sr-iov virtualize pci devices in host[uuid:{0}] that are attached to vm", - "zh_CN": "物理机[uuid:{0}]上的PCI设备已经挂载到云主机,无法SRIOV虚拟化", + "raw": "create vxlan network on sdn controller [ip:%s] failed", + "en_US": "create vxlan network on sdn controller [ip:{0}] failed", + "zh_CN": "在SDN控制器[IP:{0}]上创建VXLAN网络失败", "arguments": [ - "pci.getHostUuid()" + "self.getIp()" ], - "line": 437, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 283, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "only %d virtual pci devices can be generated by %ss in host[uuid:%s]", - "en_US": "only {0} virtual pci devices can be generated by {1}s in host[uuid:{2}]", - "zh_CN": "物理机[uuid:{2}]上的{1}类型PCI设备最多被切分出{0}个虚拟PCI设备", + "raw": "delete vxlan network on sdn controller [ip:%s] failed because %s", + "en_US": "delete vxlan network on sdn controller [ip:{0}] failed because {1}", + "zh_CN": "删除SDN控制器[IP:{0}]上的VXLAN网络失败,原因是{1}", "arguments": [ - "minIns", - "pci.getType()", - "pci.getHostUuid()" + "self.getIp()", + "e.getMessage()" ], - "line": 457, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 383, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "the host[uuid:%s] that pci device[uuid:%s] in is not Connected", - "en_US": "the host[uuid:{0}] that pci device[uuid:{1}] in is not Connected", - "zh_CN": "PCI设备[uuid:{1}]所在物理机[uuid:{0}]已失联", + "raw": "delete vxlan network on sdn controller [ip:%s] failed", + "en_US": "delete vxlan network on sdn controller [ip:{0}] failed", + "zh_CN": "删除SDN控制器[IP:{0}]上的VXLAN网络失败", "arguments": [ - "pci.getHostUuid()", - "pci.getUuid()" + "self.getIp()" ], - "line": 569, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 377, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "pci device[uuid:%s] doesn\u0027t exist or is not sriov virtualized", - "en_US": "pci device[uuid:{0}] doesn\u0027t exist or is not sriov virtualized", - "zh_CN": "PCI设备[uuid:{0}]不存在,或者未处于SRIOV虚拟化状态", + "raw": "get token of sdn controller [ip:%s] failed because %s", + "en_US": "get token of sdn controller [ip:{0}] failed because {1}", + "zh_CN": "获取SDN控制器[IP:{0}]的令牌失败,原因是{1}", "arguments": [ - "msg.getPciDeviceUuid()" + "self.getIp()", + "e.getMessage()" ], - "line": 477, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 468, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "virtual pci devices generated from pci devices in host[uuid:%s] still attached to vm", - "en_US": "virtual pci devices generated from pci devices in host[uuid:{0}] still attached to vm", - "zh_CN": "物理机[uuid:{0}]上存在仍处于已挂载状态的虚拟PCI设备,无法执行虚拟化还原操作", + "raw": "get leader of sdn controller [ip:%s] failed", + "en_US": "get leader of sdn controller [ip:{0}] failed", + "zh_CN": "获取SDN控制器[IP:{0}]的领导者失败", "arguments": [ - "pci.getHostUuid()" + "self.getIp()" ], - "line": 488, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 439, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "pci device[uuid:%s] cannot be virtualized into mdevs, make sure it\u0027s enabled and un-attached", - "en_US": "pci device[uuid:{0}] cannot be virtualized into mdevs, make sure it\u0027s enabled and un-attached", - "zh_CN": "PCI设备[uuid:{0}]无法被切分为MDEV设备,请确保它处于启用状态,并且没有挂载到云主机", + "raw": "get token of sdn controller [ip:%s] failed", + "en_US": "get token of sdn controller [ip:{0}] failed", + "zh_CN": "获取SDN控制器[IP:{0}]的令牌失败", "arguments": [ - "msg.getPciDeviceUuid()" + "self.getIp()" ], - "line": 510, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 460, + "fileName": "src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java" }, { - "raw": "pci device[uuid:%s] cannot be virtualized by mdev spec[uuid:%s]", - "en_US": "pci device[uuid:{0}] cannot be virtualized by mdev spec[uuid:{1}]", - "zh_CN": "PCI设备[uuid:{0}]无法使用MDEV设备规格[uuid:{1}]进行虚拟化切分", + "raw": "there is no sdn controller for vxlan pool [uuid:%s]", + "en_US": "there is no sdn controller for vxlan pool [uuid:{0}]", + "zh_CN": "VXLAN池[uuid:{0}]没有SDN控制器", "arguments": [ - "msg.getPciDeviceUuid()", - "msg.getMdevSpecUuid()" + "vo.getPoolUuid()" ], - "line": 521, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 51, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java" }, { - "raw": "pci device[uuid:%s] is not virtualized into mdevs", - "en_US": "pci device[uuid:{0}] is not virtualized into mdevs", - "zh_CN": "PCI设备[uuid:{0}]未处于VFIO_MDEV虚拟化状态", + "raw": "cannot configure hardware vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", + "en_US": "cannot configure hardware vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}]", + "zh_CN": "无法为目标物理机[uuid:{1}]上的VM[uuid:{0}]配置硬件VXLAN网络", "arguments": [ - "msg.getPciDeviceUuid()" + "inv.getUuid()", + "destHostUuid" ], - "line": 543, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 410, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java" }, { - "raw": "mdev devices generated from pci device[uuid:%s] still attached to vm", - "en_US": "mdev devices generated from pci device[uuid:{0}] still attached to vm", - "zh_CN": "PCI设备[uuid:{0}]切分出的MDEV设备仍处于已挂载状态,无法执行虚拟化还原操作", + "raw": "cannot create vlan-device on %s because it\u0027s too long", + "en_US": "cannot create vlan-device on {0} because it\u0027s too long", + "zh_CN": "无法在{0}上创建VLAN设备,因为它太长", "arguments": [ - "msg.getPciDeviceUuid()" + "msg.getPhysicalInterface()" ], - "line": 560, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java" + "line": 150, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" }, { - "raw": "illegal type[%s] for pci device spec, only %s are legal", - "en_US": "illegal type[{0}] for pci device spec, only {1} are legal", - "zh_CN": "", + "raw": "hardware vxlan network pool doesn\u0027t support create l3 network", + "en_US": "hardware vxlan network pool doesn\u0027t support create l3 network", + "zh_CN": "硬件VXLAN网络池不支持创建三层网络", + "arguments": [], + "line": 112, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + }, + { + "raw": "hardware vxlan network pool must configure the physical interface", + "en_US": "hardware vxlan network pool must configure the physical interface", + "zh_CN": "硬件VXLAN网络池必须配置物理接口", + "arguments": [], + "line": 118, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + }, + { + "raw": "ONLY hardware vxlan network can be created in hardware vxlan pool", + "en_US": "ONLY hardware vxlan network can be created in hardware vxlan pool", + "zh_CN": "在硬件VXLAN池中只能创建硬件VXLAN网络", + "arguments": [], + "line": 126, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + }, + { + "raw": "hardware vxlan network can ONLY be created in hardware vxlan pool", + "en_US": "hardware vxlan network can ONLY be created in hardware vxlan pool", + "zh_CN": "硬件VXLAN网络只能在硬件VXLAN池中创建", + "arguments": [], + "line": 131, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + }, + { + "raw": "failed to create bridge[%s] for hardwareVxlan[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", + "en_US": "failed to create bridge[{0}] for hardwareVxlan[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5}", + "zh_CN": "无法在KVM物理机[uuid:{4}]上为HardwareVXLAN[uuid:{1},类型:{2},VLAN:{3}]创建网桥[{0}],因为{5}", "arguments": [ - "spec.getType()", - "PciDeviceType.leagalPciDeviceCandidateTypes" + "cmd.getBridgeName()", + "l2Network.getUuid()", + "l2Network.getType()", + "finalVlanId", + "hostUuid", + "rsp.getError()" ], - "line": 989, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "line": 86, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java" }, { - "raw": "illegal type[%s] for pci device, only %s are legal", - "en_US": "illegal type[{0}] for pci device, only {1} are legal", - "zh_CN": "", + "raw": "failed to check bridge[%s] for hardwareVxlan[uuid:%s, name:%s] on kvm host[uuid:%s], %s", + "en_US": "failed to check bridge[{0}] for hardwareVxlan[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", + "zh_CN": "无法在KVM物理机[uuid:{3}]上检查硬件VXLAN[uuid:{1},名称:{2}]的网桥[{0}],{4}", "arguments": [ - "vo.getType()", - "PciDeviceType.leagalPciDeviceCandidateTypes" + "cmd.getBridgeName()", + "vxlan.getUuid()", + "vxlan.getName()", + "hostUuid", + "rsp.getError()" ], - "line": 978, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "line": 144, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java" }, { - "raw": "can not attach this pci device[uuid:%s] to vm[uuid:%s] due to host allocation", - "en_US": "can not attach this pci device[uuid:{0}] to vm[uuid:{1}] due to host allocation", - "zh_CN": "由于物理机分配问题导致不能将PCI设备[uuid:{0}]绑定虚拟机[uuid:{1}]", + "raw": "failed to check physical interface for HardwareVxlanPool[uuid:%s, name:%s] on kvm host[uuid: %s], %s", + "en_US": "failed to check physical interface for HardwareVxlanPool[uuid:{0}, name:{1}] on kvm host[uuid: {2}], {3}", + "zh_CN": "无法检查KVM物理机[uuid:{2}]上的硬件vxlanpool[uuid:{0},名称:{1}]的物理接口,{3}", "arguments": [ - "msg.getPciDeviceUuid()", - "msg.getVmInstanceUuid()" + "l2Network.getUuid()", + "l2Network.getName()", + "hostUuid", + "rsp.getError()" ], - "line": 637, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "line": 64, + "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java" }, { - "raw": "can not migrate vm[uuid:%s] since pci device attached", - "en_US": "can not migrate vm[uuid:{0}] since pci device attached", - "zh_CN": "当PCI设备绑定后不能迁移虚拟机[uuid:{0}]", - "arguments": [ - "msg.getVmInstanceUuid()" - ], - "line": 910, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "raw": "set to disconnected", + "en_US": "set to disconnected", + "zh_CN": "设置为断开连接", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/simulator/SimulatorHost.java" }, { - "raw": "cannot migrate root volume[uuid:%s] because there are pci devices attached", - "en_US": "cannot migrate root volume[uuid:{0}] because there are pci devices attached", - "zh_CN": "不能迁移根云盘[uuid:{0}],因为它所在的云主机挂载了PCI设备", + "raw": "invalid phone number[%s], sms number is like +86-18654321234", + "en_US": "invalid phone number[{0}], sms number is like +86-18654321234", + "zh_CN": "电话号码[{0}]无效,短信号码类似于+86-18654321234", "arguments": [ - "msg.getVolumeUuid()" + "number" ], - "line": 941, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "line": 97, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "pci device[uuid:%s] doesn\u0027t exist or is disabled for vm[uuid:%s]", - "en_US": "pci device[uuid:{0}] doesn\u0027t exist or is disabled for vm[uuid:{1}]", - "zh_CN": "", + "raw": "can not add same email address to endpoint[uuid:%s]", + "en_US": "can not add same email address to endpoint[uuid:{0}]", + "zh_CN": "无法将同一电子邮件地址添加到端点[uuid:{0}]", "arguments": [ - "pciUuid", - "vmUuid" + "msg.getApplicationEndpointUuid()" ], - "line": 1167, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "line": 64, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "pci device[uuid:%s] already attached to vm[uuid:%s], cannot attach to vm[uuid:%s]", - "en_US": "pci device[uuid:{0}] already attached to vm[uuid:{1}], cannot attach to vm[uuid:{2}]", - "zh_CN": "", + "raw": "invalid email address[%s]", + "en_US": "invalid email address[{0}]", + "zh_CN": "无效的email地址[{0}]", "arguments": [ - "pciUuid", - "vo.getVmInstanceUuid()", - "vmUuid" + "errorEmails" ], - "line": 1176, - "fileName": "src/main/java/org/zstack/pciDevice/PciDeviceManager.java" + "line": 165, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "The host [%s] has failed to enter the maintenance, The vm [%s] cannot migrate automatically because it contains the PCI device", - "en_US": "The host [{0}] has failed to enter the maintenance, The vm [{1}] cannot migrate automatically because it contains the PCI device", - "zh_CN": "物理机[{0}]进入维护状态失败,这个虚拟机[{1}]不能自动迁移,因为虚拟机包含了PCI设备", + "raw": "cannot update email address to %s, which is already exists in endpoint[uuid:%s]", + "en_US": "cannot update email address to {0}, which is already exists in endpoint[uuid:{1}]", + "zh_CN": "无法将电子邮件地址更新为{0},该地址已存在于端点[uuid:{1}]中", "arguments": [ - "inventory.getUuid()", - "hasPciVmUuids.toString()" + "msg.getEmailAddress()", + "msg.getApplicationEndpointUuid()" ], - "line": 58, - "fileName": "src/main/java/org/zstack/pciDevice/PciHostChangeStateExtension.java" + "line": 77, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to set pci device spec", - "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to set pci device spec", - "zh_CN": "云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以设置PCI设备规格", + "raw": "phone number [%s] already exists", + "en_US": "phone number [{0}] already exists", + "zh_CN": "电话号码[{0}]已存在", "arguments": [ - "vmUuid", - "state" + "msg.getPhoneNumber()" ], - "line": 258, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "line": 91, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm[uuid:%s] already has pci device spec[uuid:%s]", - "en_US": "vm[uuid:{0}] already has pci device spec[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]已经设置过了PCI设备规格[uuid:{1}]", + "raw": "phone number[%s] already exists", + "en_US": "phone number[{0}] already exists", + "zh_CN": "手机号码[{0}]已存在", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getPciSpecUuid()" + "msg.getPhoneNumber()" ], - "line": 169, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "line": 106, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm[uuid:%s] doesn\u0027t have pci device spec[uuid:%s]", - "en_US": "vm[uuid:{0}] doesn\u0027t have pci device spec[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]未设置PCI设备规格[uuid:{1}]", + "raw": "invalid url[%s]", + "en_US": "invalid url[{0}]", + "zh_CN": "无效的url[{0}]", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getPciSpecUuid()" + "url" ], - "line": 197, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "line": 115, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to remove pci device spec[uuid:%s]", - "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to remove pci device spec[uuid:{2}]", - "zh_CN": "云主机[uuid:{0}], state:{1}需要处于关机状态下才可以取消PCI设备规格[uuid:{2}]", + "raw": "[%s] is not a legal ip", + "en_US": "[{0}] is not a legal ip", + "zh_CN": "[{0}]不是合法的IP", "arguments": [ - "vm.getUuid()", - "vm.getState()", - "msg.getPciSpecUuid()" + "host" ], - "line": 204, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "line": 121, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm[uuid:%s] already has mdev device spec[uuid:%s]", - "en_US": "vm[uuid:{0}] already has mdev device spec[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]已经设置过了MDEV设备规格[uuid:{1}]", + "raw": "invalid phone number[%s], the DingDing phone number is like +86-12388889999", + "en_US": "invalid phone number[{0}], the DingDing phone number is like +86-12388889999", + "zh_CN": "无效的手机号码[{0}], 钉钉手机号码格式应当为 +86-12388889999", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getMdevSpecUuid()" + "n" ], - "line": 285, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "line": 127, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to set mdev device spec", - "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to set mdev device spec", - "zh_CN": "云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以设置MDEV设备规格", - "arguments": [ - "vm.getUuid()", - "vm.getState()" - ], - "line": 293, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "raw": "username and password must either absent at all or present with each other", + "en_US": "username and password must either absent at all or present with each other", + "zh_CN": "用户名和密码要么同时为空要么同时不为空", + "arguments": [], + "line": 144, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm[uuid:%s] doesn\u0027t have mdev device spec[uuid:%s]", - "en_US": "vm[uuid:{0}] doesn\u0027t have mdev device spec[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]未设置过MDEV设备规格[uuid:{1}]", - "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getMdevSpecUuid()" - ], - "line": 306, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "raw": "can not create sns email endpoint without any email address", + "en_US": "can not create sns email endpoint without any email address", + "zh_CN": "无法在没有任何电子邮件地址的情况下创建SNS电子邮件端点", + "arguments": [], + "line": 152, + "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" }, { - "raw": "vm instance[uuid:%s, state:%s] needs to be stopped to remove mdev device spec[uuid:%s]", - "en_US": "vm instance[uuid:{0}, state:{1}] needs to be stopped to remove mdev device spec[uuid:{2}]", - "zh_CN": "云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以取消MDEV设备规格[uuid:{2}]", - "arguments": [ - "vm.getUuid()", - "vm.getState()", - "msg.getMdevSpecUuid()" - ], - "line": 313, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java" + "raw": "the operation is not permitted for the system application platform", + "en_US": "the operation is not permitted for the system application platform", + "zh_CN": "禁止对该应用平台进行当前操作", + "arguments": [], + "line": 118, + "fileName": "src/main/java/org/zstack/sns/SNSApplicationPlatformBase.java" }, { - "raw": "pci device spec[uuid:%s] is not available for vm[uuid:%s]", - "en_US": "pci device spec[uuid:{0}] is not available for vm[uuid:{1}]", - "zh_CN": "云主机[uuid:{1}]无法设置PCI设备规格[uuid:{0}]", + "raw": "cannot find the SNSTopic[uuid:%s], it may have been deleted", + "en_US": "cannot find the SNSTopic[uuid:{0}], it may have been deleted", + "zh_CN": "找不到SNS主题[uuid:{0}], 它可能已经被删除", "arguments": [ - "msg.getPciSpecUuid()", - "msg.getVmInstanceUuid()" + "msg.getTopicUuid()" ], - "line": 373, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "line": 67, + "fileName": "src/main/java/org/zstack/sns/SNSManagerImpl.java" }, { - "raw": "no pci device spec available for vm[uuid:%s]", - "en_US": "no pci device spec available for vm[uuid:{0}]", - "zh_CN": "云主机[uuid:{0}]无可用的PCI设备规格", + "raw": "cannot find SNSApplicationPlatform[uuid:%s], it may have been deleted", + "en_US": "cannot find SNSApplicationPlatform[uuid:{0}], it may have been deleted", + "zh_CN": "找不到SNS应用平台[uuid:{0}], 它可能已经被删除", "arguments": [ - "msg.getVmInstanceUuid()" + "msg.getApplicationPlatformUuid()" ], - "line": 371, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "line": 85, + "fileName": "src/main/java/org/zstack/sns/SNSManagerImpl.java" }, { - "raw": "failed to get pci device spec available for vm[uuid:%s]: %s", - "en_US": "failed to get pci device spec available for vm[uuid:{0}]: {1}", - "zh_CN": "", + "raw": "cannot find SNSApplicationEndpoint[uuid:%s], it may have been deleted", + "en_US": "cannot find SNSApplicationEndpoint[uuid:{0}], it may have been deleted", + "zh_CN": "找不到SNS应用接收终端[uuid:{0}], 它可能已经被删除", "arguments": [ - "msg.getVmInstanceUuid()", - "rly.getError()" + "msg.getApplicationEndpointUuid()" ], - "line": 366, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "line": 95, + "fileName": "src/main/java/org/zstack/sns/SNSManagerImpl.java" }, { - "raw": "pci devices[uuid:%s] should have been attached to vm[uuid:%s] but it is attached to vm[uuid:%s]", - "en_US": "pci devices[uuid:{0}] should have been attached to vm[uuid:{1}] but it is attached to vm[uuid:{2}]", - "zh_CN": "PCI设备[uuid:{0}]本应该绑定云主机[uuid:{1}], 但实际上绑定了云主机[uuid:{2}]", - "arguments": [ - "pciUuidsNotMatch", - "msg.getVmInstanceUuid()", - "vmUuidsPciAttached" - ], - "line": 454, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "raw": "the topic is not subscribed by any endpoints", + "en_US": "the topic is not subscribed by any endpoints", + "zh_CN": "当前主题并未被任何应用终端订阅", + "arguments": [], + "line": 128, + "fileName": "src/main/java/org/zstack/sns/SNSTopicBase.java" + }, + { + "raw": "application platform is disabled", + "en_US": "application platform is disabled", + "zh_CN": "应用平台被不可用", + "arguments": [], + "line": 154, + "fileName": "src/main/java/org/zstack/sns/SNSTopicBase.java" + }, + { + "raw": "application endpoint is disabled", + "en_US": "application endpoint is disabled", + "zh_CN": "应用接收端被禁用", + "arguments": [], + "line": 224, + "fileName": "src/main/java/org/zstack/sns/SNSTopicBase.java" }, { - "raw": "mdev device spec[uuid:%s] is not available for vm[uuid:%s]", - "en_US": "mdev device spec[uuid:{0}] is not available for vm[uuid:{1}]", - "zh_CN": "云主机[uuid:{1}]无法设置MDEV设备规格[uuid:{0}]", + "raw": "Aliyun account[uuid:%s] not exists", + "en_US": "Aliyun account[uuid:{0}] not exists", + "zh_CN": "阿里云账号[uuid:{0}]不存在", "arguments": [ - "msg.getMdevSpecUuid()", - "msg.getVmInstanceUuid()" + "msg.getAccessKeyUuid()" ], - "line": 565, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "line": 44, + "fileName": "src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java" }, { - "raw": "no mdev device spec available for vm[uuid:%s]", - "en_US": "no mdev device spec available for vm[uuid:{0}]", - "zh_CN": "云主机[uuid:{0}]无可用的MDEV设备规格", + "raw": "Aliyun sms event text template not found.", + "en_US": "Aliyun sms event text template not found.", + "zh_CN": "未找到阿里云短信事件文本模板。", "arguments": [ - "msg.getVmInstanceUuid()" + "SysErrors.RESOURCE_NOT_FOUND" ], - "line": 558, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "line": 83, + "fileName": "src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsEndpoint.java" }, { - "raw": "pci device spec[uuid:%s] doesn\u0027t exist", - "en_US": "pci device spec[uuid:{0}] doesn\u0027t exist", - "zh_CN": "PCI设备规格[uuid:{0}]不存在", + "raw": "failed to send messages to DingTalk. status: %s, body: %s", + "en_US": "failed to send messages to DingTalk. status: {0}, body: {1}", + "zh_CN": "向DingTalk发送消息失败。状态:{0},正文:{1}", "arguments": [ - "specUuid", - "systemTag" + "rsp.getStatusCode()", + "rsp.getBody()" ], - "line": 779, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" + "line": 130, + "fileName": "src/main/java/org/zstack/sns/platform/dingtalk/SNSDingTalkEndpoint.java" }, { - "raw": "mdev device spec[uuid:%s] doesn\u0027t exist", - "en_US": "mdev device spec[uuid:{0}] doesn\u0027t exist", - "zh_CN": "MDEV设备规格[uuid:{0}]不存在", + "raw": "cannot connect SMTP server[server: %s, port: %s] in 15 seconds", + "en_US": "cannot connect SMTP server[server: {0}, port: {1}] in 15 seconds", + "zh_CN": "在15秒内无法连接到SMTP服务器[server: {0}, port: {1}]", "arguments": [ - "specUuid", - "systemTag" + "getSelf().getSmtpServer()", + "getSelf().getSmtpPort()" ], - "line": 792, - "fileName": "src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java" - }, - { - "raw": "cluster uuids or host uuid or vm uuid can not be set at same time", - "en_US": "cluster uuids or host uuid or vm uuid can not be set at same time", - "zh_CN": "获取候选规格列表时不要同时指定集群UUIDs、物理机UUID或云主机UUID", - "arguments": [], - "line": 153, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" - }, - { - "raw": "clusters not exist or disabled", - "en_US": "clusters not exist or disabled", - "zh_CN": "集群不存在或已禁用", - "arguments": [], - "line": 160, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 72, + "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" }, { - "raw": "illegal mdev device type [%s], only %s are legal", - "en_US": "illegal mdev device type [{0}], only {1} are legal", - "zh_CN": "非法的MDEV设备类型[{0}],只有{1}才是合法的", + "raw": "SMTP server validation error: %s", + "en_US": "SMTP server validation error: {0}", + "zh_CN": "SMTP服务器验证错误: {0}", "arguments": [ - "type", - "legalTypes" + "e.getMessage()" ], - "line": 194, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 88, + "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" }, { - "raw": "cannot change the state of mdev device that\u0027s in attached status", - "en_US": "cannot change the state of mdev device that\u0027s in attached status", - "zh_CN": "MDEV设备处于已挂载状态,无法修改其状态", + "raw": "the endpoint is disabled", + "en_US": "the endpoint is disabled", + "zh_CN": "通知终端不可用", "arguments": [], - "line": 67, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 130, + "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" }, { - "raw": "cannot attach mdev device[uuid:%s] to vm, make sure it\u0027s enabled and un-attached", - "en_US": "cannot attach mdev device[uuid:{0}] to vm, make sure it\u0027s enabled and un-attached", - "zh_CN": "无法为云主机挂载MDEV设备[uuid:{0}],因为该设备处于禁用状态或已被挂载", - "arguments": [ - "msg.getMdevDeviceUuid()" - ], - "line": 75, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "raw": "no subject", + "en_US": "no subject", + "zh_CN": "没有主题", + "arguments": [], + "line": 158, + "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" }, { - "raw": "cannot attach mdev device to vm instance that\u0027s not stopped", - "en_US": "cannot attach mdev device to vm instance that\u0027s not stopped", - "zh_CN": "云主机需要处于关机状态下才可以挂载MDEV设备", + "raw": "The problem may be caused by an incorrect user name or password or email permission denied", + "en_US": "The problem may be caused by an incorrect user name or password or email permission denied", + "zh_CN": "导致操作失败的原因可能是不正确的用户名、密码或邮件访问权限不足", "arguments": [], - "line": 182, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 66, + "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java" }, { - "raw": "vm[uuid:%s] has pci devices attached that are in different host with mdev device[uuid:%s]", - "en_US": "vm[uuid:{0}] has pci devices attached that are in different host with mdev device[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]已经挂载了PCI设备,并且它们和MDEV设备[uuid:{1}]不在同一台物理机上", + "raw": "Couldn\u0027t connect to host, port: %s, %d. The problem may be caused by an incorrect smtpServer or smtpPort", + "en_US": "Couldn\u0027t connect to host, port: {0}, {1}. The problem may be caused by an incorrect smtpServer or smtpPort", + "zh_CN": "连接{0}:{1}超时,导致原因可能是不正确的邮件服务器和邮件服务器端口", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getMdevDeviceUuid()" + "smtpServer", + "smtpPort" ], - "line": 95, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 68, + "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java" }, { - "raw": "vm[uuid:%s] has mdev devices attached that are in different host with mdev device[uuid:%s]", - "en_US": "vm[uuid:{0}] has mdev devices attached that are in different host with mdev device[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]已经挂载了MDEV设备,并且它们和MDEV设备[uuid:{1}]不在同一台物理机上", + "raw": "HTTP POST failure. status: %s, body: %s", + "en_US": "HTTP POST failure. status: {0}, body: {1}", + "zh_CN": "HTTP POST失败,状态码: {0}, body: {1}", "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getMdevDeviceUuid()" + "rsp.getStatusCode()", + "rsp.getBody()" ], - "line": 105, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 67, + "fileName": "src/main/java/org/zstack/sns/platform/http/SNSHttpEndpoint.java" }, { - "raw": "the host[uuid:%s] that holds mdev device[uuid:%s] is not [%s] and [%s]", - "en_US": "the host[uuid:{0}] that holds mdev device[uuid:{1}] is not [{2}] and [{3}]", - "zh_CN": "", + "raw": "failed to send messages to Microsoft Teams. status: %s, body: %s", + "en_US": "failed to send messages to Microsoft Teams. status: {0}, body: {1}", + "zh_CN": "未能将消息发送到Microsoft Teams。状态:{0},正文:{1}", "arguments": [ - "mdev.getHostUuid()", - "mdev.getUuid()", - "HostState.Enabled", - "HostStatus.Connected" + "rsp.getStatusCode()", + "rsp.getBody()" ], - "line": 112, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 69, + "fileName": "src/main/java/org/zstack/sns/platform/microsoftteams/SNSMicrosoftTeamsEndpoint.java" }, { - "raw": "IOMMU of the host[uuid:%s] that hosts pci device[uuid:%s] is not [%s] and [%s]", - "en_US": "IOMMU of the host[uuid:{0}] that hosts pci device[uuid:{1}] is not [{2}] and [{3}]", - "zh_CN": "", + "raw": "only HTTP endpoint can subscribe API topic, the endpoint[type:%s] is not a HTTP endpoint", + "en_US": "only HTTP endpoint can subscribe API topic, the endpoint[type:{0}] is not a HTTP endpoint", + "zh_CN": "仅HTTP通知终端可以订阅API通知主题,当前通知终端[type:{0}]不是一个HTTP通知终端", "arguments": [ - "mdev.getHostUuid()", - "mdev.getUuid()", - "HostState.Enabled", - "HostStatus.Connected" + "endpoint.getType()" ], - "line": 121, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 172, + "fileName": "src/main/java/org/zstack/sns/system/SNSApiTopicManagerImpl.java" }, { - "raw": "mdev device [uuid:%s] is not attached to vm[uuid:%s]", - "en_US": "mdev device [uuid:{0}] is not attached to vm[uuid:{1}]", - "zh_CN": "MDEV设备[uuid:{0}]没有挂载到云主机[uuid:{1}]", - "arguments": [ - "msg.getMdevDeviceUuid()", - "msg.getVmInstanceUuid()" - ], - "line": 134, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "raw": "API topic cannot be deleted", + "en_US": "API topic cannot be deleted", + "zh_CN": "API通知主题无法被删除", + "arguments": [], + "line": 191, + "fileName": "src/main/java/org/zstack/sns/system/SNSApiTopicManagerImpl.java" }, { - "raw": "cannot detach mdev device from vm instance when it\u0027s not stopped", - "en_US": "cannot detach mdev device from vm instance when it\u0027s not stopped", - "zh_CN": "云主机需要处于关机状态下才可以卸载MDEV设备", + "raw": "system alarm topic cannot be deleted", + "en_US": "system alarm topic cannot be deleted", + "zh_CN": "系统警报通知主题不能被删除", "arguments": [], - "line": 143, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java" + "line": 78, + "fileName": "src/main/java/org/zstack/sns/system/SNSSystemAlarmTopicManagerImpl.java" }, { - "raw": "vm[uuid:%s] cannot start in host that hold mdev device[uuid:%s]", - "en_US": "vm[uuid:{0}] cannot start in host that hold mdev device[uuid:{1}]", - "zh_CN": "云主机[uuid:{0}]无法在MDEV设备[uuid:{1}]所在的物理机上启动", - "arguments": [ - "msg.getVmInstanceUuid()", - "msg.getMdevDeviceUuid()" - ], - "line": 111, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java" + "raw": "url is error, clientUuid is miss", + "en_US": "url is error, clientUuid is miss", + "zh_CN": "URL错误,缺少Clientuuid", + "arguments": [], + "line": 53, + "fileName": "src/main/java/org/zstack/sso/cas/filter/CasLoginFilter.java" }, { - "raw": "pci device[uuid:%s] is known as %s, but cannot find it\u0027s mdev spec, so abort.", - "en_US": "pci device[uuid:{0}] is known as {1}, but cannot find it\u0027s mdev spec, so abort.", - "zh_CN": "PCI设备[uuid:{0}]是{1},但无法找到可用的MDEV设备规格", - "arguments": [ - "pciDevice.getUuid()", - "PciDeviceVirtStatus.VFIO_MDEV_VIRTUALIZED" - ], - "line": 68, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFactory.java" + "raw": " missing cas client, please create cas client before sso", + "en_US": " missing cas client, please create cas client before sso", + "zh_CN": "缺少CAS客户端,请在SSO之前创建CAS客户端", + "arguments": [], + "line": 58, + "fileName": "src/main/java/org/zstack/sso/cas/filter/CasLoginFilter.java" }, { - "raw": "The host [%s] has failed to enter the maintenance, because vm[%s] has mdev devices attached and cannot migrate automatically", - "en_US": "The host [{0}] has failed to enter the maintenance, because vm[{1}] has mdev devices attached and cannot migrate automatically", - "zh_CN": "物理机[{0}]无法进入维护模式,因为云主机[{1}]挂载了MDEV设备导致无法迁移", + "raw": "duplicate casLogin[%s, %s] for type[%s]", + "en_US": "duplicate casLogin[{0}, {1}] for type[{2}]", + "zh_CN": "类型[{2}]的CASLogin[{0},{1}]重复", "arguments": [ - "inventory.getUuid()", - "hasMdevVmUuids.toString()" + "login.getClass().getName()", + "old.getClass().getName()", + "login.getLoginType()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceHostChangeStateExtension.java" + "line": 62, + "fileName": "src/main/java/org/zstack/sso/cas/service/CasClientManagerImpl.java" }, { - "raw": "failed to get candidate hosts to start vm[uuid:%s], %s", - "en_US": "failed to get candidate hosts to start vm[uuid:{0}], {1}", - "zh_CN": "无法为云主机[uuid:{0}]寻找到可启动的物理机:{1}", + "raw": "Cannot find CasLogin for type(%s)", + "en_US": "Cannot find CasLogin for type({0})", + "zh_CN": "找不到类型({0})的CASlogin", "arguments": [ - "msg.getVmInstanceUuid()", - "rly.getError()" + "type" ], - "line": 133, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 73, + "fileName": "src/main/java/org/zstack/sso/cas/service/CasClientManagerImpl.java" }, { - "raw": "cannot find mdev device[uuid:%s], it may have been deleted", - "en_US": "cannot find mdev device[uuid:{0}], it may have been deleted", - "zh_CN": "找不到MDEV设备[uuid:{0}]", + "raw": "iam2 has a user with the same name[%s]", + "en_US": "iam2 has a user with the same name[{0}]", + "zh_CN": "IAM2具有同名[{0}]的用户", "arguments": [ - "msg.getMdevDeviceUuid()" + "userName" ], - "line": 231, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 67, + "fileName": "src/main/java/org/zstack/sso/cas/service/CasLoginIAM2.java" }, { - "raw": "mdev device[uuid:%s] doesn\u0027t exist or is disabled for vm[uuid:%s]", - "en_US": "mdev device[uuid:{0}] doesn\u0027t exist or is disabled for vm[uuid:{1}]", - "zh_CN": "", + "raw": " local user has a user with the same name[%s]", + "en_US": " local user has a user with the same name[{0}]", + "zh_CN": "本地用户具有同名[{0}]的用户", "arguments": [ - "mdevUuid", - "vmUuid" + "userName" ], - "line": 403, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 71, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM1.java" }, { - "raw": "mdev device[uuid:%s] already attached to vm[uuid:%s], cannot attach to vm [uuid:%s]", - "en_US": "mdev device[uuid:{0}] already attached to vm[uuid:{1}], cannot attach to vm [uuid:{2}]", - "zh_CN": "", + "raw": "fail to get params[%s]", + "en_US": "fail to get params[{0}]", + "zh_CN": "无法获取参数[{0}]", "arguments": [ - "mdevUuid", - "vo.getVmInstanceUuid()", - "vmUuid" + "ssoUseAsLoginName" ], - "line": 412, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 57, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java" }, { - "raw": "can not migrate vm[uuid:%s] since mdev device attached", - "en_US": "can not migrate vm[uuid:{0}] since mdev device attached", - "zh_CN": "无法迁移云主机[uuid:{0}],因为它挂载了MDEV设备", - "arguments": [ - "msg.getVmInstanceUuid()" - ], - "line": 509, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "raw": "get user name is null", + "en_US": "get user name is null", + "zh_CN": "获取用户名为空", + "arguments": [], + "line": 61, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java" }, { - "raw": "cannot migrate root volume[uuid:%s] because there are mdev devices attached", - "en_US": "cannot migrate root volume[uuid:{0}] because there are mdev devices attached", - "zh_CN": "无法迁移跟云盘[uuid:{0}],因为它所在云主机挂载了MDEV设备", + "raw": " iam2 has a user with the same name[%s]", + "en_US": " iam2 has a user with the same name[{0}]", + "zh_CN": "IAM2具有同名[{0}]的用户", "arguments": [ - "msg.getVolumeUuid()" + "userName" ], - "line": 538, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 66, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java" }, { - "raw": "cannot migrate vm[uuid:%s] because there are mdev devices attached", - "en_US": "cannot migrate vm[uuid:{0}] because there are mdev devices attached", - "zh_CN": "无法迁移云主机[uuid:{0}],因为它挂载了MDEV设备", + "raw": "HTTP ERROR, status code: %s, body: %s", + "en_US": "HTTP ERROR, status code: {0}, body: {1}", + "zh_CN": "HTTP错误,状态代码:{0},正文:{1}", "arguments": [ - "msg.getVmInstanceUuid()" + "rsp.getStatusCode()", + "rsp.getBody()" ], - "line": 553, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 375, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "specified mdev devices not on same host: mdev device[uuid: %s] on host[uuid: %s] while mdev device[uuid: %s] on host[uuid: %s]", - "en_US": "specified mdev devices not on same host: mdev device[uuid: {0}] on host[uuid: {1}] while mdev device[uuid: {2}] on host[uuid: {3}]", - "zh_CN": "云主机试图挂载来自不同物理机的MDEV设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}]", + "raw": "failed to %s to %s, status code: %s, response body: %s", + "en_US": "failed to {0} to {1}, status code: {2}, response body: {3}", + "zh_CN": "访问{1}时执行{0}方法失败,状态码: {2},响应体: {3}", "arguments": [ - "mdev.getUuid()", - "mdev.getHostUuid()", - "attachedMdevUuid", - "dstHostUuid" + "HttpMethod.POST", + "url", + "e.getStatusCode()", + "e.getResponseBodyAsString()" ], - "line": 796, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "line": 382, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "no candidate host with enough mdev devices", - "en_US": "no candidate host with enough mdev devices", - "zh_CN": "没有物理机满足mdev device设备的条件", - "arguments": [], - "line": 829, - "fileName": "src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java" + "raw": "failed to %s to %s, IO Error: %s", + "en_US": "failed to {0} to {1}, IO Error: {2}", + "zh_CN": "访问{1}时执行{0}方法失败,IO错误: {2}", + "arguments": [ + "HttpMethod.POST", + "url", + "e.getMessage()" + ], + "line": 386, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "No host with fewer than %s vms found", - "en_US": "No host with fewer than {0} vms found", - "zh_CN": "", + "raw": "response has error : %s", + "en_US": "response has error : {0}", + "zh_CN": "响应出现错误:{0}", "arguments": [ - "maxInstancePerHost" + "e" ], - "line": 70, - "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostAllocatorFlow.java" + "line": 201, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "Select %s strategy, you must set %s", - "en_US": "Select {0} strategy, you must set {1}", - "zh_CN": "选择策略{0},你必须设置{1}", + "raw": "duplicate OAuth2Login[%s, %s] for type[%s]", + "en_US": "duplicate OAuth2Login[{0}, {1}] for type[{2}]", + "zh_CN": "类型[{2}]的重复OAuth2Login[{0},{1}]", "arguments": [ - "HostAllocatorConstant.MAX_INSTANCE_PER_HOST_HOST_ALLOCATOR_STRATEGY_TYPE", - "HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN" + "login.getClass().getName()", + "old.getClass().getName()", + "login.getLoginType()" ], - "line": 58, - "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java" + "line": 101, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "Incorrect %s settings, valid value is %s", - "en_US": "Incorrect {0} settings, valid value is {1}", - "zh_CN": "不正确的设置{0},有效的值是{1}", + "raw": "Cannot find OAuth2Login for type(%s)", + "en_US": "Cannot find OAuth2Login for type({0})", + "zh_CN": "找不到类型({0})的OAuth2Login", "arguments": [ - "HostAllocatorSystemTags.MINIMUM_MEMORY_USAGE_HOST_ALLOCATOR_STRATEGY_MODE_TOKEN", - "modes" + "type" ], - "line": 58, - "fileName": "src/main/java/org/zstack/pluginpremium/compute/allocator/MinimumMemoryUsageHostAllocatorStrategyFactory.java" + "line": 113, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "can not find related virtual router", - "en_US": "can not find related virtual router", - "zh_CN": "", + "raw": "there was an error, reason: token response is null", + "en_US": "there was an error, reason: token response is null", + "zh_CN": "出现错误,原因:令牌响应为空", "arguments": [], - "line": 326, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" - }, - { - "raw": "l3[%s] already attached a policy route ruleSet", - "en_US": "l3[{0}] already attached a policy route ruleSet", - "zh_CN": "", - "arguments": [ - "msg.getL3Uuid()" - ], - "line": 117, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 190, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "VRouter[%s] already has a ruleSet named %s", - "en_US": "VRouter[{0}] already has a ruleSet named {1}", - "zh_CN": "", + "raw": "there was an error, reason: %s is null", + "en_US": "there was an error, reason: {0} is null", + "zh_CN": "出现错误,原因:{0}为空", "arguments": [ - "msg.getvRouterUuid()", - "msg.getName()" + "AuthGolabalProperty.OAUTH2_GET_TOKEN_USERINFO" ], - "line": 168, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 194, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "DestinationCidr must be in cidr format but found [%s]", - "en_US": "DestinationCidr must be in cidr format but found [{0}]", - "zh_CN": "", + "raw": "get code response has error : %s", + "en_US": "get code response has error : {0}", + "zh_CN": "获取代码响应出现错误:{0}", "arguments": [ - "msg.getDestinationCidr()" + "e" ], - "line": 174, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 300, + "fileName": "src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java" }, { - "raw": "NextHopIp must be in ipv4 format but found [%s]", - "en_US": "NextHopIp must be in ipv4 format but found [{0}]", - "zh_CN": "", + "raw": "%s should not be null", + "en_US": "{0} should not be null", + "zh_CN": "{0} 不能为空", "arguments": [ - "msg.getNextHopIp()" + "name" ], - "line": 178, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 65, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" }, { - "raw": "can not find related vRouter", - "en_US": "can not find related vRouter", - "zh_CN": "", + "raw": "zoneUuids, backupStorageUuids must have at least one be none-empty list, or all is set to true", + "en_US": "zoneUuids, backupStorageUuids must have at least one be none-empty list, or all is set to true", + "zh_CN": "zoneUuids, backupStorageUuids 至少有一个不为空,或者all被设置为真 ", "arguments": [], - "line": 249, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 88, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" }, { - "raw": "VRouter[%s] already has a policy route table [%s]", - "en_US": "VRouter[{0}] already has a policy route table [{1}]", - "zh_CN": "", + "raw": "backup storage[uuid:%s] has not been attached to zone[uuid:%s]", + "en_US": "backup storage[uuid:{0}] has not been attached to zone[uuid:{1}]", + "zh_CN": "镜像服务器[uuid:{0}]没有被加载到zone[uuid:{1}]", "arguments": [ - "msg.getvRouterUuid()", - "msg.getNumber()" + "msg.getBackupStorageUuid()", + "msg.getZoneUuid()" ], - "line": 271, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 118, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" }, { - "raw": "ruleSet[%s] is still attached to nic", - "en_US": "ruleSet[{0}] is still attached to nic", - "zh_CN": "", + "raw": "backup storage[uuid:%s] has been attached to zone[uuid:%s]", + "en_US": "backup storage[uuid:{0}] has been attached to zone[uuid:{1}]", + "zh_CN": "镜像服务器[uuid:{0}]已经被加载到zone[uuid:{1}]", "arguments": [ - "msg.getUuid()" + "msg.getBackupStorageUuid()", + "msg.getZoneUuid()" ], - "line": 309, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java" + "line": 127, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" }, { - "raw": "virtual router[uuid:%s] can not find", - "en_US": "virtual router[uuid:{0}] can not find", - "zh_CN": "云路由[uuid:{0}]未找到", + "raw": "failed to get header of image url %s: %s", + "en_US": "failed to get header of image url {0}: {1}", + "zh_CN": "获取链接 {0} 的Header信息失败,原因:{1}", "arguments": [ - "vrouterVmUuid" + "url", + "e.toString()" ], - "line": 743, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java" + "line": 148, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" }, { - "raw": "can not find service factory for virtual router type[%s]", - "en_US": "can not find service factory for virtual router type[{0}]", - "zh_CN": "未找到云路由类型为[{0}]的服务工厂", + "raw": "failed to get header of image url %s", + "en_US": "failed to get header of image url {0}", + "zh_CN": "获取链接 {0} 的Header信息失败", "arguments": [ - "vo.getApplianceVmType()" + "url" ], - "line": 748, - "fileName": "src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java" + "line": 152, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" }, { - "raw": "Invalid parameter [%s], make sure it\u0027s PortMirror Network", - "en_US": "Invalid parameter [{0}], make sure it\u0027s PortMirror Network", - "zh_CN": "", + "raw": "the backup storage[uuid:%s, name:%s] has not enough capacity to download the image[%s].Required size:%s, available size:%s", + "en_US": "the backup storage[uuid:{0}, name:{1}] has not enough capacity to download the image[{2}].Required size:{3}, available size:{4}", + "zh_CN": "镜像服务器[uuid:{0}, name:{1}]没有足够的容量可供下载镜像[{2}]。需要的大小: {3},可用的大小: {4}", "arguments": [ - "msg.getMirrorNetworkUuid()" + "self.getUuid()", + "self.getName()", + "url", + "size", + "self.getAvailableCapacity()" ], - "line": 47, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 175, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" }, { - "raw": "The network[%s] has been attached with a PortMirror service", - "en_US": "The network[{0}] has been attached with a PortMirror service", - "zh_CN": "", + "raw": "the image size get from url %s is %d bytes, it\u0027s too small for an image, please check the url again.", + "en_US": "the image size get from url {0} is {1} bytes, it\u0027s too small for an image, please check the url again.", + "zh_CN": "从链接 {0} 获取到的镜像大小为{1}字节,对一个正常的镜像来说太小了,请检查该链接是否合法", "arguments": [ - "msg.getMirrorNetworkUuid()" + "url", + "size" ], - "line": 55, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 172, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" }, { - "raw": "The PortMirror service[%s] has not been created", - "en_US": "The PortMirror service[{0}] has not been created", - "zh_CN": "", + "raw": "backup storage cannot proceed message[%s] because its status is %s", + "en_US": "backup storage cannot proceed message[{0}] because its status is {1}", + "zh_CN": "镜像服务器无法处理消息[{0}]因为它的状态为{1}", "arguments": [ - "msg.getUuid()" + "msg.getClass().getName()", + "self.getStatus()" ], - "line": 63, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 190, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" }, { - "raw": "The nic[%s, %s] has been mirrored by service[%s]", - "en_US": "The nic[{0}, {1}] has been mirrored by service[{2}]", - "zh_CN": "", + "raw": "backup storage cannot proceed message[%s] because its state is %s", + "en_US": "backup storage cannot proceed message[{0}] because its state is {1}", + "zh_CN": "镜像服务器无法处理消息[{0}]因为它的状态为{1}", "arguments": [ - "msg.getSrcEndPoint()", - "msg.getDstEndPoint()", - "mirror.getUuid()" + "msg.getClass().getName()", + "self.getState()" ], - "line": 99, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 196, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" }, { - "raw": "The nic[%s] can\u0027t been mirrored for service[%s] using", - "en_US": "The nic[{0}] can\u0027t been mirrored for service[{1}] using", - "zh_CN": "", + "raw": "cannot reserve %s on the backup storage[uuid:%s], it only has %s available", + "en_US": "cannot reserve {0} on the backup storage[uuid:{1}], it only has {2} available", + "zh_CN": "无法在镜像服务器{1}保留{0},它仅有{2}可用容量", "arguments": [ - "msg.getSrcEndPoint()", - "mirror.getUuid()" + "size", + "backupStorageUuid", + "capacityVO.getAvailableCapacity()" ], - "line": 105, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 139, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageCapacityUpdater.java" }, { - "raw": "The PortMirror service doesn\u0027t support to mirror the nic[%s]", - "en_US": "The PortMirror service doesn\u0027t support to mirror the nic[{0}]", - "zh_CN": "", - "arguments": [ - "msg.getSrcEndPoint()" - ], - "line": 122, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "raw": "capacity reservation on all backup storage failed", + "en_US": "capacity reservation on all backup storage failed", + "zh_CN": "在所有镜像服务器上保留容量失败", + "arguments": [], + "line": 276, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java" }, { - "raw": "The PortMirror service doesn\u0027t support the nic[%s] because of its hypervisor type", - "en_US": "The PortMirror service doesn\u0027t support the nic[{0}] because of its hypervisor type", - "zh_CN": "", + "raw": "only one backup storage data network system tag is allowed, but %s got", + "en_US": "only one backup storage data network system tag is allowed, but {0} got", + "zh_CN": "只允许一个备份存储数据网络系统标记,但{0}已获得", "arguments": [ - "msg.getDstEndPoint()" + "backupStorageDataNetworkTags.size()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 320, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java" }, { - "raw": "The PortMirror service can\u0027t mirror to the nic[%s] that is not a non-default interface of a vm", - "en_US": "The PortMirror service can\u0027t mirror to the nic[{0}] that is not a non-default interface of a vm", - "zh_CN": "", + "raw": "required primary storage[uuid:%s, type:%s] could not support any backup storage.", + "en_US": "required primary storage[uuid:{0}, type:{1}] could not support any backup storage.", + "zh_CN": "所需的主存储[uuid:{0},类型:{1}]无法支持任何备份存储。", "arguments": [ - "msg.getDstEndPoint()" + "spec.getRequiredPrimaryStorageUuid()", + "psTypeName" ], - "line": 134, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 46, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStoragePrimaryStorageAllocatorFlow.java" }, { - "raw": "The PortMirror service can\u0027t mirror the nic[%s] that is not an interface of any vm", - "en_US": "The PortMirror service can\u0027t mirror the nic[{0}] that is not an interface of any vm", - "zh_CN": "", + "raw": "after subtracting reserved capacity, no backup storage has required capacity[%s bytes]", + "en_US": "after subtracting reserved capacity, no backup storage has required capacity[{0} bytes]", + "zh_CN": "减去保留容量后,没有备份存储具有所需容量[{0}字节]", "arguments": [ - "msg.getSrcEndPoint()" + "spec.getSize()" ], - "line": 141, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 55, + "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageReservedCapacityAllocatorFlow.java" }, { - "raw": "The PortMirror service can\u0027t mirror the nic[%s] to nic[%s] because the mirror network[%s] can\u0027t setup the mirror tunnel", - "en_US": "The PortMirror service can\u0027t mirror the nic[{0}] to nic[{1}] because the mirror network[{2}] can\u0027t setup the mirror tunnel", - "zh_CN": "", - "arguments": [ - "msg.getSrcEndPoint()", - "msg.getDstEndPoint()", - "vo.getMirrorNetworkUuid()" - ], - "line": 151, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "raw": "missing \u0027retentionType\u0027 in job parameters", + "en_US": "missing \u0027retentionType\u0027 in job parameters", + "zh_CN": "parameters中缺少retentionType参数", + "arguments": [], + "line": 328, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "The PortMirror service can\u0027t mirror the nic[%s] to itself", - "en_US": "The PortMirror service can\u0027t mirror the nic[{0}] to itself", - "zh_CN": "", - "arguments": [ - "msg.getSrcEndPoint()" - ], - "line": 157, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "raw": "missing \u0027retentionValue\u0027 in job parameters", + "en_US": "missing \u0027retentionValue\u0027 in job parameters", + "zh_CN": "parameter中缺少retentionValue参数", + "arguments": [], + "line": 332, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "The PortMirror service can\u0027t work at the nic with configured Qos", - "en_US": "The PortMirror service can\u0027t work at the nic with configured Qos", - "zh_CN": "", + "raw": "missing \u0027backupStorageUuids\u0027 in job parameters", + "en_US": "missing \u0027backupStorageUuids\u0027 in job parameters", + "zh_CN": "parameter中缺少backupStorageUuids参数", "arguments": [], - "line": 163, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java" + "line": 336, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "failed to delete portMirror session[%s] from hypervisor, detail: %s", - "en_US": "failed to delete portMirror session[{0}] from hypervisor, detail: {1}", - "zh_CN": "", - "arguments": [ - "sessionVO.getUuid()", - "errorCode.getDetails()" - ], - "line": 750, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java" + "raw": "job parameter \u0027backupStorageUuids\u0027 is empty", + "en_US": "job parameter \u0027backupStorageUuids\u0027 is empty", + "zh_CN": "parameter中backupStorageUuids为空", + "arguments": [], + "line": 340, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "failed to release portMirror session[%s] from hypervisor, detail: %s", - "en_US": "failed to release portMirror session[{0}] from hypervisor, detail: {1}", - "zh_CN": "", + "raw": "unexpected backup storage uuid: %s", + "en_US": "unexpected backup storage uuid: {0}", + "zh_CN": "错误的镜像服务器uuid: {0}", "arguments": [ - "sessionVO.getUuid()", - "errorCode.getDetails()" + "bsUuid" ], - "line": 783, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java" + "line": 345, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "cannot find internal id of the session[uuid:%s], are there too many sessions in a host???", - "en_US": "cannot find internal id of the session[uuid:{0}], are there too many sessions in a host???", - "zh_CN": "", - "arguments": [ - "vo.getUuid()" - ], - "line": 901, - "fileName": "src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java" + "raw": "missing \u0027remoteRetentionValue\u0027 in job parameters", + "en_US": "missing \u0027remoteRetentionValue\u0027 in job parameters", + "zh_CN": "作业参数中缺少“ RemoteRetentionValue ”", + "arguments": [], + "line": 354, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "resourceUuid[%s] is not a valid uuid. A valid uuid is a UUID(v4 recommended) with \u0027-\u0027 stripped. see http://en.wikipedia.org/wiki/Universally_unique_identifier for format of UUID, the regular expression ZStack uses to validate a UUID is \u0027[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}\u0027", - "en_US": "resourceUuid[{0}] is not a valid uuid. A valid uuid is a UUID(v4 recommended) with \u0027-\u0027 stripped. see http://en.wikipedia.org/wiki/Universally_unique_identifier for format of UUID, the regular expression ZStack uses to validate a UUID is \u0027[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}\u0027", - "zh_CN": "资源UUID()不是一个有效的uuid。一个有效的UUID是一个没有-的UUID(建议为UUIDv4).格式参见http://en.wikipedia.org/wiki/Universally_unique_identifier,ZStack中验证一个UUID的正则表达式为: [0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}", - "arguments": [ - "cmsg.getResourceUuid()" - ], - "line": 246, - "fileName": "src/main/java/org/zstack/portal/apimediator/ApiMediatorImpl.java" + "raw": "missing \u0027remoteRetentionType\u0027 in job parameters", + "en_US": "missing \u0027remoteRetentionType\u0027 in job parameters", + "zh_CN": "作业参数中缺少“ RemoteRetentionType ”", + "arguments": [], + "line": 352, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "non support method: %s", - "en_US": "non support method: {0}", - "zh_CN": "", - "arguments": [ - "method" - ], - "line": 122, - "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java" + "raw": "No available backup storage found, skip this job", + "en_US": "No available backup storage found, skip this job", + "zh_CN": "找不到可用的备份存储,请跳过此作业", + "arguments": [], + "line": 84, + "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" }, { - "raw": "http request error! status_code: %s, error: %s", - "en_US": "http request error! status_code: {0}, error: {1}", - "zh_CN": "", + "raw": "volume[uuid:%s] is deleted, state change is not allowed", + "en_US": "volume[uuid:{0}] is deleted, state change is not allowed", + "zh_CN": "卷[uuid:{0}]已删除,不允许更改状态", "arguments": [ - "statusCode", - "response.getStatusLine().getReasonPhrase()" + "getTargetResourceUuid()" ], - "line": 135, - "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java" + "line": 578, + "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" }, { - "raw": "sqlite3 execute failed, because: %s", - "en_US": "sqlite3 execute failed, because: {0}", - "zh_CN": "", - "arguments": [ - "r.getStderr()" - ], - "line": 24, - "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaDB.java" + "raw": "bandWidth must be a positive number", + "en_US": "bandWidth must be a positive number", + "zh_CN": "带宽必须为正数", + "arguments": [], + "line": 137, + "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" }, { - "raw": "cannot find folder: %s in dashboard", - "en_US": "cannot find folder: {0} in dashboard", - "zh_CN": "", + "raw": "missing job parameters", + "en_US": "missing job parameters", + "zh_CN": "缺少parameters参数", + "arguments": [], + "line": 217, + "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" + }, + { + "raw": "database backup[uuid%s] has not been exported from backupStorage[uuid:%s]", + "en_US": "database backup[uuid{0}] has not been exported from backupStorage[uuid:{1}]", + "zh_CN": "数据库备份[uuid{0}]尚未从备份存储[uuid:{1}]中导出", "arguments": [ - "GrafanaDB.folderTitle" + "msg.getDatabaseBackupUuid()", + "msg.getBackupStorageUuid()" ], - "line": 34, - "fileName": "src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaDashboard.java" + "line": 93, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" }, { - "raw": "cannot copy %s to %s, caused: %s", - "en_US": "cannot copy {0} to {1}, caused: {2}", - "zh_CN": "", + "raw": "database backup[uuid%s] has been exported from backupStorage[uuid:%s]", + "en_US": "database backup[uuid{0}] has been exported from backupStorage[uuid:{1}]", + "zh_CN": "数据库备份[uuid{0}]已从备份存储[uuid:{1}]中导出", "arguments": [ - "src.getAbsolutePath()", - "dst.getAbsolutePath()", - "rst.getStderr()" + "msg.getDatabaseBackupUuid()", + "msg.getBackupStorageUuid()" ], - "line": 84, - "fileName": "src/main/java/org/zstack/premium/externalservice/loki/LokiFactory.java" + "line": 107, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" }, { - "raw": "ssh failed", - "en_US": "ssh failed", - "zh_CN": "", + "raw": "do not allow cover database from backup", + "en_US": "do not allow cover database from backup", + "zh_CN": "不允许从备份中覆盖数据库", "arguments": [], - "line": 103, - "fileName": "src/main/java/org/zstack/premium/externalservice/loki/PromtailFactory.java" - }, - { - "raw": "unknown value type %s, key \u003d %s", - "en_US": "unknown value type {0}, key \u003d {1}", - "zh_CN": "", - "arguments": [ - "v.getClass().getSimpleName()", - "k" - ], - "line": 106, - "fileName": "src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java" + "line": 120, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" }, { - "raw": "failed to HTTP call all prometheus instances", - "en_US": "failed to HTTP call all prometheus instances", - "zh_CN": "", + "raw": "installPath and bsUrl are both need", + "en_US": "installPath and bsUrl are both need", + "zh_CN": "InstallPath和BSURL都是必需", "arguments": [], - "line": 132, - "fileName": "src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java" + "line": 124, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" }, { - "raw": "the operation is not permitted by white list of virtual-id[uuid:%s]", - "en_US": "the operation is not permitted by white list of virtual-id[uuid:{0}]", - "zh_CN": "无法操作,操作不存在用户[uuid:{0}]白名单中", - "arguments": [ - "rbacEntity.getApiMessage().getSession().getUserUuid()" - ], - "line": 48, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminAPIRequestChecker.java" + "raw": "databaseBackup[uuid:%s] is not Enabled and Ready", + "en_US": "databaseBackup[uuid:{0}] is not Enabled and Ready", + "zh_CN": "DatabaseBackup[uuid:{0}]未启用且未就绪", + "arguments": [], + "line": 133, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" }, { - "raw": "the operation is denied by black list of virtual-id[uuid:%s]", - "en_US": "the operation is denied by black list of virtual-id[uuid:{0}]", - "zh_CN": "无法操作,操作被用户[uuid:{0}]黑名单拒绝", + "raw": "illegal url[%s], correct example is ssh://username:password@hostname[:sshPort]/path", + "en_US": "illegal url[{0}], correct example is ssh://username:password@hostname[:sshPort]/path", + "zh_CN": "非法URL[{0}],正确示例为SSH://username:password@hostname[:sshport]/path", "arguments": [ - "rbacEntity.getApiMessage().getSession().getUserUuid()" + "url" ], - "line": 60, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminAPIRequestChecker.java" + "line": 142, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" }, { - "raw": "action: %s, is not supported for role identity: %s", - "en_US": "action: {0}, is not supported for role identity: {1}", - "zh_CN": "", + "raw": "database backup[uuid:%s] is not Enabled and Ready", + "en_US": "database backup[uuid:{0}] is not Enabled and Ready", + "zh_CN": "数据库备份[uuid:{0}]未启用且未就绪", "arguments": [ - "unmatchedApis", - "identity.toString()" + "self.getUuid()" ], - "line": 199, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 80, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" }, { - "raw": "%s is a reserved name, please use another name", - "en_US": "{0} is a reserved name, please use another name", - "zh_CN": "", + "raw": "database backup[uuid:%s] not found in backup storage[uuid:%s]", + "en_US": "database backup[uuid:{0}] not found in backup storage[uuid:{1}]", + "zh_CN": "未在备份存储[uuid:{1}]中找到数据库备份[uuid:{0}]", "arguments": [ - "msg.getName()" + "msg.getDatabaseBackupUuid()", + "msg.getSrcBackupStorageUuid()" ], - "line": 341, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 328, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" }, { - "raw": "the name of initial user can not be updated", - "en_US": "the name of initial user can not be updated", - "zh_CN": "", - "arguments": [], - "line": 339, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "raw": "database backup [uuid:%s] is not existed yet", + "en_US": "database backup [uuid:{0}] is not existed yet", + "zh_CN": "数据库备份[uuid:{0}]尚不存在", + "arguments": [ + "msg.getDatabaseBackupUuid()" + ], + "line": 91, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" }, { - "raw": "cannot remove builtin system admin role from builtin system admin.", - "en_US": "cannot remove builtin system admin role from builtin system admin.", - "zh_CN": "", + "raw": "backup storage[uuid:%s] is not enabled and connected", + "en_US": "backup storage[uuid:{0}] is not enabled and connected", + "zh_CN": "备份存储[uuid:{0}]未启用和连接", "arguments": [], - "line": 376, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 107, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" }, { - "raw": "cannot remove builtin security admin role from builtin security admin.", - "en_US": "cannot remove builtin security admin role from builtin security admin.", - "zh_CN": "", - "arguments": [], - "line": 374, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "raw": "not pass the restore security check:\\n%s", + "en_US": "not pass the restore security check:\\n{0}", + "zh_CN": "未通过还原安全检查:\\n{0}", + "arguments": [ + "result.getStderr()" + ], + "line": 603, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" }, { - "raw": "cannot remove builtin audit admin role from builtin audit admin.", - "en_US": "cannot remove builtin audit admin role from builtin audit admin.", - "zh_CN": "", + "raw": "cannot get free port to listen", + "en_US": "cannot get free port to listen", + "zh_CN": "无法获取空闲端口以进行侦听", "arguments": [], - "line": 372, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 615, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" }, { - "raw": "cannot delete builtin system admin.", - "en_US": "cannot delete builtin system admin.", - "zh_CN": "", - "arguments": [], - "line": 386, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "raw": "database backup version[%s] is not match currently version[%s]", + "en_US": "database backup version[{0}] is not match currently version[{1}]", + "zh_CN": "数据库备份版本[{0}]与当前版本[{1}]不匹配", + "arguments": [ + "version", + "dbf.getDbVersion()" + ], + "line": 643, + "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" }, { - "raw": "cannot delete builtin security admin.", - "en_US": "cannot delete builtin security admin.", - "zh_CN": "", + "raw": "cannot ssh peer node via sshkey, please check connection", + "en_US": "cannot ssh peer node via sshkey, please check connection", + "zh_CN": "无法通过SSHKEY进行SSH对等节点,请检查连接", "arguments": [], - "line": 384, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 26, + "fileName": "src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java" }, { - "raw": "cannot delete builtin audit admin.", - "en_US": "cannot delete builtin audit admin.", - "zh_CN": "", + "raw": "please stop other node first!", + "en_US": "please stop other node first!", + "zh_CN": "请先停止其他节点!", "arguments": [], - "line": 382, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 19, + "fileName": "src/main/java/org/zstack/storage/backup/SingleDatabaseRecoverChecker.java" }, { - "raw": "Confirm the roles you want to add have same identity", - "en_US": "Confirm the roles you want to add have same identity", - "zh_CN": "", + "raw": "could not create vm, because at least one of field (l3NetworkUuids,zoneUuid,clusterUuid,hostUuid) should be set", + "en_US": "could not create vm, because at least one of field (l3NetworkUuids,zoneUuid,clusterUuid,hostUuid) should be set", + "zh_CN": "无法创建VM,因为至少应设置字段(l3NetworkUuids、zoneUuid、clusterUuid、hostUuid)中的一个", "arguments": [], - "line": 399, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 355, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "Cannot add role: %s with identity: %s to virtualID[uuid:%s]", - "en_US": "Cannot add role: {0} with identity: {1} to virtualID[uuid:{2}]", - "zh_CN": "", + "raw": "current backup storage state[%s] doesn\u0027t allow to proceed message[%s], allowed states are %s", + "en_US": "current backup storage state[{0}] doesn\u0027t allow to proceed message[{1}], allowed states are {2}", + "zh_CN": "当前镜像服务器状态[{0}]不能处理消息[{1}],仅当镜像服务器处于{2}时才能处理该消息", "arguments": [ - "msg.getRoleUuids()", - "identitySet", - "msg.getVirtualIDUuid()" + "currentState", + "msgName", + "checker.getStatesForOperation(msgName)" ], - "line": 413, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 91, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "can not add privilege admin[uuids:%s] to project[uuid:%s]", - "en_US": "can not add privilege admin[uuids:{0}] to project[uuid:{1}]", - "zh_CN": "无法将特殊管理员用户[uuids:{0}]加入到项目中去", + "raw": "Unexpected backup storage[type:%s,uuid:%s]", + "en_US": "Unexpected backup storage[type:{0},uuid:{1}]", + "zh_CN": "错误的镜像服务器[type:{0}, uuid:{1}]", "arguments": [ - "String.join(\",\", privilegeAdminUuids)", - "msg.getProjectUuid()" + "bsType", + "bsUuid" ], - "line": 425, - "fileName": "src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java" + "line": 231, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "condition name[%s] is invalid, no such field on inventory class[%s]", - "en_US": "condition name[{0}] is invalid, no such field on inventory class[{1}]", - "zh_CN": "条件名[{0}]非法,在清单类里面没有这个阈", + "raw": "Can not create volume backup for shareable volume[uuid:%s]", + "en_US": "Can not create volume backup for shareable volume[uuid:{0}]", + "zh_CN": "无法给共享云盘[uuid:{0}]创建云盘备份", "arguments": [ - "attr", - "inventoryClass.getName()" + "msg.getVolumeUuid()" ], - "line": 432, - "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" + "line": 252, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "condition name[%s] is invalid, field[%s] of inventory[%s] is annotated as @Unqueryable field", - "en_US": "condition name[{0}] is invalid, field[{1}] of inventory[{2}] is annotated as @Unqueryable field", - "zh_CN": "条件名[{0}]非法,清单[{2}]的值[{1}]不是被标记为@Unqueryable的值", + "raw": "Failed to create volume backup for volume[uuid:%s], because it is not attached to any vm", + "en_US": "Failed to create volume backup for volume[uuid:{0}], because it is not attached to any vm", + "zh_CN": "无法给云盘[uuid:{0}]创建云盘备份,因为它未加载到云主机上", "arguments": [ - "attr", - "attr", - "inventoryClass.getName()" + "msg.getVolumeUuid()" ], - "line": 437, - "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" + "line": 256, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "entity meta class[%s] has no field[%s]", - "en_US": "entity meta class[{0}] has no field[{1}]", - "zh_CN": "实体元类[{0}]中没有值[{1}]", + "raw": "Failed to create volume backup for volume[uuid:%s], because its attached volume is not in state[%s, %s]", + "en_US": "Failed to create volume backup for volume[uuid:{0}], because its attached volume is not in state[{1}, {2}]", + "zh_CN": "无法给云盘[uuid:{0}]创建云盘备份,因为加载到的云主机并不处于以下状态[{1}, {2}]", "arguments": [ - "info.jpaMetaClass.getName()", - "attr" + "msg.getVolumeUuid()", + "VmInstanceState.Running.toString()", + "VmInstanceState.Paused.toString()" ], - "line": 448, - "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" + "line": 265, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "field[%s] is not a primitive of the inventory %s; you cannot specify it in the parameter \u0027fields\u0027;valid fields are %s", - "en_US": "field[{0}] is not a primitive of the inventory {1}; you cannot specify it in the parameter \u0027fields\u0027;valid fields are {2}", - "zh_CN": "值[{0}]不是清单{1}的原语;你不能在参数\u0027域\u0027中指定该参数;非法的域{2}", + "raw": "Failed to create volume backup for volume[uuid:%s], because the vm is not in state[%s, %s]", + "en_US": "Failed to create volume backup for volume[uuid:{0}], because the vm is not in state[{1}, {2}]", + "zh_CN": "无法给云盘[uuid:{0}]创建云盘备份,因为加载到的云主机并不处于以下状态[{1}, {2}]", "arguments": [ - "f", - "info.inventoryClass.getSimpleName()", - "info.premitiveFieldNames" + "msg.getVolumeUuid()", + "VmInstanceState.Running.toString()", + "VmInstanceState.Paused.toString()" ], - "line": 1000, - "fileName": "src/main/java/org/zstack/query/MysqlQueryBuilderImpl3.java" + "line": 262, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "\u0027value\u0027 of query condition %s cannot be null", - "en_US": "\u0027value\u0027 of query condition {0} cannot be null", - "zh_CN": "查询条件中{0}的\u0027值\u0027不能为空", + "raw": "The resource[uuid: %s] has already created a cdp task, cannot create the backup job at the same time.", + "en_US": "The resource[uuid: {0}] has already created a cdp task, cannot create the backup job at the same time.", + "zh_CN": "资源[uuid:{0}]已创建CDP任务,无法同时创建备份作业。", "arguments": [ - "JSONObjectUtil.toJsonString(cond)" + "msg.getVolumeUuid()" ], - "line": 496, - "fileName": "src/main/java/org/zstack/query/QueryFacadeImpl.java" + "line": 292, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "cannot find resource[uuid: %s]", - "en_US": "cannot find resource[uuid: {0}]", - "zh_CN": "", + "raw": "Volume[uuid:%s] is not root volume", + "en_US": "Volume[uuid:{0}] is not root volume", + "zh_CN": "卷[uuid:{0}]不是根卷", "arguments": [ - "resourceUuid" + "msg.getVolumeUuid()" ], - "line": 326, - "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfig.java" + "line": 280, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "ResourceConfig [category:%s, name:%s] cannot bind to resourceType: %s", - "en_US": "ResourceConfig [category:{0}, name:{1}] cannot bind to resourceType: {2}", - "zh_CN": "", + "raw": "Failed to create backups for VM[uuid:%s], because it is not in state[%s, %s]", + "en_US": "Failed to create backups for VM[uuid:{0}], because it is not in state[{1}, {2}]", + "zh_CN": "无法为VM[uuid:{0}]创建备份,因为它未处于状态[{1},{2}]", "arguments": [ - "globalConfig.getCategory()", - "globalConfig.getName()", - "resourceType" + "t.get(0)", + "VmInstanceState.Running.toString()", + "VmInstanceState.Paused.toString()" ], - "line": 330, - "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfig.java" + "line": 287, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "account has no access to the resource[uuid: %s]", - "en_US": "account has no access to the resource[uuid: {0}]", - "zh_CN": "账号没有访问资源[uuid:{0}]的权限", + "raw": "No volume backup found for group uuid: %s", + "en_US": "No volume backup found for group uuid: {0}", + "zh_CN": "未找到组uuid为{0}的卷备份", "arguments": [ - "msg.getResourceUuid()" + "groupUuid" ], - "line": 60, - "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java" + "line": 305, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "no global config[category:%s, name:%s] found", - "en_US": "no global config[category:{0}, name:{1}] found", - "zh_CN": "", + "raw": "root volume backup of group[uuid:%s] not found", + "en_US": "root volume backup of group[uuid:{0}] not found", + "zh_CN": "未找到组[uuid:{0}]的根卷备份", "arguments": [ - "msg.getCategory()", - "msg.getName()" + "groupUuid" ], - "line": 43, - "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java" + "line": 311, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "global config[category:%s, name:%s] cannot bind resource", - "en_US": "global config[category:{0}, name:{1}] cannot bind resource", - "zh_CN": "", + "raw": "Current vm[uuid: %s] of the volume[uuid: %s] is no longer the vm[uuid: %s] that was used for backup", + "en_US": "Current vm[uuid: {0}] of the volume[uuid: {1}] is no longer the vm[uuid: {2}] that was used for backup", + "zh_CN": "卷[uuid:{1}]的当前云主机[uuid:{0}]不再是用于备份的云主机[UuId:{2}]", "arguments": [ - "msg.getCategory()", - "msg.getName()" + "expectVmUuid", + "rootVolumeInfo.get(0)", + "rootVolumeInfo.get(1)" ], - "line": 49, - "fileName": "src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java" + "line": 315, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "[%s] field is excepted an int or long, but was [%s].", - "en_US": "[{0}] field is excepted an int or long, but was [{1}].", - "zh_CN": "[{0}] 属性期望是一个整数,但是得到的是 [{1}]", - "arguments": [ - "f.getName()", - "source" - ], - "line": 22, - "fileName": "src/main/java/org/zstack/rest/TypeVerifier.java" + "raw": "cannot specify primary storage which attached different cluster.", + "en_US": "cannot specify primary storage which attached different cluster.", + "zh_CN": "无法指定连接到其他集群的主存储。", + "arguments": [], + "line": 348, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "Invalid value for boolean field [%s], [%s] is not a valid boolean string[true, false].", - "en_US": "Invalid value for boolean field [{0}], [{1}] is not a valid boolean string[true, false].", - "zh_CN": "boolean属性字段[{0}]无效,[{1}]不是一个有效的boolean字符串[true, false]", + "raw": "volume backup[uuid:%s] is in state %s, cannot revert volume to it", + "en_US": "volume backup[uuid:{0}] is in state {1}, cannot revert volume to it", + "zh_CN": "云盘备份[uuid:{0}]处于{1}状态,无法用于恢复云盘", "arguments": [ - "f.getName()", - "source" + "backupUuid", + "state" ], - "line": 31, - "fileName": "src/main/java/org/zstack/rest/TypeVerifier.java" + "line": 378, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "[%s] is not formatted as IPv4 address", - "en_US": "[{0}] is not formatted as IPv4 address", - "zh_CN": "", + "raw": "original volume for backup[uuid:%s] has been deleted, cannot revert volume to it", + "en_US": "original volume for backup[uuid:{0}] has been deleted, cannot revert volume to it", + "zh_CN": "云盘备份[uuid:{0}]已经被删除,无法用于恢复云盘", "arguments": [ - "msg.getAreaId()" + "backupUuid" ], - "line": 69, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "line": 388, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "KeyID \u0026 password must be not null when authentication type is %s", - "en_US": "KeyID \u0026 password must be not null when authentication type is {0}", - "zh_CN": "", + "raw": "original volume[uuid:%s] for backup[uuid:%s] is no longer attached to vm[uuid:%s]", + "en_US": "original volume[uuid:{0}] for backup[uuid:{1}] is no longer attached to vm[uuid:{2}]", + "zh_CN": "原始卷[uuid:{0}](用于备份[uuid:{1}])不再连接到云主机[uuid:{2}]", "arguments": [ - "msg.getAreaAuth()" + "volUuid", + "backupUuid", + "expectVmUuid" ], - "line": 108, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "line": 392, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "password must be not null when authentication type is %s", - "en_US": "password must be not null when authentication type is {0}", - "zh_CN": "", + "raw": "VM not found with volume backup[uuid:%s]", + "en_US": "VM not found with volume backup[uuid:{0}]", + "zh_CN": "找不到和云盘备份[uuid:{0}]对应的云主机", "arguments": [ - "msg.getAreaAuth()" + "backupUuid" ], - "line": 114, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "line": 402, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "the length of password is at most than 8Bytes when authentication type is %s", - "en_US": "the length of password is at most than 8Bytes when authentication type is {0}", - "zh_CN": "", + "raw": "VM is not in stopped state: %s", + "en_US": "VM is not in stopped state: {0}", + "zh_CN": "当前云主机状态并不是停止状态:{0}", "arguments": [ - "msg.getAreaAuth()" + "vmState" ], - "line": 118, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "line": 406, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "AreaId[%s] type must be %s", - "en_US": "AreaId[{0}] type must be {1}", - "zh_CN": "", - "arguments": [ - "vo.getAreaId()", - "RouterAreaType.Standard.toString()" - ], - "line": 127, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "raw": "No available backup storage found", + "en_US": "No available backup storage found", + "zh_CN": "没有可用的镜像服务器", + "arguments": [], + "line": 423, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "AreaId[%s] has been created", - "en_US": "AreaId[{0}] has been created", - "zh_CN": "", - "arguments": [ - "msg.getAreaId()" - ], - "line": 97, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "raw": "The vm is creating a backup job, cannot enable the cdp task at the same time.", + "en_US": "The vm is creating a backup job, cannot enable the cdp task at the same time.", + "zh_CN": "云主机正在创建备份作业,无法同时启用CDP任务。", + "arguments": [], + "line": 518, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" }, { - "raw": "The network[%s] have been added into the haGroup[%s]", - "en_US": "The network[{0}] have been added into the haGroup[{1}]", - "zh_CN": "", - "arguments": [ - "vo.getL3NetworkUuid()", - "haUuid" - ], - "line": 158, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "raw": "Operation not supported on shared volume", + "en_US": "Operation not supported on shared volume", + "zh_CN": "共享云盘不支持该操作", + "arguments": [], + "line": 191, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java" }, { - "raw": "The network[%s] have been added into the virtual routerArea[%s]", - "en_US": "The network[{0}] have been added into the virtual routerArea[{1}]", - "zh_CN": "", + "raw": "No VM found for volume[uuid:%s]", + "en_US": "No VM found for volume[uuid:{0}]", + "zh_CN": "找不到和云盘[uuid:{0}]对应的云主机", "arguments": [ - "vo.getL3NetworkUuid()", - "vo.getRouterAreaUuid()" + "volumeVO.getUuid()" ], - "line": 150, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "line": 196, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java" }, { - "raw": "Router ID[%s] is not formatted as IPv4 address", - "en_US": "Router ID[{0}] is not formatted as IPv4 address", - "zh_CN": "", + "raw": "No VM found with root volume uuid: %s", + "en_US": "No VM found with root volume uuid: {0}", + "zh_CN": "找不到根卷uuid为{0}的云主机", "arguments": [ - "msg.getRouterId()" + "msg.getRootVolumeUuid()" ], - "line": 181, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" + "line": 380, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java" }, { - "raw": "Router ID[%s] is not unique in this system", - "en_US": "Router ID[{0}] is not unique in this system", - "zh_CN": "", + "raw": "[%s] is not a standard cidr, do you mean [%s]?", + "en_US": "[{0}] is not a standard cidr, do you mean [{1}]?", + "zh_CN": "[{0}]不是一个标准的cidr, 是否指定的是[{1}]", "arguments": [ - "msg.getRouterId()" + "cidr", + "fmtCidr" ], - "line": 193, - "fileName": "src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java" - }, - { - "raw": "cron must be set when use cron scheduler", - "en_US": "cron must be set when use cron scheduler", - "zh_CN": "当使用定时器任务时,必须设置cron", - "arguments": [], - "line": 188, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 1974, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "cron task must follow format like this : \\\"0 0/3 17-23 * * ?\\\" ", - "en_US": "cron task must follow format like this : \\\"0 0/3 17-23 * * ?\\\" ", - "zh_CN": "定时器任务必须符合以下格式: \\\"0 0/3 17-23 * * ?\\\" ", - "arguments": [], - "line": 194, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "One of the backup storage[uuids: %s, %s] is in the state of %s, can not do sync operation", + "en_US": "One of the backup storage[uuids: {0}, {1}] is in the state of {2}, can not do sync operation", + "zh_CN": "镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作", + "arguments": [ + "msg.getDstBackupStorageUuid()", + "msg.getSrcBackupStorageUuid()", + "BackupStorageState.Disabled.toString()" + ], + "line": 1320, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "cron scheduler only need to specify cron task", - "en_US": "cron scheduler only need to specify cron task", - "zh_CN": "定时调度器(Cron Scheduler)仅需要指定定时任务(Cron Task)", + "raw": "sync task failed.", + "en_US": "sync task failed.", + "zh_CN": "同步失败", "arguments": [], - "line": 197, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 992, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "startTime out of range", - "en_US": "startTime out of range", - "zh_CN": "开始时间超出范围", - "arguments": [], - "line": 206, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "unexpected task status: %s", + "en_US": "unexpected task status: {0}", + "zh_CN": "错误的任务状态{0}", + "arguments": [ + "reply.getStatus()" + ], + "line": 999, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "startTime must be positive integer or 0", - "en_US": "startTime must be positive integer or 0", - "zh_CN": "开始时间必须是正整数或者0", - "arguments": [], - "line": 202, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "failed to create image from backup %s", + "en_US": "failed to create image from backup {0}", + "zh_CN": "无法从备份{0}创建镜像", + "arguments": [ + "vos.stream().filter( vo -\u003e !succeedUuids.contains(vo.getUuid())).map(VolumeBackupVO::getUuid).collect(Collectors.toList())" + ], + "line": 293, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "stopTime has been passed", - "en_US": "stopTime has been passed", - "zh_CN": "截止时间已经过去了", - "arguments": [], - "line": 183, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "sync volume backup metadata file in image store[uuid:%s] meet I/O error: %s", + "en_US": "sync volume backup metadata file in image store[uuid:{0}] meet I/O error: {1}", + "zh_CN": "同步卷备份元数据文件(位于镜像存储[uuid:{0}]中)遇到I/O错误:{1}", + "arguments": [ + "msg.getImageStoreUuid()", + "e.getMessage()" + ], + "line": 498, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "stopTime out of mysql timestamp range", - "en_US": "stopTime out of mysql timestamp range", - "zh_CN": "定时任务停止时间超出mysql的timestamp的范围", - "arguments": [], - "line": 181, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "Current vm[uuid: %s] of the backup volume is no longer the vm[uuid: %s] that was used for backup", + "en_US": "Current vm[uuid: {0}] of the backup volume is no longer the vm[uuid: {1}] that was used for backup", + "zh_CN": "备份卷的当前云主机[uuid:{0}]不再是用于备份的云主机[uuid:{1}]", + "arguments": [ + "volumeVmUuid", + "backupUuid", + "backupVmUuid" + ], + "line": 535, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "duration time out of range", - "en_US": "duration time out of range", - "zh_CN": "任务需要的时间超出范围", - "arguments": [], - "line": 179, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "No VolumeBackupFactory of type[%s] found", + "en_US": "No VolumeBackupFactory of type[{0}] found", + "zh_CN": "未找到类型为[{0}]的VolumeBackupFactory", + "arguments": [ + "hypervisorType" + ], + "line": 544, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "interval must be set when use simple scheduler when repeat more than once", - "en_US": "interval must be set when use simple scheduler when repeat more than once", - "zh_CN": "当简单定时任务执行超过一次时,必须设置间隔时间", - "arguments": [], - "line": 98, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "One of the backup storage[uuid: %s] is in the state of %s, can not do sync operation", + "en_US": "One of the backup storage[uuid: {0}] is in the state of {1}, can not do sync operation", + "zh_CN": "镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作", + "arguments": [ + "msg.getBackupStorageUuid()", + "BackupStorageState.Disabled.toString()" + ], + "line": 561, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "Can not add job[uuid:%s] twice to the same trigger[uuid:%s]", - "en_US": "Can not add job[uuid:{0}] twice to the same trigger[uuid:{1}]", - "zh_CN": "不能两次添加任务[uuid:{0}]到相同的触发器[uuid:{1}]", + "raw": "Volume backup[uuid:%s] not found on backup storage[uuid:%s]", + "en_US": "Volume backup[uuid:{0}] not found on backup storage[uuid:{1}]", + "zh_CN": "在镜像服务器[uuid:{1}]上找不到云盘备份[uuid:{0}]", "arguments": [ - "msg.getSchedulerJobUuid()", - "msg.getSchedulerTriggerUuid()" + "struct.getBackupUuid()", + "struct.getBackupStorageUuid()" ], - "line": 133, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 738, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "Can not add job[uuid:%s] to a out of time trigger[uuid:%s]", - "en_US": "Can not add job[uuid:{0}] to a out of time trigger[uuid:{1}]", - "zh_CN": "不能添加任务[uuid:{0}]到一个已经过时的触发器[uuid:{1}]", + "raw": "volume backup[uuid:%s] not found in backup storage[uuid:%s]", + "en_US": "volume backup[uuid:{0}] not found in backup storage[uuid:{1}]", + "zh_CN": "在镜像服务器[uuid:{1}]上找不到云盘备份[uuid:{0}]", "arguments": [ - "msg.getSchedulerJobUuid()", - "msg.getSchedulerTriggerUuid()" + "backupUuid", + "srcBackupStorageUuid" ], - "line": 138, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 1187, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "There are [%d] triggers added to job[uuid:%s], cannot add any more.", - "en_US": "There are [{0}] triggers added to job[uuid:{1}], cannot add any more.", - "zh_CN": "", + "raw": "No volume backups found with group uuid: %s", + "en_US": "No volume backups found with group uuid: {0}", + "zh_CN": "未找到组uuid为{0}的卷备份", "arguments": [ - "count", - "msg.getSchedulerJobUuid()" + "groupUuid" ], - "line": 146, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 1399, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "There are [%d] triggers added to job group[uuid:%s], cannot add any more.", - "en_US": "There are [{0}] triggers added to job group[uuid:{1}], cannot add any more.", - "zh_CN": "", + "raw": "Root volume missing within group uuid: %s", + "en_US": "Root volume missing within group uuid: {0}", + "zh_CN": "组uuid中缺少根卷:{0}", "arguments": [ - "count", - "msg.getSchedulerJobGroupUuid()" + "groupUuid" ], - "line": 161, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 1406, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "invalid cron expression", - "en_US": "invalid cron expression", - "zh_CN": "无效的cron表达式", - "arguments": [], - "line": 191, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "Multiple root volumes found within group uuid: %s", + "en_US": "Multiple root volumes found within group uuid: {0}", + "zh_CN": "在组uuid中找到多个根卷:{0}", + "arguments": [ + "groupUuid" + ], + "line": 1412, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "startTime must be set for simple scheduler", - "en_US": "startTime must be set for simple scheduler", - "zh_CN": "simple类型的定时任务必须设置开始时间[startTime]", - "arguments": [], - "line": 171, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "No permission to volume backups within group uuid: %s", + "en_US": "No permission to volume backups within group uuid: {0}", + "zh_CN": "对组uuid{0}中的卷备份没有权限", + "arguments": [ + "groupUuid" + ], + "line": 1424, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "schedulerInterval must be set for simple scheduler", - "en_US": "schedulerInterval must be set for simple scheduler", - "zh_CN": "simple类型的定时任务必须设置执行间隔[schedulerInterval]", - "arguments": [], - "line": 175, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "raw": "Volume backup[uuid:%s] not found on any backup storage", + "en_US": "Volume backup[uuid:{0}] not found on any backup storage", + "zh_CN": "未在任何备份存储上找到卷备份[uuid:{0}]", + "arguments": [ + "vo.getUuid()" + ], + "line": 1564, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "snapshotMaxNumber : %s format error because %s", - "en_US": "snapshotMaxNumber : {0} format error because {1}", - "zh_CN": "snapshotMaxNumber : {0} 转换类型失败,因为{1}", + "raw": "degree [%s] should be a positive number", + "en_US": "degree [{0}] should be a positive number", + "zh_CN": "度[{0}]应为正数", "arguments": [ - "msg.getParameters().get(SchedulerJobParameters.snapshotMax)", - "e.getMessage()" + "degree" ], - "line": 239, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 2001, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "%d jobs have different job type with job group", - "en_US": "{0} jobs have different job type with job group", - "zh_CN": "", + "raw": "invalid type[%s], should be [nfs, sshfs, nbd]", + "en_US": "invalid type[{0}], should be [nfs, sshfs, nbd]", + "zh_CN": "类型[{0}]无效,应为[NFS,sshfs,NBD]", "arguments": [ - "n" + "type" ], - "line": 265, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 2035, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "job group has contained %d job, only %d seats left", - "en_US": "job group has contained {0} job, only {1} seats left", - "zh_CN": "", + "raw": "invalid url[%s], should be hostname:/path", + "en_US": "invalid url[{0}], should be hostname:/path", + "zh_CN": "URL[{0}]无效,应为hostname:/path", "arguments": [ - "count", - "limit - count" + "url" ], - "line": 274, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java" + "line": 2045, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" }, { - "raw": "trigger job[uuid: %s] failed, because %s", - "en_US": "trigger job[uuid: {0}] failed, because {1}", - "zh_CN": "", + "raw": "generate volume backup metadata file on image store[uuid:%s] failure, because IO error: %s", + "en_US": "generate volume backup metadata file on image store[uuid:{0}] failure, because IO error: {1}", + "zh_CN": "在镜像存储[uuid:{0}]上生成卷备份元数据文件失败,因为IO错误:{1}", "arguments": [ - "jobUuid", + "inv.getUuid()", "e.getMessage()" ], - "line": 500, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java" + "line": 177, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java" }, { - "raw": "Scheduler job[uuid:%s] already in group[uuid: %s]", - "en_US": "Scheduler job[uuid:{0}] already in group[uuid: {1}]", - "zh_CN": "", + "raw": "volume backup metadata operation failure, because %s", + "en_US": "volume backup metadata operation failure, because {0}", + "zh_CN": "卷备份元数据操作失败,原因是{0}", "arguments": [ - "jobUuid", - "jobGroupUuid" + "rsp.getError()" ], - "line": 613, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java" + "line": 505, + "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java" }, { - "raw": "field[%s] cannot be empty", - "en_US": "field[{0}] cannot be empty", - "zh_CN": "", + "raw": "failed to download image[url: %s] on backup storage[uuid: %s], because: %s", + "en_US": "failed to download image[url: {0}] on backup storage[uuid: {1}], because: {2}", + "zh_CN": "无法下载镜像[URL:{0}](在备份存储[uuid:{1}]上),原因是:{2}", "arguments": [ - "field.getName()" + "cmd.imgurl", + "cmd.uuid", + "ret.getError()" ], - "line": 86, - "fileName": "src/main/java/org/zstack/scheduler/SchedulerJobParamCascadeUpdater.java" + "line": 586, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "vm[uuid:%s] is destroyed, state change is not allowed", - "en_US": "vm[uuid:{0}] is destroyed, state change is not allowed", - "zh_CN": "", + "raw": "unable to connect to SimpleHttpBackupStorage[url:%s], because %s", + "en_US": "unable to connect to SimpleHttpBackupStorage[url:{0}], because {1}", + "zh_CN": "无法连接到SimpleHttpBackupStorage[url:{0}],因为{1}", "arguments": [ - "getTargetResourceUuid()" + "url", + "rsp.getError()" ], - "line": 78, - "fileName": "src/main/java/org/zstack/scheduler/vm/StopVmInstanceJob.java" + "line": 277, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "Sdn controller type: %s in not in the supported list: %s ", - "en_US": "Sdn controller type: {0} in not in the supported list: {1} ", - "zh_CN": "", + "raw": "Missing cert file for downloading image: %s", + "en_US": "Missing cert file for downloading image: {0}", + "zh_CN": "下载镜像时证书文件丢失", "arguments": [ - "msg.getVendorType()", - "SdnControllerType.getAllTypeNames()" + "iinv.getName()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java" + "line": 507, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "H3C VCFC controller must include systemTags vdsUuid::{%s}", - "en_US": "H3C VCFC controller must include systemTags vdsUuid::{{0}}", - "zh_CN": "", + "raw": "No response", + "en_US": "No response", + "zh_CN": "无响应", "arguments": [], - "line": 97, - "fileName": "src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java" + "line": 831, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "get sdn controller [ip:%s] vni range failed because %s", - "en_US": "get sdn controller [ip:{0}] vni range failed because {1}", - "zh_CN": "", + "raw": "reclaim imagestore error, because:%s", + "en_US": "reclaim imagestore error, because:{0}", + "zh_CN": "收回imagestore错误,因为{0}", "arguments": [ - "self.getIp()", - "e.getLocalizedMessage()" + "ret.getError()" ], - "line": 117, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 907, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "get vni range on sdn controller [ip:%s] failed", - "en_US": "get vni range on sdn controller [ip:{0}] failed", - "zh_CN": "", + "raw": "failed to set max capacity on image store[uuid:%s], because: %s", + "en_US": "failed to set max capacity on image store[uuid:{0}], because: {1}", + "zh_CN": "无法设置镜像存储[uuid:{0}]的最大容量,因为:{1}", "arguments": [ - "self.getIp()" + "self.getUuid()", + "ret.getError()" ], - "line": 87, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 994, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "there is no vni range on sdn controller [ip:%s]", - "en_US": "there is no vni range on sdn controller [ip:{0}]", - "zh_CN": "", + "raw": "image[%s] not found on backup storage[%s]", + "en_US": "image[{0}] not found on backup storage[{1}]", + "zh_CN": "在备份存储[{1}]上找不到镜像[{0}]", "arguments": [ - "self.getIp()" + "msg.getImageUuid()", + "self.getUuid()" ], - "line": 149, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 1223, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "there is no default tenant on sdn controller [ip:%s]", - "en_US": "there is no default tenant on sdn controller [ip:{0}]", - "zh_CN": "", + "raw": "failed to delete image package, because: %s", + "en_US": "failed to delete image package, because: {0}", + "zh_CN": "无法删除镜像包,因为:{0}", "arguments": [ - "self.getIp()" + "ret.getError()" ], - "line": 155, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 1134, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "create vxlan network on sdn controller [ip:%s] failed because %s", - "en_US": "create vxlan network on sdn controller [ip:{0}] failed because {1}", - "zh_CN": "", + "raw": "some images [%s] are not exported on the backup storage[uuid: %s]", + "en_US": "some images [{0}] are not exported on the backup storage[uuid: {1}]", + "zh_CN": "某些镜像[{0}]未在备份存储[uuid:{1}]上导出", "arguments": [ - "self.getIp()", - "e.getMessage()" + "StringUtils.join(notOnBsImageUuids, \u0027,\u0027)", + "msg.getBackupStorageUuid()" ], - "line": 275, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 1158, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "create vxlan network on sdn controller [ip:%s] failed", - "en_US": "create vxlan network on sdn controller [ip:{0}] failed", - "zh_CN": "", + "raw": "failed to package exported images, because %s", + "en_US": "failed to package exported images, because {0}", + "zh_CN": "无法打包导出的镜像,因为{0}", "arguments": [ - "self.getIp()" + "ret.getError()" ], - "line": 259, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 1192, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "delete vxlan network on sdn controller [ip:%s] failed because %s", - "en_US": "delete vxlan network on sdn controller [ip:{0}] failed because {1}", - "zh_CN": "", + "raw": "the backup storage[uuid:%s] has not enough capacity[%s] to export", + "en_US": "the backup storage[uuid:{0}] has not enough capacity[{1}] to export", + "zh_CN": "备份存储[uuid:{0}]没有足够的容量[{1}]用于导出", "arguments": [ - "self.getIp()", - "e.getMessage()" + "self.getUuid()", + "actualSize" ], - "line": 321, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 1234, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "delete vxlan network on sdn controller [ip:%s] failed", - "en_US": "delete vxlan network on sdn controller [ip:{0}] failed", - "zh_CN": "", - "arguments": [ - "self.getIp()" - ], - "line": 315, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "raw": "image store [%s] cannot add image, because it is used for backup remote", + "en_US": "image store [{0}] cannot add image, because it is used for backup remote", + "zh_CN": "ImageStore[{0}]不能添加镜像,因为它已经被远程镜像使用", + "arguments": [], + "line": 1393, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "get token of sdn controller [ip:%s] failed because %s", - "en_US": "get token of sdn controller [ip:{0}] failed because {1}", - "zh_CN": "", + "raw": "commercial license is required to use ImageStore", + "en_US": "commercial license is required to use ImageStore", + "zh_CN": "使用ImageStore需要商业许可证", + "arguments": [], + "line": 1591, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + }, + { + "raw": "the uuid of imagestoreBackupStorage agent changed[expected:%s, actual:%s], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", + "en_US": "the uuid of imagestoreBackupStorage agent changed[expected:{0}, actual:{1}], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", + "zh_CN": "镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态", "arguments": [ - "self.getIp()", - "e.getMessage()" + "self.getUuid()", + "resp.getUuid()" ], - "line": 381, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 1712, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" }, { - "raw": "get leader of sdn controller [ip:%s] failed", - "en_US": "get leader of sdn controller [ip:{0}] failed", - "zh_CN": "", + "raw": "hostname[%s] is neither an IPv4 address nor a valid hostname", + "en_US": "hostname[{0}] is neither an IPv4 address nor a valid hostname", + "zh_CN": "物理机名[{0}]不是一个IPv4的地址,而是一个非法的物理机名", "arguments": [ - "self.getIp()" + "msg.getHostname()" ], - "line": 352, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 125, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "get token of sdn controller [ip:%s] failed", - "en_US": "get token of sdn controller [ip:{0}] failed", - "zh_CN": "", + "raw": "target backup storage[uuid:%s] already contains the image [uuid:%s]", + "en_US": "target backup storage[uuid:{0}] already contains the image [uuid:{1}]", + "zh_CN": "目标备份存储[uuid:{0}]已包含镜像[uuid:{1}]", "arguments": [ - "self.getIp()" + "bsUuid", + "imageUuid" ], - "line": 373, - "fileName": "src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java" + "line": 60, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "there is no sdn controller for vxlan pool [uuid:%s]", - "en_US": "there is no sdn controller for vxlan pool [uuid:{0}]", - "zh_CN": "", + "raw": "source backup storage[%s] doesn\u0027t contain image[%s]", + "en_US": "source backup storage[{0}] doesn\u0027t contain image[{1}]", + "zh_CN": "源镜像服务器[{0}]不包含该镜像[{1}]", "arguments": [ - "vo.getPoolUuid()" + "msg.getSrcBackupStorageUuid()", + "msg.getUuid()" ], - "line": 72, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java" + "line": 79, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "cannot configure hardware vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", - "en_US": "cannot configure hardware vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}]", - "zh_CN": "", + "raw": "src backupstorage[%s] doesn\u0027t contain image[%s]", + "en_US": "src backupstorage[{0}] doesn\u0027t contain image[{1}]", + "zh_CN": "SRC BackupStorage[{0}]不包含镜像[{1}]", "arguments": [ - "inv.getUuid()", - "destHostUuid" + "msg.getSrcBackupStorageUuid()", + "msg.getUuid()" ], - "line": 259, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java" + "line": 94, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "overlap vni range with vxlan network pool [%s]", - "en_US": "overlap vni range with vxlan network pool [{0}]", - "zh_CN": "", + "raw": "duplicate backup storage. There has been an image store backup storage[hostname:%s]", + "en_US": "duplicate backup storage. There has been an image store backup storage[hostname:{0}]", + "zh_CN": "重复的镜像服务器。已经存在一个镜像服务器[物理机名: {0}]", "arguments": [ - "overlappedPool" + "msg.getHostname()" ], - "line": 103, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + "line": 142, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "hareware vxlan network pool doesn\u0027t support create l3 network", - "en_US": "hareware vxlan network pool doesn\u0027t support create l3 network", - "zh_CN": "", + "raw": "file path needed", + "en_US": "file path needed", + "zh_CN": "需要文件路径", "arguments": [], - "line": 110, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + "line": 147, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "hareware vxlan network pool must configure the physical interface", - "en_US": "hareware vxlan network pool must configure the physical interface", - "zh_CN": "", - "arguments": [], - "line": 116, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + "raw": "absolute file path required: %s", + "en_US": "absolute file path required: {0}", + "zh_CN": "需要文件的绝对路径;{0}", + "arguments": [ + "dir" + ], + "line": 151, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "ONLY hareware vxlan network can be created in hareware vxlan pool", - "en_US": "ONLY hareware vxlan network can be created in hareware vxlan pool", - "zh_CN": "", + "raw": "the url contains an invalid folder[/dev or /proc or /sys]", + "en_US": "the url contains an invalid folder[/dev or /proc or /sys]", + "zh_CN": "URL包含了一个无效的目录[/dev or /proc or /sys]", "arguments": [], - "line": 124, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + "line": 154, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "hareware vxlan network can ONLY be created in hareware vxlan pool", - "en_US": "hareware vxlan network can ONLY be created in hareware vxlan pool", - "zh_CN": "", - "arguments": [], - "line": 129, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java" + "raw": "file path contains invalid character: %s", + "en_US": "file path contains invalid character: {0}", + "zh_CN": "文件路径包含非法字符: {0}", + "arguments": [ + "dir" + ], + "line": 162, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" }, { - "raw": "failed to create bridge[%s] for hardwareVxlan[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", - "en_US": "failed to create bridge[{0}] for hardwareVxlan[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5}", - "zh_CN": "", + "raw": "cannot find a connected host in cluster to which PS [uuid: %s] attached", + "en_US": "cannot find a connected host in cluster to which PS [uuid: {0}] attached", + "zh_CN": "在PS[uuid:{0}]连接到的集群中找不到已连接的物理机", "arguments": [ - "cmd.getBridgeName()", - "l2Network.getUuid()", - "l2Network.getType()", - "vlanId", - "hostUuid", - "rsp.getError()" + "ps.getUuid()" ], - "line": 75, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java" + "line": 193, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageExtension.java" }, { - "raw": "failed to check bridge[%s] for hardwareVxlan[uuid:%s, name:%s] on kvm host[uuid:%s], %s", - "en_US": "failed to check bridge[{0}] for hardwareVxlan[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4}", - "zh_CN": "", + "raw": "invalid url[%s], the url must be an absolute path starting with \u0027/\u0027", + "en_US": "invalid url[{0}], the url must be an absolute path starting with \u0027/\u0027", + "zh_CN": "无效的url[{0}],url必须是以\u0027/\u0027开头的绝对路径", "arguments": [ - "cmd.getBridgeName()", - "vxlan.getUuid()", - "vxlan.getName()", - "hostUuid", - "rsp.getError()" + "amsg.getUrl()" ], - "line": 129, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java" + "line": 108, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" }, { - "raw": "failed to check physical interface for HardwareVxlanPool[uuid:%s, name:%s] on kvm host[uuid: %s], %s", - "en_US": "failed to check physical interface for HardwareVxlanPool[uuid:{0}, name:{1}] on kvm host[uuid: {2}], {3}", - "zh_CN": "", + "raw": "existing SimpleHttpBackupStorage with hostname[%s] found", + "en_US": "existing SimpleHttpBackupStorage with hostname[{0}] found", + "zh_CN": "存在物理机名为[{0}]的简单http镜像服务器", "arguments": [ - "l2Network.getUuid()", - "l2Network.getName()", - "hostUuid", - "rsp.getError()" + "hostname" ], - "line": 61, - "fileName": "src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java" + "line": 117, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" }, { - "raw": "set to disconnected", - "en_US": "set to disconnected", - "zh_CN": "", + "raw": "sync status failed.", + "en_US": "sync status failed.", + "zh_CN": "同步失败", "arguments": [], - "line": 92, - "fileName": "src/main/java/org/zstack/simulator/SimulatorHost.java" + "line": 228, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java" }, { - "raw": "can not add same email address to endpoint[uuid:%s]", - "en_US": "can not add same email address to endpoint[uuid:{0}]", - "zh_CN": "", - "arguments": [ - "msg.getApplicationEndpointUuid()" - ], - "line": 60, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "raw": "failed to get task reply!", + "en_US": "failed to get task reply!", + "zh_CN": "获取任务回复失败!", + "arguments": [], + "line": 343, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java" }, { - "raw": "invalid email address[%s]", - "en_US": "invalid email address[{0}]", - "zh_CN": "无效的email地址[{0}]", + "raw": "delete image metadata file failed: %s", + "en_US": "delete image metadata file failed: {0}", + "zh_CN": "删除镜像元数据文件失败: {0}", "arguments": [ - "errorEmails" + "rsp.getError()" ], - "line": 171, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "line": 841, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" }, { - "raw": "cannot update email address to %s, which is already exists in endpoint[uuid:%s]", - "en_US": "cannot update email address to {0}, which is already exists in endpoint[uuid:{1}]", - "zh_CN": "", + "raw": "AddImage is forbidden in Disaster BS: [%s]", + "en_US": "AddImage is forbidden in Disaster BS: [{0}]", + "zh_CN": "在Disaster镜像服务器中添加镜像是被禁止的", "arguments": [ - "msg.getEmailAddress()", - "msg.getApplicationEndpointUuid()" + "bsUuid" ], - "line": 73, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "line": 397, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" }, { - "raw": "phone number [%s] already exists", - "en_US": "phone number [{0}] already exists", - "zh_CN": "", + "raw": "Check image metadata file: %s failed", + "en_US": "Check image metadata file: {0} failed", + "zh_CN": "检查镜像元数据文件: {0}失败", "arguments": [ - "msg.getPhoneNumber()" + "rsp.getBackupStorageMetaFileName()" ], - "line": 87, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" - }, - { - "raw": "password is not set while username is set", - "en_US": "password is not set while username is set", - "zh_CN": "设置了用户名但未设置密码", - "arguments": [], - "line": 99, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" - }, - { - "raw": "username is not set while password is set", - "en_US": "username is not set while password is set", - "zh_CN": "设置了密码但未设置用户名", - "arguments": [], - "line": 103, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "line": 770, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" }, { - "raw": "phone number[%s] already exists", - "en_US": "phone number[{0}] already exists", - "zh_CN": "手机号码[{0}]已存在", + "raw": "Create image metadata file : %s failed", + "en_US": "Create image metadata file : {0} failed", + "zh_CN": "创建镜像元数据文件: {0}失败", "arguments": [ - "msg.getPhoneNumber()" + "rsp.getBackupStorageMetaFileName()" ], - "line": 112, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "line": 594, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" }, { - "raw": "invalid url[%s]", - "en_US": "invalid url[{0}]", - "zh_CN": "无效的url[{0}]", + "raw": "Create image metadata file sync : %s failed", + "en_US": "Create image metadata file sync : {0} failed", + "zh_CN": "同步创建镜像元数据文件{0}失败了", "arguments": [ - "url" + "rsp.getBackupStorageMetaFileName()" ], - "line": 121, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "line": 569, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" }, { - "raw": "[%s] is not a legal ip", - "en_US": "[{0}] is not a legal ip", - "zh_CN": "", + "raw": "parse create time error: %s", + "en_US": "parse create time error: {0}", + "zh_CN": "解析创建时间出错: {0}", "arguments": [ - "host" + "e.getMessage()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "line": 80, + "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreImageStruct.java" }, { - "raw": "invalid phone number[%s], the DingDing phone number is like +86-12388889999", - "en_US": "invalid phone number[{0}], the DingDing phone number is like +86-12388889999", - "zh_CN": "无效的手机号码[{0}], 钉钉手机号码格式应当为 +86-12388889999", + "raw": "SftpBackupStorage doesn\u0027t support scheme[%s] in url[%s]", + "en_US": "SftpBackupStorage doesn\u0027t support scheme[{0}] in url[{1}]", + "zh_CN": "Sftp镜像服务器不支持在url[{1}]里包含scheme[{0}]", "arguments": [ - "n" - ], - "line": 133, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" - }, - { - "raw": "username and password must either absent at all or present with each other", - "en_US": "username and password must either absent at all or present with each other", - "zh_CN": "用户名和密码要么同时为空要么同时不为空", - "arguments": [], - "line": 150, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "scheme", + "url" + ], + "line": 111, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" }, { - "raw": "can not create sns email endpoint without any email address", - "en_US": "can not create sns email endpoint without any email address", - "zh_CN": "", - "arguments": [], - "line": 158, - "fileName": "src/main/java/org/zstack/sns/SNSApiInterceptor.java" + "raw": "fail to cancel download image, because %s", + "en_US": "fail to cancel download image, because {0}", + "zh_CN": "无法取消下载镜像,因为{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 242, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" }, { - "raw": "the operation is not permitted for the system application platform", - "en_US": "the operation is not permitted for the system application platform", - "zh_CN": "禁止对该应用平台进行当前操作", - "arguments": [], - "line": 118, - "fileName": "src/main/java/org/zstack/sns/SNSApplicationPlatformBase.java" + "raw": "the uuid of sftpBackupStorage agent changed[expected:%s, actual:%s], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", + "en_US": "the uuid of sftpBackupStorage agent changed[expected:{0}, actual:{1}], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", + "zh_CN": "Sftp镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态", + "arguments": [ + "self.getUuid()", + "ret.getUuid()" + ], + "line": 316, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" }, { - "raw": "cannot find the SNSTopic[uuid:%s], it may have been deleted", - "en_US": "cannot find the SNSTopic[uuid:{0}], it may have been deleted", - "zh_CN": "找不到SNS主题[uuid:{0}], 它可能已经被删除", + "raw": "Please stop the vm before create volume template to sftp backup storage %s", + "en_US": "Please stop the vm before create volume template to sftp backup storage {0}", + "zh_CN": "请在创建SFTP备份存储{0}的卷模板之前停止云主机", "arguments": [ - "msg.getTopicUuid()" + "bsUuid" ], - "line": 75, - "fileName": "src/main/java/org/zstack/sns/SNSManagerImpl.java" + "line": 70, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java" }, { - "raw": "cannot find SNSApplicationPlatform[uuid:%s], it may have been deleted", - "en_US": "cannot find SNSApplicationPlatform[uuid:{0}], it may have been deleted", - "zh_CN": "找不到SNS应用平台[uuid:{0}], 它可能已经被删除", + "raw": "duplicate backup storage. There has been a sftp backup storage[hostname:%s] existing", + "en_US": "duplicate backup storage. There has been a sftp backup storage[hostname:{0}] existing", + "zh_CN": "重复的镜像服务器。已经存在一个镜像服务器[物理机名: {0}]", "arguments": [ - "msg.getApplicationPlatformUuid()" + "msg.getHostname()" ], - "line": 93, - "fileName": "src/main/java/org/zstack/sns/SNSManagerImpl.java" + "line": 106, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java" }, { - "raw": "cannot find SNSApplicationEndpoint[uuid:%s], it may have been deleted", - "en_US": "cannot find SNSApplicationEndpoint[uuid:{0}], it may have been deleted", - "zh_CN": "找不到SNS应用接收终端[uuid:{0}], 它可能已经被删除", + "raw": "check image metadata file: %s failed", + "en_US": "check image metadata file: {0} failed", + "zh_CN": "检查镜像元数据文件: {0}失败", "arguments": [ - "msg.getApplicationEndpointUuid()" + "rsp.getBackupStorageMetaFileName()" ], - "line": 103, - "fileName": "src/main/java/org/zstack/sns/SNSManagerImpl.java" + "line": 554, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java" }, { - "raw": "the topic is not subscribed by any endpoints", - "en_US": "the topic is not subscribed by any endpoints", - "zh_CN": "当前主题并未被任何应用终端订阅", - "arguments": [], - "line": 125, - "fileName": "src/main/java/org/zstack/sns/SNSTopicBase.java" + "raw": "create image metadata file : %s failed", + "en_US": "create image metadata file : {0} failed", + "zh_CN": "创建镜像元数据文件: {0}失败", + "arguments": [ + "rsp.getBackupStorageMetaFileName()" + ], + "line": 399, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java" }, { - "raw": "application platform is disabled", - "en_US": "application platform is disabled", - "zh_CN": "应用平台被不可用", - "arguments": [], - "line": 149, - "fileName": "src/main/java/org/zstack/sns/SNSTopicBase.java" + "raw": "image metadata file: %s is not exist", + "en_US": "image metadata file: {0} is not exist", + "zh_CN": "镜像元数据文件: {0}不存在", + "arguments": [ + "rsp.getBackupStorageMetaFileName()" + ], + "line": 559, + "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java" }, { - "raw": "application endpoint is disabled", - "en_US": "application endpoint is disabled", - "zh_CN": "应用接收端被禁用", - "arguments": [], - "line": 201, - "fileName": "src/main/java/org/zstack/sns/SNSTopicBase.java" + "raw": "host not found for VM: %s", + "en_US": "host not found for VM: {0}", + "zh_CN": "找不到VM的物理机:{0}", + "arguments": [ + "vmUuid" + ], + "line": 321, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java" }, { - "raw": "invalid phone number[%s], sms number is like +86-18654321234", - "en_US": "invalid phone number[{0}], sms number is like +86-18654321234", - "zh_CN": "", + "raw": "query-mirror: host not found for VM[uuid:%s]", + "en_US": "query-mirror: host not found for VM[uuid:{0}]", + "zh_CN": "查询镜像:找不到VM[uuid:{0}]的物理机", "arguments": [ - "number" + "vmUuid" ], - "line": 34, - "fileName": "src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java" + "line": 241, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java" }, { - "raw": "Aliyun account[uuid:%s] not exists", - "en_US": "Aliyun account[uuid:{0}] not exists", - "zh_CN": "", + "raw": "libvirt on the host[uuid: %s] not support to create cdp task, please check the version of libvirt.", + "en_US": "libvirt on the host[uuid: {0}] not support to create cdp task, please check the version of libvirt.", + "zh_CN": "物理机[uuid:{0}]上的libvirt不支持创建CDP任务,请检查libvirt的版本。", "arguments": [ - "msg.getAccessKeyUuid()" + "hostUuid" ], - "line": 43, - "fileName": "src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java" + "line": 328, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java" }, { - "raw": "Aliyun sms event text template not found.", - "en_US": "Aliyun sms event text template not found.", - "zh_CN": "", + "raw": "qemu on the host[uuid: %s] not support to create cdp task, please check the version of qemu.", + "en_US": "qemu on the host[uuid: {0}] not support to create cdp task, please check the version of qemu.", + "zh_CN": "物理机[uuid:{0}]上的QEMU不支持创建CDP任务,请检查QEMU的版本。", "arguments": [ - "SysErrors.RESOURCE_NOT_FOUND" + "hostUuid" ], - "line": 83, - "fileName": "src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsEndpoint.java" + "line": 334, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java" }, { - "raw": "Sending message to DingTalk failure. status: %s, body: %s", - "en_US": "Sending message to DingTalk failure. status: {0}, body: {1}", - "zh_CN": "发送消息到DingTalk失败. status: {0}, body: {1}", + "raw": "The QEMU version running on the VM[uuid:%s] does not support mirrorBitmap.", + "en_US": "The QEMU version running on the VM[uuid:{0}] does not support mirrorBitmap.", + "zh_CN": "在VM[uuid:{0}]上运行的QEMU版本不支持MirrorBitMap。", "arguments": [ - "rsp.getStatusCode()", - "rsp.getBody()" + "vmUuid" ], - "line": 118, - "fileName": "src/main/java/org/zstack/sns/platform/dingtalk/SNSDingTalkEndpoint.java" + "line": 366, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java" }, { - "raw": "cannot connect SMTP server[server: %s, port: %s] in 15 seconds", - "en_US": "cannot connect SMTP server[server: {0}, port: {1}] in 15 seconds", - "zh_CN": "在15秒内无法连接到SMTP服务器[server: {0}, port: {1}]", + "raw": "cannot ask primary storage[uuid:%s] for volume snapshot capability, see detail [%s]", + "en_US": "cannot ask primary storage[uuid:{0}] for volume snapshot capability, see detail [{1}]", + "zh_CN": "无法向主存储[uuid:{0}]请求卷快照功能,请参阅详细信息[{1}]", "arguments": [ - "getSelf().getSmtpServer()", - "getSelf().getSmtpPort()" + "vol.getUuid()", + "reply.getError()" ], - "line": 72, - "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" + "line": 458, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "SMTP server validation error: %s", - "en_US": "SMTP server validation error: {0}", - "zh_CN": "SMTP服务器验证错误: {0}", + "raw": "unexpected task type: %s", + "en_US": "unexpected task type: {0}", + "zh_CN": "意外的任务类型:{0}", "arguments": [ - "e.getMessage()" + "msg.getTaskType()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" + "line": 320, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "the endpoint is disabled", - "en_US": "the endpoint is disabled", - "zh_CN": "通知终端不可用", + "raw": "CDP task is still enabled", + "en_US": "CDP task is still enabled", + "zh_CN": "CDP任务仍处于启用状态", "arguments": [], - "line": 134, - "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" + "line": 127, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "no subject", - "en_US": "no subject", - "zh_CN": "没有主题", - "arguments": [], - "line": 162, - "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java" + "raw": "invalid time string: %s, should be in ISO offset format, for example: %s", + "en_US": "invalid time string: {0}, should be in ISO offset format, for example: {1}", + "zh_CN": "无效的时间字符串:{0},应为ISO偏移格式,例如:{1}", + "arguments": [ + "s", + "OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS)" + ], + "line": 152, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "The problem may be caused by an incorrect user name or password or email permission denied", - "en_US": "The problem may be caused by an incorrect user name or password or email permission denied", - "zh_CN": "导致操作失败的原因可能是不正确的用户名、密码或邮件访问权限不足", - "arguments": [], - "line": 59, - "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java" + "raw": "VM is not stopped, current state: %s", + "en_US": "VM is not stopped, current state: {0}", + "zh_CN": "云主机未停止,当前状态:{0}", + "arguments": [ + "state" + ], + "line": 189, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "Couldn\u0027t connect to host, port: %s, %d. The problem may be caused by an incorrect smtpServer or smtpPort", - "en_US": "Couldn\u0027t connect to host, port: {0}, {1}. The problem may be caused by an incorrect smtpServer or smtpPort", - "zh_CN": "连接{0}:{1}超时,导致原因可能是不正确的邮件服务器和邮件服务器端口", + "raw": "Shared volume[%s] from VM[uuid] is still used by other VMs.", + "en_US": "Shared volume[{0}] from VM[uuid] is still used by other VMs.", + "zh_CN": "云主机[uuid]中的共享云盘[{0}]仍由其他云主机使用。", "arguments": [ - "smtpServer", - "smtpPort" + "volumeUuid", + "msg.getVmInstanceUuid()" ], - "line": 61, - "fileName": "src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java" + "line": 233, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "HTTP POST failure. status: %s, body: %s", - "en_US": "HTTP POST failure. status: {0}, body: {1}", - "zh_CN": "HTTP POST失败,状态码: {0}, body: {1}", + "raw": "Task not found[uuid: %s]", + "en_US": "Task not found[uuid: {0}]", + "zh_CN": "未找到任务[uuid:{0}]", "arguments": [ - "rsp.getStatusCode()", - "rsp.getBody()" + "msg.getUuid()" ], - "line": 67, - "fileName": "src/main/java/org/zstack/sns/platform/http/SNSHttpEndpoint.java" + "line": 243, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "only HTTP endpoint can subscribe API topic, the endpoint[type:%s] is not a HTTP endpoint", - "en_US": "only HTTP endpoint can subscribe API topic, the endpoint[type:{0}] is not a HTTP endpoint", - "zh_CN": "仅HTTP通知终端可以订阅API通知主题,当前通知终端[type:{0}]不是一个HTTP通知终端", + "raw": "Unexpected task type[uuid: %s, type: %s]", + "en_US": "Unexpected task type[uuid: {0}, type: {1}]", + "zh_CN": "意外的任务类型[uuid:{0},类型:{1}]", "arguments": [ - "endpoint.getType()" + "msg.getUuid()", + "taskVO.getTaskType()" ], - "line": 172, - "fileName": "src/main/java/org/zstack/sns/system/SNSApiTopicManagerImpl.java" + "line": 248, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "API topic cannot be deleted", - "en_US": "API topic cannot be deleted", - "zh_CN": "API通知主题无法被删除", - "arguments": [], - "line": 191, - "fileName": "src/main/java/org/zstack/sns/system/SNSApiTopicManagerImpl.java" + "raw": "VM[uuid: %s] already deleted", + "en_US": "VM[uuid: {0}] already deleted", + "zh_CN": "云主机[uuid:{0}]已删除", + "arguments": [ + "refVO.getResourceUuid()" + ], + "line": 261, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "system alarm topic cannot be deleted", - "en_US": "system alarm topic cannot be deleted", - "zh_CN": "系统警报通知主题不能被删除", - "arguments": [], - "line": 76, - "fileName": "src/main/java/org/zstack/sns/system/SNSSystemAlarmTopicManagerImpl.java" + "raw": "Unexpected VM state: %s", + "en_US": "Unexpected VM state: {0}", + "zh_CN": "意外的VM状态:{0}", + "arguments": [ + "state" + ], + "line": 275, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "%s should not be null", - "en_US": "{0} should not be null", - "zh_CN": "{0} 不能为空", + "raw": "Backup storage not found[uuid: %s]", + "en_US": "Backup storage not found[uuid: {0}]", + "zh_CN": "未找到备份存储[uuid:{0}]", "arguments": [ - "name" + "taskVO.getBackupStorageUuid()" ], - "line": 65, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" + "line": 283, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "zoneUuids, backupStorageUuids must have at least one be none-empty list, or all is set to true", - "en_US": "zoneUuids, backupStorageUuids must have at least one be none-empty list, or all is set to true", - "zh_CN": "zoneUuids, backupStorageUuids 至少有一个不为空,或者all被设置为真 ", - "arguments": [], - "line": 88, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" + "raw": "Backup storage[uuid: %s] is disabled", + "en_US": "Backup storage[uuid: {0}] is disabled", + "zh_CN": "备份存储[uuid:{0}]已禁用", + "arguments": [ + "taskVO.getBackupStorageUuid()" + ], + "line": 288, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "backup storage[uuid:%s] has not been attached to zone[uuid:%s]", - "en_US": "backup storage[uuid:{0}] has not been attached to zone[uuid:{1}]", - "zh_CN": "镜像服务器[uuid:{0}]没有被加载到zone[uuid:{1}]", + "raw": "Backup storage[uuid: %s] is not connected", + "en_US": "Backup storage[uuid: {0}] is not connected", + "zh_CN": "备份存储[uuid:{0}]未连接", "arguments": [ - "msg.getBackupStorageUuid()", - "msg.getZoneUuid()" + "taskVO.getBackupStorageUuid()" ], - "line": 118, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" + "line": 293, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "backup storage[uuid:%s] has been attached to zone[uuid:%s]", - "en_US": "backup storage[uuid:{0}] has been attached to zone[uuid:{1}]", - "zh_CN": "镜像服务器[uuid:{0}]已经被加载到zone[uuid:{1}]", + "raw": "The vm[uuid: %s] has already created a backup job, cannot enable the cdp task at the same time.", + "en_US": "The vm[uuid: {0}] has already created a backup job, cannot enable the cdp task at the same time.", + "zh_CN": "VM[uuid:{0}]已创建备份作业,无法同时启用CDP任务。", "arguments": [ - "msg.getBackupStorageUuid()", - "msg.getZoneUuid()" + "refVO.getResourceUuid()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java" + "line": 309, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "failed to get header of image url %s: %s", - "en_US": "failed to get header of image url {0}: {1}", - "zh_CN": "获取链接 {0} 的Header信息失败,原因:{1}", + "raw": "\u0027%s\u0027(%d) should be larger than \u0027%s\u0027(%d)", + "en_US": "\u0027{0}\u0027({1}) should be larger than \u0027{2}\u0027({3})", + "zh_CN": "“{0}”({1})应大于“{2}”({3})", "arguments": [ - "url", - "e.toString()" + "s2", + "v2", + "s1", + "v1" ], - "line": 162, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" + "line": 334, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "failed to get header of image url %s", - "en_US": "failed to get header of image url {0}", - "zh_CN": "获取链接 {0} 的Header信息失败", + "raw": "mandatory args missing: %s", + "en_US": "mandatory args missing: {0}", + "zh_CN": "缺少必需的参数:{0}", "arguments": [ - "url" + "\"hourlyRpSinceDay\"" ], - "line": 166, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" + "line": 340, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "the backup storage[uuid:%s, name:%s] has not enough capacity to download the image[%s].Required size:%s, available size:%s", - "en_US": "the backup storage[uuid:{0}, name:{1}] has not enough capacity to download the image[{2}].Required size:{3}, available size:{4}", - "zh_CN": "镜像服务器[uuid:{0}, name:{1}]没有足够的容量可供下载镜像[{2}]。需要的大小: {3},可用的大小: {4}", + "raw": "expected one VM uuid, but given %d", + "en_US": "expected one VM uuid, but given {0}", + "zh_CN": "应为一个VM uuid,但给定了{0}", "arguments": [ - "self.getUuid()", - "self.getName()", - "url", - "size", - "self.getAvailableCapacity()" + "vmUuids.size()" ], - "line": 176, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" + "line": 376, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "the image size get from url %s is %d bytes, it\u0027s too small for an image, please check the url again.", - "en_US": "the image size get from url {0} is {1} bytes, it\u0027s too small for an image, please check the url again.", - "zh_CN": "从链接 {0} 获取到的镜像大小为{1}字节,对一个正常的镜像来说太小了,请检查该链接是否合法", + "raw": "resource [uuid: %s] is not VM", + "en_US": "resource [uuid: {0}] is not VM", + "zh_CN": "资源[uuid:{0}]不是VM", "arguments": [ - "url", - "size" + "vmUuids.get(0)" ], - "line": 173, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" + "line": 380, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "backup storage cannot proceed message[%s] because its status is %s", - "en_US": "backup storage cannot proceed message[{0}] because its status is {1}", - "zh_CN": "镜像服务器无法处理消息[{0}]因为它的状态为{1}", + "raw": "The vm[uuid: %s] has already created a cdp task, cannot create the backup job at the same time.", + "en_US": "The vm[uuid: {0}] has already created a cdp task, cannot create the backup job at the same time.", + "zh_CN": "VM[uuid:{0}]已创建CDP任务,无法同时创建备份作业。", "arguments": [ - "msg.getClass().getName()", - "self.getStatus()" + "msg.getTargetResourceUuid()" ], - "line": 191, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" + "line": 402, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java" }, { - "raw": "backup storage cannot proceed message[%s] because its state is %s", - "en_US": "backup storage cannot proceed message[{0}] because its state is {1}", - "zh_CN": "镜像服务器无法处理消息[{0}]因为它的状态为{1}", + "raw": "No recovery point found with grpId %d", + "en_US": "No recovery point found with grpId {0}", + "zh_CN": "找不到具有grpid{0}的恢复点", "arguments": [ - "msg.getClass().getName()", - "self.getState()" + "groupId" ], - "line": 197, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageBase.java" + "line": 243, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageImpl.java" }, { - "raw": "cannot reserve %s on the backup storage[uuid:%s], it only has %s available", - "en_US": "cannot reserve {0} on the backup storage[uuid:{1}], it only has {2} available", - "zh_CN": "无法在镜像服务器{1}保留{0},它仅有{2}可用容量", + "raw": "hostname not found for backup storage[uuid: %s]", + "en_US": "hostname not found for backup storage[uuid: {0}]", + "zh_CN": "未找到备份存储的物理机名[uuid:{0}]", "arguments": [ - "size", - "backupStorageUuid", - "capacityVO.getAvailableCapacity()" + "backupStorageUuid" ], - "line": 139, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageCapacityUpdater.java" + "line": 717, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageImpl.java" }, { - "raw": "capacity reservation on all backup storage failed", - "en_US": "capacity reservation on all backup storage failed", - "zh_CN": "在所有镜像服务器上保留容量失败", - "arguments": [], - "line": 279, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java" + "raw": "CDP task[uuid: %s] not found", + "en_US": "CDP task[uuid: {0}] not found", + "zh_CN": "未找到CDP任务[uuid:{0}]", + "arguments": [ + "msg.getUuid()" + ], + "line": 1921, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "after subtracting reserved capacity[%s], no backup storage has required capacity[%s bytes]", - "en_US": "after subtracting reserved capacity[{0}], no backup storage has required capacity[{1} bytes]", - "zh_CN": "在减去保留容量[{0}],没有镜像服务器有容量[{1}] bytes", + "raw": "Invalid max capacity[%d], current usage is %d", + "en_US": "Invalid max capacity[{0}], current usage is {1}", + "zh_CN": "最大容量[{0}]无效,当前使用量为{1}", "arguments": [ - "BackupStorageGlobalConfig.RESERVED_CAPACITY.value()", - "spec.getSize()" + "msg.getMaxCapacity()", + "oldUsedCapacity" ], - "line": 46, - "fileName": "src/main/java/org/zstack/storage/backup/BackupStorageReservedCapacityAllocatorFlow.java" + "line": 179, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "missing \u0027retentionType\u0027 in job parameters", - "en_US": "missing \u0027retentionType\u0027 in job parameters", - "zh_CN": "parameters中缺少retentionType参数", - "arguments": [], - "line": 284, - "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" + "raw": "VM [uuid: %s] have been protected by task: %s", + "en_US": "VM [uuid: {0}] have been protected by task: {1}", + "zh_CN": "云主机[uuid:{0}]已受任务{1}保护", + "arguments": [ + "vmUuid", + "tasks.get(0)" + ], + "line": 269, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "missing \u0027retentionValue\u0027 in job parameters", - "en_US": "missing \u0027retentionValue\u0027 in job parameters", - "zh_CN": "parameter中缺少retentionValue参数", + "raw": "revert job cancelled", + "en_US": "revert job cancelled", + "zh_CN": "已取消还原作业", "arguments": [], - "line": 288, - "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" + "line": 715, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "missing \u0027backupStorageUuids\u0027 in job parameters", - "en_US": "missing \u0027backupStorageUuids\u0027 in job parameters", - "zh_CN": "parameter中缺少backupStorageUuids参数", + "raw": "create-vm job cancelled", + "en_US": "create-vm job cancelled", + "zh_CN": "创建云主机作业已取消", "arguments": [], - "line": 292, - "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" + "line": 781, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "job parameter \u0027backupStorageUuids\u0027 is empty", - "en_US": "job parameter \u0027backupStorageUuids\u0027 is empty", - "zh_CN": "parameter中backupStorageUuids为空", - "arguments": [], - "line": 296, - "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" + "raw": "CDP task[uuid: %s] has no VM attached", + "en_US": "CDP task[uuid: {0}] has no VM attached", + "zh_CN": "CDP任务[uuid:{0}]未连接VM", + "arguments": [ + "taskVO.getUuid()" + ], + "line": 1181, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "unexpected backup storage uuid: %s", - "en_US": "unexpected backup storage uuid: {0}", - "zh_CN": "错误的镜像服务器uuid: {0}", + "raw": "task[uuid:%s] have been deleted", + "en_US": "task[uuid:{0}] have been deleted", + "zh_CN": "任务[uuid:{0}]已被删除", "arguments": [ - "bsUuid" + "taskVO.getUuid()" ], - "line": 301, - "fileName": "src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java" + "line": 1215, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "volume[uuid:%s] is deleted, state change is not allowed", - "en_US": "volume[uuid:{0}] is deleted, state change is not allowed", - "zh_CN": "", + "raw": "CDP task[uuid:%s] exceeded storage usage: maximum %d, used %d.", + "en_US": "CDP task[uuid:{0}] exceeded storage usage: maximum {1}, used {2}.", + "zh_CN": "CDP任务[uuid:{0}]超出了存储使用率:最大值{1},已使用{2}。", "arguments": [ - "getTargetResourceUuid()" + "taskUuid", + "maxCapacity", + "usedCapacity" ], - "line": 484, - "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" + "line": 1279, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "bandWidth must be a positive number", - "en_US": "bandWidth must be a positive number", - "zh_CN": "", - "arguments": [], - "line": 114, - "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" + "raw": "No CDP task found for VM: %s", + "en_US": "No CDP task found for VM: {0}", + "zh_CN": "未找到VM{0}的CDP任务", + "arguments": [ + "vmUuid" + ], + "line": 1728, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "missing job parameters", - "en_US": "missing job parameters", - "zh_CN": "缺少parameters参数", - "arguments": [], - "line": 170, - "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" + "raw": "No CDP backup storage found for VM: %s", + "en_US": "No CDP backup storage found for VM: {0}", + "zh_CN": "未找到云主机{0}的CDP备份存储", + "arguments": [ + "vmUuid" + ], + "line": 1736, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "No available backup storage found, skip this job", - "en_US": "No available backup storage found, skip this job", - "zh_CN": "", - "arguments": [], - "line": 429, - "fileName": "src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java" + "raw": "No CdpBackupFactory of type[%s] found", + "en_US": "No CdpBackupFactory of type[{0}] found", + "zh_CN": "未找到类型为[{0}]的CDPBackupFactory", + "arguments": [ + "hypervisorType" + ], + "line": 1784, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "database backup[uuid%s] has not been exported from backupStorage[uuid:%s]", - "en_US": "database backup[uuid{0}] has not been exported from backupStorage[uuid:{1}]", - "zh_CN": "", + "raw": "No hypervisor type for VM %s", + "en_US": "No hypervisor type for VM {0}", + "zh_CN": "云主机{0}没有云主机管理程序类型", "arguments": [ - "msg.getDatabaseBackupUuid()", - "msg.getBackupStorageUuid()" + "hostUuid" ], - "line": 93, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" + "line": 1815, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "database backup[uuid%s] has been exported from backupStorage[uuid:%s]", - "en_US": "database backup[uuid{0}] has been exported from backupStorage[uuid:{1}]", - "zh_CN": "", + "raw": "The operation has volume[uuid: %s] that will take chain type snapshot. Therefore, you could not do this operation when a CDP task is running on the VM instance.", + "en_US": "The operation has volume[uuid: {0}] that will take chain type snapshot. Therefore, you could not do this operation when a CDP task is running on the VM instance.", + "zh_CN": "该操作具有将创建链类型快照的卷[uuid:{0}]。因此,当CDP任务在VM实例上运行时,您无法执行此操作。", "arguments": [ - "msg.getDatabaseBackupUuid()", - "msg.getBackupStorageUuid()" + "msg.getVolume().getUuid()" ], - "line": 107, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" + "line": 2221, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java" }, { - "raw": "do not allow cover database from backup", - "en_US": "do not allow cover database from backup", - "zh_CN": "", + "raw": "Could not attach volume.The VM instance is running a CDP task. After the volume is attached, the capacity required for full backup will exceed the CDP task planned size. Please plan the size properly and try again.", + "en_US": "Could not attach volume.The VM instance is running a CDP task. After the volume is attached, the capacity required for full backup will exceed the CDP task planned size. Please plan the size properly and try again.", + "zh_CN": "无法连接卷。VM实例正在运行CDP任务。连接卷后,完整备份所需的容量将超过CDP任务计划的大小。请正确规划大小,然后重试。", "arguments": [], - "line": 120, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" + "line": 163, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpTaskMonitor.java" }, { - "raw": "installPath and bsUrl are both need", - "en_US": "installPath and bsUrl are both need", - "zh_CN": "", - "arguments": [], - "line": 124, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" + "raw": "The VM[%s] for volume[%s] is running CDP, cannot resize now.", + "en_US": "The VM[{0}] for volume[{1}] is running CDP, cannot resize now.", + "zh_CN": "卷[{1}]的VM[{0}]正在运行CDP,现在无法调整大小。", + "arguments": [ + "volume.getVmInstanceUuid()", + "volume.getUuid()" + ], + "line": 187, + "fileName": "src/main/java/org/zstack/storage/cdp/CdpTaskMonitor.java" }, { - "raw": "databaseBackup[uuid:%s] is not Enabled and Ready", - "en_US": "databaseBackup[uuid:{0}] is not Enabled and Ready", - "zh_CN": "", - "arguments": [], - "line": 133, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" + "raw": "No VM found for CDP task[uuid: %s]", + "en_US": "No VM found for CDP task[uuid: {0}]", + "zh_CN": "未找到CDP任务[uuid:{0}]的VM", + "arguments": [ + "apiMessage.getCdpTaskUuid()" + ], + "line": 88, + "fileName": "src/main/java/org/zstack/storage/cdp/CreateVmFromCdpBackupLongJob.java" }, { - "raw": "illegal url[%s], correct example is ssh://username:password@hostname[:sshPort]/path", - "en_US": "illegal url[{0}], correct example is ssh://username:password@hostname[:sshPort]/path", - "zh_CN": "", + "raw": "BackupStorage[uuid: %s] already been deleted", + "en_US": "BackupStorage[uuid: {0}] already been deleted", + "zh_CN": "BackupStorage[uuid:{0}]已删除", "arguments": [ - "url" + "bsUuid" ], - "line": 142, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java" + "line": 119, + "fileName": "src/main/java/org/zstack/storage/cdp/CreateVmFromCdpBackupLongJob.java" }, { - "raw": "sync task failed.", - "en_US": "sync task failed.", - "zh_CN": "同步失败", + "raw": "no volume records found from VM backup", + "en_US": "no volume records found from VM backup", + "zh_CN": "未从云主机备份中找到卷记录", "arguments": [], - "line": 467, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" + "line": 179, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java" }, { - "raw": "unexpected task status: %s", - "en_US": "unexpected task status: {0}", - "zh_CN": "错误的任务状态{0}", + "raw": "VM CDP task[uuid: %s] not found", + "en_US": "VM CDP task[uuid: {0}] not found", + "zh_CN": "找不到VM CDP任务[uuid:{0}]", "arguments": [ - "reply.getStatus()" + "taskUuid" ], - "line": 474, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" + "line": 138, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java" }, { - "raw": "One of the backup storage[uuids: %s, %s] is in the state of %s, can not do sync operation", - "en_US": "One of the backup storage[uuids: {0}, {1}] is in the state of {2}, can not do sync operation", - "zh_CN": "镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作", + "raw": "VM not found for CDP task[uuid: %s]", + "en_US": "VM not found for CDP task[uuid: {0}]", + "zh_CN": "未找到CDP任务[uuid:{0}]的VM", "arguments": [ - "msg.getDstBackupStorageUuid()", - "msg.getSrcBackupStorageUuid()", - "BackupStorageState.Disabled.toString()" + "taskUuid" ], - "line": 280, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" + "line": 147, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java" }, { - "raw": "database backup[uuid:%s] is not Enabled and Ready", - "en_US": "database backup[uuid:{0}] is not Enabled and Ready", - "zh_CN": "", + "raw": "multiple root volumes found from CDP backup %s:%d", + "en_US": "multiple root volumes found from CDP backup {0}:{1}", + "zh_CN": "从CDP备份{0}中找到多个根卷:{1}", "arguments": [ - "self.getUuid()" + "taskUuid", + "msg.getGroupId()" ], - "line": 80, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" + "line": 236, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java" }, { - "raw": "database backup[uuid:%s] not found in backup storage[uuid:%s]", - "en_US": "database backup[uuid:{0}] not found in backup storage[uuid:{1}]", - "zh_CN": "", + "raw": "cannot find root volume from CDP backup %s:%d", + "en_US": "cannot find root volume from CDP backup {0}:{1}", + "zh_CN": "无法从CDP备份{0}中找到根卷:{1}", "arguments": [ - "msg.getDatabaseBackupUuid()", - "msg.getSrcBackupStorageUuid()" + "taskUuid", + "msg.getGroupId()" ], - "line": 325, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java" + "line": 250, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java" }, { - "raw": "database backup [uuid:%s] is not existed yet", - "en_US": "database backup [uuid:{0}] is not existed yet", - "zh_CN": "", + "raw": "root volume not found from CDP backup %s:%d", + "en_US": "root volume not found from CDP backup {0}:{1}", + "zh_CN": "未从CDP备份{0}中找到根卷:{1}", "arguments": [ - "msg.getDatabaseBackupUuid()" + "taskUuid", + "msg.getGroupId()" ], - "line": 90, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" - }, - { - "raw": "backup storage[uuid:%s] is not enabled and connected", - "en_US": "backup storage[uuid:{0}] is not enabled and connected", - "zh_CN": "", - "arguments": [], - "line": 106, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" + "line": 257, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java" }, { - "raw": "not pass the restore security check:\\n%s", - "en_US": "not pass the restore security check:\\n{0}", - "zh_CN": "", + "raw": "recoverVm: host[uuid: %s] not found for VM[uuid: %s]", + "en_US": "recoverVm: host[uuid: {0}] not found for VM[uuid: {1}]", + "zh_CN": "未找到VM[uuid:{1}]的RecoverVM:物理机[uuid:{0}]", "arguments": [ - "result.getStderr()" + "hostUuid", + "this.msg.getVmInstanceUuid()" ], - "line": 600, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" + "line": 118, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "cannot get free port to listen", - "en_US": "cannot get free port to listen", - "zh_CN": "", - "arguments": [], - "line": 612, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" + "raw": "multiple root volumes found: %s", + "en_US": "multiple root volumes found: {0}", + "zh_CN": "找到多个根卷:{0}", + "arguments": [ + "uuids" + ], + "line": 216, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "database backup version[%s] is not match currently version[%s]", - "en_US": "database backup version[{0}] is not match currently version[{1}]", - "zh_CN": "", + "raw": "volume[uuid: %s] has unexpected path: %s", + "en_US": "volume[uuid: {0}] has unexpected path: {1}", + "zh_CN": "卷[uuid:{0}]具有意外路径:{1}", "arguments": [ - "version", - "dbf.getDbVersion()" + "volumeUuid", + "installPath" ], - "line": 640, - "fileName": "src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java" + "line": 792, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "cannot ssh peer node via sshkey, please check connection", - "en_US": "cannot ssh peer node via sshkey, please check connection", - "zh_CN": "", - "arguments": [], - "line": 25, - "fileName": "src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java" + "raw": "unexpected volume[uuid: %s] size: %d", + "en_US": "unexpected volume[uuid: {0}] size: {1}", + "zh_CN": "意外卷[uuid:{0}]大小:{1}", + "arguments": [ + "volumeUuid", + "oldVolumeSize" + ], + "line": 718, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "cannot get zsha2 status, because %s", - "en_US": "cannot get zsha2 status, because {0}", - "zh_CN": "", + "raw": "resize volume[uuid: %s] failed: %s", + "en_US": "resize volume[uuid: {0}] failed: {1}", + "zh_CN": "调整卷[uuid:{0}]大小失败:{1}", "arguments": [ - "result.getStderr()" + "volumeUuid", + "reply.getError().getDetails()" ], - "line": 40, - "fileName": "src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java" + "line": 746, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "cannot get zsha2 config, because %s, maybe you need upgrade zsha2", - "en_US": "cannot get zsha2 config, because {0}, maybe you need upgrade zsha2", - "zh_CN": "", + "raw": "volume %s contains in backup but detached from VM[uuid: %s]: you need to either attach it back or delete it", + "en_US": "volume {0} contains in backup but detached from VM[uuid: {1}]: you need to either attach it back or delete it", + "zh_CN": "卷{0}包含在备份中,但已从VM分离[uuid:{1}]:您需要将其重新连接或将其删除", "arguments": [ - "result.getStderr()" + "uuid", + "msg.getVmInstanceUuid()" ], - "line": 45, - "fileName": "src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java" + "line": 377, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "please stop other node first!", - "en_US": "please stop other node first!", - "zh_CN": "", + "raw": "no root volume found from VM backup", + "en_US": "no root volume found from VM backup", + "zh_CN": "未从云主机备份中找到根卷", "arguments": [], - "line": 19, - "fileName": "src/main/java/org/zstack/storage/backup/SingleDatabaseRecoverChecker.java" + "line": 305, + "fileName": "src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java" }, { - "raw": "current backup storage state[%s] doesn\u0027t allow to proceed message[%s], allowed states are %s", - "en_US": "current backup storage state[{0}] doesn\u0027t allow to proceed message[{1}], allowed states are {2}", - "zh_CN": "当前镜像服务器状态[{0}]不能处理消息[{1}],仅当镜像服务器处于{2}时才能处理该消息", + "raw": "kvmagent restarted", + "en_US": "kvmagent restarted", + "zh_CN": "KVMAGENT重新启动", + "arguments": [], + "line": 145, + "fileName": "src/main/java/org/zstack/storage/cdp/RecoverVmTracker.java" + }, + { + "raw": "kvmagent no response %d times", + "en_US": "kvmagent no response {0} times", + "zh_CN": "KVMAgent无响应{0}次", "arguments": [ - "currentState", - "msgName", - "checker.getStatesForOperation(msgName)" + "maxFailure" ], - "line": 81, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 164, + "fileName": "src/main/java/org/zstack/storage/cdp/RecoverVmTracker.java" }, { - "raw": "Unexpected backup storage[type:%s,uuid:%s]", - "en_US": "Unexpected backup storage[type:{0},uuid:{1}]", - "zh_CN": "错误的镜像服务器[type:{0}, uuid:{1}]", + "raw": "waiting host[uuid:%s] and backupStorage[uuid:%s] to be Connected...", + "en_US": "waiting host[uuid:{0}] and backupStorage[uuid:{1}] to be Connected...", + "zh_CN": "正在等待要连接的物理机[uuid:{0}]和备份存储[uuid:{1}]..", "arguments": [ - "bsType", - "bsUuid" + "apiMessage.getHostUuid()", + "apiMessage.getBackupStorageUuid()" ], - "line": 212, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 117, + "fileName": "src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java" }, { - "raw": "Can not create volume backup for shareable volume[uuid:%s]", - "en_US": "Can not create volume backup for shareable volume[uuid:{0}]", - "zh_CN": "无法给共享云盘[uuid:{0}]创建云盘备份", + "raw": "recoverVm: host uuid is not provided and original host is not found for VM[uuid: %s]", + "en_US": "recoverVm: host uuid is not provided and original host is not found for VM[uuid: {0}]", + "zh_CN": "RecoverVM:未提供物理机uuid,并且未找到VM[uuid:{0}]的原始物理机", "arguments": [ - "msg.getVolumeUuid()" + "apiMessage.getVmInstanceUuid()" ], - "line": 233, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 72, + "fileName": "src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java" }, { - "raw": "Failed to create volume backup for volume[uuid:%s], because it is not attached to any vm", - "en_US": "Failed to create volume backup for volume[uuid:{0}], because it is not attached to any vm", - "zh_CN": "无法给云盘[uuid:{0}]创建云盘备份,因为它未加载到虚拟机上", + "raw": "No CDP task found for VM[uuid: %s]", + "en_US": "No CDP task found for VM[uuid: {0}]", + "zh_CN": "找不到VM[uuid:{0}]的CDP任务", "arguments": [ - "msg.getVolumeUuid()" + "vmUuid" ], - "line": 237, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 165, + "fileName": "src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java" }, { - "raw": "Failed to create volume backup for volume[uuid:%s], because its attached volume is not in state[%s, %s]", - "en_US": "Failed to create volume backup for volume[uuid:{0}], because its attached volume is not in state[{1}, {2}]", - "zh_CN": "无法给云盘[uuid:{0}]创建云盘备份,因为加载到的虚拟机并不处于以下状态[{1}, {2}]", + "raw": "CDP task for VM[uuid: %s] is not found on BS[uuid: %s]", + "en_US": "CDP task for VM[uuid: {0}] is not found on BS[uuid: {1}]", + "zh_CN": "在BS[uuid:{1}]上找不到VM[uuid:{0}]的CDP任务", "arguments": [ - "msg.getVolumeUuid()", - "VmInstanceState.Running.toString()", - "VmInstanceState.Paused.toString()" + "vmUuid", + "backupStorageUuid" ], - "line": 246, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 174, + "fileName": "src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java" }, { - "raw": "Failed to create volume backup for volume[uuid:%s], because the vm is not in state[%s, %s]", - "en_US": "Failed to create volume backup for volume[uuid:{0}], because the vm is not in state[{1}, {2}]", - "zh_CN": "无法给云盘[uuid:{0}]创建云盘备份,因为加载到的虚拟机并不处于以下状态[{1}, {2}]", + "raw": "operation failure, because the poolName[poolName:%s] can not include unprintable ascii characters.", + "en_US": "operation failure, because the poolName[poolName:{0}] can not include unprintable ascii characters.", + "zh_CN": "操作失败,因为pool名称[poolName:{0}]不能包含中文和特殊字符", "arguments": [ - "msg.getVolumeUuid()", - "VmInstanceState.Running.toString()", - "VmInstanceState.Paused.toString()" + "msg.getPoolName()" ], - "line": 243, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 84, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "Volume[uuid:%s] is not root volume", - "en_US": "Volume[uuid:{0}] is not root volume", - "zh_CN": "", + "raw": "Ceph pool[uuid:%s] with this name is already added into ZStack and used elsewhere, cannot reuse the ceph pool.", + "en_US": "Ceph pool[uuid:{0}] with this name is already added into ZStack and used elsewhere, cannot reuse the ceph pool.", + "zh_CN": "池名称为此的扩展池[uuid:{0}]已经被添加进 ZStack 了,已做它用,不能复用该扩展池", "arguments": [ - "msg.getVolumeUuid()" + "duplicatePoolUuid" ], - "line": 255, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 98, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "Failed to create backups for VM[uuid:%s], because it is not in state[%s, %s]", - "en_US": "Failed to create backups for VM[uuid:{0}], because it is not in state[{1}, {2}]", - "zh_CN": "", + "raw": "creation failure, duplicate poolName[%s]. There has been a pool[uuid:%s] with the same name existing.", + "en_US": "creation failure, duplicate poolName[{0}]. There has been a pool[uuid:{1}] with the same name existing.", + "zh_CN": "创建失败,重复的池名称[{0}]。已经有一个相同名称的扩展池[uuid:{1}]存在", "arguments": [ - "t.get(0)", - "VmInstanceState.Running.toString()", - "VmInstanceState.Paused.toString()" + "msg.getPoolName()", + "duplicatePoolUuid" ], - "line": 262, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 93, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "No volume backup found for group uuid: %s", - "en_US": "No volume backup found for group uuid: {0}", - "zh_CN": "", + "raw": "cannot add ceph primary storage, there has been some ceph primary storage using mon[hostnames:%s]", + "en_US": "cannot add ceph primary storage, there has been some ceph primary storage using mon[hostnames:{0}]", + "zh_CN": "无法添加分布式存储,一定有某些分布式存储使用了mon[物理机名: {0}]", "arguments": [ - "groupUuid" + "existing" ], - "line": 276, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 126, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "root volume backup of group[uuid:%s] not found", - "en_US": "root volume backup of group[uuid:{0}] not found", - "zh_CN": "", + "raw": "Cannot add same host[%s] in mons", + "en_US": "Cannot add same host[{0}] in mons", + "zh_CN": "在mon中无法添加相同的物理机[{0}]", "arguments": [ - "groupUuid" + "uri.getHostname()" ], - "line": 282, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 137, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "cannot specify primary storage which attached different cluster.", - "en_US": "cannot specify primary storage which attached different cluster.", - "zh_CN": "", + "raw": "Adding the same Mon node is not allowed", + "en_US": "Adding the same Mon node is not allowed", + "zh_CN": "添加相同的Mon节点不被允许", "arguments": [], - "line": 312, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 163, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "volume backup[uuid:%s] is in state %s, cannot revert volume to it", - "en_US": "volume backup[uuid:{0}] is in state {1}, cannot revert volume to it", - "zh_CN": "云盘备份[uuid:{0}]处于{1}状态,无法用于恢复云盘", + "raw": "invalid monUrl[%s]. A valid url is in format of %s", + "en_US": "invalid monUrl[{0}]. A valid url is in format of {1}", + "zh_CN": "无效的monURL[{0}]。有效URL的格式为{1}", "arguments": [ - "backupUuid", - "state" + "monUrl", + "MON_URL_FORMAT" ], - "line": 335, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 202, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "original volume for backup[uuid:%s] has been deleted, cannot revert volume to it", - "en_US": "original volume for backup[uuid:{0}] has been deleted, cannot revert volume to it", - "zh_CN": "云盘备份[uuid:{0}]已经被删除,无法用于恢复云盘", - "arguments": [ - "backupUuid" - ], - "line": 345, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "raw": "dataVolumePoolName can be null but cannot be an empty string", + "en_US": "dataVolumePoolName can be null but cannot be an empty string", + "zh_CN": "DataVolumePoolName可以为空,但不能为空字符串", + "arguments": [], + "line": 209, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "original volume[uuid:%s] for backup[uuid:%s] is no longer attached to vm[uuid:%s]", - "en_US": "original volume[uuid:{0}] for backup[uuid:{1}] is no longer attached to vm[uuid:{2}]", - "zh_CN": "", - "arguments": [ - "volUuid", - "backupUuid", - "expectVmUuid" - ], - "line": 349, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "raw": "rootVolumePoolName can be null but cannot be an empty string", + "en_US": "rootVolumePoolName can be null but cannot be an empty string", + "zh_CN": "RootVolumePoolName可以为空,但不能为空字符串", + "arguments": [], + "line": 214, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "VM not found with volume backup[uuid:%s]", - "en_US": "VM not found with volume backup[uuid:{0}]", - "zh_CN": "找不到和云盘备份[uuid:{0}]对应的虚拟机", - "arguments": [ - "backupUuid" - ], - "line": 359, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "raw": "imageCachePoolName can be null but cannot be an empty string", + "en_US": "imageCachePoolName can be null but cannot be an empty string", + "zh_CN": "ImageCachePoolName可以为空,但不能为空字符串", + "arguments": [], + "line": 219, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "VM is not in stopped state: %s", - "en_US": "VM is not in stopped state: {0}", - "zh_CN": "当前虚拟机状态并不是停止状态:{0}", + "raw": "cannot add ceph backup storage, there has been some ceph backup storage using mon[hostnames:%s]", + "en_US": "cannot add ceph backup storage, there has been some ceph backup storage using mon[hostnames:{0}]", + "zh_CN": "无法添加Ceph镜像服务器监控节点,已经有某个Ceph镜像服务器监控节点使用mon[物理机名: {0}]", "arguments": [ - "vmState" + "existing" ], - "line": 363, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 242, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "No available backup storage found", - "en_US": "No available backup storage found", - "zh_CN": "没有可用的镜像服务器", + "raw": "poolName is required when importImages is true", + "en_US": "poolName is required when importImages is true", + "zh_CN": "当importImages为真的时候必须填写池名", "arguments": [], - "line": 380, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java" + "line": 250, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "Operation not supported on shared volume", - "en_US": "Operation not supported on shared volume", - "zh_CN": "共享云盘不支持该操作", + "raw": "poolName can be null but cannot be an empty string", + "en_US": "poolName can be null but cannot be an empty string", + "zh_CN": "PoolName可以为空,但不能为空字符串", "arguments": [], - "line": 181, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java" + "line": 248, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" }, { - "raw": "No VM found for volume[uuid:%s]", - "en_US": "No VM found for volume[uuid:{0}]", - "zh_CN": "找不到和云盘[uuid:{0}]对应的虚拟机", + "raw": "Third-party ceph cannot mixed with other primary storage.", + "en_US": "Third-party ceph cannot mixed with other primary storage.", + "zh_CN": "第三方Ceph不能与其他主存储混合。", + "arguments": [], + "line": 269, + "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + }, + { + "raw": "The problem may be caused by an incorrect user name or password or SSH port or unstable network environment", + "en_US": "The problem may be caused by an incorrect user name or password or SSH port or unstable network environment", + "zh_CN": "该问题可能是由不正确的用户名、密码、SSH端口或者不稳定的网络环境引起的", + "arguments": [], + "line": 66, + "fileName": "src/main/java/org/zstack/storage/ceph/CephMonBase.java" + }, + { + "raw": "all monitors cannot execute http call[%s]", + "en_US": "all monitors cannot execute http call[{0}]", + "zh_CN": "所有的监控节点都无法执行http call[{0}]", "arguments": [ - "volumeVO.getUuid()" + "path" ], - "line": 186, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java" + "line": 768, + "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" + }, + { + "raw": "CephMon[hostname:%s] not found on backup storage[uuid:%s]", + "en_US": "CephMon[hostname:{0}] not found on backup storage[uuid:{1}]", + "zh_CN": "在备份存储[uuid:{1}]上找不到cephmon[物理机名:{0}]", + "arguments": [ + "msg.getHostname()", + "msg.getBackupStorageUuid()" + ], + "line": 866, + "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" }, { - "raw": "No VM found with root volume uuid: %s", - "en_US": "No VM found with root volume uuid: {0}", - "zh_CN": "", + "raw": "there is another CEPH backup storage[name:%s, uuid:%s] with the same FSID[%s], you cannot add the same CEPH setup as two different backup storage", + "en_US": "there is another CEPH backup storage[name:{0}, uuid:{1}] with the same FSID[{2}], you cannot add the same CEPH setup as two different backup storage", + "zh_CN": "有另外一个Ceph镜像服务器监控节点[name:{0}, uuid:{1}]有相同的FSID[{2}],你不能添加同样的CEPH为两个不同的镜像服务器", "arguments": [ - "msg.getRootVolumeUuid()" + "otherCeph.getName()", + "otherCeph.getUuid()", + "fsId" ], - "line": 435, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java" + "line": 1386, + "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" }, { - "raw": "[%s] is not a standard cidr, do you mean [%s]?", - "en_US": "[{0}] is not a standard cidr, do you mean [{1}]?", - "zh_CN": "[{0}]不是一个标准的cidr, 是否指定的是[{1}]", + "raw": "image[uuid: %s] is not on backup storage[uuid:%s, name:%s]", + "en_US": "image[uuid: {0}] is not on backup storage[uuid:{1}, name:{2}]", + "zh_CN": "镜像[uuid:{0}]不在备份存储[uuid:{1},名称:{2}]上", "arguments": [ - "cidr", - "fmtCidr" + "msg.getImageUuid()", + "self.getUuid()", + "self.getName()" ], - "line": 2041, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 1756, + "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" }, { - "raw": "failed to create image from backup %s", - "en_US": "failed to create image from backup {0}", - "zh_CN": "", + "raw": "cannot update status of the ceph backup storage mon[uuid:%s], it has been deleted.This error can be ignored", + "en_US": "cannot update status of the ceph backup storage mon[uuid:{0}], it has been deleted.This error can be ignored", + "zh_CN": "无法更新Ceph镜像服务器监控节点监控节点[uuid:{0}],他已经被删除。这个错误可以被忽略", "arguments": [ - "vos.stream().filter( vo -\u003e !succeedUuids.contains(vo.getUuid())).map(VolumeBackupVO::getUuid).collect(Collectors.toList())" + "uuid" ], - "line": 306, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 97, + "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java" }, { - "raw": "sync volume backup metadata file in image store[uuid:%s] meet I/O error: %s", - "en_US": "sync volume backup metadata file in image store[uuid:{0}] meet I/O error: {1}", - "zh_CN": "", + "raw": "Ceph bs[uuid\u003d%s] pool name not found", + "en_US": "Ceph bs[uuid\u003d{0}] pool name not found", + "zh_CN": "找不到Ceph BS[uuid\u003d{0}]池名称", "arguments": [ - "msg.getImageStoreUuid()", - "e.getMessage()" + "getSelf().getBackupStorageUuid()" ], - "line": 660, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 463, + "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java" }, { - "raw": "No VolumeBackupFactory of type[%s] found", - "en_US": "No VolumeBackupFactory of type[{0}] found", - "zh_CN": "", + "raw": "the mon[ip:%s] returns a fsid[%s] different from the current fsid[%s] of the cep cluster,are you adding a mon not belonging to current cluster mistakenly?", + "en_US": "the mon[ip:{0}] returns a fsid[{1}] different from the current fsid[{2}] of the cep cluster,are you adding a mon not belonging to current cluster mistakenly?", + "zh_CN": "MON[IP:{0}]返回的FSID[{1}]与CEP集群的当前FSID[{2}]不同,您是否错误地添加了不属于当前集群的MON?", "arguments": [ - "hypervisorType" + "base.getSelf().getHostname()", + "fsid", + "getSelf().getFsid()" ], - "line": 697, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 4126, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "One of the backup storage[uuid: %s] is in the state of %s, can not do sync operation", - "en_US": "One of the backup storage[uuid: {0}] is in the state of {1}, can not do sync operation", - "zh_CN": "镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作", + "raw": "the backup storage[uuid:%s, name:%s, fsid:%s] is not in the same ceph cluster with the primary storage[uuid:%s, name:%s, fsid:%s]", + "en_US": "the backup storage[uuid:{0}, name:{1}, fsid:{2}] is not in the same ceph cluster with the primary storage[uuid:{3}, name:{4}, fsid:{5}]", + "zh_CN": "镜像服务器[uuid:{0}, name:{1}, fsid:{2}]和主存储[uuid:{3}, name:{4}, fsid:{5}]不在同一个ceph集群中", "arguments": [ - "msg.getBackupStorageUuid()", - "BackupStorageState.Disabled.toString()" + "backupStorage.getUuid()", + "backupStorage.getName()", + "bsFsid", + "self.getUuid()", + "self.getName()", + "getSelf().getFsid()" ], - "line": 714, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 1520, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "Volume backup[uuid:%s] not found on backup storage[uuid:%s]", - "en_US": "Volume backup[uuid:{0}] not found on backup storage[uuid:{1}]", - "zh_CN": "在镜像服务器[uuid:{1}]上找不到云盘备份[uuid:{0}]", + "raw": "fsid is not same between ps[%s] and bs[%s], create template is forbidden.", + "en_US": "fsid is not same between ps[{0}] and bs[{1}], create template is forbidden.", + "zh_CN": "在主存储和镜像服务器中fsid不是一样的,禁止创建模版。", "arguments": [ - "struct.getBackupUuid()", - "struct.getBackupStorageUuid()" + "psUuid", + "bsUuid" ], - "line": 854, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 2588, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "volume backup[uuid:%s] not found in backup storage[uuid:%s]", - "en_US": "volume backup[uuid:{0}] not found in backup storage[uuid:{1}]", - "zh_CN": "在镜像服务器[uuid:{1}]上找不到云盘备份[uuid:{0}]", + "raw": "ceph primary storage[uuid:%s] may have been deleted.", + "en_US": "ceph primary storage[uuid:{0}] may have been deleted.", + "zh_CN": "分布式存储[uuid:{0}]可能已经被删除", "arguments": [ - "backupUuid", - "srcBackupStorageUuid" + "self.getUuid()" ], - "line": 1298, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 3410, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "No volume backups found with group uuid: %s", - "en_US": "No volume backups found with group uuid: {0}", - "zh_CN": "", + "raw": "unable to connect to the ceph primary storage[uuid:%s], failed to connect all ceph monitors.", + "en_US": "unable to connect to the ceph primary storage[uuid:{0}], failed to connect all ceph monitors.", + "zh_CN": "无法连接到分布式存储[uuid:{0}],所有监控节点均连接失败", "arguments": [ - "groupUuid" + "self.getUuid()" ], - "line": 1506, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 3394, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "Root volume missing within group uuid: %s", - "en_US": "Root volume missing within group uuid: {0}", - "zh_CN": "", + "raw": "the fsid returned by mons are mismatching, it seems the mons belong to different ceph clusters:\\n", + "en_US": "the fsid returned by mons are mismatching, it seems the mons belong to different ceph clusters:\\n", + "zh_CN": "监控节点返回的fsid不匹配,似乎监控节点属于不同的ceph集群", + "arguments": [], + "line": 3507, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + }, + { + "raw": "there is another CEPH primary storage[name:%s, uuid:%s] with the same FSID[%s], you cannot add the same CEPH setup as two different primary storage", + "en_US": "there is another CEPH primary storage[name:{0}, uuid:{1}] with the same FSID[{2}], you cannot add the same CEPH setup as two different primary storage", + "zh_CN": "有另外一个分布式存储[name:{0}, uuid:{1}] 有相同的 FSID[{2}],你不能添加相同的CEPH设置到两个不同的主存储", "arguments": [ - "groupUuid" + "otherCeph.getName()", + "otherCeph.getUuid()", + "fsId" ], - "line": 1513, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 3525, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "Multiple root volumes found within group uuid: %s", - "en_US": "Multiple root volumes found within group uuid: {0}", - "zh_CN": "", + "raw": "the ceph primary storage[uuid:%s, name:%s] is down, as one mon[uuid:%s] reports an operation failure[%s]", + "en_US": "the ceph primary storage[uuid:{0}, name:{1}] is down, as one mon[uuid:{2}] reports an operation failure[{3}]", + "zh_CN": "分布式存储[uuid:{0}, name:{1}]关闭,因为一个mon[uuid:{2}]报告了一个操作失败[{3}]", "arguments": [ - "groupUuid" + "self.getUuid()", + "self.getName()", + "mon.getSelf().getUuid()", + "res.error" ], - "line": 1519, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 3783, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "No permission to volume backups within group uuid: %s", - "en_US": "No permission to volume backups within group uuid: {0}", - "zh_CN": "", + "raw": "operation error, because: failed to get response", + "en_US": "operation error, because: failed to get response", + "zh_CN": "操作错误,原因:无法获取响应", + "arguments": [], + "line": 4697, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + }, + { + "raw": "backing up snapshots to backup storage is a depreciated feature, which will be removed in future version", + "en_US": "backing up snapshots to backup storage is a depreciated feature, which will be removed in future version", + "zh_CN": "将快照备份到备份存储是一项过时的功能,在未来版本中将被删除", + "arguments": [], + "line": 4744, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + }, + { + "raw": "cannot reinit rootvolume [%s] because image [%s] has been deleted and imagecache cannot be found", + "en_US": "cannot reinit rootvolume [{0}] because image [{1}] has been deleted and imagecache cannot be found", + "zh_CN": "无法重新初始化RootVolume[{0}],因为镜像[{1}]已被删除并且找不到ImageCache", "arguments": [ - "groupUuid" + "volume.getUuid()", + "volume.getRootImageUuid()" ], - "line": 1531, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 4915, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "Volume backup[uuid:%s] not found on any backup storage", - "en_US": "Volume backup[uuid:{0}] not found on any backup storage", - "zh_CN": "", + "raw": "Because image status is not %s", + "en_US": "Because image status is not {0}", + "zh_CN": "因为镜像状态不是{0}", "arguments": [ - "vo.getUuid()" + "ImageStatus.Ready.toString()" ], - "line": 1669, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 4950, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "degree [%s] should be a positive number", - "en_US": "degree [{0}] should be a positive number", - "zh_CN": "", + "raw": "Because the image is currently inaccessible, possibly due to a previous volume storage migration", + "en_US": "Because the image is currently inaccessible, possibly due to a previous volume storage migration", + "zh_CN": "因为镜像当前不可访问,可能是由于之前的卷存储迁移", + "arguments": [], + "line": 4947, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + }, + { + "raw": "cannot find backupstorage to download image [%s] to primarystorage [%s]. %s", + "en_US": "cannot find backupstorage to download image [{0}] to primarystorage [{1}]. {2}", + "zh_CN": "找不到用于将镜像[{0}]下载到主存储[{1}]的备份存储。{2}", "arguments": [ - "degree" + "volume.getRootImageUuid()", + "getSelf().getUuid()", + "cause" ], - "line": 2068, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 4953, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "invalid type[%s], should be [nfs]", - "en_US": "invalid type[{0}], should be [nfs]", - "zh_CN": "", + "raw": "allocated url not found", + "en_US": "allocated url not found", + "zh_CN": "未找到分配的URL", + "arguments": [], + "line": 5653, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + }, + { + "raw": "invalid allocated url:%s", + "en_US": "invalid allocated url:{0}", + "zh_CN": "分配的URL无效:{0}", "arguments": [ - "type" + "allocatedUrl" ], - "line": 2102, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 5658, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" }, { - "raw": "invalid url[%s], should be hostname:/path", - "en_US": "invalid url[{0}], should be hostname:/path", - "zh_CN": "", + "raw": "cannot find any Connected ceph mon for the primary storage[uuid:%s]", + "en_US": "cannot find any Connected ceph mon for the primary storage[uuid:{0}]", + "zh_CN": "无法为分布式存储[uuid:{0}]找到一台处于Connected状态的的监控节点", "arguments": [ - "url" + "vol.getPrimaryStorageUuid()" ], - "line": 2108, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java" + "line": 396, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "generate volume backup metadata file on image store[uuid:%s] failure, because IO error: %s", - "en_US": "generate volume backup metadata file on image store[uuid:{0}] failure, because IO error: {1}", - "zh_CN": "", + "raw": "ceph pool conflict, the ceph pool specified by the instance offering is %s, and the ceph pool specified in the creation parameter is %s", + "en_US": "ceph pool conflict, the ceph pool specified by the instance offering is {0}, and the ceph pool specified in the creation parameter is {1}", + "zh_CN": "Ceph池冲突,由实例提供的Ceph池指定为{0},而在创建参数中指定的Ceph池为{1}", "arguments": [ - "inv.getUuid()", - "e.getMessage()" + "targetCephPoolName", + "cephPoolName" ], - "line": 181, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java" + "line": 838, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "volume backup metadata operation failure, because %s", - "en_US": "volume backup metadata operation failure, because {0}", - "zh_CN": "", + "raw": "ceph pool conflict, the ceph pool specified by the disk offering is %s, and the ceph pool specified in the creation parameter is %s", + "en_US": "ceph pool conflict, the ceph pool specified by the disk offering is {0}, and the ceph pool specified in the creation parameter is {1}", + "zh_CN": "Ceph池冲突,磁盘产品指定的Ceph池为{0},而创建参数中指定的Ceph池为{1}", "arguments": [ - "rsp.getError()" + "targetCephPoolName", + "cephPoolName" ], - "line": 508, - "fileName": "src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java" + "line": 964, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "unable to connect to SimpleHttpBackupStorage[url:%s], because %s", - "en_US": "unable to connect to SimpleHttpBackupStorage[url:{0}], because {1}", - "zh_CN": "无法连接到SimpleHttpBackupStorage[url:{0}],因为{1}", + "raw": "get rootVolume[%s] rbd image watchers fail, %s", + "en_US": "get rootVolume[{0}] rbd image watchers fail, {1}", + "zh_CN": "查询云盘[{0}] rbd image watchers失败,{1}", "arguments": [ - "url", - "rsp.getError()" + "rootVolume.getInstallPath()", + "reply.getError().getDetails()" ], - "line": 271, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 1217, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "Missing cert file for downloading image: %s", - "en_US": "Missing cert file for downloading image: {0}", - "zh_CN": "下载镜像时证书文件丢失", + "raw": "rootVolume[%s] is already in use(ceph rbd image[%s] already has watchers), in order to prevent brain splitting, Starting VM is prohibited.", + "en_US": "rootVolume[{0}] is already in use(ceph rbd image[{1}] already has watchers), in order to prevent brain splitting, Starting VM is prohibited.", + "zh_CN": "云盘[{0}]正在使用中(ceph rbd 镜像[{1}]存在watchers),为了防止云主机脑裂,禁止启动云主机", "arguments": [ - "iinv.getName()" + "msg.getVolumeUuid()", + "installPath" ], - "line": 493, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 1233, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "image store service is temporary not available, because it is reclaiming space now", - "en_US": "image store service is temporary not available, because it is reclaiming space now", - "zh_CN": "", - "arguments": [], - "line": 622, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "raw": "cannot find cephPrimaryStorage pool[poolName\u003d%s]", + "en_US": "cannot find cephPrimaryStorage pool[poolName\u003d{0}]", + "zh_CN": "找不到CephPrimaryStorage池[PoolName\u003d{0}]", + "arguments": [ + "poolName" + ], + "line": 1341, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "No response", - "en_US": "No response", - "zh_CN": "无响应", - "arguments": [], - "line": 798, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "raw": "cephPrimaryStorage pool[poolName\u003d%s] available virtual capacity not enough for size %s", + "en_US": "cephPrimaryStorage pool[poolName\u003d{0}] available virtual capacity not enough for size {1}", + "zh_CN": "CephPrimary存储池[PoolName\u003d{0}]可用虚拟容量不足,无法满足大小{1}", + "arguments": [ + "poolName", + "volumeSize" + ], + "line": 1351, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "reclaim imagestore error, because:%s", - "en_US": "reclaim imagestore error, because:{0}", - "zh_CN": "收回imagestore错误,因为{0}", + "raw": "cannot allocate pool for primaryStorage[%s], purpose: %s", + "en_US": "cannot allocate pool for primaryStorage[{0}], purpose: {1}", + "zh_CN": "无法为主存储[{0}]分配池,目的:{1}", "arguments": [ - "ret.getError()" - ], - "line": 871, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "psUuid", + "purpose" + ], + "line": 1399, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" }, { - "raw": "failed to set max capacity on image store[uuid:%s], because: %s", - "en_US": "failed to set max capacity on image store[uuid:{0}], because: {1}", - "zh_CN": "", + "raw": "cannot update status of the ceph primary storage mon[uuid:%s], it has been deleted.This error can be ignored", + "en_US": "cannot update status of the ceph primary storage mon[uuid:{0}], it has been deleted.This error can be ignored", + "zh_CN": "不能更新一台已经被删除的Ceph主存储监控节点[uuid:{0}],这个错误可被忽略", "arguments": [ - "self.getUuid()", - "ret.getError()" + "uuid" ], - "line": 958, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 93, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java" }, { - "raw": "image[%s] not found on backup storage[%s]", - "en_US": "image[{0}] not found on backup storage[{1}]", - "zh_CN": "", + "raw": "Ceph ps[uuid\u003d%s] root pool name not found", + "en_US": "Ceph ps[uuid\u003d{0}] root pool name not found", + "zh_CN": "找不到Ceph PS[uuid\u003d{0}]根池名称", "arguments": [ - "msg.getImageUuid()", - "self.getUuid()" + "primaryStorageUuid" ], - "line": 1085, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 471, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java" }, { - "raw": "image store [%s] cannot add image, because it is used for backup remote", - "en_US": "image store [{0}] cannot add image, because it is used for backup remote", - "zh_CN": "ImageStore[{0}]不能添加镜像,因为它已经被远程镜像使用", + "raw": "invalid uri, correct example is ceph://$POOLNAME/$VOLUMEuuid or volume://$VOLUMEuuid", + "en_US": "invalid uri, correct example is ceph://$POOLNAME/$VOLUMEuuid or volume://$VOLUMEuuid", + "zh_CN": "URI无效,正确示例为ceph://$poolName/$volumeUuid或volume://$volumeUuid", "arguments": [], - "line": 1235, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 32, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephRequiredUrlParser.java" }, { - "raw": "commercial license is required to use ImageStore", - "en_US": "commercial license is required to use ImageStore", - "zh_CN": "使用ImageStore需要商业许可证", + "raw": "Can not attach third-party ceph with token into kvm cluster.", + "en_US": "Can not attach third-party ceph with token into kvm cluster.", + "zh_CN": "无法使用令牌将第三方Ceph连接到KVM集群。", "arguments": [], - "line": 1435, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 19, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java" }, { - "raw": "the uuid of imagestoreBackupStorage agent changed[expected:%s, actual:%s], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", - "en_US": "the uuid of imagestoreBackupStorage agent changed[expected:{0}, actual:{1}], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", - "zh_CN": "镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态", + "raw": "required ceph pool[uuid:%s] cannot satisfy conditions [availableSize \u003e %s bytes], current available size %s", + "en_US": "required ceph pool[uuid:{0}] cannot satisfy conditions [availableSize \u003e {1} bytes], current available size {2}", + "zh_CN": "所需的Ceph池[uuid:{0}]无法满足条件[AvailableSize\u003e{1}字节],当前可用大小{2}", "arguments": [ - "self.getUuid()", - "ret.getUuid()" + "poolUuid", + "size", + "originAvailableCapacity" ], - "line": 1468, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java" + "line": 168, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java" }, { - "raw": "hostname[%s] is neither an IPv4 address nor a valid hostname", - "en_US": "hostname[{0}] is neither an IPv4 address nor a valid hostname", - "zh_CN": "主机名[{0}]不是一个IPv4的地址,而是一个非法的主机名", + "raw": "cannot find ceph pool [%s] related osdgroup", + "en_US": "cannot find ceph pool [{0}] related osdgroup", + "zh_CN": "找不到Ceph池[{0}]相关的OSDGroup", "arguments": [ - "msg.getHostname()" + "poolUuid" ], - "line": 125, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 196, + "fileName": "src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java" }, { - "raw": "target backup storage[uuid:%s] already contains the image [uuid:%s]", - "en_US": "target backup storage[uuid:{0}] already contains the image [uuid:{1}]", - "zh_CN": "", + "raw": "no candidate host with the scsi lun with enough cpu / memory or Enabled/Connected status", + "en_US": "no candidate host with the scsi lun with enough cpu / memory or Enabled/Connected status", + "zh_CN": "需要的lun所在的物理机都不满足cpu / memory 以及物理机状态的条件", + "arguments": [], + "line": 95, + "fileName": "src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java" + }, + { + "raw": "scsi lun[uuid: %s] and [uuid: %s] does not has a common host", + "en_US": "scsi lun[uuid: {0}] and [uuid: {1}] does not has a common host", + "zh_CN": "SCSI Lun[uuid:{0}]和[uuid:{1}]没有共同的物理机", "arguments": [ - "bsUuid", - "imageUuid" + "firstScsiLunVO.getUuid()", + "scsiLunVO.getUuid()" ], - "line": 60, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 54, + "fileName": "src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java" }, { - "raw": "source backup storage[%s] doesn\u0027t contain image[%s]", - "en_US": "source backup storage[{0}] doesn\u0027t contain image[{1}]", - "zh_CN": "源镜像服务器[{0}]不包含该镜像[{1}]", + "raw": "scsi lun[uuid: %s] is in disabled state", + "en_US": "scsi lun[uuid: {0}] is in disabled state", + "zh_CN": "SCSI Lun[uuid:{0}]处于禁用状态", "arguments": [ - "msg.getSrcBackupStorageUuid()", - "msg.getUuid()" + "scsiLunVO.getUuid()" ], - "line": 79, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 59, + "fileName": "src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java" }, { - "raw": "src backupstorage[%s] doesn\u0027t contain image[%s]", - "en_US": "src backupstorage[{0}] doesn\u0027t contain image[{1}]", - "zh_CN": "", + "raw": "scsi lun[wwid: %s] has been attached to vm instance %s", + "en_US": "scsi lun[wwid: {0}] has been attached to vm instance {1}", + "zh_CN": "SCSI Lun[WWID:{0}]已连接到VM实例{1}", "arguments": [ - "msg.getSrcBackupStorageUuid()", - "msg.getUuid()" + "scsiLunVO.getWwid()", + "refVO.getVmInstanceUuid()" ], - "line": 94, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 150, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "duplicate backup storage. There has been an image store backup storage[hostname:%s]", - "en_US": "duplicate backup storage. There has been an image store backup storage[hostname:{0}]", - "zh_CN": "重复的镜像服务器。已经存在一个镜像服务器[主机名: {0}]", + "raw": "iSCSI server[ip: %s, port: %s] already exists", + "en_US": "iSCSI server[ip: {0}, port: {1}] already exists", + "zh_CN": "iSCSI服务器[IP:{0},端口:{1}]已存在", "arguments": [ - "msg.getHostname()" + "msg.getIp()", + "msg.getPort()" ], - "line": 142, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 86, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "file path needed", - "en_US": "file path needed", - "zh_CN": "需要文件路径", - "arguments": [], - "line": 147, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "raw": "iSCSI server ip: %s is not valid", + "en_US": "iSCSI server ip: {0} is not valid", + "zh_CN": "iSCSI服务器IP:{0}无效", + "arguments": [ + "msg.getIp()" + ], + "line": 91, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "absolute file path required: %s", - "en_US": "absolute file path required: {0}", - "zh_CN": "需要文件的绝对路径;{0}", + "raw": "iSCSI server[uuid: %s] already attached to cluster[uuid: %s]", + "en_US": "iSCSI server[uuid: {0}] already attached to cluster[uuid: {1}]", + "zh_CN": "iSCSI服务器[uuid:{0}]已连接到集群[uuid:{1}]", "arguments": [ - "dir" + "msg.getUuid()", + "msg.getClusterUuid()" ], - "line": 151, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 100, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "the url contains an invalid folder[/dev or /proc or /sys]", - "en_US": "the url contains an invalid folder[/dev or /proc or /sys]", - "zh_CN": "URL包含了一个无效的目录[/dev or /proc or /sys]", - "arguments": [], - "line": 154, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "raw": "iSCSI server[uuid: %s] not attached to cluster[uuid: %s]", + "en_US": "iSCSI server[uuid: {0}] not attached to cluster[uuid: {1}]", + "zh_CN": "iSCSI服务器[uuid:{0}]未连接到集群[uuid:{1}]", + "arguments": [ + "msg.getUuid()", + "msg.getClusterUuid()" + ], + "line": 110, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "file path contains invalid character: %s", - "en_US": "file path contains invalid character: {0}", - "zh_CN": "文件路径包含非法字符: {0}", + "raw": "iSCSI server[uuid: %s] still attached to cluster[uuid: %s]", + "en_US": "iSCSI server[uuid: {0}] still attached to cluster[uuid: {1}]", + "zh_CN": "iSCSI服务器[uuid:{0}]仍连接到集群[uuid:{1}]", "arguments": [ - "dir" + "msg.getUuid()", + "clusterUuid" ], - "line": 162, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java" + "line": 121, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "cannot find a connected host in cluster to which PS [uuid: %s] attached", - "en_US": "cannot find a connected host in cluster to which PS [uuid: {0}] attached", - "zh_CN": "", + "raw": "please umount all block devices of the vm[%s] and try again", + "en_US": "please umount all block devices of the vm[{0}] and try again", + "zh_CN": "请卸载云主机[{0}]的所有块设备,然后重试", "arguments": [ - "ps.getUuid()" + "VmInstanceUuid" ], - "line": 188, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageExtension.java" + "line": 171, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" }, { - "raw": "invalid url[%s], the url must be an absolute path starting with \u0027/\u0027", - "en_US": "invalid url[{0}], the url must be an absolute path starting with \u0027/\u0027", - "zh_CN": "无效的url[{0}],url必须是以\u0027/\u0027开头的绝对路径", + "raw": "scsi lun[wwid:%s] has been attached into the vm[%s]", + "en_US": "scsi lun[wwid:{0}] has been attached into the vm[{1}]", + "zh_CN": "SCSI Lun[WWID:{0}]已连接到云主机[{1}]", "arguments": [ - "amsg.getUrl()" + "lunVO.getWwid()", + "msg.getVmInstanceUuid()" ], - "line": 142, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" + "line": 1501, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "existing SimpleHttpBackupStorage with hostname[%s] found", - "en_US": "existing SimpleHttpBackupStorage with hostname[{0}] found", - "zh_CN": "存在主机名为[{0}]的简单http镜像服务器", + "raw": "vm instance[%s] state [%s] not in allowed state[%s] for operation", + "en_US": "vm instance[{0}] state [{1}] not in allowed state[{2}] for operation", + "zh_CN": "VM实例[{0}]状态[{1}]不处于操作的允许状态[{2}]", "arguments": [ - "hostname" + "msg.getUuid()", + "vmInstanceVO.getState()", + "allowedVmOperationStates" ], - "line": 151, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" + "line": 1508, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "ansible mkdir failed, due to: %s", - "en_US": "ansible mkdir failed, due to: {0}", - "zh_CN": "Ansible创建目录失败,因为{0}", + "raw": "vm instance[uuid: %s] host[uuid: %s] not attached scsi lun[uuid: %s]", + "en_US": "vm instance[uuid: {0}] host[uuid: {1}] not attached scsi lun[uuid: {2}]", + "zh_CN": "云主机实例[uuid:{0}]物理机[uuid:{1}]未连接scsi lun[uuid:{2}]", "arguments": [ - "result.getStderr()" + "msg.getUuid()", + "vmInstanceVO.getHostUuid()", + "msg.getUuid()" ], - "line": 100, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" + "line": 1517, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "ansible failed, due to: %s", - "en_US": "ansible failed, due to: {0}", - "zh_CN": "Ansible失败,因为{0}", + "raw": "vm instance[%s] state[%s] not in allowed state[%s] for operation", + "en_US": "vm instance[{0}] state[{1}] not in allowed state[{2}] for operation", + "zh_CN": "VM实例[{0}]状态[{1}]不处于操作的允许状态[{2}]", "arguments": [ - "result.getStderr()" + "msg.getVmInstanceUuid()", + "vmInstanceVO.getState()", + "allowedVmOperationStates" ], - "line": 112, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" + "line": 1576, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "ansible attach nas failed, due to: %s", - "en_US": "ansible attach nas failed, due to: {0}", - "zh_CN": "Ansible绑定失败,因为{0}", + "raw": "vm instance[%s] host[uuid: %s] not attached scsi lun[uuid: %s]", + "en_US": "vm instance[{0}] host[uuid: {1}] not attached scsi lun[uuid: {2}]", + "zh_CN": "云主机实例[{0}]物理机[uuid:{1}]未连接SCSI Lun[uuid:{2}]", "arguments": [ - "result.getStdout()" + "msg.getVmInstanceUuid()", + "hostVO.getUuid()", + "msg.getUuid()" ], - "line": 110, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java" + "line": 1585, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "create tmp file [%s] failed, due to: %s", - "en_US": "create tmp file [{0}] failed, due to: {1}", - "zh_CN": "创建tmp文件[{0}]失败,因为{1}", + "raw": "SCSI LUN[%s] is attached to VM [%s]", + "en_US": "SCSI LUN[{0}] is attached to VM [{1}]", + "zh_CN": "SCSI Lun[{0}]已连接到云主机[{1}]", "arguments": [ - "tmpHostFile", - "result.getStderr()" + "msg.getUuid()", + "vmUuids" ], - "line": 395, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java" + "line": 1738, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "sync status failed.", - "en_US": "sync status failed.", - "zh_CN": "同步失败", - "arguments": [], - "line": 229, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java" + "raw": "SCSI LUN[%s] record not found on host [%s]", + "en_US": "SCSI LUN[{0}] record not found on host [{1}]", + "zh_CN": "在物理机[{1}]上未找到SCSI Lun[{0}]记录", + "arguments": [ + "msg.getUuid()", + "msg.getHostUuid()" + ], + "line": 1748, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "delete image metadata file failed: %s", - "en_US": "delete image metadata file failed: {0}", - "zh_CN": "删除镜像元数据文件失败: {0}", + "raw": "unexpected hypervisor type[%s] for host [%s]", + "en_US": "unexpected hypervisor type[{0}] for host [{1}]", + "zh_CN": "物理机[{1}]的意外云主机监控程序类型[{0}]", "arguments": [ - "rsp.getError()" + "hvType", + "msg.getHostUuid()" ], - "line": 806, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" + "line": 1760, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "AddImage is forbidden in Disaster BS: [%s]", - "en_US": "AddImage is forbidden in Disaster BS: [{0}]", - "zh_CN": "在Disaster镜像服务器中添加镜像是被禁止的", + "raw": "different disk types are found in different hosts for lun[serial:%s], unable to attach it to cluster", + "en_US": "different disk types are found in different hosts for lun[serial:{0}], unable to attach it to cluster", + "zh_CN": "在不同的物理机中为Lun[serial:{0}]找到不同的磁盘类型,无法将其连接到集群", "arguments": [ - "bsUuid" + "serial" ], - "line": 389, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" + "line": 2024, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + }, + { + "raw": "different iscsi configuration were found on host[uuid:%s, targets:%s]and host[uuid:%s, targets:%s]", + "en_US": "different iscsi configuration were found on host[uuid:{0}, targets:{1}]and host[uuid:{2}, targets:{3}]", + "zh_CN": "在物理机[uuid:{0},目标:{1}]和物理机[uuid:{2},目标:{3}]上找到不同的iSCSI配置", + "arguments": [ + "scannedServer.getKey()", + "JSONObjectUtil.toJsonString(scannedTargets)", + "hostVO.getUuid()", + "JSONObjectUtil.toJsonString(returnValue.getIscsiTargets())" + ], + "line": 1975, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "Check image metadata file: %s failed", - "en_US": "Check image metadata file: {0} failed", - "zh_CN": "检查镜像元数据文件: {0}失败", + "raw": "specified scsi lun[wwid: %s] not exists or disabled", + "en_US": "specified scsi lun[wwid: {0}] not exists or disabled", + "zh_CN": "指定的SCSI Lun[WWID:{0}]不存在或已禁用", "arguments": [ - "rsp.getBackupStorageMetaFileName()" + "refVO.getScsiLunUuid()" ], - "line": 735, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" + "line": 2661, + "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" }, { - "raw": "Create image metadata file : %s failed", - "en_US": "Create image metadata file : {0} failed", - "zh_CN": "创建镜像元数据文件: {0}失败", + "raw": "the vm where the data volume [%s] is located has a memory snapshot, can\u0027t delete", + "en_US": "the vm where the data volume [{0}] is located has a memory snapshot, can\u0027t delete", + "zh_CN": "数据云盘[{0}]所在的云主机具有内存快照,无法删除", "arguments": [ - "rsp.getBackupStorageMetaFileName()" + "msg.getVolumeUuid()" ], - "line": 563, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" + "line": 60, + "fileName": "src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java" }, { - "raw": "Create image metadata file sync : %s failed", - "en_US": "Create image metadata file sync : {0} failed", - "zh_CN": "同步创建镜像元数据文件{0}失败了", + "raw": "unable to attach volume %s to vmInstance %s with memory snapshot group", + "en_US": "unable to attach volume {0} to vmInstance {1} with memory snapshot group", + "zh_CN": "无法使用内存快照组将卷{0}附加到VMInstance{1}", "arguments": [ - "rsp.getBackupStorageMetaFileName()" + "msg.getVolumeUuid()", + "msg.getVmInstanceUuid()" ], - "line": 538, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java" + "line": 71, + "fileName": "src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java" }, { - "raw": "parse create time error: %s", - "en_US": "parse create time error: {0}", - "zh_CN": "解析创建时间出错: {0}", + "raw": "the vm where the data volume [%s] is located has a memory snapshot, can\u0027t detach", + "en_US": "the vm where the data volume [{0}] is located has a memory snapshot, can\u0027t detach", + "zh_CN": "数据云盘[{0}]所在的VM具有内存快照,无法分离", "arguments": [ - "e.getMessage()" + "msg.getVolumeUuid()" ], - "line": 79, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ImageStoreImageStruct.java" + "line": 78, + "fileName": "src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java" }, { - "raw": "Cancel operation is not supported", - "en_US": "Cancel operation is not supported", - "zh_CN": "", + "raw": "defaultL3NetworkUuid not exist", + "en_US": "defaultL3NetworkUuid not exist", + "zh_CN": "defaultL3NetworkUuid不存在", "arguments": [], - "line": 62, - "fileName": "src/main/java/org/zstack/storage/backup/imagestore/ReclaimSpaceFromImageStoreLongJob.java" + "line": 60, + "fileName": "src/main/java/org/zstack/storage/memorySnapshot/VmNicMemorySnapshotGroupExtension.java" }, { - "raw": "SftpBackupStorage doesn\u0027t support scheme[%s] in url[%s]", - "en_US": "SftpBackupStorage doesn\u0027t support scheme[{0}] in url[{1}]", - "zh_CN": "Sftp镜像服务器不支持在url[{1}]里包含scheme[{0}]", + "raw": "nic with l3 network[uuid: %s] is referenced by VolumeSnapshotGroup[uuid: %s], delete this VolumeSnapshotGroup before deleting this l3 network.", + "en_US": "nic with l3 network[uuid: {0}] is referenced by VolumeSnapshotGroup[uuid: {1}], delete this VolumeSnapshotGroup before deleting this l3 network.", + "zh_CN": "具有三层网络[uuid:{0}]的NIC由卷SnapshotGroup[uuid:{1}]引用,请在删除此三层网络之前删除此卷SnapshotGroup。", "arguments": [ - "scheme", - "url" + "l3Uuid", + "String.join(\"\u0027,\u0027\", memorySnapshotGroupUuidList)" ], - "line": 105, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" + "line": 432, + "fileName": "src/main/java/org/zstack/storage/memorySnapshot/VmNicMemorySnapshotGroupExtension.java" }, { - "raw": "fail to download image, because %s", - "en_US": "fail to download image, because {0}", - "zh_CN": "下载镜像失败,因为{0}", + "raw": "the volume %s does not exist", + "en_US": "the volume {0} does not exist", + "zh_CN": "卷{0}不存在", "arguments": [ - "ret.getError()" + "archiveVolume.getResourceUuid()" ], - "line": 133, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" + "line": 155, + "fileName": "src/main/java/org/zstack/storage/memorySnapshot/VolumeMemorySnapshotGroupExtension.java" }, { - "raw": "fail to cancel download image, because %s", - "en_US": "fail to cancel download image, because {0}", - "zh_CN": "", + "raw": "vm block migrate failed: %s", + "en_US": "vm block migrate failed: {0}", + "zh_CN": "VM块迁移失败:{0}", "arguments": [ "rsp.getError()" ], - "line": 233, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" + "line": 161, + "fileName": "src/main/java/org/zstack/storage/migration/KvmBlockLiveMigrationWorkFlow.java" }, { - "raw": "the uuid of sftpBackupStorage agent changed[expected:%s, actual:%s], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", - "en_US": "the uuid of sftpBackupStorage agent changed[expected:{0}, actual:{1}], it\u0027s most likely the agent was manually restarted. Issue a reconnect to sync the status", - "zh_CN": "Sftp镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态", - "arguments": [ - "self.getUuid()", - "ret.getUuid()" - ], - "line": 307, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java" + "raw": "target primary storage does not support migration for current host", + "en_US": "target primary storage does not support migration for current host", + "zh_CN": "目标主存储不支持当前物理机的迁移", + "arguments": [], + "line": 188, + "fileName": "src/main/java/org/zstack/storage/migration/KvmBlockLiveMigrationWorkFlow.java" }, { - "raw": "Please stop the vm before create volume template to sftp backup storage %s", - "en_US": "Please stop the vm before create volume template to sftp backup storage {0}", - "zh_CN": "", - "arguments": [ - "bsUuid" - ], - "line": 70, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java" + "raw": "No host available for block live migration", + "en_US": "No host available for block live migration", + "zh_CN": "没有可用于数据块实时迁移的物理机", + "arguments": [], + "line": 116, + "fileName": "src/main/java/org/zstack/storage/migration/KvmMigrateVmWithStorageWorkFlow.java" }, { - "raw": "duplicate backup storage. There has been a sftp backup storage[hostname:%s] existing", - "en_US": "duplicate backup storage. There has been a sftp backup storage[hostname:{0}] existing", - "zh_CN": "重复的镜像服务器。已经存在一个镜像服务器[主机名: {0}]", - "arguments": [ - "msg.getHostname()" - ], - "line": 106, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java" + "raw": "do not support storage migration with iso in ceph backup storage attached", + "en_US": "do not support storage migration with iso in ceph backup storage attached", + "zh_CN": "不支持Ceph备份存储中附加ISO的存储迁移", + "arguments": [], + "line": 121, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "check image metadata file: %s failed", - "en_US": "check image metadata file: {0} failed", - "zh_CN": "检查镜像元数据文件: {0}失败", + "raw": "do not support storage migration of vm[uuid:%s, name: %s] while shared volume attached", + "en_US": "do not support storage migration of vm[uuid:{0}, name: {1}] while shared volume attached", + "zh_CN": "连接共享云盘时,不支持VM[uuid:{0},名称:{1}]的存储迁移", "arguments": [ - "rsp.getBackupStorageMetaFileName()" + "srcVm.getUuid()", + "srcVm.getName()" ], - "line": 543, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java" + "line": 289, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "create image metadata file : %s failed", - "en_US": "create image metadata file : {0} failed", - "zh_CN": "创建镜像元数据文件: {0}失败", + "raw": "do not support storage migration from [%s] to [%s] with data volume", + "en_US": "do not support storage migration from [{0}] to [{1}] with data volume", + "zh_CN": "不支持从[{0}]到[{1}]的带数据盘的存储迁移", "arguments": [ - "rsp.getBackupStorageMetaFileName()" + "srcPsType", + "dstPsType" ], - "line": 392, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java" + "line": 173, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "image metadata file: %s is not exist", - "en_US": "image metadata file: {0} is not exist", - "zh_CN": "镜像元数据文件: {0}不存在", + "raw": "do not support storage migration from [%s] to [%s] with snapshot", + "en_US": "do not support storage migration from [{0}] to [{1}] with snapshot", + "zh_CN": "不支持从[{0}]到[{1}]的存在云盘快照的存储迁移", "arguments": [ - "rsp.getBackupStorageMetaFileName()" + "srcPsType", + "dstPsType" ], - "line": 548, - "fileName": "src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java" + "line": 178, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "operation failure, because the poolName[poolName:%s] can not include unprintable ascii characters.", - "en_US": "operation failure, because the poolName[poolName:{0}] can not include unprintable ascii characters.", - "zh_CN": "操作失败,因为pool名称[poolName:{0}]不能包含中文和特殊字符", + "raw": "do not support storage migration from [%s] to [%s]", + "en_US": "do not support storage migration from [{0}] to [{1}]", + "zh_CN": "不支持从[{0}]到[{1}]的存储迁移", "arguments": [ - "msg.getPoolName()" + "primaryStorageVO.getType()", + "dstPrimaryStorageVO.getType()" ], - "line": 77, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "line": 185, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "Ceph pool[uuid:%s] with this name is already added into ZStack and used elsewhere, cannot reuse the ceph pool.", - "en_US": "Ceph pool[uuid:{0}] with this name is already added into ZStack and used elsewhere, cannot reuse the ceph pool.", - "zh_CN": "池名称为此的扩展池[uuid:{0}]已经被添加进 ZStack 了,已做它用,不能复用该扩展池", + "raw": "VM[uuid:%s] is running but host uuid is missing", + "en_US": "VM[uuid:{0}] is running but host uuid is missing", + "zh_CN": "云主机[uuid:{0}]正在运行,但缺少物理机uuid", "arguments": [ - "duplicatePoolUuid" + "vmInstanceVO.getUuid()" ], - "line": 91, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "line": 191, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "creation failure, duplicate poolName[%s]. There has been a pool[uuid:%s] with the same name existing.", - "en_US": "creation failure, duplicate poolName[{0}]. There has been a pool[uuid:{1}] with the same name existing.", - "zh_CN": "创建失败,重复的池名称[{0}]。已经有一个相同名称的扩展池[uuid:{1}]存在", - "arguments": [ - "msg.getPoolName()", - "duplicatePoolUuid" - ], - "line": 86, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "raw": "Source BS and Destination BS cannot be the same.", + "en_US": "Source BS and Destination BS cannot be the same.", + "zh_CN": "源镜像服务器和目标镜像服务器不能相同", + "arguments": [], + "line": 202, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "cannot add ceph primary storage, there has been some ceph primary storage using mon[hostnames:%s]", - "en_US": "cannot add ceph primary storage, there has been some ceph primary storage using mon[hostnames:{0}]", - "zh_CN": "无法添加ceph主存储,一定有某些ceph主存储使用了mon[主机名: {0}]", + "raw": "Source BS and Destination BS must not be Disabled.", + "en_US": "Source BS and Destination BS must not be Disabled.", + "zh_CN": "源镜像服务器和目标镜像服务器必须不是不可用。", + "arguments": [], + "line": 210, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + }, + { + "raw": "Image[uuid:%s] is not in status Ready, cannot migrate it.", + "en_US": "Image[uuid:{0}] is not in status Ready, cannot migrate it.", + "zh_CN": "镜像[uuid:{0}]的状态不是已准备,不能迁移它", "arguments": [ - "existing" + "msg.getImageUuid()" ], - "line": 119, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "line": 217, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "Cannot add same host[%s] in mons", - "en_US": "Cannot add same host[{0}] in mons", - "zh_CN": "在mon中无法添加相同的物理机[{0}]", + "raw": "Image[uuid:%s] is not in source backup storage[uuid:%s]", + "en_US": "Image[uuid:{0}] is not in source backup storage[uuid:{1}]", + "zh_CN": "镜像[uuid:{0}]没有在源镜像服务器[uuid:{1}]", "arguments": [ - "uri.getHostname()" + "msg.getImageUuid()", + "msg.getSrcBackupStorageUuid()" ], - "line": 130, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "line": 228, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "Adding the same Mon node is not allowed", - "en_US": "Adding the same Mon node is not allowed", - "zh_CN": "添加相同的Mon节点不被允许", - "arguments": [], - "line": 156, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "raw": "Cannot migrate image from %s to %s.", + "en_US": "Cannot migrate image from {0} to {1}.", + "zh_CN": "不能从{0}迁移镜像到{1}", + "arguments": [ + "srcBS.getType()", + "dstBS.getType()" + ], + "line": 237, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "cannot add ceph backup storage, there has been some ceph backup storage using mon[hostnames:%s]", - "en_US": "cannot add ceph backup storage, there has been some ceph backup storage using mon[hostnames:{0}]", - "zh_CN": "无法添加ceph镜像服务器,已经有某个ceph镜像服务器使用mon[主机名: {0}]", + "raw": "Volume[uuid:%s] is already in PS[uuid:%s], cannot migrate.", + "en_US": "Volume[uuid:{0}] is already in PS[uuid:{1}], cannot migrate.", + "zh_CN": "云盘[uuid:{0}]已经在主存储[uuid:{1}]里,不能迁移。", "arguments": [ - "existing" + "msg.getVolumeUuid()", + "msg.getDstPrimaryStorageUuid()" ], - "line": 235, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "line": 256, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "poolName is required when importImages is true", - "en_US": "poolName is required when importImages is true", - "zh_CN": "当importImages为真的时候必须填写池名", + "raw": "Source PS and Destination PS must not be Disabled or Maintenance state.", + "en_US": "Source PS and Destination PS must not be Disabled or Maintenance state.", + "zh_CN": "源主存储和目标主存储必须不是不可用或者维护状态。", "arguments": [], - "line": 243, - "fileName": "src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java" + "line": 264, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "The problem may be caused by an incorrect user name or password or SSH port or unstable network environment", - "en_US": "The problem may be caused by an incorrect user name or password or SSH port or unstable network environment", - "zh_CN": "该问题可能是由不正确的用户名、密码、SSH端口或者不稳定的网络环境引起的", - "arguments": [], - "line": 66, - "fileName": "src/main/java/org/zstack/storage/ceph/CephMonBase.java" + "raw": "Volume[uuid:%s] is not in status Ready, cannot migrate it.", + "en_US": "Volume[uuid:{0}] is not in status Ready, cannot migrate it.", + "zh_CN": "云盘[uuid:{0}]状态不是已准备,不能进行迁移", + "arguments": [ + "msg.getVolumeUuid()" + ], + "line": 271, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "CephMon[hostname:%s] not found on backup storage[uuid:%s]", - "en_US": "CephMon[hostname:{0}] not found on backup storage[uuid:{1}]", - "zh_CN": "", + "raw": "cannot migrate data volume[uuid:%s] bewteen sharedblock primary storages when vm[vmuuid:%s] instance is not stopped.", + "en_US": "cannot migrate data volume[uuid:{0}] bewteen sharedblock primary storages when vm[vmuuid:{1}] instance is not stopped.", + "zh_CN": "VM[vmuuid:{1}]实例未停止时,无法在SharedBlock主存储之间迁移数据云盘[uuid:{0}]。", "arguments": [ - "msg.getHostname()", - "msg.getBackupStorageUuid()" + "msg.getVolumeUuid()", + "srcVolume.getVmInstanceUuid()" ], - "line": 834, - "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" + "line": 333, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "unable to connect to the ceph backup storage[uuid:%s]. Failed to connect all ceph mons. Errors are %s", - "en_US": "unable to connect to the ceph backup storage[uuid:{0}]. Failed to connect all ceph mons. Errors are {1}", - "zh_CN": "无法连接到ceph镜像服务器[uuid:{0}]。所有监控节点均无法连接。错误是{1}", + "raw": "the volume[uuid:%s] is still attached on vm[uuid:%s], please detach it before migration.", + "en_US": "the volume[uuid:{0}] is still attached on vm[uuid:{1}], please detach it before migration.", + "zh_CN": "云盘[uuid:{0}]一直连接在云主机[uuid:{1}],在迁移之前请先断开连接", "arguments": [ - "self.getUuid()", - "JSONObjectUtil.toJsonString(errorCodes)" + "msg.getVolumeUuid()", + "srcVolume.getVmInstanceUuid()" ], - "line": 1218, - "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" + "line": 328, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "there is another CEPH backup storage[name:%s, uuid:%s] with the same FSID[%s], you cannot add the same CEPH setup as two different backup storage", - "en_US": "there is another CEPH backup storage[name:{0}, uuid:{1}] with the same FSID[{2}], you cannot add the same CEPH setup as two different backup storage", - "zh_CN": "有另外一个CEPH镜像服务器[name:{0}, uuid:{1}]有相同的FSID[{2}],你不能添加同样的CEPH为两个不同的镜像服务器", + "raw": "do not support storage migration while shared volume[uuid: %s, name: %s] attached", + "en_US": "do not support storage migration while shared volume[uuid: {0}, name: {1}] attached", + "zh_CN": "加载了共享云盘[uuid:{0}, name:{1}]不支持存储迁移", "arguments": [ - "otherCeph.getName()", - "otherCeph.getUuid()", - "fsId" + "srcVolume.getUuid()", + "srcVolume.getName()" ], - "line": 1339, - "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java" + "line": 341, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "cannot update status of the ceph backup storage mon[uuid:%s], it has been deleted.This error can be ignored", - "en_US": "cannot update status of the ceph backup storage mon[uuid:{0}], it has been deleted.This error can be ignored", - "zh_CN": "无法更新ceph镜像服务器监控节点[uuid:{0}],他已经被删除。这个错误可以被忽略", + "raw": "Cannot migrate root volume when vm instance is not stopped.", + "en_US": "Cannot migrate root volume when vm instance is not stopped.", + "zh_CN": "当云主机不是已停止,不能迁移云盘。", + "arguments": [], + "line": 284, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + }, + { + "raw": "Cannot migrate root volume when there are data volumes attached to the vm instance.", + "en_US": "Cannot migrate root volume when there are data volumes attached to the vm instance.", + "zh_CN": "当云盘连接在云主机上时,不能迁移云盘", + "arguments": [], + "line": 301, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + }, + { + "raw": "The destination primary storage is not attached to any cluster that has the same L2 networks as source cluster.", + "en_US": "The destination primary storage is not attached to any cluster that has the same L2 networks as source cluster.", + "zh_CN": "目标主存储不能连接任何和源集群一样的二层网络的集群", + "arguments": [], + "line": 320, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + }, + { + "raw": "Cannot migrate volume from %s to %s.", + "en_US": "Cannot migrate volume from {0} to {1}.", + "zh_CN": "不能从{0}迁移云盘到{1}", "arguments": [ - "uuid" + "srcPS.getType()", + "dstPS.getType()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java" + "line": 351, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "the backup storage[uuid:%s, name:%s, fsid:%s] is not in the same ceph cluster with the primary storage[uuid:%s, name:%s, fsid:%s]", - "en_US": "the backup storage[uuid:{0}, name:{1}, fsid:{2}] is not in the same ceph cluster with the primary storage[uuid:{3}, name:{4}, fsid:{5}]", - "zh_CN": "镜像服务器[uuid:{0}, name:{1}, fsid:{2}]和主存储[uuid:{3}, name:{4}, fsid:{5}]不在同一个ceph集群中", + "raw": "can not migrate volume[%s], because volume state is Disabled", + "en_US": "can not migrate volume[{0}], because volume state is Disabled", + "zh_CN": "无法迁移卷[{0}],因为卷状态已禁用", "arguments": [ - "backupStorage.getUuid()", - "backupStorage.getName()", - "bsFsid", - "self.getUuid()", - "self.getName()", - "getSelf().getFsid()" + "msg.getVolumeUuid()" ], - "line": 1283, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 372, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" }, { - "raw": "cannot find cephPrimaryStorage pool[poolName\u003d%s]", - "en_US": "cannot find cephPrimaryStorage pool[poolName\u003d{0}]", - "zh_CN": "", + "raw": "not support vm state[%s] to do storage migration", + "en_US": "not support vm state[{0}] to do storage migration", + "zh_CN": "云主机状态为[{0}],无法进行存储迁移", "arguments": [ - "poolName" + "vmInstanceVO.getState()" ], - "line": 1477, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 510, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "cephPrimaryStorage pool[poolName\u003d%s] available capacity not enough", - "en_US": "cephPrimaryStorage pool[poolName\u003d{0}] available capacity not enough", - "zh_CN": "", + "raw": "there are not enough capacity for vm[uuid: %s] storage migration, required capacity(include image cache): %s, current available physical capacity: %s", + "en_US": "there are not enough capacity for vm[uuid: {0}] storage migration, required capacity(include image cache): {1}, current available physical capacity: {2}", + "zh_CN": "对云主机[uuid: {0}]存储迁移需要目标主存储具有至少{1}的空余容量(容量计算包含镜像cache),但现在只有{2}的空余容量", "arguments": [ - "poolName" + "msg.getVmInstanceUuid()", + "size", + "dstPrimaryStorageVO.getCapacity().getAvailablePhysicalCapacity()" ], - "line": 1483, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 448, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "fsid is not same between ps[%s] and bs[%s], create template is forbidden.", - "en_US": "fsid is not same between ps[{0}] and bs[{1}], create template is forbidden.", - "zh_CN": "在主存储和镜像服务器中fsid不是一样的,禁止创建模版。", + "raw": "VM[uuid: %s] not found", + "en_US": "VM[uuid: {0}] not found", + "zh_CN": "找不到VM[uuid:{0}]", "arguments": [ - "psUuid", - "bsUuid" + "msg.getVmInstanceUuid()" ], - "line": 2303, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 1125, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "ceph primary storage[uuid:%s] may have been deleted.", - "en_US": "ceph primary storage[uuid:{0}] may have been deleted.", - "zh_CN": "Ceph主存储[uuid:{0}]可能已经被删除", + "raw": "unsupported storage migration type: from %s to %s", + "en_US": "unsupported storage migration type: from {0} to {1}", + "zh_CN": "不支持的存储迁移类型:从{0}到{1}", "arguments": [ - "self.getUuid()" + "srcPs.getType()", + "dstPs.getType()" ], - "line": 2762, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 846, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "unable to connect to the ceph primary storage[uuid:%s]. Failed to connect all ceph mons. Errors are %s", - "en_US": "unable to connect to the ceph primary storage[uuid:{0}]. Failed to connect all ceph mons. Errors are {1}", - "zh_CN": "无法连接到ceph主存储[uuid:{0}]。所有监控节点均连接失败。错误是{1}", + "raw": "not support to cancel %s", + "en_US": "not support to cancel {0}", + "zh_CN": "不支持取消{0}", "arguments": [ - "self.getUuid()", - "JSONObjectUtil.toJsonString(errorCodes)" + "msg.getType()" ], - "line": 2749, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 1094, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "unable to connect to the ceph primary storage[uuid:%s]. Failed to connect all ceph mons.", - "en_US": "unable to connect to the ceph primary storage[uuid:{0}]. Failed to connect all ceph mons.", - "zh_CN": "未能连接ceph主存储[uuid:{0}],连接所有的ceph mons失败", + "raw": "not support vm state[%s] to do cancellation of storage migration", + "en_US": "not support vm state[{0}] to do cancellation of storage migration", + "zh_CN": "不支持云主机状态[{0}]取消存储迁移", "arguments": [ - "self.getUuid()" + "vmInstanceVO.getState()" ], - "line": 2746, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 1194, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "the fsid returned by mons are mismatching, it seems the mons belong to different ceph clusters:\\n", - "en_US": "the fsid returned by mons are mismatching, it seems the mons belong to different ceph clusters:\\n", - "zh_CN": "监控节点返回的fsid不匹配,似乎监控节点属于不同的ceph集群", + "raw": "failed to get host candidates for vm migration", + "en_US": "failed to get host candidates for vm migration", + "zh_CN": "无法获取云主机迁移的候选物理机", "arguments": [], - "line": 2866, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 1514, + "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" }, { - "raw": "there is another CEPH primary storage[name:%s, uuid:%s] with the same FSID[%s], you cannot add the same CEPH setup as two different primary storage", - "en_US": "there is another CEPH primary storage[name:{0}, uuid:{1}] with the same FSID[{2}], you cannot add the same CEPH setup as two different primary storage", - "zh_CN": "有另外一个CEPH主存储[name:{0}, uuid:{1}] 有相同的 FSID[{2}],你不能添加相同的CEPH设置到两个不同的主存储", + "raw": "all ceph mons are Disconnected in ceph backup storage[uuid:%s]", + "en_US": "all ceph mons are Disconnected in ceph backup storage[uuid:{0}]", + "zh_CN": "所有在Ceph镜像服务器监控节点[uuid:{0}]的监控节点都处于失联状态", "arguments": [ - "otherCeph.getName()", - "otherCeph.getUuid()", - "fsId" + "dstBsVO.getUuid()" ], - "line": 2884, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 114, + "fileName": "src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java" }, { - "raw": "the ceph primary storage[uuid:%s, name:%s] is down, as one mon[uuid:%s] reports an operation failure[%s]", - "en_US": "the ceph primary storage[uuid:{0}, name:{1}] is down, as one mon[uuid:{2}] reports an operation failure[{3}]", - "zh_CN": "ceph主存储[uuid:{0}, name:{1}]关闭,因为一个mon[uuid:{2}]报告了一个操作失败[{3}]", + "raw": "Failed to migrate Image %s from BS %s to BS %s. cause: %s", + "en_US": "Failed to migrate Image {0} from BS {1} to BS {2}. cause: {3}", + "zh_CN": "无法将镜像{0}从BS{1}迁移到BS{2}。原因:{3}", "arguments": [ - "self.getUuid()", - "self.getName()", - "mon.getSelf().getUuid()", - "res.error" + "imageUuid", + "srcBsUuid", + "dstBsUuid", + "errCode.getDetails()" ], - "line": 3135, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 187, + "fileName": "src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java" }, { - "raw": "unable to upload bits to the backup storage[type:%s], we only support CEPH", - "en_US": "unable to upload bits to the backup storage[type:{0}], we only support CEPH", - "zh_CN": "不能上传bits到镜像服务器[type:{0}],目前只支持CEPH", + "raw": "found trashId(%s) in BackupStorage [%s] for the migrate installPath[%s]. Please clean it first by \u0027APICleanUpTrashOnBackupStorageMsg\u0027 if you insist to migrate the image[%s]", + "en_US": "found trashId({0}) in BackupStorage [{1}] for the migrate installPath[{2}]. Please clean it first by \u0027APICleanUpTrashOnBackupStorageMsg\u0027 if you insist to migrate the image[{3}]", + "zh_CN": "在备份存储[{1}]的回收数据({0})中己存在要迁移的目标路径[{2}],如果要继续迁移镜像[{3}],请先调用\u0027APICleanUpTrashOnBackupStorageMsg\u0027来手动清理该回收数据", "arguments": [ - "bsType" + "reply1.getTrashId()", + "dstBsUuid", + "dstImageInstallPath", + "reply1.getResourceUuid()" ], - "line": 3736, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 143, + "fileName": "src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java" }, { - "raw": "cannot reinit rootvolume [%s] because image [%s] has been deleted and imagecache cannot be found", - "en_US": "cannot reinit rootvolume [{0}] because image [{1}] has been deleted and imagecache cannot be found", - "zh_CN": "", + "raw": "vm[uuid:%s] storage migration long job[uuid:%s] failed because management node was restarted", + "en_US": "vm[uuid:{0}] storage migration long job[uuid:{1}] failed because management node was restarted", + "zh_CN": "云主机[uuid:{0}]存储迁移长作业[uuid:{1}]失败,因为管理节点已重新启动", "arguments": [ - "volume.getUuid()", - "volume.getRootImageUuid()" + "amsg.getVmInstanceUuid()", + "job.getUuid()" ], - "line": 3910, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 141, + "fileName": "src/main/java/org/zstack/storage/migration/primary/PrimaryStorageMigrateVmJob.java" }, { - "raw": "cannot find backupstorage to download image [%s] to primarystorage [%s]", - "en_US": "cannot find backupstorage to download image [{0}] to primarystorage [{1}]", - "zh_CN": "", + "raw": "The type [%s] of volume is invalid.", + "en_US": "The type [{0}] of volume is invalid.", + "zh_CN": "卷的类型[{0}]无效。", "arguments": [ - "volume.getRootImageUuid()", - "getSelf().getUuid()" + "volume.getType()" ], - "line": 3929, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java" + "line": 584, + "fileName": "src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java" }, { - "raw": "cannot find any Connected ceph mon for the primary storage[uuid:%s]", - "en_US": "cannot find any Connected ceph mon for the primary storage[uuid:{0}]", - "zh_CN": "无法为Ceph主存储[uuid:{0}]找到一台处于Connected状态的的监控节点", + "raw": "all ceph mons are Disconnected in ceph primary storage[uuid:%s]", + "en_US": "all ceph mons are Disconnected in ceph primary storage[uuid:{0}]", + "zh_CN": "所有Ceph MON都在分布式存储[uuid:{0}]中断开连接", "arguments": [ - "vol.getPrimaryStorageUuid()" + "dstPsVO.getUuid()" ], - "line": 457, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" + "line": 122, + "fileName": "src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java" }, { - "raw": "not support take volumes snapshots on multiple ps when including ceph", - "en_US": "not support take volumes snapshots on multiple ps when including ceph", - "zh_CN": "", + "raw": "cannot find any connected host to perform the storage migration operation", + "en_US": "cannot find any connected host to perform the storage migration operation", + "zh_CN": "为了执行存储迁移操作,未找到连接的物理机", "arguments": [], - "line": 758, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" + "line": 89, + "fileName": "src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java" }, { - "raw": "ceph pool conflict, the ceph pool specified by the instance offering is %s, and the ceph pool specified in the creation parameter is %s", - "en_US": "ceph pool conflict, the ceph pool specified by the instance offering is {0}, and the ceph pool specified in the creation parameter is {1}", - "zh_CN": "", + "raw": "both image %s and its cache is missing", + "en_US": "both image {0} and its cache is missing", + "zh_CN": "缺少镜像{0}及其缓存", "arguments": [ - "targetCephPoolName", - "cephPoolName" + "imageUuid" ], - "line": 853, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" + "line": 194, + "fileName": "src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java" }, { - "raw": "ceph pool conflict, the ceph pool specified by the disk offering is %s, and the ceph pool specified in the creation parameter is %s", - "en_US": "ceph pool conflict, the ceph pool specified by the disk offering is {0}, and the ceph pool specified in the creation parameter is {1}", - "zh_CN": "", - "arguments": [ - "targetCephPoolName", - "cephPoolName" - ], - "line": 984, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" + "raw": "\u0027resourceUuid\u0027 and \u0027resourceType\u0027 must be set both or neither!", + "en_US": "\u0027resourceUuid\u0027 and \u0027resourceType\u0027 must be set both or neither!", + "zh_CN": "“ resourceUuid ”和“ resourceType ”必须同时设置或都不设置!", + "arguments": [], + "line": 203, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" }, { - "raw": "get rootVolume[%s] rbd image watchers fail, %s", - "en_US": "get rootVolume[{0}] rbd image watchers fail, {1}", - "zh_CN": "查询根云盘[{0}] rbd image watchers失败,{1}", + "raw": "zoneUuids, clusterUuids, primaryStorageUuids must have at least one be none-empty list, or all is set to true", + "en_US": "zoneUuids, clusterUuids, primaryStorageUuids must have at least one be none-empty list, or all is set to true", + "zh_CN": "zoneUuids、clusterUuids、primaryStorageUuids中必须至少有一个不为空列表,除非将字段 all 设为 true", + "arguments": [], + "line": 92, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + }, + { + "raw": "primary storage[uuid:%s] has not been attached to cluster[uuid:%s] yet", + "en_US": "primary storage[uuid:{0}] has not been attached to cluster[uuid:{1}] yet", + "zh_CN": "主存储[uuid:{0}]还未加载到集群[uuid:{1}]上", "arguments": [ - "rootVolume.getInstallPath()", - "reply.getError().getDetails()" + "msg.getPrimaryStorageUuid()", + "msg.getClusterUuid()" ], - "line": 1203, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" + "line": 114, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" }, { - "raw": "rootVolume[%s] is already in use(ceph rbd image[%s] already has watchers), in order to prevent brain splitting, Starting VM is prohibited.", - "en_US": "rootVolume[{0}] is already in use(ceph rbd image[{1}] already has watchers), in order to prevent brain splitting, Starting VM is prohibited.", - "zh_CN": "根云盘[{0}]正在使用中(ceph rbd 镜像[{1}]存在watchers),为了防止云主机脑裂,禁止启动云主机", + "raw": "primary storage[uuid:%s] has been attached to cluster[uuid:%s]", + "en_US": "primary storage[uuid:{0}] has been attached to cluster[uuid:{1}]", + "zh_CN": "主存储[uuid:{0}]已被加载到集群[uuid:{1}]上", "arguments": [ - "msg.getVolumeUuid()", - "installPath" - ], - "line": 1219, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java" + "msg.getPrimaryStorageUuid()", + "msg.getClusterUuid()" + ], + "line": 131, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" }, { - "raw": "cannot update status of the ceph primary storage mon[uuid:%s], it has been deleted.This error can be ignored", - "en_US": "cannot update status of the ceph primary storage mon[uuid:{0}], it has been deleted.This error can be ignored", - "zh_CN": "不能更新一台已经被删除的Ceph主存储监控节点[uuid:{0}],这个错误可被忽略", + "raw": "primary storage[uuid:%s] and cluster[uuid:%s] are not in the same zone", + "en_US": "primary storage[uuid:{0}] and cluster[uuid:{1}] are not in the same zone", + "zh_CN": "主存储[uuid:{0}]和集群[uuid:{1}]不在同一个区域内", "arguments": [ - "uuid" + "msg.getPrimaryStorageUuid()", + "msg.getClusterUuid()" ], - "line": 92, - "fileName": "src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java" + "line": 146, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" }, { - "raw": "scsi lun[uuid: %s] and [uuid: %s] does not has a common host", - "en_US": "scsi lun[uuid: {0}] and [uuid: {1}] does not has a common host", - "zh_CN": "", + "raw": "url[%s] has been occupied, it cannot be duplicate in same cluster", + "en_US": "url[{0}] has been occupied, it cannot be duplicate in same cluster", + "zh_CN": "url[{0}]已经被占用,在相同的集群里它不能再次使用", "arguments": [ - "firstScsiLunVO.getUuid()", - "scsiLunVO.getUuid()" + "url" ], - "line": 54, - "fileName": "src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java" + "line": 168, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" }, { - "raw": "scsi lun[uuid: %s] is in disabled state", - "en_US": "scsi lun[uuid: {0}] is in disabled state", - "zh_CN": "", + "raw": "primary storage(s) [uuid: %s] where volume(s) locate is not Enabled or Connected", + "en_US": "primary storage(s) [uuid: {0}] where volume(s) locate is not Enabled or Connected", + "zh_CN": "卷所在的主存储[uuid:{0}]未启用或未连接", "arguments": [ - "scsiLunVO.getUuid()" + "psUuids" ], - "line": 59, - "fileName": "src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java" + "line": 220, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" }, { - "raw": "iSCSI server[ip: %s, port: %s] already exists", - "en_US": "iSCSI server[ip: {0}, port: {1}] already exists", - "zh_CN": "", + "raw": "after removing primary storage%s to avoid, there is no candidate primary storage anymore. please check primary storage status and state in the cluster.", + "en_US": "after removing primary storage{0} to avoid, there is no candidate primary storage anymore. please check primary storage status and state in the cluster.", + "zh_CN": "把主存储{0}移到排除列表后,就没有可用的主存储了,请确认集群中主存储的状态", "arguments": [ - "msg.getIp()", - "msg.getPort()" + "spec.getAvoidPrimaryStorageUuids()" ], - "line": 62, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" + "line": 50, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageAvoidAllocatorFlow.java" }, { - "raw": "iSCSI server ip: %s is not valid", - "en_US": "iSCSI server ip: {0} is not valid", - "zh_CN": "", + "raw": "cannot attach ISO to a primary storage[uuid:%s] which is disabled", + "en_US": "cannot attach ISO to a primary storage[uuid:{0}] which is disabled", + "zh_CN": "无法将ISO附加到已禁用的主存储[uuid:{0}]", "arguments": [ - "msg.getIp()" + "self.getUuid()" ], - "line": 67, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" + "line": 239, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" }, { - "raw": "iSCSI server[uuid: %s] already attached to cluster[uuid: %s]", - "en_US": "iSCSI server[uuid: {0}] already attached to cluster[uuid: {1}]", - "zh_CN": "", + "raw": "backup storage[uuid:%s] is not attached to zone[uuid:%s] the primary storage[uuid:%s] belongs to", + "en_US": "backup storage[uuid:{0}] is not attached to zone[uuid:{1}] the primary storage[uuid:{2}] belongs to", + "zh_CN": "镜像服务器[uuid:{0}]没有加载到主存储[uuid:{2}]所在的区域[uuid:{1}]", "arguments": [ - "msg.getUuid()", - "msg.getClusterUuid()" + "bsUuid", + "self.getZoneUuid()", + "self.getUuid()" ], - "line": 76, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" + "line": 769, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" }, { - "raw": "iSCSI server[uuid: %s] not attached to cluster[uuid: %s]", - "en_US": "iSCSI server[uuid: {0}] not attached to cluster[uuid: {1}]", - "zh_CN": "", + "raw": "volume[uuid:%s] has been attached a %s VM. VM should be Stopped.", + "en_US": "volume[uuid:{0}] has been attached a {1} VM. VM should be Stopped.", + "zh_CN": "卷[uuid:{0}]已连接到{1}云主机。应停止云主机。", "arguments": [ - "msg.getUuid()", - "msg.getClusterUuid()" + "volUuid", + "vmState" ], - "line": 86, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" + "line": 789, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" }, { - "raw": "iSCSI server[uuid: %s] still attached to cluster[uuid: %s]", - "en_US": "iSCSI server[uuid: {0}] still attached to cluster[uuid: {1}]", - "zh_CN": "", + "raw": "primary storage[uuid:%s] cannot be deleted for still being attached to cluster[uuid:%s].", + "en_US": "primary storage[uuid:{0}] cannot be deleted for still being attached to cluster[uuid:{1}].", + "zh_CN": "不能删除主存储[uuid:{0}],因为它还被加载在集群[uuid:{1}]上", "arguments": [ - "msg.getUuid()", - "clusterUuid" + "self.getUuid()", + "clusterUuidsString" ], - "line": 97, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" + "line": 1602, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" }, { - "raw": "scsi lun[wwid: %s] has been attached to vm instance %s", - "en_US": "scsi lun[wwid: {0}] has been attached to vm instance {1}", - "zh_CN": "", + "raw": "cannot attach volume[uuid:%s] whose primary storage is Maintenance", + "en_US": "cannot attach volume[uuid:{0}] whose primary storage is Maintenance", + "zh_CN": "无法挂载云盘[uuid:{0}],其主存储处于维护模式", "arguments": [ - "scsiLunVO.getWwid()", - "refVO.getVmInstanceUuid()" + "volumeUuid" ], - "line": 126, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java" + "line": 1749, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" }, { - "raw": "vm instance[%s] state [%s] not in allowed state[%s] for operation", - "en_US": "vm instance[{0}] state [{1}] not in allowed state[{2}] for operation", - "zh_CN": "", + "raw": "cannot reserve %s bytes on the primary storage[uuid:%s], it\u0027s short of available capacity", + "en_US": "cannot reserve {0} bytes on the primary storage[uuid:{1}], it\u0027s short of available capacity", + "zh_CN": "无法在主存储[uuid:{1}]上保留{0}字节,可用容量不足", "arguments": [ - "msg.getUuid()", - "vmInstanceVO.getState()", - "allowedVmOperationStates" + "size", + "capacityVO.getUuid()" ], - "line": 1188, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + "line": 283, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageCapacityUpdater.java" }, { - "raw": "vm instance[uuid: %s] host[uuid: %s] not attached scsi lun[uuid: %s]", - "en_US": "vm instance[uuid: {0}] host[uuid: {1}] not attached scsi lun[uuid: {2}]", - "zh_CN": "", + "raw": "the primary storage[uuid:%s] is not in status of Connected, current status is %s", + "en_US": "the primary storage[uuid:{0}] is not in status of Connected, current status is {1}", + "zh_CN": "主存储[uuid:{0}]的状态不是已连接,当前的状态是{1}", "arguments": [ - "msg.getUuid()", - "vmInstanceVO.getHostUuid()", - "msg.getUuid()" + "ps.getUuid()", + "ps.getStatus().toString()" ], - "line": 1197, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + "line": 45, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageDeleteBitGC.java" }, { - "raw": "vm instance[%s] state[%s] not in allowed state[%s] for operation", - "en_US": "vm instance[{0}] state[{1}] not in allowed state[{2}] for operation", - "zh_CN": "", + "raw": "no way to get image size of %s, report exception.", + "en_US": "no way to get image size of {0}, report exception.", + "zh_CN": "无法获取{0}的镜像大小,报告异常。", "arguments": [ - "msg.getVmInstanceUuid()", - "vmInstanceVO.getState()", - "allowedVmOperationStates" + "spec.getImageUuid()" ], - "line": 1256, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + "line": 225, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageMainAllocatorFlow.java" }, { - "raw": "vm instance[%s] host[uuid: %s] not attached scsi lun[uuid: %s]", - "en_US": "vm instance[{0}] host[uuid: {1}] not attached scsi lun[uuid: {2}]", - "zh_CN": "", + "raw": "%s is invalid. %s is not a valid zstack uuid", + "en_US": "{0} is invalid. {1} is not a valid zstack uuid", + "zh_CN": "{0}是无效的,{1}不是一个有效的ZStack uuid", "arguments": [ - "msg.getVmInstanceUuid()", - "hostVO.getUuid()", - "msg.getUuid()" + "systemTag", + "uuid" ], - "line": 1265, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + "line": 106, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "different iscsi configuration were found on host[uuid:%s, targets:%s]and host[uuid:%s, targets:%s]", - "en_US": "different iscsi configuration were found on host[uuid:{0}, targets:{1}]and host[uuid:{2}, targets:{3}]", - "zh_CN": "", + "raw": "no primary storage[uuid:%s] found", + "en_US": "no primary storage[uuid:{0}] found", + "zh_CN": "找不到主存储[uuid:{0}]", "arguments": [ - "scannedServer.getKey()", - "JSONObjectUtil.toJsonString(scannedTargets)", - "hostVO.getUuid()", - "JSONObjectUtil.toJsonString(returnValue.getIscsiTargets())" + "resourceUuid" ], - "line": 1447, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + "line": 110, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "specified scsi lun[wwid: %s] not exists or disabled", - "en_US": "specified scsi lun[wwid: {0}] not exists or disabled", - "zh_CN": "", + "raw": "primaryStorage[uuid\u003d%s] does not exist", + "en_US": "primaryStorage[uuid\u003d{0}] does not exist", + "zh_CN": "PrimaryStorage[uuid\u003d{0}]不存在", "arguments": [ - "refVO.getScsiLunUuid()" + "msg.getUuid()" ], - "line": 2055, - "fileName": "src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java" + "line": 138, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "No host available for block live migration", - "en_US": "No host available for block live migration", - "zh_CN": "", + "raw": "please specify the purpose before allocating space", + "en_US": "please specify the purpose before allocating space", + "zh_CN": "请在分配空间之前指定用途", "arguments": [], - "line": 256, - "fileName": "src/main/java/org/zstack/storage/migration/KvmStorageLiveMigrationFlowChain.java" + "line": 492, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "live block migration failed: %s", - "en_US": "live block migration failed: {0}", - "zh_CN": "", + "raw": "cannot find any qualified primary storage, errors are %s", + "en_US": "cannot find any qualified primary storage, errors are {0}", + "zh_CN": "找不到可用的主存储,错误为:{0}", "arguments": [ - "rsp.getError()" + "errs" ], - "line": 494, - "fileName": "src/main/java/org/zstack/storage/migration/KvmStorageLiveMigrationFlowChain.java" + "line": 614, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "do not support storage migration with iso in ceph backup storage attached", - "en_US": "do not support storage migration with iso in ceph backup storage attached", - "zh_CN": "", - "arguments": [], - "line": 123, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "raw": "cidr[%s] Input Format Error", + "en_US": "cidr[{0}] Input Format Error", + "zh_CN": "CIDR[{0}]输入格式错误", + "arguments": [ + "cidr" + ], + "line": 833, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "do not support storage migration of vm[uuid:%s, name: %s] while shared volume attached", - "en_US": "do not support storage migration of vm[uuid:{0}, name: {1}] while shared volume attached", - "zh_CN": "", + "raw": "only one primaryStorage cidr system tag is allowed, but %d got", + "en_US": "only one primaryStorage cidr system tag is allowed, but {0} got", + "zh_CN": "只允许一个PrimaryStorage CIDR系统标记,但{0}获得了", "arguments": [ - "srcVm.getUuid()", - "srcVm.getName()" + "cidrCount" ], - "line": 292, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 829, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "do not support storage migration from [%s] to [%s] with data volume", - "en_US": "do not support storage migration from [{0}] to [{1}] with data volume", - "zh_CN": "不支持从[{0}]到[{1}]的带数据盘的存储迁移", + "raw": "clusterUuid conflict, the cluster specified by the instance offering is %s, and the cluster specified in the creation parameter is %s", + "en_US": "clusterUuid conflict, the cluster specified by the instance offering is {0}, and the cluster specified in the creation parameter is {1}", + "zh_CN": "Clusteruuid冲突,实例产品指定的集群为{0},创建参数中指定的集群为{1}", "arguments": [ - "srcPsType", - "dstPsType" + "clusterUuid", + "msg.getClusterUuid()" ], - "line": 175, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1186, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "do not support storage migration from [%s] to [%s] with snapshot", - "en_US": "do not support storage migration from [{0}] to [{1}] with snapshot", - "zh_CN": "不支持从[{0}]到[{1}]的存在云盘快照的存储迁移", + "raw": "primaryStorageUuid conflict, the primary storage specified by the instance offering is %s, and the primary storage specified in the creation parameter is %s", + "en_US": "primaryStorageUuid conflict, the primary storage specified by the instance offering is {0}, and the primary storage specified in the creation parameter is {1}", + "zh_CN": "PrimaryStorageuuid冲突,实例产品指定的主存储为{0},而创建参数中指定的主存储为{1}", "arguments": [ - "srcPsType", - "dstPsType" + "psUuid", + "msg.getPrimaryStorageUuidForRootVolume()" ], - "line": 180, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1201, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" }, { - "raw": "do not support storage migration from [%s] to [%s]", - "en_US": "do not support storage migration from [{0}] to [{1}]", - "zh_CN": "不支持从[{0}]到[{1}]的存储迁移", + "raw": "cannot find primary storage[uuid:%s], the uuid is specified in instance offering or disk offering", + "en_US": "cannot find primary storage[uuid:{0}], the uuid is specified in instance offering or disk offering", + "zh_CN": "找不到由计算规格或云盘规格指定的主存储[uuid:{0}]", "arguments": [ - "primaryStorageVO.getType()", - "dstPrimaryStorageVO.getType()" + "uuid" ], - "line": 188, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 127, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorExtension.java" }, { - "raw": "VM[uuid:%s] is running but host uuid is missing", - "en_US": "VM[uuid:{0}] is running but host uuid is missing", - "zh_CN": "", + "raw": "cannot find primary storage having user tag[%s]. The user tag is specified in instance offering or disk offering", + "en_US": "cannot find primary storage having user tag[{0}]. The user tag is specified in instance offering or disk offering", + "zh_CN": "找不到带有指定用户标签的主存储[uuid:{0}],该标签由计算规格或者云盘规格指定", "arguments": [ - "vmInstanceVO.getUuid()" + "tag" ], - "line": 194, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 167, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorExtension.java" }, { - "raw": "Source BS and Destination BS cannot be the same.", - "en_US": "Source BS and Destination BS cannot be the same.", - "zh_CN": "源镜像服务器和目标镜像服务器不能相同", - "arguments": [], - "line": 205, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "raw": "PrimaryStorageTagAllocatorExtensionPoint[%s] returns zero primary storage candidate", + "en_US": "PrimaryStorageTagAllocatorExtensionPoint[{0}] returns zero primary storage candidate", + "zh_CN": "主存储标签分配插件[{0}]找不到可用的主存储", + "arguments": [ + "extp.getClass().getName()" + ], + "line": 85, + "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorFlow.java" }, { - "raw": "Source BS and Destination BS must not be Disabled.", - "en_US": "Source BS and Destination BS must not be Disabled.", - "zh_CN": "源镜像服务器和目标镜像服务器必须不是不可用。", + "raw": "not support", + "en_US": "not support", + "zh_CN": "不是支持", "arguments": [], - "line": 213, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1825, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "Image[uuid:%s] is not in status Ready, cannot migrate it.", - "en_US": "Image[uuid:{0}] is not in status Ready, cannot migrate it.", - "zh_CN": "镜像[uuid:{0}]的状态不是已准备,不能迁移它", + "raw": "cannot find any BackupStorageKvmFactory for the type[%s]", + "en_US": "cannot find any BackupStorageKvmFactory for the type[{0}]", + "zh_CN": "找不到类型[{0}]的任何BackupStorageKVMFactory", "arguments": [ - "msg.getImageUuid()" + "bsType" ], - "line": 220, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 471, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "Image[uuid:%s] is not in source backup storage[uuid:%s]", - "en_US": "Image[uuid:{0}] is not in source backup storage[uuid:{1}]", - "zh_CN": "镜像[uuid:{0}]没有在源镜像服务器[uuid:{1}]", + "raw": "the block primary storage[uuid:%s, name:%s] can not find any available host in attached clusters for instantiating the volume", + "en_US": "the block primary storage[uuid:{0}, name:{1}] can not find any available host in attached clusters for instantiating the volume", + "zh_CN": "块主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机", "arguments": [ - "msg.getImageUuid()", - "msg.getSrcBackupStorageUuid()" + "self.getUuid()", + "self.getName()" ], - "line": 231, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 670, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "Cannot migrate image from %s to %s.", - "en_US": "Cannot migrate image from {0} to {1}.", - "zh_CN": "不能从{0}迁移镜像到{1}", + "raw": "fail to find a host to map for volume %s", + "en_US": "fail to find a host to map for volume {0}", + "zh_CN": "找不到要为卷{0}映射的物理机", "arguments": [ - "srcBS.getType()", - "dstBS.getType()" + "msg.getVolumeInventory().getUuid()" ], - "line": 240, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1242, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "Source PS and Destination PS must not be Disabled or Maintenance state.", - "en_US": "Source PS and Destination PS must not be Disabled or Maintenance state.", - "zh_CN": "源主存储和目标主存储必须不是不可用或者维护状态。", + "raw": "host uuid is mandatory", + "en_US": "host uuid is mandatory", + "zh_CN": "物理机uuid是必需的", "arguments": [], - "line": 260, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" - }, - { - "raw": "Volume[uuid:%s] is already in PS[uuid:%s], cannot migrate.", - "en_US": "Volume[uuid:{0}] is already in PS[uuid:{1}], cannot migrate.", - "zh_CN": "云盘[uuid:{0}]已经在主存储[uuid:{1}]里,不能迁移。", - "arguments": [ - "msg.getVolumeUuid()", - "msg.getDstPrimaryStorageUuid()" - ], - "line": 267, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1491, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "Volume[uuid:%s] is not in status Ready, cannot migrate it.", - "en_US": "Volume[uuid:{0}] is not in status Ready, cannot migrate it.", - "zh_CN": "云盘[uuid:{0}]状态不是已准备,不能进行迁移", + "raw": "Fail to get host initiator ref, please reconnect this host:%s", + "en_US": "Fail to get host initiator ref, please reconnect this host:{0}", + "zh_CN": "无法获取物理机启动器引用,请重新连接此物理机:{0}", "arguments": [ - "msg.getVolumeUuid()" + "msg.getDestHostUuid()" ], - "line": 274, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1612, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "the volume[uuid:%s] is still attached on vm[uuid:%s], please detach it before migration.", - "en_US": "the volume[uuid:{0}] is still attached on vm[uuid:{1}], please detach it before migration.", - "zh_CN": "云盘[uuid:{0}]一直连接在虚拟机[uuid:{1}],在迁移之前请先断开连接", + "raw": "fail to find cluster for commit volume on ps:%s", + "en_US": "fail to find cluster for commit volume on ps:{0}", + "zh_CN": "在PS:{0}上找不到提交卷的集群", "arguments": [ - "msg.getVolumeUuid()", - "srcVolume.getVmInstanceUuid()" + "msg.getPrimaryStorageUuid()" ], - "line": 330, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 2608, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "do not support storage migration while shared volume[uuid: %s, name: %s] attached", - "en_US": "do not support storage migration while shared volume[uuid: {0}, name: {1}] attached", - "zh_CN": "加载了共享云盘[uuid:{0}, name:{1}]不支持存储迁移", + "raw": "fail to find host for commit volume:%s", + "en_US": "fail to find host for commit volume:{0}", + "zh_CN": "找不到提交卷的物理机:{0}", "arguments": [ - "srcVolume.getUuid()", - "srcVolume.getName()" + "msg.getVolumeUuid()" ], - "line": 338, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" - }, - { - "raw": "Cannot migrate root volume when vm instance is not stopped.", - "en_US": "Cannot migrate root volume when vm instance is not stopped.", - "zh_CN": "当虚拟机不是已停止,不能迁移根云盘。", - "arguments": [], - "line": 287, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" - }, - { - "raw": "Cannot migrate root volume when there are data volumes attached to the vm instance.", - "en_US": "Cannot migrate root volume when there are data volumes attached to the vm instance.", - "zh_CN": "当数据云盘连接在虚拟机上时,不能迁移根云盘", - "arguments": [], - "line": 304, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 2617, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java" }, { - "raw": "The destination primary storage is not attached to any cluster that has the same L2 networks as source cluster.", - "en_US": "The destination primary storage is not attached to any cluster that has the same L2 networks as source cluster.", - "zh_CN": "目标主存储不能连接任何和源集群一样的二层网络的集群", + "raw": "not support take volumes snapshots on multiple ps when including ceph", + "en_US": "not support take volumes snapshots on multiple ps when including ceph", + "zh_CN": "包含Ceph时,不支持在多个PS上拍摄卷快照", "arguments": [], - "line": 323, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 1132, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java" }, { - "raw": "Cannot migrate volume from %s to %s.", - "en_US": "Cannot migrate volume from {0} to {1}.", - "zh_CN": "不能从{0}迁移云盘到{1}", + "raw": "KVM host[uuid: %s] fails to be added into local primary storage[uuid: %s], %s", + "en_US": "KVM host[uuid: {0}] fails to be added into local primary storage[uuid: {1}], {2}", + "zh_CN": "本地存储[uuid:{1}]添加物理机[uuid:{0}]失败,{2}", "arguments": [ - "srcPS.getType()", - "dstPS.getType()" + "context.getInventory().getUuid()", + "priUuid", + "reply.getError()" ], - "line": 348, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java" + "line": 370, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java" }, { - "raw": "not support vm state[%s] to do storage migration", - "en_US": "not support vm state[{0}] to do storage migration", - "zh_CN": "虚拟机状态为[{0}],无法进行存储迁移", + "raw": "fail to find block scsi lun for volume: %s", + "en_US": "fail to find block scsi lun for volume: {0}", + "zh_CN": "找不到卷{0}的块SCSI Lun", "arguments": [ - "vmInstanceVO.getState()" + "volume.getUuid()" ], - "line": 531, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" + "line": 669, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java" }, { - "raw": "there are not enough capacity for vm[uuid: %s] storage migration, required capacity(include image cache): %s, current available physical capacity: %s", - "en_US": "there are not enough capacity for vm[uuid: {0}] storage migration, required capacity(include image cache): {1}, current available physical capacity: {2}", - "zh_CN": "对虚拟机[uuid: {0}]存储迁移需要目标主存储具有至少{1}的空余容量(容量计算包含镜像cache),但现在只有{2}的空余容量", + "raw": "fail to exchange block scsi lun info:%s", + "en_US": "fail to exchange block scsi lun info:{0}", + "zh_CN": "无法交换块SCSI Lun信息:{0}", "arguments": [ - "msg.getVmInstanceUuid()", - "size", - "dstPrimaryStorageVO.getCapacity().getAvailablePhysicalCapacity()" + "e.getCause().toString()" ], - "line": 472, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" + "line": 967, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java" }, { - "raw": "VM[uuid: %s] not found", - "en_US": "VM[uuid: {0}] not found", - "zh_CN": "", - "arguments": [ - "msg.getVmInstanceUuid()" - ], - "line": 582, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" + "raw": "currently block storage only support full mode backup", + "en_US": "currently block storage only support full mode backup", + "zh_CN": "当前,数据块存储仅支持完整模式备份", + "arguments": [], + "line": 1560, + "fileName": "src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java" }, { - "raw": "unsupported primary storage type[%s] for storage migration", - "en_US": "unsupported primary storage type[{0}] for storage migration", - "zh_CN": "当前存储[类型:{0}],不支持存储迁移", + "raw": "failed to download[%s] from BackupStorage[hostname:%s] to block primary storage[uuid:%s, path:%s], %s", + "en_US": "failed to download[{0}] from BackupStorage[hostname:{1}] to block primary storage[uuid:{2}, path:{3}], {4}", + "zh_CN": "无法将[{0}]从备份存储[物理机名:{1}]下载到块主存储[uuid:{2},路径:{3}],{4}", "arguments": [ - "srcPs.getType()" + "bsPath", + "greply.getHostname()", + "pinv.getUuid()", + "psPath", + "rsp.getError()" ], - "line": 815, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" + "line": 143, + "fileName": "src/main/java/org/zstack/storage/primary/block/ImageStoreBackupStorageBlockKvmDownloader.java" }, { - "raw": "not support to cancel %s", - "en_US": "not support to cancel {0}", - "zh_CN": "", + "raw": "fail to sync access zones because %s", + "en_US": "fail to sync access zones because {0}", + "zh_CN": "无法同步访问分区,因为{0}", "arguments": [ - "msg.getType()" + "accessZoneRsp.getDetail_err_msg()" ], - "line": 1001, - "fileName": "src/main/java/org/zstack/storage/migration/StorageMigrationBase.java" + "line": 875, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "Cannot reserve enough space for Image[uuid:%s] in BS[uuid:%s]", - "en_US": "Cannot reserve enough space for Image[uuid:{0}] in BS[uuid:{1}]", - "zh_CN": "不能在镜像服务器[uuid:{1}]上为镜像[uuid:{0}]预留足够的空间", + "raw": "fail to get access zone\u0027s subnet because %s", + "en_US": "fail to get access zone\u0027s subnet because {0}", + "zh_CN": "无法获取访问区域的子网,因为{0}", "arguments": [ - "imageUuid", - "dstBsUuid" + "queryAccessZoneSubnetRsp.getDetail_err_msg()" ], - "line": 61, - "fileName": "src/main/java/org/zstack/storage/migration/backup/ReserveCapacityFromDstBSFlow.java" + "line": 881, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "all ceph mons are Disconnected in ceph backup storage[uuid:%s]", - "en_US": "all ceph mons are Disconnected in ceph backup storage[uuid:{0}]", - "zh_CN": "所有在ceph镜像服务器[uuid:{0}]的监控节点都处于失联状态", + "raw": "fail to query all hosts, because of %s", + "en_US": "fail to query all hosts, because of {0}", + "zh_CN": "由于{0},无法查询所有物理机", "arguments": [ - "dstBsVO.getUuid()" + "queryHostRsp.getDetail_err_msg()" ], - "line": 114, - "fileName": "src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java" + "line": 893, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "Failed to migrate Image %s from BS %s to BS %s. cause: %s", - "en_US": "Failed to migrate Image {0} from BS {1} to BS {2}. cause: {3}", - "zh_CN": "", + "raw": "fail to query hosts %s, because of %s", + "en_US": "fail to query hosts {0}, because of {1}", + "zh_CN": "由于{1},无法查询物理机{0}", "arguments": [ - "imageUuid", - "srcBsUuid", - "dstBsUuid", - "errCode.getDetails()" + "ids.toString()", + "queryHostRsp.getDetail_err_msg()" ], - "line": 187, - "fileName": "src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java" + "line": 908, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "found trashId(%s) in BackupStorage [%s] for the migrate installPath[%s]. Please clean it first by \u0027APICleanUpTrashOnBackupStorageMsg\u0027 if you insist to migrate the image[%s]", - "en_US": "found trashId({0}) in BackupStorage [{1}] for the migrate installPath[{2}]. Please clean it first by \u0027APICleanUpTrashOnBackupStorageMsg\u0027 if you insist to migrate the image[{3}]", - "zh_CN": "在备份存储[{1}]的回收数据({0})中己存在要迁移的目标路径[{2}],如果要继续迁移镜像[{3}],请先调用\u0027APICleanUpTrashOnBackupStorageMsg\u0027来手动清理该回收数据", + "raw": "fail to add host %s into hostGroup %s, because of %s", + "en_US": "fail to add host {0} into hostGroup {1}, because of {2}", + "zh_CN": "由于{2},无法将物理机{0}添加到物理机组{1}", "arguments": [ - "reply1.getTrashId()", - "dstBsUuid", - "dstImageInstallPath", - "reply1.getResourceUuid()" + "String.valueOf(hostId)", + "String.valueOf(hostGroupId)", + "addHostRsp.getDetail_err_msg()" ], - "line": 143, - "fileName": "src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java" + "line": 927, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "Cannot reserve enough space for Volume[uuid:%s] in PS[uuid:%s]", - "en_US": "Cannot reserve enough space for Volume[uuid:{0}] in PS[uuid:{1}]", - "zh_CN": "不能在主存储[uuid:{1}]为云盘[uuid:{0}]预留足够的空间", + "raw": "host id is mandatory but get:%s", + "en_US": "host id is mandatory but get:{0}", + "zh_CN": "物理机ID是必需的,但获取:{0}", "arguments": [ - "volumeUuid", - "dstPsUuid" + "String.valueOf(initiatorId)" ], - "line": 85, - "fileName": "src/main/java/org/zstack/storage/migration/primary/ReserveCapacityFromDstPSFlow.java" + "line": 962, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "all ceph mons are Disconnected in ceph primary storage[uuid:%s]", - "en_US": "all ceph mons are Disconnected in ceph primary storage[uuid:{0}]", - "zh_CN": "所有的ceph mons无法连接到主存储[uuid:{0}]", + "raw": "fail to delete host %s, because of %s", + "en_US": "fail to delete host {0}, because of {1}", + "zh_CN": "由于{1},无法删除物理机{0}", "arguments": [ - "dstPsVO.getUuid()" + "String.valueOf(hostId)", + "rsp.getDetail_err_msg()" ], - "line": 120, - "fileName": "src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java" + "line": 943, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "The type [%s] of volume is invalid.", - "en_US": "The type [{0}] of volume is invalid.", - "zh_CN": "", + "raw": "fail to delete host group %s, because of %s", + "en_US": "fail to delete host group {0}, because of {1}", + "zh_CN": "由于{1},无法删除物理机组{0}", "arguments": [ - "volume.getType()" + "String.valueOf(hostGroupId)", + "rsp.getDetail_err_msg()" ], - "line": 571, - "fileName": "src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java" + "line": 955, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot find any connected host to perform the storage migration operation", - "en_US": "cannot find any connected host to perform the storage migration operation", - "zh_CN": "为了执行存储迁移操作,未找到连接的物理机", - "arguments": [], - "line": 88, - "fileName": "src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java" + "raw": "fail to delete initiator %s, because of %s", + "en_US": "fail to delete initiator {0}, because of {1}", + "zh_CN": "由于{1},无法删除发起程序{0}", + "arguments": [ + "String.valueOf(initiatorId)", + "rsp.getDetail_err_msg()" + ], + "line": 967, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "both image %s and its cache is missing", - "en_US": "both image {0} and its cache is missing", - "zh_CN": "", + "raw": "fail to query host group, because of %s", + "en_US": "fail to query host group, because of {0}", + "zh_CN": "由于{0},无法查询物理机组", "arguments": [ - "imageUuid" + "queryHostGroupRsp.getDetail_err_msg()" ], - "line": 187, - "fileName": "src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java" + "line": 975, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "\u0027resourceUuid\u0027 and \u0027resourceType\u0027 must be set both or neither!", - "en_US": "\u0027resourceUuid\u0027 and \u0027resourceType\u0027 must be set both or neither!", - "zh_CN": "", - "arguments": [], - "line": 189, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "raw": "fail to add host group: %s, error message:%s ", + "en_US": "fail to add host group: {0}, error message:{1} ", + "zh_CN": "无法添加物理机组:{0},错误消息:{1}", + "arguments": [ + "name", + "addHostGroupRsp.getDetail_err_msg()" + ], + "line": 993, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "zoneUuids, clusterUuids, primaryStorageUuids must have at least one be none-empty list, or all is set to true", - "en_US": "zoneUuids, clusterUuids, primaryStorageUuids must have at least one be none-empty list, or all is set to true", - "zh_CN": "区域、集群、主存储的Uuids中必须至少有一个不为空列表,除非将字段 all 设为 true", - "arguments": [], - "line": 85, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "raw": "fail to query lun : %s, error message:%s ", + "en_US": "fail to query lun : {0}, error message:{1} ", + "zh_CN": "无法查询Lun:{0},错误消息:{1}", + "arguments": [ + "ids.toString()", + "queryLunRsp.getDetail_err_msg()" + ], + "line": 1011, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primary storage[uuid:%s] has not been attached to cluster[uuid:%s] yet", - "en_US": "primary storage[uuid:{0}] has not been attached to cluster[uuid:{1}] yet", - "zh_CN": "主存储[uuid:{0}]还未加载到集群[uuid:{1}]上", + "raw": "fail to query lun by path: %s, error message:%s ", + "en_US": "fail to query lun by path: {0}, error message:{1} ", + "zh_CN": "无法按路径查询Lun:{0},错误消息:{1}", "arguments": [ - "msg.getPrimaryStorageUuid()", - "msg.getClusterUuid()" + "queryPath", + "queryLunRsp.getDetail_err_msg()" ], - "line": 107, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "line": 1050, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primary storage[uuid:%s] has been attached to cluster[uuid:%s]", - "en_US": "primary storage[uuid:{0}] has been attached to cluster[uuid:{1}]", - "zh_CN": "主存储[uuid:{0}]已被加载到集群[uuid:{1}]上", + "raw": "fail to update lun name: %s, error message:%s ", + "en_US": "fail to update lun name: {0}, error message:{1} ", + "zh_CN": "无法更新Lun名称:{0},错误消息:{1}", "arguments": [ - "msg.getPrimaryStorageUuid()", - "msg.getClusterUuid()" + "name", + "serverCommonRsp.getDetail_err_msg()" ], - "line": 124, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "line": 1067, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primary storage[uuid:%s] and cluster[uuid:%s] are not in the same zone", - "en_US": "primary storage[uuid:{0}] and cluster[uuid:{1}] are not in the same zone", - "zh_CN": "主存储[uuid:{0}]和集群[uuid:{1}]不在同一个区域内", + "raw": "fail to create lun name: %s, error message:%s ", + "en_US": "fail to create lun name: {0}, error message:{1} ", + "zh_CN": "无法创建Lun名称:{0},错误消息:{1}", "arguments": [ - "msg.getPrimaryStorageUuid()", - "msg.getClusterUuid()" + "blockScsiLunVO.getName()", + "serverRsp.getDetail_err_msg()" ], - "line": 139, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "line": 1178, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "url[%s] has been occupied, it cannot be duplicate in same cluster", - "en_US": "url[{0}] has been occupied, it cannot be duplicate in same cluster", - "zh_CN": "url[{0}]已经被占用,在相同的集群里它不能再次使用", + "raw": "fail to get created lun[name: %s], error message:%s ", + "en_US": "fail to get created lun[name: {0}], error message:{1} ", + "zh_CN": "无法获取已创建的Lun[名称:{0}],错误消息:{1}", "arguments": [ - "url" + "blockScsiLunVO.getName()", + "serverRsp.getDetail_err_msg()" ], - "line": 161, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "line": 1115, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primary storage[uuid:%s] cannot be deleted for still being attached to cluster[uuid:%s].", - "en_US": "primary storage[uuid:{0}] cannot be deleted for still being attached to cluster[uuid:{1}].", - "zh_CN": "不能删除主存储[uuid:{0}],因为它还被加载在集群[uuid:{1}]上", + "raw": "fail to create lun name: %s, can not find root cause", + "en_US": "fail to create lun name: {0}, can not find root cause", + "zh_CN": "无法创建Lun名称:{0},找不到根本原因", "arguments": [ - "msg.getPrimaryStorageUuid()", - "clusterUuidsString" + "blockScsiLunVO.getName()" ], - "line": 181, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "line": 1129, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primary storage(s) [uuid: %s] where volume(s) locate is not Enabled or Connected", - "en_US": "primary storage(s) [uuid: {0}] where volume(s) locate is not Enabled or Connected", - "zh_CN": "", + "raw": "fail to query lun %s, because of %s", + "en_US": "fail to query lun {0}, because of {1}", + "zh_CN": "由于{1},无法查询Lun{0}", "arguments": [ - "psUuids" + "String.valueOf(lunId)", + "queryLunRsp.getDetail_err_msg()" ], - "line": 206, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java" + "line": 1188, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "after removing primary storage%s to avoid, there is no candidate primary storage anymore. please check primary storage status and state in the cluster.", - "en_US": "after removing primary storage{0} to avoid, there is no candidate primary storage anymore. please check primary storage status and state in the cluster.", - "zh_CN": "把主存储{0}移到排除列表后,就没有可用的主存储了,请确认集群中主存储的状态", + "raw": "fail to query lun map for lun %s and host group %s, because of %s", + "en_US": "fail to query lun map for lun {0} and host group {1}, because of {2}", + "zh_CN": "由于{2},无法查询Lun{0}和物理机组{1}的Lun映射", "arguments": [ - "spec.getAvoidPrimaryStorageUuids()" + "String.valueOf(lunId)", + "String.valueOf(hostGroupId)", + "queryLunMapRsp.getDetail_err_msg()" ], - "line": 50, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageAvoidAllocatorFlow.java" + "line": 1204, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot attach ISO to a primary storage[uuid:%s] which is disabled", - "en_US": "cannot attach ISO to a primary storage[uuid:{0}] which is disabled", - "zh_CN": "", + "raw": "fail to query lun map for host group %s, because of %s", + "en_US": "fail to query lun map for host group {0}, because of {1}", + "zh_CN": "由于{1},无法查询物理机组{0}的Lun映射", "arguments": [ - "self.getUuid()" + "String.valueOf(hostGroupId)", + "queryLunMapRsp.getDetail_err_msg()" ], - "line": 221, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" + "line": 1225, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "backup storage[uuid:%s] is not attached to zone[uuid:%s] the primary storage[uuid:%s] belongs to", - "en_US": "backup storage[uuid:{0}] is not attached to zone[uuid:{1}] the primary storage[uuid:{2}] belongs to", - "zh_CN": "镜像服务器[uuid:{0}]没有加载到主存储[uuid:{2}]所在的区域[uuid:{1}]", + "raw": "fail to get cluster info, because of %s", + "en_US": "fail to get cluster info, because of {0}", + "zh_CN": "由于{0},无法获取集群信息", "arguments": [ - "bsUuid", - "self.getZoneUuid()", - "self.getUuid()" + "clusterOverviewRsp.getDetail_err_msg()" ], - "line": 657, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" + "line": 1236, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "operation not supported", - "en_US": "operation not supported", - "zh_CN": "不支持的操作", - "arguments": [], - "line": 781, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" + "raw": "fail to map lun %s to host group %s, because of %s", + "en_US": "fail to map lun {0} to host group {1}, because of {2}", + "zh_CN": "由于{2},无法将Lun{0}映射到物理机组{1}", + "arguments": [ + "String.valueOf(lunId)", + "String.valueOf(hostGroupId)", + "serverRsp.getDetail_err_msg()" + ], + "line": 1259, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot attach volume[uuid:%s] whose primary storage is Maintenance", - "en_US": "cannot attach volume[uuid:{0}] whose primary storage is Maintenance", - "zh_CN": "无法挂载云盘[uuid:{0}],其主存储处于维护模式", + "raw": "lun map id is mandatory but get:%s", + "en_US": "lun map id is mandatory but get:{0}", + "zh_CN": "Lun映射ID是必需的,但获取:{0}", "arguments": [ - "volumeUuid" + "String.valueOf(lunMapId)" ], - "line": 1558, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java" + "line": 1267, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot reserve %s bytes on the primary storage[uuid:%s], it\u0027s short of available capacity", - "en_US": "cannot reserve {0} bytes on the primary storage[uuid:{1}], it\u0027s short of available capacity", - "zh_CN": "无法在主存储[uuid:{1}]上保留{0}字节,可用容量不足", + "raw": "fail to delete lun map %s, because of %s", + "en_US": "fail to delete lun map {0}, because of {1}", + "zh_CN": "由于{1},无法删除Lun映射{0}", "arguments": [ - "size", - "capacityVO.getUuid()" + "String.valueOf(lunMapId)", + "serverRsp.getDetail_err_msg()" ], - "line": 283, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageCapacityUpdater.java" + "line": 1273, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "the primary storage[uuid:%s] is not in status of Connected, current status is %s", - "en_US": "the primary storage[uuid:{0}] is not in status of Connected, current status is {1}", - "zh_CN": "主存储[uuid:{0}]的状态不是已连接,当前的状态是{1}", + "raw": "lun id is mandatory but get:%s", + "en_US": "lun id is mandatory but get:{0}", + "zh_CN": "Lun ID是必需的,但获取:{0}", "arguments": [ - "ps.getUuid()", - "ps.getStatus().toString()" + "String.valueOf(lunId)" ], - "line": 45, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageDeleteBitGC.java" + "line": 1279, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "%s is invalid. %s is not a valid zstack uuid", - "en_US": "{0} is invalid. {1} is not a valid zstack uuid", - "zh_CN": "{0}是无效的,{1}不是一个有效的ZStack uuid", + "raw": "fail to delete lun %s, because of %s", + "en_US": "fail to delete lun {0}, because of {1}", + "zh_CN": "由于{1},无法删除Lun{0}", "arguments": [ - "systemTag", - "uuid" + "String.valueOf(lunId)", + "serverRsp.getDetail_err_msg()" ], - "line": 115, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1285, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "no primary storage[uuid:%s] found", - "en_US": "no primary storage[uuid:{0}] found", - "zh_CN": "找不到主存储[uuid:{0}]", + "raw": "fail to get storage pool %s, because of %s", + "en_US": "fail to get storage pool {0}, because of {1}", + "zh_CN": "由于{1},无法获取存储池{0}", "arguments": [ - "resourceUuid" + "String.valueOf(id)", + "storagePoolRsp.getDetail_err_msg()" ], - "line": 119, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1295, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primaryStorage[uuid\u003d%s] does not exist", - "en_US": "primaryStorage[uuid\u003d{0}] does not exist", - "zh_CN": "", + "raw": "fail to create snapshot for lun %s, because of %s", + "en_US": "fail to create snapshot for lun {0}, because of {1}", + "zh_CN": "由于{1},无法为Lun{0}创建快照", "arguments": [ - "msg.getUuid()" + "JSONObjectUtil.toJsonString(blockScsiLunVO)", + "rsp.getDetail_err_msg()" ], - "line": 147, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1308, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot find any qualified primary storage, errors are %s", - "en_US": "cannot find any qualified primary storage, errors are {0}", - "zh_CN": "找不到可用的主存储,错误为:{0}", + "raw": "fail to query snapshots %s, because of %s", + "en_US": "fail to query snapshots {0}, because of {1}", + "zh_CN": "由于{1},无法查询快照{0}", "arguments": [ - "errs" + "ids.toString()", + "rsp.getDetail_err_msg()" ], - "line": 482, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1330, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cidr[%s] Input Format Error", - "en_US": "cidr[{0}] Input Format Error", - "zh_CN": "", + "raw": "snapshot id is mandatory but get:%s", + "en_US": "snapshot id is mandatory but get:{0}", + "zh_CN": "快照ID是必需的,但获取:{0}", "arguments": [ - "cidr" + "String.valueOf(snapshotId)" ], - "line": 558, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1337, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "only one primaryStorage cidr system tag is allowed, but %d got", - "en_US": "only one primaryStorage cidr system tag is allowed, but {0} got", - "zh_CN": "", + "raw": "fail to delete snapshot %s, because of %s", + "en_US": "fail to delete snapshot {0}, because of {1}", + "zh_CN": "由于{1},无法删除快照{0}", "arguments": [ - "cidrCount" + "String.valueOf(snapshotId)", + "rsp.getDetail_err_msg()" ], - "line": 554, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1344, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primaryStorageUuid conflict, the primary storage specified by the instance offering is %s, and the primary storage specified in the creation parameter is %s", - "en_US": "primaryStorageUuid conflict, the primary storage specified by the instance offering is {0}, and the primary storage specified in the creation parameter is {1}", - "zh_CN": "", + "raw": "fail to revert snapshot:%s, because of: %s", + "en_US": "fail to revert snapshot:{0}, because of: {1}", + "zh_CN": "无法恢复快照:{0},因为:{1}", "arguments": [ - "psUuid", - "msg.getPrimaryStorageUuidForRootVolume()" + "String.valueOf(snapshotId)", + "serverRsp.getDetail_err_msg()" ], - "line": 903, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1355, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "primaryStorageUuid conflict, the primary storage specified by the disk offering is %s, and the primary storage specified in the creation parameter is %s", - "en_US": "primaryStorageUuid conflict, the primary storage specified by the disk offering is {0}, and the primary storage specified in the creation parameter is {1}", - "zh_CN": "", + "raw": "fail to check lun %s session state , because of: %s", + "en_US": "fail to check lun {0} session state , because of: {1}", + "zh_CN": "无法检查Lun{0}会话状态,原因是:{1}", "arguments": [ - "psUuid", - "msg.getPrimaryStorageUuid()" + "String.valueOf(lunId)", + "getLunSessionRsp.getDetail_err_msg()" ], - "line": 985, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java" + "line": 1364, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "after subtracting reserved capacity[%s], there is no primary storage having required size[%s bytes], may be the threshold of primary storage physical capacity setting is lower", - "en_US": "after subtracting reserved capacity[{0}], there is no primary storage having required size[{1} bytes], may be the threshold of primary storage physical capacity setting is lower", - "zh_CN": "", + "raw": "fail to get lun %s maps, because of: %s", + "en_US": "fail to get lun {0} maps, because of: {1}", + "zh_CN": "无法获取Lun{0}映射,因为:{1}", "arguments": [ - "PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value()", - "spec.getSize()" + "String.valueOf(lunId)", + "queryLunMapRsp.getDetail_err_msg()" ], - "line": 55, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageReservedCapacityAllocatorFlow.java" + "line": 1380, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot find primary storage[uuid:%s], the uuid is specified in instance offering or disk offering", - "en_US": "cannot find primary storage[uuid:{0}], the uuid is specified in instance offering or disk offering", - "zh_CN": "找不到由计算规格或云盘规格指定的主存储[uuid:{0}]", + "raw": "fail to get lun %s remain created lun number, because of: %s", + "en_US": "fail to get lun {0} remain created lun number, because of: {1}", + "zh_CN": "无法获取Lun{0}保持创建状态的Lun编号,原因是:{1}", "arguments": [ - "uuid" + "String.valueOf(lunId)", + "lunQuantityInfoRsp.getDetail_err_msg()" ], - "line": 127, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorExtension.java" + "line": 1402, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java" }, { - "raw": "cannot find primary storage having user tag[%s]. The user tag is specified in instance offering or disk offering", - "en_US": "cannot find primary storage having user tag[{0}]. The user tag is specified in instance offering or disk offering", - "zh_CN": "找不到带有指定用户标签的主存储[uuid:{0}],该标签由计算规格或者云盘规格指定", + "raw": "lun map id is mandatory can not be null, neither 0", + "en_US": "lun map id is mandatory can not be null, neither 0", + "zh_CN": "Lun映射ID是必需的,不能为空,也不能为0", + "arguments": [], + "line": 161, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java" + }, + { + "raw": "lun id is illegal", + "en_US": "lun id is illegal", + "zh_CN": "Lun ID非法", + "arguments": [], + "line": 194, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java" + }, + { + "raw": "XStor cluster is unhealthy, cluster info[cluster_ data_ state: %s, cluster_ healthy_ state: %s, cluster_ running_ state: %s]", + "en_US": "XStor cluster is unhealthy, cluster info[cluster_ data_ state: {0}, cluster_ healthy_ state: {1}, cluster_ running_ state: {2}]", + "zh_CN": "xstor集群运行不正常,集群信息[集群_数据_状态:{0},集群_运行正常_状态:{1},集群_运行_状态:{2}]", "arguments": [ - "tag" + "clusterOverview.getCluster_data_state()", + "clusterOverview.getCluster_healthy_state()", + "clusterOverview.getCluster_running_state()" ], - "line": 167, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorExtension.java" + "line": 527, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java" }, { - "raw": "PrimaryStorageTagAllocatorExtensionPoint[%s] returns zero primary storage candidate", - "en_US": "PrimaryStorageTagAllocatorExtensionPoint[{0}] returns zero primary storage candidate", - "zh_CN": "主存储标签分配插件[{0}]找不到可用的主存储", + "raw": "illegal lun id", + "en_US": "illegal lun id", + "zh_CN": "非法Lun ID", + "arguments": [], + "line": 555, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java" + }, + { + "raw": "fail to get image cache lun info", + "en_US": "fail to get image cache lun info", + "zh_CN": "无法获取镜像缓存Lun信息", + "arguments": [], + "line": 647, + "fileName": "src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java" + }, + { + "raw": "host %s\u0027s heartbeat is not updated", + "en_US": "host {0}\u0027s heartbeat is not updated", + "zh_CN": "物理机{0}的检测信号未更新", "arguments": [ - "extp.getClass().getName()" + "targetHostUuid" ], - "line": 85, - "fileName": "src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorFlow.java" + "line": 204, + "fileName": "src/main/java/org/zstack/storage/primary/ceph/CephHostHeartbeatChecker.java" }, { - "raw": "all mons failed to execute http call[%s], errors are %s", - "en_US": "all mons failed to execute http call[{0}], errors are {1}", - "zh_CN": "所有的监控节点都无法执行http call[{0}],错误是{1}", + "raw": "host[uuid:%s]\u0027s heartbeat is not updated", + "en_US": "host[uuid:{0}]\u0027s heartbeat is not updated", + "zh_CN": "物理机[uuid:{0}]的检测信号未更新", "arguments": [ - "path", - "JSONObjectUtil.toJsonString(errorCodes)" + "cmd.targetHostUuid" ], - "line": 132, - "fileName": "src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java" + "line": 116, + "fileName": "src/main/java/org/zstack/storage/primary/filesystem/AbstractFileSystemHostHeartbeatChecker.java" }, { "raw": "all ceph mons of primary storage[uuid:%s] are not in Connected state", "en_US": "all ceph mons of primary storage[uuid:{0}] are not in Connected state", - "zh_CN": "Ceph主存储[uuid:{0}]所有的监控节点都不是已连接状态", + "zh_CN": "分布式存储[uuid:{0}]所有的监控节点都不是已连接状态", "arguments": [ "vo.getUuid()" ], - "line": 97, + "line": 120, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java" }, { "raw": "CephPrimaryStorage[%s] not existed!", "en_US": "CephPrimaryStorage[{0}] not existed!", - "zh_CN": "Ceph镜像服务器[{0}]不存在", + "zh_CN": "Ceph镜像服务器监控节点[{0}]不存在", "arguments": [ "param.getPrimaryStorageUuid()" ], - "line": 120, + "line": 164, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java" }, { @@ -18476,7 +30330,7 @@ "arguments": [ "licMgr.getLicenseType().toString()" ], - "line": 170, + "line": 201, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java" }, { @@ -18484,7 +30338,7 @@ "en_US": "System can\u0027t find imagestore backup Storage. Please do not set imagestore backup Storage server IP to localhost(127.*.*.*),", "zh_CN": "系统找不到镜像仓库镜像服务器。请不要设置镜像服务器IP为localhost(127.*.*.*)", "arguments": [], - "line": 207, + "line": 229, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java" }, { @@ -18499,34 +30353,22 @@ "primaryStorageInstallPath", "rsp.getError()" ], - "line": 210, + "line": 232, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java" }, { "raw": "failed to upload bits from the local storage[uuid:%s, path:%s] to image store [hostname:%s], %s", "en_US": "failed to upload bits from the local storage[uuid:{0}, path:{1}] to image store [hostname:{2}], {3}", - "zh_CN": "无法从本地存储[uuid:{0}, path:{1}]上传数据到镜像仓库[主机名:{2}],因为{3}", + "zh_CN": "无法从本地存储[uuid:{0}, path:{1}]上传数据到镜像仓库[物理机名:{2}],因为{3}", "arguments": [ "pinv.getUuid()", "primaryStorageInstallPath", "r.getHostname()", "rsp.getError()" ], - "line": 270, + "line": 293, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java" }, - { - "raw": "fails to create root volume[uuid:%s] from cached image[path:%s] because %s", - "en_US": "fails to create root volume[uuid:{0}] from cached image[path:{1}] because {2}", - "zh_CN": "从镜像[path:{1}]创建根云盘失败,因为{2}", - "arguments": [ - "volume.getUuid()", - "image.getImageUuid()", - "rsp.getError()" - ], - "line": 207, - "fileName": "src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java" - }, { "raw": "failed to download bits from the imagestore backup storage[hostname:%s, path: %s] to the nfs primary storage[uuid:%s, path: %s], %s", "en_US": "failed to download bits from the imagestore backup storage[hostname:{0}, path: {1}] to the nfs primary storage[uuid:{2}, path: {3}], {4}", @@ -18538,66 +30380,87 @@ "primaryStorageInstallPath", "rsp.getError()" ], - "line": 262, + "line": 238, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java" }, { "raw": "failed to upload bits from the NFS[uuid:%s, path:%s] to image store [hostname:%s], %s", "en_US": "failed to upload bits from the NFS[uuid:{0}, path:{1}] to image store [hostname:{2}], {3}", - "zh_CN": "无法从NFS主存储[uuid:{0}, path:{1}]上传数据到镜像仓库[主机名:{2}],因为{3}", + "zh_CN": "无法从NFS主存储[uuid:{0}, path:{1}]上传数据到镜像仓库[物理机名:{2}],因为{3}", "arguments": [ "pinv.getUuid()", "primaryStorageInstallPath", "r.getHostname()", "rsp.getError()" ], - "line": 323, + "line": 300, "fileName": "src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java" }, + { + "raw": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared mount point storage[uuid:%s] are disconnected", + "en_US": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared mount point storage[uuid:{0}] are disconnected", + "zh_CN": "找不到任何Connected的物理机去执行操作,看起来加载到shared mount point存储的集群上所有物理机都处于Disconnected状态", + "arguments": [ + "this.primaryStorageUuid" + ], + "line": 70, + "fileName": "src/main/java/org/zstack/storage/primary/imagestore/smp/KvmAgentCommandDispatcher.java" + }, { "raw": "failed to get primaryStorage[%s] license info, because no MonIP available", "en_US": "failed to get primaryStorage[{0}] license info, because no MonIP available", - "zh_CN": "", + "zh_CN": "无法获取PrimaryStorage[{0}]许可证信息,因为没有可用的monIP", "arguments": [ "primaryStorageUuid" ], - "line": 39, + "line": 52, "fileName": "src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java" }, { "raw": "failed to get primaryStorage[%s] license info, because no data returned", "en_US": "failed to get primaryStorage[{0}] license info, because no data returned", - "zh_CN": "", + "zh_CN": "无法获取PrimaryStorage[{0}]许可证信息,因为未返回任何数据", "arguments": [ "primaryStorageUuid" ], - "line": 46, + "line": 62, "fileName": "src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java" }, { "raw": "failed to get primaryStorage[%s] license info, because the returned data does not have an active license", "en_US": "failed to get primaryStorage[{0}] license info, because the returned data does not have an active license", - "zh_CN": "", + "zh_CN": "无法获取PrimaryStorage[{0}]许可证信息,因为返回的数据没有活动许可证", "arguments": [ "primaryStorageUuid" ], - "line": 61, + "line": 87, "fileName": "src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java" }, { "raw": "failed to get primaryStorage[%s] license info, because expired_time is null", "en_US": "failed to get primaryStorage[{0}] license info, because expired_time is null", - "zh_CN": "", + "zh_CN": "无法获取PrimaryStorage[{0}]许可证信息,因为过期_时间为空", "arguments": [ "primaryStorageUuid" ], - "line": 53, + "line": 70, + "fileName": "src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java" + }, + { + "raw": "failed to parse the date format[%s] of the primaryStorage[%s] license info", + "en_US": "failed to parse the date format[{0}] of the primaryStorage[{1}] license info", + "zh_CN": "无法分析PrimaryStorage[{1}]许可证信息的日期格式[{0}]", + "arguments": [ + "license.getExpired_time()", + "primaryStorageUuid" + ], + "line": 76, "fileName": "src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java" }, { "raw": "no hosts can provide %s bytes for all volumes of the vm[uuid:%s]", "en_US": "no hosts can provide {0} bytes for all volumes of the vm[uuid:{1}]", - "zh_CN": "", + "zh_CN": "没有物理机可以为VM[uuid:{1}]的所有卷提供{0}字节", "arguments": [ "volumeSize", "spec.getVmInstance().getUuid()" @@ -18610,7 +30473,25 @@ "en_US": "localstorage allocator failed", "zh_CN": "localstorage类型的主存储过滤失败", "arguments": [], - "line": 306, + "line": 336, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java" + }, + { + "raw": "invalid uri, correct example is file://$URL;hostUuid://$HOSTuuid or volume://$VOLUMEuuid ", + "en_US": "invalid uri, correct example is file://$URL;hostUuid://$HOSTuuid or volume://$VOLUMEuuid ", + "zh_CN": "URI无效,正确示例为file://$URL;HOSTuuid://$HOSTuuid或VOLUME://$VOLUMEuuid", + "arguments": [], + "line": 356, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java" + }, + { + "raw": "To create volume on the local primary storage, you must specify the host that the volume is going to be created using the system tag [%s]", + "en_US": "To create volume on the local primary storage, you must specify the host that the volume is going to be created using the system tag [{0}]", + "zh_CN": "要在本地主存储上创建卷,必须使用系统标记[{0}]指定要创建卷的物理机", + "arguments": [ + "LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat()" + ], + "line": 369, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java" }, { @@ -18620,7 +30501,7 @@ "arguments": [ "msg.getVolumeUuid()" ], - "line": 90, + "line": 88, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18631,7 +30512,7 @@ "msg.getVolumeUuid()", "msg.getDestHostUuid()" ], - "line": 95, + "line": 93, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18641,7 +30522,7 @@ "arguments": [ "msg.getPrimaryStorageUuid()" ], - "line": 101, + "line": 99, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18651,7 +30532,7 @@ "arguments": [ "ref.getPrimaryStorageUuid()" ], - "line": 105, + "line": 103, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18663,7 +30544,7 @@ "ref.getPrimaryStorageUuid()", "msg.getVolumeUuid()" ], - "line": 114, + "line": 112, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18676,7 +30557,7 @@ "physicalThreshold", "refVO.getAvailablePhysicalCapacity()" ], - "line": 120, + "line": 118, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18686,66 +30567,66 @@ "arguments": [ "msg.getVolumeUuid()" ], - "line": 127, + "line": 125, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { "raw": "the volume[uuid:%s] is the root volume of the vm[uuid:%s]. Currently the vm is in state of %s, please stop it before migration", "en_US": "the volume[uuid:{0}] is the root volume of the vm[uuid:{1}]. Currently the vm is in state of {2}, please stop it before migration", - "zh_CN": "云盘[uuid:{0}]是云主机[uuid:{1}]的根云盘。当前云主机的状态为{2},请停止后再迁移", + "zh_CN": "云盘[uuid:{0}]是云主机[uuid:{1}]的云盘。当前云主机的状态为{2},请停止后再迁移", "arguments": [ "vol.getUuid()", "vol.getVmInstanceUuid()", "vmstate" ], - "line": 139, + "line": 138, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { "raw": "the volume[uuid:%s] is the root volume of the vm[uuid:%s]. Currently the vm still has %s data volumes attached, please detach them before migration", "en_US": "the volume[uuid:{0}] is the root volume of the vm[uuid:{1}]. Currently the vm still has {2} data volumes attached, please detach them before migration", - "zh_CN": "云盘[uuid:{0}]是云主机[uuid:{1}]的根云盘。当前云主机仍有已挂载的数据云盘,请卸载后再迁移", + "zh_CN": "云盘[uuid:{0}]是云主机[uuid:{1}]的云盘。当前云主机仍有已挂载的云盘,请卸载后再迁移", "arguments": [ "vol.getUuid()", "vol.getVmInstanceUuid()", "count" ], - "line": 147, + "line": 146, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { "raw": "the volume[uuid:%s] is the root volume of the vm[uuid:%s]. Currently the vm still has ISO attached, please detach it before migration", "en_US": "the volume[uuid:{0}] is the root volume of the vm[uuid:{1}]. Currently the vm still has ISO attached, please detach it before migration", - "zh_CN": "", + "zh_CN": "卷[uuid:{0}]是云主机[uuid:{1}]的根卷。当前云主机仍连接有ISO,请在迁移前将其分离", "arguments": [ "vol.getUuid()", "vol.getVmInstanceUuid()" ], - "line": 152, + "line": 151, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { "raw": "The two clusters[uuid:%s,uuid:%s] cannot access each other in l2 network when migrate the vm[uuid:%s] to another cluster", "en_US": "The two clusters[uuid:{0},uuid:{1}] cannot access each other in l2 network when migrate the vm[uuid:{2}] to another cluster", - "zh_CN": "两个集群[uuid:{0},uuid:{1}]无法在L2网络中互相访问对方,当迁移云主机[uuid:{2}]从其中一个集群到另一个集群时", + "zh_CN": "两个集群[uuid:{0},uuid:{1}]无法在二层网络中互相访问对方,当迁移云主机[uuid:{2}]从其中一个集群到另一个集群时", "arguments": [ "originClusterUuid", "clusterUuid", "vol.getVmInstanceUuid()" ], - "line": 177, + "line": 176, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { "raw": "the data volume[uuid:%s, name: %s] is still attached to the VM[uuid:%s]. Please detach it before migration", "en_US": "the data volume[uuid:{0}, name: {1}] is still attached to the VM[uuid:{2}]. Please detach it before migration", - "zh_CN": "数据云盘[uuid:{0}, 名称: {1}]仍然挂载在云主机[uuid:{2}]上,请在迁移前卸载", + "zh_CN": "云盘[uuid:{0}, 名称: {1}]仍然挂载在云主机[uuid:{2}]上,请在迁移前卸载", "arguments": [ "vol.getUuid()", "vol.getName()", "vol.getVmInstanceUuid()" ], - "line": 132, + "line": 130, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18755,7 +30636,7 @@ "arguments": [ "msg.getUrl()" ], - "line": 191, + "line": 190, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java" }, { @@ -18765,7 +30646,7 @@ "arguments": [ "msg.getPrimaryStorageUuid()" ], - "line": 258, + "line": 262, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { @@ -18775,7 +30656,7 @@ "arguments": [ "msg.getVolumeUuid()" ], - "line": 560, + "line": 540, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { @@ -18787,41 +30668,7 @@ "self.getUuid()", "JSONObjectUtil.toJsonString(ret.errorCodes)" ], - "line": 1143, - "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" - }, - { - "raw": "Resource[uuid:%s] can only be operated on host[uuid:%s], but the host has been deleted", - "en_US": "Resource[uuid:{0}] can only be operated on host[uuid:{1}], but the host has been deleted", - "zh_CN": "资源[uuid:{0}]只能在物理机[uuid:{0}]上对其操作,但是该物理机已经被删除了", - "arguments": [ - "resUuid", - "uuid" - ], - "line": 1392, - "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" - }, - { - "raw": "cannot find any host which has resource[uuid:%s]", - "en_US": "cannot find any host which has resource[uuid:{0}]", - "zh_CN": "找不到任何拥有资源[uuid:{0}]的物理机", - "arguments": [ - "resUuid" - ], - "line": 1389, - "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" - }, - { - "raw": "host[uuid: %s] of local primary storage[uuid: %s] doesn\u0027t have enough capacity[current: %s bytes, needed: %s]", - "en_US": "host[uuid: {0}] of local primary storage[uuid: {1}] doesn\u0027t have enough capacity[current: {2} bytes, needed: {3}]", - "zh_CN": "主存储[uuid:{1}]上的物理机[uuid:{0}]没有足够的容量[现在: {2} bytes, 需要: {3}]", - "arguments": [ - "hostUuid", - "self.getUuid()", - "ref.getAvailableCapacity()", - "size" - ], - "line": 1764, + "line": 1168, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { @@ -18832,51 +30679,51 @@ "msg.getVolumeUuid()", "self.getUuid()" ], - "line": 2111, + "line": 2326, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { "raw": "No Host state is Enabled, Please check the availability of the host", "en_US": "No Host state is Enabled, Please check the availability of the host", - "zh_CN": "", + "zh_CN": "未启用物理机状态,请检查物理机的可用性", "arguments": [], - "line": 2634, + "line": 2887, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { "raw": "host[uuid:%s] cannot access local storage[uuid:%s], maybe it is detached", "en_US": "host[uuid:{0}] cannot access local storage[uuid:{1}], maybe it is detached", - "zh_CN": "", + "zh_CN": "物理机[uuid:{0}]无法访问本地存储[uuid:{1}],它可能已分离", "arguments": [ "hostUuid", "self.getUuid()" ], - "line": 2741, + "line": 3018, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { "raw": "resource[uuid:%s, type: %s] is not on the local primary storage[uuid:%s]", "en_US": "resource[uuid:{0}, type: {1}] is not on the local primary storage[uuid:{2}]", - "zh_CN": "", + "zh_CN": "资源[uuid:{0},类型:{1}]不在本地主存储[uuid:{2}]上", "arguments": [ "resUuid", "resourceType", "self.getUuid()" ], - "line": 2765, + "line": 3042, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { "raw": "resource[uuid:%s, type: %s] on the local primary storage[uuid:%s] maps to multiple hypervisor%s", "en_US": "resource[uuid:{0}, type: {1}] on the local primary storage[uuid:{2}] maps to multiple hypervisor{3}", - "zh_CN": "", + "zh_CN": "本地主存储[uuid:{2}]上的资源[uuid:{0},类型:{1}]映射到多个云主机管理程序{3}", "arguments": [ "resUuid", "resourceType", "self.getUuid()", "ret" ], - "line": 2770, + "line": 3047, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java" }, { @@ -18888,7 +30735,7 @@ "PrimaryStorageStatus.Connected", "clusterUuid" ], - "line": 99, + "line": 100, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java" }, { @@ -18898,41 +30745,52 @@ "arguments": [ "psUuid" ], - "line": 118, + "line": 119, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java" }, { "raw": "The cluster mounts multiple primary storage[%s(%s), other non-LocalStorage primary storage], primaryStorageUuidForDataVolume cannot be specified %s", "en_US": "The cluster mounts multiple primary storage[{0}({1}), other non-LocalStorage primary storage], primaryStorageUuidForDataVolume cannot be specified {2}", - "zh_CN": "集群绑定了多个主存储[{0}({1}), 其他的非LocalStorage主存储],主存储根云盘未进行指定{2}", + "zh_CN": "集群绑定了多个主存储[{0}({1}), 其他的非LocalStorage主存储],主存储云盘未进行指定{2}", "arguments": [ "requiredPrimaryStorageUuidForDataVolume.getUuid()", "requiredPrimaryStorageUuidForDataVolume.getType()", "LocalStorageConstants.LOCAL_STORAGE_TYPE" ], - "line": 183, + "line": 187, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java" }, { "raw": "The cluster[uuid\u003d%s] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the root disk is located", "en_US": "The cluster[uuid\u003d{0}] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the root disk is located", - "zh_CN": "集群[uuid\u003d{0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下根云盘所在的主存储", + "zh_CN": "集群[uuid\u003d{0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下云盘所在的主存储", "arguments": [ "spec.getDestHost().getClusterUuid()" ], - "line": 119, + "line": 126, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java" }, { "raw": "The cluster[uuid\u003d%s] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the data disk is located", "en_US": "The cluster[uuid\u003d{0}] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the data disk is located", - "zh_CN": "集群[uuid\u003d{0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下根云盘所在的主存储。", + "zh_CN": "集群[uuid\u003d{0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下云盘所在的主存储。", "arguments": [ "spec.getDestHost().getClusterUuid()" ], - "line": 125, + "line": 132, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java" }, + { + "raw": "creation rely on image cache[uuid:%s, locate host uuids: [%s]], cannot create other places.", + "en_US": "creation rely on image cache[uuid:{0}, locate host uuids: [{1}]], cannot create other places.", + "zh_CN": "创建依赖于镜像缓存[uuid:{0},定位物理机uuid:[{1}]],无法创建其他位置。", + "arguments": [ + "imageUuid", + "cachedHostUuids" + ], + "line": 404, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" + }, { "raw": "local storage doesn\u0027t support live migration for hypervisor[%s]", "en_US": "local storage doesn\u0027t support live migration for hypervisor[{0}]", @@ -18940,13 +30798,13 @@ "arguments": [ "spec.getVmInventory().getHypervisorType()" ], - "line": 365, + "line": 462, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { "raw": "cannot attach the data volume[uuid:%s] to the vm[uuid:%s]. Both vm\u0027s root volume and the data volume are on local primary storage, but they are on different hosts. The root volume[uuid:%s] is on the host[uuid:%s] but the data volume[uuid: %s] is on the host[uuid: %s]", "en_US": "cannot attach the data volume[uuid:{0}] to the vm[uuid:{1}]. Both vm\u0027s root volume and the data volume are on local primary storage, but they are on different hosts. The root volume[uuid:{2}] is on the host[uuid:{3}] but the data volume[uuid: {4}] is on the host[uuid: {5}]", - "zh_CN": "不能加载数据云盘[uuid:{0}]到云主机[uuid:{1}]。根云盘和数据云盘都在本地主存储上,但他们属于不同的物理机。根云盘[uuid:{2}]在物理机[uuid:{3}]上,但数据云盘[uuid:{4}]在物理机[uuid:{5}]上", + "zh_CN": "不能加载云盘[uuid:{0}]到云主机[uuid:{1}]。云盘和云盘都在本地主存储上,但他们属于不同的物理机。云盘[uuid:{2}]在物理机[uuid:{3}]上,但云盘[uuid:{4}]在物理机[uuid:{5}]上", "arguments": [ "volume.getUuid()", "vm.getUuid()", @@ -18955,41 +30813,41 @@ "volume.getUuid()", "dataHost" ], - "line": 581, + "line": 678, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { "raw": "the data volume[name:%s, uuid:%s] is on the local storage[uuid:%s]; however,the host on which the data volume is has been deleted. Unable to recover this volume", "en_US": "the data volume[name:{0}, uuid:{1}] is on the local storage[uuid:{2}]; however,the host on which the data volume is has been deleted. Unable to recover this volume", - "zh_CN": "数据云盘[name:{0}, uuid:{1}]在本地存储[uuid:{2}]上;然而物理机内的数据云盘已经被删除了", + "zh_CN": "云盘[name:{0}, uuid:{1}]在本地存储[uuid:{2}]上;然而物理机内的云盘已经被删除了", "arguments": [ "vol.getName()", "vol.getUuid()", "vol.getPrimaryStorageUuid()" ], - "line": 809, + "line": 896, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { "raw": "unable to recover the vm[uuid:%s, name:%s]. The vm\u0027s root volume is on the local storage[uuid:%s]; however, the host on which the root volume is has been deleted", "en_US": "unable to recover the vm[uuid:{0}, name:{1}]. The vm\u0027s root volume is on the local storage[uuid:{2}]; however, the host on which the root volume is has been deleted", - "zh_CN": "不能恢复云主机[uuid:{0}, name:{1}]。云主机的根云盘在本地存储[uuid:{2}]上;然而物理机内的根云盘已经被删除了", + "zh_CN": "不能恢复云主机[uuid:{0}, name:{1}]。云主机的云盘在本地存储[uuid:{2}]上;然而物理机内的云盘已经被删除了", "arguments": [ "vm.getUuid()", "vm.getName()", "psuuid" ], - "line": 851, + "line": 938, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { "raw": "unable to live migrate vm[uuid:%s] with data volumes on local storage. Need detach all data volumes first.", "en_US": "unable to live migrate vm[uuid:{0}] with data volumes on local storage. Need detach all data volumes first.", - "zh_CN": "无法在本地存储上热迁移挂载了数据云盘的云主机[uuid:{0}]。需要先手动卸载所有数据云盘", + "zh_CN": "无法在本地存储上热迁移挂载了云盘的云主机[uuid:{0}]。需要先手动卸载所有云盘", "arguments": [ "vm.getUuid()" ], - "line": 888, + "line": 972, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { @@ -19000,37 +30858,27 @@ "vm.getUuid()", "vm.getPlatform()" ], - "line": 893, + "line": 977, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { "raw": "unable to live migrate vm[uuid:%s] with ISO on local storage. Need detach all ISO first.", "en_US": "unable to live migrate vm[uuid:{0}] with ISO on local storage. Need detach all ISO first.", - "zh_CN": "", - "arguments": [ - "vm.getUuid()" - ], - "line": 898, - "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" - }, - { - "raw": "unable to live migrate with local storage. The vm[uuid:%s] has volumes on local storage,to protect your data, please stop the vm and do the volume migration", - "en_US": "unable to live migrate with local storage. The vm[uuid:{0}] has volumes on local storage,to protect your data, please stop the vm and do the volume migration", - "zh_CN": "本地存储不能热迁移。云主机[uuid:{0}]在本地存储上有云盘,为了保护你的数据,请停止云主机做云盘迁移", + "zh_CN": "无法在本地存储上实时迁移带有ISO的VM[uuid:{0}]。需要先分离所有ISO。", "arguments": [ "vm.getUuid()" ], - "line": 929, + "line": 982, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { "raw": "To create data volume on the local primary storage, you must specify the host that the data volume is going to be created using the system tag [%s]", "en_US": "To create data volume on the local primary storage, you must specify the host that the data volume is going to be created using the system tag [{0}]", - "zh_CN": "要在本地主存储上创建数据云盘,必须用系统标签[{0}]指定创建数据云盘的物理机", + "zh_CN": "要在本地主存储上创建云盘,必须用系统标签[{0}]指定创建云盘的物理机", "arguments": [ "LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat()" ], - "line": 979, + "line": 1058, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { @@ -19041,7 +30889,7 @@ "hostUuid", "msg.getPrimaryStorageUuid()" ], - "line": 989, + "line": 1068, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java" }, { @@ -19049,31 +30897,43 @@ "en_US": "root image has been deleted, cannot reimage now", "zh_CN": "系统镜像已经被删除,无法重制云主机", "arguments": [], - "line": 1782, + "line": 2083, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java" }, { "raw": "cannot find flag file [%s] on host [%s], it might not mount correct path", "en_US": "cannot find flag file [{0}] on host [{1}], it might not mount correct path", - "zh_CN": "", + "zh_CN": "在物理机[{1}]上找不到标记文件[{0}],可能是装载路径不正确", "arguments": [ "makeInitializedFilePath()", "hostUuid" ], - "line": 3117, + "line": 3676, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java" }, { - "raw": "KVM host[uuid: %s] fails to be added into local primary storage[uuid: %s], %s", - "en_US": "KVM host[uuid: {0}] fails to be added into local primary storage[uuid: {1}], {2}", - "zh_CN": "本地存储[uuid:{1}]添加物理机[uuid:{0}]失败,{2}", + "raw": "cannot find flag file [%s] on host [%s], because: %s", + "en_US": "cannot find flag file [{0}] on host [{1}], because: {2}", + "zh_CN": "找不到标记文件[{0}](在物理机[{1}]上),因为:{2}", "arguments": [ - "context.getInventory().getUuid()", - "priUuid", - "reply.getError()" + "makeInitializedFilePath()", + "hostUuid", + "errorCode.getCause().getDetails()" ], - "line": 105, - "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java" + "line": 3684, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java" + }, + { + "raw": "cannot create flag file [%s] on host [%s], because: %s", + "en_US": "cannot create flag file [{0}] on host [{1}], because: {2}", + "zh_CN": "无法在物理机[{1}]上创建标志文件[{0}],因为:{2}", + "arguments": [ + "makeInitializedFilePath()", + "hostUuid", + "errorCode.getCause().getDetails()" + ], + "line": 3705, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java" }, { "raw": "unable to create an empty volume[uuid:%s, name:%s] on the kvm host[uuid:%s]", @@ -19084,7 +30944,7 @@ "p.volume.getName()", "dstHostUuid" ], - "line": 1196, + "line": 1192, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java" }, { @@ -19112,13 +30972,13 @@ "backupStorageInstallPath", "rsp.getError()" ], - "line": 254, + "line": 253, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java" }, { "raw": "no local primary storage can satisfy conditions[state: %s, status: %s] or contain hosts satisfying conditions[state: %s, status: %s, size \u003e %s bytes]", "en_US": "no local primary storage can satisfy conditions[state: {0}, status: {1}] or contain hosts satisfying conditions[state: {2}, status: {3}, size \u003e {4} bytes]", - "zh_CN": "", + "zh_CN": "本地主存储不能满足条件[状态:{0},状态:{1}]或包含满足条件[状态:{2},状态:{3},大小\u003e{4}字节]的物理机", "arguments": [ "PrimaryStorageState.Enabled", "PrimaryStorageStatus.Connected", @@ -19126,13 +30986,13 @@ "HostStatus.Connected", "spec.getSize()" ], - "line": 157, + "line": 159, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java" }, { "raw": "no local primary storage in zone[uuid:%s] can satisfy conditions[state: %s, status: %s] or contain hosts satisfying conditions[state: %s, status: %s, size \u003e %s bytes]", "en_US": "no local primary storage in zone[uuid:{0}] can satisfy conditions[state: {1}, status: {2}] or contain hosts satisfying conditions[state: {3}, status: {4}, size \u003e {5} bytes]", - "zh_CN": "", + "zh_CN": "区域[uuid:{0}]中的本地主存储不能满足条件[状态:{1},状态:{2}],也不包含满足条件[状态:{3},状态:[4},大小\u003e{5}字节]的物理机", "arguments": [ "spec.getRequiredZoneUuid()", "PrimaryStorageState.Enabled", @@ -19141,13 +31001,13 @@ "HostStatus.Connected", "spec.getSize()" ], - "line": 132, + "line": 134, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java" }, { "raw": "the required host[uuid:%s] cannot satisfy conditions[state: %s, status: %s, size \u003e %s bytes], or doesn\u0027t belong to a local primary storage satisfying conditions[state: %s, status: %s], or its cluster doesn\u0027t attach to any local primary storage", "en_US": "the required host[uuid:{0}] cannot satisfy conditions[state: {1}, status: {2}, size \u003e {3} bytes], or doesn\u0027t belong to a local primary storage satisfying conditions[state: {4}, status: {5}], or its cluster doesn\u0027t attach to any local primary storage", - "zh_CN": "", + "zh_CN": "所需的物理机[uuid:{0}]无法满足条件[状态:{1},状态:{2},大小\u003e{3}字节],或者不属于满足条件[状态:{4},状态:{5}]的本地主存储,或者其集群未连接到任何本地主存储", "arguments": [ "spec.getRequiredHostUuid()", "HostState.Enabled", @@ -19156,13 +31016,13 @@ "PrimaryStorageState.Enabled", "PrimaryStorageStatus.Connected" ], - "line": 105, + "line": 107, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java" }, { "raw": "required local primary storage[uuid:%s] cannot satisfy conditions[state: %s, status: %s], or hosts providing the primary storage don\u0027t satisfy conditions[state: %s, status: %s, size \u003e %s bytes]", "en_US": "required local primary storage[uuid:{0}] cannot satisfy conditions[state: {1}, status: {2}], or hosts providing the primary storage don\u0027t satisfy conditions[state: {3}, status: {4}, size \u003e {5} bytes]", - "zh_CN": "", + "zh_CN": "所需的本地主存储[uuid:{0}]无法满足条件[状态:{1},状态:{2}],或者提供主存储的物理机不满足条件[状态:{3},状态:[4},大小\u003e{5}字节]", "arguments": [ "spec.getRequiredPrimaryStorageUuid()", "PrimaryStorageState.Enabled", @@ -19171,82 +31031,191 @@ "HostStatus.Connected", "spec.getSize()" ], - "line": 77, + "line": 79, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java" }, { "raw": "{the physical capacity usage of the host[uuid:%s] has exceeded the threshold[%s]}", "en_US": "{the physical capacity usage of the host[uuid:{0}] has exceeded the threshold[{1}]}", - "zh_CN": "", + "zh_CN": "{物理机[uuid:{0}]的物理容量使用率已超过阈值[{1}]}", "arguments": [ "ref.getHostUuid()", "physicalCapacityMgr.getRatio(ref.getPrimaryStorageUuid())" ], - "line": 198, + "line": 201, "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java" }, { - "raw": "not supported", - "en_US": "not supported", - "zh_CN": "不支持", + "raw": "failed allocate localstorage", + "en_US": "failed allocate localstorage", + "zh_CN": "分配localStorage失败", "arguments": [], - "line": 1002, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" + "line": 207, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java" + }, + { + "raw": "Resource[uuid:%s] can only be operated on host[uuid:%s], but the host has been deleted", + "en_US": "Resource[uuid:{0}] can only be operated on host[uuid:{1}], but the host has been deleted", + "zh_CN": "资源[uuid:{0}]只能在物理机[uuid:{0}]上对其操作,但是该物理机已经被删除了", + "arguments": [ + "resUuid", + "uuid" + ], + "line": 205, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java" + }, + { + "raw": "cannot find any host which has resource[uuid:%s]", + "en_US": "cannot find any host which has resource[uuid:{0}]", + "zh_CN": "找不到任何拥有资源[uuid:{0}]的物理机", + "arguments": [ + "resUuid" + ], + "line": 202, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java" + }, + { + "raw": "host[uuid: %s] of local primary storage[uuid: %s] doesn\u0027t have enough capacity[current: %s bytes, needed: %s]", + "en_US": "host[uuid: {0}] of local primary storage[uuid: {1}] doesn\u0027t have enough capacity[current: {2} bytes, needed: {3}]", + "zh_CN": "主存储[uuid:{1}]上的物理机[uuid:{0}]没有足够的容量[现在: {2} bytes, 需要: {3}]", + "arguments": [ + "hostUuid", + "self.getUuid()", + "ref.getAvailableCapacity()", + "size" + ], + "line": 135, + "fileName": "src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java" + }, + { + "raw": "Invalid resourceUuid %s", + "en_US": "Invalid resourceUuid {0}", + "zh_CN": "资源uuid{0}无效", + "arguments": [ + "msg.getResourceUuid()" + ], + "line": 82, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java" + }, + { + "raw": "primary storage uuid cannot be null.", + "en_US": "primary storage uuid cannot be null.", + "zh_CN": "主存储uuid不能为空。", + "arguments": [], + "line": 88, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java" + }, + { + "raw": "volume[uuid:%s] has been attached some VM(s)[uuid:%s] which are not Stopped and not running on the specific host.", + "en_US": "volume[uuid:{0}] has been attached some VM(s)[uuid:{1}] which are not Stopped and not running on the specific host.", + "zh_CN": "卷[uuid:{0}]已连接到某些未停止且未在特定物理机上运行的云主机[uuid:{1}]。", + "arguments": [ + "volume.getUuid()", + "runningVmUuids.toString()" + ], + "line": 105, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java" + }, + { + "raw": "VM[uuid:%s] are not Stopped and not running on the specific host.", + "en_US": "VM[uuid:{0}] are not Stopped and not running on the specific host.", + "zh_CN": "云主机[uuid:{0}]未停止,也未在特定物理机上运行。", + "arguments": [ + "msg.getResourceUuid()" + ], + "line": 124, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java" + }, + { + "raw": "Fail to %s, because host(s)[uuid:%s] are not enable and not in connected status.", + "en_US": "Fail to {0}, because host(s)[uuid:{1}] are not enable and not in connected status.", + "zh_CN": "{0}失败,因为物理机[uuid:{1}]未启用且未处于连接状态。", + "arguments": [ + "task", + "hostUuids" + ], + "line": 191, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java" }, { "raw": "cannot reserve enough space for primary storage[uuid: %s] on host[uuid: %s], not enough physical capacity", "en_US": "cannot reserve enough space for primary storage[uuid: {0}] on host[uuid: {1}], not enough physical capacity", - "zh_CN": "", + "zh_CN": "无法为物理机[uuid:{1}]上的主存储[uuid:{0}]保留足够的空间,物理容量不足", "arguments": [ "self.getUuid()", "hostUuid" ], - "line": 1104, + "line": 1549, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" }, { - "raw": "cannot find proper hypervisorType for primary storage[uuid:%s] to handle image format or volume format[%s]", - "en_US": "cannot find proper hypervisorType for primary storage[uuid:{0}] to handle image format or volume format[{1}]", - "zh_CN": "对主存储[uuid:{0}]来说不能发现合适的管理程序类型来处理镜像格式或云盘格式[{1}]", + "raw": "not supported", + "en_US": "not supported", + "zh_CN": "不支持", + "arguments": [], + "line": 1449, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" + }, + { + "raw": "ResourceType [%s] of APIRecoverResourceSplitBrainMsg is invalid.", + "en_US": "ResourceType [{0}] of APIRecoverResourceSplitBrainMsg is invalid.", + "zh_CN": "ApiRecoverResourceSplitBrainMsg的ResourceType[{0}]无效。", "arguments": [ - "psUuid", - "imageFormat" + "msg.getResourceType()" ], - "line": 154, + "line": 216, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" }, { "raw": "the mini storage[uuid:%s, name:%s] cannot find any available host in attached clusters for instantiating the volume", "en_US": "the mini storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume", - "zh_CN": "", + "zh_CN": "小型存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机", "arguments": [ "self.getUuid()", "self.getName()" ], - "line": 226, + "line": 360, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" }, { "raw": "can not determine which host", "en_US": "can not determine which host", - "zh_CN": "", + "zh_CN": "无法确定是哪个物理机", "arguments": [], - "line": 449, + "line": 673, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" + }, + { + "raw": "no connected host found, mini storage failed", + "en_US": "no connected host found, mini storage failed", + "zh_CN": "未找到连接的物理机,小型存储失败", + "arguments": [], + "line": 1364, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" }, { "raw": "host[uuid: %s] of mini primary storage[uuid: %s] doesn\u0027t have enough capacity[current: %s bytes, needed: %s]", "en_US": "host[uuid: {0}] of mini primary storage[uuid: {1}] doesn\u0027t have enough capacity[current: {2} bytes, needed: {3}]", - "zh_CN": "", + "zh_CN": "物理机[uuid:{0}](属于小型主存储[uuid:{1}])的容量不足[当前:{2}字节,需要:{3}]", "arguments": [ "hostUuid", "self.getUuid()", "ref.getAvailableCapacity()", "size" ], - "line": 1118, + "line": 1563, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java" }, + { + "raw": "the host[uuid:%s] is not connected", + "en_US": "the host[uuid:{0}] is not connected", + "zh_CN": "物理机[uuid:{0}]不是Connected状态", + "arguments": [ + "hostUuid" + ], + "line": 75, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageDeactivateVolumeGC.java" + }, { "raw": "no LocalStorageBackupStorageMediator supporting hypervisor[%s] and backup storage type[%s] ", "en_US": "no LocalStorageBackupStorageMediator supporting hypervisor[{0}] and backup storage type[{1}] ", @@ -19255,143 +31224,157 @@ "hvType", "bsType" ], - "line": 167, + "line": 173, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageFactory.java" }, { - "raw": "can not get cluster uuid of volume %s", - "en_US": "can not get cluster uuid of volume {0}", - "zh_CN": "", + "raw": "no backup storage can get image[uuid:%s] of volume[uuid:%s]", + "en_US": "no backup storage can get image[uuid:{0}] of volume[uuid:{1}]", + "zh_CN": "没有备份存储可以获取镜像[uuid:{0}](属于卷[uuid:{1}])", "arguments": [ - "volumeUuid" + "volume.getRootImageUuid()", + "volume.getUuid()" ], - "line": 59, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageImageStoreBackend.java" + "line": 332, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java" }, { - "raw": "%s", - "en_US": "{0}", - "zh_CN": "{0}", + "raw": "image[uuid: %s] has no image ref with backup storage[uuid: %s]", + "en_US": "image[uuid: {0}] has no image ref with backup storage[uuid: {1}]", + "zh_CN": "镜像[uuid:{0}]没有备份存储[uuid:{1}]的镜像引用", + "arguments": [ + "image.getUuid()", + "cache.backupStorage.getUuid()" + ], + "line": 343, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java" + }, + { + "raw": "can not find any available host to resize volume[uuid: %s] on mini storage[uuid: %s]", + "en_US": "can not find any available host to resize volume[uuid: {0}] on mini storage[uuid: {1}]", + "zh_CN": "找不到任何可用于调整小型存储[uuid:{1}]上卷[uuid:{0}]大小的物理机", "arguments": [ - "returnValue.error" + "volume.getUuid()", + "volume.getPrimaryStorageUuid()" ], - "line": 736, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java" + "line": 832, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java" }, { - "raw": "no connected host found in the cluster[uuid:%s]", - "en_US": "no connected host found in the cluster[uuid:{0}]", - "zh_CN": "cluster[uuid:{0}]不存在已连接的物理机", + "raw": "volume[uuid:%s] replication is syncing data, please wait until it is finished.", + "en_US": "volume[uuid:{0}] replication is syncing data, please wait until it is finished.", + "zh_CN": "卷[uuid:{0}]复制正在同步数据,请等待其完成。", "arguments": [ - "clusterUuid" + "volumeUuid" ], - "line": 181, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java" + "line": 925, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java" }, { - "raw": "cannot find backup storage[uuid:%s]", - "en_US": "cannot find backup storage[uuid:{0}]", - "zh_CN": "找不到镜像服务器[uuid:{0}]", + "raw": "replication network status of volume[uuid:%s] run into StandAlone, but host are all Connected, please recover it first.", + "en_US": "replication network status of volume[uuid:{0}] run into StandAlone, but host are all Connected, please recover it first.", + "zh_CN": "卷[uuid:{0}]的复制网络状态变为独立运行,但物理机均已连接,请先将其恢复。", "arguments": [ - "backupStorageUuid" + "volumeUuid" ], - "line": 1271, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java" + "line": 938, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java" }, { - "raw": "can not find volume[uuid: %s]", - "en_US": "can not find volume[uuid: {0}]", - "zh_CN": "找不到云盘[uuid: {0}]", + "raw": "Invalid path string %s", + "en_US": "Invalid path string {0}", + "zh_CN": "路径字符串{0}无效", "arguments": [ - "msg.getVolumeUuid()" + "dir" ], - "line": 1056, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java" + "line": 73, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageManagerImpl.java" }, { - "raw": "can not find any available host to resize volume[uuid: %s] on mini storage[uuid: %s]", - "en_US": "can not find any available host to resize volume[uuid: {0}] on mini storage[uuid: {1}]", - "zh_CN": "", + "raw": "Still cache volume exists on ps[uuid:%s] can not update cache volume url", + "en_US": "Still cache volume exists on ps[uuid:{0}] can not update cache volume url", + "zh_CN": "PS[uuid:{0}]上仍然存在缓存卷,无法更新缓存卷URL", "arguments": [ - "volume.getUuid()", - "volume.getPrimaryStorageUuid()" + "resourceUuid" ], - "line": 723, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java" + "line": 80, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStorageManagerImpl.java" }, { "raw": "can not find replication of volume %s on host %s", "en_US": "can not find replication of volume {0} on host {1}", - "zh_CN": "", + "zh_CN": "在物理机{1}上找不到卷{0}的复制", "arguments": [ "resourceUuid", "hostUuid" ], - "line": 105, + "line": 115, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePathManagerImpl.java" }, - { - "raw": "no candidate host with the scsi lun with enough cpu / memory or Enabled/Connected status", - "en_US": "no candidate host with the scsi lun with enough cpu / memory or Enabled/Connected status", - "zh_CN": "需要的lun所在的物理机都不满足cpu / memory 以及物理机状态的条件", - "arguments": [], - "line": 187, - "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java" - }, { "raw": "required cluster %s not attached to primary storage %s for volume %s create", "en_US": "required cluster {0} not attached to primary storage {1} for volume {2} create", - "zh_CN": "", + "zh_CN": "创建卷{2}所需的集群{0}未连接到主存储{1}", "arguments": [ "clusterUuid", "msg.getPrimaryStorageUuid()", "volume.getUuid()" ], - "line": 113, + "line": 141, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java" }, { "raw": "can not find avaliable host on required cluster %s for volume %s create", "en_US": "can not find avaliable host on required cluster {0} for volume {1} create", - "zh_CN": "", + "zh_CN": "在创建卷{1}所需的集群{0}上找不到可用物理机", "arguments": [ "clusterUuid", "volume.getUuid()" ], - "line": 120, + "line": 148, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java" }, { "raw": "cannot find an available host to execute command for primary storage[uuid: %s]", "en_US": "cannot find an available host to execute command for primary storage[uuid: {0}]", - "zh_CN": "", + "zh_CN": "找不到可用于执行主存储[uuid:{0}]命令的物理机", "arguments": [ "primaryStorageUuid" ], - "line": 347, + "line": 445, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java" }, { "raw": "can not allocate storage sync port on host %s: %s", "en_US": "can not allocate storage sync port on host {0}: {1}", - "zh_CN": "", + "zh_CN": "无法在物理机{0}上分配存储同步端口:{1}", "arguments": [ "hostUuid" ], - "line": 378, + "line": 476, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java" }, { "raw": "expect operate on hosts[%s] but only host %s are connected and enabled", "en_US": "expect operate on hosts[{0}] but only host {1} are connected and enabled", - "zh_CN": "", + "zh_CN": "预期在物理机[{0}]上运行,但只有物理机{1}已连接并启用", "arguments": [ "hostUuids", - "connectedEnabledHosts" + "finalHostUuids" ], - "line": 490, + "line": 622, "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java" }, + { + "raw": "mini storage[uuid:%s] has to be empty before restoring bits from zbox. please clean it up.", + "en_US": "mini storage[uuid:{0}] has to be empty before restoring bits from zbox. please clean it up.", + "zh_CN": "从ZBox还原位之前,小型存储[uuid:{0}]必须为空。请把它清理干净。", + "arguments": [ + "msg.getPrimaryStorageUuid()" + ], + "line": 91, + "fileName": "src/main/java/org/zstack/storage/primary/ministorage/MiniToZBoxBackupStorageMediator.java" + }, { "raw": "there has been a nfs primary storage having url as %s in zone[uuid:%s]", "en_US": "there has been a nfs primary storage having url as {0} in zone[uuid:{1}]", @@ -19443,12 +31426,23 @@ "line": 96, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsApiParamChecker.java" }, + { + "raw": "vm[uuid:%s] is not Running, Paused or Stopped, current state is %s", + "en_US": "vm[uuid:{0}] is not Running, Paused or Stopped, current state is {1}", + "zh_CN": "云主机[uuid:{0}]不是运行中、已暂停或者已停止状态,现在的状态是{1}", + "arguments": [ + "vol.getVmInstanceUuid()", + "state" + ], + "line": 694, + "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" + }, { "raw": "cannot find usable backend", "en_US": "cannot find usable backend", "zh_CN": "无法找到可用的NFS主存储后端", "arguments": [], - "line": 227, + "line": 303, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { @@ -19456,7 +31450,7 @@ "en_US": "no usable backend found", "zh_CN": "无法找到可用的NFS主存储后端", "arguments": [], - "line": 286, + "line": 362, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { @@ -19470,7 +31464,7 @@ "msg.getSnapshot().getUuid()", "msg.getSnapshot().getName()" ], - "line": 426, + "line": 520, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { @@ -19483,18 +31477,7 @@ "msg.getVolume().getUuid()", "msg.getVolume().getRootImageUuid()" ], - "line": 457, - "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" - }, - { - "raw": "vm[uuid:%s] is not Running, Paused or Stopped, current state is %s", - "en_US": "vm[uuid:{0}] is not Running, Paused or Stopped, current state is {1}", - "zh_CN": "云主机[uuid:{0}]不是运行中、已暂停或者已停止状态,现在的状态是{1}", - "arguments": [ - "vol.getVmInstanceUuid()", - "state" - ], - "line": 536, + "line": 551, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { @@ -19504,20 +31487,20 @@ "arguments": [ "self.getUuid()" ], - "line": 579, + "line": 737, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { "raw": "the NFS primary storage[uuid:%s, name:%s] cannot find any usable host to create the data volume[uuid:%s, name:%s]", "en_US": "the NFS primary storage[uuid:{0}, name:{1}] cannot find any usable host to create the data volume[uuid:{2}, name:{3}]", - "zh_CN": "NFS主存储[uuid:{0}, name:{1}]无法找到任何可用的物理机以创建数据云盘[uuid:{2}, name:{3}]", + "zh_CN": "NFS主存储[uuid:{0}, name:{1}]无法找到任何可用的物理机以创建云盘[uuid:{2}, name:{3}]", "arguments": [ "self.getUuid()", "self.getName()", "msg.getVolume().getUuid()", "msg.getVolume().getName()" ], - "line": 809, + "line": 968, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { @@ -19528,7 +31511,7 @@ "self.getUuid()", "self.getName()" ], - "line": 1425, + "line": 1889, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { @@ -19539,19 +31522,19 @@ "self.getUuid()", "self.getName()" ], - "line": 1392, + "line": 1726, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java" }, { "raw": "the NFS primary storage[uuid:%s] is not attached to any clusters, and cannot expunge the root volume[uuid:%s] of the VM[uuid:%s]", "en_US": "the NFS primary storage[uuid:{0}] is not attached to any clusters, and cannot expunge the root volume[uuid:{1}] of the VM[uuid:{2}]", - "zh_CN": "NFS主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除VM[uuid:{2}]的根云盘[uuid:{1}]", + "zh_CN": "NFS主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除VM[uuid:{2}]的云盘[uuid:{1}]", "arguments": [ "psUuid", "vmUuid", "volumeUuid" ], - "line": 112, + "line": 115, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java" }, { @@ -19561,17 +31544,17 @@ "arguments": [ "pri.getUuid()" ], - "line": 278, + "line": 281, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java" }, { "raw": "cannot find a connected host in cluster which ps [uuid: %s] attached", "en_US": "cannot find a connected host in cluster which ps [uuid: {0}] attached", - "zh_CN": "", + "zh_CN": "在PS[uuid:{0}]连接的集群中找不到已连接的物理机", "arguments": [ "pri.getUuid()" ], - "line": 269, + "line": 272, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java" }, { @@ -19581,17 +31564,17 @@ "arguments": [ "pri.getUuid()" ], - "line": 297, + "line": 300, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java" }, { "raw": "cannot get root image of volume[uuid:%s], may be it create from iso", "en_US": "cannot get root image of volume[uuid:{0}], may be it create from iso", - "zh_CN": "", + "zh_CN": "无法获取卷[uuid:{0}]的根镜像,它可能是从ISO创建的", "arguments": [ "msg.getVolume().getUuid()" ], - "line": 673, + "line": 804, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19607,20 +31590,20 @@ "QCOW3_QEMU_IMG_VERSION", "QCOW3_QEMU_IMG_VERSION" ], - "line": 241, + "line": 248, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { "raw": "unable to create folder[installUrl:%s] on kvm host[uuid:%s, ip:%s], because %s", "en_US": "unable to create folder[installUrl:{0}] on kvm host[uuid:{1}, ip:{2}], because {3}", - "zh_CN": "", + "zh_CN": "无法在KVM物理机[uuid:{1},IP:{2}]上创建文件夹[InstallUrl:{0}],原因是{3}", "arguments": [ "cmd.getInstallUrl()", "host.getUuid()", "host.getManagementIp()", "rsp.getError()" ], - "line": 316, + "line": 323, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19630,7 +31613,7 @@ "arguments": [ "inv.getUuid()" ], - "line": 394, + "line": 401, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19642,7 +31625,7 @@ "huuid", "reply.isSuccess() ? rsp.getError() : reply.getError()" ], - "line": 433, + "line": 440, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19652,7 +31635,7 @@ "arguments": [ "msg.getHostUuid()" ], - "line": 699, + "line": 879, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19664,7 +31647,7 @@ "inv.getUuid()", "rsp.getError()" ], - "line": 835, + "line": 1017, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19678,19 +31661,19 @@ "host.getManagementIp()", "rsp.getError()" ], - "line": 947, + "line": 1131, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { "raw": "failed to delete bits[%s] on nfs primary storage[uuid:%s], %s, will clean up installPath, pinv.getUuid(), rsp.getError()", "en_US": "failed to delete bits[{0}] on nfs primary storage[uuid:{1}], {2}, will clean up installPath, pinv.getUuid(), rsp.getError()", - "zh_CN": "", + "zh_CN": "无法删除NFS主存储[uuid:{1}]上的位[{0}],{2},将清除InstallPath、PINV.Getuuid()、RSP.GetError()", "arguments": [ "installPath", "pinv.getUuid()", "rsp.getError()" ], - "line": 1051, + "line": 1240, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19704,7 +31687,7 @@ "host.getManagementIp()", "rsp.getError()" ], - "line": 1095, + "line": 1302, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19718,17 +31701,29 @@ "host.getManagementIp()", "rsp.getError()" ], - "line": 1132, + "line": 1339, + "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" + }, + { + "raw": "fails to create root volume[uuid:%s] from cached image[path:%s] because %s", + "en_US": "fails to create root volume[uuid:{0}] from cached image[path:{1}] because {2}", + "zh_CN": "从镜像[path:{1}]创建云盘失败,因为{2}", + "arguments": [ + "volume.getUuid()", + "imageCache.getImageUuid()", + "rsp.getError()" + ], + "line": 1383, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { "raw": "no hosts in the cluster[uuid:%s] are connected", "en_US": "no hosts in the cluster[uuid:{0}] are connected", - "zh_CN": "", + "zh_CN": "集群[uuid:{0}]中没有连接任何物理机", "arguments": [ "clusterUuid" ], - "line": 1270, + "line": 1541, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java" }, { @@ -19742,7 +31737,7 @@ "primaryStorageInstallPath", "rsp.getError()" ], - "line": 158, + "line": 109, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java" }, { @@ -19756,46 +31751,97 @@ "backupStorageInstallPath", "rsp.getError()" ], - "line": 214, + "line": 165, "fileName": "src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java" }, { - "raw": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared mount point storage[uuid:%s] are disconnected", - "en_US": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared mount point storage[uuid:{0}] are disconnected", - "zh_CN": "找不到任何Connected的物理机去执行操作,看起来加载到shared mount point存储的集群上所有物理机都处于Disconnected状态", + "raw": "shareblock says host %s is offline on %s", + "en_US": "shareblock says host {0} is offline on {1}", + "zh_CN": "ShareBlock显示物理机{0}在{1}上处于脱机状态", "arguments": [ - "this.primaryStorageUuid" + "cmd.hostUuid", + "sentinelHostUuid" ], - "line": 65, + "line": 135, + "fileName": "src/main/java/org/zstack/storage/primary/shareblock/ShareBlockHostHeartbeatChecker.java" + }, + { + "raw": "sanlock says host %s is offline on %s", + "en_US": "sanlock says host {0} is offline on {1}", + "zh_CN": "SANlock指出物理机{0}在{1}上处于脱机状态", + "arguments": [ + "cmd.hostIds", + "sentinelHostUuid" + ], + "line": 141, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/HaSanlockHostChecker.java" + }, + { + "raw": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared block group storage[uuid:%s] are disconnected", + "en_US": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared block group storage[uuid:{0}] are disconnected", + "zh_CN": "找不到任何可以执行操作的已连接状态的物理机,所有的共享存储[uuid:{0}]挂载的集群下的物理机都处于已失联状态", + "arguments": [ + "primaryStorageUuid" + ], + "line": 110, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java" + }, + { + "raw": "can not find volume need to operate shared block group primary storage", + "en_US": "can not find volume need to operate shared block group primary storage", + "zh_CN": "找不到能进行共享块存储操作的云盘", + "arguments": [], + "line": 80, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java" + }, + { + "raw": "KVM host which volume[uuid%s] attached disconnected with the shared block group storage[uuid:%s]", + "en_US": "KVM host which volume[uuid{0}] attached disconnected with the shared block group storage[uuid:{1}]", + "zh_CN": "云盘[uuid:{0}]所处的挂载了共享块存储[uuid:{1}]物理机均处于已失联状态", + "arguments": [ + "volumeInventory.getUuid()", + "primaryStorageUuid" + ], + "line": 88, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java" + }, + { + "raw": "can not find qualified kvm host for shared block group primary storage[uuid: %s]", + "en_US": "can not find qualified kvm host for shared block group primary storage[uuid: {0}]", + "zh_CN": "无法找到满足条件的物理机来对共享块存储[uuid: {0}]进行操作", + "arguments": [ + "psUuid" + ], + "line": 98, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java" }, { "raw": "primary storage[uuid: %s] has attached the scsi lun[wwid: %s]", "en_US": "primary storage[uuid: {0}] has attached the scsi lun[wwid: {1}]", - "zh_CN": "", + "zh_CN": "主存储[uuid:{0}]已连接SCSI Lun[WWID:{1}]", "arguments": [ "sharedBlockVO.getSharedBlockGroupUuid()", "scsiLunVO.getWwid()" ], - "line": 77, + "line": 81, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java" }, { "raw": "the vm[uuid: %s] does not has additional qmp socket, it may because of the vm start without the global config[vm.additionalQmp] enabled, please make sure it enabled and reboot vm in zstack", "en_US": "the vm[uuid: {0}] does not has additional qmp socket, it may because of the vm start without the global config[vm.additionalQmp] enabled, please make sure it enabled and reboot vm in zstack", - "zh_CN": "", + "zh_CN": "VM[uuid:{0}]没有其他QMP套接字,这可能是因为VM在未启用全局配置[VM.AdditionalQMP]的情况下启动,请确保其已启用并在ZStack中重新启动VM", "arguments": [ "msg.getVmInstanceUuid()" ], - "line": 100, + "line": 105, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java" }, { "raw": "must specify at least one disk when add shared block group primary storage", "en_US": "must specify at least one disk when add shared block group primary storage", - "zh_CN": "添加共享块存储时必须指定至少一个硬盘", + "zh_CN": "添加共享块存储时必须指定至少一个云盘", "arguments": [], - "line": 125, + "line": 130, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java" }, { @@ -19808,7 +31854,7 @@ "vo.getDescription()", "vo.getSharedBlockGroupUuid()" ], - "line": 137, + "line": 142, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java" }, { @@ -19818,20 +31864,31 @@ "arguments": [ "msg.getUuid()" ], - "line": 160, + "line": 165, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java" }, { "raw": "shared volume[uuid: %s] on shared block group primary storage has attached to not stopped vm instances[uuids: %s]", "en_US": "shared volume[uuid: {0}] on shared block group primary storage has attached to not stopped vm instances[uuids: {1}]", - "zh_CN": "SharedBlock存储上的共享云盘[uuid: {0}]加载到了不是停止状态的虚拟机[uuid: {1}],请先从虚拟机卸载或将虚拟机停止", + "zh_CN": "SharedBlock存储上的共享云盘[uuid: {0}]加载到了不是停止状态的云主机[uuid: {1}],请先从云主机卸载或将云主机停止", "arguments": [ "volumeUuid", "notStoppedVmUuids" ], - "line": 229, + "line": 234, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java" }, + { + "raw": "cannot find proper hypervisorType for primary storage[uuid:%s] to handle image format or volume format[%s]", + "en_US": "cannot find proper hypervisorType for primary storage[uuid:{0}] to handle image format or volume format[{1}]", + "zh_CN": "对主存储[uuid:{0}]来说不能发现合适的管理程序类型来处理镜像格式或云盘格式[{1}]", + "arguments": [ + "psUuid", + "imageFormat" + ], + "line": 1665, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" + }, { "raw": "the shared mount point primary storage[uuid:%s, name:%s] cannot find any available host in attached clusters for instantiating the volume", "en_US": "the shared mount point primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume", @@ -19840,7 +31897,7 @@ "self.getUuid()", "self.getName()" ], - "line": 301, + "line": 344, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" }, { @@ -19850,7 +31907,7 @@ "arguments": [ "getSelfInventory().getUuid()" ], - "line": 530, + "line": 697, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" }, { @@ -19861,23 +31918,34 @@ "self.getUuid()", "self.getName()" ], - "line": 880, + "line": 1100, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" + }, + { + "raw": "the SharedBlock primary storage[uuid:%s, name:%s] has not attached to any clusters, or no hosts in the attached clusters are connected", + "en_US": "the SharedBlock primary storage[uuid:{0}, name:{1}] has not attached to any clusters, or no hosts in the attached clusters are connected", + "zh_CN": "SharedBlock主存储[uuid:{0},名称:{1}]尚未连接到任何集群,或者已连接的集群中没有物理机", + "arguments": [ + "self.getUuid()", + "self.getName()" + ], + "line": 1179, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" }, { "raw": "empty migrateVolumeStructs in migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg!", "en_US": "empty migrateVolumeStructs in migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg!", - "zh_CN": "", + "zh_CN": "MigrateEvoluesBetweenSharedBlockGroupPrimaryStorageMsg中的MigrateEvolumeStructs为空!", "arguments": [], - "line": 1070, + "line": 1369, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" }, { "raw": "no volume in migrateVolumeStructs in migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg!", "en_US": "no volume in migrateVolumeStructs in migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg!", - "zh_CN": "", + "zh_CN": "MigrateEvolumesBetweenSharedBlockGroupPrimaryStorageMsg中的MigrateEvolmeStructs中没有卷!", "arguments": [], - "line": 1076, + "line": 1375, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java" }, { @@ -19887,7 +31955,7 @@ "arguments": [ "newValue" ], - "line": 110, + "line": 112, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" }, { @@ -19897,7 +31965,7 @@ "arguments": [ "pri.getUuid()" ], - "line": 438, + "line": 444, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" }, { @@ -19905,10 +31973,52 @@ "en_US": "cannot find a host which has connected shared block to execute command for shared block group primary storage[uuid:{0}]", "zh_CN": "找不到处于连接状态的加载了共享块存储[uuid:{0}]物理机执行命令", "arguments": [ - "pri.getUuid()" + "pri.getUuid()" + ], + "line": 468, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" + }, + { + "raw": "the host[uuid: %s] running on is not available to resize volume[uuid: %s] on shared block group primary storage[uuid: %s]", + "en_US": "the host[uuid: {0}] running on is not available to resize volume[uuid: {1}] on shared block group primary storage[uuid: {2}]", + "zh_CN": "共享块存储[uuid: {2}]上的云盘[uuid : {1}]运行在物理机[uuid : {0}]上,但状态无法执行扩容操作", + "arguments": [ + "vmvo.getHostUuid()", + "volumeInventory.getUuid()", + "volumeInventory.getPrimaryStorageUuid()" + ], + "line": 515, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" + }, + { + "raw": "primary storage[uuid:%s] not found", + "en_US": "primary storage[uuid:{0}] not found", + "zh_CN": "找不到主存储[uuid:{0}]", + "arguments": [ + "psUuid" + ], + "line": 524, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" + }, + { + "raw": "volume[uuid:%s] not found", + "en_US": "volume[uuid:{0}] not found", + "zh_CN": "未找到卷[uuid:{0}]", + "arguments": [ + "volUuid" + ], + "line": 541, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" + }, + { + "raw": "can not get cluster uuid of volume %s", + "en_US": "can not get cluster uuid of volume {0}", + "zh_CN": "无法获取卷{0}的集群uuid", + "arguments": [ + "volumeUuid" ], - "line": 462, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java" + "line": 81, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockImageStoreBackend.java" }, { "raw": "the image[uuid:%s, name: %s] is not available to download on any backup storage:\\n1. check if image is in status of Deleted\\n2. check if the backup storage on which the image is shown as Ready is attached to the zone[uuid:%s]", @@ -19919,7 +32029,29 @@ "img.getName()", "self.getZoneUuid()" ], - "line": 1104, + "line": 1413, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "the volume[uuid;%s] is attached to a VM[uuid:%s] which is in state of %s, cannot do the snapshot merge", + "en_US": "the volume[uuid;{0}] is attached to a VM[uuid:{1}] which is in state of {2}, cannot do the snapshot merge", + "zh_CN": "云盘[uuid;{0}] 挂载到处于{2}状态的云主机,不能合并快照", + "arguments": [ + "volume.getUuid()", + "volume.getVmInstanceUuid()", + "state" + ], + "line": 1251, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "no connected host found in the cluster[uuid:%s]", + "en_US": "no connected host found in the cluster[uuid:{0}]", + "zh_CN": "cluster[uuid:{0}]不存在已连接的物理机", + "arguments": [ + "clusterUuid" + ], + "line": 1907, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -19930,19 +32062,35 @@ "vol.getVmInstanceUuid()", "state" ], - "line": 832, + "line": 5893, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { - "raw": "the volume[uuid;%s] is attached to a VM[uuid:%s] which is in state of %s, cannot do the snapshot merge", - "en_US": "the volume[uuid;{0}] is attached to a VM[uuid:{1}] which is in state of {2}, cannot do the snapshot merge", - "zh_CN": "云盘[uuid;{0}] 挂载到处于{2}状态的虚拟机,不能合并快照", + "raw": "cannot find backup storage[uuid:%s]", + "en_US": "cannot find backup storage[uuid:{0}]", + "zh_CN": "找不到镜像服务器[uuid:{0}]", "arguments": [ - "volume.getUuid()", - "volume.getVmInstanceUuid()", - "state" + "backupStorageUuid" ], - "line": 986, + "line": 2798, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "can not find volume[uuid: %s]", + "en_US": "can not find volume[uuid: {0}]", + "zh_CN": "找不到云盘[uuid: {0}]", + "arguments": [ + "msg.getVolumeUuid()" + ], + "line": 2260, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "shared volume not support thin provisioning", + "en_US": "shared volume not support thin provisioning", + "zh_CN": "共享云盘不支持精简配置", + "arguments": [], + "line": 773, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -19952,18 +32100,18 @@ "arguments": [ "volume.getUuid()" ], - "line": 1075, + "line": 1340, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { "raw": "the image[uuid: %s, name:%s] is not found on any backup storage", "en_US": "the image[uuid: {0}, name:{1}] is not found on any backup storage", - "zh_CN": "", + "zh_CN": "在任何备份存储上都找不到镜像[uuid:{0},名称:{1}]", "arguments": [ "img.getUuid()", "img.getName()" ], - "line": 1120, + "line": 1429, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -19973,62 +32121,23 @@ "arguments": [ "ret.firstAccessHosts.stream().map( h -\u003e h.hostUuid).collect(Collectors.toList())" ], - "line": 1561, + "line": 2043, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { "raw": "not support convert thin volume to thick volume yet", "en_US": "not support convert thin volume to thick volume yet", - "zh_CN": "", + "zh_CN": "尚不支持将精简卷转换为密集卷", "arguments": [], - "line": 1867, + "line": 2400, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { "raw": "expected status is %s and current status", "en_US": "expected status is {0} and current status", - "zh_CN": "", - "arguments": [], - "line": 1921, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" - }, - { - "raw": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared block group storage[uuid:%s] are disconnected", - "en_US": "cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared block group storage[uuid:{0}] are disconnected", - "zh_CN": "找不到任何可以执行操作的已连接状态的物理机,所有的共享存储[uuid:{0}]挂载的集群下的物理机都处于已失联状态", - "arguments": [ - "self.getUuid()" - ], - "line": 2372, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" - }, - { - "raw": "can not find volume need to operate shared block group primary storage", - "en_US": "can not find volume need to operate shared block group primary storage", - "zh_CN": "找不到能进行共享块存储操作的云盘", + "zh_CN": "预期状态为{0},当前状态为", "arguments": [], - "line": 2344, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" - }, - { - "raw": "KVM host which volume[uuid%s] attached disconnected with the shared block group storage[uuid:%s]", - "en_US": "KVM host which volume[uuid{0}] attached disconnected with the shared block group storage[uuid:{1}]", - "zh_CN": "云盘[uuid:{0}]所处的挂载了共享块存储[uuid:{1}]物理机均处于已失联状态", - "arguments": [ - "volumeInventory.getUuid()", - "self.getUuid()" - ], - "line": 2352, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" - }, - { - "raw": "can not find qualified kvm host for shared block group primary storage[uuid: %s]", - "en_US": "can not find qualified kvm host for shared block group primary storage[uuid: {0}]", - "zh_CN": "无法找到满足条件的物理机来对共享块存储[uuid: {0}]进行操作", - "arguments": [ - "psUuid" - ], - "line": 2361, + "line": 2453, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20039,40 +32148,17 @@ "spec.getVmInventory().getUuid()", "String.join(\",\", psUuids)" ], - "line": 2779, + "line": 3409, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { "raw": "QCow2 shared volume[uuid:%s] is not supported", "en_US": "QCow2 shared volume[uuid:{0}] is not supported", - "zh_CN": "", + "zh_CN": "不支持QCOW2共享云盘[uuid:{0}]", "arguments": [ "volume.getUuid()" ], - "line": 2954, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" - }, - { - "raw": "can not find any available host to resize volume[uuid: %s] on shared block group primary storage[uuid: %s]", - "en_US": "can not find any available host to resize volume[uuid: {0}] on shared block group primary storage[uuid: {1}]", - "zh_CN": "无法找到合适的物理机来对共享块存储[uuid: {1}]上的云盘[uuid: {0}]执行扩容", - "arguments": [ - "volumeVO.getUuid()", - "volumeVO.getPrimaryStorageUuid()" - ], - "line": 3819, - "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" - }, - { - "raw": "the host[uuid: %s] running on is not available to resize volume[uuid: %s] on shared block group primary storage[uuid: %s]", - "en_US": "the host[uuid: {0}] running on is not available to resize volume[uuid: {1}] on shared block group primary storage[uuid: {2}]", - "zh_CN": "共享块存储[uuid: {2}]上的云盘[uuid : {1}]运行在物理机[uuid : {0}]上,但状态无法执行扩容操作", - "arguments": [ - "struct.getVmHostUuid()", - "volumeVO.getUuid()", - "volumeVO.getPrimaryStorageUuid()" - ], - "line": 3825, + "line": 3584, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20083,7 +32169,7 @@ "msg.getVolumeUuid()", "msg.getTargetPrimaryStorageUuid()" ], - "line": 3943, + "line": 4650, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20094,7 +32180,7 @@ "msg.getPrimaryStorageUuid()", "msg.getTargetPrimaryStorageUuid()" ], - "line": 4001, + "line": 4708, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20102,7 +32188,7 @@ "en_US": "only support full", "zh_CN": "共享块存储目前只支持全量快照", "arguments": [], - "line": 3956, + "line": 4663, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20114,7 +32200,7 @@ "msg.getPrimaryStorageUuid()", "msg.getTargetPrimaryStorageUuid()" ], - "line": 3984, + "line": 4691, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20126,7 +32212,7 @@ "msg.getTargetPrimaryStorageUuid()", "msg.getTargetPrimaryStorageUuid()" ], - "line": 3993, + "line": 4700, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { @@ -20136,25 +32222,58 @@ "arguments": [ "msg.getPrimaryStorageUuid()" ], - "line": 4045, + "line": 4753, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "cannot shrink snapshot %s, because volume %s not ready", + "en_US": "cannot shrink snapshot {0}, because volume {1} not ready", + "zh_CN": "无法收缩快照{0},因为卷{1}未就绪", + "arguments": [ + "snapshotVO.getUuid()", + "volumeVO.getUuid()" + ], + "line": 4971, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "cannot shrink snapshot %s, beacuse vm %s not in Running/Stopped state", + "en_US": "cannot shrink snapshot {0}, beacuse vm {1} not in Running/Stopped state", + "zh_CN": "无法收缩快照{0},因为VM{1}未处于正在运行/已停止状态", + "arguments": [ + "snapshotVO.getUuid()", + "instanceVO.getUuid()" + ], + "line": 5147, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { "raw": "get null install path in snapshot for vm %s", "en_US": "get null install path in snapshot for vm {0}", - "zh_CN": "", + "zh_CN": "在云主机{0}的快照中获取Null安装路径", "arguments": [ "vmVolumesStruct.vmInstanceVO.getUuid()" ], - "line": 4386, + "line": 5394, + "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" + }, + { + "raw": "dest path %s not belong to volume %s any snapshot", + "en_US": "dest path {0} not belong to volume {1} any snapshot", + "zh_CN": "目标路径{0}不属于任何快照的卷{1}", + "arguments": [ + "msg.getDstPath()", + "msg.getVolume().getUuid()" + ], + "line": 5707, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java" }, { "raw": "migrate volume without snapshot on shared block is not support to cancel.", "en_US": "migrate volume without snapshot on shared block is not support to cancel.", - "zh_CN": "", + "zh_CN": "不支持取消在共享数据块上迁移不带快照的卷。", "arguments": [], - "line": 37, + "line": 33, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkCancelMigrateVolumeFlow.java" }, { @@ -20167,7 +32286,7 @@ "dstVolumeFolderPath", "reply1.getResourceUuid()" ], - "line": 129, + "line": 131, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java" }, { @@ -20179,7 +32298,7 @@ "volumeVO.getActualSize()", "dstPsInv.getAvailablePhysicalCapacity()" ], - "line": 263, + "line": 271, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java" }, { @@ -20191,7 +32310,7 @@ "zoneUuid", "zoneUuid" ], - "line": 194, + "line": 202, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java" }, { @@ -20204,7 +32323,7 @@ "image.getActualSize()", "dstPsInv.getAvailablePhysicalCapacity()" ], - "line": 217, + "line": 225, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java" }, { @@ -20217,6 +32336,18 @@ "line": 70, "fileName": "src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkRollbackMigrateVolumeFlow.java" }, + { + "raw": "why volume[uuid:%s, installPath:%s] not in directory %s", + "en_US": "why volume[uuid:{0}, installPath:{1}] not in directory {2}", + "zh_CN": "为什么卷[uuid:{0},InstallPath:{1}]不在目录{2}中", + "arguments": [ + "cmd.volumeUuid", + "msg.getVolume().getInstallPath()", + "cmd.srcDir" + ], + "line": 2415, + "fileName": "src/main/java/org/zstack/storage/primary/smp/KvmBackend.java" + }, { "raw": "hosts[uuid:%s] have the same mount path, but actually mount different storage.", "en_US": "hosts[uuid:{0}] have the same mount path, but actually mount different storage.", @@ -20224,38 +32355,49 @@ "arguments": [ "ret.firstAccessHostUuids" ], - "line": 1673, + "line": 2184, "fileName": "src/main/java/org/zstack/storage/primary/smp/KvmBackend.java" }, { "raw": "host[uuid:%s] might mount storage which is different from SMP[uuid:%s], please check it", "en_US": "host[uuid:{0}] might mount storage which is different from SMP[uuid:{1}], please check it", - "zh_CN": "", + "zh_CN": "物理机[uuid:{0}]可能装载与SMP[uuid:{1}]不同的存储,请检查", "arguments": [ "msg.getHostUuid()", "msg.getPrimaryStorageUuid()" ], - "line": 1837, + "line": 2372, "fileName": "src/main/java/org/zstack/storage/primary/smp/KvmBackend.java" }, + { + "raw": "volume[uuid:%s] has reference volume[%s], can not change volume type before flatten them and their descendants", + "en_US": "volume[uuid:{0}] has reference volume[{1}], can not change volume type before flatten them and their descendants", + "zh_CN": "卷[uuid:{0}]具有引用卷[{1}],在展平它们及其后代之前无法更改卷类型", + "arguments": [ + "volumeUuid", + "infos.toString()" + ], + "line": 1139, + "fileName": "src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java" + }, { "raw": "not supported operation", "en_US": "not supported operation", "zh_CN": "不支持的操作", "arguments": [], - "line": 497, + "line": 597, "fileName": "src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java" }, { "raw": "the SMP primary storage[uuid:%s] is not attached to any clusters, and cannot expunge the root volume[uuid:%s] of the VM[uuid:%s]", "en_US": "the SMP primary storage[uuid:{0}] is not attached to any clusters, and cannot expunge the root volume[uuid:{1}] of the VM[uuid:{2}]", - "zh_CN": "SMP主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除云主机[uuid:{2}]的根云盘[uuid:{1}]", + "zh_CN": "SMP主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除云主机[uuid:{2}]的云盘[uuid:{1}]", "arguments": [ "psUuid", "vmUuid", "volumeUuid" ], - "line": 106, + "line": 109, "fileName": "src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java" }, { @@ -20265,7 +32407,7 @@ "arguments": [ "pri.getUuid()" ], - "line": 300, + "line": 303, "fileName": "src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java" }, { @@ -20275,7 +32417,7 @@ "arguments": [ "pri.getUuid()" ], - "line": 320, + "line": 323, "fileName": "src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java" }, { @@ -20286,15 +32428,59 @@ "line": 25, "fileName": "src/main/java/org/zstack/storage/primary/smp/SharedMountPointApiInterceptor.java" }, + { + "raw": "failed to cancel deletion job. Volume[uuid:%s] not exists.", + "en_US": "failed to cancel deletion job. Volume[uuid:{0}] not exists.", + "zh_CN": "无法取消删除作业。卷[uuid:{0}]不存在。", + "arguments": [], + "line": 96, + "fileName": "src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java" + }, + { + "raw": "failed to cancel deletion job. Volume[uuid:%s] not attached to any vm, offline snapshot deletion do not support cancel.", + "en_US": "failed to cancel deletion job. Volume[uuid:{0}] not attached to any vm, offline snapshot deletion do not support cancel.", + "zh_CN": "无法取消删除作业。卷[uuid:{0}]未连接到任何VM,脱机快照删除不支持取消。", + "arguments": [], + "line": 100, + "fileName": "src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java" + }, + { + "raw": "failed to cancel deletion job. Volume[uuid:%s] attached vm not exists, offline snapshot deletion do not support cancel.", + "en_US": "failed to cancel deletion job. Volume[uuid:{0}] attached vm not exists, offline snapshot deletion do not support cancel.", + "zh_CN": "无法取消删除作业。卷[uuid:{0}]连接的VM不存在,脱机快照删除不支持取消。", + "arguments": [], + "line": 106, + "fileName": "src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java" + }, + { + "raw": "failed to cancel deletion job. Volume[uuid:%s] attached vm not in state %s offline snapshot deletion do not support cancel.", + "en_US": "failed to cancel deletion job. Volume[uuid:{0}] attached vm not in state {1} offline snapshot deletion do not support cancel.", + "zh_CN": "无法取消删除作业。卷[uuid:{0}]连接的VM未处于状态{1}脱机快照删除不支持取消。", + "arguments": [ + "VmInstanceState.Running" + ], + "line": 111, + "fileName": "src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java" + }, + { + "raw": "volume snapshot[uuids:%s] is in state Disabled, cannot revert volume to it", + "en_US": "volume snapshot[uuids:{0}] is in state Disabled, cannot revert volume to it", + "zh_CN": "卷快照[uuid:{0}]处于禁用状态,无法将卷恢复为该状态", + "arguments": [ + "disabledSnapshotUuids" + ], + "line": 100, + "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java" + }, { "raw": "Can not take memory snapshot, expected vm states are [%s, %s]", "en_US": "Can not take memory snapshot, expected vm states are [{0}, {1}]", - "zh_CN": "", + "zh_CN": "无法获取内存快照,预期的VM状态为[{0},{1}]", "arguments": [ "VmInstanceState.Running.toString()", "VmInstanceState.Paused.toString()" ], - "line": 88, + "line": 121, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java" }, { @@ -20305,7 +32491,7 @@ "msg.getUuid()", "state" ], - "line": 155, + "line": 188, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java" }, { @@ -20315,50 +32501,50 @@ "arguments": [ "msg.getUuid()" ], - "line": 160, + "line": 193, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java" }, { "raw": "not support delete snapshots on different volumes[uuid: %s, %s]", "en_US": "not support delete snapshots on different volumes[uuid: {0}, {1}]", - "zh_CN": "", + "zh_CN": "不支持删除不同卷上的快照[uuid:{0},{1}]", "arguments": [ "msg.getVolumeUuid()", "snapshotVO.getVolumeUuid()" ], - "line": 178, + "line": 211, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java" }, { "raw": "can not find volume uuid for snapshosts[uuid: %s]", "en_US": "can not find volume uuid for snapshosts[uuid: {0}]", - "zh_CN": "", + "zh_CN": "找不到快照物理机[uuid:{0}]的卷uuid", "arguments": [ "msg.getUuids()" ], - "line": 182, + "line": 215, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java" }, { - "raw": "Unsupported maximum snapshot number (%d) for volume [uuid:%s]", - "en_US": "Unsupported maximum snapshot number ({0}) for volume [uuid:{1}]", - "zh_CN": "", + "raw": "after subtracting reserved capacity[%s], there is no primary storage having required size[%s bytes], may be the threshold of primary storage physical capacity setting is lower", + "en_US": "after subtracting reserved capacity[{0}], there is no primary storage having required size[{1} bytes], may be the threshold of primary storage physical capacity setting is lower", + "zh_CN": "减去保留容量[{0}]后,没有具有所需大小[{1}字节]的主存储,可能是主存储物理容量设置的阈值较低", "arguments": [ - "maxIncrementalSnapshotNum", - "vo.getVolumeUuid()" + "PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value()", + "volumeSize" ], - "line": 521, + "line": 834, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java" }, { - "raw": "cannot ask primary storage[uuid:%s] for volume snapshot capability, see detail [%s]", - "en_US": "cannot ask primary storage[uuid:{0}] for volume snapshot capability, see detail [{1}]", - "zh_CN": "", + "raw": "Unsupported maximum snapshot number (%d) for volume [uuid:%s]", + "en_US": "Unsupported maximum snapshot number ({0}) for volume [uuid:{1}]", + "zh_CN": "不支持卷[uuid:{1}]的最大快照数({0})", "arguments": [ - "vol.getUuid()", - "reply.getError()" + "maxIncrementalSnapshotNum", + "vo.getVolumeUuid()" ], - "line": 618, + "line": 617, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java" }, { @@ -20369,27 +32555,37 @@ "primaryStorageUuid", "vol.getUuid()" ], - "line": 814, + "line": 1044, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java" }, { "raw": "cannot find type for primaryStorage [%s]", "en_US": "cannot find type for primaryStorage [{0}]", - "zh_CN": "", + "zh_CN": "找不到PrimaryStorage[{0}]的类型", "arguments": [ "vol.getPrimaryStorageUuid()" ], - "line": 780, + "line": 1010, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java" }, { "raw": "cannot find snapshot: %s", "en_US": "cannot find snapshot: {0}", - "zh_CN": "", + "zh_CN": "找不到快照:{0}", "arguments": [ "uuid" ], - "line": 877, + "line": 1107, + "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java" + }, + { + "raw": "this resource type %s does not support querying memory snapshot references", + "en_US": "this resource type {0} does not support querying memory snapshot references", + "zh_CN": "此资源类型{0}不支持查询内存快照引用", + "arguments": [ + "msg.getResourceType()" + ], + "line": 1176, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java" }, { @@ -20400,7 +32596,17 @@ "currentRoot.getUuid()", "currentRoot.getName()" ], - "line": 153, + "line": 162, + "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java" + }, + { + "raw": "snapshot or its desendant has reference volume[uuids:%s]", + "en_US": "snapshot or its desendant has reference volume[uuids:{0}]", + "zh_CN": "快照或其目标具有引用卷[uuid:{0}]", + "arguments": [ + "refVolUuids" + ], + "line": 418, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java" }, { @@ -20412,22 +32618,42 @@ "failSnapshot.getName()", "evt" ], - "line": 759, + "line": 1004, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java" }, { "raw": "unable to reset volume[uuid:%s] to snapshot[uuid:%s], the vm[uuid:%s] volume attached to is not in Stopped state, current state is %s", "en_US": "unable to reset volume[uuid:{0}] to snapshot[uuid:{1}], the vm[uuid:{2}] volume attached to is not in Stopped state, current state is {3}", - "zh_CN": "不能重置云盘[uuid:{0}]到快照[uuid:{1}]状态,云盘的虚拟机[uuid:{2}]未处于停止状态,当前状态是{3}", + "zh_CN": "不能重置云盘[uuid:{0}]到快照[uuid:{1}]状态,云盘的云主机[uuid:{2}]未处于停止状态,当前状态是{3}", "arguments": [ "volumeInventory.getUuid()", "currentRoot.getUuid()", "vmUuid", "state" ], - "line": 1465, + "line": 1847, + "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java" + }, + { + "raw": "current snapshot:%s is not latest snapshot, cannot mark as volume", + "en_US": "current snapshot:{0} is not latest snapshot, cannot mark as volume", + "zh_CN": "当前快照:{0}不是最新的快照,无法标记为卷", + "arguments": [ + "currentRoot.getUuid()" + ], + "line": 2228, "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java" }, + { + "raw": "no bundle found for type:%s", + "en_US": "no bundle found for type:{0}", + "zh_CN": "未找到类型为{0}的包", + "arguments": [ + "ext.getArchiveBundleCanonicalName()" + ], + "line": 282, + "fileName": "src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupBase.java" + }, { "raw": "snapshot(s) %s in the group has been deleted, can only revert one by one.", "en_US": "snapshot(s) {0} in the group has been deleted, can only revert one by one.", @@ -20435,7 +32661,7 @@ "arguments": [ "String.join(\", \", deletedSnapshotInfos)" ], - "line": 77, + "line": 89, "fileName": "src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java" }, { @@ -20445,7 +32671,7 @@ "arguments": [ "String.join(\", \", detachedVolInfos)" ], - "line": 81, + "line": 93, "fileName": "src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java" }, { @@ -20455,15 +32681,26 @@ "arguments": [ "volInfos" ], - "line": 89, + "line": 101, "fileName": "src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java" }, { - "raw": "Can\u0027t attach volume to VM, no qualified cluster", - "en_US": "Can\u0027t attach volume to VM, no qualified cluster", - "zh_CN": "不能加载云盘到虚拟机上,没有可用集群", - "arguments": [], - "line": 269, + "raw": "Can\u0027t attach volume to VM, no qualified cluster", + "en_US": "Can\u0027t attach volume to VM, no qualified cluster", + "zh_CN": "不能加载云盘到云主机上,没有可用集群", + "arguments": [], + "line": 292, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "primaryStorageUuid conflict, the primary storage specified by the disk offering is %s, and the primary storage specified in the creation parameter is %s", + "en_US": "primaryStorageUuid conflict, the primary storage specified by the disk offering is {0}, and the primary storage specified in the creation parameter is {1}", + "zh_CN": "PrimaryStorageuuid冲突,磁盘产品指定的主存储为{0},而创建参数中指定的主存储为{1}", + "arguments": [ + "psUuid", + "msg.getPrimaryStorageUuid()" + ], + "line": 407, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { @@ -20474,50 +32711,51 @@ "vol.getUuid()", "vol.getStatus()" ], - "line": 137, + "line": 156, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "volume[uuid:%s, type:%s], can\u0027t create snapshot", "en_US": "volume[uuid:{0}, type:{1}], can\u0027t create snapshot", - "zh_CN": "", + "zh_CN": "卷[uuid:{0},类型:{1}],无法创建快照", "arguments": [ "msg.getVolumeUuid()", "type" ], - "line": 113, + "line": 126, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { - "raw": "volume[uuid:%s] is root volume", - "en_US": "volume[uuid:{0}] is root volume", - "zh_CN": "", + "raw": "volume[uuid:%s] is not in state Enabled, current is %s, can\u0027t create snapshot", + "en_US": "volume[uuid:{0}] is not in state Enabled, current is {1}, can\u0027t create snapshot", + "zh_CN": "卷[uuid:{0}]未处于启用状态,当前为{1},无法创建快照", "arguments": [ - "msg.getRootVolumeUuid()" + "msg.getVolumeUuid()", + "state" ], - "line": 127, + "line": 131, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "Can not take memory snapshot, vm current state[%s], but expect state are [%s, %s]", "en_US": "Can not take memory snapshot, vm current state[{0}], but expect state are [{1}, {2}]", - "zh_CN": "", + "zh_CN": "无法获取内存快照,VM当前状态为[{0}],但预期状态为[{1},{2}]", "arguments": [ "vmvo.getState().toString()", "VmInstanceState.Running.toString()", "VmInstanceState.Paused.toString()" ], - "line": 131, + "line": 150, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "the volume[uuid:%s] is not in status of deleted. This is operation is to recover a deleted data volume", "en_US": "the volume[uuid:{0}] is not in status of deleted. This is operation is to recover a deleted data volume", - "zh_CN": "云盘[uuid:{0}]未处于删除状态。此操作将覆盖一个被删除的数据云盘", + "zh_CN": "云盘[uuid:{0}]未处于删除状态。此操作将覆盖一个被删除的云盘", "arguments": [ "msg.getVolumeUuid()" ], - "line": 150, + "line": 183, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { @@ -20527,7 +32765,7 @@ "arguments": [ "vol.getUuid()" ], - "line": 296, + "line": 319, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { @@ -20539,7 +32777,7 @@ "ImageMediaType.DataVolumeTemplate", "type" ], - "line": 168, + "line": 201, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { @@ -20550,7 +32788,7 @@ "img.getUuid()", "img.getState()" ], - "line": 172, + "line": 205, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { @@ -20561,142 +32799,134 @@ "img.getUuid()", "img.getStatus()" ], - "line": 176, - "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" - }, - { - "raw": "DataVolumeFromVolumeTemplate not support Shareable", - "en_US": "DataVolumeFromVolumeTemplate not support Shareable", - "zh_CN": "", - "arguments": [], - "line": 182, + "line": 209, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "volume[uuid:%s] is Root volume, can not be attach to vm", "en_US": "volume[uuid:{0}] is Root volume, can not be attach to vm", - "zh_CN": "云盘[uuid:{0}]是一个根云盘,不能被手动挂载到其他云主机", + "zh_CN": "云盘[uuid:{0}]是一个云盘,不能被手动挂载到其他云主机", "arguments": [ "msg.getVolumeUuid()" ], - "line": 197, + "line": 221, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "volume[uuid:%s] is in state[%s], data volume can only be attached when state is %s", "en_US": "volume[uuid:{0}] is in state[{1}], data volume can only be attached when state is {2}", - "zh_CN": "云盘[uuid:{0}]处于[{1}]状态,数据云盘只能在处于{2}状态的时候挂载", + "zh_CN": "云盘[uuid:{0}]处于[{1}]状态,云盘只能在处于{2}状态的时候挂载", "arguments": [ "msg.getVolumeUuid()", "state", "VolumeState.Enabled" ], - "line": 204, + "line": 228, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "volume[uuid:%s] is in status[%s], data volume can only be attached when status is %s or %S", "en_US": "volume[uuid:{0}] is in status[{1}], data volume can only be attached when status is {2} or %S", - "zh_CN": "云盘[uuid:{0}]处于[{1}],数据云盘只能在处于{2}或%S状态的时候挂载", + "zh_CN": "云盘[uuid:{0}]处于[{1}],云盘只能在处于{2}或%S状态的时候挂载", "arguments": [ "msg.getVolumeUuid()", "status", "VolumeStatus.Ready", "VolumeStatus.NotInstantiated" ], - "line": 209, + "line": 233, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "data volume[uuid:%s] is not attached to any vm, can\u0027t detach", "en_US": "data volume[uuid:{0}] is not attached to any vm, can\u0027t detach", - "zh_CN": "数据云盘没有被挂载到任何云主机上,不能卸载", + "zh_CN": "云盘没有被挂载到任何云主机上,不能卸载", "arguments": [ "msg.getVolumeUuid()" ], - "line": 216, + "line": 240, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "to detach shareable data volume[uuid:%s], vm uuid is needed.", "en_US": "to detach shareable data volume[uuid:{0}], vm uuid is needed.", - "zh_CN": "卸载共享数据云盘[uuid:{0}]需要虚拟机的uuid", + "zh_CN": "卸载共享云盘[uuid:{0}]需要云主机的uuid", "arguments": [ "msg.getVolumeUuid()" ], - "line": 220, + "line": 244, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "the volume[uuid:%s, name:%s, type:%s] can\u0027t detach it", "en_US": "the volume[uuid:{0}, name:{1}, type:{2}] can\u0027t detach it", - "zh_CN": "", + "zh_CN": "卷[uuid:{0},名称:{1},类型:{2}]无法将其分离", "arguments": [ "vol.getUuid()", "vol.getName()", "vol.getType()" ], - "line": 225, + "line": 249, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "the vm[uuid:%s] doesn\u0027t support to online attach volume[%s] on the basis of that the image platform type of the vm is other ", "en_US": "the vm[uuid:{0}] doesn\u0027t support to online attach volume[{1}] on the basis of that the image platform type of the vm is other ", - "zh_CN": "云主机[uuid:{0}]不支持在线挂载云盘[{1}]。因为这台虚拟机的基础镜像平台类型为“其他”", + "zh_CN": "云主机[uuid:{0}]不支持在线挂载云盘[{1}]。因为这台云主机的基础镜像平台类型为“其他”", "arguments": [ "msg.getVmInstanceUuid()", "msg.getVolumeUuid()" ], - "line": 282, + "line": 305, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "the volume[uuid:%s, name:%s] is Root Volume, can\u0027t attach it", "en_US": "the volume[uuid:{0}, name:{1}] is Root Volume, can\u0027t attach it", - "zh_CN": "不能挂载根云盘[uuid:{0}, name:{1}]", + "zh_CN": "不能挂载云盘[uuid:{0}, name:{1}]", "arguments": [ "vol.getUuid()", "vol.getName()" ], - "line": 287, + "line": 310, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "data volume[uuid:%s] is Disabled, can\u0027t attach", "en_US": "data volume[uuid:{0}] is Disabled, can\u0027t attach", - "zh_CN": "数据云盘已被禁用,不能挂载", + "zh_CN": "云盘已被禁用,不能挂载", "arguments": [ "vol.getUuid()" ], - "line": 292, + "line": 315, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "data volume[uuid:%s] has been attached to some vm, can\u0027t attach again", "en_US": "data volume[uuid:{0}] has been attached to some vm, can\u0027t attach again", - "zh_CN": "数据云盘[uuid:{0}]已经被加载上云主机了,不能再次加载", + "zh_CN": "云盘[uuid:{0}]已经被加载上云主机了,不能再次加载", "arguments": [ "vol.getUuid()" ], - "line": 300, + "line": 323, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "data volume can only be attached when status is [%s, %s], current is %s", "en_US": "data volume can only be attached when status is [{0}, {1}], current is {2}", - "zh_CN": "数据云盘仅能当处于[{0}, {1}]状态挂载,当前状态是{2}", + "zh_CN": "云盘仅能当处于[{0}, {1}]状态挂载,当前状态是{2}", "arguments": [ "VolumeStatus.Ready", "VolumeStatus.NotInstantiated", "vol.getStatus()" ], - "line": 305, + "line": 328, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "data volume[uuid:%s] has format[%s] that can only be attached to hypervisor[%s], but vm[uuid:%s] has hypervisor type[%s]. Can\u0027t attach", "en_US": "data volume[uuid:{0}] has format[{1}] that can only be attached to hypervisor[{2}], but vm[uuid:{3}] has hypervisor type[{4}]. Can\u0027t attach", - "zh_CN": "只有[{1}]格式的数据云盘[uuid:{0}]才能被挂载到管理程序[{2}],但是虚拟机是[{4}]类型的管理程序,数据云盘不能挂载到该虚拟机", + "zh_CN": "只有[{1}]格式的云盘[uuid:{0}]才能被挂载到管理程序[{2}],但是云主机是[{4}]类型的管理程序,云盘不能挂载到该云主机", "arguments": [ "vol.getUuid()", "vol.getFormat()", @@ -20704,49 +32934,60 @@ "msg.getVmInstanceUuid()", "hvType" ], - "line": 313, + "line": 336, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "hypervisor[%s] only allows max %s data volumes to be attached to a single vm; there have been %s data volumes attached to vm[uuid:%s]", "en_US": "hypervisor[{0}] only allows max {1} data volumes to be attached to a single vm; there have been {2} data volumes attached to vm[uuid:{3}]", - "zh_CN": "[{0}]管理程序仅允许最大不超过{1}数据云盘挂载到单个虚拟机。{2} data volumes已经挂载到虚拟机[uuid:{3}]", + "zh_CN": "[{0}]管理程序仅允许最大不超过{1}云盘挂载到单个云主机。{2} data volumes已经挂载到云主机[uuid:{3}]", "arguments": [ "hvType", "maxDataVolumeNum", "count", "msg.getVmInstanceUuid()" ], - "line": 326, + "line": 349, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "Can not attach volume to vm runs on host[uuid: %s] which is disconnected with volume\u0027s storage[uuid: %s]", + "en_US": "Can not attach volume to vm runs on host[uuid: {0}] which is disconnected with volume\u0027s storage[uuid: {1}]", + "zh_CN": "无法将卷附加到物理机[uuid:{0}]上运行的VM,该物理机已与卷的存储[uuid:{1}]断开连接", + "arguments": [ + "hostUuid", + "vol.getPrimaryStorageUuid()" + ], + "line": 367, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "it\u0027s not allowed to backup root volume, uuid:%s", "en_US": "it\u0027s not allowed to backup root volume, uuid:{0}", - "zh_CN": "备份根云盘不被允许,uuid:{0}", + "zh_CN": "备份云盘不被允许,uuid:{0}", "arguments": [ "msg.getUuid()" ], - "line": 338, + "line": 378, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "unexpected disk size settings", "en_US": "unexpected disk size settings", - "zh_CN": "", + "zh_CN": "意外的磁盘大小设置", "arguments": [], - "line": 347, + "line": 387, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { "raw": "volume[uuid:%s, type:%s] can\u0027t be deleted", "en_US": "volume[uuid:{0}, type:{1}] can\u0027t be deleted", - "zh_CN": "", + "zh_CN": "无法删除卷[uuid:{0},类型:{1}]", "arguments": [ "msg.getVolumeUuid()", "type" ], - "line": 365, + "line": 427, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { @@ -20756,124 +32997,393 @@ "arguments": [ "msg.getVolumeUuid()" ], - "line": 370, + "line": 432, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not delete volume[%s], because volume attach to host[%s]", + "en_US": "can not delete volume[{0}], because volume attach to host[{1}]", + "zh_CN": "无法删除卷[{0}],因为卷连接到物理机[{1}]", + "arguments": [ + "msg.getVolumeUuid()", + "hostUuid" + ], + "line": 438, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "it\u0027s not allowed to change state of root volume, uuid:%s", + "en_US": "it\u0027s not allowed to change state of root volume, uuid:{0}", + "zh_CN": "不能改变云盘状态,uuid:{0}", + "arguments": [ + "msg.getUuid()" + ], + "line": 453, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not change volume[%s] state, because volume attach to host[%s]", + "en_US": "can not change volume[{0}] state, because volume attach to host[{1}]", + "zh_CN": "无法更改卷[{0}]状态,因为卷连接到物理机[{1}]", + "arguments": [ + "msg.getVolumeUuid()", + "hostUuid" + ], + "line": 461, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not attach volume[%s] to host[%s], because host[status:%s] is not connected", + "en_US": "can not attach volume[{0}] to host[{1}], because host[status:{2}] is not connected", + "zh_CN": "无法将云盘[{0}]挂载到物理机[{1}],因为物理机[status:{2}]未连接", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getHostUuid()", + "hostStatus" + ], + "line": 469, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "mount path must be absolute path", + "en_US": "mount path must be absolute path", + "zh_CN": "装载路径必须是绝对路径", + "arguments": [], + "line": 474, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not attach volume[%s] to host[%s], because volume is attaching to host[%s]", + "en_US": "can not attach volume[{0}] to host[{1}], because volume is attaching to host[{2}]", + "zh_CN": "无法将云盘[{0}]挂载到物理机[{1}],因为云盘正在挂载到物理机[{2}]", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getHostUuid()", + "hostUuid" + ], + "line": 491, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not attach volume[%s] to host[%s], because the volume[%s] occupies the mount path[%s] on host[%s]", + "en_US": "can not attach volume[{0}] to host[{1}], because the volume[{2}] occupies the mount path[{3}] on host[{4}]", + "zh_CN": "无法将云盘[{0}]挂载到物理机[{1}],因为云盘[{2}]在物理机[{4}]上占用了挂载路径[{3}]", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getHostUuid()", + "msg.getVolumeUuid()", + "mountPath", + "hostUuid" + ], + "line": 495, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not attach volume[%s] to host[%s], because the another volume occupies the mount path[%s]", + "en_US": "can not attach volume[{0}] to host[{1}], because the another volume occupies the mount path[{2}]", + "zh_CN": "无法将云盘[{0}]挂载到物理机[{1}],因为另一个云盘占用了挂载路径[{2}]", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getHostUuid()", + "msg.getMountPath()" + ], + "line": 505, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not detach volume[%s] from host. it may have been detached", + "en_US": "can not detach volume[{0}] from host. it may have been detached", + "zh_CN": "无法从物理机分离卷[{0}]。它可能已经分离了。", + "arguments": [ + "msg.getVolumeUuid()" + ], + "line": 512, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "cannot flatten a shareable volume[uuid:%s]", + "en_US": "cannot flatten a shareable volume[uuid:{0}]", + "zh_CN": "无法平整可共享的卷[uuid:{0}]", + "arguments": [ + "msg.getVolumeUuid()" + ], + "line": 520, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "can not found in used snapshot tree of volume[uuid: %s]", + "en_US": "can not found in used snapshot tree of volume[uuid: {0}]", + "zh_CN": "在卷[uuid:{0}]的已使用快照树中找不到", + "arguments": [ + "msg.getUuid()" + ], + "line": 531, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + }, + { + "raw": "cannot undo not latest snapshot", + "en_US": "cannot undo not latest snapshot", + "zh_CN": "无法撤消不是最新的快照", + "arguments": [], + "line": 541, "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" }, { - "raw": "it\u0027s not allowed to change state of root volume, uuid:%s", - "en_US": "it\u0027s not allowed to change state of root volume, uuid:{0}", - "zh_CN": "不能改变根云盘状态,uuid:{0}", + "raw": "cannot find image cache[imageUuid: %s] for reinit volume", + "en_US": "cannot find image cache[imageUuid: {0}] for reinit volume", + "zh_CN": "找不到重新初始化卷的镜像缓存[imageUuid:{0}]", + "arguments": [ + "self.getRootImageUuid()" + ], + "line": 200, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeBase.java" + }, + { + "raw": "the volume[uuid:%s, name:%s] is not deleted yet, can\u0027t expunge it", + "en_US": "the volume[uuid:{0}, name:{1}] is not deleted yet, can\u0027t expunge it", + "zh_CN": "云盘[uuid:{0}, name:{1}]仍未被删除,不能清除该云盘", + "arguments": [ + "self.getUuid()", + "self.getName()" + ], + "line": 843, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeBase.java" + }, + { + "raw": "volume[uuid%s] should be attached.", + "en_US": "volume[uuid{0}] should be attached.", + "zh_CN": "应附加卷[uuid{0}]。", + "arguments": [], + "line": 1780, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeBase.java" + }, + { + "raw": "only support detached volume, use SetVmBootVolumeMsg instead.", + "en_US": "only support detached volume, use SetVmBootVolumeMsg instead.", + "zh_CN": "仅支持分离卷,请改用SetVMBootVolumeMsg。", + "arguments": [], + "line": 1866, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeBase.java" + }, + { + "raw": "get primaryStorage %s type failed", + "en_US": "get primaryStorage {0} type failed", + "zh_CN": "获取PrimaryStorage{0}类型失败", + "arguments": [ + "msg.getPrimaryStorageUuid()" + ], + "line": 166, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + }, + { + "raw": "primaryStorage type [%s] not support shared volume yet", + "en_US": "primaryStorage type [{0}] not support shared volume yet", + "zh_CN": "主存储类型[{0}]尚不支持共享云盘", + "arguments": [ + "psType" + ], + "line": 170, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + }, + { + "raw": "the image[uuid:%s, name:%s] has been deleted on all backup storage", + "en_US": "the image[uuid:{0}, name:{1}] has been deleted on all backup storage", + "zh_CN": "镜像[uuid:{0}, name:{1}]已经从所有的镜像服务器中删除", + "arguments": [ + "template.getUuid()", + "template.getName()" + ], + "line": 296, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + }, + { + "raw": "cannot find a backup storage on which the image[uuid:%s] is that satisfies all conditions of: 1. has state Enabled 2. has status Connected. 3 has attached to zone in which primary storage[uuid:%s] is", + "en_US": "cannot find a backup storage on which the image[uuid:{0}] is that satisfies all conditions of: 1. has state Enabled 2. has status Connected. 3 has attached to zone in which primary storage[uuid:{1}] is", + "zh_CN": "无法找到一个镜像[uuid:{0}]所在的镜像服务器符合全部的下列条件: 状态启动[state:Enabled],已连接[status:Connected],被挂载到主存储[uuid:{1}]所在的区域中", + "arguments": [ + "template.getUuid()", + "msg.getPrimaryStorageUuid()" + ], + "line": 313, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + }, + { + "raw": "target volume is expunged during volume creation", + "en_US": "target volume is expunged during volume creation", + "zh_CN": "目标卷在卷创建过程中被删除", + "arguments": [], + "line": 868, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + }, + { + "raw": "there should not be more than one %s implementation.", + "en_US": "there should not be more than one {0} implementation.", + "zh_CN": "不允许超过一种实现", + "arguments": [ + "VolumeFactory.class.getSimpleName()" + ], + "line": 1106, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + }, + { + "raw": "volume[uuid:%s] is not root volume", + "en_US": "volume[uuid:{0}] is not root volume", + "zh_CN": "云盘[uuid:{0}]不是云盘", + "arguments": [ + "msg.getUuid()" + ], + "line": 231, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "iothread need qemu version \u003e\u003d %s, but %s on host[%s].", + "en_US": "iothread need qemu version \u003e\u003d {0}, but {1} on host[{2}].", + "zh_CN": "IOThread需要QEMU版本\u003e\u003d{0},但物理机[{2}]上需要{1}。", + "arguments": [ + "IOTHREAD_QEMU_VERSION", + "qemuVersion", + "finalHostUuid" + ], + "line": 95, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "iothread need libvirt version \u003e\u003d %s, but %s on host[%s].", + "en_US": "iothread need libvirt version \u003e\u003d {0}, but {1} on host[{2}].", + "zh_CN": "IOThread需要libvirt版本\u003e\u003d{0},但物理机[{2}]上需要{1}。", "arguments": [ - "msg.getUuid()" + "IOTHREAD_LIBVIRT_VERSION", + "libvirtVersion", + "finalHostUuid" ], - "line": 384, - "fileName": "src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java" + "line": 103, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { - "raw": "the volume[uuid:%s, name:%s] is not deleted yet, can\u0027t expunge it", - "en_US": "the volume[uuid:{0}, name:{1}] is not deleted yet, can\u0027t expunge it", - "zh_CN": "云盘[uuid:{0}, name:{1}]仍未被删除,不能清除该云盘", + "raw": "root volume[%s] cannot set iothreadpin.", + "en_US": "root volume[{0}] cannot set iothreadpin.", + "zh_CN": "根卷[{0}]无法设置ioThreadPin。", "arguments": [ - "self.getUuid()", - "self.getName()" + "msg.getVolumeUuid()" ], - "line": 687, - "fileName": "src/main/java/org/zstack/storage/volume/VolumeBase.java" + "line": 108, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { - "raw": "the image[uuid:%s, name:%s] has been deleted on all backup storage", - "en_US": "the image[uuid:{0}, name:{1}] has been deleted on all backup storage", - "zh_CN": "镜像[uuid:{0}, name:{1}]已经从所有的镜像服务器中删除", + "raw": "current iothread id[%s] is not the same as attached vol[%s] iothread[%s].", + "en_US": "current iothread id[{0}] is not the same as attached vol[{1}] iothread[{2}].", + "zh_CN": "当前ioThread ID[{0}]与附加的卷[{1}]ioThread[{2}]不同。", "arguments": [ - "template.getUuid()", - "template.getName()" + "msg.getIoThreadId()", + "msg.getVolumeUuid()", + "pinInfo[0]" ], - "line": 194, - "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + "line": 115, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { - "raw": "cannot find a backup storage on which the image[uuid:%s] is that satisfies all conditions of: 1. has state Enabled 2. has status Connected. 3 has attached to zone in which primary storage[uuid:%s] is", - "en_US": "cannot find a backup storage on which the image[uuid:{0}] is that satisfies all conditions of: 1. has state Enabled 2. has status Connected. 3 has attached to zone in which primary storage[uuid:{1}] is", - "zh_CN": "无法找到一个镜像[uuid:{0}]所在的镜像服务器符合全部的下列条件: 状态启动[state:Enabled],已连接[status:Connected],被挂载到主存储[uuid:{1}]所在的区域中", + "raw": "snapshot validation is unsupported for volume[uuid: %s]. Volume should be attached to vm", + "en_US": "snapshot validation is unsupported for volume[uuid: {0}]. Volume should be attached to vm", + "zh_CN": "卷[uuid:{0}]不支持快照验证。卷应连接到云主机", "arguments": [ - "template.getUuid()", - "msg.getPrimaryStorageUuid()" + "msg.getUuid()" ], - "line": 211, - "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + "line": 131, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { - "raw": "there should not be more than one %s implementation.", - "en_US": "there should not be more than one {0} implementation.", - "zh_CN": "不允许超过一种实现", + "raw": "snapshot validation is unsupported for volume[uuid: %s]. Attached vm is not in state of [%s, %s]", + "en_US": "snapshot validation is unsupported for volume[uuid: {0}]. Attached vm is not in state of [{1}, {2}]", + "zh_CN": "卷[uuid:{0}]不支持快照验证。连接的云主机未处于[{1},{2}]状态", "arguments": [ - "VolumeFactory.class.getSimpleName()" + "msg.getUuid()", + "VmInstanceState.Running", + "VmInstanceState.Paused" ], - "line": 695, - "fileName": "src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java" + "line": 139, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { "raw": "volume[uuid:%s] can not found", "en_US": "volume[uuid:{0}] can not found", - "zh_CN": "", + "zh_CN": "未找到卷[uuid:{0}]", "arguments": [ "volumeUuid" ], - "line": 77, + "line": 149, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { "raw": "not support take snapshots volume[uuid:%s, uuid:%s] on different vms[uuid:%s, uuid:%s]", "en_US": "not support take snapshots volume[uuid:{0}, uuid:{1}] on different vms[uuid:{2}, uuid:{3}]", - "zh_CN": "", + "zh_CN": "不支持在不同的云主机[uuid:{2},uuid:{3}]上拍摄卷[UUId:{0},UUId:{1}]的快照", "arguments": [ "volumeUuid", "volumeVOS.get(0).getUuid()", "volumeVO.getVmInstanceUuid()", "volumeVOS.get(0).getVmInstanceUuid()" ], - "line": 84, + "line": 156, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { "raw": "volume[uuid:%s] is not ready", "en_US": "volume[uuid:{0}] is not ready", - "zh_CN": "", + "zh_CN": "卷[uuid:{0}]未就绪", "arguments": [ "volumeUuid" ], - "line": 91, + "line": 163, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { "raw": "state of vm[uuid: %s] is %s, not allowed to take snapshots", "en_US": "state of vm[uuid: {0}] is {1}, not allowed to take snapshots", - "zh_CN": "", + "zh_CN": "VM[uuid:{0}]的状态为{1},不允许拍摄快照", "arguments": [ "vmInstanceVO.getUuid()", "vmInstanceVO.getState()" ], - "line": 106, + "line": 178, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { "raw": "volume[uuid:%s] is not data volume", "en_US": "volume[uuid:{0}] is not data volume", - "zh_CN": "云盘[uuid:{0}]不是数据云盘", + "zh_CN": "云盘[uuid:{0}]不是云盘", "arguments": [ "msg.getUuid()" ], - "line": 142, + "line": 188, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { - "raw": "volume[uuid:%s] is not root volume", - "en_US": "volume[uuid:{0}] is not root volume", - "zh_CN": "云盘[uuid:{0}]不是根云盘", + "raw": "can not resize volume[%s], because volume state is Disabled", + "en_US": "can not resize volume[{0}], because volume state is Disabled", + "zh_CN": "无法调整卷[{0}]的大小,因为卷状态已禁用", "arguments": [ - "msg.getUuid()" + "msg.getVolumeUuid()" ], - "line": 162, + "line": 198, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "At least one of vmInstanceUuid or uuid should be set", + "en_US": "At least one of vmInstanceUuid or uuid should be set", + "zh_CN": "至少应设置VMInstanceuuid或uuid中的一个", + "arguments": [], + "line": 212, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "no volume[uuid:%s, vmInstanceUuid:%s] can be found", + "en_US": "no volume[uuid:{0}, vmInstanceUuid:{1}] can be found", + "zh_CN": "找不到卷[uuid:{0},VMInstanceuuid:{1}]", + "arguments": [ + "msg.getUuid()", + "msg.getVmInstanceUuid()" + ], + "line": 227, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { @@ -20881,7 +33391,39 @@ "en_US": "SharedVolume cannot be set bandwidth.", "zh_CN": "共享云盘不允许设置带宽", "arguments": [], - "line": 174, + "line": 245, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "Cannot set legacy params and new params at the same time.", + "en_US": "Cannot set legacy params and new params at the same time.", + "zh_CN": "不能同时设置旧参数和新参数。", + "arguments": [], + "line": 254, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "Cannot set the read/write and the total IOPS limits at the same time.", + "en_US": "Cannot set the read/write and the total IOPS limits at the same time.", + "zh_CN": "无法同时设置读/写和总IOPS限制。", + "arguments": [], + "line": 259, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "Cannot set the read/write and the total bandwidth limits at the same time.", + "en_US": "Cannot set the read/write and the total bandwidth limits at the same time.", + "zh_CN": "无法同时设置读/写和总带宽限制。", + "arguments": [], + "line": 264, + "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" + }, + { + "raw": "The volume bandwidth cannot be null, must give a volume bandwidth value.", + "en_US": "The volume bandwidth cannot be null, must give a volume bandwidth value.", + "zh_CN": "卷带宽不能为空,必须提供卷带宽值。", + "arguments": [], + "line": 273, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { @@ -20892,7 +33434,7 @@ "vo.getType()", "vo.getUuid()" ], - "line": 182, + "line": 284, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { @@ -20900,7 +33442,7 @@ "en_US": "Minimum increase size should be larger than 4MB", "zh_CN": "最小扩容量需要大于4MB", "arguments": [], - "line": 189, + "line": 291, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { @@ -20908,7 +33450,7 @@ "en_US": "Expansion operation not allowed at all host disable", "zh_CN": "扩展操作不被允许在所有不可用的物理机上进行", "arguments": [], - "line": 213, + "line": 315, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { @@ -20916,18 +33458,18 @@ "en_US": "Expansion operation not allowed at host disable", "zh_CN": "扩展操作不被允许在不可用的物理机上进行", "arguments": [], - "line": 200, + "line": 302, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { "raw": "shared volume[uuid: %s] has attached to not stopped vm instances[uuids: %s]", "en_US": "shared volume[uuid: {0}] has attached to not stopped vm instances[uuids: {1}]", - "zh_CN": "", + "zh_CN": "共享云盘[uuid:{0}]已连接到未停止的云主机实例[uuid:{1}]", "arguments": [ "vo.getUuid()", "notStoppedVmUuids" ], - "line": 239, + "line": 341, "fileName": "src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java" }, { @@ -20937,7 +33479,7 @@ "arguments": [ "msg.getResourceType()" ], - "line": 56, + "line": 79, "fileName": "src/main/java/org/zstack/tag/TagApiInterceptor.java" }, { @@ -20947,15 +33489,15 @@ "arguments": [ "msg.getUuid()" ], - "line": 74, + "line": 102, "fileName": "src/main/java/org/zstack/tag/TagApiInterceptor.java" }, { "raw": "The argument :\u0027resourceType\u0027 doesn\u0027t match uuid", "en_US": "The argument :\u0027resourceType\u0027 doesn\u0027t match uuid", - "zh_CN": "参数: 资源类型(resourceType)与UUID不匹配", + "zh_CN": "参数: 资源类型(resourceType)与uuid不匹配", "arguments": [], - "line": 100, + "line": 128, "fileName": "src/main/java/org/zstack/tag/TagApiInterceptor.java" }, { @@ -20968,7 +33510,7 @@ "resourceType", "resourceUuid" ], - "line": 207, + "line": 239, "fileName": "src/main/java/org/zstack/tag/TagManagerImpl.java" }, { @@ -20979,7 +33521,18 @@ "tag", "resourceType" ], - "line": 645, + "line": 755, + "fileName": "src/main/java/org/zstack/tag/TagManagerImpl.java" + }, + { + "raw": "validate system tag [%s] for resourceType[%s] failed", + "en_US": "validate system tag [{0}] for resourceType[{1}] failed", + "zh_CN": "验证ResourceType[{1}]的系统标记[{0}]失败", + "arguments": [ + "tag", + "resourceType" + ], + "line": 761, "fileName": "src/main/java/org/zstack/tag/TagManagerImpl.java" }, { @@ -20989,23 +33542,34 @@ "arguments": [ "tag" ], - "line": 818, + "line": 944, "fileName": "src/main/java/org/zstack/tag/TagManagerImpl.java" }, { "raw": "tag[%s] is only for admin", "en_US": "tag[{0}] is only for admin", - "zh_CN": "", + "zh_CN": "标记[{0}]仅适用于管理员", "arguments": [ "tag" ], - "line": 847, + "line": 979, "fileName": "src/main/java/org/zstack/tag/TagManagerImpl.java" }, + { + "raw": "resource[uuids:%s] is not owned by account[uuid:%s]", + "en_US": "resource[uuids:{0}] is not owned by account[uuid:{1}]", + "zh_CN": "资源[uuid:{0}]不归帐户[uuid:{1}]所有", + "arguments": [ + "invalidUuids", + "expectAccountUuid" + ], + "line": 162, + "fileName": "src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java" + }, { "raw": "cannot update simple tag pattern format", "en_US": "cannot update simple tag pattern format", - "zh_CN": "", + "zh_CN": "无法更新简单标记模式格式", "arguments": [], "line": 85, "fileName": "src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java" @@ -21013,7 +33577,7 @@ { "raw": "you can only update token name", "en_US": "you can only update token name", - "zh_CN": "", + "zh_CN": "您只能更新令牌名称", "arguments": [], "line": 83, "fileName": "src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java" @@ -21021,7 +33585,7 @@ { "raw": "simple tag pattern has no tokens", "en_US": "simple tag pattern has no tokens", - "zh_CN": "", + "zh_CN": "简单标记模式没有标记", "arguments": [], "line": 95, "fileName": "src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java" @@ -21029,7 +33593,7 @@ { "raw": "illegal tag uuids %s, tag type must be simple,", "en_US": "illegal tag uuids {0}, tag type must be simple,", - "zh_CN": "", + "zh_CN": "标记uuid{0}非法,标记类型必须简单。", "arguments": [ "sub" ], @@ -21039,7 +33603,7 @@ { "raw": "Invalid color specification[%s], must like #FF00FF", "en_US": "Invalid color specification[{0}], must like #FF00FF", - "zh_CN": "", + "zh_CN": "颜色规范[{0}]无效,必须类似于#FF00FF", "arguments": [ "color" ], @@ -21049,7 +33613,7 @@ { "raw": "Get format[%s], format must like that name::{tokenName1}::{tokenName2} ... ::{tokenNameN} or {tokenName1}::{tokenName2} ... ::{tokenNameN} Name cannot contain \u0027{}:\u0027", "en_US": "Get format[{0}], format must like that name::{tokenName1}::{tokenName2} ... ::{tokenNameN} or {tokenName1}::{tokenName2} ... ::{tokenNameN} Name cannot contain \u0027{}:\u0027", - "zh_CN": "", + "zh_CN": "获取格式[{0}],格式必须类似于名称:{TokenName1}:{TokenName2}.:{TOKENNAMEn}或{TOKENNAME1}:?TokenNAME2}.:?TokENNAMEn}名称不能包含“{}:”", "arguments": [ "format" ], @@ -21059,47 +33623,85 @@ { "raw": "all tokens %s must be specify", "en_US": "all tokens {0} must be specify", - "zh_CN": "", + "zh_CN": "必须指定所有令牌{0}", "arguments": [ "formatTokens" ], "line": 151, "fileName": "src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java" }, - { - "raw": "resource[uuids:%s] is not owned by account[uuid:%s]", - "en_US": "resource[uuids:{0}] is not owned by account[uuid:{1}]", - "zh_CN": "", - "arguments": [ - "invalidUuids", - "expectAccountUuid" - ], - "line": 162, - "fileName": "src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java" - }, { "raw": "resource[uuid:%s] has been attached %d tags, cannot attach any more", "en_US": "resource[uuid:{0}] has been attached {1} tags, cannot attach any more", - "zh_CN": "", + "zh_CN": "资源[uuid:{0}]已附加{1}个标记,无法再附加", "arguments": [ "resourceUuid", "attachedCount" ], - "line": 184, + "line": 185, "fileName": "src/main/java/org/zstack/tag2/TagPatternBase.java" }, + { + "raw": "unable to find any TemplateConfigs: [templateUuid: %s]", + "en_US": "unable to find any TemplateConfigs: [templateUuid: {0}]", + "zh_CN": "找不到任何TemplateConfigs:[templateUuid:{0}]", + "arguments": [ + "msg.getTemplateUuid()" + ], + "line": 79, + "fileName": "src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java" + }, + { + "raw": "Unable to find any TemplateConfigs: [templateUuid: %s]", + "en_US": "Unable to find any TemplateConfigs: [templateUuid: {0}]", + "zh_CN": "找不到任何TemplateConfigs:[templateUuid:{0}]", + "arguments": [ + "msg.getTemplateUuid()" + ], + "line": 151, + "fileName": "src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java" + }, { "raw": "Unable to find TemplateConfig[category: %s, name: %s, templateUuid: %s]", "en_US": "Unable to find TemplateConfig[category: {0}, name: {1}, templateUuid: {2}]", - "zh_CN": "", + "zh_CN": "找不到TemplateConfig[类别:{0},名称:{1},Templateuuid:{2}]", "arguments": [ "msg.getCategory()", "msg.getName()", "msg.getTemplateUuid()" ], - "line": 88, + "line": 128, "fileName": "src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java" }, + { + "raw": "illegal argument %s", + "en_US": "illegal argument {0}", + "zh_CN": "非法参数{0}", + "arguments": [ + "algType" + ], + "line": 123, + "fileName": "src/main/java/org/zstack/testlib/premium/crypto/EncryptDriverSimulator.java" + }, + { + "raw": "failed to decrypt data", + "en_US": "failed to decrypt data", + "zh_CN": "无法解密数据", + "arguments": [], + "line": 136, + "fileName": "src/main/java/org/zstack/testlib/premium/crypto/EncryptDriverSimulator.java" + }, + { + "raw": "failed to parse MS envelope: %s, %s", + "en_US": "failed to parse MS envelope: {0}, {1}", + "zh_CN": "无法分析MS信封:{0},{1}", + "arguments": [ + "e.getMessage()", + "cipherText" + ], + "line": 399, + "fileName": "src/main/java/org/zstack/testlib/premium/crypto/SecurityMachineSimulator.java" + }, { "raw": "ticket[uuid:%s, name:%s] can only be updated after being cancelled, current status is %s", "en_US": "ticket[uuid:{0}, name:{1}] can only be updated after being cancelled, current status is {2}", @@ -21109,7 +33711,7 @@ "self.getName()", "self.getStatus()" ], - "line": 239, + "line": 235, "fileName": "src/main/java/org/zstack/ticket/TicketBase.java" }, { @@ -21119,7 +33721,7 @@ "arguments": [ "operator.operatorUuid" ], - "line": 293, + "line": 299, "fileName": "src/main/java/org/zstack/ticket/TicketBase.java" }, { @@ -21155,7 +33757,7 @@ { "raw": "not matched ticket type found", "en_US": "not matched ticket type found", - "zh_CN": "", + "zh_CN": "未找到匹配的票证类型", "arguments": [], "line": 74, "fileName": "src/main/java/org/zstack/ticket/api/TicketApiInterceptor.java" @@ -21163,7 +33765,7 @@ { "raw": "Ticket flow collection[uuid:%s] not matches ticket type[uuid:%s]", "en_US": "Ticket flow collection[uuid:{0}] not matches ticket type[uuid:{1}]", - "zh_CN": "", + "zh_CN": "票证流集合[uuid:{0}]与票证类型[uuid:{1}]不匹配", "arguments": [ "msg.getFlowCollectionUuid()", "ticketTypeUuid" @@ -21174,7 +33776,7 @@ { "raw": "no matched ticket flow collection or no default ticket flow collection found, you must specify the flowCollectionUuid or create a default ticket flow collection in system", "en_US": "no matched ticket flow collection or no default ticket flow collection found, you must specify the flowCollectionUuid or create a default ticket flow collection in system", - "zh_CN": "", + "zh_CN": "找不到匹配的票证流集合或找不到默认的票证流集合,必须指定FlowCollectionuuid或在系统中创建默认的票证流集合", "arguments": [], "line": 83, "fileName": "src/main/java/org/zstack/ticket/api/TicketApiInterceptor.java" @@ -21214,7 +33816,7 @@ { "raw": "No api class[name:%s] is found", "en_US": "No api class[name:{0}] is found", - "zh_CN": "", + "zh_CN": "找不到API类[名称:{0}]", "arguments": [ "request.apiName" ], @@ -21224,7 +33826,7 @@ { "raw": "failed to get value from event: %s", "en_US": "failed to get value from event: {0}", - "zh_CN": "", + "zh_CN": "无法从事件中获取值:{0}", "arguments": [ "exception.getMessage()" ], @@ -21288,7 +33890,7 @@ "en_US": "at least one flow is needed for create flow collection", "zh_CN": "创建流程时需要至少一个步骤", "arguments": [], - "line": 118, + "line": 117, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { @@ -21299,7 +33901,7 @@ "flow.approverTitle", "approveTitles" ], - "line": 125, + "line": 124, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { @@ -21309,7 +33911,7 @@ "arguments": [ "flow.approverUuid" ], - "line": 141, + "line": 140, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { @@ -21317,35 +33919,23 @@ "en_US": "name is needed when create a flow", "zh_CN": "创建步骤时需要填写名称", "arguments": [], - "line": 64, + "line": 62, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, - { - "raw": "primaryStorage[uuid:%s] has no enough space to rebase snapshot[uuid:%s], please free more than %s bytes storage space", - "en_US": "primaryStorage[uuid:{0}] has no enough space to rebase snapshot[uuid:{1}], please free more than {2} bytes storage space", - "zh_CN": "主存储[uuid:{0}]没有足够的空间合并快照,请释放大于{2}字节的存储空间。", - "arguments": [ - "currentRoot.getPrimaryStorageUuid()", - "currentLeaf.getUuid()", - "Math.abs(requiredSize - primaryStorageVO.getCapacity().getAvailablePhysicalCapacity())" - ], - "line": 427, - "fileName": "src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java" - }, { "raw": "one ticket type can only have one matches flow collection", "en_US": "one ticket type can only have one matches flow collection", - "zh_CN": "", + "zh_CN": "一个票证类型只能有一个匹配流集合", "arguments": [], - "line": 81, + "line": 79, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { - "raw": "admin is required as approver of the last flow", - "en_US": "admin is required as approver of the last flow", - "zh_CN": "", + "raw": "admin or iam2 operation is required as approver of the last flow", + "en_US": "admin or iam2 operation is required as approver of the last flow", + "zh_CN": "需要管理员或IAM2操作作为最后一个流的批准人", "arguments": [], - "line": 103, + "line": 102, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { @@ -21353,15 +33943,15 @@ "en_US": "name cannot be null", "zh_CN": "名称不能为空", "arguments": [], - "line": 129, + "line": 128, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { "raw": "approverUuid cannot be null", "en_US": "approverUuid cannot be null", - "zh_CN": "", + "zh_CN": "Approveruuid不能为空", "arguments": [], - "line": 133, + "line": 132, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, { @@ -21372,45 +33962,100 @@ "flow.approverUuid", "projectUuid" ], - "line": 148, + "line": 147, "fileName": "src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java" }, + { + "raw": "Unsupported AccountType:%s", + "en_US": "Unsupported AccountType:{0}", + "zh_CN": "不支持的帐户类型:{0}", + "arguments": [ + "loginType" + ], + "line": 42, + "fileName": "src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationIAM2Backend.java" + }, { "raw": "two factor authenticator is not enabled", "en_US": "two factor authenticator is not enabled", "zh_CN": "双因子认证未启用", "arguments": [], - "line": 118, + "line": 124, + "fileName": "src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java" + }, + { + "raw": "two factor authentication failed because there is no system tags in msg", + "en_US": "two factor authentication failed because there is no system tags in msg", + "zh_CN": "双因素身份验证失败,因为MSG中没有系统标记", + "arguments": [], + "line": 484, + "fileName": "src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java" + }, + { + "raw": "two factor authentication failed because there is no token in msg system tag", + "en_US": "two factor authentication failed because there is no token in msg system tag", + "zh_CN": "双因素身份验证失败,因为MSG系统标记中没有令牌", + "arguments": [], + "line": 490, + "fileName": "src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java" + }, + { + "raw": "two factor authentication failed because there is no secret for %s:%s", + "en_US": "two factor authentication failed because there is no secret for {0}:{1}", + "zh_CN": "双因素身份验证失败,因为{0}没有密码:{1}", + "arguments": [ + "loginContext.getLoginBackendType()", + "info.getUserUuid()" + ], + "line": 497, + "fileName": "src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java" + }, + { + "raw": "failed to verify two factor authentication code", + "en_US": "failed to verify two factor authentication code", + "zh_CN": "验证双因素身份验证代码失败", + "arguments": [], + "line": 507, "fileName": "src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java" }, + { + "raw": "Operation [%s] is forbidden during grayscale upgrade", + "en_US": "Operation [{0}] is forbidden during grayscale upgrade", + "zh_CN": "灰度升级期间禁止操作[{0}]", + "arguments": [ + "msg.getClass().getName()" + ], + "line": 148, + "fileName": "src/main/java/org/zstack/upgrade/UpgradeManagerImpl.java" + }, { "raw": "host[%s] has started more than 64 usb redirect port", "en_US": "host[{0}] has started more than 64 usb redirect port", - "zh_CN": "", + "zh_CN": "物理机[{0}]已启动64个以上的USB重定向端口", "arguments": [ "usbInv.getHostUuid()" ], - "line": 269, + "line": 267, "fileName": "src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java" }, { "raw": "unable to start usb server on host[%s], because host is not connected", "en_US": "unable to start usb server on host[{0}], because host is not connected", - "zh_CN": "", + "zh_CN": "无法启动物理机[{0}]上的USB服务器,因为物理机未连接", "arguments": [ "host.getUuid()" ], - "line": 274, + "line": 272, "fileName": "src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java" }, { "raw": "failed to start usbredirect server from host[uuid:%s]", "en_US": "failed to start usbredirect server from host[uuid:{0}]", - "zh_CN": "", + "zh_CN": "无法从物理机[uuid:{0}]启动USBDirect服务器", "arguments": [ "usbInv.getHostUuid()" ], - "line": 296, + "line": 294, "fileName": "src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java" }, { @@ -21421,15 +34066,55 @@ "line": 83, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceAllocatorFactory.java" }, + { + "raw": "%s can only be called by admin account", + "en_US": "{0} can only be called by admin account", + "zh_CN": "{0}只能被admin账户调用", + "arguments": [ + "msg.getClass().getSimpleName()" + ], + "line": 60, + "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" + }, + { + "raw": "You can attach at most %s USB 1.0 devices to one vm instance.", + "en_US": "You can attach at most {0} USB 1.0 devices to one vm instance.", + "zh_CN": "最多可以绑定{0}个USB 1.0设备到一个云主机上", + "arguments": [ + "UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM" + ], + "line": 98, + "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" + }, + { + "raw": "You can attach at most %s USB 2.0 devices to one vm instance.", + "en_US": "You can attach at most {0} USB 2.0 devices to one vm instance.", + "zh_CN": "最多可以绑定{0}个USB 2.0设备到一个云主机上", + "arguments": [ + "UsbDeviceConstants.MAX_USB_2_DEVICE_PER_VM" + ], + "line": 107, + "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" + }, + { + "raw": "You can attach at most %s USB 3.0 devices to one vm instance.", + "en_US": "You can attach at most {0} USB 3.0 devices to one vm instance.", + "zh_CN": "最多可以绑定{0}个USB 3.0设备到一个云主机上", + "arguments": [ + "UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM" + ], + "line": 116, + "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" + }, { "raw": "the usb device[uuid:%s] has already been attached to another vm[uuid:%s]", "en_US": "the usb device[uuid:{0}] has already been attached to another vm[uuid:{1}]", - "zh_CN": "USB设备[uuid:{0}]已经被绑定在其他的虚拟机[uuid:{1}]", + "zh_CN": "USB设备[uuid:{0}]已经被绑定在其他的云主机[uuid:{1}]", "arguments": [ "msg.getUsbDeviceUuid()", "usb.getVmInstanceUuid()" ], - "line": 59, + "line": 127, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { @@ -21440,18 +34125,18 @@ "msg.getUsbDeviceUuid()", "UsbDeviceState.Enabled" ], - "line": 66, + "line": 134, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { "raw": "the vm instance[uuid:%s] is not in attachable state of %s for usb device", "en_US": "the vm instance[uuid:{0}] is not in attachable state of {1} for usb device", - "zh_CN": "虚拟机[uuid:{0}]不能绑定{1}状态的USB设备", + "zh_CN": "云主机[uuid:{0}]不能绑定{1}状态的USB设备", "arguments": [ "msg.getVmInstanceUuid()", "allowedVmInstanceAttachableState" ], - "line": 74, + "line": 142, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { @@ -21464,155 +34149,156 @@ "HostState.Enabled", "HostStatus.Connected" ], - "line": 84, + "line": 152, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { "raw": "the usb device[uuid:%s] has different hostUuid than devices that already attached to the vm instance[uuid:%s]", "en_US": "the usb device[uuid:{0}] has different hostUuid than devices that already attached to the vm instance[uuid:{1}]", - "zh_CN": "与已经绑定虚拟机实例相比,USB设备[uuid:{0}]有不同的物理机uuid", + "zh_CN": "与已经绑定云主机实例相比,USB设备[uuid:{0}]有不同的物理机uuid", "arguments": [ "usb.getUuid()", "vm.getUuid()" ], - "line": 97, + "line": 165, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { "raw": "the usb device[uuid:%s] is not attached to any vm instance.", "en_US": "the usb device[uuid:{0}] is not attached to any vm instance.", - "zh_CN": "USB设备[uuid:{0}]不能绑定任何虚拟机实例", + "zh_CN": "USB设备[uuid:{0}]不能绑定任何云主机实例", "arguments": [ "usb.getUuid()" ], - "line": 109, + "line": 177, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { "raw": "the vm instance that the usb device[uuid:%s] is attached to is not in detachable state of %s", "en_US": "the vm instance that the usb device[uuid:{0}] is attached to is not in detachable state of {1}", - "zh_CN": "绑定了USB设备[uuid:{0}]的虚拟机实例处于一种不能解绑的状态{1}", + "zh_CN": "绑定了USB设备[uuid:{0}]的云主机实例处于一种不能解绑的状态{1}", "arguments": [ "usb.getUuid()", "allowedVmInstanceDetachableState" ], - "line": 117, + "line": 185, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { "raw": "vm instance[uuid:%s] not in attachable state of %s for usb device", "en_US": "vm instance[uuid:{0}] not in attachable state of {1} for usb device", - "zh_CN": "虚拟机实例[uuid:{0}]对于USB设备没有处于一种可绑定的状态{1}", + "zh_CN": "云主机实例[uuid:{0}]对于USB设备没有处于一种可绑定的状态{1}", "arguments": [ "vm.getUuid()", "allowedVmInstanceAttachableState" ], - "line": 127, + "line": 195, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { "raw": "cannot disable usb device[uuid:%s] when it\u0027s attached to a vm instance", "en_US": "cannot disable usb device[uuid:{0}] when it\u0027s attached to a vm instance", - "zh_CN": "当USB设备绑定到虚拟机上时不能禁用该USB设备", + "zh_CN": "当USB设备绑定到云主机上时不能禁用该USB设备", "arguments": [ "msg.getUuid()" ], - "line": 138, + "line": 206, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { - "raw": "cannot migrate vm[uuid:%s] because there are pci devices attached", - "en_US": "cannot migrate vm[uuid:{0}] because there are pci devices attached", - "zh_CN": "虚拟机[uuid:{0}]加载了pci设备无法迁移", - "arguments": [ - "msg.getVmInstanceUuid()" - ], - "line": 711, - "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" - }, - { - "raw": "You can attach at most %s USB 1.0 devices to one vm instance.", - "en_US": "You can attach at most {0} USB 1.0 devices to one vm instance.", - "zh_CN": "最多可以绑定{0}个USB 1.0设备到一个虚拟机上", + "raw": "please umount all usb devices of the vm[%s] and try again", + "en_US": "please umount all usb devices of the vm[{0}] and try again", + "zh_CN": "请卸载云主机[{0}]的所有USB设备,然后重试", "arguments": [ - "UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM" + "VmInstanceUuid" ], - "line": 202, - "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" + "line": 218, + "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java" }, { - "raw": "You can attach at most %s USB 2.0 devices to one vm instance.", - "en_US": "You can attach at most {0} USB 2.0 devices to one vm instance.", - "zh_CN": "最多可以绑定{0}个USB 2.0设备到一个虚拟机上", + "raw": "cannot migrate vm[uuid:%s] because there are pci devices attached", + "en_US": "cannot migrate vm[uuid:{0}] because there are pci devices attached", + "zh_CN": "云主机[uuid:{0}]加载了pci设备无法迁移", "arguments": [ - "UsbDeviceConstants.MAX_USB_2_DEVICE_PER_VM" + "msg.getVmInstanceUuid()" ], - "line": 217, + "line": 795, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { - "raw": "You can attach at most %s USB 3.0 devices to one vm instance.", - "en_US": "You can attach at most {0} USB 3.0 devices to one vm instance.", - "zh_CN": "最多可以绑定{0}个USB 3.0设备到一个虚拟机上", + "raw": "the usb device[uuid:%s] has already been attached to vm[uuid:%s]", + "en_US": "the usb device[uuid:{0}] has already been attached to vm[uuid:{1}]", + "zh_CN": "USB设备[uuid:{0}]已连接到云主机[uuid:{1}]", "arguments": [ - "UsbDeviceConstants.MAX_USB_3_DEVICE_PER_VM" + "msg.getUsbDeviceUuid()", + "usb.getVmInstanceUuid()" ], - "line": 232, + "line": 164, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { "raw": "PassThrough only support use on vm running host", "en_US": "PassThrough only support use on vm running host", - "zh_CN": "", + "zh_CN": "直通仅支持在运行物理机的云主机上使用", "arguments": [], - "line": 160, + "line": 181, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { - "raw": "cannot attach the usb device[uuid:%s] to vm[uuid:%s] due to host allocation", - "en_US": "cannot attach the usb device[uuid:{0}] to vm[uuid:{1}] due to host allocation", - "zh_CN": "不能绑定USB设备[uuid:{0}]到虚拟机[uuid:{1}],因为物理机的配置", + "raw": "cannot attach the usb device[uuid:%s] to vm[uuid:%s], possibly reasons include: the device is not enabled or had been attached to a vm, or the device and the vm are not on same host.", + "en_US": "cannot attach the usb device[uuid:{0}] to vm[uuid:{1}], possibly reasons include: the device is not enabled or had been attached to a vm, or the device and the vm are not on same host.", + "zh_CN": "无法将USB设备[uuid:{0}]连接到VM[uuid:{1}],原因可能包括:设备未启用或已连接到VM,或者设备和VM不在同一物理机上。", "arguments": [ "msg.getUsbDeviceUuid()", "msg.getVmInstanceUuid()" ], - "line": 177, + "line": 198, + "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" + }, + { + "raw": "usb is already bound to vm[uuid:%s] and cannot be bound to other vm", + "en_US": "usb is already bound to vm[uuid:{0}] and cannot be bound to other vm", + "zh_CN": "USB已绑定到VM[uuid:{0}],无法绑定到其他VM", + "arguments": [ + "deviceVO.getVmInstanceUuid()" + ], + "line": 558, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { "raw": "vm[%s] cannot start because usb redirect host is not connected", "en_US": "vm[{0}] cannot start because usb redirect host is not connected", - "zh_CN": "", + "zh_CN": "云主机[{0}]无法启动,因为未连接USB重定向物理机", "arguments": [ "msg.getVmInstanceUuid()" ], - "line": 647, + "line": 731, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { "raw": "cannot migrate vm[uuid:%s] because there are usb devices attached by passthrough", "en_US": "cannot migrate vm[uuid:{0}] because there are usb devices attached by passthrough", - "zh_CN": "不能迁移虚拟机[uuid:{0}],因为虚拟机通过直连的方式绑定了USB设备", + "zh_CN": "不能迁移云主机[uuid:{0}],因为云主机通过直连的方式绑定了USB设备", "arguments": [ "msg.getVmInstanceUuid()" ], - "line": 660, + "line": 744, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { "raw": "cannot migrate root volume[uuid:%s] because there are usb devices attached", "en_US": "cannot migrate root volume[uuid:{0}] because there are usb devices attached", - "zh_CN": "不能迁移根云盘[uuid:{0}],因为USB设备已经被绑定", + "zh_CN": "不能迁移云盘[uuid:{0}],因为USB设备已经被绑定", "arguments": [ "msg.getVolumeUuid()" ], - "line": 693, + "line": 777, "fileName": "src/main/java/org/zstack/usbDevice/UsbDeviceManager.java" }, { "raw": "not the time to clean", "en_US": "not the time to clean", - "zh_CN": "", + "zh_CN": "不是打扫的时候。", "arguments": [], "line": 43, "fileName": "src/main/java/org/zstack/v2v/CleanConversionVolumeCacheGC.java" @@ -21620,7 +34306,7 @@ { "raw": "conversionHost[uuid:%s, hostUuid:%s] is not Connected", "en_US": "conversionHost[uuid:{0}, hostUuid:{1}] is not Connected", - "zh_CN": "", + "zh_CN": "ConversionHost[uuid:{0},Hostuuid:{1}]未连接", "arguments": [ "conversionHost.getUuid()", "conversionHost.getHostUuid()" @@ -21628,25 +34314,36 @@ "line": 48, "fileName": "src/main/java/org/zstack/v2v/CleanConversionVolumeCacheGC.java" }, + { + "raw": "waiting host[uuid:%s] and primaryStorage[uuid:%s] Connected...", + "en_US": "waiting host[uuid:{0}] and primaryStorage[uuid:{1}] Connected...", + "zh_CN": "正在等待的物理机[uuid:{0}]和主存储[uuid:{1}]已连接..", + "arguments": [ + "hostUuid", + "psUuid" + ], + "line": 91, + "fileName": "src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java" + }, { "raw": "host[uuid:%s] is not Connected", "en_US": "host[uuid:{0}] is not Connected", - "zh_CN": "", + "zh_CN": "物理机[uuid:{0}]未连接", "arguments": [ "hostUuid" ], - "line": 126, - "fileName": "src/main/java/org/zstack/v2v/ResumeConvertVmJobGC.java" + "line": 149, + "fileName": "src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java" }, { "raw": "primaryStorage[uuid%s] is not Connected", "en_US": "primaryStorage[uuid{0}] is not Connected", - "zh_CN": "", + "zh_CN": "主存储[uuid{0}]未连接", "arguments": [ "primaryStorageUuid" ], - "line": 130, - "fileName": "src/main/java/org/zstack/v2v/ResumeConvertVmJobGC.java" + "line": 153, + "fileName": "src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java" }, { "raw": "Not allowed same mac [%s]", @@ -21661,13 +34358,33 @@ { "raw": "Can\u0027t add same uuid in the l3Network,uuid: %s", "en_US": "Can\u0027t add same uuid in the l3Network,uuid: {0}", - "zh_CN": "不能添加相同的uuid{0}在L3网络中", + "zh_CN": "不能添加相同的uuid{0}在三层网络中", "arguments": [ "duplicateElements.get(0)" ], "line": 205, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, + { + "raw": "l3Network[uuid:%s] is Disabled, can not create vm on it", + "en_US": "l3Network[uuid:{0}] is Disabled, can not create vm on it", + "zh_CN": "三层网络[uuid:{0}]没有被启用,不能从这个三层网络创建云主机", + "arguments": [ + "l3Uuid" + ], + "line": 217, + "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" + }, + { + "raw": "l3Network[uuid:%s] is system network, can not create user vm on it", + "en_US": "l3Network[uuid:{0}] is system network, can not create user vm on it", + "zh_CN": "三层网络[uuid:{0}]是系统网络,不能在这上面创建云主机", + "arguments": [ + "l3Uuid" + ], + "line": 220, + "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" + }, { "raw": "zone[uuid:%s] is specified but it\u0027s Disabled, can not create vm from it", "en_US": "zone[uuid:{0}] is specified but it\u0027s Disabled, can not create vm from it", @@ -21712,7 +34429,7 @@ { "raw": "defaultL3NetworkUuid[uuid:%s] is not in l3NetworkUuids%s", "en_US": "defaultL3NetworkUuid[uuid:{0}] is not in l3NetworkUuids{1}", - "zh_CN": "默认L3网络的uuid是[uuid:{0}],不在L3网络uuid们中{1}", + "zh_CN": "默认三层网络的uuid是[uuid:{0}],不在三层网络uuid们中{1}", "arguments": [ "msg.getDefaultL3NetworkUuid()", "msg.getL3NetworkUuids()" @@ -21721,59 +34438,57 @@ "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, { - "raw": "host[uuid:%s] must be Enabled and Connected to be a conversion host", - "en_US": "host[uuid:{0}] must be Enabled and Connected to be a conversion host", - "zh_CN": "", + "raw": "there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null", + "en_US": "there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null", + "zh_CN": "在三层网络uuid们中有很多三层网络被指定了,但是默认三层网络的uuid是空的", + "arguments": [], + "line": 230, + "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" + }, + { + "raw": "the status of host[uuid:%s] must be Connected", + "en_US": "the status of host[uuid:{0}] must be Connected", + "zh_CN": "物理机[uuid:{0}]的状态必须为已连接", "arguments": [ "msg.getHostUuid()" ], - "line": 76, + "line": 84, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, { "raw": "v2v conversion host storage path must be absolute path", "en_US": "v2v conversion host storage path must be absolute path", - "zh_CN": "", + "zh_CN": "V2V转换物理机存储路径必须为绝对路径", "arguments": [], - "line": 89, + "line": 97, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, { "raw": "invalid v2v url: %s", "en_US": "invalid v2v url: {0}", - "zh_CN": "", + "zh_CN": "无效的V2V URL:{0}", "arguments": [ "msg.getUrl()" ], - "line": 112, + "line": 120, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, { "raw": "vm instance[uuid:%s] does not exist or is not a vmware vm", "en_US": "vm instance[uuid:{0}] does not exist or is not a vmware vm", - "zh_CN": "", + "zh_CN": "云主机实例[uuid:{0}]不存在或不是VMware云主机", "arguments": [ "srcVmUuid" ], - "line": 123, + "line": 131, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, { "raw": "conversionHostUuid should not be null", "en_US": "conversionHostUuid should not be null", - "zh_CN": "", + "zh_CN": "ConversionHostuuid不应为空", "arguments": [], - "line": 130, - "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" - }, - { - "raw": "conversion host[uuid:%s] should be Enabled", - "en_US": "conversion host[uuid:{0}] should be Enabled", - "zh_CN": "", - "arguments": [ - "msg.getConversionHostUuid()" - ], - "line": 136, + "line": 138, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, { @@ -21789,7 +34504,7 @@ { "raw": "conversion host[uuid:%s] cannot connect to primary storage[uuid:%s]", "en_US": "conversion host[uuid:{0}] cannot connect to primary storage[uuid:{1}]", - "zh_CN": "", + "zh_CN": "转换物理机[uuid:{0}]无法连接到主存储[uuid:{1}]", "arguments": [ "msg.getConversionHostUuid()", "msg.getPrimaryStorageUuid()" @@ -21800,7 +34515,7 @@ { "raw": "Duplicate mac address %s", "en_US": "Duplicate mac address {0}", - "zh_CN": "", + "zh_CN": "重复的MAC地址{0}", "arguments": [ "duplicateMacs" ], @@ -21810,7 +34525,7 @@ { "raw": "primary storage[uuid:%s] is not supported for v2v", "en_US": "primary storage[uuid:{0}] is not supported for v2v", - "zh_CN": "", + "zh_CN": "V2V不支持主存储[uuid:{0}]", "arguments": [ "msg.getPrimaryStorageUuid()" ], @@ -21820,21 +34535,54 @@ { "raw": "primary storage[uuid:%s] is neither Enabled nor Connected", "en_US": "primary storage[uuid:{0}] is neither Enabled nor Connected", - "zh_CN": "", + "zh_CN": "主存储[uuid:{0}]既未启用也未连接", "arguments": [ "msg.getPrimaryStorageUuid()" ], "line": 292, "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" }, + { + "raw": "there are some v2v jobs in progress. can not attach volume[%s] to host[%s]", + "en_US": "there are some v2v jobs in progress. can not attach volume[{0}] to host[{1}]", + "zh_CN": "有一些V2V作业正在进行中。无法将卷[{0}]附加到物理机[{1}]", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getHostUuid()" + ], + "line": 302, + "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" + }, + { + "raw": "there are some v2v jobs in progress. can not detach volume[%s] from host[%s]", + "en_US": "there are some v2v jobs in progress. can not detach volume[{0}] from host[{1}]", + "zh_CN": "有一些V2V作业正在进行中。无法从物理机[{1}]分离卷[{0}]", + "arguments": [ + "msg.getVolumeUuid()", + "msg.getHostUuid()" + ], + "line": 313, + "fileName": "src/main/java/org/zstack/v2v/V2VApiInterceptor.java" + }, + { + "raw": "cannot reserve %s bytes on the conversion host[uuid:%s], it\u0027s short of available capacity", + "en_US": "cannot reserve {0} bytes on the conversion host[uuid:{1}], it\u0027s short of available capacity", + "zh_CN": "无法在转换物理机[uuid:{1}]上保留{0}字节,可用容量不足", + "arguments": [ + "reserveSize", + "conversionHostVO.getUuid()" + ], + "line": 98, + "fileName": "src/main/java/org/zstack/v2v/V2VConversionHostCapacityUpdater.java" + }, { "raw": "Unable to find L3Network[uuid:%s] to start the current vm, it may have been deleted, Operation suggestion: delete this vm, recreate a new vm", "en_US": "Unable to find L3Network[uuid:{0}] to start the current vm, it may have been deleted, Operation suggestion: delete this vm, recreate a new vm", - "zh_CN": "", + "zh_CN": "找不到启动当前云主机的L3Network[uuid:{0}],该云主机可能已被删除,操作建议:删除该云主机,重新创建新的云主机", "arguments": [ "l3Uuid" ], - "line": 577, + "line": 597, "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" }, { @@ -21844,17 +34592,7 @@ "arguments": [ "bandwidth" ], - "line": 1150, - "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" - }, - { - "raw": "invalid network bandwidth[%s], it must be greater than or equal to 8192", - "en_US": "invalid network bandwidth[{0}], it must be greater than or equal to 8192", - "zh_CN": "错误的网络带宽[{0}],这个数字必须大于等于8K", - "arguments": [ - "bandwidth" - ], - "line": 1145, + "line": 1207, "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" }, { @@ -21862,58 +34600,87 @@ "en_US": "networkInboundBandwidth execeds the max value 32G bps", "zh_CN": "超过下行网络带宽超过最大值32G bps", "arguments": [], - "line": 1147, - "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" - }, - { - "raw": "can not find type for src vm[url:%s]", - "en_US": "can not find type for src vm[url:{0}]", - "zh_CN": "", - "arguments": [ - "msg.getUrl()" - ], - "line": 624, + "line": 1204, "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" }, { "raw": "can not find factory for src vm[url:%s, v2vType:%s]", "en_US": "can not find factory for src vm[url:{0}, v2vType:{1}]", - "zh_CN": "", + "zh_CN": "找不到SRC VM[URL:{0},v2vType:{1}]的工厂", "arguments": [ "msg.getUrl()", "msg.getType()" ], - "line": 638, + "line": 661, "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" }, { "raw": "there has been a v2v conversion host with hostUuid %s", "en_US": "there has been a v2v conversion host with hostUuid {0}", - "zh_CN": "", + "zh_CN": "已存在Hostuuid为{0}的V2V转换物理机", "arguments": [ "msg.getHostUuid()" ], - "line": 898, + "line": 921, "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" }, { "raw": "invalid v2v qos systemtag", "en_US": "invalid v2v qos systemtag", - "zh_CN": "", + "zh_CN": "V2V QoS系统标记无效", "arguments": [], - "line": 1139, + "line": 1196, + "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" + }, + { + "raw": "invalid network bandwidth[%s], it must be greater than or equal to 1048576", + "en_US": "invalid network bandwidth[{0}], it must be greater than or equal to 1048576", + "zh_CN": "网络带宽[{0}]无效,它必须大于或等于1048576", + "arguments": [ + "bandwidth" + ], + "line": 1202, "fileName": "src/main/java/org/zstack/v2v/V2VManagerImpl.java" }, + { + "raw": "can not find type for src vm[url:%s]", + "en_US": "can not find type for src vm[url:{0}]", + "zh_CN": "找不到SRC VM[URL:{0}]的类型", + "arguments": [ + "srcVmUrl" + ], + "line": 118, + "fileName": "src/main/java/org/zstack/v2v/V2VMsgTranslator.java" + }, + { + "raw": "missing VM uuid in \u0027srcVmUrl\u0027", + "en_US": "missing VM uuid in \u0027srcVmUrl\u0027", + "zh_CN": "“ srcvmurl ”中缺少VM uuid", + "arguments": [], + "line": 890, + "fileName": "src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java" + }, { "raw": "No root volume found for VM: %s", "en_US": "No root volume found for VM: {0}", - "zh_CN": "", + "zh_CN": "找不到VM的根卷:{0}", "arguments": [ "srcVmUuid" ], - "line": 863, + "line": 956, "fileName": "src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java" }, + { + "raw": "there is no available ip found in cidr %s on host %s, try reconnect host to refresh ips", + "en_US": "there is no available ip found in cidr {0} on host {1}, try reconnect host to refresh ips", + "zh_CN": "在物理机{1}上的CIDR{0}中找不到可用的IP,请尝试重新连接物理机以刷新IP", + "arguments": [ + "cidr", + "hostUuid" + ], + "line": 1575, + "fileName": "src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java" + }, { "raw": "v2v job[uuid:%s] is running", "en_US": "v2v job[uuid:{0}] is running", @@ -21921,43 +34688,43 @@ "arguments": [ "job.getUuid()" ], - "line": 189, + "line": 190, "fileName": "src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java" }, { "raw": "failed to get virt-v2v uri for %s", "en_US": "failed to get virt-v2v uri for {0}", - "zh_CN": "", + "zh_CN": "无法获取{0}的virt-v2v URI", "arguments": [ "srcVmUrl" ], - "line": 788, + "line": 808, "fileName": "src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java" }, { "raw": "Failed to parse url %s", "en_US": "Failed to parse url {0}", - "zh_CN": "", + "zh_CN": "无法分析URL{0}", "arguments": [ "urlBuilder.toString()" ], - "line": 953, + "line": 1007, "fileName": "src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java" }, { "raw": "Target vm name can not contain those characters %s", "en_US": "Target vm name can not contain those characters {0}", - "zh_CN": "", + "zh_CN": "目标VM名称不能包含这些字符{0}", "arguments": [ "NOT_SUPPORTED_SPECIAL_CHARACTER" ], - "line": 1231, + "line": 1288, "fileName": "src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java" }, { "raw": "There is already a long job[uuid:%s] convert vm from %s", "en_US": "There is already a long job[uuid:{0}] convert vm from {1}", - "zh_CN": "", + "zh_CN": "已有长作业[uuid:{0}]从{1}转换VM", "arguments": [ "jobUuid", "msg.getUrl()" @@ -21968,7 +34735,7 @@ { "raw": "Failed to update conversion host dependency", "en_US": "Failed to update conversion host dependency", - "zh_CN": "", + "zh_CN": "无法更新转换物理机依赖关系", "arguments": [], "line": 145, "fileName": "src/main/java/org/zstack/v2v/vmware/VMwareV2VFactory.java" @@ -21976,141 +34743,172 @@ { "raw": "host is not connected", "en_US": "host is not connected", - "zh_CN": "", + "zh_CN": "物理机未连接", "arguments": [], - "line": 151, + "line": 155, + "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" + }, + { + "raw": "Syncing with VCenter[uuid:%s], please try again later.", + "en_US": "Syncing with VCenter[uuid:{0}], please try again later.", + "zh_CN": "正在与vCenter[uuid:{0}]同步,请稍后重试。", + "arguments": [ + "self.getvCenterUuid()" + ], + "line": 244, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "vmUuid [%s] not found in ESX host [%s]", "en_US": "vmUuid [{0}] not found in ESX host [{1}]", - "zh_CN": "", + "zh_CN": "在ESX物理机[{1}]中找不到VMuuid[{0}]", "arguments": [ "vmUuid", "self.getUuid()" ], - "line": 329, + "line": 359, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "VM not found: %s", "en_US": "VM not found: {0}", - "zh_CN": "", + "zh_CN": "找不到VM:{0}", "arguments": [ "vmUuid" ], - "line": 673, + "line": 709, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "failed to suspend VM [%s]: %s", "en_US": "failed to suspend VM [{0}]: {1}", - "zh_CN": "", + "zh_CN": "无法挂起云主机[{0}]:{1}", "arguments": [ "vmUuid", "VMwareHelper.exStr(ex)" ], - "line": 602, + "line": 635, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "failed to suspend VM, task status: %s", "en_US": "failed to suspend VM, task status: {0}", - "zh_CN": "", + "zh_CN": "无法挂起云主机,任务状态:{0}", "arguments": [ "t.getTaskInfo().getError().getLocalizedMessage()" ], - "line": 598, + "line": 631, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "failed to resume VM [%s]: %s", "en_US": "failed to resume VM [{0}]: {1}", - "zh_CN": "", + "zh_CN": "无法恢复VM[{0}]:{1}", "arguments": [ "vmUuid", "VMwareHelper.exStr(ex)" ], - "line": 636, + "line": 670, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "failed to resume VM, task status: %s", "en_US": "failed to resume VM, task status: {0}", - "zh_CN": "", + "zh_CN": "无法恢复VM,任务状态:{0}", "arguments": [ "t.getTaskInfo().getError().getLocalizedMessage()" ], - "line": 632, + "line": 666, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "failed to shutdown guest: %s, %s", "en_US": "failed to shutdown guest: {0}, {1}", - "zh_CN": "", + "zh_CN": "无法关闭来宾:{0},{1}", "arguments": [ "vmUuid", "VMwareHelper.exStr(ex)" ], - "line": 704, + "line": 740, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "instance uuid [%s] not found", "en_US": "instance uuid [{0}] not found", - "zh_CN": "", + "zh_CN": "未找到实例uuid[{0}]", "arguments": [ "vmInv.getInstanceOfferingUuid()" ], - "line": 1314, + "line": 1370, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "Image [%s] not found", "en_US": "Image [{0}] not found", - "zh_CN": "", + "zh_CN": "未找到镜像[{0}]", "arguments": [ "vmInv.getImageUuid()" ], - "line": 1324, + "line": 1380, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "VM [%s] not found in vCenter", "en_US": "VM [{0}] not found in vCenter", - "zh_CN": "", + "zh_CN": "在vCenter中找不到云主机[{0}]", "arguments": [ "vmUuid" ], - "line": 1423, + "line": 1479, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, { "raw": "failed to power on VM, task status: %s", "en_US": "failed to power on VM, task status: {0}", - "zh_CN": "", + "zh_CN": "无法启动云主机,任务状态:{0}", "arguments": [ "t.getTaskInfo().getError().getLocalizedMessage()" ], - "line": 1592, + "line": 1654, "fileName": "src/main/java/org/zstack/vmware/ESXHost.java" }, + { + "raw": "Nic driver %s not support yet", + "en_US": "Nic driver {0} not support yet", + "zh_CN": "NIC驱动程序{0}尚不支持", + "arguments": [ + "msg.getDriverType()" + ], + "line": 122, + "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" + }, + { + "raw": "console password is not supported by vm[uuid:%s] on vCenter[version:%s]", + "en_US": "console password is not supported by vm[uuid:{0}] on vCenter[version:{1}]", + "zh_CN": "vCenter[版本:{1}]上的VM[uuid:{0}]不支持控制台密码", + "arguments": [ + "msg.getUuid()", + "vCenterVersion" + ], + "line": 67, + "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" + }, { "raw": "vCenter login name expected.", "en_US": "vCenter login name expected.", "zh_CN": "vCenter登录名称为空", "arguments": [], - "line": 47, + "line": 73, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { "raw": "domainName[%s] is neither an IPv4 address nor a valid hostname", "en_US": "domainName[{0}] is neither an IPv4 address nor a valid hostname", - "zh_CN": "域名[{0}]不是一个IPv4地址或有效的主机名", + "zh_CN": "域名[{0}]不是一个IPv4地址或有效的物理机名", "arguments": [ "msg.getDomainName()" ], - "line": 51, + "line": 77, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { @@ -22120,7 +34918,7 @@ "arguments": [ "msg.getDomainName()" ], - "line": 57, + "line": 83, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { @@ -22131,7 +34929,7 @@ "clusterUuid", "l2uuid" ], - "line": 94, + "line": 139, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { @@ -22141,7 +34939,7 @@ "arguments": [ "clusterUuid" ], - "line": 106, + "line": 151, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { @@ -22152,7 +34950,7 @@ "phyinf", "phyinf" ], - "line": 139, + "line": 184, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { @@ -22164,27 +34962,27 @@ "vcvo.getUuid()", "clusterUuid" ], - "line": 153, + "line": 198, "fileName": "src/main/java/org/zstack/vmware/VCenterApiInterceptor.java" }, { "raw": "No data-store attached to %s", "en_US": "No data-store attached to {0}", - "zh_CN": "", + "zh_CN": "没有附加到{0}的主存储", "arguments": [ "bsUuid" ], - "line": 60, + "line": 68, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { "raw": "Data-store not found for %s", "en_US": "Data-store not found for {0}", - "zh_CN": "", + "zh_CN": "找不到{0}的主存储", "arguments": [ "bsUuid" ], - "line": 65, + "line": 73, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { @@ -22194,25 +34992,25 @@ "arguments": [ "url.getProtocol()" ], - "line": 93, + "line": 103, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { "raw": "%s already exists", "en_US": "{0} already exists", - "zh_CN": "", + "zh_CN": "{0}已存在", "arguments": [ "iinv.getName()" ], - "line": 99, + "line": 109, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { "raw": "vcenter backup storage do not support to cancel download image", "en_US": "vcenter backup storage do not support to cancel download image", - "zh_CN": "", + "zh_CN": "vCenter备份存储不支持取消下载镜像", "arguments": [], - "line": 138, + "line": 153, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { @@ -22220,15 +35018,15 @@ "en_US": "image not found in BS", "zh_CN": "在镜像服务器上未找到目标镜像", "arguments": [], - "line": 188, + "line": 203, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { "raw": "not supported yet", "en_US": "not supported yet", - "zh_CN": "", + "zh_CN": "尚不支持", "arguments": [], - "line": 200, + "line": 215, "fileName": "src/main/java/org/zstack/vmware/VCenterBackupStorage.java" }, { @@ -22236,30 +35034,25 @@ "en_US": "no candidate host for vcenter vm", "zh_CN": "找不到VCenter的物理机去启动vm", "arguments": [], - "line": 357, + "line": 368, "fileName": "src/main/java/org/zstack/vmware/VCenterHostAllocatorFilterExtensionPoint.java" }, - { - "raw": "Duplicated mac address[%s] on VM[uuid: %s, name: %s] and VM[uuid: %s, name: %s], and current mac address conflicting strategy is: %s.", - "en_US": "Duplicated mac address[{0}] on VM[uuid: {1}, name: {2}] and VM[uuid: {3}, name: {4}], and current mac address conflicting strategy is: {5}.", - "zh_CN": "云主机[uuid:{1},名称:{2}]和云主机 [uuid:{3},名称:{4}]中存在重复的mac地址[{0}],当前的 MAC 地址冲突策略是:{5}。", - "arguments": [ - "nNic.getMac()", - "nVm.getUuid()", - "nVm.getName()", - "eVM.getUuid()", - "eVM.getName()", - "VCENTER_MAC_CONFLICT_STRATEGY_STRICT" - ], - "line": 1031, - "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" - }, { "raw": "can\u0027t sync before datastores are separated", "en_US": "can\u0027t sync before datastores are separated", - "zh_CN": "", + "zh_CN": "在分离主存储之前无法同步", "arguments": [], - "line": 1804, + "line": 2040, + "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" + }, + { + "raw": "There are tasks running on the VCenter[uuid:%s], please try again later.", + "en_US": "There are tasks running on the VCenter[uuid:{0}], please try again later.", + "zh_CN": "vCenter[uuid:{0}]上正在运行任务,请稍后重试。", + "arguments": [ + "vcvo.getUuid()" + ], + "line": 3044, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22269,7 +35062,7 @@ "arguments": [ "msg.getVCenterUuid()" ], - "line": 2858, + "line": 3134, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22277,7 +35070,7 @@ "en_US": "Login failed, please check your login parameters.", "zh_CN": "登录失败,请检查用户名密码是否正确", "arguments": [], - "line": 2974, + "line": 3252, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22288,7 +35081,7 @@ "msg.getDomainName()", "ex.getMessage()" ], - "line": 2978, + "line": 3256, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22299,7 +35092,7 @@ "msg.getDomainName()", "msg.getUsername()" ], - "line": 2984, + "line": 3262, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22310,7 +35103,28 @@ "msg.getDomainName()", "msg.getPort() \u003d\u003d null ? 443 : msg.getPort()" ], - "line": 2991, + "line": 3269, + "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" + }, + { + "raw": "SSL handshake failed with vCenter [%s],because insecure TLS 1.0 is used. Manually enabled TLS 1.0 in jdk configuration if needed.", + "en_US": "SSL handshake failed with vCenter [{0}],because insecure TLS 1.0 is used. Manually enabled TLS 1.0 in jdk configuration if needed.", + "zh_CN": "与vCenter[{0}]的SSL握手失败,因为使用了不安全的TLS 1.0。如果需要,在JDK配置中手动启用TLS 1.0。", + "arguments": [ + "msg.getDomainName()" + ], + "line": 3277, + "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" + }, + { + "raw": "SSL handshake failed with vCenter [%s],please check the port number[%d].", + "en_US": "SSL handshake failed with vCenter [{0}],please check the port number[{1}].", + "zh_CN": "与vCenter[{0}]的SSL握手失败,请检查端口号[{1}]。", + "arguments": [ + "msg.getDomainName()", + "msg.getPort() \u003d\u003d null ? 443 : msg.getPort()" + ], + "line": 3283, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22318,7 +35132,7 @@ "en_US": "No clustered compute resource found", "zh_CN": "未找到集群资源", "arguments": [], - "line": 3070, + "line": 3359, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22326,7 +35140,7 @@ "en_US": "No dvSwitch or qualified vSwitch found", "zh_CN": "未找到可使用的dvSwitch/vSwitch", "arguments": [], - "line": 3074, + "line": 3363, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22337,23 +35151,23 @@ "dsMorVal", "vcUuid" ], - "line": 3255, + "line": 3546, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { - "raw": "Missing host UUID in message", - "en_US": "Missing host UUID in message", - "zh_CN": "消息中缺失物理机UUID", + "raw": "Missing host uuid in message", + "en_US": "Missing host uuid in message", + "zh_CN": "消息中缺失物理机uuid", "arguments": [], - "line": 3627, + "line": 3936, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { "raw": "Missing destination host uuid.", "en_US": "Missing destination host uuid.", - "zh_CN": "缺少目标物理机的Uuid", + "zh_CN": "缺少目标物理机的uuid", "arguments": [], - "line": 3725, + "line": 4035, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22361,18 +35175,18 @@ "en_US": "Destination host is not ESX host.", "zh_CN": "目标物理机不是Esx类型物理机", "arguments": [], - "line": 3730, + "line": 4040, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { "raw": "Checking compatibility with vm %s failed on host %s", "en_US": "Checking compatibility with vm {0} failed on host {1}", - "zh_CN": "检查主机{1}与虚拟机{0}的兼容性失败", + "zh_CN": "检查物理机{1}与云主机{0}的兼容性失败", "arguments": [ "vm.getConfig().getName()", "hvo.getManagementIp()" ], - "line": 3768, + "line": 4079, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22380,7 +35194,7 @@ "en_US": "HOST CPU/software NOT compatible", "zh_CN": "物理机的CPU/software不兼容", "arguments": [], - "line": 3765, + "line": 4075, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { @@ -22388,31 +35202,31 @@ "en_US": "Can\u0027t detach nic because the nic not supported to hot plugin in vcenter", "zh_CN": "无法卸载网络,因为该网卡不支持热拔插", "arguments": [], - "line": 3993, + "line": 4137, "fileName": "src/main/java/org/zstack/vmware/VCenterManagerImpl.java" }, { "raw": "No virtual disk manager", "en_US": "No virtual disk manager", - "zh_CN": "", + "zh_CN": "无虚拟磁盘管理器", "arguments": [], - "line": 204, + "line": 228, "fileName": "src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java" }, { "raw": "No file manager", "en_US": "No file manager", - "zh_CN": "", + "zh_CN": "没有文件管理器", "arguments": [], - "line": 211, + "line": 235, "fileName": "src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java" }, { "raw": "No file Datacenter", "en_US": "No file Datacenter", - "zh_CN": "", + "zh_CN": "无文件数据中心", "arguments": [], - "line": 220, + "line": 244, "fileName": "src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java" }, { @@ -22422,7 +35236,7 @@ "arguments": [ "vm.getName()" ], - "line": 324, + "line": 350, "fileName": "src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java" }, { @@ -22430,11 +35244,30 @@ "en_US": "failed to get VM from installPath: {0}", "zh_CN": "在路径{0}下未找到云主机", "arguments": [ - "msg.getInstallPath()" + "installPath" ], - "line": 320, + "line": 346, "fileName": "src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java" }, + { + "raw": "VCenter not found", + "en_US": "VCenter not found", + "zh_CN": "找不到vCenter", + "arguments": [], + "line": 258, + "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" + }, + { + "raw": "VCenter[%s] is not in operation status, current status: %s", + "en_US": "VCenter[{0}] is not in operation status, current status: {1}", + "zh_CN": "vCenter[{0}]未处于操作状态,当前状态:{1}", + "arguments": [ + "vcvo.getUuid()", + "vcvo.getStatus()" + ], + "line": 262, + "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" + }, { "raw": "failed to connect to vCenter: %s: %s", "en_US": "failed to connect to vCenter: {0}: {1}", @@ -22443,58 +35276,59 @@ "vCenterUrl", "ex.getMessage()" ], - "line": 230, + "line": 328, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "vdisk not found: %s", "en_US": "vdisk not found: {0}", - "zh_CN": "", + "zh_CN": "未找到虚拟磁盘:{0}", "arguments": [ "installPath" ], - "line": 362, + "line": 460, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "list storage failed for %s", "en_US": "list storage failed for {0}", - "zh_CN": "", + "zh_CN": "{0}的列表存储失败", "arguments": [ "getVcDomainName(si)" ], - "line": 437, + "line": 536, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "No datastore found for VM: %s", "en_US": "No datastore found for VM: {0}", - "zh_CN": "", + "zh_CN": "找不到云主机{0}的主存储区", "arguments": [ "vm.getName()" ], - "line": 457, + "line": 556, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { - "raw": "failed to set ESX VM uuid [%s:%s]", - "en_US": "failed to set ESX VM uuid [{0}:{1}]", - "zh_CN": "设置ESX VM uuid [{0}:{1}]失败", + "raw": "failed to set ESX VM uuid [%s:%s], because[%s]", + "en_US": "failed to set ESX VM uuid [{0}:{1}], because[{2}]", + "zh_CN": "无法设置ESX VM uuid[{0}:{1}],因为[{2}]", "arguments": [ "info.getName()", - "info.getInstanceUuid()" + "info.getInstanceUuid()", + "ex.getMessage()" ], - "line": 511, + "line": 610, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "template [%s] not found", "en_US": "template [{0}] not found", - "zh_CN": "", + "zh_CN": "未找到模板[{0}]", "arguments": [ "zsImageUuid" ], - "line": 592, + "line": 709, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22504,7 +35338,7 @@ "arguments": [ "host.getName()" ], - "line": 669, + "line": 786, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22514,17 +35348,17 @@ "arguments": [ "host.getName()" ], - "line": 665, + "line": 782, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "No unit number available for data disk %s", "en_US": "No unit number available for data disk {0}", - "zh_CN": "", + "zh_CN": "没有可用于数据磁盘{0}的单元号", "arguments": [ "installPath" ], - "line": 2105, + "line": 2415, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22534,7 +35368,7 @@ "arguments": [ "vm.getName()" ], - "line": 1245, + "line": 1546, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22544,37 +35378,37 @@ "arguments": [ "vm.getName()" ], - "line": 1280, + "line": 1581, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "list dvSwitch failed for %s", "en_US": "list dvSwitch failed for {0}", - "zh_CN": "", + "zh_CN": "为{0}列出dvSwitch失败", "arguments": [ "vcvo.getName()" ], - "line": 1368, + "line": 1670, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "get vCenter cluster[%s] name failed", "en_US": "get vCenter cluster[{0}] name failed", - "zh_CN": "", + "zh_CN": "获取vCenter集群[{0}]名称失败", "arguments": [ "clusterUuid" ], - "line": 1630, + "line": 1936, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "dvSwitch name [%s] not unique", "en_US": "dvSwitch name [{0}] not unique", - "zh_CN": "", + "zh_CN": "dvSwitch名称[{0}]不唯一", "arguments": [ "dvSwitch" ], - "line": 1739, + "line": 2045, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22584,7 +35418,7 @@ "arguments": [ "hvo.getName()" ], - "line": 1797, + "line": 2103, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22595,7 +35429,7 @@ "hvo.getName()", "((OperationFailureException) ex).getErrorCode().getDetails()" ], - "line": 1794, + "line": 2100, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22606,90 +35440,91 @@ "hvo.getName()", "hvo.getUuid()" ], - "line": 1761, + "line": 2067, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "portgroup[%s] already exists on host[%s] but with different vlanId(%d)", "en_US": "portgroup[{0}] already exists on host[{1}] but with different vlanId({2})", - "zh_CN": "", + "zh_CN": "端口组[{0}]已存在于物理机[{1}]上,但具有不同的VlanID({2})", "arguments": [ "pgLabel", "hvo.getName()", "vlanId" ], - "line": 1773, + "line": 2079, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "portgroup[%s] already exists on host[%s],please create again with other name or delete portgroup manually and attach to cluster again", - "en_US": "portgroup[%s] already exists on host[%s],please create again with other name or delete portgroup manually and attach to cluster again", + "en_US": "portgroup[{0}] already exists on host[{1}],please create again with other name or delete portgroup manually and attach to cluster again", "zh_CN": "端口组[{0}]已经存在于物理机[{1}],请重新使用另外的名字创建或者手动删除端口组然后重新加载到集群", "arguments": [ + "pgLabel", "hvo.getName()" ], - "line": 1833, + "line": 2083, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "create dvPortGroup failed for %s", "en_US": "create dvPortGroup failed for {0}", - "zh_CN": "", + "zh_CN": "为{0}创建DVPortGroup失败", "arguments": [ "vcvo.getName()" ], - "line": 1836, + "line": 2142, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "dvSwitch [%s] not found on vCenter [%s]", "en_US": "dvSwitch [{0}] not found on vCenter [{1}]", - "zh_CN": "", + "zh_CN": "在vCenter[{1}]上找不到dvSwitch[{0}]", "arguments": [ "dvSwitchName", "vcvo.getName()" ], - "line": 1831, + "line": 2137, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "no dataCenter found for datastore", "en_US": "no dataCenter found for datastore", - "zh_CN": "", + "zh_CN": "找不到主存储的区域", "arguments": [ "ds.getName()" ], - "line": 2026, + "line": 2335, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "virtual disk manager unavailable", "en_US": "virtual disk manager unavailable", - "zh_CN": "", + "zh_CN": "虚拟磁盘管理器不可用", "arguments": [], - "line": 2031, + "line": 2340, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "delete vdisk[%s] failed: %s", "en_US": "delete vdisk[{0}] failed: {1}", - "zh_CN": "", + "zh_CN": "删除虚拟磁盘[{0}]失败:{1}", "arguments": [ "installPath", "mf.getLocalizedMessage()" ], - "line": 2042, + "line": 2351, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { "raw": "create dvPortGroup failed for dvSwitch [%s], %s", "en_US": "create dvPortGroup failed for dvSwitch [{0}], {1}", - "zh_CN": "", + "zh_CN": "为dvSwitch[{0}]创建dvPortGroup失败,{1}", "arguments": [ "dvSwitch.getName()", "task.getTaskInfo().getError().getLocalizedMessage()" ], - "line": 2171, + "line": 2481, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22701,7 +35536,7 @@ "mor.val", "ex.getMessage()" ], - "line": 2275, + "line": 2593, "fileName": "src/main/java/org/zstack/vmware/VMwareHelper.java" }, { @@ -22709,9 +35544,19 @@ "en_US": "No VNC ports available", "zh_CN": "未找到可用的VNC端口", "arguments": [], - "line": 162, + "line": 165, "fileName": "src/main/java/org/zstack/vmware/VncPortAllocatorImpl.java" }, + { + "raw": "dns[%s] is not a IP address", + "en_US": "dns[{0}] is not a IP address", + "zh_CN": "dns地址[{0}]不是有效的IP地址", + "arguments": [ + "msg.getDns()" + ], + "line": 450, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, { "raw": "no ip ranges attached with l3 network[uuid:%s]", "en_US": "no ip ranges attached with l3 network[uuid:{0}]", @@ -22719,31 +35564,75 @@ "arguments": [ "l3NetworkVO.getUuid()" ], - "line": 225, + "line": 338, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "management network can not be detached", + "en_US": "management network can not be detached", + "zh_CN": "管理网络无法分离", + "arguments": [], + "line": 178, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "default route network can not be detached", + "en_US": "default route network can not be detached", + "zh_CN": "无法分离默认路由网络", + "arguments": [], + "line": 182, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "original public network can not be detached", + "en_US": "original public network can not be detached", + "zh_CN": "原有公网不能脱离", + "arguments": [], + "line": 186, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "could not detach l3 network to vpc router[uuid:%s] because its state is not running or stopped", + "en_US": "could not detach l3 network to vpc router[uuid:{0}] because its state is not running or stopped", + "zh_CN": "无法将三层网络与VPC路由器[uuid:{0}]分离,因为其状态未运行或已停止", + "arguments": [ + "vpc.getUuid()" + ], + "line": 190, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "could not detach l3 network to vpc router[uuid:%s] becaus the states of the master and slave are inconsistent", + "en_US": "could not detach l3 network to vpc router[uuid:{0}] becaus the states of the master and slave are inconsistent", + "zh_CN": "无法将三层网络与VPC路由器[uuid:{0}]分离,因为主设备和从设备的状态不一致", + "arguments": [ + "vpc.getUuid()" + ], + "line": 198, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { "raw": "l3 network[uuid:%s] can not detach from vpc vrouter[uuid:%s] since network services attached vips[%s] still used in l3", "en_US": "l3 network[uuid:{0}] can not detach from vpc vrouter[uuid:{1}] since network services attached vips[{2}] still used in l3", - "zh_CN": "", + "zh_CN": "三层网络[uuid:{0}]无法与VPC虚拟路由器[uuid:{1}]分离,因为网络服务附加的VIP[{2}]仍在L3中使用", "arguments": [ "l3NetworkVO.getUuid()", "vmInstanceVO.getUuid()", - "vipPeerVOs.stream().map( n -\u003e n.getVipUuid()).collect(Collectors.toList())" + "vipPeerVOs.stream().map(VipPeerL3NetworkRefVO::getVipUuid).collect(Collectors.toList())" ], - "line": 167, + "line": 231, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { "raw": "vpc l3 network[uuid:%s] can not detach from vpc vrouter[uuid:%s] since vm nics[%s] still used in l3", "en_US": "vpc l3 network[uuid:{0}] can not detach from vpc vrouter[uuid:{1}] since vm nics[{2}] still used in l3", - "zh_CN": "vpc三层网络[uuid:{0}]无法从vpc路由器[uuid:{1}]卸载, l3网络还在使用以下云主机网卡[{2}]", + "zh_CN": "vpc三层网络[uuid:{0}]无法从vpc路由器[uuid:{1}]卸载, 三层网络还在使用以下云主机网卡[{2}]", "arguments": [ "l3NetworkVO.getUuid()", "vmInstanceVO.getUuid()", - "vmNicVOS.stream().map( n -\u003e n.getUuid()).collect(Collectors.toList())" + "vmNicVOS.stream().map(ResourceVO::getUuid).collect(Collectors.toList())" ], - "line": 183, + "line": 247, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { @@ -22753,7 +35642,7 @@ "arguments": [ "msg.getVirtualRouterOfferingUuid()" ], - "line": 193, + "line": 257, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { @@ -22761,7 +35650,38 @@ "en_US": "only vpc l3 network can attach to vpc vrouter", "zh_CN": "只有VPC三层网络可以绑定到VPC云路由", "arguments": [], - "line": 218, + "line": 284, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "Vpc network [uuid:%s] already attached to vpc router [uuid:%s]", + "en_US": "Vpc network [uuid:{0}] already attached to vpc router [uuid:{1}]", + "zh_CN": "VPC网络[uuid:{0}]已连接到VPC路由器[uuid:{1}]", + "arguments": [ + "msg.getL3NetworkUuid()", + "vmNics.get(0).getVmInstanceUuid()" + ], + "line": 292, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "could not attached l3 network to vpc router[uuid:%s] because both its state and it peer state is not running or stopped", + "en_US": "could not attached l3 network to vpc router[uuid:{0}] because both its state and it peer state is not running or stopped", + "zh_CN": "无法将三层网络连接到VPC路由器[uuid:{0}],因为其状态和对等状态均未运行或已停止", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 329, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "could not attached l3 network to vpc router[uuid:%s] because its state is not running or stopped", + "en_US": "could not attached l3 network to vpc router[uuid:{0}] because its state is not running or stopped", + "zh_CN": "无法将三层网络连接到VPC路由器[uuid:{0}],因为其状态未运行或已停止", + "arguments": [ + "msg.getVmInstanceUuid()" + ], + "line": 312, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { @@ -22775,7 +35695,7 @@ "msg.getL3NetworkUuid()", "vmInstanceVO.getUuid()" ], - "line": 249, + "line": 362, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { @@ -22783,42 +35703,32 @@ "en_US": "the gateway[ip:{0}] of l3[uuid:{1}] has been occupied", "zh_CN": "三层网络[uuid:{1}]的网关[uuid:{0}]已经被占用", "arguments": [ - "gateway", + "gateways", "msg.getL3NetworkUuid()" ], - "line": 261, + "line": 383, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { - "raw": "the static ip[%s] specified in message not equals to gateway ip[%s] of l3 network[uuid:%s]", - "en_US": "the static ip[{0}] specified in message not equals to gateway ip[{1}] of l3 network[uuid:{2}]", - "zh_CN": "在消息中指定的静态IP地址[{0}]和三层网络[uuid:{2}]的网关IP地址[{1}]不一样", + "raw": "the static ip[%s] specified in message not equals to gateway ips[%s] of l3 network[uuid:%s]", + "en_US": "the static ip[{0}] specified in message not equals to gateway ips[{1}] of l3 network[uuid:{2}]", + "zh_CN": "消息中指定的静态IP[{0}]不等于三层网络[uuid:{2}]的网关IP[{1}]", "arguments": [ "msg.getStaticIp()", - "gateway", + "gateways", "l3NetworkVO.getUuid()" ], - "line": 272, + "line": 428, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { "raw": "l3 network [uuid:%s] must be attached first, because there is vip on that l3 network", "en_US": "l3 network [uuid:{0}] must be attached first, because there is vip on that l3 network", - "zh_CN": "", + "zh_CN": "必须首先连接三层网络[uuid:{0}],因为该三层网络上存在VIP", "arguments": [ "vipL3Uuid" ], - "line": 284, - "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" - }, - { - "raw": "dns[%s] is not a IP address", - "en_US": "dns[{0}] is not a IP address", - "zh_CN": "dns地址[{0}]不是有效的IP地址", - "arguments": [ - "msg.getDns()" - ], - "line": 335, + "line": 440, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { @@ -22829,15 +35739,41 @@ "msg.getDns()", "msg.getUuid()" ], - "line": 296, + "line": 457, "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" }, { - "raw": "chrony server not configured!", - "en_US": "chrony server not configured!", - "zh_CN": "", - "arguments": [], - "line": 1056, + "raw": "could not add ipv6 range to l3 network[uuid:%s], because it\u0027s overlap with cidr [%s] of vRouter [uuid:%s]", + "en_US": "could not add ipv6 range to l3 network[uuid:{0}], because it\u0027s overlap with cidr [{1}] of vRouter [uuid:{2}]", + "zh_CN": "无法将IPv6范围添加到三层网络[uuid:{0}],因为它与VRouter[uuid:{2}]的CIDR[{1}]重叠", + "arguments": [ + "ipr.getL3NetworkUuid()", + "ipRangeVO.getNetworkCidr()", + "uuid" + ], + "line": 488, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "could not add ip range to l3 network[uuid:%s], because it\u0027s overlap with cidr [%s] of vRouter [uuid:%s]", + "en_US": "could not add ip range to l3 network[uuid:{0}], because it\u0027s overlap with cidr [{1}] of vRouter [uuid:{2}]", + "zh_CN": "无法将IP范围添加到三层网络[uuid:{0}],因为它与VRouter[uuid:{2}]的CIDR[{1}]重叠", + "arguments": [ + "ipr.getL3NetworkUuid()", + "ipRangeVO.getNetworkCidr()", + "uuid" + ], + "line": 483, + "fileName": "src/main/java/org/zstack/vpc/VpcApiInterceptor.java" + }, + { + "raw": "operation error, because:%s", + "en_US": "operation error, because:{0}", + "zh_CN": "操作错误,因为{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 859, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { @@ -22847,7 +35783,7 @@ "arguments": [ "msg.getUuid()" ], - "line": 314, + "line": 558, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { @@ -22857,17 +35793,7 @@ "arguments": [ "vrinv.getUuid()" ], - "line": 351, - "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" - }, - { - "raw": "can not get state of distributed routing to virtual router %s", - "en_US": "can not get state of distributed routing to virtual router {0}", - "zh_CN": "获取路由器 {0} 分布式路由的状态失败", - "arguments": [ - "vrinv.getUuid()" - ], - "line": 595, + "line": 596, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { @@ -22878,7 +35804,17 @@ "msg.getNetworkService()", "msg.getUuid()" ], - "line": 469, + "line": 720, + "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" + }, + { + "raw": "can not get state of distributed routing to virtual router %s", + "en_US": "can not get state of distributed routing to virtual router {0}", + "zh_CN": "获取路由器 {0} 分布式路由的状态失败", + "arguments": [ + "vrinv.getUuid()" + ], + "line": 855, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { @@ -22889,15 +35825,15 @@ "msg.getNetworkService()", "msg.getUuid()" ], - "line": 613, + "line": 934, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { "raw": "vpc l3 network must attach a vpc vrouter first before do anything related to vrouter(like start/stop vm, create lb, etc.)", "en_US": "vpc l3 network must attach a vpc vrouter first before do anything related to vrouter(like start/stop vm, create lb, etc.)", - "zh_CN": "在做设置云路由的任何操作(如启动/停止虚拟机、创建负载均衡等),VPC三层网络必须首先绑定三层路由", + "zh_CN": "在做设置云路由的任何操作(如启动/停止云主机、创建负载均衡等),VPC三层网络必须首先绑定三层路由", "arguments": [], - "line": 1004, + "line": 1336, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { @@ -22908,7 +35844,7 @@ "msg.getDns()", "msg.getVpcRouterUuid()" ], - "line": 1281, + "line": 1594, "fileName": "src/main/java/org/zstack/vpc/VpcManagerImpl.java" }, { @@ -22916,19 +35852,19 @@ "en_US": "can not detach nic from vpc vr[uuid:{0}]", "zh_CN": "不能从VPC云路由[uuid:{0}]解绑网卡", "arguments": [ - "vpc.getUuid()" + "vpcUuid" ], - "line": 161, + "line": 166, "fileName": "src/main/java/org/zstack/vpc/VpcVRouterFactory.java" }, { - "raw": "can not detach nic from vpc during delete ip range[uuid:%s]", - "en_US": "can not detach nic from vpc during delete ip range[uuid:{0}]", - "zh_CN": "", + "raw": "there is no ip range for l3 network[uuid:%s]", + "en_US": "there is no ip range for l3 network[uuid:{0}]", + "zh_CN": "三层网络[uuid:{0}]没有IP范围", "arguments": [ - "ipRange.getUuid()" + "l3.getUuid()" ], - "line": 289, + "line": 473, "fileName": "src/main/java/org/zstack/vpc/VpcVRouterFactory.java" }, { @@ -22936,21 +35872,21 @@ "en_US": "the gateway[ip:{0}] of l3[uuid:{1}] has been occupied on vpc vr[uuid: {2}]", "zh_CN": "在VPC的云路由[uuid: {2}]上,三层网络[uuid:{1}]的网关[uuid:{0}]已经被占用", "arguments": [ - "gateway", + "ip.getGateway()", "l3.getUuid()", "vm.getUuid()" ], - "line": 342, + "line": 501, "fileName": "src/main/java/org/zstack/vpc/VpcVRouterFactory.java" }, { - "raw": "unable to ssh in to the vyos[%s], the ssh port seems not open", - "en_US": "unable to ssh in to the vyos[{0}], the ssh port seems not open", - "zh_CN": "未能通过ssh进入vyos[{0}],ssh端口看起来没有打开", + "raw": "unable to ssh in to the vpc router[%s], the ssh port seems not open", + "en_US": "unable to ssh in to the vpc router[{0}], the ssh port seems not open", + "zh_CN": "无法通过SSH连接到VPC路由器[{0}],SSH端口似乎未打开", "arguments": [ "mgmtNicIp" ], - "line": 130, + "line": 133, "fileName": "src/main/java/org/zstack/vpc/VpcVyosDeployZsnAgentFlow.java" }, { @@ -22960,7 +35896,56 @@ "arguments": [ "msg.getVmInstanceUuid()" ], - "line": 164, + "line": 217, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" + }, + { + "raw": "Could not update this network service, due to vpc [uuid:%s] is not support update network service version", + "en_US": "Could not update this network service, due to vpc [uuid:{0}] is not support update network service version", + "zh_CN": "无法更新此网络服务,因为VPC[uuid:{0}]不支持更新网络服务版本", + "arguments": [ + "msg.getVirtualRouterUuid()" + ], + "line": 130, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" + }, + { + "raw": "Could not update this network service, due to vpc [uuid:%s] used old kernel version:[%s]", + "en_US": "Could not update this network service, due to vpc [uuid:{0}] used old kernel version:[{1}]", + "zh_CN": "无法更新此网络服务,因为VPC[uuid:{0}]使用了旧内核版本:[{1}]", + "arguments": [ + "msg.getVirtualRouterUuid()", + "vo.getKernelVersion()" + ], + "line": 137, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" + }, + { + "raw": "Could not apply snat with non-default public network, due to multi snat feature is disabled", + "en_US": "Could not apply snat with non-default public network, due to multi snat feature is disabled", + "zh_CN": "无法使用非默认公用网络应用SNAT,因为多SNAT功能已禁用", + "arguments": [], + "line": 144, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" + }, + { + "raw": "Could not apply snat with this L3Network, due to l3 network [uuid:%s] is not public network", + "en_US": "Could not apply snat with this L3Network, due to l3 network [uuid:{0}] is not public network", + "zh_CN": "无法对此三层网络应用SNAT,因为三层网络[uuid:{0}]不是公共网络", + "arguments": [ + "msg.getL3NetworkUuid()" + ], + "line": 147, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" + }, + { + "raw": "Could not apply snat with this L3Network, due to l3 network [uuid:%s] is not attached to vpc router", + "en_US": "Could not apply snat with this L3Network, due to l3 network [uuid:{0}] is not attached to vpc router", + "zh_CN": "无法对此三层网络应用SNAT,因为三层网络[uuid:{0}]未连接到VPC路由器", + "arguments": [ + "msg.getL3NetworkUuid()" + ], + "line": 150, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -22970,7 +35955,7 @@ "arguments": [ "ip" ], - "line": 115, + "line": 168, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -22978,9 +35963,9 @@ "en_US": "vpcHaRouter [uuid:{0}] is deleted", "zh_CN": "高可用组[uuid:{0}]被删除了", "arguments": [ - "vpcHaUuid" + "vpcVo.getUuid()" ], - "line": 152, + "line": 205, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -22990,7 +35975,7 @@ "arguments": [ "haUuid" ], - "line": 182, + "line": 235, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23001,7 +35986,7 @@ "l3Uuids", "offeringL3Uuids" ], - "line": 211, + "line": 266, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23012,7 +35997,7 @@ "vpcL3Uuids", "vpcHaGroupL3Uuids" ], - "line": 267, + "line": 322, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23022,7 +36007,7 @@ "arguments": [ "oldHaUuid" ], - "line": 275, + "line": 330, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23032,7 +36017,7 @@ "arguments": [ "haUuid" ], - "line": 279, + "line": 334, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23042,7 +36027,7 @@ "arguments": [ "haUuid" ], - "line": 283, + "line": 339, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23052,7 +36037,7 @@ "arguments": [ "haUuid" ], - "line": 288, + "line": 344, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java" }, { @@ -23062,9 +36047,52 @@ "arguments": [ "ha.getName()" ], - "line": 571, + "line": 611, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java" + }, + { + "raw": "virtualrouter %s [uuid: %s ] of VPC HA group %s [uuid: %s] haStatus changed from %s to %s", + "en_US": "virtualrouter {0} [uuid: {1} ] of VPC HA group {2} [uuid: {3}] haStatus changed from {4} to {5}", + "zh_CN": "VPC高可用性组{2}[uuid:{3}]的VirtualRouter{0}[uuid:{1}]的高可用性状态已从{4}更改为{5}", + "arguments": [ + "vrName", + "vrUuid", + "vpcHaGroupName", + "vpcHaGroupUuid", + "old", + "status" + ], + "line": 785, "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java" }, + { + "raw": "ha group uuid nil", + "en_US": "ha group uuid nil", + "zh_CN": "高可用性组uuid无", + "arguments": [], + "line": 694, + "fileName": "src/main/java/org/zstack/vpc/ha/VpcHaGroupVpcVrImpl.java" + }, + { + "raw": "VR[uuid: %s] not running", + "en_US": "VR[uuid: {0}] not running", + "zh_CN": "VR[uuid:{0}]未运行", + "arguments": [ + "struct.getVmInstanceUuid()" + ], + "line": 85, + "fileName": "src/main/java/org/zstack/vpc/ha/vpcHaGc/VpcHaGcManagerImpl.java" + }, + { + "raw": "VR[uuid: %s] not connected", + "en_US": "VR[uuid: {0}] not connected", + "zh_CN": "VR[uuid:{0}]未连接", + "arguments": [ + "struct.getVmInstanceUuid()" + ], + "line": 90, + "fileName": "src/main/java/org/zstack/vpc/ha/vpcHaGc/VpcHaGcManagerImpl.java" + }, { "raw": "failed to enable ha on virtual router[uuid:%s], %s", "en_US": "failed to enable ha on virtual router[uuid:{0}], {1}", @@ -23073,387 +36101,551 @@ "vrUuid", "ret.getError()" ], - "line": 137, + "line": 140, "fileName": "src/main/java/org/zstack/vpc/ha/vyos/vyosVpcHaRouterBackendManagerImpl.java" }, { - "raw": "operation failure, ip format only supports ipv4/iprange/cidr, but find %s", - "en_US": "operation failure, ip format only supports ipv4/iprange/cidr, but find {0}", - "zh_CN": "", + "raw": "only tcp or udp protocol can use port", + "en_US": "only tcp or udp protocol can use port", + "zh_CN": "只有TCP或UDP协议可以使用端口", + "arguments": [], + "line": 373, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "can not delete ruleSet[%s] because it still attached to nic", + "en_US": "can not delete ruleSet[{0}] because it still attached to nic", + "zh_CN": "无法删除规则集[{0}],因为它仍连接到NIC", "arguments": [ - "ips" + "msg.getUuid()" ], - "line": 291, + "line": 150, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "illegal protocol type %s", - "en_US": "illegal protocol type {0}", - "zh_CN": "", + "raw": "can not detach system default ruleSet", + "en_US": "can not detach system default ruleSet", + "zh_CN": "无法分离系统默认规则集", + "arguments": [], + "line": 129, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "only system ruleSet can change action type", + "en_US": "only system ruleSet can change action type", + "zh_CN": "只有系统规则集才能更改操作类型", + "arguments": [], + "line": 142, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "can not delete system default ruleSet", + "en_US": "can not delete system default ruleSet", + "zh_CN": "无法删除系统默认规则集", + "arguments": [], + "line": 154, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "can not delete system default rule", + "en_US": "can not delete system default rule", + "zh_CN": "无法删除系统默认规则", + "arguments": [], + "line": 160, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "the router [uuid:%s] does not has a master router", + "en_US": "the router [uuid:{0}] does not has a master router", + "zh_CN": "路由器[uuid:{0}]没有主路由器", "arguments": [ - "protocol" + "vRouteUuid" ], - "line": 317, + "line": 170, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "RuleSet[%s] already has a rule with rule number %s.", - "en_US": "RuleSet[{0}] already has a rule with rule number {1}.", - "zh_CN": "", + "raw": "the VPC Router[uuid:%s] already has a firewall.", + "en_US": "the VPC Router[uuid:{0}] already has a firewall.", + "zh_CN": "VPC路由器[uuid:{0}]已有防火墙。", "arguments": [ - "msg.getRuleSetUuid()", - "msg.getRuleNumber()" + "msg.getVpcUuid()" ], - "line": 342, + "line": 188, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "only tcp or udp protocol can use port", - "en_US": "only tcp or udp protocol can use port", - "zh_CN": "", + "raw": "only tcp protocol can use tcp flag", + "en_US": "only tcp protocol can use tcp flag", + "zh_CN": "只有TCP协议才能使用TCP标志", "arguments": [], - "line": 372, + "line": 378, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "can not detach system default ruleSet", - "en_US": "can not detach system default ruleSet", - "zh_CN": "", + "raw": "only icmp protocol can use icmp type", + "en_US": "only icmp protocol can use icmp type", + "zh_CN": "只有ICMP协议才能使用ICMP类型", "arguments": [], - "line": 88, + "line": 382, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "can not delete ruleSet[%s] because it still attached to nic", - "en_US": "can not delete ruleSet[{0}] because it still attached to nic", - "zh_CN": "", + "raw": "already has a rule template with name %s", + "en_US": "already has a rule template with name {0}", + "zh_CN": "已有名为{0}的规则模板", + "arguments": [ + "msg.getName()", + "msg.getRuleNumber()" + ], + "line": 239, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "the ruleSet[%s] already has a rule with rule number %s.", + "en_US": "the ruleSet[{0}] already has a rule with rule number {1}.", + "zh_CN": "规则集[{0}]已具有规则编号为{1}的规则。", + "arguments": [ + "msg.getRuleSetUuid()", + "msg.getRuleNumber()" + ], + "line": 338, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "can not update default rule[%s]", + "en_US": "can not update default rule[{0}]", + "zh_CN": "无法更新默认规则[{0}]", "arguments": [ "msg.getUuid()" ], - "line": 110, + "line": 343, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "can not delete system default ruleSet", - "en_US": "can not delete system default ruleSet", - "zh_CN": "", + "raw": "the rule [%s] number is invalid", + "en_US": "the rule [{0}] number is invalid", + "zh_CN": "规则[{0}]编号无效", + "arguments": [ + "msg.getUuid()" + ], + "line": 407, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "can not attach the default ruleSet to other nic", + "en_US": "can not attach the default ruleSet to other nic", + "zh_CN": "无法将默认规则集附加到其他NIC", "arguments": [], - "line": 114, + "line": 416, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "ruleSet[%s] already has a l3[%s]", + "en_US": "ruleSet[{0}] already has a l3[{1}]", + "zh_CN": "规则集[{0}]已具有L3[{1}]", + "arguments": [ + "msg.getRuleSetUuid()", + "msg.getL3Uuid()" + ], + "line": 431, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "already has a rule with the number[%s]", + "en_US": "already has a rule with the number[{0}]", + "zh_CN": "已具有编号为[{0}]的规则", + "arguments": [ + "duplicateRuleNumbers" + ], + "line": 450, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" + }, + { + "raw": "the ruleSet[%s] already has a rule with the rule number %s.", + "en_US": "the ruleSet[{0}] already has a rule with the rule number {1}.", + "zh_CN": "规则集[{0}]已具有规则编号为{1}的规则。", + "arguments": [ + "msg.getRuleSetUuid()", + "msg.getRuleNumber()" + ], + "line": 748, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "can not delete system default rule", - "en_US": "can not delete system default rule", - "zh_CN": "", - "arguments": [], - "line": 125, + "raw": "could not add firewall rule[%d] only tcp or udp protocol can use port", + "en_US": "could not add firewall rule[{0}] only tcp or udp protocol can use port", + "zh_CN": "无法添加防火墙规则[{0}]只有TCP或UDP协议可以使用端口", + "arguments": [ + "msg.getRuleNumber()" + ], + "line": 779, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "VPC Router[uuid:%s] already has a firewall.", - "en_US": "VPC Router[uuid:{0}] already has a firewall.", - "zh_CN": "", + "raw": "could not add firewall rule[%d] only tcp protocol can use tcp flag", + "en_US": "could not add firewall rule[{0}] only tcp protocol can use tcp flag", + "zh_CN": "无法添加防火墙规则[{0}]只有TCP协议可以使用TCP标志", "arguments": [ - "msg.getVpcUuid()" + "msg.getRuleNumber()" ], - "line": 150, + "line": 785, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "can not update default rule[%s]", - "en_US": "can not update default rule[{0}]", - "zh_CN": "", + "raw": "could not add firewall rule[%d] because only icmp protocol can use icmp type", + "en_US": "could not add firewall rule[{0}] because only icmp protocol can use icmp type", + "zh_CN": "无法添加防火墙规则[{0}],因为只有ICMP协议可以使用ICMP类型", "arguments": [ - "msg.getUuid()" + "msg.getRuleNumber()" ], - "line": 157, + "line": 790, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "only tcp protocol can use tcp flag", - "en_US": "only tcp protocol can use tcp flag", - "zh_CN": "", - "arguments": [], - "line": 377, + "raw": "could not add firewall rule[%d] because only tcp or udp protocol can use port", + "en_US": "could not add firewall rule[{0}] because only tcp or udp protocol can use port", + "zh_CN": "无法添加防火墙规则[{0}],因为只有TCP或UDP协议可以使用端口", + "arguments": [ + "msg.getRuleNumber()" + ], + "line": 801, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "only icmp protocol can use icmp type", - "en_US": "only icmp protocol can use icmp type", - "zh_CN": "", - "arguments": [], - "line": 381, + "raw": "could not add firewall rule[%d] because only tcp protocol can use tcp flag", + "en_US": "could not add firewall rule[{0}] because only tcp protocol can use tcp flag", + "zh_CN": "无法添加防火墙规则[{0}],因为只有TCP协议可以使用TCP标志", + "arguments": [ + "msg.getRuleNumber()" + ], + "line": 824, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "Rule [%s] not support update state", - "en_US": "Rule [{0}] not support update state", - "zh_CN": "", + "raw": "could not add firewall rule[%d] because %s", + "en_US": "could not add firewall rule[{0}] because {1}", + "zh_CN": "无法添加防火墙规则[{0}],因为{1}", "arguments": [ - "msg.getUuid()" + "msg.getRuleNumber()", + "error" ], - "line": 221, + "line": 832, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "Default ruleSet can not be attached to other nic", - "en_US": "Default ruleSet can not be attached to other nic", - "zh_CN": "", - "arguments": [], - "line": 227, + "raw": "could not add firewall rule, because ruleNo %d is invalid", + "en_US": "could not add firewall rule, because ruleNo {0} is invalid", + "zh_CN": "无法添加防火墙规则,因为RuleNo{0}无效", + "arguments": [ + "vo.getRuleNumber()" + ], + "line": 846, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "Only out direction support attach ruleSet", - "en_US": "Only out direction support attach ruleSet", - "zh_CN": "", - "arguments": [], - "line": 231, + "raw": "could not add firewall rule, because there is no action for ruleNo:%d", + "en_US": "could not add firewall rule, because there is no action for ruleNo:{0}", + "zh_CN": "无法添加防火墙规则,因为没有针对RuleNo的操作:{0}", + "arguments": [ + "vo.getRuleNumber()" + ], + "line": 853, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "L3[%s] forward[%s] already attached a ruleSet", - "en_US": "L3[{0}] forward[{1}] already attached a ruleSet", - "zh_CN": "", + "raw": "could not add firewall rule, because source IP length: %s is not valid for ruleNo:%d", + "en_US": "could not add firewall rule, because source IP length: {0} is not valid for ruleNo:{1}", + "zh_CN": "无法添加防火墙规则,因为源IP长度{0}对RuleNo{1}无效", "arguments": [ - "msg.getL3Uuid()", - "msg.getForward()" + "vo.getSourceIp()", + "vo.getRuleNumber()" ], - "line": 239, + "line": 867, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "Invalid rule expression, the detail: %s", - "en_US": "Invalid rule expression, the detail: {0}", - "zh_CN": "", + "raw": "could not add firewall rule, because destination IP length: %s is not valid for ruleNo:%d", + "en_US": "could not add firewall rule, because destination IP length: {0} is not valid for ruleNo:{1}", + "zh_CN": "无法添加防火墙规则,因为目标IP长度{0}对RuleNo{1}无效", "arguments": [ - "e.getMessage()" + "vo.getDestIp()", + "vo.getRuleNumber()" ], - "line": 302, + "line": 874, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "operation failure, duplicate/overlap ip entry in %s", - "en_US": "operation failure, duplicate/overlap ip entry in {0}", - "zh_CN": "", + "raw": "could not add firewall rule, because there is no state for ruleNo:%d", + "en_US": "could not add firewall rule, because there is no state for ruleNo:{0}", + "zh_CN": "无法添加防火墙规则,因为RuleNo没有状态:{0}", "arguments": [ - "ips" + "vo.getRuleNumber()" ], - "line": 284, + "line": 885, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "operation failure, there are overlap ip range[start ip:%s, end ip: %s and start ip:%s, end ip: %s]", - "en_US": "operation failure, there are overlap ip range[start ip:{0}, end ip: {1} and start ip:{2}, end ip: {3}]", - "zh_CN": "", + "raw": "could not add firewall rule, because description length %s is not valid for ruleNo:%d", + "en_US": "could not add firewall rule, because description length {0} is not valid for ruleNo:{1}", + "zh_CN": "无法添加防火墙规则,因为描述长度{0}对RuleNo无效:{1}", "arguments": [ - "startIp", - "endIp", - "NetworkUtils.longToIpv4String(r.lowerEndpoint())", - "NetworkUtils.longToIpv4String(r.upperEndpoint())" + "vo.getDestIp()", + "vo.getRuleNumber()" ], - "line": 295, + "line": 892, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "operation failure, port format only supports port/portRange, but find %s", - "en_US": "operation failure, port format only supports port/portRange, but find {0}", - "zh_CN": "", - "arguments": [ - "port" - ], - "line": 309, + "raw": "the configuration file has format error", + "en_US": "the configuration file has format error", + "zh_CN": "配置文件有格式错误", + "arguments": [], + "line": 942, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { - "raw": "protocol state only support new/established/invalid/related,but found %s", - "en_US": "protocol state only support new/established/invalid/related,but found {0}", - "zh_CN": "", + "raw": "the firewall rules in the configuration file have syntax errors: %s", + "en_US": "the firewall rules in the configuration file have syntax errors: {0}", + "zh_CN": "配置文件中的防火墙规则有语法错误:{0}", "arguments": [ - "state" + "errorInfo" ], - "line": 331, + "line": 948, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java" }, { "raw": "sync firewall config failed,because %s", "en_US": "sync firewall config failed,because {0}", - "zh_CN": "", + "zh_CN": "同步防火墙配置失败,因为{0}", "arguments": [ "rsp.getError()" ], - "line": 290, + "line": 272, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "update firewall ruleSet action failed, because %s", "en_US": "update firewall ruleSet action failed, because {0}", - "zh_CN": "", + "zh_CN": "更新防火墙规则集操作失败,因为{0}", "arguments": [ "rsp.getError()" ], - "line": 441, + "line": 459, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" + }, + { + "raw": "Can not find l3[%] related mac on vRouter[%s]", + "en_US": "Can not find l3[%] related mac on vRouter[{0}]", + "zh_CN": "在VRouter[{0}]上找不到与L3[%]相关的MAC", + "arguments": [ + "l3Uuid", + "vRouterUuid" + ], + "line": 492, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "create firewall rule[%s] failed, because %s", "en_US": "create firewall rule[{0}] failed, because {1}", - "zh_CN": "", + "zh_CN": "创建防火墙规则[{0}]失败,原因是{1}", "arguments": [ - "cmd.getRule().getRuleNumber()", + "cmd.getRef().getRuleSetInfo().getRules().get(0).getRuleNumber()", "rsp.getError()" ], - "line": 516, + "line": 557, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "delete firewall on vRouter[%s],because %s", "en_US": "delete firewall on vRouter[{0}],because {1}", - "zh_CN": "", + "zh_CN": "删除VRouter[{0}]上的防火墙,因为{1}", "arguments": [ "vRouterUuid", "re.getError().getCause()" ], - "line": 591, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" - }, - { - "raw": "create firewall ruleSet[%s] failed, because %s", - "en_US": "create firewall ruleSet[{0}] failed, because {1}", - "zh_CN": "", - "arguments": [ - "cmd.getRuleSet().getName()", - "re.getError().getCause()" - ], - "line": 664, + "line": 645, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "delete firewall rule failed on vRouter[%s], because %s", "en_US": "delete firewall rule failed on vRouter[{0}], because {1}", - "zh_CN": "", + "zh_CN": "在VRouter[{0}]上删除防火墙规则失败,因为{1}", "arguments": [ "vRouterUuid", "rsp.getError()" ], - "line": 744, + "line": 851, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { - "raw": "change firewall rule state on vRouter[%s] failed, because %s", - "en_US": "change firewall rule state on vRouter[{0}] failed, because {1}", - "zh_CN": "", + "raw": "create firewall ruleSet[%s] failed, because %s", + "en_US": "create firewall ruleSet[{0}] failed, because {1}", + "zh_CN": "创建防火墙规则集[{0}]失败,原因是{1}", "arguments": [ - "vRouterUuid", - "rsp.getError()" + "cmd.getRuleSet().getName()", + "re.getError().getCause()" ], - "line": 822, + "line": 784, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { - "raw": "Can not find l3[%] related mac on vRouter[%s]", - "en_US": "Can not find l3[%] related mac on vRouter[{0}]", - "zh_CN": "", + "raw": "change firewall rule state on vRouter[%s] failed, because %s", + "en_US": "change firewall rule state on vRouter[{0}] failed, because {1}", + "zh_CN": "更改VRouter[{0}]上的防火墙规则状态失败,原因是{1}", "arguments": [ - "struct.getL3Uuid()", - "vRouterUuid" + "vRouterUuid", + "rsp.getError()" ], - "line": 996, + "line": 936, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "attach firewall ruleSet[%s] failed, because %s", "en_US": "attach firewall ruleSet[{0}] failed, because {1}", - "zh_CN": "", + "zh_CN": "附加防火墙规则集[{0}]失败,原因是{1}", "arguments": [ - "cmd.getRef().getRuleSetName()", + "struct.getRuleSetUuid()", "re.getError()" ], - "line": 921, + "line": 1032, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "detach ruleSet failed, maybe it has been deleted", "en_US": "detach ruleSet failed, maybe it has been deleted", - "zh_CN": "", + "zh_CN": "分离规则集失败,它可能已被删除", "arguments": [], - "line": 956, + "line": 1063, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { "raw": "detach firewall ruleSet[%s] failed,because %s", "en_US": "detach firewall ruleSet[{0}] failed,because {1}", - "zh_CN": "", + "zh_CN": "分离防火墙规则集[{0}]失败,原因是{1}", "arguments": [ - "cmd.getRef().getRuleSetName()", + "struct.getRuleSetUuid()", "re.getError().getCause()" ], - "line": 1024, + "line": 1129, "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" }, { - "raw": "delete firewall ruleSet[%s] failed,because %s", - "en_US": "delete firewall ruleSet[{0}] failed,because {1}", - "zh_CN": "", + "raw": "cannot find vpcFirewall[uuid:%s] related vRouter", + "en_US": "cannot find vpcFirewall[uuid:{0}] related vRouter", + "zh_CN": "找不到与vpcFirewall[uuid:{0}]相关的虚拟路由器", "arguments": [ - "cmd.getRuleSetName()", - "re.getError().getCause()" + "msg.getVpcFirewallUuid()" ], - "line": 1102, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java" + "line": 114, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" + }, + { + "raw": "cannot find vpcFirewall[uuid:%s], it may have been deleted", + "en_US": "cannot find vpcFirewall[uuid:{0}], it may have been deleted", + "zh_CN": "找不到vpcFirewall[uuid:{0}],它可能已被删除", + "arguments": [ + "msg.getVpcFirewallUuid()" + ], + "line": 109, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" + }, + { + "raw": "cannot find vpcFirewallRuleSet[uuid:%s], it may have been deleted", + "en_US": "cannot find vpcFirewallRuleSet[uuid:{0}], it may have been deleted", + "zh_CN": "找不到VpcFirewallRuleSet[uuid:{0}],它可能已被删除", + "arguments": [ + "msg.getRuleSetUuid()" + ], + "line": 125, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" + }, + { + "raw": "cannot find vpcFirewallIpSetTemplate[uuid:%s], it may have been deleted", + "en_US": "cannot find vpcFirewallIpSetTemplate[uuid:{0}], it may have been deleted", + "zh_CN": "找不到VpcFireWallipSetTemplate[uuid:{0}],它可能已被删除", + "arguments": [ + "msg.getUuid()" + ], + "line": 301, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" }, { "raw": "attach firewall ruleSet[%s] to l3[%s] failed,because %s", "en_US": "attach firewall ruleSet[{0}] to l3[{1}] failed,because {2}", - "zh_CN": "", + "zh_CN": "将防火墙规则集[{0}]附加到L3[{1}]失败,原因是{2}", "arguments": [ "msg.getRuleSetUuid()", "msg.getL3Uuid()", "errorCode.getCause()" ], - "line": 129, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBase.java" + "line": 396, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java" }, { "raw": "detach firewall ruleSet from l3[%s] failed,because %s", "en_US": "detach firewall ruleSet from l3[{0}] failed,because {1}", - "zh_CN": "", + "zh_CN": "从L3[{0}]分离防火墙规则集失败,原因是{1}", "arguments": [ "msg.getL3Uuid()", "errorCode.getCause()" ], - "line": 156, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallBase.java" + "line": 424, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java" }, { - "raw": "cannot find vpcFirewall[uuid:%s], it may have been deleted", - "en_US": "cannot find vpcFirewall[uuid:{0}], it may have been deleted", - "zh_CN": "", + "raw": "find duplicate rule numbers %s on firewall[%s],l3[%s],forward[%s]", + "en_US": "find duplicate rule numbers {0} on firewall[{1}],l3[{2}],forward[{3}]", + "zh_CN": "在防火墙[{1}]、L3[{2}]、转发[{3}]上查找重复的规则编号{0}", "arguments": [ - "msg.getVpcFirewallUuid()" + "duplicateRuleNumber.get()", + "ref.getVpcFirewallUuid()", + "ref.getL3NetworkUuid()", + "ref.getPacketsForwardType()" ], - "line": 83, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" + "line": 475, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java" }, { - "raw": "cannot find vpcFirewall[uuid:%s] related vRouter", - "en_US": "cannot find vpcFirewall[uuid:{0}] related vRouter", - "zh_CN": "", + "raw": "no changes in ruleset %s", + "en_US": "no changes in ruleset {0}", + "zh_CN": "规则集{0}中没有更改", "arguments": [ - "vo.getVpcFirewallUuid()" + "self.getUuid()" ], - "line": 104, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" + "line": 483, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java" }, { - "raw": "cannot find vpcFirewallRule[uuid:%s], it may have been deleted", - "en_US": "cannot find vpcFirewallRule[uuid:{0}], it may have been deleted", - "zh_CN": "", + "raw": "firewall %s related vpc not in running state", + "en_US": "firewall {0} related vpc not in running state", + "zh_CN": "防火墙{0}相关的VPC未处于运行状态", "arguments": [ - "msg.getVpcFirewallRuleUuid()" + "firewall.get()" ], - "line": 99, - "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java" + "line": 515, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java" + }, + { + "raw": "default ruleset %s can only attached to one interface forward, but find %s related interface", + "en_US": "default ruleset {0} can only attached to one interface forward, but find {1} related interface", + "zh_CN": "默认规则集{0}只能转发到一个接口,但找到{1}个相关接口", + "arguments": [ + "self.getUuid()", + "refVOs.size()" + ], + "line": 753, + "fileName": "src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java" + }, + { + "raw": "destination[%s] can not has blackHole route and static route at same time", + "en_US": "destination[{0}] can not has blackHole route and static route at same time", + "zh_CN": "目标[{0}]不能同时具有黑洞路由和静态路由", + "arguments": [ + "msg.getDestination()" + ], + "line": 115, + "fileName": "src/main/java/org/zstack/vrouterRoute/VRouterRouteApiInterceptor.java" }, { "raw": "cannot find the route table [uuid:%s]", @@ -23462,138 +36654,211 @@ "arguments": [ "msg.getUuid()" ], - "line": 466, + "line": 469, "fileName": "src/main/java/org/zstack/vrouterRoute/VRouterRouteManagerImpl.java" }, { - "raw": "cluster[uuid:%s] hypervisorType is not %s", - "en_US": "cluster[uuid:{0}] hypervisorType is not {1}", - "zh_CN": "", + "raw": "xdragon host not support create vm using an iso image.", + "en_US": "xdragon host not support create vm using an iso image.", + "zh_CN": "神龙服务器不支持使用ISO镜像创建云主机。", + "arguments": [], + "line": 30, + "fileName": "src/main/java/org/zstack/xdragon/XDragonFilterExtensionPoint.java" + }, + { + "raw": "cluster[uuid:%s] hypervisorType is not %s", + "en_US": "cluster[uuid:{0}] hypervisorType is not {1}", + "zh_CN": "集群[uuid:{0}]管理程序类型不是{1}", + "arguments": [ + "msg.getClusterUuid()", + "XDragonConstant.HYPERVISOR_TYPE" + ], + "line": 34, + "fileName": "src/main/java/org/zstack/xdragon/XDragonHostFactory.java" + }, + { + "raw": "the url is null, please config the YunShan NSP.", + "en_US": "the url is null, please config the YunShan NSP.", + "zh_CN": "URL为空,请配置云山NSP。", + "arguments": [], + "line": 46, + "fileName": "src/main/java/org/zstack/yunshan/util/YunshanClient.java" + }, + { + "raw": "usb device[uuid:%s] has been attached VM[uuid:%s], cannot be add to zbox", + "en_US": "usb device[uuid:{0}] has been attached VM[uuid:{1}], cannot be add to zbox", + "zh_CN": "USB设备[uuid:{0}]已连接到云主机[uuid:{1}],无法添加到ZBox", + "arguments": [ + "msg.getUsbDeviceUuid()", + "inventory.getVmInstanceUuid()" + ], + "line": 55, + "fileName": "src/main/java/org/zstack/zbox/ZBoxApiInterceptor.java" + }, + { + "raw": "zbox[name:%s] status is not Ready, current status is %s", + "en_US": "zbox[name:{0}] status is not Ready, current status is {1}", + "zh_CN": "ZBox[名称:{0}]状态未就绪,当前状态为{1}", + "arguments": [ + "zbox.getName()", + "zbox.getStatus()" + ], + "line": 72, + "fileName": "src/main/java/org/zstack/zbox/ZBoxApiInterceptor.java" + }, + { + "raw": "zbox[uuid:%s] is still in use, cannot eject it", + "en_US": "zbox[uuid:{0}] is still in use, cannot eject it", + "zh_CN": "ZBox[uuid:{0}]仍在使用,无法将其弹出", + "arguments": [ + "msg.getZBoxUuid()" + ], + "line": 122, + "fileName": "src/main/java/org/zstack/zbox/ZBoxBase.java" + }, + { + "raw": "zbox[uuid:%s] is not Ready, cannot sync capacity.", + "en_US": "zbox[uuid:{0}] is not Ready, cannot sync capacity.", + "zh_CN": "ZBox[uuid:{0}]未就绪,无法同步容量。", + "arguments": [ + "msg.getZBoxUuid()" + ], + "line": 151, + "fileName": "src/main/java/org/zstack/zbox/ZBoxBase.java" + }, + { + "raw": "only file on zbox[mountPath:%s] can be deleted. but pass [%s]", + "en_US": "only file on zbox[mountPath:{0}] can be deleted. but pass [{1}]", + "zh_CN": "只能删除ZBox[mountPath:{0}]上的文件。但传递[{1}]", + "arguments": [ + "self.getMountPath()", + "msg.getInstallPath()" + ], + "line": 219, + "fileName": "src/main/java/org/zstack/zbox/ZBoxBase.java" + }, + { + "raw": "zbox[name:%s] state is not Ready, current state is %s", + "en_US": "zbox[name:{0}] state is not Ready, current state is {1}", + "zh_CN": "ZBox[名称:{0}]状态未就绪,当前状态为{1}", + "arguments": [ + "self.getName()", + "self.getStatus()" + ], + "line": 285, + "fileName": "src/main/java/org/zstack/zbox/ZBoxBase.java" + }, + { + "raw": "zbox[uuid: %s] seems like removed", + "en_US": "zbox[uuid: {0}] seems like removed", + "zh_CN": "ZBox[uuid:{0}]似乎已删除", "arguments": [ - "msg.getClusterUuid()", - "XDragonConstant.HYPERVISOR_TYPE" + "zbox.getUuid()" ], - "line": 34, - "fileName": "src/main/java/org/zstack/xdragon/XDragonHostFactory.java" + "line": 57, + "fileName": "src/main/java/org/zstack/zbox/ZBoxFactory.java" }, { - "raw": "xdragon host not support create vm using an iso image.", - "en_US": "xdragon host not support create vm using an iso image.", - "zh_CN": "神龙服务器不支持使用ISO镜像创建云主机。", - "arguments": [], - "line": 30, - "fileName": "src/main/java/org/zstack/xdragon/XDragonFilterExtensionPoint.java" + "raw": "output from [%s] is empty", + "en_US": "output from [{0}] is empty", + "zh_CN": "[{0}]的输出为空", + "arguments": [ + "apiStr" + ], + "line": 140, + "fileName": "src/main/java/org/zstack/zql/ast/parser/visitors/ValueVisitor.java" }, { - "raw": "the url is null, please config the YunShan NSP.", - "en_US": "the url is null, please config the YunShan NSP.", - "zh_CN": "", - "arguments": [], - "line": 46, - "fileName": "src/main/java/org/zstack/yunshan/util/YunshanClient.java" + "raw": "call action[%s] failed, cause: %s", + "en_US": "call action[{0}] failed, cause: {1}", + "zh_CN": "调用操作[{0}]失败,原因:{1}", + "arguments": [ + "apiName", + "JSONObjectUtil.toJsonString(ob)" + ], + "line": 159, + "fileName": "src/main/java/org/zstack/zql/ast/parser/visitors/ValueVisitor.java" }, { "raw": "invalid order by clause, expect direction[asc,desc] but got %s", "en_US": "invalid order by clause, expect direction[asc,desc] but got {0}", - "zh_CN": "", + "zh_CN": "ORDER BY子句无效,应为方向[ASC,DESC],但得到{0}", "arguments": [ "node.getDirection()" ], - "line": 13, - "fileName": "src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java" + "line": 14, + "fileName": "src/main/java/org/zstack/zql/ast/visitors/OrderByExprVistor.java" }, { "raw": "invalid order by clause, inventory[%s] doesn\u0027t have field[%s]", "en_US": "invalid order by clause, inventory[{0}] doesn\u0027t have field[{1}]", - "zh_CN": "", + "zh_CN": "ORDER BY子句无效,库存[{0}]没有字段[{1}]", "arguments": [ "m.simpleInventoryName()", - "node.getField()" + "f" ], - "line": 19, + "line": 22, "fileName": "src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java" }, { "raw": "the field to sum must be specified", "en_US": "the field to sum must be specified", - "zh_CN": "", + "zh_CN": "必须指定要汇总的字段", "arguments": [], "line": 31, "fileName": "src/main/java/org/zstack/zql/ast/visitors/plugin/SumPlugin.java" }, { - "raw": "resource[%s] doesn\u0027t support zwatch return with clause", - "en_US": "resource[{0}] doesn\u0027t support zwatch return with clause", - "zh_CN": "", + "raw": "volume %s still have snapshot group on vm %s, cannot attach to other vm", + "en_US": "volume {0} still have snapshot group on vm {1}, cannot attach to other vm", + "zh_CN": "卷{0}在云主机{1}上仍具有快照组,无法连接到其他云主机", "arguments": [ - "clz.getName()" + "volume.getUuid()", + "volume.getLastVmInstanceUuid()" ], - "line": 125, - "fileName": "src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java" + "line": 95, + "fileName": "src/main/java/org/zstack/zsv/ZsvManagerImpl.java" + }, + { + "raw": "volume %s still have snapshot group, cannot delete it", + "en_US": "volume {0} still have snapshot group, cannot delete it", + "zh_CN": "卷{0}仍具有快照组,无法将其删除", + "arguments": [ + "volume.getUuid()" + ], + "line": 127, + "fileName": "src/main/java/org/zstack/zsv/ZsvManagerImpl.java" }, { "raw": "unknown parameter[%s] in zwatch return with clause, %s", "en_US": "unknown parameter[{0}] in zwatch return with clause, {1}", - "zh_CN": "", + "zh_CN": "ZWatch Return WITH子句中的未知参数[{0}],{1}", "arguments": [ "paramName", "normalizedExpr" ], - "line": 270, + "line": 241, "fileName": "src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java" }, { "raw": "invalid zwatch return with clause: %s, %s", "en_US": "invalid zwatch return with clause: {0}, {1}", - "zh_CN": "", + "zh_CN": "无效的ZWatch返回WITH子句:{0},{1}", "arguments": [ "expr", "e.getMessage()" ], - "line": 279, + "line": 250, "fileName": "src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java" }, - { - "raw": "update eventData[dataUuid\u003d%s] failed, %s", - "en_US": "update eventData[dataUuid\u003d{0}] failed, {1}", - "zh_CN": "", - "arguments": [ - "eventData.getDataUuid()", - "t.getMessage()" - ], - "line": 571, - "fileName": "src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java" - }, - { - "raw": "update alarmData[dataUuid\u003d%s] failed, %s", - "en_US": "update alarmData[dataUuid\u003d{0}] failed, {1}", - "zh_CN": "", - "arguments": [ - "alarmData.getDataUuid()", - "t.getMessage()" - ], - "line": 694, - "fileName": "src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java" - }, { "raw": "Some messages have expired. The expired messages are not allowed to be modified. The system will automatically clean up the expired messages. Please operate later", "en_US": "Some messages have expired. The expired messages are not allowed to be modified. The system will automatically clean up the expired messages. Please operate later", "zh_CN": "部分消息已过期,过期消息不允许修改。系统会自动清理过期消息,请稍后再操作", "arguments": [], - "line": 705, + "line": 1188, "fileName": "src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java" }, - { - "raw": "the action[uuid:%s] already attached to the event subscription[uuid:%s]", - "en_US": "the action[uuid:{0}] already attached to the event subscription[uuid:{1}]", - "zh_CN": "报警动作[uuid:{0}]已经被加载到报警时间订阅[uuid:{1}]", - "arguments": [ - "msg.getActionUuid()", - "msg.getSubscriptionUuid()" - ], - "line": 83, - "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" - }, { "raw": "event doesn\u0027t have label[%s]", "en_US": "event doesn\u0027t have label[{0}]", @@ -23601,7 +36866,7 @@ "arguments": [ "msg.getKey()" ], - "line": 107, + "line": 162, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23611,7 +36876,18 @@ "arguments": [ "msg.getKey()" ], - "line": 112, + "line": 167, + "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" + }, + { + "raw": "the action[uuid:%s] already attached to the event subscription[uuid:%s]", + "en_US": "the action[uuid:{0}] already attached to the event subscription[uuid:{1}]", + "zh_CN": "报警动作[uuid:{0}]已经被加载到报警时间订阅[uuid:{1}]", + "arguments": [ + "msg.getActionUuid()", + "msg.getSubscriptionUuid()" + ], + "line": 138, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23621,7 +36897,7 @@ "arguments": [ "msg.getNamespace()" ], - "line": 155, + "line": 213, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23632,7 +36908,7 @@ "ns.getName()", "msg.getEventName()" ], - "line": 129, + "line": 187, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23643,7 +36919,7 @@ "msg.getEventName()", "l.getKey()" ], - "line": 137, + "line": 195, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23654,27 +36930,27 @@ "k", "l" ], - "line": 197, + "line": 361, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { "raw": "Period field is not supported for metric [name:%s]", "en_US": "Period field is not supported for metric [name:{0}]", - "zh_CN": "", + "zh_CN": "度量[名称:{0}]不支持期间字段", "arguments": [ "msg.getMetricName()" ], - "line": 164, + "line": 222, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { "raw": "Period field can not be null for metric [name:%s]", "en_US": "Period field can not be null for metric [name:{0}]", - "zh_CN": "", + "zh_CN": "度量[名称:{0}]的期间字段不能为Null", "arguments": [ "msg.getMetricName()" ], - "line": 161, + "line": 219, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23683,19 +36959,19 @@ "zh_CN": "命名空间[{0}]不包含时序数据[{1}]", "arguments": [ "msg.getNamespace()", - "msg.getMetricName()" + "metricName" ], - "line": 172, + "line": 401, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { "raw": "the metric[%s] is admin only, not available for current user", "en_US": "the metric[{0}] is admin only, not available for current user", - "zh_CN": "", + "zh_CN": "指标[{0}]仅供管理员使用,不可用于当前用户", "arguments": [ - "msg.getMetricName()" + "metric" ], - "line": 178, + "line": 405, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23703,10 +36979,10 @@ "en_US": "the metric[{0}] doesn\u0027t have the label[{1}]", "zh_CN": "时序数据[{0}]没有标签[{0}]", "arguments": [ - "msg.getMetricName()", + "templateVO.getMetricName()", "l.getKey()" ], - "line": 186, + "line": 350, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23716,7 +36992,7 @@ "arguments": [ "actionType" ], - "line": 209, + "line": 273, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23727,7 +37003,7 @@ "actionUuid", "actionType" ], - "line": 214, + "line": 278, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23739,7 +37015,7 @@ "msg.getActionType()", "msg.getAlarmUuid()" ], - "line": 222, + "line": 286, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23752,7 +37028,17 @@ "msg.getValue()", "msg.getAlarmUuid()" ], - "line": 232, + "line": 296, + "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" + }, + { + "raw": "namespace[%s] not support", + "en_US": "namespace[{0}] not support", + "zh_CN": "不支持命名空间[{0}]", + "arguments": [ + "msg.getNamespace()" + ], + "line": 390, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java" }, { @@ -23782,7 +37068,7 @@ "arguments": [ "alarmVO.getMetricName()" ], - "line": 576, + "line": 525, "fileName": "src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java" }, { @@ -23834,20 +37120,20 @@ "en_US": "invalid application platform type[{0}]", "zh_CN": "无效的平台类型[{0}]", "arguments": [ - "msg.getApplicationPlatformType()" + "vo.getApplicationPlatformType()" ], - "line": 73, + "line": 198, "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java" }, { "raw": "parameters:\\n %s are not supported by ZStack, available values are:\\n %s", "en_US": "parameters:\\n {0} are not supported by ZStack, available values are:\\n {1}", - "zh_CN": "", + "zh_CN": "参数:\\n{0}不受ZStack支持,可用值为:\\n{1}", "arguments": [ - "String.join(\",\\n\", errorParams)", - "String.join(\",\\n\", AbstractTextTemplate.defaultSupportedParams)" + "String.join(\",\\n\", errorRecoverParams)", + "String.join(\",\\n\", AbstractTextTemplate.defaultSupportedParams.get(vo.getType()))" ], - "line": 159, + "line": 212, "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java" }, { @@ -23855,52 +37141,72 @@ "en_US": "application platform/endpoint [{0}] doesn\u0027t support user-defined template", "zh_CN": "应用平台/终端[{0}]不支持用户定义模板", "arguments": [ - "msg.getApplicationPlatformType()" + "vo.getApplicationPlatformType()" ], - "line": 78, + "line": 203, "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java" }, { "raw": "The length of aliyun sms sign should between 2 to 12 characters. Got sign: [%s] with [%d] characters.", "en_US": "The length of aliyun sms sign should between 2 to 12 characters. Got sign: [{0}] with [{1}] characters.", - "zh_CN": "", + "zh_CN": "阿里云短信标识的长度应在2-12个字符之间。获得符号:[{0}],包含[{1}]个字符。", "arguments": [ "sign", "sign.length()" ], - "line": 91, + "line": 107, "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java" }, { "raw": "Sms template code is a string with 13 characters. Got alarm template code: [%s] with [%d] characters.", "en_US": "Sms template code is a string with 13 characters. Got alarm template code: [{0}] with [{1}] characters.", - "zh_CN": "", + "zh_CN": "短信模板代码是一个13个字符的字符串。获取报警模板代码:[{0}],包含[{1}]个字符。", "arguments": [ "alarmTemplateCode", "alarmTemplateCode.length()" ], - "line": 96, + "line": 112, "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java" }, { "raw": "Sms template code is a string with 13 characters. Got event template code: [%s] with [%d] characters.", "en_US": "Sms template code is a string with 13 characters. Got event template code: [{0}] with [{1}] characters.", - "zh_CN": "", + "zh_CN": "短信模板代码是一个13个字符的字符串。获取事件模板代码:[{0}],包含[{1}]个字符。", "arguments": [ "eventTemplateCode", "eventTemplateCode.length()" ], - "line": 101, + "line": 117, "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java" }, + { + "raw": "no template of this type:%s, ", + "en_US": "no template of this type:{0}, ", + "zh_CN": "没有此类型的模板:{0},", + "arguments": [ + "type" + ], + "line": 31, + "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/TextTemplateFactory.java" + }, + { + "raw": "template error:%s", + "en_US": "template error:{0}", + "zh_CN": "模板错误:{0}", + "arguments": [ + "e.getMessage()" + ], + "line": 43, + "fileName": "src/main/java/org/zstack/zwatch/alarm/sns/TextTemplateFactory.java" + }, { "raw": "alarm[uuid:%s] is a system alarm which cannot be deleted", "en_US": "alarm[uuid:{0}] is a system alarm which cannot be deleted", "zh_CN": "报警器[uuid:{0}]是一个系统报警器,不能被删除", "arguments": [ - "DATA_DIR_CAPACITY_ALARM_UUID" + "DATA_DIR_CAPACITY_ALARM_uuid" ], - "line": 587, + "line": 1471, "fileName": "src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java" }, { @@ -23908,10 +37214,10 @@ "en_US": "removing system topic[uuid:{0}] from system alarm[uuid:{1}] is forbidden", "zh_CN": "禁止从系统报警器[uuid:{1}]移除系统主题[uuid:{0}]", "arguments": [ - "SNSSystemAlarmTopicManager.SYSTEM_ALARM_TOPIC_UUID", - "DATA_DIR_CAPACITY_ALARM_UUID" + "SNSSystemAlarmTopicManager.SYSTEM_ALARM_TOPIC_uuid", + "DATA_DIR_CAPACITY_ALARM_uuid" ], - "line": 598, + "line": 1482, "fileName": "src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java" }, { @@ -23922,7 +37228,7 @@ "l.getKey()", "AuditDataV2.queryableLoginLabels" ], - "line": 203, + "line": 270, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -23930,37 +37236,37 @@ "en_US": "startTime[{0}] is greater than endTime[{1}]", "zh_CN": "开始时间[{0}]大于结束时间[{1}]", "arguments": [ - "msg.getStartTime()", - "msg.getEndTime()" + "startTime", + "endTime" ], - "line": 250, + "line": 487, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { "raw": "dataUuid cannot be missed", "en_US": "dataUuid cannot be missed", - "zh_CN": "", + "zh_CN": "不能缺少数据用户ID", "arguments": [], - "line": 114, + "line": 162, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { "raw": "dataStartTime and dataEndTime cannot be missed", "en_US": "dataStartTime and dataEndTime cannot be missed", - "zh_CN": "", + "zh_CN": "DataStartTime和DataEndTime不能丢失", "arguments": [], - "line": 120, + "line": 168, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { "raw": "dataStartTime[%s] is greater than dataEndTime[%s]", "en_US": "dataStartTime[{0}] is greater than dataEndTime[{1}]", - "zh_CN": "", + "zh_CN": "DataStartTime[{0}]大于DataEndTime[{1}]", "arguments": [ "msg.getDataStartTime()", "msg.getDataEndTime()" ], - "line": 124, + "line": 172, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -23970,7 +37276,30 @@ "arguments": [ "Namespace.ZSTACK_NAMESPACE_PREFIX" ], - "line": 142, + "line": 190, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "endTime[%s, %sms] must not be before startTime[%s, %sms]", + "en_US": "endTime[{0}, {1}ms] must not be before startTime[{2}, {3}ms]", + "zh_CN": "停止时间(endTime)[{0}, {1}ms]不能在开始时间(startTime)[{2}, {3}ms]", + "arguments": [ + "end", + "msg.getEndTime()", + "start", + "msg.getStartTime()" + ], + "line": 396, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "query period cannot exceed %s", + "en_US": "query period cannot exceed {0}", + "zh_CN": "查询期间不能超过{0}", + "arguments": [ + "MAX_QUERY_PERIOD" + ], + "line": 211, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -23980,7 +37309,7 @@ "arguments": [ "msg.getNamespace()" ], - "line": 153, + "line": 355, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -23991,7 +37320,7 @@ "msg.getMetricName()", "msg.getNamespace()" ], - "line": 161, + "line": 228, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -24000,10 +37329,10 @@ "zh_CN": "时序数据[{0}]的标签列表[{1}]没有指定的标签[{2}]", "arguments": [ "msg.getMetricName()", - "metric.getLabelNames()", - "l.getKey()" + "labels", + "label.getKey()" ], - "line": 174, + "line": 378, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -24014,51 +37343,114 @@ "msg.getMetricName()", "l.getValue()" ], - "line": 186, + "line": 253, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { - "raw": "label[%s] must be specified", - "en_US": "label[{0}] must be specified", - "zh_CN": "必须指定标签[{0}]", + "raw": "account[uuid: %s] has no access to the resource[uuid: %s]", + "en_US": "account[uuid: {0}] has no access to the resource[uuid: {1}]", + "zh_CN": "帐户[uuid:{0}]无权访问资源[uuid:{1}]", "arguments": [ - "AuditDataV2.TAG_RESOURCE_UUID" + "msg.getSession().getAccountUuid()", + "opt.get().getValue()" ], - "line": 229, + "line": 324, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { - "raw": "endTime[%s, %sms] must not be before startTime[%s, %sms]", - "en_US": "endTime[{0}, {1}ms] must not be before startTime[{2}, {3}ms]", - "zh_CN": "停止时间(endTime)[{0}, {1}ms]不能在开始时间(startTime)[{2}, {3}ms]", + "raw": "if namespace is all, not support specify metric and labels", + "en_US": "if namespace is all, not support specify metric and labels", + "zh_CN": "如果命名空间为ALL,则不支持指定规格和标签", + "arguments": [], + "line": 346, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "no namespace[%s] defined in the system", + "en_US": "no namespace[{0}] defined in the system", + "zh_CN": "系统中未定义名字空间(namespace[{0}])", "arguments": [ - "end", - "msg.getEndTime()", - "start", - "msg.getStartTime()" + "msg.getNamespace()" + ], + "line": 440, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "the namespace[%s] has no metric[%s]", + "en_US": "the namespace[{0}] has no metric[{1}]", + "zh_CN": "名字空间(namespace[{0}])不包含时序数据[{1}]", + "arguments": [ + "msg.getNamespace()", + "msg.getMetricName()" + ], + "line": 443, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "The url format is invalid, the beginning is not http", + "en_US": "The url format is invalid, the beginning is not http", + "zh_CN": "URL格式无效,开头不是HTTP", + "arguments": [], + "line": 433, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "Illegal json string, labelsJsonStr format is invalid", + "en_US": "Illegal json string, labelsJsonStr format is invalid", + "zh_CN": "非法的JSON字符串,labelsjsonstr格式无效", + "arguments": [], + "line": 449, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "platform[url\u003d%s] already exists", + "en_US": "platform[url\u003d{0}] already exists", + "zh_CN": "平台[URL\u003d{0}]已存在", + "arguments": [ + "url" + ], + "line": 477, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "alert acknowledgement record does not exist", + "en_US": "alert acknowledgement record does not exist", + "zh_CN": "警报确认记录不存在", + "arguments": [ + "msg.getAlertDataUuid()" + ], + "line": 498, + "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" + }, + { + "raw": "invalid table[%s]", + "en_US": "invalid table[{0}]", + "zh_CN": "表[{0}]无效", + "arguments": [ + "tableName" ], - "line": 271, + "line": 516, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { - "raw": "no namespace[%s] defined in the system", - "en_US": "no namespace[{0}] defined in the system", - "zh_CN": "系统中未定义名字空间(namespace[{0}])", + "raw": "endTime[%s] must not be before startTime[%s]", + "en_US": "endTime[{0}] must not be before startTime[{1}]", + "zh_CN": "EndTime[{0}]不能早于StartTime[{1}]", "arguments": [ - "msg.getNamespace()" + "endTime", + "startTime" ], - "line": 289, + "line": 522, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { - "raw": "the namespace[%s] has no metric[%s]", - "en_US": "the namespace[{0}] has no metric[{1}]", - "zh_CN": "名字空间(namespace[{0}])不包含时序数据[{1}]", + "raw": "the time interval exceeds % days", + "en_US": "the time interval exceeds % days", + "zh_CN": "时间间隔超过%天", "arguments": [ - "msg.getNamespace()", - "msg.getMetricName()" + "maxDurationDay" ], - "line": 293, + "line": 527, "fileName": "src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java" }, { @@ -24113,7 +37505,7 @@ "arguments": [ "str" ], - "line": 57, + "line": 58, "fileName": "src/main/java/org/zstack/zwatch/datatype/Label.java" }, { @@ -24123,7 +37515,7 @@ "arguments": [ "JSONObjectUtil.toJsonString(this)" ], - "line": 72, + "line": 79, "fileName": "src/main/java/org/zstack/zwatch/datatype/Label.java" }, { @@ -24133,7 +37525,7 @@ "arguments": [ "JSONObjectUtil.toJsonString(this)" ], - "line": 75, + "line": 82, "fileName": "src/main/java/org/zstack/zwatch/datatype/Label.java" }, { @@ -24143,9 +37535,19 @@ "arguments": [ "JSONObjectUtil.toJsonString(this)" ], - "line": 78, + "line": 85, "fileName": "src/main/java/org/zstack/zwatch/datatype/Label.java" }, + { + "raw": "the ValueCondition string[%s] require \u0027value\u0027 as key ", + "en_US": "the ValueCondition string[{0}] require \u0027value\u0027 as key ", + "zh_CN": "ValueCondition字符串[{0}]需要“ value ”作为键", + "arguments": [ + "str" + ], + "line": 73, + "fileName": "src/main/java/org/zstack/zwatch/datatype/ValueCondition.java" + }, { "raw": "invalid value[%s] of the argument[%s]", "en_US": "invalid value[{0}] of the argument[{1}]", @@ -24158,24 +37560,20 @@ "fileName": "src/main/java/org/zstack/zwatch/function/ArgumentChecker.java" }, { - "raw": "value[%s] is not a Integer number", - "en_US": "value[{0}] is not a Integer number", - "zh_CN": "值(value)[{0}]不是一个整数", - "arguments": [ - "v" - ], - "line": 21, - "fileName": "src/main/java/org/zstack/zwatch/function/LimitFunction.java" + "raw": "unknown arguments", + "en_US": "unknown arguments", + "zh_CN": "未知参数", + "arguments": [], + "line": 24, + "fileName": "src/main/java/org/zstack/zwatch/function/ExtremumFunction.java" }, { - "raw": "invalid argument[limit:%s], it can\u0027t be a negative number", - "en_US": "invalid argument[limit:{0}], it can\u0027t be a negative number", - "zh_CN": "无效的参数[limit:{0}],不能是负数", - "arguments": [ - "v" - ], - "line": 18, - "fileName": "src/main/java/org/zstack/zwatch/function/LimitFunction.java" + "raw": "missing required argument", + "en_US": "missing required argument", + "zh_CN": "缺少必需的参数", + "arguments": [], + "line": 30, + "fileName": "src/main/java/org/zstack/zwatch/function/ExtremumFunction.java" }, { "raw": "missing required argument[%s]", @@ -24184,7 +37582,7 @@ "arguments": [ "name" ], - "line": 46, + "line": 88, "fileName": "src/main/java/org/zstack/zwatch/function/MetricFunction.java" }, { @@ -24194,7 +37592,7 @@ "arguments": [ "k" ], - "line": 59, + "line": 101, "fileName": "src/main/java/org/zstack/zwatch/function/MetricFunction.java" }, { @@ -24204,119 +37602,195 @@ "arguments": [ "func.getName()" ], - "line": 68, + "line": 116, "fileName": "src/main/java/org/zstack/zwatch/function/MetricFunction.java" }, { - "raw": "unknown argument[%s]", - "en_US": "unknown argument[{0}]", - "zh_CN": "未知参数[{0}]", - "arguments": [ - "arg.name" - ], - "line": 41, - "fileName": "src/main/java/org/zstack/zwatch/function/SortFunction.java" - }, - { - "raw": "cannot find EventFamily[name:%s]", - "en_US": "cannot find EventFamily[name:{0}]", - "zh_CN": "找不到事件族[name:{0}]", + "raw": "value[%s] is not a Integer number", + "en_US": "value[{0}] is not a Integer number", + "zh_CN": "值(value)[{0}]不是一个整数", "arguments": [ - "name" + "v" ], - "line": 153, - "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java" + "line": 32, + "fileName": "src/main/java/org/zstack/zwatch/function/PaginationFunction.java" }, { - "raw": "cannot find EventFamily[name:%s, namespace:%s]", - "en_US": "cannot find EventFamily[name:{0}, namespace:{1}]", - "zh_CN": "找不到事件族[name:{0}, namespace:{1}]", + "raw": "invalid argument[limit:%s], it can\u0027t be a negative number", + "en_US": "invalid argument[limit:{0}], it can\u0027t be a negative number", + "zh_CN": "无效的参数[limit:{0}],不能是负数", "arguments": [ - "name", - "namespace" + "v" ], - "line": 175, - "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java" + "line": 19, + "fileName": "src/main/java/org/zstack/zwatch/function/PaginationFunction.java" }, { - "raw": "invalid query label[%s]. Allowed label names are %s", - "en_US": "invalid query label[{0}]. Allowed label names are {1}", - "zh_CN": "无效的查询标签[{0}]。允许标签名是 {1}", + "raw": "invalid argument[start:%s], it can\u0027t be a negative number", + "en_US": "invalid argument[start:{0}], it can\u0027t be a negative number", + "zh_CN": "参数[开始:{0}]无效,它不能是负数", "arguments": [ - "label.getKey()", - "names" + "v" ], - "line": 632, - "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java" + "line": 29, + "fileName": "src/main/java/org/zstack/zwatch/function/PaginationFunction.java" }, { - "raw": "there are multiple EventFamily with the name[%s], you must specify the label[%s]", - "en_US": "there are multiple EventFamily with the name[{0}], you must specify the label[{1}]", - "zh_CN": "存在多个名为[{0}]的事件族,你必须指定标签[{1}]", + "raw": "unknown argument[%s]", + "en_US": "unknown argument[{0}]", + "zh_CN": "未知参数[{0}]", "arguments": [ - "name.getValue()", - "InfluxEventDataV2.FIELD_NAMESPACE" + "arg.name" ], - "line": 666, - "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java" + "line": 42, + "fileName": "src/main/java/org/zstack/zwatch/function/SortFunction.java" }, { "raw": "unable to query influxdb, %s", "en_US": "unable to query influxdb, {0}", - "zh_CN": "", + "zh_CN": "无法查询InfluxDB,{0}", "arguments": [ "ret.getError()" ], - "line": 58, + "line": 62, "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java" }, { "raw": "invalid influxdb response: %s, no name found in columns", "en_US": "invalid influxdb response: {0}, no name found in columns", - "zh_CN": "", + "zh_CN": "InfluxDB响应无效:{0},在列中找不到名称", "arguments": [ "JSONObjectUtil.toJsonString(ret)" ], - "line": 102, + "line": 106, "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java" }, { "raw": "failed to create influxdb retention \u0027%s\u0027, %s", "en_US": "failed to create influxdb retention \u0027{0}\u0027, {1}", - "zh_CN": "", + "zh_CN": "无法创建InfluxDB保留“{0}”,{1}", "arguments": [ "retention", "res.getError()" ], - "line": 88, + "line": 92, "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java" }, { "raw": "failed to alter influxdb retention \u0027%s\u0027, %s", "en_US": "failed to alter influxdb retention \u0027{0}\u0027, {1}", - "zh_CN": "", + "zh_CN": "无法更改InfluxDB保留“{0}”,{1}", "arguments": [ "retention", "res.getError()" ], - "line": 81, + "line": 85, "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java" }, { "raw": "failed to create influxdb default user \u0027%s\u0027, %s", "en_US": "failed to create influxdb default user \u0027{0}\u0027, {1}", - "zh_CN": "", + "zh_CN": "无法创建InfluxDB默认用户“{0}”,{1}", "arguments": [ "defaultUserName", "res.getError()" ], - "line": 120, + "line": 124, "fileName": "src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java" }, + { + "raw": "cannot find EventFamily[name:%s]", + "en_US": "cannot find EventFamily[name:{0}]", + "zh_CN": "找不到事件族[name:{0}]", + "arguments": [ + "name" + ], + "line": 806, + "fileName": "src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java" + }, + { + "raw": "cannot find EventFamily[name:%s, namespace:%s]", + "en_US": "cannot find EventFamily[name:{0}, namespace:{1}]", + "zh_CN": "找不到事件族[name:{0}, namespace:{1}]", + "arguments": [ + "name", + "namespace" + ], + "line": 797, + "fileName": "src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java" + }, + { + "raw": "invalid query label[%s]. Allowed label names are %s", + "en_US": "invalid query label[{0}]. Allowed label names are {1}", + "zh_CN": "无效的查询标签[{0}]。允许标签名是 {1}", + "arguments": [ + "label.getKey()", + "nameSpaceLabelList" + ], + "line": 726, + "fileName": "src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java" + }, + { + "raw": "there are multiple EventFamily with the name[%s], you must specify the label[%s]", + "en_US": "there are multiple EventFamily with the name[{0}], you must specify the label[{1}]", + "zh_CN": "存在多个名为[{0}]的事件族,你必须指定标签[{1}]", + "arguments": [ + "name.getValue()", + "InfluxEventDataV2.FIELD_NAMESPACE" + ], + "line": 627, + "fileName": "src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java" + }, + { + "raw": "the instance[%s] is already in the group", + "en_US": "the instance[{0}] is already in the group", + "zh_CN": "实例[{0}]已在组中", + "arguments": [ + "msg.getInstanceUuid()" + ], + "line": 55, + "fileName": "src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java" + }, + { + "raw": "instance[%s] is not in the group", + "en_US": "instance[{0}] is not in the group", + "zh_CN": "实例[{0}]不在组中", + "arguments": [ + "msg.getInstanceUuid()" + ], + "line": 66, + "fileName": "src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java" + }, + { + "raw": "The monitorGroup[%s] does not have an monitorTemplate applied", + "en_US": "The monitorGroup[{0}] does not have an monitorTemplate applied", + "zh_CN": "MonitorGroup[{0}]未应用MonitorTemplate", + "arguments": [ + "msg.getGroupUuid()" + ], + "line": 76, + "fileName": "src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java" + }, + { + "raw": "The instance in the group has reached the maximum limit", + "en_US": "The instance in the group has reached the maximum limit", + "zh_CN": "组中的实例已达到最大限制", + "arguments": [], + "line": 333, + "fileName": "src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupBase.java" + }, + { + "raw": "The rule in the template has reached the maximum limit", + "en_US": "The rule in the template has reached the maximum limit", + "zh_CN": "模板中的规则已达到最大限制", + "arguments": [], + "line": 607, + "fileName": "src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupManagerImpl.java" + }, { "raw": "no mysql namespace[%s] found", "en_US": "no mysql namespace[{0}] found", - "zh_CN": "", + "zh_CN": "未找到MySQL命名空间[{0}]", "arguments": [ "qo.getNamespaceName()" ], @@ -24331,19 +37805,19 @@ "getName()", "queryObject.getMetricName()" ], - "line": 46, + "line": 48, "fileName": "src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java" }, { "raw": "metric[%s] of the namespace[%s] has no label named %s", "en_US": "metric[{0}] of the namespace[{1}] has no label named {2}", - "zh_CN": "名字空间(namespace)[{1}]的时序数据(metric)[{1}]没有名为{2}的标签", + "zh_CN": "名字空间(namespace)[{1}]的时序数据(metric)[{0}]没有名为{2}的标签", "arguments": [ "m.getName()", "getName()", "l.getKey()" ], - "line": 52, + "line": 54, "fileName": "src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java" }, { @@ -24351,7 +37825,7 @@ "en_US": "error happened but reason not specified", "zh_CN": "发生了意想不到的错误", "arguments": [], - "line": 406, + "line": 437, "fileName": "src/main/java/org/zstack/zwatch/namespace/NamespaceEventManagerImpl.java" }, { @@ -24362,9 +37836,19 @@ "d", "Platform.getManagementServerIp()" ], - "line": 31, + "line": 32, "fileName": "src/main/java/org/zstack/zwatch/namespace/SystemNamespace.java" }, + { + "raw": "%s", + "en_US": "{0}", + "zh_CN": "{0}", + "arguments": [ + "rsp.getError()" + ], + "line": 165, + "fileName": "src/main/java/org/zstack/zwatch/prometheus/KvmHostScrape.java" + }, { "raw": "LessThanOrEqualTo", "en_US": "LessThanOrEqualTo", @@ -24397,6 +37881,78 @@ "line": 29, "fileName": "src/main/java/org/zstack/zwatch/ruleengine/ComparisonOperator.java" }, + { + "raw": "resource[%s] doesn\u0027t support zwatch return with clause", + "en_US": "resource[{0}] doesn\u0027t support zwatch return with clause", + "zh_CN": "资源[{0}]不支持ZWatch Return WITH子句", + "arguments": [ + "voClassSimpleName" + ], + "line": 78, + "fileName": "src/main/java/org/zstack/zwatch/utils/ResourceVOToNamespaceMappingUtils.java" + }, + { + "raw": "on purpose", + "en_US": "on purpose", + "zh_CN": "", + "arguments": [], + "line": 80, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, + { + "raw": "on purpose %d", + "en_US": "on purpose {0}", + "zh_CN": "", + "arguments": [ + "item" + ], + "line": 56, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, + { + "raw": "I should not be in error list %d", + "en_US": "I should not be in error list {0}", + "zh_CN": "", + "arguments": [ + "item" + ], + "line": 39, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, + { + "raw": "I should not be in error list either %d", + "en_US": "I should not be in error list either {0}", + "zh_CN": "", + "arguments": [ + "item" + ], + "line": 40, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, + { + "raw": "done, on purpose", + "en_US": "done, on purpose", + "zh_CN": "", + "arguments": [], + "line": 63, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, + { + "raw": "I should not be errs list", + "en_US": "I should not be errs list", + "zh_CN": "", + "arguments": [], + "line": 81, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, + { + "raw": "I should not be errs list either.", + "en_US": "I should not be errs list either.", + "zh_CN": "", + "arguments": [], + "line": 82, + "fileName": "src/test/java/org/zstack/test/TestSafeWhile.java" + }, { "raw": "unit test asks it to fail", "en_US": "unit test asks it to fail", @@ -24414,11 +37970,35 @@ "fileName": "src/test/java/org/zstack/test/compute/hostallocator/HostAllocateExtension.java" }, { - "raw": "on purpose", - "en_US": "on purpose", + "raw": "on purpose 3", + "en_US": "on purpose 3", "zh_CN": "", "arguments": [], - "line": 27, - "fileName": "src/test/java/org/zstack/test/kvm/KVMPingAgentExtensionForTest.java" + "line": 67, + "fileName": "src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java" + }, + { + "raw": "on purpose 1", + "en_US": "on purpose 1", + "zh_CN": "", + "arguments": [], + "line": 75, + "fileName": "src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java" + }, + { + "raw": "on purpose 2", + "en_US": "on purpose 2", + "zh_CN": "", + "arguments": [], + "line": 83, + "fileName": "src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java" + }, + { + "raw": "Failed to validate universal sms", + "en_US": "Failed to validate universal sms", + "zh_CN": "发送测试短信失败", + "arguments": [], + "line": 166, + "fileName": "src/main/java/org/zstack/sns/platform/universalsms/SNSUniversalSmsEndpoint.java" } -] +] \ No newline at end of file diff --git a/conf/i18n/messages_en_US.properties b/conf/i18n/messages_en_US.properties index 3a62745a408..8148dcd6869 100755 --- a/conf/i18n/messages_en_US.properties +++ b/conf/i18n/messages_en_US.properties @@ -1,16 +1,16 @@ -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:44 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:43 # args: accountUuid,userUuid no\ pemission\ to\ do\ the\ operation\ for\ [accountUuid\:%s,\ userUuid\:%s] = no pemission to do the operation for [accountUuid:{0}, userUuid:{1}] -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:51 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:50 # args: If\ a\ specified\ Accesskey\ is\ expected,\ the\ AccesskeyId\ and\ the\ AccesskeySecret\ must\ be\ provided\ at\ the\ same\ time. = If a specified Accesskey is expected, the AccesskeyId and the AccesskeySecret must be provided at the same time. -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:65 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:72 # args: msg.getAccountUuid(),msg.getUserUuid() [accountId\:\ %s,\ userID\:\ %s]\ is\ not\ valid\ account\ or\ iam2\ porject/user = [accountId: {0}, userID: {1}] is not valid account or iam2 porject/user -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:77 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:91 # args: msg.getAccountUuid(),msg.getUserUuid() accessKey\ number\ for\ [accountId\:\ %s,\ userID\:\ %s]exceeds\ the\ max = accessKey number for [accountId: {0}, userID: {1}]exceeds the max @@ -31,14 +31,42 @@ ip\ format\ only\ supports\ ip/iprange/cidr,\ but\ find\ %s = ip format only sup ip\ range[%s,\ %s]\ is\ overlap\ with\ [%s,\ %s]\ in\ access-control-list\ group\:%s = ip range[{0}, {1}] is overlap with [{2}, {3}] in access-control-list group:{4} # at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:127 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ redirect\ rule,\ can\ not\ add\ IP\ Entry = the access-control-list groups[{0}] already own redirect rule, can not add IP Entry + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:133 # args: acl.getUuid(),AccessControlListConstants.MAX_ENTRY_COUNT_PER_GROUP the\ access-control-list\ groups[%s]\ can't\ be\ added\ more\ than\ %d\ ip\ entries = the access-control-list groups[{0}] can't be added more than {1} ip entries +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:138 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ redirect\ rule,\ can\ not\ add\ ip\ entry = the access-control-list groups[{0}] already own redirect rule, can not add ip entry + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:154 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ ip\ entry,\ can\ not\ add\ redirect\ rule = the access-control-list groups[{0}] already own ip entry, can not add redirect rule + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:158 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ one\ redirect\ rule,\ can\ not\ add\ redirect\ rule = the access-control-list groups[{0}] already own one redirect rule, can not add redirect rule + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:162 +# args: +domain\ and\ url\ can\ not\ both\ empty = domain and url can not both empty + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:178 +# args: msg.getUrl() +url[%s]\ is\ not\ validate\ url = url[{0}] is not validate url + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:167 +# args: msg.getDomain() +domain[%s]\ is\ not\ validate\ domain = domain[{0}] is not validate domain + # at: src/main/java/org/zstack/aliyun/account/AliyunAccountBase.java:348 # args: builder.deleteCharAt(builder.length() - 1),timeout cannot\ connect\ to\ [%s]\ in\ %d\ milliseconds,\ so\ aliyun\ openapi\ is\ unreachable. = cannot connect to [{0}] in {1} milliseconds, so aliyun openapi is unreachable. -# at: src/main/java/org/zstack/aliyun/backup/BackupToAliyunBase.java:465 +# at: src/main/java/org/zstack/aliyun/backup/BackupToAliyunBase.java:466 # args: no\ bucket\ found\ for\ backup = no bucket found for backup @@ -58,67 +86,63 @@ accessKey\ and\ keySecret\ must\ be\ set! = accessKey and keySecret must be set! # args: regionId\ must\ be\ set! = regionId must be set! -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:238 -# args: -cannot\ find\ key\ /\ secret\ from\ msg = cannot find key / secret from msg - -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2131 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2162 # args: AliyunConstant.DEFAULT_ENTRY_WAIT_STATUS_TIMEOUT entry\ is\ still\ existed\ after\ %s\ ms = entry is still existed after {0} ms -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2637 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2648 # args: request.getInstanceIds() cannot\ find\ EcsInstance[%s],\ please\ check\ if\ it\ exists\ in\ Aliyun\ console = cannot find EcsInstance[{0}], please check if it exists in Aliyun console -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2697 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2708 # args: image\ already\ existed\ remote,\ please\ use\ sync\ first. = image already existed remote, please use sync first. -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2883 -# args: -no\ identity\ zones\ can\ be\ used\ now = no identity zones can be used now - -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:3019 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:3015 # args: request.getRegionId() regionId[%s]\ is\ invalid\ by\ aliyun! = regionId[{0}] is invalid by aliyun! -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:63 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:61 # args: Not\ a\ valid\ message! = Not a valid message! -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:159 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:177 # args: action,result.ErrorCode,result.ErrorMessage %s\ failed,\ ErrorCode\:\ %s,\ ErrorMessage\:\ %s = {0} failed, ErrorCode: {1}, ErrorMessage: {2} -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:282 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:301 # args: 15000 Device\ Not\ Ready\ in\ %d\ milli\ seconds = Device Not Ready in {0} milli seconds -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:476 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:497 # args: result.Content.TaskStatus snapshot\ task\ status\ is\ finished\ %s = snapshot task status is finished {0} -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:472 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:493 # args: msg.getTimeout(),result.Content.Progress,result.Content.TaskStatus snapshot\ task\ cannot\ finished\ in\ %d\ milliseconds,\ now\ progress\ is\ %d,\ status\ is\ %s = snapshot task cannot finished in {0} milliseconds, now progress is {1}, status is {2} -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:877 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:898 # args: not\ supported\ HybridClient = not supported HybridClient -# at: src/main/java/org/zstack/aliyun/core/AliyunUtils.java:263 +# at: src/main/java/org/zstack/aliyun/core/AliyunUtils.java:259 # args: e.getMessage() add\ endpoint\ to\ sdk\ failed,\ due\ to\:\ %s = add endpoint to sdk failed, due to: {0} -# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:407 +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:86 +# args: +cannot\ find\ key\ /\ secret\ from\ msg = cannot find key / secret from msg + +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:410 # args: cannot\ input\ 0-length\ file\ as\ vm\ images! = cannot input 0-length file as vm images! -# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:496 +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:499 # args: e.getMessage() Permission\ denied\ for\:\ %s = Permission denied for: {0} -# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:585 +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:588 # args: e.getRequestId() Bucket\ name\ is\ already\ existed\ (maybe\ created\ by\ other\ user),\ Please\ select\ a\ different\ name\ and\ try\ again.(aliyun\ request-id\:\ %s) = Bucket name is already existed (maybe created by other user), Please select a different name and try again.(aliyun request-id: {0}) @@ -130,7 +154,7 @@ arg\ 'endpoint'\ must\ be\ set\ in\ %s\ type = arg 'endpoint' must be set in {0} # args: type.toString() not\ supported\ datacenter\ [%s]\ type\ here! = not supported datacenter [{0}] type here! -# at: src/main/java/org/zstack/aliyun/core/identityzone/AliyunPrivateIdentityZoneBase.java:252 +# at: src/main/java/org/zstack/aliyun/core/identityzone/AliyunPrivateIdentityZoneBase.java:175 # args: must\ indicate\ zoneId\ in\ private\ aliyun. = must indicate zoneId in private aliyun. @@ -182,31 +206,23 @@ panguPartitionUuid\ or\ identityZoneUuid\ must\ be\ set. = panguPartitionUuid or # args: msg.getPanguPartitionUuid(),msg.getIdentityZoneUuid() panguPartitionUuid\ [%s]\ not\ be\ matched\ with\ identityZoneUuid\ [%s] = panguPartitionUuid [{0}] not be matched with identityZoneUuid [{1}] -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3189 -# args: imageVO.getUuid() -image\ [uuid\:%s]\ has\ been\ deleted = image [uuid:{0}] has been deleted - -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3762 -# args: msg.getResourceUuid() -resource[uuid\:\ %s]\ cannot\ found = resource[uuid: {0}] cannot found - -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:674 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:669 # args: self.getUuid(),self.getName() the\ aliyun\ ebs\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = the aliyun ebs primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2829 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2888 # args: reply1.getProgress() create\ snapshot\ timeout,\ progress\ is\ %d = create snapshot timeout, progress is {0} -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:1925 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:1971 # args: msg.getVolume().getRootImageUuid() cannot\ find\ snapshot\ from\ image\:\ %s,\ maybe\ the\ image\ has\ been\ deleted = cannot find snapshot from image: {0}, maybe the image has been deleted -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2687 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2746 # args: ebs\ primarystorage\ cannot\ support\ decrease\ size\ now = ebs primarystorage cannot support decrease size now -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3089 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3134 # args: bsvo.getType() aliyun\ ebs\ primarystorage\ only\ support\ aliyun\ ebs\ bs,\ actually\ get\ type\:\ %s = aliyun ebs primarystorage only support aliyun ebs bs, actually get type: {0} @@ -246,11 +262,15 @@ ecs\ image\ existed\ remote\ and\ local,\ ecs\ image\ uuid\:\ %s,\ name\:\ %s,\ # args: msg.getName(),new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(HybridUtilsForAliyun.fmtTime(rpl.getCreateDate())) ecs\ image\ existed\ remote,\ name\:\ %s,\ created\ time\:\ %s = ecs image existed remote, name: {0}, created time: {1} -# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:181 +# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:184 # args: No\ Available\ instance\ types\ now. = No Available instance types now. -# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:304 +# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:253 +# args: regionId,data1.get("type") +This\ region\ [%s]\ cannot\ produce\ instance\ type\ [%s]\ now,\ please\ select\ another\ instance\ type\ or\ another\ region = This region [{0}] cannot produce instance type [{1}] now, please select another instance type or another region + +# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:344 # args: ecs.getUuid(),ecs.getEcsInstanceId() no\ system\ disk\ found\ for\ ecs\:\ [%s],\ ecs\ id\ is\:\ [%s] = no system disk found for ecs: [{0}], ecs id is: [{1}] @@ -294,7 +314,7 @@ bandwidth\ must\ be\ set\ while\ allocate\ publicIp = bandwidth must be set whil # args: instanceOffering\ or\ instanceType\ must\ be\ set! = instanceOffering or instanceType must be set! -# at: src/main/java/org/zstack/aliyun/ecs/EcsInstanceManagerImpl.java:384 +# at: src/main/java/org/zstack/aliyun/ecs/EcsInstanceManagerImpl.java:517 # args: rly1.getVncUrl() decode\ url\ failed\:\ %s = decode url failed: {0} @@ -302,9 +322,9 @@ decode\ url\ failed\:\ %s = decode url failed: {0} # args: image\ has\ been\ deleted! = image has been deleted! -# at: src/main/java/org/zstack/aliyun/identityzone/SelectValidIdentityZoneFlow.java:50 +# at: src/main/java/org/zstack/aliyun/identityzone/AliyunIdentityZoneBase.java:187 # args: -no\ identity\ chosen,\ may\ be\ stock\ problems = no identity chosen, may be stock problems +no\ identity\ found = no identity found # at: src/main/java/org/zstack/aliyun/image/EcsImageApiInterceptor.java:71 # args: @@ -394,79 +414,83 @@ nas\ mount\ target\ [%s]\ existed\ in\ filesystem\:\ %s = nas mount target [{0}] # args: self.getAccessGroupUuid() the\ access\ group\ attached\ is\ already\:\ %s = the access group attached is already: {0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:534 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2907 +# args: imageVO.getUuid() +image\ [uuid\:%s]\ has\ been\ deleted = image [uuid:{0}] has been deleted + +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:535 # args: vSwitchUuid EcsVSwitchVO[%s]\ is\ not\ existed,\ may\ be\ it\ has\ been\ deleted! = EcsVSwitchVO[{0}] is not existed, may be it has been deleted! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:527 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:528 # args: accessGroupUuid AliyunNasAccessGroupVO[%s]\ is\ not\ existed,\ may\ be\ it\ has\ been\ deleted! = AliyunNasAccessGroupVO[{0}] is not existed, may be it has been deleted! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:826 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:827 # args: self.getUuid() cannot\ find\ an\ available\ host\ to\ operation\ in\ primary\ storage\:\ %s = cannot find an available host to operation in primary storage: {0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:905 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:906 # args: self.getUuid(),hostUuid,rsp.error failed\ to\ ping\ aliyun\ nas\ primary\ storage[uuid\:%s]\ from\ host[uuid\:%s],because\ %s.\ disconnect\ this\ host-ps\ connection = failed to ping aliyun nas primary storage[uuid:{0}] from host[uuid:{1}],because {2}. disconnect this host-ps connection -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:1393 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:1394 # args: nas\ primary\ storage\ not\ mounted,\ please\ init\ it\ first! = nas primary storage not mounted, please init it first! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:1577 -# args: bsType -cannot\ find\ any\ BackupStorageKvmFactory\ for\ the\ type[%s] = cannot find any BackupStorageKvmFactory for the type[{0}] - -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2003 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2004 # args: vol.getUuid() cannot\ find\ host\ to\ operate\ volume\:\ [%s] = cannot find host to operate volume: [{0}] -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2240 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2241 # args: self.getUuid() cannot\ find\ and\ host\ to\ sync\ volume\ size\ in\ primary\:\ %s = cannot find and host to sync volume size in primary: {0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2267 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2268 # args: image\ [%s]\ has\ been\ deleted,\ cannot\ reinit\ root\ volume\ from\ it = image [{0}] has been deleted, cannot reinit root volume from it -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2422 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2423 # args: no\ available\ host\ could\ check\ mountPath! = no available host could check mountPath! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2649 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2653 # args: String.join(",", msg.getBackupStorageUuids()),errorCodes.getCauses().get(0).getDetails() unable\ to\ allocate\ backup\ storage\ specified\ by\ uuids\:\ %s,\ becasue\:\ %s = unable to allocate backup storage specified by uuids: {0}, becasue: {1} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2817 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2795 # args: bsvo.getType() aliyun\ nas\ primarystorage\ only\ support\ imagestore\ bs,\ actually\ get\ type\:\ %s = aliyun nas primarystorage only support imagestore bs, actually get type: {0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:158 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:161 # args: context.getInventory().getUuid(),context.getInventory().getName(),mine,e.getKey(),version,QCOW3_QEMU_IMG_VERSION,QCOW3_QEMU_IMG_VERSION unable\ to\ attach\ a\ primary\ storage\ to\ cluster.\ Kvm\ host[uuid\:%s,\ name\:%s]\ in\ cluster\ has\ qemu-img\ with\ version[%s];\ but\ the\ primary\ storage\ has\ attached\ to\ a\ cluster\ that\ has\ kvm\ host[uuid\:%s],\ which\ has\ qemu-img\ with\ version[%s].\ qemu-img\ version\ greater\ than\ %s\ is\ incompatible\ with\ versions\ less\ than\ %s,\ this\ will\ causes\ volume\ snapshot\ operation\ to\ fail.\ Please\ avoid\ attaching\ a\ primary\ storage\ to\ clusters\ that\ have\ different\ Linux\ distributions,\ in\ order\ to\ prevent\ qemu-img\ version\ mismatch = unable to attach a primary storage to cluster. Kvm host[uuid:{0}, name:{1}] in cluster has qemu-img with version[{2}]; but the primary storage has attached to a cluster that has kvm host[uuid:{3}], which has qemu-img with version[{4}]. qemu-img version greater than {5} is incompatible with versions less than {6}, this will causes volume snapshot operation to fail. Please avoid attaching a primary storage to clusters that have different Linux distributions, in order to prevent qemu-img version mismatch -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:342 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:344 # args: no\ available\ host\ could\ download\ imagecache! = no available host could download imagecache! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:69 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:1147 +# args: msg.getResourceUuid() +resource[uuid\:\ %s]\ cannot\ found = resource[uuid: {0}] cannot found + +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:75 # args: self.getUuid(),self.getName() the\ aliyun\ nas\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = the aliyun nas primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:192 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:208 # args: self.getUuid(),self.getName() the\ aliyun\ nas\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ delete\ bits\ on\ primarystorage = the aliyun nas primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for delete bits on primarystorage -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:555 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:619 # args: self.getUuid(),self.getName() the\ Aliyun\ Nas\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = the Aliyun Nas primary storage[uuid:{0}, name:{1}] has not attached to any clusters, or no hosts in the attached clusters are connected -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:856 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:936 # args: hostUuid failed\ to\ check\ mount\ path\ on\ host\:\ %s = failed to check mount path on host: {0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:943 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:1023 # args: cannot\ find\ a\ host\ to\ cleanup\ image\ cache. = cannot find a host to cleanup image cache. @@ -502,11 +526,11 @@ custom\ cidr\ [%s]\ is\ already\ existed\ in\ vbr\ [%s],\ it\ is\ overlapped\ wi # args: tuple.get(0, String.class),vRouterUuid,cidr custom\ cidr\ [%s]\ is\ already\ existed\ in\ vrouter\ [%s],\ it\ is\ overlapped\ with\ target\ cidr\ [%s],\ please\ check\ and\ delete\ it\ first. = custom cidr [{0}] is already existed in vrouter [{1}], it is overlapped with target cidr [{2}], please check and delete it first. -# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:50 +# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:51 # args: msg.getL3networkUuid() No\ Such\ Cidr\ found\ for\ l3network\:\ %s = No Such Cidr found for l3network: {0} -# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:40 +# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:42 # args: msg.getL3networkUuid() No\ Such\ VRouter\ nic\ found\ for\ l3network\:\ %s = No Such VRouter nic found for l3network: {0} @@ -562,7 +586,7 @@ OssBucket[%s]\ is\ not\ attached. = OssBucket[{0}] is not attached. # args: domain,\ key,\ secret\ must\ be\ set\ all = domain, key, secret must be set all -# at: src/main/java/org/zstack/aliyun/oss/OssBucketCascadeExtension.java:106 +# at: src/main/java/org/zstack/aliyun/oss/OssBucketCascadeExtension.java:107 # args: oss\ bucket\ is\ not\ empty! = oss bucket is not empty! @@ -642,159 +666,267 @@ More\ than\ one\ BackupStorage\ on\ the\ same\ host\ identified\ by\ hostname.\ # args: hostname,newBS More\ than\ one\ BackupStorage\ on\ the\ same\ host\ identified\ by\ hostname.\ There\ has\ been\ an\ ImageStoreBackupStorage\ [hostname\:%s]\ existing.\ The\ BackupStorage\ type\ to\ be\ added\ is\ %s.\ = More than one BackupStorage on the same host identified by hostname. There has been an ImageStoreBackupStorage [hostname:{0}] existing. The BackupStorage type to be added is {1}. -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:129 +# at: src/main/java/org/zstack/appcenter/AppCenterManagerImpl.java:486 +# args: msg.getAppUuid() +PublishAppVO[uuid\:\ %s]\ is\ not\ existed = PublishAppVO[uuid: {0}] is not existed + +# at: src/main/java/org/zstack/appcenter/AppCenterManagerImpl.java:588 +# args: +[appcenter]\ filterName\ must\ be\ appcenter\:true\ or\ appcenter\:false = [appcenter] filterName must be appcenter:true or appcenter:false + +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:127 +# args: struct.getParamName() +%s\ is\ in\ preParameters,\ but\ not\ be\ set = {0} is in preParameters, but not be set + +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:131 +# args: +%s\ need\ Number\ value,\ but\ got\ wrong\ type = {0} need Number value, but got wrong type + +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:136 +# args: +%s\ need\ Boolean\ value,\ but\ got\ wrong\ type = {0} need Boolean value, but got wrong type + +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:141 +# args: +%s\ need\ String\ value,\ but\ got\ wrong\ type = {0} need String value, but got wrong type + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:389 +# args: msg.getBuildSystemUuid() +cannot\ find\ build\ system\ [%s] = cannot find build system [{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:339 +# args: msg.getBuildSystemUuid(),msg.getZoneUuid() +build\ system[uuid\:\ %s]\ has\ been\ attached\ to\ zone[uuid\:\ %s] = build system[uuid: {0}] has been attached to zone[uuid: {1}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:396 +# args: msg.getBuildSystemUuid(),msg.getZoneUuid() +build\ system[uuid\:\ %s]\ has\ not\ been\ attached\ to\ zone[uuid\:\ %s] = build system[uuid: {0}] has not been attached to zone[uuid: {1}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:620 +# args: appUuid +cannot\ find\ build\ application\:\ [%s] = cannot find build application: [{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:989 +# args: +imageStore\ is\ not\ Enabled = imageStore is not Enabled + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:993 +# args: +imageStore\ is\ not\ Connected = imageStore is not Connected + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:1147 +# args: p.getDefaultValue() +cannot\ find\ imageUuid\ for\ image[%s] = cannot find imageUuid for image[{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:1159 +# args: msg.getUuid() +cannot\ find\ build-app[uuid\:\ %s],\ or\ it\ was\ in\ Deleting\ status = cannot find build-app[uuid: {0}], or it was in Deleting status + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:50 +# args: msg.getUuid() +build-app[%s]\ is\ exported\ or\ is\ exporting,\ please\ delete\ it\ first = build-app[{0}] is exported or is exporting, please delete it first + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:63 +# args: build.getUuid(),build.getName(),build.getHostname(),build.getUrl() +another\ build\ system[uuid\:\ %s,\ name\:\ %s]\ in\ this\ host[%s]\ used\ the\ url[%s] = another build system[uuid: {0}, name: {1}] in this host[{2}] used the url[{3}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:74 +# args: msg.getDataPath() +dataPath\ must\ start\ with\ '/',\ actually\ got\ [%s] = dataPath must start with '/', actually got [{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:88 +# args: +both\ backupStorageUuid\ and\ hostname\ are\ null = both backupStorageUuid and hostname are null + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:95 +# args: msg.getHostname() +cannot\ find\ imageStore\ which\ hostname\ is\ \:%s = cannot find imageStore which hostname is :{0} + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:98 +# args: msg.getHostname() +find\ more\ than\ one\ imageStore\ which\ hostname\ is\:\ %s,\ please\ use\ backupStorageUuid\ instead = find more than one imageStore which hostname is: {0}, please use backupStorageUuid instead + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:102 +# args: +both\ backupStorageUuid\ and\ hostname\ are\ set,\ but\ they\ are\ not\ the\ same\ host = both backupStorageUuid and hostname are set, but they are not the same host + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:116 +# args: +buildAppUuid\ and\ exportId\ cannot\ both\ be\ null = buildAppUuid and exportId cannot both be null + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:120 +# args: +buildAppUuid\ and\ buildSystemUuid\ cannot\ both\ be\ null = buildAppUuid and buildSystemUuid cannot both be null + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:126 +# args: +no\ such\ exportId\ in\ build\ export\ history = no such exportId in build export history + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:130 +# args: +both\ exportId\ and\ buildAppUuid\ are\ set\ but\ they\ are\ not\ equal = both exportId and buildAppUuid are set but they are not equal + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:108 +# args: self.getStatus() +unable\ to\ do\ the\ operation\ because\ the\ build\ system\ is\ in\ status\ of\ %s = unable to do the operation because the build system is in status of {0} + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:121 +# args: msg.getBuildAppUuid() +cannot\ find\ the\ build\ app\ by\ uuid[%s] = cannot find the build app by uuid[{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:126 +# args: status.toString() +build\ app\ is\ in\ %s\ status,\ which\ can\ not\ support\ the\ current\ operation. = build app is in {0} status, which can not support the current operation. + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:156 +# args: buildUrl(path),rsp.error +rest\ call\ %s\ failed,\ because\:\ %s = rest call {0} failed, because: {1} + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:353 +# args: +build\ application\ is\ disabled\ because\ build\ system\ is\ in\ 'Disabled'\ state = build application is disabled because build system is in 'Disabled' state + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:506 +# args: meta.getAppId(),meta.getVersion().getVersion() +create\ BuildApp\ failed,\ because\ appId[%s\:\ %s]\ is\ duplicated\ by\ another\ BuildApp = create BuildApp failed, because appId[{0}: {1}] is duplicated by another BuildApp + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:659 +# args: buildUrl(CONNECT_BUILDSYSTEM_PATH),errorCode +unable\ to\ connect\ to\ localstorage\ build\ system[url\:%s],\ because\ %s = unable to connect to localstorage build system[url:{0}], because {1} + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:762 +# args: struct.getAppId(),struct.getVersion().getVersion() +add\ BuildApp\ failed,\ because\ appId[%s\:%s]\ is\ duplicated\ by\ another\ BuildApp = add BuildApp failed, because appId[{0}:{1}] is duplicated by another BuildApp + +# at: src/main/java/org/zstack/appcenter/utils/AppCenterUtils.java:48 +# args: file +cannot\ find\ raw-template\ json\ file\ at\:\ %s = cannot find raw-template json file at: {0} + +# at: src/main/java/org/zstack/appcenter/utils/AppCenterUtils.java:61 +# args: e +Unable\ to\ create\ json\ template = Unable to create json template + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java:108 +# args: l2NetworkVO.getUuid() +there\ is\ no\ available\ nicType\ on\ L2\ network\ [%s] = there is no available nicType on L2 network [{0}] + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:136 # args: self.getUuid(),getSelf().getStatus(),msg.getPath() appliance\ vm[uuid\:%s]\ is\ in\ status\ of\ %s\ that\ cannot\ make\ http\ call\ to\ %s = appliance vm[uuid:{0}] is in status of {1} that cannot make http call to {2} -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:413 +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:430 # args: getSelf().getUuid() appliance\ vm\ %s\ stopped = appliance vm {0} stopped -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:482 -# args: getSelf().getUuid() -appliance\ vm\ %s\ destroyed = appliance vm {0} destroyed - -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:543 +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:709 # args: getSelf().getUuid() appliance\ vm\ %s\ reboot = appliance vm {0} reboot -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:553 +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:719 # args: getSelf().getUuid() appliance\ vm\ %s\ reboot\ failed = appliance vm {0} reboot failed -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:606 +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:781 # args: getSelf().getUuid() appliance\ vm\ %s\ start\ failed = appliance vm {0} start failed -# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:116 +# at: src/main/java/org/zstack/appliancevm/ApplianceVmKvmBootstrapFlow.java:64 +# args: rsp.getError() +set\ appliance\ bootstrapinfo\ error,\ because\:%s = set appliance bootstrapinfo error, because:{0} + +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:120 # args: msg.getUuid(),uuid listener[uuid\:%s]\ are\ being\ used\ by\ the\ autoScalingVmTemplate[%s]\ and\ cannot\ be\ deleted = listener[uuid:{0}] are being used by the autoScalingVmTemplate[{1}] and cannot be deleted -# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:148 +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:131 +# args: msg.getInstanceUuid(),msg.getGroupUuid() +The\ instance[%s]\ does\ not\ exist\ in\ the\ scaling\ group[%s] = The instance[{0}] does not exist in the scaling group[{1}] + +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:163 # args: msg.getAlarmUuid(),ruleVO.getScalingGroupUuid() alarm[uuid\:%s]\ are\ being\ used\ by\ the\ autoScalingGroup[%s]\ which\ cannot\ be\ deleted = alarm[uuid:{0}] are being used by the autoScalingGroup[{1}] which cannot be deleted -# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:158 +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:173 # args: msg.getUuid() rule[%s]\ state\ is\ Disabled = rule[{0}] state is Disabled -# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:314 +# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:386 # args: l3Uuids,uuid invalid\ l3\ network\ uuids[%s]\ for\ listener\ that\ belongs\ lb[%s],\ all\ the\ networks\ must\ be\ attached\ the\ LB\ service\ and\ be\ attached\ with\ the\ same\ vRouter\ with\ LB = invalid l3 network uuids[{0}] for listener that belongs lb[{1}], all the networks must be attached the LB service and be attached with the same vRouter with LB -# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:626 +# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:744 # args: msg.getTemplateUuid(),JSONObjectUtil.toJsonString(errors) detach\ autoScalingTemplate[%s]\ from\ AutoScalingGroup\ failed,\ errors\ are\ %s = detach autoScalingTemplate[{0}] from AutoScalingGroup failed, errors are {1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:933 -# args: -rootDiskOfferingUuid\ cannot\ be\ null\ when\ image\ mediaType\ is\ ISO = rootDiskOfferingUuid cannot be null when image mediaType is ISO - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:913 -# args: instanceOfferingVO.getUuid() -instance\ offering[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = instance offering[uuid:{0}] is Disabled, can't create vm from it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:916 -# args: instanceOfferingVO.getUuid(),instanceOfferingVO.getType() -instance\ offering[uuid\:%s,\ type\:%s]\ is\ not\ UserVm\ type,\ can't\ create\ vm\ from\ it = instance offering[uuid:{0}, type:{1}] is not UserVm type, can't create vm from it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:924 -# args: imageVO.getUuid() -image[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = image[uuid:{0}] is Disabled, can't create vm from it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:927 -# args: imageVO.getUuid() -image[uuid\:%s]\ is\ not\ ready\ yet,\ can't\ create\ vm\ from\ it = image[uuid:{0}] is not ready yet, can't create vm from it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:930 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:890 # args: imageVO.getUuid(),imageVO.getMediaType() image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ and\ ISO\ can\ be\ used\ to\ create\ vm = image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate and ISO can be used to create vm -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:937 -# args: imageVO.getUuid() -image[uuid\:%s]\ is\ system\ image,\ can't\ be\ used\ to\ create\ user\ vm = image[uuid:{0}] is system image, can't be used to create user vm - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:949 -# args: diskOfferingVO.getUuid() -disk\ offerings[uuids\:%s]\ are\ Disabled,\ can\ not\ create\ vm\ from\ it = disk offerings[uuids:{0}] are Disabled, can not create vm from it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:963 -# args: l3Uuid -l3Network[uuid\:%s]\ is\ Disabled,\ can\ not\ create\ vm\ on\ it = l3Network[uuid:{0}] is Disabled, can not create vm on it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:966 -# args: l3Uuid -l3Network[uuid\:%s]\ is\ system\ network,\ can\ not\ create\ user\ vm\ on\ it = l3Network[uuid:{0}] is system network, can not create user vm on it - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:970 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:893 # args: -there\ are\ more\ than\ one\ L3\ network\ specified\ in\ l3NetworkUuids,\ but\ defaultL3NetworkUuid\ is\ null = there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null +rootDiskOfferingUuid\ cannot\ be\ null\ when\ image\ mediaType\ is\ ISO = rootDiskOfferingUuid cannot be null when image mediaType is ISO -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:409 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:367 # args: Only\ one\ scaling\ activity\ can\ be\ executed\ in\ the\ same\ scaling\ group\ at\ the\ same\ time. = Only one scaling activity can be executed in the same scaling group at the same time. -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1330 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1317 # args: The\ number\ of\ instances\ exceeds\ the\ limit = The number of instances exceeds the limit -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:637 -# args: msg.getAutoScalingGroupUuid(),JSONObjectUtil.toJsonString(errors) -autoScalingGroup[%s]\ create\ vms\ failed\ completely,\ errors\ are\ %s = autoScalingGroup[{0}] create vms failed completely, errors are {1} - -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:685 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:645 # args: loadBalancerListenerUuidListStr add\ vm\ nic\ to\ loadBalancer\ failed,\ No\ loadBalancer[uuids\=%s]\ can\ be\ found. = add vm nic to loadBalancer failed, No loadBalancer[uuids={0}] can be found. -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:724 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:684 # args: msg.getAutoScalingGroupUuid(),JSONObjectUtil.toJsonString(addVmNicToLoadBalancerErrorCodes) autoScalingGroup[%s]\ add\ newly\ created\ vm\ to\ loadBalancer\ failed\ completely,\ errors\ are\ %s = autoScalingGroup[{0}] add newly created vm to loadBalancer failed completely, errors are {1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:759 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:719 # args: securityGroupUuid add\ vm\ nic\ to\ securityGroup\ failed,\ No\ securityGroup[uuid\=%s]\ can\ be\ found. = add vm nic to securityGroup failed, No securityGroup[uuid={0}] can be found. -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:795 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:755 # args: msg.getAutoScalingGroupUuid(),JSONObjectUtil.toJsonString(addVmNicToSecurityGroupErrorCodes) autoScalingGroup[%s]\ add\ newly\ created\ vm\ to\ securityGroup\ failed\ completely,\ errors\ are\ %s = autoScalingGroup[{0}] add newly created vm to securityGroup failed completely, errors are {1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:905 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:865 # args: templateGroupRefVO.getTemplateUuid() A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:AutoScalingVmTemplateVO]\ not\ found = A resource can not be found, details: resource[uuid:{0}, type:AutoScalingVmTemplateVO] not found -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:910 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:870 # args: vmTemplateVO.getVmInstanceOfferingUuid() A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:InstanceOfferingVO]\ not\ found = A resource can not be found, details: resource[uuid:{0}, type:InstanceOfferingVO] not found -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:921 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:881 # args: vmTemplateVO.getImageUuid() A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:ImageVO]\ not\ found = A resource can not be found, details: resource[uuid:{0}, type:ImageVO] not found -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:945 -# args: diskOfferingVO.getUuid() +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:905 +# args: diskOffering A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:DiskOfferingVO]\ not\ found = A resource can not be found, details: resource[uuid:{0}, type:DiskOfferingVO] not found -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:958 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:918 # args: l3Uuid A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:L3NetworkVO]\ not\ found = A resource can not be found, details: resource[uuid:{0}, type:L3NetworkVO] not found -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:974 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:934 # args: vmTemplateVO.getDefaultL3NetworkUuid(),l3Uuids defaultL3NetworkUuid[uuid\:%s]\ is\ not\ in\ l3NetworkUuids\ %s = defaultL3NetworkUuid[uuid:{0}] is not in l3NetworkUuids {1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1047 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1018 # args: self.getUuid(),AutoScalingGroupState.Enabled.toString() the\ auto\ scaling\ group[%s]\ state\ error,\ expected\:\ %s\ state = the auto scaling group[{0}] state error, expected: {1} state -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1084 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1055 # args: self.getUuid() The\ autoScalingGroup[%s]\ not\ attach\ any\ vm\ template = The autoScalingGroup[{0}] not attach any vm template -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1138 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1123 # args: self.getUuid(),vmInstanceUuids,JSONObjectUtil.toJsonString(errors) autoScalingGroup[%s]\ destroy\ vms[%s]\ failed\ completely,\ errors\ are\ %s = autoScalingGroup[{0}] destroy vms[{1}] failed completely, errors are {2} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1343 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1330 # args: Cannot\ find\ deleted\ target\ instance\ list = Cannot find deleted target instance list @@ -802,135 +934,131 @@ Cannot\ find\ deleted\ target\ instance\ list = Cannot find deleted target insta # args: need\ skip\ autoScalingGroup\ activity = need skip autoScalingGroup activity -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1820 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1835 # args: ruleUuid,JSONObjectUtil.toJsonString(errors) delete\ autoScalingRule[%s]\ triggers\ failed,\ errors\ are\ %s = delete autoScalingRule[{0}] triggers failed, errors are {1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:2437 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:2452 # args: removalPolicy.toString() Unsupported\ RemovalPolicy[%s]\ type = Unsupported RemovalPolicy[{0}] type -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:63 -# args: address -IPMI\ Address\ %s\ is\ not\ valid = IPMI Address {0} is not valid +# at: src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java:183 +# args: triggerVO.getUuid(),triggerVO.getState() +AutoScalingRuleSchedulerJobTriggerVO[uuid\:%s]\ is\ %s,\ state\ change\ is\ not\ allowed = AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}] is {1}, state change is not allowed -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:69 -# args: -Failed\ to\ reach\ the\ bare-metal\ chassis,\ please\ make\ sure\:\ 1.\ the\ IPMI\ connection\ is\ active;\ 2.\ the\ IPMI\ Address,\ Port,\ Username\ and\ Password\ are\ correct;\ 3.\ IPMI\ Over\ LAN\ is\ enabled\ in\ BIOS. = Failed to reach the bare-metal chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS. +# at: src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java:192 +# args: ruleUuid +AutoScalingRuleSchedulerJobTriggerVO[uuid\:%s]\ is\ be\ in\ cooldownDate = AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}] is be in cooldownDate -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:84 -# args: address,port -Baremetal\ Chassis\ of\ IPMI\ address\ %s\ and\ IPMI\ port\ %d\ has\ already\ been\ created. = Baremetal Chassis of IPMI address {0} and IPMI port {1} has already been created. +# at: src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java:250 +# args: ruleUuid,AutoScalingRuleState.Disabled.toString() +AutoScalingRuleVO[uuid\:%s]\ is\ %s,\ state\ change\ is\ not\ allowed = AutoScalingRuleVO[uuid:{0}] is {1}, state change is not allowed -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:95 -# args: msg.getClusterUuid() -Cluster[uuid\:%s]\ does\ not\ exists. = Cluster[uuid:{0}] does not exists. +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:64 +# args: +Failed\ to\ reach\ the\ bare-metal\ chassis,\ please\ make\ sure\:\ 1.\ the\ IPMI\ connection\ is\ active;\ 2.\ the\ IPMI\ Address,\ Port,\ Username\ and\ Password\ are\ correct;\ 3.\ IPMI\ Over\ LAN\ is\ enabled\ in\ BIOS. = Failed to reach the bare-metal chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS. -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:102 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:111 # args: msg.getClusterUuid() Cluster[uuid\:%s]\ is\ not\ a\ baremetal\ cluster. = Cluster[uuid:{0}] is not a baremetal cluster. -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:108 -# args: msg.getClusterUuid() -Cluster[uuid\:%s]\ is\ not\ Enabled. = Cluster[uuid:{0}] is not Enabled. - -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:146 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:155 # args: address,port IPMI\ Address\ and\ Port\ %s\:%d\ already\ exists. = IPMI Address and Port {0}:{1} already exists. -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:211 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:220 # args: clusterUuid no\ usable\ baremetal\ pxeserver\ attached\ to\ cluster[uuid\:%s] = no usable baremetal pxeserver attached to cluster[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:153 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:175 # args: chassis.getUuid(),chassis.getPxeServerUuid(),cmd.content baremetal\ chassis[uuid\:%s]\ is\ supposed\ to\ using\ pxeserver[uuid\:%s],\ but\ it\ was\ pxeserver[uuid\:%s]\ that\ actually\ handled\ the\ DHCP\ request = baremetal chassis[uuid:{0}] is supposed to using pxeserver[uuid:{1}], but it was pxeserver[uuid:{2}] that actually handled the DHCP request -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:639 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:671 # args: msg.getUuid() failed\ to\ delete\ baremetal\ chassis\ %s = failed to delete baremetal chassis {0} -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:706 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:737 # args: bmc.getUuid() Failed\ to\ remotely\ power\ on\ baremetal\ chassis[uuid\:%s] = Failed to remotely power on baremetal chassis[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:722 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:753 # args: bmc.getUuid() Failed\ to\ remotely\ power\ reset\ baremetal\ chassis[uuid\:%s] = Failed to remotely power reset baremetal chassis[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:733 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:764 # args: bmc.getUuid() Failed\ to\ remotely\ pxe\ boot\ chassis[uuid\:%s] = Failed to remotely pxe boot chassis[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:901 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:924 # args: bmc.getUuid() failed\ to\ connect\ to\ chassis\ [uuid\:%s],\ please\ check\ ipmi\ connection. = failed to connect to chassis [uuid:{0}], please check ipmi connection. -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:987 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:1010 # args: e.getMessage() fail\ to\ load\ chassis\ info\ from\ file,\ because\:\ %s = fail to load chassis info from file, because: {0} -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:66 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:59 # args: msg.getChassisUuid() Baremetal\ chassis[uuid\:%s]\ does\ not\ exist = Baremetal chassis[uuid:{0}] does not exist -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:72 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:65 # args: chassis.getUuid() Baremetal\ chassis[uuid\:%s]\ is\ not\ Enabled\ or\ Available,\ please\ choose\ another\ one. = Baremetal chassis[uuid:{0}] is not Enabled or Available, please choose another one. -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:78 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:71 # args: chassis.getUuid() no\ corresponding\ pxeserver,\ please\ inspect\ baremetal\ chassis[uuid\:%s]\ again = no corresponding pxeserver, please inspect baremetal chassis[uuid:{0}] again -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:91 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:84 # args: chassis.getUuid() No\ hardware\ info\ found\ for\ baremetal\ chassis[uuid\:%s],\ please\ choose\ another\ one. = No hardware info found for baremetal chassis[uuid:{0}], please choose another one. -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:102 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:95 # args: chassis.getPxeServerUuid() baremetal\ pxeserver[uuid\:%s]\ is\ neither\ Enabled\ nor\ Connected,\ please\ check = baremetal pxeserver[uuid:{0}] is neither Enabled nor Connected, please check -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:119 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:112 # args: mac Mac\ address\ %s\ is\ invalid.\ It\ should\ be\ like\ 6c\:b3\:11\:1b\:0b\:1e = Mac address {0} is invalid. It should be like 6c:b3:11:1b:0b:1e -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:125 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:118 # args: chassis.getUuid(),mac Baremetal\ chassis[uuid\:%s]\ doesn't\ have\ nic\ with\ mac\ address\ %s = Baremetal chassis[uuid:{0}] doesn't have nic with mac address {1} -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:143 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:136 # args: duplicated\ bm\ bonding\ uuid\ detacted = duplicated bm bonding uuid detacted -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:147 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:140 # args: Baremetal\ Bonding\ does\ not\ exist = Baremetal Bonding does not exist -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:155 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:148 # args: duplicated\ l3\ network\ uuid\ detacted = duplicated l3 network uuid detacted -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:159 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:152 # args: the\ selected\ l3\ network\ doesn't\ exist = the selected l3 network doesn't exist -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:172 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:165 # args: chassis.getUuid() the\ selected\ l3\ network\ cannot\ be\ assigned\ to\ chassis[uuid\:%s] = the selected l3 network cannot be assigned to chassis[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:184 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:177 # args: only\ iso\ image\ is\ supported\ in\ zstack\ baremetal\ service = only iso image is supported in zstack baremetal service -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:193 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:186 # args: only\ ImageStoreBackupStorage\ is\ supported\ in\ zstack\ baremetal\ service = only ImageStoreBackupStorage is supported in zstack baremetal service -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:207 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:200 # args: cannot\ recover\ baremetal\ instance\ that's\ not\ in\ Destroyed\ state = cannot recover baremetal instance that's not in Destroyed state -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:219 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:212 # args: cannot\ expunge\ baremetal\ instance\ that's\ not\ in\ Destroyed\ state = cannot expunge baremetal instance that's not in Destroyed state @@ -990,4251 +1118,7855 @@ cannot\ delete\ predefined\ preconfiguration\ templates = cannot delete predefin # args: cannot\ change\ state\ of\ predefined\ preconfiguration\ templates = cannot change state of predefined preconfiguration templates -# at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationManagerImpl.java:65 +# at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationManagerImpl.java:66 # args: msg.getTemplateUuid() cannot\ find\ PreconfigurationTemplateVO[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find PreconfigurationTemplateVO[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:44 -# args: msg.getClass().getSimpleName() -%s\ can\ only\ be\ called\ by\ admin\ account = {0} can only be called by admin account - -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:74 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:69 # args: netmask PXE\ Server\ DHCP\ Range\ Netmask\ %s\ is\ invalid. = PXE Server DHCP Range Netmask {0} is invalid. -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:80 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:75 # args: begin,end PXE\ Server\ DHCP\ Range\ Start\ %s\ and\ Range\ Stop\ %s\ do\ not\ belong\ to\ the\ same\ subnet. = PXE Server DHCP Range Start {0} and Range Stop {1} do not belong to the same subnet. -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:88 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:92 # args: msg.getHostname() PXE\ Server\ with\ hostname\ %s\ already\ exists. = PXE Server with hostname {0} already exists. -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:95 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:103 +# args: msg.getHostname() +there\ is\ already\ a\ baremetal2\ gateway\ with\ management\ ip\ %s,\ do\ not\ use\ it\ to\ create\ baremetal\ pxe\ server = there is already a baremetal2 gateway with management ip {0}, do not use it to create baremetal pxe server + +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:110 # args: storagePath\ should\ be\ an\ absolute\ path = storagePath should be an absolute path -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:113 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:126 # args: msg.getHostname() failed\ to\ connect\ to\ %s,\ please\ check\ network\ connection\ between\ zstack\ management\ node\ and\ baremetal\ pxeserver = failed to connect to {0}, please check network connection between zstack management node and baremetal pxeserver -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:127 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:136 # args: msg.getHostname() no\ local\ repo\ found\ under\ /opt/zstack-dvd\ of\ %s,\ please\ download\ zstack\ iso\ and\ create\ local\ repo\ first = no local repo found under /opt/zstack-dvd of {0}, please download zstack iso and create local repo first -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:141 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:146 # args: msg.getDhcpInterface() PXE\ Server\ DHCP\ Interface\ %s\ does\ not\ exists,\ or\ it\ does\ not\ have\ an\ IP\ address. = PXE Server DHCP Interface {0} does not exists, or it does not have an IP address. -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:150 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:155 # args: msg.getDhcpRangeBegin(),msg.getDhcpRangeEnd(),msg.getDhcpInterface() %s\ ~\ %s\ cannot\ connect\ to\ dhcp\ interface\ %s = {0} ~ {1} cannot connect to dhcp interface {2} -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:187 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:192 # args: msg.getClusterUuid(),msg.getPxeServerUuid() cluster[uuid\:%s]\ and\ pxeserver[uuid\:%s]\ don't\ belong\ to\ one\ zone = cluster[uuid:{0}] and pxeserver[uuid:{1}] don't belong to one zone -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:196 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:201 # args: msg.getClusterUuid() cluster[uuid\:%s]\ is\ not\ baremetal\ cluster = cluster[uuid:{0}] is not baremetal cluster -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:207 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:212 # args: msg.getPxeServerUuid(),msg.getClusterUuid() baremetal\ pxeserver[uuid\:%s]\ already\ attached\ to\ cluster[uuid\:%s] = baremetal pxeserver[uuid:{0}] already attached to cluster[uuid:{1}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:233 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:238 # args: msg.getPxeServerUuid(),msg.getClusterUuid(),ip,begin,end baremetal\ pxeserver[uuid\:%s]\ is\ not\ compatible\ with\ baremetal\ instances\ in\ cluster[uuid\:%s],\ existing\ nic\ ip\ %s\ is\ out\ of\ pxeserver\ dhcp\ range\ %s\ ~\ %s. = baremetal pxeserver[uuid:{0}] is not compatible with baremetal instances in cluster[uuid:{1}], existing nic ip {2} is out of pxeserver dhcp range {3} ~ {4}. -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:250 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:255 # args: msg.getPxeServerUuid(),msg.getClusterUuid() baremetal\ pxeserver[uuid\:\ %s]\ not\ attached\ to\ cluster[uuid\:\ %s] = baremetal pxeserver[uuid: {0}] not attached to cluster[uuid: {1}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:286 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:295 # args: self.getUuid() failed\ to\ init\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = failed to init configs on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:423 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:432 # args: self.getUuid() failed\ to\ create\ bm\ instance\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = failed to create bm instance configs on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:454 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:463 # args: self.getUuid() failed\ to\ delete\ bm\ instance\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = failed to delete bm instance configs on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:485 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:494 # args: self.getUuid() failed\ to\ create\ bm\ instance\ novnc\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = failed to create bm instance novnc proxy on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:516 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:525 # args: self.getUuid() failed\ to\ delete\ bm\ instance\ novnc\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = failed to delete bm instance novnc proxy on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:549 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:558 # args: self.getUuid() failed\ to\ create\ bm\ instance\ nginx\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = failed to create bm instance nginx proxy on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:580 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:589 # args: self.getUuid() failed\ to\ delete\ bm\ instance\ nginx\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = failed to delete bm instance nginx proxy on baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:611 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:620 # args: self.getUuid() failed\ to\ start\ baremetal\ pxeserver[uuid\:%s] = failed to start baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:644 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:653 # args: self.getUuid() failed\ to\ stop\ baremetal\ pxeserver[uuid\:%s] = failed to stop baremetal pxeserver[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:959 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:968 # args: msg.getChassisUuid(),self.getUuid() failed\ to\ create\ dhcp\ config\ of\ chassis[uuid\:%s]\ on\ pxeserver[uuid\:%s] = failed to create dhcp config of chassis[uuid:{0}] on pxeserver[uuid:{1}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:988 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:997 # args: msg.getChassisUuid(),self.getUuid() failed\ to\ delete\ dhcp\ config\ of\ chassis[uuid\:%s]\ on\ pxeserver[uuid\:%s] = failed to delete dhcp config of chassis[uuid:{0}] on pxeserver[uuid:{1}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1046 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1055 # args: self.getUuid(),ret.uuid the\ uuid\ of\ baremtal\ pxeserver\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = the uuid of baremtal pxeserver agent changed[expected:{0}, actual:{1}], it's most likely the agent was manually restarted. Issue a reconnect to sync the status -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1229 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1270 # args: url,rsp.error unable\ to\ connect\ to\ baremetal\ pxeserver[url\:%s],\ because\ %s = unable to connect to baremetal pxeserver[url:{0}], because {1} -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1320 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1362 # args: cache.getImageUuid() failed\ to\ mount\ baremetal\ cache\ of\ image[uuid\:%s] = failed to mount baremetal cache of image[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1430 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1467 # args: msg.getImageUuid() no\ enough\ space\ left\ in\ baremetal\ image\ cache\ for\ image[uuid\:%s] = no enough space left in baremetal image cache for image[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1526 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1563 # args: unsupported\ backup\ storage\ type\ for\ baremetal = unsupported backup storage type for baremetal -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:104 -# args: -the\ start\ date\ must\ be\ greater\ than\ the\ end\ date = the start date must be greater than the end date - -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:108 -# args: -resourceType\ and\ resourceUuid\ cannot\ be\ empty\ at\ the\ same\ time = resourceType and resourceUuid cannot be empty at the same time +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:59 +# args: msg.getName() +bond\ name\ %s\ has\ been\ existed = bond name {0} has been existed -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:226 -# args: -the\ minimal\ resource\ unit\ is\ megabyte,\ cannot\ be\ byte = the minimal resource unit is megabyte, cannot be byte +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:71 +# args: mac +nic\ with\ mac\:%s\ has\ been\ bonded = nic with mac:{0} has been bonded -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:234 -# args: -price\ must\ be\ 0\ and\ 9999.99 = price must be 0 and 9999.99 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:98 +# args: chassisUuid +cannot\ find\ the\ cluster\ of\ baremetal2\ chassis[uuid\:%s],\ maybe\ it\ doesn't\ exist = cannot find the cluster of baremetal2 chassis[uuid:{0}], maybe it doesn't exist -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:241 -# args: -gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ empty = gpu price must be bound to gpu uuid empty +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:107 +# args: clusterUuid +there\ is\ no\ baremetal2\ gateway\ found\ in\ cluster[uuid\:%s] = there is no baremetal2 gateway found in cluster[uuid:{0}] -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:248 -# args: price.getSystemTags() -gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ %s = gpu price must be bound to gpu uuid {0} +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:116 +# args: clusterUuid +there\ is\ no\ usable\ baremetal2\ gateway\ found\ in\ cluster[uuid\:%s] = there is no usable baremetal2 gateway found in cluster[uuid:{0}] -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:208 -# args: resourceName -resourceName[%s]\ is\ invalid = resourceName[{0}] is invalid +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:124 +# args: clusterUuid +there\ is\ no\ baremetal2\ provision\ network\ found\ in\ cluster[uuid\:%s] = there is no baremetal2 provision network found in cluster[uuid:{0}] -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:260 -# args: msg.getAccountUuid() -The\ account[uuid\=%s]\ has\ attach\ price\ table = The account[uuid={0}] has attach price table +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:132 +# args: provisionNetworkUuid +baremetal2\ provision\ network[uuid\:%s]\ is\ not\ usable,\ make\ sure\ it's\ Enabled = baremetal2 provision network[uuid:{0}] is not usable, make sure it's Enabled -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:266 -# args: msg.getUuid() -This\ priceTable[uuid\=%s]\ is\ not\ allowed\ to\ delete = This priceTable[uuid={0}] is not allowed to delete +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:78 +# args: hardwareInfo +wrong\ baremetal2\ chassis\ hardware\ info\ format\:\ %s = wrong baremetal2 chassis hardware info format: {0} -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:280 -# args: -accountUuid/tableUuid\ only\ one\ of\ them\ is\ allowed\ to\ be\ set = accountUuid/tableUuid only one of them is allowed to be set +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:87 +# args: info.architecture,clusterArchitecture +the\ cpu\ architecture\ of\ the\ chassis[arch\:%s]\ and\ the\ cluster[arch\:%s]\ don't\ match = the cpu architecture of the chassis[arch:{0}] and the cluster[arch:{1}] don't match -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:286 -# args: -endDateInLong\ is\ not\ allowed\ to\ be\ negative = endDateInLong is not allowed to be negative +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:97 +# args: BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE +only\ baremetal2\ chassis\ with\ boot\ mode\ %s\ is\ supported = only baremetal2 chassis with boot mode {0} is supported -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:290 -# args: -endDateInLong\ and\ setEndDateInLongBaseOnCurrentTime\ are\ not\ allowed\ to\ set\ at\ the\ same\ time = endDateInLong and setEndDateInLongBaseOnCurrentTime are not allowed to set at the same time +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:108 +# args: hardwareInfo +wrong\ baremetal2\ chassis\ nic\ hardware\ info\ format\:\ %s = wrong baremetal2 chassis nic hardware info format: {0} -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:303 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:114 # args: -endDateInLong\ is\ set,\ no\ modification\ allowed = endDateInLong is set, no modification allowed +there\ must\ be\ one\ and\ only\ one\ provision\ nic\ in\ a\ baremetal2\ chassis = there must be one and only one provision nic in a baremetal2 chassis -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:311 -# args: -endDateInLong\ cannot\ be\ earlier\ than\ dateInLong = endDateInLong cannot be earlier than dateInLong +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:124 +# args: hardwareInfo +wrong\ baremetal2\ chassis\ disk\ hardware\ info\ format\:\ %s = wrong baremetal2 chassis disk hardware info format: {0} -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:254 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:167 # args: -priceKeyName\ is\ null = priceKeyName is null +other\ chassis\ has\ nics\ with\ the\ same\ mac\ address,\ which\ is\ impossible = other chassis has nics with the same mac address, which is impossible -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:879 -# args: currentPriceVO.getDateInLong() -dateInLong\ is\ less\ than\ %s = dateInLong is less than {0} +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java:372 +# args: msg.getClusterUuid() +BareMetal2\ Chassis[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled = BareMetal2 Chassis[uuid:{0}] doesn't exist or is disabled -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1281 -# args: resourceUuid -Already\ have\ one\ userdata\ systemTag\ for\ instanceOffering[uuid\:\ %s]. = Already have one userdata systemTag for instanceOffering[uuid: {0}]. +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java:438 +# args: msg.getRequiredClusterUuids() +no\ available\ baremetal2\ chassis\ found\ in\ baremetal2\ clusters[uuids\:%s] = no available baremetal2 chassis found in baremetal2 clusters[uuids:{0}] -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1346 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java:430 # args: -Shouldn't\ be\ more\ than\ one\ systemTag\ for\ one\ instanceOffering. = Shouldn't be more than one systemTag for one instanceOffering. - -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1323 -# args: resourceUuid -Already\ have\ one\ userdata\ systemTag\ for\ diskOffering[uuid\:\ %s]. = Already have one userdata systemTag for diskOffering[uuid: {0}]. +no\ available\ baremetal2\ chassis\ found = no available baremetal2 chassis found -# at: src/main/java/org/zstack/billing/ResourceSpendingHelper.java:50 -# args: resourceType -unsupported\ billing\ resource\ type\ [%s] = unsupported billing resource type [{0}] +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:82 +# args: address +IPMI\ Address\ %s\ is\ not\ valid = IPMI Address {0} is not valid -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:63 -# args: msg.getUuid() -cannot\ find\ such\ ResourceStackVO\ by\ uuid\ [%s] = cannot find such ResourceStackVO by uuid [{0}] +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:121 +# args: address,port +Baremetal\ Chassis\ of\ IPMI\ address\ %s\ and\ IPMI\ port\ %d\ has\ already\ been\ created. = Baremetal Chassis of IPMI address {0} and IPMI port {1} has already been created. -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:67 -# args: validStatus -restart\ resource\ stack\ only\ support\ %s\ status! = restart resource stack only support {0} status! +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:111 +# args: address,port +BareMetal2\ Chassis\ of\ IPMI\ address\ %s\ and\ IPMI\ port\ %d\ has\ already\ been\ created. = BareMetal2 Chassis of IPMI address {0} and IPMI port {1} has already been created. -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:175 -# args: -templateContent\ and\ uuid\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = templateContent and uuid mustn't both be empty or both be set! +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:133 +# args: msg.getClusterUuid() +Cluster[uuid\:%s]\ does\ not\ exists. = Cluster[uuid:{0}] does not exists. -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:98 -# args: validStatus -expect\ %s\ status! = expect {0} status! +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:146 +# args: msg.getClusterUuid() +Cluster[uuid\:%s]\ is\ not\ Enabled. = Cluster[uuid:{0}] is not Enabled. -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:118 -# args: -templateContent\ and\ templateUuid\ mustn't\ both\ be\ empty! = templateContent and templateUuid mustn't both be empty! +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:74 +# args: address,port +Bare\ Metal\ IPMI\ 2\ Chassis\ %s\:%d\ already\ exists = Bare Metal IPMI 2 Chassis {0}:{1} already exists -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:129 +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:93 # args: -templateContent\ and\ url\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = templateContent and url mustn't both be empty or both be set! +Failed\ to\ reach\ the\ baremetal2\ chassis,\ please\ make\ sure\:\ 1.\ the\ IPMI\ connection\ is\ active;\ 2.\ the\ IPMI\ Address,\ Port,\ Username\ and\ Password\ are\ correct;\ 3.\ IPMI\ Over\ LAN\ is\ enabled\ in\ BIOS. = Failed to reach the baremetal2 chassis, please make sure: 1. the IPMI connection is active; 2. the IPMI Address, Port, Username and Password are correct; 3. IPMI Over LAN is enabled in BIOS. -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:145 -# args: -only\ admin\ could\ enable/disable\ system\ StackTemplate = only admin could enable/disable system StackTemplate +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:140 +# args: msg.getClusterUuid() +Cluster[uuid\:%s]\ is\ not\ a\ BareMetal2\ Cluster. = Cluster[uuid:{0}] is not a BareMetal2 Cluster. -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:856 -# args: vo.getName() -cannot\ delete\ or\ update\ system\ template\:\ %s = cannot delete or update system template: {0} +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:178 +# args: clusterUuid +no\ usable\ baremetal2\ gateway\ in\ cluster[uuid\:%s] = no usable baremetal2 gateway in cluster[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:385 -# args: msg.getUuid() -ResourceStackVO\:\ [%s]\ has\ been\ deleted... = ResourceStackVO: [{0}] has been deleted... +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:134 +# args: self.getUuid() +failed\ to\ power\ on\ baremetal2\ ipmi\ chassis[uuid\:%s] = failed to power on baremetal2 ipmi chassis[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:415 -# args: uuid -ResourceStackVO\ [%s]\ already\ been\ deleted! = ResourceStackVO [{0}] already been deleted! +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:206 +# args: self.getUuid() +failed\ to\ power\ off\ baremetal2\ ipmi\ chassis[uuid\:%s] = failed to power off baremetal2 ipmi chassis[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:641 -# args: -templateContent\ must\ be\ set! = templateContent must be set! +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:249 +# args: self.getUuid() +failed\ to\ power\ reset\ baremetal2\ ipmi\ chassis[uuid\:%s] = failed to power reset baremetal2 ipmi chassis[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:636 -# args: template.getUuid() -template\ [%s]\ chosen\ is\ disabled = template [{0}] chosen is disabled +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:340 +# args: self.getUuid() +Failed\ to\ remotely\ ipxe\ boot\ chassis[uuid\:%s] = Failed to remotely ipxe boot chassis[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:779 -# args: p.getParamName(),p.getResourceType() -cannot\ find\ parameters\ for\ %s,\ which\ is\ %s\ type,\ please\ check\ parameters = cannot find parameters for {0}, which is {1} type, please check parameters +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java:76 +# args: e.getMessage() +fail\ to\ load\ baremetal2\ ipmi\ chassis\ info\ from\ file,\ because\:\ %s = fail to load baremetal2 ipmi chassis info from file, because: {0} -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:849 +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java:94 # args: -StackTemplateVO\ has\ been\ deleted... = StackTemplateVO has been deleted... +the\ api\ message's\ chassis\ type\ is\ ipmi,\ but\ it's\ not\ an\ APICreateBareMetal2ChassisHardwareInfoMsg = the api message's chassis type is ipmi, but it's not an APICreateBareMetal2ChassisHardwareInfoMsg + +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java:104 +# args: imsg.getIpmiAddress(),imsg.getIpmiPort() +received\ hardware\ info\ for\ unknown\ baremetal2\ chassis[ipmi_addr\:%s,\ ipmi_port\:%d] = received hardware info for unknown baremetal2 chassis[ipmi_addr:{0}, ipmi_port:{1}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:872 +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:84 # args: -content\ must\ be\ set\ by\ templateContent\ or\ url! = content must be set by templateContent or url! +cluster\ type\ and\ hypervisor\ type\ should\ all\ be\ baremetal2\ or\ all\ not = cluster type and hypervisor type should all be baremetal2 or all not -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:890 +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:90 # args: -get\ null\ content\ input = get null content input +the\ architecture\ must\ be\ set\ when\ create\ new\ baremetal2\ clusters = the architecture must be set when create new baremetal2 clusters -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:897 -# args: result.getTemplateVersion() -invalid\ cloudformation\ template\ version\:\ %s = invalid cloudformation template version: {0} +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:101 +# args: +do\ not\ add\ host\ into\ baremetal2\ cluster = do not add host into baremetal2 cluster -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:911 -# args: msg.getUuid() -StackTemplateVO\:\ [%s]\ has\ been\ deleted... = StackTemplateVO: [{0}] has been deleted... +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:123 +# args: +l2\ network\ should\ not\ have\ the\ same\ interface\ name\ with\ provision\ network\ that's\ already\ attached\ to\ the\ cluster = l2 network should not have the same interface name with provision network that's already attached to the cluster -# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:20 +# at: src/main/java/org/zstack/baremetal2/cluster/CephStorageAttachBm2ClusterMetric.java:29 # args: -get\ null\ element\ in\ template\ content = get null element in template content +Can\ not\ attach\ third-party\ ceph\ with\ token\ into\ aarch64\ cluster. = Can not attach third-party ceph with token into aarch64 cluster. -# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:24 +# at: src/main/java/org/zstack/baremetal2/cluster/LocalStorageAttachBm2ClusterMetric.java:12 # args: -template\ must\ contain\ [ZStackTemplateFormatVersion] = template must contain [ZStackTemplateFormatVersion] +Can\ not\ attach\ local\ storage\ into\ baremetal2\ cluster. = Can not attach local storage into baremetal2 cluster. -# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:27 -# args: result.getTemplateVersion(),CloudFormationConstant.version -invalid\ ZStackTemplateFormatVersion\:\ %s,\ %s = invalid ZStackTemplateFormatVersion: {0}, {1} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1328 +# args: msg.getInstanceUuid() +no\ provision\ nic\ found\ for\ baremetal2\ instance[uuid\:%s] = no provision nic found for baremetal2 instance[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:156 -# args: -verb\ must\ contain\ '\:\:'! = verb must contain '::'! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:269 +# args: self.getUuid(),msg.getInstanceUuid() +failed\ to\ delete\ convert\ volume\ to\ chassis\ local\ disk\ configurations\ in\ gateway[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s] = failed to delete convert volume to chassis local disk configurations in gateway[uuid:{0}] for baremetal2 instance[uuid:{1}] -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:197 -# args: t[0],last.getClass().getName() -need\ List\ for\ resource\ [%s]\ output\ here,\ but\ got\ %s. = need List for resource [{0}] output here, but got {1}. +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1342 +# args: msg.getInstanceUuid(),self.getUuid(),ret.getError() +failed\ to\ create\ provision\ configurations\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = failed to create provision configurations for baremetal2 instance[uuid:{0}] in gateway[uuid:{1}], because {2} -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:221 -# args: value -invalid\ dynamic\ variables,\ which\ must\ contained\ ${\:\ %s = invalid dynamic variables, which must contained $'{: {0}' +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:418 +# args: chassis.getUuid() +chassis\:%s\ disk\ does\ not\ have\ wwn\ info,\ please\ inspect\ chassis\ and\ try\ again = chassis:{0} disk does not have wwn info, please inspect chassis and try again -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:283 -# args: -cannot\ find\ resource\ of\ properties\ set\ before! = cannot find resource of properties set before! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1809 +# args: chassis.getUuid() +failed\ to\ power\ on\ baremetal2\ chassis[uuid\:%s]\ using\ ipmitool = failed to power on baremetal2 chassis[uuid:{0}] using ipmitool -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:359 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:567 # args: -Some\ actions\ are\ invalid = Some actions are invalid +convert\ image\ data\ to\ local\ disk\ failed = convert image data to local disk failed -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:128 -# args: e -Unable\ to\ create\ json\ template = Unable to create json template +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:576 +# args: instanceVO.getUuid(),chassis.getUuid(),BareMetal2GlobalConfig.CONVERT_VOLUME_TO_LOCAL_DISK_TIMEOUT.value(Integer.class) +baremetal2\ instance[uuid\:%s]\ convert\ volume\ failed\ on\ baremetal2\ chassis[uuid\:%s]\ ,\ timeout\ after\ %s\ minutes\ = baremetal2 instance[uuid:{0}] convert volume failed on baremetal2 chassis[uuid:{1}] , timeout after {2} minutes -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:116 -# args: jsonFile -cannot\ find\ such\ template\ file\:\ %s = cannot find such template file: {0} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1235 +# args: self.getUuid(),ret.getError() +failed\ to\ prepare\ provision\ network\ in\ gateway[uuid\:%s],\ because\ %s = failed to prepare provision network in gateway[uuid:{0}], because {1} -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:233 -# args: -no\ root\ element\ found,\ please\ check\ your\ cfn\ formation! = no root element found, please check your cfn formation! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1304 +# args: self.getUuid(),ret.getError() +failed\ to\ destroy\ provision\ network\ in\ gateway[uuid\:%s],\ because\ %s = failed to destroy provision network in gateway[uuid:{0}], because {1} -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:365 -# args: e.getMessage() -Wrong\ json\ format,\ causes\:\ %s = Wrong json format, causes: {0} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1391 +# args: msg.getInstanceUuid(),self.getUuid(),ret.getError() +failed\ to\ delete\ provision\ configurations\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = failed to delete provision configurations for baremetal2 instance[uuid:{0}] in gateway[uuid:{1}], because {2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:59 -# args: -Mappings\ root\ body\ must\ be\ json\ object! = Mappings root body must be json object! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1435 +# args: msg.getInstanceUuid(),self.getUuid(),ret.getError() +failed\ to\ create\ console\ proxy\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = failed to create console proxy for baremetal2 instance[uuid:{0}] in gateway[uuid:{1}], because {2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:45 -# args: -Condition\ body\ cannot\ support\ json\ null\ or\ array! = Condition body cannot support json null or array! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1492 +# args: msg.getOldDefaultL3Uuid(),msg.getNewDefaultL3Uuid(),msg.getInstanceUuid(),ret.getError() +failed\ to\ change\ default\ network\ from\ l3[uuid\:%s]\ to\ l3[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s],\ because\ %s = failed to change default network from l3[uuid:{0}] to l3[uuid:{1}] for baremetal2 instance[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:41 -# args: -Only\ support\ ZStack\ Template\ Functions\ in\ 'Condition'\ field! = Only support ZStack Template Functions in 'Condition' field! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1531 +# args: msg.getInstanceUuid(),msg.getGatewayUuid(),ret.getError() +failed\ to\ ping\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to ping baremetal2 instance[uuid:{0}] through gateway[uuid:{1}], because {2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:37 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1578 +# args: msg.getInstanceUuid(),msg.getGatewayUuid(),ret.getError() +failed\ to\ change\ the\ password\ of\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to change the password of baremetal2 instance[uuid:{0}] through gateway[uuid:{1}], because {2} + +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1677 # args: -Value\ must\ be\ boolean\ in\ 'Condition'\ field = Value must be boolean in 'Condition' field +third\ party\ ceph\ with\ token\ not\ support\ local\ disk\ yet = third party ceph with token not support local disk yet -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:30 -# args: key,es.size() -Condition\ key\:\ %s\ only\ support\ 1\ element\ in\ the\ json\ object\ of\ value,\ but\ got\ %d\ elements! = Condition key: {0} only support 1 element in the json object of value, but got {1} elements! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1838 +# args: chassis.getUuid() +failed\ to\ power\ off\ baremetal2\ chassis[uuid\:%s]\ using\ ipmitool = failed to power off baremetal2 chassis[uuid:{0}] using ipmitool -# at: src/main/java/org/zstack/cloudformation/template/decoder/DecoderUtils.java:87 -# args: msg -cannot\ find\ such\ msg\:\ %s\ for\ create = cannot find such msg: {0} for create +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1923 +# args: chassis.getUuid(),timeout +baremetal2\ chassis[uuid\:%s]\ is\ still\ not\ POWER_OFF\ %d\ seconds\ later = baremetal2 chassis[uuid:{0}] is still not POWER_OFF {1} seconds later -# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:56 -# args: -Mapping\ value\ body\ cannot\ support\ null! = Mapping value body cannot support null! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1896 +# args: bm.getUuid(),ret.getError() +failed\ to\ power\ off\ baremetal2\ instance[uuid\:%s]\ by\ bm\ agent,\ because\ %s = failed to power off baremetal2 instance[uuid:{0}] by bm agent, because {1} -# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:54 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2103 # args: -Mapping\ value\ body\ cannot\ support\ json\ array! = Mapping value body cannot support json array! +vmInstanceUuids\ is\ empty = vmInstanceUuids is empty -# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:66 -# args: -mappingName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = mappingName must be found in result, or it is invalid cfn json. +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2109 +# args: self.getUuid(),self.getStatus() +the\ baremetal2\ gateway[uuid\:%s,\ status\:%s]\ is\ not\ Connected = the baremetal2 gateway[uuid:{0}, status:{1}] is not Connected -# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:83 -# args: -Mapping\ body\ cannot\ support\ json\ null! = Mapping body cannot support json null! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2186 +# args: bmUuid +baremetal2\ instance[uuid\:%s]\ not\ connected,\ cannot\ attach\ nic\ to\ it = baremetal2 instance[uuid:{0}] not connected, cannot attach nic to it -# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:81 -# args: -Mapping\ body\ cannot\ support\ non\ map\ value! = Mapping body cannot support non map value! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2209 +# args: nicUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ attach\ nic[uuid\:%s]\ to\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to attach nic[uuid:{0}] to baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:70 -# args: -Description\ in\ Outputs\ must\ be\ String\ type! = Description in Outputs must be String type! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2252 +# args: bmUuid +baremetal2\ instance[uuid\:%s]\ is\ not\ connected,\ cannot\ detach\ nic\ from\ it = baremetal2 instance[uuid:{0}] is not connected, cannot detach nic from it -# at: src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java:59 -# args: -paramName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = paramName must be found in result, or it is invalid cfn json. +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2275 +# args: nicUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ detach\ nic[uuid\:%s]\ from\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to detach nic[uuid:{0}] from baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java:129 -# args: -Parameters\ root\ body\ must\ be\ json\ object! = Parameters root body must be json object! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2441 +# args: bmUuid +baremetal2\ instance[uuid\:%s]\ is\ not\ connected,\ cannot\ attach\ volume\ to\ it = baremetal2 instance[uuid:{0}] is not connected, cannot attach volume to it -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:112 -# args: -resourceName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = resourceName must be found in result, or it is invalid cfn json. +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2338 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ prepare\ volume[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to prepare volume[uuid:{0}] for baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:123 -# args: -Parameters\ body\ cannot\ support\ null! = Parameters body cannot support null! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2399 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ attach\ volume[uuid\:%s]\ to\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to attach volume[uuid:{0}] to baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:68 -# args: -Resource\ value\ body\ cannot\ support\ null! = Resource value body cannot support null! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2480 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ get\ volume[uuid\:%s]\ lunid\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = failed to get volume[uuid:{0}] lunid for baremetal2 instance[uuid:{1}] in gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:48 -# args: resource.getResourceName(),e.getKey(),resource.getResourceName() -Resource\ %s\ cannot\ depends\ on\ itself,\ please\ check\ %s\ in\ Resource\ [%s] = Resource {0} cannot depends on itself, please check {1} in Resource [{2}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2535 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ detach\ volume[uuid\:%s]\ from\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = failed to detach volume[uuid:{0}] from baremetal2 instance[uuid:{1}] through gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:254 -# args: -Resource\ root\ body\ must\ be\ json\ object! = Resource root body must be json object! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2570 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ destroy\ volume[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = failed to destroy volume[uuid:{0}] for baremetal2 instance[uuid:{1}] in gateway[uuid:{2}], because {3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:216 -# args: -Resource\ Type\ must\ be\ String! = Resource Type must be String! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:100 +# args: msg.getManagementIp() +there\ has\ been\ a\ baremetal2\ gateway\ having\ management\ ip\ %s = there has been a baremetal2 gateway having management ip {0} -# at: src/main/java/org/zstack/cloudformation/template/function/IfTemplateFunction.java:42 -# args: cond -cannot\ find\ condition[%s]\ in\ 'Conditions' = cannot find condition[{0}] in 'Conditions' +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:66 +# args: msg.getManagementIp() +there\ is\ already\ a\ baremetal\ pxe\ server\ with\ management\ ip\ %s,\ do\ not\ use\ it\ to\ create\ baremetal2\ gateway = there is already a baremetal pxe server with management ip {0}, do not use it to create baremetal2 gateway -# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:42 -# args: e.getAsString() -expect\ 'true',\ 'false'\ for\ the\ object,\ but\ got\ %s = expect 'true', 'false' for the object, but got {0} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:107 +# args: msg.getManagementIp() +there\ has\ been\ a\ host\ having\ management\ ip\ %s = there has been a host having management ip {0} -# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:35 -# args: keys,e.getAsString() -expect\ 'true',\ 'false'\ or\ an\ other\ Condition,\ current\ Conditions\ include\:\ %s,\ but\ got\ %s = expect 'true', 'false' or an other Condition, current Conditions include: {0}, but got {1} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:80 +# args: msg.getManagementIp() +management\ ip[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = management ip[{0}] is neither an IPv4 address nor a valid hostname -# at: src/main/java/org/zstack/cloudformation/template/function/SelectTemplateFunction.java:83 -# args: -Fn\:\:Select\ out\ of\ range,\ please\ check\ your\ json\ file! = Fn::Select out of range, please check your json file! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:90 +# args: msg.getClusterUuid() +cannot\ add\ baremetal2\ gateway\ in\ non-baremetal2\ cluster[uuid\:%s] = cannot add baremetal2 gateway in non-baremetal2 cluster[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:75 -# args: e.getKey() -only\ functions\ can\ in\ Function,\ but\ found\ %s = only functions can in Function, but found {0} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:120 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ gateway[uuid\:%s]\ to\ non-baremetal2\ cluster[uuid\:%s] = cannot attach baremetal2 gateway[uuid:{0}] to non-baremetal2 cluster[uuid:{1}] -# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:90 -# args: -element\ is\ null! = element is null! +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:131 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ already\ attached\ to\ cluster[uuid\:%s] = baremetal2 gateway[uuid:{0}] already attached to cluster[uuid:{1}] -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:317 -# args: resourceUuid,affinityGroupUuid -VM\ [uuid\:\ %s]\ has\ already\ been\ added\ to\ affinityGroup\ [uuid\:\ %s] = VM [uuid: {0}] has already been added to affinityGroup [uuid: {1}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:140 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ can\ only\ attach\ to\ one\ cluster = baremetal2 gateway[uuid:{0}] can only attach to one cluster -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:334 -# args: hostUuid,affinityGroupUuid -There\ are\ other\ VMs\ on\ this\ host\ [uuid\:\ %s]\ belonging\ to\ same\ affinityGroup\ [%s] = There are other VMs on this host [uuid: {0}] belonging to same affinityGroup [{1}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:151 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ not\ attached\ to\ cluster[uuid\:%s],\ no\ need\ to\ detach = baremetal2 gateway[uuid:{0}] not attached to cluster[uuid:{1}], no need to detach -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:363 -# args: self.getUuid(),host.getUuid(),vmUuid -affinityGroup\ [uuid\:%s]\ reserve\ host\ [uuid\:%s]\ for\ vm\ [uuid\:\ %s]\ failed = affinityGroup [uuid:{0}] reserve host [uuid:{1}] for vm [uuid: {2}] failed +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:156 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ is\ attached\ to\ only\ one\ cluster\ now,\ do\ not\ detach\ it = baremetal2 gateway[uuid:{0}] is attached to only one cluster now, do not detach it -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:433 -# args: inv.getResourceUuid(),self.getUuid() -vm\ [uuid\:%s]\ doesn't\ satisfy\ the\ affinityGroup\ [uuid\:%s] = vm [uuid:{0}] doesn't satisfy the affinityGroup [uuid:{1}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:164 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ does\ not\ exist = cluster[uuid:{0}] does not exist -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupFilterFlow.java:136 -# args: -can\ not\ satisfied\ affinity\ group\ conditions = can not satisfied affinity group conditions +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:168 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ is\ not\ a\ baremetal2\ cluster = cluster[uuid:{0}] is not a baremetal2 cluster -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:42 -# args: VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString(),state.toString() -Vm\ can\ change\ its\ affinityGroup\ only\ in\ state\ [%s,%s],\ but\ vm\ is\ in\ state\ [%s] = Vm can change its affinityGroup only in state [{0},{1}], but vm is in state [{2}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:173 +# args: msg.getGatewayUuid() +gateway[uuid\:%s]\ does\ not\ exist = gateway[uuid:{0}] does not exist -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:52 -# args: msg.getUuid(),agUuid -Vm\ [uuid\:\ %s]\ is\ already\ added\ to\ affinityGroup\ [uuid\:\ %s] = Vm [uuid: {0}] is already added to affinityGroup [uuid: {1}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:177 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ is\ already\ in\ cluster[uuid\:%s] = baremetal2 gateway[uuid:{0}] is already in cluster[uuid:{1}] -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:77 -# args: affinityGroupUuid -AffinityGroup\ [uuid\:\ %s]\ does\ not\ existed = AffinityGroup [uuid: {0}] does not existed +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:181 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ in\ the\ same\ zone\ as\ cluster[uuid\:%s] = baremetal2 gateway[uuid:{0}] is not in the same zone as cluster[uuid:{1}] -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:81 -# args: -Can\ not\ operate\ on\ affinity\ group\ created\ by\ system = Can not operate on affinity group created by system +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:191 +# args: msg.getGatewayUuid() +cannot\ change\ the\ cluster\ of\ baremetal2\ gateway[uuid\:%s]\ when\ there\ are\ running\ instances\ depending\ on\ it = cannot change the cluster of baremetal2 gateway[uuid:{0}] when there are running instances depending on it -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:88 -# args: affinityGroupUuid -Can\ not\ operate\ on\ affinityGroup\ [uuid\:\ %s]\ which\ is\ not\ enabled = Can not operate on affinityGroup [uuid: {0}] which is not enabled +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayConsoleHypervisorBackend.java:45 +# args: +baremetal2\ instance[uuid\:%s]\ doesn't\ exist,\ cannot\ generate\ its\ console\ url = baremetal2 instance[uuid:{0}] doesn't exist, cannot generate its console url -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupManagerImpl.java:98 -# args: msg.getAffinityGroupUuid() -cannot\ find\ the\ affinity\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the affinity group[uuid:{0}], it may have been deleted +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayConsoleHypervisorBackend.java:54 +# args: bm.getGatewayUuid(),bm.getUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ Connected,\ cannot\ generate\ console\ url\ for\ instance[uuid\:%s] = baremetal2 gateway[uuid:{0}] is not Connected, cannot generate console url for instance[uuid:{1}] -# at: src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java:103 -# args: spec.getL3NetworkUuids() -no\ host\ found\ in\ clusters\ that\ has\ attached\ to\ L2Networks\ which\ have\ L3Networks%s = no host found in clusters that has attached to L2Networks which have L3Networks{0} +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayManagerImpl.java:258 +# args: resourceUuid +cluster[%s]\ is\ not\ baremetal2\ type = cluster[{0}] is not baremetal2 type -# at: src/main/java/org/zstack/compute/allocator/AttachedPrimaryStorageAllocatorFlow.java:79 -# args: psuuids -no\ host\ found\ in\ clusters\ that\ have\ attached\ to\ primary\ storage\ %s = no host found in clusters that have attached to primary storage {0} +# at: src/main/java/org/zstack/baremetal2/gateway/allocator/AbstractGatewayAllocatorStrategy.java:102 +# args: +failed\ to\ allocate\ baremetal2\ gateway = failed to allocate baremetal2 gateway -# at: src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java:79 -# args: requiredPsUuids,vm.getUuid() -no\ host\ found\ in\ clusters\ which\ have\ attached\ to\ all\ primary\ storage\ %s\ where\ vm[uuid\:%s]'s\ volumes\ locate = no host found in clusters which have attached to all primary storage {0} where vm[uuid:{1}]'s volumes locate +# at: src/main/java/org/zstack/baremetal2/gateway/allocator/BareMetal2GatewayMainAllocatorFlow.java:62 +# args: +no\ available\ baremetal2\ gateway\ found = no available baremetal2 gateway found -# at: src/main/java/org/zstack/compute/allocator/AvoidHostAllocatorFlow.java:30 -# args: spec.getAvoidHostUuids() -after\ rule\ out\ avoided\ host%s,\ there\ is\ no\ host\ left\ in\ candidates = after rule out avoided host{0}, there is no host left in candidates +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:166 +# args: BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE +only\ baremetal2\ image\ with\ boot\ mode\ %s\ is\ supported = only baremetal2 image with boot mode {0} is supported -# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:87 -# args: spec.getRequiredBackupStorageUuid(),bsType -the\ backup\ storage[uuid\:%s,\ type\:%s]\ requires\ bound\ primary\ storage,\ however,\ the\ primary\ storage\ has\ not\ been\ added = the backup storage[uuid:{0}, type:{1}] requires bound primary storage, however, the primary storage has not been added +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:138 +# args: bm2ImageCount +only\ one\ baremetal2\ system\ tag\ is\ allowed,\ but\ %d\ was\ got = only one baremetal2 system tag is allowed, but {0} was got -# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:80 -# args: spec.getImage().getUuid(),spec.getRequiredBackupStorageUuid(),type,psUuids -The\ image[uuid\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[uuids\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = The image[uuid:{0}] is on the backup storage[uuid:{1}, type:{2}] that requires to work with primary storage[uuids:{3}],however, no host found suitable to work with those primary storage +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:158 +# args: +only\ root\ volume\ template\ of\ format\ raw/qcow2\ can\ be\ tagged\ with\ baremetal2 = only root volume template of format raw/qcow2 can be tagged with baremetal2 -# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:71 -# args: spec.getImage().getUuid(),name,spec.getRequiredBackupStorageUuid(),spec.getImage().getType(),possiblePrimaryStorageTypes -The\ image[uuid\:%s,\ name\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[types\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = The image[uuid:{0}, name:{1}] is on the backup storage[uuid:{2}, type:{3}] that requires to work with primary storage[types:{4}],however, no host found suitable to work with those primary storage +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:162 +# args: +the\ bootMode\ tag\ is\ mandatory\ for\ baremetal2\ images = the bootMode tag is mandatory for baremetal2 images -# at: src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java:107 -# args: args -No\ host\ with\ %s\ found = No host with {0} found +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateChassisFlow.java:76 +# args: spec.getRequiredChassisDiskUuid(),chassis.getUuid() +required\ chassis\ disk[%s]\ not\ belong\ to\ chassis[%s] = required chassis disk[{0}] not belong to chassis[{1}] -# at: src/main/java/org/zstack/compute/allocator/FilterFlow.java:33 -# args: filter.getClass().getSimpleName(),filter.filterErrorReason() -after\ filtering,\ HostAllocatorFilterExtensionPoint[%s]\ returns\ zero\ candidate\ host,\ it\ means\:\ %s = after filtering, HostAllocatorFilterExtensionPoint[{0}] returns zero candidate host, it means: {1} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateChassisFlow.java:88 +# args: chassis.getUuid(),spec.getImageSpec().getInventory().getUuid() +chassis\ not\ have\ engouh\ capacity\ for\ image[%s] = chassis not have engouh capacity for image[{0}] -# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:56 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:85 # args: -either\ volumeUuid\ or\ volumeSnapshotUuid\ must\ be\ set = either volumeUuid or volumeSnapshotUuid must be set +not\ enough\ information\ to\ determine\ which\ baremetal2\ cluster\ should\ be\ used = not enough information to determine which baremetal2 cluster should be used -# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:75 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:100 # args: -zoneUuids,\ clusterUuids,\ hostUuids\ must\ at\ least\ have\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = zoneUuids, clusterUuids, hostUuids must at least have one be none-empty list, or all is set to true +no\ baremetal2\ cluster\ found = no baremetal2 cluster found -# at: src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java:71 -# args: spec.getCpuCapacity(),spec.getMemoryCapacity() -no\ host\ having\ cpu[%s],\ memory[%s\ bytes]\ found = no host having cpu[{0}], memory[{1} bytes] found +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:217 +# args: spec.getRequiredClusterUuids(),spec.getVmInventory().getUuid() +failed\ to\ allocate\ primary\ storage\ in\ clusters[uuids\:%s]\ for\ baremetal2\ instance[uuid\:%s] = failed to allocate primary storage in clusters[uuids:{0}] for baremetal2 instance[uuid:{1}] -# at: src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java:62 -# args: currentVersion -no\ candidate\ host\ has\ version[%s] = no candidate host has version[{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:224 +# args: spec.getRequiredClusterUuids(),spec.getVmInventory().getUuid() +failed\ to\ allocate\ gateway\ in\ clusters[uuids\:%s]\ for\ baremetal2\ instance[uuid\:%s] = failed to allocate gateway in clusters[uuids:{0}] for baremetal2 instance[uuid:{1}] -# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:221 -# args: PrimaryStorageState.Enabled,PrimaryStorageState.Disabled,PrimaryStorageStatus.Connected -cannot\ find\ available\ primary\ storage[state\:\ %s\ or\ %s,\ status\:\ %s].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = cannot find available primary storage[state: {0} or {1}, status: {2}]. Check the state/status of primary storage and make sure they have been attached to clusters +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:231 +# args: spec.getRequiredClusterUuids(),spec.getVmInventory().getUuid() +failed\ to\ allocate\ chassis\ in\ clusters[uuids\:%s]\ for\ baremetal2\ instance[uuid\:%s] = failed to allocate chassis in clusters[uuids:{0}] for baremetal2 instance[uuid:{1}] -# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:217 -# args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,spec.getDiskSize() -cannot\ find\ available\ primary\ storage[state\:\ %s,\ status\:\ %s,\ available\ capacity\ %s\ bytes].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = cannot find available primary storage[state: {0}, status: {1}, available capacity {2} bytes]. Check the state/status of primary storage and make sure they have been attached to clusters +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:262 +# args: clusterUuids +only\ baremetal2\ clusters[uuid\:%s]\ meet\ the\ needs\ for\ chassis\ and\ gateway,\ but\ they\ have\ no\ provision\ network\ attached = only baremetal2 clusters[uuid:{0}] meet the needs for chassis and gateway, but they have no provision network attached -# at: src/main/java/org/zstack/compute/allocator/HostSortorChain.java:127 -# args: e.getMessage(),host.getUuid(),e.getMessage() -[Host\ Allocation]\:\ %s\ on\ host[uuid\:%s].\ try\ next\ one.\ %s = [Host Allocation]: {0} on host[uuid:{1}]. try next one. {2} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:253 +# args: spec.getRequiredClusterUuids() +no\ baremetal2\ cluster\ found\ in\ clusters[uuid\:%s] = no baremetal2 cluster found in clusters[uuid:{0}] -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:97 -# args: spec.getHypervisorType() -no\ host\ having\ state\=Enabled\ status\=Connected\ hypervisorType\=%s\ found = no host having state=Enabled status=Connected hypervisorType={0} found +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:881 +# args: msg.getPrimaryStorageUuidForRootVolume(),msg.getPrimaryStorageUuidForDataVolume() +the\ primary\ storage[%s]\ of\ the\ root\ volume\ and\ the\ primary\ storage[%s]\ of\ the\ data\ volume\ are\ not\ in\ the\ same\ cluster = the primary storage[{0}] of the root volume and the primary storage[{1}] of the data volume are not in the same cluster -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:99 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:244 +# args: networkUuid +make\ sure\ all\ baremetal2\ gateways\ on\ provision\ network[uuid\:%s]\ are\ Connected = make sure all baremetal2 gateways on provision network[uuid:{0}] are Connected + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:707 # args: -no\ host\ having\ state\=Enabled\ status\=Connected\ found = no host having state=Enabled status=Connected found +neither\ chassisUuid\ nor\ chassisOfferingUuid\ is\ set\ when\ create\ baremetal2\ instance = neither chassisUuid nor chassisOfferingUuid is set when create baremetal2 instance -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:94 -# args: candidates.size(),spec.getHypervisorType() -no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts\ having\ the\ hypervisor\ type\ [%s] = no Enabled hosts found in the [{0}] candidate hosts having the hypervisor type [{1}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:169 +# args: +only\ support\ vpc\ network\ support\ attach\ eip\ on\ baremetal2\ instance = only support vpc network support attach eip on baremetal2 instance -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:92 -# args: candidates.size() -no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = no Enabled hosts found in the [{0}] candidate hosts +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:179 +# args: +bare\ metal\ instance\ not\ allowed\ to\ change\ vm\ nic\ network = bare metal instance not allowed to change vm nic network -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:90 -# args: candidates.size() -no\ Connected\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = no Connected hosts found in the [{0}] candidate hosts +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:190 +# args: +current\ operation\ is\ not\ supported\ on\ local\ baremetal\ instance = current operation is not supported on local baremetal instance -# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:92 -# args: spec.getImage().getUuid(),spec.getImage().getName() -the\ image[uuid\:%s,\ name\:%s]\ is\ deleted\ on\ all\ backup\ storage = the image[uuid:{0}, name:{1}] is deleted on all backup storage +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:201 +# args: +not\ supported\ by\ baremetal2\ instance = not supported by baremetal2 instance -# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:126 -# args: zoneUuids,spec.getImage().getUuid() -no\ host\ found\ in\ zones[uuids\:%s]\ that\ attaches\ to\ backup\ storage\ where\ image[%s]\ is\ on = no host found in zones[uuids:{0}] that attaches to backup storage where image[{1}] is on +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:207 +# args: bm.getUuid() +baremetal2\ instance[uuid\:%s]\ is\ not\ Connected = baremetal2 instance[uuid:{0}] is not Connected -# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:98 -# args: entry.getKey() -resource\ binding\ not\ support\ type\ %s\ yet = resource binding not support type {0} yet +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:215 +# args: bm.getUuid() +baremetal2\ instance[uuid\:%s]\ is\ not\ stopped = baremetal2 instance[uuid:{0}] is not stopped -# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:117 -# args: resources -no\ available\ host\ found\ with\ binded\ resource\ %s = no available host found with binded resource {0} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:221 +# args: bm.getUuid() +baremetal2\ instance[uuid\:%s]\ is\ running\ but\ its\ agent\ is\ not\ Connected = baremetal2 instance[uuid:{0}] is running but its agent is not Connected -# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:68 -# args: extp.getClass().getName() -InstanceOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = InstanceOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:607 +# args: msg.getChassisOfferingUuid() +baremetal2\ chassis\ offering[uuid\:%s]\ does\ not\ exist = baremetal2 chassis offering[uuid:{0}] does not exist -# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:104 -# args: extp.getClass().getName() -DiskOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = DiskOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:318 +# args: msg.getInstanceUuid() +baremetal2\ instance[uuid\:%s]\ is\ not\ stopped\ can\ not\ change\ its\ chassis\ offering = baremetal2 instance[uuid:{0}] is not stopped can not change its chassis offering -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:55 -# args: -if\ cluster\ type\ is\ baremetal,\ then\ hypervisorType\ must\ be\ baremetal\ too,\ or\ vice\ versa = if cluster type is baremetal, then hypervisorType must be baremetal too, or vice versa +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:337 +# args: msg.getVmInstanceUuid() +baremetal2\ instance[uuid\:%s]\ has\ not\ been\ allocated\ a\ chassis,\ start\ the\ instance\ and\ try\ again = baremetal2 instance[uuid:{0}] has not been allocated a chassis, start the instance and try again -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:71 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:343 +# args: ipVersion +only\ l3\ network\ with\ ip\ version\ %d\ is\ supported\ by\ baremetal2\ instance = only l3 network with ip version {0} is supported by baremetal2 instance + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:349 +# args: l2Type +l2\ network\ type\ %s\ not\ supported\ by\ baremetal2\ instance = l2 network type {0} not supported by baremetal2 instance + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:355 # args: -only\ kvm\ hosts'\ operating\ system\ can\ be\ updated,\ for\ now = only kvm hosts' operating system can be updated, for now +customMac\ is\ mandatory\ when\ attaching\ l3\ network\ to\ baremetal2\ instance = customMac is mandatory when attaching l3 network to baremetal2 instance -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:82 -# args: msg.getUuid() -there\ are\ hosts\ in\ cluster[uuid\:%s]\ in\ the\ PreMaintenance\ state,\ cannot\ update\ cluster\ os\ right\ now = there are hosts in cluster[uuid:{0}] in the PreMaintenance state, cannot update cluster os right now +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:359 +# args: msg.getCustomMac() +%s\ is\ not\ valid\ mac\ address = {0} is not valid mac address -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:94 -# args: msg.getUuid() -not\ all\ hosts\ in\ cluster[uuid\:%s]\ are\ in\ the\ Connected\ status,\ cannot\ update\ cluster\ os\ right\ now = not all hosts in cluster[uuid:{0}] are in the Connected status, cannot update cluster os right now +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:364 +# args: msg.getCustomMac() +duplicated\ mac\ address\ %s = duplicated mac address {0} -# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java:45 -# args: r -invalid\ cpu\ pinning\ ref[%s].\ correct\ example\ is\ [1,3\:3-6,^5] = invalid cpu pinning ref[{0}]. correct example is [1,3:3-6,^5] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:373 +# args: bm.getUuid(),bm.getChassisUuid(),msg.getCustomMac() +baremetal2\ instance[uuid\:%s]\ running\ on\ chassis[uuid\:%s],\ which\ doesn't\ have\ non-provisioning\ nic\ with\ mac\ address\ %s = baremetal2 instance[uuid:{0}] running on chassis[uuid:{1}], which doesn't have non-provisioning nic with mac address {2} -# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java:82 -# args: pCpuNum -the\ host\ vm\ located\ only\ have\ %\ CPUs = the host vm located only have % CPUs +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:382 +# args: msg.getCustomMac() +mac\ address\ %s\ has\ already\ been\ used,\ try\ another\ one = mac address {0} has already been used, try another one + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:399 +# args: msg.getCustomMac() +nic\ with\ mac\:%s\ cannot\ be\ attached\ l3Network,\ because\ it\ has\ been\ bonded = nic with mac:{0} cannot be attached l3Network, because it has been bonded -# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningFilterFlow.java:48 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:448 # args: -vcpu\ pinning\ pcpu\ id\ >\ host\ cores = vcpu pinning pcpu id > host cores +third\ party\ ceph\ cannot\ mixed\ with\ other\ primary\ storage = third party ceph cannot mixed with other primary storage -# at: src/main/java/org/zstack/compute/cpuPinning/CpuRangeSet.java:58 -# args: word -Invalid\ cpuset\ [%s] = Invalid cpuset [{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:571 +# args: msg.getClusterUuid(),msg.getUuid() +cluster[uuid\:%s]\ is\ not\ an\ Enabled\ baremetal2\ cluster,\ cannot\ start\ instance[uuid\:%s]\ in\ it = cluster[uuid:{0}] is not an Enabled baremetal2 cluster, cannot start instance[uuid:{1}] in it -# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:78 -# args: msg.getManagementIp() -managementIp[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = managementIp[{0}] is neither an IPv4 address nor a valid hostname +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:583 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ does\ not\ exist\ or\ is\ not\ Enabled\ or\ Connected = baremetal2 gateway[uuid:{0}] does not exist or is not Enabled or Connected -# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:88 -# args: msg.getHostUuid(),hostStatus -can\ not\ maintain\ host[uuid\:%s,\ status\:%s]which\ is\ not\ Connected = can not maintain host[uuid:{0}, status:{1}]which is not Connected +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:594 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ in\ cluster\ [uuid\:%s] = baremetal2 gateway[uuid:{0}] is not in cluster [uuid:{1}] -# at: src/main/java/org/zstack/compute/host/HostBase.java:259 -# args: vmFailedToMigrate,self.getUuid(),self.getName(),self.getManagementIp() -failed\ to\ migrate\ vm[uuids\:%s]\ on\ host[uuid\:%s,\ name\:%s,\ ip\:%s],\ will\ try\ stopping\ it. = failed to migrate vm[uuids:{0}] on host[uuid:{1}, name:{2}, ip:{3}], will try stopping it. +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:600 +# args: msg.getUuid() +please\ specify\ chassis\ uuid\ or\ chassis\ offering\ uuid\ to\ start\ baremetal2\ instance[uuid\:%s] = please specify chassis uuid or chassis offering uuid to start baremetal2 instance[uuid:{0}] -# at: src/main/java/org/zstack/compute/host/HostBase.java:609 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:611 +# args: msg.getChassisOfferingUuid() +baremetal2\ chassis\ offering[uuid\:%s]\ is\ not\ Enabled = baremetal2 chassis offering[uuid:{0}] is not Enabled + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:711 # args: -host\ is\ connecting,\ ping\ failed = host is connecting, ping failed +do\ not\ set\ chassisUuid\ and\ chassisOfferingUuid\ at\ the\ same\ time = do not set chassisUuid and chassisOfferingUuid at the same time -# at: src/main/java/org/zstack/compute/host/HostBase.java:1085 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:619 # args: -an\ other\ connect\ host\ task\ is\ running,\ cancel\ the\ new\ task\ and\ wait\ return = an other connect host task is running, cancel the new task and wait return +no\ need\ to\ set\ chassisOfferingUuid\ because\ the\ instance\ has\ been\ assigned\ an\ chassis\ already = no need to set chassisOfferingUuid because the instance has been assigned an chassis already -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:282 -# args: msg.getManagementIp() -there\ has\ been\ a\ host\ having\ managementIp[%s] = there has been a host having managementIp[{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:623 +# args: +no\ need\ to\ set\ chassisOfferingUuid\ because\ the\ instance\ has\ been\ assigned\ an\ chassis\ offering\ already = no need to set chassisOfferingUuid because the instance has been assigned an chassis offering already -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:288 -# args: msg.getClusterUuid() -cluster[uuid\:%s]\ is\ not\ existing = cluster[uuid:{0}] is not existing +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:631 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ does\ not\ exist = baremetal2 chassis[uuid:{0}] does not exist -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:378 -# args: vo.getName(),vo.getManagementIp() -after\ connecting,\ host[name\:%s,\ ip\:%s]\ returns\ a\ null\ os\ version = after connecting, host[name:{0}, ip:{1}] returns a null os version +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:636 +# args: msg.getChassisUuid(),bm.getChassisOfferingUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ belonging\ to\ chassis\ offering[uuid\:%s] = baremetal2 chassis[uuid:{0}] is not belonging to chassis offering[uuid:{1}] -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:409 -# args: vo.getClusterUuid(),currentVersion,vo.getName(),vo.getManagementIp(),mineVersion -cluster[uuid\:%s]\ already\ has\ host\ with\ os\ version[%s],\ but\ new\ added\ host[name\:%s\ ip\:%s]\ has\ host\ os\ version[%s] = cluster[uuid:{0}] already has host with os version[{1}], but new added host[name:{2} ip:{3}] has host os version[{4}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:641 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ Enabled = baremetal2 chassis[uuid:{0}] is not Enabled -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:531 -# args: msg.getCancellationApiId() -no\ running\ api[%s]\ task\ on\ hosts = no running api[{0}] task on hosts +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:645 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ has\ already\ been\ allocated = baremetal2 chassis[uuid:{0}] has already been allocated -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:624 -# args: d.getPrimaryStorageUuid() -primary\ storage[uuid\:%s]\ becomes\ disconnected,\ the\ host\ has\ no\ connected\ primary\ storage\ attached = primary storage[uuid:{0}] becomes disconnected, the host has no connected primary storage attached +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:763 +# args: msg.getGatewayUuid(),msg.getChassisUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ in\ the\ same\ cluster\ with\ chassis[uuid\:%s] = baremetal2 gateway[uuid:{0}] is not in the same cluster with chassis[uuid:{1}] -# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:38 -# args: nameips.stream().map( it -> it.get(1, String.class) + "/" + it.get(0, String.class)).collect(Collectors.joining(", ")) -host(s)\ [%s]\ is\ not\ Connected,\ not\ support\ to\ power\ off = host(s) [{0}] is not Connected, not support to power off +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:685 +# args: msg.getZoneUuid() +zone[uuid\:%s]\ is\ specified\ but\ it's\ not\ Enabled,\ can\ not\ create\ baremetal2\ instance\ from\ it = zone[uuid:{0}] is specified but it's not Enabled, can not create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/host/HostSecurityLevelAllocatorFilterExtensionPoint.java:68 -# args: -vm\ security\ level\ not\ consistent\ with\ vms\ running\ on\ host = vm security level not consistent with vms running on host +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:699 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ is\ specified\ but\ it's\ not\ an\ Enabled\ baremetal2\ cluster,\ can\ not\ create\ baremetal2\ instance\ from\ it = cluster[uuid:{0}] is specified but it's not an Enabled baremetal2 cluster, can not create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:204 -# args: host.getUuid(),host.getName(),host.getState() -host[uuid\:%s,\ name\:%s]\ is\ in\ state[%s],\ cannot\ perform\ required\ operation = host[uuid:{0}, name:{1}] is in state[{2}], cannot perform required operation +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:717 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = baremetal2 chassis[uuid:{0}] is not Enabled, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:485 -# args: ret.getError() -operation\ error,\ because\ %s = operation error, because {0} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:722 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ Available,\ can't\ create\ baremetal2\ instance\ from\ it = baremetal2 chassis[uuid:{0}] is not Available, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:377 -# args: vmInstanceVO.getUuid(),vmInstanceVO.getState() -only\ support\ do\ live\ snapshot\ on\ vm\ state[%s],\ but\ vm\ is\ on\ [%s]\ state = only support do live snapshot on vm state[{0}], but vm is on [{1}] state +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:732 +# args: msg.getChassisOfferingUuid() +baremetal2\ chassis\ offering[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = baremetal2 chassis offering[uuid:{0}] is not Enabled, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/host/MevocoHostBaseFactory.java:71 -# args: huuid,cidr -host[uuid\:%s]\ has\ multi\ ips\ in\ cidr[%s] = host[uuid:{0}] has multi ips in cidr[{1}] - -# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:344 -# args: msg.getHostUuid() -host[uuid\:%s]\ can\ not\ find = host[uuid:{0}] can not find +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:743 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = baremetal2 gateway[uuid:{0}] is not Enabled, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:336 -# args: clusterUuids,hypervisorType -cluster[uuids\:%s,\ hypervisorType\:%s]\ are\ not\ exist! = cluster[uuids:{0}, hypervisorType:{1}] are not exist! +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:748 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ Connected,\ can't\ create\ baremetal2\ instance\ from\ it = baremetal2 gateway[uuid:{0}] is not Connected, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:50 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:780 # args: -not\ dest\ host\ found\ in\ db,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = not dest host found in db, can't send change password cmd to the host! +image\ cannot\ be\ empty\ unless\ chassis\ is\ in\ direct\ mode = image cannot be empty unless chassis is in direct mode -# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:51 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:787 # args: -not\ system\ tag\ found\ on\ vm,\ vm\ must\ have\ the\ following\ system\ tag\:\ qemuga,\ if\ you\ installed\ qemu-ga\ yourself,\ please\ use\ CreateSystemTag\ first. = not system tag found on vm, vm must have the following system tag: qemuga, if you installed qemu-ga yourself, please use CreateSystemTag first. +direct\ mode\ not\ support\ choose\ image = direct mode not support choose image -# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:54 -# args: -not\ account\ preference\ found,\ \ send\ change\ password\ cmd\ to\ the\ host! = not account preference found, send change password cmd to the host! +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:794 +# args: msg.getImageUuid() +image[uuid\:%s]\ does\ not\ exist = image[uuid:{0}] does not exist -# at: src/main/java/org/zstack/compute/vm/DeleteVmGC.java:50 -# args: hostUuid -the\ host[uuid\:%s]\ is\ not\ connected = the host[uuid:{0}] is not connected +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:800 +# args: disk.getUuid(),image.getUuid() +Chassis\ disk[%s]\ not\ have\ enough\ capacity\ for\ image[%s] = Chassis disk[{0}] not have enough capacity for image[{1}] -# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:40 -# args: vmUuid,isoUuid -VM[uuid\:%s]\ has\ attached\ ISO[uuid\:%s] = VM[uuid:{0}] has attached ISO[uuid:{1}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:805 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = image[uuid:{0}] is not Enabled, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:48 -# args: vmUuid -All\ vm[uuid\:%s]\ CD-ROMs\ have\ mounted\ ISO = All vm[uuid:{0}] CD-ROMs have mounted ISO +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:810 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ not\ Ready,\ can't\ create\ baremetal2\ instance\ from\ it = image[uuid:{0}] is not Ready, can't create baremetal2 instance from it -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:77 -# args: mac -This\ is\ not\ a\ valid\ MAC\ address\ [%s] = This is not a valid MAC address [{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:815 +# args: msg.getImageUuid(),image.getMediaType() +image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ can\ be\ used\ to\ create\ baremetal2\ instance = image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate can be used to create baremetal2 instance -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:87 -# args: mac -Not\ a\ valid\ MAC\ address\ [%s] = Not a valid MAC address [{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:820 +# args: image.getFormat(),BareMetal2InstanceConstant.IMAGE_FORMAT_FOR_BM +image[uuid\:%s]\ is\ of\ format\:\ %s,\ only\ %s\ can\ be\ used\ to\ create\ baremetal2\ instance = image[uuid:{0}] is of format: {1}, only {2} can be used to create baremetal2 instance -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:90 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:826 +# args: image.getUuid() +image[uuid\:%s]\ is\ not\ baremetal2\ image,\ can't\ create\ baremetal2\ instance\ from\ it = image[uuid:{0}] is not baremetal2 image, can't create baremetal2 instance from it + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:832 +# args: BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE +only\ image\ with\ boot\ mode\ %s\ is\ supported\ to\ create\ baremetal2\ instance = only image with boot mode {0} is supported to create baremetal2 instance + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:841 # args: -Disallowed\ address = Disallowed address +different\ boot\ mode\ between\ the\ image\ and\ chassis/offering = different boot mode between the image and chassis/offering -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:93 -# args: mac -Expected\ unicast\ mac\ address,\ found\ multicast\ MAC\ address\ [%s] = Expected unicast mac address, found multicast MAC address [{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:851 +# args: clusterArchitecture,image.getArchitecture() +the\ architecture\ of\ baremetal2\ cluster[arch\:%s]\ and\ image[arch\:%s]\ don't\ match = the architecture of baremetal2 cluster[arch:{0}] and image[arch:{1}] don't match -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:192 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:863 +# args: msg.getDataDiskOfferingUuids() +not\ all\ disk\ offerings[uuids\:%s]\ are\ Enabled,\ can\ not\ create\ baremetal2\ instance\ from\ them = not all disk offerings[uuids:{0}] are Enabled, can not create baremetal2 instance from them + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:890 # args: -vm[uuid\:\ %s]'s\ state\ is\ not\ Stopped\ now,\ cannot\ operate\ 'changevmimage'\ action = vm[uuid: {0}]'s state is not Stopped now, cannot operate 'changevmimage' action +cannot\ decide\ which\ zone\ the\ baremetal2\ instance\ should\ be\ created\ in = cannot decide which zone the baremetal2 instance should be created in -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:602 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceBase.java:476 # args: -can\ not\ find\ image\ store\ backup\ storage,\ unable\ to\ commit\ volume\ snapshot\ as\ image = can not find image store backup storage, unable to commit volume snapshot as image +baremetal2\ instance[uuid\:%s]\ is\ either\ not\ exist\ or\ not\ Connected,\ cannot\ change\ its\ password = baremetal2 instance[uuid:{0}] is either not exist or not Connected, cannot change its password -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:397 -# args: vivo.getRootVolumeUuid() -cannot\ find\ backupStorage\ for\ volume\:\ %s = cannot find backupStorage for volume: {0} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceManagerImpl.java:386 +# args: releaseTag +%s\ can\ only\ be\ created\ or\ deleted = {0} can only be created or deleted -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:898 -# args: inv.getInventory().getUuid(),state -vm\ running\ on\ local\ storage\ %s\ state\ is\ %s\ not\ running/stopped/paused,\ can\ not\ attach\ volume = vm running on local storage {0} state is {1} not running/stopped/paused, can not attach volume +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceManagerImpl.java:397 +# args: releaseTag +%s\ can\ only\ be\ created\ or\ deleted\ when\ the\ baremetal2\ instance\ is\ Running = {0} can only be created or deleted when the baremetal2 instance is Running -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1120 -# args: pvo.getType(),bsType -Destination\ PrimaryStorageType\ is\ %s,\ but\ the\ selected\ BackupStorageType\ for\ source\ Volume\ is\ %s,\ which\ cannot\ be\ matched = Destination PrimaryStorageType is {0}, but the selected BackupStorageType for source Volume is {1}, which cannot be matched +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:112 +# args: dhcpInterface,dhcpRangeStartIp,dhcpRangeEndIp,dhcpRangeNetmask,dhcpRangeGateway +there\ already\ exists\ a\ baremetal2\ provision\ network\ with\ dhcpInterface\ \=\ %s,\ dhcpRangeStartIp\ \=\ %s,\ dhcpRangeEndIp\ \=\ %s,\ dhcpRangeNetmask\ \=\ %s,\ dhcpRangeGateway\ \=\ %s = there already exists a baremetal2 provision network with dhcpInterface = {0}, dhcpRangeStartIp = {1}, dhcpRangeEndIp = {2}, dhcpRangeNetmask = {3}, dhcpRangeGateway = {4} -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1507 -# args: -direction\ must\ be\ set\ to\ in\ or\ out = direction must be set to in or out +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:123 +# args: msg.getNetworkUuid() +cannot\ update\ baremetal2\ provision\ network[uuid\:%s]\ dhcp\ configuration\ when\ there\ are\ instances\ depending\ on\ it = cannot update baremetal2 provision network[uuid:{0}] dhcp configuration when there are instances depending on it -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1549 -# args: inbound -inboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = inboundBandwidth must be set no more than {0}. +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:141 +# args: netmask +baremetal2\ provision\ network\ dhcp\ range\ netmask\ %s\ is\ invalid = baremetal2 provision network dhcp range netmask {0} is invalid -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1560 -# args: outbound -outboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = outboundBandwidth must be set no more than {0}. +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:147 +# args: begin,end +baremetal2\ provision\ network\ start\ ip\ %s\ and\ stop\ ip\ %s\ do\ not\ belong\ to\ the\ same\ subnet = baremetal2 provision network start ip {0} and stop ip {1} do not belong to the same subnet -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1651 -# args: self.getUuid() -vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ nic\ qos = vm [{0}]' state must be Running or Paused to sync nic qos +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:157 +# args: msg.getNetworkUuid() +cannot\ delete\ baremetal2\ provision\ network[uuid\:%s]\ when\ there\ are\ instances\ depending\ on\ it = cannot delete baremetal2 provision network[uuid:{0}] when there are instances depending on it -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1656 -# args: -vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ nic\ qos = vm [{0}]'s HostUuid is null, cannot sync nic qos +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:171 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ non-baremetal2\ cluster[uuid\:%s] = cannot attach baremetal2 provision network[uuid:{0}] to non-baremetal2 cluster[uuid:{1}] -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2056 -# args: amsg.getVmInstanceUuid() -not\ dest\ host\ found\ in\ db\ by\ uuid\:\ %s,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = not dest host found in db by uuid: {0}, can't send change password cmd to the host! +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:182 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +baremetal2\ provision\ network[uuid\:%s]\ is\ already\ attached\ to\ cluster[uuid\:%s] = baremetal2 provision network[uuid:{0}] is already attached to cluster[uuid:{1}] -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2084 -# args: -state\ is\ not\ correct\ while\ change\ password. = state is not correct while change password. +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:188 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ cluster[uuid\:%s]\ because\ the\ cluster\ already\ have\ one = cannot attach baremetal2 provision network[uuid:{0}] to cluster[uuid:{1}] because the cluster already have one -# at: src/main/java/org/zstack/compute/vm/VmAllocateCdRomFlow.java:55 -# args: spec.getVmInventory().getUuid() -vm[uuid\:%s]\ cdRom\ deviceId\ repetition = vm[uuid:{0}] cdRom deviceId repetition +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:198 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ cluster[uuid\:%s]\ because\ they\ are\ not\ in\ the\ same\ zone = cannot attach baremetal2 provision network[uuid:{0}] to cluster[uuid:{1}] because they are not in the same zone -# at: src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java:81 -# args: v.getUuid() -there\ is\ no\ available\ ipRange\ on\ L3\ network\ [%s] = there is no available ipRange on L3 network [{0}] +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:219 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ cluster[uuid\:%s],\ because\ we\ need\ to\ make\ sure\ that\ every\ gateway\ attached\ to\ the\ clusters\ that\ have\ the\ same\ provision\ network\ attached = cannot attach baremetal2 provision network[uuid:{0}] to cluster[uuid:{1}], because we need to make sure that every gateway attached to the clusters that have the same provision network attached -# at: src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java:49 -# args: spec.getVmInventory().getUuid() -\ Can\ not\ find\ the\ vm's\ host,\ please\ start\ the\ vm[%s],\ then\ mount\ the\ disk = Can not find the vm's host, please start the vm[{0}], then mount the disk +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:241 +# args: +provision\ network\ should\ not\ have\ the\ same\ interface\ name\ with\ l2\ networks\ that\ are\ already\ attached\ to\ the\ cluster = provision network should not have the same interface name with l2 networks that are already attached to the cluster -# at: src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java:68 -# args: iso.getUuid(),host.getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() -cannot\ find\ the\ iso[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ running\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = cannot find the iso[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is running\n2. if the backup storage is in connected status, if not, try reconnecting it +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:251 +# args: msg.getNetworkUuid() +cannot\ detach\ baremetal2\ provision\ network[uuid\:%s]\ when\ there\ are\ running\ instances\ depending\ on\ it = cannot detach baremetal2 provision network[uuid:{0}] when there are running instances depending on it -# at: src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java:92 -# args: imageUuid,spec.getVmInventory().getName(),spec.getVmInventory().getUuid() -cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage.\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = cannot find the image[uuid:{0}] in any connected backup storage. check below:\n1. if the backup storage is attached to the zone where the VM[name: {1}, uuid:{2}] is in\n2. if the backup storage is in connected status, if not, try reconnecting it +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:258 +# args: +networkUuids\ is\ empty = networkUuids is empty -# at: src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java:86 -# args: imageUuid,spec.getVmInventory().getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() -cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = cannot find the image[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is in\n2. if the backup storage is in connected status, if not, try reconnecting it +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:265 +# args: msg.getNetworkUuids() +not\ all\ baremetal2\ provision\ networks\ exist\ in\ %s = not all baremetal2 provision networks exist in {0} -# at: src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java:114 -# args: zoneUuid,isoImageUuid -no\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s]\ contains\ the\ ISO[uuid\:%s] = no backup storage attached to the zone[uuid:{0}] contains the ISO[uuid:{1}] +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java:496 +# args: networkUuid,gatewayUuid,reply.getError() +failed\ to\ prepare\ provision\ network[uuid\:%s]\ in\ gateway[uuid\:%s]\:\ %s = failed to prepare provision network[uuid:{0}] in gateway[uuid:{1}]: {2} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:341 -# args: msg.getVmInstanceUuid(),msg.getIsoUuid() -VM[uuid\:%s]\ already\ has\ an\ ISO[uuid\:%s]\ attached = VM[uuid:{0}] already has an ISO[uuid:{1}] attached +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java:308 +# args: networkUuid,gatewayUuid,reply.getError() +failed\ to\ update\ provision\ network[uuid\:%s]\ in\ gateway[uuid\:%s]\:\ %s = failed to update provision network[uuid:{0}] in gateway[uuid:{1}]: {2} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:500 -# args: ipv4Count -there\ are\ %d\ ipv4\ network\ on\ same\ nic = there are {0} ipv4 network on same nic +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java:650 +# args: msg.getNetworkUuid() +failed\ to\ allocate\ ip\ from\ baremetal2\ provision\ network[uuid\:%s] = failed to allocate ip from baremetal2 provision network[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:133 -# args: msg.getVmInstanceUuid(),vo.getState().toString() -Can\ not\ create\ CD-ROM\ for\ vm[uuid\:%s]\ which\ is\ in\ state[%s]\ = Can not create CD-ROM for vm[uuid:{0}] which is in state[{1}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:73 +# args: +billing\ is\ disabled = billing is disabled -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:141 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:120 # args: -rootDiskSize\ is\ needed\ when\ image\ media\ type\ is\ ISO = rootDiskSize is needed when image media type is ISO +the\ start\ date\ must\ be\ greater\ than\ the\ end\ date = the start date must be greater than the end date -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:151 -# args: msg.getVmInstanceUuid(),msg.getHostUuid() -the\ vm[uuid\:%s]\ is\ already\ on\ host[uuid\:%s] = the vm[uuid:{0}] is already on host[uuid:{1}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:124 +# args: +resourceType\ and\ resourceUuid\ cannot\ be\ empty\ at\ the\ same\ time = resourceType and resourceUuid cannot be empty at the same time -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:207 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:244 # args: -the\ VM\ cannot\ do\ online\ cpu/memory\ update\ because\ it\ is\ not\ of\ NUMA\ architecture.\ Please\ stop\ the\ VM\ then\ do\ the\ cpu/memory\ update\ again = the VM cannot do online cpu/memory update because it is not of NUMA architecture. Please stop the VM then do the cpu/memory update again +the\ minimal\ resource\ unit\ is\ megabyte,\ cannot\ be\ byte = the minimal resource unit is megabyte, cannot be byte -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:213 -# args: vo.getUuid(),vo.getState(),StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), ",") -The\ state\ of\ vm[uuid\:%s]\ is\ %s.\ Only\ these\ state[%s]\ is\ allowed\ to\ update\ cpu\ or\ memory. = The state of vm[uuid:{0}] is {1}. Only these state[{2}] is allowed to update cpu or memory. +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:252 +# args: +price\ must\ be\ 0\ and\ 999999999.99 = price must be 0 and 999999999.99 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:184 -# args: vo.getUuid() -can't\ decrease\ capacity\ when\ vm[uuid\:%s]\ is\ running = can't decrease capacity when vm[uuid:{0}] is running +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:259 +# args: +gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ empty = gpu price must be bound to gpu uuid empty -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:224 -# args: vo.getUuid() -can't\ decrease\ cpu\ of\ vm[uuid\:%s]\ when\ it\ is\ running = can't decrease cpu of vm[uuid:{0}] when it is running +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:266 +# args: price.getSystemTags() +gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ %s = gpu price must be bound to gpu uuid {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:230 -# args: vo.getUuid() -can't\ decrease\ memory\ size\ of\ vm[uuid\:%s]\ when\ it\ is\ running = can't decrease memory size of vm[uuid:{0}] when it is running +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:226 +# args: resourceName +resourceName[%s]\ is\ invalid = resourceName[{0}] is invalid -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:241 -# args: -either\ l3NetworkUuids\ or\ imageUuid\ must\ be\ set = either l3NetworkUuids or imageUuid must be set +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:278 +# args: msg.getAccountUuid() +The\ account[uuid\=%s]\ has\ attach\ price\ table = The account[uuid={0}] has attach price table -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:256 -# args: ip -%s\ is\ not\ a\ valid\ IPv4\ address = {0} is not a valid IPv4 address +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:284 +# args: msg.getUuid() +This\ priceTable[uuid\=%s]\ is\ not\ allowed\ to\ delete = This priceTable[uuid={0}] is not allowed to delete -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:282 -# args: ip,vmNicVO.getUuid() -ip\ address\ [%s]\ already\ set\ to\ vmNic\ [uuid\:%s] = ip address [{0}] already set to vmNic [uuid:{1}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:298 +# args: +accountUuid/tableUuid\ only\ one\ of\ them\ is\ allowed\ to\ be\ set = accountUuid/tableUuid only one of them is allowed to be set -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:267 -# args: ip,rangeVO.getNetworkCidr() -ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [%s] = ip address [{0}] is not in ip range [{1}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:304 +# args: +endDateInLong\ is\ not\ allowed\ to\ be\ negative = endDateInLong is not allowed to be negative -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:276 -# args: ip -%s\ is\ not\ a\ valid\ IPv6\ address = {0} is not a valid IPv6 address +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:308 +# args: +endDateInLong\ and\ setEndDateInLongBaseOnCurrentTime\ are\ not\ allowed\ to\ set\ at\ the\ same\ time = endDateInLong and setEndDateInLongBaseOnCurrentTime are not allowed to set at the same time -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:287 -# args: ip,rangeVO.getStartIp(),rangeVO.getEndIp() -ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [startIp\ %s,\ endIp\ %s] = ip address [{0}] is not in ip range [startIp {1}, endIp {2}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:321 +# args: +endDateInLong\ is\ set,\ no\ modification\ allowed = endDateInLong is set, no modification allowed -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:321 -# args: msg.getVmInstanceUuid(),msg.getL3NetworkUuid() -the\ VM[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = the VM[uuid:{0}] has no nic on the L3 network[uuid:{1}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:329 +# args: +endDateInLong\ cannot\ be\ earlier\ than\ dateInLong = endDateInLong cannot be earlier than dateInLong -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:332 -# args: o,msg.getBootOrder() -invalid\ boot\ device[%s]\ in\ boot\ order%s = invalid boot device[{0}] in boot order{1} +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:336 +# args: +billing\ is\ enable,\ This\ operation\ is\ only\ allowed\ in\ the\ disabled\ state = billing is enable, This operation is only allowed in the disabled state -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:356 -# args: cdRomUuid -The\ cdRom[uuid\:%s]\ does\ not\ exist = The cdRom[uuid:{0}] does not exist +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:451 +# args: +priceKeyName\ is\ null = priceKeyName is null -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:360 -# args: msg.getVmInstanceUuid(),cdRomUuid -VM[uuid\:%s]\ cdRom[uuid\:%s]\ has\ mounted\ the\ ISO = VM[uuid:{0}] cdRom[uuid:{1}] has mounted the ISO +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1084 +# args: currentPriceVO.getDateInLong() +dateInLong\ is\ less\ than\ %s = dateInLong is less than {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:378 -# args: msg.getVmInstanceUuid() -VM[uuid\:%s]\ has\ multiple\ ISOs\ attached,\ specify\ the\ isoUuid\ when\ detaching = VM[uuid:{0}] has multiple ISOs attached, specify the isoUuid when detaching +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:3090 +# args: +please\ set\ the\ correct\ priceUserConfig,\ for\ example\:\ priceUserConfig\:{\nrootVolume\:{\npriceKeyName\:\"priceKeyName\"}} = please set the correct priceUserConfig, for example: priceUserConfig:'{\nrootVolume:{\npriceKeyName:\"priceKeyName\"}'} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:482 -# args: l3Uuid -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ disabled = unable to attach a L3 network. The L3 network[uuid:{0}] is disabled +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:3105 +# args: +please\ set\ the\ correct\ priceUserConfig,\ for\ example\:\ priceUserConfig\:{\nvolume\:{\npriceKeyName\:\"priceKeyName\"}} = please set the correct priceUserConfig, for example: priceUserConfig:'{\nvolume:{\npriceKeyName:\"priceKeyName\"}'} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:553 -# args: staticIp,l3Uuid -the\ static\ IP[%s]\ is\ not\ in\ any\ IP\ range\ of\ the\ L3\ network[uuid\:%s] = the static IP[{0}] is not in any IP range of the L3 network[uuid:{1}] +# at: src/main/java/org/zstack/billing/ResourceSpendingHelper.java:49 +# args: resourceType +unsupported\ billing\ resource\ type\ [%s] = unsupported billing resource type [{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:560 -# args: staticIp,l3Uuid -the\ static\ IP[%s]\ has\ been\ occupied\ on\ the\ L3\ network[uuid\:%s] = the static IP[{0}] has been occupied on the L3 network[uuid:{1}] +# at: src/main/java/org/zstack/cas/CasInterceptor.java:31 +# args: type +there\ is\ no\ such\ type[%s]\ in\ CAS = there is no such type[{0}] in CAS -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:432 -# args: msg.getVmInstanceUuid(),state -unable\ to\ attach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to attach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} +# at: src/main/java/org/zstack/cas/CasLoginBackend.java:76 +# args: loginContext.getUsername() +wrong\ virtual\ ID[name\:%s],\ not\ existing\ or\ wrong\ password = wrong virtual ID[name:{0}], not existing or wrong password -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:446 -# args: newAddedL3Uuids,l2Uuids -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ different\ l2\ networks\ [uuids\:%s] = unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to different l2 networks [uuids:{1}] +# at: src/main/java/org/zstack/cas/CasLoginBackend.java:57 +# args: +missing\ property\ of\ cas\ driver = missing property of cas driver -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:453 -# args: newAddedL3Uuids,l2Uuids -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ l2\ networks\ [uuids\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to l2 networks [uuids:{1}] that have not been attached to any cluster +# at: src/main/java/org/zstack/cas/CasLoginBackend.java:64 +# args: casDriverType +Unsupported\ cas\ driver\:\ %s = Unsupported cas driver: {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:465 -# args: attachedL3Uuids,msg.getVmInstanceUuid() -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach a L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:63 +# args: msg.getUuid() +cannot\ find\ such\ ResourceStackVO\ by\ uuid\ [%s] = cannot find such ResourceStackVO by uuid [{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:472 -# args: attachedL3Uuids,msg.getVmInstanceUuid() -unable\ to\ attach\ a\ non-guest\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach a non-guest L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:67 +# args: validStatus +restart\ resource\ stack\ only\ support\ %s\ status! = restart resource stack only support {0} status! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:485 -# args: l3Uuid -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = unable to attach a L3 network. The L3 network[uuid:{0}] is a system network and vm is a user vm +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:173 +# args: +templateContent\ and\ uuid\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = templateContent and uuid mustn't both be empty or both be set! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:503 -# args: statefulIpv6 -there\ are\ %d\ ipv6\ stateful\ or\ stateless\ network\ on\ same\ nic = there are {0} ipv6 stateful or stateless network on same nic +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:98 +# args: validStatus +expect\ %s\ status! = expect {0} status! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:535 -# args: e.getKey(),newAddedL3Uuids -static\ ip\ l3\ uuid[%s]\ is\ not\ included\ in\ nic\ l3\ [%s] = static ip l3 uuid[{0}] is not included in nic l3 [{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:118 +# args: +templateContent\ and\ templateUuid\ mustn't\ both\ be\ empty! = templateContent and templateUuid mustn't both be empty! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:583 -# args: msg.getVmInstanceUuid(),state -unable\ to\ attach\ the\ nic.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to attach the nic. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:129 +# args: +templateContent\ and\ url\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = templateContent and url mustn't both be empty or both be set! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:590 -# args: vmNicVO.getVmInstanceUuid() -unable\ to\ attach\ the\ nic.\ The\ nic\ has\ been\ attached\ with\ vm[uuid\:\ %s] = unable to attach the nic. The nic has been attached with vm[uuid: {0}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:145 +# args: +only\ admin\ could\ enable/disable\ system\ StackTemplate = only admin could enable/disable system StackTemplate -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:601 -# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() -unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach the nic. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1032 +# args: vo.getName() +cannot\ delete\ or\ update\ system\ template\:\ %s = cannot delete or update system template: {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:606 -# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() -unable\ to\ attach\ the\ nic\ with\ a\ non-guest\ L3\ network.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach the nic with a non-guest L3 network. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:322 +# args: msg.getVmInstanceUuid() +no\ stackUuid\ found\ for\ the\ vmInstance[%s] = no stackUuid found for the vmInstance[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:615 -# args: l3NetworkVO.getUuid() -unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ disabled = unable to attach the nic. Its L3 network[uuid:{0}] is disabled +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:612 +# args: msg.getUuid() +ResourceStackVO\:\ [%s]\ has\ been\ deleted... = ResourceStackVO: [{0}] has been deleted... -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:618 -# args: l3NetworkVO.getUuid() -unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = unable to attach the nic. Its L3 network[uuid:{0}] is a system network and vm is a user vm +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:642 +# args: uuid +ResourceStackVO\ [%s]\ already\ been\ deleted! = ResourceStackVO [{0}] already been deleted! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:625 -# args: l3NetworkVO.getL2NetworkUuid() -unable\ to\ attach\ the\ nic.\ Its\ l2\ network\ [uuid\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = unable to attach the nic. Its l2 network [uuid:{0}] that have not been attached to any cluster +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:871 +# args: +templateContent\ must\ be\ set! = templateContent must be set! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:640 -# args: msg.getVmInstanceUuid(),state -unable\ to\ detach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to detach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:865 +# args: template.getUuid() +template\ [%s]\ chosen\ is\ disabled = template [{0}] chosen is disabled -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:666 -# args: msg.getVmInstanceUuid(),state -vm[uuid\:%s]\ can\ only\ attach\ volume\ when\ state\ is\ Running\ or\ Stopped,\ current\ state\ is\ %s = vm[uuid:{0}] can only attach volume when state is Running or Stopped, current state is {1} +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:955 +# args: p.getParamName(),p.getResourceType() +cannot\ find\ parameters\ for\ %s,\ which\ is\ %s\ type,\ please\ check\ parameters = cannot find parameters for {0}, which is {1} type, please check parameters -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:674 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1025 # args: -image\ mediaType\ is\ ISO\ but\ missing\ root\ disk\ settings = image mediaType is ISO but missing root disk settings +StackTemplateVO\ has\ been\ deleted... = StackTemplateVO has been deleted... -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:678 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1048 # args: -Unexpected\ root\ disk\ settings = Unexpected root disk settings +content\ must\ be\ set\ by\ templateContent\ or\ url! = content must be set by templateContent or url! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:689 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1066 # args: -Missing\ CPU/memory\ settings = Missing CPU/memory settings +get\ null\ content\ input = get null content input -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:693 -# args: -Unexpected\ CPU/memory\ settings = Unexpected CPU/memory settings +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1073 +# args: result.getTemplateVersion() +invalid\ cloudformation\ template\ version\:\ %s = invalid cloudformation template version: {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:881 -# args: cdRomIsoUuid -The\ image[uuid\=%s]\ does\ not\ exist = The image[uuid={0}] does not exist +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1087 +# args: msg.getUuid() +StackTemplateVO\:\ [%s]\ has\ been\ deleted... = StackTemplateVO: [{0}] has been deleted... -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:886 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1385 # args: -Do\ not\ allow\ to\ mount\ duplicate\ ISO = Do not allow to mount duplicate ISO +[cloudformation]\ filterName\ must\ be\ cloudformation\:true\ or\ cloudformation\:false = [cloudformation] filterName must be cloudformation:true or cloudformation:false -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:901 +# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:31 # args: -The\ console\ password\ cannot\ start\ with\ 'password'\ which\ may\ trigger\ a\ VNC\ security\ issue = The console password cannot start with 'password' which may trigger a VNC security issue +get\ null\ element\ in\ template\ content = get null element in template content -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:910 -# args: msg.getVmNicUuid() -vmNic[uuid\:%s]\ is\ not\ attached\ to\ vmInstance = vmNic[uuid:{0}] is not attached to vmInstance +# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:35 +# args: +template\ must\ contain\ [ZStackTemplateFormatVersion] = template must contain [ZStackTemplateFormatVersion] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:917 -# args: msg.getL3NetworkUuid(),msg.getVmNicUuid() -L3\ network[uuid\:%s]\ has\ already\ been\ to\ attached\ vmNic[uuid\:%s] = L3 network[uuid:{0}] has already been to attached vmNic[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:38 +# args: result.getTemplateVersion(),CloudFormationConstant.version +invalid\ ZStackTemplateFormatVersion\:\ [%s,\ expected\:\ %s] = invalid ZStackTemplateFormatVersion: [{0}, expected: {1}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:937 -# args: ipVO.getL3NetworkUuid(),msg.getVmNicUuid() -there\ is\ another\ IPv6\ stateful-dhcp\ network[uuid\:%s]\ attached\ vmNic[uuid\:%s] = there is another IPv6 stateful-dhcp network[uuid:{0}] attached vmNic[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/VmPortMonitorTask.java:124 +# args: l2Uuid +cannot\ find\ l2_bridge_name\ of\ l2[%s]\ from\ systemTag = cannot find l2_bridge_name of l2[{0}] from systemTag -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:926 -# args: ipVO.getL3NetworkUuid(),msg.getVmNicUuid() -there\ is\ another\ IPv4\ network[uuid\:%s]\ attached\ vmNic[uuid\:%s] = there is another IPv4 network[uuid:{0}] attached vmNic[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/VmPortMonitorTask.java:135 +# args: vm.getUuid() +cannot\ find\ default\ ip\ on\ vm[%s] = cannot find default ip on vm[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:955 -# args: l3Vo.getL2NetworkUuid(),oldL3.getL2NetworkUuid() -l2Network\ [uuid\:%s]\ to\ be\ attached\ is\ different\ from\ l2Network\ [uuid\:%s]\ of\ the\ nic = l2Network [uuid:{0}] to be attached is different from l2Network [uuid:{1}] of the nic +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:97 +# args: +cannot\ find\ resource\ of\ properties\ set\ before! = cannot find resource of properties set before! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:974 -# args: vmCdRomVO.getUuid() -The\ CdRom[%s]\ Already\ the\ default = The CdRom[{0}] Already the default +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:152 +# args: value +invalid\ dynamic\ variables,\ which\ must\ contained\ ${\:\ %s = invalid dynamic variables, which must contained $'{: {0}' -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:235 -# args: vo.getUuid(),vo.getName() -vm[uuid\:%s,\ name\:%s]\ has\ been\ deleted = vm[uuid:{0}, name:{1}] has been deleted +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:174 +# args: +verb\ must\ contain\ '\:\:'! = verb must contain '::'! -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:766 -# args: self.getUuid(),l3Uuid -the\ vm[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = the vm[uuid:{0}] has no nic on the L3 network[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:218 +# args: t[0],last.getClass().getName() +need\ List\ for\ resource\ [%s]\ output\ here,\ but\ got\ %s. = need List for resource [{0}] output here, but got {1}. -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:1154 +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:380 # args: -the\ vm\ has\ been\ deleted = the vm has been deleted +Some\ actions\ are\ invalid = Some actions are invalid -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:3822 -# args: isoUuid,psUuid,self.getName(),self.getUuid() -the\ ISO[uuid\:%s]\ is\ on\ backup\ storage\ that\ is\ not\ compatible\ of\ the\ primary\ storage[uuid\:%s]\ where\ the\ VM[name\:%s,\ uuid\:%s]\ is\ on = the ISO[uuid:{0}] is on backup storage that is not compatible of the primary storage[uuid:{1}] where the VM[name:{2}, uuid:{3}] is on +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:253 +# args: +no\ root\ element\ found,\ please\ check\ your\ cfn\ formation! = no root element found, please check your cfn formation! + +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:432 +# args: e.getMessage() +Wrong\ json\ format,\ causes\:\ %s = Wrong json format, causes: {0} + +# at: src/main/java/org/zstack/cloudformation/template/decoder/AbstractCfnRootDecoder.java:14 +# args: +CfnRootDecoder's\ weight\ must\ between\ 0-100,\ 0\ means\ decode\ first,\ default\ is\ 50 = CfnRootDecoder's weight must between 0-100, 0 means decode first, default is 50 + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:45 +# args: +Condition\ body\ cannot\ support\ json\ null\ or\ array! = Condition body cannot support json null or array! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:41 +# args: +Only\ support\ ZStack\ Template\ Functions\ in\ 'Condition'\ field! = Only support ZStack Template Functions in 'Condition' field! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:37 +# args: +Value\ must\ be\ boolean\ in\ 'Condition'\ field = Value must be boolean in 'Condition' field + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:30 +# args: key,es.size() +Condition\ key\:\ %s\ only\ support\ 1\ element\ in\ the\ json\ object\ of\ value,\ but\ got\ %d\ elements! = Condition key: {0} only support 1 element in the json object of value, but got {1} elements! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/DecoderUtils.java:91 +# args: msg +cannot\ find\ such\ msg\:\ %s\ for\ create = cannot find such msg: {0} for create + +# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:56 +# args: +Mapping\ value\ body\ cannot\ support\ null! = Mapping value body cannot support null! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:54 +# args: +Mapping\ value\ body\ cannot\ support\ json\ array! = Mapping value body cannot support json array! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:66 +# args: +mappingName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = mappingName must be found in result, or it is invalid cfn json. + +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:84 +# args: +Mapping\ body\ cannot\ support\ json\ null! = Mapping body cannot support json null! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:82 +# args: +Mapping\ body\ cannot\ support\ non\ map\ value! = Mapping body cannot support non map value! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:57 +# args: +Output\ body\ cannot\ support\ json\ null! = Output body cannot support json null! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:70 +# args: +Description\ in\ Outputs\ must\ be\ String\ type! = Description in Outputs must be String type! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java:59 +# args: +paramName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = paramName must be found in result, or it is invalid cfn json. + +# at: src/main/java/org/zstack/cloudformation/template/decoder/PreParameterDecoder.java:53 +# args: +Parameters\ root\ body\ must\ be\ json\ object! = Parameters root body must be json object! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:145 +# args: +Mappings\ root\ body\ must\ be\ json\ object! = Mappings root body must be json object! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:112 +# args: +resourceName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = resourceName must be found in result, or it is invalid cfn json. + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:123 +# args: +Parameters\ body\ cannot\ support\ null! = Parameters body cannot support null! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:68 +# args: +Resource\ value\ body\ cannot\ support\ null! = Resource value body cannot support null! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:48 +# args: resource.getResourceName(),e.getKey(),resource.getResourceName() +Resource\ %s\ cannot\ depends\ on\ itself,\ please\ check\ %s\ in\ Resource\ [%s] = Resource {0} cannot depends on itself, please check {1} in Resource [{2}] + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:254 +# args: +Resource\ root\ body\ must\ be\ json\ object! = Resource root body must be json object! + +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:216 +# args: +Resource\ Type\ must\ be\ String! = Resource Type must be String! + +# at: src/main/java/org/zstack/cloudformation/template/function/IfTemplateFunction.java:42 +# args: cond +cannot\ find\ condition[%s]\ in\ 'Conditions' = cannot find condition[{0}] in 'Conditions' + +# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:42 +# args: e.getAsString() +expect\ 'true',\ 'false'\ for\ the\ object,\ but\ got\ %s = expect 'true', 'false' for the object, but got {0} + +# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:35 +# args: keys,e.getAsString() +expect\ 'true',\ 'false'\ or\ an\ other\ Condition,\ current\ Conditions\ include\:\ %s,\ but\ got\ %s = expect 'true', 'false' or an other Condition, current Conditions include: {0}, but got {1} + +# at: src/main/java/org/zstack/cloudformation/template/function/SelectTemplateFunction.java:83 +# args: +Fn\:\:Select\ out\ of\ range,\ please\ check\ your\ json\ file! = Fn::Select out of range, please check your json file! + +# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:75 +# args: e.getKey() +only\ functions\ can\ in\ Function,\ but\ found\ %s = only functions can in Function, but found {0} + +# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:90 +# args: +element\ is\ null! = element is null! + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:26 +# args: +duplicate\ nic\ params = duplicate nic params + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:32 +# args: +l3NetworkUuid\ of\ vm\ nic\ can\ not\ be\ null = l3NetworkUuid of vm nic can not be null + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:35 +# args: l3Uuids +l3NetworkUuid\ of\ vm\ nic\ is\ not\ in\ l3[%s] = l3NetworkUuid of vm nic is not in l3[{0}] + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:40 +# args: nic.getOutboundBandwidth() +outbound\ bandwidth[%d]\ of\ vm\ nic\ is\ out\ of\ [8192,\ 32212254720] = outbound bandwidth[{0}] of vm nic is out of [8192, 32212254720] + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:46 +# args: nic.getInboundBandwidth() +inbound\ bandwidth[%d]\ of\ vm\ nic\ is\ out\ of\ [8192,\ 32212254720] = inbound bandwidth[{0}] of vm nic is out of [8192, 32212254720] + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:52 +# args: nic.getMultiQueueNum() +multi\ queue\ num[%d]\ of\ vm\ nic\ is\ out\ of\ [1,256] = multi queue num[{0}] of vm nic is out of [1,256] + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:58 +# args: nic.getL3NetworkUuid(),nic.getState(),VmNicState.enable.toString(),VmNicState.disable.toString() +vm\ nic\ of\ l3[uuid\:%s]\ state[%s]\ is\ not\ %s\ or\ %s\ = vm nic of l3[uuid:{0}] state[{1}] is not {2} or {3} + +# at: src/main/java/org/zstack/compute/VmNicUtils.java:64 +# args: driverType +vm\ nic\ driver\ %s\ not\ support\ yet = vm nic driver {0} not support yet + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:420 +# args: resourceUuid,affinityGroupUuid +VM\ [uuid\:\ %s]\ has\ already\ been\ added\ to\ affinityGroup\ [uuid\:\ %s] = VM [uuid: {0}] has already been added to affinityGroup [uuid: {1}] + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:437 +# args: hostUuid,affinityGroupUuid +There\ are\ other\ VMs\ on\ this\ host\ [uuid\:\ %s]\ belonging\ to\ same\ affinityGroup\ [%s] = There are other VMs on this host [uuid: {0}] belonging to same affinityGroup [{1}] + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:468 +# args: self.getUuid(),host.getUuid(),vmUuid +affinityGroup\ [uuid\:%s]\ reserve\ host\ [uuid\:%s]\ for\ vm\ [uuid\:\ %s]\ failed = affinityGroup [uuid:{0}] reserve host [uuid:{1}] for vm [uuid: {2}] failed + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:538 +# args: inv.getResourceUuid(),self.getUuid() +vm\ [uuid\:%s]\ doesn't\ satisfy\ the\ affinityGroup\ [uuid\:%s] = vm [uuid:{0}] doesn't satisfy the affinityGroup [uuid:{1}] + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupFilterFlow.java:139 +# args: +can\ not\ satisfied\ affinity\ group\ conditions = can not satisfied affinity group conditions + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:42 +# args: VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString(),state.toString() +Vm\ can\ change\ its\ affinityGroup\ only\ in\ state\ [%s,%s],\ but\ vm\ is\ in\ state\ [%s] = Vm can change its affinityGroup only in state [{0},{1}], but vm is in state [{2}] + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:52 +# args: msg.getUuid(),agUuid +Vm\ [uuid\:\ %s]\ is\ already\ added\ to\ affinityGroup\ [uuid\:\ %s] = Vm [uuid: {0}] is already added to affinityGroup [uuid: {1}] + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:77 +# args: affinityGroupUuid +AffinityGroup\ [uuid\:\ %s]\ does\ not\ existed = AffinityGroup [uuid: {0}] does not existed + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:81 +# args: +Can\ not\ operate\ on\ affinity\ group\ created\ by\ system = Can not operate on affinity group created by system + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:88 +# args: affinityGroupUuid +Can\ not\ operate\ on\ affinityGroup\ [uuid\:\ %s]\ which\ is\ not\ enabled = Can not operate on affinityGroup [uuid: {0}] which is not enabled + +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupManagerImpl.java:219 +# args: msg.getAffinityGroupUuid() +cannot\ find\ the\ affinity\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the affinity group[uuid:{0}], it may have been deleted + +# at: src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java:118 +# args: spec.getL3NetworkUuids() +no\ host\ found\ in\ clusters\ that\ has\ attached\ to\ L2Networks\ which\ have\ L3Networks%s = no host found in clusters that has attached to L2Networks which have L3Networks{0} + +# at: src/main/java/org/zstack/compute/allocator/AttachedPrimaryStorageAllocatorFlow.java:79 +# args: psuuids +no\ host\ found\ in\ clusters\ that\ have\ attached\ to\ primary\ storage\ %s = no host found in clusters that have attached to primary storage {0} + +# at: src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java:41 +# args: vm.getUuid() +cannot\ find\ root\ volume\ of\ vm[uuid\:%s] = cannot find root volume of vm[uuid:{0}] + +# at: src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java:84 +# args: requiredPsUuids,vm.getUuid() +no\ host\ found\ in\ clusters\ which\ have\ attached\ to\ all\ primary\ storage\ %s\ where\ vm[uuid\:%s]'s\ volumes\ locate = no host found in clusters which have attached to all primary storage {0} where vm[uuid:{1}]'s volumes locate + +# at: src/main/java/org/zstack/compute/allocator/AvoidHostAllocatorFlow.java:30 +# args: spec.getAvoidHostUuids() +after\ rule\ out\ avoided\ host%s,\ there\ is\ no\ host\ left\ in\ candidates = after rule out avoided host{0}, there is no host left in candidates + +# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:87 +# args: spec.getRequiredBackupStorageUuid(),bsType +the\ backup\ storage[uuid\:%s,\ type\:%s]\ requires\ bound\ primary\ storage,\ however,\ the\ primary\ storage\ has\ not\ been\ added = the backup storage[uuid:{0}, type:{1}] requires bound primary storage, however, the primary storage has not been added + +# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:80 +# args: spec.getImage().getUuid(),spec.getRequiredBackupStorageUuid(),type,psUuids +The\ image[uuid\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[uuids\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = The image[uuid:{0}] is on the backup storage[uuid:{1}, type:{2}] that requires to work with primary storage[uuids:{3}],however, no host found suitable to work with those primary storage + +# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:71 +# args: spec.getImage().getUuid(),name,spec.getRequiredBackupStorageUuid(),spec.getImage().getType(),possiblePrimaryStorageTypes +The\ image[uuid\:%s,\ name\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[types\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = The image[uuid:{0}, name:{1}] is on the backup storage[uuid:{2}, type:{3}] that requires to work with primary storage[types:{4}],however, no host found suitable to work with those primary storage + +# at: src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java:107 +# args: args +No\ host\ with\ %s\ found = No host with {0} found + +# at: src/main/java/org/zstack/compute/allocator/FilterFlow.java:39 +# args: filter.getClass().getSimpleName(),filter.filterErrorReason() +after\ filtering,\ HostAllocatorFilterExtensionPoint[%s]\ returns\ zero\ candidate\ host,\ it\ means\:\ %s = after filtering, HostAllocatorFilterExtensionPoint[{0}] returns zero candidate host, it means: {1} + +# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:56 +# args: +either\ volumeUuid\ or\ volumeSnapshotUuid\ must\ be\ set = either volumeUuid or volumeSnapshotUuid must be set + +# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:75 +# args: +zoneUuids,\ clusterUuids,\ hostUuids\ must\ at\ least\ have\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = zoneUuids, clusterUuids, hostUuids must at least have one be none-empty list, or all is set to true + +# at: src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java:69 +# args: spec.getCpuCapacity(),spec.getMemoryCapacity() +no\ host\ having\ cpu[%s],\ memory[%s\ bytes]\ found = no host having cpu[{0}], memory[{1} bytes] found + +# at: src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java:52 +# args: currentHostOs +no\ candidate\ host\ has\ version[%s] = no candidate host has version[{0}] + +# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:248 +# args: PrimaryStorageState.Enabled,PrimaryStorageState.Disabled,PrimaryStorageStatus.Connected +cannot\ find\ available\ primary\ storage[state\:\ %s\ or\ %s,\ status\:\ %s].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = cannot find available primary storage[state: {0} or {1}, status: {2}]. Check the state/status of primary storage and make sure they have been attached to clusters + +# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:244 +# args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,spec.getDiskSize() +cannot\ find\ available\ primary\ storage[state\:\ %s,\ status\:\ %s,\ available\ capacity\ %s\ bytes].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = cannot find available primary storage[state: {0}, status: {1}, available capacity {2} bytes]. Check the state/status of primary storage and make sure they have been attached to clusters + +# at: src/main/java/org/zstack/compute/allocator/HostSortorChain.java:130 +# args: e.getMessage(),host.getUuid(),e.getMessage() +[Host\ Allocation]\:\ %s\ on\ host[uuid\:%s].\ try\ next\ one.\ %s = [Host Allocation]: {0} on host[uuid:{1}]. try next one. {2} + +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:97 +# args: spec.getHypervisorType() +no\ host\ having\ state\=Enabled\ status\=Connected\ hypervisorType\=%s\ found = no host having state=Enabled status=Connected hypervisorType={0} found + +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:99 +# args: +no\ host\ having\ state\=Enabled\ status\=Connected\ found = no host having state=Enabled status=Connected found + +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:94 +# args: candidates.size(),spec.getHypervisorType() +no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts\ having\ the\ hypervisor\ type\ [%s] = no Enabled hosts found in the [{0}] candidate hosts having the hypervisor type [{1}] + +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:92 +# args: candidates.size() +no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = no Enabled hosts found in the [{0}] candidate hosts + +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:90 +# args: candidates.size() +no\ Connected\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = no Connected hosts found in the [{0}] candidate hosts + +# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:110 +# args: spec.getImage().getUuid(),spec.getImage().getName() +the\ image[uuid\:%s,\ name\:%s]\ is\ deleted\ on\ all\ backup\ storage = the image[uuid:{0}, name:{1}] is deleted on all backup storage + +# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:144 +# args: zoneUuids,spec.getImage().getUuid() +no\ host\ found\ in\ zones[uuids\:%s]\ that\ attaches\ to\ backup\ storage\ where\ image[%s]\ is\ on = no host found in zones[uuids:{0}] that attaches to backup storage where image[{1}] is on + +# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:114 +# args: entry.getKey() +resource\ binding\ not\ support\ type\ %s\ yet = resource binding not support type {0} yet + +# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:133 +# args: resources +no\ available\ host\ found\ with\ binded\ resource\ %s = no available host found with binded resource {0} + +# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:68 +# args: extp.getClass().getName() +InstanceOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = InstanceOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host + +# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:104 +# args: extp.getClass().getName() +DiskOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = DiskOfferingTagAllocatorExtensionPoint[{0}] return zero candidate host + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:108 +# args: +cannot\ bind\ with\ interface\ configured\ with\ vtep\ ip = cannot bind with interface configured with vtep ip + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:64 +# args: bondingName,HostNetworkBondingConstant.BONDING_NAME_MAX +invalid\ bonding\ name[%s],\ it\ must\ be\ shorter\ than\ [%s]\ characters = invalid bonding name[{0}], it must be shorter than [{1}] characters + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:68 +# args: bondingName +invalid\ bonding\ name[%s],\ it\ must\ only\ contains\ letters,\ numbers\ and\ underscores = invalid bonding name[{0}], it must only contains letters, numbers and underscores + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:77 +# args: bondingName,hostUuid +bonding\ card\ can\ not\ have\ occupied\ bondingName\:[%s],\ which\ was\ already\ been\ used\ by\ host[%s]. = bonding card can not have occupied bondingName:[{0}], which was already been used by host[{1}]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:103 +# args: +cannot\ bind\ with\ interface\ corresponding\ to\ the\ management\ network = cannot bind with interface corresponding to the management network + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:115 +# args: hostUuid +bonding\ card\ can\ not\ have\ interfaces\ which\ is\ not\ on\ the\ same\ host[%s]. = bonding card can not have interfaces which is not on the same host[{0}]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:120 +# args: hostUuid +bonding\ card\ can\ not\ have\ occupied\ interfaces,\ which\ was\ already\ been\ used\ by\ host[%s]. = bonding card can not have occupied interfaces, which was already been used by host[{0}]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:125 +# args: hostUuid +bonding\ card\ can\ not\ have\ interfaces\ that\ has\ been\ used\ as\ a\ network\ bridge,\ which\ was\ already\ been\ used\ by\ host[%s]. = bonding card can not have interfaces that has been used as a network bridge, which was already been used by host[{0}]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:152 +# args: interfaceVO.getUuid() +bonding\ card\ can\ not\ have\ interface[%s]\ which\ have\ been\ sriov\ virtualized. = bonding card can not have interface[{0}] which have been sriov virtualized. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:161 +# args: hostUuid +bonding\ card\ can\ not\ have\ interfaces\ with\ different\ speed,\ which\ is\ on\ the\ host[%s]. = bonding card can not have interfaces with different speed, which is on the host[{0}]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:168 +# args: mode,xmitHashPolicy +[%s]\ bonding\ card\ can\ not\ designate\ [%s],\ Only\ mode\ 802.3ad\ support\ specifying\ different\ xmit_hash_policys = [{0}] bonding card can not designate [{1}], Only mode 802.3ad support specifying different xmit_hash_policys + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:181 +# args: mode,size +[%s]\ bonding\ can\ not\ have\ [%s]\ interfaces,\ it\ must\ be\ the\ number\ between[1~2]. = [{0}] bonding can not have [{1}] interfaces, it must be the number between[1~2]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:177 +# args: mode,size +[%s]\ bonding\ card\ can\ not\ have\ [%s]\ interfaces,\ it\ must\ be\ the\ number\ between[1~8]. = [{0}] bonding card can not have [{1}] interfaces, it must be the number between[1~8]. + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:214 +# args: msg.getType() +invalid\ bonding\ type[%s] = invalid bonding type[{0}] + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:242 +# args: +cannot\ delete\ bonding\ corresponding\ to\ the\ management\ network = cannot delete bonding corresponding to the management network + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:247 +# args: +cannot\ delete\ bonding\ configured\ with\ vtep\ ip = cannot delete bonding configured with vtep ip + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java:58 +# args: bondingInv.getHostUuid(),reply.getError() +failed\ to\ add\ linux\ bonding\ to\ host[uuid\:%s]\ \:\ %s = failed to add linux bonding to host[uuid:{0}] : {1} + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java:97 +# args: bondingInv.getHostUuid(),reply.getError() +failed\ to\ update\ linux\ bonding\ on\ host[uuid\:%s]\ \:\ %s = failed to update linux bonding on host[uuid:{0}] : {1} + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java:132 +# args: bondingInv.getHostUuid(),reply.getError() +failed\ to\ remove\ linux\ bonding\ from\ host[uuid\:%s]\ \:\ %s = failed to remove linux bonding from host[uuid:{0}] : {1} + +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:55 +# args: +if\ cluster\ type\ is\ baremetal,\ then\ hypervisorType\ must\ be\ baremetal\ too,\ or\ vice\ versa = if cluster type is baremetal, then hypervisorType must be baremetal too, or vice versa + +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:71 +# args: +only\ kvm\ hosts'\ operating\ system\ can\ be\ updated,\ for\ now = only kvm hosts' operating system can be updated, for now + +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:82 +# args: msg.getUuid() +there\ are\ hosts\ in\ cluster[uuid\:%s]\ in\ the\ PreMaintenance\ state,\ cannot\ update\ cluster\ os\ right\ now = there are hosts in cluster[uuid:{0}] in the PreMaintenance state, cannot update cluster os right now + +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:94 +# args: msg.getUuid() +not\ all\ hosts\ in\ cluster[uuid\:%s]\ are\ in\ the\ Connected\ status,\ cannot\ update\ cluster\ os\ right\ now = not all hosts in cluster[uuid:{0}] are in the Connected status, cannot update cluster os right now + +# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java:45 +# args: r +invalid\ cpu\ pinning\ ref[%s].\ correct\ example\ is\ [1,3\:3-6,^5] = invalid cpu pinning ref[{0}]. correct example is [1,3:3-6,^5] + +# at: src/main/java/org/zstack/compute/cpuPinning/CpuRangeSet.java:58 +# args: word +Invalid\ cpuset\ [%s] = Invalid cpuset [{0}] + +# at: src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningBasicFactory.java:53 +# args: pCpuNum +the\ host\ vm\ located\ only\ have\ %\ CPUs = the host vm located only have % CPUs + +# at: src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningBasicFactory.java:46 +# args: +incorrect\ input\ format,\ only\ accept\ '^[0-9,]+$' = incorrect input format, only accept '^[0-9,]+$' + +# at: src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningFilterFlow.java:37 +# args: +vcpu\ pinning\ pcpu\ id\ >\ host\ cores = vcpu pinning pcpu id > host cores + +# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:81 +# args: +webssh\ server\ is\ not\ running. = webssh server is not running. + +# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:105 +# args: msg.getManagementIp() +managementIp[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = managementIp[{0}] is neither an IPv4 address nor a valid hostname + +# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:115 +# args: msg.getHostUuid(),hostStatus +can\ not\ maintain\ host[uuid\:%s,\ status\:%s]which\ is\ not\ Connected = can not maintain host[uuid:{0}, status:{1}]which is not Connected + +# at: src/main/java/org/zstack/compute/host/HostBase.java:272 +# args: msg.getHostUuid() +host[%s]\ does\ not\ have\ ipmi\ device\ or\ ipmi\ does\ not\ have\ address.After\ config\ ipmi\ address,\ please\ reconnect\ host\ to\ refresh\ host\ ipmi\ information = host[{0}] does not have ipmi device or ipmi does not have address.After config ipmi address, please reconnect host to refresh host ipmi information + +# at: src/main/java/org/zstack/compute/host/HostBase.java:435 +# args: vmFailedToMigrate.keySet(),self.getUuid(),self.getName(),self.getManagementIp() +failed\ to\ migrate\ vm[uuids\:%s]\ on\ host[uuid\:%s,\ name\:%s,\ ip\:%s],\ will\ try\ stopping\ it. = failed to migrate vm[uuids:{0}] on host[uuid:{1}, name:{2}, ip:{3}], will try stopping it. + +# at: src/main/java/org/zstack/compute/host/HostBase.java:841 +# args: +host\ is\ connecting,\ ping\ failed = host is connecting, ping failed + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:63 +# args: host.getUuid() +mock\ power\ off\ host[%s]\ by\ ipmi\ failed. = mock power off host[{0}] by ipmi failed. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:79 +# args: host.getUuid() +power\ off\ host[%s]\ by\ ipmi\ failed. = power off host[{0}] by ipmi failed. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:121 +# args: host.getUuid() +mock\ power\ on\ host[%s]\ by\ ipmi\ failed. = mock power on host[{0}] by ipmi failed. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:131 +# args: host.getUuid() +power\ on\ host[%s]\ by\ ipmi\ failed. = power on host[{0}] by ipmi failed. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:161 +# args: host.getUuid() +mock\ power\ reset\ host[%s]\ by\ ipmi\ failed. = mock power reset host[{0}] by ipmi failed. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:171 +# args: host.getUuid() +power\ reset\ host[%s]\ by\ ipmi\ failed. = power reset host[{0}] by ipmi failed. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:192 +# args: +ipmi\ information\ is\ not\ complete. = ipmi information is not complete. + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:205 +# args: ipmi.getUuid(),rst.getStderr() +host[%s]\ can\ not\ connect\ ipmi[%s],\ because\:%s = host[{0}] can not connect ipmi[{1}], because:{2} + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:202 +# args: ipmi.getUuid() +host[%s]\ got\ unexpected\ return\ value = host[{0}] got unexpected return value + +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:222 +# args: ipmi.getIpmiAddress(),rst.getStderr() +host\ ipmi[%s]\ is\ not\ reachable.because\ %s = host ipmi[{0}] is not reachable.because {1} + +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:264 +# args: msg.getManagementIp() +there\ has\ been\ a\ host\ having\ managementIp[%s] = there has been a host having managementIp[{0}] + +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:270 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ is\ not\ existing = cluster[uuid:{0}] is not existing + +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:364 +# args: vo.getName(),vo.getManagementIp() +after\ connecting,\ host[name\:%s,\ ip\:%s]\ returns\ a\ null\ architecture = after connecting, host[name:{0}, ip:{1}] returns a null architecture + +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:379 +# args: vo.getClusterUuid(),cluster.getArchitecture(),vo.getName(),vo.getManagementIp(),arch +cluster[uuid\:%s]'s\ architecture\ is\ %s,\ not\ match\ the\ host[name\:%s,\ ip\:%s]\ architecture\ %s = cluster[uuid:{0}]'s architecture is {1}, not match the host[name:{2}, ip:{3}] architecture {4} + +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:515 +# args: msg.getCancellationApiId() +no\ running\ api[%s]\ task\ on\ hosts = no running api[{0}] task on hosts + +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:733 +# args: d.getPrimaryStorageUuid() +primary\ storage[uuid\:%s]\ becomes\ disconnected,\ the\ host\ has\ no\ connected\ primary\ storage\ attached = primary storage[uuid:{0}] becomes disconnected, the host has no connected primary storage attached + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:59 +# args: nameips.stream().map( it -> it.get(1, String.class) + "/" + it.get(0, String.class)).collect(Collectors.joining(", ")) +host(s)\ [%s]\ is\ not\ Connected,\ not\ support\ to\ power\ off = host(s) [{0}] is not Connected, not support to power off + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:67 +# args: ipAddress +invalid\ ip\ address\ format[%s] = invalid ip address format[{0}] + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:71 +# args: netmask +invalid\ netmask\ format[%s] = invalid netmask format[{0}] + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:75 +# args: +invalid\ ip\ set,\ it\ must\ be\ set\ with\ netmask = invalid ip set, it must be set with netmask + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:91 +# args: +cannot\ set\ ip\ on\ interface\ corresponding\ to\ the\ management\ network = cannot set ip on interface corresponding to the management network + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:192 +# args: +cannot\ set\ ip\ which\ has\ been\ set\ on\ the\ other\ interfaces = cannot set ip which has been set on the other interfaces + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:126 +# args: +cannot\ set\ ip\ on\ bonding\ slaves = cannot set ip on bonding slaves + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:203 +# args: +cannot\ set\ ip\ on\ bridge\ slaves = cannot set ip on bridge slaves + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:151 +# args: msg.getInterfaceUuid() +invalid\ interface\ uuid = invalid interface uuid + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:168 +# args: +cannot\ set\ ip\ on\ bonding\ corresponding\ to\ the\ management\ network = cannot set ip on bonding corresponding to the management network + +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:213 +# args: msg.getBondingUuid() +invalid\ bonding\ uuid = invalid bonding uuid + +# at: src/main/java/org/zstack/compute/host/HostNetworkInterfaceStateAllocatorFlow.java:141 +# args: +no\ available\ network\ interface\ on\ the\ host\ to\ start\ the\ vm = no available network interface on the host to start the vm + +# at: src/main/java/org/zstack/compute/host/HostSecurityLevelAllocatorFilterExtensionPoint.java:68 +# args: +vm\ security\ level\ not\ consistent\ with\ vms\ running\ on\ host = vm security level not consistent with vms running on host + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:280 +# args: host.getUuid(),host.getName(),host.getState() +host[uuid\:%s,\ name\:%s]\ is\ in\ state[%s],\ cannot\ perform\ required\ operation = host[uuid:{0}, name:{1}] is in state[{2}], cannot perform required operation + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:917 +# args: ret.getError() +operation\ error,\ because\ %s = operation error, because {0} + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:370 +# args: l3Uuid,msg.getHostUuid() +failed\ to\ allocate\ pci\ device\ for\ l3[uuid\:%s]\ on\ host[uuid\:%s] = failed to allocate pci device for l3[uuid:{0}] on host[uuid:{1}] + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:622 +# args: msg.getNetworkInterfaceName(),msg.getHostUuid() +networkInterface[name\:%s]\ of\ host[uuid\:%s]\ can\ not\ find = networkInterface[name:{0}] of host[uuid:{1}] can not find + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:805 +# args: vmInstanceVO.getUuid(),vmInstanceVO.getState() +only\ support\ do\ live\ snapshot\ on\ vm\ state[%s],\ but\ vm\ is\ on\ [%s]\ state = only support do live snapshot on vm state[{0}], but vm is on [{1}] state + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:1389 +# args: ret.getError() +sync\ vm\ port\ config\ failed\:\ %s = sync vm port config failed: {0} + +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:1423 +# args: ret.getError() +set\ vm\ hostname\ failed\:\ %s = set vm hostname failed: {0} + +# at: src/main/java/org/zstack/compute/host/MevocoHostBaseFactory.java:84 +# args: huuid,cidr +host[uuid\:%s]\ has\ multi\ ips\ in\ cidr[%s] = host[uuid:{0}] has multi ips in cidr[{1}] + +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:1058 +# args: msg.getHostUuid() +host[uuid\:%s]\ can\ not\ find = host[uuid:{0}] can not find + +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:408 +# args: rsp.getError() +failed\ to\ update\ interface\ ip,\ because\ %s = failed to update interface ip, because {0} + +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:510 +# args: rsp.getError() +failed\ to\ update\ bonding\ ip,\ because\ %s = failed to update bonding ip, because {0} + +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:1024 +# args: clusterUuids,hypervisorType +cluster[uuids\:%s,\ hypervisorType\:%s]\ are\ not\ exist! = cluster[uuids:{0}, hypervisorType:{1}] are not exist! + +# at: src/main/java/org/zstack/compute/ovs/VSwitchOvsManagerImpl.java:72 +# args: newValue +ovs\ cpu\ pinning\ resource\ config\:[%s]\ format\ error. = ovs cpu pinning resource config:[{0}] format error. + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:136 +# args: msg.getVmNicUuid() +vm\ nic[uuid\:%s]\ doesn't\ exist = vm nic[uuid:{0}] doesn't exist + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:77 +# args: VmVfNicConstant.SRIOVABLE_L2_NETWORK_TYPES +only\ %s\ support\ sriov = only {0} support sriov + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:83 +# args: L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK +%s\ don't\ support\ sriov = {0} don't support sriov + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:93 +# args: l3Uuid +L3\ Network\ [uuid\:%s]\ doesn't\ exist = L3 Network [uuid:{0}] doesn't exist + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:97 +# args: l2Uuid,l3Uuid +related\ l2\ network[uuid\:%s]\ of\ l3\ network[uuid\:%s]\ is\ not\ sriov\ enabled = related l2 network[uuid:{0}] of l3 network[uuid:{1}] is not sriov enabled + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:140 +# args: msg.getVmNicUuid(),msg.getVmNicType() +vm\ nic[uuid\:%s]\ is\ already\ of\ type\ %s,\ no\ need\ to\ change = vm nic[uuid:{0}] is already of type {1}, no need to change + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:146 +# args: +change\ vm\ nic\ type\ only\ when\ the\ vm\ is\ stopped = change vm nic type only when the vm is stopped + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:190 +# args: +cant\ not\ change\ vf\ nic\ to\ normal\ type = cant not change vf nic to normal type + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:197 +# args: +cant\ not\ change\ nic\ to\ vf\ type = cant not change nic to vf type + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicFilterFlow.java:89 +# args: +no\ candidate\ host\ with\ enough\ vf\ nic\ pci\ devices = no candidate host with enough vf nic pci devices + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java:275 +# args: vmType +enableSRIOV\ tag\ is\ not\ supported\ for\ vm\ type\ [%s] = enableSRIOV tag is not supported for vm type [{0}] + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java:476 +# args: vmUuid +vm[uuid\:%s]\ needs\ to\ be\ running\ when\ attach\ vf\ nics,\ but\ no\ hostUuid\ found = vm[uuid:{0}] needs to be running when attach vf nics, but no hostUuid found + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java:499 +# args: hostUuid,l3Uuid +cannot\ find\ available\ vf\ nic\ pci\ device\ on\ host[uuid\:%s]\ for\ l3[uuid\:%s] = cannot find available vf nic pci device on host[uuid:{0}] for l3[uuid:{1}] + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicReserveFlow.java:88 +# args: hostUuid,vmUuid +reserve\ pci\ address\ for\ on\ host[uuid]\ for\ vm\ [uuid\:%s]\ failed, = reserve pci address for on host[uuid] for vm [uuid:{0}] failed, + +# at: src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicKvmBackend.java:49 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ delete\ vHost\ User\ Client\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = failed to delete vHost User Client in host[uuid:{0}] for vm[uuid:{1}] : {2} + +# at: src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicKvmBackend.java:85 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ generate\ vHost\ User\ Client\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = failed to generate vHost User Client in host[uuid:{0}] for vm[uuid:{1}] : {2} + +# at: src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicManagerImpl.java:309 +# args: inv.getUuid(),destHostUuid +cannot\ generate\ vhost\ user\ client\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot generate vhost user client for vm[uuid:{0}] on the destination host[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:66 +# args: VmVdpaNicConstant.VDPA_L2_NETWORK_TYPES +only\ %s\ support\ vdpa = only {0} support vdpa + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:106 +# args: l2Vo.getvSwitchType(),l2Vo.getPhysicalInterface() +can\ not\ create\ %s\ with\ physical\ interface\:[%s]\ which\ was\ already\ been\ used\ by\ another\ vSwitch\ type. = can not create {0} with physical interface:[{1}] which was already been used by another vSwitch type. + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:131 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ do\ not\ support\ ovs-dpdk = cluster[uuid:{0}] do not support ovs-dpdk + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:147 +# args: l2NicName,hostUuid,l2NicName +physical\ interface[%s]\ in\ host[uuid\:%s]\ is\ not\ sriov\ virtualized,\ please\ perform\ sriov\ cutting\ operation\ on\ physical\ interface[%s]. = physical interface[{0}] in host[uuid:{1}] is not sriov virtualized, please perform sriov cutting operation on physical interface[{2}]. + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicKvmBackend.java:49 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ delete\ vdpas\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = failed to delete vdpas in host[uuid:{0}] for vm[uuid:{1}] : {2} + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicKvmBackend.java:86 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ generate\ vdpas\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = failed to generate vdpas in host[uuid:{0}] for vm[uuid:{1}] : {2} + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:650 +# args: hostUuid,l3Uuid +cannot\ find\ available\ vdpa\ nic\ pci\ device\ on\ host[uuid\:%s]\ for\ l3[uuid\:%s] = cannot find available vdpa nic pci device on host[uuid:{0}] for l3[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:263 +# args: vmUuid +vm[uuid\:%s]\ needs\ to\ be\ running\ when\ attach\ vdpa\ nics,\ but\ no\ hostUuid\ found = vm[uuid:{0}] needs to be running when attach vdpa nics, but no hostUuid found + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:688 +# args: inv.getUuid(),destHostUuid +cannot\ generate\ vdpa\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot generate vdpa for vm[uuid:{0}] on the destination host[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:835 +# args: +no\ candidate\ host\ with\ enough\ vdpa\ resource = no candidate host with enough vdpa resource + +# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:63 +# args: +not\ dest\ host\ found\ in\ db,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = not dest host found in db, can't send change password cmd to the host! + +# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:64 +# args: +not\ account\ preference\ found,\ \ send\ change\ password\ cmd\ to\ the\ host! = not account preference found, send change password cmd to the host! + +# at: src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java:160 +# args: srcPath,getManagementServerId() +fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ file\ not\ found\ on\ classpath = fail to attach virtio driver because read md5 of file[{0}] fail in mn[uuid:{1}]: file not found on classpath + +# at: src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java:172 +# args: srcPath,getManagementServerId(),e.getMessage() +fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ %s = fail to attach virtio driver because read md5 of file[{0}] fail in mn[uuid:{1}]: {2} + +# at: src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java:167 +# args: srcPath,getManagementServerId() +fail\ to\ attach\ virtio\ driver\ because\ of\ invalid\ md5\ of\ file[%s]\ in\ mn[uuid\:%s] = fail to attach virtio driver because of invalid md5 of file[{0}] in mn[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/CheckIfCreateTemporaryTemplateFlow.java:105 +# args: spec.getDataVolumeRequiredHostUuids() +only\ host(s)[uuid(s)\:\ %s]\ can\ access\ data\ volume. = only host(s)[uuid(s): {0}] can access data volume. + +# at: src/main/java/org/zstack/compute/vm/CpuTopology.java:71 +# args: cpuNum,cpuSockets,cpuCores,cpuThreads,socketNum,coreNum,threadNum +cpu\ topology\ is\ not\ correct,\ cpuNum[%s],\ configured\ cpuSockets[%s],\ cpuCores[%s],\ cpuThreads[%s];\ Calculated\ cpuSockets[%s],\ cpuCores[%s],\ cpuThreads[%s] = cpu topology is not correct, cpuNum[{0}], configured cpuSockets[{1}], cpuCores[{2}], cpuThreads[{3}]; Calculated cpuSockets[{4}], cpuCores[{5}], cpuThreads[{6}] + +# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:40 +# args: vmUuid,isoUuid +VM[uuid\:%s]\ has\ attached\ ISO[uuid\:%s] = VM[uuid:{0}] has attached ISO[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:48 +# args: vmUuid +All\ vm[uuid\:%s]\ CD-ROMs\ have\ mounted\ ISO = All vm[uuid:{0}] CD-ROMs have mounted ISO + +# at: src/main/java/org/zstack/compute/vm/KvmUserVmVirtIODriverExtension.java:142 +# args: driverFormat +invalid\ virtio\ driver\ device\ format\:\ %s = invalid virtio driver device format: {0} + +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:77 +# args: mac +This\ is\ not\ a\ valid\ MAC\ address\ [%s] = This is not a valid MAC address [{0}] + +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:87 +# args: mac +Not\ a\ valid\ MAC\ address\ [%s] = Not a valid MAC address [{0}] + +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:90 +# args: +Disallowed\ address = Disallowed address + +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:93 +# args: mac +Expected\ unicast\ mac\ address,\ found\ multicast\ MAC\ address\ [%s] = Expected unicast mac address, found multicast MAC address [{0}] + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:251 +# args: +state\ of\ vm[uuid\:%s]\ is\ not\ in\ Running\ state,\ can\ not\ sync\ clock = state of vm[uuid:{0}] is not in Running state, can not sync clock + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:442 +# args: +hot\ plug\ is\ not\ turned\ off,can\ not\ open\ vm\ numa = hot plug is not turned off,can not open vm numa + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:609 +# args: self.getUuid() +vm[uuid\:\ %s]'s\ state\ is\ not\ Stopped\ now,\ cannot\ operate\ 'changevmimage'\ action = vm[uuid: {0}]'s state is not Stopped now, cannot operate 'changevmimage' action + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:662 +# args: self.getUuid() +vm[uuid\:%s]\ cluster\ uuid\ is\ null,\ cannot\ change\ image\ for\ it = vm[uuid:{0}] cluster uuid is null, cannot change image for it + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:675 +# args: self.getUuid(),self.getClusterUuid() +vm[uuid\:%s]\ is\ in\ cluster[uuid\:%s],\ but\ there\ is\ no\ available\ host\ in\ the\ cluster,\ cannot\ change\ image\ for\ the\ vm = vm[uuid:{0}] is in cluster[uuid:{1}], but there is no available host in the cluster, cannot change image for the vm + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:967 +# args: vivo.getRootVolumeUuid(),vivo.getRootVolume().getPrimaryStorageUuid(),msg.getPrimaryStorageUuidForRootVolume() +cannot\ find\ backupStorage\ for\ volume[uuid\:\ %s,\ psUuid\:\ %s],\ required\ primary\ storage\ uuid\:%s = cannot find backupStorage for volume[uuid: {0}, psUuid: {1}], required primary storage uuid:{2} + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1152 +# args: vol.getPrimaryStorageUuid(),requiredPsUuid +can\ not\ find\ backup\ storage,\ unable\ to\ commit\ volume\ snapshot[psUuid\:%s]\ as\ image,\ destination\ required\ PS\ uuid\:%s = can not find backup storage, unable to commit volume snapshot[psUuid:{0}] as image, destination required PS uuid:{1} + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2052 +# args: +direction\ must\ be\ set\ to\ in\ or\ out = direction must be set to in or out + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2132 +# args: struct.inboundBandwidthUpthreshold +inboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = inboundBandwidth must be set no more than {0}. + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2142 +# args: struct.outboundBandwidthUpthreshold +outboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = outboundBandwidth must be set no more than {0}. + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2199 +# args: self.getUuid() +vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ nic\ qos = vm [{0}]' state must be Running or Paused to sync nic qos + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2204 +# args: +vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ nic\ qos = vm [{0}]'s HostUuid is null, cannot sync nic qos + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2661 +# args: amsg.getVmInstanceUuid() +not\ dest\ host\ found\ in\ db\ by\ uuid\:\ %s,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = not dest host found in db by uuid: {0}, can't send change password cmd to the host! + +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2691 +# args: +state\ is\ not\ correct\ while\ change\ password. = state is not correct while change password. + +# at: src/main/java/org/zstack/compute/vm/VmAllocateCdRomFlow.java:56 +# args: spec.getVmInventory().getUuid() +vm[uuid\:%s]\ cdRom\ deviceId\ repetition = vm[uuid:{0}] cdRom deviceId repetition + +# at: src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java:69 +# args: imageUuid,cachedPsUuids +creation\ rely\ on\ image\ cache[uuid\:%s,\ locate\ ps\ uuids\:\ [%s]],\ cannot\ create\ other\ places. = creation rely on image cache[uuid:{0}, locate ps uuids: [{1}]], cannot create other places. + +# at: src/main/java/org/zstack/compute/vm/VmAllocateNicIpFlow.java:83 +# args: v.getL3Invs().get(0).getUuid() +there\ is\ no\ available\ ipRange\ on\ L3\ network\ [%s] = there is no available ipRange on L3 network [{0}] + +# at: src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java:50 +# args: spec.getVmInventory().getUuid() +\ Can\ not\ find\ the\ vm's\ host,\ please\ start\ the\ vm[%s],\ then\ mount\ the\ disk = Can not find the vm's host, please start the vm[{0}], then mount the disk + +# at: src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java:68 +# args: iso.getUuid(),host.getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() +cannot\ find\ the\ iso[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ running\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = cannot find the iso[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is running\n2. if the backup storage is in connected status, if not, try reconnecting it + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:713 +# args: msg.getVmInstanceUuid(),msg.getIsoUuid() +VM[uuid\:%s]\ already\ has\ an\ ISO[uuid\:%s]\ attached = VM[uuid:{0}] already has an ISO[uuid:{1}] attached + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:169 +# args: +either\ l3NetworkUuids\ or\ backupStorageUuid\ must\ be\ set = either l3NetworkUuids or backupStorageUuid must be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:205 +# args: msg.getVmInstanceUuid(),state +unable\ to\ change\ to\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to change to L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:211 +# args: msg.getDestL3NetworkUuid() +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ doesn't\ has\ have\ ip\ range = unable to change to L3 network. The L3 network[uuid:{0}] doesn't has have ip range + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:221 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ different\ l2\ networks\ [uuids\:%s] = unable to change to L3 network. The L3 network[uuid:{0}] are belonged to different l2 networks [uuids:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:228 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ l2\ networks\ [uuids\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = unable to change to L3 network. The L3 network[uuid:{0}] are belonged to l2 networks [uuids:{1}] that have not been attached to any cluster + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:240 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to change to L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:247 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ change\ to\ a\ non-guest\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to change to a non-guest L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:255 +# args: l3Uuid +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ disabled = unable to change to L3 network. The L3 network[uuid:{0}] is disabled + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:258 +# args: l3Uuid +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = unable to change to L3 network. The L3 network[uuid:{0}] is a system network and vm is a user vm + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:942 +# args: staticIp,l3Uuid +the\ static\ IP[%s]\ is\ not\ in\ any\ IP\ range\ of\ the\ L3\ network[uuid\:%s] = the static IP[{0}] is not in any IP range of the L3 network[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:949 +# args: staticIp,l3Uuid +the\ static\ IP[%s]\ has\ been\ occupied\ on\ the\ L3\ network[uuid\:%s] = the static IP[{0}] has been occupied on the L3 network[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:912 +# args: e.getKey(),newAddedL3Uuids +static\ ip\ l3\ uuid[%s]\ is\ not\ included\ in\ nic\ l3\ [%s] = static ip l3 uuid[{0}] is not included in nic l3 [{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:373 +# args: image.getName(),image.getUuid() +the\ image[name\:%s,\ uuid\:%s]\ is\ an\ ISO,\ rootDiskSize\ must\ be\ set = the image[name:{0}, uuid:{1}] is an ISO, rootDiskSize must be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:383 +# args: msg.getVmInstanceUuid(),vo.getState().toString() +Can\ not\ create\ CD-ROM\ for\ vm[uuid\:%s]\ which\ is\ in\ state[%s]\ = Can not create CD-ROM for vm[uuid:{0}] which is in state[{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:391 +# args: vo.getPlatform() +Current\ platform\ %s\ not\ support\ update\ nic\ driver\ yet = Current platform {0} not support update nic driver yet + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:407 +# args: +rootDiskSize\ is\ needed\ when\ image\ media\ type\ is\ ISO = rootDiskSize is needed when image media type is ISO + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:419 +# args: msg.getVmInstanceUuid(),msg.getHostUuid() +the\ vm[uuid\:%s]\ is\ already\ on\ host[uuid\:%s] = the vm[uuid:{0}] is already on host[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:436 +# args: +the\ VM\ cannot\ do\ online\ cpu/memory\ update\ because\ of\ disabling\ Instance\ Offering\ Online\ Modification.\ Please\ stop\ the\ VM\ then\ do\ the\ cpu/memory\ update\ again = the VM cannot do online cpu/memory update because of disabling Instance Offering Online Modification. Please stop the VM then do the cpu/memory update again + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:495 +# args: vo.getUuid(),vo.getState(),StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), ",") +The\ state\ of\ vm[uuid\:%s]\ is\ %s.\ Only\ these\ state[%s]\ is\ allowed\ to\ update\ cpu\ or\ memory. = The state of vm[uuid:{0}] is {1}. Only these state[{2}] is allowed to update cpu or memory. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:452 +# args: vo.getUuid() +can't\ decrease\ capacity\ when\ vm[uuid\:%s]\ is\ running = can't decrease capacity when vm[uuid:{0}] is running + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:482 +# args: +the\ VM\ cannot\ do\ cpu\ hot\ plug\ because\ of\ disabling\ cpu\ hot\ plug.\ Please\ stop\ the\ VM\ then\ do\ the\ cpu\ hot\ plug\ again = the VM cannot do cpu hot plug because of disabling cpu hot plug. Please stop the VM then do the cpu hot plug again + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:488 +# args: +the\ VM\ cannot\ do\ memory\ hot\ plug\ because\ of\ disabling\ memory\ hot\ plug.\ Please\ stop\ the\ VM\ then\ do\ the\ memory\ hot\ plug\ again = the VM cannot do memory hot plug because of disabling memory hot plug. Please stop the VM then do the memory hot plug again + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:506 +# args: vo.getUuid() +can't\ decrease\ cpu\ of\ vm[uuid\:%s]\ when\ it\ is\ running = can't decrease cpu of vm[uuid:{0}] when it is running + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:512 +# args: vo.getUuid() +can't\ decrease\ memory\ size\ of\ vm[uuid\:%s]\ when\ it\ is\ running = can't decrease memory size of vm[uuid:{0}] when it is running + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:523 +# args: +either\ l3NetworkUuids\ or\ imageUuid\ must\ be\ set = either l3NetworkUuids or imageUuid must be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:538 +# args: ip +%s\ is\ not\ a\ valid\ IPv4\ address = {0} is not a valid IPv4 address + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:576 +# args: ip,vmNicVO.getUuid() +ip\ address\ [%s]\ already\ set\ to\ vmNic\ [uuid\:%s] = ip address [{0}] already set to vmNic [uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:557 +# args: ip,rangeVO.getNetworkCidr() +ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [%s] = ip address [{0}] is not in ip range [{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:566 +# args: ip +%s\ is\ not\ a\ valid\ IPv6\ address = {0} is not a valid IPv6 address + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:584 +# args: ip,rangeVO.getStartIp(),rangeVO.getEndIp() +ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [startIp\ %s,\ endIp\ %s] = ip address [{0}] is not in ip range [startIp {1}, endIp {2}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:595 +# args: +could\ not\ set\ ip\ address,\ due\ to\ no\ ip\ address\ is\ specified = could not set ip address, due to no ip address is specified + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:610 +# args: msg.getIp() +static\ ip\ [%s]\ format\ error = static ip [{0}] format error + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:622 +# args: +ipv4\ address\ need\ a\ netmask = ipv4 address need a netmask + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:640 +# args: msg.getIp6() +ip\ address\ [%s]\ already\ set\ to\ vmNic = ip address [{0}] already set to vmNic + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:634 +# args: +ipv6\ address\ need\ a\ prefix = ipv6 address need a prefix + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:654 +# args: msg.getVmInstanceUuid(),msg.getL3NetworkUuid() +the\ VM[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = the VM[uuid:{0}] has no nic on the L3 network[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:661 +# args: msg.getStaticIp(),msg.getVmInstanceUuid() +could\ not\ delete\ static\ ip\ [%s]\ for\ vm\ [uuid\:%s]\ because\ it\ doesn't\ existed = could not delete static ip [{0}] for vm [uuid:{1}] because it doesn't existed + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:673 +# args: o,msg.getBootOrder() +invalid\ boot\ device[%s]\ in\ boot\ order%s = invalid boot device[{0}] in boot order{1} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:696 +# args: +boot\ volume\ cannot\ be\ shareable. = boot volume cannot be shareable. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:700 +# args: msg.getVolumeUuid(),msg.getVmInstanceUuid() +volume[uuid\:%s]\ must\ be\ attached\ to\ vm[uuid\:%s] = volume[uuid:{0}] must be attached to vm[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:705 +# args: msg.getVmInstanceUuid() +the\ vm\ %s\ with\ memory\ snapshots\ do\ not\ support\ setting\ boot\ volume = the vm {0} with memory snapshots do not support setting boot volume + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:718 +# args: type +Unsupported\ Image\ Media\ Type\:\ [%s]\ = Unsupported Image Media Type: [{0}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:733 +# args: cdRomUuid +The\ cdRom[uuid\:%s]\ does\ not\ exist = The cdRom[uuid:{0}] does not exist + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:737 +# args: msg.getVmInstanceUuid(),cdRomUuid +VM[uuid\:%s]\ cdRom[uuid\:%s]\ has\ mounted\ the\ ISO = VM[uuid:{0}] cdRom[uuid:{1}] has mounted the ISO + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:755 +# args: msg.getVmInstanceUuid() +VM[uuid\:%s]\ has\ multiple\ ISOs\ attached,\ specify\ the\ isoUuid\ when\ detaching = VM[uuid:{0}] has multiple ISOs attached, specify the isoUuid when detaching + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:863 +# args: l3Uuid +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ disabled = unable to attach a L3 network. The L3 network[uuid:{0}] is disabled + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:813 +# args: msg.getVmInstanceUuid(),state +unable\ to\ attach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to attach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:819 +# args: msg.getL3NetworkUuid() +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ doesn't\ has\ have\ ip\ range = unable to attach a L3 network. The L3 network[uuid:{0}] doesn't has have ip range + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:829 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ different\ l2\ networks\ [uuids\:%s] = unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to different l2 networks [uuids:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:836 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ l2\ networks\ [uuids\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = unable to attach a L3 network. The L3 network[uuid:{0}] are belonged to l2 networks [uuids:{1}] that have not been attached to any cluster + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:848 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach a L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:855 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ attach\ a\ non-guest\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach a non-guest L3 network. The L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:866 +# args: l3Uuid +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = unable to attach a L3 network. The L3 network[uuid:{0}] is a system network and vm is a user vm + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1300 +# args: e.getMessage() +invalid\ json\ format,\ causes\:\ %s = invalid json format, causes: {0} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:986 +# args: msg.getVmInstanceUuid(),state +unable\ to\ attach\ the\ nic.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to attach the nic. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:993 +# args: vmNicVO.getVmInstanceUuid() +unable\ to\ attach\ the\ nic.\ The\ nic\ has\ been\ attached\ with\ vm[uuid\:\ %s] = unable to attach the nic. The nic has been attached with vm[uuid: {0}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1004 +# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() +unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach the nic. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1009 +# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() +unable\ to\ attach\ the\ nic\ with\ a\ non-guest\ L3\ network.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = unable to attach the nic with a non-guest L3 network. Its L3 network[uuid:{0}] is already attached to the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1018 +# args: l3NetworkVO.getUuid() +unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ disabled = unable to attach the nic. Its L3 network[uuid:{0}] is disabled + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1021 +# args: l3NetworkVO.getUuid() +unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = unable to attach the nic. Its L3 network[uuid:{0}] is a system network and vm is a user vm + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1028 +# args: l3NetworkVO.getL2NetworkUuid() +unable\ to\ attach\ the\ nic.\ Its\ l2\ network\ [uuid\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = unable to attach the nic. Its l2 network [uuid:{0}] that have not been attached to any cluster + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1037 +# args: msg.getVmNicUuid(),nicVO.getType() +could\ not\ update\ nic[uuid\:\ %s]\ state,\ due\ to\ nic\ type[%s]\ not\ support = could not update nic[uuid: {0}] state, due to nic type[{1}] not support + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1043 +# args: msg.getVmNicUuid() +could\ not\ update\ nic[uuid\:\ %s]\ state,\ due\ to\ vm\ not\ support = could not update nic[uuid: {0}] state, due to vm not support + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1060 +# args: vmUuid,state +unable\ to\ detach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = unable to detach a L3 network. The vm[uuid: {0}] is not Running or Stopped; the current state is {1} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1075 +# args: msg.getVmInstanceUuid(),state +vm[uuid\:%s]\ can\ only\ attach\ volume\ when\ state\ is\ Running\ or\ Stopped,\ current\ state\ is\ %s = vm[uuid:{0}] can only attach volume when state is Running or Stopped, current state is {1} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1083 +# args: +image\ mediaType\ is\ ISO\ but\ missing\ root\ disk\ settings = image mediaType is ISO but missing root disk settings + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1087 +# args: +Unexpected\ root\ disk\ settings = Unexpected root disk settings + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1154 +# args: +Unexpected\ data\ disk\ settings.\ dataDiskSizes\ need\ to\ be\ greater\ than\ 0 = Unexpected data disk settings. dataDiskSizes need to be greater than 0 + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1206 +# args: msg.getImageUuid() +at\ least\ one\ of\ field\ platform\ in\ msg\ or\ image[uuid\:%s]\ should\ be\ set = at least one of field platform in msg or image[uuid:{0}] should be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1210 +# args: msg.getImageUuid() +at\ least\ one\ of\ field\ guestOsType\ in\ msg\ or\ image[uuid\:%s]\ should\ be\ set = at least one of field guestOsType in msg or image[uuid:{0}] should be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1214 +# args: msg.getImageUuid() +at\ least\ one\ of\ field\ architecture\ in\ msg\ or\ image[uuid\:%s]\ should\ be\ set = at least one of field architecture in msg or image[uuid:{0}] should be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1349 +# args: errorMsg +Cannot\ set\ the\ following\ properties\ at\ the\ same\ time\:\ %s = Cannot set the following properties at the same time: {0} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1357 +# args: properties +Need\ to\ set\ one\ of\ the\ following\ properties,\ and\ can\ only\ be\ one\ of\ them\:\ %s = Need to set one of the following properties, and can only be one of them: {0} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1249 +# args: +cannot\ create\ vm\ instance\ from\ a\ shareable\ volume. = cannot create vm instance from a shareable volume. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1253 +# args: +could\ not\ create\ vm\ instance\ from\ a\ attached\ volume. = could not create vm instance from a attached volume. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1257 +# args: msg.getVolumeUuid() +volume[uuid\:%s]\ could\ not\ satisfy\ conditions[state\:Enabled\ status\:Ready] = volume[uuid:{0}] could not satisfy conditions[state:Enabled status:Ready] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1293 +# args: +l3NetworkUuids\ and\ vmNicInventories\ mustn't\ both\ be\ empty\ or\ both\ be\ set = l3NetworkUuids and vmNicInventories mustn't both be empty or both be set + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1415 +# args: cdRomIsoUuid +The\ image[uuid\=%s]\ does\ not\ exist = The image[uuid={0}] does not exist + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1420 +# args: +Do\ not\ allow\ to\ mount\ duplicate\ ISO = Do not allow to mount duplicate ISO + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1435 +# args: +The\ console\ password\ cannot\ start\ with\ 'password'\ which\ may\ trigger\ a\ VNC\ security\ issue = The console password cannot start with 'password' which may trigger a VNC security issue + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1440 +# args: +can\ not\ call\ this\ api\ because\ it's\ Deprecated = can not call this api because it's Deprecated + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1457 +# args: vmCdRomVO.getUuid() +The\ CdRom[%s]\ Already\ the\ default = The CdRom[{0}] Already the default + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:271 +# args: vo.getUuid(),vo.getName() +vm[uuid\:%s,\ name\:%s]\ has\ been\ deleted = vm[uuid:{0}, name:{1}] has been deleted + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:595 +# args: vmInv.getUuid(),vmInv.getHostUuid(),reply.getError() +failed\ to\ check\ state\ of\ the\ vm[uuid\:%s]\ on\ the\ host[uuid\:%s],\ %s = failed to check state of the vm[uuid:{0}] on the host[uuid:{1}], {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:602 +# args: vmInv.getUuid(),vmInv.getHostUuid() +got\ an\ unrecognized\ state\ of\ the\ vm[uuid\:%s]\ on\ the\ host[uuid\:%s] = got an unrecognized state of the vm[uuid:{0}] on the host[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:984 +# args: self.getUuid(),l3Uuid +the\ vm[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = the vm[uuid:{0}] has no nic on the L3 network[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:1382 +# args: +the\ vm\ has\ been\ deleted = the vm has been deleted + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:3758 +# args: msg.getUuid() +VM[uuid\:%s]\ state\ is\ not\ Running. = VM[uuid:{0}] state is not Running. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:4837 +# args: isoUuid,psUuid,self.getName(),self.getUuid() +the\ ISO[uuid\:%s]\ is\ on\ backup\ storage\ that\ is\ not\ compatible\ of\ the\ primary\ storage[uuid\:%s]\ where\ the\ VM[name\:%s,\ uuid\:%s]\ is\ on = the ISO[uuid:{0}] is on backup storage that is not compatible of the primary storage[uuid:{1}] where the VM[name:{2}, uuid:{3}] is on + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5325 +# args: self.getHostUuid(),cpuNum - oldCpuNum,struct.alignedMemory - oldMemorySize +host[uuid\:%s]\ capacity\ is\ not\ enough\ to\ offer\ cpu[%s],\ memory[%s\ bytes] = host[uuid:{0}] capacity is not enough to offer cpu[{1}], memory[{2} bytes] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5633 +# args: isoUuid,self.getUuid() +ISO[uuid\:%s]\ is\ not\ attached\ to\ VM[uuid\:%s] = ISO[uuid:{0}] is not attached to VM[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:7168 +# args: cdRomSpecs.size(),max +One\ vm\ cannot\ create\ %s\ CDROMs,\ vm\ can\ only\ add\ %s\ CDROMs = One vm cannot create {0} CDROMs, vm can only add {1} CDROMs + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:8150 +# args: msg.getVmInstanceUuid(),max +VM[uuid\:%s]\ can\ only\ add\ %s\ CDROMs = VM[uuid:{0}] can only add {1} CDROMs + +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:8219 +# args: self.getUuid(),msg.getPriority(),reply.getError() +update\ vm[%s]\ priority\ to\ [%s]\ failed,because\ %s = update vm[{0}] priority to [{1}] failed,because {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:65 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceStartNewCreatedVmExtensionPoint[%s]\ refuses\ to\ create\ vm[uuid\:%s]\ because\ %s = VmInstanceStartNewCreatedVmExtensionPoint[{0}] refuses to create vm[uuid:{1}] because {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:192 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceRebootExtensionPoint[%s]\ refuses\ to\ reboot\ vm[uuid\:%s]\ because\ %s = VmInstanceRebootExtensionPoint[{0}] refuses to reboot vm[uuid:{1}] because {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:234 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceDestroyVmExtensionPoint[%s]\ refuses\ to\ destroy\ vm[uuid\:%s]\ because\ %s = VmInstanceDestroyVmExtensionPoint[{0}] refuses to destroy vm[uuid:{1}] because {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:284 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceStartExtensionPoint[%s]\ refuses\ to\ start\ vm[uuid\:%s]\ because\ %s = VmInstanceStartExtensionPoint[{0}] refuses to start vm[uuid:{1}] because {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1136 +# args: msg.getName() +could\ not\ create\ vm,\ a\ vm\ with\ the\ name\ [%s]\ already\ exists = could not create vm, a vm with the name [{0}] already exists + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2245 +# args: +rootDiskOfferingUuid\ cannot\ be\ null\ when\ create\ vm\ without\ image = rootDiskOfferingUuid cannot be null when create vm without image + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:308 +# args: +Spice\ certificate\ does\ not\ exist,\ Please\ check\ if\ spice\ tls\ is\ enabled = Spice certificate does not exist, Please check if spice tls is enabled + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:492 +# args: msg.getImageUuid(),msg.getZoneUuid() +the\ image[uuid\:%s]\ is\ not\ on\ any\ backup\ storage\ that\ has\ been\ attached\ to\ the\ zone[uuid\:%s] = the image[uuid:{0}] is not on any backup storage that has been attached to the zone[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:565 +# args: bss.get(0).getUuid(),bss.get(0).getType() +no\ primary\ storage\ accessible\ to\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ is\ found = no primary storage accessible to the backup storage[uuid:{0}, type:{1}] is found + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:586 +# args: psUuids,zoneUuid +the\ primary\ storages[uuids\:%s]\ has\ not\ attached\ any\ cluster\ on\ the\ zone[uuid\:%s] = the primary storages[uuids:{0}] has not attached any cluster on the zone[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:605 +# args: psUuids +no\ l2Networks\ found\ in\ clusters\ that\ have\ attached\ to\ primary\ storages[uuids\:%s] = no l2Networks found in clusters that have attached to primary storages[uuids:{0}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:672 +# args: image.getName(),image.getUuid() +zoneUuid\ must\ be\ set\ because\ the\ image[name\:%s,\ uuid\:%s]\ is\ on\ multiple\ backup\ storage = zoneUuid must be set because the image[name:{0}, uuid:{1}] is on multiple backup storage + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1067 +# args: +CreateVmInstanceMsg\ cannot\ be\ null = CreateVmInstanceMsg cannot be null + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1158 +# args: StringUtils.join(errorCodes.stream().map(ErrorCode::getDescription).collect(Collectors.toList()), ", ") +handle\ system\ tag\ fail\ when\ creating\ vm\ because\ [%s] = handle system tag fail when creating vm because [{0}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1589 +# args: tuple.get(0, String.class),tuple.get(1, String.class) +unable\ to\ enable\ this\ function.\ There\ are\ multi\ nics\ of\ L3\ network[uuid\:%s]\ in\ the\ vm[uuid\:\ %s] = unable to enable this function. There are multi nics of L3 network[uuid:{0}] in the vm[uuid: {1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1623 +# args: hostname,tag +hostname[%s]\ specified\ in\ system\ tag[%s]\ is\ not\ a\ valid\ domain\ name = hostname[{0}] specified in system tag[{1}] is not a valid domain name + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1635 +# args: hostnameCount +only\ one\ hostname\ system\ tag\ is\ allowed,\ but\ %s\ got = only one hostname system tag is allowed, but {0} got + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1660 +# args: ip,sysTag +%s\ is\ not\ a\ valid\ ip\ address.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = {0} is not a valid ip address. Please correct your system tag[{1}] of static IP + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1666 +# args: ip,l3Uuid,sysTag +IP[%s]\ is\ already\ used\ on\ the\ L3\ network[uuid\:%s].\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = IP[{0}] is already used on the L3 network[uuid:{1}]. Please correct your system tag[{2}] of static IP + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1683 +# args: ip,l3Uuid,cr.getReason() +IP[%s]\ is\ not\ available\ on\ the\ L3\ network[uuid\:%s]\ because\:\ %s = IP[{0}] is not available on the L3 network[uuid:{1}] because: {2} + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1706 +# args: tag,sameTag.getResourceUuid(),hostname,l3Uuid +conflict\ hostname\ in\ system\ tag[%s];\ there\ has\ been\ a\ VM[uuid\:%s]\ having\ hostname[%s]\ on\ L3\ network[uuid\:%s] = conflict hostname in system tag[{0}]; there has been a VM[uuid:{1}] having hostname[{2}] on L3 network[uuid:{3}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1737 +# args: o,order +invalid\ boot\ device[%s]\ in\ boot\ order[%s] = invalid boot device[{0}] in boot order[{1}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1753 +# args: +cpuSockets\ must\ be\ an\ integer = cpuSockets must be an integer + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1762 +# args: +cpuCores\ must\ be\ an\ integer = cpuCores must be an integer + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1771 +# args: +cpuThreads\ must\ be\ an\ integer = cpuThreads must be an integer + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1782 +# args: resourceUuid +Already\ have\ one\ userdata\ systemTag\ for\ vm[uuid\:\ %s]. = Already have one userdata systemTag for vm[uuid: {0}]. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1808 +# args: +Shouldn't\ be\ more\ than\ one\ userdata\ systemTag\ for\ one\ vm. = Shouldn't be more than one userdata systemTag for one vm. + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1932 +# args: type +vm\ machine\ type\ requires\ [q35,\ pc,\ virt],\ but\ get\ [%s] = vm machine type requires [q35, pc, virt], but get [{0}] + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1992 +# args: systemTag,SecurityElementEnableTokenByTag +invalid\ securityElementEnable[%s],\ %s\ is\ not\ securityElementEnable\ tag = invalid securityElementEnable[{0}], {1} is not securityElementEnable tag + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1995 +# args: systemTag,SecurityElementEnableTokenByTag +invalid\ securityElementEnable[%s],\ %s\ is\ not\ boolean\ class = invalid securityElementEnable[{0}], {1} is not boolean class + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2022 +# args: systemTag,usbRedirectTokenByTag +invalid\ usbRedirect[%s],\ %s\ is\ not\ usbRedirect\ tag = invalid usbRedirect[{0}], {1} is not usbRedirect tag + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2025 +# args: systemTag,usbRedirectTokenByTag +invalid\ usbRedirect[%s],\ %s\ is\ not\ boolean\ class = invalid usbRedirect[{0}], {1} is not boolean class + +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2561 +# args: ref.getResourceUuid() +the\ resource[uuid\:%s]\ is\ a\ ROOT\ volume,\ you\ cannot\ change\ its\ owner,\ instead,change\ the\ owner\ of\ the\ VM\ the\ root\ volume\ belongs\ to = the resource[uuid:{0}] is a ROOT volume, you cannot change its owner, instead,change the owner of the VM the root volume belongs to + +# at: src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java:54 +# args: spec.getDestHost().getUuid(),pinv.getUuid() +Failed\ to\ instantiate\ volume.\ Because\ vm's\ host[uuid\:\ %s]\ and\ allocated\ primary\ storage[uuid\:\ %s]\ is\ not\ connected. = Failed to instantiate volume. Because vm's host[uuid: {0}] and allocated primary storage[uuid: {1}] is not connected. + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:211 +# args: msg.getMac() +Duplicate\ mac\ address\ [%s] = Duplicate mac address [{0}] + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:221 +# args: vmType +clean\ traffic\ is\ not\ supported\ for\ vm\ type\ [%s] = clean traffic is not supported for vm type [{0}] + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:100 +# args: KVMGlobalConfig.MAX_DATA_VOLUME_NUM.value(int.class) +The\ number\ of\ data\ volumes\ exceeds\ the\ limit[num\:\ %s],\ please\ reduce\ the\ number\ of\ data\ volumes\ during\ vm\ creation. = The number of data volumes exceeds the limit[num: {0}], please reduce the number of data volumes during vm creation. + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:130 +# args: VmInstanceState.Stopped,msg.getVmInstanceUuid() +Can\ not\ set\ security\ level\ to\ not\ %s\ vm\ [uuid\:%s] = Can not set security level to not {0} vm [uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:147 +# args: +The\ operation\ only\ allows\ on\ user\ vm = The operation only allows on user vm + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:177 +# args: msg.getVmInstanceUuid(),volumeVOS.stream().map(VolumeVO::getUuid).collect(Collectors.toList()),primaryStorageUuid,(totalCapacity - snapshotsCapacity) * msg.getNames().size(),primaryStorageVO.getCapacity().getAvailableCapacity() +there\ are\ not\ enough\ capacity\ for\ full\ vm\ clone\ to\ vm[uuid\:\ %s],\ volumes[uuid\:\ %s]\ on\ primary\ storage[uuid\:\ %s]\ required\:\ %s\ bytes,\ current\ available\ capacity\ is\ %s\ bytes = there are not enough capacity for full vm clone to vm[uuid: {0}], volumes[uuid: {1}] on primary storage[uuid: {2}] required: {3} bytes, current available capacity is {4} bytes + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:191 +# args: msg.getVmNicUuid() +The\ nic\ [%s%s]\ is\ not\ mounted\ on\ the\ VM = The nic [{0}{1}] is not mounted on the VM + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:197 +# args: +The\ operation\ only\ allows\ on\ user\ vm\ = The operation only allows on user vm + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:202 +# args: vmInstanceVO.getUuid() +The\ operation\ only\ allows\ when\ vm\ [%s]\ state\ is\ stopped\ = The operation only allows when vm [{0}] state is stopped + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:231 +# args: msg.getVmInstanceUuid() +user\ has\ no\ privilege\ to\ change\ image\ of\ vm\ %s = user has no privilege to change image of vm {0} + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:243 +# args: +do\ not\ change\ vm\ image\ when\ it's\ not\ stopped = do not change vm image when it's not stopped + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:260 +# args: msg.getVmInstanceUuid() +make\ sure\ the\ primary\ storage\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = make sure the primary storage vm[uuid:{0}] was on is Enabled and Connected + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:275 +# args: msg.getVmInstanceUuid() +make\ sure\ the\ last\ host\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = make sure the last host vm[uuid:{0}] was on is Enabled and Connected + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:285 +# args: msg.getVmInstanceUuid() +vm[uuid\:%s]\ has\ no\ default\ l3,\ cannot\ change\ image\ for\ it = vm[uuid:{0}] has no default l3, cannot change image for it + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:305 +# args: msg.getVmInstanceUuid(),msg.getImageUuid() +instance[uuid\:%s]\ cannot\ be\ changed\ image\ to\ image[uuid\:%s] = instance[uuid:{0}] cannot be changed image to image[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:314 +# args: +either\ uuid\ or\ account\ or\ password\ must\ be\ set = either uuid or account or password must be set + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:327 +# args: msg.getDirection() +direction\ must\ be\ set\ in\ (in,\ out),\ but\ was\ %s = direction must be set in (in, out), but was {0} + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:333 +# args: +Monitor\ number\ must\ be\ 1\ or\ 2\ or\ 4. = Monitor number must be 1 or 2 or 4. + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:341 +# args: +outboundBandwidth\ and\ inboundBandwidth\ must\ be\ set\ at\ lease\ one. = outboundBandwidth and inboundBandwidth must be set at lease one. + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:350 +# args: +the\ nic\ can't\ apply\ Qos\ with\ the\ port\ mirror\ service\ at\ same\ time. = the nic can't apply Qos with the port mirror service at same time. + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:359 +# args: msg.getUuid() +nic\ id\:\ %s\ does\ not\ exist... = nic id: {0} does not exist... + +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:370 +# args: +The\ 'uuids'\ parameter\ must\ belong\ to\ the\ VmInstanceVO\ or\ HostVO = The 'uuids' parameter must belong to the VmInstanceVO or HostVO + +# at: src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java:261 +# args: state,VmInstanceState.Stopped +vm\ current\ state[%s],\ modify\ virtio\ requires\ the\ vm\ state[%s] = vm current state[{0}], modify virtio requires the vm state[{1}] + +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:111 +# args: +wrong\ format\ of\ password\ strength\ config = wrong format of password strength config + +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:114 +# args: +minimum\ can\ not\ be\ larger\ than\ maximum = minimum can not be larger than maximum + +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:74 +# args: minimum,maximum +password\ length\ must\ be\ [%s-%s] = password length must be [{0}-{1}] + +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:93 +# args: +password\ does\ not\ match\ numbers,\ uppercase\ and\ lowercase,\ and\ special\ character\ combinations = password does not match numbers, uppercase and lowercase, and special character combinations + +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:117 +# args: resourceUuid,vmInstanceUuid +missing\ parameter,\ resourceUuid\:\ %s,\ vmInstanceUuid\:\ %s\ is\ requested = missing parameter, resourceUuid: {0}, vmInstanceUuid: {1} is requested + +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:153 +# args: vmInstanceUuid +missing\ parameter,\ vmInstanceUuid\:\ %s\ is\ requested = missing parameter, vmInstanceUuid: {0} is requested + +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:334 +# args: vmInstanceUuid +cannot\ find\ vm\ with\ uuid\:\ %s = cannot find vm with uuid: {0} + +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:338 +# args: resourceUuid +cannot\ find\ vm\ device\ with\ uuid\:\ %s = cannot find vm device with uuid: {0} + +# at: src/main/java/org/zstack/compute/vm/numa/CommonVmNumaBasicFactory.java:38 +# args: vmUuid,hostUuid +vm[%s]\ start\ fail,because\ numa\ is\ enable\ but\ host[%s]\ not\ have\ numa\ node = vm[{0}] start fail,because numa is enable but host[{1}] not have numa node + +# at: src/main/java/org/zstack/compute/vm/numa/CommonVmNumaBasicFactory.java:41 +# args: vmUuid +vm[%s]\ start\ fail,because\ numa\ is\ enable\ but\ cpu\ not\ pin = vm[{0}] start fail,because numa is enable but cpu not pin + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:45 +# args: +hot\ plug\ not\ close = hot plug not close + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:49 +# args: +vm\ cpu\ not\ all\ pinning = vm cpu not all pinning + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:53 +# args: entry.getKey().toString() +cpu[%s]\ not\ pin\ in\ a\ same\ host\ numa\ node = cpu[{0}] not pin in a same host numa node + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:57 +# args: vmUuid,String.join(VmNumaConstant.RULES_SEPARATOR, errors) +vm[%s]\ start\ fail,because\ numa\ is\ enable\ but\:\ %s = vm[{0}] start fail,because numa is enable but: {1} + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaFilterFlow.java:52 +# args: +No\ host\ is\ available\ to\ create\ vm\ Instance.Because\ vNuma\ vms\ need\ to\ be\ created\ on\ hosts\ with\ same\ numa,\ but\ no\ hosts\ is\ available\ after\ filter\ primary\ vm's\ host = No host is available to create vm Instance.Because vNuma vms need to be created on hosts with same numa, but no hosts is available after filter primary vm's host + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaManagerImpl.java:92 +# args: +fail\ to\ set\ vm\ numa,\ incorrect\ input\ format,only\ accept\ true\ or\ false = fail to set vm numa, incorrect input format,only accept true or false + +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaUtils.java:46 +# args: word +invalid\ cpu\ set\ [%s] = invalid cpu set [{0}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:98 +# args: msg.getHostUuid(),refVO.getHostGroupUuid() +the\ host[uuid\:%s]\ already\ attached\ to\ host\ scheduling\ group[uuid\:%s] = the host[uuid:{0}] already attached to host scheduling group[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:107 +# args: +host\ clusterUuid\ is\ null = host clusterUuid is null + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:111 +# args: +hosts\ that\ you\ can\ add\ to\ a\ host\ scheduling\ group\ must\ be\ enabled\ and\ connected\ to\ the\ MN. = hosts that you can add to a host scheduling group must be enabled and connected to the MN. + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:117 +# args: hostVO.getUuid(),hostVO.getZoneUuid(),hostGroup.getUuid(),hostGroup.getZoneUuid() +unmatched\ zone\ detected,\ host[uuid\:\ %s,\ zone\ uuid\:\ %s]'s\ zone\ is\ different\ from\ host\ sheduling\ rule\ group[uuid\:\ %s,\ zone\ uuid\:\ %s] = unmatched zone detected, host[uuid: {0}, zone uuid: {1}]'s zone is different from host sheduling rule group[uuid: {2}, zone uuid: {3}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:132 +# args: msg.getVmUuid(),refVO.getVmGroupUuid() +vm[uuid\:%s]\ already\ attached\ to\ vm\ scheduling\ group[uuid\:%s] = vm[uuid:{0}] already attached to vm scheduling group[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:145 +# args: vm.getUuid(),vm.getZoneUuid(),groupVO.getUuid(),groupVO.getZoneUuid() +unmatched\ zone\ detected,\ vm[uuid\:\ %s,\ zone\ uuid\:\ %s]'s\ zone\ is\ different\ from\ vm\ sheduling\ rule\ group[uuid\:\ %s,\ zone\ uuid\:\ %s] = unmatched zone detected, vm[uuid: {0}, zone uuid: {1}]'s zone is different from vm sheduling rule group[uuid: {2}, zone uuid: {3}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:161 +# args: VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString(),vm.getState().toString() +vm\ can\ change\ its\ vm\ scheduling\ group\ only\ in\ state\ [%s,%s],\ but\ vm\ is\ in\ state\ [%s] = vm can change its vm scheduling group only in state [{0},{1}], but vm is in state [{2}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:171 +# args: +cannot\ operate\ vpc\ vm\ scheduling\ group = cannot operate vpc vm scheduling group + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:209 +# args: +zoneUuid\ is\ not\ null = zoneUuid is not null + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:399 +# args: +the\ vm\ scheduling\ group[uuid\:%s]\ has\ already\ had\ a\ executed\ exclusive\ vm\ or\ affinitive\ vm\ scheduling\ policy\ attached.\ you\ cannot\ attach\ either\ of\ the\ two\ scheduling\ policies\ that\ require\ execution\ to\ the\ group\ again = the vm scheduling group[uuid:{0}] has already had a executed exclusive vm or affinitive vm scheduling policy attached. you cannot attach either of the two scheduling policies that require execution to the group again + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleFilterFlow.java:132 +# args: +can\ not\ satisfied\ vm\ scheduling\ rule\ group\ conditions = can not satisfied vm scheduling rule group conditions + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:158 +# args: self.getUuid(),host.getUuid(),vmUuid +vm\ scheduling\ group[uuid\:%s]\ reserve\ host\ [uuid\:%s]\ for\ vm\ [uuid\:\ %s]\ failed = vm scheduling group[uuid:{0}] reserve host [uuid:{1}] for vm [uuid: {2}] failed + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:392 +# args: vmInv.getUuid(),hostUuid,refVO.getVmGroupUuid() +vm[uuid\:%s]\ is\ now\ running\ on\ host[uuid\:%s],which\ does\ not\ comply\ with\ the\ scheduling\ rule\ associated\ with\ vm\ scheduling\ group[uuid\:%s]. = vm[uuid:{0}] is now running on host[uuid:{1}],which does not comply with the scheduling rule associated with vm scheduling group[uuid:{2}]. + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:402 +# args: msg.getVmGroupUuid() +hostGroup[uuid\:%s]\ is\ no\ host = hostGroup[uuid:{0}] is no host + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:407 +# args: msg.getVmUuid(),hostUuid,VMSchedulingRuleType.AFFINITY.toString(),msg.getVmGroupUuid() +vm[uuid\:%s]\ is\ now\ running\ on\ host[uuid\:%s],\ which\ does\ not\ comply\ with\ the\ scheduling\ rule[%s]\ associated\ with\ vm\ scheduling\ group[uuid\:%s]. = vm[uuid:{0}] is now running on host[uuid:{1}], which does not comply with the scheduling rule[{2}] associated with vm scheduling group[uuid:{3}]. + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:414 +# args: msg.getVmUuid(),hostUuid,VMSchedulingRuleType.ANTIAFFINITY.toString(),msg.getVmGroupUuid() +vm[uuid\:%s]\ is\ now\ running\ on\ host[uuid\:%s],which\ does\ not\ comply\ with\ the\ scheduling\ rule[%s]\ associated\ with\ vm\ scheduling\ group[uuid\:%s]. = vm[uuid:{0}] is now running on host[uuid:{1}],which does not comply with the scheduling rule[{2}] associated with vm scheduling group[uuid:{3}]. + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java:82 +# args: msg.getHostGroupUuid() +cannot\ find\ the\ host\ scheduling\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the host scheduling group[uuid:{0}], it may have been deleted + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java:95 +# args: msg.getVmSchedulingRuleUuid() +cannot\ find\ the\ vm\ scheduling\ rule[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the vm scheduling rule[uuid:{0}], it may have been deleted + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java:108 +# args: msg.getVmSchedulingRuleGroupUuid() +cannot\ find\ the\ vm\ scheduling\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the vm scheduling group[uuid:{0}], it may have been deleted + +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:86 +# args: msg.getAllocatorStrategy() +unsupported\ host\ allocation\ strategy[%s] = unsupported host allocation strategy[{0}] + +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:72 +# args: msg.getType() +unsupported\ instance\ offering\ type[%s] = unsupported instance offering type[{0}] + +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:76 +# args: msg.getCpuNum() +cpu\ num[%s]\ is\ less\ than\ 1 = cpu num[{0}] is less than 1 + +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:80 +# args: msg.getMemorySize() +memory\ size[%s\ bytes]\ is\ less\ than\ 16M,\ no\ modern\ operating\ system\ is\ likely\ able\ to\ boot\ with\ such\ small\ memory\ size = memory size[{0} bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size + +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:92 +# args: msg.getAllocationStrategy() +unsupported\ primary\ storage\ allocation\ strategy[%s] = unsupported primary storage allocation strategy[{0}] + +# at: src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java:1043 +# args: resourceUuid +Already\ have\ one\ userdata\ systemTag\ for\ instanceOffering[uuid\:\ %s]. = Already have one userdata systemTag for instanceOffering[uuid: {0}]. + +# at: src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java:1108 +# args: +Shouldn't\ be\ more\ than\ one\ systemTag\ for\ one\ instanceOffering. = Shouldn't be more than one systemTag for one instanceOffering. + +# at: src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java:1085 +# args: resourceUuid +Already\ have\ one\ userdata\ systemTag\ for\ diskOffering[uuid\:\ %s]. = Already have one userdata systemTag for diskOffering[uuid: {0}]. + +# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:104 +# args: +the\ console\ agent\ is\ not\ connected;\ it's\ mostly\ like\ the\ management\ node\ just\ starts,\ please\ wait\ for\ the\ console\ agent\ connected,\ or\ you\ can\ reconnect\ it\ manually\ if\ disconnected\ for\ a\ long\ time. = the console agent is not connected; it's mostly like the management node just starts, please wait for the console agent connected, or you can reconnect it manually if disconnected for a long time. + +# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:125 +# args: vm.getUuid() +cannot\ find\ host\ IP\ of\ the\ vm[uuid\:%s],\ is\ the\ vm\ running??? = cannot find host IP of the vm[uuid:{0}], is the vm running??? + +# at: src/main/java/org/zstack/console/ConsoleApiInterceptor.java:49 +# args: msg.getVmInstanceUuid(),state +Console\ is\ only\ available\ when\ the\ VM[uuid\:%s]\ is\ Running\ or\ Crashed,\ but\ the\ current\ state\ is\ %s = Console is only available when the VM[uuid:{0}] is Running or Crashed, but the current state is {1} + +# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:133 +# args: uri.toString() +establish\ VNC\:\ unexpected\ uri\:\ %s = establish VNC: unexpected uri: {0} + +# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:198 +# args: ret.getError() +unable\ to\ check\ console\ proxy\ availability,\ because\ %s = unable to check console proxy availability, because {0} + +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:189 +# args: +Ansible\ private\ key\ not\ found. = Ansible private key not found. + +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:387 +# args: uuid +invalid\ management\ node\ uuid[%s] = invalid management node uuid[{0}] + +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:520 +# args: +failed\ to\ configure\ consoleProxyOverriddenIp[code\:%d]\ or\ consoleProxyPort[code\:%d] = failed to configure consoleProxyOverriddenIp[code:{0}] or consoleProxyPort[code:{1}] + +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:543 +# args: +failed\ to\ reconnect\ console\ proxy = failed to reconnect console proxy + +# at: src/main/java/org/zstack/core/ansible/AnsibleRunner.java:426 +# args: +User\ name\ or\ password\ or\ port\ number\ may\ be\ problematic = User name or password or port number may be problematic + +# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:106 +# args: srcFolder,srcRes.getStdout(),srcRes.getStderr() +cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s].\nstdout\:%s\nstderr\:%s = cannot check md5sum of files in the folder[{0}].\nstdout:{1}\nstderr:{2} + +# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:121 +# args: dstFolder,hostname,dstRes.getStdout(),dstRes.getStderr() +cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s]\ on\ the\ host[ip\:%s].\nstdout\:%s\nstderr\:%s = cannot check md5sum of files in the folder[{0}] on the host[ip:{1}].\nstdout:{2}\nstderr:{3} + +# at: src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java:684 +# args: errMsg +message\ is\ not\ in\ corrected\ JSON\ mediaType,\ %s = message is not in corrected JSON mediaType, {0} + +# at: src/main/java/org/zstack/core/cloudbus/EventFacadeImpl.java:69 +# args: EventFacade.WEBHOOK_TYPE +for\ webhooks\ with\ type[%s],\ the\ field\ opaque\ cannot\ be\ null = for webhooks with type[{0}], the field opaque cannot be null + +# at: src/main/java/org/zstack/core/config/GlobalConfig.java:430 +# args: +do\ not\ allow\ skip\ verification = do not allow skip verification + +# at: src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java:118 +# args: msg.getCategory(),msg.getName() +Unable\ to\ find\ GlobalConfig[category\:\ %s,\ name\:\ %s] = Unable to find GlobalConfig[category: {0}, name: {1}] + +# at: src/main/java/org/zstack/core/debug/DebugManagerImpl.java:93 +# args: +taskInfo\ was\ not\ found = taskInfo was not found + +# at: src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java:204 +# args: encrypt.error +Encryption\ error\ \:\ %s = Encryption error : {0} + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:71 +# args: +non\ file\ or\ jsoncontent\ input = non file or jsoncontent input + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:76 +# args: +file\ or\ jsoncontent\ cannot\ both\ nonempty = file or jsoncontent cannot both nonempty + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:108 +# args: e.getMessage() +Unable\ to\ scan\ folder\:\ %s = Unable to scan folder: {0} + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:112 +# args: filename +%s\ is\ not\ existed\ or\ is\ empty\ folder = {0} is not existed or is empty folder + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:249 +# args: +elaboration\ code\ must\ be\ number! = elaboration code must be number! + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:318 +# args: returnValue.get(0).getContent(),returnValue.get(0).getReason() +%s\:\ %s = {0}: {1} + +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:415 +# args: +input\ args\ 'regex'\ or\ 'category'\ must\ be\ set = input args 'regex' or 'category' must be set + +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:32 +# args: service.getName() +service[%s]\ has\ been\ registered = service[{0}] has been registered + +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:93 +# args: msg.getName() +service[%s]\ is\ not\ registered = service[{0}] is not registered + +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:99 +# args: msg.getName() +service[%s]\ does\ not\ support\ reload\ config = service[{0}] does not support reload config + +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:105 +# args: msg.getName() +service[%s]\ is\ not\ running = service[{0}] is not running + +# at: src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java:315 +# args: vo.getUuid(),vo.getName() +cannot\ trigger\ a\ finished\ GC\ job[uuid\:%s,\ name\:%s] = cannot trigger a finished GC job[uuid:{0}, name:{1}] + +# at: src/main/java/org/zstack/core/progress/ProgressApiInterceptor.java:38 +# args: msg.getApiId() +parameter\ apiId[%s]\ is\ not\ a\ valid\ uuid. = parameter apiId[{0}] is not a valid uuid. + +# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:656 +# args: url,finalTimeout +unable\ to\ echo\ %s\ in\ %sms = unable to echo {0} in {1}ms + +# at: src/main/java/org/zstack/core/retry/Retry.java:103 +# args: __name__,times,interval +an\ operation[%s]\ fails\ after\ retrying\ %s\ times\ with\ the\ interval\ %s\ seconds = an operation[{0}] fails after retrying {1} times with the interval {2} seconds + +# at: src/main/java/org/zstack/core/salt/SaltRunner.java:297 +# args: stateName,targetIp,retry +failed\ to\ run\ salt\ state[%s]\ on\ system[%s],\ failed\ after\ %s\ retries = failed to run salt state[{0}] on system[{1}], failed after {2} retries + +# at: src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java:84 +# args: targetIp +scp\ is\ not\ found\ on\ system[%s],\ unable\ to\ setup\ salt = scp is not found on system[{0}], unable to setup salt + +# at: src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java:76 +# args: ApiTimeoutGlobalProperty.MINIMAL_TIMEOUT +api\ timeout\ cannot\ be\ set\ smaller\ than\ %s = api timeout cannot be set smaller than {0} + +# at: src/main/java/org/zstack/core/webhook/WebhookApiInterceptor.java:28 +# args: url +Invalid\ url[%s] = Invalid url[{0}] + +# at: src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java:72 +# args: +the\ identity\ authentication\ does\ not\ specify\ the\ resource\ pool\ to\ provide\ the\ service = the identity authentication does not specify the resource pool to provide the service + +# at: src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java:83 +# args: setting.resourcePoolType,model +wrong\ secret\ resource\ pool\ model,\ expect\ %s,\ actual\ %s = wrong secret resource pool model, expect {0}, actual {1} + +# at: src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java:81 +# args: resourceUuid +failed\ to\ find\ model\ for\ secretResourcePool\ [%s] = failed to find model for secretResourcePool [{0}] + +# at: src/main/java/org/zstack/crypto/auth/CryptoAuthenticationHelper.java:121 +# args: +failed\ to\ find\ certificate\ info = failed to find certificate info + +# at: src/main/java/org/zstack/crypto/auth/CryptoEncryptionParamParser.java:57 +# args: plainText,e.getMessage() +failed\ to\ parse\ plain\ text\ in\ encryption\ param\ to\ json\ object\:\ %s,\ %s = failed to parse plain text in encryption param to json object: {0}, {1} + +# at: src/main/java/org/zstack/crypto/auth/UKeyCryptoAuthenticationFacade.java:73 +# args: +operation\ not\ supported = operation not supported + +# at: src/main/java/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:200 +# args: userUuid +user[uuid\=%s]\ not\ found = user[uuid={0}] not found + +# at: src/main/java/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:204 +# args: +certificate\ uuid\ is\ empty\ and\ UKey\ system\ tag\ does\ not\ exist = certificate uuid is empty and UKey system tag does not exist + +# at: src/main/java/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:217 +# args: msg.getCertificateUuid() +certificate[uuid\=%s]\ not\ found = certificate[uuid={0}] not found + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java:47 +# args: msg.getResourceType() +check\ batch\ data\ integrity\ fail,\ unsupported\ resourceType\:\ %s = check batch data integrity fail, unsupported resourceType: {0} + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java:57 +# args: msg.getResourceType() +add\ integrity\ resource\ fail,\ unsupported\ resourceType\:\ %s = add integrity resource fail, unsupported resourceType: {0} + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java:65 +# args: msg.getEncryptType() +start\ data\ protection\ encryptType[%s]\ is\ error = start data protection encryptType[{0}] is error + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:240 +# args: inventory.getUuid() +the\ snapshot[uuid\:%s]\ is\ not\ encrypted = the snapshot[uuid:{0}] is not encrypted + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:249 +# args: inventory.getUuid() +verify\ volume\ snapshot[%s]\ consistency\ failed = verify volume snapshot[{0}] consistency failed + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:311 +# args: inventory.getId(),exception.getMessage() +encryption\ image\ cache[id\:%s]\ error\:\ %s = encryption image cache[id:{0}] error: {1} + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:375 +# args: inventory.getId() +the\ image\ cache[id\:%s]\ is\ not\ encrypted = the image cache[id:{0}] is not encrypted + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:388 +# args: inventory.getId() +verify\ image\ cache[%s]\ consistency\ failed = verify image cache[{0}] consistency failed + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:668 +# args: msg.getNodeType(),msg.getPath() +nodeType\ %s\ integrity\ file[path\:%s]\ already\ exists = nodeType {0} integrity file[path:{1}] already exists + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:682 +# args: msg.getNodeType() +invalid\ nodeType[%s] = invalid nodeType[{0}] + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:694 +# args: msg.getNodeType(),msg.getPath() +filed\ to\ add\ integrity\ file[%s.%s],\ it's\ a\ directory\ now. = filed to add integrity file[{0}.{1}], it's a directory now. + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:699 +# args: msg.getNodeType(),msg.getPath() +integrity\ file[%s.%s]\ is\ not\ exists = integrity file[{0}.{1}] is not exists + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:716 +# args: msg.getNodeUuid() +host\ %s\ is\ not\ exists = host {0} is not exists + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:724 +# args: res.getStderr() +Shell\ fail,\ because\ %s = Shell fail, because {0} + +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:747 +# args: msg.getNodeType(),msg.getPath(),exception.getMessage() +add\ integrity\ file[%s.%s]\ fail,\ because\ %s = add integrity file[{0}.{1}] fail, because {2} + +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/EncryptColumnIntegrityFactory.java:141 +# args: +unsupported\ operation\ for\ EncryptColumnIntegrityFactory = unsupported operation for EncryptColumnIntegrityFactory + +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java:138 +# args: encrypt.error +virtualID\ attribute\ encryption\ error,\ because\:%s = virtualID attribute encryption error, because:{0} + +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java:187 +# args: resourceUuid +IAM2VirtualIDAttributeVO\ %s\ does\ not\ exists = IAM2VirtualIDAttributeVO {0} does not exists + +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java:194 +# args: encrypt.error +virtualID\ attribute\ check\ error,\ because\:%s = virtualID attribute check error, because:{0} + +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/RolePolicyIntegrityFactory.java:115 +# args: encrypt.error +rolePolicy\ encryption\ error,\ because\:%s = rolePolicy encryption error, because:{0} + +# at: src/main/java/org/zstack/crypto/datacrypto/smp/SMPCryptoBase.java:40 +# args: self.getUuid(),self.getName() +the\ shared\ mount\ point\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters = the shared mount point primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters + +# at: src/main/java/org/zstack/crypto/securitymachine/AttachVerifyPair.java:26 +# args: +originText\ or\ certificateText\ can\ not\ be\ null = originText or certificateText can not be null + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:60 +# args: msg.getSecurityMachineUuid() +the\ security\ machine\ [%s]\ does\ not\ exist = the security machine [{0}] does not exist + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:86 +# args: msg.getManagementIp() +managementIp[%s]\ is\ not\ in\ IPV4\ format = managementIp[{0}] is not in IPV4 format + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:92 +# args: msg.getName(),msg.getManagementIp(),error +failed\ to\ connect\ to\ the\ security\ machine\ %s[%s],\ because\ %s = failed to connect to the security machine {0}[{1}], because {2} + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:112 +# args: msg.getSecurityMachineUuid() +after\ the\ crypto\ function\ is\ enabled,\ at\ least\ one\ security\ machine\ should\ be\ reserved\ in\ the\ corresponding\ resource\ pool = after the crypto function is enabled, at least one security machine should be reserved in the corresponding resource pool + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:123 +# args: msg.getAlgType(),StringUtils.join(EncryptType.values(), ',') +invalid\ algType\ %s,\ supported\ types\:\ %s. = invalid algType {0}, supported types: {1}. + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:127 +# args: poolForProtect +the\ resource\ pool[%s]\ specified\ by\ data\ protection\ does\ not\ exist = the resource pool[{0}] specified by data protection does not exist + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java:145 +# args: +cannot\ be\ deleted.\ after\ the\ encryption\ function\ is\ enabled,\ the\ number\ of\ synced\ security\ machines\ in\ the\ resource\ pool\ that\ provides\ the\ service\ is\ at\ least\ 1 = cannot be deleted. after the encryption function is enabled, the number of synced security machines in the resource pool that provides the service is at least 1 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java:444 +# args: +securityMachine\ is\ disabled,\ failed\ to\ detect\ heartbeat = securityMachine is disabled, failed to detect heartbeat + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java:584 +# args: +an\ other\ connect\ security\ machine\ task\ is\ running,\ cancel\ the\ new\ task\ and\ wait\ return = an other connect security machine task is running, cancel the new task and wait return + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:183 +# args: data,algType +encrypt\ data[%s]\ or\ algType[%s]\ is\ null = encrypt data[{0}] or algType[{1}] is null + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:165 +# args: resourceUuid +cannot\ find\ model\ for\ secretResourcePool\ [%s] = cannot find model for secretResourcePool [{0}] + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:105 +# args: poolForAuth +the\ crypto\ function\ is\ enabled\ but\ the\ resource\ pool[%s]\ for\ auto\ login\ is\ not\ set. = the crypto function is enabled but the resource pool[{0}] for auto login is not set. + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:113 +# args: poolForProtect +the\ crypto\ function\ is\ enabled\ but\ the\ resource\ pool[%s]\ for\ data\ protect\ is\ not\ set. = the crypto function is enabled but the resource pool[{0}] for data protect is not set. + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:122 +# args: state.toString() +the\ current\ state[%s]\ does\ not\ allow\ manual\ modification\ of\ the\ state = the current state[{0}] does not allow manual modification of the state + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:149 +# args: +cannot\ disable\ all\ security\ machines\ when\ the\ crypto\ function\ is\ enabled = cannot disable all security machines when the crypto function is enabled + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:159 +# args: +check\ whether\ the\ resource\ pool\ uuid\ is\ set\ for\ authentication = check whether the resource pool uuid is set for authentication + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:202 +# args: algType +unknown\ encryptType[%s] = unknown encryptType[{0}] + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:216 +# args: data,algType +decrypt\ data[%s]\ or\ algType[%s]\ is\ null = decrypt data[{0}] or algType[{1}] is null + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:225 +# args: algType +invalid\ decrypt\ algType\:\ %s = invalid decrypt algType: {0} + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java:280 +# args: msg.getManagementIp() +there\ has\ been\ a\ security\ machine\ having\ managementIp[%s] = there has been a security machine having managementIp[{0}] + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java:82 +# args: securityMachineType +no\ client\ for\ security\ machine[type\=%s] = no client for security machine[type={0}] + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java:101 +# args: securityMachineType +no\ security\ machine\ client\ factory\ for\ security\ machine[type\=%s] = no security machine client factory for security machine[type={0}] + +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:50 +# args: +there\ is\ no\ security\ machine\ that\ can\ be\ activated = there is no security machine that can be activated + +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:54 +# args: msg.getType(),StringUtils.join(SecurityMachineKeyType.values(), ',') +invalid\ token\ type\ %s,\ only\ supports\ %s. = invalid token type {0}, only supports {1}. + +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:68 +# args: msg.getSecretResourcePoolUuid() +the\ identity\ authentication\ function\ is\ enabled\ but\ the\ corresponding\ resource\ pool\ is\ not\ set,\ please\ re-enable\ the\ function\ and\ try\ again = the identity authentication function is enabled but the corresponding resource pool is not set, please re-enable the function and try again + +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:72 +# args: msg.getSecretResourcePoolUuid() +cannot\ delete\ the\ resource\ pool\ %s\ when\ in\ use = cannot delete the resource pool {0} when in use + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java:237 +# args: +generate\ certificate\ failed = generate certificate failed + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java:134 +# args: rsp.getData() +flkSec\ securityMachine\ unhealthy\:\ %s = flkSec securityMachine unhealthy: {0} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java:161 +# args: keyLabel,sm4EncryptResponse.result +keyLabel\ %s\ and\ encryptResult\ %s\ are\ inconsistent = keyLabel {0} and encryptResult {1} are inconsistent + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:168 +# args: vo.getUuid(),response.error +the\ connection\ to\ the\ security\ machine\ %s\ failed\ during\ the\ process\ of\ generating\ the\ test\ key\ because\ %s = the connection to the security machine {0} failed during the process of generating the test key because {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:185 +# args: vo.getUuid(),dataProtectTokenRes.error +failed\ to\ generate\ dataProtect\ token\ for\ the\ security\ machine\ %s\ because\ %s = failed to generate dataProtect token for the security machine {0} because {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:196 +# args: vo.getUuid(),hmacTokenTokenRes.error +failed\ to\ generate\ hmac\ token\ for\ the\ security\ machine\ %s\ because\ %s = failed to generate hmac token for the security machine {0} because {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:208 +# args: vo.getUuid(),encryptRes.error +failed\ to\ get\ encrypt\ result\ for\ the\ security\ machine\ %s\ because\ %s = failed to get encrypt result for the security machine {0} because {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecurityMachineBase.java:123 +# args: self.getManagementIp() +the\ security\ machine\ [%s]\ failed\ to\ manually\ detect\ synchronization,\ please\ confirm\ whether\ the\ security\ machine\ has\ synchronized\ the\ key! = the security machine [{0}] failed to manually detect synchronization, please confirm whether the security machine has synchronized the key! + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecurityMachineFactory.java:32 +# args: msg.getName(),vo.getModel() +security\ machine[uuid\:%s]\ model\ is\ not\ %s = security machine[uuid:{0}] model is not {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/haitai/HaiTaiSecretResourcePoolApiInterceptor.java:52 +# args: msg.getModel() +currently\ does\ not\ support\ the\ creation\ of\ %s\ resource\ pools = currently does not support the creation of {0} resource pools + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/haitai/HaiTaiSecretResourcePoolFactory.java:33 +# args: msg.getResourceUuid(),vo.getModel() +secretResourcePool[uuid\:%s]\ model\ is\ not\ %s = secretResourcePool[uuid:{0}] model is not {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:409 +# args: agentBasic.INSMGetReturnCode(),agentBasic.INSMGetErrMsg() +large\ file\ hmac\ encrypt\ failed,\ code\:\ %s,\ detail\:\ %s = large file hmac encrypt failed, code: {0}, detail: {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:457 +# args: +failed\ to\ find\ secret\ key = failed to find secret key + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:465 +# args: e.getMessage() +failed\ to\ parse\ secret\ key,\ error\:\ %s = failed to parse secret key, error: {0} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:500 +# args: +cipherText\ can\ not\ be\ null = cipherText can not be null + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:503 +# args: +encryptSubjectDN\ can\ not\ be\ null = encryptSubjectDN can not be null + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:508 +# args: +failed\ to\ parse\ MS\ Envelope = failed to parse MS Envelope + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:533 +# args: +failed\ to\ export\ secret\ key = failed to export secret key + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:550 +# args: +import\ secret\ key\ fail = import secret key fail + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java:196 +# args: vo.getUuid(),activateTokenRes.error +failed\ to\ generate\ activated\ token\ for\ the\ security\ machine\ %s\ because\ %s = failed to generate activated token for the security machine {0} because {1} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java:206 +# args: dataProtectTokenName,vo.getUuid(),dataProtectTokenRes.error +failed\ to\ generate\ dataProtect\ token\ %s\ for\ the\ security\ machine\ %s\ because\ %s = failed to generate dataProtect token {0} for the security machine {1} because {2} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java:216 +# args: hmacTokenName,vo.getUuid(),hmacTokenTokenRes.error +failed\ to\ generate\ hmac\ token\ %s\ for\ the\ security\ machine\ %s\ because\ %s = failed to generate hmac token {0} for the security machine {1} because {2} + +# at: src/main/java/org/zstack/cube/CubeManagerImpl.java:505 +# args: cmd.host,cmd.detail +host[uuid\:\ %s]\ memory\ ecc\ triggered,\ detail\:\ %s = host[uuid: {0}] memory ecc triggered, detail: {1} + +# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:99 +# args: +parameters\ [accountUuid]\ only\ can\ be\ used\ by\ admin\ user! = parameters [accountUuid] only can be used by admin user! + +# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:54 +# args: msg.getExpirePolicy() +expire\ policy\:\ %s\ is\ not\ valid = expire policy: {0} is not valid + +# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:57 +# args: msg.getVlan() +vlanId[%s]\ has\ been\ existed! = vlanId[{0}] has been existed! + +# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:128 +# args: +create\ daho\ vll\ task\ failed! = create daho vll task failed! + +# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:169 +# args: msg.getAccountUuid() +no\ aliyun\ account\ found\ for\ accountUuid\:\ %s = no aliyun account found for accountUuid: {0} + +# at: src/main/java/org/zstack/directory/DirectoryApiInterceptor.java:105 +# args: list,msg.getDirectoryUuid() +resources\ %s\ has\ already\ been\ bound\ to\ directory\ uuid[%s]\ ,\ multiple\ paths\ are\ not\ supported = resources {0} has already been bound to directory uuid[{1}] , multiple paths are not supported + +# at: src/main/java/org/zstack/directory/DirectoryApiInterceptor.java:112 +# args: list,ALLOW_RESOURCE_TYPES +resource\ types\ %s\ are\ not\ supported\ by\ directory,\ allowed\ types\ are\ %s = resource types {0} are not supported by directory, allowed types are {1} + +# at: src/main/java/org/zstack/directory/DirectoryApiInterceptor.java:129 +# args: +name\ contains\ unsupported\ characters,\ name\ can\ only\ contain\ Chinese\ characters,\ English\ letters,\ numbers,\ spaces,\ and\ the\ following\ characters\:\ ()()【】@._-+\ = name contains unsupported characters, name can only contain Chinese characters, English letters, numbers, spaces, and the following characters: ()()【】@._-+ + +# at: src/main/java/org/zstack/directory/DirectoryBase.java:356 +# args: msg.getDirectoryUuid(),msg.getTargetParentUuid() +circular\ dependency\ detected,\ directory\ %s\ and\ directory\ %s\ will\ cause\ circular\ dependency = circular dependency detected, directory {0} and directory {1} will cause circular dependency + +# at: src/main/java/org/zstack/directory/DirectoryManagerImpl.java:147 +# args: list.get(0).getUuid(),msg.getName() +duplicate\ directory\ name,\ directory[uuid\:\ %s]\ with\ name\ %s\ already\ exists = duplicate directory name, directory[uuid: {0}] with name {1} already exists + +# at: src/main/java/org/zstack/directory/DirectoryManagerImpl.java:154 +# args: +fail\ to\ create\ directory,\ directories\ are\ up\ to\ four\ levels = fail to create directory, directories are up to four levels + +# at: src/main/java/org/zstack/directory/DirectoryManagerImpl.java:158 +# args: msg.getType(),DIRECTORY_TYPES +the\ type\ of\ directory\ %s\ is\ not\ supported,\ the\ supported\ directory\ types\ are\ %s = the type of directory {0} is not supported, the supported directory types are {1} + +# at: src/main/java/org/zstack/directory/VmDirectoryChecker.java:27 +# args: vo.getZoneUuid() +all\ resources\ zoneUuid\ must\ be\ consistent\ with\ the\ directory\ zoneUuid[%s] = all resources zoneUuid must be consistent with the directory zoneUuid[{0}] + +# at: src/main/java/org/zstack/drs/DRSBase.java:216 +# args: +Advice\ not\ allowed\ while\ scheduling = Advice not allowed while scheduling + +# at: src/main/java/org/zstack/drs/DRSBase.java:277 +# args: +delete\ DRS\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = delete DRS is not allowed while the vm is being migrated + +# at: src/main/java/org/zstack/drs/DRSBase.java:370 +# args: +Scheduling\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = Scheduling is not allowed while the vm is being migrated + +# at: src/main/java/org/zstack/drs/DRSBase.java:481 +# args: +Lack\ of\ host\ CPU,\ memory\ monitoring\ data = Lack of host CPU, memory monitoring data + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:55 +# args: msg.getClusterUuid() +The\ cluster[%s]\ has\ created\ DRS = The cluster[{0}] has created DRS + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:59 +# args: +DRS\ is\ disabled = DRS is disabled + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:64 +# args: +thresholds\ can\ not\ be\ empty = thresholds can not be empty + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:73 +# args: threshold.getThresholdName() +illegal\ thresholdName[%s] = illegal thresholdName[{0}] + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:77 +# args: threshold.getOperator() +illegal\ threshold\ operator[%s] = illegal threshold operator[{0}] + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:81 +# args: +thresholdValue\ can\ not\ be\ empty = thresholdValue can not be empty + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:86 +# args: +illegal\ thresholdValue,\ valid\ range\:\ (0,\ 100] = illegal thresholdValue, valid range: (0, 100] + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:103 +# args: +GlobalConfig\ ENABLE_DRS\ is\ closed = GlobalConfig ENABLE_DRS is closed + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:107 +# args: msg.getUuid(),vo.getState().toString() +The\ DRS[%s]\ state\ is\ %s = The DRS[{0}] state is {1} + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:122 +# args: adviceVO.getDrsUuid() +The\ DRS[%s]\ automation\ level\ is\ not\ manual = The DRS[{0}] automation level is not manual + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:136 +# args: msg.getAdviceUuid() +advice[%s]\ has\ expired = advice[{0}] has expired + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:145 +# args: +Successfully\ executed,\ no\ repeated\ executions\ allowed = Successfully executed, no repeated executions allowed + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:152 +# args: adviceVO.getVmUuid() +The\ vm[%s]\ has\ been\ deleted = The vm[{0}] has been deleted + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:155 +# args: adviceVO.getVmUuid() +The\ vm[%s]\ state\ is\ not\ running = The vm[{0}] state is not running + +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:158 +# args: adviceVO.getVmUuid(),adviceVO.getVmSourceHostUuid() +The\ vm[%s]\ is\ no\ longer\ on\ the\ source\ host[%s] = The vm[{0}] is no longer on the source host[{1}] + +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:273 +# args: msg.getClusterUuid() +The\ cluster[%s]\ does\ not\ support\ DRS. = The cluster[{0}] does not support DRS. + +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:290 +# args: reasons +Can\ not\ create\ DRS,\ %s = Can not create DRS, {0} + +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:323 +# args: +hostUuids\ is\ empty = hostUuids is empty + +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:330 +# args: +query\ hosts\ utilization\ data\ failed = query hosts utilization data failed + +# at: src/main/java/org/zstack/encrypt/EncryptionParamApiInterceptor.java:83 +# args: bundle.getEncryptionType() +failed\ to\ parse\ API\ message\:\ can\ not\ parse\ encryption\ param\ with\ type\ %s = failed to parse API message: can not parse encryption param with type {0} + +# at: src/main/java/org/zstack/encrypt/EncryptionParamApiInterceptor.java:128 +# args: matchTags.size() +failed\ to\ parse\ API\ message\:\ found\ %d\ encryption\ param\ system\ tags,\ expect\ 1 = failed to parse API message: found {0} encryption param system tags, expect 1 + +# at: src/main/java/org/zstack/externalbackup/zbox/HostZBoxBackupRecoverGC.java:142 +# args: volumeUuids +some\ volume[uuids\:%s]\ recover\ failed.\ you\ can\ trigger\ it\ again\ by\ reconnect\ it. = some volume[uuids:{0}] recover failed. you can trigger it again by reconnect it. + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupApiInterceptor.java:34 +# args: externalBackupUuid +there\ is\ another\ external\ backup[uuid\:\ %s]\ recovering = there is another external backup[uuid: {0}] recovering + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupApiInterceptor.java:38 +# args: +both\ hostUuids\ and\ backupStorageUuids\ are\ empty.\ you\ must\ specify\ one\ or\ both\ of\ them. = both hostUuids and backupStorageUuids are empty. you must specify one or both of them. + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:691 +# args: +please\ insert\ zbox\ to\ management\ node. = please insert zbox to management node. + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:219 +# args: +cannot\ find\ recover.conf\ under\ zbox\ backup\ install\ dir. = cannot find recover.conf under zbox backup install dir. + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:741 +# args: result.getExecutionLog() +fail\ to\ backup\ database\:\ %s = fail to backup database: {0} + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:591 +# args: +zbox\ should\ be\ inserted\ to\ a\ host\ first. = zbox should be inserted to a host first. + +# at: src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java:81 +# args: +crond\ is\ not\ running = crond is not running + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:485 +# args: +Missing\ CPU/memory\ settings = Missing CPU/memory settings + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:489 +# args: +Unexpected\ CPU/memory\ settings = Unexpected CPU/memory settings + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:498 +# args: instanceOfferingUuid +instance\ offering[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = instance offering[uuid:{0}] is Disabled, can't create vm from it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:502 +# args: instanceOfferingUuid,ivo.getType() +instance\ offering[uuid\:%s,\ type\:%s]\ is\ not\ UserVm\ type,\ can't\ create\ vm\ from\ it = instance offering[uuid:{0}, type:{1}] is not UserVm type, can't create vm from it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:539 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = image[uuid:{0}] is Disabled, can't create vm from it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:544 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ not\ ready\ yet,\ can't\ create\ vm\ from\ it = image[uuid:{0}] is not ready yet, can't create vm from it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:559 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ system\ image,\ can't\ be\ used\ to\ create\ user\ vm = image[uuid:{0}] is system image, can't be used to create user vm + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:575 +# args: diskUuids +disk\ offerings[uuids\:%s]\ are\ Disabled,\ can\ not\ create\ vm\ from\ it = disk offerings[uuids:{0}] are Disabled, can not create vm from it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:450 +# args: vmInstanceUuid +current\ operation\ is\ not\ supported\ on\ ft\ secondary\ vm[uuid\:%s] = current operation is not supported on ft secondary vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:126 +# args: group.getPrimaryVmInstanceUuid(),group.getSecondaryVmInstanceUuid() +pvm[uuid\:%s]\ and\ svm[uuid\:%s]\ volume\ number\ not\ matches,\ do\ not\ allowed\ to\ start = pvm[uuid:{0}] and svm[uuid:{1}] volume number not matches, do not allowed to start + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:135 +# args: i,group.getPrimaryVmInstanceUuid(),group.getSecondaryVmInstanceUuid() +volume\ with\ index\:\ %d,\ of\ pvm[uuid\:%s]\ and\ svm[uuid\:%s]\ have\ different\ size,\ do\ not\ allowed\ to\ start = volume with index: {0}, of pvm[uuid:{1}] and svm[uuid:{2}] have different size, do not allowed to start + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:146 +# args: i,group.getPrimaryVmInstanceUuid(),group.getSecondaryVmInstanceUuid() +volume\ with\ index\:\ %d,\ of\ pvm[uuid\:%s]\ and\ svm[uuid\:%s]'s\ cache\ volume\ have\ different\ size,\ do\ not\ allowed\ to\ start = volume with index: {0}, of pvm[uuid:{1}] and svm[uuid:{2}]'s cache volume have different size, do not allowed to start + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:169 +# args: msg.getUuid(),faultToleranceVmGroupUuid +image[uuid\:%s]\ is\ still\ used\ by\ fault\ tolerance\ vm[uuid\:%s] = image[uuid:{0}] is still used by fault tolerance vm[uuid:{1}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:212 +# args: msg.getL3NetworkUuid(),String.join(",", vmInstanceUuids),VmInstanceState.Paused,VmInstanceState.Running +could\ not\ delete\ l3\ network[uuid\:%s].\ Fault\ tolerance\ vm[%s]\ in\ states[%s,\ %s]\ still\ using\ it.\ Stop\ related\ fault\ tolerance\ vms\ before\ delete\ l3\ network = could not delete l3 network[uuid:{0}]. Fault tolerance vm[{1}] in states[{2}, {3}] still using it. Stop related fault tolerance vms before delete l3 network + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:266 +# args: msg.getFaultToleranceVmUuid() +Can\ not\ fail-over\ vm[uuid\:%s],\ please\ enable\ ft\ in\ GlobalConfig = Can not fail-over vm[uuid:{0}], please enable ft in GlobalConfig + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:270 +# args: msg.getFaultToleranceVmUuid() +Can\ not\ fail-over\ vm[uuid\:%s],\ please\ confirm\ it\ is\ a\ fault\ tolerance\ vm\ group = Can not fail-over vm[uuid:{0}], please confirm it is a fault tolerance vm group + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:276 +# args: msg.getFaultToleranceVmUuid(),FaultToleranceStatus.Protected,FaultToleranceStatus.Unknown +Can\ not\ fail-over\ vm[uuid\:%s],\ because\ fault\ tolerance\ vm\ group\ is\ not\ in\ status\ of\ [%s,\ %s] = Can not fail-over vm[uuid:{0}], because fault tolerance vm group is not in status of [{1}, {2}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:301 +# args: Joiner.on(",").join(vmUuids) +Can\ not\ maintain\ host,\ because\ ft\ vms[%s]\ are\ under\ recovering = Can not maintain host, because ft vms[{0}] are under recovering + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:319 +# args: msg.getClass(),msg.getVmInstanceUuid(),state +current\ operation[api\:%s]\ is\ not\ supported\ when\ ft\ vm[uuid\:%s,\ state\:%s]\ is\ not\ stopped = current operation[api:{0}] is not supported when ft vm[uuid:{1}, state:{2}] is not stopped + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:367 +# args: VmHaLevel.FaultTolerance.toString() +Can\ not\ set\ vm\ level\ to\ %s,\ please\ enable\ ft\ in\ GlobalConfig = Can not set vm level to {0}, please enable ft in GlobalConfig + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:515 +# args: +Ft\ network\ is\ not\ set = Ft network is not set + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:423 +# args: msg.getVmInstanceUuid() +can\ not\ update\ ft\ vm[uuid\:%s]\ cpu\ number,\ need\ to\ stop\ both\ of\ the\ vms = can not update ft vm[uuid:{0}] cpu number, need to stop both of the vms + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:427 +# args: msg.getVmInstanceUuid() +can\ not\ update\ ft\ vm[uuid\:%s]\ memory\ size,\ need\ to\ stop\ both\ of\ the\ vms = can not update ft vm[uuid:{0}] memory size, need to stop both of the vms + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:431 +# args: msg.getVmInstanceUuid() +can\ not\ update\ ft\ vm[uuid\:%s]\ platform,\ need\ to\ stop\ both\ of\ the\ vms = can not update ft vm[uuid:{0}] platform, need to stop both of the vms + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:442 +# args: vmInstanceUuid +current\ operation\ is\ not\ supported\ on\ ft\ group\ vm[uuid\:%s] = current operation is not supported on ft group vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:446 +# args: vmInstanceUuid +current\ operation\ is\ not\ supported\ on\ ft\ primary\ vm[uuid\:%s] = current operation is not supported on ft primary vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:466 +# args: msg.getVmInstanceUuid() +current\ operation\ is\ not\ supported\ on\ secondary\ vm[uuid\:%s] = current operation is not supported on secondary vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:472 +# args: +can\ not\ migrate\ FT\ primary\ vm = can not migrate FT primary vm + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:476 +# args: +can\ not\ migrate\ FT\ secondary\ vm = can not migrate FT secondary vm + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:511 +# args: +Failed\ to\ create\ ft\ vm,\ please\ enable\ ft\ in\ GlobalConfig = Failed to create ft vm, please enable ft in GlobalConfig + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:549 +# args: msg.getImageUuid(),imgFormat +image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ can\ be\ used\ to\ create\ vm = image[uuid:{0}] is of mediaType: {1}, only RootVolumeTemplate can be used to create vm + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:554 +# args: msg.getImageUuid(),imageFileFmt,ImageConstant.QCOW2_FORMAT_STRING +image[uuid\:%s]\ is\ of\ format\:\ %s,\ only\ %s\ can\ be\ used\ to\ create\ vm = image[uuid:{0}] is of format: {1}, only {2} can be used to create vm + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:364 +# args: hostUuid +failed\ to\ allocate\ port\ on\ host[uuid\:\ %s] = failed to allocate port on host[uuid: {0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:369 +# args: hostUuid +allocated\ port\ num\ less\ than\ requested\ on\ host[uuid\:\ %s] = allocated port num less than requested on host[uuid: {0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:524 +# args: smsg.getPrimaryVmInstanceUuid() +could\ not\ get\ hostUuid\ of\ primary\ vm[uuid\:%s] = could not get hostUuid of primary vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:892 +# args: +can\ not\ start\ secondary\ vm,\ because\ primary\ vm\ is\ still\ stopped = can not start secondary vm, because primary vm is still stopped + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:1322 +# args: vm.getUuid() +Can\ not\ migrate\ ft\ secondary\ vm[uuid\:%s] = Can not migrate ft secondary vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:1327 +# args: vm.getUuid() +Can\ not\ migrate\ ft\ primary\ vm[uuid\:%s] = Can not migrate ft primary vm[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmInstanceBase.java:546 +# args: +Current\ ft\ vm\ is\ in\ unknown\ status,\ can\ not\ stop\ it,\ please\ try\ to\ fail-over\ it\ manually = Current ft vm is in unknown status, can not stop it, please try to fail-over it manually + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmInstanceBase.java:596 +# args: self.getUuid() +unable\ to\ start\ the\ vm[uuid\:%s].\ It\ doesn't\ have\ any\ nic,\ please\ attach\ a\ nic\ and\ try\ again = unable to start the vm[uuid:{0}]. It doesn't have any nic, please attach a nic and try again + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:3110 +# args: nicUuid,pvm.getHostUuid() +failed\ to\ allocate\ port\ of\ nic[uuid\:\ %s]\ on\ host[uuid\:\ %s] = failed to allocate port of nic[uuid: {0}] on host[uuid: {1}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:3115 +# args: nicUuid,pvm.getHostUuid() +allocated\ port\ num\ less\ than\ requested\ of\ nic[uuid\:\ %s]\ on\ host[uuid\:\ %s] = allocated port num less than requested of nic[uuid: {0}] on host[uuid: {1}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:727 +# args: +can\ not\ create\ secondary\ vm,\ because\ primary\ vm\ is\ stopped = can not create secondary vm, because primary vm is stopped + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:641 +# args: +an\ other\ fault\ tolerance\ gc\ task\ is\ running,\ cancel\ the\ new\ task\ and\ wait\ return = an other fault tolerance gc task is running, cancel the new task and wait return + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:2256 +# args: +can\ not\ start\ secondary\ vm,\ because\ primary\ vm\ is\ stopped = can not start secondary vm, because primary vm is stopped + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1212 +# args: +created\ svm\ found,\ report\ error\ for\ this\ start\ secondary\ vm\ request = created svm found, report error for this start secondary vm request + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1468 +# args: vmInstanceUuid +could\ not\ failover\ vm[uuid\:%s].\ Related\ fault\ tolerance\ vm\ group\ not\ exists = could not failover vm[uuid:{0}]. Related fault tolerance vm group not exists + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1484 +# args: group.getPrimaryVmInstanceUuid() +pvm[uuid\:%s]\ not\ exists = pvm[uuid:{0}] not exists + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1596 +# args: +unexpected\ exception = unexpected exception + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1556 +# args: +could\ not\ failover.\ Secondary\ vm\ is\ unknown\ but\ no\ fault\ tolerance\ network\ address\ available = could not failover. Secondary vm is unknown but no fault tolerance network address available + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1495 +# args: +could\ not\ failover.\ Primary\ vm\ is\ unknown\ but\ no\ fault\ tolerance\ network\ address\ available = could not failover. Primary vm is unknown but no fault tolerance network address available + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1669 +# args: hostUuid +cannot\ found\ available\ ip\ from\ current\ ft\ network.\ Check\ whether\ global\ config[category\:ft\ name\:fault.tolerance.network.cidr]\ is\ correctly\ set,\ and\ confirm\ that\ host[uuid\:%s]\ own\ ip\ address\ in\ the\ CIDR = cannot found available ip from current ft network. Check whether global config[category:ft name:fault.tolerance.network.cidr] is correctly set, and confirm that host[uuid:{0}] own ip address in the CIDR + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:3009 +# args: +not\ fault\ tolerance\ vm\ port\ found = not fault tolerance vm port found + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java:95 +# args: imageUuid,spec.getVmInventory().getName(),spec.getVmInventory().getUuid() +cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage.\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = cannot find the image[uuid:{0}] in any connected backup storage. check below:\n1. if the backup storage is attached to the zone where the VM[name: {1}, uuid:{2}] is in\n2. if the backup storage is in connected status, if not, try reconnecting it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java:89 +# args: imageUuid,spec.getVmInventory().getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() +cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = cannot find the image[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\n1. if the backup storage is attached to the zone where the VM[name: {2}, uuid:{3}] is in\n2. if the backup storage is in connected status, if not, try reconnecting it + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java:117 +# args: zoneUuid,isoImageUuid +no\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s]\ contains\ the\ ISO[uuid\:%s] = no backup storage attached to the zone[uuid:{0}] contains the ISO[uuid:{1}] + +# at: src/main/java/org/zstack/faulttolerance/ShadowVmCloneTagsFlow.java:63 +# args: +missing\ fault\ tolerance\ vm\ group = missing fault tolerance vm group + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:63 +# args: vo.getL3NetworkUuid(),vo.getFlowMeterUuid() +The\ network[%s]\ have\ been\ added\ into\ the\ flow\ meter[%s] = The network[{0}] have been added into the flow meter[{1}] + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:71 +# args: +The\ virtual\ router\ have\ been\ added\ into\ other\ flow\ meter = The virtual router have been added into other flow meter + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:77 +# args: msg.getVersion(),FlowMeterConstants.TYPE.NetFlow.toString() +invalid\ type\ parameter\ is\ %s\ and\ should\ be\ in\ %s = invalid type parameter is {0} and should be in {1} + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:154 +# args: msg.getServer() +[%s]\ is\ not\ formatted\ as\ IP\ address = [{0}] is not formatted as IP address + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:143 +# args: collector.getUuid() +Collector\ duplicate\ with\ %s = Collector duplicate with {0} + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:164 +# args: collectorVO.getFlowMeterUuid() +FlowMeter[%s]\ doesn't\ exist = FlowMeter[{0}] doesn't exist + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:168 +# args: collectorVO.getFlowMeterUuid(),vo.getVersion().toString() +FlowMeter[%s]\ IPv6\ doesn't\ support\ version[%s] = FlowMeter[{0}] IPv6 doesn't support version[{1}] + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:150 +# args: +no\ specify\ parameter = no specify parameter + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:159 +# args: msg.getUuid() +Flow\ collector[%s]\ doesn't\ exist = Flow collector[{0}] doesn't exist + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:183 +# args: server,port,collector.getUuid() +Collector\ [%s\ %d]\ duplicate\ with\ %s = Collector [{0} {1}] duplicate with {2} + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:88 +# args: vmUuid +unable\ to\ set\ vm\ hostname.\ the\ vm[uuid\:%s]\ do\ not\ have\ default\ L3\ network = unable to set vm hostname. the vm[uuid:{0}] do not have default L3 network + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:103 +# args: sameTag.getResourceUuid(),hostname,defaultL3uuid +conflict\ hostname,\ there\ has\ been\ a\ VM[uuid\:%s]\ having\ hostname[%s]\ on\ L3\ network[uuid\:%s] = conflict hostname, there has been a VM[uuid:{0}] having hostname[{1}] on L3 network[uuid:{2}] + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:111 +# args: msg.getVmInstanceUuid() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ vm\ not\ running. = update vm[uuid:{0}] network config failed, because vm not running. + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:116 +# args: msg.getVmInstanceUuid(),vm.getType() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ the\ vm\ type\ %s\ is\ not\ supported. = update vm[uuid:{0}] network config failed, because the vm type {1} is not supported. + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:129 +# args: msg.getVmInstanceUuid() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ guesttools\ not\ running. = update vm[uuid:{0}] network config failed, because guesttools not running. + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:125 +# args: msg.getVmInstanceUuid() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ the\ guesttools\ version\ is\ too\ low\ for\ this\ feature. = update vm[uuid:{0}] network config failed, because the guesttools version is too low for this feature. + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:136 +# args: nic.getUuid() +sync\ nic[uuid\:%s]\ network\ config\ failed,\ the\ current\ qga\ tools\ only\ support\ manual\ ipv6\ configuration\ and\ do\ not\ support\ automatic\ sync = sync nic[uuid:{0}] network config failed, the current qga tools only support manual ipv6 configuration and do not support automatic sync + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:147 +# args: msg.getUuid() +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = cannot attach guest-tools iso to vm[uuid:{0}] because it's hypervisor type is not supported + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:154 +# args: msg.getUuid() +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ running = cannot attach guest-tools iso to vm[uuid:{0}] because it's not running + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:161 +# args: msg.getUuid() +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = cannot attach guest-tools iso to vm[uuid:{0}] because it's not user vm + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:168 +# args: msg.getUuid() +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it\ has\ no\ cdrom = cannot attach guest-tools iso to vm[uuid:{0}] because it has no cdrom + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:191 +# args: vmUuid +cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ running = cannot get guest-tools info from vm[uuid:{0}] because it's not running + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:197 +# args: vmUuid +cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = cannot get guest-tools info from vm[uuid:{0}] because it's not user vm + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:219 +# args: invalidSet +invalid\ debug\ parameter\:\ %s = invalid debug parameter: {0} + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:227 +# args: msg.getVmInstanceUuid() +can\ not\ update\ guest\ tools\ state\ for\ vm\ [uuid\:%s]\ because\ vm\ is\ deleted = can not update guest tools state for vm [uuid:{0}] because vm is deleted + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:232 +# args: msg.getVmInstanceUuid() +can\ not\ update\ guest\ tools\ state\ for\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = can not update guest tools state for vm[uuid:{0}] because it's not user vm + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:704 +# args: msg.getUuid() +cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = cannot get latest guest-tools for vm[uuid:{0}] because it's hypervisor type is not supported + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:713 +# args: msg.getUuid() +cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ running\ or\ volume\ recovering. = cannot get latest guest-tools for vm[uuid:{0}] because it's not running or volume recovering. + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:722 +# args: msg.getUuid() +cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = cannot get latest guest-tools for vm[uuid:{0}] because it's not user vm + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:1067 +# args: Platform.getManagementServerId(),msg.getHostUuid() +no\ proper\ guest\ tools\ iso\ found\ in\ management\ node[uuid\:%s]\ for\ host[uuid\:%s] = no proper guest tools iso found in management node[uuid:{0}] for host[uuid:{1}] + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:2042 +# args: vm.getUuid(),vm.getName() +failed\ to\ set\ vm[uuid\:\ %s,\ name\:\ %s]\ hostname,\ because\ qga\ state\ is\ not\ running\ and\ there\ is\ no\ dhcp\ service = failed to set vm[uuid: {0}, name: {1}] hostname, because qga state is not running and there is no dhcp service + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:144 +# args: vmUuid,rsp.getError() +failed\ to\ get\ guest\ tools\ info\ from\ vm[uuid\:%s],\ because\:%s = failed to get guest tools info from vm[uuid:{0}], because:{1} + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:244 +# args: host.getUuid() +failed\ to\ download\ guest\ tools\ iso\ because\ no\ kvm\ host[uuid\:%s]\ found = failed to download guest tools iso because no kvm host[uuid:{0}] found + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:313 +# args: vm.getUuid(),rsp.getError() +failed\ to\ attach\ guest\ tools\ iso\ to\ vm[uuid\:%s],\ because\:%s = failed to attach guest tools iso to vm[uuid:{0}], because:{1} + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:358 +# args: vm.getUuid(),rsp.getError() +failed\ to\ detach\ guest\ tools\ iso\ from\ vm[uuid\:%s],\ because\:%s = failed to detach guest tools iso from vm[uuid:{0}], because:{1} + +# at: src/main/java/org/zstack/guesttools/pvpanic/PVPanicCrashStrategyManagerImpl.java:200 +# args: errCode +can\ not\ be\ here = can not be here + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:90 +# args: vm.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ because\ it\ is\ not\ stopped = can not set FT on vm[uuid:{0}] because it is not stopped + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:94 +# args: vm.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ because\ some\ data\ volume\ is\ still\ attached = can not set FT on vm[uuid:{0}] because some data volume is still attached + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:102 +# args: msg.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ since\ pci\ device\ attached = can not set FT on vm[uuid:{0}] since pci device attached + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:108 +# args: msg.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached\ by\ passthrough = can not set FT on vm[uuid:{0}] because there are usb devices attached by passthrough + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:119 +# args: msg.getUuid() +can\ not\ set\ FT\ on\ vmm[uuid\:%s]\ since\ mdev\ device\ attached = can not set FT on vmm[uuid:{0}] since mdev device attached + +# at: src/main/java/org/zstack/ha/HaKvmHostSiblingChecker.java:257 +# args: struct.getHostUuid(),struct.getHostIp() +hosts\ failed\ to\ port\ scan\ the\ failure\ host[uuid\:%s,\ ip\:%s] = hosts failed to port scan the failure host[uuid:{0}, ip:{1}] + +# at: src/main/java/org/zstack/ha/HaKvmWorker.java:96 +# args: checkers.indexOf(checker) + 1,checkers.size(),checker.getClass().getSimpleName(),s.getSuccessTimes() * s.getSuccessInterval() +(%d/%d)\ start\ HaHostChecker\ %s\:\ predict\ time\ is\ [%d]\ seconds = ({0}/{1}) start HaHostChecker {2}: predict time is [{3}] seconds + +# at: src/main/java/org/zstack/ha/HaKvmWorker.java:160 +# args: self.getName(),self.getUuid() +cannot\ find\ the\ host\ of\ the\ vm[name\:%s,\ uuid\:%s],\ hostUuid\ is\ null = cannot find the host of the vm[name:{0}, uuid:{1}], hostUuid is null + +# at: src/main/java/org/zstack/ha/HaKvmWorker.java:167 +# args: +no\ HaHostChecker\ found,\ cannot\ do\ HA = no HaHostChecker found, cannot do HA + +# at: src/main/java/org/zstack/ha/HaManagementNodeChecker.java:102 +# args: +the\ management\ node\ fails\ to\ scan\ the\ host = the management node fails to scan the host + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1873 +# args: vmUuid +the\ VM[uuid\:%s]\ volume\ stored\ location\ primary\ storage\ is\ in\ a\ state\ of\ maintenance = the VM[uuid:{0}] volume stored location primary storage is in a state of maintenance + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1615 +# args: +VM\ is\ started\ successfully = VM is started successfully + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1618 +# args: +Failed\ to\ start\ the\ NeverStop\ VM = Failed to start the NeverStop VM + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:394 +# args: newValue +the\ value[%s]\ is\ lesser\ than\ 0\ or\ greater\ than\ 1\ = the value[{0}] is lesser than 0 or greater than 1 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:699 +# args: HaGlobalConfig.NEVER_STOP_VM_FAILURE_RETRY_DELAY.value(Long.class) +A\ GC\ job\ is\ submitted\ to\ HA\ the\ VM[retry\ delay\:\ %s\ seconds] = A GC job is submitted to HA the VM[retry delay: {0} seconds] + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1301 +# args: +HA\ is\ successfully\ completed = HA is successfully completed + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1309 +# args: +Failed\ to\ HA\ the\ VM = Failed to HA the VM + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1195 +# args: +vm\ stopped\ unexpectedly,\ double\ check\ state = vm stopped unexpectedly, double check state + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1204 +# args: vmUuid,hostUuid +cannot\ determine\ VM[%s]\ status\ on\ host[%s],\ try\ to\ start\ it = cannot determine VM[{0}] status on host[{1}], try to start it + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1601 +# args: +vm\ state\ is\ stopped,\ try\ to\ start\ it = vm state is stopped, try to start it + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1227 +# args: vmUuid,hostUuid +VM[%s]\ is\ running\ on\ host[%s] = VM[{0}] is running on host[{1}] + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1240 +# args: vmUuid,hostUuid +VM[%s]\ is\ paused\ on\ host[%s] = VM[{0}] is paused on host[{1}] + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1268 +# args: vm.getHypervisorType() +the\ hypervisor[%s]\ does\ not\ support\ VM\ HA = the hypervisor[{0}] does not support VM HA + +# at: src/main/java/org/zstack/ha/HostCheckResult.java:59 +# args: ratio,threshold,hostUuid,errors +[HA\ Worker]\:\ the\ success\ ratio[%s]\ below\ the\ threshold[%s],\ the\ host[uuid\:%s]\ is\ judged\ as\ dead,\ errors\ are\ %s.\ Start\ HA\ all\ the\ vms\ on\ this\ host\ before = [HA Worker]: the success ratio[{0}] below the threshold[{1}], the host[uuid:{2}] is judged as dead, errors are {3}. Start HA all the vms on this host before + +# at: src/main/java/org/zstack/ha/HostCheckResult.java:56 +# args: ratio,threshold +[HA\ worker]\:\ all\ host\ checkers\ are\ finished\ and\ the\ success\ ratio\ is\ %s\ that\ is\ greater\ than\ the\ threshold[%s];\ no\ HA\ need\ for\ the\ vms\ on\ this\ host\ before.\ Please\ wait\ for\ the\ host\ reconnected = [HA worker]: all host checkers are finished and the success ratio is {0} that is greater than the threshold[{1}]; no HA need for the vms on this host before. Please wait for the host reconnected + +# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:102 +# args: +VM\ state\ is\ not\ running,\ try\ to\ start\ it = VM state is not running, try to start it + +# at: src/main/java/org/zstack/header/backup/NonBackupInfo.java:14 +# args: +enter\ the\ new\ value\ here,\ empty\ means\ no\ change. = enter the new value here, empty means no change. + +# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:44 +# args: type +keyType\ not\ supported\ type\ [%s] = keyType not supported type [{0}] + +# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:60 +# args: msg.getKey(),msg.getType(),accountUuid +key\:\ [%s]\ with\ type\:\ [%s]\ already\ existed\ by\ accountUuid\:\ [%s] = key: [{0}] with type: [{1}] already existed by accountUuid: [{2}] + +# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:84 +# args: msg.getKey(),accountUuid +key\:\ [%s]\ already\ existed\ by\ accountUuid\:\ [%s] = key: [{0}] already existed by accountUuid: [{1}] + +# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:63 +# args: msg.getRegionId(),ak +regionId\ [%s]\ already\ created\ by\ ak\ [%s] = regionId [{0}] already created by ak [{1}] + +# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:46 +# args: type +dcType\ not\ supported\ type\ [%s] = dcType not supported type [{0}] + +# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterManagerImpl.java:96 +# args: msg.getUuid() +DataCenter\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = DataCenter [{0}] is still in sync progress, please wait. + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:55 +# args: msg.getZoneId(),izo.getUuid() +identity\ zone\ [%s]\ already\ existed,\ uuid\ is\:\ %s = identity zone [{0}] already existed, uuid is: {1} + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:72 +# args: type,dvo.getDcType().toString() +type\ [%s]\ is\ not\ matched\ datacenter\ type\ [%s] = type [{0}] is not matched datacenter type [{1}] + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:82 +# args: +either\ dataCenterUuid\ or\ regionId\ should\ be\ set,\ please\ check\ the\ parameters. = either dataCenterUuid or regionId should be set, please check the parameters. + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneManagerImpl.java:111 +# args: msg.getUuid() +IdentityZone\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = IdentityZone [{0}] is still in sync progress, please wait. + +# at: src/main/java/org/zstack/hybrid/network/HybridEipCascadeExtension.java:88 +# args: +EcsInstance\ must\ be\ running\ or\ stopped\ while\ deleting\ eip\ = EcsInstance must be running or stopped while deleting eip + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:83 +# args: vbri.getUuid(),vbri.getDataCenterUuid(),vrouteri.getUuid(),vrouteri.getDataCenterUuid() +router\ interface\ must\ be\ in\ the\ same\ datacenter,\ but\ ri[%s]\ is\ in\ dc[%s]\ and\ ri[%s]\ is\ in\ dc[%s] = router interface must be in the same datacenter, but ri[{0}] is in dc[{1}] and ri[{2}] is in dc[{3}] + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:93 +# args: vrouteri.getUuid(),vrouteri.getStatus() +router\ interface[%s]\ status\ is\ not\ idle,\ it\ is\ %s = router interface[{0}] status is not idle, it is {1} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:101 +# args: vrouteri.getUuid(),vrouteri.getOppositeInterfaceUuid() +router\ interface[%s]\ already\ has\ a\ connection,\ it\ is\ %s = router interface[{0}] already has a connection, it is {1} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:109 +# args: +accessPointUuid\ cannot\ be\ null\ if\ the\ router\ interface\ on\ VBR\ type\ router = accessPointUuid cannot be null if the router interface on VBR type router + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:183 +# args: +cannot\ delete\ system\ entry = cannot delete system entry + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:189 +# args: +only\ support\ intranet\ rule\ in\ vpc = only support intranet rule in vpc + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:194 +# args: msg.getCidr() +%s\ is\ not\ a\ valid\ cidr = {0} is not a valid cidr + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:204 +# args: +security\ group\ rule\ already\ existed = security group rule already existed + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:210 +# args: msg.getDstCidrBlock() +dstCidrBlock[%s]\ is\ not\ a\ valid\ cidr = dstCidrBlock[{0}] is not a valid cidr + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:239 +# args: msg.getNextHopType() +next\ hop\ type\ [%s]\ not\ supported\ create\ route\ entry\ now! = next hop type [{0}] not supported create route entry now! + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:235 +# args: msg.getNextHopUuid() +no\ such\ vpn\ gateway\:\ %s = no such vpn gateway: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:224 +# args: rivo.getvRouterType().toString(),msg.getvRouterType() +nexthop\ routerInterface\ belongs\ to\ %s,\ but\ the\ entry\ belongs\ to\ %s = nexthop routerInterface belongs to {0}, but the entry belongs to {1} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:217 +# args: msg.getNextHopUuid() +no\ such\ ecs\ instance\:\ %s = no such ecs instance: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:249 +# args: +virtual\ border\ router\ only\ support\ routerinterface\ as\ next\ hop\ type = virtual border router only support routerinterface as next hop type + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:269 +# args: msg.getCidrBlock(),vpcCidr +vswitch's\ cidr\ [%s]\ not\ in\ the\ vpc's\ [%s] = vswitch's cidr [{0}] not in the vpc's [{1}] + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:276 +# args: old.getUuid() +cidr\ is\ overlap\ by\ another\ vswitch\:\ %s = cidr is overlap by another vswitch: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:289 +# args: msg.getCidrBlock() +invalid\ CidrBlock\:\ %s,\ which\ must\ subnet\ in\ '10.0.0.0/8',\ '172.16.0.0/12',\ '192.168.0.0/16' = invalid CidrBlock: {0}, which must subnet in '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16' + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:305 +# args: msg.getvRouterUuid() +no\ such\ virtual\ router\:\ %s = no such virtual router: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:300 +# args: msg.getvRouterUuid() +no\ such\ virtual\ border\ router\:\ %s = no such virtual border router: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:312 +# args: msg.getLocalGatewayIp() +localGateway\ is\ not\ IPv4\:\ %s = localGateway is not IPv4: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:315 +# args: msg.getPeerGatewayIp() +peerGateway\ is\ not\ IPv4\:\ %s = peerGateway is not IPv4: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:318 +# args: msg.getPeeringSubnetMask() +peerGateway\ is\ not\ subnet\ mask\:\ %s = peerGateway is not subnet mask: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:322 +# args: msg.getVlanId() +vlanId\ is\ not\ number\:\ %s = vlanId is not number: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:332 +# args: msg.getEcsUuid(),msg.getEipUuid(),hevo.getAllocateResourceUuid() +couldn't\ attach\ eip\ to\ ecs\:\ [%s]\ ,\ eip\ \:[%s]\ already\ attached\ ecs\:[%s]\ = couldn't attach eip to ecs: [{0}] , eip :[{1}] already attached ecs:[{2}] + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:337 +# args: msg.getEcsUuid() +ecs\ [%s]\ already\ has\ public\ ip\ now = ecs [{0}] already has public ip now + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:343 +# args: msg.getEipUuid(),msg.getEcsUuid() +couldn't\ attach\ eip\ [%s]\ to\ ecs\:\ [%s]\ ,\ ecs\ is\ already\ attached = couldn't attach eip [{0}] to ecs: [{1}] , ecs is already attached + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:350 +# args: msg.getEipUuid(),msg.getEcsUuid() +eip[%s]\ and\ ecs[%s]\ should\ be\ in\ the\ same\ dataCenter\ = eip[{0}] and ecs[{1}] should be in the same dataCenter + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:359 +# args: msg.getEipUuid() +couldn't\ detach\ eip\ \:[%s],\ it\ is\ not\ attached\ on\ any\ instance\ = couldn't detach eip :[{0}], it is not attached on any instance + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:45 +# args: msg.getId() +%s\ is\ not\ a\ valid\ ipv4\ address = {0} is not a valid ipv4 address + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:51 +# args: +localCidr\ must\ be\ Cidr! = localCidr must be Cidr! + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:55 +# args: +remoteCidr\ must\ be\ Cidr! = remoteCidr must be Cidr! + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:62 +# args: +localCidr\ and\ remoteCidr\ must\ be\ Cidr! = localCidr and remoteCidr must be Cidr! + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnGatewayCascadeExtension.java:80 +# args: gateways.get(0).getUuid() +vpngateway\ [%s]\ existed,\ cannot\ delete\ remote = vpngateway [{0}] existed, cannot delete remote + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:343 +# args: oldSession.getUserUuid() +The\ user[%s]\ is\ not\ a\ platform\ user = The user[{0}] is not a platform user + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:994 +# args: results.size() +There\ are\ %d\ problems\ with\ the\ file.\ = There are {0} problems with the file. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1011 +# args: e.getMessage() +fail\ to\ load\ VirtualID\ info\ from\ file.\ because\n%s = fail to load VirtualID info from file. because\n{0} + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1022 +# args: +name\ cannot\ be\ empty.\ = name cannot be empty. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1030 +# args: cmsg.getUsername() +userName[%s]\ is\ repeated.\ = userName[{0}] is repeated. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1028 +# args: cmsg.username.length() +name\ exceeds\ max\ length\ of\ string.\ expected\ was\ <\=\ 255,\ actual\ was\ %s.\ = name exceeds max length of string. expected was <= 255, actual was {0}. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1026 +# args: +username\ cannot\ be\ empty.\ = username cannot be empty. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1036 +# args: cmsg.password.length() +Incorrect\ password\ length.\ expected\ was\ >\=\ 6\ and\ <\=\ 255,\ actual\ was\ %s.\ = Incorrect password length. expected was >= 6 and <= 255, actual was {0}. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1034 +# args: +password\ cannot\ be\ empty.\ = password cannot be empty. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1044 +# args: +email\ format\ does\ not\ match.\ = email format does not match. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1100 +# args: noMatchNames +organization[%s]\ is\ not\ exist.\ = organization[{0}] is not exist. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1108 +# args: repeatNames +organization[%s]\ in\ line\ is\ repeated.\ = organization[{0}] in line is repeated. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1116 +# args: repeatNames +organization[%s]\ is\ repeated.\ = organization[{0}] is repeated. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1146 +# args: noMatchName +project[%s]\ is\ not\ exist.\ = project[{0}] is not exist. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1340 +# args: +fail\ to\ build\ VirtualID\ info\ from\ file.\ = fail to build VirtualID info from file. + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1469 +# args: resourceUuid,projectUuid +virtualID[uuid\:%s]\ not\ in\ project[uuid\:%s] = virtualID[uuid:{0}] not in project[uuid:{1}] + +# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:144 +# args: self.getUuid() +Can\ not\ do\ operations,\ because\ current\ organization[uuid\:%s]\ is\ staled,\ please\ enable\ it = Can not do operations, because current organization[uuid:{0}] is staled, please enable it + +# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:688 +# args: puuid,self.getUuid() +organization[uuid\:%s]\ is\ parent\ of\ the\ organization[uuid\:%s],\ cannot\ set\ it\ as\ a\ child\ organization = organization[uuid:{0}] is parent of the organization[uuid:{1}], cannot set it as a child organization + +# at: src/main/java/org/zstack/iam2/IAM2ProjectBase.java:130 +# args: self.getUuid(),self.getName(),self.getState(),msg.getClass() +the\ project[uuid\:\ %s,\ name\:%s]\ is\ in\ state\ of\ %s\ which\ disallows\ the\ operation[%s] = the project[uuid: {0}, name:{1}] is in state of {2} which disallows the operation[{3}] + +# at: src/main/java/org/zstack/iam2/IAM2ProjectBase.java:910 +# args: +can\ not\ parse\ the\ cron\ expression = can not parse the cron expression + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:43 +# args: loginContext.getUsername() +project[name\:%s]\ not\ existing = project[name:{0}] not existing + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:51 +# args: puuid,loginContext.getUsername() +no\ account\ found\ for\ project[uuid\:%s,\ name\:%s] = no account found for project[uuid:{0}, name:{1}] + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:57 +# args: loginContext.getOperatorSession().getUserUuid() +wrong\ virtual\ ID[uuid\:%s],\ not\ existing\ or\ wrong\ password = wrong virtual ID[uuid:{0}], not existing or wrong password + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:62 +# args: vid.getName() +virtual\ ID[name\:%s]\ is\ disabled = virtual ID[name:{0}] is disabled + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:72 +# args: vid.getName(),loginContext.getUsername() +virtual\ ID[name\:%s]\ not\ belonging\ to\ the\ project[name\:%s] = virtual ID[name:{0}] not belonging to the project[name:{1}] + +# at: src/main/java/org/zstack/iam2/IAM2QuotaUpdateChecker.java:75 +# args: quota.getName(),quota.getIdentityUuid(),updatedValue,organizationUuid +the\ quota[name\:%s]\ of\ Account[uuid\:%s]\ can\ not\ be\ %d,\ otherwise\ it\ will\ exceeds\ the\ quota\ of\ organization[uuid\:%s] = the quota[name:{0}] of Account[uuid:{1}] can not be {2}, otherwise it will exceeds the quota of organization[uuid:{3}] + +# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:256 +# args: self.getUuid() +Can\ not\ do\ operations,\ because\ Current\ virtualID[uuid\:%s]\ is\ staled,\ please\ enable\ it = Can not do operations, because Current virtualID[uuid:{0}] is staled, please enable it + +# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:649 +# args: +only\ admin\ and\ the\ virtual\ ID\ itself\ can\ do\ the\ update = only admin and the virtual ID itself can do the update + +# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:653 +# args: msg.getVirtualIDUuid() +old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ virtual\ ID[uuid\:%s] = old password is not equal to the original password, cannot update the password of virtual ID[uuid:{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:50 +# args: attr.getValue() +attribute\ name\ cannot\ be\ null,\ value[%s] = attribute name cannot be null, value[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:54 +# args: attr.getName() +attribute\ name[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = attribute name[{0}] exceed the max length of 2048 chars + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:57 +# args: attr.getName(),attr.getValue() +attribute[name\:%s]\ value[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = attribute[name:{0}] value[{1}] exceed the max length of 2048 chars + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:173 +# args: msg.getOrganizationUuid(),msg.getName(),projectUsed,msg.getValue() +The\ Organization[uuid\:\ %s]\ used\ [name\:\ %s,\ usedValue\:\ %s]\ exceeds\ Request\:%s. = The Organization[uuid: {0}] used [name: {1}, usedValue: {2}] exceeds Request:{3}. + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:186 +# args: msg.getLoginExpired() +%s\ is\ not\ a\ valid\ value.\ Valid\ values\ are\ \ allow/rejection\ \ xxx\ to\ xxx = {0} is not a valid value. Valid values are allow/rejection xxx to xxx + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:192 +# args: msg.getUuid() +The\ default\ organization[%s]\ cannot\ be\ deleted = The default organization[{0}] cannot be deleted + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:201 +# args: msg.getName() +duplicate\ template\ name[%s] = duplicate template name[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:652 +# args: IAM2RolePolicyStatementHelper.PROJECT_ADMIN_ROLE_NAME +illegal\ operation,\ cannot\ add\ Role[%s] = illegal operation, cannot add Role[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:265 +# args: +admin\ is\ a\ reserved\ name,\ please\ use\ another\ name = admin is a reserved name, please use another name + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:273 +# args: msg.getName() +invalid\ name[%s],\ there\ has\ been\ a\ project\ or\ account\ with\ the\ same\ name = invalid name[{0}], there has been a project or account with the same name + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:281 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ group = attribute[uuid:{0}] is not for any group + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:289 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ organization = attribute[uuid:{0}] is not for any organization + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:297 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ project = attribute[uuid:{0}] is not for any project + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:305 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ virtual\ ID = attribute[uuid:{0}] is not for any virtual ID + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:325 +# args: +retire\ policy\ must\ be\ deleted\ before\ pull\ the\ project\ out\ of\ Retired\ state = retire policy must be deleted before pull the project out of Retired state + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:337 +# args: state +login\ is\ prohibited\ because\ the\ project\ is\ in\ state\ of\ %s = login is prohibited because the project is in state of {0} + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:347 +# args: name +no\ quota[name\:%s]\ found = no quota[name:{0}] found + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:371 +# args: msg.getUuid() +organization[uuid\:%s]\ is\ a\ Company\ that\ cannot\ have\ parent\ organization = organization[uuid:{0}] is a Company that cannot have parent organization + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:381 +# args: msg.getUuid(),msg.getParentUuid() +parent\ organization[uuid\:%s]\ cannot\ be\ a\ child\ organization[uuid\:%s]\ of\ a\ childOrganization = parent organization[uuid:{0}] cannot be a child organization[uuid:{1}] of a childOrganization + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:400 +# args: msg.getName() +duplicate\ virtualID\ name[%s] = duplicate virtualID name[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:418 +# args: msg.getName() +duplicate\ project\ name[%s] = duplicate project name[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:426 +# args: msg.getName() +invalid\ project\ name[%s],\ an\ account\ or\ project\ with\ the\ same\ name\ exists = invalid project name[{0}], an account or project with the same name exists + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:432 +# args: msg.getOrganizationUuid() +IAM2OrganizationVO[uuid\:%s]\ is\ not\ exists = IAM2OrganizationVO[uuid:{0}] is not exists + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:515 +# args: refVO.getProjectUuid(),refVO.getOrganizationUuid() +The\ project[uuid\=%s]\ has\ been\ attached\ to\ the\ organization[uuid\=%s] = The project[uuid={0}] has been attached to the organization[uuid={1}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:557 +# args: msg.getProjectUuid() +The\ project[uuid\=%s]\ is\ not\ attached = The project[uuid={0}] is not attached + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:568 +# args: uuids +organizations%s\ are\ company\ that\ cannot\ be\ children\ of\ other\ organization = organizations{0} are company that cannot be children of other organization + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:582 +# args: msg.getVirtualIDUuid(),msg.getProjectUuid() +virtual\ id[uuid\:\ %s]\ is\ not\ in\ project[uuid\:\ %s] = virtual id[uuid: {0}] is not in project[uuid: {1}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:679 +# args: staleVirtualIDs +can\ not\ operate\ stale\ virtual\ ids\:\ %s = can not operate stale virtual ids: {0} + +# at: src/main/java/org/zstack/iam2/attribute/SystemAttributes.java:69 +# args: +attribute[name\:%s]\ is\ a\ system\ attribute\ that\ cannot\ be\ updated = attribute[name:{0}] is a system attribute that cannot be updated + +# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:38 +# args: inv.getValue() +virtual\ ID[uuid\:%s]\ not\ existing = virtual ID[uuid:{0}] not existing + +# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:45 +# args: inv.getValue(),((IAM2OrganizationAttributeInventory) inv).getOrganizationUuid() +virtual\ ID[uuid\:%s]\ not\ in\ organization[uuid\:%s] = virtual ID[uuid:{0}] not in organization[uuid:{1}] + +# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:50 +# args: oinv.getOrganizationUuid() +organization[uuid\:%s]\ already\ has\ a\ supervisor = organization[uuid:{0}] already has a supervisor + +# at: src/main/java/org/zstack/iam2/attribute/project/LoginExpired.java:58 +# args: pinv.getUuid(),pinv.getName() +the\ project[uuid\:%s,\ name\:%s]\ already\ has\ a\ login\ expired\ strategy = the project[uuid:{0}, name:{1}] already has a login expired strategy + +# at: src/main/java/org/zstack/iam2/attribute/project/LoginExpired.java:109 +# args: projectUuid,ProjectState.Enabled.toString() +IAM2ProjectVO[uuid\:%s]\ is\ not\ %s,\ state\ change\ is\ not\ allowed = IAM2ProjectVO[uuid:{0}] is not {1}, state change is not allowed + +# at: src/main/java/org/zstack/iam2/attribute/project/Retire.java:65 +# args: pinv.getUuid(),pinv.getName() +the\ project[uuid\:%s,\ name\:%s]\ already\ has\ a\ retire\ policy = the project[uuid:{0}, name:{1}] already has a retire policy + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:53 +# args: +invalid\ value,\ no\ 'at',\ 'after'\ or\ 'exceed'\ found = invalid value, no 'at', 'after' or 'exceed' found + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:58 +# args: value +invalid\ value,\ %s = invalid value, {0} + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:64 +# args: ss[0],Arrays.asList(Means.values()).toString() +invalid\ means[%s],\ allowed\ means\ are\ %s = invalid means[{0}], allowed means are {1} + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:100 +# args: policyValue +invalid\ spending\ value[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10.001 = invalid spending value[{0}], it should be in format of for example 10.001 + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:94 +# args: policyValue,Double.MAX_VALUE +invalid\ spending\ value[%s],\ spending\ value\ should\ between\ 0\ and\ %f = invalid spending value[{0}], spending value should between 0 and {1} + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:87 +# args: policyValue +invalid\ time[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10m,\ 1h,\ 2d = invalid time[{0}], it should be in format of for example 10m, 1h, 2d + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:78 +# args: policyValue +invalid\ date[%s],\ it\ should\ be\ in\ format\ of\ yyyy-MM-dd\ HH\:mm\:ss = invalid date[{0}], it should be in format of yyyy-MM-dd HH:mm:ss + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:107 +# args: policyValue,dateFormat.format(new Timestamp(System.currentTimeMillis())) +invalid\ date\ or\ time[%s],\ it\ cannot\ be\ before\ current\ time[%s] = invalid date or time[{0}], it cannot be before current time[{1}] + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/AbstractAdminAttribute.java:17 +# args: vid,attributeName +virtual\ ID[uuid\:%s]\ already\ has\ admin\ related\ attributes,\ can\ not\ add\ %s = virtual ID[uuid:{0}] already has admin related attributes, can not add {1} + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/IAM2OrganizationOperator.java:29 +# args: inv.getValue(),IAM2_ORGANIZATION_OPERATION.getName() +organiztion\ ID[uuid\:%s]\ already\ has\ opoeration\ attributes,\ can\ not\ add\ %s = organiztion ID[uuid:{0}] already has opoeration attributes, can not add {1} + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/IAM2ProjectOperator.java:35 +# args: idinv.getVirtualIDUuid() +virtual\ id[uuid\:%s]\ already\ has\ a\ project\ operator\ attribute = virtual id[uuid:{0}] already has a project operator attribute + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/PlatformAdminZoneRelation.java:36 +# args: inv.getValue() +cannot\ find\ zone[uuid\:%s] = cannot find zone[uuid:{0}] + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:71 +# args: inv.getValue() +project[uuid\:%s]\ already\ has\ a\ project\ admin = project[uuid:{0}] already has a project admin + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:83 +# args: inv.getValue() +project[uuid\:%s]\ not\ existing = project[uuid:{0}] not existing + +# at: src/main/java/org/zstack/iam2/rbac/IAM2AuthorizationBackend.java:133 +# args: deniedApis +the\ operations[%s]\ is\ denied = the operations[{0}] is denied + +# at: src/main/java/org/zstack/iam2/rbac/IAM2OperationTargetAPIRequestChecker.java:114 +# args: +since\ the\ project\ starts\ the\ force\ securityGroup,\ systemtag\ is\ required\ for\ VM\ operation = since the project starts the force securityGroup, systemtag is required for VM operation + +# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:28 +# args: session.getAccountUuid() +project\ of\ account[uuid\:%s]\ not\ exists = project of account[uuid:{0}] not exists + +# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:37 +# args: projectUuid +project[uuid\:%s]\ is\ retired,\ reject\ all\ operations = project[uuid:{0}] is retired, reject all operations + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:107 +# args: +system\ tag\ requested.\ need\ specify\ default\ security\ group\ for\ vm\ nic\ by\ system\ tag\ L3_NETWORK_SECURITY_GROUP_uuidS_REF\ with\ format\ l3\:\:{%s}\:\:SecurityGroupUuids\:\:{%s},\ because\ force\ security\ group\ is\ enabled = system tag requested. need specify default security group for vm nic by system tag L3_NETWORK_SECURITY_GROUP_uuidS_REF with format l3::'{{0}'}::SecurityGroupUuids::'{{1}'}, because force security group is enabled + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:114 +# args: l3Uuid,msg.getL3NetworkUuid() +the\ l3Uuid[%s]\ in\ the\ label\ is\ inconsistent\ with\ the\ l3Uuid[%s]\ in\ the\ parameter = the l3Uuid[{0}] in the label is inconsistent with the l3Uuid[{1}] in the parameter + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:124 +# args: projectUuid +since\ force\ security\ group\ is\ enabled,\ securityGroupUuid\ in\ the\ tag\ must\ be\ in\ the\ project[%s] = since force security group is enabled, securityGroupUuid in the tag must be in the project[{0}] + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:145 +# args: msg.getL3NetworkUuid(),msg.getSecurityGroupUuid() +nics\ on\ the\ l3Network[uuid\:%s]\ are\ attached\ to\ the\ securityGroup.\ before\ you\ can\ detach\ the\ l3Network\ from\ the\ securityGroup,\ you\ need\ to\ detach\ the\ nics\ from\ the\ securityGroup. = nics on the l3Network[uuid:{0}] are attached to the securityGroup. before you can detach the l3Network from the securityGroup, you need to detach the nics from the securityGroup. + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:161 +# args: msg.getUuid() +the\ default\ security\ group\ %s\ cannot\ be\ deleted\ by\ enabling\ the\ enforced\ security\ group\ function = the default security group {0} cannot be deleted by enabling the enforced security group function + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:165 +# args: msg.getUuid() +this\ security\ group\ %s\ is\ bound\ to\ vm,\ please\ try\ again\ after\ unbinding = this security group {0} is bound to vm, please try again after unbinding + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:175 +# args: sessionInventory.getAccountUuid(),securityGroupUuid +account[%s]\ cannot\ operation\ the\ default\ securityGroup[%s] = account[{0}] cannot operation the default securityGroup[{1}] + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:187 +# args: msg.getSession().getAccountUuid() +account[%s]\ not\ allowed\ to\ operate\ on\ default\ securityGroup = account[{0}] not allowed to operate on default securityGroup + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:241 +# args: refVOS.stream().map(VmNicSecurityGroupRefVO::getVmNicUuid).collect(Collectors.joining(",")),msg.getSecurityGroupUuid() +vm's\ nic[uuid\:%s]\ only\ has\ one\ security\ group,\ can\ not\ delete\ the\ nic\ from\ security\ group[uuid\:%s] = vm's nic[uuid:{0}] only has one security group, can not delete the nic from security group[uuid:{1}] + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupFactory.java:60 +# args: projectUuid +can't\ find\ the\ quota\ for\ the\ security\ group\ for\ the\ corresponding\ project\ %s = can't find the quota for the security group for the corresponding project {0} + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupFactory.java:64 +# args: +security\ group\ quota\ cannot\ less\ than\ 1 = security group quota cannot less than 1 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:35 +# args: +The\ iam2\ script\ function\ is\ not\ enabled. = The iam2 script function is not enabled. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:39 +# args: +Script\ doesn't\ have\ any\ content. = Script doesn't have any content. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:45 +# args: +The\ amount\ of\ params\ exceeds\ the\ limit. = The amount of params exceeds the limit. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:61 +# args: +Specified\ script\ executor\ are\ not\ supported. = Specified script executor are not supported. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:139 +# args: +Decode\ script\ content\ failed. = Decode script content failed. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:147 +# args: +Script\ content\ is\ blank. = Script content is blank. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:179 +# args: +Run\ iam2\ script\ failed. = Run iam2 script failed. + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:244 +# args: +Cannot\ read\ the\ result\ of\ the\ script\ running. = Cannot read the result of the script running. + +# at: src/main/java/org/zstack/identity/AccountBase.java:327 +# args: group.getUuid(),msg.getAccountUuid() +the\ user\ group[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = the user group[uuid:{0}] does not belong to the account[uuid:{1}] + +# at: src/main/java/org/zstack/identity/AccountBase.java:528 +# args: self.getUuid(),ruuid +the\ account[uuid\:\ %s]\ doesn't\ have\ a\ resource[uuid\:\ %s] = the account[uuid: {0}] doesn't have a resource[uuid: {1}] + +# at: src/main/java/org/zstack/identity/AccountBase.java:590 +# args: user.getUuid(),msg.getAccountUuid() +the\ user[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = the user[uuid:{0}] does not belong to the account[uuid:{1}] + +# at: src/main/java/org/zstack/identity/AccountBase.java:595 +# args: user.getUuid() +old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ user[uuid\:%s] = old password is not equal to the original password, cannot update the password of user[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:4224 -# args: self.getHostUuid(),cpuNum - oldCpuNum,struct.alignedMemory - oldMemorySize -host[uuid\:%s]\ capacity\ is\ not\ enough\ to\ offer\ cpu[%s],\ memory[%s\ bytes] = host[uuid:{0}] capacity is not enough to offer cpu[{1}], memory[{2} bytes] +# at: src/main/java/org/zstack/identity/AccountInterceptor.java:55 +# args: +wrong\ password = wrong password -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:4444 -# args: isoUuid,self.getUuid() -ISO[uuid\:%s]\ is\ not\ attached\ to\ VM[uuid\:%s] = ISO[uuid:{0}] is not attached to VM[uuid:{1}] +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1660 +# args: JSONObjectUtil.toJsonString(s) +a\ statement\ must\ have\ effect\ field.\ Invalid\ statement[%s] = a statement must have effect field. Invalid statement[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5174 -# args: self.getUuid() -unable\ to\ start\ the\ vm[uuid\:%s].\ It\ doesn't\ have\ any\ nic,\ please\ attach\ a\ nic\ and\ try\ again = unable to start the vm[uuid:{0}]. It doesn't have any nic, please attach a nic and try again +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1663 +# args: JSONObjectUtil.toJsonString(s) +a\ statement\ must\ have\ action\ field.\ Invalid\ statement[%s] = a statement must have action field. Invalid statement[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5411 -# args: cdRomSpecs.size(),max -One\ vm\ cannot\ create\ %s\ CDROMs,\ vm\ can\ only\ add\ %s\ CDROMs = One vm cannot create {0} CDROMs, vm can only add {1} CDROMs +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1666 +# args: JSONObjectUtil.toJsonString(s) +a\ statement\ must\ have\ a\ non-empty\ action\ field.\ Invalid\ statement[%s] = a statement must have a non-empty action field. Invalid statement[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:6301 -# args: msg.getVmInstanceUuid(),max -VM[uuid\:%s]\ can\ only\ add\ %s\ CDROMs = VM[uuid:{0}] can only add {1} CDROMs +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:175 +# args: resourceUuid +cannot\ find\ the\ resource[uuid\:%s];\ wrong\ resourceUuid\ or\ the\ resource\ is\ admin\ resource = cannot find the resource[uuid:{0}]; wrong resourceUuid or the resource is admin resource -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:6371 -# args: self.getUuid(),msg.getPriority(),reply.getError() -update\ vm[%s]\ priority\ to\ [%s]\ failed,because\ %s = update vm[{0}] priority to [{1}] failed,because {2} +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:405 +# args: msg.getUserUuid() +the\ user\ specified\ by\ the\ userUuid[%s]\ does\ not\ belong\ to\ the\ current\ account,\ and\ the\ current\ account\ is\ not\ an\ admin\ account,\ so\ it\ has\ no\ permission\ to\ check\ the\ user'spermissions = the user specified by the userUuid[{0}] does not belong to the current account, and the current account is not an admin account, so it has no permission to check the user'spermissions -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:58 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceStartNewCreatedVmExtensionPoint[%s]\ refuses\ to\ create\ vm[uuid\:%s]\ because\ %s = VmInstanceStartNewCreatedVmExtensionPoint[{0}] refuses to create vm[uuid:{1}] because {2} +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1055 +# args: accountUuid +cannot\ find\ the\ account[uuid\:%s] = cannot find the account[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:176 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceRebootExtensionPoint[%s]\ refuses\ to\ reboot\ vm[uuid\:%s]\ because\ %s = VmInstanceRebootExtensionPoint[{0}] refuses to reboot vm[uuid:{1}] because {2} +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1495 +# args: +accountName\ and\ accountUuid\ cannot\ both\ be\ null,\ you\ must\ specify\ at\ least\ one = accountName and accountUuid cannot both be null, you must specify at least one -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:218 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceDestroyVmExtensionPoint[%s]\ refuses\ to\ destroy\ vm[uuid\:%s]\ because\ %s = VmInstanceDestroyVmExtensionPoint[{0}] refuses to destroy vm[uuid:{1}] because {2} +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1506 +# args: msg.getName(),msg.getAccountUuid() +unable\ to\ create\ a\ group.\ A\ group\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = unable to create a group. A group called {0} is already under the account[uuid:{1}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:259 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceStartExtensionPoint[%s]\ refuses\ to\ start\ vm[uuid\:%s]\ because\ %s = VmInstanceStartExtensionPoint[{0}] refuses to start vm[uuid:{1}] because {2} +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1516 +# args: msg.getName(),msg.getAccountUuid() +unable\ to\ create\ a\ user.\ A\ user\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = unable to create a user. A user called {0} is already under the account[uuid:{1}] + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1525 +# args: msg.getName() +unable\ to\ create\ an\ account.\ An\ account\ already\ called\ %s = unable to create an account. An account already called {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:251 +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1532 # args: -Spice\ certificate\ does\ not\ exist,\ Please\ check\ if\ spice\ tls\ is\ enabled = Spice certificate does not exist, Please check if spice tls is enabled +account\ cannot\ delete\ itself = account cannot delete itself -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:434 -# args: msg.getImageUuid(),msg.getZoneUuid() -the\ image[uuid\:%s]\ is\ not\ on\ any\ backup\ storage\ that\ has\ been\ attached\ to\ the\ zone[uuid\:%s] = the image[uuid:{0}] is not on any backup storage that has been attached to the zone[uuid:{1}] +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1538 +# args: +cannot\ delete\ builtin\ admin\ account. = cannot delete builtin admin account. -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:502 -# args: image.getName(),image.getUuid() -the\ image[name\:%s,\ uuid\:%s]\ is\ an\ ISO,\ rootDiskSize\ must\ be\ set = the image[name:{0}, uuid:{1}] is an ISO, rootDiskSize must be set +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1544 +# args: +Only\ admin\ can\ delete\ account. = Only admin can delete account. -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:542 -# args: image.getName(),image.getUuid() -zoneUuid\ must\ be\ set\ because\ the\ image[name\:%s,\ uuid\:%s]\ is\ on\ multiple\ backup\ storage = zoneUuid must be set because the image[name:{0}, uuid:{1}] is on multiple backup storage +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1552 +# args: +the\ current\ session\ is\ an\ account\ session.\ You\ need\ to\ specify\ the\ field\ 'uuid'\ of\ the\ user\ you\ want\ to\ update = the current session is an account session. You need to specify the field 'uuid' of the user you want to update -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1453 -# args: tuple.get(0, String.class),tuple.get(1, String.class) -unable\ to\ enable\ this\ function.\ There\ are\ multi\ nics\ of\ L3\ network[uuid\:%s]\ in\ the\ vm[uuid\:\ %s] = unable to enable this function. There are multi nics of L3 network[uuid:{0}] in the vm[uuid: {1}] +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1567 +# args: msg.getUuid() +your\ are\ login\ as\ a\ user,\ you\ cannot\ another\ user[uuid\:%s] = your are login as a user, you cannot another user[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1466 -# args: hostname,tag -hostname[%s]\ specified\ in\ system\ tag[%s]\ is\ not\ a\ valid\ domain\ name = hostname[{0}] specified in system tag[{1}] is not a valid domain name +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1575 +# args: +all\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = all is set to false, accountUuids cannot be null or empty -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1478 -# args: hostnameCount -only\ one\ hostname\ system\ tag\ is\ allowed,\ but\ %s\ got = only one hostname system tag is allowed, but {0} got +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1583 +# args: +toPublic\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = toPublic is set to false, accountUuids cannot be null or empty -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1514 -# args: ip,sysTag -%s\ is\ not\ a\ valid\ IPv6\ address.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = {0} is not a valid IPv6 address. Please correct your system tag[{1}] of static IP +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1632 +# args: policy.getName(),policy.getUuid(),msg.getSession().getAccountUuid() +policy[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = policy[name: {0}, uuid: {1}] doesn't belong to the account[uuid: {2}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1508 -# args: ip,sysTag -%s\ is\ not\ a\ valid\ IPv4\ address.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = {0} is not a valid IPv4 address. Please correct your system tag[{1}] of static IP +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1646 +# args: user.getName(),user.getUuid(),msg.getSession().getAccountUuid() +user[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = user[name: {0}, uuid: {1}] doesn't belong to the account[uuid: {2}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1530 -# args: ip,l3Uuid,cr.getReason() -IP[%s]\ is\ not\ available\ on\ the\ L3\ network[uuid\:%s]\ because\:\ %s = IP[{0}] is not available on the L3 network[uuid:{1}] because: {2} +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1650 +# args: group.getName(),group.getUuid(),msg.getSession().getAccountUuid() +group[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = group[name: {0}, uuid: {1}] doesn't belong to the account[uuid: {2}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1573 -# args: uuid -l3\ network\ [uuid\:\ %s]\ is\ added\ to\ vm\ more\ than\ once = l3 network [uuid: {0}] is added to vm more than once +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1691 +# args: msg.getName() +unable\ to\ update\ name.\ An\ account\ already\ called\ %s = unable to update name. An account already called {0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1567 -# args: statefulIpv6Count -there\ are\ %d\ ipv6\ stateful\ network\ on\ same\ nic = there are {0} ipv6 stateful network on same nic +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1702 +# args: msg.getUuid() +old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ account[uuid\:\ %s] = old password is not equal to the original password, cannot update the password of account[uuid: {0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1590 -# args: primaryL3Uuid,sysTag -L3\ network[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ dualStackNic = L3 network[uuid:{0}] not found. Please correct your system tag[{1}] of dualStackNic +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1707 +# args: +the\ name\ of\ admin\ account\ cannot\ be\ updated = the name of admin account cannot be updated -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1595 -# args: primaryL3Uuid,secondaryL3Uuid -L3\ networks[primaryL3Uuid\:%s,\ secondaryL3Uuid\:%s]\ of\ dualStackNic\ is\ not\ on\ same\ l2\ network = L3 networks[primaryL3Uuid:{0}, secondaryL3Uuid:{1}] of dualStackNic is not on same l2 network +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1713 +# args: +only\ admin\ account\ can\ update\ it's\ password = only admin account can update it's password -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1606 -# args: secondaryL3Uuid -L3\ networks[uuid\:%s]\ does\ not\ have\ ip\ range = L3 networks[uuid:{0}] does not have ip range +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1720 +# args: account.getUuid(),account.getName(),msg.getUuid() +account[uuid\:\ %s,\ name\:\ %s]\ is\ a\ normal\ account,\ it\ cannot\ reset\ the\ password\ of\ another\ account[uuid\:\ %s] = account[uuid: {0}, name: {1}] is a normal account, it cannot reset the password of another account[uuid: {2}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1629 -# args: tag,sameTag.getResourceUuid(),hostname,l3Uuid -conflict\ hostname\ in\ system\ tag[%s];\ there\ has\ been\ a\ VM[uuid\:%s]\ having\ hostname[%s]\ on\ L3\ network[uuid\:%s] = conflict hostname in system tag[{0}]; there has been a VM[uuid:{1}] having hostname[{2}] on L3 network[uuid:{3}] +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1731 +# args: msg.getName(),msg.getIdentityUuid() +cannot\ find\ Quota[name\:\ %s]\ for\ the\ account[uuid\:\ %s] = cannot find Quota[name: {0}] for the account[uuid: {1}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1662 -# args: o,order -invalid\ boot\ device[%s]\ in\ boot\ order[%s] = invalid boot device[{0}] in boot order[{1}] +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1738 +# args: quota.getIdentityUuid(),quota.getIdentityType() +can\ not\ find\ quota\ update\ checker\ for\ quota[uuid\:%s,\ type\:%s] = can not find quota update checker for quota[uuid:{0}, type:{1}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1680 -# args: resourceUuid -Already\ have\ one\ userdata\ systemTag\ for\ vm[uuid\:\ %s]. = Already have one userdata systemTag for vm[uuid: {0}]. +# at: src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java:32 +# args: quota.getName(),quota.getIdentityUuid(),updatedValue +the\ quota[name\:%s]\ of\ account[uuid\:%s]\ can\ not\ be\ %d = the quota[name:{0}] of account[uuid:{1}] can not be {2} + +# at: src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java:54 +# args: accountUuid,quotaName,used,updatedValue +the\ account[uuid\:%s]\ used\ [name\:%s,\ usedValue\:%s]\ exceeds\ request\ quota\:\ %d = the account[uuid:{0}] used [name:{1}, usedValue:{2}] exceeds request quota: {3} + +# at: src/main/java/org/zstack/identity/login/LoginManagerImpl.java:46 +# args: loginType +unsupported\ login\ type\ %s = unsupported login type {0} + +# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:180 +# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),uuid,resourceType.getSimpleName() +permission\ denied,\ the\ account[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ resource[uuid\:%s,\ type\:%s] = permission denied, the account[uuid:{0}] is not the owner of the resource[uuid:{1}, type:{2}] + +# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:228 +# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),uuid,type +permission\ denied,\ the\ account[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ tagged\ resource[uuid\:%s,\ type\:%s] = permission denied, the account[uuid:{0}] is not the owner of the tagged resource[uuid:{1}, type:{2}] + +# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:251 +# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),resourceWithNoAccess,resourceType.getSimpleName() +the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resources[uuid\:%s,\ type\:%s] = the account[uuid:{0}] has no access to the resources[uuid:{1}, type:{2}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1700 +# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:80 +# args: rbacEntity.getApiMessage().getClass().getName() +operation[API\:%s]\ is\ denied\ by\ default,\ please\ contact\ admin\ to\ correct\ it = operation[API:{0}] is denied by default, please contact admin to correct it + +# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:187 +# args: p.getName(),p.getUuid() +the\ operation\ is\ denied\ by\ the\ policy[name\:%s\ uuid\:%s] = the operation is denied by the policy[name:{0} uuid:{1}] + +# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:200 +# args: p.getName(),p.getUuid(),fname +the\ operation\ is\ denied\ by\ the\ policy[name\:%s,\ uuid\:%s],\ field[%s]\ is\ not\ permitted\ to\ set = the operation is denied by the policy[name:{0}, uuid:{1}], field[{2}] is not permitted to set + +# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:92 # args: -Shouldn't\ be\ more\ than\ one\ userdata\ systemTag\ for\ one\ vm. = Shouldn't be more than one userdata systemTag for one vm. +cannot\ update\ a\ system\ or\ predefined\ role = cannot update a system or predefined role -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1823 -# args: type -vm\ machine\ type\ requires\ [q35,\ pc],\ but\ get\ [%s] = vm machine type requires [q35, pc], but get [{0}] +# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:108 +# args: +cannot\ delete\ a\ system\ or\ predefined\ role = cannot delete a system or predefined role -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2235 -# args: ref.getResourceUuid() -the\ resource[uuid\:%s]\ is\ a\ ROOT\ volume,\ you\ cannot\ change\ its\ owner,\ instead,change\ the\ owner\ of\ the\ VM\ the\ root\ volume\ belongs\ to = the resource[uuid:{0}] is a ROOT volume, you cannot change its owner, instead,change the owner of the VM the root volume belongs to +# at: src/main/java/org/zstack/image/AddImageLongJob.java:187 +# args: +Failed\ because\ management\ node\ restarted. = Failed because management node restarted. -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:182 -# args: vmType -clean\ traffic\ is\ not\ supported\ for\ vm\ type\ [%s] = clean traffic is not supported for vm type [{0}] +# at: src/main/java/org/zstack/image/BackupStorageDeleteBitGC.java:35 +# args: backupStorageUuid,bsStatus +the\ backup\ storage[uuid\:%s]\ is\ not\ in\ status\ of\ Connected,\ current\ status\ is\ %s = the backup storage[uuid:{0}] is not in status of Connected, current status is {1} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:172 -# args: msg.getMac() -Duplicate\ mac\ address\ [%s] = Duplicate mac address [{0}] +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:101 +# args: +The\ aarch64\ architecture\ does\ not\ support\ legacy. = The aarch64 architecture does not support legacy. -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:91 -# args: VmInstanceState.Stopped,msg.getVmInstanceUuid() -Can\ not\ set\ security\ level\ to\ not\ %s\ vm\ [uuid\:%s] = Can not set security level to not {0} vm [uuid:{1}] +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:108 +# args: vol.getUuid(),vol.getStatus() +volume[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = volume[uuid:{0}] is not Ready, it's {1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:112 +# args: vol.getUuid(),vol.getState() +volume[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = volume[uuid:{0}] is not Enabled, it's {1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:119 +# args: vsvo.getUuid(),vsvo.getStatus() +volume\ snapshot[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = volume snapshot[uuid:{0}] is not Ready, it's {1} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:108 +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:123 +# args: vsvo.getUuid(),vsvo.getState() +volume\ snapshot[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = volume snapshot[uuid:{0}] is not Enabled, it's {1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:142 # args: -The\ operation\ only\ allows\ on\ user\ vm = The operation only allows on user vm +ISO\ cannot\ be\ used\ as\ system\ image = ISO cannot be used as system image -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:138 -# args: msg.getVmInstanceUuid(),volumeVOS.stream().map(VolumeVO::getUuid).collect(Collectors.toList()),primaryStorageUuid,(totalCapacity - snapshotsCapacity) * msg.getNames().size(),primaryStorageVO.getCapacity().getAvailableCapacity() -there\ are\ not\ enough\ capacity\ for\ full\ vm\ clone\ to\ vm[uuid\:\ %s],\ volumes[uuid\:\ %s]\ on\ primary\ storage[uuid\:\ %s]\ required\:\ %s\ bytes,\ current\ available\ capacity\ is\ %s\ bytes = there are not enough capacity for full vm clone to vm[uuid: {0}], volumes[uuid: {1}] on primary storage[uuid: {2}] required: {3} bytes, current available capacity is {4} bytes +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:148 +# args: msg.getFormat() +unknown\ format[%s] = unknown format[{0}] -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:152 -# args: msg.getVmNicUuid() -The\ nic\ [%s%s]\ is\ not\ mounted\ on\ the\ VM = The nic [{0}{1}] is not mounted on the VM +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:152 +# args: msg.getType() +unsupported\ image\ type[%s] = unsupported image type[{0}] + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:169 +# args: msg.getBackupStorageUuids(),BackupStorageStatus.Connected,BackupStorageState.Enabled +no\ backup\ storage\ specified\ in\ uuids%s\ is\ available\ for\ adding\ this\ image;\ they\ are\ not\ in\ status\ %s\ or\ not\ in\ state\ %s,\ or\ the\ uuid\ is\ invalid\ backup\ storage\ uuid = no backup storage specified in uuids{0} is available for adding this image; they are not in status {1} or not in state {2}, or the uuid is invalid backup storage uuid -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:158 +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:180 # args: -The\ operation\ only\ allows\ on\ user\ vm\ = The operation only allows on user vm +url\ must\ starts\ with\ 'file\:///',\ 'http\://',\ 'https\://',\ 'ftp\://',\ 'sftp\://'\ or\ '/' = url must starts with 'file:///', 'http://', 'https://', 'ftp://', 'sftp://' or '/' -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:163 -# args: vmInstanceVO.getUuid() -The\ operation\ only\ allows\ when\ vm\ [%s]\ state\ is\ stopped\ = The operation only allows when vm [{0}] state is stopped +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:191 +# args: path +absolute\ path\ must\ be\ used = absolute path must be used -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:192 -# args: msg.getVmInstanceUuid() -user\ has\ no\ privilege\ to\ change\ image\ of\ vm\ %s = user has no privilege to change image of vm {0} +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:214 +# args: path,blackList.value() +image\ path\ [%s]\ is\ in\ black\ list\ %s = image path [{0}] is in black list {1} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:205 +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:223 # args: -Can't\ change\ vm\ image\ when\ it's\ not\ stopped = Can't change vm image when it's not stopped +all\ images\ on\ this\ server\ cannot\ be\ used = all images on this server cannot be used -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:211 +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:228 +# args: whiteList.value() +image\ path\ is\ not\ in\ white\ list\:\ %s = image path is not in white list: {0} + +# at: src/main/java/org/zstack/image/ImageBase.java:214 +# args: self.getUuid(),self.getName() +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ any\ backup\ storage = the image[uuid:{0}, name:{1}] is not on any backup storage + +# at: src/main/java/org/zstack/image/ImageBase.java:224 +# args: self.getUuid(),self.getName() +No\ connected\ backup\ storage\ found\ for\ image[uuid\:%s,\ name\:%s] = No connected backup storage found for image[uuid:{0}, name:{1}] + +# at: src/main/java/org/zstack/image/ImageBase.java:416 +# args: msg.getImageUuid(),JSONObjectUtil.toJsonString(errors) +detach\ iso[uuid\=%s]\ from\ vm\ failed,\ errors\ are\ %s = detach iso[uuid={0}] from vm failed, errors are {1} + +# at: src/main/java/org/zstack/image/ImageBase.java:782 +# args: self.getUuid(),self.getName(),bsUuid +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ the\ backup\ storage[uuid\:%s] = the image[uuid:{0}, name:{1}] is not on the backup storage[uuid:{2}] + +# at: src/main/java/org/zstack/image/ImageBase.java:724 +# args: self.getUuid(),self.getName(),ref.getStatus(),bsUuid +the\ image[uuid\:%s,\ name\:%s]'s\ status[%s]\ is\ not\ Deleted\ on\ the\ backup\ storage[uuid\:%s] = the image[uuid:{0}, name:{1}]'s status[{2}] is not Deleted on the backup storage[uuid:{3}] + +# at: src/main/java/org/zstack/image/ImageBase.java:766 +# args: self.getUuid(),self.getName() +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ any\ backup\ storage = the image[uuid:{0}, name:{1}] is not deleted on any backup storage + +# at: src/main/java/org/zstack/image/ImageBase.java:787 +# args: self.getUuid(),self.getName(),bsUuid +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ the\ backup\ storage[uuid\:%s] = the image[uuid:{0}, name:{1}] is not deleted on the backup storage[uuid:{2}] + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:812 +# args: bootModeCount +only\ one\ bootMode\ system\ tag\ is\ allowed,\ but\ %d\ got = only one bootMode system tag is allowed, but {0} got + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:830 +# args: bootMode,systemTag +[%s]\ specified\ in\ system\ tag\ [%s]\ is\ not\ a\ valid\ boot\ mode = [{0}] specified in system tag [{1}] is not a valid boot mode + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1455 +# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) +unable\ to\ allocate\ backup\ storage\ specified\ by\ uuids%s,\ list\ errors\ are\:\ %s = unable to allocate backup storage specified by uuids{0}, list errors are: {1} + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1581 +# args: rootVolumeUuid +failed\ to\ create\ image\ from\ root\ volume[uuid\:%s]\ on\ all\ backup\ storage,\ see\ cause\ for\ one\ of\ errors = failed to create image from root volume[uuid:{0}] on all backup storage, see cause for one of errors + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1809 +# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) +failed\ to\ allocate\ all\ backup\ storage[uuid\:%s],\ a\ list\ of\ error\:\ %s = failed to allocate all backup storage[uuid:{0}], a list of error: {1} + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1779 # args: -Can't\ change\ vm\ image\ without\ L3\ network = Can't change vm image without L3 network +cannot\ find\ proper\ backup\ storage = cannot find proper backup storage -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:226 -# args: msg.getVmInstanceUuid() -make\ sure\ the\ primary\ storage\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = make sure the primary storage vm[uuid:{0}] was on is Enabled and Connected +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1922 +# args: volumeUuid,msgData.getBackupStorageUuids() +failed\ to\ create\ data\ volume\ template\ from\ volume[uuid\:%s]\ on\ all\ backup\ storage%s.\ See\ cause\ for\ one\ of\ errors = failed to create data volume template from volume[uuid:{0}] on all backup storage{1}. See cause for one of errors -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:241 -# args: msg.getVmInstanceUuid() -make\ sure\ the\ last\ host\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = make sure the last host vm[uuid:{0}] was on is Enabled and Connected +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1999 +# args: imageUuid +image[uuid\:%s]\ is\ not\ on\ creating,\ please\ wait\ for\ it\ to\ cancel\ itself. = image[uuid:{0}] is not on creating, please wait for it to cancel itself. -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:260 -# args: msg.getVmInstanceUuid(),msg.getImageUuid() -user\ has\ no\ privilege\ to\ change\ root\ volume\ of\ vm\ %s\ using\ image\ %s = user has no privilege to change root volume of vm {0} using image {1} +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2005 +# args: volumeUuid +volume[uuid\:%s]\ has\ been\ deleted.\ no\ need\ to\ cancel = volume[uuid:{0}] has been deleted. no need to cancel + +# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:48 +# args: +Failed\ to\ set\ security\ level,\ because\ security\ level\ is\ disabled. = Failed to set security level, because security level is disabled. + +# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:58 +# args: msg.getSecurityLevel(),Arrays.stream(SecurityLevel.values()).map(SecurityLevel::getCode).collect(Collectors.toList()) +Unknown\ security\ level\ code[%s],\ supported\ values\ are\ %s = Unknown security level code[{0}], supported values are {1} + +# at: src/main/java/org/zstack/image/UploadImageTracker.java:197 +# args: +upload\ session\ expired = upload session expired + +# at: src/main/java/org/zstack/imagereplicator/ImageReplicatorImpl.java:366 +# args: targetBsUuid +target\ backup\ storage[uuid\:%s]\ became\ unavailable = target backup storage[uuid:{0}] became unavailable + +# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:30 +# args: String.join(",", msg.getBackupStorageUuids()),msg.getReplicationGroupUuid() +One\ or\ more\ backup\ storage[uuids\:%s]\ has\ been\ added\ to\ replication\ group[uuid\:%s] = One or more backup storage[uuids:{0}] has been added to replication group[uuid:{1}] + +# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:41 +# args: bsUuid +Backup\ storage[uuids\:%s]\ is\ not\ of\ type\ ImageStore = Backup storage[uuids:{0}] is not of type ImageStore + +# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:51 +# args: bsUuid +Backup\ storage[uuids\:%s]\ is\ not\ attached\ to\ any\ Zone = Backup storage[uuids:{0}] is not attached to any Zone + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:65 +# args: l3NetworkUuid +Network\ [uuid\:\ %s]\ does't\ not\ have\ IPsec\ service = Network [uuid: {0}] does't not have IPsec service + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:74 +# args: rcidr +the\ remote\ CIDR[%s]\ is\ same\ to\ existed\ cidrs = the remote CIDR[{0}] is same to existed cidrs + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:86 +# args: rcidr,tempCidr +the\ remote\ CIDR[%s]\ and\ remote\ CIDR[%s]\ are\ overlaped = the remote CIDR[{0}] and remote CIDR[{1}] are overlaped + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:109 +# args: lcidr,tempCidr +the\ CIDR[%s]\ of\ local\ router\ and\ remote\ CIDR[%s]\ are\ overlaped = the CIDR[{0}] of local router and remote CIDR[{1}] are overlaped -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:271 +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:122 # args: -either\ uuid\ or\ account\ or\ password\ must\ be\ set = either uuid or account or password must be set +all\ networks\ in\ same\ IPsecConnection\ should\ be\ same\ type = all networks in same IPsecConnection should be same type -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:279 -# args: msg.getDirection() -direction\ must\ be\ set\ in\ (in,\ out),\ but\ was\ %s = direction must be set in (in, out), but was {0} +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:128 +# args: L3NetworkConstant.L3_BASIC_NETWORK_TYPE +IPsecConnection\ can\ ONLY\ have\ 1\ network\ for\ %s = IPsecConnection can ONLY have 1 network for {0} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:285 -# args: -Monitor\ number\ must\ be\ 1\ or\ 2\ or\ 4. = Monitor number must be 1 or 2 or 4. +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:140 +# args: l3Uuid +L3Network\ [uuid\:\ %s]\ has\ not\ been\ attached\ to\ vpc\ router = L3Network [uuid: {0}] has not been attached to vpc router -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:293 -# args: -outboundBandwidth\ and\ inboundBandwidth\ must\ be\ set\ at\ lease\ one. = outboundBandwidth and inboundBandwidth must be set at lease one. +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:162 +# args: vrUuids.toArray()[0] +there\ is\ no\ master\ vpc\ for\ ha\ group\ %s = there is no master vpc for ha group {0} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:302 +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:159 # args: -the\ nic\ can't\ apply\ Qos\ with\ the\ port\ mirror\ service\ at\ same\ time. = the nic can't apply Qos with the port mirror service at same time. - -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:311 -# args: msg.getUuid() -nic\ id\:\ %s\ does\ not\ exist... = nic id: {0} does not exist... +all\ networks\ in\ same\ IPsecConnection\ must\ be\ attached\ to\ same\ VPC\ router = all networks in same IPsecConnection must be attached to same VPC router -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:86 -# args: msg.getAllocatorStrategy() -unsupported\ host\ allocation\ strategy[%s] = unsupported host allocation strategy[{0}] +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:172 +# args: masterUuid +there\ is\ a\ vpc[%s]\ using\ old\ ipsec\ plugin,\ upgrade\ it\ to\ create\ ipsec = there is a vpc[{0}] using old ipsec plugin, upgrade it to create ipsec -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:72 -# args: msg.getType() -unsupported\ instance\ offering\ type[%s] = unsupported instance offering type[{0}] +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:185 +# args: tuples.get(0).get(0, String.class),tuples.get(0).get(1, String.class) +there\ already\ have\ ipsec\ connection[uuid\:%s,\ name\:%s]\ with\ the\ same\ vrouter\ and\ peerAddress = there already have ipsec connection[uuid:{0}, name:{1}] with the same vrouter and peerAddress -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:76 -# args: msg.getCpuNum() -cpu\ num[%s]\ is\ less\ than\ 1 = cpu num[{0}] is less than 1 +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:209 +# args: msg.getVipUuid(),useForList.toString() +the\ vip[uuid\:%s]\ has\ been\ used\ for\ %s = the vip[uuid:{0}] has been used for {1} -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:80 -# args: msg.getMemorySize() -memory\ size[%s\ bytes]\ is\ less\ than\ 16M,\ no\ modern\ operating\ system\ is\ likely\ able\ to\ boot\ with\ such\ small\ memory\ size = memory size[{0} bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:214 +# args: msg.getPeerAddress() +the\ peerAddress[%s]\ cannot\ be\ the\ same\ to\ the\ VIP\ address = the peerAddress[{0}] cannot be the same to the VIP address -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:92 -# args: msg.getAllocationStrategy() -unsupported\ primary\ storage\ allocation\ strategy[%s] = unsupported primary storage allocation strategy[{0}] +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:218 +# args: msg.getPeerAddress() +the\ peerAddress[%s]\ is\ not\ an\ IPv4\ address = the peerAddress[{0}] is not an IPv4 address -# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:101 +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:230 # args: -the\ console\ agent\ is\ not\ connected;\ it's\ mostly\ like\ the\ management\ node\ just\ starts,\ please\ wait\ for\ the\ console\ agent\ connected,\ or\ you\ can\ reconnect\ it\ manually\ if\ disconnected\ for\ a\ long\ time. = the console agent is not connected; it's mostly like the management node just starts, please wait for the console agent connected, or you can reconnect it manually if disconnected for a long time. - -# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:122 -# args: vm.getUuid() -cannot\ find\ host\ IP\ of\ the\ vm[uuid\:%s],\ is\ the\ vm\ running??? = cannot find host IP of the vm[uuid:{0}], is the vm running??? +the\ authKey\ cannot\ contain\ white\ space\ and\ special\ characters\ of\ '\"`\\ = the authKey cannot contain white space and special characters of '\"`\\ -# at: src/main/java/org/zstack/console/ConsoleApiInterceptor.java:52 -# args: msg.getVmInstanceUuid(),state -Console\ is\ only\ available\ when\ the\ VM[uuid\:%s]\ is\ Running,\ but\ the\ current\ state\ is\ %s = Console is only available when the VM[uuid:{0}] is Running, but the current state is {1} +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:249 +# args: vipVO.getIp() +Ipsec\ VIP\ [%s]\ cannot\ be\ the\ first\ or\ the\ last\ IP\ of\ the\ CIDR\ with\ the\ public\ address\ pool\ type = Ipsec VIP [{0}] cannot be the first or the last IP of the CIDR with the public address pool type -# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:62 -# args: uri.toString() -establish\ VNC\:\ unexpected\ uri\:\ %s = establish VNC: unexpected uri: {0} +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:281 +# args: +must\ include\ l3\ networks\ in\ APIAttachL3NetworksToIPsecConnectionMsg = must include l3 networks in APIAttachL3NetworksToIPsecConnectionMsg -# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:148 -# args: ret.getError() -unable\ to\ check\ console\ proxy\ availability,\ because\ %s = unable to check console proxy availability, because {0} +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:288 +# args: l3NetworkUuid +L3\ network\ [%s]\ is\ not\ vpc\ network,\ can\ not\ be\ attached\ or\ detached\ to\ ipsec = L3 network [{0}] is not vpc network, can not be attached or detached to ipsec -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:153 -# args: -Ansible\ private\ key\ not\ found. = Ansible private key not found. +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:269 +# args: l3NetworkUuid,msg.getIPsecConnectionUuid() +L3\ network\ [%s]\ can\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s]twice = L3 network [{0}] can not be attached to ipsec [uuid :{1}]twice -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:347 -# args: uuid -invalid\ management\ node\ UUID[%s] = invalid management node UUID[{0}] +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:292 +# args: l3NetworkUuid,msg.getIPsecConnectionUuid() +L3\ network\ [%s]\ is\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s] = L3 network [{0}] is not be attached to ipsec [uuid :{1}] -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:468 -# args: -failed\ to\ configure\ consoleProxyOverriddenIp = failed to configure consoleProxyOverriddenIp +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:302 +# args: cidr,msg.getIPsecConnectionUuid() +Cidr\ [%s]\ is\ already\ in\ the\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = Cidr [{0}] is already in the Cidrs of ipsec [uuid :{1}] -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:491 -# args: -failed\ to\ reconnect\ console\ proxy = failed to reconnect console proxy +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:316 +# args: cidr,msg.getIPsecConnectionUuid() +Cidr\ [%s]\ is\ not\ in\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = Cidr [{0}] is not in Cidrs of ipsec [uuid :{1}] -# at: src/main/java/org/zstack/core/ansible/AnsibleRunner.java:397 -# args: -User\ name\ or\ password\ or\ port\ number\ may\ be\ problematic = User name or password or port number may be problematic +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:324 +# args: msg.getUuid() +can\ not\ change\ state\ because\ ipsec\ [uuid\:%s]\ status\ is\ not\ ready = can not change state because ipsec [uuid:{0}] status is not ready -# at: src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java:70 -# args: targetIp,callbackIp,callBackPort -cannot\ nmap\ from\ agent\:\ %s\ to\ callback\ address\:\ %s\:%s = cannot nmap from agent: {0} to callback address: {1}:{2} +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:330 +# args: msg.getUuid() +could\ not\ reconnect\ this\ ipsec\ [uuid\:%s],\ please\ upgrade\ ipsec\ version = could not reconnect this ipsec [uuid:{0}], please upgrade ipsec version -# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:106 -# args: srcFolder,srcRes.getStdout(),srcRes.getStderr() -cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s].\nstdout\:%s\nstderr\:%s = cannot check md5sum of files in the folder[{0}].\nstdout:{1}\nstderr:{2} +# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:133 +# args: msg.getIPsecConnectionUuid() +cannot\ find\ the\ IPsecconnection[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the IPsecconnection[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:121 -# args: dstFolder,hostname,dstRes.getStdout(),dstRes.getStderr() -cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s]\ on\ the\ host[ip\:%s].\nstdout\:%s\nstderr\:%s = cannot check md5sum of files in the folder[{0}] on the host[ip:{1}].\nstdout:{2}\nstderr:{3} +# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:466 +# args: Long.toString(range2.getStart()),Long.toString(range2.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),msg.getVipUuid() +Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ UDP = Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: UDP -# at: src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java:681 -# args: errMsg -message\ is\ not\ in\ corrected\ JSON\ mediaType,\ %s = message is not in corrected JSON mediaType, {0} +# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:504 +# args: cidr,l3Inv.getUuid(),uuid,rCidr +cidr[%s]\ of\ attached\ L3Network\ [uuid\:%s]\ is\ overlapped\ with\ ipsec\ [uuid\:%s]\ remote\ cidr[%s] = cidr[{0}] of attached L3Network [uuid:{1}] is overlapped with ipsec [uuid:{2}] remote cidr[{3}] -# at: src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java:543 -# args: rsp.getStatusCode(),rsp.getBody() -HTTP\ ERROR,\ status\ code\:\ %s,\ body\:\ %s = HTTP ERROR, status code: {0}, body: {1} +# at: src/main/java/org/zstack/ipsec/vyos/VyosCreateIPsecFlow.java:69 +# args: errorCode.getDescription() +create\ ipsec\ to\ ha\ route\ failed,\ because\ %s = create ipsec to ha route failed, because {0} -# at: src/main/java/org/zstack/core/cloudbus/EventFacadeImpl.java:68 -# args: EventFacade.WEBHOOK_TYPE -for\ webhooks\ with\ type[%s],\ the\ field\ opaque\ cannot\ be\ null = for webhooks with type[{0}], the field opaque cannot be null +# at: src/main/java/org/zstack/ipsec/vyos/VyosDeleteIPsecFlow.java:55 +# args: errorCode.getDescription() +delete\ ipsec\ from\ ha\ group\ failed\ because\ %s = delete ipsec from ha group failed because {0} -# at: src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java:90 -# args: msg.getCategory(),msg.getName() -Unable\ to\ find\ GlobalConfig[category\:\ %s,\ name\:\ %s] = Unable to find GlobalConfig[category: {0}, name: {1}] +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:178 +# args: rcidr,cidr +the\ remoteCidr[%s]\ is\ overlaped\ with\ VirtualRouter\ interface\ cidr[%s] = the remoteCidr[{0}] is overlaped with VirtualRouter interface cidr[{1}] -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:77 +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:293 # args: -non\ file\ or\ jsoncontent\ input = non file or jsoncontent input +vyos\ doesn't\ support\ aes-192\ as\ IkeEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos doesn't support aes-192 as IkeEncryptionAlgorithm, available options aes-128, aes-256, 3des -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:82 +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:299 # args: -file\ or\ jsoncontent\ cannot\ both\ nonempty = file or jsoncontent cannot both nonempty +vyos\ doesn't\ support\ aes-192\ as\ PolicyEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos doesn't support aes-192 as PolicyEncryptionAlgorithm, available options aes-128, aes-256, 3des -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:114 -# args: e.getMessage() -Unable\ to\ scan\ folder\:\ %s = Unable to scan folder: {0} +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:305 +# args: msg.getIkeDhGroup() +vyos\ doesn't\ support\ %d\ as\ Ike\ DhGroup\ = vyos doesn't support {0} as Ike DhGroup -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:118 -# args: filename -%s\ is\ not\ existed\ or\ is\ empty\ folder = {0} is not existed or is empty folder +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:788 +# args: errorCode.getDescription() +sync\ to\ ha\ group\ failed,\ because\:%s = sync to ha group failed, because:{0} -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:255 -# args: -elaboration\ code\ must\ be\ number! = elaboration code must be number! +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:675 +# args: errorCode.getDescription() +apply\ to\ ha\ group\ failed,\ because\ %s = apply to ha group failed, because {0} -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:328 -# args: -arg\ 'startTime'\ should\ format\ like\ 'yyyy-MM-dd\ HH\:mm\:ss'\ or\ '1545380003000' = arg 'startTime' should format like 'yyyy-MM-dd HH:mm:ss' or '1545380003000' +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:768 +# args: vrUuid +update\ ipsec\ version\ failed,\ because\:vpc[%s]\ not\ exist = update ipsec version failed, because:vpc[{0}] not exist -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:325 -# args: from -%s\ is\ not\ a\ Long\ value\ Number = {0} is not a Long value Number +# at: src/main/java/org/zstack/kvm/KVMApiInterceptor.java:46 +# args: msg.getManagementIp() +there\ has\ been\ a\ kvm\ host\ having\ management\ ip[%s] = there has been a kvm host having management ip[{0}] -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:368 -# args: returnValue.get(0).getContent(),returnValue.get(0).getReason() -%s\:\ %s = {0}: {1} +# at: src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java:70 +# args: rsp.getPort(),vm.getUuid() +unexpected\ VNC\ port\ number[%d]\ for\ VM\ [uuid\:%s] = unexpected VNC port number[{0}] for VM [uuid:{1}] -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:476 -# args: -input\ args\ 'regex'\ or\ 'category'\ must\ be\ set = input args 'regex' or 'category' must be set +# at: src/main/java/org/zstack/kvm/KVMHost.java:465 +# args: self.getUuid() +host[uuid\:%s]\ has\ been\ deleted = host[uuid:{0}] has been deleted -# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:17 -# args: service.getName() -service[%s]\ has\ been\ registered = service[{0}] has been registered +# at: src/main/java/org/zstack/kvm/KVMHost.java:2499 +# args: msg.getVmUuid(),vmState +vm[uuid\:%s]\ is\ not\ Running\ or\ Stopped,\ current\ state[%s] = vm[uuid:{0}] is not Running or Stopped, current state[{1}] -# at: src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java:244 -# args: vo.getUuid(),vo.getName() -cannot\ trigger\ a\ finished\ GC\ job[uuid\:%s,\ name\:%s] = cannot trigger a finished GC job[uuid:{0}, name:{1}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:745 +# args: ret.getNewVolumeInstallPath() +after\ block\ commit,\ new\ volume\ path\ still\ use\ %s = after block commit, new volume path still use {0} -# at: src/main/java/org/zstack/core/progress/ProgressApiInterceptor.java:38 -# args: msg.getApiId() -parameter\ apiId[%s]\ is\ not\ a\ valid\ uuid. = parameter apiId[{0}] is not a valid uuid. +# at: src/main/java/org/zstack/kvm/KVMHost.java:877 +# args: host.getUuid(),webSsh.status +create\ connection\ to\ host[%s]\ failed,\ because\ %s = create connection to host[{0}] failed, because {1} -# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:526 -# args: method.toString().toLowerCase(),url,rsp.getStatusCode(),rsp.getBody() -failed\ to\ %s\ to\ %s,\ status\ code\:\ %s,\ response\ body\:\ %s = failed to {0} to {1}, status code: {2}, response body: {3} +# at: src/main/java/org/zstack/kvm/KVMHost.java:1326 +# args: reply.getError() +check\ host\ capacity\ failed,\ because\:%s = check host capacity failed, because:{0} -# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:513 -# args: method.toString().toLowerCase(),url,e.getMessage() -failed\ to\ %s\ to\ %s,\ IO\ Error\:\ %s = failed to {0} to {1}, IO Error: {2} +# at: src/main/java/org/zstack/kvm/KVMHost.java:1337 +# args: msg.getHostUuid(),rsp.getTotalMemory(),reservedSize +The\ host[uuid\:%s]'s\ available\ memory\ capacity[%s]\ is\ lower\ than\ the\ reserved\ capacity[%s] = The host[uuid:{0}]'s available memory capacity[{1}] is lower than the reserved capacity[{2}] -# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:569 -# args: url,finalTimeout -unable\ to\ echo\ %s\ in\ %sms = unable to echo {0} in {1}ms +# at: src/main/java/org/zstack/kvm/KVMHost.java:1392 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ register\ colo\ heartbeat\ for\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = unable to register colo heartbeat for vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3} -# at: src/main/java/org/zstack/core/retry/Retry.java:102 -# args: __name__,times,interval -an\ operation[%s]\ fails\ after\ retrying\ %s\ times\ with\ the\ interval\ %s\ seconds = an operation[{0}] fails after retrying {1} times with the interval {2} seconds +# at: src/main/java/org/zstack/kvm/KVMHost.java:1448 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ start\ colo\ sync\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = unable to start colo sync vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3} -# at: src/main/java/org/zstack/core/salt/SaltRunner.java:296 -# args: stateName,targetIp,retry -failed\ to\ run\ salt\ state[%s]\ on\ system[%s],\ failed\ after\ %s\ retries = failed to run salt state[{0}] on system[{1}], failed after {2} retries +# at: src/main/java/org/zstack/kvm/KVMHost.java:1503 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ config\ secondary\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = unable to config secondary vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3} -# at: src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java:84 -# args: targetIp -scp\ is\ not\ found\ on\ system[%s],\ unable\ to\ setup\ salt = scp is not found on system[{0}], unable to setup salt +# at: src/main/java/org/zstack/kvm/KVMHost.java:1535 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ config\ primary\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = unable to config primary vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3} -# at: src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java:81 -# args: ApiTimeoutGlobalProperty.MINIMAL_TIMEOUT -api\ timeout\ cannot\ be\ set\ smaller\ than\ %s = api timeout cannot be set smaller than {0} +# at: src/main/java/org/zstack/kvm/KVMHost.java:1576 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ get\ first\ boot\ dev\ of\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = unable to get first boot dev of vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3} -# at: src/main/java/org/zstack/core/webhook/WebhookApiInterceptor.java:28 -# args: url -Invalid\ url[%s] = Invalid url[{0}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:1625 +# args: msg.getVmInstanceUuid(),rsp.getError() +failed\ to\ get\ vm[uuid\:%s]\ device\ address,\ because\:%s = failed to get vm[uuid:{0}] device address, because:{1} -# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:99 -# args: -parameters\ [accountUuid]\ only\ can\ be\ used\ by\ admin\ user! = parameters [accountUuid] only can be used by admin user! +# at: src/main/java/org/zstack/kvm/KVMHost.java:1680 +# args: msg.getHostUuid(),rsp.getError() +failed\ to\ get\ host[uuid\:%s]\ virtualizer\ info,\ because\:%s = failed to get host[uuid:{0}] virtualizer info, because:{1} -# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:54 -# args: msg.getExpirePolicy() -expire\ policy\:\ %s\ is\ not\ valid = expire policy: {0} is not valid +# at: src/main/java/org/zstack/kvm/KVMHost.java:1762 +# args: ret.getError() +failed\ to\ increase\ vm\ cpu,\ error\ details\:\ %s = failed to increase vm cpu, error details: {0} -# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:57 -# args: msg.getVlan() -vlanId[%s]\ has\ been\ existed! = vlanId[{0}] has been existed! +# at: src/main/java/org/zstack/kvm/KVMHost.java:1860 +# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),result.getExitErrorMessage() +unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2} ] to do DNS check, please check if username/password is wrong; {3} -# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:129 -# args: -create\ daho\ vll\ task\ failed! = create daho vll task failed! +# at: src/main/java/org/zstack/kvm/KVMHost.java:1942 +# args: self.getUuid(),self.getStatus() +the\ host[uuid\:%s,\ status\:%s]\ is\ not\ Connected = the host[uuid:{0}, status:{1}] is not Connected -# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:170 -# args: msg.getAccountUuid() -no\ aliyun\ account\ found\ for\ accountUuid\:\ %s = no aliyun account found for accountUuid: {0} +# at: src/main/java/org/zstack/kvm/KVMHost.java:2280 +# args: volume.getUuid(),state +cannot\ do\ volume\ snapshot\ merge\ when\ vm[uuid\:%s]\ is\ in\ state\ of\ %s.\ The\ operation\ is\ only\ allowed\ when\ vm\ is\ Running\ or\ Stopped = cannot do volume snapshot merge when vm[uuid:{0}] is in state of {1}. The operation is only allowed when vm is Running or Stopped -# at: src/main/java/org/zstack/drs/DRSBase.java:201 -# args: -Advice\ not\ allowed\ while\ scheduling = Advice not allowed while scheduling +# at: src/main/java/org/zstack/kvm/KVMHost.java:2287 +# args: KVMConstant.MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION,libvirtVersion +live\ volume\ snapshot\ merge\ needs\ libvirt\ version\ greater\ than\ %s,\ current\ libvirt\ version\ is\ %s.\ Please\ stop\ vm\ and\ redo\ the\ operation\ or\ detach\ the\ volume\ if\ it's\ data\ volume = live volume snapshot merge needs libvirt version greater than {0}, current libvirt version is {1}. Please stop vm and redo the operation or detach the volume if it's data volume -# at: src/main/java/org/zstack/drs/DRSBase.java:264 -# args: -delete\ DRS\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = delete DRS is not allowed while the vm is being migrated +# at: src/main/java/org/zstack/kvm/KVMHost.java:2911 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +failed\ to\ update\ nic[vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = failed to update nic[vm:{0}] on kvm host[uuid:{1}, ip:{2}],because {3} -# at: src/main/java/org/zstack/drs/DRSBase.java:324 -# args: -Scheduling\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = Scheduling is not allowed while the vm is being migrated +# at: src/main/java/org/zstack/kvm/KVMHost.java:2963 +# args: msg.getNicInventory().getUuid(),msg.getNicInventory().getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +failed\ to\ attach\ nic[uuid\:%s,\ vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = failed to attach nic[uuid:{0}, vm:{1}] on kvm host[uuid:{2}, ip:{3}],because {4} -# at: src/main/java/org/zstack/drs/DRSBase.java:435 -# args: -Lack\ of\ host\ CPU,\ memory\ monitoring\ data = Lack of host CPU, memory monitoring data +# at: src/main/java/org/zstack/kvm/KVMHost.java:2959 +# args: msg.getNicInventory().getUuid(),msg.getNicInventory().getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError(),msg.getNicInventory().getInternalName() +failed\ to\ attach\ nic[uuid\:%s,\ vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s,\ please\ try\ again\ or\ delete\ device[%s]\ by\ yourself = failed to attach nic[uuid:{0}, vm:{1}] on kvm host[uuid:{2}, ip:{3}],because {4}, please try again or delete device[{5}] by yourself -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:55 -# args: msg.getClusterUuid() -The\ cluster[%s]\ has\ created\ DRS = The cluster[{0}] has created DRS +# at: src/main/java/org/zstack/kvm/KVMHost.java:3018 +# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() +failed\ to\ detach\ data\ volume[uuid\:%s,\ installPath\:%s]\ from\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to detach data volume[uuid:{0}, installPath:{1}] from vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:59 -# args: -DRS\ is\ disabled = DRS is disabled +# at: src/main/java/org/zstack/kvm/KVMHost.java:3105 +# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() +failed\ to\ attach\ data\ volume[uuid\:%s,\ installPath\:%s]\ to\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to attach data volume[uuid:{0}, installPath:{1}] to vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:64 -# args: -thresholds\ can\ not\ be\ empty = thresholds can not be empty +# at: src/main/java/org/zstack/kvm/KVMHost.java:3149 +# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() +failed\ to\ destroy\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to destroy vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:73 -# args: threshold.getThresholdName() -illegal\ thresholdName[%s] = illegal thresholdName[{0}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:3281 +# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() +failed\ to\ stop\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to stop vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:77 -# args: threshold.getOperator() -illegal\ threshold\ operator[%s] = illegal threshold operator[{0}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:3386 +# args: msg.getHostUuid(),ret.getError() +Host[%s]\ update\ spice\ channel\ config\ faild,\ because\ %s = Host[{0}] update spice channel config faild, because {1} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:81 -# args: -thresholdValue\ can\ not\ be\ empty = thresholdValue can not be empty +# at: src/main/java/org/zstack/kvm/KVMHost.java:3505 +# args: total +when\ the\ vm\ platform\ is\ Other,\ the\ number\ of\ dataVolumes\ and\ cdroms\ cannot\ exceed\ 3,\ currently\ %s = when the vm platform is Other, the number of dataVolumes and cdroms cannot exceed 3, currently {0} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:86 -# args: -illegal\ thresholdValue,\ valid\ range\:\ (0,\ 100] = illegal thresholdValue, valid range: (0, 100] +# at: src/main/java/org/zstack/kvm/KVMHost.java:3997 +# args: msg.getPhysicalInterface(),context.getInventory().getUuid(),context.getInventory().getManagementIp() +failed\ to\ check\ physical\ network\ interfaces[names\ \:\ %s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s] = failed to check physical network interfaces[names : {0}] on kvm host[uuid:{1}, ip:{2}] -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:103 -# args: -GlobalConfig\ ENABLE_DRS\ is\ closed = GlobalConfig ENABLE_DRS is closed +# at: src/main/java/org/zstack/kvm/KVMHost.java:4128 +# args: self.getUuid(),ret.getHostUuid(),dbf.getDbVersion(),ret.getVersion() +detected\ abnormal\ status[host\ uuid\ change,\ expected\:\ %s\ but\:\ %s\ or\ agent\ version\ change,\ expected\:\ %s\ but\:\ %s]\ of\ kvmagent,it's\ mainly\ caused\ by\ kvmagent\ restarts\ behind\ zstack\ management\ server.\ Report\ this\ to\ ping\ task,\ it\ will\ issue\ a\ reconnect\ soon = detected abnormal status[host uuid change, expected: {0} but: {1} or agent version change, expected: {2} but: {3}] of kvmagent,it's mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:107 -# args: msg.getUuid(),vo.getState().toString() -The\ DRS[%s]\ state\ is\ %s = The DRS[{0}] state is {1} +# at: src/main/java/org/zstack/kvm/KVMHost.java:4283 +# args: self.getUuid(),self.getManagementIp(),connectPath,rsp.getError() +unable\ to\ connect\ to\ kvm\ host[uuid\:%s,\ ip\:%s,\ url\:%s],\ because\ %s = unable to connect to kvm host[uuid:{0}, ip:{1}, url:{2}], because {3} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:122 -# args: adviceVO.getDrsUuid() -The\ DRS[%s]\ automation\ level\ is\ not\ manual = The DRS[{0}] automation level is not manual +# at: src/main/java/org/zstack/kvm/KVMHost.java:4342 +# args: errorCodeList != null && StringUtils.isNotEmpty(errorCodeList.getReadableDetails()) ? errorCodeList.getReadableDetails() : "please check network" +host\ can\ not\ access\ any\ primary\ storage,\ %s = host can not access any primary storage, {0} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:136 -# args: msg.getAdviceUuid() -advice[%s]\ has\ expired = advice[{0}] has expired +# at: src/main/java/org/zstack/kvm/KVMHost.java:4482 +# args: getSelf().getManagementIp(),getSelf().getPort(),TimeUnit.MILLISECONDS.toSeconds(sshTimeout) +the\ host[%s]\ ssh\ port[%s]\ not\ open\ after\ %s\ seconds,\ connect\ timeout = the host[{0}] ssh port[{1}] not open after {2} seconds, connect timeout -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:145 -# args: -Successfully\ executed,\ no\ repeated\ executions\ allowed = Successfully executed, no repeated executions allowed +# at: src/main/java/org/zstack/kvm/KVMHost.java:4542 +# args: checkList +failed\ to\ ping\ all\ DNS/IP\ in\ %s;\ please\ check\ /etc/resolv.conf\ to\ make\ sure\ your\ host\ is\ able\ to\ reach\ public\ internet = failed to ping all DNS/IP in {0}; please check /etc/resolv.conf to make sure your host is able to reach public internet + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4540 +# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() +unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:\ %d,\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = unable to connect to KVM[ip:{0}, username:{1}, sshPort: {2}, ] to do DNS check, please check if username/password is wrong; {3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4585 +# args: self.getManagementIp(),restf.getHostName(),ret.getStderr(),ret.getExitErrorMessage() +the\ KVM\ host[ip\:%s]\ cannot\ access\ the\ management\ node's\ callback\ url.\ It\ seems\ that\ the\ KVM\ host\ cannot\ reach\ the\ management\ IP[%s].\ %s\ %s = the KVM host[ip:{0}] cannot access the management node's callback url. It seems that the KVM host cannot reach the management IP[{1}]. {2} {3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4582 +# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() +unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d]\ to\ check\ the\ management\ node\ connectivity,please\ check\ if\ username/password\ is\ wrong;\ %s = unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2}] to check the management node connectivity,please check if username/password is wrong; {3} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:152 -# args: adviceVO.getVmUuid() -The\ vm[%s]\ has\ been\ deleted = The vm[{0}] has been deleted +# at: src/main/java/org/zstack/kvm/KVMHost.java:4611 +# args: hostRet.getExitErrorMessage() +unable\ to\ Check\ whether\ the\ host\ is\ taken\ over,\ \ because\ %s = unable to Check whether the host is taken over, because {0} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:155 -# args: adviceVO.getVmUuid() -The\ vm[%s]\ state\ is\ not\ running = The vm[{0}] state is not running +# at: src/main/java/org/zstack/kvm/KVMHost.java:4625 +# args: timeRet.getExitErrorMessage() +Unable\ to\ get\ the\ timestamp\ of\ the\ flag,\ \ because\ %s = Unable to get the timestamp of the flag, because {0} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:158 -# args: adviceVO.getVmUuid(),adviceVO.getVmSourceHostUuid() -The\ vm[%s]\ is\ no\ longer\ on\ the\ source\ host[%s] = The vm[{0}] is no longer on the source host[{1}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:4634 +# args: self.getManagementIp(),hostOutput,diff,HostGlobalConfig.PING_HOST_INTERVAL.value(int.class) +the\ host[ip\:%s]\ has\ been\ taken\ over,\ because\ the\ takeover\ flag[HostUuid\:%s]\ already\ exists\ and\ utime[%d]\ has\ not\ exceeded\ host\ ping\ interval[%d] = the host[ip:{0}] has been taken over, because the takeover flag[HostUuid:{1}] already exists and utime[{2}] has not exceeded host ping interval[{3}] -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:242 -# args: msg.getClusterUuid() -The\ cluster[%s]\ does\ not\ support\ DRS. = The cluster[{0}] does not support DRS. +# at: src/main/java/org/zstack/kvm/KVMHost.java:4643 +# args: self.getManagementIp(),lastHostInv.getUuid() +the\ host[ip\:%s]\ has\ been\ taken\ over,\ because\ flag[HostUuid\:%s]\ exists\ in\ the\ database = the host[ip:{0}] has been taken over, because flag[HostUuid:{1}] exists in the database -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:258 -# args: reasons -Can\ not\ create\ DRS,\ %s = Can not create DRS, {0} +# at: src/main/java/org/zstack/kvm/KVMHost.java:4666 +# args: ret.getExitErrorMessage() +unable\ to\ get\ host\ cpu\ architecture,\ please\ check\ if\ username/password\ is\ wrong;\ %s = unable to get host cpu architecture, please check if username/password is wrong; {0} -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:290 -# args: -hostUuids\ is\ empty = hostUuids is empty +# at: src/main/java/org/zstack/kvm/KVMHost.java:4693 +# args: hostArchitecture,cluster.getArchitecture() +host\ cpu\ architecture[%s]\ is\ not\ matched\ the\ cluster[%s] = host cpu architecture[{0}] is not matched the cluster[{1}] -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:297 +# at: src/main/java/org/zstack/kvm/KVMHost.java:4997 # args: -query\ hosts\ utilization\ data\ failed = query hosts utilization data failed +cannot\ find\ either\ 'vmx'\ or\ 'svm'\ in\ /proc/cpuinfo,\ please\ make\ sure\ you\ have\ enabled\ virtualization\ in\ your\ BIOS\ setting = cannot find either 'vmx' or 'svm' in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting -# at: src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java:54 -# args: -crond\ is\ not\ running = crond is not running +# at: src/main/java/org/zstack/kvm/KVMHost.java:5064 +# args: self.getUuid(),self.getClusterUuid() +host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ qemu/libvirt\ version\ does\ not\ match = host [uuid:{0}] cannot be added to cluster [uuid:{1}] because qemu/libvirt version does not match -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:55 -# args: msg.getvRouterUuid() -All\ the\ networks\ should\ be\ in\ the\ virtual\ router[%s] = All the networks should be in the virtual router[{0}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:5084 +# args: self.getUuid(),self.getClusterUuid() +host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ cpu\ model\ name\ does\ not\ match = host [uuid:{0}] cannot be added to cluster [uuid:{1}] because cpu model name does not match -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:63 -# args: vo.getL3NetworkUuid(),vo.getFlowMeterUuid() -The\ network[%s]\ have\ been\ added\ into\ the\ flow\ meter[%s] = The network[{0}] have been added into the flow meter[{1}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:5217 +# args: msg.getHostUuid(),ctimeout +host[%s]\ not\ shutdown\ in\ %d\ seconds = host[{0}] not shutdown in {1} seconds -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:71 +# at: src/main/java/org/zstack/kvm/KVMHost.java:5374 # args: -The\ virtual\ router\ have\ been\ added\ into\ other\ flow\ meter = The virtual router have been added into other flow meter - -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:77 -# args: msg.getVersion(),FlowMeterConstants.TYPE.NetFlow.toString() -invalid\ type\ parameter\ is\ %s\ and\ should\ be\ in\ %s = invalid type parameter is {0} and should be in {1} - -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:154 -# args: msg.getServer() -[%s]\ is\ not\ formatted\ as\ IP\ address = [{0}] is not formatted as IP address +host\ is\ not\ in\ the\ connected\ status,\ cannot\ update\ os = host is not in the connected status, cannot update os -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:143 -# args: collector.getUuid() -Collector\ duplicate\ with\ %s = Collector duplicate with {0} +# at: src/main/java/org/zstack/kvm/KVMHost.java:5372 +# args: +host\ is\ in\ the\ premaintenance\ state,\ cannot\ update\ os = host is in the premaintenance state, cannot update os -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:164 -# args: collectorVO.getFlowMeterUuid() -FlowMeter[%s]\ doesn't\ exist = FlowMeter[{0}] doesn't exist +# at: src/main/java/org/zstack/kvm/KVMHost.java:5666 +# args: rsp.getError() +failed\ to\ attach\ volume\ to\ host,\ because\:%s = failed to attach volume to host, because:{0} -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:168 -# args: collectorVO.getFlowMeterUuid(),vo.getVersion().toString() -FlowMeter[%s]\ IPv6\ doesn't\ support\ version[%s] = FlowMeter[{0}] IPv6 doesn't support version[{1}] +# at: src/main/java/org/zstack/kvm/KVMHost.java:5727 +# args: rsp.getError() +failed\ to\ detach\ volume\ from\ host,\ because\:%s = failed to detach volume from host, because:{0} -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:150 +# at: src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java:201 # args: -no\ specify\ parameter = no specify parameter - -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:159 -# args: msg.getUuid() -Flow\ collector[%s]\ doesn't\ exist = Flow collector[{0}] doesn't exist +cannot\ adapt\ version\ for\ the\ bellow\ rpm\:\ libvirt\ /\ qemu\ /\ cpumodel = cannot adapt version for the bellow rpm: libvirt / qemu / cpumodel -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:183 -# args: server,port,collector.getUuid() -Collector\ [%s\ %d]\ duplicate\ with\ %s = Collector [{0} {1}] duplicate with {2} +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:164 +# args: e.getMessage() +fail\ to\ load\ host\ info\ from\ file.\ because\n%s = fail to load host info from file. because\n{0} -# at: src/main/java/org/zstack/flowMeter/FlowMeterManagerImpl.java:148 -# args: FlowMeterSystemTags.FLOW_EXPIRE_INTERVAL_TOKEN -%s\ must\ be\ a\ number = {0} must be a number +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:290 +# args: os,vo.getName(),vo.getManagementIp() +the\ operation\ system[%s]\ of\ host[name\:%s,\ ip\:%s]\ is\ invalid = the operation system[{0}] of host[name:{1}, ip:{2}] is invalid -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:43 -# args: msg.getUuid() -cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = cannot get latest guest-tools for vm[uuid:{0}] because it's hypervisor type is not supported +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:316 +# args: vo.getClusterUuid(),otherOs,vo.getName(),vo.getManagementIp(),os +cluster[uuid\:%s]\ already\ has\ host\ with\ os\ version[%s],\ but\ new\ added\ host[name\:%s\ ip\:%s]\ has\ different\ host\ os\ version[%s] = cluster[uuid:{0}] already has host with os version[{1}], but new added host[name:{2} ip:{3}] has different host os version[{4}] -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:50 -# args: msg.getUuid() -cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ running = cannot get latest guest-tools for vm[uuid:{0}] because it's not running +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:461 +# args: cmd.vmUuid +vm[uuid\:%s]\ crashes\ due\ to\ kernel\ error = vm[uuid:{0}] crashes due to kernel error -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:57 -# args: msg.getUuid() -cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = cannot get latest guest-tools for vm[uuid:{0}] because it's not user vm +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:500 +# args: str.toString() +there\ are\ still\ hosts\ not\ have\ the\ same\ cpu\ model,\ details\:\ %s = there are still hosts not have the same cpu model, details: {0} -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:67 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = cannot attach guest-tools iso to vm[uuid:{0}] because it's hypervisor type is not supported +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:514 +# args: KVMSystemTags.VM_PREDEFINED_PCI_BRIDGE_NUM_TOKEN +pci\ bridge\ need\ a\ value\ greater\ than\ 0\ and\ lower\ than\ 32 = pci bridge need a value greater than 0 and lower than 32 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:74 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ running = cannot attach guest-tools iso to vm[uuid:{0}] because it's not running +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:557 +# args: vm.getState(),VmInstanceState.Stopped +vm\ current\ state[%s],\ modify\ virtioSCSI\ requires\ the\ vm\ state[%s] = vm current state[{0}], modify virtioSCSI requires the vm state[{1}] -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:81 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = cannot attach guest-tools iso to vm[uuid:{0}] because it's not user vm +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:759 +# args: hostUuid +host[uuid\:%s]\ does\ not\ have\ cpu\ model\ information,\ you\ can\ reconnect\ the\ host\ to\ fix\ it = host[uuid:{0}] does not have cpu model information, you can reconnect the host to fix it -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:88 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it\ has\ no\ cdrom = cannot attach guest-tools iso to vm[uuid:{0}] because it has no cdrom +# at: src/main/java/org/zstack/kvm/KVMHostUtils.java:35 +# args: format +invalid\ format\ string\ %s = invalid format string {0} -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:98 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it\ has\ VirtioSCSI\ data\ volume\ attached = cannot attach guest-tools iso to vm[uuid:{0}] because it has VirtioSCSI data volume attached +# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:70 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}] on kvm host[uuid:{3}], because {4} -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:109 -# args: msg.getUuid() -cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = cannot get guest-tools info from vm[uuid:{0}] because it's hypervisor type is not supported +# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:129 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getName(),hostUuid,rsp.getError() +failed\ to\ check\ bridge[%s]\ for\ l2NoVlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = failed to check bridge[{0}] for l2NoVlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid: {3}], {4} -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:116 -# args: msg.getUuid() -cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ running = cannot get guest-tools info from vm[uuid:{0}] because it's not running +# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:211 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() +failed\ to\ delete\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to delete bridge[{0}] for l2Network[uuid:{1}, type:{2}] on kvm host[uuid:{3}], because {4} -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:123 -# args: msg.getUuid() -cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = cannot get guest-tools info from vm[uuid:{0}] because it's not user vm +# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:82 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vlan.getVlan(),hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5} -# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:243 -# args: Platform.getManagementServerId(),msg.getHostUuid() -no\ proper\ guest\ tools\ iso\ found\ in\ management\ node[uuid\:%s]\ for\ host[uuid\:%s] = no proper guest tools iso found in management node[uuid:{0}] for host[uuid:{1}] +# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:142 +# args: cmd.getBridgeName(),l2vlan.getUuid(),l2vlan.getName(),hostUuid,rsp.getError() +failed\ to\ check\ bridge[%s]\ for\ l2VlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check bridge[{0}] for l2VlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForLinuxOnKvmBackend.java:93 -# args: vm.getUuid() -The\ vmInstance\ [uuid]\ zwatch\ agent\ version\ was\ not\ found = The vmInstance [uuid] zwatch agent version was not found +# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:239 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vlan.getVlan(),hostUuid,rsp.getError() +failed\ to\ delete\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to delete bridge[{0}] for l2Network[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5} -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java:59 -# args: host.getUuid() -failed\ to\ download\ guest\ tools\ iso\ because\ no\ kvm\ host[uuid\:%s]\ found = failed to download guest tools iso because no kvm host[uuid:{0}] found +# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:109 +# args: hto.getHostUuid(),rsp.getError() +failed\ to\ apply\ rules\ of\ security\ group\ rules\ to\ kvm\ host[uuid\:%s],\ because\ %s = failed to apply rules of security group rules to kvm host[uuid:{0}], because {1} -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java:127 -# args: vm.getUuid(),rsp.getError() -failed\ to\ attach\ guest\ tools\ iso\ to\ vm[uuid\:%s],\ because\:%s = failed to attach guest tools iso to vm[uuid:{0}], because:{1} +# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:152 +# args: hostUuid,rsp.getError() +failed\ to\ check\ default\ rules\ of\ security\ group\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to check default rules of security group on kvm host[uuid:{0}], because {1} -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java:160 -# args: vm.getUuid(),rsp.getError() -failed\ to\ get\ guest\ tools\ info\ from\ vm[uuid\:%s],\ because\:%s = failed to get guest tools info from vm[uuid:{0}], because:{1} +# at: src/main/java/org/zstack/kvm/KvmVmHardwareVerifyExtensionPoint.java:31 +# args: +Failed\ to\ start\ vm,\ because\ can\ not\ disable\ vm.cpu.hypervisor.feature\ with\ vm.cpuMode\ none = Failed to start vm, because can not disable vm.cpu.hypervisor.feature with vm.cpuMode none -# at: src/main/java/org/zstack/ha/HaKvmHostSiblingChecker.java:236 -# args: struct.getHostUuid(),struct.getHostIp(),errors -hosts\ failed\ to\ port\ scan\ the\ failure\ host[uuid\:%s,\ ip\:%s],\ errors\ are\ %s = hosts failed to port scan the failure host[uuid:{0}, ip:{1}], errors are {2} +# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:95 +# args: msg.getMessageName() +cannot\ get\ vmUuid\ from\ msg\ %s = cannot get vmUuid from msg {0} -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:88 -# args: checkers.indexOf(checker) + 1,checkers.size(),checker.getClass().getSimpleName(),s.getSuccessTimes() * s.getSuccessInterval() -(%d/%d)\ start\ HaHostChecker\ %s\:\ predict\ time\ is\ [%d]\ seconds = ({0}/{1}) start HaHostChecker {2}: predict time is [{3}] seconds +# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:258 +# args: host.getUuid(),host.getManagementIp(),ret.getError() +unable\ to\ do\ vm\ sync\ on\ host[uuid\:%s,\ ip\:%s]\ because\ %s = unable to do vm sync on host[uuid:{0}, ip:{1}] because {2} -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:144 -# args: self.getName(),self.getUuid() -cannot\ find\ the\ host\ of\ the\ vm[name\:%s,\ uuid\:%s],\ hostUuid\ is\ null = cannot find the host of the vm[name:{0}, uuid:{1}], hostUuid is null +# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:287 +# args: vmUuid +The\ vm[%s]\ state\ is\ in\ shutdown\ for\ a\ long\ time,\ check\ whether\ the\ vm\ is\ normal = The vm[{0}] state is in shutdown for a long time, check whether the vm is normal -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:151 +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:67 # args: -no\ HaHostChecker\ found,\ cannot\ do\ HA = no HaHostChecker found, cannot do HA +unsupported\ LDAP/AD\ server\ scope = unsupported LDAP/AD server scope -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:158 -# args: self.getUuid() -can\ not\ ha\ because\ device\ still\ attached\ to\ vm[%s] = can not ha because device still attached to vm[{0}] +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:128 +# args: type,LdapConstant.OpenLdap.TYPE,LdapConstant.WindowsAD.TYPE +Wrong\ LdapServerType[%s],\ valid\ values\:\ [%,%s] = Wrong LdapServerType[{0}], valid values: [%,{1}] -# at: src/main/java/org/zstack/ha/HaManagementNodeChecker.java:99 +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:153 # args: -the\ management\ node\ fails\ to\ scan\ the\ host = the management node fails to scan the host +Cannot\ connect\ to\ LDAP/AD\ server,\ Invalid\ Credentials,\ please\ checkout\ User\ DN\ and\ password = Cannot connect to LDAP/AD server, Invalid Credentials, please checkout User DN and password -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1363 -# args: vmUuid -the\ VM[uuid\:%s]\ volume\ stored\ location\ primary\ storage\ is\ in\ a\ state\ of\ maintenance = the VM[uuid:{0}] volume stored location primary storage is in a state of maintenance +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:156 +# args: +Cannot\ connect\ to\ LDAP/AD\ server,\ communication\ false,\ please\ checkout\ IP,\ port\ and\ Base\ DN = Cannot connect to LDAP/AD server, communication false, please checkout IP, port and Base DN -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:232 -# args: newValue -the\ value[%s]\ is\ lesser\ than\ 0 = the value[{0}] is lesser than 0 +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:159 +# args: e.toString() +Cannot\ connect\ to\ LDAP/AD\ server,\ %s = Cannot connect to LDAP/AD server, {0} + +# at: src/main/java/org/zstack/ldap/LdapManagerImpl.java:560 +# args: vo.getAccountUuid() +Account[uuid\:%s]\ Not\ Found!!! = Account[uuid:{0}] Not Found!!! -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:247 -# args: hostUuids,HostStatus.Connected -host[uuid\:%s]\ is\ not\ %s,\ but\ still\ have\ vm\ on\ it,\ please\ resolve\ hosts'\ problems\ before\ enable\ ha = host[uuid:{0}] is not {1}, but still have vm on it, please resolve hosts' problems before enable ha +# at: src/main/java/org/zstack/ldap/LdapUtil.java:581 +# args: filter,errorMessage +query\ ldap\ entry[filter\:\ %s]\ fail,\ because\ %s = query ldap entry[filter: {0}] fail, because {1} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:255 -# args: hostUuids,HostStatus.Connected -host[uuid\:%s]\ is\ not\ %s,\ but\ still\ have\ vm\ on\ it,\ please\ resolve\ hosts'\ problems\ before\ update\ fencer\ strategy = host[uuid:{0}] is not {1}, but still have vm on it, please resolve hosts' problems before update fencer strategy +# at: src/main/java/org/zstack/ldap/externalSearch/AggregateSearch.java:52 +# args: e.toString() +query\ ldap\ entry\ fail,\ %s = query ldap entry fail, {0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:472 +# at: src/main/java/org/zstack/license/LicenseChecker.java:167 # args: -there\ is\ already\ a\ HA\ GC\ job\ for\ the\ VM,\ wait\ it\ to\ run = there is already a HA GC job for the VM, wait it to run - -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:480 -# args: HaGlobalConfig.NEVER_STOP_VM_FAILURE_RETRY_DELAY.value(Long.class) -A\ GC\ job\ is\ submitted\ to\ HA\ the\ VM[retry\ delay\:\ %s\ seconds] = A GC job is submitted to HA the VM[retry delay: {0} seconds] +Parse\ license\ error,\n1.\ check\ your\ private\ key\ and\ application\ code\ is\ correct\n2.\ check\ your\ license\ is\ not\ corrupted\n3.\ use\ zstack-ctl\ clear_license\ to\ clear\ your\ licenses\ and\ try\ to\ reinstall\n = Parse license error,\n1. check your private key and application code is correct\n2. check your license is not corrupted\n3. use zstack-ctl clear_license to clear your licenses and try to reinstall\n -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:998 +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:229 # args: -HA\ is\ successfully\ completed = HA is successfully completed +the\ licenseRequestCode\ is\ illegal = the licenseRequestCode is illegal + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:242 +# args: e.getMessage() +Decode\ fail\ because\ %s = Decode fail because {0} + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:239 +# args: bytes.length +Unexpected\ decoded\ license\ file\ length\:\ %d = Unexpected decoded license file length: {0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1006 +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:791 # args: -Failed\ to\ HA\ the\ VM = Failed to HA the VM +Licensed\ VM\ number\ overrun = Licensed VM number overrun -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:908 +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:857 # args: -vm\ stopped\ unexpectedly,\ double\ check\ state = vm stopped unexpectedly, double check state +unexpected\ host\ vendor\ for\ MINI = unexpected host vendor for MINI -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:917 -# args: vmUuid,hostUuid -cannot\ determine\ VM[%s]\ status\ on\ host[%s],\ try\ to\ start\ it = cannot determine VM[{0}] status on host[{1}], try to start it +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1216 +# args: info.getUuid() +not\ supported\:\ delete\ license[%s]\ from\ USB-key = not supported: delete license[{0}] from USB-key + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1271 +# args: System.getProperty("os.arch") +UKey\ not\ supported\ (arch\:\ %s) = UKey not supported (arch: {0}) + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1351 +# args: ex.getLocalizedMessage() +update\ local\ ukey\ license\:\ %s = update local ukey license: {0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1112 +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1347 # args: -vm\ state\ is\ stopped,\ try\ to\ start\ it = vm state is stopped, try to start it +No\ local\ ukey\ license\ updated = No local ukey license updated -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:934 -# args: vmUuid,hostUuid -VM[%s]\ is\ running\ on\ host[%s] = VM[{0}] is running on host[{1}] +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1377 +# args: +No\ node\ available\ to\ update\ UKey = No node available to update UKey -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:947 -# args: vmUuid,hostUuid -VM[%s]\ is\ paused\ on\ host[%s] = VM[{0}] is paused on host[{1}] +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1519 +# args: Platform.getManagementServerIp() +Multiple\ MN\ exists\ but\ only\ supplied\ licenses\ for\ %s = Multiple MN exists but only supplied licenses for {0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:975 -# args: vm.getHypervisorType() -the\ hypervisor[%s]\ does\ not\ support\ VM\ HA = the hypervisor[{0}] does not support VM HA +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1493 +# args: mnUuid,reply.getError().getDetails() +MN[uuid\:%s]\:\ %s = MN[uuid:{0}]: {1} -# at: src/main/java/org/zstack/ha/HostCheckResult.java:49 -# args: ratio,threshold,hostUuid,errors -[HA\ Worker]\:\ the\ success\ ratio[%s]\ below\ the\ threshold[%s],\ the\ host[uuid\:%s]\ is\ judged\ as\ dead,\ errors\ are\ %s.\ Start\ HA\ all\ the\ vms\ on\ this\ host\ before = [HA Worker]: the success ratio[{0}] below the threshold[{1}], the host[uuid:{2}] is judged as dead, errors are {3}. Start HA all the vms on this host before +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1521 +# args: msg.getManagementUuids() +MN\ HA\ environment,\ but\ only\ updated\ license\ for\ %s = MN HA environment, but only updated license for {0} -# at: src/main/java/org/zstack/ha/HostCheckResult.java:46 -# args: ratio,threshold -[HA\ worker]\:\ all\ host\ checkers\ are\ finished\ and\ the\ success\ ratio\ is\ %s\ that\ is\ greater\ than\ the\ threshold[%s];\ no\ HA\ need\ for\ the\ vms\ on\ this\ host\ before.\ Please\ wait\ for\ the\ host\ reconnected = [HA worker]: all host checkers are finished and the success ratio is {0} that is greater than the threshold[{1}]; no HA need for the vms on this host before. Please wait for the host reconnected +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1724 +# args: newLicenseInfo.getUuid(),newLicenseInfo.getLicenseType().toString(),path +can\ not\ find\ license[uuid\:%s,\ type\:%s]\ file\ on\ path\ %s = can not find license[uuid:{0}, type:{1}] file on path {2} -# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:89 +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:2263 # args: -Failed\ to\ start\ the\ NeverStop\ VM = Failed to start the NeverStop VM +License\ expired = License expired -# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:80 -# args: -VM\ is\ started\ successfully = VM is started successfully +# at: src/main/java/org/zstack/license/cube/CubeLicenseFactory.java:50 +# args: sdsInfoPath +%s\ is\ not\ existed = {0} is not existed -# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:74 +# at: src/main/java/org/zstack/license/cube/XmsCli.java:61 # args: -VM\ state\ is\ not\ running,\ try\ to\ start\ it = VM state is not running, try to start it +context\ cannot\ be\ null\ in\ license = context cannot be null in license -# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:45 -# args: type -keyType\ not\ supported\ type\ [%s] = keyType not supported type [{0}] - -# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:85 -# args: msg.getKey(),accountUuid -key\:\ [%s]\ already\ existed\ by\ accountUuid\:\ [%s] = key: [{0}] already existed by accountUuid: [{1}] +# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:247 +# args: struct.getType() +No\ factory\ found\ for\ type\:%s = No factory found for type:{0} -# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:63 -# args: msg.getRegionId(),ak -regionId\ [%s]\ already\ created\ by\ ak\ [%s] = regionId [{0}] already created by ak [{1}] +# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:462 +# args: msg.getType() +Unknown\ log\ configuration\ type\ %s = Unknown log configuration type {0} -# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:46 -# args: type -dcType\ not\ supported\ type\ [%s] = dcType not supported type [{0}] +# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:60 +# args: lstruct.getAppenderType() +No\ factory\ found\ for\ log4j2\ appender\ type\:%s. = No factory found for log4j2 appender type:{0}. -# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterManagerImpl.java:96 -# args: msg.getUuid() -DataCenter\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = DataCenter [{0}] is still in sync progress, please wait. +# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:134 +# args: lstruct.getAppenderType() +Unknown\ log4j2\ appender\ type\ %s = Unknown log4j2 appender type {0} -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:55 -# args: msg.getZoneId(),izo.getUuid() -identity\ zone\ [%s]\ already\ existed,\ uuid\ is\:\ %s = identity zone [{0}] already existed, uuid is: {1} +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:33 +# args: +facility\ can\ not\ be\ null = facility can not be null -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:72 -# args: type,dvo.getDcType().toString() -type\ [%s]\ is\ not\ matched\ datacenter\ type\ [%s] = type [{0}] is not matched datacenter type [{1}] +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:37 +# args: configuration.facility +invalid\ facility\ %s = invalid facility {0} -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:82 +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:41 # args: -either\ dataCenterUuid\ or\ regionId\ should\ be\ set,\ please\ check\ the\ parameters. = either dataCenterUuid or regionId should be set, please check the parameters. +hostname\ can\ not\ be\ null = hostname can not be null -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneManagerImpl.java:111 -# args: msg.getUuid() -IdentityZone\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = IdentityZone [{0}] is still in sync progress, please wait. +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:45 +# args: +port\ can\ not\ be\ null = port can not be null -# at: src/main/java/org/zstack/hybrid/network/HybridEipCascadeExtension.java:88 +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:49 # args: -EcsInstance\ must\ be\ running\ or\ stopped\ while\ deleting\ eip\ = EcsInstance must be running or stopped while deleting eip +protocol\ can\ not\ be\ null = protocol can not be null -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:86 -# args: vbri.getUuid(),vbri.getDataCenterUuid(),vrouteri.getUuid(),vrouteri.getDataCenterUuid() -router\ interface\ must\ be\ in\ the\ same\ datacenter,\ but\ ri[%s]\ is\ in\ dc[%s]\ and\ ri[%s]\ is\ in\ dc[%s] = router interface must be in the same datacenter, but ri[{0}] is in dc[{1}] and ri[{2}] is in dc[{3}] +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:55 +# args: configuration.protocol +unsupported\ protocol\ %s = unsupported protocol {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:96 -# args: vrouteri.getUuid(),vrouteri.getStatus() -router\ interface[%s]\ status\ is\ not\ idle,\ it\ is\ %s = router interface[{0}] status is not idle, it is {1} +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:69 +# args: configuration.hostname,configuration.port +syslog\ server[address\:\ %s\:%s]\ is\ not\ available = syslog server[address: {0}:{1}] is not available -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:104 -# args: vrouteri.getUuid(),vrouteri.getOppositeInterfaceUuid() -router\ interface[%s]\ already\ has\ a\ connection,\ it\ is\ %s = router interface[{0}] already has a connection, it is {1} +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:61 +# args: configuration.hostname +syslog\ server[address\:\ %s]\ is\ not\ available = syslog server[address: {0}] is not available -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:112 +# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:74 # args: -accessPointUuid\ cannot\ be\ null\ if\ the\ router\ interface\ on\ VBR\ type\ router = accessPointUuid cannot be null if the router interface on VBR type router +There\ is\ no\ LDAP/AD\ server\ in\ the\ system,\ Please\ add\ a\ LDAP/AD\ server\ first. = There is no LDAP/AD server in the system, Please add a LDAP/AD server first. + +# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:68 +# args: msg.getLdapUid(),msg.getVirtualIDUuid() +Can\ not\ bind\ this\ ldap\ uid\ %s\ to\ virtual\ id\ [uuid\:%s] = Can not bind this ldap uid {0} to virtual id [uuid:{1}] -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:186 +# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:82 # args: -cannot\ delete\ system\ entry = cannot delete system entry +This\ uid\ is\ already\ used = This uid is already used -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:192 +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:228 # args: -only\ support\ intranet\ rule\ in\ vpc = only support intranet rule in vpc +ZStack\ is\ loading\ ldap\ organizations\ from\ DB\ now,\ can\ not\ execute\ sync\ operation = ZStack is loading ldap organizations from DB now, can not execute sync operation + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:390 +# args: e.getMessage() +Failed\ to\ sync\ ldap\ entry[],\ because\ %s = Failed to sync ldap entry[], because {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:197 -# args: msg.getCidr() -%s\ is\ not\ a\ valid\ cidr = {0} is not a valid cidr +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1021 +# args: reply.getError().getReadableDetails() +Failed\ to\ sync\ organizations,\ because\ %s = Failed to sync organizations, because {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:207 +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:969 # args: -security\ group\ rule\ already\ existed = security group rule already existed +Failed\ to\ transform\ ldap\ entry\ to\ organization\ ndoe = Failed to transform ldap entry to organization ndoe -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:213 -# args: msg.getDstCidrBlock() -dstCidrBlock[%s]\ is\ not\ a\ valid\ cidr = dstCidrBlock[{0}] is not a valid cidr +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:958 +# args: +failed\ to\ sync\ ldap\ organization = failed to sync ldap organization -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:242 -# args: msg.getNextHopType() -next\ hop\ type\ [%s]\ not\ supported\ create\ route\ entry\ now! = next hop type [{0}] not supported create route entry now! +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1441 +# args: scope.toString() +Can\ not\ sync\ LDAP/AD\ server\ whose\ scope\ is\ not\ %s = Can not sync LDAP/AD server whose scope is not {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:238 -# args: msg.getNextHopUuid() -no\ such\ vpn\ gateway\:\ %s = no such vpn gateway: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1575 +# args: uid +Failed\ to\ validate\ uid[%s],\ maybe\ it\ has\ been\ deleted = Failed to validate uid[{0}], maybe it has been deleted -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:227 -# args: rivo.getvRouterType().toString(),msg.getvRouterType() -nexthop\ routerInterface\ belongs\ to\ %s,\ but\ the\ entry\ belongs\ to\ %s = nexthop routerInterface belongs to {0}, but the entry belongs to {1} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1616 +# args: uid,reply.getError().getReadableDetails() +Failed\ to\ create\ iam2\ virtual\ id\ for\ uid[%s],\ because\ %s = Failed to create iam2 virtual id for uid[{0}], because {1} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:220 -# args: msg.getNextHopUuid() -no\ such\ ecs\ instance\:\ %s = no such ecs instance: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1751 +# args: ldapUid +Failed\ to\ validate\ dn\ [%s],\ maybe\ it\ has\ been\ deleted = Failed to validate dn [{0}], maybe it has been deleted -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:252 +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2195 # args: -virtual\ border\ router\ only\ support\ routerinterface\ as\ next\ hop\ type = virtual border router only support routerinterface as next hop type +invalid\ json\ format = invalid json format -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:272 -# args: msg.getCidrBlock(),vpcCidr -vswitch's\ cidr\ [%s]\ not\ in\ the\ vpc's\ [%s] = vswitch's cidr [{0}] not in the vpc's [{1}] +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2206 +# args: +name\ is\ mandatory\ field\ % = name is mandatory field % -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:279 -# args: old.getUuid() -cidr\ is\ overlap\ by\ another\ vswitch\:\ %s = cidr is overlap by another vswitch: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2210 +# args: +attribute\ is\ mandatory\ field\ % = attribute is mandatory field % -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:292 -# args: msg.getCidrBlock() -invalid\ CidrBlock\:\ %s,\ which\ must\ subnet\ in\ '10.0.0.0/8',\ '172.16.0.0/12',\ '192.168.0.0/16' = invalid CidrBlock: {0}, which must subnet in '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16' +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2214 +# args: +type\ is\ mandatory\ field\ % = type is mandatory field % -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:308 -# args: msg.getvRouterUuid() -no\ such\ virtual\ router\:\ %s = no such virtual router: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2218 +# args: +optional\ is\ mandatory\ field\ % = optional is mandatory field % -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:303 -# args: msg.getvRouterUuid() -no\ such\ virtual\ border\ router\:\ %s = no such virtual border router: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2222 +# args: fieldNames +name\ should\ use\ values\ in\ %s = name should use values in {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:315 -# args: msg.getLocalGatewayIp() -localGateway\ is\ not\ IPv4\:\ %s = localGateway is not IPv4: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2254 +# args: rule.getAttribute() +Invalid\ attribute.\ Attribute[%s]\ is\ required,\ but\ found\ there\ are\ some\ record\ not\ matched = Invalid attribute. Attribute[{0}] is required, but found there are some record not matched -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:318 -# args: msg.getPeerGatewayIp() -peerGateway\ is\ not\ IPv4\:\ %s = peerGateway is not IPv4: {0} +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2199 +# args: +strategy\ is\ mandatory\ field\ % = strategy is mandatory field % -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:321 -# args: msg.getPeeringSubnetMask() -peerGateway\ is\ not\ subnet\ mask\:\ %s = peerGateway is not subnet mask: {0} +# at: src/main/java/org/zstack/login/plugin/LoginPluginBackend.java:54 +# args: +missing\ loginPluginName = missing loginPluginName -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:325 -# args: msg.getVlanId() -vlanId\ is\ not\ number\:\ %s = vlanId is not number: {0} +# at: src/main/java/org/zstack/login/plugin/LoginPluginBackend.java:59 +# args: loginContext.getLoginPluginName() +no\ login\ plugin\ named\ %s = no login plugin named {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:335 -# args: msg.getEcsUuid(),msg.getEipUuid(),hevo.getAllocateResourceUuid() -couldn't\ attach\ eip\ to\ ecs\:\ [%s]\ ,\ eip\ \:[%s]\ already\ attached\ ecs\:[%s]\ = couldn't attach eip to ecs: [{0}] , eip :[{1}] already attached ecs:[{2}] +# at: src/main/java/org/zstack/login/plugin/LoginPluginBackend.java:64 +# args: loginContext.getLoginPluginName() +missing\ LoginUserInfo\ when\ use\ plugin\ login = missing LoginUserInfo when use plugin login -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:340 -# args: msg.getEcsUuid() -ecs\ [%s]\ already\ has\ public\ ip\ now = ecs [{0}] already has public ip now +# at: src/main/java/org/zstack/loginControl/LoginControlApiInterceptor.java:40 +# args: e.getMessage() +Invalid\ rule\ expression,\ add\ access\ control\ rule\ fail\ because\:\ %s = Invalid rule expression, add access control rule fail because: {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:346 -# args: msg.getEipUuid(),msg.getEcsUuid() -couldn't\ attach\ eip\ [%s]\ to\ ecs\:\ [%s]\ ,\ ecs\ is\ already\ attached = couldn't attach eip [{0}] to ecs: [{1}] , ecs is already attached +# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:107 +# args: key +unrecognized\ key\:\ %s = unrecognized key: {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:353 -# args: msg.getEipUuid(),msg.getEcsUuid() -eip[%s]\ and\ ecs[%s]\ should\ be\ in\ the\ same\ dataCenter\ = eip[{0}] and ecs[{1}] should be in the same dataCenter +# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:113 +# args: opt.get() +missing\ key\:value\ of\ %s = missing key:value of {0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:362 -# args: msg.getEipUuid() -couldn't\ detach\ eip\ \:[%s],\ it\ is\ not\ attached\ on\ any\ instance\ = couldn't detach eip :[{0}], it is not attached on any instance +# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:291 +# args: msg.getResourceName(),msg.getLoginType() +No\ available\ user\ with\ name\:\ %s,\ type\:\ %s = No available user with name: {0}, type: {1} -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:45 -# args: msg.getId() -%s\ is\ not\ a\ valid\ ipv4\ address = {0} is not a valid ipv4 address +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:90 +# args: msg.getJobName() +%s\ is\ not\ an\ API = {0} is not an API -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:51 +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:152 # args: -localCidr\ must\ be\ Cidr! = localCidr must be Cidr! +cannot\ cancel\ longjob\ that\ is\ succeeded = cannot cancel longjob that is succeeded -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:55 +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:155 # args: -remoteCidr\ must\ be\ Cidr! = remoteCidr must be Cidr! +cannot\ cancel\ longjob\ that\ is\ failed = cannot cancel longjob that is failed -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:62 +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:166 # args: -localCidr\ and\ remoteCidr\ must\ be\ Cidr! = localCidr and remoteCidr must be Cidr! - -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnGatewayCascadeExtension.java:80 -# args: gateways.get(0).getUuid() -vpngateway\ [%s]\ existed,\ cannot\ delete\ remote = vpngateway [{0}] existed, cannot delete remote - -# at: src/main/java/org/zstack/iam2/IAM2AttributeHelper.java:420 -# args: vid,msg.getProjectUuid() -virtual\ id[uuid\:%s]\ is\ platform\ user\ can\ not\ be\ added\ to\ project[uuid\:%s] = virtual id[uuid:{0}] is platform user can not be added to project[uuid:{1}] +delete\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = delete longjob only when it's succeeded, canceled, or failed -# at: src/main/java/org/zstack/iam2/IAM2AttributeHelper.java:450 +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:177 # args: -Can\ not\ add\ both\ platform\ role\ and\ project\ role\ to\ virtual\ id = Can not add both platform role and project role to virtual id - -# at: src/main/java/org/zstack/iam2/IAM2AttributeHelper.java:458 -# args: virtualIDUuid -Can\ not\ add\ project\ role\ to\ platform\ virtual\ id[uuid\:%s] = Can not add project role to platform virtual id[uuid:{0}] - -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:319 -# args: msg.getName() -wrong\ virtual\ ID[name\:%s],\ not\ existing\ or\ wrong\ password = wrong virtual ID[name:{0}], not existing or wrong password +rerun\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = rerun longjob only when it's succeeded, canceled, or failed -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:326 +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:206 # args: -additional\ authentication\ failed = additional authentication failed - -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:366 -# args: msg.getProjectName() -project[name\:%s]\ not\ existing = project[name:{0}] not existing +can\ only\ resume\ longjob\ that\ is\ Suspended = can only resume longjob that is Suspended -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:374 -# args: puuid,msg.getProjectName() -no\ account\ found\ for\ project[uuid\:%s,\ name\:%s] = no account found for project[uuid:{0}, name:{1}] - -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:380 -# args: msg.getSession().getUserUuid() -wrong\ virtual\ ID[uuid\:%s],\ not\ existing\ or\ wrong\ password = wrong virtual ID[uuid:{0}], not existing or wrong password +# at: src/main/java/org/zstack/longjob/LongJobFactoryImpl.java:39 +# args: jobName +%s\ has\ no\ corresponding\ longjob = {0} has no corresponding longjob -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:385 -# args: vid.getName() -virtual\ ID[name\:%s]\ is\ disabled = virtual ID[name:{0}] is disabled +# at: src/main/java/org/zstack/mediator/ApiValidator.java:123 +# args: l3NetworkUuid,vmNicVO.getL3NetworkUuid() +unable\ to\ attach\ a\ L3\ network.\ The\ cidr\ of\ l3[%s]\ to\ attach\ overlapped\ with\ l3[%s]\ already\ attached\ to\ vm = unable to attach a L3 network. The cidr of l3[{0}] to attach overlapped with l3[{1}] already attached to vm -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:391 -# args: vid.getName(),msg.getProjectName() -virtual\ ID[name\:%s]\ not\ belonging\ to\ the\ project[name\:%s] = virtual ID[name:{0}] not belonging to the project[name:{1}] +# at: src/main/java/org/zstack/mediator/ApiValidator.java:155 +# args: vm.getName(),vm.getUuid(),StringUtils.join(pfStr, ",") +the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ port\ forwarding\ rules%s\ attached = the vm[name:{0}, uuid:{1}] already has some port forwarding rules{2} attached -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:647 -# args: results.size() -There\ are\ %d\ problems\ with\ the\ file.\ = There are {0} problems with the file. +# at: src/main/java/org/zstack/mediator/ApiValidator.java:176 +# args: vm.getName(),vm.getUuid(),StringUtils.join(eipStr, ",") +the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ EIPs%s\ attached = the vm[name:{0}, uuid:{1}] already has some EIPs{2} attached -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:664 -# args: e.getMessage() -fail\ to\ load\ VirtualID\ info\ from\ file.\ because\n%s = fail to load VirtualID info from file. because\n{0} +# at: src/main/java/org/zstack/mediator/ApiValidator.java:191 +# args: msg.getVipUuid(),useForList.toString() +the\ vip[uuid\:%s]\ already\ has\ bound\ to\ other\ service[%s] = the vip[uuid:{0}] already has bound to other service[{1}] -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:675 -# args: -name\ cannot\ be\ empty.\ = name cannot be empty. +# at: src/main/java/org/zstack/mediator/ApiValidator.java:231 +# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol +Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:683 -# args: cmsg.getUsername() -userName[%s]\ is\ repeated.\ = userName[{0}] is repeated. +# at: src/main/java/org/zstack/mediator/ApiValidator.java:228 +# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol +Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ system\ service\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = Current port range[{0}, {1}] is conflicted with system service port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:681 -# args: cmsg.username.length() -name\ exceeds\ max\ length\ of\ string.\ expected\ was\ <\=\ 255,\ actual\ was\ %s.\ = name exceeds max length of string. expected was <= 255, actual was {0}. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:851 +# args: l3Uuid,systemTag +L3\ network[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = L3 network[uuid:{0}] not found. Please correct your system tag[{1}] of static IP -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:679 -# args: -username\ cannot\ be\ empty.\ = username cannot be empty. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:327 +# args: supportSharedVolumePrimaryStorage,psType +for\ shareable\ volume,\ the\ only\ supported\ primary\ storage\ type\ is\ %s,\ current\ is\ %s = for shareable volume, the only supported primary storage type is {0}, current is {1} -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:689 -# args: cmsg.password.length() -Incorrect\ password\ length.\ expected\ was\ >\=\ 6\ and\ <\=\ 255,\ actual\ was\ %s.\ = Incorrect password length. expected was >= 6 and <= 255, actual was {0}. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:795 +# args: bandwidth,Long.MAX_VALUE +invalid\ volume\ bandwidth[%s]\ is\ larger\ than\ %d = invalid volume bandwidth[{0}] is larger than {1} -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:687 -# args: -password\ cannot\ be\ empty.\ = password cannot be empty. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:745 +# args: bandwidth +invalid\ network\ bandwidth[%s],\ it\ must\ be\ greater\ than\ or\ equal\ to\ 8192 = invalid network bandwidth[{0}], it must be greater than or equal to 8192 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:697 -# args: -email\ format\ does\ not\ match.\ = email format does not match. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:793 +# args: bandwidth +invalid\ volume\ bandwidth[%s]\ is\ not\ a\ number = invalid volume bandwidth[{0}] is not a number -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:753 -# args: noMatchNames -organization[%s]\ is\ not\ exist.\ = organization[{0}] is not exist. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:790 +# args: bandwidth +invalid\ volume\ bandwidth[%s],\ it\ must\ be\ greater\ than\ 1024\ (include\ 1024) = invalid volume bandwidth[{0}], it must be greater than 1024 (include 1024) -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:761 -# args: repeatNames -organization[%s]\ in\ line\ is\ repeated.\ = organization[{0}] in line is repeated. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:832 +# args: iops +invalid\ volume\ IOPS[%s]\ is\ not\ a\ number = invalid volume IOPS[{0}] is not a number -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:769 -# args: repeatNames -organization[%s]\ is\ repeated.\ = organization[{0}] is repeated. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:834 +# args: iops,Long.MAX_VALUE +invalid\ volume\ IOPS[%s]\ is\ larger\ than\ %d = invalid volume IOPS[{0}] is larger than {1} -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:799 -# args: noMatchName -project[%s]\ is\ not\ exist.\ = project[{0}] is not exist. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:829 +# args: iops +invalid\ volume\ IOPS[%s],\ it\ must\ be\ greater\ than\ 1\ (include\ 1) = invalid volume IOPS[{0}], it must be greater than 1 (include 1) -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:963 +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:865 # args: -fail\ to\ build\ VirtualID\ info\ from\ file.\ = fail to build VirtualID info from file. +\ usb\ device\ can\ only\ be\ called\ by\ admin\ account = usb device can only be called by admin account -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1034 -# args: resourceUuid,projectUuid -virtualID[uuid\:%s]\ not\ in\ project[uuid\:%s] = virtualID[uuid:{0}] not in project[uuid:{1}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:901 +# args: level +Unknown\ code[%s]\ of\ Security\ Level = Unknown code[{0}] of Security Level -# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:86 -# args: self.getUuid() -Can\ not\ do\ operations,\ because\ current\ organization[uuid\:%s]\ is\ staled,\ please\ enable\ it = Can not do operations, because current organization[uuid:{0}] is staled, please enable it +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:918 +# args: cidr +[%s]\ is\ not\ a\ standard\ cidr = [{0}] is not a standard cidr -# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:192 -# args: puuid,self.getUuid() -organization[uuid\:%s]\ is\ parent\ of\ the\ organization[uuid\:%s],\ cannot\ set\ it\ as\ a\ child\ organization = organization[uuid:{0}] is parent of the organization[uuid:{1}], cannot set it as a child organization +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:939 +# args: hostUuid,os.distribution,os.version +the\ host[uuid\:%s]'s\ operating\ system\ %s\ %s\ is\ too\ old,\ the\ QEMU\ doesn't\ support\ QoS\ of\ network\ or\ disk\ IO.\ Please\ choose\ another\ instance\ offering\ with\ no\ QoS\ configuration = the host[uuid:{0}]'s operating system {1} {2} is too old, the QEMU doesn't support QoS of network or disk IO. Please choose another instance offering with no QoS configuration -# at: src/main/java/org/zstack/iam2/IAM2ProjectBase.java:106 -# args: self.getUuid(),self.getName(),self.getState(),msg.getClass() -the\ project[uuid\:\ %s,\ name\:%s]\ is\ in\ state\ of\ %s\ which\ disallows\ the\ operation[%s] = the project[uuid: {0}, name:{1}] is in state of {2} which disallows the operation[{3}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1186 +# args: newValue +invalid\ value[%s],\ it's\ not\ a\ double = invalid value[{0}], it's not a double -# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:132 -# args: self.getUuid() -Can\ not\ do\ operations,\ because\ Current\ virtualID[uuid\:%s]\ is\ staled,\ please\ enable\ it = Can not do operations, because Current virtualID[uuid:{0}] is staled, please enable it +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1154 +# args: newValue +invalid\ value[%s],\ it\ must\ be\ a\ double\ greater\ than\ 0 = invalid value[{0}], it must be a double greater than 0 -# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:554 -# args: -only\ admin\ and\ the\ virtual\ ID\ itself\ can\ do\ the\ update = only admin and the virtual ID itself can do the update +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1183 +# args: newValue +invalid\ value[%s],\ it\ must\ be\ a\ double\ between\ (0,\ 1] = invalid value[{0}], it must be a double between (0, 1] -# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:558 -# args: msg.getVirtualIDUuid() -old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ virtual\ ID[uuid\:%s] = old password is not equal to the original password, cannot update the password of virtual ID[uuid:{0}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1197 +# args: newValue +invalid\ value[%s],\ ZStack\ doesn't\ have\ such\ host\ allocator\ type = invalid value[{0}], ZStack doesn't have such host allocator type -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:43 -# args: attr.getValue() -attribute\ name\ cannot\ be\ null,\ value[%s] = attribute name cannot be null, value[{0}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1219 +# args: MevocoGlobalConfig.AIO_NATIVE.getCanonicalName(),MevocoGlobalConfig.AIO_NATIVE.value(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.getCanonicalName(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.value() +%s\ value\ is[%s],\ which\ is\ conflict\ with\ %s\ value\ [%s] = {0} value is[{1}], which is conflict with {2} value [{3}] -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:47 -# args: attr.getName() -attribute\ name[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = attribute name[{0}] exceed the max length of 2048 chars +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1489 +# args: +obj\ is\ not\ instanceof\ NicQos! = obj is not instanceof NicQos! -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:50 -# args: attr.getName(),attr.getValue() -attribute[name\:%s]\ value[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = attribute[name:{0}] value[{1}] exceed the max length of 2048 chars +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2054 +# args: String.join(",", ips) +unexpected\ host\ management\ IPs\:\ [%s] = unexpected host management IPs: [{0}] -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:151 +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2190 # args: -admin\ is\ a\ reserved\ name,\ please\ use\ another\ name = admin is a reserved name, please use another name +can\ not\ set\ local\ and\ configure\ at\ same\ time = can not set local and configure at same time -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:159 -# args: msg.getName() -invalid\ name[%s],\ there\ has\ been\ a\ project\ or\ account\ with\ the\ same\ name = invalid name[{0}], there has been a project or account with the same name +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2242 +# args: +can\ not\ find\ node\ A\ config\ info = can not find node A config info -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:167 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ group = attribute[uuid:{0}] is not for any group +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2252 +# args: +can\ not\ find\ node\ A\ address\ info\ from\ bootstrap\ agent = can not find node A address info from bootstrap agent -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:175 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ organization = attribute[uuid:{0}] is not for any organization +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2314 +# args: s.getJobUuid() +can\ not\ get\ bootstrap\ job\ %s\ result\ after\ 900s = can not get bootstrap job {0} result after 900s -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:183 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ project = attribute[uuid:{0}] is not for any project +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2322 +# args: ret.getRetCode(),ret.getStdout(),ret.getStderr() +curl\ bootstrap\ agent\ finished,\ return\ code\:\ %s,\ stdout\:\ %s,\ stderr\:\ %s = curl bootstrap agent finished, return code: {0}, stdout: {1}, stderr: {2} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:191 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ virtual\ ID = attribute[uuid:{0}] is not for any virtual ID +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2686 +# args: errorOfNodeA.getCauses().get(0) +node\ A\ update\ factory\ mode\ failed,\ details\:\ %s = node A update factory mode failed, details: {0} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:211 -# args: -retire\ policy\ must\ be\ deleted\ before\ pull\ the\ project\ out\ of\ Retired\ state = retire policy must be deleted before pull the project out of Retired state +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2684 +# args: errorCodeList.getCauses().get(0) +all\ management\ node\ update\ factory\ mode\ failed,\ details\:\ %s = all management node update factory mode failed, details: {0} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:223 -# args: state -login\ is\ prohibited\ because\ the\ project\ is\ in\ state\ of\ %s = login is prohibited because the project is in state of {0} +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2790 +# args: ManagementNodeState.RUNNING +management\ node\ status\ is\ not\ %s = management node status is not {0} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:237 -# args: name -no\ quota[name\:%s]\ found = no quota[name:{0}] found +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2720 +# args: r.getStdout() +some\ node\ on\ factory\ mode\ exists,\ detail\ of\ arping\:\ %s = some node on factory mode exists, detail of arping: {0} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:261 -# args: msg.getUuid() -organization[uuid\:%s]\ is\ a\ Company\ that\ cannot\ have\ parent\ organization = organization[uuid:{0}] is a Company that cannot have parent organization +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2741 +# args: +set\ address\ on\ node\ A\ failed = set address on node A failed -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:273 -# args: msg.getName() -duplicate\ virtualID\ name[%s] = duplicate virtualID name[{0}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2738 +# args: +this\ node\ is\ not\ node\ A = this node is not node A -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:291 -# args: msg.getName() -duplicate\ project\ name[%s] = duplicate project name[{0}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2875 +# args: bandwidth +networkInboundBandwidth\ format\ error\ %s = networkInboundBandwidth format error {0} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:299 -# args: msg.getName() -invalid\ project\ name[%s],\ an\ account\ or\ project\ with\ the\ same\ name\ exists = invalid project name[{0}], an account or project with the same name exists. +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2887 +# args: bandwidth +networkOutboundBandwidth\ format\ error\ %s = networkOutboundBandwidth format error {0} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:315 -# args: refVO.getProjectUuid(),refVO.getOrganizationUuid() -The\ project[uuid\=%s]\ has\ been\ attached\ to\ the\ organization[uuid\=%s] = The project[uuid={0}] has been attached to the organization[uuid={1}] +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2884 +# args: +networkOutboundBandwidth\ execeds\ the\ max\ value\ 32G\ bps = networkOutboundBandwidth execeds the max value 32G bps -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:325 -# args: msg.getProjectUuid() -The\ project[uuid\=%s]\ is\ not\ attached = The project[uuid={0}] is not attached +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3060 +# args: volume.getUuid(),vm.getUuid() +Shareable\ Volume[uuid\:%s]\ has\ already\ been\ attached\ to\ VM[uuid\:%s] = Shareable Volume[uuid:{0}] has already been attached to VM[uuid:{1}] -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:336 -# args: uuids -organizations%s\ are\ company\ that\ cannot\ be\ children\ of\ other\ organization = organizations{0} are company that cannot be children of other organization +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3078 +# args: +shareable\ disk\ only\ support\ virtio-scsi\ type\ for\ now = shareable disk only support virtio-scsi type for now -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:398 -# args: staleVirtualIDs -can\ not\ operate\ stale\ virtual\ ids\:\ %s = can not operate stale virtual ids: {0} +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3213 +# args: sharedVolUuids +shareable\ volume(s)[uuid\:\ %s]\ attached,\ not\ support\ to\ group\ snapshot. = shareable volume(s)[uuid: {0}] attached, not support to group snapshot. -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:417 -# args: wrong,msg.getGroupUuid() -virtual\ ids%s\ not\ in\ the\ project\ the\ group[uuid\:%s]\ belongs\ to = virtual ids{0} not in the project the group[uuid:{1}] belongs to +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1811 +# args: msg.getMode() +invalid\ volume\ qos\ mode\:\ %s = invalid volume qos mode: {0} -# at: src/main/java/org/zstack/iam2/attribute/SystemAttributes.java:69 -# args: -attribute[name\:%s]\ is\ a\ system\ attribute\ that\ cannot\ be\ updated = attribute[name:{0}] is a system attribute that cannot be updated +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:284 +# args: msg.getIoThreadId(),msg.getPin(),vm.getUuid(),rsp.getError() +Failed\ set\ iothread[%d]\ pin[%s]\ on\ vm[%s]\:\ %s. = Failed set iothread[{0}] pin[{1}] on vm[{2}]: {3}. -# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:37 -# args: inv.getValue() -virtual\ ID[uuid\:%s]\ not\ existing = virtual ID[uuid:{0}] not existing +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:339 +# args: msg.getUuid() +can\ not\ found\ in\ used\ snapshot\ tree\ of\ volume[uuid\:\ %s].\ Maybe\ no\ snapshot\ chain\ need\ to\ validate. = can not found in used snapshot tree of volume[uuid: {0}]. Maybe no snapshot chain need to validate. -# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:44 -# args: inv.getValue(),((IAM2OrganizationAttributeInventory) inv).getOrganizationUuid() -virtual\ ID[uuid\:%s]\ not\ in\ organization[uuid\:%s] = virtual ID[uuid:{0}] not in organization[uuid:{1}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:352 +# args: currentTreeUuid,msg.getUuid() +can\ not\ found\ latest\ snapshot\ from\ tree[uuid\:\ %s]\ of\ volume[uuid\:\ %s].\ Maybe\ no\ snapshot\ chain\ need\ to\ validate. = can not found latest snapshot from tree[uuid: {0}] of volume[uuid: {1}]. Maybe no snapshot chain need to validate. -# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:49 -# args: oinv.getOrganizationUuid() -organization[uuid\:%s]\ already\ has\ a\ supervisor = organization[uuid:{0}] already has a supervisor +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:368 +# args: currentTreeUuid,msg.getUuid() +can\ not\ found\ snapshots\ from\ tree[uuid\:\ %s]\ of\ volume[uuid\:\ %s].\ Maybe\ no\ snapshot\ chain\ need\ to\ validate. = can not found snapshots from tree[uuid: {0}] of volume[uuid: {1}]. Maybe no snapshot chain need to validate. -# at: src/main/java/org/zstack/iam2/attribute/project/Retire.java:65 -# args: pinv.getUuid(),pinv.getName() -the\ project[uuid\:%s,\ name\:%s]\ already\ has\ a\ retire\ policy = the project[uuid:{0}, name:{1}] already has a retire policy +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:678 +# args: vmInstanceVO.getUuid() +How\ can\ a\ Running\ VM[uuid\:%s]\ has\ no\ hostUuid? = How can a Running VM[uuid:{0}] has no hostUuid? -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:52 -# args: -invalid\ value,\ no\ 'at',\ 'after'\ or\ 'exceed'\ found = invalid value, no 'at', 'after' or 'exceed' found +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:676 +# args: vmInstanceVO.getUuid() +Unexpectedly,\ VM[uuid\:%s]\ is\ not\ running\ any\ more,\ please\ try\ again\ later = Unexpectedly, VM[uuid:{0}] is not running any more, please try again later -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:57 -# args: value -invalid\ value,\ %s = invalid value, {0} +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:842 +# args: PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value(),errorInfoMap.keySet(),errorInfoMap.values() +after\ subtracting\ reserved\ capacity[%s],\ primary\ storage[%s]\ don't\ have\ required\ size[%s\ bytes],\ may\ be\ the\ threshold\ of\ primary\ storage\ physical\ capacity\ setting\ is\ lower = after subtracting reserved capacity[{0}], primary storage[{1}] don't have required size[{2} bytes], may be the threshold of primary storage physical capacity setting is lower -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:63 -# args: ss[0],Means.values() -invalid\ means[%s],\ allowed\ means\ are\ %s = invalid means[{0}], allowed means are {1} +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1231 +# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() +can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ not\ attached = can not take snapshot for volumes[{0}] while volume[uuid: {1}] not attached -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:98 -# args: policyValue -invalid\ spending\ value[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10.001 = invalid spending value[{0}], it should be in format of for example 10.001 +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1237 +# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() +can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ appears\ twice = can not take snapshot for volumes[{0}] while volume[uuid: {1}] appears twice -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:92 -# args: policyValue,Double.MAX_VALUE -invalid\ spending\ value[%s],\ spending\ value\ should\ between\ 0\ and\ %f = invalid spending value[{0}], spending value should between 0 and {1} +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1244 +# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid(),volumeVOS.get(0).getVmInstanceUuid() +can\ not\ take\ snapshot\ for\ volumes[%s]\ attached\ multiple\ vms[%s,\ %s] = can not take snapshot for volumes[{0}] attached multiple vms[{1}, {2}] -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:85 -# args: policyValue -invalid\ time[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10m,\ 1h,\ 2d = invalid time[{0}], it should be in format of for example 10m, 1h, 2d +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1251 +# args: +no\ volumes\ found = no volumes found -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:76 -# args: policyValue -invalid\ date[%s],\ it\ should\ be\ in\ format\ of\ yyyy-MM-dd\ HH\:mm\:ss = invalid date[{0}], it should be in format of yyyy-MM-dd HH:mm:ss +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1516 +# args: SizeUnit.BYTE.toGigaByte((double) resize) +this\ snapshot\ recording\ the\ volume\ state\ before\ resize\ to\ %fG\ is\ created\ automatically = this snapshot recording the volume state before resize to {0}G is created automatically -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:105 -# args: policyValue,dateFormat.format(new Timestamp(System.currentTimeMillis())) -invalid\ date\ or\ time[%s],\ it\ cannot\ be\ before\ current\ time[%s] = invalid date or time[{0}], it cannot be before current time[{1}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1823 +# args: msg.getUuid() +DeleteVolumeQos\ [%s]\ ignore\ because\ of\ account\ privilege. = DeleteVolumeQos [{0}] ignore because of account privilege. -# at: src/main/java/org/zstack/iam2/attribute/virtualid/AbstractAdminAttribute.java:17 -# args: vid,attributeName -virtual\ ID[uuid\:%s]\ already\ has\ admin\ related\ attributes,\ can\ not\ add\ %s = virtual ID[uuid:{0}] already has admin related attributes, can not add {1} +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1891 +# args: ivo.getHostUuid(),ivo.getState(),VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString() +Cannot\ delete\ vm's\ volume\ qos\ on\ host\ %s,\ because\ the\ current\ vm\ is\ in\ state\ of\ %s,\ but\ support\ expect\ states\ are\ [%s,\ %s] = Cannot delete vm's volume qos on host {0}, because the current vm is in state of {1}, but support expect states are [{2}, {3}] -# at: src/main/java/org/zstack/iam2/attribute/virtualid/IAM2ProjectOperator.java:35 -# args: idinv.getVirtualIDUuid() -virtual\ id[uuid\:%s]\ already\ has\ a\ project\ operator\ attribute = virtual id[uuid:{0}] already has a project operator attribute +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2039 +# args: VolumeQos.getVolumeQosByMode(self.getVolumeQos(), mode) +non\ admin\ account\ cannot\ set\ bandwidth\ more\ than\ %s = non admin account cannot set bandwidth more than {0} -# at: src/main/java/org/zstack/iam2/attribute/virtualid/PlatformAdminZoneRelation.java:36 -# args: inv.getValue() -cannot\ find\ zone[uuid\:%s] = cannot find zone[uuid:{0}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2051 +# args: +unknown\ message\ version. = unknown message version. -# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:71 -# args: inv.getValue() -project[uuid\:%s]\ already\ has\ a\ project\ admin = project[uuid:{0}] already has a project admin +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2068 +# args: +unknown\ qos\ limit\ type. = unknown qos limit type. -# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:83 -# args: inv.getValue() -project[uuid\:%s]\ not\ existing = project[uuid:{0}] not existing +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2082 +# args: limitType +Non-admin\ account\ is\ only\ allowed\ to\ set\ the\ total\ %s\ limit. = Non-admin account is only allowed to set the total {0} limit. -# at: src/main/java/org/zstack/iam2/rbac/IAM2AuthorizationBackend.java:130 -# args: deniedApis -the\ operations[%s]\ is\ denied = the operations[{0}] is denied +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2091 +# args: limitType.getType() +Non-admin\ account\ cannot\ set\ the\ total\ %s\ limits\ as\ unlimited. = Non-admin account cannot set the total {0} limits as unlimited. -# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:28 -# args: session.getAccountUuid() -project\ of\ account[uuid\:%s]\ not\ exists = project of account[uuid:{0}] not exists +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2095 +# args: limitType.getType(),totalLimit +Non-admin\ account\ cannot\ set\ the\ total\ %s\ limit\ greater\ than\:\ %s = Non-admin account cannot set the total {0} limit greater than: {1} -# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:37 -# args: projectUuid -project[uuid\:%s]\ is\ retired,\ reject\ all\ operations = project[uuid:{0}] is retired, reject all operations +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2102 +# args: limitType.getType() +Non-admin\ account\ is\ only\ allowed\ to\ set\ the\ read/write\ %s\ limits. = Non-admin account is only allowed to set the read/write {0} limits. -# at: src/main/java/org/zstack/iam2/IAM2QuotaChangeChecker.java:112 -# args: quota.getName(),quota.getIdentityUuid(),updatedValue,organizationUuid -the\ quota[name\:%s]\ of\ Account[uuid\:%s]\ can\ not\ be\ %d,\ otherwise\ it\ will\ exceeds\ the\ quota\ of\ organization[uuid\:%s] = the quota[{0}] of Account[uuid:{1}] can not be {2}, otherwise it will exceeds the quota of organization[uuid:{3}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2108 +# args: limitType.getType() +Non-admin\ account\ cannot\ set\ the\ read\ %s\ limits\ as\ unlimited. = Non-admin account cannot set the read {0} limits as unlimited. -# at: src/main/java/org/zstack/identity/AccountBase.java:323 -# args: group.getUuid(),msg.getAccountUuid() -the\ user\ group[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = the user group[uuid:{0}] does not belong to the account[uuid:{1}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2119 +# args: limitType.getType() +Non-admin\ account\ cannot\ set\ the\ write\ %s\ limits\ as\ unlimited. = Non-admin account cannot set the write {0} limits as unlimited. -# at: src/main/java/org/zstack/identity/AccountBase.java:425 -# args: msg.getName(),msg.getIdentityUuid() -cannot\ find\ Quota[name\:\ %s]\ for\ the\ account[uuid\:\ %s] = cannot find Quota[name: {0}] for the account[uuid: {1}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2128 +# args: limitType.getType(),readLimit,writeLimit +Non-admin\ account\ cannot\ set\ the\ read/write\ %s\ limits\ greater\ than\:\ %s/%s = Non-admin account cannot set the read/write {0} limits greater than: {1}/{2} -# at: src/main/java/org/zstack/identity/AccountBase.java:504 -# args: self.getUuid(),ruuid -the\ account[uuid\:\ %s]\ doesn't\ have\ a\ resource[uuid\:\ %s] = the account[uuid: {0}] doesn't have a resource[uuid: {1}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2215 +# args: self.getUuid() +volume\ [%s]\ isn't\ attached\ to\ any\ vm,\ cannot\ get\ qos\ by\ forceSync = volume [{0}] isn't attached to any vm, cannot get qos by forceSync -# at: src/main/java/org/zstack/identity/AccountBase.java:561 -# args: user.getUuid(),msg.getAccountUuid() -the\ user[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = the user[uuid:{0}] does not belong to the account[uuid:{1}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2221 +# args: self.getUuid() +volume\ [%s]\ isn't\ attached\ to\ any\ vm\ (or\ vm\ is\ not\ existed\ now),\ cannot\ sync\ volume\ qos = volume [{0}] isn't attached to any vm (or vm is not existed now), cannot sync volume qos -# at: src/main/java/org/zstack/identity/AccountBase.java:566 -# args: user.getUuid() -old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ user[uuid\:%s] = old password is not equal to the original password, cannot update the password of user[uuid:{0}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2226 +# args: vm.getUuid() +vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ volume\ qos = vm [{0}]' state must be Running or Paused to sync volume qos -# at: src/main/java/org/zstack/identity/AccountInterceptor.java:55 +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2231 # args: -wrong\ password = wrong password +vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ volume\ qos = vm [{0}]'s HostUuid is null, cannot sync volume qos -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1612 -# args: JSONObjectUtil.toJsonString(s) -a\ statement\ must\ have\ effect\ field.\ Invalid\ statement[%s] = a statement must have effect field. Invalid statement[{0}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2377 +# args: msg.getVolume().getUuid(),msg.getVmInstanceUuid() +failed\ to\ detach\ shareable\ volume[uuid\:%s]\ from\ VmInstance[uuid\:%s] = failed to detach shareable volume[uuid:{0}] from VmInstance[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1615 -# args: JSONObjectUtil.toJsonString(s) -a\ statement\ must\ have\ action\ field.\ Invalid\ statement[%s] = a statement must have action field. Invalid statement[{0}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2389 +# args: StringUtils.join(errors, "\n\n") +failed\ to\ detach\ shareable\ volume\ from\ VmInstance\:[\n%s] = failed to detach shareable volume from VmInstance because:[\n{0}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1618 -# args: JSONObjectUtil.toJsonString(s) -a\ statement\ must\ have\ a\ non-empty\ action\ field.\ Invalid\ statement[%s] = a statement must have a non-empty action field. Invalid statement[{0}] +# at: src/main/java/org/zstack/mevoco/MevocoVolumeFactoryImpl.java:89 +# args: resourceUuid +unsupported\ operation\ for\ setting\ root\ volume[%s]\ multiQueues. = unsupported operation for setting root volume[{0}] multiQueues. -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:165 +# at: src/main/java/org/zstack/mevoco/MevocoVolumeFactoryImpl.java:93 # args: resourceUuid -cannot\ find\ the\ resource[uuid\:%s];\ wrong\ resourceUuid\ or\ the\ resource\ is\ admin\ resource = cannot find the resource[uuid:{0}]; wrong resourceUuid or the resource is admin resource +unsupported\ operation\ for\ setting\ virtio-scsi\ volume[%s]\ multiQueues. = unsupported operation for setting virtio-scsi volume[{0}] multiQueues. -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:399 -# args: msg.getUserUuid() -the\ user\ specified\ by\ the\ userUuid[%s]\ does\ not\ belong\ to\ the\ current\ account,\ and\ the\ current\ account\ is\ not\ an\ admin\ account,\ so\ it\ has\ no\ permission\ to\ check\ the\ user'spermissions = the user specified by the userUuid[{0}] does not belong to the current account, and the current account is not an admin account, so it has no permission to check the user'spermissions +# at: src/main/java/org/zstack/mevoco/PauseWorldApiInterceptor.java:46 +# args: MevocoSystemTags.CONFIRM_CALL_API.getTagFormat() +ZStack\ has\ been\ paused,\ reject\ all\ API\ which\ are\ not\ read\ only.\ If\ you\ really\ want\ to\ call\ it\ and\ known\ the\ consequence,\ add\ '%s'\ into\ systemTags. = ZStack has been paused, reject all API which are not read only. If you really want to call it and known the consequence, add '{0}' into systemTags. -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1009 -# args: accountUuid -cannot\ find\ the\ account[uuid\:%s] = cannot find the account[uuid:{0}] +# at: src/main/java/org/zstack/mevoco/PremiumGlobalConfig.java:27 +# args: getName() +the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ global\ config\ [name\:%s] = the current version of license does not support modifying this global config [name:{0}] + +# at: src/main/java/org/zstack/mevoco/PremiumResourceConfig.java:22 +# args: globalConfig.getName() +the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ resource\ config\ [name\:%s] = the current version of license does not support modifying this resource config [name:{0}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1447 +# at: src/main/java/org/zstack/mevoco/VolumeQos.java:331 # args: -accountName\ and\ accountUuid\ cannot\ both\ be\ null,\ you\ must\ specify\ at\ least\ one = accountName and accountUuid cannot both be null, you must specify at least one +cannot\ find\ mode\ from\ null\ VolumeQos = cannot find mode from null VolumeQos -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1458 -# args: msg.getName(),msg.getAccountUuid() -unable\ to\ create\ a\ group.\ A\ group\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = unable to create a group. A group called {0} is already under the account[uuid:{1}] +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:190 +# args: msg.getMonitorTriggerUuid() +cannot\ find\ monitor\ trigger[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find monitor trigger[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1468 -# args: msg.getName(),msg.getAccountUuid() -unable\ to\ create\ a\ user.\ A\ user\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = unable to create a user. A user called {0} is already under the account[uuid:{1}] +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:199 +# args: msg.getMonitorTriggerActionUuid() +cannot\ find\ monitor\ trigger\ action[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find monitor trigger action[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1477 -# args: msg.getName() -unable\ to\ create\ an\ account.\ An\ account\ already\ called\ %s = unable to create an account. An account already called {0} +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:243 +# args: msg.getResourceType() +the\ resource[type\:%s]\ doesn't\ have\ any\ monitoring\ items = the resource[type:{0}] doesn't have any monitoring items -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1484 -# args: -account\ cannot\ delete\ itself = account cannot delete itself +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:335 +# args: msg.getTargetResourceUuid(),msg.getSession().getAccountUuid() +the\ resource[uuid\:%s]\ doesn't\ belong\ to\ the\ account[uuid\:%s] = the resource[uuid:{0}] doesn't belong to the account[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1490 -# args: -cannot\ delete\ builtin\ admin\ account. = cannot delete builtin admin account. +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:386 +# args: resourceUuid +cannot\ find\ type\ for\ the\ resource[uuid\:%s] = cannot find type for the resource[uuid:{0}] + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:391 +# args: resourceType,triggerExpression.getItem() +no\ monitoring\ item\ found\ for\ the\ resourceType[%s]\ and\ item[%s] = no monitoring item found for the resourceType[{0}] and item[{1}] + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:50 +# args: args +A\ resource[name\:{resourceName},\ uuid\:{resourceUuid},\ type\:{resourceType}]'s\ monitoring\ trigger[uuid\:{triggerUuid}]\ changes\ status\ to\ {triggerStatus} = A resource[name:'{resourceName}', uuid:'{resourceUuid}', type:'{resourceType}']'s monitoring trigger[uuid:'{triggerUuid}'] changes status to '{triggerStatus}' -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1496 +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:55 # args: -Only\ admin\ can\ delete\ account. = Only admin can delete account. +\n\=\=\=\ BELOW\ ARE\ DETAILS\ OF\ THE\ PREVIOUS\ ALERT\ \=\=\= = \n=== BELOW ARE DETAILS OF THE PREVIOUS ALERT === -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1504 +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:58 # args: -the\ current\ session\ is\ an\ account\ session.\ You\ need\ to\ specify\ the\ field\ 'uuid'\ of\ the\ user\ you\ want\ to\ update = the current session is an account session. You need to specify the field 'uuid' of the user you want to update +\nalert\ details\: = \nalert details: -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1519 -# args: msg.getUuid() -your\ are\ login\ as\ a\ user,\ you\ cannot\ another\ user[uuid\:%s] = your are login as a user, you cannot another user[uuid:{0}] +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:59 +# args: args +\ncondition\:\ {itemName}\ {operator}\ {threshold} = \ncondition: '{itemName}' '{operator}' '{threshold}' + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:60 +# args: args +\ncurrent\ value\:\ {value} = \ncurrent value: '{value}' -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1527 +# at: src/main/java/org/zstack/monitoring/items/host/HostCpuUtilItem.java:31 # args: -all\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = all is set to false, accountUuids cannot be null or empty +Host\ CPU\ utilization = Host CPU utilization -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1535 +# at: src/main/java/org/zstack/monitoring/items/vm/VmCpuUtilItem.java:29 # args: -toPublic\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = toPublic is set to false, accountUuids cannot be null or empty +VM\ CPU\ utilization = VM CPU utilization -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1584 -# args: policy.getName(),policy.getUuid(),msg.getSession().getAccountUuid() -policy[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = policy[name: {0}, uuid: {1}] doesn't belong to the account[uuid: {2}] +# at: src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java:98 +# args: ruleFile +fail\ to\ create\ new\ File[%s] = fail to create new File[{0}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1598 -# args: user.getName(),user.getUuid(),msg.getSession().getAccountUuid() -user[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = user[name: {0}, uuid: {1}] doesn't belong to the account[uuid: {2}] +# at: src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java:143 +# args: rb.name,r +conflict\ alert\ rule[%s],\ there\ has\ been\ a\ rule[%s]\ with\ the\ same\ name = conflict alert rule[{0}], there has been a rule[{1}] with the same name -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1602 -# args: group.getName(),group.getUuid(),msg.getSession().getAccountUuid() -group[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = group[name: {0}, uuid: {1}] doesn't belong to the account[uuid: {2}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusAlert.java:79 +# args: resourceName,resourceUuid,toI18nString(resourceType),itemName,toI18nString(expression.getOperator()),expression.getConstant(),value,tvo.getDuration() +ALERT\:\n\ resource[name\:\ %s,\ uuid\:\ %s,\ type\:\ %s]\nevent\:\ %s\ %s\ %s\ncurrent\ value\:\ %s\nduration\:\ %s\ seconds\n = ALERT:\n resource[name: {0}, uuid: {1}, type: {2}]\nevent: {3} {4} {5}\ncurrent value: {6}\nduration: {7} seconds\n -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1643 -# args: msg.getName() -unable\ to\ update\ name.\ An\ account\ already\ called\ %s = unable to update name. An account already called {0} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:40 +# args: msg.getRelativeTime() +the\ relativeTime[%s]\ is\ invalid,\ it\ must\ be\ in\ format\ of,\ for\ example,\ 10s,\ 1h = the relativeTime[{0}] is invalid, it must be in format of, for example, 10s, 1h -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1654 -# args: msg.getUuid() -old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ account[uuid\:\ %s] = old password is not equal to the original password, cannot update the password of account[uuid: {0}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:44 +# args: msg.getRelativeTime() +the\ relativeTime[%s]\ is\ invalid,\ it's\ too\ big = the relativeTime[{0}] is invalid, it's too big -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1659 +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilAlertWriter.java:95 # args: -the\ name\ of\ admin\ account\ cannot\ be\ updated = the name of admin account cannot be updated +CPU\ number = CPU number -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1665 +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilItem.java:70 +# args: cpu,trigger.getTargetResourceUuid(),cpuNum +invalid\ cpu[%s],\ the\ host[uuid\:%s]\ doesn't\ have\ a\ CPU\ numbered\ by\ %s = invalid cpu[{0}], the host[uuid:{1}] doesn't have a CPU numbered by {2} + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:92 # args: -only\ admin\ account\ can\ update\ it's\ password = only admin account can update it's password +Host\ Disk\ Capacity = Host Disk Capacity -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1672 -# args: account.getUuid(),account.getName(),msg.getUuid() -account[uuid\:\ %s,\ name\:\ %s]\ is\ a\ normal\ account,\ it\ cannot\ reset\ the\ password\ of\ another\ account[uuid\:\ %s] = account[uuid: {0}, name: {1}] is a normal account, it cannot reset the password of another account[uuid: {2}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:98 +# args: +Host\ Disk\ Capacity\ type = Host Disk Capacity type -# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:190 -# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),uuid,resourceType.getSimpleName() -permission\ denied,\ the\ account[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ resource[uuid\:%s,\ type\:%s] = permission denied, the account[uuid:{0}] is not the owner of the resource[uuid:{1}, type:{2}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:100 +# args: +Host\ devices = Host devices -# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:210 -# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),resourceWithNoAccess,resourceType.getSimpleName() -the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resources[uuid\:%s,\ type\:%s] = the account[uuid:{0}] has no access to the resources[uuid:{1}, type:{2}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostNetworkIOAlertWriter.java:77 +# args: +Host = Host -# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:80 -# args: rbacEntity.getApiMessage().getClass().getName() -operation[API\:%s]\ is\ denied\ by\ default,\ please\ contact\ admin\ to\ correct\ it = operation[API:{0}] is denied by default, please contact admin to correct it +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusMonitorProviderFactory.java:124 +# args: ret.get("errorType"),ret.get("error") +query\ failure,\ errorType\:%s,\ error\:\ %s = query failure, errorType:{0}, error: {1} -# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:187 -# args: p.getName(),p.getUuid() -the\ operation\ is\ denied\ by\ the\ policy[name\:%s\ uuid\:%s] = the operation is denied by the policy[name:{0} uuid:{1}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:81 +# args: +CPU\ Utilization = CPU Utilization -# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:200 -# args: p.getName(),p.getUuid(),fname -the\ operation\ is\ denied\ by\ the\ policy[name\:%s,\ uuid\:%s],\ field[%s]\ is\ not\ permitted\ to\ set = the operation is denied by the policy[name:{0}, uuid:{1}], field[{2}] is not permitted to set +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:84 +# args: +CPU\ utilization\ type = CPU utilization type -# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:92 +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:86 # args: -cannot\ update\ a\ system\ or\ predefined\ role = cannot update a system or predefined role +Disk\ IO = Disk IO -# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:108 +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:92 # args: -cannot\ delete\ a\ system\ or\ predefined\ role = cannot delete a system or predefined role +Disk\ IO\ direction = Disk IO direction -# at: src/main/java/org/zstack/identity/AccountQuotaChangeChecker.java:31 -# args: quota.getName(),quota.getIdentityUuid(),updatedValue -the\ quota[name\:%s]\ of\ account[uuid\:%s]\ can\ not\ be\ %d = the quota[{0}] of account[uuid:{1}] can not be {2} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:93 +# args: +Disk\ IO\ type = Disk IO type -# at: src/main/java/org/zstack/identity/AccountQuotaChangeChecker.java:55 -# args: accountUuid,quotaName,usage.getUsed(),updatedValue -the\ account[uuid\:%s]\ used\ [name\:%s,\ usedValue\:%s]\ exceeds\ request\ quota\:\ %d = the account[uuid:{0}] used [name:{1}, usedValue:{2}] exceeds request quota: {3} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOItem.java:19 +# args: type,ALLOWED_TYPES +invalid\ type[%s],\ only\ %s\ are\ allowed = invalid type[{0}], only {1} are allowed -# at: src/main/java/org/zstack/image/BackupStorageDeleteBitGC.java:35 -# args: backupStorageUuid,bsStatus -the\ backup\ storage[uuid\:%s]\ is\ not\ in\ status\ of\ Connected,\ current\ status\ is\ %s = the backup storage[uuid:{0}] is not in status of Connected, current status is {1} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilAlertWriter.java:77 +# args: +Memory\ Utilization = Memory Utilization -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:88 -# args: vol.getUuid(),vol.getStatus() -volume[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = volume[uuid:{0}] is not Ready, it's {1} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:57 +# args: expression.getConstant() +invalid\ right\ value[%s],\ it\ must\ be\ a\ float\ or\ double\ number = invalid right value[{0}], it must be a float or double number -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:92 -# args: vol.getUuid(),vol.getState() -volume[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = volume[uuid:{0}] is not Enabled, it's {1} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:53 +# args: expression.getConstant() +invalid\ right\ value[%s],\ it\ must\ be\ float\ or\ double\ number\ greater\ than\ zero\ and\ lesser\ than\ one = invalid right value[{0}], it must be float or double number greater than zero and lesser than one -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:99 -# args: vsvo.getUuid(),vsvo.getStatus() -volume\ snapshot[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = volume snapshot[uuid:{0}] is not Ready, it's {1} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:47 +# args: expression.getArguments().keySet() +invalid\ arguments\ %s,\ no\ argument\ is\ allowed = invalid arguments {0}, no argument is allowed -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:103 -# args: vsvo.getUuid(),vsvo.getState() -volume\ snapshot[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = volume snapshot[uuid:{0}] is not Enabled, it's {1} +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:84 +# args: +Network\ IO = Network IO -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:174 +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:89 # args: -ISO\ cannot\ be\ used\ as\ system\ image = ISO cannot be used as system image +Network\ IO\ direction = Network IO direction -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:180 -# args: msg.getFormat() -unknown\ format[%s] = unknown format[{0}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:77 +# args: +Virtual\ Machine = Virtual Machine -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:184 -# args: msg.getType() -unsupported\ image\ type[%s] = unsupported image type[{0}] +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:22 +# args: expression.getConstant() +invalid\ right\ value[%s],\ it\ must\ be\ a\ number(int,\ long,\ float,\ double) = invalid right value[{0}], it must be a number(int, long, float, double) -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:203 -# args: msg.getBackupStorageUuids(),BackupStorageStatus.Connected,BackupStorageState.Enabled -no\ backup\ storage\ specified\ in\ uuids%s\ is\ available\ for\ adding\ this\ image;\ they\ are\ not\ in\ status\ %s\ or\ not\ in\ state\ %s,\ or\ the\ uuid\ is\ invalid\ backup\ storage\ uuid = no backup storage specified in uuids{0} is available for adding this image; they are not in status {1} or not in state {2}, or the uuid is invalid backup storage uuid +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:18 +# args: dir,ALLOWED_DIRECTION +invalid\ direction[%s],\ only\ %s\ are\ allowed = invalid direction[{0}], only {1} are allowed -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:214 -# args: -url\ must\ starts\ with\ 'file\:///',\ 'http\://',\ 'https\://',\ 'ftp\://',\ 'sftp\://'\ or\ '/' = url must starts with 'file:///', 'http://', 'https://', 'ftp://', 'sftp://' or '/' +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:106 +# args: expr,e.getMessage() +invalid\ expression\:\ %s,\ %s = invalid expression: {0}, {1} -# at: src/main/java/org/zstack/image/ImageBase.java:168 -# args: self.getUuid(),self.getName() -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ any\ backup\ storage = the image[uuid:{0}, name:{1}] is not on any backup storage +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:110 +# args: expr +invalid\ expression\:\ %s,\ no\ expression\ found = invalid expression: {0}, no expression found -# at: src/main/java/org/zstack/image/ImageBase.java:178 -# args: self.getUuid(),self.getName() -No\ connected\ backup\ storage\ found\ for\ image[uuid\:%s,\ name\:%s] = No connected backup storage found for image[uuid:{0}, name:{1}] +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:127 +# args: key +missing\ parameter\ '%s'\ in\ the\ expression = missing parameter '{0}' in the expression -# at: src/main/java/org/zstack/image/ImageBase.java:366 -# args: msg.getImageUuid(),JSONObjectUtil.toJsonString(errors) -detach\ iso[uuid\=%s]\ from\ vm\ failed,\ errors\ are\ %s = detach iso[uuid={0}] from vm failed, errors are {1} +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:131 +# args: key,clz,value.getClass() +wrong\ type\ of\ parameter\ '%s'\ in\ the\ expression,\ it\ must\ be\ type\ of\ %s,\ but\ got\ %s = wrong type of parameter '{0}' in the expression, it must be type of {1}, but got {2} -# at: src/main/java/org/zstack/image/ImageBase.java:713 -# args: self.getUuid(),self.getName(),bsUuid -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ the\ backup\ storage[uuid\:%s] = the image[uuid:{0}, name:{1}] is not on the backup storage[uuid:{2}] +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:58 +# args: partNum +The\ number[value\:%s]\ is\ not\ a\ valid\ part\ number. = The number[value:{0}] is not a valid part number. -# at: src/main/java/org/zstack/image/ImageBase.java:655 -# args: self.getUuid(),self.getName(),ref.getStatus(),bsUuid -the\ image[uuid\:%s,\ name\:%s]'s\ status[%s]\ is\ not\ Deleted\ on\ the\ backup\ storage[uuid\:%s] = the image[uuid:{0}, name:{1}]'s status[{2}] is not Deleted on the backup storage[uuid:{3}] +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:69 +# args: mttyDeviceUuid,accu +The\ quantity\ exceeded.\ The\ device[uuid\:\ %s]\ required\ se\ devices\ number\ exceeds\ a\ quantiry[value\:\ %s]. = The quantity exceeded. The device[uuid: {0}] required se devices number exceeds a quantiry[value: {1}]. -# at: src/main/java/org/zstack/image/ImageBase.java:697 -# args: self.getUuid(),self.getName() -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ any\ backup\ storage = the image[uuid:{0}, name:{1}] is not deleted on any backup storage +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:93 +# args: rsp.getError() +failed\ to\ generate\ se\ devices,\ because\:%s = failed to generate se devices, because:{0} -# at: src/main/java/org/zstack/image/ImageBase.java:718 -# args: self.getUuid(),self.getName(),bsUuid -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ the\ backup\ storage[uuid\:%s] = the image[uuid:{0}, name:{1}] is not deleted on the backup storage[uuid:{2}] +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:152 +# args: rsp.getError() +failed\ to\ ungenerate\ se\ devices,\ because\:%s = failed to ungenerate se devices, because:{0} -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:524 -# args: bootModeCount -only\ one\ bootMode\ system\ tag\ is\ allowed,\ but\ %d\ got = only one bootMode system tag is allowed, but {0} got +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:41 +# args: msg.getMttyDeviceUuid() +mtty\ device[uuid\:%s]\ is\ not\ virtualized\ into\ mdevs = mtty device[uuid:{0}] is not virtualized into mdevs -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:542 -# args: bootMode,systemTag -[%s]\ specified\ in\ system\ tag\ [%s]\ is\ not\ a\ valid\ boot\ mode = [{0}] specified in system tag [{1}] is not a valid boot mode +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:58 +# args: msg.getMttyDeviceUuid() +mdev\ devices\ generated\ from\ mtty\ device[uuid\:%s]\ still\ attached\ to\ vm = mdev devices generated from mtty device[uuid:{0}] still attached to vm -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1032 -# args: -upload\ session\ expired = upload session expired +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:87 +# args: mtty.getHostUuid(),mtty.getUuid() +the\ host[uuid\:%s]\ that\ mtty\ device[uuid\:%s]\ in\ is\ not\ Connected = the host[uuid:{0}] that mtty device[uuid:{1}] in is not Connected -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1534 -# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) -unable\ to\ allocate\ backup\ storage\ specified\ by\ uuids%s,\ list\ errors\ are\:\ %s = unable to allocate backup storage specified by uuids{0}, list errors are: {1} +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:78 +# args: msg.getMttyDeviceUuid() +mtty\ device[uuid\:%s]\ cannot\ be\ virtualized\ into\ mdevs = mtty device[uuid:{0}] cannot be virtualized into mdevs -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1645 -# args: msgData.getRootVolumeUuid() -failed\ to\ create\ image\ from\ root\ volume[uuid\:%s]\ on\ all\ backup\ storage,\ see\ cause\ for\ one\ of\ errors = failed to create image from root volume[uuid:{0}] on all backup storage, see cause for one of errors +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:59 +# args: rpAddress +Rendezvous\ Point\ [%s]\ is\ not\ a\ unicast\ address = Rendezvous Point [{0}] is not a unicast address -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1916 -# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) -failed\ to\ allocate\ all\ backup\ storage[uuid\:%s],\ a\ list\ of\ error\:\ %s = failed to allocate all backup storage[uuid:{0}], a list of error: {1} +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:63 +# args: multicastGroup +group\ address\ [%s]\ is\ not\ a\ multicast\ address = group address [{0}] is not a multicast address -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2018 -# args: msgData.getVolumeUuid(),msgData.getBackupStorageUuids() -failed\ to\ create\ data\ volume\ template\ from\ volume[uuid\:%s]\ on\ all\ backup\ storage%s.\ See\ cause\ for\ one\ of\ errors = failed to create data volume template from volume[uuid:{0}] on all backup storage{1}. See cause for one of errors +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:75 +# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() +rp\ address\ pair\ [%s\:\ %s]\ already\ existed\ for\ multicast\ router\ [uuid\:%s] = rp address pair [{0}: {1}] already existed for multicast router [uuid:{2}] -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2104 -# args: imageUuid -image[uuid\:%s]\ is\ not\ on\ creating,\ please\ wait\ for\ it\ to\ cancel\ itself. = image[uuid:{0}] is not on creating, please wait for it to cancel itself. +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:89 +# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() +rp\ address\ tuple\ [%s\ \:\ %s]\ is\ not\ existed\ for\ multicast\ router\ [uuid\:%s] = rp address tuple [{0} : {1}] is not existed for multicast router [uuid:{2}] -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2110 -# args: volumeUuid -volume[uuid\:%s]\ has\ been\ deleted.\ no\ need\ to\ cancel = volume[uuid:{0}] has been deleted. no need to cancel +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:98 +# args: msg.getUuid() +multicastRouter[uuid\:%s]\ has\ not\ been\ attached\ to\ vpc\ router = multicastRouter[uuid:{0}] has not been attached to vpc router -# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:35 -# args: -Failed\ to\ set\ security\ level,\ because\ security\ level\ is\ disabled. = Failed to set security level, because security level is disabled. +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:124 +# args: msg.getVpcRouterVmUuid() +multicast\ already\ enabled\ on\ vpc\ router\ uuid[\:%s] = multicast already enabled on vpc router uuid[:{0}] -# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:45 -# args: msg.getSecurityLevel(),Arrays.stream(SecurityLevel.values()).map(SecurityLevel::getCode).collect(Collectors.toList()) -Unknown\ security\ level\ code[%s],\ supported\ values\ are\ %s = Unknown security level code[{0}], supported values are {1} +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:317 +# args: msg.getUuid() +vpc\ router\ for\ multicast\ router\ [uuid\:%s]\ has\ been\ deleted = vpc router for multicast router [uuid:{0}] has been deleted -# at: src/main/java/org/zstack/imagereplicator/ImageReplicatorImpl.java:318 -# args: targetBsUuid -target\ backup\ storage[uuid\:%s]\ became\ unavailable = target backup storage[uuid:{0}] became unavailable +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:760 +# args: msg.getUuid() +multicast\ router\ [uuid\:%s]\ is\ not\ attached\ to\ Vpc\ Router = multicast router [uuid:{0}] is not attached to Vpc Router -# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:30 -# args: String.join(",", msg.getBackupStorageUuids()),msg.getReplicationGroupUuid() -One\ or\ more\ backup\ storage[uuids\:%s]\ has\ been\ added\ to\ replication\ group[uuid\:%s] = One or more backup storage[uuids:{0}] has been added to replication group[uuid:{1}] +# at: src/main/java/org/zstack/multicast/router/backend/MulticastRouterVyosBackendImpl.java:95 +# args: vrUuid +multicast\ router\ [uuid\:%s]\ has\ been\ delete\ during\ enable\ multilcast\ on\ backend = multicast router [uuid:{0}] has been delete during enable multilcast on backend -# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:41 -# args: bsUuid -Backup\ storage[uuids\:%s]\ is\ not\ of\ type\ ImageStore = Backup storage[uuids:{0}] is not of type ImageStore +# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:91 +# args: msg.getNasFileSystemUuid() +nas\ file\ system\ [%s]\ is\ not\ existed\ yet = nas file system [{0}] is not existed yet -# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:51 -# args: bsUuid -Backup\ storage[uuids\:%s]\ is\ not\ attached\ to\ any\ Zone = Backup storage[uuids:{0}] is not attached to any Zone +# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:139 +# args: type +cannot\ find\ nas\ factory\ for\ type\:\ %s = cannot find nas factory for type: {0} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:63 -# args: l3NetworkUuid -Network\ [uuid\:\ %s]\ does't\ not\ have\ IPsec\ service = Network [uuid: {0}] does't not have IPsec service +# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:164 +# args: f.getClass().getSimpleName(),old.getClass().getSimpleName(),f.getNasFileSystemType() +duplicate\ NasFileSystemFactory[%s,\ %s]\ for\ type[%s] = duplicate NasFileSystemFactory[{0}, {1}] for type[{2}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:73 -# args: rcidr,tempCidr -the\ remote\ CIDR[%s]\ and\ remote\ CIDR[%s]\ are\ overlaped = the remote CIDR[{0}] and remote CIDR[{1}] are overlaped +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:63 +# args: msg.getL2NetworkUuid(),msg.getClusterUuid() +l2Network[uuid\:%s]\ has\ attached\ to\ cluster[uuid\:%s],\ can't\ attach\ again = l2Network[uuid:{0}] has attached to cluster[uuid:{1}], can't attach again -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:97 -# args: lcidr,tempCidr -the\ CIDR[%s]\ of\ local\ router\ and\ remote\ CIDR[%s]\ are\ overlaped = the CIDR[{0}] of local router and remote CIDR[{1}] are overlaped +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:75 +# args: otherL2s.get(0),l2.getPhysicalInterface() +could\ not\ attach\ l2\ network,\ because\ there\ is\ another\ network\ [uuid\:%]\ on\ physical\ interface\ [%s]\ with\ different\ vswitch\ type = could not attach l2 network, because there is another network [uuid:%] on physical interface [{0}] with different vswitch type -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:110 -# args: -all\ networks\ in\ same\ IPsecConnection\ should\ be\ same\ type = all networks in same IPsecConnection should be same type +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:87 +# args: msg.getL2NetworkUuid(),msg.getClusterUuid() +l2Network[uuid\:%s]\ has\ not\ attached\ to\ cluster[uuid\:%s] = l2Network[uuid:{0}] has not attached to cluster[uuid:{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:116 -# args: L3NetworkConstant.L3_BASIC_NETWORK_TYPE -IPsecConnection\ can\ ONLY\ have\ 1\ network\ for\ %s = IPsecConnection can ONLY have 1 network for {0} +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:101 +# args: msg.getType() +unsupported\ l2Network\ type[%s] = unsupported l2Network type[{0}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:127 -# args: l3Uuid -L3Network\ [uuid\:\ %s]\ has\ not\ been\ attached\ to\ vpc\ router = L3Network [uuid: {0}] has not been attached to vpc router +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:105 +# args: msg.getvSwitchType() +unsupported\ vSwitch\ type[%s] = unsupported vSwitch type[{0}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:133 -# args: -all\ networks\ in\ same\ IPsecConnection\ must\ be\ attached\ to\ same\ VPC\ router = all networks in same IPsecConnection must be attached to same VPC router +# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:626 +# args: vl2.getUuid(),vl2.getName(),msg.getClusterUuid(),vl2.getPhysicalInterface(),vl2.getVlan(),tl2.getUuid() +There\ has\ been\ a\ L2VlanNetwork[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s],\ vlan[%s].\ Failed\ to\ attach\ L2VlanNetwork[uuid\:%s] = There has been a L2VlanNetwork[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}], vlan[{4}]. Failed to attach L2VlanNetwork[uuid:{5}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:150 -# args: tuples.get(0).get(0, String.class),tuples.get(0).get(1, String.class) -there\ already\ have\ ipsec\ connection[uuid\:%s,\ name\:%s]\ with\ the\ same\ vrouter\ and\ peerAddress = there already have ipsec connection[uuid:{0}, name:{1}] with the same vrouter and peerAddress +# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:608 +# args: l2.getUuid(),l2.getName(),msg.getClusterUuid(),l2.getPhysicalInterface(),tl2.getUuid() +There\ has\ been\ a\ l2Network[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s].\ Failed\ to\ attach\ l2Network[uuid\:%s] = There has been a l2Network[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}]. Failed to attach l2Network[uuid:{4}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:174 -# args: msg.getVipUuid(),useForList.toString() -the\ vip[uuid\:%s]\ has\ been\ used\ for\ %s = the vip[uuid:{0}] has been used for {1} +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:84 +# args: msg.getvSwitchUuid(),msg.getVlan() +could\ not\ create\ L2PortGroupNetwork,\ because\ L2VirtualSwitchNetwork[uuid\:%s]\ already\ has\ L2PortGroupNetworks\ with\ the\ same\ vlanId[%s] = could not create L2PortGroupNetwork, because L2VirtualSwitchNetwork[uuid:{0}] already has L2PortGroupNetworks with the same vlanId[{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:179 -# args: msg.getPeerAddress() -the\ peerAddress[%s]\ cannot\ be\ the\ same\ to\ the\ VIP\ address = the peerAddress[{0}] cannot be the same to the VIP address +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:106 +# args: vswitchVO.getPhysicalInterface(),msg.getClusterUuid() +could\ not\ attach\ L2VirtualSwitchNetwork,\ because\ interface[%s]\ in\ cluster[uuid\:%s]\ is\ already\ used\ for\ another\ L2VirtualSwitchNetwork = could not attach L2VirtualSwitchNetwork, because interface[{0}] in cluster[uuid:{1}] is already used for another L2VirtualSwitchNetwork -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:183 -# args: msg.getPeerAddress() -the\ peerAddress[%s]\ is\ not\ an\ IPv4\ address = the peerAddress[{0}] is not an IPv4 address +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:113 +# args: msg.getClusterUuid() +could\ not\ attach\ L2VirtualSwitchNetwork,\ because\ there\ are\ no\ hosts\ in\ cluster[uuid\:%s] = could not attach L2VirtualSwitchNetwork, because there are no hosts in cluster[uuid:{0}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:195 -# args: -the\ authKey\ cannot\ contain\ white\ space\ and\ special\ characters\ of\ '\"`\\ = the authKey cannot contain white space and special characters of '\"`\\ +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:126 +# args: vswitchVO.getPhysicalInterface(),hostUuid +could\ not\ attach\ L2VirtualSwitchNetwork,\ because\ interface[%s]\ should\ be\ created\ on\ host[uuid\:%s] = could not attach L2VirtualSwitchNetwork, because interface[{0}] should be created on host[uuid:{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:229 -# args: -must\ include\ l3\ networks\ in\ APIAttachL3NetworksToIPsecConnectionMsg = must include l3 networks in APIAttachL3NetworksToIPsecConnectionMsg +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java:231 +# args: inv.getUuid(),destHostUuid +cannot\ configure\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot configure vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:236 -# args: l3NetworkUuid -L3\ network\ [%s]\ is\ not\ vpc\ network,\ can\ not\ be\ attached\ or\ detached\ to\ ipsec = L3 network [{0}] is not vpc network, can not be attached or detached to ipsec +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:77 +# args: vtepIps,hostUuid +find\ multiple\ vtep\ ips[%s]\ for\ one\ host[uuid\:%s],\ need\ to\ delete\ host\ and\ add\ again = find multiple vtep ips[{0}] for one host[uuid:{1}], need to delete host and add again -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:217 -# args: l3NetworkUuid,msg.getIPsecConnectionUuid() -L3\ network\ [%s]\ can\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s]twice = L3 network [{0}] can not be attached to ipsec [uuid :{1}]twice +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:82 +# args: hostUuid,l2vxlan.getPoolUuid() +failed\ to\ find\ vtep\ on\ host[uuid\:\ %s],\ please\ re-attach\ vxlanpool[uuid\:\ %s]\ to\ cluster. = failed to find vtep on host[uuid: {0}], please re-attach vxlanpool[uuid: {1}] to cluster. -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:240 -# args: l3NetworkUuid,msg.getIPsecConnectionUuid() -L3\ network\ [%s]\ is\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s] = L3 network [{0}] is not be attached to ipsec [uuid :{1}] +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:133 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vxlan.getVni(),hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vni\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vni:{3}] on kvm host[uuid:{4}], because {5} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:250 -# args: cidr,msg.getIPsecConnectionUuid() -Cidr\ [%s]\ is\ already\ in\ the\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = Cidr [{0}] is already in the Cidrs of ipsec [uuid :{1}] +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:197 +# args: cmd.getCidr(),l2vxlan.getUuid(),l2vxlan.getName(),hostUuid,rsp.getError() +failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check cidr[{0}] for l2VxlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:264 -# args: cidr,msg.getIPsecConnectionUuid() -Cidr\ [%s]\ is\ not\ in\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = Cidr [{0}] is not in Cidrs of ipsec [uuid :{1}] +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:474 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vxlan.getVni(),hostUuid,rsp.getError() +failed\ to\ delete\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vni\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to delete bridge[{0}] for l2Network[uuid:{1}, type:{2}, vni:{3}] on kvm host[uuid:{4}], because {5} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:272 -# args: msg.getUuid() -can\ not\ change\ state\ because\ ipsec\ [uuid\:%s]\ status\ is\ not\ ready = can not change state because ipsec [uuid:{0}] status is not ready +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:261 +# args: l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() +failed\ to\ realize\ vxlan\ network\ pool[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to realize vxlan network pool[uuid:{0}, type:{1}] on kvm host[uuid:{2}], because {3} -# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:132 -# args: msg.getIPsecConnectionUuid() -cannot\ find\ the\ IPsecconnection[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the IPsecconnection[uuid:{0}], it may have been deleted +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:111 +# args: cmd.getCidr(),vxlanPool.getUuid(),vxlanPool.getName(),hostUuid,rsp.getError() +failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetworkPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check cidr[{0}] for l2VxlanNetworkPool[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} -# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:336 -# args: Long.toString(range2.getStart()),Long.toString(range2.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),msg.getVipUuid() -Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ UDP = Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: UDP +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:37 +# args: VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat() +need\ to\ input\ one\ system\ tag\ like\ \:\ [%s] = need to input one system tag like : [{0}] -# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:373 -# args: cidr,l3Inv.getUuid(),uuid,rCidr -cidr[%s]\ of\ attached\ L3Network\ [uuid\:%s]\ is\ overlapped\ with\ ipsec\ [uuid\:%s]\ remote\ cidr[%s] = cidr[{0}] of attached L3Network [uuid:{1}] is overlapped with ipsec [uuid:{2}] remote cidr[{3}] +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:49 +# args: tag,VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat() +wrong\ system\ tag\ [%s],\ should\ be\ like\ \:\ [%s] = wrong system tag [{0}], should be like : [{1}] -# at: src/main/java/org/zstack/ipsec/vyos/VyosCreateIPsecFlow.java:90 -# args: errorCode.getDescription() -create\ ipsec\ to\ ha\ route\ failed,\ because\ %s = create ipsec to ha route failed, because {0} +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:55 +# args: tag +wrong\ cidr\ format\ in\ system\ tag\ [%s] = wrong cidr format in system tag [{0}] -# at: src/main/java/org/zstack/ipsec/vyos/VyosDeleteIPsecFlow.java:80 -# args: errorCode.getDescription() -delete\ ipsec\ from\ ha\ group\ failed\ because\ %s = delete ipsec from ha group failed because {0} +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:64 +# args: inv.getType(),overlappedPool +overlap\ vni\ range\ with\ %s\ [%s] = overlap vni range with {0} [{1}] -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:607 -# args: rsp.getError() -operation\ error,\ because\:%s = operation error, because:{0} +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:99 +# args: +vxlan\ network\ pool\ doesn't\ support\ create\ l3\ network = vxlan network pool doesn't support create l3 network -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:162 -# args: rcidr,cidr -the\ remoteCidr[%s]\ is\ overlaped\ with\ VirtualRouter\ interface\ cidr[%s] = the remoteCidr[{0}] is overlaped with VirtualRouter interface cidr[{1}] +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java:56 +# args: msg.getHostUuid(),msg.getPoolUuid() +vxlan\ vtep\ address\ for\ host\ [uuid\ \:\ %s]\ and\ pool\ [uuid\ \:\ %s]\ pair\ already\ existed = vxlan vtep address for host [uuid : {0}] and pool [uuid : {1}] pair already existed -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:279 +# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:27 # args: -vyos\ doesn't\ support\ aes-192\ as\ IkeEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos doesn't support aes-192 as IkeEncryptionAlgorithm, available options aes-128, aes-256, 3des +it\ is\ used = it is used -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:285 +# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:25 # args: -vyos\ doesn't\ support\ aes-192\ as\ PolicyEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos doesn't support aes-192 as PolicyEncryptionAlgorithm, available options aes-128, aes-256, 3des +it\ is\ not\ in\ this\ range = it is not in this range -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:291 -# args: msg.getIkeDhGroup() -vyos\ doesn't\ support\ %d\ as\ Ike\ DhGroup\ = vyos doesn't support {0} as Ike DhGroup +# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:23 +# args: +it\ is\ gateway = it is gateway + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:159 +# args: l2VO.getUuid(),msg.getL3NetworkUuid() +could\ not\ set\ mtu\ because\ l2\ network[uuid\:%s]\ of\ l3\ network\ [uuid\:%s]\ mtu\ can\ not\ be\ bigger\ than\ the\ novlan\ network = could not set mtu because l2 network[uuid:{0}] of l3 network [uuid:{1}] mtu can not be bigger than the novlan network + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:175 +# args: +can\ not\ delete\ the\ last\ normal\ ip\ range\ because\ there\ is\ still\ has\ address\ pool = can not delete the last normal ip range because there is still has address pool + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:190 +# args: +you\ must\ update\ system\ and\ category\ both = you must update system and category both + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:474 +# args: L3NetworkCategory.validCombination +not\ valid\ combination\ of\ system\ and\ category,only\ %s\ are\ valid = not valid combination of system and category,only {0} are valid + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:237 +# args: msg.getIp() +invalid\ IP[%s] = invalid IP[{0}] -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:424 -# args: errorCode.getDescription() -sync\ to\ ha\ group\ failed,\ because\:%s = sync to ha group failed, because:{0} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:221 +# args: msg.getL3NetworkUuid() +no\ ip\ range\ in\ l3[%s] = no ip range in l3[{0}] -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:646 -# args: errorCode.getDescription() -apply\ to\ ha\ group\ failed,\ because\ %s = apply to ha group failed, because {0} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:225 +# args: msg.getRouterInterfaceIp(),ipr.getUuid(),ipr.getNetworkCidr(),msg.getL3NetworkUuid() +ip[%s]\ is\ not\ in\ the\ cidr\ of\ ip\ range[uuid\:%s,\ cidr\:%s]\ which\ l3\ network[%s]\ attached = ip[{0}] is not in the cidr of ip range[uuid:{1}, cidr:{2}] which l3 network[{3}] attached -# at: src/main/java/org/zstack/kvm/KVMApiInterceptor.java:37 -# args: msg.getManagementIp() -there\ has\ been\ a\ kvm\ host\ having\ management\ ip[%s] = there has been a kvm host having management ip[{0}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:229 +# args: msg.getRouterInterfaceIp(),ipr.getUuid(),ipr.getStartIp(),ipr.getEndIp(),msg.getL3NetworkUuid() +ip[%s]\ in\ ip\ range[uuid\:%s,\ startIp\:%s,\ endIp\:%s]\ which\ l3\ network[%s]\ attached,\ this\ is\ not\ allowed = ip[{0}] in ip range[uuid:{1}, startIp:{2}, endIp:{3}] which l3 network[{4}] attached, this is not allowed -# at: src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java:127 -# args: l2.getType() -KVMConnectExtensionForL2Network\ wont's\ support\ L2Network[type\:%s] = KVMConnectExtensionForL2Network wont's support L2Network[type:{0}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:243 +# args: +ipRangeUuid\ and\ l3NetworkUuid\ cannot\ both\ be\ null;\ you\ must\ set\ either\ one. = ipRangeUuid and l3NetworkUuid cannot both be null; you must set either one. -# at: src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java:68 -# args: rsp.getPort(),vm.getUuid() -unexpected\ VNC\ port\ number[%d]\ for\ VM\ [uuid\:%s] = unexpected VNC port number[{0}] for VM [uuid:{1}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:276 +# args: msg.getStart(),msg.getStart() +could\ not\ get\ free\ ip\ with\ start[ip\:%s],because\ start[ip\:%s]\ is\ not\ a\ correct\ ipv6\ address = could not get free ip with start[ip:{0}],because start[ip:{1}] is not a correct ipv6 address -# at: src/main/java/org/zstack/kvm/KVMHost.java:333 -# args: self.getUuid() -host[uuid\:%s]\ has\ been\ deleted = host[uuid:{0}] has been deleted +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:274 +# args: msg.getStart(),msg.getStart() +could\ not\ get\ free\ ip\ with\ start[ip\:%s],because\ start[ip\:%s]\ is\ not\ a\ correct\ ipv4\ address = could not get free ip with start[ip:{0}],because start[ip:{1}] is not a correct ipv4 address -# at: src/main/java/org/zstack/kvm/KVMHost.java:499 -# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() -unable\ to\ get\ first\ boot\ dev\ of\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = unable to get first boot dev of vm[uuid:{0}] on kvm host [uuid:{1}, ip:{2}], because {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:272 +# args: msg.getStart(),msg.getL3NetworkUuid() +could\ not\ get\ free\ ip\ with\ start[ip\:%s],because\ l3Network[uuid\:%s]\ is\ dual\ stack = could not get free ip with start[ip:{0}],because l3Network[uuid:{1}] is dual stack -# at: src/main/java/org/zstack/kvm/KVMHost.java:713 -# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),result.getExitErrorMessage() -unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2} ] to do DNS check, please check if username/password is wrong; {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:408 +# args: msg.getNetworkCidr() +%s\ is\ not\ a\ valid\ network\ cidr = {0} is not a valid network cidr -# at: src/main/java/org/zstack/kvm/KVMHost.java:795 -# args: self.getUuid(),self.getStatus() -the\ host[uuid\:%s,\ status\:%s]\ is\ not\ Connected = the host[uuid:{0}, status:{1}] is not Connected +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:304 +# args: msg.getGateway() +%s\ is\ not\ a\ valid\ ipv6\ address = {0} is not a valid ipv6 address -# at: src/main/java/org/zstack/kvm/KVMHost.java:1121 -# args: volume.getUuid(),state -cannot\ do\ volume\ snapshot\ merge\ when\ vm[uuid\:%s]\ is\ in\ state\ of\ %s.\ The\ operation\ is\ only\ allowed\ when\ vm\ is\ Running\ or\ Stopped = cannot do volume snapshot merge when vm[uuid:{0}] is in state of {1}. The operation is only allowed when vm is Running or Stopped +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:308 +# args: msg.getStartIp(),msg.getEndIp(),msg.getPrefixLen(),msg.getGateway() +[startIp\ %s,\ endIp\ %s,\ prefixLen\ %d,\ gateway\ %s]\ is\ not\ a\ valid\ ipv6\ range = [startIp {0}, endIp {1}, prefixLen {2}, gateway {3}] is not a valid ipv6 range -# at: src/main/java/org/zstack/kvm/KVMHost.java:1128 -# args: KVMConstant.MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION,libvirtVersion -live\ volume\ snapshot\ merge\ needs\ libvirt\ version\ greater\ than\ %s,\ current\ libvirt\ version\ is\ %s.\ Please\ stop\ vm\ and\ redo\ the\ operation\ or\ detach\ the\ volume\ if\ it's\ data\ volume = live volume snapshot merge needs libvirt version greater than {0}, current libvirt version is {1}. Please stop vm and redo the operation or detach the volume if it's data volume +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:633 +# args: +adding\ normal\ ip\ range\ must\ specify\ gateway\ ip\ address = adding normal ip range must specify gateway ip address -# at: src/main/java/org/zstack/kvm/KVMHost.java:1217 -# args: msg.getVmUuid(),vmState -vm[uuid\:%s]\ is\ not\ Running\ or\ Stopped,\ current\ state[%s] = vm[uuid:{0}] is not Running or Stopped, current state[{1}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:324 +# args: +can\ not\ add\ ip\ range,\ because\ ipv6\ address\ pool\ is\ not\ supported = can not add ip range, because ipv6 address pool is not supported -# at: src/main/java/org/zstack/kvm/KVMHost.java:1578 -# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() -failed\ to\ update\ nic[vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = failed to update nic[vm:{0}] on kvm host[uuid:{1}, ip:{2}],because {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:335 +# args: IPv6Constants.IPV6_PREFIX_LEN_MIN,IPv6Constants.IPV6_PREFIX_LEN_MAX +ip\ range\ prefix\ length\ is\ out\ of\ range\ [%d\ -\ %d]\ = ip range prefix length is out of range [{0} - {1}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:1625 -# args: msg.getNicInventory().getUuid(),msg.getNicInventory().getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() -failed\ to\ attach\ nic[uuid\:%s,\ vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = failed to attach nic[uuid:{0}, vm:{1}] on kvm host[uuid:{2}, ip:{3}],because {4} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:342 +# args: +can\ not\ add\ ip\ range,\ because\ system\ network\ doesn't\ support\ ipv6\ yet = can not add ip range, because system network doesn't support ipv6 yet -# at: src/main/java/org/zstack/kvm/KVMHost.java:1672 -# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() -failed\ to\ detach\ data\ volume[uuid\:%s,\ installPath\:%s]\ from\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to detach data volume[uuid:{0}, installPath:{1}] from vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:348 +# args: ipr.getAddressMode(),rangeVOS.get(0).getAddressMode() +addressMode[%s]\ is\ different\ from\ L3Netowork\ address\ mode[%s] = addressMode[{0}] is different from L3Netowork address mode[{1}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:1759 -# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() -failed\ to\ attach\ data\ volume[uuid\:%s,\ installPath\:%s]\ to\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to attach data volume[uuid:{0}, installPath:{1}] to vm[uuid:{2}, name:{3}] on kvm host[uuid:{4}, ip:{5}], because {6} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:354 +# args: IPv6Constants.IPV6_STATELESS_PREFIX_LEN +ipv6\ prefix\ length\ must\ be\ %d\ for\ Stateless-DHCP\ or\ SLAAC = ipv6 prefix length must be {0} for Stateless-DHCP or SLAAC -# at: src/main/java/org/zstack/kvm/KVMHost.java:1799 -# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() -failed\ to\ destroy\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to destroy vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:364 +# args: ipr.getStartIp(),ipr.getEndIp(),r.getStartIp(),r.getEndIp() +new\ ip\ range\ [startip\ \:%s,\ endip\ \:%s]\ is\ overlaped\ with\ old\ ip\ range[startip\ \:%s,\ endip\ \:%s] = new ip range [startip :{0}, endip :{1}] is overlaped with old ip range[startip :{2}, endip :{3}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:1928 -# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() -failed\ to\ stop\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = failed to stop vm[uuid:{0} name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:374 +# args: r.getNetworkCidr(),ipr.getNetworkCidr() +new\ network\ CIDR\ [%s]\ is\ different\ from\ old\ network\ cidr\ [%s] = new network CIDR [{0}] is different from old network cidr [{1}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:2015 -# args: msg.getHostUuid(),ret.getError() -Host[%s]\ update\ spice\ channel\ config\ faild,\ because\ %s = Host[{0}] update spice channel config faild, because {1} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:618 +# args: ipr.getGateway(),r.getGateway() +new\ add\ ip\ range\ gateway\ %s\ is\ different\ from\ old\ gateway\ %s = new add ip range gateway {0} is different from old gateway {1} -# at: src/main/java/org/zstack/kvm/KVMHost.java:2414 -# args: msg.getPhysicalInterface(),context.getInventory().getUuid(),context.getInventory().getManagementIp() -failed\ to\ check\ physical\ network\ interfaces[names\ \:\ %s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s] = failed to check physical network interfaces[names : {0}] on kvm host[uuid:{1}, ip:{2}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:611 +# args: ipr.getGateway(),ipr.getStartIp(),ipr.getEndIp() +gateway[%s]\ can\ not\ be\ part\ of\ range[%s,\ %s] = gateway[{0}] can not be part of range[{1}, {2}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:2477 -# args: self.getUuid(),ret.getHostUuid() -detected\ abnormal\ status[host\ uuid\ change,\ expected\:\ %s\ but\:\ %s]\ of\ kvmagent,it's\ mainly\ caused\ by\ kvmagent\ restarts\ behind\ zstack\ management\ server.\ Report\ this\ to\ ping\ task,\ it\ will\ issue\ a\ reconnect\ soon = detected abnormal status[host uuid change, expected: {0} but: {1}] of kvmagent,it's mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:401 +# args: msg.getNetworkCidr() +%s\ is\ not\ an\ allowed\ network\ cidr,\ because\ it\ doesn't\ have\ usable\ ip\ range = {0} is not an allowed network cidr, because it doesn't have usable ip range -# at: src/main/java/org/zstack/kvm/KVMHost.java:2602 -# args: self.getUuid(),self.getManagementIp(),connectPath,rsp.getError() -unable\ to\ connect\ to\ kvm\ host[uuid\:%s,\ ip\:%s,\ url\:%s],\ because\ %s = unable to connect to kvm host[uuid:{0}, ip:{1}, url:{2}], because {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:405 +# args: msg.getGateway(),msg.getNetworkCidr() +%s\ is\ not\ the\ first\ or\ last\ address\ of\ the\ cidr\ %s = {0} is not the first or last address of the cidr {1} -# at: src/main/java/org/zstack/kvm/KVMHost.java:2660 +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:432 # args: -host\ can\ not\ access\ any\ primary\ storage,\ please\ check\ network = host can not access any primary storage, please check network - -# at: src/main/java/org/zstack/kvm/KVMHost.java:2836 -# args: getSelf().getPort(),KVMGlobalConfig.TEST_SSH_PORT_ON_OPEN_TIMEOUT.value(Long.class) -the\ host'\ ssh\ port[%s]\ not\ open\ after\ %s\ seconds,\ connect\ timeout = the host' ssh port[{0}] not open after {1} seconds, connect timeout +ipRangeUuids,\ L3NetworkUuids,\ zoneUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = ipRangeUuids, L3NetworkUuids, zoneUuids must have at least one be none-empty list, or all is set to true -# at: src/main/java/org/zstack/kvm/KVMHost.java:2891 -# args: checkList -failed\ to\ ping\ all\ DNS/IP\ in\ %s;\ please\ check\ /etc/resolv.conf\ to\ make\ sure\ your\ host\ is\ able\ to\ reach\ public\ internet = failed to ping all DNS/IP in {0}; please check /etc/resolv.conf to make sure your host is able to reach public internet +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:453 +# args: msg.getType() +unsupported\ l3network\ type[%s] = unsupported l3network type[{0}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:2889 -# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() -unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:\ %d,\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = unable to connect to KVM[ip:{0}, username:{1}, sshPort: {2}, ] to do DNS check, please check if username/password is wrong; {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:459 +# args: msg.getDnsDomain() +%s\ is\ not\ a\ valid\ domain\ name = {0} is not a valid domain name -# at: src/main/java/org/zstack/kvm/KVMHost.java:2917 -# args: self.getManagementIp(),restf.getHostName(),ret.getStderr(),ret.getExitErrorMessage() -the\ KVM\ host[ip\:%s]\ cannot\ access\ the\ management\ node's\ callback\ url.\ It\ seems\ that\ the\ KVM\ host\ cannot\ reach\ the\ management\ IP[%s].\ %s\ %s = the KVM host[ip:{0}] cannot access the management node's callback url. It seems that the KVM host cannot reach the management IP[{1}]. {2} {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:580 +# args: r.getUuid(),r.getStartIp(),r.getEndIp() +overlap\ with\ ip\ range[uuid\:%s,\ start\ ip\:%s,\ end\ ip\:\ %s] = overlap with ip range[uuid:{0}, start ip:{1}, end ip: {2}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:2914 -# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() -unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d]\ to\ check\ the\ management\ node\ connectivity,please\ check\ if\ username/password\ is\ wrong;\ %s = unable to connect to KVM[ip:{0}, username:{1}, sshPort:{2}] to check the management node connectivity,please check if username/password is wrong; {3} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:523 +# args: l3Vo.getUuid(),l3Vo.getName() +l3\ network\ [uuid\ %s\:\ name\ %s]\ is\ not\ a\ public\ network,\ address\ pool\ range\ can\ not\ be\ added = l3 network [uuid {0}: name {1}] is not a public network, address pool range can not be added -# at: src/main/java/org/zstack/kvm/KVMHost.java:3123 -# args: -cannot\ find\ either\ 'vmx'\ or\ 'svm'\ in\ /proc/cpuinfo,\ please\ make\ sure\ you\ have\ enabled\ virtualization\ in\ your\ BIOS\ setting = cannot find either 'vmx' or 'svm' in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:527 +# args: ipr.getStartIp(),ipr.getEndIp() +the\ IP\ range[%s\ ~\ %s]\ contains\ D\ class\ addresses\ which\ are\ for\ multicast = the IP range[{0} ~ {1}] contains D class addresses which are for multicast -# at: src/main/java/org/zstack/kvm/KVMHost.java:2748 -# args: self.getUuid(),self.getClusterUuid() -host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ qemu/libvirt\ version\ does\ not\ match = host [uuid:{0}] cannot be added to cluster [uuid:{1}] because qemu/libvirt version does not match +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:531 +# args: ipr.getStartIp(),ipr.getEndIp() +the\ IP\ range[%s\ ~\ %s]\ contains\ E\ class\ addresses\ which\ are\ reserved = the IP range[{0} ~ {1}] contains E class addresses which are reserved -# at: src/main/java/org/zstack/kvm/KVMHost.java:2769 -# args: self.getUuid(),self.getClusterUuid() -host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ cpu\ model\ name\ does\ not\ match = host [uuid:{0}] cannot be added to cluster [uuid:{1}] because cpu model name does not match +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:535 +# args: ipr.getStartIp(),ipr.getEndIp() +the\ IP\ range[%s\ ~\ %s]\ contains\ link\ local\ addresses\ which\ are\ reserved = the IP range[{0} ~ {1}] contains link local addresses which are reserved -# at: src/main/java/org/zstack/kvm/KVMHost.java:3402 -# args: -host\ is\ not\ in\ the\ connected\ status,\ cannot\ update\ os = host is not in the connected status, cannot update os +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:541 +# args: ipr.getGateway(),ipr.getStartIp(),ipr.getNetmask() +the\ gateway[%s]\ is\ not\ in\ the\ subnet\ %s/%s = the gateway[{0}] is not in the subnet {1}/{2} -# at: src/main/java/org/zstack/kvm/KVMHost.java:3400 +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:545 # args: -host\ is\ in\ the\ premaintenance\ state,\ cannot\ update\ os = host is in the premaintenance state, cannot update os +ip\ allocation\ can\ not\ contain\ network\ address\ or\ broadcast\ address = ip allocation can not contain network address or broadcast address -# at: src/main/java/org/zstack/kvm/KVMHost.java:4331 -# args: hostUuid,errorCode -fail\ to\ check\ file\ %s\ on\ host[uuid\:%s] = failed to check file[0] on host[uuid:{1}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:551 +# args: ipr.getStartIp() +start\ ip[%s]\ is\ not\ a\ IPv4\ address = start ip[{0}] is not a IPv4 address -# at: src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java:63 -# args: -cannot\ adapt\ version\ for\ the\ bellow\ rpm\:\ livirt\ /\ qemu\ /\ cpumodel = cannot adapt version for the bellow rpm: livirt / qemu / cpumodel +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:555 +# args: ipr.getEndIp() +end\ ip[%s]\ is\ not\ a\ IPv4\ address = end ip[{0}] is not a IPv4 address -# at: src/main/java/org/zstack/kvm/KVMHostCapacityExtension.java:57 -# args: host.getUuid(),rsp.getTotalMemory(),reservedSize -The\ host[uuid\:%s]'s\ available\ memory\ capacity[%s]\ is\ lower\ than\ the\ reserved\ capacity[%s] = The host[uuid:{0}]'s available memory capacity[{1}] is lower than the reserved capacity[{2}] +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:559 +# args: ipr.getGateway() +gateway[%s]\ is\ not\ a\ IPv4\ address = gateway[{0}] is not a IPv4 address -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:111 -# args: e.getMessage() -fail\ to\ load\ host\ info\ from\ file.\ because\n%s = fail to load host info from file. because\n{0} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:563 +# args: ipr.getNetmask() +netmask[%s]\ is\ not\ a\ netmask,\ and\ the\ IP\ range\ netmask\ cannot\ be\ 0.0.0.0 = netmask[{0}] is not a netmask, and the IP range netmask cannot be 0.0.0.0 -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:329 -# args: str.toString() -there\ are\ still\ hosts\ not\ have\ the\ same\ cpu\ model,\ details\:\ %s = there are still hosts not have the same cpu model, details: {0} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:569 +# args: ipr.getStartIp(),ipr.getEndIp() +start\ ip[%s]\ is\ behind\ end\ ip[%s] = start ip[{0}] is behind end ip[{1}] -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:343 -# args: KVMSystemTags.VM_PREDEFINED_PCI_BRIDGE_NUM_TOKEN -pci\ bridge\ need\ a\ value\ greater\ than\ 0\ and\ lower\ than\ 32 = pci bridge need a value greater than 0 and lower than 32 +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:596 +# args: r.getUuid(),rcidr,cidr +multiple\ CIDR\ on\ the\ same\ L3\ network\ is\ not\ allowed.\ There\ has\ been\ a\ IP\ range[uuid\:%s,\ CIDR\:%s],\ the\ new\ IP\ range[CIDR\:%s]\ is\ not\ in\ the\ CIDR\ with\ the\ existing\ one = multiple CIDR on the same L3 network is not allowed. There has been a IP range[uuid:{0}, CIDR:{1}], the new IP range[CIDR:{2}] is not in the CIDR with the existing one -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:364 -# args: hostUuid -host[uuid\:%s]\ does\ not\ have\ cpu\ model\ information,\ you\ can\ reconnect\ the\ host\ to\ fix\ it = host[uuid:{0}] does not have cpu model information, you can reconnect the host to fix it +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:606 +# args: ipr.getEndIp(),ipr.getStartIp(),ipr.getNetmask() +the\ endip[%s]\ is\ not\ in\ the\ subnet\ %s/%s = the endip[{0}] is not in the subnet {1}/{2} -# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:69 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}] on kvm host[uuid:{3}], because {4} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:659 +# args: msg.getDns(),msg.getL3NetworkUuid() +there\ has\ been\ a\ DNS[%s]\ on\ L3\ network[uuid\:%s] = there has been a DNS[{0}] on L3 network[uuid:{1}] -# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:119 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getName(),hostUuid,rsp.getError() -failed\ to\ check\ bridge[%s]\ for\ l2NoVlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = failed to check bridge[{0}] for l2NoVlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid: {3}], {4} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:692 +# args: msg.getL3NetworkUuid() +prefix\ [%s]\ is\ not\ a\ IPv4\ network\ cidr = prefix [{0}] is not a IPv4 network cidr -# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:66 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vlan.getVlan(),hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:679 +# args: msg.getNexthop() +nexthop[%s]\ is\ not\ a\ IPv4\ address = nexthop[{0}] is not a IPv4 address -# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:117 -# args: cmd.getBridgeName(),l2vlan.getUuid(),l2vlan.getName(),hostUuid,rsp.getError() -failed\ to\ check\ bridge[%s]\ for\ l2VlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check bridge[{0}] for l2VlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:686 +# args: msg.getPrefix(),msg.getL3NetworkUuid() +there\ has\ been\ a\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = there has been a hostroute for prefix[{0}] on L3 network[uuid:{1}] -# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:111 -# args: hto.getHostUuid(),rsp.getError() -failed\ to\ apply\ rules\ of\ security\ group\ rules\ to\ kvm\ host[uuid\:%s],\ because\ %s = failed to apply rules of security group rules to kvm host[uuid:{0}], because {1} +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:699 +# args: msg.getPrefix(),msg.getL3NetworkUuid() +there\ is\ no\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = there is no hostroute for prefix[{0}] on L3 network[uuid:{1}] -# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:154 -# args: hostUuid,rsp.getError() -failed\ to\ check\ default\ rules\ of\ security\ group\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to check default rules of security group on kvm host[uuid:{0}], because {1} +# at: src/main/java/org/zstack/network/plugin/FlatGratuitousARPBackend.java:286 +# args: rsp.getError() +apply\ gratuitous\ arp\ error,\ because\:%s = apply gratuitous arp error, because:{0} -# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:162 -# args: host.getUuid(),host.getManagementIp(),ret.getError() -unable\ to\ do\ vm\ sync\ on\ host[uuid\:%s,\ ip\:%s]\ because\ %s = unable to do vm sync on host[uuid:{0}, ip:{1}] because {2} +# at: src/main/java/org/zstack/network/plugin/FlatGratuitousARPBackend.java:329 +# args: rsp.getError() +release\ gratuitous\ arp\ error,\ because\:%s = release gratuitous arp error, because:{0} -# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:191 -# args: vmUuid -The\ vm[%s]\ state\ is\ in\ shutdown\ for\ a\ long\ time,\ check\ whether\ the\ vm\ is\ normal = The vm[{0}] state is in shutdown for a long time, check whether the vm is normal +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:248 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ vm\ nic[uuid\:%s]\ not\ found = could no set vm nic security group, because vm nic[uuid:{0}] not found -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:67 -# args: -unsupported\ LDAP/AD\ server\ scope = unsupported LDAP/AD server scope +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:254 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ the\ vm\ nic[uuid\:%s]\ not\ attached\ to\ any\ security\ group = could no set vm nic security group, because the vm nic[uuid:{0}] not attached to any security group -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:117 -# args: type,LdapConstant.OpenLdap.TYPE,LdapConstant.WindowsAD.TYPE -Wrong\ LdapServerType[%s],\ valid\ values\:\ [%,%s] = Wrong LdapServerType[{0}], valid values: [%,{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:261 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ security\ group[uuid\:%s]\ not\ found = could no set vm nic security group, because security group[uuid:{0}] not found -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:142 -# args: -Cannot\ connect\ to\ LDAP/AD\ server,\ Invalid\ Credentials,\ please\ checkout\ User\ DN\ and\ password = Cannot connect to LDAP/AD server, Invalid Credentials, please checkout User DN and password +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:266 +# args: priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ cannot\ be\ less\ than\ 1 = could no set vm nic security group, because invalid priority, priority[{0}] cannot be less than 1 -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:145 -# args: -Cannot\ connect\ to\ LDAP/AD\ server,\ communication\ false,\ please\ checkout\ IP,\ port\ and\ Base\ DN = Cannot connect to LDAP/AD server, communication false, please checkout IP, port and Base DN +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:270 +# args: aoMap.get(priority),ao.getSecurityGroupUuid(),priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ priority,\ both\ security\ group\ %s\ and\ %s\ have\ priority[%d] = could no set vm nic security group, because duplicate priority, both security group {0} and {1} have priority[{2}] -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:148 -# args: e.toString() -Cannot\ connect\ to\ LDAP/AD\ server,\ %s = Cannot connect to LDAP/AD server, {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:273 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ security\ group[uuid\:%s] = could no set vm nic security group, because duplicate security group[uuid:{0}] -# at: src/main/java/org/zstack/ldap/LdapManagerImpl.java:181 -# args: vo.getAccountUuid() -Account[uuid\:%s]\ Not\ Found!!! = Account[uuid:{0}] Not Found!!! +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:285 +# args: priorities[0] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority\ expects\ to\ start\ at\ 1,\ but\ [%d] = could no set vm nic security group, because invalid priority, priority expects to start at 1, but [{0}] -# at: src/main/java/org/zstack/ldap/LdapUtil.java:456 -# args: filter,errorMessage -query\ ldap\ entry[filter\:\ %s]\ fail,\ because\ %s = query ldap entry[filter: {0}] fail, because {1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:289 +# args: priorities[i],priorities[i + 1] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ and\ priority[%d]\ expected\ to\ be\ consecutive = could no set vm nic security group, because invalid priority, priority[{0}] and priority[{1}] expected to be consecutive -# at: src/main/java/org/zstack/ldap/externalSearch/AggregateSearch.java:52 -# args: e.toString() -query\ ldap\ entry\ fail,\ %s = query ldap entry fail, {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:301 +# args: ref.getSecurityGroupUuid(),sgOwnerAccountUuid +could\ no\ set\ vm\ nic\ security\ Group,\ because\ securityGroup[uuid\:%s]\ is\ already\ attached\ on\ this\ nic\ by\ account[uuid\:%s],\ current\ user\ does\ not\ have\ permission\ to\ delete = could no set vm nic security Group, because securityGroup[uuid:{0}] is already attached on this nic by account[uuid:{1}], current user does not have permission to delete -# at: src/main/java/org/zstack/license/LicenseChecker.java:129 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:310 # args: -Parse\ license\ error,\n1.\ check\ your\ private\ key\ and\ application\ code\ is\ correct\n2.\ check\ your\ license\ is\ not\ corrupted\n3.\ use\ zstack-ctl\ clear_license\ to\ clear\ your\ licenses\ and\ try\ to\ reinstall\n = Parse license error,\n1. check your private key and application code is correct\n2. check your license is not corrupted\n3. use zstack-ctl clear_license to clear your licenses and try to reinstall\n +could\ no\ change\ security\ group\ rule\ state,\ because\ ruleUuids\ is\ empty = could no change security group rule state, because ruleUuids is empty -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:220 -# args: e.getMessage() -Decode\ fail\ because\ %s = Decode fail because {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:314 +# args: msg.getSecurityGroupUuid() +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group[uuid\:%s]\ not\ found = could no change security group rule state, because security group[uuid:{0}] not found -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:217 -# args: bytes.length -Unexpected\ decoded\ license\ file\ length\:\ %d = Unexpected decoded license file length: {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:322 +# args: r +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group\ rule[uuid\:%s]\ not\ found = could no change security group rule state, because security group rule[uuid:{0}] not found -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:846 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:331 # args: -Licensed\ VM\ number\ overrun = Licensed VM number overrun +could\ no\ change\ security\ group\ rule\ state,\ because\ no\ security\ group\ rule\ state\ need\ to\ change = could no change security group rule state, because no security group rule state need to change -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1144 -# args: addonLicBy.first(),addonLicBy.second() -unexpected\ license\ policy\:\ %d\ %s. = unexpected license policy: {0} {1}. +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:339 +# args: +could\ no\ change\ vm\ nic\ security\ policy,\ because\ ingress\ policy\ and\ egress\ policy\ cannot\ be\ both\ null = could no change vm nic security policy, because ingress policy and egress policy cannot be both null -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1195 -# args: info.getProdInfo(),addonLicBy.first(),addonLicBy.second() -Addon[%s]\ licensed\ %d\ %s,\ but\ platform\ is\ licensed\ with\ VM\ number = Addon[{0}] licensed {1} {2}, but platform is licensed with VM number +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:342 +# args: msg.getIngressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ ingress\ policy[%s] = could no change vm nic security policy, because invalid ingress policy[{0}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1191 -# args: info.getProdInfo(),addonLicBy.first(),addonLicBy.second() -Addon[%s]\ licensed\ %d\ %s,\ but\ platform\ is\ licensed\ with\ host = Addon[{0}] licensed {1} {2}, but platform is licensed with host +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:346 +# args: msg.getEgressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ egress\ policy[%s] = could no change vm nic security policy, because invalid egress policy[{0}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1187 -# args: info.getProdInfo(),addonLicBy.first(),addonLicBy.second() -Addon[%s]\ licensed\ %d\ %s,\ but\ platform\ is\ licensed\ with\ CPU\ socket = Addon[{0}] licensed {1} {2}, but platform is licensed with CPU socket +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:350 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ not\ found = could no change vm nic security policy, because vm nic[uuid:{0}] not found -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1318 -# args: AddOnLicenseModule -issue\ date\ of\ addon\ license\ is\ earlier\ than\ the\ existing\ license\ issue\ date = issue date of addon license is earlier than the existing license issue date +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:355 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ has\ no\ security\ policy = could no change vm nic security policy, because vm nic[uuid:{0}] has no security policy -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1323 -# args: -issue\ date\ of\ platform\ license\ is\ earlier\ than\ the\ existing\ license\ issue\ date = issue date of platform license is earlier than the existing license issue date +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:369 +# args: msg.getType() +could\ not\ update\ security\ group\ rule\ priority,\ because\ invalid\ type[%s] = could not update security group rule priority, because invalid type[{0}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1360 -# args: -Add-on\ license\ is\ not\ supported\ when\ license\ type\ is\ Community = Add-on license is not supported when license type is Community +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:374 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ is\ not\ exist = could not update security group rule priority, because security group[uuid:{0}] is not exist -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1368 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:378 # args: -Add-on\ license\ is\ not\ supported\ when\ license\ type\ is\ Basic\ or\ Standard = Add-on license is not supported when license type is Basic or Standard +could\ not\ update\ security\ group\ rule\ priority,\ because\ rules\ is\ empty = could not update security group rule priority, because rules is empty -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1682 -# args: -License\ expired = License expired +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:388 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ rules\ size\ not\ match = could not update security group rule priority, because security group[uuid:{0}] rules size not match -# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:249 -# args: struct.getType() -No\ factory\ found\ for\ type\:%s = No factory found for type:{0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:393 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ priority[%d]\ is\ invalid = could not update security group rule priority, because rule priority[{0}] is invalid -# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:464 -# args: msg.getType() -Unknown\ log\ configuration\ type\ %s = Unknown log configuration type {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:396 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ has\ duplicate = could not update security group rule priority, because priority[{0}] has duplicate -# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:60 -# args: lstruct.getAppenderType() -No\ factory\ found\ for\ log4j2\ appender\ type\:%s. = No factory found for log4j2 appender type:{0}. +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:402 +# args: ao.getRuleUuid(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule[uuid\:%s]\ not\ in\ security\ group[uuid\:%s] = could not update security group rule priority, because rule[uuid:{0}] not in security group[uuid:{1}] -# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:134 -# args: lstruct.getAppenderType() -Unknown\ log4j2\ appender\ type\ %s = Unknown log4j2 appender type {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:405 +# args: ao.getPriority(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ not\ in\ security\ group[uuid\:%s] = could not update security group rule priority, because priority[{0}] not in security group[uuid:{1}] -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:44 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:410 # args: -facility\ can\ not\ be\ null = facility can not be null +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ uuid\ duplicate = could not update security group rule priority, because rule uuid duplicate -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:48 -# args: configuration.facility -invalid\ facility\ %s = invalid facility {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:417 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule\ uuid[%s]\ is\ not\ exist = could not change security group rule, because security group rule uuid[{0}] is not exist -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:52 -# args: -hostname\ can\ not\ be\ null = hostname can not be null +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:423 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ is\ default\ rule,\ only\ the\ description\ and\ status\ can\ be\ set = could not change security group rule, because security group rule[{0}] is default rule, only the description and status can be set -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:56 -# args: -port\ can\ not\ be\ null = port can not be null +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:429 +# args: msg.getUuid(),SecurityGroupConstant.DEFAULT_RULE_PRIORITY +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ priority\ cannot\ be\ set\ to\ default\ rule\ priority[%d] = could not change security group rule, because security group rule[{0}] priority cannot be set to default rule priority[{1}] -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:60 -# args: -protocol\ can\ not\ be\ null = protocol can not be null +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:438 +# args: vo.getType(),count.intValue(),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = could not change security group rule, because security group {0} rules number[{1}] is out of max limit[{2}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1456 -# args: Platform.getManagementServerIp() -MN\ HA\ environment,\ but\ only\ updated\ license\ for\ %s = MN HA environment, but only updated license for {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:441 +# args: vo.getType().toString(),count.intValue() +could\ not\ change\ security\ group\ rule,\ because\ the\ maximum\ priority\ of\ %s\ rule\ is\ [%d] = could not change security group rule, because the maximum priority of {0} rule is [{1}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1454 -# args: Platform.getManagementServerIp() -Multiple\ MN\ exists\ but\ only\ supplied\ licenses\ for\ %s = Multiple MN exists but only supplied licenses for {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:450 +# args: msg.getState() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ state[%s] = could not change security group rule, because invalid state[{0}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1569 -# args: -unexpected\ license\ file = unexpected license file +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:458 +# args: msg.getAction() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ action[%s] = could not change security group rule, because invalid action[{0}] -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:66 -# args: configuration.protocol -unsupported\ protocol\ %s = unsupported protocol {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:466 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ protocol[%s] = could not change security group rule, because invalid protocol[{0}] -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:80 -# args: configuration.hostname,configuration.port -syslog\ server[address\:\ %s\:%s]\ is\ not\ available = syslog server[address: {0}:{1}] is not available +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:498 +# args: msg.getUuid(),msg.getSrcIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Egress,\ srcIpRange[%s]\ cannot\ be\ set = could not change security group rule, because security group rule[{0}] type is Egress, srcIpRange[{1}] cannot be set -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:72 -# args: configuration.hostname -syslog\ server[address\:\ %s]\ is\ not\ available = syslog server[address: {0}] is not available +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:495 +# args: msg.getUuid(),msg.getDstIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Ingress,\ dstIpRange[%s]\ cannot\ be\ set = could not change security group rule, because security group rule[{0}] type is Ingress, dstIpRange[{1}] cannot be set -# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:45 -# args: -There\ is\ no\ LDAP/AD\ server\ in\ the\ system,\ Please\ add\ a\ LDAP/AD\ server\ first. = There is no LDAP/AD server in the system, Please add a LDAP/AD server first. +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:488 +# args: msg.getSrcIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ srcIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = could not change security group rule, because srcIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty -# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:39 -# args: msg.getLdapUid(),msg.getVirtualIDUuid() -Can\ not\ bind\ this\ ldap\ uid\ %s\ to\ virtual\ id\ [uuid\:%s] = Can not bind this ldap uid {0} to virtual id [uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:501 +# args: msg.getDstIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ dstIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = could not change security group rule, because dstIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty -# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:53 -# args: -This\ uid\ is\ already\ used = This uid is already used +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:508 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ not\ found = could not change security group rule, because remote security group[uuid:{0}] not found -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:230 -# args: -ZStack\ is\ loading\ ldap\ organizations\ from\ DB\ now,\ can\ not\ execute\ sync\ operation = ZStack is loading ldap organizations from DB now, can not execute sync operation +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:511 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ is\ set,\ srcIpRange\ and\ dstIpRange\ must\ be\ empty = could not change security group rule, because remote security group[uuid:{0}] is set, srcIpRange and dstIpRange must be empty -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:352 -# args: e.getMessage() -Failed\ to\ sync\ ldap\ entry[],\ because\ %s = Failed to sync ldap entry[], because {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:564 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ must\ be\ set = could not change security group rule, because rule protocol is [{0}], dstPortRange must be set -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:975 -# args: reply.getError().getReadableDetails() -Failed\ to\ sync\ organizations,\ because\ %s = Failed to sync organizations, because {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:556 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ empty = could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be empty -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:923 -# args: -Failed\ to\ transform\ ldap\ entry\ to\ organization\ ndoe = Failed to transform ldap entry to organization ndoe +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:551 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ set = could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be set -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:912 -# args: -failed\ to\ sync\ ldap\ organization = failed to sync ldap organization +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:595 +# args: JSONObjectUtil.toJsonString(sao),o.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = could not change security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1380 -# args: scope.toString() -Can\ not\ sync\ LDAP/AD\ server\ whose\ scope\ is\ not\ %s = Can not sync LDAP/AD server whose scope is not {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:721 +# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() +security\ group[uuid\:%s]\ has\ not\ attached\ to\ l3Network[uuid\:%s],\ can't\ detach = security group[uuid:{0}] has not attached to l3Network[uuid:{1}], can't detach -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1503 -# args: uid -Failed\ to\ validate\ uid[%s],\ maybe\ it\ has\ been\ deleted = Failed to validate uid[{0}], maybe it has been deleted +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:757 +# args: +can't\ delete\ rules\ of\ different\ security\ group = can't delete rules of different security group + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:760 +# args: vo.getUuid() +can't\ delete\ default\ rule[uuid\:%s] = can't delete default rule[uuid:{0}] -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1544 -# args: uid,reply.getError().getReadableDetails() -Failed\ to\ create\ iam2\ virtual\ id\ for\ uid[%s],\ because\ %s = Failed to create iam2 virtual id for uid[{0}], because {1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:780 +# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() +security\ group[uuid\:%s]\ has\ attached\ to\ l3Network[uuid\:%s],\ can't\ attach\ again = security group[uuid:{0}] has attached to l3Network[uuid:{1}], can't attach again -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1679 -# args: ldapUid -Failed\ to\ validate\ dn\ [%s],\ maybe\ it\ has\ been\ deleted = Failed to validate dn [{0}], maybe it has been deleted +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:788 +# args: msg.getL3NetworkUuid(),SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE +the\ L3\ network[uuid\:%s]\ doesn't\ have\ the\ network\ service\ type[%s]\ enabled = the L3 network[uuid:{0}] doesn't have the network service type[{1}] enabled -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2097 -# args: -invalid\ json\ format = invalid json format +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:850 +# args: wrongUuids,securityGroupUuid +VM\ nics[uuids\:%s]\ are\ not\ on\ L3\ networks\ that\ have\ been\ attached\ to\ the\ security\ group[uuid\:%s] = VM nics[uuids:{0}] are not on L3 networks that have been attached to the security group[uuid:{1}] -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2108 -# args: -name\ is\ mandatory\ field\ % = name is mandatory field % +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:886 +# args: uuid +could\ not\ add\ security\ group\ rule,\ because\ security\ group[uuid\:%s]\ does\ not\ exist = could not add security group rule, because security group[uuid:{0}] does not exist -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2112 -# args: -attribute\ is\ mandatory\ field\ % = attribute is mandatory field % +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:875 +# args: SecurityGroupConstant.ONE_API_RULES_MAX_NUM +could\ not\ add\ security\ group\ rule,\ because\ the\ rules\ cannot\ be\ empty\ or\ exceed\ the\ max\ number\ %d = could not add security group rule, because the rules cannot be empty or exceed the max number {0} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2116 -# args: -type\ is\ mandatory\ field\ % = type is mandatory field % +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:880 +# args: msg.getRemoteSecurityGroupUuids() +could\ not\ add\ security\ group\ rule,\ because\ duplicate\ uuid\ in\ remoteSecurityGroupUuids\:\ %s = could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: {0} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2120 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:891 # args: -optional\ is\ mandatory\ field\ % = optional is mandatory field % +could\ not\ add\ security\ group\ rule,\ because\ the\ remote\ security\ group\ uuid\ is\ conflict = could not add security group rule, because the remote security group uuid is conflict -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2124 -# args: fieldNames -name\ should\ use\ values\ in\ %s = name should use values in {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:927 +# args: SecurityGroupConstant.DEFAULT_RULE_PRIORITY,SecurityGroupConstant.LOWEST_RULE_PRIORITY +could\ not\ add\ security\ group\ rule,\ because\ rule\ priority\ must\ greater\ than\ %d\ or\ equals\ %d = could not add security group rule, because rule priority must greater than {0} or equals {1} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2150 -# args: rule.getAttribute() -Invalid\ attribute.\ Attribute[%s]\ is\ required,\ but\ found\ there\ are\ some\ record\ not\ matched = Invalid attribute. Attribute[{0}] is required, but found there are some record not matched +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:935 +# args: ao.getType(),SecurityGroupRuleType.getAllType() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ type[%s],\ valid\ types\ are\ %s = could not add security group rule, because invalid rule type[{0}], valid types are {1} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2101 -# args: -strategy\ is\ mandatory\ field\ % = strategy is mandatory field % +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:942 +# args: ao.getState(),SecurityGroupRuleState.getAllState() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ state[%s],\ valid\ states\ are\ %s = could not add security group rule, because invalid rule state[{0}], valid states are {1} -# at: src/main/java/org/zstack/loginControl/LoginControlApiInterceptor.java:40 -# args: e.getMessage() -Invalid\ rule\ expression,\ add\ access\ control\ rule\ fail\ because\:\ %s = Invalid rule expression, add access control rule fail because: {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:947 +# args: ao.getProtocol(),SecurityGroupRuleProtocolType.getAllProtocol() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ protocol[%s],\ valid\ protocols\ are\ %s = could not add security group rule, because invalid rule protocol[{0}], valid protocols are {1} -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:154 -# args: -wrong\ format\ of\ password\ strength\ config = wrong format of password strength config +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:954 +# args: ao.getAction(),SecurityGroupRuleAction.getAllAction() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ action[%s],\ valid\ actions\ are\ %s = could not add security group rule, because invalid rule action[{0}], valid actions are {1} -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:143 -# args: key -unrecognized\ key\:\ %s = unrecognized key: {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:962 +# args: ao.getIpVersion(),IPv6Constants.IPv4,IPv6Constants.IPv6 +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ ipVersion[%d],\ valid\ ipVersions\ are\ %d/%d = could not add security group rule, because invalid rule ipVersion[{0}], valid ipVersions are {1}/{2} -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:149 -# args: opt.get() -missing\ key\:value\ of\ %s = missing key:value of {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:990 +# args: ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ dstIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ ingress\ rule = could not add security group rule, because the dstIpRange[{0}] is not allowed to set for ingress rule -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:158 -# args: -minimum\ can\ not\ be\ larger\ than\ maximum = minimum can not be larger than maximum +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:995 +# args: ao.getAllowedCidr(),ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ srcIpRange[%s]\ are\ in\ conflict = could not add security group rule, because the allowedCidr[{0}] and srcIpRange[{1}] are in conflict -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:321 -# args: results.size() -Consult\ result\ expect\ to\ be\ 1,\ but\ actually\ %s = Consult result expect to be 1, but actually {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:984 +# args: ao.getDstIpRange(),ao.getRemoteSecurityGroupUuid() +could\ not\ add\ security\ group\ rule,\ because\ the\ ip\ range[%s]\ and\ remoteSecurityGroupUuid[%s]\ are\ in\ conflict = could not add security group rule, because the ip range[{0}] and remoteSecurityGroupUuid[{1}] are in conflict -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:505 -# args: msg.getResourceName() -No\ available\ processor\ for\ %s = No available processor for {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:972 +# args: ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ srcIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ egress\ rule = could not add security group rule, because the srcIpRange[{0}] is not allowed to set for egress rule -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:529 -# args: msg.getCaptchaUuid(),msg.getResourceName() -can\ not\ get\ suitable\ captcha\ with[uuid\:%s],\ related\ to\ resourceName[uuid\:%s] = can not get suitable captcha with[uuid:{0}], related to resourceName[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:977 +# args: ao.getAllowedCidr(),ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ dstIpRange[%s]\ are\ in\ conflict = could not add security group rule, because the allowedCidr[{0}] and dstIpRange[{1}] are in conflict -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:69 -# args: msg.getJobName() -%s\ is\ not\ an\ API = {0} is not an API +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1026 +# args: ao.getEndPort(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ endPort[%d],\ endPort\ must\ be\ greater\ than\ or\ equal\ to\ startPort[%d] = could not add security group rule, because invalid rule endPort[{0}], endPort must be greater than or equal to startPort[{1}] -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:127 -# args: -cannot\ cancel\ longjob\ that\ is\ succeeded = cannot cancel longjob that is succeeded +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1029 +# args: ao.getDstPortRange(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ dstPortRange[%s]\ and\ starPort[%s]\ are\ in\ conflict = could not add security group rule, because dstPortRange[{0}] and starPort[{1}] are in conflict -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:130 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1040 # args: -cannot\ cancel\ longjob\ that\ is\ failed = cannot cancel longjob that is failed +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ TCP/UDP\ must\ set\ dstPortRange = could not add security group rule, because the protocol type TCP/UDP must set dstPortRange -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:141 -# args: -delete\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = delete longjob only when it's succeeded, canceled, or failed +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1018 +# args: ao.getDstPortRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ dstPortRange[%s] = could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[{0}] -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:152 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1021 # args: -rerun\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = rerun longjob only when it's succeeded, canceled, or failed +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ startPort\ or\ endPort = could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort -# at: src/main/java/org/zstack/longjob/LongJobFactoryImpl.java:31 -# args: jobName -%s\ has\ no\ corresponding\ longjob = {0} has no corresponding longjob +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1050 +# args: JSONObjectUtil.toJsonString(newRules.get(i)),JSONObjectUtil.toJsonString(newRules.get(j)) +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ and\ rule[%s]\ are\ dupilicated = could not add security group rule, because rule[{0}] and rule[{1}] are dupilicated -# at: src/main/java/org/zstack/mediator/ApiValidator.java:109 -# args: l3NetworkUuid,vmNicVO.getL3NetworkUuid() -unable\ to\ attach\ a\ L3\ network.\ The\ cidr\ of\ l3[%s]\ to\ attach\ overlapped\ with\ l3[%s]\ already\ attached\ to\ vm = unable to attach a L3 network. The cidr of l3[{0}] to attach overlapped with l3[{1}] already attached to vm +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1074 +# args: JSONObjectUtil.toJsonString(sao),vo.getUuid() +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = could not add security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase -# at: src/main/java/org/zstack/mediator/ApiValidator.java:141 -# args: vm.getName(),vm.getUuid(),StringUtils.join(pfStr, ",") -the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ port\ forwarding\ rules%s\ attached = the vm[name:{0}, uuid:{1}] already has some port forwarding rules{2} attached +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1089 +# args: SecurityGroupRuleType.Egress,SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ has\ reached\ the\ maximum\ limit[%d] = could not add security group rule, because security group {0} rules has reached the maximum limit[{1}] -# at: src/main/java/org/zstack/mediator/ApiValidator.java:162 -# args: vm.getName(),vm.getUuid(),StringUtils.join(eipStr, ",") -the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ EIPs%s\ attached = the vm[name:{0}, uuid:{1}] already has some EIPs{2} attached +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1097 +# args: SecurityGroupRuleType.Egress,(egressRuleCount + toCreateEgressRuleCount),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = could not add security group rule, because security group {0} rules number[{1}] is out of max limit[{2}] -# at: src/main/java/org/zstack/mediator/ApiValidator.java:177 -# args: msg.getVipUuid(),useForList.toString() -the\ vip[uuid\:%s]\ already\ has\ bound\ to\ other\ service[%s] = the vip[uuid:{0}] already has bound to other service[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1101 +# args: msg.getPriority(),ingressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ ingress\ rule\ maximum\ priority\ is\ [%d] = could not add security group rule, because priority[{0}] must be consecutive, the ingress rule maximum priority is [{1}] -# at: src/main/java/org/zstack/mediator/ApiValidator.java:213 -# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol -Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = Current port range[{0}, {1}] is conflicted with used port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1104 +# args: msg.getPriority(),egressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ egress\ rule\ maximum\ priority\ is\ [%d] = could not add security group rule, because priority[{0}] must be consecutive, the egress rule maximum priority is [{1}] -# at: src/main/java/org/zstack/mediator/ApiValidator.java:240 -# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol -Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ system\ service\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = Current port range[{0}, {1}] is conflicted with system service port range [{2}, {3}] with vip[uuid: {4}] protocol: {5} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:1908 +# args: ref.getVmNicUuid(),msg.getSecurityGroupUuid() +vm\ nic[uuid\:%s]\ has\ been\ attach\ to\ security\ group[uuid\:%s] = vm nic[uuid:{0}] has been attach to security group[uuid:{1}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:772 -# args: l3Uuid,systemTag -L3\ network[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = L3 network[uuid:{0}] not found. Please correct your system tag[{1}] of static IP +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:1917 +# args: SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE,nic.getL3NetworkUuid(),nic.getUuid() +the\ netwotk\ service[type\:%s]\ not\ enabled\ on\ the\ l3Network[uuid\:%s]\ of\ nic[uuid\:%s] = the netwotk service[type:{0}] not enabled on the l3Network[uuid:{1}] of nic[uuid:{2}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:304 -# args: supportSharedVolumePrimaryStorage,psType -for\ shareable\ volume,\ the\ only\ supported\ primary\ storage\ type\ is\ %s,\ current\ is\ %s = for shareable volume, the only supported primary storage type is {0}, current is {1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:153 +# args: SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE,l3Uuid +the\ netwotk\ service[type\:%s]\ not\ enabled\ on\ the\ l3Network[uuid\:%s] = the netwotk service[type:{0}] not enabled on the l3Network[uuid:{1}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:734 -# args: bandwidth,Long.MAX_VALUE -invalid\ volume\ bandwidth[%s]\ is\ larger\ than\ %d = invalid volume bandwidth[{0}] is larger than {1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:1051 +# args: ao.getRuleUuid() +failed\ to\ chenge\ rule[uuid\:%s]\ priority,\ beacuse\ it's\ not\ found = failed to chenge rule[uuid:{0}] priority, beacuse it's not found -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:732 -# args: bandwidth -invalid\ volume\ bandwidth[%s]\ is\ not\ a\ number = invalid volume bandwidth[{0}] is not a number +# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:88 +# args: msg.getL3NetworkUuid() +L3Network\ [uuid\:\ %s]\ provide\ type\ null = L3Network [uuid: {0}] provide type null -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:729 -# args: bandwidth -invalid\ volume\ bandwidth[%s],\ it\ must\ be\ greater\ than\ 1024\ (include\ 1024) = invalid volume bandwidth[{0}], it must be greater than 1024 (include 1024) +# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:113 +# args: msg.getL3NetworkUuid() +L3Network\ [uuid\:\ %s]\ does\ not\ have\ host\ route\ service = L3Network [uuid: {0}] does not have host route service -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:753 -# args: bandwidth -invalid\ volume\ IOPS[%s]\ is\ not\ a\ number = invalid volume IOPS[{0}] is not a number +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:107 +# args: +networkServices\ cannot\ be\ empty = networkServices cannot be empty -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:755 -# args: bandwidth,Long.MAX_VALUE -invalid\ volume\ IOPS[%s]\ is\ larger\ than\ %d = invalid volume IOPS[{0}] is larger than {1} +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:68 +# args: puuid +network\ service\ for\ provider[uuid\:%s]\ must\ be\ specified = network service for provider[uuid:{0}] must be specified -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:750 -# args: bandwidth -invalid\ volume\ IOPS[%s],\ it\ must\ be\ greater\ than\ 0 = invalid volume IOPS[{0}], it must be greater than 0 +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:73 +# args: puuid +cannot\ find\ network\ service\ provider[uuid\:%s]\ or\ it\ provides\ no\ services = cannot find network service provider[uuid:{0}] or it provides no services -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:810 -# args: level -Unknown\ code[%s]\ of\ Security\ Level = Unknown code[{0}] of Security Level +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:87 +# args: puuid,notSupported +network\ service\ provider[uuid\:%s]\ doesn't\ provide\ services%s = network service provider[uuid:{0}] doesn't provide services{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:832 -# args: cidr -[%s]\ is\ not\ a\ standard\ cidr = [{0}] is not a standard cidr +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:99 +# args: type,msg.getL3NetworkUuid() +there\ has\ been\ a\ network\ service[%s]\ attached\ to\ L3\ network[uuid\:%s] = there has been a network service[{0}] attached to L3 network[uuid:{1}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:849 -# args: hostUuid,distro,version -the\ host[uuid\:%s]'s\ operating\ system\ %s\ %s\ is\ too\ old,\ the\ QEMU\ doesn't\ support\ QoS\ of\ network\ or\ disk\ IO.\ Please\ choose\ another\ instance\ offering\ with\ no\ QoS\ configuration = the host[uuid:{0}]'s operating system {1} {2} is too old, the QEMU doesn't support QoS of network or disk IO. Please choose another instance offering with no QoS configuration +# at: src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java:332 +# args: l3NetworkUuid,serviceType +L3Network[uuid\:%s]\ doesn't\ have\ network\ service[type\:%s]\ enabled\ or\ no\ provider\ provides\ this\ network\ service = L3Network[uuid:{0}] doesn't have network service[type:{1}] enabled or no provider provides this network service -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1082 -# args: newValue -invalid\ value[%s],\ it's\ not\ a\ double = invalid value[{0}], it's not a double +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:87 +# args: msg.getVmNicUuid() +vmNic[uuid\:%s]\ is\ not\ attached\ to\ vmInstance,\ cannot\ get\ attachable\ eips = vmNic[uuid:{0}] is not attached to vmInstance, cannot get attachable eips -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1050 -# args: newValue -invalid\ value[%s],\ it\ must\ be\ a\ double\ greater\ than\ 0 = invalid value[{0}], it must be a double greater than 0 +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:93 +# args: +either\ eipUuid\ or\ vipUuid\ must\ be\ set = either eipUuid or vipUuid must be set -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1079 -# args: newValue -invalid\ value[%s],\ it\ must\ be\ a\ double\ between\ (0,\ 1] = invalid value[{0}], it must be a double between (0, 1] +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:99 +# args: msg.getEipUuid() +eip[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ cannot\ get\ attachable\ vm\ nic = eip[uuid:{0}] is not in state of Enabled, cannot get attachable vm nic -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1093 -# args: newValue -invalid\ value[%s],\ ZStack\ doesn't\ have\ such\ host\ allocator\ type = invalid value[{0}], ZStack doesn't have such host allocator type +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:137 +# args: guestIpUuid,vmNicUuid +ip\ [uuid\:%s]\ is\ attached\ to\ vm\ nic\ [%s] = ip [uuid:{0}] is attached to vm nic [{1}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1115 -# args: MevocoGlobalConfig.AIO_NATIVE.getCanonicalName(),MevocoGlobalConfig.AIO_NATIVE.value(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.getCanonicalName(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.value() -%s\ value\ is[%s],\ which\ is\ conflict\ with\ %s\ value\ [%s] = {0} value is[{1}], which is conflict with {2} value [{3}] +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:148 +# args: msg.getEipUuid(),vmNicUuid +eip[uuid\:%s]\ has\ attached\ to\ another\ vm\ nic[uuid\:%s],\ can't\ attach\ again = eip[uuid:{0}] has attached to another vm nic[uuid:{1}], can't attach again -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1371 -# args: -obj\ is\ not\ instanceof\ NicQos! = obj is not instanceof NicQos! +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:154 +# args: msg.getEipUuid(),EipState.Enabled,state +eip[uuid\:\ %s]\ can\ only\ be\ attached\ when\ state\ is\ %s,\ current\ state\ is\ %s = eip[uuid: {0}] can only be attached when state is {1}, current state is {2} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1732 -# args: String.join(",", ips) -unexpected\ host\ management\ IPs\:\ [%s] = unexpected host management IPs: [{0}] +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:184 +# args: msg.getVmNicUuid(),msg.getEipUuid() +guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ EIP[uuid\:%s]\ are\ the\ same\ network = guest l3Network of vm nic[uuid:{0}] and vip l3Network of EIP[uuid:{1}] are the same network -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1864 -# args: -can\ not\ set\ local\ and\ configure\ at\ same\ time = can not set local and configure at same time +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:203 +# args: msg.getEipUuid(),msg.getVmNicUuid() +Ip\ address\ [uuid\:%s]\ is\ not\ belonged\ to\ nic\ [uuid\:%s] = Ip address [uuid:{0}] is not belonged to nic [uuid:{1}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1916 -# args: -can\ not\ find\ node\ A\ config\ info = can not find node A config info +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:216 +# args: msg.getUuid() +eip[uuid\:%s]\ has\ not\ attached\ to\ any\ vm\ nic = eip[uuid:{0}] has not attached to any vm nic -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1926 -# args: -can\ not\ find\ node\ A\ address\ info\ from\ bootstrap\ agent = can not find node A address info from bootstrap agent +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:239 +# args: vipIp.getIpVersion(),guestIp.getIpVersion() +vip\ ipVersion\ [%d]\ is\ different\ from\ guestIp\ ipVersion\ [%d]. = vip ipVersion [{0}] is different from guestIp ipVersion [{1}]. -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1987 -# args: s.getJobUuid() -can\ not\ get\ bootstrap\ job\ %s\ result\ after\ 900s = can not get bootstrap job {0} result after 900s +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:246 +# args: vipIp.getIp(),guestRange.getStartIp(),guestRange.getEndIp() +Vip[%s]\ is\ in\ the\ guest\ ip\ range\ [%s,\ %s] = Vip[{0}] is in the guest ip range [{1}, {2}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1995 -# args: ret.getRetCode(),ret.getStdout(),ret.getStderr() -curl\ bootstrap\ agent\ finished,\ return\ code\:\ %s,\ stdout\:\ %s,\ stderr\:\ %s = curl bootstrap agent finished, return code: {0}, stdout: {1}, stderr: {2} +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:266 +# args: vmUuid,vip.getL3NetworkUuid(),vip.getUuid(),vip.getName(),vip.getIp() +the\ vm[uuid\:%s]\ that\ the\ EIP\ is\ about\ to\ attach\ is\ already\ on\ the\ public\ network[uuid\:%s]\ from\ which\ the\ vip[uuid\:%s,\ name\:%s,\ ip\:%s]\ comes = the vm[uuid:{0}] that the EIP is about to attach is already on the public network[uuid:{1}] from which the vip[uuid:{2}, name:{3}, ip:{4}] comes -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2459 -# args: errorOfNodeA.getCauses().get(0) -node\ A\ update\ factory\ mode\ failed,\ details\:\ %s = node A update factory mode failed, details: {0} +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:277 +# args: msg.getVipUuid(),useForList.toString() +vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = vip[uuid:{0}] has been occupied other network service entity[{1}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2457 -# args: errorCodeList.getCauses().get(0) -all\ management\ node\ update\ factory\ mode\ failed,\ details\:\ %s = all management node update factory mode failed, details: {0} +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:282 +# args: +eip\ can\ not\ be\ created\ on\ system\ vip = eip can not be created on system vip -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2566 -# args: ManagementNodeState.RUNNING -management\ node\ status\ is\ not\ %s = management node status is not {0} +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:286 +# args: msg.getVipUuid(),VipState.Enabled,vip.getState() +vip[uuid\:%s]\ is\ not\ in\ state[%s],\ current\ state\ is\ %s = vip[uuid:{0}] is not in state[{1}], current state is {2} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2493 -# args: r.getStdout() -some\ node\ on\ factory\ mode\ exists,\ detail\ of\ arping\:\ %s = some node on factory mode exists, detail of arping: {0} +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:323 +# args: state.toString() +vm\ state[%s]\ is\ not\ allowed\ to\ operate\ eip,\ maybe\ you\ should\ wait\ the\ vm\ process\ complete = vm state[{0}] is not allowed to operate eip, maybe you should wait the vm process complete -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2514 -# args: -set\ address\ on\ node\ A\ failed = set address on node A failed +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:337 +# args: vmNicUuid +vmNic\ uuid[%s]\ is\ not\ allowed\ add\ eip,\ because\ vmNic\ exist\ portForwarding\ with\ allowedCidr\ rule = vmNic uuid[{0}] is not allowed add eip, because vmNic exist portForwarding with allowedCidr rule -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2511 -# args: -this\ node\ is\ not\ node\ A = this node is not node A +# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1463 +# args: struct.getEip().getUuid() +eip\ [uuid\:%s]\ is\ deleted = eip [uuid:{0}] is deleted -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2651 -# args: bandwidth -networkInboundBandwidth\ format\ error\ %s = networkInboundBandwidth format error {0} +# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1316 +# args: eip.getGuestIp(),nicIps +cannot\ find\ Eip\ guest\ ip\:\ %s\ in\ vmNic\ ips\ \:%s = cannot find Eip guest ip: {0} in vmNic ips :{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2663 -# args: bandwidth -networkOutboundBandwidth\ format\ error\ %s = networkOutboundBandwidth format error {0} +# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1622 +# args: l3.getUuid(),l3.getName(),vm.getUuid(),vm.getName() +unable\ to\ attach\ the\ L3\ network[uuid\:%s,\ name\:%s]\ to\ the\ vm[uuid\:%s,\ name\:%s],\ because\ the\ L3\ network\ is\ providing\ EIP\ to\ one\ of\ the\ vm's\ nic = unable to attach the L3 network[uuid:{0}, name:{1}] to the vm[uuid:{2}, name:{3}], because the L3 network is providing EIP to one of the vm's nic + +# at: src/main/java/org/zstack/network/service/flat/DhcpApply.java:73 +# args: msg.getL3NetworkUuid() +could\ not\ get\ dhcp4\ server\ ip\ for\ l3\ network\ [uuid\:%s] = could not get dhcp4 server ip for l3 network [uuid:{0}] + +# at: src/main/java/org/zstack/network/service/flat/DhcpApply.java:77 +# args: msg.getL3NetworkUuid() +could\ not\ get\ dhcp6\ server\ ip\ for\ l3\ network\ [uuid\:%s] = could not get dhcp6 server ip for l3 network [uuid:{0}] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2660 +# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:39 # args: -networkOutboundBandwidth\ execeds\ the\ max\ value\ 32G\ bps = networkOutboundBandwidth execeds the max value 32G bps +Session/account\ uuid\ is\ not\ valid. = Session/account uuid is not valid. -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2855 -# args: volume.getUuid(),vm.getUuid() -Shareable\ Volume[uuid\:%s]\ has\ already\ been\ attached\ to\ VM[uuid\:%s] = Shareable Volume[uuid:{0}] has already been attached to VM[uuid:{1}] +# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:43 +# args: accountUuid,msg.getL3NetworkUuid() +the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resource[uuid\:%s,\ type\:L3NetworkVO] = the account[uuid:{0}] has no access to the resource[uuid:{1}, type:L3NetworkVO] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2873 +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:647 # args: -shareable\ disk\ only\ support\ virtio-scsi\ type\ for\ now = shareable disk only support virtio-scsi type for now +l3\ network\ uuid\ cannot\ be\ null = l3 network uuid cannot be null -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3279 -# args: sharedVolUuids -shareable\ volume(s)[uuid\:\ %s]\ attached,\ not\ support\ to\ group\ snapshot. = shareable volume(s)[uuid: {0}] attached, not support to group snapshot. +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:654 +# args: msg.getL3NetworkUuid() +Cannot\ find\ DhcpIp\ for\ l3\ network[uuid\:%s] = Cannot find DhcpIp for l3 network[uuid:{0}] -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:331 -# args: vmInstanceVO.getUuid() -How\ can\ a\ Running\ VM[uuid\:%s]\ has\ no\ hostUuid? = How can a Running VM[uuid:{0}] has no hostUuid? +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:998 +# args: inv.getUuid(),destHostUuid +cannot\ configure\ DHCP\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot configure DHCP for vm[uuid:{0}] on the destination host[uuid:{1}] -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:329 -# args: vmInstanceVO.getUuid() -Unexpectedly,\ VM[uuid\:%s]\ is\ not\ running\ any\ more,\ please\ try\ again\ later = Unexpectedly, VM[uuid:{0}] is not running any more, please try again later +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1751 +# args: IPv6Constants.IPV6_PREFIX_LEN_MIN_DNSMASQ +minimum\ ip\ range\ prefix\ length\ of\ flat\ network\ is\ %d = minimum ip range prefix length of flat network is {0} -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:719 -# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() -can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ not\ attached = can not take snapshot for volumes[{0}] while volume[uuid: {1}] not attached +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1780 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv6\ address = DHCP server ip [{0}] is not a IPv6 address -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:725 -# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() -can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ appears\ twice = can not take snapshot for volumes[{0}] while volume[uuid: {1}] appears twice +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1776 +# args: dhcpServerIp,inv.getNetworkCidr() +DHCP\ server\ ip\ [%s]\ is\ not\ in\ the\ cidr\ [%s] = DHCP server ip [{0}] is not in the cidr [{1}] -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:732 -# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid(),volumeVOS.get(0).getVmInstanceUuid() -can\ not\ take\ snapshot\ for\ volumes[%s]\ attached\ multiple\ vms[%s,\ %s] = can not take snapshot for volumes[{0}] attached multiple vms[{1}, {2}] +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1772 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv4\ address = DHCP server ip [{0}] is not a IPv4 address -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:739 -# args: -no\ volumes\ found = no volumes found +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1791 +# args: entry.getKey(),inv.getL3NetworkUuid() +DHCP\ server\ ip\ [%s]\ is\ already\ existed\ in\ l3\ network\ [%s] = DHCP server ip [{0}] is already existed in l3 network [{1}] -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:971 -# args: SizeUnit.BYTE.toGigaByte((double) resize) -this\ snapshot\ recording\ the\ volume\ state\ before\ resize\ to\ %fG\ is\ created\ automatically = this snapshot recording the volume state before resize to {0}G is created automatically +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1796 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ can\ not\ be\ equaled\ to\ gateway\ ip = DHCP server ip [{0}] can not be equaled to gateway ip -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1238 -# args: msg.getUuid() -DeleteVolumeQos\ [%s]\ ingor\ because\ of\ account\ privilege. = DeleteVolumeQos [{0}] ingor because of account privilege. +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1802 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ can\ not\ be\ configured\ to\ system\ l3 = DHCP server ip [{0}] can not be configured to system l3 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1270 -# args: ivo.getHostUuid(),ivo.getState(),VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString() -Cannot\ delete\ vm's\ volume\ qos\ on\ host\ %s,\ because\ the\ current\ vm\ is\ in\ state\ of\ %s,\ but\ support\ expect\ states\ are\ [%s,\ %s] = Cannot delete vm's volume qos on host {0}, because the current vm is in state of {1}, but support expect states are [{2}, {3}] +# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:80 +# args: +could\ not\ attach\ eip\ because\ ipv6\ eip\ can\ ONLY\ be\ attached\ to\ flat\ network = could not attach eip because ipv6 eip can ONLY be attached to flat network -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1428 -# args: VolumeQos.getVolumeQosByMode(self.getVolumeQos(), msg.getMode()) -non\ admin\ account\ cannot\ set\ bandwidth\ more\ than\ %s = non admin account cannot set bandwidth more than {0} +# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:109 +# args: vmNicUuid +L2Network\ where\ vip's\ L3Network\ based\ hasn't\ attached\ the\ cluster\ where\ vmNic[uuid\:%s]\ located = L2Network where vip's L3Network based hasn't attached the cluster where vmNic[uuid:{0}] located -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1469 -# args: self.getUuid() -volume\ [%s]\ isn't\ attached\ to\ any\ vm,\ cannot\ get\ qos\ by\ forceSync = volume [{0}] isn't attached to any vm, cannot get qos by forceSync +# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:134 +# args: version,vmNicUuid +can\ not\ bound\ more\ than\ 1\ %s\ eip\ to\ a\ vm\ nic[uuid\:%s]\ of\ flat\ = can not bound more than 1 {0} eip to a vm nic[uuid:{1}] of flat -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1475 -# args: self.getUuid() -volume\ [%s]\ isn't\ attached\ to\ any\ vm\ (or\ vm\ is\ not\ existed\ now),\ cannot\ sync\ volume\ qos = volume [{0}] isn't attached to any vm (or vm is not existed now), cannot sync volume qos +# at: src/main/java/org/zstack/network/service/flat/FlatEipBackend.java:614 +# args: vmUuid,vm.getState() +unable\ to\ apply\ the\ EIP\ operation\ for\ the\ the\ vm[uuid\:%s,\ state\:%s],\ because\ cannot\ find\ the\ VM's\ hostUUid = unable to apply the EIP operation for the the vm[uuid:{0}, state:{1}], because cannot find the VM's hostUUid -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1480 -# args: vm.getUuid() -vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ volume\ qos = vm [{0}]' state must be Running or Paused to sync volume qos +# at: src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java:374 +# args: struct.getHostUuid() +host[uuid\:%s]\ is\ not\ connected = host[uuid:{0}] is not connected -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1485 -# args: -vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ volume\ qos = vm [{0}]'s HostUuid is null, cannot sync volume qos +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:306 +# args: e.getMessage() +Invalid\ rule\ expression,\ the\ detail\:\ %s = Invalid rule expression, the detail: {0} -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1595 -# args: msg.getVolume().getUuid(),msg.getVmInstanceUuid() -failed\ to\ detach\ shareable\ volume[uuid\:%s]\ from\ VmInstance[uuid\:%s] = failed to detach shareable volume[uuid:{0}] from VmInstance[uuid:{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:180 +# args: +could\ not\ get\ candidate\ vmnic,\ because\ both\ load\ balancer\ uuid\ and\ server\ group\ uuid\ are\ not\ specified = could not get candidate vmnic, because both load balancer uuid and server group uuid are not specified -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1607 -# args: StringUtils.join(errors, "\n\n") -failed\ to\ detach\ shareable\ volume\ from\ VmInstance\:[\n%s] = failed to detach shareable volume from VmInstance:[\n{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:198 +# args: +could\ not\ get\ candidate\ l3\ network,\ because\ both\ load\ balancer\ uuid\ and\ server\ group\ uuid\ are\ not\ specified = could not get candidate l3 network, because both load balancer uuid and server group uuid are not specified -# at: src/main/java/org/zstack/mevoco/PremiumGlobalConfig.java:27 -# args: getName() -the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ global\ config\ [name\:%s] = the current version of license does not support modifying this global config [name:{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:222 +# args: msg.getListenerUuid() +could\ not\ detach\ vm\ nic\ to\ load\ balancer\ listener[uuid\:%s],\ because\ default\ server\ group\ for\ listener\ has\ been\ deleted = could not detach vm nic to load balancer listener[uuid:{0}], because default server group for listener has been deleted -# at: src/main/java/org/zstack/mevoco/PremiumResourceConfig.java:22 -# args: globalConfig.getName() -the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ resource\ config\ [name\:%s] = the current version of license does not support modifying this resource config [name:{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:251 +# args: vipVO.getIp() +Load\ balancer\ VIP\ [%s]\ cannot\ be\ the\ first\ or\ the\ last\ IP\ of\ the\ CIDR\ with\ the\ public\ address\ pool\ type = Load balancer VIP [{0}] cannot be the first or the last IP of the CIDR with the public address pool type -# at: src/main/java/org/zstack/mevoco/VolumeQos.java:229 -# args: mode -invalid\ volume\ qos\ mode\:\ %s = invalid volume qos mode: {0} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:282 +# args: ipVer +operation\ failure,\ not\ support\ the\ ip\ version\ %d = operation failure, not support the ip version {0} -# at: src/main/java/org/zstack/mevoco/VolumeQos.java:199 -# args: -cannot\ find\ mode\ from\ null\ VolumeQos = cannot find mode from null VolumeQos +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:288 +# args: ips,acl.getUuid() +operation\ failure,\ duplicate/overlap\ ip\ entry\ in\ %s\ of\ accesscontrol\ list\ group\:%s = operation failure, duplicate/overlap ip entry in {0} of accesscontrol list group:{1} -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:190 -# args: msg.getMonitorTriggerUuid() -cannot\ find\ monitor\ trigger[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find monitor trigger[uuid:{0}], it may have been deleted +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:295 +# args: ips +operation\ failure,\ ip\ format\ only\ supports\ ip/iprange/cidr,\ but\ find\ %s = operation failure, ip format only supports ip/iprange/cidr, but find {0} -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:199 -# args: msg.getMonitorTriggerActionUuid() -cannot\ find\ monitor\ trigger\ action[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find monitor trigger action[uuid:{0}], it may have been deleted +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:299 +# args: startIp,endIp,NetworkUtils.longToIpv4String(r.lowerEndpoint()),NetworkUtils.longToIpv4String(r.upperEndpoint()),acl.getUuid() +ip\ range[%s,\ %s]\ is\ overlap\ with\ start\ ip\:%s,\ end\ ip\:\ %s\ of\ access-control-list\ group\:%s = ip range[{0}, {1}] is overlap with start ip:{2}, end ip: {3} of access-control-list group:{4} -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:243 -# args: msg.getResourceType() -the\ resource[type\:%s]\ doesn't\ have\ any\ monitoring\ items = the resource[type:{0}] doesn't have any monitoring items +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:321 +# args: aclUuids,lbUuid +Can't\ attach\ the\ type\ access-control-list\ group[%s]\ whose\ ip\ version\ is\ different\ with\ LoadBalancer[%s] = Can't attach the type access-control-list group[{0}] whose ip version is different with LoadBalancer[{1}] -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:335 -# args: msg.getTargetResourceUuid(),msg.getSession().getAccountUuid() -the\ resource[uuid\:%s]\ doesn't\ belong\ to\ the\ account[uuid\:%s] = the resource[uuid:{0}] doesn't belong to the account[uuid:{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:396 +# args: aclEntry.getDomain(),aclEntry.getUrl(),acl.getUuid() +domian[%s],\ url[%s]\ duplicate/overlap\ redirect\ rule\ with\ access-control-list\ group\:%s = domian[{0}], url[{1}] duplicate/overlap redirect rule with access-control-list group:{2} -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:386 -# args: resourceUuid -cannot\ find\ type\ for\ the\ resource[uuid\:%s] = cannot find type for the resource[uuid:{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:506 +# args: msg.getAclType(),msg.getAclUuids() +access-control-list\ groups[uuid\:%s]\ use\ to\ %s,\ but\ there\ some\ access-control-list\ not\ has\ ip\ entry\ but\ redirect\ rule = access-control-list groups[uuid:{0}] use to {1}, but there some access-control-list not has ip entry but redirect rule -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:391 -# args: resourceType,triggerExpression.getItem() -no\ monitoring\ item\ found\ for\ the\ resourceType[%s]\ and\ item[%s] = no monitoring item found for the resourceType[{0}] and item[{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:515 +# args: existingAcls,msg.getListenerUuid() +the\ access-control-list\ groups[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ listener[uuid\:%s] = the access-control-list groups[uuid:{0}] are already on the load balancer listener[uuid:{1}] -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:50 -# args: args -A\ resource[name\:{resourceName},\ uuid\:{resourceUuid},\ type\:{resourceType}]'s\ monitoring\ trigger[uuid\:{triggerUuid}]\ changes\ status\ to\ {triggerStatus} = A resource[name:'{resourceName}', uuid:'{resourceUuid}', type:'{resourceType}']'s monitoring trigger[uuid:'{triggerUuid}'] changes status to '{triggerStatus}' +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:521 +# args: msg.getListenerUuid(),type.toString() +the\ load\ balancer\ listener[uuid\:%s]\ just\ only\ attach\ the\ %s\ type\ access-control-list\ group = the load balancer listener[uuid:{0}] just only attach the {1} type access-control-list group -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:55 -# args: -\n\=\=\=\ BELOW\ ARE\ DETAILS\ OF\ THE\ PREVIOUS\ ALERT\ \=\=\= = \n=== BELOW ARE DETAILS OF THE PREVIOUS ALERT === +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:526 +# args: msg.getListenerUuid(),LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) +the\ load\ balancer\ listener[uuid\:%s]\ can't\ \ attach\ more\ than\ %d\ access-control-list\ groups = the load balancer listener[uuid:{0}] can't attach more than {1} access-control-list groups -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:58 -# args: -\nalert\ details\: = \nalert details: +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:414 +# args: msg.getAclUuids() +access-control-list\ groups[uuid\:%s]\ use\ to\ redirect,\ but\ there\ some\ access-control-list\ not\ has\ redirect\ rule\ but\ ip\ entry = access-control-list groups[uuid:{0}] use to redirect, but there some access-control-list not has redirect rule but ip entry -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:59 -# args: args -\ncondition\:\ {itemName}\ {operator}\ {threshold} = \ncondition: '{itemName}' '{operator}' '{threshold}' +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:419 +# args: msg.getAclUuids() +redirect\ access-control-list\ groups[uuid\:%s]\ cannot\ only\ attach\ to\ load\ balancer\ listener,\ must\ assign\ server\ group = redirect access-control-list groups[uuid:{0}] cannot only attach to load balancer listener, must assign server group -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:60 -# args: args -\ncurrent\ value\:\ {value} = \ncurrent value: '{value}' +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:424 +# args: msg.getAclUuids(),msg.getListenerUuid() +access-control-list\ groups[uuid\:%s]\ attach\ to\ load\ balancer\ listener[uuid\:%s]\ not\ https\ or\ http = access-control-list groups[uuid:{0}] attach to load balancer listener[uuid:{1}] not https or http -# at: src/main/java/org/zstack/monitoring/items/host/HostCpuUtilItem.java:31 -# args: -Host\ CPU\ utilization = Host CPU utilization +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:547 +# args: msg.getServerGroupUuids(),msg.getListenerUuid() +server\ group[%s]\ not\ attach\ to\ load\ balancer\ listener[%s] = server group[{0}] not attach to load balancer listener[{1}] -# at: src/main/java/org/zstack/monitoring/items/vm/VmCpuUtilItem.java:29 -# args: -VM\ CPU\ utilization = VM CPU utilization +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:443 +# args: msg.getAclUuids() +access-control-list\ groups[uuid\:%s]\ has\ no\ redirect\ rule = access-control-list groups[uuid:{0}] has no redirect rule -# at: src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java:141 -# args: rb.name,r -conflict\ alert\ rule[%s],\ there\ has\ been\ a\ rule[%s]\ with\ the\ same\ name = conflict alert rule[{0}], there has been a rule[{1}] with the same name +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:456 +# args: msg.getAclUuids(),msg.getListenerUuid() +access-control-list\ groups[uuid\:%s]\ has\ attach\ to\ another\ load\ balancer\ listener[uuid\:%s] = access-control-list groups[uuid:{0}] has attach to another load balancer listener[uuid:{1}] -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusAlert.java:79 -# args: resourceName,resourceUuid,toI18nString(resourceType),itemName,toI18nString(expression.getOperator()),expression.getConstant(),value,tvo.getDuration() -ALERT\:\n\ resource[name\:\ %s,\ uuid\:\ %s,\ type\:\ %s]\nevent\:\ %s\ %s\ %s\ncurrent\ value\:\ %s\nduration\:\ %s\ seconds\n = ALERT:\n resource[name: {0}, uuid: {1}, type: {2}]\nevent: {3} {4} {5}\ncurrent value: {6}\nduration: {7} seconds\n +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:468 +# args: msg.getListenerUuid(),LoadBalancerGlobalConfig.ACL_REDIRECT_MAX_COUNT.value(Long.class) +the\ load\ balancer\ listener[uuid\:%s]\ can't\ \ attach\ more\ than\ %d\ redirect\ rule\ access-control-list\ groups = the load balancer listener[uuid:{0}] can't attach more than {1} redirect rule access-control-list groups -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:40 -# args: msg.getRelativeTime() -the\ relativeTime[%s]\ is\ invalid,\ it\ must\ be\ in\ format\ of,\ for\ example,\ 10s,\ 1h = the relativeTime[{0}] is invalid, it must be in format of, for example, 10s, 1h +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:494 +# args: msg.getListenerUuid(),redireRuleExistAclUuid +load\ balancer\ listener\ [uuid\:%s]\ had\ redirect\ rule\ of\ access-control-list\ groups[uuid\:%s] = load balancer listener [uuid:{0}] had redirect rule of access-control-list groups[uuid:{1}] -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:44 -# args: msg.getRelativeTime() -the\ relativeTime[%s]\ is\ invalid,\ it's\ too\ big = the relativeTime[{0}] is invalid, it's too big +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:555 +# args: msg.getAclUuid(),msg.getListenerUuid() +acl[%s]\ not\ attach\ to\ load\ balancer\ listener[%s] = acl[{0}] not attach to load balancer listener[{1}] -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilAlertWriter.java:95 -# args: -CPU\ number = CPU number +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1294 +# args: l3Uuids,LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING +L3\ networks[uuids\:%s]\ of\ the\ vm\ nics\ has\ no\ network\ service[%s]\ enabled = L3 networks[uuids:{0}] of the vm nics has no network service[{1}] enabled -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilItem.java:70 -# args: cpu,trigger.getTargetResourceUuid(),cpuNum -invalid\ cpu[%s],\ the\ host[uuid\:%s]\ doesn't\ have\ a\ CPU\ numbered\ by\ %s = invalid cpu[{0}], the host[uuid:{1}] doesn't have a CPU numbered by {2} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:587 +# args: nicUuid,groupVO.getUuid() +could\ not\ attach\ vm\ nic\ to\ load\ balancer\ listener,\ because\ the\ vm\ nic[uuid\:%s]\ are\ already\ on\ the\ default\ server\ group\ [uuid\:%s] = could not attach vm nic to load balancer listener, because the vm nic[uuid:{0}] are already on the default server group [uuid:{1}] -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:92 -# args: -Host\ Disk\ Capacity = Host Disk Capacity +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1176 +# args: listenerVO.getProtocol(),msg.getHealthCheckProtocol() +the\ listener\ with\ protocol\ [%s]\ doesn't\ support\ this\ health\ check\:[%s] = the listener with protocol [{0}] doesn't support this health check:[{1}] -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:98 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1145 # args: -Host\ Disk\ Capacity\ type = Host Disk Capacity type +the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameter\ healthCheckURI = the http health check protocol must be specified its healthy checking parameter healthCheckURI -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:100 -# args: -Host\ devices = Host devices +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1152 +# args: msg.getHealthCheckHttpCode() +the\ http\ health\ check\ protocol's\ expecting\ code\ [%s]\ is\ invalidate = the http health check protocol's expecting code [{0}] is invalidate -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityItem.java:22 -# args: type,ALLOWED_TYPES -invalid\ type[%s],\ only\ %s\ are\ allowed = invalid type[{0}], only {1} are allowed +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:697 +# args: LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) +Can't\ attach\ more\ than\ %d\ access-control-list\ groups\ to\ a\ listener = Can't attach more than {0} access-control-list groups to a listener -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostNetworkIOAlertWriter.java:77 -# args: -Host = Host +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:787 +# args: msg.getProtocol(),msg.getName() +l4[%s]\ loadBalancer\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ state = l4[{0}] loadBalancer listener[{1}] doesn't support assigning session persistence state -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusMonitorProviderFactory.java:124 -# args: ret.get("errorType"),ret.get("error") -query\ failure,\ errorType\:%s,\ error\:\ %s = query failure, errorType:{0}, error: {1} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:808 +# args: msg.getLoadBalancerUuid(),msg.getName(),algorithm +loadBalancer[%s]\ listener[%s]\ %s\ algorithm\ doesn't\ support\ assigning\ session\ persistence\ state\ except\ assigning\ disable\ explicitly = loadBalancer[{0}] listener[{1}] {2} algorithm doesn't support assigning session persistence state except assigning disable explicitly -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:81 -# args: -CPU\ Utilization = CPU Utilization +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:823 +# args: msg.getLoadBalancerUuid(),msg.getName(),algorithm +loadBalancer[%s]\ listener[%s]\ %s\ algorithm\ doesn't\ support\ assigning\ session\ persistence\ state\ except\ assigning\ iphash\ explicitly = loadBalancer[{0}] listener[{1}] {2} algorithm doesn't support assigning session persistence state except assigning iphash explicitly -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:84 -# args: -CPU\ utilization\ type = CPU utilization type +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:849 +# args: enableSession,Arrays.toString(LoadBalancerSessionPersistence.values()) +invalid\ session\ persistence\ type[%s],\ it\ only\ support\ %s = invalid session persistence type[{0}], it only support {1} -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:86 -# args: -Disk\ IO = Disk IO +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:856 +# args: timeout,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX +invalid\ session\ idle\ timeout[%s],\ it\ must\ be\ the\ number\ between[%s~%s]\ = invalid session idle timeout[{0}], it must be the number between[{1}~{2}] -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:92 -# args: -Disk\ IO\ direction = Disk IO direction +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:863 +# args: cookieName,COOKIE_NAME_MAX +invalid\ session\ cookie\ name[%s],\ it\ must\ be\ shorter\ than\ [%s]\ characters = invalid session cookie name[{0}], it must be shorter than [{1}] characters -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:93 -# args: -Disk\ IO\ type = Disk IO type +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:866 +# args: cookieName +invalid\ session\ cookie\ name[%s],\ it\ must\ only\ contains\ letters,\ numbers\ and\ underscores = invalid session cookie name[{0}], it must only contains letters, numbers and underscores -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilAlertWriter.java:77 -# args: -Memory\ Utilization = Memory Utilization +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:870 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ idle\ timeout\ and\ cookie\ name\ at\ the\ same\ time = loadBalancer[{0}] listener[{1}] doesn't support assigning idle timeout and cookie name at the same time -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:57 -# args: expression.getConstant() -invalid\ right\ value[%s],\ it\ must\ be\ a\ float\ or\ double\ number = invalid right value[{0}], it must be a float or double number +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:876 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ idle\ timeout\ and\ cookie\ name,\ it\ must\ specify\ session\ persistence = loadBalancer[{0}] listener[{1}] doesn't support assigning idle timeout and cookie name, it must specify session persistence -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:53 -# args: expression.getConstant() -invalid\ right\ value[%s],\ it\ must\ be\ float\ or\ double\ number\ greater\ than\ zero\ and\ lesser\ than\ one = invalid right value[{0}], it must be float or double number greater than zero and lesser than one +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:880 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ idle\ timeout\ and\ cookie\ name\ when\ the\ session\ persistence\ is\ disabled = loadBalancer[{0}] listener[{1}] doesn't support assigning idle timeout and cookie name when the session persistence is disabled -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:47 -# args: expression.getArguments().keySet() -invalid\ arguments\ %s,\ no\ argument\ is\ allowed = invalid arguments {0}, no argument is allowed +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:894 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ rewrite\ without\ assigning\ cookie\ name = loadBalancer[{0}] listener[{1}] doesn't support assigning session persistence rewrite without assigning cookie name -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:84 -# args: -Network\ IO = Network IO +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:899 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ idle\ timeout\ without\ assigning\ rewrite\ mode = loadBalancer[{0}] listener[{1}] doesn't support assigning session persistence idle timeout without assigning rewrite mode -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:89 -# args: -Network\ IO\ direction = Network IO direction +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:904 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ cookieName\ without\ assigning\ insert\ mode = loadBalancer[{0}] listener[{1}] doesn't support assigning session persistence cookieName without assigning insert mode -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:77 -# args: -Virtual\ Machine = Virtual Machine +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:909 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ rewrite\ when\ the\ http\ mode\ is\ http-tunnel = loadBalancer[{0}] listener[{1}] doesn't support assigning session persistence rewrite when the http mode is http-tunnel -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:22 -# args: expression.getConstant() -invalid\ right\ value[%s],\ it\ must\ be\ a\ number(int,\ long,\ float,\ double) = invalid right value[{0}], it must be a number(int, long, float, double) +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:920 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ other\ session\ persistence\ when\ the\ source\ balancer\ algorithm\ is\ source = loadBalancer[{0}] listener[{1}] doesn't support assigning other session persistence when the source balancer algorithm is source -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:18 -# args: dir,ALLOWED_DIRECTION -invalid\ direction[%s],\ only\ %s\ are\ allowed = invalid direction[{0}], only {1} are allowed +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:932 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ iphash = loadBalancer[{0}] listener[{1}] doesn't support assigning session persistence iphash -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:106 -# args: expr,e.getMessage() -invalid\ expression\:\ %s,\ %s = invalid expression: {0}, {1} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:950 +# args: tag,s,LoadBalancerConstants.MAX_CONNECTION_LIMIT +invalid\ max\ connection[%s],\ %s\ is\ larger\ than\ upper\ threshold\ %d = invalid max connection[{0}], {1} is larger than upper threshold {2} -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:110 -# args: expr -invalid\ expression\:\ %s,\ no\ expression\ found = invalid expression: {0}, no expression found +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:972 +# args: msg.getLoadBalancerPort(),luuid +conflict\ loadBalancerPort[%s],\ a\ listener[uuid\:%s]\ has\ used\ that\ port = conflict loadBalancerPort[{0}], a listener[uuid:{1}] has used that port -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:127 -# args: key -missing\ parameter\ '%s'\ in\ the\ expression = missing parameter '{0}' in the expression +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1161 +# args: listenerVO.getProtocol(),msg.getHealthCheckProtocol() +the\ listener\ with\ protocol\ [%s]\ doesn't\ support\ select\ security\ policy = the listener with protocol [{0}] doesn't support select security policy -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:131 -# args: key,clz,value.getClass() -wrong\ type\ of\ parameter\ '%s'\ in\ the\ expression,\ it\ must\ be\ type\ of\ %s,\ but\ got\ %s = wrong type of parameter '{0}' in the expression, it must be type of {1}, but got {2} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1005 +# args: vo.getProtocol() +loadbalancer\ listener\ with\ type\ %s\ does\ not\ need\ certificate = loadbalancer listener with type {0} does not need certificate -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:59 -# args: rpAddress -Rendezvous\ Point\ [%s]\ is\ not\ a\ unicast\ address = Rendezvous Point [{0}] is not a unicast address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1009 +# args: msg.getListenerUuid(),msg.getCertificateUuid() +loadbalancer\ listener\ [uuid\:%s]\ already\ had\ certificate[uuid\:%s] = loadbalancer listener [uuid:{0}] already had certificate[uuid:{1}] -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:63 -# args: multicastGroup -group\ address\ [%s]\ is\ not\ a\ multicast\ address = group address [{0}] is not a multicast address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1019 +# args: msg.getCertificateUuid(),msg.getListenerUuid() +certificate\ [uuid\:%s]\ is\ not\ added\ to\ loadbalancer\ listener\ [uuid\:%s] = certificate [uuid:{0}] is not added to loadbalancer listener [uuid:{1}] -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:75 -# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() -rp\ address\ pair\ [%s\:\ %s]\ already\ existed\ for\ multicast\ router\ [uuid\:%s] = rp address pair [{0}: {1}] already existed for multicast router [uuid:{2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1034 +# args: target +healthCheck\ target\ [%s]\ error,\ it\ must\ be\ 'default'\ or\ number\ between[1~65535]\ = healthCheck target [{0}] error, it must be 'default' or number between[1~65535] -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:89 -# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() -rp\ address\ tuple\ [%s\ \:\ %s]\ is\ not\ existed\ for\ multicast\ router\ [uuid\:%s] = rp address tuple [{0} : {1}] is not existed for multicast router [uuid:{2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1050 +# args: listener.getProtocol(),listener.getName() +l4[%s]\ loadBalancer\ listener[%s]\ doesn't\ support\ modifying\ session\ persistence\ state = l4[{0}] loadBalancer listener[{1}] doesn't support modifying session persistence state -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:98 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1064 # args: msg.getUuid() -multicastRouter[uuid\:%s]\ has\ not\ been\ attached\ to\ vpc\ router = multicastRouter[uuid:{0}] has not been attached to vpc router - -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:124 -# args: msg.getVpcRouterVmUuid() -multicast\ already\ enabled\ on\ vpc\ router\ uuid[\:%s] = multicast already enabled on vpc router uuid[:{0}] +listener[%s]\ can\ not\ modifying\ session\ persistence\ rewrite\ when\ the\ http\ mode\ is\ http-tunnel = listener[{0}] can not modifying session persistence rewrite when the http mode is http-tunnel -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:316 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1072 # args: msg.getUuid() -vpc\ router\ for\ multicast\ router\ [uuid\:%s]\ has\ been\ deleted = vpc router for multicast router [uuid:{0}] has been deleted +listener[%s]\ can\ not\ modifying\ httpMode\ http-tunnel\ when\ the\ session\ persistence\ is\ rewrite = listener[{0}] can not modifying httpMode http-tunnel when the session persistence is rewrite -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:759 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1079 # args: msg.getUuid() -multicast\ router\ [uuid\:%s]\ is\ not\ attached\ to\ Vpc\ Router = multicast router [uuid:{0}] is not attached to Vpc Router +listener[%s]\ changes\ session\ persistence\ to\ iphash,\ it\ must\ specify\ source\ balancer\ algorithm = listener[{0}] changes session persistence to iphash, it must specify source balancer algorithm -# at: src/main/java/org/zstack/multicast/router/backend/MulticastRouterVyosBackendImpl.java:86 -# args: vrUuid -multicast\ router\ [uuid\:%s]\ has\ been\ delete\ during\ enable\ multilcast\ on\ backend = multicast router [uuid:{0}] has been delete during enable multilcast on backend +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1084 +# args: msg.getUuid() +listener[%s]\ modifies\ session\ persistence,\ it\ must\ specify\ balancer\ algorithm = listener[{0}] modifies session persistence, it must specify balancer algorithm -# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:91 -# args: msg.getNasFileSystemUuid() -nas\ file\ system\ [%s]\ is\ not\ existed\ yet = nas file system [{0}] is not existed yet +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1090 +# args: msg.getUuid(),msg.getBalancerAlgorithm() +listener[%s]\ %s\ algorithm\ doesn't\ support\ modifying\ session\ persistence\ except\ assigning\ iphash\ explicitly = listener[{0}] {1} algorithm doesn't support modifying session persistence except assigning iphash explicitly -# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:139 -# args: type -cannot\ find\ nas\ factory\ for\ type\:\ %s = cannot find nas factory for type: {0} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1098 +# args: msg.getUuid(),msg.getBalancerAlgorithm() +listener[%s]\ %s\ algorithm\ doesn't\ support\ modifying\ session\ persistence\ except\ assigning\ disable\ explicitly = listener[{0}] {1} algorithm doesn't support modifying session persistence except assigning disable explicitly -# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:164 -# args: f.getClass().getSimpleName(),old.getClass().getSimpleName(),f.getNasFileSystemType() -duplicate\ NasFileSystemFactory[%s,\ %s]\ for\ type[%s] = duplicate NasFileSystemFactory[{0}, {1}] for type[{2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1106 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ idle\ timeout\ and\ cookie\ name,\ it\ must\ specify\ session\ persistence = listener[{0}] doesn't support modifying idle timeout and cookie name, it must specify session persistence -# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:66 -# args: msg.getL2NetworkUuid(),msg.getClusterUuid() -l2Network[uuid\:%s]\ has\ attached\ to\ cluster[uuid\:%s],\ can't\ attach\ again = l2Network[uuid:{0}] has attached to cluster[uuid:{1}], can't attach again +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1110 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ idle\ timeout\ when\ the\ session\ persistence\ is\ not\ insert = listener[{0}] doesn't support modifying idle timeout when the session persistence is not insert -# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:75 -# args: msg.getL2NetworkUuid(),msg.getClusterUuid() -l2Network[uuid\:%s]\ has\ not\ attached\ to\ cluster[uuid\:%s] = l2Network[uuid:{0}] has not attached to cluster[uuid:{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1114 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ cookie\ name\ when\ the\ session\ persistence\ is\ not\ rewrite = listener[{0}] doesn't support modifying cookie name when the session persistence is not rewrite -# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:89 -# args: msg.getType() -unsupported\ l2Network\ type[%s] = unsupported l2Network type[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1118 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ session\ rewrite\ without\ modifying\ cookie\ name = listener[{0}] doesn't support modifying session rewrite without modifying cookie name -# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:558 -# args: vl2.getUuid(),vl2.getName(),msg.getClusterUuid(),vl2.getPhysicalInterface(),vl2.getVlan(),tl2.getUuid() -There\ has\ been\ a\ L2VlanNetwork[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s],\ vlan[%s].\ Failed\ to\ attach\ L2VlanNetwork[uuid\:%s] = There has been a L2VlanNetwork[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}], vlan[{4}]. Failed to attach L2VlanNetwork[uuid:{5}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1132 +# args: timeout,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX +invalid\ session\ idle\ timeout[%s],\ it\ must\ be\ the\ number\ between[%s~%s] = invalid session idle timeout[{0}], it must be the number between[{1}~{2}] -# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:540 -# args: l2.getUuid(),l2.getName(),msg.getClusterUuid(),l2.getPhysicalInterface(),tl2.getUuid() -There\ has\ been\ a\ l2Network[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s].\ Failed\ to\ attach\ l2Network[uuid\:%s] = There has been a l2Network[uuid:{0}, name:{1}] attached to cluster[uuid:{2}] that has physical interface[{3}]. Failed to attach l2Network[uuid:{4}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1181 +# args: +the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameters\ including\ healthCheckMethod\ and\ healthCheckURI = the http health check protocol must be specified its healthy checking parameters including healthCheckMethod and healthCheckURI -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java:218 -# args: inv.getUuid(),destHostUuid -cannot\ configure\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot configure vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1204 +# args: msg.getUuid() +could\ not\ allow\ to\ delete\ default\ serverGroup[uuid\:%s] = could not allow to delete default serverGroup[uuid:{0}] -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:79 -# args: vtepIps,hostUuid -find\ multiple\ vtep\ ips[%s]\ for\ one\ host[uuid\:%s],\ need\ to\ delete\ host\ and\ add\ again = find multiple vtep ips[{0}] for one host[uuid:{1}], need to delete host and add again +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1429 +# args: msg.getServerGroupUuid() +loadbalacerServerGroup\ [%s]\ is\ non-existent = loadbalacerServerGroup [{0}] is non-existent -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:119 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vxlan.getVni(),hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vni\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for l2Network[uuid:{1}, type:{2}, vni:{3}] on kvm host[uuid:{4}], because {5} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1263 +# args: vmNic.get("uuid"),msg.getServerGroupUuid() +could\ not\ add\ backend\ server\ vmnic[uuid\:%s]\ to\ serverGroup[uuid\:%s],because\ vmnic\ uuid\ is\ not\ exist = could not add backend server vmnic[uuid:{0}] to serverGroup[uuid:{1}],because vmnic uuid is not exist -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:183 -# args: cmd.getCidr(),l2vxlan.getUuid(),l2vxlan.getName(),hostUuid,rsp.getError() -failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check cidr[{0}] for l2VxlanNetwork[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1274 +# args: vmNic.get("weight") +could\ not\ add\ backend\ server\ vmnic\ to\ serverGroup[uuid\:%s]\ ,because\ vmnic\ weight[%s]\ not\ a\ correct\ number = could not add backend server vmnic to serverGroup[uuid:{0}] ,because vmnic weight[{1}] not a correct number -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:251 -# args: l2Network.getUuid(),l2Network.getType(),l2networks,hostUuid,rsp.getError() -failed\ to\ realize\ vxlan\ network\ pool[uuid\:%s,\ type\:%s,\ vnis\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to realize vxlan network pool[uuid:{0}, type:{1}, vnis:{2}] on kvm host[uuid:{3}], because {4} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1552 +# args: vmNic.get("uuid"),vmNicWeight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight[vimNic\:%s,weight\:%s],\ weight\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid balancer weight[vimNic:{0},weight:{1}], weight is not in the range [{2}, {3}] -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:110 -# args: cmd.getCidr(),vxlanPool.getUuid(),vxlanPool.getName(),hostUuid,rsp.getError() -failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetworkPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check cidr[{0}] for l2VxlanNetworkPool[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1304 +# args: existingNics,msg.getServerGroupUuid() +the\ vm\ nics[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ servegroup\ [uuid\:%s] = the vm nics[uuid:{0}] are already on the load balancer servegroup [uuid:{1}] -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java:55 -# args: msg.getHostUuid(),msg.getPoolUuid() -vxlan\ vtep\ address\ for\ host\ [uuid\ \:\ %s]\ and\ pool\ [uuid\ \:\ %s]\ pair\ already\ existed = vxlan vtep address for host [uuid : {0}] and pool [uuid : {1}] pair already existed +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1313 +# args: msg.getServerGroupUuid(),vmNicIps +could\ not\ add\ backend\ server\ vmnic\ to\ serverGroup\ [uuid\:%s],\ because\ vmnic\ ip\ [ipAddress\:%s]\ is\ repeated = could not add backend server vmnic to serverGroup [uuid:{0}], because vmnic ip [ipAddress:{1}] is repeated -# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:27 -# args: -it\ is\ used = it is used +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1325 +# args: vmNicUuids,msg.getServerGroupUuid(),listenerVO.getUuid() +could\ not\ add\ vm\ nic\ [uuid\:%s]\ to\ server\ group\ [uuid\:%s]\ because\ listener\ [uuid\:%s]\ attached\ this\ server\ group\ already\ the\ nic\ to\ be\ added = could not add vm nic [uuid:{0}] to server group [uuid:{1}] because listener [uuid:{2}] attached this server group already the nic to be added -# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:25 -# args: -it\ is\ not\ in\ this\ range = it is not in this range +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1606 +# args: msg.getServerGroupUuid(),serverIps +could\ not\ add\ backend\ server\ ip\ to\ serverGroup\ [uuid\:%s],\ because\ ip\ [ipAddress\:%s]\ is\ invalid = could not add backend server ip to serverGroup [uuid:{0}], because ip [ipAddress:{1}] is invalid -# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:23 -# args: -it\ is\ gateway = it is gateway +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1341 +# args: msg.getServerGroupUuid(),server.get("ipAddress") +could\ not\ add\ backend\ server\ ip\ to\ serverGroup\ [uuid\:%s],\ because\ ip\ [ipAddress\:%s]\ is\ repeated = could not add backend server ip to serverGroup [uuid:{0}], because ip [ipAddress:{1}] is repeated -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:116 -# args: -you\ must\ update\ system\ and\ category\ both = you must update system and category both +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1599 +# args: server.get("weight") +could\ not\ add\ backend\ server\ ip\ to\ serverGroup[uuid\:%s]\ ,because\ vmnic\ weight[%s]\ not\ a\ correct\ number = could not add backend server ip to serverGroup[uuid:{0}] ,because vmnic weight[{1}] not a correct number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:355 -# args: L3NetworkCategory.validCombination -not\ valid\ combination\ of\ system\ and\ category,only\ %s\ are\ valid = not valid combination of system and category,only {0} are valid +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1352 +# args: server.get("ipAddress"),serverIpWeight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ \ weight[serverIp\:%s,weight\:%s],\ weight\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid weight[serverIp:{0},weight:{1}], weight is not in the range [{2}, {3}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:161 -# args: msg.getIp() -invalid\ IP[%s] = invalid IP[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1367 +# args: existingServerIps,msg.getServerGroupUuid() +the\ server\ ips\ [uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ servegroup\ [uuid\:%s] = the server ips [uuid:{0}] are already on the load balancer servegroup [uuid:{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:145 -# args: msg.getL3NetworkUuid() -no\ ip\ range\ in\ l3[%s] = no ip range in l3[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1611 +# args: +could\ not\ add\ server\ ip\ to\ share\ load\ balancer\ server\ group = could not add server ip to share load balancer server group -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:149 -# args: msg.getRouterInterfaceIp(),ipRangeVO.getUuid(),ipRangeVO.getNetworkCidr(),msg.getL3NetworkUuid() -ip[%s]\ is\ not\ in\ the\ cidr\ of\ ip\ range[uuid\:%s,\ cidr\:%s]\ which\ l3\ network[%s]\ attached = ip[{0}] is not in the cidr of ip range[uuid:{1}, cidr:{2}] which l3 network[{3}] attached +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1433 +# args: +vmnic\ or\ ip\ is\ null = vmnic or ip is null -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:153 -# args: msg.getRouterInterfaceIp(),ipRangeVO.getUuid(),ipRangeVO.getStartIp(),ipRangeVO.getEndIp(),msg.getL3NetworkUuid() -ip[%s]\ in\ ip\ range[uuid\:%s,\ startIp\:%s,\ endIp\:%s]\ which\ l3\ network[%s]\ attached,\ this\ is\ not\ allowed = ip[{0}] in ip range[uuid:{1}, startIp:{2}, endIp:{3}] which l3 network[{4}] attached, this is not allowed +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1397 +# args: msg.getServerGroupUuid() +vmnics\ are\ all\ not\ in\ servergroup\ [%s] = vmnics are all not in servergroup [{0}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:167 -# args: -ipRangeUuid\ and\ l3NetworkUuid\ cannot\ both\ be\ null;\ you\ must\ set\ either\ one. = ipRangeUuid and l3NetworkUuid cannot both be null; you must set either one. +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1414 +# args: msg.getServerGroupUuid() +serverips\ are\ all\ not\ in\ servergroup\ [%s] = serverips are all not in servergroup [{0}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:293 -# args: msg.getNetworkCidr() -%s\ is\ not\ a\ valid\ network\ cidr = {0} is not a valid network cidr +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1444 +# args: msg.getServerGroupUuid(),msg.getlistenerUuid() +could\ not\ add\ server\ group[uuid\:%s}\ to\ listener\ [uuid\:%s]\ because\ it\ is\ already\ added\ = could not add server group[uuid:{0}} to listener [uuid:{1}] because it is already added -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:214 -# args: msg.getGateway() -%s\ is\ not\ a\ valid\ ipv6\ address = {0} is not a valid ipv6 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1461 +# args: msg.getServerGroupUuid(),msg.getlistenerUuid(),nicUuid +could\ not\ add\ server\ group[uuid\:%s}\ to\ listener\ [uuid\:%s]\ because\ nic\ [uuid\:%s]\ is\ already\ added = could not add server group[uuid:{0}} to listener [uuid:{1}] because nic [uuid:{2}] is already added -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:218 -# args: msg.getStartIp(),msg.getEndIp(),msg.getPrefixLen(),msg.getGateway() -[startIp\ %s,\ endIp\ %s,\ prefixLen\ %d,\ gateway\ %s]\ is\ not\ a\ valid\ ipv6\ range = [startIp {0}, endIp {1}, prefixLen {2}, gateway {3}] is not a valid ipv6 range +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1476 +# args: msg.getServerGroupUuid(),msg.getlistenerUuid(),ipAddress +could\ not\ add\ server\ group[uuid\:%s}\ to\ listener\ [uuid\:%s]\ because\ server\ ip\ [%s]\ is\ already\ added = could not add server group[uuid:{0}} to listener [uuid:{1}] because server ip [{2}] is already added -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:228 -# args: IPv6Constants.IPV6_PREFIX_LEN_MIN,IPv6Constants.IPV6_PREFIX_LEN_MAX -ip\ range\ prefix\ length\ is\ out\ of\ range\ [%d\ -\ %d]\ = ip range prefix length is out of range [{0} - {1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1496 +# args: msg.getServerGroupUuid(),msg.getListenerUuid() +could\ not\ remove\ server\ group[uuid\:%s}\ from\ listener\ [uuid\:%s]\ because\ it\ is\ not\ added = could not remove server group[uuid:{0}} from listener [uuid:{1}] because it is not added -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:234 -# args: l3Vo.getUuid(),l3Vo.getName() -l3\ network\ [uuid\ %s\:\ name\ %s]\ is\ not\ a\ ipv6\ network = l3 network [uuid {0}: name {1}] is not a ipv6 network +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1511 +# args: loadBalancerUuid +loadbalacerUuid\ [%s]\ is\ non-existent = loadbalacerUuid [{0}] is non-existent -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:240 -# args: ipr.getAddressMode(),rangeVOS.get(0).getAddressMode() -addressMode[%s]\ is\ different\ from\ L3Netowork\ address\ mode[%s] = addressMode[{0}] is different from L3Netowork address mode[{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1526 +# args: msg.getServerGroupUuid() +could\ not\ find\ loadBalancer\ with\ serverGroup\ [uuid\:%s] = could not find loadBalancer with serverGroup [uuid:{0}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:246 -# args: IPv6Constants.IPV6_STATELESS_PREFIX_LEN -ipv6\ prefix\ length\ must\ be\ %d\ for\ Stateless-DHCP\ or\ SLAAC = ipv6 prefix length must be {0} for Stateless-DHCP or SLAAC +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1567 +# args: msg.getServerGroupUuid() +could\ not\ update\ backend\ server\ vmnic\ of\ serverGroup[uuid\:%s],because\ vmnic\ uuid\ is\ null = could not update backend server vmnic of serverGroup[uuid:{0}],because vmnic uuid is null -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:256 -# args: ipr.getStartIp(),ipr.getEndIp(),r.getStartIp(),r.getEndIp() -new\ ip\ range\ [startip\ \:%s,\ endip\ \:%s]\ is\ overlaped\ with\ old\ ip\ range[startip\ \:%s,\ endip\ \:%s] = new ip range [startip :{0}, endip :{1}] is overlaped with old ip range[startip :{2}, endip :{3}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1542 +# args: msg.getServerGroupUuid(),vmNic.containsKey("uuid") +could\ not\ update\ backend\ server\ vmnic\ of\ serverGroup,because\ serverGroup[uuid\:%s]\ don\ not\ have\ vmnic\ [uuid\:%s]\ = could not update backend server vmnic of serverGroup,because serverGroup[uuid:{0}] don not have vmnic [uuid:{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:266 -# args: r.getNetworkCidr(),ipr.getNetworkCidr() -new\ network\ CIDR\ [%s]\ is\ different\ from\ old\ network\ cidr\ [%s] = new network CIDR [{0}] is different from old network cidr [{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1564 +# args: vmNic.get("uuid") +invalid\ balancer\ weight[vimNic\:%s],\ weight\ is\ null = invalid balancer weight[vimNic:{0}], weight is null -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:468 -# args: ipr.getGateway(),r.getGateway() -new\ add\ ip\ range\ gateway\ %s\ is\ different\ from\ old\ gateway\ %s = new add ip range gateway {0} is different from old gateway {1} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1559 +# args: vmNic.get("weight") +could\ not\ change\ backend\ server\ vmnic\ to\ serverGroup[uuid\:%s]\ ,because\ vmnic\ weight[%s]\ not\ a\ correct\ number = could not change backend server vmnic to serverGroup[uuid:{0}] ,because vmnic weight[{1}] not a correct number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:286 -# args: msg.getNetworkCidr() -%s\ is\ not\ an\ allowed\ network\ cidr,\ because\ it\ doesn't\ have\ usable\ ip\ range = {0} is not an allowed network cidr, because it doesn't have usable ip range +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1583 +# args: msg.getServerGroupUuid(),ipAddress +could\ not\ update\ backend\ server\ ip\ of\ serverGroup,because\ serverGroup[uuid\:%s]\ don\ not\ have\ ip\ [ipAddress\:%s]\ = could not update backend server ip of serverGroup,because serverGroup[uuid:{0}] don not have ip [ipAddress:{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:290 -# args: msg.getGateway(),msg.getNetworkCidr() -%s\ is\ not\ the\ first\ or\ last\ address\ of\ the\ cidr\ %s = {0} is not the first or last address of the cidr {1} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1602 +# args: server.get("ipAddress") +invalid\ balancer\ weight[serverIp\:%s],\ weight\ is\ null = invalid balancer weight[serverIp:{0}], weight is null + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1592 +# args: server.get("ipAddress"),serverIpWeight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight[serverIp\:%s,weight\:%s],\ weight\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid balancer weight[serverIp:{0},weight:{1}], weight is not in the range [{2}, {3}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:313 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1618 # args: -ipRangeUuids,\ L3NetworkUuids,\ zoneUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = ipRangeUuids, L3NetworkUuids, zoneUuids must have at least one be none-empty list, or all is set to true +could\ not\ change\ backendserver,\ beacause\ vmincs\ and\ serverips\ is\ null = could not change backendserver, beacause vmincs and serverips is null -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:334 -# args: msg.getType() -unsupported\ l3network\ type[%s] = unsupported l3network type[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1355 +# args: struct.listenerUuid +can\ not\ get\ service\ providerType\ for\ load\ balancer\ listener\ [uuid\:%s] = can not get service providerType for load balancer listener [uuid:{0}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:340 -# args: msg.getDnsDomain() -%s\ is\ not\ a\ valid\ domain\ name = {0} is not a valid domain name +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1384 +# args: self.getUuid(),self.getProviderType(),providerType +service\ provider\ type\ mismatching.\ The\ load\ balancer[uuid\:%s]\ is\ provided\ by\ the\ service\ provider[type\:%s],\ but\ new\ service\ provider\ is\ [type\:\ %s] = service provider type mismatching. The load balancer[uuid:{0}] is provided by the service provider[type:{1}], but new service provider is [type: {2}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:382 -# args: l3Vo.getUuid(),l3Vo.getName() -l3\ network\ [uuid\ %s\:\ name\ %s]\ is\ not\ a\ ipv4\ network = l3 network [uuid {0}: name {1}] is not a ipv4 network +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1486 +# args: msg.getLoadBalancerPort(),msg.getLoadBalancerUuid() +there\ is\ listener\ with\ same\ port\ [%s]\ and\ same\ load\ balancer\ [uuid\:%s] = there is listener with same port [{0}] and same load balancer [uuid:{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:386 -# args: ipr.getStartIp(),ipr.getEndIp() -the\ IP\ range[%s\ ~\ %s]\ contains\ D\ class\ addresses\ which\ are\ for\ multicast = the IP range[{0} ~ {1}] contains D class addresses which are for multicast +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:2011 +# args: param +invalid\ health\ checking\ parameters[%s],\ the\ format\ is\ method\:URI\:code,\ for\ example,\ GET\:/index.html\:http_2xx = invalid health checking parameters[{0}], the format is method:URI:code, for example, GET:/index.html:http_2xx -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:390 -# args: ipr.getStartIp(),ipr.getEndIp() -the\ IP\ range[%s\ ~\ %s]\ contains\ E\ class\ addresses\ which\ are\ reserved = the IP range[{0} ~ {1}] contains E class addresses which are reserved +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:699 +# args: systemTag +invalid\ health\ target[%s],\ the\ format\ is\ targetCheckProtocol\:port,\ for\ example,\ tcp\:default = invalid health target[{0}], the format is targetCheckProtocol:port, for example, tcp:default -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:394 -# args: ipr.getStartIp(),ipr.getEndIp() -the\ IP\ range[%s\ ~\ %s]\ contains\ link\ local\ addresses\ which\ are\ reserved = the IP range[{0} ~ {1}] contains link local addresses which are reserved +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:100 +# args: msg.getLoadBalancerUuid() +cannot\ find\ the\ load\ balancer[uuid\:%s] = cannot find the load balancer[uuid:{0}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:400 -# args: ipr.getGateway(),ipr.getStartIp(),ipr.getNetmask() -the\ gateway[%s]\ is\ not\ in\ the\ subnet\ %s/%s = the gateway[{0}] is not in the subnet {1}/{2} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:483 +# args: tag.getTag() +cannot\ delete\ the\ system\ tag[%s].\ The\ load\ balancer\ plugin\ relies\ on\ it,\ you\ can\ only\ update\ it = cannot delete the system tag[{0}]. The load balancer plugin relies on it, you can only update it -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:404 -# args: ipr.getEndIp(),ipr.getStartIp(),ipr.getNetmask() -the\ endip[%s]\ is\ not\ in\ the\ subnet\ %s/%s = the endip[{0}] is not in the subnet {1}/{2} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:502 +# args: nicUuid,systemTag +nic[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ loadbalancer = nic[uuid:{0}] not found. Please correct your system tag[{1}] of loadbalancer -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:408 -# args: ipr.getStartIp() -start\ ip[%s]\ is\ not\ a\ IPv4\ address = start ip[{0}] is not a IPv4 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:514 +# args: systemTag,s +invalid\ balancer\ weight[%s],\ %s\ is\ not\ a\ number = invalid balancer weight[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:412 -# args: ipr.getEndIp() -end\ ip[%s]\ is\ not\ a\ IPv4\ address = end ip[{0}] is not a IPv4 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:510 +# args: systemTag,s,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight[%s],\ %s\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid balancer weight[{0}], {1} is not in the range [{2}, {3}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:416 -# args: ipr.getGateway() -gateway[%s]\ is\ not\ a\ IPv4\ address = gateway[{0}] is not a IPv4 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:526 +# args: algorithm,LoadBalancerConstants.BALANCE_ALGORITHMS +invalid\ balance\ algorithm[%s],\ valid\ algorithms\ are\ %s = invalid balance algorithm[{0}], valid algorithms are {1} -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:420 -# args: ipr.getNetmask() -netmask[%s]\ is\ not\ a\ netmask,\ and\ the\ IP\ range\ netmask\ cannot\ be\ 0.0.0.0 = netmask[{0}] is not a netmask, and the IP range netmask cannot be 0.0.0.0 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:602 +# args: systemTag,s +invalid\ unhealthy\ threshold[%s],\ %s\ is\ not\ a\ number = invalid unhealthy threshold[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:424 -# args: -ip\ allocation\ can\ not\ contain\ network\ address\ or\ broadcast\ address = ip allocation can not contain network address or broadcast address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:616 +# args: systemTag,s +invalid\ healthy\ threshold[%s],\ %s\ is\ not\ a\ number = invalid healthy threshold[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:432 -# args: ipr.getStartIp(),ipr.getEndIp() -start\ ip[%s]\ is\ behind\ end\ ip[%s] = start ip[{0}] is behind end ip[{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:630 +# args: systemTag,s +invalid\ healthy\ timeout[%s],\ %s\ is\ not\ a\ number = invalid healthy timeout[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:437 -# args: ipr.getGateway(),ipr.getStartIp(),ipr.getEndIp() -gateway[%s]\ can\ not\ be\ part\ of\ range[%s,\ %s] = gateway[{0}] can not be part of range[{1}, {2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:644 +# args: systemTag,s +invalid\ connection\ idle\ timeout[%s],\ %s\ is\ not\ a\ number = invalid connection idle timeout[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:448 -# args: r.getUuid(),r.getStartIp(),r.getEndIp() -overlap\ with\ ip\ range[uuid\:%s,\ start\ ip\:%s,\ end\ ip\:\ %s] = overlap with ip range[uuid:{0}, start ip:{1}, end ip: {2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:658 +# args: systemTag,s +invalid\ health\ check\ interval[%s],\ %s\ is\ not\ a\ number = invalid health check interval[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:458 -# args: r.getUuid(),rcidr,cidr -multiple\ CIDR\ on\ the\ same\ L3\ network\ is\ not\ allowed.\ There\ has\ been\ a\ IP\ range[uuid\:%s,\ CIDR\:%s],\ the\ new\ IP\ range[CIDR\:%s]\ is\ not\ in\ the\ CIDR\ with\ the\ existing\ one = multiple CIDR on the same L3 network is not allowed. There has been a IP range[uuid:{0}, CIDR:{1}], the new IP range[CIDR:{2}] is not in the CIDR with the existing one +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:672 +# args: systemTag,s +invalid\ max\ connection[%s],\ %s\ is\ not\ a\ number = invalid max connection[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:490 -# args: manner,ip -%s[%s]\ is\ not\ a\ IPv6\ address = {0}[{1}] is not a IPv6 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:686 +# args: systemTag,s +invalid\ process\ number[%s],\ %s\ is\ not\ a\ number = invalid process number[{0}], {1} is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:486 -# args: manner,ip -%s[%s]\ is\ not\ a\ IPv4\ address = {0}[{1}] is not a IPv4 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:704 +# args: systemTag,protocol,LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCOLS +invalid\ health\ target[%s],\ the\ target\ checking\ protocol[%s]\ is\ invalid,\ valid\ protocols\ are\ %s = invalid health target[{0}], the target checking protocol[{1}] is invalid, valid protocols are {2} -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:502 -# args: msg.getDns(),msg.getL3NetworkUuid() -there\ has\ been\ a\ DNS[%s]\ on\ L3\ network[uuid\:%s] = there has been a DNS[{0}] on L3 network[uuid:{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:716 +# args: systemTag,port +invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ a\ number = invalid invalid health target[{0}], port[{1}] is not a number -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:525 -# args: msg.getL3NetworkUuid() -prefix\ [%s]\ is\ not\ a\ IPv4\ network\ cidr = prefix [{0}] is not a IPv4 network cidr +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:713 +# args: systemTag,port +invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ in\ the\ range\ of\ [1,\ 65535] = invalid invalid health target[{0}], port[{1}] is not in the range of [1, 65535] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:512 -# args: msg.getNexthop() -nexthop[%s]\ is\ not\ a\ IPv4\ address = nexthop[{0}] is not a IPv4 address +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java:89 +# args: nicUuid,weight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight\ for\ nic\:%s,\ %d\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid balancer weight for nic:{0}, {1} is not in the range [{2}, {3}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:519 -# args: msg.getPrefix(),msg.getL3NetworkUuid() -there\ has\ been\ a\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = there has been a hostroute for prefix[{0}] on L3 network[uuid:{1}] +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:226 +# args: msg.getVmNicUuid(),msg.getVipUuid() +guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ vip[uuid\:\ %s]\ are\ the\ same\ network = guest l3Network of vm nic[uuid:{0}] and vip l3Network of vip[uuid: {1}] are the same network -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:532 -# args: msg.getPrefix(),msg.getL3NetworkUuid() -there\ is\ no\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = there is no hostroute for prefix[{0}] on L3 network[uuid:{1}] +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:201 +# args: msg.getVipUuid(),useForList.toString() +the\ vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = the vip[uuid:{0}] has been occupied other network service entity[{1}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:171 -# args: wrongUuids,securityGroupUuid -VM\ nics[uuids\:%s]\ are\ not\ on\ L3\ networks\ that\ have\ been\ attached\ to\ the\ security\ group[uuid\:%s] = VM nics[uuids:{0}] are not on L3 networks that have been attached to the security group[uuid:{1}] +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:68 +# args: msg.getRuleUuid(),state +Port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ current\ state\ is\ %s = Port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1} -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:69 -# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() -security\ group[uuid\:%s]\ has\ not\ attached\ to\ l3Network[uuid\:%s],\ can't\ detach = security group[uuid:{0}] has not attached to l3Network[uuid:{1}], can't detach +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:83 +# args: msg.getUuid() +port\ forwarding\ rule\ rule[uuid\:%s]\ has\ not\ been\ attached\ to\ any\ vm\ nic,\ can't\ detach = port forwarding rule rule[uuid:{0}] has not been attached to any vm nic, can't detach -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:117 -# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() -security\ group[uuid\:%s]\ has\ attached\ to\ l3Network[uuid\:%s],\ can't\ attach\ again = security group[uuid:{0}] has attached to l3Network[uuid:{1}], can't attach again +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:99 +# args: msg.getRuleUuid(),vmNicUuid +port\ forwarding\ rule[uuid\:%s]\ has\ been\ attached\ to\ vm\ nic[uuid\:%s],\ can't\ attach\ again = port forwarding rule[uuid:{0}] has been attached to vm nic[uuid:{1}], can't attach again -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:125 -# args: msg.getL3NetworkUuid(),SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE -the\ L3\ network[uuid\:%s]\ doesn't\ have\ the\ network\ service\ type[%s]\ enabled = the L3 network[uuid:{0}] doesn't have the network service type[{1}] enabled +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:104 +# args: msg.getRuleUuid(),state +port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ \ current\ state\ is\ %s.\ A\ rule\ can\ only\ be\ attached\ when\ its\ state\ is\ Enabled = port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1}. A rule can only be attached when its state is Enabled -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:131 -# args: msg.getL3NetworkUuid(),l3Vo.getIpVersion(),msg.getSecurityGroupUuid(),sgVo.getIpVersion() -the\ L3\ network[uuid\:%s]\ ipVersion\ [%d]\ is\ different\ from\ securityGroup\ [uuid\:%s]\ ipVersion\ [%d] = the L3 network[uuid:{0}] ipVersion [{1}] is different from securityGroup [uuid:{2}] ipVersion [{3}] +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:123 +# args: msg.getVmNicUuid(),msg.getRuleUuid() +guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ port\ forwarding\ rule[uuid\:%s]\ are\ the\ same\ network = guest l3Network of vm nic[uuid:{0}] and vip l3Network of port forwarding rule[uuid:{1}] are the same network -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:214 -# args: JSONObjectUtil.toJsonString(ao) -rule\ type\ can\ not\ be\ null.\ rule\ dump\:\ %s = rule type can not be null. rule dump: {0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:167 +# args: msg.getVipPortStart(),msg.getVipPortEnd(),msg.getPrivatePortStart(),msg.getPrivatePortEnd() +could\ not\ create\ port\ forwarding\ rule,\ because\ vip\ port\ range[vipStartPort\:%s,\ vipEndPort\:%s]\ is\ incompatible\ with\ private\ port\ range[privateStartPort\:%s,\ privateEndPort\:%s] = could not create port forwarding rule, because vip port range[vipStartPort:{0}, vipEndPort:{1}] is incompatible with private port range[privateStartPort:{2}, privateEndPort:{3}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:219 -# args: ao.getType(),JSONObjectUtil.toJsonString(ao) -unknown\ rule\ type[%s],\ rule\ can\ only\ be\ Ingress/Egress.\ rule\ dump\:\ %s = unknown rule type[{0}], rule can only be Ingress/Egress. rule dump: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:184 +# args: msg.getVipPortStart(),msg.getVipPortEnd(),msg.getPrivatePortStart(),msg.getPrivatePortEnd() +for\ range\ port\ forwarding,\ the\ port\ range\ size\ must\ match;\ vip\ range[%s,\ %s]'s\ size\ doesn't\ match\ range[%s,\ %s]'s\ size = for range port forwarding, the port range size must match; vip range[{0}, {1}]'s size doesn't match range[{2}, {3}]'s size -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:225 -# args: JSONObjectUtil.toJsonString(ao) -protocol\ can\ not\ be\ null.\ rule\ dump\:\ %s = protocol can not be null. rule dump: {0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:193 +# args: msg.getAllowedCidr() +invalid\ CIDR[%s],\ only\ ipv4\ is\ supported = invalid CIDR[{0}], only ipv4 is supported -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:231 -# args: ao.getProtocol(),JSONObjectUtil.toJsonString(ao) -invalid\ protocol[%s].\ Valid\ protocols\ are\ [TCP,\ UDP,\ ICMP,\ ALL].\ rule\ dump\:\ %s = invalid protocol[{0}]. Valid protocols are [TCP, UDP, ICMP, ALL]. rule dump: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:191 +# args: msg.getAllowedCidr() +invalid\ CIDR[%s] = invalid CIDR[{0}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:238 -# args: JSONObjectUtil.toJsonString(ao) -can\ not\ set\ port\ for\ protocol\ [type\:ALL].\ rule\ dump\:\ %s = can not set port for protocol [type:ALL]. rule dump: {0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:211 +# args: vipStart,vipEnd,vo.getUuid(),vo.getVipPortStart(),vo.getVipPortEnd() +vip\ port\ range[vipStartPort\:%s,\ vipEndPort\:%s]\ overlaps\ with\ rule[uuid\:%s,\ vipStartPort\:%s,\ vipEndPort\:%s] = vip port range[vipStartPort:{0}, vipEndPort:{1}] overlaps with rule[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:236 -# args: JSONObjectUtil.toJsonString(ao) -startPort\ can\ not\ be\ null.\ rule\ dump\:\ %s = startPort can not be null. rule dump: {0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:269 +# args: vm.getName(),vm.getUuid(),vipUuid +the\ VM[name\:%s\ uuid\:%s]\ already\ has\ port\ forwarding\ rules\ that\ have\ different\ VIPs\ than\ the\ one[uuid\:%s] = the VM[name:{0} uuid:{1}] already has port forwarding rules that have different VIPs than the one[uuid:{2}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:250 -# args: ao.getStartPort(),JSONObjectUtil.toJsonString(ao) -invalid\ startPort[%s].\ Valid\ range\ is\ [0,\ 65535].\ rule\ dump\:\ %s = invalid startPort[{0}]. Valid range is [0, 65535]. rule dump: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:282 +# args: vmNicUuid +vmNic\ uuid[%s]\ is\ not\ allowed\ add\ portForwarding\ with\ allowedCidr\ rule,\ because\ vmNic\ exist\ eip = vmNic uuid[{0}] is not allowed add portForwarding with allowedCidr rule, because vmNic exist eip -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:243 -# args: ao.getStartPort(),JSONObjectUtil.toJsonString(ao) -invalid\ ICMP\ type[%s].\ Valid\ type\ is\ [-1,\ 255].\ rule\ dump\:\ %s = invalid ICMP type[{0}]. Valid type is [-1, 255]. rule dump: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:316 +# args: vmNicUuid,privatePortStart,privatePortEnd,protocolType +could\ not\ attach\ port\ forwarding\ rule,\ because\ vmNic[uuid\:%s]\ already\ has\ a\ rule\ that\ overlaps\ the\ target\ private\ port\ ranges[%s,\ %s],\ has\ the\ same\ protocol\ type[%s]\ and\ has\ AllowedCidr = could not attach port forwarding rule, because vmNic[uuid:{0}] already has a rule that overlaps the target private port ranges[{1}, {2}], has the same protocol type[{3}] and has AllowedCidr -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:269 -# args: ao.getEndPort(),JSONObjectUtil.toJsonString(ao) -invalid\ endPort[%s].\ Valid\ range\ is\ [0,\ 65535].\ rule\ dump\:\ %s = invalid endPort[{0}]. Valid range is [0, 65535]. rule dump: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:306 +# args: vmNicUuid,privatePortStart,privatePortEnd,protocolType +could\ not\ attach\ port\ forwarding\ rule\ with\ allowedCidr,\ because\ vmNic[uuid\:%s]\ already\ has\ rules\ that\ overlap\ the\ target\ private\ port\ ranges[%s,\ %s]\ and\ have\ the\ same\ protocol\ type[%s] = could not attach port forwarding rule with allowedCidr, because vmNic[uuid:{0}] already has rules that overlap the target private port ranges[{1}, {2}] and have the same protocol type[{3}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:262 -# args: ao.getEndPort(),JSONObjectUtil.toJsonString(ao) -invalid\ ICMP\ code[%s].\ Valid\ range\ is\ [-1,\ 3].\ rule\ dump\:\ %s = invalid ICMP code[{0}]. Valid range is [-1, 3]. rule dump: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java:1222 +# args: struct.getRule().getUuid() +port\ forwarding\ rule\ [uuid\:%s]\ is\ deleted = port forwarding rule [uuid:{0}] is deleted -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:279 -# args: ao.getAllowedCidr(),JSONObjectUtil.toJsonString(ao) -invalid\ CIDR[%s].\ rule\ dump\:\ %s = invalid CIDR[{0}]. rule dump: {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:375 +# args: msg.getServerGroupUuid() +could\ not\ add\ backend\ server\ vmnic\ to\ serverGroup[uuid\:%s],because\ vmnic\ uuid\ is\ null = could not add backend server vmnic to serverGroup[uuid:{0}],because vmnic uuid is null -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:283 -# args: sgVo.getIpVersion(),ao.getIpVersion() -security\ group\ rule\ ipVersion\ [%d]\ is\ different\ from\ security\ group\ version\ [%d] = security group rule ipVersion [{0}] is different from security group version [{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:88 +# args: msg.getSlbGroupUuid() +could\ not\ create\ slb\ instance\ because\ there\ is\ no\ load\ balancer\ slb\ group\ [uuid\:%s] = could not create slb instance because there is no load balancer slb group [uuid:{0}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:292 -# args: JSONObjectUtil.toJsonString(msg.getRules().get(j)) -rule\ should\ not\ be\ duplicated.\ rule\ dump\:\ %s = rule should not be duplicated. rule dump: {0} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:93 +# args: msg.getSlbGroupUuid() +could\ not\ create\ slb\ instance\ because\ there\ is\ no\ slb\ offering\ configured\ for\ slb\ group\ [uuid\:%s] = could not create slb instance because there is no slb offering configured for slb group [uuid:{0}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:318 -# args: JSONObjectUtil.toJsonString(sao),svo.getRemoteSecurityGroupUuid() -rule\ exist.\ rule\ dump\:\ %s,\ remoteSecurityGroupUuid\:[%s] = rule exist. rule dump: {0}, remoteSecurityGroupUuid:[{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:99 +# args: msg.getSlbGroupUuid() +could\ not\ create\ slb\ instance\ because\ image\ uuid\ of\ slb\ offering\ [uuid\:%s]\ is\ null = could not create slb instance because image uuid of slb offering [uuid:{0}] is null -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:345 -# args: rsgVo.getIpVersion(),sgVo.getIpVersion() -remote\ security\ group\ ipVersion\ [%d]\ is\ different\ from\ security\ group\ version\ [%d] = remote security group ipVersion [{0}] is different from security group version [{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:104 +# args: slbOfferingVO.getImageUuid() +could\ not\ create\ slb\ instance\ because\ image\ [uuid\:%s]\ is\ deleted = could not create slb instance because image [uuid:{0}] is deleted -# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:88 -# args: msg.getL3NetworkUuid() -L3Network\ [uuid\:\ %s]\ provide\ type\ null = L3Network [uuid: {0}] provide type null +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:112 +# args: frontL3.getCategory() +could\ not\ create\ slb\ group\ because\ invalid\ front\ l3\ network\ type\ %s = could not create slb group because invalid front l3 network type {0} -# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:113 -# args: msg.getL3NetworkUuid() -L3Network\ [uuid\:\ %s]\ does\ not\ have\ host\ route\ service = L3Network [uuid: {0}] does not have host route service +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:127 +# args: +could\ not\ create\ slb\ group,\ because\ front\ network\ doesn't\ support\ ipv6\ yet = could not create slb group, because front network doesn't support ipv6 yet -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:41 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:142 # args: -networkServices\ cannot\ be\ empty = networkServices cannot be empty +could\ not\ create\ slb\ group,\ because\ backend\ network\ doesn't\ support\ ipv6\ yet = could not create slb group, because backend network doesn't support ipv6 yet -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:62 -# args: puuid -network\ service\ for\ provider[uuid\:%s]\ must\ be\ specified = network service for provider[uuid:{0}] must be specified +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:143 +# args: msg.getResourceUuid() +could\ not\ change\ resource\ owner,\ because\ the\ resource[uuid\:%s,\ type\:VmInstance]\ has\ already\ attached\ security\ group = could not change resource owner, because the resource[uuid:{0}, type:VmInstance] has already attached security group -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:67 -# args: puuid -cannot\ find\ network\ service\ provider[uuid\:%s]\ or\ it\ provides\ no\ services = cannot find network service provider[uuid:{0}] or it provides no services +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:250 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ vm\ nic[uuid\:%s]\ not\ found = could no set vm nic security group, because vm nic[uuid:{0}] not found -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:81 -# args: puuid,notSupported -network\ service\ provider[uuid\:%s]\ doesn't\ provide\ services%s = network service provider[uuid:{0}] doesn't provide services{1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:256 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ the\ vm\ nic[uuid\:%s]\ not\ attached\ to\ any\ security\ group = could no set vm nic security group, because the vm nic[uuid:{0}] not attached to any security group -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:93 -# args: type,msg.getL3NetworkUuid() -there\ has\ been\ a\ network\ service[%s]\ attached\ to\ L3\ network[uuid\:%s] = there has been a network service[{0}] attached to L3 network[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:266 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ security\ group[uuid\:%s]\ not\ found = could no set vm nic security group, because security group[uuid:{0}] not found -# at: src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java:342 -# args: l3NetworkUuid,serviceType -L3Network[uuid\:%s]\ doesn't\ have\ network\ service[type\:%s]\ enabled\ or\ no\ provider\ provides\ this\ network\ service = L3Network[uuid:{0}] doesn't have network service[type:{1}] enabled or no provider provides this network service +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:271 +# args: priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ cannot\ be\ less\ than\ 1 = could no set vm nic security group, because invalid priority, priority[{0}] cannot be less than 1 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:82 -# args: -either\ eipUuid\ or\ vipUuid\ must\ be\ set = either eipUuid or vipUuid must be set +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:275 +# args: aoMap.get(priority),ao.getSecurityGroupUuid(),priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ priority,\ both\ security\ group\ %s\ and\ %s\ have\ priority[%d] = could no set vm nic security group, because duplicate priority, both security group {0} and {1} have priority[{2}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:88 -# args: msg.getEipUuid() -eip[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ cannot\ get\ attachable\ vm\ nic = eip[uuid:{0}] is not in state of Enabled, cannot get attachable vm nic +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:278 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ security\ group[uuid\:%s] = could no set vm nic security group, because duplicate security group[uuid:{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:103 -# args: guestIpUuid,vmNicUuid -ip\ [uuid\:%s]\ is\ attached\ to\ vm\ nic\ [%s] = ip [uuid:{0}] is attached to vm nic [{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:288 +# args: ao.getSecurityGroupUuid(),vmAccountUuid +could\ no\ set\ vm\ nic\ security\ group,\ because\ security\ group[uuid\:%s]\ is\ not\ owned\ by\ account[uuid\:%s]\ or\ admin = could no set vm nic security group, because security group[uuid:{0}] is not owned by account[uuid:{1}] or admin -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:114 -# args: msg.getEipUuid(),vmNicUuid -eip[uuid\:%s]\ has\ attached\ to\ another\ vm\ nic[uuid\:%s],\ can't\ attach\ again = eip[uuid:{0}] has attached to another vm nic[uuid:{1}], can't attach again +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:298 +# args: priorities[0] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority\ expects\ to\ start\ at\ 1,\ but\ [%d] = could no set vm nic security group, because invalid priority, priority expects to start at 1, but [{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:120 -# args: msg.getEipUuid(),EipState.Enabled,state -eip[uuid\:\ %s]\ can\ only\ be\ attached\ when\ state\ is\ %s,\ current\ state\ is\ %s = eip[uuid: {0}] can only be attached when state is {1}, current state is {2} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:302 +# args: priorities[i],priorities[i + 1] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ and\ priority[%d]\ expected\ to\ be\ consecutive = could no set vm nic security group, because invalid priority, priority[{0}] and priority[{1}] expected to be consecutive -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:150 -# args: msg.getVmNicUuid(),msg.getEipUuid() -guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ EIP[uuid\:%s]\ are\ the\ same\ network = guest l3Network of vm nic[uuid:{0}] and vip l3Network of EIP[uuid:{1}] are the same network +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:348 +# args: priorities[i + 1] +could\ no\ set\ vm\ nic\ security\ group,\ because\ admin\ security\ group\ priority[%d]\ must\ be\ higher\ than\ users = could no set vm nic security group, because admin security group priority[{0}] must be higher than users -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:167 -# args: msg.getEipUuid(),msg.getVmNicUuid() -Ip\ address\ [uuid\:%s]\ is\ not\ belonged\ to\ nic\ [uuid\:%s] = Ip address [uuid:{0}] is not belonged to nic [uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:357 +# args: +could\ no\ change\ security\ group\ rule\ state,\ because\ ruleUuids\ is\ empty = could no change security group rule state, because ruleUuids is empty -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:180 -# args: msg.getUuid() -eip[uuid\:%s]\ has\ not\ attached\ to\ any\ vm\ nic = eip[uuid:{0}] has not attached to any vm nic +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:361 +# args: msg.getSecurityGroupUuid() +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group[uuid\:%s]\ not\ found = could no change security group rule state, because security group[uuid:{0}] not found -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:203 -# args: vipIp.getIpVersion(),guestIp.getIpVersion() -vip\ ipVersion\ [%d]\ is\ different\ from\ guestIp\ ipVersion\ [%d]. = vip ipVersion [{0}] is different from guestIp ipVersion [{1}]. +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:369 +# args: r +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group\ rule[uuid\:%s]\ not\ found = could no change security group rule state, because security group rule[uuid:{0}] not found -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:210 -# args: vipIp.getIp(),guestRange.getStartIp(),guestRange.getEndIp() -Vip[%s]\ is\ in\ the\ guest\ ip\ range\ [%s,\ %s] = Vip[{0}] is in the guest ip range [{1}, {2}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:378 +# args: +could\ no\ change\ security\ group\ rule\ state,\ because\ no\ security\ group\ rule\ state\ need\ to\ change = could no change security group rule state, because no security group rule state need to change -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:230 -# args: vmUuid,vip.getL3NetworkUuid(),vip.getUuid(),vip.getName(),vip.getIp() -the\ vm[uuid\:%s]\ that\ the\ EIP\ is\ about\ to\ attach\ is\ already\ on\ the\ public\ network[uuid\:%s]\ from\ which\ the\ vip[uuid\:%s,\ name\:%s,\ ip\:%s]\ comes = the vm[uuid:{0}] that the EIP is about to attach is already on the public network[uuid:{1}] from which the vip[uuid:{2}, name:{3}, ip:{4}] comes +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:386 +# args: +could\ no\ change\ vm\ nic\ security\ policy,\ because\ ingress\ policy\ and\ egress\ policy\ cannot\ be\ both\ null = could no change vm nic security policy, because ingress policy and egress policy cannot be both null -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:241 -# args: msg.getVipUuid(),useForList.toString() -vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = vip[uuid:{0}] has been occupied other network service entity[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:389 +# args: msg.getIngressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ ingress\ policy[%s] = could no change vm nic security policy, because invalid ingress policy[{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:246 -# args: msg.getVipUuid(),VipState.Enabled,vip.getState() -vip[uuid\:%s]\ is\ not\ in\ state[%s],\ current\ state\ is\ %s = vip[uuid:{0}] is not in state[{1}], current state is {2} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:393 +# args: msg.getEgressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ egress\ policy[%s] = could no change vm nic security policy, because invalid egress policy[{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:281 -# args: state.toString() -vm\ state[%s]\ is\ not\ allowed\ to\ operate\ eip,\ maybe\ you\ should\ wait\ the\ vm\ process\ complete = vm state[{0}] is not allowed to operate eip, maybe you should wait the vm process complete +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:397 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ not\ found = could no change vm nic security policy, because vm nic[uuid:{0}] not found -# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:944 -# args: eip.getGuestIp(),nicIps -cannot\ find\ Eip\ guest\ ip\:\ %s\ in\ vmNic\ ips\ \:%s = cannot find Eip guest ip: {0} in vmNic ips :{1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:402 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ has\ no\ security\ policy = could no change vm nic security policy, because vm nic[uuid:{0}] has no security policy -# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1305 -# args: l3.getUuid(),l3.getName(),vm.getUuid(),vm.getName() -unable\ to\ attach\ the\ L3\ network[uuid\:%s,\ name\:%s]\ to\ the\ vm[uuid\:%s,\ name\:%s],\ because\ the\ L3\ network\ is\ providing\ EIP\ to\ one\ of\ the\ vm's\ nic = unable to attach the L3 network[uuid:{0}, name:{1}] to the vm[uuid:{2}, name:{3}], because the L3 network is providing EIP to one of the vm's nic +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:416 +# args: msg.getType() +could\ not\ update\ security\ group\ rule\ priority,\ because\ invalid\ type[%s] = could not update security group rule priority, because invalid type[{0}] -# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:39 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:421 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ is\ not\ exist = could not update security group rule priority, because security group[uuid:{0}] is not exist + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:425 # args: -Session/account\ uuid\ is\ not\ valid. = Session/account uuid is not valid. +could\ not\ update\ security\ group\ rule\ priority,\ because\ rules\ is\ empty = could not update security group rule priority, because rules is empty -# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:43 -# args: accountUuid,msg.getL3NetworkUuid() -the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resource[uuid\:%s,\ type\:L3NetworkVO] = the account[uuid:{0}] has no access to the resource[uuid:{1}, type:L3NetworkVO] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:435 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ rules\ size\ not\ match = could not update security group rule priority, because security group[uuid:{0}] rules size not match + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:440 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ priority[%d]\ is\ invalid = could not update security group rule priority, because rule priority[{0}] is invalid + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:443 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ has\ duplicate = could not update security group rule priority, because priority[{0}] has duplicate + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:449 +# args: ao.getRuleUuid(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule[uuid\:%s]\ not\ in\ security\ group[uuid\:%s] = could not update security group rule priority, because rule[uuid:{0}] not in security group[uuid:{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:452 +# args: ao.getPriority(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ not\ in\ security\ group[uuid\:%s] = could not update security group rule priority, because priority[{0}] not in security group[uuid:{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:712 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:457 # args: -l3\ network\ uuid\ cannot\ be\ null = l3 network uuid cannot be null +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ uuid\ duplicate = could not update security group rule priority, because rule uuid duplicate -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:728 -# args: msg.getL3NetworkUuid() -Cannot\ find\ DhcpIp\ for\ l3\ network[uuid\:%s] = Cannot find DhcpIp for l3 network[uuid:{0}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:464 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule\ uuid[%s]\ is\ not\ exist = could not change security group rule, because security group rule uuid[{0}] is not exist -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:823 -# args: msg.getL3NetworkUuid() -L3\ network[uuid\:%s]\ does\ not\ have\ any\ iprange = L3 network[uuid:{0}] does not have any iprange +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:470 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ is\ default\ rule,\ only\ the\ description\ and\ status\ can\ be\ set = could not change security group rule, because security group rule[{0}] is default rule, only the description and status can be set -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1089 -# args: inv.getUuid(),destHostUuid -cannot\ configure\ DHCP\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot configure DHCP for vm[uuid:{0}] on the destination host[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:476 +# args: msg.getUuid(),SecurityGroupConstant.DEFAULT_RULE_PRIORITY +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ priority\ cannot\ be\ set\ to\ default\ rule\ priority[%d] = could not change security group rule, because security group rule[{0}] priority cannot be set to default rule priority[{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1959 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv6\ address = DHCP server ip [{0}] is not a IPv6 address +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:485 +# args: vo.getType(),count.intValue(),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = could not change security group rule, because security group {0} rules number[{1}] is out of max limit[{2}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1955 -# args: dhcpServerIp,inv.getNetworkCidr() -DHCP\ server\ ip\ [%s]\ is\ not\ in\ the\ cidr\ [%s] = DHCP server ip [{0}] is not in the cidr [{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:488 +# args: vo.getType().toString(),count.intValue() +could\ not\ change\ security\ group\ rule,\ because\ the\ maximum\ priority\ of\ %s\ rule\ is\ [%d] = could not change security group rule, because the maximum priority of {0} rule is [{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1951 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv4\ address = DHCP server ip [{0}] is not a IPv4 address +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:497 +# args: msg.getState() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ state[%s] = could not change security group rule, because invalid state[{0}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1970 -# args: IPv6NetworkUtils.ipv6TagValueToAddress(oldDhcpServer),inv.getL3NetworkUuid() -DHCP\ server\ ip\ [%s]\ is\ already\ existed\ in\ l3\ network\ [%s] = DHCP server ip [{0}] is already existed in l3 network [{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:505 +# args: msg.getAction() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ action[%s] = could not change security group rule, because invalid action[{0}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1975 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ can\ not\ be\ equaled\ to\ gateway\ ip = DHCP server ip [{0}] can not be equaled to gateway ip +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:513 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ protocol[%s] = could not change security group rule, because invalid protocol[{0}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1981 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ can\ not\ be\ configured\ to\ system\ l3 = DHCP server ip [{0}] can not be configured to system l3 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:545 +# args: msg.getUuid(),msg.getSrcIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Egress,\ srcIpRange[%s]\ cannot\ be\ set = could not change security group rule, because security group rule[{0}] type is Egress, srcIpRange[{1}] cannot be set -# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:99 -# args: vmNicUuid -L2Network\ where\ vip's\ L3Network\ based\ hasn't\ attached\ the\ cluster\ where\ vmNic[uuid\:%s]\ located = L2Network where vip's L3Network based hasn't attached the cluster where vmNic[uuid:{0}] located +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:542 +# args: msg.getUuid(),msg.getDstIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Ingress,\ dstIpRange[%s]\ cannot\ be\ set = could not change security group rule, because security group rule[{0}] type is Ingress, dstIpRange[{1}] cannot be set -# at: src/main/java/org/zstack/network/service/flat/FlatEipBackend.java:573 -# args: vmUuid,vm.getState() -unable\ to\ apply\ the\ EIP\ operation\ for\ the\ the\ vm[uuid\:%s,\ state\:%s],\ because\ cannot\ find\ the\ VM's\ hostUUid = unable to apply the EIP operation for the the vm[uuid:{0}, state:{1}], because cannot find the VM's hostUUid +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:535 +# args: msg.getSrcIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ srcIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = could not change security group rule, because srcIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty -# at: src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java:353 -# args: struct.getHostUuid() -host[uuid\:%s]\ is\ not\ connected = host[uuid:{0}] is not connected +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:548 +# args: msg.getDstIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ dstIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = could not change security group rule, because dstIpRange[{0}] is set, remoteSecurityGroupUuid[{1}] must be empty -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:672 -# args: target -invalid\ health\ target[%s],\ the\ format\ is\ targetCheckProtocol\:port,\ for\ example,\ tcp\:default = invalid health target[{0}], the format is targetCheckProtocol:port, for example, tcp:default +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:555 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ not\ found = could not change security group rule, because remote security group[uuid:{0}] not found -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:121 -# args: msg.getUuid(),refs -the\ access\ control\ list\ group[%s]\ is\ being\ used\ by\ the\ load\ balancer\ listeners[%s] = the access control list group[{0}] is being used by the load balancer listeners[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:558 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ is\ set,\ srcIpRange\ and\ dstIpRange\ must\ be\ empty = could not change security group rule, because remote security group[uuid:{0}] is set, srcIpRange and dstIpRange must be empty -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:203 -# args: ipVer -operation\ failure,\ not\ support\ the\ ip\ version\ %d = operation failure, not support the ip version {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:611 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ must\ be\ set = could not change security group rule, because rule protocol is [{0}], dstPortRange must be set -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:209 -# args: ips,acl.getUuid() -operation\ failure,\ duplicate/overlap\ ip\ entry\ in\ %s\ of\ accesscontrol\ list\ group\:%s = operation failure, duplicate/overlap ip entry in {0} of accesscontrol list group:{1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:603 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ empty = could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be empty -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:216 -# args: ips -operation\ failure,\ ip\ format\ only\ supports\ ip/iprange/cidr,\ but\ find\ %s = operation failure, ip format only supports ip/iprange/cidr, but find {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:598 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ set = could not change security group rule, because rule protocol is [{0}], dstPortRange cannot be set -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:220 -# args: startIp,endIp,NetworkUtils.longToIpv4String(r.lowerEndpoint()),NetworkUtils.longToIpv4String(r.upperEndpoint()),acl.getUuid() -ip\ range[%s,\ %s]\ is\ overlap\ with\ start\ ip\:%s,\ end\ ip\:\ %s\ of\ access-control-list\ group\:%s = ip range[{0}, {1}] is overlap with start ip:{2}, end ip: {3} of access-control-list group:{4} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:642 +# args: JSONObjectUtil.toJsonString(sao),o.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = could not change security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:242 -# args: aclUuids,lbUuid -Can't\ attach\ the\ type\ access-control-list\ group[%s]\ whose\ ip\ version\ is\ different\ with\ LoadBalancer[%s] = Can't attach the type access-control-list group[{0}] whose ip version is different with LoadBalancer[{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:145 +# args: uuid,backendL3Cidr,frontL3Uuid,frontL3Cidr +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ cidr\ [%s]\ is\ overlapped\ with\ frond\ l3\ network[uuid\:%s]\ cidr\ [%s] = could not execute the api operation. backend network [uuid:{0}] cidr [{1}] is overlapped with frond l3 network[uuid:{2}] cidr [{3}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:302 -# args: existingAcls,msg.getListenerUuid() -the\ access-control-list\ groups[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ listener[uuid\:%s] = the access-control-list groups[uuid:{0}] are already on the load balancer listener[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:768 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ can\ not\ be\ vpc\ network\ because\ other\ backend\ network\ is\ not\ vpc\ network = could not execute the api operation. backend network [uuid:{0}] can not be vpc network because other backend network is not vpc network -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:308 -# args: msg.getListenerUuid(),type.toString() -the\ load\ balancer\ listener[uuid\:%s]\ just\ only\ attach\ the\ %s\ type\ access-control-list\ group = the load balancer listener[uuid:{0}] just only attach the {1} type access-control-list group +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:804 +# args: +can't\ delete\ rules\ of\ different\ security\ group = can't delete rules of different security group + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:807 +# args: vo.getUuid() +can't\ delete\ default\ rule[uuid\:%s] = can't delete default rule[uuid:{0}] + +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:170 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ not\ connected\ vpc\ router = could not execute the api operation. backend network [uuid:{0}] is not connected vpc router + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:835 +# args: backendL3Uuids.get(0),firstBackendVrUuids.get(0),frontL3Uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ connected\ vpc\ router\ [uuid\:%s]\ which\ is\ not\ connect\ to\ front\ network[uuid\:%s] = could not execute the api operation. backend network [uuid:{0}] is connected vpc router [uuid:{1}] which is not connect to front network[uuid:{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:313 -# args: msg.getListenerUuid(),LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) -the\ load\ balancer\ listener[uuid\:%s]\ can't\ \ attach\ more\ than\ %d\ access-control-list\ groups = the load balancer listener[uuid:{0}] can't attach more than {1} access-control-list groups +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:897 +# args: wrongUuids,securityGroupUuid +VM\ nics[uuids\:%s]\ are\ not\ on\ L3\ networks\ that\ have\ been\ attached\ to\ the\ security\ group[uuid\:%s] = VM nics[uuids:{0}] are not on L3 networks that have been attached to the security group[uuid:{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:339 -# args: l3Uuids,LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING -L3\ networks[uuids\:%s]\ of\ the\ vm\ nics\ has\ no\ network\ service[%s]\ enabled = L3 networks[uuids:{0}] of the vm nics has no network service[{1}] enabled +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:933 +# args: uuid +could\ not\ add\ security\ group\ rule,\ because\ security\ group[uuid\:%s]\ does\ not\ exist = could not add security group rule, because security group[uuid:{0}] does not exist -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:349 -# args: existingNics,msg.getListenerUuid() -the\ vm\ nics[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ listener[uuid\:%s] = the vm nics[uuid:{0}] are already on the load balancer listener[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:922 +# args: SecurityGroupConstant.ONE_API_RULES_MAX_NUM +could\ not\ add\ security\ group\ rule,\ because\ the\ rules\ cannot\ be\ empty\ or\ exceed\ the\ max\ number\ %d = could not add security group rule, because the rules cannot be empty or exceed the max number {0} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:678 -# args: listenerVO.getProtocol(),msg.getHealthCheckProtocol() -the\ listener\ with\ protocol\ [%s]\ doesn't\ support\ this\ health\ check\:[%s] = the listener with protocol [{0}] doesn't support this health check:[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:927 +# args: msg.getRemoteSecurityGroupUuids() +could\ not\ add\ security\ group\ rule,\ because\ duplicate\ uuid\ in\ remoteSecurityGroupUuids\:\ %s = could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: {0} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:652 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:938 # args: -the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameter\ healthCheckURI = the http health check protocol must be specified its healthy checking parameter healthCheckURI +could\ not\ add\ security\ group\ rule,\ because\ the\ remote\ security\ group\ uuid\ is\ conflict = could not add security group rule, because the remote security group uuid is conflict -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:659 -# args: msg.getHealthCheckHttpCode() -the\ http\ health\ check\ protocol's\ expecting\ code\ [%s]\ is\ invalidate = the http health check protocol's expecting code [{0}] is invalidate +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:974 +# args: SecurityGroupConstant.DEFAULT_RULE_PRIORITY,SecurityGroupConstant.LOWEST_RULE_PRIORITY +could\ not\ add\ security\ group\ rule,\ because\ rule\ priority\ must\ greater\ than\ %d\ or\ equals\ %d = could not add security group rule, because rule priority must greater than {0} or equals {1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:457 -# args: LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) -Can't\ attach\ more\ than\ %d\ access-control-list\ groups\ to\ a\ listener = Can't attach more than {0} access-control-list groups to a listener +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:982 +# args: ao.getType(),SecurityGroupRuleType.getAllType() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ type[%s],\ valid\ types\ are\ %s = could not add security group rule, because invalid rule type[{0}], valid types are {1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:537 -# args: tag,s,LoadBalancerConstants.MAX_CONNECTION_LIMIT -invalid\ max\ connection[%s],\ %s\ is\ larger\ than\ upper\ threshold\ %d = invalid max connection[{0}], {1} is larger than upper threshold {2} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:989 +# args: ao.getState(),SecurityGroupRuleState.getAllState() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ state[%s],\ valid\ states\ are\ %s = could not add security group rule, because invalid rule state[{0}], valid states are {1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:559 -# args: msg.getLoadBalancerPort(),luuid -conflict\ loadBalancerPort[%s],\ a\ listener[uuid\:%s]\ has\ used\ that\ port = conflict loadBalancerPort[{0}], a listener[uuid:{1}] has used that port +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:994 +# args: ao.getProtocol(),SecurityGroupRuleProtocolType.getAllProtocol() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ protocol[%s],\ valid\ protocols\ are\ %s = could not add security group rule, because invalid rule protocol[{0}], valid protocols are {1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:564 -# args: -udp\ port\ 53\ is\ used\ by\ dns\ daemon = udp port 53 is used by dns daemon +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1001 +# args: ao.getAction(),SecurityGroupRuleAction.getAllAction() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ action[%s],\ valid\ actions\ are\ %s = could not add security group rule, because invalid rule action[{0}], valid actions are {1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:577 -# args: -tcp\ port\ 22,\ 7272\ is\ used\ by\ vrouter = tcp port 22, 7272 is used by vrouter +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1009 +# args: ao.getIpVersion(),IPv6Constants.IPv4,IPv6Constants.IPv6 +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ ipVersion[%d],\ valid\ ipVersions\ are\ %d/%d = could not add security group rule, because invalid rule ipVersion[{0}], valid ipVersions are {1}/{2} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:604 -# args: vo.getProtocol() -loadbalancer\ listener\ with\ type\ %s\ does\ not\ need\ certificate = loadbalancer listener with type {0} does not need certificate +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1037 +# args: ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ dstIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ ingress\ rule = could not add security group rule, because the dstIpRange[{0}] is not allowed to set for ingress rule -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:608 -# args: msg.getListenerUuid(),msg.getCertificateUuid() -loadbalancer\ listener\ [uuid\:%s]\ already\ had\ certificate[uuid\:%s] = loadbalancer listener [uuid:{0}] already had certificate[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1042 +# args: ao.getAllowedCidr(),ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ srcIpRange[%s]\ are\ in\ conflict = could not add security group rule, because the allowedCidr[{0}] and srcIpRange[{1}] are in conflict -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:618 -# args: msg.getCertificateUuid(),msg.getListenerUuid() -certificate\ [uuid\:%s]\ is\ not\ added\ to\ loadbalancer\ listener\ [uuid\:%s] = certificate [uuid:{0}] is not added to loadbalancer listener [uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1031 +# args: ao.getDstIpRange(),ao.getRemoteSecurityGroupUuid() +could\ not\ add\ security\ group\ rule,\ because\ the\ ip\ range[%s]\ and\ remoteSecurityGroupUuid[%s]\ are\ in\ conflict = could not add security group rule, because the ip range[{0}] and remoteSecurityGroupUuid[{1}] are in conflict -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:633 -# args: target -healthCheck\ target\ [%s]\ error,\ it\ must\ be\ 'default'\ or\ number\ between[1~65535]\ = healthCheck target [{0}] error, it must be 'default' or number between[1~65535] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1019 +# args: ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ srcIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ egress\ rule = could not add security group rule, because the srcIpRange[{0}] is not allowed to set for egress rule -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:683 -# args: -the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameters\ including\ healthCheckMethod\ and\ healthCheckURI = the http health check protocol must be specified its healthy checking parameters including healthCheckMethod and healthCheckURI +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1024 +# args: ao.getAllowedCidr(),ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ dstIpRange[%s]\ are\ in\ conflict = could not add security group rule, because the allowedCidr[{0}] and dstIpRange[{1}] are in conflict -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1113 -# args: msg.getVmNicUuids().get(0) -the\ L3\ network\ of\ vm\ nic[uuid\:%s]\ doesn't\ have\ load\ balancer\ service\ enabled = the L3 network of vm nic[uuid:{0}] doesn't have load balancer service enabled +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1073 +# args: ao.getEndPort(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ endPort[%d],\ endPort\ must\ be\ greater\ than\ or\ equal\ to\ startPort[%d] = could not add security group rule, because invalid rule endPort[{0}], endPort must be greater than or equal to startPort[{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1140 -# args: self.getUuid(),self.getProviderType(),msg.getVmNicUuids().get(0),providerType -service\ provider\ type\ mismatching.\ The\ load\ balancer[uuid\:%s]\ is\ provided\ by\ the\ service\ provider[type\:%s],\ but\ the\ L3\ network\ of\ vm\ nic[uuid\:%s]\ is\ enabled\ with\ the\ service\ provider[type\:\ %s] = service provider type mismatching. The load balancer[uuid:{0}] is provided by the service provider[type:{1}], but the L3 network of vm nic[uuid:{2}] is enabled with the service provider[type: {3}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1076 +# args: ao.getDstPortRange(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ dstPortRange[%s]\ and\ starPort[%s]\ are\ in\ conflict = could not add security group rule, because dstPortRange[{0}] and starPort[{1}] are in conflict -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1670 -# args: param -invalid\ health\ checking\ parameters[%s],\ the\ format\ is\ method\:URI\:code,\ for\ example,\ GET\:/index.html\:http_2xx = invalid health checking parameters[{0}], the format is method:URI:code, for example, GET:/index.html:http_2xx +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1087 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ TCP/UDP\ must\ set\ dstPortRange = could not add security group rule, because the protocol type TCP/UDP must set dstPortRange -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:99 -# args: msg.getLoadBalancerUuid() -cannot\ find\ the\ load\ balancer[uuid\:%s] = cannot find the load balancer[uuid:{0}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1065 +# args: ao.getDstPortRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ dstPortRange[%s] = could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[{0}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:381 -# args: tag.getTag() -cannot\ delete\ the\ system\ tag[%s].\ The\ load\ balancer\ plugin\ relies\ on\ it,\ you\ can\ only\ update\ it = cannot delete the system tag[{0}]. The load balancer plugin relies on it, you can only update it +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1068 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ startPort\ or\ endPort = could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:399 -# args: nicUuid,systemTag -nic[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ loadbalancer = nic[uuid:{0}] not found. Please correct your system tag[{1}] of loadbalancer +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1097 +# args: JSONObjectUtil.toJsonString(newRules.get(i)),JSONObjectUtil.toJsonString(newRules.get(j)) +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ and\ rule[%s]\ are\ dupilicated = could not add security group rule, because rule[{0}] and rule[{1}] are dupilicated -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:411 -# args: systemTag,s -invalid\ balancer\ weight[%s],\ %s\ is\ not\ a\ number = invalid balancer weight[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1121 +# args: JSONObjectUtil.toJsonString(sao),vo.getUuid() +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = could not add security group rule, because rule[{0}] is duplicated to rule[uuid:{1}] in datebase -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:407 -# args: systemTag,s,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX -invalid\ balancer\ weight[%s],\ %s\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid balancer weight[{0}], {1} is not in the range [{2}, {3}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1136 +# args: SecurityGroupRuleType.Egress,SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ has\ reached\ the\ maximum\ limit[%d] = could not add security group rule, because security group {0} rules has reached the maximum limit[{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:423 -# args: algorithm,LoadBalancerConstants.BALANCE_ALGORITHMS -invalid\ balance\ algorithm[%s],\ valid\ algorithms\ are\ %s = invalid balance algorithm[{0}], valid algorithms are {1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1144 +# args: SecurityGroupRuleType.Egress,(egressRuleCount + toCreateEgressRuleCount),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = could not add security group rule, because security group {0} rules number[{1}] is out of max limit[{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:497 -# args: systemTag,s -invalid\ unhealthy\ threshold[%s],\ %s\ is\ not\ a\ number = invalid unhealthy threshold[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1148 +# args: msg.getPriority(),ingressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ ingress\ rule\ maximum\ priority\ is\ [%d] = could not add security group rule, because priority[{0}] must be consecutive, the ingress rule maximum priority is [{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:511 -# args: systemTag,s -invalid\ healthy\ threshold[%s],\ %s\ is\ not\ a\ number = invalid healthy threshold[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1151 +# args: msg.getPriority(),egressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ egress\ rule\ maximum\ priority\ is\ [%d] = could not add security group rule, because priority[{0}] must be consecutive, the egress rule maximum priority is [{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:525 -# args: systemTag,s -invalid\ healthy\ timeout[%s],\ %s\ is\ not\ a\ number = invalid healthy timeout[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:217 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ must\ be\ vpc\ network\ because\ other\ backend\ network\ is\ vpc\ network = could not execute the api operation. backend network [uuid:{0}] must be vpc network because other backend network is vpc network -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:539 -# args: systemTag,s -invalid\ connection\ idle\ timeout[%s],\ %s\ is\ not\ a\ number = invalid connection idle timeout[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:228 +# args: uuid,bVrUuids.get(0),firstBackendVrUuids.get(0) +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ connected\ vpc\ router\ [uuid\:%s]\ while\ other\ backend\ network\ is\ connected\ to\ vpc\ router[uuid\:%s] = could not execute the api operation. backend network [uuid:{0}] is connected vpc router [uuid:{1}] while other backend network is connected to vpc router[uuid:{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:553 -# args: systemTag,s -invalid\ health\ check\ interval[%s],\ %s\ is\ not\ a\ number = invalid health check interval[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:186 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ must\ be\ private\ flat\ network\ because\ frond\ l3\ network\ is\ private\ flat\ network = could not execute the api operation. backend network [uuid:{0}] must be private flat network because frond l3 network is private flat network -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:567 -# args: systemTag,s -invalid\ max\ connection[%s],\ %s\ is\ not\ a\ number = invalid max connection[{0}], {1} is not a number +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:156 +# args: frontL3.getUuid() +could\ not\ execute\ the\ api\ operation.\ frontend\ network\ [uuid\:%s]\ is\ not\ connected\ vpc\ router = could not execute the api operation. frontend network [uuid:{0}] is not connected vpc router -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:585 -# args: systemTag,protocol,LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCOLS -invalid\ health\ target[%s],\ the\ target\ checking\ protocol[%s]\ is\ invalid,\ valid\ protocols\ are\ %s = invalid health target[{0}], the target checking protocol[{1}] is invalid, valid protocols are {2} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:164 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ must\ be\ vpc\ network\ because\ frond\ l3\ network\ is\ vpc\ network = could not execute the api operation. backend network [uuid:{0}] must be vpc network because frond l3 network is vpc network -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:597 -# args: systemTag,port -invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ a\ number = invalid invalid health target[{0}], port[{1}] is not a number +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:175 +# args: uuid,backendVrUuids.get(0),frontVrUuids.get(0) +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ connected\ vpc\ router\ [uuid\:%s]\ while\ front\ network\ is\ connected\ to\ vpc\ router[uuid\:%s] = could not execute the api operation. backend network [uuid:{0}] is connected vpc router [uuid:{1}] while front network is connected to vpc router[uuid:{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:594 -# args: systemTag,port -invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ in\ the\ range\ of\ [1,\ 65535] = invalid invalid health target[{0}], port[{1}] is not in the range of [1, 65535] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:254 +# args: msg.getDeployType() +could\ not\ create\ slb\ group\ because\ invalid\ deploy\ type\ %s = could not create slb group because invalid deploy type {0} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java:74 -# args: nicUuid,weight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX -invalid\ balancer\ weight\ for\ nic\:%s,\ %d\ is\ not\ in\ the\ range\ [%d,\ %d] = invalid balancer weight for nic:{0}, {1} is not in the range [{2}, {3}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:263 +# args: msg.getBackendType() +could\ not\ create\ slb\ group\ because\ invalid\ backend\ type\ %s = could not create slb group because invalid backend type {0} -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:206 -# args: msg.getVmNicUuid(),msg.getVipUuid() -guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ vip[uuid\:\ %s]\ are\ the\ same\ network = guest l3Network of vm nic[uuid:{0}] and vip l3Network of vip[uuid: {1}] are the same network +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:298 +# args: frontL3Uuid,slbVO.getUuid() +can\ not\ detach\ front\ end\ l3\ network\ [uuid\:%s]\ from\ SLB\ instance = can not detach front end l3 network [uuid:{0}] from SLB instance -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:181 -# args: msg.getVipUuid(),useForList.toString() -the\ vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = the vip[uuid:{0}] has been occupied other network service entity[{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:303 +# args: slbVO.getManagementNetworkUuid(),slbVO.getUuid() +can\ not\ detach\ management\ l3\ network\ [uuid\:%s]\ from\ SLB\ instance = can not detach management l3 network [uuid:{0}] from SLB instance -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:66 -# args: msg.getRuleUuid(),state -Port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ current\ state\ is\ %s = Port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:315 +# args: msg.getVmNicUuid() +can\ not\ detach\ nic\ [uuid\:%s]\ from\ SLB\ instance,\ because\ it\ is\ the\ last\ backend\ l3\ network\ nic = can not detach nic [uuid:{0}] from SLB instance, because it is the last backend l3 network nic -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:81 -# args: msg.getUuid() -port\ forwarding\ rule\ rule[uuid\:%s]\ has\ not\ been\ attached\ to\ any\ vm\ nic,\ can't\ detach = port forwarding rule rule[uuid:{0}] has not been attached to any vm nic, can't detach +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:343 +# args: msg.getVipUuid(),vipVO.getServicesTypes() +can\ not\ create\ load\ balancer\ because\ vip\ [uuid\:%s]\ has\ attached\ other\ network\ service\ [%s] = can not create load balancer because vip [uuid:{0}] has attached other network service [{1}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:95 -# args: msg.getRuleUuid(),vmNicUuid -port\ forwarding\ rule[uuid\:%s]\ has\ been\ attached\ to\ vm\ nic[uuid\:%s],\ can't\ attach\ again = port forwarding rule[uuid:{0}] has been attached to vm nic[uuid:{1}], can't attach again +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:350 +# args: msg.getVipUuid(),vrUuids +can\ not\ create\ load\ balancer\ because\ vip\ [uuid\:%s]\ has\ attached\ to\ vpc\ router\ [%s] = can not create load balancer because vip [uuid:{0}] has attached to vpc router [{1}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:100 -# args: msg.getRuleUuid(),state -port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ \ current\ state\ is\ %s.\ A\ rule\ can\ only\ be\ attached\ when\ its\ state\ is\ Enabled = port forwarding rule[uuid:{0}] is not in state of Enabled, current state is {1}. A rule can only be attached when its state is Enabled +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:356 +# args: slbGroupUuid +can\ not\ create\ load\ balancer\ because\ invalid\ slb\ group\ [uuid\:%s] = can not create load balancer because invalid slb group [uuid:{0}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:119 -# args: msg.getVmNicUuid(),msg.getRuleUuid() -guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ port\ forwarding\ rule[uuid\:%s]\ are\ the\ same\ network = guest l3Network of vm nic[uuid:{0}] and vip l3Network of port forwarding rule[uuid:{1}] are the same network +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:407 +# args: +could\ not\ add\ vmnic\ to\ load\ balancer\ server\ \ group\ because\ l3\ network\ is\ not\ connected\ slb\ instance = could not add vmnic to load balancer server group because l3 network is not connected slb instance -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:166 -# args: msg.getVipPortStart(),msg.getVipPortEnd(),msg.getPrivatePortStart(),msg.getPrivatePortEnd() -for\ range\ port\ forwarding,\ the\ port\ range\ size\ must\ match;\ vip\ range[%s,\ %s]'s\ size\ doesn't\ match\ range[%s,\ %s]'s\ size = for range port forwarding, the port range size must match; vip range[{0}, {1}]'s size doesn't match range[{2}, {3}]'s size +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:389 +# args: uuid +could\ not\ add\ vmnic\ to\ load\ balancer\ server\ \ group\ because\ l3\ network\ [uuid\:%s]\ is\ connected\ any\ vpc\ router = could not add vmnic to load balancer server group because l3 network [uuid:{0}] is connected any vpc router -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:173 -# args: msg.getAllowedCidr() -invalid\ CIDR[%s] = invalid CIDR[{0}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:396 +# args: uuid +could\ not\ add\ vmnic\ to\ load\ balancer\ server\ \ group\ because\ l3\ network[uuid\:%s]\ is\ connected\ to\ different\ vpc\ router = could not add vmnic to load balancer server group because l3 network[uuid:{0}] is connected to different vpc router -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:191 -# args: vipStart,vipEnd,vo.getUuid(),vo.getVipPortStart(),vo.getVipPortEnd() -vip\ port\ range[vipStartPort\:%s,\ vipEndPort\:%s]\ overlaps\ with\ rule[uuid\:%s,\ vipStartPort\:%s,\ vipEndPort\:%s] = vip port range[vipStartPort:{0}, vipEndPort:{1}] overlaps with rule[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}] +# at: src/main/java/org/zstack/network/service/slb/SlbCreatePublicVipFlow.java:60 +# args: slbInstance.getUuid(),frontL3Uuid +can\ not\ find\ nic\ of\ slb\ instance\ [uuid\:%s]\ which\ is\ attached\ to\ slb\ group\ front\ l3\ network\ [uuid\:%s] = can not find nic of slb instance [uuid:{0}] which is attached to slb group front l3 network [uuid:{1}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:243 -# args: vm.getName(),vm.getUuid(),vipUuid -the\ VM[name\:%s\ uuid\:%s]\ already\ has\ port\ forwarding\ rules\ that\ have\ different\ VIPs\ than\ the\ one[uuid\:%s] = the VM[name:{0} uuid:{1}] already has port forwarding rules that have different VIPs than the one[uuid:{2}] +# at: src/main/java/org/zstack/network/service/slb/SlbVyosBackend.java:38 +# args: +can\ not\ find\ slb\ vm\ instance = can not find slb vm instance + +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:48 +# args: +system\ vip\ can\ not\ be\ deleted\ by\ API\ message = system vip can not be deleted by API message -# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:49 +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:54 # args: msg.getAllocatorStrategy() unsupported\ ip\ allocation\ strategy[%s] = unsupported ip allocation strategy[{0}] -# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:61 -# args: msg.getRequiredIp() -requiredIp[%s]\ is\ not\ in\ valid\ IPv6\ mediaType = requiredIp[{0}] is not in valid IPv6 mediaType - -# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:56 +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:63 # args: msg.getRequiredIp() requiredIp[%s]\ is\ not\ in\ valid\ IPv4\ mediaType = requiredIp[{0}] is not in valid IPv4 mediaType @@ -5242,14 +8974,18 @@ requiredIp[%s]\ is\ not\ in\ valid\ IPv4\ mediaType = requiredIp[{0}] is not in # args: msg.getRequiredIp(),msg.getL3NetworkUuid() there\ is\ already\ a\ vip[%s]\ on\ l3Network[uuid\:%s] = there is already a vip[{0}] on l3Network[uuid:{1}] -# at: src/main/java/org/zstack/network/service/vip/VipBase.java:152 +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:76 +# args: msg.getRequiredIp() +required\ ip\ address\ [%s]\ is\ already\ used = required ip address [{0}] is already used + +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:100 +# args: +could\ not\ create\ vip,\ because\ can\ not\ determine\ the\ vip\ version = could not create vip, because can not determine the vip version + +# at: src/main/java/org/zstack/network/service/vip/VipBase.java:155 # args: self.getUuid(),self.getName(),self.getIp(),self.getServiceProvider() service\ provider\ of\ the\ vip[uuid\:%s,\ name\:%s,\ ip\:\ %s]\ has\ been\ set\ to\ %s = service provider of the vip[uuid:{0}, name:{1}, ip: {2}] has been set to {3} -# at: src/main/java/org/zstack/network/service/vip/VipBase.java:712 -# args: self.getUuid(),self.getIp() -Vip\ [uuid\ %s,\ ip\ %s]\ of\ router\ public\ interface\ can\ not\ be\ deleted = Vip [uuid {0}, ip {1}] of router public interface can not be deleted - # at: src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java:43 # args: VipQos\ for\ ipv6\ wil\ be\ added\ soon = VipQos for ipv6 wil be added soon @@ -5282,110 +9018,138 @@ VipQos\ for\ Vip\ [uuid\:\ %s]\ port\ %s\ does\ not\ exist = VipQos for Vip [uui # args: vipUuid Can\ not\ find\ VipQos\ backend\ for\ Vip\ [uuid\:%s] = Can not find VipQos backend for Vip [uuid:{0}] -# at: src/main/java/org/zstack/network/service/vipQos/flat/FlatVipQosBackend.java:197 +# at: src/main/java/org/zstack/network/service/vipQos/flat/FlatVipQosBackend.java:198 # args: hostUuid operation\ error,\ vip\ %s\ has\ not\ bind\ to\ vm = operation error, vip {0} has not bind to vm -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:277 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:656 # args: self.getName(),self.getUuid(),self.getState() the\ virtual\ router[name\:%s,\ uuid\:%s,\ current\ state\:%s]\ is\ not\ running,and\ cannot\ perform\ required\ operation.\ Please\ retry\ your\ operation\ later\ once\ it\ is\ running = the virtual router[name:{0}, uuid:{1}, current state:{2}] is not running,and cannot perform required operation. Please retry your operation later once it is running -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:282 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:661 # args: self.getUuid(),getSelf().getStatus(),msg.getPath() virtual\ router[uuid\:%s]\ is\ in\ status\ of\ %s\ that\ cannot\ make\ http\ call\ to\ %s = virtual router[uuid:{0}] is in status of {1} that cannot make http call to {2} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:287 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:666 # args: self.getUuid(),msg.getPath() virtual\ router[uuid\:%s]\ has\ no\ management\ nic\ that\ cannot\ make\ http\ call\ to\ %s = virtual router[uuid:{0}] has no management nic that cannot make http call to {1} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:397 -# args: getSelf().getUuid() -appliance\ vm\ %s\ reconnect\ failed = appliance vm {0} reconnect failed - -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:473 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:995 # args: info.getIp(),info.getMac(),vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError() unable\ to\ add\ nic[ip\:%s,\ mac\:%s]\ to\ virtual\ router\ vm[uuid\:%s\ ip\:%s],\ because\ %s = unable to add nic[ip:{0}, mac:{1}] to virtual router vm[uuid:{2} ip:{3}], because {4} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:750 -# args: info,vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError() -unable\ to\ detach\ nic[%s]\ from\ virtual\ router\ vm[uuid\:%s\ ip\:%s],\ because\ %s = unable to detach nic[{0}] from virtual router vm[uuid:{1} ip:{2}], because {3} +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:94 +# args: msg.getDefaultRouteL3NetworkUuid(),msg.getVmInstanceUuid() +l3\ uuid[\:%s]\ is\ same\ to\ default\ network\ of\ virtual\ router\ [uuid\:%s] = l3 uuid[:{0}] is same to default network of virtual router [uuid:{1}] -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:106 -# args: msg.getDefaultRouteL3NetworkUuid() -could\ not\ set\ the\ default\ network,\ because\ l3\ uuid[\:%s]\ is\ management\ network = could not set the default network, because l3 uuid[:{0}] is management network +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:107 +# args: msg.getDefaultRouteL3NetworkUuid(),msg.getVmInstanceUuid() +l3\ uuid[\:%s]\ is\ not\ attached\ to\ virtual\ router\ [uuid\:%s] = l3 uuid[:{0}] is not attached to virtual router [uuid:{1}] -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:108 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:114 # args: msg.getDefaultRouteL3NetworkUuid() could\ not\ set\ the\ default\ network,\ because\ l3\ uuid[\:%s]\ is\ not\ public\ network = could not set the default network, because l3 uuid[:{0}] is not public network -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:149 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:112 +# args: msg.getDefaultRouteL3NetworkUuid() +could\ not\ set\ the\ default\ network,\ because\ l3\ uuid[\:%s]\ is\ management\ network = could not set the default network, because l3 uuid[:{0}] is management network + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:219 # args: msg.getImageUuid(),type,ImageMediaType.RootVolumeTemplate image[uuid\:%s]'s\ mediaType\ is\ %s,\ the\ mediaType\ of\ a\ virtual\ router\ image\ must\ be\ %s = image[uuid:{0}]'s mediaType is {1}, the mediaType of a virtual router image must be {2} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:155 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:225 # args: msg.getImageUuid(),format image[uuid\:%s]\ is\ of\ format\ %s,\ cannot\ be\ used\ for\ virtual\ router = image[uuid:{0}] is of format {1}, cannot be used for virtual router -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:125 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:191 # args: msg.getManagementNetworkUuid(),msg.getZoneUuid() management\ network[uuid\:%s]\ is\ not\ in\ the\ same\ zone[uuid\:%s]\ this\ offering\ is\ going\ to\ create = management network[uuid:{0}] is not in the same zone[uuid:{1}] this offering is going to create -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:138 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:196 +# args: +can\ not\ create\ virtual\ router\ offering,\ because\ management\ network\ doesn't\ support\ ipv6\ yet = can not create virtual router offering, because management network doesn't support ipv6 yet + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:208 # args: msg.getManagementNetworkUuid(),msg.getZoneUuid() public\ network[uuid\:%s]\ is\ not\ in\ the\ same\ zone[uuid\:%s]\ this\ offering\ is\ going\ to\ create = public network[uuid:{0}] is not in the same zone[uuid:{1}] this offering is going to create -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:166 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:236 # args: msg.getPublicNetworkUuid() the\ L3\ network[uuid\:\ %s]\ has\ the\ SNAT\ service\ enabled,\ it\ cannot\ be\ used\ as\ a\ public\ network = the L3 network[uuid: {0}] has the SNAT service enabled, it cannot be used as a public network -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:164 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:234 # args: msg.getManagementNetworkUuid() the\ L3\ network[uuid\:\ %s]\ has\ the\ SNAT\ service\ enabled,\ it\ cannot\ be\ used\ as\ a\ management\ network = the L3 network[uuid: {0}] has the SNAT service enabled, it cannot be used as a management network -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:173 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:243 # args: msg.getManagementNetworkUuid(),msg.getPublicNetworkUuid() the\ L3\ network[uuid\:\ %s]\ is\ same\ network\ address\ with\ [uuid\:\ %s],\ it\ cannot\ be\ used\ for\ virtual\ router = the L3 network[uuid: {0}] is same network address with [uuid: {1}], it cannot be used for virtual router -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:183 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:253 # args: managementNetworkUuid the\ management\ network[uuid\:%s]\ doesn't\ have\ any\ IP\ range = the management network[uuid:{0}] doesn't have any IP range -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:200 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:274 # args: managementNetworkUuid,gateway the\ management\ network[uuid\:%s,\ gateway\:%s]\ is\ not\ reachable = the management network[uuid:{0}, gateway:{1}] is not reachable -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:107 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:103 # args: iso.getIsoPath(),vrSpec.getDestHost().getUuid(),vrSpec.getDestHost().getManagementIp(),iso.getVirtualRouterUuid(),rsp.getError() failed\ to\ create\ VirtualRouterBootstrapIso[%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s]\ for\ virtual\ router[uuid\:%s],\ because\ %s = failed to create VirtualRouterBootstrapIso[{0}] on kvm host[uuid:{1}, ip:{2}] for virtual router[uuid:{3}], because {4} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:140 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:136 # args: iso.getIsoPath(),hostUuid,iso.getVirtualRouterUuid(),rsp.getError() failed\ to\ delete\ VirtualRouterBootstrapIso[%s]\ on\ kvm\ host[uuid\:%s]\ for\ virtual\ router[uuid\:%s],\ because\ %s = failed to delete VirtualRouterBootstrapIso[{0}] on kvm host[uuid:{1}] for virtual router[uuid:{2}], because {3} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:280 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:289 # args: cannot\ create\ virtual\ Router\ vm\ while\ virtual\ router\ network\ overlaps\ with\ private\ network\ in\ ip\ = cannot create virtual Router vm while virtual router network overlaps with private network in ip -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:585 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:716 # args: offeringUuid No\ virtual\ router\ instance\ offering\ with\ uuid\:%s\ is\ found = No virtual router instance offering with uuid:{0} is found -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1182 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:720 +# args: offeringUuid,resourceUuid +the\ network\ of\ virtual\ router\ instance\ offering\ with\ uuid\:%s\ can't\ be\ same\ with\ private\ l3\ network\ uuid\:%s = the network of virtual router instance offering with uuid:{0} can't be same with private l3 network uuid:{1} + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1434 +# args: l3NetworkUuid +cannot\ add\ ip\ range,\ because\ l3\ network[uuid\:%s]\ is\ management\ network\ of\ virtual\ router\ offering = cannot add ip range, because l3 network[uuid:{0}] is management network of virtual router offering + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1439 +# args: l3NetworkUuid +cannot\ add\ ip\ range,\ because\ l3\ network[uuid\:%s]\ is\ management\ network\ of\ virtual\ router = cannot add ip range, because l3 network[uuid:{0}] is management network of virtual router + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1466 +# args: tag,type +couldn't\ add\ image,\ because\ systemTag\ [%s]\ includes\ invalid\ appliance\ image\ type\ [%s] = couldn't add image, because systemTag [{0}] includes invalid appliance image type [{1}] + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1504 # args: msg.getL3NetworkUuid() failed\ tot\ attach\ virtual\ router\ network\ services\ to\ l3Network[uuid\:%s].\ When\ eip\ is\ selected,\ snat\ must\ be\ selected\ too = failed tot attach virtual router network services to l3Network[uuid:{0}]. When eip is selected, snat must be selected too -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1186 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1508 # args: msg.getL3NetworkUuid() failed\ tot\ attach\ virtual\ router\ network\ services\ to\ l3Network[uuid\:%s].\ When\ port\ forwarding\ is\ selected,\ snat\ must\ be\ selected\ too = failed tot attach virtual router network services to l3Network[uuid:{0}]. When port forwarding is selected, snat must be selected too -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1698 -# args: toDeleteNics.stream().map( n -> n.getUuid()).collect(Collectors.toList()) -can\ not\ detach\ nic\ [uuid\:%s] = can not detach nic [uuid:{0}] +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:2445 +# args: vrUuid,ret.getError() +update\ virtual\ router\ [uuid\:%s]\ default\ network\ failed,\ because\ %s = update virtual router [uuid:{0}] default network failed, because {1} + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:2541 +# args: ss[1] +invalid\ ApplianceVmType\ %s = invalid ApplianceVmType {0} -# at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java:126 -# args: vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError(),struct +# at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java:93 +# args: vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError(),JSONObjectUtil.toJsonString(info) unable\ to\ add\ dhcp\ entries\ to\ virtual\ router\ vm[uuid\:%s\ ip\:%s],\ because\ %s,\ dhcp\ entry[%s] = unable to add dhcp entries to virtual router vm[uuid:{0} ip:{1}], because {2}, dhcp entry[{3}] +# at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java:375 +# args: +no\ virtual\ router\ is\ configured\ for\ vyos\ dhcp = no virtual router is configured for vyos dhcp + # at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterSyncDHCPOnStartFlow.java:208 # args: vr.getUuid(),vr.getManagementNic().getIp(),ret.getError() unable\ to\ program\ dhcp\ entries\ served\ by\ virtual\ router[uuid\:%s,\ ip\:%s],\ %s = unable to program dhcp entries served by virtual router[uuid:{0}, ip:{1}], {2} @@ -5394,51 +9158,59 @@ unable\ to\ program\ dhcp\ entries\ served\ by\ virtual\ router[uuid\:%s,\ ip\:% # args: vr.getUuid(),vr.getManagementNic().getIp(),struct,l3.getUuid(),l3.getName(),ret.getError() virtual\ router[uuid\:%s,\ ip\:%s]\ failed\ to\ configure\ dns%s\ for\ L3Network[uuid\:%s,\ name\:%s],\ %s = virtual router[uuid:{0}, ip:{1}] failed to configure dns{2} for L3Network[uuid:{3}, name:{4}], {5} -# at: src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java:124 +# at: src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java:127 # args: vr.getName(),vr.getUuid(),JSONObjectUtil.toJsonString(dns),ret.getError() virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ configure\ dns%s,\ %s\ = virtual router[name: {0}, uuid: {1}] failed to configure dns{2}, {3} -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:496 -# args: vr.getUuid(),ret.getError() -failed\ to\ sync\ eip\ on\ virtual\ router[uuid\:%s],\ %s = failed to sync eip on virtual router[uuid:{0}], {1} - -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:165 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:168 # args: struct.getEip().getUuid(),struct.getEip().getName(),struct.getVip().getIp(),struct.getNic().getUuid(),vr.getUuid(),ret.getError() failed\ to\ create\ eip[uuid\:%s,\ name\:%s,\ ip\:%s]\ for\ vm\ nic[uuid\:%s]\ on\ virtual\ router[uuid\:%s],\ %s = failed to create eip[uuid:{0}, name:{1}, ip:{2}] for vm nic[uuid:{3}] on virtual router[uuid:{4}], {5} -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:246 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:226 # args: offering.getUuid(),l3inv.getUuid(),l3inv.getZoneUuid(),struct.getVip().getL3NetworkUuid(),struct.getEip().getUuid() found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ EIP[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network's public network[uuid:{3}] is not the same to EIP[uuid:{4}]'s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:336 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:318 # args: struct.getEip().getUuid(),struct.getEip().getName(),struct.getVip().getIp(),struct.getNic().getUuid(),vr.getUuid(),ret.getError() failed\ to\ remove\ eip[uuid\:%s,\ name\:%s,\ ip\:%s]\ for\ vm\ nic[uuid\:%s]\ on\ virtual\ router[uuid\:%s],\ %s = failed to remove eip[uuid:{0}, name:{1}, ip:{2}] for vm nic[uuid:{3}] on virtual router[uuid:{4}], {5} -# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:152 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java:214 +# args: vr.getUuid(),ret.getError() +failed\ to\ sync\ eip\ on\ virtual\ router[uuid\:%s],\ %s = failed to sync eip on virtual router[uuid:{0}], {1} + +# at: src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaBackendImpl.java:63 +# args: +ha\ group\ extension\ point\ nil = ha group extension point nil + +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:170 # args: msg.getVmNicUuids(),vrUuids new\ add\ vm\ nics[uuids\:%s]\ and\ attached\ vmnics\ are\ not\ on\ the\ same\ vrouter,\ they\ are\ on\ vrouters[uuids\:%s] = new add vm nics[uuids:{0}] and attached vmnics are not on the same vrouter, they are on vrouters[uuids:{1}] -# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:182 +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:200 # args: msg.getVmNicUuids(),peerL3NetworkUuids,msg.getLoadBalancerUuid(),vrUuids new\ add\ vm\ nics[uuids\:%s]\ and\ peer\ l3s[uuids\:%s]\ of\ loadbalancer[uuid\:\ %s]'s\ vip\ are\ not\ on\ the\ same\ vrouter,\ they\ are\ on\ vrouters[uuids\:%s] = new add vm nics[uuids:{0}] and peer l3s[uuids:{1}] of loadbalancer[uuid: {2}]'s vip are not on the same vrouter, they are on vrouters[uuids:{3}] -# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:1318 +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:1320 +# args: +vmnic\ must\ be\ specified\ for\ share\ loadbalancer = vmnic must be specified for share loadbalancer + +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:1778 # args: struct.getLb().getUuid() cannot\ find\ virtual\ router\ for\ load\ balancer\ [uuid\:%s] = cannot find virtual router for load balancer [uuid:{0}] -# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java:331 -# args: vr.getName(),vr.getUuid(),JSONObjectUtil.toJsonString(snatInfo),ret.getError() -virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ sync\ snat%s,\ %s = virtual router[name: {0}, uuid: {1}] failed to sync snat{2}, {3} - -# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java:92 +# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java:91 # args: guestL3.getUuid(),guestL3.getName(),offering.getPublicNetworkUuid(),offering.getUuid(),offering.getName() guest\ l3Network[uuid\:%s,\ name\:%s]\ needs\ SNAT\ service\ provided\ by\ virtual\ router,\ but\ public\ l3Network[uuid\:%s]\ of\ virtual\ router\ offering[uuid\:\ %s,\ name\:%s]\ is\ the\ same\ to\ this\ guest\ l3Network = guest l3Network[uuid:{0}, name:{1}] needs SNAT service provided by virtual router, but public l3Network[uuid:{2}] of virtual router offering[uuid: {3}, name:{4}] is the same to this guest l3Network -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ApplyPortforwardingRuleOnVirtualRouterVmFlow.java:80 +# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java:144 +# args: vr.getName(),vr.getUuid(),JSONObjectUtil.toJsonString(snatInfo),ret.getError() +virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ sync\ snat%s,\ %s = virtual router[name: {0}, uuid: {1}] failed to sync snat{2}, {3} + +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ApplyPortforwardingRuleOnVirtualRouterVmFlow.java:85 # args: to.getVipIp(),to.getPrivateIp(),to.getVipPortStart(),to.getVipPortEnd(),to.getPrivatePortStart(),to.getPrivatePortEnd(),ret.getError() failed\ to\ create\ port\ forwarding\ rule[vip\ ip\:\ %s,\ private\ ip\:\ %s,\ vip\ start\ port\:\ %s,\ vip\ end\ port\:\ %s,\ private\ start\ port\:\ %s,\ private\ end\ port\:\ %s],\ because\ %s = failed to create port forwarding rule[vip ip: {0}, private ip: {1}, vip start port: {2}, vip end port: {3}, private start port: {4}, private end port: {5}], because {6} -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ReleasePortForwardingRuleOnVirtualRouterVmFlow.java:74 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ReleasePortForwardingRuleOnVirtualRouterVmFlow.java:82 # args: JSONObjectUtil.toJsonString(to),ret.getError() failed\ to\ revoke\ port\ forwarding\ rules\ %s,\ because\ %s = failed to revoke port forwarding rules {0}, because {1} @@ -5450,39 +9222,35 @@ found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zon # args: rule.getVipPortStart(),rule.getVipPortEnd(),rule.getPrivatePortStart(),rule.getPrivatePortEnd() virtual\ router\ doesn't\ support\ port\ forwarding\ range\ redirection,\ the\ vipPortStart\ must\ be\ equals\ to\ privatePortStart\ and\ vipPortEnd\ must\ be\ equals\ to\ privatePortEnd;but\ this\ rule\ rule\ has\ a\ mismatching\ range\:\ vip\ port[%s,\ %s],\ private\ port[%s,\ %s] = virtual router doesn't support port forwarding range redirection, the vipPortStart must be equals to privatePortStart and vipPortEnd must be equals to privatePortEnd;but this rule rule has a mismatching range: vip port[{0}, {1}], private port[{2}, {3}] -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:402 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:408 # args: vrVO.getUuid(),ret.getError() failed\ to\ add\ portforwardings\ on\ virtual\ router[uuid\:%s],\ %s = failed to add portforwardings on virtual router[uuid:{0}], {1} -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:471 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:484 # args: vrVO.getUuid(),ret.getError() failed\ to\ revoke\ port\ forwardings\ on\ virtual\ router[uuid\:%s],\ %s = failed to revoke port forwardings on virtual router[uuid:{0}], {1} -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java:197 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java:212 # args: vr.getName(),vr.getUuid(),ret.getError() failed\ to\ sync\ port\ forwarding\ rules\ served\ by\ virtual\ router[name\:\ %s,\ uuid\:\ %s],\ because\ %s = failed to sync port forwarding rules served by virtual router[name: {0}, uuid: {1}], because {2} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreateVipForPublicIpFlow.java:66 -# args: vr.getName(),vr.getUuid(),nic.getIp(),nic.getL3NetworkUuid() -virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ create\ vip\ for\ public\ ip\ %s\ because\ no\ ip\ range\ for\ l3NetworkUuid\ %s = virtual router[name: {0}, uuid: {1}] failed to create vip for public ip {2} because no ip range for l3NetworkUuid {3} - -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:136 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:179 # args: tos,ret.getError() failed\ to\ remove\ vip%s,\ because\ %s = failed to remove vip{0}, because {1} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:92 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:125 # args: tos,vr.getUuid(),ret.getError() failed\ to\ create\ vip%s\ on\ virtual\ router[uuid\:%s],\ because\ %s = failed to create vip{0} on virtual router[uuid:{1}], because {2} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:201 -# args: vips.stream().map( v -> v.getIp()).collect(Collectors.toList()),nic.getVmInstanceUuid(),nic.getUuid(),nic.getIp(),ret.getError() +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:245 +# args: vips.stream().map(VipTO::getIp).collect(Collectors.toList()),nic.getVmInstanceUuid(),nic.getUuid(),nic.getIp(),ret.getError() failed\ to\ sync\ vips[ips\:\ %s]\ on\ virtual\ router[uuid\:%s]\ for\ attaching\ nic[uuid\:\ %s,\ ip\:\ %s],\ because\ %s = failed to sync vips[ips: {0}] on virtual router[uuid:{1}] for attaching nic[uuid: {2}, ip: {3}], because {4} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:262 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:240 # args: vrUuid,vrState virtual\ router[uuid\:%s,\ state\:%s]\ is\ not\ running = virtual router[uuid:{0}, state:{1}] is not running -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:303 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:281 # args: offering.getUuid(),s.getL3Network().getUuid(),s.getL3Network().getZoneUuid(),self.getL3NetworkUuid(),self.getUuid() found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ VIP[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = found a virtual router offering[uuid:{0}] for L3Network[uuid:{1}] in zone[uuid:{2}]; however, the network's public network[uuid:{3}] is not the same to VIP[uuid:{4}]'s; you may need to use system tag guestL3Network::l3NetworkUuid to specify a particular virtual router offering for the L3Network @@ -5490,138 +9258,242 @@ found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zon # args: nic.getIp(),nic.getMac(),nic.getVmInstanceUuid(),rsp.getError() failed\ to\ change\ nic[ip\:%s,\ mac\:%s]\ firewall\ default\ action\ of\ virtual\ router\ vm[uuid\:%s],\ because\ %s = failed to change nic[ip:{0}, mac:{1}] firewall default action of virtual router vm[uuid:{2}], because {3} -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:56 -# args: vrUuid,ret.getError() -virtual\ router[uuid\:\ %s]\ failed\ to\ get\ version\ because\ %s\ = virtual router[uuid: {0}] failed to get version because {1} +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java:156 +# args: mgmtNicIp +unable\ to\ ssh\ in\ to\ the\ virtual\ router[%s]\ after\ configure\ ssh = unable to ssh in to the virtual router[{0}] after configure ssh -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:63 -# args: vrUuid -virtual\ router[uuid\:\ %s]\ doesn't\ have\ version = virtual router[uuid: {0}] doesn't have version +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java:214 +# args: ret.getError() +vyos\ init\ command\ failed,\ because\:%s = vyos init command failed, because:{0} -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:69 -# args: vrUuid,ret.getVersion() -virtual\ router[uuid\:\ %s]\ version\ [%s]\ format\ error = virtual router[uuid: {0}] version [{1}] format error +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDhcpBackend.java:246 +# args: nic.getVmInstanceUuid(),rsp.getError() +unable\ to\ start\ dhcp\ server\ on\ virtual\ router\ vm[uuid\:%s],\ because\ %s = unable to start dhcp server on virtual router vm[uuid:{0}], because {1} -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:75 -# args: vrUuid,ret.getVersion(),managementVersion -virtual\ router[uuid\:\ %s]\ version\ [%s]\ is\ older\ than\ management\ node\ version\ [%s] = virtual router[uuid: {0}] version [{1}] is older than management node version [{2}] +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDhcpBackend.java:282 +# args: nic.getVmInstanceUuid(),rsp.getError() +unable\ to\ stop\ dhcp\ server\ on\ virtual\ router\ vm[uuid\:%s],\ because\ %s = unable to stop dhcp server on virtual router vm[uuid:{0}], because {1} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:79 -# args: vmUuid,specMap.keySet() -failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ pci\ specs[uuids\:%s]\ exist = failed to start vm[uuid:{0}] because not all pci specs[uuids:{1}] exist +# at: src/main/java/org/zstack/ovf/OvfHelper.java:104 +# args: id +File\ reference\ not\ fount\ for\ disk\ %s = File reference not fount for disk {0} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:132 -# args: vmUuid -no\ candidate\ host\ with\ enough\ spec\ related\ pci\ devices\ for\ vm[uuid\:%s] = no candidate host with enough spec related pci devices for vm[uuid:{0}] +# at: src/main/java/org/zstack/ovf/OvfHelper.java:117 +# args: capacity +Illegal\ disk\ capacity\:\ %s = Illegal disk capacity: {0} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:154 -# args: vmUuid,specMap.keySet() -failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ mdev\ specs[uuids\:%s]\ exist = failed to start vm[uuid:{0}] because not all mdev specs[uuids:{1}] exist +# at: src/main/java/org/zstack/ovf/OvfHelper.java:127 +# args: pSize +Illegal\ disk\ populated\ size\:\ %s = Illegal disk populated size: {0} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:205 -# args: vmUuid -no\ candidate\ host\ with\ enough\ spec\ related\ mdev\ devices\ for\ vm[uuid\:%s] = no candidate host with enough spec related mdev devices for vm[uuid:{0}] +# at: src/main/java/org/zstack/ovf/OvfHelper.java:288 +# args: +Volume\ controller\ not\ found. = Volume controller not found. -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:260 -# args: specUuid,hostUuid,vmUuid -failed\ to\ find\ enough\ pci\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = failed to find enough pci device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}] +# at: src/main/java/org/zstack/ovf/OvfHelper.java:320 +# args: +CD\ Driver\ controller\ not\ found. = CD Driver controller not found. -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:337 -# args: specUuid,hostUuid,vmUuid -failed\ to\ find\ enough\ mdev\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = failed to find enough mdev device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}] +# at: src/main/java/org/zstack/ovf/OvfHelper.java:368 +# args: name +Ethernet\ Adapter\:\ %s\ do\ not\ connect\ to\ a\ network. = Ethernet Adapter: {0} do not connect to a network. + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:380 +# args: +Memory\ 'InstanceID'\ not\ found = Memory 'InstanceID' not found -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:411 -# args: vmUuid,errorCode -failed\ to\ sort\ host\ candidates\ for\ vm\ [uuid\:%s]\ in\ HostDeviceAllocatorFlow\:\ %s = failed to sort host candidates for vm [uuid:{0}] in HostDeviceAllocatorFlow: {1} +# at: src/main/java/org/zstack/ovf/OvfHelper.java:387 +# args: +Memory\ 'VirtualQuantity'\ not\ found = Memory 'VirtualQuantity' not found -# at: src/main/java/org/zstack/pciDevice/PciDeviceAllocatorFactory.java:87 -# args: vo.getUuid(),vo.getHostUuid(),attachedPciUuid,dstHostUuid -specified\ pci\ devices\ not\ on\ same\ host\:\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = specified pci devices not on same host: pci device[uuid: {0}] on host[uuid: {1}] while pci device[uuid: {2}] on host[uuid: {3}] +# at: src/main/java/org/zstack/ovf/OvfHelper.java:392 +# args: quantity +Illegal\ Memory\ 'VirtualQuantity'\ value\:\ %s = Illegal Memory 'VirtualQuantity' value: {0} + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:401 +# args: +CPU\ 'InstanceID'\ not\ found = CPU 'InstanceID' not found + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:407 +# args: +CPU\ 'VirtualQuantity'\ not\ found = CPU 'VirtualQuantity' not found + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:412 +# args: quantity +Illegal\ CPU\ 'VirtualQuantity'\ value\:\ %s = Illegal CPU 'VirtualQuantity' value: {0} + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:422 +# args: cps +Illegal\ CPU\ 'CoresPerSocket'\ value\:\ %s = Illegal CPU 'CoresPerSocket' value: {0} + +# at: src/main/java/org/zstack/ovf/OvfImageUploadTracker.java:156 +# args: failLongJobUuids +long\ job[uuid\:%s]\ execute\ fail = long job[uuid:{0}] execute fail + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:69 +# args: msg.getVmUuid(),ovaUuid +Vm[uuid\:\ %s]\ is\ already\ exported\ as\ the\ ova\ package[uuid\:\ %s],\ please\ delete\ the\ package\ and\ try\ again. = Vm[uuid: {0}] is already exported as the ova package[uuid: {1}], please delete the package and try again. + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:77 +# args: msg.getBackupStorageUuid() +Export\ vm\ requires\ an\ ImageStore\ backup\ storage,\ but\ given\ backupStorageUuid\:\ %s\ is\ not\ an\ ImageStore\ backup\ storage. = Export vm requires an ImageStore backup storage, but given backupStorageUuid: {0} is not an ImageStore backup storage. + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:84 +# args: msg.getVmUuid() +Not\ found\ the\ vm\ to\ be\ exported\ with\ the\ uuid\:\ %s = Not found the vm to be exported with the uuid: {0} + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:89 +# args: VmInstanceState.Stopped.toString() +Only\ vm\ in\ state\:\ %s\ can\ be\ exported. = Only vm in state: {0} can be exported. + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:114 +# args: +failed\ to\ parse\ jsonCreateVmParam\ in\ APICreateVmInstanceFromOvfMsg = failed to parse jsonCreateVmParam in APICreateVmInstanceFromOvfMsg + +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:229 +# args: msg.getBackupStorageUuid(),msg.getVmUuid(),totalSize +backup\ storage[uuid\:\ %s]\ does\ not\ have\ enough\ available\ capacity\ for\ exporting\ vm[uuid\:\ %s],\ required\ capacity\ is\:\ %d = backup storage[uuid: {0}] does not have enough available capacity for exporting vm[uuid: {1}], required capacity is: {2} + +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:629 +# args: msg.getUuid() +ova\ package[uuid\:\ %s]\ not\ found. = ova package[uuid: {0}] not found. -# at: src/main/java/org/zstack/pciDevice/PciDeviceAllocatorFactory.java:140 +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:757 # args: -cannot\ find\ required\ pci\ device\ on\ hosts = cannot find required pci device on hosts +Failed\ to\ read\ ovf\ file. = Failed to read ovf file. -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:416 +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:1028 +# args: +failed\ to\ create\ VM\ from\ OVF\ because\ the\ root\ disk\ of\ the\ VM\ cannot\ be\ found = failed to create VM from OVF because the root disk of the VM cannot be found + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:417 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ doesn't\ exist = pci device[uuid:{0}] doesn't exist -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:426 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:422 +# args: pci.getHostUuid() +could\ not\ enable\ sriov\ for\ device\ because\ iommu\ is\ disabled\ on\ host[uuid\:%s] = could not enable sriov for device because iommu is disabled on host[uuid:{0}] + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:468 # args: pci.getHostUuid() pci\ devices\ in\ host[uuid\:%s]\ already\ sriov\ virtualized = pci devices in host[uuid:{0}] already sriov virtualized -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:437 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:473 # args: pci.getHostUuid() cannot\ sr-iov\ virtualize\ pci\ devices\ in\ host[uuid\:%s]\ that\ are\ attached\ to\ vm = cannot sr-iov virtualize pci devices in host[uuid:{0}] that are attached to vm -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:457 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:487 # args: minIns,pci.getType(),pci.getHostUuid() only\ %d\ virtual\ pci\ devices\ can\ be\ generated\ by\ %ss\ in\ host[uuid\:%s] = only {0} virtual pci devices can be generated by {1}s in host[uuid:{2}] -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:569 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:609 # args: pci.getHostUuid(),pci.getUuid() the\ host[uuid\:%s]\ that\ pci\ device[uuid\:%s]\ in\ is\ not\ Connected = the host[uuid:{0}] that pci device[uuid:{1}] in is not Connected -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:477 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:505 +# args: interfaceVO.getUuid() +cannot\ sr-iov\ virtualize\ pci\ devices\ on\ interface[uuid\:%s]\ that\ are\ been\ bonded = cannot sr-iov virtualize pci devices on interface[uuid:{0}] that are been bonded + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:513 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ not\ sriov\ virtualized = pci device[uuid:{0}] doesn't exist or is not sriov virtualized -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:488 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:528 # args: pci.getHostUuid() virtual\ pci\ devices\ generated\ from\ pci\ devices\ in\ host[uuid\:%s]\ still\ attached\ to\ vm = virtual pci devices generated from pci devices in host[uuid:{0}] still attached to vm -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:510 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:550 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ cannot\ be\ virtualized\ into\ mdevs,\ make\ sure\ it's\ enabled\ and\ un-attached = pci device[uuid:{0}] cannot be virtualized into mdevs, make sure it's enabled and un-attached -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:521 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:561 # args: msg.getPciDeviceUuid(),msg.getMdevSpecUuid() pci\ device[uuid\:%s]\ cannot\ be\ virtualized\ by\ mdev\ spec[uuid\:%s] = pci device[uuid:{0}] cannot be virtualized by mdev spec[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:543 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:583 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ is\ not\ virtualized\ into\ mdevs = pci device[uuid:{0}] is not virtualized into mdevs -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:560 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:600 # args: msg.getPciDeviceUuid() mdev\ devices\ generated\ from\ pci\ device[uuid\:%s]\ still\ attached\ to\ vm = mdev devices generated from pci device[uuid:{0}] still attached to vm -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:989 -# args: spec.getType(),PciDeviceType.leagalPciDeviceCandidateTypes -illegal\ type[%s]\ for\ pci\ device\ spec,\ only\ %s\ are\ legal = illegal type[{0}] for pci device spec, only {1} are legal +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:624 +# args: VmInstanceUuid +please\ umount\ all\ GPU\ devices\ of\ the\ vm[%s]\ and\ try\ again = please umount all GPU devices of the vm[{0}] and try again + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:628 +# args: VmInstanceUuid +please\ umount\ all\ vGPU\ devices\ of\ the\ vm[%s]\ and\ try\ again = please umount all vGPU devices of the vm[{0}] and try again + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:635 +# args: VmInstanceUuid +please\ umount\ other\ pci\ devices\ of\ the\ vm[%s]\ and\ try\ again = please umount other pci devices of the vm[{0}] and try again + +# at: src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java:59 +# args: vo.getUuid(),vo.getHostUuid(),attachedPciUuid,dstHostUuid +specified\ pci\ devices\ not\ on\ same\ host\:\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = specified pci devices not on same host: pci device[uuid: {0}] on host[uuid: {1}] while pci device[uuid: {2}] on host[uuid: {3}] + +# at: src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java:92 +# args: +no\ candidate\ host\ with\ enough\ pci\ devices = no candidate host with enough pci devices + +# at: src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java:123 +# args: vmUuid,specMap.keySet() +failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ pci\ specs[uuids\:%s]\ exist = failed to start vm[uuid:{0}] because not all pci specs[uuids:{1}] exist -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:978 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1319 # args: vo.getType(),PciDeviceType.leagalPciDeviceCandidateTypes illegal\ type[%s]\ for\ pci\ device,\ only\ %s\ are\ legal = illegal type[{0}] for pci device, only {1} are legal -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:637 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:719 +# args: specUuid,hostUuid,vmUuid +failed\ to\ find\ enough\ pci\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = failed to find enough pci device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}] + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:782 +# args: pciUuid +something\ wrong\ with\ iommu\ group\ of\ pci\ device[uuid\:%s] = something wrong with iommu group of pci device[uuid:{0}] + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:795 +# args: pciUuids +pci\ devices\ [%s]\ are\ not\ all\ available = pci devices [{0}] are not all available + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:928 # args: msg.getPciDeviceUuid(),msg.getVmInstanceUuid() can\ not\ attach\ this\ pci\ device[uuid\:%s]\ to\ vm[uuid\:%s]\ due\ to\ host\ allocation = can not attach this pci device[uuid:{0}] to vm[uuid:{1}] due to host allocation -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:910 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1221 # args: msg.getVmInstanceUuid() can\ not\ migrate\ vm[uuid\:%s]\ since\ pci\ device\ attached = can not migrate vm[uuid:{0}] since pci device attached -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:941 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1270 # args: msg.getVolumeUuid() cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ pci\ devices\ attached = cannot migrate root volume[uuid:{0}] because there are pci devices attached -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1167 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1316 +# args: pciDeviceUuid +pci\ device[uuid\:%s]\ doesn't\ exists = pci device[uuid:{0}] doesn't exists + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1330 +# args: pciSpecUuid +pci\ device\ spec[uuid\:%s]\ doesn't\ exists = pci device spec[uuid:{0}] doesn't exists + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1511 # args: pciUuid,vmUuid pci\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled\ for\ vm[uuid\:%s] = pci device[uuid:{0}] doesn't exist or is disabled for vm[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1176 -# args: pciUuid,vo.getVmInstanceUuid(),vmUuid -pci\ device[uuid\:%s]\ already\ attached\ to\ vm[uuid\:%s],\ cannot\ attach\ to\ vm[uuid\:%s] = pci device[uuid:{0}] already attached to vm[uuid:{1}], cannot attach to vm[uuid:{2}] - -# at: src/main/java/org/zstack/pciDevice/PciDeviceReserveFlow.java:732 -# args: pciDeviceUuid, vmInstanceUuid +# at: src/main/java/org/zstack/pciDevice/PciDeviceReserveFlow.java:161 +# args: wrongStatusPciUuids,vmUuid pci\ device[uuid\:%s]\ can\ not\ attach\ to\ vm[uuid\:%s]\ due\ to\ wrong\ status = pci device[uuid:{0}] can not attach to vm[uuid:{1}] due to wrong status -# at: src/main/java/org/zstack/pciDevice/PciHostChangeStateExtension.java:58 +# at: src/main/java/org/zstack/pciDevice/PciHostChangeStateExtension.java:69 # args: inventory.getUuid(),hasPciVmUuids.toString() The\ host\ [%s]\ has\ failed\ to\ enter\ the\ maintenance,\ The\ vm\ [%s]\ cannot\ migrate\ automatically\ because\ it\ contains\ the\ PCI\ device = The host [{0}] has failed to enter the maintenance, The vm [{1}] cannot migrate automatically because it contains the PCI device +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java:185 +# args: vo.getType(),PciDeviceType.leagalPciDeviceCandidateTypes +illegal\ type[%s]\ for\ pci\ device\ spec,\ only\ %s\ are\ legal = illegal type[{0}] for pci device spec, only {1} are legal + # at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java:258 # args: vmUuid,state vm\ instance[uuid\:%s,\ state\:%s]\ needs\ to\ be\ stopped\ to\ set\ pci\ device\ spec = vm instance[uuid:{0}, state:{1}] needs to be stopped to set pci device spec @@ -5654,138 +9526,166 @@ vm[uuid\:%s]\ doesn't\ have\ mdev\ device\ spec[uuid\:%s] = vm[uuid:{0}] doesn't # args: vm.getUuid(),vm.getState(),msg.getMdevSpecUuid() vm\ instance[uuid\:%s,\ state\:%s]\ needs\ to\ be\ stopped\ to\ remove\ mdev\ device\ spec[uuid\:%s] = vm instance[uuid:{0}, state:{1}] needs to be stopped to remove mdev device spec[uuid:{2}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:373 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:374 # args: msg.getPciSpecUuid(),msg.getVmInstanceUuid() pci\ device\ spec[uuid\:%s]\ is\ not\ available\ for\ vm[uuid\:%s] = pci device spec[uuid:{0}] is not available for vm[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:371 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:372 # args: msg.getVmInstanceUuid() no\ pci\ device\ spec\ available\ for\ vm[uuid\:%s] = no pci device spec available for vm[uuid:{0}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:366 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:367 # args: msg.getVmInstanceUuid(),rly.getError() failed\ to\ get\ pci\ device\ spec\ available\ for\ vm[uuid\:%s]\:\ %s = failed to get pci device spec available for vm[uuid:{0}]: {1} -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:454 -# args: pciUuidsNotMatch,msg.getVmInstanceUuid(),vmUuidsPciAttached -pci\ devices[uuid\:%s]\ should\ have\ been\ attached\ to\ vm[uuid\:%s]\ but\ it\ is\ attached\ to\ vm[uuid\:%s] = pci devices[uuid:{0}] should have been attached to vm[uuid:{1}] but it is attached to vm[uuid:{2}] - -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:565 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:557 # args: msg.getMdevSpecUuid(),msg.getVmInstanceUuid() mdev\ device\ spec[uuid\:%s]\ is\ not\ available\ for\ vm[uuid\:%s] = mdev device spec[uuid:{0}] is not available for vm[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:558 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:550 # args: msg.getVmInstanceUuid() no\ mdev\ device\ spec\ available\ for\ vm[uuid\:%s] = no mdev device spec available for vm[uuid:{0}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:779 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:751 # args: specUuid,systemTag pci\ device\ spec[uuid\:%s]\ doesn't\ exist = pci device spec[uuid:{0}] doesn't exist -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:792 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:764 # args: specUuid,systemTag mdev\ device\ spec[uuid\:%s]\ doesn't\ exist = mdev device spec[uuid:{0}] doesn't exist -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:153 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:191 # args: cluster\ uuids\ or\ host\ uuid\ or\ vm\ uuid\ can\ not\ be\ set\ at\ same\ time = cluster uuids or host uuid or vm uuid can not be set at same time -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:160 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:198 # args: clusters\ not\ exist\ or\ disabled = clusters not exist or disabled -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:194 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:232 # args: type,legalTypes illegal\ mdev\ device\ type\ [%s],\ only\ %s\ are\ legal = illegal mdev device type [{0}], only {1} are legal -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:67 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:69 # args: cannot\ change\ the\ state\ of\ mdev\ device\ that's\ in\ attached\ status = cannot change the state of mdev device that's in attached status -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:75 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:77 # args: msg.getMdevDeviceUuid() cannot\ attach\ mdev\ device[uuid\:%s]\ to\ vm,\ make\ sure\ it's\ enabled\ and\ un-attached = cannot attach mdev device[uuid:{0}] to vm, make sure it's enabled and un-attached -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:182 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:220 # args: cannot\ attach\ mdev\ device\ to\ vm\ instance\ that's\ not\ stopped = cannot attach mdev device to vm instance that's not stopped -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:95 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:103 # args: msg.getVmInstanceUuid(),msg.getMdevDeviceUuid() vm[uuid\:%s]\ has\ pci\ devices\ attached\ that\ are\ in\ different\ host\ with\ mdev\ device[uuid\:%s] = vm[uuid:{0}] has pci devices attached that are in different host with mdev device[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:105 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:113 # args: msg.getVmInstanceUuid(),msg.getMdevDeviceUuid() vm[uuid\:%s]\ has\ mdev\ devices\ attached\ that\ are\ in\ different\ host\ with\ mdev\ device[uuid\:%s] = vm[uuid:{0}] has mdev devices attached that are in different host with mdev device[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:112 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:168 # args: mdev.getHostUuid(),mdev.getUuid(),HostState.Enabled,HostStatus.Connected the\ host[uuid\:%s]\ that\ holds\ mdev\ device[uuid\:%s]\ is\ not\ [%s]\ and\ [%s] = the host[uuid:{0}] that holds mdev device[uuid:{1}] is not [{2}] and [{3}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:121 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:132 +# args: msg.getVmInstanceUuid(),mdev.getUuid() +the\ vm[uuid\:%s]\ that\ holds\ se\ mdev\ device\ can\ not\ attach\ more\ se\ mdev[%s] = the vm[uuid:{0}] that holds se mdev device can not attach more se mdev[{1}] + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:143 # args: mdev.getHostUuid(),mdev.getUuid(),HostState.Enabled,HostStatus.Connected IOMMU\ of\ the\ host[uuid\:%s]\ that\ hosts\ pci\ device[uuid\:%s]\ is\ not\ [%s]\ and\ [%s] = IOMMU of the host[uuid:{0}] that hosts pci device[uuid:{1}] is not [{2}] and [{3}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:134 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:156 # args: msg.getMdevDeviceUuid(),msg.getVmInstanceUuid() mdev\ device\ [uuid\:%s]\ is\ not\ attached\ to\ vm[uuid\:%s] = mdev device [uuid:{0}] is not attached to vm[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:143 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:181 # args: cannot\ detach\ mdev\ device\ from\ vm\ instance\ when\ it's\ not\ stopped = cannot detach mdev device from vm instance when it's not stopped -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:111 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:245 +# args: +cannot\ delete\ mdev\ device\ when\ it's\ attached = cannot delete mdev device when it's attached + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:379 +# args: msg.getVmInstanceUuid(),reply.getError() +failed\ to\ get\ candidate\ hosts\ to\ start\ vm[uuid\:%s],\ %s = failed to get candidate hosts to start vm[uuid:{0}], {1} + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:100 +# args: mdevUuid +mdev\ device\ [%s]\ is\ not\ available = mdev device [{0}] is not available + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:217 +# args: rsp.getError() +failed\ to\ hot\ plug\ mdev\ device\ to\ running\ vm,\ because\:%s = failed to hot plug mdev device to running vm, because:{0} + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:278 # args: msg.getVmInstanceUuid(),msg.getMdevDeviceUuid() vm[uuid\:%s]\ cannot\ start\ in\ host\ that\ hold\ mdev\ device[uuid\:%s] = vm[uuid:{0}] cannot start in host that hold mdev device[uuid:{1}] +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:353 +# args: rsp.getError() +failed\ to\ hot\ unplug\ mdev\ device\ to\ running\ vm,\ because\:%s = failed to hot unplug mdev device to running vm, because:{0} + # at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFactory.java:68 # args: pciDevice.getUuid(),PciDeviceVirtStatus.VFIO_MDEV_VIRTUALIZED pci\ device[uuid\:%s]\ is\ known\ as\ %s,\ but\ cannot\ find\ it's\ mdev\ spec,\ so\ abort. = pci device[uuid:{0}] is known as {1}, but cannot find it's mdev spec, so abort. +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java:48 +# args: vmUuid,specMap.keySet() +failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ mdev\ specs[uuids\:%s]\ exist = failed to start vm[uuid:{0}] because not all mdev specs[uuids:{1}] exist + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java:145 +# args: mdev.getUuid(),mdev.getHostUuid(),attachedMdevUuid,dstHostUuid +specified\ mdev\ devices\ not\ on\ same\ host\:\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = specified mdev devices not on same host: mdev device[uuid: {0}] on host[uuid: {1}] while mdev device[uuid: {2}] on host[uuid: {3}] + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java:184 +# args: +no\ candidate\ host\ with\ enough\ mdev\ devices = no candidate host with enough mdev devices + # at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceHostChangeStateExtension.java:55 # args: inventory.getUuid(),hasMdevVmUuids.toString() The\ host\ [%s]\ has\ failed\ to\ enter\ the\ maintenance,\ because\ vm[%s]\ has\ mdev\ devices\ attached\ and\ cannot\ migrate\ automatically = The host [{0}] has failed to enter the maintenance, because vm[{1}] has mdev devices attached and cannot migrate automatically -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:133 -# args: msg.getVmInstanceUuid(),rly.getError() -failed\ to\ get\ candidate\ hosts\ to\ start\ vm[uuid\:%s],\ %s = failed to get candidate hosts to start vm[uuid:{0}], {1} +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:308 +# args: specUuid,hostUuid,vmUuid +failed\ to\ find\ enough\ mdev\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = failed to find enough mdev device of spec[uuid:{0}] in dest host[uuid:{1}] for vm[uuid:{2}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:231 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:352 # args: msg.getMdevDeviceUuid() cannot\ find\ mdev\ device[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find mdev device[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:403 -# args: mdevUuid,vmUuid +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:555 +# args: vo.getUuid(),vmUuid mdev\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled\ for\ vm[uuid\:%s] = mdev device[uuid:{0}] doesn't exist or is disabled for vm[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:412 -# args: mdevUuid,vo.getVmInstanceUuid(),vmUuid -mdev\ device[uuid\:%s]\ already\ attached\ to\ vm[uuid\:%s],\ cannot\ attach\ to\ vm\ [uuid\:%s] = mdev device[uuid:{0}] already attached to vm[uuid:{1}], cannot attach to vm [uuid:{2}] - -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:509 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:644 # args: msg.getVmInstanceUuid() can\ not\ migrate\ vm[uuid\:%s]\ since\ mdev\ device\ attached = can not migrate vm[uuid:{0}] since mdev device attached -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:538 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:673 # args: msg.getVolumeUuid() cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ mdev\ devices\ attached = cannot migrate root volume[uuid:{0}] because there are mdev devices attached -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:553 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:688 # args: msg.getVmInstanceUuid() cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ mdev\ devices\ attached = cannot migrate vm[uuid:{0}] because there are mdev devices attached -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:796 -# args: mdev.getUuid(),mdev.getHostUuid(),attachedMdevUuid,dstHostUuid -specified\ mdev\ devices\ not\ on\ same\ host\:\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = specified mdev devices not on same host: mdev device[uuid: {0}] on host[uuid: {1}] while mdev device[uuid: {2}] on host[uuid: {3}] - -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:829 -# args: -no\ candidate\ host\ with\ enough\ mdev\ devices = no candidate host with enough mdev devices +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceReserveFlow.java:129 +# args: wrongStatusMdevUuids,vmUuid +mdev\ device[uuid\:%s]\ can\ not\ attach\ to\ vm[uuid\:%s]\ due\ to\ wrong\ status = mdev device[uuid:{0}] can not attach to vm[uuid:{1}] due to wrong status -# at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostAllocatorFlow.java:70 -# args: maxInstancePerHost +# at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostAllocatorFlow.java:71 +# args: String.format("maxInstancePerHost = %d", maxInstancePerHost) No\ host\ with\ fewer\ than\ %s\ vms\ found = No host with fewer than {0} vms found +# at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java:76 +# args: HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN +%s\ must\ be\ a\ number = {0} must be a number + # at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java:58 # args: HostAllocatorConstant.MAX_INSTANCE_PER_HOST_HOST_ALLOCATOR_STRATEGY_TYPE,HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN Select\ %s\ strategy,\ you\ must\ set\ %s = Select {0} strategy, you must set {1} @@ -5794,115 +9694,147 @@ Select\ %s\ strategy,\ you\ must\ set\ %s = Select {0} strategy, you must set {1 # args: HostAllocatorSystemTags.MINIMUM_MEMORY_USAGE_HOST_ALLOCATOR_STRATEGY_MODE_TOKEN,modes Incorrect\ %s\ settings,\ valid\ value\ is\ %s = Incorrect {0} settings, valid value is {1} -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:326 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:93 +# args: +default\ route\ network\ can\ not\ be\ changed\ when\ system\ policy\ route\ is\ enabled = default route network can not be changed when system policy route is enabled + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:382 # args: can\ not\ find\ related\ virtual\ router = can not find related virtual router -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:117 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:132 # args: msg.getL3Uuid() l3[%s]\ already\ attached\ a\ policy\ route\ ruleSet = l3[{0}] already attached a policy route ruleSet -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:168 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:192 # args: msg.getvRouterUuid(),msg.getName() VRouter[%s]\ already\ has\ a\ ruleSet\ named\ %s = VRouter[{0}] already has a ruleSet named {1} -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:174 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:283 +# args: +can\ not\ update\ system\ policy\ route\ set = can not update system policy route set + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:198 # args: msg.getDestinationCidr() DestinationCidr\ must\ be\ in\ cidr\ format\ but\ found\ [%s] = DestinationCidr must be in cidr format but found [{0}] -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:178 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:202 # args: msg.getNextHopIp() NextHopIp\ must\ be\ in\ ipv4\ format\ but\ found\ [%s] = NextHopIp must be in ipv4 format but found [{0}] -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:249 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:278 # args: can\ not\ find\ related\ vRouter = can not find related vRouter -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:271 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:288 +# args: +can\ not\ update\ system\ policy\ route\ table = can not update system policy route table + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:237 +# args: ip +operation\ failure,\ ip\ format\ only\ supports\ ipv4/iprange/cidr,\ but\ find\ %s = operation failure, ip format only supports ipv4/iprange/cidr, but find {0} + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:245 +# args: protocol +illegal\ protocol\ type\ %s = illegal protocol type {0} + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:254 +# args: msg.getRuleSetUuid(),msg.getRuleNumber() +RuleSet[%s]\ already\ has\ a\ rule\ with\ rule\ number\ %s. = RuleSet[{0}] already has a rule with rule number {1}. + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:310 # args: msg.getvRouterUuid(),msg.getNumber() VRouter[%s]\ already\ has\ a\ policy\ route\ table\ [%s] = VRouter[{0}] already has a policy route table [{1}] -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:309 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:387 +# args: +can\ not\ delete\ system\ policy\ route\ table = can not delete system policy route table + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:371 +# args: +can\ not\ delete\ system\ policy\ route\ set = can not delete system policy route set + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:360 # args: msg.getUuid() ruleSet[%s]\ is\ still\ attached\ to\ nic = ruleSet[{0}] is still attached to nic -# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:743 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:958 # args: vrouterVmUuid virtual\ router[uuid\:%s]\ can\ not\ find = virtual router[uuid:{0}] can not find -# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:748 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:963 # args: vo.getApplianceVmType() can\ not\ find\ service\ factory\ for\ virtual\ router\ type[%s] = can not find service factory for virtual router type[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:47 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:54 # args: msg.getMirrorNetworkUuid() Invalid\ parameter\ [%s],\ make\ sure\ it's\ PortMirror\ Network = Invalid parameter [{0}], make sure it's PortMirror Network -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:55 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:62 # args: msg.getMirrorNetworkUuid() The\ network[%s]\ has\ been\ attached\ with\ a\ PortMirror\ service = The network[{0}] has been attached with a PortMirror service -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:63 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:70 # args: msg.getUuid() The\ PortMirror\ service[%s]\ has\ not\ been\ created = The PortMirror service[{0}] has not been created -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:99 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:86 # args: msg.getSrcEndPoint(),msg.getDstEndPoint(),mirror.getUuid() The\ nic[%s,\ %s]\ has\ been\ mirrored\ by\ service[%s] = The nic[{0}, {1}] has been mirrored by service[{2}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:105 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:92 # args: msg.getSrcEndPoint(),mirror.getUuid() The\ nic[%s]\ can't\ been\ mirrored\ for\ service[%s]\ using = The nic[{0}] can't been mirrored for service[{1}] using -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:122 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:109 # args: msg.getSrcEndPoint() The\ PortMirror\ service\ doesn't\ support\ to\ mirror\ the\ nic[%s] = The PortMirror service doesn't support to mirror the nic[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:127 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:114 # args: msg.getDstEndPoint() The\ PortMirror\ service\ doesn't\ support\ the\ nic[%s]\ because\ of\ its\ hypervisor\ type = The PortMirror service doesn't support the nic[{0}] because of its hypervisor type -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:134 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:121 # args: msg.getDstEndPoint() The\ PortMirror\ service\ can't\ mirror\ to\ the\ nic[%s]\ that\ is\ not\ a\ non-default\ interface\ of\ a\ vm = The PortMirror service can't mirror to the nic[{0}] that is not a non-default interface of a vm -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:141 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:128 # args: msg.getSrcEndPoint() The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ that\ is\ not\ an\ interface\ of\ any\ vm = The PortMirror service can't mirror the nic[{0}] that is not an interface of any vm -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:151 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:138 # args: msg.getSrcEndPoint(),msg.getDstEndPoint(),vo.getMirrorNetworkUuid() The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ \ to\ nic[%s]\ because\ the\ mirror\ network[%s]\ can't\ setup\ the\ mirror\ tunnel = The PortMirror service can't mirror the nic[{0}] to nic[{1}] because the mirror network[{2}] can't setup the mirror tunnel -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:157 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:144 # args: msg.getSrcEndPoint() The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ to\ itself = The PortMirror service can't mirror the nic[{0}] to itself -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:163 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:153 # args: The\ PortMirror\ service\ can't\ work\ at\ the\ nic\ with\ configured\ Qos = The PortMirror service can't work at the nic with configured Qos -# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:750 +# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:761 # args: sessionVO.getUuid(),errorCode.getDetails() failed\ to\ delete\ portMirror\ session[%s]\ from\ hypervisor,\ detail\:\ %s = failed to delete portMirror session[{0}] from hypervisor, detail: {1} -# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:783 +# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:794 # args: sessionVO.getUuid(),errorCode.getDetails() failed\ to\ release\ portMirror\ session[%s]\ from\ hypervisor,\ detail\:\ %s = failed to release portMirror session[{0}] from hypervisor, detail: {1} -# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:901 +# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:912 # args: vo.getUuid() cannot\ find\ internal\ id\ of\ the\ session[uuid\:%s],\ are\ there\ too\ many\ sessions\ in\ a\ host??? = cannot find internal id of the session[uuid:{0}], are there too many sessions in a host??? -# at: src/main/java/org/zstack/portal/apimediator/ApiMediatorImpl.java:246 +# at: src/main/java/org/zstack/portal/apimediator/ApiMediatorImpl.java:276 # args: cmsg.getResourceUuid() -resourceUuid[%s]\ is\ not\ a\ valid\ uuid.\ A\ valid\ uuid\ is\ a\ UUID(v4\ recommended)\ with\ '-'\ stripped.\ see\ http\://en.wikipedia.org/wiki/Universally_unique_identifier\ for\ format\ of\ UUID,\ the\ regular\ expression\ ZStack\ uses\ to\ validate\ a\ UUID\ is\ '[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}' = resourceUuid[{0}] is not a valid uuid. A valid uuid is a UUID(v4 recommended) with '-' stripped. see http://en.wikipedia.org/wiki/Universally_unique_identifier for format of UUID, the regular expression ZStack uses to validate a UUID is '[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}' +resourceUuid[%s]\ is\ not\ a\ valid\ uuid.\ A\ valid\ uuid\ is\ a\ uuid(v4\ recommended)\ with\ '-'\ stripped.\ see\ http\://en.wikipedia.org/wiki/Universally_unique_identifier\ for\ format\ of\ uuid,\ the\ regular\ expression\ uses\ to\ validate\ a\ uuid\ is\ '[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}' = resourceUuid[{0}] is not a valid uuid. A valid uuid is a uuid(v4 recommended) with '-' stripped. see http://en.wikipedia.org/wiki/Universally_unique_identifier for format of uuid, the regular expression uses to validate a uuid is '[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}' # at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java:122 # args: method non\ support\ method\:\ %s = non support method: {0} -# at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java:135 +# at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java:134 # args: statusCode,response.getStatusLine().getReasonPhrase() http\ request\ error!\ status_code\:\ %s,\ error\:\ %s = http request error! status_code: {0}, error: {1} @@ -5922,11 +9854,11 @@ cannot\ copy\ %s\ to\ %s,\ caused\:\ %s = cannot copy {0} to {1}, caused: {2} # args: ssh\ failed = ssh failed -# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:106 +# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:124 # args: v.getClass().getSimpleName(),k unknown\ value\ type\ %s,\ key\ \=\ %s = unknown value type {0}, key = {1} -# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:132 +# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:153 # args: failed\ to\ HTTP\ call\ all\ prometheus\ instances = failed to HTTP call all prometheus instances @@ -5942,47 +9874,47 @@ the\ operation\ is\ denied\ by\ black\ list\ of\ virtual-id[uuid\:%s] = the oper # args: unmatchedApis,identity.toString() action\:\ %s,\ is\ not\ supported\ for\ role\ identity\:\ %s = action: {0}, is not supported for role identity: {1} -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:341 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:372 # args: msg.getName() %s\ is\ a\ reserved\ name,\ please\ use\ another\ name = {0} is a reserved name, please use another name -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:339 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:370 # args: the\ name\ of\ initial\ user\ can\ not\ be\ updated = the name of initial user can not be updated -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:376 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:407 # args: cannot\ remove\ builtin\ system\ admin\ role\ from\ builtin\ system\ admin. = cannot remove builtin system admin role from builtin system admin. -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:374 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:405 # args: cannot\ remove\ builtin\ security\ admin\ role\ from\ builtin\ security\ admin. = cannot remove builtin security admin role from builtin security admin. -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:372 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:403 # args: cannot\ remove\ builtin\ audit\ admin\ role\ from\ builtin\ audit\ admin. = cannot remove builtin audit admin role from builtin audit admin. -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:386 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:417 # args: cannot\ delete\ builtin\ system\ admin. = cannot delete builtin system admin. -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:384 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:415 # args: cannot\ delete\ builtin\ security\ admin. = cannot delete builtin security admin. -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:382 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:413 # args: cannot\ delete\ builtin\ audit\ admin. = cannot delete builtin audit admin. -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:399 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:430 # args: Confirm\ the\ roles\ you\ want\ to\ add\ have\ same\ identity = Confirm the roles you want to add have same identity -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:413 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:444 # args: msg.getRoleUuids(),identitySet,msg.getVirtualIDUuid() Cannot\ add\ role\:\ %s\ with\ identity\:\ %s\ to\ virtualID[uuid\:%s] = Cannot add role: {0} with identity: {1} to virtualID[uuid:{2}] -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:425 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:456 # args: String.join(",", privilegeAdminUuids),msg.getProjectUuid() can\ not\ add\ privilege\ admin[uuids\:%s]\ to\ project[uuid\:%s] = can not add privilege admin[uuids:{0}] to project[uuid:{1}] @@ -6002,30 +9934,38 @@ entity\ meta\ class[%s]\ has\ no\ field[%s] = entity meta class[{0}] has no fiel # args: f,info.inventoryClass.getSimpleName(),info.premitiveFieldNames field[%s]\ is\ not\ a\ primitive\ of\ the\ inventory\ %s;\ you\ cannot\ specify\ it\ in\ the\ parameter\ 'fields';valid\ fields\ are\ %s = field[{0}] is not a primitive of the inventory {1}; you cannot specify it in the parameter 'fields';valid fields are {2} -# at: src/main/java/org/zstack/query/QueryFacadeImpl.java:496 +# at: src/main/java/org/zstack/query/QueryFacadeImpl.java:519 +# args: +filterName\ must\ be\ formatted\ as\ [filterType\:condition(s)] = filterName must be formatted as [filterType:condition(s)] + +# at: src/main/java/org/zstack/query/QueryFacadeImpl.java:659 # args: JSONObjectUtil.toJsonString(cond) 'value'\ of\ query\ condition\ %s\ cannot\ be\ null = 'value' of query condition {0} cannot be null -# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:326 +# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:273 +# args: typeByResourceUuids.toString() +resources\ has\ inconsistent\ resourceTypes.\ Details\:\ %s = resources has inconsistent resourceTypes. Details: {0} + +# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:433 # args: resourceUuid cannot\ find\ resource[uuid\:\ %s] = cannot find resource[uuid: {0}] -# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:330 +# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:437 # args: globalConfig.getCategory(),globalConfig.getName(),resourceType ResourceConfig\ [category\:%s,\ name\:%s]\ cannot\ bind\ to\ resourceType\:\ %s = ResourceConfig [category:{0}, name:{1}] cannot bind to resourceType: {2} -# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:60 -# args: msg.getResourceUuid() -account\ has\ no\ access\ to\ the\ resource[uuid\:\ %s] = account has no access to the resource[uuid: {0}] - -# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:43 -# args: msg.getCategory(),msg.getName() +# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:85 +# args: msg.getCategory(),identity no\ global\ config[category\:%s,\ name\:%s]\ found = no global config[category:{0}, name:{1}] found -# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:49 -# args: msg.getCategory(),msg.getName() +# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:91 +# args: msg.getCategory(),identity global\ config[category\:%s,\ name\:%s]\ cannot\ bind\ resource = global config[category:{0}, name:{1}] cannot bind resource +# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:114 +# args: msg.getResourceUuid() +account\ has\ no\ access\ to\ the\ resource[uuid\:\ %s] = account has no access to the resource[uuid: {0}] + # at: src/main/java/org/zstack/rest/TypeVerifier.java:22 # args: f.getName(),source [%s]\ field\ is\ excepted\ an\ int\ or\ long,\ but\ was\ [%s]. = [{0}] field is excepted an int or long, but was [{1}]. @@ -6034,6 +9974,10 @@ global\ config[category\:%s,\ name\:%s]\ cannot\ bind\ resource = global config[ # args: f.getName(),source Invalid\ value\ for\ boolean\ field\ [%s],\ [%s]\ is\ not\ a\ valid\ boolean\ string[true,\ false]. = Invalid value for boolean field [{0}], [{1}] is not a valid boolean string[true, false]. +# at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:141 +# args: msg.getvRouterUuid() +All\ the\ networks\ should\ be\ in\ the\ virtual\ router[%s] = All the networks should be in the virtual router[{0}] + # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:69 # args: msg.getAreaId() [%s]\ is\ not\ formatted\ as\ IPv4\ address = [{0}] is not formatted as IPv4 address @@ -6074,187 +10018,239 @@ Router\ ID[%s]\ is\ not\ formatted\ as\ IPv4\ address = Router ID[{0}] is not fo # args: msg.getRouterId() Router\ ID[%s]\ is\ not\ unique\ in\ this\ system = Router ID[{0}] is not unique in this system -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:188 +# at: src/main/java/org/zstack/scheduler/AbstractSchedulerJob.java:235 +# args: +the\ last\ job\ is\ not\ completed.\ skip\ this\ job = the last job is not completed. skip this job + +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:189 # args: cron\ must\ be\ set\ when\ use\ cron\ scheduler = cron must be set when use cron scheduler -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:194 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:195 # args: cron\ task\ must\ follow\ format\ like\ this\ \:\ \"0\ 0/3\ 17-23\ *\ *\ ?\"\ = cron task must follow format like this : \"0 0/3 17-23 * * ?\" -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:197 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:198 # args: cron\ scheduler\ only\ need\ to\ specify\ cron\ task = cron scheduler only need to specify cron task -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:206 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:207 # args: startTime\ out\ of\ range = startTime out of range -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:202 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:203 # args: startTime\ must\ be\ positive\ integer\ or\ 0 = startTime must be positive integer or 0 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:183 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:184 # args: stopTime\ has\ been\ passed = stopTime has been passed -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:181 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:182 # args: stopTime\ out\ of\ mysql\ timestamp\ range = stopTime out of mysql timestamp range -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:179 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:180 # args: duration\ time\ out\ of\ range = duration time out of range -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:98 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:99 # args: interval\ must\ be\ set\ when\ use\ simple\ scheduler\ when\ repeat\ more\ than\ once = interval must be set when use simple scheduler when repeat more than once -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:133 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:134 # args: msg.getSchedulerJobUuid(),msg.getSchedulerTriggerUuid() Can\ not\ add\ job[uuid\:%s]\ twice\ to\ the\ same\ trigger[uuid\:%s] = Can not add job[uuid:{0}] twice to the same trigger[uuid:{1}] -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:138 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:139 # args: msg.getSchedulerJobUuid(),msg.getSchedulerTriggerUuid() Can\ not\ add\ job[uuid\:%s]\ to\ a\ out\ of\ time\ trigger[uuid\:%s] = Can not add job[uuid:{0}] to a out of time trigger[uuid:{1}] -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:146 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:147 # args: count,msg.getSchedulerJobUuid() There\ are\ [%d]\ triggers\ added\ to\ job[uuid\:%s],\ cannot\ add\ any\ more. = There are [{0}] triggers added to job[uuid:{1}], cannot add any more. -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:161 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:162 # args: count,msg.getSchedulerJobGroupUuid() There\ are\ [%d]\ triggers\ added\ to\ job\ group[uuid\:%s],\ cannot\ add\ any\ more. = There are [{0}] triggers added to job group[uuid:{1}], cannot add any more. -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:191 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:192 # args: invalid\ cron\ expression = invalid cron expression -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:171 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:172 # args: startTime\ must\ be\ set\ for\ simple\ scheduler = startTime must be set for simple scheduler -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:175 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:176 # args: schedulerInterval\ must\ be\ set\ for\ simple\ scheduler = schedulerInterval must be set for simple scheduler -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:239 -# args: msg.getParameters().get(SchedulerJobParameters.snapshotMax),e.getMessage() -snapshotMaxNumber\ \:\ %s\ format\ error\ because\ %s = snapshotMaxNumber : {0} format error because {1} +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:226 +# args: msg.getType() +No\ SchedulerJobFactory\ of\ type[%s]\ found = No SchedulerJobFactory of type[{0}] found -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:265 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:253 # args: n %d\ jobs\ have\ different\ job\ type\ with\ job\ group = {0} jobs have different job type with job group -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:274 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:262 # args: count,limit - count job\ group\ has\ contained\ %d\ job,\ only\ %d\ seats\ left = job group has contained {0} job, only {1} seats left -# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:500 +# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:794 +# args: timeUnitInStr +invalid\ time\ unit\:\ %s = invalid time unit: {0} + +# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:921 # args: jobUuid,e.getMessage() trigger\ job[uuid\:\ %s]\ failed,\ because\ %s = trigger job[uuid: {0}] failed, because {1} -# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:613 -# args: jobUuid,jobGroupUuid -Scheduler\ job[uuid\:%s]\ already\ in\ group[uuid\:\ %s] = Scheduler job[uuid:{0}] already in group[uuid: {1}] - # at: src/main/java/org/zstack/scheduler/SchedulerJobParamCascadeUpdater.java:86 # args: field.getName() field[%s]\ cannot\ be\ empty = field[{0}] cannot be empty -# at: src/main/java/org/zstack/scheduler/vm/StopVmInstanceJob.java:78 +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:54 +# args: msg.getTargetResourceUuid() +the\ volume[%s]\ is\ not\ available.\ check\ if\ the\ volume\ exists. = the volume[{0}] is not available. check if the volume exists. + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:58 +# args: msg.getTargetResourceUuid() +the\ volume[%s]\ is\ not\ root\ volume = the volume[{0}] is not root volume + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:63 +# args: msg.getTargetResourceUuid() +the\ vm\ of\ the\ root\ volume[%s]\ is\ not\ available.\ check\ if\ the\ vm\ exists. = the vm of the root volume[{0}] is not available. check if the vm exists. + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:70 +# args: +The\ primary\ storage\ of\ volumes\ don\ not\ support\ create\ volume\ snapshot\ group\ job. = The primary storage of volumes don not support create volume snapshot group job. + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:77 +# args: msg.getParameters().get(SchedulerJobParameters.snapshotGroupMax),e.getMessage() +snapshotGroupMaxNumber\ \:\ %s\ format\ error\ because\ %s = snapshotGroupMaxNumber : {0} format error because {1} + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotJobFactory.java:58 +# args: msg.getTargetResourceUuid() +the\ volume[%s]\ does\ not\ support\ snapshots\ retention = the volume[{0}] does not support snapshots retention + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotJobFactory.java:70 +# args: msg.getParameters().get(SchedulerJobParameters.snapshotMax),e.getMessage() +snapshotMaxNumber\ \:\ %s\ format\ error\ because\ %s = snapshotMaxNumber : {0} format error because {1} + +# at: src/main/java/org/zstack/scheduler/snapshot/CreateVolumeSnapshotGroupJob.java:125 +# args: getTargetResourceUuid() +the\ vm\ of\ the\ root\ volume[%s]\ state\ in\ Destroyed.\ job\ state\ change\ is\ not\ allowed = the vm of the root volume[{0}] state in Destroyed. job state change is not allowed + +# at: src/main/java/org/zstack/scheduler/snapshot/CreateVolumeSnapshotGroupJob.java:189 +# args: +The\ primary\ storage\ of\ volumes\ don\ not\ support\ create\ volume\ snapshot\ group\ job = The primary storage of volumes don not support create volume snapshot group job + +# at: src/main/java/org/zstack/scheduler/vm/StopVmInstanceJob.java:83 # args: getTargetResourceUuid() vm[uuid\:%s]\ is\ destroyed,\ state\ change\ is\ not\ allowed = vm[uuid:{0}] is destroyed, state change is not allowed -# at: src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:92 +# at: src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:75 # args: msg.getVendorType(),SdnControllerType.getAllTypeNames() Sdn\ controller\ type\:\ %s\ in\ not\ in\ the\ supported\ list\:\ %s\ = Sdn controller type: {0} in not in the supported list: {1} -# at: src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:97 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:102 +# args: msg.getL2NetworkUuid() +unable\ create\ vni\ range,\ because\ l2\ uuid[%s]\ is\ not\ vxlan\ network\ pool = unable create vni range, because l2 uuid[{0}] is not vxlan network pool + +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:117 +# args: msg.getStartVni(),msg.getEndVni() +the\ vni\ range\:[%s.%s}\ is\ illegal,\ because\ h3c's\ controller\ uses\ vni\ as\ vlan\ id = the vni range:[{0}.{1}} is illegal, because h3c's controller uses vni as vlan id + +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:132 +# args: userVniRange.startVni,userVniRange.endVni +the\ vni\ range\:[%s.%s}\ is\ illegal,\ must\ covered\ by\ a\ sdn's\ vniRange = the vni range:[{0}.{1}} is illegal, must covered by a sdn's vniRange + +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:178 # args: H3C\ VCFC\ controller\ must\ include\ systemTags\ vdsUuid\:\:{%s} = H3C VCFC controller must include systemTags vdsUuid::'{{0}'} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:117 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:116 # args: self.getIp(),e.getLocalizedMessage() get\ sdn\ controller\ [ip\:%s]\ vni\ range\ failed\ because\ %s = get sdn controller [ip:{0}] vni range failed because {1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:87 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:86 # args: self.getIp() get\ vni\ range\ on\ sdn\ controller\ [ip\:%s]\ failed = get vni range on sdn controller [ip:{0}] failed -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:149 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:148 # args: self.getIp() there\ is\ no\ vni\ range\ on\ sdn\ controller\ [ip\:%s] = there is no vni range on sdn controller [ip:{0}] -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:155 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:154 # args: self.getIp() there\ is\ no\ default\ tenant\ on\ sdn\ controller\ [ip\:%s] = there is no default tenant on sdn controller [ip:{0}] -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:275 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:299 # args: self.getIp(),e.getMessage() create\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = create vxlan network on sdn controller [ip:{0}] failed because {1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:259 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:283 # args: self.getIp() create\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed = create vxlan network on sdn controller [ip:{0}] failed -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:321 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:383 # args: self.getIp(),e.getMessage() delete\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = delete vxlan network on sdn controller [ip:{0}] failed because {1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:315 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:377 # args: self.getIp() delete\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed = delete vxlan network on sdn controller [ip:{0}] failed -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:381 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:468 # args: self.getIp(),e.getMessage() get\ token\ of\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = get token of sdn controller [ip:{0}] failed because {1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:352 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:439 # args: self.getIp() get\ leader\ of\ sdn\ controller\ [ip\:%s]\ failed = get leader of sdn controller [ip:{0}] failed -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:373 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:460 # args: self.getIp() get\ token\ of\ sdn\ controller\ [ip\:%s]\ failed = get token of sdn controller [ip:{0}] failed -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java:72 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java:51 # args: vo.getPoolUuid() there\ is\ no\ sdn\ controller\ for\ vxlan\ pool\ [uuid\:%s] = there is no sdn controller for vxlan pool [uuid:{0}] -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java:259 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java:410 # args: inv.getUuid(),destHostUuid cannot\ configure\ hardware\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = cannot configure hardware vxlan network for vm[uuid:{0}] on the destination host[uuid:{1}] -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:103 -# args: overlappedPool -overlap\ vni\ range\ with\ vxlan\ network\ pool\ [%s] = overlap vni range with vxlan network pool [{0}] +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:150 +# args: msg.getPhysicalInterface() +cannot\ create\ vlan-device\ on\ %s\ because\ it's\ too\ long = cannot create vlan-device on {0} because it's too long -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:110 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:112 # args: -hareware\ vxlan\ network\ pool\ doesn't\ support\ create\ l3\ network = hareware vxlan network pool doesn't support create l3 network +hardware\ vxlan\ network\ pool\ doesn't\ support\ create\ l3\ network = hardware vxlan network pool doesn't support create l3 network -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:116 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:118 # args: -hareware\ vxlan\ network\ pool\ must\ configure\ the\ physical\ interface = hareware vxlan network pool must configure the physical interface +hardware\ vxlan\ network\ pool\ must\ configure\ the\ physical\ interface = hardware vxlan network pool must configure the physical interface -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:124 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:126 # args: -ONLY\ hareware\ vxlan\ network\ can\ be\ created\ in\ hareware\ vxlan\ pool = ONLY hareware vxlan network can be created in hareware vxlan pool +ONLY\ hardware\ vxlan\ network\ can\ be\ created\ in\ hardware\ vxlan\ pool = ONLY hardware vxlan network can be created in hardware vxlan pool -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:129 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:131 # args: -hareware\ vxlan\ network\ can\ ONLY\ be\ created\ in\ hareware\ vxlan\ pool = hareware vxlan network can ONLY be created in hareware vxlan pool +hardware\ vxlan\ network\ can\ ONLY\ be\ created\ in\ hardware\ vxlan\ pool = hardware vxlan network can ONLY be created in hardware vxlan pool -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:75 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),vlanId,hostUuid,rsp.getError() +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:86 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),finalVlanId,hostUuid,rsp.getError() failed\ to\ create\ bridge[%s]\ for\ hardwareVxlan[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = failed to create bridge[{0}] for hardwareVxlan[uuid:{1}, type:{2}, vlan:{3}] on kvm host[uuid:{4}], because {5} -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:129 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:144 # args: cmd.getBridgeName(),vxlan.getUuid(),vxlan.getName(),hostUuid,rsp.getError() failed\ to\ check\ bridge[%s]\ for\ hardwareVxlan[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = failed to check bridge[{0}] for hardwareVxlan[uuid:{1}, name:{2}] on kvm host[uuid:{3}], {4} -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java:61 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java:64 # args: l2Network.getUuid(),l2Network.getName(),hostUuid,rsp.getError() failed\ to\ check\ physical\ interface\ for\ HardwareVxlanPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = failed to check physical interface for HardwareVxlanPool[uuid:{0}, name:{1}] on kvm host[uuid: {2}], {3} @@ -6262,51 +10258,47 @@ failed\ to\ check\ physical\ interface\ for\ HardwareVxlanPool[uuid\:%s,\ name\: # args: set\ to\ disconnected = set to disconnected -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:60 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:97 +# args: number +invalid\ phone\ number[%s],\ sms\ number\ is\ like\ +86-18654321234 = invalid phone number[{0}], sms number is like +86-18654321234 + +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:64 # args: msg.getApplicationEndpointUuid() can\ not\ add\ same\ email\ address\ to\ endpoint[uuid\:%s] = can not add same email address to endpoint[uuid:{0}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:171 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:165 # args: errorEmails invalid\ email\ address[%s] = invalid email address[{0}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:73 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:77 # args: msg.getEmailAddress(),msg.getApplicationEndpointUuid() cannot\ update\ email\ address\ to\ %s,\ which\ is\ already\ exists\ in\ endpoint[uuid\:%s] = cannot update email address to {0}, which is already exists in endpoint[uuid:{1}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:87 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:91 # args: msg.getPhoneNumber() phone\ number\ [%s]\ already\ exists = phone number [{0}] already exists -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:99 -# args: -password\ is\ not\ set\ while\ username\ is\ set = password is not set while username is set - -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:103 -# args: -username\ is\ not\ set\ while\ password\ is\ set = username is not set while password is set - -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:112 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:106 # args: msg.getPhoneNumber() phone\ number[%s]\ already\ exists = phone number[{0}] already exists -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:121 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:115 # args: url invalid\ url[%s] = invalid url[{0}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:127 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:121 # args: host [%s]\ is\ not\ a\ legal\ ip = [{0}] is not a legal ip -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:133 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:127 # args: n invalid\ phone\ number[%s],\ the\ DingDing\ phone\ number\ is\ like\ +86-12388889999 = invalid phone number[{0}], the DingDing phone number is like +86-12388889999 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:150 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:144 # args: username\ and\ password\ must\ either\ absent\ at\ all\ or\ present\ with\ each\ other = username and password must either absent at all or present with each other -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:158 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:152 # args: can\ not\ create\ sns\ email\ endpoint\ without\ any\ email\ address = can not create sns email endpoint without any email address @@ -6314,35 +10306,31 @@ can\ not\ create\ sns\ email\ endpoint\ without\ any\ email\ address = can not c # args: the\ operation\ is\ not\ permitted\ for\ the\ system\ application\ platform = the operation is not permitted for the system application platform -# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:75 +# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:67 # args: msg.getTopicUuid() cannot\ find\ the\ SNSTopic[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the SNSTopic[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:93 +# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:85 # args: msg.getApplicationPlatformUuid() cannot\ find\ SNSApplicationPlatform[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find SNSApplicationPlatform[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:103 +# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:95 # args: msg.getApplicationEndpointUuid() cannot\ find\ SNSApplicationEndpoint[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find SNSApplicationEndpoint[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/sns/SNSTopicBase.java:125 +# at: src/main/java/org/zstack/sns/SNSTopicBase.java:128 # args: the\ topic\ is\ not\ subscribed\ by\ any\ endpoints = the topic is not subscribed by any endpoints -# at: src/main/java/org/zstack/sns/SNSTopicBase.java:149 +# at: src/main/java/org/zstack/sns/SNSTopicBase.java:154 # args: application\ platform\ is\ disabled = application platform is disabled -# at: src/main/java/org/zstack/sns/SNSTopicBase.java:201 +# at: src/main/java/org/zstack/sns/SNSTopicBase.java:224 # args: application\ endpoint\ is\ disabled = application endpoint is disabled -# at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java:34 -# args: number -invalid\ phone\ number[%s],\ sms\ number\ is\ like\ +86-18654321234 = invalid phone number[{0}], sms number is like +86-18654321234 - -# at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java:43 +# at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java:44 # args: msg.getAccessKeyUuid() Aliyun\ account[uuid\:%s]\ not\ exists = Aliyun account[uuid:{0}] not exists @@ -6350,31 +10338,31 @@ Aliyun\ account[uuid\:%s]\ not\ exists = Aliyun account[uuid:{0}] not exists # args: SysErrors.RESOURCE_NOT_FOUND Aliyun\ sms\ event\ text\ template\ not\ found. = Aliyun sms event text template not found. -# at: src/main/java/org/zstack/sns/platform/dingtalk/SNSDingTalkEndpoint.java:118 +# at: src/main/java/org/zstack/sns/platform/dingtalk/SNSDingTalkEndpoint.java:130 # args: rsp.getStatusCode(),rsp.getBody() -Sending\ message\ to\ DingTalk\ failure.\ status\:\ %s,\ body\:\ %s = Sending message to DingTalk failure. status: {0}, body: {1} +failed\ to\ send\ messages\ to\ DingTalk.\ status\:\ %s,\ body\:\ %s = failed to send messages to DingTalk. status: {0}, body: {1} # at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:72 # args: getSelf().getSmtpServer(),getSelf().getSmtpPort() cannot\ connect\ SMTP\ server[server\:\ %s,\ port\:\ %s]\ in\ 15\ seconds = cannot connect SMTP server[server: {0}, port: {1}] in 15 seconds -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:92 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:88 # args: e.getMessage() SMTP\ server\ validation\ error\:\ %s = SMTP server validation error: {0} -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:134 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:130 # args: the\ endpoint\ is\ disabled = the endpoint is disabled -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:162 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:158 # args: no\ subject = no subject -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:59 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:66 # args: The\ problem\ may\ be\ caused\ by\ an\ incorrect\ user\ name\ or\ password\ or\ email\ permission\ denied = The problem may be caused by an incorrect user name or password or email permission denied -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:61 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:68 # args: smtpServer,smtpPort Couldn't\ connect\ to\ host,\ port\:\ %s,\ %d.\ The\ problem\ may\ be\ caused\ by\ an\ incorrect\ smtpServer\ or\ smtpPort = Couldn't connect to host, port: {0}, {1}. The problem may be caused by an incorrect smtpServer or smtpPort @@ -6382,6 +10370,10 @@ Couldn't\ connect\ to\ host,\ port\:\ %s,\ %d.\ The\ problem\ may\ be\ caused\ b # args: rsp.getStatusCode(),rsp.getBody() HTTP\ POST\ failure.\ status\:\ %s,\ body\:\ %s = HTTP POST failure. status: {0}, body: {1} +# at: src/main/java/org/zstack/sns/platform/microsoftteams/SNSMicrosoftTeamsEndpoint.java:69 +# args: rsp.getStatusCode(),rsp.getBody() +failed\ to\ send\ messages\ to\ Microsoft\ Teams.\ status\:\ %s,\ body\:\ %s = failed to send messages to Microsoft Teams. status: {0}, body: {1} + # at: src/main/java/org/zstack/sns/system/SNSApiTopicManagerImpl.java:172 # args: endpoint.getType() only\ HTTP\ endpoint\ can\ subscribe\ API\ topic,\ the\ endpoint[type\:%s]\ is\ not\ a\ HTTP\ endpoint = only HTTP endpoint can subscribe API topic, the endpoint[type:{0}] is not a HTTP endpoint @@ -6390,10 +10382,82 @@ only\ HTTP\ endpoint\ can\ subscribe\ API\ topic,\ the\ endpoint[type\:%s]\ is\ # args: API\ topic\ cannot\ be\ deleted = API topic cannot be deleted -# at: src/main/java/org/zstack/sns/system/SNSSystemAlarmTopicManagerImpl.java:76 +# at: src/main/java/org/zstack/sns/system/SNSSystemAlarmTopicManagerImpl.java:78 # args: system\ alarm\ topic\ cannot\ be\ deleted = system alarm topic cannot be deleted +# at: src/main/java/org/zstack/sso/cas/filter/CasLoginFilter.java:53 +# args: +url\ is\ error,\ clientUuid\ is\ miss = url is error, clientUuid is miss + +# at: src/main/java/org/zstack/sso/cas/filter/CasLoginFilter.java:58 +# args: +\ missing\ cas\ client,\ please\ create\ cas\ client\ before\ sso = missing cas client, please create cas client before sso + +# at: src/main/java/org/zstack/sso/cas/service/CasClientManagerImpl.java:62 +# args: login.getClass().getName(),old.getClass().getName(),login.getLoginType() +duplicate\ casLogin[%s,\ %s]\ for\ type[%s] = duplicate casLogin[{0}, {1}] for type[{2}] + +# at: src/main/java/org/zstack/sso/cas/service/CasClientManagerImpl.java:73 +# args: type +Cannot\ find\ CasLogin\ for\ type(%s) = Cannot find CasLogin for type({0}) + +# at: src/main/java/org/zstack/sso/cas/service/CasLoginIAM2.java:67 +# args: userName +iam2\ has\ a\ user\ with\ the\ same\ name[%s] = iam2 has a user with the same name[{0}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM1.java:71 +# args: userName +\ local\ user\ has\ a\ user\ with\ the\ same\ name[%s] = local user has a user with the same name[{0}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java:57 +# args: ssoUseAsLoginName +fail\ to\ get\ params[%s] = fail to get params[{0}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java:61 +# args: +get\ user\ name\ is\ null = get user name is null + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java:66 +# args: userName +\ iam2\ has\ a\ user\ with\ the\ same\ name[%s] = iam2 has a user with the same name[{0}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:375 +# args: rsp.getStatusCode(),rsp.getBody() +HTTP\ ERROR,\ status\ code\:\ %s,\ body\:\ %s = HTTP ERROR, status code: {0}, body: {1} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:382 +# args: HttpMethod.POST,url,e.getStatusCode(),e.getResponseBodyAsString() +failed\ to\ %s\ to\ %s,\ status\ code\:\ %s,\ response\ body\:\ %s = failed to {0} to {1}, status code: {2}, response body: {3} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:386 +# args: HttpMethod.POST,url,e.getMessage() +failed\ to\ %s\ to\ %s,\ IO\ Error\:\ %s = failed to {0} to {1}, IO Error: {2} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:201 +# args: e +response\ has\ error\ \:\ %s = response has error : {0} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:101 +# args: login.getClass().getName(),old.getClass().getName(),login.getLoginType() +duplicate\ OAuth2Login[%s,\ %s]\ for\ type[%s] = duplicate OAuth2Login[{0}, {1}] for type[{2}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:113 +# args: type +Cannot\ find\ OAuth2Login\ for\ type(%s) = Cannot find OAuth2Login for type({0}) + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:190 +# args: +there\ was\ an\ error,\ reason\:\ \ token\ response\ is\ null = there was an error, reason: token response is null + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:194 +# args: AuthGolabalProperty.OAUTH2_GET_TOKEN_USERINFO +there\ was\ an\ error,\ reason\:\ \ %s\ is\ null = there was an error, reason: {0} is null + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:300 +# args: e +get\ code\ response\ has\ error\ \:\ %s = get code response has error : {0} + # at: src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java:65 # args: name %s\ should\ not\ be\ null = {0} should not be null @@ -6410,27 +10474,27 @@ backup\ storage[uuid\:%s]\ has\ not\ been\ attached\ to\ zone[uuid\:%s] = backup # args: msg.getBackupStorageUuid(),msg.getZoneUuid() backup\ storage[uuid\:%s]\ has\ been\ attached\ to\ zone[uuid\:%s] = backup storage[uuid:{0}] has been attached to zone[uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:162 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:148 # args: url,e.toString() failed\ to\ get\ header\ of\ image\ url\ %s\:\ %s = failed to get header of image url {0}: {1} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:166 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:152 # args: url failed\ to\ get\ header\ of\ image\ url\ %s = failed to get header of image url {0} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:176 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:175 # args: self.getUuid(),self.getName(),url,size,self.getAvailableCapacity() the\ backup\ storage[uuid\:%s,\ name\:%s]\ has\ not\ enough\ capacity\ to\ download\ the\ image[%s].Required\ size\:%s,\ available\ size\:%s = the backup storage[uuid:{0}, name:{1}] has not enough capacity to download the image[{2}].Required size:{3}, available size:{4} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:173 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:172 # args: url,size the\ image\ size\ get\ from\ url\ %s\ is\ %d\ bytes,\ it's\ too\ small\ for\ an\ image,\ please\ check\ the\ url\ again. = the image size get from url {0} is {1} bytes, it's too small for an image, please check the url again. -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:191 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:190 # args: msg.getClass().getName(),self.getStatus() backup\ storage\ cannot\ proceed\ message[%s]\ because\ its\ status\ is\ %s = backup storage cannot proceed message[{0}] because its status is {1} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:197 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:196 # args: msg.getClass().getName(),self.getState() backup\ storage\ cannot\ proceed\ message[%s]\ because\ its\ state\ is\ %s = backup storage cannot proceed message[{0}] because its state is {1} @@ -6438,50 +10502,66 @@ backup\ storage\ cannot\ proceed\ message[%s]\ because\ its\ state\ is\ %s = bac # args: size,backupStorageUuid,capacityVO.getAvailableCapacity() cannot\ reserve\ %s\ on\ the\ backup\ storage[uuid\:%s],\ it\ only\ has\ %s\ available = cannot reserve {0} on the backup storage[uuid:{1}], it only has {2} available -# at: src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java:279 +# at: src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java:276 # args: capacity\ reservation\ on\ all\ backup\ storage\ failed = capacity reservation on all backup storage failed -# at: src/main/java/org/zstack/storage/backup/BackupStorageReservedCapacityAllocatorFlow.java:46 -# args: BackupStorageGlobalConfig.RESERVED_CAPACITY.value(),spec.getSize() -after\ subtracting\ reserved\ capacity[%s],\ no\ backup\ storage\ has\ required\ capacity[%s\ bytes] = after subtracting reserved capacity[{0}], no backup storage has required capacity[{1} bytes] +# at: src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java:320 +# args: backupStorageDataNetworkTags.size() +only\ one\ backup\ storage\ data\ network\ system\ tag\ is\ allowed,\ but\ %s\ got = only one backup storage data network system tag is allowed, but {0} got + +# at: src/main/java/org/zstack/storage/backup/BackupStoragePrimaryStorageAllocatorFlow.java:46 +# args: spec.getRequiredPrimaryStorageUuid(),psTypeName +required\ primary\ storage[uuid\:%s,\ type\:%s]\ could\ not\ support\ any\ backup\ storage. = required primary storage[uuid:{0}, type:{1}] could not support any backup storage. -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:284 +# at: src/main/java/org/zstack/storage/backup/BackupStorageReservedCapacityAllocatorFlow.java:55 +# args: spec.getSize() +after\ subtracting\ reserved\ capacity,\ no\ backup\ storage\ has\ required\ capacity[%s\ bytes] = after subtracting reserved capacity, no backup storage has required capacity[{0} bytes] + +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:328 # args: missing\ 'retentionType'\ in\ job\ parameters = missing 'retentionType' in job parameters -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:288 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:332 # args: missing\ 'retentionValue'\ in\ job\ parameters = missing 'retentionValue' in job parameters -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:292 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:336 # args: missing\ 'backupStorageUuids'\ in\ job\ parameters = missing 'backupStorageUuids' in job parameters -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:296 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:340 # args: job\ parameter\ 'backupStorageUuids'\ is\ empty = job parameter 'backupStorageUuids' is empty -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:301 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:345 # args: bsUuid unexpected\ backup\ storage\ uuid\:\ %s = unexpected backup storage uuid: {0} -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:484 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:354 +# args: +missing\ 'remoteRetentionValue'\ in\ job\ parameters = missing 'remoteRetentionValue' in job parameters + +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:352 +# args: +missing\ 'remoteRetentionType'\ in\ job\ parameters = missing 'remoteRetentionType' in job parameters + +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:84 +# args: +No\ available\ backup\ storage\ found,\ skip\ this\ job = No available backup storage found, skip this job + +# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:578 # args: getTargetResourceUuid() volume[uuid\:%s]\ is\ deleted,\ state\ change\ is\ not\ allowed = volume[uuid:{0}] is deleted, state change is not allowed -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:114 +# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:137 # args: bandWidth\ must\ be\ a\ positive\ number = bandWidth must be a positive number -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:170 +# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:217 # args: missing\ job\ parameters = missing job parameters -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:429 -# args: -No\ available\ backup\ storage\ found,\ skip\ this\ job = No available backup storage found, skip this job - # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:93 # args: msg.getDatabaseBackupUuid(),msg.getBackupStorageUuid() database\ backup[uuid%s]\ has\ not\ been\ exported\ from\ backupStorage[uuid\:%s] = database backup[uuid{0}] has not been exported from backupStorage[uuid:{1}] @@ -6506,248 +10586,276 @@ databaseBackup[uuid\:%s]\ is\ not\ Enabled\ and\ Ready = databaseBackup[uuid:{0} # args: url illegal\ url[%s],\ correct\ example\ is\ ssh\://username\:password@hostname[\:sshPort]/path = illegal url[{0}], correct example is ssh://username:password@hostname[:sshPort]/path -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:467 -# args: -sync\ task\ failed. = sync task failed. - -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:474 -# args: reply.getStatus() -unexpected\ task\ status\:\ %s = unexpected task status: {0} - -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:280 -# args: msg.getDstBackupStorageUuid(),msg.getSrcBackupStorageUuid(),BackupStorageState.Disabled.toString() -One\ of\ the\ backup\ storage[uuids\:\ %s,\ %s]\ is\ in\ the\ state\ of\ %s,\ can\ not\ do\ sync\ operation = One of the backup storage[uuids: {0}, {1}] is in the state of {2}, can not do sync operation - # at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:80 # args: self.getUuid() database\ backup[uuid\:%s]\ is\ not\ Enabled\ and\ Ready = database backup[uuid:{0}] is not Enabled and Ready -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:325 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:328 # args: msg.getDatabaseBackupUuid(),msg.getSrcBackupStorageUuid() database\ backup[uuid\:%s]\ not\ found\ in\ backup\ storage[uuid\:%s] = database backup[uuid:{0}] not found in backup storage[uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:90 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:91 # args: msg.getDatabaseBackupUuid() database\ backup\ [uuid\:%s]\ is\ not\ existed\ yet = database backup [uuid:{0}] is not existed yet -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:106 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:107 # args: backup\ storage[uuid\:%s]\ is\ not\ enabled\ and\ connected = backup storage[uuid:{0}] is not enabled and connected -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:600 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:603 # args: result.getStderr() not\ pass\ the\ restore\ security\ check\:\n%s = not pass the restore security check:\n{0} -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:612 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:615 # args: cannot\ get\ free\ port\ to\ listen = cannot get free port to listen -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:640 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:643 # args: version,dbf.getDbVersion() database\ backup\ version[%s]\ is\ not\ match\ currently\ version[%s] = database backup version[{0}] is not match currently version[{1}] -# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:25 +# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:26 # args: cannot\ ssh\ peer\ node\ via\ sshkey,\ please\ check\ connection = cannot ssh peer node via sshkey, please check connection -# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:40 -# args: result.getStderr() -cannot\ get\ zsha2\ status,\ because\ %s = cannot get zsha2 status, because {0} - -# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:45 -# args: result.getStderr() -cannot\ get\ zsha2\ config,\ because\ %s,\ maybe\ you\ need\ upgrade\ zsha2 = cannot get zsha2 config, because {0}, maybe you need upgrade zsha2 - # at: src/main/java/org/zstack/storage/backup/SingleDatabaseRecoverChecker.java:19 # args: please\ stop\ other\ node\ first! = please stop other node first! -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:81 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:355 +# args: +could\ not\ create\ vm,\ because\ at\ least\ one\ of\ field\ (l3NetworkUuids,zoneUuid,clusterUuid,hostUuid)\ should\ be\ set = could not create vm, because at least one of field (l3NetworkUuids,zoneUuid,clusterUuid,hostUuid) should be set + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:91 # args: currentState,msgName,checker.getStatesForOperation(msgName) current\ backup\ storage\ state[%s]\ doesn't\ allow\ to\ proceed\ message[%s],\ allowed\ states\ are\ %s = current backup storage state[{0}] doesn't allow to proceed message[{1}], allowed states are {2} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:212 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:231 # args: bsType,bsUuid Unexpected\ backup\ storage[type\:%s,uuid\:%s] = Unexpected backup storage[type:{0},uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:233 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:252 # args: msg.getVolumeUuid() Can\ not\ create\ volume\ backup\ for\ shareable\ volume[uuid\:%s] = Can not create volume backup for shareable volume[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:237 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:256 # args: msg.getVolumeUuid() Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ it\ is\ not\ attached\ to\ any\ vm = Failed to create volume backup for volume[uuid:{0}], because it is not attached to any vm -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:246 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:265 # args: msg.getVolumeUuid(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ its\ attached\ volume\ is\ not\ in\ state[%s,\ %s] = Failed to create volume backup for volume[uuid:{0}], because its attached volume is not in state[{1}, {2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:243 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:262 # args: msg.getVolumeUuid(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ the\ vm\ is\ not\ in\ state[%s,\ %s] = Failed to create volume backup for volume[uuid:{0}], because the vm is not in state[{1}, {2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:255 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:292 +# args: msg.getVolumeUuid() +The\ resource[uuid\:\ %s]\ has\ already\ created\ a\ cdp\ task,\ cannot\ create\ the\ backup\ job\ at\ the\ same\ time. = The resource[uuid: {0}] has already created a cdp task, cannot create the backup job at the same time. + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:280 # args: msg.getVolumeUuid() Volume[uuid\:%s]\ is\ not\ root\ volume = Volume[uuid:{0}] is not root volume -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:262 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:287 # args: t.get(0),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() Failed\ to\ create\ backups\ for\ VM[uuid\:%s],\ because\ it\ is\ not\ in\ state[%s,\ %s] = Failed to create backups for VM[uuid:{0}], because it is not in state[{1}, {2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:276 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:305 # args: groupUuid No\ volume\ backup\ found\ for\ group\ uuid\:\ %s = No volume backup found for group uuid: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:282 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:311 # args: groupUuid root\ volume\ backup\ of\ group[uuid\:%s]\ not\ found = root volume backup of group[uuid:{0}] not found -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:312 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:315 +# args: expectVmUuid,rootVolumeInfo.get(0),rootVolumeInfo.get(1) +Current\ vm[uuid\:\ %s]\ of\ the\ volume[uuid\:\ %s]\ is\ no\ longer\ the\ vm[uuid\:\ %s]\ that\ was\ used\ for\ backup = Current vm[uuid: {0}] of the volume[uuid: {1}] is no longer the vm[uuid: {2}] that was used for backup + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:348 # args: cannot\ specify\ primary\ storage\ which\ attached\ different\ cluster. = cannot specify primary storage which attached different cluster. -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:335 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:378 # args: backupUuid,state volume\ backup[uuid\:%s]\ is\ in\ state\ %s,\ cannot\ revert\ volume\ to\ it = volume backup[uuid:{0}] is in state {1}, cannot revert volume to it -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:345 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:388 # args: backupUuid original\ volume\ for\ backup[uuid\:%s]\ has\ been\ deleted,\ cannot\ revert\ volume\ to\ it = original volume for backup[uuid:{0}] has been deleted, cannot revert volume to it -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:349 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:392 # args: volUuid,backupUuid,expectVmUuid original\ volume[uuid\:%s]\ for\ backup[uuid\:%s]\ is\ no\ longer\ attached\ to\ vm[uuid\:%s] = original volume[uuid:{0}] for backup[uuid:{1}] is no longer attached to vm[uuid:{2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:359 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:402 # args: backupUuid VM\ not\ found\ with\ volume\ backup[uuid\:%s] = VM not found with volume backup[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:363 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:406 # args: vmState VM\ is\ not\ in\ stopped\ state\:\ %s = VM is not in stopped state: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:380 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:423 # args: No\ available\ backup\ storage\ found = No available backup storage found -# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:181 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:518 +# args: +The\ vm\ is\ creating\ a\ backup\ job,\ cannot\ enable\ the\ cdp\ task\ at\ the\ same\ time. = The vm is creating a backup job, cannot enable the cdp task at the same time. + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:191 # args: Operation\ not\ supported\ on\ shared\ volume = Operation not supported on shared volume -# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:186 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:196 # args: volumeVO.getUuid() No\ VM\ found\ for\ volume[uuid\:%s] = No VM found for volume[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:435 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:380 # args: msg.getRootVolumeUuid() No\ VM\ found\ with\ root\ volume\ uuid\:\ %s = No VM found with root volume uuid: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2041 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1974 # args: cidr,fmtCidr [%s]\ is\ not\ a\ standard\ cidr,\ do\ you\ mean\ [%s]? = [{0}] is not a standard cidr, do you mean [{1}]? -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:306 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1320 +# args: msg.getDstBackupStorageUuid(),msg.getSrcBackupStorageUuid(),BackupStorageState.Disabled.toString() +One\ of\ the\ backup\ storage[uuids\:\ %s,\ %s]\ is\ in\ the\ state\ of\ %s,\ can\ not\ do\ sync\ operation = One of the backup storage[uuids: {0}, {1}] is in the state of {2}, can not do sync operation + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:992 +# args: +sync\ task\ failed. = sync task failed. + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:999 +# args: reply.getStatus() +unexpected\ task\ status\:\ %s = unexpected task status: {0} + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:293 # args: vos.stream().filter( vo -> !succeedUuids.contains(vo.getUuid())).map(VolumeBackupVO::getUuid).collect(Collectors.toList()) failed\ to\ create\ image\ from\ backup\ %s = failed to create image from backup {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:660 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:498 # args: msg.getImageStoreUuid(),e.getMessage() sync\ volume\ backup\ metadata\ file\ in\ image\ store[uuid\:%s]\ meet\ I/O\ error\:\ %s = sync volume backup metadata file in image store[uuid:{0}] meet I/O error: {1} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:697 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:535 +# args: volumeVmUuid,backupUuid,backupVmUuid +Current\ vm[uuid\:\ %s]\ of\ the\ backup\ volume\ is\ no\ longer\ the\ vm[uuid\:\ %s]\ that\ was\ used\ for\ backup = Current vm[uuid: {0}] of the backup volume is no longer the vm[uuid: {1}] that was used for backup + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:544 # args: hypervisorType No\ VolumeBackupFactory\ of\ type[%s]\ found = No VolumeBackupFactory of type[{0}] found -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:714 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:561 # args: msg.getBackupStorageUuid(),BackupStorageState.Disabled.toString() One\ of\ the\ backup\ storage[uuid\:\ %s]\ is\ in\ the\ state\ of\ %s,\ can\ not\ do\ sync\ operation = One of the backup storage[uuid: {0}] is in the state of {1}, can not do sync operation -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:854 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:738 # args: struct.getBackupUuid(),struct.getBackupStorageUuid() Volume\ backup[uuid\:%s]\ not\ found\ on\ backup\ storage[uuid\:%s] = Volume backup[uuid:{0}] not found on backup storage[uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1298 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1187 # args: backupUuid,srcBackupStorageUuid volume\ backup[uuid\:%s]\ not\ found\ in\ backup\ storage[uuid\:%s] = volume backup[uuid:{0}] not found in backup storage[uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1506 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1399 # args: groupUuid No\ volume\ backups\ found\ with\ group\ uuid\:\ %s = No volume backups found with group uuid: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1513 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1406 # args: groupUuid Root\ volume\ missing\ within\ group\ uuid\:\ %s = Root volume missing within group uuid: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1519 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1412 # args: groupUuid Multiple\ root\ volumes\ found\ within\ group\ uuid\:\ %s = Multiple root volumes found within group uuid: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1531 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1424 # args: groupUuid No\ permission\ to\ volume\ backups\ within\ group\ uuid\:\ %s = No permission to volume backups within group uuid: {0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1669 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1564 # args: vo.getUuid() Volume\ backup[uuid\:%s]\ not\ found\ on\ any\ backup\ storage = Volume backup[uuid:{0}] not found on any backup storage -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2068 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2001 # args: degree degree\ [%s]\ should\ be\ a\ positive\ number = degree [{0}] should be a positive number -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2102 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2035 # args: type -invalid\ type[%s],\ should\ be\ [nfs] = invalid type[{0}], should be [nfs] +invalid\ type[%s],\ should\ be\ [nfs,\ sshfs,\ nbd] = invalid type[{0}], should be [nfs, sshfs, nbd] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2108 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2045 # args: url invalid\ url[%s],\ should\ be\ hostname\:/path = invalid url[{0}], should be hostname:/path -# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:181 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:177 # args: inv.getUuid(),e.getMessage() generate\ volume\ backup\ metadata\ file\ on\ image\ store[uuid\:%s]\ failure,\ because\ IO\ error\:\ %s = generate volume backup metadata file on image store[uuid:{0}] failure, because IO error: {1} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:508 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:505 # args: rsp.getError() volume\ backup\ metadata\ operation\ failure,\ because\ %s = volume backup metadata operation failure, because {0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:271 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:586 +# args: cmd.imgurl,cmd.uuid,ret.getError() +failed\ to\ download\ image[url\:\ %s]\ on\ backup\ storage[uuid\:\ %s],\ because\:\ %s = failed to download image[url: {0}] on backup storage[uuid: {1}], because: {2} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:277 # args: url,rsp.getError() unable\ to\ connect\ to\ SimpleHttpBackupStorage[url\:%s],\ because\ %s = unable to connect to SimpleHttpBackupStorage[url:{0}], because {1} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:493 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:507 # args: iinv.getName() Missing\ cert\ file\ for\ downloading\ image\:\ %s = Missing cert file for downloading image: {0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:622 -# args: -image\ store\ service\ is\ temporary\ not\ available,\ because\ it\ is\ reclaiming\ space\ now = image store service is temporary not available, because it is reclaiming space now - -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:798 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:831 # args: No\ response = No response -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:871 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:907 # args: ret.getError() reclaim\ imagestore\ error,\ because\:%s = reclaim imagestore error, because:{0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:958 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:994 # args: self.getUuid(),ret.getError() failed\ to\ set\ max\ capacity\ on\ image\ store[uuid\:%s],\ because\:\ %s = failed to set max capacity on image store[uuid:{0}], because: {1} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1085 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1223 # args: msg.getImageUuid(),self.getUuid() image[%s]\ not\ found\ on\ backup\ storage[%s] = image[{0}] not found on backup storage[{1}] -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1235 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1134 +# args: ret.getError() +failed\ to\ delete\ image\ package,\ because\:\ %s = failed to delete image package, because: {0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1158 +# args: StringUtils.join(notOnBsImageUuids, ','),msg.getBackupStorageUuid() +some\ images\ [%s]\ are\ not\ exported\ on\ the\ backup\ storage[uuid\:\ %s] = some images [{0}] are not exported on the backup storage[uuid: {1}] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1192 +# args: ret.getError() +failed\ to\ package\ exported\ images,\ because\ %s = failed to package exported images, because {0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1234 +# args: self.getUuid(),actualSize +the\ backup\ storage[uuid\:%s]\ has\ not\ enough\ capacity[%s]\ to\ export = the backup storage[uuid:{0}] has not enough capacity[{1}] to export + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1393 # args: image\ store\ [%s]\ cannot\ add\ image,\ because\ it\ is\ used\ for\ backup\ remote = image store [{0}] cannot add image, because it is used for backup remote -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1435 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1591 # args: commercial\ license\ is\ required\ to\ use\ ImageStore = commercial license is required to use ImageStore -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1468 -# args: self.getUuid(),ret.getUuid() +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1712 +# args: self.getUuid(),resp.getUuid() the\ uuid\ of\ imagestoreBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = the uuid of imagestoreBackupStorage agent changed[expected:{0}, actual:{1}], it's most likely the agent was manually restarted. Issue a reconnect to sync the status # at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:125 @@ -6786,79 +10894,59 @@ the\ url\ contains\ an\ invalid\ folder[/dev\ or\ /proc\ or\ /sys] = the url con # args: dir file\ path\ contains\ invalid\ character\:\ %s = file path contains invalid character: {0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageExtension.java:188 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageExtension.java:193 # args: ps.getUuid() cannot\ find\ a\ connected\ host\ in\ cluster\ to\ which\ PS\ [uuid\:\ %s]\ attached = cannot find a connected host in cluster to which PS [uuid: {0}] attached -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:142 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:108 # args: amsg.getUrl() invalid\ url[%s],\ the\ url\ must\ be\ an\ absolute\ path\ starting\ with\ '/' = invalid url[{0}], the url must be an absolute path starting with '/' -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:151 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:117 # args: hostname existing\ SimpleHttpBackupStorage\ with\ hostname[%s]\ found = existing SimpleHttpBackupStorage with hostname[{0}] found -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:100 -# args: result.getStderr() -ansible\ mkdir\ failed,\ due\ to\:\ %s = ansible mkdir failed, due to: {0} - -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:112 -# args: result.getStderr() -ansible\ failed,\ due\ to\:\ %s = ansible failed, due to: {0} - -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:110 -# args: result.getStdout() -ansible\ attach\ nas\ failed,\ due\ to\:\ %s = ansible attach nas failed, due to: {0} - -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:395 -# args: tmpHostFile,result.getStderr() -create\ tmp\ file\ [%s]\ failed,\ due\ to\:\ %s = create tmp file [{0}] failed, due to: {1} - -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:229 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:228 # args: sync\ status\ failed. = sync status failed. -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:806 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:343 +# args: +failed\ to\ get\ task\ reply! = failed to get task reply! + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:841 # args: rsp.getError() delete\ image\ metadata\ file\ failed\:\ %s = delete image metadata file failed: {0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:389 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:397 # args: bsUuid AddImage\ is\ forbidden\ in\ Disaster\ BS\:\ [%s] = AddImage is forbidden in Disaster BS: [{0}] -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:735 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:770 # args: rsp.getBackupStorageMetaFileName() Check\ image\ metadata\ file\:\ %s\ failed = Check image metadata file: {0} failed -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:563 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:594 # args: rsp.getBackupStorageMetaFileName() Create\ image\ metadata\ file\ \:\ %s\ failed = Create image metadata file : {0} failed -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:538 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:569 # args: rsp.getBackupStorageMetaFileName() Create\ image\ metadata\ file\ sync\ \:\ %s\ failed = Create image metadata file sync : {0} failed -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreImageStruct.java:79 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreImageStruct.java:80 # args: e.getMessage() parse\ create\ time\ error\:\ %s = parse create time error: {0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ReclaimSpaceFromImageStoreLongJob.java:62 -# args: -Cancel\ operation\ is\ not\ supported = Cancel operation is not supported - -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:105 +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:111 # args: scheme,url SftpBackupStorage\ doesn't\ support\ scheme[%s]\ in\ url[%s] = SftpBackupStorage doesn't support scheme[{0}] in url[{1}] -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:133 -# args: ret.getError() -fail\ to\ download\ image,\ because\ %s = fail to download image, because {0} - -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:233 +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:242 # args: rsp.getError() fail\ to\ cancel\ download\ image,\ because\ %s = fail to cancel download image, because {0} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:307 +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:316 # args: self.getUuid(),ret.getUuid() the\ uuid\ of\ sftpBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = the uuid of sftpBackupStorage agent changed[expected:{0}, actual:{1}], it's most likely the agent was manually restarted. Issue a reconnect to sync the status @@ -6866,154 +10954,478 @@ the\ uuid\ of\ sftpBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it # args: bsUuid Please\ stop\ the\ vm\ before\ create\ volume\ template\ to\ sftp\ backup\ storage\ %s = Please stop the vm before create volume template to sftp backup storage {0} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java:106 -# args: msg.getHostname() -duplicate\ backup\ storage.\ There\ has\ been\ a\ sftp\ backup\ storage[hostname\:%s]\ existing = duplicate backup storage. There has been a sftp backup storage[hostname:{0}] existing +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java:106 +# args: msg.getHostname() +duplicate\ backup\ storage.\ There\ has\ been\ a\ sftp\ backup\ storage[hostname\:%s]\ existing = duplicate backup storage. There has been a sftp backup storage[hostname:{0}] existing + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:554 +# args: rsp.getBackupStorageMetaFileName() +check\ image\ metadata\ file\:\ %s\ failed = check image metadata file: {0} failed + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:399 +# args: rsp.getBackupStorageMetaFileName() +create\ image\ metadata\ file\ \:\ %s\ failed = create image metadata file : {0} failed + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:559 +# args: rsp.getBackupStorageMetaFileName() +image\ metadata\ file\:\ %s\ is\ not\ exist = image metadata file: {0} is not exist + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:321 +# args: vmUuid +host\ not\ found\ for\ VM\:\ %s = host not found for VM: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:241 +# args: vmUuid +query-mirror\:\ host\ not\ found\ for\ VM[uuid\:%s] = query-mirror: host not found for VM[uuid:{0}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:328 +# args: hostUuid +libvirt\ on\ the\ host[uuid\:\ %s]\ not\ support\ to\ create\ cdp\ task,\ please\ check\ the\ version\ of\ libvirt. = libvirt on the host[uuid: {0}] not support to create cdp task, please check the version of libvirt. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:334 +# args: hostUuid +qemu\ on\ the\ host[uuid\:\ %s]\ not\ support\ to\ create\ cdp\ task,\ please\ check\ the\ version\ of\ qemu. = qemu on the host[uuid: {0}] not support to create cdp task, please check the version of qemu. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:366 +# args: vmUuid +The\ QEMU\ version\ running\ on\ the\ VM[uuid\:%s]\ does\ not\ support\ mirrorBitmap. = The QEMU version running on the VM[uuid:{0}] does not support mirrorBitmap. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:458 +# args: vol.getUuid(),reply.getError() +cannot\ ask\ primary\ storage[uuid\:%s]\ for\ volume\ snapshot\ capability,\ see\ detail\ [%s] = cannot ask primary storage[uuid:{0}] for volume snapshot capability, see detail [{1}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:320 +# args: msg.getTaskType() +unexpected\ task\ type\:\ %s = unexpected task type: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:127 +# args: +CDP\ task\ is\ still\ enabled = CDP task is still enabled + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:152 +# args: s,OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS) +invalid\ time\ string\:\ %s,\ should\ be\ in\ ISO\ offset\ format,\ for\ example\:\ %s = invalid time string: {0}, should be in ISO offset format, for example: {1} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:189 +# args: state +VM\ is\ not\ stopped,\ current\ state\:\ %s = VM is not stopped, current state: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:233 +# args: volumeUuid,msg.getVmInstanceUuid() +Shared\ volume[%s]\ from\ VM[uuid]\ is\ still\ used\ by\ other\ VMs. = Shared volume[{0}] from VM[uuid] is still used by other VMs. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:243 +# args: msg.getUuid() +Task\ not\ found[uuid\:\ %s] = Task not found[uuid: {0}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:248 +# args: msg.getUuid(),taskVO.getTaskType() +Unexpected\ task\ type[uuid\:\ %s,\ type\:\ %s] = Unexpected task type[uuid: {0}, type: {1}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:261 +# args: refVO.getResourceUuid() +VM[uuid\:\ %s]\ already\ deleted = VM[uuid: {0}] already deleted + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:275 +# args: state +Unexpected\ VM\ state\:\ %s = Unexpected VM state: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:283 +# args: taskVO.getBackupStorageUuid() +Backup\ storage\ not\ found[uuid\:\ %s] = Backup storage not found[uuid: {0}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:288 +# args: taskVO.getBackupStorageUuid() +Backup\ storage[uuid\:\ %s]\ is\ disabled = Backup storage[uuid: {0}] is disabled + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:293 +# args: taskVO.getBackupStorageUuid() +Backup\ storage[uuid\:\ %s]\ is\ not\ connected = Backup storage[uuid: {0}] is not connected + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:309 +# args: refVO.getResourceUuid() +The\ vm[uuid\:\ %s]\ has\ already\ created\ a\ backup\ job,\ cannot\ enable\ the\ cdp\ task\ at\ the\ same\ time. = The vm[uuid: {0}] has already created a backup job, cannot enable the cdp task at the same time. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:334 +# args: s2,v2,s1,v1 +'%s'(%d)\ should\ be\ larger\ than\ '%s'(%d) = '{0}'({1}) should be larger than '{2}'({3}) + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:340 +# args: "hourlyRpSinceDay" +mandatory\ args\ missing\:\ %s = mandatory args missing: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:376 +# args: vmUuids.size() +expected\ one\ VM\ uuid,\ but\ given\ %d = expected one VM uuid, but given {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:380 +# args: vmUuids.get(0) +resource\ [uuid\:\ %s]\ is\ not\ VM = resource [uuid: {0}] is not VM + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:402 +# args: msg.getTargetResourceUuid() +The\ vm[uuid\:\ %s]\ has\ already\ created\ a\ cdp\ task,\ cannot\ create\ the\ backup\ job\ at\ the\ same\ time. = The vm[uuid: {0}] has already created a cdp task, cannot create the backup job at the same time. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageImpl.java:243 +# args: groupId +No\ recovery\ point\ found\ with\ grpId\ %d = No recovery point found with grpId {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageImpl.java:717 +# args: backupStorageUuid +hostname\ not\ found\ for\ backup\ storage[uuid\:\ %s] = hostname not found for backup storage[uuid: {0}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1921 +# args: msg.getUuid() +CDP\ task[uuid\:\ %s]\ not\ found = CDP task[uuid: {0}] not found + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:179 +# args: msg.getMaxCapacity(),oldUsedCapacity +Invalid\ max\ capacity[%d],\ current\ usage\ is\ %d = Invalid max capacity[{0}], current usage is {1} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:269 +# args: vmUuid,tasks.get(0) +VM\ [uuid\:\ %s]\ have\ been\ protected\ by\ task\:\ %s = VM [uuid: {0}] have been protected by task: {1} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:715 +# args: +revert\ job\ cancelled = revert job cancelled + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:781 +# args: +create-vm\ job\ cancelled = create-vm job cancelled + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1181 +# args: taskVO.getUuid() +CDP\ task[uuid\:\ %s]\ has\ no\ VM\ attached = CDP task[uuid: {0}] has no VM attached + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1215 +# args: taskVO.getUuid() +task[uuid\:%s]\ have\ been\ deleted = task[uuid:{0}] have been deleted + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1279 +# args: taskUuid,maxCapacity,usedCapacity +CDP\ task[uuid\:%s]\ exceeded\ storage\ usage\:\ maximum\ %d,\ used\ %d. = CDP task[uuid:{0}] exceeded storage usage: maximum {1}, used {2}. + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1728 +# args: vmUuid +No\ CDP\ task\ found\ for\ VM\:\ %s = No CDP task found for VM: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1736 +# args: vmUuid +No\ CDP\ backup\ storage\ found\ for\ VM\:\ %s = No CDP backup storage found for VM: {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1784 +# args: hypervisorType +No\ CdpBackupFactory\ of\ type[%s]\ found = No CdpBackupFactory of type[{0}] found + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1815 +# args: hostUuid +No\ hypervisor\ type\ for\ VM\ %s = No hypervisor type for VM {0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:2221 +# args: msg.getVolume().getUuid() +The\ operation\ has\ volume[uuid\:\ %s]\ that\ will\ take\ chain\ type\ snapshot.\ Therefore,\ you\ could\ not\ do\ this\ operation\ when\ a\ CDP\ task\ is\ running\ on\ the\ VM\ instance. = The operation has volume[uuid: {0}] that will take chain type snapshot. Therefore, you could not do this operation when a CDP task is running on the VM instance. + +# at: src/main/java/org/zstack/storage/cdp/CdpTaskMonitor.java:163 +# args: +Could\ not\ attach\ volume.The\ VM\ instance\ is\ running\ a\ CDP\ task.\ After\ the\ volume\ is\ attached,\ the\ capacity\ required\ for\ full\ backup\ will\ exceed\ the\ CDP\ task\ planned\ size.\ Please\ plan\ the\ size\ properly\ and\ try\ again. = Could not attach volume.The VM instance is running a CDP task. After the volume is attached, the capacity required for full backup will exceed the CDP task planned size. Please plan the size properly and try again. + +# at: src/main/java/org/zstack/storage/cdp/CdpTaskMonitor.java:187 +# args: volume.getVmInstanceUuid(),volume.getUuid() +The\ VM[%s]\ for\ volume[%s]\ is\ running\ CDP,\ cannot\ resize\ now. = The VM[{0}] for volume[{1}] is running CDP, cannot resize now. + +# at: src/main/java/org/zstack/storage/cdp/CreateVmFromCdpBackupLongJob.java:88 +# args: apiMessage.getCdpTaskUuid() +No\ VM\ found\ for\ CDP\ task[uuid\:\ %s] = No VM found for CDP task[uuid: {0}] + +# at: src/main/java/org/zstack/storage/cdp/CreateVmFromCdpBackupLongJob.java:119 +# args: bsUuid +BackupStorage[uuid\:\ %s]\ already\ been\ deleted = BackupStorage[uuid: {0}] already been deleted + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:179 +# args: +no\ volume\ records\ found\ from\ VM\ backup = no volume records found from VM backup + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:138 +# args: taskUuid +VM\ CDP\ task[uuid\:\ %s]\ not\ found = VM CDP task[uuid: {0}] not found + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:147 +# args: taskUuid +VM\ not\ found\ for\ CDP\ task[uuid\:\ %s] = VM not found for CDP task[uuid: {0}] + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:236 +# args: taskUuid,msg.getGroupId() +multiple\ root\ volumes\ found\ from\ CDP\ backup\ %s\:%d = multiple root volumes found from CDP backup {0}:{1} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:250 +# args: taskUuid,msg.getGroupId() +cannot\ find\ root\ volume\ from\ CDP\ backup\ %s\:%d = cannot find root volume from CDP backup {0}:{1} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:257 +# args: taskUuid,msg.getGroupId() +root\ volume\ not\ found\ from\ CDP\ backup\ %s\:%d = root volume not found from CDP backup {0}:{1} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:118 +# args: hostUuid,this.msg.getVmInstanceUuid() +recoverVm\:\ host[uuid\:\ %s]\ not\ found\ for\ VM[uuid\:\ %s] = recoverVm: host[uuid: {0}] not found for VM[uuid: {1}] + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:216 +# args: uuids +multiple\ root\ volumes\ found\:\ %s = multiple root volumes found: {0} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:792 +# args: volumeUuid,installPath +volume[uuid\:\ %s]\ has\ unexpected\ path\:\ %s = volume[uuid: {0}] has unexpected path: {1} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:718 +# args: volumeUuid,oldVolumeSize +unexpected\ volume[uuid\:\ %s]\ size\:\ %d = unexpected volume[uuid: {0}] size: {1} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:746 +# args: volumeUuid,reply.getError().getDetails() +resize\ volume[uuid\:\ %s]\ failed\:\ %s = resize volume[uuid: {0}] failed: {1} + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:377 +# args: uuid,msg.getVmInstanceUuid() +volume\ %s\ contains\ in\ backup\ but\ detached\ from\ VM[uuid\:\ %s]\:\ you\ need\ to\ either\ attach\ it\ back\ or\ delete\ it = volume {0} contains in backup but detached from VM[uuid: {1}]: you need to either attach it back or delete it + +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:305 +# args: +no\ root\ volume\ found\ from\ VM\ backup = no root volume found from VM backup + +# at: src/main/java/org/zstack/storage/cdp/RecoverVmTracker.java:145 +# args: +kvmagent\ restarted = kvmagent restarted + +# at: src/main/java/org/zstack/storage/cdp/RecoverVmTracker.java:164 +# args: maxFailure +kvmagent\ no\ response\ %d\ times = kvmagent no response {0} times + +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:117 +# args: apiMessage.getHostUuid(),apiMessage.getBackupStorageUuid() +waiting\ host[uuid\:%s]\ and\ backupStorage[uuid\:%s]\ to\ be\ Connected... = waiting host[uuid:{0}] and backupStorage[uuid:{1}] to be Connected... -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:543 -# args: rsp.getBackupStorageMetaFileName() -check\ image\ metadata\ file\:\ %s\ failed = check image metadata file: {0} failed +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:72 +# args: apiMessage.getVmInstanceUuid() +recoverVm\:\ host\ uuid\ is\ not\ provided\ and\ original\ host\ is\ not\ found\ for\ VM[uuid\:\ %s] = recoverVm: host uuid is not provided and original host is not found for VM[uuid: {0}] -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:392 -# args: rsp.getBackupStorageMetaFileName() -create\ image\ metadata\ file\ \:\ %s\ failed = create image metadata file : {0} failed +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:165 +# args: vmUuid +No\ CDP\ task\ found\ for\ VM[uuid\:\ %s] = No CDP task found for VM[uuid: {0}] -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:548 -# args: rsp.getBackupStorageMetaFileName() -image\ metadata\ file\:\ %s\ is\ not\ exist = image metadata file: {0} is not exist +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:174 +# args: vmUuid,backupStorageUuid +CDP\ task\ for\ VM[uuid\:\ %s]\ is\ not\ found\ on\ BS[uuid\:\ %s] = CDP task for VM[uuid: {0}] is not found on BS[uuid: {1}] -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:77 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:84 # args: msg.getPoolName() operation\ failure,\ because\ the\ poolName[poolName\:%s]\ can\ not\ include\ unprintable\ ascii\ characters. = operation failure, because the poolName[poolName:{0}] can not include unprintable ascii characters. -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:91 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:98 # args: duplicatePoolUuid Ceph\ pool[uuid\:%s]\ with\ this\ name\ is\ already\ added\ into\ ZStack\ and\ used\ elsewhere,\ cannot\ reuse\ the\ ceph\ pool. = Ceph pool[uuid:{0}] with this name is already added into ZStack and used elsewhere, cannot reuse the ceph pool. -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:86 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:93 # args: msg.getPoolName(),duplicatePoolUuid creation\ failure,\ duplicate\ poolName[%s].\ There\ has\ been\ a\ pool[uuid\:%s]\ with\ the\ same\ name\ existing. = creation failure, duplicate poolName[{0}]. There has been a pool[uuid:{1}] with the same name existing. -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:119 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:126 # args: existing cannot\ add\ ceph\ primary\ storage,\ there\ has\ been\ some\ ceph\ primary\ storage\ using\ mon[hostnames\:%s] = cannot add ceph primary storage, there has been some ceph primary storage using mon[hostnames:{0}] -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:130 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:137 # args: uri.getHostname() Cannot\ add\ same\ host[%s]\ in\ mons = Cannot add same host[{0}] in mons -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:156 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:163 # args: Adding\ the\ same\ Mon\ node\ is\ not\ allowed = Adding the same Mon node is not allowed -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:235 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:202 +# args: monUrl,MON_URL_FORMAT +invalid\ monUrl[%s].\ A\ valid\ url\ is\ in\ format\ of\ %s = invalid monUrl[{0}]. A valid url is in format of {1} + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:209 +# args: +dataVolumePoolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = dataVolumePoolName can be null but cannot be an empty string + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:214 +# args: +rootVolumePoolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = rootVolumePoolName can be null but cannot be an empty string + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:219 +# args: +imageCachePoolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = imageCachePoolName can be null but cannot be an empty string + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:242 # args: existing cannot\ add\ ceph\ backup\ storage,\ there\ has\ been\ some\ ceph\ backup\ storage\ using\ mon[hostnames\:%s] = cannot add ceph backup storage, there has been some ceph backup storage using mon[hostnames:{0}] -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:243 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:250 # args: poolName\ is\ required\ when\ importImages\ is\ true = poolName is required when importImages is true +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:248 +# args: +poolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = poolName can be null but cannot be an empty string + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:269 +# args: +Third-party\ ceph\ cannot\ mixed\ with\ other\ primary\ storage. = Third-party ceph cannot mixed with other primary storage. + # at: src/main/java/org/zstack/storage/ceph/CephMonBase.java:66 # args: The\ problem\ may\ be\ caused\ by\ an\ incorrect\ user\ name\ or\ password\ or\ SSH\ port\ or\ unstable\ network\ environment = The problem may be caused by an incorrect user name or password or SSH port or unstable network environment -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:834 +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:768 +# args: path +all\ monitors\ cannot\ execute\ http\ call[%s] = all monitors cannot execute http call[{0}] + +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:866 # args: msg.getHostname(),msg.getBackupStorageUuid() CephMon[hostname\:%s]\ not\ found\ on\ backup\ storage[uuid\:%s] = CephMon[hostname:{0}] not found on backup storage[uuid:{1}] -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1218 -# args: self.getUuid(),JSONObjectUtil.toJsonString(errorCodes) -unable\ to\ connect\ to\ the\ ceph\ backup\ storage[uuid\:%s].\ Failed\ to\ connect\ all\ ceph\ mons.\ Errors\ are\ %s = unable to connect to the ceph backup storage[uuid:{0}]. Failed to connect all ceph mons. Errors are {1} - -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1339 +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1386 # args: otherCeph.getName(),otherCeph.getUuid(),fsId there\ is\ another\ CEPH\ backup\ storage[name\:%s,\ uuid\:%s]\ with\ the\ same\ FSID[%s],\ you\ cannot\ add\ the\ same\ CEPH\ setup\ as\ two\ different\ backup\ storage = there is another CEPH backup storage[name:{0}, uuid:{1}] with the same FSID[{2}], you cannot add the same CEPH setup as two different backup storage -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java:92 +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1756 +# args: msg.getImageUuid(),self.getUuid(),self.getName() +image[uuid\:\ %s]\ is\ not\ on\ backup\ storage[uuid\:%s,\ name\:%s] = image[uuid: {0}] is not on backup storage[uuid:{1}, name:{2}] + +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java:97 # args: uuid cannot\ update\ status\ of\ the\ ceph\ backup\ storage\ mon[uuid\:%s],\ it\ has\ been\ deleted.This\ error\ can\ be\ ignored = cannot update status of the ceph backup storage mon[uuid:{0}], it has been deleted.This error can be ignored -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1283 -# args: backupStorage.getUuid(),backupStorage.getName(),bsFsid,self.getUuid(),self.getName(),getSelf().getFsid() -the\ backup\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s]\ is\ not\ in\ the\ same\ ceph\ cluster\ with\ the\ primary\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s] = the backup storage[uuid:{0}, name:{1}, fsid:{2}] is not in the same ceph cluster with the primary storage[uuid:{3}, name:{4}, fsid:{5}] +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java:463 +# args: getSelf().getBackupStorageUuid() +Ceph\ bs[uuid\=%s]\ pool\ name\ not\ found = Ceph bs[uuid={0}] pool name not found -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1477 -# args: poolName -cannot\ find\ cephPrimaryStorage\ pool[poolName\=%s] = cannot find cephPrimaryStorage pool[poolName={0}] +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4126 +# args: base.getSelf().getHostname(),fsid,getSelf().getFsid() +the\ mon[ip\:%s]\ returns\ a\ fsid[%s]\ different\ from\ the\ current\ fsid[%s]\ of\ the\ cep\ cluster,are\ you\ adding\ a\ mon\ not\ belonging\ to\ current\ cluster\ mistakenly? = the mon[ip:{0}] returns a fsid[{1}] different from the current fsid[{2}] of the cep cluster,are you adding a mon not belonging to current cluster mistakenly? -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1483 -# args: poolName -cephPrimaryStorage\ pool[poolName\=%s]\ available\ capacity\ not\ enough = cephPrimaryStorage pool[poolName={0}] available capacity not enough +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1520 +# args: backupStorage.getUuid(),backupStorage.getName(),bsFsid,self.getUuid(),self.getName(),getSelf().getFsid() +the\ backup\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s]\ is\ not\ in\ the\ same\ ceph\ cluster\ with\ the\ primary\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s] = the backup storage[uuid:{0}, name:{1}, fsid:{2}] is not in the same ceph cluster with the primary storage[uuid:{3}, name:{4}, fsid:{5}] -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2303 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2588 # args: psUuid,bsUuid fsid\ is\ not\ same\ between\ ps[%s]\ and\ bs[%s],\ create\ template\ is\ forbidden. = fsid is not same between ps[{0}] and bs[{1}], create template is forbidden. -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2762 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3410 # args: self.getUuid() ceph\ primary\ storage[uuid\:%s]\ may\ have\ been\ deleted. = ceph primary storage[uuid:{0}] may have been deleted. -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2749 -# args: self.getUuid(),JSONObjectUtil.toJsonString(errorCodes) -unable\ to\ connect\ to\ the\ ceph\ primary\ storage[uuid\:%s].\ Failed\ to\ connect\ all\ ceph\ mons.\ Errors\ are\ %s = unable to connect to the ceph primary storage[uuid:{0}]. Failed to connect all ceph mons. Errors are {1} - -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2746 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3394 # args: self.getUuid() -unable\ to\ connect\ to\ the\ ceph\ primary\ storage[uuid\:%s].\ Failed\ to\ connect\ all\ ceph\ mons. = unable to connect to the ceph primary storage[uuid:{0}]. Failed to connect all ceph mons. +unable\ to\ connect\ to\ the\ ceph\ primary\ storage[uuid\:%s],\ failed\ to\ connect\ all\ ceph\ monitors. = unable to connect to the ceph primary storage[uuid:{0}], failed to connect all ceph monitors. -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2866 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3507 # args: the\ fsid\ returned\ by\ mons\ are\ mismatching,\ it\ seems\ the\ mons\ belong\ to\ different\ ceph\ clusters\:\n = the fsid returned by mons are mismatching, it seems the mons belong to different ceph clusters:\n -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2884 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3525 # args: otherCeph.getName(),otherCeph.getUuid(),fsId there\ is\ another\ CEPH\ primary\ storage[name\:%s,\ uuid\:%s]\ with\ the\ same\ FSID[%s],\ you\ cannot\ add\ the\ same\ CEPH\ setup\ as\ two\ different\ primary\ storage = there is another CEPH primary storage[name:{0}, uuid:{1}] with the same FSID[{2}], you cannot add the same CEPH setup as two different primary storage -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3135 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3783 # args: self.getUuid(),self.getName(),mon.getSelf().getUuid(),res.error the\ ceph\ primary\ storage[uuid\:%s,\ name\:%s]\ is\ down,\ as\ one\ mon[uuid\:%s]\ reports\ an\ operation\ failure[%s] = the ceph primary storage[uuid:{0}, name:{1}] is down, as one mon[uuid:{2}] reports an operation failure[{3}] -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3736 -# args: bsType -unable\ to\ upload\ bits\ to\ the\ backup\ storage[type\:%s],\ we\ only\ support\ CEPH = unable to upload bits to the backup storage[type:{0}], we only support CEPH +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4697 +# args: +operation\ error,\ because\:\ failed\ to\ get\ response = operation error, because: failed to get response + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4744 +# args: +backing\ up\ snapshots\ to\ backup\ storage\ is\ a\ depreciated\ feature,\ which\ will\ be\ removed\ in\ future\ version = backing up snapshots to backup storage is a depreciated feature, which will be removed in future version -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3910 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4915 # args: volume.getUuid(),volume.getRootImageUuid() cannot\ reinit\ rootvolume\ [%s]\ because\ image\ [%s]\ has\ been\ deleted\ and\ imagecache\ cannot\ be\ found = cannot reinit rootvolume [{0}] because image [{1}] has been deleted and imagecache cannot be found -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3929 -# args: volume.getRootImageUuid(),getSelf().getUuid() -cannot\ find\ backupstorage\ to\ download\ image\ [%s]\ to\ primarystorage\ [%s] = cannot find backupstorage to download image [{0}] to primarystorage [{1}] +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4950 +# args: ImageStatus.Ready.toString() +Because\ image\ status\ is\ not\ %s = Because image status is not {0} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:457 -# args: vol.getPrimaryStorageUuid() -cannot\ find\ any\ Connected\ ceph\ mon\ for\ the\ primary\ storage[uuid\:%s] = cannot find any Connected ceph mon for the primary storage[uuid:{0}] +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4947 +# args: +Because\ the\ image\ is\ currently\ inaccessible,\ possibly\ due\ to\ a\ previous\ volume\ storage\ migration = Because the image is currently inaccessible, possibly due to a previous volume storage migration + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4953 +# args: volume.getRootImageUuid(),getSelf().getUuid(),cause +cannot\ find\ backupstorage\ to\ download\ image\ [%s]\ to\ primarystorage\ [%s].\ %s = cannot find backupstorage to download image [{0}] to primarystorage [{1}]. {2} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:758 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:5653 # args: -not\ support\ take\ volumes\ snapshots\ on\ multiple\ ps\ when\ including\ ceph = not support take volumes snapshots on multiple ps when including ceph +allocated\ url\ not\ found = allocated url not found + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:5658 +# args: allocatedUrl +invalid\ allocated\ url\:%s = invalid allocated url:{0} + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:396 +# args: vol.getPrimaryStorageUuid() +cannot\ find\ any\ Connected\ ceph\ mon\ for\ the\ primary\ storage[uuid\:%s] = cannot find any Connected ceph mon for the primary storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:853 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:838 # args: targetCephPoolName,cephPoolName ceph\ pool\ conflict,\ the\ ceph\ pool\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ ceph\ pool\ specified\ in\ the\ creation\ parameter\ is\ %s = ceph pool conflict, the ceph pool specified by the instance offering is {0}, and the ceph pool specified in the creation parameter is {1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:984 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:964 # args: targetCephPoolName,cephPoolName ceph\ pool\ conflict,\ the\ ceph\ pool\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ ceph\ pool\ specified\ in\ the\ creation\ parameter\ is\ %s = ceph pool conflict, the ceph pool specified by the disk offering is {0}, and the ceph pool specified in the creation parameter is {1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1203 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1217 # args: rootVolume.getInstallPath(),reply.getError().getDetails() get\ rootVolume[%s]\ rbd\ image\ watchers\ fail,\ %s = get rootVolume[{0}] rbd image watchers fail, {1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1219 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1233 # args: msg.getVolumeUuid(),installPath rootVolume[%s]\ is\ already\ in\ use(ceph\ rbd\ image[%s]\ already\ has\ watchers),\ in\ order\ to\ prevent\ brain\ splitting,\ Starting\ VM\ is\ prohibited. = rootVolume[{0}] is already in use(ceph rbd image[{1}] already has watchers), in order to prevent brain splitting, Starting VM is prohibited. -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java:92 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1341 +# args: poolName +cannot\ find\ cephPrimaryStorage\ pool[poolName\=%s] = cannot find cephPrimaryStorage pool[poolName={0}] + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1351 +# args: poolName,volumeSize +cephPrimaryStorage\ pool[poolName\=%s]\ available\ virtual\ capacity\ not\ enough\ for\ size\ %s = cephPrimaryStorage pool[poolName={0}] available virtual capacity not enough for size {1} + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1399 +# args: psUuid,purpose +cannot\ allocate\ pool\ for\ primaryStorage[%s],\ purpose\:\ %s = cannot allocate pool for primaryStorage[{0}], purpose: {1} + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java:93 # args: uuid cannot\ update\ status\ of\ the\ ceph\ primary\ storage\ mon[uuid\:%s],\ it\ has\ been\ deleted.This\ error\ can\ be\ ignored = cannot update status of the ceph primary storage mon[uuid:{0}], it has been deleted.This error can be ignored +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java:471 +# args: primaryStorageUuid +Ceph\ ps[uuid\=%s]\ root\ pool\ name\ not\ found = Ceph ps[uuid={0}] root pool name not found + +# at: src/main/java/org/zstack/storage/ceph/primary/CephRequiredUrlParser.java:32 +# args: +invalid\ uri,\ correct\ example\ is\ ceph\://$POOLNAME/$VOLUMEuuid\ or\ volume\://$VOLUMEuuid = invalid uri, correct example is ceph://$POOLNAME/$VOLUMEuuid or volume://$VOLUMEuuid + +# at: src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java:19 +# args: +Can\ not\ attach\ third-party\ ceph\ with\ token\ into\ kvm\ cluster. = Can not attach third-party ceph with token into kvm cluster. + +# at: src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java:168 +# args: poolUuid,size,originAvailableCapacity +required\ ceph\ pool[uuid\:%s]\ cannot\ satisfy\ conditions\ [availableSize\ >\ %s\ bytes],\ current\ available\ size\ %s = required ceph pool[uuid:{0}] cannot satisfy conditions [availableSize > {1} bytes], current available size {2} + +# at: src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java:196 +# args: poolUuid +cannot\ find\ ceph\ pool\ [%s]\ related\ osdgroup = cannot find ceph pool [{0}] related osdgroup + +# at: src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java:95 +# args: +no\ candidate\ host\ with\ the\ scsi\ lun\ with\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = no candidate host with the scsi lun with enough cpu / memory or Enabled/Connected status + # at: src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java:54 # args: firstScsiLunVO.getUuid(),scsiLunVO.getUuid() scsi\ lun[uuid\:\ %s]\ and\ [uuid\:\ %s]\ does\ not\ has\ a\ common\ host = scsi lun[uuid: {0}] and [uuid: {1}] does not has a common host @@ -7022,165 +11434,229 @@ scsi\ lun[uuid\:\ %s]\ and\ [uuid\:\ %s]\ does\ not\ has\ a\ common\ host = scsi # args: scsiLunVO.getUuid() scsi\ lun[uuid\:\ %s]\ is\ in\ disabled\ state = scsi lun[uuid: {0}] is in disabled state -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:62 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:150 +# args: scsiLunVO.getWwid(),refVO.getVmInstanceUuid() +scsi\ lun[wwid\:\ %s]\ has\ been\ attached\ to\ vm\ instance\ %s = scsi lun[wwid: {0}] has been attached to vm instance {1} + +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:86 # args: msg.getIp(),msg.getPort() iSCSI\ server[ip\:\ %s,\ port\:\ %s]\ already\ exists = iSCSI server[ip: {0}, port: {1}] already exists -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:67 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:91 # args: msg.getIp() iSCSI\ server\ ip\:\ %s\ is\ not\ valid = iSCSI server ip: {0} is not valid -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:76 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:100 # args: msg.getUuid(),msg.getClusterUuid() iSCSI\ server[uuid\:\ %s]\ already\ attached\ to\ cluster[uuid\:\ %s] = iSCSI server[uuid: {0}] already attached to cluster[uuid: {1}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:86 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:110 # args: msg.getUuid(),msg.getClusterUuid() iSCSI\ server[uuid\:\ %s]\ not\ attached\ to\ cluster[uuid\:\ %s] = iSCSI server[uuid: {0}] not attached to cluster[uuid: {1}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:97 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:121 # args: msg.getUuid(),clusterUuid iSCSI\ server[uuid\:\ %s]\ still\ attached\ to\ cluster[uuid\:\ %s] = iSCSI server[uuid: {0}] still attached to cluster[uuid: {1}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:126 -# args: scsiLunVO.getWwid(),refVO.getVmInstanceUuid() -scsi\ lun[wwid\:\ %s]\ has\ been\ attached\ to\ vm\ instance\ %s = scsi lun[wwid: {0}] has been attached to vm instance {1} +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:171 +# args: VmInstanceUuid +please\ umount\ all\ block\ devices\ of\ the\ vm[%s]\ and\ try\ again = please umount all block devices of the vm[{0}] and try again -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1188 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1501 +# args: lunVO.getWwid(),msg.getVmInstanceUuid() +scsi\ lun[wwid\:%s]\ has\ been\ attached\ into\ the\ vm[%s] = scsi lun[wwid:{0}] has been attached into the vm[{1}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1508 # args: msg.getUuid(),vmInstanceVO.getState(),allowedVmOperationStates vm\ instance[%s]\ state\ [%s]\ not\ in\ allowed\ state[%s]\ for\ operation = vm instance[{0}] state [{1}] not in allowed state[{2}] for operation -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1197 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1517 # args: msg.getUuid(),vmInstanceVO.getHostUuid(),msg.getUuid() vm\ instance[uuid\:\ %s]\ host[uuid\:\ %s]\ not\ attached\ scsi\ lun[uuid\:\ %s] = vm instance[uuid: {0}] host[uuid: {1}] not attached scsi lun[uuid: {2}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1256 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1576 # args: msg.getVmInstanceUuid(),vmInstanceVO.getState(),allowedVmOperationStates vm\ instance[%s]\ state[%s]\ not\ in\ allowed\ state[%s]\ for\ operation = vm instance[{0}] state[{1}] not in allowed state[{2}] for operation -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1265 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1585 # args: msg.getVmInstanceUuid(),hostVO.getUuid(),msg.getUuid() vm\ instance[%s]\ host[uuid\:\ %s]\ not\ attached\ scsi\ lun[uuid\:\ %s] = vm instance[{0}] host[uuid: {1}] not attached scsi lun[uuid: {2}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1447 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1738 +# args: msg.getUuid(),vmUuids +SCSI\ LUN[%s]\ is\ attached\ to\ VM\ [%s] = SCSI LUN[{0}] is attached to VM [{1}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1748 +# args: msg.getUuid(),msg.getHostUuid() +SCSI\ LUN[%s]\ record\ not\ found\ on\ host\ [%s] = SCSI LUN[{0}] record not found on host [{1}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1760 +# args: hvType,msg.getHostUuid() +unexpected\ hypervisor\ type[%s]\ for\ host\ [%s] = unexpected hypervisor type[{0}] for host [{1}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:2024 +# args: serial +different\ disk\ types\ are\ found\ in\ different\ hosts\ for\ lun[serial\:%s],\ unable\ to\ attach\ it\ to\ cluster = different disk types are found in different hosts for lun[serial:{0}], unable to attach it to cluster + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1975 # args: scannedServer.getKey(),JSONObjectUtil.toJsonString(scannedTargets),hostVO.getUuid(),JSONObjectUtil.toJsonString(returnValue.getIscsiTargets()) different\ iscsi\ configuration\ were\ found\ on\ host[uuid\:%s,\ targets\:%s]and\ host[uuid\:%s,\ targets\:%s] = different iscsi configuration were found on host[uuid:{0}, targets:{1}]and host[uuid:{2}, targets:{3}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:2055 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:2661 # args: refVO.getScsiLunUuid() specified\ scsi\ lun[wwid\:\ %s]\ not\ exists\ or\ disabled = specified scsi lun[wwid: {0}] not exists or disabled -# at: src/main/java/org/zstack/storage/migration/KvmStorageLiveMigrationFlowChain.java:256 +# at: src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java:60 +# args: msg.getVolumeUuid() +the\ vm\ where\ the\ data\ volume\ [%s]\ is\ located\ has\ a\ memory\ snapshot,\ can't\ delete = the vm where the data volume [{0}] is located has a memory snapshot, can't delete + +# at: src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java:71 +# args: msg.getVolumeUuid(),msg.getVmInstanceUuid() +unable\ to\ attach\ volume\ %s\ to\ vmInstance\ %s\ with\ memory\ snapshot\ group = unable to attach volume {0} to vmInstance {1} with memory snapshot group + +# at: src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java:78 +# args: msg.getVolumeUuid() +the\ vm\ where\ the\ data\ volume\ [%s]\ is\ located\ has\ a\ memory\ snapshot,\ can't\ detach = the vm where the data volume [{0}] is located has a memory snapshot, can't detach + +# at: src/main/java/org/zstack/storage/memorySnapshot/VmNicMemorySnapshotGroupExtension.java:60 # args: -No\ host\ available\ for\ block\ live\ migration = No host available for block live migration +defaultL3NetworkUuid\ not\ exist = defaultL3NetworkUuid not exist + +# at: src/main/java/org/zstack/storage/memorySnapshot/VmNicMemorySnapshotGroupExtension.java:432 +# args: l3Uuid,String.join("','", memorySnapshotGroupUuidList) +nic\ with\ l3\ network[uuid\:\ %s]\ is\ referenced\ by\ VolumeSnapshotGroup[uuid\:\ %s],\ delete\ this\ VolumeSnapshotGroup\ before\ deleting\ this\ l3\ network. = nic with l3 network[uuid: {0}] is referenced by VolumeSnapshotGroup[uuid: {1}], delete this VolumeSnapshotGroup before deleting this l3 network. -# at: src/main/java/org/zstack/storage/migration/KvmStorageLiveMigrationFlowChain.java:494 +# at: src/main/java/org/zstack/storage/memorySnapshot/VolumeMemorySnapshotGroupExtension.java:155 +# args: archiveVolume.getResourceUuid() +the\ volume\ %s\ does\ not\ exist = the volume {0} does not exist + +# at: src/main/java/org/zstack/storage/migration/KvmBlockLiveMigrationWorkFlow.java:161 # args: rsp.getError() -live\ block\ migration\ failed\:\ %s = live block migration failed: {0} +vm\ block\ migrate\ failed\:\ %s = vm block migrate failed: {0} + +# at: src/main/java/org/zstack/storage/migration/KvmBlockLiveMigrationWorkFlow.java:188 +# args: +target\ primary\ storage\ does\ not\ support\ migration\ for\ current\ host = target primary storage does not support migration for current host + +# at: src/main/java/org/zstack/storage/migration/KvmMigrateVmWithStorageWorkFlow.java:116 +# args: +No\ host\ available\ for\ block\ live\ migration = No host available for block live migration -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:123 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:121 # args: do\ not\ support\ storage\ migration\ with\ iso\ in\ ceph\ backup\ storage\ attached = do not support storage migration with iso in ceph backup storage attached -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:292 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:289 # args: srcVm.getUuid(),srcVm.getName() do\ not\ support\ storage\ migration\ of\ vm[uuid\:%s,\ name\:\ %s]\ while\ shared\ volume\ attached = do not support storage migration of vm[uuid:{0}, name: {1}] while shared volume attached -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:175 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:173 # args: srcPsType,dstPsType do\ not\ support\ storage\ migration\ from\ [%s]\ to\ [%s]\ with\ data\ volume = do not support storage migration from [{0}] to [{1}] with data volume -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:180 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:178 # args: srcPsType,dstPsType do\ not\ support\ storage\ migration\ from\ [%s]\ to\ [%s]\ with\ snapshot = do not support storage migration from [{0}] to [{1}] with snapshot -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:188 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:185 # args: primaryStorageVO.getType(),dstPrimaryStorageVO.getType() do\ not\ support\ storage\ migration\ from\ [%s]\ to\ [%s] = do not support storage migration from [{0}] to [{1}] -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:194 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:191 # args: vmInstanceVO.getUuid() VM[uuid\:%s]\ is\ running\ but\ host\ uuid\ is\ missing = VM[uuid:{0}] is running but host uuid is missing -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:205 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:202 # args: Source\ BS\ and\ Destination\ BS\ cannot\ be\ the\ same. = Source BS and Destination BS cannot be the same. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:213 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:210 # args: Source\ BS\ and\ Destination\ BS\ must\ not\ be\ Disabled. = Source BS and Destination BS must not be Disabled. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:220 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:217 # args: msg.getImageUuid() Image[uuid\:%s]\ is\ not\ in\ status\ Ready,\ cannot\ migrate\ it. = Image[uuid:{0}] is not in status Ready, cannot migrate it. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:231 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:228 # args: msg.getImageUuid(),msg.getSrcBackupStorageUuid() Image[uuid\:%s]\ is\ not\ in\ source\ backup\ storage[uuid\:%s] = Image[uuid:{0}] is not in source backup storage[uuid:{1}] -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:240 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:237 # args: srcBS.getType(),dstBS.getType() Cannot\ migrate\ image\ from\ %s\ to\ %s. = Cannot migrate image from {0} to {1}. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:260 -# args: -Source\ PS\ and\ Destination\ PS\ must\ not\ be\ Disabled\ or\ Maintenance\ state. = Source PS and Destination PS must not be Disabled or Maintenance state. - -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:267 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:256 # args: msg.getVolumeUuid(),msg.getDstPrimaryStorageUuid() Volume[uuid\:%s]\ is\ already\ in\ PS[uuid\:%s],\ cannot\ migrate. = Volume[uuid:{0}] is already in PS[uuid:{1}], cannot migrate. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:274 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:264 +# args: +Source\ PS\ and\ Destination\ PS\ must\ not\ be\ Disabled\ or\ Maintenance\ state. = Source PS and Destination PS must not be Disabled or Maintenance state. + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:271 # args: msg.getVolumeUuid() Volume[uuid\:%s]\ is\ not\ in\ status\ Ready,\ cannot\ migrate\ it. = Volume[uuid:{0}] is not in status Ready, cannot migrate it. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:330 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:333 +# args: msg.getVolumeUuid(),srcVolume.getVmInstanceUuid() +cannot\ migrate\ data\ volume[uuid\:%s]\ bewteen\ sharedblock\ primary\ storages\ when\ vm[vmuuid\:%s]\ instance\ is\ not\ stopped. = cannot migrate data volume[uuid:{0}] bewteen sharedblock primary storages when vm[vmuuid:{1}] instance is not stopped. + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:328 # args: msg.getVolumeUuid(),srcVolume.getVmInstanceUuid() the\ volume[uuid\:%s]\ is\ still\ attached\ on\ vm[uuid\:%s],\ please\ detach\ it\ before\ migration. = the volume[uuid:{0}] is still attached on vm[uuid:{1}], please detach it before migration. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:338 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:341 # args: srcVolume.getUuid(),srcVolume.getName() do\ not\ support\ storage\ migration\ while\ shared\ volume[uuid\:\ %s,\ name\:\ %s]\ attached = do not support storage migration while shared volume[uuid: {0}, name: {1}] attached -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:287 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:284 # args: Cannot\ migrate\ root\ volume\ when\ vm\ instance\ is\ not\ stopped. = Cannot migrate root volume when vm instance is not stopped. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:304 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:301 # args: Cannot\ migrate\ root\ volume\ when\ there\ are\ data\ volumes\ attached\ to\ the\ vm\ instance. = Cannot migrate root volume when there are data volumes attached to the vm instance. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:323 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:320 # args: The\ destination\ primary\ storage\ is\ not\ attached\ to\ any\ cluster\ that\ has\ the\ same\ L2\ networks\ as\ source\ cluster. = The destination primary storage is not attached to any cluster that has the same L2 networks as source cluster. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:348 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:351 # args: srcPS.getType(),dstPS.getType() Cannot\ migrate\ volume\ from\ %s\ to\ %s. = Cannot migrate volume from {0} to {1}. -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:531 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:372 +# args: msg.getVolumeUuid() +can\ not\ migrate\ volume[%s],\ because\ volume\ state\ is\ Disabled = can not migrate volume[{0}], because volume state is Disabled + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:510 # args: vmInstanceVO.getState() not\ support\ vm\ state[%s]\ to\ do\ storage\ migration = not support vm state[{0}] to do storage migration -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:472 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:448 # args: msg.getVmInstanceUuid(),size,dstPrimaryStorageVO.getCapacity().getAvailablePhysicalCapacity() there\ are\ not\ enough\ capacity\ for\ vm[uuid\:\ %s]\ storage\ migration,\ required\ capacity(include\ image\ cache)\:\ %s,\ current\ available\ physical\ capacity\:\ %s = there are not enough capacity for vm[uuid: {0}] storage migration, required capacity(include image cache): {1}, current available physical capacity: {2} -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:582 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1125 # args: msg.getVmInstanceUuid() VM[uuid\:\ %s]\ not\ found = VM[uuid: {0}] not found -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:815 -# args: srcPs.getType() -unsupported\ primary\ storage\ type[%s]\ for\ storage\ migration = unsupported primary storage type[{0}] for storage migration +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:846 +# args: srcPs.getType(),dstPs.getType() +unsupported\ storage\ migration\ type\:\ from\ %s\ to\ %s = unsupported storage migration type: from {0} to {1} -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1001 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1094 # args: msg.getType() not\ support\ to\ cancel\ %s = not support to cancel {0} -# at: src/main/java/org/zstack/storage/migration/backup/ReserveCapacityFromDstBSFlow.java:61 -# args: imageUuid,dstBsUuid -Cannot\ reserve\ enough\ space\ for\ Image[uuid\:%s]\ in\ BS[uuid\:%s] = Cannot reserve enough space for Image[uuid:{0}] in BS[uuid:{1}] +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1194 +# args: vmInstanceVO.getState() +not\ support\ vm\ state[%s]\ to\ do\ cancellation\ of\ storage\ migration = not support vm state[{0}] to do cancellation of storage migration + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1514 +# args: +failed\ to\ get\ host\ candidates\ for\ vm\ migration = failed to get host candidates for vm migration # at: src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java:114 # args: dstBsVO.getUuid() @@ -7194,55 +11670,51 @@ Failed\ to\ migrate\ Image\ %s\ from\ BS\ %s\ to\ BS\ %s.\ cause\:\ %s = Failed # args: reply1.getTrashId(),dstBsUuid,dstImageInstallPath,reply1.getResourceUuid() found\ trashId(%s)\ in\ BackupStorage\ [%s]\ for\ the\ migrate\ installPath[%s].\ Please\ clean\ it\ first\ by\ 'APICleanUpTrashOnBackupStorageMsg'\ if\ you\ insist\ to\ migrate\ the\ image[%s] = found trashId({0}) in BackupStorage [{1}] for the migrate installPath[{2}]. Please clean it first by 'APICleanUpTrashOnBackupStorageMsg' if you insist to migrate the image[{3}] -# at: src/main/java/org/zstack/storage/migration/primary/ReserveCapacityFromDstPSFlow.java:85 -# args: volumeUuid,dstPsUuid -Cannot\ reserve\ enough\ space\ for\ Volume[uuid\:%s]\ in\ PS[uuid\:%s] = Cannot reserve enough space for Volume[uuid:{0}] in PS[uuid:{1}] - -# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:120 -# args: dstPsVO.getUuid() -all\ ceph\ mons\ are\ Disconnected\ in\ ceph\ primary\ storage[uuid\:%s] = all ceph mons are Disconnected in ceph primary storage[uuid:{0}] +# at: src/main/java/org/zstack/storage/migration/primary/PrimaryStorageMigrateVmJob.java:141 +# args: amsg.getVmInstanceUuid(),job.getUuid() +vm[uuid\:%s]\ storage\ migration\ long\ job[uuid\:%s]\ failed\ because\ management\ node\ was\ restarted = vm[uuid:{0}] storage migration long job[uuid:{1}] failed because management node was restarted -# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:571 +# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:584 # args: volume.getType() The\ type\ [%s]\ of\ volume\ is\ invalid. = The type [{0}] of volume is invalid. -# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:88 +# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:122 +# args: dstPsVO.getUuid() +all\ ceph\ mons\ are\ Disconnected\ in\ ceph\ primary\ storage[uuid\:%s] = all ceph mons are Disconnected in ceph primary storage[uuid:{0}] + +# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:89 # args: cannot\ find\ any\ connected\ host\ to\ perform\ the\ storage\ migration\ operation = cannot find any connected host to perform the storage migration operation -# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:187 +# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:194 # args: imageUuid both\ image\ %s\ and\ its\ cache\ is\ missing = both image {0} and its cache is missing -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:189 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:203 # args: 'resourceUuid'\ and\ 'resourceType'\ must\ be\ set\ both\ or\ neither! = 'resourceUuid' and 'resourceType' must be set both or neither! -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:85 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:92 # args: zoneUuids,\ clusterUuids,\ primaryStorageUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = zoneUuids, clusterUuids, primaryStorageUuids must have at least one be none-empty list, or all is set to true -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:107 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:114 # args: msg.getPrimaryStorageUuid(),msg.getClusterUuid() primary\ storage[uuid\:%s]\ has\ not\ been\ attached\ to\ cluster[uuid\:%s]\ yet = primary storage[uuid:{0}] has not been attached to cluster[uuid:{1}] yet -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:124 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:131 # args: msg.getPrimaryStorageUuid(),msg.getClusterUuid() primary\ storage[uuid\:%s]\ has\ been\ attached\ to\ cluster[uuid\:%s] = primary storage[uuid:{0}] has been attached to cluster[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:139 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:146 # args: msg.getPrimaryStorageUuid(),msg.getClusterUuid() primary\ storage[uuid\:%s]\ and\ cluster[uuid\:%s]\ are\ not\ in\ the\ same\ zone = primary storage[uuid:{0}] and cluster[uuid:{1}] are not in the same zone -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:161 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:168 # args: url url[%s]\ has\ been\ occupied,\ it\ cannot\ be\ duplicate\ in\ same\ cluster = url[{0}] has been occupied, it cannot be duplicate in same cluster -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:181 -# args: msg.getPrimaryStorageUuid(),clusterUuidsString -primary\ storage[uuid\:%s]\ cannot\ be\ deleted\ for\ still\ being\ attached\ to\ cluster[uuid\:%s]. = primary storage[uuid:{0}] cannot be deleted for still being attached to cluster[uuid:{1}]. - -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:206 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:220 # args: psUuids primary\ storage(s)\ [uuid\:\ %s]\ where\ volume(s)\ locate\ is\ not\ Enabled\ or\ Connected = primary storage(s) [uuid: {0}] where volume(s) locate is not Enabled or Connected @@ -7250,19 +11722,23 @@ primary\ storage(s)\ [uuid\:\ %s]\ where\ volume(s)\ locate\ is\ not\ Enabled\ o # args: spec.getAvoidPrimaryStorageUuids() after\ removing\ primary\ storage%s\ to\ avoid,\ there\ is\ no\ candidate\ primary\ storage\ anymore.\ please\ check\ primary\ storage\ status\ and\ state\ in\ the\ cluster. = after removing primary storage{0} to avoid, there is no candidate primary storage anymore. please check primary storage status and state in the cluster. -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:221 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:239 # args: self.getUuid() cannot\ attach\ ISO\ to\ a\ primary\ storage[uuid\:%s]\ which\ is\ disabled = cannot attach ISO to a primary storage[uuid:{0}] which is disabled -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:657 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:769 # args: bsUuid,self.getZoneUuid(),self.getUuid() backup\ storage[uuid\:%s]\ is\ not\ attached\ to\ zone[uuid\:%s]\ the\ primary\ storage[uuid\:%s]\ belongs\ to = backup storage[uuid:{0}] is not attached to zone[uuid:{1}] the primary storage[uuid:{2}] belongs to -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:781 -# args: -operation\ not\ supported = operation not supported +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:789 +# args: volUuid,vmState +volume[uuid\:%s]\ has\ been\ attached\ a\ %s\ VM.\ VM\ should\ be\ Stopped. = volume[uuid:{0}] has been attached a {1} VM. VM should be Stopped. + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:1602 +# args: self.getUuid(),clusterUuidsString +primary\ storage[uuid\:%s]\ cannot\ be\ deleted\ for\ still\ being\ attached\ to\ cluster[uuid\:%s]. = primary storage[uuid:{0}] cannot be deleted for still being attached to cluster[uuid:{1}]. -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:1558 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:1749 # args: volumeUuid cannot\ attach\ volume[uuid\:%s]\ whose\ primary\ storage\ is\ Maintenance = cannot attach volume[uuid:{0}] whose primary storage is Maintenance @@ -7274,42 +11750,46 @@ cannot\ reserve\ %s\ bytes\ on\ the\ primary\ storage[uuid\:%s],\ it's\ short\ o # args: ps.getUuid(),ps.getStatus().toString() the\ primary\ storage[uuid\:%s]\ is\ not\ in\ status\ of\ Connected,\ current\ status\ is\ %s = the primary storage[uuid:{0}] is not in status of Connected, current status is {1} -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:115 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageMainAllocatorFlow.java:225 +# args: spec.getImageUuid() +no\ way\ to\ get\ image\ size\ of\ %s,\ report\ exception. = no way to get image size of {0}, report exception. + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:106 # args: systemTag,uuid %s\ is\ invalid.\ %s\ is\ not\ a\ valid\ zstack\ uuid = {0} is invalid. {1} is not a valid zstack uuid -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:119 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:110 # args: resourceUuid no\ primary\ storage[uuid\:%s]\ found = no primary storage[uuid:{0}] found -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:147 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:138 # args: msg.getUuid() primaryStorage[uuid\=%s]\ does\ not\ exist = primaryStorage[uuid={0}] does not exist -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:482 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:492 +# args: +please\ specify\ the\ purpose\ before\ allocating\ space = please specify the purpose before allocating space + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:614 # args: errs cannot\ find\ any\ qualified\ primary\ storage,\ errors\ are\ %s = cannot find any qualified primary storage, errors are {0} -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:558 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:833 # args: cidr cidr[%s]\ Input\ Format\ Error = cidr[{0}] Input Format Error -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:554 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:829 # args: cidrCount only\ one\ primaryStorage\ cidr\ system\ tag\ is\ allowed,\ but\ %d\ got = only one primaryStorage cidr system tag is allowed, but {0} got -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:903 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:1186 +# args: clusterUuid,msg.getClusterUuid() +clusterUuid\ conflict,\ the\ cluster\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ cluster\ specified\ in\ the\ creation\ parameter\ is\ %s = clusterUuid conflict, the cluster specified by the instance offering is {0}, and the cluster specified in the creation parameter is {1} + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:1201 # args: psUuid,msg.getPrimaryStorageUuidForRootVolume() primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = primaryStorageUuid conflict, the primary storage specified by the instance offering is {0}, and the primary storage specified in the creation parameter is {1} -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:985 -# args: psUuid,msg.getPrimaryStorageUuid() -primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = primaryStorageUuid conflict, the primary storage specified by the disk offering is {0}, and the primary storage specified in the creation parameter is {1} - -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageReservedCapacityAllocatorFlow.java:55 -# args: PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value(),spec.getSize() -after\ subtracting\ reserved\ capacity[%s],\ there\ is\ no\ primary\ storage\ having\ required\ size[%s\ bytes],\ may\ be\ the\ threshold\ of\ primary\ storage\ physical\ capacity\ setting\ is\ lower = after subtracting reserved capacity[{0}], there is no primary storage having required size[{1} bytes], may be the threshold of primary storage physical capacity setting is lower - # at: src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorExtension.java:127 # args: uuid cannot\ find\ primary\ storage[uuid\:%s],\ the\ uuid\ is\ specified\ in\ instance\ offering\ or\ disk\ offering = cannot find primary storage[uuid:{0}], the uuid is specified in instance offering or disk offering @@ -7322,239 +11802,463 @@ cannot\ find\ primary\ storage\ having\ user\ tag[%s].\ The\ user\ tag\ is\ spec # args: extp.getClass().getName() PrimaryStorageTagAllocatorExtensionPoint[%s]\ returns\ zero\ primary\ storage\ candidate = PrimaryStorageTagAllocatorExtensionPoint[{0}] returns zero primary storage candidate -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:132 -# args: path,JSONObjectUtil.toJsonString(errorCodes) -all\ mons\ failed\ to\ execute\ http\ call[%s],\ errors\ are\ %s = all mons failed to execute http call[{0}], errors are {1} +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1825 +# args: +not\ support = not support + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:471 +# args: bsType +cannot\ find\ any\ BackupStorageKvmFactory\ for\ the\ type[%s] = cannot find any BackupStorageKvmFactory for the type[{0}] + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:670 +# args: self.getUuid(),self.getName() +the\ block\ primary\ storage[uuid\:%s,\ name\:%s]\ can\ not\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = the block primary storage[uuid:{0}, name:{1}] can not find any available host in attached clusters for instantiating the volume + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1242 +# args: msg.getVolumeInventory().getUuid() +fail\ to\ find\ a\ host\ to\ map\ for\ volume\ %s = fail to find a host to map for volume {0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1491 +# args: +host\ uuid\ is\ mandatory = host uuid is mandatory + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1612 +# args: msg.getDestHostUuid() +Fail\ to\ get\ host\ initiator\ ref,\ please\ reconnect\ this\ host\:%s = Fail to get host initiator ref, please reconnect this host:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:2608 +# args: msg.getPrimaryStorageUuid() +fail\ to\ find\ cluster\ for\ commit\ volume\ on\ ps\:%s = fail to find cluster for commit volume on ps:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:2617 +# args: msg.getVolumeUuid() +fail\ to\ find\ host\ for\ commit\ volume\:%s = fail to find host for commit volume:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:1132 +# args: +not\ support\ take\ volumes\ snapshots\ on\ multiple\ ps\ when\ including\ ceph = not support take volumes snapshots on multiple ps when including ceph + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:370 +# args: context.getInventory().getUuid(),priUuid,reply.getError() +KVM\ host[uuid\:\ %s]\ fails\ to\ be\ added\ into\ local\ primary\ storage[uuid\:\ %s],\ %s = KVM host[uuid: {0}] fails to be added into local primary storage[uuid: {1}], {2} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:669 +# args: volume.getUuid() +fail\ to\ find\ block\ scsi\ lun\ for\ volume\:\ %s = fail to find block scsi lun for volume: {0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:967 +# args: e.getCause().toString() +fail\ to\ exchange\ block\ scsi\ lun\ info\:%s = fail to exchange block scsi lun info:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:1560 +# args: +currently\ block\ storage\ only\ support\ full\ mode\ backup = currently block storage only support full mode backup + +# at: src/main/java/org/zstack/storage/primary/block/ImageStoreBackupStorageBlockKvmDownloader.java:143 +# args: bsPath,greply.getHostname(),pinv.getUuid(),psPath,rsp.getError() +failed\ to\ download[%s]\ from\ BackupStorage[hostname\:%s]\ to\ block\ primary\ storage[uuid\:%s,\ path\:%s],\ %s = failed to download[{0}] from BackupStorage[hostname:{1}] to block primary storage[uuid:{2}, path:{3}], {4} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:875 +# args: accessZoneRsp.getDetail_err_msg() +fail\ to\ sync\ access\ zones\ because\ %s = fail to sync access zones because {0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:881 +# args: queryAccessZoneSubnetRsp.getDetail_err_msg() +fail\ to\ get\ access\ zone's\ subnet\ because\ %s = fail to get access zone's subnet because {0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:893 +# args: queryHostRsp.getDetail_err_msg() +fail\ to\ query\ all\ hosts,\ because\ of\ %s = fail to query all hosts, because of {0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:908 +# args: ids.toString(),queryHostRsp.getDetail_err_msg() +fail\ to\ query\ hosts\ %s,\ because\ of\ %s = fail to query hosts {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:927 +# args: String.valueOf(hostId),String.valueOf(hostGroupId),addHostRsp.getDetail_err_msg() +fail\ to\ add\ host\ %s\ into\ hostGroup\ %s,\ because\ of\ %s = fail to add host {0} into hostGroup {1}, because of {2} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:962 +# args: String.valueOf(initiatorId) +host\ id\ is\ mandatory\ but\ get\:%s = host id is mandatory but get:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:943 +# args: String.valueOf(hostId),rsp.getDetail_err_msg() +fail\ to\ delete\ host\ %s,\ because\ of\ %s = fail to delete host {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:955 +# args: String.valueOf(hostGroupId),rsp.getDetail_err_msg() +fail\ to\ delete\ host\ group\ %s,\ because\ of\ %s = fail to delete host group {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:967 +# args: String.valueOf(initiatorId),rsp.getDetail_err_msg() +fail\ to\ delete\ initiator\ %s,\ because\ of\ %s = fail to delete initiator {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:975 +# args: queryHostGroupRsp.getDetail_err_msg() +fail\ to\ query\ host\ group,\ because\ of\ %s = fail to query host group, because of {0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:993 +# args: name,addHostGroupRsp.getDetail_err_msg() +fail\ to\ add\ host\ group\:\ %s,\ error\ message\:%s\ = fail to add host group: {0}, error message:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1011 +# args: ids.toString(),queryLunRsp.getDetail_err_msg() +fail\ to\ query\ lun\ \:\ %s,\ error\ message\:%s\ = fail to query lun : {0}, error message:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1050 +# args: queryPath,queryLunRsp.getDetail_err_msg() +fail\ to\ query\ lun\ by\ path\:\ %s,\ error\ message\:%s\ = fail to query lun by path: {0}, error message:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1067 +# args: name,serverCommonRsp.getDetail_err_msg() +fail\ to\ update\ lun\ name\:\ %s,\ error\ message\:%s\ = fail to update lun name: {0}, error message:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1178 +# args: blockScsiLunVO.getName(),serverRsp.getDetail_err_msg() +fail\ to\ create\ lun\ name\:\ %s,\ error\ message\:%s\ = fail to create lun name: {0}, error message:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1115 +# args: blockScsiLunVO.getName(),serverRsp.getDetail_err_msg() +fail\ to\ get\ created\ lun[name\:\ %s],\ error\ message\:%s\ = fail to get created lun[name: {0}], error message:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1129 +# args: blockScsiLunVO.getName() +fail\ to\ create\ lun\ name\:\ %s,\ can\ not\ find\ root\ cause = fail to create lun name: {0}, can not find root cause + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1188 +# args: String.valueOf(lunId),queryLunRsp.getDetail_err_msg() +fail\ to\ query\ lun\ %s,\ because\ of\ %s = fail to query lun {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1204 +# args: String.valueOf(lunId),String.valueOf(hostGroupId),queryLunMapRsp.getDetail_err_msg() +fail\ to\ query\ lun\ map\ for\ lun\ %s\ and\ host\ group\ %s,\ because\ of\ %s = fail to query lun map for lun {0} and host group {1}, because of {2} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1225 +# args: String.valueOf(hostGroupId),queryLunMapRsp.getDetail_err_msg() +fail\ to\ query\ lun\ map\ for\ host\ group\ %s,\ because\ of\ %s = fail to query lun map for host group {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1236 +# args: clusterOverviewRsp.getDetail_err_msg() +fail\ to\ get\ cluster\ info,\ because\ of\ %s = fail to get cluster info, because of {0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1259 +# args: String.valueOf(lunId),String.valueOf(hostGroupId),serverRsp.getDetail_err_msg() +fail\ to\ map\ lun\ %s\ to\ host\ group\ %s,\ because\ of\ %s = fail to map lun {0} to host group {1}, because of {2} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1267 +# args: String.valueOf(lunMapId) +lun\ map\ id\ is\ mandatory\ but\ get\:%s = lun map id is mandatory but get:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1273 +# args: String.valueOf(lunMapId),serverRsp.getDetail_err_msg() +fail\ to\ delete\ lun\ map\ %s,\ because\ of\ %s = fail to delete lun map {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1279 +# args: String.valueOf(lunId) +lun\ id\ is\ mandatory\ but\ get\:%s = lun id is mandatory but get:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1285 +# args: String.valueOf(lunId),serverRsp.getDetail_err_msg() +fail\ to\ delete\ lun\ %s,\ because\ of\ %s = fail to delete lun {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1295 +# args: String.valueOf(id),storagePoolRsp.getDetail_err_msg() +fail\ to\ get\ storage\ pool\ %s,\ because\ of\ %s = fail to get storage pool {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1308 +# args: JSONObjectUtil.toJsonString(blockScsiLunVO),rsp.getDetail_err_msg() +fail\ to\ create\ snapshot\ for\ lun\ %s,\ because\ of\ %s = fail to create snapshot for lun {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1330 +# args: ids.toString(),rsp.getDetail_err_msg() +fail\ to\ query\ snapshots\ %s,\ because\ of\ %s = fail to query snapshots {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1337 +# args: String.valueOf(snapshotId) +snapshot\ id\ is\ mandatory\ but\ get\:%s = snapshot id is mandatory but get:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1344 +# args: String.valueOf(snapshotId),rsp.getDetail_err_msg() +fail\ to\ delete\ snapshot\ %s,\ because\ of\ %s = fail to delete snapshot {0}, because of {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1355 +# args: String.valueOf(snapshotId),serverRsp.getDetail_err_msg() +fail\ to\ revert\ snapshot\:%s,\ because\ of\:\ %s = fail to revert snapshot:{0}, because of: {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1364 +# args: String.valueOf(lunId),getLunSessionRsp.getDetail_err_msg() +fail\ to\ check\ lun\ %s\ session\ state\ ,\ because\ of\:\ %s = fail to check lun {0} session state , because of: {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1380 +# args: String.valueOf(lunId),queryLunMapRsp.getDetail_err_msg() +fail\ to\ get\ lun\ %s\ maps,\ because\ of\:\ %s = fail to get lun {0} maps, because of: {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1402 +# args: String.valueOf(lunId),lunQuantityInfoRsp.getDetail_err_msg() +fail\ to\ get\ lun\ %s\ remain\ created\ lun\ number,\ because\ of\:\ %s = fail to get lun {0} remain created lun number, because of: {1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:161 +# args: +lun\ map\ id\ is\ mandatory\ can\ not\ be\ null,\ neither\ 0 = lun map id is mandatory can not be null, neither 0 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:194 +# args: +lun\ id\ is\ illegal = lun id is illegal + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:527 +# args: clusterOverview.getCluster_data_state(),clusterOverview.getCluster_healthy_state(),clusterOverview.getCluster_running_state() +XStor\ cluster\ is\ unhealthy,\ cluster\ info[cluster_\ data_\ state\:\ %s,\ cluster_\ healthy_\ state\:\ %s,\ cluster_\ running_\ state\:\ %s] = XStor cluster is unhealthy, cluster info[cluster_ data_ state: {0}, cluster_ healthy_ state: {1}, cluster_ running_ state: {2}] + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:555 +# args: +illegal\ lun\ id = illegal lun id + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:647 +# args: +fail\ to\ get\ image\ cache\ lun\ info = fail to get image cache lun info + +# at: src/main/java/org/zstack/storage/primary/ceph/CephHostHeartbeatChecker.java:204 +# args: targetHostUuid +host\ %s's\ heartbeat\ is\ not\ updated = host {0}'s heartbeat is not updated + +# at: src/main/java/org/zstack/storage/primary/filesystem/AbstractFileSystemHostHeartbeatChecker.java:116 +# args: cmd.targetHostUuid +host[uuid\:%s]'s\ heartbeat\ is\ not\ updated = host[uuid:{0}]'s heartbeat is not updated -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:97 +# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:120 # args: vo.getUuid() all\ ceph\ mons\ of\ primary\ storage[uuid\:%s]\ are\ not\ in\ Connected\ state = all ceph mons of primary storage[uuid:{0}] are not in Connected state -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:120 +# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:164 # args: param.getPrimaryStorageUuid() CephPrimaryStorage[%s]\ not\ existed! = CephPrimaryStorage[{0}] not existed! -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:170 +# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:201 # args: licMgr.getLicenseType().toString() current\ license[%s]\ is\ not\ valid\ license\ while\ download\ from\ imagestore\ backupstorage = current license[{0}] is not valid license while download from imagestore backupstorage -# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:207 +# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:229 # args: System\ can't\ find\ imagestore\ backup\ Storage.\ Please\ do\ not\ set\ imagestore\ backup\ Storage\ server\ IP\ to\ localhost(127.*.*.*), = System can't find imagestore backup Storage. Please do not set imagestore backup Storage server IP to localhost(127.*.*.*), -# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:210 +# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:232 # args: operationSuggestion,greply.getHostname(),backupStorageInstallPath,pinv.getUuid(),primaryStorageInstallPath,rsp.getError() %s\ failed\ to\ download\ bits\ from\ the\ imagestore\ backup\ storage[hostname\:%s,\ path\:\ %s]\ to\ the\ local\ primary\ storage[uuid\:%s,\ path\:\ %s],\ %s = {0} failed to download bits from the imagestore backup storage[hostname:{1}, path: {2}] to the local primary storage[uuid:{3}, path: {4}], {5} -# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:270 +# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:293 # args: pinv.getUuid(),primaryStorageInstallPath,r.getHostname(),rsp.getError() failed\ to\ upload\ bits\ from\ the\ local\ storage[uuid\:%s,\ path\:%s]\ to\ image\ store\ [hostname\:%s],\ %s = failed to upload bits from the local storage[uuid:{0}, path:{1}] to image store [hostname:{2}], {3} -# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:207 -# args: volume.getUuid(),image.getImageUuid(),rsp.getError() -fails\ to\ create\ root\ volume[uuid\:%s]\ from\ cached\ image[path\:%s]\ because\ %s = fails to create root volume[uuid:{0}] from cached image[path:{1}] because {2} - -# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:262 +# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:238 # args: greply.getHostname(),backupStorageInstallPath,pinv.getUuid(),primaryStorageInstallPath,rsp.getError() failed\ to\ download\ bits\ from\ the\ imagestore\ backup\ storage[hostname\:%s,\ path\:\ %s]\ to\ the\ nfs\ primary\ storage[uuid\:%s,\ path\:\ %s],\ %s = failed to download bits from the imagestore backup storage[hostname:{0}, path: {1}] to the nfs primary storage[uuid:{2}, path: {3}], {4} -# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:323 +# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:300 # args: pinv.getUuid(),primaryStorageInstallPath,r.getHostname(),rsp.getError() failed\ to\ upload\ bits\ from\ the\ NFS[uuid\:%s,\ path\:%s]\ to\ image\ store\ [hostname\:%s],\ %s = failed to upload bits from the NFS[uuid:{0}, path:{1}] to image store [hostname:{2}], {3} -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:39 +# at: src/main/java/org/zstack/storage/primary/imagestore/smp/KvmAgentCommandDispatcher.java:70 +# args: this.primaryStorageUuid +cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ mount\ point\ storage[uuid\:%s]\ are\ disconnected = cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared mount point storage[uuid:{0}] are disconnected + +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:52 # args: primaryStorageUuid failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ no\ MonIP\ available = failed to get primaryStorage[{0}] license info, because no MonIP available -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:46 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:62 # args: primaryStorageUuid failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ no\ data\ returned = failed to get primaryStorage[{0}] license info, because no data returned -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:61 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:87 # args: primaryStorageUuid failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ the\ returned\ data\ does\ not\ have\ an\ active\ license = failed to get primaryStorage[{0}] license info, because the returned data does not have an active license -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:53 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:70 # args: primaryStorageUuid failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ expired_time\ is\ null = failed to get primaryStorage[{0}] license info, because expired_time is null +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:76 +# args: license.getExpired_time(),primaryStorageUuid +failed\ to\ parse\ the\ date\ format[%s]\ of\ the\ primaryStorage[%s]\ license\ info = failed to parse the date format[{0}] of the primaryStorage[{1}] license info + # at: src/main/java/org/zstack/storage/primary/local/AllocatePrimaryStorageForVmMigrationFlow.java:85 # args: volumeSize,spec.getVmInstance().getUuid() no\ hosts\ can\ provide\ %s\ bytes\ for\ all\ volumes\ of\ the\ vm[uuid\:%s] = no hosts can provide {0} bytes for all volumes of the vm[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:306 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:336 # args: localstorage\ allocator\ failed = localstorage allocator failed -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:90 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:356 +# args: +invalid\ uri,\ correct\ example\ is\ file\://$URL;hostUuid\://$HOSTuuid\ or\ volume\://$VOLUMEuuid\ = invalid uri, correct example is file://$URL;hostUuid://$HOSTuuid or volume://$VOLUMEuuid + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:369 +# args: LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat() +To\ create\ volume\ on\ the\ local\ primary\ storage,\ you\ must\ specify\ the\ host\ that\ the\ volume\ is\ going\ to\ be\ created\ using\ the\ system\ tag\ [%s] = To create volume on the local primary storage, you must specify the host that the volume is going to be created using the system tag [{0}] + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:88 # args: msg.getVolumeUuid() the\ volume[uuid\:%s]\ is\ not\ on\ any\ local\ primary\ storage = the volume[uuid:{0}] is not on any local primary storage -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:95 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:93 # args: msg.getVolumeUuid(),msg.getDestHostUuid() the\ volume[uuid\:%s]\ is\ already\ on\ the\ host[uuid\:%s] = the volume[uuid:{0}] is already on the host[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:101 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:99 # args: msg.getPrimaryStorageUuid() the\ primary\ storage[uuid\:%s]\ is\ not\ found = the primary storage[uuid:{0}] is not found -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:105 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:103 # args: ref.getPrimaryStorageUuid() the\ primary\ storage[uuid\:%s]\ is\ disabled\ or\ maintenance\ cold\ migrate\ is\ not\ allowed = the primary storage[uuid:{0}] is disabled or maintenance cold migrate is not allowed -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:114 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:112 # args: msg.getDestHostUuid(),ref.getPrimaryStorageUuid(),msg.getVolumeUuid() the\ dest\ host[uuid\:%s]\ doesn't\ belong\ to\ the\ local\ primary\ storage[uuid\:%s]\ where\ the\ volume[uuid\:%s]\ locates = the dest host[uuid:{0}] doesn't belong to the local primary storage[uuid:{1}] where the volume[uuid:{2}] locates -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:120 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:118 # args: msg.getDestHostUuid(),msg.getPrimaryStorageUuid(),physicalThreshold,refVO.getAvailablePhysicalCapacity() the\ dest\ host[uuid\:%s]\ doesn't\ have\ enough\ physical\ capacity\ due\ to\ the\ threshold\ of\ primary\ storage[uuid\:%s]\ is\ %f\ but\ available\ physical\ capacity\ is\ %d = the dest host[uuid:{0}] doesn't have enough physical capacity due to the threshold of primary storage[uuid:{1}] is {2} but available physical capacity is {3} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:127 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:125 # args: msg.getVolumeUuid() the\ volume[uuid\:%s]\ is\ not\ in\ status\ of\ Ready,\ cannot\ migrate\ it = the volume[uuid:{0}] is not in status of Ready, cannot migrate it -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:139 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:138 # args: vol.getUuid(),vol.getVmInstanceUuid(),vmstate the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ is\ in\ state\ of\ %s,\ please\ stop\ it\ before\ migration = the volume[uuid:{0}] is the root volume of the vm[uuid:{1}]. Currently the vm is in state of {2}, please stop it before migration -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:147 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:146 # args: vol.getUuid(),vol.getVmInstanceUuid(),count the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ still\ has\ %s\ data\ volumes\ attached,\ please\ detach\ them\ before\ migration = the volume[uuid:{0}] is the root volume of the vm[uuid:{1}]. Currently the vm still has {2} data volumes attached, please detach them before migration -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:152 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:151 # args: vol.getUuid(),vol.getVmInstanceUuid() the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ still\ has\ ISO\ attached,\ please\ detach\ it\ before\ migration = the volume[uuid:{0}] is the root volume of the vm[uuid:{1}]. Currently the vm still has ISO attached, please detach it before migration -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:177 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:176 # args: originClusterUuid,clusterUuid,vol.getVmInstanceUuid() The\ two\ clusters[uuid\:%s,uuid\:%s]\ cannot\ access\ each\ other\ in\ l2\ network\ \ when\ migrate\ the\ vm[uuid\:%s]\ to\ another\ cluster = The two clusters[uuid:{0},uuid:{1}] cannot access each other in l2 network when migrate the vm[uuid:{2}] to another cluster -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:132 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:130 # args: vol.getUuid(),vol.getName(),vol.getVmInstanceUuid() the\ data\ volume[uuid\:%s,\ name\:\ %s]\ is\ still\ attached\ to\ the\ VM[uuid\:%s].\ Please\ detach\ it\ before\ migration = the data volume[uuid:{0}, name: {1}] is still attached to the VM[uuid:{2}]. Please detach it before migration -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:191 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:190 # args: msg.getUrl() the\ url[%s]\ is\ not\ an\ absolute\ path\ starting\ with\ '/' = the url[{0}] is not an absolute path starting with '/' -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:258 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:262 # args: msg.getPrimaryStorageUuid() The\ primary\ storage[uuid\:%s]\ is\ disabled\ cold\ migrate\ is\ not\ allowed = The primary storage[uuid:{0}] is disabled cold migrate is not allowed -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:560 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:540 # args: msg.getVolumeUuid() volume[uuid\:%s]\ is\ not\ on\ the\ local\ storage\ anymore,it\ may\ have\ been\ deleted = volume[uuid:{0}] is not on the local storage anymore,it may have been deleted -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1143 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1168 # args: msg.getImage().getUuid(),self.getUuid(),JSONObjectUtil.toJsonString(ret.errorCodes) failed\ to\ download\ image[uuid\:%s]\ to\ all\ hosts\ in\ the\ local\ storage[uuid\:%s].\ %s = failed to download image[uuid:{0}] to all hosts in the local storage[uuid:{1}]. {2} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1392 -# args: resUuid,uuid -Resource[uuid\:%s]\ can\ only\ be\ operated\ on\ host[uuid\:%s],\ but\ the\ host\ has\ been\ deleted = Resource[uuid:{0}] can only be operated on host[uuid:{1}], but the host has been deleted - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1389 -# args: resUuid -cannot\ find\ any\ host\ which\ has\ resource[uuid\:%s] = cannot find any host which has resource[uuid:{0}] - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1764 -# args: hostUuid,self.getUuid(),ref.getAvailableCapacity(),size -host[uuid\:\ %s]\ of\ local\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = host[uuid: {0}] of local primary storage[uuid: {1}] doesn't have enough capacity[current: {2} bytes, needed: {3}] - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2111 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2326 # args: msg.getVolumeUuid(),self.getUuid() unable\ to\ create\ the\ data\ volume[uuid\:\ %s]\ on\ a\ local\ primary\ storage[uuid\:%s],\ because\ the\ hostUuid\ is\ not\ specified. = unable to create the data volume[uuid: {0}] on a local primary storage[uuid:{1}], because the hostUuid is not specified. -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2634 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2887 # args: No\ Host\ state\ is\ Enabled,\ Please\ check\ the\ availability\ of\ the\ host = No Host state is Enabled, Please check the availability of the host -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2741 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:3018 # args: hostUuid,self.getUuid() host[uuid\:%s]\ cannot\ access\ local\ storage[uuid\:%s],\ maybe\ it\ is\ detached = host[uuid:{0}] cannot access local storage[uuid:{1}], maybe it is detached -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2765 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:3042 # args: resUuid,resourceType,self.getUuid() resource[uuid\:%s,\ type\:\ %s]\ is\ not\ on\ the\ local\ primary\ storage[uuid\:%s] = resource[uuid:{0}, type: {1}] is not on the local primary storage[uuid:{2}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2770 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:3047 # args: resUuid,resourceType,self.getUuid(),ret resource[uuid\:%s,\ type\:\ %s]\ on\ the\ local\ primary\ storage[uuid\:%s]\ maps\ to\ multiple\ hypervisor%s = resource[uuid:{0}, type: {1}] on the local primary storage[uuid:{2}] maps to multiple hypervisor{3} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:99 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:100 # args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,clusterUuid There\ is\ no\ LocalStorage\ primary\ storage[state\=%s,status\=%s]\ on\ the\ cluster[%s],\ when\ the\ cluster\ mounts\ multiple\ primary\ storage,\ the\ system\ uses\ the\ local\ primary\ storage\ by\ default.\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = There is no LocalStorage primary storage[state={0},status={1}] on the cluster[{2}], when the cluster mounts multiple primary storage, the system uses the local primary storage by default. Check the state/status of primary storage and make sure they have been attached to clusters -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:118 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:119 # args: psUuid the\ type\ of\ primary\ storage[uuid\:%s]\ chosen\ is\ not\ local\ storage,\ check\ if\ the\ resource\ can\ be\ created\ on\ other\ storage\ when\ cluster\ has\ attached\ local\ primary\ storage = the type of primary storage[uuid:{0}] chosen is not local storage, check if the resource can be created on other storage when cluster has attached local primary storage -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:183 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:187 # args: requiredPrimaryStorageUuidForDataVolume.getUuid(),requiredPrimaryStorageUuidForDataVolume.getType(),LocalStorageConstants.LOCAL_STORAGE_TYPE The\ cluster\ mounts\ multiple\ primary\ storage[%s(%s),\ other\ non-LocalStorage\ primary\ storage],\ primaryStorageUuidForDataVolume\ cannot\ be\ specified\ %s = The cluster mounts multiple primary storage[{0}({1}), other non-LocalStorage primary storage], primaryStorageUuidForDataVolume cannot be specified {2} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:119 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:126 # args: spec.getDestHost().getClusterUuid() The\ cluster[uuid\=%s]\ mounts\ multiple\ primary\ storage[LocalStorage,\ other\ non-LocalStorage\ primary\ storage],\ You\ must\ specify\ the\ primary\ storage\ where\ the\ root\ disk\ is\ located = The cluster[uuid={0}] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the root disk is located -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:125 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:132 # args: spec.getDestHost().getClusterUuid() The\ cluster[uuid\=%s]\ mounts\ multiple\ primary\ storage[LocalStorage,\ other\ non-LocalStorage\ primary\ storage],\ You\ must\ specify\ the\ primary\ storage\ where\ the\ data\ disk\ is\ located = The cluster[uuid={0}] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the data disk is located -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:365 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:404 +# args: imageUuid,cachedHostUuids +creation\ rely\ on\ image\ cache[uuid\:%s,\ locate\ host\ uuids\:\ [%s]],\ cannot\ create\ other\ places. = creation rely on image cache[uuid:{0}, locate host uuids: [{1}]], cannot create other places. + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:462 # args: spec.getVmInventory().getHypervisorType() local\ storage\ doesn't\ support\ live\ migration\ for\ hypervisor[%s] = local storage doesn't support live migration for hypervisor[{0}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:581 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:678 # args: volume.getUuid(),vm.getUuid(),vm.getRootVolumeUuid(),rootHost,volume.getUuid(),dataHost cannot\ attach\ the\ data\ volume[uuid\:%s]\ to\ the\ vm[uuid\:%s].\ Both\ vm's\ root\ volume\ and\ the\ data\ volume\ are\ on\ local\ primary\ storage,\ but\ they\ are\ on\ different\ hosts.\ The\ root\ volume[uuid\:%s]\ is\ on\ the\ host[uuid\:%s]\ but\ the\ data\ volume[uuid\:\ %s]\ is\ on\ the\ host[uuid\:\ %s] = cannot attach the data volume[uuid:{0}] to the vm[uuid:{1}]. Both vm's root volume and the data volume are on local primary storage, but they are on different hosts. The root volume[uuid:{2}] is on the host[uuid:{3}] but the data volume[uuid: {4}] is on the host[uuid: {5}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:809 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:896 # args: vol.getName(),vol.getUuid(),vol.getPrimaryStorageUuid() the\ data\ volume[name\:%s,\ uuid\:%s]\ is\ on\ the\ local\ storage[uuid\:%s];\ however,the\ host\ on\ which\ the\ data\ volume\ is\ has\ been\ deleted.\ Unable\ to\ recover\ this\ volume = the data volume[name:{0}, uuid:{1}] is on the local storage[uuid:{2}]; however,the host on which the data volume is has been deleted. Unable to recover this volume -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:851 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:938 # args: vm.getUuid(),vm.getName(),psuuid unable\ to\ recover\ the\ vm[uuid\:%s,\ name\:%s].\ The\ vm's\ root\ volume\ is\ on\ the\ local\ storage[uuid\:%s];\ however,\ the\ host\ on\ which\ the\ root\ volume\ is\ has\ been\ deleted = unable to recover the vm[uuid:{0}, name:{1}]. The vm's root volume is on the local storage[uuid:{2}]; however, the host on which the root volume is has been deleted -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:888 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:972 # args: vm.getUuid() unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ data\ volumes\ on\ local\ storage.\ Need\ detach\ all\ data\ volumes\ first. = unable to live migrate vm[uuid:{0}] with data volumes on local storage. Need detach all data volumes first. -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:893 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:977 # args: vm.getUuid(),vm.getPlatform() unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ local\ storage.\ Only\ linux\ guest\ is\ supported.\ Current\ platform\ is\ [%s] = unable to live migrate vm[uuid:{0}] with local storage. Only linux guest is supported. Current platform is [{1}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:898 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:982 # args: vm.getUuid() unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ ISO\ on\ local\ storage.\ Need\ detach\ all\ ISO\ first. = unable to live migrate vm[uuid:{0}] with ISO on local storage. Need detach all ISO first. -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:929 -# args: vm.getUuid() -unable\ to\ live\ migrate\ with\ local\ storage.\ The\ vm[uuid\:%s]\ has\ volumes\ on\ local\ storage,to\ protect\ your\ data,\ please\ stop\ the\ vm\ and\ do\ the\ volume\ migration = unable to live migrate with local storage. The vm[uuid:{0}] has volumes on local storage,to protect your data, please stop the vm and do the volume migration - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:979 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:1058 # args: LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat() To\ create\ data\ volume\ on\ the\ local\ primary\ storage,\ you\ must\ specify\ the\ host\ that\ the\ data\ volume\ is\ going\ to\ be\ created\ using\ the\ system\ tag\ [%s] = To create data volume on the local primary storage, you must specify the host that the data volume is going to be created using the system tag [{0}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:989 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:1068 # args: hostUuid,msg.getPrimaryStorageUuid() the\ host[uuid\:%s]\ doesn't\ belong\ to\ the\ local\ primary\ storage[uuid\:%s] = the host[uuid:{0}] doesn't belong to the local primary storage[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:1782 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:2083 # args: root\ image\ has\ been\ deleted,\ cannot\ reimage\ now = root image has been deleted, cannot reimage now -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3117 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3676 # args: makeInitializedFilePath(),hostUuid cannot\ find\ flag\ file\ [%s]\ on\ host\ [%s],\ it\ might\ not\ mount\ correct\ path = cannot find flag file [{0}] on host [{1}], it might not mount correct path -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java:105 -# args: context.getInventory().getUuid(),priUuid,reply.getError() -KVM\ host[uuid\:\ %s]\ fails\ to\ be\ added\ into\ local\ primary\ storage[uuid\:\ %s],\ %s = KVM host[uuid: {0}] fails to be added into local primary storage[uuid: {1}], {2} +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3684 +# args: makeInitializedFilePath(),hostUuid,errorCode.getCause().getDetails() +cannot\ find\ flag\ file\ [%s]\ on\ host\ [%s],\ because\:\ %s = cannot find flag file [{0}] on host [{1}], because: {2} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java:1196 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3705 +# args: makeInitializedFilePath(),hostUuid,errorCode.getCause().getDetails() +cannot\ create\ flag\ file\ [%s]\ on\ host\ [%s],\ because\:\ %s = cannot create flag file [{0}] on host [{1}], because: {2} + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java:1192 # args: p.volume.getUuid(),p.volume.getName(),dstHostUuid unable\ to\ create\ an\ empty\ volume[uuid\:%s,\ name\:%s]\ on\ the\ kvm\ host[uuid\:%s] = unable to create an empty volume[uuid:{0}, name:{1}] on the kvm host[uuid:{2}] @@ -7562,110 +12266,158 @@ unable\ to\ create\ an\ empty\ volume[uuid\:%s,\ name\:%s]\ on\ the\ kvm\ host[u # args: greply.getHostname(),backupStorageInstallPath,pinv.getUuid(),primaryStorageInstallPath,rsp.getError() failed\ to\ download\ bits\ from\ the\ SFTP\ backup\ storage[hostname\:%s,\ path\:\ %s]\ to\ the\ local\ primary\ storage[uuid\:%s,\ path\:\ %s],\ %s = failed to download bits from the SFTP backup storage[hostname:{0}, path: {1}] to the local primary storage[uuid:{2}, path: {3}], {4} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java:254 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java:253 # args: pinv.getUuid(),primaryStorageInstallPath,r.getHostname(),backupStorageInstallPath,rsp.getError() failed\ to\ upload\ bits\ from\ the\ local\ storage[uuid\:%s,\ path\:%s]\ to\ the\ SFTP\ backup\ storage[hostname\:%s,\ path\:%s],\ %s = failed to upload bits from the local storage[uuid:{0}, path:{1}] to the SFTP backup storage[hostname:{2}, path:{3}], {4} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:157 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:159 # args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,HostState.Enabled,HostStatus.Connected,spec.getSize() no\ local\ primary\ storage\ can\ satisfy\ conditions[state\:\ %s,\ status\:\ %s]\ or\ contain\ hosts\ satisfying\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = no local primary storage can satisfy conditions[state: {0}, status: {1}] or contain hosts satisfying conditions[state: {2}, status: {3}, size > {4} bytes] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:132 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:134 # args: spec.getRequiredZoneUuid(),PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,HostState.Enabled,HostStatus.Connected,spec.getSize() no\ local\ primary\ storage\ in\ zone[uuid\:%s]\ can\ satisfy\ conditions[state\:\ %s,\ status\:\ %s]\ or\ contain\ hosts\ satisfying\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = no local primary storage in zone[uuid:{0}] can satisfy conditions[state: {1}, status: {2}] or contain hosts satisfying conditions[state: {3}, status: {4}, size > {5} bytes] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:105 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:107 # args: spec.getRequiredHostUuid(),HostState.Enabled,HostStatus.Connected,spec.getSize(),PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected the\ required\ host[uuid\:%s]\ cannot\ satisfy\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes],\ or\ doesn't\ belong\ to\ a\ local\ primary\ storage\ satisfying\ conditions[state\:\ %s,\ status\:\ %s],\ or\ its\ cluster\ doesn't\ attach\ to\ any\ local\ primary\ storage = the required host[uuid:{0}] cannot satisfy conditions[state: {1}, status: {2}, size > {3} bytes], or doesn't belong to a local primary storage satisfying conditions[state: {4}, status: {5}], or its cluster doesn't attach to any local primary storage -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:77 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:79 # args: spec.getRequiredPrimaryStorageUuid(),PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,HostState.Enabled,HostStatus.Connected,spec.getSize() required\ local\ primary\ storage[uuid\:%s]\ cannot\ satisfy\ conditions[state\:\ %s,\ status\:\ %s],\ or\ hosts\ providing\ the\ primary\ storage\ don't\ satisfy\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = required local primary storage[uuid:{0}] cannot satisfy conditions[state: {1}, status: {2}], or hosts providing the primary storage don't satisfy conditions[state: {3}, status: {4}, size > {5} bytes] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:198 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:201 # args: ref.getHostUuid(),physicalCapacityMgr.getRatio(ref.getPrimaryStorageUuid()) {the\ physical\ capacity\ usage\ of\ the\ host[uuid\:%s]\ has\ exceeded\ the\ threshold[%s]} = '{the physical capacity usage of the host[uuid:{0}'] has exceeded the threshold[{1}]} -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1002 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:207 # args: -not\ supported = not supported +failed\ allocate\ localstorage = failed allocate localstorage + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java:205 +# args: resUuid,uuid +Resource[uuid\:%s]\ can\ only\ be\ operated\ on\ host[uuid\:%s],\ but\ the\ host\ has\ been\ deleted = Resource[uuid:{0}] can only be operated on host[uuid:{1}], but the host has been deleted + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java:202 +# args: resUuid +cannot\ find\ any\ host\ which\ has\ resource[uuid\:%s] = cannot find any host which has resource[uuid:{0}] + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java:135 +# args: hostUuid,self.getUuid(),ref.getAvailableCapacity(),size +host[uuid\:\ %s]\ of\ local\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = host[uuid: {0}] of local primary storage[uuid: {1}] doesn't have enough capacity[current: {2} bytes, needed: {3}] + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:82 +# args: msg.getResourceUuid() +Invalid\ resourceUuid\ %s = Invalid resourceUuid {0} + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:88 +# args: +primary\ storage\ uuid\ cannot\ be\ null. = primary storage uuid cannot be null. + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:105 +# args: volume.getUuid(),runningVmUuids.toString() +volume[uuid\:%s]\ has\ been\ attached\ some\ VM(s)[uuid\:%s]\ which\ are\ not\ Stopped\ and\ not\ running\ on\ the\ specific\ host. = volume[uuid:{0}] has been attached some VM(s)[uuid:{1}] which are not Stopped and not running on the specific host. + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:124 +# args: msg.getResourceUuid() +VM[uuid\:%s]\ are\ not\ Stopped\ and\ not\ running\ on\ the\ specific\ host. = VM[uuid:{0}] are not Stopped and not running on the specific host. -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1104 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:191 +# args: task,hostUuids +Fail\ to\ %s,\ because\ host(s)[uuid\:%s]\ are\ not\ enable\ and\ not\ in\ connected\ status. = Fail to {0}, because host(s)[uuid:{1}] are not enable and not in connected status. + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1549 # args: self.getUuid(),hostUuid cannot\ reserve\ enough\ space\ for\ primary\ storage[uuid\:\ %s]\ on\ host[uuid\:\ %s],\ not\ enough\ physical\ capacity = cannot reserve enough space for primary storage[uuid: {0}] on host[uuid: {1}], not enough physical capacity -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:154 -# args: psUuid,imageFormat -cannot\ find\ proper\ hypervisorType\ for\ primary\ storage[uuid\:%s]\ to\ handle\ image\ format\ or\ volume\ format[%s] = cannot find proper hypervisorType for primary storage[uuid:{0}] to handle image format or volume format[{1}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1449 +# args: +not\ supported = not supported + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:216 +# args: msg.getResourceType() +ResourceType\ [%s]\ of\ APIRecoverResourceSplitBrainMsg\ is\ invalid. = ResourceType [{0}] of APIRecoverResourceSplitBrainMsg is invalid. -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:226 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:360 # args: self.getUuid(),self.getName() the\ mini\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = the mini storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:449 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:673 # args: can\ not\ determine\ which\ host = can not determine which host -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1118 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1364 +# args: +no\ connected\ host\ found,\ mini\ storage\ failed = no connected host found, mini storage failed + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1563 # args: hostUuid,self.getUuid(),ref.getAvailableCapacity(),size host[uuid\:\ %s]\ of\ mini\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = host[uuid: {0}] of mini primary storage[uuid: {1}] doesn't have enough capacity[current: {2} bytes, needed: {3}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageFactory.java:167 -# args: hvType,bsType -no\ LocalStorageBackupStorageMediator\ supporting\ hypervisor[%s]\ and\ backup\ storage\ type[%s]\ = no LocalStorageBackupStorageMediator supporting hypervisor[{0}] and backup storage type[{1}] - -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageImageStoreBackend.java:59 -# args: volumeUuid -can\ not\ get\ cluster\ uuid\ of\ volume\ %s = can not get cluster uuid of volume {0} - -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:736 -# args: returnValue.error -%s = {0} +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageDeactivateVolumeGC.java:75 +# args: hostUuid +the\ host[uuid\:%s]\ is\ not\ connected = the host[uuid:{0}] is not connected -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:181 -# args: clusterUuid -no\ connected\ host\ found\ in\ the\ cluster[uuid\:%s] = no connected host found in the cluster[uuid:{0}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageFactory.java:173 +# args: hvType,bsType +no\ LocalStorageBackupStorageMediator\ supporting\ hypervisor[%s]\ and\ backup\ storage\ type[%s]\ = no LocalStorageBackupStorageMediator supporting hypervisor[{0}] and backup storage type[{1}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:1271 -# args: backupStorageUuid -cannot\ find\ backup\ storage[uuid\:%s] = cannot find backup storage[uuid:{0}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:332 +# args: volume.getRootImageUuid(),volume.getUuid() +no\ backup\ storage\ can\ get\ image[uuid\:%s]\ of\ volume[uuid\:%s] = no backup storage can get image[uuid:{0}] of volume[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:1056 -# args: msg.getVolumeUuid() -can\ not\ find\ volume[uuid\:\ %s] = can not find volume[uuid: {0}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:343 +# args: image.getUuid(),cache.backupStorage.getUuid() +image[uuid\:\ %s]\ has\ no\ image\ ref\ with\ backup\ storage[uuid\:\ %s] = image[uuid: {0}] has no image ref with backup storage[uuid: {1}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:723 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:832 # args: volume.getUuid(),volume.getPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ resize\ volume[uuid\:\ %s]\ on\ mini\ storage[uuid\:\ %s] = can not find any available host to resize volume[uuid: {0}] on mini storage[uuid: {1}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePathManagerImpl.java:105 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:925 +# args: volumeUuid +volume[uuid\:%s]\ replication\ is\ syncing\ data,\ please\ wait\ until\ it\ is\ finished. = volume[uuid:{0}] replication is syncing data, please wait until it is finished. + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:938 +# args: volumeUuid +replication\ network\ status\ of\ volume[uuid\:%s]\ run\ into\ StandAlone,\ but\ host\ are\ all\ Connected,\ please\ recover\ it\ first. = replication network status of volume[uuid:{0}] run into StandAlone, but host are all Connected, please recover it first. + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageManagerImpl.java:73 +# args: dir +Invalid\ path\ string\ %s = Invalid path string {0} + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageManagerImpl.java:80 +# args: resourceUuid +Still\ cache\ volume\ exists\ on\ ps[uuid\:%s]\ can\ not\ update\ cache\ volume\ url = Still cache volume exists on ps[uuid:{0}] can not update cache volume url + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePathManagerImpl.java:115 # args: resourceUuid,hostUuid can\ not\ find\ replication\ of\ volume\ %s\ on\ host\ %s = can not find replication of volume {0} on host {1} -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:187 -# args: -no\ candidate\ host\ with\ the\ scsi\ lun\ with\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = no candidate host with the scsi lun with enough cpu / memory or Enabled/Connected status - -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:113 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:141 # args: clusterUuid,msg.getPrimaryStorageUuid(),volume.getUuid() required\ cluster\ %s\ not\ attached\ to\ primary\ storage\ %s\ for\ volume\ %s\ create = required cluster {0} not attached to primary storage {1} for volume {2} create -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:120 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:148 # args: clusterUuid,volume.getUuid() can\ not\ find\ avaliable\ host\ on\ required\ cluster\ %s\ for\ volume\ %s\ create = can not find avaliable host on required cluster {0} for volume {1} create -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:347 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:445 # args: primaryStorageUuid cannot\ find\ an\ available\ host\ to\ execute\ command\ for\ primary\ storage[uuid\:\ %s] = cannot find an available host to execute command for primary storage[uuid: {0}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:378 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:476 # args: hostUuid can\ not\ allocate\ storage\ sync\ port\ on\ host\ %s\:\ %s = can not allocate storage sync port on host {0}: {1} -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:490 -# args: hostUuids,connectedEnabledHosts +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:622 +# args: hostUuids,finalHostUuids expect\ operate\ on\ hosts[%s]\ but\ only\ host\ %s\ are\ connected\ and\ enabled = expect operate on hosts[{0}] but only host {1} are connected and enabled +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniToZBoxBackupStorageMediator.java:91 +# args: msg.getPrimaryStorageUuid() +mini\ storage[uuid\:%s]\ has\ to\ be\ empty\ before\ restoring\ bits\ from\ zbox.\ please\ clean\ it\ up. = mini storage[uuid:{0}] has to be empty before restoring bits from zbox. please clean it up. + # at: src/main/java/org/zstack/storage/primary/nfs/NfsApiParamChecker.java:46 # args: url,zoneUuid there\ has\ been\ a\ nfs\ primary\ storage\ having\ url\ as\ %s\ in\ zone[uuid\:%s] = there has been a nfs primary storage having url as {0} in zone[uuid:{1}] @@ -7686,283 +12438,335 @@ IP\ address[%s]\ is\ not\ in\ CIDR[%s] = IP address[{0}] is not in CIDR[{1}] # args: vms.size(),StringUtils.join(vms, "\n") there\ are\ %s\ running\ VMs\ on\ the\ NFS\ primary\ storage,\ please\ stop\ them\ and\ try\ again\:\n%s\n = there are {0} running VMs on the NFS primary storage, please stop them and try again:\n{1}\n -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:227 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:694 +# args: vol.getVmInstanceUuid(),state +vm[uuid\:%s]\ is\ not\ Running,\ Paused\ or\ Stopped,\ current\ state\ is\ %s = vm[uuid:{0}] is not Running, Paused or Stopped, current state is {1} + +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:303 # args: cannot\ find\ usable\ backend = cannot find usable backend -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:286 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:362 # args: no\ usable\ backend\ found = no usable backend found -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:426 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:520 # args: self.getUuid(),self.getName(),msg.getVolume().getUuid(),msg.getSnapshot().getUuid(),msg.getSnapshot().getName() no\ host\ in\ Connected\ status\ to\ which\ nfs\ primary\ storage[uuid\:%s,\ name\:%s]\ attached\ found\ to\ revert\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s,\ name\:%s] = no host in Connected status to which nfs primary storage[uuid:{0}, name:{1}] attached found to revert volume[uuid:{2}] to snapshot[uuid:{3}, name:{4}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:457 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:551 # args: self.getUuid(),self.getName(),msg.getVolume().getUuid(),msg.getVolume().getRootImageUuid() no\ host\ in\ Connected\ status\ to\ which\ nfs\ primary\ storage[uuid\:%s,\ name\:%s]\ attached\ found\ to\ revert\ volume[uuid\:%s]\ to\ image[uuid\:%s] = no host in Connected status to which nfs primary storage[uuid:{0}, name:{1}] attached found to revert volume[uuid:{2}] to image[uuid:{3}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:536 -# args: vol.getVmInstanceUuid(),state -vm[uuid\:%s]\ is\ not\ Running,\ Paused\ or\ Stopped,\ current\ state\ is\ %s = vm[uuid:{0}] is not Running, Paused or Stopped, current state is {1} - -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:579 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:737 # args: self.getUuid() primary\ storage[uuid\:%s]\ doesn't\ attach\ to\ any\ cluster = primary storage[uuid:{0}] doesn't attach to any cluster -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:809 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:968 # args: self.getUuid(),self.getName(),msg.getVolume().getUuid(),msg.getVolume().getName() the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ usable\ host\ to\ create\ the\ data\ volume[uuid\:%s,\ name\:%s] = the NFS primary storage[uuid:{0}, name:{1}] cannot find any usable host to create the data volume[uuid:{2}, name:{3}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1425 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1889 # args: self.getUuid(),self.getName() the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ hosts\ in\ attached\ clusters\ to\ perform\ the\ operation = the NFS primary storage[uuid:{0}, name:{1}] cannot find hosts in attached clusters to perform the operation -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1392 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1726 # args: self.getUuid(),self.getName() the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = the NFS primary storage[uuid:{0}, name:{1}] has not attached to any clusters, or no hosts in the attached clusters are connected -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:112 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:115 # args: psUuid,vmUuid,volumeUuid the\ NFS\ primary\ storage[uuid\:%s]\ is\ not\ attached\ to\ any\ clusters,\ and\ cannot\ expunge\ the\ root\ volume[uuid\:%s]\ of\ the\ VM[uuid\:%s] = the NFS primary storage[uuid:{0}] is not attached to any clusters, and cannot expunge the root volume[uuid:{1}] of the VM[uuid:{2}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:278 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:281 # args: pri.getUuid() cannot\ find\ a\ Connected\ host\ to\ execute\ command\ for\ nfs\ primary\ storage[uuid\:%s] = cannot find a Connected host to execute command for nfs primary storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:269 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:272 # args: pri.getUuid() cannot\ find\ a\ connected\ host\ in\ cluster\ which\ ps\ [uuid\:\ %s]\ attached = cannot find a connected host in cluster which ps [uuid: {0}] attached -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:297 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:300 # args: pri.getUuid() cannot\ find\ a\ host\ which\ has\ Connected\ host-NFS\ connection\ to\ execute\ command\ for\ nfs\ primary\ storage[uuid\:%s] = cannot find a host which has Connected host-NFS connection to execute command for nfs primary storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:673 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:804 # args: msg.getVolume().getUuid() cannot\ get\ root\ image\ of\ volume[uuid\:%s],\ may\ be\ it\ create\ from\ iso = cannot get root image of volume[uuid:{0}], may be it create from iso -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:241 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:248 # args: inv.getUuid(),inv.getName(),clusterUuid,versionInCluster,otherVersion,QCOW3_QEMU_IMG_VERSION,QCOW3_QEMU_IMG_VERSION unable\ to\ attach\ a\ primary\ storage[uuid\:%s,\ name\:%s]\ to\ cluster[uuid\:%s].\ Kvm\ host\ in\ the\ cluster\ has\ qemu-img\ with\ version[%s];\ but\ the\ primary\ storage\ has\ attached\ to\ another\ cluster\ that\ has\ kvm\ host\ which\ has\ qemu-img\ with\ version[%s].\ qemu-img\ version\ greater\ than\ %s\ is\ incompatible\ with\ versions\ less\ than\ %s,\ this\ will\ causes\ volume\ snapshot\ operation\ to\ fail.\ Please\ avoid\ attaching\ a\ primary\ storage\ to\ clusters\ that\ have\ different\ Linux\ distributions,\ in\ order\ to\ prevent\ qemu-img\ version\ mismatch = unable to attach a primary storage[uuid:{0}, name:{1}] to cluster[uuid:{2}]. Kvm host in the cluster has qemu-img with version[{3}]; but the primary storage has attached to another cluster that has kvm host which has qemu-img with version[{4}]. qemu-img version greater than {5} is incompatible with versions less than {6}, this will causes volume snapshot operation to fail. Please avoid attaching a primary storage to clusters that have different Linux distributions, in order to prevent qemu-img version mismatch -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:316 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:323 # args: cmd.getInstallUrl(),host.getUuid(),host.getManagementIp(),rsp.getError() unable\ to\ create\ folder[installUrl\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = unable to create folder[installUrl:{0}] on kvm host[uuid:{1}, ip:{2}], because {3} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:394 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:401 # args: inv.getUuid() no\ host\ in\ is\ Connected\ or\ primary\ storage[uuid\:%s]\ attach\ no\ cluster = no host in is Connected or primary storage[uuid:{0}] attach no cluster -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:433 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:440 # args: psInv.getUuid(),huuid,reply.isSuccess() ? rsp.getError() : reply.getError() failed\ to\ ping\ nfs\ primary\ storage[uuid\:%s]\ from\ host[uuid\:%s],because\ %s.\ disconnect\ this\ host-ps\ connection = failed to ping nfs primary storage[uuid:{0}] from host[uuid:{1}],because {2}. disconnect this host-ps connection -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:699 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:879 # args: msg.getHostUuid() The\ chosen\ host[uuid\:%s]\ to\ perform\ storage\ migration\ is\ lost = The chosen host[uuid:{0}] to perform storage migration is lost -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:835 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1017 # args: installPath,inv.getUuid(),rsp.getError() failed\ to\ check\ existence\ of\ %s\ on\ nfs\ primary\ storage[uuid\:%s],\ %s = failed to check existence of {0} on nfs primary storage[uuid:{1}], {2} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:947 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1131 # args: volume.getUuid(),volume.getName(),host.getUuid(),host.getManagementIp(),rsp.getError() unable\ to\ create\ empty\ volume[uuid\:%s,\ \ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = unable to create empty volume[uuid:{0}, name:{1}] on kvm host[uuid:{2}, ip:{3}], because {4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1051 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1240 # args: installPath,pinv.getUuid(),rsp.getError() failed\ to\ delete\ bits[%s]\ on\ nfs\ primary\ storage[uuid\:%s],\ %s,\ will\ clean\ up\ installPath,\ pinv.getUuid(),\ rsp.getError() = failed to delete bits[{0}] on nfs primary storage[uuid:{1}], {2}, will clean up installPath, pinv.getUuid(), rsp.getError() -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1095 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1302 # args: vol.getUuid(),sinv.getUuid(),host.getUuid(),host.getManagementIp(),rsp.getError() failed\ to\ revert\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ %s = failed to revert volume[uuid:{0}] to snapshot[uuid:{1}] on kvm host[uuid:{2}, ip:{3}], {4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1132 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1339 # args: vol.getUuid(),vol.getRootImageUuid(),host.getUuid(),host.getManagementIp(),rsp.getError() failed\ to\ revert\ volume[uuid\:%s]\ to\ image[uuid\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ %s = failed to revert volume[uuid:{0}] to image[uuid:{1}] on kvm host[uuid:{2}, ip:{3}], {4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1270 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1383 +# args: volume.getUuid(),imageCache.getImageUuid(),rsp.getError() +fails\ to\ create\ root\ volume[uuid\:%s]\ from\ cached\ image[path\:%s]\ because\ %s = fails to create root volume[uuid:{0}] from cached image[path:{1}] because {2} + +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1541 # args: clusterUuid no\ hosts\ in\ the\ cluster[uuid\:%s]\ are\ connected = no hosts in the cluster[uuid:{0}] are connected -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:158 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:109 # args: backupStorageInstallPath,greply.getHostname(),pinv.getUuid(),primaryStorageInstallPath,rsp.getError() failed\ to\ download[%s]\ from\ SftpBackupStorage[hostname\:%s]\ to\ nfs\ primary\ storage[uuid\:%s,\ path\:%s],\ %s = failed to download[{0}] from SftpBackupStorage[hostname:{1}] to nfs primary storage[uuid:{2}, path:{3}], {4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:214 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:165 # args: pinv.getUuid(),primaryStorageInstallPath,hostname,backupStorageInstallPath,rsp.getError() failed\ to\ upload\ bits\ from\ nfs\ primary\ storage[uuid\:%s,\ path\:%s]\ to\ SFTP\ backup\ storage[hostname\:%s,\ path\:\ %s],\ %s = failed to upload bits from nfs primary storage[uuid:{0}, path:{1}] to SFTP backup storage[hostname:{2}, path: {3}], {4} -# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:65 -# args: this.primaryStorageUuid -cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ mount\ point\ storage[uuid\:%s]\ are\ disconnected = cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared mount point storage[uuid:{0}] are disconnected +# at: src/main/java/org/zstack/storage/primary/shareblock/ShareBlockHostHeartbeatChecker.java:135 +# args: cmd.hostUuid,sentinelHostUuid +shareblock\ says\ host\ %s\ is\ offline\ on\ %s = shareblock says host {0} is offline on {1} + +# at: src/main/java/org/zstack/storage/primary/sharedblock/HaSanlockHostChecker.java:141 +# args: cmd.hostIds,sentinelHostUuid +sanlock\ says\ host\ %s\ is\ offline\ on\ %s = sanlock says host {0} is offline on {1} + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:110 +# args: primaryStorageUuid +cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ block\ group\ storage[uuid\:%s]\ are\ disconnected = cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared block group storage[uuid:{0}] are disconnected + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:80 +# args: +can\ not\ find\ volume\ need\ to\ operate\ shared\ block\ group\ primary\ storage = can not find volume need to operate shared block group primary storage + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:88 +# args: volumeInventory.getUuid(),primaryStorageUuid +KVM\ host\ which\ volume[uuid%s]\ attached\ disconnected\ with\ the\ shared\ block\ group\ storage[uuid\:%s] = KVM host which volume[uuid{0}] attached disconnected with the shared block group storage[uuid:{1}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:98 +# args: psUuid +can\ not\ find\ qualified\ kvm\ host\ for\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = can not find qualified kvm host for shared block group primary storage[uuid: {0}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:77 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:81 # args: sharedBlockVO.getSharedBlockGroupUuid(),scsiLunVO.getWwid() primary\ storage[uuid\:\ %s]\ has\ attached\ the\ scsi\ lun[wwid\:\ %s] = primary storage[uuid: {0}] has attached the scsi lun[wwid: {1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:100 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:105 # args: msg.getVmInstanceUuid() the\ vm[uuid\:\ %s]\ does\ not\ has\ additional\ qmp\ socket,\ it\ may\ because\ of\ the\ vm\ start\ without\ the\ global\ config[vm.additionalQmp]\ enabled,\ please\ make\ sure\ it\ enabled\ and\ reboot\ vm\ in\ zstack = the vm[uuid: {0}] does not has additional qmp socket, it may because of the vm start without the global config[vm.additionalQmp] enabled, please make sure it enabled and reboot vm in zstack -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:125 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:130 # args: must\ specify\ at\ least\ one\ disk\ when\ add\ shared\ block\ group\ primary\ storage = must specify at least one disk when add shared block group primary storage -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:137 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:142 # args: vo.getUuid(),vo.getDiskUuid(),vo.getDescription(),vo.getSharedBlockGroupUuid() shared\ block[uuid\:%s,\ diskUuid\:%s,\ description\:%s]\ already\ added\ to\ shared\ block\ group[uuid\:%s]in\ new\ shared\ block\ group = shared block[uuid:{0}, diskUuid:{1}, description:{2}] already added to shared block group[uuid:{3}]in new shared block group -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:160 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:165 # args: msg.getUuid() shared\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage\ can\ not\ resize = shared volume[uuid: {0}] on shared block group primary storage can not resize -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:229 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:234 # args: volumeUuid,notStoppedVmUuids shared\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage\ has\ attached\ to\ not\ stopped\ vm\ instances[uuids\:\ %s] = shared volume[uuid: {0}] on shared block group primary storage has attached to not stopped vm instances[uuids: {1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:301 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1665 +# args: psUuid,imageFormat +cannot\ find\ proper\ hypervisorType\ for\ primary\ storage[uuid\:%s]\ to\ handle\ image\ format\ or\ volume\ format[%s] = cannot find proper hypervisorType for primary storage[uuid:{0}] to handle image format or volume format[{1}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:344 # args: self.getUuid(),self.getName() the\ shared\ mount\ point\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = the shared mount point primary storage[uuid:{0}, name:{1}] cannot find any available host in attached clusters for instantiating the volume -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:530 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:697 # args: getSelfInventory().getUuid() can\ not\ found\ any\ cluster\ attached\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %S] = can not found any cluster attached on shared block group primary storage[uuid: %S] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:880 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1100 # args: self.getUuid(),self.getName() the\ shared\ block\ group\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = the shared block group primary storage[uuid:{0}, name:{1}] has not attached to any clusters, or no hosts in the attached clusters are connected -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1070 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1179 +# args: self.getUuid(),self.getName() +the\ SharedBlock\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = the SharedBlock primary storage[uuid:{0}, name:{1}] has not attached to any clusters, or no hosts in the attached clusters are connected + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1369 # args: empty\ migrateVolumeStructs\ in\ migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! = empty migrateVolumeStructs in migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1076 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1375 # args: no\ volume\ in\ migrateVolumeStructs\ in\ migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! = no volume in migrateVolumeStructs in migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:110 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:112 # args: newValue the\ value[%s]\ is\ not\ power\ of\ 2 = the value[{0}] is not power of 2 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:438 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:444 # args: pri.getUuid() cannot\ find\ an\ available\ host\ to\ execute\ command\ for\ shared\ block\ group\ primary\ storage[uuid\:%s] = cannot find an available host to execute command for shared block group primary storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:462 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:468 # args: pri.getUuid() cannot\ find\ a\ host\ which\ has\ connected\ shared\ block\ to\ execute\ command\ for\ shared\ block\ group\ primary\ storage[uuid\:%s] = cannot find a host which has connected shared block to execute command for shared block group primary storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1104 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:515 +# args: vmvo.getHostUuid(),volumeInventory.getUuid(),volumeInventory.getPrimaryStorageUuid() +the\ host[uuid\:\ %s]\ running\ on\ is\ not\ available\ to\ resize\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = the host[uuid: {0}] running on is not available to resize volume[uuid: {1}] on shared block group primary storage[uuid: {2}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:524 +# args: psUuid +primary\ storage[uuid\:%s]\ not\ found = primary storage[uuid:{0}] not found + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:541 +# args: volUuid +volume[uuid\:%s]\ not\ found = volume[uuid:{0}] not found + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockImageStoreBackend.java:81 +# args: volumeUuid +can\ not\ get\ cluster\ uuid\ of\ volume\ %s = can not get cluster uuid of volume {0} + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1413 # args: img.getUuid(),img.getName(),self.getZoneUuid() the\ image[uuid\:%s,\ name\:\ %s]\ is\ not\ available\ to\ download\ on\ any\ backup\ storage\:\n1.\ check\ if\ image\ is\ in\ status\ of\ Deleted\n2.\ check\ if\ the\ backup\ storage\ on\ which\ the\ image\ is\ shown\ as\ Ready\ is\ attached\ to\ the\ zone[uuid\:%s] = the image[uuid:{0}, name: {1}] is not available to download on any backup storage:\n1. check if image is in status of Deleted\n2. check if the backup storage on which the image is shown as Ready is attached to the zone[uuid:{2}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:832 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1251 +# args: volume.getUuid(),volume.getVmInstanceUuid(),state +the\ volume[uuid;%s]\ is\ attached\ to\ a\ VM[uuid\:%s]\ which\ is\ in\ state\ of\ %s,\ cannot\ do\ the\ snapshot\ merge = the volume[uuid;{0}] is attached to a VM[uuid:{1}] which is in state of {2}, cannot do the snapshot merge + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1907 +# args: clusterUuid +no\ connected\ host\ found\ in\ the\ cluster[uuid\:%s] = no connected host found in the cluster[uuid:{0}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5893 # args: vol.getVmInstanceUuid(),state vm[uuid\:%s]\ is\ not\ Running,\ Paused\ or\ Stopped,\ current\ state[%s] = vm[uuid:{0}] is not Running, Paused or Stopped, current state[{1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:986 -# args: volume.getUuid(),volume.getVmInstanceUuid(),state -the\ volume[uuid;%s]\ is\ attached\ to\ a\ VM[uuid\:%s]\ which\ is\ in\ state\ of\ %s,\ cannot\ do\ the\ snapshot\ merge = the volume[uuid;{0}] is attached to a VM[uuid:{1}] which is in state of {2}, cannot do the snapshot merge +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2798 +# args: backupStorageUuid +cannot\ find\ backup\ storage[uuid\:%s] = cannot find backup storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1075 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2260 +# args: msg.getVolumeUuid() +can\ not\ find\ volume[uuid\:\ %s] = can not find volume[uuid: {0}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:773 +# args: +shared\ volume\ not\ support\ thin\ provisioning = shared volume not support thin provisioning + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1340 # args: volume.getUuid() not\ support\ online\ merge\ snapshot\ for\ shareable\ volume[uuid\:\ %s]\ on\ sharedblock = not support online merge snapshot for shareable volume[uuid: {0}] on sharedblock -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1120 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1429 # args: img.getUuid(),img.getName() the\ image[uuid\:\ %s,\ name\:%s]\ is\ not\ found\ on\ any\ backup\ storage = the image[uuid: {0}, name:{1}] is not found on any backup storage -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1561 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2043 # args: ret.firstAccessHosts.stream().map( h -> h.hostUuid).collect(Collectors.toList()) hosts[uuid\:%s]\ have\ the\ disk\ uuid\ of\ shared\ block,\ but\ actually\ different\ storage. = hosts[uuid:{0}] have the disk uuid of shared block, but actually different storage. -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1867 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2400 # args: not\ support\ convert\ thin\ volume\ to\ thick\ volume\ yet = not support convert thin volume to thick volume yet -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1921 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2453 # args: expected\ status\ is\ %s\ and\ current\ status = expected status is {0} and current status -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2372 -# args: self.getUuid() -cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ block\ group\ storage[uuid\:%s]\ are\ disconnected = cannot find any connected host to perform the operation, it seems all KVM hosts in the clusters attached with the shared block group storage[uuid:{0}] are disconnected - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2344 -# args: -can\ not\ find\ volume\ need\ to\ operate\ shared\ block\ group\ primary\ storage = can not find volume need to operate shared block group primary storage - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2352 -# args: volumeInventory.getUuid(),self.getUuid() -KVM\ host\ which\ volume[uuid%s]\ attached\ disconnected\ with\ the\ shared\ block\ group\ storage[uuid\:%s] = KVM host which volume[uuid{0}] attached disconnected with the shared block group storage[uuid:{1}] - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2361 -# args: psUuid -can\ not\ find\ qualified\ kvm\ host\ for\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = can not find qualified kvm host for shared block group primary storage[uuid: {0}] - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2779 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3409 # args: spec.getVmInventory().getUuid(),String.join(",", psUuids) VM[uuid\:%s]\ has\ multiple\ ISOs\ from\ different\ primary\ storage\:\ %s = VM[uuid:{0}] has multiple ISOs from different primary storage: {1} -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2954 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3584 # args: volume.getUuid() QCow2\ shared\ volume[uuid\:%s]\ is\ not\ supported = QCow2 shared volume[uuid:{0}] is not supported -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3819 -# args: volumeVO.getUuid(),volumeVO.getPrimaryStorageUuid() -can\ not\ find\ any\ available\ host\ to\ resize\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = can not find any available host to resize volume[uuid: {0}] on shared block group primary storage[uuid: {1}] - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3825 -# args: struct.getVmHostUuid(),volumeVO.getUuid(),volumeVO.getPrimaryStorageUuid() -the\ host[uuid\:\ %s]\ running\ on\ is\ not\ available\ to\ resize\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = the host[uuid: {0}] running on is not available to resize volume[uuid: {1}] on shared block group primary storage[uuid: {2}] - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3943 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4650 # args: msg.getVolumeUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ take\ snapshot\ for\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = can not find any available host to take snapshot for volume[uuid: {0}] on shared block group primary storage[uuid: {1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4001 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4708 # args: msg.getPrimaryStorageUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ hosts\ both\ connect\ to\ primary\ storage[uuid\:\ %s]\ and\ primary\ storage[uuid\:\ %s] = can not find hosts both connect to primary storage[uuid: {0}] and primary storage[uuid: {1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3956 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4663 # args: only\ support\ full = only support full -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3984 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4691 # args: msg.getMigrateVolumeStructs().get(0).volumeUuid,msg.getPrimaryStorageUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ migrate\ volume[uuid\:\ %s]\ between\ shared\ block\ group\ primary\ storage[uuid\:\ %s]\ and\ [uuid\:\ %s] = can not find any available host to migrate volume[uuid: {0}] between shared block group primary storage[uuid: {1}] and [uuid: {2}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3993 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4700 # args: msg.getMigrateVolumeStructs().get(0).volumeUuid,msg.getTargetPrimaryStorageUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ migrate\ for\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s]\ and\ [uuid\:\ %s] = can not find any available host to migrate for volume[uuid: {0}] on shared block group primary storage[uuid: {1}] and [uuid: {2}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4045 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4753 # args: msg.getPrimaryStorageUuid() cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ attached\ with\ the\ shared\ block\ group\ storage[uuid\:%s]\ are\ disconnected = cannot find any connected host to perform the operation, it seems all KVM hosts attached with the shared block group storage[uuid:{0}] are disconnected -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4386 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4971 +# args: snapshotVO.getUuid(),volumeVO.getUuid() +cannot\ shrink\ snapshot\ %s,\ because\ volume\ %s\ not\ ready = cannot shrink snapshot {0}, because volume {1} not ready + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5147 +# args: snapshotVO.getUuid(),instanceVO.getUuid() +cannot\ shrink\ snapshot\ %s,\ beacuse\ vm\ %s\ not\ in\ Running/Stopped\ state = cannot shrink snapshot {0}, beacuse vm {1} not in Running/Stopped state + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5394 # args: vmVolumesStruct.vmInstanceVO.getUuid() get\ null\ install\ path\ in\ snapshot\ for\ vm\ %s = get null install path in snapshot for vm {0} -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkCancelMigrateVolumeFlow.java:37 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5707 +# args: msg.getDstPath(),msg.getVolume().getUuid() +dest\ path\ %s\ not\ belong\ to\ volume\ %s\ any\ snapshot = dest path {0} not belong to volume {1} any snapshot + +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkCancelMigrateVolumeFlow.java:33 # args: migrate\ volume\ without\ snapshot\ on\ shared\ block\ is\ not\ support\ to\ cancel. = migrate volume without snapshot on shared block is not support to cancel. -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:129 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:131 # args: reply1.getTrashId(),dstPsUuid,dstVolumeFolderPath,reply1.getResourceUuid() found\ trashId(%s)\ in\ PrimaryStorage\ [%s]\ for\ the\ migrate\ installPath[%s].\ Please\ clean\ it\ first\ by\ 'APICleanUpTrashOnPrimaryStorageMsg'\ if\ you\ insist\ to\ migrate\ the\ volume[%s] = found trashId({0}) in PrimaryStorage [{1}] for the migrate installPath[{2}]. Please clean it first by 'APICleanUpTrashOnPrimaryStorageMsg' if you insist to migrate the volume[{3}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:263 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:271 # args: volumeUuid,volumeVO.getActualSize(),dstPsInv.getAvailablePhysicalCapacity() there\ are\ not\ enough\ capacity\ for\ volume[uuid\:\ %s]\ storage\ migration,\ required\ capacity\:\ %s,\ current\ available\ physical\ capacity\:\ %s = there are not enough capacity for volume[uuid: {0}] storage migration, required capacity: {1}, current available physical capacity: {2} -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:194 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:202 # args: imageUuid,zoneUuid,zoneUuid cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ whether\ the\ backup\ storage\ is\ attached\ to\ the\ zone[uuid\:%s]\n2.\ whether\ the\ backup\ storage\ is\ in\ connected\ status;\ try\ to\ reconnect\ it\ if\ not = cannot find the image[uuid:{0}] in any connected backup storage attached to the zone[uuid:{1}]. check below:\n1. whether the backup storage is attached to the zone[uuid:{2}]\n2. whether the backup storage is in connected status; try to reconnect it if not -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:217 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:225 # args: image.getUuid(),volumeUuid,image.getActualSize(),dstPsInv.getAvailablePhysicalCapacity() there\ are\ not\ enough\ capacity\ for\ image[uuid\:\ %s]\ download\ while\ volume[uuid\:\ %s]\ storage\ migration,\ required\ capacity\:\ %s,\ current\ available\ physical\ capacity\:\ %s = there are not enough capacity for image[uuid: {0}] download while volume[uuid: {1}] storage migration, required capacity: {2}, current available physical capacity: {3} @@ -7970,27 +12774,35 @@ there\ are\ not\ enough\ capacity\ for\ image[uuid\:\ %s]\ download\ while\ volu # args: srcPsUuid data\ on\ source\ ps[uuid\:\ %s]\ has\ been\ discarded,\ not\ support\ rollback = data on source ps[uuid: {0}] has been discarded, not support rollback -# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:1673 +# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:2415 +# args: cmd.volumeUuid,msg.getVolume().getInstallPath(),cmd.srcDir +why\ volume[uuid\:%s,\ installPath\:%s]\ not\ in\ directory\ %s = why volume[uuid:{0}, installPath:{1}] not in directory {2} + +# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:2184 # args: ret.firstAccessHostUuids hosts[uuid\:%s]\ have\ the\ same\ mount\ path,\ but\ actually\ mount\ different\ storage. = hosts[uuid:{0}] have the same mount path, but actually mount different storage. -# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:1837 +# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:2372 # args: msg.getHostUuid(),msg.getPrimaryStorageUuid() host[uuid\:%s]\ might\ mount\ storage\ which\ is\ different\ from\ SMP[uuid\:%s],\ please\ check\ it = host[uuid:{0}] might mount storage which is different from SMP[uuid:{1}], please check it -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java:497 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java:1139 +# args: volumeUuid,infos.toString() +volume[uuid\:%s]\ has\ reference\ volume[%s],\ can\ not\ change\ volume\ type\ before\ flatten\ them\ and\ their\ descendants = volume[uuid:{0}] has reference volume[{1}], can not change volume type before flatten them and their descendants + +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java:597 # args: not\ supported\ operation = not supported operation -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:106 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:109 # args: psUuid,vmUuid,volumeUuid the\ SMP\ primary\ storage[uuid\:%s]\ is\ not\ attached\ to\ any\ clusters,\ and\ cannot\ expunge\ the\ root\ volume[uuid\:%s]\ of\ the\ VM[uuid\:%s] = the SMP primary storage[uuid:{0}] is not attached to any clusters, and cannot expunge the root volume[uuid:{1}] of the VM[uuid:{2}] -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:300 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:303 # args: pri.getUuid() cannot\ find\ a\ Connected\ host\ to\ execute\ command\ for\ smp\ primary\ storage[uuid\:%s] = cannot find a Connected host to execute command for smp primary storage[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:320 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:323 # args: pri.getUuid() cannot\ find\ a\ host\ which\ has\ Connected\ host-SMP\ connection\ to\ execute\ command\ for\ smp\ primary\ storage[uuid\:%s] = cannot find a host which has Connected host-SMP connection to execute command for smp primary storage[uuid:{0}] @@ -7998,278 +12810,446 @@ cannot\ find\ a\ host\ which\ has\ Connected\ host-SMP\ connection\ to\ execute\ # args: \ the\ url\ contains\ an\ invalid\ folder[/dev\ or\ /proc\ or\ /sys] = the url contains an invalid folder[/dev or /proc or /sys] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:88 +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:96 +# args: +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ not\ exists. = failed to cancel deletion job. Volume[uuid:{0}] not exists. + +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:100 +# args: +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ not\ attached\ to\ any\ vm,\ offline\ snapshot\ deletion\ do\ not\ support\ cancel. = failed to cancel deletion job. Volume[uuid:{0}] not attached to any vm, offline snapshot deletion do not support cancel. + +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:106 +# args: +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ attached\ vm\ not\ exists,\ offline\ snapshot\ deletion\ do\ not\ support\ cancel. = failed to cancel deletion job. Volume[uuid:{0}] attached vm not exists, offline snapshot deletion do not support cancel. + +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:111 +# args: VmInstanceState.Running +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ attached\ vm\ not\ in\ state\ %s\ offline\ snapshot\ deletion\ do\ not\ support\ cancel. = failed to cancel deletion job. Volume[uuid:{0}] attached vm not in state {1} offline snapshot deletion do not support cancel. + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:100 +# args: disabledSnapshotUuids +volume\ snapshot[uuids\:%s]\ is\ in\ state\ Disabled,\ cannot\ revert\ volume\ to\ it = volume snapshot[uuids:{0}] is in state Disabled, cannot revert volume to it + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:121 # args: VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() Can\ not\ take\ memory\ snapshot,\ expected\ vm\ states\ are\ [%s,\ %s] = Can not take memory snapshot, expected vm states are [{0}, {1}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:155 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:188 # args: msg.getUuid(),state volume\ snapshot[uuid\:%s]\ is\ in\ state\ %s,\ cannot\ revert\ volume\ to\ it = volume snapshot[uuid:{0}] is in state {1}, cannot revert volume to it -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:160 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:193 # args: msg.getUuid() original\ volume\ for\ snapshot[uuid\:%s]\ has\ been\ deleted,\ cannot\ revert\ volume\ to\ it = original volume for snapshot[uuid:{0}] has been deleted, cannot revert volume to it -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:178 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:211 # args: msg.getVolumeUuid(),snapshotVO.getVolumeUuid() not\ support\ delete\ snapshots\ on\ different\ volumes[uuid\:\ %s,\ %s] = not support delete snapshots on different volumes[uuid: {0}, {1}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:182 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:215 # args: msg.getUuids() can\ not\ find\ volume\ uuid\ for\ snapshosts[uuid\:\ %s] = can not find volume uuid for snapshosts[uuid: {0}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:521 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:834 +# args: PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value(),volumeSize +after\ subtracting\ reserved\ capacity[%s],\ there\ is\ no\ primary\ storage\ having\ required\ size[%s\ bytes],\ may\ be\ the\ threshold\ of\ primary\ storage\ physical\ capacity\ setting\ is\ lower = after subtracting reserved capacity[{0}], there is no primary storage having required size[{1} bytes], may be the threshold of primary storage physical capacity setting is lower + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:617 # args: maxIncrementalSnapshotNum,vo.getVolumeUuid() Unsupported\ maximum\ snapshot\ number\ (%d)\ for\ volume\ [uuid\:%s] = Unsupported maximum snapshot number ({0}) for volume [uuid:{1}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:618 -# args: vol.getUuid(),reply.getError() -cannot\ ask\ primary\ storage[uuid\:%s]\ for\ volume\ snapshot\ capability,\ see\ detail\ [%s] = cannot ask primary storage[uuid:{0}] for volume snapshot capability, see detail [{1}] - -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:814 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1044 # args: primaryStorageUuid,vol.getUuid() primary\ storage[uuid\:%s]\ doesn't\ support\ volume\ snapshot;\ cannot\ create\ snapshot\ for\ volume[uuid\:%s] = primary storage[uuid:{0}] doesn't support volume snapshot; cannot create snapshot for volume[uuid:{1}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:780 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1010 # args: vol.getPrimaryStorageUuid() cannot\ find\ type\ for\ primaryStorage\ [%s] = cannot find type for primaryStorage [{0}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:877 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1107 # args: uuid cannot\ find\ snapshot\:\ %s = cannot find snapshot: {0} -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:153 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1176 +# args: msg.getResourceType() +this\ resource\ type\ %s\ does\ not\ support\ querying\ memory\ snapshot\ references = this resource type {0} does not support querying memory snapshot references + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:162 # args: currentRoot.getUuid(),currentRoot.getName() cannot\ find\ volume\ snapshot[uuid\:%s,\ name\:%s],\ it\ may\ have\ been\ deleted\ by\ previous\ operation = cannot find volume snapshot[uuid:{0}, name:{1}], it may have been deleted by previous operation -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:759 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:418 +# args: refVolUuids +snapshot\ or\ its\ desendant\ has\ reference\ volume[uuids\:%s] = snapshot or its desendant has reference volume[uuids:{0}] + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:1004 # args: failSnapshot.getUuid(),failSnapshot.getName(),evt failed\ to\ change\ status\ of\ volume\ snapshot[uuid\:%s,\ name\:%s]\ by\ status\ event[%s] = failed to change status of volume snapshot[uuid:{0}, name:{1}] by status event[{2}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:1465 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:1847 # args: volumeInventory.getUuid(),currentRoot.getUuid(),vmUuid,state unable\ to\ reset\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s],\ the\ vm[uuid\:%s]\ volume\ attached\ to\ is\ not\ in\ Stopped\ state,\ current\ state\ is\ %s = unable to reset volume[uuid:{0}] to snapshot[uuid:{1}], the vm[uuid:{2}] volume attached to is not in Stopped state, current state is {3} -# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:77 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:2228 +# args: currentRoot.getUuid() +current\ snapshot\:%s\ is\ not\ latest\ snapshot,\ cannot\ mark\ as\ volume = current snapshot:{0} is not latest snapshot, cannot mark as volume + +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupBase.java:282 +# args: ext.getArchiveBundleCanonicalName() +no\ bundle\ found\ for\ type\:%s = no bundle found for type:{0} + +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:89 # args: String.join(", ", deletedSnapshotInfos) snapshot(s)\ %s\ in\ the\ group\ has\ been\ deleted,\ can\ only\ revert\ one\ by\ one. = snapshot(s) {0} in the group has been deleted, can only revert one by one. -# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:81 +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:93 # args: String.join(", ", detachedVolInfos) volume(s)\ %s\ is\ no\ longer\ attached,\ can\ only\ revert\ one\ by\ one.\ If\ you\ need\ to\ group\ revert,\ please\ re-attach\ it. = volume(s) {0} is no longer attached, can only revert one by one. If you need to group revert, please re-attach it. -# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:89 +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:101 # args: volInfos new\ volume(s)\ %s\ attached\ after\ snapshot\ point,\ can\ only\ revert\ one\ by\ one.\ If\ you\ need\ to\ group\ revert,\ please\ detach\ it. = new volume(s) {0} attached after snapshot point, can only revert one by one. If you need to group revert, please detach it. -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:269 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:292 # args: Can't\ attach\ volume\ to\ VM,\ no\ qualified\ cluster = Can't attach volume to VM, no qualified cluster -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:137 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:407 +# args: psUuid,msg.getPrimaryStorageUuid() +primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = primaryStorageUuid conflict, the primary storage specified by the disk offering is {0}, and the primary storage specified in the creation parameter is {1} + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:156 # args: vol.getUuid(),vol.getStatus() volume[uuid\:%s]\ is\ not\ in\ status\ Ready,\ current\ is\ %s,\ can't\ create\ snapshot = volume[uuid:{0}] is not in status Ready, current is {1}, can't create snapshot -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:113 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:126 # args: msg.getVolumeUuid(),type volume[uuid\:%s,\ type\:%s],\ can't\ create\ snapshot = volume[uuid:{0}, type:{1}], can't create snapshot -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:127 -# args: msg.getRootVolumeUuid() -volume[uuid\:%s]\ is\ root\ volume = volume[uuid:{0}] is root volume - # at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:131 +# args: msg.getVolumeUuid(),state +volume[uuid\:%s]\ is\ not\ in\ state\ Enabled,\ current\ is\ %s,\ can't\ create\ snapshot = volume[uuid:{0}] is not in state Enabled, current is {1}, can't create snapshot + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:150 # args: vmvo.getState().toString(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() Can\ not\ take\ memory\ snapshot,\ vm\ current\ state[%s],\ but\ expect\ state\ are\ [%s,\ %s] = Can not take memory snapshot, vm current state[{0}], but expect state are [{1}, {2}] -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:150 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:183 # args: msg.getVolumeUuid() the\ volume[uuid\:%s]\ is\ not\ in\ status\ of\ deleted.\ This\ is\ operation\ is\ to\ recover\ a\ deleted\ data\ volume = the volume[uuid:{0}] is not in status of deleted. This is operation is to recover a deleted data volume -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:296 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:319 # args: vol.getUuid() the\ volume[uuid\:%s]\ is\ in\ status\ of\ deleted,\ cannot\ do\ the\ operation = the volume[uuid:{0}] is in status of deleted, cannot do the operation -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:168 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:201 # args: msg.getImageUuid(),ImageMediaType.DataVolumeTemplate,type image[uuid\:%s]\ is\ not\ %s,\ it's\ %s = image[uuid:{0}] is not {1}, it's {2} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:172 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:205 # args: img.getUuid(),img.getState() image[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = image[uuid:{0}] is not Enabled, it's {1} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:176 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:209 # args: img.getUuid(),img.getStatus() image[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = image[uuid:{0}] is not Ready, it's {1} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:182 -# args: -DataVolumeFromVolumeTemplate\ not\ support\ Shareable = DataVolumeFromVolumeTemplate not support Shareable - -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:197 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:221 # args: msg.getVolumeUuid() volume[uuid\:%s]\ is\ Root\ volume,\ can\ not\ be\ attach\ to\ vm = volume[uuid:{0}] is Root volume, can not be attach to vm -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:204 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:228 # args: msg.getVolumeUuid(),state,VolumeState.Enabled volume[uuid\:%s]\ is\ in\ state[%s],\ data\ volume\ can\ only\ be\ attached\ when\ state\ is\ %s = volume[uuid:{0}] is in state[{1}], data volume can only be attached when state is {2} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:209 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:233 # args: msg.getVolumeUuid(),status,VolumeStatus.Ready,VolumeStatus.NotInstantiated volume[uuid\:%s]\ is\ in\ status[%s],\ data\ volume\ can\ only\ be\ attached\ when\ status\ is\ %s\ or\ %S = volume[uuid:{0}] is in status[{1}], data volume can only be attached when status is {2} or %S -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:216 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:240 # args: msg.getVolumeUuid() data\ volume[uuid\:%s]\ is\ not\ attached\ to\ any\ vm,\ can't\ detach = data volume[uuid:{0}] is not attached to any vm, can't detach -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:220 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:244 # args: msg.getVolumeUuid() to\ detach\ shareable\ data\ volume[uuid\:%s],\ vm\ uuid\ is\ needed. = to detach shareable data volume[uuid:{0}], vm uuid is needed. -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:225 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:249 # args: vol.getUuid(),vol.getName(),vol.getType() the\ volume[uuid\:%s,\ name\:%s,\ type\:%s]\ can't\ detach\ it = the volume[uuid:{0}, name:{1}, type:{2}] can't detach it -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:282 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:305 # args: msg.getVmInstanceUuid(),msg.getVolumeUuid() the\ vm[uuid\:%s]\ doesn't\ support\ to\ online\ attach\ volume[%s]\ on\ the\ basis\ of\ that\ the\ image\ platform\ type\ of\ the\ vm\ is\ other\ = the vm[uuid:{0}] doesn't support to online attach volume[{1}] on the basis of that the image platform type of the vm is other -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:287 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:310 # args: vol.getUuid(),vol.getName() the\ volume[uuid\:%s,\ name\:%s]\ is\ Root\ Volume,\ can't\ attach\ it = the volume[uuid:{0}, name:{1}] is Root Volume, can't attach it -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:292 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:315 # args: vol.getUuid() data\ volume[uuid\:%s]\ is\ Disabled,\ can't\ attach = data volume[uuid:{0}] is Disabled, can't attach -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:300 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:323 # args: vol.getUuid() data\ volume[uuid\:%s]\ has\ been\ attached\ to\ some\ vm,\ can't\ attach\ again = data volume[uuid:{0}] has been attached to some vm, can't attach again -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:305 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:328 # args: VolumeStatus.Ready,VolumeStatus.NotInstantiated,vol.getStatus() data\ volume\ can\ only\ be\ attached\ when\ status\ is\ [%s,\ %s],\ current\ is\ %s = data volume can only be attached when status is [{0}, {1}], current is {2} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:313 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:336 # args: vol.getUuid(),vol.getFormat(),hvTypes,msg.getVmInstanceUuid(),hvType data\ volume[uuid\:%s]\ has\ format[%s]\ that\ can\ only\ be\ attached\ to\ hypervisor[%s],\ but\ vm[uuid\:%s]\ has\ hypervisor\ type[%s].\ Can't\ attach = data volume[uuid:{0}] has format[{1}] that can only be attached to hypervisor[{2}], but vm[uuid:{3}] has hypervisor type[{4}]. Can't attach -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:326 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:349 # args: hvType,maxDataVolumeNum,count,msg.getVmInstanceUuid() hypervisor[%s]\ only\ allows\ max\ %s\ data\ volumes\ to\ be\ attached\ to\ a\ single\ vm;\ there\ have\ been\ %s\ data\ volumes\ attached\ to\ vm[uuid\:%s] = hypervisor[{0}] only allows max {1} data volumes to be attached to a single vm; there have been {2} data volumes attached to vm[uuid:{3}] -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:338 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:367 +# args: hostUuid,vol.getPrimaryStorageUuid() +Can\ not\ attach\ volume\ to\ vm\ runs\ on\ host[uuid\:\ %s]\ which\ is\ disconnected\ with\ volume's\ storage[uuid\:\ %s] = Can not attach volume to vm runs on host[uuid: {0}] which is disconnected with volume's storage[uuid: {1}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:378 # args: msg.getUuid() it's\ not\ allowed\ to\ backup\ root\ volume,\ uuid\:%s = it's not allowed to backup root volume, uuid:{0} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:347 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:387 # args: unexpected\ disk\ size\ settings = unexpected disk size settings -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:365 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:427 # args: msg.getVolumeUuid(),type volume[uuid\:%s,\ type\:%s]\ can't\ be\ deleted = volume[uuid:{0}, type:{1}] can't be deleted -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:370 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:432 # args: msg.getVolumeUuid() volume[uuid\:%s]\ is\ already\ in\ status\ of\ deleted = volume[uuid:{0}] is already in status of deleted -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:384 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:438 +# args: msg.getVolumeUuid(),hostUuid +can\ not\ delete\ volume[%s],\ because\ volume\ attach\ to\ host[%s] = can not delete volume[{0}], because volume attach to host[{1}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:453 # args: msg.getUuid() it's\ not\ allowed\ to\ change\ state\ of\ root\ volume,\ uuid\:%s = it's not allowed to change state of root volume, uuid:{0} -# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:687 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:461 +# args: msg.getVolumeUuid(),hostUuid +can\ not\ change\ volume[%s]\ state,\ because\ volume\ attach\ to\ host[%s] = can not change volume[{0}] state, because volume attach to host[{1}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:469 +# args: msg.getVolumeUuid(),msg.getHostUuid(),hostStatus +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ host[status\:%s]\ is\ not\ connected = can not attach volume[{0}] to host[{1}], because host[status:{2}] is not connected + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:474 +# args: +mount\ path\ must\ be\ absolute\ path = mount path must be absolute path + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:491 +# args: msg.getVolumeUuid(),msg.getHostUuid(),hostUuid +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ volume\ is\ attaching\ to\ host[%s] = can not attach volume[{0}] to host[{1}], because volume is attaching to host[{2}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:495 +# args: msg.getVolumeUuid(),msg.getHostUuid(),msg.getVolumeUuid(),mountPath,hostUuid +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ the\ volume[%s]\ occupies\ the\ mount\ path[%s]\ on\ host[%s] = can not attach volume[{0}] to host[{1}], because the volume[{2}] occupies the mount path[{3}] on host[{4}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:505 +# args: msg.getVolumeUuid(),msg.getHostUuid(),msg.getMountPath() +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ the\ another\ volume\ occupies\ the\ mount\ path[%s] = can not attach volume[{0}] to host[{1}], because the another volume occupies the mount path[{2}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:512 +# args: msg.getVolumeUuid() +can\ not\ detach\ volume[%s]\ from\ host.\ it\ may\ have\ been\ detached = can not detach volume[{0}] from host. it may have been detached + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:520 +# args: msg.getVolumeUuid() +cannot\ flatten\ a\ shareable\ volume[uuid\:%s] = cannot flatten a shareable volume[uuid:{0}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:531 +# args: msg.getUuid() +can\ not\ found\ in\ used\ snapshot\ tree\ of\ volume[uuid\:\ %s] = can not found in used snapshot tree of volume[uuid: {0}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:541 +# args: +cannot\ undo\ not\ latest\ snapshot = cannot undo not latest snapshot + +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:200 +# args: self.getRootImageUuid() +cannot\ find\ image\ cache[imageUuid\:\ %s]\ for\ reinit\ volume = cannot find image cache[imageUuid: {0}] for reinit volume + +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:843 # args: self.getUuid(),self.getName() the\ volume[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ yet,\ can't\ expunge\ it = the volume[uuid:{0}, name:{1}] is not deleted yet, can't expunge it -# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:194 +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:1780 +# args: +volume[uuid%s]\ should\ be\ attached. = volume[uuid{0}] should be attached. + +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:1866 +# args: +only\ support\ detached\ volume,\ use\ SetVmBootVolumeMsg\ instead. = only support detached volume, use SetVmBootVolumeMsg instead. + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:166 +# args: msg.getPrimaryStorageUuid() +get\ primaryStorage\ %s\ type\ failed = get primaryStorage {0} type failed + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:170 +# args: psType +primaryStorage\ type\ [%s]\ not\ support\ shared\ volume\ yet = primaryStorage type [{0}] not support shared volume yet + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:296 # args: template.getUuid(),template.getName() the\ image[uuid\:%s,\ name\:%s]\ has\ been\ deleted\ on\ all\ backup\ storage = the image[uuid:{0}, name:{1}] has been deleted on all backup storage -# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:211 +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:313 # args: template.getUuid(),msg.getPrimaryStorageUuid() cannot\ find\ a\ backup\ storage\ on\ which\ the\ image[uuid\:%s]\ is\ that\ satisfies\ all\ conditions\ of\:\ 1.\ has\ state\ Enabled\ 2.\ has\ status\ Connected.\ 3\ has\ attached\ to\ zone\ in\ which\ primary\ storage[uuid\:%s]\ is = cannot find a backup storage on which the image[uuid:{0}] is that satisfies all conditions of: 1. has state Enabled 2. has status Connected. 3 has attached to zone in which primary storage[uuid:{1}] is -# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:695 +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:868 +# args: +target\ volume\ is\ expunged\ during\ volume\ creation = target volume is expunged during volume creation + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:1106 # args: VolumeFactory.class.getSimpleName() there\ should\ not\ be\ more\ than\ one\ %s\ implementation. = there should not be more than one {0} implementation. -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:77 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:231 +# args: msg.getUuid() +volume[uuid\:%s]\ is\ not\ root\ volume = volume[uuid:{0}] is not root volume + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:95 +# args: IOTHREAD_QEMU_VERSION,qemuVersion,finalHostUuid +iothread\ need\ qemu\ version\ >\=\ %s,\ but\ %s\ on\ host[%s]. = iothread need qemu version >= {0}, but {1} on host[{2}]. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:103 +# args: IOTHREAD_LIBVIRT_VERSION,libvirtVersion,finalHostUuid +iothread\ need\ libvirt\ version\ >\=\ %s,\ but\ %s\ on\ host[%s]. = iothread need libvirt version >= {0}, but {1} on host[{2}]. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:108 +# args: msg.getVolumeUuid() +root\ volume[%s]\ cannot\ set\ iothreadpin. = root volume[{0}] cannot set iothreadpin. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:115 +# args: msg.getIoThreadId(),msg.getVolumeUuid(),pinInfo[0] +current\ iothread\ id[%s]\ is\ not\ the\ same\ as\ attached\ vol[%s]\ iothread[%s]. = current iothread id[{0}] is not the same as attached vol[{1}] iothread[{2}]. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:131 +# args: msg.getUuid() +snapshot\ validation\ is\ unsupported\ for\ volume[uuid\:\ %s].\ Volume\ should\ be\ attached\ to\ vm = snapshot validation is unsupported for volume[uuid: {0}]. Volume should be attached to vm + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:139 +# args: msg.getUuid(),VmInstanceState.Running,VmInstanceState.Paused +snapshot\ validation\ is\ unsupported\ for\ volume[uuid\:\ %s].\ Attached\ vm\ is\ not\ in\ state\ of\ [%s,\ %s] = snapshot validation is unsupported for volume[uuid: {0}]. Attached vm is not in state of [{1}, {2}] + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:149 # args: volumeUuid volume[uuid\:%s]\ can\ not\ found = volume[uuid:{0}] can not found -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:84 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:156 # args: volumeUuid,volumeVOS.get(0).getUuid(),volumeVO.getVmInstanceUuid(),volumeVOS.get(0).getVmInstanceUuid() not\ support\ take\ snapshots\ volume[uuid\:%s,\ uuid\:%s]\ on\ different\ vms[uuid\:%s,\ uuid\:%s] = not support take snapshots volume[uuid:{0}, uuid:{1}] on different vms[uuid:{2}, uuid:{3}] -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:91 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:163 # args: volumeUuid volume[uuid\:%s]\ is\ not\ ready = volume[uuid:{0}] is not ready -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:106 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:178 # args: vmInstanceVO.getUuid(),vmInstanceVO.getState() state\ of\ vm[uuid\:\ %s]\ is\ %s,\ not\ allowed\ to\ take\ snapshots = state of vm[uuid: {0}] is {1}, not allowed to take snapshots -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:142 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:188 # args: msg.getUuid() volume[uuid\:%s]\ is\ not\ data\ volume = volume[uuid:{0}] is not data volume -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:162 -# args: msg.getUuid() -volume[uuid\:%s]\ is\ not\ root\ volume = volume[uuid:{0}] is not root volume +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:198 +# args: msg.getVolumeUuid() +can\ not\ resize\ volume[%s],\ because\ volume\ state\ is\ Disabled = can not resize volume[{0}], because volume state is Disabled + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:212 +# args: +At\ least\ one\ of\ vmInstanceUuid\ or\ uuid\ should\ be\ set = At least one of vmInstanceUuid or uuid should be set + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:227 +# args: msg.getUuid(),msg.getVmInstanceUuid() +no\ volume[uuid\:%s,\ vmInstanceUuid\:%s]\ can\ be\ found = no volume[uuid:{0}, vmInstanceUuid:{1}] can be found -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:174 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:245 # args: SharedVolume\ cannot\ be\ set\ bandwidth. = SharedVolume cannot be set bandwidth. -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:182 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:254 +# args: +Cannot\ set\ legacy\ params\ and\ new\ params\ at\ the\ same\ time. = Cannot set legacy params and new params at the same time. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:259 +# args: +Cannot\ set\ the\ read/write\ and\ the\ total\ IOPS\ limits\ at\ the\ same\ time. = Cannot set the read/write and the total IOPS limits at the same time. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:264 +# args: +Cannot\ set\ the\ read/write\ and\ the\ total\ bandwidth\ limits\ at\ the\ same\ time. = Cannot set the read/write and the total bandwidth limits at the same time. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:273 +# args: +The\ volume\ bandwidth\ cannot\ be\ null,\ must\ give\ a\ volume\ bandwidth\ value. = The volume bandwidth cannot be null, must give a volume bandwidth value. + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:284 # args: vo.getType(),vo.getUuid() Cannot\ shrink\ [%s]\ volume[uuid\:%s]'s\ size = Cannot shrink [{0}] volume[uuid:{1}]'s size -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:189 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:291 # args: Minimum\ increase\ size\ should\ be\ larger\ than\ 4MB = Minimum increase size should be larger than 4MB -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:213 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:315 # args: Expansion\ operation\ not\ allowed\ at\ all\ host\ disable = Expansion operation not allowed at all host disable -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:200 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:302 # args: Expansion\ operation\ not\ allowed\ at\ host\ disable = Expansion operation not allowed at host disable -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:239 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:341 # args: vo.getUuid(),notStoppedVmUuids shared\ volume[uuid\:\ %s]\ has\ attached\ to\ not\ stopped\ vm\ instances[uuids\:\ %s] = shared volume[uuid: {0}] has attached to not stopped vm instances[uuids: {1}] -# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:56 +# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:79 # args: msg.getResourceType() no\ resource\ type[%s]\ found\ in\ tag\ system = no resource type[{0}] found in tag system -# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:74 +# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:102 # args: msg.getUuid() tag[uuid\:%s]\ is\ an\ inherent\ system\ tag,\ can\ not\ be\ removed = tag[uuid:{0}] is an inherent system tag, can not be removed -# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:100 +# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:128 # args: The\ argument\ \:'resourceType'\ doesn't\ match\ uuid = The argument :'resourceType' doesn't match uuid -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:207 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:239 # args: tag,type,resourceType,resourceUuid Duplicated\ Tag[tag\:%s,\ type\:%s,\ resourceType\:%s,\ resourceUuid\:%s] = Duplicated Tag[tag:{0}, type:{1}, resourceType:{2}, resourceUuid:{3}] -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:645 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:755 # args: tag,resourceType no\ system\ tag\ matches[%s]\ for\ resourceType[%s] = no system tag matches[{0}] for resourceType[{1}] -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:818 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:761 +# args: tag,resourceType +validate\ system\ tag\ [%s]\ for\ resourceType[%s]\ failed = validate system tag [{0}] for resourceType[{1}] failed + +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:944 # args: tag no\ system\ tag\ matches\ %s = no system tag matches {0} -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:847 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:979 # args: tag tag[%s]\ is\ only\ for\ admin = tag[{0}] is only for admin +# at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:162 +# args: invalidUuids,expectAccountUuid +resource[uuids\:%s]\ is\ not\ owned\ by\ account[uuid\:%s] = resource[uuids:{0}] is not owned by account[uuid:{1}] + # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:85 # args: cannot\ update\ simple\ tag\ pattern\ format = cannot update simple tag pattern format @@ -8298,23 +13278,39 @@ Get\ format[%s],\ format\ must\ like\ that\ name\:\:{tokenName1}\:\:{tokenName2} # args: formatTokens all\ tokens\ %s\ must\ be\ specify = all tokens {0} must be specify -# at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:162 -# args: invalidUuids,expectAccountUuid -resource[uuids\:%s]\ is\ not\ owned\ by\ account[uuid\:%s] = resource[uuids:{0}] is not owned by account[uuid:{1}] - -# at: src/main/java/org/zstack/tag2/TagPatternBase.java:184 +# at: src/main/java/org/zstack/tag2/TagPatternBase.java:185 # args: resourceUuid,attachedCount resource[uuid\:%s]\ has\ been\ attached\ %d\ tags,\ cannot\ attach\ any\ more = resource[uuid:{0}] has been attached {1} tags, cannot attach any more -# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:88 +# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:79 +# args: msg.getTemplateUuid() +unable\ to\ find\ any\ TemplateConfigs\:\ [templateUuid\:\ %s] = unable to find any TemplateConfigs: [templateUuid: {0}] + +# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:151 +# args: msg.getTemplateUuid() +Unable\ to\ find\ any\ TemplateConfigs\:\ [templateUuid\:\ %s] = Unable to find any TemplateConfigs: [templateUuid: {0}] + +# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:128 # args: msg.getCategory(),msg.getName(),msg.getTemplateUuid() Unable\ to\ find\ TemplateConfig[category\:\ %s,\ name\:\ %s,\ templateUuid\:\ %s] = Unable to find TemplateConfig[category: {0}, name: {1}, templateUuid: {2}] -# at: src/main/java/org/zstack/ticket/TicketBase.java:239 +# at: src/main/java/org/zstack/testlib/premium/crypto/EncryptDriverSimulator.java:123 +# args: algType +illegal\ argument\ %s = illegal argument {0} + +# at: src/main/java/org/zstack/testlib/premium/crypto/EncryptDriverSimulator.java:136 +# args: +failed\ to\ decrypt\ data = failed to decrypt data + +# at: src/main/java/org/zstack/testlib/premium/crypto/SecurityMachineSimulator.java:399 +# args: e.getMessage(),cipherText +failed\ to\ parse\ MS\ envelope\:\ %s,\ %s = failed to parse MS envelope: {0}, {1} + +# at: src/main/java/org/zstack/ticket/TicketBase.java:235 # args: self.getUuid(),self.getName(),self.getStatus() ticket[uuid\:%s,\ name\:%s]\ can\ only\ be\ updated\ after\ being\ cancelled,\ current\ status\ is\ %s = ticket[uuid:{0}, name:{1}] can only be updated after being cancelled, current status is {2} -# at: src/main/java/org/zstack/ticket/TicketBase.java:293 +# at: src/main/java/org/zstack/ticket/TicketBase.java:299 # args: operator.operatorUuid operation\ denied.\ the\ operator\ needs\ to\ be\ done\ by\ account/virtual\ ID[uuid\:%s] = operation denied. the operator needs to be done by account/virtual ID[uuid:{0}] @@ -8382,59 +13378,79 @@ the\ virtual\ ID[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ ticket[uuid\:%s,\ name # args: approver\ is\ removed\ from\ project\ or\ deleted,\ flow\ collection\ changed\ to\ invalid,\ reject\ this\ ticket = approver is removed from project or deleted, flow collection changed to invalid, reject this ticket -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:118 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:117 # args: at\ least\ one\ flow\ is\ needed\ for\ create\ flow\ collection = at least one flow is needed for create flow collection -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:125 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:124 # args: flow.approverTitle,approveTitles wrong\ approver\ title\ %s,\ valid\ value\ is\ %s = wrong approver title {0}, valid value is {1} -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:141 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:140 # args: flow.approverUuid can\ not\ find\ IAM2VirtualIDVO[uuid\:%s] = can not find IAM2VirtualIDVO[uuid:{0}] -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:64 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:62 # args: name\ is\ needed\ when\ create\ a\ flow = name is needed when create a flow -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:427 -# args: currentRoot.getPrimaryStorageUuid(),currentLeaf.getUuid(),Math.abs(requiredSize - primaryStorageVO.getCapacity().getAvailablePhysicalCapacity()) -primaryStorage[uuid\:%s]\ has\ no\ enough\ space\ to\ rebase\ snapshot[uuid\:%s],\ please\ free\ more\ than\ %s\ bytes\ storage\ space = primaryStorage[uuid:{0}] has no enough space to rebase snapshot[uuid:{1}], please free more than {2} bytes storage space - -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:81 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:79 # args: one\ ticket\ type\ can\ only\ have\ one\ matches\ flow\ collection = one ticket type can only have one matches flow collection -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:103 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:102 # args: -admin\ is\ required\ as\ approver\ of\ the\ last\ flow = admin is required as approver of the last flow +admin\ or\ iam2\ operation\ is\ required\ as\ approver\ of\ the\ last\ flow = admin or iam2 operation is required as approver of the last flow -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:129 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:128 # args: name\ cannot\ be\ null = name cannot be null -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:133 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:132 # args: approverUuid\ cannot\ be\ null = approverUuid cannot be null -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:148 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:147 # args: flow.approverUuid,projectUuid virtual\ id[uuid\:%s]\ not\ belong\ to\ project[uuid\:%s] = virtual id[uuid:{0}] not belong to project[uuid:{1}] -# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:118 +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationIAM2Backend.java:42 +# args: loginType +Unsupported\ AccountType:%s = Unsupported AccountType:{0} + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:124 # args: two\ factor\ authenticator\ is\ not\ enabled = two factor authenticator is not enabled -# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:269 +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:484 +# args: +two\ factor\ authentication\ failed\ because\ there\ is\ no\ system\ tags\ in\ msg = two factor authentication failed because there is no system tags in msg + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:490 +# args: +two\ factor\ authentication\ failed\ because\ there\ is\ no\ token\ in\ msg\ system\ tag = two factor authentication failed because there is no token in msg system tag + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:497 +# args: loginContext.getLoginBackendType(),info.getUserUuid() +two\ factor\ authentication\ failed\ because\ there\ is\ no\ secret\ for\ %s\:%s = two factor authentication failed because there is no secret for {0}:{1} + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:507 +# args: +failed\ to\ verify\ two\ factor\ authentication\ code = failed to verify two factor authentication code + +# at: src/main/java/org/zstack/upgrade/UpgradeManagerImpl.java:148 +# args: msg.getClass().getName() +Operation\ [%s]\ is\ forbidden\ during\ grayscale\ upgrade = Operation [{0}] is forbidden during grayscale upgrade + +# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:267 # args: usbInv.getHostUuid() host[%s]\ has\ started\ more\ than\ 64\ usb\ redirect\ port = host[{0}] has started more than 64 usb redirect port -# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:274 +# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:272 # args: host.getUuid() unable\ to\ start\ usb\ server\ on\ host[%s],\ because\ host\ is\ not\ connected = unable to start usb server on host[{0}], because host is not connected -# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:296 +# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:294 # args: usbInv.getHostUuid() failed\ to\ start\ usbredirect\ server\ from\ host[uuid\:%s] = failed to start usbredirect server from host[uuid:{0}] @@ -8442,75 +13458,91 @@ failed\ to\ start\ usbredirect\ server\ from\ host[uuid\:%s] = failed to start u # args: no\ candidate\ host\ with\ the\ usb\ device\ have\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = no candidate host with the usb device have enough cpu / memory or Enabled/Connected status -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:59 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:60 +# args: msg.getClass().getSimpleName() +%s\ can\ only\ be\ called\ by\ admin\ account = {0} can only be called by admin account + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:98 +# args: UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM +You\ can\ attach\ at\ most\ %s\ USB\ 1.0\ devices\ to\ one\ vm\ instance. = You can attach at most {0} USB 1.0 devices to one vm instance. + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:107 +# args: UsbDeviceConstants.MAX_USB_2_DEVICE_PER_VM +You\ can\ attach\ at\ most\ %s\ USB\ 2.0\ devices\ to\ one\ vm\ instance. = You can attach at most {0} USB 2.0 devices to one vm instance. + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:116 +# args: UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM +You\ can\ attach\ at\ most\ %s\ USB\ 3.0\ devices\ to\ one\ vm\ instance. = You can attach at most {0} USB 3.0 devices to one vm instance. + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:127 # args: msg.getUsbDeviceUuid(),usb.getVmInstanceUuid() the\ usb\ device[uuid\:%s]\ has\ already\ been\ attached\ to\ another\ vm[uuid\:%s] = the usb device[uuid:{0}] has already been attached to another vm[uuid:{1}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:66 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:134 # args: msg.getUsbDeviceUuid(),UsbDeviceState.Enabled the\ usb\ device[uuid\:%s]\ is\ not\ in\ attachable\ state\ of\ %s = the usb device[uuid:{0}] is not in attachable state of {1} -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:74 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:142 # args: msg.getVmInstanceUuid(),allowedVmInstanceAttachableState the\ vm\ instance[uuid\:%s]\ is\ not\ in\ attachable\ state\ of\ %s\ for\ usb\ device = the vm instance[uuid:{0}] is not in attachable state of {1} for usb device -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:84 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:152 # args: usb.getHostUuid(),msg.getUsbDeviceUuid(),HostState.Enabled,HostStatus.Connected the\ host\ that\ the\ usb\ device[uuid\:%s]\ pluged\ in\ is\ not\ in\ valid\ state[%s]\ or\ status[%s] = the host that the usb device[uuid:{0}] pluged in is not in valid state[{1}] or status[{2}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:97 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:165 # args: usb.getUuid(),vm.getUuid() the\ usb\ device[uuid\:%s]\ has\ different\ hostUuid\ than\ devices\ that\ already\ attached\ to\ the\ vm\ instance[uuid\:%s] = the usb device[uuid:{0}] has different hostUuid than devices that already attached to the vm instance[uuid:{1}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:109 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:177 # args: usb.getUuid() the\ usb\ device[uuid\:%s]\ is\ not\ attached\ to\ any\ vm\ instance. = the usb device[uuid:{0}] is not attached to any vm instance. -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:117 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:185 # args: usb.getUuid(),allowedVmInstanceDetachableState the\ vm\ instance\ that\ the\ usb\ device[uuid\:%s]\ is\ attached\ to\ is\ not\ in\ detachable\ state\ of\ %s = the vm instance that the usb device[uuid:{0}] is attached to is not in detachable state of {1} -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:127 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:195 # args: vm.getUuid(),allowedVmInstanceAttachableState vm\ instance[uuid\:%s]\ not\ in\ attachable\ state\ of\ %s\ for\ usb\ device = vm instance[uuid:{0}] not in attachable state of {1} for usb device -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:138 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:206 # args: msg.getUuid() cannot\ disable\ usb\ device[uuid\:%s]\ when\ it's\ attached\ to\ a\ vm\ instance = cannot disable usb device[uuid:{0}] when it's attached to a vm instance -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:711 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:218 +# args: VmInstanceUuid +please\ umount\ all\ usb\ devices\ of\ the\ vm[%s]\ and\ try\ again = please umount all usb devices of the vm[{0}] and try again + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:795 # args: msg.getVmInstanceUuid() cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ pci\ devices\ attached = cannot migrate vm[uuid:{0}] because there are pci devices attached -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:202 -# args: UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM -You\ can\ attach\ at\ most\ %s\ USB\ 1.0\ devices\ to\ one\ vm\ instance. = You can attach at most {0} USB 1.0 devices to one vm instance. - -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:217 -# args: UsbDeviceConstants.MAX_USB_2_DEVICE_PER_VM -You\ can\ attach\ at\ most\ %s\ USB\ 2.0\ devices\ to\ one\ vm\ instance. = You can attach at most {0} USB 2.0 devices to one vm instance. - -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:232 -# args: UsbDeviceConstants.MAX_USB_3_DEVICE_PER_VM -You\ can\ attach\ at\ most\ %s\ USB\ 3.0\ devices\ to\ one\ vm\ instance. = You can attach at most {0} USB 3.0 devices to one vm instance. +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:164 +# args: msg.getUsbDeviceUuid(),usb.getVmInstanceUuid() +the\ usb\ device[uuid\:%s]\ has\ already\ been\ attached\ to\ vm[uuid\:%s] = the usb device[uuid:{0}] has already been attached to vm[uuid:{1}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:160 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:181 # args: PassThrough\ only\ support\ use\ on\ vm\ running\ host = PassThrough only support use on vm running host -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:177 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:198 # args: msg.getUsbDeviceUuid(),msg.getVmInstanceUuid() -cannot\ attach\ the\ usb\ device[uuid\:%s]\ to\ vm[uuid\:%s]\ due\ to\ host\ allocation = cannot attach the usb device[uuid:{0}] to vm[uuid:{1}] due to host allocation +cannot\ attach\ the\ usb\ device[uuid\:%s]\ to\ vm[uuid\:%s],\ possibly\ reasons\ include\:\ the\ device\ is\ not\ enabled\ or\ had\ been\ attached\ to\ a\ vm,\ or\ the\ device\ and\ the\ vm\ are\ not\ on\ same\ host. = cannot attach the usb device[uuid:{0}] to vm[uuid:{1}], possibly reasons include: the device is not enabled or had been attached to a vm, or the device and the vm are not on same host. + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:558 +# args: deviceVO.getVmInstanceUuid() +usb\ is\ already\ bound\ to\ vm[uuid\:%s]\ and\ cannot\ be\ bound\ to\ other\ vm = usb is already bound to vm[uuid:{0}] and cannot be bound to other vm -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:647 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:731 # args: msg.getVmInstanceUuid() vm[%s]\ cannot\ start\ because\ usb\ redirect\ host\ is\ not\ connected = vm[{0}] cannot start because usb redirect host is not connected -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:660 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:744 # args: msg.getVmInstanceUuid() cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached\ by\ passthrough = cannot migrate vm[uuid:{0}] because there are usb devices attached by passthrough -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:693 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:777 # args: msg.getVolumeUuid() cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached = cannot migrate root volume[uuid:{0}] because there are usb devices attached @@ -8522,11 +13554,15 @@ not\ the\ time\ to\ clean = not the time to clean # args: conversionHost.getUuid(),conversionHost.getHostUuid() conversionHost[uuid\:%s,\ hostUuid\:%s]\ is\ not\ Connected = conversionHost[uuid:{0}, hostUuid:{1}] is not Connected -# at: src/main/java/org/zstack/v2v/ResumeConvertVmJobGC.java:126 +# at: src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java:91 +# args: hostUuid,psUuid +waiting\ host[uuid\:%s]\ and\ primaryStorage[uuid\:%s]\ Connected... = waiting host[uuid:{0}] and primaryStorage[uuid:{1}] Connected... + +# at: src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java:149 # args: hostUuid host[uuid\:%s]\ is\ not\ Connected = host[uuid:{0}] is not Connected -# at: src/main/java/org/zstack/v2v/ResumeConvertVmJobGC.java:130 +# at: src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java:153 # args: primaryStorageUuid primaryStorage[uuid%s]\ is\ not\ Connected = primaryStorage[uuid{0}] is not Connected @@ -8538,6 +13574,14 @@ Not\ allowed\ same\ mac\ [%s] = Not allowed same mac [{0}] # args: duplicateElements.get(0) Can't\ add\ same\ uuid\ in\ the\ l3Network,uuid\:\ %s = Can't add same uuid in the l3Network,uuid: {0} +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:217 +# args: l3Uuid +l3Network[uuid\:%s]\ is\ Disabled,\ can\ not\ create\ vm\ on\ it = l3Network[uuid:{0}] is Disabled, can not create vm on it + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:220 +# args: l3Uuid +l3Network[uuid\:%s]\ is\ system\ network,\ can\ not\ create\ user\ vm\ on\ it = l3Network[uuid:{0}] is system network, can not create user vm on it + # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:252 # args: msg.getZoneUuid() zone[uuid\:%s]\ is\ specified\ but\ it's\ Disabled,\ can\ not\ create\ vm\ from\ it = zone[uuid:{0}] is specified but it's Disabled, can not create vm from it @@ -8558,30 +13602,30 @@ host[uuid\:%s]\ is\ specified\ but\ it's\ connection\ status\ is\ %s,\ can\ not\ # args: msg.getDefaultL3NetworkUuid(),msg.getL3NetworkUuids() defaultL3NetworkUuid[uuid\:%s]\ is\ not\ in\ l3NetworkUuids%s = defaultL3NetworkUuid[uuid:{0}] is not in l3NetworkUuids{1} -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:76 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:230 +# args: +there\ are\ more\ than\ one\ L3\ network\ specified\ in\ l3NetworkUuids,\ but\ defaultL3NetworkUuid\ is\ null = there are more than one L3 network specified in l3NetworkUuids, but defaultL3NetworkUuid is null + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:84 # args: msg.getHostUuid() -host[uuid\:%s]\ must\ be\ Enabled\ and\ Connected\ to\ be\ a\ conversion\ host = host[uuid:{0}] must be Enabled and Connected to be a conversion host +the\ status\ of\ host[uuid\:%s]\ must\ be\ Connected = the status of host[uuid:{0}] must be Connected -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:89 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:97 # args: v2v\ conversion\ host\ storage\ path\ must\ be\ absolute\ path = v2v conversion host storage path must be absolute path -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:112 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:120 # args: msg.getUrl() invalid\ v2v\ url\:\ %s = invalid v2v url: {0} -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:123 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:131 # args: srcVmUuid vm\ instance[uuid\:%s]\ does\ not\ exist\ or\ is\ not\ a\ vmware\ vm = vm instance[uuid:{0}] does not exist or is not a vmware vm -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:130 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:138 # args: conversionHostUuid\ should\ not\ be\ null = conversionHostUuid should not be null -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:136 -# args: msg.getConversionHostUuid() -conversion\ host[uuid\:%s]\ should\ be\ Enabled = conversion host[uuid:{0}] should be Enabled - # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:148 # args: msg.getConversionHostUuid() underlying\ host\ of\ conversion\ host[uuid\:%s]\ should\ be\ Connected = underlying host of conversion host[uuid:{0}] should be Connected @@ -8602,55 +13646,75 @@ primary\ storage[uuid\:%s]\ is\ not\ supported\ for\ v2v = primary storage[uuid: # args: msg.getPrimaryStorageUuid() primary\ storage[uuid\:%s]\ is\ neither\ Enabled\ nor\ Connected = primary storage[uuid:{0}] is neither Enabled nor Connected -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:577 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:302 +# args: msg.getVolumeUuid(),msg.getHostUuid() +there\ are\ some\ v2v\ jobs\ in\ progress.\ can\ not\ attach\ volume[%s]\ to\ host[%s] = there are some v2v jobs in progress. can not attach volume[{0}] to host[{1}] + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:313 +# args: msg.getVolumeUuid(),msg.getHostUuid() +there\ are\ some\ v2v\ jobs\ in\ progress.\ can\ not\ detach\ volume[%s]\ from\ host[%s] = there are some v2v jobs in progress. can not detach volume[{0}] from host[{1}] + +# at: src/main/java/org/zstack/v2v/V2VConversionHostCapacityUpdater.java:98 +# args: reserveSize,conversionHostVO.getUuid() +cannot\ reserve\ %s\ bytes\ on\ the\ conversion\ host[uuid\:%s],\ it's\ short\ of\ available\ capacity = cannot reserve {0} bytes on the conversion host[uuid:{1}], it's short of available capacity + +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:597 # args: l3Uuid Unable\ to\ find\ L3Network[uuid\:%s]\ to\ start\ the\ current\ vm,\ it\ may\ have\ been\ deleted,\ Operation\ suggestion\:\ delete\ this\ vm,\ recreate\ a\ new\ vm = Unable to find L3Network[uuid:{0}] to start the current vm, it may have been deleted, Operation suggestion: delete this vm, recreate a new vm -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1150 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1207 # args: bandwidth invalid\ network\ bandwidth[%s],\ it\ is\ not\ a\ number = invalid network bandwidth[{0}], it is not a number -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1145 -# args: bandwidth -invalid\ network\ bandwidth[%s],\ it\ must\ be\ greater\ than\ or\ equal\ to\ 8192 = invalid network bandwidth[{0}], it must be greater than or equal to 8192 - -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1147 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1204 # args: networkInboundBandwidth\ execeds\ the\ max\ value\ 32G\ bps = networkInboundBandwidth execeds the max value 32G bps -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:624 -# args: msg.getUrl() -can\ not\ find\ type\ for\ src\ vm[url\:%s] = can not find type for src vm[url:{0}] - -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:638 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:661 # args: msg.getUrl(),msg.getType() can\ not\ find\ factory\ for\ src\ vm[url\:%s,\ v2vType\:%s] = can not find factory for src vm[url:{0}, v2vType:{1}] -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:898 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:921 # args: msg.getHostUuid() there\ has\ been\ a\ v2v\ conversion\ host\ with\ hostUuid\ %s = there has been a v2v conversion host with hostUuid {0} -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1139 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1196 # args: invalid\ v2v\ qos\ systemtag = invalid v2v qos systemtag -# at: src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java:863 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1202 +# args: bandwidth +invalid\ network\ bandwidth[%s],\ it\ must\ be\ greater\ than\ or\ equal\ to\ 1048576 = invalid network bandwidth[{0}], it must be greater than or equal to 1048576 + +# at: src/main/java/org/zstack/v2v/V2VMsgTranslator.java:118 +# args: srcVmUrl +can\ not\ find\ type\ for\ src\ vm[url\:%s] = can not find type for src vm[url:{0}] + +# at: src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java:890 +# args: +missing\ VM\ uuid\ in\ 'srcVmUrl' = missing VM uuid in 'srcVmUrl' + +# at: src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java:956 # args: srcVmUuid No\ root\ volume\ found\ for\ VM\:\ %s = No root volume found for VM: {0} -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:189 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1575 +# args: cidr,hostUuid +there\ is\ no\ available\ ip\ found\ in\ cidr\ %s\ on\ host\ %s,\ try\ reconnect\ host\ to\ refresh\ ips = there is no available ip found in cidr {0} on host {1}, try reconnect host to refresh ips + +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:190 # args: job.getUuid() v2v\ job[uuid\:%s]\ is\ running = v2v job[uuid:{0}] is running -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:788 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:808 # args: srcVmUrl failed\ to\ get\ virt-v2v\ uri\ for\ %s = failed to get virt-v2v uri for {0} -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:953 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1007 # args: urlBuilder.toString() Failed\ to\ parse\ url\ %s = Failed to parse url {0} -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1231 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1288 # args: NOT_SUPPORTED_SPECIAL_CHARACTER Target\ vm\ name\ can\ not\ contain\ those\ characters\ %s = Target vm name can not contain those characters {0} @@ -8662,714 +13726,918 @@ There\ is\ already\ a\ long\ job[uuid\:%s]\ convert\ vm\ from\ %s = There is alr # args: Failed\ to\ update\ conversion\ host\ dependency = Failed to update conversion host dependency -# at: src/main/java/org/zstack/vmware/ESXHost.java:151 +# at: src/main/java/org/zstack/vmware/ESXHost.java:155 # args: host\ is\ not\ connected = host is not connected -# at: src/main/java/org/zstack/vmware/ESXHost.java:329 +# at: src/main/java/org/zstack/vmware/ESXHost.java:244 +# args: self.getvCenterUuid() +Syncing\ with\ VCenter[uuid\:%s],\ please\ try\ again\ later. = Syncing with VCenter[uuid:{0}], please try again later. + +# at: src/main/java/org/zstack/vmware/ESXHost.java:359 # args: vmUuid,self.getUuid() vmUuid\ [%s]\ not\ found\ in\ ESX\ host\ [%s] = vmUuid [{0}] not found in ESX host [{1}] -# at: src/main/java/org/zstack/vmware/ESXHost.java:673 +# at: src/main/java/org/zstack/vmware/ESXHost.java:709 # args: vmUuid VM\ not\ found\:\ %s = VM not found: {0} -# at: src/main/java/org/zstack/vmware/ESXHost.java:602 +# at: src/main/java/org/zstack/vmware/ESXHost.java:635 # args: vmUuid,VMwareHelper.exStr(ex) failed\ to\ suspend\ VM\ [%s]\:\ %s = failed to suspend VM [{0}]: {1} -# at: src/main/java/org/zstack/vmware/ESXHost.java:598 +# at: src/main/java/org/zstack/vmware/ESXHost.java:631 # args: t.getTaskInfo().getError().getLocalizedMessage() failed\ to\ suspend\ VM,\ task\ status\:\ %s = failed to suspend VM, task status: {0} -# at: src/main/java/org/zstack/vmware/ESXHost.java:636 +# at: src/main/java/org/zstack/vmware/ESXHost.java:670 # args: vmUuid,VMwareHelper.exStr(ex) failed\ to\ resume\ VM\ [%s]\:\ %s = failed to resume VM [{0}]: {1} -# at: src/main/java/org/zstack/vmware/ESXHost.java:632 +# at: src/main/java/org/zstack/vmware/ESXHost.java:666 # args: t.getTaskInfo().getError().getLocalizedMessage() failed\ to\ resume\ VM,\ task\ status\:\ %s = failed to resume VM, task status: {0} -# at: src/main/java/org/zstack/vmware/ESXHost.java:704 +# at: src/main/java/org/zstack/vmware/ESXHost.java:740 # args: vmUuid,VMwareHelper.exStr(ex) failed\ to\ shutdown\ guest\:\ %s,\ %s = failed to shutdown guest: {0}, {1} -# at: src/main/java/org/zstack/vmware/ESXHost.java:1314 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1370 # args: vmInv.getInstanceOfferingUuid() instance\ uuid\ [%s]\ not\ found = instance uuid [{0}] not found -# at: src/main/java/org/zstack/vmware/ESXHost.java:1324 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1380 # args: vmInv.getImageUuid() Image\ [%s]\ not\ found = Image [{0}] not found -# at: src/main/java/org/zstack/vmware/ESXHost.java:1423 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1479 # args: vmUuid VM\ [%s]\ not\ found\ in\ vCenter = VM [{0}] not found in vCenter -# at: src/main/java/org/zstack/vmware/ESXHost.java:1592 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1654 # args: t.getTaskInfo().getError().getLocalizedMessage() failed\ to\ power\ on\ VM,\ task\ status\:\ %s = failed to power on VM, task status: {0} -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:47 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:122 +# args: msg.getDriverType() +Nic\ driver\ %s\ not\ support\ yet = Nic driver {0} not support yet + +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:67 +# args: msg.getUuid(),vCenterVersion +console\ password\ is\ not\ supported\ by\ vm[uuid\:%s]\ on\ vCenter[version\:%s] = console password is not supported by vm[uuid:{0}] on vCenter[version:{1}] + +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:73 # args: vCenter\ login\ name\ expected. = vCenter login name expected. -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:51 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:77 # args: msg.getDomainName() domainName[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = domainName[{0}] is neither an IPv4 address nor a valid hostname -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:57 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:83 # args: msg.getDomainName() vCenter\ [domainName\:%s]\ has\ been\ added = vCenter [domainName:{0}] has been added -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:94 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:139 # args: clusterUuid,l2uuid Cluster[uuid\:%s]\ and\ L2[uuid\:%s]\ belongs\ to\ different\ DCs = Cluster[uuid:{0}] and L2[uuid:{1}] belongs to different DCs -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:106 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:151 # args: clusterUuid No\ hosts\ found\ within\ cluster\:\ %s = No hosts found within cluster: {0} -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:139 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:184 # args: phyinf,phyinf vSwitch/dvSwitch\ not\ found\:\ %s,\ or\ vSwitch\:\ %s\ on\ different\ ESX\ host\ doesn't\ has\ same\ portgroup = vSwitch/dvSwitch not found: {0}, or vSwitch: {1} on different ESX host doesn't has same portgroup -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:153 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:198 # args: l2uuid,vcvo.getUuid(),clusterUuid L2[uuid\:%s]\ doesn't\ belong\ to\ vCenter[uuid\:%s]\ cluster[uuid\:%s] = L2[uuid:{0}] doesn't belong to vCenter[uuid:{1}] cluster[uuid:{2}] -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:60 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:68 # args: bsUuid No\ data-store\ attached\ to\ %s = No data-store attached to {0} -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:65 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:73 # args: bsUuid Data-store\ not\ found\ for\ %s = Data-store not found for {0} -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:93 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:103 # args: url.getProtocol() unexpected\ protocol\:\ %s = unexpected protocol: {0} -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:99 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:109 # args: iinv.getName() %s\ already\ exists = {0} already exists -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:138 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:153 # args: vcenter\ backup\ storage\ do\ not\ support\ to\ cancel\ download\ image = vcenter backup storage do not support to cancel download image -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:188 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:203 # args: image\ not\ found\ in\ BS = image not found in BS -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:200 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:215 # args: not\ supported\ yet = not supported yet -# at: src/main/java/org/zstack/vmware/VCenterHostAllocatorFilterExtensionPoint.java:357 +# at: src/main/java/org/zstack/vmware/VCenterHostAllocatorFilterExtensionPoint.java:368 # args: no\ candidate\ host\ for\ vcenter\ vm = no candidate host for vcenter vm -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:1031 -# args: nNic.getMac(),nVm.getUuid(),nVm.getName(),eVM.getUuid(),eVM.getName(),VCENTER_MAC_CONFLICT_STRATEGY_STRICT -Duplicated\ mac\ address[%s]\ on\ VM[uuid\:\ %s,\ name\:\ %s]\ and\ VM[uuid\:\ %s,\ name\:\ %s],\ and\ current\ mac\ address\ conflicting\ strategy\ is\:\ %s. = Duplicated mac address[{0}] on VM[uuid: {1}, name: {2}] and VM[uuid: {3}, name: {4}], and current mac address conflicting strategy is: {5}. - -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:1804 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2040 # args: can't\ sync\ before\ datastores\ are\ separated = can't sync before datastores are separated -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2858 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3044 +# args: vcvo.getUuid() +There\ are\ tasks\ running\ on\ the\ VCenter[uuid\:%s],\ please\ try\ again\ later. = There are tasks running on the VCenter[uuid:{0}], please try again later. + +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3134 # args: msg.getVCenterUuid() VCenter[uuid\:%s]\ not\ found\:\ = VCenter[uuid:{0}] not found: -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2974 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3252 # args: Login\ failed,\ please\ check\ your\ login\ parameters. = Login failed, please check your login parameters. -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2978 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3256 # args: msg.getDomainName(),ex.getMessage() connect\ %s\ failed\:\ %s = connect {0} failed: {1} -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2984 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3262 # args: msg.getDomainName(),msg.getUsername() Login\ to\ vCenter\ [%s]\ failed\ with\ user\ [%s],please\ check\ your\ network\ connection\ and\ credential. = Login to vCenter [{0}] failed with user [{1}],please check your network connection and credential. -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2991 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3269 # args: msg.getDomainName(),msg.getPort() == null ? 443 : msg.getPort() Parse\ response\ failed\ from\ vCenter\ [%s],please\ check\ the\ port\ number[%d]. = Parse response failed from vCenter [{0}],please check the port number[{1}]. -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3070 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3277 +# args: msg.getDomainName() +SSL\ handshake\ failed\ with\ vCenter\ [%s],because\ insecure\ TLS\ 1.0\ is\ used.\ Manually\ enabled\ TLS\ 1.0\ in\ jdk\ configuration\ if\ needed. = SSL handshake failed with vCenter [{0}],because insecure TLS 1.0 is used. Manually enabled TLS 1.0 in jdk configuration if needed. + +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3283 +# args: msg.getDomainName(),msg.getPort() == null ? 443 : msg.getPort() +SSL\ handshake\ failed\ with\ vCenter\ [%s],please\ check\ the\ port\ number[%d]. = SSL handshake failed with vCenter [{0}],please check the port number[{1}]. + +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3359 # args: No\ clustered\ compute\ resource\ found = No clustered compute resource found -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3074 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3363 # args: No\ dvSwitch\ or\ qualified\ vSwitch\ found = No dvSwitch or qualified vSwitch found -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3255 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3546 # args: dsMorVal,vcUuid Datastore\ %s\ not\ found\ for\ vCenter\ %s = Datastore {0} not found for vCenter {1} -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3627 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3936 # args: -Missing\ host\ UUID\ in\ message = Missing host UUID in message +Missing\ host\ uuid\ in\ message = Missing host uuid in message -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3725 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4035 # args: Missing\ destination\ host\ uuid. = Missing destination host uuid. -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3730 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4040 # args: Destination\ host\ is\ not\ ESX\ host. = Destination host is not ESX host. -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3768 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4079 # args: vm.getConfig().getName(),hvo.getManagementIp() Checking\ compatibility\ with\ vm\ %s\ failed\ on\ host\ %s = Checking compatibility with vm {0} failed on host {1} -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3765 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4075 # args: HOST\ CPU/software\ NOT\ compatible = HOST CPU/software NOT compatible -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3993 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4137 # args: Can't\ detach\ nic\ because\ the\ nic\ not\ supported\ to\ hot\ plugin\ in\ vcenter = Can't detach nic because the nic not supported to hot plugin in vcenter -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:204 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:228 # args: No\ virtual\ disk\ manager = No virtual disk manager -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:211 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:235 # args: No\ file\ manager = No file manager -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:220 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:244 # args: No\ file\ Datacenter = No file Datacenter -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:324 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:350 # args: vm.getName() failed\ to\ get\ VM[%s]\ root\ disk\ usage = failed to get VM[{0}] root disk usage -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:320 -# args: msg.getInstallPath() +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:346 +# args: installPath failed\ to\ get\ VM\ from\ installPath\:\ %s = failed to get VM from installPath: {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:230 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:258 +# args: +VCenter\ not\ found = VCenter not found + +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:262 +# args: vcvo.getUuid(),vcvo.getStatus() +VCenter[%s]\ is\ not\ in\ operation\ status,\ current\ status\:\ %s = VCenter[{0}] is not in operation status, current status: {1} + +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:328 # args: vCenterUrl,ex.getMessage() failed\ to\ connect\ to\ vCenter\:\ %s\:\ %s = failed to connect to vCenter: {0}: {1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:362 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:460 # args: installPath vdisk\ not\ found\:\ %s = vdisk not found: {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:437 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:536 # args: getVcDomainName(si) list\ storage\ failed\ for\ %s = list storage failed for {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:457 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:556 # args: vm.getName() No\ datastore\ found\ for\ VM\:\ %s = No datastore found for VM: {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:511 -# args: info.getName(),info.getInstanceUuid() -failed\ to\ set\ ESX\ VM\ uuid\ [%s\:%s] = failed to set ESX VM uuid [{0}:{1}] +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:610 +# args: info.getName(),info.getInstanceUuid(),ex.getMessage() +failed\ to\ set\ ESX\ VM\ uuid\ [%s\:%s],\ because[%s] = failed to set ESX VM uuid [{0}:{1}], because[{2}] -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:592 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:709 # args: zsImageUuid template\ [%s]\ not\ found = template [{0}] not found -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:669 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:786 # args: host.getName() failed\ to\ search\ resource\ pool\ for\ host\ %s = failed to search resource pool for host {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:665 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:782 # args: host.getName() No\ resource\ pool\ found\ for\ host\ %s = No resource pool found for host {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2105 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2415 # args: installPath No\ unit\ number\ available\ for\ data\ disk\ %s = No unit number available for data disk {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1245 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1546 # args: vm.getName() guest\ tools\ not\ installed\ or\ running\ for\ VM\:\ %s = guest tools not installed or running for VM: {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1280 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1581 # args: vm.getName() upload\ file\ failed\ for\ VM\:\ %s = upload file failed for VM: {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1368 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1670 # args: vcvo.getName() list\ dvSwitch\ failed\ for\ %s = list dvSwitch failed for {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1630 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1936 # args: clusterUuid get\ vCenter\ cluster[%s]\ name\ failed = get vCenter cluster[{0}] name failed -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1739 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2045 # args: dvSwitch dvSwitch\ name\ [%s]\ not\ unique = dvSwitch name [{0}] not unique -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1797 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2103 # args: hvo.getName() create\ portgroup\ failed\ for\ host\ %s = create portgroup failed for host {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1794 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2100 # args: hvo.getName(),((OperationFailureException) ex).getErrorCode().getDetails() create\ portgroup\ failed\ for\ host\ %s\:\ because\ %s = create portgroup failed for host {0}: because {1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1761 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2067 # args: hvo.getName(),hvo.getUuid() Host[%s\:%s]\ not\ found\ on\ vCenter = Host[{0}:{1}] not found on vCenter -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1773 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2079 # args: pgLabel,hvo.getName(),vlanId portgroup[%s]\ already\ exists\ on\ host[%s]\ but\ with\ different\ vlanId(%d) = portgroup[{0}] already exists on host[{1}] but with different vlanId({2}) -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1833 -# args: hvo.getName() -portgroup[%s]\ already\ exists\ on\ host[%s],please\ create\ again\ with\ other\ name\ or\ delete\ portgroup\ manually\ and\ attach\ to\ cluster\ again = portgroup[%s] already exists on host[%s],please create again with other name or delete portgroup manually and attach to cluster again +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2083 +# args: pgLabel,hvo.getName() +portgroup[%s]\ already\ exists\ on\ host[%s],please\ create\ again\ with\ other\ name\ or\ delete\ portgroup\ manually\ and\ attach\ to\ cluster\ again = portgroup[{0}] already exists on host[{1}],please create again with other name or delete portgroup manually and attach to cluster again -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1836 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2142 # args: vcvo.getName() create\ dvPortGroup\ failed\ for\ %s = create dvPortGroup failed for {0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1831 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2137 # args: dvSwitchName,vcvo.getName() dvSwitch\ [%s]\ not\ found\ on\ vCenter\ [%s] = dvSwitch [{0}] not found on vCenter [{1}] -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2026 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2335 # args: ds.getName() no\ dataCenter\ found\ for\ datastore = no dataCenter found for datastore -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2031 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2340 # args: virtual\ disk\ manager\ unavailable = virtual disk manager unavailable -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2042 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2351 # args: installPath,mf.getLocalizedMessage() delete\ vdisk[%s]\ failed\:\ %s = delete vdisk[{0}] failed: {1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2171 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2481 # args: dvSwitch.getName(),task.getTaskInfo().getError().getLocalizedMessage() create\ dvPortGroup\ failed\ for\ dvSwitch\ [%s],\ %s = create dvPortGroup failed for dvSwitch [{0}], {1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2275 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2593 # args: me.getName(),mor.val,ex.getMessage() failed\ to\ set\ ZStack\ uuid\ to\ VCenter\ ManagedEntity\ [name\:%s,\ mor\:%s]\ because\ %s = failed to set ZStack uuid to VCenter ManagedEntity [name:{0}, mor:{1}] because {2} -# at: src/main/java/org/zstack/vmware/VncPortAllocatorImpl.java:162 +# at: src/main/java/org/zstack/vmware/VncPortAllocatorImpl.java:165 # args: No\ VNC\ ports\ available = No VNC ports available -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:225 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:450 +# args: msg.getDns() +dns[%s]\ is\ not\ a\ IP\ address = dns[{0}] is not a IP address + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:338 # args: l3NetworkVO.getUuid() no\ ip\ ranges\ attached\ with\ l3\ network[uuid\:%s] = no ip ranges attached with l3 network[uuid:{0}] -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:167 -# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vipPeerVOs.stream().map( n -> n.getVipUuid()).collect(Collectors.toList()) +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:178 +# args: +management\ network\ can\ not\ be\ detached = management network can not be detached + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:182 +# args: +default\ route\ network\ can\ not\ be\ detached = default route network can not be detached + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:186 +# args: +original\ public\ network\ can\ not\ be\ detached = original public network can not be detached + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:190 +# args: vpc.getUuid() +could\ not\ detach\ l3\ network\ to\ vpc\ router[uuid\:%s]\ because\ its\ state\ is\ not\ running\ or\ stopped = could not detach l3 network to vpc router[uuid:{0}] because its state is not running or stopped + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:198 +# args: vpc.getUuid() +could\ not\ detach\ l3\ network\ to\ vpc\ router[uuid\:%s]\ becaus\ the\ states\ of\ the\ master\ and\ slave\ are\ inconsistent = could not detach l3 network to vpc router[uuid:{0}] becaus the states of the master and slave are inconsistent + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:231 +# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vipPeerVOs.stream().map(VipPeerL3NetworkRefVO::getVipUuid).collect(Collectors.toList()) l3\ network[uuid\:%s]\ can\ not\ detach\ from\ vpc\ vrouter[uuid\:%s]\ since\ network\ services\ attached\ vips[%s]\ still\ used\ in\ l3 = l3 network[uuid:{0}] can not detach from vpc vrouter[uuid:{1}] since network services attached vips[{2}] still used in l3 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:183 -# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vmNicVOS.stream().map( n -> n.getUuid()).collect(Collectors.toList()) +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:247 +# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vmNicVOS.stream().map(ResourceVO::getUuid).collect(Collectors.toList()) vpc\ l3\ network[uuid\:%s]\ can\ not\ detach\ from\ vpc\ vrouter[uuid\:%s]\ since\ vm\ nics[%s]\ still\ used\ in\ l3 = vpc l3 network[uuid:{0}] can not detach from vpc vrouter[uuid:{1}] since vm nics[{2}] still used in l3 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:193 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:257 # args: msg.getVirtualRouterOfferingUuid() virtual\ router\ offering[uuid\:\ %s]\ is\ not\ enabled = virtual router offering[uuid: {0}] is not enabled -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:218 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:284 # args: only\ vpc\ l3\ network\ can\ attach\ to\ vpc\ vrouter = only vpc l3 network can attach to vpc vrouter -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:249 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:292 +# args: msg.getL3NetworkUuid(),vmNics.get(0).getVmInstanceUuid() +Vpc\ network\ [uuid\:%s]\ already\ attached\ to\ vpc\ router\ [uuid\:%s] = Vpc network [uuid:{0}] already attached to vpc router [uuid:{1}] + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:329 +# args: msg.getVmInstanceUuid() +could\ not\ attached\ l3\ network\ to\ vpc\ router[uuid\:%s]\ because\ both\ its\ state\ and\ it\ peer\ state\ is\ not\ running\ or\ stopped = could not attached l3 network to vpc router[uuid:{0}] because both its state and it peer state is not running or stopped + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:312 +# args: msg.getVmInstanceUuid() +could\ not\ attached\ l3\ network\ to\ vpc\ router[uuid\:%s]\ because\ its\ state\ is\ not\ running\ or\ stopped = could not attached l3 network to vpc router[uuid:{0}] because its state is not running or stopped + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:362 # args: vip.getL3NetworkUuid(),vip.getUuid(),vip.getIp(),msg.getL3NetworkUuid(),vmInstanceVO.getUuid() public\ network[uuid\:\ %s]\ vip[uuid\:\ %s,\ ip\:\ %s]\ peer\ with\ l3network[uuid\:\ %s]\ not\ on\ vpc\ vr[uuid\:\ %s] = public network[uuid: {0}] vip[uuid: {1}, ip: {2}] peer with l3network[uuid: {3}] not on vpc vr[uuid: {4}] -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:261 -# args: gateway,msg.getL3NetworkUuid() +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:383 +# args: gateways,msg.getL3NetworkUuid() the\ gateway[ip\:%s]\ of\ l3[uuid\:%s]\ has\ been\ occupied = the gateway[ip:{0}] of l3[uuid:{1}] has been occupied -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:272 -# args: msg.getStaticIp(),gateway,l3NetworkVO.getUuid() -the\ static\ ip[%s]\ specified\ in\ message\ not\ equals\ to\ gateway\ ip[%s]\ of\ l3\ network[uuid\:%s] = the static ip[{0}] specified in message not equals to gateway ip[{1}] of l3 network[uuid:{2}] +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:428 +# args: msg.getStaticIp(),gateways,l3NetworkVO.getUuid() +the\ static\ ip[%s]\ specified\ in\ message\ not\ equals\ to\ gateway\ ips[%s]\ of\ l3\ network[uuid\:%s] = the static ip[{0}] specified in message not equals to gateway ips[{1}] of l3 network[uuid:{2}] -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:284 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:440 # args: vipL3Uuid l3\ network\ [uuid\:%s]\ must\ be\ attached\ first,\ because\ there\ is\ vip\ on\ that\ l3\ network = l3 network [uuid:{0}] must be attached first, because there is vip on that l3 network -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:335 -# args: msg.getDns() -dns[%s]\ is\ not\ a\ IP\ address = dns[{0}] is not a IP address - -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:296 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:457 # args: msg.getDns(),msg.getUuid() dns\ address\ [%s]\ is\ not\ added\ to\ vpc\ router\ [uuid\:%s] = dns address [{0}] is not added to vpc router [uuid:{1}] -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1056 -# args: -chrony\ server\ not\ configured! = chrony server not configured! +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:488 +# args: ipr.getL3NetworkUuid(),ipRangeVO.getNetworkCidr(),uuid +could\ not\ add\ ipv6\ range\ to\ l3\ network[uuid\:%s],\ because\ it's\ overlap\ with\ cidr\ [%s]\ of\ vRouter\ [uuid\:%s] = could not add ipv6 range to l3 network[uuid:{0}], because it's overlap with cidr [{1}] of vRouter [uuid:{2}] + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:483 +# args: ipr.getL3NetworkUuid(),ipRangeVO.getNetworkCidr(),uuid +could\ not\ add\ ip\ range\ to\ l3\ network[uuid\:%s],\ because\ it's\ overlap\ with\ cidr\ [%s]\ of\ vRouter\ [uuid\:%s] = could not add ip range to l3 network[uuid:{0}], because it's overlap with cidr [{1}] of vRouter [uuid:{2}] + +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:859 +# args: rsp.getError() +operation\ error,\ because\:%s = operation error, because:{0} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:314 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:558 # args: msg.getUuid() can\ not\ get\ connections\ of\ distributed\ routing\ to\ virtual\ router\ %s = can not get connections of distributed routing to virtual router {0} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:351 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:596 # args: vrinv.getUuid() can\ not\ set\ state\ of\ distributed\ routing\ to\ virtual\ router\ %s = can not set state of distributed routing to virtual router {0} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:595 -# args: vrinv.getUuid() -can\ not\ get\ state\ of\ distributed\ routing\ to\ virtual\ router\ %s = can not get state of distributed routing to virtual router {0} - -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:469 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:720 # args: msg.getNetworkService(),msg.getUuid() not\ support\ to\ get\ the\ service\ %s\ state\ to\ virtual\ router\ %s = not support to get the service {0} state to virtual router {1} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:613 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:855 +# args: vrinv.getUuid() +can\ not\ get\ state\ of\ distributed\ routing\ to\ virtual\ router\ %s = can not get state of distributed routing to virtual router {0} + +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:934 # args: msg.getNetworkService(),msg.getUuid() not\ support\ to\ update\ the\ service\ %s\ state\ to\ virtual\ router\ %s = not support to update the service {0} state to virtual router {1} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1004 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1336 # args: vpc\ l3\ network\ must\ attach\ a\ vpc\ vrouter\ first\ before\ do\ anything\ related\ to\ vrouter(like\ start/stop\ vm,\ create\ lb,\ etc.) = vpc l3 network must attach a vpc vrouter first before do anything related to vrouter(like start/stop vm, create lb, etc.) -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1281 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1594 # args: msg.getDns(),msg.getVpcRouterUuid() dns\ address\ [%s]\ has\ bean\ added\ to\ vpc\ router\ [uuid\:%s] = dns address [{0}] has bean added to vpc router [uuid:{1}] -# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:161 -# args: vpc.getUuid() +# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:166 +# args: vpcUuid can\ not\ detach\ nic\ from\ vpc\ vr[uuid\:%s] = can not detach nic from vpc vr[uuid:{0}] -# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:289 -# args: ipRange.getUuid() -can\ not\ detach\ nic\ from\ vpc\ during\ delete\ ip\ range[uuid\:%s] = can not detach nic from vpc during delete ip range[uuid:{0}] +# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:473 +# args: l3.getUuid() +there\ is\ no\ ip\ range\ for\ l3\ network[uuid\:%s] = there is no ip range for l3 network[uuid:{0}] -# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:342 -# args: gateway,l3.getUuid(),vm.getUuid() +# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:501 +# args: ip.getGateway(),l3.getUuid(),vm.getUuid() the\ gateway[ip\:%s]\ of\ l3[uuid\:%s]\ has\ been\ occupied\ on\ vpc\ vr[uuid\:\ %s] = the gateway[ip:{0}] of l3[uuid:{1}] has been occupied on vpc vr[uuid: {2}] -# at: src/main/java/org/zstack/vpc/VpcVyosDeployZsnAgentFlow.java:130 +# at: src/main/java/org/zstack/vpc/VpcVyosDeployZsnAgentFlow.java:133 # args: mgmtNicIp -unable\ to\ ssh\ in\ to\ the\ vyos[%s],\ the\ ssh\ port\ seems\ not\ open = unable to ssh in to the vyos[{0}], the ssh port seems not open +unable\ to\ ssh\ in\ to\ the\ vpc\ router[%s],\ the\ ssh\ port\ seems\ not\ open = unable to ssh in to the vpc router[{0}], the ssh port seems not open -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:164 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:217 # args: msg.getVmInstanceUuid() there\ is\ no\ master\ router\ of\ router\ [uuid\:%s] = there is no master router of router [uuid:{0}] -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:115 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:130 +# args: msg.getVirtualRouterUuid() +Could\ not\ update\ this\ network\ service,\ due\ to\ vpc\ [uuid\:%s]\ is\ not\ support\ update\ network\ service\ version = Could not update this network service, due to vpc [uuid:{0}] is not support update network service version + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:137 +# args: msg.getVirtualRouterUuid(),vo.getKernelVersion() +Could\ not\ update\ this\ network\ service,\ due\ to\ vpc\ [uuid\:%s]\ used\ old\ kernel\ version\:[%s] = Could not update this network service, due to vpc [uuid:{0}] used old kernel version:[{1}] + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:144 +# args: +Could\ not\ apply\ snat\ with\ non-default\ public\ network,\ due\ to\ multi\ snat\ feature\ is\ disabled = Could not apply snat with non-default public network, due to multi snat feature is disabled + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:147 +# args: msg.getL3NetworkUuid() +Could\ not\ apply\ snat\ with\ this\ L3Network,\ due\ to\ l3\ network\ [uuid\:%s]\ is\ not\ public\ network = Could not apply snat with this L3Network, due to l3 network [uuid:{0}] is not public network + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:150 +# args: msg.getL3NetworkUuid() +Could\ not\ apply\ snat\ with\ this\ L3Network,\ due\ to\ l3\ network\ [uuid\:%s]\ is\ not\ attached\ to\ vpc\ router = Could not apply snat with this L3Network, due to l3 network [uuid:{0}] is not attached to vpc router + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:168 # args: ip invalid\ monitor\ ip\ address\ [%s] = invalid monitor ip address [{0}] -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:152 -# args: vpcHaUuid +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:205 +# args: vpcVo.getUuid() vpcHaRouter\ [uuid\:%s]\ is\ deleted = vpcHaRouter [uuid:{0}] is deleted -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:182 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:235 # args: haUuid there\ are\ more\ than\ 2\ vpc\ routers\ attached\ to\ haGroup\ [uuid\:%s] = there are more than 2 vpc routers attached to haGroup [uuid:{0}] -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:211 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:266 # args: l3Uuids,offeringL3Uuids ha\ group\ management\ l3\ and\ public\ l3\ networks[uuid\:%s]\ are\ different\ from\ offering\ l3\ networks\ [uuid\:%s] = ha group management l3 and public l3 networks[uuid:{0}] are different from offering l3 networks [uuid:{1}] -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:267 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:322 # args: vpcL3Uuids,vpcHaGroupL3Uuids vpc\ router\ l3\ networks\ [uuid\:%s]\ are\ different\ from\ ha\ group\ l3\ networks\ [uuid\:%s],\ !!!\ please\ delete\ this\ router\ and\ recreate\ it = vpc router l3 networks [uuid:{0}] are different from ha group l3 networks [uuid:{1}], !!! please delete this router and recreate it -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:275 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:330 # args: oldHaUuid vpc\ router\ has\ been\ attached\ to\ ha\ group\ [uuid\:%s] = vpc router has been attached to ha group [uuid:{0}] -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:279 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:334 # args: haUuid vpc\ ha\ group\ [uuid\:%s]\ is\ not\ existed = vpc ha group [uuid:{0}] is not existed -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:283 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:339 # args: haUuid there\ are\ more\ than\ 1\ vpc\ routers\ attached\ to\ haGroup\ [uuid\:%s] = there are more than 1 vpc routers attached to haGroup [uuid:{0}] -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:288 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:344 # args: haUuid vpc\ router\ [uuid\:%s]\ can\ not\ be\ upgraded\ to\ ha\ router\ because\ it\ public\ network\ is\ same\ to\ management\ network = vpc router [uuid:{0}] can not be upgraded to ha router because it public network is same to management network -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java:571 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java:611 # args: ha.getName() create\ affinityGroup\ for\ ha\ group\ [uuid\:%s]\ failed = create affinityGroup for ha group [uuid:{0}] failed -# at: src/main/java/org/zstack/vpc/ha/vyos/vyosVpcHaRouterBackendManagerImpl.java:137 -# args: vrUuid,ret.getError() -failed\ to\ enable\ ha\ on\ virtual\ router[uuid\:%s],\ %s = failed to enable ha on virtual router[uuid:{0}], {1} +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java:785 +# args: vrName,vrUuid,vpcHaGroupName,vpcHaGroupUuid,old,status +virtualrouter\ %s\ [uuid\:\ %s\ ]\ of\ VPC\ HA\ group\ %s\ [uuid\:\ %s]\ haStatus\ changed\ from\ %s\ to\ %s = virtualrouter {0} [uuid: {1} ] of VPC HA group {2} [uuid: {3}] haStatus changed from {4} to {5} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:291 -# args: ips -operation\ failure,\ ip\ format\ only\ supports\ ipv4/iprange/cidr,\ but\ find\ %s = operation failure, ip format only supports ipv4/iprange/cidr, but find {0} +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupVpcVrImpl.java:694 +# args: +ha\ group\ uuid\ nil = ha group uuid nil -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:317 -# args: protocol -illegal\ protocol\ type\ %s = illegal protocol type {0} +# at: src/main/java/org/zstack/vpc/ha/vpcHaGc/VpcHaGcManagerImpl.java:85 +# args: struct.getVmInstanceUuid() +VR[uuid\:\ %s]\ not\ running = VR[uuid: {0}] not running -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:342 -# args: msg.getRuleSetUuid(),msg.getRuleNumber() -RuleSet[%s]\ already\ has\ a\ rule\ with\ rule\ number\ %s. = RuleSet[{0}] already has a rule with rule number {1}. +# at: src/main/java/org/zstack/vpc/ha/vpcHaGc/VpcHaGcManagerImpl.java:90 +# args: struct.getVmInstanceUuid() +VR[uuid\:\ %s]\ not\ connected = VR[uuid: {0}] not connected + +# at: src/main/java/org/zstack/vpc/ha/vyos/vyosVpcHaRouterBackendManagerImpl.java:140 +# args: vrUuid,ret.getError() +failed\ to\ enable\ ha\ on\ virtual\ router[uuid\:%s],\ %s = failed to enable ha on virtual router[uuid:{0}], {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:372 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:373 # args: only\ tcp\ or\ udp\ protocol\ can\ use\ port = only tcp or udp protocol can use port -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:88 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:150 +# args: msg.getUuid() +can\ not\ delete\ ruleSet[%s]\ because\ it\ still\ attached\ to\ nic = can not delete ruleSet[{0}] because it still attached to nic + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:129 # args: can\ not\ detach\ system\ default\ ruleSet = can not detach system default ruleSet -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:110 -# args: msg.getUuid() -can\ not\ delete\ ruleSet[%s]\ because\ it\ still\ attached\ to\ nic = can not delete ruleSet[{0}] because it still attached to nic +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:142 +# args: +only\ system\ ruleSet\ can\ change\ action\ type = only system ruleSet can change action type -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:114 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:154 # args: can\ not\ delete\ system\ default\ ruleSet = can not delete system default ruleSet -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:125 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:160 # args: can\ not\ delete\ system\ default\ rule = can not delete system default rule -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:150 -# args: msg.getVpcUuid() -VPC\ Router[uuid\:%s]\ already\ has\ a\ firewall. = VPC Router[uuid:{0}] already has a firewall. +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:170 +# args: vRouteUuid +the\ router\ [uuid\:%s]\ does\ not\ has\ a\ master\ router = the router [uuid:{0}] does not has a master router -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:157 -# args: msg.getUuid() -can\ not\ update\ default\ rule[%s] = can not update default rule[{0}] +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:188 +# args: msg.getVpcUuid() +the\ VPC\ Router[uuid\:%s]\ already\ has\ a\ firewall. = the VPC Router[uuid:{0}] already has a firewall. -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:377 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:378 # args: only\ tcp\ protocol\ can\ use\ tcp\ flag = only tcp protocol can use tcp flag -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:381 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:382 # args: only\ icmp\ protocol\ can\ use\ icmp\ type = only icmp protocol can use icmp type -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:221 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:239 +# args: msg.getName(),msg.getRuleNumber() +already\ has\ a\ rule\ template\ with\ name\ %s = already has a rule template with name {0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:338 +# args: msg.getRuleSetUuid(),msg.getRuleNumber() +the\ ruleSet[%s]\ already\ has\ a\ rule\ with\ rule\ number\ %s. = the ruleSet[{0}] already has a rule with rule number {1}. + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:343 # args: msg.getUuid() -Rule\ [%s]\ not\ support\ update\ state = Rule [{0}] not support update state +can\ not\ update\ default\ rule[%s] = can not update default rule[{0}] -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:227 -# args: -Default\ ruleSet\ can\ not\ be\ attached\ to\ other\ nic = Default ruleSet can not be attached to other nic +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:407 +# args: msg.getUuid() +the\ rule\ [%s]\ number\ is\ invalid = the rule [{0}] number is invalid -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:231 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:416 # args: -Only\ out\ direction\ support\ attach\ ruleSet = Only out direction support attach ruleSet +can\ not\ attach\ the\ default\ ruleSet\ to\ other\ nic = can not attach the default ruleSet to other nic -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:239 -# args: msg.getL3Uuid(),msg.getForward() -L3[%s]\ forward[%s]\ already\ attached\ a\ ruleSet = L3[{0}] forward[{1}] already attached a ruleSet +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:431 +# args: msg.getRuleSetUuid(),msg.getL3Uuid() +ruleSet[%s]\ already\ has\ a\ l3[%s] = ruleSet[{0}] already has a l3[{1}] -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:302 -# args: e.getMessage() -Invalid\ rule\ expression,\ the\ detail\:\ %s = Invalid rule expression, the detail: {0} +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:450 +# args: duplicateRuleNumbers +already\ has\ a\ rule\ with\ the\ number[%s] = already has a rule with the number[{0}] -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:284 -# args: ips -operation\ failure,\ duplicate/overlap\ ip\ entry\ in\ %s = operation failure, duplicate/overlap ip entry in {0} +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:748 +# args: msg.getRuleSetUuid(),msg.getRuleNumber() +the\ ruleSet[%s]\ already\ has\ a\ rule\ with\ the\ rule\ number\ %s. = the ruleSet[{0}] already has a rule with the rule number {1}. -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:295 -# args: startIp,endIp,NetworkUtils.longToIpv4String(r.lowerEndpoint()),NetworkUtils.longToIpv4String(r.upperEndpoint()) -operation\ failure,\ there\ are\ overlap\ ip\ range[start\ ip\:%s,\ end\ ip\:\ %s\ and\ start\ ip\:%s,\ end\ ip\:\ %s] = operation failure, there are overlap ip range[start ip:{0}, end ip: {1} and start ip:{2}, end ip: {3}] +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:779 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ only\ tcp\ or\ udp\ protocol\ can\ use\ port = could not add firewall rule[{0}] only tcp or udp protocol can use port -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:309 -# args: port -operation\ failure,\ port\ format\ only\ supports\ port/portRange,\ but\ find\ %s = operation failure, port format only supports port/portRange, but find {0} +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:785 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ only\ tcp\ protocol\ can\ use\ tcp\ flag = could not add firewall rule[{0}] only tcp protocol can use tcp flag -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:331 -# args: state -protocol\ state\ only\ support\ new/established/invalid/related,but\ found\ %s = protocol state only support new/established/invalid/related,but found {0} +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:790 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ because\ only\ icmp\ protocol\ can\ use\ icmp\ type = could not add firewall rule[{0}] because only icmp protocol can use icmp type + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:801 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ because\ only\ tcp\ or\ udp\ protocol\ can\ use\ port = could not add firewall rule[{0}] because only tcp or udp protocol can use port + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:824 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ because\ only\ tcp\ protocol\ can\ use\ tcp\ flag = could not add firewall rule[{0}] because only tcp protocol can use tcp flag + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:832 +# args: msg.getRuleNumber(),error +could\ not\ add\ firewall\ rule[%d]\ because\ %s = could not add firewall rule[{0}] because {1} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:846 +# args: vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ ruleNo\ %d\ is\ invalid = could not add firewall rule, because ruleNo {0} is invalid + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:853 +# args: vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ there\ is\ no\ action\ for\ ruleNo\:%d = could not add firewall rule, because there is no action for ruleNo:{0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:867 +# args: vo.getSourceIp(),vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ source\ IP\ length\:\ %s\ is\ not\ valid\ for\ ruleNo\:%d = could not add firewall rule, because source IP length: {0} is not valid for ruleNo:{1} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:874 +# args: vo.getDestIp(),vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ destination\ IP\ length\:\ %s\ is\ not\ valid\ for\ ruleNo\:%d = could not add firewall rule, because destination IP length: {0} is not valid for ruleNo:{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:290 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:885 +# args: vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ there\ is\ no\ state\ for\ ruleNo\:%d = could not add firewall rule, because there is no state for ruleNo:{0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:892 +# args: vo.getDestIp(),vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ description\ length\ %s\ is\ not\ valid\ for\ ruleNo\:%d = could not add firewall rule, because description length {0} is not valid for ruleNo:{1} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:942 +# args: +the\ configuration\ file\ has\ format\ error = the configuration file has format error + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:948 +# args: errorInfo +the\ firewall\ rules\ in\ the\ configuration\ file\ have\ syntax\ errors\:\ %s = the firewall rules in the configuration file have syntax errors: {0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:272 # args: rsp.getError() sync\ firewall\ config\ failed,because\ %s = sync firewall config failed,because {0} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:441 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:459 # args: rsp.getError() update\ firewall\ ruleSet\ action\ failed,\ because\ %s = update firewall ruleSet action failed, because {0} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:516 -# args: cmd.getRule().getRuleNumber(),rsp.getError() +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:492 +# args: l3Uuid,vRouterUuid +Can\ not\ find\ l3[%]\ related\ mac\ on\ vRouter[%s] = Can not find l3[%] related mac on vRouter[{0}] + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:557 +# args: cmd.getRef().getRuleSetInfo().getRules().get(0).getRuleNumber(),rsp.getError() create\ firewall\ rule[%s]\ failed,\ because\ %s = create firewall rule[{0}] failed, because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:591 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:645 # args: vRouterUuid,re.getError().getCause() delete\ firewall\ on\ vRouter[%s],because\ %s = delete firewall on vRouter[{0}],because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:664 -# args: cmd.getRuleSet().getName(),re.getError().getCause() -create\ firewall\ ruleSet[%s]\ failed,\ because\ %s = create firewall ruleSet[{0}] failed, because {1} - -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:744 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:851 # args: vRouterUuid,rsp.getError() delete\ firewall\ rule\ failed\ on\ vRouter[%s],\ because\ %s = delete firewall rule failed on vRouter[{0}], because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:822 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:784 +# args: cmd.getRuleSet().getName(),re.getError().getCause() +create\ firewall\ ruleSet[%s]\ failed,\ because\ %s = create firewall ruleSet[{0}] failed, because {1} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:936 # args: vRouterUuid,rsp.getError() change\ firewall\ rule\ state\ on\ vRouter[%s]\ failed,\ because\ %s = change firewall rule state on vRouter[{0}] failed, because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:996 -# args: struct.getL3Uuid(),vRouterUuid -Can\ not\ find\ l3[%]\ related\ mac\ on\ vRouter[%s] = Can not find l3[%] related mac on vRouter[{0}] - -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:921 -# args: cmd.getRef().getRuleSetName(),re.getError() +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1032 +# args: struct.getRuleSetUuid(),re.getError() attach\ firewall\ ruleSet[%s]\ failed,\ because\ %s = attach firewall ruleSet[{0}] failed, because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:956 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1063 # args: detach\ ruleSet\ failed,\ maybe\ it\ has\ been\ deleted = detach ruleSet failed, maybe it has been deleted -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1024 -# args: cmd.getRef().getRuleSetName(),re.getError().getCause() +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1129 +# args: struct.getRuleSetUuid(),re.getError().getCause() detach\ firewall\ ruleSet[%s]\ failed,because\ %s = detach firewall ruleSet[{0}] failed,because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1102 -# args: cmd.getRuleSetName(),re.getError().getCause() -delete\ firewall\ ruleSet[%s]\ failed,because\ %s = delete firewall ruleSet[{0}] failed,because {1} +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:114 +# args: msg.getVpcFirewallUuid() +cannot\ find\ vpcFirewall[uuid\:%s]\ related\ vRouter = cannot find vpcFirewall[uuid:{0}] related vRouter + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:109 +# args: msg.getVpcFirewallUuid() +cannot\ find\ vpcFirewall[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find vpcFirewall[uuid:{0}], it may have been deleted + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:125 +# args: msg.getRuleSetUuid() +cannot\ find\ vpcFirewallRuleSet[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find vpcFirewallRuleSet[uuid:{0}], it may have been deleted + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:301 +# args: msg.getUuid() +cannot\ find\ vpcFirewallIpSetTemplate[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find vpcFirewallIpSetTemplate[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBase.java:129 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:396 # args: msg.getRuleSetUuid(),msg.getL3Uuid(),errorCode.getCause() attach\ firewall\ ruleSet[%s]\ to\ l3[%s]\ failed,because\ %s = attach firewall ruleSet[{0}] to l3[{1}] failed,because {2} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBase.java:156 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:424 # args: msg.getL3Uuid(),errorCode.getCause() detach\ firewall\ ruleSet\ from\ l3[%s]\ failed,because\ %s = detach firewall ruleSet from l3[{0}] failed,because {1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:83 -# args: msg.getVpcFirewallUuid() -cannot\ find\ vpcFirewall[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find vpcFirewall[uuid:{0}], it may have been deleted +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:475 +# args: duplicateRuleNumber.get(),ref.getVpcFirewallUuid(),ref.getL3NetworkUuid(),ref.getPacketsForwardType() +find\ duplicate\ rule\ numbers\ %s\ on\ firewall[%s],l3[%s],forward[%s] = find duplicate rule numbers {0} on firewall[{1}],l3[{2}],forward[{3}] -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:104 -# args: vo.getVpcFirewallUuid() -cannot\ find\ vpcFirewall[uuid\:%s]\ related\ vRouter = cannot find vpcFirewall[uuid:{0}] related vRouter +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:483 +# args: self.getUuid() +no\ changes\ in\ ruleset\ %s = no changes in ruleset {0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:515 +# args: firewall.get() +firewall\ %s\ related\ vpc\ not\ in\ running\ state = firewall {0} related vpc not in running state -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:99 -# args: msg.getVpcFirewallRuleUuid() -cannot\ find\ vpcFirewallRule[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find vpcFirewallRule[uuid:{0}], it may have been deleted +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:753 +# args: self.getUuid(),refVOs.size() +default\ ruleset\ %s\ can\ only\ attached\ to\ one\ interface\ forward,\ but\ find\ %s\ related\ interface = default ruleset {0} can only attached to one interface forward, but find {1} related interface -# at: src/main/java/org/zstack/vrouterRoute/VRouterRouteManagerImpl.java:466 +# at: src/main/java/org/zstack/vrouterRoute/VRouterRouteApiInterceptor.java:115 +# args: msg.getDestination() +destination[%s]\ can\ not\ has\ blackHole\ route\ and\ static\ route\ at\ same\ time = destination[{0}] can not has blackHole route and static route at same time + +# at: src/main/java/org/zstack/vrouterRoute/VRouterRouteManagerImpl.java:469 # args: msg.getUuid() cannot\ find\ the\ route\ table\ [uuid\:%s] = cannot find the route table [uuid:{0}] +# at: src/main/java/org/zstack/xdragon/XDragonFilterExtensionPoint.java:30 +# args: +xdragon\ host\ not\ support\ create\ vm\ using\ an\ iso\ image. = xdragon host not support create vm using an iso image. + # at: src/main/java/org/zstack/xdragon/XDragonHostFactory.java:34 # args: msg.getClusterUuid(),XDragonConstant.HYPERVISOR_TYPE cluster[uuid\:%s]\ hypervisorType\ is\ not\ %s = cluster[uuid:{0}] hypervisorType is not {1} -# at: src/main/java/org/zstack/xdragon/XDragonFilterExtensionPoint.java:30 -# args: -xdragon\ host\ not\ support\ create\ vm\ using\ an\ iso\ image. = xdragon host not support create vm using an iso image. - # at: src/main/java/org/zstack/yunshan/util/YunshanClient.java:46 # args: the\ url\ is\ null,\ please\ config\ the\ YunShan\ NSP. = the url is null, please config the YunShan NSP. -# at: src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java:13 +# at: src/main/java/org/zstack/zbox/ZBoxApiInterceptor.java:55 +# args: msg.getUsbDeviceUuid(),inventory.getVmInstanceUuid() +usb\ device[uuid\:%s]\ has\ been\ attached\ VM[uuid\:%s],\ cannot\ be\ add\ to\ zbox = usb device[uuid:{0}] has been attached VM[uuid:{1}], cannot be add to zbox + +# at: src/main/java/org/zstack/zbox/ZBoxApiInterceptor.java:72 +# args: zbox.getName(),zbox.getStatus() +zbox[name\:%s]\ status\ is\ not\ Ready,\ current\ status\ is\ %s = zbox[name:{0}] status is not Ready, current status is {1} + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:122 +# args: msg.getZBoxUuid() +zbox[uuid\:%s]\ is\ still\ in\ use,\ cannot\ eject\ it = zbox[uuid:{0}] is still in use, cannot eject it + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:151 +# args: msg.getZBoxUuid() +zbox[uuid\:%s]\ is\ not\ Ready,\ cannot\ sync\ capacity. = zbox[uuid:{0}] is not Ready, cannot sync capacity. + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:219 +# args: self.getMountPath(),msg.getInstallPath() +only\ file\ on\ zbox[mountPath\:%s]\ can\ be\ deleted.\ but\ pass\ [%s] = only file on zbox[mountPath:{0}] can be deleted. but pass [{1}] + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:285 +# args: self.getName(),self.getStatus() +zbox[name\:%s]\ state\ is\ not\ Ready,\ current\ state\ is\ %s = zbox[name:{0}] state is not Ready, current state is {1} + +# at: src/main/java/org/zstack/zbox/ZBoxFactory.java:57 +# args: zbox.getUuid() +zbox[uuid\:\ %s]\ seems\ like\ removed = zbox[uuid: {0}] seems like removed + +# at: src/main/java/org/zstack/zql/ast/parser/visitors/ValueVisitor.java:140 +# args: apiStr +output\ from\ [%s]\ is\ empty = output from [{0}] is empty + +# at: src/main/java/org/zstack/zql/ast/parser/visitors/ValueVisitor.java:159 +# args: apiName,JSONObjectUtil.toJsonString(ob) +call\ action[%s]\ failed,\ cause\:\ %s = call action[{0}] failed, cause: {1} + +# at: src/main/java/org/zstack/zql/ast/visitors/OrderByExprVistor.java:14 # args: node.getDirection() invalid\ order\ by\ clause,\ expect\ direction[asc,desc]\ but\ got\ %s = invalid order by clause, expect direction[asc,desc] but got {0} -# at: src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java:19 -# args: m.simpleInventoryName(),node.getField() +# at: src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java:22 +# args: m.simpleInventoryName(),f invalid\ order\ by\ clause,\ inventory[%s]\ doesn't\ have\ field[%s] = invalid order by clause, inventory[{0}] doesn't have field[{1}] # at: src/main/java/org/zstack/zql/ast/visitors/plugin/SumPlugin.java:31 # args: the\ field\ to\ sum\ must\ be\ specified = the field to sum must be specified -# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:125 -# args: clz.getName() -resource[%s]\ doesn't\ support\ zwatch\ return\ with\ clause = resource[{0}] doesn't support zwatch return with clause +# at: src/main/java/org/zstack/zsv/ZsvManagerImpl.java:95 +# args: volume.getUuid(),volume.getLastVmInstanceUuid() +volume\ %s\ still\ have\ snapshot\ group\ on\ vm\ %s,\ cannot\ attach\ to\ other\ vm = volume {0} still have snapshot group on vm {1}, cannot attach to other vm + +# at: src/main/java/org/zstack/zsv/ZsvManagerImpl.java:127 +# args: volume.getUuid() +volume\ %s\ still\ have\ snapshot\ group,\ cannot\ delete\ it = volume {0} still have snapshot group, cannot delete it -# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:270 +# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:241 # args: paramName,normalizedExpr unknown\ parameter[%s]\ in\ zwatch\ return\ with\ clause,\ %s = unknown parameter[{0}] in zwatch return with clause, {1} -# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:279 +# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:250 # args: expr,e.getMessage() invalid\ zwatch\ return\ with\ clause\:\ %s,\ %s = invalid zwatch return with clause: {0}, {1} -# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:571 -# args: eventData.getDataUuid(),t.getMessage() -update\ eventData[dataUuid\=%s]\ failed,\ %s = update eventData[dataUuid={0}] failed, {1} - -# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:694 -# args: alarmData.getDataUuid(),t.getMessage() -update\ alarmData[dataUuid\=%s]\ failed,\ %s = update alarmData[dataUuid={0}] failed, {1} - -# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:705 +# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:1188 # args: Some\ messages\ have\ expired.\ The\ expired\ messages\ are\ not\ allowed\ to\ be\ modified.\ The\ system\ will\ automatically\ clean\ up\ the\ expired\ messages.\ Please\ operate\ later = Some messages have expired. The expired messages are not allowed to be modified. The system will automatically clean up the expired messages. Please operate later -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:83 -# args: msg.getActionUuid(),msg.getSubscriptionUuid() -the\ action[uuid\:%s]\ already\ attached\ to\ the\ event\ subscription[uuid\:%s] = the action[uuid:{0}] already attached to the event subscription[uuid:{1}] - -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:107 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:162 # args: msg.getKey() event\ doesn't\ have\ label[%s] = event doesn't have label[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:112 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:167 # args: msg.getKey() the\ event\ subscription\ already\ has\ the\ label[%s] = the event subscription already has the label[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:155 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:138 +# args: msg.getActionUuid(),msg.getSubscriptionUuid() +the\ action[uuid\:%s]\ already\ attached\ to\ the\ event\ subscription[uuid\:%s] = the action[uuid:{0}] already attached to the event subscription[uuid:{1}] + +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:213 # args: msg.getNamespace() namespace[%s]\ not\ found = namespace[{0}] not found -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:129 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:187 # args: ns.getName(),msg.getEventName() namespace[%s]\ doesn't\ have\ the\ event[%s] = namespace[{0}] doesn't have the event[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:137 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:195 # args: msg.getEventName(),l.getKey() event[%s]\ doesn't\ have\ the\ label[%s] = event[{0}] doesn't have the label[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:197 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:361 # args: k,l duplicate\ key[%s]\ with\ values%s = duplicate key[{0}] with values{1} -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:164 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:222 # args: msg.getMetricName() Period\ field\ is\ not\ supported\ for\ metric\ [name\:%s] = Period field is not supported for metric [name:{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:161 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:219 # args: msg.getMetricName() Period\ field\ can\ not\ be\ null\ for\ metric\ [name\:%s] = Period field can not be null for metric [name:{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:172 -# args: msg.getNamespace(),msg.getMetricName() +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:401 +# args: msg.getNamespace(),metricName namespace[%s]\ doesn't\ have\ the\ metric[%s] = namespace[{0}] doesn't have the metric[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:178 -# args: msg.getMetricName() +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:405 +# args: metric the\ metric[%s]\ is\ admin\ only,\ not\ available\ for\ current\ user = the metric[{0}] is admin only, not available for current user -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:186 -# args: msg.getMetricName(),l.getKey() +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:350 +# args: templateVO.getMetricName(),l.getKey() the\ metric[%s]\ doesn't\ have\ the\ label[%s] = the metric[{0}] doesn't have the label[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:209 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:273 # args: actionType invalid\ action\ type[%s] = invalid action type[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:214 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:278 # args: actionUuid,actionType action[uuid\:%s,\ type\:%s]\ not\ found = action[uuid:{0}, type:{1}] not found -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:222 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:286 # args: msg.getActionUuid(),msg.getActionType(),msg.getAlarmUuid() duplicated\ action[uuid\:%s,\ type\:%s]\ for\ the\ alarm[uuid\:%s] = duplicated action[uuid:{0}, type:{1}] for the alarm[uuid:{2}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:232 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:296 # args: msg.getKey(),msg.getOperator(),msg.getValue(),msg.getAlarmUuid() duplicate\ label[key\:%s,\ operator\:%s,\ value\:%s]\ for\ the\ alarm[uuid\:%s] = duplicate label[key:{0}, operator:{1}, value:{2}] for the alarm[uuid:{3}] +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:390 +# args: msg.getNamespace() +namespace[%s]\ not\ support = namespace[{0}] not support + # at: src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java:110 # args: msg.getSubscriptionUuid() cannot\ find\ the\ event\ subscription[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the event subscription[uuid:{0}], it may have been deleted @@ -9378,7 +14646,7 @@ cannot\ find\ the\ event\ subscription[uuid\:%s],\ it\ may\ have\ been\ deleted # args: msg.getAlarmUuid() cannot\ find\ the\ alarm[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find the alarm[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java:576 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java:525 # args: alarmVO.getMetricName() the\ metric[%s]\ repeatInterval\ value\ cannot\ be\ less\ than\ 1h = the metric[{0}] repeatInterval value cannot be less than 1h @@ -9402,94 +14670,138 @@ cannot\ find\ the\ topic[uuid\:%s] = cannot find the topic[uuid:{0}] # args: msg.getAlarmTextTemplateUuid() cannot\ find\ SNSTextTemplate[uuid\:%s],\ it\ may\ have\ been\ deleted = cannot find SNSTextTemplate[uuid:{0}], it may have been deleted -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:73 -# args: msg.getApplicationPlatformType() +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:198 +# args: vo.getApplicationPlatformType() invalid\ application\ platform\ type[%s] = invalid application platform type[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:159 -# args: String.join(",\n", errorParams),String.join(",\n", AbstractTextTemplate.defaultSupportedParams) +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:212 +# args: String.join(",\n", errorRecoverParams),String.join(",\n", AbstractTextTemplate.defaultSupportedParams.get(vo.getType())) parameters\:\n\ %s\ are\ not\ supported\ by\ ZStack,\ available\ values\ are\:\n\ %s = parameters:\n {0} are not supported by ZStack, available values are:\n {1} -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:78 -# args: msg.getApplicationPlatformType() +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:203 +# args: vo.getApplicationPlatformType() application\ platform/endpoint\ [%s]\ doesn't\ support\ user-defined\ template = application platform/endpoint [{0}] doesn't support user-defined template -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:91 +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:107 # args: sign,sign.length() The\ length\ of\ aliyun\ sms\ sign\ should\ between\ 2\ to\ 12\ characters.\ Got\ sign\:\ [%s]\ with\ [%d]\ characters. = The length of aliyun sms sign should between 2 to 12 characters. Got sign: [{0}] with [{1}] characters. -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:96 +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:112 # args: alarmTemplateCode,alarmTemplateCode.length() Sms\ template\ code\ is\ a\ string\ with\ 13\ characters.\ Got\ alarm\ template\ code\:\ [%s]\ with\ [%d]\ characters. = Sms template code is a string with 13 characters. Got alarm template code: [{0}] with [{1}] characters. -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:101 +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:117 # args: eventTemplateCode,eventTemplateCode.length() Sms\ template\ code\ is\ a\ string\ with\ 13\ characters.\ Got\ event\ template\ code\:\ [%s]\ with\ [%d]\ characters. = Sms template code is a string with 13 characters. Got event template code: [{0}] with [{1}] characters. -# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:587 -# args: DATA_DIR_CAPACITY_ALARM_UUID +# at: src/main/java/org/zstack/zwatch/alarm/sns/TextTemplateFactory.java:31 +# args: type +no\ template\ of\ this\ type:%s,\ = no template of this type:{0}, + +# at: src/main/java/org/zstack/zwatch/alarm/sns/TextTemplateFactory.java:43 +# args: e.getMessage() +template\ error:%s = template error:{0} + +# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:1471 +# args: DATA_DIR_CAPACITY_ALARM_uuid alarm[uuid\:%s]\ is\ a\ system\ alarm\ which\ cannot\ be\ deleted = alarm[uuid:{0}] is a system alarm which cannot be deleted -# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:598 -# args: SNSSystemAlarmTopicManager.SYSTEM_ALARM_TOPIC_UUID,DATA_DIR_CAPACITY_ALARM_UUID +# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:1482 +# args: SNSSystemAlarmTopicManager.SYSTEM_ALARM_TOPIC_uuid,DATA_DIR_CAPACITY_ALARM_uuid removing\ system\ topic[uuid\:%s]\ from\ system\ alarm[uuid\:%s]\ is\ forbidden = removing system topic[uuid:{0}] from system alarm[uuid:{1}] is forbidden -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:203 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:270 # args: l.getKey(),AuditDataV2.queryableLoginLabels invalid\ label[%s],\ valid\ queryable\ labels\ are\ %s = invalid label[{0}], valid queryable labels are {1} -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:250 -# args: msg.getStartTime(),msg.getEndTime() +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:487 +# args: startTime,endTime startTime[%s]\ is\ greater\ than\ endTime[%s] = startTime[{0}] is greater than endTime[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:114 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:162 # args: dataUuid\ cannot\ be\ missed = dataUuid cannot be missed -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:120 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:168 # args: dataStartTime\ and\ dataEndTime\ cannot\ be\ missed = dataStartTime and dataEndTime cannot be missed -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:124 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:172 # args: msg.getDataStartTime(),msg.getDataEndTime() dataStartTime[%s]\ is\ greater\ than\ dataEndTime[%s] = dataStartTime[{0}] is greater than dataEndTime[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:142 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:190 # args: Namespace.ZSTACK_NAMESPACE_PREFIX namespace\ name\ cannot\ start\ with\ %s\ that\ is\ reserved = namespace name cannot start with {0} that is reserved -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:153 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:396 +# args: end,msg.getEndTime(),start,msg.getStartTime() +endTime[%s,\ %sms]\ must\ not\ be\ before\ startTime[%s,\ %sms] = endTime[{0}, {1}ms] must not be before startTime[{2}, {3}ms] + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:211 +# args: MAX_QUERY_PERIOD +query\ period\ cannot\ exceed\ %s = query period cannot exceed {0} + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:355 # args: msg.getNamespace() cannot\ find\ namespace[%s] = cannot find namespace[{0}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:161 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:228 # args: msg.getMetricName(),msg.getNamespace() cannot\ find\ metric[%s]\ in\ namespace[%s] = cannot find metric[{0}] in namespace[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:174 -# args: msg.getMetricName(),metric.getLabelNames(),l.getKey() +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:378 +# args: msg.getMetricName(),labels,label.getKey() metric[%s]'s\ labels[%s]\ does\ not\ include\ [%s] = metric[{0}]'s labels[{1}] does not include [{2}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:186 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:253 # args: msg.getMetricName(),l.getValue() metric[%s]\ does\ not\ has\ filter[%s] = metric[{0}] does not has filter[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:229 -# args: AuditDataV2.TAG_RESOURCE_UUID -label[%s]\ must\ be\ specified = label[{0}] must be specified +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:324 +# args: msg.getSession().getAccountUuid(),opt.get().getValue() +account[uuid\:\ %s]\ has\ no\ access\ to\ the\ resource[uuid\:\ %s] = account[uuid: {0}] has no access to the resource[uuid: {1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:271 -# args: end,msg.getEndTime(),start,msg.getStartTime() -endTime[%s,\ %sms]\ must\ not\ be\ before\ startTime[%s,\ %sms] = endTime[{0}, {1}ms] must not be before startTime[{2}, {3}ms] +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:346 +# args: +if\ namespace\ is\ all,\ not\ support\ specify\ metric\ and\ labels = if namespace is all, not support specify metric and labels -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:289 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:440 # args: msg.getNamespace() no\ namespace[%s]\ defined\ in\ the\ system = no namespace[{0}] defined in the system -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:293 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:443 # args: msg.getNamespace(),msg.getMetricName() the\ namespace[%s]\ has\ no\ metric[%s] = the namespace[{0}] has no metric[{1}] +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:433 +# args: +The\ url\ format\ is\ invalid,\ the\ beginning\ is\ not\ http = The url format is invalid, the beginning is not http + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:449 +# args: +Illegal\ json\ string,\ labelsJsonStr\ format\ is\ invalid = Illegal json string, labelsJsonStr format is invalid + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:477 +# args: url +platform[url\=%s]\ already\ exists = platform[url={0}] already exists + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:498 +# args: msg.getAlertDataUuid() +alert\ acknowledgement\ record\ does\ not\ exist = alert acknowledgement record does not exist + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:516 +# args: tableName +invalid\ table[%s] = invalid table[{0}] + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:522 +# args: endTime,startTime +endTime[%s]\ must\ not\ be\ before\ startTime[%s] = endTime[{0}] must not be before startTime[{1}] + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:527 +# args: maxDurationDay +the\ time\ interval\ exceeds\ %\ days = the time interval exceeds % days + # at: src/main/java/org/zstack/zwatch/datatype/EmergencyLevel.java:19 # args: Normal = Normal @@ -9510,117 +14822,145 @@ invalid\ function\:\ %s,\ %s = invalid function: {0}, {1} # args: expr invalid\ expression\:\ %s,\ no\ function\ found = invalid expression: {0}, no function found -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:57 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:58 # args: str the\ label\ string[%s]\ contains\ no\ valid\ operator = the label string[{0}] contains no valid operator -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:72 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:79 # args: JSONObjectUtil.toJsonString(this) invalid\ label,\ 'key'\ field\ cannot\ be\ null.\ %s = invalid label, 'key' field cannot be null. {0} -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:75 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:82 # args: JSONObjectUtil.toJsonString(this) invalid\ label,\ 'op'\ field\ is\ null\ or\ something\ another\ than\ Regex\ and\ Equal.\ %s = invalid label, 'op' field is null or something another than Regex and Equal. {0} -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:78 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:85 # args: JSONObjectUtil.toJsonString(this) invalid\ label,\ 'value'\ field\ cannot\ be\ null.\ %s = invalid label, 'value' field cannot be null. {0} +# at: src/main/java/org/zstack/zwatch/datatype/ValueCondition.java:73 +# args: str +the\ ValueCondition\ string[%s]\ require\ 'value'\ as\ key\ = the ValueCondition string[{0}] require 'value' as key + # at: src/main/java/org/zstack/zwatch/function/ArgumentChecker.java:30 # args: value,name invalid\ value[%s]\ of\ the\ argument[%s] = invalid value[{0}] of the argument[{1}] -# at: src/main/java/org/zstack/zwatch/function/LimitFunction.java:21 -# args: v -value[%s]\ is\ not\ a\ Integer\ number = value[{0}] is not a Integer number +# at: src/main/java/org/zstack/zwatch/function/ExtremumFunction.java:24 +# args: +unknown\ arguments = unknown arguments -# at: src/main/java/org/zstack/zwatch/function/LimitFunction.java:18 -# args: v -invalid\ argument[limit\:%s],\ it\ can't\ be\ a\ negative\ number = invalid argument[limit:{0}], it can't be a negative number +# at: src/main/java/org/zstack/zwatch/function/ExtremumFunction.java:30 +# args: +missing\ required\ argument = missing required argument -# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:46 +# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:88 # args: name missing\ required\ argument[%s] = missing required argument[{0}] -# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:59 +# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:101 # args: k duplicate\ argument[%s] = duplicate argument[{0}] -# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:68 +# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:116 # args: func.getName() unknown\ function[%s] = unknown function[{0}] -# at: src/main/java/org/zstack/zwatch/function/SortFunction.java:41 -# args: arg.name -unknown\ argument[%s] = unknown argument[{0}] - -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:153 -# args: name -cannot\ find\ EventFamily[name\:%s] = cannot find EventFamily[name:{0}] +# at: src/main/java/org/zstack/zwatch/function/PaginationFunction.java:32 +# args: v +value[%s]\ is\ not\ a\ Integer\ number = value[{0}] is not a Integer number -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:175 -# args: name,namespace -cannot\ find\ EventFamily[name\:%s,\ namespace\:%s] = cannot find EventFamily[name:{0}, namespace:{1}] +# at: src/main/java/org/zstack/zwatch/function/PaginationFunction.java:19 +# args: v +invalid\ argument[limit\:%s],\ it\ can't\ be\ a\ negative\ number = invalid argument[limit:{0}], it can't be a negative number -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:632 -# args: label.getKey(),names -invalid\ query\ label[%s].\ Allowed\ label\ names\ are\ %s = invalid query label[{0}]. Allowed label names are {1} +# at: src/main/java/org/zstack/zwatch/function/PaginationFunction.java:29 +# args: v +invalid\ argument[start\:%s],\ it\ can't\ be\ a\ negative\ number = invalid argument[start:{0}], it can't be a negative number -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:666 -# args: name.getValue(),InfluxEventDataV2.FIELD_NAMESPACE -there\ are\ multiple\ EventFamily\ with\ the\ name[%s],\ you\ must\ specify\ the\ label[%s] = there are multiple EventFamily with the name[{0}], you must specify the label[{1}] +# at: src/main/java/org/zstack/zwatch/function/SortFunction.java:42 +# args: arg.name +unknown\ argument[%s] = unknown argument[{0}] -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:58 +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:62 # args: ret.getError() unable\ to\ query\ influxdb,\ %s = unable to query influxdb, {0} -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:102 +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:106 # args: JSONObjectUtil.toJsonString(ret) invalid\ influxdb\ response\:\ %s,\ no\ name\ found\ in\ columns = invalid influxdb response: {0}, no name found in columns -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:88 +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:92 # args: retention,res.getError() failed\ to\ create\ influxdb\ retention\ '%s',\ %s = failed to create influxdb retention '{0}', {1} -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:81 +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:85 # args: retention,res.getError() failed\ to\ alter\ influxdb\ retention\ '%s',\ %s = failed to alter influxdb retention '{0}', {1} -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:120 +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:124 # args: defaultUserName,res.getError() failed\ to\ create\ influxdb\ default\ user\ '%s',\ %s = failed to create influxdb default user '{0}', {1} +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:806 +# args: name +cannot\ find\ EventFamily[name\:%s] = cannot find EventFamily[name:{0}] + +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:797 +# args: name,namespace +cannot\ find\ EventFamily[name\:%s,\ namespace\:%s] = cannot find EventFamily[name:{0}, namespace:{1}] + +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:726 +# args: label.getKey(),nameSpaceLabelList +invalid\ query\ label[%s].\ Allowed\ label\ names\ are\ %s = invalid query label[{0}]. Allowed label names are {1} + +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:627 +# args: name.getValue(),InfluxEventDataV2.FIELD_NAMESPACE +there\ are\ multiple\ EventFamily\ with\ the\ name[%s],\ you\ must\ specify\ the\ label[%s] = there are multiple EventFamily with the name[{0}], you must specify the label[{1}] + +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java:55 +# args: msg.getInstanceUuid() +the\ instance[%s]\ is\ already\ in\ the\ group = the instance[{0}] is already in the group + +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java:66 +# args: msg.getInstanceUuid() +instance[%s]\ is\ not\ in\ the\ group = instance[{0}] is not in the group + +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java:76 +# args: msg.getGroupUuid() +The\ monitorGroup[%s]\ does\ not\ have\ an\ monitorTemplate\ applied = The monitorGroup[{0}] does not have an monitorTemplate applied + +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupBase.java:333 +# args: +The\ instance\ in\ the\ group\ has\ reached\ the\ maximum\ limit = The instance in the group has reached the maximum limit + +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupManagerImpl.java:607 +# args: +The\ rule\ in\ the\ template\ has\ reached\ the\ maximum\ limit = The rule in the template has reached the maximum limit + # at: src/main/java/org/zstack/zwatch/mysql/MysqlDatabaseDriver.java:51 # args: qo.getNamespaceName() no\ mysql\ namespace[%s]\ found = no mysql namespace[{0}] found -# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:46 +# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:48 # args: getName(),queryObject.getMetricName() namespace[%s]\ has\ no\ metric[%s] = namespace[{0}] has no metric[{1}] -# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:52 +# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:54 # args: m.getName(),getName(),l.getKey() metric[%s]\ of\ the\ namespace[%s]\ has\ no\ label\ named\ %s = metric[{0}] of the namespace[{1}] has no label named {2} -# at: src/main/java/org/zstack/zwatch/namespace/NamespaceEventManagerImpl.java:406 +# at: src/main/java/org/zstack/zwatch/namespace/NamespaceEventManagerImpl.java:437 # args: error\ happened\ but\ reason\ not\ specified = error happened but reason not specified -# at: src/main/java/org/zstack/zwatch/namespace/SystemNamespace.java:31 +# at: src/main/java/org/zstack/zwatch/namespace/SystemNamespace.java:32 # args: d,Platform.getManagementServerIp() folder[%s]\ not\ found\ on\ the\ management\ server[%s] = folder[{0}] not found on the management server[{1}] -# at: src/main/java/org/zstack/compute/vm/InstantiateVirtIODriverFlow.java:148 -# args: filepath,Platform.getManagementServerIp() -fail\ to\ attach\ virtio\ driver\ because\ of\ invalid\ md5\ of\ file[%s]\ in\ mn[uuid\:%s] = fail to attach virtio driver because of invalid MD5sum of file[{0}] in management server[uuid:{1}] - -# at: src/main/java/org/zstack/compute/vm/InstantiateVirtIODriverFlow.java:154 -# args: filepath,Platform.getManagementServerIp(),cause -fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ %s = fail to attach virtio driver because read MD5sum of file[{0}] fail in management server[uuid:{1}]: {2} - -# at: src/main/java/org/zstack/compute/vm/InstantiateVirtIODriverFlow.java:142 -# args: filepath,Platform.getManagementServerIp() -fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ file\ not\ found\ on\ classpath = fail to attach virtio driver because read MD5sum of file[{0}] fail in management server[uuid:{1}]: file is not exist on class path +# at: src/main/java/org/zstack/zwatch/prometheus/KvmHostScrape.java:165 +# args: rsp.getError() +%s = {0} # at: src/main/java/org/zstack/zwatch/ruleengine/ComparisonOperator.java:35 # args: @@ -9638,62 +14978,62 @@ GreaterThan = GreaterThan # args: GreaterThanOrEqualTo = GreaterThanOrEqualTo -# at: src/test/java/org/zstack/test/aop/ManInTheMiddleService.java:40 -# args: -unit\ test\ asks\ it\ to\ fail = unit test asks it to fail - -# at: src/test/java/org/zstack/test/compute/hostallocator/HostAllocateExtension.java:22 -# args: -On\ purpose = On purpose +# at: src/main/java/org/zstack/zwatch/utils/ResourceVOToNamespaceMappingUtils.java:78 +# args: voClassSimpleName +resource[%s]\ doesn't\ support\ zwatch\ return\ with\ clause = resource[{0}] doesn't support zwatch return with clause -# at: src/test/java/org/zstack/test/kvm/KVMPingAgentExtensionForTest.java:27 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:80 # args: on\ purpose = on purpose -# at: src/test/crypto/org/zstack/crypto/auth/CryptoAuthenticationManagerImpl.java:162 -# args: -could\ not\ enable\ two-factor\ authentication\ when\ CCS\ certificate\ authentication\ is\ enabled = could not enable crypto UKey authentication when other two-factor authentication is enabled +# at: src/test/java/org/zstack/test/TestSafeWhile.java:56 +# args: item +on\ purpose\ %d = on purpose {0} -# at: src/test/crypto/org/zstack/crypto/auth/CryptoAuthenticationManagerImpl.java:170 -# args: -could\ not\ enable\ CCS\ certificate\ authentication\ when\ two-factor\ authentication\ is\ enabled = could not enable two-factor authentication when crypto UKey authentication is enabled +# at: src/test/java/org/zstack/test/TestSafeWhile.java:39 +# args: item +I\ should\ not\ be\ in\ error\ list\ %d = I should not be in error list {0} + +# at: src/test/java/org/zstack/test/TestSafeWhile.java:40 +# args: item +I\ should\ not\ be\ in\ error\ list\ either\ %d = I should not be in error list either {0} -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:209 -# args: certificate.uuid -certificate[uuid\=%s]\ not\ found = CCS certificate[uuid:{0}] does not exist +# at: src/test/java/org/zstack/test/TestSafeWhile.java:63 +# args: +done,\ on\ purpose = done, on purpose -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:224 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:81 # args: -CCS\ certificate\ authentication\ disabled = CCS certificate authentication disabled. Please check whether the current secret resource pool is enabled +I\ should\ not\ be\ errs\ list = I should not be errs list -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:230 -# args: expectCryptoAuthenticationType, actualCryptoAuthenticationType -wrong\ crypto\ authentication\ type,\ expect[%s],\ actual[%s] = wrong crypto authentication type in UKey system tag, expect[{0}], actual[{1}]. Please check out your UKey system tag in API parameter +# at: src/test/java/org/zstack/test/TestSafeWhile.java:82 +# args: +I\ should\ not\ be\ errs\ list\ either. = I should not be errs list either. -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:242 +# at: src/test/java/org/zstack/test/aop/ManInTheMiddleService.java:40 # args: -failed\ to\ decrypt\ cipher\ text = failed to decrypt cipher text in UKey system tag. Please check out your UKey system tag in API parameter +unit\ test\ asks\ it\ to\ fail = unit test asks it to fail -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:247 +# at: src/test/java/org/zstack/test/compute/hostallocator/HostAllocateExtension.java:22 # args: -wrong\ credential = wrong credential. Please check out your UKey system tag in API parameter +On\ purpose = On purpose -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:298 -# args: certificate.uuid -certificate[uuid\=%s]\ is\ not\ within\ the\ valid\ period = the CCS certificate[uuid:{0}] is not within the valid period +# at: src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java:67 +# args: +on\ purpose\ 3 = on purpose 3 -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:158 -# args: certificate.uuid -user[uuid\=%s]\ not\ found = user[uuid:{0}] does not exist +# at: src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java:75 +# args: +on\ purpose\ 1 = on purpose 1 -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:162 +# at: src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java:83 # args: -certificate\ uuid\ is\ empty\ and\ UKey\ system\ tag\ does\ not\ exist = bad API request: certificate UUID and UKey system tag cannot be empty at the same time. Please check out your UKey system tag in API parameter +on\ purpose\ 2 = on purpose 2 -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:167 -# args: user.uuid -user[uuid\=%s]\ does\ not\ have\ any\ CCS\ certificate\ attached = user[uuid:{0}] does not have any CCS certificate attached +# at:src/main/java/org/zstack/identity/AccountLoginBackend.java:64 +# args: +wrong\ account\ name\ or\ password = wrong account name or password -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:172 -# args: user.uuid, certificate.uuid -user[uuid\=%s]\ already\ has\ the\ certificate[uuid\=%s]\ attached = user[uuid:{0}] already has the certificate[uuid:{1}] attached +# at: src/main/java/org/zstack/sns/platform/universalsms/SNSUniversalSmsEndpoint.java:166 +# args: +Failed\ to\ validate\ universal\ sms = Failed to validate universal sms diff --git a/conf/i18n/messages_zh_CN.properties b/conf/i18n/messages_zh_CN.properties index 34d823a2383..8bc97465306 100755 --- a/conf/i18n/messages_zh_CN.properties +++ b/conf/i18n/messages_zh_CN.properties @@ -1,18 +1,18 @@ -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:44 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:43 # args: accountUuid,userUuid -no\ pemission\ to\ do\ the\ operation\ for\ [accountUuid\:%s,\ userUuid\:%s] = +no\ pemission\ to\ do\ the\ operation\ for\ [accountUuid\:%s,\ userUuid\:%s] = 没有可对[AccountUuId:{0},UserUuId:{1}]执行操作的pEmission -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:51 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:50 # args: -If\ a\ specified\ Accesskey\ is\ expected,\ the\ AccesskeyId\ and\ the\ AccesskeySecret\ must\ be\ provided\ at\ the\ same\ time. = +If\ a\ specified\ Accesskey\ is\ expected,\ the\ AccesskeyId\ and\ the\ AccesskeySecret\ must\ be\ provided\ at\ the\ same\ time. = 如果需要指定的AccessKey,则必须同时提供AccessKeyId和AccessKeySecret。 -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:65 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:72 # args: msg.getAccountUuid(),msg.getUserUuid() -[accountId\:\ %s,\ userID\:\ %s]\ is\ not\ valid\ account\ or\ iam2\ porject/user = +[accountId\:\ %s,\ userID\:\ %s]\ is\ not\ valid\ account\ or\ iam2\ porject/user = [帐户ID:{0},用户ID:{1}]不是有效的帐户或IAM2对象/用户 -# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:77 +# at: src/main/java/org/zstack/accessKey/AccessKeyApiInterceptor.java:91 # args: msg.getAccountUuid(),msg.getUserUuid() -accessKey\ number\ for\ [accountId\:\ %s,\ userID\:\ %s]exceeds\ the\ max = +accessKey\ number\ for\ [accountId\:\ %s,\ userID\:\ %s]exceeds\ the\ max = [AccountId:{0},UserId:{1}]的AccessKey编号超出最大值 # at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:92 # args: ipVer @@ -31,14 +31,42 @@ ip\ format\ only\ supports\ ip/iprange/cidr,\ but\ find\ %s = 只支持IP地址/ ip\ range[%s,\ %s]\ is\ overlap\ with\ [%s,\ %s]\ in\ access-control-list\ group\:%s = IP段[{0},{1}]和访问控制组:{4}里的[{2}, {3}]有重叠的ip # at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:127 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ redirect\ rule,\ can\ not\ add\ IP\ Entry = 访问控制列表组[{0}]已拥有重定向规则,无法添加IP条目 + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:133 # args: acl.getUuid(),AccessControlListConstants.MAX_ENTRY_COUNT_PER_GROUP the\ access-control-list\ groups[%s]\ can't\ be\ added\ more\ than\ %d\ ip\ entries = 访问控制组[{0}]最多只能添加{1}ip组 +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:138 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ redirect\ rule,\ can\ not\ add\ ip\ entry = 访问控制列表组[{0}]已拥有重定向规则,无法添加IP条目 + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:154 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ ip\ entry,\ can\ not\ add\ redirect\ rule = 访问控制列表组[{0}]已拥有IP条目,无法添加重定向规则 + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:158 +# args: acl.getUuid() +the\ access-control-list\ groups[%s]\ already\ own\ one\ redirect\ rule,\ can\ not\ add\ redirect\ rule = 访问控制列表组[{0}]已拥有一个重定向规则,无法添加重定向规则 + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:162 +# args: +domain\ and\ url\ can\ not\ both\ empty = 域和URL不能同时为空 + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:178 +# args: msg.getUrl() +url[%s]\ is\ not\ validate\ url = URL[{0}]不是验证URL + +# at: src/main/java/org/zstack/acl/AccessControlListApiInterceptor.java:167 +# args: msg.getDomain() +domain[%s]\ is\ not\ validate\ domain = 域[{0}]不是验证域 + # at: src/main/java/org/zstack/aliyun/account/AliyunAccountBase.java:348 # args: builder.deleteCharAt(builder.length() - 1),timeout -cannot\ connect\ to\ [%s]\ in\ %d\ milliseconds,\ so\ aliyun\ openapi\ is\ unreachable. = +cannot\ connect\ to\ [%s]\ in\ %d\ milliseconds,\ so\ aliyun\ openapi\ is\ unreachable. = 无法在{1}毫秒内连接到[{0}],因此无法访问阿里云OpenAPI。 -# at: src/main/java/org/zstack/aliyun/backup/BackupToAliyunBase.java:465 +# at: src/main/java/org/zstack/aliyun/backup/BackupToAliyunBase.java:466 # args: no\ bucket\ found\ for\ backup = 没有可用的Bucket执行备份 @@ -48,195 +76,183 @@ accessKey\ and\ keySecret\ must\ be\ set = 必须设置accessKey和keySecret # at: src/main/java/org/zstack/aliyun/core/AliyunEbsClient.java:73 # args: -ocean\ api\ endpoint\ must\ not\ be\ null = +ocean\ api\ endpoint\ must\ not\ be\ null = Ocean API端点不能为空 # at: src/main/java/org/zstack/aliyun/core/AliyunNasClient.java:33 # args: -accessKey\ and\ keySecret\ must\ be\ set! = +accessKey\ and\ keySecret\ must\ be\ set! = 必须设置AccessKey和KeySecret! # at: src/main/java/org/zstack/aliyun/core/AliyunNasClient.java:40 # args: -regionId\ must\ be\ set! = - -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:238 -# args: -cannot\ find\ key\ /\ secret\ from\ msg = +regionId\ must\ be\ set! = 必须设置RegionID! -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2131 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2162 # args: AliyunConstant.DEFAULT_ENTRY_WAIT_STATUS_TIMEOUT entry\ is\ still\ existed\ after\ %s\ ms = 虚拟路由器删除超时({0} ms) -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2637 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2648 # args: request.getInstanceIds() -cannot\ find\ EcsInstance[%s],\ please\ check\ if\ it\ exists\ in\ Aliyun\ console = +cannot\ find\ EcsInstance[%s],\ please\ check\ if\ it\ exists\ in\ Aliyun\ console = 找不到ECSInstance[{0}],请检查阿里云控制台是否存在 -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2697 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2708 # args: image\ already\ existed\ remote,\ please\ use\ sync\ first. = 镜像已经存在阿里云服务器上,请尝试同步数据 -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:2883 -# args: -no\ identity\ zones\ can\ be\ used\ now = 没有可用区能使用 - -# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:3019 +# at: src/main/java/org/zstack/aliyun/core/AliyunSdkImpl.java:3015 # args: request.getRegionId() regionId[%s]\ is\ invalid\ by\ aliyun! = regionId[{0}]是无效的! -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:63 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:61 # args: -Not\ a\ valid\ message! = +Not\ a\ valid\ message! = 无效消息! -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:159 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:177 # args: action,result.ErrorCode,result.ErrorMessage -%s\ failed,\ ErrorCode\:\ %s,\ ErrorMessage\:\ %s = +%s\ failed,\ ErrorCode\:\ %s,\ ErrorMessage\:\ %s = {0}失败,错误代码:{1},错误消息:{2} -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:282 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:301 # args: 15000 -Device\ Not\ Ready\ in\ %d\ milli\ seconds = +Device\ Not\ Ready\ in\ %d\ milli\ seconds = 设备在{0}毫秒内未就绪 -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:476 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:497 # args: result.Content.TaskStatus -snapshot\ task\ status\ is\ finished\ %s = +snapshot\ task\ status\ is\ finished\ %s = 快照任务状态为已完成{0} -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:472 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:493 # args: msg.getTimeout(),result.Content.Progress,result.Content.TaskStatus -snapshot\ task\ cannot\ finished\ in\ %d\ milliseconds,\ now\ progress\ is\ %d,\ status\ is\ %s = +snapshot\ task\ cannot\ finished\ in\ %d\ milliseconds,\ now\ progress\ is\ %d,\ status\ is\ %s = 快照任务无法在{0}毫秒内完成,当前进度为{1},状态为{2} -# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:877 +# at: src/main/java/org/zstack/aliyun/core/AliyunStorageSdkIml.java:898 # args: -not\ supported\ HybridClient = +not\ supported\ HybridClient = 不支持HybridClient -# at: src/main/java/org/zstack/aliyun/core/AliyunUtils.java:263 +# at: src/main/java/org/zstack/aliyun/core/AliyunUtils.java:259 # args: e.getMessage() -add\ endpoint\ to\ sdk\ failed,\ due\ to\:\ %s = +add\ endpoint\ to\ sdk\ failed,\ due\ to\:\ %s = 将端点添加到SDK失败,原因是:{0} + +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:86 +# args: +cannot\ find\ key\ /\ secret\ from\ msg = 无法从消息中找到密钥/机密 -# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:407 +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:410 # args: -cannot\ input\ 0-length\ file\ as\ vm\ images! = +cannot\ input\ 0-length\ file\ as\ vm\ images! = 无法将长度为0的文件作为云主机镜像输入! -# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:496 +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:499 # args: e.getMessage() -Permission\ denied\ for\:\ %s = +Permission\ denied\ for\:\ %s = 权限被拒绝:{0} -# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:585 +# at: src/main/java/org/zstack/aliyun/core/OssSdkImpl.java:588 # args: e.getRequestId() Bucket\ name\ is\ already\ existed\ (maybe\ created\ by\ other\ user),\ Please\ select\ a\ different\ name\ and\ try\ again.(aliyun\ request-id\:\ %s) = Bucket名称已经存在(可能已经被别的用户使用了),请尝试使用一个新的命名。(阿里云请求ID: {0}) # at: src/main/java/org/zstack/aliyun/core/datacenter/AliyunPrivateDataCenterBase.java:277 # args: HybridType.AliyunEBS.toString() -arg\ 'endpoint'\ must\ be\ set\ in\ %s\ type = +arg\ 'endpoint'\ must\ be\ set\ in\ %s\ type = 必须在{0}类型中设置参数“ endpoint ” # at: src/main/java/org/zstack/aliyun/core/datacenter/AliyunPrivateDataCenterBase.java:332 # args: type.toString() -not\ supported\ datacenter\ [%s]\ type\ here! = +not\ supported\ datacenter\ [%s]\ type\ here! = 此处不支持数据中心[{0}]类型! -# at: src/main/java/org/zstack/aliyun/core/identityzone/AliyunPrivateIdentityZoneBase.java:252 +# at: src/main/java/org/zstack/aliyun/core/identityzone/AliyunPrivateIdentityZoneBase.java:175 # args: -must\ indicate\ zoneId\ in\ private\ aliyun. = +must\ indicate\ zoneId\ in\ private\ aliyun. = 必须在私有阿里云中注明ZoneID。 # at: src/main/java/org/zstack/aliyun/ebs/storage/OceanApi.java:87 # args: e.getMessage() -make\ ocean\ api\ signature\ string\ failed\:\ %s = +make\ ocean\ api\ signature\ string\ failed\:\ %s = 生成Ocean API签名字符串失败:{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/backup/AliyunEbsBackupStorageApiInterceptor.java:30 # args: -url(ocean\ endpoint)\ must\ be\ set\ for\ aliyun\ ebs\ backupstorage = +url(ocean\ endpoint)\ must\ be\ set\ for\ aliyun\ ebs\ backupstorage = 阿里云EBS备份存储必须设置URL(海洋端点) # at: src/main/java/org/zstack/aliyun/ebs/storage/backup/AliyunEbsBackupStorageBase.java:376 # args: -aliyun\ ebs\ backup\ storage\ do\ not\ support\ to\ cancel\ download\ image = +aliyun\ ebs\ backup\ storage\ do\ not\ support\ to\ cancel\ download\ image = 阿里云EBS备份存储不支持取消下载镜像 # at: src/main/java/org/zstack/aliyun/ebs/storage/backup/AliyunEbsBackupStorageBase.java:620 # args: objectFile,ovo.getBucketName() -no\ such\ object\ %s\ found\ in\ bucket\ %s = +no\ such\ object\ %s\ found\ in\ bucket\ %s = 在存储桶{1}中找不到此类对象{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/backup/AliyunEbsBackupStorageCascadeExtenstion.java:46 # args: oss.getUuid(),evo.getUuid() -cannot\ delete\ oss\ bucket\ [%s],\ Aliyun\ Ebs\ BackupStorage\ [%s]\ still\ existed,\ please\ delete\ it\ first. = +cannot\ delete\ oss\ bucket\ [%s],\ Aliyun\ Ebs\ BackupStorage\ [%s]\ still\ existed,\ please\ delete\ it\ first. = 无法删除OSS Bucket[{0}],Aliyun EBS BackupStorage[{1}]仍然存在,请先将其删除。 # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsKvmFactory.java:147 # args: vol.getUuid() -cannot\ find\ device\ path\ from\ volume\:\ %s = +cannot\ find\ device\ path\ from\ volume\:\ %s = 无法从卷中找到设备路径:{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsKvmFactory.java:490 # args: -aliyun\ ebs\ not\ support\ resize\ on\ running\ vm\ now. = +aliyun\ ebs\ not\ support\ resize\ on\ running\ vm\ now. = 阿里云EBS现在不支持在运行的云主机上调整大小。 # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsKvmFactory.java:612 # args: isoUuid -iso\ [%s]\ has\ been\ attached,\ we\ can\ not\ attach\ it\ until\ detach\ it = +iso\ [%s]\ has\ been\ attached,\ we\ can\ not\ attach\ it\ until\ detach\ it = 已附加ISO[{0}],在分离它之前无法附加它 # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java:39 # args: msg.getUrl() -url\ must\ starts\ with\ http\://\ or\ https\://,\ but\ got\ %s = +url\ must\ starts\ with\ http\://\ or\ https\://,\ but\ got\ %s = URL必须以HTTP://或HTTPS://开头,但获得了{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java:35 # args: -url(ocean\ endpoint)\ must\ be\ set\ for\ aliyun\ ebs\ primarystorage = +url(ocean\ endpoint)\ must\ be\ set\ for\ aliyun\ ebs\ primarystorage = 阿里云EBS PrimaryStorage必须设置URL(海洋端点) # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java:43 # args: -panguPartitionUuid\ or\ identityZoneUuid\ must\ be\ set. = +panguPartitionUuid\ or\ identityZoneUuid\ must\ be\ set. = 必须设置PangUpartitionUuid或IdentityZoneUuid。 # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageApiInterceptor.java:49 # args: msg.getPanguPartitionUuid(),msg.getIdentityZoneUuid() -panguPartitionUuid\ [%s]\ not\ be\ matched\ with\ identityZoneUuid\ [%s] = - -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3189 -# args: imageVO.getUuid() -image\ [uuid\:%s]\ has\ been\ deleted = 镜像[uuid:{0}]已经被删除 - -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3762 -# args: msg.getResourceUuid() -resource[uuid\:\ %s]\ cannot\ found = +panguPartitionUuid\ [%s]\ not\ be\ matched\ with\ identityZoneUuid\ [%s] = panguPartitionUuid[{0}]与identityZoneUuid[{1}]不匹配 -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:674 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:669 # args: self.getUuid(),self.getName() -the\ aliyun\ ebs\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = +the\ aliyun\ ebs\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = 阿里云EBS主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机 -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2829 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2888 # args: reply1.getProgress() -create\ snapshot\ timeout,\ progress\ is\ %d = +create\ snapshot\ timeout,\ progress\ is\ %d = 创建快照超时,进度为{0} -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:1925 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:1971 # args: msg.getVolume().getRootImageUuid() -cannot\ find\ snapshot\ from\ image\:\ %s,\ maybe\ the\ image\ has\ been\ deleted = +cannot\ find\ snapshot\ from\ image\:\ %s,\ maybe\ the\ image\ has\ been\ deleted = 无法从镜像中找到快照:{0},该镜像可能已被删除 -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2687 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:2746 # args: -ebs\ primarystorage\ cannot\ support\ decrease\ size\ now = +ebs\ primarystorage\ cannot\ support\ decrease\ size\ now = EBS主存储现在无法支持减小大小 -# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3089 +# at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageBase.java:3134 # args: bsvo.getType() -aliyun\ ebs\ primarystorage\ only\ support\ aliyun\ ebs\ bs,\ actually\ get\ type\:\ %s = +aliyun\ ebs\ primarystorage\ only\ support\ aliyun\ ebs\ bs,\ actually\ get\ type\:\ %s = 阿里云EBS PrimaryStorage仅支持阿里云EBS BS,实际获取类型:{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStorageCascadeExtension.java:46 # args: iz.getUuid(),evo.getUuid() -cannot\ delete\ identity\ zone\ [%s],\ Aliyun\ Ebs\ PrimaryStorage\ [%s]\ still\ existed,\ please\ delete\ it\ first. = +cannot\ delete\ identity\ zone\ [%s],\ Aliyun\ Ebs\ PrimaryStorage\ [%s]\ still\ existed,\ please\ delete\ it\ first. = 无法删除标识区[{0}],阿里云EBS PrimaryStorage[{1}]仍然存在,请先删除。 # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStoragePathMaker.java:113 # args: installPath -invalid\ install\ path\:\ %s = +invalid\ install\ path\:\ %s = 安装路径无效:{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStoragePathMaker.java:24 # args: volumeId,url -append\ volumeId\:\ %s,\ but\ another\ volumeId\ existed\ in\ url\:\ %s = +append\ volumeId\:\ %s,\ but\ another\ volumeId\ existed\ in\ url\:\ %s = 附加VolumeID:{0},但URL中存在另一个VolumeID:{1} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStoragePathMaker.java:79 # args: url -invalid\ install\ url\:\ %s = +invalid\ install\ url\:\ %s = 无效的安装URL:{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStoragePathMaker.java:35 # args: hostUuid,url -hostUuid\ [%s]\ already\ existed\ in\ url\:\ %s = +hostUuid\ [%s]\ already\ existed\ in\ url\:\ %s = URL{1}中已存在HostUuid[{0}] # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStoragePathMaker.java:83 # args: hostUuid -cannot\ find\ devicePath\ on\ host\:\ %s = +cannot\ find\ devicePath\ on\ host\:\ %s = 在物理机上找不到DevicePath:{0} # at: src/main/java/org/zstack/aliyun/ebs/storage/primary/AliyunEbsPrimaryStoragePathMaker.java:128 # args: installPath -invalid\ snapshot\ install\ path\:\ %s = +invalid\ snapshot\ install\ path\:\ %s = 快照安装路径无效:{0} # at: src/main/java/org/zstack/aliyun/ecs/CheckEcsImageExistPublicFlow.java:79 # args: eivo.getUuid(),eivo.getName(),eivo.getCreateDate() @@ -246,11 +262,15 @@ ecs\ image\ existed\ remote\ and\ local,\ ecs\ image\ uuid\:\ %s,\ name\:\ %s,\ # args: msg.getName(),new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(HybridUtilsForAliyun.fmtTime(rpl.getCreateDate())) ecs\ image\ existed\ remote,\ name\:\ %s,\ created\ time\:\ %s = 云主机镜像已经存在于阿里云服务器上,名称: {0},创建时间: {1} -# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:181 +# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:184 # args: No\ Available\ instance\ types\ now. = 没有可用的实例类型 -# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:304 +# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:253 +# args: regionId,data1.get("type") +This\ region\ [%s]\ cannot\ produce\ instance\ type\ [%s]\ now,\ please\ select\ another\ instance\ type\ or\ another\ region = 此地区[{0}]现在无法生成实例类型[{1}],请选择其他实例类型或其他地区 + +# at: src/main/java/org/zstack/aliyun/ecs/CreateEcsInstancePublicFlow.java:344 # args: ecs.getUuid(),ecs.getEcsInstanceId() no\ system\ disk\ found\ for\ ecs\:\ [%s],\ ecs\ id\ is\:\ [%s] = 没有系统云盘可用来创建云主机,云主机id是: [{1}] @@ -294,17 +314,17 @@ bandwidth\ must\ be\ set\ while\ allocate\ publicIp = 当分配公有IP时带宽 # args: instanceOffering\ or\ instanceType\ must\ be\ set! = 计算规格和实例类型必须被设置 -# at: src/main/java/org/zstack/aliyun/ecs/EcsInstanceManagerImpl.java:384 +# at: src/main/java/org/zstack/aliyun/ecs/EcsInstanceManagerImpl.java:517 # args: rly1.getVncUrl() decode\ url\ failed\:\ %s = url解码失败: {0} # at: src/main/java/org/zstack/aliyun/ecs/ExportImageFromBSFlow.java:52 # args: -image\ has\ been\ deleted! = +image\ has\ been\ deleted! = 图像已删除! -# at: src/main/java/org/zstack/aliyun/identityzone/SelectValidIdentityZoneFlow.java:50 +# at: src/main/java/org/zstack/aliyun/identityzone/AliyunIdentityZoneBase.java:187 # args: -no\ identity\ chosen,\ may\ be\ stock\ problems = 没有可用区选择,可能是存储问题 +no\ identity\ found = 找不到身份 # at: src/main/java/org/zstack/aliyun/image/EcsImageApiInterceptor.java:71 # args: @@ -320,7 +340,7 @@ can\ not\ delete\ ecs\ system\ image\ remote = 不能删除阿里云服务器上 # at: src/main/java/org/zstack/aliyun/image/EcsImageApiInterceptor.java:142 # args: -Only\ support\ ImageStoreBackupStorage = 用本地镜像创建阿里云上的镜像只支持ImageStore镜像存储 +Only\ support\ ImageStoreBackupStorage = 用本地镜像创建阿里云上的镜像只支持ImageStore镜像服务器 # at: src/main/java/org/zstack/aliyun/image/EcsImageApiInterceptor.java:145 # args: @@ -352,123 +372,127 @@ the\ indicated\ image\ [%s]\ is\ importing\ to\ datacenter\ [%s]\ now... = 指 # at: src/main/java/org/zstack/aliyun/nas/core/AliyunNasApiInterceptor.java:44 # args: psUuids.toString() -PrimaryStorage\ [%s]\ still\ running,\ can\ not\ delete\ access\ group = +PrimaryStorage\ [%s]\ still\ running,\ can\ not\ delete\ access\ group = PrimaryStorage[{0}]仍在运行,无法删除访问组 # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasBase.java:194 # args: msg.getSourceCidrIp(),msg.getAccessGroupUuid() -access\ group\ rule\ [%s]\ already\ existed\ in\ access\ group\ [%s] = +access\ group\ rule\ [%s]\ already\ existed\ in\ access\ group\ [%s] = 访问组规则[{0}]已存在于访问组[{1}]中 # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasBase.java:849 # args: msg.getName(),msg.getDataCenterUuid() -access\ group\ [%s]\ already\ existed\ in\ datacenter\ [%s] = +access\ group\ [%s]\ already\ existed\ in\ datacenter\ [%s] = 数据中心[{1}]中已存在访问组[{0}] # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasFileSystemBase.java:150 # args: self.getFileSystemId(),regionId -no\ filesystem\ [%s]\ found\ in\ region\:\ %s = +no\ filesystem\ [%s]\ found\ in\ region\:\ %s = 在数据中心{1}中找不到文件系统[{0}] # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasFileSystemBase.java:203 # args: msg.getDataCenterUuid() -nas\ filesystem\ existed\ in\ datacenter\:\ %s = +nas\ filesystem\ existed\ in\ datacenter\:\ %s = NAS文件系统存在于数据中心:{0} # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasFileSystemBase.java:304 # args: refs.toString() -some\ primary\ storage\ [%s]\ used\ this\ nas,\ can\ not\ delete\ it\ until\ delete\ the\ primary\ storage. = +some\ primary\ storage\ [%s]\ used\ this\ nas,\ can\ not\ delete\ it\ until\ delete\ the\ primary\ storage. = 某个主存储[{0}]使用了此NAS,在删除主存储之前无法将其删除。 # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java:314 # args: cmsg.getWait() -mount\ domain\ not\ valid\ after\ %d\ milliseconds,\ delete\ it... = +mount\ domain\ not\ valid\ after\ %d\ milliseconds,\ delete\ it... = 装载域在{0}毫秒后无效,请将其删除.. # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java:422 # args: -there\ are\ no\ nas\ access\ group\ existed,\ please\ create\ at\ least\ one = +there\ are\ no\ nas\ access\ group\ existed,\ please\ create\ at\ least\ one = 不存在NAS访问组,请至少创建一个 # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java:404 # args: self.getMountDomain(),self.getNasFileSystemUuid() -no\ such\ mount\ target\ [%s]\ in\ nas\:\ %s = +no\ such\ mount\ target\ [%s]\ in\ nas\:\ %s = NAS中没有这样的装载目标[{0}]:{1} # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java:472 # args: msg.getMountDomain(),msg.getNasFSUuid() -nas\ mount\ target\ [%s]\ existed\ in\ filesystem\:\ %s = +nas\ mount\ target\ [%s]\ existed\ in\ filesystem\:\ %s = 文件系统{1}中存在NAS装载目标[{0}] # at: src/main/java/org/zstack/aliyun/nas/filesystem/AliyunNasMountTargetBase.java:512 # args: self.getAccessGroupUuid() -the\ access\ group\ attached\ is\ already\:\ %s = +the\ access\ group\ attached\ is\ already\:\ %s = 附加的访问组已为:{0} + +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2907 +# args: imageVO.getUuid() +image\ [uuid\:%s]\ has\ been\ deleted = 镜像[uuid:{0}]已经被删除 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:534 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:535 # args: vSwitchUuid -EcsVSwitchVO[%s]\ is\ not\ existed,\ may\ be\ it\ has\ been\ deleted! = +EcsVSwitchVO[%s]\ is\ not\ existed,\ may\ be\ it\ has\ been\ deleted! = ECSVSwitchVO[{0}]不存在,可能已被删除! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:527 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:528 # args: accessGroupUuid -AliyunNasAccessGroupVO[%s]\ is\ not\ existed,\ may\ be\ it\ has\ been\ deleted! = +AliyunNasAccessGroupVO[%s]\ is\ not\ existed,\ may\ be\ it\ has\ been\ deleted! = AliyunNASAccessGroupVO[{0}]不存在,可能已被删除! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:826 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:827 # args: self.getUuid() -cannot\ find\ an\ available\ host\ to\ operation\ in\ primary\ storage\:\ %s = +cannot\ find\ an\ available\ host\ to\ operation\ in\ primary\ storage\:\ %s = 在主存储中找不到可用于操作的物理机:{0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:905 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:906 # args: self.getUuid(),hostUuid,rsp.error -failed\ to\ ping\ aliyun\ nas\ primary\ storage[uuid\:%s]\ from\ host[uuid\:%s],because\ %s.\ disconnect\ this\ host-ps\ connection = +failed\ to\ ping\ aliyun\ nas\ primary\ storage[uuid\:%s]\ from\ host[uuid\:%s],because\ %s.\ disconnect\ this\ host-ps\ connection = 无法从物理机[uuid:{1}]Ping Aliyun NAS主存储[uuid:{0}],因为{2}。断开此物理机-PS连接 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:1393 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:1394 # args: -nas\ primary\ storage\ not\ mounted,\ please\ init\ it\ first! = +nas\ primary\ storage\ not\ mounted,\ please\ init\ it\ first! = NAS主存储未装载,请先将其初始化! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:1577 -# args: bsType -cannot\ find\ any\ BackupStorageKvmFactory\ for\ the\ type[%s] = - -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2003 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2004 # args: vol.getUuid() -cannot\ find\ host\ to\ operate\ volume\:\ [%s] = +cannot\ find\ host\ to\ operate\ volume\:\ [%s] = 找不到操作卷[{0}]的物理机 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2240 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2241 # args: self.getUuid() -cannot\ find\ and\ host\ to\ sync\ volume\ size\ in\ primary\:\ %s = +cannot\ find\ and\ host\ to\ sync\ volume\ size\ in\ primary\:\ %s = 在主节点中找不到要同步卷大小的物理机:{0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2267 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2268 # args: -image\ [%s]\ has\ been\ deleted,\ cannot\ reinit\ root\ volume\ from\ it = +image\ [%s]\ has\ been\ deleted,\ cannot\ reinit\ root\ volume\ from\ it = 镜像[{0}]已删除,无法从中重新初始化根卷 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2422 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2423 # args: -no\ available\ host\ could\ check\ mountPath! = +no\ available\ host\ could\ check\ mountPath! = 没有可用的物理机可以检查装载路径! -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2649 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2653 # args: String.join(",", msg.getBackupStorageUuids()),errorCodes.getCauses().get(0).getDetails() unable\ to\ allocate\ backup\ storage\ specified\ by\ uuids\:\ %s,\ becasue\:\ %s = 不能给uuid列表{0}分配镜像服务器,因为{1} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2817 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmBackend.java:2795 # args: bsvo.getType() -aliyun\ nas\ primarystorage\ only\ support\ imagestore\ bs,\ actually\ get\ type\:\ %s = +aliyun\ nas\ primarystorage\ only\ support\ imagestore\ bs,\ actually\ get\ type\:\ %s = 阿里云NAS PrimaryStorage仅支持ImageStore BS,实际获取类型:{0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:158 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:161 # args: context.getInventory().getUuid(),context.getInventory().getName(),mine,e.getKey(),version,QCOW3_QEMU_IMG_VERSION,QCOW3_QEMU_IMG_VERSION unable\ to\ attach\ a\ primary\ storage\ to\ cluster.\ Kvm\ host[uuid\:%s,\ name\:%s]\ in\ cluster\ has\ qemu-img\ with\ version[%s];\ but\ the\ primary\ storage\ has\ attached\ to\ a\ cluster\ that\ has\ kvm\ host[uuid\:%s],\ which\ has\ qemu-img\ with\ version[%s].\ qemu-img\ version\ greater\ than\ %s\ is\ incompatible\ with\ versions\ less\ than\ %s,\ this\ will\ causes\ volume\ snapshot\ operation\ to\ fail.\ Please\ avoid\ attaching\ a\ primary\ storage\ to\ clusters\ that\ have\ different\ Linux\ distributions,\ in\ order\ to\ prevent\ qemu-img\ version\ mismatch = 不能挂载主存储到集群。集群中的物理机[uuid:{0}, name:{1}]拥有[{2}]版本的qemu-img;但是主存储已经挂载到拥有[{4}]版本qemu-img的集群上。版本大于{5}的qemu-img不兼容版本小于{6},这将会造成云盘快照操作失败。为了防止qemu-img版本不兼容,请避免挂载主存储到物理机装有不同linux版本的集群 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:342 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunKvmFactory.java:344 # args: -no\ available\ host\ could\ download\ imagecache! = +no\ available\ host\ could\ download\ imagecache! = 没有可用的物理机可以下载ImageCache! + +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:1147 +# args: msg.getResourceUuid() +resource[uuid\:\ %s]\ cannot\ found = 找不到资源[uuid:{0}] -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:69 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:75 # args: self.getUuid(),self.getName() -the\ aliyun\ nas\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = +the\ aliyun\ nas\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = Aliyun NAS主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:192 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:208 # args: self.getUuid(),self.getName() -the\ aliyun\ nas\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ delete\ bits\ on\ primarystorage = +the\ aliyun\ nas\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ delete\ bits\ on\ primarystorage = Aliyun NAS主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于主存储删除位的物理机 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:555 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:619 # args: self.getUuid(),self.getName() -the\ Aliyun\ Nas\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = +the\ Aliyun\ Nas\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = 阿里云NAS主存储[uuid:{0},名称:{1}]未挂接任何集群,或挂接的集群中没有物理机 -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:856 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:936 # args: hostUuid -failed\ to\ check\ mount\ path\ on\ host\:\ %s = +failed\ to\ check\ mount\ path\ on\ host\:\ %s = 无法检查物理机上的装载路径:{0} -# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:943 +# at: src/main/java/org/zstack/aliyun/nas/storage/primary/AliyunNasPrimaryStorageBase.java:1023 # args: -cannot\ find\ a\ host\ to\ cleanup\ image\ cache. = +cannot\ find\ a\ host\ to\ cleanup\ image\ cache. = 找不到用于清除镜像缓存的物理机。 # at: src/main/java/org/zstack/aliyun/network/AliyunNetworkServiceBase.java:533 # args: eipVo.getAllocateResourceUuid() @@ -502,11 +526,11 @@ custom\ cidr\ [%s]\ is\ already\ existed\ in\ vbr\ [%s],\ it\ is\ overlapped\ wi # args: tuple.get(0, String.class),vRouterUuid,cidr custom\ cidr\ [%s]\ is\ already\ existed\ in\ vrouter\ [%s],\ it\ is\ overlapped\ with\ target\ cidr\ [%s],\ please\ check\ and\ delete\ it\ first. = 原始的CIDR[{0}]已经存在于虚拟路由器中[{1}],已经被目标CIDR所覆盖,请先检验然后删除它 -# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:50 +# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:51 # args: msg.getL3networkUuid() No\ Such\ Cidr\ found\ for\ l3network\:\ %s = 未找到三层网络{0}对应的CIDR -# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:40 +# at: src/main/java/org/zstack/aliyun/network/connection/GetCidrsFlow.java:42 # args: msg.getL3networkUuid() No\ Such\ VRouter\ nic\ found\ for\ l3network\:\ %s = 未找到三层网络{0}对应的虚拟路由器网卡 @@ -560,19 +584,19 @@ OssBucket[%s]\ is\ not\ attached. = oss Bucket[{0}]没有被添加 # at: src/main/java/org/zstack/aliyun/oss/EcsOssManagerImpl.java:114 # args: -domain,\ key,\ secret\ must\ be\ set\ all = +domain,\ key,\ secret\ must\ be\ set\ all = 域、密钥、机密必须全部设置 -# at: src/main/java/org/zstack/aliyun/oss/OssBucketCascadeExtension.java:106 +# at: src/main/java/org/zstack/aliyun/oss/OssBucketCascadeExtension.java:107 # args: oss\ bucket\ is\ not\ empty! = oss Bucket不为空 # at: src/main/java/org/zstack/aliyun/pangu/AliyunPanguApiInterceptor.java:39 # args: appName,partitionName,vo.getIdentityZoneUuid() -appName\:\ %s,\ partitionName\:\ %s\ is\ existed\ in\ identityZone\:\ %s = +appName\:\ %s,\ partitionName\:\ %s\ is\ existed\ in\ identityZone\:\ %s = AppName:{0},PartitionName:{1}存在于IdentityZone:{2}中 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:62 # args: -Root\ volume\ cannot\ be\ deleted = 根云盘不能被删除 +Root\ volume\ cannot\ be\ deleted = 云盘不能被删除 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:83 # args: @@ -592,7 +616,7 @@ The\ state\ of\ the\ ecs\ [%s]\ instance\ must\ be\ running\ or\ stopped = 云 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:105 # args: -Only\ data\ disk\ can\ be\ mounted\ on\ ecs = 只有数据云盘可以挂装到云主机上 +Only\ data\ disk\ can\ be\ mounted\ on\ ecs = 只有云盘可以挂装到云主机上 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:109 # args: @@ -612,7 +636,7 @@ The\ disk\ [%s]\ is\ already\ mounted\ on\ the\ instance\ [%s] = 云盘[{0}]已 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:135 # args: -Only\ data\ disk\ can\ attach\ to\ ecs = 只有数据云盘能加载到云服务器 +Only\ data\ disk\ can\ attach\ to\ ecs = 只有云盘能加载到云服务器 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:139 # args: @@ -624,7 +648,7 @@ The\ size\ and\ snapshot\ id\ in\ the\ request\ parameter\ must\ select\ one\ of # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:167 # args: -Not\ allowed\ create\ disk\ on\ root\ volume\ snapshot = 不允许在根云盘快照上创建云盘 +Not\ allowed\ create\ disk\ on\ root\ volume\ snapshot = 不允许在云盘快照上创建云盘 # at: src/main/java/org/zstack/aliyun/storage/disk/AliyunDiskApiInterceptor.java:176 # args: @@ -636,303 +660,407 @@ The\ operation\ allows\ only\ when\ ecs\ state\ of\ the\ ecs\ instance\ status\ # at: src/main/java/org/zstack/apimediator/ApiValidator.java:60 # args: hostname,newBS -More\ than\ one\ BackupStorage\ on\ the\ same\ host\ identified\ by\ hostname.\ There\ has\ been\ a\ SftpBackupStorage\ [hostname\:%s]\ existing.\ The\ BackupStorage\ type\ to\ be\ added\ is\ %s.\ = 有超过一个镜像服务器拥有相同的主机名,已经存在一个 SFTP 镜像服务器 [主机名:{0}],被添加的镜像存储类型为 {1} +More\ than\ one\ BackupStorage\ on\ the\ same\ host\ identified\ by\ hostname.\ There\ has\ been\ a\ SftpBackupStorage\ [hostname\:%s]\ existing.\ The\ BackupStorage\ type\ to\ be\ added\ is\ %s.\ = 有超过一个镜像服务器拥有相同的物理机名,已经存在一个 SFTP 镜像服务器 [物理机名:{0}],被添加的镜像服务器类型为 {1} # at: src/main/java/org/zstack/apimediator/ApiValidator.java:68 # args: hostname,newBS -More\ than\ one\ BackupStorage\ on\ the\ same\ host\ identified\ by\ hostname.\ There\ has\ been\ an\ ImageStoreBackupStorage\ [hostname\:%s]\ existing.\ The\ BackupStorage\ type\ to\ be\ added\ is\ %s.\ = 有超过一个镜像服务器拥有相同的主机名,已经存在一个镜像服务器 [主机名:{0}],被添加的镜像存储类型为 {1} +More\ than\ one\ BackupStorage\ on\ the\ same\ host\ identified\ by\ hostname.\ There\ has\ been\ an\ ImageStoreBackupStorage\ [hostname\:%s]\ existing.\ The\ BackupStorage\ type\ to\ be\ added\ is\ %s.\ = 有超过一个镜像服务器拥有相同的物理机名,已经存在一个镜像服务器 [物理机名:{0}],被添加的镜像服务器类型为 {1} -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:129 -# args: self.getUuid(),getSelf().getStatus(),msg.getPath() -appliance\ vm[uuid\:%s]\ is\ in\ status\ of\ %s\ that\ cannot\ make\ http\ call\ to\ %s = 系统虚拟机[uuid:{0}]处于{1}状态,无法对[{2}]执行HTTP RPC调用 +# at: src/main/java/org/zstack/appcenter/AppCenterManagerImpl.java:486 +# args: msg.getAppUuid() +PublishAppVO[uuid\:\ %s]\ is\ not\ existed = PublishAppVO[uuid:{0}]不存在 -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:413 -# args: getSelf().getUuid() -appliance\ vm\ %s\ stopped = +# at: src/main/java/org/zstack/appcenter/AppCenterManagerImpl.java:588 +# args: +[appcenter]\ filterName\ must\ be\ appcenter\:true\ or\ appcenter\:false = [appCenter]FilterName必须为appCenter:true或appCenter:false -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:482 -# args: getSelf().getUuid() -appliance\ vm\ %s\ destroyed = +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:127 +# args: struct.getParamName() +%s\ is\ in\ preParameters,\ but\ not\ be\ set = {0}在前参数中,但未设置 -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:543 -# args: getSelf().getUuid() -appliance\ vm\ %s\ reboot = +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:131 +# args: +%s\ need\ Number\ value,\ but\ got\ wrong\ type = {0}需要数值,但类型错误 -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:553 -# args: getSelf().getUuid() -appliance\ vm\ %s\ reboot\ failed = +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:136 +# args: +%s\ need\ Boolean\ value,\ but\ got\ wrong\ type = {0}需要布尔值,但类型错误 -# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:606 -# args: getSelf().getUuid() -appliance\ vm\ %s\ start\ failed = +# at: src/main/java/org/zstack/appcenter/ZStackAppCenterBase.java:141 +# args: +%s\ need\ String\ value,\ but\ got\ wrong\ type = {0}需要字符串值,但获取的类型错误 -# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:116 -# args: msg.getUuid(),uuid -listener[uuid\:%s]\ are\ being\ used\ by\ the\ autoScalingVmTemplate[%s]\ and\ cannot\ be\ deleted = +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:389 +# args: msg.getBuildSystemUuid() +cannot\ find\ build\ system\ [%s] = 找不到生成系统[{0}] -# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:148 -# args: msg.getAlarmUuid(),ruleVO.getScalingGroupUuid() -alarm[uuid\:%s]\ are\ being\ used\ by\ the\ autoScalingGroup[%s]\ which\ cannot\ be\ deleted = +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:339 +# args: msg.getBuildSystemUuid(),msg.getZoneUuid() +build\ system[uuid\:\ %s]\ has\ been\ attached\ to\ zone[uuid\:\ %s] = 生成系统[uuid:{0}]已附加到区域[uuid:{1}] -# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:158 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:396 +# args: msg.getBuildSystemUuid(),msg.getZoneUuid() +build\ system[uuid\:\ %s]\ has\ not\ been\ attached\ to\ zone[uuid\:\ %s] = 生成系统[uuid:{0}]尚未附加到区域[uuid:{1}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:620 +# args: appUuid +cannot\ find\ build\ application\:\ [%s] = 找不到生成应用程序:[{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:989 +# args: +imageStore\ is\ not\ Enabled = 未启用ImageStore + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:993 +# args: +imageStore\ is\ not\ Connected = ImageStore未连接 + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:1147 +# args: p.getDefaultValue() +cannot\ find\ imageUuid\ for\ image[%s] = 找不到镜像[{0}]的ImageUuid + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemImpl.java:1159 # args: msg.getUuid() -rule[%s]\ state\ is\ Disabled = +cannot\ find\ build-app[uuid\:\ %s],\ or\ it\ was\ in\ Deleting\ status = 找不到Build-App[uuid:{0}],或者它处于删除状态 -# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:314 -# args: l3Uuids,uuid -invalid\ l3\ network\ uuids[%s]\ for\ listener\ that\ belongs\ lb[%s],\ all\ the\ networks\ must\ be\ attached\ the\ LB\ service\ and\ be\ attached\ with\ the\ same\ vRouter\ with\ LB = +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:50 +# args: msg.getUuid() +build-app[%s]\ is\ exported\ or\ is\ exporting,\ please\ delete\ it\ first = Build-App[{0}]已导出或正在导出,请先删除它 -# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:626 -# args: msg.getTemplateUuid(),JSONObjectUtil.toJsonString(errors) -detach\ autoScalingTemplate[%s]\ from\ AutoScalingGroup\ failed,\ errors\ are\ %s = +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:63 +# args: build.getUuid(),build.getName(),build.getHostname(),build.getUrl() +another\ build\ system[uuid\:\ %s,\ name\:\ %s]\ in\ this\ host[%s]\ used\ the\ url[%s] = 此物理机[{2}]中的另一个生成系统[uuid:{0},名称:{1}]使用了URL[{3}] -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:933 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:74 +# args: msg.getDataPath() +dataPath\ must\ start\ with\ '/',\ actually\ got\ [%s] = 数据路径必须以“/”开头,实际获得[{0}] + +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:88 # args: -rootDiskOfferingUuid\ cannot\ be\ null\ when\ image\ mediaType\ is\ ISO = 根云盘规格不能为空在镜像类型为ISO时 +both\ backupStorageUuid\ and\ hostname\ are\ null = backupStorageUuid和hostname均为空 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:913 -# args: instanceOfferingVO.getUuid() -instance\ offering[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = 计算规格[uuid:{0}]没有被启用,不能根据该规格创建云主机 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:95 +# args: msg.getHostname() +cannot\ find\ imageStore\ which\ hostname\ is\ \:%s = 找不到物理机名为{0}的ImageStore -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:916 -# args: instanceOfferingVO.getUuid(),instanceOfferingVO.getType() -instance\ offering[uuid\:%s,\ type\:%s]\ is\ not\ UserVm\ type,\ can't\ create\ vm\ from\ it = 计算规格[uuid:{0}, type:{1}]不是UserVm类型,不能通过它创建虚拟机 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:98 +# args: msg.getHostname() +find\ more\ than\ one\ imageStore\ which\ hostname\ is\:\ %s,\ please\ use\ backupStorageUuid\ instead = 找到多个物理机名为{0}的ImageStore,请改用BackupStorageUuid -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:924 -# args: imageVO.getUuid() -image[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = 镜像[uuid:{0}]没被启用,不能根据该镜像创建云主机 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:102 +# args: +both\ backupStorageUuid\ and\ hostname\ are\ set,\ but\ they\ are\ not\ the\ same\ host = 同时设置了backupStorageuuid和hostname,但它们不是同一物理机 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:927 -# args: imageVO.getUuid() -image[uuid\:%s]\ is\ not\ ready\ yet,\ can't\ create\ vm\ from\ it = +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:116 +# args: +buildAppUuid\ and\ exportId\ cannot\ both\ be\ null = BuildAppuuid和ExportId不能同时为空 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:930 -# args: imageVO.getUuid(),imageVO.getMediaType() -image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ and\ ISO\ can\ be\ used\ to\ create\ vm = 镜像[uuid:{0}] 类型为{1},只能用RootVolumeTemplate和ISO来创建云主机 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:120 +# args: +buildAppUuid\ and\ buildSystemUuid\ cannot\ both\ be\ null = BuildAppUuid和BuildSystemUuid不能同时为空 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:937 -# args: imageVO.getUuid() -image[uuid\:%s]\ is\ system\ image,\ can't\ be\ used\ to\ create\ user\ vm = 镜像[uuid:{0}] 是系统镜像,不能使用它创建用户虚拟机 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:126 +# args: +no\ such\ exportId\ in\ build\ export\ history = 在生成导出历史记录中没有这样的导出ID -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:949 -# args: diskOfferingVO.getUuid() -disk\ offerings[uuids\:%s]\ are\ Disabled,\ can\ not\ create\ vm\ from\ it = 云盘规格[uuids:{0}]没有被启用,不能使用它创建云主机 +# at: src/main/java/org/zstack/appcenter/buildsystem/AppBuildSystemInterceptor.java:130 +# args: +both\ exportId\ and\ buildAppUuid\ are\ set\ but\ they\ are\ not\ equal = 同时设置了ExportId和BuildAppUuid,但它们不相等 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:963 -# args: l3Uuid -l3Network[uuid\:%s]\ is\ Disabled,\ can\ not\ create\ vm\ on\ it = L3网络[uuid:{0}]没有被启用,不能从这个L3网络创建云主机 +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:108 +# args: self.getStatus() +unable\ to\ do\ the\ operation\ because\ the\ build\ system\ is\ in\ status\ of\ %s = 无法执行该操作,因为生成系统处于{0}状态 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:966 -# args: l3Uuid -l3Network[uuid\:%s]\ is\ system\ network,\ can\ not\ create\ user\ vm\ on\ it = L3网络[uuid:{0}]是系统网络,不能在这上面创建云主机 +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:121 +# args: msg.getBuildAppUuid() +cannot\ find\ the\ build\ app\ by\ uuid[%s] = 按uuid[{0}]找不到生成应用程序 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:970 +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:126 +# args: status.toString() +build\ app\ is\ in\ %s\ status,\ which\ can\ not\ support\ the\ current\ operation. = 生成应用程序处于{0}状态,无法支持当前操作。 + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:156 +# args: buildUrl(path),rsp.error +rest\ call\ %s\ failed,\ because\:\ %s = REST调用{0}失败,因为:{1} + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:353 # args: -there\ are\ more\ than\ one\ L3\ network\ specified\ in\ l3NetworkUuids,\ but\ defaultL3NetworkUuid\ is\ null = 在L3网络uuid们中有很多L3网络被指定了,但是默认L3网络的uuid是空的 +build\ application\ is\ disabled\ because\ build\ system\ is\ in\ 'Disabled'\ state = 生成应用程序已禁用,因为生成系统处于“禁用”状态 + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:506 +# args: meta.getAppId(),meta.getVersion().getVersion() +create\ BuildApp\ failed,\ because\ appId[%s\:\ %s]\ is\ duplicated\ by\ another\ BuildApp = 创建BuildApp失败,因为AppId[{0}:{1}]与另一个BuildApp重复 + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:659 +# args: buildUrl(CONNECT_BUILDSYSTEM_PATH),errorCode +unable\ to\ connect\ to\ localstorage\ build\ system[url\:%s],\ because\ %s = 无法连接到localStorage生成系统[URL:{0}],因为{1} + +# at: src/main/java/org/zstack/appcenter/buildsystem/LocalStorageBuildSystemBase.java:762 +# args: struct.getAppId(),struct.getVersion().getVersion() +add\ BuildApp\ failed,\ because\ appId[%s\:%s]\ is\ duplicated\ by\ another\ BuildApp = 添加BuildApp失败,因为AppId[{0}:{1}]与另一个BuildApp重复 + +# at: src/main/java/org/zstack/appcenter/utils/AppCenterUtils.java:48 +# args: file +cannot\ find\ raw-template\ json\ file\ at\:\ %s = 在{0}处找不到原始模板JSON文件 + +# at: src/main/java/org/zstack/appcenter/utils/AppCenterUtils.java:61 +# args: e +Unable\ to\ create\ json\ template = 无法创建JSON模板 + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java:108 +# args: l2NetworkVO.getUuid() +there\ is\ no\ available\ nicType\ on\ L2\ network\ [%s] = 二层网络[{0}]上没有可用的nicType + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:136 +# args: self.getUuid(),getSelf().getStatus(),msg.getPath() +appliance\ vm[uuid\:%s]\ is\ in\ status\ of\ %s\ that\ cannot\ make\ http\ call\ to\ %s = 系统云主机[uuid:{0}]处于{1}状态,无法对[{2}]执行HTTP RPC调用 + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:430 +# args: getSelf().getUuid() +appliance\ vm\ %s\ stopped = 应用装置VM{0}已停止 + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:709 +# args: getSelf().getUuid() +appliance\ vm\ %s\ reboot = 应用装置云主机{0}重新启动 + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:719 +# args: getSelf().getUuid() +appliance\ vm\ %s\ reboot\ failed = 应用装置云主机{0}重新启动失败 + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmBase.java:781 +# args: getSelf().getUuid() +appliance\ vm\ %s\ start\ failed = 应用装置VM{0}启动失败 + +# at: src/main/java/org/zstack/appliancevm/ApplianceVmKvmBootstrapFlow.java:64 +# args: rsp.getError() +set\ appliance\ bootstrapinfo\ error,\ because\:%s = 设置装置BootstrapInfo错误,原因:{0} + +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:120 +# args: msg.getUuid(),uuid +listener[uuid\:%s]\ are\ being\ used\ by\ the\ autoScalingVmTemplate[%s]\ and\ cannot\ be\ deleted = 侦听器[uuid:{0}]正由AutoScalingVMTemplate[{1}]使用,无法删除 + +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:131 +# args: msg.getInstanceUuid(),msg.getGroupUuid() +The\ instance[%s]\ does\ not\ exist\ in\ the\ scaling\ group[%s] = 缩放组[{1}]中不存在实例[{0}] + +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:163 +# args: msg.getAlarmUuid(),ruleVO.getScalingGroupUuid() +alarm[uuid\:%s]\ are\ being\ used\ by\ the\ autoScalingGroup[%s]\ which\ cannot\ be\ deleted = 无法删除的AutoScalingGroup[{1}]正在使用报警[uuid:{0}] + +# at: src/main/java/org/zstack/autoscaling/AutoScalingInterceptor.java:173 +# args: msg.getUuid() +rule[%s]\ state\ is\ Disabled = 规则[{0}]状态已禁用 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:409 +# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:386 +# args: l3Uuids,uuid +invalid\ l3\ network\ uuids[%s]\ for\ listener\ that\ belongs\ lb[%s],\ all\ the\ networks\ must\ be\ attached\ the\ LB\ service\ and\ be\ attached\ with\ the\ same\ vRouter\ with\ LB = 属于LB[{1}]的侦听器的三层网络uuid[{0}]无效,所有网络都必须附加到LB服务,并且必须附加到与LB相同的VRouter + +# at: src/main/java/org/zstack/autoscaling/AutoScalingManagerImpl.java:744 +# args: msg.getTemplateUuid(),JSONObjectUtil.toJsonString(errors) +detach\ autoScalingTemplate[%s]\ from\ AutoScalingGroup\ failed,\ errors\ are\ %s = 从AutoScalingGroup分离AutoScalingTemplate[{0}]失败,错误为{1} + +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:890 +# args: imageVO.getUuid(),imageVO.getMediaType() +image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ and\ ISO\ can\ be\ used\ to\ create\ vm = 镜像[uuid:{0}] 类型为{1},只能用RootVolumeTemplate和ISO来创建云主机 + +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:893 # args: -Only\ one\ scaling\ activity\ can\ be\ executed\ in\ the\ same\ scaling\ group\ at\ the\ same\ time. = +rootDiskOfferingUuid\ cannot\ be\ null\ when\ image\ mediaType\ is\ ISO = 云盘规格不能为空在镜像类型为ISO时 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1330 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:367 # args: -The\ number\ of\ instances\ exceeds\ the\ limit = +Only\ one\ scaling\ activity\ can\ be\ executed\ in\ the\ same\ scaling\ group\ at\ the\ same\ time. = 同一伸缩组中同一时间只能执行一个伸缩活动。 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:637 -# args: msg.getAutoScalingGroupUuid(),JSONObjectUtil.toJsonString(errors) -autoScalingGroup[%s]\ create\ vms\ failed\ completely,\ errors\ are\ %s = +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1317 +# args: +The\ number\ of\ instances\ exceeds\ the\ limit = 实例数超过限制 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:685 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:645 # args: loadBalancerListenerUuidListStr -add\ vm\ nic\ to\ loadBalancer\ failed,\ No\ loadBalancer[uuids\=%s]\ can\ be\ found. = +add\ vm\ nic\ to\ loadBalancer\ failed,\ No\ loadBalancer[uuids\=%s]\ can\ be\ found. = 将VM NIC添加到LoadBalancer失败,找不到LoadBalancer[uuid={0}]。 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:724 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:684 # args: msg.getAutoScalingGroupUuid(),JSONObjectUtil.toJsonString(addVmNicToLoadBalancerErrorCodes) -autoScalingGroup[%s]\ add\ newly\ created\ vm\ to\ loadBalancer\ failed\ completely,\ errors\ are\ %s = +autoScalingGroup[%s]\ add\ newly\ created\ vm\ to\ loadBalancer\ failed\ completely,\ errors\ are\ %s = AutoScalingGroup[{0}]将新创建的VM添加到LoadBalancer完全失败,错误为{1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:759 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:719 # args: securityGroupUuid -add\ vm\ nic\ to\ securityGroup\ failed,\ No\ securityGroup[uuid\=%s]\ can\ be\ found. = +add\ vm\ nic\ to\ securityGroup\ failed,\ No\ securityGroup[uuid\=%s]\ can\ be\ found. = 将VM NIC添加到SecurityGroup失败,找不到SecurityGroup[uuid={0}]。 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:795 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:755 # args: msg.getAutoScalingGroupUuid(),JSONObjectUtil.toJsonString(addVmNicToSecurityGroupErrorCodes) -autoScalingGroup[%s]\ add\ newly\ created\ vm\ to\ securityGroup\ failed\ completely,\ errors\ are\ %s = +autoScalingGroup[%s]\ add\ newly\ created\ vm\ to\ securityGroup\ failed\ completely,\ errors\ are\ %s = AutoScalingGroup[{0}]将新创建的VM添加到SecurityGroup完全失败,错误为{1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:905 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:865 # args: templateGroupRefVO.getTemplateUuid() -A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:AutoScalingVmTemplateVO]\ not\ found = +A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:AutoScalingVmTemplateVO]\ not\ found = 找不到资源,详细信息:找不到资源[uuid:{0},类型:AutoScalingVMTemplateVo] -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:910 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:870 # args: vmTemplateVO.getVmInstanceOfferingUuid() -A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:InstanceOfferingVO]\ not\ found = +A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:InstanceOfferingVO]\ not\ found = 找不到资源,详细信息:找不到资源[uuid:{0},类型:InstanceOfferingVO] -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:921 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:881 # args: vmTemplateVO.getImageUuid() -A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:ImageVO]\ not\ found = +A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:ImageVO]\ not\ found = 找不到资源,详细信息:找不到资源[uuid:{0},类型:ImageVO] -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:945 -# args: diskOfferingVO.getUuid() -A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:DiskOfferingVO]\ not\ found = +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:905 +# args: diskOffering +A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:DiskOfferingVO]\ not\ found = 找不到资源,详细信息:找不到资源[uuid:{0},类型:DiskOfferingVO] -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:958 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:918 # args: l3Uuid -A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:L3NetworkVO]\ not\ found = +A\ resource\ can\ not\ be\ found,\ details\:\ resource[uuid\:%s,\ type\:L3NetworkVO]\ not\ found = 找不到资源,详细信息:找不到资源[uuid:{0},类型:L3NetworkVO] -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:974 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:934 # args: vmTemplateVO.getDefaultL3NetworkUuid(),l3Uuids -defaultL3NetworkUuid[uuid\:%s]\ is\ not\ in\ l3NetworkUuids\ %s = +defaultL3NetworkUuid[uuid\:%s]\ is\ not\ in\ l3NetworkUuids\ %s = 默认L3NetworkUuid[Uuid:{0}]不在L3NetworkUuids{1}中 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1047 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1018 # args: self.getUuid(),AutoScalingGroupState.Enabled.toString() -the\ auto\ scaling\ group[%s]\ state\ error,\ expected\:\ %s\ state = +the\ auto\ scaling\ group[%s]\ state\ error,\ expected\:\ %s\ state = 自动缩放组[{0}]状态错误,应为:{1}状态 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1084 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1055 # args: self.getUuid() -The\ autoScalingGroup[%s]\ not\ attach\ any\ vm\ template = +The\ autoScalingGroup[%s]\ not\ attach\ any\ vm\ template = AutoScalingGroup[{0}]未附加任何VM模板 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1138 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1123 # args: self.getUuid(),vmInstanceUuids,JSONObjectUtil.toJsonString(errors) -autoScalingGroup[%s]\ destroy\ vms[%s]\ failed\ completely,\ errors\ are\ %s = +autoScalingGroup[%s]\ destroy\ vms[%s]\ failed\ completely,\ errors\ are\ %s = AutoScalingGroup[{0}]销毁云主机[{1}]完全失败,错误为{2} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1343 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1330 # args: -Cannot\ find\ deleted\ target\ instance\ list = +Cannot\ find\ deleted\ target\ instance\ list = 找不到已删除的目标实例列表 # at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1569 # args: -need\ skip\ autoScalingGroup\ activity = +need\ skip\ autoScalingGroup\ activity = 需要跳过自动缩放组活动 -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1820 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:1835 # args: ruleUuid,JSONObjectUtil.toJsonString(errors) -delete\ autoScalingRule[%s]\ triggers\ failed,\ errors\ are\ %s = +delete\ autoScalingRule[%s]\ triggers\ failed,\ errors\ are\ %s = 删除AutoScalingRule[{0}]触发器失败,错误为{1} -# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:2437 +# at: src/main/java/org/zstack/autoscaling/group/AutoScalingGroupBase.java:2452 # args: removalPolicy.toString() -Unsupported\ RemovalPolicy[%s]\ type = +Unsupported\ RemovalPolicy[%s]\ type = 不支持RemovalPolicy[{0}]类型 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:63 -# args: address -IPMI\ Address\ %s\ is\ not\ valid = IPMI地址{0}是无效的 +# at: src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java:183 +# args: triggerVO.getUuid(),triggerVO.getState() +AutoScalingRuleSchedulerJobTriggerVO[uuid\:%s]\ is\ %s,\ state\ change\ is\ not\ allowed = AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}]为{1},不允许更改状态 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:69 -# args: -Failed\ to\ reach\ the\ bare-metal\ chassis,\ please\ make\ sure\:\ 1.\ the\ IPMI\ connection\ is\ active;\ 2.\ the\ IPMI\ Address,\ Port,\ Username\ and\ Password\ are\ correct;\ 3.\ IPMI\ Over\ LAN\ is\ enabled\ in\ BIOS. = 无法连通裸金属设备,请确认:1,管理节点与裸金属设备远程控制口连通;2,IPMI地址、端口、账号、密码是正确的;3,BIOS中启用LAN上的IPMI功能。 +# at: src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java:192 +# args: ruleUuid +AutoScalingRuleSchedulerJobTriggerVO[uuid\:%s]\ is\ be\ in\ cooldownDate = AutoScalingRuleSchedulerJobTriggerVO[uuid:{0}]在CooldownDate中 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:84 -# args: address,port -Baremetal\ Chassis\ of\ IPMI\ address\ %s\ and\ IPMI\ port\ %d\ has\ already\ been\ created. = IPMI地址为{0},端口为{1}的裸金属设备已经被创建 +# at: src/main/java/org/zstack/autoscaling/group/rule/AutoScalingRuleManagerImpl.java:250 +# args: ruleUuid,AutoScalingRuleState.Disabled.toString() +AutoScalingRuleVO[uuid\:%s]\ is\ %s,\ state\ change\ is\ not\ allowed = AutoScalingRuleVO[uuid:{0}]为{1},不允许更改状态 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:95 -# args: msg.getClusterUuid() -Cluster[uuid\:%s]\ does\ not\ exists. = 集群[uuid:{0}]不存在 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:64 +# args: +Failed\ to\ reach\ the\ bare-metal\ chassis,\ please\ make\ sure\:\ 1.\ the\ IPMI\ connection\ is\ active;\ 2.\ the\ IPMI\ Address,\ Port,\ Username\ and\ Password\ are\ correct;\ 3.\ IPMI\ Over\ LAN\ is\ enabled\ in\ BIOS. = 无法连通裸金属设备,请确认:1,管理节点与裸金属设备远程控制口连通;2,IPMI地址、端口、账号、密码是正确的;3,BIOS中启用LAN上的IPMI功能。 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:102 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:111 # args: msg.getClusterUuid() Cluster[uuid\:%s]\ is\ not\ a\ baremetal\ cluster. = 集群[uuid:{0}]不是一个裸金属集群 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:108 -# args: msg.getClusterUuid() -Cluster[uuid\:%s]\ is\ not\ Enabled. = 集群[uuid:{0}]处于停用状态 - -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:146 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:155 # args: address,port IPMI\ Address\ and\ Port\ %s\:%d\ already\ exists. = IPMI地址为{0},端口为{1}的裸金属设备已经存在 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:211 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisApiInterceptor.java:220 # args: clusterUuid no\ usable\ baremetal\ pxeserver\ attached\ to\ cluster[uuid\:%s] = 裸金属集群[uuid:{0}]中没有可用的部署服务器 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:153 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:175 # args: chassis.getUuid(),chassis.getPxeServerUuid(),cmd.content baremetal\ chassis[uuid\:%s]\ is\ supposed\ to\ using\ pxeserver[uuid\:%s],\ but\ it\ was\ pxeserver[uuid\:%s]\ that\ actually\ handled\ the\ DHCP\ request = 裸金属设备[uuid:{0}]应当由部署服务器[uuid:{1}]提供DHCP服务,但实际情况是部署服务器[uuid:{2}]提供的DHCP服务 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:639 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:671 # args: msg.getUuid() -failed\ to\ delete\ baremetal\ chassis\ %s = +failed\ to\ delete\ baremetal\ chassis\ %s = 无法删除裸机机箱{0} -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:706 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:737 # args: bmc.getUuid() Failed\ to\ remotely\ power\ on\ baremetal\ chassis[uuid\:%s] = 无法远程启动裸金属设备[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:722 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:753 # args: bmc.getUuid() Failed\ to\ remotely\ power\ reset\ baremetal\ chassis[uuid\:%s] = 无法远程重启裸金属设备[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:733 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:764 # args: bmc.getUuid() Failed\ to\ remotely\ pxe\ boot\ chassis[uuid\:%s] = 无法远程设置裸金属设备[uuid:{0}]从网卡启动 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:901 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:924 # args: bmc.getUuid() failed\ to\ connect\ to\ chassis\ [uuid\:%s],\ please\ check\ ipmi\ connection. = 无法连接到裸金属设备[uuid:{0}], 请确认IPMI连接可用 -# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:987 +# at: src/main/java/org/zstack/baremetal/chassis/BaremetalChassisManagerImpl.java:1010 # args: e.getMessage() fail\ to\ load\ chassis\ info\ from\ file,\ because\:\ %s = 无法从文件中读取裸金属设备信息,因为:{0} -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:66 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:59 # args: msg.getChassisUuid() -Baremetal\ chassis[uuid\:%s]\ does\ not\ exist = +Baremetal\ chassis[uuid\:%s]\ does\ not\ exist = 裸机机箱[uuid:{0}]不存在 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:72 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:65 # args: chassis.getUuid() Baremetal\ chassis[uuid\:%s]\ is\ not\ Enabled\ or\ Available,\ please\ choose\ another\ one. = 裸金属设备[uuid:{0}]被停用或者已被分配,请重新选择 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:78 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:71 # args: chassis.getUuid() no\ corresponding\ pxeserver,\ please\ inspect\ baremetal\ chassis[uuid\:%s]\ again = 裸金属设备[uuid:{0}]没有关联部署服务器,请重新获取硬件信息 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:91 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:84 # args: chassis.getUuid() No\ hardware\ info\ found\ for\ baremetal\ chassis[uuid\:%s],\ please\ choose\ another\ one. = 裸金属设备[uuid:{0}]硬件信息未知,请重新选择 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:102 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:95 # args: chassis.getPxeServerUuid() -baremetal\ pxeserver[uuid\:%s]\ is\ neither\ Enabled\ nor\ Connected,\ please\ check = +baremetal\ pxeserver[uuid\:%s]\ is\ neither\ Enabled\ nor\ Connected,\ please\ check = Baremetal Pxeserver[uuid:{0}]既未启用也未连接,请检查 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:119 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:112 # args: mac Mac\ address\ %s\ is\ invalid.\ It\ should\ be\ like\ 6c\:b3\:11\:1b\:0b\:1e = MAC地址{0}不合法 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:125 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:118 # args: chassis.getUuid(),mac Baremetal\ chassis[uuid\:%s]\ doesn't\ have\ nic\ with\ mac\ address\ %s = 裸金属设备[uuid:{0}]硬件信息中未发现MAC地址为{1}的网卡 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:143 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:136 # args: -duplicated\ bm\ bonding\ uuid\ detacted = +duplicated\ bm\ bonding\ uuid\ detacted = 已分离重复的BM绑定uuid -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:147 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:140 # args: -Baremetal\ Bonding\ does\ not\ exist = +Baremetal\ Bonding\ does\ not\ exist = 裸机焊接不存在 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:155 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:148 # args: -duplicated\ l3\ network\ uuid\ detacted = +duplicated\ l3\ network\ uuid\ detacted = 已分离重复的三层网络uuid -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:159 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:152 # args: -the\ selected\ l3\ network\ doesn't\ exist = +the\ selected\ l3\ network\ doesn't\ exist = 选定的三层网络不存在 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:172 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:165 # args: chassis.getUuid() -the\ selected\ l3\ network\ cannot\ be\ assigned\ to\ chassis[uuid\:%s] = +the\ selected\ l3\ network\ cannot\ be\ assigned\ to\ chassis[uuid\:%s] = 无法将选定的三层网络分配给机箱[uuid:{0}] -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:184 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:177 # args: only\ iso\ image\ is\ supported\ in\ zstack\ baremetal\ service = 目前仅支持为裸机部署ISO镜像 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:193 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:186 # args: only\ ImageStoreBackupStorage\ is\ supported\ in\ zstack\ baremetal\ service = 目前仅支持从镜像仓库中为裸机选择ISO镜像 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:207 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:200 # args: -cannot\ recover\ baremetal\ instance\ that's\ not\ in\ Destroyed\ state = 只能恢复处于Destroyed状态的裸金属主机 +cannot\ recover\ baremetal\ instance\ that's\ not\ in\ Destroyed\ state = 只能恢复处于Destroyed状态的裸金属物理机 -# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:219 +# at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceApiInterceptor.java:212 # args: -cannot\ expunge\ baremetal\ instance\ that's\ not\ in\ Destroyed\ state = 只能彻底删除处于Destroyed状态的裸金属主机 +cannot\ expunge\ baremetal\ instance\ that's\ not\ in\ Destroyed\ state = 只能彻底删除处于Destroyed状态的裸金属物理机 # at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceBase.java:461 # args: bmc.getUuid() @@ -944,4315 +1072,7923 @@ failed\ to\ allocate\ baremetal\ pxeserver,\ make\ sure\ there\ is\ a\ pxeserver # at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceBase.java:453 # args: reboot ? "reset" : "on",bmc.getUuid() -Failed\ to\ remotely\ power\ %s\ baremetal\ chassis[uuid\:%s] = +Failed\ to\ remotely\ power\ %s\ baremetal\ chassis[uuid\:%s] = 无法远程启动{0}裸机机箱[uuid:{1}] # at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceManagerImpl.java:1141 # args: msg.getL2NetworkUuid() -there\ are\ bm\ instances\ using\ ip\ address\ allocated\ from\ l2[uuid\:%s] = +there\ are\ bm\ instances\ using\ ip\ address\ allocated\ from\ l2[uuid\:%s] = 存在使用从L2[uuid:{0}]分配的IP地址的BM实例 # at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceManagerImpl.java:1149 # args: msg.getL3NetworkUuid() -there\ are\ bm\ instances\ using\ ip\ address\ allocated\ from\ l3[uuid\:%s] = +there\ are\ bm\ instances\ using\ ip\ address\ allocated\ from\ l3[uuid\:%s] = 存在使用从L3[uuid:{0}]分配的IP地址的BM实例 # at: src/main/java/org/zstack/baremetal/instance/BaremetalInstanceManagerImpl.java:1169 # args: msg.getIpRangeUuid() -there\ are\ bm\ instances\ using\ ip\ address\ allocated\ from\ ip\ range[uuid\:%s] = +there\ are\ bm\ instances\ using\ ip\ address\ allocated\ from\ ip\ range[uuid\:%s] = 存在使用从IP范围[uuid:{0}]分配的IP地址的BM实例 # at: src/main/java/org/zstack/baremetal/network/BaremetalNetworkApiInterceptor.java:39 # args: -creating\ bm\ bonding\ is\ only\ allowed\ before\ creating\ bm\ instance = +creating\ bm\ bonding\ is\ only\ allowed\ before\ creating\ bm\ instance = 只能在创建BM实例之前创建BM绑定 # at: src/main/java/org/zstack/baremetal/network/BaremetalNetworkApiInterceptor.java:48 # args: msg.getName() -bond\ name\ %s\ already\ exists = +bond\ name\ %s\ already\ exists = 结合名称{0}已存在 # at: src/main/java/org/zstack/baremetal/network/BaremetalNetworkApiInterceptor.java:73 # args: slave -Slave\ address\ %s\ is\ invalid.\ It\ should\ be\ like\ 6c\:b3\:11\:1b\:0b\:1e,6c\:b3\:11\:1b\:0b\:1f = +Slave\ address\ %s\ is\ invalid.\ It\ should\ be\ like\ 6c\:b3\:11\:1b\:0b\:1e,6c\:b3\:11\:1b\:0b\:1f = 从属地址{0}无效。它应该类似于6C:B3:11:1B:0B:1E,6C:B3:11:1B:0B:1F # at: src/main/java/org/zstack/baremetal/network/BaremetalNetworkApiInterceptor.java:79 # args: slave,msg.getChassisUuid() -mac\ address\ %s\ does\ not\ belong\ to\ chassis[uuid\:%s] = +mac\ address\ %s\ does\ not\ belong\ to\ chassis[uuid\:%s] = MAC地址{0}不属于机箱[uuid:{1}] # at: src/main/java/org/zstack/baremetal/network/BaremetalNetworkApiInterceptor.java:85 # args: slave -mac\ address\ %s\ is\ already\ a\ bond\ slave = +mac\ address\ %s\ is\ already\ a\ bond\ slave = MAC地址{0}已是绑定从属地址 # at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationApiInterceptor.java:43 # args: -cannot\ update\ predefined\ preconfiguration\ templates = +cannot\ update\ predefined\ preconfiguration\ templates = 无法更新预定义的预配置模板 # at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationApiInterceptor.java:55 # args: -cannot\ delete\ predefined\ preconfiguration\ templates = +cannot\ delete\ predefined\ preconfiguration\ templates = 无法删除预定义的预配置模板 # at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationApiInterceptor.java:63 # args: -cannot\ change\ state\ of\ predefined\ preconfiguration\ templates = +cannot\ change\ state\ of\ predefined\ preconfiguration\ templates = 无法更改预定义的预配置模板的状态 -# at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationManagerImpl.java:65 +# at: src/main/java/org/zstack/baremetal/preconfiguration/PreconfigurationManagerImpl.java:66 # args: msg.getTemplateUuid() -cannot\ find\ PreconfigurationTemplateVO[uuid\:%s],\ it\ may\ have\ been\ deleted = - -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:44 -# args: msg.getClass().getSimpleName() -%s\ can\ only\ be\ called\ by\ admin\ account = {0}只能被admin账户调用 +cannot\ find\ PreconfigurationTemplateVO[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到PreConfigurationTemplateVo[uuid:{0}],它可能已被删除 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:74 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:69 # args: netmask PXE\ Server\ DHCP\ Range\ Netmask\ %s\ is\ invalid. = 部署服务器DHCP服务子网掩码{0}非法 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:80 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:75 # args: begin,end PXE\ Server\ DHCP\ Range\ Start\ %s\ and\ Range\ Stop\ %s\ do\ not\ belong\ to\ the\ same\ subnet. = 部署服务器DHCP地址区间起始IP{0}和结束IP{1}不属于一个子网内 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:88 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:92 # args: msg.getHostname() PXE\ Server\ with\ hostname\ %s\ already\ exists. = 地址为{0}的部署服务器已经存在 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:95 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:103 +# args: msg.getHostname() +there\ is\ already\ a\ baremetal2\ gateway\ with\ management\ ip\ %s,\ do\ not\ use\ it\ to\ create\ baremetal\ pxe\ server = 已存在管理IP为{0}的BareMetal2网关,请不要使用它来创建BareMetal PXE服务器 + +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:110 # args: storagePath\ should\ be\ an\ absolute\ path = 部署服务器的存储路径必须是绝对路径 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:113 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:126 # args: msg.getHostname() failed\ to\ connect\ to\ %s,\ please\ check\ network\ connection\ between\ zstack\ management\ node\ and\ baremetal\ pxeserver = 请检查管理节点与部署服务器{0}之间的网络连接 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:127 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:136 # args: msg.getHostname() no\ local\ repo\ found\ under\ /opt/zstack-dvd\ of\ %s,\ please\ download\ zstack\ iso\ and\ create\ local\ repo\ first = 部署服务器{0}中缺少使用ZStack ISO创建的本地源 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:141 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:146 # args: msg.getDhcpInterface() PXE\ Server\ DHCP\ Interface\ %s\ does\ not\ exists,\ or\ it\ does\ not\ have\ an\ IP\ address. = 部署服务器DHCP接口{0}不存在,或者它没有IP地址 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:150 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:155 # args: msg.getDhcpRangeBegin(),msg.getDhcpRangeEnd(),msg.getDhcpInterface() %s\ ~\ %s\ cannot\ connect\ to\ dhcp\ interface\ %s = {0} ~ {1} 无法连通DHCP监听网卡{2} -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:187 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:192 # args: msg.getClusterUuid(),msg.getPxeServerUuid() cluster[uuid\:%s]\ and\ pxeserver[uuid\:%s]\ don't\ belong\ to\ one\ zone = 裸金属集群[uuid:{0}]和部署服务器[uuid:{1}]不属于同一个区域 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:196 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:201 # args: msg.getClusterUuid() cluster[uuid\:%s]\ is\ not\ baremetal\ cluster = 集群[uuid:{0}]不是一个裸金属集群 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:207 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:212 # args: msg.getPxeServerUuid(),msg.getClusterUuid() baremetal\ pxeserver[uuid\:%s]\ already\ attached\ to\ cluster[uuid\:%s] = 部署服务器[uuid:{0}]已经挂载到裸金属集群[uuid:{1}],无需再次挂载 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:233 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:238 # args: msg.getPxeServerUuid(),msg.getClusterUuid(),ip,begin,end -baremetal\ pxeserver[uuid\:%s]\ is\ not\ compatible\ with\ baremetal\ instances\ in\ cluster[uuid\:%s],\ existing\ nic\ ip\ %s\ is\ out\ of\ pxeserver\ dhcp\ range\ %s\ ~\ %s. = 部署服务器[uuid:{0}]不适合于集群[uuid:{1}],因为集群中已有的裸金属主机网卡地址{2}超出了部署服务器的DHCP范围{3} ~ {4} +baremetal\ pxeserver[uuid\:%s]\ is\ not\ compatible\ with\ baremetal\ instances\ in\ cluster[uuid\:%s],\ existing\ nic\ ip\ %s\ is\ out\ of\ pxeserver\ dhcp\ range\ %s\ ~\ %s. = 部署服务器[uuid:{0}]不适合于集群[uuid:{1}],因为集群中已有的裸金属物理机网卡地址{2}超出了部署服务器的DHCP范围{3} ~ {4} -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:250 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerApiInterceptor.java:255 # args: msg.getPxeServerUuid(),msg.getClusterUuid() baremetal\ pxeserver[uuid\:\ %s]\ not\ attached\ to\ cluster[uuid\:\ %s] = 部署服务器[uuid:{0}]没有挂载到裸金属集群[uuid:{1}] -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:286 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:295 # args: self.getUuid() failed\ to\ init\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = 部署服务器[uuid:{0}]初始化配置失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:423 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:432 # args: self.getUuid() -failed\ to\ create\ bm\ instance\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上创建裸金属主机相关配置失败 +failed\ to\ create\ bm\ instance\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上创建裸金属物理机相关配置失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:454 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:463 # args: self.getUuid() -failed\ to\ delete\ bm\ instance\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上删除裸金属主机相关配置失败 +failed\ to\ delete\ bm\ instance\ configs\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上删除裸金属物理机相关配置失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:485 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:494 # args: self.getUuid() -failed\ to\ create\ bm\ instance\ novnc\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上创建裸金属主机NoVNC代理失败 +failed\ to\ create\ bm\ instance\ novnc\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上创建裸金属物理机NoVNC代理失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:516 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:525 # args: self.getUuid() -failed\ to\ delete\ bm\ instance\ novnc\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上删除裸金属主机NoVNC代理失败 +failed\ to\ delete\ bm\ instance\ novnc\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上删除裸金属物理机NoVNC代理失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:549 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:558 # args: self.getUuid() -failed\ to\ create\ bm\ instance\ nginx\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上创建裸金属主机Nginx代理失败 +failed\ to\ create\ bm\ instance\ nginx\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上创建裸金属物理机Nginx代理失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:580 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:589 # args: self.getUuid() -failed\ to\ delete\ bm\ instance\ nginx\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上删除裸金属主机Nginx代理失败 +failed\ to\ delete\ bm\ instance\ nginx\ proxy\ on\ baremetal\ pxeserver[uuid\:%s] = 在部署服务器[uuid:{0}]上删除裸金属物理机Nginx代理失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:611 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:620 # args: self.getUuid() failed\ to\ start\ baremetal\ pxeserver[uuid\:%s] = 启动部署服务器[uuid:{0}]失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:644 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:653 # args: self.getUuid() failed\ to\ stop\ baremetal\ pxeserver[uuid\:%s] = 停止部署服务器[uuid:{0}]失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:959 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:968 # args: msg.getChassisUuid(),self.getUuid() -failed\ to\ create\ dhcp\ config\ of\ chassis[uuid\:%s]\ on\ pxeserver[uuid\:%s] = +failed\ to\ create\ dhcp\ config\ of\ chassis[uuid\:%s]\ on\ pxeserver[uuid\:%s] = 无法在Pxeserver[uuid:{1}]上创建机箱[uuid:{0}]的DHCP配置 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:988 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:997 # args: msg.getChassisUuid(),self.getUuid() -failed\ to\ delete\ dhcp\ config\ of\ chassis[uuid\:%s]\ on\ pxeserver[uuid\:%s] = +failed\ to\ delete\ dhcp\ config\ of\ chassis[uuid\:%s]\ on\ pxeserver[uuid\:%s] = 无法删除机箱[uuid:{0}](在Pxeserver[uuid:{1}]上)的DHCP配置 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1046 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1055 # args: self.getUuid(),ret.uuid -the\ uuid\ of\ baremtal\ pxeserver\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = +the\ uuid\ of\ baremtal\ pxeserver\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = Baremtal PXEServer代理的uuid已更改[应为:{0},实际为:{1}],代理很可能已手动重新启动。发出重新连接以同步状态 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1229 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1270 # args: url,rsp.error unable\ to\ connect\ to\ baremetal\ pxeserver[url\:%s],\ because\ %s = 连接部署服务器[uuid:{0}]失败,因为: {1} -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1320 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1362 # args: cache.getImageUuid() failed\ to\ mount\ baremetal\ cache\ of\ image[uuid\:%s] = 挂载裸金属镜像缓存[uuid:{0}]失败 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1430 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1467 # args: msg.getImageUuid() no\ enough\ space\ left\ in\ baremetal\ image\ cache\ for\ image[uuid\:%s] = 部署服务器存储路径剩余空间不足 -# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1526 -# args: -unsupported\ backup\ storage\ type\ for\ baremetal = 裸金属管理所不支持的镜像存储类型 - -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:104 +# at: src/main/java/org/zstack/baremetal/pxeserver/BaremetalPxeServerBase.java:1563 # args: -the\ start\ date\ must\ be\ greater\ than\ the\ end\ date = 开始时间必须早于结束时间 +unsupported\ backup\ storage\ type\ for\ baremetal = 裸金属管理所不支持的镜像服务器类型 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:108 -# args: -resourceType\ and\ resourceUuid\ cannot\ be\ empty\ at\ the\ same\ time = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:59 +# args: msg.getName() +bond\ name\ %s\ has\ been\ existed = 债券名称{0}已存在 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:226 -# args: -the\ minimal\ resource\ unit\ is\ megabyte,\ cannot\ be\ byte = 资源的最小单位必须为MB,而不是byte +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:71 +# args: mac +nic\ with\ mac\:%s\ has\ been\ bonded = 已绑定具有MAC:{0}的NIC -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:234 -# args: -price\ must\ be\ 0\ and\ 9999.99 = 价格必须在0和9999.99之间 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:98 +# args: chassisUuid +cannot\ find\ the\ cluster\ of\ baremetal2\ chassis[uuid\:%s],\ maybe\ it\ doesn't\ exist = 找不到BareMetal2机箱[uuid:{0}]的集群,该集群可能不存在 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:241 -# args: -gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ empty = GPU类型的价格必须绑定一个GPU设备 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:107 +# args: clusterUuid +there\ is\ no\ baremetal2\ gateway\ found\ in\ cluster[uuid\:%s] = 在集群[uuid:{0}]中找不到BareMetal2网关 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:248 -# args: price.getSystemTags() -gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ %s = GPU类型的价格必须绑定一个正确的GPU设备{0} +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:116 +# args: clusterUuid +there\ is\ no\ usable\ baremetal2\ gateway\ found\ in\ cluster[uuid\:%s] = 在集群[uuid:{0}]中找不到可用的Baremetal2网关 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:208 -# args: resourceName -resourceName[%s]\ is\ invalid = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:124 +# args: clusterUuid +there\ is\ no\ baremetal2\ provision\ network\ found\ in\ cluster[uuid\:%s] = 在集群[uuid:{0}]中找不到BareMetal2配置网络 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:260 -# args: msg.getAccountUuid() -The\ account[uuid\=%s]\ has\ attach\ price\ table = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisApiInterceptor.java:132 +# args: provisionNetworkUuid +baremetal2\ provision\ network[uuid\:%s]\ is\ not\ usable,\ make\ sure\ it's\ Enabled = Baremetal2配置网络[uuid:{0}]不可用,请确保它已启用 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:266 -# args: msg.getUuid() -This\ priceTable[uuid\=%s]\ is\ not\ allowed\ to\ delete = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:78 +# args: hardwareInfo +wrong\ baremetal2\ chassis\ hardware\ info\ format\:\ %s = 错误的Baremetal2机箱硬件信息格式:{0} -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:280 -# args: -accountUuid/tableUuid\ only\ one\ of\ them\ is\ allowed\ to\ be\ set = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:87 +# args: info.architecture,clusterArchitecture +the\ cpu\ architecture\ of\ the\ chassis[arch\:%s]\ and\ the\ cluster[arch\:%s]\ don't\ match = 机箱[arch:{0}]和集群[arch:{1}]的CPU体系结构不匹配 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:286 -# args: -endDateInLong\ is\ not\ allowed\ to\ be\ negative = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:97 +# args: BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE +only\ baremetal2\ chassis\ with\ boot\ mode\ %s\ is\ supported = 仅支持引导模式为{0}的BareMetal2机箱 -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:290 -# args: -endDateInLong\ and\ setEndDateInLongBaseOnCurrentTime\ are\ not\ allowed\ to\ set\ at\ the\ same\ time = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:108 +# args: hardwareInfo +wrong\ baremetal2\ chassis\ nic\ hardware\ info\ format\:\ %s = 错误的Baremetal2机箱NIC硬件信息格式:{0} -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:303 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:114 # args: -endDateInLong\ is\ set,\ no\ modification\ allowed = +there\ must\ be\ one\ and\ only\ one\ provision\ nic\ in\ a\ baremetal2\ chassis = Baremetal2机箱中必须有且只有一个配置NIC -# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:311 -# args: -endDateInLong\ cannot\ be\ earlier\ than\ dateInLong = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:124 +# args: hardwareInfo +wrong\ baremetal2\ chassis\ disk\ hardware\ info\ format\:\ %s = 错误的Baremetal2机箱磁盘硬件信息格式:{0} -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:254 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisHardwareInfoSyncer.java:167 # args: -priceKeyName\ is\ null = +other\ chassis\ has\ nics\ with\ the\ same\ mac\ address,\ which\ is\ impossible = 其他机箱具有相同MAC地址的NIC,这是不可能的 -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:879 -# args: currentPriceVO.getDateInLong() -dateInLong\ is\ less\ than\ %s = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java:372 +# args: msg.getClusterUuid() +BareMetal2\ Chassis[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled = Baremetal2机箱[uuid:{0}]不存在或已禁用 -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1281 -# args: resourceUuid -Already\ have\ one\ userdata\ systemTag\ for\ instanceOffering[uuid\:\ %s]. = +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java:438 +# args: msg.getRequiredClusterUuids() +no\ available\ baremetal2\ chassis\ found\ in\ baremetal2\ clusters[uuids\:%s] = 在Baremetal2集群中找不到可用的Baremetal2机箱[uuid:{0}] -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1346 +# at: src/main/java/org/zstack/baremetal2/chassis/BareMetal2ChassisManagerImpl.java:430 # args: -Shouldn't\ be\ more\ than\ one\ systemTag\ for\ one\ instanceOffering. = - -# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1323 -# args: resourceUuid -Already\ have\ one\ userdata\ systemTag\ for\ diskOffering[uuid\:\ %s]. = +no\ available\ baremetal2\ chassis\ found = 找不到可用的Baremetal2机箱 -# at: src/main/java/org/zstack/billing/ResourceSpendingHelper.java:50 -# args: resourceType -unsupported\ billing\ resource\ type\ [%s] = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:82 +# args: address +IPMI\ Address\ %s\ is\ not\ valid = IPMI地址{0}是无效的 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:63 -# args: msg.getUuid() -cannot\ find\ such\ ResourceStackVO\ by\ uuid\ [%s] = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:121 +# args: address,port +Baremetal\ Chassis\ of\ IPMI\ address\ %s\ and\ IPMI\ port\ %d\ has\ already\ been\ created. = IPMI地址为{0},端口为{1}的裸金属设备已经被创建 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:67 -# args: validStatus -restart\ resource\ stack\ only\ support\ %s\ status! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:111 +# args: address,port +BareMetal2\ Chassis\ of\ IPMI\ address\ %s\ and\ IPMI\ port\ %d\ has\ already\ been\ created. = 已创建IPMI地址为{0}、IPMI端口为{1}的BareMetal2机箱。 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:175 -# args: -templateContent\ and\ uuid\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:133 +# args: msg.getClusterUuid() +Cluster[uuid\:%s]\ does\ not\ exists. = 集群[uuid:{0}]不存在 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:98 -# args: validStatus -expect\ %s\ status! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:146 +# args: msg.getClusterUuid() +Cluster[uuid\:%s]\ is\ not\ Enabled. = 集群[uuid:{0}]处于停用状态 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:118 -# args: -templateContent\ and\ templateUuid\ mustn't\ both\ be\ empty! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:74 +# args: address,port +Bare\ Metal\ IPMI\ 2\ Chassis\ %s\:%d\ already\ exists = 裸机IPMI 2机箱{0}:{1}已存在 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:129 +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:93 # args: -templateContent\ and\ url\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = +Failed\ to\ reach\ the\ baremetal2\ chassis,\ please\ make\ sure\:\ 1.\ the\ IPMI\ connection\ is\ active;\ 2.\ the\ IPMI\ Address,\ Port,\ Username\ and\ Password\ are\ correct;\ 3.\ IPMI\ Over\ LAN\ is\ enabled\ in\ BIOS. = 无法访问Baremetal2机箱,请确保:1.IPMI连接处于活动状态;2.IPMI地址、端口、用户名和密码正确;3.在BIOS中启用了IPMI over LAN。 -# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:145 -# args: -only\ admin\ could\ enable/disable\ system\ StackTemplate = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:140 +# args: msg.getClusterUuid() +Cluster[uuid\:%s]\ is\ not\ a\ BareMetal2\ Cluster. = 集群[uuid:{0}]不是BareMetal2集群。 -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:856 -# args: vo.getName() -cannot\ delete\ or\ update\ system\ template\:\ %s = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisApiInterceptor.java:178 +# args: clusterUuid +no\ usable\ baremetal2\ gateway\ in\ cluster[uuid\:%s] = 集群[uuid:{0}]中没有可用的Baremetal2网关 -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:385 -# args: msg.getUuid() -ResourceStackVO\:\ [%s]\ has\ been\ deleted... = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:134 +# args: self.getUuid() +failed\ to\ power\ on\ baremetal2\ ipmi\ chassis[uuid\:%s] = 无法打开BareMetal2 IPMI机箱[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:415 -# args: uuid -ResourceStackVO\ [%s]\ already\ been\ deleted! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:206 +# args: self.getUuid() +failed\ to\ power\ off\ baremetal2\ ipmi\ chassis[uuid\:%s] = 无法关闭BareMetal2 IPMI机箱[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:641 -# args: -templateContent\ must\ be\ set! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:249 +# args: self.getUuid() +failed\ to\ power\ reset\ baremetal2\ ipmi\ chassis[uuid\:%s] = 无法重新启动BareMetal2 IPMI机箱[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:636 -# args: template.getUuid() -template\ [%s]\ chosen\ is\ disabled = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisBase.java:340 +# args: self.getUuid() +Failed\ to\ remotely\ ipxe\ boot\ chassis[uuid\:%s] = 无法远程IPXE引导机箱[uuid:{0}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:779 -# args: p.getParamName(),p.getResourceType() -cannot\ find\ parameters\ for\ %s,\ which\ is\ %s\ type,\ please\ check\ parameters = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java:76 +# args: e.getMessage() +fail\ to\ load\ baremetal2\ ipmi\ chassis\ info\ from\ file,\ because\:\ %s = 无法从文件加载BareMetal2 IPMI机箱信息,原因是:{0} -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:849 +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java:94 # args: -StackTemplateVO\ has\ been\ deleted... = +the\ api\ message's\ chassis\ type\ is\ ipmi,\ but\ it's\ not\ an\ APICreateBareMetal2ChassisHardwareInfoMsg = API消息的机箱类型为IPMI,但它不是APICreateBareMetal2ChassisHardwareInfoMsg -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:872 -# args: -content\ must\ be\ set\ by\ templateContent\ or\ url! = +# at: src/main/java/org/zstack/baremetal2/chassis/ipmi/BareMetal2IpmiChassisFactory.java:104 +# args: imsg.getIpmiAddress(),imsg.getIpmiPort() +received\ hardware\ info\ for\ unknown\ baremetal2\ chassis[ipmi_addr\:%s,\ ipmi_port\:%d] = 收到未知Baremetal2机箱的硬件信息[IPMI_地址:{0},IPMI_端口:{1}] -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:890 +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:84 # args: -get\ null\ content\ input = - -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:897 -# args: result.getTemplateVersion() -invalid\ cloudformation\ template\ version\:\ %s = - -# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:911 -# args: msg.getUuid() -StackTemplateVO\:\ [%s]\ has\ been\ deleted... = +cluster\ type\ and\ hypervisor\ type\ should\ all\ be\ baremetal2\ or\ all\ not = 集群类型和云主机管理程序类型应全部为BareMetal2或全部为非BareMetal2 -# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:20 +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:90 # args: -get\ null\ element\ in\ template\ content = +the\ architecture\ must\ be\ set\ when\ create\ new\ baremetal2\ clusters = 创建新的Baremetal2集群时必须设置体系结构 -# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:24 +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:101 # args: -template\ must\ contain\ [ZStackTemplateFormatVersion] = - -# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:27 -# args: result.getTemplateVersion(),CloudFormationConstant.version -invalid\ ZStackTemplateFormatVersion\:\ %s,\ %s = +do\ not\ add\ host\ into\ baremetal2\ cluster = 不要将物理机添加到BareMetal2集群中 -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:156 +# at: src/main/java/org/zstack/baremetal2/cluster/BareMetal2ClusterFactory.java:123 # args: -verb\ must\ contain\ '\:\:'! = - -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:197 -# args: t[0],last.getClass().getName() -need\ List\ for\ resource\ [%s]\ output\ here,\ but\ got\ %s. = - -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:221 -# args: value -invalid\ dynamic\ variables,\ which\ must\ contained\ ${\:\ %s = +l2\ network\ should\ not\ have\ the\ same\ interface\ name\ with\ provision\ network\ that's\ already\ attached\ to\ the\ cluster = 二层网络不应与已连接到集群的Provision网络具有相同的接口名称 -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:283 +# at: src/main/java/org/zstack/baremetal2/cluster/CephStorageAttachBm2ClusterMetric.java:29 # args: -cannot\ find\ resource\ of\ properties\ set\ before! = +Can\ not\ attach\ third-party\ ceph\ with\ token\ into\ aarch64\ cluster. = 无法使用令牌将第三方 分布式存储 附加到Aarch64集群。 -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:359 +# at: src/main/java/org/zstack/baremetal2/cluster/LocalStorageAttachBm2ClusterMetric.java:12 # args: -Some\ actions\ are\ invalid = +Can\ not\ attach\ local\ storage\ into\ baremetal2\ cluster. = 无法将本地存储连接到BareMetal2集群。 -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:128 -# args: e -Unable\ to\ create\ json\ template = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1328 +# args: msg.getInstanceUuid() +no\ provision\ nic\ found\ for\ baremetal2\ instance[uuid\:%s] = 未找到BareMetal2实例[uuid:{0}]的配置NIC -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:116 -# args: jsonFile -cannot\ find\ such\ template\ file\:\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:269 +# args: self.getUuid(),msg.getInstanceUuid() +failed\ to\ delete\ convert\ volume\ to\ chassis\ local\ disk\ configurations\ in\ gateway[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s] = 无法删除将网关[uuid:{0}]中的卷转换为机箱本地磁盘配置(对于BareMetal2实例[uuid:{1}]) -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:233 -# args: -no\ root\ element\ found,\ please\ check\ your\ cfn\ formation! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1342 +# args: msg.getInstanceUuid(),self.getUuid(),ret.getError() +failed\ to\ create\ provision\ configurations\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = 无法为网关[uuid:{1}]中的BareMetal2实例[uuid:{0}]创建设置配置,因为{2} -# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:365 -# args: e.getMessage() -Wrong\ json\ format,\ causes\:\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:418 +# args: chassis.getUuid() +chassis\:%s\ disk\ does\ not\ have\ wwn\ info,\ please\ inspect\ chassis\ and\ try\ again = 机箱:{0}磁盘没有WWN信息,请检查机箱并重试 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:59 -# args: -Mappings\ root\ body\ must\ be\ json\ object! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1809 +# args: chassis.getUuid() +failed\ to\ power\ on\ baremetal2\ chassis[uuid\:%s]\ using\ ipmitool = 无法使用ipmitool打开Baremetal2机箱[uuid:{0}]的电源 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:45 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:567 # args: -Condition\ body\ cannot\ support\ json\ null\ or\ array! = +convert\ image\ data\ to\ local\ disk\ failed = 将图像数据转换到本地磁盘失败 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:41 -# args: -Only\ support\ ZStack\ Template\ Functions\ in\ 'Condition'\ field! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:576 +# args: instanceVO.getUuid(),chassis.getUuid(),BareMetal2GlobalConfig.CONVERT_VOLUME_TO_LOCAL_DISK_TIMEOUT.value(Integer.class) +baremetal2\ instance[uuid\:%s]\ convert\ volume\ failed\ on\ baremetal2\ chassis[uuid\:%s]\ ,\ timeout\ after\ %s\ minutes\ = Baremetal2实例[uuid:{0}]转换卷在Baremetal2机箱[uuid:{1}]上失败,{2}分钟后超时 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:37 -# args: -Value\ must\ be\ boolean\ in\ 'Condition'\ field = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1235 +# args: self.getUuid(),ret.getError() +failed\ to\ prepare\ provision\ network\ in\ gateway[uuid\:%s],\ because\ %s = 无法在网关[uuid:{0}]中准备设置网络,因为{1} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:30 -# args: key,es.size() -Condition\ key\:\ %s\ only\ support\ 1\ element\ in\ the\ json\ object\ of\ value,\ but\ got\ %d\ elements! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1304 +# args: self.getUuid(),ret.getError() +failed\ to\ destroy\ provision\ network\ in\ gateway[uuid\:%s],\ because\ %s = 无法销毁网关[uuid:{0}]中的设置网络,因为{1} -# at: src/main/java/org/zstack/cloudformation/template/decoder/DecoderUtils.java:87 -# args: msg -cannot\ find\ such\ msg\:\ %s\ for\ create = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1391 +# args: msg.getInstanceUuid(),self.getUuid(),ret.getError() +failed\ to\ delete\ provision\ configurations\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = 无法删除Baremetal2实例[uuid:{0}](在网关[uuid:{1}]中)的设置配置,因为{2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:56 -# args: -Mapping\ value\ body\ cannot\ support\ null! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1435 +# args: msg.getInstanceUuid(),self.getUuid(),ret.getError() +failed\ to\ create\ console\ proxy\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = 无法为网关[uuid:{1}]中的BareMetal2实例[uuid:{0}]创建控制台代理,因为{2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:54 -# args: -Mapping\ value\ body\ cannot\ support\ json\ array! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1492 +# args: msg.getOldDefaultL3Uuid(),msg.getNewDefaultL3Uuid(),msg.getInstanceUuid(),ret.getError() +failed\ to\ change\ default\ network\ from\ l3[uuid\:%s]\ to\ l3[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s],\ because\ %s = 无法将默认网络从第3层[uuid:{0}]更改为第3层[uuid:{1}](对于BareMetal2实例[UUid:{2}]),因为{3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:66 -# args: -mappingName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1531 +# args: msg.getInstanceUuid(),msg.getGatewayUuid(),ret.getError() +failed\ to\ ping\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{1}]Ping BareMetal2实例[uuid:{0}],因为{2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:83 -# args: -Mapping\ body\ cannot\ support\ json\ null! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1578 +# args: msg.getInstanceUuid(),msg.getGatewayUuid(),ret.getError() +failed\ to\ change\ the\ password\ of\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{1}]更改BareMetal2实例[uuid:{0}]的密码,因为{2} -# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:81 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1677 # args: -Mapping\ body\ cannot\ support\ non\ map\ value! = +third\ party\ ceph\ with\ token\ not\ support\ local\ disk\ yet = 带有令牌的第三方 分布式存储 尚不支持本地磁盘 -# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:70 -# args: -Description\ in\ Outputs\ must\ be\ String\ type! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1838 +# args: chassis.getUuid() +failed\ to\ power\ off\ baremetal2\ chassis[uuid\:%s]\ using\ ipmitool = 无法使用ipmitool关闭Baremetal2机箱[uuid:{0}]的电源 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java:59 -# args: -paramName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1923 +# args: chassis.getUuid(),timeout +baremetal2\ chassis[uuid\:%s]\ is\ still\ not\ POWER_OFF\ %d\ seconds\ later = Baremetal2机箱[uuid:{0}]在{1}秒后仍未关闭电源_。 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java:129 -# args: -Parameters\ root\ body\ must\ be\ json\ object! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:1896 +# args: bm.getUuid(),ret.getError() +failed\ to\ power\ off\ baremetal2\ instance[uuid\:%s]\ by\ bm\ agent,\ because\ %s = 无法通过BM代理关闭BareMetal2实例[uuid:{0}],因为{1} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:112 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2103 # args: -resourceName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = +vmInstanceUuids\ is\ empty = VMInstanceUuids为空 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:123 -# args: -Parameters\ body\ cannot\ support\ null! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2109 +# args: self.getUuid(),self.getStatus() +the\ baremetal2\ gateway[uuid\:%s,\ status\:%s]\ is\ not\ Connected = Baremetal2网关[uuid:{0},状态:{1}]未连接 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:68 -# args: -Resource\ value\ body\ cannot\ support\ null! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2186 +# args: bmUuid +baremetal2\ instance[uuid\:%s]\ not\ connected,\ cannot\ attach\ nic\ to\ it = BareMetal2实例[uuid:{0}]未连接,无法将NIC连接到该实例 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:48 -# args: resource.getResourceName(),e.getKey(),resource.getResourceName() -Resource\ %s\ cannot\ depends\ on\ itself,\ please\ check\ %s\ in\ Resource\ [%s] = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2209 +# args: nicUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ attach\ nic[uuid\:%s]\ to\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{2}]将NIC[uuid:{0}]连接到BareMetal2实例[Uuid:{1}],因为{3} -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:254 -# args: -Resource\ root\ body\ must\ be\ json\ object! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2252 +# args: bmUuid +baremetal2\ instance[uuid\:%s]\ is\ not\ connected,\ cannot\ detach\ nic\ from\ it = BareMetal2实例[uuid:{0}]未连接,无法将NIC与其分离 -# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:216 -# args: -Resource\ Type\ must\ be\ String! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2275 +# args: nicUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ detach\ nic[uuid\:%s]\ from\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{2}]从BareMetal2实例[uuid:{1}]分离NIC[Uuid:{0}],因为{3} -# at: src/main/java/org/zstack/cloudformation/template/function/IfTemplateFunction.java:42 -# args: cond -cannot\ find\ condition[%s]\ in\ 'Conditions' = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2441 +# args: bmUuid +baremetal2\ instance[uuid\:%s]\ is\ not\ connected,\ cannot\ attach\ volume\ to\ it = BareMetal2实例[uuid:{0}]未连接,无法将卷附加到该实例 -# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:42 -# args: e.getAsString() -expect\ 'true',\ 'false'\ for\ the\ object,\ but\ got\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2338 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ prepare\ volume[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{2}]为BareMetal2实例[uuid:{1}]准备卷[Uuid:{0}],因为{3} -# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:35 -# args: keys,e.getAsString() -expect\ 'true',\ 'false'\ or\ an\ other\ Condition,\ current\ Conditions\ include\:\ %s,\ but\ got\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2399 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ attach\ volume[uuid\:%s]\ to\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{2}]将卷[uuid:{0}]附加到BareMetal2实例[Uuid:{1}],因为{3} -# at: src/main/java/org/zstack/cloudformation/template/function/SelectTemplateFunction.java:83 -# args: -Fn\:\:Select\ out\ of\ range,\ please\ check\ your\ json\ file! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2480 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ get\ volume[uuid\:%s]\ lunid\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = 无法获取卷[uuid:{0}]的lunid(针对网关[uuid:{2}]中的BareMetal2实例[Uuid:{1}]),因为{3} -# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:75 -# args: e.getKey() -only\ functions\ can\ in\ Function,\ but\ found\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2535 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ detach\ volume[uuid\:%s]\ from\ baremetal2\ instance[uuid\:%s]\ through\ gateway[uuid\:%s],\ because\ %s = 无法通过网关[uuid:{2}]分离卷[uuid:{0}](从BareMetal2实例[Uuid:{1}]),因为{3} -# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:90 -# args: -element\ is\ null! = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2Gateway.java:2570 +# args: volumeUuid,bmUuid,gatewayUuid,ret.getError() +failed\ to\ destroy\ volume[uuid\:%s]\ for\ baremetal2\ instance[uuid\:%s]\ in\ gateway[uuid\:%s],\ because\ %s = 无法销毁网关[uuid:{2}]中BareMetal2实例[uuid:{1}]的卷[Uuid:{0}],因为{3} -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:317 -# args: resourceUuid,affinityGroupUuid -VM\ [uuid\:\ %s]\ has\ already\ been\ added\ to\ affinityGroup\ [uuid\:\ %s] = VM[uuid:{0}已经被添加到亲和组[uuid:{1}]中。] - -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:334 -# args: hostUuid,affinityGroupUuid -There\ are\ other\ VMs\ on\ this\ host\ [uuid\:\ %s]\ belonging\ to\ same\ affinityGroup\ [%s] = 在物理机[uuid:{0}]上的虚拟机属于同一个亲和组中[{1}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:100 +# args: msg.getManagementIp() +there\ has\ been\ a\ baremetal2\ gateway\ having\ management\ ip\ %s = 存在管理IP为{0}的BareMetal2网关 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:363 -# args: self.getUuid(),host.getUuid(),vmUuid -affinityGroup\ [uuid\:%s]\ reserve\ host\ [uuid\:%s]\ for\ vm\ [uuid\:\ %s]\ failed = 亲和组[uuid:{0}]为虚拟机[uuid:{2}]预分配物理机资源[uuid:{1}]失败 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:66 +# args: msg.getManagementIp() +there\ is\ already\ a\ baremetal\ pxe\ server\ with\ management\ ip\ %s,\ do\ not\ use\ it\ to\ create\ baremetal2\ gateway = 已存在管理IP为{0}的Baremetal PXE服务器,请不要使用它来创建Baremetal2网关 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:433 -# args: inv.getResourceUuid(),self.getUuid() -vm\ [uuid\:%s]\ doesn't\ satisfy\ the\ affinityGroup\ [uuid\:%s] = 虚拟机[uuid:{1}]不满足亲和组[uuid:{2}]的要求 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:107 +# args: msg.getManagementIp() +there\ has\ been\ a\ host\ having\ management\ ip\ %s = 已存在管理IP为{0}的物理机 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupFilterFlow.java:136 -# args: -can\ not\ satisfied\ affinity\ group\ conditions = 不能满足亲和组的条件 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:80 +# args: msg.getManagementIp() +management\ ip[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 管理IP[{0}]既不是IPv4地址也不是有效的物理机名 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:42 -# args: VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString(),state.toString() -Vm\ can\ change\ its\ affinityGroup\ only\ in\ state\ [%s,%s],\ but\ vm\ is\ in\ state\ [%s] = 只有状态为[{0},{1}]的虚拟机可以改变亲和组,但是现在虚拟机的状态为[{2}] +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:90 +# args: msg.getClusterUuid() +cannot\ add\ baremetal2\ gateway\ in\ non-baremetal2\ cluster[uuid\:%s] = 无法在非Baremetal2集群[uuid:{0}]中添加Baremetal2网关 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:52 -# args: msg.getUuid(),agUuid -Vm\ [uuid\:\ %s]\ is\ already\ added\ to\ affinityGroup\ [uuid\:\ %s] = 云主机[uuid:{0}]已经被添加至亲和组[uuid:{1}]中 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:120 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ gateway[uuid\:%s]\ to\ non-baremetal2\ cluster[uuid\:%s] = 无法将Baremetal2网关[uuid:{0}]连接到非Baremetal2集群[uuid:{1}] -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:77 -# args: affinityGroupUuid -AffinityGroup\ [uuid\:\ %s]\ does\ not\ existed = 亲和组[uuid:{0}]不存在 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:131 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ already\ attached\ to\ cluster[uuid\:%s] = Baremetal2网关[uuid:{0}]已连接到集群[uuid:{1}] -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:81 -# args: -Can\ not\ operate\ on\ affinity\ group\ created\ by\ system = 不能对系统创建的亲和组进行操作 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:140 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ can\ only\ attach\ to\ one\ cluster = Baremetal2网关[uuid:{0}]只能连接到一个集群 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:88 -# args: affinityGroupUuid -Can\ not\ operate\ on\ affinityGroup\ [uuid\:\ %s]\ which\ is\ not\ enabled = 不能对不是enabled状态的亲和组操作 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:151 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ not\ attached\ to\ cluster[uuid\:%s],\ no\ need\ to\ detach = Baremetal2网关[uuid:{0}]未连接到集群[uuid:{1}],无需分离 -# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupManagerImpl.java:98 -# args: msg.getAffinityGroupUuid() -cannot\ find\ the\ affinity\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = 未找到亲和组[uuid:{0}],它可能已经被删除 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:156 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ is\ attached\ to\ only\ one\ cluster\ now,\ do\ not\ detach\ it = BareMetal2网关[uuid:{0}]现在仅连接到一个集群,请不要将其分离 -# at: src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java:103 -# args: spec.getL3NetworkUuids() -no\ host\ found\ in\ clusters\ that\ has\ attached\ to\ L2Networks\ which\ have\ L3Networks%s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:164 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ does\ not\ exist = 集群[uuid:{0}]不存在 -# at: src/main/java/org/zstack/compute/allocator/AttachedPrimaryStorageAllocatorFlow.java:79 -# args: psuuids -no\ host\ found\ in\ clusters\ that\ have\ attached\ to\ primary\ storage\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:168 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ is\ not\ a\ baremetal2\ cluster = 集群[uuid:{0}]不是BareMetal2集群 -# at: src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java:79 -# args: requiredPsUuids,vm.getUuid() -no\ host\ found\ in\ clusters\ which\ have\ attached\ to\ all\ primary\ storage\ %s\ where\ vm[uuid\:%s]'s\ volumes\ locate = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:173 +# args: msg.getGatewayUuid() +gateway[uuid\:%s]\ does\ not\ exist = 网关[uuid:{0}]不存在 -# at: src/main/java/org/zstack/compute/allocator/AvoidHostAllocatorFlow.java:30 -# args: spec.getAvoidHostUuids() -after\ rule\ out\ avoided\ host%s,\ there\ is\ no\ host\ left\ in\ candidates = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:177 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ is\ already\ in\ cluster[uuid\:%s] = Baremetal2网关[uuid:{0}]已在集群[uuid:{1}]中 -# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:87 -# args: spec.getRequiredBackupStorageUuid(),bsType -the\ backup\ storage[uuid\:%s,\ type\:%s]\ requires\ bound\ primary\ storage,\ however,\ the\ primary\ storage\ has\ not\ been\ added = 无法找到跟镜像服务器[uuid:{0}, type:{1}]配对的主存储。一些镜像服务器必须跟配对的主存储共同使用,例如Ceph镜像服务器只能搭配Ceph主存储使用。请检查你主存储的设置 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:181 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ in\ the\ same\ zone\ as\ cluster[uuid\:%s] = Baremetal2网关[uuid:{0}]与集群[uuid:{1}]不在同一个区域中 -# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:80 -# args: spec.getImage().getUuid(),spec.getRequiredBackupStorageUuid(),type,psUuids -The\ image[uuid\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[uuids\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = 镜像[uuid:{0}]所在的镜像服务器[uuid:{1}, type:{2}]必须跟主存储[uuid:{3}]配对使用,但无法找到可以跟满足条件并可以访问该主存储的物理机 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayApiInterceptor.java:191 +# args: msg.getGatewayUuid() +cannot\ change\ the\ cluster\ of\ baremetal2\ gateway[uuid\:%s]\ when\ there\ are\ running\ instances\ depending\ on\ it = 存在依赖于Baremetal2网关[uuid:{0}]的正在运行的实例时,无法更改该集群 -# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:71 -# args: spec.getImage().getUuid(),name,spec.getRequiredBackupStorageUuid(),spec.getImage().getType(),possiblePrimaryStorageTypes -The\ image[uuid\:%s,\ name\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[types\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = 镜像[uuid:{0},name:{1}]所在的镜像服务器[uuid:{2}, type:{3}]必须跟主存储[uuid:{4}]一起使用,但无法找到可以跟满足条件并可以访问该主存储的物理机 +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayConsoleHypervisorBackend.java:45 +# args: +baremetal2\ instance[uuid\:%s]\ doesn't\ exist,\ cannot\ generate\ its\ console\ url = Baremetal2实例[uuid:{0}]不存在,无法生成其控制台URL -# at: src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java:107 -# args: args -No\ host\ with\ %s\ found = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayConsoleHypervisorBackend.java:54 +# args: bm.getGatewayUuid(),bm.getUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ Connected,\ cannot\ generate\ console\ url\ for\ instance[uuid\:%s] = Baremetal2网关[uuid:{0}]未连接,无法为实例[uuid:{1}]生成控制台URL -# at: src/main/java/org/zstack/compute/allocator/FilterFlow.java:33 -# args: filter.getClass().getSimpleName(),filter.filterErrorReason() -after\ filtering,\ HostAllocatorFilterExtensionPoint[%s]\ returns\ zero\ candidate\ host,\ it\ means\:\ %s = +# at: src/main/java/org/zstack/baremetal2/gateway/BareMetal2GatewayManagerImpl.java:258 +# args: resourceUuid +cluster[%s]\ is\ not\ baremetal2\ type = 集群[{0}]不是BareMetal2类型 -# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:56 +# at: src/main/java/org/zstack/baremetal2/gateway/allocator/AbstractGatewayAllocatorStrategy.java:102 # args: -either\ volumeUuid\ or\ volumeSnapshotUuid\ must\ be\ set = 云盘uuid或者快照uuid必须被设置 +failed\ to\ allocate\ baremetal2\ gateway = 无法分配Baremetal2网关 -# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:75 +# at: src/main/java/org/zstack/baremetal2/gateway/allocator/BareMetal2GatewayMainAllocatorFlow.java:62 # args: -zoneUuids,\ clusterUuids,\ hostUuids\ must\ at\ least\ have\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = 区域uuid,集群uuid,物理机uuid必须有一个不为空,或者全部都填写 +no\ available\ baremetal2\ gateway\ found = 找不到可用的Baremetal2网关 -# at: src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java:71 -# args: spec.getCpuCapacity(),spec.getMemoryCapacity() -no\ host\ having\ cpu[%s],\ memory[%s\ bytes]\ found = +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:166 +# args: BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE +only\ baremetal2\ image\ with\ boot\ mode\ %s\ is\ supported = 仅支持引导模式为{0}的BareMetal2镜像 -# at: src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java:62 -# args: currentVersion -no\ candidate\ host\ has\ version[%s] = +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:138 +# args: bm2ImageCount +only\ one\ baremetal2\ system\ tag\ is\ allowed,\ but\ %d\ was\ got = 只允许一个Baremetal2系统标记,但获得了{0} -# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:221 -# args: PrimaryStorageState.Enabled,PrimaryStorageState.Disabled,PrimaryStorageStatus.Connected -cannot\ find\ available\ primary\ storage[state\:\ %s\ or\ %s,\ status\:\ %s].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:158 +# args: +only\ root\ volume\ template\ of\ format\ raw/qcow2\ can\ be\ tagged\ with\ baremetal2 = 只有RAW/QCOW2格式的根卷模板才能使用BareMetal2进行标记 -# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:217 -# args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,spec.getDiskSize() -cannot\ find\ available\ primary\ storage[state\:\ %s,\ status\:\ %s,\ available\ capacity\ %s\ bytes].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = +# at: src/main/java/org/zstack/baremetal2/image/BareMetal2ImageManagerImpl.java:162 +# args: +the\ bootMode\ tag\ is\ mandatory\ for\ baremetal2\ images = 对于BareMetal2镜像,bootmode标记是必需的 -# at: src/main/java/org/zstack/compute/allocator/HostSortorChain.java:127 -# args: e.getMessage(),host.getUuid(),e.getMessage() -[Host\ Allocation]\:\ %s\ on\ host[uuid\:%s].\ try\ next\ one.\ %s = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateChassisFlow.java:76 +# args: spec.getRequiredChassisDiskUuid(),chassis.getUuid() +required\ chassis\ disk[%s]\ not\ belong\ to\ chassis[%s] = 所需的机箱磁盘[{0}]不属于机箱[{1}] -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:97 -# args: spec.getHypervisorType() -no\ host\ having\ state\=Enabled\ status\=Connected\ hypervisorType\=%s\ found = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateChassisFlow.java:88 +# args: chassis.getUuid(),spec.getImageSpec().getInventory().getUuid() +chassis\ not\ have\ engouh\ capacity\ for\ image[%s] = 机箱没有足够的容量用于镜像[{0}] -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:99 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:85 # args: -no\ host\ having\ state\=Enabled\ status\=Connected\ found = +not\ enough\ information\ to\ determine\ which\ baremetal2\ cluster\ should\ be\ used = 没有足够的信息来确定应使用哪个BareMetal2集群 -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:94 -# args: candidates.size(),spec.getHypervisorType() -no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts\ having\ the\ hypervisor\ type\ [%s] = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:100 +# args: +no\ baremetal2\ cluster\ found = 未找到BareMetal2集群 -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:92 -# args: candidates.size() -no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:217 +# args: spec.getRequiredClusterUuids(),spec.getVmInventory().getUuid() +failed\ to\ allocate\ primary\ storage\ in\ clusters[uuids\:%s]\ for\ baremetal2\ instance[uuid\:%s] = 无法在集群[uuid:{0}]中为Baremetal2实例[uuid:{1}]分配主存储 -# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:90 -# args: candidates.size() -no\ Connected\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:224 +# args: spec.getRequiredClusterUuids(),spec.getVmInventory().getUuid() +failed\ to\ allocate\ gateway\ in\ clusters[uuids\:%s]\ for\ baremetal2\ instance[uuid\:%s] = 无法在集群[uuid:{0}]中为BareMetal2实例[uuid:{1}]分配网关 -# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:92 -# args: spec.getImage().getUuid(),spec.getImage().getName() -the\ image[uuid\:%s,\ name\:%s]\ is\ deleted\ on\ all\ backup\ storage = 镜像[uuid:{0}, name:{1}]已经从所有镜像服务器上删除,无法执行相应操作 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:231 +# args: spec.getRequiredClusterUuids(),spec.getVmInventory().getUuid() +failed\ to\ allocate\ chassis\ in\ clusters[uuids\:%s]\ for\ baremetal2\ instance[uuid\:%s] = 无法在集群[uuid:{0}]中为Baremetal2实例[uuid:{1}]分配机箱 -# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:126 -# args: zoneUuids,spec.getImage().getUuid() -no\ host\ found\ in\ zones[uuids\:%s]\ that\ attaches\ to\ backup\ storage\ where\ image[%s]\ is\ on = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:262 +# args: clusterUuids +only\ baremetal2\ clusters[uuid\:%s]\ meet\ the\ needs\ for\ chassis\ and\ gateway,\ but\ they\ have\ no\ provision\ network\ attached = 只有BareMetal2集群[uuid:{0}]满足机箱和网关的需求,但它们没有连接的配置网络 -# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:98 -# args: entry.getKey() -resource\ binding\ not\ support\ type\ %s\ yet = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceAllocateClusterFlow.java:253 +# args: spec.getRequiredClusterUuids() +no\ baremetal2\ cluster\ found\ in\ clusters[uuid\:%s] = 在集群[uuid:{0}]中找不到BareMetal2集群 -# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:117 -# args: resources -no\ available\ host\ found\ with\ binded\ resource\ %s = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:881 +# args: msg.getPrimaryStorageUuidForRootVolume(),msg.getPrimaryStorageUuidForDataVolume() +the\ primary\ storage[%s]\ of\ the\ root\ volume\ and\ the\ primary\ storage[%s]\ of\ the\ data\ volume\ are\ not\ in\ the\ same\ cluster = 根卷的主存储[{0}]和数据云盘的主存储[{1}]不在同一集群中 -# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:68 -# args: extp.getClass().getName() -InstanceOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:244 +# args: networkUuid +make\ sure\ all\ baremetal2\ gateways\ on\ provision\ network[uuid\:%s]\ are\ Connected = 确保配置网络[uuid:{0}]上的所有Baremetal2网关均已连接 -# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:104 -# args: extp.getClass().getName() -DiskOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:707 +# args: +neither\ chassisUuid\ nor\ chassisOfferingUuid\ is\ set\ when\ create\ baremetal2\ instance = 创建BareMetal2实例时,Chassisuuid和ChassisOfferuuid均未设置 -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:55 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:169 # args: -if\ cluster\ type\ is\ baremetal,\ then\ hypervisorType\ must\ be\ baremetal\ too,\ or\ vice\ versa = +only\ support\ vpc\ network\ support\ attach\ eip\ on\ baremetal2\ instance = 仅支持VPC网络支持在Baremetal2实例上附加EIP -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:71 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:179 # args: -only\ kvm\ hosts'\ operating\ system\ can\ be\ updated,\ for\ now = 目前只支持升级KVM物理机操作系统 +bare\ metal\ instance\ not\ allowed\ to\ change\ vm\ nic\ network = 不允许裸机实例更改VM NIC网络 -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:82 -# args: msg.getUuid() -there\ are\ hosts\ in\ cluster[uuid\:%s]\ in\ the\ PreMaintenance\ state,\ cannot\ update\ cluster\ os\ right\ now = 集群[uuid:{0}] 中存在处于预维护模式的物理机,无法执行操作系统升级操作 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:190 +# args: +current\ operation\ is\ not\ supported\ on\ local\ baremetal\ instance = 本地裸机实例不支持当前操作 -# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:94 -# args: msg.getUuid() -not\ all\ hosts\ in\ cluster[uuid\:%s]\ are\ in\ the\ Connected\ status,\ cannot\ update\ cluster\ os\ right\ now = 集群[uuid:{0}] 中存在未处于已连接状态的物理机,无法执行操作系统升级操作 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:201 +# args: +not\ supported\ by\ baremetal2\ instance = BareMetal2实例不支持 -# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java:45 -# args: r -invalid\ cpu\ pinning\ ref[%s].\ correct\ example\ is\ [1,3\:3-6,^5] = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:207 +# args: bm.getUuid() +baremetal2\ instance[uuid\:%s]\ is\ not\ Connected = BareMetal2实例[uuid:{0}]未连接 -# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java:82 -# args: pCpuNum -the\ host\ vm\ located\ only\ have\ %\ CPUs = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:215 +# args: bm.getUuid() +baremetal2\ instance[uuid\:%s]\ is\ not\ stopped = Baremetal2实例[uuid:{0}]未停止 -# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningFilterFlow.java:48 -# args: -vcpu\ pinning\ pcpu\ id\ >\ host\ cores = vcpu要绑定的pcpu id大于了物理机实际核数 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:221 +# args: bm.getUuid() +baremetal2\ instance[uuid\:%s]\ is\ running\ but\ its\ agent\ is\ not\ Connected = Baremetal2实例[uuid:{0}]正在运行,但其代理未连接 -# at: src/main/java/org/zstack/compute/cpuPinning/CpuRangeSet.java:58 -# args: word -Invalid\ cpuset\ [%s] = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:607 +# args: msg.getChassisOfferingUuid() +baremetal2\ chassis\ offering[uuid\:%s]\ does\ not\ exist = Baremetal2机箱产品[uuid:{0}]不存在 -# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:78 -# args: msg.getManagementIp() -managementIp[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 管理IP[{0}]既不是有效的IPv4地址也不是有效的物理机名 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:318 +# args: msg.getInstanceUuid() +baremetal2\ instance[uuid\:%s]\ is\ not\ stopped\ can\ not\ change\ its\ chassis\ offering = Baremetal2实例[uuid:{0}]未停止,无法更改其机箱产品 -# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:88 -# args: msg.getHostUuid(),hostStatus -can\ not\ maintain\ host[uuid\:%s,\ status\:%s]which\ is\ not\ Connected = 只能对已连接状态的物理机[uuid:{0}, status:{1}]进行维护操作 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:337 +# args: msg.getVmInstanceUuid() +baremetal2\ instance[uuid\:%s]\ has\ not\ been\ allocated\ a\ chassis,\ start\ the\ instance\ and\ try\ again = 尚未为BareMetal2实例[uuid:{0}]分配机箱,请启动该实例并重试 -# at: src/main/java/org/zstack/compute/host/HostBase.java:259 -# args: vmFailedToMigrate,self.getUuid(),self.getName(),self.getManagementIp() -failed\ to\ migrate\ vm[uuids\:%s]\ on\ host[uuid\:%s,\ name\:%s,\ ip\:%s],\ will\ try\ stopping\ it. = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:343 +# args: ipVersion +only\ l3\ network\ with\ ip\ version\ %d\ is\ supported\ by\ baremetal2\ instance = Baremetal2实例仅支持IP版本为{0}的三层网络 -# at: src/main/java/org/zstack/compute/host/HostBase.java:609 -# args: -host\ is\ connecting,\ ping\ failed = 物理机正在连接, 不能进行ping操作 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:349 +# args: l2Type +l2\ network\ type\ %s\ not\ supported\ by\ baremetal2\ instance = 二层网络类型{0}不受Baremetal2实例支持 -# at: src/main/java/org/zstack/compute/host/HostBase.java:1085 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:355 # args: -an\ other\ connect\ host\ task\ is\ running,\ cancel\ the\ new\ task\ and\ wait\ return = - -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:282 -# args: msg.getManagementIp() -there\ has\ been\ a\ host\ having\ managementIp[%s] = 已经存在一个管理IP是[{0}]的物理机 +customMac\ is\ mandatory\ when\ attaching\ l3\ network\ to\ baremetal2\ instance = 将三层网络连接到Baremetal2实例时,CustomMAC是必需的 -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:288 -# args: msg.getClusterUuid() -cluster[uuid\:%s]\ is\ not\ existing = - -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:378 -# args: vo.getName(),vo.getManagementIp() -after\ connecting,\ host[name\:%s,\ ip\:%s]\ returns\ a\ null\ os\ version = 在连接操作后,物理机[name:{0}, ip:{1}]没有返回操作系统版本信息 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:359 +# args: msg.getCustomMac() +%s\ is\ not\ valid\ mac\ address = {0}不是有效的MAC地址 -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:409 -# args: vo.getClusterUuid(),currentVersion,vo.getName(),vo.getManagementIp(),mineVersion -cluster[uuid\:%s]\ already\ has\ host\ with\ os\ version[%s],\ but\ new\ added\ host[name\:%s\ ip\:%s]\ has\ host\ os\ version[%s] = 集群[uuid:{0}]中物理机使用的操作系统版本是[{1}],但是新的物理机[name:{2} ip:{3}]的操作系统版本是 [{4}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:364 +# args: msg.getCustomMac() +duplicated\ mac\ address\ %s = 重复的MAC地址{0} -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:531 -# args: msg.getCancellationApiId() -no\ running\ api[%s]\ task\ on\ hosts = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:373 +# args: bm.getUuid(),bm.getChassisUuid(),msg.getCustomMac() +baremetal2\ instance[uuid\:%s]\ running\ on\ chassis[uuid\:%s],\ which\ doesn't\ have\ non-provisioning\ nic\ with\ mac\ address\ %s = 机箱[uuid:{1}]上运行的Baremetal2实例[uuid:{0}]没有MAC地址为{2}的非配置NIC -# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:624 -# args: d.getPrimaryStorageUuid() -primary\ storage[uuid\:%s]\ becomes\ disconnected,\ the\ host\ has\ no\ connected\ primary\ storage\ attached = 主存储[uuid:{0}]失联,物理机没有关联的主存储 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:382 +# args: msg.getCustomMac() +mac\ address\ %s\ has\ already\ been\ used,\ try\ another\ one = MAC地址{0}已被使用,请尝试其他地址 -# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:38 -# args: nameips.stream().map( it -> it.get(1, String.class) + "/" + it.get(0, String.class)).collect(Collectors.joining(", ")) -host(s)\ [%s]\ is\ not\ Connected,\ not\ support\ to\ power\ off = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:399 +# args: msg.getCustomMac() +nic\ with\ mac\:%s\ cannot\ be\ attached\ l3Network,\ because\ it\ has\ been\ bonded = MAC为{0}的NIC无法连接到L3Network,因为它已绑定 -# at: src/main/java/org/zstack/compute/host/HostSecurityLevelAllocatorFilterExtensionPoint.java:68 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:448 # args: -vm\ security\ level\ not\ consistent\ with\ vms\ running\ on\ host = +third\ party\ ceph\ cannot\ mixed\ with\ other\ primary\ storage = 第三方 分布式存储 不能与其他主存储混合 -# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:204 -# args: host.getUuid(),host.getName(),host.getState() -host[uuid\:%s,\ name\:%s]\ is\ in\ state[%s],\ cannot\ perform\ required\ operation = 物理机[uuid:{0}, name:{1}]处于状态[{2}]中,不能处理该请求 - -# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:485 -# args: ret.getError() -operation\ error,\ because\ %s = 操作错误,因为{0} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:571 +# args: msg.getClusterUuid(),msg.getUuid() +cluster[uuid\:%s]\ is\ not\ an\ Enabled\ baremetal2\ cluster,\ cannot\ start\ instance[uuid\:%s]\ in\ it = 集群[uuid:{0}]不是已启用的BareMetal2集群,无法在其中启动实例[uuid:{1}] -# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:377 -# args: vmInstanceVO.getUuid(),vmInstanceVO.getState() -only\ support\ do\ live\ snapshot\ on\ vm\ state[%s],\ but\ vm\ is\ on\ [%s]\ state = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:583 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ does\ not\ exist\ or\ is\ not\ Enabled\ or\ Connected = Baremetal2网关[uuid:{0}]不存在,或者未启用或未连接 -# at: src/main/java/org/zstack/compute/host/MevocoHostBaseFactory.java:71 -# args: huuid,cidr -host[uuid\:%s]\ has\ multi\ ips\ in\ cidr[%s] = 物理机[uuid:{0}]在cidr[{1}]中有多个ip +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:594 +# args: msg.getGatewayUuid(),msg.getClusterUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ in\ cluster\ [uuid\:%s] = Baremetal2网关[uuid:{0}]不在集群[uuid:{1}]中 -# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:344 -# args: msg.getHostUuid() -host[uuid\:%s]\ can\ not\ find = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:600 +# args: msg.getUuid() +please\ specify\ chassis\ uuid\ or\ chassis\ offering\ uuid\ to\ start\ baremetal2\ instance[uuid\:%s] = 请指定机箱uuid或机箱提供uuid以启动BareMetal2实例[uuid:{0}] -# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:336 -# args: clusterUuids,hypervisorType -cluster[uuids\:%s,\ hypervisorType\:%s]\ are\ not\ exist! = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:611 +# args: msg.getChassisOfferingUuid() +baremetal2\ chassis\ offering[uuid\:%s]\ is\ not\ Enabled = 未启用Baremetal2机箱产品[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:50 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:711 # args: -not\ dest\ host\ found\ in\ db,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = 没有在物理机上发现数据库,不能发送更改密码的指令到这个物理机上 +do\ not\ set\ chassisUuid\ and\ chassisOfferingUuid\ at\ the\ same\ time = 不要同时设置Chassisuuid和ChassisOfferuuid -# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:51 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:619 # args: -not\ system\ tag\ found\ on\ vm,\ vm\ must\ have\ the\ following\ system\ tag\:\ qemuga,\ if\ you\ installed\ qemu-ga\ yourself,\ please\ use\ CreateSystemTag\ first. = 没有发现系统标签在云主机上,云主机必须有系统标签: qemuga。如果你已经安装了qemu-ga,请先使用 CreateSystemTag +no\ need\ to\ set\ chassisOfferingUuid\ because\ the\ instance\ has\ been\ assigned\ an\ chassis\ already = 无需设置Chassisofferinguuid,因为实例已分配机箱 -# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:54 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:623 # args: -not\ account\ preference\ found,\ \ send\ change\ password\ cmd\ to\ the\ host! = 没有优先级账户去发送改变密码的指令到物理机 +no\ need\ to\ set\ chassisOfferingUuid\ because\ the\ instance\ has\ been\ assigned\ an\ chassis\ offering\ already = 无需设置ChassisOfferinguuid,因为已为实例分配了机箱产品 -# at: src/main/java/org/zstack/compute/vm/DeleteVmGC.java:50 -# args: hostUuid -the\ host[uuid\:%s]\ is\ not\ connected = 物理机[uuid:{0}]不是Connected状态 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:631 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ does\ not\ exist = Baremetal2机箱[uuid:{0}]不存在 -# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:40 -# args: vmUuid,isoUuid -VM[uuid\:%s]\ has\ attached\ ISO[uuid\:%s] = 云主机[uuid:{0}]已经加载了ISO[uuid:{1}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:636 +# args: msg.getChassisUuid(),bm.getChassisOfferingUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ belonging\ to\ chassis\ offering[uuid\:%s] = Baremetal2机箱[uuid:{0}]不属于机箱产品[uuid:{1}] -# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:48 -# args: vmUuid -All\ vm[uuid\:%s]\ CD-ROMs\ have\ mounted\ ISO = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:641 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ Enabled = 未启用Baremetal2机箱[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:77 -# args: mac -This\ is\ not\ a\ valid\ MAC\ address\ [%s] = 这是一个无效的MAC地址 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:645 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ has\ already\ been\ allocated = 已分配Baremetal2机箱[uuid:{0}] -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:87 -# args: mac -Not\ a\ valid\ MAC\ address\ [%s] = 这是一个无效的MAC地址[{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:763 +# args: msg.getGatewayUuid(),msg.getChassisUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ in\ the\ same\ cluster\ with\ chassis[uuid\:%s] = Baremetal2网关[uuid:{0}]与机箱[uuid:{1}]不在同一集群中 -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:90 -# args: -Disallowed\ address = 不被允许的MAC地址 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:685 +# args: msg.getZoneUuid() +zone[uuid\:%s]\ is\ specified\ but\ it's\ not\ Enabled,\ can\ not\ create\ baremetal2\ instance\ from\ it = 区域[uuid:{0}]已指定但未启用,无法从中创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MacOperator.java:93 -# args: mac -Expected\ unicast\ mac\ address,\ found\ multicast\ MAC\ address\ [%s] = 期望的是一个单播的MAC地址,但找到的是一个组播的MAC地址[{0}] +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:699 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ is\ specified\ but\ it's\ not\ an\ Enabled\ baremetal2\ cluster,\ can\ not\ create\ baremetal2\ instance\ from\ it = 指定了集群[uuid:{0}],但它不是启用的BareMetal2集群,无法从中创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:192 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:717 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = Baremetal2机箱[uuid:{0}]未启用,无法从中创建Baremetal2实例 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:722 +# args: msg.getChassisUuid() +baremetal2\ chassis[uuid\:%s]\ is\ not\ Available,\ can't\ create\ baremetal2\ instance\ from\ it = Baremetal2机箱[uuid:{0}]不可用,无法从中创建Baremetal2实例 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:732 +# args: msg.getChassisOfferingUuid() +baremetal2\ chassis\ offering[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = Baremetal2机箱产品[uuid:{0}]未启用,无法从中创建Baremetal2实例 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:743 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = Baremetal2网关[uuid:{0}]未启用,无法从中创建Baremetal2实例 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:748 +# args: msg.getGatewayUuid() +baremetal2\ gateway[uuid\:%s]\ is\ not\ Connected,\ can't\ create\ baremetal2\ instance\ from\ it = Baremetal2网关[uuid:{0}]未连接,无法从中创建Baremetal2实例 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:780 # args: -vm[uuid\:\ %s]'s\ state\ is\ not\ Stopped\ now,\ cannot\ operate\ 'changevmimage'\ action = +image\ cannot\ be\ empty\ unless\ chassis\ is\ in\ direct\ mode = 除非机箱处于直接模式,否则镜像不能为空 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:602 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:787 # args: -can\ not\ find\ image\ store\ backup\ storage,\ unable\ to\ commit\ volume\ snapshot\ as\ image = +direct\ mode\ not\ support\ choose\ image = 直接模式不支持选择镜像 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:794 +# args: msg.getImageUuid() +image[uuid\:%s]\ does\ not\ exist = 镜像[uuid:{0}]不存在 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:397 -# args: vivo.getRootVolumeUuid() -cannot\ find\ backupStorage\ for\ volume\:\ %s = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:800 +# args: disk.getUuid(),image.getUuid() +Chassis\ disk[%s]\ not\ have\ enough\ capacity\ for\ image[%s] = 机箱磁盘[{0}]没有足够的容量用于镜像[{1}] -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:898 -# args: inv.getInventory().getUuid(),state -vm\ running\ on\ local\ storage\ %s\ state\ is\ %s\ not\ running/stopped/paused,\ can\ not\ attach\ volume = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:805 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ not\ Enabled,\ can't\ create\ baremetal2\ instance\ from\ it = 镜像[uuid:{0}]未启用,无法从中创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1120 -# args: pvo.getType(),bsType -Destination\ PrimaryStorageType\ is\ %s,\ but\ the\ selected\ BackupStorageType\ for\ source\ Volume\ is\ %s,\ which\ cannot\ be\ matched = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:810 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ not\ Ready,\ can't\ create\ baremetal2\ instance\ from\ it = 镜像[uuid:{0}]未就绪,无法从中创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1507 -# args: -direction\ must\ be\ set\ to\ in\ or\ out = 方法必须设置in或者out +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:815 +# args: msg.getImageUuid(),image.getMediaType() +image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ can\ be\ used\ to\ create\ baremetal2\ instance = 镜像[uuid:{0}]的媒体类型为:{1},只有RootVolumeTemplate可用于创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1549 -# args: inbound -inboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = 下行带宽不能超过{0} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:820 +# args: image.getFormat(),BareMetal2InstanceConstant.IMAGE_FORMAT_FOR_BM +image[uuid\:%s]\ is\ of\ format\:\ %s,\ only\ %s\ can\ be\ used\ to\ create\ baremetal2\ instance = 镜像[uuid:{0}]的格式为:{1},只有{2}可用于创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1560 -# args: outbound -outboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = 上行带宽不能超过{0} +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:826 +# args: image.getUuid() +image[uuid\:%s]\ is\ not\ baremetal2\ image,\ can't\ create\ baremetal2\ instance\ from\ it = 镜像[uuid:{0}]不是BareMetal2镜像,无法从中创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1651 -# args: self.getUuid() -vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ nic\ qos = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:832 +# args: BareMetal2GlobalProperty.BAREMETAL2_SUPPORTED_BOOT_MODE +only\ image\ with\ boot\ mode\ %s\ is\ supported\ to\ create\ baremetal2\ instance = 仅支持引导模式为{0}的镜像来创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1656 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:841 # args: -vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ nic\ qos = +different\ boot\ mode\ between\ the\ image\ and\ chassis/offering = 镜像和机箱/产品之间的引导模式不同 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2056 -# args: amsg.getVmInstanceUuid() -not\ dest\ host\ found\ in\ db\ by\ uuid\:\ %s,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = 没有在物理机{0}上发现数据库,不能发送更改密码的指令到这个物理机上 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:851 +# args: clusterArchitecture,image.getArchitecture() +the\ architecture\ of\ baremetal2\ cluster[arch\:%s]\ and\ image[arch\:%s]\ don't\ match = BareMetal2集群[arch:{0}]的体系结构与镜像[arch:{1}]不匹配 -# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2084 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:863 +# args: msg.getDataDiskOfferingUuids() +not\ all\ disk\ offerings[uuids\:%s]\ are\ Enabled,\ can\ not\ create\ baremetal2\ instance\ from\ them = 并非所有磁盘产品[uuid:{0}]都已启用,无法从中创建BareMetal2实例 + +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceApiInterceptor.java:890 # args: -state\ is\ not\ correct\ while\ change\ password. = 该状态不支持修改密码 +cannot\ decide\ which\ zone\ the\ baremetal2\ instance\ should\ be\ created\ in = 无法确定应在哪个区域中创建BareMetal2实例 -# at: src/main/java/org/zstack/compute/vm/VmAllocateCdRomFlow.java:55 -# args: spec.getVmInventory().getUuid() -vm[uuid\:%s]\ cdRom\ deviceId\ repetition = +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceBase.java:476 +# args: +baremetal2\ instance[uuid\:%s]\ is\ either\ not\ exist\ or\ not\ Connected,\ cannot\ change\ its\ password = Baremetal2实例[uuid:{0}]不存在或未连接,无法更改其密码 -# at: src/main/java/org/zstack/compute/vm/VmAllocateNicFlow.java:81 -# args: v.getUuid() -there\ is\ no\ available\ ipRange\ on\ L3\ network\ [%s] = L3网络[{0}]中没有可用的网络段 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceManagerImpl.java:386 +# args: releaseTag +%s\ can\ only\ be\ created\ or\ deleted = 只能创建或删除{0} -# at: src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java:49 -# args: spec.getVmInventory().getUuid() -\ Can\ not\ find\ the\ vm's\ host,\ please\ start\ the\ vm[%s],\ then\ mount\ the\ disk = 未找到虚拟机的物理机,请重启虚拟机[{0}],然后挂载云盘 +# at: src/main/java/org/zstack/baremetal2/instance/BareMetal2InstanceManagerImpl.java:397 +# args: releaseTag +%s\ can\ only\ be\ created\ or\ deleted\ when\ the\ baremetal2\ instance\ is\ Running = 只能在运行BareMetal2实例时创建或删除{0} -# at: src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java:68 -# args: iso.getUuid(),host.getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() -cannot\ find\ the\ iso[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ running\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = 不能发现iso[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \n1. 镜像服务器是否已经挂载到区域中的任何运行状态的云主机[name: {2}, uuid:{3}]上;\n2. 如果镜像服务器不是处于连接状态,请尝试重连 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:112 +# args: dhcpInterface,dhcpRangeStartIp,dhcpRangeEndIp,dhcpRangeNetmask,dhcpRangeGateway +there\ already\ exists\ a\ baremetal2\ provision\ network\ with\ dhcpInterface\ \=\ %s,\ dhcpRangeStartIp\ \=\ %s,\ dhcpRangeEndIp\ \=\ %s,\ dhcpRangeNetmask\ \=\ %s,\ dhcpRangeGateway\ \=\ %s = 已存在DHCPINTERFACE={0}、DHCPRANGESTARTIP={1}、DHCPRANGEENDIP={2}、DhcpRangeNetMask={3}、DhcpRangeGateway={4}的BareMetal2配置网络 -# at: src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java:92 -# args: imageUuid,spec.getVmInventory().getName(),spec.getVmInventory().getUuid() -cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage.\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = 不能发现镜像[uuid:{0}]在任何处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \n1. 镜像服务器是否已经过载到区域中的云主机[name: {1}, uuid:{2}]中;\n2. 如果镜像服务器不是处于连接状态,请尝试重连 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:123 +# args: msg.getNetworkUuid() +cannot\ update\ baremetal2\ provision\ network[uuid\:%s]\ dhcp\ configuration\ when\ there\ are\ instances\ depending\ on\ it = 当有实例依赖于网络[uuid:{0}]DHCP配置时,无法更新该配置 -# at: src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java:86 -# args: imageUuid,spec.getVmInventory().getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() -cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = 不能发现镜像[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \n1. 镜像服务器是否已经过载到区域中的云主机[name: {2}, uuid:{3}]中;\n2. 如果镜像服务器不是处于Connected状态,请尝试重连 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:141 +# args: netmask +baremetal2\ provision\ network\ dhcp\ range\ netmask\ %s\ is\ invalid = Baremetal2设置网络DHCP范围网络掩码{0}无效 -# at: src/main/java/org/zstack/compute/vm/VmImageSelectBackupStorageFlow.java:114 -# args: zoneUuid,isoImageUuid -no\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s]\ contains\ the\ ISO[uuid\:%s] = 没有包含着ISO[uuid:{1}]的镜像服务器添加到区域[uuid:{0}] +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:147 +# args: begin,end +baremetal2\ provision\ network\ start\ ip\ %s\ and\ stop\ ip\ %s\ do\ not\ belong\ to\ the\ same\ subnet = Baremetal2配置网络启动IP{0}和停止IP{1}不属于同一子网 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:341 -# args: msg.getVmInstanceUuid(),msg.getIsoUuid() -VM[uuid\:%s]\ already\ has\ an\ ISO[uuid\:%s]\ attached = 云主机[uuid:{0}]已经挂载了ISO[uuid:{1}] +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:157 +# args: msg.getNetworkUuid() +cannot\ delete\ baremetal2\ provision\ network[uuid\:%s]\ when\ there\ are\ instances\ depending\ on\ it = 有实例依赖于BareMetal2配置网络[uuid:{0}]时,无法删除该网络 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:500 -# args: ipv4Count -there\ are\ %d\ ipv4\ network\ on\ same\ nic = +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:171 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ non-baremetal2\ cluster[uuid\:%s] = 无法将BareMetal2设置网络[uuid:{0}]连接到非BareMetal2集群[uuid:{1}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:133 -# args: msg.getVmInstanceUuid(),vo.getState().toString() -Can\ not\ create\ CD-ROM\ for\ vm[uuid\:%s]\ which\ is\ in\ state[%s]\ = +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:182 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +baremetal2\ provision\ network[uuid\:%s]\ is\ already\ attached\ to\ cluster[uuid\:%s] = Baremetal2配置网络[uuid:{0}]已连接到集群[uuid:{1}] + +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:188 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ cluster[uuid\:%s]\ because\ the\ cluster\ already\ have\ one = 无法将BareMetal2设置网络[uuid:{0}]附加到集群[uuid:{1}],因为该集群已有一个网络 + +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:198 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ cluster[uuid\:%s]\ because\ they\ are\ not\ in\ the\ same\ zone = 无法将BareMetal2配置网络[uuid:{0}]附加到集群[uuid:{1}],因为它们不在同一区域中 + +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:219 +# args: msg.getNetworkUuid(),msg.getClusterUuid() +cannot\ attach\ baremetal2\ provision\ network[uuid\:%s]\ to\ cluster[uuid\:%s],\ because\ we\ need\ to\ make\ sure\ that\ every\ gateway\ attached\ to\ the\ clusters\ that\ have\ the\ same\ provision\ network\ attached = 无法将BareMetal2配置网络[uuid:{0}]连接到集群[uuid:{1}],因为我们需要确保连接到具有相同配置网络的集群的每个网关 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:141 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:241 # args: -rootDiskSize\ is\ needed\ when\ image\ media\ type\ is\ ISO = 当镜像类型是ISO时根云盘大小需要设置 +provision\ network\ should\ not\ have\ the\ same\ interface\ name\ with\ l2\ networks\ that\ are\ already\ attached\ to\ the\ cluster = 设置网络不应与已连接到集群的二层网络具有相同的接口名称 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:151 -# args: msg.getVmInstanceUuid(),msg.getHostUuid() -the\ vm[uuid\:%s]\ is\ already\ on\ host[uuid\:%s] = 云主机[uuid:{0}]已经运行于物理机[uuid:{1}]上 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:251 +# args: msg.getNetworkUuid() +cannot\ detach\ baremetal2\ provision\ network[uuid\:%s]\ when\ there\ are\ running\ instances\ depending\ on\ it = 存在依赖于Baremetal2配置网络[uuid:{0}]的正在运行的实例时,无法分离该网络 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:207 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:258 # args: -the\ VM\ cannot\ do\ online\ cpu/memory\ update\ because\ it\ is\ not\ of\ NUMA\ architecture.\ Please\ stop\ the\ VM\ then\ do\ the\ cpu/memory\ update\ again = 云主机无法执行在线升级CPU/内存,因为不是NUMA架构。请关闭该云主机再尝试 +networkUuids\ is\ empty = 网络uuid为空 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:213 -# args: vo.getUuid(),vo.getState(),StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), ",") -The\ state\ of\ vm[uuid\:%s]\ is\ %s.\ Only\ these\ state[%s]\ is\ allowed\ to\ update\ cpu\ or\ memory. = 云主机[uuid:{0}]的状态为{1}。只有这些状态[{2}]允许在线升级CPU/内存 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkApiInterceptor.java:265 +# args: msg.getNetworkUuids() +not\ all\ baremetal2\ provision\ networks\ exist\ in\ %s = {0}中并不存在所有BareMetal2配置网络 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:184 -# args: vo.getUuid() -can't\ decrease\ capacity\ when\ vm[uuid\:%s]\ is\ running = 无法在云主机[uuid:{0}]运行时减少容量 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java:496 +# args: networkUuid,gatewayUuid,reply.getError() +failed\ to\ prepare\ provision\ network[uuid\:%s]\ in\ gateway[uuid\:%s]\:\ %s = 无法准备设置网络[uuid:{0}](在网关[uuid:{1}]中):{2} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:224 -# args: vo.getUuid() -can't\ decrease\ cpu\ of\ vm[uuid\:%s]\ when\ it\ is\ running = 无法在云主机[uuid:{0}]运行时减少CPU数目 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java:308 +# args: networkUuid,gatewayUuid,reply.getError() +failed\ to\ update\ provision\ network[uuid\:%s]\ in\ gateway[uuid\:%s]\:\ %s = 无法更新设置网络[uuid:{0}](在网关[uuid:{1}]中):{2} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:230 -# args: vo.getUuid() -can't\ decrease\ memory\ size\ of\ vm[uuid\:%s]\ when\ it\ is\ running = 无法在云主机[uuid:{0}]运行时减少容量 +# at: src/main/java/org/zstack/baremetal2/provisionnetwork/BareMetal2ProvisionNetworkBase.java:650 +# args: msg.getNetworkUuid() +failed\ to\ allocate\ ip\ from\ baremetal2\ provision\ network[uuid\:%s] = 无法从BareMetal2配置网络[uuid:{0}]分配IP -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:241 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:73 # args: -either\ l3NetworkUuids\ or\ imageUuid\ must\ be\ set = L3网络的uuid们或者镜像的uuid必须被设置 +billing\ is\ disabled = 已禁用计费 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:256 -# args: ip -%s\ is\ not\ a\ valid\ IPv4\ address = {0}不是有效的IPv4地址 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:120 +# args: +the\ start\ date\ must\ be\ greater\ than\ the\ end\ date = 开始时间必须早于结束时间 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:282 -# args: ip,vmNicVO.getUuid() -ip\ address\ [%s]\ already\ set\ to\ vmNic\ [uuid\:%s] = IP地址[{0}]已经设置到网卡[uuid:{1}] +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:124 +# args: +resourceType\ and\ resourceUuid\ cannot\ be\ empty\ at\ the\ same\ time = ResourceType和Resourceuuid不能同时为空 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:267 -# args: ip,rangeVO.getNetworkCidr() -ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [%s] = IP地址[{0}]不在IP地址段[{1}]范围内 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:244 +# args: +the\ minimal\ resource\ unit\ is\ megabyte,\ cannot\ be\ byte = 资源的最小单位必须为MB,而不是byte -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:276 -# args: ip -%s\ is\ not\ a\ valid\ IPv6\ address = {0}不是有效的IPv6地址 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:252 +# args: +price\ must\ be\ 0\ and\ 999999999.99 = 价格必须为0和999999999.99 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:287 -# args: ip,rangeVO.getStartIp(),rangeVO.getEndIp() -ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [startIp\ %s,\ endIp\ %s] = IP地址[{0}]不在IP地址段[{1}-{2}]范围内 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:259 +# args: +gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ empty = GPU类型的价格必须绑定一个GPU设备 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:321 -# args: msg.getVmInstanceUuid(),msg.getL3NetworkUuid() -the\ VM[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = 云主机[uuid:{0}]在L3网络[uuid:{1}]上没有任何网卡 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:266 +# args: price.getSystemTags() +gpu\ price\ must\ be\ bound\ to\ gpu\ uuid\ %s = GPU类型的价格必须绑定一个正确的GPU设备{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:332 -# args: o,msg.getBootOrder() -invalid\ boot\ device[%s]\ in\ boot\ order%s = 在启动列表{1}中的设备[{0}]启动失败 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:226 +# args: resourceName +resourceName[%s]\ is\ invalid = 资源名称[{0}]无效 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:356 -# args: cdRomUuid -The\ cdRom[uuid\:%s]\ does\ not\ exist = +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:278 +# args: msg.getAccountUuid() +The\ account[uuid\=%s]\ has\ attach\ price\ table = 帐户[uuid={0}]具有附加价格表 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:360 -# args: msg.getVmInstanceUuid(),cdRomUuid -VM[uuid\:%s]\ cdRom[uuid\:%s]\ has\ mounted\ the\ ISO = +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:284 +# args: msg.getUuid() +This\ priceTable[uuid\=%s]\ is\ not\ allowed\ to\ delete = 不允许删除此价格表[uuid={0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:378 -# args: msg.getVmInstanceUuid() -VM[uuid\:%s]\ has\ multiple\ ISOs\ attached,\ specify\ the\ isoUuid\ when\ detaching = 云主机[uuid:{0}]已经加载了多个ISO,卸载ISO时需要指定ISO的Uuid +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:298 +# args: +accountUuid/tableUuid\ only\ one\ of\ them\ is\ allowed\ to\ be\ set = Accountuuid/Tableuuid只允许设置其中一个 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:482 -# args: l3Uuid -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ disabled = 不能挂载L3网络,因为该L3网络[uuid:{0}]处于未启动状态 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:304 +# args: +endDateInLong\ is\ not\ allowed\ to\ be\ negative = EndDateInLong不允许为负数 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:553 -# args: staticIp,l3Uuid -the\ static\ IP[%s]\ is\ not\ in\ any\ IP\ range\ of\ the\ L3\ network[uuid\:%s] = 该静态IP[{0}]不在L3网络[uuid:{1}]的任何IP段 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:308 +# args: +endDateInLong\ and\ setEndDateInLongBaseOnCurrentTime\ are\ not\ allowed\ to\ set\ at\ the\ same\ time = 不允许同时设置EndDateInLong和SetEndDateInLongBaseOnCurrentTime -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:560 -# args: staticIp,l3Uuid -the\ static\ IP[%s]\ has\ been\ occupied\ on\ the\ L3\ network[uuid\:%s] = 该静态IP[{0}]已经存在在L3网络[uuid:{1}]中 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:321 +# args: +endDateInLong\ is\ set,\ no\ modification\ allowed = EndDateInLong已设置,不允许修改 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:432 -# args: msg.getVmInstanceUuid(),state -unable\ to\ attach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = 无法挂载L3网络。云主机[uuid: {0}]既不处于Running也不处于Stopped状态中,当前状态为{1} +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:329 +# args: +endDateInLong\ cannot\ be\ earlier\ than\ dateInLong = EndDateInlong不能早于DateInlong -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:446 -# args: newAddedL3Uuids,l2Uuids -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ different\ l2\ networks\ [uuids\:%s] = 不能挂载L3网络,L3网络[uuid:{0}]属于不同的L2网络 +# at: src/main/java/org/zstack/billing/BillingApiInterceptor.java:336 +# args: +billing\ is\ enable,\ This\ operation\ is\ only\ allowed\ in\ the\ disabled\ state = 计费已启用,只有在禁用状态下才能执行此操作 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:453 -# args: newAddedL3Uuids,l2Uuids -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ l2\ networks\ [uuids\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:451 +# args: +priceKeyName\ is\ null = PriceKeyName为空 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:465 -# args: attachedL3Uuids,msg.getVmInstanceUuid() -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 不能挂载L3网络,l3网络[uuid:{0}]已经挂载到云主机[uuid: {1}]上了 +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:1084 +# args: currentPriceVO.getDateInLong() +dateInLong\ is\ less\ than\ %s = DateInLong小于{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:472 -# args: attachedL3Uuids,msg.getVmInstanceUuid() -unable\ to\ attach\ a\ non-guest\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:3090 +# args: +please\ set\ the\ correct\ priceUserConfig,\ for\ example\:\ priceUserConfig\:{\nrootVolume\:{\npriceKeyName\:\"priceKeyName\"}} = 请设置正确的priceUserConfig,例如:priceUserConfig:'{\nRootVolume:{\nPriceKeyName:\“ priceKeyName\”}'} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:485 -# args: l3Uuid -unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = 不能连接三层网络。这个三层网络[uuid:{0}]是系统网络,但虚拟机是一个用户虚拟机 +# at: src/main/java/org/zstack/billing/BillingManagerImpl.java:3105 +# args: +please\ set\ the\ correct\ priceUserConfig,\ for\ example\:\ priceUserConfig\:{\nvolume\:{\npriceKeyName\:\"priceKeyName\"}} = 请设置正确的priceUserConfig,例如:priceUserConfig:'{\nVolume:{\nPriceKeyName:\“ priceKeyName\”}'} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:503 -# args: statefulIpv6 -there\ are\ %d\ ipv6\ stateful\ or\ stateless\ network\ on\ same\ nic = 不能挂载L3网络,有{0}个Stateful-DHCP类型或者Stateless-DHCP类型的网络属于同一个网卡 +# at: src/main/java/org/zstack/billing/ResourceSpendingHelper.java:49 +# args: resourceType +unsupported\ billing\ resource\ type\ [%s] = 不支持的计费资源类型[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:535 -# args: e.getKey(),newAddedL3Uuids -static\ ip\ l3\ uuid[%s]\ is\ not\ included\ in\ nic\ l3\ [%s] = 静态IP的L3网络[uuid:{0}]不在网卡的L3列表[uuid:{1}]中 +# at: src/main/java/org/zstack/cas/CasInterceptor.java:31 +# args: type +there\ is\ no\ such\ type[%s]\ in\ CAS = CAS中没有此类型[{0}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:583 -# args: msg.getVmInstanceUuid(),state -unable\ to\ attach\ the\ nic.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:590 -# args: vmNicVO.getVmInstanceUuid() -unable\ to\ attach\ the\ nic.\ The\ nic\ has\ been\ attached\ with\ vm[uuid\:\ %s] = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:601 -# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() -unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:606 -# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() -unable\ to\ attach\ the\ nic\ with\ a\ non-guest\ L3\ network.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:615 -# args: l3NetworkVO.getUuid() -unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ disabled = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:618 -# args: l3NetworkVO.getUuid() -unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = +# at: src/main/java/org/zstack/cas/CasLoginBackend.java:76 +# args: loginContext.getUsername() +wrong\ virtual\ ID[name\:%s],\ not\ existing\ or\ wrong\ password = 错误的virtual ID[名称:{0}], 密码不存在或者密码错误 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:625 -# args: l3NetworkVO.getL2NetworkUuid() -unable\ to\ attach\ the\ nic.\ Its\ l2\ network\ [uuid\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = +# at: src/main/java/org/zstack/cas/CasLoginBackend.java:57 +# args: +missing\ property\ of\ cas\ driver = 缺少CAS驱动程序的属性 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:640 -# args: msg.getVmInstanceUuid(),state -unable\ to\ detach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = 不能卸载L3网络,云主机[uuid: {0}]不是运行状态或者暂停状态,状态为{1} +# at: src/main/java/org/zstack/cas/CasLoginBackend.java:64 +# args: casDriverType +Unsupported\ cas\ driver\:\ %s = 不支持的CAS驱动程序:{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:666 -# args: msg.getVmInstanceUuid(),state -vm[uuid\:%s]\ can\ only\ attach\ volume\ when\ state\ is\ Running\ or\ Stopped,\ current\ state\ is\ %s = 云主机[uuid:{0}]挂载盘时状态只能是运行或者暂停状态,而现在的状态是{1} +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:63 +# args: msg.getUuid() +cannot\ find\ such\ ResourceStackVO\ by\ uuid\ [%s] = 无法通过uuid[{0}]找到此类ResourceStackVO -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:674 -# args: -image\ mediaType\ is\ ISO\ but\ missing\ root\ disk\ settings = +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:67 +# args: validStatus +restart\ resource\ stack\ only\ support\ %s\ status! = 重新启动资源堆栈仅支持{0}状态! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:678 +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:173 # args: -Unexpected\ root\ disk\ settings = +templateContent\ and\ uuid\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = TemplateContent和uuid不能同时为空或同时设置! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:689 -# args: -Missing\ CPU/memory\ settings = +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:98 +# args: validStatus +expect\ %s\ status! = 预期{0}状态! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:693 +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:118 # args: -Unexpected\ CPU/memory\ settings = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:881 -# args: cdRomIsoUuid -The\ image[uuid\=%s]\ does\ not\ exist = +templateContent\ and\ templateUuid\ mustn't\ both\ be\ empty! = TemplateContent和TemplateUuid不能同时为空! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:886 +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:129 # args: -Do\ not\ allow\ to\ mount\ duplicate\ ISO = +templateContent\ and\ url\ mustn't\ both\ be\ empty\ or\ both\ be\ set! = TemplateContent和URL不能同时为空或同时设置! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:901 +# at: src/main/java/org/zstack/cloudformation/CloudFormationInterceptor.java:145 # args: -The\ console\ password\ cannot\ start\ with\ 'password'\ which\ may\ trigger\ a\ VNC\ security\ issue = 控制台密码不能以password开头,这样可能导致一个VNC安全问题 +only\ admin\ could\ enable/disable\ system\ StackTemplate = 只有管理员才能启用/禁用系统堆栈模板 -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:910 -# args: msg.getVmNicUuid() -vmNic[uuid\:%s]\ is\ not\ attached\ to\ vmInstance = 网卡[uuid{0}]还没有绑定到云主机 - -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:917 -# args: msg.getL3NetworkUuid(),msg.getVmNicUuid() -L3\ network[uuid\:%s]\ has\ already\ been\ to\ attached\ vmNic[uuid\:%s] = 三层网络[uuid:{0}]已经绑定到网卡[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1032 +# args: vo.getName() +cannot\ delete\ or\ update\ system\ template\:\ %s = 无法删除或更新系统模板:{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:937 -# args: ipVO.getL3NetworkUuid(),msg.getVmNicUuid() -there\ is\ another\ IPv6\ stateful-dhcp\ network[uuid\:%s]\ attached\ vmNic[uuid\:%s] = 已经有另外一个有状态的IPv6网络[uuid:{0}]绑定到网卡[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:322 +# args: msg.getVmInstanceUuid() +no\ stackUuid\ found\ for\ the\ vmInstance[%s] = 找不到VMInstance[{0}]stackUuid -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:926 -# args: ipVO.getL3NetworkUuid(),msg.getVmNicUuid() -there\ is\ another\ IPv4\ network[uuid\:%s]\ attached\ vmNic[uuid\:%s] = 已经有另外一个IPv4网络[uuid:{0}]绑定到网卡[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:612 +# args: msg.getUuid() +ResourceStackVO\:\ [%s]\ has\ been\ deleted... = ResourceStackVO:[{0}]已被删除.. -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:955 -# args: l3Vo.getL2NetworkUuid(),oldL3.getL2NetworkUuid() -l2Network\ [uuid\:%s]\ to\ be\ attached\ is\ different\ from\ l2Network\ [uuid\:%s]\ of\ the\ nic = 将被添加的二层网络[uuid:{0}]和网卡当前的二层网络[uuid:{1}]不同 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:642 +# args: uuid +ResourceStackVO\ [%s]\ already\ been\ deleted! = ResourceStackVO[{0}]已被删除! -# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:974 -# args: vmCdRomVO.getUuid() -The\ CdRom[%s]\ Already\ the\ default = +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:871 +# args: +templateContent\ must\ be\ set! = 必须设置TemplateContent! -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:235 -# args: vo.getUuid(),vo.getName() -vm[uuid\:%s,\ name\:%s]\ has\ been\ deleted = 云主机[uuid:{0}, name:{1}]已经被删除了 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:865 +# args: template.getUuid() +template\ [%s]\ chosen\ is\ disabled = 所选模板[{0}]已禁用 -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:766 -# args: self.getUuid(),l3Uuid -the\ vm[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = 云主机[uuid:{0}] 没有网卡在L3网络[uuid:{1}]上 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:955 +# args: p.getParamName(),p.getResourceType() +cannot\ find\ parameters\ for\ %s,\ which\ is\ %s\ type,\ please\ check\ parameters = 找不到{1}类型的{0}的参数,请检查参数 -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:1154 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1025 # args: -the\ vm\ has\ been\ deleted = 云主机已经被删除了 - -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:3822 -# args: isoUuid,psUuid,self.getName(),self.getUuid() -the\ ISO[uuid\:%s]\ is\ on\ backup\ storage\ that\ is\ not\ compatible\ of\ the\ primary\ storage[uuid\:%s]\ where\ the\ VM[name\:%s,\ uuid\:%s]\ is\ on = ISO[uuid:{0}]在镜像服务器上,这个ISO不能兼容主存储[uuid:{1}]在云主机[name:{2}, uuid:{3}]上 +StackTemplateVO\ has\ been\ deleted... = StackTemplateVo已被删除.. -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:4224 -# args: self.getHostUuid(),cpuNum - oldCpuNum,struct.alignedMemory - oldMemorySize -host[uuid\:%s]\ capacity\ is\ not\ enough\ to\ offer\ cpu[%s],\ memory[%s\ bytes] = 物理机[uuid:{0}]无法提供CPU: [{1}],内存: [{2} bytes] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1048 +# args: +content\ must\ be\ set\ by\ templateContent\ or\ url! = 必须通过TemplateContent或URL设置内容! -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:4444 -# args: isoUuid,self.getUuid() -ISO[uuid\:%s]\ is\ not\ attached\ to\ VM[uuid\:%s] = ISO[uuid:{0}]未被加载到云主机[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1066 +# args: +get\ null\ content\ input = 获取空内容输入 -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5174 -# args: self.getUuid() -unable\ to\ start\ the\ vm[uuid\:%s].\ It\ doesn't\ have\ any\ nic,\ please\ attach\ a\ nic\ and\ try\ again = 无法启动虚拟机[uuid:{0}]。该虚拟机没有网卡,请添加网卡后再试 +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1073 +# args: result.getTemplateVersion() +invalid\ cloudformation\ template\ version\:\ %s = CloudFormation模板版本无效:{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5411 -# args: cdRomSpecs.size(),max -One\ vm\ cannot\ create\ %s\ CDROMs,\ vm\ can\ only\ add\ %s\ CDROMs = +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1087 +# args: msg.getUuid() +StackTemplateVO\:\ [%s]\ has\ been\ deleted... = StackTemplateVo:[{0}]已删除.. -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:6301 -# args: msg.getVmInstanceUuid(),max -VM[uuid\:%s]\ can\ only\ add\ %s\ CDROMs = +# at: src/main/java/org/zstack/cloudformation/CloudFormationManagerImpl.java:1385 +# args: +[cloudformation]\ filterName\ must\ be\ cloudformation\:true\ or\ cloudformation\:false = [cloudFormation]FilterName必须为cloudFormation:true或cloudFormat:false -# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:6371 -# args: self.getUuid(),msg.getPriority(),reply.getError() -update\ vm[%s]\ priority\ to\ [%s]\ failed,because\ %s = +# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:31 +# args: +get\ null\ element\ in\ template\ content = 获取模板内容中的空元素 -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:58 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceStartNewCreatedVmExtensionPoint[%s]\ refuses\ to\ create\ vm[uuid\:%s]\ because\ %s = VmInstanceStartNewCreatedVmExtensionPoint[{0}] 因为{2} 拒绝创建虚拟机[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:35 +# args: +template\ must\ contain\ [ZStackTemplateFormatVersion] = 模板必须包含[ZStackTemplateFormatVersion] -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:176 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceRebootExtensionPoint[%s]\ refuses\ to\ reboot\ vm[uuid\:%s]\ because\ %s = VmInstanceRebootExtensionPoint[{0}] 因为{2} 拒绝重启虚拟机[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/CloudFormationUtils.java:38 +# args: result.getTemplateVersion(),CloudFormationConstant.version +invalid\ ZStackTemplateFormatVersion\:\ [%s,\ expected\:\ %s] = 无效的ZStackTemplateFormatVersion:[{0},应为:{1}] -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:218 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceDestroyVmExtensionPoint[%s]\ refuses\ to\ destroy\ vm[uuid\:%s]\ because\ %s = VmInstanceDestroyVmExtensionPoint[{0}] 因为{2} 拒绝删除虚拟机[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/VmPortMonitorTask.java:124 +# args: l2Uuid +cannot\ find\ l2_bridge_name\ of\ l2[%s]\ from\ systemTag = 在系统标记中找不到L2[{0}]的L 2_Bridge_名称 -# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:259 -# args: ext.getClass().getName(),inv.getUuid(),err -VmInstanceStartExtensionPoint[%s]\ refuses\ to\ start\ vm[uuid\:%s]\ because\ %s = VmInstanceStartExtensionPoint[{0}] 因为{2} 拒绝启动虚拟机[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/VmPortMonitorTask.java:135 +# args: vm.getUuid() +cannot\ find\ default\ ip\ on\ vm[%s] = 在云主机[{0}]上找不到默认IP -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:251 +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:97 # args: -Spice\ certificate\ does\ not\ exist,\ Please\ check\ if\ spice\ tls\ is\ enabled = - -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:434 -# args: msg.getImageUuid(),msg.getZoneUuid() -the\ image[uuid\:%s]\ is\ not\ on\ any\ backup\ storage\ that\ has\ been\ attached\ to\ the\ zone[uuid\:%s] = 镜像[uuid:{0}]不在任何加载到区域[uuid:{1}]的镜像服务器上 - -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:502 -# args: image.getName(),image.getUuid() -the\ image[name\:%s,\ uuid\:%s]\ is\ an\ ISO,\ rootDiskSize\ must\ be\ set = 镜像[name:{0}, uuid:{1}]是一个IOS, 必须设置根云盘大小 - -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:542 -# args: image.getName(),image.getUuid() -zoneUuid\ must\ be\ set\ because\ the\ image[name\:%s,\ uuid\:%s]\ is\ on\ multiple\ backup\ storage = zoneUuid必须被设置,因为image[name:{0}, uuid:{1}]在多个镜像服务器上 +cannot\ find\ resource\ of\ properties\ set\ before! = 找不到以前设置的属性的资源! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1453 -# args: tuple.get(0, String.class),tuple.get(1, String.class) -unable\ to\ enable\ this\ function.\ There\ are\ multi\ nics\ of\ L3\ network[uuid\:%s]\ in\ the\ vm[uuid\:\ %s] = +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:152 +# args: value +invalid\ dynamic\ variables,\ which\ must\ contained\ ${\:\ %s = 动态变量无效,必须包含$'{:{0}' -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1466 -# args: hostname,tag -hostname[%s]\ specified\ in\ system\ tag[%s]\ is\ not\ a\ valid\ domain\ name = 在系统标签[{1}]中特别声明的主机名[{0}]不是一个有效的域名 +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:174 +# args: +verb\ must\ contain\ '\:\:'! = 谓词必须包含“::”! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1478 -# args: hostnameCount -only\ one\ hostname\ system\ tag\ is\ allowed,\ but\ %s\ got = 只允许通过系统标签设置一个主机名,但是实际上有{0} +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:218 +# args: t[0],last.getClass().getName() +need\ List\ for\ resource\ [%s]\ output\ here,\ but\ got\ %s. = 此处需要资源[{0}]输出的列表,但获得了{1}。 -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1514 -# args: ip,sysTag -%s\ is\ not\ a\ valid\ IPv6\ address.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationCreator.java:380 +# args: +Some\ actions\ are\ invalid = 某些操作无效 -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1508 -# args: ip,sysTag -%s\ is\ not\ a\ valid\ IPv4\ address.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = {0}不是一个有效的IPv4地址。请修改你关于静态IP的系统标签 +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:253 +# args: +no\ root\ element\ found,\ please\ check\ your\ cfn\ formation! = 找不到根元素,请检查您的CFN结构! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1530 -# args: ip,l3Uuid,cr.getReason() -IP[%s]\ is\ not\ available\ on\ the\ L3\ network[uuid\:%s]\ because\:\ %s = 在L3网络[uuid:{1}]中,IP[{0}]不可用, 因为{2} +# at: src/main/java/org/zstack/cloudformation/template/CloudFormationDecoder.java:432 +# args: e.getMessage() +Wrong\ json\ format,\ causes\:\ %s = 错误的JSON格式,导致:{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1573 -# args: uuid -l3\ network\ [uuid\:\ %s]\ is\ added\ to\ vm\ more\ than\ once = +# at: src/main/java/org/zstack/cloudformation/template/decoder/AbstractCfnRootDecoder.java:14 +# args: +CfnRootDecoder's\ weight\ must\ between\ 0-100,\ 0\ means\ decode\ first,\ default\ is\ 50 = cfnRootDecoder的权重必须介于0-100之间,0表示先解码,默认值为50 -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1567 -# args: statefulIpv6Count -there\ are\ %d\ ipv6\ stateful\ network\ on\ same\ nic = +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:45 +# args: +Condition\ body\ cannot\ support\ json\ null\ or\ array! = 条件体不支持JSON NULL或数组! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1590 -# args: primaryL3Uuid,sysTag -L3\ network[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ dualStackNic = +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:41 +# args: +Only\ support\ ZStack\ Template\ Functions\ in\ 'Condition'\ field! = 仅支持“条件”字段中的ZStack模板函数! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1595 -# args: primaryL3Uuid,secondaryL3Uuid -L3\ networks[primaryL3Uuid\:%s,\ secondaryL3Uuid\:%s]\ of\ dualStackNic\ is\ not\ on\ same\ l2\ network = +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:37 +# args: +Value\ must\ be\ boolean\ in\ 'Condition'\ field = “条件”字段中的值必须为布尔值 -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1606 -# args: secondaryL3Uuid -L3\ networks[uuid\:%s]\ does\ not\ have\ ip\ range = +# at: src/main/java/org/zstack/cloudformation/template/decoder/ConditionDecoder.java:30 +# args: key,es.size() +Condition\ key\:\ %s\ only\ support\ 1\ element\ in\ the\ json\ object\ of\ value,\ but\ got\ %d\ elements! = 条件键:{0}在值为的JSON对象中只支持1个元素,但得到了{1}个元素! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1629 -# args: tag,sameTag.getResourceUuid(),hostname,l3Uuid -conflict\ hostname\ in\ system\ tag[%s];\ there\ has\ been\ a\ VM[uuid\:%s]\ having\ hostname[%s]\ on\ L3\ network[uuid\:%s] = 系统标签的主机名存在冲突[{0}];已经存在以一个主机名为[{2}]的VM[uuid:{1}]出现在L3网络[uuid:{3}]中 +# at: src/main/java/org/zstack/cloudformation/template/decoder/DecoderUtils.java:91 +# args: msg +cannot\ find\ such\ msg\:\ %s\ for\ create = 无法为创建找到这样的消息:{0} -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1662 -# args: o,order -invalid\ boot\ device[%s]\ in\ boot\ order[%s] = 在引导顺序[{1}]中存在无效的引导设备[{0}] +# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:56 +# args: +Mapping\ value\ body\ cannot\ support\ null! = 映射值正文不能支持Null! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1680 -# args: resourceUuid -Already\ have\ one\ userdata\ systemTag\ for\ vm[uuid\:\ %s]. = 在虚拟机[uuid:{0}]已经存在一个userdata的系统标签 +# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:54 +# args: +Mapping\ value\ body\ cannot\ support\ json\ array! = 映射值主体不支持JSON数组! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1700 +# at: src/main/java/org/zstack/cloudformation/template/decoder/MappingDecoder.java:66 # args: -Shouldn't\ be\ more\ than\ one\ userdata\ systemTag\ for\ one\ vm. = 在一个虚拟机中不能存在多个userdata的系统标签 +mappingName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = 必须在结果中找到MappingName,否则它是无效的CFN JSON。 -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1823 -# args: type -vm\ machine\ type\ requires\ [q35,\ pc],\ but\ get\ [%s] = +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:84 +# args: +Mapping\ body\ cannot\ support\ json\ null! = 映射体不支持JSON NULL! -# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2235 -# args: ref.getResourceUuid() -the\ resource[uuid\:%s]\ is\ a\ ROOT\ volume,\ you\ cannot\ change\ its\ owner,\ instead,change\ the\ owner\ of\ the\ VM\ the\ root\ volume\ belongs\ to = 当前资源[uuid:{0}]是一个根云盘,你不能改变它的所有者,但是你能够修改对应VM的所有者 +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:82 +# args: +Mapping\ body\ cannot\ support\ non\ map\ value! = 映射体不支持非映射值! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:182 -# args: vmType -clean\ traffic\ is\ not\ supported\ for\ vm\ type\ [%s] = +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:57 +# args: +Output\ body\ cannot\ support\ json\ null! = 输出正文不支持JSON NULL! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:172 -# args: msg.getMac() -Duplicate\ mac\ address\ [%s] = 重复的MAC地址[{0}] +# at: src/main/java/org/zstack/cloudformation/template/decoder/OutputDecoder.java:70 +# args: +Description\ in\ Outputs\ must\ be\ String\ type! = 输出中的描述必须是字符串类型! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:91 -# args: VmInstanceState.Stopped,msg.getVmInstanceUuid() -Can\ not\ set\ security\ level\ to\ not\ %s\ vm\ [uuid\:%s] = 设置密级失败,无法对不处于{0}状态的虚拟机操作[uuid:{1}] +# at: src/main/java/org/zstack/cloudformation/template/decoder/ParameterDecoder.java:59 +# args: +paramName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = 必须在结果中找到ParamName,否则它是无效的CFN JSON。 -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:108 +# at: src/main/java/org/zstack/cloudformation/template/decoder/PreParameterDecoder.java:53 # args: -The\ operation\ only\ allows\ on\ user\ vm = +Parameters\ root\ body\ must\ be\ json\ object! = 参数根体必须是JSON对象! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:138 -# args: msg.getVmInstanceUuid(),volumeVOS.stream().map(VolumeVO::getUuid).collect(Collectors.toList()),primaryStorageUuid,(totalCapacity - snapshotsCapacity) * msg.getNames().size(),primaryStorageVO.getCapacity().getAvailableCapacity() -there\ are\ not\ enough\ capacity\ for\ full\ vm\ clone\ to\ vm[uuid\:\ %s],\ volumes[uuid\:\ %s]\ on\ primary\ storage[uuid\:\ %s]\ required\:\ %s\ bytes,\ current\ available\ capacity\ is\ %s\ bytes = 没有足够的空间对虚拟机[uuid: {0}]做整机克隆,主存储[uuid: {2}]上的云盘[uuid: {1}]共需要[{3}]字节的空间,目前主存储的可用空间为[{4}]字节 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:145 +# args: +Mappings\ root\ body\ must\ be\ json\ object! = 映射根体必须是JSON对象! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:152 -# args: msg.getVmNicUuid() -The\ nic\ [%s%s]\ is\ not\ mounted\ on\ the\ VM = 网卡[{0}]不能被挂载到虚拟机上 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:112 +# args: +resourceName\ must\ be\ found\ in\ result,\ or\ it\ is\ invalid\ cfn\ json. = ResourceName必须在结果中找到,或者它是无效的CFN JSON。 -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:158 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:123 # args: -The\ operation\ only\ allows\ on\ user\ vm\ = 该操作只能在用户虚拟机上进行 +Parameters\ body\ cannot\ support\ null! = 参数体不支持NULL! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:163 -# args: vmInstanceVO.getUuid() -The\ operation\ only\ allows\ when\ vm\ [%s]\ state\ is\ stopped\ = 该操作只有虚拟机[{0}]状态为已停止才能进行 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:68 +# args: +Resource\ value\ body\ cannot\ support\ null! = 资源值体不能支持null! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:192 -# args: msg.getVmInstanceUuid() -user\ has\ no\ privilege\ to\ change\ image\ of\ vm\ %s = 当前用户不能修改虚拟机{0}的镜像 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:48 +# args: resource.getResourceName(),e.getKey(),resource.getResourceName() +Resource\ %s\ cannot\ depends\ on\ itself,\ please\ check\ %s\ in\ Resource\ [%s] = 资源{0}不能依赖自身,请检查资源[{2}]中的{1} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:205 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:254 # args: -Can't\ change\ vm\ image\ when\ it's\ not\ stopped = +Resource\ root\ body\ must\ be\ json\ object! = 资源根体必须是JSON对象! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:211 +# at: src/main/java/org/zstack/cloudformation/template/decoder/ResourceDecoder.java:216 # args: -Can't\ change\ vm\ image\ without\ L3\ network = +Resource\ Type\ must\ be\ String! = 资源类型必须是字符串! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:226 -# args: msg.getVmInstanceUuid() -make\ sure\ the\ primary\ storage\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = 确认主存储[uuid:{0}]是可用的且已连接 +# at: src/main/java/org/zstack/cloudformation/template/function/IfTemplateFunction.java:42 +# args: cond +cannot\ find\ condition[%s]\ in\ 'Conditions' = 在“条件”中找不到条件[{0}] -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:241 -# args: msg.getVmInstanceUuid() -make\ sure\ the\ last\ host\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = 确定物理机[uuid:{0}]是可用的且已连接 +# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:42 +# args: e.getAsString() +expect\ 'true',\ 'false'\ for\ the\ object,\ but\ got\ %s = 该对象应为“ true ”和“ false ”,但得到了{0} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:260 -# args: msg.getVmInstanceUuid(),msg.getImageUuid() -user\ has\ no\ privilege\ to\ change\ root\ volume\ of\ vm\ %s\ using\ image\ %s = 当前用户不能修改使用镜像{1}的虚拟机{0}的根云盘 +# at: src/main/java/org/zstack/cloudformation/template/function/OrTemplateFunction.java:35 +# args: keys,e.getAsString() +expect\ 'true',\ 'false'\ or\ an\ other\ Condition,\ current\ Conditions\ include\:\ %s,\ but\ got\ %s = 应为“ true ”、“ false ”或其他条件,当前条件包括:{0},但得到了{1} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:271 +# at: src/main/java/org/zstack/cloudformation/template/function/SelectTemplateFunction.java:83 # args: -either\ uuid\ or\ account\ or\ password\ must\ be\ set = uuid或者账户或者密码需要被设置 +Fn\:\:Select\ out\ of\ range,\ please\ check\ your\ json\ file! = FN::选择超出范围,请检查您的JSON文件! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:279 -# args: msg.getDirection() -direction\ must\ be\ set\ in\ (in,\ out),\ but\ was\ %s = 方向必须设置在(in, out),但是输入的是{0} +# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:75 +# args: e.getKey() +only\ functions\ can\ in\ Function,\ but\ found\ %s = 只能在函数中使用函数,但找到了{0} -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:285 +# at: src/main/java/org/zstack/cloudformation/template/function/TemplateFunctionUtils.java:90 # args: -Monitor\ number\ must\ be\ 1\ or\ 2\ or\ 4. = 监听器数量必须是1、2或4 +element\ is\ null! = 元素为空! -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:293 +# at: src/main/java/org/zstack/compute/VmNicUtils.java:26 # args: -outboundBandwidth\ and\ inboundBandwidth\ must\ be\ set\ at\ lease\ one. = 上行带宽和下行带宽至少有一个需要被设置 +duplicate\ nic\ params = 复制NIC参数 -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:302 +# at: src/main/java/org/zstack/compute/VmNicUtils.java:32 # args: -the\ nic\ can't\ apply\ Qos\ with\ the\ port\ mirror\ service\ at\ same\ time. = +l3NetworkUuid\ of\ vm\ nic\ can\ not\ be\ null = 云主机NIC的L3Networkuuid不能为空 -# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:311 -# args: msg.getUuid() -nic\ id\:\ %s\ does\ not\ exist... = 网卡id: {0}不存在 - -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:86 -# args: msg.getAllocatorStrategy() -unsupported\ host\ allocation\ strategy[%s] = 不被支持的主机分配策略[{0}] +# at: src/main/java/org/zstack/compute/VmNicUtils.java:35 +# args: l3Uuids +l3NetworkUuid\ of\ vm\ nic\ is\ not\ in\ l3[%s] = 云主机NIC的l3NetworkUuid不在L3[{0}]中 -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:72 -# args: msg.getType() -unsupported\ instance\ offering\ type[%s] = 不被支持的计算规格类型[{0}] +# at: src/main/java/org/zstack/compute/VmNicUtils.java:40 +# args: nic.getOutboundBandwidth() +outbound\ bandwidth[%d]\ of\ vm\ nic\ is\ out\ of\ [8192,\ 32212254720] = VM NIC的出站带宽[{0}]超出[8192,32212254720] -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:76 -# args: msg.getCpuNum() -cpu\ num[%s]\ is\ less\ than\ 1 = cpu数量[{0}]少于1 +# at: src/main/java/org/zstack/compute/VmNicUtils.java:46 +# args: nic.getInboundBandwidth() +inbound\ bandwidth[%d]\ of\ vm\ nic\ is\ out\ of\ [8192,\ 32212254720] = VM NIC的入站带宽[{0}]超出[8192,32212254720] -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:80 -# args: msg.getMemorySize() -memory\ size[%s\ bytes]\ is\ less\ than\ 16M,\ no\ modern\ operating\ system\ is\ likely\ able\ to\ boot\ with\ such\ small\ memory\ size = 内存大小[{0} bytes]少于16M,没有一个现代操作系统能够在如此小的内存里被引导 +# at: src/main/java/org/zstack/compute/VmNicUtils.java:52 +# args: nic.getMultiQueueNum() +multi\ queue\ num[%d]\ of\ vm\ nic\ is\ out\ of\ [1,256] = VM NIC的多队列数[{0}]超出[1,256] -# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:92 -# args: msg.getAllocationStrategy() -unsupported\ primary\ storage\ allocation\ strategy[%s] = 不被支持的主存储分配策略[{0}] +# at: src/main/java/org/zstack/compute/VmNicUtils.java:58 +# args: nic.getL3NetworkUuid(),nic.getState(),VmNicState.enable.toString(),VmNicState.disable.toString() +vm\ nic\ of\ l3[uuid\:%s]\ state[%s]\ is\ not\ %s\ or\ %s\ = L3[uuid:{0}]状态[{1}]的VM NIC不是{2}或{3} -# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:101 -# args: -the\ console\ agent\ is\ not\ connected;\ it's\ mostly\ like\ the\ management\ node\ just\ starts,\ please\ wait\ for\ the\ console\ agent\ connected,\ or\ you\ can\ reconnect\ it\ manually\ if\ disconnected\ for\ a\ long\ time. = 控制台代理失联,很有可能管理节点刚刚启动,请等待控制台代理的连接,如果长时间没有连上可以尝试手动重连控制台代理。 +# at: src/main/java/org/zstack/compute/VmNicUtils.java:64 +# args: driverType +vm\ nic\ driver\ %s\ not\ support\ yet = VM NIC驱动程序{0}尚不支持 -# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:122 -# args: vm.getUuid() -cannot\ find\ host\ IP\ of\ the\ vm[uuid\:%s],\ is\ the\ vm\ running??? = 无法找到vm[uuid:{0}]的主机IP,请确认该vm是否在运行??? +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:420 +# args: resourceUuid,affinityGroupUuid +VM\ [uuid\:\ %s]\ has\ already\ been\ added\ to\ affinityGroup\ [uuid\:\ %s] = VM[uuid:{0}已经被添加到亲和组[uuid:{1}]中。] -# at: src/main/java/org/zstack/console/ConsoleApiInterceptor.java:52 -# args: msg.getVmInstanceUuid(),state -Console\ is\ only\ available\ when\ the\ VM[uuid\:%s]\ is\ Running,\ but\ the\ current\ state\ is\ %s = 仅当VM[uuid:{0}]处于运行状态时控制台可用,但是现在的状态为{1} +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:437 +# args: hostUuid,affinityGroupUuid +There\ are\ other\ VMs\ on\ this\ host\ [uuid\:\ %s]\ belonging\ to\ same\ affinityGroup\ [%s] = 在物理机[uuid:{0}]上的云主机属于同一个亲和组中[{1}] -# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:62 -# args: uri.toString() -establish\ VNC\:\ unexpected\ uri\:\ %s = +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:468 +# args: self.getUuid(),host.getUuid(),vmUuid +affinityGroup\ [uuid\:%s]\ reserve\ host\ [uuid\:%s]\ for\ vm\ [uuid\:\ %s]\ failed = 亲和组[uuid:{0}]为云主机[uuid:{2}]预分配物理机资源[uuid:{1}]失败 -# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:148 -# args: ret.getError() -unable\ to\ check\ console\ proxy\ availability,\ because\ %s = 无法检查控制台代理是否可用,因为{0} +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupBase.java:538 +# args: inv.getResourceUuid(),self.getUuid() +vm\ [uuid\:%s]\ doesn't\ satisfy\ the\ affinityGroup\ [uuid\:%s] = 云主机[uuid:{1}]不满足亲和组[uuid:{2}]的要求 -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:153 +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupFilterFlow.java:139 # args: -Ansible\ private\ key\ not\ found. = +can\ not\ satisfied\ affinity\ group\ conditions = 不能满足亲和组的条件 -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:347 -# args: uuid -invalid\ management\ node\ UUID[%s] = 非法的管理节点UUID[{0}] +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:42 +# args: VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString(),state.toString() +Vm\ can\ change\ its\ affinityGroup\ only\ in\ state\ [%s,%s],\ but\ vm\ is\ in\ state\ [%s] = 只有状态为[{0},{1}]的云主机可以改变亲和组,但是现在云主机的状态为[{2}] -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:468 -# args: -failed\ to\ configure\ consoleProxyOverriddenIp = 设置consoleProxyOverriddenIp失败 +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:52 +# args: msg.getUuid(),agUuid +Vm\ [uuid\:\ %s]\ is\ already\ added\ to\ affinityGroup\ [uuid\:\ %s] = 云主机[uuid:{0}]已经被添加至亲和组[uuid:{1}]中 -# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:491 -# args: -failed\ to\ reconnect\ console\ proxy = 重连控制台代理失败 +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:77 +# args: affinityGroupUuid +AffinityGroup\ [uuid\:\ %s]\ does\ not\ existed = 亲和组[uuid:{0}]不存在 -# at: src/main/java/org/zstack/core/ansible/AnsibleRunner.java:397 +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:81 # args: -User\ name\ or\ password\ or\ port\ number\ may\ be\ problematic = 用户名、密码或者端口可能是错误的 +Can\ not\ operate\ on\ affinity\ group\ created\ by\ system = 不能对系统创建的亲和组进行操作 -# at: src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java:70 -# args: targetIp,callbackIp,callBackPort -cannot\ nmap\ from\ agent\:\ %s\ to\ callback\ address\:\ %s\:%s = +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupInterceptor.java:88 +# args: affinityGroupUuid +Can\ not\ operate\ on\ affinityGroup\ [uuid\:\ %s]\ which\ is\ not\ enabled = 不能对不是enabled状态的亲和组操作 -# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:106 -# args: srcFolder,srcRes.getStdout(),srcRes.getStderr() -cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s].\nstdout\:%s\nstderr\:%s = 无法检查文件夹[{0}]下文件的md5sum.\nstdout:{1}\nstderr:{2} +# at: src/main/java/org/zstack/compute/affinityGroup/AffinityGroupManagerImpl.java:219 +# args: msg.getAffinityGroupUuid() +cannot\ find\ the\ affinity\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = 未找到亲和组[uuid:{0}],它可能已经被删除 -# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:121 -# args: dstFolder,hostname,dstRes.getStdout(),dstRes.getStderr() -cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s]\ on\ the\ host[ip\:%s].\nstdout\:%s\nstderr\:%s = 无法检查主机[ip:{1}]的文件夹[{0}]下文件的md5sum.\nstdout:{2}\nstderr:{3} +# at: src/main/java/org/zstack/compute/allocator/AttachedL2NetworkAllocatorFlow.java:118 +# args: spec.getL3NetworkUuids() +no\ host\ found\ in\ clusters\ that\ has\ attached\ to\ L2Networks\ which\ have\ L3Networks%s = 在连接到具有L3Networks{0}的L2Networks的集群中找不到物理机 -# at: src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java:681 -# args: errMsg -message\ is\ not\ in\ corrected\ JSON\ mediaType,\ %s = 消息是错误的JSON格式,{0} +# at: src/main/java/org/zstack/compute/allocator/AttachedPrimaryStorageAllocatorFlow.java:79 +# args: psuuids +no\ host\ found\ in\ clusters\ that\ have\ attached\ to\ primary\ storage\ %s = 在已连接到主存储{0}的集群中找不到物理机 -# at: src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java:543 -# args: rsp.getStatusCode(),rsp.getBody() -HTTP\ ERROR,\ status\ code\:\ %s,\ body\:\ %s = +# at: src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java:41 +# args: vm.getUuid() +cannot\ find\ root\ volume\ of\ vm[uuid\:%s] = 找不到VM[uuid:{0}]的根卷 -# at: src/main/java/org/zstack/core/cloudbus/EventFacadeImpl.java:68 -# args: EventFacade.WEBHOOK_TYPE -for\ webhooks\ with\ type[%s],\ the\ field\ opaque\ cannot\ be\ null = 对于[{0}]类型的webhooks,opaque字段不能为null +# at: src/main/java/org/zstack/compute/allocator/AttachedVolumePrimaryStorageAllocatorFlow.java:84 +# args: requiredPsUuids,vm.getUuid() +no\ host\ found\ in\ clusters\ which\ have\ attached\ to\ all\ primary\ storage\ %s\ where\ vm[uuid\:%s]'s\ volumes\ locate = 在已连接到VM[uuid:{1}]的卷所在的所有主存储{0}的集群中找不到物理机 -# at: src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java:90 -# args: msg.getCategory(),msg.getName() -Unable\ to\ find\ GlobalConfig[category\:\ %s,\ name\:\ %s] = 无法找到全局变量[category:{0}, name:{1}] +# at: src/main/java/org/zstack/compute/allocator/AvoidHostAllocatorFlow.java:30 +# args: spec.getAvoidHostUuids() +after\ rule\ out\ avoided\ host%s,\ there\ is\ no\ host\ left\ in\ candidates = 在排除避免的物理机{0}后,候选物理机中没有剩余的物理机 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:77 -# args: -non\ file\ or\ jsoncontent\ input = +# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:87 +# args: spec.getRequiredBackupStorageUuid(),bsType +the\ backup\ storage[uuid\:%s,\ type\:%s]\ requires\ bound\ primary\ storage,\ however,\ the\ primary\ storage\ has\ not\ been\ added = 无法找到跟镜像服务器[uuid:{0}, type:{1}]配对的主存储。一些镜像服务器必须跟配对的主存储共同使用,例如Ceph镜像服务器监控节点只能搭配分布式存储使用。请检查你主存储的设置 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:82 -# args: -file\ or\ jsoncontent\ cannot\ both\ nonempty = +# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:80 +# args: spec.getImage().getUuid(),spec.getRequiredBackupStorageUuid(),type,psUuids +The\ image[uuid\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[uuids\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = 镜像[uuid:{0}]所在的镜像服务器[uuid:{1}, type:{2}]必须跟主存储[uuid:{3}]配对使用,但无法找到可以跟满足条件并可以访问该主存储的物理机 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:114 -# args: e.getMessage() -Unable\ to\ scan\ folder\:\ %s = +# at: src/main/java/org/zstack/compute/allocator/BackupStorageSelectPrimaryStorageAllocatorFlow.java:71 +# args: spec.getImage().getUuid(),name,spec.getRequiredBackupStorageUuid(),spec.getImage().getType(),possiblePrimaryStorageTypes +The\ image[uuid\:%s,\ name\:%s]\ is\ on\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ that\ requires\ to\ work\ with\ primary\ storage[types\:%s],however,\ no\ host\ found\ suitable\ to\ work\ with\ those\ primary\ storage = 镜像[uuid:{0},name:{1}]所在的镜像服务器[uuid:{2}, type:{3}]必须跟主存储[uuid:{4}]一起使用,但无法找到可以跟满足条件并可以访问该主存储的物理机 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:118 -# args: filename -%s\ is\ not\ existed\ or\ is\ empty\ folder = +# at: src/main/java/org/zstack/compute/allocator/DesignatedHostAllocatorFlow.java:107 +# args: args +No\ host\ with\ %s\ found = 找不到具有{0}的物理机 + +# at: src/main/java/org/zstack/compute/allocator/FilterFlow.java:39 +# args: filter.getClass().getSimpleName(),filter.filterErrorReason() +after\ filtering,\ HostAllocatorFilterExtensionPoint[%s]\ returns\ zero\ candidate\ host,\ it\ means\:\ %s = 过滤后,HostAllocatorFilterExtensionPoint[{0}]返回零候选物理机,表示:{1} -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:255 +# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:56 # args: -elaboration\ code\ must\ be\ number! = +either\ volumeUuid\ or\ volumeSnapshotUuid\ must\ be\ set = 云盘uuid或者快照uuid必须被设置 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:328 +# at: src/main/java/org/zstack/compute/allocator/HostAllocatorApiInterceptor.java:75 # args: -arg\ 'startTime'\ should\ format\ like\ 'yyyy-MM-dd\ HH\:mm\:ss'\ or\ '1545380003000' = +zoneUuids,\ clusterUuids,\ hostUuids\ must\ at\ least\ have\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = 区域uuid,集群uuid,物理机uuid必须有一个不为空,或者全部都填写 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:325 -# args: from -%s\ is\ not\ a\ Long\ value\ Number = +# at: src/main/java/org/zstack/compute/allocator/HostCapacityAllocatorFlow.java:69 +# args: spec.getCpuCapacity(),spec.getMemoryCapacity() +no\ host\ having\ cpu[%s],\ memory[%s\ bytes]\ found = 未找到CPU为[{0}]、内存为[{1}字节]的物理机 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:368 -# args: returnValue.get(0).getContent(),returnValue.get(0).getReason() -%s\:\ %s = +# at: src/main/java/org/zstack/compute/allocator/HostOsVersionAllocatorFlow.java:52 +# args: currentHostOs +no\ candidate\ host\ has\ version[%s] = 没有版本为[{0}]的候选物理机 -# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:476 -# args: -input\ args\ 'regex'\ or\ 'category'\ must\ be\ set = +# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:248 +# args: PrimaryStorageState.Enabled,PrimaryStorageState.Disabled,PrimaryStorageStatus.Connected +cannot\ find\ available\ primary\ storage[state\:\ %s\ or\ %s,\ status\:\ %s].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = 找不到可用的主存储[状态:{0}或{1},状态:{2}]。检查主存储的状态,并确保它们已连接到集群 -# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:17 -# args: service.getName() -service[%s]\ has\ been\ registered = 服务(service)[{0}]已经被注册 +# at: src/main/java/org/zstack/compute/allocator/HostPrimaryStorageAllocatorFlow.java:244 +# args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,spec.getDiskSize() +cannot\ find\ available\ primary\ storage[state\:\ %s,\ status\:\ %s,\ available\ capacity\ %s\ bytes].\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = 找不到可用的主存储[状态:{0},状态:{1},可用容量为{2}字节]。检查主存储的状态,并确保它们已连接到集群 -# at: src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java:244 -# args: vo.getUuid(),vo.getName() -cannot\ trigger\ a\ finished\ GC\ job[uuid\:%s,\ name\:%s] = 无法触发一个完成过的GC任务 - -# at: src/main/java/org/zstack/core/progress/ProgressApiInterceptor.java:38 -# args: msg.getApiId() -parameter\ apiId[%s]\ is\ not\ a\ valid\ uuid. = 参数apiId[{0}]不是一个有效的UUID +# at: src/main/java/org/zstack/compute/allocator/HostSortorChain.java:130 +# args: e.getMessage(),host.getUuid(),e.getMessage() +[Host\ Allocation]\:\ %s\ on\ host[uuid\:%s].\ try\ next\ one.\ %s = [物理机分配]:物理机[uuid:{1}]上的{0}。请尝试下一个。{2} -# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:526 -# args: method.toString().toLowerCase(),url,rsp.getStatusCode(),rsp.getBody() -failed\ to\ %s\ to\ %s,\ status\ code\:\ %s,\ response\ body\:\ %s = 访问{1}时执行{0}方法失败,状态码: {2},响应体: {3} +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:97 +# args: spec.getHypervisorType() +no\ host\ having\ state\=Enabled\ status\=Connected\ hypervisorType\=%s\ found = 未找到状态为“已启用”、状态为“已连接”、管理程序类型为“{0}”的物理机 -# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:513 -# args: method.toString().toLowerCase(),url,e.getMessage() -failed\ to\ %s\ to\ %s,\ IO\ Error\:\ %s = 访问{1}时执行{0}方法失败,IO错误: {2} +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:99 +# args: +no\ host\ having\ state\=Enabled\ status\=Connected\ found = 未找到状态=已启用、状态=已连接的物理机 -# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:569 -# args: url,finalTimeout -unable\ to\ echo\ %s\ in\ %sms = 无法在{1}ms内返回{0} +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:94 +# args: candidates.size(),spec.getHypervisorType() +no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts\ having\ the\ hypervisor\ type\ [%s] = 在具有云主机监控程序类型[{1}]的[{0}]候选物理机中未找到已启用的物理机 -# at: src/main/java/org/zstack/core/retry/Retry.java:102 -# args: __name__,times,interval -an\ operation[%s]\ fails\ after\ retrying\ %s\ times\ with\ the\ interval\ %s\ seconds = 在重试{1}次间隔时间为{2}后操作[{0}]失败 +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:92 +# args: candidates.size() +no\ Enabled\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = 在[{0}]个候选物理机中找不到已启用的物理机 -# at: src/main/java/org/zstack/core/salt/SaltRunner.java:296 -# args: stateName,targetIp,retry -failed\ to\ run\ salt\ state[%s]\ on\ system[%s],\ failed\ after\ %s\ retries = 重试{2}次之后,在系统[{1}]上运行加盐状态[{0}]失败 +# at: src/main/java/org/zstack/compute/allocator/HostStateAndHypervisorAllocatorFlow.java:90 +# args: candidates.size() +no\ Connected\ hosts\ found\ in\ the\ [%s]\ candidate\ hosts = 在[{0}]个候选物理机中找不到已连接的物理机 -# at: src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java:84 -# args: targetIp -scp\ is\ not\ found\ on\ system[%s],\ unable\ to\ setup\ salt = +# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:110 +# args: spec.getImage().getUuid(),spec.getImage().getName() +the\ image[uuid\:%s,\ name\:%s]\ is\ deleted\ on\ all\ backup\ storage = 镜像[uuid:{0}, name:{1}]已经从所有镜像服务器上删除,无法执行相应操作 -# at: src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java:81 -# args: ApiTimeoutGlobalProperty.MINIMAL_TIMEOUT -api\ timeout\ cannot\ be\ set\ smaller\ than\ %s = +# at: src/main/java/org/zstack/compute/allocator/ImageBackupStorageAllocatorFlow.java:144 +# args: zoneUuids,spec.getImage().getUuid() +no\ host\ found\ in\ zones[uuids\:%s]\ that\ attaches\ to\ backup\ storage\ where\ image[%s]\ is\ on = 在区域[uuid:{0}]中找不到连接到镜像[{1}]所在的备份存储的物理机 -# at: src/main/java/org/zstack/core/webhook/WebhookApiInterceptor.java:28 -# args: url -Invalid\ url[%s] = 无效的URL[{0}] +# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:114 +# args: entry.getKey() +resource\ binding\ not\ support\ type\ %s\ yet = 资源绑定尚不支持类型{0} -# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:99 -# args: -parameters\ [accountUuid]\ only\ can\ be\ used\ by\ admin\ user! = 参数[accountUuid]必须被admin用户设置 +# at: src/main/java/org/zstack/compute/allocator/ResourceBindingAllocatorFlow.java:133 +# args: resources +no\ available\ host\ found\ with\ binded\ resource\ %s = 未找到具有绑定资源{0}的可用物理机 -# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:54 -# args: msg.getExpirePolicy() -expire\ policy\:\ %s\ is\ not\ valid = 无效的过期策略:{0} +# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:68 +# args: extp.getClass().getName() +InstanceOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = InstanceOfferingTagAllocatorExtensionPoint[{0}]返回零个候选物理机 -# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:57 -# args: msg.getVlan() -vlanId[%s]\ has\ been\ existed! = +# at: src/main/java/org/zstack/compute/allocator/TagAllocatorFlow.java:104 +# args: extp.getClass().getName() +DiskOfferingTagAllocatorExtensionPoint[%s]\ return\ zero\ candidate\ host = DiskOfferingTagAllocatorExtensionPoint[{0}]返回零候选物理机 -# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:129 +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:108 # args: -create\ daho\ vll\ task\ failed! = 创建daho vll任务失败 +cannot\ bind\ with\ interface\ configured\ with\ vtep\ ip = 无法与配置了VTEP IP的接口绑定 -# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:170 -# args: msg.getAccountUuid() -no\ aliyun\ account\ found\ for\ accountUuid\:\ %s = 找不到当前账户{0}对应的阿里云账户 +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:64 +# args: bondingName,HostNetworkBondingConstant.BONDING_NAME_MAX +invalid\ bonding\ name[%s],\ it\ must\ be\ shorter\ than\ [%s]\ characters = 绑定名称[{0}]无效,它必须少于[{1}]个字符 -# at: src/main/java/org/zstack/drs/DRSBase.java:201 -# args: -Advice\ not\ allowed\ while\ scheduling = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:68 +# args: bondingName +invalid\ bonding\ name[%s],\ it\ must\ only\ contains\ letters,\ numbers\ and\ underscores = 绑定名称[{0}]无效,它只能包含字母、数字和下划线 -# at: src/main/java/org/zstack/drs/DRSBase.java:264 -# args: -delete\ DRS\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:77 +# args: bondingName,hostUuid +bonding\ card\ can\ not\ have\ occupied\ bondingName\:[%s],\ which\ was\ already\ been\ used\ by\ host[%s]. = 绑定卡不能占用BondingName:[{0}],它已被物理机[{1}]使用。 -# at: src/main/java/org/zstack/drs/DRSBase.java:324 +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:103 # args: -Scheduling\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = +cannot\ bind\ with\ interface\ corresponding\ to\ the\ management\ network = 无法与管理网络对应的接口绑定 -# at: src/main/java/org/zstack/drs/DRSBase.java:435 -# args: -Lack\ of\ host\ CPU,\ memory\ monitoring\ data = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:115 +# args: hostUuid +bonding\ card\ can\ not\ have\ interfaces\ which\ is\ not\ on\ the\ same\ host[%s]. = 绑定卡不能具有不在同一物理机[{0}]上的接口。 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:55 -# args: msg.getClusterUuid() -The\ cluster[%s]\ has\ created\ DRS = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:120 +# args: hostUuid +bonding\ card\ can\ not\ have\ occupied\ interfaces,\ which\ was\ already\ been\ used\ by\ host[%s]. = 绑定卡不能占用接口,该接口已被物理机[{0}]使用。 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:59 -# args: -DRS\ is\ disabled = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:125 +# args: hostUuid +bonding\ card\ can\ not\ have\ interfaces\ that\ has\ been\ used\ as\ a\ network\ bridge,\ which\ was\ already\ been\ used\ by\ host[%s]. = 绑定卡不能具有已用作网桥的接口,该接口已被物理机[{0}]使用。 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:64 -# args: -thresholds\ can\ not\ be\ empty = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:152 +# args: interfaceVO.getUuid() +bonding\ card\ can\ not\ have\ interface[%s]\ which\ have\ been\ sriov\ virtualized. = 绑定卡不能具有已被SRIOV虚拟化的接口[{0}]。 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:73 -# args: threshold.getThresholdName() -illegal\ thresholdName[%s] = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:161 +# args: hostUuid +bonding\ card\ can\ not\ have\ interfaces\ with\ different\ speed,\ which\ is\ on\ the\ host[%s]. = 绑定卡不能有不同速度的接口,在物理机[{0}]上。 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:77 -# args: threshold.getOperator() -illegal\ threshold\ operator[%s] = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:168 +# args: mode,xmitHashPolicy +[%s]\ bonding\ card\ can\ not\ designate\ [%s],\ Only\ mode\ 802.3ad\ support\ specifying\ different\ xmit_hash_policys = [{0}]绑定卡无法指定[{1}],只有模式802.3ad支持指定不同的xmit_哈希_策略 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:81 -# args: -thresholdValue\ can\ not\ be\ empty = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:181 +# args: mode,size +[%s]\ bonding\ can\ not\ have\ [%s]\ interfaces,\ it\ must\ be\ the\ number\ between[1~2]. = [{0}]绑定不能有[{1}]个接口,其数量必须在[1~2]之间。 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:86 +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:177 +# args: mode,size +[%s]\ bonding\ card\ can\ not\ have\ [%s]\ interfaces,\ it\ must\ be\ the\ number\ between[1~8]. = [{0}]个绑定卡不能有[{1}]个接口,必须在[1~8]之间。 + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:214 +# args: msg.getType() +invalid\ bonding\ type[%s] = 绑定类型[{0}]无效 + +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:242 # args: -illegal\ thresholdValue,\ valid\ range\:\ (0,\ 100] = +cannot\ delete\ bonding\ corresponding\ to\ the\ management\ network = 无法删除与管理网络对应的绑定 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:103 +# at: src/main/java/org/zstack/compute/bonding/HostNetworkBondingApiInterceptor.java:247 # args: -GlobalConfig\ ENABLE_DRS\ is\ closed = +cannot\ delete\ bonding\ configured\ with\ vtep\ ip = 无法删除使用VTEP IP配置的绑定 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:107 -# args: msg.getUuid(),vo.getState().toString() -The\ DRS[%s]\ state\ is\ %s = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java:58 +# args: bondingInv.getHostUuid(),reply.getError() +failed\ to\ add\ linux\ bonding\ to\ host[uuid\:%s]\ \:\ %s = 无法将Linux绑定添加到物理机[uuid:{0}]:{1} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:122 -# args: adviceVO.getDrsUuid() -The\ DRS[%s]\ automation\ level\ is\ not\ manual = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java:97 +# args: bondingInv.getHostUuid(),reply.getError() +failed\ to\ update\ linux\ bonding\ on\ host[uuid\:%s]\ \:\ %s = 无法更新物理机[uuid:{0}]上的Linux绑定:{1} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:136 -# args: msg.getAdviceUuid() -advice[%s]\ has\ expired = +# at: src/main/java/org/zstack/compute/bonding/HostNetworkLinuxBondingFactory.java:132 +# args: bondingInv.getHostUuid(),reply.getError() +failed\ to\ remove\ linux\ bonding\ from\ host[uuid\:%s]\ \:\ %s = 无法从物理机[uuid:{0}]中删除Linux绑定:{1} -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:145 +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:55 # args: -Successfully\ executed,\ no\ repeated\ executions\ allowed = +if\ cluster\ type\ is\ baremetal,\ then\ hypervisorType\ must\ be\ baremetal\ too,\ or\ vice\ versa = 如果集群类型为裸机,则hypervisorType也必须为裸机,反之亦然 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:152 -# args: adviceVO.getVmUuid() -The\ vm[%s]\ has\ been\ deleted = +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:71 +# args: +only\ kvm\ hosts'\ operating\ system\ can\ be\ updated,\ for\ now = 目前只支持升级KVM物理机操作系统 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:155 -# args: adviceVO.getVmUuid() -The\ vm[%s]\ state\ is\ not\ running = +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:82 +# args: msg.getUuid() +there\ are\ hosts\ in\ cluster[uuid\:%s]\ in\ the\ PreMaintenance\ state,\ cannot\ update\ cluster\ os\ right\ now = 集群[uuid:{0}] 中存在处于预维护模式的物理机,无法执行操作系统升级操作 -# at: src/main/java/org/zstack/drs/DRSInterceptor.java:158 -# args: adviceVO.getVmUuid(),adviceVO.getVmSourceHostUuid() -The\ vm[%s]\ is\ no\ longer\ on\ the\ source\ host[%s] = +# at: src/main/java/org/zstack/compute/cluster/ClusterApiInterceptor.java:94 +# args: msg.getUuid() +not\ all\ hosts\ in\ cluster[uuid\:%s]\ are\ in\ the\ Connected\ status,\ cannot\ update\ cluster\ os\ right\ now = 集群[uuid:{0}] 中存在未处于已连接状态的物理机,无法执行操作系统升级操作 -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:242 -# args: msg.getClusterUuid() -The\ cluster[%s]\ does\ not\ support\ DRS. = +# at: src/main/java/org/zstack/compute/cpuPinning/CpuPinningBasicFactory.java:45 +# args: r +invalid\ cpu\ pinning\ ref[%s].\ correct\ example\ is\ [1,3\:3-6,^5] = CPU固定引用[{0}]无效。正确的例子是[1,3:3-6,^5] -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:258 -# args: reasons -Can\ not\ create\ DRS,\ %s = +# at: src/main/java/org/zstack/compute/cpuPinning/CpuRangeSet.java:58 +# args: word +Invalid\ cpuset\ [%s] = 无效的CPUSet[{0}] -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:290 +# at: src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningBasicFactory.java:53 +# args: pCpuNum +the\ host\ vm\ located\ only\ have\ %\ CPUs = 所定位的物理机云主机只有%的CPU + +# at: src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningBasicFactory.java:46 # args: -hostUuids\ is\ empty = +incorrect\ input\ format,\ only\ accept\ '^[0-9,]+$' = 输入格式不正确,只接受'^[0-9,]+$' -# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:297 +# at: src/main/java/org/zstack/compute/emulatorpinning/EmulatorPinningFilterFlow.java:37 # args: -query\ hosts\ utilization\ data\ failed = +vcpu\ pinning\ pcpu\ id\ >\ host\ cores = vcpu要绑定的pcpu id大于了物理机实际核数 -# at: src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java:54 +# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:81 # args: -crond\ is\ not\ running = crond任务未在运行 +webssh\ server\ is\ not\ running. = WebSSH服务器未运行。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:55 -# args: msg.getvRouterUuid() -All\ the\ networks\ should\ be\ in\ the\ virtual\ router[%s] = +# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:105 +# args: msg.getManagementIp() +managementIp[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 管理IP[{0}]既不是有效的IPv4地址也不是有效的物理机名 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:63 -# args: vo.getL3NetworkUuid(),vo.getFlowMeterUuid() -The\ network[%s]\ have\ been\ added\ into\ the\ flow\ meter[%s] = +# at: src/main/java/org/zstack/compute/host/HostApiInterceptor.java:115 +# args: msg.getHostUuid(),hostStatus +can\ not\ maintain\ host[uuid\:%s,\ status\:%s]which\ is\ not\ Connected = 只能对已连接状态的物理机[uuid:{0}, status:{1}]进行维护操作 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:71 +# at: src/main/java/org/zstack/compute/host/HostBase.java:272 +# args: msg.getHostUuid() +host[%s]\ does\ not\ have\ ipmi\ device\ or\ ipmi\ does\ not\ have\ address.After\ config\ ipmi\ address,\ please\ reconnect\ host\ to\ refresh\ host\ ipmi\ information = 物理机[{0}]没有IPMI设备或IPMI没有地址。配置IPMI地址后,请重新连接物理机以刷新物理机IPMI信息 + +# at: src/main/java/org/zstack/compute/host/HostBase.java:435 +# args: vmFailedToMigrate.keySet(),self.getUuid(),self.getName(),self.getManagementIp() +failed\ to\ migrate\ vm[uuids\:%s]\ on\ host[uuid\:%s,\ name\:%s,\ ip\:%s],\ will\ try\ stopping\ it. = 无法迁移物理机[uuid:{1},名称:{2},IP:{3}]上的VM[uuid:{0}],将尝试停止它。 + +# at: src/main/java/org/zstack/compute/host/HostBase.java:841 # args: -The\ virtual\ router\ have\ been\ added\ into\ other\ flow\ meter = +host\ is\ connecting,\ ping\ failed = 物理机正在连接, 不能进行ping操作 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:77 -# args: msg.getVersion(),FlowMeterConstants.TYPE.NetFlow.toString() -invalid\ type\ parameter\ is\ %s\ and\ should\ be\ in\ %s = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:63 +# args: host.getUuid() +mock\ power\ off\ host[%s]\ by\ ipmi\ failed. = 通过IPMI模拟物理机[{0}]断电失败。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:154 -# args: msg.getServer() -[%s]\ is\ not\ formatted\ as\ IP\ address = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:79 +# args: host.getUuid() +power\ off\ host[%s]\ by\ ipmi\ failed. = 通过IPMI关闭物理机[{0}]失败。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:143 -# args: collector.getUuid() -Collector\ duplicate\ with\ %s = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:121 +# args: host.getUuid() +mock\ power\ on\ host[%s]\ by\ ipmi\ failed. = 通过IPMI模拟物理机[{0}]上的电源失败。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:164 -# args: collectorVO.getFlowMeterUuid() -FlowMeter[%s]\ doesn't\ exist = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:131 +# args: host.getUuid() +power\ on\ host[%s]\ by\ ipmi\ failed. = 通过IPMI打开物理机[{0}]电源失败。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:168 -# args: collectorVO.getFlowMeterUuid(),vo.getVersion().toString() -FlowMeter[%s]\ IPv6\ doesn't\ support\ version[%s] = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:161 +# args: host.getUuid() +mock\ power\ reset\ host[%s]\ by\ ipmi\ failed. = 通过IPMI模拟电源重置物理机[{0}]失败。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:150 -# args: -no\ specify\ parameter = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:171 +# args: host.getUuid() +power\ reset\ host[%s]\ by\ ipmi\ failed. = 通过IPMI对物理机[{0}]进行电源重置失败。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:159 -# args: msg.getUuid() -Flow\ collector[%s]\ doesn't\ exist = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:192 +# args: +ipmi\ information\ is\ not\ complete. = IPMI信息不完整。 -# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:183 -# args: server,port,collector.getUuid() -Collector\ [%s\ %d]\ duplicate\ with\ %s = +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:205 +# args: ipmi.getUuid(),rst.getStderr() +host[%s]\ can\ not\ connect\ ipmi[%s],\ because\:%s = 物理机[{0}]无法连接IPMI[{1}],因为:{2} -# at: src/main/java/org/zstack/flowMeter/FlowMeterManagerImpl.java:148 -# args: FlowMeterSystemTags.FLOW_EXPIRE_INTERVAL_TOKEN -%s\ must\ be\ a\ number = {0}必须是一个数字 +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:202 +# args: ipmi.getUuid() +host[%s]\ got\ unexpected\ return\ value = 物理机[{0}]获得意外的返回值 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:43 -# args: msg.getUuid() -cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = 无法为云主机[uuid:{0}获取最新可用的增强工具镜像,因为其虚拟化层目前不支持增强工具 +# at: src/main/java/org/zstack/compute/host/HostIpmiPowerExecutor.java:222 +# args: ipmi.getIpmiAddress(),rst.getStderr() +host\ ipmi[%s]\ is\ not\ reachable.because\ %s = 无法访问物理机IPMI[{0}]。原因是{1} -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:50 -# args: msg.getUuid() -cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ running = 无法为云主机[uuid:{0}]获取最新可用的增强工具镜像,因为它目前并未处于运行状态 +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:264 +# args: msg.getManagementIp() +there\ has\ been\ a\ host\ having\ managementIp[%s] = 已经存在一个管理IP是[{0}]的物理机 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:57 -# args: msg.getUuid() -cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法为云主机[uuid:{0}]获取最新可用的增强工具镜像,因为它不是用户云主机 +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:270 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ is\ not\ existing = 集群[uuid:{0}]不存在 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:67 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为其虚拟化层目前不支持增强工具 +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:364 +# args: vo.getName(),vo.getManagementIp() +after\ connecting,\ host[name\:%s,\ ip\:%s]\ returns\ a\ null\ architecture = 连接后,物理机[名称:{0},IP:{1}]返回空体系结构 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:74 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ running = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为它目前并未处于运行状态 +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:379 +# args: vo.getClusterUuid(),cluster.getArchitecture(),vo.getName(),vo.getManagementIp(),arch +cluster[uuid\:%s]'s\ architecture\ is\ %s,\ not\ match\ the\ host[name\:%s,\ ip\:%s]\ architecture\ %s = 集群[uuid:{0}]的体系结构为{1},与物理机[名称:{2},IP:{3}]的体系结构{4}不匹配 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:81 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为它不是用户云主机 +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:515 +# args: msg.getCancellationApiId() +no\ running\ api[%s]\ task\ on\ hosts = 物理机上没有正在运行的API[{0}]任务 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:88 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it\ has\ no\ cdrom = 无法为云主机[uuid:{0}挂载增强工具镜像,因为它没有配备光驱 +# at: src/main/java/org/zstack/compute/host/HostManagerImpl.java:733 +# args: d.getPrimaryStorageUuid() +primary\ storage[uuid\:%s]\ becomes\ disconnected,\ the\ host\ has\ no\ connected\ primary\ storage\ attached = 主存储[uuid:{0}]失联,物理机没有关联的主存储 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:98 -# args: msg.getUuid() -cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it\ has\ VirtioSCSI\ data\ volume\ attached = 无法为云主机[uuid:{0}挂载增强工具镜像,因为它挂载了VirtioSCSI云盘 +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:59 +# args: nameips.stream().map( it -> it.get(1, String.class) + "/" + it.get(0, String.class)).collect(Collectors.joining(", ")) +host(s)\ [%s]\ is\ not\ Connected,\ not\ support\ to\ power\ off = 物理机[{0}]未连接,不支持关机 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:109 -# args: msg.getUuid() -cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为其虚拟化层目前不支持增强工具 +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:67 +# args: ipAddress +invalid\ ip\ address\ format[%s] = IP地址格式[{0}]无效 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:116 -# args: msg.getUuid() -cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ running = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为它目前并未处于运行状态 +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:71 +# args: netmask +invalid\ netmask\ format[%s] = 网络掩码格式[{0}]无效 -# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:123 -# args: msg.getUuid() -cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为它不是用户云主机 +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:75 +# args: +invalid\ ip\ set,\ it\ must\ be\ set\ with\ netmask = 设置的IP无效,必须使用网络掩码进行设置 -# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:243 -# args: Platform.getManagementServerId(),msg.getHostUuid() -no\ proper\ guest\ tools\ iso\ found\ in\ management\ node[uuid\:%s]\ for\ host[uuid\:%s] = 无法在管理节点[uuid:{0}]上为物理机[uuid:{1}]寻找到合适的增强工具镜像 +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:91 +# args: +cannot\ set\ ip\ on\ interface\ corresponding\ to\ the\ management\ network = 无法在与管理网络对应的接口上设置IP -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForLinuxOnKvmBackend.java:93 -# args: vm.getUuid() -The\ vmInstance\ [uuid]\ zwatch\ agent\ version\ was\ not\ found = +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:192 +# args: +cannot\ set\ ip\ which\ has\ been\ set\ on\ the\ other\ interfaces = 无法设置已在其他接口上设置的IP -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java:59 -# args: host.getUuid() -failed\ to\ download\ guest\ tools\ iso\ because\ no\ kvm\ host[uuid\:%s]\ found = KVM物理机[uuid:{0}]不存在,无法为其下载增强工具镜像 +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:126 +# args: +cannot\ set\ ip\ on\ bonding\ slaves = 无法在绑定从属服务器上设置IP -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java:127 -# args: vm.getUuid(),rsp.getError() -failed\ to\ attach\ guest\ tools\ iso\ to\ vm[uuid\:%s],\ because\:%s = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为:{1} +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:203 +# args: +cannot\ set\ ip\ on\ bridge\ slaves = 无法在网桥从属服务器上设置IP -# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsForWindowsOnKvmBackend.java:160 -# args: vm.getUuid(),rsp.getError() -failed\ to\ get\ guest\ tools\ info\ from\ vm[uuid\:%s],\ because\:%s = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为:{1} +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:151 +# args: msg.getInterfaceUuid() +invalid\ interface\ uuid = 接口uuid无效 -# at: src/main/java/org/zstack/ha/HaKvmHostSiblingChecker.java:236 -# args: struct.getHostUuid(),struct.getHostIp(),errors -hosts\ failed\ to\ port\ scan\ the\ failure\ host[uuid\:%s,\ ip\:%s],\ errors\ are\ %s = 扫描物理机失败[uuid:{0}, ip:{1}],错误原因是 {2} +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:168 +# args: +cannot\ set\ ip\ on\ bonding\ corresponding\ to\ the\ management\ network = 无法在与管理网络对应的绑定上设置IP -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:88 -# args: checkers.indexOf(checker) + 1,checkers.size(),checker.getClass().getSimpleName(),s.getSuccessTimes() * s.getSuccessInterval() -(%d/%d)\ start\ HaHostChecker\ %s\:\ predict\ time\ is\ [%d]\ seconds = +# at: src/main/java/org/zstack/compute/host/HostMevocoApiInterceptor.java:213 +# args: msg.getBondingUuid() +invalid\ bonding\ uuid = 绑定uuid无效 -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:144 -# args: self.getName(),self.getUuid() -cannot\ find\ the\ host\ of\ the\ vm[name\:%s,\ uuid\:%s],\ hostUuid\ is\ null = 找不到vm[name:{0}, uuid:{1}]的物理机, 因为hostUuid为null +# at: src/main/java/org/zstack/compute/host/HostNetworkInterfaceStateAllocatorFlow.java:141 +# args: +no\ available\ network\ interface\ on\ the\ host\ to\ start\ the\ vm = 物理机上没有可用于启动云主机的网络接口 -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:151 +# at: src/main/java/org/zstack/compute/host/HostSecurityLevelAllocatorFilterExtensionPoint.java:68 # args: -no\ HaHostChecker\ found,\ cannot\ do\ HA = 找不到HaHostChecker,无法执行HA +vm\ security\ level\ not\ consistent\ with\ vms\ running\ on\ host = 云主机安全级别与物理机上运行的云主机不一致 -# at: src/main/java/org/zstack/ha/HaKvmWorker.java:158 -# args: self.getUuid() -can\ not\ ha\ because\ device\ still\ attached\ to\ vm[%s] = +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:280 +# args: host.getUuid(),host.getName(),host.getState() +host[uuid\:%s,\ name\:%s]\ is\ in\ state[%s],\ cannot\ perform\ required\ operation = 物理机[uuid:{0}, name:{1}]处于状态[{2}]中,不能处理该请求 -# at: src/main/java/org/zstack/ha/HaManagementNodeChecker.java:99 -# args: -the\ management\ node\ fails\ to\ scan\ the\ host = 管理节点扫描物理机失败 +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:917 +# args: ret.getError() +operation\ error,\ because\ %s = 操作错误,因为{0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1363 -# args: vmUuid -the\ VM[uuid\:%s]\ volume\ stored\ location\ primary\ storage\ is\ in\ a\ state\ of\ maintenance = 虚拟机[{0}]云盘所在主存储处于维护状态 +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:370 +# args: l3Uuid,msg.getHostUuid() +failed\ to\ allocate\ pci\ device\ for\ l3[uuid\:%s]\ on\ host[uuid\:%s] = 无法为物理机[uuid:{1}]上的L3[uuid:{0}]分配PCI设备 -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:232 -# args: newValue -the\ value[%s]\ is\ lesser\ than\ 0 = 值[{0}]比0小 +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:622 +# args: msg.getNetworkInterfaceName(),msg.getHostUuid() +networkInterface[name\:%s]\ of\ host[uuid\:%s]\ can\ not\ find = 找不到物理机[uuid:{1}]的网络接口[名称:{0}] -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:247 -# args: hostUuids,HostStatus.Connected -host[uuid\:%s]\ is\ not\ %s,\ but\ still\ have\ vm\ on\ it,\ please\ resolve\ hosts'\ problems\ before\ enable\ ha = +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:805 +# args: vmInstanceVO.getUuid(),vmInstanceVO.getState() +only\ support\ do\ live\ snapshot\ on\ vm\ state[%s],\ but\ vm\ is\ on\ [%s]\ state = 仅支持在VM状态[{0}]上执行实时快照,但VM处于[{1}]状态 -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:255 -# args: hostUuids,HostStatus.Connected -host[uuid\:%s]\ is\ not\ %s,\ but\ still\ have\ vm\ on\ it,\ please\ resolve\ hosts'\ problems\ before\ update\ fencer\ strategy = +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:1389 +# args: ret.getError() +sync\ vm\ port\ config\ failed\:\ %s = 同步云主机端口配置失败:{0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:472 -# args: -there\ is\ already\ a\ HA\ GC\ job\ for\ the\ VM,\ wait\ it\ to\ run = VM已经有一个HA GC任务,等待运行 +# at: src/main/java/org/zstack/compute/host/MevocoHostBase.java:1423 +# args: ret.getError() +set\ vm\ hostname\ failed\:\ %s = 设置VM物理机名失败:{0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:480 -# args: HaGlobalConfig.NEVER_STOP_VM_FAILURE_RETRY_DELAY.value(Long.class) -A\ GC\ job\ is\ submitted\ to\ HA\ the\ VM[retry\ delay\:\ %s\ seconds] = 提交GC任务来高可用VM[重试间隔: {0} 秒] +# at: src/main/java/org/zstack/compute/host/MevocoHostBaseFactory.java:84 +# args: huuid,cidr +host[uuid\:%s]\ has\ multi\ ips\ in\ cidr[%s] = 物理机[uuid:{0}]在CIDR[{1}]中具有多个IP -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:998 -# args: -HA\ is\ successfully\ completed = +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:1058 +# args: msg.getHostUuid() +host[uuid\:%s]\ can\ not\ find = 找不到物理机[uuid:{0}] -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1006 -# args: -Failed\ to\ HA\ the\ VM = 高可用VM失败 +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:408 +# args: rsp.getError() +failed\ to\ update\ interface\ ip,\ because\ %s = 无法更新接口IP,因为{0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:908 -# args: -vm\ stopped\ unexpectedly,\ double\ check\ state = +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:510 +# args: rsp.getError() +failed\ to\ update\ bonding\ ip,\ because\ %s = 无法更新绑定IP,因为{0} -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:917 -# args: vmUuid,hostUuid -cannot\ determine\ VM[%s]\ status\ on\ host[%s],\ try\ to\ start\ it = +# at: src/main/java/org/zstack/compute/host/MevocoHostManagerImpl.java:1024 +# args: clusterUuids,hypervisorType +cluster[uuids\:%s,\ hypervisorType\:%s]\ are\ not\ exist! = 集群[uuid:{0},HypervisorType:{1}]不存在! -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1112 -# args: -vm\ state\ is\ stopped,\ try\ to\ start\ it = +# at: src/main/java/org/zstack/compute/ovs/VSwitchOvsManagerImpl.java:72 +# args: newValue +ovs\ cpu\ pinning\ resource\ config\:[%s]\ format\ error. = OVS CPU固定资源配置:[{0}]格式错误。 -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:934 -# args: vmUuid,hostUuid -VM[%s]\ is\ running\ on\ host[%s] = +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:136 +# args: msg.getVmNicUuid() +vm\ nic[uuid\:%s]\ doesn't\ exist = VM NIC[uuid:{0}]不存在 -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:947 -# args: vmUuid,hostUuid -VM[%s]\ is\ paused\ on\ host[%s] = +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:77 +# args: VmVfNicConstant.SRIOVABLE_L2_NETWORK_TYPES +only\ %s\ support\ sriov = 仅{0}支持SRIOV -# at: src/main/java/org/zstack/ha/HaManagerImpl.java:975 -# args: vm.getHypervisorType() -the\ hypervisor[%s]\ does\ not\ support\ VM\ HA = 当前虚拟机监视器(hypervisor)[{0}]不支持VM HA +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:83 +# args: L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK +%s\ don't\ support\ sriov = {0}不支持SRIOV -# at: src/main/java/org/zstack/ha/HostCheckResult.java:49 -# args: ratio,threshold,hostUuid,errors -[HA\ Worker]\:\ the\ success\ ratio[%s]\ below\ the\ threshold[%s],\ the\ host[uuid\:%s]\ is\ judged\ as\ dead,\ errors\ are\ %s.\ Start\ HA\ all\ the\ vms\ on\ this\ host\ before = +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:93 +# args: l3Uuid +L3\ Network\ [uuid\:%s]\ doesn't\ exist = 三层网络[uuid:{0}]不存在 -# at: src/main/java/org/zstack/ha/HostCheckResult.java:46 -# args: ratio,threshold -[HA\ worker]\:\ all\ host\ checkers\ are\ finished\ and\ the\ success\ ratio\ is\ %s\ that\ is\ greater\ than\ the\ threshold[%s];\ no\ HA\ need\ for\ the\ vms\ on\ this\ host\ before.\ Please\ wait\ for\ the\ host\ reconnected = +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:97 +# args: l2Uuid,l3Uuid +related\ l2\ network[uuid\:%s]\ of\ l3\ network[uuid\:%s]\ is\ not\ sriov\ enabled = 三层网络[uuid:{1}]的相关二层网络[uuid:{0}]未启用SRIOV + +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:140 +# args: msg.getVmNicUuid(),msg.getVmNicType() +vm\ nic[uuid\:%s]\ is\ already\ of\ type\ %s,\ no\ need\ to\ change = VM NIC[uuid:{0}]已属于类型{1},无需更改 -# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:89 +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:146 # args: -Failed\ to\ start\ the\ NeverStop\ VM = +change\ vm\ nic\ type\ only\ when\ the\ vm\ is\ stopped = 仅在VM停止时更改VM NIC类型 -# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:80 +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:190 # args: -VM\ is\ started\ successfully = +cant\ not\ change\ vf\ nic\ to\ normal\ type = 无法将VF NIC更改为正常类型 -# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:74 +# at: src/main/java/org/zstack/compute/sriov/VmVfNicApiInterceptor.java:197 # args: -VM\ state\ is\ not\ running,\ try\ to\ start\ it = +cant\ not\ change\ nic\ to\ vf\ type = 无法将NIC更改为VF类型 -# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:45 -# args: type -keyType\ not\ supported\ type\ [%s] = +# at: src/main/java/org/zstack/compute/sriov/VmVfNicFilterFlow.java:89 +# args: +no\ candidate\ host\ with\ enough\ vf\ nic\ pci\ devices = 没有具有足够VF NIC PCI设备的候选物理机 -# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:85 -# args: msg.getKey(),accountUuid -key\:\ [%s]\ already\ existed\ by\ accountUuid\:\ [%s] = key: [{0}]已经存在于accountUuid: [{1}] +# at: src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java:275 +# args: vmType +enableSRIOV\ tag\ is\ not\ supported\ for\ vm\ type\ [%s] = 云主机类型[{0}]不支持EnableSriov标记 -# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:63 -# args: msg.getRegionId(),ak -regionId\ [%s]\ already\ created\ by\ ak\ [%s] = 区域ID[{0}]已经被AccessKey[{1}]创建 +# at: src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java:476 +# args: vmUuid +vm[uuid\:%s]\ needs\ to\ be\ running\ when\ attach\ vf\ nics,\ but\ no\ hostUuid\ found = 连接VF NIC时需要运行VM[uuid:{0}],但未找到HOSTuuid -# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:46 -# args: type -dcType\ not\ supported\ type\ [%s] = +# at: src/main/java/org/zstack/compute/sriov/VmVfNicManagerImpl.java:499 +# args: hostUuid,l3Uuid +cannot\ find\ available\ vf\ nic\ pci\ device\ on\ host[uuid\:%s]\ for\ l3[uuid\:%s] = 对于L3[uuid:{1}],在物理机[uuid:{0}]上找不到可用的VF NIC PCI设备 -# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterManagerImpl.java:96 -# args: msg.getUuid() -DataCenter\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = 数据中心[{0}]仍在同步进程中,请稍后 +# at: src/main/java/org/zstack/compute/sriov/VmVfNicReserveFlow.java:88 +# args: hostUuid,vmUuid +reserve\ pci\ address\ for\ on\ host[uuid]\ for\ vm\ [uuid\:%s]\ failed, = 在物理机[uuid]上为云主机[uuid:{0}]保留的PCI地址失败, -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:55 -# args: msg.getZoneId(),izo.getUuid() -identity\ zone\ [%s]\ already\ existed,\ uuid\ is\:\ %s = 可用区[{0}]已经存在,uuid是{1} +# at: src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicKvmBackend.java:49 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ delete\ vHost\ User\ Client\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = 无法删除云主机[uuid:{1}]的物理机[uuid:{0}]中的vhost用户客户端:{2} -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:72 -# args: type,dvo.getDcType().toString() -type\ [%s]\ is\ not\ matched\ datacenter\ type\ [%s] = +# at: src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicKvmBackend.java:85 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ generate\ vHost\ User\ Client\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = 无法在物理机[uuid:{0}]中为VM[uuid:{1}]生成vhost用户客户端:{2} -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:82 -# args: -either\ dataCenterUuid\ or\ regionId\ should\ be\ set,\ please\ check\ the\ parameters. = 数据中心Uuid和区域Id应该被设置,请检查参数 +# at: src/main/java/org/zstack/compute/vHostUser/VmVHostUserNicManagerImpl.java:309 +# args: inv.getUuid(),destHostUuid +cannot\ generate\ vhost\ user\ client\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为目标物理机[uuid:{1}]上的云主机[uuid:{0}]生成vhost用户客户端 -# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneManagerImpl.java:111 -# args: msg.getUuid() -IdentityZone\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = 可用区[{0}]仍在同步进程中,请稍后 +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:66 +# args: VmVdpaNicConstant.VDPA_L2_NETWORK_TYPES +only\ %s\ support\ vdpa = 仅{0}支持VDPA -# at: src/main/java/org/zstack/hybrid/network/HybridEipCascadeExtension.java:88 -# args: -EcsInstance\ must\ be\ running\ or\ stopped\ while\ deleting\ eip\ = 删除弹性IP时云主机必须时允许中或者已停止 +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:106 +# args: l2Vo.getvSwitchType(),l2Vo.getPhysicalInterface() +can\ not\ create\ %s\ with\ physical\ interface\:[%s]\ which\ was\ already\ been\ used\ by\ another\ vSwitch\ type. = 无法创建物理接口为[{1}]的{0},该接口已由另一个vSwitch类型使用。 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:86 -# args: vbri.getUuid(),vbri.getDataCenterUuid(),vrouteri.getUuid(),vrouteri.getDataCenterUuid() -router\ interface\ must\ be\ in\ the\ same\ datacenter,\ but\ ri[%s]\ is\ in\ dc[%s]\ and\ ri[%s]\ is\ in\ dc[%s] = 路由接口必须在相同的数据中心,但是接口[{0}]在数据中心[{1}]而接口[{2}]在数据中心[{3}] +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:131 +# args: msg.getClusterUuid() +cluster[uuid\:%s]\ do\ not\ support\ ovs-dpdk = 集群[uuid:{0}]不支持OVS-DPDK -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:96 -# args: vrouteri.getUuid(),vrouteri.getStatus() -router\ interface[%s]\ status\ is\ not\ idle,\ it\ is\ %s = 路由接口[{0}]并非闲置状态,当前状态为{1} +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicApiInterceptor.java:147 +# args: l2NicName,hostUuid,l2NicName +physical\ interface[%s]\ in\ host[uuid\:%s]\ is\ not\ sriov\ virtualized,\ please\ perform\ sriov\ cutting\ operation\ on\ physical\ interface[%s]. = 物理机[uuid:{1}]中的物理接口[{0}]未进行SRIOV虚拟化,请对物理接口[{2}]进行SRIOV裁剪操作。 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:104 -# args: vrouteri.getUuid(),vrouteri.getOppositeInterfaceUuid() -router\ interface[%s]\ already\ has\ a\ connection,\ it\ is\ %s = 路由接口[{0}]已经有链接{1} +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicKvmBackend.java:49 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ delete\ vdpas\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = 无法删除物理机[uuid:{0}]中VM[uuid:{1}]的VDPA:{2} + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicKvmBackend.java:86 +# args: hostUuid,vmUuid,reply.getError() +failed\ to\ generate\ vdpas\ in\ host[uuid\:%s]\ for\ vm[uuid\:%s]\ \:\ %s = 无法在物理机[uuid:{0}]中为VM[uuid:{1}]生成VDPA:{2} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:112 +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:650 +# args: hostUuid,l3Uuid +cannot\ find\ available\ vdpa\ nic\ pci\ device\ on\ host[uuid\:%s]\ for\ l3[uuid\:%s] = 在物理机[uuid:{0}]上找不到可用于L3[uuid:{1}]的VDPA NIC PCI设备 + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:263 +# args: vmUuid +vm[uuid\:%s]\ needs\ to\ be\ running\ when\ attach\ vdpa\ nics,\ but\ no\ hostUuid\ found = 连接VDPA NIC时需要运行VM[uuid:{0}],但未找到HOSTuuid + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:688 +# args: inv.getUuid(),destHostUuid +cannot\ generate\ vdpa\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为目标物理机[uuid:{1}]上的云主机[uuid:{0}]生成VDPA + +# at: src/main/java/org/zstack/compute/vdpa/VmVdpaNicManagerImpl.java:835 # args: -accessPointUuid\ cannot\ be\ null\ if\ the\ router\ interface\ on\ VBR\ type\ router = 当路由接口的类型为VBR路由时,accessPointUuid不能为空 +no\ candidate\ host\ with\ enough\ vdpa\ resource = 没有具有足够VDPA资源的候选物理机 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:186 +# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:63 # args: -cannot\ delete\ system\ entry = 不能删除系统路由条目 +not\ dest\ host\ found\ in\ db,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = 没有在物理机上发现数据库,不能发送更改密码的指令到这个物理机上 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:192 +# at: src/main/java/org/zstack/compute/vm/ChangeVmPasswordFlow.java:64 # args: -only\ support\ intranet\ rule\ in\ vpc = 在VPC中仅仅支持内网规则 +not\ account\ preference\ found,\ \ send\ change\ password\ cmd\ to\ the\ host! = 没有优先级账户去发送改变密码的指令到物理机 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:197 -# args: msg.getCidr() -%s\ is\ not\ a\ valid\ cidr = {0}是一个无效的CIDR +# at: src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java:160 +# args: srcPath,getManagementServerId() +fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ file\ not\ found\ on\ classpath = 无法附加virtio驱动程序,因为在Mn[uuid:{1}]中读取文件[{0}]的MD5失败:在类路径中找不到文件 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:207 -# args: -security\ group\ rule\ already\ existed = 安全组已经存在了 +# at: src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java:172 +# args: srcPath,getManagementServerId(),e.getMessage() +fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ %s = 无法附加virtio驱动程序,因为在Mn[uuid:{1}]中读取文件[{0}]的MD5失败:{2} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:213 -# args: msg.getDstCidrBlock() -dstCidrBlock[%s]\ is\ not\ a\ valid\ cidr = dstCidrBlock[{0}]是一个无效的CIDR +# at: src/main/java/org/zstack/compute/vm/CheckAndSendVirtIODriverFlow.java:167 +# args: srcPath,getManagementServerId() +fail\ to\ attach\ virtio\ driver\ because\ of\ invalid\ md5\ of\ file[%s]\ in\ mn[uuid\:%s] = 无法附加virtio驱动程序,因为Mn[uuid:{1}]中文件[{0}]的MD5无效 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:242 -# args: msg.getNextHopType() -next\ hop\ type\ [%s]\ not\ supported\ create\ route\ entry\ now! = +# at: src/main/java/org/zstack/compute/vm/CheckIfCreateTemporaryTemplateFlow.java:105 +# args: spec.getDataVolumeRequiredHostUuids() +only\ host(s)[uuid(s)\:\ %s]\ can\ access\ data\ volume. = 只有物理机[uuid:{0}]可以访问数据云盘。 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:238 -# args: msg.getNextHopUuid() -no\ such\ vpn\ gateway\:\ %s = 没有这样的VPN网关: {0} +# at: src/main/java/org/zstack/compute/vm/CpuTopology.java:71 +# args: cpuNum,cpuSockets,cpuCores,cpuThreads,socketNum,coreNum,threadNum +cpu\ topology\ is\ not\ correct,\ cpuNum[%s],\ configured\ cpuSockets[%s],\ cpuCores[%s],\ cpuThreads[%s];\ Calculated\ cpuSockets[%s],\ cpuCores[%s],\ cpuThreads[%s] = CPU拓扑结构不正确,cpunum[{0}],已配置的cpusockets[{1}],cpuCore[{2}],cpuThreads[{3}]。计算的CPU套接字[{4}],CPU核心[{5}],CPU线程[{6}] -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:227 -# args: rivo.getvRouterType().toString(),msg.getvRouterType() -nexthop\ routerInterface\ belongs\ to\ %s,\ but\ the\ entry\ belongs\ to\ %s = 下一跳路由接口类型是{0},但是该路由类型是{1} +# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:40 +# args: vmUuid,isoUuid +VM[uuid\:%s]\ has\ attached\ ISO[uuid\:%s] = 云主机[uuid:{0}]已经加载了ISO[uuid:{1}] -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:220 -# args: msg.getNextHopUuid() -no\ such\ ecs\ instance\:\ %s = 没有这样的ESC云主机: {0} +# at: src/main/java/org/zstack/compute/vm/IsoOperator.java:48 +# args: vmUuid +All\ vm[uuid\:%s]\ CD-ROMs\ have\ mounted\ ISO = 所有VM[uuid:{0}]CD-ROM都已装载ISO -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:252 -# args: -virtual\ border\ router\ only\ support\ routerinterface\ as\ next\ hop\ type = 作为下一跳类型,虚拟边界路由只支持路由接口 +# at: src/main/java/org/zstack/compute/vm/KvmUserVmVirtIODriverExtension.java:142 +# args: driverFormat +invalid\ virtio\ driver\ device\ format\:\ %s = 无效的virtio驱动程序设备格式:{0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:272 -# args: msg.getCidrBlock(),vpcCidr -vswitch's\ cidr\ [%s]\ not\ in\ the\ vpc's\ [%s] = 虚拟交换机的CIDR没有在VPC[{1}]中 +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:77 +# args: mac +This\ is\ not\ a\ valid\ MAC\ address\ [%s] = 这是一个无效的MAC地址 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:279 -# args: old.getUuid() -cidr\ is\ overlap\ by\ another\ vswitch\:\ %s = CIDR和其他的虚拟交换机{0}有重叠 +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:87 +# args: mac +Not\ a\ valid\ MAC\ address\ [%s] = 这是一个无效的MAC地址[{0}] -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:292 -# args: msg.getCidrBlock() -invalid\ CidrBlock\:\ %s,\ which\ must\ subnet\ in\ '10.0.0.0/8',\ '172.16.0.0/12',\ '192.168.0.0/16' = 无效的CIDR块: {0},CIDR必须在10.0.0.0/8、172.16.0.0/12和192.168.0.0/16子网内 +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:90 +# args: +Disallowed\ address = 不被允许的MAC地址 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:308 -# args: msg.getvRouterUuid() -no\ such\ virtual\ router\:\ %s = 没有这个的虚拟路由: {0} +# at: src/main/java/org/zstack/compute/vm/MacOperator.java:93 +# args: mac +Expected\ unicast\ mac\ address,\ found\ multicast\ MAC\ address\ [%s] = 期望的是一个单播的MAC地址,但找到的是一个组播的MAC地址[{0}] -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:303 -# args: msg.getvRouterUuid() -no\ such\ virtual\ border\ router\:\ %s = 没有这个虚拟边界路由器: {0} +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:251 +# args: +state\ of\ vm[uuid\:%s]\ is\ not\ in\ Running\ state,\ can\ not\ sync\ clock = VM[uuid:{0}]的状态未处于运行状态,无法同步时钟 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:315 -# args: msg.getLocalGatewayIp() -localGateway\ is\ not\ IPv4\:\ %s = 本地网关地址不是IPV4: {0} +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:442 +# args: +hot\ plug\ is\ not\ turned\ off,can\ not\ open\ vm\ numa = 热插拔未关闭,无法打开VM NUMA -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:318 -# args: msg.getPeerGatewayIp() -peerGateway\ is\ not\ IPv4\:\ %s = 对端网关地址不是IPV4: {0} +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:609 +# args: self.getUuid() +vm[uuid\:\ %s]'s\ state\ is\ not\ Stopped\ now,\ cannot\ operate\ 'changevmimage'\ action = VM[uuid:{0}]的状态现在未停止,无法执行“ ChangeVMImage ”操作 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:321 -# args: msg.getPeeringSubnetMask() -peerGateway\ is\ not\ subnet\ mask\:\ %s = 对端网关地址不是在子网掩码{0}中 +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:662 +# args: self.getUuid() +vm[uuid\:%s]\ cluster\ uuid\ is\ null,\ cannot\ change\ image\ for\ it = VM[uuid:{0}]集群uuid为空,无法更改其镜像 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:325 -# args: msg.getVlanId() -vlanId\ is\ not\ number\:\ %s = vlanId不是一个数字:{0} +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:675 +# args: self.getUuid(),self.getClusterUuid() +vm[uuid\:%s]\ is\ in\ cluster[uuid\:%s],\ but\ there\ is\ no\ available\ host\ in\ the\ cluster,\ cannot\ change\ image\ for\ the\ vm = 云主机[uuid:{0}]位于集群[uuid:{1}]中,但集群中没有可用的物理机,无法更改云主机的镜像 -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:335 -# args: msg.getEcsUuid(),msg.getEipUuid(),hevo.getAllocateResourceUuid() -couldn't\ attach\ eip\ to\ ecs\:\ [%s]\ ,\ eip\ \:[%s]\ already\ attached\ ecs\:[%s]\ = 不能绑定弹性IP到ECS云主机[{0}],弹性IP[{1}]已经绑定到ECS云主机[{2}] +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:967 +# args: vivo.getRootVolumeUuid(),vivo.getRootVolume().getPrimaryStorageUuid(),msg.getPrimaryStorageUuidForRootVolume() +cannot\ find\ backupStorage\ for\ volume[uuid\:\ %s,\ psUuid\:\ %s],\ required\ primary\ storage\ uuid\:%s = 找不到卷[uuid:{0},PSuuid:{1}]的BackupStorage,所需的主存储uuid为{2} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:340 -# args: msg.getEcsUuid() -ecs\ [%s]\ already\ has\ public\ ip\ now = ECS云主机[{0}]已经拥有IP +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:1152 +# args: vol.getPrimaryStorageUuid(),requiredPsUuid +can\ not\ find\ backup\ storage,\ unable\ to\ commit\ volume\ snapshot[psUuid\:%s]\ as\ image,\ destination\ required\ PS\ uuid\:%s = 找不到备份存储,无法将卷快照[PSuuid:{0}]作为镜像提交,目标需要PS uuid:{1} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:346 -# args: msg.getEipUuid(),msg.getEcsUuid() -couldn't\ attach\ eip\ [%s]\ to\ ecs\:\ [%s]\ ,\ ecs\ is\ already\ attached = 不能绑定弹性IP[{0}]到ECS云主机[{1}],ECS云主机已经绑定了弹性IP +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2052 +# args: +direction\ must\ be\ set\ to\ in\ or\ out = 方法必须设置in或者out -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:353 -# args: msg.getEipUuid(),msg.getEcsUuid() -eip[%s]\ and\ ecs[%s]\ should\ be\ in\ the\ same\ dataCenter\ = 弹性IP[{0}]和ECS云主机[{1}]应该在同一个数据中心 +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2132 +# args: struct.inboundBandwidthUpthreshold +inboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = 下行带宽不能超过{0} -# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:362 -# args: msg.getEipUuid() -couldn't\ detach\ eip\ \:[%s],\ it\ is\ not\ attached\ on\ any\ instance\ = 不能解绑弹性IP[{0}],因为它没有绑定任何云主机 +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2142 +# args: struct.outboundBandwidthUpthreshold +outboundBandwidth\ must\ be\ set\ no\ more\ than\ %s. = 上行带宽不能超过{0} -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:45 -# args: msg.getId() -%s\ is\ not\ a\ valid\ ipv4\ address = {0}是一个无效的IPV4地址 +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2199 +# args: self.getUuid() +vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ nic\ qos = VM[{0}]状态必须为“正在运行”或“已暂停”才能同步NIC QoS -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:51 +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2204 # args: -localCidr\ must\ be\ Cidr! = 本地CIDR必须是CIDR +vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ nic\ qos = VM[{0}]的Hostuuid为空,无法同步NIC QoS -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:55 -# args: -remoteCidr\ must\ be\ Cidr! = 远程CIDR必须是CIDR +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2661 +# args: amsg.getVmInstanceUuid() +not\ dest\ host\ found\ in\ db\ by\ uuid\:\ %s,\ can't\ send\ change\ password\ cmd\ to\ the\ host! = 没有在物理机{0}上发现数据库,不能发送更改密码的指令到这个物理机上 -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:62 +# at: src/main/java/org/zstack/compute/vm/MevocoVmInstanceBase.java:2691 # args: -localCidr\ and\ remoteCidr\ must\ be\ Cidr! = 本地CIDR和远程CIDR必须是CIDR +state\ is\ not\ correct\ while\ change\ password. = 该状态不支持修改密码 -# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnGatewayCascadeExtension.java:80 -# args: gateways.get(0).getUuid() -vpngateway\ [%s]\ existed,\ cannot\ delete\ remote = VPN网关[{0}]已经存在,不能删除远程的 +# at: src/main/java/org/zstack/compute/vm/VmAllocateCdRomFlow.java:56 +# args: spec.getVmInventory().getUuid() +vm[uuid\:%s]\ cdRom\ deviceId\ repetition = VM[uuid:{0}]CDROM DeviceID重复 -# at: src/main/java/org/zstack/iam2/IAM2AttributeHelper.java:420 -# args: vid,msg.getProjectUuid() -virtual\ id[uuid\:%s]\ is\ platform\ user\ can\ not\ be\ added\ to\ project[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmAllocateHostAndPrimaryStorageFlow.java:69 +# args: imageUuid,cachedPsUuids +creation\ rely\ on\ image\ cache[uuid\:%s,\ locate\ ps\ uuids\:\ [%s]],\ cannot\ create\ other\ places. = 创建依赖于镜像缓存[uuid:{0},定位PS uuid:[{1}]],无法创建其他位置。 -# at: src/main/java/org/zstack/iam2/IAM2AttributeHelper.java:450 -# args: -Can\ not\ add\ both\ platform\ role\ and\ project\ role\ to\ virtual\ id = +# at: src/main/java/org/zstack/compute/vm/VmAllocateNicIpFlow.java:83 +# args: v.getL3Invs().get(0).getUuid() +there\ is\ no\ available\ ipRange\ on\ L3\ network\ [%s] = 三层网络[{0}]中没有可用的网络段 -# at: src/main/java/org/zstack/iam2/IAM2AttributeHelper.java:458 -# args: virtualIDUuid -Can\ not\ add\ project\ role\ to\ platform\ virtual\ id[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmAllocatePrimaryStorageForAttachingDiskFlow.java:50 +# args: spec.getVmInventory().getUuid() +\ Can\ not\ find\ the\ vm's\ host,\ please\ start\ the\ vm[%s],\ then\ mount\ the\ disk = 未找到云主机的物理机,请重启云主机[{0}],然后挂载云盘 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:319 -# args: msg.getName() -wrong\ virtual\ ID[name\:%s],\ not\ existing\ or\ wrong\ password = 错误的virtual ID[名称:{0}], 密码不存在或者密码错误 +# at: src/main/java/org/zstack/compute/vm/VmDownloadIsoFlow.java:68 +# args: iso.getUuid(),host.getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() +cannot\ find\ the\ iso[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ running\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = 不能发现iso[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \n1. 镜像服务器是否已经挂载到区域中的任何运行状态的云主机[name: {2}, uuid:{3}]上;\n2. 如果镜像服务器不是处于连接状态,请尝试重连 + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:713 +# args: msg.getVmInstanceUuid(),msg.getIsoUuid() +VM[uuid\:%s]\ already\ has\ an\ ISO[uuid\:%s]\ attached = 云主机[uuid:{0}]已经挂载了ISO[uuid:{1}] -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:326 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:169 # args: -additional\ authentication\ failed = 附加认证失败 +either\ l3NetworkUuids\ or\ backupStorageUuid\ must\ be\ set = 必须设置L3Networkuuid或BackupStorageuuid -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:366 -# args: msg.getProjectName() -project[name\:%s]\ not\ existing = 项目[name:{0}]不存在 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:205 +# args: msg.getVmInstanceUuid(),state +unable\ to\ change\ to\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = 无法更改为三层网络。VM[uuid:{0}]未运行或已停止。当前状态为{1} -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:374 -# args: puuid,msg.getProjectName() -no\ account\ found\ for\ project[uuid\:%s,\ name\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:211 +# args: msg.getDestL3NetworkUuid() +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ doesn't\ has\ have\ ip\ range = 无法更改为三层网络。三层网络[uuid:{0}]没有IP范围 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:380 -# args: msg.getSession().getUserUuid() -wrong\ virtual\ ID[uuid\:%s],\ not\ existing\ or\ wrong\ password = 错误的virtual ID[uuid:{0}], 密码不存在或者密码错误 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:221 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ different\ l2\ networks\ [uuids\:%s] = 无法更改为三层网络。三层网络[uuid:{0}]属于不同的二层网络[uuid:{1}] -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:385 -# args: vid.getName() -virtual\ ID[name\:%s]\ is\ disabled = virtual ID[名称:{0}]不可用 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:228 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ l2\ networks\ [uuids\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = 无法更改为三层网络。三层网络[uuid:{0}]属于尚未连接到任何集群的二层网络[uuid:{1}] -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:391 -# args: vid.getName(),msg.getProjectName() -virtual\ ID[name\:%s]\ not\ belonging\ to\ the\ project[name\:%s] = virtual ID[名称:{0}]不属于项目[name:{1}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:240 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 无法更改为三层网络。三层网络[uuid:{0}]已连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:647 -# args: results.size() -There\ are\ %d\ problems\ with\ the\ file.\ = 文件中包含{0}个错误 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:247 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ change\ to\ a\ non-guest\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 无法更改为非来宾三层网络。三层网络[uuid:{0}]已连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:664 -# args: e.getMessage() -fail\ to\ load\ VirtualID\ info\ from\ file.\ because\n%s = 解析文件内容出错,{0} +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:255 +# args: l3Uuid +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ disabled = 无法更改为三层网络。三层网络[uuid:{0}]已禁用 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:675 -# args: -name\ cannot\ be\ empty.\ = 名称不能为空 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:258 +# args: l3Uuid +unable\ to\ change\ to\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = 无法更改为三层网络。三层网络[uuid:{0}]是系统网络,VM是用户VM -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:683 -# args: cmsg.getUsername() -userName[%s]\ is\ repeated.\ = 用户名[{0}]重复 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:942 +# args: staticIp,l3Uuid +the\ static\ IP[%s]\ is\ not\ in\ any\ IP\ range\ of\ the\ L3\ network[uuid\:%s] = 该静态IP[{0}]不在三层网络[uuid:{1}]的任何IP段 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:681 -# args: cmsg.username.length() -name\ exceeds\ max\ length\ of\ string.\ expected\ was\ <\=\ 255,\ actual\ was\ %s.\ = 名称字符数量不能超过255 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:949 +# args: staticIp,l3Uuid +the\ static\ IP[%s]\ has\ been\ occupied\ on\ the\ L3\ network[uuid\:%s] = 该静态IP[{0}]已经存在在三层网络[uuid:{1}]中 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:679 -# args: -username\ cannot\ be\ empty.\ = 用户名不能为空 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:912 +# args: e.getKey(),newAddedL3Uuids +static\ ip\ l3\ uuid[%s]\ is\ not\ included\ in\ nic\ l3\ [%s] = 静态IP的三层网络[uuid:{0}]不在网卡的L3列表[uuid:{1}]中 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:689 -# args: cmsg.password.length() -Incorrect\ password\ length.\ expected\ was\ >\=\ 6\ and\ <\=\ 255,\ actual\ was\ %s.\ = 密码长度错误,应该大于等于6个字符,小于等于255字符 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:373 +# args: image.getName(),image.getUuid() +the\ image[name\:%s,\ uuid\:%s]\ is\ an\ ISO,\ rootDiskSize\ must\ be\ set = 镜像[name:{0}, uuid:{1}]是一个IOS, 必须设置云盘大小 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:687 -# args: -password\ cannot\ be\ empty.\ = 密码不能为空 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:383 +# args: msg.getVmInstanceUuid(),vo.getState().toString() +Can\ not\ create\ CD-ROM\ for\ vm[uuid\:%s]\ which\ is\ in\ state[%s]\ = 无法为处于状态[{1}]的VM[uuid:{0}]创建CD-ROM + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:391 +# args: vo.getPlatform() +Current\ platform\ %s\ not\ support\ update\ nic\ driver\ yet = 当前平台{0}尚不支持更新NIC驱动程序 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:697 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:407 # args: -email\ format\ does\ not\ match.\ = 邮箱格式错误 +rootDiskSize\ is\ needed\ when\ image\ media\ type\ is\ ISO = 当镜像类型是ISO时云盘大小需要设置 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:753 -# args: noMatchNames -organization[%s]\ is\ not\ exist.\ = 部门[{0}]不存在 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:419 +# args: msg.getVmInstanceUuid(),msg.getHostUuid() +the\ vm[uuid\:%s]\ is\ already\ on\ host[uuid\:%s] = 云主机[uuid:{0}]已经运行于物理机[uuid:{1}]上 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:761 -# args: repeatNames -organization[%s]\ in\ line\ is\ repeated.\ = 部门[{0}]出现重复 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:436 +# args: +the\ VM\ cannot\ do\ online\ cpu/memory\ update\ because\ of\ disabling\ Instance\ Offering\ Online\ Modification.\ Please\ stop\ the\ VM\ then\ do\ the\ cpu/memory\ update\ again = 云主机无法执行在线升级CPU/内存,因为未启用计算规格在线修改。请关闭该云主机再尝试 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:769 -# args: repeatNames -organization[%s]\ is\ repeated.\ = 部门[{0}]出现重复 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:495 +# args: vo.getUuid(),vo.getState(),StringUtils.join(list(VmInstanceState.Running, VmInstanceState.Stopped), ",") +The\ state\ of\ vm[uuid\:%s]\ is\ %s.\ Only\ these\ state[%s]\ is\ allowed\ to\ update\ cpu\ or\ memory. = 云主机[uuid:{0}]的状态为{1}。只有这些状态[{2}]允许在线升级CPU/内存 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:799 -# args: noMatchName -project[%s]\ is\ not\ exist.\ = 项目[{0}]不存在 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:452 +# args: vo.getUuid() +can't\ decrease\ capacity\ when\ vm[uuid\:%s]\ is\ running = 无法在云主机[uuid:{0}]运行时减少容量 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:963 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:482 # args: -fail\ to\ build\ VirtualID\ info\ from\ file.\ = 不能解析文件内容 +the\ VM\ cannot\ do\ cpu\ hot\ plug\ because\ of\ disabling\ cpu\ hot\ plug.\ Please\ stop\ the\ VM\ then\ do\ the\ cpu\ hot\ plug\ again = 云主机无法执行在线添加CPU,因为未启用CPU热插拔。请关闭该云主机再尝试 -# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1034 -# args: resourceUuid,projectUuid -virtualID[uuid\:%s]\ not\ in\ project[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:488 +# args: +the\ VM\ cannot\ do\ memory\ hot\ plug\ because\ of\ disabling\ memory\ hot\ plug.\ Please\ stop\ the\ VM\ then\ do\ the\ memory\ hot\ plug\ again = 云主机无法执行在线添加内存,因为未启用内存热插拔。请关闭该云主机再尝试 -# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:86 -# args: self.getUuid() -Can\ not\ do\ operations,\ because\ current\ organization[uuid\:%s]\ is\ staled,\ please\ enable\ it = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:506 +# args: vo.getUuid() +can't\ decrease\ cpu\ of\ vm[uuid\:%s]\ when\ it\ is\ running = 无法在云主机[uuid:{0}]运行时减少CPU数目 -# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:192 -# args: puuid,self.getUuid() -organization[uuid\:%s]\ is\ parent\ of\ the\ organization[uuid\:%s],\ cannot\ set\ it\ as\ a\ child\ organization = 部门[uuid:{0}]是部门[uuid:{1}]的上级部门,无法被设置为子部门 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:512 +# args: vo.getUuid() +can't\ decrease\ memory\ size\ of\ vm[uuid\:%s]\ when\ it\ is\ running = 无法在云主机[uuid:{0}]运行时减少容量 -# at: src/main/java/org/zstack/iam2/IAM2ProjectBase.java:106 -# args: self.getUuid(),self.getName(),self.getState(),msg.getClass() -the\ project[uuid\:\ %s,\ name\:%s]\ is\ in\ state\ of\ %s\ which\ disallows\ the\ operation[%s] = 项目[[uuid: {0}, 名称:{1}]]是{2}状态,不允许执行[{3}]操作 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:523 +# args: +either\ l3NetworkUuids\ or\ imageUuid\ must\ be\ set = 三层网络的uuid们或者镜像的uuid必须被设置 -# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:132 -# args: self.getUuid() -Can\ not\ do\ operations,\ because\ Current\ virtualID[uuid\:%s]\ is\ staled,\ please\ enable\ it = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:538 +# args: ip +%s\ is\ not\ a\ valid\ IPv4\ address = {0}不是有效的IPv4地址 -# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:554 -# args: -only\ admin\ and\ the\ virtual\ ID\ itself\ can\ do\ the\ update = 只有admin和virtual ID本身可以执行更新操作 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:576 +# args: ip,vmNicVO.getUuid() +ip\ address\ [%s]\ already\ set\ to\ vmNic\ [uuid\:%s] = IP地址[{0}]已经设置到网卡[uuid:{1}] -# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:558 -# args: msg.getVirtualIDUuid() -old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ virtual\ ID[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:557 +# args: ip,rangeVO.getNetworkCidr() +ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [%s] = IP地址[{0}]不在IP地址段[{1}]范围内 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:43 -# args: attr.getValue() -attribute\ name\ cannot\ be\ null,\ value[%s] = 属性不能为null,输入值[{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:566 +# args: ip +%s\ is\ not\ a\ valid\ IPv6\ address = {0}不是有效的IPv6地址 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:47 -# args: attr.getName() -attribute\ name[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = 属性名称[{0}]不能超过2048个字符 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:584 +# args: ip,rangeVO.getStartIp(),rangeVO.getEndIp() +ip\ address\ [%s]\ is\ not\ in\ ip\ range\ [startIp\ %s,\ endIp\ %s] = IP地址[{0}]不在IP地址段[{1}-{2}]范围内 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:50 -# args: attr.getName(),attr.getValue() -attribute[name\:%s]\ value[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = 属性[name:{0}] value[{1}]不能超过2048个字符 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:595 +# args: +could\ not\ set\ ip\ address,\ due\ to\ no\ ip\ address\ is\ specified = 无法设置IP地址,因为未指定IP地址 + +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:610 +# args: msg.getIp() +static\ ip\ [%s]\ format\ error = 静态IP[{0}]格式错误 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:151 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:622 # args: -admin\ is\ a\ reserved\ name,\ please\ use\ another\ name = admin是保留名称,请使用其他名称 +ipv4\ address\ need\ a\ netmask = IPv4地址需要网络掩码 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:159 -# args: msg.getName() -invalid\ name[%s],\ there\ has\ been\ a\ project\ or\ account\ with\ the\ same\ name = 无效的名称[{0}],已经存在同名的项目或账户 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:640 +# args: msg.getIp6() +ip\ address\ [%s]\ already\ set\ to\ vmNic = IP地址[{0}]已设置为vmnic -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:167 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ group = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:634 +# args: +ipv6\ address\ need\ a\ prefix = IPv6地址需要前缀 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:175 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ organization = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:654 +# args: msg.getVmInstanceUuid(),msg.getL3NetworkUuid() +the\ VM[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = 云主机[uuid:{0}]在三层网络[uuid:{1}]上没有任何网卡 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:183 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ project = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:661 +# args: msg.getStaticIp(),msg.getVmInstanceUuid() +could\ not\ delete\ static\ ip\ [%s]\ for\ vm\ [uuid\:%s]\ because\ it\ doesn't\ existed = 无法删除VM[uuid:{1}]的静态IP[{0}],因为它不存在 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:191 -# args: msg.getUuid() -attribute[uuid\:%s]\ is\ not\ for\ any\ virtual\ ID = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:673 +# args: o,msg.getBootOrder() +invalid\ boot\ device[%s]\ in\ boot\ order%s = 在启动列表{1}中的设备[{0}]启动失败 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:211 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:696 # args: -retire\ policy\ must\ be\ deleted\ before\ pull\ the\ project\ out\ of\ Retired\ state = +boot\ volume\ cannot\ be\ shareable. = 启动卷无法共享。 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:223 -# args: state -login\ is\ prohibited\ because\ the\ project\ is\ in\ state\ of\ %s = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:700 +# args: msg.getVolumeUuid(),msg.getVmInstanceUuid() +volume[uuid\:%s]\ must\ be\ attached\ to\ vm[uuid\:%s] = 卷[uuid:{0}]必须连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:237 -# args: name -no\ quota[name\:%s]\ found = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:705 +# args: msg.getVmInstanceUuid() +the\ vm\ %s\ with\ memory\ snapshots\ do\ not\ support\ setting\ boot\ volume = 具有内存快照的云主机{0}不支持设置启动卷 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:261 -# args: msg.getUuid() -organization[uuid\:%s]\ is\ a\ Company\ that\ cannot\ have\ parent\ organization = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:718 +# args: type +Unsupported\ Image\ Media\ Type\:\ [%s]\ = 不支持的镜像媒体类型:[{0}] -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:273 -# args: msg.getName() -duplicate\ virtualID\ name[%s] = 重复的用户名[{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:733 +# args: cdRomUuid +The\ cdRom[uuid\:%s]\ does\ not\ exist = CDROM[uuid:{0}]不存在 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:291 -# args: msg.getName() -duplicate\ project\ name[%s] = 重复的项目名[{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:737 +# args: msg.getVmInstanceUuid(),cdRomUuid +VM[uuid\:%s]\ cdRom[uuid\:%s]\ has\ mounted\ the\ ISO = VM[uuid:{0}]CDROM[uuid:{1}]已装载ISO -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:299 -# args: msg.getName() -invalid\ project\ name[%s],\ an\ account\ or\ project\ with\ the\ same\ name\ exists = 无效的项目名[{0}],已有账户或项目使用了相同的名称 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:755 +# args: msg.getVmInstanceUuid() +VM[uuid\:%s]\ has\ multiple\ ISOs\ attached,\ specify\ the\ isoUuid\ when\ detaching = 云主机[uuid:{0}]已经加载了多个ISO,卸载ISO时需要指定isoUuid -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:315 -# args: refVO.getProjectUuid(),refVO.getOrganizationUuid() -The\ project[uuid\=%s]\ has\ been\ attached\ to\ the\ organization[uuid\=%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:863 +# args: l3Uuid +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ disabled = 不能挂载三层网络,因为该三层网络[uuid:{0}]处于未启动状态 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:325 -# args: msg.getProjectUuid() -The\ project[uuid\=%s]\ is\ not\ attached = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:813 +# args: msg.getVmInstanceUuid(),state +unable\ to\ attach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = 无法挂载三层网络。云主机[uuid: {0}]既不处于Running也不处于Stopped状态中,当前状态为{1} -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:336 -# args: uuids -organizations%s\ are\ company\ that\ cannot\ be\ children\ of\ other\ organization = 组织{0}类型是子公司,不能设置为其它组织的部门 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:819 +# args: msg.getL3NetworkUuid() +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ doesn't\ has\ have\ ip\ range = 无法连接三层网络。三层网络[uuid:{0}]没有IP范围 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:398 -# args: staleVirtualIDs -can\ not\ operate\ stale\ virtual\ ids\:\ %s = 无法操作无效的用户: {0} +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:829 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ different\ l2\ networks\ [uuids\:%s] = 不能挂载三层网络,三层网络[uuid:{0}]属于不同的二层网络 -# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:417 -# args: wrong,msg.getGroupUuid() -virtual\ ids%s\ not\ in\ the\ project\ the\ group[uuid\:%s]\ belongs\ to = 用户{0}不在用户组[uuid:{1}]所在的项目中 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:836 +# args: newAddedL3Uuids,l2Uuids +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ are\ belonged\ to\ l2\ networks\ [uuids\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = 无法连接三层网络。三层网络[uuid:{0}]属于尚未连接到任何集群的二层网络[uuid:{1}] -# at: src/main/java/org/zstack/iam2/attribute/SystemAttributes.java:69 -# args: -attribute[name\:%s]\ is\ a\ system\ attribute\ that\ cannot\ be\ updated = 属性[名称:{0}]是一个系统属性,无法被更新 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:848 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 不能挂载三层网络,三层网络[uuid:{0}]已经挂载到云主机[uuid: {1}]上了 -# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:37 -# args: inv.getValue() -virtual\ ID[uuid\:%s]\ not\ existing = 用户[uuid:{0}]不存在 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:855 +# args: attachedL3Uuids,msg.getVmInstanceUuid() +unable\ to\ attach\ a\ non-guest\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 无法连接非来宾三层网络。三层网络[uuid:{0}]已连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:44 -# args: inv.getValue(),((IAM2OrganizationAttributeInventory) inv).getOrganizationUuid() -virtual\ ID[uuid\:%s]\ not\ in\ organization[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:866 +# args: l3Uuid +unable\ to\ attach\ a\ L3\ network.\ The\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = 不能连接三层网络。这个三层网络[uuid:{0}]是系统网络,但云主机是一个用户云主机 -# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:49 -# args: oinv.getOrganizationUuid() -organization[uuid\:%s]\ already\ has\ a\ supervisor = 组织[uuid:{0}]已经设置了负责人 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1300 +# args: e.getMessage() +invalid\ json\ format,\ causes\:\ %s = 无效的JSON格式,原因:{0} -# at: src/main/java/org/zstack/iam2/attribute/project/Retire.java:65 -# args: pinv.getUuid(),pinv.getName() -the\ project[uuid\:%s,\ name\:%s]\ already\ has\ a\ retire\ policy = 项目[uuid:{0}, name:{1}]已经设置了回收策略 - -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:52 -# args: -invalid\ value,\ no\ 'at',\ 'after'\ or\ 'exceed'\ found = 无效的值,找不到关键字no 'at', 'after' or 'exceed' +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:986 +# args: msg.getVmInstanceUuid(),state +unable\ to\ attach\ the\ nic.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = 无法连接NIC。VM[uuid:{0}]未运行或已停止。当前状态为{1} -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:57 -# args: value -invalid\ value,\ %s = 无效的值, {0} +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:993 +# args: vmNicVO.getVmInstanceUuid() +unable\ to\ attach\ the\ nic.\ The\ nic\ has\ been\ attached\ with\ vm[uuid\:\ %s] = 无法连接NIC。已使用VM[uuid:{0}]连接NIC -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:63 -# args: ss[0],Means.values() -invalid\ means[%s],\ allowed\ means\ are\ %s = 无效的回收方法[{0}],允许的方法是{1} +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1004 +# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() +unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 无法连接NIC。其三层网络[uuid:{0}]已连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:98 -# args: policyValue -invalid\ spending\ value[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10.001 = 无效的费用[{0}], 费用格式应该符合例如:10.001 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1009 +# args: vmNicVO.getL3NetworkUuid(),msg.getVmInstanceUuid() +unable\ to\ attach\ the\ nic\ with\ a\ non-guest\ L3\ network.\ Its\ L3\ network[uuid\:%s]\ is\ already\ attached\ to\ the\ vm[uuid\:\ %s] = 无法将NIC连接到非来宾三层网络。其三层网络[uuid:{0}]已连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:92 -# args: policyValue,Double.MAX_VALUE -invalid\ spending\ value[%s],\ spending\ value\ should\ between\ 0\ and\ %f = 无效的费用[{0}], 费用范围应该在0到{1}之间 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1018 +# args: l3NetworkVO.getUuid() +unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ disabled = 无法连接NIC。其三层网络[uuid:{0}]已禁用 -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:85 -# args: policyValue -invalid\ time[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10m,\ 1h,\ 2d = 无效的时间[{0}],时间格式需要符合例如:10m, 1h, 2d +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1021 +# args: l3NetworkVO.getUuid() +unable\ to\ attach\ the\ nic.\ Its\ L3\ network[uuid\:%s]\ is\ a\ system\ network\ and\ vm\ is\ a\ user\ vm = 无法连接NIC。其三层网络[uuid:{0}]是系统网络,VM是用户VM -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:76 -# args: policyValue -invalid\ date[%s],\ it\ should\ be\ in\ format\ of\ yyyy-MM-dd\ HH\:mm\:ss = 无效的日期,日期格式需要符合:yyyy-MM-dd HH:mm:ss +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1028 +# args: l3NetworkVO.getL2NetworkUuid() +unable\ to\ attach\ the\ nic.\ Its\ l2\ network\ [uuid\:%s]\ that\ have\ not\ been\ attached\ to\ any\ cluster = 无法连接NIC。其二层网络[uuid:{0}]尚未连接到任何集群 -# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:105 -# args: policyValue,dateFormat.format(new Timestamp(System.currentTimeMillis())) -invalid\ date\ or\ time[%s],\ it\ cannot\ be\ before\ current\ time[%s] = 无效的日期或时间,回收时间不能在当前时间之前[{1}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1037 +# args: msg.getVmNicUuid(),nicVO.getType() +could\ not\ update\ nic[uuid\:\ %s]\ state,\ due\ to\ nic\ type[%s]\ not\ support = 无法更新NIC[uuid:{0}]状态,因为不支持NIC类型[{1}] -# at: src/main/java/org/zstack/iam2/attribute/virtualid/AbstractAdminAttribute.java:17 -# args: vid,attributeName -virtual\ ID[uuid\:%s]\ already\ has\ admin\ related\ attributes,\ can\ not\ add\ %s = 用户[uuid:{0}]已经有管理员属性了,无法继续添加属性{1} +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1043 +# args: msg.getVmNicUuid() +could\ not\ update\ nic[uuid\:\ %s]\ state,\ due\ to\ vm\ not\ support = 无法更新NIC[uuid:{0}]状态,因为VM不支持 -# at: src/main/java/org/zstack/iam2/attribute/virtualid/IAM2ProjectOperator.java:35 -# args: idinv.getVirtualIDUuid() -virtual\ id[uuid\:%s]\ already\ has\ a\ project\ operator\ attribute = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1060 +# args: vmUuid,state +unable\ to\ detach\ a\ L3\ network.\ The\ vm[uuid\:\ %s]\ is\ not\ Running\ or\ Stopped;\ the\ current\ state\ is\ %s = 不能卸载三层网络,云主机[uuid: {0}]不是运行状态或者暂停状态,状态为{1} -# at: src/main/java/org/zstack/iam2/attribute/virtualid/PlatformAdminZoneRelation.java:36 -# args: inv.getValue() -cannot\ find\ zone[uuid\:%s] = 找不到区域[uuid:{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1075 +# args: msg.getVmInstanceUuid(),state +vm[uuid\:%s]\ can\ only\ attach\ volume\ when\ state\ is\ Running\ or\ Stopped,\ current\ state\ is\ %s = 云主机[uuid:{0}]挂载盘时状态只能是运行或者暂停状态,而现在的状态是{1} -# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:71 -# args: inv.getValue() -project[uuid\:%s]\ already\ has\ a\ project\ admin = 项目[uuid:{0}]已经设置过项目管理员了 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1083 +# args: +image\ mediaType\ is\ ISO\ but\ missing\ root\ disk\ settings = 镜像媒体类型为ISO,但缺少根磁盘设置 -# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:83 -# args: inv.getValue() -project[uuid\:%s]\ not\ existing = 项目[uuid:{0}]不存在 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1087 +# args: +Unexpected\ root\ disk\ settings = 意外的根磁盘设置 -# at: src/main/java/org/zstack/iam2/rbac/IAM2AuthorizationBackend.java:130 -# args: deniedApis -the\ operations[%s]\ is\ denied = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1154 +# args: +Unexpected\ data\ disk\ settings.\ dataDiskSizes\ need\ to\ be\ greater\ than\ 0 = 意外的数据磁盘设置。DataDiskSizes需要大于0 -# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:28 -# args: session.getAccountUuid() -project\ of\ account[uuid\:%s]\ not\ exists = 账户为[uuid:{0}]的项目不存在 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1206 +# args: msg.getImageUuid() +at\ least\ one\ of\ field\ platform\ in\ msg\ or\ image[uuid\:%s]\ should\ be\ set = 至少应设置消息或镜像[uuid:{0}]中的一个字段平台 -# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:37 -# args: projectUuid -project[uuid\:%s]\ is\ retired,\ reject\ all\ operations = 项目[uuid:{0}]已经过期,无法操作 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1210 +# args: msg.getImageUuid() +at\ least\ one\ of\ field\ guestOsType\ in\ msg\ or\ image[uuid\:%s]\ should\ be\ set = 至少应设置邮件或镜像[uuid:{0}]中的一个字段GuestOsType -# at: src/main/java/org/zstack/iam2/IAM2QuotaChangeChecker.java:112 -# args: quota.getName(),quota.getIdentityUuid(),updatedValue,organizationUuid -the\ quota[name\:%s]\ of\ Account[uuid\:%s]\ can\ not\ be\ %d,\ otherwise\ it\ will\ exceeds\ the\ quota\ of\ organization[uuid\:%s] = 账户[uuid:{1}]的Quota[{0}]不能改成{2},因为修改后它将超出组织[uuid:{3}]的Quota +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1214 +# args: msg.getImageUuid() +at\ least\ one\ of\ field\ architecture\ in\ msg\ or\ image[uuid\:%s]\ should\ be\ set = 至少应设置消息或镜像[uuid:{0}]中的一个字段体系结构 -# at: src/main/java/org/zstack/identity/AccountBase.java:323 -# args: group.getUuid(),msg.getAccountUuid() -the\ user\ group[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = 这个用户组[uuid:{0}]不属于当前账户[uuid:{1}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1349 +# args: errorMsg +Cannot\ set\ the\ following\ properties\ at\ the\ same\ time\:\ %s = 不能同时设置以下属性:{0} -# at: src/main/java/org/zstack/identity/AccountBase.java:425 -# args: msg.getName(),msg.getIdentityUuid() -cannot\ find\ Quota[name\:\ %s]\ for\ the\ account[uuid\:\ %s] = 无法为当前账户[uuid: {1}]找到Quota +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1357 +# args: properties +Need\ to\ set\ one\ of\ the\ following\ properties,\ and\ can\ only\ be\ one\ of\ them\:\ %s = 需要设置以下属性之一,且只能是其中一个:{0} -# at: src/main/java/org/zstack/identity/AccountBase.java:504 -# args: self.getUuid(),ruuid -the\ account[uuid\:\ %s]\ doesn't\ have\ a\ resource[uuid\:\ %s] = 账户[uuid: {0}]没有资源[uuid: {1}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1249 +# args: +cannot\ create\ vm\ instance\ from\ a\ shareable\ volume. = 无法从可共享云盘创建VM实例。 -# at: src/main/java/org/zstack/identity/AccountBase.java:561 -# args: user.getUuid(),msg.getAccountUuid() -the\ user[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = 当前用户[uuid:{0}]不属于当前账户[uuid:{1}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1253 +# args: +could\ not\ create\ vm\ instance\ from\ a\ attached\ volume. = 无法从连接的卷创建VM实例。 -# at: src/main/java/org/zstack/identity/AccountBase.java:566 -# args: user.getUuid() -old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ user[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1257 +# args: msg.getVolumeUuid() +volume[uuid\:%s]\ could\ not\ satisfy\ conditions[state\:Enabled\ status\:Ready] = 卷[uuid:{0}]无法满足条件[状态:已启用状态:就绪] -# at: src/main/java/org/zstack/identity/AccountInterceptor.java:55 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1293 # args: -wrong\ password = - -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1612 -# args: JSONObjectUtil.toJsonString(s) -a\ statement\ must\ have\ effect\ field.\ Invalid\ statement[%s] = 声明必须含有'effect'字段。 无效的声明 +l3NetworkUuids\ and\ vmNicInventories\ mustn't\ both\ be\ empty\ or\ both\ be\ set = l3NetworkUuids和vmnicinventory不能同时为空或同时设置 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1615 -# args: JSONObjectUtil.toJsonString(s) -a\ statement\ must\ have\ action\ field.\ Invalid\ statement[%s] = 声明必须含有'action'字段。 无效的声明 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1415 +# args: cdRomIsoUuid +The\ image[uuid\=%s]\ does\ not\ exist = 镜像[uuid={0}]不存在 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1618 -# args: JSONObjectUtil.toJsonString(s) -a\ statement\ must\ have\ a\ non-empty\ action\ field.\ Invalid\ statement[%s] = 声明必须含有不为空的'action'字段。 无效的声明 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1420 +# args: +Do\ not\ allow\ to\ mount\ duplicate\ ISO = 不允许装载重复的ISO -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:165 -# args: resourceUuid -cannot\ find\ the\ resource[uuid\:%s];\ wrong\ resourceUuid\ or\ the\ resource\ is\ admin\ resource = 无法找到资源[uuid:{0}]: 错误的资源uuid或者资源是管理员资源 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1435 +# args: +The\ console\ password\ cannot\ start\ with\ 'password'\ which\ may\ trigger\ a\ VNC\ security\ issue = 控制台密码不能以password开头,这样可能导致一个VNC安全问题 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:399 -# args: msg.getUserUuid() -the\ user\ specified\ by\ the\ userUuid[%s]\ does\ not\ belong\ to\ the\ current\ account,\ and\ the\ current\ account\ is\ not\ an\ admin\ account,\ so\ it\ has\ no\ permission\ to\ check\ the\ user'spermissions = 当前通过userUuid获得的user不属于当前账户,而且当前账户不是管理员账户 +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1440 +# args: +can\ not\ call\ this\ api\ because\ it's\ Deprecated = 无法调用此API,因为它已被弃用 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1009 -# args: accountUuid -cannot\ find\ the\ account[uuid\:%s] = 找不到账户[uuid:{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java:1457 +# args: vmCdRomVO.getUuid() +The\ CdRom[%s]\ Already\ the\ default = CDROM[{0}]已经是默认的 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1447 -# args: -accountName\ and\ accountUuid\ cannot\ both\ be\ null,\ you\ must\ specify\ at\ least\ one = 账户名和账户Uuid不能同时为空,您必须定义至少一个 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:271 +# args: vo.getUuid(),vo.getName() +vm[uuid\:%s,\ name\:%s]\ has\ been\ deleted = 云主机[uuid:{0}, name:{1}]已经被删除了 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1458 -# args: msg.getName(),msg.getAccountUuid() -unable\ to\ create\ a\ group.\ A\ group\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = 不能创建用户组,用户组“{0}”已经在账户“{0}”下了 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:595 +# args: vmInv.getUuid(),vmInv.getHostUuid(),reply.getError() +failed\ to\ check\ state\ of\ the\ vm[uuid\:%s]\ on\ the\ host[uuid\:%s],\ %s = 无法检查物理机[uuid:{1}]上的VM[uuid:{0}]的状态,{2} -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1468 -# args: msg.getName(),msg.getAccountUuid() -unable\ to\ create\ a\ user.\ A\ user\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = 不能创建用户,用户“{0}”已经在账户“{0}”下了 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:602 +# args: vmInv.getUuid(),vmInv.getHostUuid() +got\ an\ unrecognized\ state\ of\ the\ vm[uuid\:%s]\ on\ the\ host[uuid\:%s] = 物理机[uuid:{1}]上的VM[uuid:{0}]的状态无法识别 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1477 -# args: msg.getName() -unable\ to\ create\ an\ account.\ An\ account\ already\ called\ %s = 不能创建账户,“{0}”已经被使用 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:984 +# args: self.getUuid(),l3Uuid +the\ vm[uuid\:%s]\ has\ no\ nic\ on\ the\ L3\ network[uuid\:%s] = 云主机[uuid:{0}] 没有网卡在三层网络[uuid:{1}]上 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1484 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:1382 # args: -account\ cannot\ delete\ itself = 账户不能删除自己 +the\ vm\ has\ been\ deleted = 云主机已经被删除了 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1490 -# args: -cannot\ delete\ builtin\ admin\ account. = +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:3758 +# args: msg.getUuid() +VM[uuid\:%s]\ state\ is\ not\ Running. = VM[uuid:{0}]状态未运行。 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1496 -# args: -Only\ admin\ can\ delete\ account. = 只有admin能删除账户 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:4837 +# args: isoUuid,psUuid,self.getName(),self.getUuid() +the\ ISO[uuid\:%s]\ is\ on\ backup\ storage\ that\ is\ not\ compatible\ of\ the\ primary\ storage[uuid\:%s]\ where\ the\ VM[name\:%s,\ uuid\:%s]\ is\ on = ISO[uuid:{0}]在镜像服务器上,这个ISO不能兼容主存储[uuid:{1}]在云主机[name:{2}, uuid:{3}]上 -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1504 -# args: -the\ current\ session\ is\ an\ account\ session.\ You\ need\ to\ specify\ the\ field\ 'uuid'\ of\ the\ user\ you\ want\ to\ update = 当前会话是一个账户会话,你需要定义一个'uuid'字段来指定你要更新的用户 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5325 +# args: self.getHostUuid(),cpuNum - oldCpuNum,struct.alignedMemory - oldMemorySize +host[uuid\:%s]\ capacity\ is\ not\ enough\ to\ offer\ cpu[%s],\ memory[%s\ bytes] = 物理机[uuid:{0}]无法提供CPU: [{1}],内存: [{2} bytes] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1519 -# args: msg.getUuid() -your\ are\ login\ as\ a\ user,\ you\ cannot\ another\ user[uuid\:%s] = 你已经登录为一个用户,不能成为另一个用户[uuid:{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:5633 +# args: isoUuid,self.getUuid() +ISO[uuid\:%s]\ is\ not\ attached\ to\ VM[uuid\:%s] = ISO[uuid:{0}]未被加载到云主机[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1527 -# args: -all\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = all参数被设为false时,账户uuid不能为空 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:7168 +# args: cdRomSpecs.size(),max +One\ vm\ cannot\ create\ %s\ CDROMs,\ vm\ can\ only\ add\ %s\ CDROMs = 一个VM无法创建{0}个CDROM,VM只能添加{1}个CDROM -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1535 -# args: -toPublic\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = toPublic参数被设为false时,账户uuid不能为空 +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:8150 +# args: msg.getVmInstanceUuid(),max +VM[uuid\:%s]\ can\ only\ add\ %s\ CDROMs = VM[uuid:{0}]只能添加{1}个CDROM -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1584 -# args: policy.getName(),policy.getUuid(),msg.getSession().getAccountUuid() -policy[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = 策略[名称: {0}, uuid: {1}]不属于账户[uuid: {2}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceBase.java:8219 +# args: self.getUuid(),msg.getPriority(),reply.getError() +update\ vm[%s]\ priority\ to\ [%s]\ failed,because\ %s = 将云主机[{0}]的优先级更新为[{1}]失败,原因是{2} -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1598 -# args: user.getName(),user.getUuid(),msg.getSession().getAccountUuid() -user[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = 用户[名称: {0}, uuid: {1}]不属于账户[uuid: {2}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:65 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceStartNewCreatedVmExtensionPoint[%s]\ refuses\ to\ create\ vm[uuid\:%s]\ because\ %s = VmInstanceStartNewCreatedVmExtensionPoint[{0}] 因为{2} 拒绝创建云主机[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1602 -# args: group.getName(),group.getUuid(),msg.getSession().getAccountUuid() -group[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = 用户组[名称: {0}, uuid: {1}]不属于账户[uuid: {2}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:192 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceRebootExtensionPoint[%s]\ refuses\ to\ reboot\ vm[uuid\:%s]\ because\ %s = VmInstanceRebootExtensionPoint[{0}] 因为{2} 拒绝重启云主机[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1643 -# args: msg.getName() -unable\ to\ update\ name.\ An\ account\ already\ called\ %s = +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:234 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceDestroyVmExtensionPoint[%s]\ refuses\ to\ destroy\ vm[uuid\:%s]\ because\ %s = VmInstanceDestroyVmExtensionPoint[{0}] 因为{2} 拒绝删除云主机[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1654 -# args: msg.getUuid() -old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ account[uuid\:\ %s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceExtensionPointEmitter.java:284 +# args: ext.getClass().getName(),inv.getUuid(),err +VmInstanceStartExtensionPoint[%s]\ refuses\ to\ start\ vm[uuid\:%s]\ because\ %s = VmInstanceStartExtensionPoint[{0}] 因为{2} 拒绝启动云主机[uuid:{1}] -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1659 -# args: -the\ name\ of\ admin\ account\ cannot\ be\ updated = 不能更改管理员账户名称 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1136 +# args: msg.getName() +could\ not\ create\ vm,\ a\ vm\ with\ the\ name\ [%s]\ already\ exists = 无法创建VM,已存在名为[{0}]的VM -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1665 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2245 # args: -only\ admin\ account\ can\ update\ it's\ password = - -# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1672 -# args: account.getUuid(),account.getName(),msg.getUuid() -account[uuid\:\ %s,\ name\:\ %s]\ is\ a\ normal\ account,\ it\ cannot\ reset\ the\ password\ of\ another\ account[uuid\:\ %s] = [uuid: {0}, 名称: {1}]是一个普通账户,不能被其他普通账户重设密码 +rootDiskOfferingUuid\ cannot\ be\ null\ when\ create\ vm\ without\ image = 在不使用镜像的情况下创建VM时,RootDiskOfferInGuuid不能为空 -# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:190 -# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),uuid,resourceType.getSimpleName() -permission\ denied,\ the\ account[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ resource[uuid\:%s,\ type\:%s] = 操作错误,账户[uuid:{0}]不是资源[uuid:{1}, type:{2}]的所有者 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:308 +# args: +Spice\ certificate\ does\ not\ exist,\ Please\ check\ if\ spice\ tls\ is\ enabled = SPICE证书不存在,请检查是否启用了SPICE TLS -# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:210 -# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),resourceWithNoAccess,resourceType.getSimpleName() -the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resources[uuid\:%s,\ type\:%s] = 账户[uuid:{0}]无法使用资源[uuid:{1}, type:{2}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:492 +# args: msg.getImageUuid(),msg.getZoneUuid() +the\ image[uuid\:%s]\ is\ not\ on\ any\ backup\ storage\ that\ has\ been\ attached\ to\ the\ zone[uuid\:%s] = 镜像[uuid:{0}]不在任何加载到区域[uuid:{1}]的镜像服务器上 -# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:80 -# args: rbacEntity.getApiMessage().getClass().getName() -operation[API\:%s]\ is\ denied\ by\ default,\ please\ contact\ admin\ to\ correct\ it = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:565 +# args: bss.get(0).getUuid(),bss.get(0).getType() +no\ primary\ storage\ accessible\ to\ the\ backup\ storage[uuid\:%s,\ type\:%s]\ is\ found = 未找到镜像服务器[uuid:{0}, type:{1}]可访问的主存储 -# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:187 -# args: p.getName(),p.getUuid() -the\ operation\ is\ denied\ by\ the\ policy[name\:%s\ uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:586 +# args: psUuids,zoneUuid +the\ primary\ storages[uuids\:%s]\ has\ not\ attached\ any\ cluster\ on\ the\ zone[uuid\:%s] = 主存储[uuids:{0}]尚未加载区域[uuid:{1}]上的任何集群 -# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:200 -# args: p.getName(),p.getUuid(),fname -the\ operation\ is\ denied\ by\ the\ policy[name\:%s,\ uuid\:%s],\ field[%s]\ is\ not\ permitted\ to\ set = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:605 +# args: psUuids +no\ l2Networks\ found\ in\ clusters\ that\ have\ attached\ to\ primary\ storages[uuids\:%s] = 在已加载到主存储[uuids:{0}]的集群中未找到二层网络 -# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:92 -# args: -cannot\ update\ a\ system\ or\ predefined\ role = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:672 +# args: image.getName(),image.getUuid() +zoneUuid\ must\ be\ set\ because\ the\ image[name\:%s,\ uuid\:%s]\ is\ on\ multiple\ backup\ storage = zoneUuid必须被设置,因为image[name:{0}, uuid:{1}]在多个镜像服务器上 -# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:108 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1067 # args: -cannot\ delete\ a\ system\ or\ predefined\ role = +CreateVmInstanceMsg\ cannot\ be\ null = CreateVmInstanceMsg不能为空 -# at: src/main/java/org/zstack/identity/AccountQuotaChangeChecker.java:31 -# args: quota.getName(),quota.getIdentityUuid(),updatedValue -the\ quota[name\:%s]\ of\ account[uuid\:%s]\ can\ not\ be\ %d = 账户[uuid:{1}]的Quota[{0}]不能改为{2} +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1158 +# args: StringUtils.join(errorCodes.stream().map(ErrorCode::getDescription).collect(Collectors.toList()), ", ") +handle\ system\ tag\ fail\ when\ creating\ vm\ because\ [%s] = 由于[{0}],在创建VM时处理系统标记失败 -# at: src/main/java/org/zstack/identity/AccountQuotaChangeChecker.java:55 -# args: accountUuid,quotaName,usage.getUsed(),updatedValue -the\ account[uuid\:%s]\ used\ [name\:%s,\ usedValue\:%s]\ exceeds\ request\ quota\:\ %d = 账户[uuid:{0}]的Quota[{1}]已使用量为{2},无法修改Quota成{3} +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1589 +# args: tuple.get(0, String.class),tuple.get(1, String.class) +unable\ to\ enable\ this\ function.\ There\ are\ multi\ nics\ of\ L3\ network[uuid\:%s]\ in\ the\ vm[uuid\:\ %s] = 无法启用此功能。云主机[uuid:{1}]中存在多个三层网络[uuid:{0}]的NIC -# at: src/main/java/org/zstack/image/BackupStorageDeleteBitGC.java:35 -# args: backupStorageUuid,bsStatus -the\ backup\ storage[uuid\:%s]\ is\ not\ in\ status\ of\ Connected,\ current\ status\ is\ %s = 镜像服务器[uuid:{0}]不是Connected状态,当前状态为{1} +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1623 +# args: hostname,tag +hostname[%s]\ specified\ in\ system\ tag[%s]\ is\ not\ a\ valid\ domain\ name = 在系统标签[{1}]中特别声明的物理机名[{0}]不是一个有效的域名 -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:88 -# args: vol.getUuid(),vol.getStatus() -volume[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = 云盘[uuid:{0}]未Ready,它现在为{1} +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1635 +# args: hostnameCount +only\ one\ hostname\ system\ tag\ is\ allowed,\ but\ %s\ got = 只允许通过系统标签设置一个物理机名,但是实际上有{0} -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:92 -# args: vol.getUuid(),vol.getState() -volume[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = 云盘[uuid:{0}]未Enabled,它现在为{1} +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1660 +# args: ip,sysTag +%s\ is\ not\ a\ valid\ ip\ address.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = {0}不是有效的IP地址。请更正静态IP的系统标记[{1}] -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:99 -# args: vsvo.getUuid(),vsvo.getStatus() -volume\ snapshot[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1666 +# args: ip,l3Uuid,sysTag +IP[%s]\ is\ already\ used\ on\ the\ L3\ network[uuid\:%s].\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = IP[{0}]已在三层网络[uuid:{1}]上使用。请更正静态IP的系统标记[{2}] -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:103 -# args: vsvo.getUuid(),vsvo.getState() -volume\ snapshot[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1683 +# args: ip,l3Uuid,cr.getReason() +IP[%s]\ is\ not\ available\ on\ the\ L3\ network[uuid\:%s]\ because\:\ %s = 在三层网络[uuid:{1}]中,IP[{0}]不可用, 因为{2} -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:174 -# args: -ISO\ cannot\ be\ used\ as\ system\ image = ISO不能被作为一个系统标签 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1706 +# args: tag,sameTag.getResourceUuid(),hostname,l3Uuid +conflict\ hostname\ in\ system\ tag[%s];\ there\ has\ been\ a\ VM[uuid\:%s]\ having\ hostname[%s]\ on\ L3\ network[uuid\:%s] = 系统标签的物理机名存在冲突[{0}];已经存在以一个物理机名为[{2}]的VM[uuid:{1}]出现在三层网络[uuid:{3}]中 -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:180 -# args: msg.getFormat() -unknown\ format[%s] = 未知格式[{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1737 +# args: o,order +invalid\ boot\ device[%s]\ in\ boot\ order[%s] = 在引导顺序[{1}]中存在无效的引导设备[{0}] -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:184 -# args: msg.getType() -unsupported\ image\ type[%s] = 不支持的镜像类型[{0}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1753 +# args: +cpuSockets\ must\ be\ an\ integer = CPUSockets必须为整数 -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:203 -# args: msg.getBackupStorageUuids(),BackupStorageStatus.Connected,BackupStorageState.Enabled -no\ backup\ storage\ specified\ in\ uuids%s\ is\ available\ for\ adding\ this\ image;\ they\ are\ not\ in\ status\ %s\ or\ not\ in\ state\ %s,\ or\ the\ uuid\ is\ invalid\ backup\ storage\ uuid = 镜像服务器uuids{0}不满足添加镜像的条件;它们的状态不同时满足{1}和{2},亦或者是无效的uuid +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1762 +# args: +cpuCores\ must\ be\ an\ integer = cpucores必须为整数 -# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:214 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1771 # args: -url\ must\ starts\ with\ 'file\:///',\ 'http\://',\ 'https\://',\ 'ftp\://',\ 'sftp\://'\ or\ '/' = url必须以下列格式开头'file:///', 'http://', 'https://', 'ftp://', 'sftp://' or '/' +cpuThreads\ must\ be\ an\ integer = CPUThreads必须为整数 -# at: src/main/java/org/zstack/image/ImageBase.java:168 -# args: self.getUuid(),self.getName() -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ any\ backup\ storage = 镜像[uuid:{0}, 名称:{1}]不在任一镜像服务器上 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1782 +# args: resourceUuid +Already\ have\ one\ userdata\ systemTag\ for\ vm[uuid\:\ %s]. = 在云主机[uuid:{0}]已经存在一个userdata的系统标签 -# at: src/main/java/org/zstack/image/ImageBase.java:178 -# args: self.getUuid(),self.getName() -No\ connected\ backup\ storage\ found\ for\ image[uuid\:%s,\ name\:%s] = 在所有 Connected 状态的镜像服务器上都找不到镜像[uuid:{0}, name:{1}] +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1808 +# args: +Shouldn't\ be\ more\ than\ one\ userdata\ systemTag\ for\ one\ vm. = 在一个云主机中不能存在多个userdata的系统标签 -# at: src/main/java/org/zstack/image/ImageBase.java:366 -# args: msg.getImageUuid(),JSONObjectUtil.toJsonString(errors) -detach\ iso[uuid\=%s]\ from\ vm\ failed,\ errors\ are\ %s = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1932 +# args: type +vm\ machine\ type\ requires\ [q35,\ pc,\ virt],\ but\ get\ [%s] = VM计算机类型需要[q35,PC,virt],但得到[{0}] -# at: src/main/java/org/zstack/image/ImageBase.java:713 -# args: self.getUuid(),self.getName(),bsUuid -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ the\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}, 名称:{1}]不在镜像服务器[uuid:{2}]上 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1992 +# args: systemTag,SecurityElementEnableTokenByTag +invalid\ securityElementEnable[%s],\ %s\ is\ not\ securityElementEnable\ tag = SecurityElementEnable[{0}]无效,{1}不是SecurityElementEnable标记 -# at: src/main/java/org/zstack/image/ImageBase.java:655 -# args: self.getUuid(),self.getName(),ref.getStatus(),bsUuid -the\ image[uuid\:%s,\ name\:%s]'s\ status[%s]\ is\ not\ Deleted\ on\ the\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}, 名称:{1}]的状态[{2}]在镜像服务器[uuid:{3}]上不是Deleled +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:1995 +# args: systemTag,SecurityElementEnableTokenByTag +invalid\ securityElementEnable[%s],\ %s\ is\ not\ boolean\ class = SecurityElementEnable[{0}]无效,{1}不是布尔类 -# at: src/main/java/org/zstack/image/ImageBase.java:697 -# args: self.getUuid(),self.getName() -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ any\ backup\ storage = 镜像[uuid:{0}, 名称:{1}]未在任一镜像服务器上被删除 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2022 +# args: systemTag,usbRedirectTokenByTag +invalid\ usbRedirect[%s],\ %s\ is\ not\ usbRedirect\ tag = usbRedirect[{0}]无效,{1}不是usbRedirect标记 -# at: src/main/java/org/zstack/image/ImageBase.java:718 -# args: self.getUuid(),self.getName(),bsUuid -the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ the\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}, 名称:{1}]未在镜像服务器[uuid:{2}]上被删除 +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2025 +# args: systemTag,usbRedirectTokenByTag +invalid\ usbRedirect[%s],\ %s\ is\ not\ boolean\ class = usbRedirect[{0}]无效,{1}不是布尔类 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:524 -# args: bootModeCount -only\ one\ bootMode\ system\ tag\ is\ allowed,\ but\ %d\ got = +# at: src/main/java/org/zstack/compute/vm/VmInstanceManagerImpl.java:2561 +# args: ref.getResourceUuid() +the\ resource[uuid\:%s]\ is\ a\ ROOT\ volume,\ you\ cannot\ change\ its\ owner,\ instead,change\ the\ owner\ of\ the\ VM\ the\ root\ volume\ belongs\ to = 当前资源[uuid:{0}]是一个云盘,你不能改变它的所有者,但是你能够修改对应VM的所有者 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:542 -# args: bootMode,systemTag -[%s]\ specified\ in\ system\ tag\ [%s]\ is\ not\ a\ valid\ boot\ mode = +# at: src/main/java/org/zstack/compute/vm/VmInstantiateAttachingVolumeFlow.java:54 +# args: spec.getDestHost().getUuid(),pinv.getUuid() +Failed\ to\ instantiate\ volume.\ Because\ vm's\ host[uuid\:\ %s]\ and\ allocated\ primary\ storage[uuid\:\ %s]\ is\ not\ connected. = 无法实例化卷。因为VM的物理机[uuid:{0}]和分配的主存储[uuid:{1}]未连接。 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1032 -# args: -upload\ session\ expired = 上传session失效了 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:211 +# args: msg.getMac() +Duplicate\ mac\ address\ [%s] = 重复的MAC地址[{0}] -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1534 -# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) -unable\ to\ allocate\ backup\ storage\ specified\ by\ uuids%s,\ list\ errors\ are\:\ %s = 不能根据[uuids:{0}]分配镜像服务器,错误清单为: {1} +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:221 +# args: vmType +clean\ traffic\ is\ not\ supported\ for\ vm\ type\ [%s] = VM类型[{0}]不支持清理流量 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1645 -# args: msgData.getRootVolumeUuid() -failed\ to\ create\ image\ from\ root\ volume[uuid\:%s]\ on\ all\ backup\ storage,\ see\ cause\ for\ one\ of\ errors = 在所有镜像服务器上从根云盘[uuid:{0}]创建镜像失败,查看错误原因 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:100 +# args: KVMGlobalConfig.MAX_DATA_VOLUME_NUM.value(int.class) +The\ number\ of\ data\ volumes\ exceeds\ the\ limit[num\:\ %s],\ please\ reduce\ the\ number\ of\ data\ volumes\ during\ vm\ creation. = 数据云盘的数量超过限制[数量:{0}],请在创建云主机期间减少数据云盘的数量。 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1916 -# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) -failed\ to\ allocate\ all\ backup\ storage[uuid\:%s],\ a\ list\ of\ error\:\ %s = 镜像服务器[uuid:{0}]分配失败,错误清单:{1} +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:130 +# args: VmInstanceState.Stopped,msg.getVmInstanceUuid() +Can\ not\ set\ security\ level\ to\ not\ %s\ vm\ [uuid\:%s] = 设置密级失败,无法对不处于{0}状态的云主机操作[uuid:{1}] -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2018 -# args: msgData.getVolumeUuid(),msgData.getBackupStorageUuids() -failed\ to\ create\ data\ volume\ template\ from\ volume[uuid\:%s]\ on\ all\ backup\ storage%s.\ See\ cause\ for\ one\ of\ errors = 在所有镜像服务器[uuid:{1}]上创建云盘[uuid:{0}]的云盘模版失败,查看错误原因 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:147 +# args: +The\ operation\ only\ allows\ on\ user\ vm = 该操作仅允许在用户云主机上执行 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2104 -# args: imageUuid -image[uuid\:%s]\ is\ not\ on\ creating,\ please\ wait\ for\ it\ to\ cancel\ itself. = +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:177 +# args: msg.getVmInstanceUuid(),volumeVOS.stream().map(VolumeVO::getUuid).collect(Collectors.toList()),primaryStorageUuid,(totalCapacity - snapshotsCapacity) * msg.getNames().size(),primaryStorageVO.getCapacity().getAvailableCapacity() +there\ are\ not\ enough\ capacity\ for\ full\ vm\ clone\ to\ vm[uuid\:\ %s],\ volumes[uuid\:\ %s]\ on\ primary\ storage[uuid\:\ %s]\ required\:\ %s\ bytes,\ current\ available\ capacity\ is\ %s\ bytes = 没有足够的空间对云主机[uuid: {0}]做整机克隆,主存储[uuid: {2}]上的云盘[uuid: {1}]共需要[{3}]字节的空间,目前主存储的可用空间为[{4}]字节 -# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2110 -# args: volumeUuid -volume[uuid\:%s]\ has\ been\ deleted.\ no\ need\ to\ cancel = +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:191 +# args: msg.getVmNicUuid() +The\ nic\ [%s%s]\ is\ not\ mounted\ on\ the\ VM = 网卡[{0}]不能被挂载到云主机上 -# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:35 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:197 # args: -Failed\ to\ set\ security\ level,\ because\ security\ level\ is\ disabled. = 设置密级失败,因为密级功能已禁用 +The\ operation\ only\ allows\ on\ user\ vm\ = 该操作只能在用户云主机上进行 -# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:45 -# args: msg.getSecurityLevel(),Arrays.stream(SecurityLevel.values()).map(SecurityLevel::getCode).collect(Collectors.toList()) -Unknown\ security\ level\ code[%s],\ supported\ values\ are\ %s = 未知的密级[{0}],支持的值有[{1}] - -# at: src/main/java/org/zstack/imagereplicator/ImageReplicatorImpl.java:318 -# args: targetBsUuid -target\ backup\ storage[uuid\:%s]\ became\ unavailable = +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:202 +# args: vmInstanceVO.getUuid() +The\ operation\ only\ allows\ when\ vm\ [%s]\ state\ is\ stopped\ = 该操作只有云主机[{0}]状态为已停止才能进行 -# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:30 -# args: String.join(",", msg.getBackupStorageUuids()),msg.getReplicationGroupUuid() -One\ or\ more\ backup\ storage[uuids\:%s]\ has\ been\ added\ to\ replication\ group[uuid\:%s] = +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:231 +# args: msg.getVmInstanceUuid() +user\ has\ no\ privilege\ to\ change\ image\ of\ vm\ %s = 当前用户不能修改云主机{0}的镜像 -# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:41 -# args: bsUuid -Backup\ storage[uuids\:%s]\ is\ not\ of\ type\ ImageStore = +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:243 +# args: +do\ not\ change\ vm\ image\ when\ it's\ not\ stopped = 当云主机镜像未停止时,不要更改它 -# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:51 -# args: bsUuid -Backup\ storage[uuids\:%s]\ is\ not\ attached\ to\ any\ Zone = +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:260 +# args: msg.getVmInstanceUuid() +make\ sure\ the\ primary\ storage\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = 确认主存储[uuid:{0}]是可用的且已连接 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:63 -# args: l3NetworkUuid -Network\ [uuid\:\ %s]\ does't\ not\ have\ IPsec\ service = 网络[uuid: {0}]没有IPsec服务 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:275 +# args: msg.getVmInstanceUuid() +make\ sure\ the\ last\ host\ vm[uuid\:%s]\ was\ on\ is\ Enabled\ and\ Connected = 确定物理机[uuid:{0}]是可用的且已连接 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:73 -# args: rcidr,tempCidr -the\ remote\ CIDR[%s]\ and\ remote\ CIDR[%s]\ are\ overlaped = 远程的CIDR[{0}]和远端CIDR[{1}]存在覆盖 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:285 +# args: msg.getVmInstanceUuid() +vm[uuid\:%s]\ has\ no\ default\ l3,\ cannot\ change\ image\ for\ it = VM[uuid:{0}]没有默认的L3,无法为其更改镜像 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:97 -# args: lcidr,tempCidr -the\ CIDR[%s]\ of\ local\ router\ and\ remote\ CIDR[%s]\ are\ overlaped = 本地路由的CIDR[{0}]和远端CIDR存在覆盖 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:305 +# args: msg.getVmInstanceUuid(),msg.getImageUuid() +instance[uuid\:%s]\ cannot\ be\ changed\ image\ to\ image[uuid\:%s] = 无法将实例[uuid:{0}]的镜像更改为镜像[uuid:{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:110 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:314 # args: -all\ networks\ in\ same\ IPsecConnection\ should\ be\ same\ type = 在相同的IPsec连接中的所有连接应该是相同类型 +either\ uuid\ or\ account\ or\ password\ must\ be\ set = uuid或者账户或者密码需要被设置 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:116 -# args: L3NetworkConstant.L3_BASIC_NETWORK_TYPE -IPsecConnection\ can\ ONLY\ have\ 1\ network\ for\ %s = IPsec连接只能有一个网络服务 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:327 +# args: msg.getDirection() +direction\ must\ be\ set\ in\ (in,\ out),\ but\ was\ %s = 方向必须设置在(in, out),但是输入的是{0} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:127 -# args: l3Uuid -L3Network\ [uuid\:\ %s]\ has\ not\ been\ attached\ to\ vpc\ router = 三层网络[uuid:{0}]还没有绑定VPC路由 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:333 +# args: +Monitor\ number\ must\ be\ 1\ or\ 2\ or\ 4. = 监听器数量必须是1、2或4 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:133 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:341 # args: -all\ networks\ in\ same\ IPsecConnection\ must\ be\ attached\ to\ same\ VPC\ router = 在相同的IPsec连接中的所有网络必须绑定在相同的VPC路由 +outboundBandwidth\ and\ inboundBandwidth\ must\ be\ set\ at\ lease\ one. = 上行带宽和下行带宽至少有一个需要被设置 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:150 -# args: tuples.get(0).get(0, String.class),tuples.get(0).get(1, String.class) -there\ already\ have\ ipsec\ connection[uuid\:%s,\ name\:%s]\ with\ the\ same\ vrouter\ and\ peerAddress = 这里已经有相同云路由和对端地址的IPsec连接[uuid:{0}, name:{1}] +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:350 +# args: +the\ nic\ can't\ apply\ Qos\ with\ the\ port\ mirror\ service\ at\ same\ time. = NIC不能同时对端口镜像服务应用QoS。 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:174 -# args: msg.getVipUuid(),useForList.toString() -the\ vip[uuid\:%s]\ has\ been\ used\ for\ %s = 虚拟IP[uuid:{0}]已经用作网络服务 {1} +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:359 +# args: msg.getUuid() +nic\ id\:\ %s\ does\ not\ exist... = 网卡id: {0}不存在 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:179 -# args: msg.getPeerAddress() -the\ peerAddress[%s]\ cannot\ be\ the\ same\ to\ the\ VIP\ address = 对端地址[{0}]不能和虚拟IP地址相同 +# at: src/main/java/org/zstack/compute/vm/VmMevocoApiInterceptor.java:370 +# args: +The\ 'uuids'\ parameter\ must\ belong\ to\ the\ VmInstanceVO\ or\ HostVO = “ uuids ”参数必须属于vminstancevo或hostvo -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:183 -# args: msg.getPeerAddress() -the\ peerAddress[%s]\ is\ not\ an\ IPv4\ address = 对端地址[{0}]不是一个IPv4地址 +# at: src/main/java/org/zstack/compute/vm/VmNicManagerImpl.java:261 +# args: state,VmInstanceState.Stopped +vm\ current\ state[%s],\ modify\ virtio\ requires\ the\ vm\ state[%s] = VM当前状态[{0}],修改virtio需要VM状态[{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:195 +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:111 # args: -the\ authKey\ cannot\ contain\ white\ space\ and\ special\ characters\ of\ '\"`\\ = 验证码不能包含空格和以下字符:'\"`\\ +wrong\ format\ of\ password\ strength\ config = 密码强度配置的格式错误 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:229 +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:114 # args: -must\ include\ l3\ networks\ in\ APIAttachL3NetworksToIPsecConnectionMsg = 参数中缺少三层网络的uuid +minimum\ can\ not\ be\ larger\ than\ maximum = 最小值不能大于最大值 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:236 -# args: l3NetworkUuid -L3\ network\ [%s]\ is\ not\ vpc\ network,\ can\ not\ be\ attached\ or\ detached\ to\ ipsec = 三层网络[{0}]不是VPC网络,不能绑定或解绑IPsec +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:74 +# args: minimum,maximum +password\ length\ must\ be\ [%s-%s] = 密码长度必须为[{0}-{1}] -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:217 -# args: l3NetworkUuid,msg.getIPsecConnectionUuid() -L3\ network\ [%s]\ can\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s]twice = 三层网络[{0}]不能绑定IPsec[uuid :{1}]两次 +# at: src/main/java/org/zstack/compute/vm/VmPasswordStrengthConfig.java:93 +# args: +password\ does\ not\ match\ numbers,\ uppercase\ and\ lowercase,\ and\ special\ character\ combinations = 密码与数字、大小写和特殊字符组合不匹配 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:240 -# args: l3NetworkUuid,msg.getIPsecConnectionUuid() -L3\ network\ [%s]\ is\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s] = 三层网络[{0}]不能绑定IPsec[uuid :{1}] +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:117 +# args: resourceUuid,vmInstanceUuid +missing\ parameter,\ resourceUuid\:\ %s,\ vmInstanceUuid\:\ %s\ is\ requested = 缺少参数,ResourceUuid:{0},请求vmInstanceUuid:{1} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:250 -# args: cidr,msg.getIPsecConnectionUuid() -Cidr\ [%s]\ is\ already\ in\ the\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = CIDR[{0}]已经在IPsec[uuid :{1}]的CIDR中 +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:153 +# args: vmInstanceUuid +missing\ parameter,\ vmInstanceUuid\:\ %s\ is\ requested = 缺少参数,请求了vmInstanceUuid:{0} -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:264 -# args: cidr,msg.getIPsecConnectionUuid() -Cidr\ [%s]\ is\ not\ in\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = CIDR[{0}]没有在IPsec[uuid :{1}]的CIDR中 +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:334 +# args: vmInstanceUuid +cannot\ find\ vm\ with\ uuid\:\ %s = 找不到uuid为{0}的云主机 -# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:272 -# args: msg.getUuid() -can\ not\ change\ state\ because\ ipsec\ [uuid\:%s]\ status\ is\ not\ ready = 不能修改IPsec的状态,因为IPsec的状态没有准备 +# at: src/main/java/org/zstack/compute/vm/devices/VmInstanceDeviceManagerImpl.java:338 +# args: resourceUuid +cannot\ find\ vm\ device\ with\ uuid\:\ %s = 找不到uuid为{0}的VM设备 -# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:132 -# args: msg.getIPsecConnectionUuid() -cannot\ find\ the\ IPsecconnection[uuid\:%s],\ it\ may\ have\ been\ deleted = 未找到IPsec连接[uuid:{0}],它可能会被删除了 +# at: src/main/java/org/zstack/compute/vm/numa/CommonVmNumaBasicFactory.java:38 +# args: vmUuid,hostUuid +vm[%s]\ start\ fail,because\ numa\ is\ enable\ but\ host[%s]\ not\ have\ numa\ node = VM[{0}]启动失败,因为已启用NUMA,但物理机[{1}]没有NUMA节点 -# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:336 -# args: Long.toString(range2.getStart()),Long.toString(range2.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),msg.getVipUuid() -Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ UDP = 当前的端口范围以UDP使用的端口范围冲突了 +# at: src/main/java/org/zstack/compute/vm/numa/CommonVmNumaBasicFactory.java:41 +# args: vmUuid +vm[%s]\ start\ fail,because\ numa\ is\ enable\ but\ cpu\ not\ pin = VM[{0}]启动失败,因为NUMA已启用,但CPU未pin -# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:373 -# args: cidr,l3Inv.getUuid(),uuid,rCidr -cidr[%s]\ of\ attached\ L3Network\ [uuid\:%s]\ is\ overlapped\ with\ ipsec\ [uuid\:%s]\ remote\ cidr[%s] = 已绑定在三层网络[uuid:{1}]的CIDR与IPSec[uuid:{2}]远程CIDR存在重叠 +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:45 +# args: +hot\ plug\ not\ close = 热插拔未关闭 -# at: src/main/java/org/zstack/ipsec/vyos/VyosCreateIPsecFlow.java:90 -# args: errorCode.getDescription() -create\ ipsec\ to\ ha\ route\ failed,\ because\ %s = +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:49 +# args: +vm\ cpu\ not\ all\ pinning = 云主机CPU未完全固定 -# at: src/main/java/org/zstack/ipsec/vyos/VyosDeleteIPsecFlow.java:80 -# args: errorCode.getDescription() -delete\ ipsec\ from\ ha\ group\ failed\ because\ %s = +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:53 +# args: entry.getKey().toString() +cpu[%s]\ not\ pin\ in\ a\ same\ host\ numa\ node = CPU[{0}]未固定在同一物理机NUMA节点中 -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:607 -# args: rsp.getError() -operation\ error,\ because\:%s = 操作错误,因为{0} +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaCpuPinInventory.java:57 +# args: vmUuid,String.join(VmNumaConstant.RULES_SEPARATOR, errors) +vm[%s]\ start\ fail,because\ numa\ is\ enable\ but\:\ %s = VM[{0}]启动失败,因为NUMA已启用,但:{1} -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:162 -# args: rcidr,cidr -the\ remoteCidr[%s]\ is\ overlaped\ with\ VirtualRouter\ interface\ cidr[%s] = +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaFilterFlow.java:52 +# args: +No\ host\ is\ available\ to\ create\ vm\ Instance.Because\ vNuma\ vms\ need\ to\ be\ created\ on\ hosts\ with\ same\ numa,\ but\ no\ hosts\ is\ available\ after\ filter\ primary\ vm's\ host = 没有物理机可用于创建VM实例。因为需要在具有相同NUMA的物理机上创建vNUMA VM,但在筛选主VM的物理机后没有可用的物理机 -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:279 +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaManagerImpl.java:92 # args: -vyos\ doesn't\ support\ aes-192\ as\ IkeEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos不支持aes-192作为密钥交换加密算法,可用选择为aes-128, aes-256, 3des +fail\ to\ set\ vm\ numa,\ incorrect\ input\ format,only\ accept\ true\ or\ false = 无法设置VM NUMA,输入格式不正确,仅接受TRUE或FALSE -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:285 +# at: src/main/java/org/zstack/compute/vm/numa/VmNumaUtils.java:46 +# args: word +invalid\ cpu\ set\ [%s] = CPU集[{0}]无效 + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:98 +# args: msg.getHostUuid(),refVO.getHostGroupUuid() +the\ host[uuid\:%s]\ already\ attached\ to\ host\ scheduling\ group[uuid\:%s] = 物理机[uuid:{0}]已连接到物理机调度组[uuid:{1}] + +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:107 # args: -vyos\ doesn't\ support\ aes-192\ as\ PolicyEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos不支持aes-192作为加密算法协议,可用选择为aes-128, aes-256, 3des +host\ clusterUuid\ is\ null = 物理机Clusteruuid为空 -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:291 -# args: msg.getIkeDhGroup() -vyos\ doesn't\ support\ %d\ as\ Ike\ DhGroup\ = vyos不支持[{0}]作为Ike DhGroup +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:111 +# args: +hosts\ that\ you\ can\ add\ to\ a\ host\ scheduling\ group\ must\ be\ enabled\ and\ connected\ to\ the\ MN. = 您可以添加到物理机调度组的物理机必须启用并连接到Mn。 -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:424 -# args: errorCode.getDescription() -sync\ to\ ha\ group\ failed,\ because\:%s = +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:117 +# args: hostVO.getUuid(),hostVO.getZoneUuid(),hostGroup.getUuid(),hostGroup.getZoneUuid() +unmatched\ zone\ detected,\ host[uuid\:\ %s,\ zone\ uuid\:\ %s]'s\ zone\ is\ different\ from\ host\ sheduling\ rule\ group[uuid\:\ %s,\ zone\ uuid\:\ %s] = 检测到不匹配的区域,物理机[uuid:{0},区域uuid:{1}]的区域不同于物理机计划规则组[UUId:{2},区域UUId:{3}] -# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:646 -# args: errorCode.getDescription() -apply\ to\ ha\ group\ failed,\ because\ %s = +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:132 +# args: msg.getVmUuid(),refVO.getVmGroupUuid() +vm[uuid\:%s]\ already\ attached\ to\ vm\ scheduling\ group[uuid\:%s] = 云主机[uuid:{0}]已连接到云主机调度组[uuid:{1}] -# at: src/main/java/org/zstack/kvm/KVMApiInterceptor.java:37 -# args: msg.getManagementIp() -there\ has\ been\ a\ kvm\ host\ having\ management\ ip[%s] = 已经存在一个拥有管理节点IP[{0}]的物理机 +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:145 +# args: vm.getUuid(),vm.getZoneUuid(),groupVO.getUuid(),groupVO.getZoneUuid() +unmatched\ zone\ detected,\ vm[uuid\:\ %s,\ zone\ uuid\:\ %s]'s\ zone\ is\ different\ from\ vm\ sheduling\ rule\ group[uuid\:\ %s,\ zone\ uuid\:\ %s] = 检测到不匹配的区域,VM[uuid:{0},区域uuid:{1}]的区域不同于VM调度规则组[UUId:{2},区域UUId:{3}] -# at: src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java:127 -# args: l2.getType() -KVMConnectExtensionForL2Network\ wont's\ support\ L2Network[type\:%s] = 物理机二层网络连接插件不支持二层网络[类型:{0}] +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:161 +# args: VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString(),vm.getState().toString() +vm\ can\ change\ its\ vm\ scheduling\ group\ only\ in\ state\ [%s,%s],\ but\ vm\ is\ in\ state\ [%s] = VM只能在状态[{0},{1}]下更改其VM调度组,但VM处于状态[{2}] -# at: src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java:68 -# args: rsp.getPort(),vm.getUuid() -unexpected\ VNC\ port\ number[%d]\ for\ VM\ [uuid\:%s] = +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:171 +# args: +cannot\ operate\ vpc\ vm\ scheduling\ group = 无法运行VPC云主机调度组 -# at: src/main/java/org/zstack/kvm/KVMHost.java:333 -# args: self.getUuid() -host[uuid\:%s]\ has\ been\ deleted = 物理机[uuid:{0}]已经被删除了 +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:209 +# args: +zoneUuid\ is\ not\ null = zoneUuid不为空 -# at: src/main/java/org/zstack/kvm/KVMHost.java:499 -# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() -unable\ to\ get\ first\ boot\ dev\ of\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleApiInterceptor.java:399 +# args: +the\ vm\ scheduling\ group[uuid\:%s]\ has\ already\ had\ a\ executed\ exclusive\ vm\ or\ affinitive\ vm\ scheduling\ policy\ attached.\ you\ cannot\ attach\ either\ of\ the\ two\ scheduling\ policies\ that\ require\ execution\ to\ the\ group\ again = VM调度组[uuid:{0}]已附加已执行的独占VM或关联VM调度策略。您不能再次将需要执行的两个计划策略中的任何一个附加到组 -# at: src/main/java/org/zstack/kvm/KVMHost.java:713 -# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),result.getExitErrorMessage() -unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = 无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3} +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleFilterFlow.java:132 +# args: +can\ not\ satisfied\ vm\ scheduling\ rule\ group\ conditions = 无法满足VM调度规则组条件 -# at: src/main/java/org/zstack/kvm/KVMHost.java:795 -# args: self.getUuid(),self.getStatus() -the\ host[uuid\:%s,\ status\:%s]\ is\ not\ Connected = 物理机[uuid:{0}, 状态:{1}]不是Connected状态 +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:158 +# args: self.getUuid(),host.getUuid(),vmUuid +vm\ scheduling\ group[uuid\:%s]\ reserve\ host\ [uuid\:%s]\ for\ vm\ [uuid\:\ %s]\ failed = 云主机调度组[uuid:{0}]为云主机[uuid:{2}]保留物理机[UuId:{1}]失败 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1121 -# args: volume.getUuid(),state -cannot\ do\ volume\ snapshot\ merge\ when\ vm[uuid\:%s]\ is\ in\ state\ of\ %s.\ The\ operation\ is\ only\ allowed\ when\ vm\ is\ Running\ or\ Stopped = 当云主机[uuid:{0}]处于{1}状态的时候不能做云盘快照合并。此操作只能在云主机处在Running和Stopped状态时进行 +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:392 +# args: vmInv.getUuid(),hostUuid,refVO.getVmGroupUuid() +vm[uuid\:%s]\ is\ now\ running\ on\ host[uuid\:%s],which\ does\ not\ comply\ with\ the\ scheduling\ rule\ associated\ with\ vm\ scheduling\ group[uuid\:%s]. = 云主机[uuid:{0}]现在正在物理机[uuid:{1}]上运行,该物理机不符合与云主机调度组[uuid:{2}]关联的调度规则。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1128 -# args: KVMConstant.MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION,libvirtVersion -live\ volume\ snapshot\ merge\ needs\ libvirt\ version\ greater\ than\ %s,\ current\ libvirt\ version\ is\ %s.\ Please\ stop\ vm\ and\ redo\ the\ operation\ or\ detach\ the\ volume\ if\ it's\ data\ volume = 实时云盘快照合并需要libvirt版本高于{0},现在libvirt版本为{1}。请停止云主机后重试或卸载云盘(仅当为数据云盘时) +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:402 +# args: msg.getVmGroupUuid() +hostGroup[uuid\:%s]\ is\ no\ host = 物理机组[uuid:{0}]不是物理机 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1217 -# args: msg.getVmUuid(),vmState -vm[uuid\:%s]\ is\ not\ Running\ or\ Stopped,\ current\ state[%s] = 云主机[uuid:{0}]未处在Running或Stopped状态, 现在状态为[{1}] +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:407 +# args: msg.getVmUuid(),hostUuid,VMSchedulingRuleType.AFFINITY.toString(),msg.getVmGroupUuid() +vm[uuid\:%s]\ is\ now\ running\ on\ host[uuid\:%s],\ which\ does\ not\ comply\ with\ the\ scheduling\ rule[%s]\ associated\ with\ vm\ scheduling\ group[uuid\:%s]. = 云主机[uuid:{0}]现在正在物理机[uuid:{1}]上运行,该物理机不符合与云主机调度组[uuid:{3}]关联的调度规则[{2}]。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1578 -# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() -failed\ to\ update\ nic[vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleGroupBase.java:414 +# args: msg.getVmUuid(),hostUuid,VMSchedulingRuleType.ANTIAFFINITY.toString(),msg.getVmGroupUuid() +vm[uuid\:%s]\ is\ now\ running\ on\ host[uuid\:%s],which\ does\ not\ comply\ with\ the\ scheduling\ rule[%s]\ associated\ with\ vm\ scheduling\ group[uuid\:%s]. = 云主机[uuid:{0}]现在正在物理机[uuid:{1}]上运行,该物理机不符合与云主机调度组[UuId:{3}]关联的调度规则[{2}]。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1625 -# args: msg.getNicInventory().getUuid(),msg.getNicInventory().getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() -failed\ to\ attach\ nic[uuid\:%s,\ vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = 在物理机[uuid:{2},IP:{3}]上加载网卡[uuid:{0},云主机:{1}]失败,因为:{4} +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java:82 +# args: msg.getHostGroupUuid() +cannot\ find\ the\ host\ scheduling\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到物理机调度组[uuid:{0}],它可能已被删除 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1672 -# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() -failed\ to\ detach\ data\ volume[uuid\:%s,\ installPath\:%s]\ from\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]卸载数据云盘[uuid:{0}, installPath:{1}],因为: {6} +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java:95 +# args: msg.getVmSchedulingRuleUuid() +cannot\ find\ the\ vm\ scheduling\ rule[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到VM计划规则[uuid:{0}],它可能已被删除 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1759 -# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() -failed\ to\ attach\ data\ volume[uuid\:%s,\ installPath\:%s]\ to\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]挂载数据云盘[uuid:{0}, installPath:{1}],因为: {6} +# at: src/main/java/org/zstack/compute/vmscheduling/VmSchedulingRuleManagerImpl.java:108 +# args: msg.getVmSchedulingRuleGroupUuid() +cannot\ find\ the\ vm\ scheduling\ group[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到VM调度组[uuid:{0}],它可能已被删除 -# at: src/main/java/org/zstack/kvm/KVMHost.java:1799 -# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() -failed\ to\ destroy\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在物理机[uuid:{2}, ip:{3}]上删除云主机[uuid:{0} name:{1}],原因: {4} +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:86 +# args: msg.getAllocatorStrategy() +unsupported\ host\ allocation\ strategy[%s] = 不被支持的物理机分配策略[{0}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:1928 -# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() -failed\ to\ stop\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 在物理机[uuid:{2}, ip:{3}]上停止云主机[uuid:{0} 名称:{1}]失败,因为:{4} +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:72 +# args: msg.getType() +unsupported\ instance\ offering\ type[%s] = 不被支持的计算规格类型[{0}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:2015 -# args: msg.getHostUuid(),ret.getError() -Host[%s]\ update\ spice\ channel\ config\ faild,\ because\ %s = +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:76 +# args: msg.getCpuNum() +cpu\ num[%s]\ is\ less\ than\ 1 = cpu数量[{0}]少于1 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2414 -# args: msg.getPhysicalInterface(),context.getInventory().getUuid(),context.getInventory().getManagementIp() -failed\ to\ check\ physical\ network\ interfaces[names\ \:\ %s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s] = +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:80 +# args: msg.getMemorySize() +memory\ size[%s\ bytes]\ is\ less\ than\ 16M,\ no\ modern\ operating\ system\ is\ likely\ able\ to\ boot\ with\ such\ small\ memory\ size = 内存大小[{0} bytes]少于16M,没有一个现代操作系统能够在如此小的内存里被引导 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2477 -# args: self.getUuid(),ret.getHostUuid() -detected\ abnormal\ status[host\ uuid\ change,\ expected\:\ %s\ but\:\ %s]\ of\ kvmagent,it's\ mainly\ caused\ by\ kvmagent\ restarts\ behind\ zstack\ management\ server.\ Report\ this\ to\ ping\ task,\ it\ will\ issue\ a\ reconnect\ soon = 监测到kvmagent异常的状态[host uuid改变,期望: {0}, 实际: {1}], 这很有可能是kvmagent重启导致的, 报告这个情况给ping, 它会触发重连 +# at: src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java:92 +# args: msg.getAllocationStrategy() +unsupported\ primary\ storage\ allocation\ strategy[%s] = 不被支持的主存储分配策略[{0}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:2602 -# args: self.getUuid(),self.getManagementIp(),connectPath,rsp.getError() -unable\ to\ connect\ to\ kvm\ host[uuid\:%s,\ ip\:%s,\ url\:%s],\ because\ %s = 连接物理机[uuid:{0}, ip:{1},url:{2}]失败,因为:{3} +# at: src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java:1043 +# args: resourceUuid +Already\ have\ one\ userdata\ systemTag\ for\ instanceOffering[uuid\:\ %s]. = 实例[uuid:{0}]已有一个用户数据系统标记。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2660 +# at: src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java:1108 # args: -host\ can\ not\ access\ any\ primary\ storage,\ please\ check\ network = 物理机无法访问任何主存储,请检查网络 +Shouldn't\ be\ more\ than\ one\ systemTag\ for\ one\ instanceOffering. = 对于一个实例提供,不应超过一个系统标记。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2836 -# args: getSelf().getPort(),KVMGlobalConfig.TEST_SSH_PORT_ON_OPEN_TIMEOUT.value(Long.class) -the\ host'\ ssh\ port[%s]\ not\ open\ after\ %s\ seconds,\ connect\ timeout = 物理机的ssh端口[{0}]在{1}秒后仍未开启,连接超时 +# at: src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java:1085 +# args: resourceUuid +Already\ have\ one\ userdata\ systemTag\ for\ diskOffering[uuid\:\ %s]. = DiskOffering[uuid:{0}]已有一个UserData系统标记。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2891 -# args: checkList -failed\ to\ ping\ all\ DNS/IP\ in\ %s;\ please\ check\ /etc/resolv.conf\ to\ make\ sure\ your\ host\ is\ able\ to\ reach\ public\ internet = 在{0}中的所有DNS/IP都ping失败了,请检查 /etc/resolv.conf 来确保你的主机能连接到公网 +# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:104 +# args: +the\ console\ agent\ is\ not\ connected;\ it's\ mostly\ like\ the\ management\ node\ just\ starts,\ please\ wait\ for\ the\ console\ agent\ connected,\ or\ you\ can\ reconnect\ it\ manually\ if\ disconnected\ for\ a\ long\ time. = 控制台代理失联,很有可能管理节点刚刚启动,请等待控制台代理的连接,如果长时间没有连上可以尝试手动重连控制台代理。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2889 -# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() -unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:\ %d,\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = 无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3} +# at: src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java:125 +# args: vm.getUuid() +cannot\ find\ host\ IP\ of\ the\ vm[uuid\:%s],\ is\ the\ vm\ running??? = 无法找到vm[uuid:{0}]的物理机IP,请确认该vm是否在运行??? -# at: src/main/java/org/zstack/kvm/KVMHost.java:2917 -# args: self.getManagementIp(),restf.getHostName(),ret.getStderr(),ret.getExitErrorMessage() -the\ KVM\ host[ip\:%s]\ cannot\ access\ the\ management\ node's\ callback\ url.\ It\ seems\ that\ the\ KVM\ host\ cannot\ reach\ the\ management\ IP[%s].\ %s\ %s = 物理机[ip:{0}] 不能连接到管理节点 。 看起来是这个物理机无法到达管理节点的IP [{1}]. {2} {3} +# at: src/main/java/org/zstack/console/ConsoleApiInterceptor.java:49 +# args: msg.getVmInstanceUuid(),state +Console\ is\ only\ available\ when\ the\ VM[uuid\:%s]\ is\ Running\ or\ Crashed,\ but\ the\ current\ state\ is\ %s = 控制台仅在VM[uuid:{0}]正在运行或崩溃时可用,但当前状态为{1} -# at: src/main/java/org/zstack/kvm/KVMHost.java:2914 -# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() -unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d]\ to\ check\ the\ management\ node\ connectivity,please\ check\ if\ username/password\ is\ wrong;\ %s = 不能连接到物理机[ip:{0}, username:{1}, sshPort:{2}] 去检查与管理节点是否连通 ,请检查您的用户名或者密码是否有误; {3} +# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:133 +# args: uri.toString() +establish\ VNC\:\ unexpected\ uri\:\ %s = 建立VNC:意外的URI:{0} -# at: src/main/java/org/zstack/kvm/KVMHost.java:3123 -# args: -cannot\ find\ either\ 'vmx'\ or\ 'svm'\ in\ /proc/cpuinfo,\ please\ make\ sure\ you\ have\ enabled\ virtualization\ in\ your\ BIOS\ setting = 不能发现以下任意一个 'vmx' or 'svm' 在路径 /proc/cpuinfo 里, 请检查你是否在你的BIOS设置里开启了virtualization选项 +# at: src/main/java/org/zstack/console/ConsoleProxyBase.java:198 +# args: ret.getError() +unable\ to\ check\ console\ proxy\ availability,\ because\ %s = 无法检查控制台代理是否可用,因为{0} -# at: src/main/java/org/zstack/kvm/KVMHost.java:2748 -# args: self.getUuid(),self.getClusterUuid() -host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ qemu/libvirt\ version\ does\ not\ match = 物理机[uuid:{0}]不能添加到集群[uuid:{1}]中,因为qemu/libvirt不匹配 +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:189 +# args: +Ansible\ private\ key\ not\ found. = 找不到Ansible私钥。 -# at: src/main/java/org/zstack/kvm/KVMHost.java:2769 -# args: self.getUuid(),self.getClusterUuid() -host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ cpu\ model\ name\ does\ not\ match = 物理机[uuid:{0}]无法被添加到集群[uuid:{1}]因为cpu型号不一致 +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:387 +# args: uuid +invalid\ management\ node\ uuid[%s] = 非法的管理节点uuid[{0}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:3402 +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:520 # args: -host\ is\ not\ in\ the\ connected\ status,\ cannot\ update\ os = 物理机当前并不是已连接状态,不能升级操作系统 +failed\ to\ configure\ consoleProxyOverriddenIp[code\:%d]\ or\ consoleProxyPort[code\:%d] = 无法配置ConsoleProxyOverriddeNip[代码:{0}]或ConsoleProxyPort[代码:{1}] -# at: src/main/java/org/zstack/kvm/KVMHost.java:3400 +# at: src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java:543 # args: -host\ is\ in\ the\ premaintenance\ state,\ cannot\ update\ os = 物理机正处于预维护状态,不能升级操作系统 - -# at: src/main/java/org/zstack/kvm/KVMHost.java:4331 -# args: hostUuid,errorCode -fail\ to\ check\ file\ %s\ on\ host[uuid\:%s] = 检查物理机[uuid:{1}]上的文件{0}失败 +failed\ to\ reconnect\ console\ proxy = 重连控制台代理失败 -# at: src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java:63 +# at: src/main/java/org/zstack/core/ansible/AnsibleRunner.java:426 # args: -cannot\ adapt\ version\ for\ the\ bellow\ rpm\:\ livirt\ /\ qemu\ /\ cpumodel = 源和目的之间的以下组件版本不兼容:livirt、qemu、cpumodel - -# at: src/main/java/org/zstack/kvm/KVMHostCapacityExtension.java:57 -# args: host.getUuid(),rsp.getTotalMemory(),reservedSize -The\ host[uuid\:%s]'s\ available\ memory\ capacity[%s]\ is\ lower\ than\ the\ reserved\ capacity[%s] = 物理机[uuid:{0}]的可用内存[{1}]少于保留内存[{2}] +User\ name\ or\ password\ or\ port\ number\ may\ be\ problematic = 用户名、密码或者端口可能是错误的 -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:111 -# args: e.getMessage() -fail\ to\ load\ host\ info\ from\ file.\ because\n%s = +# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:106 +# args: srcFolder,srcRes.getStdout(),srcRes.getStderr() +cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s].\nstdout\:%s\nstderr\:%s = 无法检查文件夹[{0}]下文件的md5sum.\nstdout:{1}\nstderr:{2} -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:329 -# args: str.toString() -there\ are\ still\ hosts\ not\ have\ the\ same\ cpu\ model,\ details\:\ %s = 仍存在host有不同的cpu模型,详细信息:{0} +# at: src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java:121 +# args: dstFolder,hostname,dstRes.getStdout(),dstRes.getStderr() +cannot\ check\ md5sum\ of\ files\ in\ the\ folder[%s]\ on\ the\ host[ip\:%s].\nstdout\:%s\nstderr\:%s = 无法检查物理机[ip:{1}]的文件夹[{0}]下文件的md5sum.\nstdout:{2}\nstderr:{3} -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:343 -# args: KVMSystemTags.VM_PREDEFINED_PCI_BRIDGE_NUM_TOKEN -pci\ bridge\ need\ a\ value\ greater\ than\ 0\ and\ lower\ than\ 32 = +# at: src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java:684 +# args: errMsg +message\ is\ not\ in\ corrected\ JSON\ mediaType,\ %s = 消息是错误的JSON格式,{0} -# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:364 -# args: hostUuid -host[uuid\:%s]\ does\ not\ have\ cpu\ model\ information,\ you\ can\ reconnect\ the\ host\ to\ fix\ it = 物理机[uuid:{0}]无cpu模型信息,你可以尝试重连来解决这个问题 +# at: src/main/java/org/zstack/core/cloudbus/EventFacadeImpl.java:69 +# args: EventFacade.WEBHOOK_TYPE +for\ webhooks\ with\ type[%s],\ the\ field\ opaque\ cannot\ be\ null = 对于[{0}]类型的webhooks,opaque字段不能为null -# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:69 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 在物理机[uuid:{3}]上为L2网络[uuid:{1}, type:{2}]创建网桥[{0}]失败,原因: {4} +# at: src/main/java/org/zstack/core/config/GlobalConfig.java:430 +# args: +do\ not\ allow\ skip\ verification = 不允许跳过验证 -# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:119 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getName(),hostUuid,rsp.getError() -failed\ to\ check\ bridge[%s]\ for\ l2NoVlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = 在L2网络[uuid:{1}中检查网桥[{0}]失败,名字为[{2}]在物理机t[uuid: {3}]上, {4} +# at: src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java:118 +# args: msg.getCategory(),msg.getName() +Unable\ to\ find\ GlobalConfig[category\:\ %s,\ name\:\ %s] = 无法找到全局变量[category:{0}, name:{1}] -# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:66 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vlan.getVlan(),hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 创建L2网络[uuid:{1}中的网桥[{0}]失败 , 类型为: {2}, vlan:{3}] 在物理机[uuid:{4}]上, 原因: {5} +# at: src/main/java/org/zstack/core/debug/DebugManagerImpl.java:93 +# args: +taskInfo\ was\ not\ found = 未找到TaskInfo -# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:117 -# args: cmd.getBridgeName(),l2vlan.getUuid(),l2vlan.getName(),hostUuid,rsp.getError() -failed\ to\ check\ bridge[%s]\ for\ l2VlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 检查在物理机[uuid:{3}]上L2网络[uuid:{1}, name:{2}]中的网桥[{0}]失败, {4} +# at: src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java:204 +# args: encrypt.error +Encryption\ error\ \:\ %s = 加密错误:{0} -# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:111 -# args: hto.getHostUuid(),rsp.getError() -failed\ to\ apply\ rules\ of\ security\ group\ rules\ to\ kvm\ host[uuid\:%s],\ because\ %s = 不能应用安全组规则在物理机t[uuid:{0}]上, 因为 {1} +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:71 +# args: +non\ file\ or\ jsoncontent\ input = 非文件或JSON内容输入 -# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:154 -# args: hostUuid,rsp.getError() -failed\ to\ check\ default\ rules\ of\ security\ group\ on\ kvm\ host[uuid\:%s],\ because\ %s = 在host[uuid:{0}]上检查默认安全组规则失败 +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:76 +# args: +file\ or\ jsoncontent\ cannot\ both\ nonempty = 文件或JSONContent不能同时为非空 -# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:162 -# args: host.getUuid(),host.getManagementIp(),ret.getError() -unable\ to\ do\ vm\ sync\ on\ host[uuid\:%s,\ ip\:%s]\ because\ %s = 不能在物理机[uuid:{0}, ip:{1}]上执行云主机状态同步操作,因为{2} +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:108 +# args: e.getMessage() +Unable\ to\ scan\ folder\:\ %s = 无法扫描文件夹:{0} -# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:191 -# args: vmUuid -The\ vm[%s]\ state\ is\ in\ shutdown\ for\ a\ long\ time,\ check\ whether\ the\ vm\ is\ normal = +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:112 +# args: filename +%s\ is\ not\ existed\ or\ is\ empty\ folder = {0}不存在或为空文件夹 -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:67 +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:249 # args: -unsupported\ LDAP/AD\ server\ scope = +elaboration\ code\ must\ be\ number! = 精化代码必须为数字! -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:117 -# args: type,LdapConstant.OpenLdap.TYPE,LdapConstant.WindowsAD.TYPE -Wrong\ LdapServerType[%s],\ valid\ values\:\ [%,%s] = 错误的LDAP服务类型[{0}],有效的值: [%,{1}] +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:318 +# args: returnValue.get(0).getContent(),returnValue.get(0).getReason() +%s\:\ %s = {0}: {1} -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:142 +# at: src/main/java/org/zstack/core/errorcode/ElaborationManagerImpl.java:415 # args: -Cannot\ connect\ to\ LDAP/AD\ server,\ Invalid\ Credentials,\ please\ checkout\ User\ DN\ and\ password = +input\ args\ 'regex'\ or\ 'category'\ must\ be\ set = 必须设置输入参数“ regex ”或“ category ” -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:145 -# args: -Cannot\ connect\ to\ LDAP/AD\ server,\ communication\ false,\ please\ checkout\ IP,\ port\ and\ Base\ DN = +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:32 +# args: service.getName() +service[%s]\ has\ been\ registered = 服务(service)[{0}]已经被注册 -# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:148 -# args: e.toString() -Cannot\ connect\ to\ LDAP/AD\ server,\ %s = 不能连接LDAP服务,{0} +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:93 +# args: msg.getName() +service[%s]\ is\ not\ registered = 服务[{0}]未注册 -# at: src/main/java/org/zstack/ldap/LdapManagerImpl.java:181 -# args: vo.getAccountUuid() -Account[uuid\:%s]\ Not\ Found!!! = +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:99 +# args: msg.getName() +service[%s]\ does\ not\ support\ reload\ config = 服务[{0}]不支持重新加载配置 -# at: src/main/java/org/zstack/ldap/LdapUtil.java:456 -# args: filter,errorMessage -query\ ldap\ entry[filter\:\ %s]\ fail,\ because\ %s = +# at: src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java:105 +# args: msg.getName() +service[%s]\ is\ not\ running = 服务[{0}]未运行 -# at: src/main/java/org/zstack/ldap/externalSearch/AggregateSearch.java:52 -# args: e.toString() -query\ ldap\ entry\ fail,\ %s = 查询LDAP条目失败,{0} +# at: src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java:315 +# args: vo.getUuid(),vo.getName() +cannot\ trigger\ a\ finished\ GC\ job[uuid\:%s,\ name\:%s] = 无法触发一个完成过的GC任务 -# at: src/main/java/org/zstack/license/LicenseChecker.java:129 -# args: -Parse\ license\ error,\n1.\ check\ your\ private\ key\ and\ application\ code\ is\ correct\n2.\ check\ your\ license\ is\ not\ corrupted\n3.\ use\ zstack-ctl\ clear_license\ to\ clear\ your\ licenses\ and\ try\ to\ reinstall\n = +# at: src/main/java/org/zstack/core/progress/ProgressApiInterceptor.java:38 +# args: msg.getApiId() +parameter\ apiId[%s]\ is\ not\ a\ valid\ uuid. = 参数apiId[{0}]不是一个有效的uuid -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:220 -# args: e.getMessage() -Decode\ fail\ because\ %s = 解码失败,因为{0} +# at: src/main/java/org/zstack/core/rest/RESTFacadeImpl.java:656 +# args: url,finalTimeout +unable\ to\ echo\ %s\ in\ %sms = 无法在{1}ms内返回{0} -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:217 -# args: bytes.length -Unexpected\ decoded\ license\ file\ length\:\ %d = +# at: src/main/java/org/zstack/core/retry/Retry.java:103 +# args: __name__,times,interval +an\ operation[%s]\ fails\ after\ retrying\ %s\ times\ with\ the\ interval\ %s\ seconds = 在重试{1}次间隔时间为{2}后操作[{0}]失败 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:846 -# args: -Licensed\ VM\ number\ overrun = VM数量超过云主机授权上限 +# at: src/main/java/org/zstack/core/salt/SaltRunner.java:297 +# args: stateName,targetIp,retry +failed\ to\ run\ salt\ state[%s]\ on\ system[%s],\ failed\ after\ %s\ retries = 重试{2}次之后,在系统[{1}]上运行加盐状态[{0}]失败 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1144 -# args: addonLicBy.first(),addonLicBy.second() -unexpected\ license\ policy\:\ %d\ %s. = +# at: src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java:84 +# args: targetIp +scp\ is\ not\ found\ on\ system[%s],\ unable\ to\ setup\ salt = 在系统[{0}]上找不到SCP,无法设置销售 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1195 -# args: info.getProdInfo(),addonLicBy.first(),addonLicBy.second() -Addon[%s]\ licensed\ %d\ %s,\ but\ platform\ is\ licensed\ with\ VM\ number = +# at: src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java:76 +# args: ApiTimeoutGlobalProperty.MINIMAL_TIMEOUT +api\ timeout\ cannot\ be\ set\ smaller\ than\ %s = API超时不能设置为小于{0} -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1191 -# args: info.getProdInfo(),addonLicBy.first(),addonLicBy.second() -Addon[%s]\ licensed\ %d\ %s,\ but\ platform\ is\ licensed\ with\ host = +# at: src/main/java/org/zstack/core/webhook/WebhookApiInterceptor.java:28 +# args: url +Invalid\ url[%s] = 无效的URL[{0}] -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1187 -# args: info.getProdInfo(),addonLicBy.first(),addonLicBy.second() -Addon[%s]\ licensed\ %d\ %s,\ but\ platform\ is\ licensed\ with\ CPU\ socket = +# at: src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java:72 +# args: +the\ identity\ authentication\ does\ not\ specify\ the\ resource\ pool\ to\ provide\ the\ service = 身份认证未指定提供服务的资源池 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1318 -# args: AddOnLicenseModule -issue\ date\ of\ addon\ license\ is\ earlier\ than\ the\ existing\ license\ issue\ date = 新上传的模块许可证签发日期早于已存在的许可证 +# at: src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java:83 +# args: setting.resourcePoolType,model +wrong\ secret\ resource\ pool\ model,\ expect\ %s,\ actual\ %s = 机密资源池模型错误,应为{0},实际为{1} -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1323 -# args: -issue\ date\ of\ platform\ license\ is\ earlier\ than\ the\ existing\ license\ issue\ date = 新上传的许可证签发日期早于已存在的许可证 +# at: src/main/java/org/zstack/crypto/auth/AbstractCryptoAuthenticationFacade.java:81 +# args: resourceUuid +failed\ to\ find\ model\ for\ secretResourcePool\ [%s] = 找不到SecretResourcePool[{0}]的模型 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1360 +# at: src/main/java/org/zstack/crypto/auth/CryptoAuthenticationHelper.java:121 # args: -Add-on\ license\ is\ not\ supported\ when\ license\ type\ is\ Community = 社区版许可证不支持添加附加模块 +failed\ to\ find\ certificate\ info = 找不到证书信息 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1368 -# args: -Add-on\ license\ is\ not\ supported\ when\ license\ type\ is\ Basic\ or\ Standard = 基础版和标准版许可证不支持添加附加模块 +# at: src/main/java/org/zstack/crypto/auth/CryptoEncryptionParamParser.java:57 +# args: plainText,e.getMessage() +failed\ to\ parse\ plain\ text\ in\ encryption\ param\ to\ json\ object\:\ %s,\ %s = 无法将加密参数中的纯文本解析为JSON对象:{0},{1} -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1682 +# at: src/main/java/org/zstack/crypto/auth/UKeyCryptoAuthenticationFacade.java:73 # args: -License\ expired = +operation\ not\ supported = 不支持的操作 -# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:249 -# args: struct.getType() -No\ factory\ found\ for\ type\:%s = +# at: src/main/java/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:200 +# args: userUuid +user[uuid\=%s]\ not\ found = 找不到用户[uuid={0}] -# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:464 -# args: msg.getType() -Unknown\ log\ configuration\ type\ %s = +# at: src/main/java/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:204 +# args: +certificate\ uuid\ is\ empty\ and\ UKey\ system\ tag\ does\ not\ exist = 证书uuid为空,且UKEY系统标记不存在 -# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:60 -# args: lstruct.getAppenderType() -No\ factory\ found\ for\ log4j2\ appender\ type\:%s. = +# at: src/main/java/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:217 +# args: msg.getCertificateUuid() +certificate[uuid\=%s]\ not\ found = 未找到证书[uuid={0}] -# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:134 -# args: lstruct.getAppenderType() -Unknown\ log4j2\ appender\ type\ %s = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java:47 +# args: msg.getResourceType() +check\ batch\ data\ integrity\ fail,\ unsupported\ resourceType\:\ %s = 检查批处理数据完整性失败,不支持的资源类型:{0} -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:44 -# args: -facility\ can\ not\ be\ null = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java:57 +# args: msg.getResourceType() +add\ integrity\ resource\ fail,\ unsupported\ resourceType\:\ %s = 添加完整性资源失败,不支持的资源类型:{0} -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:48 -# args: configuration.facility -invalid\ facility\ %s = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoInterceptor.java:65 +# args: msg.getEncryptType() +start\ data\ protection\ encryptType[%s]\ is\ error = 启动数据保护加密类型[{0}]出错 -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:52 -# args: -hostname\ can\ not\ be\ null = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:240 +# args: inventory.getUuid() +the\ snapshot[uuid\:%s]\ is\ not\ encrypted = 快照[uuid:{0}]未加密 -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:56 -# args: -port\ can\ not\ be\ null = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:249 +# args: inventory.getUuid() +verify\ volume\ snapshot[%s]\ consistency\ failed = 验证卷快照[{0}]一致性失败 -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:60 -# args: -protocol\ can\ not\ be\ null = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:311 +# args: inventory.getId(),exception.getMessage() +encryption\ image\ cache[id\:%s]\ error\:\ %s = 加密镜像缓存[ID:{0}]错误:{1} -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1456 -# args: Platform.getManagementServerIp() -MN\ HA\ environment,\ but\ only\ updated\ license\ for\ %s = 管理节点有多个,但是仅更新了节点{0}的许可证 +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:375 +# args: inventory.getId() +the\ image\ cache[id\:%s]\ is\ not\ encrypted = 镜像缓存[ID:{0}]未加密 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1454 -# args: Platform.getManagementServerIp() -Multiple\ MN\ exists\ but\ only\ supplied\ licenses\ for\ %s = 管理节点有多个,但是仅提供了节点{0}的许可证 +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:388 +# args: inventory.getId() +verify\ image\ cache[%s]\ consistency\ failed = 验证镜像缓存[{0}]一致性失败 -# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1569 -# args: -unexpected\ license\ file = 许可证错误 +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:668 +# args: msg.getNodeType(),msg.getPath() +nodeType\ %s\ integrity\ file[path\:%s]\ already\ exists = NodeType{0}完整性文件[路径:{1}]已存在 -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:66 -# args: configuration.protocol -unsupported\ protocol\ %s = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:682 +# args: msg.getNodeType() +invalid\ nodeType[%s] = 节点类型[{0}]无效 -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:80 -# args: configuration.hostname,configuration.port -syslog\ server[address\:\ %s\:%s]\ is\ not\ available = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:694 +# args: msg.getNodeType(),msg.getPath() +filed\ to\ add\ integrity\ file[%s.%s],\ it's\ a\ directory\ now. = 已归档以添加完整性文件[{0}.{1}],它现在是一个目录。 -# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:72 -# args: configuration.hostname -syslog\ server[address\:\ %s]\ is\ not\ available = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:699 +# args: msg.getNodeType(),msg.getPath() +integrity\ file[%s.%s]\ is\ not\ exists = 完整性文件[{0}.{1}]不存在 -# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:45 -# args: -There\ is\ no\ LDAP/AD\ server\ in\ the\ system,\ Please\ add\ a\ LDAP/AD\ server\ first. = 在系统中没有LDAP服务,请先添加一个LDAP服务 +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:716 +# args: msg.getNodeUuid() +host\ %s\ is\ not\ exists = 物理机{0}不存在 -# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:39 -# args: msg.getLdapUid(),msg.getVirtualIDUuid() -Can\ not\ bind\ this\ ldap\ uid\ %s\ to\ virtual\ id\ [uuid\:%s] = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:724 +# args: res.getStderr() +Shell\ fail,\ because\ %s = Shell失败,原因是{0} -# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:53 -# args: -This\ uid\ is\ already\ used = +# at: src/main/java/org/zstack/crypto/datacrypto/CryptoManagerImpl.java:747 +# args: msg.getNodeType(),msg.getPath(),exception.getMessage() +add\ integrity\ file[%s.%s]\ fail,\ because\ %s = 添加完整性文件[{0}.{1}]失败,原因是{2} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:230 +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/EncryptColumnIntegrityFactory.java:141 # args: -ZStack\ is\ loading\ ldap\ organizations\ from\ DB\ now,\ can\ not\ execute\ sync\ operation = +unsupported\ operation\ for\ EncryptColumnIntegrityFactory = 不支持对EncryptColumnIntegrityFactory的操作 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:352 -# args: e.getMessage() -Failed\ to\ sync\ ldap\ entry[],\ because\ %s = +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java:138 +# args: encrypt.error +virtualID\ attribute\ encryption\ error,\ because\:%s = VirtualID属性加密错误,原因:{0} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:975 -# args: reply.getError().getReadableDetails() -Failed\ to\ sync\ organizations,\ because\ %s = +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java:187 +# args: resourceUuid +IAM2VirtualIDAttributeVO\ %s\ does\ not\ exists = IAM2VirtualIDAttributeVO{0}不存在 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:923 -# args: -Failed\ to\ transform\ ldap\ entry\ to\ organization\ ndoe = +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/IAM2VirtualIDAttributeIntegrityFactory.java:194 +# args: encrypt.error +virtualID\ attribute\ check\ error,\ because\:%s = VirtualID属性检查错误,原因:{0} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:912 -# args: -failed\ to\ sync\ ldap\ organization = +# at: src/main/java/org/zstack/crypto/datacrypto/integrity/RolePolicyIntegrityFactory.java:115 +# args: encrypt.error +rolePolicy\ encryption\ error,\ because\:%s = RolePolicy加密错误,原因:{0} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1380 -# args: scope.toString() -Can\ not\ sync\ LDAP/AD\ server\ whose\ scope\ is\ not\ %s = +# at: src/main/java/org/zstack/crypto/datacrypto/smp/SMPCryptoBase.java:40 +# args: self.getUuid(),self.getName() +the\ shared\ mount\ point\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters = 共享装入点主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用物理机 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1503 -# args: uid -Failed\ to\ validate\ uid[%s],\ maybe\ it\ has\ been\ deleted = +# at: src/main/java/org/zstack/crypto/securitymachine/AttachVerifyPair.java:26 +# args: +originText\ or\ certificateText\ can\ not\ be\ null = 原始文本或证书文本不能为空 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1544 -# args: uid,reply.getError().getReadableDetails() -Failed\ to\ create\ iam2\ virtual\ id\ for\ uid[%s],\ because\ %s = +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:60 +# args: msg.getSecurityMachineUuid() +the\ security\ machine\ [%s]\ does\ not\ exist = 密码机[{0}]不存在 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1679 -# args: ldapUid -Failed\ to\ validate\ dn\ [%s],\ maybe\ it\ has\ been\ deleted = +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:86 +# args: msg.getManagementIp() +managementIp[%s]\ is\ not\ in\ IPV4\ format = ManagementIP[{0}]不是IPv4格式 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:92 +# args: msg.getName(),msg.getManagementIp(),error +failed\ to\ connect\ to\ the\ security\ machine\ %s[%s],\ because\ %s = 无法连接到密码机{0}[{1}],因为{2} -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2097 +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:112 +# args: msg.getSecurityMachineUuid() +after\ the\ crypto\ function\ is\ enabled,\ at\ least\ one\ security\ machine\ should\ be\ reserved\ in\ the\ corresponding\ resource\ pool = 启用加密功能后,应在相应的资源池中至少保留一台密码机 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:123 +# args: msg.getAlgType(),StringUtils.join(EncryptType.values(), ',') +invalid\ algType\ %s,\ supported\ types\:\ %s. = AlgType{0}无效,支持的类型:{1}。 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineApiInterceptor.java:127 +# args: poolForProtect +the\ resource\ pool[%s]\ specified\ by\ data\ protection\ does\ not\ exist = 数据保护指定的资源池[{0}]不存在 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java:145 # args: -invalid\ json\ format = +cannot\ be\ deleted.\ after\ the\ encryption\ function\ is\ enabled,\ the\ number\ of\ synced\ security\ machines\ in\ the\ resource\ pool\ that\ provides\ the\ service\ is\ at\ least\ 1 = 无法删除。启用加密功能后,提供该服务的资源池中同步的密码机至少为1台 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2108 +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java:444 # args: -name\ is\ mandatory\ field\ % = +securityMachine\ is\ disabled,\ failed\ to\ detect\ heartbeat = SecurityMachine已禁用,无法检测心跳 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2112 +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineBase.java:584 # args: -attribute\ is\ mandatory\ field\ % = +an\ other\ connect\ security\ machine\ task\ is\ running,\ cancel\ the\ new\ task\ and\ wait\ return = 其他连接密码机任务正在运行,请取消新任务并等待返回 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:183 +# args: data,algType +encrypt\ data[%s]\ or\ algType[%s]\ is\ null = 加密数据[{0}]或AlgType[{1}]为空 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2116 +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:165 +# args: resourceUuid +cannot\ find\ model\ for\ secretResourcePool\ [%s] = 找不到SecretResourcePool[{0}]的模型 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:105 +# args: poolForAuth +the\ crypto\ function\ is\ enabled\ but\ the\ resource\ pool[%s]\ for\ auto\ login\ is\ not\ set. = 已启用加密功能,但未设置用于自动登录的资源池[{0}]。 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:113 +# args: poolForProtect +the\ crypto\ function\ is\ enabled\ but\ the\ resource\ pool[%s]\ for\ data\ protect\ is\ not\ set. = 已启用加密功能,但未设置数据保护的资源池[{0}]。 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:122 +# args: state.toString() +the\ current\ state[%s]\ does\ not\ allow\ manual\ modification\ of\ the\ state = 当前状态[{0}]不允许手动修改状态 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:149 # args: -type\ is\ mandatory\ field\ % = +cannot\ disable\ all\ security\ machines\ when\ the\ crypto\ function\ is\ enabled = 启用加密功能时,无法禁用所有密码机 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2120 +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:159 # args: -optional\ is\ mandatory\ field\ % = +check\ whether\ the\ resource\ pool\ uuid\ is\ set\ for\ authentication = 检查是否为身份验证设置了资源池uuid -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2124 -# args: fieldNames -name\ should\ use\ values\ in\ %s = +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:202 +# args: algType +unknown\ encryptType[%s] = 未知的加密类型[{0}] -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2150 -# args: rule.getAttribute() -Invalid\ attribute.\ Attribute[%s]\ is\ required,\ but\ found\ there\ are\ some\ record\ not\ matched = +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:216 +# args: data,algType +decrypt\ data[%s]\ or\ algType[%s]\ is\ null = 解密数据[{0}]或AlgType[{1}]为空 -# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2101 -# args: -strategy\ is\ mandatory\ field\ % = +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineHelper.java:225 +# args: algType +invalid\ decrypt\ algType\:\ %s = 无效的解密AlgType:{0} -# at: src/main/java/org/zstack/loginControl/LoginControlApiInterceptor.java:40 -# args: e.getMessage() -Invalid\ rule\ expression,\ add\ access\ control\ rule\ fail\ because\:\ %s = +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java:280 +# args: msg.getManagementIp() +there\ has\ been\ a\ security\ machine\ having\ managementIp[%s] = 已存在具有ManagementIP[{0}]的密码机 -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:154 +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java:82 +# args: securityMachineType +no\ client\ for\ security\ machine[type\=%s] = 密码机[类型={0}]没有客户端 + +# at: src/main/java/org/zstack/crypto/securitymachine/SecurityMachineManagerImpl.java:101 +# args: securityMachineType +no\ security\ machine\ client\ factory\ for\ security\ machine[type\=%s] = 密码机[类型={0}]没有密码机客户端工厂 + +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:50 # args: -wrong\ format\ of\ password\ strength\ config = +there\ is\ no\ security\ machine\ that\ can\ be\ activated = 没有可以激活的密码机。 -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:143 -# args: key -unrecognized\ key\:\ %s = +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:54 +# args: msg.getType(),StringUtils.join(SecurityMachineKeyType.values(), ',') +invalid\ token\ type\ %s,\ only\ supports\ %s. = 令牌类型{0}无效,仅支持{1}。 -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:149 -# args: opt.get() -missing\ key\:value\ of\ %s = +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:68 +# args: msg.getSecretResourcePoolUuid() +the\ identity\ authentication\ function\ is\ enabled\ but\ the\ corresponding\ resource\ pool\ is\ not\ set,\ please\ re-enable\ the\ function\ and\ try\ again = 身份认证功能已启用,但未设置相应的资源池,请重新启用后再试 -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:158 +# at: src/main/java/org/zstack/crypto/securitymachine/secretresourcepool/SecretResourcePoolApiInterceptor.java:72 +# args: msg.getSecretResourcePoolUuid() +cannot\ delete\ the\ resource\ pool\ %s\ when\ in\ use = 无法删除正在使用的资源池{0} + +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java:237 # args: -minimum\ can\ not\ be\ larger\ than\ maximum = +generate\ certificate\ failed = 生成证书失败 -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:321 -# args: results.size() -Consult\ result\ expect\ to\ be\ 1,\ but\ actually\ %s = 查询结果期望是1,但是实际上是{0} +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java:134 +# args: rsp.getData() +flkSec\ securityMachine\ unhealthy\:\ %s = FlkSec SecurityMachine不正常:{0} -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:505 -# args: msg.getResourceName() -No\ available\ processor\ for\ %s = +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecClient.java:161 +# args: keyLabel,sm4EncryptResponse.result +keyLabel\ %s\ and\ encryptResult\ %s\ are\ inconsistent = KeyLabel{0}和EncryptResult{1}不一致 -# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:529 -# args: msg.getCaptchaUuid(),msg.getResourceName() -can\ not\ get\ suitable\ captcha\ with[uuid\:%s],\ related\ to\ resourceName[uuid\:%s] = 找不到和名称[uuid:{1}]对应的验证码[uuid:{0}] +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:168 +# args: vo.getUuid(),response.error +the\ connection\ to\ the\ security\ machine\ %s\ failed\ during\ the\ process\ of\ generating\ the\ test\ key\ because\ %s = 在生成测试密钥的过程中,与密码机{0}的连接失败,原因是{1} -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:69 -# args: msg.getJobName() -%s\ is\ not\ an\ API = {0}不是一个API +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:185 +# args: vo.getUuid(),dataProtectTokenRes.error +failed\ to\ generate\ dataProtect\ token\ for\ the\ security\ machine\ %s\ because\ %s = 无法为密码机{0}生成DataProtect令牌,因为{1} -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:127 -# args: -cannot\ cancel\ longjob\ that\ is\ succeeded = 不能取消已经成功的longjob +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:196 +# args: vo.getUuid(),hmacTokenTokenRes.error +failed\ to\ generate\ hmac\ token\ for\ the\ security\ machine\ %s\ because\ %s = 无法为密码机{0}生成HMAC令牌,因为{1} -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:130 -# args: -cannot\ cancel\ longjob\ that\ is\ failed = 不能取消已经失败的longjob +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecretResourcePoolBase.java:208 +# args: vo.getUuid(),encryptRes.error +failed\ to\ get\ encrypt\ result\ for\ the\ security\ machine\ %s\ because\ %s = 无法获取密码机{0}的加密结果,因为{1} -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:141 -# args: -delete\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = 只能删除已经成功、取消、失败的longjob +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecurityMachineBase.java:123 +# args: self.getManagementIp() +the\ security\ machine\ [%s]\ failed\ to\ manually\ detect\ synchronization,\ please\ confirm\ whether\ the\ security\ machine\ has\ synchronized\ the\ key! = 密码机[{0}]手动检测同步失败,请确认密码机是否已同步密钥! -# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:152 -# args: -rerun\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/flkSec/FlkSecSecurityMachineFactory.java:32 +# args: msg.getName(),vo.getModel() +security\ machine[uuid\:%s]\ model\ is\ not\ %s = 密码机[uuid:{0}]型号不是{1} -# at: src/main/java/org/zstack/longjob/LongJobFactoryImpl.java:31 -# args: jobName -%s\ has\ no\ corresponding\ longjob = {0}没有与之对应的longjob +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/haitai/HaiTaiSecretResourcePoolApiInterceptor.java:52 +# args: msg.getModel() +currently\ does\ not\ support\ the\ creation\ of\ %s\ resource\ pools = 当前不支持创建{0}资源池 -# at: src/main/java/org/zstack/mediator/ApiValidator.java:109 -# args: l3NetworkUuid,vmNicVO.getL3NetworkUuid() -unable\ to\ attach\ a\ L3\ network.\ The\ cidr\ of\ l3[%s]\ to\ attach\ overlapped\ with\ l3[%s]\ already\ attached\ to\ vm = 不能绑定这个三层网络。这个虚拟机上已经绑定的三层网络[{1}]和这个三层网络[{0}]的CIDR存在重叠 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/haitai/HaiTaiSecretResourcePoolFactory.java:33 +# args: msg.getResourceUuid(),vo.getModel() +secretResourcePool[uuid\:%s]\ model\ is\ not\ %s = SecretResourcePool[uuid:{0}]模型不是{1} -# at: src/main/java/org/zstack/mediator/ApiValidator.java:141 -# args: vm.getName(),vm.getUuid(),StringUtils.join(pfStr, ",") -the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ port\ forwarding\ rules%s\ attached = 云主机[name:{0}, uuid:{1}] 已经设置了一些端口转发规则{2} +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:409 +# args: agentBasic.INSMGetReturnCode(),agentBasic.INSMGetErrMsg() +large\ file\ hmac\ encrypt\ failed,\ code\:\ %s,\ detail\:\ %s = 大文件HMAC加密失败,代码:{0},详细信息:{1} -# at: src/main/java/org/zstack/mediator/ApiValidator.java:162 -# args: vm.getName(),vm.getUuid(),StringUtils.join(eipStr, ",") -the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ EIPs%s\ attached = 云主机[name:{0}, uuid:{1}] 已经配置了弹性IP{2} +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:457 +# args: +failed\ to\ find\ secret\ key = 找不到密钥 -# at: src/main/java/org/zstack/mediator/ApiValidator.java:177 -# args: msg.getVipUuid(),useForList.toString() -the\ vip[uuid\:%s]\ already\ has\ bound\ to\ other\ service[%s] = 该虚拟IP[uuid:{0}]已经绑定了其他服务 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:465 +# args: e.getMessage() +failed\ to\ parse\ secret\ key,\ error\:\ %s = 无法分析密钥,错误:{0} -# at: src/main/java/org/zstack/mediator/ApiValidator.java:213 -# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol -Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = 当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的端口范围[{2}, {3}]冲突 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:500 +# args: +cipherText\ can\ not\ be\ null = 密文不能为空 -# at: src/main/java/org/zstack/mediator/ApiValidator.java:240 -# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol -Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ system\ service\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = 当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的系统服务端口范围[{2}, {3}]冲突 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:503 +# args: +encryptSubjectDN\ can\ not\ be\ null = EncryptSubjectDN不能为空 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:772 -# args: l3Uuid,systemTag -L3\ network[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = 找不到L3网络[uuid:0]。请确认静态IP的系统标签 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:508 +# args: +failed\ to\ parse\ MS\ Envelope = 解析MS信封失败 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:304 -# args: supportSharedVolumePrimaryStorage,psType -for\ shareable\ volume,\ the\ only\ supported\ primary\ storage\ type\ is\ %s,\ current\ is\ %s = 共享云盘仅支持在主存储类型为{0}的主存储上使用,当前的类型为{1} +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:533 +# args: +failed\ to\ export\ secret\ key = 无法导出密钥 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:734 -# args: bandwidth,Long.MAX_VALUE -invalid\ volume\ bandwidth[%s]\ is\ larger\ than\ %d = 云盘带宽[{0}]大于{1}是无效的 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecClient.java:550 +# args: +import\ secret\ key\ fail = 导入密钥失败 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:732 -# args: bandwidth -invalid\ volume\ bandwidth[%s]\ is\ not\ a\ number = 错误的云盘带宽 ,[{0}] 这个不是数字 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java:196 +# args: vo.getUuid(),activateTokenRes.error +failed\ to\ generate\ activated\ token\ for\ the\ security\ machine\ %s\ because\ %s = 无法为密码机{0}生成激活的令牌,因为{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:729 -# args: bandwidth -invalid\ volume\ bandwidth[%s],\ it\ must\ be\ greater\ than\ 1024\ (include\ 1024) = 无效的云盘带宽,它必须大于等于1M +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java:206 +# args: dataProtectTokenName,vo.getUuid(),dataProtectTokenRes.error +failed\ to\ generate\ dataProtect\ token\ %s\ for\ the\ security\ machine\ %s\ because\ %s = 无法为密码机{1}生成DataProtect令牌{0},因为{2} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:753 -# args: bandwidth -invalid\ volume\ IOPS[%s]\ is\ not\ a\ number = 错误的云盘每秒读写速度[{0}],它应该是个数字 +# at: src/main/java/org/zstack/crypto/securitymachine/thirdparty/infoSec/InfoSecSecretResourcePoolBase.java:216 +# args: hmacTokenName,vo.getUuid(),hmacTokenTokenRes.error +failed\ to\ generate\ hmac\ token\ %s\ for\ the\ security\ machine\ %s\ because\ %s = 无法为密码机{1}生成HMAC令牌{0},因为{2} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:755 -# args: bandwidth,Long.MAX_VALUE -invalid\ volume\ IOPS[%s]\ is\ larger\ than\ %d = 云盘IOPS[{0}]大于{1}是无效的 +# at: src/main/java/org/zstack/cube/CubeManagerImpl.java:505 +# args: cmd.host,cmd.detail +host[uuid\:\ %s]\ memory\ ecc\ triggered,\ detail\:\ %s = 物理机[uuid:{0}]内存ECC已触发,详细信息:{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:750 -# args: bandwidth -invalid\ volume\ IOPS[%s],\ it\ must\ be\ greater\ than\ 0 = 错误的云盘每秒读写速度[{0}],它应该大于0 +# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:99 +# args: +parameters\ [accountUuid]\ only\ can\ be\ used\ by\ admin\ user! = 参数[accountUuid]必须被admin用户设置 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:810 -# args: level -Unknown\ code[%s]\ of\ Security\ Level = +# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:54 +# args: msg.getExpirePolicy() +expire\ policy\:\ %s\ is\ not\ valid = 无效的过期策略:{0} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:832 -# args: cidr -[%s]\ is\ not\ a\ standard\ cidr = +# at: src/main/java/org/zstack/daho/core/DahoApiInterceptor.java:57 +# args: msg.getVlan() +vlanId[%s]\ has\ been\ existed! = VlanId[{0}]已存在! -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:849 -# args: hostUuid,distro,version -the\ host[uuid\:%s]'s\ operating\ system\ %s\ %s\ is\ too\ old,\ the\ QEMU\ doesn't\ support\ QoS\ of\ network\ or\ disk\ IO.\ Please\ choose\ another\ instance\ offering\ with\ no\ QoS\ configuration = 物理机[uuid:{0}] 的操作系统{1} {2} 过老, QEMU 不支持云盘的QOS IO设置 。 请选择别的没有Qos的计算规格 +# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:128 +# args: +create\ daho\ vll\ task\ failed! = 创建daho vll任务失败 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1082 -# args: newValue -invalid\ value[%s],\ it's\ not\ a\ double = 错误的值[{0}],这个不是双精度值 +# at: src/main/java/org/zstack/daho/core/DahoSdkImpl.java:169 +# args: msg.getAccountUuid() +no\ aliyun\ account\ found\ for\ accountUuid\:\ %s = 找不到当前账户{0}对应的阿里云账户 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1050 -# args: newValue -invalid\ value[%s],\ it\ must\ be\ a\ double\ greater\ than\ 0 = 错误的值[{0}],必须是一个大于0的双精度值 +# at: src/main/java/org/zstack/directory/DirectoryApiInterceptor.java:105 +# args: list,msg.getDirectoryUuid() +resources\ %s\ has\ already\ been\ bound\ to\ directory\ uuid[%s]\ ,\ multiple\ paths\ are\ not\ supported = 资源{0}已绑定到目录uuid[{1}],不支持多个路径 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1079 -# args: newValue -invalid\ value[%s],\ it\ must\ be\ a\ double\ between\ (0,\ 1] = 错误的值[{0}],这个必须在0~1之间的双精度值 +# at: src/main/java/org/zstack/directory/DirectoryApiInterceptor.java:112 +# args: list,ALLOW_RESOURCE_TYPES +resource\ types\ %s\ are\ not\ supported\ by\ directory,\ allowed\ types\ are\ %s = 目录不支持资源类型{0},允许的类型为{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1093 -# args: newValue -invalid\ value[%s],\ ZStack\ doesn't\ have\ such\ host\ allocator\ type = 错误值[{0}],Zstack没有这样的分配器类型 +# at: src/main/java/org/zstack/directory/DirectoryApiInterceptor.java:129 +# args: +name\ contains\ unsupported\ characters,\ name\ can\ only\ contain\ Chinese\ characters,\ English\ letters,\ numbers,\ spaces,\ and\ the\ following\ characters\:\ ()()【】@._-+\ = 名称包含不支持的字符,名称只能包含中文字符、英文字母、数字、空格和以下字符:()()[]@._-+ -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1115 -# args: MevocoGlobalConfig.AIO_NATIVE.getCanonicalName(),MevocoGlobalConfig.AIO_NATIVE.value(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.getCanonicalName(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.value() -%s\ value\ is[%s],\ which\ is\ conflict\ with\ %s\ value\ [%s] = +# at: src/main/java/org/zstack/directory/DirectoryBase.java:356 +# args: msg.getDirectoryUuid(),msg.getTargetParentUuid() +circular\ dependency\ detected,\ directory\ %s\ and\ directory\ %s\ will\ cause\ circular\ dependency = 检测到循环依赖,目录{0}和目录{1}将导致循环依赖 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1371 +# at: src/main/java/org/zstack/directory/DirectoryManagerImpl.java:147 +# args: list.get(0).getUuid(),msg.getName() +duplicate\ directory\ name,\ directory[uuid\:\ %s]\ with\ name\ %s\ already\ exists = 已存在名称为{1}的重复目录名、目录[uuid:{0}] + +# at: src/main/java/org/zstack/directory/DirectoryManagerImpl.java:154 # args: -obj\ is\ not\ instanceof\ NicQos! = +fail\ to\ create\ directory,\ directories\ are\ up\ to\ four\ levels = 创建目录失败,目录最多有四层 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1732 -# args: String.join(",", ips) -unexpected\ host\ management\ IPs\:\ [%s] = +# at: src/main/java/org/zstack/directory/DirectoryManagerImpl.java:158 +# args: msg.getType(),DIRECTORY_TYPES +the\ type\ of\ directory\ %s\ is\ not\ supported,\ the\ supported\ directory\ types\ are\ %s = 不支持目录{0}的类型,支持的目录类型为{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1864 +# at: src/main/java/org/zstack/directory/VmDirectoryChecker.java:27 +# args: vo.getZoneUuid() +all\ resources\ zoneUuid\ must\ be\ consistent\ with\ the\ directory\ zoneUuid[%s] = 所有资源的zoneuuid必须与目录zoneuuid[{0}]一致 + +# at: src/main/java/org/zstack/drs/DRSBase.java:216 # args: -can\ not\ set\ local\ and\ configure\ at\ same\ time = +Advice\ not\ allowed\ while\ scheduling = 计划时不允许通知 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1916 +# at: src/main/java/org/zstack/drs/DRSBase.java:277 # args: -can\ not\ find\ node\ A\ config\ info = +delete\ DRS\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = 迁移云主机时不允许删除DRS -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1926 +# at: src/main/java/org/zstack/drs/DRSBase.java:370 # args: -can\ not\ find\ node\ A\ address\ info\ from\ bootstrap\ agent = +Scheduling\ is\ not\ allowed\ while\ the\ vm\ is\ being\ migrated = 迁移云主机时不允许计划 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1987 -# args: s.getJobUuid() -can\ not\ get\ bootstrap\ job\ %s\ result\ after\ 900s = +# at: src/main/java/org/zstack/drs/DRSBase.java:481 +# args: +Lack\ of\ host\ CPU,\ memory\ monitoring\ data = 缺少物理机CPU、内存监控数据 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1995 -# args: ret.getRetCode(),ret.getStdout(),ret.getStderr() -curl\ bootstrap\ agent\ finished,\ return\ code\:\ %s,\ stdout\:\ %s,\ stderr\:\ %s = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:55 +# args: msg.getClusterUuid() +The\ cluster[%s]\ has\ created\ DRS = 集群[{0}]已创建DRS -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2459 -# args: errorOfNodeA.getCauses().get(0) -node\ A\ update\ factory\ mode\ failed,\ details\:\ %s = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:59 +# args: +DRS\ is\ disabled = DRS已禁用 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2457 -# args: errorCodeList.getCauses().get(0) -all\ management\ node\ update\ factory\ mode\ failed,\ details\:\ %s = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:64 +# args: +thresholds\ can\ not\ be\ empty = 阈值不能为空 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2566 -# args: ManagementNodeState.RUNNING -management\ node\ status\ is\ not\ %s = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:73 +# args: threshold.getThresholdName() +illegal\ thresholdName[%s] = 阈值名称[{0}]非法 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2493 -# args: r.getStdout() -some\ node\ on\ factory\ mode\ exists,\ detail\ of\ arping\:\ %s = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:77 +# args: threshold.getOperator() +illegal\ threshold\ operator[%s] = 阈值运算符[{0}]非法 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2514 +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:81 # args: -set\ address\ on\ node\ A\ failed = +thresholdValue\ can\ not\ be\ empty = 阈值不能为空 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2511 +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:86 # args: -this\ node\ is\ not\ node\ A = +illegal\ thresholdValue,\ valid\ range\:\ (0,\ 100] = 阈值非法,有效范围:([0,100] -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2651 -# args: bandwidth -networkInboundBandwidth\ format\ error\ %s = 下行网络带宽格式错误{0} +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:103 +# args: +GlobalConfig\ ENABLE_DRS\ is\ closed = GlobalConfig启用_DRS已关闭 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2663 -# args: bandwidth -networkOutboundBandwidth\ format\ error\ %s = 上行网络带宽超格式错误{0} +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:107 +# args: msg.getUuid(),vo.getState().toString() +The\ DRS[%s]\ state\ is\ %s = DRS[{0}]状态为{1} -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2660 -# args: -networkOutboundBandwidth\ execeds\ the\ max\ value\ 32G\ bps = 超过上行网络带宽超过最大值32G bps +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:122 +# args: adviceVO.getDrsUuid() +The\ DRS[%s]\ automation\ level\ is\ not\ manual = DRS[{0}]自动化级别不是手动的 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2855 -# args: volume.getUuid(),vm.getUuid() -Shareable\ Volume[uuid\:%s]\ has\ already\ been\ attached\ to\ VM[uuid\:%s] = 共享云盘[uuid:{0}]已经挂载到云主机[uuid:{1}]上 +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:136 +# args: msg.getAdviceUuid() +advice[%s]\ has\ expired = 建议[{0}]已过期 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2873 +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:145 # args: -shareable\ disk\ only\ support\ virtio-scsi\ type\ for\ now = 目前共享盘只支持virtio-scsi +Successfully\ executed,\ no\ repeated\ executions\ allowed = 执行成功,不允许重复执行 -# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3279 -# args: sharedVolUuids -shareable\ volume(s)[uuid\:\ %s]\ attached,\ not\ support\ to\ group\ snapshot. = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:152 +# args: adviceVO.getVmUuid() +The\ vm[%s]\ has\ been\ deleted = 云主机[{0}]已删除 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:331 -# args: vmInstanceVO.getUuid() -How\ can\ a\ Running\ VM[uuid\:%s]\ has\ no\ hostUuid? = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:155 +# args: adviceVO.getVmUuid() +The\ vm[%s]\ state\ is\ not\ running = VM[{0}]状态未运行 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:329 -# args: vmInstanceVO.getUuid() -Unexpectedly,\ VM[uuid\:%s]\ is\ not\ running\ any\ more,\ please\ try\ again\ later = +# at: src/main/java/org/zstack/drs/DRSInterceptor.java:158 +# args: adviceVO.getVmUuid(),adviceVO.getVmSourceHostUuid() +The\ vm[%s]\ is\ no\ longer\ on\ the\ source\ host[%s] = VM[{0}]不再位于源物理机[{1}]上 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:719 -# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() -can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ not\ attached = 当云盘[uuid:{1}]未加载时,无法给云盘[{0}]创建快照 +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:273 +# args: msg.getClusterUuid() +The\ cluster[%s]\ does\ not\ support\ DRS. = 集群[{0}]不支持DRS。 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:725 -# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() -can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ appears\ twice = 当云盘[uuid:{1}]出现多次时,无法给云盘[{0}]创建快照 +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:290 +# args: reasons +Can\ not\ create\ DRS,\ %s = 无法创建DRS,{0} -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:732 -# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid(),volumeVOS.get(0).getVmInstanceUuid() -can\ not\ take\ snapshot\ for\ volumes[%s]\ attached\ multiple\ vms[%s,\ %s] = 当云盘[uuid:{1}]加载到多个虚拟机上时,无法给云盘[{0}]创建快照 +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:323 +# args: +hostUuids\ is\ empty = HOSTuuidS为空 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:739 +# at: src/main/java/org/zstack/drs/DRSManagerImpl.java:330 # args: -no\ volumes\ found = 找不到云盘 +query\ hosts\ utilization\ data\ failed = 查询物理机利用率数据失败 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:971 -# args: SizeUnit.BYTE.toGigaByte((double) resize) -this\ snapshot\ recording\ the\ volume\ state\ before\ resize\ to\ %fG\ is\ created\ automatically = 该快照记录云盘扩容到{0}G之前的状态,由系统自动创建 +# at: src/main/java/org/zstack/encrypt/EncryptionParamApiInterceptor.java:83 +# args: bundle.getEncryptionType() +failed\ to\ parse\ API\ message\:\ can\ not\ parse\ encryption\ param\ with\ type\ %s = 未能分析API消息:无法分析类型为{0}的加密参数 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1238 -# args: msg.getUuid() -DeleteVolumeQos\ [%s]\ ingor\ because\ of\ account\ privilege. = +# at: src/main/java/org/zstack/encrypt/EncryptionParamApiInterceptor.java:128 +# args: matchTags.size() +failed\ to\ parse\ API\ message\:\ found\ %d\ encryption\ param\ system\ tags,\ expect\ 1 = 未能分析API消息:找到{0}个加密参数系统标记,应为1个 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1270 -# args: ivo.getHostUuid(),ivo.getState(),VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString() -Cannot\ delete\ vm's\ volume\ qos\ on\ host\ %s,\ because\ the\ current\ vm\ is\ in\ state\ of\ %s,\ but\ support\ expect\ states\ are\ [%s,\ %s] = +# at: src/main/java/org/zstack/externalbackup/zbox/HostZBoxBackupRecoverGC.java:142 +# args: volumeUuids +some\ volume[uuids\:%s]\ recover\ failed.\ you\ can\ trigger\ it\ again\ by\ reconnect\ it. = 某些卷[uuid:{0}]恢复失败。您可以通过重新连接来再次触发它。 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1428 -# args: VolumeQos.getVolumeQosByMode(self.getVolumeQos(), msg.getMode()) -non\ admin\ account\ cannot\ set\ bandwidth\ more\ than\ %s = +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupApiInterceptor.java:34 +# args: externalBackupUuid +there\ is\ another\ external\ backup[uuid\:\ %s]\ recovering = 另一个外部备份[uuid:{0}]正在恢复 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1469 -# args: self.getUuid() -volume\ [%s]\ isn't\ attached\ to\ any\ vm,\ cannot\ get\ qos\ by\ forceSync = +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupApiInterceptor.java:38 +# args: +both\ hostUuids\ and\ backupStorageUuids\ are\ empty.\ you\ must\ specify\ one\ or\ both\ of\ them. = Hostuuid和BackupStorageuuid均为空。您必须指定其中一个或两个。 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1475 -# args: self.getUuid() -volume\ [%s]\ isn't\ attached\ to\ any\ vm\ (or\ vm\ is\ not\ existed\ now),\ cannot\ sync\ volume\ qos = +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:691 +# args: +please\ insert\ zbox\ to\ management\ node. = 请将ZBOX插入管理节点。 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1480 -# args: vm.getUuid() -vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ volume\ qos = +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:219 +# args: +cannot\ find\ recover.conf\ under\ zbox\ backup\ install\ dir. = 在ZBOX备份安装目录下找不到recover.conf。 + +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:741 +# args: result.getExecutionLog() +fail\ to\ backup\ database\:\ %s = 无法备份数据库:{0} -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1485 +# at: src/main/java/org/zstack/externalbackup/zbox/ZBoxBackupBase.java:591 # args: -vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ volume\ qos = +zbox\ should\ be\ inserted\ to\ a\ host\ first. = 应首先将ZBox插入物理机。 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1595 -# args: msg.getVolume().getUuid(),msg.getVmInstanceUuid() -failed\ to\ detach\ shareable\ volume[uuid\:%s]\ from\ VmInstance[uuid\:%s] = 不能卸载云主机[uuid:{1}]上的共享盘[uuid:{0}] +# at: src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java:81 +# args: +crond\ is\ not\ running = crond任务未在运行 -# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1607 -# args: StringUtils.join(errors, "\n\n") -failed\ to\ detach\ shareable\ volume\ from\ VmInstance\:[\n%s] = 不能卸载云主机[uuid:{0}]上的共享盘 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:485 +# args: +Missing\ CPU/memory\ settings = 缺少CPU/内存设置 -# at: src/main/java/org/zstack/mevoco/PremiumGlobalConfig.java:27 -# args: getName() -the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ global\ config\ [name\:%s] = 当前license版本不支持修改此全局设置[name:{0}] +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:489 +# args: +Unexpected\ CPU/memory\ settings = 意外的CPU/内存设置 -# at: src/main/java/org/zstack/mevoco/PremiumResourceConfig.java:22 -# args: globalConfig.getName() -the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ resource\ config\ [name\:%s] = +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:498 +# args: instanceOfferingUuid +instance\ offering[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = 计算规格[uuid:{0}]没有被启用,不能根据该规格创建云主机 -# at: src/main/java/org/zstack/mevoco/VolumeQos.java:229 -# args: mode -invalid\ volume\ qos\ mode\:\ %s = +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:502 +# args: instanceOfferingUuid,ivo.getType() +instance\ offering[uuid\:%s,\ type\:%s]\ is\ not\ UserVm\ type,\ can't\ create\ vm\ from\ it = 计算规格[uuid:{0}, type:{1}]不是UserVm类型,不能通过它创建云主机 -# at: src/main/java/org/zstack/mevoco/VolumeQos.java:199 -# args: -cannot\ find\ mode\ from\ null\ VolumeQos = +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:539 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ Disabled,\ can't\ create\ vm\ from\ it = 镜像[uuid:{0}]没被启用,不能根据该镜像创建云主机 -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:190 -# args: msg.getMonitorTriggerUuid() -cannot\ find\ monitor\ trigger[uuid\:%s],\ it\ may\ have\ been\ deleted = 不能找到触发监控器[uuid:{0}],它可能已经被删除了 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:544 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ not\ ready\ yet,\ can't\ create\ vm\ from\ it = 镜像[uuid:{0}]尚未就绪,无法从中创建VM -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:199 -# args: msg.getMonitorTriggerActionUuid() -cannot\ find\ monitor\ trigger\ action[uuid\:%s],\ it\ may\ have\ been\ deleted = 为找到这个监控触发行为[uuid:{0}],它可能已经被删除了 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:559 +# args: msg.getImageUuid() +image[uuid\:%s]\ is\ system\ image,\ can't\ be\ used\ to\ create\ user\ vm = 镜像[uuid:{0}] 是系统镜像,不能使用它创建用户云主机 -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:243 -# args: msg.getResourceType() -the\ resource[type\:%s]\ doesn't\ have\ any\ monitoring\ items = 该资源[type:{0}]没有任何监控条目 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:575 +# args: diskUuids +disk\ offerings[uuids\:%s]\ are\ Disabled,\ can\ not\ create\ vm\ from\ it = 云盘规格[uuids:{0}]没有被启用,不能使用它创建云主机 -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:335 -# args: msg.getTargetResourceUuid(),msg.getSession().getAccountUuid() -the\ resource[uuid\:%s]\ doesn't\ belong\ to\ the\ account[uuid\:%s] = 该资源[uuid:{0}]不属于账户[uuid:{1}] +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:450 +# args: vmInstanceUuid +current\ operation\ is\ not\ supported\ on\ ft\ secondary\ vm[uuid\:%s] = FT辅助云主机[uuid:{0}]不支持当前操作 -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:386 -# args: resourceUuid -cannot\ find\ type\ for\ the\ resource[uuid\:%s] = 未找到资源[uuid:{0}]这种类型 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:126 +# args: group.getPrimaryVmInstanceUuid(),group.getSecondaryVmInstanceUuid() +pvm[uuid\:%s]\ and\ svm[uuid\:%s]\ volume\ number\ not\ matches,\ do\ not\ allowed\ to\ start = PVM[uuid:{0}]和SVM[uuid:{1}]卷号不匹配,不允许启动 -# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:391 -# args: resourceType,triggerExpression.getItem() -no\ monitoring\ item\ found\ for\ the\ resourceType[%s]\ and\ item[%s] = 未找到资源类型[{0}]和条目[{1}]这种监控条目 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:135 +# args: i,group.getPrimaryVmInstanceUuid(),group.getSecondaryVmInstanceUuid() +volume\ with\ index\:\ %d,\ of\ pvm[uuid\:%s]\ and\ svm[uuid\:%s]\ have\ different\ size,\ do\ not\ allowed\ to\ start = PVM[uuid:{1}]和SVM[uuid:{2}]中索引为{0}的卷大小不同,不允许启动 -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:50 -# args: args -A\ resource[name\:{resourceName},\ uuid\:{resourceUuid},\ type\:{resourceType}]'s\ monitoring\ trigger[uuid\:{triggerUuid}]\ changes\ status\ to\ {triggerStatus} = 资源[name:'{resourceName}', uuid:'{resourceUuid}', type:'{resourceType}']的监听触发器[uuid:'{triggerUuid}']修改状态为'{triggerStatus}' +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:146 +# args: i,group.getPrimaryVmInstanceUuid(),group.getSecondaryVmInstanceUuid() +volume\ with\ index\:\ %d,\ of\ pvm[uuid\:%s]\ and\ svm[uuid\:%s]'s\ cache\ volume\ have\ different\ size,\ do\ not\ allowed\ to\ start = PVM[uuid:{1}]和SVM[uuid:{2}]的缓存卷的索引为{0}的卷大小不同,不允许启动 -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:55 -# args: -\n\=\=\=\ BELOW\ ARE\ DETAILS\ OF\ THE\ PREVIOUS\ ALERT\ \=\=\= = \n=== 以下是上一次警告内容 === +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:169 +# args: msg.getUuid(),faultToleranceVmGroupUuid +image[uuid\:%s]\ is\ still\ used\ by\ fault\ tolerance\ vm[uuid\:%s] = 容错云主机[uuid:{1}]仍在使用镜像[uuid:{0}] -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:58 -# args: -\nalert\ details\: = \n警告内容: +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:212 +# args: msg.getL3NetworkUuid(),String.join(",", vmInstanceUuids),VmInstanceState.Paused,VmInstanceState.Running +could\ not\ delete\ l3\ network[uuid\:%s].\ Fault\ tolerance\ vm[%s]\ in\ states[%s,\ %s]\ still\ using\ it.\ Stop\ related\ fault\ tolerance\ vms\ before\ delete\ l3\ network = 无法删除三层网络[uuid:{0}]。状态为[{2},{3}]的容错VM[{1}]仍在使用。在删除三层网络之前停止相关的容错云主机 -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:59 -# args: args -\ncondition\:\ {itemName}\ {operator}\ {threshold} = \n环境: '{itemName}' '{operator}' '{threshold}' +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:266 +# args: msg.getFaultToleranceVmUuid() +Can\ not\ fail-over\ vm[uuid\:%s],\ please\ enable\ ft\ in\ GlobalConfig = 无法对VM[uuid:{0}]进行故障转移,请在GlobalConfig中启用FT -# at: src/main/java/org/zstack/monitoring/items/AlertText.java:60 -# args: args -\ncurrent\ value\:\ {value} = \n当前值: '{value}' +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:270 +# args: msg.getFaultToleranceVmUuid() +Can\ not\ fail-over\ vm[uuid\:%s],\ please\ confirm\ it\ is\ a\ fault\ tolerance\ vm\ group = 无法对VM[uuid:{0}]进行故障转移,请确认它是容错VM组 -# at: src/main/java/org/zstack/monitoring/items/host/HostCpuUtilItem.java:31 -# args: -Host\ CPU\ utilization = CPU使用率 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:276 +# args: msg.getFaultToleranceVmUuid(),FaultToleranceStatus.Protected,FaultToleranceStatus.Unknown +Can\ not\ fail-over\ vm[uuid\:%s],\ because\ fault\ tolerance\ vm\ group\ is\ not\ in\ status\ of\ [%s,\ %s] = 无法对VM[uuid:{0}]进行故障转移,因为容错VM组的状态不是[{1},{2}] -# at: src/main/java/org/zstack/monitoring/items/vm/VmCpuUtilItem.java:29 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:301 +# args: Joiner.on(",").join(vmUuids) +Can\ not\ maintain\ host,\ because\ ft\ vms[%s]\ are\ under\ recovering = 无法维护物理机,因为正在恢复FT VM[{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:319 +# args: msg.getClass(),msg.getVmInstanceUuid(),state +current\ operation[api\:%s]\ is\ not\ supported\ when\ ft\ vm[uuid\:%s,\ state\:%s]\ is\ not\ stopped = 未停止FT VM[uuid:{1},状态:{2}]时,不支持当前操作[API:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:367 +# args: VmHaLevel.FaultTolerance.toString() +Can\ not\ set\ vm\ level\ to\ %s,\ please\ enable\ ft\ in\ GlobalConfig = 无法将VM级别设置为{0},请在GlobalConfig中启用FT + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:515 # args: -VM\ CPU\ utilization = 虚拟机CPU使用率 +Ft\ network\ is\ not\ set = 未设置FT网络 -# at: src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java:141 -# args: rb.name,r -conflict\ alert\ rule[%s],\ there\ has\ been\ a\ rule[%s]\ with\ the\ same\ name = 冲突提示规则[{0}],这里已经存在和它一样名称的规则 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:423 +# args: msg.getVmInstanceUuid() +can\ not\ update\ ft\ vm[uuid\:%s]\ cpu\ number,\ need\ to\ stop\ both\ of\ the\ vms = 无法更新FT VM[uuid:{0}]CPU编号,需要停止两个VM -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusAlert.java:79 -# args: resourceName,resourceUuid,toI18nString(resourceType),itemName,toI18nString(expression.getOperator()),expression.getConstant(),value,tvo.getDuration() -ALERT\:\n\ resource[name\:\ %s,\ uuid\:\ %s,\ type\:\ %s]\nevent\:\ %s\ %s\ %s\ncurrent\ value\:\ %s\nduration\:\ %s\ seconds\n = 警告:\n 资源[名称: {0}, uuid: {1}, 类型: {2}]\n 事件: {3} {4} {5}\n 周期: {7}\n +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:427 +# args: msg.getVmInstanceUuid() +can\ not\ update\ ft\ vm[uuid\:%s]\ memory\ size,\ need\ to\ stop\ both\ of\ the\ vms = 无法更新FT VM[uuid:{0}]内存大小,需要停止两个VM -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:40 -# args: msg.getRelativeTime() -the\ relativeTime[%s]\ is\ invalid,\ it\ must\ be\ in\ format\ of,\ for\ example,\ 10s,\ 1h = 相关时间[{0}]不合法,格式必须例如10s,1h +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:431 +# args: msg.getVmInstanceUuid() +can\ not\ update\ ft\ vm[uuid\:%s]\ platform,\ need\ to\ stop\ both\ of\ the\ vms = 无法更新FT VM[uuid:{0}]平台,需要停止两个VM -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:44 -# args: msg.getRelativeTime() -the\ relativeTime[%s]\ is\ invalid,\ it's\ too\ big = 相关时间[{0}]不合法,值's 过大 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:442 +# args: vmInstanceUuid +current\ operation\ is\ not\ supported\ on\ ft\ group\ vm[uuid\:%s] = FT组VM[uuid:{0}]不支持当前操作 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilAlertWriter.java:95 -# args: -CPU\ number = CPU数量 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:446 +# args: vmInstanceUuid +current\ operation\ is\ not\ supported\ on\ ft\ primary\ vm[uuid\:%s] = FT主VM[uuid:{0}]不支持当前操作 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilItem.java:70 -# args: cpu,trigger.getTargetResourceUuid(),cpuNum -invalid\ cpu[%s],\ the\ host[uuid\:%s]\ doesn't\ have\ a\ CPU\ numbered\ by\ %s = 无效CPU数目[{0}],物理机[uuid:{1}]存在的CPU数目是{2} +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:466 +# args: msg.getVmInstanceUuid() +current\ operation\ is\ not\ supported\ on\ secondary\ vm[uuid\:%s] = 辅助云主机[uuid:{0}]不支持当前操作 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:92 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:472 # args: -Host\ Disk\ Capacity = 物理机磁盘容量 +can\ not\ migrate\ FT\ primary\ vm = 无法迁移FT主云主机 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:98 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:476 # args: -Host\ Disk\ Capacity\ type = 物理机磁盘容量类型 +can\ not\ migrate\ FT\ secondary\ vm = 无法迁移FT辅助云主机 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:100 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:511 # args: -Host\ devices = 物理机服务 +Failed\ to\ create\ ft\ vm,\ please\ enable\ ft\ in\ GlobalConfig = 无法创建FT VM,请在GlobalConfig中启用FT -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityItem.java:22 -# args: type,ALLOWED_TYPES -invalid\ type[%s],\ only\ %s\ are\ allowed = 无效类型[{0}],只有{1}被允许 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:549 +# args: msg.getImageUuid(),imgFormat +image[uuid\:%s]\ is\ of\ mediaType\:\ %s,\ only\ RootVolumeTemplate\ can\ be\ used\ to\ create\ vm = 镜像[uuid:{0}]的媒体类型为:{1},只能使用RootVolumeTemplate创建VM -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostNetworkIOAlertWriter.java:77 -# args: -Host = 物理机 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceApiInterceptor.java:554 +# args: msg.getImageUuid(),imageFileFmt,ImageConstant.QCOW2_FORMAT_STRING +image[uuid\:%s]\ is\ of\ format\:\ %s,\ only\ %s\ can\ be\ used\ to\ create\ vm = 镜像[uuid:{0}]的格式为:{1},只有{2}可用于创建VM -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusMonitorProviderFactory.java:124 -# args: ret.get("errorType"),ret.get("error") -query\ failure,\ errorType\:%s,\ error\:\ %s = 查询失败,错误类型: {0}, 错误: {1} +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:364 +# args: hostUuid +failed\ to\ allocate\ port\ on\ host[uuid\:\ %s] = 无法在物理机[uuid:{0}]上分配端口 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:81 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:369 +# args: hostUuid +allocated\ port\ num\ less\ than\ requested\ on\ host[uuid\:\ %s] = 物理机[uuid:{0}]上分配的端口号小于请求的端口号 + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:524 +# args: smsg.getPrimaryVmInstanceUuid() +could\ not\ get\ hostUuid\ of\ primary\ vm[uuid\:%s] = 无法获取主云主机[uuid:{0}]的Hostuuid + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:892 # args: -CPU\ Utilization = CPU使用率 +can\ not\ start\ secondary\ vm,\ because\ primary\ vm\ is\ still\ stopped = 无法启动辅助云主机,因为主云主机仍处于停止状态 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:84 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:1322 +# args: vm.getUuid() +Can\ not\ migrate\ ft\ secondary\ vm[uuid\:%s] = 无法迁移FT辅助云主机[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmFactory.java:1327 +# args: vm.getUuid() +Can\ not\ migrate\ ft\ primary\ vm[uuid\:%s] = 无法迁移FT主云主机[uuid:{0}] + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmInstanceBase.java:546 # args: -CPU\ utilization\ type = CPU使用类型 +Current\ ft\ vm\ is\ in\ unknown\ status,\ can\ not\ stop\ it,\ please\ try\ to\ fail-over\ it\ manually = 当前FT云主机处于未知状态,无法停止,请尝试手动故障转移 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:86 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceGroupVmInstanceBase.java:596 +# args: self.getUuid() +unable\ to\ start\ the\ vm[uuid\:%s].\ It\ doesn't\ have\ any\ nic,\ please\ attach\ a\ nic\ and\ try\ again = 无法启动云主机[uuid:{0}]。该云主机没有网卡,请添加网卡后再试 + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:3110 +# args: nicUuid,pvm.getHostUuid() +failed\ to\ allocate\ port\ of\ nic[uuid\:\ %s]\ on\ host[uuid\:\ %s] = 无法分配物理机[uuid:{1}]上的NIC[uuid:{0}]的端口 + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:3115 +# args: nicUuid,pvm.getHostUuid() +allocated\ port\ num\ less\ than\ requested\ of\ nic[uuid\:\ %s]\ on\ host[uuid\:\ %s] = 分配的端口数小于物理机[uuid:{1}]上的NIC[uuid:{0}]请求的端口数 + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:727 # args: -Disk\ IO = 磁盘IO +can\ not\ create\ secondary\ vm,\ because\ primary\ vm\ is\ stopped = 无法创建辅助云主机,因为主云主机已停止 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:92 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:641 # args: -Disk\ IO\ direction = 磁盘IO方向 +an\ other\ fault\ tolerance\ gc\ task\ is\ running,\ cancel\ the\ new\ task\ and\ wait\ return = 其他容错GC任务正在运行,请取消新任务并等待返回 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:93 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:2256 # args: -Disk\ IO\ type = 磁盘IO类型 +can\ not\ start\ secondary\ vm,\ because\ primary\ vm\ is\ stopped = 无法启动辅助云主机,因为主云主机已停止 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilAlertWriter.java:77 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1212 # args: -Memory\ Utilization = 内存使用率 +created\ svm\ found,\ report\ error\ for\ this\ start\ secondary\ vm\ request = 找到已创建的SVM,报告此启动辅助云主机请求的错误 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:57 -# args: expression.getConstant() -invalid\ right\ value[%s],\ it\ must\ be\ a\ float\ or\ double\ number = 无效的参数值[{0}],它必须是一个float或者double类型的数值 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1468 +# args: vmInstanceUuid +could\ not\ failover\ vm[uuid\:%s].\ Related\ fault\ tolerance\ vm\ group\ not\ exists = 无法对云主机[uuid:{0}]进行故障切换。相关容错云主机组不存在 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:53 -# args: expression.getConstant() -invalid\ right\ value[%s],\ it\ must\ be\ float\ or\ double\ number\ greater\ than\ zero\ and\ lesser\ than\ one = 无效参数值[{0}],它必须是一个float或者double类型的大于0小于1的数值 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1484 +# args: group.getPrimaryVmInstanceUuid() +pvm[uuid\:%s]\ not\ exists = PVM[uuid:{0}]不存在 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:47 -# args: expression.getArguments().keySet() -invalid\ arguments\ %s,\ no\ argument\ is\ allowed = 无效参数列表{0},没有被参数被允许 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1596 +# args: +unexpected\ exception = 意外异常 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:84 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1556 # args: -Network\ IO = 网络IO +could\ not\ failover.\ Secondary\ vm\ is\ unknown\ but\ no\ fault\ tolerance\ network\ address\ available = 无法进行故障转移。辅助云主机未知,但没有可用的容错网络地址 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:89 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1495 # args: -Network\ IO\ direction = 网络IO方向 +could\ not\ failover.\ Primary\ vm\ is\ unknown\ but\ no\ fault\ tolerance\ network\ address\ available = 无法进行故障转移。主云主机未知,但没有可用的容错网络地址 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:77 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:1669 +# args: hostUuid +cannot\ found\ available\ ip\ from\ current\ ft\ network.\ Check\ whether\ global\ config[category\:ft\ name\:fault.tolerance.network.cidr]\ is\ correctly\ set,\ and\ confirm\ that\ host[uuid\:%s]\ own\ ip\ address\ in\ the\ CIDR = 在当前FT网络中找不到可用的IP。e.检查是否正确设置了全局配置[Category:FT Name:Fault.TolerancNetwork.CIDR],并确认物理机[uuid:{0}]在CIDR中拥有IP地址 + +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceManagerImpl.java:3009 # args: -Virtual\ Machine = 虚拟机器 +not\ fault\ tolerance\ vm\ port\ found = 未找到容错VM端口 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:22 -# args: expression.getConstant() -invalid\ right\ value[%s],\ it\ must\ be\ a\ number(int,\ long,\ float,\ double) = 无效参数值[{0}],他应该是一个数字(int, long, float, double) +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java:95 +# args: imageUuid,spec.getVmInventory().getName(),spec.getVmInventory().getUuid() +cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage.\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = 不能发现镜像[uuid:{0}]在任何处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \n1. 镜像服务器是否已经过载到区域中的云主机[name: {1}, uuid:{2}]中;\n2. 如果镜像服务器不是处于连接状态,请尝试重连 -# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:18 -# args: dir,ALLOWED_DIRECTION -invalid\ direction[%s],\ only\ %s\ are\ allowed = 无效direction[{0}],只有{1}被允许 +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java:89 +# args: imageUuid,spec.getVmInventory().getZoneUuid(),spec.getVmInventory().getName(),spec.getVmInventory().getUuid() +cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ if\ the\ backup\ storage\ is\ attached\ to\ the\ zone\ where\ the\ VM[name\:\ %s,\ uuid\:%s]\ is\ in\n2.\ if\ the\ backup\ storage\ is\ in\ connected\ status,\ if\ not,\ try\ reconnecting\ it = 不能发现镜像[uuid:{0}]在任何已经挂载到集群[uuid:{1}]上的并且处于Connected状态备份的镜像服务器。可以进行对以下选项的检查: \n1. 镜像服务器是否已经过载到区域中的云主机[name: {2}, uuid:{3}]中;\n2. 如果镜像服务器不是处于Connected状态,请尝试重连 -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:106 -# args: expr,e.getMessage() -invalid\ expression\:\ %s,\ %s = 无效的语句: {0}, {1} +# at: src/main/java/org/zstack/faulttolerance/FaultToleranceVmImageSelectBackupStorageFlow.java:117 +# args: zoneUuid,isoImageUuid +no\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s]\ contains\ the\ ISO[uuid\:%s] = 没有包含着ISO[uuid:{1}]的镜像服务器添加到区域[uuid:{0}] -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:110 -# args: expr -invalid\ expression\:\ %s,\ no\ expression\ found = 无效的语句: {0},未找到该语句 +# at: src/main/java/org/zstack/faulttolerance/ShadowVmCloneTagsFlow.java:63 +# args: +missing\ fault\ tolerance\ vm\ group = 缺少容错VM组 -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:127 -# args: key -missing\ parameter\ '%s'\ in\ the\ expression = 在语句中缺失参数{0} +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:63 +# args: vo.getL3NetworkUuid(),vo.getFlowMeterUuid() +The\ network[%s]\ have\ been\ added\ into\ the\ flow\ meter[%s] = 网络[{0}]已添加到流量计[{1}]中 -# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:131 -# args: key,clz,value.getClass() -wrong\ type\ of\ parameter\ '%s'\ in\ the\ expression,\ it\ must\ be\ type\ of\ %s,\ but\ got\ %s = 在语句中{0}参数类型错误,它必须是{1}这种类型,但是获得的是{2} +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:71 +# args: +The\ virtual\ router\ have\ been\ added\ into\ other\ flow\ meter = 已将虚拟路由器添加到其他流量计中 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:59 -# args: rpAddress -Rendezvous\ Point\ [%s]\ is\ not\ a\ unicast\ address = 组播聚合点地址[{0}]不是单播地址 +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:77 +# args: msg.getVersion(),FlowMeterConstants.TYPE.NetFlow.toString() +invalid\ type\ parameter\ is\ %s\ and\ should\ be\ in\ %s = 无效的类型参数为{0},应位于{1}中 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:63 -# args: multicastGroup -group\ address\ [%s]\ is\ not\ a\ multicast\ address = 地址 [{0}] 不是组播地址 +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:154 +# args: msg.getServer() +[%s]\ is\ not\ formatted\ as\ IP\ address = [{0}]的格式不是IP地址 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:75 -# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() -rp\ address\ pair\ [%s\:\ %s]\ already\ existed\ for\ multicast\ router\ [uuid\:%s] = 组播聚合点地址对[{0}: {1}]已经存在于组播路由器[uuid:{2}]的配置中 +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:143 +# args: collector.getUuid() +Collector\ duplicate\ with\ %s = 收集器与{0}重复 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:89 -# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() -rp\ address\ tuple\ [%s\ \:\ %s]\ is\ not\ existed\ for\ multicast\ router\ [uuid\:%s] = 组播聚合点地址对[{0}: {1}]不存于组播路由器[uuid:{2}]的配置中 +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:164 +# args: collectorVO.getFlowMeterUuid() +FlowMeter[%s]\ doesn't\ exist = 流量计[{0}]不存在 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:98 +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:168 +# args: collectorVO.getFlowMeterUuid(),vo.getVersion().toString() +FlowMeter[%s]\ IPv6\ doesn't\ support\ version[%s] = 流量计[{0}]IPv6不支持版本[{1}] + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:150 +# args: +no\ specify\ parameter = 没有指定参数 + +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:159 # args: msg.getUuid() -multicastRouter[uuid\:%s]\ has\ not\ been\ attached\ to\ vpc\ router = 组播路由器[uuid:{0}]没有关联到VPC路由器 +Flow\ collector[%s]\ doesn't\ exist = 流收集器[{0}]不存在 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:124 -# args: msg.getVpcRouterVmUuid() -multicast\ already\ enabled\ on\ vpc\ router\ uuid[\:%s] = VPC路由器[uuid:{0}]的组播路功能已经打开 +# at: src/main/java/org/zstack/flowMeter/FlowMeterApiInterceptor.java:183 +# args: server,port,collector.getUuid() +Collector\ [%s\ %d]\ duplicate\ with\ %s = 收集器[{0}{1}]与{2}重复 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:88 +# args: vmUuid +unable\ to\ set\ vm\ hostname.\ the\ vm[uuid\:%s]\ do\ not\ have\ default\ L3\ network = 无法设置云主机物理机名。VM[uuid:{0}]没有默认的三层网络 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:103 +# args: sameTag.getResourceUuid(),hostname,defaultL3uuid +conflict\ hostname,\ there\ has\ been\ a\ VM[uuid\:%s]\ having\ hostname[%s]\ on\ L3\ network[uuid\:%s] = 物理机名冲突,在三层网络[uuid:{2}]上存在物理机名为[{1}]的云主机[uuid:{0}] -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:316 +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:111 +# args: msg.getVmInstanceUuid() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ vm\ not\ running. = 更新VM[uuid:{0}]网络配置失败,因为VM未运行。 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:116 +# args: msg.getVmInstanceUuid(),vm.getType() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ the\ vm\ type\ %s\ is\ not\ supported. = 更新VM[uuid:{0}]网络配置失败,因为不支持VM类型{1}。 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:129 +# args: msg.getVmInstanceUuid() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ guesttools\ not\ running. = 更新VM[uuid:{0}]网络配置失败,因为guestTools未运行。 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:125 +# args: msg.getVmInstanceUuid() +update\ vm[uuid\:%s]\ network\ config\ failed,\ because\ the\ guesttools\ version\ is\ too\ low\ for\ this\ feature. = 更新VM[uuid:{0}]网络配置失败,因为GuestTools版本太低,无法使用此功能。 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:136 +# args: nic.getUuid() +sync\ nic[uuid\:%s]\ network\ config\ failed,\ the\ current\ qga\ tools\ only\ support\ manual\ ipv6\ configuration\ and\ do\ not\ support\ automatic\ sync = 同步NIC[uuid:{0}]网络配置失败,当前QGA工具仅支持手动IPv6配置,不支持自动同步 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:147 # args: msg.getUuid() -vpc\ router\ for\ multicast\ router\ [uuid\:%s]\ has\ been\ deleted = 组播路由器[uuid:{0}]关联的VPC路由器已经被删除 +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为其虚拟化层目前不支持增强工具 -# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:759 +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:154 # args: msg.getUuid() -multicast\ router\ [uuid\:%s]\ is\ not\ attached\ to\ Vpc\ Router = 组播路由器[uuid:{0}]没有关联到VPC路由器 +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ running = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为它目前并未处于运行状态 -# at: src/main/java/org/zstack/multicast/router/backend/MulticastRouterVyosBackendImpl.java:86 -# args: vrUuid -multicast\ router\ [uuid\:%s]\ has\ been\ delete\ during\ enable\ multilcast\ on\ backend = 组播路由器[uuid:{0}]已经被删除 +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:161 +# args: msg.getUuid() +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为它不是用户云主机 -# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:91 -# args: msg.getNasFileSystemUuid() -nas\ file\ system\ [%s]\ is\ not\ existed\ yet = +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:168 +# args: msg.getUuid() +cannot\ attach\ guest-tools\ iso\ to\ vm[uuid\:%s]\ because\ it\ has\ no\ cdrom = 无法为云主机[uuid:{0}挂载增强工具镜像,因为它没有配备光驱 -# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:139 +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:191 +# args: vmUuid +cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ running = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为它目前并未处于运行状态 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:197 +# args: vmUuid +cannot\ get\ guest-tools\ info\ from\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为它不是用户云主机 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:219 +# args: invalidSet +invalid\ debug\ parameter\:\ %s = 无效的调试参数:{0} + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:227 +# args: msg.getVmInstanceUuid() +can\ not\ update\ guest\ tools\ state\ for\ vm\ [uuid\:%s]\ because\ vm\ is\ deleted = 无法更新VM[uuid:{0}]的来宾工具状态,因为VM已删除 + +# at: src/main/java/org/zstack/guesttools/GuestToolsApiInterceptor.java:232 +# args: msg.getVmInstanceUuid() +can\ not\ update\ guest\ tools\ state\ for\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法更新VM[uuid:{0}]的来宾工具状态,因为它不是用户VM + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:704 +# args: msg.getUuid() +cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ hypervisor\ type\ is\ not\ supported = 无法为云主机[uuid:{0}获取最新可用的增强工具镜像,因为其虚拟化层目前不支持增强工具 + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:713 +# args: msg.getUuid() +cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ running\ or\ volume\ recovering. = 无法获取VM[uuid:{0}]的最新来宾工具,因为它未运行或卷正在恢复。 + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:722 +# args: msg.getUuid() +cannot\ get\ latest\ guest-tools\ for\ vm[uuid\:%s]\ because\ it's\ not\ user\ vm = 无法为云主机[uuid:{0}]获取最新可用的增强工具镜像,因为它不是用户云主机 + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:1067 +# args: Platform.getManagementServerId(),msg.getHostUuid() +no\ proper\ guest\ tools\ iso\ found\ in\ management\ node[uuid\:%s]\ for\ host[uuid\:%s] = 无法在管理节点[uuid:{0}]上为物理机[uuid:{1}]寻找到合适的增强工具镜像 + +# at: src/main/java/org/zstack/guesttools/GuestToolsManagerImpl.java:2042 +# args: vm.getUuid(),vm.getName() +failed\ to\ set\ vm[uuid\:\ %s,\ name\:\ %s]\ hostname,\ because\ qga\ state\ is\ not\ running\ and\ there\ is\ no\ dhcp\ service = 无法设置VM[uuid:{0},名称:{1}]物理机名,因为QGA状态未在运行,并且没有DHCP服务 + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:144 +# args: vmUuid,rsp.getError() +failed\ to\ get\ guest\ tools\ info\ from\ vm[uuid\:%s],\ because\:%s = 无法从云主机[uuid:{0}]内部获取增强工具信息,因为:{1} + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:244 +# args: host.getUuid() +failed\ to\ download\ guest\ tools\ iso\ because\ no\ kvm\ host[uuid\:%s]\ found = KVM物理机[uuid:{0}]不存在,无法为其下载增强工具镜像 + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:313 +# args: vm.getUuid(),rsp.getError() +failed\ to\ attach\ guest\ tools\ iso\ to\ vm[uuid\:%s],\ because\:%s = 无法为云主机[uuid:{0}]挂载增强工具镜像,因为:{1} + +# at: src/main/java/org/zstack/guesttools/kvm/GuestToolsOnKvmBackend.java:358 +# args: vm.getUuid(),rsp.getError() +failed\ to\ detach\ guest\ tools\ iso\ from\ vm[uuid\:%s],\ because\:%s = 无法从VM[uuid:{0}]分离来宾工具ISO,因为:{1} + +# at: src/main/java/org/zstack/guesttools/pvpanic/PVPanicCrashStrategyManagerImpl.java:200 +# args: errCode +can\ not\ be\ here = 不能在这里。 + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:90 +# args: vm.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ because\ it\ is\ not\ stopped = 无法在VM[uuid:{0}]上设置FT,因为它未停止 + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:94 +# args: vm.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ because\ some\ data\ volume\ is\ still\ attached = 无法在VM[uuid:{0}]上设置FT,因为某些数据云盘仍处于挂接状态 + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:102 +# args: msg.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ since\ pci\ device\ attached = 由于连接了PCI设备,无法在VM[uuid:{0}]上设置FT + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:108 +# args: msg.getUuid() +can\ not\ set\ FT\ on\ vm[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached\ by\ passthrough = 无法在VM[uuid:{0}]上设置FT,因为存在通过passthrough连接的USB设备 + +# at: src/main/java/org/zstack/ha/HaInterceptor.java:119 +# args: msg.getUuid() +can\ not\ set\ FT\ on\ vmm[uuid\:%s]\ since\ mdev\ device\ attached = 无法在VMM[uuid:{0}]上设置FT,因为已连接MDEV设备 + +# at: src/main/java/org/zstack/ha/HaKvmHostSiblingChecker.java:257 +# args: struct.getHostUuid(),struct.getHostIp() +hosts\ failed\ to\ port\ scan\ the\ failure\ host[uuid\:%s,\ ip\:%s] = 扫描IP为{1}的主机端口失败 + +# at: src/main/java/org/zstack/ha/HaKvmWorker.java:96 +# args: checkers.indexOf(checker) + 1,checkers.size(),checker.getClass().getSimpleName(),s.getSuccessTimes() * s.getSuccessInterval() +(%d/%d)\ start\ HaHostChecker\ %s\:\ predict\ time\ is\ [%d]\ seconds = ({0}/{1})启动HaHostChecker{2}:预测时间为[{3}]秒 + +# at: src/main/java/org/zstack/ha/HaKvmWorker.java:160 +# args: self.getName(),self.getUuid() +cannot\ find\ the\ host\ of\ the\ vm[name\:%s,\ uuid\:%s],\ hostUuid\ is\ null = 找不到vm[name:{0}, uuid:{1}]的物理机, 因为hostUuid为null + +# at: src/main/java/org/zstack/ha/HaKvmWorker.java:167 +# args: +no\ HaHostChecker\ found,\ cannot\ do\ HA = 找不到HaHostChecker,无法执行HA + +# at: src/main/java/org/zstack/ha/HaManagementNodeChecker.java:102 +# args: +the\ management\ node\ fails\ to\ scan\ the\ host = 管理节点扫描物理机失败 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1873 +# args: vmUuid +the\ VM[uuid\:%s]\ volume\ stored\ location\ primary\ storage\ is\ in\ a\ state\ of\ maintenance = 云主机[{0}]云盘所在主存储处于维护状态 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1615 +# args: +VM\ is\ started\ successfully = 云主机已成功启动 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1618 +# args: +Failed\ to\ start\ the\ NeverStop\ VM = 无法启动NeverStop云主机 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:394 +# args: newValue +the\ value[%s]\ is\ lesser\ than\ 0\ or\ greater\ than\ 1\ = 值[{0}]小于0或大于1 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:699 +# args: HaGlobalConfig.NEVER_STOP_VM_FAILURE_RETRY_DELAY.value(Long.class) +A\ GC\ job\ is\ submitted\ to\ HA\ the\ VM[retry\ delay\:\ %s\ seconds] = 提交GC任务来高可用VM[重试间隔: {0} 秒] + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1301 +# args: +HA\ is\ successfully\ completed = HA已成功完成 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1309 +# args: +Failed\ to\ HA\ the\ VM = 高可用VM失败 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1195 +# args: +vm\ stopped\ unexpectedly,\ double\ check\ state = VM意外停止,请再次检查状态 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1204 +# args: vmUuid,hostUuid +cannot\ determine\ VM[%s]\ status\ on\ host[%s],\ try\ to\ start\ it = 无法确定物理机[{1}]上的VM[{0}]状态,尝试启动虚拟机 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1601 +# args: +vm\ state\ is\ stopped,\ try\ to\ start\ it = 云主机状态为“已停止”,尝试启动虚拟机 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1227 +# args: vmUuid,hostUuid +VM[%s]\ is\ running\ on\ host[%s] = VM[{0}]正在物理机[{1}]上运行 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1240 +# args: vmUuid,hostUuid +VM[%s]\ is\ paused\ on\ host[%s] = 物理机[{1}]上的云主机[{0}]已暂停 + +# at: src/main/java/org/zstack/ha/HaManagerImpl.java:1268 +# args: vm.getHypervisorType() +the\ hypervisor[%s]\ does\ not\ support\ VM\ HA = 当前云主机监视器(hypervisor)[{0}]不支持VM HA + +# at: src/main/java/org/zstack/ha/HostCheckResult.java:59 +# args: ratio,threshold,hostUuid,errors +[HA\ Worker]\:\ the\ success\ ratio[%s]\ below\ the\ threshold[%s],\ the\ host[uuid\:%s]\ is\ judged\ as\ dead,\ errors\ are\ %s.\ Start\ HA\ all\ the\ vms\ on\ this\ host\ before = [HA Worker]:成功率[{0}]低于阈值[{1}],物理机[uuid:{2}]被判断为死,错误为{3}。之前在此物理机上启动所有云主机的HA + +# at: src/main/java/org/zstack/ha/HostCheckResult.java:56 +# args: ratio,threshold +[HA\ worker]\:\ all\ host\ checkers\ are\ finished\ and\ the\ success\ ratio\ is\ %s\ that\ is\ greater\ than\ the\ threshold[%s];\ no\ HA\ need\ for\ the\ vms\ on\ this\ host\ before.\ Please\ wait\ for\ the\ host\ reconnected = [HA Worker]:所有物理机检查器都已完成,成功率为{0},大于阈值[{1}]。以前,此物理机上的云主机不需要HA。请等待物理机重新连接 + +# at: src/main/java/org/zstack/ha/NeverStopVmGC.java:102 +# args: +VM\ state\ is\ not\ running,\ try\ to\ start\ it = 云主机状态为未运行,尝试启动虚拟机 + +# at: src/main/java/org/zstack/header/backup/NonBackupInfo.java:14 +# args: +enter\ the\ new\ value\ here,\ empty\ means\ no\ change. = 在此输入新值,空表示不变。 + +# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:44 # args: type -cannot\ find\ nas\ factory\ for\ type\:\ %s = +keyType\ not\ supported\ type\ [%s] = KeyType不支持类型[{0}] -# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:164 -# args: f.getClass().getSimpleName(),old.getClass().getSimpleName(),f.getNasFileSystemType() -duplicate\ NasFileSystemFactory[%s,\ %s]\ for\ type[%s] = +# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:60 +# args: msg.getKey(),msg.getType(),accountUuid +key\:\ [%s]\ with\ type\:\ [%s]\ already\ existed\ by\ accountUuid\:\ [%s] = AccountUuId[{2}]已存在类型为[{1}]的项[{0}] -# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:66 -# args: msg.getL2NetworkUuid(),msg.getClusterUuid() -l2Network[uuid\:%s]\ has\ attached\ to\ cluster[uuid\:%s],\ can't\ attach\ again = 不能再次挂载l2网络[uuid:{0}],因为已经挂载到集群[uuid:{1}]上了 +# at: src/main/java/org/zstack/hybrid/account/HybridAccountApiInterceptor.java:84 +# args: msg.getKey(),accountUuid +key\:\ [%s]\ already\ existed\ by\ accountUuid\:\ [%s] = key: [{0}]已经存在于accountUuid: [{1}] -# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:75 -# args: msg.getL2NetworkUuid(),msg.getClusterUuid() -l2Network[uuid\:%s]\ has\ not\ attached\ to\ cluster[uuid\:%s] = L2网络[uuid:{0}]没有挂载到集群上[uuid:{1}] +# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:63 +# args: msg.getRegionId(),ak +regionId\ [%s]\ already\ created\ by\ ak\ [%s] = 区域ID[{0}]已经被AccessKey[{1}]创建 + +# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterApiInterceptor.java:46 +# args: type +dcType\ not\ supported\ type\ [%s] = DCType不支持类型[{0}] + +# at: src/main/java/org/zstack/hybrid/datacenter/DataCenterManagerImpl.java:96 +# args: msg.getUuid() +DataCenter\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = 区域[{0}]仍在同步进程中,请稍后 + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:55 +# args: msg.getZoneId(),izo.getUuid() +identity\ zone\ [%s]\ already\ existed,\ uuid\ is\:\ %s = 可用区[{0}]已经存在,uuid是{1} + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:72 +# args: type,dvo.getDcType().toString() +type\ [%s]\ is\ not\ matched\ datacenter\ type\ [%s] = 类型[{0}]与区域类型[{1}]不匹配 + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneApiInterceptor.java:82 +# args: +either\ dataCenterUuid\ or\ regionId\ should\ be\ set,\ please\ check\ the\ parameters. = dataCenterUuid和regionId应该被设置,请检查参数 + +# at: src/main/java/org/zstack/hybrid/identityzone/IdentityZoneManagerImpl.java:111 +# args: msg.getUuid() +IdentityZone\ [%s]\ is\ still\ in\ sync\ progress,\ please\ wait. = 可用区[{0}]仍在同步进程中,请稍后 + +# at: src/main/java/org/zstack/hybrid/network/HybridEipCascadeExtension.java:88 +# args: +EcsInstance\ must\ be\ running\ or\ stopped\ while\ deleting\ eip\ = 删除弹性IP时云主机必须时允许中或者已停止 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:83 +# args: vbri.getUuid(),vbri.getDataCenterUuid(),vrouteri.getUuid(),vrouteri.getDataCenterUuid() +router\ interface\ must\ be\ in\ the\ same\ datacenter,\ but\ ri[%s]\ is\ in\ dc[%s]\ and\ ri[%s]\ is\ in\ dc[%s] = 路由接口必须在相同的区域,但是接口[{0}]在区域[{1}]而接口[{2}]在区域[{3}] + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:93 +# args: vrouteri.getUuid(),vrouteri.getStatus() +router\ interface[%s]\ status\ is\ not\ idle,\ it\ is\ %s = 路由接口[{0}]并非闲置状态,当前状态为{1} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:101 +# args: vrouteri.getUuid(),vrouteri.getOppositeInterfaceUuid() +router\ interface[%s]\ already\ has\ a\ connection,\ it\ is\ %s = 路由接口[{0}]已经有链接{1} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:109 +# args: +accessPointUuid\ cannot\ be\ null\ if\ the\ router\ interface\ on\ VBR\ type\ router = 当路由接口的类型为VBR路由时,accessPointUuid不能为空 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:183 +# args: +cannot\ delete\ system\ entry = 不能删除系统路由条目 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:189 +# args: +only\ support\ intranet\ rule\ in\ vpc = 在VPC中仅仅支持内网规则 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:194 +# args: msg.getCidr() +%s\ is\ not\ a\ valid\ cidr = {0}是一个无效的CIDR + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:204 +# args: +security\ group\ rule\ already\ existed = 安全组已经存在了 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:210 +# args: msg.getDstCidrBlock() +dstCidrBlock[%s]\ is\ not\ a\ valid\ cidr = dstCidrBlock[{0}]是一个无效的CIDR + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:239 +# args: msg.getNextHopType() +next\ hop\ type\ [%s]\ not\ supported\ create\ route\ entry\ now! = 不支持下一个跃点类型[{0}],请立即创建路由条目! + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:235 +# args: msg.getNextHopUuid() +no\ such\ vpn\ gateway\:\ %s = 没有这样的VPN网关: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:224 +# args: rivo.getvRouterType().toString(),msg.getvRouterType() +nexthop\ routerInterface\ belongs\ to\ %s,\ but\ the\ entry\ belongs\ to\ %s = 下一跳路由接口类型是{0},但是该路由类型是{1} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:217 +# args: msg.getNextHopUuid() +no\ such\ ecs\ instance\:\ %s = 没有这样的ESC云主机: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:249 +# args: +virtual\ border\ router\ only\ support\ routerinterface\ as\ next\ hop\ type = 作为下一跳类型,虚拟边界路由只支持路由接口 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:269 +# args: msg.getCidrBlock(),vpcCidr +vswitch's\ cidr\ [%s]\ not\ in\ the\ vpc's\ [%s] = 虚拟交换机的CIDR没有在VPC[{1}]中 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:276 +# args: old.getUuid() +cidr\ is\ overlap\ by\ another\ vswitch\:\ %s = CIDR和其他的虚拟交换机{0}有重叠 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:289 +# args: msg.getCidrBlock() +invalid\ CidrBlock\:\ %s,\ which\ must\ subnet\ in\ '10.0.0.0/8',\ '172.16.0.0/12',\ '192.168.0.0/16' = 无效的CIDR块: {0},CIDR必须在10.0.0.0/8、172.16.0.0/12和192.168.0.0/16子网内 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:305 +# args: msg.getvRouterUuid() +no\ such\ virtual\ router\:\ %s = 没有这个的虚拟路由: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:300 +# args: msg.getvRouterUuid() +no\ such\ virtual\ border\ router\:\ %s = 没有这个虚拟边界路由器: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:312 +# args: msg.getLocalGatewayIp() +localGateway\ is\ not\ IPv4\:\ %s = 本地网关地址不是IPV4: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:315 +# args: msg.getPeerGatewayIp() +peerGateway\ is\ not\ IPv4\:\ %s = 对端网关地址不是IPV4: {0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:318 +# args: msg.getPeeringSubnetMask() +peerGateway\ is\ not\ subnet\ mask\:\ %s = 对端网关地址不是在子网掩码{0}中 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:322 +# args: msg.getVlanId() +vlanId\ is\ not\ number\:\ %s = vlanId不是一个数字:{0} + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:332 +# args: msg.getEcsUuid(),msg.getEipUuid(),hevo.getAllocateResourceUuid() +couldn't\ attach\ eip\ to\ ecs\:\ [%s]\ ,\ eip\ \:[%s]\ already\ attached\ ecs\:[%s]\ = 不能绑定弹性IP到ECS云主机[{0}],弹性IP[{1}]已经绑定到ECS云主机[{2}] + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:337 +# args: msg.getEcsUuid() +ecs\ [%s]\ already\ has\ public\ ip\ now = ECS云主机[{0}]已经拥有IP + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:343 +# args: msg.getEipUuid(),msg.getEcsUuid() +couldn't\ attach\ eip\ [%s]\ to\ ecs\:\ [%s]\ ,\ ecs\ is\ already\ attached = 不能绑定弹性IP[{0}]到ECS云主机[{1}],ECS云主机已经绑定了弹性IP + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:350 +# args: msg.getEipUuid(),msg.getEcsUuid() +eip[%s]\ and\ ecs[%s]\ should\ be\ in\ the\ same\ dataCenter\ = 弹性IP[{0}]和ECS云主机[{1}]应该在同一个区域 + +# at: src/main/java/org/zstack/hybrid/network/HybridNetworkApiInterceptor.java:359 +# args: msg.getEipUuid() +couldn't\ detach\ eip\ \:[%s],\ it\ is\ not\ attached\ on\ any\ instance\ = 不能解绑弹性IP[{0}],因为它没有绑定任何云主机 + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:45 +# args: msg.getId() +%s\ is\ not\ a\ valid\ ipv4\ address = {0}是一个无效的IPV4地址 + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:51 +# args: +localCidr\ must\ be\ Cidr! = 本地CIDR必须是CIDR + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:55 +# args: +remoteCidr\ must\ be\ Cidr! = 远程CIDR必须是CIDR + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnApiInterceptor.java:62 +# args: +localCidr\ and\ remoteCidr\ must\ be\ Cidr! = 本地CIDR和远程CIDR必须是CIDR + +# at: src/main/java/org/zstack/hybrid/network/vpn/VpcVpnGatewayCascadeExtension.java:80 +# args: gateways.get(0).getUuid() +vpngateway\ [%s]\ existed,\ cannot\ delete\ remote = VPN网关[{0}]已经存在,不能删除远程的 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:343 +# args: oldSession.getUserUuid() +The\ user[%s]\ is\ not\ a\ platform\ user = 用户[{0}]不是平台用户 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:994 +# args: results.size() +There\ are\ %d\ problems\ with\ the\ file.\ = 文件中包含{0}个错误 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1011 +# args: e.getMessage() +fail\ to\ load\ VirtualID\ info\ from\ file.\ because\n%s = 解析文件内容出错,{0} + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1022 +# args: +name\ cannot\ be\ empty.\ = 名称不能为空 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1030 +# args: cmsg.getUsername() +userName[%s]\ is\ repeated.\ = 用户名[{0}]重复 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1028 +# args: cmsg.username.length() +name\ exceeds\ max\ length\ of\ string.\ expected\ was\ <\=\ 255,\ actual\ was\ %s.\ = 名称字符数量不能超过255 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1026 +# args: +username\ cannot\ be\ empty.\ = 用户名不能为空 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1036 +# args: cmsg.password.length() +Incorrect\ password\ length.\ expected\ was\ >\=\ 6\ and\ <\=\ 255,\ actual\ was\ %s.\ = 密码长度错误,应该大于等于6个字符,小于等于255字符 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1034 +# args: +password\ cannot\ be\ empty.\ = 密码不能为空 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1044 +# args: +email\ format\ does\ not\ match.\ = 邮箱格式错误 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1100 +# args: noMatchNames +organization[%s]\ is\ not\ exist.\ = 部门[{0}]不存在 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1108 +# args: repeatNames +organization[%s]\ in\ line\ is\ repeated.\ = 部门[{0}]出现重复 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1116 +# args: repeatNames +organization[%s]\ is\ repeated.\ = 部门[{0}]出现重复 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1146 +# args: noMatchName +project[%s]\ is\ not\ exist.\ = 项目[{0}]不存在 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1340 +# args: +fail\ to\ build\ VirtualID\ info\ from\ file.\ = 不能解析文件内容 + +# at: src/main/java/org/zstack/iam2/IAM2ManagerImpl.java:1469 +# args: resourceUuid,projectUuid +virtualID[uuid\:%s]\ not\ in\ project[uuid\:%s] = VirtualID[uuid:{0}]不在项目[uuid:{1}]中 + +# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:144 +# args: self.getUuid() +Can\ not\ do\ operations,\ because\ current\ organization[uuid\:%s]\ is\ staled,\ please\ enable\ it = 无法进行操作,因为当前组织[uuid:{0}]已过时,请启用该组织 + +# at: src/main/java/org/zstack/iam2/IAM2OrganizationBase.java:688 +# args: puuid,self.getUuid() +organization[uuid\:%s]\ is\ parent\ of\ the\ organization[uuid\:%s],\ cannot\ set\ it\ as\ a\ child\ organization = 部门[uuid:{0}]是部门[uuid:{1}]的上级部门,无法被设置为子部门 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectBase.java:130 +# args: self.getUuid(),self.getName(),self.getState(),msg.getClass() +the\ project[uuid\:\ %s,\ name\:%s]\ is\ in\ state\ of\ %s\ which\ disallows\ the\ operation[%s] = 项目[[uuid: {0}, 名称:{1}]]是{2}状态,不允许执行[{3}]操作 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectBase.java:910 +# args: +can\ not\ parse\ the\ cron\ expression = 无法分析Cron表达式 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:43 +# args: loginContext.getUsername() +project[name\:%s]\ not\ existing = 项目[name:{0}]不存在 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:51 +# args: puuid,loginContext.getUsername() +no\ account\ found\ for\ project[uuid\:%s,\ name\:%s] = 未找到项目[uuid:{0},名称:{1}]的帐户 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:57 +# args: loginContext.getOperatorSession().getUserUuid() +wrong\ virtual\ ID[uuid\:%s],\ not\ existing\ or\ wrong\ password = 错误的virtual ID[uuid:{0}], 密码不存在或者密码错误 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:62 +# args: vid.getName() +virtual\ ID[name\:%s]\ is\ disabled = virtual ID[名称:{0}]不可用 + +# at: src/main/java/org/zstack/iam2/IAM2ProjectLoginBackend.java:72 +# args: vid.getName(),loginContext.getUsername() +virtual\ ID[name\:%s]\ not\ belonging\ to\ the\ project[name\:%s] = virtual ID[名称:{0}]不属于项目[name:{1}] + +# at: src/main/java/org/zstack/iam2/IAM2QuotaUpdateChecker.java:75 +# args: quota.getName(),quota.getIdentityUuid(),updatedValue,organizationUuid +the\ quota[name\:%s]\ of\ Account[uuid\:%s]\ can\ not\ be\ %d,\ otherwise\ it\ will\ exceeds\ the\ quota\ of\ organization[uuid\:%s] = 帐户[uuid:{1}]的配额[名称:{0}]不能为{2},否则将超过组织[uuid:{3}]的配额 + +# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:256 +# args: self.getUuid() +Can\ not\ do\ operations,\ because\ Current\ virtualID[uuid\:%s]\ is\ staled,\ please\ enable\ it = 无法执行操作,因为当前VirtualID[uuid:{0}]已过时,请启用它 + +# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:649 +# args: +only\ admin\ and\ the\ virtual\ ID\ itself\ can\ do\ the\ update = 只有admin和virtual ID本身可以执行更新操作 + +# at: src/main/java/org/zstack/iam2/IAM2VirtualIDBase.java:653 +# args: msg.getVirtualIDUuid() +old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ virtual\ ID[uuid\:%s] = 旧密码不等于原始密码,无法更新虚拟ID[uuid:{0}]的密码 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:50 +# args: attr.getValue() +attribute\ name\ cannot\ be\ null,\ value[%s] = 属性不能为null,输入值[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:54 +# args: attr.getName() +attribute\ name[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = 属性名称[{0}]不能超过2048个字符 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:57 +# args: attr.getName(),attr.getValue() +attribute[name\:%s]\ value[%s]\ exceed\ the\ max\ length\ of\ 2048\ chars = 属性[name:{0}] value[{1}]不能超过2048个字符 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:173 +# args: msg.getOrganizationUuid(),msg.getName(),projectUsed,msg.getValue() +The\ Organization[uuid\:\ %s]\ used\ [name\:\ %s,\ usedValue\:\ %s]\ exceeds\ Request\:%s. = 组织[uuid:{0}]使用的[名称:{1},UsedValue:{2}]超出请求:{3}。 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:186 +# args: msg.getLoginExpired() +%s\ is\ not\ a\ valid\ value.\ Valid\ values\ are\ \ allow/rejection\ \ xxx\ to\ xxx = {0}不是有效值。有效值为允许/拒绝XXX至XXX + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:192 +# args: msg.getUuid() +The\ default\ organization[%s]\ cannot\ be\ deleted = 无法删除默认组织[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:201 +# args: msg.getName() +duplicate\ template\ name[%s] = 重复的模板名称[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:652 +# args: IAM2RolePolicyStatementHelper.PROJECT_ADMIN_ROLE_NAME +illegal\ operation,\ cannot\ add\ Role[%s] = 非法操作,无法添加角色[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:265 +# args: +admin\ is\ a\ reserved\ name,\ please\ use\ another\ name = admin是保留名称,请使用其他名称 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:273 +# args: msg.getName() +invalid\ name[%s],\ there\ has\ been\ a\ project\ or\ account\ with\ the\ same\ name = 无效的名称[{0}],已经存在同名的项目或账户 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:281 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ group = 属性[uuid:{0}]不适用于任何组 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:289 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ organization = 属性[uuid:{0}]不适用于任何组织 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:297 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ project = 属性[uuid:{0}]不适用于任何项目 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:305 +# args: msg.getUuid() +attribute[uuid\:%s]\ is\ not\ for\ any\ virtual\ ID = 属性[uuid:{0}]不适用于任何虚拟ID + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:325 +# args: +retire\ policy\ must\ be\ deleted\ before\ pull\ the\ project\ out\ of\ Retired\ state = 在将项目从已停用状态拉出之前,必须删除停用策略 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:337 +# args: state +login\ is\ prohibited\ because\ the\ project\ is\ in\ state\ of\ %s = 禁止登录,因为项目处于{0}状态 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:347 +# args: name +no\ quota[name\:%s]\ found = 未找到配额[名称:{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:371 +# args: msg.getUuid() +organization[uuid\:%s]\ is\ a\ Company\ that\ cannot\ have\ parent\ organization = 组织[uuid:{0}]是不能有上级组织的公司 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:381 +# args: msg.getUuid(),msg.getParentUuid() +parent\ organization[uuid\:%s]\ cannot\ be\ a\ child\ organization[uuid\:%s]\ of\ a\ childOrganization = 父组织[uuid:{0}]不能是子组织[uuid:{1}]的子组织 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:400 +# args: msg.getName() +duplicate\ virtualID\ name[%s] = 重复的用户名[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:418 +# args: msg.getName() +duplicate\ project\ name[%s] = 重复的项目名[{0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:426 +# args: msg.getName() +invalid\ project\ name[%s],\ an\ account\ or\ project\ with\ the\ same\ name\ exists = 无效的项目名[{0}],已有账户或项目使用了相同的名称 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:432 +# args: msg.getOrganizationUuid() +IAM2OrganizationVO[uuid\:%s]\ is\ not\ exists = Iam2OrganizationVO[uuid:{0}]不存在 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:515 +# args: refVO.getProjectUuid(),refVO.getOrganizationUuid() +The\ project[uuid\=%s]\ has\ been\ attached\ to\ the\ organization[uuid\=%s] = 项目[uuid={0}]已附加到组织[uuid={1}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:557 +# args: msg.getProjectUuid() +The\ project[uuid\=%s]\ is\ not\ attached = 未附加项目[uuid={0}] + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:568 +# args: uuids +organizations%s\ are\ company\ that\ cannot\ be\ children\ of\ other\ organization = 组织{0}类型是子公司,不能设置为其它组织的部门 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:582 +# args: msg.getVirtualIDUuid(),msg.getProjectUuid() +virtual\ id[uuid\:\ %s]\ is\ not\ in\ project[uuid\:\ %s] = 虚拟ID[uuid:{0}]不在项目[uuid:{1}]中 + +# at: src/main/java/org/zstack/iam2/api/IAM2ApiInterceptor.java:679 +# args: staleVirtualIDs +can\ not\ operate\ stale\ virtual\ ids\:\ %s = 无法操作无效的用户: {0} + +# at: src/main/java/org/zstack/iam2/attribute/SystemAttributes.java:69 +# args: +attribute[name\:%s]\ is\ a\ system\ attribute\ that\ cannot\ be\ updated = 属性[名称:{0}]是一个系统属性,无法被更新 + +# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:38 +# args: inv.getValue() +virtual\ ID[uuid\:%s]\ not\ existing = 用户[uuid:{0}]不存在 + +# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:45 +# args: inv.getValue(),((IAM2OrganizationAttributeInventory) inv).getOrganizationUuid() +virtual\ ID[uuid\:%s]\ not\ in\ organization[uuid\:%s] = 虚拟ID[uuid:{0}]不在组织中[uuid:{1}] + +# at: src/main/java/org/zstack/iam2/attribute/organization/OrganizationSupervisor.java:50 +# args: oinv.getOrganizationUuid() +organization[uuid\:%s]\ already\ has\ a\ supervisor = 组织[uuid:{0}]已经设置了负责人 + +# at: src/main/java/org/zstack/iam2/attribute/project/LoginExpired.java:58 +# args: pinv.getUuid(),pinv.getName() +the\ project[uuid\:%s,\ name\:%s]\ already\ has\ a\ login\ expired\ strategy = 项目[uuid:{0},名称:{1}]已有登录过期策略 + +# at: src/main/java/org/zstack/iam2/attribute/project/LoginExpired.java:109 +# args: projectUuid,ProjectState.Enabled.toString() +IAM2ProjectVO[uuid\:%s]\ is\ not\ %s,\ state\ change\ is\ not\ allowed = Iam2ProjectVO[uuid:{0}]不是{1},不允许更改状态 + +# at: src/main/java/org/zstack/iam2/attribute/project/Retire.java:65 +# args: pinv.getUuid(),pinv.getName() +the\ project[uuid\:%s,\ name\:%s]\ already\ has\ a\ retire\ policy = 项目[uuid:{0}, name:{1}]已经设置了回收策略 + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:53 +# args: +invalid\ value,\ no\ 'at',\ 'after'\ or\ 'exceed'\ found = 无效的值,找不到关键字no 'at', 'after' or 'exceed' + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:58 +# args: value +invalid\ value,\ %s = 无效的值, {0} + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:64 +# args: ss[0],Arrays.asList(Means.values()).toString() +invalid\ means[%s],\ allowed\ means\ are\ %s = 无效的回收方法[{0}],允许的方法是{1} + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:100 +# args: policyValue +invalid\ spending\ value[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10.001 = 无效的费用[{0}], 费用格式应该符合例如:10.001 + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:94 +# args: policyValue,Double.MAX_VALUE +invalid\ spending\ value[%s],\ spending\ value\ should\ between\ 0\ and\ %f = 无效的费用[{0}], 费用范围应该在0到{1}之间 + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:87 +# args: policyValue +invalid\ time[%s],\ it\ should\ be\ in\ format\ of\ for\ example\ 10m,\ 1h,\ 2d = 无效的时间[{0}],时间格式需要符合例如:10m, 1h, 2d + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:78 +# args: policyValue +invalid\ date[%s],\ it\ should\ be\ in\ format\ of\ yyyy-MM-dd\ HH\:mm\:ss = 无效的日期,日期格式需要符合:yyyy-MM-dd HH:mm:ss + +# at: src/main/java/org/zstack/iam2/attribute/project/RetirePolicy.java:107 +# args: policyValue,dateFormat.format(new Timestamp(System.currentTimeMillis())) +invalid\ date\ or\ time[%s],\ it\ cannot\ be\ before\ current\ time[%s] = 无效的日期或时间,回收时间不能在当前时间之前[{1}] + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/AbstractAdminAttribute.java:17 +# args: vid,attributeName +virtual\ ID[uuid\:%s]\ already\ has\ admin\ related\ attributes,\ can\ not\ add\ %s = 用户[uuid:{0}]已经有管理员属性了,无法继续添加属性{1} + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/IAM2OrganizationOperator.java:29 +# args: inv.getValue(),IAM2_ORGANIZATION_OPERATION.getName() +organiztion\ ID[uuid\:%s]\ already\ has\ opoeration\ attributes,\ can\ not\ add\ %s = 组织ID[uuid:{0}]已具有Poeration属性,无法添加{1} + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/IAM2ProjectOperator.java:35 +# args: idinv.getVirtualIDUuid() +virtual\ id[uuid\:%s]\ already\ has\ a\ project\ operator\ attribute = 虚拟ID[uuid:{0}]已具有项目运算符属性 + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/PlatformAdminZoneRelation.java:36 +# args: inv.getValue() +cannot\ find\ zone[uuid\:%s] = 找不到区域[uuid:{0}] + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:71 +# args: inv.getValue() +project[uuid\:%s]\ already\ has\ a\ project\ admin = 项目[uuid:{0}]已经设置过项目管理员了 + +# at: src/main/java/org/zstack/iam2/attribute/virtualid/ProjectAdmin.java:83 +# args: inv.getValue() +project[uuid\:%s]\ not\ existing = 项目[uuid:{0}]不存在 + +# at: src/main/java/org/zstack/iam2/rbac/IAM2AuthorizationBackend.java:133 +# args: deniedApis +the\ operations[%s]\ is\ denied = 操作[{0}]被拒绝 + +# at: src/main/java/org/zstack/iam2/rbac/IAM2OperationTargetAPIRequestChecker.java:114 +# args: +since\ the\ project\ starts\ the\ force\ securityGroup,\ systemtag\ is\ required\ for\ VM\ operation = 由于项目启动了Force SecurityGroup,因此VM操作需要SystemTag + +# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:28 +# args: session.getAccountUuid() +project\ of\ account[uuid\:%s]\ not\ exists = 账户为[uuid:{0}]的项目不存在 + +# at: src/main/java/org/zstack/iam2/rbac/IAM2SessionAPIRequestChecker.java:37 +# args: projectUuid +project[uuid\:%s]\ is\ retired,\ reject\ all\ operations = 项目[uuid:{0}]已经过期,无法操作 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:107 +# args: +system\ tag\ requested.\ need\ specify\ default\ security\ group\ for\ vm\ nic\ by\ system\ tag\ L3_NETWORK_SECURITY_GROUP_uuidS_REF\ with\ format\ l3\:\:{%s}\:\:SecurityGroupUuids\:\:{%s},\ because\ force\ security\ group\ is\ enabled = 已请求系统标记。需要按系统标记L为VM NIC指定默认安全组3_网络_安全_组_uuid_引用,格式为L3:{0}:SecurityGroupUUIds:{1},因为启用了强制安全组 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:114 +# args: l3Uuid,msg.getL3NetworkUuid() +the\ l3Uuid[%s]\ in\ the\ label\ is\ inconsistent\ with\ the\ l3Uuid[%s]\ in\ the\ parameter = 标签中的L3uuid[{0}]与参数中的L3uuid[{1}]不一致 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:124 +# args: projectUuid +since\ force\ security\ group\ is\ enabled,\ securityGroupUuid\ in\ the\ tag\ must\ be\ in\ the\ project[%s] = 由于启用了强制安全组,因此标记中的SecurityGroupuuid必须在项目[{0}]中 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:145 +# args: msg.getL3NetworkUuid(),msg.getSecurityGroupUuid() +nics\ on\ the\ l3Network[uuid\:%s]\ are\ attached\ to\ the\ securityGroup.\ before\ you\ can\ detach\ the\ l3Network\ from\ the\ securityGroup,\ you\ need\ to\ detach\ the\ nics\ from\ the\ securityGroup. = 三层网络[uuid:{0}]上的NIC已连接到SecurityGroup。在将L3Network与SecurityGroup分离之前,需要将NIC与SecurityGroup分离。 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:161 +# args: msg.getUuid() +the\ default\ security\ group\ %s\ cannot\ be\ deleted\ by\ enabling\ the\ enforced\ security\ group\ function = 无法通过启用强制安全组功能来删除默认安全组{0} + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:165 +# args: msg.getUuid() +this\ security\ group\ %s\ is\ bound\ to\ vm,\ please\ try\ again\ after\ unbinding = 此安全组{0}已绑定到VM,请在解除绑定后重试 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:175 +# args: sessionInventory.getAccountUuid(),securityGroupUuid +account[%s]\ cannot\ operation\ the\ default\ securityGroup[%s] = 帐户[{0}]无法操作默认SecurityGroup[{1}] + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:187 +# args: msg.getSession().getAccountUuid() +account[%s]\ not\ allowed\ to\ operate\ on\ default\ securityGroup = 不允许帐户[{0}]对默认的SecurityGroup进行操作 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupApiInterceptor.java:241 +# args: refVOS.stream().map(VmNicSecurityGroupRefVO::getVmNicUuid).collect(Collectors.joining(",")),msg.getSecurityGroupUuid() +vm's\ nic[uuid\:%s]\ only\ has\ one\ security\ group,\ can\ not\ delete\ the\ nic\ from\ security\ group[uuid\:%s] = VM的NIC[uuid:{0}]只有一个安全组,无法从安全组[uuid:{1}]中删除NIC + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupFactory.java:60 +# args: projectUuid +can't\ find\ the\ quota\ for\ the\ security\ group\ for\ the\ corresponding\ project\ %s = 找不到对应项目{0}的安全组的配额 + +# at: src/main/java/org/zstack/iam2/securitygroup/IAM2ProjectSecurityGroupFactory.java:64 +# args: +security\ group\ quota\ cannot\ less\ than\ 1 = 安全组配额不能小于1 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:35 +# args: +The\ iam2\ script\ function\ is\ not\ enabled. = 未启用IAM2脚本函数。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:39 +# args: +Script\ doesn't\ have\ any\ content. = 脚本没有任何内容。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:45 +# args: +The\ amount\ of\ params\ exceeds\ the\ limit. = 参数数量超过限制。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptInterceptor.java:61 +# args: +Specified\ script\ executor\ are\ not\ supported. = 不支持指定的脚本执行程序。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:139 +# args: +Decode\ script\ content\ failed. = 解码脚本内容失败。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:147 +# args: +Script\ content\ is\ blank. = 脚本内容为空。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:179 +# args: +Run\ iam2\ script\ failed. = 运行IAM2脚本失败。 + +# at: src/main/java/org/zstack/iam2script/IAM2ScriptManagerImpl.java:244 +# args: +Cannot\ read\ the\ result\ of\ the\ script\ running. = 无法读取脚本运行的结果。 + +# at: src/main/java/org/zstack/identity/AccountBase.java:327 +# args: group.getUuid(),msg.getAccountUuid() +the\ user\ group[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = 这个用户组[uuid:{0}]不属于当前账户[uuid:{1}] + +# at: src/main/java/org/zstack/identity/AccountBase.java:528 +# args: self.getUuid(),ruuid +the\ account[uuid\:\ %s]\ doesn't\ have\ a\ resource[uuid\:\ %s] = 账户[uuid: {0}]没有资源[uuid: {1}] + +# at: src/main/java/org/zstack/identity/AccountBase.java:590 +# args: user.getUuid(),msg.getAccountUuid() +the\ user[uuid\:%s]\ does\ not\ belong\ to\ the\ account[uuid\:%s] = 当前用户[uuid:{0}]不属于当前账户[uuid:{1}] + +# at: src/main/java/org/zstack/identity/AccountBase.java:595 +# args: user.getUuid() +old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ user[uuid\:%s] = 旧密码不等于原始密码,无法更新用户[uuid:{0}]的密码 + +# at: src/main/java/org/zstack/identity/AccountInterceptor.java:55 +# args: +wrong\ password = 密码错误 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1660 +# args: JSONObjectUtil.toJsonString(s) +a\ statement\ must\ have\ effect\ field.\ Invalid\ statement[%s] = 声明必须含有'effect'字段。 无效的声明 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1663 +# args: JSONObjectUtil.toJsonString(s) +a\ statement\ must\ have\ action\ field.\ Invalid\ statement[%s] = 声明必须含有'action'字段。 无效的声明 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1666 +# args: JSONObjectUtil.toJsonString(s) +a\ statement\ must\ have\ a\ non-empty\ action\ field.\ Invalid\ statement[%s] = 声明必须含有不为空的'action'字段。 无效的声明 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:175 +# args: resourceUuid +cannot\ find\ the\ resource[uuid\:%s];\ wrong\ resourceUuid\ or\ the\ resource\ is\ admin\ resource = 无法找到资源[uuid:{0}]: 错误的资源uuid或者资源是管理员资源 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:405 +# args: msg.getUserUuid() +the\ user\ specified\ by\ the\ userUuid[%s]\ does\ not\ belong\ to\ the\ current\ account,\ and\ the\ current\ account\ is\ not\ an\ admin\ account,\ so\ it\ has\ no\ permission\ to\ check\ the\ user'spermissions = 当前通过userUuid获得的user不属于当前账户,而且当前账户不是管理员账户 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1055 +# args: accountUuid +cannot\ find\ the\ account[uuid\:%s] = 找不到账户[uuid:{0}] + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1495 +# args: +accountName\ and\ accountUuid\ cannot\ both\ be\ null,\ you\ must\ specify\ at\ least\ one = accountName和accountUuid不能同时为空,您必须定义至少一个 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1506 +# args: msg.getName(),msg.getAccountUuid() +unable\ to\ create\ a\ group.\ A\ group\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = 不能创建用户组,用户组“{0}”已经在账户“{0}”下了 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1516 +# args: msg.getName(),msg.getAccountUuid() +unable\ to\ create\ a\ user.\ A\ user\ called\ %s\ is\ already\ under\ the\ account[uuid\:%s] = 不能创建用户,用户“{0}”已经在账户“{0}”下了 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1525 +# args: msg.getName() +unable\ to\ create\ an\ account.\ An\ account\ already\ called\ %s = 不能创建账户,“{0}”已经被使用 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1532 +# args: +account\ cannot\ delete\ itself = 账户不能删除自己 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1538 +# args: +cannot\ delete\ builtin\ admin\ account. = 无法删除内置管理员帐户。 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1544 +# args: +Only\ admin\ can\ delete\ account. = 只有admin能删除账户 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1552 +# args: +the\ current\ session\ is\ an\ account\ session.\ You\ need\ to\ specify\ the\ field\ 'uuid'\ of\ the\ user\ you\ want\ to\ update = 当前会话是一个账户会话,你需要定义一个'uuid'字段来指定你要更新的用户 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1567 +# args: msg.getUuid() +your\ are\ login\ as\ a\ user,\ you\ cannot\ another\ user[uuid\:%s] = 你已经登录为一个用户,不能成为另一个用户[uuid:{0}] + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1575 +# args: +all\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = all参数被设为false时,账户uuid不能为空 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1583 +# args: +toPublic\ is\ set\ to\ false,\ accountUuids\ cannot\ be\ null\ or\ empty = toPublic参数被设为false时,账户uuid不能为空 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1632 +# args: policy.getName(),policy.getUuid(),msg.getSession().getAccountUuid() +policy[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = 策略[名称: {0}, uuid: {1}]不属于账户[uuid: {2}] + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1646 +# args: user.getName(),user.getUuid(),msg.getSession().getAccountUuid() +user[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = 用户[名称: {0}, uuid: {1}]不属于账户[uuid: {2}] + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1650 +# args: group.getName(),group.getUuid(),msg.getSession().getAccountUuid() +group[name\:\ %s,\ uuid\:\ %s]\ doesn't\ belong\ to\ the\ account[uuid\:\ %s] = 用户组[名称: {0}, uuid: {1}]不属于账户[uuid: {2}] + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1691 +# args: msg.getName() +unable\ to\ update\ name.\ An\ account\ already\ called\ %s = 无法更新名称。已有一个名为{0}的帐户 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1702 +# args: msg.getUuid() +old\ password\ is\ not\ equal\ to\ the\ original\ password,\ cannot\ update\ the\ password\ of\ account[uuid\:\ %s] = 旧密码不等于原始密码,无法更新帐户[uuid:{0}]的密码 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1707 +# args: +the\ name\ of\ admin\ account\ cannot\ be\ updated = 不能更改管理员账户名称 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1713 +# args: +only\ admin\ account\ can\ update\ it's\ password = 只有管理员帐户才能更新其密码 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1720 +# args: account.getUuid(),account.getName(),msg.getUuid() +account[uuid\:\ %s,\ name\:\ %s]\ is\ a\ normal\ account,\ it\ cannot\ reset\ the\ password\ of\ another\ account[uuid\:\ %s] = [uuid: {0}, 名称: {1}]是一个普通账户,不能被其他普通账户重设密码 + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1731 +# args: msg.getName(),msg.getIdentityUuid() +cannot\ find\ Quota[name\:\ %s]\ for\ the\ account[uuid\:\ %s] = 无法为当前账户[uuid: {1}]找到Quota + +# at: src/main/java/org/zstack/identity/AccountManagerImpl.java:1738 +# args: quota.getIdentityUuid(),quota.getIdentityType() +can\ not\ find\ quota\ update\ checker\ for\ quota[uuid\:%s,\ type\:%s] = 找不到配额[uuid:{0},类型:{1}]的配额更新检查器 + +# at: src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java:32 +# args: quota.getName(),quota.getIdentityUuid(),updatedValue +the\ quota[name\:%s]\ of\ account[uuid\:%s]\ can\ not\ be\ %d = 帐户[uuid:{1}]的配额[名称:{0}]不能为{2} + +# at: src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java:54 +# args: accountUuid,quotaName,used,updatedValue +the\ account[uuid\:%s]\ used\ [name\:%s,\ usedValue\:%s]\ exceeds\ request\ quota\:\ %d = 帐户[uuid:{0}]使用的[名称:{1},UsedValue:{2}]超过了请求配额:{3} + +# at: src/main/java/org/zstack/identity/login/LoginManagerImpl.java:46 +# args: loginType +unsupported\ login\ type\ %s = 不支持的登录类型{0} + +# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:180 +# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),uuid,resourceType.getSimpleName() +permission\ denied,\ the\ account[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ resource[uuid\:%s,\ type\:%s] = 操作错误,账户[uuid:{0}]不是资源[uuid:{1}, type:{2}]的所有者 + +# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:228 +# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),uuid,type +permission\ denied,\ the\ account[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ tagged\ resource[uuid\:%s,\ type\:%s] = 权限被拒绝,帐户[uuid:{0}]不是已标记资源[uuid:{1},类型:{2}]的所有者 + +# at: src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java:251 +# args: rbacEntity.getApiMessage().getSession().getAccountUuid(),resourceWithNoAccess,resourceType.getSimpleName() +the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resources[uuid\:%s,\ type\:%s] = 账户[uuid:{0}]无法使用资源[uuid:{1}, type:{2}] + +# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:80 +# args: rbacEntity.getApiMessage().getClass().getName() +operation[API\:%s]\ is\ denied\ by\ default,\ please\ contact\ admin\ to\ correct\ it = 默认情况下拒绝操作[API:{0}],请与管理员联系以更正 + +# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:187 +# args: p.getName(),p.getUuid() +the\ operation\ is\ denied\ by\ the\ policy[name\:%s\ uuid\:%s] = 操作被策略[名称:{0}uuid:{1}]拒绝 + +# at: src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java:200 +# args: p.getName(),p.getUuid(),fname +the\ operation\ is\ denied\ by\ the\ policy[name\:%s,\ uuid\:%s],\ field[%s]\ is\ not\ permitted\ to\ set = 策略[名称:{0},uuid:{1}]拒绝该操作,不允许设置字段[{2}] + +# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:92 +# args: +cannot\ update\ a\ system\ or\ predefined\ role = 无法更新系统角色或预定义角色 + +# at: src/main/java/org/zstack/identity/rbac/RBACApiInterceptor.java:108 +# args: +cannot\ delete\ a\ system\ or\ predefined\ role = 无法删除系统角色或预定义角色 + +# at: src/main/java/org/zstack/image/AddImageLongJob.java:187 +# args: +Failed\ because\ management\ node\ restarted. = 失败,因为管理节点已重新启动。 + +# at: src/main/java/org/zstack/image/BackupStorageDeleteBitGC.java:35 +# args: backupStorageUuid,bsStatus +the\ backup\ storage[uuid\:%s]\ is\ not\ in\ status\ of\ Connected,\ current\ status\ is\ %s = 镜像服务器[uuid:{0}]不是Connected状态,当前状态为{1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:101 +# args: +The\ aarch64\ architecture\ does\ not\ support\ legacy. = AARCH64体系结构不支持旧版。 + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:108 +# args: vol.getUuid(),vol.getStatus() +volume[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = 云盘[uuid:{0}]未Ready,它现在为{1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:112 +# args: vol.getUuid(),vol.getState() +volume[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = 云盘[uuid:{0}]未Enabled,它现在为{1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:119 +# args: vsvo.getUuid(),vsvo.getStatus() +volume\ snapshot[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = 卷快照[uuid:{0}]未就绪,它是{1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:123 +# args: vsvo.getUuid(),vsvo.getState() +volume\ snapshot[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = 卷快照[uuid:{0}]未启用,它是{1} + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:142 +# args: +ISO\ cannot\ be\ used\ as\ system\ image = ISO不能被作为一个系统标签 + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:148 +# args: msg.getFormat() +unknown\ format[%s] = 未知格式[{0}] + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:152 +# args: msg.getType() +unsupported\ image\ type[%s] = 不支持的镜像类型[{0}] + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:169 +# args: msg.getBackupStorageUuids(),BackupStorageStatus.Connected,BackupStorageState.Enabled +no\ backup\ storage\ specified\ in\ uuids%s\ is\ available\ for\ adding\ this\ image;\ they\ are\ not\ in\ status\ %s\ or\ not\ in\ state\ %s,\ or\ the\ uuid\ is\ invalid\ backup\ storage\ uuid = 镜像服务器uuids{0}不满足添加镜像的条件;它们的状态不同时满足{1}和{2},亦或者是无效的uuid + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:180 +# args: +url\ must\ starts\ with\ 'file\:///',\ 'http\://',\ 'https\://',\ 'ftp\://',\ 'sftp\://'\ or\ '/' = url必须以下列格式开头'file:///', 'http://', 'https://', 'ftp://', 'sftp://' or '/' + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:191 +# args: path +absolute\ path\ must\ be\ used = 必须使用绝对路径 + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:214 +# args: path,blackList.value() +image\ path\ [%s]\ is\ in\ black\ list\ %s = 镜像路径[{0}]在黑名单{1}中 + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:223 +# args: +all\ images\ on\ this\ server\ cannot\ be\ used = 无法使用此服务器上的所有镜像 + +# at: src/main/java/org/zstack/image/ImageApiInterceptor.java:228 +# args: whiteList.value() +image\ path\ is\ not\ in\ white\ list\:\ %s = 镜像路径不在白名单中:{0} + +# at: src/main/java/org/zstack/image/ImageBase.java:214 +# args: self.getUuid(),self.getName() +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ any\ backup\ storage = 镜像[uuid:{0}, 名称:{1}]不在任一镜像服务器上 + +# at: src/main/java/org/zstack/image/ImageBase.java:224 +# args: self.getUuid(),self.getName() +No\ connected\ backup\ storage\ found\ for\ image[uuid\:%s,\ name\:%s] = 在所有 Connected 状态的镜像服务器上都找不到镜像[uuid:{0}, name:{1}] + +# at: src/main/java/org/zstack/image/ImageBase.java:416 +# args: msg.getImageUuid(),JSONObjectUtil.toJsonString(errors) +detach\ iso[uuid\=%s]\ from\ vm\ failed,\ errors\ are\ %s = 从VM分离ISO[uuid={0}]失败,错误为{1} + +# at: src/main/java/org/zstack/image/ImageBase.java:782 +# args: self.getUuid(),self.getName(),bsUuid +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ on\ the\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}, 名称:{1}]不在镜像服务器[uuid:{2}]上 + +# at: src/main/java/org/zstack/image/ImageBase.java:724 +# args: self.getUuid(),self.getName(),ref.getStatus(),bsUuid +the\ image[uuid\:%s,\ name\:%s]'s\ status[%s]\ is\ not\ Deleted\ on\ the\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}, 名称:{1}]的状态[{2}]在镜像服务器[uuid:{3}]上不是Deleled + +# at: src/main/java/org/zstack/image/ImageBase.java:766 +# args: self.getUuid(),self.getName() +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ any\ backup\ storage = 镜像[uuid:{0}, 名称:{1}]未在任一镜像服务器上被删除 + +# at: src/main/java/org/zstack/image/ImageBase.java:787 +# args: self.getUuid(),self.getName(),bsUuid +the\ image[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ on\ the\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}, 名称:{1}]未在镜像服务器[uuid:{2}]上被删除 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:812 +# args: bootModeCount +only\ one\ bootMode\ system\ tag\ is\ allowed,\ but\ %d\ got = 只允许一个Bootmode系统标记,但{0}获得了 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:830 +# args: bootMode,systemTag +[%s]\ specified\ in\ system\ tag\ [%s]\ is\ not\ a\ valid\ boot\ mode = 系统标记[{1}]中指定的[{0}]不是有效的启动模式 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1455 +# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) +unable\ to\ allocate\ backup\ storage\ specified\ by\ uuids%s,\ list\ errors\ are\:\ %s = 不能根据[uuids:{0}]分配镜像服务器,错误清单为: {1} + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1581 +# args: rootVolumeUuid +failed\ to\ create\ image\ from\ root\ volume[uuid\:%s]\ on\ all\ backup\ storage,\ see\ cause\ for\ one\ of\ errors = 在所有镜像服务器上从云盘[uuid:{0}]创建镜像失败,查看错误原因 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1809 +# args: msgData.getBackupStorageUuids(),JSONObjectUtil.toJsonString(errs) +failed\ to\ allocate\ all\ backup\ storage[uuid\:%s],\ a\ list\ of\ error\:\ %s = 镜像服务器[uuid:{0}]分配失败,错误清单:{1} + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1779 +# args: +cannot\ find\ proper\ backup\ storage = 找不到适当的备份存储 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1922 +# args: volumeUuid,msgData.getBackupStorageUuids() +failed\ to\ create\ data\ volume\ template\ from\ volume[uuid\:%s]\ on\ all\ backup\ storage%s.\ See\ cause\ for\ one\ of\ errors = 在所有镜像服务器[uuid:{1}]上创建云盘[uuid:{0}]的云盘模版失败,查看错误原因 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:1999 +# args: imageUuid +image[uuid\:%s]\ is\ not\ on\ creating,\ please\ wait\ for\ it\ to\ cancel\ itself. = 镜像[uuid:{0}]未处于创建状态,请等待其自行取消。 + +# at: src/main/java/org/zstack/image/ImageManagerImpl.java:2005 +# args: volumeUuid +volume[uuid\:%s]\ has\ been\ deleted.\ no\ need\ to\ cancel = 卷[uuid:{0}]已删除。不需要取消。 + +# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:48 +# args: +Failed\ to\ set\ security\ level,\ because\ security\ level\ is\ disabled. = 设置密级失败,因为密级功能已禁用 + +# at: src/main/java/org/zstack/image/ImageMevocoApiInterceptor.java:58 +# args: msg.getSecurityLevel(),Arrays.stream(SecurityLevel.values()).map(SecurityLevel::getCode).collect(Collectors.toList()) +Unknown\ security\ level\ code[%s],\ supported\ values\ are\ %s = 未知的密级[{0}],支持的值有[{1}] + +# at: src/main/java/org/zstack/image/UploadImageTracker.java:197 +# args: +upload\ session\ expired = 上传session失效了 + +# at: src/main/java/org/zstack/imagereplicator/ImageReplicatorImpl.java:366 +# args: targetBsUuid +target\ backup\ storage[uuid\:%s]\ became\ unavailable = 目标备份存储[uuid:{0}]变得不可用 + +# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:30 +# args: String.join(",", msg.getBackupStorageUuids()),msg.getReplicationGroupUuid() +One\ or\ more\ backup\ storage[uuids\:%s]\ has\ been\ added\ to\ replication\ group[uuid\:%s] = 已将一个或多个备份存储[uuid:{0}]添加到复制组[uuid:{1}] + +# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:41 +# args: bsUuid +Backup\ storage[uuids\:%s]\ is\ not\ of\ type\ ImageStore = 备份存储[uuid:{0}]不属于ImageStore类型 + +# at: src/main/java/org/zstack/imagereplicator/ReplicationGroupApiInterceptor.java:51 +# args: bsUuid +Backup\ storage[uuids\:%s]\ is\ not\ attached\ to\ any\ Zone = 备份存储[uuid:{0}]未连接到任何区域 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:65 +# args: l3NetworkUuid +Network\ [uuid\:\ %s]\ does't\ not\ have\ IPsec\ service = 网络[uuid: {0}]没有IPsec服务 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:74 +# args: rcidr +the\ remote\ CIDR[%s]\ is\ same\ to\ existed\ cidrs = 远程CIDR[{0}]与现有的CIDR相同 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:86 +# args: rcidr,tempCidr +the\ remote\ CIDR[%s]\ and\ remote\ CIDR[%s]\ are\ overlaped = 远程的CIDR[{0}]和远端CIDR[{1}]存在覆盖 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:109 +# args: lcidr,tempCidr +the\ CIDR[%s]\ of\ local\ router\ and\ remote\ CIDR[%s]\ are\ overlaped = 本地路由的CIDR[{0}]和远端CIDR存在覆盖 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:122 +# args: +all\ networks\ in\ same\ IPsecConnection\ should\ be\ same\ type = 在相同的IPsec连接中的所有连接应该是相同类型 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:128 +# args: L3NetworkConstant.L3_BASIC_NETWORK_TYPE +IPsecConnection\ can\ ONLY\ have\ 1\ network\ for\ %s = IPsec连接只能有一个网络服务 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:140 +# args: l3Uuid +L3Network\ [uuid\:\ %s]\ has\ not\ been\ attached\ to\ vpc\ router = 三层网络[uuid:{0}]还没有绑定VPC路由 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:162 +# args: vrUuids.toArray()[0] +there\ is\ no\ master\ vpc\ for\ ha\ group\ %s = 高可用性组{0}没有主VPC + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:159 +# args: +all\ networks\ in\ same\ IPsecConnection\ must\ be\ attached\ to\ same\ VPC\ router = 在相同的IPsec连接中的所有网络必须绑定在相同的VPC路由 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:172 +# args: masterUuid +there\ is\ a\ vpc[%s]\ using\ old\ ipsec\ plugin,\ upgrade\ it\ to\ create\ ipsec = 存在使用旧IPSec插件的VPC[{0}],请升级该插件以创建IPSec + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:185 +# args: tuples.get(0).get(0, String.class),tuples.get(0).get(1, String.class) +there\ already\ have\ ipsec\ connection[uuid\:%s,\ name\:%s]\ with\ the\ same\ vrouter\ and\ peerAddress = 这里已经有相同云路由和对端地址的IPsec连接[uuid:{0}, name:{1}] + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:209 +# args: msg.getVipUuid(),useForList.toString() +the\ vip[uuid\:%s]\ has\ been\ used\ for\ %s = 虚拟IP[uuid:{0}]已经用作网络服务 {1} + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:214 +# args: msg.getPeerAddress() +the\ peerAddress[%s]\ cannot\ be\ the\ same\ to\ the\ VIP\ address = 对端地址[{0}]不能和虚拟IP地址相同 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:218 +# args: msg.getPeerAddress() +the\ peerAddress[%s]\ is\ not\ an\ IPv4\ address = 对端地址[{0}]不是一个IPv4地址 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:230 +# args: +the\ authKey\ cannot\ contain\ white\ space\ and\ special\ characters\ of\ '\"`\\ = 验证码不能包含空格和以下字符:'\"`\\ + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:249 +# args: vipVO.getIp() +Ipsec\ VIP\ [%s]\ cannot\ be\ the\ first\ or\ the\ last\ IP\ of\ the\ CIDR\ with\ the\ public\ address\ pool\ type = IPSec VIP[{0}]不能是具有公用地址池类型的CIDR的第一个或最后一个IP + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:281 +# args: +must\ include\ l3\ networks\ in\ APIAttachL3NetworksToIPsecConnectionMsg = 参数中缺少三层网络的uuid + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:288 +# args: l3NetworkUuid +L3\ network\ [%s]\ is\ not\ vpc\ network,\ can\ not\ be\ attached\ or\ detached\ to\ ipsec = 三层网络[{0}]不是VPC网络,不能绑定或解绑IPsec + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:269 +# args: l3NetworkUuid,msg.getIPsecConnectionUuid() +L3\ network\ [%s]\ can\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s]twice = 三层网络[{0}]不能绑定IPsec[uuid :{1}]两次 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:292 +# args: l3NetworkUuid,msg.getIPsecConnectionUuid() +L3\ network\ [%s]\ is\ not\ be\ attached\ to\ ipsec\ [uuid\ \:%s] = 三层网络[{0}]不能绑定IPsec[uuid :{1}] + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:302 +# args: cidr,msg.getIPsecConnectionUuid() +Cidr\ [%s]\ is\ already\ in\ the\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = CIDR[{0}]已经在IPsec[uuid :{1}]的CIDR中 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:316 +# args: cidr,msg.getIPsecConnectionUuid() +Cidr\ [%s]\ is\ not\ in\ Cidrs\ of\ ipsec\ [uuid\ \:%s] = CIDR[{0}]没有在IPsec[uuid :{1}]的CIDR中 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:324 +# args: msg.getUuid() +can\ not\ change\ state\ because\ ipsec\ [uuid\:%s]\ status\ is\ not\ ready = 不能修改IPsec的状态,因为IPsec的状态没有准备 + +# at: src/main/java/org/zstack/ipsec/IPsecApiInterceptor.java:330 +# args: msg.getUuid() +could\ not\ reconnect\ this\ ipsec\ [uuid\:%s],\ please\ upgrade\ ipsec\ version = 无法重新连接此IPSec[uuid:{0}],请升级IPSec版本 + +# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:133 +# args: msg.getIPsecConnectionUuid() +cannot\ find\ the\ IPsecconnection[uuid\:%s],\ it\ may\ have\ been\ deleted = 未找到IPsec连接[uuid:{0}],它可能会被删除了 + +# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:466 +# args: Long.toString(range2.getStart()),Long.toString(range2.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),msg.getVipUuid() +Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ UDP = 当前的端口范围以UDP使用的端口范围冲突了 + +# at: src/main/java/org/zstack/ipsec/IPsecManagerImpl.java:504 +# args: cidr,l3Inv.getUuid(),uuid,rCidr +cidr[%s]\ of\ attached\ L3Network\ [uuid\:%s]\ is\ overlapped\ with\ ipsec\ [uuid\:%s]\ remote\ cidr[%s] = 已绑定在三层网络[uuid:{1}]的CIDR与IPSec[uuid:{2}]远程CIDR存在重叠 + +# at: src/main/java/org/zstack/ipsec/vyos/VyosCreateIPsecFlow.java:69 +# args: errorCode.getDescription() +create\ ipsec\ to\ ha\ route\ failed,\ because\ %s = 创建IPSec到HA路由失败,因为{0} + +# at: src/main/java/org/zstack/ipsec/vyos/VyosDeleteIPsecFlow.java:55 +# args: errorCode.getDescription() +delete\ ipsec\ from\ ha\ group\ failed\ because\ %s = 从HA组中删除IPSec失败,原因是{0} + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:178 +# args: rcidr,cidr +the\ remoteCidr[%s]\ is\ overlaped\ with\ VirtualRouter\ interface\ cidr[%s] = RemoteCidR[{0}]与VirtualRouter接口CIDR[{1}]重叠 + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:293 +# args: +vyos\ doesn't\ support\ aes-192\ as\ IkeEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos不支持aes-192作为密钥交换加密算法,可用选择为aes-128, aes-256, 3des + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:299 +# args: +vyos\ doesn't\ support\ aes-192\ as\ PolicyEncryptionAlgorithm,\ available\ options\ aes-128,\ aes-256,\ 3des = vyos不支持aes-192作为加密算法协议,可用选择为aes-128, aes-256, 3des + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:305 +# args: msg.getIkeDhGroup() +vyos\ doesn't\ support\ %d\ as\ Ike\ DhGroup\ = vyos不支持[{0}]作为Ike DhGroup + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:788 +# args: errorCode.getDescription() +sync\ to\ ha\ group\ failed,\ because\:%s = 与高可用性组同步失败,原因:{0} + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:675 +# args: errorCode.getDescription() +apply\ to\ ha\ group\ failed,\ because\ %s = 应用到HA组失败,原因是{0} + +# at: src/main/java/org/zstack/ipsec/vyos/VyosIPsecBackend.java:768 +# args: vrUuid +update\ ipsec\ version\ failed,\ because\:vpc[%s]\ not\ exist = 更新IPSec版本失败,因为:VPC[{0}]不存在 + +# at: src/main/java/org/zstack/kvm/KVMApiInterceptor.java:46 +# args: msg.getManagementIp() +there\ has\ been\ a\ kvm\ host\ having\ management\ ip[%s] = 已经存在一个拥有管理节点IP[{0}]的物理机 + +# at: src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java:70 +# args: rsp.getPort(),vm.getUuid() +unexpected\ VNC\ port\ number[%d]\ for\ VM\ [uuid\:%s] = VM[uuid:{1}]的意外VNC端口号[{0}] + +# at: src/main/java/org/zstack/kvm/KVMHost.java:465 +# args: self.getUuid() +host[uuid\:%s]\ has\ been\ deleted = 物理机[uuid:{0}]已经被删除了 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:2499 +# args: msg.getVmUuid(),vmState +vm[uuid\:%s]\ is\ not\ Running\ or\ Stopped,\ current\ state[%s] = 云主机[uuid:{0}]未处在Running或Stopped状态, 现在状态为[{1}] + +# at: src/main/java/org/zstack/kvm/KVMHost.java:745 +# args: ret.getNewVolumeInstallPath() +after\ block\ commit,\ new\ volume\ path\ still\ use\ %s = 块提交后,新卷路径仍使用{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:877 +# args: host.getUuid(),webSsh.status +create\ connection\ to\ host[%s]\ failed,\ because\ %s = 创建到物理机[{0}]的连接失败,原因是{1} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1326 +# args: reply.getError() +check\ host\ capacity\ failed,\ because\:%s = 检查物理机容量失败,原因:{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1337 +# args: msg.getHostUuid(),rsp.getTotalMemory(),reservedSize +The\ host[uuid\:%s]'s\ available\ memory\ capacity[%s]\ is\ lower\ than\ the\ reserved\ capacity[%s] = 物理机[uuid:{0}]的可用内存[{1}]少于保留内存[{2}] + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1392 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ register\ colo\ heartbeat\ for\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = 无法为KVM物理机[uuid:{1},IP:{2}]上的VM[uuid:{0}]注册COLO检测信号,因为{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1448 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ start\ colo\ sync\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{1},IP:{2}]上启动Colo Sync VM[uuid:{0}],原因是{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1503 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ config\ secondary\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{1},IP:{2}]上配置辅助云主机[uuid:{0}],原因是{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1535 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ config\ primary\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{1},IP:{2}]上配置主VM[uuid:{0}],原因是{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1576 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +unable\ to\ get\ first\ boot\ dev\ of\ vm[uuid\:%s]\ on\ kvm\ host\ [uuid\:%s,\ ip\:%s],\ because\ %s = 无法获取KVM物理机[uuid:{1},IP:{2}]上的VM[uuid:{0}]的第一个引导设备,因为{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1625 +# args: msg.getVmInstanceUuid(),rsp.getError() +failed\ to\ get\ vm[uuid\:%s]\ device\ address,\ because\:%s = 无法获取VM[uuid:{0}]设备地址,因为:{1} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1680 +# args: msg.getHostUuid(),rsp.getError() +failed\ to\ get\ host[uuid\:%s]\ virtualizer\ info,\ because\:%s = 无法获取物理机[uuid:{0}]虚拟化程序信息,因为:{1} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1762 +# args: ret.getError() +failed\ to\ increase\ vm\ cpu,\ error\ details\:\ %s = 无法增加VM CPU,错误详细信息:{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1860 +# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),result.getExitErrorMessage() +unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = 无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:1942 +# args: self.getUuid(),self.getStatus() +the\ host[uuid\:%s,\ status\:%s]\ is\ not\ Connected = 物理机[uuid:{0}, 状态:{1}]不是Connected状态 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:2280 +# args: volume.getUuid(),state +cannot\ do\ volume\ snapshot\ merge\ when\ vm[uuid\:%s]\ is\ in\ state\ of\ %s.\ The\ operation\ is\ only\ allowed\ when\ vm\ is\ Running\ or\ Stopped = 当云主机[uuid:{0}]处于{1}状态的时候不能做云盘快照合并。此操作只能在云主机处在Running和Stopped状态时进行 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:2287 +# args: KVMConstant.MIN_LIBVIRT_LIVE_BLOCK_COMMIT_VERSION,libvirtVersion +live\ volume\ snapshot\ merge\ needs\ libvirt\ version\ greater\ than\ %s,\ current\ libvirt\ version\ is\ %s.\ Please\ stop\ vm\ and\ redo\ the\ operation\ or\ detach\ the\ volume\ if\ it's\ data\ volume = 实时云盘快照合并需要libvirt版本高于{0},现在libvirt版本为{1}。请停止云主机后重试或卸载云盘(仅当为云盘时) + +# at: src/main/java/org/zstack/kvm/KVMHost.java:2911 +# args: msg.getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +failed\ to\ update\ nic[vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = 无法更新KVM物理机[uuid:{1},IP:{2}]上的NIC[VM:{0}],因为{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:2963 +# args: msg.getNicInventory().getUuid(),msg.getNicInventory().getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError() +failed\ to\ attach\ nic[uuid\:%s,\ vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s = 在物理机[uuid:{2},IP:{3}]上加载网卡[uuid:{0},云主机:{1}]失败,因为:{4} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:2959 +# args: msg.getNicInventory().getUuid(),msg.getNicInventory().getVmInstanceUuid(),self.getUuid(),self.getManagementIp(),ret.getError(),msg.getNicInventory().getInternalName() +failed\ to\ attach\ nic[uuid\:%s,\ vm\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],because\ %s,\ please\ try\ again\ or\ delete\ device[%s]\ by\ yourself = 无法在KVM物理机[uuid:{2},IP:{3}]上连接NIC[uuid:{0},VM:{1}],因为{4},请重试或自行删除设备[{5} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3018 +# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() +failed\ to\ detach\ data\ volume[uuid\:%s,\ installPath\:%s]\ from\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]卸载云盘[uuid:{0}, installPath:{1}],因为: {6} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3105 +# args: vol.getUuid(),vol.getInstallPath(),vm.getUuid(),vm.getName(),getSelf().getUuid(),getSelf().getManagementIp(),ret.getError() +failed\ to\ attach\ data\ volume[uuid\:%s,\ installPath\:%s]\ to\ vm[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{4}, ip:{5}]上为云主机[uuid:{2}, name:{3}]挂载云盘[uuid:{0}, installPath:{1}],因为: {6} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3149 +# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() +failed\ to\ destroy\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在物理机[uuid:{2}, ip:{3}]上删除云主机[uuid:{0} name:{1}],原因: {4} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3281 +# args: vminv.getUuid(),vminv.getName(),self.getUuid(),self.getManagementIp(),e.getMessage() +failed\ to\ stop\ vm[uuid\:%s\ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 在物理机[uuid:{2}, ip:{3}]上停止云主机[uuid:{0} 名称:{1}]失败,因为:{4} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3386 +# args: msg.getHostUuid(),ret.getError() +Host[%s]\ update\ spice\ channel\ config\ faild,\ because\ %s = 物理机[{0}]更新SPICE通道配置失败,原因是{1} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3505 +# args: total +when\ the\ vm\ platform\ is\ Other,\ the\ number\ of\ dataVolumes\ and\ cdroms\ cannot\ exceed\ 3,\ currently\ %s = 当VM平台为OTHER时,DataVolumes和CDROM的数量不能超过3个,目前为{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:3997 +# args: msg.getPhysicalInterface(),context.getInventory().getUuid(),context.getInventory().getManagementIp() +failed\ to\ check\ physical\ network\ interfaces[names\ \:\ %s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s] = 无法检查KVM物理机[uuid:{1},IP:{2}]上的物理网络接口[名称:{0}] + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4128 +# args: self.getUuid(),ret.getHostUuid(),dbf.getDbVersion(),ret.getVersion() +detected\ abnormal\ status[host\ uuid\ change,\ expected\:\ %s\ but\:\ %s\ or\ agent\ version\ change,\ expected\:\ %s\ but\:\ %s]\ of\ kvmagent,it's\ mainly\ caused\ by\ kvmagent\ restarts\ behind\ zstack\ management\ server.\ Report\ this\ to\ ping\ task,\ it\ will\ issue\ a\ reconnect\ soon = 检测到KVMAgent的异常状态[物理机uuid更改,预期:{0}但是:{1}或代理版本更改,预期:{2}但是:{3}],这主要是由KVMAgent在ZStack管理服务器后面重新启动引起的。将此报告给ping任务,它将很快发出重新连接 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4283 +# args: self.getUuid(),self.getManagementIp(),connectPath,rsp.getError() +unable\ to\ connect\ to\ kvm\ host[uuid\:%s,\ ip\:%s,\ url\:%s],\ because\ %s = 连接物理机[uuid:{0}, ip:{1},url:{2}]失败,因为:{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4342 +# args: errorCodeList != null && StringUtils.isNotEmpty(errorCodeList.getReadableDetails()) ? errorCodeList.getReadableDetails() : "please check network" +host\ can\ not\ access\ any\ primary\ storage,\ %s = 物理机无法访问任何主存储,{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4482 +# args: getSelf().getManagementIp(),getSelf().getPort(),TimeUnit.MILLISECONDS.toSeconds(sshTimeout) +the\ host[%s]\ ssh\ port[%s]\ not\ open\ after\ %s\ seconds,\ connect\ timeout = 物理机[{0}]SSH端口[{1}]在{2}秒后未打开,连接超时 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4542 +# args: checkList +failed\ to\ ping\ all\ DNS/IP\ in\ %s;\ please\ check\ /etc/resolv.conf\ to\ make\ sure\ your\ host\ is\ able\ to\ reach\ public\ internet = 在{0}中的所有DNS/IP都ping失败了,请检查 /etc/resolv.conf 来确保你的物理机能连接到公网 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4540 +# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() +unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:\ %d,\ ]\ to\ do\ DNS\ check,\ please\ check\ if\ username/password\ is\ wrong;\ %s = 无法连接物理机[ip:{0}, 用户名:{1}, ssh端口:{2} ]做DNS检查,请检查用户名密码是否正确;{3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4585 +# args: self.getManagementIp(),restf.getHostName(),ret.getStderr(),ret.getExitErrorMessage() +the\ KVM\ host[ip\:%s]\ cannot\ access\ the\ management\ node's\ callback\ url.\ It\ seems\ that\ the\ KVM\ host\ cannot\ reach\ the\ management\ IP[%s].\ %s\ %s = 物理机[ip:{0}] 无法连接到管理节点IP [{1}]. {2} {3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4582 +# args: self.getManagementIp(),getSelf().getUsername(),getSelf().getPort(),ret.getExitErrorMessage() +unable\ to\ connect\ to\ KVM[ip\:%s,\ username\:%s,\ sshPort\:%d]\ to\ check\ the\ management\ node\ connectivity,please\ check\ if\ username/password\ is\ wrong;\ %s = 不能连接到物理机[ip:{0}, username:{1}, sshPort:{2}] 去检查与管理节点是否连通 ,请检查您的用户名或者密码是否有误; {3} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4611 +# args: hostRet.getExitErrorMessage() +unable\ to\ Check\ whether\ the\ host\ is\ taken\ over,\ \ because\ %s = 无法检查物理机是否已被接管,因为{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4625 +# args: timeRet.getExitErrorMessage() +Unable\ to\ get\ the\ timestamp\ of\ the\ flag,\ \ because\ %s = 无法获取标志的时间戳,因为{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4634 +# args: self.getManagementIp(),hostOutput,diff,HostGlobalConfig.PING_HOST_INTERVAL.value(int.class) +the\ host[ip\:%s]\ has\ been\ taken\ over,\ because\ the\ takeover\ flag[HostUuid\:%s]\ already\ exists\ and\ utime[%d]\ has\ not\ exceeded\ host\ ping\ interval[%d] = 物理机[IP:{0}]已被接管,因为接管标志[HOSTuuid:{1}]已存在,并且UTIME[{2}]未超过物理机ping间隔[{3}] + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4643 +# args: self.getManagementIp(),lastHostInv.getUuid() +the\ host[ip\:%s]\ has\ been\ taken\ over,\ because\ flag[HostUuid\:%s]\ exists\ in\ the\ database = 物理机[IP:{0}]已被接管,因为数据库中存在标志[HOSTuuid:{1}] + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4666 +# args: ret.getExitErrorMessage() +unable\ to\ get\ host\ cpu\ architecture,\ please\ check\ if\ username/password\ is\ wrong;\ %s = 无法获取物理机CPU架构,请检查用户名/密码是否错误;{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4693 +# args: hostArchitecture,cluster.getArchitecture() +host\ cpu\ architecture[%s]\ is\ not\ matched\ the\ cluster[%s] = 物理机CPU体系结构[{0}]与集群[{1}]不匹配 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:4997 +# args: +cannot\ find\ either\ 'vmx'\ or\ 'svm'\ in\ /proc/cpuinfo,\ please\ make\ sure\ you\ have\ enabled\ virtualization\ in\ your\ BIOS\ setting = 不能发现以下任意一个 'vmx' or 'svm' 在路径 /proc/cpuinfo 里, 请检查你是否在你的BIOS设置里开启了virtualization选项 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5064 +# args: self.getUuid(),self.getClusterUuid() +host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ qemu/libvirt\ version\ does\ not\ match = 物理机[uuid:{0}]不能添加到集群[uuid:{1}]中,因为qemu/libvirt不匹配 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5084 +# args: self.getUuid(),self.getClusterUuid() +host\ [uuid\:%s]\ cannot\ be\ added\ to\ cluster\ [uuid\:%s]\ because\ cpu\ model\ name\ does\ not\ match = 物理机[uuid:{0}]无法被添加到集群[uuid:{1}]因为cpu型号不一致 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5217 +# args: msg.getHostUuid(),ctimeout +host[%s]\ not\ shutdown\ in\ %d\ seconds = 物理机[{0}]未在{1}秒内关闭 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5374 +# args: +host\ is\ not\ in\ the\ connected\ status,\ cannot\ update\ os = 物理机当前并不是已连接状态,不能升级操作系统 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5372 +# args: +host\ is\ in\ the\ premaintenance\ state,\ cannot\ update\ os = 物理机正处于预维护状态,不能升级操作系统 + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5666 +# args: rsp.getError() +failed\ to\ attach\ volume\ to\ host,\ because\:%s = 无法将卷附加到物理机,因为:{0} + +# at: src/main/java/org/zstack/kvm/KVMHost.java:5727 +# args: rsp.getError() +failed\ to\ detach\ volume\ from\ host,\ because\:%s = 无法从物理机分离卷,因为:{0} + +# at: src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java:201 +# args: +cannot\ adapt\ version\ for\ the\ bellow\ rpm\:\ libvirt\ /\ qemu\ /\ cpumodel = 源和目的之间的以下组件版本不兼容:libvirt、qemu、cpumodel + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:164 +# args: e.getMessage() +fail\ to\ load\ host\ info\ from\ file.\ because\n%s = 无法从文件加载物理机信息。因为\n{0} + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:290 +# args: os,vo.getName(),vo.getManagementIp() +the\ operation\ system[%s]\ of\ host[name\:%s,\ ip\:%s]\ is\ invalid = 物理机[名称:{1},IP:{2}]的操作系统[{0}]无效 + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:316 +# args: vo.getClusterUuid(),otherOs,vo.getName(),vo.getManagementIp(),os +cluster[uuid\:%s]\ already\ has\ host\ with\ os\ version[%s],\ but\ new\ added\ host[name\:%s\ ip\:%s]\ has\ different\ host\ os\ version[%s] = 集群[uuid:{0}]已具有操作系统版本为[{1}]的物理机,但新添加的物理机[名称:{2}IP:{3}]具有不同的物理机操作系统版本[{4}] + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:461 +# args: cmd.vmUuid +vm[uuid\:%s]\ crashes\ due\ to\ kernel\ error = VM[uuid:{0}]因内核错误而崩溃 + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:500 +# args: str.toString() +there\ are\ still\ hosts\ not\ have\ the\ same\ cpu\ model,\ details\:\ %s = 仍存在host有不同的cpu模型,详细信息:{0} + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:514 +# args: KVMSystemTags.VM_PREDEFINED_PCI_BRIDGE_NUM_TOKEN +pci\ bridge\ need\ a\ value\ greater\ than\ 0\ and\ lower\ than\ 32 = PCI桥需要大于0且小于32的值 + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:557 +# args: vm.getState(),VmInstanceState.Stopped +vm\ current\ state[%s],\ modify\ virtioSCSI\ requires\ the\ vm\ state[%s] = VM当前状态[{0}],修改VirtiosCsi需要VM状态[{1}] + +# at: src/main/java/org/zstack/kvm/KVMHostFactory.java:759 +# args: hostUuid +host[uuid\:%s]\ does\ not\ have\ cpu\ model\ information,\ you\ can\ reconnect\ the\ host\ to\ fix\ it = 物理机[uuid:{0}]无cpu模型信息,你可以尝试重连来解决这个问题 + +# at: src/main/java/org/zstack/kvm/KVMHostUtils.java:35 +# args: format +invalid\ format\ string\ %s = 格式字符串{0}无效 + +# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:70 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 在物理机[uuid:{3}]上为二层网络[uuid:{1}, type:{2}]创建网桥[{0}]失败,原因: {4} + +# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:129 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getName(),hostUuid,rsp.getError() +failed\ to\ check\ bridge[%s]\ for\ l2NoVlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = 在二层网络[uuid:{1}中检查网桥[{0}]失败,名字为[{2}]在物理机t[uuid: {3}]上, {4} + +# at: src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java:211 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() +failed\ to\ delete\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 无法在KVM物理机[uuid:{3}]上删除二层网络[uuid:{1},类型:{2}]的网桥[{0}],因为{4} + +# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:82 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vlan.getVlan(),hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 创建二层网络[uuid:{1}中的网桥[{0}]失败 , 类型为: {2}, vlan:{3}] 在物理机[uuid:{4}]上, 原因: {5} + +# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:142 +# args: cmd.getBridgeName(),l2vlan.getUuid(),l2vlan.getName(),hostUuid,rsp.getError() +failed\ to\ check\ bridge[%s]\ for\ l2VlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 检查在物理机[uuid:{3}]上二层网络[uuid:{1}, name:{2}]中的网桥[{0}]失败, {4} + +# at: src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java:239 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vlan.getVlan(),hostUuid,rsp.getError() +failed\ to\ delete\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 无法在KVM物理机[uuid:{4}]上删除二层网络[uuid:{1},类型:{2},VLAN:{3}]的网桥[{0}],因为{5} + +# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:109 +# args: hto.getHostUuid(),rsp.getError() +failed\ to\ apply\ rules\ of\ security\ group\ rules\ to\ kvm\ host[uuid\:%s],\ because\ %s = 不能应用安全组规则在物理机t[uuid:{0}]上, 因为 {1} + +# at: src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java:152 +# args: hostUuid,rsp.getError() +failed\ to\ check\ default\ rules\ of\ security\ group\ on\ kvm\ host[uuid\:%s],\ because\ %s = 在host[uuid:{0}]上检查默认安全组规则失败 + +# at: src/main/java/org/zstack/kvm/KvmVmHardwareVerifyExtensionPoint.java:31 +# args: +Failed\ to\ start\ vm,\ because\ can\ not\ disable\ vm.cpu.hypervisor.feature\ with\ vm.cpuMode\ none = 无法启动VM,因为无法使用VM.CPUMode None禁用VM.CPU.Hypervisor.Feature + +# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:95 +# args: msg.getMessageName() +cannot\ get\ vmUuid\ from\ msg\ %s = 无法从消息{0}获取VMuuid + +# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:258 +# args: host.getUuid(),host.getManagementIp(),ret.getError() +unable\ to\ do\ vm\ sync\ on\ host[uuid\:%s,\ ip\:%s]\ because\ %s = 不能在物理机[uuid:{0}, ip:{1}]上执行云主机状态同步操作,因为{2} + +# at: src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java:287 +# args: vmUuid +The\ vm[%s]\ state\ is\ in\ shutdown\ for\ a\ long\ time,\ check\ whether\ the\ vm\ is\ normal = 云主机[{0}]长时间处于关闭状态,请检查云主机是否正常 + +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:67 +# args: +unsupported\ LDAP/AD\ server\ scope = 不支持的LDAP/AD服务器作用域 + +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:128 +# args: type,LdapConstant.OpenLdap.TYPE,LdapConstant.WindowsAD.TYPE +Wrong\ LdapServerType[%s],\ valid\ values\:\ [%,%s] = 错误的LDAP服务类型[{0}],有效的值: [%,{1}] + +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:153 +# args: +Cannot\ connect\ to\ LDAP/AD\ server,\ Invalid\ Credentials,\ please\ checkout\ User\ DN\ and\ password = 无法连接到LDAP/AD服务器,凭据无效,请签出用户DN和密码 + +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:156 +# args: +Cannot\ connect\ to\ LDAP/AD\ server,\ communication\ false,\ please\ checkout\ IP,\ port\ and\ Base\ DN = 无法连接到LDAP/AD服务器,通信错误,请检查IP、端口和基本DN + +# at: src/main/java/org/zstack/ldap/LdapApiInterceptor.java:159 +# args: e.toString() +Cannot\ connect\ to\ LDAP/AD\ server,\ %s = 不能连接LDAP服务,{0} + +# at: src/main/java/org/zstack/ldap/LdapManagerImpl.java:560 +# args: vo.getAccountUuid() +Account[uuid\:%s]\ Not\ Found!!! = 未找到帐户[uuid:{0}]! + +# at: src/main/java/org/zstack/ldap/LdapUtil.java:581 +# args: filter,errorMessage +query\ ldap\ entry[filter\:\ %s]\ fail,\ because\ %s = 查询LDAP条目[筛选器:{0}]失败,原因是{1} + +# at: src/main/java/org/zstack/ldap/externalSearch/AggregateSearch.java:52 +# args: e.toString() +query\ ldap\ entry\ fail,\ %s = 查询LDAP条目失败,{0} + +# at: src/main/java/org/zstack/license/LicenseChecker.java:167 +# args: +Parse\ license\ error,\n1.\ check\ your\ private\ key\ and\ application\ code\ is\ correct\n2.\ check\ your\ license\ is\ not\ corrupted\n3.\ use\ zstack-ctl\ clear_license\ to\ clear\ your\ licenses\ and\ try\ to\ reinstall\n = 解析许可证错误,\N1。检查您的私钥和应用程序代码是否正确\N2。检查您的许可证是否已损坏\N3。使用zstack-CTL清除_许可证清除您的许可证并尝试重新安装\n + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:229 +# args: +the\ licenseRequestCode\ is\ illegal = 许可证请求代码不合法 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:242 +# args: e.getMessage() +Decode\ fail\ because\ %s = 解码失败,因为{0} + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:239 +# args: bytes.length +Unexpected\ decoded\ license\ file\ length\:\ %d = 意外的解码许可证文件长度:{0} + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:791 +# args: +Licensed\ VM\ number\ overrun = VM数量超过云主机授权上限 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:857 +# args: +unexpected\ host\ vendor\ for\ MINI = Mini的意外物理机供应商 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1216 +# args: info.getUuid() +not\ supported\:\ delete\ license[%s]\ from\ USB-key = 不支持:从USB-KEY删除许可证[{0}] + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1271 +# args: System.getProperty("os.arch") +UKey\ not\ supported\ (arch\:\ %s) = 不支持UKey(Arch:{0}) + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1351 +# args: ex.getLocalizedMessage() +update\ local\ ukey\ license\:\ %s = 更新本地UKEY许可证:{0} + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1347 +# args: +No\ local\ ukey\ license\ updated = 没有本地UKEY许可证更新 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1377 +# args: +No\ node\ available\ to\ update\ UKey = 没有节点可用于更新UKEY + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1519 +# args: Platform.getManagementServerIp() +Multiple\ MN\ exists\ but\ only\ supplied\ licenses\ for\ %s = 管理节点有多个,但是仅提供了节点{0}的许可证 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1493 +# args: mnUuid,reply.getError().getDetails() +MN[uuid\:%s]\:\ %s = Mn[uuid:{0}]:{1} + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1521 +# args: msg.getManagementUuids() +MN\ HA\ environment,\ but\ only\ updated\ license\ for\ %s = 管理节点有多个,但是仅更新了节点{0}的许可证 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:1724 +# args: newLicenseInfo.getUuid(),newLicenseInfo.getLicenseType().toString(),path +can\ not\ find\ license[uuid\:%s,\ type\:%s]\ file\ on\ path\ %s = 在路径{2}上找不到许可证[uuid:{0},类型:{1}]文件 + +# at: src/main/java/org/zstack/license/LicenseManagerImpl.java:2263 +# args: +License\ expired = 许可证已过期 + +# at: src/main/java/org/zstack/license/cube/CubeLicenseFactory.java:50 +# args: sdsInfoPath +%s\ is\ not\ existed = {0}不存在 + +# at: src/main/java/org/zstack/license/cube/XmsCli.java:61 +# args: +context\ cannot\ be\ null\ in\ license = 许可证中的上下文不能为空 + +# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:247 +# args: struct.getType() +No\ factory\ found\ for\ type\:%s = 未找到类型为{0}的工厂 + +# at: src/main/java/org/zstack/log/LogConfigurationManagerImpl.java:462 +# args: msg.getType() +Unknown\ log\ configuration\ type\ %s = 未知的日志配置类型{0} + +# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:60 +# args: lstruct.getAppenderType() +No\ factory\ found\ for\ log4j2\ appender\ type\:%s. = 找不到Log4j2附加器类型的工厂:{0}。 + +# at: src/main/java/org/zstack/log4j2/Log4j2LogConfigurationFactory.java:134 +# args: lstruct.getAppenderType() +Unknown\ log4j2\ appender\ type\ %s = 未知的Log4j2 Appender类型{0} + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:33 +# args: +facility\ can\ not\ be\ null = 设备不能为空 + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:37 +# args: configuration.facility +invalid\ facility\ %s = 工具{0}无效 + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:41 +# args: +hostname\ can\ not\ be\ null = 物理机名不能为空 + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:45 +# args: +port\ can\ not\ be\ null = 端口不能为空 + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:49 +# args: +protocol\ can\ not\ be\ null = 协议不能为空 + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:55 +# args: configuration.protocol +unsupported\ protocol\ %s = 不支持的协议{0} + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:69 +# args: configuration.hostname,configuration.port +syslog\ server[address\:\ %s\:%s]\ is\ not\ available = Syslog服务器[地址:{0}:{1}]不可用 + +# at: src/main/java/org/zstack/log4j2/appender/syslog/SyslogAppenderProxyFactory.java:61 +# args: configuration.hostname +syslog\ server[address\:\ %s]\ is\ not\ available = Syslog服务器[地址:{0}]不可用 + +# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:74 +# args: +There\ is\ no\ LDAP/AD\ server\ in\ the\ system,\ Please\ add\ a\ LDAP/AD\ server\ first. = 在系统中没有LDAP服务,请先添加一个LDAP服务 + +# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:68 +# args: msg.getLdapUid(),msg.getVirtualIDUuid() +Can\ not\ bind\ this\ ldap\ uid\ %s\ to\ virtual\ id\ [uuid\:%s] = 无法将此LDAP UID{0}绑定到虚拟ID[uuid:{1}] + +# at: src/main/java/org/zstack/login/LdapLoginInterceptor.java:82 +# args: +This\ uid\ is\ already\ used = 此UID已被使用 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:228 +# args: +ZStack\ is\ loading\ ldap\ organizations\ from\ DB\ now,\ can\ not\ execute\ sync\ operation = ZStack正在从数据库加载LDAP组织,无法执行同步操作 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:390 +# args: e.getMessage() +Failed\ to\ sync\ ldap\ entry[],\ because\ %s = 无法同步LDAP条目[],因为{0} + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1021 +# args: reply.getError().getReadableDetails() +Failed\ to\ sync\ organizations,\ because\ %s = 无法同步组织,因为{0} + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:969 +# args: +Failed\ to\ transform\ ldap\ entry\ to\ organization\ ndoe = 无法将LDAP条目转换为组织ndoe + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:958 +# args: +failed\ to\ sync\ ldap\ organization = 无法同步LDAP组织 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1441 +# args: scope.toString() +Can\ not\ sync\ LDAP/AD\ server\ whose\ scope\ is\ not\ %s = 无法同步范围不是{0}的LDAP/AD服务器 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1575 +# args: uid +Failed\ to\ validate\ uid[%s],\ maybe\ it\ has\ been\ deleted = 无法验证UID[{0}],它可能已被删除 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1616 +# args: uid,reply.getError().getReadableDetails() +Failed\ to\ create\ iam2\ virtual\ id\ for\ uid[%s],\ because\ %s = 无法为UID[{0}]创建IAM2虚拟ID,因为{1} + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:1751 +# args: ldapUid +Failed\ to\ validate\ dn\ [%s],\ maybe\ it\ has\ been\ deleted = 无法验证DN[{0}],它可能已被删除 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2195 +# args: +invalid\ json\ format = 无效的JSON格式 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2206 +# args: +name\ is\ mandatory\ field\ % = 名称是必填字段% + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2210 +# args: +attribute\ is\ mandatory\ field\ % = 属性是强制字段% + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2214 +# args: +type\ is\ mandatory\ field\ % = 类型为必填字段% + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2218 +# args: +optional\ is\ mandatory\ field\ % = 可选为必填字段% + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2222 +# args: fieldNames +name\ should\ use\ values\ in\ %s = 名称应使用{0}中的值 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2254 +# args: rule.getAttribute() +Invalid\ attribute.\ Attribute[%s]\ is\ required,\ but\ found\ there\ are\ some\ record\ not\ matched = 无效属性。属性[{0}]是必需的,但发现有一些记录不匹配 + +# at: src/main/java/org/zstack/login/LdapLoginManagerImpl.java:2199 +# args: +strategy\ is\ mandatory\ field\ % = 策略为必填字段% + +# at: src/main/java/org/zstack/login/plugin/LoginPluginBackend.java:54 +# args: +missing\ loginPluginName = 缺少LoginPluginName + +# at: src/main/java/org/zstack/login/plugin/LoginPluginBackend.java:59 +# args: loginContext.getLoginPluginName() +no\ login\ plugin\ named\ %s = 没有名为{0}的登录插件 + +# at: src/main/java/org/zstack/login/plugin/LoginPluginBackend.java:64 +# args: loginContext.getLoginPluginName() +missing\ LoginUserInfo\ when\ use\ plugin\ login = 使用插件登录时缺少LoginUserInfo + +# at: src/main/java/org/zstack/loginControl/LoginControlApiInterceptor.java:40 +# args: e.getMessage() +Invalid\ rule\ expression,\ add\ access\ control\ rule\ fail\ because\:\ %s = 规则表达式无效,添加访问控制规则失败,原因是:{0} + +# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:107 +# args: key +unrecognized\ key\:\ %s = 无法识别的键:{0} + +# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:113 +# args: opt.get() +missing\ key\:value\ of\ %s = 缺少键:{0}的值 + +# at: src/main/java/org/zstack/loginControl/LoginControlManagerImpl.java:291 +# args: msg.getResourceName(),msg.getLoginType() +No\ available\ user\ with\ name\:\ %s,\ type\:\ %s = 没有名称为{0}、类型为{1}的可用用户 + +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:90 +# args: msg.getJobName() +%s\ is\ not\ an\ API = {0}不是一个API + +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:152 +# args: +cannot\ cancel\ longjob\ that\ is\ succeeded = 不能取消已经成功的longjob + +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:155 +# args: +cannot\ cancel\ longjob\ that\ is\ failed = 不能取消已经失败的longjob + +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:166 +# args: +delete\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = 只能删除已经成功、取消、失败的longjob + +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:177 +# args: +rerun\ longjob\ only\ when\ it's\ succeeded,\ canceled,\ or\ failed = 仅在成功、取消或失败时重新运行LongJob + +# at: src/main/java/org/zstack/longjob/LongJobApiInterceptor.java:206 +# args: +can\ only\ resume\ longjob\ that\ is\ Suspended = 只能恢复挂起的LongJob + +# at: src/main/java/org/zstack/longjob/LongJobFactoryImpl.java:39 +# args: jobName +%s\ has\ no\ corresponding\ longjob = {0}没有与之对应的longjob + +# at: src/main/java/org/zstack/mediator/ApiValidator.java:123 +# args: l3NetworkUuid,vmNicVO.getL3NetworkUuid() +unable\ to\ attach\ a\ L3\ network.\ The\ cidr\ of\ l3[%s]\ to\ attach\ overlapped\ with\ l3[%s]\ already\ attached\ to\ vm = 不能绑定这个三层网络。这个云主机上已经绑定的三层网络[{1}]和这个三层网络[{0}]的CIDR存在重叠 + +# at: src/main/java/org/zstack/mediator/ApiValidator.java:155 +# args: vm.getName(),vm.getUuid(),StringUtils.join(pfStr, ",") +the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ port\ forwarding\ rules%s\ attached = 云主机[name:{0}, uuid:{1}] 已经设置了一些端口转发规则{2} + +# at: src/main/java/org/zstack/mediator/ApiValidator.java:176 +# args: vm.getName(),vm.getUuid(),StringUtils.join(eipStr, ",") +the\ vm[name\:%s,\ uuid\:%s]\ already\ has\ some\ EIPs%s\ attached = 云主机[name:{0}, uuid:{1}] 已经配置了弹性IP{2} + +# at: src/main/java/org/zstack/mediator/ApiValidator.java:191 +# args: msg.getVipUuid(),useForList.toString() +the\ vip[uuid\:%s]\ already\ has\ bound\ to\ other\ service[%s] = 该虚拟IP[uuid:{0}]已经绑定了其他服务 + +# at: src/main/java/org/zstack/mediator/ApiValidator.java:231 +# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol +Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ used\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = 当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的端口范围[{2}, {3}]冲突 + +# at: src/main/java/org/zstack/mediator/ApiValidator.java:228 +# args: Long.toString(range.getStart()),Long.toString(range.getEnd()),Long.toString(cur.getStart()),Long.toString(cur.getEnd()),vipUuid,protocol +Current\ port\ range[%s,\ %s]\ is\ conflicted\ with\ system\ service\ port\ range\ [%s,\ %s]\ with\ vip[uuid\:\ %s]\ protocol\:\ %s\ = 当前使用的端口范围[{0}, {1}]和虚拟IP[uuid: {4}, 协议: {5}]已经使用的系统服务端口范围[{2}, {3}]冲突 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:851 +# args: l3Uuid,systemTag +L3\ network[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ static\ IP = 找不到三层网络[uuid:0]。请确认静态IP的系统标签 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:327 +# args: supportSharedVolumePrimaryStorage,psType +for\ shareable\ volume,\ the\ only\ supported\ primary\ storage\ type\ is\ %s,\ current\ is\ %s = 共享云盘仅支持在主存储类型为{0}的主存储上使用,当前的类型为{1} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:795 +# args: bandwidth,Long.MAX_VALUE +invalid\ volume\ bandwidth[%s]\ is\ larger\ than\ %d = 云盘带宽[{0}]大于{1}是无效的 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:745 +# args: bandwidth +invalid\ network\ bandwidth[%s],\ it\ must\ be\ greater\ than\ or\ equal\ to\ 8192 = 错误的网络带宽[{0}],这个数字必须大于等于8K + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:793 +# args: bandwidth +invalid\ volume\ bandwidth[%s]\ is\ not\ a\ number = 错误的云盘带宽 ,[{0}] 这个不是数字 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:790 +# args: bandwidth +invalid\ volume\ bandwidth[%s],\ it\ must\ be\ greater\ than\ 1024\ (include\ 1024) = 无效的云盘带宽,它必须大于等于1M + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:832 +# args: iops +invalid\ volume\ IOPS[%s]\ is\ not\ a\ number = 错误的云盘每秒读写速度[{0}],它应该是个数字 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:834 +# args: iops,Long.MAX_VALUE +invalid\ volume\ IOPS[%s]\ is\ larger\ than\ %d = 云盘IOPS[{0}]大于{1}是无效的 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:829 +# args: iops +invalid\ volume\ IOPS[%s],\ it\ must\ be\ greater\ than\ 1\ (include\ 1) = 卷IOPS[{0}]无效,它必须大于1(包括1) + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:865 +# args: +\ usb\ device\ can\ only\ be\ called\ by\ admin\ account = USB设备只能由管理员帐户调用 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:901 +# args: level +Unknown\ code[%s]\ of\ Security\ Level = 安全级别的未知代码[{0}] + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:918 +# args: cidr +[%s]\ is\ not\ a\ standard\ cidr = [{0}]不是标准CIDR + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:939 +# args: hostUuid,os.distribution,os.version +the\ host[uuid\:%s]'s\ operating\ system\ %s\ %s\ is\ too\ old,\ the\ QEMU\ doesn't\ support\ QoS\ of\ network\ or\ disk\ IO.\ Please\ choose\ another\ instance\ offering\ with\ no\ QoS\ configuration = 物理机[uuid:{0}] 的操作系统{1} {2} 过老, QEMU 不支持云盘的QOS IO设置 。 请选择别的没有Qos的计算规格 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1186 +# args: newValue +invalid\ value[%s],\ it's\ not\ a\ double = 错误的值[{0}],这个不是双精度值 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1154 +# args: newValue +invalid\ value[%s],\ it\ must\ be\ a\ double\ greater\ than\ 0 = 错误的值[{0}],必须是一个大于0的双精度值 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1183 +# args: newValue +invalid\ value[%s],\ it\ must\ be\ a\ double\ between\ (0,\ 1] = 错误的值[{0}],这个必须在0~1之间的双精度值 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1197 +# args: newValue +invalid\ value[%s],\ ZStack\ doesn't\ have\ such\ host\ allocator\ type = 错误值[{0}],Zstack没有这样的分配器类型 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1219 +# args: MevocoGlobalConfig.AIO_NATIVE.getCanonicalName(),MevocoGlobalConfig.AIO_NATIVE.value(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.getCanonicalName(),KVMGlobalConfig.LIBVIRT_CACHE_MODE.value() +%s\ value\ is[%s],\ which\ is\ conflict\ with\ %s\ value\ [%s] = {0}值为[{1}],与{2}值[{3}]冲突 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:1489 +# args: +obj\ is\ not\ instanceof\ NicQos! = OBJ不是NICQoS的实例! + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2054 +# args: String.join(",", ips) +unexpected\ host\ management\ IPs\:\ [%s] = 意外的物理机管理IP:[{0}] + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2190 +# args: +can\ not\ set\ local\ and\ configure\ at\ same\ time = 不能同时设置本地和配置 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2242 +# args: +can\ not\ find\ node\ A\ config\ info = 找不到节点A配置信息 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2252 +# args: +can\ not\ find\ node\ A\ address\ info\ from\ bootstrap\ agent = 无法从启动代理中找到节点A地址信息 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2314 +# args: s.getJobUuid() +can\ not\ get\ bootstrap\ job\ %s\ result\ after\ 900s = 无法在900秒后获取引导程序作业{0}结果 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2322 +# args: ret.getRetCode(),ret.getStdout(),ret.getStderr() +curl\ bootstrap\ agent\ finished,\ return\ code\:\ %s,\ stdout\:\ %s,\ stderr\:\ %s = cURL引导代理已完成,返回代码:{0},标准输出:{1},标准错误:{2} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2686 +# args: errorOfNodeA.getCauses().get(0) +node\ A\ update\ factory\ mode\ failed,\ details\:\ %s = 节点A更新工厂模式失败,详细信息:{0} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2684 +# args: errorCodeList.getCauses().get(0) +all\ management\ node\ update\ factory\ mode\ failed,\ details\:\ %s = 所有管理节点更新工厂模式失败,详细信息:{0} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2790 +# args: ManagementNodeState.RUNNING +management\ node\ status\ is\ not\ %s = 管理节点状态不是{0} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2720 +# args: r.getStdout() +some\ node\ on\ factory\ mode\ exists,\ detail\ of\ arping\:\ %s = 工厂模式上的某些节点存在,ARPING的详细信息:{0} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2741 +# args: +set\ address\ on\ node\ A\ failed = 在节点A上设置地址失败 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2738 +# args: +this\ node\ is\ not\ node\ A = 此节点不是节点A + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2875 +# args: bandwidth +networkInboundBandwidth\ format\ error\ %s = 下行网络带宽格式错误{0} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2887 +# args: bandwidth +networkOutboundBandwidth\ format\ error\ %s = 上行网络带宽超格式错误{0} + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:2884 +# args: +networkOutboundBandwidth\ execeds\ the\ max\ value\ 32G\ bps = 超过上行网络带宽超过最大值32G bps + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3060 +# args: volume.getUuid(),vm.getUuid() +Shareable\ Volume[uuid\:%s]\ has\ already\ been\ attached\ to\ VM[uuid\:%s] = 共享云盘[uuid:{0}]已经挂载到云主机[uuid:{1}]上 + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3078 +# args: +shareable\ disk\ only\ support\ virtio-scsi\ type\ for\ now = 目前共享盘只支持virtio-scsi + +# at: src/main/java/org/zstack/mevoco/MevocoManagerImpl.java:3213 +# args: sharedVolUuids +shareable\ volume(s)[uuid\:\ %s]\ attached,\ not\ support\ to\ group\ snapshot. = 可共享云盘[uuid:{0}]已连接,但不支持组快照。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1811 +# args: msg.getMode() +invalid\ volume\ qos\ mode\:\ %s = 无效的卷QoS模式:{0} + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:284 +# args: msg.getIoThreadId(),msg.getPin(),vm.getUuid(),rsp.getError() +Failed\ set\ iothread[%d]\ pin[%s]\ on\ vm[%s]\:\ %s. = 无法在VM[{2}]上设置IOThread[{0}]Pin[{1}]:{3}。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:339 +# args: msg.getUuid() +can\ not\ found\ in\ used\ snapshot\ tree\ of\ volume[uuid\:\ %s].\ Maybe\ no\ snapshot\ chain\ need\ to\ validate. = 在卷[uuid:{0}]的已使用快照树中找不到。可能不需要验证快照链。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:352 +# args: currentTreeUuid,msg.getUuid() +can\ not\ found\ latest\ snapshot\ from\ tree[uuid\:\ %s]\ of\ volume[uuid\:\ %s].\ Maybe\ no\ snapshot\ chain\ need\ to\ validate. = 从树[uuid:{0}](属于卷[uuid:{1}])中找不到最新快照。可能不需要验证快照链。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:368 +# args: currentTreeUuid,msg.getUuid() +can\ not\ found\ snapshots\ from\ tree[uuid\:\ %s]\ of\ volume[uuid\:\ %s].\ Maybe\ no\ snapshot\ chain\ need\ to\ validate. = 从树[uuid:{0}](属于卷[uuid:{1}])中找不到快照。可能不需要验证快照链。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:678 +# args: vmInstanceVO.getUuid() +How\ can\ a\ Running\ VM[uuid\:%s]\ has\ no\ hostUuid? = 正在运行的VM[uuid:{0}]怎么会没有HOSTuuid? + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:676 +# args: vmInstanceVO.getUuid() +Unexpectedly,\ VM[uuid\:%s]\ is\ not\ running\ any\ more,\ please\ try\ again\ later = 意外的是,VM[uuid:{0}]不再运行,请稍后再试 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:842 +# args: PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value(),errorInfoMap.keySet(),errorInfoMap.values() +after\ subtracting\ reserved\ capacity[%s],\ primary\ storage[%s]\ don't\ have\ required\ size[%s\ bytes],\ may\ be\ the\ threshold\ of\ primary\ storage\ physical\ capacity\ setting\ is\ lower = 减去保留容量[{0}]后,主存储[{1}]没有所需的大小[{2}字节],可能是主存储物理容量设置的阈值较低 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1231 +# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() +can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ not\ attached = 当云盘[uuid:{1}]未加载时,无法给云盘[{0}]创建快照 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1237 +# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid() +can\ not\ take\ snapshot\ for\ volumes[%s]\ while\ volume[uuid\:\ %s]\ appears\ twice = 当云盘[uuid:{1}]出现多次时,无法给云盘[{0}]创建快照 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1244 +# args: msg.getVolumeSnapshotJobs().stream().map(CreateVolumesSnapshotsJobStruct::getVolumeUuid).collect(Collectors.toList()),job.getVolumeUuid(),volumeVOS.get(0).getVmInstanceUuid() +can\ not\ take\ snapshot\ for\ volumes[%s]\ attached\ multiple\ vms[%s,\ %s] = 当云盘[uuid:{1}]加载到多个云主机上时,无法给云盘[{0}]创建快照 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1251 +# args: +no\ volumes\ found = 找不到云盘 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1516 +# args: SizeUnit.BYTE.toGigaByte((double) resize) +this\ snapshot\ recording\ the\ volume\ state\ before\ resize\ to\ %fG\ is\ created\ automatically = 该快照记录云盘扩容到{0}G之前的状态,由系统自动创建 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1823 +# args: msg.getUuid() +DeleteVolumeQos\ [%s]\ ignore\ because\ of\ account\ privilege. = DeleteVolumeQoS[{0}]由于帐户权限而忽略。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:1891 +# args: ivo.getHostUuid(),ivo.getState(),VmInstanceState.Running.toString(),VmInstanceState.Stopped.toString() +Cannot\ delete\ vm's\ volume\ qos\ on\ host\ %s,\ because\ the\ current\ vm\ is\ in\ state\ of\ %s,\ but\ support\ expect\ states\ are\ [%s,\ %s] = 无法在物理机{0}上删除VM的卷QoS,因为当前VM的状态为{1},但支持的预期状态为[{2},{3}] + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2039 +# args: VolumeQos.getVolumeQosByMode(self.getVolumeQos(), mode) +non\ admin\ account\ cannot\ set\ bandwidth\ more\ than\ %s = 非管理员帐户无法设置大于{0}的带宽 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2051 +# args: +unknown\ message\ version. = 未知消息版本。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2068 +# args: +unknown\ qos\ limit\ type. = 未知的QoS限制类型。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2082 +# args: limitType +Non-admin\ account\ is\ only\ allowed\ to\ set\ the\ total\ %s\ limit. = 仅允许非管理员帐户设置总{0}限制。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2091 +# args: limitType.getType() +Non-admin\ account\ cannot\ set\ the\ total\ %s\ limits\ as\ unlimited. = 非管理员帐户无法将总{0}限制设置为无限制。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2095 +# args: limitType.getType(),totalLimit +Non-admin\ account\ cannot\ set\ the\ total\ %s\ limit\ greater\ than\:\ %s = 非管理员帐户无法将总{0}限制设置为大于:{1} + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2102 +# args: limitType.getType() +Non-admin\ account\ is\ only\ allowed\ to\ set\ the\ read/write\ %s\ limits. = 仅允许非管理员帐户设置读/写{0}限制。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2108 +# args: limitType.getType() +Non-admin\ account\ cannot\ set\ the\ read\ %s\ limits\ as\ unlimited. = 非管理员帐户无法将读取{0}限制设置为无限制。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2119 +# args: limitType.getType() +Non-admin\ account\ cannot\ set\ the\ write\ %s\ limits\ as\ unlimited. = 非管理员帐户无法将写入{0}限制设置为无限制。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2128 +# args: limitType.getType(),readLimit,writeLimit +Non-admin\ account\ cannot\ set\ the\ read/write\ %s\ limits\ greater\ than\:\ %s/%s = 非管理员帐户无法将读/写{0}限制设置为大于:{1}/{2} + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2215 +# args: self.getUuid() +volume\ [%s]\ isn't\ attached\ to\ any\ vm,\ cannot\ get\ qos\ by\ forceSync = 卷[{0}]未连接到任何VM,无法通过ForceSync获得QoS + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2221 +# args: self.getUuid() +volume\ [%s]\ isn't\ attached\ to\ any\ vm\ (or\ vm\ is\ not\ existed\ now),\ cannot\ sync\ volume\ qos = 卷[{0}]未连接到任何VM(或VM现在不存在),无法同步卷QoS + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2226 +# args: vm.getUuid() +vm\ [%s]'\ state\ must\ be\ Running\ or\ Paused\ to\ sync\ volume\ qos = VM[{0}]状态必须为“正在运行”或“已暂停”才能同步卷QoS + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2231 +# args: +vm\ [%s]'s\ HostUuid\ is\ null,\ cannot\ sync\ volume\ qos = VM[{0}]的HostUuid为空,无法同步卷QoS + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2377 +# args: msg.getVolume().getUuid(),msg.getVmInstanceUuid() +failed\ to\ detach\ shareable\ volume[uuid\:%s]\ from\ VmInstance[uuid\:%s] = 不能卸载云主机[uuid:{1}]上的共享盘[uuid:{0}] + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeBase.java:2389 +# args: StringUtils.join(errors, "\n\n") +failed\ to\ detach\ shareable\ volume\ from\ VmInstance\:[\n%s] = 不能卸载云主机上的共享盘,原因是{0} + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeFactoryImpl.java:89 +# args: resourceUuid +unsupported\ operation\ for\ setting\ root\ volume[%s]\ multiQueues. = 不支持设置根卷[{0}]多队列的操作。 + +# at: src/main/java/org/zstack/mevoco/MevocoVolumeFactoryImpl.java:93 +# args: resourceUuid +unsupported\ operation\ for\ setting\ virtio-scsi\ volume[%s]\ multiQueues. = 不支持设置virtio-SCSI卷[{0}]多队列的操作。 + +# at: src/main/java/org/zstack/mevoco/PauseWorldApiInterceptor.java:46 +# args: MevocoSystemTags.CONFIRM_CALL_API.getTagFormat() +ZStack\ has\ been\ paused,\ reject\ all\ API\ which\ are\ not\ read\ only.\ If\ you\ really\ want\ to\ call\ it\ and\ known\ the\ consequence,\ add\ '%s'\ into\ systemTags. = ZStack已暂停,拒绝所有非只读API。如果您确实想调用它并且知道结果,请将“{0}”添加到SystemTags中。 + +# at: src/main/java/org/zstack/mevoco/PremiumGlobalConfig.java:27 +# args: getName() +the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ global\ config\ [name\:%s] = 当前license版本不支持修改此全局设置[name:{0}] + +# at: src/main/java/org/zstack/mevoco/PremiumResourceConfig.java:22 +# args: globalConfig.getName() +the\ current\ version\ of\ license\ does\ not\ support\ modifying\ this\ resource\ config\ [name\:%s] = 当前版本的许可证不支持修改此资源配置[名称:{0}] + +# at: src/main/java/org/zstack/mevoco/VolumeQos.java:331 +# args: +cannot\ find\ mode\ from\ null\ VolumeQos = 无法从NULL卷中找到模式QoS + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:190 +# args: msg.getMonitorTriggerUuid() +cannot\ find\ monitor\ trigger[uuid\:%s],\ it\ may\ have\ been\ deleted = 不能找到触发监控器[uuid:{0}],它可能已经被删除了 + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:199 +# args: msg.getMonitorTriggerActionUuid() +cannot\ find\ monitor\ trigger\ action[uuid\:%s],\ it\ may\ have\ been\ deleted = 为找到这个监控触发行为[uuid:{0}],它可能已经被删除了 + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:243 +# args: msg.getResourceType() +the\ resource[type\:%s]\ doesn't\ have\ any\ monitoring\ items = 该资源[type:{0}]没有任何监控条目 + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:335 +# args: msg.getTargetResourceUuid(),msg.getSession().getAccountUuid() +the\ resource[uuid\:%s]\ doesn't\ belong\ to\ the\ account[uuid\:%s] = 该资源[uuid:{0}]不属于账户[uuid:{1}] + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:386 +# args: resourceUuid +cannot\ find\ type\ for\ the\ resource[uuid\:%s] = 未找到资源[uuid:{0}]这种类型 + +# at: src/main/java/org/zstack/monitoring/MonitorManagerImpl.java:391 +# args: resourceType,triggerExpression.getItem() +no\ monitoring\ item\ found\ for\ the\ resourceType[%s]\ and\ item[%s] = 未找到资源类型[{0}]和条目[{1}]这种监控条目 + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:50 +# args: args +A\ resource[name\:{resourceName},\ uuid\:{resourceUuid},\ type\:{resourceType}]'s\ monitoring\ trigger[uuid\:{triggerUuid}]\ changes\ status\ to\ {triggerStatus} = 资源[name:'{resourceName}', uuid:'{resourceUuid}', type:'{resourceType}']的监听触发器[uuid:'{triggerUuid}']修改状态为'{triggerStatus}' + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:55 +# args: +\n\=\=\=\ BELOW\ ARE\ DETAILS\ OF\ THE\ PREVIOUS\ ALERT\ \=\=\= = \n=== 以下是上一次警告内容 === + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:58 +# args: +\nalert\ details\: = \n警告内容: + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:59 +# args: args +\ncondition\:\ {itemName}\ {operator}\ {threshold} = \n环境: '{itemName}' '{operator}' '{threshold}' + +# at: src/main/java/org/zstack/monitoring/items/AlertText.java:60 +# args: args +\ncurrent\ value\:\ {value} = \n当前值: '{value}' + +# at: src/main/java/org/zstack/monitoring/items/host/HostCpuUtilItem.java:31 +# args: +Host\ CPU\ utilization = CPU使用率 + +# at: src/main/java/org/zstack/monitoring/items/vm/VmCpuUtilItem.java:29 +# args: +VM\ CPU\ utilization = 云主机CPU使用率 + +# at: src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java:98 +# args: ruleFile +fail\ to\ create\ new\ File[%s] = 无法创建新文件[{0}] + +# at: src/main/java/org/zstack/monitoring/prometheus/AlertRuleWriter.java:143 +# args: rb.name,r +conflict\ alert\ rule[%s],\ there\ has\ been\ a\ rule[%s]\ with\ the\ same\ name = 冲突提示规则[{0}],这里已经存在和它一样名称的规则 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusAlert.java:79 +# args: resourceName,resourceUuid,toI18nString(resourceType),itemName,toI18nString(expression.getOperator()),expression.getConstant(),value,tvo.getDuration() +ALERT\:\n\ resource[name\:\ %s,\ uuid\:\ %s,\ type\:\ %s]\nevent\:\ %s\ %s\ %s\ncurrent\ value\:\ %s\nduration\:\ %s\ seconds\n = 警告:\n 资源[名称: {0}, uuid: {1}, 类型: {2}]\n 事件: {3} {4} {5}\n 周期: {7}\n + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:40 +# args: msg.getRelativeTime() +the\ relativeTime[%s]\ is\ invalid,\ it\ must\ be\ in\ format\ of,\ for\ example,\ 10s,\ 1h = 相关时间[{0}]不合法,格式必须例如10s,1h + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusApiInterceptor.java:44 +# args: msg.getRelativeTime() +the\ relativeTime[%s]\ is\ invalid,\ it's\ too\ big = 相关时间[{0}]不合法,值's 过大 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilAlertWriter.java:95 +# args: +CPU\ number = CPU数量 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostCpuUtilItem.java:70 +# args: cpu,trigger.getTargetResourceUuid(),cpuNum +invalid\ cpu[%s],\ the\ host[uuid\:%s]\ doesn't\ have\ a\ CPU\ numbered\ by\ %s = 无效CPU数目[{0}],物理机[uuid:{1}]存在的CPU数目是{2} + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:92 +# args: +Host\ Disk\ Capacity = 物理机磁盘容量 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:98 +# args: +Host\ Disk\ Capacity\ type = 物理机磁盘容量类型 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostDiskCapacityAlertWriter.java:100 +# args: +Host\ devices = 物理机服务 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusHostNetworkIOAlertWriter.java:77 +# args: +Host = 物理机 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusMonitorProviderFactory.java:124 +# args: ret.get("errorType"),ret.get("error") +query\ failure,\ errorType\:%s,\ error\:\ %s = 查询失败,错误类型: {0}, 错误: {1} + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:81 +# args: +CPU\ Utilization = CPU使用率 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmCpuUtilAlertWriter.java:84 +# args: +CPU\ utilization\ type = CPU使用类型 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:86 +# args: +Disk\ IO = 磁盘IO + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:92 +# args: +Disk\ IO\ direction = 磁盘IO方向 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOAlertWriter.java:93 +# args: +Disk\ IO\ type = 磁盘IO类型 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmDiskIOItem.java:19 +# args: type,ALLOWED_TYPES +invalid\ type[%s],\ only\ %s\ are\ allowed = 无效类型[{0}],只有{1}被允许 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilAlertWriter.java:77 +# args: +Memory\ Utilization = 内存使用率 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:57 +# args: expression.getConstant() +invalid\ right\ value[%s],\ it\ must\ be\ a\ float\ or\ double\ number = 无效的参数值[{0}],它必须是一个float或者double类型的数值 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:53 +# args: expression.getConstant() +invalid\ right\ value[%s],\ it\ must\ be\ float\ or\ double\ number\ greater\ than\ zero\ and\ lesser\ than\ one = 无效参数值[{0}],它必须是一个float或者double类型的大于0小于1的数值 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmMemUtilItem.java:47 +# args: expression.getArguments().keySet() +invalid\ arguments\ %s,\ no\ argument\ is\ allowed = 无效参数列表{0},没有被参数被允许 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:84 +# args: +Network\ IO = 网络IO + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:89 +# args: +Network\ IO\ direction = 网络IO方向 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOAlertWriter.java:77 +# args: +Virtual\ Machine = 云主机器 + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:22 +# args: expression.getConstant() +invalid\ right\ value[%s],\ it\ must\ be\ a\ number(int,\ long,\ float,\ double) = 无效参数值[{0}],他应该是一个数字(int, long, float, double) + +# at: src/main/java/org/zstack/monitoring/prometheus/PrometheusVmNetworkIOItem.java:18 +# args: dir,ALLOWED_DIRECTION +invalid\ direction[%s],\ only\ %s\ are\ allowed = 无效direction[{0}],只有{1}被允许 + +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:106 +# args: expr,e.getMessage() +invalid\ expression\:\ %s,\ %s = 无效的语句: {0}, {1} + +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:110 +# args: expr +invalid\ expression\:\ %s,\ no\ expression\ found = 无效的语句: {0},未找到该语句 + +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:127 +# args: key +missing\ parameter\ '%s'\ in\ the\ expression = 在语句中缺失参数{0} + +# at: src/main/java/org/zstack/monitoring/trigger/expression/TriggerExpression.java:131 +# args: key,clz,value.getClass() +wrong\ type\ of\ parameter\ '%s'\ in\ the\ expression,\ it\ must\ be\ type\ of\ %s,\ but\ got\ %s = 在语句中{0}参数类型错误,它必须是{1}这种类型,但是获得的是{2} + +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:58 +# args: partNum +The\ number[value\:%s]\ is\ not\ a\ valid\ part\ number. = 编号[值:{0}]不是有效的物料编号。 + +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:69 +# args: mttyDeviceUuid,accu +The\ quantity\ exceeded.\ The\ device[uuid\:\ %s]\ required\ se\ devices\ number\ exceeds\ a\ quantiry[value\:\ %s]. = 数量超出。设备[uuid:{0}]所需的SE设备数量超过数量[值:{1}]。 + +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:93 +# args: rsp.getError() +failed\ to\ generate\ se\ devices,\ because\:%s = 无法生成SE设备,因为:{0} + +# at: src/main/java/org/zstack/mttyDevice/KvmMttyDeviceBackend/MttyDeviceKvmBackend.java:152 +# args: rsp.getError() +failed\ to\ ungenerate\ se\ devices,\ because\:%s = 无法取消生成SE设备,因为:{0} + +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:41 +# args: msg.getMttyDeviceUuid() +mtty\ device[uuid\:%s]\ is\ not\ virtualized\ into\ mdevs = MTTY设备[uuid:{0}]未虚拟化为MDEV + +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:58 +# args: msg.getMttyDeviceUuid() +mdev\ devices\ generated\ from\ mtty\ device[uuid\:%s]\ still\ attached\ to\ vm = 从MTTY设备[uuid:{0}]生成的MDEV设备仍连接到云主机 + +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:87 +# args: mtty.getHostUuid(),mtty.getUuid() +the\ host[uuid\:%s]\ that\ mtty\ device[uuid\:%s]\ in\ is\ not\ Connected = 未连接MTTY设备[uuid:{1}]所在的物理机[uuid:{0}] + +# at: src/main/java/org/zstack/mttyDevice/MttyDeviceApiInterceptor.java:78 +# args: msg.getMttyDeviceUuid() +mtty\ device[uuid\:%s]\ cannot\ be\ virtualized\ into\ mdevs = MTTY设备[uuid:{0}]无法虚拟化为MDEV + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:59 +# args: rpAddress +Rendezvous\ Point\ [%s]\ is\ not\ a\ unicast\ address = 组播聚合点地址[{0}]不是单播地址 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:63 +# args: multicastGroup +group\ address\ [%s]\ is\ not\ a\ multicast\ address = 地址 [{0}] 不是组播地址 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:75 +# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() +rp\ address\ pair\ [%s\:\ %s]\ already\ existed\ for\ multicast\ router\ [uuid\:%s] = 组播聚合点地址对[{0}: {1}]已经存在于组播路由器[uuid:{2}]的配置中 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterApiInterceptor.java:89 +# args: msg.getRpAddress(),msg.getGroupAddress(),msg.getUuid() +rp\ address\ tuple\ [%s\ \:\ %s]\ is\ not\ existed\ for\ multicast\ router\ [uuid\:%s] = 组播聚合点地址对[{0}: {1}]不存于组播路由器[uuid:{2}]的配置中 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:98 +# args: msg.getUuid() +multicastRouter[uuid\:%s]\ has\ not\ been\ attached\ to\ vpc\ router = 组播路由器[uuid:{0}]没有关联到VPC路由器 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:124 +# args: msg.getVpcRouterVmUuid() +multicast\ already\ enabled\ on\ vpc\ router\ uuid[\:%s] = VPC路由器[uuid:{0}]的组播路功能已经打开 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:317 +# args: msg.getUuid() +vpc\ router\ for\ multicast\ router\ [uuid\:%s]\ has\ been\ deleted = 组播路由器[uuid:{0}]关联的VPC路由器已经被删除 + +# at: src/main/java/org/zstack/multicast/router/MulticastRouterManagerImpl.java:760 +# args: msg.getUuid() +multicast\ router\ [uuid\:%s]\ is\ not\ attached\ to\ Vpc\ Router = 组播路由器[uuid:{0}]没有关联到VPC路由器 + +# at: src/main/java/org/zstack/multicast/router/backend/MulticastRouterVyosBackendImpl.java:95 +# args: vrUuid +multicast\ router\ [uuid\:%s]\ has\ been\ delete\ during\ enable\ multilcast\ on\ backend = 组播路由器[uuid:{0}]已经被删除 + +# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:91 +# args: msg.getNasFileSystemUuid() +nas\ file\ system\ [%s]\ is\ not\ existed\ yet = NAS文件系统[{0}]尚不存在 + +# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:139 +# args: type +cannot\ find\ nas\ factory\ for\ type\:\ %s = 找不到类型为{0}的NAS工厂 + +# at: src/main/java/org/zstack/nas/NasFileSystemManagerImpl.java:164 +# args: f.getClass().getSimpleName(),old.getClass().getSimpleName(),f.getNasFileSystemType() +duplicate\ NasFileSystemFactory[%s,\ %s]\ for\ type[%s] = 类型[{2}]的NASFileSystemFactory[{0},{1}]重复 + +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:63 +# args: msg.getL2NetworkUuid(),msg.getClusterUuid() +l2Network[uuid\:%s]\ has\ attached\ to\ cluster[uuid\:%s],\ can't\ attach\ again = 不能再次挂载二层网络[uuid:{0}],因为已经挂载到集群[uuid:{1}]上了 + +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:75 +# args: otherL2s.get(0),l2.getPhysicalInterface() +could\ not\ attach\ l2\ network,\ because\ there\ is\ another\ network\ [uuid\:%]\ on\ physical\ interface\ [%s]\ with\ different\ vswitch\ type = 无法连接二层网络,因为物理接口[{0}]上存在另一个具有不同vSwitch类型的网络[uuid:%] + +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:87 +# args: msg.getL2NetworkUuid(),msg.getClusterUuid() +l2Network[uuid\:%s]\ has\ not\ attached\ to\ cluster[uuid\:%s] = 二层网络[uuid:{0}]没有挂载到集群上[uuid:{1}] + +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:101 +# args: msg.getType() +unsupported\ l2Network\ type[%s] = 不支持的网络类型[{0}] + +# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:105 +# args: msg.getvSwitchType() +unsupported\ vSwitch\ type[%s] = 不支持的vSwitch类型[{0}] + +# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:626 +# args: vl2.getUuid(),vl2.getName(),msg.getClusterUuid(),vl2.getPhysicalInterface(),vl2.getVlan(),tl2.getUuid() +There\ has\ been\ a\ L2VlanNetwork[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s],\ vlan[%s].\ Failed\ to\ attach\ L2VlanNetwork[uuid\:%s] = 二层网络挂载失败[uuid:{5}]: 二层网络[uuid:{0}, name:{1}]的物理接口[{3}], vlan[{4}]已经挂载到集群[uuid:{2}]上 + +# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:608 +# args: l2.getUuid(),l2.getName(),msg.getClusterUuid(),l2.getPhysicalInterface(),tl2.getUuid() +There\ has\ been\ a\ l2Network[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s].\ Failed\ to\ attach\ l2Network[uuid\:%s] = 二层网络挂载失败[uuid:{4}]: 二层网络[uuid:{0}, name:{1}]的物理接口[{3}]]已经挂载到集群[uuid:{2}]上 + +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:84 +# args: msg.getvSwitchUuid(),msg.getVlan() +could\ not\ create\ L2PortGroupNetwork,\ because\ L2VirtualSwitchNetwork[uuid\:%s]\ already\ has\ L2PortGroupNetworks\ with\ the\ same\ vlanId[%s] = 创建端口组失败,因为虚拟交换机[uuid:{0}]已经存在vlanId[{1}]的端口组 + +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:106 +# args: vswitchVO.getPhysicalInterface(),msg.getClusterUuid() +could\ not\ attach\ L2VirtualSwitchNetwork,\ because\ interface[%s]\ in\ cluster[uuid\:%s]\ is\ already\ used\ for\ another\ L2VirtualSwitchNetwork = 挂载虚拟交换机失败,因为集群[uuid:{1}]中的网卡[{0}]已被其他虚拟交换机使用 + +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:113 +# args: msg.getClusterUuid() +could\ not\ attach\ L2VirtualSwitchNetwork,\ because\ there\ are\ no\ hosts\ in\ cluster[uuid\:%s] = 挂载虚拟交换机失败,因为集群[uuid:{0}]中不存在任何物理机 + +# at: src/main/java/org/zstack/network/l2/virtualSwitch/VirtualSwitchApiInterceptor.java:126 +# args: vswitchVO.getPhysicalInterface(),hostUuid +could\ not\ attach\ L2VirtualSwitchNetwork,\ because\ interface[%s]\ should\ be\ created\ on\ host[uuid\:%s] = 挂载虚拟交换机失败,因为网卡[{0}]应当在物理机[uuid:{1}]上创建 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java:231 +# args: inv.getUuid(),destHostUuid +cannot\ configure\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为云主机[uuid:{0}]在目标物理机[uuid:{1}]上配置VXLAN网络 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:77 +# args: vtepIps,hostUuid +find\ multiple\ vtep\ ips[%s]\ for\ one\ host[uuid\:%s],\ need\ to\ delete\ host\ and\ add\ again = 在一个物理机[uuid:{1}]发现多个VTEP IP,需要删除物理机在进行添加 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:82 +# args: hostUuid,l2vxlan.getPoolUuid() +failed\ to\ find\ vtep\ on\ host[uuid\:\ %s],\ please\ re-attach\ vxlanpool[uuid\:\ %s]\ to\ cluster. = 无法在物理机[uuid:{0}]上找到VTEP,请将vxlanpool[uuid:{1}]重新挂接到集群。 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:133 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vxlan.getVni(),hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vni\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 为二层网络[uuid:{1}, type:{2}, vni:{3}]在KVM物理机[uuid:{4}]上创建网桥[{0}]失败,错误细节: {5} + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:197 +# args: cmd.getCidr(),l2vxlan.getUuid(),l2vxlan.getName(),hostUuid,rsp.getError() +failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 为KVM物理机[uuid:{3}]上的L2 VXLAN 网络[uuid:{1}, name:{2}]检查CIDR[{0}]失败,错误细节: {4} + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:474 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vxlan.getVni(),hostUuid,rsp.getError() +failed\ to\ delete\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vni\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 无法删除KVM物理机[uuid:{4}]上的二层网络[uuid:{1},类型:{2},VNI:{3}]的网桥[{0}],因为{5} + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:261 +# args: l2Network.getUuid(),l2Network.getType(),hostUuid,rsp.getError() +failed\ to\ realize\ vxlan\ network\ pool[uuid\:%s,\ type\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 无法在KVM物理机[uuid:{2}]上实现VXLAN网络池[uuid:{0},类型:{1}],因为{3} + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:111 +# args: cmd.getCidr(),vxlanPool.getUuid(),vxlanPool.getName(),hostUuid,rsp.getError() +failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetworkPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 检查在kvm物理机[uuid:{3}]上的l2VxlanNetworkPool[uuid:{1}, name:{2}]的CIDR[{0}]失败,{4} + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:37 +# args: VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat() +need\ to\ input\ one\ system\ tag\ like\ \:\ [%s] = 需要输入一个系统标签,格式为:[{0}] + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:49 +# args: tag,VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat() +wrong\ system\ tag\ [%s],\ should\ be\ like\ \:\ [%s] = 错误的系统标签[{0}],格式应该为:[{1}] + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:55 +# args: tag +wrong\ cidr\ format\ in\ system\ tag\ [%s] = 系统标签[{0}]中的cidr格式错误 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:64 +# args: inv.getType(),overlappedPool +overlap\ vni\ range\ with\ %s\ [%s] = 与{0}[{1}]的vni范围重叠 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java:99 +# args: +vxlan\ network\ pool\ doesn't\ support\ create\ l3\ network = vxlan network pool不支持创建三层网络 + +# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java:56 +# args: msg.getHostUuid(),msg.getPoolUuid() +vxlan\ vtep\ address\ for\ host\ [uuid\ \:\ %s]\ and\ pool\ [uuid\ \:\ %s]\ pair\ already\ existed = 物理机[uuid : {0}]在vxlan资源池[uuid : {1}]中隧道端点地址已经配置 + +# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:27 +# args: +it\ is\ used = 被占用 + +# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:25 +# args: +it\ is\ not\ in\ this\ range = 不在IP地址范围内 + +# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:23 +# args: +it\ is\ gateway = 网关不能分配 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:159 +# args: l2VO.getUuid(),msg.getL3NetworkUuid() +could\ not\ set\ mtu\ because\ l2\ network[uuid\:%s]\ of\ l3\ network\ [uuid\:%s]\ mtu\ can\ not\ be\ bigger\ than\ the\ novlan\ network = 无法设置MTU,因为三层网络[uuid:{1}]MTU的二层网络[uuid:{0}]不能大于NoVLAN网络 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:175 +# args: +can\ not\ delete\ the\ last\ normal\ ip\ range\ because\ there\ is\ still\ has\ address\ pool = 无法删除最后一个正常IP范围,因为仍有地址池 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:190 +# args: +you\ must\ update\ system\ and\ category\ both = 必须同时更行system属性和category属性 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:474 +# args: L3NetworkCategory.validCombination +not\ valid\ combination\ of\ system\ and\ category,only\ %s\ are\ valid = 无效的system属性和category属性的组合,只有{0}是有效的 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:237 +# args: msg.getIp() +invalid\ IP[%s] = 错误的IP值[{0}] + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:221 +# args: msg.getL3NetworkUuid() +no\ ip\ range\ in\ l3[%s] = 没有IP在三层网络范围中 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:225 +# args: msg.getRouterInterfaceIp(),ipr.getUuid(),ipr.getNetworkCidr(),msg.getL3NetworkUuid() +ip[%s]\ is\ not\ in\ the\ cidr\ of\ ip\ range[uuid\:%s,\ cidr\:%s]\ which\ l3\ network[%s]\ attached = IP[{0}]没有在三层网络[{3}]的CIDR的IP范围内[uuid:{1}, cidr:{2}] + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:229 +# args: msg.getRouterInterfaceIp(),ipr.getUuid(),ipr.getStartIp(),ipr.getEndIp(),msg.getL3NetworkUuid() +ip[%s]\ in\ ip\ range[uuid\:%s,\ startIp\:%s,\ endIp\:%s]\ which\ l3\ network[%s]\ attached,\ this\ is\ not\ allowed = IP[{0}]在三层网络[{4}]绑定的IP范围内[uuid:{1}, startIp:{2}, endIp:{3}],这是不被允许的 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:243 +# args: +ipRangeUuid\ and\ l3NetworkUuid\ cannot\ both\ be\ null;\ you\ must\ set\ either\ one. = IP段和L3的uuid不能都为空,您必须选择一个填上 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:276 +# args: msg.getStart(),msg.getStart() +could\ not\ get\ free\ ip\ with\ start[ip\:%s],because\ start[ip\:%s]\ is\ not\ a\ correct\ ipv6\ address = 无法使用start[IP:{0}]获取可用IP,因为start[IP:{1}]不是正确的IPv6地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:274 +# args: msg.getStart(),msg.getStart() +could\ not\ get\ free\ ip\ with\ start[ip\:%s],because\ start[ip\:%s]\ is\ not\ a\ correct\ ipv4\ address = 无法使用start[IP:{0}]获取可用IP,因为start[IP:{1}]不是正确的IPv4地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:272 +# args: msg.getStart(),msg.getL3NetworkUuid() +could\ not\ get\ free\ ip\ with\ start[ip\:%s],because\ l3Network[uuid\:%s]\ is\ dual\ stack = 无法使用start[IP:{0}]获取可用IP,因为L3Network[uuid:{1}]是双堆栈 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:408 +# args: msg.getNetworkCidr() +%s\ is\ not\ a\ valid\ network\ cidr = {0}不是有效的无类别域间路由 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:304 +# args: msg.getGateway() +%s\ is\ not\ a\ valid\ ipv6\ address = {0}不是有效的IPv6地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:308 +# args: msg.getStartIp(),msg.getEndIp(),msg.getPrefixLen(),msg.getGateway() +[startIp\ %s,\ endIp\ %s,\ prefixLen\ %d,\ gateway\ %s]\ is\ not\ a\ valid\ ipv6\ range = IPv6地址段{0}-{1}/{2}, 网关{3}不是有效的IPv6地址段 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:633 +# args: +adding\ normal\ ip\ range\ must\ specify\ gateway\ ip\ address = 添加正常IP范围必须指定网关IP地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:324 +# args: +can\ not\ add\ ip\ range,\ because\ ipv6\ address\ pool\ is\ not\ supported = 无法添加IP范围,因为不支持IPv6地址池 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:335 +# args: IPv6Constants.IPV6_PREFIX_LEN_MIN,IPv6Constants.IPV6_PREFIX_LEN_MAX +ip\ range\ prefix\ length\ is\ out\ of\ range\ [%d\ -\ %d]\ = IPv6地址前缀长度不在有效范围内[{0}-{1}] + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:342 +# args: +can\ not\ add\ ip\ range,\ because\ system\ network\ doesn't\ support\ ipv6\ yet = 无法添加IP范围,因为系统网络尚不支持IPv6 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:348 +# args: ipr.getAddressMode(),rangeVOS.get(0).getAddressMode() +addressMode[%s]\ is\ different\ from\ L3Netowork\ address\ mode[%s] = 地址模式[{0}]和三层网络的地址模式[{1}]不同 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:354 +# args: IPv6Constants.IPV6_STATELESS_PREFIX_LEN +ipv6\ prefix\ length\ must\ be\ %d\ for\ Stateless-DHCP\ or\ SLAAC = Stateless-DHCP or SLAAC地址模式IPv6网络前缀长度必须是{0} + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:364 +# args: ipr.getStartIp(),ipr.getEndIp(),r.getStartIp(),r.getEndIp() +new\ ip\ range\ [startip\ \:%s,\ endip\ \:%s]\ is\ overlaped\ with\ old\ ip\ range[startip\ \:%s,\ endip\ \:%s] = 新的IP地址段[{0}-{1}]和旧的IP地址段[{2}-{3}]冲突 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:374 +# args: r.getNetworkCidr(),ipr.getNetworkCidr() +new\ network\ CIDR\ [%s]\ is\ different\ from\ old\ network\ cidr\ [%s] = 同一三层网络上不能加载多个CIDR。 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:618 +# args: ipr.getGateway(),r.getGateway() +new\ add\ ip\ range\ gateway\ %s\ is\ different\ from\ old\ gateway\ %s = 新ip段的网关地址{0}和已有ip段的网关地址{1}冲突 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:611 +# args: ipr.getGateway(),ipr.getStartIp(),ipr.getEndIp() +gateway[%s]\ can\ not\ be\ part\ of\ range[%s,\ %s] = 网关[{0}]不能是IP段[{1}, {2}]的一部分 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:401 +# args: msg.getNetworkCidr() +%s\ is\ not\ an\ allowed\ network\ cidr,\ because\ it\ doesn't\ have\ usable\ ip\ range = {0}是不允许的无类别域间路由,因为它不支持可用的IP段 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:405 +# args: msg.getGateway(),msg.getNetworkCidr() +%s\ is\ not\ the\ first\ or\ last\ address\ of\ the\ cidr\ %s = {0}不是CIDR{1}的第一个或最后一个地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:432 +# args: +ipRangeUuids,\ L3NetworkUuids,\ zoneUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = ipRangeUuids, L3NetworkUuids, zoneUuids 至少一个不是为空列表,或者全部不为空 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:453 +# args: msg.getType() +unsupported\ l3network\ type[%s] = 不支持的三层网络类型[{0}] + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:459 +# args: msg.getDnsDomain() +%s\ is\ not\ a\ valid\ domain\ name = {0}不是有效的域名 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:580 +# args: r.getUuid(),r.getStartIp(),r.getEndIp() +overlap\ with\ ip\ range[uuid\:%s,\ start\ ip\:%s,\ end\ ip\:\ %s] = 重叠的IP段[uuid:{0}, 起始ip:{1}, 尾ip: {2}] + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:523 +# args: l3Vo.getUuid(),l3Vo.getName() +l3\ network\ [uuid\ %s\:\ name\ %s]\ is\ not\ a\ public\ network,\ address\ pool\ range\ can\ not\ be\ added = 三层网络[uuid{0}:名称{1}]不是公用网络,无法添加地址池范围 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:527 +# args: ipr.getStartIp(),ipr.getEndIp() +the\ IP\ range[%s\ ~\ %s]\ contains\ D\ class\ addresses\ which\ are\ for\ multicast = 这个IP段[{0} ~ {1}]包含了D类的组播地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:531 +# args: ipr.getStartIp(),ipr.getEndIp() +the\ IP\ range[%s\ ~\ %s]\ contains\ E\ class\ addresses\ which\ are\ reserved = 这个IP段[{0} ~ {1}]包含了E类的保留地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:535 +# args: ipr.getStartIp(),ipr.getEndIp() +the\ IP\ range[%s\ ~\ %s]\ contains\ link\ local\ addresses\ which\ are\ reserved = 这个IP段[{0} ~ {1}]包含了本地的保留地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:541 +# args: ipr.getGateway(),ipr.getStartIp(),ipr.getNetmask() +the\ gateway[%s]\ is\ not\ in\ the\ subnet\ %s/%s = 网关[{0}]不在子网{1}/{2} + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:545 +# args: +ip\ allocation\ can\ not\ contain\ network\ address\ or\ broadcast\ address = ip 地址分配不能包含网络地址或广播的地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:551 +# args: ipr.getStartIp() +start\ ip[%s]\ is\ not\ a\ IPv4\ address = 开始的ip[{0}] 不是IPV4的地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:555 +# args: ipr.getEndIp() +end\ ip[%s]\ is\ not\ a\ IPv4\ address = 结束的ip[{0}] 不是IPV4的地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:559 +# args: ipr.getGateway() +gateway[%s]\ is\ not\ a\ IPv4\ address = 网关[{0}]不是IPV4的地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:563 +# args: ipr.getNetmask() +netmask[%s]\ is\ not\ a\ netmask,\ and\ the\ IP\ range\ netmask\ cannot\ be\ 0.0.0.0 = 子网掩码[{0}]不是子网掩码,并且IP段的子网掩码不能是0.0.0.0 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:569 +# args: ipr.getStartIp(),ipr.getEndIp() +start\ ip[%s]\ is\ behind\ end\ ip[%s] = 起始ip[{0}]在尾ip[{1}]后 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:596 +# args: r.getUuid(),rcidr,cidr +multiple\ CIDR\ on\ the\ same\ L3\ network\ is\ not\ allowed.\ There\ has\ been\ a\ IP\ range[uuid\:%s,\ CIDR\:%s],\ the\ new\ IP\ range[CIDR\:%s]\ is\ not\ in\ the\ CIDR\ with\ the\ existing\ one = 在相同的三层网络上多个CIDR是不允许的,已有的IP范围 [uuid: {0},CIDR: {1}]。新的IP范围 [CIDR: {2}] 不在现有的一个CIDR + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:606 +# args: ipr.getEndIp(),ipr.getStartIp(),ipr.getNetmask() +the\ endip[%s]\ is\ not\ in\ the\ subnet\ %s/%s = IP段结束地址不在子网{1}/{2}范围内 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:659 +# args: msg.getDns(),msg.getL3NetworkUuid() +there\ has\ been\ a\ DNS[%s]\ on\ L3\ network[uuid\:%s] = 在三层网络[uuid:{1}]上已经存在一个DNS[{0}] + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:692 +# args: msg.getL3NetworkUuid() +prefix\ [%s]\ is\ not\ a\ IPv4\ network\ cidr = 网络段{0}不是合法的网络段 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:679 +# args: msg.getNexthop() +nexthop[%s]\ is\ not\ a\ IPv4\ address = 下一跳{0}不是有效的IP地址 + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:686 +# args: msg.getPrefix(),msg.getL3NetworkUuid() +there\ has\ been\ a\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = 三层网络{1}已配置物理机路由{0} + +# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:699 +# args: msg.getPrefix(),msg.getL3NetworkUuid() +there\ is\ no\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = 三层网络{1}没有物理机路由{0} + +# at: src/main/java/org/zstack/network/plugin/FlatGratuitousARPBackend.java:286 +# args: rsp.getError() +apply\ gratuitous\ arp\ error,\ because\:%s = 应用无故ARP错误,原因:{0} + +# at: src/main/java/org/zstack/network/plugin/FlatGratuitousARPBackend.java:329 +# args: rsp.getError() +release\ gratuitous\ arp\ error,\ because\:%s = 释放无端的ARP错误,原因:{0} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:248 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ vm\ nic[uuid\:%s]\ not\ found = 无法设置VM NIC安全组,因为找不到VM NIC[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:254 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ the\ vm\ nic[uuid\:%s]\ not\ attached\ to\ any\ security\ group = 无法设置VM NIC安全组,因为VM NIC[uuid:{0}]未连接到任何安全组 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:261 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ security\ group[uuid\:%s]\ not\ found = 无法设置VM NIC安全组,因为找不到安全组[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:266 +# args: priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ cannot\ be\ less\ than\ 1 = 无法设置VM NIC安全组,因为优先级无效,优先级[{0}]不能小于1 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:270 +# args: aoMap.get(priority),ao.getSecurityGroupUuid(),priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ priority,\ both\ security\ group\ %s\ and\ %s\ have\ priority[%d] = 无法设置VM NIC安全组,因为优先级重复,安全组{0}和{1}都具有优先级[{2}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:273 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ security\ group[uuid\:%s] = 无法设置VM NIC安全组,因为安全组[uuid:{0}]重复 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:285 +# args: priorities[0] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority\ expects\ to\ start\ at\ 1,\ but\ [%d] = 无法设置VM NIC安全组,因为优先级无效,优先级应从1开始,但[{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:289 +# args: priorities[i],priorities[i + 1] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ and\ priority[%d]\ expected\ to\ be\ consecutive = 无法设置VM NIC安全组,因为优先级无效,优先级[{0}]和优先级[{1}]应是连续的 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:301 +# args: ref.getSecurityGroupUuid(),sgOwnerAccountUuid +could\ no\ set\ vm\ nic\ security\ Group,\ because\ securityGroup[uuid\:%s]\ is\ already\ attached\ on\ this\ nic\ by\ account[uuid\:%s],\ current\ user\ does\ not\ have\ permission\ to\ delete = 无法设置VM NIC安全组,因为SecurityGroup[uuid:{0}]已由帐户[uuid:{1}]附加在此NIC上,当前用户没有删除权限 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:310 +# args: +could\ no\ change\ security\ group\ rule\ state,\ because\ ruleUuids\ is\ empty = 无法更改安全组规则状态,因为RuleUIds为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:314 +# args: msg.getSecurityGroupUuid() +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group[uuid\:%s]\ not\ found = 无法更改安全组规则状态,因为找不到安全组[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:322 +# args: r +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group\ rule[uuid\:%s]\ not\ found = 无法更改安全组规则状态,因为找不到安全组规则[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:331 +# args: +could\ no\ change\ security\ group\ rule\ state,\ because\ no\ security\ group\ rule\ state\ need\ to\ change = 无法更改安全组规则状态,因为无需更改安全组规则状态 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:339 +# args: +could\ no\ change\ vm\ nic\ security\ policy,\ because\ ingress\ policy\ and\ egress\ policy\ cannot\ be\ both\ null = 无法更改VM NIC安全策略,因为入口策略和出口策略不能同时为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:342 +# args: msg.getIngressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ ingress\ policy[%s] = 无法更改VM NIC安全策略,因为入口策略[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:346 +# args: msg.getEgressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ egress\ policy[%s] = 无法更改VM NIC安全策略,因为出口策略[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:350 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ not\ found = 无法更改VM NIC安全策略,因为找不到VM NIC[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:355 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ has\ no\ security\ policy = 无法更改VM NIC安全策略,因为VM NIC[uuid:{0}]没有安全策略 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:369 +# args: msg.getType() +could\ not\ update\ security\ group\ rule\ priority,\ because\ invalid\ type[%s] = 无法更新安全组规则优先级,因为类型[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:374 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ is\ not\ exist = 无法更新安全组规则优先级,因为安全组[uuid:{0}]不存在 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:378 +# args: +could\ not\ update\ security\ group\ rule\ priority,\ because\ rules\ is\ empty = 无法更新安全组规则优先级,因为规则为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:388 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ rules\ size\ not\ match = 无法更新安全组规则优先级,因为安全组[uuid:{0}]规则大小不匹配 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:393 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ priority[%d]\ is\ invalid = 无法更新安全组规则优先级,因为规则优先级[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:396 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ has\ duplicate = 无法更新安全组规则优先级,因为优先级[{0}]重复 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:402 +# args: ao.getRuleUuid(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule[uuid\:%s]\ not\ in\ security\ group[uuid\:%s] = 无法更新安全组规则优先级,因为规则[uuid:{0}]不在安全组[uuid:{1}]中 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:405 +# args: ao.getPriority(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ not\ in\ security\ group[uuid\:%s] = 无法更新安全组规则优先级,因为优先级[{0}]不在安全组[uuid:{1}]中 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:410 +# args: +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ uuid\ duplicate = 无法更新安全组规则优先级,因为规则uuid重复 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:417 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule\ uuid[%s]\ is\ not\ exist = 无法更改安全组规则,因为安全组规则uuid[{0}]不存在 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:423 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ is\ default\ rule,\ only\ the\ description\ and\ status\ can\ be\ set = 无法更改安全组规则,因为安全组规则[{0}]是默认规则,只能设置描述和状态 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:429 +# args: msg.getUuid(),SecurityGroupConstant.DEFAULT_RULE_PRIORITY +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ priority\ cannot\ be\ set\ to\ default\ rule\ priority[%d] = 无法更改安全组规则,因为安全组规则[{0}]优先级无法设置为默认规则优先级[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:438 +# args: vo.getType(),count.intValue(),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = 无法更改安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:441 +# args: vo.getType().toString(),count.intValue() +could\ not\ change\ security\ group\ rule,\ because\ the\ maximum\ priority\ of\ %s\ rule\ is\ [%d] = 无法更改安全组规则,因为{0}规则的最高优先级为[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:450 +# args: msg.getState() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ state[%s] = 无法更改安全组规则,因为状态[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:458 +# args: msg.getAction() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ action[%s] = 无法更改安全组规则,因为操作[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:466 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ protocol[%s] = 无法更改安全组规则,因为协议[{0}]无效 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:498 +# args: msg.getUuid(),msg.getSrcIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Egress,\ srcIpRange[%s]\ cannot\ be\ set = 无法更改安全组规则,因为安全组规则[{0}]类型为出口,无法设置SrcIPRange[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:495 +# args: msg.getUuid(),msg.getDstIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Ingress,\ dstIpRange[%s]\ cannot\ be\ set = 无法更改安全组规则,因为安全组规则[{0}]类型为入口,无法设置DSTIPRange[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:488 +# args: msg.getSrcIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ srcIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = 无法更改安全组规则,因为已设置SrcIPRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:501 +# args: msg.getDstIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ dstIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = 无法更改安全组规则,因为已设置DSTIPRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:508 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ not\ found = 无法更改安全组规则,因为找不到远程安全组[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:511 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ is\ set,\ srcIpRange\ and\ dstIpRange\ must\ be\ empty = 无法更改安全组规则,因为已设置远程安全组[uuid:{0}],SrcIPRange和DstIPRange必须为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:564 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ must\ be\ set = 无法更改安全组规则,因为规则协议为[{0}],必须设置DSTPortRange + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:556 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ empty = 无法更改安全组规则,因为规则协议为[{0}],DstPortRange不能为空 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:551 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ set = 无法更改安全组规则,因为规则协议为[{0}],无法设置目标映射 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:595 +# args: JSONObjectUtil.toJsonString(sao),o.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = 无法更改安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:721 +# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() +security\ group[uuid\:%s]\ has\ not\ attached\ to\ l3Network[uuid\:%s],\ can't\ detach = 不能卸载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为还未挂载 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:757 +# args: +can't\ delete\ rules\ of\ different\ security\ group = 无法删除不同安全组的规则 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:760 +# args: vo.getUuid() +can't\ delete\ default\ rule[uuid\:%s] = 无法删除默认规则[uuid:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:780 +# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() +security\ group[uuid\:%s]\ has\ attached\ to\ l3Network[uuid\:%s],\ can't\ attach\ again = 不能再次挂载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为已经挂载了 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:788 +# args: msg.getL3NetworkUuid(),SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE +the\ L3\ network[uuid\:%s]\ doesn't\ have\ the\ network\ service\ type[%s]\ enabled = 三层网络[uuid:{0}]没有开启[{1}]类型的网络服务 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:850 +# args: wrongUuids,securityGroupUuid +VM\ nics[uuids\:%s]\ are\ not\ on\ L3\ networks\ that\ have\ been\ attached\ to\ the\ security\ group[uuid\:%s] = 云主机网卡[uuids:{0}]不在安全组[uuid:{1}]挂载的三层网络上 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:886 +# args: uuid +could\ not\ add\ security\ group\ rule,\ because\ security\ group[uuid\:%s]\ does\ not\ exist = 无法添加安全组规则,因为安全组[uuid:{0}]不存在 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:875 +# args: SecurityGroupConstant.ONE_API_RULES_MAX_NUM +could\ not\ add\ security\ group\ rule,\ because\ the\ rules\ cannot\ be\ empty\ or\ exceed\ the\ max\ number\ %d = 无法添加安全组规则,因为规则不能为空或超过最大数量{0} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:880 +# args: msg.getRemoteSecurityGroupUuids() +could\ not\ add\ security\ group\ rule,\ because\ duplicate\ uuid\ in\ remoteSecurityGroupUuids\:\ %s = 无法添加安全组规则,因为RemoteSecurityGroupuuid中存在重复的uuid:{0} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:891 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ remote\ security\ group\ uuid\ is\ conflict = 无法添加安全组规则,因为远程安全组uuid冲突 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:927 +# args: SecurityGroupConstant.DEFAULT_RULE_PRIORITY,SecurityGroupConstant.LOWEST_RULE_PRIORITY +could\ not\ add\ security\ group\ rule,\ because\ rule\ priority\ must\ greater\ than\ %d\ or\ equals\ %d = 无法添加安全组规则,因为规则优先级必须大于{0}或等于{1} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:935 +# args: ao.getType(),SecurityGroupRuleType.getAllType() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ type[%s],\ valid\ types\ are\ %s = 无法添加安全组规则,因为规则类型[{0}]无效,有效类型为{1} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:942 +# args: ao.getState(),SecurityGroupRuleState.getAllState() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ state[%s],\ valid\ states\ are\ %s = 无法添加安全组规则,因为规则状态[{0}]无效,有效状态为{1} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:947 +# args: ao.getProtocol(),SecurityGroupRuleProtocolType.getAllProtocol() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ protocol[%s],\ valid\ protocols\ are\ %s = 无法添加安全组规则,因为规则协议[{0}]无效,有效协议为{1} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:954 +# args: ao.getAction(),SecurityGroupRuleAction.getAllAction() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ action[%s],\ valid\ actions\ are\ %s = 无法添加安全组规则,因为规则操作[{0}]无效,有效操作为{1} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:962 +# args: ao.getIpVersion(),IPv6Constants.IPv4,IPv6Constants.IPv6 +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ ipVersion[%d],\ valid\ ipVersions\ are\ %d/%d = 无法添加安全组规则,因为规则IPVersion[{0}]无效,有效的IPVersion为{1}/{2} + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:990 +# args: ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ dstIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ ingress\ rule = 无法添加安全组规则,因为不允许为入口规则设置DSTIPRange[{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:995 +# args: ao.getAllowedCidr(),ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ srcIpRange[%s]\ are\ in\ conflict = 无法添加安全组规则,因为allowedcidr[{0}]和srciprange[{1}]冲突 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:984 +# args: ao.getDstIpRange(),ao.getRemoteSecurityGroupUuid() +could\ not\ add\ security\ group\ rule,\ because\ the\ ip\ range[%s]\ and\ remoteSecurityGroupUuid[%s]\ are\ in\ conflict = 无法添加安全组规则,因为IP范围[{0}]和RemoteSecurityGroupuuid[{1}]冲突 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:972 +# args: ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ srcIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ egress\ rule = 无法添加安全组规则,因为不允许为出口规则设置SrcIPRange[{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:977 +# args: ao.getAllowedCidr(),ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ dstIpRange[%s]\ are\ in\ conflict = 无法添加安全组规则,因为AllowedCidr[{0}]和DSTIPRange[{1}]冲突 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1026 +# args: ao.getEndPort(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ endPort[%d],\ endPort\ must\ be\ greater\ than\ or\ equal\ to\ startPort[%d] = 无法添加安全组规则,因为规则endPort[{0}]无效,endPort必须大于或等于startPort[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1029 +# args: ao.getDstPortRange(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ dstPortRange[%s]\ and\ starPort[%s]\ are\ in\ conflict = 无法添加安全组规则,因为DstPortRange[{0}]和StarPort[{1}]冲突 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1040 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ TCP/UDP\ must\ set\ dstPortRange = 无法添加安全组规则,因为协议类型TCP/UDP必须设置DSTPortRange + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1018 +# args: ao.getDstPortRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ dstPortRange[%s] = 无法添加安全组规则,因为协议类型ALL或ICMP无法设置DstPortRange[{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1021 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ startPort\ or\ endPort = 无法添加安全组规则,因为协议类型ALL或ICMP无法设置StartPort或EndPort + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1050 +# args: JSONObjectUtil.toJsonString(newRules.get(i)),JSONObjectUtil.toJsonString(newRules.get(j)) +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ and\ rule[%s]\ are\ dupilicated = 无法添加安全组规则,因为规则[{0}]和规则[{1}]重复 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1074 +# args: JSONObjectUtil.toJsonString(sao),vo.getUuid() +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = 无法添加安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1089 +# args: SecurityGroupRuleType.Egress,SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ has\ reached\ the\ maximum\ limit[%d] = 无法添加安全组规则,因为安全组{0}规则已达到最大限制[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1097 +# args: SecurityGroupRuleType.Egress,(egressRuleCount + toCreateEgressRuleCount),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = 无法添加安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1101 +# args: msg.getPriority(),ingressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ ingress\ rule\ maximum\ priority\ is\ [%d] = 无法添加安全组规则,因为优先级[{0}]必须连续,入口规则最大优先级为[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1104 +# args: msg.getPriority(),egressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ egress\ rule\ maximum\ priority\ is\ [%d] = 无法添加安全组规则,因为优先级[{0}]必须是连续的,出口规则最大优先级为[{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:1908 +# args: ref.getVmNicUuid(),msg.getSecurityGroupUuid() +vm\ nic[uuid\:%s]\ has\ been\ attach\ to\ security\ group[uuid\:%s] = VM NIC[uuid:{0}]已连接到安全组[uuid:{1}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:1917 +# args: SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE,nic.getL3NetworkUuid(),nic.getUuid() +the\ netwotk\ service[type\:%s]\ not\ enabled\ on\ the\ l3Network[uuid\:%s]\ of\ nic[uuid\:%s] = 网络服务[类型:{0}]未在NIC[uuid:{2}]的L3网络[uuid:{1}]上启用 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:153 +# args: SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE,l3Uuid +the\ netwotk\ service[type\:%s]\ not\ enabled\ on\ the\ l3Network[uuid\:%s] = 未在L3网络[uuid:{1}]上启用网络服务[类型:{0}] + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java:1051 +# args: ao.getRuleUuid() +failed\ to\ chenge\ rule[uuid\:%s]\ priority,\ beacuse\ it's\ not\ found = 无法更改规则[uuid:{0}]的优先级,因为找不到该优先级 + +# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:88 +# args: msg.getL3NetworkUuid() +L3Network\ [uuid\:\ %s]\ provide\ type\ null = 三层网络{0}后端为空 + +# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:113 +# args: msg.getL3NetworkUuid() +L3Network\ [uuid\:\ %s]\ does\ not\ have\ host\ route\ service = 三层网络{0}没有物理机路由功能 + +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:107 +# args: +networkServices\ cannot\ be\ empty = 网络服务(networkServices)不能为空 + +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:68 +# args: puuid +network\ service\ for\ provider[uuid\:%s]\ must\ be\ specified = 服务提供器[uuid:{0}]的网络服务必须被指定 + +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:73 +# args: puuid +cannot\ find\ network\ service\ provider[uuid\:%s]\ or\ it\ provides\ no\ services = 无法找到网络服务提供器[uuid:{0}]或它没有提供任何服务 + +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:87 +# args: puuid,notSupported +network\ service\ provider[uuid\:%s]\ doesn't\ provide\ services%s = 网络服务提供器[uuid:{0}]无法提供服务{1} + +# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:99 +# args: type,msg.getL3NetworkUuid() +there\ has\ been\ a\ network\ service[%s]\ attached\ to\ L3\ network[uuid\:%s] = 已经有一个网络服务[{0}]被挂载到三层网络[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java:332 +# args: l3NetworkUuid,serviceType +L3Network[uuid\:%s]\ doesn't\ have\ network\ service[type\:%s]\ enabled\ or\ no\ provider\ provides\ this\ network\ service = 三层网络[uuid:{0}]上没有网络服务[type:{1}]被启用或没有服务提供器提供该网络服务 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:87 +# args: msg.getVmNicUuid() +vmNic[uuid\:%s]\ is\ not\ attached\ to\ vmInstance,\ cannot\ get\ attachable\ eips = vmnic[uuid:{0}]未连接到VMInstance,无法获取可连接的EIP + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:93 +# args: +either\ eipUuid\ or\ vipUuid\ must\ be\ set = eipUuid或vipUuid必须有一个被指定 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:99 +# args: msg.getEipUuid() +eip[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ cannot\ get\ attachable\ vm\ nic = eip[uuid:{0}]没有被启用,无法获取可挂载的云主机网卡 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:137 +# args: guestIpUuid,vmNicUuid +ip\ [uuid\:%s]\ is\ attached\ to\ vm\ nic\ [%s] = IP地址[uuid:{0}]已经绑定到网卡[{1}] + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:148 +# args: msg.getEipUuid(),vmNicUuid +eip[uuid\:%s]\ has\ attached\ to\ another\ vm\ nic[uuid\:%s],\ can't\ attach\ again = eip[uuid:{0}]已经被挂载到另外一台云主机网卡[uuid:{1}],无法再次挂载 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:154 +# args: msg.getEipUuid(),EipState.Enabled,state +eip[uuid\:\ %s]\ can\ only\ be\ attached\ when\ state\ is\ %s,\ current\ state\ is\ %s = eip[uuid:{0}]只有在状态(state)为{1}的情况下可以被挂载,当前状态是{2} + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:184 +# args: msg.getVmNicUuid(),msg.getEipUuid() +guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ EIP[uuid\:%s]\ are\ the\ same\ network = 云主机网卡[uuid:{0}]的客户三层网络,和EIP[uuid:{1}]的虚拟ip 三层网络是同一个网络 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:203 +# args: msg.getEipUuid(),msg.getVmNicUuid() +Ip\ address\ [uuid\:%s]\ is\ not\ belonged\ to\ nic\ [uuid\:%s] = IP地址[uuid:{0}]没有绑定到网卡[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:216 +# args: msg.getUuid() +eip[uuid\:%s]\ has\ not\ attached\ to\ any\ vm\ nic = eip[uuid:{0}]还没有被挂载到任意云主机网卡 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:239 +# args: vipIp.getIpVersion(),guestIp.getIpVersion() +vip\ ipVersion\ [%d]\ is\ different\ from\ guestIp\ ipVersion\ [%d]. = 虚拟IP的协议号[{0}]和网卡的IP协议号[{1}]不同 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:246 +# args: vipIp.getIp(),guestRange.getStartIp(),guestRange.getEndIp() +Vip[%s]\ is\ in\ the\ guest\ ip\ range\ [%s,\ %s] = 虚拟IP[{0}]和网卡的IP不能在相同地址段[{1}-{2}] + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:266 +# args: vmUuid,vip.getL3NetworkUuid(),vip.getUuid(),vip.getName(),vip.getIp() +the\ vm[uuid\:%s]\ that\ the\ EIP\ is\ about\ to\ attach\ is\ already\ on\ the\ public\ network[uuid\:%s]\ from\ which\ the\ vip[uuid\:%s,\ name\:%s,\ ip\:%s]\ comes = EIP将要挂载到的云主机[uuid:{0}]已经处于公共网络[uuid:{1}]上,该网络上已有vip[uuid:{2}, name:{3}, ip:{4}] + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:277 +# args: msg.getVipUuid(),useForList.toString() +vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = vip[uuid:{0}]已经被其他网络服务实体[{1}]占用 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:282 +# args: +eip\ can\ not\ be\ created\ on\ system\ vip = 无法在系统VIP上创建EIP + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:286 +# args: msg.getVipUuid(),VipState.Enabled,vip.getState() +vip[uuid\:%s]\ is\ not\ in\ state[%s],\ current\ state\ is\ %s = vip[uuid:{0}]不处于状态[{1}]中,当前状态[{2}] + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:323 +# args: state.toString() +vm\ state[%s]\ is\ not\ allowed\ to\ operate\ eip,\ maybe\ you\ should\ wait\ the\ vm\ process\ complete = 云主机状态[{0}]不允许进行弹性IP操作,你可能需要等待云主机操作完成 + +# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:337 +# args: vmNicUuid +vmNic\ uuid[%s]\ is\ not\ allowed\ add\ eip,\ because\ vmNic\ exist\ portForwarding\ with\ allowedCidr\ rule = 不允许vmnic uuid[{0}]添加EIP,因为vmnic存在具有AllowedCIDR规则的端口转发 + +# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1463 +# args: struct.getEip().getUuid() +eip\ [uuid\:%s]\ is\ deleted = 已删除EIP[uuid:{0}] + +# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1316 +# args: eip.getGuestIp(),nicIps +cannot\ find\ Eip\ guest\ ip\:\ %s\ in\ vmNic\ ips\ \:%s = 在vmnic IP{1}中找不到EIP来宾IP{0} + +# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1622 +# args: l3.getUuid(),l3.getName(),vm.getUuid(),vm.getName() +unable\ to\ attach\ the\ L3\ network[uuid\:%s,\ name\:%s]\ to\ the\ vm[uuid\:%s,\ name\:%s],\ because\ the\ L3\ network\ is\ providing\ EIP\ to\ one\ of\ the\ vm's\ nic = 无法将三层网络[uuid:{0}, name:{1}]挂载到云主机[uuid:{2}, name:{3}],因为三层网络正在为云主机上的一块网卡提供EIP + +# at: src/main/java/org/zstack/network/service/flat/DhcpApply.java:73 +# args: msg.getL3NetworkUuid() +could\ not\ get\ dhcp4\ server\ ip\ for\ l3\ network\ [uuid\:%s] = 无法获取三层网络[uuid:{0}]的DHCP4服务器IP + +# at: src/main/java/org/zstack/network/service/flat/DhcpApply.java:77 +# args: msg.getL3NetworkUuid() +could\ not\ get\ dhcp6\ server\ ip\ for\ l3\ network\ [uuid\:%s] = 无法获取三层网络[uuid:{0}]的DHCP6服务器IP + +# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:39 +# args: +Session/account\ uuid\ is\ not\ valid. = 会话/帐户uuid无效。 + +# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:43 +# args: accountUuid,msg.getL3NetworkUuid() +the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resource[uuid\:%s,\ type\:L3NetworkVO] = 帐户[uuid:{0}]无权访问资源[uuid:{1},类型:L3NetworkVO] + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:647 +# args: +l3\ network\ uuid\ cannot\ be\ null = 三层网络的uuid不能为空 + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:654 +# args: msg.getL3NetworkUuid() +Cannot\ find\ DhcpIp\ for\ l3\ network[uuid\:%s] = 无法为三层网络[uuid:{0}]找到DHCP IP + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:998 +# args: inv.getUuid(),destHostUuid +cannot\ configure\ DHCP\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为目标物理机[uuid:{1}]上的云主机[uuid:{0}]配置DHCP + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1751 +# args: IPv6Constants.IPV6_PREFIX_LEN_MIN_DNSMASQ +minimum\ ip\ range\ prefix\ length\ of\ flat\ network\ is\ %d = 三层网络的最小IP范围前缀长度为{0} + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1780 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv6\ address = DHCP服务器地址[{0}]不是一个正确的IPv6地址 + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1776 +# args: dhcpServerIp,inv.getNetworkCidr() +DHCP\ server\ ip\ [%s]\ is\ not\ in\ the\ cidr\ [%s] = DHCP服务器地址[{0}]不在网络段[{1}]的范围内 + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1772 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv4\ address = DHCP服务器地址[{0}]不是一个正确的IPv4地址 + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1791 +# args: entry.getKey(),inv.getL3NetworkUuid() +DHCP\ server\ ip\ [%s]\ is\ already\ existed\ in\ l3\ network\ [%s] = 三层网络[{1}]已经配置了DHCP服务器地址[{0}] + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1796 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ can\ not\ be\ equaled\ to\ gateway\ ip = DHCP服务器地址[{0}]不能等于网关地址 + +# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1802 +# args: dhcpServerIp +DHCP\ server\ ip\ [%s]\ can\ not\ be\ configured\ to\ system\ l3 = 系统网络不能配置DHCP服务器地址[{0}] + +# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:80 +# args: +could\ not\ attach\ eip\ because\ ipv6\ eip\ can\ ONLY\ be\ attached\ to\ flat\ network = 无法附加EIP,因为IPv6 EIP只能附加到三层网络 + +# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:109 +# args: vmNicUuid +L2Network\ where\ vip's\ L3Network\ based\ hasn't\ attached\ the\ cluster\ where\ vmNic[uuid\:%s]\ located = 基于虚拟IP三层网络的二层网络没有绑定到云主机网卡所在的集群 + +# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:134 +# args: version,vmNicUuid +can\ not\ bound\ more\ than\ 1\ %s\ eip\ to\ a\ vm\ nic[uuid\:%s]\ of\ flat\ = 无法将1个以上的{0}EIP绑定到平面的VM NIC[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/flat/FlatEipBackend.java:614 +# args: vmUuid,vm.getState() +unable\ to\ apply\ the\ EIP\ operation\ for\ the\ the\ vm[uuid\:%s,\ state\:%s],\ because\ cannot\ find\ the\ VM's\ hostUUid = 无法为云主机[uuid:{0}, state:{1}]应用EIP操作,因为无法找到该云主机的物理机uuid(hostUuid) + +# at: src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java:374 +# args: struct.getHostUuid() +host[uuid\:%s]\ is\ not\ connected = 物理机[uuid:{0}]未连接 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:306 +# args: e.getMessage() +Invalid\ rule\ expression,\ the\ detail\:\ %s = 规则表达式无效,详细信息:{0} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:180 +# args: +could\ not\ get\ candidate\ vmnic,\ because\ both\ load\ balancer\ uuid\ and\ server\ group\ uuid\ are\ not\ specified = 无法获取候选vmnic,因为未指定负载平衡器uuid和服务器组uuid + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:198 +# args: +could\ not\ get\ candidate\ l3\ network,\ because\ both\ load\ balancer\ uuid\ and\ server\ group\ uuid\ are\ not\ specified = 无法获取候选三层网络,因为未指定负载平衡器uuid和服务器组uuid + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:222 +# args: msg.getListenerUuid() +could\ not\ detach\ vm\ nic\ to\ load\ balancer\ listener[uuid\:%s],\ because\ default\ server\ group\ for\ listener\ has\ been\ deleted = 无法将VM NIC与负载平衡器侦听器[uuid:{0}]分离,因为已删除侦听器的默认服务器组 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:251 +# args: vipVO.getIp() +Load\ balancer\ VIP\ [%s]\ cannot\ be\ the\ first\ or\ the\ last\ IP\ of\ the\ CIDR\ with\ the\ public\ address\ pool\ type = 负载平衡器VIP[{0}]不能是具有公共地址池类型的CIDR的第一个或最后一个IP + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:282 +# args: ipVer +operation\ failure,\ not\ support\ the\ ip\ version\ %d = 操作失败,不支持IPv{0} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:288 +# args: ips,acl.getUuid() +operation\ failure,\ duplicate/overlap\ ip\ entry\ in\ %s\ of\ accesscontrol\ list\ group\:%s = 操作失败,在访问控制组:{1}中有重复/重叠ip{0} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:295 +# args: ips +operation\ failure,\ ip\ format\ only\ supports\ ip/iprange/cidr,\ but\ find\ %s = 操作失败,只支持IP地址/IP段/IP网络格式的参数,不支持{0} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:299 +# args: startIp,endIp,NetworkUtils.longToIpv4String(r.lowerEndpoint()),NetworkUtils.longToIpv4String(r.upperEndpoint()),acl.getUuid() +ip\ range[%s,\ %s]\ is\ overlap\ with\ start\ ip\:%s,\ end\ ip\:\ %s\ of\ access-control-list\ group\:%s = ip段[{0}, {1}]和访问控制列表组:{4}中的ip段[{2},{3}]重叠 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:321 +# args: aclUuids,lbUuid +Can't\ attach\ the\ type\ access-control-list\ group[%s]\ whose\ ip\ version\ is\ different\ with\ LoadBalancer[%s] = 负载均衡器[{1}]不能添加IP版本不一致的访问控制列表组[{0}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:396 +# args: aclEntry.getDomain(),aclEntry.getUrl(),acl.getUuid() +domian[%s],\ url[%s]\ duplicate/overlap\ redirect\ rule\ with\ access-control-list\ group\:%s = 域[{0}],URL[{1}]与访问控制列表组{2}重复/重叠重定向规则 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:506 +# args: msg.getAclType(),msg.getAclUuids() +access-control-list\ groups[uuid\:%s]\ use\ to\ %s,\ but\ there\ some\ access-control-list\ not\ has\ ip\ entry\ but\ redirect\ rule = 访问控制列表组[uuid:{0}]用于{1},但某些访问控制列表没有IP条目,但有重定向规则 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:515 +# args: existingAcls,msg.getListenerUuid() +the\ access-control-list\ groups[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ listener[uuid\:%s] = 负载均衡监听器[uuid:{1}]已经添加了访问控制列表组[uuid:{0}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:521 +# args: msg.getListenerUuid(),type.toString() +the\ load\ balancer\ listener[uuid\:%s]\ just\ only\ attach\ the\ %s\ type\ access-control-list\ group = 负载均衡监听器[uuid:{0}]只能以{1}方式添加访问控制列表组 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:526 +# args: msg.getListenerUuid(),LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) +the\ load\ balancer\ listener[uuid\:%s]\ can't\ \ attach\ more\ than\ %d\ access-control-list\ groups = 负载均衡监听器[uuid:{0}]最多只能添加{1}个访问控制列表组 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:414 +# args: msg.getAclUuids() +access-control-list\ groups[uuid\:%s]\ use\ to\ redirect,\ but\ there\ some\ access-control-list\ not\ has\ redirect\ rule\ but\ ip\ entry = Access-Control-List组[uuid:{0}]用于重定向,但某些Access-Control-List没有重定向规则,只有IP条目 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:419 +# args: msg.getAclUuids() +redirect\ access-control-list\ groups[uuid\:%s]\ cannot\ only\ attach\ to\ load\ balancer\ listener,\ must\ assign\ server\ group = 重定向访问控制列表组[uuid:{0}]不能仅连接到负载平衡器侦听器,必须分配服务器组 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:424 +# args: msg.getAclUuids(),msg.getListenerUuid() +access-control-list\ groups[uuid\:%s]\ attach\ to\ load\ balancer\ listener[uuid\:%s]\ not\ https\ or\ http = 访问控制列表组[uuid:{0}]连接到负载平衡器侦听器[uuid:{1}]而不是HTTPS或HTTP + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:547 +# args: msg.getServerGroupUuids(),msg.getListenerUuid() +server\ group[%s]\ not\ attach\ to\ load\ balancer\ listener[%s] = 服务器组[{0}]未连接到负载平衡器侦听器[{1}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:443 +# args: msg.getAclUuids() +access-control-list\ groups[uuid\:%s]\ has\ no\ redirect\ rule = 访问控制列表组[uuid:{0}]没有重定向规则 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:456 +# args: msg.getAclUuids(),msg.getListenerUuid() +access-control-list\ groups[uuid\:%s]\ has\ attach\ to\ another\ load\ balancer\ listener[uuid\:%s] = 访问控制列表组[uuid:{0}]已连接到另一个负载平衡器侦听器[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:468 +# args: msg.getListenerUuid(),LoadBalancerGlobalConfig.ACL_REDIRECT_MAX_COUNT.value(Long.class) +the\ load\ balancer\ listener[uuid\:%s]\ can't\ \ attach\ more\ than\ %d\ redirect\ rule\ access-control-list\ groups = 负载平衡器侦听器[uuid:{0}]无法附加{1}个以上的重定向规则访问控制列表组 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:494 +# args: msg.getListenerUuid(),redireRuleExistAclUuid +load\ balancer\ listener\ [uuid\:%s]\ had\ redirect\ rule\ of\ access-control-list\ groups[uuid\:%s] = 负载平衡器侦听器[uuid:{0}]具有访问控制列表组的重定向规则[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:555 +# args: msg.getAclUuid(),msg.getListenerUuid() +acl[%s]\ not\ attach\ to\ load\ balancer\ listener[%s] = ACL[{0}]未附加到负载平衡器侦听器[{1}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1294 +# args: l3Uuids,LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING +L3\ networks[uuids\:%s]\ of\ the\ vm\ nics\ has\ no\ network\ service[%s]\ enabled = 云主机网卡的三层网络没有可用的网络服务 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:587 +# args: nicUuid,groupVO.getUuid() +could\ not\ attach\ vm\ nic\ to\ load\ balancer\ listener,\ because\ the\ vm\ nic[uuid\:%s]\ are\ already\ on\ the\ default\ server\ group\ [uuid\:%s] = 无法将VM NIC附加到负载平衡器侦听器,因为VM NIC[uuid:{0}]已位于默认服务器组[uuid:{1}]上 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1176 +# args: listenerVO.getProtocol(),msg.getHealthCheckProtocol() +the\ listener\ with\ protocol\ [%s]\ doesn't\ support\ this\ health\ check\:[%s] = [{0}]类型的监听器不支持此类型[{1}]的健康检查 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1145 +# args: +the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameter\ healthCheckURI = http类型的健康检查必须提供healthCheckURI参数 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1152 +# args: msg.getHealthCheckHttpCode() +the\ http\ health\ check\ protocol's\ expecting\ code\ [%s]\ is\ invalidate = http健康检查协议的expeting-code参数非法 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:697 +# args: LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) +Can't\ attach\ more\ than\ %d\ access-control-list\ groups\ to\ a\ listener = 一个监听器加载的访问控制组不能超过{0} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:787 +# args: msg.getProtocol(),msg.getName() +l4[%s]\ loadBalancer\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ state = L4[{0}]LoadBalancer侦听器[{1}]不支持分配会话持久性状态 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:808 +# args: msg.getLoadBalancerUuid(),msg.getName(),algorithm +loadBalancer[%s]\ listener[%s]\ %s\ algorithm\ doesn't\ support\ assigning\ session\ persistence\ state\ except\ assigning\ disable\ explicitly = LoadBalancer[{0}]Listener[{1}]{2}算法不支持分配会话持久性状态,但显式分配Disable时除外 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:823 +# args: msg.getLoadBalancerUuid(),msg.getName(),algorithm +loadBalancer[%s]\ listener[%s]\ %s\ algorithm\ doesn't\ support\ assigning\ session\ persistence\ state\ except\ assigning\ iphash\ explicitly = LoadBalancer[{0}]Listener[{1}]{2}算法不支持分配会话持久性状态,但显式分配IPHASH除外 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:849 +# args: enableSession,Arrays.toString(LoadBalancerSessionPersistence.values()) +invalid\ session\ persistence\ type[%s],\ it\ only\ support\ %s = 会话持久性类型[{0}]无效,它仅支持{1} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:856 +# args: timeout,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX +invalid\ session\ idle\ timeout[%s],\ it\ must\ be\ the\ number\ between[%s~%s]\ = 会话空闲超时[{0}]无效,它必须是介于[{1}~{2}]之间的数字 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:863 +# args: cookieName,COOKIE_NAME_MAX +invalid\ session\ cookie\ name[%s],\ it\ must\ be\ shorter\ than\ [%s]\ characters = 会话Cookie名称[{0}]无效,必须少于[{1}]个字符 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:866 +# args: cookieName +invalid\ session\ cookie\ name[%s],\ it\ must\ only\ contains\ letters,\ numbers\ and\ underscores = 会话Cookie名称[{0}]无效,它只能包含字母、数字和下划线 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:870 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ idle\ timeout\ and\ cookie\ name\ at\ the\ same\ time = LoadBalancer[{0}]Listener[{1}]不支持同时分配空闲超时和Cookie名称 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:876 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ idle\ timeout\ and\ cookie\ name,\ it\ must\ specify\ session\ persistence = LoadBalancer[{0}]Listener[{1}]不支持分配空闲超时和Cookie名称,它必须指定会话持久性 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:880 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ idle\ timeout\ and\ cookie\ name\ when\ the\ session\ persistence\ is\ disabled = 禁用会话持久性时,LoadBalancer[{0}]Listener[{1}]不支持分配空闲超时和Cookie名称 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:894 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ rewrite\ without\ assigning\ cookie\ name = LoadBalancer[{0}]侦听器[{1}]不支持在不分配Cookie名称的情况下分配会话持久性重写 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:899 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ idle\ timeout\ without\ assigning\ rewrite\ mode = LoadBalancer[{0}]侦听器[{1}]不支持在不分配重写模式的情况下分配会话持久性空闲超时 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:904 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ cookieName\ without\ assigning\ insert\ mode = LoadBalancer[{0}]侦听器[{1}]不支持在不分配插入模式的情况下分配会话持久性CookieName + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:909 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ rewrite\ when\ the\ http\ mode\ is\ http-tunnel = 当HTTP模式为HTTP隧道时,LoadBalancer[{0}]Listener[{1}]不支持分配会话持久性重写 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:920 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ other\ session\ persistence\ when\ the\ source\ balancer\ algorithm\ is\ source = 当源平衡器算法为源时,LoadBalancer[{0}]侦听器[{1}]不支持分配其他会话持久性 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:932 +# args: msg.getLoadBalancerUuid(),msg.getName() +loadBalancer[%s]\ listener[%s]\ doesn't\ support\ assigning\ session\ persistence\ iphash = LoadBalancer[{0}]侦听器[{1}]不支持分配会话持久性IPHASH + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:950 +# args: tag,s,LoadBalancerConstants.MAX_CONNECTION_LIMIT +invalid\ max\ connection[%s],\ %s\ is\ larger\ than\ upper\ threshold\ %d = 非法的最大连接数标签[{0}],因为其值{1}大于上限值{2} + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:972 +# args: msg.getLoadBalancerPort(),luuid +conflict\ loadBalancerPort[%s],\ a\ listener[uuid\:%s]\ has\ used\ that\ port = 冲突的负载均衡器端口(loadBalancerPort)[{0}],一个监听器[uuid:{1}]已经使用了该端口 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1161 +# args: listenerVO.getProtocol(),msg.getHealthCheckProtocol() +the\ listener\ with\ protocol\ [%s]\ doesn't\ support\ select\ security\ policy = 具有协议[{0}]的侦听器不支持选择安全策略 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1005 +# args: vo.getProtocol() +loadbalancer\ listener\ with\ type\ %s\ does\ not\ need\ certificate = [{0}]类型证书不需要证书 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1009 +# args: msg.getListenerUuid(),msg.getCertificateUuid() +loadbalancer\ listener\ [uuid\:%s]\ already\ had\ certificate[uuid\:%s] = LoadBalancer侦听器[uuid:{0}]已具有证书[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1019 +# args: msg.getCertificateUuid(),msg.getListenerUuid() +certificate\ [uuid\:%s]\ is\ not\ added\ to\ loadbalancer\ listener\ [uuid\:%s] = 证书[uuid:{0}]未添加到负载均衡监听器[uuid:{1}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1034 +# args: target +healthCheck\ target\ [%s]\ error,\ it\ must\ be\ 'default'\ or\ number\ between[1~65535]\ = 健康检查端口[{0}]错误,值必须是'default'或者数字[1~65535] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1050 +# args: listener.getProtocol(),listener.getName() +l4[%s]\ loadBalancer\ listener[%s]\ doesn't\ support\ modifying\ session\ persistence\ state = L4[{0}]LoadBalancer侦听器[{1}]不支持修改会话持久性状态 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1064 +# args: msg.getUuid() +listener[%s]\ can\ not\ modifying\ session\ persistence\ rewrite\ when\ the\ http\ mode\ is\ http-tunnel = 当HTTP模式为HTTP隧道时,侦听器[{0}]无法修改会话持久性重写 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1072 +# args: msg.getUuid() +listener[%s]\ can\ not\ modifying\ httpMode\ http-tunnel\ when\ the\ session\ persistence\ is\ rewrite = 重写会话持久性时,侦听器[{0}]无法修改httpmode HTTP-tunnel + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1079 +# args: msg.getUuid() +listener[%s]\ changes\ session\ persistence\ to\ iphash,\ it\ must\ specify\ source\ balancer\ algorithm = 侦听器[{0}]将会话持久性更改为IPHASH,它必须指定源平衡器算法 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1084 +# args: msg.getUuid() +listener[%s]\ modifies\ session\ persistence,\ it\ must\ specify\ balancer\ algorithm = 侦听器[{0}]修改会话持久性,它必须指定平衡器算法 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1090 +# args: msg.getUuid(),msg.getBalancerAlgorithm() +listener[%s]\ %s\ algorithm\ doesn't\ support\ modifying\ session\ persistence\ except\ assigning\ iphash\ explicitly = 侦听器[{0}]{1}算法不支持修改会话持久性,除非显式分配IPHASH + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1098 +# args: msg.getUuid(),msg.getBalancerAlgorithm() +listener[%s]\ %s\ algorithm\ doesn't\ support\ modifying\ session\ persistence\ except\ assigning\ disable\ explicitly = 侦听器[{0}]{1}算法不支持修改会话持久性,除非显式指定禁用 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1106 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ idle\ timeout\ and\ cookie\ name,\ it\ must\ specify\ session\ persistence = 侦听器[{0}]不支持修改空闲超时和cookie名称,它必须指定会话持久性 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1110 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ idle\ timeout\ when\ the\ session\ persistence\ is\ not\ insert = 当会话持久性不是INSERT时,侦听器[{0}]不支持修改空闲超时 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1114 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ cookie\ name\ when\ the\ session\ persistence\ is\ not\ rewrite = 侦听器[{0}]不支持在会话持久性未重写时修改cookie名称 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1118 +# args: msg.getUuid() +listener[%s]\ doesn't\ support\ modifying\ session\ rewrite\ without\ modifying\ cookie\ name = 侦听器[{0}]不支持在不修改Cookie名称的情况下修改会话重写 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1132 +# args: timeout,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN,LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX +invalid\ session\ idle\ timeout[%s],\ it\ must\ be\ the\ number\ between[%s~%s] = 会话空闲超时[{0}]无效,它必须是介于[{1}~{2}]之间的数字 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1181 +# args: +the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameters\ including\ healthCheckMethod\ and\ healthCheckURI = http类型的健康检查协议必须提供healthCheckMethod和healthCheckURI参数 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1204 +# args: msg.getUuid() +could\ not\ allow\ to\ delete\ default\ serverGroup[uuid\:%s] = 无法允许删除默认服务器组[uuid:{0}] + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1429 +# args: msg.getServerGroupUuid() +loadbalacerServerGroup\ [%s]\ is\ non-existent = LoadBalacerServerGroup[{0}]不存在 -# at: src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java:89 -# args: msg.getType() -unsupported\ l2Network\ type[%s] = 不支持的网络类型[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1263 +# args: vmNic.get("uuid"),msg.getServerGroupUuid() +could\ not\ add\ backend\ server\ vmnic[uuid\:%s]\ to\ serverGroup[uuid\:%s],because\ vmnic\ uuid\ is\ not\ exist = 无法将后端服务器vmnic[uuid:{0}]添加到ServerGroup[uuid:{1}],因为vmnic uuid不存在 -# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:558 -# args: vl2.getUuid(),vl2.getName(),msg.getClusterUuid(),vl2.getPhysicalInterface(),vl2.getVlan(),tl2.getUuid() -There\ has\ been\ a\ L2VlanNetwork[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s],\ vlan[%s].\ Failed\ to\ attach\ L2VlanNetwork[uuid\:%s] = L2网络挂载失败[uuid:{5}]: L2网络[uuid:{0}, name:{1}]的物理接口[{3}], vlan[{4}]已经挂载到集群[uuid:{2}]上 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1274 +# args: vmNic.get("weight") +could\ not\ add\ backend\ server\ vmnic\ to\ serverGroup[uuid\:%s]\ ,because\ vmnic\ weight[%s]\ not\ a\ correct\ number = 无法将后端服务器vmnic添加到ServerGroup[uuid:{0}],因为vmnic权重[{1}]不是正确的数字 -# at: src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java:540 -# args: l2.getUuid(),l2.getName(),msg.getClusterUuid(),l2.getPhysicalInterface(),tl2.getUuid() -There\ has\ been\ a\ l2Network[uuid\:%s,\ name\:%s]\ attached\ to\ cluster[uuid\:%s]\ that\ has\ physical\ interface[%s].\ Failed\ to\ attach\ l2Network[uuid\:%s] = L2网络挂载失败[uuid:{4}]: L2网络[uuid:{0}, name:{1}]的物理接口[{3}]]已经挂载到集群[uuid:{2}]上 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1552 +# args: vmNic.get("uuid"),vmNicWeight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight[vimNic\:%s,weight\:%s],\ weight\ is\ not\ in\ the\ range\ [%d,\ %d] = 无效的平衡器重量[vimnic:{0},重量:{1}],重量不在范围[{2},{3}]内 -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java:218 -# args: inv.getUuid(),destHostUuid -cannot\ configure\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为云主机[uuid:{0}]在目标物理机[uuid:{1}]上配置VXLAN网络 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1304 +# args: existingNics,msg.getServerGroupUuid() +the\ vm\ nics[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ servegroup\ [uuid\:%s] = VM NIC[uuid:{0}]已位于负载平衡器ServerGroup[uuid:{1}]上 -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:79 -# args: vtepIps,hostUuid -find\ multiple\ vtep\ ips[%s]\ for\ one\ host[uuid\:%s],\ need\ to\ delete\ host\ and\ add\ again = 在一个物理机[uuid:{1}]发现多个VTEP IP,需要删除物理机在进行添加 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1313 +# args: msg.getServerGroupUuid(),vmNicIps +could\ not\ add\ backend\ server\ vmnic\ to\ serverGroup\ [uuid\:%s],\ because\ vmnic\ ip\ [ipAddress\:%s]\ is\ repeated = 无法将后端服务器vmnic添加到ServerGroup[uuid:{0}],因为vmnic IP[IPAddress:{1}]重复 -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:119 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),l2vxlan.getVni(),hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ l2Network[uuid\:%s,\ type\:%s,\ vni\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 为L2网络[uuid:{1}, type:{2}, vni:{3}]在KVM物理机[uuid:{4}]上创建网桥[{0}]失败,错误细节: {5} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1325 +# args: vmNicUuids,msg.getServerGroupUuid(),listenerVO.getUuid() +could\ not\ add\ vm\ nic\ [uuid\:%s]\ to\ server\ group\ [uuid\:%s]\ because\ listener\ [uuid\:%s]\ attached\ this\ server\ group\ already\ the\ nic\ to\ be\ added = 无法将VM NIC[uuid:{0}]添加到服务器组[uuid:{1}],因为侦听程序[uuid:{2}]已将此服务器组连接到要添加的NIC -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java:183 -# args: cmd.getCidr(),l2vxlan.getUuid(),l2vxlan.getName(),hostUuid,rsp.getError() -failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetwork[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 为KVM物理机[uuid:{3}]上的L2 VXLAN 网络[uuid:{1}, name:{2}]检查CIDR[{0}]失败,错误细节: {4} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1606 +# args: msg.getServerGroupUuid(),serverIps +could\ not\ add\ backend\ server\ ip\ to\ serverGroup\ [uuid\:%s],\ because\ ip\ [ipAddress\:%s]\ is\ invalid = 无法将后端服务器IP添加到ServerGroup[uuid:{0}],因为IP[IPAddress:{1}]无效 -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:251 -# args: l2Network.getUuid(),l2Network.getType(),l2networks,hostUuid,rsp.getError() -failed\ to\ realize\ vxlan\ network\ pool[uuid\:%s,\ type\:%s,\ vnis\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 在kvm物理机[uuid:{3}]实现vxlan network pool[uuid:{0}, type:{1}, vnis:{2}]失败,因为{4} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1341 +# args: msg.getServerGroupUuid(),server.get("ipAddress") +could\ not\ add\ backend\ server\ ip\ to\ serverGroup\ [uuid\:%s],\ because\ ip\ [ipAddress\:%s]\ is\ repeated = 无法将后端服务器IP添加到ServerGroup[uuid:{0}],因为IP[IPAddress:{1}]重复 -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java:110 -# args: cmd.getCidr(),vxlanPool.getUuid(),vxlanPool.getName(),hostUuid,rsp.getError() -failed\ to\ check\ cidr[%s]\ for\ l2VxlanNetworkPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 检查在kvm物理机[uuid:{3}]上的l2VxlanNetworkPool[uuid:{1}, name:{2}]的CIDR[{0}]失败,{4} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1599 +# args: server.get("weight") +could\ not\ add\ backend\ server\ ip\ to\ serverGroup[uuid\:%s]\ ,because\ vmnic\ weight[%s]\ not\ a\ correct\ number = 无法将后端服务器IP添加到ServerGroup[uuid:{0}],因为vmnic权重[{1}]不是正确的数字 -# at: src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java:55 -# args: msg.getHostUuid(),msg.getPoolUuid() -vxlan\ vtep\ address\ for\ host\ [uuid\ \:\ %s]\ and\ pool\ [uuid\ \:\ %s]\ pair\ already\ existed = 物理机[uuid : {0}]在vxlan资源池[uuid : {1}]中隧道端点地址已经配置 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1352 +# args: server.get("ipAddress"),serverIpWeight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ \ weight[serverIp\:%s,weight\:%s],\ weight\ is\ not\ in\ the\ range\ [%d,\ %d] = 权重[服务器IP:{0},权重:{1}]无效,权重不在范围[{2},{3}]内 -# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:27 -# args: -it\ is\ used = 被占用 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1367 +# args: existingServerIps,msg.getServerGroupUuid() +the\ server\ ips\ [uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ servegroup\ [uuid\:%s] = 服务器IP[uuid:{0}]已在负载平衡器ServerGroup[uuid:{1}]上 -# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:25 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1611 # args: -it\ is\ not\ in\ this\ range = 不在IP地址范围内 +could\ not\ add\ server\ ip\ to\ share\ load\ balancer\ server\ group = 无法将服务器IP添加到共享负载平衡器服务器组 -# at: src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java:23 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1433 # args: -it\ is\ gateway = 网关不能分配 +vmnic\ or\ ip\ is\ null = vmnic或IP为空 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:116 -# args: -you\ must\ update\ system\ and\ category\ both = 必须同时更行system属性和category属性 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1397 +# args: msg.getServerGroupUuid() +vmnics\ are\ all\ not\ in\ servergroup\ [%s] = VMNIC均不在ServerGroup[{0}]中 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:355 -# args: L3NetworkCategory.validCombination -not\ valid\ combination\ of\ system\ and\ category,only\ %s\ are\ valid = 无效的system属性和category属性的组合,只有{0}是有效的 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1414 +# args: msg.getServerGroupUuid() +serverips\ are\ all\ not\ in\ servergroup\ [%s] = ServerIP全部不在ServerGroup[{0}]中 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:161 -# args: msg.getIp() -invalid\ IP[%s] = 错误的IP值[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1444 +# args: msg.getServerGroupUuid(),msg.getlistenerUuid() +could\ not\ add\ server\ group[uuid\:%s}\ to\ listener\ [uuid\:%s]\ because\ it\ is\ already\ added\ = 无法将服务器组[uuid:{0}}添加到侦听器[uuid:{1}],因为它已添加 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:145 -# args: msg.getL3NetworkUuid() -no\ ip\ range\ in\ l3[%s] = 没有IP在三层网络范围中 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1461 +# args: msg.getServerGroupUuid(),msg.getlistenerUuid(),nicUuid +could\ not\ add\ server\ group[uuid\:%s}\ to\ listener\ [uuid\:%s]\ because\ nic\ [uuid\:%s]\ is\ already\ added = 无法将服务器组[uuid:{0}}添加到侦听器[uuid:{1}],因为已经添加了NIC[uuid:{2}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:149 -# args: msg.getRouterInterfaceIp(),ipRangeVO.getUuid(),ipRangeVO.getNetworkCidr(),msg.getL3NetworkUuid() -ip[%s]\ is\ not\ in\ the\ cidr\ of\ ip\ range[uuid\:%s,\ cidr\:%s]\ which\ l3\ network[%s]\ attached = IP[{0}]没有在三层网络[{3}]的CIDR的IP范围内[uuid:{1}, cidr:{2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1476 +# args: msg.getServerGroupUuid(),msg.getlistenerUuid(),ipAddress +could\ not\ add\ server\ group[uuid\:%s}\ to\ listener\ [uuid\:%s]\ because\ server\ ip\ [%s]\ is\ already\ added = 无法将服务器组[uuid:{0}}添加到侦听器[uuid:{1}],因为已添加服务器IP[{2}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:153 -# args: msg.getRouterInterfaceIp(),ipRangeVO.getUuid(),ipRangeVO.getStartIp(),ipRangeVO.getEndIp(),msg.getL3NetworkUuid() -ip[%s]\ in\ ip\ range[uuid\:%s,\ startIp\:%s,\ endIp\:%s]\ which\ l3\ network[%s]\ attached,\ this\ is\ not\ allowed = IP[{0}]在三层网络[{4}]绑定的IP范围内[uuid:{1}, startIp:{2}, endIp:{3}],这是不被允许的 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1496 +# args: msg.getServerGroupUuid(),msg.getListenerUuid() +could\ not\ remove\ server\ group[uuid\:%s}\ from\ listener\ [uuid\:%s]\ because\ it\ is\ not\ added = 由于未添加服务器组[uuid:{1}],因此无法将其从侦听器[uuid:{1}]中删除 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:167 -# args: -ipRangeUuid\ and\ l3NetworkUuid\ cannot\ both\ be\ null;\ you\ must\ set\ either\ one. = IP段和L3的uuid不能都为空,您必须选择一个填上 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1511 +# args: loadBalancerUuid +loadbalacerUuid\ [%s]\ is\ non-existent = LoadBalaceRuuid[{0}]不存在 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:293 -# args: msg.getNetworkCidr() -%s\ is\ not\ a\ valid\ network\ cidr = {0}不是有效的无类别域间路由 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1526 +# args: msg.getServerGroupUuid() +could\ not\ find\ loadBalancer\ with\ serverGroup\ [uuid\:%s] = 找不到ServerGroup为[uuid:{0}]的LoadBalancer -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:214 -# args: msg.getGateway() -%s\ is\ not\ a\ valid\ ipv6\ address = {0}不是有效的IPv6地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1567 +# args: msg.getServerGroupUuid() +could\ not\ update\ backend\ server\ vmnic\ of\ serverGroup[uuid\:%s],because\ vmnic\ uuid\ is\ null = 无法更新ServerGroup[uuid:{0}]的后端服务器vmnic,因为vmnic uuid为空 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:218 -# args: msg.getStartIp(),msg.getEndIp(),msg.getPrefixLen(),msg.getGateway() -[startIp\ %s,\ endIp\ %s,\ prefixLen\ %d,\ gateway\ %s]\ is\ not\ a\ valid\ ipv6\ range = IPv6地址段{0}-{1}/{2}, 网关{3}不是有效的IPv6地址段 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1542 +# args: msg.getServerGroupUuid(),vmNic.containsKey("uuid") +could\ not\ update\ backend\ server\ vmnic\ of\ serverGroup,because\ serverGroup[uuid\:%s]\ don\ not\ have\ vmnic\ [uuid\:%s]\ = 无法更新ServerGroup的后端服务器vmnic,因为ServerGroup[uuid:{0}]没有vmnic[uuid:{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:228 -# args: IPv6Constants.IPV6_PREFIX_LEN_MIN,IPv6Constants.IPV6_PREFIX_LEN_MAX -ip\ range\ prefix\ length\ is\ out\ of\ range\ [%d\ -\ %d]\ = IPv6地址前缀长度不在有效范围内[{0}-{1}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1564 +# args: vmNic.get("uuid") +invalid\ balancer\ weight[vimNic\:%s],\ weight\ is\ null = 平衡器权重[vimnic:{0}]无效,权重为空 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:234 -# args: l3Vo.getUuid(),l3Vo.getName() -l3\ network\ [uuid\ %s\:\ name\ %s]\ is\ not\ a\ ipv6\ network = 三层网络[uuid:{0},名称{1}]不是IPv6网络 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1559 +# args: vmNic.get("weight") +could\ not\ change\ backend\ server\ vmnic\ to\ serverGroup[uuid\:%s]\ ,because\ vmnic\ weight[%s]\ not\ a\ correct\ number = 无法将后端服务器vmnic更改为ServerGroup[uuid:{0}],因为vmnic权重[{1}]不是正确的数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:240 -# args: ipr.getAddressMode(),rangeVOS.get(0).getAddressMode() -addressMode[%s]\ is\ different\ from\ L3Netowork\ address\ mode[%s] = 地址模式[{0}]和三层网络的地址模式[{1}]不同 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1583 +# args: msg.getServerGroupUuid(),ipAddress +could\ not\ update\ backend\ server\ ip\ of\ serverGroup,because\ serverGroup[uuid\:%s]\ don\ not\ have\ ip\ [ipAddress\:%s]\ = 无法更新ServerGroup的后端服务器IP,因为ServerGroup[uuid:{0}]没有IP[IP地址:{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:246 -# args: IPv6Constants.IPV6_STATELESS_PREFIX_LEN -ipv6\ prefix\ length\ must\ be\ %d\ for\ Stateless-DHCP\ or\ SLAAC = Stateless-DHCP or SLAAC地址模式IPv6网络前缀长度必须是{0} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1602 +# args: server.get("ipAddress") +invalid\ balancer\ weight[serverIp\:%s],\ weight\ is\ null = 无效的平衡器权重[ServerIP:{0}],权重为空 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:256 -# args: ipr.getStartIp(),ipr.getEndIp(),r.getStartIp(),r.getEndIp() -new\ ip\ range\ [startip\ \:%s,\ endip\ \:%s]\ is\ overlaped\ with\ old\ ip\ range[startip\ \:%s,\ endip\ \:%s] = 新的IP地址段[{0}-{1}]和旧的IP地址段[{2}-{3}]冲突 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1592 +# args: server.get("ipAddress"),serverIpWeight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight[serverIp\:%s,weight\:%s],\ weight\ is\ not\ in\ the\ range\ [%d,\ %d] = 无效的平衡器权重[服务器IP:{0},权重:{1}],权重不在范围[{2},{3}]内 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:266 -# args: r.getNetworkCidr(),ipr.getNetworkCidr() -new\ network\ CIDR\ [%s]\ is\ different\ from\ old\ network\ cidr\ [%s] = 同一L3网络上不能加载多个CIDR。 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:1618 +# args: +could\ not\ change\ backendserver,\ beacause\ vmincs\ and\ serverips\ is\ null = 无法更改后端服务器,因为VMINCS和ServerIPS为空 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:468 -# args: ipr.getGateway(),r.getGateway() -new\ add\ ip\ range\ gateway\ %s\ is\ different\ from\ old\ gateway\ %s = 新ip段的网关地址{0}和已有ip段的网关地址{1}冲突 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1355 +# args: struct.listenerUuid +can\ not\ get\ service\ providerType\ for\ load\ balancer\ listener\ [uuid\:%s] = 无法获取负载平衡器侦听器[uuid:{0}]的Service ProviderType -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:286 -# args: msg.getNetworkCidr() -%s\ is\ not\ an\ allowed\ network\ cidr,\ because\ it\ doesn't\ have\ usable\ ip\ range = {0}是不允许的无类别域间路由,因为它不支持可用的IP段 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1384 +# args: self.getUuid(),self.getProviderType(),providerType +service\ provider\ type\ mismatching.\ The\ load\ balancer[uuid\:%s]\ is\ provided\ by\ the\ service\ provider[type\:%s],\ but\ new\ service\ provider\ is\ [type\:\ %s] = 服务提供商类型不匹配。负载平衡器[uuid:{0}]由服务提供程序[类型:{1}]提供,但新服务提供程序为[类型:{2}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:290 -# args: msg.getGateway(),msg.getNetworkCidr() -%s\ is\ not\ the\ first\ or\ last\ address\ of\ the\ cidr\ %s = +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1486 +# args: msg.getLoadBalancerPort(),msg.getLoadBalancerUuid() +there\ is\ listener\ with\ same\ port\ [%s]\ and\ same\ load\ balancer\ [uuid\:%s] = 存在具有相同端口[{0}]和相同负载平衡器[uuid:{1}]的侦听器 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:313 -# args: -ipRangeUuids,\ L3NetworkUuids,\ zoneUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = ipRangeUuids, L3NetworkUuids, zoneUuids 至少一个不是为空列表,或者全部不为空 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:2011 +# args: param +invalid\ health\ checking\ parameters[%s],\ the\ format\ is\ method\:URI\:code,\ for\ example,\ GET\:/index.html\:http_2xx = 无效的健康检查参数[{0}],正确格式:method:URI:code,例如 GET:/index.html:http_2xx -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:334 -# args: msg.getType() -unsupported\ l3network\ type[%s] = 不支持的L3网络类型[{0}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:699 +# args: systemTag +invalid\ health\ target[%s],\ the\ format\ is\ targetCheckProtocol\:port,\ for\ example,\ tcp\:default = 无效的健康检查目标[{0}],格式为[目标检查协议(targetCheckProtocol):端口(port)], 例如[tcp:default] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:340 -# args: msg.getDnsDomain() -%s\ is\ not\ a\ valid\ domain\ name = {0}不是有效的域名 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:100 +# args: msg.getLoadBalancerUuid() +cannot\ find\ the\ load\ balancer[uuid\:%s] = 无法找到负载均衡器[uuid:{0}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:382 -# args: l3Vo.getUuid(),l3Vo.getName() -l3\ network\ [uuid\ %s\:\ name\ %s]\ is\ not\ a\ ipv4\ network = 三层网络[uuid:{0},name:{1}]不是IPv4网络 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:483 +# args: tag.getTag() +cannot\ delete\ the\ system\ tag[%s].\ The\ load\ balancer\ plugin\ relies\ on\ it,\ you\ can\ only\ update\ it = 无法删除系统标签[{0}]。负载均衡器插件依赖于该标签,该标签只能被更新 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:386 -# args: ipr.getStartIp(),ipr.getEndIp() -the\ IP\ range[%s\ ~\ %s]\ contains\ D\ class\ addresses\ which\ are\ for\ multicast = 这个IP段[{0} ~ {1}]包含了D类的组播地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:502 +# args: nicUuid,systemTag +nic[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ loadbalancer = 找不到网卡[uuid:{0}]。请检查负载均衡器的系统标签[{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:390 -# args: ipr.getStartIp(),ipr.getEndIp() -the\ IP\ range[%s\ ~\ %s]\ contains\ E\ class\ addresses\ which\ are\ reserved = 这个IP段[{0} ~ {1}]包含了E类的保留地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:514 +# args: systemTag,s +invalid\ balancer\ weight[%s],\ %s\ is\ not\ a\ number = 无效的权重值[{0}], {1}不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:394 -# args: ipr.getStartIp(),ipr.getEndIp() -the\ IP\ range[%s\ ~\ %s]\ contains\ link\ local\ addresses\ which\ are\ reserved = 这个IP段[{0} ~ {1}]包含了本地的保留地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:510 +# args: systemTag,s,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight[%s],\ %s\ is\ not\ in\ the\ range\ [%d,\ %d] = 无效的权重值[{0}], {1}不在允许范围[{2}, {3}]中 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:400 -# args: ipr.getGateway(),ipr.getStartIp(),ipr.getNetmask() -the\ gateway[%s]\ is\ not\ in\ the\ subnet\ %s/%s = 网关[{0}]不在子网{1}/{2} +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:526 +# args: algorithm,LoadBalancerConstants.BALANCE_ALGORITHMS +invalid\ balance\ algorithm[%s],\ valid\ algorithms\ are\ %s = 无效的均衡算法[{0}],有效的为[{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:404 -# args: ipr.getEndIp(),ipr.getStartIp(),ipr.getNetmask() -the\ endip[%s]\ is\ not\ in\ the\ subnet\ %s/%s = IP段结束地址不在子网{1}/{2}范围内 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:602 +# args: systemTag,s +invalid\ unhealthy\ threshold[%s],\ %s\ is\ not\ a\ number = 无效的不健康阈值[{0}],[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:408 -# args: ipr.getStartIp() -start\ ip[%s]\ is\ not\ a\ IPv4\ address = 开始的ip[{0}] 不是IPV4的地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:616 +# args: systemTag,s +invalid\ healthy\ threshold[%s],\ %s\ is\ not\ a\ number = 无效的健康阈值[{0}],[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:412 -# args: ipr.getEndIp() -end\ ip[%s]\ is\ not\ a\ IPv4\ address = 结束的ip[{0}] 不是IPV4的地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:630 +# args: systemTag,s +invalid\ healthy\ timeout[%s],\ %s\ is\ not\ a\ number = 无效的健康超时[{0}],[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:416 -# args: ipr.getGateway() -gateway[%s]\ is\ not\ a\ IPv4\ address = 网关[{0}]不是IPV4的地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:644 +# args: systemTag,s +invalid\ connection\ idle\ timeout[%s],\ %s\ is\ not\ a\ number = 无效的连接空闲超时[{0}],[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:420 -# args: ipr.getNetmask() -netmask[%s]\ is\ not\ a\ netmask,\ and\ the\ IP\ range\ netmask\ cannot\ be\ 0.0.0.0 = 子网掩码[{0}]不是子网掩码,并且IP段的子网掩码不能是0.0.0.0 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:658 +# args: systemTag,s +invalid\ health\ check\ interval[%s],\ %s\ is\ not\ a\ number = 无效的健康检查间隔[{0}],[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:424 -# args: -ip\ allocation\ can\ not\ contain\ network\ address\ or\ broadcast\ address = ip 地址分配不能包含网络地址或广播的地址 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:672 +# args: systemTag,s +invalid\ max\ connection[%s],\ %s\ is\ not\ a\ number = 无效的最大连接[{0}],[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:432 -# args: ipr.getStartIp(),ipr.getEndIp() -start\ ip[%s]\ is\ behind\ end\ ip[%s] = 起始ip[{0}]在尾ip[{1}]后 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:686 +# args: systemTag,s +invalid\ process\ number[%s],\ %s\ is\ not\ a\ number = 进程编号[{0}]无效,{1}不是数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:437 -# args: ipr.getGateway(),ipr.getStartIp(),ipr.getEndIp() -gateway[%s]\ can\ not\ be\ part\ of\ range[%s,\ %s] = 网关[{0}]不能是IP段[{1}, {2}]的一部分 +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:704 +# args: systemTag,protocol,LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCOLS +invalid\ health\ target[%s],\ the\ target\ checking\ protocol[%s]\ is\ invalid,\ valid\ protocols\ are\ %s = 无效的健康检查目标[{0}],目标检查协议无效[{1}],有效的为[{2}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:448 -# args: r.getUuid(),r.getStartIp(),r.getEndIp() -overlap\ with\ ip\ range[uuid\:%s,\ start\ ip\:%s,\ end\ ip\:\ %s] = 重叠的IP段[uuid:{0}, 起始ip:{1}, 尾ip: {2}] +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:716 +# args: systemTag,port +invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ a\ number = 无效的健康检查目标[{0}],端口[{1}]不是一个数字 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:458 -# args: r.getUuid(),rcidr,cidr -multiple\ CIDR\ on\ the\ same\ L3\ network\ is\ not\ allowed.\ There\ has\ been\ a\ IP\ range[uuid\:%s,\ CIDR\:%s],\ the\ new\ IP\ range[CIDR\:%s]\ is\ not\ in\ the\ CIDR\ with\ the\ existing\ one = 在相同的三层网络上多个CIDR是不允许的,已有的IP范围 [uuid: {0},CIDR: {1}]。新的IP范围 [CIDR: {2}] 不在现有的一个CIDR +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:713 +# args: systemTag,port +invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ in\ the\ range\ of\ [1,\ 65535] = 无效的无效健康检查目标[{0}],端口[{1}]不在范围[1, 65535]内 + +# at: src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java:89 +# args: nicUuid,weight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX +invalid\ balancer\ weight\ for\ nic\:%s,\ %d\ is\ not\ in\ the\ range\ [%d,\ %d] = 无效的网卡:{0}权重值{1},不在有效范围[{2}, {3}]内 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:490 -# args: manner,ip -%s[%s]\ is\ not\ a\ IPv6\ address = {0}[{1}]不是IPv6地址 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:226 +# args: msg.getVmNicUuid(),msg.getVipUuid() +guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ vip[uuid\:\ %s]\ are\ the\ same\ network = 云主机网卡[uuid:{0}]的客户三层网络和虚拟IP[uuid:{1}]的虚拟IP 三层网络是同一个网络 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:486 -# args: manner,ip -%s[%s]\ is\ not\ a\ IPv4\ address = {0}[{1}]不是IPv4地址 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:201 +# args: msg.getVipUuid(),useForList.toString() +the\ vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = 虚拟IP[uuid:{0}]已经被其他网络服务占用 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:502 -# args: msg.getDns(),msg.getL3NetworkUuid() -there\ has\ been\ a\ DNS[%s]\ on\ L3\ network[uuid\:%s] = 在L3网络[uuid:{1}]上已经存在一个DNS[{0}] +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:68 +# args: msg.getRuleUuid(),state +Port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ current\ state\ is\ %s = 端口转发规则[uuid:{0}]未启用,当前状态[{1}] -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:525 -# args: msg.getL3NetworkUuid() -prefix\ [%s]\ is\ not\ a\ IPv4\ network\ cidr = 网络段{0}不是合法的网络段 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:83 +# args: msg.getUuid() +port\ forwarding\ rule\ rule[uuid\:%s]\ has\ not\ been\ attached\ to\ any\ vm\ nic,\ can't\ detach = 端口转发规则[uuid:{0}]尚未被挂载到任何云主机网卡,无法卸载 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:512 -# args: msg.getNexthop() -nexthop[%s]\ is\ not\ a\ IPv4\ address = 下一跳{0}不是有效的IP地址 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:99 +# args: msg.getRuleUuid(),vmNicUuid +port\ forwarding\ rule[uuid\:%s]\ has\ been\ attached\ to\ vm\ nic[uuid\:%s],\ can't\ attach\ again = 端口转发规则[uuid:{0}]已经被挂载到云主机网卡[uuid:{1}],无法再次挂载 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:519 -# args: msg.getPrefix(),msg.getL3NetworkUuid() -there\ has\ been\ a\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = 三层网络{1}已配置主机路由{0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:104 +# args: msg.getRuleUuid(),state +port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ \ current\ state\ is\ %s.\ A\ rule\ can\ only\ be\ attached\ when\ its\ state\ is\ Enabled = 端口转发规则[uuid:{0}]没有启用,当前状态为{1}。一个规则只能在启用时被挂载 -# at: src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java:532 -# args: msg.getPrefix(),msg.getL3NetworkUuid() -there\ is\ no\ hostroute\ for\ prefix[%s]\ on\ L3\ network[uuid\:%s] = 三层网络{1}没有主机路由{0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:123 +# args: msg.getVmNicUuid(),msg.getRuleUuid() +guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ port\ forwarding\ rule[uuid\:%s]\ are\ the\ same\ network = 云主机网卡[uuid:{0}]的客户三层网络和端口转发规则[uuid:{1}]的VIP 三层网络是同一个网络 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:171 -# args: wrongUuids,securityGroupUuid -VM\ nics[uuids\:%s]\ are\ not\ on\ L3\ networks\ that\ have\ been\ attached\ to\ the\ security\ group[uuid\:%s] = 云主机网卡[uuids:{0}]不在安全组[uuid:{1}]挂载的L3网络上 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:167 +# args: msg.getVipPortStart(),msg.getVipPortEnd(),msg.getPrivatePortStart(),msg.getPrivatePortEnd() +could\ not\ create\ port\ forwarding\ rule,\ because\ vip\ port\ range[vipStartPort\:%s,\ vipEndPort\:%s]\ is\ incompatible\ with\ private\ port\ range[privateStartPort\:%s,\ privateEndPort\:%s] = 无法创建端口转发规则,因为VIP端口范围[vipStartPort:{0},vipEndPort:{1}]与专用端口范围[PrivateStartPort:[2},PrivateEndPport:{3}]不兼容 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:69 -# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() -security\ group[uuid\:%s]\ has\ not\ attached\ to\ l3Network[uuid\:%s],\ can't\ detach = 不能卸载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为还未挂载 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:184 +# args: msg.getVipPortStart(),msg.getVipPortEnd(),msg.getPrivatePortStart(),msg.getPrivatePortEnd() +for\ range\ port\ forwarding,\ the\ port\ range\ size\ must\ match;\ vip\ range[%s,\ %s]'s\ size\ doesn't\ match\ range[%s,\ %s]'s\ size = 对于范围端口转发,端口范围大小必须匹配;VIP范围[{0}, {1}]的大小不匹配范围[{2}, {3}]的大小 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:117 -# args: msg.getSecurityGroupUuid(),msg.getL3NetworkUuid() -security\ group[uuid\:%s]\ has\ attached\ to\ l3Network[uuid\:%s],\ can't\ attach\ again = 不能再次挂载安全组[uuid:{0}]到L3[uuid:{1}]网络上,因为已经挂载了 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:193 +# args: msg.getAllowedCidr() +invalid\ CIDR[%s],\ only\ ipv4\ is\ supported = 无效的CIDR[{0}],仅支持ipv4 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:125 -# args: msg.getL3NetworkUuid(),SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE -the\ L3\ network[uuid\:%s]\ doesn't\ have\ the\ network\ service\ type[%s]\ enabled = L3网络[uuid:{0}]没有开启[{1}]类型的网络服务 +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:191 +# args: msg.getAllowedCidr() +invalid\ CIDR[%s] = 无效的CIDR[{0}] + +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:211 +# args: vipStart,vipEnd,vo.getUuid(),vo.getVipPortStart(),vo.getVipPortEnd() +vip\ port\ range[vipStartPort\:%s,\ vipEndPort\:%s]\ overlaps\ with\ rule[uuid\:%s,\ vipStartPort\:%s,\ vipEndPort\:%s] = 虚拟IP(vip)端口范围[vipStartPort:{0}, vipEndPort:{1}]与规则[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}]重叠 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:131 -# args: msg.getL3NetworkUuid(),l3Vo.getIpVersion(),msg.getSecurityGroupUuid(),sgVo.getIpVersion() -the\ L3\ network[uuid\:%s]\ ipVersion\ [%d]\ is\ different\ from\ securityGroup\ [uuid\:%s]\ ipVersion\ [%d] = +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:269 +# args: vm.getName(),vm.getUuid(),vipUuid +the\ VM[name\:%s\ uuid\:%s]\ already\ has\ port\ forwarding\ rules\ that\ have\ different\ VIPs\ than\ the\ one[uuid\:%s] = 云主机[name:{0} uuid:{1}]已经有端口转发规则,且与[uuid:{2}]有不同的VIPs -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:214 -# args: JSONObjectUtil.toJsonString(ao) -rule\ type\ can\ not\ be\ null.\ rule\ dump\:\ %s = 规则类型(rule type)不能为空(null)。规则内容为: {0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:282 +# args: vmNicUuid +vmNic\ uuid[%s]\ is\ not\ allowed\ add\ portForwarding\ with\ allowedCidr\ rule,\ because\ vmNic\ exist\ eip = 不允许vmnic uuid[{0}]使用AllowedCIDR规则添加PortForwarding,因为vmnic存在EIP -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:219 -# args: ao.getType(),JSONObjectUtil.toJsonString(ao) -unknown\ rule\ type[%s],\ rule\ can\ only\ be\ Ingress/Egress.\ rule\ dump\:\ %s = 未知的规则类型(rule type)[{0}],规则类型只能为Ingress/Egress。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:316 +# args: vmNicUuid,privatePortStart,privatePortEnd,protocolType +could\ not\ attach\ port\ forwarding\ rule,\ because\ vmNic[uuid\:%s]\ already\ has\ a\ rule\ that\ overlaps\ the\ target\ private\ port\ ranges[%s,\ %s],\ has\ the\ same\ protocol\ type[%s]\ and\ has\ AllowedCidr = 无法挂载端口转发规则,因为云主机网卡[uuid:{0}]已经有与目标规则的云主机端口范围[{1}, {2}]重叠、协议类型[{3}]相同且设置有允许CIDR的规则 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:225 -# args: JSONObjectUtil.toJsonString(ao) -protocol\ can\ not\ be\ null.\ rule\ dump\:\ %s = 协议(protocol)不能为空(null)。规则内容为: {0} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:306 +# args: vmNicUuid,privatePortStart,privatePortEnd,protocolType +could\ not\ attach\ port\ forwarding\ rule\ with\ allowedCidr,\ because\ vmNic[uuid\:%s]\ already\ has\ rules\ that\ overlap\ the\ target\ private\ port\ ranges[%s,\ %s]\ and\ have\ the\ same\ protocol\ type[%s] = 无法挂载设置有允许CIDR的端口转发规则,因为云主机网卡[uuid:{0}]已经有与目标规则的云主机端口范围[{1}, {2}]重叠且协议类型[{3}]相同的规则 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:231 -# args: ao.getProtocol(),JSONObjectUtil.toJsonString(ao) -invalid\ protocol[%s].\ Valid\ protocols\ are\ [TCP,\ UDP,\ ICMP,\ ALL].\ rule\ dump\:\ %s = 无效的协议(protocol)[{0}]。有效的协议类型为[TCP,UDP,ICMP,ALL]。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java:1222 +# args: struct.getRule().getUuid() +port\ forwarding\ rule\ [uuid\:%s]\ is\ deleted = 端口转发规则[uuid:{0}]已删除 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:238 -# args: JSONObjectUtil.toJsonString(ao) -can\ not\ set\ port\ for\ protocol\ [type\:ALL].\ rule\ dump\:\ %s = 不能为协议类型为 ALL 的规则指定端口号,规则为:{0} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:375 +# args: msg.getServerGroupUuid() +could\ not\ add\ backend\ server\ vmnic\ to\ serverGroup[uuid\:%s],because\ vmnic\ uuid\ is\ null = 无法将后端服务器vmnic添加到ServerGroup[uuid:{0}],因为vmnic uuid为空 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:236 -# args: JSONObjectUtil.toJsonString(ao) -startPort\ can\ not\ be\ null.\ rule\ dump\:\ %s = 起始端口(startPort)不能为空(null)。规则内容为: {0} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:88 +# args: msg.getSlbGroupUuid() +could\ not\ create\ slb\ instance\ because\ there\ is\ no\ load\ balancer\ slb\ group\ [uuid\:%s] = 无法创建SLB实例,因为没有负载平衡器SLB组[uuid:{0}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:250 -# args: ao.getStartPort(),JSONObjectUtil.toJsonString(ao) -invalid\ startPort[%s].\ Valid\ range\ is\ [0,\ 65535].\ rule\ dump\:\ %s = 无效的起始端口(startPort)[{0}]。有效的范围为[0,65535]。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:93 +# args: msg.getSlbGroupUuid() +could\ not\ create\ slb\ instance\ because\ there\ is\ no\ slb\ offering\ configured\ for\ slb\ group\ [uuid\:%s] = 无法创建SLB实例,因为没有为SLB组[uuid:{0}]配置SLB产品 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:243 -# args: ao.getStartPort(),JSONObjectUtil.toJsonString(ao) -invalid\ ICMP\ type[%s].\ Valid\ type\ is\ [-1,\ 255].\ rule\ dump\:\ %s = 无效的ICMP类型[{0}]。有效的类型为[-1,255]。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:99 +# args: msg.getSlbGroupUuid() +could\ not\ create\ slb\ instance\ because\ image\ uuid\ of\ slb\ offering\ [uuid\:%s]\ is\ null = 无法创建SLB实例,因为SLB产品[uuid:{0}]的镜像uuid为空 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:269 -# args: ao.getEndPort(),JSONObjectUtil.toJsonString(ao) -invalid\ endPort[%s].\ Valid\ range\ is\ [0,\ 65535].\ rule\ dump\:\ %s = 无效的结束端口(endPort)[{0}]。有效的范围为[0,65535]。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:104 +# args: slbOfferingVO.getImageUuid() +could\ not\ create\ slb\ instance\ because\ image\ [uuid\:%s]\ is\ deleted = 无法创建SLB实例,因为镜像[uuid:{0}]已删除 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:262 -# args: ao.getEndPort(),JSONObjectUtil.toJsonString(ao) -invalid\ ICMP\ code[%s].\ Valid\ range\ is\ [-1,\ 3].\ rule\ dump\:\ %s = 无效的ICMP编码[{0}]。有效的范围为[-1,3]。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:112 +# args: frontL3.getCategory() +could\ not\ create\ slb\ group\ because\ invalid\ front\ l3\ network\ type\ %s = 无法创建SLB组,因为前端三层网络类型{0}无效 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:279 -# args: ao.getAllowedCidr(),JSONObjectUtil.toJsonString(ao) -invalid\ CIDR[%s].\ rule\ dump\:\ %s = 无效的CIDR[{0}]。规则内容为: {1} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:127 +# args: +could\ not\ create\ slb\ group,\ because\ front\ network\ doesn't\ support\ ipv6\ yet = 无法创建SLB组,因为前端网络尚不支持IPv6 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:283 -# args: sgVo.getIpVersion(),ao.getIpVersion() -security\ group\ rule\ ipVersion\ [%d]\ is\ different\ from\ security\ group\ version\ [%d] = 远端安全组IP协议号[{0}]和本地安全组的IP协议号[{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:142 +# args: +could\ not\ create\ slb\ group,\ because\ backend\ network\ doesn't\ support\ ipv6\ yet = 无法创建SLB组,因为后端网络尚不支持IPv6 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:292 -# args: JSONObjectUtil.toJsonString(msg.getRules().get(j)) -rule\ should\ not\ be\ duplicated.\ rule\ dump\:\ %s = 规则不应该重复。规则内容为: {0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:143 +# args: msg.getResourceUuid() +could\ not\ change\ resource\ owner,\ because\ the\ resource[uuid\:%s,\ type\:VmInstance]\ has\ already\ attached\ security\ group = 无法更改资源所有者,因为资源[uuid:{0}, 类型:VmInstance] 已加载安全组 -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:318 -# args: JSONObjectUtil.toJsonString(sao),svo.getRemoteSecurityGroupUuid() -rule\ exist.\ rule\ dump\:\ %s,\ remoteSecurityGroupUuid\:[%s] = 规则已存在,规则内容为:{0},源安全组[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:250 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ vm\ nic[uuid\:%s]\ not\ found = 无法设置VM NIC安全组,因为找不到VM NIC[uuid:{0}] -# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:345 -# args: rsgVo.getIpVersion(),sgVo.getIpVersion() -remote\ security\ group\ ipVersion\ [%d]\ is\ different\ from\ security\ group\ version\ [%d] = 远端安全组IP协议号[{0}]和安全组协议号[{1}]不一致 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:256 +# args: msg.getVmNicUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ the\ vm\ nic[uuid\:%s]\ not\ attached\ to\ any\ security\ group = 无法设置VM NIC安全组,因为VM NIC[uuid:{0}]未挂载到任何安全组 -# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:88 -# args: msg.getL3NetworkUuid() -L3Network\ [uuid\:\ %s]\ provide\ type\ null = 三层网络{0}后端为空 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:266 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ security\ group[uuid\:%s]\ not\ found = 无法设置VM NIC安全组,因为找不到安全组[uuid:{0}] -# at: src/main/java/org/zstack/network/service/HostRouteExtension.java:113 -# args: msg.getL3NetworkUuid() -L3Network\ [uuid\:\ %s]\ does\ not\ have\ host\ route\ service = 三层网络{0}没有主机路由功能 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:271 +# args: priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ cannot\ be\ less\ than\ 1 = 无法设置VM NIC安全组,因为优先级无效,优先级[{0}]不能小于1 -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:41 -# args: -networkServices\ cannot\ be\ empty = 网络服务(networkServices)不能为空 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:275 +# args: aoMap.get(priority),ao.getSecurityGroupUuid(),priority +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ priority,\ both\ security\ group\ %s\ and\ %s\ have\ priority[%d] = 无法设置VM NIC安全组,因为优先级重复,安全组{0}和{1}都具有相同的优先级[{2}] -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:62 -# args: puuid -network\ service\ for\ provider[uuid\:%s]\ must\ be\ specified = 服务提供器[uuid:{0}]的网络服务必须被指定 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:278 +# args: ao.getSecurityGroupUuid() +could\ no\ set\ vm\ nic\ security\ group,\ because\ duplicate\ security\ group[uuid\:%s] = 无法设置VM NIC安全组,因为安全组[uuid:{0}]重复 -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:67 -# args: puuid -cannot\ find\ network\ service\ provider[uuid\:%s]\ or\ it\ provides\ no\ services = 无法找到网络服务提供器[uuid:{0}]或它没有提供任何服务 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:288 +# args: ao.getSecurityGroupUuid(),vmAccountUuid +could\ no\ set\ vm\ nic\ security\ group,\ because\ security\ group[uuid\:%s]\ is\ not\ owned\ by\ account[uuid\:%s]\ or\ admin = 无法设置 VM NIC 安全组,因为安全组 [uuid:{0}] 不属于帐户[uuid:{1}] 或管理员 -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:81 -# args: puuid,notSupported -network\ service\ provider[uuid\:%s]\ doesn't\ provide\ services%s = 网络服务提供器[uuid:{0}]无法提供服务{1} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:298 +# args: priorities[0] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority\ expects\ to\ start\ at\ 1,\ but\ [%d] = 无法设置VM NIC安全组,因为优先级无效,优先级应从1开始,而不是[{0}] -# at: src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java:93 -# args: type,msg.getL3NetworkUuid() -there\ has\ been\ a\ network\ service[%s]\ attached\ to\ L3\ network[uuid\:%s] = 已经有一个网络服务[{0}]被挂载到L3网络[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:302 +# args: priorities[i],priorities[i + 1] +could\ no\ set\ vm\ nic\ security\ group,\ because\ invalid\ priority,\ priority[%d]\ and\ priority[%d]\ expected\ to\ be\ consecutive = 无法设置VM NIC安全组,因为优先级无效,优先级[{0}]和优先级[{1}]应是连续的 -# at: src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java:342 -# args: l3NetworkUuid,serviceType -L3Network[uuid\:%s]\ doesn't\ have\ network\ service[type\:%s]\ enabled\ or\ no\ provider\ provides\ this\ network\ service = L3网络[uuid:{0}]上没有网络服务[type:{1}]被启用或没有服务提供器提供该网络服务 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:348 +# args: priorities[i + 1] +could\ no\ set\ vm\ nic\ security\ group,\ because\ admin\ security\ group\ priority[%d]\ must\ be\ higher\ than\ users = 无法设置VM NIC安全组,因为管理员安全组优先级[{0}]必须高于用户安全组 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:82 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:357 # args: -either\ eipUuid\ or\ vipUuid\ must\ be\ set = eipUuid或vipUuid必须有一个被指定 +could\ no\ change\ security\ group\ rule\ state,\ because\ ruleUuids\ is\ empty = 无法更改安全组规则状态,因为RuleUIds为空 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:88 -# args: msg.getEipUuid() -eip[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ cannot\ get\ attachable\ vm\ nic = eip[uuid:{0}]没有被启用,无法获取可挂载的虚拟机网卡 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:361 +# args: msg.getSecurityGroupUuid() +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group[uuid\:%s]\ not\ found = 无法更改安全组规则状态,因为找不到安全组[uuid:{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:103 -# args: guestIpUuid,vmNicUuid -ip\ [uuid\:%s]\ is\ attached\ to\ vm\ nic\ [%s] = IP地址[uuid:{0}]已经绑定到网卡[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:369 +# args: r +could\ no\ change\ security\ group\ rule\ state,\ because\ security\ group\ rule[uuid\:%s]\ not\ found = 无法更改安全组规则状态,因为找不到安全组规则[uuid:{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:114 -# args: msg.getEipUuid(),vmNicUuid -eip[uuid\:%s]\ has\ attached\ to\ another\ vm\ nic[uuid\:%s],\ can't\ attach\ again = eip[uuid:{0}]已经被挂载到另外一台虚拟机网卡[uuid:{1}],无法再次挂载 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:378 +# args: +could\ no\ change\ security\ group\ rule\ state,\ because\ no\ security\ group\ rule\ state\ need\ to\ change = 无法更改安全组规则状态,因为没有安全组规则需要修改状态 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:120 -# args: msg.getEipUuid(),EipState.Enabled,state -eip[uuid\:\ %s]\ can\ only\ be\ attached\ when\ state\ is\ %s,\ current\ state\ is\ %s = eip[uuid:{0}]只有在状态(state)为{1}的情况下可以被挂载,当前状态是{2} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:386 +# args: +could\ no\ change\ vm\ nic\ security\ policy,\ because\ ingress\ policy\ and\ egress\ policy\ cannot\ be\ both\ null = 无法更改VM NIC安全策略,因为入口策略和出口策略不能同时为空 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:150 -# args: msg.getVmNicUuid(),msg.getEipUuid() -guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ EIP[uuid\:%s]\ are\ the\ same\ network = 虚拟机网卡[uuid:{0}]的客户L3网络,和EIP[uuid:{1}]的虚拟ip L3网络是同一个网络 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:389 +# args: msg.getIngressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ ingress\ policy[%s] = 无法更改VM NIC安全策略,因为入口策略[{0}]无效 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:167 -# args: msg.getEipUuid(),msg.getVmNicUuid() -Ip\ address\ [uuid\:%s]\ is\ not\ belonged\ to\ nic\ [uuid\:%s] = IP地址[uuid:{0}]没有绑定到网卡[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:393 +# args: msg.getEgressPolicy() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ invalid\ egress\ policy[%s] = 无法更改VM NIC安全策略,因为出口策略[{0}]无效 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:180 -# args: msg.getUuid() -eip[uuid\:%s]\ has\ not\ attached\ to\ any\ vm\ nic = eip[uuid:{0}]还没有被挂载到任意虚拟机网卡 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:397 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ not\ found = 无法更改VM NIC安全策略,因为找不到VM NIC[uuid:{0}] -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:203 -# args: vipIp.getIpVersion(),guestIp.getIpVersion() -vip\ ipVersion\ [%d]\ is\ different\ from\ guestIp\ ipVersion\ [%d]. = 虚拟IP的协议号[{0}]和网卡的IP协议号[{1}]不同 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:402 +# args: msg.getVmNicUuid() +could\ no\ change\ vm\ nic\ security\ policy,\ because\ vm\ nic[uuid\:%s]\ has\ no\ security\ policy = 无法更改VM NIC安全策略,因为VM NIC[uuid:{0}]没有安全策略 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:210 -# args: vipIp.getIp(),guestRange.getStartIp(),guestRange.getEndIp() -Vip[%s]\ is\ in\ the\ guest\ ip\ range\ [%s,\ %s] = 虚拟IP[{0}]和网卡的IP不能在相同地址段[{1}-{2}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:416 +# args: msg.getType() +could\ not\ update\ security\ group\ rule\ priority,\ because\ invalid\ type[%s] = 无法更新安全组规则优先级,因为类型[{0}]无效 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:230 -# args: vmUuid,vip.getL3NetworkUuid(),vip.getUuid(),vip.getName(),vip.getIp() -the\ vm[uuid\:%s]\ that\ the\ EIP\ is\ about\ to\ attach\ is\ already\ on\ the\ public\ network[uuid\:%s]\ from\ which\ the\ vip[uuid\:%s,\ name\:%s,\ ip\:%s]\ comes = EIP将要挂载到的虚拟机[uuid:{0}]已经处于公共网络[uuid:{1}]上,该网络上已有vip[uuid:{2}, name:{3}, ip:{4}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:421 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ is\ not\ exist = 无法更新安全组规则优先级,因为安全组[uuid:{0}]不存在 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:241 -# args: msg.getVipUuid(),useForList.toString() -vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = vip[uuid:{0}]已经被其他网络服务实体[{1}]占用 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:425 +# args: +could\ not\ update\ security\ group\ rule\ priority,\ because\ rules\ is\ empty = 无法更新安全组规则优先级,因为规则为空 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:246 -# args: msg.getVipUuid(),VipState.Enabled,vip.getState() -vip[uuid\:%s]\ is\ not\ in\ state[%s],\ current\ state\ is\ %s = vip[uuid:{0}]不处于状态[{1}]中,当前状态[{2}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:435 +# args: msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ security\ group[uuid\:%s]\ rules\ size\ not\ match = 无法更新安全组规则优先级,因为安全组[uuid:{0}]规则大小不匹配 -# at: src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java:281 -# args: state.toString() -vm\ state[%s]\ is\ not\ allowed\ to\ operate\ eip,\ maybe\ you\ should\ wait\ the\ vm\ process\ complete = 云主机状态[{0}]不允许进行弹性IP操作,你可能需要等待云主机操作完成 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:440 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ priority[%d]\ is\ invalid = 无法更新安全组规则优先级,因为规则优先级[{0}]无效 -# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:944 -# args: eip.getGuestIp(),nicIps -cannot\ find\ Eip\ guest\ ip\:\ %s\ in\ vmNic\ ips\ \:%s = +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:443 +# args: ao.getPriority() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ has\ duplicate = 无法更新安全组规则优先级,因为优先级[{0}]重复 -# at: src/main/java/org/zstack/network/service/eip/EipManagerImpl.java:1305 -# args: l3.getUuid(),l3.getName(),vm.getUuid(),vm.getName() -unable\ to\ attach\ the\ L3\ network[uuid\:%s,\ name\:%s]\ to\ the\ vm[uuid\:%s,\ name\:%s],\ because\ the\ L3\ network\ is\ providing\ EIP\ to\ one\ of\ the\ vm's\ nic = 无法将L3网络[uuid:{0}, name:{1}]挂载到虚拟机[uuid:{2}, name:{3}],因为L3网络正在为虚拟机上的一块网卡提供EIP +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:449 +# args: ao.getRuleUuid(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule[uuid\:%s]\ not\ in\ security\ group[uuid\:%s] = 无法更新安全组规则优先级,因为规则[uuid:{0}]不在安全组[uuid:{1}]中 -# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:39 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:452 +# args: ao.getPriority(),msg.getSecurityGroupUuid() +could\ not\ update\ security\ group\ rule\ priority,\ because\ priority[%d]\ not\ in\ security\ group[uuid\:%s] = 无法更新安全组规则优先级,因为优先级[{0}]不在安全组[uuid:{1}]中 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:457 # args: -Session/account\ uuid\ is\ not\ valid. = +could\ not\ update\ security\ group\ rule\ priority,\ because\ rule\ uuid\ duplicate = 无法更新安全组规则优先级,因为规则uuid重复 -# at: src/main/java/org/zstack/network/service/flat/FlatApiInterceptor.java:43 -# args: accountUuid,msg.getL3NetworkUuid() -the\ account[uuid\:%s]\ has\ no\ access\ to\ the\ resource[uuid\:%s,\ type\:L3NetworkVO] = +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:464 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule\ uuid[%s]\ is\ not\ exist = 无法更改安全组规则,因为安全组规则uuid[{0}]不存在 -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:712 -# args: -l3\ network\ uuid\ cannot\ be\ null = L3网络的uuid不能为空 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:470 +# args: msg.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ is\ default\ rule,\ only\ the\ description\ and\ status\ can\ be\ set = 无法更改安全组规则,因为安全组规则[{0}]是默认规则,只能设置描述和状态 -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:728 -# args: msg.getL3NetworkUuid() -Cannot\ find\ DhcpIp\ for\ l3\ network[uuid\:%s] = 无法为L3网络[uuid:{0}]找到DHCP IP +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:476 +# args: msg.getUuid(),SecurityGroupConstant.DEFAULT_RULE_PRIORITY +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ priority\ cannot\ be\ set\ to\ default\ rule\ priority[%d] = 无法更改安全组规则,因为安全组规则[{0}]优先级无法设置为默认规则优先级[{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:823 -# args: msg.getL3NetworkUuid() -L3\ network[uuid\:%s]\ does\ not\ have\ any\ iprange = 三层网络[{0}]没有配置ip段 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:485 +# args: vo.getType(),count.intValue(),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = 无法更改安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1089 -# args: inv.getUuid(),destHostUuid -cannot\ configure\ DHCP\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为目标物理机[uuid:{1}]上的虚拟机[uuid:{0}]配置DHCP +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:488 +# args: vo.getType().toString(),count.intValue() +could\ not\ change\ security\ group\ rule,\ because\ the\ maximum\ priority\ of\ %s\ rule\ is\ [%d] = 无法更改安全组规则,因为{0}规则的最高优先级为[{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1959 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv6\ address = DHCP服务器地址[{0}]不是一个正确的IPv6地址 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:497 +# args: msg.getState() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ state[%s] = 无法更改安全组规则,因为状态[{0}]无效 -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1955 -# args: dhcpServerIp,inv.getNetworkCidr() -DHCP\ server\ ip\ [%s]\ is\ not\ in\ the\ cidr\ [%s] = DHCP服务器地址[{0}]不在网络段[{1}]的范围内 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:505 +# args: msg.getAction() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ action[%s] = 无法更改安全组规则,因为协议[{0}]无效 -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1951 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ is\ not\ a\ IPv4\ address = DHCP服务器地址[{0}]不是一个正确的IPv4地址 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:513 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ invalid\ protocol[%s] = 无法更改安全组规则,因为协议[{0}]无效 -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1970 -# args: IPv6NetworkUtils.ipv6TagValueToAddress(oldDhcpServer),inv.getL3NetworkUuid() -DHCP\ server\ ip\ [%s]\ is\ already\ existed\ in\ l3\ network\ [%s] = 三层网络[{1}]已经配置了DHCP服务器地址[{0}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:545 +# args: msg.getUuid(),msg.getSrcIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Egress,\ srcIpRange[%s]\ cannot\ be\ set = 无法更改安全组规则,因为安全组规则[{0}]类型为出口,无法设置SrcIPRange[{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1975 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ can\ not\ be\ equaled\ to\ gateway\ ip = DHCP服务器地址[{0}]不能等于网关地址 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:542 +# args: msg.getUuid(),msg.getDstIpRange() +could\ not\ change\ security\ group\ rule,\ because\ security\ group\ rule[%s]\ type\ is\ Ingress,\ dstIpRange[%s]\ cannot\ be\ set = 无法更改安全组规则,因为安全组规则[{0}]类型为入口,无法设置dstIpRange[{1}] -# at: src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java:1981 -# args: dhcpServerIp -DHCP\ server\ ip\ [%s]\ can\ not\ be\ configured\ to\ system\ l3 = 系统网络不能配置DHCP服务器地址[{0}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:535 +# args: msg.getSrcIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ srcIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = 无法更改安全组规则,因为已设置SrcIPRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空 -# at: src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java:99 -# args: vmNicUuid -L2Network\ where\ vip's\ L3Network\ based\ hasn't\ attached\ the\ cluster\ where\ vmNic[uuid\:%s]\ located = 基于虚拟IP三层网络的二层网络没有绑定到虚拟机网卡所在的集群 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:548 +# args: msg.getDstIpRange(),msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ dstIpRange[%s]\ is\ set,\ remoteSecurityGroupUuid[%s]\ must\ be\ empty = 无法更改安全组规则,因为已设置dstIpRange[{0}],RemoteSecurityGroupuuid[{1}]必须为空 -# at: src/main/java/org/zstack/network/service/flat/FlatEipBackend.java:573 -# args: vmUuid,vm.getState() -unable\ to\ apply\ the\ EIP\ operation\ for\ the\ the\ vm[uuid\:%s,\ state\:%s],\ because\ cannot\ find\ the\ VM's\ hostUUid = 无法为虚拟机[uuid:{0}, state:{1}]应用EIP操作,因为无法找到该虚拟机的物理机uuid(hostUuid) +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:555 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ not\ found = 无法更改安全组规则,因为找不到远程安全组[uuid:{0}] -# at: src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java:353 -# args: struct.getHostUuid() -host[uuid\:%s]\ is\ not\ connected = 物理机[uuid:{0}]未连接 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:558 +# args: msg.getRemoteSecurityGroupUuid() +could\ not\ change\ security\ group\ rule,\ because\ remote\ security\ group[uuid\:%s]\ is\ set,\ srcIpRange\ and\ dstIpRange\ must\ be\ empty = 无法更改安全组规则,因为已设置远端安全组[uuid:{0}],SrcIPRange和DstIPRange必须为空 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:672 -# args: target -invalid\ health\ target[%s],\ the\ format\ is\ targetCheckProtocol\:port,\ for\ example,\ tcp\:default = 无效的健康检查目标[{0}],格式为[目标检查协议(targetCheckProtocol):端口(port)], 例如[tcp:default] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:611 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ must\ be\ set = 无法更改安全组规则,因为规则协议为[{0}],必须设置dstPortRange -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:121 -# args: msg.getUuid(),refs -the\ access\ control\ list\ group[%s]\ is\ being\ used\ by\ the\ load\ balancer\ listeners[%s] = 访问控制组[{0}]正在被监听器[{1}]使用 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:603 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ empty = 无法更改安全组规则,因为规则协议为[{0}],dstPortRange不能为空 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:203 -# args: ipVer -operation\ failure,\ not\ support\ the\ ip\ version\ %d = 操作失败,不支持IPv{0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:598 +# args: msg.getProtocol() +could\ not\ change\ security\ group\ rule,\ because\ rule\ protocol\ is\ [%s],\ dstPortRange\ cannot\ be\ set = 无法更改安全组规则,因为规则协议为[{0}],无法设置dstPortRange -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:209 -# args: ips,acl.getUuid() -operation\ failure,\ duplicate/overlap\ ip\ entry\ in\ %s\ of\ accesscontrol\ list\ group\:%s = 操作失败,在访问控制组:{1}中有重复/重叠ip{0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:642 +# args: JSONObjectUtil.toJsonString(sao),o.getUuid() +could\ not\ change\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = 无法更改安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:216 -# args: ips -operation\ failure,\ ip\ format\ only\ supports\ ip/iprange/cidr,\ but\ find\ %s = 操作失败,只支持IP地址/IP段/IP网络格式的参数,不支持{0} +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:145 +# args: uuid,backendL3Cidr,frontL3Uuid,frontL3Cidr +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ cidr\ [%s]\ is\ overlapped\ with\ frond\ l3\ network[uuid\:%s]\ cidr\ [%s] = 无法执行API操作。后端网络[uuid:{0}]CIDR[{1}]与前端三层网络[uuid:{2}]CIDR[{3}]重叠 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:220 -# args: startIp,endIp,NetworkUtils.longToIpv4String(r.lowerEndpoint()),NetworkUtils.longToIpv4String(r.upperEndpoint()),acl.getUuid() -ip\ range[%s,\ %s]\ is\ overlap\ with\ start\ ip\:%s,\ end\ ip\:\ %s\ of\ access-control-list\ group\:%s = ip段[{0}, {1}]和访问控制列表组:{4}中的ip段[{2},{3}]重叠 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:768 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ can\ not\ be\ vpc\ network\ because\ other\ backend\ network\ is\ not\ vpc\ network = 无法执行API操作。后端网络[uuid:{0}]不能是VPC网络,因为其他后端网络不是VPC网络 + +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:804 +# args: +can't\ delete\ rules\ of\ different\ security\ group = 无法删除不同安全组的规则 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:242 -# args: aclUuids,lbUuid -Can't\ attach\ the\ type\ access-control-list\ group[%s]\ whose\ ip\ version\ is\ different\ with\ LoadBalancer[%s] = 负载均衡器[{1}]不能添加IP版本不一致的访问控制列表组[{0}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:807 +# args: vo.getUuid() +can't\ delete\ default\ rule[uuid\:%s] = 无法删除默认规则[uuid:{0}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:302 -# args: existingAcls,msg.getListenerUuid() -the\ access-control-list\ groups[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ listener[uuid\:%s] = 负载均衡监听器[uuid:{1}]已经添加了访问控制列表组[uuid:{0}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:170 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ not\ connected\ vpc\ router = 无法执行API操作。后端网络[uuid:{0}]未连接到VPC路由器 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:308 -# args: msg.getListenerUuid(),type.toString() -the\ load\ balancer\ listener[uuid\:%s]\ just\ only\ attach\ the\ %s\ type\ access-control-list\ group = 负载均衡监听器[uuid:{0}]只能以{1}方式添加访问控制列表组 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:835 +# args: backendL3Uuids.get(0),firstBackendVrUuids.get(0),frontL3Uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ connected\ vpc\ router\ [uuid\:%s]\ which\ is\ not\ connect\ to\ front\ network[uuid\:%s] = 无法执行API操作。后端网络[uuid:{0}]连接了VPC路由器[uuid:{1}],而该路由器未连接到前端网络[uuid:{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:313 -# args: msg.getListenerUuid(),LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) -the\ load\ balancer\ listener[uuid\:%s]\ can't\ \ attach\ more\ than\ %d\ access-control-list\ groups = 负载均衡监听器[uuid:{0}]最多只能添加{1}个访问控制列表组 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:897 +# args: wrongUuids,securityGroupUuid +VM\ nics[uuids\:%s]\ are\ not\ on\ L3\ networks\ that\ have\ been\ attached\ to\ the\ security\ group[uuid\:%s] = 云物理机网卡[uuids:{0}]不在安全组[uuid:{1}]挂载的L3网络上 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:339 -# args: l3Uuids,LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING -L3\ networks[uuids\:%s]\ of\ the\ vm\ nics\ has\ no\ network\ service[%s]\ enabled = 虚拟机网卡的三层网络没有可用的网络服务 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:933 +# args: uuid +could\ not\ add\ security\ group\ rule,\ because\ security\ group[uuid\:%s]\ does\ not\ exist = 无法添加安全组规则,因为安全组[uuid:{0}]不存在 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:349 -# args: existingNics,msg.getListenerUuid() -the\ vm\ nics[uuid\:%s]\ are\ already\ on\ the\ load\ balancer\ listener[uuid\:%s] = 虚拟机网卡[uuid:{0}]已经处于负载均衡监听器[uuid:{1}]上 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:922 +# args: SecurityGroupConstant.ONE_API_RULES_MAX_NUM +could\ not\ add\ security\ group\ rule,\ because\ the\ rules\ cannot\ be\ empty\ or\ exceed\ the\ max\ number\ %d = 无法添加安全组规则,因为规则不能为空或超过最大数量{0} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:678 -# args: listenerVO.getProtocol(),msg.getHealthCheckProtocol() -the\ listener\ with\ protocol\ [%s]\ doesn't\ support\ this\ health\ check\:[%s] = [{0}]类型的监听器不支持此类型[{1}]的健康检查 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:927 +# args: msg.getRemoteSecurityGroupUuids() +could\ not\ add\ security\ group\ rule,\ because\ duplicate\ uuid\ in\ remoteSecurityGroupUuids\:\ %s = 无法添加安全组规则,因为RemoteSecurityGroupuuid中存在重复的uuid:{0} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:652 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:938 # args: -the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameter\ healthCheckURI = http类型的健康检查必须提供healthCheckURI参数 +could\ not\ add\ security\ group\ rule,\ because\ the\ remote\ security\ group\ uuid\ is\ conflict = 无法添加安全组规则,因为远端安全组uuid冲突 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:659 -# args: msg.getHealthCheckHttpCode() -the\ http\ health\ check\ protocol's\ expecting\ code\ [%s]\ is\ invalidate = http健康检查协议的expeting-code参数非法 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:974 +# args: SecurityGroupConstant.DEFAULT_RULE_PRIORITY,SecurityGroupConstant.LOWEST_RULE_PRIORITY +could\ not\ add\ security\ group\ rule,\ because\ rule\ priority\ must\ greater\ than\ %d\ or\ equals\ %d = 无法添加安全组规则,因为规则优先级必须大于{0}或等于{1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:457 -# args: LoadBalancerGlobalConfig.ACL_MAX_COUNT.value(Long.class) -Can't\ attach\ more\ than\ %d\ access-control-list\ groups\ to\ a\ listener = 一个监听器加载的访问控制组不能超过{0} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:982 +# args: ao.getType(),SecurityGroupRuleType.getAllType() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ type[%s],\ valid\ types\ are\ %s = 无法添加安全组规则,因为规则类型[{0}]无效,有效类型为{1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:537 -# args: tag,s,LoadBalancerConstants.MAX_CONNECTION_LIMIT -invalid\ max\ connection[%s],\ %s\ is\ larger\ than\ upper\ threshold\ %d = 非法的最大连接数标签[{0}],因为其值{1}大于上限值{2} +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:989 +# args: ao.getState(),SecurityGroupRuleState.getAllState() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ state[%s],\ valid\ states\ are\ %s = 无法添加安全组规则,因为规则状态[{0}]无效,有效状态为{1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:559 -# args: msg.getLoadBalancerPort(),luuid -conflict\ loadBalancerPort[%s],\ a\ listener[uuid\:%s]\ has\ used\ that\ port = 冲突的负载均衡器端口(loadBalancerPort)[{0}],一个监听器[uuid:{1}]已经使用了该端口 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:994 +# args: ao.getProtocol(),SecurityGroupRuleProtocolType.getAllProtocol() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ protocol[%s],\ valid\ protocols\ are\ %s = 无法添加安全组规则,因为规则协议[{0}]无效,有效协议为{1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:564 -# args: -udp\ port\ 53\ is\ used\ by\ dns\ daemon = udp端口53已经被dns进程使用 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1001 +# args: ao.getAction(),SecurityGroupRuleAction.getAllAction() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ action[%s],\ valid\ actions\ are\ %s = 无法添加安全组规则,因为规则动作[{0}]无效,有效动作为{1} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:577 -# args: -tcp\ port\ 22,\ 7272\ is\ used\ by\ vrouter = tcp端口22,7272已经被vrouter管理进程进程使用 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1009 +# args: ao.getIpVersion(),IPv6Constants.IPv4,IPv6Constants.IPv6 +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ ipVersion[%d],\ valid\ ipVersions\ are\ %d/%d = 无法添加安全组规则,因为规则IPVersion[{0}]无效,有效的IPVersion为{1}/{2} -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:604 -# args: vo.getProtocol() -loadbalancer\ listener\ with\ type\ %s\ does\ not\ need\ certificate = [{0}]类型证书不需要证书 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1037 +# args: ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ dstIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ ingress\ rule = 无法添加安全组规则,因为不允许为入口规则设置dstIpRange[{0}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:608 -# args: msg.getListenerUuid(),msg.getCertificateUuid() -loadbalancer\ listener\ [uuid\:%s]\ already\ had\ certificate[uuid\:%s] = +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1042 +# args: ao.getAllowedCidr(),ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ srcIpRange[%s]\ are\ in\ conflict = 无法添加安全组规则,因为allowedcidr[{0}]和srciprange[{1}]冲突 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:618 -# args: msg.getCertificateUuid(),msg.getListenerUuid() -certificate\ [uuid\:%s]\ is\ not\ added\ to\ loadbalancer\ listener\ [uuid\:%s] = 证书[uuid:{0}]未添加到负载均衡监听器[uuid:{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1031 +# args: ao.getDstIpRange(),ao.getRemoteSecurityGroupUuid() +could\ not\ add\ security\ group\ rule,\ because\ the\ ip\ range[%s]\ and\ remoteSecurityGroupUuid[%s]\ are\ in\ conflict = 无法添加安全组规则,因为IP范围[{0}]和RemoteSecurityGroupuuid[{1}]冲突 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:633 -# args: target -healthCheck\ target\ [%s]\ error,\ it\ must\ be\ 'default'\ or\ number\ between[1~65535]\ = 健康检查端口[{0}]错误,值必须是'default'或者数字[1~65535] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1019 +# args: ao.getSrcIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ srcIpRange[%s]\ is\ not\ allowed\ to\ set\ for\ egress\ rule = 无法添加安全组规则,因为不允许为出口规则设置SrcIPRange[{0}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java:683 -# args: -the\ http\ health\ check\ protocol\ must\ be\ specified\ its\ healthy\ checking\ parameters\ including\ healthCheckMethod\ and\ healthCheckURI = http类型的健康检查协议必须提供healthCheckMethod和healthCheckURI参数 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1024 +# args: ao.getAllowedCidr(),ao.getDstIpRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ allowedCidr[%s]\ and\ dstIpRange[%s]\ are\ in\ conflict = 无法添加安全组规则,因为AllowedCidr[{0}]和dstIpRange[{1}]冲突 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1113 -# args: msg.getVmNicUuids().get(0) -the\ L3\ network\ of\ vm\ nic[uuid\:%s]\ doesn't\ have\ load\ balancer\ service\ enabled = 虚拟机网卡[uuid:{0}]的L3网络没有启用负载均衡服务 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1073 +# args: ao.getEndPort(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ invalid\ rule\ endPort[%d],\ endPort\ must\ be\ greater\ than\ or\ equal\ to\ startPort[%d] = 无法添加安全组规则,因为规则endPort[{0}]无效,endPort必须大于或等于startPort[{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1140 -# args: self.getUuid(),self.getProviderType(),msg.getVmNicUuids().get(0),providerType -service\ provider\ type\ mismatching.\ The\ load\ balancer[uuid\:%s]\ is\ provided\ by\ the\ service\ provider[type\:%s],\ but\ the\ L3\ network\ of\ vm\ nic[uuid\:%s]\ is\ enabled\ with\ the\ service\ provider[type\:\ %s] = 网络服务提供器的类型不匹配。负载均衡器[uuid:{0}]由服务提供器[type:{1}]提供,但虚拟机网卡[uuid:{2}]的L3网络启用服务器类型为[type: {3}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1076 +# args: ao.getDstPortRange(),ao.getStartPort() +could\ not\ add\ security\ group\ rule,\ because\ dstPortRange[%s]\ and\ starPort[%s]\ are\ in\ conflict = 无法添加安全组规则,因为DstPortRange[{0}]和StarPort[{1}]冲突 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java:1670 -# args: param -invalid\ health\ checking\ parameters[%s],\ the\ format\ is\ method\:URI\:code,\ for\ example,\ GET\:/index.html\:http_2xx = 无效的健康检查参数[{0}],正确格式:method:URI:code,例如 GET:/index.html:http_2xx +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1087 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ TCP/UDP\ must\ set\ dstPortRange = 无法添加安全组规则,因为协议类型TCP/UDP必须设置dstPortRange -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:99 -# args: msg.getLoadBalancerUuid() -cannot\ find\ the\ load\ balancer[uuid\:%s] = 无法找到负载均衡器[uuid:{0}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1065 +# args: ao.getDstPortRange() +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ dstPortRange[%s] = 无法添加安全组规则,因为协议类型ALL或ICMP无法设置DstPortRange[{0}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:381 -# args: tag.getTag() -cannot\ delete\ the\ system\ tag[%s].\ The\ load\ balancer\ plugin\ relies\ on\ it,\ you\ can\ only\ update\ it = 无法删除系统标签[{0}]。负载均衡器插件依赖于该标签,该标签只能被更新 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1068 +# args: +could\ not\ add\ security\ group\ rule,\ because\ the\ protocol\ type\ ALL\ or\ ICMP\ cant\ not\ set\ startPort\ or\ endPort = 无法添加安全组规则,因为协议类型ALL或ICMP无法设置StartPort或EndPort -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:399 -# args: nicUuid,systemTag -nic[uuid\:%s]\ not\ found.\ Please\ correct\ your\ system\ tag[%s]\ of\ loadbalancer = 找不到网卡[uuid:{0}]。请检查负载均衡器的系统标签[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1097 +# args: JSONObjectUtil.toJsonString(newRules.get(i)),JSONObjectUtil.toJsonString(newRules.get(j)) +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ and\ rule[%s]\ are\ dupilicated = 无法添加安全组规则,因为规则[{0}]和规则[{1}]重复 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:411 -# args: systemTag,s -invalid\ balancer\ weight[%s],\ %s\ is\ not\ a\ number = 无效的权重值[{0}], {1}不是一个数字 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1121 +# args: JSONObjectUtil.toJsonString(sao),vo.getUuid() +could\ not\ add\ security\ group\ rule,\ because\ rule[%s]\ is\ duplicated\ to\ rule[uuid\:%s]\ in\ datebase = 无法添加安全组规则,因为规则[{0}]与数据库中的规则[uuid:{1}]重复 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:407 -# args: systemTag,s,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX -invalid\ balancer\ weight[%s],\ %s\ is\ not\ in\ the\ range\ [%d,\ %d] = 无效的权重值[{0}], {1}不在允许范围[{2}, {3}]中 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1136 +# args: SecurityGroupRuleType.Egress,SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ has\ reached\ the\ maximum\ limit[%d] = 无法添加安全组规则,因为安全组{0}规则已达到最大限制[{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:423 -# args: algorithm,LoadBalancerConstants.BALANCE_ALGORITHMS -invalid\ balance\ algorithm[%s],\ valid\ algorithms\ are\ %s = 无效的均衡算法[{0}],有效的为[{1}] +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1144 +# args: SecurityGroupRuleType.Egress,(egressRuleCount + toCreateEgressRuleCount),SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) +could\ not\ add\ security\ group\ rule,\ because\ security\ group\ %s\ rules\ number[%d]\ is\ out\ of\ max\ limit[%d] = 无法添加安全组规则,因为安全组{0}规则编号[{1}]超出最大限制[{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:497 -# args: systemTag,s -invalid\ unhealthy\ threshold[%s],\ %s\ is\ not\ a\ number = 无效的不健康阈值[{0}],[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1148 +# args: msg.getPriority(),ingressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ ingress\ rule\ maximum\ priority\ is\ [%d] = 无法添加安全组规则,因为优先级[{0}]必须连续,入口规则最大优先级为[{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:511 -# args: systemTag,s -invalid\ healthy\ threshold[%s],\ %s\ is\ not\ a\ number = 无效的健康阈值[{0}],[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java:1151 +# args: msg.getPriority(),egressRuleCount +could\ not\ add\ security\ group\ rule,\ because\ priority[%d]\ must\ be\ consecutive,\ the\ egress\ rule\ maximum\ priority\ is\ [%d] = 无法添加安全组规则,因为优先级[{0}]必须是连续的,出口规则最大优先级为[{1}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:525 -# args: systemTag,s -invalid\ healthy\ timeout[%s],\ %s\ is\ not\ a\ number = 无效的健康超时[{0}],[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:217 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ must\ be\ vpc\ network\ because\ other\ backend\ network\ is\ vpc\ network = 无法执行API操作。后端网络[uuid:{0}]必须是VPC网络,因为其他后端网络是VPC网络 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:539 -# args: systemTag,s -invalid\ connection\ idle\ timeout[%s],\ %s\ is\ not\ a\ number = 无效的连接空闲超时[{0}],[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:228 +# args: uuid,bVrUuids.get(0),firstBackendVrUuids.get(0) +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ connected\ vpc\ router\ [uuid\:%s]\ while\ other\ backend\ network\ is\ connected\ to\ vpc\ router[uuid\:%s] = 无法执行API操作。后端网络[uuid:{0}]连接到VPC路由器[uuid:{1}],而另一个后端网络连接到VPC路由器[uuid:{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:553 -# args: systemTag,s -invalid\ health\ check\ interval[%s],\ %s\ is\ not\ a\ number = 无效的健康检查间隔[{0}],[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:186 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ must\ be\ private\ flat\ network\ because\ frond\ l3\ network\ is\ private\ flat\ network = 无法执行API操作。后端网络[uuid:{0}]必须是专用三层网络,因为前端三层网络是专用三层网络 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:567 -# args: systemTag,s -invalid\ max\ connection[%s],\ %s\ is\ not\ a\ number = 无效的最大连接[{0}],[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:156 +# args: frontL3.getUuid() +could\ not\ execute\ the\ api\ operation.\ frontend\ network\ [uuid\:%s]\ is\ not\ connected\ vpc\ router = 无法执行API操作。前端网络[uuid:{0}]未连接VPC路由器 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:585 -# args: systemTag,protocol,LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCOLS -invalid\ health\ target[%s],\ the\ target\ checking\ protocol[%s]\ is\ invalid,\ valid\ protocols\ are\ %s = 无效的健康检查目标[{0}],目标检查协议无效[{1}],有效的为[{2}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:164 +# args: uuid +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ must\ be\ vpc\ network\ because\ frond\ l3\ network\ is\ vpc\ network = 无法执行API操作。后端网络[uuid:{0}]必须是VPC网络,因为前端三层网络是VPC网络 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:597 -# args: systemTag,port -invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ a\ number = 无效的健康检查目标[{0}],端口[{1}]不是一个数字 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:175 +# args: uuid,backendVrUuids.get(0),frontVrUuids.get(0) +could\ not\ execute\ the\ api\ operation.\ backend\ network\ [uuid\:%s]\ is\ connected\ vpc\ router\ [uuid\:%s]\ while\ front\ network\ is\ connected\ to\ vpc\ router[uuid\:%s] = 无法执行API操作。后端网络[uuid:{0}]连接到VPC路由器[uuid:{1}],前端网络连接到VPC路由器[uuid:{2}] -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java:594 -# args: systemTag,port -invalid\ invalid\ health\ target[%s],\ port[%s]\ is\ not\ in\ the\ range\ of\ [1,\ 65535] = 无效的无效健康检查目标[{0}],端口[{1}]不在范围[1, 65535]内 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:254 +# args: msg.getDeployType() +could\ not\ create\ slb\ group\ because\ invalid\ deploy\ type\ %s = 无法创建SLB组,因为部署类型{0}无效 -# at: src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java:74 -# args: nicUuid,weight,LoadBalancerConstants.BALANCER_WEIGHT_MIN,LoadBalancerConstants.BALANCER_WEIGHT_MAX -invalid\ balancer\ weight\ for\ nic\:%s,\ %d\ is\ not\ in\ the\ range\ [%d,\ %d] = 无效的网卡:{0}权重值{1},不在有效范围[{2}, {3}]内 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:263 +# args: msg.getBackendType() +could\ not\ create\ slb\ group\ because\ invalid\ backend\ type\ %s = 无法创建SLB组,因为后端类型{0}无效 -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:206 -# args: msg.getVmNicUuid(),msg.getVipUuid() -guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ vip[uuid\:\ %s]\ are\ the\ same\ network = 虚拟机网卡[uuid:{0}]的客户L3网络和虚拟IP[uuid:{1}]的虚拟IP L3网络是同一个网络 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:298 +# args: frontL3Uuid,slbVO.getUuid() +can\ not\ detach\ front\ end\ l3\ network\ [uuid\:%s]\ from\ SLB\ instance = 无法从SLB实例分离前端三层网络[uuid:{0}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:181 -# args: msg.getVipUuid(),useForList.toString() -the\ vip[uuid\:%s]\ has\ been\ occupied\ other\ network\ service\ entity[%s] = 虚拟IP[uuid:{0}]已经被其他网络服务占用 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:303 +# args: slbVO.getManagementNetworkUuid(),slbVO.getUuid() +can\ not\ detach\ management\ l3\ network\ [uuid\:%s]\ from\ SLB\ instance = 无法从SLB实例分离管理三层网络[uuid:{0}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:66 -# args: msg.getRuleUuid(),state -Port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ current\ state\ is\ %s = 端口转发规则[uuid:{0}]未启用,当前状态[{1}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:315 +# args: msg.getVmNicUuid() +can\ not\ detach\ nic\ [uuid\:%s]\ from\ SLB\ instance,\ because\ it\ is\ the\ last\ backend\ l3\ network\ nic = 无法从SLB实例分离NIC[uuid:{0}],因为它是最后一个后端三层网络NIC -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:81 -# args: msg.getUuid() -port\ forwarding\ rule\ rule[uuid\:%s]\ has\ not\ been\ attached\ to\ any\ vm\ nic,\ can't\ detach = 端口转发规则[uuid:{0}]尚未被挂载到任何虚拟机网卡,无法卸载 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:343 +# args: msg.getVipUuid(),vipVO.getServicesTypes() +can\ not\ create\ load\ balancer\ because\ vip\ [uuid\:%s]\ has\ attached\ other\ network\ service\ [%s] = 无法创建负载平衡器,因为VIP[uuid:{0}]已附加其他网络服务[{1}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:95 -# args: msg.getRuleUuid(),vmNicUuid -port\ forwarding\ rule[uuid\:%s]\ has\ been\ attached\ to\ vm\ nic[uuid\:%s],\ can't\ attach\ again = 端口转发规则[uuid:{0}]已经被挂载到虚拟机网卡[uuid:{1}],无法再次挂载 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:350 +# args: msg.getVipUuid(),vrUuids +can\ not\ create\ load\ balancer\ because\ vip\ [uuid\:%s]\ has\ attached\ to\ vpc\ router\ [%s] = 无法创建负载平衡器,因为VIP[uuid:{0}]已连接到VPC路由器[{1}] -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:100 -# args: msg.getRuleUuid(),state -port\ forwarding\ rule[uuid\:%s]\ is\ not\ in\ state\ of\ Enabled,\ \ current\ state\ is\ %s.\ A\ rule\ can\ only\ be\ attached\ when\ its\ state\ is\ Enabled = 端口转发规则[uuid:{0}]没有启用,当前状态为{1}。一个规则只能在启用时被挂载 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:356 +# args: slbGroupUuid +can\ not\ create\ load\ balancer\ because\ invalid\ slb\ group\ [uuid\:%s] = 无法创建负载平衡器,因为SLB组[uuid:{0}]无效 -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:119 -# args: msg.getVmNicUuid(),msg.getRuleUuid() -guest\ l3Network\ of\ vm\ nic[uuid\:%s]\ and\ vip\ l3Network\ of\ port\ forwarding\ rule[uuid\:%s]\ are\ the\ same\ network = 虚拟机网卡[uuid:{0}]的客户L3网络和端口转发规则[uuid:{1}]的VIP L3网络是同一个网络 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:407 +# args: +could\ not\ add\ vmnic\ to\ load\ balancer\ server\ \ group\ because\ l3\ network\ is\ not\ connected\ slb\ instance = 无法将vmnic添加到负载平衡器服务器组,因为三层网络未连接到SLB实例 -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:166 -# args: msg.getVipPortStart(),msg.getVipPortEnd(),msg.getPrivatePortStart(),msg.getPrivatePortEnd() -for\ range\ port\ forwarding,\ the\ port\ range\ size\ must\ match;\ vip\ range[%s,\ %s]'s\ size\ doesn't\ match\ range[%s,\ %s]'s\ size = 对于范围端口转发,端口范围大小必须匹配;VIP范围[{0}, {1}]的大小不匹配范围[{2}, {3}]的大小 +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:389 +# args: uuid +could\ not\ add\ vmnic\ to\ load\ balancer\ server\ \ group\ because\ l3\ network\ [uuid\:%s]\ is\ connected\ any\ vpc\ router = 无法将vmnic添加到负载平衡器服务器组,因为三层网络[uuid:{0}]已连接到任何VPC路由器 -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:173 -# args: msg.getAllowedCidr() -invalid\ CIDR[%s] = 无效的CIDR[{0}] +# at: src/main/java/org/zstack/network/service/slb/SlbApiInterceptor.java:396 +# args: uuid +could\ not\ add\ vmnic\ to\ load\ balancer\ server\ \ group\ because\ l3\ network[uuid\:%s]\ is\ connected\ to\ different\ vpc\ router = 无法将vmnic添加到负载平衡器服务器组,因为三层网络[uuid:{0}]已连接到不同的VPC路由器 -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:191 -# args: vipStart,vipEnd,vo.getUuid(),vo.getVipPortStart(),vo.getVipPortEnd() -vip\ port\ range[vipStartPort\:%s,\ vipEndPort\:%s]\ overlaps\ with\ rule[uuid\:%s,\ vipStartPort\:%s,\ vipEndPort\:%s] = 虚拟IP(vip)端口范围[vipStartPort:{0}, vipEndPort:{1}]与规则[uuid:{2}, vipStartPort:{3}, vipEndPort:{4}]重叠 +# at: src/main/java/org/zstack/network/service/slb/SlbCreatePublicVipFlow.java:60 +# args: slbInstance.getUuid(),frontL3Uuid +can\ not\ find\ nic\ of\ slb\ instance\ [uuid\:%s]\ which\ is\ attached\ to\ slb\ group\ front\ l3\ network\ [uuid\:%s] = 找不到SLB实例[uuid:{0}]的网卡,该网卡挂接在SLB组前三层网络[uuid:{1}]上 -# at: src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java:243 -# args: vm.getName(),vm.getUuid(),vipUuid -the\ VM[name\:%s\ uuid\:%s]\ already\ has\ port\ forwarding\ rules\ that\ have\ different\ VIPs\ than\ the\ one[uuid\:%s] = 虚拟机[name:{0} uuid:{1}]已经有端口转发规则,且与[uuid:{2}]有不同的VIPs +# at: src/main/java/org/zstack/network/service/slb/SlbVyosBackend.java:38 +# args: +can\ not\ find\ slb\ vm\ instance = 找不到SLB云主机实例 + +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:48 +# args: +system\ vip\ can\ not\ be\ deleted\ by\ API\ message = API消息无法删除系统VIP -# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:49 +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:54 # args: msg.getAllocatorStrategy() unsupported\ ip\ allocation\ strategy[%s] = 不支持的ip分配策略[{0}] -# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:61 -# args: msg.getRequiredIp() -requiredIp[%s]\ is\ not\ in\ valid\ IPv6\ mediaType = 请求的ip[{0}]不是有效的IPv6地址 - -# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:56 +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:63 # args: msg.getRequiredIp() requiredIp[%s]\ is\ not\ in\ valid\ IPv4\ mediaType = 请求的ip[{0}]不是有效的IPv4地址 # at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:70 # args: msg.getRequiredIp(),msg.getL3NetworkUuid() -there\ is\ already\ a\ vip[%s]\ on\ l3Network[uuid\:%s] = 已有一个vip[{0}]在L3网络[uuid:{1}]上 +there\ is\ already\ a\ vip[%s]\ on\ l3Network[uuid\:%s] = 已有一个vip[{0}]在三层网络[uuid:{1}]上 + +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:76 +# args: msg.getRequiredIp() +required\ ip\ address\ [%s]\ is\ already\ used = 所需的IP地址[{0}]已被使用 -# at: src/main/java/org/zstack/network/service/vip/VipBase.java:152 +# at: src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java:100 +# args: +could\ not\ create\ vip,\ because\ can\ not\ determine\ the\ vip\ version = 无法创建VIP,因为无法确定VIP版本 + +# at: src/main/java/org/zstack/network/service/vip/VipBase.java:155 # args: self.getUuid(),self.getName(),self.getIp(),self.getServiceProvider() service\ provider\ of\ the\ vip[uuid\:%s,\ name\:%s,\ ip\:\ %s]\ has\ been\ set\ to\ %s = vip[uuid:{0}, name:{1}, ip: {2}]的服务提供器已经被设置成[{3}] -# at: src/main/java/org/zstack/network/service/vip/VipBase.java:712 -# args: self.getUuid(),self.getIp() -Vip\ [uuid\ %s,\ ip\ %s]\ of\ router\ public\ interface\ can\ not\ be\ deleted = 路由公共接口的虚拟IP[uuid {0}, ip {1}]不能删除 - # at: src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java:43 # args: -VipQos\ for\ ipv6\ wil\ be\ added\ soon = +VipQos\ for\ ipv6\ wil\ be\ added\ soon = IPv6的VIPQoS将很快添加 # at: src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java:53 # args: msg.getVipUuid() @@ -5268,7 +9004,7 @@ SetVipQos\ MUST\ set\ InboundBandwidth\ or\ OutboundBandwidth = 设置虚拟IP # at: src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java:67 # args: -Cannot\ set\ Qos\ for\ this\ Vip.\ Not\ all\ peer\ l3networks\ provide\ VipQos\ service. = +Cannot\ set\ Qos\ for\ this\ Vip.\ Not\ all\ peer\ l3networks\ provide\ VipQos\ service. = 无法设置此VIP的QoS。并非所有对等三层网络都提供VIPQoS服务。 # at: src/main/java/org/zstack/network/service/vipQos/VipQosApiInterceptor.java:80 # args: msg.getUuid() @@ -5282,345 +9018,481 @@ VipQos\ for\ Vip\ [uuid\:\ %s]\ port\ %s\ does\ not\ exist = 虚拟IP[uuid: {0}] # args: vipUuid Can\ not\ find\ VipQos\ backend\ for\ Vip\ [uuid\:%s] = 未找到虚拟IP的Qos后端 -# at: src/main/java/org/zstack/network/service/vipQos/flat/FlatVipQosBackend.java:197 +# at: src/main/java/org/zstack/network/service/vipQos/flat/FlatVipQosBackend.java:198 # args: hostUuid -operation\ error,\ vip\ %s\ has\ not\ bind\ to\ vm = 操作失败,虚拟IP{0}没有绑定虚拟机 +operation\ error,\ vip\ %s\ has\ not\ bind\ to\ vm = 操作失败,虚拟IP{0}没有绑定云主机 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:277 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:656 # args: self.getName(),self.getUuid(),self.getState() the\ virtual\ router[name\:%s,\ uuid\:%s,\ current\ state\:%s]\ is\ not\ running,and\ cannot\ perform\ required\ operation.\ Please\ retry\ your\ operation\ later\ once\ it\ is\ running = 云路由[name:{0}, uuid:{1}, current state:{2}]没有运行,无法执行请求的操作。请在其启动后重试 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:282 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:661 # args: self.getUuid(),getSelf().getStatus(),msg.getPath() virtual\ router[uuid\:%s]\ is\ in\ status\ of\ %s\ that\ cannot\ make\ http\ call\ to\ %s = 云路由[uuid:{0}]处于状态{1}中,无法向{2}发送http调用 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:287 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:666 # args: self.getUuid(),msg.getPath() -virtual\ router[uuid\:%s]\ has\ no\ management\ nic\ that\ cannot\ make\ http\ call\ to\ %s = - -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:397 -# args: getSelf().getUuid() -appliance\ vm\ %s\ reconnect\ failed = +virtual\ router[uuid\:%s]\ has\ no\ management\ nic\ that\ cannot\ make\ http\ call\ to\ %s = 虚拟路由器[uuid:{0}]没有无法对{1}进行HTTP调用的管理NIC -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:473 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:995 # args: info.getIp(),info.getMac(),vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError() unable\ to\ add\ nic[ip\:%s,\ mac\:%s]\ to\ virtual\ router\ vm[uuid\:%s\ ip\:%s],\ because\ %s = 不能添加网卡[ip:{0}, mac:{1}]到虚拟路由设备[uuid:{2} ip:{3}],因为{4} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java:750 -# args: info,vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError() -unable\ to\ detach\ nic[%s]\ from\ virtual\ router\ vm[uuid\:%s\ ip\:%s],\ because\ %s = 无法从云路由设备[uuid:{1} ip:{2}]上卸载网卡[{0}],错误细节: {3} +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:94 +# args: msg.getDefaultRouteL3NetworkUuid(),msg.getVmInstanceUuid() +l3\ uuid[\:%s]\ is\ same\ to\ default\ network\ of\ virtual\ router\ [uuid\:%s] = L3 uuid[:{0}]与虚拟路由器[uuid:{1}]的默认网络相同 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:106 -# args: msg.getDefaultRouteL3NetworkUuid() -could\ not\ set\ the\ default\ network,\ because\ l3\ uuid[\:%s]\ is\ management\ network = 设置默认网络失败,因为三层网路[:{0}] 是管理网络 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:107 +# args: msg.getDefaultRouteL3NetworkUuid(),msg.getVmInstanceUuid() +l3\ uuid[\:%s]\ is\ not\ attached\ to\ virtual\ router\ [uuid\:%s] = L3 uuid[:{0}]未连接到虚拟路由器[uuid:{1}] -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:108 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:114 # args: msg.getDefaultRouteL3NetworkUuid() could\ not\ set\ the\ default\ network,\ because\ l3\ uuid[\:%s]\ is\ not\ public\ network = 设置默认网络失败,因为三层网路[:{0}] 不是公有网络 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:149 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:112 +# args: msg.getDefaultRouteL3NetworkUuid() +could\ not\ set\ the\ default\ network,\ because\ l3\ uuid[\:%s]\ is\ management\ network = 设置默认网络失败,因为三层网路[:{0}] 是管理网络 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:219 # args: msg.getImageUuid(),type,ImageMediaType.RootVolumeTemplate image[uuid\:%s]'s\ mediaType\ is\ %s,\ the\ mediaType\ of\ a\ virtual\ router\ image\ must\ be\ %s = 镜像[uuid:{0}]的mediaType为{1},云路由的mediaType必须为{2} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:155 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:225 # args: msg.getImageUuid(),format image[uuid\:%s]\ is\ of\ format\ %s,\ cannot\ be\ used\ for\ virtual\ router = 镜像[uuid:{0}]的格式为{1},无法被用于云路由 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:125 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:191 # args: msg.getManagementNetworkUuid(),msg.getZoneUuid() management\ network[uuid\:%s]\ is\ not\ in\ the\ same\ zone[uuid\:%s]\ this\ offering\ is\ going\ to\ create = 管理网络[uuid:{0}]和将要创建的规格不处于同一个区域(zone)[uuid:{1}]中 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:138 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:196 +# args: +can\ not\ create\ virtual\ router\ offering,\ because\ management\ network\ doesn't\ support\ ipv6\ yet = 无法创建虚拟路由器产品,因为管理网络尚不支持IPv6 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:208 # args: msg.getManagementNetworkUuid(),msg.getZoneUuid() public\ network[uuid\:%s]\ is\ not\ in\ the\ same\ zone[uuid\:%s]\ this\ offering\ is\ going\ to\ create = 公共网络[uuid:{0}]和将要创建的规格不处于同一个区域(zone)[uuid:{1}]中 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:166 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:236 # args: msg.getPublicNetworkUuid() -the\ L3\ network[uuid\:\ %s]\ has\ the\ SNAT\ service\ enabled,\ it\ cannot\ be\ used\ as\ a\ public\ network = L3网络[uuid: {0}]启用了SNAT服务,无法被用作公共网络 +the\ L3\ network[uuid\:\ %s]\ has\ the\ SNAT\ service\ enabled,\ it\ cannot\ be\ used\ as\ a\ public\ network = 三层网络[uuid: {0}]启用了SNAT服务,无法被用作公共网络 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:164 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:234 # args: msg.getManagementNetworkUuid() -the\ L3\ network[uuid\:\ %s]\ has\ the\ SNAT\ service\ enabled,\ it\ cannot\ be\ used\ as\ a\ management\ network = L3网络[uuid: {0}]启用了SNAT服务,无法被用作管理网络 +the\ L3\ network[uuid\:\ %s]\ has\ the\ SNAT\ service\ enabled,\ it\ cannot\ be\ used\ as\ a\ management\ network = 三层网络[uuid: {0}]启用了SNAT服务,无法被用作管理网络 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:173 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:243 # args: msg.getManagementNetworkUuid(),msg.getPublicNetworkUuid() -the\ L3\ network[uuid\:\ %s]\ is\ same\ network\ address\ with\ [uuid\:\ %s],\ it\ cannot\ be\ used\ for\ virtual\ router = L3网络[uuid: {0}] 和 网络 [uuid: {1}] 具有相同的网络地址,无法被用于云路由 +the\ L3\ network[uuid\:\ %s]\ is\ same\ network\ address\ with\ [uuid\:\ %s],\ it\ cannot\ be\ used\ for\ virtual\ router = 三层网络[uuid: {0}] 和 网络 [uuid: {1}] 具有相同的网络地址,无法被用于云路由 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:183 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:253 # args: managementNetworkUuid the\ management\ network[uuid\:%s]\ doesn't\ have\ any\ IP\ range = 管理网络[uuid:{0}]不包含任何的IP范围 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:200 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java:274 # args: managementNetworkUuid,gateway the\ management\ network[uuid\:%s,\ gateway\:%s]\ is\ not\ reachable = 管理网络[uuid:{0}, gateway:{1}]不可抵达 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:107 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:103 # args: iso.getIsoPath(),vrSpec.getDestHost().getUuid(),vrSpec.getDestHost().getManagementIp(),iso.getVirtualRouterUuid(),rsp.getError() failed\ to\ create\ VirtualRouterBootstrapIso[%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s]\ for\ virtual\ router[uuid\:%s],\ because\ %s = 创建云路由引导镜像(VirtualRouterBootstrapIso)[{0}]失败,该操作是在KVM物理机[uuid:{1}, ip:{2}]上为云路由[uuid:{3}]执行的,原因为{4} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:140 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackend.java:136 # args: iso.getIsoPath(),hostUuid,iso.getVirtualRouterUuid(),rsp.getError() failed\ to\ delete\ VirtualRouterBootstrapIso[%s]\ on\ kvm\ host[uuid\:%s]\ for\ virtual\ router[uuid\:%s],\ because\ %s = 删除云路由引导镜像(VirtualRouterBootstrapIso)[{0}]失败,该操作是在KVM物理机[uuid:{1}]上为云路由[uuid:{2}]执行的,原因为{3} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:280 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:289 # args: cannot\ create\ virtual\ Router\ vm\ while\ virtual\ router\ network\ overlaps\ with\ private\ network\ in\ ip\ = 当云路由规格的网络和私有网络IP范围有重叠时,无法创建云路由设备 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:585 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:716 # args: offeringUuid -No\ virtual\ router\ instance\ offering\ with\ uuid\:%s\ is\ found = +No\ virtual\ router\ instance\ offering\ with\ uuid\:%s\ is\ found = 找不到uuid为{0}的虚拟路由器实例产品 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:720 +# args: offeringUuid,resourceUuid +the\ network\ of\ virtual\ router\ instance\ offering\ with\ uuid\:%s\ can't\ be\ same\ with\ private\ l3\ network\ uuid\:%s = uuid为{0}的虚拟路由器实例提供的网络不能与uuid为{1}的专用三层网络相同 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1434 +# args: l3NetworkUuid +cannot\ add\ ip\ range,\ because\ l3\ network[uuid\:%s]\ is\ management\ network\ of\ virtual\ router\ offering = 无法添加IP范围,因为三层网络[uuid:{0}]是虚拟路由器产品的管理网络 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1439 +# args: l3NetworkUuid +cannot\ add\ ip\ range,\ because\ l3\ network[uuid\:%s]\ is\ management\ network\ of\ virtual\ router = 无法添加IP范围,因为三层网络[uuid:{0}]是虚拟路由器的管理网络 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1466 +# args: tag,type +couldn't\ add\ image,\ because\ systemTag\ [%s]\ includes\ invalid\ appliance\ image\ type\ [%s] = 无法添加镜像,因为系统标记[{0}]包含无效的装置镜像类型[{1}] -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1182 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1504 # args: msg.getL3NetworkUuid() -failed\ tot\ attach\ virtual\ router\ network\ services\ to\ l3Network[uuid\:%s].\ When\ eip\ is\ selected,\ snat\ must\ be\ selected\ too = 挂载虚拟路由网络服务到L3网络[uuid:{0}]失败。选中EIP服务时,SNAT服务也必须被选中 +failed\ tot\ attach\ virtual\ router\ network\ services\ to\ l3Network[uuid\:%s].\ When\ eip\ is\ selected,\ snat\ must\ be\ selected\ too = 挂载虚拟路由网络服务到三层网络[uuid:{0}]失败。选中EIP服务时,SNAT服务也必须被选中 -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1186 +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1508 # args: msg.getL3NetworkUuid() -failed\ tot\ attach\ virtual\ router\ network\ services\ to\ l3Network[uuid\:%s].\ When\ port\ forwarding\ is\ selected,\ snat\ must\ be\ selected\ too = 挂载虚拟路由网络服务到L3网络[uuid:{0}]失败。选中端口转发服务时,SNAT服务也必须被选中 +failed\ tot\ attach\ virtual\ router\ network\ services\ to\ l3Network[uuid\:%s].\ When\ port\ forwarding\ is\ selected,\ snat\ must\ be\ selected\ too = 挂载虚拟路由网络服务到三层网络[uuid:{0}]失败。选中端口转发服务时,SNAT服务也必须被选中 + +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:2445 +# args: vrUuid,ret.getError() +update\ virtual\ router\ [uuid\:%s]\ default\ network\ failed,\ because\ %s = 更新虚拟路由器[uuid:{0}]默认网络失败,原因是{1} -# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:1698 -# args: toDeleteNics.stream().map( n -> n.getUuid()).collect(Collectors.toList()) -can\ not\ detach\ nic\ [uuid\:%s] = 无法卸载网卡nic[uuid:{0}] +# at: src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java:2541 +# args: ss[1] +invalid\ ApplianceVmType\ %s = 无效的设备VMType{0} -# at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java:126 -# args: vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError(),struct +# at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java:93 +# args: vr.getUuid(),vr.getManagementNic().getIp(),rsp.getError(),JSONObjectUtil.toJsonString(info) unable\ to\ add\ dhcp\ entries\ to\ virtual\ router\ vm[uuid\:%s\ ip\:%s],\ because\ %s,\ dhcp\ entry[%s] = 无法向云路由[uuid:{0} ip:{1}]添加DHCP条目,因为{2},DHCP条目为[{3}] +# at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java:375 +# args: +no\ virtual\ router\ is\ configured\ for\ vyos\ dhcp = 没有为VyOS DHCP配置虚拟路由器 + # at: src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterSyncDHCPOnStartFlow.java:208 # args: vr.getUuid(),vr.getManagementNic().getIp(),ret.getError() unable\ to\ program\ dhcp\ entries\ served\ by\ virtual\ router[uuid\:%s,\ ip\:%s],\ %s = 无法执行由云路由[uuid:{0}, ip:{1}]提供的DHCP条目{2}. # at: src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterDnsBackend.java:210 # args: vr.getUuid(),vr.getManagementNic().getIp(),struct,l3.getUuid(),l3.getName(),ret.getError() -virtual\ router[uuid\:%s,\ ip\:%s]\ failed\ to\ configure\ dns%s\ for\ L3Network[uuid\:%s,\ name\:%s],\ %s = 云路由[uuid:{0}, ip:{1}]未能为L3网络[uuid:{3}, name:{4}]配置DNS{2},错误细节: {5} +virtual\ router[uuid\:%s,\ ip\:%s]\ failed\ to\ configure\ dns%s\ for\ L3Network[uuid\:%s,\ name\:%s],\ %s = 云路由[uuid:{0}, ip:{1}]未能为三层网络[uuid:{3}, name:{4}]配置DNS{2},错误细节: {5} -# at: src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java:124 +# at: src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java:127 # args: vr.getName(),vr.getUuid(),JSONObjectUtil.toJsonString(dns),ret.getError() virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ configure\ dns%s,\ %s\ = 云路由[name: {0}, uuid: {1}]未能配置DNS{2},错误细节: {3} -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:496 -# args: vr.getUuid(),ret.getError() -failed\ to\ sync\ eip\ on\ virtual\ router[uuid\:%s],\ %s = 未能在云路由[uuid:{0}]上同步EIP,错误细节: {1} - -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:165 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:168 # args: struct.getEip().getUuid(),struct.getEip().getName(),struct.getVip().getIp(),struct.getNic().getUuid(),vr.getUuid(),ret.getError() -failed\ to\ create\ eip[uuid\:%s,\ name\:%s,\ ip\:%s]\ for\ vm\ nic[uuid\:%s]\ on\ virtual\ router[uuid\:%s],\ %s = 无法为虚拟机网卡[uuid:{3}]在云路由[uuid:{4}]上创建EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5} +failed\ to\ create\ eip[uuid\:%s,\ name\:%s,\ ip\:%s]\ for\ vm\ nic[uuid\:%s]\ on\ virtual\ router[uuid\:%s],\ %s = 无法为云主机网卡[uuid:{3}]在云路由[uuid:{4}]上创建EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5} -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:246 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:226 # args: offering.getUuid(),l3inv.getUuid(),l3inv.getZoneUuid(),struct.getVip().getL3NetworkUuid(),struct.getEip().getUuid() -found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ EIP[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = 在区域(zone)[uuid:{2}]上为L3网络[uuid:{1}]找到了云路由规格[uuid:{0}];但是,其公共网络[uuid:{3}]和EIP[uuid:{4}]的公共网络不是同一个L3网络。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该L3网络指定一个特定的云路有规格 +found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ EIP[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = 在区域(zone)[uuid:{2}]上为三层网络[uuid:{1}]找到了云路由规格[uuid:{0}];但是,其公共网络[uuid:{3}]和EIP[uuid:{4}]的公共网络不是同一个三层网络。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该三层网络指定一个特定的云路有规格 -# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:336 +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java:318 # args: struct.getEip().getUuid(),struct.getEip().getName(),struct.getVip().getIp(),struct.getNic().getUuid(),vr.getUuid(),ret.getError() -failed\ to\ remove\ eip[uuid\:%s,\ name\:%s,\ ip\:%s]\ for\ vm\ nic[uuid\:%s]\ on\ virtual\ router[uuid\:%s],\ %s = 未能在云路由[uuid:{4}]上为虚拟机网卡[uuid:{3}]移除EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5} +failed\ to\ remove\ eip[uuid\:%s,\ name\:%s,\ ip\:%s]\ for\ vm\ nic[uuid\:%s]\ on\ virtual\ router[uuid\:%s],\ %s = 未能在云路由[uuid:{4}]上为云主机网卡[uuid:{3}]移除EIP[uuid:{0}, name:{1}, ip:{2}],错误细节: {5} + +# at: src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java:214 +# args: vr.getUuid(),ret.getError() +failed\ to\ sync\ eip\ on\ virtual\ router[uuid\:%s],\ %s = 未能在云路由[uuid:{0}]上同步EIP,错误细节: {1} -# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:152 +# at: src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaBackendImpl.java:63 +# args: +ha\ group\ extension\ point\ nil = HA组扩展点Nil + +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:170 # args: msg.getVmNicUuids(),vrUuids -new\ add\ vm\ nics[uuids\:%s]\ and\ attached\ vmnics\ are\ not\ on\ the\ same\ vrouter,\ they\ are\ on\ vrouters[uuids\:%s] = 新添加的虚拟网卡[uuids:{0}]和绑定虚拟机的网卡没有在一个云路由上,它们分别在云路由[uuids:{1}]上 +new\ add\ vm\ nics[uuids\:%s]\ and\ attached\ vmnics\ are\ not\ on\ the\ same\ vrouter,\ they\ are\ on\ vrouters[uuids\:%s] = 新添加的虚拟网卡[uuids:{0}]和绑定云主机的网卡没有在一个云路由上,它们分别在云路由[uuids:{1}]上 -# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:182 +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:200 # args: msg.getVmNicUuids(),peerL3NetworkUuids,msg.getLoadBalancerUuid(),vrUuids -new\ add\ vm\ nics[uuids\:%s]\ and\ peer\ l3s[uuids\:%s]\ of\ loadbalancer[uuid\:\ %s]'s\ vip\ are\ not\ on\ the\ same\ vrouter,\ they\ are\ on\ vrouters[uuids\:%s] = 新添加的虚拟机网卡[uuids:{0}]和负载均衡器[uuid: {2}]的弹性IP的三层网络[uuids:{1}]没有在相同的云路由上,它们分别在云路由[uuids:{3}]上 +new\ add\ vm\ nics[uuids\:%s]\ and\ peer\ l3s[uuids\:%s]\ of\ loadbalancer[uuid\:\ %s]'s\ vip\ are\ not\ on\ the\ same\ vrouter,\ they\ are\ on\ vrouters[uuids\:%s] = 新添加的云主机网卡[uuids:{0}]和负载均衡器[uuid: {2}]的弹性IP的三层网络[uuids:{1}]没有在相同的云路由上,它们分别在云路由[uuids:{3}]上 + +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:1320 +# args: +vmnic\ must\ be\ specified\ for\ share\ loadbalancer = 必须为Share LoadBalancer指定vmnic -# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:1318 +# at: src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java:1778 # args: struct.getLb().getUuid() cannot\ find\ virtual\ router\ for\ load\ balancer\ [uuid\:%s] = 未能为负载均衡器[uuid:{0}]找到云路由 -# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java:331 +# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java:91 +# args: guestL3.getUuid(),guestL3.getName(),offering.getPublicNetworkUuid(),offering.getUuid(),offering.getName() +guest\ l3Network[uuid\:%s,\ name\:%s]\ needs\ SNAT\ service\ provided\ by\ virtual\ router,\ but\ public\ l3Network[uuid\:%s]\ of\ virtual\ router\ offering[uuid\:\ %s,\ name\:%s]\ is\ the\ same\ to\ this\ guest\ l3Network = 用户三层网络[uuid:{0}, name:{1}]需要云路由提供的SNAT服务,但是云路由规格[uuid: {3}, name:{4}]的公共三层网络[uuid:{2}]与该客户三层网络相同 + +# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java:144 # args: vr.getName(),vr.getUuid(),JSONObjectUtil.toJsonString(snatInfo),ret.getError() virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ sync\ snat%s,\ %s = 云路由[name: {0}, uuid: {1}]未能同步SNAT{2},错误细节: {3} -# at: src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java:92 -# args: guestL3.getUuid(),guestL3.getName(),offering.getPublicNetworkUuid(),offering.getUuid(),offering.getName() -guest\ l3Network[uuid\:%s,\ name\:%s]\ needs\ SNAT\ service\ provided\ by\ virtual\ router,\ but\ public\ l3Network[uuid\:%s]\ of\ virtual\ router\ offering[uuid\:\ %s,\ name\:%s]\ is\ the\ same\ to\ this\ guest\ l3Network = 用户L3网络[uuid:{0}, name:{1}]需要云路由提供的SNAT服务,但是云路由规格[uuid: {3}, name:{4}]的公共L3网络[uuid:{2}]与该客户L3网络相同 - -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ApplyPortforwardingRuleOnVirtualRouterVmFlow.java:80 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ApplyPortforwardingRuleOnVirtualRouterVmFlow.java:85 # args: to.getVipIp(),to.getPrivateIp(),to.getVipPortStart(),to.getVipPortEnd(),to.getPrivatePortStart(),to.getPrivatePortEnd(),ret.getError() failed\ to\ create\ port\ forwarding\ rule[vip\ ip\:\ %s,\ private\ ip\:\ %s,\ vip\ start\ port\:\ %s,\ vip\ end\ port\:\ %s,\ private\ start\ port\:\ %s,\ private\ end\ port\:\ %s],\ because\ %s = 无法创建端口转发规则[vip ip: {0}, private ip: {1}, vip start port: {2}, vip end port: {3}, private start port: {4}, private end port: {5}],错误细节: {6} -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ReleasePortForwardingRuleOnVirtualRouterVmFlow.java:74 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/ReleasePortForwardingRuleOnVirtualRouterVmFlow.java:82 # args: JSONObjectUtil.toJsonString(to),ret.getError() failed\ to\ revoke\ port\ forwarding\ rules\ %s,\ because\ %s = 未能解除端口转发规则{0},原因: {1} # at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:184 # args: offering.getUuid(),struct.getGuestL3Network().getUuid(),struct.getGuestL3Network().getZoneUuid(),struct.getVip().getL3NetworkUuid(),struct.getRule().getUuid() -found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ PortForwarding\ rule[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = 在区域(zone)[uuid:{2}]内为L3网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和端口转发规则[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该L3网络指定一个特定的云路有规格 +found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ PortForwarding\ rule[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = 在区域(zone)[uuid:{2}]内为三层网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和端口转发规则[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该三层网络指定一个特定的云路有规格 # at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:249 # args: rule.getVipPortStart(),rule.getVipPortEnd(),rule.getPrivatePortStart(),rule.getPrivatePortEnd() virtual\ router\ doesn't\ support\ port\ forwarding\ range\ redirection,\ the\ vipPortStart\ must\ be\ equals\ to\ privatePortStart\ and\ vipPortEnd\ must\ be\ equals\ to\ privatePortEnd;but\ this\ rule\ rule\ has\ a\ mismatching\ range\:\ vip\ port[%s,\ %s],\ private\ port[%s,\ %s] = 云路由不支持范围性的端口转发重定向,vipPortStart和privatePortStart必须一致,vipPortEnd和privatePortEnd必须一致,但这条规则有个不匹配的范围: vip端口范围[{0}, {1}],私有端口范围[{2}, {3}] -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:402 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:408 # args: vrVO.getUuid(),ret.getError() failed\ to\ add\ portforwardings\ on\ virtual\ router[uuid\:%s],\ %s = 在云路由[uuid:{0}]添加端口转发失败,{1} -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:471 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java:484 # args: vrVO.getUuid(),ret.getError() failed\ to\ revoke\ port\ forwardings\ on\ virtual\ router[uuid\:%s],\ %s = 取消在云路由[uuid:{0}]上端口转发服务失败,{1} -# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java:197 +# at: src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java:212 # args: vr.getName(),vr.getUuid(),ret.getError() failed\ to\ sync\ port\ forwarding\ rules\ served\ by\ virtual\ router[name\:\ %s,\ uuid\:\ %s],\ because\ %s = 未能同步由云路由[name: {0}, uuid: {1}]提供的端口转发规则,因为: {2} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreateVipForPublicIpFlow.java:66 -# args: vr.getName(),vr.getUuid(),nic.getIp(),nic.getL3NetworkUuid() -virtual\ router[name\:\ %s,\ uuid\:\ %s]\ failed\ to\ create\ vip\ for\ public\ ip\ %s\ because\ no\ ip\ range\ for\ l3NetworkUuid\ %s = 虚拟路由[name: {0}, uuid: {1}]为公有IP创建虚拟IP失败,因为三层网络[uuid:{3}]的没有IP段 - -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:136 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:179 # args: tos,ret.getError() failed\ to\ remove\ vip%s,\ because\ %s = 未能移除VIP{0},因为{1} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:92 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:125 # args: tos,vr.getUuid(),ret.getError() failed\ to\ create\ vip%s\ on\ virtual\ router[uuid\:%s],\ because\ %s = 未能在云路由[uuid:{1}]上创建VIP{0},因为{2} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:201 -# args: vips.stream().map( v -> v.getIp()).collect(Collectors.toList()),nic.getVmInstanceUuid(),nic.getUuid(),nic.getIp(),ret.getError() +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java:245 +# args: vips.stream().map(VipTO::getIp).collect(Collectors.toList()),nic.getVmInstanceUuid(),nic.getUuid(),nic.getIp(),ret.getError() failed\ to\ sync\ vips[ips\:\ %s]\ on\ virtual\ router[uuid\:%s]\ for\ attaching\ nic[uuid\:\ %s,\ ip\:\ %s],\ because\ %s = 为了绑定网卡[uuid: {2}, ip: {3}]在云路由[uuid:{1}]上同步虚拟IP[ips: {0}]失败,因为{4} -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:262 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:240 # args: vrUuid,vrState virtual\ router[uuid\:%s,\ state\:%s]\ is\ not\ running = 云路由[uuid:{0}, state:{1}]没有运行 -# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:303 +# at: src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java:281 # args: offering.getUuid(),s.getL3Network().getUuid(),s.getL3Network().getZoneUuid(),self.getL3NetworkUuid(),self.getUuid() -found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ VIP[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = 在区域(zone)[uuid:{2}]内为L3网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和VIP[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该L3网络指定一个特定的云路有规格 +found\ a\ virtual\ router\ offering[uuid\:%s]\ for\ L3Network[uuid\:%s]\ in\ zone[uuid\:%s];\ however,\ the\ network's\ public\ network[uuid\:%s]\ is\ not\ the\ same\ to\ VIP[uuid\:%s]'s;\ you\ may\ need\ to\ use\ system\ tag\ guestL3Network\:\:l3NetworkUuid\ to\ specify\ a\ particular\ virtual\ router\ offering\ for\ the\ L3Network = 在区域(zone)[uuid:{2}]内为三层网络[uuid:{1}]找到了一个云路由规格[uuid:{0}];然而,其网络的公共网络[uuid:{3}]和VIP[uuid:{4}]的公共网络不一致。你可能需要使用系统标签[guestL3Network::l3NetworkUuid]为该三层网络指定一个特定的云路有规格 # at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosChangePrivateL3FirewallDefaultActionExtensionPoint.java:67 # args: nic.getIp(),nic.getMac(),nic.getVmInstanceUuid(),rsp.getError() failed\ to\ change\ nic[ip\:%s,\ mac\:%s]\ firewall\ default\ action\ of\ virtual\ router\ vm[uuid\:%s],\ because\ %s = 修改云路由[uuid:{2}]的网卡[ip:{0}, mac:{1}]的默认防火墙规则失败,因为{3} -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:56 -# args: vrUuid,ret.getError() -virtual\ router[uuid\:\ %s]\ failed\ to\ get\ version\ because\ %s\ = 获取云路由[uuid: {0}]版本失败,因为{1} +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java:156 +# args: mgmtNicIp +unable\ to\ ssh\ in\ to\ the\ virtual\ router[%s]\ after\ configure\ ssh = 配置SSH后,无法通过SSH连接到虚拟路由器[{0}] -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:63 -# args: vrUuid -virtual\ router[uuid\:\ %s]\ doesn't\ have\ version = 云路由[uuid: {0}]没有版本信息 +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java:214 +# args: ret.getError() +vyos\ init\ command\ failed,\ because\:%s = vyos init命令失败,原因是:{0} -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:69 -# args: vrUuid,ret.getVersion() -virtual\ router[uuid\:\ %s]\ version\ [%s]\ format\ error = 云路由[uuid{0}]版本号[{1}]格式错误 +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDhcpBackend.java:246 +# args: nic.getVmInstanceUuid(),rsp.getError() +unable\ to\ start\ dhcp\ server\ on\ virtual\ router\ vm[uuid\:%s],\ because\ %s = 无法在虚拟路由器VM[uuid:{0}]上启动DHCP服务器,因为{1} -# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java:75 -# args: vrUuid,ret.getVersion(),managementVersion -virtual\ router[uuid\:\ %s]\ version\ [%s]\ is\ older\ than\ management\ node\ version\ [%s] = 云路由[uuid: {0}]版本[{1}]比管理节点的版本[{2}]旧 +# at: src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDhcpBackend.java:282 +# args: nic.getVmInstanceUuid(),rsp.getError() +unable\ to\ stop\ dhcp\ server\ on\ virtual\ router\ vm[uuid\:%s],\ because\ %s = 无法停止虚拟路由器VM[uuid:{0}]上的DHCP服务器,因为{1} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:79 -# args: vmUuid,specMap.keySet() -failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ pci\ specs[uuids\:%s]\ exist = 云主机[uuid:{0}]启动失败,因为所设置的PCI设备规格[uuids:{1}]中有部分不存在 +# at: src/main/java/org/zstack/ovf/OvfHelper.java:104 +# args: id +File\ reference\ not\ fount\ for\ disk\ %s = 找不到磁盘{0}的文件引用 -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:132 -# args: vmUuid -no\ candidate\ host\ with\ enough\ spec\ related\ pci\ devices\ for\ vm[uuid\:%s] = +# at: src/main/java/org/zstack/ovf/OvfHelper.java:117 +# args: capacity +Illegal\ disk\ capacity\:\ %s = 非法磁盘容量:{0} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:154 -# args: vmUuid,specMap.keySet() -failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ mdev\ specs[uuids\:%s]\ exist = 云主机[uuid:{0}]启动失败,由于所设置的MDEV设备规格[uuids:{1}]中有部分不存在 +# at: src/main/java/org/zstack/ovf/OvfHelper.java:127 +# args: pSize +Illegal\ disk\ populated\ size\:\ %s = 非法的磁盘填充大小:{0} -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:205 -# args: vmUuid -no\ candidate\ host\ with\ enough\ spec\ related\ mdev\ devices\ for\ vm[uuid\:%s] = +# at: src/main/java/org/zstack/ovf/OvfHelper.java:288 +# args: +Volume\ controller\ not\ found. = 未找到卷控制器。 -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:260 -# args: specUuid,hostUuid,vmUuid -failed\ to\ find\ enough\ pci\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = 无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的PCI设备 +# at: src/main/java/org/zstack/ovf/OvfHelper.java:320 +# args: +CD\ Driver\ controller\ not\ found. = 找不到光驱控制器。 -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:337 -# args: specUuid,hostUuid,vmUuid -failed\ to\ find\ enough\ mdev\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = 无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的MDEV设备 +# at: src/main/java/org/zstack/ovf/OvfHelper.java:368 +# args: name +Ethernet\ Adapter\:\ %s\ do\ not\ connect\ to\ a\ network. = 以太网适配器:{0}不要连接到网络。 -# at: src/main/java/org/zstack/pciDevice/HostDeviceAllocatorFlow.java:411 -# args: vmUuid,errorCode -failed\ to\ sort\ host\ candidates\ for\ vm\ [uuid\:%s]\ in\ HostDeviceAllocatorFlow\:\ %s = +# at: src/main/java/org/zstack/ovf/OvfHelper.java:380 +# args: +Memory\ 'InstanceID'\ not\ found = 未找到内存“ instanceId ” -# at: src/main/java/org/zstack/pciDevice/PciDeviceAllocatorFactory.java:87 -# args: vo.getUuid(),vo.getHostUuid(),attachedPciUuid,dstHostUuid -specified\ pci\ devices\ not\ on\ same\ host\:\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = 云主机试图挂载来自不同物理机的PCI设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}] +# at: src/main/java/org/zstack/ovf/OvfHelper.java:387 +# args: +Memory\ 'VirtualQuantity'\ not\ found = 未找到内存“ virtualQuantity ” + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:392 +# args: quantity +Illegal\ Memory\ 'VirtualQuantity'\ value\:\ %s = 非法内存“ virtualQuantity ”值:{0} + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:401 +# args: +CPU\ 'InstanceID'\ not\ found = 未找到CPU “ instanceId ” + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:407 +# args: +CPU\ 'VirtualQuantity'\ not\ found = 未找到CPU ' virtualQuantity ' + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:412 +# args: quantity +Illegal\ CPU\ 'VirtualQuantity'\ value\:\ %s = 非法的CPU “ VirtualQuantity ”值:{0} + +# at: src/main/java/org/zstack/ovf/OvfHelper.java:422 +# args: cps +Illegal\ CPU\ 'CoresPerSocket'\ value\:\ %s = 非法的CPU “ CoreSperSocket ”值:{0} + +# at: src/main/java/org/zstack/ovf/OvfImageUploadTracker.java:156 +# args: failLongJobUuids +long\ job[uuid\:%s]\ execute\ fail = 长作业[uuid:{0}]执行失败 + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:69 +# args: msg.getVmUuid(),ovaUuid +Vm[uuid\:\ %s]\ is\ already\ exported\ as\ the\ ova\ package[uuid\:\ %s],\ please\ delete\ the\ package\ and\ try\ again. = VM[uuid:{0}]已作为OVA程序包[uuid:{1}]导出,请删除该程序包,然后重试。 + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:77 +# args: msg.getBackupStorageUuid() +Export\ vm\ requires\ an\ ImageStore\ backup\ storage,\ but\ given\ backupStorageUuid\:\ %s\ is\ not\ an\ ImageStore\ backup\ storage. = 导出VM需要ImageStore备份存储,但给定的BackupStorageUuid{0}不是ImageStore备份存储。 + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:84 +# args: msg.getVmUuid() +Not\ found\ the\ vm\ to\ be\ exported\ with\ the\ uuid\:\ %s = 未找到uuid为{0}的要导出的VM + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:89 +# args: VmInstanceState.Stopped.toString() +Only\ vm\ in\ state\:\ %s\ can\ be\ exported. = 只能导出状态为{0}的云主机。 + +# at: src/main/java/org/zstack/ovf/OvfInterceptor.java:114 +# args: +failed\ to\ parse\ jsonCreateVmParam\ in\ APICreateVmInstanceFromOvfMsg = 无法分析APICreateVmInstanceFromOvFMsg中的JsonCreateVmParam -# at: src/main/java/org/zstack/pciDevice/PciDeviceAllocatorFactory.java:140 +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:229 +# args: msg.getBackupStorageUuid(),msg.getVmUuid(),totalSize +backup\ storage[uuid\:\ %s]\ does\ not\ have\ enough\ available\ capacity\ for\ exporting\ vm[uuid\:\ %s],\ required\ capacity\ is\:\ %d = 备份存储[uuid:{0}]没有足够的可用容量来导出云主机[uuid:{1}],所需容量为:{2} + +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:629 +# args: msg.getUuid() +ova\ package[uuid\:\ %s]\ not\ found. = 未找到OVA程序包[uuid:{0}]。 + +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:757 +# args: +Failed\ to\ read\ ovf\ file. = 无法读取OVF文件。 + +# at: src/main/java/org/zstack/ovf/OvfManagerImpl.java:1028 # args: -cannot\ find\ required\ pci\ device\ on\ hosts = 没有物理机满足需要的pci 设备条件 +failed\ to\ create\ VM\ from\ OVF\ because\ the\ root\ disk\ of\ the\ VM\ cannot\ be\ found = 无法从OVF创建VM,因为找不到VM的根磁盘 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:416 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:417 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ doesn't\ exist = PCI设备[uuid:{0}]不存在 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:426 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:422 +# args: pci.getHostUuid() +could\ not\ enable\ sriov\ for\ device\ because\ iommu\ is\ disabled\ on\ host[uuid\:%s] = 无法为设备启用SRIOV,因为已在物理机[uuid:{0}]上禁用IOMMU + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:468 # args: pci.getHostUuid() pci\ devices\ in\ host[uuid\:%s]\ already\ sriov\ virtualized = 物理机[uuid:{0}]上的PCI设备已经SRIOV虚拟化,无法再次切分 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:437 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:473 # args: pci.getHostUuid() cannot\ sr-iov\ virtualize\ pci\ devices\ in\ host[uuid\:%s]\ that\ are\ attached\ to\ vm = 物理机[uuid:{0}]上的PCI设备已经挂载到云主机,无法SRIOV虚拟化 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:457 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:487 # args: minIns,pci.getType(),pci.getHostUuid() only\ %d\ virtual\ pci\ devices\ can\ be\ generated\ by\ %ss\ in\ host[uuid\:%s] = 物理机[uuid:{2}]上的{1}类型PCI设备最多被切分出{0}个虚拟PCI设备 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:569 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:609 # args: pci.getHostUuid(),pci.getUuid() the\ host[uuid\:%s]\ that\ pci\ device[uuid\:%s]\ in\ is\ not\ Connected = PCI设备[uuid:{1}]所在物理机[uuid:{0}]已失联 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:477 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:505 +# args: interfaceVO.getUuid() +cannot\ sr-iov\ virtualize\ pci\ devices\ on\ interface[uuid\:%s]\ that\ are\ been\ bonded = SR-IOV无法虚拟化已绑定的接口[uuid:{0}]上的PCI设备 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:513 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ not\ sriov\ virtualized = PCI设备[uuid:{0}]不存在,或者未处于SRIOV虚拟化状态 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:488 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:528 # args: pci.getHostUuid() virtual\ pci\ devices\ generated\ from\ pci\ devices\ in\ host[uuid\:%s]\ still\ attached\ to\ vm = 物理机[uuid:{0}]上存在仍处于已挂载状态的虚拟PCI设备,无法执行虚拟化还原操作 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:510 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:550 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ cannot\ be\ virtualized\ into\ mdevs,\ make\ sure\ it's\ enabled\ and\ un-attached = PCI设备[uuid:{0}]无法被切分为MDEV设备,请确保它处于启用状态,并且没有挂载到云主机 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:521 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:561 # args: msg.getPciDeviceUuid(),msg.getMdevSpecUuid() pci\ device[uuid\:%s]\ cannot\ be\ virtualized\ by\ mdev\ spec[uuid\:%s] = PCI设备[uuid:{0}]无法使用MDEV设备规格[uuid:{1}]进行虚拟化切分 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:543 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:583 # args: msg.getPciDeviceUuid() pci\ device[uuid\:%s]\ is\ not\ virtualized\ into\ mdevs = PCI设备[uuid:{0}]未处于VFIO_MDEV虚拟化状态 -# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:560 +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:600 # args: msg.getPciDeviceUuid() mdev\ devices\ generated\ from\ pci\ device[uuid\:%s]\ still\ attached\ to\ vm = PCI设备[uuid:{0}]切分出的MDEV设备仍处于已挂载状态,无法执行虚拟化还原操作 -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:989 -# args: spec.getType(),PciDeviceType.leagalPciDeviceCandidateTypes -illegal\ type[%s]\ for\ pci\ device\ spec,\ only\ %s\ are\ legal = +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:624 +# args: VmInstanceUuid +please\ umount\ all\ GPU\ devices\ of\ the\ vm[%s]\ and\ try\ again = 请卸载云主机[{0}]的所有GPU设备,然后重试 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:628 +# args: VmInstanceUuid +please\ umount\ all\ vGPU\ devices\ of\ the\ vm[%s]\ and\ try\ again = 请卸载云主机[{0}]的所有vGPU设备,然后重试 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceApiInterceptor.java:635 +# args: VmInstanceUuid +please\ umount\ other\ pci\ devices\ of\ the\ vm[%s]\ and\ try\ again = 请卸载VM[{0}]的其他PCI设备,然后重试 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java:59 +# args: vo.getUuid(),vo.getHostUuid(),attachedPciUuid,dstHostUuid +specified\ pci\ devices\ not\ on\ same\ host\:\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ pci\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = 云主机试图挂载来自不同物理机的PCI设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}] + +# at: src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java:92 +# args: +no\ candidate\ host\ with\ enough\ pci\ devices = 没有具有足够PCI设备的候选物理机 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceFilterFlow.java:123 +# args: vmUuid,specMap.keySet() +failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ pci\ specs[uuids\:%s]\ exist = 云主机[uuid:{0}]启动失败,因为所设置的PCI设备规格[uuids:{1}]中有部分不存在 -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:978 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1319 # args: vo.getType(),PciDeviceType.leagalPciDeviceCandidateTypes -illegal\ type[%s]\ for\ pci\ device,\ only\ %s\ are\ legal = +illegal\ type[%s]\ for\ pci\ device,\ only\ %s\ are\ legal = PCI设备的类型[{0}]非法,只有{1}是合法的 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:719 +# args: specUuid,hostUuid,vmUuid +failed\ to\ find\ enough\ pci\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = 无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的PCI设备 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:782 +# args: pciUuid +something\ wrong\ with\ iommu\ group\ of\ pci\ device[uuid\:%s] = PCI设备[uuid:{0}]的IOMMU组出现问题 -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:637 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:795 +# args: pciUuids +pci\ devices\ [%s]\ are\ not\ all\ available = PCI设备[{0}]并非全部可用 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:928 # args: msg.getPciDeviceUuid(),msg.getVmInstanceUuid() -can\ not\ attach\ this\ pci\ device[uuid\:%s]\ to\ vm[uuid\:%s]\ due\ to\ host\ allocation = 由于物理机分配问题导致不能将PCI设备[uuid:{0}]绑定虚拟机[uuid:{1}] +can\ not\ attach\ this\ pci\ device[uuid\:%s]\ to\ vm[uuid\:%s]\ due\ to\ host\ allocation = 由于物理机分配问题导致不能将PCI设备[uuid:{0}]绑定云主机[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:910 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1221 # args: msg.getVmInstanceUuid() -can\ not\ migrate\ vm[uuid\:%s]\ since\ pci\ device\ attached = 当PCI设备绑定后不能迁移虚拟机[uuid:{0}] +can\ not\ migrate\ vm[uuid\:%s]\ since\ pci\ device\ attached = 当PCI设备绑定后不能迁移云主机[uuid:{0}] -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:941 +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1270 # args: msg.getVolumeUuid() -cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ pci\ devices\ attached = 不能迁移根云盘[uuid:{0}],因为它所在的云主机挂载了PCI设备 +cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ pci\ devices\ attached = 不能迁移云盘[uuid:{0}],因为它所在的云主机挂载了PCI设备 -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1167 -# args: pciUuid,vmUuid -pci\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled\ for\ vm[uuid\:%s] = +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1316 +# args: pciDeviceUuid +pci\ device[uuid\:%s]\ doesn't\ exists = PCI设备[uuid:{0}]不存在 -# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1176 -# args: pciUuid,vo.getVmInstanceUuid(),vmUuid -pci\ device[uuid\:%s]\ already\ attached\ to\ vm[uuid\:%s],\ cannot\ attach\ to\ vm[uuid\:%s] = +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1330 +# args: pciSpecUuid +pci\ device\ spec[uuid\:%s]\ doesn't\ exists = PCI设备规范[uuid:{0}]不存在 -# at: src/main/java/org/zstack/pciDevice/PciDeviceReserveFlow.java:732 -# args: pciDeviceUuid, vmInstanceUuid -pci\ device[uuid\:%s]\ can\ not\ attach\ to\ vm[uuid\:%s]\ due\ to\ wrong\ status = 由于PCI设备[uuid:{0}]处于错误状态,无法绑定云主机[uuid:{1}] +# at: src/main/java/org/zstack/pciDevice/PciDeviceManager.java:1511 +# args: pciUuid,vmUuid +pci\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled\ for\ vm[uuid\:%s] = PCI设备[uuid:{0}]不存在或已为云主机[uuid:{1}]禁用 + +# at: src/main/java/org/zstack/pciDevice/PciDeviceReserveFlow.java:161 +# args: wrongStatusPciUuids,vmUuid +pci\ device[uuid\:%s]\ can\ not\ attach\ to\ vm[uuid\:%s]\ due\ to\ wrong\ status = 由于状态错误,PCI设备[uuid:{0}]无法连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/PciHostChangeStateExtension.java:58 +# at: src/main/java/org/zstack/pciDevice/PciHostChangeStateExtension.java:69 # args: inventory.getUuid(),hasPciVmUuids.toString() -The\ host\ [%s]\ has\ failed\ to\ enter\ the\ maintenance,\ The\ vm\ [%s]\ cannot\ migrate\ automatically\ because\ it\ contains\ the\ PCI\ device = 物理机[{0}]进入维护状态失败,这个虚拟机[{1}]不能自动迁移,因为虚拟机包含了PCI设备 +The\ host\ [%s]\ has\ failed\ to\ enter\ the\ maintenance,\ The\ vm\ [%s]\ cannot\ migrate\ automatically\ because\ it\ contains\ the\ PCI\ device = 物理机[{0}]进入维护状态失败,这个云主机[{1}]不能自动迁移,因为云主机包含了PCI设备 + +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java:185 +# args: vo.getType(),PciDeviceType.leagalPciDeviceCandidateTypes +illegal\ type[%s]\ for\ pci\ device\ spec,\ only\ %s\ are\ legal = PCI设备规范的类型[{0}]非法,只有{1}合法 # at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationApiInterceptor.java:258 # args: vmUuid,state @@ -5654,137 +9526,165 @@ vm[uuid\:%s]\ doesn't\ have\ mdev\ device\ spec[uuid\:%s] = 云主机[uuid:{0}] # args: vm.getUuid(),vm.getState(),msg.getMdevSpecUuid() vm\ instance[uuid\:%s,\ state\:%s]\ needs\ to\ be\ stopped\ to\ remove\ mdev\ device\ spec[uuid\:%s] = 云主机[uuid:{0}, state:{1}]需要处于关机状态下才可以取消MDEV设备规格[uuid:{2}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:373 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:374 # args: msg.getPciSpecUuid(),msg.getVmInstanceUuid() pci\ device\ spec[uuid\:%s]\ is\ not\ available\ for\ vm[uuid\:%s] = 云主机[uuid:{1}]无法设置PCI设备规格[uuid:{0}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:371 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:372 # args: msg.getVmInstanceUuid() no\ pci\ device\ spec\ available\ for\ vm[uuid\:%s] = 云主机[uuid:{0}]无可用的PCI设备规格 -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:366 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:367 # args: msg.getVmInstanceUuid(),rly.getError() -failed\ to\ get\ pci\ device\ spec\ available\ for\ vm[uuid\:%s]\:\ %s = +failed\ to\ get\ pci\ device\ spec\ available\ for\ vm[uuid\:%s]\:\ %s = 无法获取可用于VM[uuid:{0}]的PCI设备规范:{1} -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:454 -# args: pciUuidsNotMatch,msg.getVmInstanceUuid(),vmUuidsPciAttached -pci\ devices[uuid\:%s]\ should\ have\ been\ attached\ to\ vm[uuid\:%s]\ but\ it\ is\ attached\ to\ vm[uuid\:%s] = PCI设备[uuid:{0}]本应该绑定云主机[uuid:{1}], 但实际上绑定了云主机[uuid:{2}] - -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:565 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:557 # args: msg.getMdevSpecUuid(),msg.getVmInstanceUuid() mdev\ device\ spec[uuid\:%s]\ is\ not\ available\ for\ vm[uuid\:%s] = 云主机[uuid:{1}]无法设置MDEV设备规格[uuid:{0}] -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:558 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:550 # args: msg.getVmInstanceUuid() no\ mdev\ device\ spec\ available\ for\ vm[uuid\:%s] = 云主机[uuid:{0}]无可用的MDEV设备规格 -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:779 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:751 # args: specUuid,systemTag pci\ device\ spec[uuid\:%s]\ doesn't\ exist = PCI设备规格[uuid:{0}]不存在 -# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:792 +# at: src/main/java/org/zstack/pciDevice/specification/PciSpecificationManagerImpl.java:764 # args: specUuid,systemTag mdev\ device\ spec[uuid\:%s]\ doesn't\ exist = MDEV设备规格[uuid:{0}]不存在 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:153 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:191 # args: -cluster\ uuids\ or\ host\ uuid\ or\ vm\ uuid\ can\ not\ be\ set\ at\ same\ time = 获取候选规格列表时不要同时指定集群UUIDs、物理机UUID或云主机UUID +cluster\ uuids\ or\ host\ uuid\ or\ vm\ uuid\ can\ not\ be\ set\ at\ same\ time = 获取候选规格列表时不要同时指定集群uuids、物理机uuid或云主机uuid -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:160 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:198 # args: clusters\ not\ exist\ or\ disabled = 集群不存在或已禁用 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:194 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:232 # args: type,legalTypes illegal\ mdev\ device\ type\ [%s],\ only\ %s\ are\ legal = 非法的MDEV设备类型[{0}],只有{1}才是合法的 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:67 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:69 # args: cannot\ change\ the\ state\ of\ mdev\ device\ that's\ in\ attached\ status = MDEV设备处于已挂载状态,无法修改其状态 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:75 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:77 # args: msg.getMdevDeviceUuid() cannot\ attach\ mdev\ device[uuid\:%s]\ to\ vm,\ make\ sure\ it's\ enabled\ and\ un-attached = 无法为云主机挂载MDEV设备[uuid:{0}],因为该设备处于禁用状态或已被挂载 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:182 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:220 # args: cannot\ attach\ mdev\ device\ to\ vm\ instance\ that's\ not\ stopped = 云主机需要处于关机状态下才可以挂载MDEV设备 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:95 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:103 # args: msg.getVmInstanceUuid(),msg.getMdevDeviceUuid() vm[uuid\:%s]\ has\ pci\ devices\ attached\ that\ are\ in\ different\ host\ with\ mdev\ device[uuid\:%s] = 云主机[uuid:{0}]已经挂载了PCI设备,并且它们和MDEV设备[uuid:{1}]不在同一台物理机上 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:105 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:113 # args: msg.getVmInstanceUuid(),msg.getMdevDeviceUuid() vm[uuid\:%s]\ has\ mdev\ devices\ attached\ that\ are\ in\ different\ host\ with\ mdev\ device[uuid\:%s] = 云主机[uuid:{0}]已经挂载了MDEV设备,并且它们和MDEV设备[uuid:{1}]不在同一台物理机上 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:112 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:168 # args: mdev.getHostUuid(),mdev.getUuid(),HostState.Enabled,HostStatus.Connected -the\ host[uuid\:%s]\ that\ holds\ mdev\ device[uuid\:%s]\ is\ not\ [%s]\ and\ [%s] = +the\ host[uuid\:%s]\ that\ holds\ mdev\ device[uuid\:%s]\ is\ not\ [%s]\ and\ [%s] = 拥有MDEV设备[uuid:{1}]的物理机[uuid:{0}]不是[{2}]和[{3}] + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:132 +# args: msg.getVmInstanceUuid(),mdev.getUuid() +the\ vm[uuid\:%s]\ that\ holds\ se\ mdev\ device\ can\ not\ attach\ more\ se\ mdev[%s] = 拥有SE MDEV设备的VM[uuid:{0}]无法附加更多SE MDEV[{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:121 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:143 # args: mdev.getHostUuid(),mdev.getUuid(),HostState.Enabled,HostStatus.Connected -IOMMU\ of\ the\ host[uuid\:%s]\ that\ hosts\ pci\ device[uuid\:%s]\ is\ not\ [%s]\ and\ [%s] = +IOMMU\ of\ the\ host[uuid\:%s]\ that\ hosts\ pci\ device[uuid\:%s]\ is\ not\ [%s]\ and\ [%s] = 托管PCI设备[uuid:{1}]的物理机[uuid:{0}]的IOMMU不是[{2}]和[{3}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:134 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:156 # args: msg.getMdevDeviceUuid(),msg.getVmInstanceUuid() mdev\ device\ [uuid\:%s]\ is\ not\ attached\ to\ vm[uuid\:%s] = MDEV设备[uuid:{0}]没有挂载到云主机[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:143 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:181 # args: cannot\ detach\ mdev\ device\ from\ vm\ instance\ when\ it's\ not\ stopped = 云主机需要处于关机状态下才可以卸载MDEV设备 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:111 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceApiInterceptor.java:245 +# args: +cannot\ delete\ mdev\ device\ when\ it's\ attached = 无法删除已连接的MDEV设备 + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:379 +# args: msg.getVmInstanceUuid(),reply.getError() +failed\ to\ get\ candidate\ hosts\ to\ start\ vm[uuid\:%s],\ %s = 无法为云主机[uuid:{0}]寻找到可启动的物理机:{1} + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:100 +# args: mdevUuid +mdev\ device\ [%s]\ is\ not\ available = MDEV设备[{0}]不可用 + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:217 +# args: rsp.getError() +failed\ to\ hot\ plug\ mdev\ device\ to\ running\ vm,\ because\:%s = 无法将MDEV设备热插拔到正在运行的云主机,因为:{0} + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:278 # args: msg.getVmInstanceUuid(),msg.getMdevDeviceUuid() vm[uuid\:%s]\ cannot\ start\ in\ host\ that\ hold\ mdev\ device[uuid\:%s] = 云主机[uuid:{0}]无法在MDEV设备[uuid:{1}]所在的物理机上启动 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceBase.java:353 +# args: rsp.getError() +failed\ to\ hot\ unplug\ mdev\ device\ to\ running\ vm,\ because\:%s = 无法将MDEV设备热拔出到正在运行的云主机,原因是:{0} + # at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFactory.java:68 # args: pciDevice.getUuid(),PciDeviceVirtStatus.VFIO_MDEV_VIRTUALIZED pci\ device[uuid\:%s]\ is\ known\ as\ %s,\ but\ cannot\ find\ it's\ mdev\ spec,\ so\ abort. = PCI设备[uuid:{0}]是{1},但无法找到可用的MDEV设备规格 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java:48 +# args: vmUuid,specMap.keySet() +failed\ to\ start\ vm[uuid\:%s]\ because\ not\ all\ mdev\ specs[uuids\:%s]\ exist = 云主机[uuid:{0}]启动失败,由于所设置的MDEV设备规格[uuids:{1}]中有部分不存在 + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java:145 +# args: mdev.getUuid(),mdev.getHostUuid(),attachedMdevUuid,dstHostUuid +specified\ mdev\ devices\ not\ on\ same\ host\:\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = 云主机试图挂载来自不同物理机的MDEV设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}] + +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceFilterFlow.java:184 +# args: +no\ candidate\ host\ with\ enough\ mdev\ devices = 没有物理机满足mdev device设备的条件 + # at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceHostChangeStateExtension.java:55 # args: inventory.getUuid(),hasMdevVmUuids.toString() The\ host\ [%s]\ has\ failed\ to\ enter\ the\ maintenance,\ because\ vm[%s]\ has\ mdev\ devices\ attached\ and\ cannot\ migrate\ automatically = 物理机[{0}]无法进入维护模式,因为云主机[{1}]挂载了MDEV设备导致无法迁移 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:133 -# args: msg.getVmInstanceUuid(),rly.getError() -failed\ to\ get\ candidate\ hosts\ to\ start\ vm[uuid\:%s],\ %s = 无法为云主机[uuid:{0}]寻找到可启动的物理机:{1} +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:308 +# args: specUuid,hostUuid,vmUuid +failed\ to\ find\ enough\ mdev\ device\ of\ spec[uuid\:%s]\ in\ dest\ host[uuid\:%s]\ for\ vm[uuid\:%s] = 无法在物理机[uuid:{1}]上为云主机[uuid:{2}]找到足够多满足规格[uuid:{0}]的MDEV设备 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:231 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:352 # args: msg.getMdevDeviceUuid() cannot\ find\ mdev\ device[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到MDEV设备[uuid:{0}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:403 -# args: mdevUuid,vmUuid -mdev\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled\ for\ vm[uuid\:%s] = +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:555 +# args: vo.getUuid(),vmUuid +mdev\ device[uuid\:%s]\ doesn't\ exist\ or\ is\ disabled\ for\ vm[uuid\:%s] = MDEV设备[uuid:{0}]不存在或已为VM[uuid:{1}]禁用 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:412 -# args: mdevUuid,vo.getVmInstanceUuid(),vmUuid -mdev\ device[uuid\:%s]\ already\ attached\ to\ vm[uuid\:%s],\ cannot\ attach\ to\ vm\ [uuid\:%s] = - -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:509 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:644 # args: msg.getVmInstanceUuid() can\ not\ migrate\ vm[uuid\:%s]\ since\ mdev\ device\ attached = 无法迁移云主机[uuid:{0}],因为它挂载了MDEV设备 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:538 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:673 # args: msg.getVolumeUuid() cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ mdev\ devices\ attached = 无法迁移跟云盘[uuid:{0}],因为它所在云主机挂载了MDEV设备 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:553 +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:688 # args: msg.getVmInstanceUuid() cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ mdev\ devices\ attached = 无法迁移云主机[uuid:{0}],因为它挂载了MDEV设备 -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:796 -# args: mdev.getUuid(),mdev.getHostUuid(),attachedMdevUuid,dstHostUuid -specified\ mdev\ devices\ not\ on\ same\ host\:\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s]\ while\ mdev\ device[uuid\:\ %s]\ on\ host[uuid\:\ %s] = 云主机试图挂载来自不同物理机的MDEV设备:设备[uuid: {0}]来自物理机[uuid: {1}],而设备[uuid: {2}]来自物理机[uuid: {3}] +# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceReserveFlow.java:129 +# args: wrongStatusMdevUuids,vmUuid +mdev\ device[uuid\:%s]\ can\ not\ attach\ to\ vm[uuid\:%s]\ due\ to\ wrong\ status = 由于状态错误,MDEV设备[uuid:{0}]无法连接到VM[uuid:{1}] -# at: src/main/java/org/zstack/pciDevice/virtual/vfio_mdev/MdevDeviceManagerImpl.java:829 -# args: -no\ candidate\ host\ with\ enough\ mdev\ devices = 没有物理机满足mdev device设备的条件 +# at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostAllocatorFlow.java:71 +# args: String.format("maxInstancePerHost = %d", maxInstancePerHost) +No\ host\ with\ fewer\ than\ %s\ vms\ found = 找不到VM少于{0}的物理机 -# at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostAllocatorFlow.java:70 -# args: maxInstancePerHost -No\ host\ with\ fewer\ than\ %s\ vms\ found = +# at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java:76 +# args: HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN +%s\ must\ be\ a\ number = {0}必须是一个数字 # at: src/main/java/org/zstack/pluginpremium/compute/allocator/MaxInstancePerHostHostAllocatorStrategyFactory.java:58 # args: HostAllocatorConstant.MAX_INSTANCE_PER_HOST_HOST_ALLOCATOR_STRATEGY_TYPE,HostAllocatorSystemTags.MAX_INSTANCE_PER_HOST_TOKEN @@ -5794,141 +9694,173 @@ Select\ %s\ strategy,\ you\ must\ set\ %s = 选择策略{0},你必须设置{1} # args: HostAllocatorSystemTags.MINIMUM_MEMORY_USAGE_HOST_ALLOCATOR_STRATEGY_MODE_TOKEN,modes Incorrect\ %s\ settings,\ valid\ value\ is\ %s = 不正确的设置{0},有效的值是{1} -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:326 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:93 # args: -can\ not\ find\ related\ virtual\ router = +default\ route\ network\ can\ not\ be\ changed\ when\ system\ policy\ route\ is\ enabled = 启用系统策略路由时,无法更改默认路由网络 -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:117 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:382 +# args: +can\ not\ find\ related\ virtual\ router = 找不到相关的虚拟路由器 + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:132 # args: msg.getL3Uuid() -l3[%s]\ already\ attached\ a\ policy\ route\ ruleSet = +l3[%s]\ already\ attached\ a\ policy\ route\ ruleSet = L3[{0}]已附加策略路由规则集 -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:168 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:192 # args: msg.getvRouterUuid(),msg.getName() -VRouter[%s]\ already\ has\ a\ ruleSet\ named\ %s = +VRouter[%s]\ already\ has\ a\ ruleSet\ named\ %s = VRouter[{0}]已具有名为{1}的规则集 + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:283 +# args: +can\ not\ update\ system\ policy\ route\ set = 无法更新系统策略路由集 -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:174 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:198 # args: msg.getDestinationCidr() -DestinationCidr\ must\ be\ in\ cidr\ format\ but\ found\ [%s] = +DestinationCidr\ must\ be\ in\ cidr\ format\ but\ found\ [%s] = DestinationCIDR必须为CIDR格式,但找到[{0}] -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:178 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:202 # args: msg.getNextHopIp() -NextHopIp\ must\ be\ in\ ipv4\ format\ but\ found\ [%s] = +NextHopIp\ must\ be\ in\ ipv4\ format\ but\ found\ [%s] = NextHopIP必须为IPv4格式,但找到[{0}] -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:249 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:278 # args: -can\ not\ find\ related\ vRouter = +can\ not\ find\ related\ vRouter = 找不到相关的VRouter -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:271 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:288 +# args: +can\ not\ update\ system\ policy\ route\ table = 无法更新系统策略路由表 + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:237 +# args: ip +operation\ failure,\ ip\ format\ only\ supports\ ipv4/iprange/cidr,\ but\ find\ %s = 操作失败,IP格式仅支持IPv4/IPRange/CIDR,但找到{0} + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:245 +# args: protocol +illegal\ protocol\ type\ %s = 非法的协议类型{0} + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:254 +# args: msg.getRuleSetUuid(),msg.getRuleNumber() +RuleSet[%s]\ already\ has\ a\ rule\ with\ rule\ number\ %s. = 规则集[{0}]已具有规则编号为{1}的规则。 + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:310 # args: msg.getvRouterUuid(),msg.getNumber() -VRouter[%s]\ already\ has\ a\ policy\ route\ table\ [%s] = +VRouter[%s]\ already\ has\ a\ policy\ route\ table\ [%s] = VRouter[{0}]已具有策略路由表[{1}] -# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:309 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:387 +# args: +can\ not\ delete\ system\ policy\ route\ table = 无法删除系统策略路由表 + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:371 +# args: +can\ not\ delete\ system\ policy\ route\ set = 无法删除系统策略路由集 + +# at: src/main/java/org/zstack/policyRoute/PolicyRouteApiInterceptor.java:360 # args: msg.getUuid() -ruleSet[%s]\ is\ still\ attached\ to\ nic = +ruleSet[%s]\ is\ still\ attached\ to\ nic = 规则集[{0}]仍连接到NIC -# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:743 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:958 # args: vrouterVmUuid virtual\ router[uuid\:%s]\ can\ not\ find = 云路由[uuid:{0}]未找到 -# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:748 +# at: src/main/java/org/zstack/policyRoute/PolicyRouteManagerImpl.java:963 # args: vo.getApplianceVmType() can\ not\ find\ service\ factory\ for\ virtual\ router\ type[%s] = 未找到云路由类型为[{0}]的服务工厂 -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:47 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:54 # args: msg.getMirrorNetworkUuid() -Invalid\ parameter\ [%s],\ make\ sure\ it's\ PortMirror\ Network = +Invalid\ parameter\ [%s],\ make\ sure\ it's\ PortMirror\ Network = 参数[{0}]无效,请确保它是PortMirror网络 -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:55 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:62 # args: msg.getMirrorNetworkUuid() -The\ network[%s]\ has\ been\ attached\ with\ a\ PortMirror\ service = +The\ network[%s]\ has\ been\ attached\ with\ a\ PortMirror\ service = 网络[{0}]已附加PortMirror服务 -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:63 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:70 # args: msg.getUuid() -The\ PortMirror\ service[%s]\ has\ not\ been\ created = +The\ PortMirror\ service[%s]\ has\ not\ been\ created = 尚未创建PortMirror服务[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:99 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:86 # args: msg.getSrcEndPoint(),msg.getDstEndPoint(),mirror.getUuid() -The\ nic[%s,\ %s]\ has\ been\ mirrored\ by\ service[%s] = +The\ nic[%s,\ %s]\ has\ been\ mirrored\ by\ service[%s] = NIC[{0},{1}]已由服务[{2}]镜像 -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:105 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:92 # args: msg.getSrcEndPoint(),mirror.getUuid() -The\ nic[%s]\ can't\ been\ mirrored\ for\ service[%s]\ using = +The\ nic[%s]\ can't\ been\ mirrored\ for\ service[%s]\ using = 无法使用为服务[{1}]镜像NIC[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:122 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:109 # args: msg.getSrcEndPoint() -The\ PortMirror\ service\ doesn't\ support\ to\ mirror\ the\ nic[%s] = +The\ PortMirror\ service\ doesn't\ support\ to\ mirror\ the\ nic[%s] = PortMirror服务不支持镜像网卡[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:127 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:114 # args: msg.getDstEndPoint() -The\ PortMirror\ service\ doesn't\ support\ the\ nic[%s]\ because\ of\ its\ hypervisor\ type = +The\ PortMirror\ service\ doesn't\ support\ the\ nic[%s]\ because\ of\ its\ hypervisor\ type = 由于其云主机监控程序类型,PortMirror服务不支持NIC[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:134 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:121 # args: msg.getDstEndPoint() -The\ PortMirror\ service\ can't\ mirror\ to\ the\ nic[%s]\ that\ is\ not\ a\ non-default\ interface\ of\ a\ vm = +The\ PortMirror\ service\ can't\ mirror\ to\ the\ nic[%s]\ that\ is\ not\ a\ non-default\ interface\ of\ a\ vm = PortMirror服务无法镜像到不是VM的非默认接口的NIC[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:141 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:128 # args: msg.getSrcEndPoint() -The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ that\ is\ not\ an\ interface\ of\ any\ vm = +The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ that\ is\ not\ an\ interface\ of\ any\ vm = PortMirror服务无法镜像不是任何VM接口的NIC[{0}] -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:151 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:138 # args: msg.getSrcEndPoint(),msg.getDstEndPoint(),vo.getMirrorNetworkUuid() -The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ \ to\ nic[%s]\ because\ the\ mirror\ network[%s]\ can't\ setup\ the\ mirror\ tunnel = +The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ \ to\ nic[%s]\ because\ the\ mirror\ network[%s]\ can't\ setup\ the\ mirror\ tunnel = PortMirror服务无法将NIC[{0}]镜像到NIC[{1}],因为镜像网络[{2}]无法设置镜像隧道 -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:157 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:144 # args: msg.getSrcEndPoint() -The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ to\ itself = +The\ PortMirror\ service\ can't\ mirror\ the\ nic[%s]\ to\ itself = PortMirror服务无法将NIC[{0}]镜像到其自身 -# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:163 +# at: src/main/java/org/zstack/portMirror/PortMirrorApiInterceptor.java:153 # args: -The\ PortMirror\ service\ can't\ work\ at\ the\ nic\ with\ configured\ Qos = +The\ PortMirror\ service\ can't\ work\ at\ the\ nic\ with\ configured\ Qos = PortMirror服务无法在配置了QoS的NIC上工作 -# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:750 +# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:761 # args: sessionVO.getUuid(),errorCode.getDetails() -failed\ to\ delete\ portMirror\ session[%s]\ from\ hypervisor,\ detail\:\ %s = +failed\ to\ delete\ portMirror\ session[%s]\ from\ hypervisor,\ detail\:\ %s = 无法从云主机监控程序中删除PortMirror会话[{0}],详细信息:{1} -# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:783 +# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:794 # args: sessionVO.getUuid(),errorCode.getDetails() -failed\ to\ release\ portMirror\ session[%s]\ from\ hypervisor,\ detail\:\ %s = +failed\ to\ release\ portMirror\ session[%s]\ from\ hypervisor,\ detail\:\ %s = 无法从云主机监控程序释放PortMirror会话[{0}],详细信息:{1} -# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:901 +# at: src/main/java/org/zstack/portMirror/PortMirrorManagerImpl.java:912 # args: vo.getUuid() -cannot\ find\ internal\ id\ of\ the\ session[uuid\:%s],\ are\ there\ too\ many\ sessions\ in\ a\ host??? = +cannot\ find\ internal\ id\ of\ the\ session[uuid\:%s],\ are\ there\ too\ many\ sessions\ in\ a\ host??? = 找不到会话[uuid:{0}]的内部ID,物理机中是否有太多会话?? -# at: src/main/java/org/zstack/portal/apimediator/ApiMediatorImpl.java:246 +# at: src/main/java/org/zstack/portal/apimediator/ApiMediatorImpl.java:276 # args: cmsg.getResourceUuid() -resourceUuid[%s]\ is\ not\ a\ valid\ uuid.\ A\ valid\ uuid\ is\ a\ UUID(v4\ recommended)\ with\ '-'\ stripped.\ see\ http\://en.wikipedia.org/wiki/Universally_unique_identifier\ for\ format\ of\ UUID,\ the\ regular\ expression\ ZStack\ uses\ to\ validate\ a\ UUID\ is\ '[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}' = 资源UUID()不是一个有效的uuid。一个有效的UUID是一个没有-的UUID(建议为UUIDv4).格式参见http://en.wikipedia.org/wiki/Universally_unique_identifier,ZStack中验证一个UUID的正则表达式为: [0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12} +resourceUuid[%s]\ is\ not\ a\ valid\ uuid.\ A\ valid\ uuid\ is\ a\ uuid(v4\ recommended)\ with\ '-'\ stripped.\ see\ http\://en.wikipedia.org/wiki/Universally_unique_identifier\ for\ format\ of\ uuid,\ the\ regular\ expression\ uses\ to\ validate\ a\ uuid\ is\ '[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}' = Resourceuuid[{0}]不是有效的uuid。有效的uuid是去除了“-”的uuid(建议使用v4)。a.请参阅http://en.wikipediorg/wiki/Universally_unique_identifier for format of uuid,用于验证uuid的正则表达式是“[0-9a-f]{8}[0-9a-f]{4}[1-5][0-9A-f){3}[89ab][O-9A-F]{3}[O-9A-F]{12}” # at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java:122 # args: method -non\ support\ method\:\ %s = +non\ support\ method\:\ %s = 不支持方法:{0} -# at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java:135 +# at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaAPI.java:134 # args: statusCode,response.getStatusLine().getReasonPhrase() -http\ request\ error!\ status_code\:\ %s,\ error\:\ %s = +http\ request\ error!\ status_code\:\ %s,\ error\:\ %s = HTTP请求错误!状态_代码:{0},错误:{1} # at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaDB.java:24 # args: r.getStderr() -sqlite3\ execute\ failed,\ because\:\ %s = +sqlite3\ execute\ failed,\ because\:\ %s = SQLite3执行失败,因为:{0} # at: src/main/java/org/zstack/premium/externalservice/grafana/api/GrafanaDashboard.java:34 # args: GrafanaDB.folderTitle -cannot\ find\ folder\:\ %s\ in\ dashboard = +cannot\ find\ folder\:\ %s\ in\ dashboard = 在仪表板中找不到文件夹:{0} # at: src/main/java/org/zstack/premium/externalservice/loki/LokiFactory.java:84 # args: src.getAbsolutePath(),dst.getAbsolutePath(),rst.getStderr() -cannot\ copy\ %s\ to\ %s,\ caused\:\ %s = +cannot\ copy\ %s\ to\ %s,\ caused\:\ %s = 无法将{0}复制到{1},原因:{2} # at: src/main/java/org/zstack/premium/externalservice/loki/PromtailFactory.java:103 # args: -ssh\ failed = +ssh\ failed = SSH失败 -# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:106 +# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:124 # args: v.getClass().getSimpleName(),k -unknown\ value\ type\ %s,\ key\ \=\ %s = +unknown\ value\ type\ %s,\ key\ \=\ %s = 未知的值类型{0},键={1} -# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:132 +# at: src/main/java/org/zstack/premium/externalservice/prometheus/MultiNodePrometheus.java:153 # args: -failed\ to\ HTTP\ call\ all\ prometheus\ instances = +failed\ to\ HTTP\ call\ all\ prometheus\ instances = 无法对所有Prometheus实例进行HTTP调用 # at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminAPIRequestChecker.java:48 # args: rbacEntity.getApiMessage().getSession().getUserUuid() @@ -5940,49 +9872,49 @@ the\ operation\ is\ denied\ by\ black\ list\ of\ virtual-id[uuid\:%s] = 无法 # at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:199 # args: unmatchedApis,identity.toString() -action\:\ %s,\ is\ not\ supported\ for\ role\ identity\:\ %s = +action\:\ %s,\ is\ not\ supported\ for\ role\ identity\:\ %s = 角色标识{1}不支持操作{0} -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:341 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:372 # args: msg.getName() -%s\ is\ a\ reserved\ name,\ please\ use\ another\ name = +%s\ is\ a\ reserved\ name,\ please\ use\ another\ name = {0}是保留名称,请使用其他名称 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:339 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:370 # args: -the\ name\ of\ initial\ user\ can\ not\ be\ updated = +the\ name\ of\ initial\ user\ can\ not\ be\ updated = 无法更新初始用户的名称 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:376 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:407 # args: -cannot\ remove\ builtin\ system\ admin\ role\ from\ builtin\ system\ admin. = +cannot\ remove\ builtin\ system\ admin\ role\ from\ builtin\ system\ admin. = 无法从内置系统管理员中删除内置系统管理员角色。 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:374 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:405 # args: -cannot\ remove\ builtin\ security\ admin\ role\ from\ builtin\ security\ admin. = +cannot\ remove\ builtin\ security\ admin\ role\ from\ builtin\ security\ admin. = 无法从内置安全管理员中删除内置安全管理员角色。 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:372 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:403 # args: -cannot\ remove\ builtin\ audit\ admin\ role\ from\ builtin\ audit\ admin. = +cannot\ remove\ builtin\ audit\ admin\ role\ from\ builtin\ audit\ admin. = 无法从内置审核管理员中删除内置审核管理员角色。 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:386 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:417 # args: -cannot\ delete\ builtin\ system\ admin. = +cannot\ delete\ builtin\ system\ admin. = 无法删除内置系统管理员。 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:384 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:415 # args: -cannot\ delete\ builtin\ security\ admin. = +cannot\ delete\ builtin\ security\ admin. = 无法删除内置安全管理员。 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:382 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:413 # args: -cannot\ delete\ builtin\ audit\ admin. = +cannot\ delete\ builtin\ audit\ admin. = 无法删除内置审核管理员。 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:399 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:430 # args: -Confirm\ the\ roles\ you\ want\ to\ add\ have\ same\ identity = +Confirm\ the\ roles\ you\ want\ to\ add\ have\ same\ identity = 确认要添加的角色具有相同的身份 -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:413 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:444 # args: msg.getRoleUuids(),identitySet,msg.getVirtualIDUuid() -Cannot\ add\ role\:\ %s\ with\ identity\:\ %s\ to\ virtualID[uuid\:%s] = +Cannot\ add\ role\:\ %s\ with\ identity\:\ %s\ to\ virtualID[uuid\:%s] = 无法将标识为{1}的角色{0}添加到VirtualID[uuid:{2}] -# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:425 +# at: src/main/java/org/zstack/privilege/admin/IAM2PrivilegeAdminPolicyHelper.java:456 # args: String.join(",", privilegeAdminUuids),msg.getProjectUuid() can\ not\ add\ privilege\ admin[uuids\:%s]\ to\ project[uuid\:%s] = 无法将特殊管理员用户[uuids:{0}]加入到项目中去 @@ -6002,29 +9934,37 @@ entity\ meta\ class[%s]\ has\ no\ field[%s] = 实体元类[{0}]中没有值[{1}] # args: f,info.inventoryClass.getSimpleName(),info.premitiveFieldNames field[%s]\ is\ not\ a\ primitive\ of\ the\ inventory\ %s;\ you\ cannot\ specify\ it\ in\ the\ parameter\ 'fields';valid\ fields\ are\ %s = 值[{0}]不是清单{1}的原语;你不能在参数'域'中指定该参数;非法的域{2} -# at: src/main/java/org/zstack/query/QueryFacadeImpl.java:496 +# at: src/main/java/org/zstack/query/QueryFacadeImpl.java:519 +# args: +filterName\ must\ be\ formatted\ as\ [filterType\:condition(s)] = FilterName的格式必须为[filterType:条件] + +# at: src/main/java/org/zstack/query/QueryFacadeImpl.java:659 # args: JSONObjectUtil.toJsonString(cond) 'value'\ of\ query\ condition\ %s\ cannot\ be\ null = 查询条件中{0}的'值'不能为空 -# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:326 +# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:273 +# args: typeByResourceUuids.toString() +resources\ has\ inconsistent\ resourceTypes.\ Details\:\ %s = 资源具有不一致的资源类型。详细信息:{0} + +# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:433 # args: resourceUuid -cannot\ find\ resource[uuid\:\ %s] = +cannot\ find\ resource[uuid\:\ %s] = 找不到资源[uuid:{0}] -# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:330 +# at: src/main/java/org/zstack/resourceconfig/ResourceConfig.java:437 # args: globalConfig.getCategory(),globalConfig.getName(),resourceType -ResourceConfig\ [category\:%s,\ name\:%s]\ cannot\ bind\ to\ resourceType\:\ %s = +ResourceConfig\ [category\:%s,\ name\:%s]\ cannot\ bind\ to\ resourceType\:\ %s = ResourceConfig[类别:{0},名称:{1}]无法绑定到资源类型:{2} -# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:60 -# args: msg.getResourceUuid() -account\ has\ no\ access\ to\ the\ resource[uuid\:\ %s] = 账号没有访问资源[uuid:{0}]的权限 +# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:85 +# args: msg.getCategory(),identity +no\ global\ config[category\:%s,\ name\:%s]\ found = 找不到全局配置[类别:{0},名称:{1}] -# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:43 -# args: msg.getCategory(),msg.getName() -no\ global\ config[category\:%s,\ name\:%s]\ found = +# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:91 +# args: msg.getCategory(),identity +global\ config[category\:%s,\ name\:%s]\ cannot\ bind\ resource = 全局配置[类别:{0},名称:{1}]无法绑定资源 -# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:49 -# args: msg.getCategory(),msg.getName() -global\ config[category\:%s,\ name\:%s]\ cannot\ bind\ resource = +# at: src/main/java/org/zstack/resourceconfig/ResourceConfigApiInterceptor.java:114 +# args: msg.getResourceUuid() +account\ has\ no\ access\ to\ the\ resource[uuid\:\ %s] = 账号没有访问资源[uuid:{0}]的权限 # at: src/main/java/org/zstack/rest/TypeVerifier.java:22 # args: f.getName(),source @@ -6034,347 +9974,395 @@ global\ config[category\:%s,\ name\:%s]\ cannot\ bind\ resource = # args: f.getName(),source Invalid\ value\ for\ boolean\ field\ [%s],\ [%s]\ is\ not\ a\ valid\ boolean\ string[true,\ false]. = boolean属性字段[{0}]无效,[{1}]不是一个有效的boolean字符串[true, false] +# at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:141 +# args: msg.getvRouterUuid() +All\ the\ networks\ should\ be\ in\ the\ virtual\ router[%s] = 所有网络都应位于虚拟路由器[{0}]中 + # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:69 # args: msg.getAreaId() -[%s]\ is\ not\ formatted\ as\ IPv4\ address = +[%s]\ is\ not\ formatted\ as\ IPv4\ address = [{0}]的格式不是IPv4地址 # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:108 # args: msg.getAreaAuth() -KeyID\ &\ password\ must\ be\ not\ null\ when\ authentication\ type\ is\ %s = +KeyID\ &\ password\ must\ be\ not\ null\ when\ authentication\ type\ is\ %s = 当身份验证类型为{0}时,密钥ID和密码不能为Null # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:114 # args: msg.getAreaAuth() -password\ must\ be\ not\ null\ when\ authentication\ type\ is\ %s = +password\ must\ be\ not\ null\ when\ authentication\ type\ is\ %s = 当身份验证类型为{0}时,密码不能为null # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:118 # args: msg.getAreaAuth() -the\ length\ of\ password\ is\ at\ most\ than\ 8Bytes\ when\ authentication\ type\ is\ %s = +the\ length\ of\ password\ is\ at\ most\ than\ 8Bytes\ when\ authentication\ type\ is\ %s = 当身份验证类型为{0}时,密码长度不超过8个字节 # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:127 # args: vo.getAreaId(),RouterAreaType.Standard.toString() -AreaId[%s]\ type\ must\ be\ %s = +AreaId[%s]\ type\ must\ be\ %s = AreaID[{0}]类型必须为{1} # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:97 # args: msg.getAreaId() -AreaId[%s]\ has\ been\ created = +AreaId[%s]\ has\ been\ created = 已创建Area ID[{0}] # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:158 # args: vo.getL3NetworkUuid(),haUuid -The\ network[%s]\ have\ been\ added\ into\ the\ haGroup[%s] = +The\ network[%s]\ have\ been\ added\ into\ the\ haGroup[%s] = 网络[{0}]已添加到HAG组[{1}] # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:150 # args: vo.getL3NetworkUuid(),vo.getRouterAreaUuid() -The\ network[%s]\ have\ been\ added\ into\ the\ virtual\ routerArea[%s] = +The\ network[%s]\ have\ been\ added\ into\ the\ virtual\ routerArea[%s] = 网络[{0}]已添加到虚拟路由器区域[{1}] # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:181 # args: msg.getRouterId() -Router\ ID[%s]\ is\ not\ formatted\ as\ IPv4\ address = +Router\ ID[%s]\ is\ not\ formatted\ as\ IPv4\ address = 路由器ID[{0}]的格式不是IPv4地址 # at: src/main/java/org/zstack/routeProtocol/RouteProtocolApiInterceptor.java:193 # args: msg.getRouterId() -Router\ ID[%s]\ is\ not\ unique\ in\ this\ system = +Router\ ID[%s]\ is\ not\ unique\ in\ this\ system = 路由器ID[{0}]在此系统中不唯一 + +# at: src/main/java/org/zstack/scheduler/AbstractSchedulerJob.java:235 +# args: +the\ last\ job\ is\ not\ completed.\ skip\ this\ job = 上一个作业未完成。跳过这份工作 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:188 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:189 # args: cron\ must\ be\ set\ when\ use\ cron\ scheduler = 当使用定时器任务时,必须设置cron -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:194 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:195 # args: cron\ task\ must\ follow\ format\ like\ this\ \:\ \"0\ 0/3\ 17-23\ *\ *\ ?\"\ = 定时器任务必须符合以下格式: \"0 0/3 17-23 * * ?\" -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:197 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:198 # args: cron\ scheduler\ only\ need\ to\ specify\ cron\ task = 定时调度器(Cron Scheduler)仅需要指定定时任务(Cron Task) -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:206 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:207 # args: startTime\ out\ of\ range = 开始时间超出范围 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:202 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:203 # args: startTime\ must\ be\ positive\ integer\ or\ 0 = 开始时间必须是正整数或者0 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:183 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:184 # args: stopTime\ has\ been\ passed = 截止时间已经过去了 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:181 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:182 # args: stopTime\ out\ of\ mysql\ timestamp\ range = 定时任务停止时间超出mysql的timestamp的范围 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:179 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:180 # args: duration\ time\ out\ of\ range = 任务需要的时间超出范围 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:98 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:99 # args: interval\ must\ be\ set\ when\ use\ simple\ scheduler\ when\ repeat\ more\ than\ once = 当简单定时任务执行超过一次时,必须设置间隔时间 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:133 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:134 # args: msg.getSchedulerJobUuid(),msg.getSchedulerTriggerUuid() Can\ not\ add\ job[uuid\:%s]\ twice\ to\ the\ same\ trigger[uuid\:%s] = 不能两次添加任务[uuid:{0}]到相同的触发器[uuid:{1}] -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:138 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:139 # args: msg.getSchedulerJobUuid(),msg.getSchedulerTriggerUuid() Can\ not\ add\ job[uuid\:%s]\ to\ a\ out\ of\ time\ trigger[uuid\:%s] = 不能添加任务[uuid:{0}]到一个已经过时的触发器[uuid:{1}] -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:146 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:147 # args: count,msg.getSchedulerJobUuid() -There\ are\ [%d]\ triggers\ added\ to\ job[uuid\:%s],\ cannot\ add\ any\ more. = +There\ are\ [%d]\ triggers\ added\ to\ job[uuid\:%s],\ cannot\ add\ any\ more. = 有[{0}]个触发器已添加到作业[uuid:{1}],无法再添加更多触发器。 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:161 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:162 # args: count,msg.getSchedulerJobGroupUuid() -There\ are\ [%d]\ triggers\ added\ to\ job\ group[uuid\:%s],\ cannot\ add\ any\ more. = +There\ are\ [%d]\ triggers\ added\ to\ job\ group[uuid\:%s],\ cannot\ add\ any\ more. = 有[{0}]个触发器已添加到作业组[uuid:{1}],无法添加更多触发器。 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:191 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:192 # args: invalid\ cron\ expression = 无效的cron表达式 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:171 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:172 # args: startTime\ must\ be\ set\ for\ simple\ scheduler = simple类型的定时任务必须设置开始时间[startTime] -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:175 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:176 # args: schedulerInterval\ must\ be\ set\ for\ simple\ scheduler = simple类型的定时任务必须设置执行间隔[schedulerInterval] -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:239 -# args: msg.getParameters().get(SchedulerJobParameters.snapshotMax),e.getMessage() -snapshotMaxNumber\ \:\ %s\ format\ error\ because\ %s = snapshotMaxNumber : {0} 转换类型失败,因为{1} +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:226 +# args: msg.getType() +No\ SchedulerJobFactory\ of\ type[%s]\ found = 未找到类型为[{0}]的SchedulerJobFactory -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:265 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:253 # args: n -%d\ jobs\ have\ different\ job\ type\ with\ job\ group = +%d\ jobs\ have\ different\ job\ type\ with\ job\ group = {0}个作业的作业类型与作业组不同 -# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:274 +# at: src/main/java/org/zstack/scheduler/SchedulerApiInterceptor.java:262 # args: count,limit - count -job\ group\ has\ contained\ %d\ job,\ only\ %d\ seats\ left = +job\ group\ has\ contained\ %d\ job,\ only\ %d\ seats\ left = 作业组已包含{0}个作业,只剩下{1}个席位 -# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:500 -# args: jobUuid,e.getMessage() -trigger\ job[uuid\:\ %s]\ failed,\ because\ %s = +# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:794 +# args: timeUnitInStr +invalid\ time\ unit\:\ %s = 无效时间单位:{0} -# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:613 -# args: jobUuid,jobGroupUuid -Scheduler\ job[uuid\:%s]\ already\ in\ group[uuid\:\ %s] = +# at: src/main/java/org/zstack/scheduler/SchedulerFacadeImpl.java:921 +# args: jobUuid,e.getMessage() +trigger\ job[uuid\:\ %s]\ failed,\ because\ %s = 触发器作业[uuid:{0}]失败,原因是{1} # at: src/main/java/org/zstack/scheduler/SchedulerJobParamCascadeUpdater.java:86 # args: field.getName() -field[%s]\ cannot\ be\ empty = +field[%s]\ cannot\ be\ empty = 字段[{0}]不能为空 + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:54 +# args: msg.getTargetResourceUuid() +the\ volume[%s]\ is\ not\ available.\ check\ if\ the\ volume\ exists. = 卷[{0}]不可用。检查卷是否存在。 + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:58 +# args: msg.getTargetResourceUuid() +the\ volume[%s]\ is\ not\ root\ volume = 卷[{0}]不是根卷 + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:63 +# args: msg.getTargetResourceUuid() +the\ vm\ of\ the\ root\ volume[%s]\ is\ not\ available.\ check\ if\ the\ vm\ exists. = 根卷[{0}]的VM不可用。检查云主机是否存在。 + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:70 +# args: +The\ primary\ storage\ of\ volumes\ don\ not\ support\ create\ volume\ snapshot\ group\ job. = 卷的主存储不支持创建卷快照组作业。 + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotGroupJobFactory.java:77 +# args: msg.getParameters().get(SchedulerJobParameters.snapshotGroupMax),e.getMessage() +snapshotGroupMaxNumber\ \:\ %s\ format\ error\ because\ %s = SnapshotGroupMaxNumber:{0}格式错误,原因是{1} + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotJobFactory.java:58 +# args: msg.getTargetResourceUuid() +the\ volume[%s]\ does\ not\ support\ snapshots\ retention = 卷[{0}]不支持快照保留 + +# at: src/main/java/org/zstack/scheduler/VolumeSnapshotJobFactory.java:70 +# args: msg.getParameters().get(SchedulerJobParameters.snapshotMax),e.getMessage() +snapshotMaxNumber\ \:\ %s\ format\ error\ because\ %s = snapshotMaxNumber : {0} 转换类型失败,因为{1} + +# at: src/main/java/org/zstack/scheduler/snapshot/CreateVolumeSnapshotGroupJob.java:125 +# args: getTargetResourceUuid() +the\ vm\ of\ the\ root\ volume[%s]\ state\ in\ Destroyed.\ job\ state\ change\ is\ not\ allowed = 根卷[{0}]的VM处于已销毁状态。不允许更改作业状态 + +# at: src/main/java/org/zstack/scheduler/snapshot/CreateVolumeSnapshotGroupJob.java:189 +# args: +The\ primary\ storage\ of\ volumes\ don\ not\ support\ create\ volume\ snapshot\ group\ job = 卷的主存储不支持创建卷快照组作业 -# at: src/main/java/org/zstack/scheduler/vm/StopVmInstanceJob.java:78 +# at: src/main/java/org/zstack/scheduler/vm/StopVmInstanceJob.java:83 # args: getTargetResourceUuid() -vm[uuid\:%s]\ is\ destroyed,\ state\ change\ is\ not\ allowed = +vm[uuid\:%s]\ is\ destroyed,\ state\ change\ is\ not\ allowed = VM[uuid:{0}]已销毁,不允许更改状态 -# at: src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:92 +# at: src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:75 # args: msg.getVendorType(),SdnControllerType.getAllTypeNames() -Sdn\ controller\ type\:\ %s\ in\ not\ in\ the\ supported\ list\:\ %s\ = +Sdn\ controller\ type\:\ %s\ in\ not\ in\ the\ supported\ list\:\ %s\ = SDN控制器类型:{0}不在支持的列表中:{1} -# at: src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java:97 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:102 +# args: msg.getL2NetworkUuid() +unable\ create\ vni\ range,\ because\ l2\ uuid[%s]\ is\ not\ vxlan\ network\ pool = 无法创建VNI范围,因为L2 uuid[{0}]不是VXLAN网络池 + +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:117 +# args: msg.getStartVni(),msg.getEndVni() +the\ vni\ range\:[%s.%s}\ is\ illegal,\ because\ h3c's\ controller\ uses\ vni\ as\ vlan\ id = VNI范围[{0}.{1}}非法,因为H3C的控制器使用VNI作为VLAN ID + +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:132 +# args: userVniRange.startVni,userVniRange.endVni +the\ vni\ range\:[%s.%s}\ is\ illegal,\ must\ covered\ by\ a\ sdn's\ vniRange = VNI范围[{0}.{1}}非法,必须由SDN的VNI范围覆盖 + +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java:178 # args: -H3C\ VCFC\ controller\ must\ include\ systemTags\ vdsUuid\:\:{%s} = +H3C\ VCFC\ controller\ must\ include\ systemTags\ vdsUuid\:\:{%s} = H3C VCFC控制器必须包含系统标签VDSuuid::'{{0}'} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:117 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:116 # args: self.getIp(),e.getLocalizedMessage() -get\ sdn\ controller\ [ip\:%s]\ vni\ range\ failed\ because\ %s = +get\ sdn\ controller\ [ip\:%s]\ vni\ range\ failed\ because\ %s = 获取SDN控制器[IP:{0}]VNI范围失败,原因是{1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:87 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:86 # args: self.getIp() -get\ vni\ range\ on\ sdn\ controller\ [ip\:%s]\ failed = +get\ vni\ range\ on\ sdn\ controller\ [ip\:%s]\ failed = 在SDN控制器[IP:{0}]上获取VNI范围失败 -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:149 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:148 # args: self.getIp() -there\ is\ no\ vni\ range\ on\ sdn\ controller\ [ip\:%s] = +there\ is\ no\ vni\ range\ on\ sdn\ controller\ [ip\:%s] = SDN控制器[IP:{0}]上没有VNI范围 -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:155 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:154 # args: self.getIp() -there\ is\ no\ default\ tenant\ on\ sdn\ controller\ [ip\:%s] = +there\ is\ no\ default\ tenant\ on\ sdn\ controller\ [ip\:%s] = SDN控制器[IP:{0}]上没有默认租户 -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:275 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:299 # args: self.getIp(),e.getMessage() -create\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = +create\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = 在SDN控制器[IP:{0}]上创建VXLAN网络失败,原因是{1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:259 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:283 # args: self.getIp() -create\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed = +create\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed = 在SDN控制器[IP:{0}]上创建VXLAN网络失败 -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:321 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:383 # args: self.getIp(),e.getMessage() -delete\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = +delete\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = 删除SDN控制器[IP:{0}]上的VXLAN网络失败,原因是{1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:315 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:377 # args: self.getIp() -delete\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed = +delete\ vxlan\ network\ on\ sdn\ controller\ [ip\:%s]\ failed = 删除SDN控制器[IP:{0}]上的VXLAN网络失败 -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:381 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:468 # args: self.getIp(),e.getMessage() -get\ token\ of\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = +get\ token\ of\ sdn\ controller\ [ip\:%s]\ failed\ because\ %s = 获取SDN控制器[IP:{0}]的令牌失败,原因是{1} -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:352 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:439 # args: self.getIp() -get\ leader\ of\ sdn\ controller\ [ip\:%s]\ failed = +get\ leader\ of\ sdn\ controller\ [ip\:%s]\ failed = 获取SDN控制器[IP:{0}]的领导者失败 -# at: src/main/java/org/zstack/sdnController/h3c/H3cSdnController.java:373 +# at: src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java:460 # args: self.getIp() -get\ token\ of\ sdn\ controller\ [ip\:%s]\ failed = +get\ token\ of\ sdn\ controller\ [ip\:%s]\ failed = 获取SDN控制器[IP:{0}]的令牌失败 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java:72 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java:51 # args: vo.getPoolUuid() -there\ is\ no\ sdn\ controller\ for\ vxlan\ pool\ [uuid\:%s] = +there\ is\ no\ sdn\ controller\ for\ vxlan\ pool\ [uuid\:%s] = VXLAN池[uuid:{0}]没有SDN控制器 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java:259 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java:410 # args: inv.getUuid(),destHostUuid -cannot\ configure\ hardware\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = +cannot\ configure\ hardware\ vxlan\ network\ for\ vm[uuid\:%s]\ on\ the\ destination\ host[uuid\:%s] = 无法为目标物理机[uuid:{1}]上的VM[uuid:{0}]配置硬件VXLAN网络 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:103 -# args: overlappedPool -overlap\ vni\ range\ with\ vxlan\ network\ pool\ [%s] = +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:150 +# args: msg.getPhysicalInterface() +cannot\ create\ vlan-device\ on\ %s\ because\ it's\ too\ long = 无法在{0}上创建VLAN设备,因为它太长 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:110 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:112 # args: -hareware\ vxlan\ network\ pool\ doesn't\ support\ create\ l3\ network = +hardware\ vxlan\ network\ pool\ doesn't\ support\ create\ l3\ network = 硬件VXLAN网络池不支持创建三层网络 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:116 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:118 # args: -hareware\ vxlan\ network\ pool\ must\ configure\ the\ physical\ interface = +hardware\ vxlan\ network\ pool\ must\ configure\ the\ physical\ interface = 硬件VXLAN网络池必须配置物理接口 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:124 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:126 # args: -ONLY\ hareware\ vxlan\ network\ can\ be\ created\ in\ hareware\ vxlan\ pool = +ONLY\ hardware\ vxlan\ network\ can\ be\ created\ in\ hardware\ vxlan\ pool = 在硬件VXLAN池中只能创建硬件VXLAN网络 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:129 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java:131 # args: -hareware\ vxlan\ network\ can\ ONLY\ be\ created\ in\ hareware\ vxlan\ pool = +hardware\ vxlan\ network\ can\ ONLY\ be\ created\ in\ hardware\ vxlan\ pool = 硬件VXLAN网络只能在硬件VXLAN池中创建 -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:75 -# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),vlanId,hostUuid,rsp.getError() -failed\ to\ create\ bridge[%s]\ for\ hardwareVxlan[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:86 +# args: cmd.getBridgeName(),l2Network.getUuid(),l2Network.getType(),finalVlanId,hostUuid,rsp.getError() +failed\ to\ create\ bridge[%s]\ for\ hardwareVxlan[uuid\:%s,\ type\:%s,\ vlan\:%s]\ on\ kvm\ host[uuid\:%s],\ because\ %s = 无法在KVM物理机[uuid:{4}]上为HardwareVXLAN[uuid:{1},类型:{2},VLAN:{3}]创建网桥[{0}],因为{5} -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:129 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java:144 # args: cmd.getBridgeName(),vxlan.getUuid(),vxlan.getName(),hostUuid,rsp.getError() -failed\ to\ check\ bridge[%s]\ for\ hardwareVxlan[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = +failed\ to\ check\ bridge[%s]\ for\ hardwareVxlan[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:%s],\ %s = 无法在KVM物理机[uuid:{3}]上检查硬件VXLAN[uuid:{1},名称:{2}]的网桥[{0}],{4} -# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java:61 +# at: src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java:64 # args: l2Network.getUuid(),l2Network.getName(),hostUuid,rsp.getError() -failed\ to\ check\ physical\ interface\ for\ HardwareVxlanPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = +failed\ to\ check\ physical\ interface\ for\ HardwareVxlanPool[uuid\:%s,\ name\:%s]\ on\ kvm\ host[uuid\:\ %s],\ %s = 无法检查KVM物理机[uuid:{2}]上的硬件vxlanpool[uuid:{0},名称:{1}]的物理接口,{3} # at: src/main/java/org/zstack/simulator/SimulatorHost.java:92 # args: -set\ to\ disconnected = +set\ to\ disconnected = 设置为断开连接 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:60 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:97 +# args: number +invalid\ phone\ number[%s],\ sms\ number\ is\ like\ +86-18654321234 = 电话号码[{0}]无效,短信号码类似于+86-18654321234 + +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:64 # args: msg.getApplicationEndpointUuid() -can\ not\ add\ same\ email\ address\ to\ endpoint[uuid\:%s] = +can\ not\ add\ same\ email\ address\ to\ endpoint[uuid\:%s] = 无法将同一电子邮件地址添加到端点[uuid:{0}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:171 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:165 # args: errorEmails invalid\ email\ address[%s] = 无效的email地址[{0}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:73 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:77 # args: msg.getEmailAddress(),msg.getApplicationEndpointUuid() -cannot\ update\ email\ address\ to\ %s,\ which\ is\ already\ exists\ in\ endpoint[uuid\:%s] = +cannot\ update\ email\ address\ to\ %s,\ which\ is\ already\ exists\ in\ endpoint[uuid\:%s] = 无法将电子邮件地址更新为{0},该地址已存在于端点[uuid:{1}]中 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:87 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:91 # args: msg.getPhoneNumber() -phone\ number\ [%s]\ already\ exists = - -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:99 -# args: -password\ is\ not\ set\ while\ username\ is\ set = 设置了用户名但未设置密码 +phone\ number\ [%s]\ already\ exists = 电话号码[{0}]已存在 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:103 -# args: -username\ is\ not\ set\ while\ password\ is\ set = 设置了密码但未设置用户名 - -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:112 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:106 # args: msg.getPhoneNumber() phone\ number[%s]\ already\ exists = 手机号码[{0}]已存在 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:121 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:115 # args: url invalid\ url[%s] = 无效的url[{0}] -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:127 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:121 # args: host -[%s]\ is\ not\ a\ legal\ ip = +[%s]\ is\ not\ a\ legal\ ip = [{0}]不是合法的IP -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:133 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:127 # args: n invalid\ phone\ number[%s],\ the\ DingDing\ phone\ number\ is\ like\ +86-12388889999 = 无效的手机号码[{0}], 钉钉手机号码格式应当为 +86-12388889999 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:150 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:144 # args: username\ and\ password\ must\ either\ absent\ at\ all\ or\ present\ with\ each\ other = 用户名和密码要么同时为空要么同时不为空 -# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:158 +# at: src/main/java/org/zstack/sns/SNSApiInterceptor.java:152 # args: -can\ not\ create\ sns\ email\ endpoint\ without\ any\ email\ address = +can\ not\ create\ sns\ email\ endpoint\ without\ any\ email\ address = 无法在没有任何电子邮件地址的情况下创建SNS电子邮件端点 # at: src/main/java/org/zstack/sns/SNSApplicationPlatformBase.java:118 # args: the\ operation\ is\ not\ permitted\ for\ the\ system\ application\ platform = 禁止对该应用平台进行当前操作 -# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:75 +# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:67 # args: msg.getTopicUuid() cannot\ find\ the\ SNSTopic[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到SNS主题[uuid:{0}], 它可能已经被删除 -# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:93 +# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:85 # args: msg.getApplicationPlatformUuid() cannot\ find\ SNSApplicationPlatform[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到SNS应用平台[uuid:{0}], 它可能已经被删除 -# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:103 +# at: src/main/java/org/zstack/sns/SNSManagerImpl.java:95 # args: msg.getApplicationEndpointUuid() cannot\ find\ SNSApplicationEndpoint[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到SNS应用接收终端[uuid:{0}], 它可能已经被删除 -# at: src/main/java/org/zstack/sns/SNSTopicBase.java:125 +# at: src/main/java/org/zstack/sns/SNSTopicBase.java:128 # args: the\ topic\ is\ not\ subscribed\ by\ any\ endpoints = 当前主题并未被任何应用终端订阅 -# at: src/main/java/org/zstack/sns/SNSTopicBase.java:149 +# at: src/main/java/org/zstack/sns/SNSTopicBase.java:154 # args: application\ platform\ is\ disabled = 应用平台被不可用 -# at: src/main/java/org/zstack/sns/SNSTopicBase.java:201 +# at: src/main/java/org/zstack/sns/SNSTopicBase.java:224 # args: application\ endpoint\ is\ disabled = 应用接收端被禁用 -# at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java:34 -# args: number -invalid\ phone\ number[%s],\ sms\ number\ is\ like\ +86-18654321234 = - -# at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java:43 +# at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsApiInterceptor.java:44 # args: msg.getAccessKeyUuid() -Aliyun\ account[uuid\:%s]\ not\ exists = +Aliyun\ account[uuid\:%s]\ not\ exists = 阿里云账号[uuid:{0}]不存在 # at: src/main/java/org/zstack/sns/platform/aliyunsms/SNSAliyunSmsEndpoint.java:83 # args: SysErrors.RESOURCE_NOT_FOUND -Aliyun\ sms\ event\ text\ template\ not\ found. = +Aliyun\ sms\ event\ text\ template\ not\ found. = 未找到阿里云短信事件文本模板。 -# at: src/main/java/org/zstack/sns/platform/dingtalk/SNSDingTalkEndpoint.java:118 +# at: src/main/java/org/zstack/sns/platform/dingtalk/SNSDingTalkEndpoint.java:130 # args: rsp.getStatusCode(),rsp.getBody() -Sending\ message\ to\ DingTalk\ failure.\ status\:\ %s,\ body\:\ %s = 发送消息到DingTalk失败. status: {0}, body: {1} +failed\ to\ send\ messages\ to\ DingTalk.\ status\:\ %s,\ body\:\ %s = 向DingTalk发送消息失败。状态:{0},正文:{1} # at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:72 # args: getSelf().getSmtpServer(),getSelf().getSmtpPort() cannot\ connect\ SMTP\ server[server\:\ %s,\ port\:\ %s]\ in\ 15\ seconds = 在15秒内无法连接到SMTP服务器[server: {0}, port: {1}] -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:92 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:88 # args: e.getMessage() SMTP\ server\ validation\ error\:\ %s = SMTP服务器验证错误: {0} -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:134 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:130 # args: the\ endpoint\ is\ disabled = 通知终端不可用 -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:162 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailApplicationPlatform.java:158 # args: no\ subject = 没有主题 -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:59 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:66 # args: The\ problem\ may\ be\ caused\ by\ an\ incorrect\ user\ name\ or\ password\ or\ email\ permission\ denied = 导致操作失败的原因可能是不正确的用户名、密码或邮件访问权限不足 -# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:61 +# at: src/main/java/org/zstack/sns/platform/email/SNSEmailPlatformFactory.java:68 # args: smtpServer,smtpPort Couldn't\ connect\ to\ host,\ port\:\ %s,\ %d.\ The\ problem\ may\ be\ caused\ by\ an\ incorrect\ smtpServer\ or\ smtpPort = 连接{0}:{1}超时,导致原因可能是不正确的邮件服务器和邮件服务器端口 @@ -6382,6 +10370,10 @@ Couldn't\ connect\ to\ host,\ port\:\ %s,\ %d.\ The\ problem\ may\ be\ caused\ b # args: rsp.getStatusCode(),rsp.getBody() HTTP\ POST\ failure.\ status\:\ %s,\ body\:\ %s = HTTP POST失败,状态码: {0}, body: {1} +# at: src/main/java/org/zstack/sns/platform/microsoftteams/SNSMicrosoftTeamsEndpoint.java:69 +# args: rsp.getStatusCode(),rsp.getBody() +failed\ to\ send\ messages\ to\ Microsoft\ Teams.\ status\:\ %s,\ body\:\ %s = 未能将消息发送到Microsoft Teams。状态:{0},正文:{1} + # at: src/main/java/org/zstack/sns/system/SNSApiTopicManagerImpl.java:172 # args: endpoint.getType() only\ HTTP\ endpoint\ can\ subscribe\ API\ topic,\ the\ endpoint[type\:%s]\ is\ not\ a\ HTTP\ endpoint = 仅HTTP通知终端可以订阅API通知主题,当前通知终端[type:{0}]不是一个HTTP通知终端 @@ -6390,10 +10382,82 @@ only\ HTTP\ endpoint\ can\ subscribe\ API\ topic,\ the\ endpoint[type\:%s]\ is\ # args: API\ topic\ cannot\ be\ deleted = API通知主题无法被删除 -# at: src/main/java/org/zstack/sns/system/SNSSystemAlarmTopicManagerImpl.java:76 +# at: src/main/java/org/zstack/sns/system/SNSSystemAlarmTopicManagerImpl.java:78 # args: system\ alarm\ topic\ cannot\ be\ deleted = 系统警报通知主题不能被删除 +# at: src/main/java/org/zstack/sso/cas/filter/CasLoginFilter.java:53 +# args: +url\ is\ error,\ clientUuid\ is\ miss = URL错误,缺少Clientuuid + +# at: src/main/java/org/zstack/sso/cas/filter/CasLoginFilter.java:58 +# args: +\ missing\ cas\ client,\ please\ create\ cas\ client\ before\ sso = 缺少CAS客户端,请在SSO之前创建CAS客户端 + +# at: src/main/java/org/zstack/sso/cas/service/CasClientManagerImpl.java:62 +# args: login.getClass().getName(),old.getClass().getName(),login.getLoginType() +duplicate\ casLogin[%s,\ %s]\ for\ type[%s] = 类型[{2}]的CASLogin[{0},{1}]重复 + +# at: src/main/java/org/zstack/sso/cas/service/CasClientManagerImpl.java:73 +# args: type +Cannot\ find\ CasLogin\ for\ type(%s) = 找不到类型({0})的CASlogin + +# at: src/main/java/org/zstack/sso/cas/service/CasLoginIAM2.java:67 +# args: userName +iam2\ has\ a\ user\ with\ the\ same\ name[%s] = IAM2具有同名[{0}]的用户 + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM1.java:71 +# args: userName +\ local\ user\ has\ a\ user\ with\ the\ same\ name[%s] = 本地用户具有同名[{0}]的用户 + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java:57 +# args: ssoUseAsLoginName +fail\ to\ get\ params[%s] = 无法获取参数[{0}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java:61 +# args: +get\ user\ name\ is\ null = 获取用户名为空 + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2LoginIAM2.java:66 +# args: userName +\ iam2\ has\ a\ user\ with\ the\ same\ name[%s] = IAM2具有同名[{0}]的用户 + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:375 +# args: rsp.getStatusCode(),rsp.getBody() +HTTP\ ERROR,\ status\ code\:\ %s,\ body\:\ %s = HTTP错误,状态代码:{0},正文:{1} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:382 +# args: HttpMethod.POST,url,e.getStatusCode(),e.getResponseBodyAsString() +failed\ to\ %s\ to\ %s,\ status\ code\:\ %s,\ response\ body\:\ %s = 访问{1}时执行{0}方法失败,状态码: {2},响应体: {3} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:386 +# args: HttpMethod.POST,url,e.getMessage() +failed\ to\ %s\ to\ %s,\ IO\ Error\:\ %s = 访问{1}时执行{0}方法失败,IO错误: {2} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:201 +# args: e +response\ has\ error\ \:\ %s = 响应出现错误:{0} + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:101 +# args: login.getClass().getName(),old.getClass().getName(),login.getLoginType() +duplicate\ OAuth2Login[%s,\ %s]\ for\ type[%s] = 类型[{2}]的重复OAuth2Login[{0},{1}] + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:113 +# args: type +Cannot\ find\ OAuth2Login\ for\ type(%s) = 找不到类型({0})的OAuth2Login + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:190 +# args: +there\ was\ an\ error,\ reason\:\ \ token\ response\ is\ null = 出现错误,原因:令牌响应为空 + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:194 +# args: AuthGolabalProperty.OAUTH2_GET_TOKEN_USERINFO +there\ was\ an\ error,\ reason\:\ \ %s\ is\ null = 出现错误,原因:{0}为空 + +# at: src/main/java/org/zstack/sso/oauth2/service/OAuth2ManagerImpl.java:300 +# args: e +get\ code\ response\ has\ error\ \:\ %s = 获取代码响应出现错误:{0} + # at: src/main/java/org/zstack/storage/backup/BackupStorageApiInterceptor.java:65 # args: name %s\ should\ not\ be\ null = {0} 不能为空 @@ -6410,27 +10474,27 @@ backup\ storage[uuid\:%s]\ has\ not\ been\ attached\ to\ zone[uuid\:%s] = 镜像 # args: msg.getBackupStorageUuid(),msg.getZoneUuid() backup\ storage[uuid\:%s]\ has\ been\ attached\ to\ zone[uuid\:%s] = 镜像服务器[uuid:{0}]已经被加载到zone[uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:162 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:148 # args: url,e.toString() failed\ to\ get\ header\ of\ image\ url\ %s\:\ %s = 获取链接 {0} 的Header信息失败,原因:{1} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:166 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:152 # args: url failed\ to\ get\ header\ of\ image\ url\ %s = 获取链接 {0} 的Header信息失败 -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:176 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:175 # args: self.getUuid(),self.getName(),url,size,self.getAvailableCapacity() the\ backup\ storage[uuid\:%s,\ name\:%s]\ has\ not\ enough\ capacity\ to\ download\ the\ image[%s].Required\ size\:%s,\ available\ size\:%s = 镜像服务器[uuid:{0}, name:{1}]没有足够的容量可供下载镜像[{2}]。需要的大小: {3},可用的大小: {4} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:173 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:172 # args: url,size the\ image\ size\ get\ from\ url\ %s\ is\ %d\ bytes,\ it's\ too\ small\ for\ an\ image,\ please\ check\ the\ url\ again. = 从链接 {0} 获取到的镜像大小为{1}字节,对一个正常的镜像来说太小了,请检查该链接是否合法 -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:191 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:190 # args: msg.getClass().getName(),self.getStatus() backup\ storage\ cannot\ proceed\ message[%s]\ because\ its\ status\ is\ %s = 镜像服务器无法处理消息[{0}]因为它的状态为{1} -# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:197 +# at: src/main/java/org/zstack/storage/backup/BackupStorageBase.java:196 # args: msg.getClass().getName(),self.getState() backup\ storage\ cannot\ proceed\ message[%s]\ because\ its\ state\ is\ %s = 镜像服务器无法处理消息[{0}]因为它的状态为{1} @@ -6438,831 +10502,1243 @@ backup\ storage\ cannot\ proceed\ message[%s]\ because\ its\ state\ is\ %s = 镜 # args: size,backupStorageUuid,capacityVO.getAvailableCapacity() cannot\ reserve\ %s\ on\ the\ backup\ storage[uuid\:%s],\ it\ only\ has\ %s\ available = 无法在镜像服务器{1}保留{0},它仅有{2}可用容量 -# at: src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java:279 +# at: src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java:276 # args: capacity\ reservation\ on\ all\ backup\ storage\ failed = 在所有镜像服务器上保留容量失败 -# at: src/main/java/org/zstack/storage/backup/BackupStorageReservedCapacityAllocatorFlow.java:46 -# args: BackupStorageGlobalConfig.RESERVED_CAPACITY.value(),spec.getSize() -after\ subtracting\ reserved\ capacity[%s],\ no\ backup\ storage\ has\ required\ capacity[%s\ bytes] = 在减去保留容量[{0}],没有镜像服务器有容量[{1}] bytes +# at: src/main/java/org/zstack/storage/backup/BackupStorageManagerImpl.java:320 +# args: backupStorageDataNetworkTags.size() +only\ one\ backup\ storage\ data\ network\ system\ tag\ is\ allowed,\ but\ %s\ got = 只允许一个备份存储数据网络系统标记,但{0}已获得 + +# at: src/main/java/org/zstack/storage/backup/BackupStoragePrimaryStorageAllocatorFlow.java:46 +# args: spec.getRequiredPrimaryStorageUuid(),psTypeName +required\ primary\ storage[uuid\:%s,\ type\:%s]\ could\ not\ support\ any\ backup\ storage. = 所需的主存储[uuid:{0},类型:{1}]无法支持任何备份存储。 -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:284 +# at: src/main/java/org/zstack/storage/backup/BackupStorageReservedCapacityAllocatorFlow.java:55 +# args: spec.getSize() +after\ subtracting\ reserved\ capacity,\ no\ backup\ storage\ has\ required\ capacity[%s\ bytes] = 减去保留容量后,没有备份存储具有所需容量[{0}字节] + +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:328 # args: missing\ 'retentionType'\ in\ job\ parameters = parameters中缺少retentionType参数 -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:288 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:332 # args: missing\ 'retentionValue'\ in\ job\ parameters = parameter中缺少retentionValue参数 -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:292 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:336 # args: missing\ 'backupStorageUuids'\ in\ job\ parameters = parameter中缺少backupStorageUuids参数 -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:296 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:340 # args: job\ parameter\ 'backupStorageUuids'\ is\ empty = parameter中backupStorageUuids为空 -# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:301 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:345 # args: bsUuid unexpected\ backup\ storage\ uuid\:\ %s = 错误的镜像服务器uuid: {0} -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:484 -# args: getTargetResourceUuid() -volume[uuid\:%s]\ is\ deleted,\ state\ change\ is\ not\ allowed = +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:354 +# args: +missing\ 'remoteRetentionValue'\ in\ job\ parameters = 作业参数中缺少“ RemoteRetentionValue ” -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:114 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:352 # args: -bandWidth\ must\ be\ a\ positive\ number = +missing\ 'remoteRetentionType'\ in\ job\ parameters = 作业参数中缺少“ RemoteRetentionType ” -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:170 +# at: src/main/java/org/zstack/storage/backup/CreateDatabaseBackupJob.java:84 # args: -missing\ job\ parameters = 缺少parameters参数 +No\ available\ backup\ storage\ found,\ skip\ this\ job = 找不到可用的备份存储,请跳过此作业 + +# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:578 +# args: getTargetResourceUuid() +volume[uuid\:%s]\ is\ deleted,\ state\ change\ is\ not\ allowed = 卷[uuid:{0}]已删除,不允许更改状态 + +# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:137 +# args: +bandWidth\ must\ be\ a\ positive\ number = 带宽必须为正数 -# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:429 +# at: src/main/java/org/zstack/storage/backup/CreateVmBackupJob.java:217 # args: -No\ available\ backup\ storage\ found,\ skip\ this\ job = +missing\ job\ parameters = 缺少parameters参数 # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:93 # args: msg.getDatabaseBackupUuid(),msg.getBackupStorageUuid() -database\ backup[uuid%s]\ has\ not\ been\ exported\ from\ backupStorage[uuid\:%s] = +database\ backup[uuid%s]\ has\ not\ been\ exported\ from\ backupStorage[uuid\:%s] = 数据库备份[uuid{0}]尚未从备份存储[uuid:{1}]中导出 # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:107 # args: msg.getDatabaseBackupUuid(),msg.getBackupStorageUuid() -database\ backup[uuid%s]\ has\ been\ exported\ from\ backupStorage[uuid\:%s] = +database\ backup[uuid%s]\ has\ been\ exported\ from\ backupStorage[uuid\:%s] = 数据库备份[uuid{0}]已从备份存储[uuid:{1}]中导出 # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:120 # args: -do\ not\ allow\ cover\ database\ from\ backup = +do\ not\ allow\ cover\ database\ from\ backup = 不允许从备份中覆盖数据库 # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:124 # args: -installPath\ and\ bsUrl\ are\ both\ need = +installPath\ and\ bsUrl\ are\ both\ need = InstallPath和BSURL都是必需 # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:133 # args: -databaseBackup[uuid\:%s]\ is\ not\ Enabled\ and\ Ready = +databaseBackup[uuid\:%s]\ is\ not\ Enabled\ and\ Ready = DatabaseBackup[uuid:{0}]未启用且未就绪 # at: src/main/java/org/zstack/storage/backup/DatabaseBackupApiInterceptor.java:142 # args: url -illegal\ url[%s],\ correct\ example\ is\ ssh\://username\:password@hostname[\:sshPort]/path = - -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:467 -# args: -sync\ task\ failed. = 同步失败 - -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:474 -# args: reply.getStatus() -unexpected\ task\ status\:\ %s = 错误的任务状态{0} - -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:280 -# args: msg.getDstBackupStorageUuid(),msg.getSrcBackupStorageUuid(),BackupStorageState.Disabled.toString() -One\ of\ the\ backup\ storage[uuids\:\ %s,\ %s]\ is\ in\ the\ state\ of\ %s,\ can\ not\ do\ sync\ operation = 镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作 +illegal\ url[%s],\ correct\ example\ is\ ssh\://username\:password@hostname[\:sshPort]/path = 非法URL[{0}],正确示例为SSH://username:password@hostname[:sshport]/path # at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:80 # args: self.getUuid() -database\ backup[uuid\:%s]\ is\ not\ Enabled\ and\ Ready = +database\ backup[uuid\:%s]\ is\ not\ Enabled\ and\ Ready = 数据库备份[uuid:{0}]未启用且未就绪 -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:325 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupBase.java:328 # args: msg.getDatabaseBackupUuid(),msg.getSrcBackupStorageUuid() -database\ backup[uuid\:%s]\ not\ found\ in\ backup\ storage[uuid\:%s] = +database\ backup[uuid\:%s]\ not\ found\ in\ backup\ storage[uuid\:%s] = 未在备份存储[uuid:{1}]中找到数据库备份[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:90 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:91 # args: msg.getDatabaseBackupUuid() -database\ backup\ [uuid\:%s]\ is\ not\ existed\ yet = +database\ backup\ [uuid\:%s]\ is\ not\ existed\ yet = 数据库备份[uuid:{0}]尚不存在 -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:106 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:107 # args: -backup\ storage[uuid\:%s]\ is\ not\ enabled\ and\ connected = +backup\ storage[uuid\:%s]\ is\ not\ enabled\ and\ connected = 备份存储[uuid:{0}]未启用和连接 -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:600 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:603 # args: result.getStderr() -not\ pass\ the\ restore\ security\ check\:\n%s = +not\ pass\ the\ restore\ security\ check\:\n%s = 未通过还原安全检查:\n{0} -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:612 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:615 # args: -cannot\ get\ free\ port\ to\ listen = +cannot\ get\ free\ port\ to\ listen = 无法获取空闲端口以进行侦听 -# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:640 +# at: src/main/java/org/zstack/storage/backup/DatabaseBackupManagerImpl.java:643 # args: version,dbf.getDbVersion() -database\ backup\ version[%s]\ is\ not\ match\ currently\ version[%s] = +database\ backup\ version[%s]\ is\ not\ match\ currently\ version[%s] = 数据库备份版本[{0}]与当前版本[{1}]不匹配 -# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:25 +# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:26 # args: -cannot\ ssh\ peer\ node\ via\ sshkey,\ please\ check\ connection = - -# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:40 -# args: result.getStderr() -cannot\ get\ zsha2\ status,\ because\ %s = - -# at: src/main/java/org/zstack/storage/backup/MultiDatabaseRecoverChecker.java:45 -# args: result.getStderr() -cannot\ get\ zsha2\ config,\ because\ %s,\ maybe\ you\ need\ upgrade\ zsha2 = +cannot\ ssh\ peer\ node\ via\ sshkey,\ please\ check\ connection = 无法通过SSHKEY进行SSH对等节点,请检查连接 # at: src/main/java/org/zstack/storage/backup/SingleDatabaseRecoverChecker.java:19 # args: -please\ stop\ other\ node\ first! = +please\ stop\ other\ node\ first! = 请先停止其他节点! + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:355 +# args: +could\ not\ create\ vm,\ because\ at\ least\ one\ of\ field\ (l3NetworkUuids,zoneUuid,clusterUuid,hostUuid)\ should\ be\ set = 无法创建VM,因为至少应设置字段(l3NetworkUuids、zoneUuid、clusterUuid、hostUuid)中的一个 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:81 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:91 # args: currentState,msgName,checker.getStatesForOperation(msgName) current\ backup\ storage\ state[%s]\ doesn't\ allow\ to\ proceed\ message[%s],\ allowed\ states\ are\ %s = 当前镜像服务器状态[{0}]不能处理消息[{1}],仅当镜像服务器处于{2}时才能处理该消息 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:212 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:231 # args: bsType,bsUuid Unexpected\ backup\ storage[type\:%s,uuid\:%s] = 错误的镜像服务器[type:{0}, uuid:{1}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:233 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:252 # args: msg.getVolumeUuid() Can\ not\ create\ volume\ backup\ for\ shareable\ volume[uuid\:%s] = 无法给共享云盘[uuid:{0}]创建云盘备份 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:237 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:256 # args: msg.getVolumeUuid() -Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ it\ is\ not\ attached\ to\ any\ vm = 无法给云盘[uuid:{0}]创建云盘备份,因为它未加载到虚拟机上 +Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ it\ is\ not\ attached\ to\ any\ vm = 无法给云盘[uuid:{0}]创建云盘备份,因为它未加载到云主机上 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:246 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:265 # args: msg.getVolumeUuid(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() -Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ its\ attached\ volume\ is\ not\ in\ state[%s,\ %s] = 无法给云盘[uuid:{0}]创建云盘备份,因为加载到的虚拟机并不处于以下状态[{1}, {2}] +Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ its\ attached\ volume\ is\ not\ in\ state[%s,\ %s] = 无法给云盘[uuid:{0}]创建云盘备份,因为加载到的云主机并不处于以下状态[{1}, {2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:243 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:262 # args: msg.getVolumeUuid(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() -Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ the\ vm\ is\ not\ in\ state[%s,\ %s] = 无法给云盘[uuid:{0}]创建云盘备份,因为加载到的虚拟机并不处于以下状态[{1}, {2}] +Failed\ to\ create\ volume\ backup\ for\ volume[uuid\:%s],\ because\ the\ vm\ is\ not\ in\ state[%s,\ %s] = 无法给云盘[uuid:{0}]创建云盘备份,因为加载到的云主机并不处于以下状态[{1}, {2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:255 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:292 # args: msg.getVolumeUuid() -Volume[uuid\:%s]\ is\ not\ root\ volume = +The\ resource[uuid\:\ %s]\ has\ already\ created\ a\ cdp\ task,\ cannot\ create\ the\ backup\ job\ at\ the\ same\ time. = 资源[uuid:{0}]已创建CDP任务,无法同时创建备份作业。 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:262 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:280 +# args: msg.getVolumeUuid() +Volume[uuid\:%s]\ is\ not\ root\ volume = 卷[uuid:{0}]不是根卷 + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:287 # args: t.get(0),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() -Failed\ to\ create\ backups\ for\ VM[uuid\:%s],\ because\ it\ is\ not\ in\ state[%s,\ %s] = +Failed\ to\ create\ backups\ for\ VM[uuid\:%s],\ because\ it\ is\ not\ in\ state[%s,\ %s] = 无法为VM[uuid:{0}]创建备份,因为它未处于状态[{1},{2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:276 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:305 # args: groupUuid -No\ volume\ backup\ found\ for\ group\ uuid\:\ %s = +No\ volume\ backup\ found\ for\ group\ uuid\:\ %s = 未找到组uuid为{0}的卷备份 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:282 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:311 # args: groupUuid -root\ volume\ backup\ of\ group[uuid\:%s]\ not\ found = +root\ volume\ backup\ of\ group[uuid\:%s]\ not\ found = 未找到组[uuid:{0}]的根卷备份 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:312 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:315 +# args: expectVmUuid,rootVolumeInfo.get(0),rootVolumeInfo.get(1) +Current\ vm[uuid\:\ %s]\ of\ the\ volume[uuid\:\ %s]\ is\ no\ longer\ the\ vm[uuid\:\ %s]\ that\ was\ used\ for\ backup = 卷[uuid:{1}]的当前云主机[uuid:{0}]不再是用于备份的云主机[UuId:{2}] + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:348 # args: -cannot\ specify\ primary\ storage\ which\ attached\ different\ cluster. = +cannot\ specify\ primary\ storage\ which\ attached\ different\ cluster. = 无法指定连接到其他集群的主存储。 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:335 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:378 # args: backupUuid,state volume\ backup[uuid\:%s]\ is\ in\ state\ %s,\ cannot\ revert\ volume\ to\ it = 云盘备份[uuid:{0}]处于{1}状态,无法用于恢复云盘 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:345 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:388 # args: backupUuid original\ volume\ for\ backup[uuid\:%s]\ has\ been\ deleted,\ cannot\ revert\ volume\ to\ it = 云盘备份[uuid:{0}]已经被删除,无法用于恢复云盘 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:349 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:392 # args: volUuid,backupUuid,expectVmUuid -original\ volume[uuid\:%s]\ for\ backup[uuid\:%s]\ is\ no\ longer\ attached\ to\ vm[uuid\:%s] = +original\ volume[uuid\:%s]\ for\ backup[uuid\:%s]\ is\ no\ longer\ attached\ to\ vm[uuid\:%s] = 原始卷[uuid:{0}](用于备份[uuid:{1}])不再连接到云主机[uuid:{2}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:359 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:402 # args: backupUuid -VM\ not\ found\ with\ volume\ backup[uuid\:%s] = 找不到和云盘备份[uuid:{0}]对应的虚拟机 +VM\ not\ found\ with\ volume\ backup[uuid\:%s] = 找不到和云盘备份[uuid:{0}]对应的云主机 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:363 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:406 # args: vmState -VM\ is\ not\ in\ stopped\ state\:\ %s = 当前虚拟机状态并不是停止状态:{0} +VM\ is\ not\ in\ stopped\ state\:\ %s = 当前云主机状态并不是停止状态:{0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:380 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:423 # args: No\ available\ backup\ storage\ found = 没有可用的镜像服务器 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:181 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupApiInterceptor.java:518 +# args: +The\ vm\ is\ creating\ a\ backup\ job,\ cannot\ enable\ the\ cdp\ task\ at\ the\ same\ time. = 云主机正在创建备份作业,无法同时启用CDP任务。 + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:191 # args: Operation\ not\ supported\ on\ shared\ volume = 共享云盘不支持该操作 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:186 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:196 # args: volumeVO.getUuid() -No\ VM\ found\ for\ volume[uuid\:%s] = 找不到和云盘[uuid:{0}]对应的虚拟机 +No\ VM\ found\ for\ volume[uuid\:%s] = 找不到和云盘[uuid:{0}]对应的云主机 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:435 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupKvmBackend.java:380 # args: msg.getRootVolumeUuid() -No\ VM\ found\ with\ root\ volume\ uuid\:\ %s = +No\ VM\ found\ with\ root\ volume\ uuid\:\ %s = 找不到根卷uuid为{0}的云主机 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2041 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1974 # args: cidr,fmtCidr [%s]\ is\ not\ a\ standard\ cidr,\ do\ you\ mean\ [%s]? = [{0}]不是一个标准的cidr, 是否指定的是[{1}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:306 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1320 +# args: msg.getDstBackupStorageUuid(),msg.getSrcBackupStorageUuid(),BackupStorageState.Disabled.toString() +One\ of\ the\ backup\ storage[uuids\:\ %s,\ %s]\ is\ in\ the\ state\ of\ %s,\ can\ not\ do\ sync\ operation = 镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作 + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:992 +# args: +sync\ task\ failed. = 同步失败 + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:999 +# args: reply.getStatus() +unexpected\ task\ status\:\ %s = 错误的任务状态{0} + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:293 # args: vos.stream().filter( vo -> !succeedUuids.contains(vo.getUuid())).map(VolumeBackupVO::getUuid).collect(Collectors.toList()) -failed\ to\ create\ image\ from\ backup\ %s = +failed\ to\ create\ image\ from\ backup\ %s = 无法从备份{0}创建镜像 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:660 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:498 # args: msg.getImageStoreUuid(),e.getMessage() -sync\ volume\ backup\ metadata\ file\ in\ image\ store[uuid\:%s]\ meet\ I/O\ error\:\ %s = +sync\ volume\ backup\ metadata\ file\ in\ image\ store[uuid\:%s]\ meet\ I/O\ error\:\ %s = 同步卷备份元数据文件(位于镜像存储[uuid:{0}]中)遇到I/O错误:{1} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:697 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:535 +# args: volumeVmUuid,backupUuid,backupVmUuid +Current\ vm[uuid\:\ %s]\ of\ the\ backup\ volume\ is\ no\ longer\ the\ vm[uuid\:\ %s]\ that\ was\ used\ for\ backup = 备份卷的当前云主机[uuid:{0}]不再是用于备份的云主机[uuid:{1}] + +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:544 # args: hypervisorType -No\ VolumeBackupFactory\ of\ type[%s]\ found = +No\ VolumeBackupFactory\ of\ type[%s]\ found = 未找到类型为[{0}]的VolumeBackupFactory -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:714 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:561 # args: msg.getBackupStorageUuid(),BackupStorageState.Disabled.toString() One\ of\ the\ backup\ storage[uuid\:\ %s]\ is\ in\ the\ state\ of\ %s,\ can\ not\ do\ sync\ operation = 镜像服务器[uuid: {0}]处于状态{1}, 无法执行同步操作 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:854 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:738 # args: struct.getBackupUuid(),struct.getBackupStorageUuid() Volume\ backup[uuid\:%s]\ not\ found\ on\ backup\ storage[uuid\:%s] = 在镜像服务器[uuid:{1}]上找不到云盘备份[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1298 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1187 # args: backupUuid,srcBackupStorageUuid volume\ backup[uuid\:%s]\ not\ found\ in\ backup\ storage[uuid\:%s] = 在镜像服务器[uuid:{1}]上找不到云盘备份[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1506 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1399 # args: groupUuid -No\ volume\ backups\ found\ with\ group\ uuid\:\ %s = +No\ volume\ backups\ found\ with\ group\ uuid\:\ %s = 未找到组uuid为{0}的卷备份 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1513 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1406 # args: groupUuid -Root\ volume\ missing\ within\ group\ uuid\:\ %s = +Root\ volume\ missing\ within\ group\ uuid\:\ %s = 组uuid中缺少根卷:{0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1519 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1412 # args: groupUuid -Multiple\ root\ volumes\ found\ within\ group\ uuid\:\ %s = +Multiple\ root\ volumes\ found\ within\ group\ uuid\:\ %s = 在组uuid中找到多个根卷:{0} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1531 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1424 # args: groupUuid -No\ permission\ to\ volume\ backups\ within\ group\ uuid\:\ %s = +No\ permission\ to\ volume\ backups\ within\ group\ uuid\:\ %s = 对组uuid{0}中的卷备份没有权限 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1669 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:1564 # args: vo.getUuid() -Volume\ backup[uuid\:%s]\ not\ found\ on\ any\ backup\ storage = +Volume\ backup[uuid\:%s]\ not\ found\ on\ any\ backup\ storage = 未在任何备份存储上找到卷备份[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2068 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2001 # args: degree -degree\ [%s]\ should\ be\ a\ positive\ number = +degree\ [%s]\ should\ be\ a\ positive\ number = 度[{0}]应为正数 -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2102 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2035 # args: type -invalid\ type[%s],\ should\ be\ [nfs] = +invalid\ type[%s],\ should\ be\ [nfs,\ sshfs,\ nbd] = 类型[{0}]无效,应为[NFS,sshfs,NBD] -# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2108 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupManagerImpl.java:2045 # args: url -invalid\ url[%s],\ should\ be\ hostname\:/path = +invalid\ url[%s],\ should\ be\ hostname\:/path = URL[{0}]无效,应为hostname:/path -# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:181 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:177 # args: inv.getUuid(),e.getMessage() -generate\ volume\ backup\ metadata\ file\ on\ image\ store[uuid\:%s]\ failure,\ because\ IO\ error\:\ %s = +generate\ volume\ backup\ metadata\ file\ on\ image\ store[uuid\:%s]\ failure,\ because\ IO\ error\:\ %s = 在镜像存储[uuid:{0}]上生成卷备份元数据文件失败,因为IO错误:{1} -# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:508 +# at: src/main/java/org/zstack/storage/backup/VolumeBackupMetadataMaker.java:505 # args: rsp.getError() -volume\ backup\ metadata\ operation\ failure,\ because\ %s = +volume\ backup\ metadata\ operation\ failure,\ because\ %s = 卷备份元数据操作失败,原因是{0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:586 +# args: cmd.imgurl,cmd.uuid,ret.getError() +failed\ to\ download\ image[url\:\ %s]\ on\ backup\ storage[uuid\:\ %s],\ because\:\ %s = 无法下载镜像[URL:{0}](在备份存储[uuid:{1}]上),原因是:{2} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:271 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:277 # args: url,rsp.getError() unable\ to\ connect\ to\ SimpleHttpBackupStorage[url\:%s],\ because\ %s = 无法连接到SimpleHttpBackupStorage[url:{0}],因为{1} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:493 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:507 # args: iinv.getName() Missing\ cert\ file\ for\ downloading\ image\:\ %s = 下载镜像时证书文件丢失 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:622 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:831 +# args: +No\ response = 无响应 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:907 +# args: ret.getError() +reclaim\ imagestore\ error,\ because\:%s = 收回imagestore错误,因为{0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:994 +# args: self.getUuid(),ret.getError() +failed\ to\ set\ max\ capacity\ on\ image\ store[uuid\:%s],\ because\:\ %s = 无法设置镜像存储[uuid:{0}]的最大容量,因为:{1} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1223 +# args: msg.getImageUuid(),self.getUuid() +image[%s]\ not\ found\ on\ backup\ storage[%s] = 在备份存储[{1}]上找不到镜像[{0}] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1134 +# args: ret.getError() +failed\ to\ delete\ image\ package,\ because\:\ %s = 无法删除镜像包,因为:{0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1158 +# args: StringUtils.join(notOnBsImageUuids, ','),msg.getBackupStorageUuid() +some\ images\ [%s]\ are\ not\ exported\ on\ the\ backup\ storage[uuid\:\ %s] = 某些镜像[{0}]未在备份存储[uuid:{1}]上导出 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1192 +# args: ret.getError() +failed\ to\ package\ exported\ images,\ because\ %s = 无法打包导出的镜像,因为{0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1234 +# args: self.getUuid(),actualSize +the\ backup\ storage[uuid\:%s]\ has\ not\ enough\ capacity[%s]\ to\ export = 备份存储[uuid:{0}]没有足够的容量[{1}]用于导出 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1393 # args: -image\ store\ service\ is\ temporary\ not\ available,\ because\ it\ is\ reclaiming\ space\ now = +image\ store\ [%s]\ cannot\ add\ image,\ because\ it\ is\ used\ for\ backup\ remote = ImageStore[{0}]不能添加镜像,因为它已经被远程镜像使用 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:798 +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1591 # args: -No\ response = 无响应 +commercial\ license\ is\ required\ to\ use\ ImageStore = 使用ImageStore需要商业许可证 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1712 +# args: self.getUuid(),resp.getUuid() +the\ uuid\ of\ imagestoreBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = 镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:125 +# args: msg.getHostname() +hostname[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 物理机名[{0}]不是一个IPv4的地址,而是一个非法的物理机名 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:60 +# args: bsUuid,imageUuid +target\ backup\ storage[uuid\:%s]\ already\ contains\ the\ image\ [uuid\:%s] = 目标备份存储[uuid:{0}]已包含镜像[uuid:{1}] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:79 +# args: msg.getSrcBackupStorageUuid(),msg.getUuid() +source\ backup\ storage[%s]\ doesn't\ contain\ image[%s] = 源镜像服务器[{0}]不包含该镜像[{1}] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:94 +# args: msg.getSrcBackupStorageUuid(),msg.getUuid() +src\ backupstorage[%s]\ doesn't\ contain\ image[%s] = SRC BackupStorage[{0}]不包含镜像[{1}] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:142 +# args: msg.getHostname() +duplicate\ backup\ storage.\ There\ has\ been\ an\ image\ store\ backup\ storage[hostname\:%s] = 重复的镜像服务器。已经存在一个镜像服务器[物理机名: {0}] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:147 +# args: +file\ path\ needed = 需要文件路径 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:151 +# args: dir +absolute\ file\ path\ required\:\ %s = 需要文件的绝对路径;{0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:154 +# args: +the\ url\ contains\ an\ invalid\ folder[/dev\ or\ /proc\ or\ /sys] = URL包含了一个无效的目录[/dev or /proc or /sys] + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:162 +# args: dir +file\ path\ contains\ invalid\ character\:\ %s = 文件路径包含非法字符: {0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageExtension.java:193 +# args: ps.getUuid() +cannot\ find\ a\ connected\ host\ in\ cluster\ to\ which\ PS\ [uuid\:\ %s]\ attached = 在PS[uuid:{0}]连接到的集群中找不到已连接的物理机 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:108 +# args: amsg.getUrl() +invalid\ url[%s],\ the\ url\ must\ be\ an\ absolute\ path\ starting\ with\ '/' = 无效的url[{0}],url必须是以'/'开头的绝对路径 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:117 +# args: hostname +existing\ SimpleHttpBackupStorage\ with\ hostname[%s]\ found = 存在物理机名为[{0}]的简单http镜像服务器 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:228 +# args: +sync\ status\ failed. = 同步失败 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:343 +# args: +failed\ to\ get\ task\ reply! = 获取任务回复失败! + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:841 +# args: rsp.getError() +delete\ image\ metadata\ file\ failed\:\ %s = 删除镜像元数据文件失败: {0} + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:397 +# args: bsUuid +AddImage\ is\ forbidden\ in\ Disaster\ BS\:\ [%s] = 在Disaster镜像服务器中添加镜像是被禁止的 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:770 +# args: rsp.getBackupStorageMetaFileName() +Check\ image\ metadata\ file\:\ %s\ failed = 检查镜像元数据文件: {0}失败 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:594 +# args: rsp.getBackupStorageMetaFileName() +Create\ image\ metadata\ file\ \:\ %s\ failed = 创建镜像元数据文件: {0}失败 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:569 +# args: rsp.getBackupStorageMetaFileName() +Create\ image\ metadata\ file\ sync\ \:\ %s\ failed = 同步创建镜像元数据文件{0}失败了 + +# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreImageStruct.java:80 +# args: e.getMessage() +parse\ create\ time\ error\:\ %s = 解析创建时间出错: {0} + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:111 +# args: scheme,url +SftpBackupStorage\ doesn't\ support\ scheme[%s]\ in\ url[%s] = Sftp镜像服务器不支持在url[{1}]里包含scheme[{0}] + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:242 +# args: rsp.getError() +fail\ to\ cancel\ download\ image,\ because\ %s = 无法取消下载镜像,因为{0} + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:316 +# args: self.getUuid(),ret.getUuid() +the\ uuid\ of\ sftpBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = Sftp镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态 + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java:70 +# args: bsUuid +Please\ stop\ the\ vm\ before\ create\ volume\ template\ to\ sftp\ backup\ storage\ %s = 请在创建SFTP备份存储{0}的卷模板之前停止云主机 + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java:106 +# args: msg.getHostname() +duplicate\ backup\ storage.\ There\ has\ been\ a\ sftp\ backup\ storage[hostname\:%s]\ existing = 重复的镜像服务器。已经存在一个镜像服务器[物理机名: {0}] + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:554 +# args: rsp.getBackupStorageMetaFileName() +check\ image\ metadata\ file\:\ %s\ failed = 检查镜像元数据文件: {0}失败 + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:399 +# args: rsp.getBackupStorageMetaFileName() +create\ image\ metadata\ file\ \:\ %s\ failed = 创建镜像元数据文件: {0}失败 + +# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:559 +# args: rsp.getBackupStorageMetaFileName() +image\ metadata\ file\:\ %s\ is\ not\ exist = 镜像元数据文件: {0}不存在 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:321 +# args: vmUuid +host\ not\ found\ for\ VM\:\ %s = 找不到VM的物理机:{0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:241 +# args: vmUuid +query-mirror\:\ host\ not\ found\ for\ VM[uuid\:%s] = 查询镜像:找不到VM[uuid:{0}]的物理机 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:328 +# args: hostUuid +libvirt\ on\ the\ host[uuid\:\ %s]\ not\ support\ to\ create\ cdp\ task,\ please\ check\ the\ version\ of\ libvirt. = 物理机[uuid:{0}]上的libvirt不支持创建CDP任务,请检查libvirt的版本。 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:334 +# args: hostUuid +qemu\ on\ the\ host[uuid\:\ %s]\ not\ support\ to\ create\ cdp\ task,\ please\ check\ the\ version\ of\ qemu. = 物理机[uuid:{0}]上的QEMU不支持创建CDP任务,请检查QEMU的版本。 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupKvmBackend.java:366 +# args: vmUuid +The\ QEMU\ version\ running\ on\ the\ VM[uuid\:%s]\ does\ not\ support\ mirrorBitmap. = 在VM[uuid:{0}]上运行的QEMU版本不支持MirrorBitMap。 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:458 +# args: vol.getUuid(),reply.getError() +cannot\ ask\ primary\ storage[uuid\:%s]\ for\ volume\ snapshot\ capability,\ see\ detail\ [%s] = 无法向主存储[uuid:{0}]请求卷快照功能,请参阅详细信息[{1}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:320 +# args: msg.getTaskType() +unexpected\ task\ type\:\ %s = 意外的任务类型:{0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:127 +# args: +CDP\ task\ is\ still\ enabled = CDP任务仍处于启用状态 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:152 +# args: s,OffsetDateTime.now().truncatedTo(ChronoUnit.SECONDS) +invalid\ time\ string\:\ %s,\ should\ be\ in\ ISO\ offset\ format,\ for\ example\:\ %s = 无效的时间字符串:{0},应为ISO偏移格式,例如:{1} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:189 +# args: state +VM\ is\ not\ stopped,\ current\ state\:\ %s = 云主机未停止,当前状态:{0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:233 +# args: volumeUuid,msg.getVmInstanceUuid() +Shared\ volume[%s]\ from\ VM[uuid]\ is\ still\ used\ by\ other\ VMs. = 云主机[uuid]中的共享云盘[{0}]仍由其他云主机使用。 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:243 +# args: msg.getUuid() +Task\ not\ found[uuid\:\ %s] = 未找到任务[uuid:{0}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:248 +# args: msg.getUuid(),taskVO.getTaskType() +Unexpected\ task\ type[uuid\:\ %s,\ type\:\ %s] = 意外的任务类型[uuid:{0},类型:{1}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:261 +# args: refVO.getResourceUuid() +VM[uuid\:\ %s]\ already\ deleted = 云主机[uuid:{0}]已删除 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:275 +# args: state +Unexpected\ VM\ state\:\ %s = 意外的VM状态:{0} + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:283 +# args: taskVO.getBackupStorageUuid() +Backup\ storage\ not\ found[uuid\:\ %s] = 未找到备份存储[uuid:{0}] + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:288 +# args: taskVO.getBackupStorageUuid() +Backup\ storage[uuid\:\ %s]\ is\ disabled = 备份存储[uuid:{0}]已禁用 + +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:293 +# args: taskVO.getBackupStorageUuid() +Backup\ storage[uuid\:\ %s]\ is\ not\ connected = 备份存储[uuid:{0}]未连接 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:871 -# args: ret.getError() -reclaim\ imagestore\ error,\ because\:%s = 收回imagestore错误,因为{0} +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:309 +# args: refVO.getResourceUuid() +The\ vm[uuid\:\ %s]\ has\ already\ created\ a\ backup\ job,\ cannot\ enable\ the\ cdp\ task\ at\ the\ same\ time. = VM[uuid:{0}]已创建备份作业,无法同时启用CDP任务。 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:958 -# args: self.getUuid(),ret.getError() -failed\ to\ set\ max\ capacity\ on\ image\ store[uuid\:%s],\ because\:\ %s = +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:334 +# args: s2,v2,s1,v1 +'%s'(%d)\ should\ be\ larger\ than\ '%s'(%d) = “{0}”({1})应大于“{2}”({3}) -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1085 -# args: msg.getImageUuid(),self.getUuid() -image[%s]\ not\ found\ on\ backup\ storage[%s] = +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:340 +# args: "hourlyRpSinceDay" +mandatory\ args\ missing\:\ %s = 缺少必需的参数:{0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1235 -# args: -image\ store\ [%s]\ cannot\ add\ image,\ because\ it\ is\ used\ for\ backup\ remote = ImageStore[{0}]不能添加镜像,因为它已经被远程镜像使用 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:376 +# args: vmUuids.size() +expected\ one\ VM\ uuid,\ but\ given\ %d = 应为一个VM uuid,但给定了{0} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1435 -# args: -commercial\ license\ is\ required\ to\ use\ ImageStore = 使用ImageStore需要商业许可证 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:380 +# args: vmUuids.get(0) +resource\ [uuid\:\ %s]\ is\ not\ VM = 资源[uuid:{0}]不是VM -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorage.java:1468 -# args: self.getUuid(),ret.getUuid() -the\ uuid\ of\ imagestoreBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = 镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageApiInterceptor.java:402 +# args: msg.getTargetResourceUuid() +The\ vm[uuid\:\ %s]\ has\ already\ created\ a\ cdp\ task,\ cannot\ create\ the\ backup\ job\ at\ the\ same\ time. = VM[uuid:{0}]已创建CDP任务,无法同时创建备份作业。 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:125 -# args: msg.getHostname() -hostname[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 主机名[{0}]不是一个IPv4的地址,而是一个非法的主机名 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageImpl.java:243 +# args: groupId +No\ recovery\ point\ found\ with\ grpId\ %d = 找不到具有grpid{0}的恢复点 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:60 -# args: bsUuid,imageUuid -target\ backup\ storage[uuid\:%s]\ already\ contains\ the\ image\ [uuid\:%s] = +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageImpl.java:717 +# args: backupStorageUuid +hostname\ not\ found\ for\ backup\ storage[uuid\:\ %s] = 未找到备份存储的物理机名[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:79 -# args: msg.getSrcBackupStorageUuid(),msg.getUuid() -source\ backup\ storage[%s]\ doesn't\ contain\ image[%s] = 源镜像服务器[{0}]不包含该镜像[{1}] +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1921 +# args: msg.getUuid() +CDP\ task[uuid\:\ %s]\ not\ found = 未找到CDP任务[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:94 -# args: msg.getSrcBackupStorageUuid(),msg.getUuid() -src\ backupstorage[%s]\ doesn't\ contain\ image[%s] = +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:179 +# args: msg.getMaxCapacity(),oldUsedCapacity +Invalid\ max\ capacity[%d],\ current\ usage\ is\ %d = 最大容量[{0}]无效,当前使用量为{1} -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:142 -# args: msg.getHostname() -duplicate\ backup\ storage.\ There\ has\ been\ an\ image\ store\ backup\ storage[hostname\:%s] = 重复的镜像服务器。已经存在一个镜像服务器[主机名: {0}] +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:269 +# args: vmUuid,tasks.get(0) +VM\ [uuid\:\ %s]\ have\ been\ protected\ by\ task\:\ %s = 云主机[uuid:{0}]已受任务{1}保护 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:147 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:715 # args: -file\ path\ needed = 需要文件路径 - -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:151 -# args: dir -absolute\ file\ path\ required\:\ %s = 需要文件的绝对路径;{0} +revert\ job\ cancelled = 已取消还原作业 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:154 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:781 # args: -the\ url\ contains\ an\ invalid\ folder[/dev\ or\ /proc\ or\ /sys] = URL包含了一个无效的目录[/dev or /proc or /sys] +create-vm\ job\ cancelled = 创建云主机作业已取消 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageApiInterceptor.java:162 -# args: dir -file\ path\ contains\ invalid\ character\:\ %s = 文件路径包含非法字符: {0} +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1181 +# args: taskVO.getUuid() +CDP\ task[uuid\:\ %s]\ has\ no\ VM\ attached = CDP任务[uuid:{0}]未连接VM -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageExtension.java:188 -# args: ps.getUuid() -cannot\ find\ a\ connected\ host\ in\ cluster\ to\ which\ PS\ [uuid\:\ %s]\ attached = +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1215 +# args: taskVO.getUuid() +task[uuid\:%s]\ have\ been\ deleted = 任务[uuid:{0}]已被删除 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:142 -# args: amsg.getUrl() -invalid\ url[%s],\ the\ url\ must\ be\ an\ absolute\ path\ starting\ with\ '/' = 无效的url[{0}],url必须是以'/'开头的绝对路径 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1279 +# args: taskUuid,maxCapacity,usedCapacity +CDP\ task[uuid\:%s]\ exceeded\ storage\ usage\:\ maximum\ %d,\ used\ %d. = CDP任务[uuid:{0}]超出了存储使用率:最大值{1},已使用{2}。 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:151 -# args: hostname -existing\ SimpleHttpBackupStorage\ with\ hostname[%s]\ found = 存在主机名为[{0}]的简单http镜像服务器 +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1728 +# args: vmUuid +No\ CDP\ task\ found\ for\ VM\:\ %s = 未找到VM{0}的CDP任务 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:100 -# args: result.getStderr() -ansible\ mkdir\ failed,\ due\ to\:\ %s = Ansible创建目录失败,因为{0} +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1736 +# args: vmUuid +No\ CDP\ backup\ storage\ found\ for\ VM\:\ %s = 未找到云主机{0}的CDP备份存储 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:112 -# args: result.getStderr() -ansible\ failed,\ due\ to\:\ %s = Ansible失败,因为{0} +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1784 +# args: hypervisorType +No\ CdpBackupFactory\ of\ type[%s]\ found = 未找到类型为[{0}]的CDPBackupFactory -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageFactory.java:110 -# args: result.getStdout() -ansible\ attach\ nas\ failed,\ due\ to\:\ %s = Ansible绑定失败,因为{0} +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:1815 +# args: hostUuid +No\ hypervisor\ type\ for\ VM\ %s = 云主机{0}没有云主机管理程序类型 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:395 -# args: tmpHostFile,result.getStderr() -create\ tmp\ file\ [%s]\ failed,\ due\ to\:\ %s = 创建tmp文件[{0}]失败,因为{1} +# at: src/main/java/org/zstack/storage/cdp/CdpBackupStorageManagerImpl.java:2221 +# args: msg.getVolume().getUuid() +The\ operation\ has\ volume[uuid\:\ %s]\ that\ will\ take\ chain\ type\ snapshot.\ Therefore,\ you\ could\ not\ do\ this\ operation\ when\ a\ CDP\ task\ is\ running\ on\ the\ VM\ instance. = 该操作具有将创建链类型快照的卷[uuid:{0}]。因此,当CDP任务在VM实例上运行时,您无法执行此操作。 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageManagerImpl.java:229 +# at: src/main/java/org/zstack/storage/cdp/CdpTaskMonitor.java:163 # args: -sync\ status\ failed. = 同步失败 +Could\ not\ attach\ volume.The\ VM\ instance\ is\ running\ a\ CDP\ task.\ After\ the\ volume\ is\ attached,\ the\ capacity\ required\ for\ full\ backup\ will\ exceed\ the\ CDP\ task\ planned\ size.\ Please\ plan\ the\ size\ properly\ and\ try\ again. = 无法连接卷。VM实例正在运行CDP任务。连接卷后,完整备份所需的容量将超过CDP任务计划的大小。请正确规划大小,然后重试。 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:806 -# args: rsp.getError() -delete\ image\ metadata\ file\ failed\:\ %s = 删除镜像元数据文件失败: {0} +# at: src/main/java/org/zstack/storage/cdp/CdpTaskMonitor.java:187 +# args: volume.getVmInstanceUuid(),volume.getUuid() +The\ VM[%s]\ for\ volume[%s]\ is\ running\ CDP,\ cannot\ resize\ now. = 卷[{1}]的VM[{0}]正在运行CDP,现在无法调整大小。 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:389 +# at: src/main/java/org/zstack/storage/cdp/CreateVmFromCdpBackupLongJob.java:88 +# args: apiMessage.getCdpTaskUuid() +No\ VM\ found\ for\ CDP\ task[uuid\:\ %s] = 未找到CDP任务[uuid:{0}]的VM + +# at: src/main/java/org/zstack/storage/cdp/CreateVmFromCdpBackupLongJob.java:119 # args: bsUuid -AddImage\ is\ forbidden\ in\ Disaster\ BS\:\ [%s] = 在Disaster镜像服务器中添加镜像是被禁止的 +BackupStorage[uuid\:\ %s]\ already\ been\ deleted = BackupStorage[uuid:{0}]已删除 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:735 -# args: rsp.getBackupStorageMetaFileName() -Check\ image\ metadata\ file\:\ %s\ failed = 检查镜像元数据文件: {0}失败 +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:179 +# args: +no\ volume\ records\ found\ from\ VM\ backup = 未从云主机备份中找到卷记录 -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:563 -# args: rsp.getBackupStorageMetaFileName() -Create\ image\ metadata\ file\ \:\ %s\ failed = 创建镜像元数据文件: {0}失败 +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:138 +# args: taskUuid +VM\ CDP\ task[uuid\:\ %s]\ not\ found = 找不到VM CDP任务[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreBackupStorageMetaDataMaker.java:538 -# args: rsp.getBackupStorageMetaFileName() -Create\ image\ metadata\ file\ sync\ \:\ %s\ failed = 同步创建镜像元数据文件{0}失败了 +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:147 +# args: taskUuid +VM\ not\ found\ for\ CDP\ task[uuid\:\ %s] = 未找到CDP任务[uuid:{0}]的VM -# at: src/main/java/org/zstack/storage/backup/imagestore/ImageStoreImageStruct.java:79 -# args: e.getMessage() -parse\ create\ time\ error\:\ %s = 解析创建时间出错: {0} +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:236 +# args: taskUuid,msg.getGroupId() +multiple\ root\ volumes\ found\ from\ CDP\ backup\ %s\:%d = 从CDP备份{0}中找到多个根卷:{1} -# at: src/main/java/org/zstack/storage/backup/imagestore/ReclaimSpaceFromImageStoreLongJob.java:62 -# args: -Cancel\ operation\ is\ not\ supported = +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:250 +# args: taskUuid,msg.getGroupId() +cannot\ find\ root\ volume\ from\ CDP\ backup\ %s\:%d = 无法从CDP备份{0}中找到根卷:{1} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:105 -# args: scheme,url -SftpBackupStorage\ doesn't\ support\ scheme[%s]\ in\ url[%s] = Sftp镜像服务器不支持在url[{1}]里包含scheme[{0}] +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveCreateFlowChain.java:257 +# args: taskUuid,msg.getGroupId() +root\ volume\ not\ found\ from\ CDP\ backup\ %s\:%d = 未从CDP备份{0}中找到根卷:{1} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:133 -# args: ret.getError() -fail\ to\ download\ image,\ because\ %s = 下载镜像失败,因为{0} +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:118 +# args: hostUuid,this.msg.getVmInstanceUuid() +recoverVm\:\ host[uuid\:\ %s]\ not\ found\ for\ VM[uuid\:\ %s] = 未找到VM[uuid:{1}]的RecoverVM:物理机[uuid:{0}] -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:233 -# args: rsp.getError() -fail\ to\ cancel\ download\ image,\ because\ %s = +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:216 +# args: uuids +multiple\ root\ volumes\ found\:\ %s = 找到多个根卷:{0} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java:307 -# args: self.getUuid(),ret.getUuid() -the\ uuid\ of\ sftpBackupStorage\ agent\ changed[expected\:%s,\ actual\:%s],\ it's\ most\ likely\ the\ agent\ was\ manually\ restarted.\ Issue\ a\ reconnect\ to\ sync\ the\ status = Sftp镜像镜像服务器的代理的uuid发生了改变[期望: {0},实际: {1}],很有可能代理被手动重启了,需要重连同步状态 +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:792 +# args: volumeUuid,installPath +volume[uuid\:\ %s]\ has\ unexpected\ path\:\ %s = 卷[uuid:{0}]具有意外路径:{1} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java:70 -# args: bsUuid -Please\ stop\ the\ vm\ before\ create\ volume\ template\ to\ sftp\ backup\ storage\ %s = +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:718 +# args: volumeUuid,oldVolumeSize +unexpected\ volume[uuid\:\ %s]\ size\:\ %d = 意外卷[uuid:{0}]大小:{1} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageApiInterceptor.java:106 -# args: msg.getHostname() -duplicate\ backup\ storage.\ There\ has\ been\ a\ sftp\ backup\ storage[hostname\:%s]\ existing = 重复的镜像服务器。已经存在一个镜像服务器[主机名: {0}] +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:746 +# args: volumeUuid,reply.getError().getDetails() +resize\ volume[uuid\:\ %s]\ failed\:\ %s = 调整卷[uuid:{0}]大小失败:{1} -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:543 -# args: rsp.getBackupStorageMetaFileName() -check\ image\ metadata\ file\:\ %s\ failed = 检查镜像元数据文件: {0}失败 +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:377 +# args: uuid,msg.getVmInstanceUuid() +volume\ %s\ contains\ in\ backup\ but\ detached\ from\ VM[uuid\:\ %s]\:\ you\ need\ to\ either\ attach\ it\ back\ or\ delete\ it = 卷{0}包含在备份中,但已从VM分离[uuid:{1}]:您需要将其重新连接或将其删除 -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:392 -# args: rsp.getBackupStorageMetaFileName() -create\ image\ metadata\ file\ \:\ %s\ failed = 创建镜像元数据文件: {0}失败 +# at: src/main/java/org/zstack/storage/cdp/KvmCdpVmLiveRestoreFlowChain.java:305 +# args: +no\ root\ volume\ found\ from\ VM\ backup = 未从云主机备份中找到根卷 -# at: src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java:548 -# args: rsp.getBackupStorageMetaFileName() -image\ metadata\ file\:\ %s\ is\ not\ exist = 镜像元数据文件: {0}不存在 +# at: src/main/java/org/zstack/storage/cdp/RecoverVmTracker.java:145 +# args: +kvmagent\ restarted = KVMAGENT重新启动 + +# at: src/main/java/org/zstack/storage/cdp/RecoverVmTracker.java:164 +# args: maxFailure +kvmagent\ no\ response\ %d\ times = KVMAgent无响应{0}次 -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:77 +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:117 +# args: apiMessage.getHostUuid(),apiMessage.getBackupStorageUuid() +waiting\ host[uuid\:%s]\ and\ backupStorage[uuid\:%s]\ to\ be\ Connected... = 正在等待要连接的物理机[uuid:{0}]和备份存储[uuid:{1}].. + +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:72 +# args: apiMessage.getVmInstanceUuid() +recoverVm\:\ host\ uuid\ is\ not\ provided\ and\ original\ host\ is\ not\ found\ for\ VM[uuid\:\ %s] = RecoverVM:未提供物理机uuid,并且未找到VM[uuid:{0}]的原始物理机 + +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:165 +# args: vmUuid +No\ CDP\ task\ found\ for\ VM[uuid\:\ %s] = 找不到VM[uuid:{0}]的CDP任务 + +# at: src/main/java/org/zstack/storage/cdp/RevertVmFromCdpBackupMsgLongJob.java:174 +# args: vmUuid,backupStorageUuid +CDP\ task\ for\ VM[uuid\:\ %s]\ is\ not\ found\ on\ BS[uuid\:\ %s] = 在BS[uuid:{1}]上找不到VM[uuid:{0}]的CDP任务 + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:84 # args: msg.getPoolName() operation\ failure,\ because\ the\ poolName[poolName\:%s]\ can\ not\ include\ unprintable\ ascii\ characters. = 操作失败,因为pool名称[poolName:{0}]不能包含中文和特殊字符 -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:91 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:98 # args: duplicatePoolUuid Ceph\ pool[uuid\:%s]\ with\ this\ name\ is\ already\ added\ into\ ZStack\ and\ used\ elsewhere,\ cannot\ reuse\ the\ ceph\ pool. = 池名称为此的扩展池[uuid:{0}]已经被添加进 ZStack 了,已做它用,不能复用该扩展池 -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:86 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:93 # args: msg.getPoolName(),duplicatePoolUuid creation\ failure,\ duplicate\ poolName[%s].\ There\ has\ been\ a\ pool[uuid\:%s]\ with\ the\ same\ name\ existing. = 创建失败,重复的池名称[{0}]。已经有一个相同名称的扩展池[uuid:{1}]存在 -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:119 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:126 # args: existing -cannot\ add\ ceph\ primary\ storage,\ there\ has\ been\ some\ ceph\ primary\ storage\ using\ mon[hostnames\:%s] = 无法添加ceph主存储,一定有某些ceph主存储使用了mon[主机名: {0}] +cannot\ add\ ceph\ primary\ storage,\ there\ has\ been\ some\ ceph\ primary\ storage\ using\ mon[hostnames\:%s] = 无法添加分布式存储,一定有某些分布式存储使用了mon[物理机名: {0}] -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:130 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:137 # args: uri.getHostname() Cannot\ add\ same\ host[%s]\ in\ mons = 在mon中无法添加相同的物理机[{0}] -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:156 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:163 # args: Adding\ the\ same\ Mon\ node\ is\ not\ allowed = 添加相同的Mon节点不被允许 -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:235 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:202 +# args: monUrl,MON_URL_FORMAT +invalid\ monUrl[%s].\ A\ valid\ url\ is\ in\ format\ of\ %s = 无效的monURL[{0}]。有效URL的格式为{1} + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:209 +# args: +dataVolumePoolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = DataVolumePoolName可以为空,但不能为空字符串 + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:214 +# args: +rootVolumePoolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = RootVolumePoolName可以为空,但不能为空字符串 + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:219 +# args: +imageCachePoolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = ImageCachePoolName可以为空,但不能为空字符串 + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:242 # args: existing -cannot\ add\ ceph\ backup\ storage,\ there\ has\ been\ some\ ceph\ backup\ storage\ using\ mon[hostnames\:%s] = 无法添加ceph镜像服务器,已经有某个ceph镜像服务器使用mon[主机名: {0}] +cannot\ add\ ceph\ backup\ storage,\ there\ has\ been\ some\ ceph\ backup\ storage\ using\ mon[hostnames\:%s] = 无法添加Ceph镜像服务器监控节点,已经有某个Ceph镜像服务器监控节点使用mon[物理机名: {0}] -# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:243 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:250 # args: poolName\ is\ required\ when\ importImages\ is\ true = 当importImages为真的时候必须填写池名 +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:248 +# args: +poolName\ can\ be\ null\ but\ cannot\ be\ an\ empty\ string = PoolName可以为空,但不能为空字符串 + +# at: src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java:269 +# args: +Third-party\ ceph\ cannot\ mixed\ with\ other\ primary\ storage. = 第三方Ceph不能与其他主存储混合。 + # at: src/main/java/org/zstack/storage/ceph/CephMonBase.java:66 # args: The\ problem\ may\ be\ caused\ by\ an\ incorrect\ user\ name\ or\ password\ or\ SSH\ port\ or\ unstable\ network\ environment = 该问题可能是由不正确的用户名、密码、SSH端口或者不稳定的网络环境引起的 -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:834 -# args: msg.getHostname(),msg.getBackupStorageUuid() -CephMon[hostname\:%s]\ not\ found\ on\ backup\ storage[uuid\:%s] = +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:768 +# args: path +all\ monitors\ cannot\ execute\ http\ call[%s] = 所有的监控节点都无法执行http call[{0}] -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1218 -# args: self.getUuid(),JSONObjectUtil.toJsonString(errorCodes) -unable\ to\ connect\ to\ the\ ceph\ backup\ storage[uuid\:%s].\ Failed\ to\ connect\ all\ ceph\ mons.\ Errors\ are\ %s = 无法连接到ceph镜像服务器[uuid:{0}]。所有监控节点均无法连接。错误是{1} +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:866 +# args: msg.getHostname(),msg.getBackupStorageUuid() +CephMon[hostname\:%s]\ not\ found\ on\ backup\ storage[uuid\:%s] = 在备份存储[uuid:{1}]上找不到cephmon[物理机名:{0}] -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1339 +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1386 # args: otherCeph.getName(),otherCeph.getUuid(),fsId -there\ is\ another\ CEPH\ backup\ storage[name\:%s,\ uuid\:%s]\ with\ the\ same\ FSID[%s],\ you\ cannot\ add\ the\ same\ CEPH\ setup\ as\ two\ different\ backup\ storage = 有另外一个CEPH镜像服务器[name:{0}, uuid:{1}]有相同的FSID[{2}],你不能添加同样的CEPH为两个不同的镜像服务器 +there\ is\ another\ CEPH\ backup\ storage[name\:%s,\ uuid\:%s]\ with\ the\ same\ FSID[%s],\ you\ cannot\ add\ the\ same\ CEPH\ setup\ as\ two\ different\ backup\ storage = 有另外一个Ceph镜像服务器监控节点[name:{0}, uuid:{1}]有相同的FSID[{2}],你不能添加同样的CEPH为两个不同的镜像服务器 -# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java:92 +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java:1756 +# args: msg.getImageUuid(),self.getUuid(),self.getName() +image[uuid\:\ %s]\ is\ not\ on\ backup\ storage[uuid\:%s,\ name\:%s] = 镜像[uuid:{0}]不在备份存储[uuid:{1},名称:{2}]上 + +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java:97 # args: uuid -cannot\ update\ status\ of\ the\ ceph\ backup\ storage\ mon[uuid\:%s],\ it\ has\ been\ deleted.This\ error\ can\ be\ ignored = 无法更新ceph镜像服务器监控节点[uuid:{0}],他已经被删除。这个错误可以被忽略 +cannot\ update\ status\ of\ the\ ceph\ backup\ storage\ mon[uuid\:%s],\ it\ has\ been\ deleted.This\ error\ can\ be\ ignored = 无法更新Ceph镜像服务器监控节点监控节点[uuid:{0}],他已经被删除。这个错误可以被忽略 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1283 -# args: backupStorage.getUuid(),backupStorage.getName(),bsFsid,self.getUuid(),self.getName(),getSelf().getFsid() -the\ backup\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s]\ is\ not\ in\ the\ same\ ceph\ cluster\ with\ the\ primary\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s] = 镜像服务器[uuid:{0}, name:{1}, fsid:{2}]和主存储[uuid:{3}, name:{4}, fsid:{5}]不在同一个ceph集群中 +# at: src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java:463 +# args: getSelf().getBackupStorageUuid() +Ceph\ bs[uuid\=%s]\ pool\ name\ not\ found = 找不到Ceph BS[uuid={0}]池名称 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1477 -# args: poolName -cannot\ find\ cephPrimaryStorage\ pool[poolName\=%s] = +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4126 +# args: base.getSelf().getHostname(),fsid,getSelf().getFsid() +the\ mon[ip\:%s]\ returns\ a\ fsid[%s]\ different\ from\ the\ current\ fsid[%s]\ of\ the\ cep\ cluster,are\ you\ adding\ a\ mon\ not\ belonging\ to\ current\ cluster\ mistakenly? = MON[IP:{0}]返回的FSID[{1}]与CEP集群的当前FSID[{2}]不同,您是否错误地添加了不属于当前集群的MON? -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1483 -# args: poolName -cephPrimaryStorage\ pool[poolName\=%s]\ available\ capacity\ not\ enough = +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:1520 +# args: backupStorage.getUuid(),backupStorage.getName(),bsFsid,self.getUuid(),self.getName(),getSelf().getFsid() +the\ backup\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s]\ is\ not\ in\ the\ same\ ceph\ cluster\ with\ the\ primary\ storage[uuid\:%s,\ name\:%s,\ fsid\:%s] = 镜像服务器[uuid:{0}, name:{1}, fsid:{2}]和主存储[uuid:{3}, name:{4}, fsid:{5}]不在同一个ceph集群中 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2303 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2588 # args: psUuid,bsUuid fsid\ is\ not\ same\ between\ ps[%s]\ and\ bs[%s],\ create\ template\ is\ forbidden. = 在主存储和镜像服务器中fsid不是一样的,禁止创建模版。 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2762 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3410 # args: self.getUuid() -ceph\ primary\ storage[uuid\:%s]\ may\ have\ been\ deleted. = Ceph主存储[uuid:{0}]可能已经被删除 - -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2749 -# args: self.getUuid(),JSONObjectUtil.toJsonString(errorCodes) -unable\ to\ connect\ to\ the\ ceph\ primary\ storage[uuid\:%s].\ Failed\ to\ connect\ all\ ceph\ mons.\ Errors\ are\ %s = 无法连接到ceph主存储[uuid:{0}]。所有监控节点均连接失败。错误是{1} +ceph\ primary\ storage[uuid\:%s]\ may\ have\ been\ deleted. = 分布式存储[uuid:{0}]可能已经被删除 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2746 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3394 # args: self.getUuid() -unable\ to\ connect\ to\ the\ ceph\ primary\ storage[uuid\:%s].\ Failed\ to\ connect\ all\ ceph\ mons. = 未能连接ceph主存储[uuid:{0}],连接所有的ceph mons失败 +unable\ to\ connect\ to\ the\ ceph\ primary\ storage[uuid\:%s],\ failed\ to\ connect\ all\ ceph\ monitors. = 无法连接到分布式存储[uuid:{0}],所有监控节点均连接失败 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2866 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3507 # args: the\ fsid\ returned\ by\ mons\ are\ mismatching,\ it\ seems\ the\ mons\ belong\ to\ different\ ceph\ clusters\:\n = 监控节点返回的fsid不匹配,似乎监控节点属于不同的ceph集群 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:2884 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3525 # args: otherCeph.getName(),otherCeph.getUuid(),fsId -there\ is\ another\ CEPH\ primary\ storage[name\:%s,\ uuid\:%s]\ with\ the\ same\ FSID[%s],\ you\ cannot\ add\ the\ same\ CEPH\ setup\ as\ two\ different\ primary\ storage = 有另外一个CEPH主存储[name:{0}, uuid:{1}] 有相同的 FSID[{2}],你不能添加相同的CEPH设置到两个不同的主存储 +there\ is\ another\ CEPH\ primary\ storage[name\:%s,\ uuid\:%s]\ with\ the\ same\ FSID[%s],\ you\ cannot\ add\ the\ same\ CEPH\ setup\ as\ two\ different\ primary\ storage = 有另外一个分布式存储[name:{0}, uuid:{1}] 有相同的 FSID[{2}],你不能添加相同的CEPH设置到两个不同的主存储 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3135 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3783 # args: self.getUuid(),self.getName(),mon.getSelf().getUuid(),res.error -the\ ceph\ primary\ storage[uuid\:%s,\ name\:%s]\ is\ down,\ as\ one\ mon[uuid\:%s]\ reports\ an\ operation\ failure[%s] = ceph主存储[uuid:{0}, name:{1}]关闭,因为一个mon[uuid:{2}]报告了一个操作失败[{3}] +the\ ceph\ primary\ storage[uuid\:%s,\ name\:%s]\ is\ down,\ as\ one\ mon[uuid\:%s]\ reports\ an\ operation\ failure[%s] = 分布式存储[uuid:{0}, name:{1}]关闭,因为一个mon[uuid:{2}]报告了一个操作失败[{3}] -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3736 -# args: bsType -unable\ to\ upload\ bits\ to\ the\ backup\ storage[type\:%s],\ we\ only\ support\ CEPH = 不能上传bits到镜像服务器[type:{0}],目前只支持CEPH +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4697 +# args: +operation\ error,\ because\:\ failed\ to\ get\ response = 操作错误,原因:无法获取响应 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3910 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4744 +# args: +backing\ up\ snapshots\ to\ backup\ storage\ is\ a\ depreciated\ feature,\ which\ will\ be\ removed\ in\ future\ version = 将快照备份到备份存储是一项过时的功能,在未来版本中将被删除 + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4915 # args: volume.getUuid(),volume.getRootImageUuid() -cannot\ reinit\ rootvolume\ [%s]\ because\ image\ [%s]\ has\ been\ deleted\ and\ imagecache\ cannot\ be\ found = +cannot\ reinit\ rootvolume\ [%s]\ because\ image\ [%s]\ has\ been\ deleted\ and\ imagecache\ cannot\ be\ found = 无法重新初始化RootVolume[{0}],因为镜像[{1}]已被删除并且找不到ImageCache -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:3929 -# args: volume.getRootImageUuid(),getSelf().getUuid() -cannot\ find\ backupstorage\ to\ download\ image\ [%s]\ to\ primarystorage\ [%s] = +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4950 +# args: ImageStatus.Ready.toString() +Because\ image\ status\ is\ not\ %s = 因为镜像状态不是{0} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:457 -# args: vol.getPrimaryStorageUuid() -cannot\ find\ any\ Connected\ ceph\ mon\ for\ the\ primary\ storage[uuid\:%s] = 无法为Ceph主存储[uuid:{0}]找到一台处于Connected状态的的监控节点 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4947 +# args: +Because\ the\ image\ is\ currently\ inaccessible,\ possibly\ due\ to\ a\ previous\ volume\ storage\ migration = 因为镜像当前不可访问,可能是由于之前的卷存储迁移 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:758 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:4953 +# args: volume.getRootImageUuid(),getSelf().getUuid(),cause +cannot\ find\ backupstorage\ to\ download\ image\ [%s]\ to\ primarystorage\ [%s].\ %s = 找不到用于将镜像[{0}]下载到主存储[{1}]的备份存储。{2} + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:5653 # args: -not\ support\ take\ volumes\ snapshots\ on\ multiple\ ps\ when\ including\ ceph = +allocated\ url\ not\ found = 未找到分配的URL + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java:5658 +# args: allocatedUrl +invalid\ allocated\ url\:%s = 分配的URL无效:{0} + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:396 +# args: vol.getPrimaryStorageUuid() +cannot\ find\ any\ Connected\ ceph\ mon\ for\ the\ primary\ storage[uuid\:%s] = 无法为分布式存储[uuid:{0}]找到一台处于Connected状态的的监控节点 -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:853 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:838 # args: targetCephPoolName,cephPoolName -ceph\ pool\ conflict,\ the\ ceph\ pool\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ ceph\ pool\ specified\ in\ the\ creation\ parameter\ is\ %s = +ceph\ pool\ conflict,\ the\ ceph\ pool\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ ceph\ pool\ specified\ in\ the\ creation\ parameter\ is\ %s = Ceph池冲突,由实例提供的Ceph池指定为{0},而在创建参数中指定的Ceph池为{1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:984 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:964 # args: targetCephPoolName,cephPoolName -ceph\ pool\ conflict,\ the\ ceph\ pool\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ ceph\ pool\ specified\ in\ the\ creation\ parameter\ is\ %s = +ceph\ pool\ conflict,\ the\ ceph\ pool\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ ceph\ pool\ specified\ in\ the\ creation\ parameter\ is\ %s = Ceph池冲突,磁盘产品指定的Ceph池为{0},而创建参数中指定的Ceph池为{1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1203 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1217 # args: rootVolume.getInstallPath(),reply.getError().getDetails() -get\ rootVolume[%s]\ rbd\ image\ watchers\ fail,\ %s = 查询根云盘[{0}] rbd image watchers失败,{1} +get\ rootVolume[%s]\ rbd\ image\ watchers\ fail,\ %s = 查询云盘[{0}] rbd image watchers失败,{1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1219 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1233 # args: msg.getVolumeUuid(),installPath -rootVolume[%s]\ is\ already\ in\ use(ceph\ rbd\ image[%s]\ already\ has\ watchers),\ in\ order\ to\ prevent\ brain\ splitting,\ Starting\ VM\ is\ prohibited. = 根云盘[{0}]正在使用中(ceph rbd 镜像[{1}]存在watchers),为了防止云主机脑裂,禁止启动云主机 +rootVolume[%s]\ is\ already\ in\ use(ceph\ rbd\ image[%s]\ already\ has\ watchers),\ in\ order\ to\ prevent\ brain\ splitting,\ Starting\ VM\ is\ prohibited. = 云盘[{0}]正在使用中(ceph rbd 镜像[{1}]存在watchers),为了防止云主机脑裂,禁止启动云主机 + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1341 +# args: poolName +cannot\ find\ cephPrimaryStorage\ pool[poolName\=%s] = 找不到CephPrimaryStorage池[PoolName={0}] + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1351 +# args: poolName,volumeSize +cephPrimaryStorage\ pool[poolName\=%s]\ available\ virtual\ capacity\ not\ enough\ for\ size\ %s = CephPrimary存储池[PoolName={0}]可用虚拟容量不足,无法满足大小{1} + +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java:1399 +# args: psUuid,purpose +cannot\ allocate\ pool\ for\ primaryStorage[%s],\ purpose\:\ %s = 无法为主存储[{0}]分配池,目的:{1} -# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java:92 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java:93 # args: uuid cannot\ update\ status\ of\ the\ ceph\ primary\ storage\ mon[uuid\:%s],\ it\ has\ been\ deleted.This\ error\ can\ be\ ignored = 不能更新一台已经被删除的Ceph主存储监控节点[uuid:{0}],这个错误可被忽略 +# at: src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java:471 +# args: primaryStorageUuid +Ceph\ ps[uuid\=%s]\ root\ pool\ name\ not\ found = 找不到Ceph PS[uuid={0}]根池名称 + +# at: src/main/java/org/zstack/storage/ceph/primary/CephRequiredUrlParser.java:32 +# args: +invalid\ uri,\ correct\ example\ is\ ceph\://$POOLNAME/$VOLUMEuuid\ or\ volume\://$VOLUMEuuid = URI无效,正确示例为ceph://$poolName/$volumeUuid或volume://$volumeUuid + +# at: src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java:19 +# args: +Can\ not\ attach\ third-party\ ceph\ with\ token\ into\ kvm\ cluster. = 无法使用令牌将第三方Ceph连接到KVM集群。 + +# at: src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java:168 +# args: poolUuid,size,originAvailableCapacity +required\ ceph\ pool[uuid\:%s]\ cannot\ satisfy\ conditions\ [availableSize\ >\ %s\ bytes],\ current\ available\ size\ %s = 所需的Ceph池[uuid:{0}]无法满足条件[AvailableSize>{1}字节],当前可用大小{2} + +# at: src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java:196 +# args: poolUuid +cannot\ find\ ceph\ pool\ [%s]\ related\ osdgroup = 找不到Ceph池[{0}]相关的OSDGroup + +# at: src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java:95 +# args: +no\ candidate\ host\ with\ the\ scsi\ lun\ with\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = 需要的lun所在的物理机都不满足cpu / memory 以及物理机状态的条件 + # at: src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java:54 # args: firstScsiLunVO.getUuid(),scsiLunVO.getUuid() -scsi\ lun[uuid\:\ %s]\ and\ [uuid\:\ %s]\ does\ not\ has\ a\ common\ host = +scsi\ lun[uuid\:\ %s]\ and\ [uuid\:\ %s]\ does\ not\ has\ a\ common\ host = SCSI Lun[uuid:{0}]和[uuid:{1}]没有共同的物理机 # at: src/main/java/org/zstack/storage/device/ScsiLunAllocatorFactory.java:59 # args: scsiLunVO.getUuid() -scsi\ lun[uuid\:\ %s]\ is\ in\ disabled\ state = +scsi\ lun[uuid\:\ %s]\ is\ in\ disabled\ state = SCSI Lun[uuid:{0}]处于禁用状态 + +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:150 +# args: scsiLunVO.getWwid(),refVO.getVmInstanceUuid() +scsi\ lun[wwid\:\ %s]\ has\ been\ attached\ to\ vm\ instance\ %s = SCSI Lun[WWID:{0}]已连接到VM实例{1} -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:62 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:86 # args: msg.getIp(),msg.getPort() -iSCSI\ server[ip\:\ %s,\ port\:\ %s]\ already\ exists = +iSCSI\ server[ip\:\ %s,\ port\:\ %s]\ already\ exists = iSCSI服务器[IP:{0},端口:{1}]已存在 -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:67 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:91 # args: msg.getIp() -iSCSI\ server\ ip\:\ %s\ is\ not\ valid = +iSCSI\ server\ ip\:\ %s\ is\ not\ valid = iSCSI服务器IP:{0}无效 -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:76 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:100 # args: msg.getUuid(),msg.getClusterUuid() -iSCSI\ server[uuid\:\ %s]\ already\ attached\ to\ cluster[uuid\:\ %s] = +iSCSI\ server[uuid\:\ %s]\ already\ attached\ to\ cluster[uuid\:\ %s] = iSCSI服务器[uuid:{0}]已连接到集群[uuid:{1}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:86 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:110 # args: msg.getUuid(),msg.getClusterUuid() -iSCSI\ server[uuid\:\ %s]\ not\ attached\ to\ cluster[uuid\:\ %s] = +iSCSI\ server[uuid\:\ %s]\ not\ attached\ to\ cluster[uuid\:\ %s] = iSCSI服务器[uuid:{0}]未连接到集群[uuid:{1}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:97 +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:121 # args: msg.getUuid(),clusterUuid -iSCSI\ server[uuid\:\ %s]\ still\ attached\ to\ cluster[uuid\:\ %s] = +iSCSI\ server[uuid\:\ %s]\ still\ attached\ to\ cluster[uuid\:\ %s] = iSCSI服务器[uuid:{0}]仍连接到集群[uuid:{1}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:126 -# args: scsiLunVO.getWwid(),refVO.getVmInstanceUuid() -scsi\ lun[wwid\:\ %s]\ has\ been\ attached\ to\ vm\ instance\ %s = +# at: src/main/java/org/zstack/storage/device/StorageDeviceApiInterceptor.java:171 +# args: VmInstanceUuid +please\ umount\ all\ block\ devices\ of\ the\ vm[%s]\ and\ try\ again = 请卸载云主机[{0}]的所有块设备,然后重试 -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1188 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1501 +# args: lunVO.getWwid(),msg.getVmInstanceUuid() +scsi\ lun[wwid\:%s]\ has\ been\ attached\ into\ the\ vm[%s] = SCSI Lun[WWID:{0}]已连接到云主机[{1}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1508 # args: msg.getUuid(),vmInstanceVO.getState(),allowedVmOperationStates -vm\ instance[%s]\ state\ [%s]\ not\ in\ allowed\ state[%s]\ for\ operation = +vm\ instance[%s]\ state\ [%s]\ not\ in\ allowed\ state[%s]\ for\ operation = VM实例[{0}]状态[{1}]不处于操作的允许状态[{2}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1197 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1517 # args: msg.getUuid(),vmInstanceVO.getHostUuid(),msg.getUuid() -vm\ instance[uuid\:\ %s]\ host[uuid\:\ %s]\ not\ attached\ scsi\ lun[uuid\:\ %s] = +vm\ instance[uuid\:\ %s]\ host[uuid\:\ %s]\ not\ attached\ scsi\ lun[uuid\:\ %s] = 云主机实例[uuid:{0}]物理机[uuid:{1}]未连接scsi lun[uuid:{2}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1256 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1576 # args: msg.getVmInstanceUuid(),vmInstanceVO.getState(),allowedVmOperationStates -vm\ instance[%s]\ state[%s]\ not\ in\ allowed\ state[%s]\ for\ operation = +vm\ instance[%s]\ state[%s]\ not\ in\ allowed\ state[%s]\ for\ operation = VM实例[{0}]状态[{1}]不处于操作的允许状态[{2}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1265 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1585 # args: msg.getVmInstanceUuid(),hostVO.getUuid(),msg.getUuid() -vm\ instance[%s]\ host[uuid\:\ %s]\ not\ attached\ scsi\ lun[uuid\:\ %s] = +vm\ instance[%s]\ host[uuid\:\ %s]\ not\ attached\ scsi\ lun[uuid\:\ %s] = 云主机实例[{0}]物理机[uuid:{1}]未连接SCSI Lun[uuid:{2}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1738 +# args: msg.getUuid(),vmUuids +SCSI\ LUN[%s]\ is\ attached\ to\ VM\ [%s] = SCSI Lun[{0}]已连接到云主机[{1}] + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1748 +# args: msg.getUuid(),msg.getHostUuid() +SCSI\ LUN[%s]\ record\ not\ found\ on\ host\ [%s] = 在物理机[{1}]上未找到SCSI Lun[{0}]记录 + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1760 +# args: hvType,msg.getHostUuid() +unexpected\ hypervisor\ type[%s]\ for\ host\ [%s] = 物理机[{1}]的意外云主机监控程序类型[{0}] -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1447 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:2024 +# args: serial +different\ disk\ types\ are\ found\ in\ different\ hosts\ for\ lun[serial\:%s],\ unable\ to\ attach\ it\ to\ cluster = 在不同的物理机中为Lun[serial:{0}]找到不同的磁盘类型,无法将其连接到集群 + +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:1975 # args: scannedServer.getKey(),JSONObjectUtil.toJsonString(scannedTargets),hostVO.getUuid(),JSONObjectUtil.toJsonString(returnValue.getIscsiTargets()) -different\ iscsi\ configuration\ were\ found\ on\ host[uuid\:%s,\ targets\:%s]and\ host[uuid\:%s,\ targets\:%s] = +different\ iscsi\ configuration\ were\ found\ on\ host[uuid\:%s,\ targets\:%s]and\ host[uuid\:%s,\ targets\:%s] = 在物理机[uuid:{0},目标:{1}]和物理机[uuid:{2},目标:{3}]上找到不同的iSCSI配置 -# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:2055 +# at: src/main/java/org/zstack/storage/device/StorageDeviceManagerImpl.java:2661 # args: refVO.getScsiLunUuid() -specified\ scsi\ lun[wwid\:\ %s]\ not\ exists\ or\ disabled = +specified\ scsi\ lun[wwid\:\ %s]\ not\ exists\ or\ disabled = 指定的SCSI Lun[WWID:{0}]不存在或已禁用 + +# at: src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java:60 +# args: msg.getVolumeUuid() +the\ vm\ where\ the\ data\ volume\ [%s]\ is\ located\ has\ a\ memory\ snapshot,\ can't\ delete = 数据云盘[{0}]所在的云主机具有内存快照,无法删除 + +# at: src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java:71 +# args: msg.getVolumeUuid(),msg.getVmInstanceUuid() +unable\ to\ attach\ volume\ %s\ to\ vmInstance\ %s\ with\ memory\ snapshot\ group = 无法使用内存快照组将卷{0}附加到VMInstance{1} -# at: src/main/java/org/zstack/storage/migration/KvmStorageLiveMigrationFlowChain.java:256 +# at: src/main/java/org/zstack/storage/memorySnapshot/MemorySnapshotGroupValidator.java:78 +# args: msg.getVolumeUuid() +the\ vm\ where\ the\ data\ volume\ [%s]\ is\ located\ has\ a\ memory\ snapshot,\ can't\ detach = 数据云盘[{0}]所在的VM具有内存快照,无法分离 + +# at: src/main/java/org/zstack/storage/memorySnapshot/VmNicMemorySnapshotGroupExtension.java:60 # args: -No\ host\ available\ for\ block\ live\ migration = +defaultL3NetworkUuid\ not\ exist = defaultL3NetworkUuid不存在 + +# at: src/main/java/org/zstack/storage/memorySnapshot/VmNicMemorySnapshotGroupExtension.java:432 +# args: l3Uuid,String.join("','", memorySnapshotGroupUuidList) +nic\ with\ l3\ network[uuid\:\ %s]\ is\ referenced\ by\ VolumeSnapshotGroup[uuid\:\ %s],\ delete\ this\ VolumeSnapshotGroup\ before\ deleting\ this\ l3\ network. = 具有三层网络[uuid:{0}]的NIC由卷SnapshotGroup[uuid:{1}]引用,请在删除此三层网络之前删除此卷SnapshotGroup。 + +# at: src/main/java/org/zstack/storage/memorySnapshot/VolumeMemorySnapshotGroupExtension.java:155 +# args: archiveVolume.getResourceUuid() +the\ volume\ %s\ does\ not\ exist = 卷{0}不存在 -# at: src/main/java/org/zstack/storage/migration/KvmStorageLiveMigrationFlowChain.java:494 +# at: src/main/java/org/zstack/storage/migration/KvmBlockLiveMigrationWorkFlow.java:161 # args: rsp.getError() -live\ block\ migration\ failed\:\ %s = +vm\ block\ migrate\ failed\:\ %s = VM块迁移失败:{0} + +# at: src/main/java/org/zstack/storage/migration/KvmBlockLiveMigrationWorkFlow.java:188 +# args: +target\ primary\ storage\ does\ not\ support\ migration\ for\ current\ host = 目标主存储不支持当前物理机的迁移 + +# at: src/main/java/org/zstack/storage/migration/KvmMigrateVmWithStorageWorkFlow.java:116 +# args: +No\ host\ available\ for\ block\ live\ migration = 没有可用于数据块实时迁移的物理机 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:123 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:121 # args: -do\ not\ support\ storage\ migration\ with\ iso\ in\ ceph\ backup\ storage\ attached = +do\ not\ support\ storage\ migration\ with\ iso\ in\ ceph\ backup\ storage\ attached = 不支持Ceph备份存储中附加ISO的存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:292 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:289 # args: srcVm.getUuid(),srcVm.getName() -do\ not\ support\ storage\ migration\ of\ vm[uuid\:%s,\ name\:\ %s]\ while\ shared\ volume\ attached = +do\ not\ support\ storage\ migration\ of\ vm[uuid\:%s,\ name\:\ %s]\ while\ shared\ volume\ attached = 连接共享云盘时,不支持VM[uuid:{0},名称:{1}]的存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:175 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:173 # args: srcPsType,dstPsType do\ not\ support\ storage\ migration\ from\ [%s]\ to\ [%s]\ with\ data\ volume = 不支持从[{0}]到[{1}]的带数据盘的存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:180 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:178 # args: srcPsType,dstPsType do\ not\ support\ storage\ migration\ from\ [%s]\ to\ [%s]\ with\ snapshot = 不支持从[{0}]到[{1}]的存在云盘快照的存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:188 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:185 # args: primaryStorageVO.getType(),dstPrimaryStorageVO.getType() do\ not\ support\ storage\ migration\ from\ [%s]\ to\ [%s] = 不支持从[{0}]到[{1}]的存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:194 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:191 # args: vmInstanceVO.getUuid() -VM[uuid\:%s]\ is\ running\ but\ host\ uuid\ is\ missing = +VM[uuid\:%s]\ is\ running\ but\ host\ uuid\ is\ missing = 云主机[uuid:{0}]正在运行,但缺少物理机uuid -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:205 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:202 # args: Source\ BS\ and\ Destination\ BS\ cannot\ be\ the\ same. = 源镜像服务器和目标镜像服务器不能相同 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:213 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:210 # args: Source\ BS\ and\ Destination\ BS\ must\ not\ be\ Disabled. = 源镜像服务器和目标镜像服务器必须不是不可用。 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:220 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:217 # args: msg.getImageUuid() Image[uuid\:%s]\ is\ not\ in\ status\ Ready,\ cannot\ migrate\ it. = 镜像[uuid:{0}]的状态不是已准备,不能迁移它 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:231 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:228 # args: msg.getImageUuid(),msg.getSrcBackupStorageUuid() Image[uuid\:%s]\ is\ not\ in\ source\ backup\ storage[uuid\:%s] = 镜像[uuid:{0}]没有在源镜像服务器[uuid:{1}] -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:240 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:237 # args: srcBS.getType(),dstBS.getType() Cannot\ migrate\ image\ from\ %s\ to\ %s. = 不能从{0}迁移镜像到{1} -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:260 -# args: -Source\ PS\ and\ Destination\ PS\ must\ not\ be\ Disabled\ or\ Maintenance\ state. = 源主存储和目标主存储必须不是不可用或者维护状态。 - -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:267 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:256 # args: msg.getVolumeUuid(),msg.getDstPrimaryStorageUuid() Volume[uuid\:%s]\ is\ already\ in\ PS[uuid\:%s],\ cannot\ migrate. = 云盘[uuid:{0}]已经在主存储[uuid:{1}]里,不能迁移。 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:274 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:264 +# args: +Source\ PS\ and\ Destination\ PS\ must\ not\ be\ Disabled\ or\ Maintenance\ state. = 源主存储和目标主存储必须不是不可用或者维护状态。 + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:271 # args: msg.getVolumeUuid() Volume[uuid\:%s]\ is\ not\ in\ status\ Ready,\ cannot\ migrate\ it. = 云盘[uuid:{0}]状态不是已准备,不能进行迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:330 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:333 +# args: msg.getVolumeUuid(),srcVolume.getVmInstanceUuid() +cannot\ migrate\ data\ volume[uuid\:%s]\ bewteen\ sharedblock\ primary\ storages\ when\ vm[vmuuid\:%s]\ instance\ is\ not\ stopped. = VM[vmuuid:{1}]实例未停止时,无法在SharedBlock主存储之间迁移数据云盘[uuid:{0}]。 + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:328 # args: msg.getVolumeUuid(),srcVolume.getVmInstanceUuid() -the\ volume[uuid\:%s]\ is\ still\ attached\ on\ vm[uuid\:%s],\ please\ detach\ it\ before\ migration. = 云盘[uuid:{0}]一直连接在虚拟机[uuid:{1}],在迁移之前请先断开连接 +the\ volume[uuid\:%s]\ is\ still\ attached\ on\ vm[uuid\:%s],\ please\ detach\ it\ before\ migration. = 云盘[uuid:{0}]一直连接在云主机[uuid:{1}],在迁移之前请先断开连接 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:338 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:341 # args: srcVolume.getUuid(),srcVolume.getName() do\ not\ support\ storage\ migration\ while\ shared\ volume[uuid\:\ %s,\ name\:\ %s]\ attached = 加载了共享云盘[uuid:{0}, name:{1}]不支持存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:287 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:284 # args: -Cannot\ migrate\ root\ volume\ when\ vm\ instance\ is\ not\ stopped. = 当虚拟机不是已停止,不能迁移根云盘。 +Cannot\ migrate\ root\ volume\ when\ vm\ instance\ is\ not\ stopped. = 当云主机不是已停止,不能迁移云盘。 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:304 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:301 # args: -Cannot\ migrate\ root\ volume\ when\ there\ are\ data\ volumes\ attached\ to\ the\ vm\ instance. = 当数据云盘连接在虚拟机上时,不能迁移根云盘 +Cannot\ migrate\ root\ volume\ when\ there\ are\ data\ volumes\ attached\ to\ the\ vm\ instance. = 当云盘连接在云主机上时,不能迁移云盘 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:323 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:320 # args: The\ destination\ primary\ storage\ is\ not\ attached\ to\ any\ cluster\ that\ has\ the\ same\ L2\ networks\ as\ source\ cluster. = 目标主存储不能连接任何和源集群一样的二层网络的集群 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:348 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:351 # args: srcPS.getType(),dstPS.getType() Cannot\ migrate\ volume\ from\ %s\ to\ %s. = 不能从{0}迁移云盘到{1} -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:531 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationApiInterceptor.java:372 +# args: msg.getVolumeUuid() +can\ not\ migrate\ volume[%s],\ because\ volume\ state\ is\ Disabled = 无法迁移卷[{0}],因为卷状态已禁用 + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:510 # args: vmInstanceVO.getState() -not\ support\ vm\ state[%s]\ to\ do\ storage\ migration = 虚拟机状态为[{0}],无法进行存储迁移 +not\ support\ vm\ state[%s]\ to\ do\ storage\ migration = 云主机状态为[{0}],无法进行存储迁移 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:472 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:448 # args: msg.getVmInstanceUuid(),size,dstPrimaryStorageVO.getCapacity().getAvailablePhysicalCapacity() -there\ are\ not\ enough\ capacity\ for\ vm[uuid\:\ %s]\ storage\ migration,\ required\ capacity(include\ image\ cache)\:\ %s,\ current\ available\ physical\ capacity\:\ %s = 对虚拟机[uuid: {0}]存储迁移需要目标主存储具有至少{1}的空余容量(容量计算包含镜像cache),但现在只有{2}的空余容量 +there\ are\ not\ enough\ capacity\ for\ vm[uuid\:\ %s]\ storage\ migration,\ required\ capacity(include\ image\ cache)\:\ %s,\ current\ available\ physical\ capacity\:\ %s = 对云主机[uuid: {0}]存储迁移需要目标主存储具有至少{1}的空余容量(容量计算包含镜像cache),但现在只有{2}的空余容量 -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:582 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1125 # args: msg.getVmInstanceUuid() -VM[uuid\:\ %s]\ not\ found = +VM[uuid\:\ %s]\ not\ found = 找不到VM[uuid:{0}] -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:815 -# args: srcPs.getType() -unsupported\ primary\ storage\ type[%s]\ for\ storage\ migration = 当前存储[类型:{0}],不支持存储迁移 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:846 +# args: srcPs.getType(),dstPs.getType() +unsupported\ storage\ migration\ type\:\ from\ %s\ to\ %s = 不支持的存储迁移类型:从{0}到{1} -# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1001 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1094 # args: msg.getType() -not\ support\ to\ cancel\ %s = +not\ support\ to\ cancel\ %s = 不支持取消{0} + +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1194 +# args: vmInstanceVO.getState() +not\ support\ vm\ state[%s]\ to\ do\ cancellation\ of\ storage\ migration = 不支持云主机状态[{0}]取消存储迁移 -# at: src/main/java/org/zstack/storage/migration/backup/ReserveCapacityFromDstBSFlow.java:61 -# args: imageUuid,dstBsUuid -Cannot\ reserve\ enough\ space\ for\ Image[uuid\:%s]\ in\ BS[uuid\:%s] = 不能在镜像服务器[uuid:{1}]上为镜像[uuid:{0}]预留足够的空间 +# at: src/main/java/org/zstack/storage/migration/StorageMigrationBase.java:1514 +# args: +failed\ to\ get\ host\ candidates\ for\ vm\ migration = 无法获取云主机迁移的候选物理机 # at: src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java:114 # args: dstBsVO.getUuid() -all\ ceph\ mons\ are\ Disconnected\ in\ ceph\ backup\ storage[uuid\:%s] = 所有在ceph镜像服务器[uuid:{0}]的监控节点都处于失联状态 +all\ ceph\ mons\ are\ Disconnected\ in\ ceph\ backup\ storage[uuid\:%s] = 所有在Ceph镜像服务器监控节点[uuid:{0}]的监控节点都处于失联状态 # at: src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java:187 # args: imageUuid,srcBsUuid,dstBsUuid,errCode.getDetails() -Failed\ to\ migrate\ Image\ %s\ from\ BS\ %s\ to\ BS\ %s.\ cause\:\ %s = +Failed\ to\ migrate\ Image\ %s\ from\ BS\ %s\ to\ BS\ %s.\ cause\:\ %s = 无法将镜像{0}从BS{1}迁移到BS{2}。原因:{3} # at: src/main/java/org/zstack/storage/migration/backup/ceph/CephToCephMigrateImageFlow.java:143 # args: reply1.getTrashId(),dstBsUuid,dstImageInstallPath,reply1.getResourceUuid() found\ trashId(%s)\ in\ BackupStorage\ [%s]\ for\ the\ migrate\ installPath[%s].\ Please\ clean\ it\ first\ by\ 'APICleanUpTrashOnBackupStorageMsg'\ if\ you\ insist\ to\ migrate\ the\ image[%s] = 在备份存储[{1}]的回收数据({0})中己存在要迁移的目标路径[{2}],如果要继续迁移镜像[{3}],请先调用'APICleanUpTrashOnBackupStorageMsg'来手动清理该回收数据 -# at: src/main/java/org/zstack/storage/migration/primary/ReserveCapacityFromDstPSFlow.java:85 -# args: volumeUuid,dstPsUuid -Cannot\ reserve\ enough\ space\ for\ Volume[uuid\:%s]\ in\ PS[uuid\:%s] = 不能在主存储[uuid:{1}]为云盘[uuid:{0}]预留足够的空间 - -# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:120 -# args: dstPsVO.getUuid() -all\ ceph\ mons\ are\ Disconnected\ in\ ceph\ primary\ storage[uuid\:%s] = 所有的ceph mons无法连接到主存储[uuid:{0}] +# at: src/main/java/org/zstack/storage/migration/primary/PrimaryStorageMigrateVmJob.java:141 +# args: amsg.getVmInstanceUuid(),job.getUuid() +vm[uuid\:%s]\ storage\ migration\ long\ job[uuid\:%s]\ failed\ because\ management\ node\ was\ restarted = 云主机[uuid:{0}]存储迁移长作业[uuid:{1}]失败,因为管理节点已重新启动 -# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:571 +# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:584 # args: volume.getType() -The\ type\ [%s]\ of\ volume\ is\ invalid. = +The\ type\ [%s]\ of\ volume\ is\ invalid. = 卷的类型[{0}]无效。 + +# at: src/main/java/org/zstack/storage/migration/primary/ceph/CephToCephMigrateVolumeFlow.java:122 +# args: dstPsVO.getUuid() +all\ ceph\ mons\ are\ Disconnected\ in\ ceph\ primary\ storage[uuid\:%s] = 所有Ceph MON都在分布式存储[uuid:{0}]中断开连接 -# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:88 +# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:89 # args: cannot\ find\ any\ connected\ host\ to\ perform\ the\ storage\ migration\ operation = 为了执行存储迁移操作,未找到连接的物理机 -# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:187 +# at: src/main/java/org/zstack/storage/migration/primary/nfs/NfsToNfsMigrateVolumeFlow.java:194 # args: imageUuid -both\ image\ %s\ and\ its\ cache\ is\ missing = +both\ image\ %s\ and\ its\ cache\ is\ missing = 缺少镜像{0}及其缓存 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:189 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:203 # args: -'resourceUuid'\ and\ 'resourceType'\ must\ be\ set\ both\ or\ neither! = +'resourceUuid'\ and\ 'resourceType'\ must\ be\ set\ both\ or\ neither! = “ resourceUuid ”和“ resourceType ”必须同时设置或都不设置! -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:85 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:92 # args: -zoneUuids,\ clusterUuids,\ primaryStorageUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = 区域、集群、主存储的Uuids中必须至少有一个不为空列表,除非将字段 all 设为 true +zoneUuids,\ clusterUuids,\ primaryStorageUuids\ must\ have\ at\ least\ one\ be\ none-empty\ list,\ or\ all\ is\ set\ to\ true = zoneUuids、clusterUuids、primaryStorageUuids中必须至少有一个不为空列表,除非将字段 all 设为 true -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:107 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:114 # args: msg.getPrimaryStorageUuid(),msg.getClusterUuid() primary\ storage[uuid\:%s]\ has\ not\ been\ attached\ to\ cluster[uuid\:%s]\ yet = 主存储[uuid:{0}]还未加载到集群[uuid:{1}]上 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:124 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:131 # args: msg.getPrimaryStorageUuid(),msg.getClusterUuid() primary\ storage[uuid\:%s]\ has\ been\ attached\ to\ cluster[uuid\:%s] = 主存储[uuid:{0}]已被加载到集群[uuid:{1}]上 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:139 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:146 # args: msg.getPrimaryStorageUuid(),msg.getClusterUuid() primary\ storage[uuid\:%s]\ and\ cluster[uuid\:%s]\ are\ not\ in\ the\ same\ zone = 主存储[uuid:{0}]和集群[uuid:{1}]不在同一个区域内 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:161 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:168 # args: url url[%s]\ has\ been\ occupied,\ it\ cannot\ be\ duplicate\ in\ same\ cluster = url[{0}]已经被占用,在相同的集群里它不能再次使用 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:181 -# args: msg.getPrimaryStorageUuid(),clusterUuidsString -primary\ storage[uuid\:%s]\ cannot\ be\ deleted\ for\ still\ being\ attached\ to\ cluster[uuid\:%s]. = 不能删除主存储[uuid:{0}],因为它还被加载在集群[uuid:{1}]上 - -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:206 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageApiInterceptor.java:220 # args: psUuids -primary\ storage(s)\ [uuid\:\ %s]\ where\ volume(s)\ locate\ is\ not\ Enabled\ or\ Connected = +primary\ storage(s)\ [uuid\:\ %s]\ where\ volume(s)\ locate\ is\ not\ Enabled\ or\ Connected = 卷所在的主存储[uuid:{0}]未启用或未连接 # at: src/main/java/org/zstack/storage/primary/PrimaryStorageAvoidAllocatorFlow.java:50 # args: spec.getAvoidPrimaryStorageUuids() after\ removing\ primary\ storage%s\ to\ avoid,\ there\ is\ no\ candidate\ primary\ storage\ anymore.\ please\ check\ primary\ storage\ status\ and\ state\ in\ the\ cluster. = 把主存储{0}移到排除列表后,就没有可用的主存储了,请确认集群中主存储的状态 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:221 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:239 # args: self.getUuid() -cannot\ attach\ ISO\ to\ a\ primary\ storage[uuid\:%s]\ which\ is\ disabled = +cannot\ attach\ ISO\ to\ a\ primary\ storage[uuid\:%s]\ which\ is\ disabled = 无法将ISO附加到已禁用的主存储[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:657 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:769 # args: bsUuid,self.getZoneUuid(),self.getUuid() backup\ storage[uuid\:%s]\ is\ not\ attached\ to\ zone[uuid\:%s]\ the\ primary\ storage[uuid\:%s]\ belongs\ to = 镜像服务器[uuid:{0}]没有加载到主存储[uuid:{2}]所在的区域[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:781 -# args: -operation\ not\ supported = 不支持的操作 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:789 +# args: volUuid,vmState +volume[uuid\:%s]\ has\ been\ attached\ a\ %s\ VM.\ VM\ should\ be\ Stopped. = 卷[uuid:{0}]已连接到{1}云主机。应停止云主机。 + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:1602 +# args: self.getUuid(),clusterUuidsString +primary\ storage[uuid\:%s]\ cannot\ be\ deleted\ for\ still\ being\ attached\ to\ cluster[uuid\:%s]. = 不能删除主存储[uuid:{0}],因为它还被加载在集群[uuid:{1}]上 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:1558 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageBase.java:1749 # args: volumeUuid cannot\ attach\ volume[uuid\:%s]\ whose\ primary\ storage\ is\ Maintenance = 无法挂载云盘[uuid:{0}],其主存储处于维护模式 @@ -7274,41 +11750,45 @@ cannot\ reserve\ %s\ bytes\ on\ the\ primary\ storage[uuid\:%s],\ it's\ short\ o # args: ps.getUuid(),ps.getStatus().toString() the\ primary\ storage[uuid\:%s]\ is\ not\ in\ status\ of\ Connected,\ current\ status\ is\ %s = 主存储[uuid:{0}]的状态不是已连接,当前的状态是{1} -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:115 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageMainAllocatorFlow.java:225 +# args: spec.getImageUuid() +no\ way\ to\ get\ image\ size\ of\ %s,\ report\ exception. = 无法获取{0}的镜像大小,报告异常。 + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:106 # args: systemTag,uuid %s\ is\ invalid.\ %s\ is\ not\ a\ valid\ zstack\ uuid = {0}是无效的,{1}不是一个有效的ZStack uuid -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:119 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:110 # args: resourceUuid no\ primary\ storage[uuid\:%s]\ found = 找不到主存储[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:147 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:138 # args: msg.getUuid() -primaryStorage[uuid\=%s]\ does\ not\ exist = +primaryStorage[uuid\=%s]\ does\ not\ exist = PrimaryStorage[uuid={0}]不存在 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:482 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:492 +# args: +please\ specify\ the\ purpose\ before\ allocating\ space = 请在分配空间之前指定用途 + +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:614 # args: errs cannot\ find\ any\ qualified\ primary\ storage,\ errors\ are\ %s = 找不到可用的主存储,错误为:{0} -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:558 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:833 # args: cidr -cidr[%s]\ Input\ Format\ Error = +cidr[%s]\ Input\ Format\ Error = CIDR[{0}]输入格式错误 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:554 +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:829 # args: cidrCount -only\ one\ primaryStorage\ cidr\ system\ tag\ is\ allowed,\ but\ %d\ got = - -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:903 -# args: psUuid,msg.getPrimaryStorageUuidForRootVolume() -primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = +only\ one\ primaryStorage\ cidr\ system\ tag\ is\ allowed,\ but\ %d\ got = 只允许一个PrimaryStorage CIDR系统标记,但{0}获得了 -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:985 -# args: psUuid,msg.getPrimaryStorageUuid() -primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:1186 +# args: clusterUuid,msg.getClusterUuid() +clusterUuid\ conflict,\ the\ cluster\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ cluster\ specified\ in\ the\ creation\ parameter\ is\ %s = Clusteruuid冲突,实例产品指定的集群为{0},创建参数中指定的集群为{1} -# at: src/main/java/org/zstack/storage/primary/PrimaryStorageReservedCapacityAllocatorFlow.java:55 -# args: PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value(),spec.getSize() -after\ subtracting\ reserved\ capacity[%s],\ there\ is\ no\ primary\ storage\ having\ required\ size[%s\ bytes],\ may\ be\ the\ threshold\ of\ primary\ storage\ physical\ capacity\ setting\ is\ lower = +# at: src/main/java/org/zstack/storage/primary/PrimaryStorageManagerImpl.java:1201 +# args: psUuid,msg.getPrimaryStorageUuidForRootVolume() +primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ instance\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = PrimaryStorageuuid冲突,实例产品指定的主存储为{0},而创建参数中指定的主存储为{1} # at: src/main/java/org/zstack/storage/primary/PrimaryStorageTagAllocatorExtension.java:127 # args: uuid @@ -7322,239 +11802,463 @@ cannot\ find\ primary\ storage\ having\ user\ tag[%s].\ The\ user\ tag\ is\ spec # args: extp.getClass().getName() PrimaryStorageTagAllocatorExtensionPoint[%s]\ returns\ zero\ primary\ storage\ candidate = 主存储标签分配插件[{0}]找不到可用的主存储 -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:132 -# args: path,JSONObjectUtil.toJsonString(errorCodes) -all\ mons\ failed\ to\ execute\ http\ call[%s],\ errors\ are\ %s = 所有的监控节点都无法执行http call[{0}],错误是{1} +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1825 +# args: +not\ support = 不是支持 -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:97 -# args: vo.getUuid() -all\ ceph\ mons\ of\ primary\ storage[uuid\:%s]\ are\ not\ in\ Connected\ state = Ceph主存储[uuid:{0}]所有的监控节点都不是已连接状态 +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:471 +# args: bsType +cannot\ find\ any\ BackupStorageKvmFactory\ for\ the\ type[%s] = 找不到类型[{0}]的任何BackupStorageKVMFactory + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:670 +# args: self.getUuid(),self.getName() +the\ block\ primary\ storage[uuid\:%s,\ name\:%s]\ can\ not\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = 块主存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机 + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1242 +# args: msg.getVolumeInventory().getUuid() +fail\ to\ find\ a\ host\ to\ map\ for\ volume\ %s = 找不到要为卷{0}映射的物理机 + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1491 +# args: +host\ uuid\ is\ mandatory = 物理机uuid是必需的 + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:1612 +# args: msg.getDestHostUuid() +Fail\ to\ get\ host\ initiator\ ref,\ please\ reconnect\ this\ host\:%s = 无法获取物理机启动器引用,请重新连接此物理机:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:2608 +# args: msg.getPrimaryStorageUuid() +fail\ to\ find\ cluster\ for\ commit\ volume\ on\ ps\:%s = 在PS:{0}上找不到提交卷的集群 + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageBase.java:2617 +# args: msg.getVolumeUuid() +fail\ to\ find\ host\ for\ commit\ volume\:%s = 找不到提交卷的物理机:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:1132 +# args: +not\ support\ take\ volumes\ snapshots\ on\ multiple\ ps\ when\ including\ ceph = 包含Ceph时,不支持在多个PS上拍摄卷快照 + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:370 +# args: context.getInventory().getUuid(),priUuid,reply.getError() +KVM\ host[uuid\:\ %s]\ fails\ to\ be\ added\ into\ local\ primary\ storage[uuid\:\ %s],\ %s = 本地存储[uuid:{1}]添加物理机[uuid:{0}]失败,{2} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:669 +# args: volume.getUuid() +fail\ to\ find\ block\ scsi\ lun\ for\ volume\:\ %s = 找不到卷{0}的块SCSI Lun + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:967 +# args: e.getCause().toString() +fail\ to\ exchange\ block\ scsi\ lun\ info\:%s = 无法交换块SCSI Lun信息:{0} + +# at: src/main/java/org/zstack/storage/primary/block/BlockPrimaryStorageFactory.java:1560 +# args: +currently\ block\ storage\ only\ support\ full\ mode\ backup = 当前,数据块存储仅支持完整模式备份 + +# at: src/main/java/org/zstack/storage/primary/block/ImageStoreBackupStorageBlockKvmDownloader.java:143 +# args: bsPath,greply.getHostname(),pinv.getUuid(),psPath,rsp.getError() +failed\ to\ download[%s]\ from\ BackupStorage[hostname\:%s]\ to\ block\ primary\ storage[uuid\:%s,\ path\:%s],\ %s = 无法将[{0}]从备份存储[物理机名:{1}]下载到块主存储[uuid:{2},路径:{3}],{4} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:875 +# args: accessZoneRsp.getDetail_err_msg() +fail\ to\ sync\ access\ zones\ because\ %s = 无法同步访问分区,因为{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:881 +# args: queryAccessZoneSubnetRsp.getDetail_err_msg() +fail\ to\ get\ access\ zone's\ subnet\ because\ %s = 无法获取访问区域的子网,因为{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:893 +# args: queryHostRsp.getDetail_err_msg() +fail\ to\ query\ all\ hosts,\ because\ of\ %s = 由于{0},无法查询所有物理机 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:908 +# args: ids.toString(),queryHostRsp.getDetail_err_msg() +fail\ to\ query\ hosts\ %s,\ because\ of\ %s = 由于{1},无法查询物理机{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:927 +# args: String.valueOf(hostId),String.valueOf(hostGroupId),addHostRsp.getDetail_err_msg() +fail\ to\ add\ host\ %s\ into\ hostGroup\ %s,\ because\ of\ %s = 由于{2},无法将物理机{0}添加到物理机组{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:962 +# args: String.valueOf(initiatorId) +host\ id\ is\ mandatory\ but\ get\:%s = 物理机ID是必需的,但获取:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:943 +# args: String.valueOf(hostId),rsp.getDetail_err_msg() +fail\ to\ delete\ host\ %s,\ because\ of\ %s = 由于{1},无法删除物理机{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:955 +# args: String.valueOf(hostGroupId),rsp.getDetail_err_msg() +fail\ to\ delete\ host\ group\ %s,\ because\ of\ %s = 由于{1},无法删除物理机组{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:967 +# args: String.valueOf(initiatorId),rsp.getDetail_err_msg() +fail\ to\ delete\ initiator\ %s,\ because\ of\ %s = 由于{1},无法删除发起程序{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:975 +# args: queryHostGroupRsp.getDetail_err_msg() +fail\ to\ query\ host\ group,\ because\ of\ %s = 由于{0},无法查询物理机组 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:993 +# args: name,addHostGroupRsp.getDetail_err_msg() +fail\ to\ add\ host\ group\:\ %s,\ error\ message\:%s\ = 无法添加物理机组:{0},错误消息:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1011 +# args: ids.toString(),queryLunRsp.getDetail_err_msg() +fail\ to\ query\ lun\ \:\ %s,\ error\ message\:%s\ = 无法查询Lun:{0},错误消息:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1050 +# args: queryPath,queryLunRsp.getDetail_err_msg() +fail\ to\ query\ lun\ by\ path\:\ %s,\ error\ message\:%s\ = 无法按路径查询Lun:{0},错误消息:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1067 +# args: name,serverCommonRsp.getDetail_err_msg() +fail\ to\ update\ lun\ name\:\ %s,\ error\ message\:%s\ = 无法更新Lun名称:{0},错误消息:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1178 +# args: blockScsiLunVO.getName(),serverRsp.getDetail_err_msg() +fail\ to\ create\ lun\ name\:\ %s,\ error\ message\:%s\ = 无法创建Lun名称:{0},错误消息:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1115 +# args: blockScsiLunVO.getName(),serverRsp.getDetail_err_msg() +fail\ to\ get\ created\ lun[name\:\ %s],\ error\ message\:%s\ = 无法获取已创建的Lun[名称:{0}],错误消息:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1129 +# args: blockScsiLunVO.getName() +fail\ to\ create\ lun\ name\:\ %s,\ can\ not\ find\ root\ cause = 无法创建Lun名称:{0},找不到根本原因 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1188 +# args: String.valueOf(lunId),queryLunRsp.getDetail_err_msg() +fail\ to\ query\ lun\ %s,\ because\ of\ %s = 由于{1},无法查询Lun{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1204 +# args: String.valueOf(lunId),String.valueOf(hostGroupId),queryLunMapRsp.getDetail_err_msg() +fail\ to\ query\ lun\ map\ for\ lun\ %s\ and\ host\ group\ %s,\ because\ of\ %s = 由于{2},无法查询Lun{0}和物理机组{1}的Lun映射 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1225 +# args: String.valueOf(hostGroupId),queryLunMapRsp.getDetail_err_msg() +fail\ to\ query\ lun\ map\ for\ host\ group\ %s,\ because\ of\ %s = 由于{1},无法查询物理机组{0}的Lun映射 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1236 +# args: clusterOverviewRsp.getDetail_err_msg() +fail\ to\ get\ cluster\ info,\ because\ of\ %s = 由于{0},无法获取集群信息 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1259 +# args: String.valueOf(lunId),String.valueOf(hostGroupId),serverRsp.getDetail_err_msg() +fail\ to\ map\ lun\ %s\ to\ host\ group\ %s,\ because\ of\ %s = 由于{2},无法将Lun{0}映射到物理机组{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1267 +# args: String.valueOf(lunMapId) +lun\ map\ id\ is\ mandatory\ but\ get\:%s = Lun映射ID是必需的,但获取:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1273 +# args: String.valueOf(lunMapId),serverRsp.getDetail_err_msg() +fail\ to\ delete\ lun\ map\ %s,\ because\ of\ %s = 由于{1},无法删除Lun映射{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1279 +# args: String.valueOf(lunId) +lun\ id\ is\ mandatory\ but\ get\:%s = Lun ID是必需的,但获取:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1285 +# args: String.valueOf(lunId),serverRsp.getDetail_err_msg() +fail\ to\ delete\ lun\ %s,\ because\ of\ %s = 由于{1},无法删除Lun{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1295 +# args: String.valueOf(id),storagePoolRsp.getDetail_err_msg() +fail\ to\ get\ storage\ pool\ %s,\ because\ of\ %s = 由于{1},无法获取存储池{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1308 +# args: JSONObjectUtil.toJsonString(blockScsiLunVO),rsp.getDetail_err_msg() +fail\ to\ create\ snapshot\ for\ lun\ %s,\ because\ of\ %s = 由于{1},无法为Lun{0}创建快照 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1330 +# args: ids.toString(),rsp.getDetail_err_msg() +fail\ to\ query\ snapshots\ %s,\ because\ of\ %s = 由于{1},无法查询快照{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1337 +# args: String.valueOf(snapshotId) +snapshot\ id\ is\ mandatory\ but\ get\:%s = 快照ID是必需的,但获取:{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1344 +# args: String.valueOf(snapshotId),rsp.getDetail_err_msg() +fail\ to\ delete\ snapshot\ %s,\ because\ of\ %s = 由于{1},无法删除快照{0} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1355 +# args: String.valueOf(snapshotId),serverRsp.getDetail_err_msg() +fail\ to\ revert\ snapshot\:%s,\ because\ of\:\ %s = 无法恢复快照:{0},因为:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1364 +# args: String.valueOf(lunId),getLunSessionRsp.getDetail_err_msg() +fail\ to\ check\ lun\ %s\ session\ state\ ,\ because\ of\:\ %s = 无法检查Lun{0}会话状态,原因是:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1380 +# args: String.valueOf(lunId),queryLunMapRsp.getDetail_err_msg() +fail\ to\ get\ lun\ %s\ maps,\ because\ of\:\ %s = 无法获取Lun{0}映射,因为:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDevice.java:1402 +# args: String.valueOf(lunId),lunQuantityInfoRsp.getDetail_err_msg() +fail\ to\ get\ lun\ %s\ remain\ created\ lun\ number,\ because\ of\:\ %s = 无法获取Lun{0}保持创建状态的Lun编号,原因是:{1} + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:161 +# args: +lun\ map\ id\ is\ mandatory\ can\ not\ be\ null,\ neither\ 0 = Lun映射ID是必需的,不能为空,也不能为0 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:194 +# args: +lun\ id\ is\ illegal = Lun ID非法 + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:527 +# args: clusterOverview.getCluster_data_state(),clusterOverview.getCluster_healthy_state(),clusterOverview.getCluster_running_state() +XStor\ cluster\ is\ unhealthy,\ cluster\ info[cluster_\ data_\ state\:\ %s,\ cluster_\ healthy_\ state\:\ %s,\ cluster_\ running_\ state\:\ %s] = xstor集群运行不正常,集群信息[集群_数据_状态:{0},集群_运行正常_状态:{1},集群_运行_状态:{2}] + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:555 +# args: +illegal\ lun\ id = 非法Lun ID + +# at: src/main/java/org/zstack/storage/primary/block/vendor/xstor/XStorDeviceImpl.java:647 +# args: +fail\ to\ get\ image\ cache\ lun\ info = 无法获取镜像缓存Lun信息 + +# at: src/main/java/org/zstack/storage/primary/ceph/CephHostHeartbeatChecker.java:204 +# args: targetHostUuid +host\ %s's\ heartbeat\ is\ not\ updated = 物理机{0}的检测信号未更新 + +# at: src/main/java/org/zstack/storage/primary/filesystem/AbstractFileSystemHostHeartbeatChecker.java:116 +# args: cmd.targetHostUuid +host[uuid\:%s]'s\ heartbeat\ is\ not\ updated = 物理机[uuid:{0}]的检测信号未更新 # at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:120 +# args: vo.getUuid() +all\ ceph\ mons\ of\ primary\ storage[uuid\:%s]\ are\ not\ in\ Connected\ state = 分布式存储[uuid:{0}]所有的监控节点都不是已连接状态 + +# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:164 # args: param.getPrimaryStorageUuid() -CephPrimaryStorage[%s]\ not\ existed! = Ceph镜像服务器[{0}]不存在 +CephPrimaryStorage[%s]\ not\ existed! = Ceph镜像服务器监控节点[{0}]不存在 -# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:170 +# at: src/main/java/org/zstack/storage/primary/imagestore/ceph/CephPrimaryToImageStoreBackupStorageMediatorImpl.java:201 # args: licMgr.getLicenseType().toString() current\ license[%s]\ is\ not\ valid\ license\ while\ download\ from\ imagestore\ backupstorage = 当从ImageStore镜像服务器进行下载操作,当前证书[{0}]是无效的证书 -# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:207 +# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:229 # args: System\ can't\ find\ imagestore\ backup\ Storage.\ Please\ do\ not\ set\ imagestore\ backup\ Storage\ server\ IP\ to\ localhost(127.*.*.*), = 系统找不到镜像仓库镜像服务器。请不要设置镜像服务器IP为localhost(127.*.*.*) -# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:210 +# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:232 # args: operationSuggestion,greply.getHostname(),backupStorageInstallPath,pinv.getUuid(),primaryStorageInstallPath,rsp.getError() %s\ failed\ to\ download\ bits\ from\ the\ imagestore\ backup\ storage[hostname\:%s,\ path\:\ %s]\ to\ the\ local\ primary\ storage[uuid\:%s,\ path\:\ %s],\ %s = {0}从镜像仓库镜像服务器[hostname:{1}, path: {2}]到本地主存储[uuid:{3}, path: {4}]下载失败,{5} -# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:270 +# at: src/main/java/org/zstack/storage/primary/imagestore/local/LocalStorageKvmImageStoreBackupStorageMediatorImpl.java:293 # args: pinv.getUuid(),primaryStorageInstallPath,r.getHostname(),rsp.getError() -failed\ to\ upload\ bits\ from\ the\ local\ storage[uuid\:%s,\ path\:%s]\ to\ image\ store\ [hostname\:%s],\ %s = 无法从本地存储[uuid:{0}, path:{1}]上传数据到镜像仓库[主机名:{2}],因为{3} +failed\ to\ upload\ bits\ from\ the\ local\ storage[uuid\:%s,\ path\:%s]\ to\ image\ store\ [hostname\:%s],\ %s = 无法从本地存储[uuid:{0}, path:{1}]上传数据到镜像仓库[物理机名:{2}],因为{3} -# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:207 -# args: volume.getUuid(),image.getImageUuid(),rsp.getError() -fails\ to\ create\ root\ volume[uuid\:%s]\ from\ cached\ image[path\:%s]\ because\ %s = 从镜像[path:{1}]创建根云盘失败,因为{2} - -# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:262 +# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:238 # args: greply.getHostname(),backupStorageInstallPath,pinv.getUuid(),primaryStorageInstallPath,rsp.getError() failed\ to\ download\ bits\ from\ the\ imagestore\ backup\ storage[hostname\:%s,\ path\:\ %s]\ to\ the\ nfs\ primary\ storage[uuid\:%s,\ path\:\ %s],\ %s = 无法从ImageStore镜像服务器[hostname:{0}, path: {1}]下载数据到NFS主存储[uuid:{2}, path: {3}],错误细节: {4} -# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:323 +# at: src/main/java/org/zstack/storage/primary/imagestore/nfs/NfsPrimaryToImageStoreBackupKVMBackend.java:300 # args: pinv.getUuid(),primaryStorageInstallPath,r.getHostname(),rsp.getError() -failed\ to\ upload\ bits\ from\ the\ NFS[uuid\:%s,\ path\:%s]\ to\ image\ store\ [hostname\:%s],\ %s = 无法从NFS主存储[uuid:{0}, path:{1}]上传数据到镜像仓库[主机名:{2}],因为{3} +failed\ to\ upload\ bits\ from\ the\ NFS[uuid\:%s,\ path\:%s]\ to\ image\ store\ [hostname\:%s],\ %s = 无法从NFS主存储[uuid:{0}, path:{1}]上传数据到镜像仓库[物理机名:{2}],因为{3} + +# at: src/main/java/org/zstack/storage/primary/imagestore/smp/KvmAgentCommandDispatcher.java:70 +# args: this.primaryStorageUuid +cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ mount\ point\ storage[uuid\:%s]\ are\ disconnected = 找不到任何Connected的物理机去执行操作,看起来加载到shared mount point存储的集群上所有物理机都处于Disconnected状态 -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:39 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:52 # args: primaryStorageUuid -failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ no\ MonIP\ available = +failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ no\ MonIP\ available = 无法获取PrimaryStorage[{0}]许可证信息,因为没有可用的monIP -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:46 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:62 # args: primaryStorageUuid -failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ no\ data\ returned = +failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ no\ data\ returned = 无法获取PrimaryStorage[{0}]许可证信息,因为未返回任何数据 -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:61 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:87 # args: primaryStorageUuid -failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ the\ returned\ data\ does\ not\ have\ an\ active\ license = +failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ the\ returned\ data\ does\ not\ have\ an\ active\ license = 无法获取PrimaryStorage[{0}]许可证信息,因为返回的数据没有活动许可证 -# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:53 +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:70 # args: primaryStorageUuid -failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ expired_time\ is\ null = +failed\ to\ get\ primaryStorage[%s]\ license\ info,\ because\ expired_time\ is\ null = 无法获取PrimaryStorage[{0}]许可证信息,因为过期_时间为空 + +# at: src/main/java/org/zstack/storage/primary/license/XskyLicenseInfoFactory.java:76 +# args: license.getExpired_time(),primaryStorageUuid +failed\ to\ parse\ the\ date\ format[%s]\ of\ the\ primaryStorage[%s]\ license\ info = 无法分析PrimaryStorage[{1}]许可证信息的日期格式[{0}] # at: src/main/java/org/zstack/storage/primary/local/AllocatePrimaryStorageForVmMigrationFlow.java:85 # args: volumeSize,spec.getVmInstance().getUuid() -no\ hosts\ can\ provide\ %s\ bytes\ for\ all\ volumes\ of\ the\ vm[uuid\:%s] = +no\ hosts\ can\ provide\ %s\ bytes\ for\ all\ volumes\ of\ the\ vm[uuid\:%s] = 没有物理机可以为VM[uuid:{1}]的所有卷提供{0}字节 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:306 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:336 # args: localstorage\ allocator\ failed = localstorage类型的主存储过滤失败 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:90 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:356 +# args: +invalid\ uri,\ correct\ example\ is\ file\://$URL;hostUuid\://$HOSTuuid\ or\ volume\://$VOLUMEuuid\ = URI无效,正确示例为file://$URL;HOSTuuid://$HOSTuuid或VOLUME://$VOLUMEuuid + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java:369 +# args: LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat() +To\ create\ volume\ on\ the\ local\ primary\ storage,\ you\ must\ specify\ the\ host\ that\ the\ volume\ is\ going\ to\ be\ created\ using\ the\ system\ tag\ [%s] = 要在本地主存储上创建卷,必须使用系统标记[{0}]指定要创建卷的物理机 + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:88 # args: msg.getVolumeUuid() the\ volume[uuid\:%s]\ is\ not\ on\ any\ local\ primary\ storage = 云盘[uuid:{0}]不在任一本地主存储上 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:95 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:93 # args: msg.getVolumeUuid(),msg.getDestHostUuid() the\ volume[uuid\:%s]\ is\ already\ on\ the\ host[uuid\:%s] = 云盘[uuid:{0}]已经在物理机[uuid:{1}]上 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:101 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:99 # args: msg.getPrimaryStorageUuid() the\ primary\ storage[uuid\:%s]\ is\ not\ found = 主存储[uuid:{0}]未找到 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:105 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:103 # args: ref.getPrimaryStorageUuid() the\ primary\ storage[uuid\:%s]\ is\ disabled\ or\ maintenance\ cold\ migrate\ is\ not\ allowed = 主存储[uuid:{0}]为Disabled或维护状态时不允许冷迁移 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:114 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:112 # args: msg.getDestHostUuid(),ref.getPrimaryStorageUuid(),msg.getVolumeUuid() the\ dest\ host[uuid\:%s]\ doesn't\ belong\ to\ the\ local\ primary\ storage[uuid\:%s]\ where\ the\ volume[uuid\:%s]\ locates = 目标物理机[uuid:{0}]不在云盘[uuid:{2}]位于的本地主存储[uuid:{1}]上 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:120 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:118 # args: msg.getDestHostUuid(),msg.getPrimaryStorageUuid(),physicalThreshold,refVO.getAvailablePhysicalCapacity() the\ dest\ host[uuid\:%s]\ doesn't\ have\ enough\ physical\ capacity\ due\ to\ the\ threshold\ of\ primary\ storage[uuid\:%s]\ is\ %f\ but\ available\ physical\ capacity\ is\ %d = 目标物理机[uuid:{0}]没有足够的物理容量,因为设置的主存储[uuid:{1}]可用阈值为{2},但实际可用物理容量是{3} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:127 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:125 # args: msg.getVolumeUuid() the\ volume[uuid\:%s]\ is\ not\ in\ status\ of\ Ready,\ cannot\ migrate\ it = 云盘[uuid:{0}]的状态不是Ready,不能迁移 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:139 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:138 # args: vol.getUuid(),vol.getVmInstanceUuid(),vmstate -the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ is\ in\ state\ of\ %s,\ please\ stop\ it\ before\ migration = 云盘[uuid:{0}]是云主机[uuid:{1}]的根云盘。当前云主机的状态为{2},请停止后再迁移 +the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ is\ in\ state\ of\ %s,\ please\ stop\ it\ before\ migration = 云盘[uuid:{0}]是云主机[uuid:{1}]的云盘。当前云主机的状态为{2},请停止后再迁移 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:147 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:146 # args: vol.getUuid(),vol.getVmInstanceUuid(),count -the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ still\ has\ %s\ data\ volumes\ attached,\ please\ detach\ them\ before\ migration = 云盘[uuid:{0}]是云主机[uuid:{1}]的根云盘。当前云主机仍有已挂载的数据云盘,请卸载后再迁移 +the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ still\ has\ %s\ data\ volumes\ attached,\ please\ detach\ them\ before\ migration = 云盘[uuid:{0}]是云主机[uuid:{1}]的云盘。当前云主机仍有已挂载的云盘,请卸载后再迁移 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:152 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:151 # args: vol.getUuid(),vol.getVmInstanceUuid() -the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ still\ has\ ISO\ attached,\ please\ detach\ it\ before\ migration = +the\ volume[uuid\:%s]\ is\ the\ root\ volume\ of\ the\ vm[uuid\:%s].\ Currently\ the\ vm\ still\ has\ ISO\ attached,\ please\ detach\ it\ before\ migration = 卷[uuid:{0}]是云主机[uuid:{1}]的根卷。当前云主机仍连接有ISO,请在迁移前将其分离 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:177 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:176 # args: originClusterUuid,clusterUuid,vol.getVmInstanceUuid() -The\ two\ clusters[uuid\:%s,uuid\:%s]\ cannot\ access\ each\ other\ in\ l2\ network\ \ when\ migrate\ the\ vm[uuid\:%s]\ to\ another\ cluster = 两个集群[uuid:{0},uuid:{1}]无法在L2网络中互相访问对方,当迁移云主机[uuid:{2}]从其中一个集群到另一个集群时 +The\ two\ clusters[uuid\:%s,uuid\:%s]\ cannot\ access\ each\ other\ in\ l2\ network\ \ when\ migrate\ the\ vm[uuid\:%s]\ to\ another\ cluster = 两个集群[uuid:{0},uuid:{1}]无法在二层网络中互相访问对方,当迁移云主机[uuid:{2}]从其中一个集群到另一个集群时 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:132 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:130 # args: vol.getUuid(),vol.getName(),vol.getVmInstanceUuid() -the\ data\ volume[uuid\:%s,\ name\:\ %s]\ is\ still\ attached\ to\ the\ VM[uuid\:%s].\ Please\ detach\ it\ before\ migration = 数据云盘[uuid:{0}, 名称: {1}]仍然挂载在云主机[uuid:{2}]上,请在迁移前卸载 +the\ data\ volume[uuid\:%s,\ name\:\ %s]\ is\ still\ attached\ to\ the\ VM[uuid\:%s].\ Please\ detach\ it\ before\ migration = 云盘[uuid:{0}, 名称: {1}]仍然挂载在云主机[uuid:{2}]上,请在迁移前卸载 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:191 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java:190 # args: msg.getUrl() the\ url[%s]\ is\ not\ an\ absolute\ path\ starting\ with\ '/' = url[{0}]不是一个以'/'开头的绝对路径 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:258 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:262 # args: msg.getPrimaryStorageUuid() The\ primary\ storage[uuid\:%s]\ is\ disabled\ cold\ migrate\ is\ not\ allowed = 主存储[uuid:{0}]Disabled时不允许冷迁移 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:560 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:540 # args: msg.getVolumeUuid() volume[uuid\:%s]\ is\ not\ on\ the\ local\ storage\ anymore,it\ may\ have\ been\ deleted = 云盘[uuid:{0}]已经不在本地存储上,可能已经被删除 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1143 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1168 # args: msg.getImage().getUuid(),self.getUuid(),JSONObjectUtil.toJsonString(ret.errorCodes) failed\ to\ download\ image[uuid\:%s]\ to\ all\ hosts\ in\ the\ local\ storage[uuid\:%s].\ %s = 在所有属于本地存储[uuid:{1}]的物理机上,均无法下载镜像[uuid:{0}]。{2} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1392 -# args: resUuid,uuid -Resource[uuid\:%s]\ can\ only\ be\ operated\ on\ host[uuid\:%s],\ but\ the\ host\ has\ been\ deleted = 资源[uuid:{0}]只能在物理机[uuid:{0}]上对其操作,但是该物理机已经被删除了 - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1389 -# args: resUuid -cannot\ find\ any\ host\ which\ has\ resource[uuid\:%s] = 找不到任何拥有资源[uuid:{0}]的物理机 - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:1764 -# args: hostUuid,self.getUuid(),ref.getAvailableCapacity(),size -host[uuid\:\ %s]\ of\ local\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = 主存储[uuid:{1}]上的物理机[uuid:{0}]没有足够的容量[现在: {2} bytes, 需要: {3}] - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2111 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2326 # args: msg.getVolumeUuid(),self.getUuid() unable\ to\ create\ the\ data\ volume[uuid\:\ %s]\ on\ a\ local\ primary\ storage[uuid\:%s],\ because\ the\ hostUuid\ is\ not\ specified. = 不能在本地主存储[uuid:{1}]上创建云盘[uuid:{0}],因为物理机uuid没有指定 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2634 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2887 # args: -No\ Host\ state\ is\ Enabled,\ Please\ check\ the\ availability\ of\ the\ host = +No\ Host\ state\ is\ Enabled,\ Please\ check\ the\ availability\ of\ the\ host = 未启用物理机状态,请检查物理机的可用性 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2741 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:3018 # args: hostUuid,self.getUuid() -host[uuid\:%s]\ cannot\ access\ local\ storage[uuid\:%s],\ maybe\ it\ is\ detached = +host[uuid\:%s]\ cannot\ access\ local\ storage[uuid\:%s],\ maybe\ it\ is\ detached = 物理机[uuid:{0}]无法访问本地存储[uuid:{1}],它可能已分离 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2765 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:3042 # args: resUuid,resourceType,self.getUuid() -resource[uuid\:%s,\ type\:\ %s]\ is\ not\ on\ the\ local\ primary\ storage[uuid\:%s] = +resource[uuid\:%s,\ type\:\ %s]\ is\ not\ on\ the\ local\ primary\ storage[uuid\:%s] = 资源[uuid:{0},类型:{1}]不在本地主存储[uuid:{2}]上 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:2770 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java:3047 # args: resUuid,resourceType,self.getUuid(),ret -resource[uuid\:%s,\ type\:\ %s]\ on\ the\ local\ primary\ storage[uuid\:%s]\ maps\ to\ multiple\ hypervisor%s = +resource[uuid\:%s,\ type\:\ %s]\ on\ the\ local\ primary\ storage[uuid\:%s]\ maps\ to\ multiple\ hypervisor%s = 本地主存储[uuid:{2}]上的资源[uuid:{0},类型:{1}]映射到多个云主机管理程序{3} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:99 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:100 # args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,clusterUuid There\ is\ no\ LocalStorage\ primary\ storage[state\=%s,status\=%s]\ on\ the\ cluster[%s],\ when\ the\ cluster\ mounts\ multiple\ primary\ storage,\ the\ system\ uses\ the\ local\ primary\ storage\ by\ default.\ Check\ the\ state/status\ of\ primary\ storage\ and\ make\ sure\ they\ have\ been\ attached\ to\ clusters = 在集群[{2}]里没有LocalStorage主存储[state={0},status={1}],当集群挂载了多个主存储的时候,系统默认的是local主存储。检查主存储的状态并确定是否连接了集群 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:118 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:119 # args: psUuid the\ type\ of\ primary\ storage[uuid\:%s]\ chosen\ is\ not\ local\ storage,\ check\ if\ the\ resource\ can\ be\ created\ on\ other\ storage\ when\ cluster\ has\ attached\ local\ primary\ storage = 被选择的主存储[uuid:{0}]的类型不是本地存储,检查该资源能否在其他存储上被创建当集群已经挂载了本地存储 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:183 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java:187 # args: requiredPrimaryStorageUuidForDataVolume.getUuid(),requiredPrimaryStorageUuidForDataVolume.getType(),LocalStorageConstants.LOCAL_STORAGE_TYPE -The\ cluster\ mounts\ multiple\ primary\ storage[%s(%s),\ other\ non-LocalStorage\ primary\ storage],\ primaryStorageUuidForDataVolume\ cannot\ be\ specified\ %s = 集群绑定了多个主存储[{0}({1}), 其他的非LocalStorage主存储],主存储根云盘未进行指定{2} +The\ cluster\ mounts\ multiple\ primary\ storage[%s(%s),\ other\ non-LocalStorage\ primary\ storage],\ primaryStorageUuidForDataVolume\ cannot\ be\ specified\ %s = 集群绑定了多个主存储[{0}({1}), 其他的非LocalStorage主存储],主存储云盘未进行指定{2} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:119 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:126 # args: spec.getDestHost().getClusterUuid() -The\ cluster[uuid\=%s]\ mounts\ multiple\ primary\ storage[LocalStorage,\ other\ non-LocalStorage\ primary\ storage],\ You\ must\ specify\ the\ primary\ storage\ where\ the\ root\ disk\ is\ located = 集群[uuid={0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下根云盘所在的主存储 +The\ cluster[uuid\=%s]\ mounts\ multiple\ primary\ storage[LocalStorage,\ other\ non-LocalStorage\ primary\ storage],\ You\ must\ specify\ the\ primary\ storage\ where\ the\ root\ disk\ is\ located = 集群[uuid={0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下云盘所在的主存储 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:125 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java:132 # args: spec.getDestHost().getClusterUuid() -The\ cluster[uuid\=%s]\ mounts\ multiple\ primary\ storage[LocalStorage,\ other\ non-LocalStorage\ primary\ storage],\ You\ must\ specify\ the\ primary\ storage\ where\ the\ data\ disk\ is\ located = 集群[uuid={0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下根云盘所在的主存储。 +The\ cluster[uuid\=%s]\ mounts\ multiple\ primary\ storage[LocalStorage,\ other\ non-LocalStorage\ primary\ storage],\ You\ must\ specify\ the\ primary\ storage\ where\ the\ data\ disk\ is\ located = 集群[uuid={0}]绑定了多个主存储[LocalStorage, 其他非LocalStorage主存储],需要检验下云盘所在的主存储。 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:365 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:404 +# args: imageUuid,cachedHostUuids +creation\ rely\ on\ image\ cache[uuid\:%s,\ locate\ host\ uuids\:\ [%s]],\ cannot\ create\ other\ places. = 创建依赖于镜像缓存[uuid:{0},定位物理机uuid:[{1}]],无法创建其他位置。 + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:462 # args: spec.getVmInventory().getHypervisorType() local\ storage\ doesn't\ support\ live\ migration\ for\ hypervisor[%s] = 本地存储不支持对虚拟化类型[{0}]进行热迁移 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:581 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:678 # args: volume.getUuid(),vm.getUuid(),vm.getRootVolumeUuid(),rootHost,volume.getUuid(),dataHost -cannot\ attach\ the\ data\ volume[uuid\:%s]\ to\ the\ vm[uuid\:%s].\ Both\ vm's\ root\ volume\ and\ the\ data\ volume\ are\ on\ local\ primary\ storage,\ but\ they\ are\ on\ different\ hosts.\ The\ root\ volume[uuid\:%s]\ is\ on\ the\ host[uuid\:%s]\ but\ the\ data\ volume[uuid\:\ %s]\ is\ on\ the\ host[uuid\:\ %s] = 不能加载数据云盘[uuid:{0}]到云主机[uuid:{1}]。根云盘和数据云盘都在本地主存储上,但他们属于不同的物理机。根云盘[uuid:{2}]在物理机[uuid:{3}]上,但数据云盘[uuid:{4}]在物理机[uuid:{5}]上 +cannot\ attach\ the\ data\ volume[uuid\:%s]\ to\ the\ vm[uuid\:%s].\ Both\ vm's\ root\ volume\ and\ the\ data\ volume\ are\ on\ local\ primary\ storage,\ but\ they\ are\ on\ different\ hosts.\ The\ root\ volume[uuid\:%s]\ is\ on\ the\ host[uuid\:%s]\ but\ the\ data\ volume[uuid\:\ %s]\ is\ on\ the\ host[uuid\:\ %s] = 不能加载云盘[uuid:{0}]到云主机[uuid:{1}]。云盘和云盘都在本地主存储上,但他们属于不同的物理机。云盘[uuid:{2}]在物理机[uuid:{3}]上,但云盘[uuid:{4}]在物理机[uuid:{5}]上 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:809 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:896 # args: vol.getName(),vol.getUuid(),vol.getPrimaryStorageUuid() -the\ data\ volume[name\:%s,\ uuid\:%s]\ is\ on\ the\ local\ storage[uuid\:%s];\ however,the\ host\ on\ which\ the\ data\ volume\ is\ has\ been\ deleted.\ Unable\ to\ recover\ this\ volume = 数据云盘[name:{0}, uuid:{1}]在本地存储[uuid:{2}]上;然而物理机内的数据云盘已经被删除了 +the\ data\ volume[name\:%s,\ uuid\:%s]\ is\ on\ the\ local\ storage[uuid\:%s];\ however,the\ host\ on\ which\ the\ data\ volume\ is\ has\ been\ deleted.\ Unable\ to\ recover\ this\ volume = 云盘[name:{0}, uuid:{1}]在本地存储[uuid:{2}]上;然而物理机内的云盘已经被删除了 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:851 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:938 # args: vm.getUuid(),vm.getName(),psuuid -unable\ to\ recover\ the\ vm[uuid\:%s,\ name\:%s].\ The\ vm's\ root\ volume\ is\ on\ the\ local\ storage[uuid\:%s];\ however,\ the\ host\ on\ which\ the\ root\ volume\ is\ has\ been\ deleted = 不能恢复云主机[uuid:{0}, name:{1}]。云主机的根云盘在本地存储[uuid:{2}]上;然而物理机内的根云盘已经被删除了 +unable\ to\ recover\ the\ vm[uuid\:%s,\ name\:%s].\ The\ vm's\ root\ volume\ is\ on\ the\ local\ storage[uuid\:%s];\ however,\ the\ host\ on\ which\ the\ root\ volume\ is\ has\ been\ deleted = 不能恢复云主机[uuid:{0}, name:{1}]。云主机的云盘在本地存储[uuid:{2}]上;然而物理机内的云盘已经被删除了 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:888 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:972 # args: vm.getUuid() -unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ data\ volumes\ on\ local\ storage.\ Need\ detach\ all\ data\ volumes\ first. = 无法在本地存储上热迁移挂载了数据云盘的云主机[uuid:{0}]。需要先手动卸载所有数据云盘 +unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ data\ volumes\ on\ local\ storage.\ Need\ detach\ all\ data\ volumes\ first. = 无法在本地存储上热迁移挂载了云盘的云主机[uuid:{0}]。需要先手动卸载所有云盘 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:893 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:977 # args: vm.getUuid(),vm.getPlatform() unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ local\ storage.\ Only\ linux\ guest\ is\ supported.\ Current\ platform\ is\ [%s] = 无法在本地存储上热迁移云主机[uuid:{0}]。只有Linux类型的云主机支持该操作。当前类型为: [{1}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:898 -# args: vm.getUuid() -unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ ISO\ on\ local\ storage.\ Need\ detach\ all\ ISO\ first. = - -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:929 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:982 # args: vm.getUuid() -unable\ to\ live\ migrate\ with\ local\ storage.\ The\ vm[uuid\:%s]\ has\ volumes\ on\ local\ storage,to\ protect\ your\ data,\ please\ stop\ the\ vm\ and\ do\ the\ volume\ migration = 本地存储不能热迁移。云主机[uuid:{0}]在本地存储上有云盘,为了保护你的数据,请停止云主机做云盘迁移 +unable\ to\ live\ migrate\ vm[uuid\:%s]\ with\ ISO\ on\ local\ storage.\ Need\ detach\ all\ ISO\ first. = 无法在本地存储上实时迁移带有ISO的VM[uuid:{0}]。需要先分离所有ISO。 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:979 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:1058 # args: LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat() -To\ create\ data\ volume\ on\ the\ local\ primary\ storage,\ you\ must\ specify\ the\ host\ that\ the\ data\ volume\ is\ going\ to\ be\ created\ using\ the\ system\ tag\ [%s] = 要在本地主存储上创建数据云盘,必须用系统标签[{0}]指定创建数据云盘的物理机 +To\ create\ data\ volume\ on\ the\ local\ primary\ storage,\ you\ must\ specify\ the\ host\ that\ the\ data\ volume\ is\ going\ to\ be\ created\ using\ the\ system\ tag\ [%s] = 要在本地主存储上创建云盘,必须用系统标签[{0}]指定创建云盘的物理机 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:989 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java:1068 # args: hostUuid,msg.getPrimaryStorageUuid() the\ host[uuid\:%s]\ doesn't\ belong\ to\ the\ local\ primary\ storage[uuid\:%s] = 物理机[uuid:{0}] 不属于本地主存储[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:1782 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:2083 # args: root\ image\ has\ been\ deleted,\ cannot\ reimage\ now = 系统镜像已经被删除,无法重制云主机 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3117 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3676 # args: makeInitializedFilePath(),hostUuid -cannot\ find\ flag\ file\ [%s]\ on\ host\ [%s],\ it\ might\ not\ mount\ correct\ path = +cannot\ find\ flag\ file\ [%s]\ on\ host\ [%s],\ it\ might\ not\ mount\ correct\ path = 在物理机[{1}]上找不到标记文件[{0}],可能是装载路径不正确 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java:105 -# args: context.getInventory().getUuid(),priUuid,reply.getError() -KVM\ host[uuid\:\ %s]\ fails\ to\ be\ added\ into\ local\ primary\ storage[uuid\:\ %s],\ %s = 本地存储[uuid:{1}]添加物理机[uuid:{0}]失败,{2} +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3684 +# args: makeInitializedFilePath(),hostUuid,errorCode.getCause().getDetails() +cannot\ find\ flag\ file\ [%s]\ on\ host\ [%s],\ because\:\ %s = 找不到标记文件[{0}](在物理机[{1}]上),因为:{2} + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java:3705 +# args: makeInitializedFilePath(),hostUuid,errorCode.getCause().getDetails() +cannot\ create\ flag\ file\ [%s]\ on\ host\ [%s],\ because\:\ %s = 无法在物理机[{1}]上创建标志文件[{0}],因为:{2} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java:1196 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java:1192 # args: p.volume.getUuid(),p.volume.getName(),dstHostUuid unable\ to\ create\ an\ empty\ volume[uuid\:%s,\ name\:%s]\ on\ the\ kvm\ host[uuid\:%s] = 不能在物理机[uuid:{2}]上创建空云盘[uuid:{0}, name:{1}] @@ -7562,109 +12266,157 @@ unable\ to\ create\ an\ empty\ volume[uuid\:%s,\ name\:%s]\ on\ the\ kvm\ host[u # args: greply.getHostname(),backupStorageInstallPath,pinv.getUuid(),primaryStorageInstallPath,rsp.getError() failed\ to\ download\ bits\ from\ the\ SFTP\ backup\ storage[hostname\:%s,\ path\:\ %s]\ to\ the\ local\ primary\ storage[uuid\:%s,\ path\:\ %s],\ %s = 从SFTP镜像服务器[hostname:{0}, path: {1}] 下载到本地存储[uuid:{2}, path: {3}]失败,{4} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java:254 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java:253 # args: pinv.getUuid(),primaryStorageInstallPath,r.getHostname(),backupStorageInstallPath,rsp.getError() failed\ to\ upload\ bits\ from\ the\ local\ storage[uuid\:%s,\ path\:%s]\ to\ the\ SFTP\ backup\ storage[hostname\:%s,\ path\:%s],\ %s = 从本地存储[uuid:{0}, path: {1}]上传到SFTP镜像服务器[hostname:{2}, path:{3}]失败, {4} -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:157 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:159 # args: PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,HostState.Enabled,HostStatus.Connected,spec.getSize() -no\ local\ primary\ storage\ can\ satisfy\ conditions[state\:\ %s,\ status\:\ %s]\ or\ contain\ hosts\ satisfying\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = +no\ local\ primary\ storage\ can\ satisfy\ conditions[state\:\ %s,\ status\:\ %s]\ or\ contain\ hosts\ satisfying\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = 本地主存储不能满足条件[状态:{0},状态:{1}]或包含满足条件[状态:{2},状态:{3},大小>{4}字节]的物理机 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:132 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:134 # args: spec.getRequiredZoneUuid(),PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,HostState.Enabled,HostStatus.Connected,spec.getSize() -no\ local\ primary\ storage\ in\ zone[uuid\:%s]\ can\ satisfy\ conditions[state\:\ %s,\ status\:\ %s]\ or\ contain\ hosts\ satisfying\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = +no\ local\ primary\ storage\ in\ zone[uuid\:%s]\ can\ satisfy\ conditions[state\:\ %s,\ status\:\ %s]\ or\ contain\ hosts\ satisfying\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = 区域[uuid:{0}]中的本地主存储不能满足条件[状态:{1},状态:{2}],也不包含满足条件[状态:{3},状态:[4},大小>{5}字节]的物理机 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:105 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:107 # args: spec.getRequiredHostUuid(),HostState.Enabled,HostStatus.Connected,spec.getSize(),PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected -the\ required\ host[uuid\:%s]\ cannot\ satisfy\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes],\ or\ doesn't\ belong\ to\ a\ local\ primary\ storage\ satisfying\ conditions[state\:\ %s,\ status\:\ %s],\ or\ its\ cluster\ doesn't\ attach\ to\ any\ local\ primary\ storage = +the\ required\ host[uuid\:%s]\ cannot\ satisfy\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes],\ or\ doesn't\ belong\ to\ a\ local\ primary\ storage\ satisfying\ conditions[state\:\ %s,\ status\:\ %s],\ or\ its\ cluster\ doesn't\ attach\ to\ any\ local\ primary\ storage = 所需的物理机[uuid:{0}]无法满足条件[状态:{1},状态:{2},大小>{3}字节],或者不属于满足条件[状态:{4},状态:{5}]的本地主存储,或者其集群未连接到任何本地主存储 -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:77 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:79 # args: spec.getRequiredPrimaryStorageUuid(),PrimaryStorageState.Enabled,PrimaryStorageStatus.Connected,HostState.Enabled,HostStatus.Connected,spec.getSize() -required\ local\ primary\ storage[uuid\:%s]\ cannot\ satisfy\ conditions[state\:\ %s,\ status\:\ %s],\ or\ hosts\ providing\ the\ primary\ storage\ don't\ satisfy\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = +required\ local\ primary\ storage[uuid\:%s]\ cannot\ satisfy\ conditions[state\:\ %s,\ status\:\ %s],\ or\ hosts\ providing\ the\ primary\ storage\ don't\ satisfy\ conditions[state\:\ %s,\ status\:\ %s,\ size\ >\ %s\ bytes] = 所需的本地主存储[uuid:{0}]无法满足条件[状态:{1},状态:{2}],或者提供主存储的物理机不满足条件[状态:{3},状态:[4},大小>{5}字节] -# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:198 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:201 # args: ref.getHostUuid(),physicalCapacityMgr.getRatio(ref.getPrimaryStorageUuid()) -{the\ physical\ capacity\ usage\ of\ the\ host[uuid\:%s]\ has\ exceeded\ the\ threshold[%s]} = +{the\ physical\ capacity\ usage\ of\ the\ host[uuid\:%s]\ has\ exceeded\ the\ threshold[%s]} = '{物理机[uuid:{0}']的物理容量使用率已超过阈值[{1}]} -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1002 +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java:207 # args: -not\ supported = 不支持 +failed\ allocate\ localstorage = 分配localStorage失败 + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java:205 +# args: resUuid,uuid +Resource[uuid\:%s]\ can\ only\ be\ operated\ on\ host[uuid\:%s],\ but\ the\ host\ has\ been\ deleted = 资源[uuid:{0}]只能在物理机[uuid:{0}]上对其操作,但是该物理机已经被删除了 + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java:202 +# args: resUuid +cannot\ find\ any\ host\ which\ has\ resource[uuid\:%s] = 找不到任何拥有资源[uuid:{0}]的物理机 + +# at: src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java:135 +# args: hostUuid,self.getUuid(),ref.getAvailableCapacity(),size +host[uuid\:\ %s]\ of\ local\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = 主存储[uuid:{1}]上的物理机[uuid:{0}]没有足够的容量[现在: {2} bytes, 需要: {3}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1104 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:82 +# args: msg.getResourceUuid() +Invalid\ resourceUuid\ %s = 资源uuid{0}无效 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:88 +# args: +primary\ storage\ uuid\ cannot\ be\ null. = 主存储uuid不能为空。 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:105 +# args: volume.getUuid(),runningVmUuids.toString() +volume[uuid\:%s]\ has\ been\ attached\ some\ VM(s)[uuid\:%s]\ which\ are\ not\ Stopped\ and\ not\ running\ on\ the\ specific\ host. = 卷[uuid:{0}]已连接到某些未停止且未在特定物理机上运行的云主机[uuid:{1}]。 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:124 +# args: msg.getResourceUuid() +VM[uuid\:%s]\ are\ not\ Stopped\ and\ not\ running\ on\ the\ specific\ host. = 云主机[uuid:{0}]未停止,也未在特定物理机上运行。 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageApiInterceptor.java:191 +# args: task,hostUuids +Fail\ to\ %s,\ because\ host(s)[uuid\:%s]\ are\ not\ enable\ and\ not\ in\ connected\ status. = {0}失败,因为物理机[uuid:{1}]未启用且未处于连接状态。 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1549 # args: self.getUuid(),hostUuid -cannot\ reserve\ enough\ space\ for\ primary\ storage[uuid\:\ %s]\ on\ host[uuid\:\ %s],\ not\ enough\ physical\ capacity = +cannot\ reserve\ enough\ space\ for\ primary\ storage[uuid\:\ %s]\ on\ host[uuid\:\ %s],\ not\ enough\ physical\ capacity = 无法为物理机[uuid:{1}]上的主存储[uuid:{0}]保留足够的空间,物理容量不足 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:154 -# args: psUuid,imageFormat -cannot\ find\ proper\ hypervisorType\ for\ primary\ storage[uuid\:%s]\ to\ handle\ image\ format\ or\ volume\ format[%s] = 对主存储[uuid:{0}]来说不能发现合适的管理程序类型来处理镜像格式或云盘格式[{1}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1449 +# args: +not\ supported = 不支持 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:226 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:216 +# args: msg.getResourceType() +ResourceType\ [%s]\ of\ APIRecoverResourceSplitBrainMsg\ is\ invalid. = ApiRecoverResourceSplitBrainMsg的ResourceType[{0}]无效。 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:360 # args: self.getUuid(),self.getName() -the\ mini\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = +the\ mini\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = 小型存储[uuid:{0},名称:{1}]在连接的集群中找不到任何可用于实例化卷的物理机 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:673 +# args: +can\ not\ determine\ which\ host = 无法确定是哪个物理机 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:449 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1364 # args: -can\ not\ determine\ which\ host = +no\ connected\ host\ found,\ mini\ storage\ failed = 未找到连接的物理机,小型存储失败 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1118 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageBase.java:1563 # args: hostUuid,self.getUuid(),ref.getAvailableCapacity(),size -host[uuid\:\ %s]\ of\ mini\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = +host[uuid\:\ %s]\ of\ mini\ primary\ storage[uuid\:\ %s]\ doesn't\ have\ enough\ capacity[current\:\ %s\ bytes,\ needed\:\ %s] = 物理机[uuid:{0}](属于小型主存储[uuid:{1}])的容量不足[当前:{2}字节,需要:{3}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageFactory.java:167 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageDeactivateVolumeGC.java:75 +# args: hostUuid +the\ host[uuid\:%s]\ is\ not\ connected = 物理机[uuid:{0}]不是Connected状态 + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageFactory.java:173 # args: hvType,bsType no\ LocalStorageBackupStorageMediator\ supporting\ hypervisor[%s]\ and\ backup\ storage\ type[%s]\ = 没有LocalStorageBackupStorageMediator支持hypervisor[{0}]和镜像服务器类型[{1}] -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageImageStoreBackend.java:59 -# args: volumeUuid -can\ not\ get\ cluster\ uuid\ of\ volume\ %s = +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:332 +# args: volume.getRootImageUuid(),volume.getUuid() +no\ backup\ storage\ can\ get\ image[uuid\:%s]\ of\ volume[uuid\:%s] = 没有备份存储可以获取镜像[uuid:{0}](属于卷[uuid:{1}]) -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:736 -# args: returnValue.error -%s = {0} +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:343 +# args: image.getUuid(),cache.backupStorage.getUuid() +image[uuid\:\ %s]\ has\ no\ image\ ref\ with\ backup\ storage[uuid\:\ %s] = 镜像[uuid:{0}]没有备份存储[uuid:{1}]的镜像引用 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:181 -# args: clusterUuid -no\ connected\ host\ found\ in\ the\ cluster[uuid\:%s] = cluster[uuid:{0}]不存在已连接的物理机 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:832 +# args: volume.getUuid(),volume.getPrimaryStorageUuid() +can\ not\ find\ any\ available\ host\ to\ resize\ volume[uuid\:\ %s]\ on\ mini\ storage[uuid\:\ %s] = 找不到任何可用于调整小型存储[uuid:{1}]上卷[uuid:{0}]大小的物理机 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:1271 -# args: backupStorageUuid -cannot\ find\ backup\ storage[uuid\:%s] = 找不到镜像服务器[uuid:{0}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:925 +# args: volumeUuid +volume[uuid\:%s]\ replication\ is\ syncing\ data,\ please\ wait\ until\ it\ is\ finished. = 卷[uuid:{0}]复制正在同步数据,请等待其完成。 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmBackend.java:1056 -# args: msg.getVolumeUuid() -can\ not\ find\ volume[uuid\:\ %s] = 找不到云盘[uuid: {0}] +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:938 +# args: volumeUuid +replication\ network\ status\ of\ volume[uuid\:%s]\ run\ into\ StandAlone,\ but\ host\ are\ all\ Connected,\ please\ recover\ it\ first. = 卷[uuid:{0}]的复制网络状态变为独立运行,但物理机均已连接,请先将其恢复。 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageKvmFactory.java:723 -# args: volume.getUuid(),volume.getPrimaryStorageUuid() -can\ not\ find\ any\ available\ host\ to\ resize\ volume[uuid\:\ %s]\ on\ mini\ storage[uuid\:\ %s] = +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageManagerImpl.java:73 +# args: dir +Invalid\ path\ string\ %s = 路径字符串{0}无效 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePathManagerImpl.java:105 -# args: resourceUuid,hostUuid -can\ not\ find\ replication\ of\ volume\ %s\ on\ host\ %s = +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStorageManagerImpl.java:80 +# args: resourceUuid +Still\ cache\ volume\ exists\ on\ ps[uuid\:%s]\ can\ not\ update\ cache\ volume\ url = PS[uuid:{0}]上仍然存在缓存卷,无法更新缓存卷URL -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:187 -# args: -no\ candidate\ host\ with\ the\ scsi\ lun\ with\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = 需要的lun所在的物理机都不满足cpu / memory 以及物理机状态的条件 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePathManagerImpl.java:115 +# args: resourceUuid,hostUuid +can\ not\ find\ replication\ of\ volume\ %s\ on\ host\ %s = 在物理机{1}上找不到卷{0}的复制 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:113 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:141 # args: clusterUuid,msg.getPrimaryStorageUuid(),volume.getUuid() -required\ cluster\ %s\ not\ attached\ to\ primary\ storage\ %s\ for\ volume\ %s\ create = +required\ cluster\ %s\ not\ attached\ to\ primary\ storage\ %s\ for\ volume\ %s\ create = 创建卷{2}所需的集群{0}未连接到主存储{1} -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:120 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:148 # args: clusterUuid,volume.getUuid() -can\ not\ find\ avaliable\ host\ on\ required\ cluster\ %s\ for\ volume\ %s\ create = +can\ not\ find\ avaliable\ host\ on\ required\ cluster\ %s\ for\ volume\ %s\ create = 在创建卷{1}所需的集群{0}上找不到可用物理机 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:347 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:445 # args: primaryStorageUuid -cannot\ find\ an\ available\ host\ to\ execute\ command\ for\ primary\ storage[uuid\:\ %s] = +cannot\ find\ an\ available\ host\ to\ execute\ command\ for\ primary\ storage[uuid\:\ %s] = 找不到可用于执行主存储[uuid:{0}]命令的物理机 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:378 +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:476 # args: hostUuid -can\ not\ allocate\ storage\ sync\ port\ on\ host\ %s\:\ %s = +can\ not\ allocate\ storage\ sync\ port\ on\ host\ %s\:\ %s = 无法在物理机{0}上分配存储同步端口:{1} + +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:622 +# args: hostUuids,finalHostUuids +expect\ operate\ on\ hosts[%s]\ but\ only\ host\ %s\ are\ connected\ and\ enabled = 预期在物理机[{0}]上运行,但只有物理机{1}已连接并启用 -# at: src/main/java/org/zstack/storage/primary/ministorage/MiniStoragePlacementManagerImpl.java:490 -# args: hostUuids,connectedEnabledHosts -expect\ operate\ on\ hosts[%s]\ but\ only\ host\ %s\ are\ connected\ and\ enabled = +# at: src/main/java/org/zstack/storage/primary/ministorage/MiniToZBoxBackupStorageMediator.java:91 +# args: msg.getPrimaryStorageUuid() +mini\ storage[uuid\:%s]\ has\ to\ be\ empty\ before\ restoring\ bits\ from\ zbox.\ please\ clean\ it\ up. = 从ZBox还原位之前,小型存储[uuid:{0}]必须为空。请把它清理干净。 # at: src/main/java/org/zstack/storage/primary/nfs/NfsApiParamChecker.java:46 # args: url,zoneUuid @@ -7686,283 +12438,335 @@ IP\ address[%s]\ is\ not\ in\ CIDR[%s] = IP地址[{0}]没有在CIDR[{1}]内 # args: vms.size(),StringUtils.join(vms, "\n") there\ are\ %s\ running\ VMs\ on\ the\ NFS\ primary\ storage,\ please\ stop\ them\ and\ try\ again\:\n%s\n = 在NFS主存储上有{0}个运行中的VM,请先手动关闭再尝试: \n{1}\n -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:227 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:694 +# args: vol.getVmInstanceUuid(),state +vm[uuid\:%s]\ is\ not\ Running,\ Paused\ or\ Stopped,\ current\ state\ is\ %s = 云主机[uuid:{0}]不是运行中、已暂停或者已停止状态,现在的状态是{1} + +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:303 # args: cannot\ find\ usable\ backend = 无法找到可用的NFS主存储后端 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:286 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:362 # args: no\ usable\ backend\ found = 无法找到可用的NFS主存储后端 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:426 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:520 # args: self.getUuid(),self.getName(),msg.getVolume().getUuid(),msg.getSnapshot().getUuid(),msg.getSnapshot().getName() no\ host\ in\ Connected\ status\ to\ which\ nfs\ primary\ storage[uuid\:%s,\ name\:%s]\ attached\ found\ to\ revert\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s,\ name\:%s] = 没有找到挂载到NFS主存储[uuid:{0}, name:{1}]且处于Connected状态的物理机,无法回退云盘[uuid:{2}]到快照[uuid:{3}, name:{4}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:457 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:551 # args: self.getUuid(),self.getName(),msg.getVolume().getUuid(),msg.getVolume().getRootImageUuid() no\ host\ in\ Connected\ status\ to\ which\ nfs\ primary\ storage[uuid\:%s,\ name\:%s]\ attached\ found\ to\ revert\ volume[uuid\:%s]\ to\ image[uuid\:%s] = 没有找到挂载到NFS主存储[uuid:{0}, name:{1}]且处于Connected状态的物理机,无法回退云盘[uuid:{2}]到镜像[uuid:{3}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:536 -# args: vol.getVmInstanceUuid(),state -vm[uuid\:%s]\ is\ not\ Running,\ Paused\ or\ Stopped,\ current\ state\ is\ %s = 云主机[uuid:{0}]不是运行中、已暂停或者已停止状态,现在的状态是{1} - -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:579 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:737 # args: self.getUuid() primary\ storage[uuid\:%s]\ doesn't\ attach\ to\ any\ cluster = 主存储[uuid:{0}]没有挂载到任何集群 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:809 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:968 # args: self.getUuid(),self.getName(),msg.getVolume().getUuid(),msg.getVolume().getName() -the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ usable\ host\ to\ create\ the\ data\ volume[uuid\:%s,\ name\:%s] = NFS主存储[uuid:{0}, name:{1}]无法找到任何可用的物理机以创建数据云盘[uuid:{2}, name:{3}] +the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ usable\ host\ to\ create\ the\ data\ volume[uuid\:%s,\ name\:%s] = NFS主存储[uuid:{0}, name:{1}]无法找到任何可用的物理机以创建云盘[uuid:{2}, name:{3}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1425 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1889 # args: self.getUuid(),self.getName() the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ hosts\ in\ attached\ clusters\ to\ perform\ the\ operation = NFS主存储[uuid:{0}, name:{1}]不能找到物理机挂载到集群,执行此操作 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1392 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java:1726 # args: self.getUuid(),self.getName() the\ NFS\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = NFS主存储[uuid:{0}, name:{1}] 没有挂载到任何一个集群,或者挂载到集群的物理机均无法连接 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:112 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:115 # args: psUuid,vmUuid,volumeUuid -the\ NFS\ primary\ storage[uuid\:%s]\ is\ not\ attached\ to\ any\ clusters,\ and\ cannot\ expunge\ the\ root\ volume[uuid\:%s]\ of\ the\ VM[uuid\:%s] = NFS主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除VM[uuid:{2}]的根云盘[uuid:{1}] +the\ NFS\ primary\ storage[uuid\:%s]\ is\ not\ attached\ to\ any\ clusters,\ and\ cannot\ expunge\ the\ root\ volume[uuid\:%s]\ of\ the\ VM[uuid\:%s] = NFS主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除VM[uuid:{2}]的云盘[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:278 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:281 # args: pri.getUuid() cannot\ find\ a\ Connected\ host\ to\ execute\ command\ for\ nfs\ primary\ storage[uuid\:%s] = 对nfs主存储[uuid:{0}]来说不能发现一个可连接的物理机执行命令 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:269 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:272 # args: pri.getUuid() -cannot\ find\ a\ connected\ host\ in\ cluster\ which\ ps\ [uuid\:\ %s]\ attached = +cannot\ find\ a\ connected\ host\ in\ cluster\ which\ ps\ [uuid\:\ %s]\ attached = 在PS[uuid:{0}]连接的集群中找不到已连接的物理机 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:297 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java:300 # args: pri.getUuid() cannot\ find\ a\ host\ which\ has\ Connected\ host-NFS\ connection\ to\ execute\ command\ for\ nfs\ primary\ storage[uuid\:%s] = 找不到一个和NFS主存储[uuid:{0}]处于已连接状态的物理机为其执行命令 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:673 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:804 # args: msg.getVolume().getUuid() -cannot\ get\ root\ image\ of\ volume[uuid\:%s],\ may\ be\ it\ create\ from\ iso = +cannot\ get\ root\ image\ of\ volume[uuid\:%s],\ may\ be\ it\ create\ from\ iso = 无法获取卷[uuid:{0}]的根镜像,它可能是从ISO创建的 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:241 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:248 # args: inv.getUuid(),inv.getName(),clusterUuid,versionInCluster,otherVersion,QCOW3_QEMU_IMG_VERSION,QCOW3_QEMU_IMG_VERSION unable\ to\ attach\ a\ primary\ storage[uuid\:%s,\ name\:%s]\ to\ cluster[uuid\:%s].\ Kvm\ host\ in\ the\ cluster\ has\ qemu-img\ with\ version[%s];\ but\ the\ primary\ storage\ has\ attached\ to\ another\ cluster\ that\ has\ kvm\ host\ which\ has\ qemu-img\ with\ version[%s].\ qemu-img\ version\ greater\ than\ %s\ is\ incompatible\ with\ versions\ less\ than\ %s,\ this\ will\ causes\ volume\ snapshot\ operation\ to\ fail.\ Please\ avoid\ attaching\ a\ primary\ storage\ to\ clusters\ that\ have\ different\ Linux\ distributions,\ in\ order\ to\ prevent\ qemu-img\ version\ mismatch = 不能挂载主存储[uuid:{0}, name:{1}]到集群[uuid:{2}].集群中的物理机存在[{3}]版本qemu-img;但是主存储已经挂载到另一个物理机拥有[{4}]版本qemu-img的集群。版本大于{5}的qemu-img不兼容版本小于{6},这将会造成云盘快照操作失败。为了防止qemu-img版本不兼容,请避免挂载主存储到物理机装有不同linux版本的集群 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:316 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:323 # args: cmd.getInstallUrl(),host.getUuid(),host.getManagementIp(),rsp.getError() -unable\ to\ create\ folder[installUrl\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = +unable\ to\ create\ folder[installUrl\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 无法在KVM物理机[uuid:{1},IP:{2}]上创建文件夹[InstallUrl:{0}],原因是{3} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:394 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:401 # args: inv.getUuid() no\ host\ in\ is\ Connected\ or\ primary\ storage[uuid\:%s]\ attach\ no\ cluster = 没有物理机处于Connected状态,或主存储[uuid:{0}]没有挂载到任何集群 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:433 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:440 # args: psInv.getUuid(),huuid,reply.isSuccess() ? rsp.getError() : reply.getError() failed\ to\ ping\ nfs\ primary\ storage[uuid\:%s]\ from\ host[uuid\:%s],because\ %s.\ disconnect\ this\ host-ps\ connection = 从物理机[uuid:{1}]Ping NFS主存储[uuid:{0}]失败,原因: {2}。断开该 物理机-主存储 连接 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:699 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:879 # args: msg.getHostUuid() The\ chosen\ host[uuid\:%s]\ to\ perform\ storage\ migration\ is\ lost = 准备存储迁移的物理机[uuid:{0}]失联了 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:835 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1017 # args: installPath,inv.getUuid(),rsp.getError() failed\ to\ check\ existence\ of\ %s\ on\ nfs\ primary\ storage[uuid\:%s],\ %s = 检查nfs主存储中是否存在{0}失败 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:947 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1131 # args: volume.getUuid(),volume.getName(),host.getUuid(),host.getManagementIp(),rsp.getError() unable\ to\ create\ empty\ volume[uuid\:%s,\ \ name\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ because\ %s = 不能在物理机[uuid:{2}, ip:{3}]上创建空云盘[uuid:{0}, name:{1}],因为{4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1051 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1240 # args: installPath,pinv.getUuid(),rsp.getError() -failed\ to\ delete\ bits[%s]\ on\ nfs\ primary\ storage[uuid\:%s],\ %s,\ will\ clean\ up\ installPath,\ pinv.getUuid(),\ rsp.getError() = +failed\ to\ delete\ bits[%s]\ on\ nfs\ primary\ storage[uuid\:%s],\ %s,\ will\ clean\ up\ installPath,\ pinv.getUuid(),\ rsp.getError() = 无法删除NFS主存储[uuid:{1}]上的位[{0}],{2},将清除InstallPath、PINV.Getuuid()、RSP.GetError() -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1095 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1302 # args: vol.getUuid(),sinv.getUuid(),host.getUuid(),host.getManagementIp(),rsp.getError() failed\ to\ revert\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ %s = 回滚在物理机[uuid:{2}, ip:{3}]上的云盘[uuid:{0}]到快照[uuid:{1}]的状态失败,{4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1132 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1339 # args: vol.getUuid(),vol.getRootImageUuid(),host.getUuid(),host.getManagementIp(),rsp.getError() failed\ to\ revert\ volume[uuid\:%s]\ to\ image[uuid\:%s]\ on\ kvm\ host[uuid\:%s,\ ip\:%s],\ %s = 回滚在物理机[uuid:{2}, ip:{3}]上的云盘[uuid:{0}]到镜像[uuid:{1}],{4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1270 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1383 +# args: volume.getUuid(),imageCache.getImageUuid(),rsp.getError() +fails\ to\ create\ root\ volume[uuid\:%s]\ from\ cached\ image[path\:%s]\ because\ %s = 从镜像[path:{1}]创建云盘失败,因为{2} + +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java:1541 # args: clusterUuid -no\ hosts\ in\ the\ cluster[uuid\:%s]\ are\ connected = +no\ hosts\ in\ the\ cluster[uuid\:%s]\ are\ connected = 集群[uuid:{0}]中没有连接任何物理机 -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:158 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:109 # args: backupStorageInstallPath,greply.getHostname(),pinv.getUuid(),primaryStorageInstallPath,rsp.getError() failed\ to\ download[%s]\ from\ SftpBackupStorage[hostname\:%s]\ to\ nfs\ primary\ storage[uuid\:%s,\ path\:%s],\ %s = 从Sftp镜像服务器[hostname:{1}] 下载[{0}]到nfs主存储[uuid:{2}, path:{3}]失败,{4} -# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:214 +# at: src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryToSftpBackupKVMBackend.java:165 # args: pinv.getUuid(),primaryStorageInstallPath,hostname,backupStorageInstallPath,rsp.getError() failed\ to\ upload\ bits\ from\ nfs\ primary\ storage[uuid\:%s,\ path\:%s]\ to\ SFTP\ backup\ storage[hostname\:%s,\ path\:\ %s],\ %s = 从nfs主存储[uuid:{0}, path:{1}]上传数据到STFP镜像服务器[hostname:{2}, path: {3}]失败,{4} -# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:65 -# args: this.primaryStorageUuid -cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ mount\ point\ storage[uuid\:%s]\ are\ disconnected = 找不到任何Connected的物理机去执行操作,看起来加载到shared mount point存储的集群上所有物理机都处于Disconnected状态 +# at: src/main/java/org/zstack/storage/primary/shareblock/ShareBlockHostHeartbeatChecker.java:135 +# args: cmd.hostUuid,sentinelHostUuid +shareblock\ says\ host\ %s\ is\ offline\ on\ %s = ShareBlock显示物理机{0}在{1}上处于脱机状态 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:77 +# at: src/main/java/org/zstack/storage/primary/sharedblock/HaSanlockHostChecker.java:141 +# args: cmd.hostIds,sentinelHostUuid +sanlock\ says\ host\ %s\ is\ offline\ on\ %s = SANlock指出物理机{0}在{1}上处于脱机状态 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:110 +# args: primaryStorageUuid +cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ block\ group\ storage[uuid\:%s]\ are\ disconnected = 找不到任何可以执行操作的已连接状态的物理机,所有的共享存储[uuid:{0}]挂载的集群下的物理机都处于已失联状态 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:80 +# args: +can\ not\ find\ volume\ need\ to\ operate\ shared\ block\ group\ primary\ storage = 找不到能进行共享块存储操作的云盘 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:88 +# args: volumeInventory.getUuid(),primaryStorageUuid +KVM\ host\ which\ volume[uuid%s]\ attached\ disconnected\ with\ the\ shared\ block\ group\ storage[uuid\:%s] = 云盘[uuid:{0}]所处的挂载了共享块存储[uuid:{1}]物理机均处于已失联状态 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/KvmAgentCommandDispatcher.java:98 +# args: psUuid +can\ not\ find\ qualified\ kvm\ host\ for\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = 无法找到满足条件的物理机来对共享块存储[uuid: {0}]进行操作 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:81 # args: sharedBlockVO.getSharedBlockGroupUuid(),scsiLunVO.getWwid() -primary\ storage[uuid\:\ %s]\ has\ attached\ the\ scsi\ lun[wwid\:\ %s] = +primary\ storage[uuid\:\ %s]\ has\ attached\ the\ scsi\ lun[wwid\:\ %s] = 主存储[uuid:{0}]已连接SCSI Lun[WWID:{1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:100 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:105 # args: msg.getVmInstanceUuid() -the\ vm[uuid\:\ %s]\ does\ not\ has\ additional\ qmp\ socket,\ it\ may\ because\ of\ the\ vm\ start\ without\ the\ global\ config[vm.additionalQmp]\ enabled,\ please\ make\ sure\ it\ enabled\ and\ reboot\ vm\ in\ zstack = +the\ vm[uuid\:\ %s]\ does\ not\ has\ additional\ qmp\ socket,\ it\ may\ because\ of\ the\ vm\ start\ without\ the\ global\ config[vm.additionalQmp]\ enabled,\ please\ make\ sure\ it\ enabled\ and\ reboot\ vm\ in\ zstack = VM[uuid:{0}]没有其他QMP套接字,这可能是因为VM在未启用全局配置[VM.AdditionalQMP]的情况下启动,请确保其已启用并在ZStack中重新启动VM -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:125 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:130 # args: -must\ specify\ at\ least\ one\ disk\ when\ add\ shared\ block\ group\ primary\ storage = 添加共享块存储时必须指定至少一个硬盘 +must\ specify\ at\ least\ one\ disk\ when\ add\ shared\ block\ group\ primary\ storage = 添加共享块存储时必须指定至少一个云盘 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:137 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:142 # args: vo.getUuid(),vo.getDiskUuid(),vo.getDescription(),vo.getSharedBlockGroupUuid() shared\ block[uuid\:%s,\ diskUuid\:%s,\ description\:%s]\ already\ added\ to\ shared\ block\ group[uuid\:%s]in\ new\ shared\ block\ group = 共享块[uuid:{0}, diskUuid:{1}, 描述:{2}],已经添加到共享块组[uuid:{3}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:160 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:165 # args: msg.getUuid() shared\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage\ can\ not\ resize = SharedBlock主存储上的共享云盘[uuid: {0}]暂时不支持扩容 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:229 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockApiInterceptor.java:234 # args: volumeUuid,notStoppedVmUuids -shared\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage\ has\ attached\ to\ not\ stopped\ vm\ instances[uuids\:\ %s] = SharedBlock存储上的共享云盘[uuid: {0}]加载到了不是停止状态的虚拟机[uuid: {1}],请先从虚拟机卸载或将虚拟机停止 +shared\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage\ has\ attached\ to\ not\ stopped\ vm\ instances[uuids\:\ %s] = SharedBlock存储上的共享云盘[uuid: {0}]加载到了不是停止状态的云主机[uuid: {1}],请先从云主机卸载或将云主机停止 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:301 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1665 +# args: psUuid,imageFormat +cannot\ find\ proper\ hypervisorType\ for\ primary\ storage[uuid\:%s]\ to\ handle\ image\ format\ or\ volume\ format[%s] = 对主存储[uuid:{0}]来说不能发现合适的管理程序类型来处理镜像格式或云盘格式[{1}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:344 # args: self.getUuid(),self.getName() the\ shared\ mount\ point\ primary\ storage[uuid\:%s,\ name\:%s]\ cannot\ find\ any\ available\ host\ in\ attached\ clusters\ for\ instantiating\ the\ volume = 共享挂载点主存储[uuid:{0}, name:{1}]在挂载的集群中找不到任何可用的物理机来实例化云盘 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:530 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:697 # args: getSelfInventory().getUuid() can\ not\ found\ any\ cluster\ attached\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %S] = 找不到任何挂载了共享块主存储[uuid: %S] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:880 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1100 # args: self.getUuid(),self.getName() the\ shared\ block\ group\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = SharedBlock主存储[uuid:{0}, name:{1}] 没有挂载到任何一个集群,或者挂载到集群的物理机均无法连接 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1070 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1179 +# args: self.getUuid(),self.getName() +the\ SharedBlock\ primary\ storage[uuid\:%s,\ name\:%s]\ has\ not\ attached\ to\ any\ clusters,\ or\ no\ hosts\ in\ the\ attached\ clusters\ are\ connected = SharedBlock主存储[uuid:{0},名称:{1}]尚未连接到任何集群,或者已连接的集群中没有物理机 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1369 # args: -empty\ migrateVolumeStructs\ in\ migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! = +empty\ migrateVolumeStructs\ in\ migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! = MigrateEvoluesBetweenSharedBlockGroupPrimaryStorageMsg中的MigrateEvolumeStructs为空! -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1076 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageBase.java:1375 # args: -no\ volume\ in\ migrateVolumeStructs\ in\ migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! = +no\ volume\ in\ migrateVolumeStructs\ in\ migrateVolumesBetweenSharedBlockGroupPrimaryStorageMsg! = MigrateEvolumesBetweenSharedBlockGroupPrimaryStorageMsg中的MigrateEvolmeStructs中没有卷! -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:110 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:112 # args: newValue the\ value[%s]\ is\ not\ power\ of\ 2 = 输入值[{0}]不是2的幂次 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:438 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:444 # args: pri.getUuid() cannot\ find\ an\ available\ host\ to\ execute\ command\ for\ shared\ block\ group\ primary\ storage[uuid\:%s] = 找不到加载了共享块存储的[uuid:{0}]可用的物理机 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:462 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:468 # args: pri.getUuid() cannot\ find\ a\ host\ which\ has\ connected\ shared\ block\ to\ execute\ command\ for\ shared\ block\ group\ primary\ storage[uuid\:%s] = 找不到处于连接状态的加载了共享块存储[uuid:{0}]物理机执行命令 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1104 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:515 +# args: vmvo.getHostUuid(),volumeInventory.getUuid(),volumeInventory.getPrimaryStorageUuid() +the\ host[uuid\:\ %s]\ running\ on\ is\ not\ available\ to\ resize\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = 共享块存储[uuid: {2}]上的云盘[uuid : {1}]运行在物理机[uuid : {0}]上,但状态无法执行扩容操作 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:524 +# args: psUuid +primary\ storage[uuid\:%s]\ not\ found = 找不到主存储[uuid:{0}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockGroupPrimaryStorageFactory.java:541 +# args: volUuid +volume[uuid\:%s]\ not\ found = 未找到卷[uuid:{0}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockImageStoreBackend.java:81 +# args: volumeUuid +can\ not\ get\ cluster\ uuid\ of\ volume\ %s = 无法获取卷{0}的集群uuid + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1413 # args: img.getUuid(),img.getName(),self.getZoneUuid() the\ image[uuid\:%s,\ name\:\ %s]\ is\ not\ available\ to\ download\ on\ any\ backup\ storage\:\n1.\ check\ if\ image\ is\ in\ status\ of\ Deleted\n2.\ check\ if\ the\ backup\ storage\ on\ which\ the\ image\ is\ shown\ as\ Ready\ is\ attached\ to\ the\ zone[uuid\:%s] = 不能从镜像服务器中下载镜像[uuid:%s, name: %s]\n1.检查镜像是否处于被删除状态\n2.检查镜像处于就绪状态的镜像服务器是否挂载到区域[uuid:{2}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:832 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1251 +# args: volume.getUuid(),volume.getVmInstanceUuid(),state +the\ volume[uuid;%s]\ is\ attached\ to\ a\ VM[uuid\:%s]\ which\ is\ in\ state\ of\ %s,\ cannot\ do\ the\ snapshot\ merge = 云盘[uuid;{0}] 挂载到处于{2}状态的云主机,不能合并快照 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1907 +# args: clusterUuid +no\ connected\ host\ found\ in\ the\ cluster[uuid\:%s] = cluster[uuid:{0}]不存在已连接的物理机 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5893 # args: vol.getVmInstanceUuid(),state vm[uuid\:%s]\ is\ not\ Running,\ Paused\ or\ Stopped,\ current\ state[%s] = 云主机[uuid:{0}]不是运行中、已暂停或者已停止状态,现在的状态是[{1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:986 -# args: volume.getUuid(),volume.getVmInstanceUuid(),state -the\ volume[uuid;%s]\ is\ attached\ to\ a\ VM[uuid\:%s]\ which\ is\ in\ state\ of\ %s,\ cannot\ do\ the\ snapshot\ merge = 云盘[uuid;{0}] 挂载到处于{2}状态的虚拟机,不能合并快照 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2798 +# args: backupStorageUuid +cannot\ find\ backup\ storage[uuid\:%s] = 找不到镜像服务器[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1075 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2260 +# args: msg.getVolumeUuid() +can\ not\ find\ volume[uuid\:\ %s] = 找不到云盘[uuid: {0}] + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:773 +# args: +shared\ volume\ not\ support\ thin\ provisioning = 共享云盘不支持精简配置 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1340 # args: volume.getUuid() not\ support\ online\ merge\ snapshot\ for\ shareable\ volume[uuid\:\ %s]\ on\ sharedblock = 不支持对共享块存储上的共享云盘[uuid: {1}]做在线合并快照,请关机或卸载后操作 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1120 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1429 # args: img.getUuid(),img.getName() -the\ image[uuid\:\ %s,\ name\:%s]\ is\ not\ found\ on\ any\ backup\ storage = +the\ image[uuid\:\ %s,\ name\:%s]\ is\ not\ found\ on\ any\ backup\ storage = 在任何备份存储上都找不到镜像[uuid:{0},名称:{1}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1561 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2043 # args: ret.firstAccessHosts.stream().map( h -> h.hostUuid).collect(Collectors.toList()) hosts[uuid\:%s]\ have\ the\ disk\ uuid\ of\ shared\ block,\ but\ actually\ different\ storage. = 物理机[uuid:{0}]已经加载了相同uuid的共享块,但实际上是不同的存储 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1867 -# args: -not\ support\ convert\ thin\ volume\ to\ thick\ volume\ yet = - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:1921 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2400 # args: -expected\ status\ is\ %s\ and\ current\ status = - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2372 -# args: self.getUuid() -cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ in\ the\ clusters\ attached\ with\ the\ shared\ block\ group\ storage[uuid\:%s]\ are\ disconnected = 找不到任何可以执行操作的已连接状态的物理机,所有的共享存储[uuid:{0}]挂载的集群下的物理机都处于已失联状态 +not\ support\ convert\ thin\ volume\ to\ thick\ volume\ yet = 尚不支持将精简卷转换为密集卷 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2344 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2453 # args: -can\ not\ find\ volume\ need\ to\ operate\ shared\ block\ group\ primary\ storage = 找不到能进行共享块存储操作的云盘 - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2352 -# args: volumeInventory.getUuid(),self.getUuid() -KVM\ host\ which\ volume[uuid%s]\ attached\ disconnected\ with\ the\ shared\ block\ group\ storage[uuid\:%s] = 云盘[uuid:{0}]所处的挂载了共享块存储[uuid:{1}]物理机均处于已失联状态 - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2361 -# args: psUuid -can\ not\ find\ qualified\ kvm\ host\ for\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = 无法找到满足条件的物理机来对共享块存储[uuid: {0}]进行操作 +expected\ status\ is\ %s\ and\ current\ status = 预期状态为{0},当前状态为 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2779 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3409 # args: spec.getVmInventory().getUuid(),String.join(",", psUuids) VM[uuid\:%s]\ has\ multiple\ ISOs\ from\ different\ primary\ storage\:\ %s = VM[uuid:{0}]挂载了来自不同主存储:{1}的ISO -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:2954 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3584 # args: volume.getUuid() -QCow2\ shared\ volume[uuid\:%s]\ is\ not\ supported = +QCow2\ shared\ volume[uuid\:%s]\ is\ not\ supported = 不支持QCOW2共享云盘[uuid:{0}] -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3819 -# args: volumeVO.getUuid(),volumeVO.getPrimaryStorageUuid() -can\ not\ find\ any\ available\ host\ to\ resize\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = 无法找到合适的物理机来对共享块存储[uuid: {1}]上的云盘[uuid: {0}]执行扩容 - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3825 -# args: struct.getVmHostUuid(),volumeVO.getUuid(),volumeVO.getPrimaryStorageUuid() -the\ host[uuid\:\ %s]\ running\ on\ is\ not\ available\ to\ resize\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = 共享块存储[uuid: {2}]上的云盘[uuid : {1}]运行在物理机[uuid : {0}]上,但状态无法执行扩容操作 - -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3943 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4650 # args: msg.getVolumeUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ take\ snapshot\ for\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s] = 无法找到合适的物理机来对共享块存储[uuid : {1}]上的云盘[uuid: {0}]执行快照操作 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4001 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4708 # args: msg.getPrimaryStorageUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ hosts\ both\ connect\ to\ primary\ storage[uuid\:\ %s]\ and\ primary\ storage[uuid\:\ %s] = 无法找到同时连接主存储[uuid: {0}]和主存储[uuid: {1}]的物理机 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3956 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4663 # args: only\ support\ full = 共享块存储目前只支持全量快照 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3984 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4691 # args: msg.getMigrateVolumeStructs().get(0).volumeUuid,msg.getPrimaryStorageUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ migrate\ volume[uuid\:\ %s]\ between\ shared\ block\ group\ primary\ storage[uuid\:\ %s]\ and\ [uuid\:\ %s] = 无法找到合适的物理机来将云盘[uuid: {0}]在共享块存储[uuid : {1}]和共享块存储[uuid: {2}]之间迁移 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:3993 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4700 # args: msg.getMigrateVolumeStructs().get(0).volumeUuid,msg.getTargetPrimaryStorageUuid(),msg.getTargetPrimaryStorageUuid() can\ not\ find\ any\ available\ host\ to\ migrate\ for\ volume[uuid\:\ %s]\ on\ shared\ block\ group\ primary\ storage[uuid\:\ %s]\ and\ [uuid\:\ %s] = 无法找到合适的物理机来将云盘[uuid: {0}]在共享块存储[uuid : {1}]和共享块存储[uuid: {2}]之间迁移 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4045 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4753 # args: msg.getPrimaryStorageUuid() cannot\ find\ any\ connected\ host\ to\ perform\ the\ operation,\ it\ seems\ all\ KVM\ hosts\ attached\ with\ the\ shared\ block\ group\ storage[uuid\:%s]\ are\ disconnected = 无法找到任何已连接的物理机来执行操作,所有连接共享块存储[uuid: {1}]的物理机均处于失联状态 -# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4386 +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:4971 +# args: snapshotVO.getUuid(),volumeVO.getUuid() +cannot\ shrink\ snapshot\ %s,\ because\ volume\ %s\ not\ ready = 无法收缩快照{0},因为卷{1}未就绪 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5147 +# args: snapshotVO.getUuid(),instanceVO.getUuid() +cannot\ shrink\ snapshot\ %s,\ beacuse\ vm\ %s\ not\ in\ Running/Stopped\ state = 无法收缩快照{0},因为VM{1}未处于正在运行/已停止状态 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5394 # args: vmVolumesStruct.vmInstanceVO.getUuid() -get\ null\ install\ path\ in\ snapshot\ for\ vm\ %s = +get\ null\ install\ path\ in\ snapshot\ for\ vm\ %s = 在云主机{0}的快照中获取Null安装路径 + +# at: src/main/java/org/zstack/storage/primary/sharedblock/SharedBlockKvmBackend.java:5707 +# args: msg.getDstPath(),msg.getVolume().getUuid() +dest\ path\ %s\ not\ belong\ to\ volume\ %s\ any\ snapshot = 目标路径{0}不属于任何快照的卷{1} -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkCancelMigrateVolumeFlow.java:37 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkCancelMigrateVolumeFlow.java:33 # args: -migrate\ volume\ without\ snapshot\ on\ shared\ block\ is\ not\ support\ to\ cancel. = +migrate\ volume\ without\ snapshot\ on\ shared\ block\ is\ not\ support\ to\ cancel. = 不支持取消在共享数据块上迁移不带快照的卷。 -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:129 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:131 # args: reply1.getTrashId(),dstPsUuid,dstVolumeFolderPath,reply1.getResourceUuid() found\ trashId(%s)\ in\ PrimaryStorage\ [%s]\ for\ the\ migrate\ installPath[%s].\ Please\ clean\ it\ first\ by\ 'APICleanUpTrashOnPrimaryStorageMsg'\ if\ you\ insist\ to\ migrate\ the\ volume[%s] = 在主存储[{1}]的回收数据({0})中己存在要迁移的目标路径[{2}],如果要继续迁移云盘[{3}],请先调用'APICleanUpTrashOnPrimaryStorageMsg'来手动清理该回收数据 -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:263 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:271 # args: volumeUuid,volumeVO.getActualSize(),dstPsInv.getAvailablePhysicalCapacity() there\ are\ not\ enough\ capacity\ for\ volume[uuid\:\ %s]\ storage\ migration,\ required\ capacity\:\ %s,\ current\ available\ physical\ capacity\:\ %s = 对云盘[uuid: {0}]存储迁移需要目标主存储具有至少{1}的空余容量,但现在只有{2}的空余容量 -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:194 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:202 # args: imageUuid,zoneUuid,zoneUuid cannot\ find\ the\ image[uuid\:%s]\ in\ any\ connected\ backup\ storage\ attached\ to\ the\ zone[uuid\:%s].\ check\ below\:\n1.\ whether\ the\ backup\ storage\ is\ attached\ to\ the\ zone[uuid\:%s]\n2.\ whether\ the\ backup\ storage\ is\ in\ connected\ status;\ try\ to\ reconnect\ it\ if\ not = 在所有的已连接区域[uuid:{1}]的镜像服务器未找到镜像[uuid:{0}]。建议进行如下检查: \n1.镜像服务器是否连接到区域[uuid:{2}]\n2.镜像服务器是否是已连接状态,如果不是尝试重新连接 -# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:217 +# at: src/main/java/org/zstack/storage/primary/sharedblock/migration/SblkToSblkMigrateVolumeFlow.java:225 # args: image.getUuid(),volumeUuid,image.getActualSize(),dstPsInv.getAvailablePhysicalCapacity() there\ are\ not\ enough\ capacity\ for\ image[uuid\:\ %s]\ download\ while\ volume[uuid\:\ %s]\ storage\ migration,\ required\ capacity\:\ %s,\ current\ available\ physical\ capacity\:\ %s = 对云盘[uuid: {0}]存储迁移需要目标主存储具有至少{1}的空余容量来下载镜像cache,但现在只有{2}的空余容量 @@ -7970,27 +12774,35 @@ there\ are\ not\ enough\ capacity\ for\ image[uuid\:\ %s]\ download\ while\ volu # args: srcPsUuid data\ on\ source\ ps[uuid\:\ %s]\ has\ been\ discarded,\ not\ support\ rollback = 源主存储[uuid:{0}]上的数据已经被清理,无法回滚 -# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:1673 +# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:2415 +# args: cmd.volumeUuid,msg.getVolume().getInstallPath(),cmd.srcDir +why\ volume[uuid\:%s,\ installPath\:%s]\ not\ in\ directory\ %s = 为什么卷[uuid:{0},InstallPath:{1}]不在目录{2}中 + +# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:2184 # args: ret.firstAccessHostUuids hosts[uuid\:%s]\ have\ the\ same\ mount\ path,\ but\ actually\ mount\ different\ storage. = 物理机[uuid:{0}]有相同挂载路径,但是实际上挂载在不同的存储上 -# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:1837 +# at: src/main/java/org/zstack/storage/primary/smp/KvmBackend.java:2372 # args: msg.getHostUuid(),msg.getPrimaryStorageUuid() -host[uuid\:%s]\ might\ mount\ storage\ which\ is\ different\ from\ SMP[uuid\:%s],\ please\ check\ it = +host[uuid\:%s]\ might\ mount\ storage\ which\ is\ different\ from\ SMP[uuid\:%s],\ please\ check\ it = 物理机[uuid:{0}]可能装载与SMP[uuid:{1}]不同的存储,请检查 + +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java:1139 +# args: volumeUuid,infos.toString() +volume[uuid\:%s]\ has\ reference\ volume[%s],\ can\ not\ change\ volume\ type\ before\ flatten\ them\ and\ their\ descendants = 卷[uuid:{0}]具有引用卷[{1}],在展平它们及其后代之前无法更改卷类型 -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java:497 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java:597 # args: not\ supported\ operation = 不支持的操作 -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:106 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:109 # args: psUuid,vmUuid,volumeUuid -the\ SMP\ primary\ storage[uuid\:%s]\ is\ not\ attached\ to\ any\ clusters,\ and\ cannot\ expunge\ the\ root\ volume[uuid\:%s]\ of\ the\ VM[uuid\:%s] = SMP主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除云主机[uuid:{2}]的根云盘[uuid:{1}] +the\ SMP\ primary\ storage[uuid\:%s]\ is\ not\ attached\ to\ any\ clusters,\ and\ cannot\ expunge\ the\ root\ volume[uuid\:%s]\ of\ the\ VM[uuid\:%s] = SMP主存储[uuid:{0}]没有挂载到任何集群,无法彻底删除云主机[uuid:{2}]的云盘[uuid:{1}] -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:300 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:303 # args: pri.getUuid() cannot\ find\ a\ Connected\ host\ to\ execute\ command\ for\ smp\ primary\ storage[uuid\:%s] = 找不到一个已连接状态的物理机为SMP主存储[uuid:{0}]执行命令 -# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:320 +# at: src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java:323 # args: pri.getUuid() cannot\ find\ a\ host\ which\ has\ Connected\ host-SMP\ connection\ to\ execute\ command\ for\ smp\ primary\ storage[uuid\:%s] = 找不到一个和SMP主存储[uuid:{0}]处于已连接状态的物理机为其执行命令 @@ -7998,323 +12810,507 @@ cannot\ find\ a\ host\ which\ has\ Connected\ host-SMP\ connection\ to\ execute\ # args: \ the\ url\ contains\ an\ invalid\ folder[/dev\ or\ /proc\ or\ /sys] = URL包含了一个无效的目录[/dev or /proc or /sys] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:88 +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:96 +# args: +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ not\ exists. = 无法取消删除作业。卷[uuid:{0}]不存在。 + +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:100 +# args: +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ not\ attached\ to\ any\ vm,\ offline\ snapshot\ deletion\ do\ not\ support\ cancel. = 无法取消删除作业。卷[uuid:{0}]未连接到任何VM,脱机快照删除不支持取消。 + +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:106 +# args: +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ attached\ vm\ not\ exists,\ offline\ snapshot\ deletion\ do\ not\ support\ cancel. = 无法取消删除作业。卷[uuid:{0}]连接的VM不存在,脱机快照删除不支持取消。 + +# at: src/main/java/org/zstack/storage/snapshot/DeleteVolumeSnapshotLongJob.java:111 +# args: VmInstanceState.Running +failed\ to\ cancel\ deletion\ job.\ Volume[uuid\:%s]\ attached\ vm\ not\ in\ state\ %s\ offline\ snapshot\ deletion\ do\ not\ support\ cancel. = 无法取消删除作业。卷[uuid:{0}]连接的VM未处于状态{1}脱机快照删除不支持取消。 + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:100 +# args: disabledSnapshotUuids +volume\ snapshot[uuids\:%s]\ is\ in\ state\ Disabled,\ cannot\ revert\ volume\ to\ it = 卷快照[uuid:{0}]处于禁用状态,无法将卷恢复为该状态 + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:121 # args: VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() -Can\ not\ take\ memory\ snapshot,\ expected\ vm\ states\ are\ [%s,\ %s] = +Can\ not\ take\ memory\ snapshot,\ expected\ vm\ states\ are\ [%s,\ %s] = 无法获取内存快照,预期的VM状态为[{0},{1}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:155 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:188 # args: msg.getUuid(),state volume\ snapshot[uuid\:%s]\ is\ in\ state\ %s,\ cannot\ revert\ volume\ to\ it = 云盘快照[uuid:{0}]出于状态{1},不能恢复云盘到该快照状态 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:160 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:193 # args: msg.getUuid() original\ volume\ for\ snapshot[uuid\:%s]\ has\ been\ deleted,\ cannot\ revert\ volume\ to\ it = 快照[uuid:{0}]的原版云盘已经被删除,不能恢复云盘到该快照 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:178 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:211 # args: msg.getVolumeUuid(),snapshotVO.getVolumeUuid() -not\ support\ delete\ snapshots\ on\ different\ volumes[uuid\:\ %s,\ %s] = +not\ support\ delete\ snapshots\ on\ different\ volumes[uuid\:\ %s,\ %s] = 不支持删除不同卷上的快照[uuid:{0},{1}] -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:182 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotApiInterceptor.java:215 # args: msg.getUuids() -can\ not\ find\ volume\ uuid\ for\ snapshosts[uuid\:\ %s] = +can\ not\ find\ volume\ uuid\ for\ snapshosts[uuid\:\ %s] = 找不到快照物理机[uuid:{0}]的卷uuid -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:521 -# args: maxIncrementalSnapshotNum,vo.getVolumeUuid() -Unsupported\ maximum\ snapshot\ number\ (%d)\ for\ volume\ [uuid\:%s] = +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:834 +# args: PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value(),volumeSize +after\ subtracting\ reserved\ capacity[%s],\ there\ is\ no\ primary\ storage\ having\ required\ size[%s\ bytes],\ may\ be\ the\ threshold\ of\ primary\ storage\ physical\ capacity\ setting\ is\ lower = 减去保留容量[{0}]后,没有具有所需大小[{1}字节]的主存储,可能是主存储物理容量设置的阈值较低 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:618 -# args: vol.getUuid(),reply.getError() -cannot\ ask\ primary\ storage[uuid\:%s]\ for\ volume\ snapshot\ capability,\ see\ detail\ [%s] = +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:617 +# args: maxIncrementalSnapshotNum,vo.getVolumeUuid() +Unsupported\ maximum\ snapshot\ number\ (%d)\ for\ volume\ [uuid\:%s] = 不支持卷[uuid:{1}]的最大快照数({0}) -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:814 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1044 # args: primaryStorageUuid,vol.getUuid() primary\ storage[uuid\:%s]\ doesn't\ support\ volume\ snapshot;\ cannot\ create\ snapshot\ for\ volume[uuid\:%s] = 主存储[uuid:{0}]不能支持云盘快照,不能为云盘[uuid:{1}]创建快照 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:780 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1010 # args: vol.getPrimaryStorageUuid() -cannot\ find\ type\ for\ primaryStorage\ [%s] = +cannot\ find\ type\ for\ primaryStorage\ [%s] = 找不到PrimaryStorage[{0}]的类型 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:877 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1107 # args: uuid -cannot\ find\ snapshot\:\ %s = +cannot\ find\ snapshot\:\ %s = 找不到快照:{0} + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotManagerImpl.java:1176 +# args: msg.getResourceType() +this\ resource\ type\ %s\ does\ not\ support\ querying\ memory\ snapshot\ references = 此资源类型{0}不支持查询内存快照引用 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:153 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:162 # args: currentRoot.getUuid(),currentRoot.getName() cannot\ find\ volume\ snapshot[uuid\:%s,\ name\:%s],\ it\ may\ have\ been\ deleted\ by\ previous\ operation = 不能创建云盘快照[uuid:{0}, name:{1}],该快照可能已经被以前的操作删除 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:759 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:418 +# args: refVolUuids +snapshot\ or\ its\ desendant\ has\ reference\ volume[uuids\:%s] = 快照或其目标具有引用卷[uuid:{0}] + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:1004 # args: failSnapshot.getUuid(),failSnapshot.getName(),evt failed\ to\ change\ status\ of\ volume\ snapshot[uuid\:%s,\ name\:%s]\ by\ status\ event[%s] = 通过状态事件[{2}]改变云盘快照[uuid:{0}, name:{1}]失败 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:1465 +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:1847 # args: volumeInventory.getUuid(),currentRoot.getUuid(),vmUuid,state -unable\ to\ reset\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s],\ the\ vm[uuid\:%s]\ volume\ attached\ to\ is\ not\ in\ Stopped\ state,\ current\ state\ is\ %s = 不能重置云盘[uuid:{0}]到快照[uuid:{1}]状态,云盘的虚拟机[uuid:{2}]未处于停止状态,当前状态是{3} +unable\ to\ reset\ volume[uuid\:%s]\ to\ snapshot[uuid\:%s],\ the\ vm[uuid\:%s]\ volume\ attached\ to\ is\ not\ in\ Stopped\ state,\ current\ state\ is\ %s = 不能重置云盘[uuid:{0}]到快照[uuid:{1}]状态,云盘的云主机[uuid:{2}]未处于停止状态,当前状态是{3} + +# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:2228 +# args: currentRoot.getUuid() +current\ snapshot\:%s\ is\ not\ latest\ snapshot,\ cannot\ mark\ as\ volume = 当前快照:{0}不是最新的快照,无法标记为卷 + +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupBase.java:282 +# args: ext.getArchiveBundleCanonicalName() +no\ bundle\ found\ for\ type\:%s = 未找到类型为{0}的包 -# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:77 +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:89 # args: String.join(", ", deletedSnapshotInfos) snapshot(s)\ %s\ in\ the\ group\ has\ been\ deleted,\ can\ only\ revert\ one\ by\ one. = 快照组里的快照{0}已经被删除了,仅能单盘恢复。 -# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:81 +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:93 # args: String.join(", ", detachedVolInfos) volume(s)\ %s\ is\ no\ longer\ attached,\ can\ only\ revert\ one\ by\ one.\ If\ you\ need\ to\ group\ revert,\ please\ re-attach\ it. = 云盘{0}已被卸载,仅能单盘恢复;如果需要整组恢复,请重新加载再执行操作 -# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:89 +# at: src/main/java/org/zstack/storage/snapshot/group/VolumeSnapshotGroupChecker.java:101 # args: volInfos new\ volume(s)\ %s\ attached\ after\ snapshot\ point,\ can\ only\ revert\ one\ by\ one.\ If\ you\ need\ to\ group\ revert,\ please\ detach\ it. = 在快照点之后加载了新的云盘{0},仅能单盘恢复;如果需要整组恢复,请先卸载再执行操作 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:269 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:292 # args: -Can't\ attach\ volume\ to\ VM,\ no\ qualified\ cluster = 不能加载云盘到虚拟机上,没有可用集群 +Can't\ attach\ volume\ to\ VM,\ no\ qualified\ cluster = 不能加载云盘到云主机上,没有可用集群 + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:407 +# args: psUuid,msg.getPrimaryStorageUuid() +primaryStorageUuid\ conflict,\ the\ primary\ storage\ specified\ by\ the\ disk\ offering\ is\ %s,\ and\ the\ primary\ storage\ specified\ in\ the\ creation\ parameter\ is\ %s = PrimaryStorageuuid冲突,磁盘产品指定的主存储为{0},而创建参数中指定的主存储为{1} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:137 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:156 # args: vol.getUuid(),vol.getStatus() volume[uuid\:%s]\ is\ not\ in\ status\ Ready,\ current\ is\ %s,\ can't\ create\ snapshot = 云盘[uuid:{0}]未出于就绪状态,当前是{1},不能创建快照 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:113 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:126 # args: msg.getVolumeUuid(),type -volume[uuid\:%s,\ type\:%s],\ can't\ create\ snapshot = - -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:127 -# args: msg.getRootVolumeUuid() -volume[uuid\:%s]\ is\ root\ volume = +volume[uuid\:%s,\ type\:%s],\ can't\ create\ snapshot = 卷[uuid:{0},类型:{1}],无法创建快照 # at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:131 -# args: vmvo.getState().toString(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() -Can\ not\ take\ memory\ snapshot,\ vm\ current\ state[%s],\ but\ expect\ state\ are\ [%s,\ %s] = +# args: msg.getVolumeUuid(),state +volume[uuid\:%s]\ is\ not\ in\ state\ Enabled,\ current\ is\ %s,\ can't\ create\ snapshot = 卷[uuid:{0}]未处于启用状态,当前为{1},无法创建快照 # at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:150 +# args: vmvo.getState().toString(),VmInstanceState.Running.toString(),VmInstanceState.Paused.toString() +Can\ not\ take\ memory\ snapshot,\ vm\ current\ state[%s],\ but\ expect\ state\ are\ [%s,\ %s] = 无法获取内存快照,VM当前状态为[{0}],但预期状态为[{1},{2}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:183 # args: msg.getVolumeUuid() -the\ volume[uuid\:%s]\ is\ not\ in\ status\ of\ deleted.\ This\ is\ operation\ is\ to\ recover\ a\ deleted\ data\ volume = 云盘[uuid:{0}]未处于删除状态。此操作将覆盖一个被删除的数据云盘 +the\ volume[uuid\:%s]\ is\ not\ in\ status\ of\ deleted.\ This\ is\ operation\ is\ to\ recover\ a\ deleted\ data\ volume = 云盘[uuid:{0}]未处于删除状态。此操作将覆盖一个被删除的云盘 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:296 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:319 # args: vol.getUuid() the\ volume[uuid\:%s]\ is\ in\ status\ of\ deleted,\ cannot\ do\ the\ operation = 云盘[uuid:{0}]已经被删除,不能执行此操作 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:168 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:201 # args: msg.getImageUuid(),ImageMediaType.DataVolumeTemplate,type image[uuid\:%s]\ is\ not\ %s,\ it's\ %s = 镜像[uuid:{0}]不是{1},而是{2} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:172 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:205 # args: img.getUuid(),img.getState() image[uuid\:%s]\ is\ not\ Enabled,\ it's\ %s = 镜像不能启用,此镜像是{1} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:176 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:209 # args: img.getUuid(),img.getStatus() image[uuid\:%s]\ is\ not\ Ready,\ it's\ %s = 镜像未准备就绪,此镜像是{1} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:182 -# args: -DataVolumeFromVolumeTemplate\ not\ support\ Shareable = - -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:197 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:221 # args: msg.getVolumeUuid() -volume[uuid\:%s]\ is\ Root\ volume,\ can\ not\ be\ attach\ to\ vm = 云盘[uuid:{0}]是一个根云盘,不能被手动挂载到其他云主机 +volume[uuid\:%s]\ is\ Root\ volume,\ can\ not\ be\ attach\ to\ vm = 云盘[uuid:{0}]是一个云盘,不能被手动挂载到其他云主机 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:204 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:228 # args: msg.getVolumeUuid(),state,VolumeState.Enabled -volume[uuid\:%s]\ is\ in\ state[%s],\ data\ volume\ can\ only\ be\ attached\ when\ state\ is\ %s = 云盘[uuid:{0}]处于[{1}]状态,数据云盘只能在处于{2}状态的时候挂载 +volume[uuid\:%s]\ is\ in\ state[%s],\ data\ volume\ can\ only\ be\ attached\ when\ state\ is\ %s = 云盘[uuid:{0}]处于[{1}]状态,云盘只能在处于{2}状态的时候挂载 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:209 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:233 # args: msg.getVolumeUuid(),status,VolumeStatus.Ready,VolumeStatus.NotInstantiated -volume[uuid\:%s]\ is\ in\ status[%s],\ data\ volume\ can\ only\ be\ attached\ when\ status\ is\ %s\ or\ %S = 云盘[uuid:{0}]处于[{1}],数据云盘只能在处于{2}或%S状态的时候挂载 +volume[uuid\:%s]\ is\ in\ status[%s],\ data\ volume\ can\ only\ be\ attached\ when\ status\ is\ %s\ or\ %S = 云盘[uuid:{0}]处于[{1}],云盘只能在处于{2}或%S状态的时候挂载 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:216 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:240 # args: msg.getVolumeUuid() -data\ volume[uuid\:%s]\ is\ not\ attached\ to\ any\ vm,\ can't\ detach = 数据云盘没有被挂载到任何云主机上,不能卸载 +data\ volume[uuid\:%s]\ is\ not\ attached\ to\ any\ vm,\ can't\ detach = 云盘没有被挂载到任何云主机上,不能卸载 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:220 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:244 # args: msg.getVolumeUuid() -to\ detach\ shareable\ data\ volume[uuid\:%s],\ vm\ uuid\ is\ needed. = 卸载共享数据云盘[uuid:{0}]需要虚拟机的uuid +to\ detach\ shareable\ data\ volume[uuid\:%s],\ vm\ uuid\ is\ needed. = 卸载共享云盘[uuid:{0}]需要云主机的uuid -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:225 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:249 # args: vol.getUuid(),vol.getName(),vol.getType() -the\ volume[uuid\:%s,\ name\:%s,\ type\:%s]\ can't\ detach\ it = +the\ volume[uuid\:%s,\ name\:%s,\ type\:%s]\ can't\ detach\ it = 卷[uuid:{0},名称:{1},类型:{2}]无法将其分离 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:282 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:305 # args: msg.getVmInstanceUuid(),msg.getVolumeUuid() -the\ vm[uuid\:%s]\ doesn't\ support\ to\ online\ attach\ volume[%s]\ on\ the\ basis\ of\ that\ the\ image\ platform\ type\ of\ the\ vm\ is\ other\ = 云主机[uuid:{0}]不支持在线挂载云盘[{1}]。因为这台虚拟机的基础镜像平台类型为“其他” +the\ vm[uuid\:%s]\ doesn't\ support\ to\ online\ attach\ volume[%s]\ on\ the\ basis\ of\ that\ the\ image\ platform\ type\ of\ the\ vm\ is\ other\ = 云主机[uuid:{0}]不支持在线挂载云盘[{1}]。因为这台云主机的基础镜像平台类型为“其他” -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:287 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:310 # args: vol.getUuid(),vol.getName() -the\ volume[uuid\:%s,\ name\:%s]\ is\ Root\ Volume,\ can't\ attach\ it = 不能挂载根云盘[uuid:{0}, name:{1}] +the\ volume[uuid\:%s,\ name\:%s]\ is\ Root\ Volume,\ can't\ attach\ it = 不能挂载云盘[uuid:{0}, name:{1}] -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:292 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:315 # args: vol.getUuid() -data\ volume[uuid\:%s]\ is\ Disabled,\ can't\ attach = 数据云盘已被禁用,不能挂载 +data\ volume[uuid\:%s]\ is\ Disabled,\ can't\ attach = 云盘已被禁用,不能挂载 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:300 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:323 # args: vol.getUuid() -data\ volume[uuid\:%s]\ has\ been\ attached\ to\ some\ vm,\ can't\ attach\ again = 数据云盘[uuid:{0}]已经被加载上云主机了,不能再次加载 +data\ volume[uuid\:%s]\ has\ been\ attached\ to\ some\ vm,\ can't\ attach\ again = 云盘[uuid:{0}]已经被加载上云主机了,不能再次加载 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:305 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:328 # args: VolumeStatus.Ready,VolumeStatus.NotInstantiated,vol.getStatus() -data\ volume\ can\ only\ be\ attached\ when\ status\ is\ [%s,\ %s],\ current\ is\ %s = 数据云盘仅能当处于[{0}, {1}]状态挂载,当前状态是{2} +data\ volume\ can\ only\ be\ attached\ when\ status\ is\ [%s,\ %s],\ current\ is\ %s = 云盘仅能当处于[{0}, {1}]状态挂载,当前状态是{2} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:313 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:336 # args: vol.getUuid(),vol.getFormat(),hvTypes,msg.getVmInstanceUuid(),hvType -data\ volume[uuid\:%s]\ has\ format[%s]\ that\ can\ only\ be\ attached\ to\ hypervisor[%s],\ but\ vm[uuid\:%s]\ has\ hypervisor\ type[%s].\ Can't\ attach = 只有[{1}]格式的数据云盘[uuid:{0}]才能被挂载到管理程序[{2}],但是虚拟机是[{4}]类型的管理程序,数据云盘不能挂载到该虚拟机 +data\ volume[uuid\:%s]\ has\ format[%s]\ that\ can\ only\ be\ attached\ to\ hypervisor[%s],\ but\ vm[uuid\:%s]\ has\ hypervisor\ type[%s].\ Can't\ attach = 只有[{1}]格式的云盘[uuid:{0}]才能被挂载到管理程序[{2}],但是云主机是[{4}]类型的管理程序,云盘不能挂载到该云主机 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:326 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:349 # args: hvType,maxDataVolumeNum,count,msg.getVmInstanceUuid() -hypervisor[%s]\ only\ allows\ max\ %s\ data\ volumes\ to\ be\ attached\ to\ a\ single\ vm;\ there\ have\ been\ %s\ data\ volumes\ attached\ to\ vm[uuid\:%s] = [{0}]管理程序仅允许最大不超过{1}数据云盘挂载到单个虚拟机。{2} data volumes已经挂载到虚拟机[uuid:{3}] +hypervisor[%s]\ only\ allows\ max\ %s\ data\ volumes\ to\ be\ attached\ to\ a\ single\ vm;\ there\ have\ been\ %s\ data\ volumes\ attached\ to\ vm[uuid\:%s] = [{0}]管理程序仅允许最大不超过{1}云盘挂载到单个云主机。{2} data volumes已经挂载到云主机[uuid:{3}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:367 +# args: hostUuid,vol.getPrimaryStorageUuid() +Can\ not\ attach\ volume\ to\ vm\ runs\ on\ host[uuid\:\ %s]\ which\ is\ disconnected\ with\ volume's\ storage[uuid\:\ %s] = 无法将卷附加到物理机[uuid:{0}]上运行的VM,该物理机已与卷的存储[uuid:{1}]断开连接 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:338 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:378 # args: msg.getUuid() -it's\ not\ allowed\ to\ backup\ root\ volume,\ uuid\:%s = 备份根云盘不被允许,uuid:{0} +it's\ not\ allowed\ to\ backup\ root\ volume,\ uuid\:%s = 备份云盘不被允许,uuid:{0} -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:347 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:387 # args: -unexpected\ disk\ size\ settings = +unexpected\ disk\ size\ settings = 意外的磁盘大小设置 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:365 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:427 # args: msg.getVolumeUuid(),type -volume[uuid\:%s,\ type\:%s]\ can't\ be\ deleted = +volume[uuid\:%s,\ type\:%s]\ can't\ be\ deleted = 无法删除卷[uuid:{0},类型:{1}] -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:370 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:432 # args: msg.getVolumeUuid() volume[uuid\:%s]\ is\ already\ in\ status\ of\ deleted = 云盘[uuid:{0}]早已处于被删除状态 -# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:384 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:438 +# args: msg.getVolumeUuid(),hostUuid +can\ not\ delete\ volume[%s],\ because\ volume\ attach\ to\ host[%s] = 无法删除卷[{0}],因为卷连接到物理机[{1}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:453 +# args: msg.getUuid() +it's\ not\ allowed\ to\ change\ state\ of\ root\ volume,\ uuid\:%s = 不能改变云盘状态,uuid:{0} + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:461 +# args: msg.getVolumeUuid(),hostUuid +can\ not\ change\ volume[%s]\ state,\ because\ volume\ attach\ to\ host[%s] = 无法更改卷[{0}]状态,因为卷连接到物理机[{1}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:469 +# args: msg.getVolumeUuid(),msg.getHostUuid(),hostStatus +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ host[status\:%s]\ is\ not\ connected = 无法将云盘[{0}]挂载到物理机[{1}],因为物理机[status:{2}]未连接 + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:474 +# args: +mount\ path\ must\ be\ absolute\ path = 装载路径必须是绝对路径 + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:491 +# args: msg.getVolumeUuid(),msg.getHostUuid(),hostUuid +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ volume\ is\ attaching\ to\ host[%s] = 无法将云盘[{0}]挂载到物理机[{1}],因为云盘正在挂载到物理机[{2}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:495 +# args: msg.getVolumeUuid(),msg.getHostUuid(),msg.getVolumeUuid(),mountPath,hostUuid +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ the\ volume[%s]\ occupies\ the\ mount\ path[%s]\ on\ host[%s] = 无法将云盘[{0}]挂载到物理机[{1}],因为云盘[{2}]在物理机[{4}]上占用了挂载路径[{3}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:505 +# args: msg.getVolumeUuid(),msg.getHostUuid(),msg.getMountPath() +can\ not\ attach\ volume[%s]\ to\ host[%s],\ because\ the\ another\ volume\ occupies\ the\ mount\ path[%s] = 无法将云盘[{0}]挂载到物理机[{1}],因为另一个云盘占用了挂载路径[{2}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:512 +# args: msg.getVolumeUuid() +can\ not\ detach\ volume[%s]\ from\ host.\ it\ may\ have\ been\ detached = 无法从物理机分离卷[{0}]。它可能已经分离了。 + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:520 +# args: msg.getVolumeUuid() +cannot\ flatten\ a\ shareable\ volume[uuid\:%s] = 无法平整可共享的卷[uuid:{0}] + +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:531 # args: msg.getUuid() -it's\ not\ allowed\ to\ change\ state\ of\ root\ volume,\ uuid\:%s = 不能改变根云盘状态,uuid:{0} +can\ not\ found\ in\ used\ snapshot\ tree\ of\ volume[uuid\:\ %s] = 在卷[uuid:{0}]的已使用快照树中找不到 -# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:687 +# at: src/main/java/org/zstack/storage/volume/VolumeApiInterceptor.java:541 +# args: +cannot\ undo\ not\ latest\ snapshot = 无法撤消不是最新的快照 + +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:200 +# args: self.getRootImageUuid() +cannot\ find\ image\ cache[imageUuid\:\ %s]\ for\ reinit\ volume = 找不到重新初始化卷的镜像缓存[imageUuid:{0}] + +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:843 # args: self.getUuid(),self.getName() the\ volume[uuid\:%s,\ name\:%s]\ is\ not\ deleted\ yet,\ can't\ expunge\ it = 云盘[uuid:{0}, name:{1}]仍未被删除,不能清除该云盘 -# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:194 +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:1780 +# args: +volume[uuid%s]\ should\ be\ attached. = 应附加卷[uuid{0}]。 + +# at: src/main/java/org/zstack/storage/volume/VolumeBase.java:1866 +# args: +only\ support\ detached\ volume,\ use\ SetVmBootVolumeMsg\ instead. = 仅支持分离卷,请改用SetVMBootVolumeMsg。 + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:166 +# args: msg.getPrimaryStorageUuid() +get\ primaryStorage\ %s\ type\ failed = 获取PrimaryStorage{0}类型失败 + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:170 +# args: psType +primaryStorage\ type\ [%s]\ not\ support\ shared\ volume\ yet = 主存储类型[{0}]尚不支持共享云盘 + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:296 # args: template.getUuid(),template.getName() the\ image[uuid\:%s,\ name\:%s]\ has\ been\ deleted\ on\ all\ backup\ storage = 镜像[uuid:{0}, name:{1}]已经从所有的镜像服务器中删除 -# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:211 +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:313 # args: template.getUuid(),msg.getPrimaryStorageUuid() cannot\ find\ a\ backup\ storage\ on\ which\ the\ image[uuid\:%s]\ is\ that\ satisfies\ all\ conditions\ of\:\ 1.\ has\ state\ Enabled\ 2.\ has\ status\ Connected.\ 3\ has\ attached\ to\ zone\ in\ which\ primary\ storage[uuid\:%s]\ is = 无法找到一个镜像[uuid:{0}]所在的镜像服务器符合全部的下列条件: 状态启动[state:Enabled],已连接[status:Connected],被挂载到主存储[uuid:{1}]所在的区域中 -# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:695 +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:868 +# args: +target\ volume\ is\ expunged\ during\ volume\ creation = 目标卷在卷创建过程中被删除 + +# at: src/main/java/org/zstack/storage/volume/VolumeManagerImpl.java:1106 # args: VolumeFactory.class.getSimpleName() there\ should\ not\ be\ more\ than\ one\ %s\ implementation. = 不允许超过一种实现 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:77 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:231 +# args: msg.getUuid() +volume[uuid\:%s]\ is\ not\ root\ volume = 云盘[uuid:{0}]不是云盘 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:95 +# args: IOTHREAD_QEMU_VERSION,qemuVersion,finalHostUuid +iothread\ need\ qemu\ version\ >\=\ %s,\ but\ %s\ on\ host[%s]. = IOThread需要QEMU版本>={0},但物理机[{2}]上需要{1}。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:103 +# args: IOTHREAD_LIBVIRT_VERSION,libvirtVersion,finalHostUuid +iothread\ need\ libvirt\ version\ >\=\ %s,\ but\ %s\ on\ host[%s]. = IOThread需要libvirt版本>={0},但物理机[{2}]上需要{1}。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:108 +# args: msg.getVolumeUuid() +root\ volume[%s]\ cannot\ set\ iothreadpin. = 根卷[{0}]无法设置ioThreadPin。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:115 +# args: msg.getIoThreadId(),msg.getVolumeUuid(),pinInfo[0] +current\ iothread\ id[%s]\ is\ not\ the\ same\ as\ attached\ vol[%s]\ iothread[%s]. = 当前ioThread ID[{0}]与附加的卷[{1}]ioThread[{2}]不同。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:131 +# args: msg.getUuid() +snapshot\ validation\ is\ unsupported\ for\ volume[uuid\:\ %s].\ Volume\ should\ be\ attached\ to\ vm = 卷[uuid:{0}]不支持快照验证。卷应连接到云主机 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:139 +# args: msg.getUuid(),VmInstanceState.Running,VmInstanceState.Paused +snapshot\ validation\ is\ unsupported\ for\ volume[uuid\:\ %s].\ Attached\ vm\ is\ not\ in\ state\ of\ [%s,\ %s] = 卷[uuid:{0}]不支持快照验证。连接的云主机未处于[{1},{2}]状态 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:149 # args: volumeUuid -volume[uuid\:%s]\ can\ not\ found = +volume[uuid\:%s]\ can\ not\ found = 未找到卷[uuid:{0}] -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:84 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:156 # args: volumeUuid,volumeVOS.get(0).getUuid(),volumeVO.getVmInstanceUuid(),volumeVOS.get(0).getVmInstanceUuid() -not\ support\ take\ snapshots\ volume[uuid\:%s,\ uuid\:%s]\ on\ different\ vms[uuid\:%s,\ uuid\:%s] = +not\ support\ take\ snapshots\ volume[uuid\:%s,\ uuid\:%s]\ on\ different\ vms[uuid\:%s,\ uuid\:%s] = 不支持在不同的云主机[uuid:{2},uuid:{3}]上拍摄卷[UUId:{0},UUId:{1}]的快照 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:91 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:163 # args: volumeUuid -volume[uuid\:%s]\ is\ not\ ready = +volume[uuid\:%s]\ is\ not\ ready = 卷[uuid:{0}]未就绪 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:106 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:178 # args: vmInstanceVO.getUuid(),vmInstanceVO.getState() -state\ of\ vm[uuid\:\ %s]\ is\ %s,\ not\ allowed\ to\ take\ snapshots = +state\ of\ vm[uuid\:\ %s]\ is\ %s,\ not\ allowed\ to\ take\ snapshots = VM[uuid:{0}]的状态为{1},不允许拍摄快照 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:142 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:188 # args: msg.getUuid() -volume[uuid\:%s]\ is\ not\ data\ volume = 云盘[uuid:{0}]不是数据云盘 +volume[uuid\:%s]\ is\ not\ data\ volume = 云盘[uuid:{0}]不是云盘 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:162 -# args: msg.getUuid() -volume[uuid\:%s]\ is\ not\ root\ volume = 云盘[uuid:{0}]不是根云盘 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:198 +# args: msg.getVolumeUuid() +can\ not\ resize\ volume[%s],\ because\ volume\ state\ is\ Disabled = 无法调整卷[{0}]的大小,因为卷状态已禁用 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:174 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:212 +# args: +At\ least\ one\ of\ vmInstanceUuid\ or\ uuid\ should\ be\ set = 至少应设置VMInstanceuuid或uuid中的一个 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:227 +# args: msg.getUuid(),msg.getVmInstanceUuid() +no\ volume[uuid\:%s,\ vmInstanceUuid\:%s]\ can\ be\ found = 找不到卷[uuid:{0},VMInstanceuuid:{1}] + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:245 # args: SharedVolume\ cannot\ be\ set\ bandwidth. = 共享云盘不允许设置带宽 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:182 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:254 +# args: +Cannot\ set\ legacy\ params\ and\ new\ params\ at\ the\ same\ time. = 不能同时设置旧参数和新参数。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:259 +# args: +Cannot\ set\ the\ read/write\ and\ the\ total\ IOPS\ limits\ at\ the\ same\ time. = 无法同时设置读/写和总IOPS限制。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:264 +# args: +Cannot\ set\ the\ read/write\ and\ the\ total\ bandwidth\ limits\ at\ the\ same\ time. = 无法同时设置读/写和总带宽限制。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:273 +# args: +The\ volume\ bandwidth\ cannot\ be\ null,\ must\ give\ a\ volume\ bandwidth\ value. = 卷带宽不能为空,必须提供卷带宽值。 + +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:284 # args: vo.getType(),vo.getUuid() Cannot\ shrink\ [%s]\ volume[uuid\:%s]'s\ size = 不能缩小云盘[uuid:{1}]的大小 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:189 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:291 # args: Minimum\ increase\ size\ should\ be\ larger\ than\ 4MB = 最小扩容量需要大于4MB -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:213 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:315 # args: Expansion\ operation\ not\ allowed\ at\ all\ host\ disable = 扩展操作不被允许在所有不可用的物理机上进行 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:200 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:302 # args: Expansion\ operation\ not\ allowed\ at\ host\ disable = 扩展操作不被允许在不可用的物理机上进行 -# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:239 +# at: src/main/java/org/zstack/storage/volume/VolumeMevocoApiInterceptor.java:341 # args: vo.getUuid(),notStoppedVmUuids -shared\ volume[uuid\:\ %s]\ has\ attached\ to\ not\ stopped\ vm\ instances[uuids\:\ %s] = +shared\ volume[uuid\:\ %s]\ has\ attached\ to\ not\ stopped\ vm\ instances[uuids\:\ %s] = 共享云盘[uuid:{0}]已连接到未停止的云主机实例[uuid:{1}] -# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:56 +# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:79 # args: msg.getResourceType() no\ resource\ type[%s]\ found\ in\ tag\ system = 标签系统中不存在[{0}]资源类型 -# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:74 +# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:102 # args: msg.getUuid() tag[uuid\:%s]\ is\ an\ inherent\ system\ tag,\ can\ not\ be\ removed = 固有系统标签[uuid:{0}]禁止移除 -# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:100 +# at: src/main/java/org/zstack/tag/TagApiInterceptor.java:128 # args: -The\ argument\ \:'resourceType'\ doesn't\ match\ uuid = 参数: 资源类型(resourceType)与UUID不匹配 +The\ argument\ \:'resourceType'\ doesn't\ match\ uuid = 参数: 资源类型(resourceType)与uuid不匹配 -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:207 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:239 # args: tag,type,resourceType,resourceUuid Duplicated\ Tag[tag\:%s,\ type\:%s,\ resourceType\:%s,\ resourceUuid\:%s] = 标签[tag:{0}, type:{1}, resourceType:{2}, resourceUuid:{3}]重复 -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:645 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:755 # args: tag,resourceType no\ system\ tag\ matches[%s]\ for\ resourceType[%s] = 没有系统标签[{0}]与资源类型[{1}]匹配 -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:818 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:761 +# args: tag,resourceType +validate\ system\ tag\ [%s]\ for\ resourceType[%s]\ failed = 验证ResourceType[{1}]的系统标记[{0}]失败 + +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:944 # args: tag no\ system\ tag\ matches\ %s = 没有找到匹配{0}的系统标签 -# at: src/main/java/org/zstack/tag/TagManagerImpl.java:847 +# at: src/main/java/org/zstack/tag/TagManagerImpl.java:979 # args: tag -tag[%s]\ is\ only\ for\ admin = +tag[%s]\ is\ only\ for\ admin = 标记[{0}]仅适用于管理员 + +# at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:162 +# args: invalidUuids,expectAccountUuid +resource[uuids\:%s]\ is\ not\ owned\ by\ account[uuid\:%s] = 资源[uuid:{0}]不归帐户[uuid:{1}]所有 # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:85 # args: -cannot\ update\ simple\ tag\ pattern\ format = +cannot\ update\ simple\ tag\ pattern\ format = 无法更新简单标记模式格式 # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:83 # args: -you\ can\ only\ update\ token\ name = +you\ can\ only\ update\ token\ name = 您只能更新令牌名称 # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:95 # args: -simple\ tag\ pattern\ has\ no\ tokens = +simple\ tag\ pattern\ has\ no\ tokens = 简单标记模式没有标记 # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:122 # args: sub -illegal\ tag\ uuids\ %s,\ tag\ type\ must\ be\ simple, = +illegal\ tag\ uuids\ %s,\ tag\ type\ must\ be\ simple, = 标记uuid{0}非法,标记类型必须简单。 # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:133 # args: color -Invalid\ color\ specification[%s],\ must\ like\ #FF00FF = +Invalid\ color\ specification[%s],\ must\ like\ #FF00FF = 颜色规范[{0}]无效,必须类似于#FF00FF # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:139 # args: format -Get\ format[%s],\ format\ must\ like\ that\ name\:\:{tokenName1}\:\:{tokenName2}\ ...\ \:\:{tokenNameN}\ or\ {tokenName1}\:\:{tokenName2}\ ...\ \:\:{tokenNameN}\ Name\ cannot\ contain\ '{}\:' = +Get\ format[%s],\ format\ must\ like\ that\ name\:\:{tokenName1}\:\:{tokenName2}\ ...\ \:\:{tokenNameN}\ or\ {tokenName1}\:\:{tokenName2}\ ...\ \:\:{tokenNameN}\ Name\ cannot\ contain\ '{}\:' = 获取格式[{0}],格式必须类似于名称:'{TokenName1}':'{TokenName2}'.:'{TOKENNAMEn}'或'{TOKENNAME1}':?TokenNAME2}.:?TokENNAMEn}名称不能包含“'{}':” # at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:151 # args: formatTokens -all\ tokens\ %s\ must\ be\ specify = +all\ tokens\ %s\ must\ be\ specify = 必须指定所有令牌{0} -# at: src/main/java/org/zstack/tag2/Tag2ApiInterceptor.java:162 -# args: invalidUuids,expectAccountUuid -resource[uuids\:%s]\ is\ not\ owned\ by\ account[uuid\:%s] = - -# at: src/main/java/org/zstack/tag2/TagPatternBase.java:184 +# at: src/main/java/org/zstack/tag2/TagPatternBase.java:185 # args: resourceUuid,attachedCount -resource[uuid\:%s]\ has\ been\ attached\ %d\ tags,\ cannot\ attach\ any\ more = +resource[uuid\:%s]\ has\ been\ attached\ %d\ tags,\ cannot\ attach\ any\ more = 资源[uuid:{0}]已附加{1}个标记,无法再附加 + +# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:79 +# args: msg.getTemplateUuid() +unable\ to\ find\ any\ TemplateConfigs\:\ [templateUuid\:\ %s] = 找不到任何TemplateConfigs:[templateUuid:{0}] + +# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:151 +# args: msg.getTemplateUuid() +Unable\ to\ find\ any\ TemplateConfigs\:\ [templateUuid\:\ %s] = 找不到任何TemplateConfigs:[templateUuid:{0}] -# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:88 +# at: src/main/java/org/zstack/templateConfig/TemplateConfigFacadeImpl.java:128 # args: msg.getCategory(),msg.getName(),msg.getTemplateUuid() -Unable\ to\ find\ TemplateConfig[category\:\ %s,\ name\:\ %s,\ templateUuid\:\ %s] = +Unable\ to\ find\ TemplateConfig[category\:\ %s,\ name\:\ %s,\ templateUuid\:\ %s] = 找不到TemplateConfig[类别:{0},名称:{1},Templateuuid:{2}] + +# at: src/main/java/org/zstack/testlib/premium/crypto/EncryptDriverSimulator.java:123 +# args: algType +illegal\ argument\ %s = 非法参数{0} -# at: src/main/java/org/zstack/ticket/TicketBase.java:239 +# at: src/main/java/org/zstack/testlib/premium/crypto/EncryptDriverSimulator.java:136 +# args: +failed\ to\ decrypt\ data = 无法解密数据 + +# at: src/main/java/org/zstack/testlib/premium/crypto/SecurityMachineSimulator.java:399 +# args: e.getMessage(),cipherText +failed\ to\ parse\ MS\ envelope\:\ %s,\ %s = 无法分析MS信封:{0},{1} + +# at: src/main/java/org/zstack/ticket/TicketBase.java:235 # args: self.getUuid(),self.getName(),self.getStatus() ticket[uuid\:%s,\ name\:%s]\ can\ only\ be\ updated\ after\ being\ cancelled,\ current\ status\ is\ %s = 工单[uuid:{0}, name:{1}]当前状态为{2},不支持更新操作 -# at: src/main/java/org/zstack/ticket/TicketBase.java:293 +# at: src/main/java/org/zstack/ticket/TicketBase.java:299 # args: operator.operatorUuid operation\ denied.\ the\ operator\ needs\ to\ be\ done\ by\ account/virtual\ ID[uuid\:%s] = 操作无效,需要account/virtual ID[uuid:{0}]才能完成操作 @@ -8332,15 +13328,15 @@ no\ accountSystemType[%s]\ defined\ in\ system = 未定义的accountSystemType[{ # at: src/main/java/org/zstack/ticket/api/TicketApiInterceptor.java:74 # args: -not\ matched\ ticket\ type\ found = +not\ matched\ ticket\ type\ found = 未找到匹配的票证类型 # at: src/main/java/org/zstack/ticket/api/TicketApiInterceptor.java:90 # args: msg.getFlowCollectionUuid(),ticketTypeUuid -Ticket\ flow\ collection[uuid\:%s]\ not\ matches\ ticket\ type[uuid\:%s] = +Ticket\ flow\ collection[uuid\:%s]\ not\ matches\ ticket\ type[uuid\:%s] = 票证流集合[uuid:{0}]与票证类型[uuid:{1}]不匹配 # at: src/main/java/org/zstack/ticket/api/TicketApiInterceptor.java:83 # args: -no\ matched\ ticket\ flow\ collection\ or\ no\ default\ ticket\ flow\ collection\ found,\ you\ must\ specify\ the\ flowCollectionUuid\ or\ create\ a\ default\ ticket\ flow\ collection\ in\ system = +no\ matched\ ticket\ flow\ collection\ or\ no\ default\ ticket\ flow\ collection\ found,\ you\ must\ specify\ the\ flowCollectionUuid\ or\ create\ a\ default\ ticket\ flow\ collection\ in\ system = 找不到匹配的票证流集合或找不到默认的票证流集合,必须指定FlowCollectionuuid或在系统中创建默认的票证流集合 # at: src/main/java/org/zstack/ticket/api/TicketApiInterceptor.java:110 # args: req.apiName @@ -8356,11 +13352,11 @@ operation\ denied.\ the\ ticket\ is\ in\ status\ of\ %s,\ cannot\ do\ the\ opera # at: src/main/java/org/zstack/ticket/executor/DefaultSingletonRequestExecutor.java:43 # args: request.apiName -No\ api\ class[name\:%s]\ is\ found = +No\ api\ class[name\:%s]\ is\ found = 找不到API类[名称:{0}] # at: src/main/java/org/zstack/ticket/executor/DefaultSingletonRequestExecutor.java:70 # args: exception.getMessage() -failed\ to\ get\ value\ from\ event\:\ %s = +failed\ to\ get\ value\ from\ event\:\ %s = 无法从事件中获取值:{0} # at: src/main/java/org/zstack/ticket/iam2/IAM2Ticket.java:44 # args: ctx.getVirtualIDUuid(),self.getUuid(),self.getName() @@ -8382,153 +13378,193 @@ the\ virtual\ ID[uuid\:%s]\ is\ not\ the\ owner\ of\ the\ ticket[uuid\:%s,\ name # args: approver\ is\ removed\ from\ project\ or\ deleted,\ flow\ collection\ changed\ to\ invalid,\ reject\ this\ ticket = 审批人已经离开项目或者被删除,流程失效,因此驳回当前工单 -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:118 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:117 # args: at\ least\ one\ flow\ is\ needed\ for\ create\ flow\ collection = 创建流程时需要至少一个步骤 -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:125 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:124 # args: flow.approverTitle,approveTitles wrong\ approver\ title\ %s,\ valid\ value\ is\ %s = 错误的审批人职位{0}, 有效输入为{1} -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:141 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:140 # args: flow.approverUuid can\ not\ find\ IAM2VirtualIDVO[uuid\:%s] = 找不到对应的IAM2VirtualIDVO[uuid:{0}] -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:64 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:62 # args: name\ is\ needed\ when\ create\ a\ flow = 创建步骤时需要填写名称 -# at: src/main/java/org/zstack/storage/snapshot/VolumeSnapshotTreeBase.java:427 -# args: currentRoot.getPrimaryStorageUuid(),currentLeaf.getUuid(),Math.abs(requiredSize - primaryStorageVO.getCapacity().getAvailablePhysicalCapacity()) -primaryStorage[uuid\:%s]\ has\ no\ enough\ space\ to\ rebase\ snapshot[uuid\:%s],\ please\ free\ more\ than\ %s\ bytes\ storage\ space = 主存储[uuid:{0}]没有足够的空间合并快照,请释放大于{2}字节的存储空间。 - -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:81 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:79 # args: -one\ ticket\ type\ can\ only\ have\ one\ matches\ flow\ collection = +one\ ticket\ type\ can\ only\ have\ one\ matches\ flow\ collection = 一个票证类型只能有一个匹配流集合 -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:103 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:102 # args: -admin\ is\ required\ as\ approver\ of\ the\ last\ flow = +admin\ or\ iam2\ operation\ is\ required\ as\ approver\ of\ the\ last\ flow = 需要管理员或IAM2操作作为最后一个流的批准人 -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:129 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:128 # args: name\ cannot\ be\ null = 名称不能为空 -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:133 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:132 # args: -approverUuid\ cannot\ be\ null = +approverUuid\ cannot\ be\ null = Approveruuid不能为空 -# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:148 +# at: src/main/java/org/zstack/ticket/iam2/api/IAM2TicketApiInterceptor.java:147 # args: flow.approverUuid,projectUuid virtual\ id[uuid\:%s]\ not\ belong\ to\ project[uuid\:%s] = virtual id[uuid:{0}]不属于项目[uuid:{1}] -# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:118 +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationIAM2Backend.java:42 +# args: loginType +Unsupported\ AccountType:%s = 不支持的帐户类型:{0} + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:124 # args: two\ factor\ authenticator\ is\ not\ enabled = 双因子认证未启用 -# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:269 +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:484 +# args: +two\ factor\ authentication\ failed\ because\ there\ is\ no\ system\ tags\ in\ msg = 双因素身份验证失败,因为MSG中没有系统标记 + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:490 +# args: +two\ factor\ authentication\ failed\ because\ there\ is\ no\ token\ in\ msg\ system\ tag = 双因素身份验证失败,因为MSG系统标记中没有令牌 + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:497 +# args: loginContext.getLoginBackendType(),info.getUserUuid() +two\ factor\ authentication\ failed\ because\ there\ is\ no\ secret\ for\ %s\:%s = 双因素身份验证失败,因为{0}没有密码:{1} + +# at: src/main/java/org/zstack/twoFactorAuthentication/TwoFactorAuthenticationManagerImpl.java:507 +# args: +failed\ to\ verify\ two\ factor\ authentication\ code = 验证双因素身份验证代码失败 + +# at: src/main/java/org/zstack/upgrade/UpgradeManagerImpl.java:148 +# args: msg.getClass().getName() +Operation\ [%s]\ is\ forbidden\ during\ grayscale\ upgrade = 灰度升级期间禁止操作[{0}] + +# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:267 # args: usbInv.getHostUuid() -host[%s]\ has\ started\ more\ than\ 64\ usb\ redirect\ port = +host[%s]\ has\ started\ more\ than\ 64\ usb\ redirect\ port = 物理机[{0}]已启动64个以上的USB重定向端口 -# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:274 +# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:272 # args: host.getUuid() -unable\ to\ start\ usb\ server\ on\ host[%s],\ because\ host\ is\ not\ connected = +unable\ to\ start\ usb\ server\ on\ host[%s],\ because\ host\ is\ not\ connected = 无法启动物理机[{0}]上的USB服务器,因为物理机未连接 -# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:296 +# at: src/main/java/org/zstack/usbDevice/KvmUsbDeviceBackend/UsbDeviceKvmBackend.java:294 # args: usbInv.getHostUuid() -failed\ to\ start\ usbredirect\ server\ from\ host[uuid\:%s] = +failed\ to\ start\ usbredirect\ server\ from\ host[uuid\:%s] = 无法从物理机[uuid:{0}]启动USBDirect服务器 + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceAllocatorFactory.java:83 +# args: +no\ candidate\ host\ with\ the\ usb\ device\ have\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = usb设备所在的物理机都不满足cpu / memory或状态的条件 + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:60 +# args: msg.getClass().getSimpleName() +%s\ can\ only\ be\ called\ by\ admin\ account = {0}只能被admin账户调用 + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:98 +# args: UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM +You\ can\ attach\ at\ most\ %s\ USB\ 1.0\ devices\ to\ one\ vm\ instance. = 最多可以绑定{0}个USB 1.0设备到一个云主机上 + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:107 +# args: UsbDeviceConstants.MAX_USB_2_DEVICE_PER_VM +You\ can\ attach\ at\ most\ %s\ USB\ 2.0\ devices\ to\ one\ vm\ instance. = 最多可以绑定{0}个USB 2.0设备到一个云主机上 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceAllocatorFactory.java:83 -# args: -no\ candidate\ host\ with\ the\ usb\ device\ have\ enough\ cpu\ /\ memory\ or\ Enabled/Connected\ status = usb设备所在的物理机都不满足cpu / memory或状态的条件 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:116 +# args: UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM +You\ can\ attach\ at\ most\ %s\ USB\ 3.0\ devices\ to\ one\ vm\ instance. = 最多可以绑定{0}个USB 3.0设备到一个云主机上 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:59 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:127 # args: msg.getUsbDeviceUuid(),usb.getVmInstanceUuid() -the\ usb\ device[uuid\:%s]\ has\ already\ been\ attached\ to\ another\ vm[uuid\:%s] = USB设备[uuid:{0}]已经被绑定在其他的虚拟机[uuid:{1}] +the\ usb\ device[uuid\:%s]\ has\ already\ been\ attached\ to\ another\ vm[uuid\:%s] = USB设备[uuid:{0}]已经被绑定在其他的云主机[uuid:{1}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:66 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:134 # args: msg.getUsbDeviceUuid(),UsbDeviceState.Enabled the\ usb\ device[uuid\:%s]\ is\ not\ in\ attachable\ state\ of\ %s = USB设备[uuid:{0}]不处于可绑定的状态[{1}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:74 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:142 # args: msg.getVmInstanceUuid(),allowedVmInstanceAttachableState -the\ vm\ instance[uuid\:%s]\ is\ not\ in\ attachable\ state\ of\ %s\ for\ usb\ device = 虚拟机[uuid:{0}]不能绑定{1}状态的USB设备 +the\ vm\ instance[uuid\:%s]\ is\ not\ in\ attachable\ state\ of\ %s\ for\ usb\ device = 云主机[uuid:{0}]不能绑定{1}状态的USB设备 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:84 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:152 # args: usb.getHostUuid(),msg.getUsbDeviceUuid(),HostState.Enabled,HostStatus.Connected the\ host\ that\ the\ usb\ device[uuid\:%s]\ pluged\ in\ is\ not\ in\ valid\ state[%s]\ or\ status[%s] = 插上USB设备的物理机没有处于一种有效的状态[{1}、{2}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:97 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:165 # args: usb.getUuid(),vm.getUuid() -the\ usb\ device[uuid\:%s]\ has\ different\ hostUuid\ than\ devices\ that\ already\ attached\ to\ the\ vm\ instance[uuid\:%s] = 与已经绑定虚拟机实例相比,USB设备[uuid:{0}]有不同的物理机uuid +the\ usb\ device[uuid\:%s]\ has\ different\ hostUuid\ than\ devices\ that\ already\ attached\ to\ the\ vm\ instance[uuid\:%s] = 与已经绑定云主机实例相比,USB设备[uuid:{0}]有不同的物理机uuid -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:109 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:177 # args: usb.getUuid() -the\ usb\ device[uuid\:%s]\ is\ not\ attached\ to\ any\ vm\ instance. = USB设备[uuid:{0}]不能绑定任何虚拟机实例 +the\ usb\ device[uuid\:%s]\ is\ not\ attached\ to\ any\ vm\ instance. = USB设备[uuid:{0}]不能绑定任何云主机实例 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:117 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:185 # args: usb.getUuid(),allowedVmInstanceDetachableState -the\ vm\ instance\ that\ the\ usb\ device[uuid\:%s]\ is\ attached\ to\ is\ not\ in\ detachable\ state\ of\ %s = 绑定了USB设备[uuid:{0}]的虚拟机实例处于一种不能解绑的状态{1} +the\ vm\ instance\ that\ the\ usb\ device[uuid\:%s]\ is\ attached\ to\ is\ not\ in\ detachable\ state\ of\ %s = 绑定了USB设备[uuid:{0}]的云主机实例处于一种不能解绑的状态{1} -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:127 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:195 # args: vm.getUuid(),allowedVmInstanceAttachableState -vm\ instance[uuid\:%s]\ not\ in\ attachable\ state\ of\ %s\ for\ usb\ device = 虚拟机实例[uuid:{0}]对于USB设备没有处于一种可绑定的状态{1} +vm\ instance[uuid\:%s]\ not\ in\ attachable\ state\ of\ %s\ for\ usb\ device = 云主机实例[uuid:{0}]对于USB设备没有处于一种可绑定的状态{1} -# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:138 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:206 # args: msg.getUuid() -cannot\ disable\ usb\ device[uuid\:%s]\ when\ it's\ attached\ to\ a\ vm\ instance = 当USB设备绑定到虚拟机上时不能禁用该USB设备 - -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:711 -# args: msg.getVmInstanceUuid() -cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ pci\ devices\ attached = 虚拟机[uuid:{0}]加载了pci设备无法迁移 +cannot\ disable\ usb\ device[uuid\:%s]\ when\ it's\ attached\ to\ a\ vm\ instance = 当USB设备绑定到云主机上时不能禁用该USB设备 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:202 -# args: UsbDeviceConstants.MAX_USB_1_DEVICE_PER_VM -You\ can\ attach\ at\ most\ %s\ USB\ 1.0\ devices\ to\ one\ vm\ instance. = 最多可以绑定{0}个USB 1.0设备到一个虚拟机上 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceApiInterceptor.java:218 +# args: VmInstanceUuid +please\ umount\ all\ usb\ devices\ of\ the\ vm[%s]\ and\ try\ again = 请卸载云主机[{0}]的所有USB设备,然后重试 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:217 -# args: UsbDeviceConstants.MAX_USB_2_DEVICE_PER_VM -You\ can\ attach\ at\ most\ %s\ USB\ 2.0\ devices\ to\ one\ vm\ instance. = 最多可以绑定{0}个USB 2.0设备到一个虚拟机上 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:795 +# args: msg.getVmInstanceUuid() +cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ pci\ devices\ attached = 云主机[uuid:{0}]加载了pci设备无法迁移 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:232 -# args: UsbDeviceConstants.MAX_USB_3_DEVICE_PER_VM -You\ can\ attach\ at\ most\ %s\ USB\ 3.0\ devices\ to\ one\ vm\ instance. = 最多可以绑定{0}个USB 3.0设备到一个虚拟机上 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:164 +# args: msg.getUsbDeviceUuid(),usb.getVmInstanceUuid() +the\ usb\ device[uuid\:%s]\ has\ already\ been\ attached\ to\ vm[uuid\:%s] = USB设备[uuid:{0}]已连接到云主机[uuid:{1}] -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:160 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:181 # args: -PassThrough\ only\ support\ use\ on\ vm\ running\ host = +PassThrough\ only\ support\ use\ on\ vm\ running\ host = 直通仅支持在运行物理机的云主机上使用 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:177 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:198 # args: msg.getUsbDeviceUuid(),msg.getVmInstanceUuid() -cannot\ attach\ the\ usb\ device[uuid\:%s]\ to\ vm[uuid\:%s]\ due\ to\ host\ allocation = 不能绑定USB设备[uuid:{0}]到虚拟机[uuid:{1}],因为物理机的配置 +cannot\ attach\ the\ usb\ device[uuid\:%s]\ to\ vm[uuid\:%s],\ possibly\ reasons\ include\:\ the\ device\ is\ not\ enabled\ or\ had\ been\ attached\ to\ a\ vm,\ or\ the\ device\ and\ the\ vm\ are\ not\ on\ same\ host. = 无法将USB设备[uuid:{0}]连接到VM[uuid:{1}],原因可能包括:设备未启用或已连接到VM,或者设备和VM不在同一物理机上。 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:647 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:558 +# args: deviceVO.getVmInstanceUuid() +usb\ is\ already\ bound\ to\ vm[uuid\:%s]\ and\ cannot\ be\ bound\ to\ other\ vm = USB已绑定到VM[uuid:{0}],无法绑定到其他VM + +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:731 # args: msg.getVmInstanceUuid() -vm[%s]\ cannot\ start\ because\ usb\ redirect\ host\ is\ not\ connected = +vm[%s]\ cannot\ start\ because\ usb\ redirect\ host\ is\ not\ connected = 云主机[{0}]无法启动,因为未连接USB重定向物理机 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:660 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:744 # args: msg.getVmInstanceUuid() -cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached\ by\ passthrough = 不能迁移虚拟机[uuid:{0}],因为虚拟机通过直连的方式绑定了USB设备 +cannot\ migrate\ vm[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached\ by\ passthrough = 不能迁移云主机[uuid:{0}],因为云主机通过直连的方式绑定了USB设备 -# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:693 +# at: src/main/java/org/zstack/usbDevice/UsbDeviceManager.java:777 # args: msg.getVolumeUuid() -cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached = 不能迁移根云盘[uuid:{0}],因为USB设备已经被绑定 +cannot\ migrate\ root\ volume[uuid\:%s]\ because\ there\ are\ usb\ devices\ attached = 不能迁移云盘[uuid:{0}],因为USB设备已经被绑定 # at: src/main/java/org/zstack/v2v/CleanConversionVolumeCacheGC.java:43 # args: -not\ the\ time\ to\ clean = +not\ the\ time\ to\ clean = 不是打扫的时候。 # at: src/main/java/org/zstack/v2v/CleanConversionVolumeCacheGC.java:48 # args: conversionHost.getUuid(),conversionHost.getHostUuid() -conversionHost[uuid\:%s,\ hostUuid\:%s]\ is\ not\ Connected = +conversionHost[uuid\:%s,\ hostUuid\:%s]\ is\ not\ Connected = ConversionHost[uuid:{0},Hostuuid:{1}]未连接 + +# at: src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java:91 +# args: hostUuid,psUuid +waiting\ host[uuid\:%s]\ and\ primaryStorage[uuid\:%s]\ Connected... = 正在等待的物理机[uuid:{0}]和主存储[uuid:{1}]已连接.. -# at: src/main/java/org/zstack/v2v/ResumeConvertVmJobGC.java:126 +# at: src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java:149 # args: hostUuid -host[uuid\:%s]\ is\ not\ Connected = +host[uuid\:%s]\ is\ not\ Connected = 物理机[uuid:{0}]未连接 -# at: src/main/java/org/zstack/v2v/ResumeConvertVmJobGC.java:130 +# at: src/main/java/org/zstack/v2v/ConvertVmFromForeignHypervisorJob.java:153 # args: primaryStorageUuid -primaryStorage[uuid%s]\ is\ not\ Connected = +primaryStorage[uuid%s]\ is\ not\ Connected = 主存储[uuid{0}]未连接 # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:186 # args: duplicateMac.get() @@ -8536,7 +13572,15 @@ Not\ allowed\ same\ mac\ [%s] = 不允许存在相同的MAC地址[{0}] # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:205 # args: duplicateElements.get(0) -Can't\ add\ same\ uuid\ in\ the\ l3Network,uuid\:\ %s = 不能添加相同的uuid{0}在L3网络中 +Can't\ add\ same\ uuid\ in\ the\ l3Network,uuid\:\ %s = 不能添加相同的uuid{0}在三层网络中 + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:217 +# args: l3Uuid +l3Network[uuid\:%s]\ is\ Disabled,\ can\ not\ create\ vm\ on\ it = 三层网络[uuid:{0}]没有被启用,不能从这个三层网络创建云主机 + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:220 +# args: l3Uuid +l3Network[uuid\:%s]\ is\ system\ network,\ can\ not\ create\ user\ vm\ on\ it = 三层网络[uuid:{0}]是系统网络,不能在这上面创建云主机 # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:252 # args: msg.getZoneUuid() @@ -8556,31 +13600,31 @@ host[uuid\:%s]\ is\ specified\ but\ it's\ connection\ status\ is\ %s,\ can\ not\ # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:234 # args: msg.getDefaultL3NetworkUuid(),msg.getL3NetworkUuids() -defaultL3NetworkUuid[uuid\:%s]\ is\ not\ in\ l3NetworkUuids%s = 默认L3网络的uuid是[uuid:{0}],不在L3网络uuid们中{1} +defaultL3NetworkUuid[uuid\:%s]\ is\ not\ in\ l3NetworkUuids%s = 默认三层网络的uuid是[uuid:{0}],不在三层网络uuid们中{1} + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:230 +# args: +there\ are\ more\ than\ one\ L3\ network\ specified\ in\ l3NetworkUuids,\ but\ defaultL3NetworkUuid\ is\ null = 在三层网络uuid们中有很多三层网络被指定了,但是默认三层网络的uuid是空的 -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:76 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:84 # args: msg.getHostUuid() -host[uuid\:%s]\ must\ be\ Enabled\ and\ Connected\ to\ be\ a\ conversion\ host = +the\ status\ of\ host[uuid\:%s]\ must\ be\ Connected = 物理机[uuid:{0}]的状态必须为已连接 -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:89 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:97 # args: -v2v\ conversion\ host\ storage\ path\ must\ be\ absolute\ path = +v2v\ conversion\ host\ storage\ path\ must\ be\ absolute\ path = V2V转换物理机存储路径必须为绝对路径 -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:112 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:120 # args: msg.getUrl() -invalid\ v2v\ url\:\ %s = +invalid\ v2v\ url\:\ %s = 无效的V2V URL:{0} -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:123 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:131 # args: srcVmUuid -vm\ instance[uuid\:%s]\ does\ not\ exist\ or\ is\ not\ a\ vmware\ vm = +vm\ instance[uuid\:%s]\ does\ not\ exist\ or\ is\ not\ a\ vmware\ vm = 云主机实例[uuid:{0}]不存在或不是VMware云主机 -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:130 +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:138 # args: -conversionHostUuid\ should\ not\ be\ null = - -# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:136 -# args: msg.getConversionHostUuid() -conversion\ host[uuid\:%s]\ should\ be\ Enabled = +conversionHostUuid\ should\ not\ be\ null = ConversionHostuuid不应为空 # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:148 # args: msg.getConversionHostUuid() @@ -8588,784 +13632,1012 @@ underlying\ host\ of\ conversion\ host[uuid\:%s]\ should\ be\ Connected = 迁移 # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:164 # args: msg.getConversionHostUuid(),msg.getPrimaryStorageUuid() -conversion\ host[uuid\:%s]\ cannot\ connect\ to\ primary\ storage[uuid\:%s] = +conversion\ host[uuid\:%s]\ cannot\ connect\ to\ primary\ storage[uuid\:%s] = 转换物理机[uuid:{0}]无法连接到主存储[uuid:{1}] # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:197 # args: duplicateMacs -Duplicate\ mac\ address\ %s = +Duplicate\ mac\ address\ %s = 重复的MAC地址{0} # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:289 # args: msg.getPrimaryStorageUuid() -primary\ storage[uuid\:%s]\ is\ not\ supported\ for\ v2v = +primary\ storage[uuid\:%s]\ is\ not\ supported\ for\ v2v = V2V不支持主存储[uuid:{0}] # at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:292 # args: msg.getPrimaryStorageUuid() -primary\ storage[uuid\:%s]\ is\ neither\ Enabled\ nor\ Connected = +primary\ storage[uuid\:%s]\ is\ neither\ Enabled\ nor\ Connected = 主存储[uuid:{0}]既未启用也未连接 + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:302 +# args: msg.getVolumeUuid(),msg.getHostUuid() +there\ are\ some\ v2v\ jobs\ in\ progress.\ can\ not\ attach\ volume[%s]\ to\ host[%s] = 有一些V2V作业正在进行中。无法将卷[{0}]附加到物理机[{1}] + +# at: src/main/java/org/zstack/v2v/V2VApiInterceptor.java:313 +# args: msg.getVolumeUuid(),msg.getHostUuid() +there\ are\ some\ v2v\ jobs\ in\ progress.\ can\ not\ detach\ volume[%s]\ from\ host[%s] = 有一些V2V作业正在进行中。无法从物理机[{1}]分离卷[{0}] -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:577 +# at: src/main/java/org/zstack/v2v/V2VConversionHostCapacityUpdater.java:98 +# args: reserveSize,conversionHostVO.getUuid() +cannot\ reserve\ %s\ bytes\ on\ the\ conversion\ host[uuid\:%s],\ it's\ short\ of\ available\ capacity = 无法在转换物理机[uuid:{1}]上保留{0}字节,可用容量不足 + +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:597 # args: l3Uuid -Unable\ to\ find\ L3Network[uuid\:%s]\ to\ start\ the\ current\ vm,\ it\ may\ have\ been\ deleted,\ Operation\ suggestion\:\ delete\ this\ vm,\ recreate\ a\ new\ vm = +Unable\ to\ find\ L3Network[uuid\:%s]\ to\ start\ the\ current\ vm,\ it\ may\ have\ been\ deleted,\ Operation\ suggestion\:\ delete\ this\ vm,\ recreate\ a\ new\ vm = 找不到启动当前云主机的L3Network[uuid:{0}],该云主机可能已被删除,操作建议:删除该云主机,重新创建新的云主机 -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1150 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1207 # args: bandwidth invalid\ network\ bandwidth[%s],\ it\ is\ not\ a\ number = 错误的网络带宽[{0}],这不是数字 -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1145 -# args: bandwidth -invalid\ network\ bandwidth[%s],\ it\ must\ be\ greater\ than\ or\ equal\ to\ 8192 = 错误的网络带宽[{0}],这个数字必须大于等于8K - -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1147 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1204 # args: networkInboundBandwidth\ execeds\ the\ max\ value\ 32G\ bps = 超过下行网络带宽超过最大值32G bps -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:624 -# args: msg.getUrl() -can\ not\ find\ type\ for\ src\ vm[url\:%s] = - -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:638 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:661 # args: msg.getUrl(),msg.getType() -can\ not\ find\ factory\ for\ src\ vm[url\:%s,\ v2vType\:%s] = +can\ not\ find\ factory\ for\ src\ vm[url\:%s,\ v2vType\:%s] = 找不到SRC VM[URL:{0},v2vType:{1}]的工厂 -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:898 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:921 # args: msg.getHostUuid() -there\ has\ been\ a\ v2v\ conversion\ host\ with\ hostUuid\ %s = +there\ has\ been\ a\ v2v\ conversion\ host\ with\ hostUuid\ %s = 已存在Hostuuid为{0}的V2V转换物理机 + +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1196 +# args: +invalid\ v2v\ qos\ systemtag = V2V QoS系统标记无效 -# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1139 +# at: src/main/java/org/zstack/v2v/V2VManagerImpl.java:1202 +# args: bandwidth +invalid\ network\ bandwidth[%s],\ it\ must\ be\ greater\ than\ or\ equal\ to\ 1048576 = 网络带宽[{0}]无效,它必须大于或等于1048576 + +# at: src/main/java/org/zstack/v2v/V2VMsgTranslator.java:118 +# args: srcVmUrl +can\ not\ find\ type\ for\ src\ vm[url\:%s] = 找不到SRC VM[URL:{0}]的类型 + +# at: src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java:890 # args: -invalid\ v2v\ qos\ systemtag = +missing\ VM\ uuid\ in\ 'srcVmUrl' = “ srcvmurl ”中缺少VM uuid -# at: src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java:863 +# at: src/main/java/org/zstack/v2v/kvm/KVMV2VBase.java:956 # args: srcVmUuid -No\ root\ volume\ found\ for\ VM\:\ %s = +No\ root\ volume\ found\ for\ VM\:\ %s = 找不到VM的根卷:{0} -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:189 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1575 +# args: cidr,hostUuid +there\ is\ no\ available\ ip\ found\ in\ cidr\ %s\ on\ host\ %s,\ try\ reconnect\ host\ to\ refresh\ ips = 在物理机{1}上的CIDR{0}中找不到可用的IP,请尝试重新连接物理机以刷新IP + +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:190 # args: job.getUuid() v2v\ job[uuid\:%s]\ is\ running = V2V迁移任务[uuid:{0}]正在运行 -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:788 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:808 # args: srcVmUrl -failed\ to\ get\ virt-v2v\ uri\ for\ %s = +failed\ to\ get\ virt-v2v\ uri\ for\ %s = 无法获取{0}的virt-v2v URI -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:953 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1007 # args: urlBuilder.toString() -Failed\ to\ parse\ url\ %s = +Failed\ to\ parse\ url\ %s = 无法分析URL{0} -# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1231 +# at: src/main/java/org/zstack/v2v/vmware/VMwareV2VBase.java:1288 # args: NOT_SUPPORTED_SPECIAL_CHARACTER -Target\ vm\ name\ can\ not\ contain\ those\ characters\ %s = +Target\ vm\ name\ can\ not\ contain\ those\ characters\ %s = 目标VM名称不能包含这些字符{0} # at: src/main/java/org/zstack/v2v/vmware/VMwareV2VFactory.java:120 # args: jobUuid,msg.getUrl() -There\ is\ already\ a\ long\ job[uuid\:%s]\ convert\ vm\ from\ %s = +There\ is\ already\ a\ long\ job[uuid\:%s]\ convert\ vm\ from\ %s = 已有长作业[uuid:{0}]从{1}转换VM # at: src/main/java/org/zstack/v2v/vmware/VMwareV2VFactory.java:145 # args: -Failed\ to\ update\ conversion\ host\ dependency = +Failed\ to\ update\ conversion\ host\ dependency = 无法更新转换物理机依赖关系 -# at: src/main/java/org/zstack/vmware/ESXHost.java:151 +# at: src/main/java/org/zstack/vmware/ESXHost.java:155 # args: -host\ is\ not\ connected = +host\ is\ not\ connected = 物理机未连接 + +# at: src/main/java/org/zstack/vmware/ESXHost.java:244 +# args: self.getvCenterUuid() +Syncing\ with\ VCenter[uuid\:%s],\ please\ try\ again\ later. = 正在与vCenter[uuid:{0}]同步,请稍后重试。 -# at: src/main/java/org/zstack/vmware/ESXHost.java:329 +# at: src/main/java/org/zstack/vmware/ESXHost.java:359 # args: vmUuid,self.getUuid() -vmUuid\ [%s]\ not\ found\ in\ ESX\ host\ [%s] = +vmUuid\ [%s]\ not\ found\ in\ ESX\ host\ [%s] = 在ESX物理机[{1}]中找不到VMuuid[{0}] -# at: src/main/java/org/zstack/vmware/ESXHost.java:673 +# at: src/main/java/org/zstack/vmware/ESXHost.java:709 # args: vmUuid -VM\ not\ found\:\ %s = +VM\ not\ found\:\ %s = 找不到VM:{0} -# at: src/main/java/org/zstack/vmware/ESXHost.java:602 +# at: src/main/java/org/zstack/vmware/ESXHost.java:635 # args: vmUuid,VMwareHelper.exStr(ex) -failed\ to\ suspend\ VM\ [%s]\:\ %s = +failed\ to\ suspend\ VM\ [%s]\:\ %s = 无法挂起云主机[{0}]:{1} -# at: src/main/java/org/zstack/vmware/ESXHost.java:598 +# at: src/main/java/org/zstack/vmware/ESXHost.java:631 # args: t.getTaskInfo().getError().getLocalizedMessage() -failed\ to\ suspend\ VM,\ task\ status\:\ %s = +failed\ to\ suspend\ VM,\ task\ status\:\ %s = 无法挂起云主机,任务状态:{0} -# at: src/main/java/org/zstack/vmware/ESXHost.java:636 +# at: src/main/java/org/zstack/vmware/ESXHost.java:670 # args: vmUuid,VMwareHelper.exStr(ex) -failed\ to\ resume\ VM\ [%s]\:\ %s = +failed\ to\ resume\ VM\ [%s]\:\ %s = 无法恢复VM[{0}]:{1} -# at: src/main/java/org/zstack/vmware/ESXHost.java:632 +# at: src/main/java/org/zstack/vmware/ESXHost.java:666 # args: t.getTaskInfo().getError().getLocalizedMessage() -failed\ to\ resume\ VM,\ task\ status\:\ %s = +failed\ to\ resume\ VM,\ task\ status\:\ %s = 无法恢复VM,任务状态:{0} -# at: src/main/java/org/zstack/vmware/ESXHost.java:704 +# at: src/main/java/org/zstack/vmware/ESXHost.java:740 # args: vmUuid,VMwareHelper.exStr(ex) -failed\ to\ shutdown\ guest\:\ %s,\ %s = +failed\ to\ shutdown\ guest\:\ %s,\ %s = 无法关闭来宾:{0},{1} -# at: src/main/java/org/zstack/vmware/ESXHost.java:1314 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1370 # args: vmInv.getInstanceOfferingUuid() -instance\ uuid\ [%s]\ not\ found = +instance\ uuid\ [%s]\ not\ found = 未找到实例uuid[{0}] -# at: src/main/java/org/zstack/vmware/ESXHost.java:1324 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1380 # args: vmInv.getImageUuid() -Image\ [%s]\ not\ found = +Image\ [%s]\ not\ found = 未找到镜像[{0}] -# at: src/main/java/org/zstack/vmware/ESXHost.java:1423 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1479 # args: vmUuid -VM\ [%s]\ not\ found\ in\ vCenter = +VM\ [%s]\ not\ found\ in\ vCenter = 在vCenter中找不到云主机[{0}] -# at: src/main/java/org/zstack/vmware/ESXHost.java:1592 +# at: src/main/java/org/zstack/vmware/ESXHost.java:1654 # args: t.getTaskInfo().getError().getLocalizedMessage() -failed\ to\ power\ on\ VM,\ task\ status\:\ %s = +failed\ to\ power\ on\ VM,\ task\ status\:\ %s = 无法启动云主机,任务状态:{0} + +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:122 +# args: msg.getDriverType() +Nic\ driver\ %s\ not\ support\ yet = NIC驱动程序{0}尚不支持 + +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:67 +# args: msg.getUuid(),vCenterVersion +console\ password\ is\ not\ supported\ by\ vm[uuid\:%s]\ on\ vCenter[version\:%s] = vCenter[版本:{1}]上的VM[uuid:{0}]不支持控制台密码 -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:47 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:73 # args: vCenter\ login\ name\ expected. = vCenter登录名称为空 -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:51 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:77 # args: msg.getDomainName() -domainName[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 域名[{0}]不是一个IPv4地址或有效的主机名 +domainName[%s]\ is\ neither\ an\ IPv4\ address\ nor\ a\ valid\ hostname = 域名[{0}]不是一个IPv4地址或有效的物理机名 -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:57 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:83 # args: msg.getDomainName() vCenter\ [domainName\:%s]\ has\ been\ added = vCenter[domainName:{0}]已经被添加 -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:94 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:139 # args: clusterUuid,l2uuid Cluster[uuid\:%s]\ and\ L2[uuid\:%s]\ belongs\ to\ different\ DCs = 集群[uuid:{0}]和二层网络[uuid:{1}]属于不同的DC -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:106 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:151 # args: clusterUuid No\ hosts\ found\ within\ cluster\:\ %s = 在集群{0}中未发现物理机 -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:139 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:184 # args: phyinf,phyinf vSwitch/dvSwitch\ not\ found\:\ %s,\ or\ vSwitch\:\ %s\ on\ different\ ESX\ host\ doesn't\ has\ same\ portgroup = vSwitch/dvSwitch未找到: {0}, 或者vSwitch: {1}在不同的ESX Host上的portgroup配置不同 -# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:153 +# at: src/main/java/org/zstack/vmware/VCenterApiInterceptor.java:198 # args: l2uuid,vcvo.getUuid(),clusterUuid L2[uuid\:%s]\ doesn't\ belong\ to\ vCenter[uuid\:%s]\ cluster[uuid\:%s] = 二层网络[uuid:{0}]不属于vCenter[uuid:{1}]集群[uuid:{2}] -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:60 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:68 # args: bsUuid -No\ data-store\ attached\ to\ %s = +No\ data-store\ attached\ to\ %s = 没有附加到{0}的主存储 -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:65 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:73 # args: bsUuid -Data-store\ not\ found\ for\ %s = +Data-store\ not\ found\ for\ %s = 找不到{0}的主存储 -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:93 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:103 # args: url.getProtocol() unexpected\ protocol\:\ %s = 不支持的协议类型:{0} -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:99 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:109 # args: iinv.getName() -%s\ already\ exists = +%s\ already\ exists = {0}已存在 -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:138 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:153 # args: -vcenter\ backup\ storage\ do\ not\ support\ to\ cancel\ download\ image = +vcenter\ backup\ storage\ do\ not\ support\ to\ cancel\ download\ image = vCenter备份存储不支持取消下载镜像 -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:188 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:203 # args: image\ not\ found\ in\ BS = 在镜像服务器上未找到目标镜像 -# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:200 +# at: src/main/java/org/zstack/vmware/VCenterBackupStorage.java:215 # args: -not\ supported\ yet = +not\ supported\ yet = 尚不支持 -# at: src/main/java/org/zstack/vmware/VCenterHostAllocatorFilterExtensionPoint.java:357 +# at: src/main/java/org/zstack/vmware/VCenterHostAllocatorFilterExtensionPoint.java:368 # args: no\ candidate\ host\ for\ vcenter\ vm = 找不到VCenter的物理机去启动vm -# src/main/java/org/zstack/vmware/VCenterManagerImpl.java:1031 -# args: nNic.getMac(),nVm.getUuid(),nVm.getName(),eVM.getUuid(),eVM.getName(),VCENTER_MAC_CONFLICT_STRATEGY_STRICT -Duplicated\ mac\ address[%s]\ on\ VM[uuid\:\ %s,\ name\:\ %s]\ and\ VM[uuid\:\ %s,\ name\:\ %s],\ and\ current\ mac\ address\ conflicting\ strategy\ is\:\ %s. = 云主机[uuid:{1},名称:{2}]和云主机 [uuid:{3},名称:{4}]中存在重复的mac地址[{0}],当前的 MAC 地址冲突策略是:{5}。 - -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:1804 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2040 # args: -can't\ sync\ before\ datastores\ are\ separated = +can't\ sync\ before\ datastores\ are\ separated = 在分离主存储之前无法同步 + +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3044 +# args: vcvo.getUuid() +There\ are\ tasks\ running\ on\ the\ VCenter[uuid\:%s],\ please\ try\ again\ later. = vCenter[uuid:{0}]上正在运行任务,请稍后重试。 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2858 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3134 # args: msg.getVCenterUuid() VCenter[uuid\:%s]\ not\ found\:\ = VCenter[uuid:{0}]不存在 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2974 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3252 # args: Login\ failed,\ please\ check\ your\ login\ parameters. = 登录失败,请检查用户名密码是否正确 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2978 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3256 # args: msg.getDomainName(),ex.getMessage() connect\ %s\ failed\:\ %s = 连接{0}失败:{1} -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2984 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3262 # args: msg.getDomainName(),msg.getUsername() Login\ to\ vCenter\ [%s]\ failed\ with\ user\ [%s],please\ check\ your\ network\ connection\ and\ credential. = 用户[{1}]登录vCenter[{0}]失败,请检查您的网络连接和凭据 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:2991 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3269 # args: msg.getDomainName(),msg.getPort() == null ? 443 : msg.getPort() Parse\ response\ failed\ from\ vCenter\ [%s],please\ check\ the\ port\ number[%d]. = 解析vCenter[{0}]响应失败,请检查端口号[{1}] -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3070 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3277 +# args: msg.getDomainName() +SSL\ handshake\ failed\ with\ vCenter\ [%s],because\ insecure\ TLS\ 1.0\ is\ used.\ Manually\ enabled\ TLS\ 1.0\ in\ jdk\ configuration\ if\ needed. = 与vCenter[{0}]的SSL握手失败,因为使用了不安全的TLS 1.0。如果需要,在JDK配置中手动启用TLS 1.0。 + +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3283 +# args: msg.getDomainName(),msg.getPort() == null ? 443 : msg.getPort() +SSL\ handshake\ failed\ with\ vCenter\ [%s],please\ check\ the\ port\ number[%d]. = 与vCenter[{0}]的SSL握手失败,请检查端口号[{1}]。 + +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3359 # args: No\ clustered\ compute\ resource\ found = 未找到集群资源 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3074 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3363 # args: No\ dvSwitch\ or\ qualified\ vSwitch\ found = 未找到可使用的dvSwitch/vSwitch -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3255 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3546 # args: dsMorVal,vcUuid Datastore\ %s\ not\ found\ for\ vCenter\ %s = vCenter{1}中未找到Datastore{0} -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3627 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3936 # args: -Missing\ host\ UUID\ in\ message = 消息中缺失物理机UUID +Missing\ host\ uuid\ in\ message = 消息中缺失物理机uuid -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3725 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4035 # args: -Missing\ destination\ host\ uuid. = 缺少目标物理机的Uuid +Missing\ destination\ host\ uuid. = 缺少目标物理机的uuid -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3730 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4040 # args: Destination\ host\ is\ not\ ESX\ host. = 目标物理机不是Esx类型物理机 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3768 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4079 # args: vm.getConfig().getName(),hvo.getManagementIp() -Checking\ compatibility\ with\ vm\ %s\ failed\ on\ host\ %s = 检查主机{1}与虚拟机{0}的兼容性失败 +Checking\ compatibility\ with\ vm\ %s\ failed\ on\ host\ %s = 检查物理机{1}与云主机{0}的兼容性失败 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3765 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4075 # args: HOST\ CPU/software\ NOT\ compatible = 物理机的CPU/software不兼容 -# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:3993 +# at: src/main/java/org/zstack/vmware/VCenterManagerImpl.java:4137 # args: Can't\ detach\ nic\ because\ the\ nic\ not\ supported\ to\ hot\ plugin\ in\ vcenter = 无法卸载网络,因为该网卡不支持热拔插 -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:204 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:228 # args: -No\ virtual\ disk\ manager = +No\ virtual\ disk\ manager = 无虚拟磁盘管理器 -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:211 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:235 # args: -No\ file\ manager = +No\ file\ manager = 没有文件管理器 -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:220 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:244 # args: -No\ file\ Datacenter = +No\ file\ Datacenter = 无文件数据中心 -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:324 +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:350 # args: vm.getName() failed\ to\ get\ VM[%s]\ root\ disk\ usage = 获取VM[{0}]根盘使用率失败 -# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:320 -# args: msg.getInstallPath() +# at: src/main/java/org/zstack/vmware/VCenterPrimaryStorageBase.java:346 +# args: installPath failed\ to\ get\ VM\ from\ installPath\:\ %s = 在路径{0}下未找到云主机 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:230 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:258 +# args: +VCenter\ not\ found = 找不到vCenter + +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:262 +# args: vcvo.getUuid(),vcvo.getStatus() +VCenter[%s]\ is\ not\ in\ operation\ status,\ current\ status\:\ %s = vCenter[{0}]未处于操作状态,当前状态:{1} + +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:328 # args: vCenterUrl,ex.getMessage() failed\ to\ connect\ to\ vCenter\:\ %s\:\ %s = 无法连接到vCenter:{0}:{1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:362 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:460 # args: installPath -vdisk\ not\ found\:\ %s = +vdisk\ not\ found\:\ %s = 未找到虚拟磁盘:{0} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:437 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:536 # args: getVcDomainName(si) -list\ storage\ failed\ for\ %s = +list\ storage\ failed\ for\ %s = {0}的列表存储失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:457 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:556 # args: vm.getName() -No\ datastore\ found\ for\ VM\:\ %s = +No\ datastore\ found\ for\ VM\:\ %s = 找不到云主机{0}的主存储区 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:511 -# args: info.getName(),info.getInstanceUuid() -failed\ to\ set\ ESX\ VM\ uuid\ [%s\:%s] = 设置ESX VM uuid [{0}:{1}]失败 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:610 +# args: info.getName(),info.getInstanceUuid(),ex.getMessage() +failed\ to\ set\ ESX\ VM\ uuid\ [%s\:%s],\ because[%s] = 无法设置ESX VM uuid[{0}:{1}],因为[{2}] -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:592 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:709 # args: zsImageUuid -template\ [%s]\ not\ found = +template\ [%s]\ not\ found = 未找到模板[{0}] -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:669 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:786 # args: host.getName() failed\ to\ search\ resource\ pool\ for\ host\ %s = 搜索物理机{0}资源池失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:665 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:782 # args: host.getName() No\ resource\ pool\ found\ for\ host\ %s = 在物理机{0}上未找到资源池 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2105 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2415 # args: installPath -No\ unit\ number\ available\ for\ data\ disk\ %s = +No\ unit\ number\ available\ for\ data\ disk\ %s = 没有可用于数据磁盘{0}的单元号 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1245 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1546 # args: vm.getName() guest\ tools\ not\ installed\ or\ running\ for\ VM\:\ %s = 云主机{0}上未安装或运行guest tools -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1280 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1581 # args: vm.getName() upload\ file\ failed\ for\ VM\:\ %s = 云主机{0}上传文件失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1368 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1670 # args: vcvo.getName() -list\ dvSwitch\ failed\ for\ %s = +list\ dvSwitch\ failed\ for\ %s = 为{0}列出dvSwitch失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1630 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1936 # args: clusterUuid -get\ vCenter\ cluster[%s]\ name\ failed = +get\ vCenter\ cluster[%s]\ name\ failed = 获取vCenter集群[{0}]名称失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1739 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2045 # args: dvSwitch -dvSwitch\ name\ [%s]\ not\ unique = +dvSwitch\ name\ [%s]\ not\ unique = dvSwitch名称[{0}]不唯一 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1797 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2103 # args: hvo.getName() create\ portgroup\ failed\ for\ host\ %s = 物理机{0}创建端口组失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1794 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2100 # args: hvo.getName(),((OperationFailureException) ex).getErrorCode().getDetails() create\ portgroup\ failed\ for\ host\ %s\:\ because\ %s = 物理机{0}创建端口组失败,因为{1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1761 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2067 # args: hvo.getName(),hvo.getUuid() Host[%s\:%s]\ not\ found\ on\ vCenter = vCenter上未找到物理机[{0}:{1}] -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1773 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2079 # args: pgLabel,hvo.getName(),vlanId -portgroup[%s]\ already\ exists\ on\ host[%s]\ but\ with\ different\ vlanId(%d) = +portgroup[%s]\ already\ exists\ on\ host[%s]\ but\ with\ different\ vlanId(%d) = 端口组[{0}]已存在于物理机[{1}]上,但具有不同的VlanID({2}) -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1833 -# args: hvo.getName() +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2083 +# args: pgLabel,hvo.getName() portgroup[%s]\ already\ exists\ on\ host[%s],please\ create\ again\ with\ other\ name\ or\ delete\ portgroup\ manually\ and\ attach\ to\ cluster\ again = 端口组[{0}]已经存在于物理机[{1}],请重新使用另外的名字创建或者手动删除端口组然后重新加载到集群 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1836 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2142 # args: vcvo.getName() -create\ dvPortGroup\ failed\ for\ %s = +create\ dvPortGroup\ failed\ for\ %s = 为{0}创建DVPortGroup失败 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:1831 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2137 # args: dvSwitchName,vcvo.getName() -dvSwitch\ [%s]\ not\ found\ on\ vCenter\ [%s] = +dvSwitch\ [%s]\ not\ found\ on\ vCenter\ [%s] = 在vCenter[{1}]上找不到dvSwitch[{0}] -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2026 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2335 # args: ds.getName() -no\ dataCenter\ found\ for\ datastore = +no\ dataCenter\ found\ for\ datastore = 找不到主存储的区域 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2031 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2340 # args: -virtual\ disk\ manager\ unavailable = +virtual\ disk\ manager\ unavailable = 虚拟磁盘管理器不可用 -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2042 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2351 # args: installPath,mf.getLocalizedMessage() -delete\ vdisk[%s]\ failed\:\ %s = +delete\ vdisk[%s]\ failed\:\ %s = 删除虚拟磁盘[{0}]失败:{1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2171 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2481 # args: dvSwitch.getName(),task.getTaskInfo().getError().getLocalizedMessage() -create\ dvPortGroup\ failed\ for\ dvSwitch\ [%s],\ %s = +create\ dvPortGroup\ failed\ for\ dvSwitch\ [%s],\ %s = 为dvSwitch[{0}]创建dvPortGroup失败,{1} -# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2275 +# at: src/main/java/org/zstack/vmware/VMwareHelper.java:2593 # args: me.getName(),mor.val,ex.getMessage() failed\ to\ set\ ZStack\ uuid\ to\ VCenter\ ManagedEntity\ [name\:%s,\ mor\:%s]\ because\ %s = 在VCenter ManagedEntity [name:{0},mor:{1}]上设置ZStack uuid失败,因为{2} -# at: src/main/java/org/zstack/vmware/VncPortAllocatorImpl.java:162 +# at: src/main/java/org/zstack/vmware/VncPortAllocatorImpl.java:165 # args: No\ VNC\ ports\ available = 未找到可用的VNC端口 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:225 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:450 +# args: msg.getDns() +dns[%s]\ is\ not\ a\ IP\ address = dns地址[{0}]不是有效的IP地址 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:338 # args: l3NetworkVO.getUuid() no\ ip\ ranges\ attached\ with\ l3\ network[uuid\:%s] = 在三层网络[uuid:{0}]上没有IP范围被绑定 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:167 -# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vipPeerVOs.stream().map( n -> n.getVipUuid()).collect(Collectors.toList()) -l3\ network[uuid\:%s]\ can\ not\ detach\ from\ vpc\ vrouter[uuid\:%s]\ since\ network\ services\ attached\ vips[%s]\ still\ used\ in\ l3 = +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:178 +# args: +management\ network\ can\ not\ be\ detached = 管理网络无法分离 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:182 +# args: +default\ route\ network\ can\ not\ be\ detached = 无法分离默认路由网络 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:186 +# args: +original\ public\ network\ can\ not\ be\ detached = 原有公网不能脱离 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:190 +# args: vpc.getUuid() +could\ not\ detach\ l3\ network\ to\ vpc\ router[uuid\:%s]\ because\ its\ state\ is\ not\ running\ or\ stopped = 无法将三层网络与VPC路由器[uuid:{0}]分离,因为其状态未运行或已停止 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:198 +# args: vpc.getUuid() +could\ not\ detach\ l3\ network\ to\ vpc\ router[uuid\:%s]\ becaus\ the\ states\ of\ the\ master\ and\ slave\ are\ inconsistent = 无法将三层网络与VPC路由器[uuid:{0}]分离,因为主设备和从设备的状态不一致 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:231 +# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vipPeerVOs.stream().map(VipPeerL3NetworkRefVO::getVipUuid).collect(Collectors.toList()) +l3\ network[uuid\:%s]\ can\ not\ detach\ from\ vpc\ vrouter[uuid\:%s]\ since\ network\ services\ attached\ vips[%s]\ still\ used\ in\ l3 = 三层网络[uuid:{0}]无法与VPC虚拟路由器[uuid:{1}]分离,因为网络服务附加的VIP[{2}]仍在L3中使用 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:183 -# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vmNicVOS.stream().map( n -> n.getUuid()).collect(Collectors.toList()) -vpc\ l3\ network[uuid\:%s]\ can\ not\ detach\ from\ vpc\ vrouter[uuid\:%s]\ since\ vm\ nics[%s]\ still\ used\ in\ l3 = vpc三层网络[uuid:{0}]无法从vpc路由器[uuid:{1}]卸载, l3网络还在使用以下云主机网卡[{2}] +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:247 +# args: l3NetworkVO.getUuid(),vmInstanceVO.getUuid(),vmNicVOS.stream().map(ResourceVO::getUuid).collect(Collectors.toList()) +vpc\ l3\ network[uuid\:%s]\ can\ not\ detach\ from\ vpc\ vrouter[uuid\:%s]\ since\ vm\ nics[%s]\ still\ used\ in\ l3 = vpc三层网络[uuid:{0}]无法从vpc路由器[uuid:{1}]卸载, 三层网络还在使用以下云主机网卡[{2}] -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:193 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:257 # args: msg.getVirtualRouterOfferingUuid() virtual\ router\ offering[uuid\:\ %s]\ is\ not\ enabled = 云路由规格[uuid: {0}]是不可用的 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:218 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:284 # args: only\ vpc\ l3\ network\ can\ attach\ to\ vpc\ vrouter = 只有VPC三层网络可以绑定到VPC云路由 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:249 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:292 +# args: msg.getL3NetworkUuid(),vmNics.get(0).getVmInstanceUuid() +Vpc\ network\ [uuid\:%s]\ already\ attached\ to\ vpc\ router\ [uuid\:%s] = VPC网络[uuid:{0}]已连接到VPC路由器[uuid:{1}] + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:329 +# args: msg.getVmInstanceUuid() +could\ not\ attached\ l3\ network\ to\ vpc\ router[uuid\:%s]\ because\ both\ its\ state\ and\ it\ peer\ state\ is\ not\ running\ or\ stopped = 无法将三层网络连接到VPC路由器[uuid:{0}],因为其状态和对等状态均未运行或已停止 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:312 +# args: msg.getVmInstanceUuid() +could\ not\ attached\ l3\ network\ to\ vpc\ router[uuid\:%s]\ because\ its\ state\ is\ not\ running\ or\ stopped = 无法将三层网络连接到VPC路由器[uuid:{0}],因为其状态未运行或已停止 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:362 # args: vip.getL3NetworkUuid(),vip.getUuid(),vip.getIp(),msg.getL3NetworkUuid(),vmInstanceVO.getUuid() public\ network[uuid\:\ %s]\ vip[uuid\:\ %s,\ ip\:\ %s]\ peer\ with\ l3network[uuid\:\ %s]\ not\ on\ vpc\ vr[uuid\:\ %s] = 在VPC云路由[uuid: {4}]上,三层网络[uuid: {3}]没有和公有网络[uuid: {0}]虚拟IP[uuid: {1}, ip: {2}]同阶 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:261 -# args: gateway,msg.getL3NetworkUuid() +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:383 +# args: gateways,msg.getL3NetworkUuid() the\ gateway[ip\:%s]\ of\ l3[uuid\:%s]\ has\ been\ occupied = 三层网络[uuid:{1}]的网关[uuid:{0}]已经被占用 -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:272 -# args: msg.getStaticIp(),gateway,l3NetworkVO.getUuid() -the\ static\ ip[%s]\ specified\ in\ message\ not\ equals\ to\ gateway\ ip[%s]\ of\ l3\ network[uuid\:%s] = 在消息中指定的静态IP地址[{0}]和三层网络[uuid:{2}]的网关IP地址[{1}]不一样 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:428 +# args: msg.getStaticIp(),gateways,l3NetworkVO.getUuid() +the\ static\ ip[%s]\ specified\ in\ message\ not\ equals\ to\ gateway\ ips[%s]\ of\ l3\ network[uuid\:%s] = 消息中指定的静态IP[{0}]不等于三层网络[uuid:{2}]的网关IP[{1}] -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:284 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:440 # args: vipL3Uuid -l3\ network\ [uuid\:%s]\ must\ be\ attached\ first,\ because\ there\ is\ vip\ on\ that\ l3\ network = - -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:335 -# args: msg.getDns() -dns[%s]\ is\ not\ a\ IP\ address = dns地址[{0}]不是有效的IP地址 +l3\ network\ [uuid\:%s]\ must\ be\ attached\ first,\ because\ there\ is\ vip\ on\ that\ l3\ network = 必须首先连接三层网络[uuid:{0}],因为该三层网络上存在VIP -# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:296 +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:457 # args: msg.getDns(),msg.getUuid() dns\ address\ [%s]\ is\ not\ added\ to\ vpc\ router\ [uuid\:%s] = dns地址[{0}]未添加到vpc路由[uuid:{1}] -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1056 -# args: -chrony\ server\ not\ configured! = +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:488 +# args: ipr.getL3NetworkUuid(),ipRangeVO.getNetworkCidr(),uuid +could\ not\ add\ ipv6\ range\ to\ l3\ network[uuid\:%s],\ because\ it's\ overlap\ with\ cidr\ [%s]\ of\ vRouter\ [uuid\:%s] = 无法将IPv6范围添加到三层网络[uuid:{0}],因为它与VRouter[uuid:{2}]的CIDR[{1}]重叠 + +# at: src/main/java/org/zstack/vpc/VpcApiInterceptor.java:483 +# args: ipr.getL3NetworkUuid(),ipRangeVO.getNetworkCidr(),uuid +could\ not\ add\ ip\ range\ to\ l3\ network[uuid\:%s],\ because\ it's\ overlap\ with\ cidr\ [%s]\ of\ vRouter\ [uuid\:%s] = 无法将IP范围添加到三层网络[uuid:{0}],因为它与VRouter[uuid:{2}]的CIDR[{1}]重叠 + +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:859 +# args: rsp.getError() +operation\ error,\ because\:%s = 操作错误,因为{0} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:314 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:558 # args: msg.getUuid() can\ not\ get\ connections\ of\ distributed\ routing\ to\ virtual\ router\ %s = 不能获取分布式路由到云路由的连接 -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:351 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:596 # args: vrinv.getUuid() can\ not\ set\ state\ of\ distributed\ routing\ to\ virtual\ router\ %s = 不能设置分布式路由到云路由的状态 -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:595 -# args: vrinv.getUuid() -can\ not\ get\ state\ of\ distributed\ routing\ to\ virtual\ router\ %s = 获取路由器 {0} 分布式路由的状态失败 - -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:469 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:720 # args: msg.getNetworkService(),msg.getUuid() not\ support\ to\ get\ the\ service\ %s\ state\ to\ virtual\ router\ %s = 路由器 {1} 不支持网络功能{0} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:613 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:855 +# args: vrinv.getUuid() +can\ not\ get\ state\ of\ distributed\ routing\ to\ virtual\ router\ %s = 获取路由器 {0} 分布式路由的状态失败 + +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:934 # args: msg.getNetworkService(),msg.getUuid() not\ support\ to\ update\ the\ service\ %s\ state\ to\ virtual\ router\ %s = 路由器 {1} 不支持更新网络功能{0} -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1004 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1336 # args: -vpc\ l3\ network\ must\ attach\ a\ vpc\ vrouter\ first\ before\ do\ anything\ related\ to\ vrouter(like\ start/stop\ vm,\ create\ lb,\ etc.) = 在做设置云路由的任何操作(如启动/停止虚拟机、创建负载均衡等),VPC三层网络必须首先绑定三层路由 +vpc\ l3\ network\ must\ attach\ a\ vpc\ vrouter\ first\ before\ do\ anything\ related\ to\ vrouter(like\ start/stop\ vm,\ create\ lb,\ etc.) = 在做设置云路由的任何操作(如启动/停止云主机、创建负载均衡等),VPC三层网络必须首先绑定三层路由 -# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1281 +# at: src/main/java/org/zstack/vpc/VpcManagerImpl.java:1594 # args: msg.getDns(),msg.getVpcRouterUuid() dns\ address\ [%s]\ has\ bean\ added\ to\ vpc\ router\ [uuid\:%s] = 在路由器[uuid:{1}]上已经存在一个DNS[{0}] -# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:161 -# args: vpc.getUuid() +# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:166 +# args: vpcUuid can\ not\ detach\ nic\ from\ vpc\ vr[uuid\:%s] = 不能从VPC云路由[uuid:{0}]解绑网卡 -# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:289 -# args: ipRange.getUuid() -can\ not\ detach\ nic\ from\ vpc\ during\ delete\ ip\ range[uuid\:%s] = +# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:473 +# args: l3.getUuid() +there\ is\ no\ ip\ range\ for\ l3\ network[uuid\:%s] = 三层网络[uuid:{0}]没有IP范围 -# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:342 -# args: gateway,l3.getUuid(),vm.getUuid() +# at: src/main/java/org/zstack/vpc/VpcVRouterFactory.java:501 +# args: ip.getGateway(),l3.getUuid(),vm.getUuid() the\ gateway[ip\:%s]\ of\ l3[uuid\:%s]\ has\ been\ occupied\ on\ vpc\ vr[uuid\:\ %s] = 在VPC的云路由[uuid: {2}]上,三层网络[uuid:{1}]的网关[uuid:{0}]已经被占用 -# at: src/main/java/org/zstack/vpc/VpcVyosDeployZsnAgentFlow.java:130 +# at: src/main/java/org/zstack/vpc/VpcVyosDeployZsnAgentFlow.java:133 # args: mgmtNicIp -unable\ to\ ssh\ in\ to\ the\ vyos[%s],\ the\ ssh\ port\ seems\ not\ open = 未能通过ssh进入vyos[{0}],ssh端口看起来没有打开 +unable\ to\ ssh\ in\ to\ the\ vpc\ router[%s],\ the\ ssh\ port\ seems\ not\ open = 无法通过SSH连接到VPC路由器[{0}],SSH端口似乎未打开 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:164 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:217 # args: msg.getVmInstanceUuid() there\ is\ no\ master\ router\ of\ router\ [uuid\:%s] = 路由器[uuid:{0}]的高可用组没有主路由器 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:115 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:130 +# args: msg.getVirtualRouterUuid() +Could\ not\ update\ this\ network\ service,\ due\ to\ vpc\ [uuid\:%s]\ is\ not\ support\ update\ network\ service\ version = 无法更新此网络服务,因为VPC[uuid:{0}]不支持更新网络服务版本 + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:137 +# args: msg.getVirtualRouterUuid(),vo.getKernelVersion() +Could\ not\ update\ this\ network\ service,\ due\ to\ vpc\ [uuid\:%s]\ used\ old\ kernel\ version\:[%s] = 无法更新此网络服务,因为VPC[uuid:{0}]使用了旧内核版本:[{1}] + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:144 +# args: +Could\ not\ apply\ snat\ with\ non-default\ public\ network,\ due\ to\ multi\ snat\ feature\ is\ disabled = 无法使用非默认公用网络应用SNAT,因为多SNAT功能已禁用 + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:147 +# args: msg.getL3NetworkUuid() +Could\ not\ apply\ snat\ with\ this\ L3Network,\ due\ to\ l3\ network\ [uuid\:%s]\ is\ not\ public\ network = 无法对此三层网络应用SNAT,因为三层网络[uuid:{0}]不是公共网络 + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:150 +# args: msg.getL3NetworkUuid() +Could\ not\ apply\ snat\ with\ this\ L3Network,\ due\ to\ l3\ network\ [uuid\:%s]\ is\ not\ attached\ to\ vpc\ router = 无法对此三层网络应用SNAT,因为三层网络[uuid:{0}]未连接到VPC路由器 + +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:168 # args: ip invalid\ monitor\ ip\ address\ [%s] = 仲裁地址[{0}]错误 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:152 -# args: vpcHaUuid +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:205 +# args: vpcVo.getUuid() vpcHaRouter\ [uuid\:%s]\ is\ deleted = 高可用组[uuid:{0}]被删除了 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:182 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:235 # args: haUuid there\ are\ more\ than\ 2\ vpc\ routers\ attached\ to\ haGroup\ [uuid\:%s] = 高可用组[uuid:{0}]的路由器数量已经超过2 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:211 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:266 # args: l3Uuids,offeringL3Uuids ha\ group\ management\ l3\ and\ public\ l3\ networks[uuid\:%s]\ are\ different\ from\ offering\ l3\ networks\ [uuid\:%s] = 高可用组的管理网,公网组合[uuid:{0}]和云路由规格的三层网络[uuid:{1}]不同 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:267 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:322 # args: vpcL3Uuids,vpcHaGroupL3Uuids vpc\ router\ l3\ networks\ [uuid\:%s]\ are\ different\ from\ ha\ group\ l3\ networks\ [uuid\:%s],\ !!!\ please\ delete\ this\ router\ and\ recreate\ it = vpc路由器的三层网路[uuid:{0}]和高可用组的三层网络[uuid:{1}]不同 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:275 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:330 # args: oldHaUuid vpc\ router\ has\ been\ attached\ to\ ha\ group\ [uuid\:%s] = vpc路由器不在高可用组[uuid:{0}]中 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:279 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:334 # args: haUuid vpc\ ha\ group\ [uuid\:%s]\ is\ not\ existed = 高可用组[uuid:{0}]不存在 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:283 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:339 # args: haUuid there\ are\ more\ than\ 1\ vpc\ routers\ attached\ to\ haGroup\ [uuid\:%s] = 高可用组[uuid:{0}]的路由器数量已经超过1 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:288 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupApiInterceptor.java:344 # args: haUuid vpc\ router\ [uuid\:%s]\ can\ not\ be\ upgraded\ to\ ha\ router\ because\ it\ public\ network\ is\ same\ to\ management\ network = vpc路由器[uuid:{0}]不能升级高可用路由器因为它的管理网和公网相同 -# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java:571 +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java:611 # args: ha.getName() create\ affinityGroup\ for\ ha\ group\ [uuid\:%s]\ failed = 高可用组[uuid:{0}]创建亲和组失败 -# at: src/main/java/org/zstack/vpc/ha/vyos/vyosVpcHaRouterBackendManagerImpl.java:137 -# args: vrUuid,ret.getError() -failed\ to\ enable\ ha\ on\ virtual\ router[uuid\:%s],\ %s = 路由器[uuid:{0}]打开高可用功能失败,{1} +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupManagerImpl.java:785 +# args: vrName,vrUuid,vpcHaGroupName,vpcHaGroupUuid,old,status +virtualrouter\ %s\ [uuid\:\ %s\ ]\ of\ VPC\ HA\ group\ %s\ [uuid\:\ %s]\ haStatus\ changed\ from\ %s\ to\ %s = VPC高可用性组{2}[uuid:{3}]的VirtualRouter{0}[uuid:{1}]的高可用性状态已从{4}更改为{5} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:291 -# args: ips -operation\ failure,\ ip\ format\ only\ supports\ ipv4/iprange/cidr,\ but\ find\ %s = +# at: src/main/java/org/zstack/vpc/ha/VpcHaGroupVpcVrImpl.java:694 +# args: +ha\ group\ uuid\ nil = 高可用性组uuid无 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:317 -# args: protocol -illegal\ protocol\ type\ %s = +# at: src/main/java/org/zstack/vpc/ha/vpcHaGc/VpcHaGcManagerImpl.java:85 +# args: struct.getVmInstanceUuid() +VR[uuid\:\ %s]\ not\ running = VR[uuid:{0}]未运行 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:342 -# args: msg.getRuleSetUuid(),msg.getRuleNumber() -RuleSet[%s]\ already\ has\ a\ rule\ with\ rule\ number\ %s. = +# at: src/main/java/org/zstack/vpc/ha/vpcHaGc/VpcHaGcManagerImpl.java:90 +# args: struct.getVmInstanceUuid() +VR[uuid\:\ %s]\ not\ connected = VR[uuid:{0}]未连接 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:372 -# args: -only\ tcp\ or\ udp\ protocol\ can\ use\ port = +# at: src/main/java/org/zstack/vpc/ha/vyos/vyosVpcHaRouterBackendManagerImpl.java:140 +# args: vrUuid,ret.getError() +failed\ to\ enable\ ha\ on\ virtual\ router[uuid\:%s],\ %s = 路由器[uuid:{0}]打开高可用功能失败,{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:88 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:373 # args: -can\ not\ detach\ system\ default\ ruleSet = +only\ tcp\ or\ udp\ protocol\ can\ use\ port = 只有TCP或UDP协议可以使用端口 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:110 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:150 # args: msg.getUuid() -can\ not\ delete\ ruleSet[%s]\ because\ it\ still\ attached\ to\ nic = +can\ not\ delete\ ruleSet[%s]\ because\ it\ still\ attached\ to\ nic = 无法删除规则集[{0}],因为它仍连接到NIC -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:114 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:129 # args: -can\ not\ delete\ system\ default\ ruleSet = +can\ not\ detach\ system\ default\ ruleSet = 无法分离系统默认规则集 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:125 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:142 # args: -can\ not\ delete\ system\ default\ rule = +only\ system\ ruleSet\ can\ change\ action\ type = 只有系统规则集才能更改操作类型 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:150 -# args: msg.getVpcUuid() -VPC\ Router[uuid\:%s]\ already\ has\ a\ firewall. = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:154 +# args: +can\ not\ delete\ system\ default\ ruleSet = 无法删除系统默认规则集 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:157 -# args: msg.getUuid() -can\ not\ update\ default\ rule[%s] = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:160 +# args: +can\ not\ delete\ system\ default\ rule = 无法删除系统默认规则 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:170 +# args: vRouteUuid +the\ router\ [uuid\:%s]\ does\ not\ has\ a\ master\ router = 路由器[uuid:{0}]没有主路由器 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:377 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:188 +# args: msg.getVpcUuid() +the\ VPC\ Router[uuid\:%s]\ already\ has\ a\ firewall. = VPC路由器[uuid:{0}]已有防火墙。 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:378 # args: -only\ tcp\ protocol\ can\ use\ tcp\ flag = +only\ tcp\ protocol\ can\ use\ tcp\ flag = 只有TCP协议才能使用TCP标志 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:381 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:382 # args: -only\ icmp\ protocol\ can\ use\ icmp\ type = +only\ icmp\ protocol\ can\ use\ icmp\ type = 只有ICMP协议才能使用ICMP类型 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:239 +# args: msg.getName(),msg.getRuleNumber() +already\ has\ a\ rule\ template\ with\ name\ %s = 已有名为{0}的规则模板 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:221 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:338 +# args: msg.getRuleSetUuid(),msg.getRuleNumber() +the\ ruleSet[%s]\ already\ has\ a\ rule\ with\ rule\ number\ %s. = 规则集[{0}]已具有规则编号为{1}的规则。 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:343 # args: msg.getUuid() -Rule\ [%s]\ not\ support\ update\ state = +can\ not\ update\ default\ rule[%s] = 无法更新默认规则[{0}] -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:227 -# args: -Default\ ruleSet\ can\ not\ be\ attached\ to\ other\ nic = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:407 +# args: msg.getUuid() +the\ rule\ [%s]\ number\ is\ invalid = 规则[{0}]编号无效 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:231 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:416 # args: -Only\ out\ direction\ support\ attach\ ruleSet = +can\ not\ attach\ the\ default\ ruleSet\ to\ other\ nic = 无法将默认规则集附加到其他NIC -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:239 -# args: msg.getL3Uuid(),msg.getForward() -L3[%s]\ forward[%s]\ already\ attached\ a\ ruleSet = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:431 +# args: msg.getRuleSetUuid(),msg.getL3Uuid() +ruleSet[%s]\ already\ has\ a\ l3[%s] = 规则集[{0}]已具有L3[{1}] -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:302 -# args: e.getMessage() -Invalid\ rule\ expression,\ the\ detail\:\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:450 +# args: duplicateRuleNumbers +already\ has\ a\ rule\ with\ the\ number[%s] = 已具有编号为[{0}]的规则 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:284 -# args: ips -operation\ failure,\ duplicate/overlap\ ip\ entry\ in\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:748 +# args: msg.getRuleSetUuid(),msg.getRuleNumber() +the\ ruleSet[%s]\ already\ has\ a\ rule\ with\ the\ rule\ number\ %s. = 规则集[{0}]已具有规则编号为{1}的规则。 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:295 -# args: startIp,endIp,NetworkUtils.longToIpv4String(r.lowerEndpoint()),NetworkUtils.longToIpv4String(r.upperEndpoint()) -operation\ failure,\ there\ are\ overlap\ ip\ range[start\ ip\:%s,\ end\ ip\:\ %s\ and\ start\ ip\:%s,\ end\ ip\:\ %s] = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:779 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ only\ tcp\ or\ udp\ protocol\ can\ use\ port = 无法添加防火墙规则[{0}]只有TCP或UDP协议可以使用端口 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:309 -# args: port -operation\ failure,\ port\ format\ only\ supports\ port/portRange,\ but\ find\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:785 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ only\ tcp\ protocol\ can\ use\ tcp\ flag = 无法添加防火墙规则[{0}]只有TCP协议可以使用TCP标志 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:331 -# args: state -protocol\ state\ only\ support\ new/established/invalid/related,but\ found\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:790 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ because\ only\ icmp\ protocol\ can\ use\ icmp\ type = 无法添加防火墙规则[{0}],因为只有ICMP协议可以使用ICMP类型 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:801 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ because\ only\ tcp\ or\ udp\ protocol\ can\ use\ port = 无法添加防火墙规则[{0}],因为只有TCP或UDP协议可以使用端口 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:824 +# args: msg.getRuleNumber() +could\ not\ add\ firewall\ rule[%d]\ because\ only\ tcp\ protocol\ can\ use\ tcp\ flag = 无法添加防火墙规则[{0}],因为只有TCP协议可以使用TCP标志 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:832 +# args: msg.getRuleNumber(),error +could\ not\ add\ firewall\ rule[%d]\ because\ %s = 无法添加防火墙规则[{0}],因为{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:290 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:846 +# args: vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ ruleNo\ %d\ is\ invalid = 无法添加防火墙规则,因为RuleNo{0}无效 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:853 +# args: vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ there\ is\ no\ action\ for\ ruleNo\:%d = 无法添加防火墙规则,因为没有针对RuleNo的操作:{0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:867 +# args: vo.getSourceIp(),vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ source\ IP\ length\:\ %s\ is\ not\ valid\ for\ ruleNo\:%d = 无法添加防火墙规则,因为源IP长度{0}对RuleNo{1}无效 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:874 +# args: vo.getDestIp(),vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ destination\ IP\ length\:\ %s\ is\ not\ valid\ for\ ruleNo\:%d = 无法添加防火墙规则,因为目标IP长度{0}对RuleNo{1}无效 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:885 +# args: vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ there\ is\ no\ state\ for\ ruleNo\:%d = 无法添加防火墙规则,因为RuleNo没有状态:{0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:892 +# args: vo.getDestIp(),vo.getRuleNumber() +could\ not\ add\ firewall\ rule,\ because\ description\ length\ %s\ is\ not\ valid\ for\ ruleNo\:%d = 无法添加防火墙规则,因为描述长度{0}对RuleNo无效:{1} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:942 +# args: +the\ configuration\ file\ has\ format\ error = 配置文件有格式错误 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallApiInterceptor.java:948 +# args: errorInfo +the\ firewall\ rules\ in\ the\ configuration\ file\ have\ syntax\ errors\:\ %s = 配置文件中的防火墙规则有语法错误:{0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:272 # args: rsp.getError() -sync\ firewall\ config\ failed,because\ %s = +sync\ firewall\ config\ failed,because\ %s = 同步防火墙配置失败,因为{0} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:441 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:459 # args: rsp.getError() -update\ firewall\ ruleSet\ action\ failed,\ because\ %s = +update\ firewall\ ruleSet\ action\ failed,\ because\ %s = 更新防火墙规则集操作失败,因为{0} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:492 +# args: l3Uuid,vRouterUuid +Can\ not\ find\ l3[%]\ related\ mac\ on\ vRouter[%s] = 在VRouter[{0}]上找不到与L3[%]相关的MAC -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:516 -# args: cmd.getRule().getRuleNumber(),rsp.getError() -create\ firewall\ rule[%s]\ failed,\ because\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:557 +# args: cmd.getRef().getRuleSetInfo().getRules().get(0).getRuleNumber(),rsp.getError() +create\ firewall\ rule[%s]\ failed,\ because\ %s = 创建防火墙规则[{0}]失败,原因是{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:591 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:645 # args: vRouterUuid,re.getError().getCause() -delete\ firewall\ on\ vRouter[%s],because\ %s = +delete\ firewall\ on\ vRouter[%s],because\ %s = 删除VRouter[{0}]上的防火墙,因为{1} + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:851 +# args: vRouterUuid,rsp.getError() +delete\ firewall\ rule\ failed\ on\ vRouter[%s],\ because\ %s = 在VRouter[{0}]上删除防火墙规则失败,因为{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:664 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:784 # args: cmd.getRuleSet().getName(),re.getError().getCause() -create\ firewall\ ruleSet[%s]\ failed,\ because\ %s = +create\ firewall\ ruleSet[%s]\ failed,\ because\ %s = 创建防火墙规则集[{0}]失败,原因是{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:744 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:936 # args: vRouterUuid,rsp.getError() -delete\ firewall\ rule\ failed\ on\ vRouter[%s],\ because\ %s = +change\ firewall\ rule\ state\ on\ vRouter[%s]\ failed,\ because\ %s = 更改VRouter[{0}]上的防火墙规则状态失败,原因是{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:822 -# args: vRouterUuid,rsp.getError() -change\ firewall\ rule\ state\ on\ vRouter[%s]\ failed,\ because\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1032 +# args: struct.getRuleSetUuid(),re.getError() +attach\ firewall\ ruleSet[%s]\ failed,\ because\ %s = 附加防火墙规则集[{0}]失败,原因是{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:996 -# args: struct.getL3Uuid(),vRouterUuid -Can\ not\ find\ l3[%]\ related\ mac\ on\ vRouter[%s] = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1063 +# args: +detach\ ruleSet\ failed,\ maybe\ it\ has\ been\ deleted = 分离规则集失败,它可能已被删除 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:921 -# args: cmd.getRef().getRuleSetName(),re.getError() -attach\ firewall\ ruleSet[%s]\ failed,\ because\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1129 +# args: struct.getRuleSetUuid(),re.getError().getCause() +detach\ firewall\ ruleSet[%s]\ failed,because\ %s = 分离防火墙规则集[{0}]失败,原因是{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:956 -# args: -detach\ ruleSet\ failed,\ maybe\ it\ has\ been\ deleted = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:114 +# args: msg.getVpcFirewallUuid() +cannot\ find\ vpcFirewall[uuid\:%s]\ related\ vRouter = 找不到与vpcFirewall[uuid:{0}]相关的虚拟路由器 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1024 -# args: cmd.getRef().getRuleSetName(),re.getError().getCause() -detach\ firewall\ ruleSet[%s]\ failed,because\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:109 +# args: msg.getVpcFirewallUuid() +cannot\ find\ vpcFirewall[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到vpcFirewall[uuid:{0}],它可能已被删除 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:125 +# args: msg.getRuleSetUuid() +cannot\ find\ vpcFirewallRuleSet[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到VpcFirewallRuleSet[uuid:{0}],它可能已被删除 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBackend.java:1102 -# args: cmd.getRuleSetName(),re.getError().getCause() -delete\ firewall\ ruleSet[%s]\ failed,because\ %s = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:301 +# args: msg.getUuid() +cannot\ find\ vpcFirewallIpSetTemplate[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到VpcFireWallipSetTemplate[uuid:{0}],它可能已被删除 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBase.java:129 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:396 # args: msg.getRuleSetUuid(),msg.getL3Uuid(),errorCode.getCause() -attach\ firewall\ ruleSet[%s]\ to\ l3[%s]\ failed,because\ %s = +attach\ firewall\ ruleSet[%s]\ to\ l3[%s]\ failed,because\ %s = 将防火墙规则集[{0}]附加到L3[{1}]失败,原因是{2} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallBase.java:156 +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:424 # args: msg.getL3Uuid(),errorCode.getCause() -detach\ firewall\ ruleSet\ from\ l3[%s]\ failed,because\ %s = +detach\ firewall\ ruleSet\ from\ l3[%s]\ failed,because\ %s = 从L3[{0}]分离防火墙规则集失败,原因是{1} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:83 -# args: msg.getVpcFirewallUuid() -cannot\ find\ vpcFirewall[uuid\:%s],\ it\ may\ have\ been\ deleted = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:475 +# args: duplicateRuleNumber.get(),ref.getVpcFirewallUuid(),ref.getL3NetworkUuid(),ref.getPacketsForwardType() +find\ duplicate\ rule\ numbers\ %s\ on\ firewall[%s],l3[%s],forward[%s] = 在防火墙[{1}]、L3[{2}]、转发[{3}]上查找重复的规则编号{0} -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:104 -# args: vo.getVpcFirewallUuid() -cannot\ find\ vpcFirewall[uuid\:%s]\ related\ vRouter = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:483 +# args: self.getUuid() +no\ changes\ in\ ruleset\ %s = 规则集{0}中没有更改 + +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:515 +# args: firewall.get() +firewall\ %s\ related\ vpc\ not\ in\ running\ state = 防火墙{0}相关的VPC未处于运行状态 -# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallManagerImpl.java:99 -# args: msg.getVpcFirewallRuleUuid() -cannot\ find\ vpcFirewallRule[uuid\:%s],\ it\ may\ have\ been\ deleted = +# at: src/main/java/org/zstack/vpcfirewall/VpcFirewallRuleSetBase.java:753 +# args: self.getUuid(),refVOs.size() +default\ ruleset\ %s\ can\ only\ attached\ to\ one\ interface\ forward,\ but\ find\ %s\ related\ interface = 默认规则集{0}只能转发到一个接口,但找到{1}个相关接口 -# at: src/main/java/org/zstack/vrouterRoute/VRouterRouteManagerImpl.java:466 +# at: src/main/java/org/zstack/vrouterRoute/VRouterRouteApiInterceptor.java:115 +# args: msg.getDestination() +destination[%s]\ can\ not\ has\ blackHole\ route\ and\ static\ route\ at\ same\ time = 目标[{0}]不能同时具有黑洞路由和静态路由 + +# at: src/main/java/org/zstack/vrouterRoute/VRouterRouteManagerImpl.java:469 # args: msg.getUuid() cannot\ find\ the\ route\ table\ [uuid\:%s] = 找不到路由表[uuid:{0}] +# at: src/main/java/org/zstack/xdragon/XDragonFilterExtensionPoint.java:30 +# args: +xdragon\ host\ not\ support\ create\ vm\ using\ an\ iso\ image. = 神龙服务器不支持使用ISO镜像创建云主机。 + # at: src/main/java/org/zstack/xdragon/XDragonHostFactory.java:34 # args: msg.getClusterUuid(),XDragonConstant.HYPERVISOR_TYPE -cluster[uuid\:%s]\ hypervisorType\ is\ not\ %s = +cluster[uuid\:%s]\ hypervisorType\ is\ not\ %s = 集群[uuid:{0}]管理程序类型不是{1} # at: src/main/java/org/zstack/yunshan/util/YunshanClient.java:46 # args: -the\ url\ is\ null,\ please\ config\ the\ YunShan\ NSP. = +the\ url\ is\ null,\ please\ config\ the\ YunShan\ NSP. = URL为空,请配置云山NSP。 + +# at: src/main/java/org/zstack/zbox/ZBoxApiInterceptor.java:55 +# args: msg.getUsbDeviceUuid(),inventory.getVmInstanceUuid() +usb\ device[uuid\:%s]\ has\ been\ attached\ VM[uuid\:%s],\ cannot\ be\ add\ to\ zbox = USB设备[uuid:{0}]已连接到云主机[uuid:{1}],无法添加到ZBox + +# at: src/main/java/org/zstack/zbox/ZBoxApiInterceptor.java:72 +# args: zbox.getName(),zbox.getStatus() +zbox[name\:%s]\ status\ is\ not\ Ready,\ current\ status\ is\ %s = ZBox[名称:{0}]状态未就绪,当前状态为{1} + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:122 +# args: msg.getZBoxUuid() +zbox[uuid\:%s]\ is\ still\ in\ use,\ cannot\ eject\ it = ZBox[uuid:{0}]仍在使用,无法将其弹出 + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:151 +# args: msg.getZBoxUuid() +zbox[uuid\:%s]\ is\ not\ Ready,\ cannot\ sync\ capacity. = ZBox[uuid:{0}]未就绪,无法同步容量。 + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:219 +# args: self.getMountPath(),msg.getInstallPath() +only\ file\ on\ zbox[mountPath\:%s]\ can\ be\ deleted.\ but\ pass\ [%s] = 只能删除ZBox[mountPath:{0}]上的文件。但传递[{1}] + +# at: src/main/java/org/zstack/zbox/ZBoxBase.java:285 +# args: self.getName(),self.getStatus() +zbox[name\:%s]\ state\ is\ not\ Ready,\ current\ state\ is\ %s = ZBox[名称:{0}]状态未就绪,当前状态为{1} + +# at: src/main/java/org/zstack/zbox/ZBoxFactory.java:57 +# args: zbox.getUuid() +zbox[uuid\:\ %s]\ seems\ like\ removed = ZBox[uuid:{0}]似乎已删除 -# at: src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java:13 +# at: src/main/java/org/zstack/zql/ast/parser/visitors/ValueVisitor.java:140 +# args: apiStr +output\ from\ [%s]\ is\ empty = [{0}]的输出为空 + +# at: src/main/java/org/zstack/zql/ast/parser/visitors/ValueVisitor.java:159 +# args: apiName,JSONObjectUtil.toJsonString(ob) +call\ action[%s]\ failed,\ cause\:\ %s = 调用操作[{0}]失败,原因:{1} + +# at: src/main/java/org/zstack/zql/ast/visitors/OrderByExprVistor.java:14 # args: node.getDirection() -invalid\ order\ by\ clause,\ expect\ direction[asc,desc]\ but\ got\ %s = +invalid\ order\ by\ clause,\ expect\ direction[asc,desc]\ but\ got\ %s = ORDER BY子句无效,应为方向[ASC,DESC],但得到{0} -# at: src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java:19 -# args: m.simpleInventoryName(),node.getField() -invalid\ order\ by\ clause,\ inventory[%s]\ doesn't\ have\ field[%s] = +# at: src/main/java/org/zstack/zql/ast/visitors/OrderByVisitor.java:22 +# args: m.simpleInventoryName(),f +invalid\ order\ by\ clause,\ inventory[%s]\ doesn't\ have\ field[%s] = ORDER BY子句无效,库存[{0}]没有字段[{1}] # at: src/main/java/org/zstack/zql/ast/visitors/plugin/SumPlugin.java:31 # args: -the\ field\ to\ sum\ must\ be\ specified = +the\ field\ to\ sum\ must\ be\ specified = 必须指定要汇总的字段 -# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:125 -# args: clz.getName() -resource[%s]\ doesn't\ support\ zwatch\ return\ with\ clause = +# at: src/main/java/org/zstack/zsv/ZsvManagerImpl.java:95 +# args: volume.getUuid(),volume.getLastVmInstanceUuid() +volume\ %s\ still\ have\ snapshot\ group\ on\ vm\ %s,\ cannot\ attach\ to\ other\ vm = 卷{0}在云主机{1}上仍具有快照组,无法连接到其他云主机 + +# at: src/main/java/org/zstack/zsv/ZsvManagerImpl.java:127 +# args: volume.getUuid() +volume\ %s\ still\ have\ snapshot\ group,\ cannot\ delete\ it = 卷{0}仍具有快照组,无法将其删除 -# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:270 +# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:241 # args: paramName,normalizedExpr -unknown\ parameter[%s]\ in\ zwatch\ return\ with\ clause,\ %s = +unknown\ parameter[%s]\ in\ zwatch\ return\ with\ clause,\ %s = ZWatch Return WITH子句中的未知参数[{0}],{1} -# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:279 +# at: src/main/java/org/zstack/zwatch/ZQLReturnWithExtension.java:250 # args: expr,e.getMessage() -invalid\ zwatch\ return\ with\ clause\:\ %s,\ %s = +invalid\ zwatch\ return\ with\ clause\:\ %s,\ %s = 无效的ZWatch返回WITH子句:{0},{1} -# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:571 -# args: eventData.getDataUuid(),t.getMessage() -update\ eventData[dataUuid\=%s]\ failed,\ %s = - -# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:694 -# args: alarmData.getDataUuid(),t.getMessage() -update\ alarmData[dataUuid\=%s]\ failed,\ %s = - -# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:705 +# at: src/main/java/org/zstack/zwatch/ZWatchManagerImpl.java:1188 # args: Some\ messages\ have\ expired.\ The\ expired\ messages\ are\ not\ allowed\ to\ be\ modified.\ The\ system\ will\ automatically\ clean\ up\ the\ expired\ messages.\ Please\ operate\ later = 部分消息已过期,过期消息不允许修改。系统会自动清理过期消息,请稍后再操作 -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:83 -# args: msg.getActionUuid(),msg.getSubscriptionUuid() -the\ action[uuid\:%s]\ already\ attached\ to\ the\ event\ subscription[uuid\:%s] = 报警动作[uuid:{0}]已经被加载到报警时间订阅[uuid:{1}] - -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:107 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:162 # args: msg.getKey() event\ doesn't\ have\ label[%s] = 报警事件没有标签[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:112 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:167 # args: msg.getKey() the\ event\ subscription\ already\ has\ the\ label[%s] = 事件订阅已经有标签[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:155 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:138 +# args: msg.getActionUuid(),msg.getSubscriptionUuid() +the\ action[uuid\:%s]\ already\ attached\ to\ the\ event\ subscription[uuid\:%s] = 报警动作[uuid:{0}]已经被加载到报警时间订阅[uuid:{1}] + +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:213 # args: msg.getNamespace() namespace[%s]\ not\ found = 找不到命名空间[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:129 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:187 # args: ns.getName(),msg.getEventName() namespace[%s]\ doesn't\ have\ the\ event[%s] = 命名空间[{0}]中没有事件[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:137 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:195 # args: msg.getEventName(),l.getKey() event[%s]\ doesn't\ have\ the\ label[%s] = 事件[{0}]不存在标签[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:197 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:361 # args: k,l duplicate\ key[%s]\ with\ values%s = 重复的键[{0}]和键值{1} -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:164 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:222 # args: msg.getMetricName() -Period\ field\ is\ not\ supported\ for\ metric\ [name\:%s] = +Period\ field\ is\ not\ supported\ for\ metric\ [name\:%s] = 度量[名称:{0}]不支持期间字段 -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:161 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:219 # args: msg.getMetricName() -Period\ field\ can\ not\ be\ null\ for\ metric\ [name\:%s] = +Period\ field\ can\ not\ be\ null\ for\ metric\ [name\:%s] = 度量[名称:{0}]的期间字段不能为Null -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:172 -# args: msg.getNamespace(),msg.getMetricName() +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:401 +# args: msg.getNamespace(),metricName namespace[%s]\ doesn't\ have\ the\ metric[%s] = 命名空间[{0}]不包含时序数据[{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:178 -# args: msg.getMetricName() -the\ metric[%s]\ is\ admin\ only,\ not\ available\ for\ current\ user = +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:405 +# args: metric +the\ metric[%s]\ is\ admin\ only,\ not\ available\ for\ current\ user = 指标[{0}]仅供管理员使用,不可用于当前用户 -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:186 -# args: msg.getMetricName(),l.getKey() +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:350 +# args: templateVO.getMetricName(),l.getKey() the\ metric[%s]\ doesn't\ have\ the\ label[%s] = 时序数据[{0}]没有标签[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:209 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:273 # args: actionType invalid\ action\ type[%s] = 无效的报警动作类型[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:214 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:278 # args: actionUuid,actionType action[uuid\:%s,\ type\:%s]\ not\ found = 找不到报警动作[uuid:{0}, 类型:{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:222 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:286 # args: msg.getActionUuid(),msg.getActionType(),msg.getAlarmUuid() duplicated\ action[uuid\:%s,\ type\:%s]\ for\ the\ alarm[uuid\:%s] = 报警器[uuid:{2}]已经存在报警动作[uuid:{0}, 类型:{1}] -# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:232 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:296 # args: msg.getKey(),msg.getOperator(),msg.getValue(),msg.getAlarmUuid() duplicate\ label[key\:%s,\ operator\:%s,\ value\:%s]\ for\ the\ alarm[uuid\:%s] = 报警器[uuid:{2}]已经存在标签[key:{0}, operator:{1}, value:{2}] +# at: src/main/java/org/zstack/zwatch/alarm/AlarmApiInterceptor.java:390 +# args: msg.getNamespace() +namespace[%s]\ not\ support = 不支持命名空间[{0}] + # at: src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java:110 # args: msg.getSubscriptionUuid() cannot\ find\ the\ event\ subscription[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到事件订阅[uuid:{0}],它可能已经被删除 @@ -9374,7 +14646,7 @@ cannot\ find\ the\ event\ subscription[uuid\:%s],\ it\ may\ have\ been\ deleted # args: msg.getAlarmUuid() cannot\ find\ the\ alarm[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到报警器[uuid:{0}],它可能已经被删除 -# at: src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java:576 +# at: src/main/java/org/zstack/zwatch/alarm/AlarmManagerImpl.java:525 # args: alarmVO.getMetricName() the\ metric[%s]\ repeatInterval\ value\ cannot\ be\ less\ than\ 1h = 时序数据[{0}]的报警间隔时间不能低于1h @@ -9398,94 +14670,138 @@ cannot\ find\ the\ topic[uuid\:%s] = 找不到主题[uuid:{0}] # args: msg.getAlarmTextTemplateUuid() cannot\ find\ SNSTextTemplate[uuid\:%s],\ it\ may\ have\ been\ deleted = 找不到报警文本模板[uuid:{0}], 它可能已经被删除 -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:73 -# args: msg.getApplicationPlatformType() +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:198 +# args: vo.getApplicationPlatformType() invalid\ application\ platform\ type[%s] = 无效的平台类型[{0}] -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:159 -# args: String.join(",\n", errorParams),String.join(",\n", AbstractTextTemplate.defaultSupportedParams) -parameters\:\n\ %s\ are\ not\ supported\ by\ ZStack,\ available\ values\ are\:\n\ %s = +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:212 +# args: String.join(",\n", errorRecoverParams),String.join(",\n", AbstractTextTemplate.defaultSupportedParams.get(vo.getType())) +parameters\:\n\ %s\ are\ not\ supported\ by\ ZStack,\ available\ values\ are\:\n\ %s = 参数:\n{0}不受ZStack支持,可用值为:\n{1} -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:78 -# args: msg.getApplicationPlatformType() +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:203 +# args: vo.getApplicationPlatformType() application\ platform/endpoint\ [%s]\ doesn't\ support\ user-defined\ template = 应用平台/终端[{0}]不支持用户定义模板 -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:91 +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:107 # args: sign,sign.length() -The\ length\ of\ aliyun\ sms\ sign\ should\ between\ 2\ to\ 12\ characters.\ Got\ sign\:\ [%s]\ with\ [%d]\ characters. = +The\ length\ of\ aliyun\ sms\ sign\ should\ between\ 2\ to\ 12\ characters.\ Got\ sign\:\ [%s]\ with\ [%d]\ characters. = 阿里云短信标识的长度应在2-12个字符之间。获得符号:[{0}],包含[{1}]个字符。 -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:96 +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:112 # args: alarmTemplateCode,alarmTemplateCode.length() -Sms\ template\ code\ is\ a\ string\ with\ 13\ characters.\ Got\ alarm\ template\ code\:\ [%s]\ with\ [%d]\ characters. = +Sms\ template\ code\ is\ a\ string\ with\ 13\ characters.\ Got\ alarm\ template\ code\:\ [%s]\ with\ [%d]\ characters. = 短信模板代码是一个13个字符的字符串。获取报警模板代码:[{0}],包含[{1}]个字符。 -# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:101 +# at: src/main/java/org/zstack/zwatch/alarm/sns/SNSTextTemplateApiInterceptor.java:117 # args: eventTemplateCode,eventTemplateCode.length() -Sms\ template\ code\ is\ a\ string\ with\ 13\ characters.\ Got\ event\ template\ code\:\ [%s]\ with\ [%d]\ characters. = +Sms\ template\ code\ is\ a\ string\ with\ 13\ characters.\ Got\ event\ template\ code\:\ [%s]\ with\ [%d]\ characters. = 短信模板代码是一个13个字符的字符串。获取事件模板代码:[{0}],包含[{1}]个字符。 + +# at: src/main/java/org/zstack/zwatch/alarm/sns/TextTemplateFactory.java:31 +# args: type +no\ template\ of\ this\ type:%s,\ = 没有此类型的模板:{0}, -# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:587 -# args: DATA_DIR_CAPACITY_ALARM_UUID +# at: src/main/java/org/zstack/zwatch/alarm/sns/TextTemplateFactory.java:43 +# args: e.getMessage() +template\ error:%s = 模板错误:{0} + +# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:1471 +# args: DATA_DIR_CAPACITY_ALARM_uuid alarm[uuid\:%s]\ is\ a\ system\ alarm\ which\ cannot\ be\ deleted = 报警器[uuid:{0}]是一个系统报警器,不能被删除 -# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:598 -# args: SNSSystemAlarmTopicManager.SYSTEM_ALARM_TOPIC_UUID,DATA_DIR_CAPACITY_ALARM_UUID +# at: src/main/java/org/zstack/zwatch/alarm/system/SystemAlarmManagerImpl.java:1482 +# args: SNSSystemAlarmTopicManager.SYSTEM_ALARM_TOPIC_uuid,DATA_DIR_CAPACITY_ALARM_uuid removing\ system\ topic[uuid\:%s]\ from\ system\ alarm[uuid\:%s]\ is\ forbidden = 禁止从系统报警器[uuid:{1}]移除系统主题[uuid:{0}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:203 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:270 # args: l.getKey(),AuditDataV2.queryableLoginLabels invalid\ label[%s],\ valid\ queryable\ labels\ are\ %s = 无效的标签[{0}],有效的可查询标签是{1} -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:250 -# args: msg.getStartTime(),msg.getEndTime() +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:487 +# args: startTime,endTime startTime[%s]\ is\ greater\ than\ endTime[%s] = 开始时间[{0}]大于结束时间[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:114 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:162 # args: -dataUuid\ cannot\ be\ missed = +dataUuid\ cannot\ be\ missed = 不能缺少数据用户ID -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:120 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:168 # args: -dataStartTime\ and\ dataEndTime\ cannot\ be\ missed = +dataStartTime\ and\ dataEndTime\ cannot\ be\ missed = DataStartTime和DataEndTime不能丢失 -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:124 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:172 # args: msg.getDataStartTime(),msg.getDataEndTime() -dataStartTime[%s]\ is\ greater\ than\ dataEndTime[%s] = +dataStartTime[%s]\ is\ greater\ than\ dataEndTime[%s] = DataStartTime[{0}]大于DataEndTime[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:142 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:190 # args: Namespace.ZSTACK_NAMESPACE_PREFIX namespace\ name\ cannot\ start\ with\ %s\ that\ is\ reserved = 名字空间(namespace)不能以{0}开头 -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:153 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:396 +# args: end,msg.getEndTime(),start,msg.getStartTime() +endTime[%s,\ %sms]\ must\ not\ be\ before\ startTime[%s,\ %sms] = 停止时间(endTime)[{0}, {1}ms]不能在开始时间(startTime)[{2}, {3}ms] + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:211 +# args: MAX_QUERY_PERIOD +query\ period\ cannot\ exceed\ %s = 查询期间不能超过{0} + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:355 # args: msg.getNamespace() cannot\ find\ namespace[%s] = 名字空间(namespace[{0}]不存在 -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:161 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:228 # args: msg.getMetricName(),msg.getNamespace() cannot\ find\ metric[%s]\ in\ namespace[%s] = 名字空间(namespace[{1}]中找不到时序数据[{0}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:174 -# args: msg.getMetricName(),metric.getLabelNames(),l.getKey() +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:378 +# args: msg.getMetricName(),labels,label.getKey() metric[%s]'s\ labels[%s]\ does\ not\ include\ [%s] = 时序数据[{0}]的标签列表[{1}]没有指定的标签[{2}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:186 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:253 # args: msg.getMetricName(),l.getValue() metric[%s]\ does\ not\ has\ filter[%s] = 时序数据[{0}]不包含过滤条件[{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:229 -# args: AuditDataV2.TAG_RESOURCE_UUID -label[%s]\ must\ be\ specified = 必须指定标签[{0}] +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:324 +# args: msg.getSession().getAccountUuid(),opt.get().getValue() +account[uuid\:\ %s]\ has\ no\ access\ to\ the\ resource[uuid\:\ %s] = 帐户[uuid:{0}]无权访问资源[uuid:{1}] -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:271 -# args: end,msg.getEndTime(),start,msg.getStartTime() -endTime[%s,\ %sms]\ must\ not\ be\ before\ startTime[%s,\ %sms] = 停止时间(endTime)[{0}, {1}ms]不能在开始时间(startTime)[{2}, {3}ms] +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:346 +# args: +if\ namespace\ is\ all,\ not\ support\ specify\ metric\ and\ labels = 如果命名空间为ALL,则不支持指定规格和标签 -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:289 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:440 # args: msg.getNamespace() no\ namespace[%s]\ defined\ in\ the\ system = 系统中未定义名字空间(namespace[{0}]) -# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:293 +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:443 # args: msg.getNamespace(),msg.getMetricName() the\ namespace[%s]\ has\ no\ metric[%s] = 名字空间(namespace[{0}])不包含时序数据[{1}] +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:433 +# args: +The\ url\ format\ is\ invalid,\ the\ beginning\ is\ not\ http = URL格式无效,开头不是HTTP + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:449 +# args: +Illegal\ json\ string,\ labelsJsonStr\ format\ is\ invalid = 非法的JSON字符串,labelsjsonstr格式无效 + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:477 +# args: url +platform[url\=%s]\ already\ exists = 平台[URL={0}]已存在 + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:498 +# args: msg.getAlertDataUuid() +alert\ acknowledgement\ record\ does\ not\ exist = 警报确认记录不存在 + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:516 +# args: tableName +invalid\ table[%s] = 表[{0}]无效 + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:522 +# args: endTime,startTime +endTime[%s]\ must\ not\ be\ before\ startTime[%s] = EndTime[{0}]不能早于StartTime[{1}] + +# at: src/main/java/org/zstack/zwatch/api/ZWatchApiInterceptor.java:527 +# args: maxDurationDay +the\ time\ interval\ exceeds\ %\ days = 时间间隔超过%天 + # at: src/main/java/org/zstack/zwatch/datatype/EmergencyLevel.java:19 # args: Normal = 提示 @@ -9506,117 +14822,145 @@ invalid\ function\:\ %s,\ %s = 无效的方法: {0}, {1} # args: expr invalid\ expression\:\ %s,\ no\ function\ found = 无效的表达式: {0},找不到对应的方法 -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:57 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:58 # args: str the\ label\ string[%s]\ contains\ no\ valid\ operator = 标签中[{0}]未包含有效的比较符号(operator) -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:72 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:79 # args: JSONObjectUtil.toJsonString(this) invalid\ label,\ 'key'\ field\ cannot\ be\ null.\ %s = 无效的标签"key"不能为空。{0} -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:75 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:82 # args: JSONObjectUtil.toJsonString(this) invalid\ label,\ 'op'\ field\ is\ null\ or\ something\ another\ than\ Regex\ and\ Equal.\ %s = 无效的标签,'op'为空或者是其它的非正则或者等于符号。{0} -# at: src/main/java/org/zstack/zwatch/datatype/Label.java:78 +# at: src/main/java/org/zstack/zwatch/datatype/Label.java:85 # args: JSONObjectUtil.toJsonString(this) invalid\ label,\ 'value'\ field\ cannot\ be\ null.\ %s = 无效的标签"value"不能为空。{0} +# at: src/main/java/org/zstack/zwatch/datatype/ValueCondition.java:73 +# args: str +the\ ValueCondition\ string[%s]\ require\ 'value'\ as\ key\ = ValueCondition字符串[{0}]需要“ value ”作为键 + # at: src/main/java/org/zstack/zwatch/function/ArgumentChecker.java:30 # args: value,name invalid\ value[%s]\ of\ the\ argument[%s] = 参数[{1}]值(value)[{0}]无效 -# at: src/main/java/org/zstack/zwatch/function/LimitFunction.java:21 -# args: v -value[%s]\ is\ not\ a\ Integer\ number = 值(value)[{0}]不是一个整数 +# at: src/main/java/org/zstack/zwatch/function/ExtremumFunction.java:24 +# args: +unknown\ arguments = 未知参数 -# at: src/main/java/org/zstack/zwatch/function/LimitFunction.java:18 -# args: v -invalid\ argument[limit\:%s],\ it\ can't\ be\ a\ negative\ number = 无效的参数[limit:{0}],不能是负数 +# at: src/main/java/org/zstack/zwatch/function/ExtremumFunction.java:30 +# args: +missing\ required\ argument = 缺少必需的参数 -# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:46 +# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:88 # args: name missing\ required\ argument[%s] = 缺少参数[{0}] -# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:59 +# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:101 # args: k duplicate\ argument[%s] = 重复的参数[{0}] -# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:68 +# at: src/main/java/org/zstack/zwatch/function/MetricFunction.java:116 # args: func.getName() unknown\ function[%s] = 未知方法[{0}] -# at: src/main/java/org/zstack/zwatch/function/SortFunction.java:41 +# at: src/main/java/org/zstack/zwatch/function/PaginationFunction.java:32 +# args: v +value[%s]\ is\ not\ a\ Integer\ number = 值(value)[{0}]不是一个整数 + +# at: src/main/java/org/zstack/zwatch/function/PaginationFunction.java:19 +# args: v +invalid\ argument[limit\:%s],\ it\ can't\ be\ a\ negative\ number = 无效的参数[limit:{0}],不能是负数 + +# at: src/main/java/org/zstack/zwatch/function/PaginationFunction.java:29 +# args: v +invalid\ argument[start\:%s],\ it\ can't\ be\ a\ negative\ number = 参数[开始:{0}]无效,它不能是负数 + +# at: src/main/java/org/zstack/zwatch/function/SortFunction.java:42 # args: arg.name unknown\ argument[%s] = 未知参数[{0}] -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:153 +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:62 +# args: ret.getError() +unable\ to\ query\ influxdb,\ %s = 无法查询InfluxDB,{0} + +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:106 +# args: JSONObjectUtil.toJsonString(ret) +invalid\ influxdb\ response\:\ %s,\ no\ name\ found\ in\ columns = InfluxDB响应无效:{0},在列中找不到名称 + +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:92 +# args: retention,res.getError() +failed\ to\ create\ influxdb\ retention\ '%s',\ %s = 无法创建InfluxDB保留“{0}”,{1} + +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:85 +# args: retention,res.getError() +failed\ to\ alter\ influxdb\ retention\ '%s',\ %s = 无法更改InfluxDB保留“{0}”,{1} + +# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:124 +# args: defaultUserName,res.getError() +failed\ to\ create\ influxdb\ default\ user\ '%s',\ %s = 无法创建InfluxDB默认用户“{0}”,{1} + +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:806 # args: name cannot\ find\ EventFamily[name\:%s] = 找不到事件族[name:{0}] -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:175 +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:797 # args: name,namespace cannot\ find\ EventFamily[name\:%s,\ namespace\:%s] = 找不到事件族[name:{0}, namespace:{1}] -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:632 -# args: label.getKey(),names +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:726 +# args: label.getKey(),nameSpaceLabelList invalid\ query\ label[%s].\ Allowed\ label\ names\ are\ %s = 无效的查询标签[{0}]。允许标签名是 {1} -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDBEventDatabaseDriver.java:666 +# at: src/main/java/org/zstack/zwatch/migratedb/MigrateDBEventDatabaseDriver.java:627 # args: name.getValue(),InfluxEventDataV2.FIELD_NAMESPACE there\ are\ multiple\ EventFamily\ with\ the\ name[%s],\ you\ must\ specify\ the\ label[%s] = 存在多个名为[{0}]的事件族,你必须指定标签[{1}] -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:58 -# args: ret.getError() -unable\ to\ query\ influxdb,\ %s = +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java:55 +# args: msg.getInstanceUuid() +the\ instance[%s]\ is\ already\ in\ the\ group = 实例[{0}]已在组中 -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:102 -# args: JSONObjectUtil.toJsonString(ret) -invalid\ influxdb\ response\:\ %s,\ no\ name\ found\ in\ columns = +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java:66 +# args: msg.getInstanceUuid() +instance[%s]\ is\ not\ in\ the\ group = 实例[{0}]不在组中 -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:88 -# args: retention,res.getError() -failed\ to\ create\ influxdb\ retention\ '%s',\ %s = +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupApiInterceptor.java:76 +# args: msg.getGroupUuid() +The\ monitorGroup[%s]\ does\ not\ have\ an\ monitorTemplate\ applied = MonitorGroup[{0}]未应用MonitorTemplate -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:81 -# args: retention,res.getError() -failed\ to\ alter\ influxdb\ retention\ '%s',\ %s = +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupBase.java:333 +# args: +The\ instance\ in\ the\ group\ has\ reached\ the\ maximum\ limit = 组中的实例已达到最大限制 -# at: src/main/java/org/zstack/zwatch/influxdb/InfluxDatabaseCreator.java:120 -# args: defaultUserName,res.getError() -failed\ to\ create\ influxdb\ default\ user\ '%s',\ %s = +# at: src/main/java/org/zstack/zwatch/monitorgroup/MonitorGroupManagerImpl.java:607 +# args: +The\ rule\ in\ the\ template\ has\ reached\ the\ maximum\ limit = 模板中的规则已达到最大限制 # at: src/main/java/org/zstack/zwatch/mysql/MysqlDatabaseDriver.java:51 # args: qo.getNamespaceName() -no\ mysql\ namespace[%s]\ found = +no\ mysql\ namespace[%s]\ found = 未找到MySQL命名空间[{0}] -# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:46 +# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:48 # args: getName(),queryObject.getMetricName() namespace[%s]\ has\ no\ metric[%s] = 名字空间(namespace)[{0}]没有任何时序数据(metric)[{1}] -# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:52 +# at: src/main/java/org/zstack/zwatch/namespace/AbstractNamespace.java:54 # args: m.getName(),getName(),l.getKey() -metric[%s]\ of\ the\ namespace[%s]\ has\ no\ label\ named\ %s = 名字空间(namespace)[{1}]的时序数据(metric)[{1}]没有名为{2}的标签 +metric[%s]\ of\ the\ namespace[%s]\ has\ no\ label\ named\ %s = 名字空间(namespace)[{1}]的时序数据(metric)[{0}]没有名为{2}的标签 -# at: src/main/java/org/zstack/zwatch/namespace/NamespaceEventManagerImpl.java:406 +# at: src/main/java/org/zstack/zwatch/namespace/NamespaceEventManagerImpl.java:437 # args: error\ happened\ but\ reason\ not\ specified = 发生了意想不到的错误 -# at: src/main/java/org/zstack/zwatch/namespace/SystemNamespace.java:31 +# at: src/main/java/org/zstack/zwatch/namespace/SystemNamespace.java:32 # args: d,Platform.getManagementServerIp() folder[%s]\ not\ found\ on\ the\ management\ server[%s] = 在管理服务器[{1}]上找不到对应的文件夹[{0}] -# at: src/main/java/org/zstack/compute/vm/InstantiateVirtIODriverFlow.java:148 -# args: filepath,Platform.getManagementServerIp() -fail\ to\ attach\ virtio\ driver\ because\ of\ invalid\ md5\ of\ file[%s]\ in\ mn[uuid\:%s] = 挂载默认的VirtIO驱动失败,原因是在管理节点[uuid:{1}]上驱动文件[{0}]已经被修改了 - -# at: src/main/java/org/zstack/compute/vm/InstantiateVirtIODriverFlow.java:154 -# args: filepath,Platform.getManagementServerIp(),cause -fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ %s = 挂载默认的VirtIO驱动失败,原因是在管理节点[uuid:{1}]上无法获取驱动文件[{0}]的MD5数据:{2} - -# at: src/main/java/org/zstack/compute/vm/InstantiateVirtIODriverFlow.java:142 -# args: filepath,Platform.getManagementServerIp() -fail\ to\ attach\ virtio\ driver\ because\ read\ md5\ of\ file[%s]\ fail\ in\ mn[uuid\:%s]\:\ file\ not\ found\ on\ classpath = 挂载默认的VirtIO驱动失败,原因是在管理节点[uuid:{1}]上,服务的ClassPath目录下不存在驱动文件[{0}] +# at: src/main/java/org/zstack/zwatch/prometheus/KvmHostScrape.java:165 +# args: rsp.getError() +%s = {0} # at: src/main/java/org/zstack/zwatch/ruleengine/ComparisonOperator.java:35 # args: @@ -9634,62 +14978,62 @@ GreaterThan = 大于 # args: GreaterThanOrEqualTo = 大于等于 -# at: src/test/java/org/zstack/test/aop/ManInTheMiddleService.java:40 -# args: -unit\ test\ asks\ it\ to\ fail = - -# at: src/test/java/org/zstack/test/compute/hostallocator/HostAllocateExtension.java:22 -# args: -On\ purpose = +# at: src/main/java/org/zstack/zwatch/utils/ResourceVOToNamespaceMappingUtils.java:78 +# args: voClassSimpleName +resource[%s]\ doesn't\ support\ zwatch\ return\ with\ clause = 资源[{0}]不支持ZWatch Return WITH子句 -# at: src/test/java/org/zstack/test/kvm/KVMPingAgentExtensionForTest.java:27 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:80 # args: on\ purpose = -# at: src/test/crypto/org/zstack/crypto/auth/CryptoAuthenticationManagerImpl.java:162 -# args: -could\ not\ enable\ two-factor\ authentication\ when\ CCS\ certificate\ authentication\ is\ enabled = 无法在其它双因子认证开启的情况下启用密评合规 UKey 身份验证 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:56 +# args: item +on\ purpose\ %d = -# at: src/test/crypto/org/zstack/crypto/auth/CryptoAuthenticationManagerImpl.java:170 -# args: -could\ not\ enable\ CCS\ certificate\ authentication\ when\ two-factor\ authentication\ is\ enabled = 无法在密评合规 UKey 身份验证开启的情况下启用双因子认证 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:39 +# args: item +I\ should\ not\ be\ in\ error\ list\ %d = + +# at: src/test/java/org/zstack/test/TestSafeWhile.java:40 +# args: item +I\ should\ not\ be\ in\ error\ list\ either\ %d = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:209 -# args: certificate.uuid -certificate[uuid\=%s]\ not\ found = CCS证书[uuid:{0}]不存在 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:63 +# args: +done,\ on\ purpose = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:224 +# at: src/test/java/org/zstack/test/TestSafeWhile.java:81 # args: -CCS\ certificate\ authentication\ disabled = CCS认证登录未启用。请检查当前是否启用密码机资源池 +I\ should\ not\ be\ errs\ list = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:230 -# args: expectCryptoAuthenticationType, actualCryptoAuthenticationType -wrong\ crypto\ authentication\ type,\ expect[%s],\ actual[%s] = 输入参数UKey的System Tag中, 认证类型错误, 期望是[{0}], 但实际传入[{1}] +# at: src/test/java/org/zstack/test/TestSafeWhile.java:82 +# args: +I\ should\ not\ be\ errs\ list\ either. = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:242 +# at: src/test/java/org/zstack/test/aop/ManInTheMiddleService.java:40 # args: -failed\ to\ decrypt\ cipher\ text = 输入参数UKey的System Tag中, 密文解析失败 +unit\ test\ asks\ it\ to\ fail = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:247 +# at: src/test/java/org/zstack/test/compute/hostallocator/HostAllocateExtension.java:22 # args: -wrong\ credential = 输入参数UKey的System Tag中, 使用的凭证错误 +On\ purpose = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateManagerImpl.java:298 -# args: certificate.uuid -certificate[uuid\=%s]\ is\ not\ within\ the\ valid\ period = CCS证书[uuid:{0}]不在有效期内 +# at: src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java:67 +# args: +on\ purpose\ 3 = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:158 -# args: certificate.uuid -user[uuid\=%s]\ not\ found = 用户[uuid:{0}]不存在 +# at: src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java:75 +# args: +on\ purpose\ 1 = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:162 +# at: src/test/java/org/zstack/test/core/asyncbackup/TestSafeCompletion.java:83 # args: -certificate\ uuid\ is\ empty\ and\ UKey\ system\ tag\ does\ not\ exist = 错误的API输入: 证书UUID (certificateUuid) 和UKey tag (UKey system tag) 不能同时为空 +on\ purpose\ 2 = -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:167 -# args: user.uuid -user[uuid\=%s]\ does\ not\ have\ any\ CCS\ certificate\ attached = = 用户[uuid:{0}]还没有绑定任何CCS证书 +# at: src/main/java/org/zstack/identity/AccountLoginBackend.java:64 +# args: +wrong\ account\ name\ or\ password = 错误信息: 错误的帐号或密码 -# at: src/test/crypto/org/zstack/crypto/ccs/CCSCertificateInterceptor.java:172 -# args: certificate.uuid, user.uuid -user[uuid\=%s]\ already\ has\ the\ certificate[uuid\=%s]\ attached = 用户[uuid:{0}]已经绑定了CCS证书[uuid:{1}] +# at: src/main/java/org/zstack/sns/platform/universalsms/SNSUniversalSmsEndpoint.java:166 +# args: +Failed\ to\ validate\ universal\ sms = 发送测试短信失败 diff --git a/conf/log4j2.xml b/conf/log4j2.xml index ad5e5a117f8..0f604907c62 100755 --- a/conf/log4j2.xml +++ b/conf/log4j2.xml @@ -3,13 +3,9 @@ - + %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] %X{api,task} (%t) %m%n - - - - - + @@ -25,13 +21,9 @@ - + %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] (%t) %m%n - - - - - + @@ -47,13 +39,9 @@ - + %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] (%t) %m%n - - - - - + @@ -63,13 +51,9 @@ - + %d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{1}] (%t) %m%n - - - - - + diff --git a/conf/persistence.xml b/conf/persistence.xml index 65539b6cc9c..33f4326f407 100755 --- a/conf/persistence.xml +++ b/conf/persistence.xml @@ -14,6 +14,7 @@ org.zstack.core.job.JobQueueEntryVO org.zstack.core.config.GlobalConfigVO org.zstack.core.eventlog.EventLogVO + org.zstack.core.plugin.PluginDriverVO org.zstack.resourceconfig.ResourceConfigVO org.zstack.header.managementnode.ManagementNodeVO org.zstack.header.managementnode.ManagementNodeContextVO @@ -23,6 +24,8 @@ org.zstack.header.cluster.ClusterEO org.zstack.header.host.HostVO org.zstack.header.host.HostEO + org.zstack.header.host.HostNetworkLabelVO + org.zstack.header.host.CpuFeaturesHistoryVO org.zstack.header.storage.primary.PrimaryStorageVO org.zstack.header.storage.primary.PrimaryStorageEO org.zstack.header.storage.primary.PrimaryStorageClusterRefVO @@ -33,6 +36,8 @@ org.zstack.header.storage.backup.BackupStorageZoneRefVO org.zstack.header.image.ImageVO org.zstack.header.image.ImageEO + org.zstack.header.image.ImageGroupVO + org.zstack.header.image.ImageGroupRefVO org.zstack.header.image.GuestOsCategoryVO org.zstack.header.image.ImageBackupStorageRefVO org.zstack.header.allocator.HostCapacityVO @@ -48,8 +53,10 @@ org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolVO org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO org.zstack.network.l2.vxlan.vtep.VtepVO + org.zstack.network.l2.vxlan.vtep.RemoteVtepVO org.zstack.network.l2.vxlan.vxlanNetworkPool.VniRangeVO org.zstack.header.network.l2.L2NetworkClusterRefVO + org.zstack.header.network.l2.L2NetworkHostRefVO org.zstack.header.network.l3.L3NetworkVO org.zstack.header.network.l3.L3NetworkEO org.zstack.header.network.l3.L3NetworkDnsVO @@ -59,6 +66,9 @@ org.zstack.header.network.l3.UsedIpVO org.zstack.header.network.l3.AddressPoolVO org.zstack.header.network.l3.NormalIpRangeVO + org.zstack.header.network.l3.ReservedIpRangeVO + org.zstack.network.hostNetworkInterface.HostNetworkBondingVO + org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO org.zstack.network.service.vip.VipVO org.zstack.network.service.vip.VipNetworkServicesRefVO org.zstack.network.service.vip.VipPeerL3NetworkRefVO @@ -76,6 +86,7 @@ org.zstack.appliancevm.ApplianceVmVO org.zstack.appliancevm.ApplianceVmFirewallRuleVO org.zstack.header.vm.VmNicVO + org.zstack.header.vm.VmSchedHistoryVO org.zstack.header.identity.SessionVO org.zstack.header.identity.AccountVO org.zstack.header.identity.AccountResourceRefVO @@ -91,6 +102,9 @@ org.zstack.header.search.InsertVO org.zstack.header.search.UpdateVO org.zstack.kvm.KVMHostVO + org.zstack.kvm.hypervisor.datatype.KvmHypervisorInfoVO + org.zstack.kvm.hypervisor.datatype.HostOsCategoryVO + org.zstack.kvm.hypervisor.datatype.KvmHostHypervisorMetadataVO org.zstack.storage.backup.sftp.SftpBackupStorageVO org.zstack.storage.backup.imagestore.ImageStoreBackupStorageVO org.zstack.header.simulator.SimulatorHostVO @@ -102,6 +116,7 @@ org.zstack.network.securitygroup.SecurityGroupVO org.zstack.network.securitygroup.SecurityGroupFailureHostVO org.zstack.network.securitygroup.VmNicSecurityGroupRefVO + org.zstack.network.securitygroup.VmNicSecurityPolicyVO org.zstack.network.securitygroup.SecurityGroupSequenceNumberVO org.zstack.network.service.portforwarding.PortForwardingRuleVO org.zstack.network.service.virtualrouter.portforwarding.VirtualRouterPortForwardingRuleRefVO @@ -110,6 +125,8 @@ org.zstack.header.storage.snapshot.VolumeSnapshotTreeEO org.zstack.header.storage.snapshot.VolumeSnapshotEO org.zstack.header.storage.snapshot.VolumeSnapshotVO + org.zstack.header.storage.snapshot.reference.VolumeSnapshotReferenceVO + org.zstack.header.storage.snapshot.reference.VolumeSnapshotReferenceTreeVO org.zstack.header.storage.snapshot.VolumeSnapshotBackupStorageRefVO org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupRefVO @@ -118,8 +135,12 @@ org.zstack.header.tag.TagPatternVO org.zstack.network.service.virtualrouter.VirtualRouterVmVO org.zstack.network.service.virtualrouter.VirtualRouterMetadataVO + org.zstack.network.service.virtualrouter.VirtualRouterSoftwareVersionVO org.zstack.storage.primary.local.LocalStorageResourceRefVO org.zstack.storage.primary.local.LocalStorageHostRefVO + org.zstack.header.storage.addon.primary.ExternalPrimaryStorageVO + org.zstack.header.storage.addon.primary.PrimaryStorageOutputProtocolRefVO + org.zstack.header.storage.addon.primary.ExternalPrimaryStorageHostRefVO org.zstack.storage.ceph.backup.CephBackupStorageVO org.zstack.storage.ceph.backup.CephBackupStorageMonVO org.zstack.storage.ceph.primary.CephPrimaryStorageMonVO @@ -167,6 +188,39 @@ org.zstack.header.vm.VmInstanceNumaNodeVO org.zstack.header.host.HostNumaNodeVO org.zstack.header.core.encrypt.EncryptionIntegrityVO - + org.zstack.storage.primary.sharedblock.SharedBlockCapacityVO + org.zstack.header.vm.devices.VmInstanceDeviceAddressVO + org.zstack.header.vm.devices.VmInstanceDeviceAddressArchiveVO + org.zstack.header.vm.devices.VmInstanceDeviceAddressGroupVO + org.zstack.header.core.encrypt.EncryptEntityMetadataVO + org.zstack.storage.ceph.primary.CephOsdGroupVO + org.zstack.header.network.sdncontroller.SdnControllerVO + org.zstack.header.network.sdncontroller.SdnControllerHostRefVO + org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolVO + org.zstack.sdnController.header.HardwareL2VxlanNetworkVO + org.zstack.sdnController.header.VxlanHostMappingVO + org.zstack.sdnController.header.VxlanClusterMappingVO + org.zstack.sdnController.header.H3cSdnControllerTenantVO + org.zstack.sdnController.header.H3cSdnSubnetIpRangeRefVO + org.zstack.header.volume.VolumeHostRefVO + org.zstack.directory.DirectoryVO + org.zstack.directory.ResourceDirectoryRefVO + org.zstack.core.upgrade.AgentVersionVO + org.zstack.header.host.HostIpmiVO + org.zstack.header.sshkeypair.SshKeyPairVO + org.zstack.header.sshkeypair.SshKeyPairRefVO + org.zstack.header.storage.primary.PrimaryStorageHistoricalUsageVO + org.zstack.storage.ceph.primary.CephOsdGroupHistoricalUsageVO + org.zstack.storage.primary.local.LocalStorageHostHistoricalUsageVO + org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpVO + org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpRefVO + org.zstack.header.volume.block.BlockVolumeVO + org.zstack.header.host.HostHwMonitorStatusVO + org.zstack.kvm.xmlhook.XmlHookVO + org.zstack.kvm.xmlhook.XmlHookVmInstanceRefVO + org.zstack.log.server.LogServerVO + org.zstack.header.network.l3.L3NetworkSequenceNumberVO + org.zstack.network.hostNetworkInterface.PhysicalSwitchVO + org.zstack.network.hostNetworkInterface.PhysicalSwitchPortVO diff --git a/conf/roleDefinitions/roleDefinition.json b/conf/roleDefinitions/roleDefinition.json index b357cfb22ae..e4be8f0c369 100644 --- a/conf/roleDefinitions/roleDefinition.json +++ b/conf/roleDefinitions/roleDefinition.json @@ -2,7 +2,7 @@ { "name": "ORGANIZATION_OPERATOR_ROLE", "uuid": "ff46f380a9b745f490f7edbe0f2c72b9", - "description": "\u90e8\u95e8\u8fd0\u8425\u7ba1\u7406\u5458", + "description": "ORGANIZATION_OPERATOR_ROLE", "statements": [ { @@ -95,6 +95,8 @@ "org.zstack.header.host.APIQueryHostMsg", "org.zstack.header.host.APIGetHypervisorTypesMsg", "org.zstack.header.host.APIGetHostTaskMsg", + "org.zstack.header.host.APIGetChainTaskMsg", + "org.zstack.header.host.APIGetVmTaskMsg", "org.zstack.header.host.APIGetHostNetworkFactsMsg", "org.zstack.header.host.APIAddKVMHostFromConfigFileMsg", "org.zstack.header.host.APIQueryHostNetworkBondingMsg", @@ -177,6 +179,8 @@ "org.zstack.network.l2.vxlan.vxlanNetwork.APICreateL2VxlanNetworkMsg", "org.zstack.network.l2.vxlan.vxlanNetworkPool.APIUpdateVniRangeMsg", "org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVniRangeMsg", + "org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVxlanPoolRemoteVtepMsg", + "org.zstack.network.l2.vxlan.vxlanNetworkPool.APIDeleteVxlanPoolRemoteVtepMsg", "org.zstack.header.network.l2.APIDeleteL2NetworkMsg", "org.zstack.ipsec.**", "org.zstack.core.errorcode.**", @@ -429,6 +433,7 @@ "org.zstack.header.configuration.APIDeleteDiskOfferingMsg", "org.zstack.tag2.**", "org.zstack.sdnController.**", + "org.zstack.sugonSdnController.**", "org.zstack.header.image.**", "org.zstack.storage.primary.local.APIGetLocalStorageHostDiskCapacityMsg", "org.zstack.storage.primary.local.APILocalStorageMigrateVolumeMsg", @@ -609,4 +614,4 @@ } ] } -] \ No newline at end of file +] diff --git a/conf/scripts/generate-keys.sh b/conf/scripts/generate-keys.sh index 7f0910a6454..9c1c22b379f 100755 --- a/conf/scripts/generate-keys.sh +++ b/conf/scripts/generate-keys.sh @@ -27,6 +27,7 @@ echo "country = CN" >> $TMP echo "state = Shanghai" >> $TMP echo "locality = Shanghai" >> $TMP echo "cn = store.zstack.org" >> $TMP +echo "dns_name = store.zstack.org" >> $TMP echo "expiration_days = 3652" >> $TMP echo "activation_date = \"$activation_date\"" >> $TMP certtool --template "$TMP" \ diff --git a/conf/scripts/generate-saml-cert.sh b/conf/scripts/generate-saml-cert.sh new file mode 100644 index 00000000000..53079e9ce68 --- /dev/null +++ b/conf/scripts/generate-saml-cert.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -euo pipefail + +OUTDIR=./ +TMP="$(mktemp -t saml_cert.XXXXXX)" +trap 'rm -f "${TMP}"* 2>/dev/null' EXIT + +# Do not overwrite existing certificates +test -s ${OUTDIR}/saml_privkey.pem && \ + { echo "SAML certificates already generated"; exit 0; } + +# Generate private key (PKCS#1) +openssl genrsa -out ${OUTDIR}/saml_privkey.pem 2048 + +# Convert private key to PKCS#8 format +openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \ + -in ${OUTDIR}/saml_privkey.pem \ + -out ${OUTDIR}/saml_privkey_pkcs8.pem + +chmod 400 ${OUTDIR}/saml_privkey.pem +chmod 400 ${OUTDIR}/saml_privkey_pkcs8.pem + +# Generate self-signed SAML certificate +openssl req -x509 -new -nodes \ + -key ${OUTDIR}/saml_privkey.pem \ + -days 1095 \ + -out ${OUTDIR}/saml_cert.pem \ + -subj "/CN=SAML Certificate" + +exit 0 \ No newline at end of file diff --git a/conf/searchConfig/indexConfig.xml b/conf/searchConfig/indexConfig.xml index ee3b4c32f56..a8a6439a059 100644 --- a/conf/searchConfig/indexConfig.xml +++ b/conf/searchConfig/indexConfig.xml @@ -131,4 +131,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/serviceConfig/acl.xml b/conf/serviceConfig/acl.xml index 9c789a6b1b0..ac0ed59c777 100644 --- a/conf/serviceConfig/acl.xml +++ b/conf/serviceConfig/acl.xml @@ -7,6 +7,10 @@ org.zstack.header.acl.APICreateAccessControlListMsg + + org.zstack.header.acl.APIUpdateAccessControlListMsg + + org.zstack.header.acl.APIDeleteAccessControlListMsg diff --git a/conf/serviceConfig/backupStorage.xml b/conf/serviceConfig/backupStorage.xml index af8ee5803e2..8a6da81dfae 100755 --- a/conf/serviceConfig/backupStorage.xml +++ b/conf/serviceConfig/backupStorage.xml @@ -7,6 +7,10 @@ org.zstack.header.storage.backup.APIAddBackupStorageMsg + + org.zstack.header.storage.addon.backup.APIAddExternalBackupStorageMsg + + org.zstack.header.storage.backup.APIChangeBackupStorageStateMsg diff --git a/conf/serviceConfig/ceph.xml b/conf/serviceConfig/ceph.xml index b523a92c80d..1f7f5641159 100755 --- a/conf/serviceConfig/ceph.xml +++ b/conf/serviceConfig/ceph.xml @@ -71,4 +71,9 @@ org.zstack.storage.ceph.primary.APIQueryCephPrimaryStoragePoolMsg query + + + org.zstack.storage.ceph.primary.APIQueryCephOsdGroupMsg + query + diff --git a/conf/serviceConfig/core.xml b/conf/serviceConfig/core.xml new file mode 100644 index 00000000000..f49a6a93f57 --- /dev/null +++ b/conf/serviceConfig/core.xml @@ -0,0 +1,7 @@ + + + core + + org.zstack.header.core.APIGetChainTaskMsg + + \ No newline at end of file diff --git a/conf/serviceConfig/directory.xml b/conf/serviceConfig/directory.xml new file mode 100644 index 00000000000..8d08de63e2d --- /dev/null +++ b/conf/serviceConfig/directory.xml @@ -0,0 +1,31 @@ + + + directory + DirectoryApiInterceptor + + + org.zstack.directory.APICreateDirectoryMsg + + + org.zstack.directory.APIDeleteDirectoryMsg + + + org.zstack.directory.APIMoveDirectoryMsg + + + org.zstack.directory.APIUpdateDirectoryMsg + + + org.zstack.directory.APIAddResourcesToDirectoryMsg + + + org.zstack.directory.APIRemoveResourcesFromDirectoryMsg + + + org.zstack.directory.APIMoveResourcesToDirectoryMsg + + + org.zstack.directory.APIQueryDirectoryMsg + query + + \ No newline at end of file diff --git a/conf/serviceConfig/externalPrimaryStorage.xml b/conf/serviceConfig/externalPrimaryStorage.xml new file mode 100644 index 00000000000..d1687fe7685 --- /dev/null +++ b/conf/serviceConfig/externalPrimaryStorage.xml @@ -0,0 +1,15 @@ + + + storage.primary + + + org.zstack.header.storage.addon.primary.APIUpdateExternalPrimaryStorageMsg + + + org.zstack.header.storage.addon.primary.APIAddExternalPrimaryStorageMsg + + + org.zstack.header.storage.addon.primary.APIDiscoverExternalPrimaryStorageMsg + externalPrimaryStorage> + + diff --git a/conf/serviceConfig/externalService.xml b/conf/serviceConfig/externalService.xml new file mode 100644 index 00000000000..cb2f6c05d86 --- /dev/null +++ b/conf/serviceConfig/externalService.xml @@ -0,0 +1,12 @@ + + + externalService + + + org.zstack.header.core.external.service.APIGetExternalServicesMsg + + + + org.zstack.header.core.external.service.APIReloadExternalServiceMsg + + diff --git a/conf/serviceConfig/flat.xml b/conf/serviceConfig/flat.xml index 4c540596152..5827fe891b2 100644 --- a/conf/serviceConfig/flat.xml +++ b/conf/serviceConfig/flat.xml @@ -6,6 +6,10 @@ org.zstack.network.service.flat.APIGetL3NetworkDhcpIpAddressMsg + + org.zstack.network.service.flat.APIChangeL3NetworkDhcpIpAddressMsg + + org.zstack.network.service.flat.APIGetL3NetworkIpStatisticMsg FlatApiInterceptor diff --git a/conf/serviceConfig/globalConfig.xml b/conf/serviceConfig/globalConfig.xml index fd7a715b52e..c3ee8fae690 100755 --- a/conf/serviceConfig/globalConfig.xml +++ b/conf/serviceConfig/globalConfig.xml @@ -19,4 +19,12 @@ org.zstack.core.config.APIResetGlobalConfigMsg + + + org.zstack.core.config.APIGetGuestOsMetadataMsg + + + + org.zstack.core.config.APIRefreshGuestOsMetadataMsg + diff --git a/conf/serviceConfig/hardwareVxlan.xml b/conf/serviceConfig/hardwareVxlan.xml new file mode 100644 index 00000000000..bb7de7acc08 --- /dev/null +++ b/conf/serviceConfig/hardwareVxlan.xml @@ -0,0 +1,14 @@ + + + network.l2 + VxlanPoolApiInterceptor + + + org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkPoolMsg + + + + org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkMsg + + + \ No newline at end of file diff --git a/conf/serviceConfig/host.xml b/conf/serviceConfig/host.xml index fe107d3c6f6..bb076932f7e 100755 --- a/conf/serviceConfig/host.xml +++ b/conf/serviceConfig/host.xml @@ -34,5 +34,42 @@ org.zstack.header.host.APIGetHostTaskMsg + core + + + + org.zstack.header.host.APIUpdateHostIpmiMsg + + + + org.zstack.header.host.APIShutdownHostMsg + + + + org.zstack.header.host.APIPowerOnHostMsg + + + + org.zstack.header.host.APIPowerResetHostMsg + + + + org.zstack.header.host.APIGetHostWebSshUrlMsg + + + + org.zstack.header.host.APIGetHostPowerStatusMsg + + + + org.zstack.header.host.APICreateHostNetworkServiceTypeMsg + + + + org.zstack.header.host.APIDeleteHostNetworkServiceTypeMsg + + + + org.zstack.header.host.APIUpdateHostNetworkServiceTypeMsg diff --git a/conf/serviceConfig/image.xml b/conf/serviceConfig/image.xml index afe1d9673c1..b93b17d9516 100755 --- a/conf/serviceConfig/image.xml +++ b/conf/serviceConfig/image.xml @@ -11,11 +11,25 @@ org.zstack.header.image.APIDeleteImageMsg + + org.zstack.header.image.APICloneImageMsg + + org.zstack.header.image.APIQueryImageMsg query + + org.zstack.header.image.APIQueryImageGroupMsg + query + + + + org.zstack.header.image.APIQueryImageGroupRefMsg + query + + org.zstack.header.image.APIGetUploadImageJobDetailsMsg @@ -48,6 +62,10 @@ org.zstack.header.image.APIExpungeImageMsg + + org.zstack.header.image.APIExpungeImageGroupMsg + + org.zstack.header.image.APIRecoverImageMsg @@ -59,4 +77,20 @@ org.zstack.header.image.APISetImageBootModeMsg + + + org.zstack.header.image.APICalculateImageHashMsg + + + + org.zstack.header.image.APICreateImageGroupFromVmInstanceMsg + + + + org.zstack.header.image.APICreateImageGroupFromImageMsg + + + + org.zstack.header.image.APICreateImageGroupFromSnapshotMsg + diff --git a/conf/serviceConfig/kvm.xml b/conf/serviceConfig/kvm.xml index 3963755b6c8..a54bd8f838b 100755 --- a/conf/serviceConfig/kvm.xml +++ b/conf/serviceConfig/kvm.xml @@ -18,4 +18,36 @@ kvm + + org.zstack.kvm.hypervisor.message.APIQueryHostOsCategoryMsg + query + + + + org.zstack.kvm.hypervisor.message.APIQueryKvmHypervisorInfoMsg + query + + + + org.zstack.kvm.xmlhook.APICreateVmUserDefinedXmlHookScriptMsg + KVMApiInterceptor + xmlhook + + + + org.zstack.kvm.xmlhook.APIExpungeVmUserDefinedXmlHookScriptMsg + KVMApiInterceptor + xmlhook + + + + org.zstack.kvm.xmlhook.APIUpdateVmUserDefinedXmlHookScriptMsg + KVMApiInterceptor + xmlhook + + + + org.zstack.kvm.xmlhook.APIQueryVmUserDefinedXmlHookScriptMsg + query + diff --git a/conf/serviceConfig/l2Network.xml b/conf/serviceConfig/l2Network.xml index 535de8bc59f..dfa11f4080f 100755 --- a/conf/serviceConfig/l2Network.xml +++ b/conf/serviceConfig/l2Network.xml @@ -40,6 +40,10 @@ org.zstack.header.network.l2.APIUpdateL2NetworkMsg + + org.zstack.header.network.l2.APIChangeL2NetworkVlanIdMsg + + org.zstack.header.network.l2.APIGetCandidateL2NetworksForAttachingClusterMsg @@ -47,4 +51,8 @@ org.zstack.header.network.l2.APIGetCandidateClustersForAttachingL2NetworkMsg + + + org.zstack.sugonSdnController.header.APICreateL2TfNetworkMsg + diff --git a/conf/serviceConfig/l3Network.xml b/conf/serviceConfig/l3Network.xml index e339f8c6a24..7f223fbd592 100755 --- a/conf/serviceConfig/l3Network.xml +++ b/conf/serviceConfig/l3Network.xml @@ -121,6 +121,18 @@ org.zstack.header.network.l3.APIRemoveHostRouteFromL3NetworkMsg + + org.zstack.header.network.l3.APIAddReservedIpRangeMsg + + + + org.zstack.header.network.l3.APIDeleteReservedIpRangeMsg + + + + org.zstack.header.network.l3.APIDeleteIpAddressMsg + + org.zstack.header.network.l3.APIQueryIpAddressMsg query diff --git a/conf/serviceConfig/lb.xml b/conf/serviceConfig/lb.xml index e9cbd954548..c8ca1131c91 100755 --- a/conf/serviceConfig/lb.xml +++ b/conf/serviceConfig/lb.xml @@ -147,4 +147,8 @@ org.zstack.network.service.lb.APIChangeLoadBalancerBackendServerMsg + + org.zstack.network.service.lb.APIAttachVipToLoadBalancerMsg + + diff --git a/conf/serviceConfig/lldp.xml b/conf/serviceConfig/lldp.xml new file mode 100644 index 00000000000..35e08859457 --- /dev/null +++ b/conf/serviceConfig/lldp.xml @@ -0,0 +1,18 @@ + + + hostNetwork.lldp + LldpApiInterceptor + + + org.zstack.network.hostNetworkInterface.lldp.api.APIChangeHostNetworkInterfaceLldpModeMsg + + + + org.zstack.network.hostNetworkInterface.lldp.api.APIGetHostNetworkInterfaceLldpMsg + + + + org.zstack.network.hostNetworkInterface.lldp.api.APIQueryHostNetworkInterfaceLldpMsg + query + + diff --git a/conf/serviceConfig/login.xml b/conf/serviceConfig/login.xml new file mode 100755 index 00000000000..1370c6c8ed7 --- /dev/null +++ b/conf/serviceConfig/login.xml @@ -0,0 +1,12 @@ + + + login + + + org.zstack.header.identity.login.APILogInMsg + + + + org.zstack.header.identity.login.APIGetLoginProceduresMsg + + diff --git a/conf/serviceConfig/plugin.xml b/conf/serviceConfig/plugin.xml new file mode 100644 index 00000000000..366d4d10b1b --- /dev/null +++ b/conf/serviceConfig/plugin.xml @@ -0,0 +1,18 @@ + + + external.plugin + PluginApiInterceptor + + + org.zstack.header.core.external.plugin.APIQueryPluginDriversMsg + query + + + + org.zstack.header.core.external.plugin.APIRefreshPluginDriversMsg + + + + org.zstack.header.core.external.plugin.APIDeletePluginDriversMsg + + \ No newline at end of file diff --git a/conf/serviceConfig/portal.xml b/conf/serviceConfig/portal.xml index f9f4da066cc..3f5618a03d4 100755 --- a/conf/serviceConfig/portal.xml +++ b/conf/serviceConfig/portal.xml @@ -23,4 +23,8 @@ org.zstack.header.managementnode.APIGetManagementNodeOSMsg + + org.zstack.header.managementnode.APIGetSupportAPIsMsg + + diff --git a/conf/serviceConfig/primaryStorage.xml b/conf/serviceConfig/primaryStorage.xml index cbe3a5fdaae..337ce4eaac3 100755 --- a/conf/serviceConfig/primaryStorage.xml +++ b/conf/serviceConfig/primaryStorage.xml @@ -73,4 +73,15 @@ org.zstack.header.storage.primary.APIGetPrimaryStorageLicenseInfoMsg + + + org.zstack.header.storage.primary.APIGetPrimaryStorageUsageReportMsg + + + + org.zstack.header.storage.primary.APICleanUpStorageTrashOnPrimaryStorageMsg + + + org.zstack.header.storage.primary.APIAddStorageProtocolMsg + diff --git a/conf/serviceConfig/resourceConfig.xml b/conf/serviceConfig/resourceConfig.xml index f2039711058..955d008f6c2 100644 --- a/conf/serviceConfig/resourceConfig.xml +++ b/conf/serviceConfig/resourceConfig.xml @@ -7,6 +7,10 @@ org.zstack.resourceconfig.APIUpdateResourceConfigMsg + + org.zstack.resourceconfig.APIUpdateResourceConfigsMsg + + org.zstack.resourceconfig.APIDeleteResourceConfigMsg @@ -24,4 +28,8 @@ org.zstack.resourceconfig.APIGetResourceConfigMsg + + org.zstack.resourceconfig.APIGetResourceConfigsMsg + + diff --git a/conf/serviceConfig/sdnController.xml b/conf/serviceConfig/sdnController.xml new file mode 100644 index 00000000000..41521e0803c --- /dev/null +++ b/conf/serviceConfig/sdnController.xml @@ -0,0 +1,52 @@ + + + SdnController + SdnControllerApiInterceptor + + + org.zstack.sdnController.header.APIAddSdnControllerMsg + + + + org.zstack.sdnController.header.APIRemoveSdnControllerMsg + + + + org.zstack.sdnController.header.APIUpdateSdnControllerMsg + + + + org.zstack.sdnController.header.APISdnControllerAddHostMsg + + + + org.zstack.sdnController.header.APISdnControllerChangeHostMsg + + + + org.zstack.sdnController.header.APISdnControllerRemoveHostMsg + + + + org.zstack.sdnController.header.APIChangeSdnControllerMsg + + + + org.zstack.sdnController.header.APIReconnectSdnControllerMsg + + + + org.zstack.sdnController.header.APIQuerySdnControllerMsg + query + + + + org.zstack.sdnController.header.APIPullSdnControllerTenantMsg + query + + + + org.zstack.network.hostNetworkInterface.APIQueryPhysicalSwitchMsg + query + + \ No newline at end of file diff --git a/conf/serviceConfig/securityGroup.xml b/conf/serviceConfig/securityGroup.xml index 76f632880a3..7b0f0f2b48b 100755 --- a/conf/serviceConfig/securityGroup.xml +++ b/conf/serviceConfig/securityGroup.xml @@ -61,4 +61,33 @@ org.zstack.network.securitygroup.APIUpdateSecurityGroupMsg + + + org.zstack.network.securitygroup.APIChangeSecurityGroupRuleMsg + + + + org.zstack.network.securitygroup.APIUpdateSecurityGroupRulePriorityMsg + + + + org.zstack.network.securitygroup.APIQueryVmNicSecurityPolicyMsg + query + + + + org.zstack.network.securitygroup.APIChangeVmNicSecurityPolicyMsg + + + + org.zstack.network.securitygroup.APIChangeSecurityGroupRuleStateMsg + + + + org.zstack.network.securitygroup.APISetVmNicSecurityGroupMsg + + + + org.zstack.network.securitygroup.APIValidateSecurityGroupRuleMsg + diff --git a/conf/serviceConfig/sshKeyPair.xml b/conf/serviceConfig/sshKeyPair.xml new file mode 100644 index 00000000000..70e7c0f7168 --- /dev/null +++ b/conf/serviceConfig/sshKeyPair.xml @@ -0,0 +1,28 @@ + + + sshKeyPair + SshKeyPairAPIInterceptor + + + org.zstack.header.sshkeypair.APICreateSshKeyPairMsg + + + org.zstack.header.sshkeypair.APIGenerateSshKeyPairMsg + + + org.zstack.header.sshkeypair.APIUpdateSshKeyPairMsg + + + org.zstack.header.sshkeypair.APIDeleteSshKeyPairMsg + + + org.zstack.header.sshkeypair.APIAttachSshKeyPairToVmInstanceMsg + + + org.zstack.header.sshkeypair.APIDetachSshKeyPairFromVmInstanceMsg + + + org.zstack.header.sshkeypair.APIQuerySshKeyPairMsg + query + + \ No newline at end of file diff --git a/conf/serviceConfig/tag.xml b/conf/serviceConfig/tag.xml index e94f8ff7835..48318c249dc 100755 --- a/conf/serviceConfig/tag.xml +++ b/conf/serviceConfig/tag.xml @@ -17,6 +17,10 @@ org.zstack.header.tag.APICreateSystemTagMsg + + org.zstack.header.tag.APICreateSystemTagsMsg + + org.zstack.header.tag.APICreateUserTagMsg diff --git a/conf/serviceConfig/upgrade.xml b/conf/serviceConfig/upgrade.xml new file mode 100644 index 00000000000..a2147d6e558 --- /dev/null +++ b/conf/serviceConfig/upgrade.xml @@ -0,0 +1,8 @@ + + + upgrade + + org.zstack.core.upgrade.APIQueryAgentVersionMsg + query + + \ No newline at end of file diff --git a/conf/serviceConfig/vip.xml b/conf/serviceConfig/vip.xml index 183d582a5e5..0e4129564f9 100755 --- a/conf/serviceConfig/vip.xml +++ b/conf/serviceConfig/vip.xml @@ -7,6 +7,14 @@ org.zstack.network.service.vip.APICreateVipMsg + + org.zstack.network.service.vip.APIGetVipAvailablePortMsg + + + + org.zstack.network.service.vip.APICheckVipPortAvailabilityMsg + + org.zstack.network.service.vip.APIDeleteVipMsg diff --git a/conf/serviceConfig/vmInstance.xml b/conf/serviceConfig/vmInstance.xml index 9677b97d255..81a683490e5 100755 --- a/conf/serviceConfig/vmInstance.xml +++ b/conf/serviceConfig/vmInstance.xml @@ -78,6 +78,9 @@ org.zstack.header.vm.APIDetachL3NetworkFromVmMsg + + org.zstack.header.vm.APIChangeVmNicStateMsg + org.zstack.header.vm.APIGetVmAttachableL3NetworkMsg @@ -117,6 +120,9 @@ org.zstack.header.vm.APIGetVmConsoleAddressMsg + + org.zstack.header.vm.APITakeVmConsoleScreenshotMsg + org.zstack.header.vm.APIDeleteVmHostnameMsg @@ -162,6 +168,9 @@ org.zstack.header.vm.APIGetInterdependentL3NetworksImagesMsg + + org.zstack.header.vm.APIGetInterdependentL3NetworksBackupStoragesMsg + org.zstack.header.vm.APIGetCandidateVmForAttachingIsoMsg @@ -211,6 +220,9 @@ org.zstack.header.vm.APISetVmQxlMemoryMsg + + org.zstack.header.vm.APIFlattenVmInstanceMsg + org.zstack.header.vm.APIGetSpiceCertificatesMsg @@ -220,4 +232,11 @@ org.zstack.header.vm.APIGetVmsCapabilitiesMsg + + org.zstack.header.vm.APIGetVmTaskMsg + core + + + org.zstack.header.vm.APIFstrimVmMsg + diff --git a/conf/serviceConfig/volume.xml b/conf/serviceConfig/volume.xml index 0ec00cd0aff..03fcb26b8de 100755 --- a/conf/serviceConfig/volume.xml +++ b/conf/serviceConfig/volume.xml @@ -73,4 +73,24 @@ org.zstack.header.volume.APIGetVolumeCapabilitiesMsg + + + org.zstack.header.volume.APIAttachDataVolumeToHostMsg + + + + org.zstack.header.volume.APIDetachDataVolumeFromHostMsg + + + + org.zstack.header.volume.APIBatchSyncVolumeSizeMsg + + + + org.zstack.header.volume.APIFlattenVolumeMsg + + + + org.zstack.header.volume.APIUndoSnapshotCreationMsg + diff --git a/conf/serviceConfig/volumeSnapshot.xml b/conf/serviceConfig/volumeSnapshot.xml index 581034ca4b1..1132ff9ad38 100755 --- a/conf/serviceConfig/volumeSnapshot.xml +++ b/conf/serviceConfig/volumeSnapshot.xml @@ -50,6 +50,20 @@ query + + org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressArchiveMsg + query + + + + org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressGroupMsg + query + + + + org.zstack.header.vm.APIGetMemorySnapshotGroupReferenceMsg + + org.zstack.header.storage.snapshot.group.APIUngroupVolumeSnapshotGroupMsg diff --git a/conf/serviceConfig/vxlan.xml b/conf/serviceConfig/vxlan.xml index bfa5981a4ef..4ed958f4ba3 100644 --- a/conf/serviceConfig/vxlan.xml +++ b/conf/serviceConfig/vxlan.xml @@ -11,6 +11,14 @@ org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVniRangeMsg + + org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVxlanPoolRemoteVtepMsg + + + + org.zstack.network.l2.vxlan.vxlanNetworkPool.APIDeleteVxlanPoolRemoteVtepMsg + + org.zstack.network.l2.vxlan.vxlanNetwork.APICreateL2VxlanNetworkMsg @@ -47,4 +55,4 @@ query - \ No newline at end of file + diff --git a/conf/springConfigXml/AccountManager.xml b/conf/springConfigXml/AccountManager.xml index 1f0d870b26c..79df4f3c2fe 100755 --- a/conf/springConfigXml/AccountManager.xml +++ b/conf/springConfigXml/AccountManager.xml @@ -53,6 +53,12 @@ + + + + + + diff --git a/conf/springConfigXml/ApiMediator.xml b/conf/springConfigXml/ApiMediator.xml index ceaad237245..1a4d1b1e6ee 100755 --- a/conf/springConfigXml/ApiMediator.xml +++ b/conf/springConfigXml/ApiMediator.xml @@ -1,8 +1,8 @@ - + default-init-method="init" default-destroy-method="destroy"> + - + + - - + + + + + serviceConfig - + - + - + + + + + + + diff --git a/conf/springConfigXml/ApplianceVmFacade.xml b/conf/springConfigXml/ApplianceVmFacade.xml index e29b57c97a8..5d3678a49f5 100755 --- a/conf/springConfigXml/ApplianceVmFacade.xml +++ b/conf/springConfigXml/ApplianceVmFacade.xml @@ -33,6 +33,15 @@ + + + + + + + + diff --git a/conf/springConfigXml/Aspect.xml b/conf/springConfigXml/Aspect.xml index 075508a3a59..e5fd89471e1 100755 --- a/conf/springConfigXml/Aspect.xml +++ b/conf/springConfigXml/Aspect.xml @@ -19,6 +19,7 @@ + diff --git a/conf/springConfigXml/ClusterManager.xml b/conf/springConfigXml/ClusterManager.xml index ee330c629d9..5e62c48d9dd 100755 --- a/conf/springConfigXml/ClusterManager.xml +++ b/conf/springConfigXml/ClusterManager.xml @@ -12,6 +12,13 @@ http://zstack.org/schema/zstack/plugin.xsd" default-init-method="init" default-destroy-method="destroy"> + + + + + + + diff --git a/conf/springConfigXml/ConsoleManager.xml b/conf/springConfigXml/ConsoleManager.xml index efc4edcaf17..fb023470cb2 100755 --- a/conf/springConfigXml/ConsoleManager.xml +++ b/conf/springConfigXml/ConsoleManager.xml @@ -18,6 +18,7 @@ + diff --git a/conf/springConfigXml/DatabaseFacade.xml b/conf/springConfigXml/DatabaseFacade.xml index 108ba0fdfd0..0e32b390993 100755 --- a/conf/springConfigXml/DatabaseFacade.xml +++ b/conf/springConfigXml/DatabaseFacade.xml @@ -87,6 +87,7 @@ sync + true diff --git a/conf/springConfigXml/ExternalBackupStorage.xml b/conf/springConfigXml/ExternalBackupStorage.xml new file mode 100755 index 00000000000..59709204e47 --- /dev/null +++ b/conf/springConfigXml/ExternalBackupStorage.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/conf/springConfigXml/ExternalPrimaryStorage.xml b/conf/springConfigXml/ExternalPrimaryStorage.xml new file mode 100644 index 00000000000..55450dca7b7 --- /dev/null +++ b/conf/springConfigXml/ExternalPrimaryStorage.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/HostAllocatorManager.xml b/conf/springConfigXml/HostAllocatorManager.xml index 5a107120b24..6370d63ea00 100755 --- a/conf/springConfigXml/HostAllocatorManager.xml +++ b/conf/springConfigXml/HostAllocatorManager.xml @@ -28,6 +28,7 @@ NFS SharedMountPoint LocalStorage + Addon @@ -35,6 +36,7 @@ SharedMountPoint LocalStorage Ceph + Addon @@ -98,9 +100,9 @@ org.zstack.compute.allocator.AttachedL2NetworkAllocatorFlow + org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.QuotaAllocatorFlow org.zstack.compute.allocator.BackupStorageSelectPrimaryStorageAllocatorFlow - org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.HostStateAndHypervisorAllocatorFlow org.zstack.compute.allocator.ImageBackupStorageAllocatorFlow org.zstack.compute.allocator.HostCapacityAllocatorFlow @@ -132,9 +134,9 @@ org.zstack.compute.allocator.AttachedL2NetworkAllocatorFlow + org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.QuotaAllocatorFlow org.zstack.compute.allocator.BackupStorageSelectPrimaryStorageAllocatorFlow - org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.HostStateAndHypervisorAllocatorFlow org.zstack.compute.allocator.ImageBackupStorageAllocatorFlow org.zstack.compute.allocator.HostCapacityAllocatorFlow @@ -165,12 +167,13 @@ org.zstack.compute.allocator.AttachedL2NetworkAllocatorFlow + org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.QuotaAllocatorFlow org.zstack.compute.allocator.BackupStorageSelectPrimaryStorageAllocatorFlow - org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.HostStateAndHypervisorAllocatorFlow org.zstack.compute.allocator.ImageBackupStorageAllocatorFlow org.zstack.compute.allocator.HostCapacityAllocatorFlow + org.zstack.compute.allocator.AttachedVolumePrimaryStorageAllocatorFlow org.zstack.compute.allocator.HostPrimaryStorageAllocatorFlow org.zstack.compute.allocator.AvoidHostAllocatorFlow org.zstack.compute.allocator.TagAllocatorFlow @@ -196,9 +199,9 @@ org.zstack.compute.allocator.AttachedL2NetworkAllocatorFlow + org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.QuotaAllocatorFlow org.zstack.compute.allocator.BackupStorageSelectPrimaryStorageAllocatorFlow - org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.ImageBackupStorageAllocatorFlow org.zstack.compute.allocator.HostStateAndHypervisorAllocatorFlow org.zstack.compute.allocator.HostCapacityAllocatorFlow @@ -222,9 +225,9 @@ org.zstack.compute.allocator.AttachedL2NetworkAllocatorFlow + org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.QuotaAllocatorFlow org.zstack.compute.allocator.BackupStorageSelectPrimaryStorageAllocatorFlow - org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.HostStateAndHypervisorAllocatorFlow org.zstack.compute.allocator.HostCapacityAllocatorFlow org.zstack.compute.allocator.AttachedVolumePrimaryStorageAllocatorFlow @@ -248,9 +251,9 @@ org.zstack.compute.allocator.AttachedL2NetworkAllocatorFlow + org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.HostStateAndHypervisorAllocatorFlow org.zstack.compute.allocator.BackupStorageSelectPrimaryStorageAllocatorFlow - org.zstack.compute.allocator.HostCapacityAllocatorFlow org.zstack.compute.allocator.AttachedVolumePrimaryStorageAllocatorFlow org.zstack.compute.allocator.DesignatedHostAllocatorFlow org.zstack.compute.allocator.HostPrimaryStorageAllocatorFlow diff --git a/conf/springConfigXml/HostManager.xml b/conf/springConfigXml/HostManager.xml index 709f882fd3f..8147620c4ae 100755 --- a/conf/springConfigXml/HostManager.xml +++ b/conf/springConfigXml/HostManager.xml @@ -1,8 +1,8 @@ + default-init-method="init" default-destroy-method="destroy"> + interface="org.zstack.header.cluster.ClusterChangeStateExtensionPoint" + instance-ref="HostExtensionToCluster" /> - - @@ -34,7 +32,7 @@ + interface="org.zstack.header.managementnode.ManagementNodeChangeListener" /> @@ -54,7 +52,7 @@ - + @@ -75,4 +73,5 @@ + diff --git a/conf/springConfigXml/HostNetworkManager.xml b/conf/springConfigXml/HostNetworkManager.xml new file mode 100644 index 00000000000..7a4641713e8 --- /dev/null +++ b/conf/springConfigXml/HostNetworkManager.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/Kvm.xml b/conf/springConfigXml/Kvm.xml index 0ee2e939c8b..580169b641a 100755 --- a/conf/springConfigXml/Kvm.xml +++ b/conf/springConfigXml/Kvm.xml @@ -32,6 +32,7 @@ + @@ -46,10 +47,15 @@ - + + + + + + @@ -83,10 +89,17 @@ + + + + + + + - + @@ -121,6 +134,13 @@ + + + + + + + @@ -150,4 +170,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/LdapManagerImpl.xml b/conf/springConfigXml/LdapManagerImpl.xml index 1e852fab12a..8f3a7de646b 100755 --- a/conf/springConfigXml/LdapManagerImpl.xml +++ b/conf/springConfigXml/LdapManagerImpl.xml @@ -16,6 +16,7 @@ + diff --git a/conf/springConfigXml/NetworkManager.xml b/conf/springConfigXml/NetworkManager.xml index 15a5c17f8e8..1b964387eb4 100755 --- a/conf/springConfigXml/NetworkManager.xml +++ b/conf/springConfigXml/NetworkManager.xml @@ -48,12 +48,13 @@ - + + @@ -75,6 +76,13 @@ + + + + + + + @@ -134,6 +142,12 @@ + + + + + + diff --git a/conf/springConfigXml/NfsPrimaryStorage.xml b/conf/springConfigXml/NfsPrimaryStorage.xml index 9ea0b6add4a..50687d7bf33 100755 --- a/conf/springConfigXml/NfsPrimaryStorage.xml +++ b/conf/springConfigXml/NfsPrimaryStorage.xml @@ -32,6 +32,7 @@ + diff --git a/conf/springConfigXml/PortForwarding.xml b/conf/springConfigXml/PortForwarding.xml index 9c02c04e2e8..0a0f5a80924 100755 --- a/conf/springConfigXml/PortForwarding.xml +++ b/conf/springConfigXml/PortForwarding.xml @@ -35,6 +35,7 @@ + diff --git a/conf/springConfigXml/PrimaryStorageManager.xml b/conf/springConfigXml/PrimaryStorageManager.xml index 13b447a2494..b458d4dd29a 100755 --- a/conf/springConfigXml/PrimaryStorageManager.xml +++ b/conf/springConfigXml/PrimaryStorageManager.xml @@ -2,6 +2,7 @@ + + @@ -37,6 +40,7 @@ org.zstack.storage.primary.PrimaryStorageMainAllocatorFlow org.zstack.storage.primary.PrimaryStorageAvoidAllocatorFlow + org.zstack.storage.primary.PrimaryStorageFeatureAllocatorFlow org.zstack.storage.primary.PrimaryStorageTagAllocatorFlow org.zstack.storage.primary.PrimaryStorageReservedCapacityAllocatorFlow @@ -55,6 +59,81 @@ + + + + org.zstack.storage.primary.PrimaryStorageMainAllocatorFlow + org.zstack.storage.primary.PrimaryStorageAvoidAllocatorFlow + org.zstack.storage.primary.PrimaryStorageFeatureAllocatorFlow + org.zstack.storage.primary.PrimaryStorageTagAllocatorFlow + org.zstack.storage.primary.PrimaryStorageReservedCapacityAllocatorFlow + + + + + org.zstack.storage.primary.PrimaryStorageSortFlow + org.zstack.storage.primary.PrimaryStorageSortByVolumeQuantityFlow + + + + + + + + + + + + + + org.zstack.storage.primary.PrimaryStorageMainAllocatorFlow + org.zstack.storage.primary.PrimaryStorageAvoidAllocatorFlow + org.zstack.storage.primary.PrimaryStorageFeatureAllocatorFlow + org.zstack.storage.primary.PrimaryStorageTagAllocatorFlow + org.zstack.storage.primary.PrimaryStorageReservedCapacityAllocatorFlow + + + + + org.zstack.storage.primary.PrimaryStorageSortFlow + org.zstack.storage.primary.PrimaryStorageSortByAvailableVirtualCapacityFlow + + + + + + + + + + + + + + org.zstack.storage.primary.PrimaryStorageMainAllocatorFlow + org.zstack.storage.primary.PrimaryStorageAvoidAllocatorFlow + org.zstack.storage.primary.PrimaryStorageFeatureAllocatorFlow + org.zstack.storage.primary.PrimaryStorageTagAllocatorFlow + org.zstack.storage.primary.PrimaryStorageReservedCapacityAllocatorFlow + + + + + org.zstack.storage.primary.PrimaryStorageSortFlow + org.zstack.storage.primary.PrimaryStorageSortByCustomOrderFlow + + + + + + + + + + @@ -96,4 +175,10 @@ + + + + + + diff --git a/conf/springConfigXml/SecurityGroupManager.xml b/conf/springConfigXml/SecurityGroupManager.xml index f78b6b4dff4..923a01f5d3e 100755 --- a/conf/springConfigXml/SecurityGroupManager.xml +++ b/conf/springConfigXml/SecurityGroupManager.xml @@ -21,18 +21,21 @@ + + + @@ -66,4 +69,10 @@ + + + + + + diff --git a/conf/springConfigXml/TfPortAllocator.xml b/conf/springConfigXml/TfPortAllocator.xml new file mode 100644 index 00000000000..cd6a5c89366 --- /dev/null +++ b/conf/springConfigXml/TfPortAllocator.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/springConfigXml/VirtualRouter.xml b/conf/springConfigXml/VirtualRouter.xml index 1ba2cc63cb6..1f60d286f95 100755 --- a/conf/springConfigXml/VirtualRouter.xml +++ b/conf/springConfigXml/VirtualRouter.xml @@ -15,6 +15,7 @@ + @@ -123,6 +124,9 @@ + + + @@ -160,6 +164,7 @@ + @@ -174,6 +179,7 @@ + @@ -190,7 +196,7 @@ - + @@ -215,6 +221,7 @@ + @@ -292,4 +299,11 @@ + + + + + + + diff --git a/conf/springConfigXml/VmInstanceManager.xml b/conf/springConfigXml/VmInstanceManager.xml index 7bd0a885ee1..ef3d5a7cc9e 100755 --- a/conf/springConfigXml/VmInstanceManager.xml +++ b/conf/springConfigXml/VmInstanceManager.xml @@ -17,13 +17,26 @@ http://zstack.org/schema/zstack/plugin.xsd" default-init-method="init" default-destroy-method="destroy"> + + + + + + + + + + + + org.zstack.compute.vm.VmImageSelectBackupStorageFlow org.zstack.compute.vm.VmAllocateHostAndPrimaryStorageFlow - org.zstack.compute.vm.VmAllocateVolumeFlow + org.zstack.compute.vm.VmAllocateVolumeFlow org.zstack.compute.vm.VmAllocateNicFlow + org.zstack.compute.vm.VmAllocateNicIpFlow org.zstack.compute.vm.VmAllocateCdRomFlow org.zstack.compute.vm.VmInstantiateResourcePreFlow org.zstack.compute.vm.VmCreateOnHypervisorFlow @@ -74,7 +87,8 @@ org.zstack.compute.vm.VmDestroyOnHypervisorFlow org.zstack.compute.vm.VmReturnHostFlow org.zstack.compute.vm.VmReleaseResourceFlow - org.zstack.compute.vm.VmReturnReleaseNicFlow + org.zstack.compute.vm.VmReturnReleaseNicFlow + org.zstack.compute.vm.VmPostReleaseNicFlow org.zstack.compute.vm.VmDeleteVolumeFlow @@ -127,6 +141,7 @@ + @@ -140,6 +155,13 @@ + + + + + + + @@ -178,10 +200,13 @@ + + virtio e1000 rtl8139 + pcnet @@ -196,6 +221,7 @@ + @@ -204,6 +230,12 @@ + + + + + + diff --git a/conf/springConfigXml/VolumeManager.xml b/conf/springConfigXml/VolumeManager.xml index b2cc6c5bfb2..977134a8873 100755 --- a/conf/springConfigXml/VolumeManager.xml +++ b/conf/springConfigXml/VolumeManager.xml @@ -21,12 +21,14 @@ + + diff --git a/conf/springConfigXml/cas.xml b/conf/springConfigXml/cas.xml new file mode 100644 index 00000000000..d95a865ada6 --- /dev/null +++ b/conf/springConfigXml/cas.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/cbd.xml b/conf/springConfigXml/cbd.xml new file mode 100644 index 00000000000..1582b325515 --- /dev/null +++ b/conf/springConfigXml/cbd.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/conf/springConfigXml/ceph.xml b/conf/springConfigXml/ceph.xml index ea44f8e6ba8..c4489de344c 100755 --- a/conf/springConfigXml/ceph.xml +++ b/conf/springConfigXml/ceph.xml @@ -49,6 +49,7 @@ + @@ -72,6 +73,12 @@ + + + + + + @@ -85,6 +92,12 @@ + + + + + + @@ -109,9 +122,27 @@ + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/core.xml b/conf/springConfigXml/core.xml new file mode 100644 index 00000000000..73524130a48 --- /dev/null +++ b/conf/springConfigXml/core.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/springConfigXml/directoryManager.xml b/conf/springConfigXml/directoryManager.xml new file mode 100644 index 00000000000..90fd4a181ab --- /dev/null +++ b/conf/springConfigXml/directoryManager.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/springConfigXml/encrypt.xml b/conf/springConfigXml/encrypt.xml index fff93ae6a3b..4cac18b6b70 100644 --- a/conf/springConfigXml/encrypt.xml +++ b/conf/springConfigXml/encrypt.xml @@ -26,7 +26,7 @@ - + @@ -43,4 +43,5 @@ + \ No newline at end of file diff --git a/conf/springConfigXml/expon.xml b/conf/springConfigXml/expon.xml new file mode 100644 index 00000000000..a7628ee7899 --- /dev/null +++ b/conf/springConfigXml/expon.xml @@ -0,0 +1,28 @@ + + + + + + + ImageStoreBackupStorage + + + + + + + + + + diff --git a/conf/springConfigXml/externalService.xml b/conf/springConfigXml/externalService.xml index 5b7bac752f5..5b77228a770 100755 --- a/conf/springConfigXml/externalService.xml +++ b/conf/springConfigXml/externalService.xml @@ -12,5 +12,10 @@ http://zstack.org/schema/zstack/plugin.xsd" default-init-method="init" default-destroy-method="destroy"> - + + + + + + diff --git a/conf/springConfigXml/flatNetworkProvider.xml b/conf/springConfigXml/flatNetworkProvider.xml index d0ce62c9e15..b05ce499cfc 100755 --- a/conf/springConfigXml/flatNetworkProvider.xml +++ b/conf/springConfigXml/flatNetworkProvider.xml @@ -24,6 +24,8 @@ + + @@ -40,6 +42,7 @@ + @@ -61,6 +64,7 @@ + diff --git a/conf/springConfigXml/identity.xml b/conf/springConfigXml/identity.xml new file mode 100644 index 00000000000..efa6655f0a7 --- /dev/null +++ b/conf/springConfigXml/identity.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/conf/springConfigXml/iscsi.xml b/conf/springConfigXml/iscsi.xml new file mode 100644 index 00000000000..cdf3ebc5fe8 --- /dev/null +++ b/conf/springConfigXml/iscsi.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/localStorage.xml b/conf/springConfigXml/localStorage.xml index 1c4781a4a2f..7a0bda427da 100755 --- a/conf/springConfigXml/localStorage.xml +++ b/conf/springConfigXml/localStorage.xml @@ -33,7 +33,7 @@ interface="org.zstack.header.storage.primary.InstantiateDataVolumeOnCreationExtensionPoint"/> - + @@ -86,6 +86,7 @@ + @@ -98,6 +99,13 @@ + + + + + + + @@ -128,4 +136,10 @@ + + + + + + diff --git a/conf/springConfigXml/plugin.xml b/conf/springConfigXml/plugin.xml new file mode 100644 index 00000000000..743bca51ec0 --- /dev/null +++ b/conf/springConfigXml/plugin.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/sdnController.xml b/conf/springConfigXml/sdnController.xml new file mode 100644 index 00000000000..a9be9ec8795 --- /dev/null +++ b/conf/springConfigXml/sdnController.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/sharedMountPointPrimaryStorage.xml b/conf/springConfigXml/sharedMountPointPrimaryStorage.xml index 5095b963d04..273767cb68d 100755 --- a/conf/springConfigXml/sharedMountPointPrimaryStorage.xml +++ b/conf/springConfigXml/sharedMountPointPrimaryStorage.xml @@ -31,6 +31,12 @@ + + + + + + @@ -48,4 +54,10 @@ + + + + + + diff --git a/conf/springConfigXml/sshKeyPair.xml b/conf/springConfigXml/sshKeyPair.xml new file mode 100644 index 00000000000..affbfc2f94b --- /dev/null +++ b/conf/springConfigXml/sshKeyPair.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/conf/springConfigXml/sugonSdnController.xml b/conf/springConfigXml/sugonSdnController.xml new file mode 100644 index 00000000000..f0ff6ad0033 --- /dev/null +++ b/conf/springConfigXml/sugonSdnController.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/upgrade.xml b/conf/springConfigXml/upgrade.xml new file mode 100644 index 00000000000..d2cdb813378 --- /dev/null +++ b/conf/springConfigXml/upgrade.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/conf/springConfigXml/vhost.xml b/conf/springConfigXml/vhost.xml new file mode 100644 index 00000000000..afe7d5abf54 --- /dev/null +++ b/conf/springConfigXml/vhost.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + diff --git a/conf/springConfigXml/vip.xml b/conf/springConfigXml/vip.xml index e2c22fcbad9..f5ca0a12870 100755 --- a/conf/springConfigXml/vip.xml +++ b/conf/springConfigXml/vip.xml @@ -15,6 +15,7 @@ + diff --git a/conf/springConfigXml/volumeSnapshot.xml b/conf/springConfigXml/volumeSnapshot.xml index 142ace52cff..09022186cb2 100755 --- a/conf/springConfigXml/volumeSnapshot.xml +++ b/conf/springConfigXml/volumeSnapshot.xml @@ -24,6 +24,8 @@ + + @@ -39,4 +41,16 @@ + + + + + + + + + + + + diff --git a/conf/springConfigXml/vxlan.xml b/conf/springConfigXml/vxlan.xml index d57fdbed7d5..6a4dd758acd 100644 --- a/conf/springConfigXml/vxlan.xml +++ b/conf/springConfigXml/vxlan.xml @@ -29,6 +29,7 @@ + @@ -95,4 +96,11 @@ + + + + + + + diff --git a/conf/springConfigXml/vyos.xml b/conf/springConfigXml/vyos.xml index 514969c1dac..0793d44131a 100755 --- a/conf/springConfigXml/vyos.xml +++ b/conf/springConfigXml/vyos.xml @@ -12,6 +12,12 @@ http://zstack.org/schema/zstack/plugin.xsd" default-init-method="init" default-destroy-method="destroy"> + + + + + + @@ -96,7 +102,11 @@ + org.zstack.network.service.virtualrouter.vyos.VyosGetVersionFlow + org.zstack.network.service.virtualrouter.vyos.VyosDeployAgentFlow + org.zstack.network.service.virtualrouter.vyos.VyosConnectFlow org.zstack.network.service.virtualrouter.vyos.VyosConfigSshFlow + org.zstack.network.service.virtualrouter.ha.VirtualRouterHaSyncConfigToBackendFlow org.zstack.network.service.virtualrouter.vyos.VyosChangePrivateL3FirewallDefaultActionFlow org.zstack.network.service.virtualrouter.dns.VirtualRouterSyncDnsOnStartFlow org.zstack.network.service.virtualrouter.vyos.VyosRefreshDchpServerFlow @@ -115,6 +125,7 @@ + @@ -153,6 +164,12 @@ + + + + + + @@ -183,6 +200,7 @@ + diff --git a/conf/springConfigXml/xinfini.xml b/conf/springConfigXml/xinfini.xml new file mode 100644 index 00000000000..8527c843f7d --- /dev/null +++ b/conf/springConfigXml/xinfini.xml @@ -0,0 +1,28 @@ + + + + + + + ImageStoreBackupStorage + + + + + + + + + + diff --git a/conf/springConfigXml/zbs.xml b/conf/springConfigXml/zbs.xml new file mode 100644 index 00000000000..2e0234ddc1d --- /dev/null +++ b/conf/springConfigXml/zbs.xml @@ -0,0 +1,32 @@ + + + + + + + ImageStoreBackupStorage + + + + + + + + + + + + + + diff --git a/conf/tools/ansible-1.9.6.tar.gz b/conf/tools/ansible-1.9.6.tar.gz index 1c9021cd33f..595c5841437 100644 Binary files a/conf/tools/ansible-1.9.6.tar.gz and b/conf/tools/ansible-1.9.6.tar.gz differ diff --git a/conf/tools/ansible-4.10.0-py2.py3-none-any.whl b/conf/tools/ansible-4.10.0-py2.py3-none-any.whl new file mode 100644 index 00000000000..6affa43ffaa Binary files /dev/null and b/conf/tools/ansible-4.10.0-py2.py3-none-any.whl differ diff --git a/conf/tools/ansible-4.10.0.tar.gz b/conf/tools/ansible-4.10.0.tar.gz new file mode 100644 index 00000000000..3d9a9ae2635 Binary files /dev/null and b/conf/tools/ansible-4.10.0.tar.gz differ diff --git a/conf/tools/install.sh b/conf/tools/install.sh index d8be4505f1b..2821bc9ab6d 100755 --- a/conf/tools/install.sh +++ b/conf/tools/install.sh @@ -39,7 +39,7 @@ if [ $tool = 'zstack-cli' ]; then CLI_VIRENV_PATH=/var/lib/zstack/virtualenv/zstackcli [ ! -z $force ] && rm -rf $CLI_VIRENV_PATH if [ ! -d "$CLI_VIRENV_PATH" ]; then - virtualenv $CLI_VIRENV_PATH + virtualenv $CLI_VIRENV_PATH --python=python2.7 if [ $? -ne 0 ]; then rm -rf $CLI_VIRENV_PATH exit 1 @@ -74,18 +74,73 @@ if [ $tool = 'zstack-cli' ]; then elif [ $tool = 'zstack-ctl' ]; then CTL_VIRENV_PATH=/var/lib/zstack/virtualenv/zstackctl - rm -rf $CTL_VIRENV_PATH && virtualenv $CTL_VIRENV_PATH || exit 1 + rm -rf $CTL_VIRENV_PATH && virtualenv $CTL_VIRENV_PATH --python=python2.7 || exit 1 . $CTL_VIRENV_PATH/bin/activate cd $cwd - pip install -i $pypi_path --trusted-host localhost --ignore-installed zstackctl-*.tar.gz || exit 1 + TMPDIR=/usr/local/zstack/ pip install -i $pypi_path --trusted-host localhost --ignore-installed zstackctl-*.tar.gz || exit 1 + TMPDIR=/usr/local/zstack/ pip install -i $pypi_path --trusted-host localhost --ignore-installed pycrypto==2.6.1 || exit 1 chmod +x /usr/bin/zstack-ctl python $CTL_VIRENV_PATH/lib/python2.7/site-packages/zstackctl/generate_zstackctl_bash_completion.py +elif [ $tool = 'zstack-sys' ]; then + SYS_VIRENV_PATH=/var/lib/zstack/virtualenv/zstacksys + NEED_INSTALL=false + if [ -d $SYS_VIRENV_PATH ]; then + . $SYS_VIRENV_PATH/bin/activate + if ! ansible --version | grep -q 'core 2.11.12.3'; then + deactivate + NEED_INSTALL=true + fi + else + NEED_INSTALL=true + fi + if $NEED_INSTALL; then + rm -rf $SYS_VIRENV_PATH && virtualenv $SYS_VIRENV_PATH --python=python2.7 || exit 1 + . $SYS_VIRENV_PATH/bin/activate + cd $cwd + TMPDIR=/usr/local/zstack/ pip install -i $pypi_path --trusted-host localhost --ignore-installed setuptools==39.2.0 || exit 1 + TMPDIR=/usr/local/zstack/ pip install -i $pypi_path --trusted-host localhost --ignore-installed ansible==4.10.0 || exit 1 + + cat > /usr/bin/ansible << EOF +#! /bin/sh +VIRTUAL_ENV=/var/lib/zstack/virtualenv/zstacksys +if [ ! -d $VIRTUAL_ENV ]; then + echo "Need to install zstacksys before using it" + exit 1 +fi + +LANG=en_US.UTF-8 +LC_ALL=en_US.utf8 +export LANG LC_ALL +. ${VIRTUAL_ENV}/bin/activate + +ansible \$@ +EOF + chmod +x /usr/bin/ansible + + cat > /usr/bin/ansible-playbook << EOF +#! /bin/sh +VIRTUAL_ENV=/var/lib/zstack/virtualenv/zstacksys +if [ ! -d $VIRTUAL_ENV ]; then + echo "Need to install zstacksys before using it" + exit 1 +fi + +LANG=en_US.UTF-8 +LC_ALL=en_US.utf8 +export LANG LC_ALL +. ${VIRTUAL_ENV}/bin/activate + +ansible-playbook \$@ +EOF + chmod +x /usr/bin/ansible-playbook + fi + elif [ $tool = 'zstack-dashboard' ]; then UI_VIRENV_PATH=/var/lib/zstack/virtualenv/zstack-dashboard [ ! -z $force ] && rm -rf $UI_VIRENV_PATH if [ ! -d "$UI_VIRENV_PATH" ]; then - virtualenv $UI_VIRENV_PATH + virtualenv $UI_VIRENV_PATH --python=python2.7 if [ $? -ne 0 ]; then rm -rf $UI_VIRENV_PATH exit 1 diff --git a/conf/zstack.xml b/conf/zstack.xml index 743b680d36b..ed752bf46ba 100755 --- a/conf/zstack.xml +++ b/conf/zstack.xml @@ -42,9 +42,18 @@ + + + + + + + + + @@ -57,6 +66,7 @@ + @@ -101,4 +111,13 @@ + + + + + + + + + diff --git a/configuration/pom.xml b/configuration/pom.xml index 5b29289499f..8ce34186f80 100755 --- a/configuration/pom.xml +++ b/configuration/pom.xml @@ -3,7 +3,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. configuration @@ -39,14 +39,10 @@ ${project.version} - - org.reflections - reflections - commons-codec commons-codec - 1.9 + 1.15 diff --git a/configuration/src/main/java/org/zstack/configuration/BusinessProperties.java b/configuration/src/main/java/org/zstack/configuration/BusinessProperties.java index b1b97e4cff8..0b9a0b1bf2b 100644 --- a/configuration/src/main/java/org/zstack/configuration/BusinessProperties.java +++ b/configuration/src/main/java/org/zstack/configuration/BusinessProperties.java @@ -5,7 +5,9 @@ import org.zstack.utils.logging.CLogger; import org.zstack.utils.path.PathUtil; -import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -19,9 +21,9 @@ public class BusinessProperties { private static Properties prop = new Properties(); private static void loadBusinessProperties(String filename) { - try { + try (InputStream inputStream = Files.newInputStream(Paths.get(filename))) { logger.debug(String.format("start load business properties: %s", filename)); - prop.load(new FileInputStream(filename)); + prop.load(inputStream); } catch (Exception e) { logger.debug(e.getMessage()); throw new CloudRuntimeException(e.getMessage()); diff --git a/configuration/src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java b/configuration/src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java index 75af029aa36..dda0df86524 100755 --- a/configuration/src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java +++ b/configuration/src/main/java/org/zstack/configuration/ConfigurationApiInterceptor.java @@ -79,6 +79,10 @@ private void validate(APICreateInstanceOfferingMsg msg) { if (msg.getMemorySize() < SizeUnit.MEGABYTE.toByte(16)) { throw new ApiMessageInterceptionException(argerr("memory size[%s bytes] is less than 16M, no modern operating system is likely able to boot with such small memory size", msg.getMemorySize())); } + + if (msg.getReservedMemorySize() > msg.getMemorySize()) { + throw new ApiMessageInterceptionException(argerr("reserved memory size[%s bytes] is greater than memory size[%s bytes]", msg.getReservedMemorySize(), msg.getMemorySize())); + } } private void validate(APIUpdateInstanceOfferingMsg msg) { diff --git a/configuration/src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java b/configuration/src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java index d833dd03784..525bf33229d 100755 --- a/configuration/src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java +++ b/configuration/src/main/java/org/zstack/configuration/ConfigurationManagerImpl.java @@ -875,6 +875,7 @@ public void generateApiJsonTemplate(String exportPath, List basePkgs) th // write inventory.py { StringBuilder pysb = new StringBuilder(); + pysb.append("#-*-coding: UTF-8 -*-\n"); pysb.append("from zstacklib.utils import log"); generateMandoryFieldClass(pysb); generateApiMessagePythonClass(pysb, basePkgs); @@ -919,6 +920,7 @@ private void handle(APICreateInstanceOfferingMsg msg) { vo.setDescription(msg.getDescription()); vo.setState(InstanceOfferingState.Enabled); vo.setMemorySize(msg.getMemorySize()); + vo.setReservedMemorySize(msg.getReservedMemorySize()); vo.setDuration(InstanceOfferingDuration.Permanent); vo.setType(type); diff --git a/configuration/src/main/java/org/zstack/configuration/TestLinkDocumentGenerator.java b/configuration/src/main/java/org/zstack/configuration/TestLinkDocumentGenerator.java index 0961c372e36..74549d8dc4b 100755 --- a/configuration/src/main/java/org/zstack/configuration/TestLinkDocumentGenerator.java +++ b/configuration/src/main/java/org/zstack/configuration/TestLinkDocumentGenerator.java @@ -124,10 +124,11 @@ private static void requirmentSpecFromXml(String outputDir, String filePath) thr ret.setReqSpec(rspec); File retFile = new File(PathUtil.join(outputDir, String.format("reqSpec-%s", tfile.getName()))); - retFile.createNewFile(); - Marshaller marshaller = context.createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - marshaller.marshal(ret, retFile); + if (retFile.createNewFile()) { + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + marshaller.marshal(ret, retFile); + } } public static void generateRequirementSpec(String outputDir) { diff --git a/console/pom.xml b/console/pom.xml index ca0972da831..47806cb4219 100755 --- a/console/pom.xml +++ b/console/pom.xml @@ -5,7 +5,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/console/src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java b/console/src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java index 7ac8812b071..fc1c3e72377 100755 --- a/console/src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java +++ b/console/src/main/java/org/zstack/console/AbstractConsoleProxyBackend.java @@ -7,19 +7,32 @@ import org.zstack.core.ansible.AnsibleFacade; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.thread.AsyncThread; +import org.zstack.core.timeout.Timer; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.Component; -import org.zstack.header.console.*; +import org.zstack.header.console.ConsoleBackend; +import org.zstack.header.console.ConsoleConstants; +import org.zstack.header.console.ConsoleInventory; +import org.zstack.header.console.ConsoleProxy; +import org.zstack.header.console.ConsoleProxyInventory; +import org.zstack.header.console.ConsoleProxyStatus; +import org.zstack.header.console.ConsoleProxyVO; +import org.zstack.header.console.ConsoleProxyVO_; import org.zstack.header.core.AsyncLatch; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.ReturnValueCompletion; -import org.zstack.header.core.workflow.*; +import org.zstack.header.core.workflow.FlowChain; +import org.zstack.header.core.workflow.FlowDoneHandler; +import org.zstack.header.core.workflow.FlowErrorHandler; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.identity.SessionInventory; @@ -33,6 +46,7 @@ import javax.persistence.TypedQuery; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import static org.zstack.core.Platform.operr; @@ -55,6 +69,8 @@ public abstract class AbstractConsoleProxyBackend implements ConsoleBackend, Com protected AnsibleFacade asf; @Autowired protected ErrorFacade errf; + @Autowired + protected Timer timer; protected static final String ANSIBLE_PLAYBOOK_NAME = "consoleproxy.py"; @@ -62,12 +78,14 @@ public abstract class AbstractConsoleProxyBackend implements ConsoleBackend, Com protected abstract ConsoleProxy getConsoleProxy(SessionInventory session, VmInstanceInventory vm); + protected abstract ConsoleProxy getConsoleProxy(ConsoleProxyInventory proxy); + protected abstract void connectAgent(); protected abstract boolean isAgentConnected(); - private void establishNewProxy(ConsoleProxy proxy, SessionInventory session, final VmInstanceInventory vm, final ReturnValueCompletion complete) { - proxy.establishProxy(session, vm, new ReturnValueCompletion(complete) { + private void establishNewProxy(ConsoleProxy proxy, final VmInstanceInventory vm, final ReturnValueCompletion complete) { + proxy.establishProxy(vm, new ReturnValueCompletion(complete) { @Override public void success(ConsoleProxyInventory ret) { ConsoleProxyVO vo = new ConsoleProxyVO(); @@ -84,8 +102,8 @@ public void success(ConsoleProxyInventory ret) { vo.setUuid(Platform.getUuid()); vo.setAgentType(ret.getAgentType()); vo.setStatus(ConsoleProxyStatus.Active); - vo.setToken(ret.getToken()); vo.setVersion(ret.getVersion()); + vo.setExpiredDate(ret.getExpiredDate()); vo = dbf.persistAndRefresh(vo); complete.success(ConsoleInventory.valueOf(vo)); @@ -115,10 +133,16 @@ public void grantConsoleAccess(final SessionInventory session, final VmInstanceI if (vo == null) { // new console proxy ConsoleProxy proxy = getConsoleProxy(session, vm); - establishNewProxy(proxy, session, vm, complete); + establishNewProxy(proxy, vm, complete); return; } + if (timer.getCurrentTimestamp().after(vo.getExpiredDate())) { + dbf.remove(vo); + ConsoleProxy proxy = getConsoleProxy(session, vm); + establishNewProxy(proxy, vm, complete); + return; + } String hostIp = getHostIp(vm); if (hostIp == null) { @@ -127,9 +151,7 @@ public void grantConsoleAccess(final SessionInventory session, final VmInstanceI if (vo.getTargetHostname().equals(hostIp)) { // vm is on the same host - final ConsoleProxy proxy = getConsoleProxy(vm, vo); - dbf.remove(vo); - establishNewProxy(proxy, session, vm, complete); + updateConsoleProxy(vm, vo, complete); } else { // vm is on another host FlowChain chain = FlowChainBuilder.newShareFlowChain(); @@ -164,7 +186,7 @@ public void fail(ErrorCode errorCode) { @Override public void run(final FlowTrigger trigger, Map data) { ConsoleProxy proxy = getConsoleProxy(session, vm); - establishNewProxy(proxy, session, vm, new ReturnValueCompletion(trigger) { + establishNewProxy(proxy, vm, new ReturnValueCompletion(trigger) { @Override public void success(ConsoleInventory returnValue) { ret = returnValue; @@ -269,6 +291,15 @@ public void deleteConsoleSession(final VmInstanceInventory vm, final Completion q.add(ConsoleProxyVO_.status, SimpleQuery.Op.EQ, ConsoleProxyStatus.Active); final ConsoleProxyVO vo = q.find(); if (vo != null) { + // wss do not request console proxy because it connect to vm's host directly + // so skip deleteProxy + // TODO: use ConsoleUrl returned needConsoleProxy as vo attribute for checking instead of schema + if (ConsoleConstants.WSS_SCHEMA.equals(vo.getScheme())) { + dbf.remove(vo); + completion.success(); + return; + } + ConsoleProxy proxy = getConsoleProxy(vm, vo); proxy.deleteProxy(vm, new Completion(completion) { @Override @@ -281,6 +312,11 @@ public void success() { @Override public void fail(ErrorCode errorCode) { + DeleteConsoleProxyGcJob gc = new DeleteConsoleProxyGcJob(); + gc.NAME = String.format("delete-console-proxy-%s", vo.getUuid()); + gc.consoleProxy = ConsoleProxyInventory.valueOf(vo); + gc.submit(ConsoleGlobalConfig.DELETE_CONSOLE_PROXY_RETRY_DELAY.value(Long.class), TimeUnit.SECONDS); + dbf.remove(vo); completion.fail(errorCode); } }); @@ -289,6 +325,61 @@ public void fail(ErrorCode errorCode) { } } + @Override + public void deactivateConsoleProxy(final VmInstanceInventory vm, final Completion completion) { + final ConsoleProxyVO vo = Q.New(ConsoleProxyVO.class).eq(ConsoleProxyVO_.vmInstanceUuid, vm.getUuid()) + .eq(ConsoleProxyVO_.status, ConsoleProxyStatus.Active).find(); + if (vo == null) { + logger.debug(String.format("this is no console proxy for vm [uuid:%s, name: %s]", + vm.getUuid(), vm.getName())); + completion.success(); + return; + } + + ConsoleProxy proxy = getConsoleProxy(vm, vo); + proxy.deleteProxy(vm, new Completion(completion) { + @Override + public void success() { + vo.setStatus(ConsoleProxyStatus.Inactive); + dbf.updateAndRefresh(vo); + logger.debug(String.format("deactivate a console proxy[vmUuid:%s, host IP: %s, host port: %s, proxy IP: %s, proxy port: %s", + vm.getUuid(), vo.getTargetHostname(), vo.getTargetPort(), vo.getProxyHostname(), vo.getProxyPort())); + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + DeleteConsoleProxyGcJob gc = new DeleteConsoleProxyGcJob(); + gc.NAME = String.format("deactivate-console-proxy-%s", vo.getUuid()); + gc.consoleProxy = ConsoleProxyInventory.valueOf(vo); + gc.submit(ConsoleGlobalConfig.DELETE_CONSOLE_PROXY_RETRY_DELAY.value(Long.class), TimeUnit.SECONDS); + completion.fail(errorCode); + } + }); + } + + @Override + public void updateConsoleProxy(VmInstanceInventory vm, ConsoleProxyVO vo, ReturnValueCompletion completion) { + ConsoleProxy proxy = getConsoleProxy(vm, vo); + proxy.establishProxy(vm, new ReturnValueCompletion(completion) { + @Override + public void success(ConsoleProxyInventory ret) { + vo.setTargetHostname(ret.getTargetHostname()); + vo.setTargetPort(ret.getTargetPort()); + vo.setStatus(ConsoleProxyStatus.Active); + vo.setExpiredDate(ret.getExpiredDate()); + vo.setProxyPort(ret.getProxyPort()); + dbf.updateAndRefresh(vo); + + completion.success(ConsoleInventory.valueOf(vo)); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } private void deploySaltState() { if (CoreGlobalProperty.UNIT_TEST_ON) { @@ -312,10 +403,6 @@ public boolean stop() { @Override @AsyncThread public void managementNodeReady() { - if (CoreGlobalProperty.UNIT_TEST_ON) { - return; - } - connectAgent(); } } diff --git a/console/src/main/java/org/zstack/console/ConsoleApiInterceptor.java b/console/src/main/java/org/zstack/console/ConsoleApiInterceptor.java index 5c1430412b5..8a62df54981 100755 --- a/console/src/main/java/org/zstack/console/ConsoleApiInterceptor.java +++ b/console/src/main/java/org/zstack/console/ConsoleApiInterceptor.java @@ -15,6 +15,9 @@ import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; +import java.util.Arrays; +import java.util.List; + import static org.zstack.core.Platform.operr; /** @@ -40,13 +43,22 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti return msg; } + private List consoleAvailableStates = Arrays.asList( + VmInstanceState.Running, + VmInstanceState.Crashed, + VmInstanceState.VolumeRecovering, + VmInstanceState.Paused, + VmInstanceState.NoState + ); + private void validate(APIRequestConsoleAccessMsg msg) { SimpleQuery q = dbf.createQuery(VmInstanceVO.class); q.select(VmInstanceVO_.state); q.add(VmInstanceVO_.uuid, Op.EQ, msg.getVmInstanceUuid()); VmInstanceState state = q.findValue(); - if (VmInstanceState.Running != state && VmInstanceState.Crashed != state && VmInstanceState.VolumeRecovering != state) { - throw new ApiMessageInterceptionException(operr("Console is only available when the VM[uuid:%s] is Running or Crashed, but the current state is %s", msg.getVmInstanceUuid(), state)); + if (!consoleAvailableStates.contains(state)) { + throw new ApiMessageInterceptionException(operr("vm[uuid:%s] is not in state of %s, current state is %s", + msg.getVmInstanceUuid(), consoleAvailableStates, state)); } bus.makeTargetServiceIdByResourceUuid(msg, ConsoleConstants.SERVICE_ID, msg.getVmInstanceUuid()); } diff --git a/console/src/main/java/org/zstack/console/ConsoleGlobalConfig.java b/console/src/main/java/org/zstack/console/ConsoleGlobalConfig.java index 106ca9d5a8e..0030c513e7f 100755 --- a/console/src/main/java/org/zstack/console/ConsoleGlobalConfig.java +++ b/console/src/main/java/org/zstack/console/ConsoleGlobalConfig.java @@ -10,6 +10,9 @@ public class ConsoleGlobalConfig { public static final String CATEGORY = "console"; + @GlobalConfigValidation(validValues = {"NONE", "TLSV1_1", "TLSV1_2"}) + public static GlobalConfig PROXY_TLS_VERSION = new GlobalConfig(CATEGORY, "proxy.tls.version"); + @GlobalConfigValidation(numberGreaterThan = 0) public static GlobalConfig PROXY_IDLE_TIMEOUT = new GlobalConfig(CATEGORY, "proxy.idleTimeout"); @@ -21,4 +24,7 @@ public class ConsoleGlobalConfig { @GlobalConfigValidation public static GlobalConfig VNC_ALLOW_PORTS_LIST = new GlobalConfig(CATEGORY, "vnc.allow.ports"); + + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig DELETE_CONSOLE_PROXY_RETRY_DELAY = new GlobalConfig(CATEGORY, "delete.consoleproxy.gc.delay"); } diff --git a/console/src/main/java/org/zstack/console/ConsoleGlobalProperty.java b/console/src/main/java/org/zstack/console/ConsoleGlobalProperty.java index 537ce70edf3..418f30ba433 100644 --- a/console/src/main/java/org/zstack/console/ConsoleGlobalProperty.java +++ b/console/src/main/java/org/zstack/console/ConsoleGlobalProperty.java @@ -9,7 +9,7 @@ */ @GlobalPropertyDefinition public class ConsoleGlobalProperty { - @GlobalProperty(name="ConsoleProxy.agentPackageName", defaultValue = "consoleproxy-4.4.0.tar.gz") + @GlobalProperty(name="ConsoleProxy.agentPackageName", defaultValue = "consoleproxy-5.4.0.tar.gz") public static String AGENT_PACKAGE_NAME; @GlobalProperty(name="MN.network.", defaultValue = "") public static List MN_NETWORKS; diff --git a/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java b/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java index a90ed850b43..ce65fc78a39 100755 --- a/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java +++ b/console/src/main/java/org/zstack/console/ConsoleManagerImpl.java @@ -8,9 +8,11 @@ import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.timeout.Timer; import org.zstack.header.AbstractService; import org.zstack.header.console.*; import org.zstack.header.core.Completion; @@ -18,7 +20,6 @@ import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HypervisorType; import org.zstack.header.identity.SessionInventory; @@ -28,7 +29,6 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.vm.*; -import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -36,8 +36,6 @@ import java.util.HashMap; import java.util.Map; -import static org.zstack.core.Platform.operr; - /** * Created with IntelliJ IDEA. * User: frank @@ -45,7 +43,7 @@ * To change this template use File | Settings | File Templates. */ public class ConsoleManagerImpl extends AbstractService implements ConsoleManager, VmInstanceMigrateExtensionPoint, ManagementNodeChangeListener, - VmReleaseResourceExtensionPoint, SessionLogoutExtensionPoint { + VmReleaseResourceExtensionPoint, SessionLogoutExtensionPoint, PostVmInstantiateResourceExtensionPoint { private static CLogger logger = Utils.getLogger(ConsoleManagerImpl.class); @Autowired @@ -56,6 +54,8 @@ public class ConsoleManagerImpl extends AbstractService implements ConsoleManage private PluginRegistry pluginRgty; @Autowired private ThreadFacade thdf; + @Autowired + private Timer timer; private Map consoleBackends = new HashMap(); private Map consoleHypervisorBackends = new HashMap(); @@ -212,13 +212,8 @@ public ConsoleBackend getConsoleBackend() { return getBackend(); } - @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } - @Override public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } @Override @@ -232,6 +227,7 @@ public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { } } catch (InterruptedException e) { logger.warn(e.getMessage(), e); + Thread.currentThread().interrupt(); } } @@ -243,19 +239,32 @@ public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, Erro @Override public void releaseVmResource(VmInstanceSpec spec, final Completion completion) { ConsoleBackend bkd = getBackend(); - bkd.deleteConsoleSession(spec.getVmInventory(), new Completion(completion) { - @Override - public void success() { - completion.success(); - } + if (spec.getCurrentVmOperation() == VmInstanceConstant.VmOperation.Reboot) { + bkd.deactivateConsoleProxy(spec.getVmInventory(), new Completion(completion) { - @Override - public void fail(ErrorCode errorCode) { - //TODO - logger.warn(errorCode.toString()); - completion.success(); - } - }); + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.success(); + } + }); + } else { + bkd.deleteConsoleSession(spec.getVmInventory(), new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.success(); + } + }); + } } @Override @@ -299,4 +308,53 @@ public void nodeJoin(ManagementNodeInventory inv) { @Override public void iJoin(ManagementNodeInventory inv) { } + + @Override + public void postBeforeInstantiateVmResource(VmInstanceSpec spec) { + + } + + @Override + public void postInstantiateVmResource(VmInstanceSpec spec, Completion completion) { + if (spec.getCurrentVmOperation() != VmInstanceConstant.VmOperation.Reboot) { + completion.success(); + return; + } + + VmInstanceInventory vm = spec.getVmInventory(); + ConsoleProxyVO vo = Q.New(ConsoleProxyVO.class) + .eq(ConsoleProxyVO_.vmInstanceUuid, vm.getUuid()) + .find(); + if (vo == null) { + completion.success(); + return; + } + + if (timer.getCurrentTimestamp().after(vo.getExpiredDate())) { + // token is stale + dbf.remove(vo); + completion.success(); + return; + } + + ConsoleBackend bkd = getBackend(); + bkd.updateConsoleProxy(vm, vo, new ReturnValueCompletion(completion) { + @Override + public void success(ConsoleInventory inv) { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + dbf.remove(vo); + logger.warn(String.format("fail to update console proxy, because: ", errorCode.toString())); + completion.success(); + } + }); + } + + @Override + public void postReleaseVmResource(VmInstanceSpec spec, Completion completion) { + completion.success(); + } } diff --git a/console/src/main/java/org/zstack/console/ConsoleProxyAgentTracker.java b/console/src/main/java/org/zstack/console/ConsoleProxyAgentTracker.java index 36b20f540d4..a7b989662a5 100755 --- a/console/src/main/java/org/zstack/console/ConsoleProxyAgentTracker.java +++ b/console/src/main/java/org/zstack/console/ConsoleProxyAgentTracker.java @@ -4,7 +4,7 @@ import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.config.GlobalConfig; import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; -import org.zstack.core.tacker.PingTracker; +import org.zstack.core.tracker.PingTracker; import org.zstack.header.console.ConsoleBackend; import org.zstack.header.console.PingConsoleProxyAgentMsg; import org.zstack.header.console.PingConsoleProxyAgentReply; diff --git a/console/src/main/java/org/zstack/console/ConsoleProxyBase.java b/console/src/main/java/org/zstack/console/ConsoleProxyBase.java index 98c70cffd18..4af9bbacbdb 100755 --- a/console/src/main/java/org/zstack/console/ConsoleProxyBase.java +++ b/console/src/main/java/org/zstack/console/ConsoleProxyBase.java @@ -5,15 +5,14 @@ import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.timeout.Timer; import org.zstack.header.console.*; import org.zstack.header.console.ConsoleProxyCommands.DeleteProxyCmd; import org.zstack.header.console.ConsoleProxyCommands.DeleteProxyRsp; import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HypervisorType; -import org.zstack.header.identity.SessionInventory; import org.zstack.header.rest.JsonAsyncRESTCallback; import org.zstack.header.rest.RESTFacade; import org.zstack.header.vm.VmInstanceInventory; @@ -22,6 +21,7 @@ import org.zstack.utils.logging.CLogger; import java.net.URI; +import java.sql.Timestamp; import static org.zstack.core.Platform.operr; @@ -42,6 +42,8 @@ public class ConsoleProxyBase implements ConsoleProxy { private ConsoleManager consoleMgr; @Autowired private ErrorFacade errf; + @Autowired + private Timer timer; private final int agentPort; @@ -68,7 +70,8 @@ private void doEstablishConsoleProxyConnection(ConsoleUrl consoleUrl, final Retu } int idleTimeout = ConsoleGlobalConfig.PROXY_IDLE_TIMEOUT.value(Integer.class); - int tokenTimeout = ConsoleGlobalConfig.VNC_TOKEN_TIMEOUT.value(Integer.class); + long tokenTimeout = ConsoleGlobalConfig.VNC_TOKEN_TIMEOUT.value(Long.class); + long expiredDate = timer.getCurrentTimeMillis() + tokenTimeout * 1000; ConsoleProxyCommands.EstablishProxyCmd cmd = new ConsoleProxyCommands.EstablishProxyCmd(); cmd.setVmUuid(self.getVmInstanceUuid()); @@ -76,7 +79,7 @@ private void doEstablishConsoleProxyConnection(ConsoleUrl consoleUrl, final Retu cmd.setTargetHostname(targetHostname); cmd.setTargetPort(targetPort); cmd.setProxyHostname("0.0.0.0"); - if (targetSchema.equals(ConsoleConstants.HTTP_SCHEMA)) { + if (ConsoleConstants.HTTP_SCHEMA.equals(targetSchema)) { cmd.setProxyPort(CoreGlobalProperty.HTTP_CONSOLE_PROXY_PORT); } else { cmd.setProxyPort(CoreGlobalProperty.CONSOLE_PROXY_PORT); @@ -85,7 +88,12 @@ private void doEstablishConsoleProxyConnection(ConsoleUrl consoleUrl, final Retu cmd.setScheme(self.getScheme()); cmd.setToken(self.getToken()); cmd.setIdleTimeout(idleTimeout); - cmd.setVncTokenTimeout(tokenTimeout); + cmd.setExpiredDate(expiredDate); + + ConsoleProxyTlsVersion tlsVersion = ConsoleProxyTlsVersion.valueOf(ConsoleGlobalConfig.PROXY_TLS_VERSION.value()); + if (tlsVersion != ConsoleProxyTlsVersion.NONE) { + cmd.setTlsVersion(tlsVersion.toCommandParameter()); + } String agentUrl = URLBuilder.buildHttpUrl(self.getAgentIp(), agentPort, ConsoleConstants.CONSOLE_PROXY_ESTABLISH_PROXY_PATH); restf.asyncJsonPost(agentUrl, cmd, new JsonAsyncRESTCallback(completion) { @@ -101,8 +109,8 @@ public void success(ConsoleProxyCommands.EstablishProxyRsp ret) { self.setTargetHostname(targetHostname); self.setTargetPort(targetPort); self.setProxyPort(ret.getProxyPort()); - self.setToken(ret.getToken()); self.setVersion(consoleUrl.getVersion()); + self.setExpiredDate(new Timestamp(expiredDate)); completion.success(self); } else { completion.fail(operr("operation error, because:%s", ret.getError())); @@ -150,7 +158,7 @@ private void doEstablish(ConsoleUrl consoleUrl, final ReturnValueCompletion completion) { + public void establishProxy(final VmInstanceInventory vm, final ReturnValueCompletion completion) { ConsoleHypervisorBackend bkd = consoleMgr.getHypervisorConsoleBackend(HypervisorType.valueOf(vm.getHypervisorType())); bkd.generateConsoleUrl(vm, new ReturnValueCompletion(completion) { @@ -204,6 +212,10 @@ public Class getReturnClass() { @Override public void deleteProxy(VmInstanceInventory vm, final Completion completion) { + deleteProxy(vm.getUuid(), completion); + } + + private void deleteProxy(String vmInstanceUuid, Completion completion) { DeleteProxyCmd cmd = new DeleteProxyCmd(); cmd.setProxyHostname(self.getProxyHostname()); cmd.setProxyPort(self.getProxyPort()); @@ -211,7 +223,7 @@ public void deleteProxy(VmInstanceInventory vm, final Completion completion) { cmd.setTargetHostname(self.getTargetHostname()); cmd.setTargetPort(self.getTargetPort()); cmd.setToken(self.getToken()); - cmd.setVmUuid(vm.getUuid()); + cmd.setVmUuid(vmInstanceUuid); restf.asyncJsonPost(URLBuilder.buildHttpUrl(self.getAgentIp(), agentPort, ConsoleConstants.CONSOLE_PROXY_DELETE_PROXY_PATH), cmd, new JsonAsyncRESTCallback(completion) { @@ -235,4 +247,9 @@ public Class getReturnClass() { } }); } + + @Override + public void deleteProxy(ConsoleProxyInventory proxy, Completion completion) { + deleteProxy(proxy.getVmInstanceUuid(), completion); + } } diff --git a/console/src/main/java/org/zstack/console/ConsoleProxyDeployArguments.java b/console/src/main/java/org/zstack/console/ConsoleProxyDeployArguments.java new file mode 100644 index 00000000000..18d0baa04d2 --- /dev/null +++ b/console/src/main/java/org/zstack/console/ConsoleProxyDeployArguments.java @@ -0,0 +1,24 @@ +package org.zstack.console; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; + +public class ConsoleProxyDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_consoleproxy") + private final String packageName = ConsoleGlobalProperty.AGENT_PACKAGE_NAME; + @SerializedName("http_console_proxy_port") + private String httpConsoleProxyPort; + + @Override + public String getPackageName() { + return packageName; + } + + public String getHttpConsoleProxyPort() { + return httpConsoleProxyPort; + } + + public void setHttpConsoleProxyPort(String httpConsoleProxyPort) { + this.httpConsoleProxyPort = httpConsoleProxyPort; + } +} diff --git a/console/src/main/java/org/zstack/console/ConsoleProxyTlsVersion.java b/console/src/main/java/org/zstack/console/ConsoleProxyTlsVersion.java new file mode 100644 index 00000000000..f631707a5c1 --- /dev/null +++ b/console/src/main/java/org/zstack/console/ConsoleProxyTlsVersion.java @@ -0,0 +1,17 @@ +package org.zstack.console; + +public enum ConsoleProxyTlsVersion { + NONE("default"), + TLSV1_1("tlsv1_1"), + TLSV1_2("tlsv1_2"); + + public final String tlsVersion; + + ConsoleProxyTlsVersion(String tlsVersion) { + this.tlsVersion = tlsVersion; + } + + public String toCommandParameter() { + return tlsVersion; + } +} diff --git a/console/src/main/java/org/zstack/console/DeleteConsoleProxyGcJob.java b/console/src/main/java/org/zstack/console/DeleteConsoleProxyGcJob.java new file mode 100644 index 00000000000..5b747aa0c74 --- /dev/null +++ b/console/src/main/java/org/zstack/console/DeleteConsoleProxyGcJob.java @@ -0,0 +1,74 @@ +package org.zstack.console; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.db.Q; +import org.zstack.core.gc.GC; +import org.zstack.core.gc.GCCompletion; +import org.zstack.core.gc.TimeBasedGarbageCollector; +import org.zstack.header.console.ConsoleBackend; +import org.zstack.header.console.ConsoleProxyAgentStatus; +import org.zstack.header.console.ConsoleProxyAgentVO; +import org.zstack.header.console.ConsoleProxyAgentVO_; +import org.zstack.header.console.ConsoleProxyInventory; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import static org.zstack.core.Platform.operr; + +public class DeleteConsoleProxyGcJob extends TimeBasedGarbageCollector { + private static final CLogger logger = Utils.getLogger(DeleteConsoleProxyGcJob.class); + + @GC + public ConsoleProxyInventory consoleProxy; + + @Autowired + private ConsoleManager consoleMgr; + + @Override + protected void triggerNow(GCCompletion completion) { + ConsoleBackend backend = consoleMgr.getConsoleBackend(); + if (backend == null) { + // no available backend, cancel the gc job + completion.cancel(); + return; + } + + ConsoleProxyAgentStatus status = Q.New(ConsoleProxyAgentVO.class) + .select(ConsoleProxyAgentVO_.status) + .eq(ConsoleProxyAgentVO_.consoleProxyOverriddenIp, consoleProxy.getAgentIp()) + .findValue(); + if (status == null) { + logger.debug(String.format("console proxy not found on agent[ip: %s, uuid: %s]," + + " assume it has been deleted", + consoleProxy.getAgentIp(), + consoleProxy.getUuid() + )); + completion.cancel(); + return; + } + + if (status != ConsoleProxyAgentStatus.Connected) { + completion.fail(operr("console proxy[uuid: %s, status: %s] on agent[ip: %s]" + + " is not Connected, fail to delete it", + consoleProxy.getUuid(), + status, + consoleProxy.getAgentIp()) + ); + return; + } + + backend.deleteConsoleSession(consoleProxy, new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } +} diff --git a/console/src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java b/console/src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java index 0b068ac8ca5..5a84fbca1ea 100755 --- a/console/src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java +++ b/console/src/main/java/org/zstack/console/ManagementServerConsoleProxyBackend.java @@ -107,6 +107,11 @@ protected ConsoleProxy getConsoleProxy(SessionInventory session, VmInstanceInven return new ConsoleProxyBase(inv, getAgentPort()); } + @Override + protected ConsoleProxy getConsoleProxy(ConsoleProxyInventory proxy) { + return new ConsoleProxyBase(proxy, getAgentPort()); + } + private void setupPublicKey() { File pubKeyFile = PathUtil.findFileOnClassPath(AnsibleConstant.RSA_PUBLIC_KEY); String script = PathUtil.findFileOnClassPath(AnsibleConstant.IMPORT_PUBLIC_KEY_SCRIPT_PATH, true).getAbsolutePath(); @@ -153,6 +158,17 @@ public void run() { } }); + if (CoreGlobalProperty.UNIT_TEST_ON) { + finalVo.setStatus(ConsoleProxyAgentStatus.Connected); + dbf.update(finalVo); + + connected = true; + logger.debug("successfully deploy console proxy agent by ansible"); + completion.success(); + chain.next(); + return; + } + try { ShellUtils.run("rm -rf /var/lib/zstack/consoleProxy/ && mkdir -p /var/lib/zstack/consoleProxy/"); StringBuilder builder = new StringBuilder(); @@ -213,16 +229,10 @@ public void run() { runner.setTargetUuid(Platform.getManagementServerId()); runner.setPlayBookName(ANSIBLE_PLAYBOOK_NAME); runner.setFullDeploy(fullDeploy); - runner.putArgument("pkg_consoleproxy", agentPackageName); - runner.putArgument("http_console_proxy_port", CoreGlobalProperty.HTTP_CONSOLE_PROXY_PORT); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - completion.fail(operr("chrony server not configured!")); - chain.next(); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } + + ConsoleProxyDeployArguments deployArguments = new ConsoleProxyDeployArguments(); + deployArguments.setHttpConsoleProxyPort(String.valueOf(CoreGlobalProperty.HTTP_CONSOLE_PROXY_PORT)); + runner.setDeployArguments(deployArguments); runner.run(new ReturnValueCompletion(completion, chain) { @Override public void success(Boolean deployed) { @@ -274,6 +284,12 @@ public String getConsoleBackendType() { return ConsoleConstants.MANAGEMENT_SERVER_CONSOLE_PROXY_BACKEND; } + @Override + public void deleteConsoleSession(ConsoleProxyInventory consoleProxy, Completion completion) { + ConsoleProxy proxy = getConsoleProxy(consoleProxy); + proxy.deleteProxy(consoleProxy, completion); + } + @Override public String returnServiceIdForConsoleAgentMsg(ConsoleProxyAgentMessage msg, String agentUuid) { return bus.makeServiceIdByManagementNodeId(ConsoleConstants.SERVICE_ID, Platform.getManagementServerId()); @@ -442,14 +458,13 @@ private void handle(APIUpdateConsoleProxyAgentMsg msg) { umsg.setConsoleProxyOverriddenIp(msg.getConsoleProxyOverriddenIp()); umsg.setConsoleProxyPort(msg.getConsoleProxyPort()); bus.makeServiceIdByManagementNodeId(umsg, ConsoleConstants.SERVICE_ID, msg.getUuid()); - bus.send(umsg, new CloudBusCallBack(evt) { + bus.send(umsg, new CloudBusCallBack(msg) { @Override public void run(MessageReply reply) { if (reply.isSuccess()) { bus.publish(evt); } else { - UpdateConsoleProxyAgentReply rly = reply.castReply(); - evt.setError(rly.getError()); + evt.setError(reply.getError()); bus.publish(evt); } } @@ -465,11 +480,40 @@ private void handle(UpdateConsoleProxyAgentMsg msg) { ConsoleProxyAgentVO vo; String oldProxyIp; int oldProxyPort; - int newProxyPort = msg.getConsoleProxyPort() == 0 ? CoreGlobalProperty.CONSOLE_PROXY_PORT : msg.getConsoleProxyPort(); + int newProxyPort = msg.getConsoleProxyPort() == null ? CoreGlobalProperty.CONSOLE_PROXY_PORT : msg.getConsoleProxyPort(); @Override public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "verify-console-proxy-port"; + @Override + public void run(FlowTrigger trigger, Map data) { + if (msg.getConsoleProxyPort() == null) { + trigger.next(); + return; + } + + vo = dbf.findByUuid(msg.getUuid(), ConsoleProxyAgentVO.class); + if ((int)msg.getConsoleProxyPort() == vo.getConsoleProxyPort()) { + trigger.next(); + return; + } + + ShellUtils.ShellRunner runner = new ShellUtils.ShellRunner(); + runner.setCommand(String.format("netstat -nltp | grep -E ':%d\\s+'", msg.getConsoleProxyPort())); + runner.setVerbose(false); + runner.setWithSudo(true); + runner.setSuppressTraceLog(true); + ShellResult res = runner.run(); + String stdout = res.getStdout(); + if (res.getRetCode() == 0) { + trigger.fail(argerr("there is other process using the port: %s", stdout)); + } else { + trigger.next(); + } + } + }); flow(new Flow() { String __name__ = "update-console-proxy-agent-vo"; @Override diff --git a/core/pom.xml b/core/pom.xml index 86fec1a7af3..2f9c5be27f1 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.zstack - 4.4.0 + 5.4.0 .. zstack @@ -24,7 +24,7 @@ org.quartz-scheduler quartz - 2.3.2 + 2.4.0 javax.servlet @@ -48,8 +48,8 @@ cglib - commons-dbcp - commons-dbcp + org.apache.commons + commons-dbcp2 org.aspectj @@ -64,8 +64,8 @@ c3p0 - mysql - mysql-connector-java + com.mysql + mysql-connector-j org.hibernate.javax.persistence @@ -123,18 +123,10 @@ org.springframework spring-webmvc - - org.springframework - spring-web - org.tuckey urlrewritefilter - - org.reflections - reflections - com.fasterxml.uuid java-uuid-generator diff --git a/core/src/main/java/org/zstack/core/CoreGlobalProperty.java b/core/src/main/java/org/zstack/core/CoreGlobalProperty.java index 79e6c8c6fb1..393face30d3 100755 --- a/core/src/main/java/org/zstack/core/CoreGlobalProperty.java +++ b/core/src/main/java/org/zstack/core/CoreGlobalProperty.java @@ -48,15 +48,24 @@ public class CoreGlobalProperty { public static int REST_FACADE_MAX_PER_ROUTE; @GlobalProperty(name = "RESTFacade.maxTotal", defaultValue = "128") public static int REST_FACADE_MAX_TOTAL; + /** + * When set RestServer.maskSensitiveInfo to true, sensitive info will be + * masked see @NoLogging. + * + * Set default value as false to keep back-compatible to avoid breaking users who + * depend on plaintext API result + */ + @GlobalProperty(name="Rest.maskSensitiveInfo", defaultValue = "false") + public static boolean MASK_SENSITIVE_INFO; @GlobalProperty(name = "upgradeStartOn", defaultValue = "false") public static boolean IS_UPGRADE_START; @GlobalProperty(name = "shadowEntityOn", defaultValue = "false") public static boolean SHADOW_ENTITY_ON; - @NumberRange({1024, 49151}) + @NumberRange({1, 65535}) @GlobalProperty(name = "consoleProxyPort", defaultValue = "4900") public static int CONSOLE_PROXY_PORT; // for vnc @GlobalProperty(name = "httpConsoleProxyPort", defaultValue = "4901") - @NumberRange({1024, 49151}) + @NumberRange({1, 65535}) public static int HTTP_CONSOLE_PROXY_PORT; // for terminal @GlobalProperty(name = "consoleProxyCertFile", defaultValue = "") public static String CONSOLE_PROXY_CERT_FILE; @@ -70,6 +79,8 @@ public class CoreGlobalProperty { public static String MN_VIP; @GlobalProperty(name = "simulatorsOn", defaultValue = "false") public static boolean SIMULATORS_ON; + @GlobalProperty(name = "startMode", defaultValue = "") + public static String START_MODE; @GlobalProperty(name = "updatePkgWhenConnect", defaultValue = "true") public static boolean UPDATE_PKG_WHEN_CONNECT; @GlobalProperty(name = "syncNodeTime", defaultValue = "true") @@ -82,4 +93,6 @@ public class CoreGlobalProperty { public static boolean CHAIN_TASK_QOS; @GlobalProperty(name = "rest.api.result.max.length", defaultValue = "64000") public static int REST_API_RESULT_MAX_LENGTH; + @GlobalProperty(name = "pending.queue.minimum.threshold", defaultValue = "50") + public static int PENDING_QUEUE_MINIMUM_THRESHOLD; } diff --git a/core/src/main/java/org/zstack/core/CoreManager.java b/core/src/main/java/org/zstack/core/CoreManager.java new file mode 100644 index 00000000000..b9c0af634d7 --- /dev/null +++ b/core/src/main/java/org/zstack/core/CoreManager.java @@ -0,0 +1,4 @@ +package org.zstack.core; + +public interface CoreManager { +} diff --git a/core/src/main/java/org/zstack/core/CoreManagerImpl.java b/core/src/main/java/org/zstack/core/CoreManagerImpl.java new file mode 100644 index 00000000000..dd8fd8a394d --- /dev/null +++ b/core/src/main/java/org/zstack/core/CoreManagerImpl.java @@ -0,0 +1,161 @@ +package org.zstack.core; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.ResourceDestinationMaker; +import org.zstack.core.singleflight.ExternalSingleFlightMsg; +import org.zstack.core.singleflight.ExternalSingleFlightReply; +import org.zstack.core.singleflight.MultiNodeSingleFlightImpl; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.AbstractService; +import org.zstack.header.core.*; +import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.addon.SingleFlightExecutor; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +public class CoreManagerImpl extends AbstractService implements CoreManager { + private static final CLogger logger = Utils.getLogger(CoreManagerImpl.class); + + @Autowired + private ResourceDestinationMaker destMaker; + @Autowired + private CloudBus bus; + @Autowired + private ThreadFacade thdf; + @Autowired + private MultiNodeSingleFlightImpl singleFlight; + + @Override + public void handleMessage(Message msg) { + if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APIGetChainTaskMsg) { + handleMessage((APIGetChainTaskMsg) msg); + } + } + + private void handleLocalMessage(Message msg) { + if (msg instanceof GetLocalTaskMsg) { + handle((GetLocalTaskMsg) msg); + } else if (msg instanceof ExternalSingleFlightMsg) { + handle((ExternalSingleFlightMsg) msg); + } + } + + private void handle(ExternalSingleFlightMsg msg) { + SingleFlightExecutor executor = MultiNodeSingleFlightImpl.getExecutor(msg.getResourceUuid()); + if (executor == null) { + bus.replyErrorByMessageType(msg, operr("no executor found for resourceUuid[%s]", msg.getResourceUuid())); + return; + } + + Object[] args = Arrays.copyOf(msg.getArgs(), msg.getArgs().length + 1); + args[args.length - 1] = new ReturnValueCompletion(msg) { + @Override + public void success(Object returnValue) { + ExternalSingleFlightReply reply = new ExternalSingleFlightReply(); + reply.setResult(returnValue); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + bus.replyErrorByMessageType(msg, errorCode); + } + }; + singleFlight.run(executor, msg.getMethod(), args); + } + + private void handleMessage(APIGetChainTaskMsg msg) { + APIGetChainTaskReply reply = new APIGetChainTaskReply(); + Function resourceUuidMaker = msg.getResourceUuidMaker(); + Map> mnIds; + if (resourceUuidMaker == null) { + mnIds = destMaker.getAllNodeInfo().stream().collect(Collectors.toMap( + ResourceDestinationMaker.NodeInfo::getNodeUuid, list -> msg.getSyncSignatures())); + } else { + mnIds = msg.getSyncSignatures().stream().collect(Collectors.groupingBy( + syncSignature -> destMaker.makeDestination(resourceUuidMaker.apply(syncSignature)))); + } + + new While<>(mnIds.entrySet()).all((e, compl) -> { + GetLocalTaskMsg gmsg = new GetLocalTaskMsg(); + gmsg.setSyncSignatures(e.getValue()); + bus.makeServiceIdByManagementNodeId(gmsg, CoreConstant.SERVICE_ID, e.getKey()); + bus.send(gmsg, new CloudBusCallBack(compl) { + @Override + public void run(MessageReply r) { + if (r.isSuccess()) { + GetLocalTaskReply gr = r.castReply(); + Map result = gr.getResults(); + if (resourceUuidMaker == null) { + reply.putAllResults(result); + } else { + Map chainInfoMap = result.keySet().stream().collect( + Collectors.toMap(resourceUuidMaker, result::get)); + reply.putAllResults(chainInfoMap); + } + } else { + logger.error("get task fail, because " + r.getError().getDetails()); + } + + compl.done(); + } + }); + }).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + bus.reply(msg, reply); + } + }); + } + + private void handle(GetLocalTaskMsg msg) { + GetLocalTaskReply reply = new GetLocalTaskReply(); + Map results = msg.getSyncSignatures().stream() + .collect(Collectors.toMap(Function.identity(), thdf::getChainTaskInfo)); + if (msg.isOnlyRunningTask()) { + results.values().forEach(c -> c.getPendingTask().clear()); + } + reply.setResults(results); + bus.reply(msg, reply); + } + + @Override + public String getId() { + return bus.makeLocalServiceId(CoreConstant.SERVICE_ID); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/core/src/main/java/org/zstack/core/GlobalProperty.java b/core/src/main/java/org/zstack/core/GlobalProperty.java index 153ef126f46..89774204644 100755 --- a/core/src/main/java/org/zstack/core/GlobalProperty.java +++ b/core/src/main/java/org/zstack/core/GlobalProperty.java @@ -13,6 +13,7 @@ String name(); String defaultValue() default DEFAULT_NULL_STRING; + String[] defaultListValue() default {}; boolean required() default false; boolean encrypted() default false; } diff --git a/core/src/main/java/org/zstack/core/Platform.java b/core/src/main/java/org/zstack/core/Platform.java index 92ea6f7dad5..a8d8ae191ed 100755 --- a/core/src/main/java/org/zstack/core/Platform.java +++ b/core/src/main/java/org/zstack/core/Platform.java @@ -20,6 +20,7 @@ import org.zstack.core.search.SearchGlobalProperty; import org.zstack.core.statemachine.StateMachine; import org.zstack.core.statemachine.StateMachineImpl; +import org.zstack.core.thread.ThreadFacade; import org.zstack.header.Component; import org.zstack.header.core.StaticInit; import org.zstack.header.core.encrypt.ENCRYPT; @@ -33,6 +34,7 @@ import org.zstack.utils.data.StringTemplate; import org.zstack.utils.logging.CLogger; import org.zstack.utils.logging.CLoggerImpl; +import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; import org.zstack.utils.path.PathUtil; import org.zstack.utils.string.ErrorCodeElaboration; @@ -49,9 +51,11 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.net.UnknownHostException; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.TimeUnit; @@ -140,6 +144,10 @@ private static void linkGlobalProperty(Class clz, Map properties valueToSet = ret; } else if (List.class.isAssignableFrom(f.getType())) { List ret = linkGlobalPropertyList(name); + if (ret.isEmpty() && at.defaultListValue().length > 0) { + ret = Arrays.asList(at.defaultListValue()); + } + if (ret.isEmpty() && at.required()) { throw new IllegalArgumentException(String.format("A required global property[%s] missing in zstack.properties", name)); } @@ -661,6 +669,11 @@ public static ComponentLoader createComponentLoaderFromWebApplicationContext(Web ((Component)gcf).start(); } + ThreadFacade thdf = loader.getComponent(ThreadFacade.class); + if (thdf != null) { + thdf.start(); + } + bus = loader.getComponentNoExceptionWhenNotExisting(CloudBus.class); if (bus != null) { bus.start(); @@ -712,6 +725,28 @@ public static int getManagementNodeServicePort() { return Integer.parseInt(System.getProperty("RESTFacade.port", "8080")); } + public static String getManagementServerVip() { + if (!ZSha2Helper.isMNHaEnvironment()) { + return getManagementServerIp(); + } + return ZSha2Helper.getInfo(false).getDbvip(); + } + + public static String getManagementServerVipBaseUrl() { + String ipAddress = getManagementServerVip(); + int port = getManagementNodeServicePort(); + String formattedIp; + + + if (IPv6NetworkUtils.isIpv6Address(ipAddress)) { + formattedIp = String.format("[%s]", ipAddress); + } else { + formattedIp = ipAddress; + } + + return String.format("http://%s:%d", formattedIp, port); + } + public static String getCanonicalServerIp() { if (!ZSha2Helper.isMNHaEnvironment()) { return getManagementServerIp(); @@ -809,9 +844,14 @@ private static String getManagementServerIpInternal() { for (NetworkInterface iface : Collections.list(nets)) { String name = iface.getName(); if (defaultLine.contains(name)) { - InetAddress ia = iface.getInetAddresses().nextElement(); - ip = ia.getHostAddress(); - break; + for (InetAddress ia : Collections.list(iface.getInetAddresses())) { + ip = ia.getHostAddress(); + if (ia instanceof Inet4Address) { + // we prefer IPv4 address + ip = ia.getHostAddress(); + break; + } + } } } } catch (SocketException e) { @@ -895,12 +935,13 @@ public static boolean killProcess(int pid, Integer timeout) { } } - private static ErrorCodeElaboration elaborate(String details, Object...args) { + private static ErrorCodeElaboration elaborate(String fmt, Object...args) { try { - if (String.format(details, args).length() > StringSimilarity.maxElaborationRegex) { + if (String.format(fmt, args).length() > StringSimilarity.maxElaborationRegex) { return null; } - ErrorCodeElaboration elaboration = StringSimilarity.findSimilar(details, args); + + ErrorCodeElaboration elaboration = StringSimilarity.findSimilar(fmt, args); if (elaboration == null) { return null; } @@ -934,66 +975,108 @@ public static ErrorCode err(Enum errCode, ErrorCode cause, String fmt, Object... } ErrorCode result = errf.instantiateErrorCode(errCode, details, cause); - // start to generate elaboration... - if (CoreGlobalProperty.ENABLE_ELABORATION) { - try { - ErrorCode coreError = cause == null ? getCoreError(result) : getCoreError(cause); - // use the core cause as elaboration if it existed - if (coreError.getElaboration() != null) { - result.setCost(coreError.getCost()); - result.setElaboration(coreError.getElaboration()); - result.setMessages(coreError.getMessages()); - } else if (cause instanceof ErrorCodeList && ((ErrorCodeList) cause).getCauses() != null) { - // suppose elaborations are existed in causes... - ErrorCodeList errList = (ErrorCodeList)cause; - String costs = null; - String elas = null; - ErrorCodeElaboration messages = null; - for (ErrorCode c: errList.getCauses()) { - ErrorCode lcError = getCoreError(c); - if (lcError.getElaboration() != null && !lcError.getElaboration().equals(elas) && !lcError.getMessages().equals(messages)) { - costs = costs == null ? lcError.getCost() : addTwoCosts(costs, lcError.getCost()); - elas = elas == null ? lcError.getElaboration() : String.join(",", elas, lcError.getElaboration()); - messages = messages == null ? lcError.getMessages() : messages.addElaborationMessage(lcError.getMessages()); - } - } - result.setCost(costs); - result.setElaboration(elas); - result.setMessages(messages); - } + handleErrorElaboration(errCode, fmt, result, cause, args); + addErrorCounter(result); - if (result.getElaboration() == null && cause == null) { - long start = System.currentTimeMillis(); - /** - * try details first, then descriptions - */ - ErrorCodeElaboration ela = elaborate(fmt, args); - if (ela == null && allowCode.contains(errCode)) { - ela = elaborate(result.getDescription()); - } - if (ela != null) { - if (args != null && args.length == 1 && StringSimilarity.isRegexMatched(ela.getRegex(), String.valueOf(args[0]))) { - result.setMessages(new ErrorCodeElaboration(ela)); - result.setElaboration(StringSimilarity.formatElaboration(String.valueOf(args[0]))); - StringSimilarity.addErrors(fmt, ela); - } else { - result.setMessages(new ErrorCodeElaboration(ela, args)); - result.setElaboration(StringSimilarity.formatElaboration(ela.getMessage_cn(), args)); - StringSimilarity.addErrors(fmt, ela); - } - } else { - StringSimilarity.addMissed(fmt); - } - result.setCost((System.currentTimeMillis() - start) + "ms"); + return result; + } + + private static void findElaborationFromCoreError(ErrorCode cause, ErrorCode result) { + ErrorCode coreError = cause == null ? getCoreError(result) : getCoreError(cause); + // use the core cause as elaboration if it existed + if (coreError.getElaboration() != null) { + result.setCost(coreError.getCost()); + result.setElaboration(coreError.getElaboration()); + result.setMessages(coreError.getMessages()); + } else if (cause instanceof ErrorCodeList && ((ErrorCodeList) cause).getCauses() != null) { + // suppose elaborations are existed in causes... + ErrorCodeList errList = (ErrorCodeList) cause; + String costs = null; + String elas = null; + ErrorCodeElaboration messages = null; + for (ErrorCode c: errList.getCauses()) { + ErrorCode lcError = getCoreError(c); + if (lcError.getElaboration() != null && !lcError.getElaboration().equals(elas) && !lcError.getMessages().equals(messages)) { + costs = costs == null ? lcError.getCost() : addTwoCosts(costs, lcError.getCost()); + elas = elas == null ? lcError.getElaboration() : String.join(",", elas, lcError.getElaboration()); + messages = messages == null ? lcError.getMessages() : messages.addElaborationMessage(lcError.getMessages()); } - } catch (Throwable e) { - logger.warn("exception happened when found elaboration"); - logger.warn(e.getMessage()); } + result.setCost(costs); + result.setElaboration(elas); + result.setMessages(messages); } - addErrorCounter(result); + } - return result; + private static void generateElaboration(Enum errCode, ErrorCode result, String fmt, Object...args) { + // try to find same error with fmt and args + ErrorCodeElaboration ela = elaborate(fmt, args); + + // only elaborate the error code in allowCode if fmt missed + if (ela == null && allowCode.contains(errCode)) { + ela = elaborate(result.getDescription()); + } + + // failed to find elaboration, add the error code fmt string to missed list + if (ela == null) { + if (args != null) { + StringSimilarity.addMissed(String.format(fmt, args)); + } else { + StringSimilarity.addMissed(fmt); + } + + // note: if allowCode failed to find elaboration, + // we still need to add the description to missed list + if (allowCode.contains(errCode)) { + StringSimilarity.addMissed(result.getDescription()); + } + + return; + } + + String prefix, msg; + if (locale.equals(Locale.SIMPLIFIED_CHINESE)) { + prefix = "错误信息: %s\n"; + msg = ela.getMessage_cn(); + } else { + prefix = "Error message: %s\n"; + msg = ela.getMessage_en(); + } + + // tricky code that we treat the only one args error maybe use the cause or + // error from other component directly, so we need to check if the args is + // matched with the regex at first + if (args != null && args.length == 1 && StringSimilarity.isRegexMatched(ela.getRegex(), String.valueOf(args[0]))) { + result.setMessages(new ErrorCodeElaboration(ela, locale)); + String formatError = String.format(prefix, args[0]); + result.setElaboration(StringSimilarity.formatElaboration(formatError)); + } else { + result.setMessages(new ErrorCodeElaboration(ela, locale, args)); + result.setElaboration(StringSimilarity.formatElaboration(String.format(prefix, msg), args)); + } + + StringSimilarity.addErrors(fmt, ela); + } + + private static void handleErrorElaboration(Enum errCode, String fmt, ErrorCode result, ErrorCode cause, Object...args) { + if (!CoreGlobalProperty.ENABLE_ELABORATION) { + return; + } + + // start to generate elaboration... + try { + findElaborationFromCoreError(cause, result); + + // if the elaboration is not found, try to generate it + if (result.getElaboration() == null && cause == null) { + long start = System.currentTimeMillis(); + generateElaboration(errCode, result, fmt, args); + result.setCost((System.currentTimeMillis() - start) + "ms"); + } + } catch (Throwable e) { + logger.warn("exception happened when found elaboration"); + logger.warn(e.getMessage()); + } } private static String addTwoCosts(String origin, String increase) { @@ -1010,6 +1093,24 @@ private static ErrorCode getCoreError(ErrorCode result) { } } + public static String missingVariables(Object...args) { + if (args.length == 1) { + return String.format("[%s] is required", args[0]); + } + + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (Object arg : args) { + if (arg == null) { + continue; + } + + sb.append(arg).append(", "); + } + sb.append("] "); + return sb.append("are required").toString(); + } + public static ErrorCode inerr(String fmt, Object...args) { return err(SysErrors.INTERNAL, fmt, args); } @@ -1096,4 +1197,12 @@ public static void addErrorCounter(ErrorCode code) { public static Map getErrorCounter() { return errorCounter; } + + public static boolean isSimulatorOn() { + return StartMode.SIMULATOR.toString().equals(CoreGlobalProperty.START_MODE) || CoreGlobalProperty.SIMULATORS_ON; + } + + public static boolean isMinimalOn() { + return StartMode.MINIMAL.toString().equals(CoreGlobalProperty.START_MODE); + } } diff --git a/core/src/main/java/org/zstack/core/RBACInfo.java b/core/src/main/java/org/zstack/core/RBACInfo.java index be68c8a9b87..2399e2c720d 100755 --- a/core/src/main/java/org/zstack/core/RBACInfo.java +++ b/core/src/main/java/org/zstack/core/RBACInfo.java @@ -2,6 +2,7 @@ import org.zstack.core.debug.APIDebugSignalMsg; import org.zstack.core.debug.APIGetDebugSignalMsg; +import org.zstack.header.core.APIGetChainTaskMsg; import org.zstack.header.identity.rbac.RBACDescription; import org.zstack.core.debug.APICleanQueueMsg; @@ -9,7 +10,8 @@ public class RBACInfo implements RBACDescription { @Override public void permissions() { permissionBuilder() - .adminOnlyAPIs(APIDebugSignalMsg.class, APIGetDebugSignalMsg.class, APICleanQueueMsg.class) + .adminOnlyAPIs(APIDebugSignalMsg.class, APIGetDebugSignalMsg.class, APICleanQueueMsg.class, + APIGetChainTaskMsg.class) .build(); } diff --git a/core/src/main/java/org/zstack/core/StartMode.java b/core/src/main/java/org/zstack/core/StartMode.java new file mode 100644 index 00000000000..4804fa69b8b --- /dev/null +++ b/core/src/main/java/org/zstack/core/StartMode.java @@ -0,0 +1,18 @@ +package org.zstack.core; + +public enum StartMode { + DEFAULT("default"), + SIMULATOR("simulator"), + MINIMAL("minimal"); + + private String mode; + + StartMode(String mode){ + this.mode = mode; + } + + @Override + public String toString() { + return mode; + } +} diff --git a/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java b/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java index a49ae84ef03..0e0482f2442 100755 --- a/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java +++ b/core/src/main/java/org/zstack/core/agent/AgentManagerImpl.java @@ -256,8 +256,12 @@ public void success(Boolean deployed) { Defer.defer(new Runnable() { @Override public void run() { - tmpInclude.delete(); - tmpAgentYaml.delete(); + if (!tmpInclude.delete()) { + logger.warn(String.format("failed to delete file[%s]", tmpInclude)); + } + if (!tmpAgentYaml.delete()) { + logger.warn(String.format("failed to delete file[%s]", tmpAgentYaml)); + } } }); @@ -283,8 +287,12 @@ public void fail(ErrorCode errorCode) { Defer.defer(new Runnable() { @Override public void run() { - tmpInclude.delete(); - tmpAgentYaml.delete(); + if (!tmpInclude.delete()) { + logger.warn(String.format("failed to delete file[%s]", tmpInclude)); + } + if (!tmpAgentYaml.delete()) { + logger.warn(String.format("failed to delete file[%s]", tmpAgentYaml)); + } } }); diff --git a/core/src/main/java/org/zstack/core/ansible/AbstractAnsibleAgentDeployArguments.java b/core/src/main/java/org/zstack/core/ansible/AbstractAnsibleAgentDeployArguments.java new file mode 100644 index 00000000000..eefe5ce06db --- /dev/null +++ b/core/src/main/java/org/zstack/core/ansible/AbstractAnsibleAgentDeployArguments.java @@ -0,0 +1,5 @@ +package org.zstack.core.ansible; + +public abstract class AbstractAnsibleAgentDeployArguments extends AnsibleBasicArguments { + public abstract String getPackageName(); +} diff --git a/core/src/main/java/org/zstack/core/ansible/AnsibleBasicArguments.java b/core/src/main/java/org/zstack/core/ansible/AnsibleBasicArguments.java new file mode 100644 index 00000000000..c66bf46521f --- /dev/null +++ b/core/src/main/java/org/zstack/core/ansible/AnsibleBasicArguments.java @@ -0,0 +1,106 @@ +package org.zstack.core.ansible; + +import com.google.gson.annotations.SerializedName; +import org.zstack.header.log.NoLogging; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + +import java.io.Serializable; +import java.util.LinkedHashMap; + +public class AnsibleBasicArguments implements Serializable { + protected static final CLogger logger = Utils.getLogger(AnsibleBasicArguments.class); + + @SerializedName("pip_url") + private String pipUrl; + @SerializedName("trusted_host") + private String trustedHost; + @SerializedName("yum_server") + private String yumServer; + @SerializedName("remote_user") + private String remoteUser; + @NoLogging + private String remotePass; + @NoLogging + private String remote_pass; + @SerializedName("remote_port") + private String remotePort; + @SerializedName("zstack_repo") + private String zstackRepo; + + public String getZstackRepo() { + return zstackRepo; + } + + public void setZstackRepo(String zstackRepo) { + this.zstackRepo = zstackRepo; + } + + public String getRemote_pass() { + return remote_pass; + } + + public void setRemote_pass(String remote_pass) { + this.remote_pass = remote_pass; + } + + public String getPipUrl() { + return pipUrl; + } + + public void setPipUrl(String pipUrl) { + this.pipUrl = pipUrl; + } + + public String getTrustedHost() { + return trustedHost; + } + + public void setTrustedHost(String trustedHost) { + this.trustedHost = trustedHost; + } + + public String getYumServer() { + return yumServer; + } + + public void setYumServer(String yumServer) { + this.yumServer = yumServer; + } + + public String getRemoteUser() { + return remoteUser; + } + + public void setRemoteUser(String remoteUser) { + this.remoteUser = remoteUser; + } + + public String getRemotePass() { + return remotePass; + } + + public void setRemotePass(String remotePass) { + this.remotePass = remotePass; + this.remote_pass = remotePass; + } + + public String getRemotePort() { + return remotePort; + } + + public void setRemotePort(String remotePort) { + this.remotePort = remotePort; + } + + public LinkedHashMap toArgumentMap() { + LinkedHashMap rehashedObject = JSONObjectUtil.rehashObject(this, LinkedHashMap.class); + + if (logger.isTraceEnabled()) { + logger.trace(String.format("object after rehashed: %s", JSONObjectUtil.toJsonString(rehashedObject))); + } + + return rehashedObject; + } +} diff --git a/core/src/main/java/org/zstack/core/ansible/AnsibleFacadeImpl.java b/core/src/main/java/org/zstack/core/ansible/AnsibleFacadeImpl.java index 400420cfd8e..dc3eb335337 100755 --- a/core/src/main/java/org/zstack/core/ansible/AnsibleFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/ansible/AnsibleFacadeImpl.java @@ -75,10 +75,10 @@ private void placePip703() { ShellUtils.run(String.format("yes | cp %s %s", pip.getAbsolutePath(), filesDir)); } - private void placeAnsible196() { - File ansible = PathUtil.findFileOnClassPath("tools/ansible-1.9.6.tar.gz"); + private void placeAnsible4100() { + File ansible = PathUtil.findFileOnClassPath("tools/ansible-4.10.0-py2.py3-none-any.whl"); if (ansible == null) { - throw new CloudRuntimeException("cannot find tools/ansible-1.9.6.tar.gz on classpath"); + throw new CloudRuntimeException("cannot find tools/ansible-4.10.0-py2.py3-none-any.whl on classpath"); } File root = new File(filesDir); @@ -102,8 +102,8 @@ void init() { invDir.mkdirs(); } - if (!invFile.exists()) { - invFile.createNewFile(); + if (!invFile.exists() && !invFile.createNewFile()) { + throw new OperationFailureException(operr("fail to create new File[%s]", invFile)); } Wini ini = new Wini(invFile); Map cfgs = Platform.getGlobalPropertiesStartWith("Ansible.cfg."); @@ -129,17 +129,26 @@ void init() { } placePip703(); - placeAnsible196(); - - ShellUtils.run(String.format("if ! sudo ansible --version | grep -q 1.9.6; then " + - "if grep -i -s centos /etc/system-release; then " + - "sudo yum remove -y ansible; " + - "elif grep -i -s ubuntu /etc/issue; then " + - "sudo apt-get --assume-yes remove ansible; " + - "else echo \"Warning: can't remove ansible from unknown platform\"; " + + placeAnsible4100(); + + ShellUtils.run(String.format( + "NEED_INSTALL=false; " + + "if [ -d /var/lib/zstack/virtualenv/zstacksys ]; then " + + ". /var/lib/zstack/virtualenv/zstacksys/bin/activate; " + + "if ! ansible --version | grep -q 'core 2.11.12'; then " + + "deactivate; " + + "NEED_INSTALL=true; " + "fi; " + - "sudo pip install -i file://%s --trusted-host localhost -I ansible==1.9.6; " + - "fi", AnsibleConstant.PYPI_REPO), false); + "else " + + "NEED_INSTALL=true; "+ + "fi; " + + "if $NEED_INSTALL; then " + + "sudo bash -c 'rm -rf /var/lib/zstack/virtualenv/zstacksys && virtualenv /var/lib/zstack/virtualenv/zstacksys --python=python2.7; "+ + ". /var/lib/zstack/virtualenv/zstacksys/bin/activate; "+ + "TMPDIR=/usr/local/zstack/ pip install -i file://%s --trusted-host localhost -I setuptools==39.2.0; "+ + "TMPDIR=/usr/local/zstack/ pip install -i file://%s --trusted-host localhost -I ansible==4.10.0'; "+ + "fi" , AnsibleConstant.PYPI_REPO, AnsibleConstant.PYPI_REPO), false); + deployModule("ansible/zstacklib", "zstacklib.py"); } catch (IOException e) { @@ -181,6 +190,43 @@ public String getName() { }); } + private Map collectArguments(RunAnsibleMsg msg) { + Map arguments = new HashMap(); + if (msg.getArguments() != null) { + arguments.putAll(msg.getArguments()); + } + + if (msg.getDeployArguments() != null) { + arguments.putAll(msg.getDeployArguments().toArgumentMap()); + } + + arguments.put("host", msg.getTargetIp()); + arguments.put("mn_ip", Platform.getCanonicalServerIp()); + if (AnsibleGlobalConfig.ENABLE_ANSIBLE_CACHE_SYSTEM_INFO.value(Boolean.class)) { + arguments.put("host_uuid", msg.getTargetUuid()); + } + + arguments.put("zstack_root", AnsibleGlobalProperty.ZSTACK_ROOT); + arguments.put("pkg_zstacklib", AnsibleGlobalProperty.ZSTACKLIB_PACKAGE_NAME); + getVariables().forEach(arguments::putIfAbsent); + String playBookPath = msg.getPlayBookPath(); + if (!playBookPath.contains("py")) { + arguments.put("ansible_ssh_user", arguments.get("remote_user")); + arguments.put("ansible_ssh_port", arguments.get("remote_port")); + arguments.put("ansible_ssh_pass", arguments.get("remote_pass")); + arguments.remove("remote_user"); + arguments.remove("remote_pass"); + arguments.remove("remote_port"); + if (!arguments.get("ansible_ssh_user").equals("root")) { + arguments.put("ansible_become", "yes"); + arguments.put("become_user", "root"); + arguments.put("ansible_become_pass", arguments.get("ansible_ssh_pass")); + } + } + + return arguments; + } + private void doHandle(final RunAnsibleMsg msg, SyncTaskChain outter) { thdf.syncSubmit(new SyncTask() { @Override @@ -201,50 +247,23 @@ public String getName() { private void run(Completion completion) { new PrepareAnsible().setTargetIp(msg.getTargetIp()).prepare(); - logger.debug(String.format("start running ansible for playbook[%s]", msg.getPlayBookPath())); - Map arguments = new HashMap(); - if (msg.getArguments() != null) { - arguments.putAll(msg.getArguments()); - } - if (msg.getRemotePass() != null) { - arguments.put("remote_pass", msg.getRemotePass()); - } - arguments.put("host", msg.getTargetIp()); - if (AnsibleGlobalConfig.ENABLE_ANSIBLE_CACHE_SYSTEM_INFO.value(Boolean.class)) { - arguments.put("host_uuid", msg.getTargetUuid()); - } - - arguments.put("zstack_root", AnsibleGlobalProperty.ZSTACK_ROOT); - arguments.put("pkg_zstacklib", AnsibleGlobalProperty.ZSTACKLIB_PACKAGE_NAME); - arguments.putAll(getVariables()); String playBookPath = msg.getPlayBookPath(); - if (!playBookPath.contains("py")) { - arguments.put("ansible_ssh_user", arguments.get("remote_user")); - arguments.put("ansible_ssh_port", arguments.get("remote_port")); - arguments.put("ansible_ssh_pass", arguments.get("remote_pass")); - arguments.remove("remote_user"); - arguments.remove("remote_pass"); - arguments.remove("remote_port"); - if (!arguments.get("ansible_ssh_user").equals("root")) { - arguments.put("ansible_become", "yes"); - arguments.put("become_user", "root"); - arguments.put("ansible_become_pass", arguments.get("ansible_ssh_pass")); - } - } + Map arguments = collectArguments(msg); + logger.debug(String.format("start running ansible for playbook[%s]", msg.getPlayBookPath())); String executable = msg.getAnsibleExecutable() == null ? AnsibleGlobalProperty.EXECUTABLE : msg.getAnsibleExecutable(); long timeout = TimeUnit.MILLISECONDS.toSeconds(msg.getTimeout()); try { String output; if (AnsibleGlobalProperty.DEBUG_MODE2) { - output = ShellUtils.run(String.format("PYTHONPATH=%s timeout %d %s %s -i %s -vvvv --private-key %s -e '%s' | tee -a %s", + output = ShellUtils.run(String.format("bash -c '. /var/lib/zstack/virtualenv/zstacksys/bin/activate; PYTHONPATH=%s timeout %d %s %s -i %s -vvvv --private-key %s -e '\\''%s'\\' | tee -a %s", AnsibleConstant.ZSTACKLIB_ROOT, timeout, executable, playBookPath, AnsibleConstant.INVENTORY_FILE, msg.getPrivateKeyFile(), JSONObjectUtil.dumpPretty(arguments), AnsibleConstant.LOG_PATH), AnsibleConstant.ROOT_DIR); } else if (AnsibleGlobalProperty.DEBUG_MODE) { - output = ShellUtils.run(String.format("PYTHONPATH=%s timeout %d %s %s -i %s -vvvv --private-key %s -e '%s'", + output = ShellUtils.run(String.format("bash -c '. /var/lib/zstack/virtualenv/zstacksys/bin/activate; PYTHONPATH=%s timeout %d %s %s -i %s -vvvv --private-key %s -e '\\''%s'\\'", AnsibleConstant.ZSTACKLIB_ROOT, timeout, executable, playBookPath, AnsibleConstant.INVENTORY_FILE, msg.getPrivateKeyFile(), JSONObjectUtil.dumpPretty(arguments)), AnsibleConstant.ROOT_DIR); } else { - output = ShellUtils.run(String.format("PYTHONPATH=%s timeout %d %s %s -i %s --private-key %s -e '%s'", + output = ShellUtils.run(String.format("bash -c '. /var/lib/zstack/virtualenv/zstacksys/bin/activate; PYTHONPATH=%s timeout %d %s %s -i %s --private-key %s -e '\\''%s'\\'", AnsibleConstant.ZSTACKLIB_ROOT, timeout, executable, playBookPath, AnsibleConstant.INVENTORY_FILE, msg.getPrivateKeyFile(), JSONObjectUtil.dumpPretty(arguments)), AnsibleConstant.ROOT_DIR); } @@ -509,8 +528,8 @@ public void deployModule(String modulePath, String playBookName) { if (f.getName().equals(playBookName)) { String lnPath = PathUtil.join(AnsibleConstant.ROOT_DIR, playBookName); File lnFile = new File(lnPath); - if (lnFile.exists()) { - lnFile.delete(); + if (lnFile.exists() && !lnFile.delete()) { + logger.warn(String.format("failed to delete file[%s]", lnFile)); } Files.createSymbolicLink(Paths.get(lnPath), Paths.get(f.getAbsolutePath())); isPlaybookLinked = true; diff --git a/core/src/main/java/org/zstack/core/ansible/AnsibleGlobalProperty.java b/core/src/main/java/org/zstack/core/ansible/AnsibleGlobalProperty.java index f6c3b181d90..0dfc6c0d2da 100755 --- a/core/src/main/java/org/zstack/core/ansible/AnsibleGlobalProperty.java +++ b/core/src/main/java/org/zstack/core/ansible/AnsibleGlobalProperty.java @@ -9,7 +9,7 @@ public class AnsibleGlobalProperty { @GlobalProperty(name = "Ansible.executable", defaultValue = "python") public static String EXECUTABLE; - @GlobalProperty(name = "Ansible.zstacklibPackageName", defaultValue = "zstacklib-4.4.0.tar.gz") + @GlobalProperty(name = "Ansible.zstacklibPackageName", defaultValue = "zstacklib-5.4.0.tar.gz") public static String ZSTACKLIB_PACKAGE_NAME; @GlobalProperty(name = "Ansible.zstackRoot", defaultValue = "/var/lib/zstack") public static String ZSTACK_ROOT; diff --git a/core/src/main/java/org/zstack/core/ansible/AnsibleRunner.java b/core/src/main/java/org/zstack/core/ansible/AnsibleRunner.java index 7491587e4b6..58a22ebceca 100755 --- a/core/src/main/java/org/zstack/core/ansible/AnsibleRunner.java +++ b/core/src/main/java/org/zstack/core/ansible/AnsibleRunner.java @@ -1,14 +1,11 @@ package org.zstack.core.ansible; -import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.defer.Defer; -import org.zstack.core.defer.Deferred; import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.errorcode.ErrorCode; @@ -51,7 +48,7 @@ public class AnsibleRunner { private RESTFacade restf; private static String privKeyFile; - private List checkers = new ArrayList(); + private List checkers = new ArrayList<>(); static { privKeyFile = PathUtil.findFileOnClassPath(AnsibleConstant.RSA_PRIVATE_KEY).getAbsolutePath(); @@ -82,6 +79,8 @@ public class AnsibleRunner { private String ansibleExecutable; private boolean forceRun; + private AnsibleBasicArguments deployArguments; + public String getAnsibleExecutable() { return ansibleExecutable; } @@ -166,6 +165,10 @@ public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } + public void useDefaultPrivateKey() { + setPrivateKey(asf.getPrivateKey()); + } + public int getSshPort() { return sshPort; } @@ -182,6 +185,14 @@ public void setPlayBookName(String playBookName) { this.playBookName = playBookName; } + public AnsibleBasicArguments getDeployArguments() { + return deployArguments; + } + + public void setDeployArguments(AnsibleBasicArguments deployArguments) { + this.deployArguments = deployArguments; + } + public Map getArguments() { return arguments; } @@ -224,7 +235,6 @@ private void setupPublicKey() throws IOException { } } - @Deferred private void setupPublicKeyOnRemote() { String script = ln( "#!/bin/sh", @@ -256,21 +266,7 @@ private void setupPublicKeyOnRemote() { ssh.setUsername(username); if (privateKey != null) { - try { - final File tempKeyFile = File.createTempFile("zstack", "tmp"); - FileUtils.writeStringToFile(tempKeyFile, privateKey); - - Defer.defer(new Runnable() { - @Override - public void run() { - tempKeyFile.delete(); - } - }); - - ssh.setPrivateKeyFile(tempKeyFile.getAbsolutePath()); - } catch (IOException e) { - throw new CloudRuntimeException(e); - } + ssh.setPrivateKey(privateKey); } SshResult res = ssh.runScript(script); @@ -284,8 +280,7 @@ private void callAnsible(final ReturnValueCompletion completion) { msg.setPrivateKeyFile(privKeyFile); msg.setArguments(arguments); msg.setAnsibleExecutable(ansibleExecutable); - // TODO hack for hide password - Optional.ofNullable(arguments.remove("remote_pass")).ifPresent(it -> msg.setRemotePass(it.toString())); + msg.setDeployArguments(deployArguments); if (playBookPath != null) { msg.setPlayBookPath(playBookPath); @@ -389,18 +384,27 @@ public void run(ReturnValueCompletion completion) { } int port = new URI(restf.getBaseUrl()).getPort(); - putArgument("pip_url", String.format("http://%s:%d/zstack/static/pypi/simple", restf.getHostName(), port)); - putArgument("trusted_host", restf.getHostName()); - putArgument("yum_server", String.format("%s:%d", restf.getHostName(), port)); - putArgument("remote_user", username); + + if (deployArguments == null) { + deployArguments = new AnsibleBasicArguments(); + } + + deployArguments.setPipUrl(String.format("http://%s:%d/zstack/static/pypi/simple", restf.getHostName(), port)); + deployArguments.setTrustedHost(restf.getHostName()); + deployArguments.setYumServer(String.format("%s:%d", restf.getHostName(), port)); + deployArguments.setRemoteUser(username); if (password != null && !password.isEmpty()) { - putArgument("remote_pass", password); + deployArguments.setRemotePass(password); } - putArgument("remote_port", Integer.toString(sshPort)); + deployArguments.setRemotePort(Integer.toString(sshPort)); logger.debug(String.format("starts to run ansible[%s]", playBookPath == null ? playBookName : playBookPath)); new PrepareAnsible().setTargetIp(targetIp).prepare(); - setupPublicKey(); + + if (!CoreGlobalProperty.UNIT_TEST_ON) { + setupPublicKey(); + } + callAnsible(completion); } catch (SshException e) { throw new OperationFailureException(operr("User name or password or port number may be problematic")); diff --git a/core/src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java b/core/src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java index e178265f4a8..ad7be7f7bb9 100644 --- a/core/src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java +++ b/core/src/main/java/org/zstack/core/ansible/CallBackNetworkChecker.java @@ -7,6 +7,7 @@ import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.ssh.Ssh; +import org.zstack.utils.ssh.SshCmdHelper; import org.zstack.utils.ssh.SshException; import org.zstack.utils.ssh.SshResult; @@ -47,9 +48,10 @@ public void deleteDestFile() { * if failed, use nmap to try again. */ private ErrorCode useNcatAndNmapToTestConnection(Ssh ssh) { - String srcScript = script.format(password, callBackPort, callbackIp); + String srcScript = script.format(SshCmdHelper.shellQuote(password), callBackPort, callbackIp); - SshResult ret = ssh.setExecTimeout(60).shell(srcScript).setTimeout(60).runAndClose(); + ssh.sudoCommand(srcScript); + SshResult ret = ssh.run(); ret.raiseExceptionIfFailed(); return null; diff --git a/core/src/main/java/org/zstack/core/ansible/PrepareAnsible.java b/core/src/main/java/org/zstack/core/ansible/PrepareAnsible.java index 635349ef0f6..cd46233ef34 100755 --- a/core/src/main/java/org/zstack/core/ansible/PrepareAnsible.java +++ b/core/src/main/java/org/zstack/core/ansible/PrepareAnsible.java @@ -2,6 +2,7 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; +import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; @@ -15,6 +16,8 @@ import java.util.List; import java.util.concurrent.locks.ReentrantLock; +import static org.zstack.core.Platform.operr; + /** * Created by frank on 7/22/2015. */ @@ -30,8 +33,8 @@ public class PrepareAnsible { static { try { - if (!hostsFile.exists()) { - hostsFile.createNewFile(); + if (!hostsFile.exists() && !hostsFile.createNewFile()) { + throw new OperationFailureException(operr("fail to create new File[%s]", hostsFile)); } if (AnsibleGlobalProperty.KEEP_HOSTS_FILE_IN_MEMORY) { diff --git a/core/src/main/java/org/zstack/core/ansible/RunAnsibleMsg.java b/core/src/main/java/org/zstack/core/ansible/RunAnsibleMsg.java index f64d077903f..afbb368e736 100755 --- a/core/src/main/java/org/zstack/core/ansible/RunAnsibleMsg.java +++ b/core/src/main/java/org/zstack/core/ansible/RunAnsibleMsg.java @@ -1,9 +1,7 @@ package org.zstack.core.ansible; -import org.zstack.header.log.NoLogging; import org.zstack.header.message.NeedReplyMessage; -import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -15,8 +13,8 @@ public class RunAnsibleMsg extends NeedReplyMessage { private String privateKeyFile; private String playBookPath; private String ansibleExecutable; - @NoLogging - private String remotePass; + private AnsibleBasicArguments deployArguments; + private Map arguments = new HashMap(); public String getAnsibleExecutable() { @@ -67,11 +65,11 @@ public void setTargetUuid(String targetUuid) { this.targetUuid = targetUuid; } - public String getRemotePass() { - return remotePass; + public AnsibleBasicArguments getDeployArguments() { + return deployArguments; } - public void setRemotePass(String remotePass) { - this.remotePass = remotePass; + public void setDeployArguments(AnsibleBasicArguments deployArguments) { + this.deployArguments = deployArguments; } } diff --git a/core/src/main/java/org/zstack/core/ansible/SshChronyConfigChecker.java b/core/src/main/java/org/zstack/core/ansible/SshChronyConfigChecker.java index 37fad948abb..e9afbb1ee09 100644 --- a/core/src/main/java/org/zstack/core/ansible/SshChronyConfigChecker.java +++ b/core/src/main/java/org/zstack/core/ansible/SshChronyConfigChecker.java @@ -29,11 +29,13 @@ public boolean needDeploy() { .setPassword(password).setPort(sshPort) .setHostname(targetIp); try { - ssh.command("awk '/^\\s*server/{print $2}' /etc/chrony.conf"); + ssh.sudoCommand("awk '/^\\s*server/{print $2}' /etc/chrony.conf"); SshResult ret = ssh.run(); int returnCode = ret.getReturnCode(); ssh.reset(); if (returnCode != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); return true; } diff --git a/core/src/main/java/org/zstack/core/ansible/SshFileExistChecker.java b/core/src/main/java/org/zstack/core/ansible/SshFileExistChecker.java new file mode 100755 index 00000000000..ccd78f74592 --- /dev/null +++ b/core/src/main/java/org/zstack/core/ansible/SshFileExistChecker.java @@ -0,0 +1,92 @@ +package org.zstack.core.ansible; + +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.ssh.Ssh; +import org.zstack.utils.ssh.SshResult; + +/** + */ +public class SshFileExistChecker implements AnsibleChecker { + private static final CLogger logger = Utils.getLogger(SshFileExistChecker.class); + + private String filePath; + private String username; + private String password; + private String privateKey; + private String targetIp; + private int sshPort = 22; + + @Override + public boolean needDeploy() { + Ssh ssh = new Ssh(); + ssh.setUsername(username).setPrivateKey(privateKey) + .setPassword(password).setPort(sshPort) + .setHostname(targetIp) + .setTimeout(5); + try { + ssh.sudoCommand(String.format("stat %s", filePath)); + SshResult ret = ssh.run(); + if (ret.getReturnCode() != 0) { + logger.debug(String.format("file not exist, file: %s", filePath)); + return true; + } + } finally { + ssh.close(); + } + + return false; + } + + @Override + public void deleteDestFile() { + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public int getSshPort() { + return sshPort; + } + + public void setSshPort(int sshPort) { + this.sshPort = sshPort; + } + + public String getTargetIp() { + return targetIp; + } + + public void setTargetIp(String targetIp) { + this.targetIp = targetIp; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } +} diff --git a/core/src/main/java/org/zstack/core/ansible/SshFileMd5Checker.java b/core/src/main/java/org/zstack/core/ansible/SshFileMd5Checker.java index 2beb2fb5058..63fd823f833 100755 --- a/core/src/main/java/org/zstack/core/ansible/SshFileMd5Checker.java +++ b/core/src/main/java/org/zstack/core/ansible/SshFileMd5Checker.java @@ -1,5 +1,6 @@ package org.zstack.core.ansible; +import org.zstack.core.CoreGlobalProperty; import org.zstack.utils.ShellResult; import org.zstack.utils.ShellUtils; import org.zstack.utils.Utils; @@ -33,7 +34,8 @@ private SrcDestPair(String srcPath, String destPath) { String destPath; } - public static final String ZSTACKLIB_SRC_PATH = PathUtil.findFileOnClassPath(String.format("ansible/zstacklib/%s", AnsibleGlobalProperty.ZSTACKLIB_PACKAGE_NAME), true).getAbsolutePath(); + public static final String ZSTACKLIB_SRC_PATH = CoreGlobalProperty.UNIT_TEST_ON ? "/tmp" : + PathUtil.findFileOnClassPath(String.format("ansible/zstacklib/%s", AnsibleGlobalProperty.ZSTACKLIB_PACKAGE_NAME), true).getAbsolutePath(); @Override public boolean needDeploy() { @@ -47,9 +49,11 @@ public boolean needDeploy() { String sourceFilePath = b.srcPath; String destFilePath = b.destPath; - ssh.command(String.format("echo %s | sudo -S md5sum %s 2>/dev/null", password, destFilePath)); + ssh.sudoCommand(String.format("md5sum %s", destFilePath)); SshResult ret = ssh.run(); if (ret.getReturnCode() != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); return true; } ssh.reset(); @@ -59,7 +63,7 @@ public boolean needDeploy() { sret.raiseExceptionIfFail(); String srcMd5 = sret.getStdout().split(" ")[0]; if (!destMd5.equals(srcMd5)) { - logger.debug(String.format("file MD5 changed, src[%s, md5:%s] dest[%s, md5, %s]", sourceFilePath, + logger.debug(String.format("file MD5 changed, src[%s, md5:%s] dest[%s, md5: %s]", sourceFilePath, srcMd5, destFilePath, destMd5)); return true; } @@ -75,10 +79,15 @@ public boolean needDeploy() { public void deleteDestFile() { for (SrcDestPair b : srcDestPairs) { String destFilePath = b.destPath; + if (!destFilePath.contains("zstack")) { + logger.debug(String.format("skip delete dest file[%s] which is not zstack file", destFilePath)); + continue; + } + Ssh ssh = new Ssh(); ssh.setUsername(username).setPrivateKey(privateKey) .setPassword(password).setPort(sshPort) - .setHostname(targetIp).command(String.format("rm -f %s", destFilePath)).runAndClose(); + .setHostname(targetIp).sudoCommand(String.format("rm -f %s", destFilePath)).runAndClose(); logger.debug(String.format("delete dest file[%s]", destFilePath)); } } diff --git a/core/src/main/java/org/zstack/core/ansible/SshFilesMd5Checker.java b/core/src/main/java/org/zstack/core/ansible/SshFilesMd5Checker.java new file mode 100644 index 00000000000..2d69ab6f7e2 --- /dev/null +++ b/core/src/main/java/org/zstack/core/ansible/SshFilesMd5Checker.java @@ -0,0 +1,120 @@ +package org.zstack.core.ansible; + +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.ssh.Ssh; +import org.zstack.utils.ssh.SshResult; + +import java.util.ArrayList; +import java.util.List; + +public class SshFilesMd5Checker implements AnsibleChecker { + private static final CLogger logger = Utils.getLogger(SshFilesMd5Checker.class); + + private String username; + private String password; + private String privateKey; + private String ip; + private int sshPort = 22; + + private List fileMd5sums = new ArrayList<>(); + String filePath; + + @Override + public boolean needDeploy() { + Ssh ssh = new Ssh(); + ssh.setUsername(username).setPrivateKey(privateKey) + .setPassword(password).setPort(sshPort) + .setHostname(ip) + .setTimeout(5); + try { + ssh.sudoCommand(String.format("md5sum %s", filePath)); + SshResult ret = ssh.run(); + if (ret.getReturnCode() != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); + return true; + } + ssh.reset(); + String md5 = ret.getStdout().split(" ")[0]; + if (!fileMd5sums.contains(md5)) { + logger.debug(String.format("file MD5 changed, dest[%s, md5, %s]", filePath, md5)); + return true; + } + } finally { + ssh.close(); + } + + return false; + } + + @Override + public void deleteDestFile() { + if (!filePath.contains("zstack")) { + logger.debug(String.format("skip delete dest file[%s] which is not zstack file", filePath)); + return; + } + + Ssh ssh = new Ssh(); + ssh.setUsername(username).setPrivateKey(privateKey) + .setPassword(password).setPort(sshPort) + .setHostname(ip).sudoCommand(String.format("rm -f %s", filePath)).runAndClose(); + logger.debug(String.format("delete dest file[%s]", filePath)); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public int getSshPort() { + return sshPort; + } + + public void setSshPort(int sshPort) { + this.sshPort = sshPort; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public List getFileMd5sums() { + return fileMd5sums; + } + + public void setFileMd5sums(List fileMd5sums) { + this.fileMd5sums = fileMd5sums; + } + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } +} diff --git a/core/src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java b/core/src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java index ed6b0e4a1d2..e9d7e318b17 100755 --- a/core/src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java +++ b/core/src/main/java/org/zstack/core/ansible/SshFolderMd5Checker.java @@ -11,6 +11,7 @@ import org.zstack.utils.StringDSL.StringWrapper; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.ssh.SshCmdHelper; import org.zstack.utils.ssh.SshResult; import org.zstack.utils.ssh.SshShell; @@ -107,7 +108,7 @@ public boolean needDeploy() { srcRes.getStdout(), srcRes.getStderr())); } - String dstScript = script.format(dstFolder, password); + String dstScript = script.format(dstFolder, SshCmdHelper.shellQuote(password)); SshShell ssh = new SshShell(); ssh.setHostname(hostname); ssh.setUsername(username); diff --git a/core/src/main/java/org/zstack/core/ansible/SshYamlChecker.java b/core/src/main/java/org/zstack/core/ansible/SshYamlChecker.java index 80f48782f66..32e6ca5ae06 100644 --- a/core/src/main/java/org/zstack/core/ansible/SshYamlChecker.java +++ b/core/src/main/java/org/zstack/core/ansible/SshYamlChecker.java @@ -36,9 +36,11 @@ public boolean needDeploy() { .setHostname(targetIp); try { - ssh.command(String.format("grep -o '%s' %s | uniq | wc -l", getGrepArgs(), yamlFilePath)); + ssh.sudoCommand(String.format("grep -o '%s' %s | uniq | wc -l", getGrepArgs(), yamlFilePath)); SshResult ret = ssh.run(); if (ret.getReturnCode() != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); return true; } diff --git a/core/src/main/java/org/zstack/core/ansible/SshYumRepoChecker.java b/core/src/main/java/org/zstack/core/ansible/SshYumRepoChecker.java index 8732f2067e6..8438fce4eac 100644 --- a/core/src/main/java/org/zstack/core/ansible/SshYumRepoChecker.java +++ b/core/src/main/java/org/zstack/core/ansible/SshYumRepoChecker.java @@ -36,12 +36,13 @@ public boolean needDeploy() { .setPassword(password).setPort(sshPort) .setHostname(targetIp); try { - ssh.command(String.format( - "echo %s | sudo -S sed -i '/baseurl/s/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}:\\([0-9]\\+\\)/%s/g' /etc/yum.repos.d/{zstack,qemu-kvm-ev}-mn.repo", - password, restf.getHostName() + ":" + restf.getPort() + ssh.sudoCommand(String.format("sed -i '/baseurl/s/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}:\\([0-9]\\+\\)/%s/g' /etc/yum.repos.d/{zstack,qemu-kvm-ev}-mn.repo", + restf.getHostName() + ":" + restf.getPort() )); SshResult ret = ssh.setTimeout(60).runAndClose(); if (ret.getReturnCode() != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); return true; } diff --git a/core/src/main/java/org/zstack/core/ansible/SyncTimeRequestedDeployArguments.java b/core/src/main/java/org/zstack/core/ansible/SyncTimeRequestedDeployArguments.java new file mode 100644 index 00000000000..c1771de55ae --- /dev/null +++ b/core/src/main/java/org/zstack/core/ansible/SyncTimeRequestedDeployArguments.java @@ -0,0 +1,31 @@ +package org.zstack.core.ansible; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.header.exception.CloudRuntimeException; + +public abstract class SyncTimeRequestedDeployArguments extends AbstractAnsibleAgentDeployArguments { + @SerializedName("chrony_servers") + private String chronyServers = initChronyServers(); + + public String initChronyServers() { + // global sync node time disabled + if (!CoreGlobalProperty.SYNC_NODE_TIME) { + return null; + } + + if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { + throw new CloudRuntimeException("chrony server not configured!"); + } + + return String.join(",", CoreGlobalProperty.CHRONY_SERVERS); + } + + public void setChronyServers(String chronyServers) { + this.chronyServers = chronyServers; + } + + public String getChronyServers() { + return chronyServers; + } +} diff --git a/core/src/main/java/org/zstack/core/aspect/AspectCompleter.java b/core/src/main/java/org/zstack/core/aspect/AspectCompleter.java new file mode 100644 index 00000000000..f01b9b5e1ba --- /dev/null +++ b/core/src/main/java/org/zstack/core/aspect/AspectCompleter.java @@ -0,0 +1,22 @@ +package org.zstack.core.aspect; + +import org.zstack.core.db.Q; +import org.zstack.header.aspect.OwnedByAccountAspect; +import org.zstack.header.core.StaticInit; +import org.zstack.header.identity.AccountResourceRefVO; +import org.zstack.header.identity.AccountResourceRefVO_; + +import java.util.function.Function; + +public class AspectCompleter { + @StaticInit + static void staticinit() { + OwnedByAccountAspect.setAccountUuidGetter(new Function() { + @Override + public String apply(String s) { + return Q.New(AccountResourceRefVO.class).select(AccountResourceRefVO_.accountUuid) + .eq(AccountResourceRefVO_.resourceUuid, s).findValue(); + } + }); + } +} diff --git a/core/src/main/java/org/zstack/core/aspect/AsyncBackupAspect.aj b/core/src/main/java/org/zstack/core/aspect/AsyncBackupAspect.aj index 144fe8161bd..700bf48a38b 100755 --- a/core/src/main/java/org/zstack/core/aspect/AsyncBackupAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/AsyncBackupAspect.aj @@ -3,14 +3,14 @@ package org.zstack.core.aspect; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.header.core.workflow.FlowRollback; -import org.zstack.header.errorcode.ErrorCodeList; -import org.zstack.header.errorcode.OperationFailureException; import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; -import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.*; +import org.zstack.header.core.workflow.FlowRollback; +import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.message.Message; import org.zstack.utils.DebugUtils; @@ -247,4 +247,13 @@ public aspect AsyncBackupAspect { backup(completion.getBackups(), t); } } + + boolean around(org.zstack.header.core.AbstractCompletion completion) : this(completion) && execution(boolean org.zstack.core.thread.CancelablePeriodicTask+.run()) { + try { + return proceed(completion); + } catch (Throwable t) { + backup(completion.getBackups(), t); + return true; + } + } } diff --git a/core/src/main/java/org/zstack/core/aspect/BackAspect.aj b/core/src/main/java/org/zstack/core/aspect/BackAspect.aj index 2f6cf54e83c..bf5d05d4b21 100644 --- a/core/src/main/java/org/zstack/core/aspect/BackAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/BackAspect.aj @@ -21,7 +21,7 @@ public aspect BackAspect { private void setMsgDeadline() { if (TaskContext.containsTaskContext("__messagedeadline__")) { long deadline = Long.parseLong((String) TaskContext.getTaskContext().get("__messagedeadline__")); - if (deadline < System.currentTimeMillis()) { + if (deadline < System.currentTimeMillis() + 1000) { TaskContext.getTaskContext().put("__messagedeadline__", String.valueOf(deadline + TimeUtils.parseTimeInMillis("30m"))); TaskContext.getTaskContext().put("__messagetimeout__", String.valueOf(TimeUtils.parseTimeInMillis("30m"))); } diff --git a/core/src/main/java/org/zstack/core/aspect/CompletionSingleCallAspect.aj b/core/src/main/java/org/zstack/core/aspect/CompletionSingleCallAspect.aj index 8b42e319139..a871d7493cd 100755 --- a/core/src/main/java/org/zstack/core/aspect/CompletionSingleCallAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/CompletionSingleCallAspect.aj @@ -53,7 +53,7 @@ public aspect CompletionSingleCallAspect { proceed(completion); } - pointcut haSuccess() : execution(void org.zstack.header.core.HaCheckerCompletion+.success()); + pointcut haSuccess() : execution(void org.zstack.header.core.HaCheckerCompletion+.success(*)); pointcut haFail() : execution(void org.zstack.header.core.HaCheckerCompletion+.fail(*)); pointcut haNoWay() : execution(void org.zstack.header.core.HaCheckerCompletion+.noWay()); pointcut haNotStable() : execution(void org.zstack.header.core.HaCheckerCompletion+.notStable()); diff --git a/core/src/main/java/org/zstack/core/aspect/DbDeadlockAspect.aj b/core/src/main/java/org/zstack/core/aspect/DbDeadlockAspect.aj index 91a0ee7a801..91836c9b326 100755 --- a/core/src/main/java/org/zstack/core/aspect/DbDeadlockAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/DbDeadlockAspect.aj @@ -1,6 +1,6 @@ package org.zstack.core.aspect; -import com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException; +import java.sql.SQLTransactionRollbackException; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.db.DatabaseGlobalProperty; import org.zstack.utils.DebugUtils; @@ -51,7 +51,7 @@ public aspect DbDeadlockAspect { Throwable root = DebugUtils.getRootCause(re); - if (root instanceof MySQLTransactionRollbackException && root.getMessage().contains("Deadlock")) { + if (root instanceof SQLTransactionRollbackException && root.getMessage().contains("Deadlock")) { logger.warn("deadlock happened, retry"); DatabaseFacadeImpl.increaseDeadlock(); try { diff --git a/core/src/main/java/org/zstack/core/aspect/EncryptColumnAspect.aj b/core/src/main/java/org/zstack/core/aspect/EncryptColumnAspect.aj index 4133bcc6ca4..53cdf8abae2 100644 --- a/core/src/main/java/org/zstack/core/aspect/EncryptColumnAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/EncryptColumnAspect.aj @@ -2,21 +2,21 @@ package org.zstack.core.aspect; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.EntityMetadata; import org.zstack.header.core.encrypt.EncryptAfterSaveDbRecordExtensionPoint; -import org.zstack.header.core.encrypt.EncryptColumn; +import org.zstack.header.core.encrypt.IntegrityVerificationResourceFactory; import org.zstack.header.vo.ResourceVO; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import javax.persistence.EntityManager; -import java.lang.reflect.Field; /** * @Author: DaoDao * @Date: 2021/12/2 */ public aspect EncryptColumnAspect { - private static final CLogger logger = Utils.getLogger(OwnedByAccountAspect.class); + private static final CLogger logger = Utils.getLogger(EncryptColumnAspect.class); @Autowired protected PluginRegistry pluginRegistry; @@ -24,27 +24,32 @@ public aspect EncryptColumnAspect { after(EntityManager mgr, Object entity) : call(void EntityManager+.persist(Object)) && target(mgr) && args(entity) { - Field[] fields = entity.getClass().getDeclaredFields(); - for (Field field : fields) { - if (field.getAnnotation(EncryptColumn.class) != null) { - ResourceVO resourceVO = (ResourceVO) entity; - pluginRegistry.getExtensionList(EncryptAfterSaveDbRecordExtensionPoint.class).forEach(point -> point.encryptAfterSaveDbRecord(resourceVO)); + for (IntegrityVerificationResourceFactory f : pluginRegistry.getExtensionList(IntegrityVerificationResourceFactory.class)) { + if (entity.getClass().getSimpleName().equals(f.getResourceType())) { + f.doIntegrityAfterSaveDbRecord(entity); break; } } + + if (EntityMetadata.hasEncryptField(entity.getClass())) { + ResourceVO resourceVO = (ResourceVO) entity; + pluginRegistry.getExtensionList(EncryptAfterSaveDbRecordExtensionPoint.class).forEach(point -> point.encryptAfterSaveDbRecord(resourceVO)); + } } after(EntityManager mgr, Object entity) : call(* EntityManager+.merge(Object)) && target(mgr) && args(entity) { - Field[] fields = entity.getClass().getDeclaredFields(); - for (Field field : fields) { - if (field.getAnnotation(EncryptColumn.class) != null) { - ResourceVO resourceVO = (ResourceVO) entity; - pluginRegistry.getExtensionList(EncryptAfterSaveDbRecordExtensionPoint.class).forEach(point -> point.encryptAfterUpdateDbRecord(resourceVO)); + for (IntegrityVerificationResourceFactory f : pluginRegistry.getExtensionList(IntegrityVerificationResourceFactory.class)) { + if (entity.getClass().getSimpleName().equals(f.getResourceType())) { + f.doIntegrityAfterUpdateDbRecord(entity); break; } } - } + if (EntityMetadata.hasEncryptField(entity.getClass())) { + ResourceVO resourceVO = (ResourceVO) entity; + pluginRegistry.getExtensionList(EncryptAfterSaveDbRecordExtensionPoint.class).forEach(point -> point.encryptAfterUpdateDbRecord(resourceVO)); + } + } } diff --git a/core/src/main/java/org/zstack/core/aspect/ExceptionSafeAspect.aj b/core/src/main/java/org/zstack/core/aspect/ExceptionSafeAspect.aj index 7b71a25cc8f..c52775e6044 100755 --- a/core/src/main/java/org/zstack/core/aspect/ExceptionSafeAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/ExceptionSafeAspect.aj @@ -1,16 +1,30 @@ package org.zstack.core.aspect; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.header.errorcode.ErrorableValue; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; public aspect ExceptionSafeAspect { private static final CLogger logger = Utils.getLogger(ExceptionSafeAspect.class); - void around() : execution(@org.zstack.header.core.ExceptionSafe * *.*(..)) { + @Autowired + private ErrorFacade errf; + + void around() : execution(@org.zstack.header.core.ExceptionSafe void *.*(..)) { try { proceed(); } catch (Throwable t) { logger.warn("unhandled exception happened", t); } } + + ErrorableValue around() : execution(@org.zstack.header.core.ExceptionSafe ErrorableValue *.*(..)) { + try { + return proceed(); + } catch (Throwable t) { + return ErrorableValue.ofErrorCode(errf.throwableToInternalError(t)); + } + } } diff --git a/core/src/main/java/org/zstack/core/aspect/OwnedByAccountAspect.aj b/core/src/main/java/org/zstack/core/aspect/OwnedByAccountAspect.aj deleted file mode 100755 index a154949a068..00000000000 --- a/core/src/main/java/org/zstack/core/aspect/OwnedByAccountAspect.aj +++ /dev/null @@ -1,37 +0,0 @@ -package org.zstack.core.aspect; - -import org.zstack.header.identity.AccountResourceRefVO; -import org.zstack.header.identity.AccountResourceRefVO_; -import org.zstack.header.vo.ResourceVO; -import org.zstack.core.db.Q; -import org.zstack.utils.Utils; -import org.zstack.utils.logging.CLogger; -import org.zstack.header.identity.OwnedByAccount; -import javax.persistence.EntityManager; - -public aspect OwnedByAccountAspect { - private static final CLogger logger = Utils.getLogger(OwnedByAccountAspect.class); - - Object around(OwnedByAccount oa) : this(oa) && execution(String OwnedByAccount+.getAccountUuid()) { - Object accountUuid = proceed(oa); - - if (accountUuid == null) { - accountUuid = Q.New(AccountResourceRefVO.class).select(AccountResourceRefVO_.accountUuid) - .eq(AccountResourceRefVO_.resourceUuid, ((ResourceVO)oa).getUuid()).findValue(); - oa.setAccountUuid((String)accountUuid); - } - - return accountUuid; - } - - after(EntityManager mgr, Object entity) : call(void EntityManager+.persist(Object)) - && target(mgr) - && args(entity) { - if (!(entity instanceof OwnedByAccount)) { - return; - } - - OwnedByAccount oa = (OwnedByAccount) entity; - OwnedByAccountAspectHelper.createAccountResourceRefVO(oa, mgr, entity); - } -} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/aspect/SetThreadContextAspect.aj b/core/src/main/java/org/zstack/core/aspect/SetThreadContextAspect.aj index 674798edf40..7915dd2fa3f 100755 --- a/core/src/main/java/org/zstack/core/aspect/SetThreadContextAspect.aj +++ b/core/src/main/java/org/zstack/core/aspect/SetThreadContextAspect.aj @@ -26,6 +26,8 @@ public aspect SetThreadContextAspect { if (tc.taskContext != null) { TaskContext.setTaskContext(tc.taskContext); + } else { + TaskContext.removeTaskContext(); } } diff --git a/core/src/main/java/org/zstack/core/asyncbatch/While.java b/core/src/main/java/org/zstack/core/asyncbatch/While.java index bf84133f070..9a0fc837826 100755 --- a/core/src/main/java/org/zstack/core/asyncbatch/While.java +++ b/core/src/main/java/org/zstack/core/asyncbatch/While.java @@ -7,10 +7,12 @@ import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.utils.DebugUtils; +import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; /** * Created by xing5 on 2017/3/5. @@ -37,6 +39,14 @@ public While(Collection items) { doneCount.set(items.size()); } + public static While makeRetryWhile(int retryCount) { + int[] array = new int[retryCount]; + for(int i = 0; i < array.length; i++) { + array[i] = i + 1; + } + return new While<>(Arrays.stream(array).mapToObj(Integer::valueOf).collect(Collectors.toList())); + } + public While each(Do consumer) { mode = WhileMode.EACH; this.consumer = consumer; @@ -112,7 +122,7 @@ public void run(WhileDoneCompletion completion) { } break; default: - DebugUtils.Assert(false, "should be here"); + DebugUtils.Assert(false, "should not be here"); break; } } diff --git a/core/src/main/java/org/zstack/core/captcha/APIRefreshCaptchaMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/captcha/APIRefreshCaptchaMsgDoc_zh_cn.groovy index cbcdf0c042e..6eb59085192 100644 --- a/core/src/main/java/org/zstack/core/captcha/APIRefreshCaptchaMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/captcha/APIRefreshCaptchaMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/core/src/main/java/org/zstack/core/cas/CasGlobalProperty.java b/core/src/main/java/org/zstack/core/cas/CasGlobalProperty.java new file mode 100644 index 00000000000..516eae9ffa8 --- /dev/null +++ b/core/src/main/java/org/zstack/core/cas/CasGlobalProperty.java @@ -0,0 +1,22 @@ +package org.zstack.core.cas; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +/** + * @Author: DaoDao + * @Date: 2022/8/26 + */ +@GlobalPropertyDefinition +public class CasGlobalProperty { + //The start of the CAS server URL + @GlobalProperty(name="casServerLoginUrl") + public static String casServerLoginUrl; + //Defines the location of the CAS server login URL + @GlobalProperty(name="casServerUrlPrefix") + public static String casServerUrlPrefix; + @GlobalProperty(name="serverName") + public static String serverName; + +} + diff --git a/core/src/main/java/org/zstack/core/cascade/CascadeFacadeImpl.java b/core/src/main/java/org/zstack/core/cascade/CascadeFacadeImpl.java index cabeb66893e..f7dad373ce1 100755 --- a/core/src/main/java/org/zstack/core/cascade/CascadeFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/cascade/CascadeFacadeImpl.java @@ -136,7 +136,8 @@ private void checkForNullElement(Node node, CascadeAction currentAction) { } } - private void collectPathsForAsyncCascade(TreeNode treeNode, boolean init, boolean fullTraverse, CascadeAction action, List result) { + //cascade builds paths one by one, there will be duplicate paths, add mergePaths to merge duplicate paths. + private void collectPathsForAsyncCascade(TreeNode treeNode, boolean init, boolean fullTraverse, CascadeAction action, List result, HashSet mergePaths) { CascadeAction currentAction; Node node = treeNode.node; if (!init) { @@ -156,19 +157,27 @@ private void collectPathsForAsyncCascade(TreeNode treeNode, boolean init, boolea } for (TreeNode tn : treeNode.leafs) { - collectPathsForAsyncCascade(tn, false, true, currentAction, result); + collectPathsForAsyncCascade(tn, false, true, currentAction, result, mergePaths); } } else { if (currentAction != null) { checkForNullElement(node, currentAction); for (TreeNode tn : treeNode.leafs) { - collectPathsForAsyncCascade(tn, false, false, currentAction, result); + collectPathsForAsyncCascade(tn, false, false, currentAction, result, mergePaths); } } } - result.add(Bucket.newBucket(node, action)); + String cascadePath = getCascadePath(action.getParentIssuer(), node.getName()); + if (!mergePaths.contains(cascadePath)) { + mergePaths.add(cascadePath); + result.add(Bucket.newBucket(node, action)); + } + } + + private String getCascadePath(String cactionParentIssuer, String nodeName) { + return String.format("%s_%s", cactionParentIssuer, nodeName); } @Override @@ -204,12 +213,13 @@ public void asyncCascade(CascadeAction action, final Completion completion) { TreeNode root = cascadeTree.get(action.getRootIssuer()); DebugUtils.Assert(root != null, String.format("found no CascadeExtension for %s", action.getRootIssuer())); List paths = new ArrayList<>(); - collectPathsForAsyncCascade(root, true, action.isFullTraverse(), action, paths); + collectPathsForAsyncCascade(root, true, action.isFullTraverse(), action, paths, new HashSet<>()); FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); for (Bucket path : paths) { final Node node = path.get(0); final CascadeAction caction = path.get(1); chain.then(new NoRollbackFlow() { + String __name__ = String.format("async-cascade(%s)[%s --> %s]", caction.getActionCode(), caction.getParentIssuer(), node.getName()); @Override public void run(final FlowTrigger trigger, Map data) { logger.debug(String.format("[Async cascade (%s)]: %s --> %s", @@ -267,6 +277,7 @@ private void runNode(Node node, CascadeAction caction, Completion completion) { FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName(String.format("branch-cascade-extension-points-for-%s", node.getName())); branches.forEach(b -> chain.then(new NoRollbackFlow() { + String __name__ = String.format("branch-asycascade-extension-points-for-%s", b.getCascadeResourceName()); @Override public void run(FlowTrigger trigger, Map data) { b.asyncCascade(caction, new Completion(trigger) { diff --git a/core/src/main/java/org/zstack/core/cloudbus/CloudBus.java b/core/src/main/java/org/zstack/core/cloudbus/CloudBus.java index e19a575c63a..2ae626dcebf 100755 --- a/core/src/main/java/org/zstack/core/cloudbus/CloudBus.java +++ b/core/src/main/java/org/zstack/core/cloudbus/CloudBus.java @@ -3,6 +3,7 @@ import org.springframework.http.HttpEntity; import org.zstack.header.Component; import org.zstack.header.Service; +import org.zstack.header.core.FutureCompletion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudConfigureFailException; import org.zstack.header.message.*; @@ -12,13 +13,19 @@ import java.util.function.Consumer; public interface CloudBus extends Component { - void send(Message msg); + /** + * submit a message sending task into the queue. + * @return {@link FutureCompletion} which can be used to check whether the message was successfully sent or not. + */ + + FutureCompletion send(Message msg); void send(List msgs); + @Deprecated void send(APIMessage msg, Consumer consumer); - void send(NeedReplyMessage msg, CloudBusCallBack callback); + FutureCompletion send(NeedReplyMessage msg, CloudBusCallBack callback); @Deprecated void send(List msgs, CloudBusListCallBack callBack); diff --git a/core/src/main/java/org/zstack/core/cloudbus/CloudBusGson.java b/core/src/main/java/org/zstack/core/cloudbus/CloudBusGson.java index f90c2143765..5c2b17f1179 100755 --- a/core/src/main/java/org/zstack/core/cloudbus/CloudBusGson.java +++ b/core/src/main/java/org/zstack/core/cloudbus/CloudBusGson.java @@ -47,7 +47,7 @@ public boolean shouldSkipClass(Class aClass) { return false; } } - }).create(); + }).enableComplexMapKeySerialization().create(); private static Gson logSafeGson = new GsonUtil().setCoder(Message.class, new GsonTypeCoder() { @@ -82,7 +82,7 @@ public boolean shouldSkipField(FieldAttributes f) { public boolean shouldSkipClass(Class clazz) { return false; } - }).create(); + }).enableComplexMapKeySerialization().create(); private static Gson httpGson = new GsonUtil().setCoder(Message.class, new GsonTypeCoder() { diff --git a/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java b/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java index dbc4f9fc1ed..579a78e4860 100755 --- a/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java +++ b/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl2.java @@ -19,6 +19,7 @@ import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.Constants; import org.zstack.header.Service; +import org.zstack.header.core.FutureCompletion; import org.zstack.header.log.NoLogging; import org.zstack.header.apimediator.APIIsReadyToGoMsg; import org.zstack.header.apimediator.APIIsReadyToGoReply; @@ -105,6 +106,11 @@ public class CloudBusImpl2 implements CloudBus, CloudBusIN, ManagementNodeChange private final String AMQP_PROPERTY_HEADER__COMPRESSED = "compressed"; private String SERVICE_ID = makeLocalServiceId("cloudbus"); + public static final FutureCompletion SEND_CONFIRMED = new FutureCompletion(null); + + static { + SEND_CONFIRMED.success(); + } public void setDEFAULT_MESSAGE_TIMEOUT(long timeout) { this.DEFAULT_MESSAGE_TIMEOUT = timeout; @@ -158,6 +164,7 @@ private void retry(Message msg) { TimeUnit.SECONDS.sleep(CloudBusGlobalProperty.RABBITMQ_RETRY_DELAY_ON_RETURN); } catch (InterruptedException e) { logger.warn(e.getMessage(), e); + Thread.currentThread().interrupt(); } if (msg instanceof Event) { @@ -213,6 +220,7 @@ Channel acquire() { DebugUtils.Assert(chan!=null, String.format("cannot get a channel after 10 minutes")); return chan; } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } } @@ -225,7 +233,7 @@ void destruct() throws IOException { for (Channel chan : pool) { try { chan.close(); - } catch (IOException e) { + } catch (IOException | TimeoutException e) { chan.abort(); } } @@ -275,7 +283,7 @@ public void construct() { public void destruct() { try { nrouteChan.close(); - } catch (IOException e) { + } catch (IOException | TimeoutException e) { throw new CloudRuntimeException(e); } } @@ -477,6 +485,7 @@ private boolean recoverSend() throws IOException { TimeUnit.SECONDS.sleep(interval); } catch (InterruptedException e1) { logger.warn(e1.getMessage()); + Thread.currentThread().interrupt(); } try { @@ -748,7 +757,7 @@ public void construct() { public void destruct() { try { eventChan.close(); - } catch (IOException e) { + } catch (IOException | TimeoutException e) { throw new CloudRuntimeException(e); } } @@ -1220,6 +1229,11 @@ public Address call(String arg) { public void handleRecovery(Recoverable recoverable) { logger.info(String.format("rabbitmq connection is recovering on %s", conn.getAddress().toString())); } + + @Override + public void handleRecoveryStarted(Recoverable recoverable) { + logger.info(String.format("start to recover rabbitmq connection on %s", conn.getAddress().toString())); + } }); channelPool = new ChannelPool(CloudBusGlobalProperty.CHANNEL_POOL_SIZE, conn); @@ -1319,8 +1333,9 @@ private void send(Message msg, Boolean noNeedReply) { } @Override - public void send(Message msg) { + public FutureCompletion send(Message msg) { send(msg, true); + return SEND_CONFIRMED; } @Override @@ -1350,7 +1365,7 @@ private void evaluateMessageTimeout(NeedReplyMessage msg) { } @Override - public void send(final NeedReplyMessage msg, final CloudBusCallBack callback) { + public FutureCompletion send(final NeedReplyMessage msg, final CloudBusCallBack callback) { evaluateMessageTimeout(msg); Envelope e = new Envelope() { @@ -1401,6 +1416,7 @@ List getRequests() { envelopes.put(msg.getId(), e); send(msg, false); + return SEND_CONFIRMED; } private MessageReply createTimeoutReply(NeedReplyMessage m) { @@ -1828,6 +1844,7 @@ List getRequests() { try { e.wait(msg.getTimeout()); } catch (InterruptedException e1) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e1); } } @@ -1924,6 +1941,7 @@ List getRequests() { try { e.wait(minTimeout); } catch (InterruptedException e1) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e1); } } @@ -2102,7 +2120,7 @@ public void inactive() { } echan.close(); echan = null; - } catch (IOException e1) { + } catch (IOException | TimeoutException e1) { try { if (echan != null) { echan.abort(); diff --git a/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java b/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java index 3416ee6a417..1a228ef7af7 100755 --- a/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java +++ b/core/src/main/java/org/zstack/core/cloudbus/CloudBusImpl3.java @@ -101,6 +101,7 @@ public class CloudBusImpl3 implements CloudBus, CloudBusIN { private final static TimeoutRestTemplate http = RESTFacade.createRestTemplate(CoreGlobalProperty.REST_FACADE_READ_TIMEOUT, CoreGlobalProperty.REST_FACADE_CONNECT_TIMEOUT); public static final String HTTP_BASE_URL = "/cloudbus"; + public static final FutureCompletion SEND_CONFIRMED = new FutureCompletion(null); { if (CloudBusGlobalProperty.MESSAGE_LOG != null) { @@ -110,10 +111,12 @@ public class CloudBusImpl3 implements CloudBus, CloudBusIN { } } - if (CoreGlobalProperty.UNIT_TEST_ON && !CoreGlobalProperty.SIMULATORS_ON) { + if (CoreGlobalProperty.UNIT_TEST_ON && !Platform.isSimulatorOn()) { CloudBusGlobalProperty.HTTP_CONTEXT_PATH = ""; CloudBusGlobalProperty.HTTP_PORT = 8989; } + + SEND_CONFIRMED.success(); } public static String getManagementNodeUUIDFromServiceID(String serviceID) { @@ -125,6 +128,12 @@ public static String getManagementNodeUUIDFromServiceID(String serviceID) { return ss[0]; } + private FutureCompletion sendFail(ErrorCode errorCode) { + FutureCompletion c = new FutureCompletion(null); + c.fail(errorCode); + return c; + } + private abstract class Envelope { long startTime; @@ -250,8 +259,8 @@ public void deActiveService(String id) { } @Override - public void send(Message msg) { - send(msg, true); + public FutureCompletion send(Message msg) { + return send(msg, true); } @Override @@ -291,8 +300,12 @@ private MessageReply createTimeoutReply(NeedReplyMessage m) { } @Override - public void send(NeedReplyMessage msg, CloudBusCallBack callback) { + public FutureCompletion send(NeedReplyMessage msg, CloudBusCallBack callback) { evaluateMessageTimeout(msg); + if (msg.getTimeout() <= 1) { + callback.run(createTimeoutReply(msg)); + return SEND_CONFIRMED; + } Envelope e = new Envelope() { final AtomicBoolean called = new AtomicBoolean(false); @@ -342,7 +355,7 @@ public void timeout() { envelopes.put(msg.getId(), e); msgExts.forEach(m -> m.afterAddEnvelopes(msg.getId())); - send(msg, false); + return send(msg, false); } @Override @@ -522,29 +535,36 @@ public MessageSender(Message msg) { localSend = !CloudBusGlobalProperty.HTTP_ALWAYS && managementNodeId.equals(Platform.getManagementServerId()); } - void send() { + FutureCompletion send() { try { - doSend(); + return doSend(); } catch (Throwable th) { - replyErrorIfNeeded(operr(th.getMessage())); + ErrorCode err = operr(th.getMessage()); + replyErrorIfNeeded(err); + + FutureCompletion c = new FutureCompletion(null); + c.fail(err); + return c; } } - private void doSend() { + private FutureCompletion doSend() { if (msg instanceof Event) { eventSend(); - return; + return SEND_CONFIRMED; } if (localSend) { localSend(); + return SEND_CONFIRMED; } else { - httpSend(); + return httpSend(); } } - private void httpSendInQueue(String ip) { - thdf.chainSubmit(new ChainTask(null) { + private FutureCompletion httpSendInQueue(String ip) { + FutureCompletion sendCompletion = new FutureCompletion(null); + thdf.chainSubmit(new ChainTask(sendCompletion) { @Override public String getSyncSignature() { return "http-send-in-queue"; @@ -553,6 +573,7 @@ public String getSyncSignature() { @Override public void run(SyncTaskChain chain) { httpSend(ip); + sendCompletion.success(); chain.next(); } @@ -566,25 +587,29 @@ public String getName() { return getSyncSignature(); } }); + return sendCompletion; } - private void httpSend() { + private FutureCompletion httpSend() { buildSchema(msg); + String ip; try { - String ip = destMaker.getNodeInfo(managementNodeId).getNodeIP(); - httpSendInQueue(ip); + ip = destMaker.getNodeInfo(managementNodeId).getNodeIP(); } catch (ManagementNodeNotFoundException e) { - if (msg instanceof MessageReply) { - if (!deadMessageManager.handleManagementNodeNotFoundError(managementNodeId, msg, () -> { - String ip = destMaker.getNodeInfo(managementNodeId).getNodeIP(); - httpSendInQueue(ip); - })) { - throw e; - } + boolean errorHandled = msg instanceof MessageReply && + deadMessageManager.handleManagementNodeNotFoundError(managementNodeId, msg, () -> { + String otherIp = destMaker.getNodeInfo(managementNodeId).getNodeIP(); + logger.warn(String.format("resend the message[id:%s] to node[ip:%s]", msg.getId(), otherIp)); + httpSendInQueue(otherIp); + }); + if (errorHandled) { + return SEND_CONFIRMED; } else { throw e; } } + + return httpSendInQueue(ip); } private void httpSend(String ip) { @@ -676,6 +701,11 @@ public void run(MessageReply reply) { }); future.await(SYNC_CALL_TIMEOUT); + if (!future.isSuccess()) { + MessageReply reply = new MessageReply(); + reply.setError(future.getErrorCode()); + return reply; + } return future.getResult(); } @@ -692,6 +722,15 @@ public void run(List replies) { }); future.await(SYNC_CALL_TIMEOUT); + if (!future.isSuccess()) { + List replies = new ArrayList<>(msgs.size()); + msgs.forEach(msg -> { + MessageReply reply = new MessageReply(); + reply.setError(future.getErrorCode()); + replies.add(reply); + }); + return replies; + } return future.getResult(); } @@ -707,10 +746,9 @@ private void setThreadLoggingContext(Message msg) { ThreadContext.putAll(ctx); } - if (!ThreadContext.containsKey(Constants.THREAD_CONTEXT_API)) { - if (!ThreadContext.containsKey(Constants.THREAD_CONTEXT_TASK)) { - ThreadContext.put(Constants.THREAD_CONTEXT_TASK, msg.getId()); - } + if (!ThreadContext.containsKey(Constants.THREAD_CONTEXT_API) + && (!ThreadContext.containsKey(Constants.THREAD_CONTEXT_TASK))) { + ThreadContext.put(Constants.THREAD_CONTEXT_TASK, msg.getId()); } } @@ -1025,7 +1063,9 @@ public void installBeforeDeliveryMessageInterceptor(BeforeDeliveryMessageInterce int order = 0; for (BeforeDeliveryMessageInterceptor i : beforeDeliveryMessageInterceptorsForAll) { if (i.orderOfBeforeDeliveryMessageInterceptor() <= interceptor.orderOfBeforeDeliveryMessageInterceptor()) { - order = beforeDeliveryMessageInterceptorsForAll.indexOf(i); + // move new interceptor's position + order = beforeDeliveryMessageInterceptorsForAll.indexOf(i) + 1; + } else { break; } } @@ -1189,7 +1229,7 @@ private void evalThreadContextToMessage(Message msg) { } } - private void doSendAndCallExtensions(Message msg) { + private FutureCompletion doSendAndCallExtensions(Message msg) { // for unit test finding invocation chain MessageCommandRecorder.record(msg.getClass()); @@ -1204,20 +1244,20 @@ private void doSendAndCallExtensions(Message msg) { interceptor.beforeSendMessage(msg); } - doSend(msg); + return doSend(msg); } - private void doSend(Message msg) { + private FutureCompletion doSend(Message msg) { evalThreadContextToMessage(msg); if (logger.isTraceEnabled() && islogMessage(msg)) { logger.trace(String.format("[msg send]: %s", dumpMessage(msg))); } - new MessageSender(msg).send(); + return new MessageSender(msg).send(); } - private void send(Message msg, Boolean noNeedReply) { + private FutureCompletion send(Message msg, Boolean noNeedReply) { if (msg.getServiceId() == null) { throw new IllegalArgumentException(String.format("service id cannot be null: %s", msg.getClass().getName())); } @@ -1233,7 +1273,7 @@ private void send(Message msg, Boolean noNeedReply) { msg.putHeaderEntry(NO_NEED_REPLY_MSG, noNeedReply.toString()); } - doSendAndCallExtensions(msg); + return doSendAndCallExtensions(msg); } private void restoreFromSchema(Message msg, Map raw) throws ClassNotFoundException { diff --git a/core/src/main/java/org/zstack/core/componentloader/BannedModule.java b/core/src/main/java/org/zstack/core/componentloader/BannedModule.java new file mode 100644 index 00000000000..0f9fbd1155b --- /dev/null +++ b/core/src/main/java/org/zstack/core/componentloader/BannedModule.java @@ -0,0 +1,15 @@ +package org.zstack.core.componentloader; + +import java.util.ArrayList; +import java.util.List; + +public interface BannedModule { + List bannedModules = new ArrayList(); + + default boolean isBannedModule(String moduleName){ + if (bannedModules == null || bannedModules.isEmpty()) { + return false; + } + return bannedModules.stream().anyMatch(moduleName::startsWith); + } +} diff --git a/core/src/main/java/org/zstack/core/componentloader/PluginRegistryImpl.java b/core/src/main/java/org/zstack/core/componentloader/PluginRegistryImpl.java index 04887dd22d6..ffba155f80f 100755 --- a/core/src/main/java/org/zstack/core/componentloader/PluginRegistryImpl.java +++ b/core/src/main/java/org/zstack/core/componentloader/PluginRegistryImpl.java @@ -10,10 +10,9 @@ import org.zstack.utils.logging.CLoggerImpl; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -public class PluginRegistryImpl implements PluginRegistryIN { +public class PluginRegistryImpl implements PluginRegistryIN, BannedModule { private static final CLogger logger = CLoggerImpl.getLogger(PluginRegistryImpl.class); private Map> extensions = new HashMap<>(); private Map> extensionsByInterfaceName = new HashMap<>(); @@ -23,13 +22,8 @@ public class PluginRegistryImpl implements PluginRegistryIN { private void sortPlugins() { for (List exts : extensionsByInterfaceName.values()) { - Collections.sort(exts, new Comparator() { - @Override - public int compare(PluginExtension o1, PluginExtension o2) { - // greater order means the position is more proceeding in plugin list - return o2.getOrder() - o1.getOrder(); - } - }); + // greater order means the position is more proceeding in plugin list + exts.sort(Comparator.comparingInt(PluginExtension::getOrder).reversed()); } } @@ -52,9 +46,14 @@ private void buildPluginTree() { } ext.setInstance(instance); + String extModuleName = ext.getInstance().getClass().getCanonicalName(); + if (isBannedModule(extModuleName)) { + continue; + } + if (!interfaceClass.isInstance(ext.getInstance())) { throw new IllegalArgumentException(String.format("%s is not an instance of the interface %s", - ext.getInstance().getClass().getCanonicalName(), interfaceClass.getName())); + extModuleName, interfaceClass.getName())); } List exts = extensionsByInterfaceName.get(ext.getReferenceInterface()); diff --git a/core/src/main/java/org/zstack/core/config/APIGetGlobalConfigOptionsMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIGetGlobalConfigOptionsMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..f23b68ff555 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIGetGlobalConfigOptionsMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.core.config + +import org.zstack.core.config.APIGetGlobalConfigOptionsReply + +doc { + title "GetGlobalConfigOptions" + + category "globalConfig" + + desc """获取全局配置参数选项""" + + rest { + request { + url "GET /v1/global-configurations/{category}/{name}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetGlobalConfigOptionsMsg.class + + desc """""" + + params { + + column { + name "category" + enclosedIn "" + desc "" + location "url" + type "String" + optional false + since "4.4.0" + } + column { + name "name" + enclosedIn "" + desc "资源名称" + location "url" + type "String" + optional false + since "4.4.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.4.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.4.0" + } + } + } + + response { + clz APIGetGlobalConfigOptionsReply.class + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/config/APIGetGlobalConfigOptionsReplyDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIGetGlobalConfigOptionsReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..149a3435c49 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIGetGlobalConfigOptionsReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.core.config + +import org.zstack.header.errorcode.ErrorCode +import org.zstack.core.config.GlobalConfigOptions + +doc { + + title "获取全局配置可用值" + + field { + name "success" + desc "" + type "boolean" + since "4.4.0" + } + ref { + name "error" + path "org.zstack.core.config.APIGetGlobalConfigOptionsReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.4.0" + clz ErrorCode.class + } + ref { + name "options" + path "org.zstack.core.config.APIGetGlobalConfigOptionsReply.options" + desc "null" + type "GlobalConfigOptions" + since "4.4.0" + clz GlobalConfigOptions.class + } +} diff --git a/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataMsg.java b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataMsg.java new file mode 100644 index 00000000000..4db8293e379 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataMsg.java @@ -0,0 +1,17 @@ +package org.zstack.core.config; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/guest-os/metadata", + method = HttpMethod.GET, + responseClass = APIGetGuestOsMetadataReply.class +) +public class APIGetGuestOsMetadataMsg extends APISyncCallMessage { + public static APIGetGuestOsMetadataMsg __example__() { + APIGetGuestOsMetadataMsg msg = new APIGetGuestOsMetadataMsg(); + return msg; + } +} diff --git a/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..33f1ffe42d3 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.core.config + +import org.zstack.core.config.APIGetGuestOsMetadataReply + +doc { + title "GetGuestOsMetadata" + + category "globalConfig" + + desc """获取虚拟机操作系统元数据""" + + rest { + request { + url "GET /v1/guest-os/metadata" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetGuestOsMetadataMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIGetGuestOsMetadataReply.class + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataReply.java b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataReply.java new file mode 100644 index 00000000000..083afe44221 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataReply.java @@ -0,0 +1,27 @@ +package org.zstack.core.config; + +import com.google.common.collect.Lists; +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIGetGuestOsMetadataReply extends APIReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIGetGuestOsMetadataReply __example__() { + APIGetGuestOsMetadataReply reply = new APIGetGuestOsMetadataReply(); + GuestOsCharacterInventory inventory = GuestOsCharacterInventory.__example__(); + reply.setInventories(Lists.newArrayList(inventory)); + return reply; + } +} diff --git a/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataReplyDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..d0d3bc3d3cd --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIGetGuestOsMetadataReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.core.config + +import org.zstack.core.config.GuestOsCharacterInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取虚拟机操作系统元数据的返回" + + ref { + name "inventories" + path "org.zstack.core.config.APIGetGuestOsMetadataReply.inventories" + desc "null" + type "List" + since "5.1.0" + clz GuestOsCharacterInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.core.config.APIGetGuestOsMetadataReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/core/src/main/java/org/zstack/core/config/APIQueryGlobalConfigMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIQueryGlobalConfigMsgDoc_zh_cn.groovy index 8345739c295..d9a127a462a 100644 --- a/core/src/main/java/org/zstack/core/config/APIQueryGlobalConfigMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/config/APIQueryGlobalConfigMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.core.config import org.zstack.core.config.APIQueryGlobalConfigReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryGlobalConfig" diff --git a/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataEvent.java b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataEvent.java new file mode 100644 index 00000000000..b7dd2dd6c5f --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataEvent.java @@ -0,0 +1,14 @@ +package org.zstack.core.config; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIRefreshGuestOsMetadataEvent extends APIEvent { + public APIRefreshGuestOsMetadataEvent() { + } + + public APIRefreshGuestOsMetadataEvent(String apiId) { + super(apiId); + } +} diff --git a/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataEventDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..9ac94059820 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.core.config + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "刷新虚拟机操作系统元数据的返回" + + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.core.config.APIRefreshGuestOsMetadataEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataMsg.java b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataMsg.java new file mode 100644 index 00000000000..33bec530c3c --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataMsg.java @@ -0,0 +1,22 @@ +package org.zstack.core.config; + +import org.springframework.http.HttpMethod; +import org.zstack.header.configuration.ConfigurationConstant; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.rest.RestRequest; + +@Action(category = ConfigurationConstant.ACTION_CATEGORY) +@RestRequest( + path = "/guest-os/metadata/actions", + isAction = true, + method = HttpMethod.PUT, + responseClass = APIRefreshGuestOsMetadataEvent.class +) +public class APIRefreshGuestOsMetadataMsg extends APIMessage { + public static APIRefreshGuestOsMetadataMsg __example__() { + APIRefreshGuestOsMetadataMsg msg = new APIRefreshGuestOsMetadataMsg(); + return msg; + } +} + diff --git a/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..6498e03a0f7 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/APIRefreshGuestOsMetadataMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.core.config + +import org.zstack.core.config.APIRefreshGuestOsMetadataEvent + +doc { + title "RefreshGuestOsMetadata" + + category "globalConfig" + + desc """刷新虚拟机操作系统元数据""" + + rest { + request { + url "PUT /v1/guest-os/metadata/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIRefreshGuestOsMetadataMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIRefreshGuestOsMetadataEvent.class + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/config/APIResetGlobalConfigMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIResetGlobalConfigMsgDoc_zh_cn.groovy index b58a0c3a018..8800bc26812 100644 --- a/core/src/main/java/org/zstack/core/config/APIResetGlobalConfigMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/config/APIResetGlobalConfigMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "3.1.0" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.1.0" - } } } diff --git a/core/src/main/java/org/zstack/core/config/APIUpdateGlobalConfigMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/APIUpdateGlobalConfigMsgDoc_zh_cn.groovy index e24078fa7be..3e7f0844718 100644 --- a/core/src/main/java/org/zstack/core/config/APIUpdateGlobalConfigMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/config/APIUpdateGlobalConfigMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "value" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/core/src/main/java/org/zstack/core/config/GlobalConfig.java b/core/src/main/java/org/zstack/core/config/GlobalConfig.java index 3dd22b96279..ca6292d7241 100755 --- a/core/src/main/java/org/zstack/core/config/GlobalConfig.java +++ b/core/src/main/java/org/zstack/core/config/GlobalConfig.java @@ -417,10 +417,12 @@ public void updateValue(Object val) { } public GlobalConfigOptions getOptions() { + GlobalConfigOptions configOptions = null; for (GlobalConfigQueryExtensionPoint ext : queryExtensions) { - return ext.getConfigOptions(); + configOptions = ext.getConfigOptions(); + } - return null; + return configOptions; } public void updateValueSkipValidation(Object val) { diff --git a/core/src/main/java/org/zstack/core/config/GlobalConfigExtensionValidValuesPoint.java b/core/src/main/java/org/zstack/core/config/GlobalConfigExtensionValidValuesPoint.java new file mode 100644 index 00000000000..3300710bdc7 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/GlobalConfigExtensionValidValuesPoint.java @@ -0,0 +1,8 @@ +package org.zstack.core.config; + +import java.util.List; +import java.util.Map; + +public interface GlobalConfigExtensionValidValuesPoint { + Map GlobalConfigExtensionValidValues(); +} diff --git a/core/src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java b/core/src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java index 3b9e489eaf7..a1879c38d1a 100755 --- a/core/src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/config/GlobalConfigFacadeImpl.java @@ -1,17 +1,27 @@ package org.zstack.core.config; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.GLock; +import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.AbstractService; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.managementnode.ManagementNodeVO; +import org.zstack.header.managementnode.ManagementNodeVO_; import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; import org.zstack.utils.BeanUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.TypeUtils; @@ -63,11 +73,85 @@ public void handleMessage(Message msg) { handle((APIGetGlobalConfigOptionsMsg) msg); } else if (msg instanceof APIResetGlobalConfigMsg) { handle((APIResetGlobalConfigMsg) msg); + } else if (msg instanceof APIGetGuestOsMetadataMsg) { + handle((APIGetGuestOsMetadataMsg) msg); + } else if (msg instanceof APIRefreshGuestOsMetadataMsg) { + handle((APIRefreshGuestOsMetadataMsg) msg); + } else if (msg instanceof RefreshGuestOsMetadataMsg) { + handle((RefreshGuestOsMetadataMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } + private void handle(APIGetGuestOsMetadataMsg msg) { + APIGetGuestOsMetadataReply reply = new APIGetGuestOsMetadataReply(); + reply.setInventories(GuestOsCharacterInventory + .valueOf(GuestOsHelper + .getInstance() + .getAllGuestOsCharacter())); + bus.reply(msg, reply); + } + + private void handle(RefreshGuestOsMetadataMsg msg) { + GuestOsHelper.getInstance().initGuestOsRelatedDb(); + bus.reply(msg, new RefreshGuestOsMetadataReply()); + } + + private void handle(APIRefreshGuestOsMetadataMsg msg) { + APIRefreshGuestOsMetadataEvent evt = new APIRefreshGuestOsMetadataEvent(msg.getId()); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName("refresh-guest-os-metadata"); + chain.then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + List managementNodeUuids = Q.New(ManagementNodeVO.class) + .select(ManagementNodeVO_.uuid) + .listValues(); + new While<>(managementNodeUuids).each((uuid, wcomp) -> { + RefreshGuestOsMetadataMsg rmsg = new RefreshGuestOsMetadataMsg(); + bus.makeServiceIdByManagementNodeId(rmsg, GlobalConfigConstant.SERVICE_ID, uuid); + bus.send(rmsg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + wcomp.addError(reply.getError()); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList); + return; + } + + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + GuestOsHelper.getInstance().initGuestOsRelatedDb(); + trigger.next(); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.publish(evt); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + evt.setError(errCode); + bus.publish(evt); + } + }).start(); + } + private void handle(APIResetGlobalConfigMsg msg) { APIResetGlobalConfigEvent evt = new APIResetGlobalConfigEvent(msg.getId()); @@ -661,6 +745,7 @@ public void validateGlobalConfig(String category, String name, String oldValue, } } + boolean isInteger = Integer.class.getName().equals(config.getType()); config.installQueryExtension(new GlobalConfigQueryExtensionPoint() { @Override public GlobalConfigOptions getConfigOptions() { @@ -669,18 +754,24 @@ public GlobalConfigOptions getConfigOptions() { if (at.validValues().length > 0) { options.setValidValue(Arrays.asList(at.validValues())); } else if (at.inNumberRange().length == 2){ - options.setNumberLessThan(at.inNumberRange()[1] + 1); - options.setNumberGreaterThan(at.inNumberRange()[0] - 1); + options.setNumberLessThanOrEqual(at.inNumberRange()[1]); + options.setNumberGreaterThanOrEqual(at.inNumberRange()[0]); } else if (at.numberLessThan() != Long.MAX_VALUE || at.numberGreaterThan() != Long.MIN_VALUE) { - options.setNumberLessThan(Long.MAX_VALUE); - options.setNumberGreaterThan(Long.MIN_VALUE); + if (isInteger) { + options.setNumberLessThanOrEqual((long) Integer.MAX_VALUE); + options.setNumberGreaterThanOrEqual((long) Integer.MIN_VALUE); + } else { + options.setNumberLessThanOrEqual(Long.MAX_VALUE); + options.setNumberGreaterThanOrEqual(Long.MIN_VALUE); + } } if (at.numberLessThan() != Long.MAX_VALUE) { - options.setNumberLessThan(at.numberLessThan()); + options.setNumberLessThanOrEqual(at.numberLessThan()); } + if (at.numberGreaterThan() != Long.MIN_VALUE) { - options.setNumberGreaterThan(at.numberGreaterThan()); + options.setNumberGreaterThanOrEqual(at.numberGreaterThan()); } return options; @@ -698,6 +789,9 @@ public GlobalConfigOptions getConfigOptions() { GlobalConfigInitializer initializer = new GlobalConfigInitializer(); initializer.init(); + + GuestOsHelper.getInstance().initGuestOsRelatedDb(); + return true; } diff --git a/core/src/main/java/org/zstack/core/config/GlobalConfigOptions.java b/core/src/main/java/org/zstack/core/config/GlobalConfigOptions.java index 2c35ac6d646..ddb62a08367 100755 --- a/core/src/main/java/org/zstack/core/config/GlobalConfigOptions.java +++ b/core/src/main/java/org/zstack/core/config/GlobalConfigOptions.java @@ -6,6 +6,8 @@ public class GlobalConfigOptions { private List validValue; private Long numberGreaterThan; private Long numberLessThan; + private Long numberGreaterThanOrEqual; + private Long numberLessThanOrEqual; public List getValidValue() { return validValue; @@ -30,4 +32,20 @@ public Long getNumberLessThan() { public void setNumberLessThan(Long numberLessThan) { this.numberLessThan = numberLessThan; } + + public Long getNumberGreaterThanOrEqual() { + return numberGreaterThanOrEqual; + } + + public void setNumberGreaterThanOrEqual(Long numberGreaterThanOrEqual) { + this.numberGreaterThanOrEqual = numberGreaterThanOrEqual; + } + + public Long getNumberLessThanOrEqual() { + return numberLessThanOrEqual; + } + + public void setNumberLessThanOrEqual(Long numberLessThanOrEqual) { + this.numberLessThanOrEqual = numberLessThanOrEqual; + } } diff --git a/core/src/main/java/org/zstack/core/config/GlobalConfigOptionsDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/GlobalConfigOptionsDoc_zh_cn.groovy new file mode 100644 index 00000000000..76c01d72be2 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/GlobalConfigOptionsDoc_zh_cn.groovy @@ -0,0 +1,40 @@ +package org.zstack.core.config + +import java.lang.Long +import java.lang.Long + +doc { + + title "全局配置可选参数的数据结构" + + field { + name "validValue" + desc "" + type "List" + since "4.4.0" + } + field { + name "numberGreaterThan" + desc "" + type "Long" + since "4.4.0" + } + field { + name "numberLessThan" + desc "" + type "Long" + since "4.4.0" + } + field { + name "numberGreaterThanOrEqual" + desc "大于等于" + type "Long" + since "5.2.0" + } + field { + name "numberLessThanOrEqual" + desc "小于等于" + type "Long" + since "5.2.0" + } +} diff --git a/core/src/main/java/org/zstack/core/config/GuestOsCharacterInventory.java b/core/src/main/java/org/zstack/core/config/GuestOsCharacterInventory.java new file mode 100644 index 00000000000..e5ab4618714 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/GuestOsCharacterInventory.java @@ -0,0 +1,120 @@ +package org.zstack.core.config; + +import org.zstack.core.config.schema.GuestOsCharacter; + +import java.util.ArrayList; +import java.util.List; + +public class GuestOsCharacterInventory { + private String architecture; + private String platform; + private String osRelease; + private Boolean acpi; + private Boolean hygonTag; + private Boolean x2apic; + private String cpuModel; + private String nicDriver; + + public GuestOsCharacterInventory() { + } + + public GuestOsCharacterInventory(GuestOsCharacter.Config config) { + this.architecture = config.getArchitecture(); + this.platform = config.getPlatform(); + this.osRelease = config.getOsRelease(); + this.acpi = config.getAcpi(); + this.hygonTag = config.getHygonTag(); + this.x2apic = config.getX2apic(); + this.cpuModel = config.getCpuModel(); + this.nicDriver = config.getNicDriver(); + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getOsRelease() { + return osRelease; + } + + public void setOsRelease(String osRelease) { + this.osRelease = osRelease; + } + + public Boolean getAcpi() { + return acpi; + } + + public void setAcpi(Boolean acpi) { + this.acpi = acpi; + } + + public Boolean getHygonTag() { + return hygonTag; + } + + public void setHygonTag(Boolean hygonTag) { + this.hygonTag = hygonTag; + } + + public Boolean getX2apic() { + return x2apic; + } + + public void setX2apic(Boolean x2apic) { + this.x2apic = x2apic; + } + + public String getCpuModel() { + return cpuModel; + } + + public void setCpuModel(String cpuModel) { + this.cpuModel = cpuModel; + } + + public String getNicDriver() { + return nicDriver; + } + + public void setNicDriver(String nicDriver) { + this.nicDriver = nicDriver; + } + + public static GuestOsCharacterInventory valueOf(GuestOsCharacter.Config config) { + return new GuestOsCharacterInventory(config); + } + + public static List valueOf(List configs) { + List invs = new ArrayList<>(); + for (GuestOsCharacter.Config config : configs) { + invs.add(valueOf(config)); + } + return invs; + } + + public static GuestOsCharacterInventory __example__() { + GuestOsCharacterInventory inventory = new GuestOsCharacterInventory(); + inventory.setArchitecture("x86_64"); + inventory.setPlatform("Linux"); + inventory.setOsRelease("CentOS 7.0"); + inventory.setAcpi(true); + inventory.setHygonTag(false); + inventory.setX2apic(true); + inventory.setCpuModel("Intel Xeon E5-2670"); + inventory.setNicDriver("e1000e"); + return inventory; + } +} diff --git a/core/src/main/java/org/zstack/core/config/GuestOsCharacterInventoryDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/config/GuestOsCharacterInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..40810127d67 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/GuestOsCharacterInventoryDoc_zh_cn.groovy @@ -0,0 +1,57 @@ +package org.zstack.core.config + +import java.lang.Boolean + +doc { + + title "虚拟机操作系统清单" + + field { + name "architecture" + desc "系统架构x86_64, aarch64等" + type "String" + since "5.1.0" + } + field { + name "platform" + desc "平台CentOS, Ubuntu等" + type "String" + since "5.1.0" + } + field { + name "osRelease" + desc "操作系统版本7, 8等" + type "String" + since "5.1.0" + } + field { + name "acpi" + desc "是否启用acpi" + type "Boolean" + since "5.1.0" + } + field { + name "hygonTag" + desc "是否运行在海光处理器上" + type "Boolean" + since "5.1.0" + } + field { + name "x2apic" + desc "是否启用x2apic" + type "Boolean" + since "5.1.0" + } + field { + name "cpuModel" + desc "CPU型号" + type "String" + since "5.1.0" + } + field { + name "nicDriver" + desc "网卡驱动" + type "String" + since "5.1.0" + } +} diff --git a/core/src/main/java/org/zstack/core/config/GuestOsExtensionPoint.java b/core/src/main/java/org/zstack/core/config/GuestOsExtensionPoint.java new file mode 100644 index 00000000000..625243b1192 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/GuestOsExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.core.config; + +import org.zstack.core.config.schema.GuestOsCharacter; + +public interface GuestOsExtensionPoint { + void validateGuestOsCharacter(GuestOsCharacter.Config config); +} diff --git a/core/src/main/java/org/zstack/core/config/GuestOsHelper.java b/core/src/main/java/org/zstack/core/config/GuestOsHelper.java new file mode 100644 index 00000000000..277482b60c6 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/GuestOsHelper.java @@ -0,0 +1,103 @@ +package org.zstack.core.config; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.config.schema.GuestOsCategory; +import org.zstack.core.config.schema.GuestOsCharacter; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.image.GuestOsCategoryVO; +import org.zstack.header.image.GuestOsCategoryVO_; +import org.zstack.utils.path.PathUtil; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Unmarshaller; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class GuestOsHelper { + @Autowired + private DatabaseFacade dbf; + @Autowired + private PluginRegistry pluginRgty; + + private static final GuestOsHelper instance = new GuestOsHelper(); + + public static GuestOsHelper getInstance() { + return instance; + } + + private static final String GUEST_OS_CATEGORY_FILE = "guestOs/guestOsCategory.xml"; + private static final String GUEST_OS_CHARACTER_FILE = "guestOs/guestOsCharacter.xml"; + private static final Map allGuestOsCategory = new ConcurrentHashMap<>(); + private static final Map allGuestOsCharacter = new ConcurrentHashMap<>(); + + public synchronized void initGuestOsRelatedDb() { + initGuestOsCategory(); + initGuestOsCharacter(); + } + + public List getAllGuestOsCharacter() { + return new ArrayList<>(allGuestOsCharacter.values()); + } + + public GuestOsCharacter.Config getGuestOsCharacter(String architecture, String platform, String osRelease) { + return allGuestOsCharacter.get(String.format("%s_%s_%s", architecture, platform, osRelease)); + } + + private void initGuestOsCharacter() { + GuestOsCharacter configs; + File guestOsCharacterFile = PathUtil.findFileOnClassPath(GUEST_OS_CHARACTER_FILE); + try { + JAXBContext context = JAXBContext.newInstance("org.zstack.core.config.schema"); + Unmarshaller unmarshaller = context.createUnmarshaller(); + configs = (GuestOsCharacter) unmarshaller.unmarshal(guestOsCharacterFile); + } catch (Exception e){ + throw new CloudRuntimeException(e); + } + for (GuestOsCharacter.Config config : configs.getOsInfo()) { + validateGuestOsCharacter(config); + allGuestOsCharacter.put(String.format("%s_%s_%s", config.getArchitecture(), config.getPlatform(), config.getOsRelease()), config); + } + } + + private void initGuestOsCategory() { + GuestOsCategory configs; + File guestOsCategoryFile = PathUtil.findFileOnClassPath(GUEST_OS_CATEGORY_FILE); + try { + JAXBContext context = JAXBContext.newInstance("org.zstack.core.config.schema"); + Unmarshaller unmarshaller = context.createUnmarshaller(); + configs = (GuestOsCategory) unmarshaller.unmarshal(guestOsCategoryFile); + } catch (Exception e){ + throw new CloudRuntimeException(e); + } + for (GuestOsCategory.Config config : configs.getOsInfo()) { + allGuestOsCategory.put(config.getOsRelease(), config); + if (!Q.New(GuestOsCategoryVO.class).eq(GuestOsCategoryVO_.osRelease, config.getOsRelease()).isExists()) { + GuestOsCategoryVO vo = new GuestOsCategoryVO(); + vo.setPlatform(config.getPlatform()); + vo.setName(config.getName()); + vo.setVersion(config.getVersion()); + vo.setOsRelease(config.getOsRelease()); + vo.setUuid(Platform.getUuid()); + dbf.persist(vo); + } + } + + //delete release not in config + SQL.New(GuestOsCategoryVO.class).notIn(GuestOsCategoryVO_.osRelease, allGuestOsCategory.keySet()).delete(); + } + + private void validateGuestOsCharacter(GuestOsCharacter.Config config) { + pluginRgty.getExtensionList(GuestOsExtensionPoint.class).forEach(ext -> ext.validateGuestOsCharacter(config)); + } +} diff --git a/core/src/main/java/org/zstack/core/config/RBACInfo.java b/core/src/main/java/org/zstack/core/config/RBACInfo.java index 66d2f39d8d5..2888bd0ebbf 100755 --- a/core/src/main/java/org/zstack/core/config/RBACInfo.java +++ b/core/src/main/java/org/zstack/core/config/RBACInfo.java @@ -9,7 +9,9 @@ public void permissions() { permissionBuilder() .name("global-config") .adminOnlyAPIs("org.zstack.core.config.**") - .normalAPIs(APIQueryGlobalConfigMsg.class) + .normalAPIs( + APIQueryGlobalConfigMsg.class, + APIGetGlobalConfigOptionsMsg.class) .build(); } @@ -17,7 +19,9 @@ public void permissions() { public void contributeToRoles() { roleContributorBuilder() .roleName("other") - .actions(APIQueryGlobalConfigMsg.class) + .actions( + APIQueryGlobalConfigMsg.class, + APIGetGlobalConfigOptionsMsg.class) .build(); } diff --git a/core/src/main/java/org/zstack/core/config/RefreshGuestOsMetadataMsg.java b/core/src/main/java/org/zstack/core/config/RefreshGuestOsMetadataMsg.java new file mode 100644 index 00000000000..8f4952a9618 --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/RefreshGuestOsMetadataMsg.java @@ -0,0 +1,6 @@ +package org.zstack.core.config; + +import org.zstack.header.message.NeedReplyMessage; + +public class RefreshGuestOsMetadataMsg extends NeedReplyMessage { +} diff --git a/core/src/main/java/org/zstack/core/config/RefreshGuestOsMetadataReply.java b/core/src/main/java/org/zstack/core/config/RefreshGuestOsMetadataReply.java new file mode 100644 index 00000000000..b8107100e5e --- /dev/null +++ b/core/src/main/java/org/zstack/core/config/RefreshGuestOsMetadataReply.java @@ -0,0 +1,6 @@ +package org.zstack.core.config; + +import org.zstack.header.message.MessageReply; + +public class RefreshGuestOsMetadataReply extends MessageReply { +} diff --git a/core/src/main/java/org/zstack/core/config/schema/GuestOsCharacter.java b/core/src/main/java/org/zstack/core/config/schema/GuestOsCharacter.java index 6e1a3633abd..ee7df2894cb 100644 --- a/core/src/main/java/org/zstack/core/config/schema/GuestOsCharacter.java +++ b/core/src/main/java/org/zstack/core/config/schema/GuestOsCharacter.java @@ -1,6 +1,7 @@ package org.zstack.core.config.schema; import javax.xml.bind.annotation.*; +import java.io.Serializable; import java.util.List; @XmlAccessorType(XmlAccessType.FIELD) @@ -25,9 +26,12 @@ public void setOsInfo(List osInfo) { "platform", "osRelease", "acpi", - "hygonCpu" + "x2apic", + "cpuModel", + "nicDriver", + "hygonTag", }) - public static class Config { + public static class Config implements Serializable { @XmlElement(required = true) protected String architecture; @@ -40,9 +44,17 @@ public static class Config { @XmlElement(required = false) protected Boolean acpi; - //whether guest need to set EPYC cpu model on Hygon @XmlElement(required = false) - protected Boolean hygonCpu; + protected Boolean hygonTag; + + @XmlElement(required = false) + protected Boolean x2apic; + + @XmlElement(required = false) + protected String cpuModel; + + @XmlElement(required = false) + protected String nicDriver; public String getPlatform() { return platform; @@ -64,10 +76,26 @@ public Boolean getAcpi() { return acpi; } + public Boolean getX2apic() { + return x2apic; + } + public void setAcpi(Boolean acpi) { this.acpi = acpi; } + public void setX2apic(Boolean x2apic) { + this.x2apic = x2apic; + } + + public Boolean getHygonTag() { + return hygonTag; + } + + public void setHygonTag(Boolean hygonTag) { + this.hygonTag = hygonTag; + } + public String getArchitecture() { return architecture; } @@ -76,13 +104,20 @@ public void setArchitecture(String architecture) { this.architecture = architecture; } + public String getCpuModel() { + return cpuModel; + } + + public void setCpuModel(String cpuModel) { + this.cpuModel = cpuModel; + } - public Boolean getHygonCpu() { - return hygonCpu; + public String getNicDriver() { + return nicDriver; } - public void setHygonCpu(Boolean hygonCpu) { - this.hygonCpu = hygonCpu; + public void setNicDriver(String nicDriver) { + this.nicDriver = nicDriver; } } } diff --git a/core/src/main/java/org/zstack/core/convert/SpecialDataConverter.java b/core/src/main/java/org/zstack/core/convert/SpecialDataConverter.java new file mode 100644 index 00000000000..ad63a9ef87e --- /dev/null +++ b/core/src/main/java/org/zstack/core/convert/SpecialDataConverter.java @@ -0,0 +1,87 @@ +package org.zstack.core.convert; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.stereotype.Component; +import org.zstack.core.encrypt.EncryptFacade; +import org.zstack.core.encrypt.EncryptGlobalConfig; +import org.zstack.header.core.encrypt.PasswordEncryptType; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Author: DaoDao + * @Date: 2023/3/9 + */ +@Component +@Converter +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class SpecialDataConverter implements AttributeConverter { + private static final CLogger logger = Utils.getLogger(SpecialDataConverter.class); + + private static EncryptFacade encryptFacade; + + + @Autowired + public void init(EncryptFacade encryptFacade){ + SpecialDataConverter.encryptFacade = encryptFacade; + } + + @Override + public String convertToDatabaseColumn(String attribute) { + if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value(String.class))) { + return attribute; + } + if (StringUtils.isEmpty(attribute)) { + return attribute; + } + + if (!isMobileNO(attribute) && !checkEmail(attribute)) { + return attribute; + } + + return encryptFacade.encrypt(attribute); + } + + @Override + public String convertToEntityAttribute(String dbData) { + if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value(String.class))) { + return dbData; + } + + if (StringUtils.isEmpty(dbData)) { + return dbData ; + } + + return encryptFacade.decrypt(dbData); + } + + public static boolean isMobileNO(String mobiles) { + try { + Pattern p = Pattern + .compile("[1][3456789][0-9]{9}$"); + Matcher m = p.matcher(mobiles); + return m.matches(); + } catch (Exception e) { + return false; + } + } + + public static boolean checkEmail(String email) { + try { + String EMAIL_PATTERN = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"; + Pattern pattern = Pattern.compile(EMAIL_PATTERN);; + Matcher matcher = pattern.matcher(email); + return matcher.matches(); + } catch (Exception e) { + return false; + } + } +} diff --git a/core/src/main/java/org/zstack/core/db/DBGraph.java b/core/src/main/java/org/zstack/core/db/DBGraph.java index 1d3959d64c5..e41b6b779e2 100755 --- a/core/src/main/java/org/zstack/core/db/DBGraph.java +++ b/core/src/main/java/org/zstack/core/db/DBGraph.java @@ -1,8 +1,6 @@ package org.zstack.core.db; import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.util.Strings; -import org.springframework.security.access.method.P; import org.zstack.header.core.StaticInit; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.vo.EntityGraph; @@ -43,6 +41,7 @@ public String toString() { } public static class EntityVertex { + public Class srcClass; public Class entityClass; public String srcKey; public String dstKey; @@ -107,6 +106,39 @@ private static String makeSQL(EntityVertex vertex, String field, SimpleQuery.Op } } + public String toBidirectionalSQL(String field, SimpleQuery.Op op, String value) { + return makeBidirectionalSQL(this, field, op, value); + } + + private static String makeBidirectionalSQL(EntityVertex vertex, String field, SimpleQuery.Op op, String val) { + List from = new ArrayList<>(); + List conditions = new ArrayList<>(); + String srcClassFiled = String.format("%s_.%s", vertex.srcClass.getSimpleName(), field); + while (true) { + String entity = String.format("%s_", vertex.entityClass.getSimpleName()); + String vo = vertex.entityClass.getSimpleName(); + from.add(vo + " " + entity); + + if (vertex.previous == null) { + conditions.add(String.format("%s.%s %s %s", entity, field, op.toString(), val)); + } else { + conditions.add(String.format("%s.%s = %s.%s", + String.format("%s_", vertex.previous.entityClass.getSimpleName()), vertex.previous.srcKey, + entity, vertex.previous.dstKey)); + } + + if (vertex.next != null) { + vertex = vertex.next; + continue; + } + + String primaryKey = vertex.previous != null ? vertex.previous.dstKey : EntityMetadata.getPrimaryKeyField(vertex.entityClass).getName(); + return String.format("select %s.%s,%s from %s where %s", entity, primaryKey, srcClassFiled, + StringUtils.join(from, ", "), + StringUtils.join(conditions, " and ")); + } + } + @Override public String toString() { return "EntityVertex{" + @@ -140,6 +172,7 @@ public static boolean isTwoResourcesConnected(Class src, Class dst) { public static EntityVertex findVerticesWithSmallestWeight(Class src, Class dst) { if (src == dst) { EntityVertex vertex = new EntityVertex(); + vertex.srcClass = src; vertex.entityClass = src; vertex.srcKey = vertex.dstKey = EntityMetadata.getPrimaryKeyField(src).getName(); vertex.previous = vertex; @@ -159,6 +192,7 @@ class Judge { List judges = new ArrayList<>(); all.forEach(lst -> { EntityVertex vertex = new EntityVertex(); + vertex.srcClass = src; Judge j = new Judge(); j.vertex = vertex; judges.add(j); @@ -177,6 +211,7 @@ class Judge { current.next = new EntityVertex(); current.next.entityClass = right.entityClass; current.next.previous = current; + current.next.srcClass = src; current = current.next; left = right; } diff --git a/core/src/main/java/org/zstack/core/db/DBSourceUtils.java b/core/src/main/java/org/zstack/core/db/DBSourceUtils.java index 2f3f873c9f9..350ade52e5d 100644 --- a/core/src/main/java/org/zstack/core/db/DBSourceUtils.java +++ b/core/src/main/java/org/zstack/core/db/DBSourceUtils.java @@ -43,6 +43,8 @@ public static boolean waitDBConnected(int retryTimes, int interval) { private static void sleep(int seconds) { try { TimeUnit.SECONDS.sleep(seconds); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { + Thread.currentThread().interrupt(); + } } } diff --git a/core/src/main/java/org/zstack/core/db/DatabaseFacadeImpl.java b/core/src/main/java/org/zstack/core/db/DatabaseFacadeImpl.java index 6f387cdffe3..d0a92426313 100755 --- a/core/src/main/java/org/zstack/core/db/DatabaseFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/db/DatabaseFacadeImpl.java @@ -1,6 +1,5 @@ package org.zstack.core.db; -import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.NestedExceptionUtils; @@ -26,6 +25,7 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.sql.DataSource; import java.lang.reflect.Field; +import java.sql.SQLIntegrityConstraintViolationException; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.atomic.AtomicLong; @@ -240,11 +240,11 @@ private Object getVOPrimaryKeyValue(Object entity) { private void updateEO(Object entity, RuntimeException de) { Throwable rootCause = NestedExceptionUtils.getRootCause(de); if (rootCause == null - || !MySQLIntegrityConstraintViolationException.class.isAssignableFrom(rootCause.getClass())) { + || !SQLIntegrityConstraintViolationException.class.isAssignableFrom(rootCause.getClass())) { throw de; } - MySQLIntegrityConstraintViolationException me = (MySQLIntegrityConstraintViolationException) rootCause; + SQLIntegrityConstraintViolationException me = (SQLIntegrityConstraintViolationException) rootCause; if (!(me.getErrorCode() == 1062 && "23000".equals(me.getSQLState()) && me.getMessage().contains("PRIMARY"))) { throw de; } diff --git a/core/src/main/java/org/zstack/core/db/EntityMetadata.java b/core/src/main/java/org/zstack/core/db/EntityMetadata.java index f63c575f16e..8305d737b24 100755 --- a/core/src/main/java/org/zstack/core/db/EntityMetadata.java +++ b/core/src/main/java/org/zstack/core/db/EntityMetadata.java @@ -20,6 +20,7 @@ private static class Metadata { } private static Map metadata = new HashMap<>(); + private static Set classesWithEncryptColumn = new HashSet<>(); @StaticInit static void staticInit() { @@ -34,6 +35,7 @@ static void staticInit() { if (f.isAnnotationPresent(EncryptColumn.class)) { m.encryptColumns.add(f.getName()); + classesWithEncryptColumn.add(clz); } }); @@ -66,4 +68,13 @@ public static List getEncryptColumn(Class clz) { } return m.encryptColumns; } + + public static boolean hasEncryptField(Class clz) { + Metadata m = getMetadata(clz); + return !m.encryptColumns.isEmpty(); + } + + public static Set getAllEncryptedClasses() { + return Collections.unmodifiableSet(classesWithEncryptColumn); + } } diff --git a/core/src/main/java/org/zstack/core/db/GLock.java b/core/src/main/java/org/zstack/core/db/GLock.java index 715923cba5b..a1e034d2f04 100755 --- a/core/src/main/java/org/zstack/core/db/GLock.java +++ b/core/src/main/java/org/zstack/core/db/GLock.java @@ -115,7 +115,8 @@ public void lock(long waitTimeout) { try { conn = dataSource.getConnection(); conn.setAutoCommit(true); - pstmt = conn.prepareStatement(String.format("select get_lock('%s', %s)", name, timeout)); + pstmt = conn.prepareStatement(String.format("select get_lock('%s', %s)", name, timeout),ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); + //pstmt = conn.prepareStatement(String.format("select get_lock('%s', %s)", name, timeout)); if (waitTimeout > 0) { pstmt.execute(String.format("set wait_timeout=%d", waitTimeout)); } @@ -197,7 +198,17 @@ public void unlock() { PreparedStatement pstmt = null; try { - pstmt = conn.prepareStatement(String.format("select release_lock('%s')", name)); + if (!conn.isValid(15)) { + logger.debug(String.format("conn is not valid, renew conn")); + conn = dataSource.getConnection(); + conn.setAutoCommit(true); + } + + if (logger.isTraceEnabled()) { + logger.trace(String.format("[GLock Release DB Lock] thread[%s] starting released DB lock[%s]", Thread.currentThread().getName(), name)); + } + + pstmt = conn.prepareStatement(String.format("select release_lock('%s')", name), ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); try (ResultSet rs = pstmt.executeQuery()) { if (!rs.next()) { throw new CloudRuntimeException("Mysql cannot find lock: " + name); diff --git a/core/src/main/java/org/zstack/core/db/JpaUnitPostProcessor.java b/core/src/main/java/org/zstack/core/db/JpaUnitPostProcessor.java index 7482ad425a9..918db9170e9 100755 --- a/core/src/main/java/org/zstack/core/db/JpaUnitPostProcessor.java +++ b/core/src/main/java/org/zstack/core/db/JpaUnitPostProcessor.java @@ -1,6 +1,6 @@ package org.zstack.core.db; -import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo; import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor; diff --git a/core/src/main/java/org/zstack/core/db/Q.java b/core/src/main/java/org/zstack/core/db/Q.java index 708fe20c048..8dcdcdf48fa 100755 --- a/core/src/main/java/org/zstack/core/db/Q.java +++ b/core/src/main/java/org/zstack/core/db/Q.java @@ -31,6 +31,16 @@ public Q orderBy(SingularAttribute attr, SimpleQuery.Od order) { return this; } + public Q orderByAsc(SingularAttribute attr) { + q.orderBy(attr, SimpleQuery.Od.ASC); + return this; + } + + public Q orderByDesc(SingularAttribute attr) { + q.orderBy(attr, SimpleQuery.Od.DESC); + return this; + } + public Q groupBy(SingularAttribute attr) { q.groupBy(attr); return this; @@ -116,11 +126,19 @@ public Q in(SingularAttribute attr, Collection val) { return this; } + public QueryMore in(SingularAttribute attr, Q subQuery) { + return toQueryMore().in(attr, subQuery); + } + public Q notIn(SingularAttribute attr, Collection val) { q.add(attr, SimpleQuery.Op.NOT_IN, val); return this; } + public QueryMore notIn(SingularAttribute attr, Q subQuery) { + return toQueryMore().notIn(attr, subQuery); + } + public Q isNull(SingularAttribute attr) { q.add(attr, SimpleQuery.Op.NULL); return this; @@ -164,4 +182,12 @@ public Q notLike(SingularAttribute attr, Object val) { public static Q New(Class clz) { return new Q(clz); } + + public static QueryMore New(Class clz, Class... more) { + return new QueryMore(clz, more); + } + + public QueryMore toQueryMore() { + return q.toQueryMore(); + } } diff --git a/core/src/main/java/org/zstack/core/db/QueryMore.java b/core/src/main/java/org/zstack/core/db/QueryMore.java new file mode 100644 index 00000000000..21d1441c677 --- /dev/null +++ b/core/src/main/java/org/zstack/core/db/QueryMore.java @@ -0,0 +1,473 @@ +package org.zstack.core.db; + +import org.apache.commons.collections.CollectionUtils; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.utils.DebugUtils; + +import javax.persistence.Tuple; +import javax.persistence.metamodel.SingularAttribute; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.IntFunction; + +import static org.zstack.core.db.SimpleQuery.Op.*; + +public class QueryMore { + private final Class[] tables; + private List selects = new ArrayList<>(); + private List orders = new ArrayList<>(); + private List conditions = new ArrayList<>(); + private List moreConditions = new ArrayList<>(); + private Integer limit; + private Integer start; + + private int tableIndex; + private int tableOffset; // used in sub-query + + QueryMore(Class one, Class... more) { + this.tables = new Class[more.length + 1]; + this.tables[0] = one; + + if (more.length > 0) { + System.arraycopy(more, 0, this.tables, 1, more.length); + } + } + + public class AttrInfo { + SingularAttribute attr; + String function; + int tableIndex; + + private String toSql() { + if (function != null) { + return attr == null ? + String.format("%s(t%d)", function, tableIndex + tableOffset) : + String.format("%s(t%d.%s)", function, tableIndex + tableOffset, attr.getName()); + } + + return attr == null ? + String.format("t%d", tableIndex + tableOffset) : + String.format("t%d.%s", tableIndex + tableOffset, attr.getName()); + } + } + + public class OrderInfo { + SingularAttribute attr; + SimpleQuery.Od od; + int tableIndex; + + private String toSql() { + return String.format("t%d.%s %s", tableIndex + tableOffset, attr.getName(), od.name()); + } + } + + public static class TableOption { + IntFunction function; + Consumer> attrConsumer; + + public ResultType table0(SingularAttribute attr) { + return table(0, attr); + } + + public ResultType table1(SingularAttribute attr) { + return table(1, attr); + } + + public ResultType table2(SingularAttribute attr) { + return table(2, attr); + } + + public ResultType table3(SingularAttribute attr) { + return table(3, attr); + } + + public ResultType table(int tableIndex, SingularAttribute attr) { + attrConsumer.accept(attr); + return function.apply(tableIndex); + } + } + + public class Condition { + SingularAttribute attr; + SimpleQuery.Op op; + Object value; + int tableIndex; + + private String toSql(int paramIndex) { + switch (op) { + case NULL: case NOT_NULL: + return String.format("t%d.%s %s", tableIndex + tableOffset, attr.getName(), op.toString()); + case IN: case NOT_IN: case LIKE: case NOT_LIKE: + return String.format("t%d.%s %s :p%d", tableIndex + tableOffset, attr.getName(), op.toString(), paramIndex); + } + return String.format("t%d.%s%s:p%d", tableIndex + tableOffset, attr.getName(), op.toString(), paramIndex); + } + + private boolean needParam() { + return op != NULL && op != NOT_NULL; + } + + private boolean hasSubQuery() { + return value instanceof QueryMore; + } + + private String handleSubQuery(Map params, int tableOffset) { + if (value instanceof QueryMore) { + final QueryMore q = (QueryMore) value; + q.tableOffset = tableOffset; + final String sql = q.toSqlAndFillParamMap(params); + return String.format("t%d.%s %s (%s)", + tableIndex + QueryMore.this.tableOffset, + attr.getName(), op.toString(), sql); + } + throw new CloudRuntimeException("should not be here"); + } + } + + public class ConditionBetweenTables { + int tableIndex1; + SingularAttribute attr1; + SimpleQuery.Op op; + int tableIndex2; + SingularAttribute attr2; + + private String toSql() { + return String.format("t%d.%s%st%d.%s", + tableIndex1 + tableOffset, attr1.getName(), op.toString(), + tableIndex2 + tableOffset, attr2.getName()); + } + } + + public QueryMore condition(SingularAttribute attr, SimpleQuery.Op op, Object value) { + Condition c = new Condition(); + c.attr = attr; + c.op = op; + c.value = value; + c.tableIndex = tableIndex; + conditions.add(c); + return this; + } + + public QueryMore selectThisTable() { + AttrInfo info = new AttrInfo(); + info.tableIndex = tableIndex; + selects.add(info); + return this; + } + + public QueryMore selectCountThisTable() { + AttrInfo info = new AttrInfo(); + info.tableIndex = tableIndex; + info.function = "count"; + selects.add(info); + return this; + } + + public QueryMore select(SingularAttribute... attrs) { + for (int i = 0; i < attrs.length; i++) { + AttrInfo info = new AttrInfo(); + info.attr = attrs[i]; + info.tableIndex = tableIndex; + selects.add(info); + } + return this; + } + + public QueryMore selectSum(SingularAttribute attr) { + AttrInfo info = new AttrInfo(); + info.attr = attr; + info.function = "sum"; + info.tableIndex = tableIndex; + selects.add(info); + return this; + } + + public QueryMore selectCount(SingularAttribute attr) { + AttrInfo info = new AttrInfo(); + info.attr = attr; + info.function = "count"; + info.tableIndex = tableIndex; + selects.add(info); + return this; + } + + public QueryMore eq(SingularAttribute attr, Object value) { + return condition(attr, EQ, value); + } + + // table0.uuid = table1.refUuid + public TableOption eq(SingularAttribute attr) { + ConditionBetweenTables condition = new ConditionBetweenTables(); + condition.tableIndex1 = tableIndex; + condition.attr1 = attr; + condition.op = SimpleQuery.Op.EQ; + + TableOption result = new TableOption<>(); + result.attrConsumer = (attr2) -> condition.attr2 = attr2; + result.function = (tableIndex) -> { + condition.tableIndex2 = tableIndex; + moreConditions.add(condition); + return this; + }; + return result; + } + + public QueryMore notEq(SingularAttribute attr, Object value) { + return condition(attr, NOT_EQ, value); + } + + public QueryMore in(SingularAttribute attr, Collection collection) { + DebugUtils.Assert(CollectionUtils.isNotEmpty(collection), "Op.IN value cannot be null or empty"); + return condition(attr, IN, collection); + } + + public QueryMore in(SingularAttribute attr, QueryMore subQuery) { + return condition(attr, IN, subQuery); + } + + public QueryMore in(SingularAttribute attr, Q subQuery) { + return in(attr, subQuery.toQueryMore()); + } + + public QueryMore notIn(SingularAttribute attr, Collection collection) { + return condition(attr, NOT_IN, collection); + } + + public QueryMore notIn(SingularAttribute attr, QueryMore subQuery) { + return condition(attr, NOT_IN, subQuery); + } + + public QueryMore notIn(SingularAttribute attr, Q subQuery) { + return notIn(attr, subQuery.toQueryMore()); + } + + public QueryMore isNull(SingularAttribute attr) { + return condition(attr, NULL, null); + } + + public QueryMore notNull(SingularAttribute attr) { + return condition(attr, NOT_NULL, null); + } + + public QueryMore gt(SingularAttribute attr, Object value) { + return condition(attr, GT, value); + } + + public QueryMore gte(SingularAttribute attr, Object value) { + return condition(attr, GTE, value); + } + + public QueryMore lt(SingularAttribute attr, Object value) { + return condition(attr, LT, value); + } + + public QueryMore lte(SingularAttribute attr, Object value) { + return condition(attr, LTE, value); + } + + public QueryMore like(SingularAttribute attr, Object value) { + return condition(attr, LIKE, value); + } + + public QueryMore notLike(SingularAttribute attr, Object value) { + return condition(attr, NOT_LIKE, value); + } + + public QueryMore table(int tableIndex) { + this.tableIndex = tableIndex; + return this; + } + + public QueryMore table0() { + return table(0); + } + + public QueryMore table1() { + return table(1); + } + + public QueryMore table2() { + return table(2); + } + + public QueryMore table3() { + return table(3); + } + + public QueryMore orderByAsc(SingularAttribute attr) { + OrderInfo order = new OrderInfo(); + order.tableIndex = tableIndex; + order.od = SimpleQuery.Od.ASC; + order.attr = attr; + orders.add(order); + return this; + } + + public QueryMore orderByDesc(SingularAttribute attr) { + OrderInfo order = new OrderInfo(); + order.tableIndex = tableIndex; + order.od = SimpleQuery.Od.DESC; + order.attr = attr; + orders.add(order); + return this; + } + + public QueryMore limit(int limit) { + this.limit = limit; + return this; + } + + public QueryMore start(int start) { + this.start = start; + return this; + } + + public String toSql() { + return toSqlAndFillParamMap(new HashMap<>()); + } + + private String toSqlAndFillParamMap(Map params) { + StringBuilder builder = new StringBuilder(); + + builder.append("select "); + if (!selects.isEmpty()) { + for (AttrInfo select : selects) { + builder.append(select.toSql()).append(','); + } + builder.deleteCharAt(builder.length() - 1); + } else if (tables.length == 1) { + builder.append("t0"); + } else { + builder.append('*'); + } + + builder.append(" from "); + for (int i = 0; i < tables.length; i++) { + Class table = tables[i]; + builder.append(table.getSimpleName()).append(' ').append('t').append(i + tableOffset).append(','); + } + builder.deleteCharAt(builder.length() - 1); + + if (!conditions.isEmpty() || !moreConditions.isEmpty()) { + builder.append(" where "); + List conditionScripts = new ArrayList<>(); + + for (Condition condition : conditions) { + if (condition.hasSubQuery()) { + conditionScripts.add(condition.handleSubQuery(params, tableOffset + tables.length)); + continue; + } + + int paramIndex = params.size(); + conditionScripts.add(condition.toSql(paramIndex)); + if (condition.needParam()) { + params.put("p" + paramIndex, condition.value); + } + } + + for (ConditionBetweenTables moreCondition : moreConditions) { + conditionScripts.add(moreCondition.toSql()); + } + + builder.append(String.join(" and ", conditionScripts)); + } + + if (!orders.isEmpty()) { + builder.append(" order by "); + + for (OrderInfo order : orders) { + builder.append(order.toSql()).append(','); + } + builder.deleteCharAt(builder.length() - 1); + } + + if (limit != null) { + builder.append(" limit ").append(limit); + } + if (start != null) { + builder.append(" offset ").append(start); + } + + return builder.toString(); + } + + @Override + public String toString() { + return toSql(); + } + + public SQL toSqlInstance(Class returnType) { + final Map paramMap = new HashMap<>(); + final SQL sqlInstance = SQL.New(toSqlAndFillParamMap(paramMap), returnType); + paramMap.forEach(sqlInstance::param); + return sqlInstance; + } + + public SQL toSqlInstance() { + final Map paramMap = new HashMap<>(); + final SQL sqlInstance = SQL.New(toSqlAndFillParamMap(paramMap)); + paramMap.forEach(sqlInstance::param); + return sqlInstance; + } + + public List list() { + if (this.selects.size() == 1 && this.selects.get(0).attr == null) { + int tableIndex = this.selects.get(0).tableIndex; + return toSqlInstance(tables[tableIndex]).list(); + } else if (this.selects.isEmpty() && this.tables.length == 1) { + return toSqlInstance(tables[0]).list(); + } + + return toSqlInstance().list(); + } + + public T find() { + if (this.selects.size() == 1 && this.selects.get(0).attr == null) { + int tableIndex = this.selects.get(0).tableIndex; + return toSqlInstance(tables[tableIndex]).find(); + } else if (this.selects.isEmpty() && this.tables.length == 1) { + return toSqlInstance(tables[0]).find(); + } + + return toSqlInstance().find(); + } + + public T find(Class returnType) { + return toSqlInstance(returnType).find(); + } + + public Tuple findTuple() { + return toSqlInstance(Tuple.class).find(); + } + + public List listTuple() { + return toSqlInstance(Tuple.class).list(); + } + + public Long count() { + if (selects.isEmpty()) { + AttrInfo info = new AttrInfo(); + info.tableIndex = 0; + info.function = "count"; + selects.add(info); + } else if (selects.size() == 1) { + selects.get(0).function = "count"; + } else { + throw new CloudRuntimeException("You must specify an attribute using the selectCount() method"); + } + + return toSqlInstance(Long.class).find(); + } + + public boolean isExists() { + return count() > 0; + } + + public static QueryMore New(Class clz) { + return new QueryMore(clz); + } +} diff --git a/core/src/main/java/org/zstack/core/db/SQLBatch.java b/core/src/main/java/org/zstack/core/db/SQLBatch.java index fe476e4b6f4..c23ea9ec71c 100755 --- a/core/src/main/java/org/zstack/core/db/SQLBatch.java +++ b/core/src/main/java/org/zstack/core/db/SQLBatch.java @@ -68,6 +68,10 @@ protected Q q(Class clz) { return Q.New(clz); } + protected QueryMore q(Class first, Class... more) { + return Q.New(first, more); + } + @Transactional private void _execute() { scripts(); diff --git a/core/src/main/java/org/zstack/core/db/SimpleQueryImpl.java b/core/src/main/java/org/zstack/core/db/SimpleQueryImpl.java index 18f5bebe189..9ba9b0ac494 100755 --- a/core/src/main/java/org/zstack/core/db/SimpleQueryImpl.java +++ b/core/src/main/java/org/zstack/core/db/SimpleQueryImpl.java @@ -405,4 +405,34 @@ public SimpleQuery setStart(int start) { this.start = start; return this; } + + public QueryMore toQueryMore() { + QueryMore q = new QueryMore(_entityClass); + + if (start != null) { + q.start(start); + } + if (limit != null) { + q.limit(limit); + } + + if (!_selects.isEmpty()) { + q.select(_selects.stream().map(s -> s._attr).toArray(SingularAttribute[]::new)); + } + if (!orderInfos.isEmpty()) { + for (OrderInfo orderInfo : orderInfos) { + if (orderInfo.od == Od.ASC) { + q.orderByAsc(orderInfo.attr); + } else { + q.orderByDesc(orderInfo.attr); + } + } + } + if (!_conditions.isEmpty()) { + for (Condition condition : _conditions) { + q.condition(condition._attr, condition._op, condition._val[0]); + } + } + return q; + } } diff --git a/core/src/main/java/org/zstack/core/debug/APICleanQueueEventDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/debug/APICleanQueueEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..056d0187566 --- /dev/null +++ b/core/src/main/java/org/zstack/core/debug/APICleanQueueEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.core.debug + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "清理管理节点队列的结果" + + field { + name "success" + desc "" + type "boolean" + since "4.1.3" + } + ref { + name "error" + path "org.zstack.core.debug.APICleanQueueEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.1.3" + clz ErrorCode.class + } +} diff --git a/core/src/main/java/org/zstack/core/debug/APICleanQueueMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/debug/APICleanQueueMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..8876fa10034 --- /dev/null +++ b/core/src/main/java/org/zstack/core/debug/APICleanQueueMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.core.debug + +import org.zstack.core.debug.APICleanQueueEvent + +doc { + title "CleanQueue" + + category "debug" + + desc """清理管理节点队列""" + + rest { + request { + url "PUT /v1/clean/queue" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICleanQueueMsg.class + + desc """""" + + params { + + column { + name "signatureName" + enclosedIn "cleanQueue" + desc "" + location "body" + type "String" + optional false + since "4.1.3" + } + column { + name "taskIndex" + enclosedIn "cleanQueue" + desc "" + location "body" + type "Integer" + optional true + since "4.1.3" + } + column { + name "isCleanUp" + enclosedIn "cleanQueue" + desc "" + location "body" + type "Boolean" + optional true + since "4.1.3" + } + column { + name "isRunningTask" + enclosedIn "cleanQueue" + desc "" + location "body" + type "Boolean" + optional true + since "4.1.3" + } + column { + name "managementiUuid" + enclosedIn "cleanQueue" + desc "" + location "body" + type "String" + optional true + since "4.1.3" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.1.3" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.1.3" + } + } + } + + response { + clz APICleanQueueEvent.class + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsg.java b/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsg.java index 7af07ec1cc5..9bdedf9e75a 100755 --- a/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsg.java +++ b/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsg.java @@ -14,7 +14,9 @@ @RestRequest( path = "/debug", method = HttpMethod.POST, - responseClass = APIDebugSignalEvent.class) + parameterName = "params", + responseClass = APIDebugSignalEvent.class +) public class APIDebugSignalMsg extends APIMessage { @APIParam private List signals; diff --git a/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsgDoc_zh_cn.groovy index fdb066e0676..1e1caa90376 100644 --- a/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/debug/APIDebugSignalMsgDoc_zh_cn.groovy @@ -23,13 +23,12 @@ doc { column { name "signals" - enclosedIn "" + enclosedIn "params" desc "" location "body" type "List" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/core/src/main/java/org/zstack/core/debug/APIGetDebugSignalMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/debug/APIGetDebugSignalMsgDoc_zh_cn.groovy index b1d02b90609..cbef6fa5552 100644 --- a/core/src/main/java/org/zstack/core/debug/APIGetDebugSignalMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/debug/APIGetDebugSignalMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.6.0" - } } } diff --git a/core/src/main/java/org/zstack/core/encrypt/Base64EncodeParamFactory.java b/core/src/main/java/org/zstack/core/encrypt/Base64EncodeParamFactory.java new file mode 100644 index 00000000000..9bbf500f365 --- /dev/null +++ b/core/src/main/java/org/zstack/core/encrypt/Base64EncodeParamFactory.java @@ -0,0 +1,62 @@ +package org.zstack.core.encrypt; + +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import org.apache.commons.codec.binary.Base64; + +import java.io.IOException; + +public class Base64EncodeParamFactory implements TypeAdapterFactory { + private static TypeAdapter adapter = Base64TypeAdapter.create(); + + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + return adapter; + } + + private static final class Base64TypeAdapter + extends TypeAdapter { + + static TypeAdapter create() { + return new Base64TypeAdapter() + .nullSafe(); // Just let Gson manage nulls itself. It's convenient + } + + @Override + public void write(JsonWriter out, T value) throws IOException { + if (value == null) { + out.nullValue(); + return; + } + String output = value.toString(); + + if (Base64.isBase64(output)) { + out.value(output); + return; + } + + out.value(new String(Base64.encodeBase64(output.getBytes()))); + } + + @Override + public T read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + + String input = in.nextString(); + + if (!Base64.isBase64(input)) { + return (T) input; + } + + return (T) new String(Base64.decodeBase64(input)); + } + } +} diff --git a/core/src/main/java/org/zstack/core/encrypt/DefaultEncryptDriver.java b/core/src/main/java/org/zstack/core/encrypt/DefaultEncryptDriver.java index 01ee52be3fc..9009eadb880 100644 --- a/core/src/main/java/org/zstack/core/encrypt/DefaultEncryptDriver.java +++ b/core/src/main/java/org/zstack/core/encrypt/DefaultEncryptDriver.java @@ -1,6 +1,7 @@ package org.zstack.core.encrypt; import org.zstack.header.core.encrypt.EncryptConstant; +import org.zstack.header.errorcode.ErrorableValue; import org.zstack.header.exception.CloudRuntimeException; public class DefaultEncryptDriver implements EncryptDriver { @@ -32,18 +33,18 @@ public String decrypt(String data) { } @Override - public EncryptFacadeResult encrypt(String data, String algType) { + public ErrorableValue encrypt(String data, String algType) { try { - return new EncryptFacadeResult<>(rsa.encrypt(data, algType)); + return ErrorableValue.of(rsa.encrypt(data, algType)); } catch (Exception e) { throw new CloudRuntimeException(e.getMessage()); } } @Override - public EncryptFacadeResult decrypt(String data, String algType) { + public ErrorableValue decrypt(String data, String algType) { try { - return new EncryptFacadeResult<>(rsa.decrypt(data, algType)); + return ErrorableValue.of(rsa.decrypt(data, algType)); } catch (Exception e) { throw new CloudRuntimeException(e.getMessage()); } diff --git a/core/src/main/java/org/zstack/core/encrypt/EncryptDriver.java b/core/src/main/java/org/zstack/core/encrypt/EncryptDriver.java index 3c0e0be1ce6..674121ca978 100644 --- a/core/src/main/java/org/zstack/core/encrypt/EncryptDriver.java +++ b/core/src/main/java/org/zstack/core/encrypt/EncryptDriver.java @@ -1,13 +1,24 @@ package org.zstack.core.encrypt; +import org.zstack.header.errorcode.ErrorableValue; +import java.util.List; + public interface EncryptDriver { + String encryptError = "%s encrypt failed"; + String decryptError = "%s decrypt failed"; + EncryptDriverType getDriverType(); + default List getDriverTypes() { + return null; + } + + String encrypt(String data); String decrypt(String data); - EncryptFacadeResult encrypt(String data, String algType); + ErrorableValue encrypt(String data, String algType); - EncryptFacadeResult decrypt(String data, String algType); + ErrorableValue decrypt(String data, String algType); } diff --git a/core/src/main/java/org/zstack/core/encrypt/EncryptFacade.java b/core/src/main/java/org/zstack/core/encrypt/EncryptFacade.java index 24f8bc7a58f..847c589b4db 100644 --- a/core/src/main/java/org/zstack/core/encrypt/EncryptFacade.java +++ b/core/src/main/java/org/zstack/core/encrypt/EncryptFacade.java @@ -1,5 +1,11 @@ package org.zstack.core.encrypt; +import org.zstack.header.core.encrypt.EncryptEntityState; +import org.zstack.header.core.encrypt.EncryptedFieldBundle; +import org.zstack.header.errorcode.ErrorableValue; + +import java.util.List; + /** * Created by kayo on 2018/9/7. */ @@ -8,7 +14,13 @@ public interface EncryptFacade { String decrypt(String encryptString); - EncryptFacadeResult encrypt(String data, String algType); + ErrorableValue encrypt(String data, String algType); + + ErrorableValue decrypt(String data, String algType); + + void updateEncryptDataStateIfExists(String entity, String column, EncryptEntityState state); + + List getIntegrityEncryptionBundle(); - EncryptFacadeResult decrypt(String data, String algType); + List getConfidentialityEncryptionBundle(); } \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java b/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java index e11a4abdf44..9580f9bebb3 100644 --- a/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeImpl.java @@ -1,20 +1,23 @@ package org.zstack.core.encrypt; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.Platform; -import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.config.GlobalConfig; -import org.zstack.core.config.GlobalConfigBeforeUpdateExtensionPoint; -import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; +import org.zstack.core.config.*; import org.zstack.core.convert.PasswordConverter; +import org.zstack.core.convert.SpecialDataConverter; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; import org.zstack.core.db.SQLBatch; import org.zstack.header.Component; -import org.zstack.header.core.encrypt.PasswordEncryptType; +import org.zstack.header.core.encrypt.*; +import org.zstack.header.errorcode.ErrorableValue; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.utils.BeanUtils; +import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -38,8 +41,6 @@ public class EncryptFacadeImpl implements EncryptFacade, Component { private EncryptDriver encryptDriver; - @Autowired - private CloudBus bus; @Autowired private DatabaseFacade dbf; @Autowired @@ -47,6 +48,8 @@ public class EncryptFacadeImpl implements EncryptFacade, Component { public static Set encryptedFields = new HashSet<>(); + public static List covertSubClasses = new ArrayList<>(); + @Override public String encrypt(String decryptString) { return encryptDriver.encrypt(decryptString); @@ -54,40 +57,55 @@ public String encrypt(String decryptString) { @Override public String decrypt(String encryptString) { - return encryptDriver.decrypt(encryptString); + try { + return encryptDriver.decrypt(encryptString); + } catch (Exception e) { + logger.debug(e.getMessage()); + return encryptString; + } } @Override - public EncryptFacadeResult encrypt(String data, String algType) { + public ErrorableValue encrypt(String data, String algType) { return encryptDriver.encrypt(data, algType); } @Override - public EncryptFacadeResult decrypt(String data, String algType) { + public ErrorableValue decrypt(String data, String algType) { return encryptDriver.decrypt(data, algType); } + private String getQuerySql(List covertSubClasses, String className, String fieldName, String uuid) { + List whereSqlList = covertSubClasses.stream() + .filter(subClass -> subClass.classSimpleName().equals(className) && !subClass.columnName().isEmpty()) + .map(subClass -> String.format(" %s = '%s'", subClass.columnName(), subClass.columnValue())) + .collect(Collectors.toList()); + + String querySql = String.format("select %s from %s where uuid = '%s'", fieldName, className, uuid); + if (!whereSqlList.isEmpty()) { + querySql = querySql + String.format(" and (%s)", whereSqlList.stream().collect(Collectors.joining(" or "))); + } + return querySql; + } + private void encryptAllPassword() { new SQLBatch() { @Override protected void scripts() { for (Field field : encryptedFields) { - List classNames = new ArrayList<>(); - - if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { - classNames.add(field.getDeclaringClass().getSimpleName()); - } else { - classNames.addAll(BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() - .filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) - .map(Class::getSimpleName) - .collect(Collectors.toList())); - } + List classNames = getClassName(field, covertSubClasses); for (String className : classNames) { List uuids = sql(String.format("select uuid from %s", className)).list(); for (String uuid : uuids) { - String value = sql(String.format("select %s from %s where uuid = '%s'", field.getName(), className, uuid)).find(); + String querySql = getQuerySql(covertSubClasses, className, field.getName(), uuid); + String value = sql(querySql).find(); + + if (StringUtils.isEmpty(value)) { + logger.debug(String.format("encryption[className: %s, uuid: %s] value is null, skip encryption", className, uuid)); + continue; + } try { String encryptedString = encrypt(value); @@ -99,50 +117,76 @@ protected void scripts() { query.setParameter("uuid", uuid); query.executeUpdate(); } catch (Exception e) { - logger.debug(String.format("encrypt error because : %s",e.getMessage())); + logger.debug(String.format("encrypt[className: %s, uuid: %s] error because : %s", className, uuid, e.getMessage())); } } + updateEncryptDataStateIfExists(className, field.getName(), EncryptEntityState.Encrypted); } } } }.execute(); } - private void decryptAllPassword() { + private void beforeRecoverDataDecryptAllPassword() { + Map> classnameFilter = new HashMap<>(); + for (Field field : encryptedFields) { + List classNames = new ArrayList<>(); + + if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { + classNames.add(field.getDeclaringClass().getSimpleName()); + } else { + List subClassNames = BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() + .filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) + .map(Class::getSimpleName) + .collect(Collectors.toList()); + + classNames.addAll(subClassNames); + } + + classnameFilter.put(field, classNames); + } + + decryptAllPassword(classnameFilter); + } + + private void decryptAllPassword(Map> classnameFilter) { new SQLBatch() { @Override protected void scripts() { for (Field field : encryptedFields) { - List classNames = new ArrayList<>(); - - if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { - classNames.add(field.getDeclaringClass().getSimpleName()); - } else { - classNames.addAll(BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() - .filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) - .map(Class::getSimpleName) - .collect(Collectors.toList())); + List covertSubClasses = new ArrayList<>(); + List classNames = classnameFilter.get(field); + + if (classNames == null || classNames.isEmpty()) { + classNames = getClassName(field, covertSubClasses); } for (String className : classNames) { List uuids = sql(String.format("select uuid from %s", className)).list(); for (String uuid : uuids) { - String encryptedString = sql(String.format("select %s from %s where uuid = '%s'", field.getName(), className, uuid)).find(); + String querySql = getQuerySql(covertSubClasses, className, field.getName(), uuid); + String encryptedString = sql(querySql).find(); + + if (StringUtils.isEmpty(encryptedString)) { + logger.debug(String.format("decryption[className: %s, uuid: %s] value is null, skip decryption", className, uuid)); + continue; + } try { String decryptString = decrypt(encryptedString); String sql = String.format("update %s set %s = :decrypted where uuid = :uuid", className, field.getName()); - Query query = dbf.getEntityManager().createQuery(sql); + Query query = dbf.getEntityManager().createNativeQuery(sql); query.setParameter("decrypted", decryptString); query.setParameter("uuid", uuid); query.executeUpdate(); } catch (Exception e) { - logger.debug(String.format("decrypt password error because : %s",e.getMessage())); + logger.debug(String.format("decrypt[className: %s, uuid: %s] password error because : %s", className, uuid, e.getMessage())); } } + updateEncryptDataStateIfExists(className, field.getName(), EncryptEntityState.NewAdded); } } } @@ -154,26 +198,23 @@ private void encryptAllPasswordWithNewKey(String key) { @Override protected void scripts() { for (Field field : encryptedFields) { - List classNames = new ArrayList<>(); - - if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { - classNames.add(field.getDeclaringClass().getSimpleName()); - } else { - classNames.addAll(BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() - .filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) - .map(Class::getSimpleName) - .collect(Collectors.toList())); - } + List classNames = getClassName(field, covertSubClasses); for (String className : classNames) { List uuids = sql(String.format("select uuid from %s", className)).list(); for (String uuid : uuids) { - String encryptedString = sql(String.format("select %s from %s where uuid = '%s'", field.getName(), className, uuid)).find(); + String querySql = getQuerySql(covertSubClasses, className, field.getName(), uuid); + String encryptedString = sql(querySql).find(); + + if (StringUtils.isEmpty(encryptedString)) { + logger.debug(String.format("encryptAllPasswordWithNewKey[className: %s, uuid: %s] value is null, skip encrypt", className, uuid)); + continue; + } try { String decryptedString = decrypt(encryptedString); - EncryptFacadeResult encrypt = encrypt(decryptedString, key); + ErrorableValue encrypt = encrypt(decryptedString, key); if (encrypt.error != null) { logger.error(String.format("Encryption error : %s", encrypt.error)); throw new OperationFailureException(operr("Encryption error : %s", encrypt.error)); @@ -182,11 +223,11 @@ protected void scripts() { String sql = String.format("update %s set %s = :encrypted where uuid = :uuid", className, field.getName()); Query query = dbf.getEntityManager().createQuery(sql); - query.setParameter("encrypted", encrypt.getResult()); + query.setParameter("encrypted", encrypt.result); query.setParameter("uuid", uuid); query.executeUpdate(); } catch (Exception e) { - logger.debug(String.format("decrypt origin password error because : %s",e.getMessage())); + logger.debug(String.format("decrypt[className: %s, uuid: %s] origin password error because : %s", className, uuid, e.getMessage())); } } } @@ -195,57 +236,62 @@ protected void scripts() { }.execute(); } - private static Set getAllEncryptPassword() { + private void collectAllEncryptPassword() { Set fields = Platform.getReflections().getFieldsAnnotatedWith(Convert.class); - return fields.stream().filter(field -> field.getAnnotation(Convert.class).converter().equals(PasswordConverter.class)).collect(Collectors.toSet()); + encryptedFields = fields.stream() + .filter(field -> field.getAnnotation(Convert.class).converter().equals(PasswordConverter.class) || + field.getAnnotation(Convert.class).converter().equals(SpecialDataConverter.class)) + .collect(Collectors.toSet()); + for (Field field : encryptedFields) { + getCovertSubClassList(field); + } } - @Override - public boolean start() { + private void initEncryptDriver() { String driverType = EncryptGlobalConfig.ENCRYPT_DRIVER.value(); - for (EncryptDriver driver : pluginRegistry.getExtensionList(EncryptDriver.class)) { - if (!driverType.equals(driver.getDriverType().toString())) { - continue; - } - - encryptDriver = driver; - break; - } - - if (encryptDriver == null) { - throw new CloudRuntimeException(String.format("no matched encrypt driver[type:%s] can be found", driverType)); + EncryptDriver encryptDriver = findEncryptDriver(driverType); + if (encryptDriver != null) { + this.encryptDriver = encryptDriver; + logger.debug(String.format("New encrypt driver: %s is included by driver class: %s", driverType, encryptDriver.getClass().getCanonicalName())); + return; } - encryptedFields = getAllEncryptPassword(); + throw new CloudRuntimeException(String.format("No matched encrypt driver[type:%s] can be found", driverType)); + } - EncryptGlobalConfig.ENCRYPT_DRIVER.installUpdateExtension(new GlobalConfigUpdateExtensionPoint() { - @Override - public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { - for (EncryptDriver driver : pluginRegistry.getExtensionList(EncryptDriver.class)) { - if (!newConfig.value().equals(driver.getDriverType().toString())) { - continue; - } + private EncryptDriver findEncryptDriver(String driverType) { + return pluginRegistry.getExtensionList(EncryptDriver.class).stream() + .filter(driver -> driverType.equals(driver.getDriverType().toString()) || + (driver.getDriverTypes() != null && driver.getDriverTypes().contains(driverType))) + .findFirst() + .orElseGet(() -> { + logger.error(String.format("No matched encrypt driver[type:%s] can be found", driverType)); + return null; + }); + } - encryptDriver = driver; - break; - } + public void installGlobalConfigUpdateHooks() { + EncryptGlobalConfig.ENCRYPT_DRIVER.installUpdateExtension((oldConfig, newConfig) -> { + String updatedToDriverType = newConfig.value(); + EncryptDriver encryptDriver = findEncryptDriver(updatedToDriverType); + if (encryptDriver != null) { + logger.debug(String.format("New encrypt driver: %s is included by driver class: %s", updatedToDriverType, encryptDriver.getClass().getCanonicalName())); + this.encryptDriver = encryptDriver; + } else { + logger.error(String.format("No matched encrypt driver[type:%s] can be found", updatedToDriverType)); } }); EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.installLocalBeforeUpdateExtension(new GlobalConfigBeforeUpdateExtensionPoint() { @Override public void beforeUpdateExtensionPoint(GlobalConfig oldConfig, String newValue) { - //encryption cannot be changed - if (PasswordEncryptType.SecurityResourceEncryption.toString().equals(oldConfig.value())) { - throw new OperationFailureException(operr("SecurityResourceEncryption cannot be change")); - } - // avoid encrypt twice need to do synchronized encrypted(decrypted) // e.g. use javax.persistence.Query set password to update encrypt password // when PasswordConverter check this value is true the password will be encrypt // again before persist, so this beforeUpdateExtension is necessary - if (PasswordEncryptType.LocalEncryption.toString().equals(newValue)) { + if (PasswordEncryptType.LocalEncryption.toString().equals(newValue) + || PasswordEncryptType.SecurityResourceEncryption.toString().equals(newValue)) { encryptAllPassword(); } } @@ -255,7 +301,7 @@ public void beforeUpdateExtensionPoint(GlobalConfig oldConfig, String newValue) @Override public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { if (PasswordEncryptType.None.toString().equals(newConfig.value())) { - decryptAllPassword(); + decryptAllPassword(new HashMap<>()); } } }); @@ -273,7 +319,256 @@ public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { } } }); + } + + protected void handleNewAddedEncryptEntity() { + if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value())) { + return; + } + + List metadataVOList = Q.New(EncryptEntityMetadataVO.class) + .eq(EncryptEntityMetadataVO_.state, EncryptEntityState.NewAdded) + .list(); + + new SQLBatch() { + @Override + protected void scripts() { + for (EncryptEntityMetadataVO metadata : metadataVOList) { + // do encrypt + long count = SQL.New(String.format("select count(1) from %s", metadata.getEntityName()), Long.class).find(); + metadata.setState(EncryptEntityState.Encrypting); + metadata = dbf.updateAndRefresh(metadata); + String className = metadata.getEntityName(); + String fieldName = metadata.getColumnName(); + sql(String.format("select uuid from %s", metadata.getEntityName()), String.class) + .limit(1000) + .paginate(count, (List uuids) -> { + for (String uuid : uuids) { + String querySql = getQuerySql(covertSubClasses, className, fieldName, uuid); + String value = sql(querySql).find(); + + if (StringUtils.isEmpty(value)){ + logger.debug(String.format("EncryptEntityMetadata[className: %s, uuid: %s] value is null, skip encrypt", className, uuid)); + continue; + } + + try { + // If part of the data has been encrypted, first decrypt all the data before encrypting + String decryptedString = decrypt(value); + String encryptedString = encrypt(decryptedString); + + String sql = String.format("update %s set %s = :encrypted where uuid = :uuid", className, fieldName); + + // need to use createNativeQuery. if use createQuery, it will be encrypted again after inserting into db + Query query = dbf.getEntityManager().createNativeQuery(sql); + query.setParameter("encrypted", encryptedString); + query.setParameter("uuid", uuid); + query.executeUpdate(); + } catch (Exception e) { + logger.debug(String.format("EncryptEntityMetadata[className: %s, uuid: %s] error because : %s", className, uuid, e.getMessage())); + } + } + + }); + metadata.setState(EncryptEntityState.Encrypted); + dbf.updateAndRefresh(metadata); + } + } + }.execute(); + } + + private void getCovertSubClassList(Field field) { + if (field.getDeclaringClass().getAnnotation(CovertSubClasses.class) != null) { + covertSubClasses.addAll(Arrays.asList(field.getDeclaringClass().getAnnotation(CovertSubClasses.class).value())); + } + List subClassNames = BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() + .filter(aClass -> aClass.getAnnotation(CovertSubClasses.class) != null) + .map(subClass -> subClass.getAnnotation(CovertSubClasses.class).value()) + .flatMap(Arrays::stream).collect(Collectors.toList()); + covertSubClasses.addAll(subClassNames); + } + + private List getClassName(Field field, List covertSubClasses) { + List classNames = new ArrayList<>(); + if (covertSubClasses == null || covertSubClasses.isEmpty()) { + getCovertSubClassList(field); + } + + if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { + classNames.add(field.getDeclaringClass().getSimpleName()); + } else { + List subClassNames = BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() + .filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) + .map(Class::getSimpleName) + .collect(Collectors.toList()); + + List filterClassName = covertSubClasses.stream().map(CovertSubClass::classSimpleName).collect(Collectors.toList()); + List covertSubClassNames = subClassNames.stream().filter(filterClassName::contains).collect(Collectors.toList()); + classNames.addAll(covertSubClassNames.isEmpty() ? subClassNames : covertSubClassNames); + } + + return classNames; + } + + private void collectEncryptEntityMetadata() { + for (Field field : encryptedFields) { + List classNames = getClassName(field, covertSubClasses); + + for (String className : classNames) { + createIfNotExists(className, field.getName()); + } + } + } + + private void createIfNotExists(String entity, String column) { + if (Q.New(EncryptEntityMetadataVO.class) + .eq(EncryptEntityMetadataVO_.entityName, entity) + .eq(EncryptEntityMetadataVO_.columnName, column) + .isExists()) { + return; + } + + EncryptEntityMetadataVO metadataVO = new EncryptEntityMetadataVO(); + metadataVO.setColumnName(column); + metadataVO.setEntityName(entity); + metadataVO.setState(EncryptEntityState.NewAdded); + dbf.persist(metadataVO); + } + + @Override + public void updateEncryptDataStateIfExists(String entity, String column, EncryptEntityState state) { + String sql = String.format("update EncryptEntityMetadataVO set state = :state where columnName = :columnName and entityName = :entityName"); + Query query = dbf.getEntityManager().createQuery(sql); + query.setParameter("state", state); + query.setParameter("entityName", entity); + query.setParameter("columnName", column); + query.executeUpdate(); + } + + @Override + public List getIntegrityEncryptionBundle() { + List fieldBundles = new ArrayList<>(); + return fieldBundles; + } + + private EncryptedFieldBundle getSm4EncryptedFieldBundle(String className, String columnName) { + EncryptedFieldBundle encryptedFieldBundle = new EncryptedFieldBundle(); + encryptedFieldBundle.setEncryptedColumn(columnName); + encryptedFieldBundle.setEncryptedType(EncryptType.SM4.toString()); + encryptedFieldBundle.setEncryptedClass(className); + return encryptedFieldBundle; + } + @Override + public List getConfidentialityEncryptionBundle() { + List fieldBundles = new ArrayList<>(); + + encryptedFields.forEach(field -> { + // all VO + if (field.getDeclaringClass().getAnnotation(Entity.class) != null && field.getDeclaringClass().getAnnotation(Table.class) != null) { + fieldBundles.add(getSm4EncryptedFieldBundle(field.getDeclaringClass().getSimpleName(), field.getName())); + return; + } + + // is sub VO and has CovertSubClass annotation + List subCovertSubClasss = BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() + .filter(aClass -> aClass.getAnnotation(CovertSubClasses.class) != null) + .map(subClass -> subClass.getAnnotation(CovertSubClasses.class).value()) + .flatMap(Arrays::stream).collect(Collectors.toList()); + if (!subCovertSubClasss.isEmpty()) { + subCovertSubClasss.forEach(subCovertSubClass -> { + EncryptedFieldBundle encryptedFieldBundle = getSm4EncryptedFieldBundle(field.getDeclaringClass().getSimpleName(), field.getName()); + encryptedFieldBundle.setEncryptedClass(((CovertSubClass) subCovertSubClass).classSimpleName()); + encryptedFieldBundle.setConditionKey(((CovertSubClass) subCovertSubClass).columnName()); + encryptedFieldBundle.setConditionValue(((CovertSubClass) subCovertSubClass).columnValue()); + fieldBundles.add(encryptedFieldBundle); + }); + return; + } + + // all AO + List subClassNames = BeanUtils.reflections.getSubTypesOf(field.getDeclaringClass()).stream() + .filter(aClass -> aClass.getAnnotation(Entity.class) != null && aClass.getAnnotation(Table.class) != null) + .map(Class::getSimpleName) + .collect(Collectors.toList()); + for (String subClassName : subClassNames) { + fieldBundles.add(getSm4EncryptedFieldBundle(subClassName, field.getName())); + } + }); + + return fieldBundles; + } + + private void removeConvertRecoverData() { + if (Q.New(EncryptEntityMetadataVO.class) + .isExists()) { + return; + } + + if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value())) { + return; + } + + beforeRecoverDataDecryptAllPassword(); + } + + protected void handleNeedDecryptEntity() { + if (PasswordEncryptType.None.toString().equals(EncryptGlobalConfig.ENABLE_PASSWORD_ENCRYPT.value())) { + return; + } + + List metadataVOList = Q.New(EncryptEntityMetadataVO.class) + .eq(EncryptEntityMetadataVO_.state, EncryptEntityState.NeedDecrypt) + .list(); + + new SQLBatch() { + @Override + protected void scripts() { + for (EncryptEntityMetadataVO metadata : metadataVOList) { + long count = SQL.New(String.format("select count(1) from %s", metadata.getEntityName()), Long.class).find(); + String className = metadata.getEntityName(); + String fieldName = metadata.getColumnName(); + sql(String.format("select uuid from %s", metadata.getEntityName()), String.class) + .limit(1000) + .paginate(count, (List uuids) -> { + for (String uuid : uuids) { + String querySql = String.format("select %s from %s where uuid = '%s'", fieldName, className, uuid); + String value = sql(querySql).find(); + + if (StringUtils.isEmpty(value)) { + logger.debug(String.format("DecryptEntity[className: %s, uuid: %s] value is null, skip decrypt", className, uuid)); + continue; + } + + try { + String decryptedString = decrypt(value); + String sql = String.format("update %s set %s = :decrypted where uuid = :uuid", className, fieldName); + Query query = dbf.getEntityManager().createQuery(sql); + query.setParameter("decrypted", decryptedString); + query.setParameter("uuid", uuid); + query.executeUpdate(); + } catch (Exception e) { + logger.debug(String.format("handleNeedDecryptEntity[className: %s, uuid: %s] error because : %s", className, uuid, e.getMessage())); + + } + } + + }); + dbf.remove(metadata); + } + } + }.execute(); + } + + @Override + public boolean start() { + initEncryptDriver(); + collectAllEncryptPassword(); + installGlobalConfigUpdateHooks(); + removeConvertRecoverData(); + collectEncryptEntityMetadata(); + handleNeedDecryptEntity(); + handleNewAddedEncryptEntity(); return true; } diff --git a/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeResult.java b/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeResult.java deleted file mode 100644 index 62970a5a906..00000000000 --- a/core/src/main/java/org/zstack/core/encrypt/EncryptFacadeResult.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.zstack.core.encrypt; - -import org.zstack.header.errorcode.ErrorCode; - -/** - * Created by LiangHanYu on 2021/11/14 19:16 - */ -public class EncryptFacadeResult { - T result; - ErrorCode error = null; - - public EncryptFacadeResult() { - } - - public EncryptFacadeResult(T result) { - this.result = result; - } - - public EncryptFacadeResult(ErrorCode error) { - this.error = error; - } - - public T getResult() { - return result; - } - - public void setResult(T result) { - this.result = result; - } - - public ErrorCode getError() { - return error; - } - - public void setError(ErrorCode error) { - this.error = error; - } -} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/encrypt/EncryptResult.java b/core/src/main/java/org/zstack/core/encrypt/EncryptResult.java new file mode 100644 index 00000000000..56bb2c38dac --- /dev/null +++ b/core/src/main/java/org/zstack/core/encrypt/EncryptResult.java @@ -0,0 +1,38 @@ +package org.zstack.core.encrypt; + +import org.zstack.header.errorcode.ErrorCode; + +/** + * Created by LiangHanYu on 2021/11/14 19:16 + */ +public class EncryptResult { + T result; + ErrorCode error = null; + + public EncryptResult() { + } + + public EncryptResult(T result) { + this.result = result; + } + + public EncryptResult(ErrorCode error) { + this.error = error; + } + + public T getResult() { + return result; + } + + public void setResult(T result) { + this.result = result; + } + + public ErrorCode getError() { + return error; + } + + public void setError(ErrorCode error) { + this.error = error; + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/errorcode/APICheckElaborationContentMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/errorcode/APICheckElaborationContentMsgDoc_zh_cn.groovy index 8ef6edea651..e5509d42376 100644 --- a/core/src/main/java/org/zstack/core/errorcode/APICheckElaborationContentMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/errorcode/APICheckElaborationContentMsgDoc_zh_cn.groovy @@ -27,9 +27,8 @@ doc { desc "要检查的文件内容,可以为一个目录" location "body" type "String" - optional false + optional true since "3.3.0" - } column { name "elaborateContent" @@ -37,9 +36,8 @@ doc { desc "要检查的文件内容,格式为json" location "body" type "String" - optional false + optional true since "3.6.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.3.0" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.3.0" - } } } diff --git a/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationCategoriesMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationCategoriesMsgDoc_zh_cn.groovy index c40805c2899..0663d082e5c 100644 --- a/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationCategoriesMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationCategoriesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "3.3.0" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.3.0" - } } } diff --git a/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationsMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationsMsgDoc_zh_cn.groovy index 94f78b87fe9..f300e7c4d62 100644 --- a/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationsMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/errorcode/APIGetElaborationsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "3.3.0" - } column { name "regex" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.3.0" - } column { name "code" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.6.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.3.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.3.0" - } } } diff --git a/core/src/main/java/org/zstack/core/errorcode/APIReloadElaborationMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/errorcode/APIReloadElaborationMsgDoc_zh_cn.groovy index ed96ff6e0f5..666b71cf5dc 100644 --- a/core/src/main/java/org/zstack/core/errorcode/APIReloadElaborationMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/errorcode/APIReloadElaborationMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "3.3.0" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.3.0" - } } } diff --git a/core/src/main/java/org/zstack/core/eventlog/APIQueryEventLogMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/eventlog/APIQueryEventLogMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..fa45815ea9f --- /dev/null +++ b/core/src/main/java/org/zstack/core/eventlog/APIQueryEventLogMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.core.eventlog + +import org.zstack.core.eventlog.APIQueryEventLogReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryEventLog" + + category "未知类别" + + desc """查询Event Log""" + + rest { + request { + url "GET /v1/eventlogs" + url "GET /v1/eventlogs/{id}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryEventLogMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryEventLogReply.class + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/eventlog/APIQueryEventLogReplyDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/eventlog/APIQueryEventLogReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..50000453d6d --- /dev/null +++ b/core/src/main/java/org/zstack/core/eventlog/APIQueryEventLogReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.core.eventlog + +import org.zstack.core.eventlog.EventLogInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询事件日志的结果" + + ref { + name "inventories" + path "org.zstack.core.eventlog.APIQueryEventLogReply.inventories" + desc "null" + type "List" + since "4.2.0" + clz EventLogInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.2.0" + } + ref { + name "error" + path "org.zstack.core.eventlog.APIQueryEventLogReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.2.0" + clz ErrorCode.class + } +} diff --git a/core/src/main/java/org/zstack/core/eventlog/EventLogGlobalConfig.java b/core/src/main/java/org/zstack/core/eventlog/EventLogGlobalConfig.java index 89631cec65c..cfe0f36843e 100644 --- a/core/src/main/java/org/zstack/core/eventlog/EventLogGlobalConfig.java +++ b/core/src/main/java/org/zstack/core/eventlog/EventLogGlobalConfig.java @@ -10,6 +10,6 @@ public class EventLogGlobalConfig { public static final String CATEGORY = "eventlog"; @GlobalConfigValidation(inNumberRange = {0, 180}) - @GlobalConfigDef(defaultValue = "14", type = Integer.class, description = "How long a log entry can stay in database") + @GlobalConfigDef(defaultValue = "90", type = Integer.class, description = "How long a log entry can stay in database") public static GlobalConfig EXPIRE_TIME_IN_DAY = new GlobalConfig(CATEGORY, "expireTimeInDay"); } diff --git a/core/src/main/java/org/zstack/core/eventlog/EventLogInventoryDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/eventlog/EventLogInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..7485a234fad --- /dev/null +++ b/core/src/main/java/org/zstack/core/eventlog/EventLogInventoryDoc_zh_cn.groovy @@ -0,0 +1,63 @@ +package org.zstack.core.eventlog + +import java.sql.Timestamp + +doc { + + title "Event Log的数据结构" + + field { + name "id" + desc "" + type "long" + since "4.2.0" + } + field { + name "content" + desc "" + type "String" + since "4.2.0" + } + field { + name "resourceUuid" + desc "资源UUID" + type "String" + since "4.2.0" + } + field { + name "resourceType" + desc "" + type "String" + since "4.2.0" + } + field { + name "category" + desc "" + type "String" + since "4.2.0" + } + field { + name "trackingId" + desc "" + type "String" + since "4.2.0" + } + field { + name "type" + desc "" + type "String" + since "4.2.0" + } + field { + name "time" + desc "" + type "long" + since "4.2.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.2.0" + } +} diff --git a/core/src/main/java/org/zstack/core/eventlog/EventLogManager.java b/core/src/main/java/org/zstack/core/eventlog/EventLogManager.java index 4d15ecb5cc8..3f64b1920fa 100644 --- a/core/src/main/java/org/zstack/core/eventlog/EventLogManager.java +++ b/core/src/main/java/org/zstack/core/eventlog/EventLogManager.java @@ -11,6 +11,8 @@ import org.zstack.header.Component; import org.zstack.header.core.ExceptionSafe; import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.header.vm.VmSchedHistoryVO; +import org.zstack.header.vm.VmSchedHistoryVO_; import org.zstack.utils.Utils; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; @@ -143,6 +145,9 @@ private void cleanup() { UpdateQuery.New(EventLogVO.class) .lt(EventLogVO_.createDate, deadline) .hardDelete(); + UpdateQuery.New(VmSchedHistoryVO.class) + .lt(VmSchedHistoryVO_.createDate, deadline) + .hardDelete(); } }); } diff --git a/core/src/main/java/org/zstack/core/externalservice/AbstractLocalExternalSystemdService.java b/core/src/main/java/org/zstack/core/externalservice/AbstractLocalExternalSystemdService.java new file mode 100644 index 00000000000..c9bc63e2d84 --- /dev/null +++ b/core/src/main/java/org/zstack/core/externalservice/AbstractLocalExternalSystemdService.java @@ -0,0 +1,17 @@ +package org.zstack.core.externalservice; + +import org.zstack.utils.Bash; + +public abstract class AbstractLocalExternalSystemdService extends AbstractLocalExternalService{ + abstract public String getSystemdServiceName(); + + public void sysctl(String ctl) { + new Bash() { + @Override + protected void scripts() { + setE(); + run("systemctl %s %s", ctl, getSystemdServiceName()); + } + }.execute(); + } +} diff --git a/core/src/main/java/org/zstack/core/externalservice/ExternalService.java b/core/src/main/java/org/zstack/core/externalservice/ExternalService.java index 4ffb9f7d15a..2b816f00337 100755 --- a/core/src/main/java/org/zstack/core/externalservice/ExternalService.java +++ b/core/src/main/java/org/zstack/core/externalservice/ExternalService.java @@ -1,5 +1,7 @@ package org.zstack.core.externalservice; +import org.zstack.header.core.external.service.ExternalServiceCapabilities; + public interface ExternalService { String getName(); @@ -10,4 +12,8 @@ public interface ExternalService { void restart(); boolean isAlive(); + + ExternalServiceCapabilities getExternalServiceCapabilities(); + + void reload(); } diff --git a/core/src/main/java/org/zstack/core/externalservice/ExternalServiceCapabilitiesBuilder.java b/core/src/main/java/org/zstack/core/externalservice/ExternalServiceCapabilitiesBuilder.java new file mode 100644 index 00000000000..0ad11093d08 --- /dev/null +++ b/core/src/main/java/org/zstack/core/externalservice/ExternalServiceCapabilitiesBuilder.java @@ -0,0 +1,14 @@ +package org.zstack.core.externalservice; + +import org.zstack.header.core.external.service.ExternalServiceCapabilities; + +public class ExternalServiceCapabilitiesBuilder extends ExternalServiceCapabilities { + public static ExternalServiceCapabilitiesBuilder build() { + return new ExternalServiceCapabilitiesBuilder(); + } + + public ExternalServiceCapabilitiesBuilder reloadConfig(boolean reloadConfig) { + setReloadConfig(reloadConfig); + return this; + } +} diff --git a/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManager.java b/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManager.java index fa048d1abf8..e1c2b47301f 100755 --- a/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManager.java +++ b/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManager.java @@ -3,6 +3,8 @@ import java.util.function.Supplier; public interface ExternalServiceManager { + String SERVICE_ID = "externalService"; + ExternalService registerService(ExternalService service); void deregisterService(String name); diff --git a/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java b/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java index 54a12c2d444..b953329dc39 100755 --- a/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java +++ b/core/src/main/java/org/zstack/core/externalservice/ExternalServiceManagerImpl.java @@ -1,15 +1,30 @@ package org.zstack.core.externalservice; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.header.AbstractService; +import org.zstack.header.core.external.service.APIGetExternalServicesMsg; +import org.zstack.header.core.external.service.APIGetExternalServicesReply; +import org.zstack.header.core.external.service.APIReloadExternalServiceEvent; +import org.zstack.header.core.external.service.APIReloadExternalServiceMsg; +import org.zstack.header.core.external.service.ExternalServiceInventory; +import org.zstack.header.core.external.service.ExternalServiceStatus; import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; -import static org.zstack.core.Platform.operr; - -import java.util.HashMap; +import java.util.ArrayList; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; -public class ExternalServiceManagerImpl implements ExternalServiceManager { - private Map services = new HashMap<>(); +import static org.zstack.core.Platform.operr; + +public class ExternalServiceManagerImpl extends AbstractService implements ExternalServiceManager { + @Autowired + public CloudBus bus; + + private final Map services = new ConcurrentHashMap<>(); @Override public ExternalService registerService(ExternalService service) { @@ -41,4 +56,75 @@ public ExternalService getService(String name, Supplier supplie service = supplier.get(); return registerService(service); } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + public void handleApiMessage(APIMessage msg) { + if (msg instanceof APIGetExternalServicesMsg) { + handle((APIGetExternalServicesMsg) msg); + } else if (msg instanceof APIReloadExternalServiceMsg) { + handle((APIReloadExternalServiceMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIReloadExternalServiceMsg msg) { + APIReloadExternalServiceEvent event = new APIReloadExternalServiceEvent(msg.getId()); + ExternalService service = services.get(msg.getName()); + if (service == null) { + event.setError(operr("service[%s] is not registered", msg.getName())); + bus.publish(event); + return; + } + + if (!service.getExternalServiceCapabilities().isReloadConfig()) { + event.setError(operr("service[%s] does not support reload config", msg.getName())); + } + + if (service.isAlive()) { + service.reload(); + } else { + event.setError(operr("service[%s] is not running", msg.getName())); + } + + bus.publish(event); + } + + private void handle(APIGetExternalServicesMsg msg) { + APIGetExternalServicesReply reply = new APIGetExternalServicesReply(); + reply.setInventories(new ArrayList<>()); + + services.forEach((name, service) -> { + ExternalServiceInventory inv = new ExternalServiceInventory(); + inv.setName(name); + inv.setStatus(service.isAlive() ? ExternalServiceStatus.RUNNING.toString() : ExternalServiceStatus.STOPPED.toString()); + inv.setCapabilities(service.getExternalServiceCapabilities()); + reply.getInventories().add(inv); + }); + + bus.reply(msg, reply); + } + + @Override + public String getId() { + return bus.makeLocalServiceId(SERVICE_ID); + } } diff --git a/core/src/main/java/org/zstack/core/gc/APIDeleteGCJobMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/gc/APIDeleteGCJobMsgDoc_zh_cn.groovy index a868f64e674..b6f60465858 100644 --- a/core/src/main/java/org/zstack/core/gc/APIDeleteGCJobMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/gc/APIDeleteGCJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/core/src/main/java/org/zstack/core/gc/APIQueryGCJobMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/gc/APIQueryGCJobMsgDoc_zh_cn.groovy index 8b08bfa3fd2..d6e3aaee725 100644 --- a/core/src/main/java/org/zstack/core/gc/APIQueryGCJobMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/gc/APIQueryGCJobMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.core.gc import org.zstack.core.gc.APIQueryGCJobReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryGCJob" diff --git a/core/src/main/java/org/zstack/core/gc/APITriggerGCJobMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/gc/APITriggerGCJobMsgDoc_zh_cn.groovy index bd3228445fe..14f4d3fdd4f 100644 --- a/core/src/main/java/org/zstack/core/gc/APITriggerGCJobMsgDoc_zh_cn.groovy +++ b/core/src/main/java/org/zstack/core/gc/APITriggerGCJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/core/src/main/java/org/zstack/core/gc/GarbageCollector.java b/core/src/main/java/org/zstack/core/gc/GarbageCollector.java index 747c307f479..a27b2c5a073 100755 --- a/core/src/main/java/org/zstack/core/gc/GarbageCollector.java +++ b/core/src/main/java/org/zstack/core/gc/GarbageCollector.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; import static org.zstack.core.Platform.inerr; @@ -111,7 +112,7 @@ protected void fail(ErrorCode err) { dbf.update(vo); } - private String buildContext() { + protected String buildContext() { Map context = new HashMap<>(); for (Field f : FieldUtils.getAllFields(getClass())) { @@ -161,6 +162,17 @@ public void updateContext() { .update(); } + public static String updateContext(String uuid, String context, Class clazz, Consumer consumer) { + T gc = JSONObjectUtil.toObject(context, clazz); + consumer.accept(gc); + context = gc.buildContext(); + SQL.New(GarbageCollectorVO.class).eq(GarbageCollectorVO_.uuid, uuid) + .set(GarbageCollectorVO_.context, context) + .update(); + + return context; + } + void loadFromVO(GarbageCollectorVO vo) { Object dataObj = JSONObjectUtil.toObject(vo.getContext(), getClass()); @@ -190,8 +202,12 @@ void runTrigger() { GarbageCollector self = this; EXECUTED_TIMES++; - boolean isExisting = Q.New(GarbageCollectorVO.class).eq(GarbageCollectorVO_.uuid, getUuid()).isExists(); - if (!isExisting) { + boolean existAndNotDone = Q.New(GarbageCollectorVO.class) + .eq(GarbageCollectorVO_.uuid, getUuid()) + .notEq(GarbageCollectorVO_.status, GCStatus.Done) + .isExists(); + + if (!existAndNotDone) { canceller.run(); gcMgr.deregisterGC(self); return; diff --git a/core/src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java b/core/src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java index 80510295c64..9cbc35b3217 100755 --- a/core/src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java +++ b/core/src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java @@ -60,7 +60,7 @@ public class GarbageCollectorManagerImpl extends AbstractService private ConcurrentHashMap managedGarbageCollectors = new ConcurrentHashMap<>(); - private void startScanOrphanJobs() { + private synchronized void startScanOrphanJobs() { if (scanOrphanJobsTask != null) { scanOrphanJobsTask.cancel(true); } @@ -94,7 +94,7 @@ public void run() { logger.debug(String.format("[GC] starts scanning orphan job thread with the interval[%ss]", GCGlobalConfig.SCAN_ORPHAN_JOB_INTERVAL.value(Integer.class))); } - private void startCleanUpCompletedJobs() { + private synchronized void startCleanUpCompletedJobs() { if (cleanUpCompletedJobsTask != null) { cleanUpCompletedJobsTask.cancel(true); } diff --git a/core/src/main/java/org/zstack/core/gc/TimeBasedGarbageCollector.java b/core/src/main/java/org/zstack/core/gc/TimeBasedGarbageCollector.java index c82d6e56ee8..e7b3075b554 100755 --- a/core/src/main/java/org/zstack/core/gc/TimeBasedGarbageCollector.java +++ b/core/src/main/java/org/zstack/core/gc/TimeBasedGarbageCollector.java @@ -18,7 +18,7 @@ public abstract class TimeBasedGarbageCollector extends GarbageCollector { private TimerTask currentTimer; public TimeBasedGarbageCollector() { - canceller = () -> {}; + canceller = this::destroy; } protected void setupTimer() { @@ -52,6 +52,7 @@ protected void fail(ErrorCode err) { public void load(GarbageCollectorVO vo) { loadFromVO(vo); + prepare(); setupTimer(); } @@ -59,8 +60,8 @@ public final void submit(Long next, TimeUnit unit) { NEXT_TIME_UNIT = unit; NEXT_TIME = next; - cleanThreadContext(); saveToDb(); + prepare(); setupTimer(); gcMgr.registerGC(this); @@ -72,4 +73,7 @@ public void deduplicateSubmit(Long next, TimeUnit unit) { } submit(next, unit); } + + protected void prepare() {} + protected void destroy() {} } diff --git a/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventory.java b/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventory.java index 5b3017f9e13..4ee009e10ff 100644 --- a/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventory.java +++ b/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventory.java @@ -1,5 +1,8 @@ package org.zstack.core.jsonlabel; +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; @@ -8,6 +11,8 @@ /** * Created by xing5 on 2016/9/13. */ +@Inventory(mappingVOClass = JsonLabelVO.class) +@PythonClassInventory public class JsonLabelInventory { private long id; private String labelKey; diff --git a/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventoryDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..a8758699511 --- /dev/null +++ b/core/src/main/java/org/zstack/core/jsonlabel/JsonLabelInventoryDoc_zh_cn.groovy @@ -0,0 +1,46 @@ +package org.zstack.core.jsonlabel + +import java.sql.Timestamp + +doc { + + title "JsonLabelInventory的数据结构" + + field { + name "id" + desc "唯一标识符" + type "long" + since "4.2.0" + } + field { + name "labelKey" + desc "标签键" + type "String" + since "4.2.0" + } + field { + name "labelValue" + desc "标签值" + type "String" + since "4.2.0" + } + field { + name "resourceUuid" + desc "资源UUID" + type "String" + since "4.2.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.2.0" + } + field { + name "lastOpDate" + desc "最后操作时间" + type "Timestamp" + since "4.2.0" + } +} + diff --git a/core/src/main/java/org/zstack/core/log/LogGlobalConfig.java b/core/src/main/java/org/zstack/core/log/LogGlobalConfig.java index a368ed1fbcc..041124abe33 100644 --- a/core/src/main/java/org/zstack/core/log/LogGlobalConfig.java +++ b/core/src/main/java/org/zstack/core/log/LogGlobalConfig.java @@ -1,6 +1,7 @@ package org.zstack.core.log; import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; @@ -13,4 +14,8 @@ public class LogGlobalConfig { @GlobalConfigValidation public static GlobalConfig LOG_DELETE_ACCUMULATED_FILE_SIZE = new GlobalConfig(CATEGORY, "log.delete.accumulatedFileSize"); + + @GlobalConfigValidation(numberGreaterThan = 1) + @GlobalConfigDef(defaultValue = "30", type = Long.class, description = "sync custom log configuration interval") + public static GlobalConfig SYNC_CUSTOM_LOG_CONFIGURATION_TASK_INTERVAL = new GlobalConfig(CATEGORY, "log.syncCustomLogConfigurationTaskInterval"); } diff --git a/core/src/main/java/org/zstack/core/log/LogSafeGson.java b/core/src/main/java/org/zstack/core/log/LogSafeGson.java index 396af553947..c3dcd26626c 100644 --- a/core/src/main/java/org/zstack/core/log/LogSafeGson.java +++ b/core/src/main/java/org/zstack/core/log/LogSafeGson.java @@ -2,8 +2,11 @@ import com.google.gson.*; import org.apache.logging.log4j.util.Strings; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.log.NoLogging; import org.zstack.header.message.GsonTransient; +import org.zstack.header.message.JsonSchemaBuilder; import org.zstack.header.message.Message; import org.zstack.utils.BeanUtils; import org.zstack.utils.FieldUtils; @@ -11,6 +14,7 @@ import org.zstack.utils.function.Function; import org.zstack.utils.gson.GsonUtil; import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; import java.io.Serializable; import java.lang.reflect.Field; @@ -21,8 +25,31 @@ * Created by MaJin on 2019/9/21. */ public class LogSafeGson { - private static Map> maskFields = new HashMap<>(); - private static Map> autoFields = new HashMap<>(); + private static final CLogger logger = Utils.getLogger(LogSafeGson.class); + + /** + * class and its need be masked fields + */ + private static final Map> maskFields = new HashMap<>(); + /** + * field with annotation @NoLogging(behavior = NoLogging.Behavior.Auto) will be collect to this map + * + * when serialize class with autoFields, the specific class will be found (for example, its super class) and + * then execute serialize. + * + * this should be used for base abstractions + */ + private static final Map> autoFields = new HashMap<>(); + + /** + * used for class implements Serializable or Message for potential sensitive check + * + * this is different from autoFields, because with NoLogging means there are some + * sensitive fields so more extendable fields check could be used. + * + * all class not annotated with NoLogging will be store in potentialSensitiveFields. + */ + private static final Map> potentialSensitiveFields = new HashMap<>(); private static final List> searchClasses = Arrays.asList(Serializable.class, Message.class); private static final Gson logSafeGson; @@ -32,7 +59,7 @@ private static class FieldNoLogging { NoLogging annotation; Field classNameField; - private static Pattern uriPattern = Pattern.compile(":[^:]*@"); + private static final Pattern uriPattern = Pattern.compile(":[^:]*@"); FieldNoLogging(Field field) { this.field = field; @@ -91,14 +118,15 @@ public boolean shouldSkipField(FieldAttributes f) { public boolean shouldSkipClass(Class clazz) { return false; } - }).create(); + }).enableComplexMapKeySerialization().create(); for (Class baseClz : searchClasses) { for (Class clz : BeanUtils.reflections.getSubTypesOf(baseClz)) { - if (!clz.isInterface()) { - cacheNoLoggingInfo(clz); + if (clz.isInterface()) { + continue; } + cacheNoLoggingInfo(clz); } } } @@ -107,22 +135,42 @@ private static void cacheNoLoggingInfo(Class si) { for (Field f : FieldUtils.getAllFields(si)) { NoLogging an = f.getAnnotation(NoLogging.class); if (an != null) { + logger.trace(String.format("load @NoLogging annotated class: %s, fields: %s", si.getName(), f.getName())); + f.setAccessible(true); if (an.behavior().auto()) { autoFields.computeIfAbsent(si, k -> new HashSet<>()).add(new FieldNoLogging(f, an, si)); } else { maskFields.computeIfAbsent(si, k -> new HashSet<>()).add(new FieldNoLogging(f, an, si)); } - } else if (mayHasSensitiveInfo(f.getType()) && !f.getType().isEnum() && !f.getType().isAssignableFrom(si)) { - f.setAccessible(true); - autoFields.computeIfAbsent(si, k -> new HashSet<>()).add(new FieldNoLogging(f)); } + + if (f.getType().isEnum() || f.getType().isAssignableFrom(si)) { + continue; + } + + if (Collection.class.isAssignableFrom(f.getType())) { + Class genericType = FieldUtils.getGenericType(f); + if (genericType == null || !mayHasSensitiveInfo(genericType)) { + continue; + } + } else if (!mayHasSensitiveInfo(f.getType())) { + continue; + } + + f.setAccessible(true); + logger.trace(String.format("load potentially sensitive info contained class: %s, fields: %s", si.getName(), f.getName())); + potentialSensitiveFields.computeIfAbsent(si, k -> new HashSet<>()).add(new FieldNoLogging(f)); } } private static JsonSerializer getSerializer() { return (o, type, jsonSerializationContext) -> { - JsonObject jObj = logSafeGson.toJsonTree(o).getAsJsonObject(); + JsonElement jsonElement = logSafeGson.toJsonTree(o); + if (!jsonElement.isJsonObject()) { + return jsonElement; + } + JsonObject jObj = jsonElement.getAsJsonObject(); maskFields.getOrDefault(o.getClass(), Collections.emptySet()).forEach(f -> { Object obj = f.getValue(o); if (obj instanceof Collection) { @@ -145,6 +193,16 @@ private static JsonSerializer getSerializer() { } }); + potentialSensitiveFields.getOrDefault(o.getClass(), Collections.emptySet()).forEach(f -> { + Object si = f.getValue(o); + if (mayHasSensitiveInfo(si)) { + jObj.add(f.getName(), toJsonElement(si)); + } else if (si instanceof Collection) { + JsonArray array = new JsonArray(); + ((Collection) si).forEach(v -> array.add(toJsonElement(v))); + jObj.add(f.getName(), array); + } + }); return jObj; }; } @@ -158,7 +216,57 @@ public static String toJson(Object o) { } public static boolean needMaskLog(Class clz) { - return maskFields.keySet().contains(clz); + return maskFields.containsKey(clz); + } + + /** + * only use maskFields and autoFields to check class + * most likely contains sensitive info which is collected from + * @NoLogging annotated classes. + * + * @param clz the class need check if contains any sensitive field + * @return if the class has any field annotated by @NoLogging return false + * else return true + */ + private static boolean mostLikelyCommonClass(Class clz) { + return !maskFields.containsKey(clz) && !autoFields.containsKey(clz); + } + + public static Message desensitize(Message o) { + if (o == null || mostLikelyCommonClass(o.getClass())) { + logger.trace(String.format("%s is not class annotated by @NoLogging, skip desensitize", + o != null ? o.getClass().getCanonicalName() : null)); + return o; + } + + buildSchemaIfNeed(o); + String retStr = toJson(o); + Map raw = JSONObjectUtil.toObject(retStr, LinkedHashMap.class); + Message result = JSONObjectUtil.toObject(retStr, o.getClass()); + + try { + result.restoreFromSchema(raw); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + logger.trace(String.format("object class: %s \ntransform sensitive object: %s \n to insensitive object: %s", + o.getClass().getName(), + JSONObjectUtil.toJsonString(o), + JSONObjectUtil.toJsonString(result))); + + return result; + } + + private static void buildSchemaIfNeed(Message msg) { + if (msg.getHeaderEntry(CloudBus.HEADER_SCHEMA) != null) { + return; + } + + try { + msg.putHeaderEntry(CloudBus.HEADER_SCHEMA, new JsonSchemaBuilder(msg).build()); + } catch (Exception e) { + throw new CloudRuntimeException(e); + } } public static Map getValuesToMask(Object o) { @@ -185,6 +293,19 @@ public static Map getValuesToMask(Object o) { } }); + potentialSensitiveFields.getOrDefault(o.getClass(), Collections.emptySet()).forEach(f -> { + Object si = f.getValue(o); + if (mayHasSensitiveInfo(si)) { + results.putAll(getValuesToMask(si)); + } else if (si instanceof Collection) { + ((Collection) si).forEach(v -> { + if (mayHasSensitiveInfo(v)) { + results.put(v.toString(), f.getMaskedValue(v.toString())); + } + }); + } + }); + results.remove(Strings.EMPTY); return results; } diff --git a/core/src/main/java/org/zstack/core/plugin/PluginApiInterceptor.java b/core/src/main/java/org/zstack/core/plugin/PluginApiInterceptor.java new file mode 100644 index 00000000000..41769af5596 --- /dev/null +++ b/core/src/main/java/org/zstack/core/plugin/PluginApiInterceptor.java @@ -0,0 +1,33 @@ +package org.zstack.core.plugin; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.core.external.plugin.APIDeletePluginDriversMsg; +import org.zstack.header.core.external.plugin.PluginDriversExtensionPoint; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.APIMessage; + +class PluginApiInterceptor implements ApiMessageInterceptor { + @Autowired + protected PluginRegistry pluginRgty; + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIDeletePluginDriversMsg) { + validate((APIDeletePluginDriversMsg) msg); + } + + return msg; + } + + private void validate(APIDeletePluginDriversMsg msg) { + for (PluginDriversExtensionPoint ext : pluginRgty.getExtensionList(PluginDriversExtensionPoint.class)) { + ErrorCode result = ext.validateDeletePluginDrivers(msg.getUuid()); + if (result != null) { + throw new ApiMessageInterceptionException(result); + } + } + } +} diff --git a/core/src/main/java/org/zstack/core/plugin/PluginGlobalConfig.java b/core/src/main/java/org/zstack/core/plugin/PluginGlobalConfig.java new file mode 100644 index 00000000000..e5114f2a9fe --- /dev/null +++ b/core/src/main/java/org/zstack/core/plugin/PluginGlobalConfig.java @@ -0,0 +1,20 @@ +package org.zstack.core.plugin; + +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; +import org.zstack.core.config.GlobalConfigDefinition; +import org.zstack.core.config.GlobalConfigValidation; + +/** + * PluginGlobalConfig implementation. + */ +@GlobalConfigDefinition +public class PluginGlobalConfig { + public static final String CATEGORY = "plugin"; + + @GlobalConfigValidation + @GlobalConfigDef(type = Boolean.class, defaultValue = "true") + public static GlobalConfig ALLOW_UNKNOWN_PRODUCT_PLUGIN = + new GlobalConfig(CATEGORY, "allow.unknown.product.plugin"); + +} diff --git a/core/src/main/java/org/zstack/core/plugin/PluginManager.java b/core/src/main/java/org/zstack/core/plugin/PluginManager.java new file mode 100644 index 00000000000..4e1b78c33d2 --- /dev/null +++ b/core/src/main/java/org/zstack/core/plugin/PluginManager.java @@ -0,0 +1,28 @@ +package org.zstack.core.plugin; + +import org.zstack.abstraction.PluginDriver; + +import java.util.List; + +/** + * PluginManager interface for plugin related operations. + *

+ * isFeatureSupported used for plugin capability check. + * getPlugin used for get plugin singleton. + *

+ */ +public interface PluginManager { + String SERVICE_ID = "external.plugin"; + + boolean isFeatureSupported(String pluginUuid, String capability); + + T getPlugin(String pluginUuid); + + List getPluginList(Class pluginClass); + + // check if a sub plugin class with a type exists + boolean isPluginTypeExist(Class pluginClass, String type); + + // get plugin class with type + T getPlugin(Class pluginClass, String type); +} diff --git a/core/src/main/java/org/zstack/core/plugin/PluginManagerImpl.java b/core/src/main/java/org/zstack/core/plugin/PluginManagerImpl.java new file mode 100644 index 00000000000..823a3ea91e9 --- /dev/null +++ b/core/src/main/java/org/zstack/core/plugin/PluginManagerImpl.java @@ -0,0 +1,490 @@ +package org.zstack.core.plugin; + +import org.reflections.Reflections; +import org.reflections.scanners.Scanners; +import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import org.reflections.util.FilterBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.abstraction.PluginDriver; +import org.zstack.abstraction.PluginValidator; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.AbstractService; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.external.plugin.*; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.managementnode.ManagementNodeVO; +import org.zstack.header.managementnode.ManagementNodeVO_; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; +import org.zstack.utils.Bash; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.path.PathUtil; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import static org.zstack.core.Platform.operr; + +/** + * PluginManagerImpl implementation of PluginManager. + */ +public class PluginManagerImpl extends AbstractService implements PluginManager { + private static final CLogger logger = Utils.getLogger(PluginManagerImpl.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + private ThreadFacade thdf; + + private final Set> pluginMetadata = new HashSet<>(); + private final Map pluginInstances = new ConcurrentHashMap<>(); + private final Map, List> + pluginRegisters = new HashMap<>(); + private final Map, PluginValidator> + pluginValidators = new HashMap<>(); + private String fileDirPath = PathUtil.join(CoreGlobalProperty.DATA_DIR, "/plugins/"); + + public String getFileDirPath() { + return fileDirPath; + } + + public void setFileDirPath(String fileDirPath) { + this.fileDirPath = fileDirPath; + } + + private void collectPluginProtocolMetadata() { + ConfigurationBuilder builder = ConfigurationBuilder.build() + .setUrls(ClasspathHelper.forPackage("org.zstack")) + .setScanners(Scanners.SubTypes, Scanners.MethodsAnnotated, + Scanners.FieldsAnnotated, Scanners.TypesAnnotated, + Scanners.MethodsParameter) + .setExpandSuperTypes(false) + .filterInputsBy(new FilterBuilder().includePackage("org.zstack")); + Reflections reflections = new Reflections(builder); + reflections.getSubTypesOf(PluginDriver.class).forEach(clz -> { + if (!clz.getCanonicalName().contains("org.zstack.abstraction") + || !clz.isInterface()) { + return; + } + + if (pluginMetadata.contains(clz)) { + throw new CloudRuntimeException( + String.format("duplicate PluginProtocol[name: %s]", clz)); + } + + pluginMetadata.add(clz); + }); + } + + protected void registerPluginAsSingleton( + Class pluginRegisterClz, + Class pluginDriverClz) { + try { + PluginDriver pluginDriver = pluginRegisterClz + .getConstructor() + .newInstance(); + + if (pluginValidators.containsKey(pluginRegisterClz)) { + pluginValidators.get(pluginRegisterClz).validate(pluginDriver); + } + + // String format all String methods of plugin from pluginRegister to logger.debug + logger.debug(String.format("%s[class: %s, productKey: %s, version: %s," + + " capabilities: %s, description: %s, vendor: %s, url: %s," + + " license: %s]", + pluginInstances.containsKey(pluginDriver.uuid()) ? "reload plugin" : "register plugin", + pluginRegisterClz, + pluginDriver.uuid(), + pluginDriver.version(), + JSONObjectUtil.toJsonString(pluginDriver.features()), + pluginDriver.description(), + pluginDriver.vendor(), + pluginDriver.url(), + pluginDriver.license())); + + verifyPluginProduct(pluginDriver); + + pluginInstances.put(pluginDriver.uuid(), pluginDriver); + pluginRegisters.computeIfAbsent(pluginDriverClz, k -> new ArrayList<>()); + pluginRegisters.get(pluginDriverClz).add(pluginDriver); + + PluginDriverVO vo = dbf.findByUuid(pluginDriver.uuid(), PluginDriverVO.class); + if (vo == null) { + vo = new PluginDriverVO(); + vo.setUuid(pluginDriver.uuid()); + vo.setName(pluginDriver.name()); + vo.setVendor(pluginDriver.vendor()); + vo.setFeatures(JSONObjectUtil.toJsonString(pluginDriver.features())); + vo.setType(pluginDriver.type()); + vo.setDescription(pluginDriver.description()); + vo.setVersion(pluginDriver.version()); + vo.setLicense(pluginDriver.license()); + vo.setOptionTypes(JSONObjectUtil.toJsonString(pluginDriver.optionTypes())); + dbf.persist(vo); + } else { + vo.setName(pluginDriver.name()); + vo.setVendor(pluginDriver.vendor()); + vo.setFeatures(JSONObjectUtil.toJsonString(pluginDriver.features())); + vo.setType(pluginDriver.type()); + vo.setDescription(pluginDriver.description()); + vo.setVersion(pluginDriver.version()); + vo.setLicense(pluginDriver.license()); + vo.setOptionTypes(JSONObjectUtil.toJsonString(pluginDriver.optionTypes())); + dbf.update(vo); + } + } catch (Exception e) { + throw new CloudRuntimeException(e); + } + } + + private void getPluginInterfaceSingletons(Class abstractPluginClz) { + Platform.getReflections() + .getSubTypesOf(abstractPluginClz) + .forEach(pluginDriverClz -> { + if (pluginDriverClz.isInterface()) { + return; + } + + registerPluginAsSingleton(pluginDriverClz, abstractPluginClz); + }); + } + + private void loadPluginsFromMetadata() { + pluginMetadata.forEach(this::getPluginInterfaceSingletons); + + pluginRegisters.forEach((pluginClazz, instanceList) -> { + PluginValidator validator = pluginValidators.get(pluginClazz); + if (validator == null) { + return; + } + + validator.validateAllPlugins(instanceList); + }); + } + + private void verifyPluginProduct(PluginDriver pluginDriver) { + if (!PluginGlobalConfig.ALLOW_UNKNOWN_PRODUCT_PLUGIN.value(Boolean.class) + && pluginDriver.uuid() == null) { + throw new OperationFailureException(operr("unknown product plugin name: %s", + pluginDriver.name())); + } + + if (pluginDriver.name() == null + || pluginDriver.uuid() == null + || pluginDriver.vendor() == null) { + throw new OperationFailureException(operr("plugin[%s] name," + + " productKey and vendor cannot be null", + pluginDriver.getClass())); + } + + doVerification(pluginDriver.name(), pluginDriver.uuid()); + } + + private void doVerification(String productName, String productKey) { + // TODO: verify plugin driver + } + + private void collectPluginValidators(Class validatorClazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + PluginValidator pluginValidator = ((Class) validatorClazz).getConstructor().newInstance(); + pluginValidators.put(pluginValidator.pluginClass(), pluginValidator); + } + + @Override + public boolean start() { + if (CoreGlobalProperty.UNIT_TEST_ON) { + return true; + } + new Bash() { + @Override + protected void scripts() { + mkdirs(fileDirPath); + } + }.execute(); + scanAndLoadPlugins(fileDirPath); + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public boolean isFeatureSupported(String pluginProductKey, + String capability) { + if (logger.isTraceEnabled()) { + logger.trace(String.format("check plugin[%s] capability[%s]", + pluginProductKey, capability)); + logger.trace(String.format("plugin features %s", + JSONObjectUtil.toJsonString(pluginInstances + .get(pluginProductKey) + .features()))); + logger.trace(String.format("plugin feature state: %s", + JSONObjectUtil.toJsonString(pluginInstances + .get(pluginProductKey) + .features().get(capability) == Boolean.TRUE))); + } + + if (pluginInstances.get(pluginProductKey) + .features() == null) { + return true; + } + + return pluginInstances.get(pluginProductKey) + .features() + .get(capability) == Boolean.TRUE; + } + + @Override + public T getPlugin(String pluginProductKey) { + if (!pluginInstances.containsKey(pluginProductKey)) { + throw new CloudRuntimeException(String.format("Unsupported plugin %s", + pluginProductKey)); + } + + return (T) pluginInstances.get(pluginProductKey); + } + + @Override + public List getPluginList(Class pluginClass) { + return (List) pluginRegisters.get(pluginClass); + } + + @Override + public boolean isPluginTypeExist(Class pluginClass, String type) { + return pluginRegisters.get(pluginClass) + .stream() + .anyMatch(plugin -> plugin.type().equals(type)); + } + + @Override + public T getPlugin(Class pluginClass, String type) { + if (pluginRegisters.get(pluginClass) + .stream() + .filter(plugin -> plugin.type().equals(type)) + .count() > 1) { + throw new CloudRuntimeException(String.format("multi plugin with same type %s", type)); + } + + return (T) pluginRegisters.get(pluginClass) + .stream() + .filter(plugin -> plugin.type().equals(type)) + .findFirst() + .orElse(null); + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof APIRefreshPluginDriversMsg) { + handle((APIRefreshPluginDriversMsg) msg); + } else if (msg instanceof APIDeletePluginDriversMsg) { + handle((APIDeletePluginDriversMsg) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleLocalMessage(Message msg) { + if (msg instanceof RefreshPluginDriversMsg) { + handle((RefreshPluginDriversMsg) msg); + } else if (msg instanceof DeletePluginDriversMsg) { + handle((DeletePluginDriversMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + protected List getJarFiles(String dirPath) { + File dir = new File(dirPath); + List jarFiles = new ArrayList<>(); + + if (!dir.exists() || !dir.isDirectory()) { + return jarFiles; + } + + File[] files = dir.listFiles((file) -> file.isFile() && file.getName().endsWith(".jar")); + if (files != null) { + for (File file : files) { + jarFiles.add(file); + } + } + return jarFiles; + } + + protected void loadPluginsFromJar(File jarFile) { + URL jarUrl = null; + try { + jarUrl = jarFile.toURI().toURL(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + try (URLClassLoader classLoader = new URLClassLoader(new URL[]{jarUrl}, getClass().getClassLoader())) { + try (JarFile jar = new JarFile(jarFile)) { + Enumeration entries = jar.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + if (!entryName.endsWith(".class")) { + continue; + } + + if (entryName.matches(".*\\$\\d+\\.class$")) { + // eg: org.zstack.CipherOnCloudCryptoPlugin$1.class + continue; + } + + if (entryName.contains("Test")) { + continue; + } + + String className = entryName.replace('/', '.').substring(0, entryName.length() - 6); + Class tempClazz = classLoader.loadClass(className); + if (className.contains("Validator")) { + collectPluginValidators(tempClazz); + continue; + } + + // Skip anonymous classes or inner classes (which are named with $) + // Anonymous classes or inner classes are typically not needed for plugin registration + if (entryName.contains("$")) { + continue; + } + + registerPluginAsSingleton((Class) tempClazz, (Class) tempClazz.getInterfaces()[0]); + } + } + } catch (Throwable t) { + logger.error(String.format("Error occurred while scanning and loading plugins from: %s", jarFile.getAbsolutePath()), t); + } + } + + protected void scanAndLoadPlugins(String directoryPath) { + List jarFiles = getJarFiles(directoryPath); + for (File jarFile : jarFiles) { + loadPluginsFromJar(jarFile); + } + } + + private void handle(RefreshPluginDriversMsg msg) { + RefreshPluginDriversReply reply = new RefreshPluginDriversReply(); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getName(); + } + + @Override + public void run(SyncTaskChain chain) { + scanAndLoadPlugins(fileDirPath); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public String getName() { + return String.format("refresh-%s-plugin-drivers", fileDirPath); + } + }); + } + + private void handle(DeletePluginDriversMsg msg) { + DeletePluginDriversReply reply = new DeletePluginDriversReply(); + pluginInstances.remove(msg.getUuid()); + if (msg.getDeletionMode() == APIDeleteMessage.DeletionMode.Permissive) { + SQL.New(PluginDriverVO.class).eq(PluginDriverVO_.uuid, msg.getUuid()).set(PluginDriverVO_.deleted, true).update(); + } else { + SQL.New(PluginDriverVO.class).eq(PluginDriverVO_.uuid, msg.getUuid()).hardDelete(); + } + bus.reply(msg, reply); + } + + private void handle(APIDeletePluginDriversMsg msg) { + APIDeletePluginDriversEvent event = new APIDeletePluginDriversEvent(msg.getId()); + new While<>(Q.New(ManagementNodeVO.class).select(ManagementNodeVO_.uuid).listValues()).step((mnUuid, com) -> { + DeletePluginDriversMsg rmsg = new DeletePluginDriversMsg(); + rmsg.setUuid(msg.getUuid()); + rmsg.setDeletionMode(msg.getDeletionMode()); + bus.makeServiceIdByManagementNodeId(rmsg, SERVICE_ID, (String) mnUuid); + bus.send(rmsg, new CloudBusCallBack(com) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + com.addError(reply.getError()); + com.allDone(); + return; + } + + com.done(); + } + }); + }, 2).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + event.setError(errorCodeList.getCauses().get(0)); + } + + bus.publish(event); + } + }); + } + + private void handle(APIRefreshPluginDriversMsg msg) { + APIRefreshPluginDriversEvent event = new APIRefreshPluginDriversEvent(msg.getId()); + new While<>(Q.New(ManagementNodeVO.class).select(ManagementNodeVO_.uuid).listValues()).step((mnUuid, com) -> { + RefreshPluginDriversMsg rmsg = new RefreshPluginDriversMsg(); + bus.makeServiceIdByManagementNodeId(rmsg, SERVICE_ID, (String) mnUuid); + bus.send(rmsg, new CloudBusCallBack(com) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + com.addError(reply.getError()); + com.allDone(); + return; + } + + com.done(); + } + }); + }, 2).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + event.setError(errorCodeList.getCauses().get(0)); + } + + bus.publish(event); + } + }); + } + + @Override + public String getId() { + return bus.makeLocalServiceId(SERVICE_ID); + } +} diff --git a/core/src/main/java/org/zstack/core/progress/ProgressCommands.java b/core/src/main/java/org/zstack/core/progress/ProgressCommands.java index 425922a3a63..5263d8a1974 100755 --- a/core/src/main/java/org/zstack/core/progress/ProgressCommands.java +++ b/core/src/main/java/org/zstack/core/progress/ProgressCommands.java @@ -32,6 +32,15 @@ public static class ProgressReportCmd { private String resourceUuid; private String progress; private String processType; + private Map detail; + + public Map getDetail() { + return detail; + } + + public void setDetail(Map detail) { + this.detail = detail; + } public Map getThreadContextMap() { return threadContextMap; diff --git a/core/src/main/java/org/zstack/core/progress/ProgressReportService.java b/core/src/main/java/org/zstack/core/progress/ProgressReportService.java index 52740eb8048..0ec682d80eb 100755 --- a/core/src/main/java/org/zstack/core/progress/ProgressReportService.java +++ b/core/src/main/java/org/zstack/core/progress/ProgressReportService.java @@ -1,5 +1,6 @@ package org.zstack.core.progress; +import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.ThreadContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; @@ -68,7 +69,7 @@ public class ProgressReportService extends AbstractService implements Management private static Map parallelTaskStage = new ConcurrentHashMap<>(); - private void startCleanupThread() { + private synchronized void startCleanupThread() { if (cleanupThread != null) { cleanupThread.cancel(true); } @@ -135,7 +136,7 @@ public String handleSyncHttpCall(ProgressReportCmd cmd) { Runnable cleanup = ThreadContextUtils.saveThreadContext(); Defer.defer(cleanup); setThreadContext(cmd); - taskProgress(TaskType.Progress, cmd.getProgress()); + taskProgressWithOpaque(TaskType.Progress, cmd.getDetail(), cmd.getProgress()); return null; } }); @@ -210,13 +211,11 @@ private void handleApiMessage(APIMessage msg) { private TaskProgressInventory inventory(TaskProgressVO vo) { TaskProgressInventory inv = new TaskProgressInventory(vo); - if (vo.getArguments() == null) { - inv.setContent(toI18nString(vo.getContent())); - } else { - List args = JSONObjectUtil.toCollection(vo.getArguments(), ArrayList.class, String.class); - inv.setContent(toI18nString(vo.getContent(), args.toArray())); - } + inv.setContent(toI18nString(vo.getContent())); + if (!StringUtils.isEmpty(vo.getArguments())) { + inv.setArguments(vo.getArguments()); + } return inv; } @@ -340,10 +339,10 @@ private static String getParentUuid() { } List lst = ThreadContext.getImmutableStack().asList(); - return lst.get(lst.size()-2); + return lst.get(lst.size() - 2); } - public static void createSubTaskProgress(String fmt, Object...args) { + public static void createSubTaskProgress(String fmt, Object... args) { if (!ProgressGlobalConfig.PROGRESS_ON.value(Boolean.class)) { return; } @@ -352,7 +351,7 @@ public static void createSubTaskProgress(String fmt, Object...args) { if (args != null) { logger.warn(String.format("no task uuid found for:" + fmt, args)); } else { - logger.warn(String.format("no task uuid found for:" + fmt, args)); + logger.warn("no task uuid found for:" + fmt); } return; } @@ -414,7 +413,11 @@ private static void persistProgress(TaskProgressVO vo, TaskType type) { Platform.getComponentLoader().getComponent(DatabaseFacade.class).persist(vo); } - private static void taskProgress(TaskType type, String fmt, Object...args) { + private static void taskProgress(TaskType type, String fmt, Object... args) { + taskProgressWithOpaque(type, null, fmt, args); + } + + private static void taskProgressWithOpaque(TaskType type, Object Opaque, String fmt, Object... args) { if (!ProgressGlobalConfig.PROGRESS_ON.value(Boolean.class)) { return; } @@ -449,6 +452,9 @@ private static void taskProgress(TaskType type, String fmt, Object...args) { if (args != null) { vo.setArguments(JSONObjectUtil.toJsonString(args)); } + if (Opaque != null) { + vo.setOpaque(JSONObjectUtil.toJsonString(Opaque)); + } vo.setType(type); vo.setTime(System.currentTimeMillis()); vo.setManagementUuid(Platform.getManagementServerId()); @@ -473,6 +479,14 @@ public static void reportProgress(String fmt) { taskProgress(TaskType.Progress, fmt); } + public static void reportProgress(String fmt, Object... args) { + if (!ProgressGlobalConfig.PROGRESS_ON.value(Boolean.class)) { + return; + } + + taskProgress(TaskType.Progress, fmt, args); + } + public void reportProgressUntil(String end, int intervalSec) { reportProgressUntil(end, intervalSec, TimeUnit.SECONDS); } @@ -557,7 +571,7 @@ public static ParallelTaskStage markParallelTaskExactStage(TaskProgressRange exa return stage; } - public static TaskProgressRange getTaskStage(){ + public static TaskProgressRange getTaskStage() { String stage = ThreadContext.get(Constants.THREAD_CONTEXT_TASK_STAGE) != null ? ThreadContext.get(Constants.THREAD_CONTEXT_TASK_STAGE) : "0-100"; return TaskProgressRange.valueOf(stage); @@ -573,14 +587,14 @@ public static List splitTaskStage(TaskProgressRange stage, Li int range = stage.getEnd() - stage.getStart(); double end = stage.getStart(); for (Number w : weight) { - results.add(new TaskProgressRange((int)end, (int)(end += (w.doubleValue() / total * range)))); + results.add(new TaskProgressRange((int) end, (int) (end += (w.doubleValue() / total * range)))); } return results; } - private static TaskProgressRange transformSubStage(TaskProgressRange parentStage, TaskProgressRange subStage){ - float ratio = (float)(parentStage.getEnd() - parentStage.getStart())/100; + private static TaskProgressRange transformSubStage(TaskProgressRange parentStage, TaskProgressRange subStage) { + float ratio = (float) (parentStage.getEnd() - parentStage.getStart()) / 100; int exactStart = Math.round(subStage.getStart() * ratio + parentStage.getStart()); int exactEnd = Math.round(subStage.getEnd() * ratio + parentStage.getStart()); return new TaskProgressRange(exactStart, exactEnd); diff --git a/core/src/main/java/org/zstack/core/rest/RESTApiController.java b/core/src/main/java/org/zstack/core/rest/RESTApiController.java index 2ee0cf9e0e7..df8657f7f73 100755 --- a/core/src/main/java/org/zstack/core/rest/RESTApiController.java +++ b/core/src/main/java/org/zstack/core/rest/RESTApiController.java @@ -13,6 +13,7 @@ import org.zstack.header.rest.RESTConstant; import org.zstack.header.rest.RESTFacade; import org.zstack.header.rest.RestAPIResponse; +import org.zstack.utils.HttpServletRequestUtils; import org.zstack.utils.Utils; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; @@ -49,10 +50,12 @@ public void queryResult(@PathVariable String uuid, HttpServletResponse rsp) thro } } - private String handleByMessageType(String body) { + private String handleByMessageType(String body, String clientIp, String clientBrowser) { APIMessage amsg = null; try { amsg = (APIMessage) RESTApiDecoder.loads(body); + amsg.setClientIp(clientIp); + amsg.setClientBrowser(clientBrowser); } catch (Throwable t) { return t.getMessage(); } @@ -69,8 +72,10 @@ private String handleByMessageType(String body) { @RequestMapping(value = RESTConstant.REST_API_CALL, method = {RequestMethod.POST, RequestMethod.PUT}) public void post(HttpServletRequest request, HttpServletResponse response) throws IOException { HttpEntity entity = restf.httpServletRequestToHttpEntity(request); + String clientIp = HttpServletRequestUtils.getClientIP(request); + String clientBrowser = HttpServletRequestUtils.getClientBrowser(request); try { - String ret = handleByMessageType(entity.getBody()); + String ret = handleByMessageType(entity.getBody(), clientIp, clientBrowser); response.setStatus(HttpStatus.SC_OK); response.setCharacterEncoding("UTF-8"); PrintWriter writer = response.getWriter(); @@ -84,4 +89,5 @@ public void post(HttpServletRequest request, HttpServletResponse response) throw response.sendError(HttpStatus.SC_INTERNAL_SERVER_ERROR, sb.toString()); } } + } diff --git a/core/src/main/java/org/zstack/core/rest/RESTApiFacadeImpl.java b/core/src/main/java/org/zstack/core/rest/RESTApiFacadeImpl.java index 625e1fb6d8b..db25fa2bb21 100755 --- a/core/src/main/java/org/zstack/core/rest/RESTApiFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/rest/RESTApiFacadeImpl.java @@ -6,16 +6,19 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.core.type.filter.AssignableTypeFilter; import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.Platform; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusEventListener; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.cloudbus.ResourceDestinationMaker; +import org.zstack.core.log.LogSafeGson; import org.zstack.core.thread.PeriodicTask; import org.zstack.core.thread.ThreadFacade; import org.zstack.header.AbstractService; import org.zstack.header.Component; import org.zstack.header.apimediator.ApiMediatorConstant; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.log.MaskSensitiveInfo; import org.zstack.header.message.*; import org.zstack.header.rest.RESTApiFacade; import org.zstack.header.rest.RestAPIResponse; @@ -33,6 +36,7 @@ import java.util.*; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; public class RESTApiFacadeImpl extends AbstractService implements RESTApiFacade, CloudBusEventListener, Component { private static final CLogger logger = Utils.getLogger(RESTApiFacadeImpl.class); @@ -43,6 +47,10 @@ public class RESTApiFacadeImpl extends AbstractService implements RESTApiFacade, private Future restAPIVOCleanTask = null; private final static int restResultMaxLength = initMaxRestResultLength(); + private static final Set maskSensitiveInfoClassNames = Platform.getReflections() + .getTypesAnnotatedWith(MaskSensitiveInfo.class).stream() + .map(Class::getSimpleName).collect(Collectors.toSet()); + @Autowired private ResourceDestinationMaker destMaker; @@ -174,6 +182,11 @@ public RestAPIResponse call(APIMessage msg) { MessageReply reply = bus.call(msg); rsp.setFinishedDate(new Date()); rsp.setState(RestAPIState.Done.toString()); + + if (CoreGlobalProperty.MASK_SENSITIVE_INFO || maskSensitiveInfoClassNames.contains(reply.getClass().getSimpleName())) { + reply = (MessageReply) LogSafeGson.desensitize(reply); + } + rsp.setResult(RESTApiDecoder.dump(reply)); return rsp; } @@ -271,7 +284,7 @@ public Set getBasePkgNames() { return basePkgNames; } - public void refreshIntervalClean() { + public synchronized void refreshIntervalClean() { if (restAPIVOCleanTask != null){ restAPIVOCleanTask.cancel(true); } diff --git a/core/src/main/java/org/zstack/core/rest/RESTApiJsonTemplateGenerator.java b/core/src/main/java/org/zstack/core/rest/RESTApiJsonTemplateGenerator.java index 2206c68839a..40e01fcfcff 100755 --- a/core/src/main/java/org/zstack/core/rest/RESTApiJsonTemplateGenerator.java +++ b/core/src/main/java/org/zstack/core/rest/RESTApiJsonTemplateGenerator.java @@ -5,6 +5,7 @@ import org.json.JSONObject; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.message.APIParam; +import org.zstack.header.message.NoJsonSchema; import org.zstack.header.rest.APINoSee; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -137,7 +138,7 @@ private static JSONObject dumpObject(Class clazz, Stack hasDone) throw do { Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { - if (f.isAnnotationPresent(APINoSee.class)) { + if (f.isAnnotationPresent(APINoSee.class) || f.isAnnotationPresent(NoJsonSchema.class)) { continue; } if (Modifier.isStatic(f.getModifiers())) { diff --git a/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java b/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java index f9589ac9278..4f2157deca2 100755 --- a/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/rest/RESTFacadeImpl.java @@ -70,6 +70,8 @@ public class RESTFacadeImpl implements RESTFacade { private String sendCommandUrl; private String callbackHostName; + private final int notifiedFailureHttpTasksSize = 128; + final private Map statistics = new ConcurrentHashMap(); final private Map httpCallhandlers = new ConcurrentHashMap(); private final List interceptors = new ArrayList(); @@ -87,6 +89,12 @@ private interface HttpCallHandlerWrapper { } final private Map wrappers = new ConcurrentHashMap(); + final private Map notifiedFailureHttpTasks = Collections.synchronizedMap(new LinkedHashMap(notifiedFailureHttpTasksSize, 0.9f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return this.size() > notifiedFailureHttpTasksSize; + } + }); void init() { DebugManager.registerDebugSignalHandler("DumpRestStats", () -> { @@ -106,6 +114,16 @@ void init() { logger.debug(sb.toString()); }); + DebugManager.registerDebugSignalHandler("DumpFailedRestTasks", () -> { + StringBuilder sb = new StringBuilder(); + sb.append("\n================ BEGIN: FAILED REST CALL TASKS ===================\n"); + synchronized (notifiedFailureHttpTasks) { + notifiedFailureHttpTasks.forEach((k, v) -> sb.append(String.format("task[%s] failed because no 'callback found for taskUuid'. request body: %s\n", k, v))); + } + sb.append("================ END: FAILED REST CALL TASKS =====================\n"); + logger.debug(sb.toString()); + }); + port = Platform.getManagementNodeServicePort(); IptablesUtils.insertRuleToFilterTable(String.format("-A INPUT -p tcp -m state --state NEW -m tcp --dport %s -j ACCEPT", port)); @@ -183,6 +201,7 @@ void notifyCallback(HttpServletRequest req, HttpServletResponse rsp) { if (wrapper == null) { rsp.sendError(HttpStatus.SC_NOT_FOUND, String.format("No callback found for taskUuid[%s]", taskUuid)); logger.warn(String.format("Received a callback request, but no 'callback found for taskUuid[%s]. request body: %s", taskUuid, entity.getBody())); + notifiedFailureHttpTasks.put(taskUuid, entity.getBody()); return; } @@ -281,13 +300,20 @@ public void asyncJsonGet(final String url, final String body, Map headers, HttpMethod method, final AsyncRESTCallback callback, final TimeUnit unit, final long timeout) { + @Override + public void asyncJson(final String url, final String body, Map headers, HttpMethod method, final AsyncRESTCallback callback, final TimeUnit unit, final long timeout) { synchronized (interceptors) { for (BeforeAsyncJsonPostInterceptor ic : interceptors) { ic.beforeAsyncJsonPost(url, body, unit, timeout); } } + if (unit.toMillis(timeout) <= 1) { + callback.fail(touterr("url: %s, current timeout: %s, api message timeout, skip post async call", + url, unit.toMillis(timeout))); + return; + } + long stime = 0; if (CoreGlobalProperty.PROFILER_HTTP_CALL) { stime = System.currentTimeMillis(); @@ -494,6 +520,110 @@ public T syncJsonPost(String url, Object body, Class returnClass, TimeUni return syncJsonPost(url, body == null ? null : JSONObjectUtil.toJsonString(body),null, returnClass, unit, timeout); } + public RestHttp http(Class returnClass) { + RestHttp http = new RestHttp<>(returnClass) + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE); + + if (CoreGlobalProperty.UNIT_TEST_ON) { + http.retryIfException(ResourceAccessException.class); + } else { + http.retryIfException(ResourceAccessException.class, HttpStatusCodeException.class); + } + + return http + .withHandler(this::syncJson) + .withErrorCodeBuilder((e, http2) -> { + if (e instanceof HttpStatusCodeException) { + final HttpStatusCodeException exception = (HttpStatusCodeException) e; + return operr("failed to %s to %s, status code: %s, response body: %s", + http2.getMethod().toString().toLowerCase(), + http2.getPath(), + exception.getStatusCode(), exception.getResponseBodyAsString()); + } else if (e instanceof ResourceAccessException) { + return operr("failed to %s to %s, IO Error: %s", + http2.getMethod().toString().toLowerCase(), + http2.getPath(), + e.getMessage()); + } + return null; + }); + } + + protected ResponseEntity syncJson(RestHttp http) { + String body = http.getBody() == null ? "" : http.getBody(); + + HttpHeaders requestHeaders = new HttpHeaders(); + requestHeaders.setAll(http.getHeaders()); + requestHeaders.setContentLength(body.length()); + HttpEntity req = new HttpEntity<>(body, requestHeaders); + ResponseEntity rsp = syncRawJson(req, http); + + if (logger.isTraceEnabled()) { + logger.trace(String.format("[http response(url: %s)] %s", http.getPath(), rsp.getBody())); + } + return rsp; + } + + public ResponseEntity syncRawJson(HttpEntity req, RestHttp http) { + if (logger.isTraceEnabled()) { + logger.trace(String.format("json %s[%s], %s", http.getMethod().toString().toLowerCase(), http.getPath(), req)); + } + + ResponseEntity rsp; + final String url = http.getPath(); + final HttpMethod method = http.getMethod(); + + try { + if (http.isRetry()) { + rsp = new Retry>() { + { + retryConditions.addAll(http.getRetryIfExceptionMatched()); + times = http.getRetryTimes(); + interval = http.getRetryIntervalInSeconds(); + } + + @Override + protected ResponseEntity call() { + if (http.isTimeoutEnabled()) { + return template.exchange(url, method, req, String.class); + } else { + final long millis = http.getTimeoutInMillis(); + return template.exchange(url, method, req, String.class, Platform.getUuid(), millis, millis); + } + } + }.run(); + } else { + rsp = (http.isTimeoutEnabled()) ? + template.exchange(url, method, req, String.class, + Platform.getUuid(), http.getTimeoutInMillis(), http.getTimeoutInMillis()) : + template.exchange(url, method, req, String.class); + } + } catch (Exception e) { + if (http.getErrorCodeBuilder() != null) { + ErrorCode errorCode = http.getErrorCodeBuilder().apply(e, http); + if (errorCode != null) { + throw new OperationFailureException(errorCode); + } + } + throw e; + } + + boolean valid = false; + if (method == HttpMethod.DELETE && rsp.getStatusCode() == org.springframework.http.HttpStatus.NO_CONTENT) { + valid = true; + } else if (method == HttpMethod.POST && rsp.getStatusCode() == org.springframework.http.HttpStatus.CREATED) { + valid = true; + } else if (rsp.getStatusCode() == org.springframework.http.HttpStatus.OK || rsp.getStatusCode() == org.springframework.http.HttpStatus.ACCEPTED) { + valid = true; + } + + if (!valid) { + throw new OperationFailureException(operr("failed to %s to %s, status code: %s, response body: %s", method.toString().toLowerCase(), url, rsp.getStatusCode(), rsp.getBody())); + } + + return rsp; + } + @Override public T syncJsonPost(String url, String body, Class returnClass) { return syncJsonPost(url, body, null, returnClass, null, -1); @@ -503,6 +633,7 @@ public T syncJsonPost(String url, String body, Class returnClass) { public T syncJsonPost(String url, String body, Map headers, Class returnClass) { return syncJsonPost(url, body, headers, returnClass, null, -1); } + @Override public T syncJsonPost(String url, String body, Map headers, Class returnClass, TimeUnit unit, long timeout) { return syncJson(url, body, headers, HttpMethod.POST, returnClass, unit, timeout); @@ -526,6 +657,16 @@ public T syncJsonGet(String url, String body, Map headers, C return syncJson(url, body, headers, HttpMethod.GET, returnClass, unit, timeout); } + @Override + public T syncJsonPut(String url, String body, Map headers, Class returnClass) { + return syncJsonPut(url, body, headers, returnClass, null, -1); + } + + @Override + public T syncJsonPut(String url, String body, Map headers, Class returnClass, TimeUnit unit, long timeout) { + return syncJson(url, body, headers, HttpMethod.PUT, returnClass, unit, timeout); + } + @Override public HttpHeaders syncHead(String url) { return template.headForHeaders(URI.create(url)); @@ -541,6 +682,23 @@ protected T syncJson(String url, String body, Map headers, requestHeaders.setContentType(MediaType.APPLICATION_JSON); requestHeaders.setContentLength(body.length()); HttpEntity req = new HttpEntity(body, requestHeaders); + ResponseEntity rsp = syncRawJson(url, req, method, unit, timeout); + + if (rsp.getBody() != null && returnClass != Void.class) { + if (logger.isTraceEnabled()) { + logger.trace(String.format("[http response(url: %s)] %s", url, rsp.getBody())); + } + + return JSONObjectUtil.toObject(rsp.getBody(), returnClass); + } else { + if (logger.isTraceEnabled()) { + logger.trace(String.format("[http response(url: %s)] %s", url, rsp.getBody())); + } + return null; + } + } + + public ResponseEntity syncRawJson(String url, HttpEntity req, HttpMethod method, TimeUnit unit, long timeout) { if (logger.isTraceEnabled()) { logger.trace(String.format("json %s[%s], %s", method.toString().toLowerCase(), url, req)); } @@ -578,7 +736,9 @@ protected ResponseEntity call() { boolean valid = false; if (method == HttpMethod.DELETE && rsp.getStatusCode() == org.springframework.http.HttpStatus.NO_CONTENT) { valid = true; - } else if (method == HttpMethod.POST && rsp.getStatusCode() == org.springframework.http.HttpStatus.CREATED) { + } else if (method == HttpMethod.POST && + (rsp.getStatusCode() == org.springframework.http.HttpStatus.CREATED || + rsp.getStatusCode() == org.springframework.http.HttpStatus.NO_CONTENT)) { valid = true; } else if (rsp.getStatusCode() == org.springframework.http.HttpStatus.OK || rsp.getStatusCode() == org.springframework.http.HttpStatus.ACCEPTED) { valid = true; @@ -587,20 +747,8 @@ protected ResponseEntity call() { if (!valid) { throw new OperationFailureException(operr("failed to %s to %s, status code: %s, response body: %s", method.toString().toLowerCase(), url, rsp.getStatusCode(), rsp.getBody())); } - - if (rsp.getBody() != null && returnClass != Void.class) { - - if (logger.isTraceEnabled()) { - logger.trace(String.format("[http response(url: %s)] %s", url, rsp.getBody())); - } - return JSONObjectUtil.toObject(rsp.getBody(), returnClass); - } else { - if (logger.isTraceEnabled()) { - logger.trace(String.format("[http response(url: %s)] %s", url, rsp.getBody())); - } - return null; - } + return rsp; } @Override diff --git a/core/src/main/java/org/zstack/core/retry/Retry.java b/core/src/main/java/org/zstack/core/retry/Retry.java index fe5498ca984..440027b0d6a 100755 --- a/core/src/main/java/org/zstack/core/retry/Retry.java +++ b/core/src/main/java/org/zstack/core/retry/Retry.java @@ -1,5 +1,6 @@ package org.zstack.core.retry; +import org.zstack.header.Confirm; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; @@ -10,6 +11,8 @@ import static org.zstack.core.Platform.i18n; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Function; @@ -40,6 +43,7 @@ public RetryException(String message, Throwable cause, boolean enableSuppression protected int times, count = 5; protected int interval = 1; + protected final List> retryConditions = new ArrayList<>(); private static final CLogger logger = Utils.getLogger(Retry.class); @@ -88,6 +92,7 @@ public T run() { TimeUnit.SECONDS.sleep(interval); } catch (InterruptedException e) { logger.warn(e.getMessage(), e); + Thread.currentThread().interrupt(); } diff --git a/core/src/main/java/org/zstack/core/salt/SaltFacadeImpl.java b/core/src/main/java/org/zstack/core/salt/SaltFacadeImpl.java index 52424ba4712..7f522167ca9 100755 --- a/core/src/main/java/org/zstack/core/salt/SaltFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/salt/SaltFacadeImpl.java @@ -90,7 +90,9 @@ private void prepareSaltMaster() throws IOException { ShellUtils.run("service salt-master restart"); } } finally { - srcMasterConf.delete(); + if (!srcMasterConf.delete()) { + logger.warn(String.format("failed to delete file[%s]", srcMasterConf)); + } } } diff --git a/core/src/main/java/org/zstack/core/salt/SaltRunner.java b/core/src/main/java/org/zstack/core/salt/SaltRunner.java index 0fb4d47208b..1397a14ccac 100755 --- a/core/src/main/java/org/zstack/core/salt/SaltRunner.java +++ b/core/src/main/java/org/zstack/core/salt/SaltRunner.java @@ -288,6 +288,7 @@ public void success() { try { TimeUnit.SECONDS.sleep(interval); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } } @@ -302,6 +303,7 @@ public void success() { } catch (Exception e) { logger.warn(String.format("failed to run salt state[%s] on system[%s], %s", stateName, targetIp, e.getMessage())); completion.fail(operr(e.getMessage())); + Thread.currentThread().interrupt(); } } diff --git a/core/src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java b/core/src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java index bc7725fc6dd..55bb1a922b5 100755 --- a/core/src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java +++ b/core/src/main/java/org/zstack/core/salt/SaltSetupMinionJob.java @@ -142,8 +142,8 @@ public void run(ReturnValueCompletion completion) { logger.warn(err, ie); completion.fail(inerr(ie.getMessage())); } finally { - if (tmpt != null) { - tmpt.delete(); + if (tmpt != null && !tmpt.delete()) { + logger.warn(String.format("failed to delete file[%s]", tmpt)); } if (ssh != null) { ssh.close(); diff --git a/core/src/main/java/org/zstack/core/singleflight/CompletionSingleFlight.java b/core/src/main/java/org/zstack/core/singleflight/CompletionSingleFlight.java deleted file mode 100644 index 132d8643928..00000000000 --- a/core/src/main/java/org/zstack/core/singleflight/CompletionSingleFlight.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.zstack.core.singleflight; - -import org.springframework.beans.factory.annotation.Autowire; -import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.header.core.ReturnValueCompletion; -import org.zstack.header.errorcode.ErrorCode; - -import java.util.Collection; -import java.util.function.Consumer; - -@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class CompletionSingleFlight extends AbstractSingleFlight { - public void execute(final K key, Consumer> getter, ReturnValueCompletion completion) { - if (!join(key, completion)) { - onNextPending(key, getContext(key)); - return; - } - final SingleFlightContext context = getContext(key); - onFirstStart(key, context); - - new CompletionConsumer<>(getter).accept(new ReturnValueCompletion(completion) { - @Override - public void success(V v) { - onSuccess(key, context, v); - Collection> rcs = dequeAll(key); - notifyResult(rcs, v); - } - - @Override - public void fail(ErrorCode errorCode) { - onFail(key, context, errorCode); - Collection> rcs = dequeAll(key); - notifyFailure(rcs, errorCode); - } - }); - } - - protected void onFirstStart(K key, SingleFlightContext context) { } - - protected void onNextPending(K key, SingleFlightContext context) { } - - protected void onSuccess(K key, SingleFlightContext context, V v) { } - - protected void onFail(K key, SingleFlightContext context, ErrorCode errorCode) { } - - /** - * This class cooperate with AsyncSafeAspect.aj to meet pointcut execution(* *.*(.., ReturnValueCompletion, ..)) - * Consumer> can not trigger pointcut of AsyncSafeAspect.aj because - * the parameter "ReturnValueCompletion" is generic type - */ - static class CompletionConsumer { - Consumer> consumer; - public CompletionConsumer(Consumer> consumer) { - this.consumer = consumer; - } - void accept(ReturnValueCompletion completion) { - consumer.accept(completion); - } - } -} diff --git a/core/src/main/java/org/zstack/core/singleflight/ExternalSingleFlightMsg.java b/core/src/main/java/org/zstack/core/singleflight/ExternalSingleFlightMsg.java new file mode 100644 index 00000000000..ac4dfdd0089 --- /dev/null +++ b/core/src/main/java/org/zstack/core/singleflight/ExternalSingleFlightMsg.java @@ -0,0 +1,35 @@ +package org.zstack.core.singleflight; + +import org.zstack.header.message.NeedReplyMessage; + +public class ExternalSingleFlightMsg extends NeedReplyMessage { + private String resourceUuid; + private String method; + + // do not contains ReturnValueCompletion + private Object[] args; + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public Object[] getArgs() { + return args; + } + + public void setArgs(Object[] args) { + this.args = args; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } +} diff --git a/core/src/main/java/org/zstack/core/singleflight/ExternalSingleFlightReply.java b/core/src/main/java/org/zstack/core/singleflight/ExternalSingleFlightReply.java new file mode 100644 index 00000000000..d86e2933993 --- /dev/null +++ b/core/src/main/java/org/zstack/core/singleflight/ExternalSingleFlightReply.java @@ -0,0 +1,16 @@ +package org.zstack.core.singleflight; + + +import org.zstack.header.message.MessageReply; + +public class ExternalSingleFlightReply extends MessageReply { + private Object result; + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } +} diff --git a/core/src/main/java/org/zstack/core/singleflight/MultiNodeSingleFlightImpl.java b/core/src/main/java/org/zstack/core/singleflight/MultiNodeSingleFlightImpl.java new file mode 100644 index 00000000000..4ce39ce2f00 --- /dev/null +++ b/core/src/main/java/org/zstack/core/singleflight/MultiNodeSingleFlightImpl.java @@ -0,0 +1,131 @@ +package org.zstack.core.singleflight; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.ResourceDestinationMakerImpl; +import org.zstack.core.thread.SingleFlightTask; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.core.CoreConstant; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.addon.SingleFlightExecutor; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.ConcurrentHashMap; + +import static org.zstack.core.Platform.operr; + +public class MultiNodeSingleFlightImpl { + private static final CLogger logger = Utils.getLogger(MultiNodeSingleFlightImpl.class); + + @Autowired + private ThreadFacade thdf; + @Autowired + private CloudBus bus; + @Autowired + private ResourceDestinationMakerImpl destinationMaker; + + private static final Map singleFlightExecutors = new ConcurrentHashMap<>(); + private static final Map> singleFlightMethods = new ConcurrentHashMap<>(); + + public static void register(SingleFlightExecutor executor) { + if (!singleFlightMethods.containsKey(executor.getClass().getName())) { + Method[] methods = executor.getClass().getDeclaredMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(SingleFlightExecutor.SingleFlight.class)) { + validateSingleFlight(method); + singleFlightMethods.computeIfAbsent(executor.getClass().getName(), k -> new HashMap<>()).put(method.getName(), method); + } + } + } + + logger.debug(String.format("register single flight executor [%s, uuid: %s]", executor.getClass().getSimpleName(), executor.getResourceUuid())); + singleFlightExecutors.put(executor.getResourceUuid(), executor); + } + + public static boolean unregister(String resourceUuid) { + SingleFlightExecutor removed = singleFlightExecutors.remove(resourceUuid); + if (removed != null) { + logger.debug(String.format("unregister single flight executor [%s, uuid: %s]", removed.getClass().getSimpleName(), resourceUuid)); + } + + return removed != null; + } + + public static SingleFlightExecutor getExecutor(String resourceUuid) { + return singleFlightExecutors.get(resourceUuid); + } + + public void run(SingleFlightExecutor executor, String method, Object... args) { + ReturnValueCompletion completion = (ReturnValueCompletion) args[args.length - 1]; + Method consumer = singleFlightMethods.get(executor.getClass().getName()).get(method); + if (consumer == null) { + throw new IllegalArgumentException(executor.getClass() + " has not register single flight method " + method); + } + + boolean localSingleFlight = !singleFlightExecutors.containsKey(executor.getResourceUuid()) || + destinationMaker.isManagedByUs(executor.getResourceUuid()); + + boolean unitTestSaySendMsg = CoreGlobalProperty.UNIT_TEST_ON && new Random().nextBoolean(); + if (localSingleFlight && !unitTestSaySendMsg) { + logger.info(String.format("start running local single flight task [method:%s,resource:%s]", method, executor.getResourceUuid())); + thdf.singleFlightSubmit(new SingleFlightTask(null) + .setSyncSignature("external-single-flight-" + executor.getResourceUuid()) + .run(outCompletion -> { + try { + args[args.length - 1] = outCompletion; + consumer.invoke(executor, args); + } catch (IllegalAccessException | InvocationTargetException e) { + outCompletion.fail(operr(e.getMessage())); + } + }) + .done(result -> { + if (result.isSuccess()) { + completion.success(result.getResult()); + } else { + completion.fail(result.getErrorCode()); + } + }) + ); + return; + } + + ExternalSingleFlightMsg msg = new ExternalSingleFlightMsg(); + msg.setResourceUuid(executor.getResourceUuid()); + msg.setMethod(method); + msg.setArgs(Arrays.copyOfRange(args, 0, args.length - 1)); + bus.makeTargetServiceIdByResourceUuid(msg, CoreConstant.SERVICE_ID, executor.getResourceUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + completion.success(((ExternalSingleFlightReply) reply).getResult()); + } + }); + } + + private static void validateSingleFlight(Method m) { + if (m.getParameterTypes()[m.getParameterTypes().length - 1] != ReturnValueCompletion.class) { + throw new IllegalArgumentException("The last parameter of " + m.getName() + " must be ReturnValueCompletion"); + } + + if (m.getReturnType() != void.class) { + throw new IllegalArgumentException("The return type of " + m.getName() + " must be void"); + } + + m.setAccessible(true); + } +} diff --git a/core/src/main/java/org/zstack/core/singleflight/TaskSingleFlight.java b/core/src/main/java/org/zstack/core/singleflight/TaskSingleFlight.java deleted file mode 100644 index b31a24f32f7..00000000000 --- a/core/src/main/java/org/zstack/core/singleflight/TaskSingleFlight.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.zstack.core.singleflight; - -import org.springframework.beans.factory.annotation.Autowire; -import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.header.Constants; -import org.zstack.header.core.ReturnValueCompletion; -import org.zstack.header.core.progress.RunningTaskInfo; -import org.zstack.header.errorcode.ErrorCode; -import org.zstack.utils.TimeUtils; -import org.zstack.utils.Utils; -import org.zstack.utils.logging.CLogger; - -import java.time.Duration; -import java.time.Instant; -import java.util.Collections; -import java.util.Map; - -import static org.zstack.utils.CollectionDSL.e; -import static org.zstack.utils.CollectionDSL.map; - -/** - * Created by Wenhao.Zhang on 21/08/10 - */ -@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class TaskSingleFlight extends CompletionSingleFlight { - private static final CLogger logger = Utils.getLogger(TaskSingleFlight.class); - - @Override - protected SingleFlightContext buildContext(K key) { - return new TaskSingleFlightContext(); - } - - @SuppressWarnings("unchecked") - public RunningTaskInfo buildRunningTaskInfo(K key) { - SingleFlightContext c = getContext(key); - if (c == null) { - return null; - } - TaskSingleFlightContext context = (TaskSingleFlightContext) c; - final Instant now = Instant.now(); - - final RunningTaskInfo info = new RunningTaskInfo(); - info.setExecutionTime(Duration.between(context.getStartTime(), now).getSeconds()); - info.setPendingTime(0); - info.setName(String.valueOf(key)); - info.setClassName(TaskSingleFlightContext.class.getSimpleName()); - info.setIndex(0); - - ReturnValueCompletion first = context.getFirst(); - if (first != null) { - Map threadContext = first.getThreadContext(); - if (threadContext != null) { - info.setApiName(threadContext.get(Constants.THREAD_CONTEXT_TASK_NAME)); - info.setApiId(threadContext.get(Constants.THREAD_CONTEXT_API)); - } - } - info.setContextList(Collections.emptyList()); - info.setContext(map(e("apiName", info.getApiName()), e("apiId", info.getApiId())).toString()); - return info; - } - - @Override - protected void onFirstStart(K key, SingleFlightContext context) { - logger.debug(String.format("running task: %s", buildRunningTaskInfo(key))); - } - - @Override - protected void onNextPending(K key, SingleFlightContext context) { - TaskSingleFlightContext taskContext = (TaskSingleFlightContext) context; - logger.debug(String.format("pending task %s: waiting for %s (start at %s), pending tasks count: %d", key, - buildRunningTaskInfo(key), TimeUtils.instantToString(taskContext.getStartTime()), context.pendingCount())); - } - - @Override - protected void onSuccess(K key, SingleFlightContext context, V v) { - logger.debug(String.format("task %s accomplished successfully: %s, pending tasks count: %d", key, - buildRunningTaskInfo(key), context.pendingCount())); - } - - @Override - protected void onFail(K key, SingleFlightContext context, ErrorCode errorCode) { - logger.warn(String.format("task %s fail because %s: %s, pending tasks count %d", key, errorCode.getDetails(), - buildRunningTaskInfo(key), context.pendingCount())); - } - - class TaskSingleFlightContext extends SingleFlightContext { - private Instant startTime = Instant.now(); - - public Instant getStartTime() { - return startTime; - } - - public boolean isPending() { - return this.startTime == null; - } - } -} diff --git a/core/src/main/java/org/zstack/core/thread/AbstractChainTask.java b/core/src/main/java/org/zstack/core/thread/AbstractChainTask.java new file mode 100644 index 00000000000..c16808db51e --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/AbstractChainTask.java @@ -0,0 +1,17 @@ +package org.zstack.core.thread; + +import org.zstack.header.PassMaskWords; +import org.zstack.header.core.AbstractCompletion; +import org.zstack.header.core.AsyncBackup; + +import java.util.Map; + +public abstract class AbstractChainTask extends AbstractCompletion implements PassMaskWords { + protected AbstractChainTask(AsyncBackup one, AsyncBackup... others) { + super(one, others); + } + + public abstract String getSyncSignature(); + + public abstract String getName(); +} diff --git a/core/src/main/java/org/zstack/core/thread/AbstractFuture.java b/core/src/main/java/org/zstack/core/thread/AbstractFuture.java index 841d2a7576b..8e40210e5ed 100755 --- a/core/src/main/java/org/zstack/core/thread/AbstractFuture.java +++ b/core/src/main/java/org/zstack/core/thread/AbstractFuture.java @@ -2,7 +2,6 @@ import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; - import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/core/src/main/java/org/zstack/core/thread/AbstractTimeStatisticFuture.java b/core/src/main/java/org/zstack/core/thread/AbstractTimeStatisticFuture.java new file mode 100644 index 00000000000..134017d2bc6 --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/AbstractTimeStatisticFuture.java @@ -0,0 +1,30 @@ +package org.zstack.core.thread; + +public abstract class AbstractTimeStatisticFuture extends AbstractFuture { + public AbstractTimeStatisticFuture(AbstractChainTask task) { + super(task); + } + + AbstractChainTask getTask() { + return (AbstractChainTask) task; + } + + private long startPendingTimeInMills = System.currentTimeMillis(); + private Long startExecutionTimeInMills; + + public long getStartPendingTimeInMills() { + return startPendingTimeInMills; + } + + public void setStartPendingTimeInMills(long startPendingTimeInMills) { + this.startPendingTimeInMills = startPendingTimeInMills; + } + + public Long getStartExecutionTimeInMills() { + return startExecutionTimeInMills; + } + + public void setStartExecutionTimeInMills(Long startExecutionTimeInMills) { + this.startExecutionTimeInMills = startExecutionTimeInMills; + } +} diff --git a/core/src/main/java/org/zstack/core/thread/AsyncTimer.java b/core/src/main/java/org/zstack/core/thread/AsyncTimer.java index 9f28263c018..3f877ab0614 100755 --- a/core/src/main/java/org/zstack/core/thread/AsyncTimer.java +++ b/core/src/main/java/org/zstack/core/thread/AsyncTimer.java @@ -63,7 +63,7 @@ public void startRightNow() { throw new CloudRuntimeException("cannot start a cancelled timer"); } - cancel = thdf.submitTimeoutTask(this, getTimeUnit(), getPeriod(), true); + cancel = thdf.submitTimeoutTask(this, getTimeUnit(), 0); if (logger.isTraceEnabled()) { logger.trace(String.format("%s starts", getName())); } diff --git a/core/src/main/java/org/zstack/core/thread/ChainTask.java b/core/src/main/java/org/zstack/core/thread/ChainTask.java index 8225484f7b6..0449ddc2720 100755 --- a/core/src/main/java/org/zstack/core/thread/ChainTask.java +++ b/core/src/main/java/org/zstack/core/thread/ChainTask.java @@ -1,24 +1,14 @@ package org.zstack.core.thread; -import org.zstack.header.PassMaskWords; -import org.zstack.header.core.AbstractCompletion; import org.zstack.header.core.AsyncBackup; -import java.util.Map; - -public abstract class ChainTask extends AbstractCompletion implements PassMaskWords { +public abstract class ChainTask extends AbstractChainTask { public ChainTask(AsyncBackup one, AsyncBackup...others) { super(one, others); } - public Map taskContext = null; - - public abstract String getSyncSignature(); - public abstract void run(SyncTaskChain chain); - public abstract String getName(); - protected int getSyncLevel() { return 1; } diff --git a/core/src/main/java/org/zstack/core/thread/DispatchQueue.java b/core/src/main/java/org/zstack/core/thread/DispatchQueue.java index f20946b0ba2..f853dbcc26a 100755 --- a/core/src/main/java/org/zstack/core/thread/DispatchQueue.java +++ b/core/src/main/java/org/zstack/core/thread/DispatchQueue.java @@ -1,6 +1,7 @@ package org.zstack.core.thread; import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.core.progress.SingleFlightChainInfo; import java.util.Map; import java.util.Set; @@ -13,6 +14,8 @@ public interface DispatchQueue { Future chainSubmit(ChainTask task); + Future singleFlightSubmit(SingleFlightTask task); + Map getSyncTaskStatistics(); Map getChainTaskStatistics(); @@ -23,5 +26,7 @@ public interface DispatchQueue { ChainInfo cleanChainTaskInfo(String signature, Integer index, Boolean cleanUp, Boolean isRunningTask); + SingleFlightChainInfo getSingleFlightChainTaskInfo(String signature); + Set getApiRunningTaskSignature(String apiId); } diff --git a/core/src/main/java/org/zstack/core/thread/DispatchQueueImpl.java b/core/src/main/java/org/zstack/core/thread/DispatchQueueImpl.java index 32884e0965d..7b608783816 100755 --- a/core/src/main/java/org/zstack/core/thread/DispatchQueueImpl.java +++ b/core/src/main/java/org/zstack/core/thread/DispatchQueueImpl.java @@ -1,7 +1,6 @@ package org.zstack.core.thread; import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.ThreadContext; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; @@ -10,9 +9,13 @@ import org.zstack.core.debug.DebugSignalHandler; import org.zstack.header.Constants; import org.zstack.header.core.ExceptionSafe; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.core.progress.ChainInfo; import org.zstack.header.core.progress.PendingTaskInfo; +import org.zstack.header.core.progress.SingleFlightChainInfo; +import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.errorcode.SysErrors; import org.zstack.utils.DebugUtils; import org.zstack.utils.TaskContext; import org.zstack.utils.Utils; @@ -27,6 +30,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import static org.zstack.core.Platform.*; + @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = true) class DispatchQueueImpl implements DispatchQueue, DebugSignalHandler { private static final CLogger logger = Utils.getLogger(DispatchQueueImpl.class); @@ -36,83 +41,64 @@ class DispatchQueueImpl implements DispatchQueue, DebugSignalHandler { @Autowired private org.zstack.core.timeout.Timer zTimer; - private final HashMap syncTasks = new HashMap(); + private final HashMap syncTasks = new HashMap<>(); private final Map chainTasks = Collections.synchronizedMap(new HashMap<>()); + private final Map singleFlightTasks = Collections.synchronizedMap(new HashMap<>()); private final Map> apiRunningSignature = new ConcurrentHashMap<>(); private static final CLogger _logger = CLoggerImpl.getLogger(DispatchQueueImpl.class); - @Override - public void handleDebugSignal() { - StringBuilder sb = new StringBuilder(); - sb.append("\n================= BEGIN TASK QUEUE DUMP ================"); - sb.append("\nASYNC TASK QUEUE DUMP:"); - sb.append(String.format("\nTASK QUEUE NUMBER: %s\n", chainTasks.size())); + private String dumpChainTaskQueue() { List asyncTasks = new ArrayList<>(); - long now = System.currentTimeMillis(); synchronized (chainTasks) { for (Map.Entry e : chainTasks.entrySet()) { - StringBuilder tb = new StringBuilder(String.format("\nQUEUE SYNC SIGNATURE: %s", e.getKey())); - ChainTaskQueueWrapper w = e.getValue(); - tb.append(String.format("\nRUNNING TASK NUMBER: %s", w.runningQueue.size())); - tb.append(String.format("\nPENDING TASK NUMBER: %s", w.pendingQueue.size())); - tb.append(String.format("\nASYNC LEVEL: %s", w.maxThreadNum)); - - int index = 0; - for (Object obj : w.runningQueue) { - ChainFuture cf = (ChainFuture) obj; - tb.append(TaskInfoBuilder.buildRunningTaskInfo(cf, now, index++)); - } - - for (Object obj : w.pendingQueue) { - ChainFuture cf = (ChainFuture) obj; - tb.append(TaskInfoBuilder.buildPendingTaskInfo(cf, now, index++)); - } - asyncTasks.add(tb.toString()); + asyncTasks.add(e.getValue().dumpTaskQueueInfo()); } } + StringBuilder sb = new StringBuilder(); + sb.append("\nASYNC TASK QUEUE DUMP:"); + sb.append(String.format("\nTASK QUEUE NUMBER: %s\n", chainTasks.size())); sb.append(StringUtils.join(asyncTasks, "\n")); + return sb.toString(); + } - sb.append("\nSYNC TASK QUEUE DUMP:"); - sb.append(String.format("\nTASK QUEUE NUMBER: %s\n", syncTasks.size())); + private String dumpSyncTaskQueue() { List queueSyncTasks = new ArrayList<>(); synchronized (syncTasks) { for (Map.Entry e : syncTasks.entrySet()) { - StringBuilder tb = new StringBuilder(String.format("\nQUEUE SYNC SIGNATURE: %s", e.getKey())); - SyncTaskQueueWrapper w = e.getValue(); - tb.append(String.format("\nRUNNING SYNC TASK NUMBER: %s", w.counter)); - tb.append(String.format("\nPENDING TASK NUMBER: %s", w.queue.size())); - tb.append(String.format("\nSYNC LEVEL: %s", w.maxThreadNum)); - tb.append(String.format("\nPENDING TASK[NAME: %s, TASK QUEUE SIZE: %d, MAX THREAD: %d] ", - w.syncSignature, w.queue.size(), w.maxThreadNum)); - for (Object obj : w.queue) { - SyncTask task = ((SyncTaskFuture) obj).getTask(); - - if (task.getThreadContext() == null) { - break; - } - - String taskId = null; - if (task.getThreadContext().containsKey(Constants.THREAD_CONTEXT_API)) { - taskId = task.getThreadContext().get(Constants.THREAD_CONTEXT_API); - } - - if (task.getThreadContext().containsKey(Constants.THREAD_CONTEXT_TASK)) { - taskId = task.getThreadContext().get(Constants.THREAD_CONTEXT_TASK); - } + queueSyncTasks.add(e.getValue().dumpTaskQueueInfo()); + } + } - if (taskId == null) { - break; - } + StringBuilder sb = new StringBuilder(); + sb.append("\nSYNC TASK QUEUE DUMP:"); + sb.append(String.format("\nTASK QUEUE NUMBER: %s\n", syncTasks.size())); + sb.append(StringUtils.join(queueSyncTasks, "\n")); + return sb.toString(); + } - tb.append(String.format("\nPENDING TASK[NAME: %s, TASK ID: %s] ", - task.getName(), taskId)); - } - queueSyncTasks.add(tb.toString()); + private String dumpSingleFlightTaskQueue() { + List queueSingleFlightTasks = new ArrayList<>(); + synchronized (singleFlightTasks) { + for (Map.Entry e : singleFlightTasks.entrySet()) { + queueSingleFlightTasks.add(e.getValue().dumpTaskQueueInfo()); } } - sb.append(StringUtils.join(queueSyncTasks, "\n")); + StringBuilder sb = new StringBuilder(); + sb.append("\nSINGLE FLIGHT TASK QUEUE DUMP:"); + sb.append(String.format("\nTASK QUEUE NUMBER: %s\n", syncTasks.size())); + sb.append(StringUtils.join(queueSingleFlightTasks, "\n")); + return sb.toString(); + } + + @Override + public void handleDebugSignal() { + StringBuilder sb = new StringBuilder(); + sb.append("\n================= BEGIN TASK QUEUE DUMP ================"); + sb.append(dumpChainTaskQueue()); + sb.append(dumpSyncTaskQueue()); + sb.append(dumpSingleFlightTaskQueue()); sb.append("\n================= END TASK QUEUE DUMP ==================\n"); _threadFacade.printThreadsAndTasks(); logger.debug(sb.toString()); @@ -120,47 +106,33 @@ public void handleDebugSignal() { public void beforeCleanQueuedumpThread(String signatureName) { String title = "\n================= Before Clean Task Queue Dump ================"; - dumpsignatureNameThread(signatureName,title); + dumpSignatureNameThread(signatureName,title); } public void afterCleanQueuedumpThread(String signatureName) { String title = "\n================= After Clean Task Queue Dump ================"; - dumpsignatureNameThread(signatureName,title); + dumpSignatureNameThread(signatureName,title); } - public void dumpsignatureNameThread(String signatureName,String title) { + public void dumpSignatureNameThread(String signatureName, String title) { StringBuilder sb = new StringBuilder(); sb.append(title); sb.append("\nASYNC TASK QUEUE DUMP:"); sb.append(String.format("\nTASK QUEUE NUMBER: %s\n", chainTasks.size())); List asyncTasks = new ArrayList<>(); - long now = System.currentTimeMillis(); - synchronized (chainTasks) { - ChainTaskQueueWrapper w = chainTasks.get(signatureName); - if (w == null) { - sb.append(String.format("\n===== NO QUEUE SYNC SIGNATURE: %s =====", signatureName)); - sb.append(StringUtils.join(asyncTasks, "\n")); - sb.append("\n================= END TASK QUEUE DUMP ==================\n"); - _threadFacade.printThreadsAndTasks(); - logger.debug(sb.toString()); - return; - } - StringBuilder tb = new StringBuilder(String.format("\nQUEUE SYNC SIGNATURE: %s", signatureName)); - tb.append(String.format("\nRUNNING TASK NUMBER: %s", w.runningQueue.size())); - tb.append(String.format("\nPENDING TASK NUMBER: %s", w.pendingQueue.size())); - tb.append(String.format("\nASYNC LEVEL: %s", w.maxThreadNum)); - int index = 0; - for (Object obj : w.runningQueue) { - ChainFuture cf = (ChainFuture) obj; - tb.append(TaskInfoBuilder.buildRunningTaskInfo(cf, now, index++)); - } - for (Object obj : w.pendingQueue) { - ChainFuture cf = (ChainFuture) obj; - tb.append(TaskInfoBuilder.buildPendingTaskInfo(cf, now, index++)); - } - asyncTasks.add(tb.toString()); + ChainTaskQueueWrapper w = chainTasks.get(signatureName); + if (w == null) { + sb.append(String.format("\n===== NO QUEUE SYNC SIGNATURE: %s =====", signatureName)); + sb.append(StringUtils.join(asyncTasks, "\n")); + sb.append("\n================= END TASK QUEUE DUMP ==================\n"); + _threadFacade.printThreadsAndTasks(); + logger.debug(sb.toString()); + return; } + StringBuilder tb = new StringBuilder(String.format("\nQUEUE SYNC SIGNATURE: %s", signatureName)); + tb.append(w.getTaskQueueInfo()); + asyncTasks.add(tb.toString()); sb.append(StringUtils.join(asyncTasks, "\n")); sb.append("\n================= END TASK QUEUE DUMP ==================\n"); @@ -170,26 +142,12 @@ public void dumpsignatureNameThread(String signatureName,String title) { @Override public ChainInfo getChainTaskInfo(String signature) { - long now = System.currentTimeMillis(); - synchronized (chainTasks) { - ChainInfo info = new ChainInfo(); - ChainTaskQueueWrapper w = chainTasks.get(signature); - if (w == null) { - return info; - } - - int index = 0; - for (Object obj : w.runningQueue) { - ChainFuture cf = (ChainFuture) obj; - info.addRunningTask(TaskInfoBuilder.buildRunningTaskInfo(cf, now, index++)); - } - - for (Object obj : w.pendingQueue) { - ChainFuture cf = (ChainFuture) obj; - info.addPendingTask(TaskInfoBuilder.buildPendingTaskInfo(cf, now, index++)); - } - return info; + ChainTaskQueueWrapper w = chainTasks.get(signature); + if (w == null) { + return new ChainInfo(); } + + return w.getChainInfo(); } @Override @@ -241,6 +199,32 @@ public ChainInfo cleanChainTaskInfo(String signature, Integer index, Boolean cle } } + @Override + public SingleFlightChainInfo getSingleFlightChainTaskInfo(String signature) { + long now = System.currentTimeMillis(); + synchronized (singleFlightTasks) { + SingleFlightChainInfo info = new SingleFlightChainInfo(); + + SingleFlightQueueWrapper w = singleFlightTasks.get(signature); + if (w == null) { + logger.warn(String.format("no queue with a corresponding signatureName[%s]", signature)); + return null; + } + + int index = 0; + if (w.runningTask != null) { + SingleFlightFuture sf = w.runningTask; + info.addRunningTask(TaskInfoBuilder.buildRunningTaskInfo(sf, now, index++)); + } + + for (Object obj : w.pendingQueue) { + SingleFlightFuture sf = (SingleFlightFuture) obj; + info.addPendingTask(TaskInfoBuilder.buildPendingTaskInfo(sf, now, index++)); + } + return info; + } + } + @Override public Set getApiRunningTaskSignature(String apiId) { return new HashSet<>(apiRunningSignature.getOrDefault(apiId, Collections.emptyList())); @@ -294,11 +278,93 @@ String getName() { } } - private class SyncTaskQueueWrapper { + private abstract class AbstractTaskQueueWrapper { + String syncSignature; + private final AtomicInteger abnormalPendingQueueThreshold = new AtomicInteger(CoreGlobalProperty.PENDING_QUEUE_MINIMUM_THRESHOLD); + + /** + * make getCurrentPendingQueueThreshold() public for test + * @return int value of abnormalPendingQueueThreshold + */ + public int getCurrentPendingQueueThreshold() { + return abnormalPendingQueueThreshold.get(); + } + + /** + * One task use 56 bytes memory, test on version 4.5.0. + * Default 50 tasks use 2.73MB memory. + * Next level 250 tasks use 13.67MB memory. + * No big change for the memory usage and just use this mechanism to detect + * system level slow executed task queue. + * @return current pending queue threshold + */ + private int extendPendingQueueThresholdForNextDetection() { + return abnormalPendingQueueThreshold.getAndUpdate(operand -> operand * 5); + } + + /** + * When confirm the task queue runs as expected, use this to reset threshold. + * Now, reset before new task started (means no pending task anymore) + * + * Note: Reset pending queue threshold should be manually invoked + */ + public void resetPendingQueueThreshold() { + abnormalPendingQueueThreshold.set(CoreGlobalProperty.PENDING_QUEUE_MINIMUM_THRESHOLD); + } + + /** + * Dump task queue if needed + * + * Pending task size is defined by wrapper itself, use the size compares to + * threshold and if pending size is over threshold, means too many pending + * task for current task queue, dump the whole queue for debug. + * + * In order to avoid frequent queue dumping, extend the threshold to 5 times + * for next abnormal detection. + * + * When the task queue recovered, use resetPendingQueueThreshold() to reset + * the threshold + * + * @param currentPendingTaskQueueSize the pending task queue size offered by + * wrapper + */ + public void dumpTaskQueueIfNeeded(int currentPendingTaskQueueSize) { + if (currentPendingTaskQueueSize <= getCurrentPendingQueueThreshold()) { + return; + } + + // change threshold for next abnormal report + if (currentPendingTaskQueueSize > getCurrentPendingQueueThreshold()) { + logger.debug(String.format("syncSignature: %s, pending queue size over abnormal limitation: %d, " + + " too many pending tasks, dump task queue for potential problem", + syncSignature, extendPendingQueueThresholdForNextDetection())); + logger.debug("\n================= BEGIN ABNORMAL TASK QUEUE DUMP ================"); + logger.debug(dumpTaskQueueInfo()); + logger.debug("\n================= END ABNORMAL TASK QUEUE DUMP ================"); + } + } + + /** + * dump current task queue info + * @return String with queue description string + */ + protected abstract String getTaskQueueInfo(); + + public String dumpTaskQueueInfo() { + StringBuilder tb = new StringBuilder(String.format("\nQUEUE SYNC SIGNATURE: %s", syncSignature)); + + synchronized (chainTasks) { + tb.append(getTaskQueueInfo()); + } + + return tb.toString(); + } + } + + private class SyncTaskQueueWrapper extends AbstractTaskQueueWrapper { ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); AtomicInteger counter = new AtomicInteger(0); int maxThreadNum = -1; - String syncSignature; void addTask(SyncTaskFuture task) { queue.offer(task); @@ -312,11 +378,15 @@ void addTask(SyncTaskFuture task) { void startThreadIfNeeded() { if (counter.get() >= maxThreadNum) { + logger.debug(String.format("Sync task syncSignature: %s reached maxThreadNum: %s, current: %d, pending queue size: %d", + syncSignature, maxThreadNum, counter.get(), queue.size())); + dumpTaskQueueIfNeeded(queue.size()); return; } + resetPendingQueueThreshold(); counter.incrementAndGet(); - _threadFacade.submitSyncPool(new Task() { + _threadFacade.submitTargetPool(new Task() { @Override public String getName() { return syncSignature; @@ -347,7 +417,43 @@ public Void call() { run(); return null; } - }); + }, syncSignature); + } + + @Override + protected String getTaskQueueInfo() { + StringBuilder tb = new StringBuilder(); + tb.append(String.format("\nRUNNING SYNC TASK NUMBER: %s", counter)); + tb.append(String.format("\nPENDING TASK NUMBER: %s", queue.size())); + tb.append(String.format("\nSYNC LEVEL: %s", maxThreadNum)); + tb.append(String.format("\nPENDING TASK[NAME: %s, TASK QUEUE SIZE: %d, MAX THREAD: %d] ", + syncSignature, queue.size(), maxThreadNum)); + for (Object obj : queue) { + SyncTask task = ((SyncTaskFuture) obj).getTask(); + + if (task.getThreadContext() == null) { + break; + } + + String taskId = null; + if (task.getThreadContext().containsKey(Constants.THREAD_CONTEXT_API)) { + taskId = task.getThreadContext().get(Constants.THREAD_CONTEXT_API); + } + + if (task.getThreadContext().containsKey(Constants.THREAD_CONTEXT_TASK)) { + taskId = task.getThreadContext().get(Constants.THREAD_CONTEXT_TASK); + } + + if (taskId == null) { + break; + } + + tb.append(String.format("\nPENDING TASK[NAME: %s, TASK ID: %s] ", + task.getName(), taskId)); + } + + + return tb.toString(); } } @@ -378,25 +484,68 @@ public Future syncSubmit(SyncTask task) { } } + class SingleFlightFuture extends AbstractTimeStatisticFuture { + private Integer taskId; - class ChainFuture extends AbstractFuture { - private AtomicBoolean isNextCalled = new AtomicBoolean(false); + public SingleFlightFuture(SingleFlightTask task) { + super(task); + } - private long startPendingTimeInMills = System.currentTimeMillis(); - private Long startExecutionTimeInMills; + protected SingleFlightTask getTask() { + return (SingleFlightTask) task; + } - public long getStartPendingTimeInMills() { - return startPendingTimeInMills; + public Integer getTaskId() { + return taskId; } - public Long getStartExecutionTimeInMills() { - return startExecutionTimeInMills; + public void setTaskId(Integer taskId) { + this.taskId = taskId; } - public void setStartExecutionTimeInMills(Long startExecutionTimeInMills) { - this.startExecutionTimeInMills = startExecutionTimeInMills; + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + cancel(); + return true; } + void singleFlightRun(final ReturnValueCompletion completion) { + if (isCancelled()) { + completion.fail(err(SysErrors.CANCEL_ERROR, "task failed due to cancelled")); + return; + } + + try { + getTask().start(completion); + } catch (Throwable t) { + try { + if (!(t instanceof OperationFailureException)) { + _logger.warn(String.format("unhandled exception happened when calling %s", task.getClass().getName()), t); + } + + done(); + } finally { + if (t instanceof OperationFailureException) { + completion.fail(operr(t.getMessage())); + } else { + completion.fail(inerr(t.getMessage())); + } + } + } + } + + void singleFlightDone(SingleFlightTaskResult result) { + getTask().singleFlightDone(result); + } + + String getSyncSignature() { + return getTask().getSyncSignature(); + } + } + + class ChainFuture extends AbstractTimeStatisticFuture { + private AtomicBoolean isNextCalled = new AtomicBoolean(false); + public ChainFuture(ChainTask task) { super(task); } @@ -455,13 +604,160 @@ public String getSyncSignature() { } } - private class ChainTaskQueueWrapper { + private class SingleFlightQueueWrapper extends AbstractTaskQueueWrapper { LinkedList pendingQueue = new LinkedList(); + volatile SingleFlightFuture runningTask = null; + AtomicInteger taskCounter = new AtomicInteger(0); + + boolean addSingleFlightTask(SingleFlightFuture task) { + task.setTaskId(taskCounter.addAndGet(1)); + pendingQueue.offer(task); + + if (syncSignature == null) { + syncSignature = task.getSyncSignature(); + } + + return true; + } + + void startSingleFlightIfNeed() { + if (taskCounter.get() > 1) { + logger.debug(String.format("single flight task[signature: %s] thread is running now," + + " skip start new thread", syncSignature)); + dumpTaskQueueIfNeeded(pendingQueue.size()); + return; + } + + resetPendingQueueThreshold(); + _threadFacade.submit(new Task() { + + @Override + public Void call() { + runSingleFlight(); + return null; + } + + @AsyncThread + private void runSingleFlight() { + synchronized (singleFlightTasks) { + if (runningTask != null) { + logger.debug(String.format("single flight task[signature: %s, id: %s] is running now," + + " skip poll new running task, current pending task num: %d", runningTask.getSyncSignature(), + runningTask.getTaskId(), pendingQueue.size())); + return; + } + + runningTask = (SingleFlightFuture) pendingQueue.poll(); + if (runningTask == null) { + logger.debug(String.format("single flight task[signature: %s] has no task available" + + " skip execute", syncSignature)); + singleFlightTasks.remove(syncSignature); + return; + } + } + + processTimeoutTask(runningTask); + runningTask.setStartExecutionTimeInMills(zTimer.getCurrentTimeMillis()); + runningTask.singleFlightRun(new ReturnValueCompletion(null) { + @Override + public void success(Object object) { + executeSingleRunTasks(object, null); + } + + @Override + public void fail(ErrorCode errorCode) { + executeSingleRunTasks(null, errorCode); + } + }); + } + + private void executeSingleRunTasks(Object object, ErrorCode errorCode) { + synchronized (singleFlightTasks) { + safeRun(object, runningTask, errorCode); + pendingQueue.forEach(task -> safeRun(object, (SingleFlightFuture) task, errorCode)); + + // all tasks done, reset counter + taskCounter.set(0); + runningTask = null; + pendingQueue.clear(); + } + + runSingleFlight(); + } + + private void safeRun(Object object, SingleFlightFuture flightFuture, ErrorCode errorCode) { + SingleFlightTaskResult result = new SingleFlightTaskResult(); + result.setResult(object); + try { + if (errorCode != null) { + result.setErrorCode(errorCode); + } + flightFuture.singleFlightDone(result); + } catch (Throwable t) { + if ((t instanceof OperationFailureException)) { + return; + } + + _logger.warn(String.format("unhandled exception happened when calling %s", flightFuture.getClass().getName()), t); + } finally { + logger.debug(String.format("single flight task[signature: %s, id: %s] finish with %s", + runningTask.getSyncSignature(), flightFuture.getTaskId(), JSONObjectUtil.toJsonString(result))); + flightFuture.done(); + } + } + + @Override + public String getName() { + return syncSignature; + } + }); + } + + @Override + protected String getTaskQueueInfo() { + StringBuilder tb = new StringBuilder(); + if (runningTask != null) { + tb.append("\nRUNNING SINGLE FLIGHT TASK NUMBER: 1"); + tb.append(String.format("\nRUNNING SINGLE FLIGHT TASK NAME: %s", runningTask.getSyncSignature())); + } + + tb.append(String.format("\nPENDING SINGLE FLIGHT TASK NUMBER: %s", pendingQueue.size())); + tb.append(String.format("\nPENDING SINGLE FLIGHT TASK[NAME: %s, TASK QUEUE SIZE: %d] ", + syncSignature, pendingQueue.size())); + for (Object obj : pendingQueue) { + SingleFlightTask task = ((SingleFlightFuture) obj).getTask(); + + if (task.getThreadContext() == null) { + break; + } + + String taskId = null; + if (task.getThreadContext().containsKey(Constants.THREAD_CONTEXT_API)) { + taskId = task.getThreadContext().get(Constants.THREAD_CONTEXT_API); + } + + if (task.getThreadContext().containsKey(Constants.THREAD_CONTEXT_TASK)) { + taskId = task.getThreadContext().get(Constants.THREAD_CONTEXT_TASK); + } + + if (taskId == null) { + break; + } + + tb.append(String.format("\nPENDING TASK[NAME: %s, TASK ID: %s] ", + task.getName(), taskId)); + } + + return tb.toString(); + } + } + + private class ChainTaskQueueWrapper extends AbstractTaskQueueWrapper { + final LinkedList pendingQueue = new LinkedList(); final Map subPendingMap = new ConcurrentHashMap<>(); final LinkedList runningQueue = new LinkedList(); AtomicInteger counter = new AtomicInteger(0); int maxThreadNum = -1; - String syncSignature; int addSubPending(String deduplicateStr) { subPendingMap.compute(deduplicateStr, (k, v) -> { @@ -533,10 +829,13 @@ boolean addTask(ChainFuture task, int length) { void startThreadIfNeeded() { if (counter.get() >= maxThreadNum) { - logger.debug(String.format("syncSignature: %s reached maxThreadNum: %s, current: %d", syncSignature, maxThreadNum, counter.get())); + logger.debug(String.format("Chain task syncSignature: %s reached maxThreadNum: %s, current: %d, pending queue size: %d", + syncSignature, maxThreadNum, counter.get(), pendingQueue.size())); + dumpTaskQueueIfNeeded(pendingQueue.size()); return; } + resetPendingQueueThreshold(); counter.incrementAndGet(); _threadFacade.submit(new Task() { @Override @@ -563,24 +862,23 @@ private void runQueue() { synchronized (runningQueue) { processTimeoutTask(cf); - cf.startExecutionTimeInMills = zTimer.getCurrentTimeMillis(); + cf.setStartExecutionTimeInMills(zTimer.getCurrentTimeMillis()); // add to running queue - logger.debug(String.format("Start executing runningQueue: %s, task name: %s", syncSignature, cf.getTask().getName())); runningQueue.offer(cf); Optional.ofNullable(getApiId(cf)) .ifPresent(apiId -> apiRunningSignature.computeIfAbsent(apiId, k -> Collections.synchronizedList(new ArrayList<>())).add(syncSignature)); } - if (cf.getTask().getDeduplicateString() != null) { - removeSubPending(cf.getTask().getDeduplicateString(), false); + // recover task context from backup + if (cf.getTask().getTaskContext() != null) { + TaskContext.setTaskContext(cf.getTask().getTaskContext()); } - // recover task context from backup - if (cf.getTask().taskContext != null) { - TaskContext.setTaskContext(cf.getTask().taskContext); - } else { - TaskContext.removeTaskContext(); + logger.debug(String.format("Start executing runningQueue: %s, task name: %s", syncSignature, cf.getTask().getName())); + + if (cf.getTask().getDeduplicateString() != null) { + removeSubPending(cf.getTask().getDeduplicateString(), false); } cf.run(() -> { @@ -598,6 +896,15 @@ private void runQueue() { } } + /* + Note: run queue @AsyncThread will set thread context from + current task and next task's context will not be set until + `cf.run` so the code from `runQueue()` to `cf.run` will + use a wrong api id which might be confusing. + + Manually remove thread context here to avoid this issue. + */ + TaskContext.removeTaskContext(); runQueue(); }); } @@ -619,26 +926,55 @@ public Void call() { } }); } + + @Override + protected String getTaskQueueInfo() { + return getChainInfo().toString(); + } + + protected ChainInfo getChainInfo() { + long now = zTimer.getCurrentTimeMillis(); + + ChainInfo info = new ChainInfo(); + info.setMaxThreadNum(maxThreadNum); + + int index = 0; + synchronized (runningQueue) { + for (Object obj : runningQueue) { + ChainFuture cf = (ChainFuture) obj; + info.addRunningTask(TaskInfoBuilder.buildRunningTaskInfo(cf, now, index++)); + } + } + + // pendingQueue is synchronized with chainTasks, do not synchronize itself + synchronized (chainTasks) { + for (Object obj : pendingQueue) { + ChainFuture cf = (ChainFuture) obj; + info.addPendingTask(TaskInfoBuilder.buildPendingTaskInfo(cf, now, index++)); + } + } + return info; + } } @ExceptionSafe - private void processTimeoutTask(ChainFuture cf) { + private void processTimeoutTask(AbstractTimeStatisticFuture abstractTimeStatisticFuture) { long now = System.currentTimeMillis(); - PendingTaskInfo taskInfo = TaskInfoBuilder.buildPendingTaskInfo(cf, now, 0); - Double timeout = 0.0; + PendingTaskInfo taskInfo = TaskInfoBuilder.buildPendingTaskInfo(abstractTimeStatisticFuture, now, 0); + long timeout = 0L; if (taskInfo.getContext().isEmpty()) { return; } for (String c : taskInfo.getContextList()) { Map context = JSONObjectUtil.toObject(c, LinkedHashMap.class); - timeout = (context.get("timeout") == null) ? 0 : (Double) context.get("timeout"); + timeout = (context.get("timeout") == null) ? 0 : (long) context.get("timeout"); } - if (timeout > 0 && taskInfo.getPendingTime() * 1000 > timeout.longValue()){ + if (timeout > 0 && taskInfo.getPendingTime() * 1000 > timeout){ logger.warn(String.format("this task has been pending for %s ms longer than timeout %s ms, cancel it. task info: %s", - taskInfo.getPendingTime()*1000, timeout, taskInfo.toString())); - cf.cancel(true); + taskInfo.getPendingTime()*1000, timeout, taskInfo)); + abstractTimeStatisticFuture.cancel(true); } } @@ -670,14 +1006,32 @@ private Future doChainSyncSubmit(final ChainTask task) { @Override public Future chainSubmit(ChainTask task) { - // backup task context for each chain task - if (TaskContext.getTaskContext() != null) { - task.taskContext = new HashMap<>(TaskContext.getTaskContext()); - } - return doChainSyncSubmit(task); } + @Override + public Future singleFlightSubmit(SingleFlightTask task) { + return doSingleFlightSyncSubmit(task); + } + + private Future doSingleFlightSyncSubmit(SingleFlightTask task) { + assert task.getSyncSignature() != null : "How can you submit a single flight chain task without sync signature ???"; + + synchronized (singleFlightTasks) { + final String signature = task.getSyncSignature(); + SingleFlightQueueWrapper wrapper = singleFlightTasks.get(signature); + if (wrapper == null) { + wrapper = new SingleFlightQueueWrapper(); + singleFlightTasks.put(signature, wrapper); + } + + SingleFlightFuture sf = new SingleFlightFuture(task); + wrapper.addSingleFlightTask(sf); + wrapper.startSingleFlightIfNeed(); + return sf; + } + } + @Override public Map getSyncTaskStatistics() { Map ret = new ConcurrentHashMap<>(); diff --git a/core/src/main/java/org/zstack/core/thread/ScheduledThreadPoolExecutorExt.java b/core/src/main/java/org/zstack/core/thread/ScheduledThreadPoolExecutorExt.java index 5c2f79df185..f65bfaeca8a 100755 --- a/core/src/main/java/org/zstack/core/thread/ScheduledThreadPoolExecutorExt.java +++ b/core/src/main/java/org/zstack/core/thread/ScheduledThreadPoolExecutorExt.java @@ -49,7 +49,7 @@ protected void beforeExecute(Thread t, Runnable r) { try { hook.beforeExecute(t, r); } catch (Exception e) { - _logger.warn("Unhandle exception happend during executing ThreadAroundHook: " + debugHook.getClass().getCanonicalName(), e); + _logger.warn("Unhandled exception happened during executing ThreadAroundHook: " + debugHook.getClass().getCanonicalName(), e); } } } @@ -70,7 +70,7 @@ protected void afterExecute(Runnable r, Throwable t) { try { hook.afterExecute(r, t); } catch (Exception e) { - _logger.warn("Unhandle exception happend during executing ThreadAroundHook: " + debugHook.getClass().getCanonicalName(), e); + _logger.warn("Unhandled exception happened during executing ThreadAroundHook: " + debugHook.getClass().getCanonicalName(), e); } } } diff --git a/core/src/main/java/org/zstack/core/thread/SingleFlightTask.java b/core/src/main/java/org/zstack/core/thread/SingleFlightTask.java new file mode 100644 index 00000000000..61fb8f84d00 --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/SingleFlightTask.java @@ -0,0 +1,53 @@ +package org.zstack.core.thread; + +import org.zstack.header.core.AsyncBackup; +import org.zstack.header.core.ReturnValueCompletion; + +import java.util.function.Consumer; + +public class SingleFlightTask extends AbstractChainTask { + public SingleFlightTask(AsyncBackup one, AsyncBackup... others) { + super(one, others); + } + + public interface SingleFlightDone { + void accept(SingleFlightTaskResult result); + } + + @Override + public String getSyncSignature() { + return this.syncSignature; + } + + private String syncSignature; + private Consumer> consumer; + private SingleFlightDone singleFlightDone; + + @Override + public String getName() { + return getSyncSignature(); + } + + public SingleFlightTask setSyncSignature(String syncSignature) { + this.syncSignature = syncSignature; + return this; + } + + public SingleFlightTask run(Consumer> consumer) { + this.consumer = consumer; + return this; + } + + public SingleFlightTask done(SingleFlightDone singleFlightDone) { + this.singleFlightDone = singleFlightDone; + return this; + } + + protected void singleFlightDone(SingleFlightTaskResult taskResult) { + singleFlightDone.accept(taskResult); + } + + public void start(ReturnValueCompletion externalCompletion) { + consumer.accept(externalCompletion); + } +} diff --git a/core/src/main/java/org/zstack/core/thread/SingleFlightTaskChain.java b/core/src/main/java/org/zstack/core/thread/SingleFlightTaskChain.java new file mode 100644 index 00000000000..478c8c5f0ed --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/SingleFlightTaskChain.java @@ -0,0 +1,12 @@ +package org.zstack.core.thread; + +import org.zstack.header.core.AsyncBackup; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public interface SingleFlightTaskChain extends AsyncBackup { + void execute(); +} diff --git a/core/src/main/java/org/zstack/core/thread/SingleFlightTaskResult.java b/core/src/main/java/org/zstack/core/thread/SingleFlightTaskResult.java new file mode 100644 index 00000000000..dcfd01c20ef --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/SingleFlightTaskResult.java @@ -0,0 +1,35 @@ +package org.zstack.core.thread; + +import org.zstack.header.errorcode.ErrorCode; + +public class SingleFlightTaskResult { + private Object result; + private boolean success = true; + private ErrorCode errorCode; + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public ErrorCode getErrorCode() { + return errorCode; + } + + public void setErrorCode(ErrorCode errorCode) { + this.success = false; + this.errorCode = errorCode; + this.result = null; + } +} diff --git a/core/src/main/java/org/zstack/core/thread/TaskInfoBuilder.java b/core/src/main/java/org/zstack/core/thread/TaskInfoBuilder.java index 51b3c323de1..cb3c1040d88 100644 --- a/core/src/main/java/org/zstack/core/thread/TaskInfoBuilder.java +++ b/core/src/main/java/org/zstack/core/thread/TaskInfoBuilder.java @@ -19,34 +19,33 @@ * Created by MaJin on 2019/7/4. */ public class TaskInfoBuilder { - static RunningTaskInfo buildRunningTaskInfo(DispatchQueueImpl.ChainFuture cf, long now, int index) { + static RunningTaskInfo buildRunningTaskInfo(AbstractTimeStatisticFuture abstractTimeStatisticFuture, long now, int index) { RunningTaskInfo info = new RunningTaskInfo(); - loadTaskInfo(info, cf, index); - info.setExecutionTime(TimeUnit.MILLISECONDS.toSeconds(now - cf.getStartExecutionTimeInMills())); - info.setPendingTime(TimeUnit.MILLISECONDS.toSeconds(now - cf.getStartPendingTimeInMills()) - info.getExecutionTime()); + loadTaskInfo(info, abstractTimeStatisticFuture.getTask(), index); + info.setExecutionTime(TimeUnit.MILLISECONDS.toSeconds(now - abstractTimeStatisticFuture.getStartExecutionTimeInMills())); + info.setPendingTime(TimeUnit.MILLISECONDS.toSeconds(now - abstractTimeStatisticFuture.getStartPendingTimeInMills()) - info.getExecutionTime()); return info; - } - static PendingTaskInfo buildPendingTaskInfo(DispatchQueueImpl.ChainFuture cf, long now, int index) { + static PendingTaskInfo buildPendingTaskInfo(AbstractTimeStatisticFuture abstractTimeStatisticFuture, long now, int index) { PendingTaskInfo info = new PendingTaskInfo(); - loadTaskInfo(info, cf, index); - info.setPendingTime(TimeUnit.MILLISECONDS.toSeconds(now - cf.getStartPendingTimeInMills())); + loadTaskInfo(info, abstractTimeStatisticFuture.getTask(), index); + info.setPendingTime(TimeUnit.MILLISECONDS.toSeconds(now - abstractTimeStatisticFuture.getStartPendingTimeInMills())); return info; } - static private void loadTaskInfo(TaskInfo info, DispatchQueueImpl.ChainFuture cf, int index) { - info.setName(cf.getTask().getName()); - info.setClassName(cf.getTask().getClass().getSimpleName()); + static private void loadTaskInfo(TaskInfo info, AbstractChainTask task, int index) { + info.setName(task.getName()); + info.setClassName(task.getClass().getSimpleName()); info.setIndex(index); - Map tc = cf.getTask().getThreadContext(); + Map tc = task.getThreadContext(); if (tc != null) { info.setApiName(tc.get(Constants.THREAD_CONTEXT_TASK_NAME)); info.setApiId(tc.get(Constants.THREAD_CONTEXT_API)); } info.setContextList(new ArrayList<>()); - for (AsyncBackup backup : cf.getTask().getBackups()) { + for (AsyncBackup backup : task.getBackups()) { if (backup instanceof Message) { info.getContextList().add(JSONObjectUtil.toJsonString(backup)); } diff --git a/core/src/main/java/org/zstack/core/thread/ThreadFacade.java b/core/src/main/java/org/zstack/core/thread/ThreadFacade.java index ac67dc4bb13..9eca11fa0f4 100755 --- a/core/src/main/java/org/zstack/core/thread/ThreadFacade.java +++ b/core/src/main/java/org/zstack/core/thread/ThreadFacade.java @@ -2,6 +2,7 @@ import org.zstack.header.Component; import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.core.progress.SingleFlightChainInfo; import java.util.Set; import java.util.concurrent.Future; @@ -12,16 +13,22 @@ public interface ThreadFacade extends Component { Future submitSyncPool(Task task); + Future submitTargetPool(Task task, String signature); + Future syncSubmit(SyncTask task); Future chainSubmit(ChainTask task); + Future singleFlightSubmit(SingleFlightTask task); + boolean isChainTaskRunning(String signature); ChainInfo getChainTaskInfo(String signature); ChainInfo cleanChainTaskInfo(String signature, Integer index, Boolean cleanUp, Boolean isRunningTask); + SingleFlightChainInfo getSingleFlightChainTaskInfo(String signature); + Set getApiRunningTaskSignature(String apiId); Future submitPeriodicTask(PeriodicTask task, long delay); @@ -38,10 +45,9 @@ public interface ThreadFacade extends Component { ThreadFacadeImpl.TimeoutTaskReceipt submitTimeoutTask(Runnable task, TimeUnit unit, long delay); - ThreadFacadeImpl.TimeoutTaskReceipt submitTimeoutTask(Runnable task, TimeUnit unit, long delay, boolean executeRightNow); - Runnable submitTimerTask(TimerTask task, TimeUnit unit, long delay); int getSyncThreadNum(int totalThreadNum); + void printThreadsAndTasks(); } diff --git a/core/src/main/java/org/zstack/core/thread/ThreadFacadeImpl.java b/core/src/main/java/org/zstack/core/thread/ThreadFacadeImpl.java index eda72c89e29..04a81cc84c8 100755 --- a/core/src/main/java/org/zstack/core/thread/ThreadFacadeImpl.java +++ b/core/src/main/java/org/zstack/core/thread/ThreadFacadeImpl.java @@ -1,9 +1,12 @@ package org.zstack.core.thread; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.jmx.JmxFacade; import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.core.progress.SingleFlightChainInfo; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.utils.CollectionUtils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.logging.CLoggerImpl; @@ -11,6 +14,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class ThreadFacadeImpl implements ThreadFacade, ThreadFactory, RejectedExecutionHandler, ThreadFacadeMXBean { private static final CLogger _logger = CLoggerImpl.getLogger(ThreadFacadeImpl.class); @@ -20,11 +24,14 @@ public class ThreadFacadeImpl implements ThreadFacade, ThreadFactory, RejectedEx private static final AtomicInteger seqNum = new AtomicInteger(0); private ScheduledThreadPoolExecutorExt _pool; private ScheduledThreadPoolExecutorExt _syncpool; // for sync tasks + private ConcurrentHashMap pools = new ConcurrentHashMap<>(); private DispatchQueue dpq; private final TimerPool timerPool = new TimerPool(5); @Autowired private JmxFacade jmxf; + @Autowired + private PluginRegistry pluginRegistry; private static class TimerWrapper extends Timer { private int cancelledTimerTaskCount = 0; @@ -140,13 +147,23 @@ public void init() { jmxf.registerBean("ThreadFacade", this); } + private void initThreadPool(ThreadPool pool) { + ScheduledThreadPoolExecutorExt threadExt = new ScheduledThreadPoolExecutorExt(pool.getThreadNum(), this, this); + pools.put(pool.getSyncSignature(), threadExt); + } + public void destroy() { _pool.shutdownNow(); _syncpool.shutdown(); + pools.forEach((queueName, pool) -> { + _logger.debug(String.format("shutdown thread pool: %s", queueName)); + pool.shutdown(); + }); } @Override public Future submit(Task task) { + _logger.trace(String.format("submit task: %s", task.getName())); return _pool.submit(new Worker(task)); } @@ -154,6 +171,12 @@ public Future submitSyncPool(Task task) { return _syncpool.submit(new Worker(task)); } + @Override + public Future submitTargetPool(Task task, String signature) { + ScheduledThreadPoolExecutorExt executorExt = pools.getOrDefault(signature, _syncpool); + return executorExt.submit(new Worker<>(task)); + } + @Override public Thread newThread(@Nonnull Runnable arg0) { return new Thread(arg0, "zs-thread-" + seqNum.getAndIncrement()); @@ -223,6 +246,11 @@ public Future chainSubmit(ChainTask task) { return dpq.chainSubmit(task); } + @Override + public Future singleFlightSubmit(SingleFlightTask task) { + return dpq.singleFlightSubmit(task); + } + @Override public boolean isChainTaskRunning(String signature) { return dpq.isChainTaskRunning(signature); @@ -238,6 +266,11 @@ public ChainInfo cleanChainTaskInfo(String signature, Integer index, Boolean cle return dpq.cleanChainTaskInfo(signature, index, cleanUp, isRunningTask); } + @Override + public SingleFlightChainInfo getSingleFlightChainTaskInfo(String signature) { + return dpq.getSingleFlightChainTaskInfo(signature); + } + @Override public Set getApiRunningTaskSignature(String apiId) { return dpq.getApiRunningTaskSignature(apiId); @@ -248,12 +281,7 @@ public interface TimeoutTaskReceipt { } @Override - public TimeoutTaskReceipt submitTimeoutTask(final Runnable task, TimeUnit unit, long delay) { - return submitTimeoutTask(task, unit, delay, false); - } - - @Override - public TimeoutTaskReceipt submitTimeoutTask(Runnable task, TimeUnit unit, long delay, boolean executeRightNow) { + public TimeoutTaskReceipt submitTimeoutTask(Runnable task, TimeUnit unit, long delay) { final TimerWrapper timer = timerPool.getTimer(); class TimerTaskWorker extends java.util.TimerTask implements TimeoutTaskReceipt { @@ -279,21 +307,9 @@ public boolean cancel() { TimerTaskWorker worker = new TimerTaskWorker(); timer.schedule(worker, unit.toMillis(delay)); - if (executeRightNow) { - executeRightNow(task); - } return worker; } - @AsyncThread - private void executeRightNow(final Runnable task) { - try { - task.run(); - } catch (Throwable t) { - _logger.warn(String.format("Unhandled exception happened when running %s", task.getClass().getName()), t); - } - } - @Override public Runnable submitTimerTask(final TimerTask task, TimeUnit unit, long delay) { final TimerWrapper timer = timerPool.getTimer(); @@ -316,13 +332,63 @@ public void run() { @Override public boolean start() { + int totalThreadNum = ThreadGlobalProperty.MAX_THREAD_NUM; + + List poolList = new ArrayList<>(); + for (ThreadPoolRegisterExtensionPoint ext : pluginRegistry.getExtensionList(ThreadPoolRegisterExtensionPoint.class)) { + List threadPools = ext.registerThreadPool(); + if (CollectionUtils.isEmpty(threadPools)) { + throw new CloudRuntimeException("Empty thread pool registration is not supported"); + } + + List noSignaturePools = threadPools.stream().filter(pool -> pool.getSyncSignature() == null).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(noSignaturePools)) { + throw new CloudRuntimeException("Thread pool registration do not allow empty syncSignature"); + } + + List distinctPoolNames = threadPools.stream().map(ThreadPool::getSyncSignature).distinct().collect(Collectors.toList()); + if (distinctPoolNames.size() < threadPools.size()) { + throw new CloudRuntimeException(String.format("Duplicate thread pool name detected %s", threadPools.stream().map(ThreadPool::getSyncSignature).collect(Collectors.toList()))); + } + + List nameDuplicatePool = poolList.stream().filter(pool -> threadPools.stream().anyMatch(newPool -> pool.getSyncSignature().equals(newPool.getSyncSignature()))).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(nameDuplicatePool)) { + throw new CloudRuntimeException(String.format("Duplicate thread pool name with existing pool %s", nameDuplicatePool.stream().map(ThreadPool::getSyncSignature).collect(Collectors.toList()))); + } + poolList.addAll(threadPools); + } + + _logger.debug(String.format("Load separate thread pool: %d", poolList.size())); + int separatedThreadNum = poolList.stream().mapToInt(ThreadPool::getThreadNum).sum(); + int internalThreadNum = totalThreadNum - separatedThreadNum; + if (internalThreadNum < 10) { + _logger.warn(String.format("ThreadFacade.maxThreadNum is configured to %s." + + " Remaining thread number for internal pools is %d, which is too" + + " small for running zstack. Change it to 10", + internalThreadNum, + ThreadGlobalProperty.MAX_THREAD_NUM)); + internalThreadNum = 10; + totalThreadNum = separatedThreadNum + internalThreadNum; + } + + _logger.debug(String.format("Total thread num: %s, registered thread num %s," + + " internal thread num %s", totalThreadNum, + separatedThreadNum, + internalThreadNum)); + poolList.forEach(this::initThreadPool); + return true; } @Override public boolean stop() { _pool.shutdown(); + _syncpool.shutdown(); timerPool.stop(); + pools.forEach((queueName, pool) -> { + _logger.debug(String.format("shutdown thread pool: %s", queueName)); + pool.shutdown(); + }); return true; } diff --git a/core/src/main/java/org/zstack/core/thread/ThreadPool.java b/core/src/main/java/org/zstack/core/thread/ThreadPool.java new file mode 100644 index 00000000000..f68e86f92e0 --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/ThreadPool.java @@ -0,0 +1,22 @@ +package org.zstack.core.thread; + +public class ThreadPool { + private String syncSignature; + private int threadNum; + + public String getSyncSignature() { + return syncSignature; + } + + public void setSyncSignature(String syncSignature) { + this.syncSignature = syncSignature; + } + + public int getThreadNum() { + return threadNum; + } + + public void setThreadNum(int threadNum) { + this.threadNum = threadNum; + } +} diff --git a/core/src/main/java/org/zstack/core/thread/ThreadPoolRegisterExtensionPoint.java b/core/src/main/java/org/zstack/core/thread/ThreadPoolRegisterExtensionPoint.java new file mode 100644 index 00000000000..88ccf644aa8 --- /dev/null +++ b/core/src/main/java/org/zstack/core/thread/ThreadPoolRegisterExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.core.thread; + +import java.util.List; + +public interface ThreadPoolRegisterExtensionPoint { + List registerThreadPool(); +} diff --git a/core/src/main/java/org/zstack/core/timeout/ApiTimeoutGlobalProperty.java b/core/src/main/java/org/zstack/core/timeout/ApiTimeoutGlobalProperty.java index 4b65883076f..0504af4a164 100755 --- a/core/src/main/java/org/zstack/core/timeout/ApiTimeoutGlobalProperty.java +++ b/core/src/main/java/org/zstack/core/timeout/ApiTimeoutGlobalProperty.java @@ -8,7 +8,7 @@ */ @GlobalPropertyDefinition public class ApiTimeoutGlobalProperty { - @GlobalProperty(name="ApiTimeout.org.zstack.header.image.APIAddImageMsg", defaultValue = "timeout::3h") + @GlobalProperty(name="ApiTimeout.org.zstack.header.image.APIAddImageMsg", defaultValue = "timeout::72h") @Deprecated public static String APIAddImageMsg; @GlobalProperty(name="ApiTimeout.org.zstack.header.image.APICreateRootVolumeTemplateFromRootVolumeMsg", defaultValue = "timeout::72h") diff --git a/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java b/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java index 1a9ed244222..fb7e1eed346 100755 --- a/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java +++ b/core/src/main/java/org/zstack/core/timeout/ApiTimeoutManagerImpl.java @@ -105,6 +105,13 @@ public long getMessageTimeout(ConfigurableTimeoutMessage msg) { } private long getNotApiMessageTimeout(ConfigurableTimeoutMessage msg) { + for (ApiTimeoutExtensionPoint apiTimeoutExt : apiTimeoutExts) { + Long timeout = apiTimeoutExt.getApiTimeout(); + if (timeout != null) { + return timeout; + } + } + String s = gcf.getConfigValue(CONFIGURABLE_TIMEOUT_GLOBAL_CONFIG_TYPE, msg.getClass().getName(), String.class); return parseTimeout(s); } @@ -125,17 +132,29 @@ private long getAPIMessageTimeout(APIMessage msg) { @Override public void beforeDeliveryMessage(Message msg) { - if (!TaskContext.containsTaskContext(TASK_CONTEXT_MESSAGE_DEADLINE)) { - long currentTime = timer.getCurrentTimeMillis(); - - if (msg instanceof ConfigurableTimeoutMessage) { - TaskContext.putTaskContextItem(TASK_CONTEXT_MESSAGE_TIMEOUT, String.valueOf(getMessageTimeout((ConfigurableTimeoutMessage) msg))); - TaskContext.putTaskContextItem(TASK_CONTEXT_MESSAGE_DEADLINE, String.valueOf(currentTime + getMessageTimeout((ConfigurableTimeoutMessage) msg))); - } else if (msg instanceof NeedReplyMessage) { - TaskContext.putTaskContextItem(TASK_CONTEXT_MESSAGE_TIMEOUT, String.valueOf(getMessageTimeout())); - TaskContext.putTaskContextItem(TASK_CONTEXT_MESSAGE_DEADLINE, String.valueOf(currentTime + getMessageTimeout())); - } + setTaskLoggingContext(getMessageTimeoutDscFromMessage(msg)); + } + + private long calculateMessageDeadline(long timeout) { + return timer.getCurrentTimeMillis() + timeout; + } + + private MessageTimeoutDsc getMessageTimeoutDscFromMessage(Message msg) { + MessageTimeoutDsc mtd = new MessageTimeoutDsc(); + + if (msg instanceof ConfigurableTimeoutMessage) { + long timeout = ((ConfigurableTimeoutMessage) msg).getTimeout(); + long deadline = ((ConfigurableTimeoutMessage) msg).getMessageDeadline(); + mtd.setMessageTimeout(timeout != -1 ? timeout : getMessageTimeout((ConfigurableTimeoutMessage) msg)); + mtd.setMessageDeadline(deadline != -1 ? deadline : calculateMessageDeadline(mtd.getMessageTimeout())); + } else if (msg instanceof NeedReplyMessage) { + long timeout = ((NeedReplyMessage) msg).getTimeout(); + long deadline = ((NeedReplyMessage) msg).getMessageDeadline(); + mtd.setMessageTimeout(timeout != -1 ? timeout : getMessageTimeout()); + mtd.setMessageDeadline(deadline != -1 ? deadline : calculateMessageDeadline(mtd.getMessageTimeout())); } + + return mtd; } private long getMessageTimeout() { @@ -278,7 +297,7 @@ private void collectLegacyTimeout() { private long parseTimeout(String timeout) { if ("5m".equals(timeout)) { - // optimization as the most of default timeout are 5 minutes + // optimization as the most default timeout are 5 minutes return 300000; } @@ -320,33 +339,91 @@ public Long getTimeoutSeconds() { @Override public void setMessageTimeout(Message msg) { if (msg instanceof ConfigurableTimeoutMessage) { - ((ConfigurableTimeoutMessage) msg).setTimeout(evalTimeout(getMessageTimeout((ConfigurableTimeoutMessage) msg))); + MessageTimeoutDsc mtd = evalTimeout(getMessageTimeout((ConfigurableTimeoutMessage) msg)); + ((ConfigurableTimeoutMessage) msg).setTimeout(mtd.getMessageTimeout()); + ((ConfigurableTimeoutMessage) msg).setMessageDeadline(mtd.getMessageDeadline()); } else if (msg instanceof NeedReplyMessage) { NeedReplyMessage nmsg = (NeedReplyMessage) msg; if (nmsg.getTimeout() == -1) { - nmsg.setTimeout(evalTimeout(getMessageTimeout())); + MessageTimeoutDsc mtd = evalTimeout(getMessageTimeout()); + nmsg.setTimeout(mtd.getMessageTimeout()); + nmsg.setMessageDeadline(mtd.getMessageDeadline()); } } } - private long evalTimeout(long messageTimeout) { - if (!TaskContext.containsTaskContext(TASK_CONTEXT_MESSAGE_DEADLINE)) { + private void setTaskLoggingContext(MessageTimeoutDsc mtd) { + if (mtd == null) { + return; + } + + TaskContext.putTaskContextItem(TASK_CONTEXT_MESSAGE_TIMEOUT, String.valueOf(mtd.getMessageTimeout())); + TaskContext.putTaskContextItem(TASK_CONTEXT_MESSAGE_DEADLINE, String.valueOf(mtd.getMessageDeadline())); + } + + static class MessageTimeoutDsc { + private long messageTimeout = -1; + private long messageDeadline = -1; + + public long getMessageTimeout() { return messageTimeout; } - if (TaskContext.containsTaskContext(TASK_CONTEXT_MESSAGE_TIMEOUT)) { - long originTimeout = Long.parseLong((String) TaskContext.getTaskContext().get(TASK_CONTEXT_MESSAGE_TIMEOUT)); + public void setMessageTimeout(long messageTimeout) { + this.messageTimeout = messageTimeout; + } - // deadline should be updated - if (messageTimeout != originTimeout) { - long deadline = Long.parseLong((String) TaskContext.getTaskContext().get(TASK_CONTEXT_MESSAGE_DEADLINE)); - long remainingTime = deadline - timer.getCurrentTimeMillis(); + public long getMessageDeadline() { + return messageDeadline; + } - TaskContext.getTaskContext().put(TASK_CONTEXT_MESSAGE_DEADLINE, String.valueOf(timer.getCurrentTimeMillis() + messageTimeout - (originTimeout - remainingTime))); - TaskContext.getTaskContext().put(TASK_CONTEXT_MESSAGE_TIMEOUT, String.valueOf(messageTimeout)); - } + public void setMessageDeadline(long messageDeadline) { + this.messageDeadline = messageDeadline; + } + } + + private MessageTimeoutDsc evalTimeout(long messageTimeout) { + MessageTimeoutDsc mtd = new MessageTimeoutDsc(); + + // no deadline is set, use message timeout directly + if (!TaskContext.containsTaskContext(TASK_CONTEXT_MESSAGE_DEADLINE)) { + mtd.setMessageTimeout(messageTimeout); + mtd.setMessageDeadline(calculateMessageDeadline(messageTimeout)); + return mtd; + } + + // no message timeout from context + boolean noMessageTimeoutInContext = !TaskContext.containsTaskContext(TASK_CONTEXT_MESSAGE_TIMEOUT); + if (noMessageTimeoutInContext) { + mtd.setMessageTimeout(getTimeout()); + mtd.setMessageDeadline(calculateMessageDeadline(mtd.getMessageTimeout())); + return mtd; + } + + // timeout from context not changed, keep the deadline with context + long messageTimeoutFromContext = Long.parseLong((String) TaskContext + .getTaskContext() + .get(TASK_CONTEXT_MESSAGE_TIMEOUT)); + long originalDeadlineFromContext = Long.parseLong((String) TaskContext + .getTaskContext() + .get(TASK_CONTEXT_MESSAGE_DEADLINE)); + if (messageTimeoutFromContext == messageTimeout) { + mtd.setMessageTimeout(messageTimeoutFromContext); + mtd.setMessageDeadline(originalDeadlineFromContext); + return mtd; } - return getTimeout(); + // in most cases message deadline is shared + // only if message manually set a different message timeout or timeout changed + // due to ApiTimeoutExtensionPoint message deadline need to follow the rule + // that if message timeout longer than current message timeout, choose a longer + // message and if timeout shorter than current message timeout, choose a shorter + // deadline + long newMessageDeadline = timer.getCurrentTimeMillis() + messageTimeout; + mtd.setMessageTimeout(messageTimeout); + mtd.setMessageDeadline(messageTimeout < messageTimeoutFromContext ? + Math.min(originalDeadlineFromContext, newMessageDeadline) : + Math.max(originalDeadlineFromContext, newMessageDeadline)); + return mtd; } } diff --git a/core/src/main/java/org/zstack/core/timeout/TimeHelper.java b/core/src/main/java/org/zstack/core/timeout/TimeHelper.java index 3344432b732..db6c8e066f6 100644 --- a/core/src/main/java/org/zstack/core/timeout/TimeHelper.java +++ b/core/src/main/java/org/zstack/core/timeout/TimeHelper.java @@ -5,6 +5,7 @@ import org.zstack.core.thread.ThreadFacade; import javax.annotation.PostConstruct; +import java.sql.Timestamp; import java.util.concurrent.TimeUnit; public class TimeHelper implements Timer { @@ -41,4 +42,9 @@ public void run() { public long getCurrentTimeMillis() { return currentTimeMillis; } + + @Override + public Timestamp getCurrentTimestamp() { + return new Timestamp(currentTimeMillis); + } } diff --git a/core/src/main/java/org/zstack/core/timeout/Timer.java b/core/src/main/java/org/zstack/core/timeout/Timer.java index d9f6eb6fa1d..039190fe435 100644 --- a/core/src/main/java/org/zstack/core/timeout/Timer.java +++ b/core/src/main/java/org/zstack/core/timeout/Timer.java @@ -1,5 +1,8 @@ package org.zstack.core.timeout; +import java.sql.Timestamp; + public interface Timer { long getCurrentTimeMillis(); + Timestamp getCurrentTimestamp(); } diff --git a/core/src/main/java/org/zstack/core/tracker/BatchTracker.java b/core/src/main/java/org/zstack/core/tracker/BatchTracker.java new file mode 100644 index 00000000000..51242251514 --- /dev/null +++ b/core/src/main/java/org/zstack/core/tracker/BatchTracker.java @@ -0,0 +1,171 @@ +package org.zstack.core.tracker; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.thread.PeriodicTask; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.Component; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Random; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; + +/** + */ +public abstract class BatchTracker implements Component { + public abstract String getResourceName(); + + public abstract long getTaskInterval(); + public abstract void executeTask(List resourceUuids); + public abstract void rescan(); + + private final static CLogger logger = Utils.getLogger(PingTracker.class); + + private final List resourceUuids = Collections.synchronizedList(new ArrayList<>()); + private Future trackerThread = null; + + @Autowired + protected CloudBus bus; + @Autowired + protected ThreadFacade thdf; + + private class Tracker implements PeriodicTask { + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + public long getInterval() { + return getTaskInterval(); + } + + @Override + public String getName() { + return String.format("pingTracker-for-%s-managementNode-%s", getResourceName(), Platform.getManagementServerId()); + } + + @Override + public void run() { + try { + executionHook(); + synchronized (resourceUuids) { + executeTask(resourceUuids); + } + } catch (Throwable t) { + logger.warn("unhandled throwable", t); + } + } + } + + protected void executionHook() { + + } + + protected void trackHook(String resourceUuid) { + } + + protected void untrackHook(String resourceUuid) { + } + + protected void startHook() { + } + + protected void taskIntervalChanged() { + startTracker(); + } + + public void track(String resUuid) { + synchronized (resourceUuids) { + if (!resourceUuids.contains(resUuid)) { + resourceUuids.add(resUuid); + trackHook(resUuid); + logger.debug(String.format("start tracking %s[uuid:%s]", getResourceName(), resUuid)); + } + } + } + + public void untrackIf(Predicate predicate) { + synchronized (resourceUuids) { + resourceUuids.removeIf(predicate); + } + } + + public void untrackAll() { + synchronized (resourceUuids) { + resourceUuids.clear(); + logger.debug(String.format("untrack all %s", getResourceName())); + } + } + + public void untrack(String resUuid) { + synchronized (resourceUuids) { + resourceUuids.remove(resUuid); + untrackHook(resUuid); + logger.debug(String.format("stop tracking %s[uuid:%s]", getResourceName(), resUuid)); + } + } + + public void track(Collection resUuids) { + synchronized (resourceUuids) { + for (String resUuid : resUuids) { + if (!resourceUuids.contains(resUuid)) { + resourceUuids.add(resUuid); + trackHook(resUuid); + logger.debug(String.format("start tracking %s[uuid:%s]", getResourceName(), resUuid)); + } + } + } + } + + public void untrack(Collection resUuids) { + synchronized (resourceUuids) { + for (String resUuid : resUuids) { + resourceUuids.remove(resUuid); + untrackHook(resUuid); + logger.debug(String.format("stop tracking %s[uuid:%s]", getResourceName(), resUuid)); + } + } + } + + protected synchronized void startTracker() { + if (trackerThread != null) { + trackerThread.cancel(true); + } + + if (CoreGlobalProperty.UNIT_TEST_ON) { + trackerThread = thdf.submitPeriodicTask(new Tracker(), getTaskInterval()); + } else { + trackerThread = thdf.submitPeriodicTask(new Tracker(), (long) getTaskInterval() + new Random().nextInt(30)); + } + } + + @Override + public boolean start() { + startTracker(); + startHook(); + return true; + } + + @Override + public boolean stop() { + if (trackerThread != null) { + trackerThread.cancel(true); + } + + return true; + } + + public List getResourceUuids() { + return resourceUuids; + } +} diff --git a/core/src/main/java/org/zstack/core/tacker/PingTracker.java b/core/src/main/java/org/zstack/core/tracker/PingTracker.java similarity index 95% rename from core/src/main/java/org/zstack/core/tacker/PingTracker.java rename to core/src/main/java/org/zstack/core/tracker/PingTracker.java index f0d1c3ccf24..ffb0ec22268 100755 --- a/core/src/main/java/org/zstack/core/tacker/PingTracker.java +++ b/core/src/main/java/org/zstack/core/tracker/PingTracker.java @@ -1,4 +1,4 @@ -package org.zstack.core.tacker; +package org.zstack.core.tracker; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.CoreGlobalProperty; @@ -67,6 +67,10 @@ public void run() { } NeedReplyMessage msg = getPingMessage(resUuid); + if (msg == null) { + continue; + } + msgs.add(msg); resourceInTracking.add(resUuid); tmp.put(msg, resUuid); @@ -155,7 +159,7 @@ public void untrack(Collection resUuids) { } } - protected void startTracker() { + protected synchronized void startTracker() { if (trackerThread != null) { trackerThread.cancel(true); } @@ -163,7 +167,7 @@ protected void startTracker() { if (CoreGlobalProperty.UNIT_TEST_ON) { trackerThread = thdf.submitPeriodicTask(new Tracker(), getPingInterval()); } else { - trackerThread = thdf.submitPeriodicTask(new Tracker(), getPingInterval() + new Random().nextInt(30)); + trackerThread = thdf.submitPeriodicTask(new Tracker(), (long) getPingInterval() + new Random().nextInt(30)); } } diff --git a/core/src/main/java/org/zstack/core/trash/StorageRecycleImpl.java b/core/src/main/java/org/zstack/core/trash/StorageRecycleImpl.java index 5aaa5cb5349..eb6c1a76d00 100644 --- a/core/src/main/java/org/zstack/core/trash/StorageRecycleImpl.java +++ b/core/src/main/java/org/zstack/core/trash/StorageRecycleImpl.java @@ -1,8 +1,8 @@ package org.zstack.core.trash; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; import org.zstack.core.CoreGlobalProperty; -import static org.zstack.core.Platform.inerr; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.componentloader.PluginRegistry; @@ -15,7 +15,7 @@ import org.zstack.core.thread.PeriodicTask; import org.zstack.core.thread.ThreadFacade; import org.zstack.header.Component; -import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.trash.InstallPathRecycleInventory; import org.zstack.header.core.trash.InstallPathRecycleVO; import org.zstack.header.core.trash.InstallPathRecycleVO_; @@ -26,22 +26,13 @@ import org.zstack.header.image.ImageVO; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.backup.BackupStorageVO; -import org.zstack.header.storage.primary.CleanUpTrashOnPrimaryStroageMsg; -import org.zstack.header.storage.primary.ImageCacheVO; -import org.zstack.header.storage.primary.ImageCacheVO_; -import org.zstack.header.storage.primary.PrimaryStorageConstant; -import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.storage.primary.*; import org.zstack.header.storage.snapshot.VolumeSnapshotAfterDeleteExtensionPoint; import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; import org.zstack.header.storage.snapshot.VolumeSnapshotVO; import org.zstack.header.storage.snapshot.VolumeSnapshotVO_; import org.zstack.header.vo.ResourceVO; -import org.zstack.header.volume.VolumeBeforeExpungeExtensionPoint; -import org.zstack.header.volume.VolumeFormat; -import org.zstack.header.volume.VolumeInventory; -import org.zstack.header.volume.VolumeJustBeforeDeleteFromDbExtensionPoint; -import org.zstack.header.volume.VolumeVO; -import org.zstack.header.volume.VolumeVO_; +import org.zstack.header.volume.*; import org.zstack.utils.CollectionDSL; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; @@ -52,6 +43,9 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.inerr; /** * Created by mingjian.deng on 2019/9/19. @@ -94,6 +88,8 @@ private InstallPathRecycleInventory createRecycleFromVolume(TrashType type, bool } vo = dbf.persistAndRefresh(vo); + logger.debug(String.format("create trash for volume[uuid:%s, installPath:%s] on primary storage[uuid:%s], trashId: %s, type: %s", + vol.getUuid(), vol.getInstallPath(), vol.getPrimaryStorageUuid(), vo.getTrashId(), type)); return InstallPathRecycleInventory.valueOf(vo); } @@ -110,6 +106,8 @@ private InstallPathRecycleInventory createRecycleFromImage(TrashType type, boole vo.setSize(image.getSize()); vo = dbf.persistAndRefresh(vo); + logger.debug(String.format("create trash for image[uuid:%s, installPath:%s] on backup storage[uuid:%s], trashId: %s, type: %s", + image.getUuid(), image.getUrl(), image.getDescription(), vo.getTrashId(), type)); return InstallPathRecycleInventory.valueOf(vo); } @@ -130,6 +128,8 @@ private InstallPathRecycleInventory createRecycleFromVolumeSnapshot(TrashType ty } vo = dbf.persistAndRefresh(vo); + logger.debug(String.format("create trash for volume snapshot[uuid:%s, installPath:%s] on primary storage[uuid:%s], trashId: %s, type: %s", + snapshot.getUuid(), snapshot.getPrimaryStorageInstallPath(), snapshot.getPrimaryStorageUuid(), vo.getTrashId(), type)); return InstallPathRecycleInventory.valueOf(vo); } @@ -186,7 +186,7 @@ private String checkImageCache(String installPath) { return null; } - private String checkCephVolumeSnapshot(String installPath) { + private String checkInnerVolumeSnapshot(String installPath) { List uuids = Q.New(VolumeSnapshotVO.class).like(VolumeSnapshotVO_.primaryStorageInstallPath, installPath + "@%").select(VolumeSnapshotVO_.uuid).listValues(); if (uuids.size() > 0) { return String.format("%s is still in using by volumesnapshot %s, cannot remove it from trash before delete them", installPath, uuids); @@ -199,7 +199,7 @@ private String checkVolumeSnapshot(String installPath) { if (uuids.size() > 0) { return String.format("%s is still in using by volumesnapshot %s, cannot remove it from trash before delete them", installPath, uuids); } - return checkCephVolumeSnapshot(installPath); + return checkInnerVolumeSnapshot(installPath); } private String checkImage(String installPath) { @@ -210,7 +210,8 @@ private String checkImage(String installPath) { return null; } - private String makeSureInstallPathNotUsedByVolume(String installPath) { + @Transactional(readOnly = true) + protected String makeSureInstallPathNotUsedByVolume(String installPath) { String details = checkVolume(installPath); if (details != null) { return details; @@ -219,14 +220,15 @@ private String makeSureInstallPathNotUsedByVolume(String installPath) { if (details != null) { return details; } - details = checkCephVolumeSnapshot(installPath); + details = checkInnerVolumeSnapshot(installPath); if (details != null) { return details; } return null; } - private String makeSureInstallPathNotUsedByImage(String installPath) { + @Transactional(readOnly = true) + protected String makeSureInstallPathNotUsedByImage(String installPath) { String details = checkImage(installPath); if (details != null) { return details; @@ -234,7 +236,8 @@ private String makeSureInstallPathNotUsedByImage(String installPath) { return null; } - private String makeSureInstallPathNotUsedBySnapshot(String installPath) { + @Transactional(readOnly = true) + protected String makeSureInstallPathNotUsedBySnapshot(String installPath) { String details = checkVolumeSnapshot(installPath); if (details != null) { return details; @@ -248,12 +251,35 @@ private String makeSureInstallPathNotUsedBySnapshot(String installPath) { @Override public String makeSureInstallPathNotUsed(InstallPathRecycleInventory inv) { - if (inv.getResourceType().equals(VolumeVO.class.getSimpleName())) { - return makeSureInstallPathNotUsedByVolume(inv.getInstallPath()); - } else if (inv.getResourceType().equals(ImageVO.class.getSimpleName())) { - return makeSureInstallPathNotUsedByImage(inv.getInstallPath()); - } else if (inv.getResourceType().equals(VolumeSnapshotVO.class.getSimpleName())) { - return makeSureInstallPathNotUsedBySnapshot(inv.getInstallPath()); + return makeSureInstallPathNotUsed(inv.getInstallPath(), inv.getResourceType()); + } + + @Override + @Transactional(readOnly = true) + public String makeSureInstallPathNotUsed(String installPath, String resourceType) { + if (VolumeVO.class.getSimpleName().equals(resourceType)) { + return makeSureInstallPathNotUsedByVolume(installPath); + } else if (ImageVO.class.getSimpleName().equals(resourceType)) { + return makeSureInstallPathNotUsedByImage(installPath); + } else if (VolumeSnapshotVO.class.getSimpleName().equals(resourceType)) { + return makeSureInstallPathNotUsedBySnapshot(installPath); + } + return null; + } + + @Override + public String makeSurePrimaryStorageInstallPathNotUsed(String installPath) { + String details = checkVolume(installPath); + if (details != null) { + return details; + } + details = checkImageCache(installPath); + if (details != null) { + return details; + } + details = checkVolumeSnapshot(installPath); + if (details != null) { + return details; } return null; } @@ -276,9 +302,10 @@ public Long getTrashId(String storageUuid, String installPath) { public void removeFromDb(Long trashId) { DebugUtils.Assert(trashId != null, "trashId is not allowed null here"); UpdateQuery.New(InstallPathRecycleVO.class).eq(InstallPathRecycleVO_.trashId, trashId).delete(); + logger.debug(String.format("remove trash[trashId:%s] from db", trashId)); } - private void deleteTrashForVolume(String resourceUuid, String primaryStorageUuid, Completion completion) { + private void deleteTrashForVolume(String resourceUuid, String primaryStorageUuid, NoErrorCompletion completion) { List vos = Q.New(InstallPathRecycleVO.class).eq(InstallPathRecycleVO_.storageUuid, primaryStorageUuid).list(); List trashIds = new ArrayList<>(); for (InstallPathRecycleVO vo: vos) { @@ -290,9 +317,9 @@ private void deleteTrashForVolume(String resourceUuid, String primaryStorageUuid deleteTrashForVolume(trashIds.iterator(), primaryStorageUuid, completion); } - private void deleteTrashForVolume(final Iterator trashIds, String primaryStorageUuid, Completion completion) { + private void deleteTrashForVolume(final Iterator trashIds, String primaryStorageUuid, NoErrorCompletion completion) { if (!trashIds.hasNext()) { - completion.success(); + completion.done(); return; } Long trashId = trashIds.next(); @@ -314,13 +341,12 @@ public void run(MessageReply reply) { } @Override - public void volumeSnapshotAfterDeleteExtensionPoint(VolumeSnapshotInventory snapshot, Completion completion) { + public void volumeSnapshotAfterDeleteExtensionPoint(VolumeSnapshotInventory snapshot, NoErrorCompletion completion) { deleteTrashForVolume(snapshot.getUuid(), snapshot.getPrimaryStorageUuid(), completion); } @Override - public void volumeSnapshotAfterFailedDeleteExtensionPoint(VolumeSnapshotInventory snapshot) { - + public void volumeSnapshotAfterCleanUpExtensionPoint(String volumeUuid, List snapshots) { } private void transfer(List trashs, String type) { @@ -390,14 +416,11 @@ public void run() { @Override public List findTrashInstallPath(String installPath, String storageUuid) { - List trashInstallPath = new ArrayList<>(); - List vos = Q.New(InstallPathRecycleVO.class).eq(InstallPathRecycleVO_.storageUuid, storageUuid).list(); - for (InstallPathRecycleVO vo: vos) { - if (vo.getInstallPath().startsWith(installPath)) { - trashInstallPath.add(vo.getInstallPath().substring(installPath.length())); - } - } - return trashInstallPath; + List absPaths = Q.New(InstallPathRecycleVO.class).select(InstallPathRecycleVO_.installPath) + .eq(InstallPathRecycleVO_.storageUuid, storageUuid) + .like(InstallPathRecycleVO_.installPath, String.format("%s%%", installPath)) + .listValues(); + return absPaths.stream().map(it -> it.substring(installPath.length())).collect(Collectors.toList()); } @Override @@ -409,7 +432,7 @@ public boolean stop() { public void volumePreExpunge(VolumeInventory volume) {} @Override - public void volumeBeforeExpunge(VolumeInventory volume, Completion completion) { + public void volumeBeforeExpunge(VolumeInventory volume, NoErrorCompletion completion) { deleteTrashForVolume(volume.getUuid(), volume.getPrimaryStorageUuid(), completion); } diff --git a/core/src/main/java/org/zstack/core/trash/StorageTrash.java b/core/src/main/java/org/zstack/core/trash/StorageTrash.java index 3b8e2d4408f..9c995ca680a 100644 --- a/core/src/main/java/org/zstack/core/trash/StorageTrash.java +++ b/core/src/main/java/org/zstack/core/trash/StorageTrash.java @@ -15,6 +15,8 @@ public interface StorageTrash { InstallPathRecycleInventory getTrash(Long trashId); String makeSureInstallPathNotUsed(InstallPathRecycleInventory inventory); + String makeSureInstallPathNotUsed(String installPath, String resourceType); + String makeSurePrimaryStorageInstallPathNotUsed(String installPath); List findTrashInstallPath(String installPath, String storageUuid); Long getTrashId(String storageUuid, String installPath); diff --git a/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionMsg.java b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionMsg.java new file mode 100644 index 00000000000..ce7ba728ea4 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionMsg.java @@ -0,0 +1,23 @@ +package org.zstack.core.upgrade; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.Collections; +import java.util.List; + + +@AutoQuery(replyClass = APIQueryAgentVersionReply.class, inventoryClass = AgentVersionInventory.class) +@RestRequest( + path = "/agent-version", + optionalPaths = {"/agent-version/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryAgentVersionReply.class +) +public class APIQueryAgentVersionMsg extends APIQueryMessage { + public static List __example__() { + return Collections.emptyList(); + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionMsgDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..dac031997d1 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.core.upgrade + +import org.zstack.core.upgrade.APIQueryAgentVersionReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryAgentVersion" + + category "core" + + desc """查询 Agent 版本信息""" + + rest { + request { + url "GET /v1/agent-version" + url "GET /v1/agent-version/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryAgentVersionMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryAgentVersionReply.class + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionReply.java b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionReply.java new file mode 100644 index 00000000000..350be017f66 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionReply.java @@ -0,0 +1,25 @@ +package org.zstack.core.upgrade; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQueryAgentVersionReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryAgentVersionReply __example__() { + APIQueryAgentVersionReply reply = new APIQueryAgentVersionReply(); + + return reply; + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionReplyDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..d934abf17ca --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/APIQueryAgentVersionReplyDoc_zh_cn.groovy @@ -0,0 +1,33 @@ +package org.zstack.core.upgrade + + +import org.zstack.core.upgrade.AgentVersionVO +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询 Agent 版本信息返回" + + ref { + name "inventories" + path "org.zstack.core.upgrade.APIQueryAgentVersionReply.inventories" + desc "null" + type "List" + since "5.0.0" + clz AgentVersionVO.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.core.upgrade.APIQueryAgentVersionReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/AgentVersionInventory.java b/core/src/main/java/org/zstack/core/upgrade/AgentVersionInventory.java new file mode 100644 index 00000000000..ec500148c93 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/AgentVersionInventory.java @@ -0,0 +1,85 @@ +package org.zstack.core.upgrade; + +import org.zstack.header.search.Inventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = AgentVersionVO.class) +public class AgentVersionInventory { + private String uuid; + private String agentType; + private String currentVersion; + private String expectVersion; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static AgentVersionInventory valueOf(AgentVersionVO vo) { + AgentVersionInventory inv = new AgentVersionInventory(); + inv.setUuid(vo.getUuid()); + inv.setAgentType(vo.getAgentType()); + inv.setCurrentVersion(vo.getCurrentVersion()); + inv.setExpectVersion(vo.getExpectVersion()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList(); + for (AgentVersionVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getAgentType() { + return agentType; + } + + public void setAgentType(String agentType) { + this.agentType = agentType; + } + + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(String currentVersion) { + this.currentVersion = currentVersion; + } + + public String getExpectVersion() { + return expectVersion; + } + + public void setExpectVersion(String expectVersion) { + this.expectVersion = expectVersion; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/AgentVersionInventoryDoc_zh_cn.groovy b/core/src/main/java/org/zstack/core/upgrade/AgentVersionInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..0ede356e722 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/AgentVersionInventoryDoc_zh_cn.groovy @@ -0,0 +1,43 @@ +package org.zstack.core.upgrade + +doc { + + title "Agent 版本信息" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.0.0" + } + field { + name "agentType" + desc "Agent 类型" + type "String" + since "5.0.0" + } + field { + name "currentVersion" + desc "当前版本" + type "String" + since "5.0.0" + } + field { + name "expectVersion" + desc "预期版本" + type "String" + since "5.0.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.0.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.0.0" + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/AgentVersionVO.java b/core/src/main/java/org/zstack/core/upgrade/AgentVersionVO.java new file mode 100644 index 00000000000..6d025fd98f6 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/AgentVersionVO.java @@ -0,0 +1,87 @@ +package org.zstack.core.upgrade; + +import org.zstack.header.vo.*; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; +import java.sql.Timestamp; + + +@Table +@Entity +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = ResourceVO.class, joinColumn = "resourceUuid") +}) +public class AgentVersionVO { + @Id + @Column + private String uuid; + + @Column + private String agentType; + + @Column + private String currentVersion; + + @Column + private String expectVersion; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getAgentType() { + return agentType; + } + + public void setAgentType(String agentType) { + this.agentType = agentType; + } + + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(String currentVersion) { + this.currentVersion = currentVersion; + } + + public String getExpectVersion() { + return expectVersion; + } + + public void setExpectVersion(String expectVersion) { + this.expectVersion = expectVersion; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/AgentVersionVO_.java b/core/src/main/java/org/zstack/core/upgrade/AgentVersionVO_.java new file mode 100644 index 00000000000..e12d136a8be --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/AgentVersionVO_.java @@ -0,0 +1,15 @@ +package org.zstack.core.upgrade; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(AgentVersionVO.class) +public class AgentVersionVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute agentType; + public static volatile SingularAttribute currentVersion; + public static volatile SingularAttribute expectVersion; + public static volatile SingularAttribute lastOpDate; + public static volatile SingularAttribute createDate; +} diff --git a/core/src/main/java/org/zstack/core/upgrade/GrayUpgradeAgent.java b/core/src/main/java/org/zstack/core/upgrade/GrayUpgradeAgent.java new file mode 100644 index 00000000000..b39231b10a9 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/GrayUpgradeAgent.java @@ -0,0 +1,8 @@ +package org.zstack.core.upgrade; + +/** + * author:kaicai.hu + * Date:2023/11/9 + */ +public class GrayUpgradeAgent { +} diff --git a/core/src/main/java/org/zstack/core/upgrade/GrayVersion.java b/core/src/main/java/org/zstack/core/upgrade/GrayVersion.java new file mode 100644 index 00000000000..9a5b56252a5 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/GrayVersion.java @@ -0,0 +1,11 @@ +package org.zstack.core.upgrade; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target(value = {ElementType.FIELD}) +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +public @interface GrayVersion { + String value(); +} diff --git a/core/src/main/java/org/zstack/core/upgrade/RBACInfo.java b/core/src/main/java/org/zstack/core/upgrade/RBACInfo.java new file mode 100644 index 00000000000..34858536753 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/RBACInfo.java @@ -0,0 +1,27 @@ +package org.zstack.core.upgrade; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .adminOnlyAPIs("org.zstack.core.upgrade.**") + .build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/UpgradeChecker.java b/core/src/main/java/org/zstack/core/upgrade/UpgradeChecker.java new file mode 100644 index 00000000000..160b32b7864 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/UpgradeChecker.java @@ -0,0 +1,422 @@ +package org.zstack.core.upgrade; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.ThreadContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.EventFacade; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.config.GlobalConfigException; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.Component; +import org.zstack.header.Constants; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; +import org.zstack.header.cluster.APIUpdateClusterOSMsg; +import org.zstack.header.console.APIRequestConsoleAccessMsg; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.host.APIReconnectHostMsg; +import org.zstack.header.message.APIMessage; +import org.zstack.header.vm.APIMigrateVmMsg; +import org.zstack.header.vm.APIRebootVmInstanceMsg; +import org.zstack.header.vm.APIStartVmInstanceMsg; +import org.zstack.header.vm.APIStopVmInstanceMsg; +import org.zstack.utils.FieldUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.VersionComparator; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.path.PathUtil; + +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.argerr; +import static org.zstack.core.Platform.operr; + +public class UpgradeChecker implements Component, GlobalApiMessageInterceptor { + private static final CLogger logger = Utils.getLogger(UpgradeChecker.class); + + @Autowired + private DatabaseFacade dbf; + + @Autowired + protected EventFacade evtf; + + @Autowired + protected PluginRegistry pluginRgty; + + private static Map> grayUpgradeConfigMap = new HashMap<>(); + private static ConcurrentLinkedQueue grayScaleApiWhiteList = new ConcurrentLinkedQueue<>(); + private static Set predefinedApiClassSet = new HashSet<>(); + + private static String INITIAL_AGENT_VERSION = "3.10.38"; + + @Override + public boolean start() { + if (!UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + return true; + } + initGrayScaleConfig(); + populateGlobalConfigForGrayscaleUpgrade(); + return true; + } + + @Override + public boolean stop() { + return true; + } + + private void initPredefinedApiClassSet() { + predefinedApiClassSet.add(APIStartVmInstanceMsg.class.getSimpleName()); + predefinedApiClassSet.add(APIStopVmInstanceMsg.class.getSimpleName()); + predefinedApiClassSet.add(APIRebootVmInstanceMsg.class.getSimpleName()); + predefinedApiClassSet.add(APIRequestConsoleAccessMsg.class.getSimpleName()); + predefinedApiClassSet.add(APIMigrateVmMsg.class.getSimpleName()); + predefinedApiClassSet.add(APIReconnectHostMsg.class.getSimpleName()); + predefinedApiClassSet.add(APIUpdateClusterOSMsg.class.getSimpleName()); + } + + private void populateGlobalConfigForGrayscaleUpgrade() { + initPredefinedApiClassSet(); + grayScaleApiWhiteList.addAll(predefinedApiClassSet); + List predefinedClasses; + try { + predefinedClasses = Arrays.asList(UpgradeGlobalConfig.ALLOWED_API_LIST_GRAYSCALE_UPGRADING.value().split(",")); + } catch (PatternSyntaxException exception) { + throw new CloudRuntimeException(String.format("Failed to split config value by ','," + + ", because %s. Please input a string separate api by ','", exception)); + } + grayScaleApiWhiteList.addAll(predefinedClasses); + + UpgradeGlobalConfig.ALLOWED_API_LIST_GRAYSCALE_UPGRADING + .installValidateExtension((category, name, oldValue, newValue) -> { + List apiClassNames; + try { + apiClassNames = Arrays.asList(newValue.split(",")); + } catch (PatternSyntaxException exception) { + throw new GlobalConfigException(String.format("Failed to split config value by ','," + + ", because %s. Please input a string separate api by ','", exception)); + } + + List matchedApiClassName = apiClassNames.stream() + .filter(className -> APIMessage.apiMessageClasses + .stream() + .anyMatch(clazz -> clazz.getSimpleName().equals(className))) + .collect(Collectors.toList()); + + apiClassNames.removeAll(matchedApiClassName); + if (!apiClassNames.isEmpty()) { + throw new GlobalConfigException(String.format("Failed to find api class name: %s", apiClassNames)); + } + }); + + UpgradeGlobalConfig.ALLOWED_API_LIST_GRAYSCALE_UPGRADING.installUpdateExtension((oldConfig, newConfig) -> { + List apiClassNames = Arrays.asList(newConfig.value().split(",")); + grayScaleApiWhiteList.clear(); + + apiClassNames.removeAll(predefinedApiClassSet); + grayScaleApiWhiteList.addAll(predefinedApiClassSet); + grayScaleApiWhiteList.addAll(apiClassNames); + }); + } + + public void initGrayScaleConfig() { + File grayUpgradeFile = PathUtil.findFileOnClassPath("grayUpgrade/grayUpgrade.json", true); + ObjectMapper objectMapper = new ObjectMapper(); + try { + grayUpgradeConfigMap = objectMapper.readValue(grayUpgradeFile, new TypeReference>>() { + }); + } catch (IOException e) { + throw new RuntimeException(String.format("unable to parse grayUpgrade json file[%s], exception: %s", grayUpgradeFile.getAbsolutePath(), e.getMessage())); + } + } + + private List> findCommandAndResponseFields(String commandName) { + Map commandFields = grayUpgradeConfigMap.get(commandName); + if (commandFields == null) { + return null; + } + + List> resultList = new ArrayList<>(); + resultList.add(commandFields); + + String rspName; + String responseName; + Pattern pattern = Pattern.compile("(Cmd|Command)$"); + Matcher matcher = pattern.matcher(commandName); + if (matcher.find()) { + rspName = matcher.replaceFirst("Rsp"); + responseName = matcher.replaceFirst("Response"); + } else { + rspName = commandName.concat("Rsp"); + responseName = commandName.concat("Response"); + } + + Map rspFields = grayUpgradeConfigMap.get(rspName); + if (rspFields != null) { + resultList.add(rspFields); + } + + Map responseFields = grayUpgradeConfigMap.get(responseName); + if (responseFields != null) { + resultList.add(responseFields); + } + + return resultList; + } + + public ErrorCode checkAgentHttpParamChanges(String agentUuid, String commandName, Object cmd) { + if (!UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + logger.trace("grayscale upgrade is not enabled, skip http param check"); + return null; + } + + final AgentVersionVO agentVersionVO; + AgentVersionVO versionVO = dbf.findByUuid(agentUuid, AgentVersionVO.class); + if (versionVO == null) { + agentVersionVO = new AgentVersionVO(); + agentVersionVO.setCurrentVersion(INITIAL_AGENT_VERSION); + agentVersionVO.setExpectVersion(dbf.getDbVersion()); + } else { + agentVersionVO = versionVO; + } + + // if agent version not changed skip gray scale check + if (agentVersionVO.getExpectVersion().equals(agentVersionVO.getCurrentVersion())) { + logger.trace(String.format("agent[uuid: %s] expected version: %s, current version :%s matched," + + " skip grayscale upgrade check", + agentUuid, + agentVersionVO.getCurrentVersion(), + agentVersionVO.getCurrentVersion())); + return null; + } + + // grayscale api white list check + if (ThreadContext.containsKey(Constants.THREAD_CONTEXT_API)) { + String className = ThreadContext.get(Constants.THREAD_CONTEXT_TASK_NAME); + if (className != null && grayScaleApiWhiteList + .stream() + .noneMatch(className::contains)) { + return operr("Api: %s is not allowed by allowedApiListGrayscaleUpgrading: %s.", + className, + grayScaleApiWhiteList); + } + } + + List> relatedFieldsVersionMap = findCommandAndResponseFields(commandName); + if (relatedFieldsVersionMap == null || relatedFieldsVersionMap.isEmpty()) { + logger.debug(String.format("Command: %s is not contained in gray scale upgrade check", commandName)); + return null; + } + + final Object commandObj; + if (cmd instanceof String) { + try { + commandObj = JSONObjectUtil.toObject((String) cmd, Class.forName(commandName)); + } catch (Exception e) { + throw new CloudRuntimeException(String.format("Failed to transform string: %s\n to \n object class: %s", cmd, commandName)); + } + } else { + commandObj = cmd; + } + + logger.debug("grayscale compare agentVersionVO " + JSONObjectUtil.toJsonString(agentVersionVO)); + for (Map fields : relatedFieldsVersionMap) { + // check if current command has unexpected versions + logger.debug("grayscale compare fields " + JSONObjectUtil.toJsonString(fields)); + VersionComparator currentVersion = new VersionComparator(agentVersionVO.getCurrentVersion()); + Set> entries = fields.entrySet() + .stream() + .filter(entry -> {//logger.debug(String.format("entry key: %s, value:%s", entry.getKey(), entry.getValue())); + String ver = entry.getValue(); + if (StringUtils.isEmpty(ver)) { + logger.warn("null version for field: " + entry.getKey()); + return false; + } + return currentVersion.lessThan(ver); + }) + .collect(Collectors.toSet()); + + // do not have new version changes + if (entries.isEmpty()) { + if (logger.isTraceEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("agent[uuid: %s] current version: %s\n", agentUuid, agentVersionVO.getCurrentVersion())); + fields.forEach((key, value) -> sb.append(String.format("field: %s, support version: %s\n", key, value))); + sb.append("all fields is supported by current agent, allow operations"); + logger.trace(sb.toString()); + } + continue; + } + + // check if field used in command + entries = entries.stream().filter(entry -> { + Object value = FieldUtils.getFieldValue(entry.getKey(), commandObj); + // not used return + if (value == null) { + logger.trace(String.format("Command obj do not use field %s, allow the usage", entry.getKey())); + return false; + } + + if (value instanceof Collection) { + if (((Collection) value).isEmpty()) { + logger.trace(String.format("Command obj use empty field %s, allow the usage", entry.getKey())); + return false; + } + } + + return true; + }).collect(Collectors.toSet()); + + if (entries.isEmpty()) { + if (logger.isTraceEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("agent[uuid: %s] current version: %s\n", agentUuid, agentVersionVO.getCurrentVersion())); + fields.forEach((key, value) -> sb.append(String.format("field: %s, support version: %s\n", key, value))); + sb.append("after check those fields' usage in command, allow operations"); + logger.trace(sb.toString()); + } + continue; + } + + StringBuilder sb = new StringBuilder(); + sb.append(String.format("This operation is not allowed on host[uuid:%s] during grayscale upgrade: \n", agentUuid)); + entries.forEach(entry -> sb.append(String.format("field: %s, current agent version %s, support version: %s\n", entry.getKey(), agentVersionVO.getCurrentVersion(), entry.getValue()))); + return operr(sb.toString()); + } + + return null; + } + + public void updateAgentVersion(String agentUuid, String agentType, String expectVersion, String currentVersion) { + if (!UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + return; + } + + AgentVersionVO agentVersionVO = dbf.findByUuid(agentUuid, AgentVersionVO.class); + if (agentVersionVO == null) { + agentVersionVO = new AgentVersionVO(); + agentVersionVO.setUuid(agentUuid); + agentVersionVO.setAgentType(agentType); + agentVersionVO.setCurrentVersion(currentVersion); + agentVersionVO.setExpectVersion(expectVersion); + dbf.persist(agentVersionVO); + logger.trace(String.format("Create agent[uuid: %s] version\n" + + "From:\n" + + "expected version: null, current version: null\n" + + "To:\n" + + "expected version: %s, current version: %s\n", + agentUuid, + agentVersionVO.getExpectVersion(), agentVersionVO.getCurrentVersion())); + return; + } + + if (currentVersion == null) { + logger.trace(String.format("Update agent[uuid: %s] version to null is not supported, skip updating", agentUuid)); + return; + } + + if (Objects.equals(agentVersionVO.getExpectVersion(), agentVersionVO.getCurrentVersion())) { + logger.trace(String.format("Agent[uuid: %s] version expected version: %s, current version: %s, not changed", agentUuid, agentVersionVO.getExpectVersion(), agentVersionVO.getCurrentVersion())); + return; + } + + if (!Objects.equals(agentVersionVO.getCurrentVersion(), currentVersion)) { + String originCurrentVersion = agentVersionVO.getCurrentVersion(); + agentVersionVO.setCurrentVersion(currentVersion); + logger.trace(String.format("Update agent[uuid: %s] version\n" + + "From:\n" + + "expected version: %s, current version: %s\n" + + "To:\n" + + "expected version: %s, current version: %s\n", + agentUuid, + agentVersionVO.getExpectVersion(), originCurrentVersion, + agentVersionVO.getExpectVersion(), agentVersionVO.getCurrentVersion())); + dbf.update(agentVersionVO); + } + } + + /** + * check weather need to skip agent deployment or other initialize operation on current agent + * + * During agent ping, agent version will be recorded as a metadata and combine with agent + * cmd param version checking if its using new params could be checked to avoid incompatible + * operations. + * + * But some early versions cloud do not prepared agent version in db record which should wait + * for the first ping to take back the result. So this method is used to avoid unexpected agent + * deployment or init is triggered during (the version initializing). So if an agent do not + * have agent version or version mismatched will be avoided to do the upgrade until a manual + * api is used to upgrade the agent. + * + * @param agentUuid the uuid of used agent + * @return true means skip the operations + */ + public boolean skipInnerDeployOrInitOnCurrentAgent(String agentUuid) { + if (!UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + return false; + } + + AgentVersionVO agentVersionVO = dbf.findByUuid(agentUuid, AgentVersionVO.class); + if (agentVersionVO == null) { + return true; + } + + return !agentVersionVO.getExpectVersion().equals(agentVersionVO.getCurrentVersion()); + } + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIUpdateClusterOSMsg) { + validate((APIUpdateClusterOSMsg) msg); + } + + return msg; + } + + private void validate(APIUpdateClusterOSMsg msg) { + if (!UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + return; + } + + if (msg.getHostUuid() == null) { + throw new ApiMessageInterceptionException( + argerr("Disable grayscale upgrade by %s \n before you want to update whole cluster's hosts' os." + + " Or try update cluster os with specific hostUuid instead.", UpgradeGlobalConfig.GRAYSCALE_UPGRADE.toString()) + ); + } + + AgentVersionVO agent = Q.New(AgentVersionVO.class) + .eq(AgentVersionVO_.uuid, msg.getHostUuid()) + .find(); + + if (agent == null) { + throw new ApiMessageInterceptionException( + argerr("Can not found agent version, upgrade cluster os is not supported during grayscale upgrade") + ); + } + + if (agent.getCurrentVersion().equals(agent.getExpectVersion())) { + return; + } + + throw new ApiMessageInterceptionException( + argerr("Host[uuid: %s] agent version is not upgraded, please reconnect host before update os", msg.getHostUuid()) + ); + } + + @Override + public List getMessageClassToIntercept() { + return Arrays.asList(APIUpdateClusterOSMsg.class); + } +} diff --git a/core/src/main/java/org/zstack/core/upgrade/UpgradeGlobalConfig.java b/core/src/main/java/org/zstack/core/upgrade/UpgradeGlobalConfig.java new file mode 100644 index 00000000000..13325cd42c6 --- /dev/null +++ b/core/src/main/java/org/zstack/core/upgrade/UpgradeGlobalConfig.java @@ -0,0 +1,16 @@ +package org.zstack.core.upgrade; + +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDefinition; +import org.zstack.core.config.GlobalConfigValidation; + +@GlobalConfigDefinition +public class UpgradeGlobalConfig { + public static final String CATEGORY = "upgradeControl"; + + @GlobalConfigValidation + public static GlobalConfig GRAYSCALE_UPGRADE = new GlobalConfig(CATEGORY, "grayscaleUpgrade"); + + @GlobalConfigValidation + public static GlobalConfig ALLOWED_API_LIST_GRAYSCALE_UPGRADING = new GlobalConfig(CATEGORY, "allowedApiListGrayscaleUpgrading"); +} diff --git a/core/src/main/java/org/zstack/core/workflow/SimpleFlowChain.java b/core/src/main/java/org/zstack/core/workflow/SimpleFlowChain.java index d4b0b86069a..73ab3cfdd32 100755 --- a/core/src/main/java/org/zstack/core/workflow/SimpleFlowChain.java +++ b/core/src/main/java/org/zstack/core/workflow/SimpleFlowChain.java @@ -39,7 +39,8 @@ public class SimpleFlowChain implements FlowTrigger, FlowRollback, FlowChain, Fl private String id; private List flows = new ArrayList<>(); - private Stack rollBackFlows = new Stack<>(); + private final Stack rollBackFlows = new Stack<>(); + private final List skippedFlows = new ArrayList<>(); private Map data = new HashMap(); private int currentLoop = 0; private Iterator it; @@ -48,12 +49,14 @@ public class SimpleFlowChain implements FlowTrigger, FlowRollback, FlowChain, Fl private Flow currentFlow; private Flow currentRollbackFlow; private ErrorCode errorCode; + private FlowContextHandler contextHandler; private FlowErrorHandler errorHandler; private FlowDoneHandler doneHandler; private FlowFinallyHandler finallyHandler; private String name; private boolean skipRestRollbacks; private boolean allowEmptyFlow; + private boolean enableDebugLog = true; private FlowMarshaller flowMarshaller; private List processors; private java.util.function.Function preCheck; @@ -75,7 +78,7 @@ void start(Flow flow) { WorkFlowStatistic stat = statistics.get(cname); stat.addStatistic(btime - stime); - logger.debug(String.format("[FlowChain(%s):%s, flow:%s] takes %sms to complete", + printDebugLog(String.format("[FlowChain(%s):%s, flow:%s] takes %sms to complete", id, name, cname, stat.getTotalTime())); } @@ -109,6 +112,10 @@ public void allowWatch() { } } + public void disableDebugLog() { + this.enableDebugLog = false; + } + { if (CoreGlobalProperty.PROFILER_WORKFLOW) { stopWatch = new FlowStopWatch(); @@ -210,6 +217,12 @@ public SimpleFlowChain then(Flow flow) { return this; } + public SimpleFlowChain ctxHandler(FlowContextHandler handler) { + DebugUtils.Assert(contextHandler==null, "there has been an FlowContextHandler installed"); + contextHandler = handler; + return this; + } + public SimpleFlowChain error(FlowErrorHandler handler) { DebugUtils.Assert(errorHandler==null, "there has been an FlowErrorHandler installed"); errorHandler = handler; @@ -291,6 +304,12 @@ private void collectAfterRunnable(Flow flow) { } } + private void printDebugLog(String msg) { + if (enableDebugLog) { + logger.debug(msg); + } + } + private void runFlow(Flow flow) { try { if (TransactionSynchronizationManager.isActualTransactionActive()) { @@ -309,7 +328,7 @@ private void runFlow(Flow flow) { toRun = flowMarshaller.marshalTheNextFlow(currentFlow == null ? null : currentFlow.getClass().getName(), flow.getClass().getName(), this, data); if (toRun != null) { - logger.debug(String.format("[FlowChain(%s): %s] FlowMarshaller[%s] replaces the next flow[%s] to the flow[%s]", + printDebugLog(String.format("[FlowChain(%s): %s] FlowMarshaller[%s] replaces the next flow[%s] to the flow[%s]", id, name, flowMarshaller.getClass(), flow.getClass(), toRun.getClass())); } } @@ -326,11 +345,13 @@ private void runFlow(Flow flow) { String flowName = getFlowName(currentFlow); String info = String.format("[FlowChain(%s): %s] start executing flow[%s]", id, name, flowName); - logger.debug(info); + printDebugLog(info); + collectAfterRunnable(toRun); if (preCheck != null) { - logger.debug(String.format("[FlowChain(%s): %s] start executing pre-check for flow[%s]", id, name, flowName)); + printDebugLog(String.format("[FlowChain(%s): %s] start executing pre-check for flow[%s]", id, name, flowName)); + ErrorCode err = preCheck.apply(data); if (err != null) { this.fail(err); @@ -339,8 +360,17 @@ private void runFlow(Flow flow) { } if (isSkipFlow(toRun)) { + printDebugLog(String.format("[FlowChain(%s): %s] skip flow[%s] because it's skip() returns true", id, name, flowName)); + skippedFlows.add(toRun); this.next(); } else { + if (contextHandler != null) { + contextHandler.saveContext(toRun); + if (contextHandler.cancelled()) { + this.fail(contextHandler.getCancelError()); + return; + } + } toRun.run(this, data); } } catch (OperationFailureException oe) { @@ -361,9 +391,25 @@ private void runFlow(Flow flow) { private void rollbackFlow(Flow flow) { try { - logger.debug(String.format("[FlowChain(%s): %s] start to rollback flow[%s]", id, name, getFlowName(flow))); + printDebugLog(String.format("[FlowChain(%s): %s] start to rollback flow[%s]", id, name, getFlowName(flow))); + currentLoop --; - flow.rollback(this, data); + + if (contextHandler != null) { + if (contextHandler.skipRollback(this.getErrorCode())) { + this.skipRestRollbacks(); + this.rollback(); + return; + } + } + + + if (skippedFlows.contains(flow)) { + printDebugLog(String.format("[FlowChain(%s): %s] skip rollback flow[%s] because it's skip() returns true", id, name, getFlowName(flow))); + rollback(); + } else { + flow.rollback(this, data); + } } catch (Throwable t) { logger.warn(String.format("unhandled exception when rollback, call backtrace %s", DebugUtils.getStackTrace(t))); logger.warn(String.format("[FlowChain(%s): %s] unhandled exception when rollback flow[%s]," + @@ -374,7 +420,7 @@ private void rollbackFlow(Flow flow) { private void callErrorHandler(boolean info) { if (info) { - logger.debug(String.format("[FlowChain(%s): %s] rolled back all flows because error%s", id, name, errorCode)); + printDebugLog(String.format("[FlowChain(%s): %s] rolled back all flows because error%s", id, name, errorCode)); } if (errorHandler != null) { @@ -392,7 +438,7 @@ private void callErrorHandler(boolean info) { CollectionUtils.safeForEach(errors, new ForEachFunction() { @Override public void run(Runnable arg) { - if (logger.isTraceEnabled()) { + if (logger.isTraceEnabled() && enableDebugLog) { logger.trace(String.format("call after error handler %s", arg.getClass())); } arg.run(); @@ -459,17 +505,17 @@ public String call(Flow arg) { } }); - logger.debug(String.format("[FlowChain(%s): %s] we are instructed to skip rollbacks for remaining flows%s", + printDebugLog(String.format("[FlowChain(%s): %s] we are instructed to skip rollbacks for remaining flows%s", id, name, restRollbackNames)); callErrorHandler(true); return; } if (currentRollbackFlow != null) { - logger.debug(String.format("[FlowChain(%s): %s] successfully rolled back flow[%s]", + printDebugLog(String.format("[FlowChain(%s): %s] successfully rolled back flow[%s]", id, name, getFlowName(currentRollbackFlow))); } else { - logger.debug(String.format("[FlowChain(%s): %s] start to rollback", id, name)); + printDebugLog(String.format("[FlowChain(%s): %s] start to rollback", id, name)); } Flow flow = rollBackFlows.pop(); @@ -508,7 +554,7 @@ private void callFinallyHandler() { CollectionUtils.safeForEach(finals, new ForEachFunction() { @Override public void run(Runnable arg) { - if (logger.isTraceEnabled()) { + if (logger.isTraceEnabled() && enableDebugLog) { logger.trace(String.format("call after final handler %s", arg.getClass())); } @@ -532,7 +578,7 @@ private void callDoneHandler() { } } - logger.debug(String.format("[FlowChain(%s): %s] successfully completed", id, name)); + printDebugLog(String.format("[FlowChain(%s): %s] successfully completed", id, name)); if (!afterDone.isEmpty()) { Collections.reverse(afterDone); @@ -541,7 +587,7 @@ private void callDoneHandler() { CollectionUtils.safeForEach(dones, new ForEachFunction() { @Override public void run(Runnable arg) { - if (logger.isTraceEnabled()) { + if (logger.isTraceEnabled() && enableDebugLog) { logger.trace(String.format("call after done handler %s", arg.getClass())); } arg.run(); @@ -563,8 +609,8 @@ public void fail(ErrorCode errorCode) { private boolean isSkipFlow(Flow flow) { boolean skip = flow.skip(data); - if (skip) { - logger.debug(String.format("[FlowChain: %s] skip flow[%s] because it's skip() returns true", name, getFlowName(flow))); + if (!skip && contextHandler != null) { + skip = contextHandler.skipFlow(flow); } return skip; } @@ -597,7 +643,8 @@ public void next() { rollBackFlows.push(currentFlow); - logger.debug(String.format("[FlowChain(%s): %s] successfully executed flow[%s]", id, name, getFlowName(currentFlow))); + printDebugLog(String.format("[FlowChain(%s): %s] successfully executed flow[%s]", + id, name, getFlowName(currentFlow))); runFlowOrComplete(); } @@ -628,9 +675,9 @@ public void start() { name = "anonymous-chain"; } - logger.debug(String.format("[FlowChain(%s): %s] starts", id, name)); + printDebugLog(String.format("[FlowChain(%s): %s] starts", id, name)); - if (logger.isTraceEnabled()) { + if (logger.isTraceEnabled() && enableDebugLog) { List names = CollectionUtils.transformToList(flows, new Function() { @Override public String call(Flow arg) { diff --git a/docs/antora.yml b/docs/antora.yml index f69829ddbae..6735cf19389 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -9,6 +9,7 @@ version: master nav: - modules/ROOT/nav.adoc - modules/core/nav.adoc +- modules/identity/nav.adoc - modules/network/nav.adoc - modules/longjob/nav.adoc - modules/test/nav.adoc \ No newline at end of file diff --git a/docs/modules/identity/nav.adoc b/docs/modules/identity/nav.adoc new file mode 100644 index 00000000000..8beb17754c7 --- /dev/null +++ b/docs/modules/identity/nav.adoc @@ -0,0 +1,2 @@ +* xref:index.adoc[] + ** xref:login.adoc[] diff --git a/docs/modules/identity/pages/index.adoc b/docs/modules/identity/pages/index.adoc new file mode 100644 index 00000000000..a42a4a5bc42 --- /dev/null +++ b/docs/modules/identity/pages/index.adoc @@ -0,0 +1,14 @@ += ZStack Cloud 权限认证模块:identity + +== 简介 + +[quote] +==== +本节内容主要对应 `identity` 目录 + +identy 目录内主要是 ZStack 项目的登录认证,权限控制代码,包括: + +* xref:login.adoc[] + +等等,具体可以阅读本节的文档以及代码。 +==== \ No newline at end of file diff --git a/docs/modules/identity/pages/login.adoc b/docs/modules/identity/pages/login.adoc new file mode 100644 index 00000000000..93a9b291f96 --- /dev/null +++ b/docs/modules/identity/pages/login.adoc @@ -0,0 +1,254 @@ +:toc: + += ZStack Cloud 权限认证模块:登录认证功能 + +ZStack作为基础软件,实际生产环境中碰到很多客户要求需要对接各种认证系统 + +为了解决认证接入过程碰到的问题,我们尝试提供了通用CAS,OAuth2的模块支持,但是依然没办法避免需要定制化开发的境遇。为了简化登录认证功能的接入,需要针对登录认证模块做一次代码重新设计,来解决目前碰到的问题。 + +== 需求总览 + +从需求上,登陆模块的架构设计,主要来源于如下五个需求点: + +[options="header",cols="1,2,2"] +|=== +| 编号 | 需求 | 解释 +| F1 | 提供标准接口开发登录认证功能 | 避免总是要重写一个新的API,实际上大部分接口只有认证步骤实现不同,登录用户等步骤都是相同的 +| F2 | 简化附加认证的接入方式 | 安全需求以及适配增多,附加认证等的接入入口不统一,不便于维护 +| F3 | 提升可配置性 | 对于标准的接入,比如oauth2,cas,提供标准的接入配置,修改配置立即可用 +| F4 | 降低开发难度 | 对于第三方用户的接入逻辑,提供标准的抽象,用来保存用户对应关系 +| F5 | 更多调试日志 | 增加更多trace日志,便于分析整个认证流程还有附加认证逻辑的运行情况 +| F6 | API使用方式不明确 | 增加接口获取登陆某个用户需要什么认证信息 | +|=== + +基于上面这些要求,软件质量上需要满足以下几点(重要性顺序): + +[options="header",cols="1,2,2"] +|=== +| 目标 | 具体需求 | 备注 +| 功能性 | 1. 针对标准协议提供标准接口/配置 + +2. 接入足够简单,比如实现一个Java接口或者改一下配置文件 + +3. 对接iam1/iam2的能力足够充分 | +| 可操作性 | 1. 针对dev或者是用户的要求,接口简单并提供文档,配置简化 | +| 可维护性 | 1. 针对异常情况,可以通过详细的调试日志找到问题原因 + +2. 选择附加认证的方式可灵活配置 | +|=== + +== 架构限制 + +架构的具体限制如下: + +1. 对接自研的登录逻辑,需要了解登录的代码抽象,实现用户的对应关系 +2. 针对第三方认证,如果使用附加认证逻辑,登录操作会变得很复杂,需要对各个附加认证的插件有了解 +3. 针对新增的API没有限制一定要使用这个框架,需要在Review的时候关注实现 + +== 业务场景 + +[plantuml,align=center] +.... +skinparam ranksep 20 +skinparam dpi 150 +skinparam arrowThickness 0.7 +skinparam packageTitleAlignment left +skinparam usecaseBorderThickness 0.4 +skinparam defaultFontSize 12 +skinparam rectangleBorderThickness 1 + +User --> (提供认证方式) +User --> (提供测试用户) +User --> (投入生产使用) +.... + +== 技术场景 + +[plantuml,align=center] +.... +skinparam ranksep 20 +skinparam dpi 150 +skinparam arrowThickness 0.7 +skinparam packageTitleAlignment left +skinparam usecaseBorderThickness 0.4 +skinparam defaultFontSize 12 +skinparam rectangleBorderThickness 1 + +Dev --> (根据通用认证接口实现新的认证逻辑) +Dev --> (修改spring配置,增加新的实现) +Dev --> (通过integration test登录认证测试用户) +.... + +== 设计思路 + +=== 通用的登录认证逻辑 + +[options="header",cols="1,2,2,2"] +|=== +| 目标 | 场景 | 解决方法 | 备注 +| 通用API | 提供标准参数 | 提供标准参数和概念,username,password,loginType,properties四个参数 | 用户名,密码,认证方式和配置项是我们要求的几个参数。其中用户名和密码实际上对应的是用户id和密文,针对认证都是需要输入的,同时为了API能够找到对应的需要使用的认证方式,还会要求指定对应的认证方式,如果需要传递额外参数,则使用properties传入 +| 通用内部抽象 | 增加额外的验证步骤,收集登录数据等 | 详细见 <> | +|=== + +整个 [#loginPhase]#登录流程# 被划分为四个阶段 + +- pre login phase: 前期认证阶段,在验证用户名密码之前如果需要做一些提前检查或者是统计数据等,在前期认证阶段处理。 + +- login phase: 认证阶段,实现对应的认证方法,比如校验用户名密码,使用API获取第三方认证结果等,并要求返回对应ZStack系统的用户信息。 + +- additional login phase: 附加认证阶段,实现对应的二次/附加认证逻辑,比如短信验证码,图片验证码等。 + +- login result process phase: 认证结果处理阶段,登录成功/失败后的处理逻辑,比如需要增加数据统计,包括增加登录过于频繁限制等等。 + +基于流程上的抽象,核心的接口设计如下: + +登录接口: + +[source,java] +---- +public interface LoginBackend { + LoginType getLoginType(); + + void login(LoginContext loginContext, ReturnValueCompletion completion); + + boolean authenticate(String username, String password); + + String getUserIdByName(String username); + + void collectUserInfoIntoContext(LoginContext loginContext); + + List getRequiredAdditionalAuthFeature(); +} +---- + +每个认证模块需要实现 `LoginBackend` 接口,包括指定认证类型,实现登录逻辑,提供用户名密码正确性校验,通过用户名获取用户id,以及指定需要启用的附加认证特性等。 + +其中 `LoginContext` 在整个登录认证流程中起到传递上下文的作用,负责转换信息以及适配各种通用附加认证逻辑。 + +拓展接口: + +[source,java] +---- +public interface LoginAuthExtensionPoint { + ErrorCode beforeExecuteLogin(LoginContext loginContext); + + ErrorCode postLogin(LoginContext loginContext, LoginSessionInfo info); + + void afterLoginSuccess(LoginContext loginContext, LoginSessionInfo info); + + void afterLoginFailure(LoginContext loginContext, LoginSessionInfo info, ErrorCode errorCode); + + AdditionalAuthFeature getAdditionalAuthFeature(); + + LoginAuthenticationProcedureDesc getAdditionalAuthDesc(LoginContext loginContext); +} +---- + +提供在登录认证生命周期中的各种hook + +并且要求提供一个`AdditionalAuthFeature`,来表示自己提供的是什么类型的认证特性,Backend通过设置对应的特性来决定这个登陆方式需要使用哪种拓展功能。 + +通过 `LoginAuthenticationProcedureDesc` 描述针对某个 `LoginContext` 需要什么认证方式,处于安全考虑,这个描述只根据功能是否启用来返回内容,避免通过API发起用户的枚举攻击。 + +这里面包含两个部分,分别是 `LoginContext` 的传递和 `LoginSessionInfo`。在登录认证后,会加入 `LoginSessionInfo` 用来表示用户在ZStack中对应的账户/用户信息,并作为最终session使用的依据。 + +note:: +单独提供一个 `LoginSessionInfo` 类型,并且用于session登录,是为了适用于认证后用户信息和登录参数不完全匹配的情况,比如共享账户,子账户等,发生变化的情况,在context中保留原始参数,info中保存实际结果。 + +== Building Block View + +从结构上,登录逻辑的构成如下图所示: + +[plantuml,align=center] +.... +skinparam ranksep 20 +skinparam dpi 150 +skinparam arrowThickness 0.7 +skinparam packageTitleAlignment left +skinparam usecaseBorderThickness 0.4 +skinparam defaultFontSize 12 +skinparam rectangleBorderThickness 1 + +component ZStack { + component LoginManagerImpl + component LoginBackend. + component LoginBackend.2 + component AdditionalAuthFeatures +} + +API - [LoginManagerImpl] +[LoginManagerImpl] ..> [LoginBackend.1] : find matched backend +[LoginBackend.1] <...> [AdditionalAuthFeatures] : negotiate additional auth features +[LoginBackend.1] ..> [Database] : login verification + +[LoginManagerImpl] ..> [LoginBackend.2] : find matched backend +[LoginBackend.2] <...> [AdditionalAuthFeatures] : negotiate additional auth features +[LoginBackend.2] ..> HTTP : login verification +.... + +== 运行时视角 + +对于几个核心的组件,做一个简单的介绍: + +`LoginManagerImpl` 是ZStack的服务,负责获取API消息,并组织整个登录流程 + +`LoginBackend` 每个登录API都会找到一个对应的LoginBackend的实现来进行登录 + +`AdditionalAuthFeatures` 每个LoginBackend会协商出自己适用的附加认证特性,并应用在登录流程里面 + +运行时功能工作的步骤主要如下: + +1. 用户发起登录认证API请求,请求通过 `CloudBus` 转送到 `LoginManagerImpl` +2. `LoginManagerImpl` 根据登录认证API要求的认证类型从内存中找到对应的 `LoginBackend` 对象 +3. 根据 `LoginBackend` 对象提供的 `AdditionalAuthFeatures` 信息,匹配到对应的提供 `AdditionalAuthFeatures` 的 `LoginAuthExtensionPoint` 实现 +4. 根据收集到的 `LoginAuthExtensionPoint` 和 `LoginBackend` 按照几个阶段执行,参考 <> + +== 部署视角 + +这一节,主要针对新增登录认证方式做一下介绍 + +1. 针对开发完毕的代码,编译出对应的jar包,需要import core和header两个依赖。 +2. 配置pom.xml,包括aspectj的编译等等 +3. 将编译好的bean包放到ZStack环境里 +4. 修改spring配置,增加新的bean依赖 +5. 启动管理节点并测试 + +== 通用设计概念 + +1. 模型,使用了分层模型,针对不同的登录方式做了分层,整体的登录流程使用统一的抽象 +2. 支持插件式开发,增加新的登录类型就能拓展 +3. 无缝升级,对旧的逻辑做了兼容,实现了对应的backend,并且API参数上也做了兼容 +4. 多管理节点下使用问题,认证逻辑不受多MN限制,具体问题取决于backend自己的实现以及backend的具体依赖(比如backend使用的认证方式需要和单个节点绑定,那么需要注意多管理节点的配置问题) +5. 数据面的改动,无,主要是控制面模型的设计和拓展 +6. 故障模型,登录的主要流程都有对应的抽象,其任意错误都会返回统一的登录失败以及详细原因,根据原因进行对应的处理即可 +7. 批量操作的场景,无,单个登录API调用 +8. API兼容性,新增的API可以适配所有登录backend,旧的API使用内部消息登录兼容 +9. 新增API所有用户都可以使用,因为是登录API所以没有过多限制 +10. 易用性,这是测试的指标,针对这部分,主要困难在部署部分,需要做更多简化 +11. 是否产生额外资源: 暂时没有,不允许保存用户关联关系 +12. 大规模,大并发,登录API因为是同步消息,所以如果接入的认证卡住了,会影响管理节点的同步消息调用,需要设置一个很短的超时 +13. 最少的外部依赖,暂时没有外部依赖 +14. 功能架构的兼容性,目前抽象的模型和流程里面保留了最简单的几个逻辑,如果需要修改或者升级,在保留已有流程的情况下是没有什么影响的 +15. 运维点:登录失败的时候如何分析问题,不过因为是第三方开发部署,所以开发插件的时候如果提供详细的报错,那么就能够知道是啥问题了 +16. 没有新资源加入全局搜索 + +== 重要架构决定 + +== 质量要求 + +== 技术风险/债务 + +[options="header",cols="1,2,2"] +|=== +| 编号 | 风险 | 解释 +| R1 | 已有的基于ZStack开发的登陆接口 | 如果是非ZStack开发的登陆接口,会出现附加认证不可用的情况,需要更换为新接口 +| R2 | Bad 2-Step verification | 目前的2-Step实现上并不是先通过登陆获取一个非用户session的方式进行下一步操作,而是接口上必须要总是附带用户名密码,使用上需要单独了解,暂时没有抽象到统一登陆流程里 +|=== + +== 术语表 + +[options="header",cols="1,2,2"] +|=== +| 编号 | 术语 | 解释 +| T1 | loginType | 登陆/认证类型,常见的是Account/IAM2 +| T2 | username | 用户名,用户登陆的唯一标识,对使用者来说可以用任意字符串作为用户名,可以识别唯一用户即可 +| T3 | password | 密码,用户登录的验证标识,对开发者来说可以用任意字符串作为密码,可以识别唯一用户即可 +| T4 | properties | 属性,用户登录的额外参数 +|=== diff --git a/docs/modules/network/images/l2/createNoVlan.png b/docs/modules/network/images/l2/createNoVlan.png new file mode 100644 index 00000000000..3b7ab71fd10 Binary files /dev/null and b/docs/modules/network/images/l2/createNoVlan.png differ diff --git a/docs/modules/network/images/l2/createVlanNetwork.jpg b/docs/modules/network/images/l2/createVlanNetwork.jpg new file mode 100644 index 00000000000..d6423343f4d Binary files /dev/null and b/docs/modules/network/images/l2/createVlanNetwork.jpg differ diff --git a/docs/modules/network/images/l2/createVxlanNetwork.png b/docs/modules/network/images/l2/createVxlanNetwork.png new file mode 100644 index 00000000000..9fdb667567f Binary files /dev/null and b/docs/modules/network/images/l2/createVxlanNetwork.png differ diff --git a/docs/modules/network/images/l2/createVxlanPool.png b/docs/modules/network/images/l2/createVxlanPool.png new file mode 100644 index 00000000000..ecc4b12a127 Binary files /dev/null and b/docs/modules/network/images/l2/createVxlanPool.png differ diff --git a/docs/modules/network/images/l2/l2NetworkImpl.svg b/docs/modules/network/images/l2/l2NetworkImpl.svg new file mode 100644 index 00000000000..d4f8c1f5738 --- /dev/null +++ b/docs/modules/network/images/l2/l2NetworkImpl.svg @@ -0,0 +1 @@ +
L2Network
L2Network
L2NoVlanNetworkL2NetworkVO selfhandle(final CheckL2NetworkOnHostMsg msg)
L2NetworkRealizationExtensionPoint
L2NetworkRealizationExtensionPoint
KVMRealizeL2VlanNetworkBackend+ field: typevoid realize()void delete()void check()KVMRealizeL2NoVlanNetworkBackend+ field: typevoid realize()void check()L2NetworkManagerImpl+ l2NetworkFactoriesL2NoVlanL2NetworkFactoryL2_NO_VLAN_NETWORK_TYPEcreateL2Network
1
1
L2VlanNetworkFactoryL2_VLAN_NETWORK_TYPEcreateL2Network
1
1
L2NetworkFactory
L2NetworkFactory
VxlanNetworkFactoryVXLAN_NETWORK_TYPEcreateL2Network
1
1
L2VlanNetworkL2NetworkVO selfhandle(final CheckL2NetworkOnHostMsg msg)VxlanNetworkL2NetworkVO selfhandle(final CheckL2NetworkOnHostMsg msg)+ realizationExts+ method(type): typeKVMRealizeL2VxlanNetworkBackend+ field: typevoid realize()
1
1
1
1
1
1
void delete()void check()void delete()void prepareL2NetworkOnHostsvoid deleteL2Bridgevoid prepareL2NetworkOnHostsvoid deleteL2Bridgevoid prepareL2NetworkOnHostsvoid deleteL2Bridge
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/l2/noVlanDataPath.svg b/docs/modules/network/images/l2/noVlanDataPath.svg new file mode 100644 index 00000000000..9d5e6ef6c91 --- /dev/null +++ b/docs/modules/network/images/l2/noVlanDataPath.svg @@ -0,0 +1 @@ +
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
eth0.100
eth0.100
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
eth0.100
eth0.100
物理交换机
物理交换机
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/l2/vlanDataPath.svg b/docs/modules/network/images/l2/vlanDataPath.svg new file mode 100644 index 00000000000..4056b66a138 --- /dev/null +++ b/docs/modules/network/images/l2/vlanDataPath.svg @@ -0,0 +1 @@ +
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
eth0
eth0
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
eth0
eth0
物理交换机
物理交换机
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/l2/vxLanDataPath.svg b/docs/modules/network/images/l2/vxLanDataPath.svg new file mode 100644 index 00000000000..8e1edf275ae --- /dev/null +++ b/docs/modules/network/images/l2/vxLanDataPath.svg @@ -0,0 +1 @@ +
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
VXLAN 100
VXLAN 100
物理交换机
物理交换机
eth0
eth0
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
VXLAN 100
VXLAN 100
eth0
eth0
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/l3/createL3Network.png b/docs/modules/network/images/l3/createL3Network.png new file mode 100644 index 00000000000..563d6c5c764 Binary files /dev/null and b/docs/modules/network/images/l3/createL3Network.png differ diff --git a/docs/modules/network/images/l3/ipAddressPool.png b/docs/modules/network/images/l3/ipAddressPool.png new file mode 100644 index 00000000000..c9ef7891036 Binary files /dev/null and b/docs/modules/network/images/l3/ipAddressPool.png differ diff --git a/docs/modules/network/images/l3/publicDataPath.svg b/docs/modules/network/images/l3/publicDataPath.svg new file mode 100644 index 00000000000..de6a073a1f4 --- /dev/null +++ b/docs/modules/network/images/l3/publicDataPath.svg @@ -0,0 +1 @@ +
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
eth0
eth0
物理交换机
物理交换机
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/l3/vpcDataPath.svg b/docs/modules/network/images/l3/vpcDataPath.svg new file mode 100644 index 00000000000..8b895fe72df --- /dev/null +++ b/docs/modules/network/images/l3/vpcDataPath.svg @@ -0,0 +1 @@ +
物理服务器
物理服务器
虚拟交换机
虚拟交换机
云主机
云主机
eth0
eth0
物理服务器
物理服务器
虚拟交换机
虚拟交换机
VPC
VPC
eth0
eth0
物理交换机
物理交换机
虚拟交换机
虚拟交换机
eth1
eth1
物理路由器
物理路由器
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/networkService/flatDhcp/arch.svg b/docs/modules/network/images/networkService/flatDhcp/arch.svg new file mode 100644 index 00000000000..ba5e5933fd8 --- /dev/null +++ b/docs/modules/network/images/networkService/flatDhcp/arch.svg @@ -0,0 +1 @@ +
云主机
云主机
namespace
namespace
DHCP server运行在namespace里面
DHCP server运行在namespace里面
物理口上通过ebtables/iptables规则保证
1. 本地的DHCP报不会发到物理机网络
2. 物理机网络的DHCP也不会进入到namespace
物理口上通过ebtables/iptables规则保证...
每个二层网络都有一个bridge
每个二层网络都有一个bridge
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/networkService/lb/lb framework.svg b/docs/modules/network/images/networkService/lb/lb framework.svg new file mode 100644 index 00000000000..9608f4f7ff5 --- /dev/null +++ b/docs/modules/network/images/networkService/lb/lb framework.svg @@ -0,0 +1 @@ +
request
request
client
client
ZStack LB
ZStack LB
response
response
client IP  ----> LB VIP
client IP  ----> LB V...
client IP  <---- LB VIP
client IP  <---- LB V...
Backend Server
Backend Server
request
request
response
response
LB Backend IP  ----> Server IP
LB Backend IP  ----> Server...
LB Backend IP  <---- Server IP
LB Backend IP  <---- Server...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/networkService/networkTotal.svg b/docs/modules/network/images/networkService/networkTotal.svg new file mode 100644 index 00000000000..21152c78359 --- /dev/null +++ b/docs/modules/network/images/networkService/networkTotal.svg @@ -0,0 +1 @@ +
二层网络
二层网络
三层网络
三层网络
DHCP
DHCP
UserData
UserData
DNS
DNS
弹性IP
弹性IP
SNAT
SNAT
网络资源
网络资源
Hardware VXLAN
Hardware VXLAN
VXLAN
VXLAN
公有网络
公有网络
扁平网络
扁平网络
VPC网络
VPC网络
网络服务
网络服务
Flat
Flat
Security Group
Security Group
vrouter
vrouter
安全组
安全组
弹性IP
弹性IP
端口转发
端口转发
IPSec隧道
IPSec隧道
负载均衡
负载均衡
防火墙
防火墙
路由表
路由表
OSPF
OSPF
组播路由
组播路由
组播路由
组播路由
VipQos
VipQos
VipQos
VipQos
所有三层网络
所有三层网络
所有三层网络
所有三层网络
扁平网络
扁平网络
VPC网络
VPC网络
主机路由表
主机路由表
DNS
DNS
VPC路由器
VPC路由器
NOVLAN
NOVLAN
VLAN
VLAN
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/modules/network/images/vpc/createVpc.png b/docs/modules/network/images/vpc/createVpc.png new file mode 100644 index 00000000000..4a87b840ff8 Binary files /dev/null and b/docs/modules/network/images/vpc/createVpc.png differ diff --git a/docs/modules/network/images/vpc/vpc router.png b/docs/modules/network/images/vpc/vpc router.png new file mode 100644 index 00000000000..31793768199 Binary files /dev/null and b/docs/modules/network/images/vpc/vpc router.png differ diff --git a/docs/modules/network/images/vpc/vpcha.png b/docs/modules/network/images/vpc/vpcha.png new file mode 100644 index 00000000000..d6ddffed418 Binary files /dev/null and b/docs/modules/network/images/vpc/vpcha.png differ diff --git a/docs/modules/network/images/vpc/vrOffering.png b/docs/modules/network/images/vpc/vrOffering.png new file mode 100644 index 00000000000..a45268e4390 Binary files /dev/null and b/docs/modules/network/images/vpc/vrOffering.png differ diff --git a/docs/modules/network/nav.adoc b/docs/modules/network/nav.adoc index e69de29bb2d..53e42d44f22 100644 --- a/docs/modules/network/nav.adoc +++ b/docs/modules/network/nav.adoc @@ -0,0 +1,6 @@ +* xref:index.adoc[] + ** xref:networkResource/networkResource.adoc[] + *** xref:networkResource/L2Network.adoc[] + *** xref:networkResource/L3Network.adoc[] + *** xref:networkResource/VpcRouter.adoc[] + ** xref:networkService/networkService.adoc[] \ No newline at end of file diff --git a/docs/modules/network/pages/index.adoc b/docs/modules/network/pages/index.adoc new file mode 100644 index 00000000000..35c2d7922e2 --- /dev/null +++ b/docs/modules/network/pages/index.adoc @@ -0,0 +1,3 @@ += ZStack 网络 + +网络是ZStack云平台的基础组件。ZStack网络包括两个方面:网络资源,网络服务。 diff --git a/docs/modules/network/pages/networkResource/L2Network.adoc b/docs/modules/network/pages/networkResource/L2Network.adoc new file mode 100644 index 00000000000..92e354cbd78 --- /dev/null +++ b/docs/modules/network/pages/networkResource/L2Network.adoc @@ -0,0 +1,59 @@ += 二层网络 + +目前支持的网络类型有: NoVlan网络, Vlan网络,VxLan网络,硬件VxLan网络 + + +[NOTE] +NoVlan网络和Vlan网络,有两种虚拟交换机类型,默认类型是Linux bridge. OVS DPDK在高性能网络章节介绍 + + +== NoVlan网络 +创建NoVan网络需要指定网卡名称。集群内的物理机必须使用相同的网卡名称。 + +image::l2/createNoVlan.png[] + +NoVlan网络的云主机数据路径如下所示: + +image::l2/noVlanDataPath.svg[] +如图所示,云主机的流量经过虚拟接口到达物理服务器,虚拟交换机不加VLAN标签,然后经过eth0发送出去。 + +== Vlan网络 + +创建VLAN网络需要指定VlanID和网卡名称。 + +image::l2/createVlanNetwork.jpg[] + +Vlan网络的云主机数据路径如下所示: + +image::l2/vlanDataPath.svg[] +如图所示,云主机的流量经过虚拟接口到达物理服务器,虚拟交换机给流量打上打上VLAN标签,然后经过eth0发送出去。 + +== VxLan Pool + +VxLan Pool定义一组VxLan网络的公共属性: + +* 使用的vni范围 +* VTEP CIDR. ZStack云平台会根据VTEP CIDR 在物理机机上选择匹配这个CIDR的网卡地址作为VxLan网络的VTEP地址 + +image::l2/createVxlanPool.png[] +[NOTE] +SDN类型默认情况是软件, 也就是VxLAN的封装,解封装由物理机服务器完成。 +SDN类型类型为硬件,请参考对接ZStack对接SDN控制器章节。 + + +== VxLan网络 + +VxLan可以带来很多Vlan网络不具备的优势: + +* 解决Vlan网络数量不足的局限性,满足大数据中心的多租户的隔离需求。 +* 解决在数据中心创建大二层网络的需求,方便云主机可以在数据中心灵活部署,迁移。 + +创建VxLan网络必须选择一个VxLan Pool, 而且必须是SDN类型为软件的VxLan Pool. + +image::l2/createVxlanNetwork.png[] + +VxLan网络的云主机数据路径如下所示: + +image::l2/vxLanDataPath.svg[] + +如图所示,根据VxLanPool选择eth0作为VxLan网络的VTEP地址,然后创建VXLAN100的子接口,然后把这个子接口和云主机的虚拟后加入同一个虚拟交换机 \ No newline at end of file diff --git a/docs/modules/network/pages/networkResource/L2NetworkImpl.adoc b/docs/modules/network/pages/networkResource/L2NetworkImpl.adoc new file mode 100644 index 00000000000..8bb55c8f23b --- /dev/null +++ b/docs/modules/network/pages/networkResource/L2NetworkImpl.adoc @@ -0,0 +1,282 @@ += 二层网络的实现 + +== 概述 + +二层网络代码入口在 `L2NetworkManagerImpl`,继承了 `AbstractService`,向ZStack CloudBus模块注册一个模块 `network.l2`. +所以二层网络的处理消息会发给 `L2NetworkManagerImpl` +[source,java] +---- +/* 注册模块: network.l2 */ +@Override +public String getId() { + return bus.makeLocalServiceId(L2NetworkConstant.SERVICE_ID); +} + +@Override +public boolean start() { + populateExtensions(); + return true; +} +---- + +如上所示,`L2NetworkManagerImpl` 还是实现了 `start` 方法,在ZStack管理节点启动时候,进行一些初始化操作。 +在这个方法里面,通过类扫描,初始化了两个Map, `l2NetworkFactories` 和 `realizationExts` +[source,java] +---- +private void populateExtensions() { + for (L2NetworkFactory f : pluginRgty.getExtensionList(L2NetworkFactory.class)) { + L2NetworkFactory old = l2NetworkFactories.get(f.getType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate L2NetworkFactory[%s, %s] for type[%s]", + f.getClass().getName(), old.getClass().getName(), f.getType())); + } + l2NetworkFactories.put(f.getType().toString(), f); + } + + for (L2NetworkRealizationExtensionPoint extp : pluginRgty.getExtensionList(L2NetworkRealizationExtensionPoint.class)) { + Map map = realizationExts.get(extp.getSupportedL2NetworkType()); + if (map == null) { + map = new HashMap(1); + realizationExts.put(extp.getSupportedL2NetworkType(), map); + } + map.put(extp.getSupportedHypervisorType(), extp); + } +---- + +`l2NetworkFactories` 保存不同类型网络的 `L2NetworkFactory`。目前的网络有: NoVlan, Vlan, VxlanNetworkPool, VxlanNetwork等,每个类型的网络都有一个工厂类,实现创建二层网络。 +对比 `Openstack`, `l2NetworkFactories` 类似 `Neutron type driver`, 它将不同类型的配置信息保存到数据库。 + +`realizationExts` 保存不同类型网络在物理机上的实现方法: `L2NetworkRealizationExtensionPoint`。对比 `Openstack`,它类似与 `Neutron mech driver`. +每个 `L2NetworkRealizationExtensionPoint` 的类称为一个backend, 它有两个属性: 网络类型, 物理机hypervisor类型。`L2NetworkRealizationExtensionPoint` 主要包含了3个方法:check, realize, delete + +`Neutron ML2` 信息可参考 https://docs.openstack.org/neutron/pike/admin/config-ml2.html[ML2 plug-in] + +[source,java] +---- +public interface L2NetworkRealizationExtensionPoint { + void realize(L2NetworkInventory l2Network, String hostUuid, Completion completion); + void check(L2NetworkInventory l2Network, String hostUuid, Completion completion); + void delete(L2NetworkInventory l2Network, String hostUuid, Completion completion); +} +---- + +通过这两个接口类,可以添加新的网络类型,或者为已有网络类型添加新的实现方法。添加新的网络类型,必然需要增加新的 `L2NetworkRealizationExtensionPoint` + +以NoVlan,Vlan,VxLan为例,下图描述了它们之间的关系 + +image::l2/l2NetworkImpl.svg[] + + +== 创建二层网络 + +用户在UI创建二层网络的时候,`L2NetworkManagerImpl`会收到 `APICreateL2NetworkMsg` 消息,根据网络类型选择不同的工厂类,创建二层网络 + +如下创建二层网络的主要代码 +[source,java] +---- +private void handle(APICreateL2NetworkMsg msg) { + L2NetworkType type = L2NetworkType.valueOf(msg.getType()); + VSwitchType vSwitchType = VSwitchType.valueOf(msg.getvSwitchType()); + L2NetworkFactory factory = getL2NetworkFactory(type); + L2NetworkVO vo = new L2NetworkVO(); + if (msg.getResourceUuid() != null) { + vo.setUuid(msg.getResourceUuid()); + } else { + vo.setUuid(Platform.getUuid()); + } + vo.setDescription(msg.getDescription()); + vo.setName(msg.getName()); + vo.setPhysicalInterface(msg.getPhysicalInterface()); + vo.setType(type.toString()); + vo.setvSwitchType(vSwitchType.toString()); + vo.setZoneUuid(msg.getZoneUuid()); + vo.setAccountUuid(msg.getSession().getAccountUuid()); + factory.createL2Network(vo, msg, new ReturnValueCompletion(msg) { + @Override + public void success(L2NetworkInventory returnValue) { + tagMgr.createTagsFromAPICreateMessage(msg, returnValue.getUuid(), L2NetworkVO.class.getSimpleName()); + APICreateL2NetworkEvent evt = new APICreateL2NetworkEvent(msg.getId()); + evt.setInventory(returnValue); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + APICreateL2NetworkEvent evt = new APICreateL2NetworkEvent(msg.getId()); + evt.setError(errorCode); + bus.publish(evt); + } + }); + +} +---- + +以vlan类型的网络为例,创建二层网络,仅仅保存数据库就结束了。如果是对接硬件SDN, 请参考对接SDN章节。 +[source,java] +---- +@Override +public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + APICreateL2VlanNetworkMsg amsg = (APICreateL2VlanNetworkMsg) msg; + L2VlanNetworkVO vo = new L2VlanNetworkVO(ovo); + vo.setVlan(amsg.getVlan()); + vo = dbf.persistAndRefresh(vo); + L2VlanNetworkInventory inv = L2VlanNetworkInventory.valueOf(vo); + String info = String.format("successfully create L2VlanNetwork, %s", JSONObjectUtil.toJsonString(inv)); + logger.debug(info); + completion.success(inv); +} +---- + +== 二层网络加载集群 +创建二层网络以后,只有加载到集群,集群中的物理机才创建对应的二层网络。 + +二层网络加载集群, `L2NetworkManagerImpl` 会收到 `APIAttachL2NetworkToClusterMsg`。以为vlan网络加载到集群为例,主要业务逻辑如下 +主要有两个步骤: + +* 检查物理机上是否存储Vlan网络需要的接口名称 +* 在物理机上创建二层网络 + +[source,java] +---- +private void prepareL2NetworkOnHosts(final List hosts, final Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("prepare-l2-%s-on-hosts", self.getUuid())); + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + List cmsgs = new ArrayList(); + for (HostInventory h : hosts) { + CheckNetworkPhysicalInterfaceMsg cmsg = new CheckNetworkPhysicalInterfaceMsg(); + cmsg.setHostUuid(h.getUuid()); + cmsg.setPhysicalInterface(self.getPhysicalInterface()); + bus.makeTargetServiceIdByResourceUuid(cmsg, HostConstant.SERVICE_ID, h.getUuid()); + cmsgs.add(cmsg); + } + + if (cmsgs.isEmpty()) { + trigger.next(); + return; + } + + bus.send(cmsgs, new CloudBusListCallBack(trigger) { + @Override + public void run(List replies) { + for (MessageReply r : replies) { + if (!r.isSuccess()) { + trigger.fail(r.getError()); + return; + } + } + + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + private void realize(final Iterator it, final FlowTrigger trigger) { + if (!it.hasNext()) { + trigger.next(); + return; + } + + HostInventory host = it.next(); + realizeNetwork(host.getUuid(), host.getHypervisorType(), new Completion(trigger) { + @Override + public void success() { + realize(it, trigger); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + realize(hosts.iterator(), trigger); + } + }).then(new NoRollbackFlow() { + String __name__ = "after-l2-network-attached"; + + private void after(final Iterator it, final FlowTrigger trigger) { + if (!it.hasNext()) { + trigger.next(); + return; + } + + HostInventory host = it.next(); + afterAttachNetwork(host.getUuid(), host.getHypervisorType(), new Completion(trigger) { + @Override + public void success() { + after(it, trigger); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + after(hosts.iterator(), trigger); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } +---- + +在集群添加物理机的时候,集群中的二层网络也会加载到物理机上。 + +== 二层网络卸载集群 +二层网络加载集群, `L2NetworkManagerImpl` 会收到 `APIDetachL2NetworkFromClusterMsg`。以为vlan网络从集群卸载为例,主要业务逻辑如下 + +[source,java] +---- +private void deleteL2Bridge(List clusterUuids, Completion completion) { + List hosts = Q.New(HostVO.class) + .in(HostVO_.clusterUuid, clusterUuids) + .list(); + List errs = new ArrayList<>(); + new While<>(hosts).step((host,compl) -> { + HostInventory hostInv = HostInventory.valueOf(host); + L2NetworkInventory l2Inv = getSelfInventory(); + + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Inv, hostInv); + ext.delete(getSelfInventory(), host.getUuid(), new Completion(compl){ + @Override + public void success() { + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + errs.add(errorCode); + compl.done(); + } + + }); + },10).run((new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errs.size() > 0) { + logger.debug(String.format("delete bridge fail [error is %s ], but ignore", errs.get(0).toString())); + } + completion.success(); + + } + })); +} +---- diff --git a/docs/modules/network/pages/networkResource/L3Network.adoc b/docs/modules/network/pages/networkResource/L3Network.adoc new file mode 100644 index 00000000000..b0aa27869ab --- /dev/null +++ b/docs/modules/network/pages/networkResource/L3Network.adoc @@ -0,0 +1,75 @@ += 三层网络 + +目前支持的网络类型有: 公有网络, 扁平网络,VPC网络 + +[NOTE] +本章节只要是云主机的业务网络类型,其他网络类型:如迁移网络,管理网络等在相关章节介绍。 + +|=== +|网络类型 |应用场景 + +|公有网络 +|可以直接和数据中心外部互通的网络 + +|扁平网络 +|可以直接和数据中心物理网络互通的网络 + +|VPC网络 +|用来隔离租户云主机的网络,通过VPC路由器和数据中心外部互通 + +|=== + +== 创建三层网络 + +创建3层网络需要指定一个二层网络,然后配置IP地址段。ZStack支持IPv4和IPv6 + +* 三层网络如果配置IPv4地址段,就是一个IPV4网络 +* 三层网络如果配置IPv6地址段,就是一个IPV6网络 +* 三层网络如果配置IPv4地址段和IPv6地址段,就是一个双栈网络 + +image::l3/createL3Network.png[] + +[NOTE] +建议一个二层网络只创建一个三层网络,如果一个二层网络多个三层网络,且三层网络的cidr相同,会导致userdata服务,vm内部监控等功能不能正常工作。 + +== IP地址段 + +=== 普通IP地址段 +扁平网络和VPC网络,可以配置一个cidr, 或者多个IP地址段,但是要求多个地址段必须在一个cidr范围内。 + +=== 地址池地址段 +公有网络除了可以配置普通IP地址段,还可以配置地址池地址段。 +由很多网络服务(比如弹性IP,端口转发,负载均衡,IPSec)需要使用公网地址,因此,可能会出现公网地址耗尽的问题。 +为了解决这个问题,可以给公网分配额外的地址段。 + +image::l3/ipAddressPool.png[] + +[quote] +.使用地址还能带来节约IP地址的好处 +____ +假设创建一个新的公网把,IP地址池作为普通IP地址段,然后这个公网加载到VPC路由器,这样必然会占用如下地址: + +* 网关地址 +* 掩码地址 +* 网络地址 +* VPC的接口地址 +____ + +[NOTE] +地址池地址段的Cidr和普通地址段的Cidr不同,因此需要用户在物理路由器上解决路由问题。 + + +== 数据路径 + +公有网络和扁平网络一般都是使用NoVlan或者Vlan类型的二层网络创建的三层网络,它们的的数据路径类型如图所示,云主机的流量经过物理机网卡直接进入数据中心网络,进行路由转发。 + +image::l3/publicDataPath.svg[] + +VPC网络可以使用任意类型的二层网络创建,它的的数据路径类型如图所示,云主机的流量经过会先转发给VPC路由器,由VPC路由转发到公有网络 + +image::l3/vpcDataPath.svg[] + + + + + diff --git a/docs/modules/network/pages/networkResource/VpcRouter.adoc b/docs/modules/network/pages/networkResource/VpcRouter.adoc new file mode 100644 index 00000000000..a81b0eecd69 --- /dev/null +++ b/docs/modules/network/pages/networkResource/VpcRouter.adoc @@ -0,0 +1,48 @@ += VPC路由器 + +== 简介 +创建VPC的步骤: + +* 上传VPC镜像 +* 建立路由器规格 + +image::vpc/vrOffering.png[] +* 创建VPC路由器 + +image::vpc/createVpc.png[] + + +== 路由器规格 + +路由器规格指定VPC的公用参数:比如镜像文件,管理网络,公有网络,以及CPU,内存的规格。 + +CPU,内存的规格在创建VPC以后可以修改,生产环境建议大于4C8G. + +管理网络必须是可以和ZStack管理节点互通的网络,否则创建VPC会失败。 + +== VPC路由器信息 + +image::vpc/vpc router.png[] + +VPC是一个特殊类型的云主机,创建VPC以后,公有网络就是VPC的默认网络。 + +VPC可以添加多个公有网络,而且可以修改默认公网。 + +路由器规格中的管理网络,公有网络和VPC的默认公网是不能从VPC移除的 + +== VPC路由器的链接状态 + +管理节点定时发送心跳包到VPC路由器,如果心跳发送失败,VPC路由器就会自动重连,进入”_连接中_“状态, + +如果重连成功,进入”_已连接_“状态,否则进入“_失联_”状态。 + +== VPC高可用组 + +VPC路由器作为网络业务的一个核心节点,为了避免单点故障,VPC高可用组创建两台完全相同配置的两台VPC,通过KeepAlived, 选举其中一台为Master路由器。 +如果Master故障,Backup路由器能迅速切换到为Master路由器,快速恢复网络流量。 + +image::vpc/vpcha.png[] + +[NOTE] +VPC高可用组其他的应用场景。比如,当前VPC镜像版本太旧,可以先删除Backup路由器,使用新的镜像重新创建Backup路由器,在业务允许的时候,进行主备切换,然后使用相同的步骤升级另外一个路由器的镜像。 + diff --git a/docs/modules/network/pages/networkResource/networkResource.adoc b/docs/modules/network/pages/networkResource/networkResource.adoc new file mode 100644 index 00000000000..9aa66ce7341 --- /dev/null +++ b/docs/modules/network/pages/networkResource/networkResource.adoc @@ -0,0 +1,5 @@ += 网络资源 + +* xref:networkResource/L2Network.adoc[] +* xref:networkResource/L3Network.adoc[] +* xref:networkResource/VpcRouter.adoc[] \ No newline at end of file diff --git a/docs/modules/network/pages/networkService/flatDhcp.adoc b/docs/modules/network/pages/networkService/flatDhcp.adoc new file mode 100644 index 00000000000..21fdd6fa36c --- /dev/null +++ b/docs/modules/network/pages/networkService/flatDhcp.adoc @@ -0,0 +1,204 @@ += DHCP + +== 简介 + +DHCP服务的入口在 `DhcpExtension`, 它实现了接口 `NetworkServiceExtensionPoint` 中,包含了配置DHCP和删除DHCP的方法 +[source,java] +---- +public interface NetworkServiceExtensionPoint { + void applyNetworkService(VmInstanceSpec servedVm, Map data, Completion completion); + void releaseNetworkService(VmInstanceSpec servedVm, Map data, NoErrorCompletion completion); +} +---- +目前有两种: + +* Flat -- 分布式DHCP +* vrouter -- 集中式DHCP + +云主机使用哪种backend,取决于云主机网卡的三层网路配置 +[source,bash] +---- +admin >>>QueryL3Network uuid='e82f9446c3e34111b8b74cfcf70f4562' +{ + "inventories": [ + { + "category": "Private", + "createDate": "Aug 23, 2022 4:31:36 PM", + "hostRoute": [], + "ipRanges": [ + { + "createDate": "Aug 23, 2022 4:31:36 PM", + "endIp": "192.168.1.254", + "gateway": "192.168.1.1", + "ipVersion": 4, + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "lastOpDate": "Aug 23, 2022 4:31:36 PM", + "name": "192.168.1.0/24", + "netmask": "255.255.255.0", + "networkCidr": "192.168.1.0/24", + "prefixLen": 24, + "startIp": "192.168.1.2", + "uuid": "114691a225164a10904e8ac176cbdec1" + } + ], + "ipVersion": 4, + "l2NetworkUuid": "8fe67ed8517845b98b7715e31828710d", + "lastOpDate": "Aug 23, 2022 4:31:36 PM", + "name": "vx-2", + "networkServices": [ + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "LoadBalancer" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "CentralizedDNS" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "cb69890a791348009e1ec61d91de8ec3", + "networkServiceType": "DHCP" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "Eip" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "cb69890a791348009e1ec61d91de8ec3", + "networkServiceType": "Userdata" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "PortForwarding" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "SNAT" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "IPsec" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "VRouterRoute" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "a09b3ad773b24b34b7ac81a01a04df9b", + "networkServiceType": "VipQos" + }, + { + "l3NetworkUuid": "e82f9446c3e34111b8b74cfcf70f4562", + "networkServiceProviderUuid": "67bcc5c436a148a6a8d156aa7b1821eb", + "networkServiceType": "SecurityGroup" + } + ], + "state": "Enabled", + "system": false, + "type": "L3VpcNetwork", + "uuid": "e82f9446c3e34111b8b74cfcf70f4562", + "zoneUuid": "f3b1d4ee02b5497ab1bff0deb3764bca" + } + ], + "success": true +} +admin >>>QueryNetworkServiceProvider uuid=cb69890a791348009e1ec61d91de8ec3 +{ + "inventories": [ + { + "attachedL2NetworkUuids": [ + "6c84e4ebdf4e4d1bb119c46488a7cc90", + "ba7a2ac0f45d4d6a9a8da7c311ded9bb", + "2131fa08cc4e43d7b82899f64f788749", + "bbe2b8b0775246b0a6a7f52c6ee35cd6", + "bd733a753aa545f2b9b3119aaa30e969", + "8fe67ed8517845b98b7715e31828710d", + "9bd8ef54b3e541c994d95cb495326e26", + "7885fb46a0a847b5b88485c092026ad0" + ], + "createDate": "Aug 15, 2022 11:58:22 AM", + "description": "Flat Network Service Provider", + "lastOpDate": "Aug 15, 2022 11:58:22 AM", + "name": "Flat Network Service Provider", + "networkServiceTypes": [ + "VipQos", + "DNS", + "HostRoute", + "Userdata", + "Eip", + "DHCP" + ], + "type": "Flat", + "uuid": "cb69890a791348009e1ec61d91de8ec3" + } + ], + "success": true +} +---- + +可以看到这个网络DHCP使用Flat方式。这个配置是在创建L3网络的时候,通过 `APIAttachNetworkServiceToL3NetworkMsg` 添加的,也可以通过 `APIDetachNetworkServiceFromL3NetworkMsg` 删除。 + +云主机的启动流程中有一个Flow: `VmInstantiateResourcePreFlow`, 它的主要逻辑是:在vm启动之前,准备vm所需的服务,其中包含网络服务,因此DHCP后端的 `applyNetworkService` 被调用。 + +云主机的删除流程/停止流程中有一个Flow: `VmReleaseResourceFlow`, 它的主要逻辑是:在vm删除/停止之前,释放vm所需的服务,其中包含网络服务,因此DHCP后端的 `releaseNetworkService` 被调用。 + +== 分布式DHCP + +每个网络在每个物理机上都有一个dhcp server, 它只为当前这个物理机上的云主机提供DHCP服务。 + +物理机上结构如下: + +image::networkService/flatDhcp/arch.svg[] + +在物理机上为每个三层网路启动一个namespace, 且连接到三层网络的bridge,在namespsace中启动dnsmasq。云主机启动以后,发送DHCP请求,namespace中的dnsmasq +响应DHCP请求。在在每个物理机上都有相同的dnsmasq,为了避免彼此干扰,在bridge的物理口配置规则: + +[source,bash] +---- +# ebtables-save +# Generated by ebtables-save v1.0 on Wed Oct 12 17:15:53 CST 2022 +*filter +:INPUT ACCEPT +:FORWARD ACCEPT +:OUTPUT ACCEPT +:ZSTACK-192.168.1.161 ACCEPT +:USERDATA-br_vx_100-847284cd ACCEPT +-A FORWARD -j ZSTACK-192.168.1.161 +-A ZSTACK-192.168.1.161 -p IPv4 -i vxlan100 --ip-proto udp --ip-sport 67:68 -j DROP +-A ZSTACK-192.168.1.161 -p IPv4 -o vxlan100 --ip-proto udp --ip-sport 67:68 -j DROP +-A ZSTACK-192.168.1.161 -p ARP -i vxlan100 --arp-ip-src 192.168.1.161 -j DROP +-A ZSTACK-192.168.1.161 -p ARP -o vxlan100 --arp-ip-src 192.168.1.161 -j DROP +-A ZSTACK-192.168.1.161 -p ARP -i vxlan100 --arp-ip-dst 192.168.1.161 -j DROP +-A ZSTACK-192.168.1.161 -p ARP -o vxlan100 --arp-ip-dst 192.168.1.161 -j DROP +-A ZSTACK-192.168.1.161 -j RETURN +---- + +dnsmasq进程信息: + +[source,bash] +---- +# ps aux | grep dnsmasq +nobody 14074 0.0 0.0 6812 1540 ? S Sep29 0:00 /usr/local/zstack/dnsmasq --conf-file=/var/lib/zstack/dnsmasq/br_vx_100_847284cd3c1b44be9569ed03f670ea00/dnsmasq.conf -K +---- + +在物理机上,三层网络的第一个云主机启动之前,创建namespace, 启动dnsqmasq服务。当删除这个三层网络的时候,会删除这个namespace, 停止dnsmasq. + + + + + + + + + + + diff --git a/docs/modules/network/pages/networkService/lb.adoc b/docs/modules/network/pages/networkService/lb.adoc new file mode 100644 index 00000000000..639d9c94a04 --- /dev/null +++ b/docs/modules/network/pages/networkService/lb.adoc @@ -0,0 +1,2 @@ += 负载均衡 + diff --git a/docs/modules/network/pages/networkService/networkService.adoc b/docs/modules/network/pages/networkService/networkService.adoc new file mode 100644 index 00000000000..4d8239ceb62 --- /dev/null +++ b/docs/modules/network/pages/networkService/networkService.adoc @@ -0,0 +1,34 @@ += 网络服务 + +ZStack平台支持如下类型的网络服务: + +* 安全组 +* DHCP +* UserData +* 主机路由 +* CentralizedDNS +* SNAT +* 弹性IP +* 端口转发 +* IPSec +* VipQos +* 源进源出 +* 防火墙 +* 静态路由表 +* OSPF +* 组播 +* NetFlow +* 端口镜像 + +但是不同类型的网络支持默认的网络服务不同,他们直接的对应关系如图: + +image::networkService/networkTotal.svg[] + + +== 网络服务提供者(NetworkServiceProvider) + +ZStack平台是一个插件化平台,网络服务和网络服务的实现是分离,实现同一个网络服务根据配置,选择不同的实现方式。 + +比如扁平网络有弹性IP服务,VPC网路也有弹性IP服务。 + +用户可以通过cli修改三层网络的网络服务,但是不建议使用。 diff --git a/externalservice/pom.xml b/externalservice/pom.xml index 3037315e997..5059f579ce7 100755 --- a/externalservice/pom.xml +++ b/externalservice/pom.xml @@ -5,7 +5,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/externalservice/src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java b/externalservice/src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java index 69f0342848f..4bd6c1d7788 100755 --- a/externalservice/src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java +++ b/externalservice/src/main/java/org/zstack/externalservice/cronjob/CronJobImpl.java @@ -4,6 +4,8 @@ import org.apache.commons.lang.StringUtils; import org.zstack.core.Platform; import org.zstack.core.externalservice.AbstractLocalExternalService; +import org.zstack.header.core.external.service.ExternalServiceCapabilities; +import org.zstack.core.externalservice.ExternalServiceCapabilitiesBuilder; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.utils.Bash; @@ -17,6 +19,10 @@ import java.util.Set; public class CronJobImpl extends AbstractLocalExternalService implements CronJob { + ExternalServiceCapabilities capabilities = ExternalServiceCapabilitiesBuilder + .build() + .reloadConfig(true); + @Override protected String[] getCommandLineKeywords() { return new String[] {"crond", "-n"}; @@ -48,6 +54,27 @@ public boolean isAlive() { return getPID() != null; } + @Override + public ExternalServiceCapabilities getExternalServiceCapabilities() { + return capabilities; + } + + @Override + public void reload() { + if (!isAlive()) { + throw new OperationFailureException(operr("crond is not running")); + } + + new Bash() { + @Override + protected void scripts() { + setE(); + + run("service crond reload"); + } + }.execute(); + } + @Override public void addJob(String job) { if (!isAlive()) { diff --git a/header/pom.xml b/header/pom.xml index 53da48467e3..d31a8194b15 100755 --- a/header/pom.xml +++ b/header/pom.xml @@ -4,7 +4,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. header @@ -74,17 +74,39 @@ org.hibernate hibernate-search-orm + + org.apache.avro + avro + 1.11.4 + org.hibernate hibernate-search-serialization-avro + + + org.apache.avro + avro + + org.hibernate hibernate-search-backend-jgroups + + com.google.protobuf + protobuf-java + 3.21.9 + org.infinispan infinispan-directory-provider + + + com.google.protobuf + protobuf-java + + com.rabbitmq @@ -126,8 +148,9 @@ httpclient - org.reflections - reflections + org.zstack + abstraction + 5.4.0 diff --git a/header/src/main/java/org/zstack/header/APIIsOpensourceVersionMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/APIIsOpensourceVersionMsgDoc_zh_cn.groovy index 4f8e9af6ebc..a17314e835f 100755 --- a/header/src/main/java/org/zstack/header/APIIsOpensourceVersionMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/APIIsOpensourceVersionMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/Confirm.java b/header/src/main/java/org/zstack/header/Confirm.java new file mode 100644 index 00000000000..ae503815262 --- /dev/null +++ b/header/src/main/java/org/zstack/header/Confirm.java @@ -0,0 +1,5 @@ +package org.zstack.header; + +public enum Confirm { + Yes, No, Skip +} diff --git a/header/src/main/java/org/zstack/header/Constants.java b/header/src/main/java/org/zstack/header/Constants.java index c132492270d..071b394b900 100755 --- a/header/src/main/java/org/zstack/header/Constants.java +++ b/header/src/main/java/org/zstack/header/Constants.java @@ -16,4 +16,7 @@ public interface Constants { String CATEGORY_METADATA = "metadata"; String UUID_FOR_EXAMPLE = "UUID_FOR_EXAMPLE"; + + String MORPH_TRANSFORM_IAM1 = "IAM1"; + String MORPH_TRANSFORM_IAM2 = "IAM2"; } diff --git a/header/src/main/java/org/zstack/header/HasThreadContext.java b/header/src/main/java/org/zstack/header/HasThreadContext.java index 6721af354fd..60266115ef3 100755 --- a/header/src/main/java/org/zstack/header/HasThreadContext.java +++ b/header/src/main/java/org/zstack/header/HasThreadContext.java @@ -9,4 +9,8 @@ public interface HasThreadContext { default Map getThreadContext() { return null; } + + default Map getTaskContext() { + return null; + } } diff --git a/header/src/main/java/org/zstack/header/HasThreadContextAspect.aj b/header/src/main/java/org/zstack/header/HasThreadContextAspect.aj index 6f76da93f32..1a5b1c20ff9 100755 --- a/header/src/main/java/org/zstack/header/HasThreadContextAspect.aj +++ b/header/src/main/java/org/zstack/header/HasThreadContextAspect.aj @@ -17,9 +17,14 @@ public aspect HasThreadContextAspect { return context.threadContext; } + Map around(HasThreadContext context) : target(context) && execution(Map HasThreadContext+.getTaskContext()) { + return context.taskContext; + } + public static void setThreadContext(HasThreadContext obj) { obj.threadContext = ThreadContext.getContext(); obj.threadContextStack = ThreadContext.getImmutableStack().asList(); - obj.taskContext = TaskContext.getTaskContext(); + // store copy of context not ref + obj.taskContext = TaskContext.getTaskContext() != null ? new HashMap<>(TaskContext.getTaskContext()) : null; } } \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/PackageAPIInfo.java b/header/src/main/java/org/zstack/header/PackageAPIInfo.java index 1d6195bd304..00ab5f6db71 100755 --- a/header/src/main/java/org/zstack/header/PackageAPIInfo.java +++ b/header/src/main/java/org/zstack/header/PackageAPIInfo.java @@ -8,7 +8,28 @@ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface PackageAPIInfo { + public static String PERMISSION_COMMUNITY_AVAILABLE = "community_available"; + /** + * If an api is available in ZSV basic version, + * then the api is also available in ZSV advanced version. + * + * It contains {@link #PERMISSION_ZSV_ADVANCED_AVAILABLE} + */ + public static String PERMISSION_ZSV_BASIC_AVAILABLE = "zsv_basic_available"; + public static String PERMISSION_ZSV_ADVANCED_AVAILABLE = "zsv_advanced_available"; + public static String PERMISSION_CLOUD_AIOS_AVAILABLE = "cloud_aios_available"; + String APICategoryName() default ""; - boolean communityAvailable() default true; + + /** + * If a package with PackageAPIInfo annotation, default permissions of api which in this package is: + * 1. community_NOT_available (only premium API) + * 2. zsv_NOT_available + * + * If a package without PackageAPIInfo annotation, the permissions of api which in this package is: + * 1. community_available ({@link #PERMISSION_COMMUNITY_AVAILABLE}) + * 2. zsv_NOT_available + */ + String[] permissions() default {}; String productName() default ""; } diff --git a/header/src/main/java/org/zstack/header/allocator/APIGetCpuMemoryCapacityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/allocator/APIGetCpuMemoryCapacityMsgDoc_zh_cn.groovy index 8d8633a63c7..4b8b69cfc06 100644 --- a/header/src/main/java/org/zstack/header/allocator/APIGetCpuMemoryCapacityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/allocator/APIGetCpuMemoryCapacityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "clusterUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "hostUuids" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "all" @@ -59,7 +56,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "hypervisorType" diff --git a/header/src/main/java/org/zstack/header/allocator/APIGetHostAllocatorStrategiesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/allocator/APIGetHostAllocatorStrategiesMsgDoc_zh_cn.groovy index 3ad2cd98838..f54351a0a55 100644 --- a/header/src/main/java/org/zstack/header/allocator/APIGetHostAllocatorStrategiesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/allocator/APIGetHostAllocatorStrategiesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/allocator/AbstractHostAllocatorFlow.java b/header/src/main/java/org/zstack/header/allocator/AbstractHostAllocatorFlow.java index 1d27c73b122..2ed50c6131f 100755 --- a/header/src/main/java/org/zstack/header/allocator/AbstractHostAllocatorFlow.java +++ b/header/src/main/java/org/zstack/header/allocator/AbstractHostAllocatorFlow.java @@ -56,6 +56,10 @@ protected void next(List candidates) { trigger.next(candidates); } + protected void allocatorTriggerFail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + protected void skip() { trigger.skip(); } diff --git a/header/src/main/java/org/zstack/header/allocator/AllocateHostMsg.java b/header/src/main/java/org/zstack/header/allocator/AllocateHostMsg.java index 14a6b8b9f53..23869aa1327 100755 --- a/header/src/main/java/org/zstack/header/allocator/AllocateHostMsg.java +++ b/header/src/main/java/org/zstack/header/allocator/AllocateHostMsg.java @@ -5,10 +5,7 @@ import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.vm.VmInstanceInventory; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public class AllocateHostMsg extends NeedReplyMessage { private long cpuCapacity; @@ -26,12 +23,25 @@ public class AllocateHostMsg extends NeedReplyMessage { private boolean allowNoL3Networks; private boolean listAllHosts; private String requiredBackupStorageUuid; + // each primary storage in this set is required private Set requiredPrimaryStorageUuids = new HashSet<>(); + // for each set in the list, the primary storage inside is optional + private final List> optionalPrimaryStorageUuids = new ArrayList<>(); private boolean fullAllocate = true; private long oldMemoryCapacity = 0; private AllocationScene allocationScene; private String architecture; + public List> getOptionalPrimaryStorageUuids() { + return optionalPrimaryStorageUuids; + } + + public void addOptionalPrimaryStorageUuids(Set optionalPrimaryStorageUuids) { + if (optionalPrimaryStorageUuids != null) { + this.optionalPrimaryStorageUuids.add(optionalPrimaryStorageUuids); + } + } + public AllocationScene getAllocationScene() { return allocationScene; } diff --git a/header/src/main/java/org/zstack/header/allocator/BeforeAllocateIpExtensionPoint.java b/header/src/main/java/org/zstack/header/allocator/BeforeAllocateIpExtensionPoint.java new file mode 100644 index 00000000000..c9fdebf444b --- /dev/null +++ b/header/src/main/java/org/zstack/header/allocator/BeforeAllocateIpExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.allocator; + +import org.zstack.header.network.l3.AllocateIpMsg; + +public interface BeforeAllocateIpExtensionPoint { + String allocateIpBySdn(AllocateIpMsg msg, String bmUuid, String mac, String switchInfo); + void releaseIpFromSdn(String nicUuid, String l3NetworkUuid); +} diff --git a/header/src/main/java/org/zstack/header/allocator/DesignatedAllocateHostMsg.java b/header/src/main/java/org/zstack/header/allocator/DesignatedAllocateHostMsg.java index 1df6817a5d8..ca12ee3ac93 100755 --- a/header/src/main/java/org/zstack/header/allocator/DesignatedAllocateHostMsg.java +++ b/header/src/main/java/org/zstack/header/allocator/DesignatedAllocateHostMsg.java @@ -2,11 +2,26 @@ import org.zstack.header.vm.VmInstanceMessage; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + public class DesignatedAllocateHostMsg extends AllocateHostMsg implements VmInstanceMessage { private String zoneUuid; - private String clusterUuid; + private List clusterUuids; private String hostUuid; + public List getClusterUuids() { + return clusterUuids == null ? Collections.emptyList() : clusterUuids; + } + + public void setClusterUuids(List clusterUuids) { + if (clusterUuids != null) { + this.clusterUuids = new ArrayList<>(clusterUuids.size()); + this.clusterUuids.addAll(clusterUuids); + } + } + public String getZoneUuid() { return zoneUuid; } @@ -15,12 +30,10 @@ public void setZoneUuid(String zoneUuid) { this.zoneUuid = zoneUuid; } - public String getClusterUuid() { - return clusterUuid; - } - public void setClusterUuid(String clusterUuid) { - this.clusterUuid = clusterUuid; + if (clusterUuid != null) { + this.clusterUuids = Collections.singletonList(clusterUuid); + } } public String getHostUuid() { diff --git a/header/src/main/java/org/zstack/header/allocator/HostAllocatorSpec.java b/header/src/main/java/org/zstack/header/allocator/HostAllocatorSpec.java index 8ee1e221194..c8d8ddc3af8 100755 --- a/header/src/main/java/org/zstack/header/allocator/HostAllocatorSpec.java +++ b/header/src/main/java/org/zstack/header/allocator/HostAllocatorSpec.java @@ -25,7 +25,10 @@ public class HostAllocatorSpec { private boolean allowNoL3Networks; private boolean listAllHosts; private String requiredBackupStorageUuid; + // each primary storage in this set is required private Set requiredPrimaryStorageUuids = new HashSet<>(); + // for each set in the list, the primary storage inside is optional + private final List> optionalPrimaryStorageUuids = new ArrayList<>(); private Map> backupStoragePrimaryStorageMetrics; private boolean dryRun; private List systemTags; @@ -67,6 +70,16 @@ public Set getRequiredPrimaryStorageUuids() { return requiredPrimaryStorageUuids; } + public List> getOptionalPrimaryStorageUuids() { + return optionalPrimaryStorageUuids; + } + + public void addOptionalPrimaryStorageUuids(Set optionalPrimaryStorageUuids) { + if (optionalPrimaryStorageUuids != null) { + this.optionalPrimaryStorageUuids.add(optionalPrimaryStorageUuids); + } + } + public String getRequiredBackupStorageUuid() { return requiredBackupStorageUuid; } @@ -234,6 +247,7 @@ public static HostAllocatorSpec fromAllocationMsg(AllocateHostMsg msg) { spec.setAllowNoL3Networks(msg.isAllowNoL3Networks()); spec.setRequiredBackupStorageUuid(msg.getRequiredBackupStorageUuid()); spec.setRequiredPrimaryStorageUuids(msg.getRequiredPrimaryStorageUuids()); + msg.getOptionalPrimaryStorageUuids().forEach(spec::addOptionalPrimaryStorageUuids); spec.setAllocationScene(msg.getAllocationScene()); spec.setArchitecture(msg.getArchitecture()); if (msg.getSystemTags() != null && !msg.getSystemTags().isEmpty()){ diff --git a/header/src/main/java/org/zstack/header/allocator/HostAllocatorTrigger.java b/header/src/main/java/org/zstack/header/allocator/HostAllocatorTrigger.java index 30b121f9b5c..6685cb66598 100755 --- a/header/src/main/java/org/zstack/header/allocator/HostAllocatorTrigger.java +++ b/header/src/main/java/org/zstack/header/allocator/HostAllocatorTrigger.java @@ -1,5 +1,6 @@ package org.zstack.header.allocator; +import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.host.HostVO; import java.util.List; @@ -12,4 +13,6 @@ public interface HostAllocatorTrigger { void skip(); boolean isFirstFlow(AbstractHostAllocatorFlow flow); + + void fail(ErrorCode errorCode); } diff --git a/header/src/main/java/org/zstack/header/allocator/HostCapacityInventory.java b/header/src/main/java/org/zstack/header/allocator/HostCapacityInventory.java index 8fd888110f2..ca76b7234ff 100755 --- a/header/src/main/java/org/zstack/header/allocator/HostCapacityInventory.java +++ b/header/src/main/java/org/zstack/header/allocator/HostCapacityInventory.java @@ -15,6 +15,7 @@ public class HostCapacityInventory { private Long totalCpu; private Integer cpuNum; private Integer cpuSockets; + private Integer cpuCoreNum; private Long availableMemory; private Long availableCpu; private Long totalPhysicalMemory; @@ -31,6 +32,7 @@ public static HostCapacityInventory valueOf(HostCapacityVO vo) { inv.setTotalPhysicalMemory(vo.getTotalPhysicalMemory()); inv.setCpuNum(vo.getCpuNum()); inv.setCpuSockets(vo.getCpuSockets()); + inv.setCpuCoreNum(vo.getCpuCoreNum()); return inv; } @@ -42,6 +44,14 @@ public static List valueOf(Collection vos return invs; } + public Integer getCpuCoreNum() { + return cpuCoreNum; + } + + public void setCpuCoreNum(Integer cpuCoreNum) { + this.cpuCoreNum = cpuCoreNum; + } + public Integer getCpuSockets() { return cpuSockets; } diff --git a/header/src/main/java/org/zstack/header/allocator/HostCapacityVO.java b/header/src/main/java/org/zstack/header/allocator/HostCapacityVO.java index 18a66f7af99..b6a17d1a91f 100755 --- a/header/src/main/java/org/zstack/header/allocator/HostCapacityVO.java +++ b/header/src/main/java/org/zstack/header/allocator/HostCapacityVO.java @@ -40,6 +40,9 @@ public class HostCapacityVO { @Column private int cpuSockets; + @Column + private int cpuCoreNum; + @Column @Index private long availableMemory; @@ -63,6 +66,14 @@ public int getCpuSockets() { return cpuSockets; } + public int getCpuCoreNum() { + return cpuCoreNum; + } + + public void setCpuCoreNum(int cpuCoreNum) { + this.cpuCoreNum = cpuCoreNum; + } + public void setCpuSockets(int cpuSockets) { this.cpuSockets = cpuSockets; } diff --git a/header/src/main/java/org/zstack/header/allocator/HostCapacityVO_.java b/header/src/main/java/org/zstack/header/allocator/HostCapacityVO_.java index 0e256752159..d521909ad5a 100755 --- a/header/src/main/java/org/zstack/header/allocator/HostCapacityVO_.java +++ b/header/src/main/java/org/zstack/header/allocator/HostCapacityVO_.java @@ -10,6 +10,7 @@ public class HostCapacityVO_ { public static volatile SingularAttribute totalCpu; public static volatile SingularAttribute cpuNum; public static volatile SingularAttribute cpuSockets; + public static volatile SingularAttribute cpuCoreNum; public static volatile SingularAttribute availableMemory; public static volatile SingularAttribute availableCpu; public static volatile SingularAttribute totalPhysicalMemory; diff --git a/header/src/main/java/org/zstack/header/allocator/HostReservedCapacityExtensionPoint.java b/header/src/main/java/org/zstack/header/allocator/HostReservedCapacityExtensionPoint.java index 17ddc44669d..5a930197969 100755 --- a/header/src/main/java/org/zstack/header/allocator/HostReservedCapacityExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/allocator/HostReservedCapacityExtensionPoint.java @@ -1,9 +1,14 @@ package org.zstack.header.allocator; +import java.util.List; +import java.util.Map; + /** */ public interface HostReservedCapacityExtensionPoint { String getHypervisorTypeForHostReserveCapacityExtension(); ReservedHostCapacity getReservedHostCapacity(String hostUuid); + + Map getReservedHostsCapacity(List hostUuids); } diff --git a/header/src/main/java/org/zstack/header/allocator/PackageInfo.java b/header/src/main/java/org/zstack/header/allocator/PackageInfo.java index fe23de0ec6f..cc32e415ad3 100755 --- a/header/src/main/java/org/zstack/header/allocator/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/allocator/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "调度算法") +@PackageAPIInfo( + APICategoryName = "调度算法", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsg.java b/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsg.java index 3003c0bf7c7..9aee1c4edde 100755 --- a/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsg.java +++ b/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsg.java @@ -2,6 +2,7 @@ import org.springframework.http.HttpMethod; import org.zstack.header.identity.SuppressCredentialCheck; +import org.zstack.header.managementnode.APIManagementNodeMessage; import org.zstack.header.message.APISyncCallMessage; import org.zstack.header.rest.RestRequest; @@ -12,7 +13,7 @@ responseClass = APIIsReadyToGoReply.class, category = "other" ) -public class APIIsReadyToGoMsg extends APISyncCallMessage { +public class APIIsReadyToGoMsg extends APISyncCallMessage implements APIManagementNodeMessage { private String managementNodeId; public String getManagementNodeId() { diff --git a/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsgDoc_zh_cn.groovy index cac756320f5..09486f44800 100644 --- a/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/apimediator/APIIsReadyToGoMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/apimediator/ApiMessageInterceptor.java b/header/src/main/java/org/zstack/header/apimediator/ApiMessageInterceptor.java index 00e271109cf..9d6521020af 100755 --- a/header/src/main/java/org/zstack/header/apimediator/ApiMessageInterceptor.java +++ b/header/src/main/java/org/zstack/header/apimediator/ApiMessageInterceptor.java @@ -10,4 +10,8 @@ */ public interface ApiMessageInterceptor { APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException; + + default int getPriority() { + return 0; + } } diff --git a/header/src/main/java/org/zstack/header/apimediator/ApiWorkerThreadPoolStrategy.java b/header/src/main/java/org/zstack/header/apimediator/ApiWorkerThreadPoolStrategy.java new file mode 100644 index 00000000000..d45589ea08e --- /dev/null +++ b/header/src/main/java/org/zstack/header/apimediator/ApiWorkerThreadPoolStrategy.java @@ -0,0 +1,6 @@ +package org.zstack.header.apimediator; + +public enum ApiWorkerThreadPoolStrategy { + SHARED, + ISOLATED +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/apimediator/GlobalApiMessageInterceptor.java b/header/src/main/java/org/zstack/header/apimediator/GlobalApiMessageInterceptor.java index b210000ba40..34777436fda 100755 --- a/header/src/main/java/org/zstack/header/apimediator/GlobalApiMessageInterceptor.java +++ b/header/src/main/java/org/zstack/header/apimediator/GlobalApiMessageInterceptor.java @@ -4,12 +4,16 @@ public interface GlobalApiMessageInterceptor extends ApiMessageInterceptor { enum InterceptorPosition { - SYSTEM, - FRONT, - END, + // In execution order + SYSTEM, FRONT, DEFAULT, END } List getMessageClassToIntercept(); - InterceptorPosition getPosition(); + /** + * Sort by position, then {@link #getPriority()} + */ + default InterceptorPosition getPosition() { + return InterceptorPosition.FRONT; + } } diff --git a/header/src/main/java/org/zstack/header/aspect/OwnedByAccountAspect.aj b/header/src/main/java/org/zstack/header/aspect/OwnedByAccountAspect.aj new file mode 100644 index 00000000000..944c3c20229 --- /dev/null +++ b/header/src/main/java/org/zstack/header/aspect/OwnedByAccountAspect.aj @@ -0,0 +1,44 @@ +package org.zstack.header.aspect; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.ResourceVO; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.EntityManager; +import java.util.function.Function; + +public aspect OwnedByAccountAspect { + private static final CLogger logger = Utils.getLogger(OwnedByAccountAspect.class); + + private static Function accountUuidGetter; + + public static Function getAccountUuidGetter() { + return accountUuidGetter; + } + + public static void setAccountUuidGetter(Function accountUuidGetter) { + OwnedByAccountAspect.accountUuidGetter = accountUuidGetter; + } + + Object around(OwnedByAccount oa) : this(oa) && execution(java.lang.String OwnedByAccount+.getAccountUuid()) { + Object accountUuid = proceed(oa); + + if (accountUuid == null) { + accountUuid = accountUuidGetter.apply(((ResourceVO) oa).getUuid()); + } + + return accountUuid; + } + + after(EntityManager mgr, Object entity) : call(void EntityManager+.persist(Object)) + && target(mgr) + && args(entity) { + if (!(entity instanceof OwnedByAccount)) { + return; + } + + OwnedByAccount oa = (OwnedByAccount) entity; + OwnedByAccountAspectHelper.createAccountResourceRefVO(oa, mgr, entity); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/zstack/core/aspect/OwnedByAccountAspectHelper.java b/header/src/main/java/org/zstack/header/aspect/OwnedByAccountAspectHelper.java old mode 100755 new mode 100644 similarity index 96% rename from core/src/main/java/org/zstack/core/aspect/OwnedByAccountAspectHelper.java rename to header/src/main/java/org/zstack/header/aspect/OwnedByAccountAspectHelper.java index 32256f3d04f..0c6b8cd1358 --- a/core/src/main/java/org/zstack/core/aspect/OwnedByAccountAspectHelper.java +++ b/header/src/main/java/org/zstack/header/aspect/OwnedByAccountAspectHelper.java @@ -1,4 +1,4 @@ -package org.zstack.core.aspect; +package org.zstack.header.aspect; import org.zstack.header.identity.AccountConstant; import org.zstack.header.identity.AccountResourceRefVO; diff --git a/header/src/main/java/org/zstack/header/cluster/APIChangeClusterStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/cluster/APIChangeClusterStateMsgDoc_zh_cn.groovy index 0604dd541f9..11a23ad64f4 100644 --- a/header/src/main/java/org/zstack/header/cluster/APIChangeClusterStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/cluster/APIChangeClusterStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsg.java b/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsg.java index 16898a449b6..18d1727a07f 100755 --- a/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsg.java +++ b/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsg.java @@ -80,7 +80,7 @@ public class APICreateClusterMsg extends APICreateMessage implements CreateClust @APIParam(required = false, validValues = {"zstack", "baremetal", "baremetal2"}) private String type; - @APIParam(required = false, validValues = {"x86_64", "aarch64", "mips64el"}) + @APIParam(required = false, validValues = {"x86_64", "aarch64", "mips64el", "loongarch64"}) private String architecture; public APICreateClusterMsg() { diff --git a/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsgDoc_zh_cn.groovy index aa2084ca293..90c01a79fa8 100644 --- a/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/cluster/APICreateClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "hypervisorType" @@ -79,7 +76,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +85,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +94,6 @@ doc { type "List" optional true since "0.6" - } column { name "architecture" @@ -109,7 +103,7 @@ doc { type "String" optional true since "4.0" - values ("x86_64","aarch64","mips64el") + values ("x86_64","aarch64","mips64el","loongarch64") } column { name "tagUuids" @@ -118,8 +112,7 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" } } } @@ -128,4 +121,4 @@ doc { clz APICreateClusterEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/cluster/APIDeleteClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/cluster/APIDeleteClusterMsgDoc_zh_cn.groovy index d64589f6b95..d2dfccf1465 100644 --- a/header/src/main/java/org/zstack/header/cluster/APIDeleteClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/cluster/APIDeleteClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/cluster/APIQueryClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/cluster/APIQueryClusterMsgDoc_zh_cn.groovy index 6e0f04344e7..680ab47f658 100644 --- a/header/src/main/java/org/zstack/header/cluster/APIQueryClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/cluster/APIQueryClusterMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.cluster import org.zstack.header.cluster.APIQueryClusterReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryCluster" diff --git a/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterMsgDoc_zh_cn.groovy index 29678f6f103..c68341d121a 100644 --- a/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsg.java b/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsg.java index acdd2e9db14..9da5d285271 100644 --- a/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsg.java +++ b/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsg.java @@ -1,6 +1,7 @@ package org.zstack.header.cluster; import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostVO; import org.zstack.header.message.APICreateMessage; import org.zstack.header.message.APIParam; import org.zstack.header.message.DefaultTimeout; @@ -23,12 +24,16 @@ public class APIUpdateClusterOSMsg extends APICreateMessage implements ClusterMessage { @APIParam(resourceType = ClusterVO.class) private String uuid; + @APIParam(resourceType = HostVO.class, required = false) + private String hostUuid; @APIParam(required = false, nonempty = true) private List excludePackages; @APIParam(required = false, nonempty = true) private List updatePackages; @APIParam(required = false, nonempty = true) private String releaseVersion; + @APIParam(required = false) + private boolean force = false; public String getUuid() { return uuid; } @@ -66,12 +71,29 @@ public String getClusterUuid() { return uuid; } + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + public static APIUpdateClusterOSMsg __example__() { APIUpdateClusterOSMsg msg = new APIUpdateClusterOSMsg(); msg.setUuid(uuid()); msg.setExcludePackages(Arrays.asList("kernel", "systemd*")); msg.setUpdatePackages(Arrays.asList("zstack-release")); msg.setReleaseVersion("c74"); + msg.setForce(false); return msg; } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } } diff --git a/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsgDoc_zh_cn.groovy index 7670020e397..3db00d67e96 100644 --- a/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/cluster/APIUpdateClusterOSMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "excludePackages" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "updatePackages" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.7" - } column { name "releaseVersion" @@ -59,7 +56,6 @@ doc { type "String" optional true since "3.7" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "tagUuids" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -99,7 +92,25 @@ doc { type "List" optional true since "2.3" - + } + column { + name "force" + enclosedIn "updateClusterOS" + desc "强制" + location "body" + type "boolean" + optional true + since "5.2.0" + values ("true","false") + } + column { + name "hostUuid" + enclosedIn "updateClusterOS" + desc "物理机UUID" + location "body" + type "String" + optional true + since "4.8.13" } } } @@ -108,4 +119,4 @@ doc { clz APIUpdateClusterOSEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/cluster/ClusterUpdateOSExtensionPoint.java b/header/src/main/java/org/zstack/header/cluster/ClusterUpdateOSExtensionPoint.java index a652463238f..e6364934368 100644 --- a/header/src/main/java/org/zstack/header/cluster/ClusterUpdateOSExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/cluster/ClusterUpdateOSExtensionPoint.java @@ -4,7 +4,7 @@ * Created by GuoYi on 3/16/18 */ public interface ClusterUpdateOSExtensionPoint { - String preUpdateClusterOS(ClusterVO cls); + String preUpdateClusterOS(UpdateClusterOSStruct updateClusterOSStruct); void beforeUpdateClusterOS(ClusterVO cls); void afterUpdateClusterOS(ClusterVO cls); } diff --git a/header/src/main/java/org/zstack/header/cluster/PackageInfo.java b/header/src/main/java/org/zstack/header/cluster/PackageInfo.java index 20cd1903b17..fc041bcf99e 100755 --- a/header/src/main/java/org/zstack/header/cluster/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/cluster/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "集群") +@PackageAPIInfo( + APICategoryName = "集群", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/cluster/ReportHostCapacityMessage.java b/header/src/main/java/org/zstack/header/cluster/ReportHostCapacityMessage.java index bd41d6a2cca..e2d069c6a10 100755 --- a/header/src/main/java/org/zstack/header/cluster/ReportHostCapacityMessage.java +++ b/header/src/main/java/org/zstack/header/cluster/ReportHostCapacityMessage.java @@ -10,6 +10,15 @@ public class ReportHostCapacityMessage extends NeedReplyMessage { private String hostUuid; private int cpuNum; private int cpuSockets; + private int cpuCoreNum; + + public int getCpuCoreNum() { + return cpuCoreNum; + } + + public void setCpuCoreNum(int cpuCoreNum) { + this.cpuCoreNum = cpuCoreNum; + } public int getCpuSockets() { return cpuSockets; diff --git a/header/src/main/java/org/zstack/header/cluster/StopClusterMsg.java b/header/src/main/java/org/zstack/header/cluster/StopClusterMsg.java index dfbb2e21d58..b7dbb4d5961 100755 --- a/header/src/main/java/org/zstack/header/cluster/StopClusterMsg.java +++ b/header/src/main/java/org/zstack/header/cluster/StopClusterMsg.java @@ -4,6 +4,6 @@ public class StopClusterMsg extends NeedReplyMessage { public StopClusterMsg() { - super.timeout = 60 * 1000; + super.timeout = 60 * 1000L; } } diff --git a/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSMsg.java b/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSMsg.java index b74842bcc40..3c9ed3f827c 100755 --- a/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSMsg.java +++ b/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSMsg.java @@ -8,9 +8,11 @@ */ public class UpdateClusterOSMsg extends NeedReplyMessage implements ClusterMessage { private String uuid; + private String hostUuid; private String excludePackages; private String updatePackages; private String releaseVersion; + private boolean force; public String getUuid() { return uuid; @@ -48,4 +50,20 @@ public void setReleaseVersion(String releaseVersion) { public String getClusterUuid() { return uuid; } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } } diff --git a/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSStruct.java b/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSStruct.java new file mode 100644 index 00000000000..06dd3969fec --- /dev/null +++ b/header/src/main/java/org/zstack/header/cluster/UpdateClusterOSStruct.java @@ -0,0 +1,49 @@ +package org.zstack.header.cluster; + +public class UpdateClusterOSStruct { + private ClusterVO cluster; + private String excludePackages; + private String updatePackages; + private String releaseVersion; + private boolean force; + + public ClusterVO getCluster() { + return cluster; + } + + public void setCluster(ClusterVO cluster) { + this.cluster = cluster; + } + + public String getReleaseVersion() { + return releaseVersion; + } + + public void setReleaseVersion(String releaseVersion) { + this.releaseVersion = releaseVersion; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public String getExcludePackages() { + return excludePackages; + } + + public void setExcludePackages(String excludePackages) { + this.excludePackages = excludePackages; + } + + public String getUpdatePackages() { + return updatePackages; + } + + public void setUpdatePackages(String updatePackages) { + this.updatePackages = updatePackages; + } +} diff --git a/header/src/main/java/org/zstack/header/configuration/APIChangeDiskOfferingStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIChangeDiskOfferingStateMsgDoc_zh_cn.groovy index 8618f5ea429..55f19c4cdb4 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIChangeDiskOfferingStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIChangeDiskOfferingStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APIChangeInstanceOfferingStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIChangeInstanceOfferingStateMsgDoc_zh_cn.groovy index 365b6f45490..601ada5571a 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIChangeInstanceOfferingStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIChangeInstanceOfferingStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APICreateDiskOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APICreateDiskOfferingMsgDoc_zh_cn.groovy index bae2ece6457..72770834f29 100644 --- a/header/src/main/java/org/zstack/header/configuration/APICreateDiskOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APICreateDiskOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "diskSize" @@ -49,7 +47,6 @@ doc { type "long" optional false since "0.6" - } column { name "sortKey" @@ -59,7 +56,6 @@ doc { type "int" optional true since "0.6" - } column { name "allocationStrategy" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -89,7 +84,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -99,7 +93,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +102,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsg.java b/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsg.java index e11be3b6690..d12925c3cf5 100755 --- a/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsg.java +++ b/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsg.java @@ -32,6 +32,8 @@ public class APICreateInstanceOfferingMsg extends APICreateMessage implements AP private int cpuSpeed; @APIParam(numberRange = {1, Long.MAX_VALUE}, numberRangeUnit = {"byte", "bytes"}) private long memorySize; + @APIParam(numberRange = {0, Long.MAX_VALUE}, numberRangeUnit = {"byte", "bytes"}, required = false) + private long reservedMemorySize; private String allocatorStrategy; private int sortKey; private String type; @@ -63,6 +65,14 @@ public void setMemorySize(long memorySize) { this.memorySize = memorySize; } + public long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public String getAllocatorStrategy() { return allocatorStrategy; } diff --git a/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsgDoc_zh_cn.groovy index e735b4f6f61..c3fe05d0050 100644 --- a/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APICreateInstanceOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "cpuNum" @@ -49,7 +47,6 @@ doc { type "int" optional false since "0.6" - } column { name "memorySize" @@ -59,7 +56,6 @@ doc { type "long" optional false since "0.6" - } column { name "allocatorStrategy" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "sortKey" @@ -79,7 +74,6 @@ doc { type "int" optional true since "0.6" - } column { name "type" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -99,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +101,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +110,24 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "reservedMemorySize" + enclosedIn "params" + desc "" + location "body" + type "long" + optional true + since "4.7.21" } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APIDeleteDiskOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIDeleteDiskOfferingMsgDoc_zh_cn.groovy index 0399a4c6c4c..332e248ee78 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIDeleteDiskOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIDeleteDiskOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APIDeleteInstanceOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIDeleteInstanceOfferingMsgDoc_zh_cn.groovy index fc29b0f6fb5..14afe85cc96 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIDeleteInstanceOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIDeleteInstanceOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APIQueryDiskOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIQueryDiskOfferingMsgDoc_zh_cn.groovy index 82f0789a36c..2a48fe94427 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIQueryDiskOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIQueryDiskOfferingMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.configuration import org.zstack.header.configuration.APIQueryDiskOfferingReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryDiskOffering" diff --git a/header/src/main/java/org/zstack/header/configuration/APIQueryInstanceOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIQueryInstanceOfferingMsgDoc_zh_cn.groovy index a563f4ef0f7..42c2f53c2ba 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIQueryInstanceOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIQueryInstanceOfferingMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.configuration import org.zstack.header.configuration.APIQueryInstanceOfferingReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryInstanceOffering" diff --git a/header/src/main/java/org/zstack/header/configuration/APIUpdateDiskOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIUpdateDiskOfferingMsgDoc_zh_cn.groovy index 9a930a9177a..8349422a1b8 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIUpdateDiskOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIUpdateDiskOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/configuration/APIUpdateInstanceOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/configuration/APIUpdateInstanceOfferingMsgDoc_zh_cn.groovy index 86bd0743b15..7ae39c450fd 100644 --- a/header/src/main/java/org/zstack/header/configuration/APIUpdateInstanceOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/configuration/APIUpdateInstanceOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "allocatorStrategy" @@ -79,7 +74,6 @@ doc { type "String" optional true since "2.3.1" - } } } diff --git a/header/src/main/java/org/zstack/header/configuration/InstanceOfferingAO.java b/header/src/main/java/org/zstack/header/configuration/InstanceOfferingAO.java index 19ad37a517c..b7e7d9fb70c 100755 --- a/header/src/main/java/org/zstack/header/configuration/InstanceOfferingAO.java +++ b/header/src/main/java/org/zstack/header/configuration/InstanceOfferingAO.java @@ -24,6 +24,9 @@ public class InstanceOfferingAO extends ResourceVO { @Column private long memorySize; + @Column + private long reservedMemorySize; + @Column private String allocatorStrategy; @@ -61,6 +64,7 @@ public InstanceOfferingAO(InstanceOfferingAO other) { this.lastOpDate = other.lastOpDate; this.type = other.type; this.duration = other.duration; + this.reservedMemorySize = other.reservedMemorySize; } public InstanceOfferingAO() { @@ -166,4 +170,12 @@ public InstanceOfferingState getState() { public void setState(InstanceOfferingState state) { this.state = state; } + + public long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } } diff --git a/header/src/main/java/org/zstack/header/configuration/InstanceOfferingInventory.java b/header/src/main/java/org/zstack/header/configuration/InstanceOfferingInventory.java index 914c8e2bdd2..708565e7c31 100755 --- a/header/src/main/java/org/zstack/header/configuration/InstanceOfferingInventory.java +++ b/header/src/main/java/org/zstack/header/configuration/InstanceOfferingInventory.java @@ -24,6 +24,7 @@ public class InstanceOfferingInventory implements Serializable { private Integer cpuNum; private Integer cpuSpeed; private Long memorySize; + private Long reservedMemorySize; private String type; private String allocatorStrategy; private Integer sortKey; @@ -39,6 +40,7 @@ protected InstanceOfferingInventory(InstanceOfferingVO vo) { this.setCpuNum(vo.getCpuNum()); this.setCpuSpeed(vo.getCpuSpeed()); this.setMemorySize(vo.getMemorySize()); + this.setReservedMemorySize(vo.getReservedMemorySize()); this.setUuid(vo.getUuid()); this.setName(vo.getName()); this.setDescription(vo.getDescription()); @@ -54,6 +56,7 @@ protected InstanceOfferingInventory(InstanceOfferingEO vo) { this.setCpuNum(vo.getCpuNum()); this.setCpuSpeed(vo.getCpuSpeed()); this.setMemorySize(vo.getMemorySize()); + this.setReservedMemorySize(vo.getReservedMemorySize()); this.setUuid(vo.getUuid()); this.setName(vo.getName()); this.setDescription(vo.getDescription()); @@ -176,4 +179,12 @@ public String getState() { public void setState(String state) { this.state = state; } + + public long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } } diff --git a/header/src/main/java/org/zstack/header/configuration/PackageInfo.java b/header/src/main/java/org/zstack/header/configuration/PackageInfo.java index fcdf008cb1c..73ccca8e189 100755 --- a/header/src/main/java/org/zstack/header/configuration/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/configuration/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "配置") +@PackageAPIInfo( + APICategoryName = "配置", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/configuration/userconfig/DiskOfferingAllocateConfig.java b/header/src/main/java/org/zstack/header/configuration/userconfig/DiskOfferingAllocateConfig.java index 2d941a6f6aa..a2e49c547c1 100644 --- a/header/src/main/java/org/zstack/header/configuration/userconfig/DiskOfferingAllocateConfig.java +++ b/header/src/main/java/org/zstack/header/configuration/userconfig/DiskOfferingAllocateConfig.java @@ -1,12 +1,26 @@ package org.zstack.header.configuration.userconfig; import org.zstack.header.storage.primary.PrimaryStorageAllocateConfig; +import org.zstack.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; /** * Created by lining on 2019/4/17. */ public class DiskOfferingAllocateConfig { private PrimaryStorageAllocateConfig primaryStorage; + private List primaryStorages; + + @Deprecated + public List getPrimaryStorages() { + return primaryStorages; + } + + public void setPrimaryStorages(List primaryStorages) { + this.primaryStorages = primaryStorages; + } public PrimaryStorageAllocateConfig getPrimaryStorage() { return primaryStorage; @@ -15,4 +29,16 @@ public PrimaryStorageAllocateConfig getPrimaryStorage() { public void setPrimaryStorage(PrimaryStorageAllocateConfig primaryStorage) { this.primaryStorage = primaryStorage; } + + public List getAllPrimaryStorages() { + List results = new ArrayList<>(); + if (primaryStorages != null) { + results.addAll(primaryStorages); + } + if (primaryStorage != null) { + results.add(primaryStorage); + } + + return results; + } } diff --git a/header/src/main/java/org/zstack/header/console/APIQueryConsoleProxyAgentMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/console/APIQueryConsoleProxyAgentMsgDoc_zh_cn.groovy index d31eb791864..647244d8b3d 100644 --- a/header/src/main/java/org/zstack/header/console/APIQueryConsoleProxyAgentMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/console/APIQueryConsoleProxyAgentMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.console import org.zstack.header.console.APIQueryConsoleProxyAgentReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryConsoleProxyAgent" diff --git a/header/src/main/java/org/zstack/header/console/APIReconnectConsoleProxyAgentMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/console/APIReconnectConsoleProxyAgentMsgDoc_zh_cn.groovy index 429cf985857..85376882993 100644 --- a/header/src/main/java/org/zstack/header/console/APIReconnectConsoleProxyAgentMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/console/APIReconnectConsoleProxyAgentMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/console/APIRequestConsoleAccessMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/console/APIRequestConsoleAccessMsgDoc_zh_cn.groovy index 23aa8eb075a..11880cc2f78 100644 --- a/header/src/main/java/org/zstack/header/console/APIRequestConsoleAccessMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/console/APIRequestConsoleAccessMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsg.java b/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsg.java index 16c44692e0f..b9f2792ea65 100755 --- a/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsg.java +++ b/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsg.java @@ -18,14 +18,14 @@ public class APIUpdateConsoleProxyAgentMsg extends APIMessage implements Console private String uuid; @APIParam private String consoleProxyOverriddenIp; - @APIParam(required = false) - private int consoleProxyPort; + @APIParam(required = false, numberRange={1, 65535}) + private Integer consoleProxyPort; - public int getConsoleProxyPort() { + public Integer getConsoleProxyPort() { return consoleProxyPort; } - public void setConsoleProxyPort(int consoleProxyPort) { + public void setConsoleProxyPort(Integer consoleProxyPort) { this.consoleProxyPort = consoleProxyPort; } diff --git a/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsgDoc_zh_cn.groovy index 466bf5b87a5..914e5a128c3 100644 --- a/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/console/APIUpdateConsoleProxyAgentMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "consoleProxyOverriddenIp" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -59,7 +56,15 @@ doc { type "List" optional true since "2.3" - + } + column { + name "consoleProxyPort" + enclosedIn "updateConsoleProxyAgent" + desc "" + location "body" + type "Integer" + optional true + since "4.1.0" } } } diff --git a/header/src/main/java/org/zstack/header/console/ConsoleBackend.java b/header/src/main/java/org/zstack/header/console/ConsoleBackend.java index 9ab0a3ca481..973810a1269 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleBackend.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleBackend.java @@ -16,6 +16,8 @@ public interface ConsoleBackend { String getConsoleBackendType(); + void deleteConsoleSession(ConsoleProxyInventory consoleProxy, Completion completion); + void grantConsoleAccess(SessionInventory session, VmInstanceInventory vm, ReturnValueCompletion complete); void deleteConsoleSession(VmInstanceInventory vm, Completion completion); @@ -25,4 +27,8 @@ public interface ConsoleBackend { String returnServiceIdForConsoleAgentMsg(ConsoleProxyAgentMessage msg, String agentUuid); void handleMessage(Message msg); + + void deactivateConsoleProxy(VmInstanceInventory vmInventory, Completion completion); + + void updateConsoleProxy(VmInstanceInventory vm, ConsoleProxyVO consoleProxy, ReturnValueCompletion consoleInventoryReturnValueCompletion); } diff --git a/header/src/main/java/org/zstack/header/console/ConsoleInventory.java b/header/src/main/java/org/zstack/header/console/ConsoleInventory.java index 3cabfda6057..2a21b61f6db 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleInventory.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleInventory.java @@ -1,5 +1,8 @@ package org.zstack.header.console; + +import java.sql.Timestamp; + /** * Created with IntelliJ IDEA. * User: frank @@ -13,6 +16,7 @@ public class ConsoleInventory { private int port; private String token; private String version; + private Timestamp expiredDate; public static ConsoleInventory valueOf(ConsoleProxyVO vo) { ConsoleInventory inv = new ConsoleInventory(); @@ -22,6 +26,7 @@ public static ConsoleInventory valueOf(ConsoleProxyVO vo) { inv.setScheme(vo.getScheme()); inv.setTargetScheme(vo.getTargetSchema()); inv.setVersion(vo.getVersion()); + inv.setExpiredDate(vo.getExpiredDate()); return inv; } @@ -72,4 +77,11 @@ public String getVersion() { public void setVersion(String version) { this.version = version; } + + public Timestamp getExpiredDate() { + return expiredDate; + } + public void setExpiredDate(Timestamp expiredDate) { + this.expiredDate = expiredDate; + } } diff --git a/header/src/main/java/org/zstack/header/console/ConsoleProxy.java b/header/src/main/java/org/zstack/header/console/ConsoleProxy.java index 34db7077983..5738a513f88 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleProxy.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleProxy.java @@ -12,9 +12,11 @@ * To change this template use File | Settings | File Templates. */ public interface ConsoleProxy { - void establishProxy(SessionInventory session, VmInstanceInventory vm, ReturnValueCompletion completion); + void establishProxy(VmInstanceInventory vm, ReturnValueCompletion completion); void checkAvailability(ReturnValueCompletion completion); void deleteProxy(VmInstanceInventory vm, Completion completion); + + void deleteProxy(ConsoleProxyInventory proxy, Completion completion); } diff --git a/header/src/main/java/org/zstack/header/console/ConsoleProxyCommands.java b/header/src/main/java/org/zstack/header/console/ConsoleProxyCommands.java index 7a529eb8ccc..5587d74bbbf 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleProxyCommands.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleProxyCommands.java @@ -199,6 +199,8 @@ public static class EstablishProxyCmd extends AgentCommand { private String scheme; private int idleTimeout; private int vncTokenTimeout; + private String tlsVersion; + private long expiredDate; public String getToken() { return token; @@ -287,6 +289,22 @@ public int getVncTokenTimeout() { public void setVncTokenTimeout(int vncTokenTimeout) { this.vncTokenTimeout = vncTokenTimeout; } + + public String getTlsVersion() { + return tlsVersion; + } + + public void setTlsVersion(String tlsVersion) { + this.tlsVersion = tlsVersion; + } + + public long getExpiredDate() { + return expiredDate; + } + + public void setExpiredDate(long expiredDate) { + this.expiredDate = expiredDate; + } } public static class EstablishProxyRsp extends AgentResponse { diff --git a/header/src/main/java/org/zstack/header/console/ConsoleProxyInventory.java b/header/src/main/java/org/zstack/header/console/ConsoleProxyInventory.java index 0f2e47003c1..5097f23a37d 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleProxyInventory.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleProxyInventory.java @@ -31,6 +31,7 @@ public class ConsoleProxyInventory { private String proxyIdentity; private String status; private String version; + private Timestamp expiredDate; private Timestamp createDate; private Timestamp lastOpDate; @@ -52,6 +53,7 @@ public static ConsoleProxyInventory valueOf(ConsoleProxyVO vo) { inv.setVersion(vo.getVersion()); inv.setLastOpDate(vo.getLastOpDate()); inv.setStatus(vo.getStatus().toString()); + inv.setExpiredDate(vo.getExpiredDate()); return inv; } @@ -190,4 +192,12 @@ public String getVersion() { public void setVersion(String version) { this.version = version; } + + public Timestamp getExpiredDate() { + return expiredDate; + } + + public void setExpiredDate(Timestamp expiredDate) { + this.expiredDate = expiredDate; + } } diff --git a/header/src/main/java/org/zstack/header/console/ConsoleProxyVO.java b/header/src/main/java/org/zstack/header/console/ConsoleProxyVO.java index cf7a987c606..116ad756ac0 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleProxyVO.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleProxyVO.java @@ -70,6 +70,9 @@ public class ConsoleProxyVO extends ResourceVO { @Column private Timestamp createDate; + @Column + private Timestamp expiredDate; + @Column private Timestamp lastOpDate; @@ -197,4 +200,12 @@ public String getVersion() { public void setVersion(String version) { this.version = version; } + + public Timestamp getExpiredDate() { + return expiredDate; + } + + public void setExpiredDate(Timestamp expiredDate) { + this.expiredDate = expiredDate; + } } diff --git a/header/src/main/java/org/zstack/header/console/ConsoleProxyVO_.java b/header/src/main/java/org/zstack/header/console/ConsoleProxyVO_.java index c88fe9eabe2..99f0f00b4ab 100755 --- a/header/src/main/java/org/zstack/header/console/ConsoleProxyVO_.java +++ b/header/src/main/java/org/zstack/header/console/ConsoleProxyVO_.java @@ -27,4 +27,5 @@ public class ConsoleProxyVO_ extends ResourceVO_ { public static volatile SingularAttribute status; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; + public static volatile SingularAttribute expiredDate; } diff --git a/header/src/main/java/org/zstack/header/console/PackageInfo.java b/header/src/main/java/org/zstack/header/console/PackageInfo.java index b213f08ff1f..61aadcd0da1 100755 --- a/header/src/main/java/org/zstack/header/console/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/console/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "Console终端") +@PackageAPIInfo( + APICategoryName = "Console终端", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/core/APIGetChainTaskMsg.java b/header/src/main/java/org/zstack/header/core/APIGetChainTaskMsg.java new file mode 100644 index 00000000000..fb5054f1a54 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/APIGetChainTaskMsg.java @@ -0,0 +1,33 @@ +package org.zstack.header.core; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +import java.util.List; +import java.util.function.Function; + +@Action(category = CoreConstant.ACTION_CATEGORY, adminOnly = true) +@RestRequest( + path = "/core/task-details", + method = HttpMethod.GET, + responseClass = APIGetChainTaskReply.class +) +public class APIGetChainTaskMsg extends APISyncCallMessage { + @APIParam(nonempty = false, required = false) + private List syncSignatures; + + public void setSyncSignatures(List syncSignatures) { + this.syncSignatures = syncSignatures; + } + + public List getSyncSignatures() { + return syncSignatures; + } + + public Function getResourceUuidMaker() { + return null; + } +} diff --git a/header/src/main/java/org/zstack/header/core/APIGetChainTaskMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/APIGetChainTaskMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..9e2d02790ff --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/APIGetChainTaskMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.core + +import org.zstack.header.core.APIGetChainTaskReply + +doc { + title "GetChainTask" + + category "core" + + desc """获取任务队列详情""" + + rest { + request { + url "GET /v1/core/task-details" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetChainTaskMsg.class + + desc """""" + + params { + + column { + name "syncSignatures" + enclosedIn "" + desc "" + location "query" + type "List" + optional true + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIGetChainTaskReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/APIGetChainTaskReply.java b/header/src/main/java/org/zstack/header/core/APIGetChainTaskReply.java new file mode 100644 index 00000000000..94cbec0efcc --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/APIGetChainTaskReply.java @@ -0,0 +1,34 @@ +package org.zstack.header.core; + +import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.HashMap; +import java.util.Map; + +@RestResponse(fieldsTo = {"all"}) +public class APIGetChainTaskReply extends APIReply { + private Map results = new HashMap<>(); + + public Map getResults() { + return results; + } + + public void setResults(Map results) { + this.results = results; + } + + public void putResults(String hostUuid, ChainInfo info) { + results.put(hostUuid, info); + } + + public void putAllResults(Map results) { + results.forEach((key, value) -> { + ChainInfo chainInfo = this.results.getOrDefault(key, new ChainInfo()); + chainInfo.getRunningTask().addAll(value.getRunningTask()); + chainInfo.getPendingTask().addAll(value.getPendingTask()); + this.results.put(key, chainInfo); + }); + } +} diff --git a/header/src/main/java/org/zstack/header/core/APIGetChainTaskReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/APIGetChainTaskReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..166348905e0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/APIGetChainTaskReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.core + +import org.zstack.header.core.progress.ChainInfo +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取任务队列返回" + + ref { + name "results" + path "org.zstack.header.core.APIGetChainTaskReply.results" + desc "null" + type "Map" + since "4.6.0" + clz ChainInfo.class + } + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.header.core.APIGetChainTaskReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/CoreConstant.java b/header/src/main/java/org/zstack/header/core/CoreConstant.java new file mode 100644 index 00000000000..c9be4f04a7c --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/CoreConstant.java @@ -0,0 +1,7 @@ +package org.zstack.header.core; + +public interface CoreConstant { + String SERVICE_ID = "core"; + + String ACTION_CATEGORY = "core"; +} diff --git a/header/src/main/java/org/zstack/header/core/FutureCompletion.java b/header/src/main/java/org/zstack/header/core/FutureCompletion.java index 2b3a192f4f5..0ad3fc488dc 100755 --- a/header/src/main/java/org/zstack/header/core/FutureCompletion.java +++ b/header/src/main/java/org/zstack/header/core/FutureCompletion.java @@ -79,10 +79,11 @@ public synchronized boolean tryWait(long timeout) { return done; } - private void doWait(long timeout) { + private synchronized void doWait(long timeout) { try { wait(timeout); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } } @@ -95,6 +96,7 @@ public synchronized void await() { try { wait(); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } } diff --git a/header/src/main/java/org/zstack/header/core/FutureReturnValueCompletion.java b/header/src/main/java/org/zstack/header/core/FutureReturnValueCompletion.java index 60a3f09f02d..982311b474d 100755 --- a/header/src/main/java/org/zstack/header/core/FutureReturnValueCompletion.java +++ b/header/src/main/java/org/zstack/header/core/FutureReturnValueCompletion.java @@ -50,10 +50,11 @@ public ErrorCode getErrorCode() { return errorCode; } - private void dumpSlowFuture() { + private synchronized void dumpSlowFuture() { try { wait(SLOW_FUTURE_TIMEOUT); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } @@ -75,6 +76,7 @@ private void dumpSlowFuture() { } } catch (Exception e) { logger.warn(String.format("dumpSlowFuture get exception %s %s", e.getMessage(), e.toString())); + Thread.currentThread().interrupt(); } } @@ -95,6 +97,7 @@ public synchronized void await(long timeout) { try { wait(timeout); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } @@ -115,6 +118,7 @@ public synchronized void await() { try { wait(); } catch (InterruptedException e) { + Thread.currentThread().interrupt(); throw new CloudRuntimeException(e); } } diff --git a/header/src/main/java/org/zstack/header/core/GetLocalTaskMsg.java b/header/src/main/java/org/zstack/header/core/GetLocalTaskMsg.java new file mode 100644 index 00000000000..6a7675b52ac --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/GetLocalTaskMsg.java @@ -0,0 +1,26 @@ +package org.zstack.header.core; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; + +public class GetLocalTaskMsg extends NeedReplyMessage { + private List syncSignatures; + private boolean onlyRunningTask; + + public boolean isOnlyRunningTask() { + return onlyRunningTask; + } + + public void setOnlyRunningTask(boolean onlyRunningTask) { + this.onlyRunningTask = onlyRunningTask; + } + + public void setSyncSignatures(List syncSignatures) { + this.syncSignatures = syncSignatures; + } + + public List getSyncSignatures() { + return syncSignatures; + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/GetLocalTaskReply.java b/header/src/main/java/org/zstack/header/core/GetLocalTaskReply.java new file mode 100644 index 00000000000..26a319ce69a --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/GetLocalTaskReply.java @@ -0,0 +1,23 @@ +package org.zstack.header.core; + +import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.message.MessageReply; + +import java.util.HashMap; +import java.util.Map; + +public class GetLocalTaskReply extends MessageReply { + private Map results = new HashMap<>(); + + public Map getResults() { + return results; + } + + public void setResults(Map results) { + this.results = results; + } + + public void putResults(String uuid, ChainInfo info) { + results.put(uuid, info); + } +} diff --git a/header/src/main/java/org/zstack/header/core/HaCheckerCompletion.java b/header/src/main/java/org/zstack/header/core/HaCheckerCompletion.java index d55b6832f67..ea2f42dedec 100644 --- a/header/src/main/java/org/zstack/header/core/HaCheckerCompletion.java +++ b/header/src/main/java/org/zstack/header/core/HaCheckerCompletion.java @@ -5,12 +5,12 @@ /** * Created by xing5 on 2016/3/29. */ -public abstract class HaCheckerCompletion extends AbstractCompletion { +public abstract class HaCheckerCompletion extends AbstractCompletion { public HaCheckerCompletion(AsyncBackup one, AsyncBackup... others) { super(one, others); } - public abstract void success(); + public abstract void success(T returnValue); public abstract void fail(ErrorCode errorCode); diff --git a/header/src/main/java/org/zstack/header/core/SafeConsumer.java b/header/src/main/java/org/zstack/header/core/SafeConsumer.java new file mode 100644 index 00000000000..7e0e522e074 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/SafeConsumer.java @@ -0,0 +1,11 @@ +package org.zstack.header.core; + + +import java.util.function.Consumer; + +public interface SafeConsumer extends Consumer { + @ExceptionSafe + default void safeAccept(T t) { + accept(t); + } +} diff --git a/header/src/main/java/org/zstack/header/core/WhileCompletion.java b/header/src/main/java/org/zstack/header/core/WhileCompletion.java index cc9f1f2a19f..ffb7e6bf86b 100644 --- a/header/src/main/java/org/zstack/header/core/WhileCompletion.java +++ b/header/src/main/java/org/zstack/header/core/WhileCompletion.java @@ -13,6 +13,15 @@ public abstract class WhileCompletion extends NoErrorCompletion { public WhileCompletion(AsyncBackup... completion) { super(completion); } + + /** + * The allDone method will IMMEDIATELY stop the executing loop and return, + * without waiting for other handler finished + * + * The executing handler will keep running; + * + * The handler that has not yet been executed will be aborted. + */ public abstract void allDone(); public abstract void addError(ErrorCode error); diff --git a/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldMsg.java b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldMsg.java new file mode 100644 index 00000000000..22ca5f12cba --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldMsg.java @@ -0,0 +1,36 @@ +package org.zstack.header.core.encrypt; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +/** + * @author hanyu.liang + * @date 2023/5/5 16:18 + */ +@Action(category = EncryptConstant.CERTIFICATE_ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/encrypted/fields", + method = HttpMethod.GET, + responseClass = APIGetEncryptedFieldReply.class +) +public class APIGetEncryptedFieldMsg extends APISyncCallMessage { + @APIParam(required = false) + private String encryptedType; + + public String getEncryptedType() { + return encryptedType; + } + + public void setEncryptedType(String encryptedType) { + this.encryptedType = encryptedType; + } + + public static APIGetEncryptedFieldMsg __example__() { + APIGetEncryptedFieldMsg msg = new APIGetEncryptedFieldMsg(); + msg.setEncryptedType("SM4"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..e1035bb3af9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.core.encrypt + +import org.zstack.header.core.encrypt.APIGetEncryptedFieldReply + +doc { + title "GetEncryptedField" + + category "crypto" + + desc """获取加密字段""" + + rest { + request { + url "GET /v1/encrypted/fields" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetEncryptedFieldMsg.class + + desc """""" + + params { + + column { + name "encryptedType" + enclosedIn "" + desc "加密字段类型" + location "query" + type "String" + optional true + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIGetEncryptedFieldReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldReply.java b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldReply.java new file mode 100644 index 00000000000..82a58577b22 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldReply.java @@ -0,0 +1,30 @@ +package org.zstack.header.core.encrypt; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.Arrays; +import java.util.List; + +/** + * @author hanyu.liang + * @date 2023/5/5 16:18 + */ +@RestResponse(fieldsTo = "all") +public class APIGetEncryptedFieldReply extends APIReply { + List encryptedFields; + + public List getEncryptedFields() { + return encryptedFields; + } + + public void setEncryptedFields(List encryptedFields) { + this.encryptedFields = encryptedFields; + } + + public static APIGetEncryptedFieldReply __example__() { + APIGetEncryptedFieldReply ret = new APIGetEncryptedFieldReply(); + ret.setEncryptedFields(Arrays.asList(EncryptedFieldBundle.class.getSimpleName())); + return ret; + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..c95d5c8fc0a --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/APIGetEncryptedFieldReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.core.encrypt + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "加密字段返回" + + field { + name "encryptedFields" + desc "所有加密字段列表,列表中每个项是jsonString格式" + type "List" + since "4.7.0" + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.core.encrypt.APIGetEncryptedFieldReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/AddIntegrityVerificationFileMsg.java b/header/src/main/java/org/zstack/header/core/encrypt/AddIntegrityVerificationFileMsg.java new file mode 100644 index 00000000000..6cf27716d9b --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/AddIntegrityVerificationFileMsg.java @@ -0,0 +1,46 @@ +package org.zstack.header.core.encrypt; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @author hanyu.liang + * @date 2023/4/17 16:29 + */ +public class AddIntegrityVerificationFileMsg extends NeedReplyMessage { + private String nodeType; + private String nodeUuid; + private String path; + private String hexType; + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getNodeUuid() { + return nodeUuid; + } + + public void setNodeUuid(String nodeUuid) { + this.nodeUuid = nodeUuid; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getHexType() { + return hexType; + } + + public void setHexType(String hexType) { + this.hexType = hexType; + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/AddIntegrityVerificationFileReply.java b/header/src/main/java/org/zstack/header/core/encrypt/AddIntegrityVerificationFileReply.java new file mode 100644 index 00000000000..0943cccecac --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/AddIntegrityVerificationFileReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.core.encrypt; + +import org.zstack.header.message.MessageReply; + +/** + * @author hanyu.liang + * @date 2023/4/17 16:29 + */ +public class AddIntegrityVerificationFileReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/CovertSubClass.java b/header/src/main/java/org/zstack/header/core/encrypt/CovertSubClass.java new file mode 100644 index 00000000000..1a442611c06 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/CovertSubClass.java @@ -0,0 +1,18 @@ +package org.zstack.header.core.encrypt; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @Author: DaoDao + * @Date: 2023/3/9 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CovertSubClass { + String classSimpleName(); + String columnName(); + String columnValue(); +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/CovertSubClasses.java b/header/src/main/java/org/zstack/header/core/encrypt/CovertSubClasses.java new file mode 100644 index 00000000000..3e471646416 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/CovertSubClasses.java @@ -0,0 +1,17 @@ +package org.zstack.header.core.encrypt; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @Author: DaoDao + * @Date: 2023/3/9 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CovertSubClasses { + CovertSubClass[] value(); +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/ENCRYPT.java b/header/src/main/java/org/zstack/header/core/encrypt/ENCRYPT.java index 9e3083e36d9..3084555a7aa 100644 --- a/header/src/main/java/org/zstack/header/core/encrypt/ENCRYPT.java +++ b/header/src/main/java/org/zstack/header/core/encrypt/ENCRYPT.java @@ -8,6 +8,7 @@ /** * Created by mingjian.deng on 16/11/1. */ +@Deprecated @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ENCRYPT { diff --git a/header/src/main/java/org/zstack/header/core/encrypt/EncryptColumn.java b/header/src/main/java/org/zstack/header/core/encrypt/EncryptColumn.java index 3f346a383ba..d70754bfb71 100644 --- a/header/src/main/java/org/zstack/header/core/encrypt/EncryptColumn.java +++ b/header/src/main/java/org/zstack/header/core/encrypt/EncryptColumn.java @@ -4,6 +4,7 @@ import java.lang.annotation.Target; /** + * Integrity encrypted field, the field is not encrypted. * @Author: DaoDao * @Date: 2021/11/23 */ diff --git a/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityMetadataVO.java b/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityMetadataVO.java new file mode 100644 index 00000000000..8248802387b --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityMetadataVO.java @@ -0,0 +1,82 @@ +package org.zstack.header.core.encrypt; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class EncryptEntityMetadataVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + private String entityName; + + @Column + private String columnName; + + @Column + @Enumerated(EnumType.STRING) + private EncryptEntityState state; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getEntityName() { + return entityName; + } + + public void setEntityName(String entityName) { + this.entityName = entityName; + } + + public String getColumnName() { + return columnName; + } + + public void setColumnName(String columnName) { + this.columnName = columnName; + } + + public EncryptEntityState getState() { + return state; + } + + public void setState(EncryptEntityState state) { + this.state = state; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityMetadataVO_.java b/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityMetadataVO_.java new file mode 100644 index 00000000000..a43d8020fb7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityMetadataVO_.java @@ -0,0 +1,15 @@ +package org.zstack.header.core.encrypt; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(EncryptEntityMetadataVO.class) +public class EncryptEntityMetadataVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute entityName; + public static volatile SingularAttribute columnName; + public static volatile SingularAttribute state; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityState.java b/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityState.java new file mode 100644 index 00000000000..badf4174655 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/EncryptEntityState.java @@ -0,0 +1,8 @@ +package org.zstack.header.core.encrypt; + +public enum EncryptEntityState { + NewAdded, + Encrypting, + Encrypted, + NeedDecrypt +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/EncryptedFieldBundle.java b/header/src/main/java/org/zstack/header/core/encrypt/EncryptedFieldBundle.java new file mode 100644 index 00000000000..1a4107adced --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/EncryptedFieldBundle.java @@ -0,0 +1,53 @@ +package org.zstack.header.core.encrypt; + +/** + * @author hanyu.liang + * @date 2023/5/5 16:35 + */ +public class EncryptedFieldBundle { + private String encryptedType; + private String encryptedClass; + private String encryptedColumn; + private String conditionValue; + private String conditionKey; + + public String getEncryptedType() { + return encryptedType; + } + + public void setEncryptedType(String encryptedType) { + this.encryptedType = encryptedType; + } + + public String getEncryptedClass() { + return encryptedClass; + } + + public void setEncryptedClass(String encryptedClass) { + this.encryptedClass = encryptedClass; + } + + public String getEncryptedColumn() { + return encryptedColumn; + } + + public void setEncryptedColumn(String encryptedColumn) { + this.encryptedColumn = encryptedColumn; + } + + public String getConditionValue() { + return conditionValue; + } + + public void setConditionValue(String conditionValue) { + this.conditionValue = conditionValue; + } + + public String getConditionKey() { + return conditionKey; + } + + public void setConditionKey(String conditionKey) { + this.conditionKey = conditionKey; + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/EncryptionParamAllowed.java b/header/src/main/java/org/zstack/header/core/encrypt/EncryptionParamAllowed.java new file mode 100644 index 00000000000..24dc24c32fd --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/EncryptionParamAllowed.java @@ -0,0 +1,36 @@ +package org.zstack.header.core.encrypt; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface EncryptionParamAllowed { + /** + * Encrypted fields are not allowed. + * + * By default, except for the userTags/systemTags fields, + * all fields owned by {@link org.zstack.header.message.APIMessage} classes are not allowed + */ + String[] forbiddenFields() default {}; + + String ACTION_CHECK_USER_INFO = "checkUserInfo"; + String ACTION_PUT_USER_INFO_INTO_SYSTEM_TAG = "putUserInfoIntoSystemTag"; + + /** + * Check the result of parsing from the digital envelope + * + * - (Default) {@link #ACTION_CHECK_USER_INFO} + * checks whether the user tag in the digital envelope matches the user of the APIMessage session + * Mismatch will throw an error + * - {@link #ACTION_PUT_USER_INFO_INTO_SYSTEM_TAG} + * system places the user data in the envelope in the system tag, + * and this process will not generate errors and interrupts + * + * It is recommended to enable this option for all APIs + * that support digital envelopes except login + */ + String[] actions() default { ACTION_CHECK_USER_INFO }; +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/FileIntegrityVerificationVO.java b/header/src/main/java/org/zstack/header/core/encrypt/FileIntegrityVerificationVO.java new file mode 100644 index 00000000000..69295bddf8e --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/FileIntegrityVerificationVO.java @@ -0,0 +1,107 @@ +package org.zstack.header.core.encrypt; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * @author hanyu.liang + * @date 2023/4/7 16:26 + */ +@Entity +@Table +public class FileIntegrityVerificationVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + private String path; + + @Column + private String nodeType; //for managementNode, node="managementNode", for host, node="host" + + @Column + private String nodeUuid; //for managementNode, node=mnUUid, for host, node=hostUuid + + @Column + private String hexType; //eg: "md5","sha1","sha256","sha384","sha512" + + @Column + private String digest; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getNodeUuid() { + return nodeUuid; + } + + public void setNodeUuid(String nodeUuid) { + this.nodeUuid = nodeUuid; + } + + public String getHexType() { + return hexType; + } + + public void setHexType(String hexType) { + this.hexType = hexType; + } + + public String getDigest() { + return digest; + } + + public void setDigest(String digest) { + this.digest = digest; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/FileIntegrityVerificationVO_.java b/header/src/main/java/org/zstack/header/core/encrypt/FileIntegrityVerificationVO_.java new file mode 100644 index 00000000000..d7ea67e335f --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/FileIntegrityVerificationVO_.java @@ -0,0 +1,18 @@ +package org.zstack.header.core.encrypt; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +/** + * @author hanyu.liang + * @date 2023/4/7 16:27 + */ +@StaticMetamodel(FileIntegrityVerificationVO.class) +public class FileIntegrityVerificationVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute path; + public static volatile SingularAttribute nodeType; + public static volatile SingularAttribute nodeUuid; + public static volatile SingularAttribute hexType; + public static volatile SingularAttribute digest; +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/IntegrityVerificationResourceFactory.java b/header/src/main/java/org/zstack/header/core/encrypt/IntegrityVerificationResourceFactory.java new file mode 100644 index 00000000000..7a822def511 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/IntegrityVerificationResourceFactory.java @@ -0,0 +1,29 @@ +package org.zstack.header.core.encrypt; + +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.progress.TaskProgressRange; + +import java.util.List; +import java.util.Map; + +/** + * @author hanyu.liang + * @date 2023/4/10 15:35 + */ +public interface IntegrityVerificationResourceFactory { + String getResourceType(); + + void doIntegrityVerification(Integer integrityDataRangeInDays, TaskProgressRange taskProgressRange, Completion completion); + + void doCheckBatchResourceIntegrity(final List resourceUuids, ReturnValueCompletion> returnValueCompletion); + + default void upgradeExtension(){ + } + + default void doIntegrityAfterSaveDbRecord(Object entity) { + } + + default void doIntegrityAfterUpdateDbRecord(Object entity) { + } +} diff --git a/header/src/main/java/org/zstack/header/core/encrypt/RemoveIntegrityVerificationFileMsg.java b/header/src/main/java/org/zstack/header/core/encrypt/RemoveIntegrityVerificationFileMsg.java new file mode 100644 index 00000000000..5549f071527 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/RemoveIntegrityVerificationFileMsg.java @@ -0,0 +1,38 @@ +package org.zstack.header.core.encrypt; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @author hanyu.liang + * @date 2023/4/17 16:33 + */ +public class RemoveIntegrityVerificationFileMsg extends NeedReplyMessage { + private String nodeType; + private String nodeUuid; + private String path; + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getNodeUuid() { + return nodeUuid; + } + + public void setNodeUuid(String nodeUuid) { + this.nodeUuid = nodeUuid; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} + diff --git a/header/src/main/java/org/zstack/header/core/encrypt/RemoveIntegrityVerificationFileReply.java b/header/src/main/java/org/zstack/header/core/encrypt/RemoveIntegrityVerificationFileReply.java new file mode 100644 index 00000000000..588e65dc6c1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/encrypt/RemoveIntegrityVerificationFileReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.core.encrypt; + +import org.zstack.header.message.MessageReply; + +/** + * @author hanyu.liang + * @date 2023/4/17 16:33 + */ +public class RemoveIntegrityVerificationFileReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversEvent.java b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversEvent.java new file mode 100644 index 00000000000..f41883cc381 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversEvent.java @@ -0,0 +1,17 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDeletePluginDriversEvent extends APIEvent { + public APIDeletePluginDriversEvent() { } + + public APIDeletePluginDriversEvent(String apiId) { + super(apiId); + } + + public static APIDeletePluginDriversEvent __example__() { + return new APIDeletePluginDriversEvent(); + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..c3d54078b5c --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.core.external.plugin + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "删除插件驱动器" + + field { + name "success" + desc "删除结果" + type "boolean" + since "5.3.20" + } + ref { + name "error" + path "org.zstack.header.core.external.plugin.APIDeletePluginDriversEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.20" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversMsg.java b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversMsg.java new file mode 100644 index 00000000000..4393f927f72 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversMsg.java @@ -0,0 +1,31 @@ +package org.zstack.header.core.external.plugin; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/external/plugins/{uuid}", + responseClass = APIDeletePluginDriversEvent.class, + method = HttpMethod.DELETE +) +public class APIDeletePluginDriversMsg extends APIDeleteMessage { + @APIParam(resourceType = PluginDriverVO.class, successIfResourceNotExisting = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public static APIDeletePluginDriversMsg __example__() { + APIDeletePluginDriversMsg msg = new APIDeletePluginDriversMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..9066b39da17 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIDeletePluginDriversMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.core.external.plugin + +import org.zstack.header.core.external.plugin.APIDeletePluginDriversEvent + +doc { + title "DeletePluginDrivers" + + category "external.plugin" + + desc """删除插件驱动器""" + + rest { + request { + url "DELETE /v1/external/plugins/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeletePluginDriversMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "deleteMode" + enclosedIn "" + desc "删除模式(Permissive / Enforcing,Permissive)" + location "body" + type "String" + optional true + since "5.3.20" + } + } + } + + response { + clz APIDeletePluginDriversEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversMsg.java b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversMsg.java new file mode 100644 index 00000000000..11754d4fa3a --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversMsg.java @@ -0,0 +1,22 @@ +package org.zstack.header.core.external.plugin; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +@AutoQuery(replyClass = APIQueryPluginDriversReply.class, inventoryClass = PluginDriverInventory.class) +@RestRequest( + path = "/external/plugins", + method = HttpMethod.GET, + responseClass = APIQueryPluginDriversReply.class +) +public class APIQueryPluginDriversMsg extends APIQueryMessage { + public static List __example__() { + return asList("name=test"); + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..0d77668f5f5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversMsgDoc_zh_cn.groovy @@ -0,0 +1,30 @@ +package org.zstack.header.core.external.plugin + +import org.zstack.header.core.external.plugin.APIQueryPluginDriversReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryPluginDrivers" + + category "external.plugin" + + desc """查询插件驱动器""" + + rest { + request { + url "GET /v1/external/plugins" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryPluginDriversMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryPluginDriversReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversReply.java b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversReply.java new file mode 100644 index 00000000000..043abb2e16a --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversReply.java @@ -0,0 +1,27 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.Collections; +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQueryPluginDriversReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryPluginDriversReply __example__() { + APIQueryPluginDriversReply reply = new APIQueryPluginDriversReply(); + PluginDriverInventory inv = new PluginDriverInventory(); + reply.setInventories(Collections.singletonList(inv)); + return reply; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..967fa11bcb7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIQueryPluginDriversReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.core.external.plugin + +import org.zstack.header.core.external.plugin.PluginDriverInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询插件驱动器" + + ref { + name "inventories" + path "org.zstack.header.core.external.plugin.APIQueryPluginDriversReply.inventories" + desc "插件驱动器列表" + type "List" + since "5.3.0" + clz PluginDriverInventory.class + } + field { + name "success" + desc "操作是否成功" + type "boolean" + since "5.3.0" + } + ref { + name "error" + path "org.zstack.header.core.external.plugin.APIQueryPluginDriversReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversEvent.java b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversEvent.java new file mode 100644 index 00000000000..f3d7970e087 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversEvent.java @@ -0,0 +1,17 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIRefreshPluginDriversEvent extends APIEvent { + public APIRefreshPluginDriversEvent() { } + + public APIRefreshPluginDriversEvent(String apiId) { + super(apiId); + } + + public static APIRefreshPluginDriversEvent __example__() { + return new APIRefreshPluginDriversEvent(); + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..784a83bace5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.core.external.plugin + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "刷新插件驱动器" + + field { + name "success" + desc "操作是否成功" + type "boolean" + since "5.3.0" + } + ref { + name "error" + path "org.zstack.header.core.external.plugin.APIRefreshPluginDriversEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversMsg.java b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversMsg.java new file mode 100644 index 00000000000..101acd50963 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversMsg.java @@ -0,0 +1,32 @@ +package org.zstack.header.core.external.plugin; + +import org.springframework.http.HttpMethod; +import org.zstack.header.core.external.service.APIReloadExternalServiceMsg; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/external/plugins", + isAction = true, + responseClass = APIRefreshPluginDriversEvent.class, + method = HttpMethod.PUT +) +public class APIRefreshPluginDriversMsg extends APIMessage { + @APIParam(required = false) + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static APIReloadExternalServiceMsg __example__() { + APIReloadExternalServiceMsg msg = new APIReloadExternalServiceMsg(); + msg.setName("prometheus"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..35e4fff9888 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/APIRefreshPluginDriversMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.core.external.plugin + +import org.zstack.header.core.external.plugin.APIRefreshPluginDriversEvent + +doc { + title "RefreshPluginDrivers" + + category "external.plugin" + + desc """刷新插件驱动器""" + + rest { + request { + url "PUT /v1/external/plugins" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIRefreshPluginDriversMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "refreshPluginDrivers" + desc "资源名称" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.0" + } + } + } + + response { + clz APIRefreshPluginDriversEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/DeletePluginDriversMsg.java b/header/src/main/java/org/zstack/header/core/external/plugin/DeletePluginDriversMsg.java new file mode 100644 index 00000000000..2873496cfda --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/DeletePluginDriversMsg.java @@ -0,0 +1,34 @@ +package org.zstack.header.core.external.plugin; + +import org.apache.commons.lang.StringUtils; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.NeedReplyMessage; + +public class DeletePluginDriversMsg extends NeedReplyMessage { + private String uuid; + private String deletionMode; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setDeletionMode(APIDeleteMessage.DeletionMode deletionMode) { + this.deletionMode = deletionMode.toString(); + } + + public APIDeleteMessage.DeletionMode getDeletionMode() { + return StringUtils.isEmpty(deletionMode) ? APIDeleteMessage.DeletionMode.Permissive : APIDeleteMessage.DeletionMode.valueOf(deletionMode); + } + + public String getDeletionModeString() { + return StringUtils.isEmpty(deletionMode) ? APIDeleteMessage.DeletionMode.Permissive.toString() : deletionMode; + } + + public void setDeletionMode(String deletionMode) { + this.deletionMode = deletionMode; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/DeletePluginDriversReply.java b/header/src/main/java/org/zstack/header/core/external/plugin/DeletePluginDriversReply.java new file mode 100644 index 00000000000..780fac1b165 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/DeletePluginDriversReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.message.MessageReply; + +public class DeletePluginDriversReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverInventory.java b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverInventory.java new file mode 100644 index 00000000000..4cfd3f89c9f --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverInventory.java @@ -0,0 +1,147 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.abstraction.OptionType; +import org.zstack.header.search.Inventory; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = PluginDriverVO.class) +public class PluginDriverInventory { + private String uuid; + private String name; + private String type; + private String vendor; + private String features; + private Collection optionTypes; + private boolean deleted; + private String license; + private String version; + private String description; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static PluginDriverInventory valueOf(PluginDriverVO vo) { + PluginDriverInventory inv = new PluginDriverInventory(); + inv.setUuid(vo.getUuid()); + inv.setName(vo.getName()); + inv.setVendor(vo.getVendor()); + inv.setFeatures(vo.getFeatures()); + inv.setType(vo.getType()); + inv.setLicense(vo.getLicense()); + inv.setVersion(vo.getVersion()); + inv.setDescription(vo.getDescription()); + inv.setOptionTypes(JSONObjectUtil.toCollection(vo.getOptionTypes(), ArrayList.class, OptionType.class)); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + inv.setDeleted(vo.isDeleted()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (PluginDriverVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public String getFeatures() { + return features; + } + + public void setFeatures(String features) { + this.features = features; + } + + public String getLicense() { + return license; + } + + public void setLicense(String license) { + this.license = license; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Collection getOptionTypes() { + return optionTypes; + } + + public void setOptionTypes(Collection optionTypes) { + this.optionTypes = optionTypes; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..f46f532b274 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverInventoryDoc_zh_cn.groovy @@ -0,0 +1,51 @@ +package org.zstack.header.core.external.plugin + + + +doc { + + title "插件驱动器" + + field { + name "name" + desc "资源名称" + type "String" + since "5.3.0" + } + field { + name "type" + desc "资源类型" + type "String" + since "5.3.0" + } + field { + name "vendor" + desc "插件供应商" + type "String" + since "5.3.0" + } + field { + name "features" + desc "插件特性" + type "String" + since "5.3.0" + } + field { + name "license" + desc "插件许可证" + type "String" + since "5.3.0" + } + field { + name "version" + desc "插件版本" + type "String" + since "5.3.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.3.0" + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverVO.java b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverVO.java new file mode 100644 index 00000000000..f1586aca36c --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverVO.java @@ -0,0 +1,163 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.vo.BaseResource; +import org.zstack.header.vo.ResourceVO; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import java.sql.Timestamp; + +@Entity +@Table +@BaseResource +public class PluginDriverVO extends ResourceVO { + @Column + private String name; + + @Column + private String type; + + @Column + private String vendor; + + @Column + private String license; + + @Column + private String version; + + @Column + private String description; + + @Column + private String features; + + @Column + private String optionTypes; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @Column + private boolean deleted = false; + + public PluginDriverVO() { + } + + public PluginDriverVO(PluginDriverVO other) { + this.uuid = other.uuid; + this.name = other.name; + this.vendor = other.vendor; + this.features = other.features; + this.license = other.license; + this.version = other.version; + this.description = other.description; + this.type = other.type; + this.optionTypes = other.optionTypes; + this.createDate = other.createDate; + this.lastOpDate = other.lastOpDate; + this.deleted = other.deleted; + } + + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + + @Override + public String getUuid() { + return uuid; + } + + @Override + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getFeatures() { + return features; + } + + public void setFeatures(String features) { + this.features = features; + } + + public String getLicense() { + return license; + } + + public void setLicense(String license) { + this.license = license; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOptionTypes() { + return optionTypes; + } + + public void setOptionTypes(String optionTypes) { + this.optionTypes = optionTypes; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverVO_.java b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverVO_.java new file mode 100644 index 00000000000..c79ce6ff7d2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriverVO_.java @@ -0,0 +1,20 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(PluginDriverVO.class) +public class PluginDriverVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute vendor; + public static volatile SingularAttribute version; + public static volatile SingularAttribute type; + public static volatile SingularAttribute features; + public static volatile SingularAttribute optionTypes; + public static volatile SingularAttribute deleted; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriversExtensionPoint.java b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriversExtensionPoint.java new file mode 100644 index 00000000000..0d31571c267 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/PluginDriversExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.errorcode.ErrorCode; + +public interface PluginDriversExtensionPoint { + ErrorCode validateDeletePluginDrivers(String pluginUuid); +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/RBACInfo.java b/header/src/main/java/org/zstack/header/core/external/plugin/RBACInfo.java new file mode 100644 index 00000000000..117a8ae28e1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/RBACInfo.java @@ -0,0 +1,35 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + + @Override + public void permissions() { + permissionBuilder() + .name("external-plugin") + .adminOnlyAPIs( + APIQueryPluginDriversMsg.class, + APIRefreshPluginDriversMsg.class, + APIDeletePluginDriversMsg.class + ).build(); + } + + @Override + public void contributeToRoles() { + roleContributorBuilder() + .roleName("other") + .actionsByPermissionName("external-plugin") + .build(); + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/RefreshPluginDriversMsg.java b/header/src/main/java/org/zstack/header/core/external/plugin/RefreshPluginDriversMsg.java new file mode 100644 index 00000000000..d5e3b892a23 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/RefreshPluginDriversMsg.java @@ -0,0 +1,15 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.message.NeedReplyMessage; + +public class RefreshPluginDriversMsg extends NeedReplyMessage { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/plugin/RefreshPluginDriversReply.java b/header/src/main/java/org/zstack/header/core/external/plugin/RefreshPluginDriversReply.java new file mode 100644 index 00000000000..eb02a336d0e --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/plugin/RefreshPluginDriversReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.core.external.plugin; + +import org.zstack.header.message.MessageReply; + +public class RefreshPluginDriversReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesMsg.java b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesMsg.java new file mode 100644 index 00000000000..24514986ecb --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesMsg.java @@ -0,0 +1,14 @@ +package org.zstack.header.core.external.service; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/external/services", + method = HttpMethod.GET, + responseClass = APIGetExternalServicesReply.class +) +public class APIGetExternalServicesMsg extends APISyncCallMessage { + +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..38c83096151 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.header.core.external.service + +import org.zstack.header.core.external.service.APIGetExternalServicesReply + +doc { + title "GetExternalServices" + + category "externalService" + + desc """获取External Services""" + + rest { + request { + url "GET /v1/external/services" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetExternalServicesMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIGetExternalServicesReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesReply.java b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesReply.java new file mode 100644 index 00000000000..9a29783bf7c --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesReply.java @@ -0,0 +1,32 @@ +package org.zstack.header.core.external.service; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.Collections; +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIGetExternalServicesReply extends APIReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIGetExternalServicesReply __example__() { + APIGetExternalServicesReply reply = new APIGetExternalServicesReply(); + ExternalServiceInventory inv = new ExternalServiceInventory(); + inv.setName("prometheus"); + inv.setStatus(ExternalServiceStatus.RUNNING.toString()); + ExternalServiceCapabilities cap = new ExternalServiceCapabilities(); + cap.setReloadConfig(true); + inv.setCapabilities(cap); + reply.setInventories(Collections.singletonList(inv)); + return reply; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..f4a08b0ea27 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIGetExternalServicesReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.core.external.service + +import org.zstack.header.core.external.service.ExternalServiceInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取External Services的返回" + + ref { + name "inventories" + path "org.zstack.header.core.external.service.APIGetExternalServicesReply.inventories" + desc "null" + type "List" + since "4.7.0" + clz ExternalServiceInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.core.external.service.APIGetExternalServicesReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceEvent.java b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceEvent.java new file mode 100644 index 00000000000..ec29acbad4e --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceEvent.java @@ -0,0 +1,17 @@ +package org.zstack.header.core.external.service; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIReloadExternalServiceEvent extends APIEvent { + public APIReloadExternalServiceEvent() { } + + public APIReloadExternalServiceEvent(String apiId) { + super(apiId); + } + + public static APIReloadExternalServiceEvent __example__() { + return new APIReloadExternalServiceEvent(); + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..6ec609b4707 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.core.external.service + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "重新加载External Services的返回" + + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.core.external.service.APIReloadExternalServiceEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceMsg.java b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceMsg.java new file mode 100644 index 00000000000..de3c8c0019f --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceMsg.java @@ -0,0 +1,31 @@ +package org.zstack.header.core.external.service; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/external/services", + isAction = true, + responseClass = APIReloadExternalServiceEvent.class, + method = HttpMethod.PUT +) +public class APIReloadExternalServiceMsg extends APIMessage { + @APIParam + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static APIReloadExternalServiceMsg __example__() { + APIReloadExternalServiceMsg msg = new APIReloadExternalServiceMsg(); + msg.setName("prometheus"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..686e0d2fa18 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/APIReloadExternalServiceMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.core.external.service + +import org.zstack.header.core.external.service.APIReloadExternalServiceEvent + +doc { + title "ReloadExternalService" + + category "externalService" + + desc """重新加载External Service""" + + rest { + request { + url "PUT /v1/external/services" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIReloadExternalServiceMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "reloadExternalService" + desc "资源名称" + location "body" + type "String" + optional false + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIReloadExternalServiceEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/core/external/service/ExporterConstant.java b/header/src/main/java/org/zstack/header/core/external/service/ExporterConstant.java new file mode 100644 index 00000000000..b9268425c9c --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/ExporterConstant.java @@ -0,0 +1,64 @@ +package org.zstack.header.core.external.service; + +import org.zstack.utils.path.PathUtil; + +import java.io.File; +import java.util.Optional; + +/** + * @author hanyu.liang + * @date 2024/10/30 17:07 + */ +public class ExporterConstant { + public static final String SYSTEMD_SERVICE_DIR = "/lib/systemd/system/"; + public static final String LOG_DIR = "/var/log/zstack/"; + public static final String PROCESS_EXPORTER_BIN_PATH = Optional + .ofNullable(PathUtil.findFileOnClassPath("tools/process_exporter")) + .map(File::getAbsolutePath) + .orElse(null); + + public static final String ZS_EXPORTER_BIN_PATH = Optional + .ofNullable(PathUtil.findFileOnClassPath("tools/zstack_service_exporter")) + .map(File::getAbsolutePath) + .orElse(null); + + public static final String PROCESS_EXPORTER_SERVICE_PATH = SYSTEMD_SERVICE_DIR + "process_exporter.service"; + public static final String ZS_EXPORTER_SERVICE_PATH = SYSTEMD_SERVICE_DIR + "zstack_service_exporter.service"; + public static final String PROCESS_EXPORTER_LOG_PATH = LOG_DIR + "process_exporter.log"; + public static final String ZS_EXPORTER_LOG_PATH = LOG_DIR + "zstack_service_exporter.log"; + public static final String PROCESS_EXPORTER_CONFIG_PATH = getProcessExporterYamlPath(); + public static final String ZS_EXPORTER_CONFIG_PATH = Optional + .ofNullable(PathUtil.findFileOnClassPath("zsExporter/zs_exporter_config.yaml")) + .map(File::getAbsolutePath) + .orElse(null); + public static final String ZS_HOST_EXPORTER_CONFIG_PATH = Optional + .ofNullable(PathUtil.findFileOnClassPath("zsExporter/zs_host_exporter_config.yaml")) + .map(File::getAbsolutePath) + .orElse(null); + + private static String getProcessExporterYamlPath() { + String arch = System.getProperty("os.arch"); + switch (arch) { + case "aarch64": + return Optional + .ofNullable(PathUtil.findFileOnClassPath("zsExporter/process_exporter_config_aarch64.yaml")) + .map(File::getAbsolutePath) + .orElse(null); + default: + return Optional + .ofNullable(PathUtil.findFileOnClassPath("zsExporter/process_exporter_config.yaml")) + .map(File::getAbsolutePath) + .orElse(null); + } + } + + public static boolean isZSExporterInstalled() { + return ExporterConstant.ZS_EXPORTER_BIN_PATH != null + && ExporterConstant.ZS_EXPORTER_CONFIG_PATH != null; + } + + public static boolean isProcessExporterInstalled() { + return ExporterConstant.PROCESS_EXPORTER_BIN_PATH != null + && ExporterConstant.PROCESS_EXPORTER_CONFIG_PATH != null; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceCapabilities.java b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceCapabilities.java new file mode 100644 index 00000000000..f5605663cca --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceCapabilities.java @@ -0,0 +1,13 @@ +package org.zstack.header.core.external.service; + +public class ExternalServiceCapabilities { + private boolean reloadConfig = false; + + public boolean isReloadConfig() { + return reloadConfig; + } + + public void setReloadConfig(boolean reloadConfig) { + this.reloadConfig = reloadConfig; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceCapabilitiesDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceCapabilitiesDoc_zh_cn.groovy new file mode 100644 index 00000000000..62805bbcd84 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceCapabilitiesDoc_zh_cn.groovy @@ -0,0 +1,15 @@ +package org.zstack.header.core.external.service + + + +doc { + + title "External Service的功能描述" + + field { + name "reloadConfig" + desc "支持重新加载配置" + type "boolean" + since "4.7.0" + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceInventory.java b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceInventory.java new file mode 100644 index 00000000000..e1b14c73baa --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceInventory.java @@ -0,0 +1,41 @@ +package org.zstack.header.core.external.service; + +public class ExternalServiceInventory { + private String name; + private String status; + private ExternalServiceCapabilities capabilities; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public ExternalServiceCapabilities getCapabilities() { + return capabilities; + } + + public void setCapabilities(ExternalServiceCapabilities capabilities) { + this.capabilities = capabilities; + } + + public static ExternalServiceInventory __example__() { + ExternalServiceInventory inv = new ExternalServiceInventory(); + inv.setName("prometheus"); + inv.setStatus(ExternalServiceStatus.RUNNING.toString()); + ExternalServiceCapabilities cap = new ExternalServiceCapabilities(); + cap.setReloadConfig(true); + inv.setCapabilities(cap); + return inv; + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..d885ab95d85 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceInventoryDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.core.external.service + +import org.zstack.header.core.external.service.ExternalServiceCapabilities + +doc { + + title "External Service的数据结构" + + field { + name "name" + desc "资源名称" + type "String" + since "4.7.0" + } + field { + name "status" + desc "服务状态" + type "String" + since "4.7.0" + } + ref { + name "capabilities" + path "org.zstack.header.core.external.service.ExternalServiceInventory.capabilities" + desc "External Service的功能描述" + type "ExternalServiceCapabilities" + since "4.7.0" + clz ExternalServiceCapabilities.class + } +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceStatus.java b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceStatus.java new file mode 100644 index 00000000000..5294bb37f81 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/ExternalServiceStatus.java @@ -0,0 +1,6 @@ +package org.zstack.header.core.external.service; + +public enum ExternalServiceStatus { + RUNNING, + STOPPED +} diff --git a/header/src/main/java/org/zstack/header/core/external/service/RBACInfo.java b/header/src/main/java/org/zstack/header/core/external/service/RBACInfo.java new file mode 100644 index 00000000000..21b5c6b03e0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/external/service/RBACInfo.java @@ -0,0 +1,30 @@ +package org.zstack.header.core.external.service; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + + @Override + public void permissions() { + permissionBuilder() + .adminOnlyAPIs( + APIGetExternalServicesMsg.class, + APIReloadExternalServiceMsg.class + ).build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + + } +} diff --git a/header/src/main/java/org/zstack/header/core/progress/APIGetTaskProgressMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/progress/APIGetTaskProgressMsgDoc_zh_cn.groovy index 6338359213e..531e8c08667 100644 --- a/header/src/main/java/org/zstack/header/core/progress/APIGetTaskProgressMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/core/progress/APIGetTaskProgressMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "1.11" - } column { name "all" @@ -39,7 +38,6 @@ doc { type "boolean" optional true since "1.11" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "1.11" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "1.11" - } } } diff --git a/header/src/main/java/org/zstack/header/core/progress/ChainInfo.java b/header/src/main/java/org/zstack/header/core/progress/ChainInfo.java index bb07ad06050..2cb11b1fbb6 100644 --- a/header/src/main/java/org/zstack/header/core/progress/ChainInfo.java +++ b/header/src/main/java/org/zstack/header/core/progress/ChainInfo.java @@ -1,5 +1,8 @@ package org.zstack.header.core.progress; +import org.zstack.header.message.NoJsonSchema; +import org.zstack.header.rest.APINoSee; + import java.util.ArrayList; import java.util.List; @@ -9,6 +12,8 @@ public class ChainInfo { private List runningTask = new ArrayList<>(); private List pendingTask = new ArrayList<>(); + @APINoSee + private long maxThreadNum; public void setPendingTask(List pendingTask) { this.pendingTask = pendingTask; @@ -33,4 +38,25 @@ public void addRunningTask(RunningTaskInfo task) { public void addPendingTask(PendingTaskInfo pendingTask) { this.pendingTask.add(pendingTask); } + + public void setMaxThreadNum(long maxThreadNum) { + this.maxThreadNum = maxThreadNum; + } + + public long getMaxThreadNum() { + return maxThreadNum; + } + + @Override + public String toString() { + StringBuilder tb = new StringBuilder(); + tb.append(String.format("\nRUNNING TASK NUMBER: %s", runningTask.size())); + tb.append(String.format("\nPENDING TASK NUMBER: %s", pendingTask.size())); + tb.append(String.format("\nASYNC LEVEL: %s", maxThreadNum)); + + runningTask.forEach(tb::append); + pendingTask.forEach(tb::append); + + return tb.toString(); + } } diff --git a/header/src/main/java/org/zstack/header/core/progress/SingleFlightChainInfo.java b/header/src/main/java/org/zstack/header/core/progress/SingleFlightChainInfo.java new file mode 100644 index 00000000000..7099d35b2cc --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/progress/SingleFlightChainInfo.java @@ -0,0 +1,33 @@ +package org.zstack.header.core.progress; + +import java.util.ArrayList; +import java.util.List; + +public class SingleFlightChainInfo { + private List runningTask = new ArrayList<>(); + private List pendingTask = new ArrayList<>(); + + public void setPendingTask(List pendingTask) { + this.pendingTask = pendingTask; + } + + public void setRunningTask(List runningTask) { + this.runningTask = runningTask; + } + + public List getRunningTask() { + return runningTask; + } + + public List getPendingTask() { + return pendingTask; + } + + public void addRunningTask(RunningTaskInfo task) { + this.runningTask.add(task); + } + + public void addPendingTask(PendingTaskInfo pendingTask) { + this.pendingTask.add(pendingTask); + } +} diff --git a/header/src/main/java/org/zstack/header/core/progress/TaskProgressInventory.java b/header/src/main/java/org/zstack/header/core/progress/TaskProgressInventory.java index 69d18dc078c..aa8c0f6db7e 100755 --- a/header/src/main/java/org/zstack/header/core/progress/TaskProgressInventory.java +++ b/header/src/main/java/org/zstack/header/core/progress/TaskProgressInventory.java @@ -17,6 +17,7 @@ public class TaskProgressInventory { private LinkedHashMap opaque; private Long time; private List subTasks; + private String arguments; public TaskProgressInventory() { } @@ -30,6 +31,15 @@ public TaskProgressInventory(TaskProgressVO vo) { } taskName = vo.getTaskName(); time = vo.getTime(); + arguments = vo.getArguments(); + } + + public String getArguments() { + return arguments; + } + + public void setArguments(String arguments) { + this.arguments = arguments; } public String getTaskName() { diff --git a/header/src/main/java/org/zstack/header/core/progress/TaskProgressVO_.java b/header/src/main/java/org/zstack/header/core/progress/TaskProgressVO_.java index b88ae50233c..936891f1787 100755 --- a/header/src/main/java/org/zstack/header/core/progress/TaskProgressVO_.java +++ b/header/src/main/java/org/zstack/header/core/progress/TaskProgressVO_.java @@ -18,6 +18,7 @@ public class TaskProgressVO_ { public static volatile SingularAttribute content; public static volatile SingularAttribute arguments; public static volatile SingularAttribute managementUuid; + public static volatile SingularAttribute opaque; public static volatile SingularAttribute timeToDelete; public static volatile SingularAttribute time; } diff --git a/header/src/main/java/org/zstack/header/core/trash/CleanTrashResult.java b/header/src/main/java/org/zstack/header/core/trash/CleanTrashResult.java index 6a52e68777c..d4025acbe1e 100644 --- a/header/src/main/java/org/zstack/header/core/trash/CleanTrashResult.java +++ b/header/src/main/java/org/zstack/header/core/trash/CleanTrashResult.java @@ -3,6 +3,7 @@ import org.zstack.header.rest.SDK; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -10,7 +11,7 @@ */ @SDK public class CleanTrashResult { - private List resourceUuids = new ArrayList<>(); + private List resourceUuids = Collections.synchronizedList(new ArrayList<>()); private List details = new ArrayList<>(); private Long size = 0L; diff --git a/header/src/main/java/org/zstack/header/core/trash/TrashCleanupResult.java b/header/src/main/java/org/zstack/header/core/trash/TrashCleanupResult.java new file mode 100644 index 00000000000..52d2794203d --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/trash/TrashCleanupResult.java @@ -0,0 +1,89 @@ +package org.zstack.header.core.trash; + +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.rest.SDK; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +@SDK +public class TrashCleanupResult { + private String resourceUuid; + private boolean success = true; + private ErrorCode error; + private long trashId; + private Long size = 0L; + + public TrashCleanupResult() { + + } + + public TrashCleanupResult(String resourceUuid, long trashId, long size) { + this.resourceUuid = resourceUuid; + this.trashId = trashId; + this.size = size; + } + + public TrashCleanupResult(String resourceUuid, long trashId, ErrorCode error) { + this.resourceUuid = resourceUuid; + this.trashId = trashId; + this.success = false; + this.error = error; + } + + public TrashCleanupResult(long trashId) { + this.trashId = trashId; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public ErrorCode getError() { + return error; + } + + public void setError(ErrorCode error) { + this.error = error; + } + + public long getTrashId() { + return trashId; + } + + public void setTrashId(long trashId) { + this.trashId = trashId; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public static CleanTrashResult buildCleanTrashResult(List results) { + CleanTrashResult cleanTrashResult = new CleanTrashResult(); + cleanTrashResult.setResourceUuids(results.stream() + .filter(it -> it.getError() == null).map(TrashCleanupResult::getResourceUuid) + .filter(Objects::nonNull).collect(Collectors.toList())); + cleanTrashResult.setDetails(results.stream().map(TrashCleanupResult::getError) + .filter(Objects::nonNull).map(ErrorCode::getDetails).collect(Collectors.toList())); + cleanTrashResult.setSize(results.stream().mapToLong(TrashCleanupResult::getSize).sum()); + return cleanTrashResult; + } +} diff --git a/header/src/main/java/org/zstack/header/core/trash/TrashCleanupResultDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/trash/TrashCleanupResultDoc_zh_cn.groovy new file mode 100644 index 00000000000..c34c83f9281 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/trash/TrashCleanupResultDoc_zh_cn.groovy @@ -0,0 +1,42 @@ +package org.zstack.header.core.trash + +import org.zstack.header.errorcode.ErrorCode +import java.lang.Long + +doc { + + title "清理回收站数据返回信息" + + field { + name "resourceUuid" + desc "清理数据对应的UUID" + type "String" + since "4.7.0" + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.core.trash.TrashCleanupResult.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } + field { + name "trashId" + desc "清理数据对应的ID" + type "long" + since "4.7.0" + } + field { + name "size" + desc "清理数据对应的大小" + type "Long" + since "4.7.0" + } +} diff --git a/header/src/main/java/org/zstack/header/core/webhooks/APICreateWebhookMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/webhooks/APICreateWebhookMsgDoc_zh_cn.groovy index 51ad341e2c2..5ab5376ffe2 100644 --- a/header/src/main/java/org/zstack/header/core/webhooks/APICreateWebhookMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/core/webhooks/APICreateWebhookMsgDoc_zh_cn.groovy @@ -7,7 +7,7 @@ doc { category "webhook" - desc """在这里填写API描述""" + desc """创建Webhook""" rest { request { @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "type" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "opaque" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "4.2.0" } } } diff --git a/header/src/main/java/org/zstack/header/core/webhooks/APIDeleteWebhookMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/webhooks/APIDeleteWebhookMsgDoc_zh_cn.groovy index 4336000652d..d6e73ced8df 100644 --- a/header/src/main/java/org/zstack/header/core/webhooks/APIDeleteWebhookMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/core/webhooks/APIDeleteWebhookMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/core/webhooks/APIQueryWebhookMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/webhooks/APIQueryWebhookMsgDoc_zh_cn.groovy index a52f7d94c64..5b454c8e402 100644 --- a/header/src/main/java/org/zstack/header/core/webhooks/APIQueryWebhookMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/core/webhooks/APIQueryWebhookMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.core.webhooks import org.zstack.header.core.webhooks.APIQueryWebhookReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryWebhook" diff --git a/header/src/main/java/org/zstack/header/core/webhooks/APIUpdateWebhookMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/core/webhooks/APIUpdateWebhookMsgDoc_zh_cn.groovy index af032261c87..f5113034adf 100644 --- a/header/src/main/java/org/zstack/header/core/webhooks/APIUpdateWebhookMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/core/webhooks/APIUpdateWebhookMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "opaque" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/core/workflow/FlowChain.java b/header/src/main/java/org/zstack/header/core/workflow/FlowChain.java index 2b8c948af72..47f8d04e2f9 100755 --- a/header/src/main/java/org/zstack/header/core/workflow/FlowChain.java +++ b/header/src/main/java/org/zstack/header/core/workflow/FlowChain.java @@ -23,6 +23,8 @@ public interface FlowChain { FlowChain error(FlowErrorHandler handler); + FlowChain ctxHandler(FlowContextHandler handler); + FlowChain Finally(FlowFinallyHandler handler); FlowChain setData(Map data); @@ -44,4 +46,6 @@ public interface FlowChain { FlowChain allowEmptyFlow(); void allowWatch(); + + void disableDebugLog(); } diff --git a/header/src/main/java/org/zstack/header/core/workflow/FlowContextHandler.java b/header/src/main/java/org/zstack/header/core/workflow/FlowContextHandler.java new file mode 100644 index 00000000000..f2f1842c968 --- /dev/null +++ b/header/src/main/java/org/zstack/header/core/workflow/FlowContextHandler.java @@ -0,0 +1,14 @@ +package org.zstack.header.core.workflow; + +import org.zstack.header.errorcode.ErrorCode; + +public interface FlowContextHandler { + String getJobUuid(); + void saveContext(Flow toRun); + boolean cancelled(); + ErrorCode getCancelError(); + boolean skipRollback(ErrorCode errorCode); + default boolean skipFlow(Flow toRun) { + return false; + } +} diff --git a/header/src/main/java/org/zstack/header/errorcode/ErrorCode.java b/header/src/main/java/org/zstack/header/errorcode/ErrorCode.java index 15e3bcceaa0..0d1dbf94bba 100755 --- a/header/src/main/java/org/zstack/header/errorcode/ErrorCode.java +++ b/header/src/main/java/org/zstack/header/errorcode/ErrorCode.java @@ -1,6 +1,7 @@ package org.zstack.header.errorcode; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.message.NoJsonSchema; import org.zstack.header.rest.APINoSee; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.string.ErrorCodeElaboration; @@ -20,6 +21,7 @@ public class ErrorCode implements Serializable, Cloneable { private ErrorCodeElaboration messages; private String cost; private ErrorCode cause; + @NoJsonSchema private LinkedHashMap opaque; public LinkedHashMap getOpaque() { @@ -37,6 +39,11 @@ public void putToOpaque(String key, Object value) { opaque.put(key, value); } + public ErrorCode withOpaque(String key, Object value) { + putToOpaque(key,value); + return this; + } + public Object getFromOpaque(String key) { return opaque == null ? null : opaque.get(key); } @@ -195,12 +202,12 @@ public ErrorCode getRootCause() { } public String getRootCauseDetails() { - ErrorCode root = getRootCause(); - if (root.getDetails() == null) { - return root.getDescription(); - } else { - return root.getDetails(); + if (cause == null) { + return getDetails() != null ? getDetails() : getDescription(); } + + ErrorCode root = getRootCause(); + return root.getReadableDetails(); } public ErrorCodeElaboration getMessages() { diff --git a/header/src/main/java/org/zstack/header/errorcode/ErrorCodeList.java b/header/src/main/java/org/zstack/header/errorcode/ErrorCodeList.java index 858d345ab3d..8a0082a2f67 100755 --- a/header/src/main/java/org/zstack/header/errorcode/ErrorCodeList.java +++ b/header/src/main/java/org/zstack/header/errorcode/ErrorCodeList.java @@ -1,5 +1,7 @@ package org.zstack.header.errorcode; +import org.apache.commons.collections.CollectionUtils; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -65,17 +67,17 @@ public int hashCode() { public String getReadableDetails() { ErrorCodeList root = this; StringBuffer errorBuf = new StringBuffer(); - if (root.causes != null && !root.causes.isEmpty()) { + if (CollectionUtils.isNotEmpty(root.causes)) { root.causes.forEach(cause -> { if (errorBuf.length() > 0) { errorBuf.append(","); } errorBuf.append(getReadableDetails(cause)); }); - } else { - return super.getReadableDetails(); + return errorBuf.toString().trim(); } - return errorBuf.toString().trim(); + + return super.getReadableDetails(); } private String getReadableDetails(ErrorCode errCode) { diff --git a/header/src/main/java/org/zstack/header/errorcode/ErrorableValue.java b/header/src/main/java/org/zstack/header/errorcode/ErrorableValue.java new file mode 100644 index 00000000000..96728a26735 --- /dev/null +++ b/header/src/main/java/org/zstack/header/errorcode/ErrorableValue.java @@ -0,0 +1,29 @@ +package org.zstack.header.errorcode; + +import java.util.Objects; + +/** + * Created by Wenhao.Zhang on 22/11/21 + */ +public class ErrorableValue { + public final T result; + public final ErrorCode error; + + public static ErrorableValue of(T result) { + return new ErrorableValue<>(result, null); + } + + public static ErrorableValue ofErrorCode(ErrorCode error) { + return new ErrorableValue<>(null, + Objects.requireNonNull(error, "errorCode in ErrorableValue can not be null")); + } + + protected ErrorableValue(T result, ErrorCode error) { + this.result = result; + this.error = error; + } + + public boolean isSuccess() { + return error == null; + } +} diff --git a/header/src/main/java/org/zstack/header/errorcode/JobResultError.java b/header/src/main/java/org/zstack/header/errorcode/JobResultError.java index 4aa3b9c5432..d98edcb5784 100644 --- a/header/src/main/java/org/zstack/header/errorcode/JobResultError.java +++ b/header/src/main/java/org/zstack/header/errorcode/JobResultError.java @@ -1,7 +1,11 @@ package org.zstack.header.errorcode; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.zstack.utils.string.ErrorCodeElaboration; +import java.util.stream.Collectors; + /** * Created by mingjian.deng on 2020/3/25. */ @@ -18,11 +22,32 @@ public JobResultError(ErrorCodeElaboration message, String detail) { } public static JobResultError valueOf(ErrorCode error) { + if (error instanceof ErrorCodeList && !CollectionUtils.isEmpty(((ErrorCodeList) error).getCauses())) { + return valueOf((ErrorCodeList) error); + } + return parseErrorCode(error); + } + + private static JobResultError parseErrorCode(ErrorCode error) { JobResultError result = new JobResultError(error.getMessages(), error.getDetails()); result.setCause(error.getRootCauseDetails()); return result; } + public static JobResultError valueOf(ErrorCodeList error) { + if (error.getMessages() != null || error.getDetails() != null || CollectionUtils.isEmpty(error.getCauses())) { + return parseErrorCode(error); + } + if (error.getCauses().size() == 1) { + return JobResultError.valueOf(error.getCauses().get(0)); + } + + JobResultError result = new JobResultError(error.getMessages(), error.getDetails()); + result.setCause(StringUtils.join( + error.getCauses().stream().map(JobResultError::valueOf).collect(Collectors.toList()), "; ")); + return result; + } + public ErrorCodeElaboration getMessage() { return message; } diff --git a/header/src/main/java/org/zstack/header/exception/SerialVersionUID.java b/header/src/main/java/org/zstack/header/exception/SerialVersionUID.java index 36c44925160..ea5f2b5d137 100755 --- a/header/src/main/java/org/zstack/header/exception/SerialVersionUID.java +++ b/header/src/main/java/org/zstack/header/exception/SerialVersionUID.java @@ -1,7 +1,7 @@ package org.zstack.header.exception; public interface SerialVersionUID { - public static final long Base = 0x564D4F70 << 32; + public static final long Base = (long) 0x564D4F70 << 32; public static final long CloudRuntimeException = Base | 0x01; public static final long CloudConfigureFailException = Base | (0x01 << 1); diff --git a/header/src/main/java/org/zstack/header/file/FileDesc.java b/header/src/main/java/org/zstack/header/file/FileDesc.java new file mode 100644 index 00000000000..27925c2d740 --- /dev/null +++ b/header/src/main/java/org/zstack/header/file/FileDesc.java @@ -0,0 +1,37 @@ +package org.zstack.header.file; + +public class FileDesc { + String path; + String md5; + long lastModified; + + public FileDesc(String path, String md5, long lastModified) { + this.path = path; + this.md5 = md5; + this.lastModified = lastModified; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getMd5() { + return md5; + } + + public void setMd5(String md5) { + this.md5 = md5; + } + + public long getLastModified() { + return lastModified; + } + + public void setLastModified(long lastModified) { + this.lastModified = lastModified; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIChangeHostStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIChangeHostStateMsgDoc_zh_cn.groovy index 2e88853f322..996f2f641c8 100644 --- a/header/src/main/java/org/zstack/header/host/APIChangeHostStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIChangeHostStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeEvent.java b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeEvent.java new file mode 100644 index 00000000000..c75b21c4ed2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeEvent.java @@ -0,0 +1,34 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * Created by boce.wang on 10/24/2024. + */ +@RestResponse(allTo = "inventory") +public class APICreateHostNetworkServiceTypeEvent extends APIEvent { + private HostNetworkLabelInventory inventory; + + public APICreateHostNetworkServiceTypeEvent(String apiId) { + super(apiId); + } + + public APICreateHostNetworkServiceTypeEvent() { + super(null); + } + + public HostNetworkLabelInventory getInventory() { + return inventory; + } + + public void setInventory(HostNetworkLabelInventory inventory) { + this.inventory = inventory; + } + + public static APICreateHostNetworkServiceTypeEvent __example__() { + APICreateHostNetworkServiceTypeEvent event = new APICreateHostNetworkServiceTypeEvent(); + event.setInventory(new HostNetworkLabelInventory()); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..783f174058c --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostNetworkLabelInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "在这里输入结构的名称" + + ref { + name "inventory" + path "org.zstack.header.host.APICreateHostNetworkServiceTypeEvent.inventory" + desc "null" + type "HostNetworkLabelInventory" + since "5.2.1" + clz HostNetworkLabelInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.2.1" + } + ref { + name "error" + path "org.zstack.header.host.APICreateHostNetworkServiceTypeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.1" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeMsg.java b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeMsg.java new file mode 100644 index 00000000000..fc903f548f6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeMsg.java @@ -0,0 +1,63 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +/** + * Created by boce.wang on 10/24/2024. + */ +@TagResourceType(HostNetworkLabelVO.class) +@Action(category = HostConstant.ACTION_CATEGORY) +@RestRequest( + path = "/hosts/service-types", + method = HttpMethod.POST, + responseClass = APICreateHostNetworkServiceTypeEvent.class, + parameterName = "params" +) +public class APICreateHostNetworkServiceTypeMsg extends APICreateMessage implements APIAuditor { + @APIParam(maxLength = 128, nonempty = true, noTrim = true) + private String serviceType; + + @APIParam(required = false, nonempty = true) + private boolean system = false; + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public boolean isSystem() { + return system; + } + + public void setSystem(boolean system) { + this.system = system; + } + + public static APICreateHostNetworkServiceTypeMsg __example__() { + APICreateHostNetworkServiceTypeMsg msg = new APICreateHostNetworkServiceTypeMsg(); + msg.setServiceType("ManagementNetwork"); + msg.setSystem(true); + return msg; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + String resUuid = ""; + if (rsp.isSuccess()) { + APICreateHostNetworkServiceTypeEvent evt = (APICreateHostNetworkServiceTypeEvent) rsp; + resUuid = evt.getInventory().getUuid(); + } + return new Result(resUuid, HostNetworkLabelVO.class); + } +} diff --git a/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..91795b2339d --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APICreateHostNetworkServiceTypeMsgDoc_zh_cn.groovy @@ -0,0 +1,85 @@ +package org.zstack.header.host + +import org.zstack.header.host.APICreateHostNetworkServiceTypeEvent + +doc { + title "CreateHostNetworkServiceType" + + category "host" + + desc """在这里填写API描述""" + + rest { + request { + url "POST /v1/hosts/service-types" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateHostNetworkServiceTypeMsg.class + + desc """""" + + params { + + column { + name "serviceType" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "5.2.1" + } + column { + name "system" + enclosedIn "params" + desc "" + location "body" + type "boolean" + optional true + since "5.2.1" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.2.1" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.2.1" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.2.1" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.2.1" + } + } + } + + response { + clz APICreateHostNetworkServiceTypeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIDeleteHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIDeleteHostMsgDoc_zh_cn.groovy index 4efa59f0fdd..51700304fb1 100644 --- a/header/src/main/java/org/zstack/header/host/APIDeleteHostMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIDeleteHostMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeEvent.java b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeEvent.java new file mode 100644 index 00000000000..c402bd45b62 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeEvent.java @@ -0,0 +1,23 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * Created by boce.wang on 10/25/2024. + */ +@RestResponse +public class APIDeleteHostNetworkServiceTypeEvent extends APIEvent { + + public APIDeleteHostNetworkServiceTypeEvent() { + } + + public APIDeleteHostNetworkServiceTypeEvent(String apiId) { + super(apiId); + } + public static APIDeleteHostNetworkServiceTypeEvent __example__() { + APIDeleteHostNetworkServiceTypeEvent event = new APIDeleteHostNetworkServiceTypeEvent(); + event.setSuccess(true); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..5a1598bd7a4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.host + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "在这里输入结构的名称" + + field { + name "success" + desc "" + type "boolean" + since "5.2.1" + } + ref { + name "error" + path "org.zstack.header.host.APIDeleteHostNetworkServiceTypeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.1" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeMsg.java b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeMsg.java new file mode 100644 index 00000000000..896222cf1f3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeMsg.java @@ -0,0 +1,35 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * Created by boce.wang on 10/25/2024. + */ +@Action(category = HostConstant.ACTION_CATEGORY) +@RestRequest( + path = "/hosts/service-types/{uuid}", + method = HttpMethod.DELETE, + responseClass = APIDeleteHostNetworkServiceTypeEvent.class +) +public class APIDeleteHostNetworkServiceTypeMsg extends APIDeleteMessage { + @APIParam(resourceType = HostNetworkLabelVO.class, successIfResourceNotExisting = true, operationTarget = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public static APIDeleteHostNetworkServiceTypeMsg __example__() { + APIDeleteHostNetworkServiceTypeMsg msg = new APIDeleteHostNetworkServiceTypeMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..715f9294c35 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIDeleteHostNetworkServiceTypeMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIDeleteHostNetworkServiceTypeEvent + +doc { + title "DeleteHostNetworkServiceType" + + category "host" + + desc """在这里填写API描述""" + + rest { + request { + url "DELETE /v1/hosts/service-types/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeleteHostNetworkServiceTypeMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.2.1" + } + column { + name "deleteMode" + enclosedIn "" + desc "删除模式(Permissive / Enforcing,Permissive)" + location "body" + type "String" + optional true + since "5.2.1" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.2.1" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.2.1" + } + } + } + + response { + clz APIDeleteHostNetworkServiceTypeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusEvent.java b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusEvent.java new file mode 100644 index 00000000000..ce499688ba9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusEvent.java @@ -0,0 +1,40 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @Author : jingwang + * @create 2023/4/18 9:51 AM + */ +@RestResponse(fieldsTo = "all") +public class APIGetHostPowerStatusEvent extends APIEvent { + HostIpmiInventory inventory; + + public APIGetHostPowerStatusEvent() { + } + + public APIGetHostPowerStatusEvent(String apiId) { + super(apiId); + } + + public HostIpmiInventory getInventory() { + return inventory; + } + + public void setInventory(HostIpmiInventory inventory) { + this.inventory = inventory; + } + + public static APIGetHostPowerStatusEvent __example__() { + APIGetHostPowerStatusEvent event = new APIGetHostPowerStatusEvent(); + HostIpmiInventory hi = new HostIpmiInventory (); + hi.setIpmiAddress("192.168.0.1"); + hi.setIpmiPort(623); + hi.setIpmiUsername("admin"); + hi.setIpmiPassword("password"); + hi.setIpmiPowerStatus(HostPowerStatus.POWER_ON.toString()); + event.setInventory(hi); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..8bce6e2b192 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostIpmiInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取物理机最新电源状态消息回复" + + ref { + name "inventory" + path "org.zstack.header.host.APIGetHostPowerStatusEvent.inventory" + desc "物理机IPMI信息" + type "HostIpmiInventory" + since "4.7.0" + clz HostIpmiInventory.class + } + field { + name "success" + desc "是否成功" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.host.APIGetHostPowerStatusEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusMsg.java b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusMsg.java new file mode 100644 index 00000000000..ab8b2f5760b --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusMsg.java @@ -0,0 +1,51 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @Author : jingwang + * @create 2023/4/14 5:27 PM + */ +@RestRequest( + path = "/hosts/power/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIGetHostPowerStatusEvent.class, + isAction = true +) +public class APIGetHostPowerStatusMsg extends APIMessage implements HostMessage { + @APIParam(nonempty = true, resourceType = HostVO.class) + private String uuid; + @APIParam(required = false, validValues = {"AUTO","AGENT","IPMI"}) + private String method = HostPowerManagementMethod.AUTO.toString(); + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + @Override + public String getHostUuid() { + return uuid; + } + + public static APIGetHostPowerStatusMsg __example__() { + APIGetHostPowerStatusMsg msg = new APIGetHostPowerStatusMsg(); + msg.setUuid(uuid()); + msg.setMethod(HostPowerManagementMethod.AUTO.name()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..fa42ac5788c --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostPowerStatusMsgDoc_zh_cn.groovy @@ -0,0 +1,68 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIGetHostPowerStatusEvent + +doc { + title "GetHostPowerStatus" + + category "host" + + desc """获取物理机最新电源状态""" + + rest { + request { + url "PUT /v1/hosts/power/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetHostPowerStatusMsg.class + + desc """获取一台物理机最新电源状态""" + + params { + + column { + name "uuid" + enclosedIn "getHostPowerStatus" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "method" + enclosedIn "getHostPowerStatus" + desc "获取物理机电源状态方式" + location "body" + type "String" + optional true + since "4.7.0" + values ("AUTO","AGENT","IPMI") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIGetHostPowerStatusEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsg.java b/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsg.java index 50d9fbdbb53..86aeb7f42f9 100644 --- a/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsg.java +++ b/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsg.java @@ -1,13 +1,15 @@ package org.zstack.header.host; import org.springframework.http.HttpMethod; +import org.zstack.header.core.APIGetChainTaskReply; import org.zstack.header.identity.Action; -import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; -import org.zstack.header.message.APISyncCallMessage; import org.zstack.header.rest.RestRequest; +import org.zstack.header.core.APIGetChainTaskMsg; +import java.util.ArrayList; import java.util.List; +import java.util.function.Function; /** * Created by MaJin on 2019/7/3. @@ -17,9 +19,9 @@ @RestRequest( path = "/hosts/task-details", method = HttpMethod.GET, - responseClass = APIGetHostTaskReply.class + responseClass = APIGetChainTaskReply.class ) -public class APIGetHostTaskMsg extends APISyncCallMessage { +public class APIGetHostTaskMsg extends APIGetChainTaskMsg { @APIParam(nonempty = true, resourceType = HostVO.class) private List hostUuids; @@ -30,4 +32,16 @@ public List getHostUuids() { public void setHostUuids(List hostUuids) { this.hostUuids = hostUuids; } + + @Override + public List getSyncSignatures() { + List syncSignatures = new ArrayList<>(); + hostUuids.forEach(hostUuid -> syncSignatures.add((HostConstant.HOST_SYNC_SIGNATURE_PREFIX + hostUuid))); + return syncSignatures; + } + + @Override + public Function getResourceUuidMaker() { + return s -> s.substring(s.lastIndexOf("-") + 1); + } } diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsgDoc_zh_cn.groovy index b37219a23e8..6039ef666fa 100644 --- a/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIGetHostTaskMsgDoc_zh_cn.groovy @@ -1,6 +1,6 @@ package org.zstack.header.host -import org.zstack.header.host.APIGetHostTaskReply +import org.zstack.header.core.APIGetChainTaskReply doc { title "GetHostTask" @@ -29,7 +29,6 @@ doc { type "List" optional false since "3.6.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -49,13 +47,21 @@ doc { type "List" optional true since "3.6.0" - + } + column { + name "syncSignatures" + enclosedIn "" + desc "" + location "query" + type "List" + optional true + since "4.6.0" } } } response { - clz APIGetHostTaskReply.class + clz APIGetChainTaskReply.class } } } \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostTaskReply.java b/header/src/main/java/org/zstack/header/host/APIGetHostTaskReply.java deleted file mode 100644 index 16ed0ee040e..00000000000 --- a/header/src/main/java/org/zstack/header/host/APIGetHostTaskReply.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.zstack.header.host; - -import org.zstack.header.core.progress.ChainInfo; -import org.zstack.header.message.APIReply; -import org.zstack.header.rest.RestResponse; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by MaJin on 2019/7/3. - */ -@RestResponse(fieldsTo = {"all"}) -public class APIGetHostTaskReply extends APIReply { - private Map results = new HashMap<>(); - - public Map getResults() { - return results; - } - - public void setResults(Map results) { - this.results = results; - } - - public void putResults(String hostUuid, ChainInfo info) { - results.put(hostUuid, info); - } -} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostTaskReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHostTaskReplyDoc_zh_cn.groovy deleted file mode 100644 index 38b6d21aa62..00000000000 --- a/header/src/main/java/org/zstack/header/host/APIGetHostTaskReplyDoc_zh_cn.groovy +++ /dev/null @@ -1,33 +0,0 @@ -package org.zstack.header.host - -import org.zstack.header.errorcode.ErrorCode -import org.zstack.header.core.progress.ChainInfo -import org.zstack.header.errorcode.ErrorCode - -doc { - - title "获取物理机上的任务信息" - - ref { - name "error" - path "org.zstack.header.host.APIGetHostTaskReply.error" - desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false - type "ErrorCode" - since "3.6.0" - clz ErrorCode.class - } - ref { - name "results" - path "org.zstack.header.host.APIGetHostTaskReply.results" - desc "获取的结果" - type "Map" - since "3.6.0" - clz ChainInfo.class - } - field { - name "success" - desc "" - type "boolean" - since "3.6.0" - } -} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlEvent.java b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlEvent.java new file mode 100644 index 00000000000..0f1f5c4c446 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlEvent.java @@ -0,0 +1,35 @@ +package org.zstack.header.host; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @Author : jingwang + * @create 2023/4/25 2:33 PM + */ +@RestResponse(fieldsTo = "all") +public class APIGetHostWebSshUrlEvent extends APIEvent { + public APIGetHostWebSshUrlEvent() { + } + + public APIGetHostWebSshUrlEvent(String apiId) { + super(apiId); + } + + private String url; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public static APIGetHostWebSshUrlEvent __example__() { + APIGetHostWebSshUrlEvent event = new APIGetHostWebSshUrlEvent(); + event.setUrl("ws://{{ip}}:8888/ws?id=140147795208568"); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..f0073957eb1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlEventDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.host + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取一台物理机网页终端链接消息回复" + + field { + name "url" + desc "物理机网页终端链接" + type "String" + since "4.7.0" + } + field { + name "success" + desc "是否成功" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.host.APIGetHostWebSshUrlEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlMsg.java b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlMsg.java new file mode 100644 index 00000000000..12415f71af6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlMsg.java @@ -0,0 +1,72 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @Author : jingwang + * @create 2023/4/25 11:29 AM + */ +@RestRequest( + path = "/hosts/webssh", + method = HttpMethod.POST, + responseClass = APIGetHostWebSshUrlEvent.class, + parameterName = "params" +) +public class APIGetHostWebSshUrlMsg extends APIMessage { + @APIParam(nonempty = true, resourceType = HostVO.class) + private String uuid; + + @APIParam(required = false) + private Boolean https = false; + + @APIParam(nonempty = true) + private String userName; + + @APIParam(nonempty = true) + @NoLogging + private String password; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Boolean getHttps() { + return https; + } + + public void setHttps(Boolean https) { + this.https = https; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public static APIGetHostWebSshUrlMsg __example__() { + APIGetHostWebSshUrlMsg msg = new APIGetHostWebSshUrlMsg(); + msg.setUuid(uuid()); + msg.setUserName("root"); + msg.setPassword("password"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..eed8e86f763 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIGetHostWebSshUrlMsgDoc_zh_cn.groovy @@ -0,0 +1,85 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIGetHostWebSshUrlEvent + +doc { + title "GetHostWebSshUrl" + + category "host" + + desc """获取物理机网页终端链接""" + + rest { + request { + url "POST /v1/hosts/webssh" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetHostWebSshUrlMsg.class + + desc """获取一台物理机网页终端链接""" + + params { + + column { + name "uuid" + enclosedIn "params" + desc "资源的UUID,唯一标示该资源" + location "body" + type "String" + optional false + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "https" + enclosedIn "params" + desc "是否是HTTPS" + location "body" + type "Boolean" + optional true + since "4.7.11" + } + column { + name "userName" + enclosedIn "params" + desc "用户名" + location "body" + type "String" + optional false + since "4.8.0" + } + column { + name "password" + enclosedIn "params" + desc "密码" + location "body" + type "String" + optional false + since "4.8.0" + } + } + } + + response { + clz APIGetHostWebSshUrlEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIGetHypervisorTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIGetHypervisorTypesMsgDoc_zh_cn.groovy index 5dcaf7fd080..f5196329ffc 100644 --- a/header/src/main/java/org/zstack/header/host/APIGetHypervisorTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIGetHypervisorTypesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/host/APIPowerOnHostEvent.java b/header/src/main/java/org/zstack/header/host/APIPowerOnHostEvent.java new file mode 100644 index 00000000000..b55aacaec93 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerOnHostEvent.java @@ -0,0 +1,42 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @Author : jingwang + * @create 2023/4/18 9:47 AM + */ +@RestResponse(fieldsTo = "all") +public class APIPowerOnHostEvent extends APIEvent { + private HostInventory inventory; + + public APIPowerOnHostEvent() { super(null); } + + public APIPowerOnHostEvent(String apiId) { + super(apiId); + } + + public HostInventory getInventory() { + return inventory; + } + + public void setInventory(HostInventory inventory) { + this.inventory = inventory; + } + + public static APIPowerOnHostEvent __example__() { + + APIPowerOnHostEvent event = new APIPowerOnHostEvent(); + HostInventory hi = new HostInventory(); + hi.setName("example"); + hi.setClusterUuid(uuid()); + hi.setManagementIp("192.168.0.1"); + hi.setAvailableCpuCapacity(100000L); + hi.setAvailableMemoryCapacity(100000L); + hi.setIpmiAddress("192.168.0.1"); + hi.setIpmiUsername("admin"); + hi.setIpmiPort(623); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIPowerOnHostEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIPowerOnHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..18aca15c2e6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerOnHostEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "物理机开机消息回复" + + ref { + name "inventory" + path "org.zstack.header.host.APIPowerOnHostEvent.inventory" + desc "物理机信息" + type "HostInventory" + since "4.7.0" + clz HostInventory.class + } + field { + name "success" + desc "是否成功" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.host.APIPowerOnHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIPowerOnHostMsg.java b/header/src/main/java/org/zstack/header/host/APIPowerOnHostMsg.java new file mode 100644 index 00000000000..f8f06ad1b33 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerOnHostMsg.java @@ -0,0 +1,51 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @Author : jingwang + * @create 2023/4/14 5:27 PM + */ +@RestRequest( + path = "/hosts/power/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIPowerOnHostEvent.class, + isAction = true +) +public class APIPowerOnHostMsg extends APIMessage implements HostMessage { + @APIParam(nonempty = true, resourceType = HostVO.class) + private String uuid; + @APIParam(required = false) + private boolean returnEarly = false; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public boolean isReturnEarly() { + return returnEarly; + } + + public void setReturnEarly(boolean returnEarly) { + this.returnEarly = returnEarly; + } + + @Override + public String getHostUuid() { + return uuid; + } + + public static APIPowerOnHostMsg __example__() { + APIPowerOnHostMsg msg = new APIPowerOnHostMsg(); + msg.setUuid(uuid()); + msg.setReturnEarly(false); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIPowerOnHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIPowerOnHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..30eed41a5e3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerOnHostMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIPowerOnHostEvent + +doc { + title "PowerOnHost" + + category "host" + + desc """物理机开机""" + + rest { + request { + url "PUT /v1/hosts/power/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIPowerOnHostMsg.class + + desc """一台物理机开机""" + + params { + + column { + name "uuid" + enclosedIn "powerOnHost" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "returnEarly" + enclosedIn "powerOnHost" + desc "是否提前返回" + location "body" + type "boolean" + optional true + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIPowerOnHostEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIPowerResetHostEvent.java b/header/src/main/java/org/zstack/header/host/APIPowerResetHostEvent.java new file mode 100644 index 00000000000..e003bd6a781 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerResetHostEvent.java @@ -0,0 +1,42 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @Author : jingwang + * @create 2023/4/18 9:48 AM + */ +@RestResponse(fieldsTo = "all") +public class APIPowerResetHostEvent extends APIEvent { + private HostInventory inventory; + + public APIPowerResetHostEvent() { super(null); } + + public APIPowerResetHostEvent(String apiId) { + super(apiId); + } + + public HostInventory getInventory() { + return inventory; + } + + public void setInventory(HostInventory inventory) { + this.inventory = inventory; + } + + public static APIPowerResetHostEvent __example__() { + + APIPowerResetHostEvent event = new APIPowerResetHostEvent(); + HostInventory hi = new HostInventory(); + hi.setName("example"); + hi.setClusterUuid(uuid()); + hi.setManagementIp("192.168.0.1"); + hi.setAvailableCpuCapacity(100000L); + hi.setAvailableMemoryCapacity(100000L); + hi.setIpmiAddress("192.168.0.1"); + hi.setIpmiUsername("admin"); + hi.setIpmiPort(623); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIPowerResetHostEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIPowerResetHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..610c24a2b4f --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerResetHostEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "重启物理机消息回复" + + ref { + name "inventory" + path "org.zstack.header.host.APIPowerResetHostEvent.inventory" + desc "物理机信息" + type "HostInventory" + since "4.7.0" + clz HostInventory.class + } + field { + name "success" + desc "是否成功" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.host.APIPowerResetHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIPowerResetHostMsg.java b/header/src/main/java/org/zstack/header/host/APIPowerResetHostMsg.java new file mode 100644 index 00000000000..ef268974ef0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerResetHostMsg.java @@ -0,0 +1,64 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @Author : jingwang + * @create 2023/4/14 5:27 PM + */ +@RestRequest( + path = "/hosts/power/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIPowerResetHostEvent.class, + isAction = true +) +public class APIPowerResetHostMsg extends APIMessage implements HostMessage { + @APIParam(nonempty = true, resourceType = HostVO.class) + private String uuid; + + @APIParam(required = false) + private boolean returnEarly = false; + + @APIParam(required = false, validValues = {"AUTO","AGENT","IPMI"}) + private String method = HostPowerManagementMethod.AUTO.toString(); + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public boolean isReturnEarly() { + return returnEarly; + } + + public void setReturnEarly(boolean returnEarly) { + this.returnEarly = returnEarly; + } + + @Override + public String getHostUuid() { + return uuid; + } + + public static APIPowerResetHostMsg __example__() { + APIPowerResetHostMsg msg = new APIPowerResetHostMsg(); + msg.setUuid(uuid()); + msg.setMethod(HostPowerManagementMethod.AUTO.name()); + msg.setReturnEarly(false); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIPowerResetHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIPowerResetHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..f3e882a4d37 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIPowerResetHostMsgDoc_zh_cn.groovy @@ -0,0 +1,77 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIPowerResetHostEvent + +doc { + title "PowerResetHost" + + category "host" + + desc """重启物理机""" + + rest { + request { + url "PUT /v1/hosts/power/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIPowerResetHostMsg.class + + desc """重启一台物理机""" + + params { + + column { + name "uuid" + enclosedIn "powerResetHost" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "method" + enclosedIn "powerResetHost" + desc "重启方式" + location "body" + type "String" + optional true + since "4.7.0" + values ("AUTO","AGENT","IPMI") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "returnEarly" + enclosedIn "powerResetHost" + desc "是否提前返回" + location "body" + type "boolean" + optional true + since "4.7.0" + } + } + } + + response { + clz APIPowerResetHostEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIQueryHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIQueryHostMsgDoc_zh_cn.groovy index c38179ca1f8..66d52fd9d7d 100644 --- a/header/src/main/java/org/zstack/header/host/APIQueryHostMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIQueryHostMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.host import org.zstack.header.host.APIQueryHostReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryHost" diff --git a/header/src/main/java/org/zstack/header/host/APIReconnectHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIReconnectHostMsgDoc_zh_cn.groovy index ff11ed58a1f..cec136b127b 100644 --- a/header/src/main/java/org/zstack/header/host/APIReconnectHostMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIReconnectHostMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/host/APIShutdownHostEvent.java b/header/src/main/java/org/zstack/header/host/APIShutdownHostEvent.java new file mode 100644 index 00000000000..1114f666264 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIShutdownHostEvent.java @@ -0,0 +1,43 @@ +package org.zstack.header.host; + +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @Author : jingwang + * @create 2023/4/14 5:51 PM + */ +@RestResponse(fieldsTo = "all") +public class APIShutdownHostEvent extends APIEvent { + private HostInventory inventory; + + public APIShutdownHostEvent() { super(null); } + + public APIShutdownHostEvent(String apiId) { + super(apiId); + } + + public HostInventory getInventory() { + return inventory; + } + + public void setInventory(HostInventory inventory) { + this.inventory = inventory; + } + + public static APIShutdownHostEvent __example__() { + + APIShutdownHostEvent event = new APIShutdownHostEvent(); + HostInventory hi = new HostInventory(); + hi.setName("example"); + hi.setClusterUuid(uuid()); + hi.setManagementIp("192.168.0.1"); + hi.setAvailableCpuCapacity(100000L); + hi.setAvailableMemoryCapacity(100000L); + hi.setIpmiAddress("192.168.0.1"); + hi.setIpmiUsername("admin"); + hi.setIpmiPort(623); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIShutdownHostEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIShutdownHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..665a5b5880e --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIShutdownHostEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "关闭物理机消息回复" + + ref { + name "inventory" + path "org.zstack.header.host.APIShutdownHostEvent.inventory" + desc "物理机信息" + type "HostInventory" + since "4.7.0" + clz HostInventory.class + } + field { + name "success" + desc "是否成功" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.host.APIShutdownHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIShutdownHostMsg.java b/header/src/main/java/org/zstack/header/host/APIShutdownHostMsg.java new file mode 100644 index 00000000000..6c165a8b3aa --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIShutdownHostMsg.java @@ -0,0 +1,74 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + + +/** + * @Author : jingwang + * @create 2023/4/14 5:24 PM + */ +@RestRequest( + path = "/hosts/power/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIShutdownHostEvent.class, + isAction = true +) +public class APIShutdownHostMsg extends APIMessage implements HostMessage { + @APIParam(nonempty = true, resourceType = HostVO.class) + private String uuid; + @APIParam(required = false) + private boolean returnEarly = false; + @APIParam(required = false) + private boolean force = false; + @APIParam(required = false, validValues = {"AUTO","AGENT","IPMI"}) + private String method = HostPowerManagementMethod.AUTO.toString(); + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public boolean isReturnEarly() { + return returnEarly; + } + + public void setReturnEarly(boolean returnEarly) { + this.returnEarly = returnEarly; + } + + @Override + public String getHostUuid() { + return uuid; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public static APIShutdownHostMsg __example__() { + APIShutdownHostMsg msg = new APIShutdownHostMsg(); + msg.setUuid(uuid()); + msg.setForce(false); + msg.setMethod(HostPowerManagementMethod.AUTO.name()); + msg.setReturnEarly(false); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIShutdownHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIShutdownHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..03f16a9f884 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIShutdownHostMsgDoc_zh_cn.groovy @@ -0,0 +1,86 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIShutdownHostEvent + +doc { + title "ShutdownHost" + + category "host" + + desc """关闭物理机""" + + rest { + request { + url "PUT /v1/hosts/power/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIShutdownHostMsg.class + + desc """关闭一台物理机""" + + params { + + column { + name "uuid" + enclosedIn "shutdownHost" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "returnEarly" + enclosedIn "shutdownHost" + desc "是否提前返回" + location "body" + type "boolean" + optional true + since "4.7.0" + } + column { + name "force" + enclosedIn "shutdownHost" + desc "是否强制关机" + location "body" + type "boolean" + optional true + since "0.6" + } + column { + name "method" + enclosedIn "shutdownHost" + desc "关机方式" + location "body" + type "String" + optional true + since "4.7.0" + values ("AUTO","AGENT","IPMI") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIShutdownHostEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIUpdateHostEventDoc_zh_cn.groovy index 8fea6a734e8..585a0b51bf8 100644 --- a/header/src/main/java/org/zstack/header/host/APIUpdateHostEventDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostEventDoc_zh_cn.groovy @@ -11,14 +11,14 @@ doc { name "success" desc "" type "boolean" - since "0.6" + since "4.7.0" } ref { name "error" path "org.zstack.header.host.APIUpdateHostEvent.error" desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false type "ErrorCode" - since "0.6" + since "4.7.0" clz ErrorCode.class } ref { @@ -26,7 +26,7 @@ doc { path "org.zstack.header.host.APIUpdateHostEvent.inventory" desc "更新后的云主机信息" type "HostInventory" - since "0.6" + since "4.7.0" clz HostInventory.class } } diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiEvent.java b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiEvent.java new file mode 100644 index 00000000000..2980c251eaa --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiEvent.java @@ -0,0 +1,39 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +/** + * @Author : jingwang + * @create 2023/4/18 11:28 AM + */ +@RestResponse(fieldsTo = {"all"}) +public class APIUpdateHostIpmiEvent extends APIEvent { + private HostIpmiInventory hostIpmiInventory; + + public APIUpdateHostIpmiEvent() { super(null); } + + public APIUpdateHostIpmiEvent(String apiId) { + super(apiId); + } + + public HostIpmiInventory getHostIpmiInventory() { + return hostIpmiInventory; + } + + public void setHostIpmiInventory(HostIpmiInventory hostIpmiInventory) { + this.hostIpmiInventory = hostIpmiInventory; + } + + public static APIUpdateHostIpmiEvent __example__() { + APIUpdateHostIpmiEvent event = new APIUpdateHostIpmiEvent(); + HostIpmiInventory ipmiInventory = new HostIpmiInventory(); + ipmiInventory.setIpmiAddress("192.168.0.1"); + ipmiInventory.setIpmiUsername("admin"); + ipmiInventory.setIpmiPort(623); + ipmiInventory.setIpmiPassword("password"); + event.setHostIpmiInventory(ipmiInventory); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..52f0dd3f870 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostIpmiInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "更新物理机IPMI信息消息回复" + + ref { + name "hostIpmiInventory" + path "org.zstack.header.host.APIUpdateHostIpmiEvent.hostIpmiInventory" + desc "物理机IPMI信息" + type "HostIpmiInventory" + since "4.7.0" + clz HostIpmiInventory.class + } + field { + name "success" + desc "是否成功" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.host.APIUpdateHostIpmiEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsg.java b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsg.java new file mode 100644 index 00000000000..4494762e4a6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsg.java @@ -0,0 +1,86 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @Author : jingwang + * @create 2023/4/14 5:28 PM + */ +@RestRequest( + path = "/hosts/ipmi/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIUpdateHostIpmiEvent.class, + isAction = true +) +public class APIUpdateHostIpmiMsg extends APIMessage implements HostMessage { + @APIParam(resourceType = HostEO.class) + private String uuid; + @APIParam(required = false, nonempty = true) + private String ipmiAddress; + @APIParam(required = false, nonempty = true) + private String ipmiUsername; + @APIParam(required = false, nonempty = true) + @NoLogging + private String ipmiPassword; + @APIParam(required = false, nonempty = true) + private int ipmiPort = 623; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getIpmiAddress() { + return ipmiAddress; + } + + public void setIpmiAddress(String ipmiAddress) { + this.ipmiAddress = ipmiAddress; + } + + public String getIpmiUsername() { + return ipmiUsername; + } + + public void setIpmiUsername(String ipmiUsername) { + this.ipmiUsername = ipmiUsername; + } + + public String getIpmiPassword() { + return ipmiPassword; + } + + public void setIpmiPassword(String ipmiPassword) { + this.ipmiPassword = ipmiPassword; + } + + public int getIpmiPort() { + return ipmiPort; + } + + public void setIpmiPort(int ipmiPort) { + this.ipmiPort = ipmiPort; + } + + @Override + public String getHostUuid() { + return uuid; + } + + public static APIUpdateHostIpmiMsg __example__() { + APIUpdateHostIpmiMsg msg = new APIUpdateHostIpmiMsg(); + msg.setUuid(uuid()); + msg.setIpmiAddress("127.0.0.10"); + msg.setIpmiPort(623); + msg.setIpmiUsername("admin"); + msg.setIpmiPassword("password"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..43990d33f80 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostIpmiMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIUpdateHostIpmiEvent + +doc { + title "UpdateHostIpmi" + + category "host" + + desc """更新物理机IPMI信息""" + + rest { + request { + url "PUT /v1/hosts/ipmi/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateHostIpmiMsg.class + + desc """更新一台物理机IPMI信息""" + + params { + + column { + name "uuid" + enclosedIn "updateHostIpmi" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7" + } + column { + name "ipmiAddress" + enclosedIn "updateHostIpmi" + desc "IPMI地址" + location "body" + type "String" + optional true + since "4.7.0" + } + column { + name "ipmiUsername" + enclosedIn "updateHostIpmi" + desc "IPMI用户名" + location "body" + type "String" + optional true + since "4.7.0" + } + column { + name "ipmiPassword" + enclosedIn "updateHostIpmi" + desc "IPMI密码" + location "body" + type "String" + optional true + since "4.7.0" + } + column { + name "ipmiPort" + enclosedIn "updateHostIpmi" + desc "IPMI端口" + location "body" + type "int" + optional true + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIUpdateHostIpmiEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIUpdateHostMsgDoc_zh_cn.groovy index 02701b6f19f..47269edf949 100644 --- a/header/src/main/java/org/zstack/header/host/APIUpdateHostMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "managementIp" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeEvent.java b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeEvent.java new file mode 100644 index 00000000000..1d9adb75607 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeEvent.java @@ -0,0 +1,35 @@ +package org.zstack.header.host; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * Created by boce.wang on 10/25/2024. + */ +@RestResponse(allTo = "inventory") +public class APIUpdateHostNetworkServiceTypeEvent extends APIEvent { + private HostNetworkLabelInventory inventory; + + public APIUpdateHostNetworkServiceTypeEvent() { + + } + + public APIUpdateHostNetworkServiceTypeEvent(String apiId) { + super(apiId); + } + + public HostNetworkLabelInventory getInventory() { + return inventory; + } + + public void setInventory(HostNetworkLabelInventory inventory) { + this.inventory = inventory; + } + + public static APIUpdateHostNetworkServiceTypeEvent __example__() { + APIUpdateHostNetworkServiceTypeEvent event = new APIUpdateHostNetworkServiceTypeEvent(); + event.setInventory(new HostNetworkLabelInventory()); + event.setSuccess(true); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..f445f88f073 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.host + +import org.zstack.header.host.HostNetworkLabelInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "在这里输入结构的名称" + + ref { + name "inventory" + path "org.zstack.header.host.APIUpdateHostNetworkServiceTypeEvent.inventory" + desc "null" + type "HostNetworkLabelInventory" + since "5.2.1" + clz HostNetworkLabelInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.2.1" + } + ref { + name "error" + path "org.zstack.header.host.APIUpdateHostNetworkServiceTypeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.1" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeMsg.java b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeMsg.java new file mode 100644 index 00000000000..973d51961a6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeMsg.java @@ -0,0 +1,60 @@ +package org.zstack.header.host; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * Created by boce.wang on 10/25/2024. + */ +@RestRequest( + path = "/hosts/service-types/{uuid}/actions", + method = HttpMethod.PUT, + isAction = true, + responseClass = APIUpdateHostNetworkServiceTypeEvent.class + +) +public class APIUpdateHostNetworkServiceTypeMsg extends APIMessage { + + @APIParam(resourceType = HostNetworkLabelVO.class) + private String uuid; + + @APIParam(maxLength = 128, nonempty = true, noTrim = true) + private String serviceType; + + @APIParam(required = false, nonempty = true) + private boolean system = false; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public boolean isSystem() { + return system; + } + + public void setSystem(boolean system) { + this.system = system; + } + + public static APIUpdateHostNetworkServiceTypeMsg __example__() { + APIUpdateHostNetworkServiceTypeMsg msg = new APIUpdateHostNetworkServiceTypeMsg(); + msg.setUuid(uuid()); + msg.setServiceType("ManagementNetwork"); + msg.setSystem(true); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..35c3c9e091c --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/APIUpdateHostNetworkServiceTypeMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.host + +import org.zstack.header.host.APIUpdateHostNetworkServiceTypeEvent + +doc { + title "UpdateHostNetworkServiceType" + + category "host" + + desc """在这里填写API描述""" + + rest { + request { + url "PUT /v1/hosts/service-types/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateHostNetworkServiceTypeMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "updateHostNetworkServiceType" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.2.1" + } + column { + name "serviceType" + enclosedIn "updateHostNetworkServiceType" + desc "" + location "body" + type "String" + optional false + since "5.2.1" + } + column { + name "system" + enclosedIn "updateHostNetworkServiceType" + desc "" + location "body" + type "boolean" + optional true + since "5.2.1" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.2.1" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.2.1" + } + } + } + + response { + clz APIUpdateHostNetworkServiceTypeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/host/AttachDataVolumeToHostMsg.java b/header/src/main/java/org/zstack/header/host/AttachDataVolumeToHostMsg.java new file mode 100644 index 00000000000..af5a53d57d4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/AttachDataVolumeToHostMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +public class AttachDataVolumeToHostMsg extends NeedReplyMessage implements HostMessage { + private String volumeUuid; + private String mountPath; + private String hostUuid; + private String device; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getMountPath() { + return mountPath; + } + + public void setMountPath(String mountPath) { + this.mountPath = mountPath; + } + + public String getDevice() { + return device; + } + + public void setDevice(String device) { + this.device = device; + } +} diff --git a/header/src/main/java/org/zstack/header/host/AttachDataVolumeToHostReply.java b/header/src/main/java/org/zstack/header/host/AttachDataVolumeToHostReply.java new file mode 100644 index 00000000000..51647a2c727 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/AttachDataVolumeToHostReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +public class AttachDataVolumeToHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/host/CancelHostTaskMsg.java b/header/src/main/java/org/zstack/header/host/CancelHostTaskMsg.java index 99dd8631125..ddda4e44492 100644 --- a/header/src/main/java/org/zstack/header/host/CancelHostTaskMsg.java +++ b/header/src/main/java/org/zstack/header/host/CancelHostTaskMsg.java @@ -7,7 +7,26 @@ */ public class CancelHostTaskMsg extends CancelMessage implements HostMessage { private String hostUuid; + private Integer times; + private Integer interval; + public Integer getInterval() { + return interval; + } + + public void setInterval(Integer interval) { + this.interval = interval; + } + + public Integer getTimes() { + return times; + } + + public void setTimes(Integer times) { + this.times = times; + } + + @Override public String getHostUuid() { return hostUuid; } diff --git a/header/src/main/java/org/zstack/header/host/CancelHostTasksMsg.java b/header/src/main/java/org/zstack/header/host/CancelHostTasksMsg.java index 799f9b1f73e..44171db3320 100644 --- a/header/src/main/java/org/zstack/header/host/CancelHostTasksMsg.java +++ b/header/src/main/java/org/zstack/header/host/CancelHostTasksMsg.java @@ -8,11 +8,31 @@ /** * Created by MaJin on 2019/7/22. * - * cancel host task by specific api ID, searchedMnIds @param, hostUuids @param are no need to set. + * cancel host task by specific api ID + * searchedMnIds @param, hostUuids @param are no need to set. + * do not retry by default. */ public class CancelHostTasksMsg extends CancelMessage { private List searchedMnIds = new ArrayList<>(); private List hostUuids = new ArrayList<>(); + private Integer times; + private Integer interval; + + public Integer getInterval() { + return interval; + } + + public void setInterval(Integer interval) { + this.interval = interval; + } + + public Integer getTimes() { + return times; + } + + public void setTimes(Integer times) { + this.times = times; + } public List getSearchedMnIds() { return searchedMnIds; diff --git a/header/src/main/java/org/zstack/header/host/ChangeHostStatusMsg.java b/header/src/main/java/org/zstack/header/host/ChangeHostStatusMsg.java new file mode 100644 index 00000000000..05c19644947 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/ChangeHostStatusMsg.java @@ -0,0 +1,33 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author: DaoDao + * @Date: 2023/7/4 + */ +public class ChangeHostStatusMsg extends NeedReplyMessage implements HostMessage{ + private String uuid; + private String statusEvent; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatusEvent() { + return statusEvent; + } + + public void setStatusEvent(String statusEvent) { + this.statusEvent = statusEvent; + } + + @Override + public String getHostUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/ChangeHostStatusReply.java b/header/src/main/java/org/zstack/header/host/ChangeHostStatusReply.java new file mode 100644 index 00000000000..d4cf0822117 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/ChangeHostStatusReply.java @@ -0,0 +1,22 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * @Author: DaoDao + * @Date: 2023/7/4 + */ +public class ChangeHostStatusReply extends MessageReply { + private HostInventory inventory; + + public ChangeHostStatusReply() { + } + + public HostInventory getInventory() { + return inventory; + } + + public void setInventory(HostInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/host/ChangeVmNicStateOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/host/ChangeVmNicStateOnHypervisorMsg.java new file mode 100755 index 00000000000..994b9bf95f6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/ChangeVmNicStateOnHypervisorMsg.java @@ -0,0 +1,47 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.vm.VmNicInventory; + +/** + * Created by boce.wang on 11/15/2022. + */ +public class ChangeVmNicStateOnHypervisorMsg extends NeedReplyMessage implements HostMessage { + private String hostUuid; + private String vmInstanceUuid; + private String state; + private VmNicInventory nic; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public VmNicInventory getNic() { + return nic; + } + + public void setNic(VmNicInventory nic) { + this.nic = nic; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } +} diff --git a/header/src/main/java/org/zstack/header/host/ChangeVmNicStateOnHypervisorReply.java b/header/src/main/java/org/zstack/header/host/ChangeVmNicStateOnHypervisorReply.java new file mode 100755 index 00000000000..8f358d557fa --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/ChangeVmNicStateOnHypervisorReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * Created by boce.wang on 11/15/2022. + */ +public class ChangeVmNicStateOnHypervisorReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/host/CommitVolumeSnapshotOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/host/CommitVolumeSnapshotOnHypervisorMsg.java new file mode 100644 index 00000000000..4ceb022eab0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CommitVolumeSnapshotOnHypervisorMsg.java @@ -0,0 +1,57 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeInventory; + +import java.util.ArrayList; +import java.util.List; + +public class CommitVolumeSnapshotOnHypervisorMsg extends NeedReplyMessage implements HostMessage { + private String hostUuid; + private VolumeInventory volume; + private VolumeSnapshotInventory srcSnapshot; + private VolumeSnapshotInventory dstSnapshot; + private List srcChildrenInstallPathInDb = new ArrayList<>(); + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } + + public VolumeSnapshotInventory getSrcSnapshot() { + return srcSnapshot; + } + + public void setSrcSnapshot(VolumeSnapshotInventory srcSnapshot) { + this.srcSnapshot = srcSnapshot; + } + + public VolumeSnapshotInventory getDstSnapshot() { + return dstSnapshot; + } + + public void setDstSnapshot(VolumeSnapshotInventory dstSnapshot) { + this.dstSnapshot = dstSnapshot; + } + + public List getSrcChildrenInstallPathInDb() { + return srcChildrenInstallPathInDb; + } + + public void setSrcChildrenInstallPathInDb(List srcChildrenInstallPathInDb) { + this.srcChildrenInstallPathInDb = srcChildrenInstallPathInDb; + } +} diff --git a/header/src/main/java/org/zstack/header/host/CommitVolumeSnapshotOnHypervisorReply.java b/header/src/main/java/org/zstack/header/host/CommitVolumeSnapshotOnHypervisorReply.java new file mode 100644 index 00000000000..38475ee85f1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CommitVolumeSnapshotOnHypervisorReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +public class CommitVolumeSnapshotOnHypervisorReply extends MessageReply { + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/header/src/main/java/org/zstack/header/host/CompareCpuFunctionOnHostMsg.java b/header/src/main/java/org/zstack/header/host/CompareCpuFunctionOnHostMsg.java new file mode 100644 index 00000000000..cfbf05fb76a --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CompareCpuFunctionOnHostMsg.java @@ -0,0 +1,41 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by LiangHanYu on 2021/8/13 16:31 + */ +public class CompareCpuFunctionOnHostMsg extends NeedReplyMessage implements HostMessage{ + private String srcHostUuid; + private String dstHostUuid; + private String CpuXml; + + public String getCpuXml() { + return CpuXml; + } + + public void setCpuXml(String cpuXml) { + CpuXml = cpuXml; + } + + @Override + public String getHostUuid() { + return dstHostUuid; + } + + public String getSrcHostUuid() { + return srcHostUuid; + } + + public void setSrcHostUuid(String srcHostUuid) { + this.srcHostUuid = srcHostUuid; + } + + public String getDstHostUuid() { + return dstHostUuid; + } + + public void setDstHostUuid(String dstHostUuid) { + this.dstHostUuid = dstHostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/CompareCpuFunctionOnHostReply.java b/header/src/main/java/org/zstack/header/host/CompareCpuFunctionOnHostReply.java new file mode 100644 index 00000000000..402fa684bbb --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CompareCpuFunctionOnHostReply.java @@ -0,0 +1,27 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2021/8/13 16:32 + */ +public class CompareCpuFunctionOnHostReply extends MessageReply { + private boolean match; + private String compareError; + + public boolean isMatch() { + return match; + } + + public void setMatch(boolean match) { + this.match = match; + } + + public String getCompareError() { + return compareError; + } + + public void setCompareError(String compareError) { + this.compareError = compareError; + } +} diff --git a/header/src/main/java/org/zstack/header/host/ConnectHostMsg.java b/header/src/main/java/org/zstack/header/host/ConnectHostMsg.java index 2ce6815ded3..2b29b11761a 100755 --- a/header/src/main/java/org/zstack/header/host/ConnectHostMsg.java +++ b/header/src/main/java/org/zstack/header/host/ConnectHostMsg.java @@ -6,6 +6,7 @@ public class ConnectHostMsg extends NeedReplyMessage implements HostMessage { private String uuid; private boolean isStartPingTaskOnFailure; private boolean newAdd; + private boolean calledByAPI; public ConnectHostMsg() { } @@ -39,6 +40,14 @@ public void setStartPingTaskOnFailure(boolean isStartPingTaskOnFailure) { this.isStartPingTaskOnFailure = isStartPingTaskOnFailure; } + public boolean isCalledByAPI() { + return calledByAPI; + } + + public void setCalledByAPI(boolean calledByAPI) { + this.calledByAPI = calledByAPI; + } + @Override public String getHostUuid() { return getUuid(); diff --git a/header/src/main/java/org/zstack/header/host/CpuArchitecture.java b/header/src/main/java/org/zstack/header/host/CpuArchitecture.java index d6fa02ea4e6..2119bdeec27 100644 --- a/header/src/main/java/org/zstack/header/host/CpuArchitecture.java +++ b/header/src/main/java/org/zstack/header/host/CpuArchitecture.java @@ -1,7 +1,11 @@ package org.zstack.header.host; +import org.zstack.header.rest.SDK; + +@SDK public enum CpuArchitecture { x86_64, aarch64, mips64el, + loongarch64, } diff --git a/header/src/main/java/org/zstack/header/host/CpuFeaturesHistoryVO.java b/header/src/main/java/org/zstack/header/host/CpuFeaturesHistoryVO.java new file mode 100644 index 00000000000..ef92ab6f7aa --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CpuFeaturesHistoryVO.java @@ -0,0 +1,89 @@ +package org.zstack.header.host; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * Created by LiangHanYu on 2021/8/25 13:56 + */ +@Entity +@Table +public class CpuFeaturesHistoryVO { + @Id + @Column + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + @Column + private String srcHostUuid; + @Column + private String dstHostUuid; + @Column + private String srcCpuModelName; + @Column + private boolean supportLiveMigration; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + public String getSrcCpuModelName() { + return srcCpuModelName; + } + + public void setSrcCpuModelName(String srcCpuModelName) { + this.srcCpuModelName = srcCpuModelName; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getSrcHostUuid() { + return srcHostUuid; + } + + public void setSrcHostUuid(String srcHostUuid) { + this.srcHostUuid = srcHostUuid; + } + + public String getDstHostUuid() { + return dstHostUuid; + } + + public void setDstHostUuid(String dstHostUuid) { + this.dstHostUuid = dstHostUuid; + } + + public boolean isSupportLiveMigration() { + return supportLiveMigration; + } + + public void setSupportLiveMigration(boolean supportLiveMigration) { + this.supportLiveMigration = supportLiveMigration; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/host/CpuFeaturesHistoryVO_.java b/header/src/main/java/org/zstack/header/host/CpuFeaturesHistoryVO_.java new file mode 100644 index 00000000000..cbd60b6fc46 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CpuFeaturesHistoryVO_.java @@ -0,0 +1,19 @@ +package org.zstack.header.host; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by LiangHanYu on 2021/8/25 14:10 + */ +@StaticMetamodel(CpuFeaturesHistoryVO.class) +public class CpuFeaturesHistoryVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute srcHostUuid; + public static volatile SingularAttribute dstHostUuid; + public static volatile SingularAttribute srcCpuModelName; + public static volatile SingularAttribute supportLiveMigration; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/host/CreateCpuFeaturesHistoryMsg.java b/header/src/main/java/org/zstack/header/host/CreateCpuFeaturesHistoryMsg.java new file mode 100644 index 00000000000..9445a55c7c1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CreateCpuFeaturesHistoryMsg.java @@ -0,0 +1,52 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @author hanyu.liang + * @date 2023/9/15 14:42 + */ +public class CreateCpuFeaturesHistoryMsg extends NeedReplyMessage implements HostMessage { + private String srcHostUuid; + private String dstHostUuid; + private String srcCpuModelName; + private boolean supportLiveMigration; + + public String getSrcHostUuid() { + return srcHostUuid; + } + + public void setSrcHostUuid(String srcHostUuid) { + this.srcHostUuid = srcHostUuid; + } + + public String getDstHostUuid() { + return dstHostUuid; + } + + public void setDstHostUuid(String dstHostUuid) { + this.dstHostUuid = dstHostUuid; + } + + public String getSrcCpuModelName() { + return srcCpuModelName; + } + + public void setSrcCpuModelName(String srcCpuModelName) { + this.srcCpuModelName = srcCpuModelName; + } + + public boolean isSupportLiveMigration() { + return supportLiveMigration; + } + + public void setSupportLiveMigration(boolean supportLiveMigration) { + this.supportLiveMigration = supportLiveMigration; + } + + @Override + public String getHostUuid() { + return srcHostUuid; + } +} + diff --git a/header/src/main/java/org/zstack/header/host/CreateCpuFeaturesHistoryReply.java b/header/src/main/java/org/zstack/header/host/CreateCpuFeaturesHistoryReply.java new file mode 100644 index 00000000000..78f94b3b514 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/CreateCpuFeaturesHistoryReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * @author hanyu.liang + * @date 2023/9/15 14:45 + */ +public class CreateCpuFeaturesHistoryReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/host/DetachDataVolumeFromHostMsg.java b/header/src/main/java/org/zstack/header/host/DetachDataVolumeFromHostMsg.java new file mode 100644 index 00000000000..0cb3aee2b4c --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/DetachDataVolumeFromHostMsg.java @@ -0,0 +1,54 @@ +package org.zstack.header.host; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +public class DetachDataVolumeFromHostMsg extends NeedReplyMessage implements HostMessage { + private String volumeInstallPath; + private String mountPath; + private String hostUuid; + private String device; + private String volumeUuid; + + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVolumeInstallPath() { + return volumeInstallPath; + } + + public void setVolumeInstallPath(String volumeInstallPath) { + this.volumeInstallPath = volumeInstallPath; + } + + public String getMountPath() { + return mountPath; + } + + public void setMountPath(String mountPath) { + this.mountPath = mountPath; + } + + public String getDevice() { + return device; + } + + public void setDevice(String device) { + this.device = device; + } + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/DetachDataVolumeFromHostReply.java b/header/src/main/java/org/zstack/header/host/DetachDataVolumeFromHostReply.java new file mode 100644 index 00000000000..5b53aa56442 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/DetachDataVolumeFromHostReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +public class DetachDataVolumeFromHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/host/GetCpuFunctionXmlOnHostMsg.java b/header/src/main/java/org/zstack/header/host/GetCpuFunctionXmlOnHostMsg.java new file mode 100644 index 00000000000..d911444a572 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetCpuFunctionXmlOnHostMsg.java @@ -0,0 +1,19 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by LiangHanYu on 2021/7/29 15:27 + */ +public class GetCpuFunctionXmlOnHostMsg extends NeedReplyMessage implements HostMessage{ + private String hostUuid; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetCpuFunctionXmlOnHostReply.java b/header/src/main/java/org/zstack/header/host/GetCpuFunctionXmlOnHostReply.java new file mode 100644 index 00000000000..c0e0a2feae5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetCpuFunctionXmlOnHostReply.java @@ -0,0 +1,27 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2021/7/29 15:30 + */ +public class GetCpuFunctionXmlOnHostReply extends MessageReply { + private String cpuXml; + private String cpuModelName; + + public String getCpuModelName() { + return cpuModelName; + } + + public void setCpuModelName(String cpuModelName) { + this.cpuModelName = cpuModelName; + } + + public String getCpuXml() { + return cpuXml; + } + + public void setCpuXml(String cpuXml) { + this.cpuXml = cpuXml; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetHostPowerStatusMsg.java b/header/src/main/java/org/zstack/header/host/GetHostPowerStatusMsg.java new file mode 100644 index 00000000000..9857a61c5ab --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetHostPowerStatusMsg.java @@ -0,0 +1,34 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author : jingwang + * @create 2023/4/20 6:15 PM + */ +public class GetHostPowerStatusMsg extends NeedReplyMessage implements HostMessage { + private String uuid; + + private HostPowerManagementMethod method; + + public HostPowerManagementMethod getMethod() { + return method; + } + + public void setMethod(HostPowerManagementMethod method) { + this.method = method; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getHostUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetHostPowerStatusReply.java b/header/src/main/java/org/zstack/header/host/GetHostPowerStatusReply.java new file mode 100644 index 00000000000..2a31957740d --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetHostPowerStatusReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * @Author : jingwang + * @create 2023/5/6 2:04 PM + */ +public class GetHostPowerStatusReply extends MessageReply { + HostIpmiInventory inventory; + + public HostIpmiInventory getInventory() { + return inventory; + } + + public void setInventory(HostIpmiInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetHostTaskMsg.java b/header/src/main/java/org/zstack/header/host/GetHostTaskMsg.java deleted file mode 100644 index fa7c225889f..00000000000 --- a/header/src/main/java/org/zstack/header/host/GetHostTaskMsg.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.zstack.header.host; - -import org.zstack.header.message.NeedReplyMessage; - -import java.util.List; - -/** - * Created by MaJin on 2019/7/26. - */ -public class GetHostTaskMsg extends NeedReplyMessage { - private List hostUuids; - - public List getHostUuids() { - return hostUuids; - } - - public void setHostUuids(List hostUuids) { - this.hostUuids = hostUuids; - } -} diff --git a/header/src/main/java/org/zstack/header/host/GetHostTaskReply.java b/header/src/main/java/org/zstack/header/host/GetHostTaskReply.java deleted file mode 100644 index b7b4927bc61..00000000000 --- a/header/src/main/java/org/zstack/header/host/GetHostTaskReply.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.zstack.header.host; - -import org.zstack.header.core.progress.ChainInfo; -import org.zstack.header.message.MessageReply; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by MaJin on 2019/7/26. - */ -public class GetHostTaskReply extends MessageReply { - private Map results = new HashMap<>(); - - public Map getResults() { - return results; - } - - public void setResults(Map results) { - this.results = results; - } - - public void putResults(String hostUuid, ChainInfo info) { - results.put(hostUuid, info); - } -} diff --git a/header/src/main/java/org/zstack/header/host/GetHostWebSshUrlMsg.java b/header/src/main/java/org/zstack/header/host/GetHostWebSshUrlMsg.java new file mode 100644 index 00000000000..3e4cafd6a44 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetHostWebSshUrlMsg.java @@ -0,0 +1,56 @@ +package org.zstack.header.host; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author : jingwang + * @create 2023/4/25 2:26 PM + */ +public class GetHostWebSshUrlMsg extends NeedReplyMessage implements HostMessage { + private String uuid; + + private Boolean https; + + private String userName; + + @NoLogging + private String password; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Boolean getHttps() { + return https; + } + + public void setHttps(Boolean https) { + this.https = https; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String getHostUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetHostWebSshUrlReply.java b/header/src/main/java/org/zstack/header/host/GetHostWebSshUrlReply.java new file mode 100644 index 00000000000..846be55d35b --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetHostWebSshUrlReply.java @@ -0,0 +1,27 @@ +package org.zstack.header.host; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.MessageReply; + +/** + * @Author : jingwang + * @create 2023/4/25 2:35 PM + */ +public class GetHostWebSshUrlReply extends MessageReply { + @NoLogging + private String url; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public static GetHostWebSshUrlReply __example__() { + GetHostWebSshUrlReply reply = new GetHostWebSshUrlReply(); + reply.setUrl("ws://{{ip}}:8888/ws?id=140147795208568"); + return reply; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetVirtualizerInfoMsg.java b/header/src/main/java/org/zstack/header/host/GetVirtualizerInfoMsg.java new file mode 100644 index 00000000000..112a721d40f --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetVirtualizerInfoMsg.java @@ -0,0 +1,27 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; + +public class GetVirtualizerInfoMsg extends NeedReplyMessage implements HostMessage { + private List vmInstanceUuids; + private String hostUuid; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public List getVmInstanceUuids() { + return vmInstanceUuids; + } + + public void setVmInstanceUuids(List vmInstanceUuids) { + this.vmInstanceUuids = vmInstanceUuids; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetVirtualizerInfoReply.java b/header/src/main/java/org/zstack/header/host/GetVirtualizerInfoReply.java new file mode 100644 index 00000000000..92011cf4755 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/GetVirtualizerInfoReply.java @@ -0,0 +1,56 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +import java.util.List; + +public class GetVirtualizerInfoReply extends MessageReply { + private String hostVirtualizer; + private String hostInstalledQemuVersion; + private List vmInfoList; + + public String getHostVirtualizer() { + return hostVirtualizer; + } + + public void setHostVirtualizer(String hostVirtualizer) { + this.hostVirtualizer = hostVirtualizer; + } + + public String getHostInstalledQemuVersion() { + return hostInstalledQemuVersion; + } + + public void setHostInstalledQemuVersion(String hostInstalledQemuVersion) { + this.hostInstalledQemuVersion = hostInstalledQemuVersion; + } + + public List getVmInfoList() { + return vmInfoList; + } + + public void setVmInfoList(List vmInfoList) { + this.vmInfoList = vmInfoList; + } + + public static class VmVirtualizerInfo { + private String vmInstanceUuid; + private String currentQemuVersion; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getCurrentQemuVersion() { + return currentQemuVersion; + } + + public void setCurrentQemuVersion(String currentQemuVersion) { + this.currentQemuVersion = currentQemuVersion; + } + } +} diff --git a/header/src/main/java/org/zstack/header/host/GetVmConsoleAddressFromHostReply.java b/header/src/main/java/org/zstack/header/host/GetVmConsoleAddressFromHostReply.java index e418ab7a873..8f1989c1180 100755 --- a/header/src/main/java/org/zstack/header/host/GetVmConsoleAddressFromHostReply.java +++ b/header/src/main/java/org/zstack/header/host/GetVmConsoleAddressFromHostReply.java @@ -9,6 +9,7 @@ public class GetVmConsoleAddressFromHostReply extends MessageReply { private String hostIp; private String protocol; + private String path; private int port; private VdiPortInfo vdiPortInfo; @@ -43,4 +44,12 @@ public VdiPortInfo getVdiPortInfo() { public void setVdiPortInfo(VdiPortInfo vdiPortInfo) { this.vdiPortInfo = vdiPortInfo; } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } } diff --git a/header/src/main/java/org/zstack/header/host/HostCanonicalEvents.java b/header/src/main/java/org/zstack/header/host/HostCanonicalEvents.java index 1a7a8c545a8..cca0e26567d 100755 --- a/header/src/main/java/org/zstack/header/host/HostCanonicalEvents.java +++ b/header/src/main/java/org/zstack/header/host/HostCanonicalEvents.java @@ -1,6 +1,7 @@ package org.zstack.header.host; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.message.NeedJsonSchema; /** @@ -10,10 +11,487 @@ public class HostCanonicalEvents { public static final String HOST_STATUS_CHANGED_PATH = "/host/status/change"; public static final String HOST_DELETED_PATH = "/host/delete"; public static final String HOST_DISCONNECTED_PATH = "/host/disconnected"; + public static final String HOST_HARDWARE_CHANGED_PATH = "/host/hardware/changed"; public static final String HOST_CHECK_MOUNT_FAULT = "/host/mount/path/fault"; public static final String HOST_CHECK_INITIALIZED_FAILED = "/host/check/initialized/failed"; public static final String HOST_PHYSICAL_NIC_STATUS_UP = "/host/physicalNic/status/up"; public static final String HOST_PHYSICAL_NIC_STATUS_DOWN = "/host/physicalNic/status/down"; + public static final String HOST_PHYSICAL_MEMORY_ECC_ERROR_TRIGGERED = "/host/physicalMemory/ecc/error/triggered"; + public static final String HOST_PHYSICAL_CPU_STATUS_ABNORMAL = "/host/physicalCpu/status/abnormal"; + public static final String HOST_PHYSICAL_MEMORY_STATUS_ABNORMAL = "/host/physicalMemory/status/abnormal"; + public static final String HOST_PHYSICAL_FAN_STATUS_ABNORMAL = "/host/physicalFan/status/abnormal"; + public static final String HOST_PHYSICAL_DISK_STATUS_ABNORMAL = "/host/physicalDisk/status/abnormal"; + public static final String HOST_PHYSICAL_DISK_INSERT_TRIGGERED = "/host/physicalDisk/insert/triggered"; + public static final String HOST_PHYSICAL_DISK_REMOVE_TRIGGERED = "/host/physicalDisk/remove/triggered"; + public static final String HOST_PHYSICAL_POWER_SUPPLY_STATUS_ABNORMAL = "/host/physicalPowerSupply/status/abnormal"; + public static final String HOST_PHYSICAL_GPU_REMOVE_TRIGGERED = "/host/physicalGpu/remove/triggered"; + public static final String HOST_PHYSICAL_GPU_STATUS_ABNORMAL = "/host/physicalGpu/status/abnormal"; + public static final String HOST_PHYSICAL_VGPU_STATUS_ABNORMAL = "/host/physicalVGpu/status/abnormal"; + public static final String HOST_PHYSICAL_RAID_STATUS_ABNORMAL = "/host/physicalRaid/status/abnormal"; + public static final String HOST_PHYSICAL_HBA_STATE_ABNORMAL = "/host/physicalHBA/state/abnormal"; + public static final String HOST_PHYSICAL_VOLUME_STATE_ABNORMAL = "/host/physicalVolume/state/abnormal"; + public static final String HOST_PROCESS_PHYSICAL_MEMORY_USAGE_ABNORMAL = "/host/process/physicalMemory/usage/abnormal"; + public static final String HOST_PING_SKIP = "/host/ping/skip"; + public static final String HOST_PING_CANCEL_SKIP = "/host/ping/cancel/skip"; + public static final String HOST_MULTIPATH_CONFIG_CHANGED = "/host/multipathConfig/changed"; + + @NeedJsonSchema + public static class HostPhysicalHbaPortStateAbnormalData { + private String hostUuid; + private String name; + private String portName; + private String newPortState; + private String oldPortState; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getPortName() { + return portName; + } + + public void setPortName(String portName) { + this.portName = portName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNewPortState() { + return newPortState; + } + + public void setNewPortState(String newPortState) { + this.newPortState = newPortState; + } + + public String getOldPortState() { + return oldPortState; + } + + public void setOldPortState(String oldPortState) { + this.oldPortState = oldPortState; + } + } + + @NeedJsonSchema + public static class HostPhysicalGpuRemoveTriggeredData { + private String hostUuid; + private String pcideviceAddress; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getPcideviceAddress() { + return pcideviceAddress; + } + + public void setPcideviceAddress(String pcideviceAddress) { + this.pcideviceAddress = pcideviceAddress; + } + } + + @NeedJsonSchema + public static class HostPhysicalVGpuStatusAbnormalData { + private String hostUuid; + private String uuid; + private String name; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + + @NeedJsonSchema + public static class HostPhysicalGpuStatusAbnormalData { + private String hostUuid; + private String pcideviceAddress; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getPcideviceAddress() { + return pcideviceAddress; + } + + public void setPcideviceAddress(String pcideviceAddress) { + this.pcideviceAddress = pcideviceAddress; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalCpuStatusAbnormalData { + private String hostUuid; + private String cpuName; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getCpuName() { + return cpuName; + } + + public void setCpuName(String cpuName) { + this.cpuName = cpuName; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalMemoryStatusAbnormalData { + private String hostUuid; + private String locator; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getLocator() { + return locator; + } + + public void setLocator(String locator) { + this.locator = locator; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalFanStatusAbnormalData { + private String hostUuid; + private String fanName; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getFanName() { + return fanName; + } + + public void setFanName(String fanName) { + this.fanName = fanName; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalPowerSupplyStatusAbnormalData { + private String hostUuid; + private String name; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalRaidStatusAbnormalData { + private String hostUuid; + private String targetId; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalDiskStatusAbnormalData { + private String hostUuid; + private String serialNumber; + private String enclosureId; + private String slotNumber; + private String status; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public String getEnclosureId() { + return enclosureId; + } + + public void setEnclosureId(String enclosureId) { + this.enclosureId = enclosureId; + } + + public String getSlotNumber() { + return slotNumber; + } + + public void setSlotNumber(String slotNumber) { + this.slotNumber = slotNumber; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } + + @NeedJsonSchema + public static class HostPhysicalDiskData { + private String hostUuid; + private String serialNumber; + private String enclosureId; + private String slotNumber; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getSerialNumber() { + return serialNumber; + } + + public void setSerialNumber(String serialNumber) { + this.serialNumber = serialNumber; + } + + public String getEnclosureId() { + return enclosureId; + } + + public void setEnclosureId(String enclosureId) { + this.enclosureId = enclosureId; + } + + public String getSlotNumber() { + return slotNumber; + } + + public void setSlotNumber(String slotNumber) { + this.slotNumber = slotNumber; + } + } + + @NeedJsonSchema + public static class HostPhysicalVolumeStateAbnormalData { + private String hostUuid; + private String diskName; + private String diskUuids; // example: scsi-360014058e50754920324473a4c85c767;wwn-0x60014058e50754920324473a4c85c767 + private String state; + private String vgName; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getDiskName() { + return diskName; + } + + public void setDiskName(String diskName) { + this.diskName = diskName; + } + + public String getDiskUuids() { + return diskUuids; + } + + public void setDiskUuids(String diskUuids) { + this.diskUuids = diskUuids; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getVgName() { + return vgName; + } + + public void setVgName(String vgName) { + this.vgName = vgName; + } + } + + @NeedJsonSchema + public static class HostPhysicalMemoryEccErrorData { + private String hostUuid; + private ErrorCode detail; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public ErrorCode getDetail() { + return detail; + } + + public void setDetail(ErrorCode detail) { + this.detail = detail; + } + } public static class HostDisconnectedData { public String hostUuid; @@ -36,6 +514,27 @@ public void setReason(ErrorCode reason) { } } + public static class HostHardwareChangedData { + public String hostUuid; + public ErrorCodeList reason; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public ErrorCodeList getReason() { + return reason; + } + + public void setReason(ErrorCodeList reason) { + this.reason = reason; + } + } + @NeedJsonSchema public static class HostStatusChangedData { private String hostUuid; @@ -165,4 +664,88 @@ public void setInterfaceStatus(String interfaceStatus) { this.interfaceStatus = interfaceStatus; } } + + @NeedJsonSchema + public static class MultipathConfigChangedData { + private String hostUuid; + private String details; + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + } + + @NeedJsonSchema + public static class HostProcessPhysicalMemoryUsageAlarmData { + private String hostUuid; + private String pid; + private String processName; + private String memoryUsage; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getProcessName() { + return processName; + } + + public void setProcessName(String processName) { + this.processName = processName; + } + + public String getMemoryUsage() { + return memoryUsage; + } + + public void setMemoryUsage(String memoryUsage) { + this.memoryUsage = memoryUsage; + } + } + + @NeedJsonSchema + public static class HostPingSkipData { + private String hostUuid; + private int skipTimeInSec; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public int getSkipTimeInSec() { + return skipTimeInSec; + } + + public void setSkipTimeInSec(int skipTimeInSec) { + this.skipTimeInSec = skipTimeInSec; + } + } } diff --git a/header/src/main/java/org/zstack/header/host/HostConstant.java b/header/src/main/java/org/zstack/header/host/HostConstant.java index 6897e7796ee..805fa985584 100755 --- a/header/src/main/java/org/zstack/header/host/HostConstant.java +++ b/header/src/main/java/org/zstack/header/host/HostConstant.java @@ -5,4 +5,8 @@ public interface HostConstant { public static final String SERVICE_ID = "host"; public static final String ACTION_CATEGORY = "host"; + + String HOST_SYNC_SIGNATURE_PREFIX = "Host-"; + + String HOST_ARCHITECTURE_X86_64 = "x86_64"; } diff --git a/header/src/main/java/org/zstack/header/host/HostErrors.java b/header/src/main/java/org/zstack/header/host/HostErrors.java index bf3eba7a02b..83337af1d5f 100755 --- a/header/src/main/java/org/zstack/header/host/HostErrors.java +++ b/header/src/main/java/org/zstack/header/host/HostErrors.java @@ -14,7 +14,9 @@ public enum HostErrors { FAILED_TO_DESTROY_VM_ON_HYPERVISOR(1008), FAILED_TO_MIGRATE_VM_ON_HYPERVISOR(1009), HOST_IS_DISCONNECTED(1010), - OPERATION_FAILURE_GC_ELIGIBLE(1011); + OPERATION_FAILURE_GC_ELIGIBLE(1011), + HOST_PASSWORD_HAS_BEEN_CHANGED(1012), + ; private String code; private HostErrors(int id) { diff --git a/header/src/main/java/org/zstack/header/host/HostHardware.java b/header/src/main/java/org/zstack/header/host/HostHardware.java new file mode 100644 index 00000000000..7b5464eb26a --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostHardware.java @@ -0,0 +1,25 @@ +package org.zstack.header.host; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/5/27 17:44 + */ +public enum HostHardware { + CPU, + MEMORY, + DISK, + GPU, + POWERSUPPLY, + FAN, + RAID, + PHYSICAL_VOLUME, + UNKNOWN; + + public static HostHardware fromString(String name) { + try { + return HostHardware.valueOf(name.toUpperCase()); + } catch (IllegalArgumentException | NullPointerException e) { + return UNKNOWN; + } + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostHugepageExtensionPoint.java b/header/src/main/java/org/zstack/header/host/HostHugepageExtensionPoint.java new file mode 100644 index 00000000000..c39ab6bffae --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostHugepageExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.host; + +/** + * Created by boce.wang on 01/24/2025. + */ +public interface HostHugepageExtensionPoint { + boolean checkHugepageSupport(HostInventory host); +} diff --git a/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusInventory.java b/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusInventory.java new file mode 100644 index 00000000000..3eabd6f8164 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusInventory.java @@ -0,0 +1,137 @@ +package org.zstack.header.host; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/5/28 11:00 + */ +@PythonClassInventory +@Inventory(mappingVOClass = HostHwMonitorStatusVO.class, collectionValueOfMethod = "valueOf1") +public class HostHwMonitorStatusInventory implements Serializable { + private String uuid; + private HwMonitorStatus cpuStatus; + private HwMonitorStatus memoryStatus; + private HwMonitorStatus diskStatus; + private HwMonitorStatus fanStatus; + private HwMonitorStatus powerSupplyStatus; + private HwMonitorStatus raidStatus; + private HwMonitorStatus networkStatus; + private HwMonitorStatus gpuStatus; + private HwMonitorStatus temperatureStatus; + + protected HostHwMonitorStatusInventory(HostHwMonitorStatusVO vo) { + this.setUuid(vo.getUuid()); + this.setCpuStatus(vo.getCpuStatus()); + this.setMemoryStatus(vo.getMemoryStatus()); + this.setDiskStatus(vo.getDiskStatus()); + this.setFanStatus(vo.getFanStatus()); + this.setPowerSupplyStatus(vo.getPowerSupplyStatus()); + this.setRaidStatus(vo.getRaidStatus()); + this.setNetworkStatus(vo.getNicStatus()); + this.setGpuStatus(vo.getGpuStatus()); + this.setTemperatureStatus(vo.getTemperatureStatus()); + } + + public static HostHwMonitorStatusInventory valueOf(HostHwMonitorStatusVO vo) { + return new HostHwMonitorStatusInventory(vo); + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (HostHwMonitorStatusVO vo : vos) { + invs.add(HostHwMonitorStatusInventory.valueOf(vo)); + } + return invs; + } + + public HostHwMonitorStatusInventory() { + } + + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public HwMonitorStatus getCpuStatus() { + return cpuStatus; + } + + public void setCpuStatus(HwMonitorStatus cpuStatus) { + this.cpuStatus = cpuStatus; + } + + public HwMonitorStatus getMemoryStatus() { + return memoryStatus; + } + + public void setMemoryStatus(HwMonitorStatus memoryStatus) { + this.memoryStatus = memoryStatus; + } + + public HwMonitorStatus getDiskStatus() { + return diskStatus; + } + + public void setDiskStatus(HwMonitorStatus diskStatus) { + this.diskStatus = diskStatus; + } + + public HwMonitorStatus getFanStatus() { + return fanStatus; + } + + public void setFanStatus(HwMonitorStatus fanStatus) { + this.fanStatus = fanStatus; + } + + public HwMonitorStatus getPowerSupplyStatus() { + return powerSupplyStatus; + } + + public void setPowerSupplyStatus(HwMonitorStatus powerSupplyStatus) { + this.powerSupplyStatus = powerSupplyStatus; + } + + public HwMonitorStatus getRaidStatus() { + return raidStatus; + } + + public void setRaidStatus(HwMonitorStatus raidStatus) { + this.raidStatus = raidStatus; + } + + public HwMonitorStatus getNetworkStatus() { + return networkStatus; + } + + public void setNetworkStatus(HwMonitorStatus networkStatus) { + this.networkStatus = networkStatus; + } + + public HwMonitorStatus getGpuStatus() { + return gpuStatus; + } + + public void setGpuStatus(HwMonitorStatus gpuStatus) { + this.gpuStatus = gpuStatus; + } + + public HwMonitorStatus getTemperatureStatus() { + return temperatureStatus; + } + + public void setTemperatureStatus(HwMonitorStatus temperatureStatus) { + this.temperatureStatus = temperatureStatus; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusVO.java b/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusVO.java new file mode 100644 index 00000000000..85429398859 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusVO.java @@ -0,0 +1,140 @@ +package org.zstack.header.host; + +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/5/28 10:45 + */ +@Entity +@Table +@EntityGraph( + parents = { + @EntityGraph.Neighbour(type = HostVO.class, myField = "uuid", targetField = "uuid") + } +) +public class HostHwMonitorStatusVO { + @Id + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String uuid; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus cpuStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus memoryStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus diskStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus nicStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus gpuStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus powerSupplyStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus fanStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus raidStatus; + + @Column + @Enumerated(EnumType.STRING) + private HwMonitorStatus temperatureStatus; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public HwMonitorStatus getCpuStatus() { + return cpuStatus; + } + + public void setCpuStatus(HwMonitorStatus cpuStatus) { + this.cpuStatus = cpuStatus; + } + + public HwMonitorStatus getMemoryStatus() { + return memoryStatus; + } + + public void setMemoryStatus(HwMonitorStatus memoryStatus) { + this.memoryStatus = memoryStatus; + } + + public HwMonitorStatus getDiskStatus() { + return diskStatus; + } + + public void setDiskStatus(HwMonitorStatus diskStatus) { + this.diskStatus = diskStatus; + } + + public HwMonitorStatus getNicStatus() { + return nicStatus; + } + + public void setNicStatus(HwMonitorStatus nicStatus) { + this.nicStatus = nicStatus; + } + + public HwMonitorStatus getGpuStatus() { + return gpuStatus; + } + + public void setGpuStatus(HwMonitorStatus gpuStatus) { + this.gpuStatus = gpuStatus; + } + + public HwMonitorStatus getPowerSupplyStatus() { + return powerSupplyStatus; + } + + public void setPowerSupplyStatus(HwMonitorStatus powerSupplyStatus) { + this.powerSupplyStatus = powerSupplyStatus; + } + + public HwMonitorStatus getFanStatus() { + return fanStatus; + } + + public void setFanStatus(HwMonitorStatus fanStatus) { + this.fanStatus = fanStatus; + } + + public HwMonitorStatus getRaidStatus() { + return raidStatus; + } + + public void setRaidStatus(HwMonitorStatus raidStatus) { + this.raidStatus = raidStatus; + } + + public HwMonitorStatus getTemperatureStatus() { + return temperatureStatus; + } + + public void setTemperatureStatus(HwMonitorStatus temperatureStatus) { + this.temperatureStatus = temperatureStatus; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusVO_.java b/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusVO_.java new file mode 100644 index 00000000000..18ef61e1f7e --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostHwMonitorStatusVO_.java @@ -0,0 +1,23 @@ +package org.zstack.header.host; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/5/28 10:57 + */ +@StaticMetamodel(HostHwMonitorStatusVO.class) +public class HostHwMonitorStatusVO_ { + + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute cpuStatus; + public static volatile SingularAttribute memoryStatus; + public static volatile SingularAttribute diskStatus; + public static volatile SingularAttribute nicStatus; + public static volatile SingularAttribute gpuStatus; + public static volatile SingularAttribute powerSupplyStatus; + public static volatile SingularAttribute fanStatus; + public static volatile SingularAttribute raidStatus; + public static volatile SingularAttribute temperatureStatus; +} diff --git a/header/src/main/java/org/zstack/header/host/HostInventory.java b/header/src/main/java/org/zstack/header/host/HostInventory.java index 1e0b5e4a72a..35958b05003 100755 --- a/header/src/main/java/org/zstack/header/host/HostInventory.java +++ b/header/src/main/java/org/zstack/header/host/HostInventory.java @@ -131,6 +131,58 @@ public class HostInventory implements Serializable { joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "cpuNum")) private Integer cpuNum; + @Queryable(mappingClass = HostIpmiInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "ipmiAddress")) + private String ipmiAddress; + + @Queryable(mappingClass = HostIpmiInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "ipmiUsername")) + private String ipmiUsername; + + @Queryable(mappingClass = HostIpmiInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "ipmiPort")) + private Integer ipmiPort; + + @Queryable(mappingClass = HostIpmiInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "ipmiPowerStatus")) + private String ipmiPowerStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "cpuStatus")) + private HwMonitorStatus cpuStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "memoryStatus")) + private HwMonitorStatus memoryStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "diskStatus")) + private HwMonitorStatus diskStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "nicStatus")) + private HwMonitorStatus nicStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "gpuStatus")) + private HwMonitorStatus gpuStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "powerSupplyStatus")) + private HwMonitorStatus powerSupplyStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "fanStatus")) + private HwMonitorStatus fanStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "raidStatus")) + private HwMonitorStatus raidStatus; + + @Queryable(mappingClass = HostHwMonitorStatusInventory.class, + joinColumn = @JoinColumn(name = "uuid", referencedColumnName = "temperatureStatus")) + private HwMonitorStatus temperatureStatus; + private String architecture; /** @@ -163,6 +215,25 @@ protected HostInventory(HostVO vo) { this.setCpuSockets(vo.getCapacity().getCpuSockets()); this.setCpuNum(vo.getCapacity().getCpuNum()); } + if (vo.getIpmi() != null) { + this.setIpmiAddress(vo.getIpmi().getIpmiAddress()); + this.setIpmiPort(vo.getIpmi().getIpmiPort()); + this.setIpmiUsername(vo.getIpmi().getIpmiUsername()); + this.setIpmiPowerStatus(vo.getIpmi().getIpmiPowerStatus().toString()); + } + + if (vo.getHwMonitorStatus() != null) { + this.setCpuStatus(vo.getHwMonitorStatus().getCpuStatus()); + this.setMemoryStatus(vo.getHwMonitorStatus().getMemoryStatus()); + this.setDiskStatus(vo.getHwMonitorStatus().getDiskStatus()); + this.setFanStatus(vo.getHwMonitorStatus().getFanStatus()); + this.setPowerSupplyStatus(vo.getHwMonitorStatus().getPowerSupplyStatus()); + this.setRaidStatus(vo.getHwMonitorStatus().getRaidStatus()); + this.setNicStatus(vo.getHwMonitorStatus().getNicStatus()); + this.setGpuStatus(vo.getHwMonitorStatus().getGpuStatus()); + this.setTemperatureStatus(vo.getHwMonitorStatus().getTemperatureStatus()); + } + } public HostInventory() { @@ -323,4 +394,108 @@ public String getArchitecture() { public void setArchitecture(String architecture) { this.architecture = architecture; } + + public String getIpmiAddress() { + return ipmiAddress; + } + + public void setIpmiAddress(String ipmiAddress) { + this.ipmiAddress = ipmiAddress; + } + + public String getIpmiUsername() { + return ipmiUsername; + } + + public void setIpmiUsername(String ipmiUsername) { + this.ipmiUsername = ipmiUsername; + } + + public Integer getIpmiPort() { + return ipmiPort; + } + + public void setIpmiPort(Integer ipmiPort) { + this.ipmiPort = ipmiPort; + } + + public String getIpmiPowerStatus() { + return ipmiPowerStatus; + } + + public void setIpmiPowerStatus(String ipmiPowerStatus) { + this.ipmiPowerStatus = ipmiPowerStatus; + } + + public HwMonitorStatus getCpuStatus() { + return cpuStatus; + } + + public void setCpuStatus(HwMonitorStatus cpuStatus) { + this.cpuStatus = cpuStatus; + } + + public HwMonitorStatus getMemoryStatus() { + return memoryStatus; + } + + public void setMemoryStatus(HwMonitorStatus memoryStatus) { + this.memoryStatus = memoryStatus; + } + + public HwMonitorStatus getDiskStatus() { + return diskStatus; + } + + public void setDiskStatus(HwMonitorStatus diskStatus) { + this.diskStatus = diskStatus; + } + + public HwMonitorStatus getNicStatus() { + return nicStatus; + } + + public void setNicStatus(HwMonitorStatus nicStatus) { + this.nicStatus = nicStatus; + } + + public HwMonitorStatus getGpuStatus() { + return gpuStatus; + } + + public void setGpuStatus(HwMonitorStatus gpuStatus) { + this.gpuStatus = gpuStatus; + } + + public HwMonitorStatus getPowerSupplyStatus() { + return powerSupplyStatus; + } + + public void setPowerSupplyStatus(HwMonitorStatus powerSupplyStatus) { + this.powerSupplyStatus = powerSupplyStatus; + } + + public HwMonitorStatus getFanStatus() { + return fanStatus; + } + + public void setFanStatus(HwMonitorStatus fanStatus) { + this.fanStatus = fanStatus; + } + + public HwMonitorStatus getRaidStatus() { + return raidStatus; + } + + public void setRaidStatus(HwMonitorStatus raidStatus) { + this.raidStatus = raidStatus; + } + + public HwMonitorStatus getTemperatureStatus() { + return temperatureStatus; + } + + public void setTemperatureStatus(HwMonitorStatus temperatureStatus) { + this.temperatureStatus = temperatureStatus; + } } diff --git a/header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy index 6e86ece5220..aa9150ddbaa 100644 --- a/header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/host/HostInventoryDoc_zh_cn.groovy @@ -1,10 +1,7 @@ package org.zstack.header.host import java.lang.Long -import java.lang.Long -import java.lang.Long -import java.lang.Long -import java.sql.Timestamp +import java.lang.Integer import java.sql.Timestamp doc { @@ -77,6 +74,12 @@ doc { type "Long" since "0.6" } + field { + name "cpuSockets" + desc "物理CPU插槽数量" + type "Integer" + since "0.6" + } field { name "totalMemoryCapacity" desc "" @@ -89,6 +92,42 @@ doc { type "Long" since "0.6" } + field { + name "cpuNum" + desc "逻辑CPU数量" + type "Integer" + since "0.6" + } + field { + name "ipmiAddress" + desc "IPMI地址" + type "String" + since "0.6" + } + field { + name "ipmiUsername" + desc "IPMI用户名" + type "String" + since "0.6" + } + field { + name "ipmiPort" + desc "IPMI端口" + type "Integer" + since "0.6" + } + field { + name "ipmiPowerStatus" + desc "IPMI电源状态" + type "String" + since "0.6" + } + field { + name "architecture" + desc "" + type "String" + since "0.6" + } field { name "createDate" desc "创建时间" diff --git a/header/src/main/java/org/zstack/header/host/HostIpmiInventory.java b/header/src/main/java/org/zstack/header/host/HostIpmiInventory.java new file mode 100644 index 00000000000..81896e07d8e --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostIpmiInventory.java @@ -0,0 +1,101 @@ +package org.zstack.header.host; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.host.HostPowerStatus; +import org.zstack.header.message.GsonTransient; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.rest.APINoSee; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = HostIpmiVO.class, collectionValueOfMethod = "valueOf1") +public class HostIpmiInventory implements Serializable { + private String uuid; + private String ipmiAddress; + private String ipmiUsername; + private int ipmiPort; + + @GsonTransient + @APINoSee + private String ipmiPassword; + private String ipmiPowerStatus; + + protected HostIpmiInventory(HostIpmiVO vo) { + this.setUuid(vo.getUuid()); + this.setIpmiAddress(vo.getIpmiAddress()); + this.setIpmiUsername(vo.getIpmiUsername()); + this.setIpmiPort(vo.getIpmiPort()); + this.setIpmiPassword(vo.getIpmiPassword()); + this.setIpmiPowerStatus(vo.getIpmiPowerStatus().toString()); + } + + public static HostIpmiInventory valueOf(HostIpmiVO vo) { + return new HostIpmiInventory(vo); + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (HostIpmiVO vo : vos) { + invs.add(HostIpmiInventory.valueOf(vo)); + } + return invs; + } + + public HostIpmiInventory() { + } + + public String getUuid() { + return uuid; + } + + void setUuid(String $paramName) { + uuid = $paramName; + } + + public String getIpmiAddress() { + return ipmiAddress; + } + + void setIpmiAddress(String $paramName) { + ipmiAddress = $paramName; + } + + public String getIpmiUsername() { + return ipmiUsername; + } + + void setIpmiUsername(String $paramName) { + ipmiUsername = $paramName; + } + + public int getIpmiPort() { + return ipmiPort; + } + + void setIpmiPort(int $paramName) { + ipmiPort = $paramName; + } + + public String getIpmiPassword() { + return ipmiPassword; + } + + void setIpmiPassword(String $paramName) { + ipmiPassword = $paramName; + } + + public String getIpmiPowerStatus() { + return ipmiPowerStatus; + } + + void setIpmiPowerStatus(String $paramName) { + ipmiPowerStatus = $paramName; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostIpmiInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/HostIpmiInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..75955f7db0f --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostIpmiInventoryDoc_zh_cn.groovy @@ -0,0 +1,39 @@ +package org.zstack.header.host + + + +doc { + + title "物理机IPMI信息" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "0.6" + } + field { + name "ipmiAddress" + desc "IPMI地址" + type "String" + since "0.6" + } + field { + name "ipmiUsername" + desc "IPMI用户名" + type "String" + since "0.6" + } + field { + name "ipmiPort" + desc "IPMI端口" + type "int" + since "0.6" + } + field { + name "ipmiPowerStatus" + desc "IPMI电源状态" + type "String" + since "0.6" + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostIpmiVO.java b/header/src/main/java/org/zstack/header/host/HostIpmiVO.java new file mode 100644 index 00000000000..fa0948097b9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostIpmiVO.java @@ -0,0 +1,88 @@ +package org.zstack.header.host; + +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; + +/** + * @Author : jingwang + * @create 2023/4/13 10:32 AM + */ +@Entity +@Table +@EntityGraph( + parents = { + @EntityGraph.Neighbour(type = HostVO.class, myField = "uuid", targetField = "uuid") + } +) +public class HostIpmiVO { + @Id + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String uuid; + + @Column + private String ipmiAddress; + + @Column + private String ipmiUsername; + + @Column + private int ipmiPort; + + @Column + private String ipmiPassword; + + @Column + @Enumerated(EnumType.STRING) + private HostPowerStatus ipmiPowerStatus; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getIpmiAddress() { + return ipmiAddress; + } + + public void setIpmiAddress(String ipmiAddress) { + this.ipmiAddress = ipmiAddress; + } + + public String getIpmiUsername() { + return ipmiUsername; + } + + public void setIpmiUsername(String ipmiUsername) { + this.ipmiUsername = ipmiUsername; + } + + public int getIpmiPort() { + return ipmiPort; + } + + public void setIpmiPort(int ipmiPort) { + this.ipmiPort = ipmiPort; + } + + public String getIpmiPassword() { + return ipmiPassword; + } + + public void setIpmiPassword(String ipmiPassword) { + this.ipmiPassword = ipmiPassword; + } + + public HostPowerStatus getIpmiPowerStatus() { + return ipmiPowerStatus; + } + + public void setIpmiPowerStatus(HostPowerStatus ipmiPowerStatus) { + this.ipmiPowerStatus = ipmiPowerStatus; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostIpmiVO_.java b/header/src/main/java/org/zstack/header/host/HostIpmiVO_.java new file mode 100644 index 00000000000..fbf97c3b398 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostIpmiVO_.java @@ -0,0 +1,18 @@ +package org.zstack.header.host; + +import org.zstack.header.host.HostPowerStatus; +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(HostIpmiVO.class) +public class HostIpmiVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute ipmiAddress; + public static volatile SingularAttribute ipmiUsername; + public static volatile SingularAttribute ipmiPort; + public static volatile SingularAttribute ipmiPassword; + public static volatile SingularAttribute ipmiPowerStatus; +} diff --git a/header/src/main/java/org/zstack/header/host/HostNUMANode.java b/header/src/main/java/org/zstack/header/host/HostNUMANode.java index 58d484538bd..733a90cc828 100644 --- a/header/src/main/java/org/zstack/header/host/HostNUMANode.java +++ b/header/src/main/java/org/zstack/header/host/HostNUMANode.java @@ -2,6 +2,8 @@ import java.util.List; +import static org.zstack.utils.CollectionDSL.list; + public class HostNUMANode { public List distance; public List cpus; @@ -57,4 +59,15 @@ public List getVMsUuid() { public void setVMsUuid(List VMsUuid) { this.VMsUuid = VMsUuid; } + + public static HostNUMANode __example__() { + HostNUMANode node = new HostNUMANode(); + node.setNodeID("1"); + node.setDistance(list("0", "1")); + node.setCpus(list("0", "1")); + node.setFree(1L); + node.setSize(2L); + node.setVMsUuid(list("vm-1", "vm-2")); + return node; + } } diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkInterfaceServiceType.java b/header/src/main/java/org/zstack/header/host/HostNetworkInterfaceServiceType.java new file mode 100644 index 00000000000..deedb9141f3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkInterfaceServiceType.java @@ -0,0 +1,24 @@ +package org.zstack.header.host; + +import java.util.ArrayList; +import java.util.List; + +public enum HostNetworkInterfaceServiceType { + ManagementNetwork, + TenantNetwork, + StorageNetwork, + BackupNetwork, + MigrationNetwork; + + public static List fromStrings(List strings) { + List list = new ArrayList<>(); + for (String s : strings) { + try { + list.add(HostNetworkInterfaceServiceType.valueOf(s)); + } catch (IllegalArgumentException e) { + // Ignore + } + } + return list; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkInterfaceServiceTypeDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/HostNetworkInterfaceServiceTypeDoc_zh_cn.groovy new file mode 100644 index 00000000000..b52f257d446 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkInterfaceServiceTypeDoc_zh_cn.groovy @@ -0,0 +1,39 @@ +package org.zstack.header.host + + + +doc { + + title "网路服务类型" + + field { + name "ManagementNetwork" + desc "管理网络" + type "HostNetworkInterfaceServiceType" + since "4.7.11" + } + field { + name "TenantNetwork" + desc "业务网络" + type "HostNetworkInterfaceServiceType" + since "4.7.11" + } + field { + name "StorageNetwork" + desc "存储网络" + type "HostNetworkInterfaceServiceType" + since "4.7.11" + } + field { + name "BackupNetwork" + desc "备份网络" + type "HostNetworkInterfaceServiceType" + since "4.7.11" + } + field { + name "MigrationNetwork" + desc "迁移网络" + type "HostNetworkInterfaceServiceType" + since "4.7.11" + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkLabelExtensionPoint.java b/header/src/main/java/org/zstack/header/host/HostNetworkLabelExtensionPoint.java new file mode 100644 index 00000000000..90f4d45184c --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkLabelExtensionPoint.java @@ -0,0 +1,12 @@ +package org.zstack.header.host; + +import org.zstack.header.core.Completion; + +/** + * Created by boce.wang on 10/25/2024. + */ +public interface HostNetworkLabelExtensionPoint { + void deleteHostNetworkLabel(HostNetworkLabelInventory hostNetworkLabel, Completion completion); + + void updateHostNetworkLabel(HostNetworkLabelInventory hostNetworkLabel, String newLabel, Completion completion); +} diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkLabelInventory.java b/header/src/main/java/org/zstack/header/host/HostNetworkLabelInventory.java new file mode 100644 index 00000000000..d00fd7bee33 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkLabelInventory.java @@ -0,0 +1,96 @@ +package org.zstack.header.host; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by boce.wang on 10/24/2024. + */ +@PythonClassInventory +@Inventory(mappingVOClass = HostNetworkLabelVO.class) +public class HostNetworkLabelInventory implements Serializable { + + private String uuid; + + private String serviceType; + + private Boolean system; + + private Timestamp createDate; + + private Timestamp lastOpDate; + + protected HostNetworkLabelInventory(HostNetworkLabelVO vo) { + this.setUuid(vo.getUuid()); + this.setServiceType(vo.getServiceType()); + this.setSystem(vo.getSystem()); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + } + + public HostNetworkLabelInventory() { + } + + public static HostNetworkLabelInventory valueOf(HostNetworkLabelVO vo) { + return new HostNetworkLabelInventory(vo); + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(vos.size()); + for (HostNetworkLabelVO vo : vos) { + invs.add(HostNetworkLabelInventory.valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public Boolean getSystem() { + return system; + } + + public void setSystem(Boolean system) { + this.system = system; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkLabelInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/HostNetworkLabelInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..99dc14838e5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkLabelInventoryDoc_zh_cn.groovy @@ -0,0 +1,40 @@ +package org.zstack.header.host + +import java.lang.Boolean +import java.sql.Timestamp + +doc { + + title "在这里输入结构的名称" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.2.1" + } + field { + name "serviceType" + desc "" + type "String" + since "5.2.1" + } + field { + name "system" + desc "" + type "Boolean" + since "5.2.1" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.2.1" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.2.1" + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkLabelVO.java b/header/src/main/java/org/zstack/header/host/HostNetworkLabelVO.java new file mode 100644 index 00000000000..068a594196c --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkLabelVO.java @@ -0,0 +1,68 @@ +package org.zstack.header.host; + +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * Created by boce.wang on 10/24/2024. + */ +@Entity +@Table +public class HostNetworkLabelVO implements ToInventory { + @Id + @Column + private String uuid; + + @Column + private String serviceType; + + @Column + private Boolean system; + + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public Boolean getSystem() { + return system; + } + + public void setSystem(Boolean system) { + this.system = system; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostNetworkLabelVO_.java b/header/src/main/java/org/zstack/header/host/HostNetworkLabelVO_.java new file mode 100644 index 00000000000..3220ddc26e5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostNetworkLabelVO_.java @@ -0,0 +1,16 @@ +package org.zstack.header.host; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; +/** + * Created by boce.wang on 10/24/2024. + */ +@StaticMetamodel(HostNetworkLabelVO.class) +public class HostNetworkLabelVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute serviceType; + public static volatile SingularAttribute system; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/host/HostOperationSystem.java b/header/src/main/java/org/zstack/header/host/HostOperationSystem.java new file mode 100644 index 00000000000..a0cab8a9a3b --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostOperationSystem.java @@ -0,0 +1,50 @@ +package org.zstack.header.host; + +import java.util.Objects; + +/** + * Define the description field for the operating system version for host. + * + * Created by Wenhao.Zhang on 23/04/07 + */ +public class HostOperationSystem { + public final String distribution; + public final String release; + public final String version; + + private HostOperationSystem(String osDistribution, String release, String version) { + this.distribution = osDistribution; + this.release = release; + this.version = version; + } + + public boolean isValid() { + return distribution != null && release != null && version != null; + } + + @Override + public String toString() { + return String.format("%s %s %s", distribution, release, version); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + HostOperationSystem that = (HostOperationSystem) o; + return Objects.equals(distribution, that.distribution) + && Objects.equals(release, that.release) + && Objects.equals(version, that.version); + } + + @Override + public int hashCode() { + return Objects.hash(distribution, release, version); + } + + public static HostOperationSystem of(String distribution, String osRelease, String osVersion) { + return new HostOperationSystem(distribution, osRelease, osVersion); + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostPowerManagementMethod.java b/header/src/main/java/org/zstack/header/host/HostPowerManagementMethod.java new file mode 100644 index 00000000000..4bdbc65a67e --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostPowerManagementMethod.java @@ -0,0 +1,13 @@ +package org.zstack.header.host; + +/** + * @Author : jingwang + * @create 2023/4/24 5:16 PM + */ +public enum HostPowerManagementMethod { + AGENT, + SSH, + IPMI, + AUTO + ; +} diff --git a/header/src/main/java/org/zstack/header/host/HostPowerStatus.java b/header/src/main/java/org/zstack/header/host/HostPowerStatus.java new file mode 100644 index 00000000000..4d5ea9e944e --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostPowerStatus.java @@ -0,0 +1,66 @@ +package org.zstack.header.host; + +import org.zstack.header.exception.CloudRuntimeException; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Author : jingwang + * @create 2023/4/13 10:06 AM + */ +public enum HostPowerStatus { + POWER_ON, + POWER_OFF, + POWER_SHUTDOWN, + POWER_BOOTING, + POWER_UNKNOWN, + UN_CONFIGURED; + + static { + POWER_ON.transactions( + new Transaction(HostPowerStatusEvent.on, POWER_ON), + new Transaction(HostPowerStatusEvent.off, POWER_SHUTDOWN) + ); + POWER_OFF.transactions( + new Transaction(HostPowerStatusEvent.on, POWER_BOOTING), + new Transaction(HostPowerStatusEvent.off, POWER_OFF) + ); + POWER_SHUTDOWN.transactions( + new Transaction(HostPowerStatusEvent.off, POWER_SHUTDOWN) + ); + POWER_BOOTING.transactions( + new Transaction(HostPowerStatusEvent.on, POWER_BOOTING), + new Transaction(HostPowerStatusEvent.off, POWER_SHUTDOWN) + ); + } + + + private static class Transaction { + HostPowerStatusEvent event; + HostPowerStatus nextStatus; + + private Transaction(HostPowerStatusEvent event, HostPowerStatus nextStatus) { + this.event = event; + this.nextStatus = nextStatus; + } + } + + private void transactions(HostPowerStatus.Transaction... transactions) { + for (HostPowerStatus.Transaction tran : transactions) { + transactionMap.put(tran.event, tran); + } + } + + private Map transactionMap = new HashMap(); + + public HostPowerStatus nextStatus(HostPowerStatusEvent event) { + HostPowerStatus.Transaction tran = transactionMap.get(event); + if (tran == null) { + throw new CloudRuntimeException(String.format("cannot find next status for current status[%s] on transaction event[%s]", + this, event)); + } + + return tran.nextStatus; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostPowerStatusEvent.java b/header/src/main/java/org/zstack/header/host/HostPowerStatusEvent.java new file mode 100644 index 00000000000..e6260d9df23 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostPowerStatusEvent.java @@ -0,0 +1,10 @@ +package org.zstack.header.host; + +/** + * @Author : jingwang + * @create 2023/5/8 1:42 PM + */ +public enum HostPowerStatusEvent { + on, + off +} diff --git a/header/src/main/java/org/zstack/header/host/HostResizeVolumeExtensionPoint.java b/header/src/main/java/org/zstack/header/host/HostResizeVolumeExtensionPoint.java new file mode 100644 index 00000000000..d1a14188180 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostResizeVolumeExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.host; + +import org.zstack.header.volume.VolumeInventory; + +/** + * Created by kayo on 2018/4/2. + */ +public interface HostResizeVolumeExtensionPoint { + HostResizeVolumeStruct beforeKvmHostResizeVolume(HostResizeVolumeStruct struct, VolumeInventory vol, String hostUuid); +} diff --git a/header/src/main/java/org/zstack/header/host/HostResizeVolumeStruct.java b/header/src/main/java/org/zstack/header/host/HostResizeVolumeStruct.java new file mode 100644 index 00000000000..2f6774c6e14 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HostResizeVolumeStruct.java @@ -0,0 +1,35 @@ +package org.zstack.header.host; + +/** + * @author Xingwei Yu + * @date 2025/8/12 14:20 + */ +public class HostResizeVolumeStruct { + private String deviceType; + String installPath; + long size; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/header/src/main/java/org/zstack/header/host/HostVO.java b/header/src/main/java/org/zstack/header/host/HostVO.java index 2f1e816fabe..319c26750c4 100755 --- a/header/src/main/java/org/zstack/header/host/HostVO.java +++ b/header/src/main/java/org/zstack/header/host/HostVO.java @@ -28,6 +28,16 @@ public class HostVO extends HostAO { @NoView private HostCapacityVO capacity; + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "uuid") + @NoView + private HostIpmiVO ipmi; + + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "uuid") + @NoView + private HostHwMonitorStatusVO hwMonitorStatus; + public HostCapacityVO getCapacity() { return capacity; } @@ -36,6 +46,22 @@ public void setCapacity(HostCapacityVO capacity) { this.capacity = capacity; } + public HostIpmiVO getIpmi() { + return ipmi; + } + + public void setIpmi(HostIpmiVO ipmi) { + this.ipmi = ipmi; + } + + public HostHwMonitorStatusVO getHwMonitorStatus() { + return hwMonitorStatus; + } + + public void setHwMonitorStatus(HostHwMonitorStatusVO hwMonitorStatus) { + this.hwMonitorStatus = hwMonitorStatus; + } + public HostVO() { } @@ -52,6 +78,8 @@ protected HostVO(HostVO vo) { this.setUuid(vo.getUuid()); this.setZoneUuid(vo.getZoneUuid()); this.setCapacity(vo.getCapacity()); + this.setIpmi(vo.getIpmi()); + this.setHwMonitorStatus(vo.getHwMonitorStatus()); } } diff --git a/header/src/main/java/org/zstack/header/host/HwMonitorStatus.java b/header/src/main/java/org/zstack/header/host/HwMonitorStatus.java new file mode 100644 index 00000000000..fa5e7fa7ed2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HwMonitorStatus.java @@ -0,0 +1,11 @@ +package org.zstack.header.host; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/7/1 16:14 + */ +public enum HwMonitorStatus { + Normal, + Error, + Unknown +} diff --git a/header/src/main/java/org/zstack/header/host/HwMonitorStatusDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/host/HwMonitorStatusDoc_zh_cn.groovy new file mode 100644 index 00000000000..b31e5718c9f --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/HwMonitorStatusDoc_zh_cn.groovy @@ -0,0 +1,27 @@ +package org.zstack.header.host + + + +doc { + + title "硬件监控状态" + + field { + name "Normal" + desc "正常状态" + type "HwMonitorStatus" + since "5.3.6" + } + field { + name "Error" + desc "错误状态" + type "HwMonitorStatus" + since "5.3.6" + } + field { + name "Unknown" + desc "未知状态" + type "HwMonitorStatus" + since "5.3.6" + } +} diff --git a/header/src/main/java/org/zstack/header/host/HypervisorFactory.java b/header/src/main/java/org/zstack/header/host/HypervisorFactory.java index d2119ec1ae7..ba79ac08d4e 100755 --- a/header/src/main/java/org/zstack/header/host/HypervisorFactory.java +++ b/header/src/main/java/org/zstack/header/host/HypervisorFactory.java @@ -1,5 +1,13 @@ package org.zstack.header.host; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.exception.CloudRuntimeException; + +import java.util.Collection; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + public interface HypervisorFactory { HostVO createHost(HostVO vo, AddHostMessage msg); @@ -10,4 +18,33 @@ public interface HypervisorFactory { HostInventory getHostInventory(HostVO vo); HostInventory getHostInventory(String uuid); + + /** + *

New added hosts need to check properties + * during the process of adding to the cluster. + * + *

The items that need to be checked are as follows: + * + *

  • Host operating system + *
    to ensure that the operating system of this host + * matches that of other hosts in the cluster. + *
  • + *

    + */ + default ErrorCode checkNewAddedHost(HostVO vo) { + return null; + } + + default HostOperationSystem getHostOS(String uuid) { + throw new CloudRuntimeException( + String.format("Obtaining operation system of %s host is not supported", getHypervisorType())); + } + + default Map getHostOsMap(Collection hostUuidList) { + return hostUuidList.stream().collect(Collectors.toMap(Function.identity(), this::getHostOS)); + } + + default boolean supportGetHostOs() { + return false; + } } diff --git a/header/src/main/java/org/zstack/header/host/HypervisorType.java b/header/src/main/java/org/zstack/header/host/HypervisorType.java index f2f08c753a1..8d48d0f4e6a 100755 --- a/header/src/main/java/org/zstack/header/host/HypervisorType.java +++ b/header/src/main/java/org/zstack/header/host/HypervisorType.java @@ -18,7 +18,7 @@ public HypervisorType(String typeName, boolean exposed) { } public static boolean hasType(String type) { - return types.keySet().contains(type); + return types.containsKey(type); } public static HypervisorType valueOf(String typeName) { @@ -44,7 +44,7 @@ public String toString() { @Override public boolean equals(Object t) { - if (t == null || !(t instanceof HypervisorType)) { + if (!(t instanceof HypervisorType)) { return false; } diff --git a/header/src/main/java/org/zstack/header/host/MigrateVmOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/host/MigrateVmOnHypervisorMsg.java index debd0da359d..21a86817d19 100755 --- a/header/src/main/java/org/zstack/header/host/MigrateVmOnHypervisorMsg.java +++ b/header/src/main/java/org/zstack/header/host/MigrateVmOnHypervisorMsg.java @@ -3,6 +3,8 @@ import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.vm.VmInstanceInventory; +import java.util.Map; + public class MigrateVmOnHypervisorMsg extends NeedReplyMessage implements HostMessage { public static enum StorageMigrationPolicy { FullCopy, @@ -15,6 +17,27 @@ public static enum StorageMigrationPolicy { private String strategy; private StorageMigrationPolicy storageMigrationPolicy; private boolean migrateFromDestination; + // A map from old disk to new disk + private Map diskMigrationMap; + private boolean reload; + private Integer downTime; + private long bandwidth; + + public Integer getDownTime() { + return downTime; + } + + public void setDownTime(Integer downTime) { + this.downTime = downTime; + } + + public boolean isReload() { + return reload; + } + + public void setReload(boolean reload) { + this.reload = reload; + } public StorageMigrationPolicy getStorageMigrationPolicy() { return storageMigrationPolicy; @@ -68,4 +91,20 @@ public boolean isMigrateFromDestination() { public void setMigrateFromDestination(boolean migrateFromDestination) { this.migrateFromDestination = migrateFromDestination; } + + public Map getDiskMigrationMap() { + return diskMigrationMap; + } + + public void setDiskMigrationMap(Map diskMigrationMap) { + this.diskMigrationMap = diskMigrationMap; + } + + public long getBandwidth() { + return bandwidth; + } + + public void setBandwidth(long bandwidth) { + this.bandwidth = bandwidth; + } } diff --git a/header/src/main/java/org/zstack/header/host/PackageInfo.java b/header/src/main/java/org/zstack/header/host/PackageInfo.java index dacf73641de..61841ebb629 100755 --- a/header/src/main/java/org/zstack/header/host/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/host/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "物理机") +@PackageAPIInfo( + APICategoryName = "物理机", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/host/PowerOnHostMsg.java b/header/src/main/java/org/zstack/header/host/PowerOnHostMsg.java new file mode 100644 index 00000000000..d8ecb034bdd --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/PowerOnHostMsg.java @@ -0,0 +1,33 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author : jingwang + * @create 2023/4/20 6:15 PM + */ +public class PowerOnHostMsg extends NeedReplyMessage implements HostMessage { + private String uuid; + private boolean returnEarly; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public boolean isReturnEarly() { + return returnEarly; + } + + public void setReturnEarly(boolean returnEarly) { + this.returnEarly = returnEarly; + } + + @Override + public String getHostUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/PowerOnHostReply.java b/header/src/main/java/org/zstack/header/host/PowerOnHostReply.java new file mode 100644 index 00000000000..e56f55e91a5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/PowerOnHostReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * @Author : jingwang + * @create 2023/4/24 2:49 PM + */ +public class PowerOnHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/host/PullVolumeSnapshotOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/host/PullVolumeSnapshotOnHypervisorMsg.java new file mode 100644 index 00000000000..c1577a1d9eb --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/PullVolumeSnapshotOnHypervisorMsg.java @@ -0,0 +1,54 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeInventory; + +public class PullVolumeSnapshotOnHypervisorMsg extends NeedReplyMessage implements HostMessage { + VolumeInventory volume; + private String srcSnapshotParentPath; + private VolumeSnapshotInventory srcSnapshot; + private VolumeSnapshotInventory dstSnapshot; + private String hostUuid; + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } + + public String getSrcSnapshotParentPath() { + return srcSnapshotParentPath; + } + + public void setSrcSnapshotParentPath(String srcSnapshotParentPath) { + this.srcSnapshotParentPath = srcSnapshotParentPath; + } + + public VolumeSnapshotInventory getSrcSnapshot() { + return srcSnapshot; + } + + public void setSrcSnapshot(VolumeSnapshotInventory srcSnapshot) { + this.srcSnapshot = srcSnapshot; + } + + public VolumeSnapshotInventory getDstSnapshot() { + return dstSnapshot; + } + + public void setDstSnapshot(VolumeSnapshotInventory dstSnapshot) { + this.dstSnapshot = dstSnapshot; + } + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/host/PullVolumeSnapshotOnHypervisorReply.java b/header/src/main/java/org/zstack/header/host/PullVolumeSnapshotOnHypervisorReply.java new file mode 100644 index 00000000000..13d109c48d5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/PullVolumeSnapshotOnHypervisorReply.java @@ -0,0 +1,17 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + */ +public class PullVolumeSnapshotOnHypervisorReply extends MessageReply { + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/header/src/main/java/org/zstack/header/host/RebootHostMsg.java b/header/src/main/java/org/zstack/header/host/RebootHostMsg.java new file mode 100644 index 00000000000..778909da508 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/RebootHostMsg.java @@ -0,0 +1,42 @@ +package org.zstack.header.host; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author : jingwang + * @create 2023/4/21 4:42 PM + */ +public class RebootHostMsg extends NeedReplyMessage implements HostMessage { + private String uuid; + private boolean returnEarly; + private HostPowerManagementMethod method = HostPowerManagementMethod.AUTO; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public boolean isReturnEarly() { + return returnEarly; + } + + public void setReturnEarly(boolean returnEarly) { + this.returnEarly = returnEarly; + } + + @Override + public String getHostUuid() { + return uuid; + } + + public HostPowerManagementMethod getMethod() { + return method; + } + + public void setMethod(HostPowerManagementMethod method) { + this.method = method; + } +} diff --git a/header/src/main/java/org/zstack/header/host/RebootHostReply.java b/header/src/main/java/org/zstack/header/host/RebootHostReply.java new file mode 100644 index 00000000000..eab37113092 --- /dev/null +++ b/header/src/main/java/org/zstack/header/host/RebootHostReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.host; + +import org.zstack.header.message.MessageReply; + +/** + * @Author : jingwang + * @create 2023/4/23 1:34 PM + */ +public class RebootHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/host/ReconnectHostMsg.java b/header/src/main/java/org/zstack/header/host/ReconnectHostMsg.java index 309e5427265..0a6232e7db0 100755 --- a/header/src/main/java/org/zstack/header/host/ReconnectHostMsg.java +++ b/header/src/main/java/org/zstack/header/host/ReconnectHostMsg.java @@ -10,6 +10,7 @@ public class ReconnectHostMsg extends NeedReplyMessage implements HostMessage, ConfigurableTimeoutMessage { private String hostUuid; private boolean skipIfHostConnected; + private boolean calledByAPI; public boolean isSkipIfHostConnected() { return skipIfHostConnected; @@ -27,4 +28,12 @@ public String getHostUuid() { public void setHostUuid(String hostUuid) { this.hostUuid = hostUuid; } + + public boolean isCalledByAPI() { + return calledByAPI; + } + + public void setCalledByAPI(boolean calledByAPI) { + this.calledByAPI = calledByAPI; + } } diff --git a/header/src/main/java/org/zstack/header/host/ShutdownHostMsg.java b/header/src/main/java/org/zstack/header/host/ShutdownHostMsg.java index 76d4955d4a4..1aa5d0f9dd1 100644 --- a/header/src/main/java/org/zstack/header/host/ShutdownHostMsg.java +++ b/header/src/main/java/org/zstack/header/host/ShutdownHostMsg.java @@ -7,9 +7,19 @@ */ public class ShutdownHostMsg extends NeedReplyMessage implements HostMessage { private String uuid; + /** + * If true, the shutdown task execution should wait for the running task to complete. + */ private boolean waitTaskCompleted; private Long maxWaitTime; + + /** + * If true, the shutdown task will return immediately without waiting for the host to be powered off. + */ private boolean returnEarly; + private String originState; + private HostPowerManagementMethod method; + private boolean force = false; @Override public String getHostUuid() { @@ -47,4 +57,28 @@ public boolean isReturnEarly() { public void setReturnEarly(boolean returnEarly) { this.returnEarly = returnEarly; } + + public HostPowerManagementMethod getMethod() { + return method; + } + + public void setMethod(HostPowerManagementMethod method) { + this.method = method; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public String getOriginState() { + return originState; + } + + public void setOriginState(String originState) { + this.originState = originState; + } } diff --git a/header/src/main/java/org/zstack/header/identity/APIAddUserToGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIAddUserToGroupMsgDoc_zh_cn.groovy index 6ed63ebad00..76e353cb8f5 100644 --- a/header/src/main/java/org/zstack/header/identity/APIAddUserToGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIAddUserToGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "groupUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIAttachPoliciesToUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIAttachPoliciesToUserMsgDoc_zh_cn.groovy index da078e494ea..7608169ff97 100644 --- a/header/src/main/java/org/zstack/header/identity/APIAttachPoliciesToUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIAttachPoliciesToUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "policyUuids" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserGroupMsgDoc_zh_cn.groovy index 7ff3638f8ae..6b5c94bbf0c 100644 --- a/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "groupUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsg.java b/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsg.java index d8f32f5c730..bd18a39ab0d 100755 --- a/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsg.java @@ -10,6 +10,7 @@ @RestRequest( path = "/accounts/users/{userUuid}/policies", responseClass = APIAttachPolicyToUserEvent.class, + parameterName = "params", method = HttpMethod.POST ) public class APIAttachPolicyToUserMsg extends APIMessage implements AccountMessage { diff --git a/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsgDoc_zh_cn.groovy index 2c92cec6c66..f90edcb911d 100644 --- a/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIAttachPolicyToUserMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "userUuid" - enclosedIn "" + enclosedIn "params" desc "用户UUID" location "url" type "String" optional false since "0.6" - } column { name "policyUuid" - enclosedIn "" + enclosedIn "params" desc "权限策略UUID" location "body" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIChangeResourceOwnerMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIChangeResourceOwnerMsgDoc_zh_cn.groovy index 08122579811..34edf33fb4f 100644 --- a/header/src/main/java/org/zstack/header/identity/APIChangeResourceOwnerMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIChangeResourceOwnerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionMsgDoc_zh_cn.groovy index 06704563ffd..e116d5982d4 100644 --- a/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "apiNames" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionReply.java b/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionReply.java index 568ba11a91d..01d5512208a 100755 --- a/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionReply.java +++ b/header/src/main/java/org/zstack/header/identity/APICheckApiPermissionReply.java @@ -24,7 +24,7 @@ public void setInventory(Map inventory) { public static APICheckApiPermissionReply __example__() { APICheckApiPermissionReply reply = new APICheckApiPermissionReply(); Map inventory = new HashMap<>(); - inventory.put("APICheckApiPermissionMsg", StatementEffect.Allow.toString()); + inventory.put("APICheckApiPermissionMsg", PolicyStatementEffect.Allow.toString()); reply.setInventory(inventory); return reply; } diff --git a/header/src/main/java/org/zstack/header/identity/APICreateAccountMsg.java b/header/src/main/java/org/zstack/header/identity/APICreateAccountMsg.java index ac06c354534..8c767dcf935 100755 --- a/header/src/main/java/org/zstack/header/identity/APICreateAccountMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APICreateAccountMsg.java @@ -1,6 +1,7 @@ package org.zstack.header.identity; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.log.NoLogging; import org.zstack.header.message.APICreateMessage; import org.zstack.header.message.APIEvent; @@ -13,15 +14,18 @@ path = "/accounts", method = HttpMethod.POST, parameterName = "params", - responseClass = APICreateAccountEvent.class + responseClass = APICreateAccountEvent.class, + morphTransform = Constants.MORPH_TRANSFORM_IAM1 ) public class APICreateAccountMsg extends APICreateMessage implements APIAuditor { @APIParam(maxLength = 255) private String name; + + @APIParam(maxLength = 255, password = true) @NoLogging private String password; - @APIParam(validValues = {"SystemAdmin", "Normal"}, required = false) + @APIParam(validValues = {"SystemAdmin", "Normal", "ThirdParty"}, required = false) private String type; @APIParam(maxLength = 2048, required = false) private String description; diff --git a/header/src/main/java/org/zstack/header/identity/APICreateAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APICreateAccountMsgDoc_zh_cn.groovy index a74a2e6f3d3..e9d47f04743 100644 --- a/header/src/main/java/org/zstack/header/identity/APICreateAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APICreateAccountMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "type" @@ -59,7 +57,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -69,7 +66,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -79,7 +75,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +84,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APICreatePolicyEvent.java b/header/src/main/java/org/zstack/header/identity/APICreatePolicyEvent.java index 6c1109fd04e..4558534f067 100755 --- a/header/src/main/java/org/zstack/header/identity/APICreatePolicyEvent.java +++ b/header/src/main/java/org/zstack/header/identity/APICreatePolicyEvent.java @@ -34,7 +34,7 @@ public static APICreatePolicyEvent __example__() { inventory.setName("USER-RESET-PASSWORD"); PolicyStatement s = new PolicyStatement(); s.setName(String.format("user-reset-password-%s", inventory.getUuid())); - s.setEffect(StatementEffect.Allow); + s.setEffect(PolicyStatementEffect.Allow); s.addAction(String.format("%s:%s", AccountConstant.ACTION_CATEGORY, APIUpdateUserMsg.class.getSimpleName())); inventory.setStatements(list(s)); diff --git a/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsg.java b/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsg.java index 077fafd1c9c..af30ad57792 100755 --- a/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsg.java @@ -1,6 +1,7 @@ package org.zstack.header.identity; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.message.APICreateMessage; import org.zstack.header.message.APIEvent; import org.zstack.header.message.APIMessage; @@ -17,7 +18,8 @@ path = "/accounts/policies", method = HttpMethod.POST, responseClass = APICreatePolicyEvent.class, - parameterName = "params" + parameterName = "params", + morphTransform = Constants.MORPH_TRANSFORM_IAM1 ) public class APICreatePolicyMsg extends APICreateMessage implements AccountMessage, APIAuditor { @APIParam(maxLength = 255) @@ -63,7 +65,7 @@ public static APICreatePolicyMsg __example__() { PolicyStatement s = new PolicyStatement(); s.setName(String.format("user-reset-password-%s", uuid())); - s.setEffect(StatementEffect.Allow); + s.setEffect(PolicyStatementEffect.Allow); s.addAction(String.format("%s:%s", AccountConstant.ACTION_CATEGORY, APIUpdateUserMsg.class.getSimpleName())); msg.setStatements(list(s)); diff --git a/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsgDoc_zh_cn.groovy index 8099c6045d0..a7dfaebff69 100644 --- a/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APICreatePolicyMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "statements" @@ -49,7 +47,6 @@ doc { type "List" optional false since "0.6" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APICreateUserGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APICreateUserGroupMsgDoc_zh_cn.groovy index 0fb48f92682..575f9c1afb3 100644 --- a/header/src/main/java/org/zstack/header/identity/APICreateUserGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APICreateUserGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APICreateUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APICreateUserMsgDoc_zh_cn.groovy index 318a5a135a5..67efbb74540 100644 --- a/header/src/main/java/org/zstack/header/identity/APICreateUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APICreateUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsg.java b/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsg.java index 6a95307a1cd..7f7dddbd901 100755 --- a/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsg.java @@ -1,9 +1,8 @@ package org.zstack.header.identity; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.message.APIDeleteMessage; -import org.zstack.header.message.APIEvent; -import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; @@ -14,7 +13,8 @@ @RestRequest( path = "/accounts/{uuid}", method = HttpMethod.DELETE, - responseClass = APIDeleteAccountEvent.class + responseClass = APIDeleteAccountEvent.class, + morphTransform = Constants.MORPH_TRANSFORM_IAM1 ) public class APIDeleteAccountMsg extends APIDeleteMessage implements AccountMessage { @APIParam(resourceType = AccountVO.class, successIfResourceNotExisting = true) diff --git a/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsgDoc_zh_cn.groovy index 7fa8185fd72..aba80b0dc35 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDeleteAccountMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsg.java b/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsg.java index 6fcd8f91217..b5338ec0126 100755 --- a/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsg.java @@ -1,9 +1,8 @@ package org.zstack.header.identity; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.message.APIDeleteMessage; -import org.zstack.header.message.APIEvent; -import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; @@ -14,7 +13,8 @@ @RestRequest( path = "/accounts/policies/{uuid}", method = HttpMethod.DELETE, - responseClass = APIDeletePolicyEvent.class + responseClass = APIDeletePolicyEvent.class, + morphTransform = Constants.MORPH_TRANSFORM_IAM1 ) public class APIDeletePolicyMsg extends APIDeleteMessage implements AccountMessage { @APIParam(resourceType = PolicyVO.class, successIfResourceNotExisting = true) diff --git a/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsgDoc_zh_cn.groovy index c54711edcfe..918d6cfaa98 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDeletePolicyMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDeleteUserGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDeleteUserGroupMsgDoc_zh_cn.groovy index 1c85b6fef3e..ef044cd9455 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDeleteUserGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDeleteUserGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDeleteUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDeleteUserMsgDoc_zh_cn.groovy index 833999b87cc..1a37ff0b5bb 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDeleteUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDeleteUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDetachPoliciesFromUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDetachPoliciesFromUserMsgDoc_zh_cn.groovy index 9ce280ad0f6..7cc824b712f 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDetachPoliciesFromUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDetachPoliciesFromUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "userUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserGroupMsgDoc_zh_cn.groovy index 71c2ea4028d..0cc906ac134 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "groupUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserMsgDoc_zh_cn.groovy index 411c43dd809..5925b481819 100644 --- a/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIDetachPolicyFromUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "userUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIGetAccountQuotaUsageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIGetAccountQuotaUsageMsgDoc_zh_cn.groovy index bdd45e1ee23..5ce719daf21 100644 --- a/header/src/main/java/org/zstack/header/identity/APIGetAccountQuotaUsageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIGetAccountQuotaUsageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIGetResourceAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIGetResourceAccountMsgDoc_zh_cn.groovy index c5873cb3104..87c0595bb0e 100644 --- a/header/src/main/java/org/zstack/header/identity/APIGetResourceAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIGetResourceAccountMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIGetSupportedIdentityModelsMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIGetSupportedIdentityModelsMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..8d18fa89ed8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/APIGetSupportedIdentityModelsMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.header.identity + +import org.zstack.header.identity.APIGetSupportedIdentityModelsReply + +doc { + title "GetSupportedIdentityModels" + + category "identity" + + desc """获取支持的账户类型""" + + rest { + request { + url "GET /v1/identity-models" + + + + clz APIGetSupportedIdentityModelsMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "3.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "3.7.0" + } + } + } + + response { + clz APIGetSupportedIdentityModelsReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/identity/APIGetSupportedIdentityModelsReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIGetSupportedIdentityModelsReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..1fd1b59d0bd --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/APIGetSupportedIdentityModelsReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.identity + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取支持的账户类型的结果" + + field { + name "configs" + desc "" + type "List" + since "3.7.0" + } + field { + name "success" + desc "" + type "boolean" + since "3.7.0" + } + ref { + name "error" + path "org.zstack.header.identity.APIGetSupportedIdentityModelsReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/identity/APILogInAuditorReply.java b/header/src/main/java/org/zstack/header/identity/APILogInAuditorReply.java index 97838b52c29..1e776b3f646 100644 --- a/header/src/main/java/org/zstack/header/identity/APILogInAuditorReply.java +++ b/header/src/main/java/org/zstack/header/identity/APILogInAuditorReply.java @@ -7,4 +7,4 @@ * Date:2019/4/24 */ public class APILogInAuditorReply extends APIReply { -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsg.java b/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsg.java index ee3e9f7606e..d9dac2ffdd3 100755 --- a/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsg.java @@ -2,6 +2,8 @@ import org.apache.commons.lang.StringUtils; import org.springframework.http.HttpMethod; +import org.zstack.header.identity.login.APICaptchaMessage; +import org.zstack.header.core.encrypt.EncryptionParamAllowed; import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; @@ -18,7 +20,8 @@ method = HttpMethod.PUT, responseClass = APILogInReply.class ) -public class APILogInByAccountMsg extends APISessionMessage implements APILoginAuditor { +@EncryptionParamAllowed(actions = { EncryptionParamAllowed.ACTION_PUT_USER_INFO_INTO_SYSTEM_TAG }) +public class APILogInByAccountMsg extends APISessionMessage implements APILoginAuditor, APICaptchaMessage { @APIParam private String accountName; @APIParam(password = true) @@ -33,7 +36,6 @@ public class APILogInByAccountMsg extends APISessionMessage implements APILoginA @APIParam(required = false) private Map clientInfo; - public String getAccountName() { return accountName; } @@ -42,10 +44,6 @@ public void setAccountName(String accountName) { this.accountName = accountName; } - public String getPassword() { - return password; - } - public void setPassword(String password) { this.password = password; } @@ -105,8 +103,26 @@ public LoginResult loginAudit(APIMessage msg, APIReply reply) { if (clientInfo != null && !clientInfo.isEmpty()) { clientIp = StringUtils.isNotEmpty(clientInfo.get("clientIp")) ? clientInfo.get("clientIp") : ""; clientBrowser = StringUtils.isNotEmpty(clientInfo.get("clientBrowser")) ? clientInfo.get("clientBrowser") : ""; + } else { + clientIp = StringUtils.isNotBlank(msg.getClientIp()) ? msg.getClientIp() : ""; + clientBrowser = StringUtils.isNotBlank(msg.getClientBrowser()) ? msg.getClientBrowser() : ""; } - String resourceUuid = reply.isSuccess() ? amsg.getSession().getUuid() : ""; + String resourceUuid = reply.isSuccess() ? ((APILogInReply) reply).getInventory().getUuid() : ""; return new LoginResult(clientIp, clientBrowser, resourceUuid, SessionVO.class); } + + @Override + public String getUsername() { + return accountName; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getLoginType() { + return AccountConstant.LOGIN_TYPE; + } } diff --git a/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsgDoc_zh_cn.groovy index dc707043386..93e7ab813b0 100644 --- a/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APILogInByAccountMsgDoc_zh_cn.groovy @@ -15,7 +15,6 @@ doc { - clz APILogInByAccountMsg.class desc """使用账户身份登录""" @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -40,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "captchaUuid" @@ -50,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "verifyCode" @@ -60,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "clientInfo" @@ -70,7 +65,6 @@ doc { type "Map" optional true since "3.5.0" - } column { name "systemTags" @@ -80,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -90,7 +83,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "accountType" + enclosedIn "logInByAccount" + desc "" + location "body" + type "String" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APILogInByUserMsg.java b/header/src/main/java/org/zstack/header/identity/APILogInByUserMsg.java index 504f0e3f8e4..5d608c0325f 100755 --- a/header/src/main/java/org/zstack/header/identity/APILogInByUserMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APILogInByUserMsg.java @@ -55,10 +55,6 @@ public void setUserName(String userName) { this.userName = userName; } - public String getPassword() { - return password; - } - public void setPassword(String password) { this.password = password; } @@ -95,8 +91,26 @@ public LoginResult loginAudit(APIMessage msg, APIReply reply) { if (clientInfo != null && !clientInfo.isEmpty()) { clientIp = StringUtils.isNotEmpty(clientInfo.get("clientIp")) ? clientInfo.get("clientIp") : ""; clientBrowser = StringUtils.isNotEmpty(clientInfo.get("clientBrowser")) ? clientInfo.get("clientBrowser") : ""; + } else { + clientIp = StringUtils.isNotBlank(msg.getClientIp()) ? msg.getClientIp() : ""; + clientBrowser = StringUtils.isNotBlank(msg.getClientBrowser()) ? msg.getClientBrowser() : ""; } - String resourceUuid = reply.isSuccess() ? amsg.getSession().getUuid() : ""; + String resourceUuid = reply.isSuccess() ? ((APILogInReply) reply).getInventory().getUuid() : ""; return new LoginResult(clientIp, clientBrowser, resourceUuid, SessionVO.class); } + + @Override + public String getUsername() { + return userName; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getLoginType() { + return AccountConstant.LOGIN_TYPE; + } } diff --git a/header/src/main/java/org/zstack/header/identity/APILogInByUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APILogInByUserMsgDoc_zh_cn.groovy index 524b65d25c1..a161c66f5fc 100644 --- a/header/src/main/java/org/zstack/header/identity/APILogInByUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APILogInByUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "accountName" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "userName" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "clientInfo" @@ -69,7 +65,6 @@ doc { type "Map" optional true since "3.5.0" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,13 +83,12 @@ doc { type "List" optional true since "0.6" - } } } response { - clz APILogInReply.class - } + clz APILogInReply.class + } } } \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/identity/APILogInReply.java b/header/src/main/java/org/zstack/header/identity/APILogInReply.java old mode 100755 new mode 100644 index bae996eeedd..a800fc20d5b --- a/header/src/main/java/org/zstack/header/identity/APILogInReply.java +++ b/header/src/main/java/org/zstack/header/identity/APILogInReply.java @@ -1,11 +1,16 @@ package org.zstack.header.identity; +import org.zstack.header.message.APIReply; import org.zstack.header.rest.RestResponse; import java.sql.Timestamp; +/** + * author:kaicai.hu + * Date:2019/4/24 + */ @RestResponse(allTo = "inventory") -public class APILogInReply extends APILogInAuditorReply { +public class APILogInReply extends APIReply { private SessionInventory inventory; public SessionInventory getInventory() { @@ -27,5 +32,4 @@ public static APILogInReply __example__() { reply.setInventory(inventory); return reply; } - } diff --git a/header/src/main/java/org/zstack/header/identity/APILogOutMsg.java b/header/src/main/java/org/zstack/header/identity/APILogOutMsg.java index 8a86ef8eca2..49fb79d1e02 100755 --- a/header/src/main/java/org/zstack/header/identity/APILogOutMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APILogOutMsg.java @@ -56,7 +56,25 @@ public LoginResult loginAudit(APIMessage msg, APIReply reply) { if (clientInfo != null && !clientInfo.isEmpty()) { clientIp = StringUtils.isNotEmpty(clientInfo.get("clientIp")) ? clientInfo.get("clientIp") : ""; clientBrowser = StringUtils.isNotEmpty(clientInfo.get("clientBrowser")) ? clientInfo.get("clientBrowser") : ""; + } else { + clientIp = StringUtils.isNotBlank(msg.getClientIp()) ? msg.getClientIp() : ""; + clientBrowser = StringUtils.isNotBlank(msg.getClientBrowser()) ? msg.getClientBrowser() : ""; } return new LoginResult(clientIp, clientBrowser, amsg.getSessionUuid(), SessionVO.class); } + + @Override + public String getUsername() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getLoginType() { + return null; + } } diff --git a/header/src/main/java/org/zstack/header/identity/APILogOutMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APILogOutMsgDoc_zh_cn.groovy index b469c922dd6..24511f36176 100644 --- a/header/src/main/java/org/zstack/header/identity/APILogOutMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APILogOutMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "clientInfo" @@ -39,7 +38,6 @@ doc { type "Map" optional true since "3.5.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APILogOutReply.java b/header/src/main/java/org/zstack/header/identity/APILogOutReply.java index 13e7284d6b7..b9c24ffdbda 100755 --- a/header/src/main/java/org/zstack/header/identity/APILogOutReply.java +++ b/header/src/main/java/org/zstack/header/identity/APILogOutReply.java @@ -3,7 +3,7 @@ import org.zstack.header.rest.RestResponse; @RestResponse -public class APILogOutReply extends APILogInAuditorReply { +public class APILogOutReply extends APILogInReply { public static APILogOutReply __example__() { APILogOutReply reply = new APILogOutReply(); diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQueryAccountMsgDoc_zh_cn.groovy index cbf968d7a91..9d1d4b05259 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQueryAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQueryAccountMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQueryAccountReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryAccount" diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryAccountResourceRefMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQueryAccountResourceRefMsgDoc_zh_cn.groovy index 05e5e7cb9ae..1754c4a3c60 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQueryAccountResourceRefMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQueryAccountResourceRefMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQueryAccountResourceRefReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryAccountResourceRef" diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryPolicyMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQueryPolicyMsgDoc_zh_cn.groovy index e172d616e56..852cacc0c91 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQueryPolicyMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQueryPolicyMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQueryPolicyReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryPolicy" diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryPolicyReply.java b/header/src/main/java/org/zstack/header/identity/APIQueryPolicyReply.java index 26e64ec8b9b..4732ada1fe4 100755 --- a/header/src/main/java/org/zstack/header/identity/APIQueryPolicyReply.java +++ b/header/src/main/java/org/zstack/header/identity/APIQueryPolicyReply.java @@ -30,7 +30,7 @@ public static APIQueryPolicyReply __example__() { inventory.setName("USER-RESET-PASSWORD"); PolicyStatement s = new PolicyStatement(); s.setName(String.format("user-reset-password-%s", inventory.getUuid())); - s.setEffect(StatementEffect.Allow); + s.setEffect(PolicyStatementEffect.Allow); s.addAction(String.format("%s:%s", AccountConstant.ACTION_CATEGORY, APIUpdateUserMsg.class.getSimpleName())); inventory.setStatements(list(s)); diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryQuotaMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQueryQuotaMsgDoc_zh_cn.groovy index 721e33bb3ae..947981fed62 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQueryQuotaMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQueryQuotaMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQueryQuotaReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryQuota" diff --git a/header/src/main/java/org/zstack/header/identity/APIQuerySharedResourceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQuerySharedResourceMsgDoc_zh_cn.groovy index 0653868cc75..e244d7f5a98 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQuerySharedResourceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQuerySharedResourceMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQuerySharedResourceReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QuerySharedResource" diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryUserGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQueryUserGroupMsgDoc_zh_cn.groovy index 4a9c0140502..a680a68cb99 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQueryUserGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQueryUserGroupMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQueryUserGroupReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryUserGroup" diff --git a/header/src/main/java/org/zstack/header/identity/APIQueryUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIQueryUserMsgDoc_zh_cn.groovy index cd4bbce9971..4e34d4f8d24 100644 --- a/header/src/main/java/org/zstack/header/identity/APIQueryUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIQueryUserMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity import org.zstack.header.identity.APIQueryUserReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryUser" diff --git a/header/src/main/java/org/zstack/header/identity/APIRemoveUserFromGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIRemoveUserFromGroupMsgDoc_zh_cn.groovy index c4d8a580680..6b02bf88106 100644 --- a/header/src/main/java/org/zstack/header/identity/APIRemoveUserFromGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIRemoveUserFromGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "groupUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIRenewSessionMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIRenewSessionMsgDoc_zh_cn.groovy index d6a98e7a37c..10f7fbd6c79 100644 --- a/header/src/main/java/org/zstack/header/identity/APIRenewSessionMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIRenewSessionMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "duration" @@ -39,7 +38,6 @@ doc { type "Long" optional true since "2.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.3" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIRevokeResourceSharingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIRevokeResourceSharingMsgDoc_zh_cn.groovy index c14507a0902..0883d0a2f0b 100644 --- a/header/src/main/java/org/zstack/header/identity/APIRevokeResourceSharingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIRevokeResourceSharingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "toPublic" @@ -39,7 +38,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "accountUuids" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "all" @@ -59,7 +56,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APISessionMessage.java b/header/src/main/java/org/zstack/header/identity/APISessionMessage.java index 6d27fbf52d9..9d0135f68f7 100755 --- a/header/src/main/java/org/zstack/header/identity/APISessionMessage.java +++ b/header/src/main/java/org/zstack/header/identity/APISessionMessage.java @@ -2,6 +2,8 @@ import org.zstack.header.message.APISyncCallMessage; -public class APISessionMessage extends APISyncCallMessage { - +public abstract class APISessionMessage extends APISyncCallMessage { + public abstract String getUsername(); + public abstract String getPassword(); + public abstract String getLoginType(); } diff --git a/header/src/main/java/org/zstack/header/identity/APIShareResourceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIShareResourceMsgDoc_zh_cn.groovy index 2998ca0ad60..9352e08d074 100644 --- a/header/src/main/java/org/zstack/header/identity/APIShareResourceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIShareResourceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "accountUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "toPublic" @@ -49,7 +47,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsg.java b/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsg.java index d60053a40a9..15b33ee87c0 100755 --- a/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsg.java @@ -1,6 +1,7 @@ package org.zstack.header.identity; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; @@ -13,7 +14,8 @@ path = "/accounts/{uuid}", method = HttpMethod.PUT, isAction = true, - responseClass = APIUpdateAccountEvent.class + responseClass = APIUpdateAccountEvent.class, + morphTransform = Constants.MORPH_TRANSFORM_IAM1 ) public class APIUpdateAccountMsg extends APIMessage implements AccountMessage, Serializable { @APIParam(resourceType = AccountVO.class, checkAccount = true, operationTarget = true) diff --git a/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsgDoc_zh_cn.groovy index d170c6a9469..16f4f3f6663 100644 --- a/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIUpdateAccountMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "name" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "oldPassword" + enclosedIn "updateAccount" + desc "" + location "body" + type "String" + optional true + since "3.6.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsg.java b/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsg.java index d111fa4fbca..bac63de35a3 100755 --- a/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsg.java @@ -1,6 +1,7 @@ package org.zstack.header.identity; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.APINoSee; @@ -13,7 +14,8 @@ path = "/accounts/quotas/actions", responseClass = APIUpdateQuotaEvent.class, isAction = true, - method = HttpMethod.PUT + method = HttpMethod.PUT, + morphTransform = Constants.MORPH_TRANSFORM_IAM1 ) public class APIUpdateQuotaMsg extends APIMessage implements AccountMessage { @APIParam(resourceType = AccountVO.class) diff --git a/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsgDoc_zh_cn.groovy index fa0247044f8..2523d192cb5 100644 --- a/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIUpdateQuotaMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "value" @@ -49,7 +47,6 @@ doc { type "long" optional false since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIUpdateUserGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIUpdateUserGroupMsgDoc_zh_cn.groovy index 556a53eea0c..c9ca41a31d6 100644 --- a/header/src/main/java/org/zstack/header/identity/APIUpdateUserGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIUpdateUserGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIUpdateUserMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIUpdateUserMsgDoc_zh_cn.groovy index abcf23df960..11671aa8863 100644 --- a/header/src/main/java/org/zstack/header/identity/APIUpdateUserMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIUpdateUserMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "name" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "oldPassword" + enclosedIn "updateUser" + desc "" + location "body" + type "String" + optional true + since "3.6.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsg.java b/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsg.java index dc6043702a3..08f90e870b7 100755 --- a/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsg.java +++ b/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsg.java @@ -34,4 +34,18 @@ public static APIValidateSessionMsg __example__() { return msg; } + @Override + public String getUsername() { + return null; + } + + @Override + public String getPassword() { + return null; + } + + @Override + public String getLoginType() { + return null; + } } diff --git a/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsgDoc_zh_cn.groovy index d2305309d5c..b66ca4c9223 100644 --- a/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/APIValidateSessionMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/AccountConstant.java b/header/src/main/java/org/zstack/header/identity/AccountConstant.java index abc50f54864..7e376a915e9 100755 --- a/header/src/main/java/org/zstack/header/identity/AccountConstant.java +++ b/header/src/main/java/org/zstack/header/identity/AccountConstant.java @@ -28,9 +28,26 @@ public interface AccountConstant { String PRINCIPAL_ACCOUNT = "account"; String LOGIN_TYPE = "account"; + String LOGIN_TYPE_AUTHENTICATIONS_KEY = "authentications"; + + String NO_EXIST_ACCOUNT ="no-exist-account:::%s"; IdentityType identityType = new IdentityType("IAM"); + // login property accountType + String ACCOUNT_TYPE = "accountType"; + + String PREFERRED_USERNAME = "preferred_username"; + String FULL_NAME = "fullname"; + String Phone_NAME = "phone"; + String Mail_NAME = "mail"; + String Identifier_NAME = "identifier"; + String LOGIN_TYPE_NAME = "loginType"; + String GROUPS_NAME = "groups"; + String PROJECTS_NAME = "projects"; + + + static boolean isAdminPermission(SessionInventory session) { return isAdminPermission(session.getAccountUuid()); } diff --git a/header/src/main/java/org/zstack/header/identity/AccountType.java b/header/src/main/java/org/zstack/header/identity/AccountType.java index 2182fed5040..34c7c24054d 100755 --- a/header/src/main/java/org/zstack/header/identity/AccountType.java +++ b/header/src/main/java/org/zstack/header/identity/AccountType.java @@ -6,4 +6,5 @@ public enum AccountType { SystemAdmin, Normal, + ThirdParty } diff --git a/header/src/main/java/org/zstack/header/identity/AccountVO.java b/header/src/main/java/org/zstack/header/identity/AccountVO.java index b38c14b169d..edd79bebe42 100755 --- a/header/src/main/java/org/zstack/header/identity/AccountVO.java +++ b/header/src/main/java/org/zstack/header/identity/AccountVO.java @@ -1,5 +1,6 @@ package org.zstack.header.identity; +import org.zstack.header.core.encrypt.EncryptColumn; import org.zstack.header.vo.BaseResource; import org.zstack.header.vo.Index; import org.zstack.header.vo.ResourceVO; @@ -18,6 +19,7 @@ public class AccountVO extends ResourceVO { @Column private String description; + @EncryptColumn @Column private String password; diff --git a/header/src/main/java/org/zstack/header/identity/AdditionalLoginExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/AdditionalLoginExtensionPoint.java deleted file mode 100644 index b0a60baf3bc..00000000000 --- a/header/src/main/java/org/zstack/header/identity/AdditionalLoginExtensionPoint.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.zstack.header.identity; - -import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.message.APIMessage; - -public interface AdditionalLoginExtensionPoint { - ErrorCode authenticate(APIMessage msg, String resourceUuid, String resourceType); -} diff --git a/header/src/main/java/org/zstack/header/identity/BeforeCreateAccountExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/BeforeCreateAccountExtensionPoint.java new file mode 100644 index 00000000000..5ebf0bb118b --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/BeforeCreateAccountExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.identity; + +/** + * @description: 创建账户前扩展点 + * @author: liupt@sugon.com + * @time: 2022/10/9 + */ +public interface BeforeCreateAccountExtensionPoint { + void beforeCreateAccount(AccountInventory account); +} diff --git a/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java new file mode 100644 index 00000000000..50b68eb89a4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.identity; + +/** + * @description: + * @author: liupt@sugon.com + * @time: 2022/10/9 + */ +public interface BeforeDeleteAccountExtensionPoint { + void beforeDeleteAccount(AccountInventory account); +} diff --git a/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java new file mode 100644 index 00000000000..285eb860a4f --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.identity; + +/** + * @description: + * @author: liupt@sugon.com + * @time: 2022/10/9 + */ +public interface BeforeUpdateAccountExtensionPoint { + void beforeUpdateAccount(AccountInventory account); +} diff --git a/header/src/main/java/org/zstack/header/identity/CreateAccountMsg.java b/header/src/main/java/org/zstack/header/identity/CreateAccountMsg.java new file mode 100644 index 00000000000..09384857f66 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/CreateAccountMsg.java @@ -0,0 +1,58 @@ +package org.zstack.header.identity; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author: DaoDao + * @Date: 2022/8/24 + */ +public class CreateAccountMsg extends NeedReplyMessage { + private String uuid; + private String name; + @NoLogging + private String password; + private String type; + private String description; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} + diff --git a/header/src/main/java/org/zstack/header/identity/CreateAccountReply.java b/header/src/main/java/org/zstack/header/identity/CreateAccountReply.java new file mode 100644 index 00000000000..9ab0ada434b --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/CreateAccountReply.java @@ -0,0 +1,20 @@ +package org.zstack.header.identity; + +import org.zstack.header.message.MessageReply; + +/** + * @Author: DaoDao + * @Date: 2022/8/24 + */ +public class CreateAccountReply extends MessageReply { + private AccountInventory inventory; + + public AccountInventory getInventory() { + return inventory; + } + + public void setInventory(AccountInventory inventory) { + this.inventory = inventory; + } +} + diff --git a/header/src/main/java/org/zstack/header/identity/GetCurrentUsernameMsg.java b/header/src/main/java/org/zstack/header/identity/GetCurrentUsernameMsg.java new file mode 100644 index 00000000000..5b94f163ef9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/GetCurrentUsernameMsg.java @@ -0,0 +1,15 @@ +package org.zstack.header.identity; + +import org.zstack.header.message.NeedReplyMessage; + +public class GetCurrentUsernameMsg extends NeedReplyMessage { + private String sessionUuid; + + public String getSessionUuid() { + return sessionUuid; + } + + public void setSessionUuid(String sessionUuid) { + this.sessionUuid = sessionUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/GetCurrentUsernameReply.java b/header/src/main/java/org/zstack/header/identity/GetCurrentUsernameReply.java new file mode 100644 index 00000000000..404a3d65161 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/GetCurrentUsernameReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.identity; + +import org.zstack.header.message.MessageReply; + +public class GetCurrentUsernameReply extends MessageReply { + private String username; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/PackageInfo.java b/header/src/main/java/org/zstack/header/identity/PackageInfo.java index 515746608f2..ce96ffa0a23 100755 --- a/header/src/main/java/org/zstack/header/identity/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/identity/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "账号") +@PackageAPIInfo( + APICategoryName = "账号", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/identity/PolicyInventory_StatementDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/PolicyInventory_StatementDoc_zh_cn.groovy index 3c19a6c7aed..a86a4c77c8c 100755 --- a/header/src/main/java/org/zstack/header/identity/PolicyInventory_StatementDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/PolicyInventory_StatementDoc_zh_cn.groovy @@ -14,9 +14,9 @@ doc { name "effect" path "org.zstack.header.identity.PolicyInventory.Statement.effect" desc "声明的效果(许可,禁止)" - type "StatementEffect" + type "PolicyStatementEffect" since "0.6" - clz StatementEffect.class + clz PolicyStatementEffect.class } field { name "principals" diff --git a/header/src/main/java/org/zstack/header/identity/PolicyStatement.java b/header/src/main/java/org/zstack/header/identity/PolicyStatement.java index 01415cdacb8..d4a6f0c5de5 100755 --- a/header/src/main/java/org/zstack/header/identity/PolicyStatement.java +++ b/header/src/main/java/org/zstack/header/identity/PolicyStatement.java @@ -10,7 +10,7 @@ @SDK(sdkClassName = "PolicyStatement") public class PolicyStatement { private String name; - private StatementEffect effect; + private PolicyStatementEffect effect; private List principals; private List actions; private List resources; @@ -31,11 +31,11 @@ public void setName(String name) { this.name = name; } - public StatementEffect getEffect() { + public PolicyStatementEffect getEffect() { return effect; } - public void setEffect(StatementEffect effect) { + public void setEffect(PolicyStatementEffect effect) { this.effect = effect; } @@ -77,7 +77,7 @@ public static PolicyStatementBuilder builder() { public static final class PolicyStatementBuilder { private String name; - private StatementEffect effect; + private PolicyStatementEffect effect; private List principals; private List actions; private List resources; @@ -90,7 +90,7 @@ public PolicyStatementBuilder name(String name) { return this; } - public PolicyStatementBuilder effect(StatementEffect effect) { + public PolicyStatementBuilder effect(PolicyStatementEffect effect) { this.effect = effect; return this; } diff --git a/header/src/main/java/org/zstack/header/identity/PolicyStatementDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/PolicyStatementDoc_zh_cn.groovy index 2228b37593d..266954dde18 100644 --- a/header/src/main/java/org/zstack/header/identity/PolicyStatementDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/PolicyStatementDoc_zh_cn.groovy @@ -1,7 +1,5 @@ package org.zstack.header.identity -import org.zstack.header.identity.StatementEffect - doc { title "在这里输入结构的名称" @@ -16,9 +14,9 @@ doc { name "effect" path "org.zstack.header.identity.PolicyStatement.effect" desc "null" - type "StatementEffect" + type "PolicyStatementEffect" since "0.6" - clz StatementEffect.class + clz PolicyStatementEffect.class } field { name "principals" diff --git a/header/src/main/java/org/zstack/header/identity/PolicyStatementEffect.java b/header/src/main/java/org/zstack/header/identity/PolicyStatementEffect.java new file mode 100644 index 00000000000..6c616c1e1d5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/PolicyStatementEffect.java @@ -0,0 +1,9 @@ +package org.zstack.header.identity; + +import org.zstack.header.rest.SDK; + +@SDK(sdkClassName = "PolicyStatementEffect") +public enum PolicyStatementEffect { + Allow, + Deny, +} diff --git a/header/src/main/java/org/zstack/header/identity/Quota.java b/header/src/main/java/org/zstack/header/identity/Quota.java index 58c3d3529d8..fa00f1b2723 100755 --- a/header/src/main/java/org/zstack/header/identity/Quota.java +++ b/header/src/main/java/org/zstack/header/identity/Quota.java @@ -1,5 +1,7 @@ package org.zstack.header.identity; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.NeedQuotaCheckMessage; @@ -11,6 +13,8 @@ */ public class Quota { public final static long DEFAULT_NO_LIMITATION = -1; + + @Deprecated public interface QuotaOperator { void checkQuota(APIMessage msg, Map pairs); @@ -19,6 +23,7 @@ public interface QuotaOperator { List getQuotaUsageByAccount(String accountUuid); } + @Deprecated public interface QuotaValidator { void checkQuota(APIMessage msg, Map pairs); @@ -57,6 +62,12 @@ public void setUsed(Long used) { } } + /** + * quota pair describes quota name with its value + * + * for every account, a list of quota pair will be stored + * and used during account's quota check + */ public static class QuotaPair { private String name; private long value; @@ -78,12 +89,38 @@ public void setValue(long value) { } } - private Set quotaSet; + /** + * Deprecated but keep it for compatible + * + * use QuotaDefinition instead + */ private List quotaPairs; + + /** + * Deprecated but keep it for compatible + * + * use addQuotaMessageChecker instead + */ private List> messagesNeedValidation = new ArrayList<>(); + + /** + * Deprecated but keep it for compatible + * + * use QuotaDefinition instead + */ private QuotaOperator operator; + + /** + * Deprecated but keep it for compatible + * + * use addQuotaMessageChecker instead + */ private Set quotaValidators; + private List quotaDefinitions; + private List> quotaMessageHandlerList = new ArrayList<>(); + + @Deprecated public void addPair(QuotaPair p) { if (quotaPairs == null) { quotaPairs = new ArrayList<>(); @@ -91,14 +128,32 @@ public void addPair(QuotaPair p) { quotaPairs.add(p); } + public void defineQuota(QuotaDefinition d) { + if (quotaDefinitions == null) { + quotaDefinitions = new ArrayList<>(); + } + quotaDefinitions.add(d); + } + + @Deprecated public List getQuotaPairs() { return quotaPairs; } + public List getQuotaDefinitions() { + return quotaDefinitions; + } + + public void setQuotaDefinitions(List quotaDefinitions) { + this.quotaDefinitions = quotaDefinitions; + } + + @Deprecated public void setQuotaPairs(List quotaPairs) { this.quotaPairs = quotaPairs; } + @Deprecated public void addMessageNeedValidation(Class msgClass) { messagesNeedValidation.add(msgClass); } @@ -107,10 +162,24 @@ public List> getMessagesNeedValidation() { return messagesNeedValidation; } + public List> getQuotaMessageCheckerList() { + return quotaMessageHandlerList; + } + + public void addQuotaMessageChecker(QuotaMessageHandler messageChecker) { + this.quotaMessageHandlerList.add(messageChecker); + } + + public void setQuotaMessageCheckerList(List> quotaMessageHandlerList) { + this.quotaMessageHandlerList = quotaMessageHandlerList; + } + + @Deprecated public QuotaOperator getOperator() { return operator; } + @Deprecated public void setOperator(QuotaOperator operator) { this.operator = operator; } @@ -127,18 +196,4 @@ public void addQuotaValidators(Set quotaValidators) { this.quotaValidators.add(q); } } - - public void addToQuotaSet(String quotaName) { - if (this.quotaSet == null) { - this.quotaSet = new HashSet<>(); - } - this.quotaSet.add(quotaName); - } - - public Set getQuotaSet() { - if (this.quotaSet == null) { - this.quotaSet = new HashSet<>(); - } - return this.quotaSet; - } } diff --git a/header/src/main/java/org/zstack/header/identity/RenewSessionPreAuthExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/RenewSessionPreAuthExtensionPoint.java new file mode 100644 index 00000000000..578f776f200 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/RenewSessionPreAuthExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.header.identity; + +import org.zstack.header.errorcode.ErrorCode; + +/** + * @Author: DaoDao + * @Date: 2023/2/10 + */ +public interface RenewSessionPreAuthExtensionPoint { + ErrorCode checkAuth(SessionInventory session); +} diff --git a/header/src/main/java/org/zstack/header/identity/SessionInventory.java b/header/src/main/java/org/zstack/header/identity/SessionInventory.java index 1dcd66c87d3..f79549f7788 100644 --- a/header/src/main/java/org/zstack/header/identity/SessionInventory.java +++ b/header/src/main/java/org/zstack/header/identity/SessionInventory.java @@ -13,6 +13,7 @@ public class SessionInventory implements Serializable { private String uuid; private String accountUuid; private String userUuid; + private String userType; private Timestamp expiredDate; private Timestamp createDate; @APINoSee @@ -83,4 +84,12 @@ public boolean isNoSessionEvaluation() { public void setNoSessionEvaluation(boolean noSessionEvaluation) { this.noSessionEvaluation = noSessionEvaluation; } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } } diff --git a/header/src/main/java/org/zstack/header/identity/StatementEffect.java b/header/src/main/java/org/zstack/header/identity/StatementEffect.java deleted file mode 100755 index 2706cffeb19..00000000000 --- a/header/src/main/java/org/zstack/header/identity/StatementEffect.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.zstack.header.identity; - -import org.zstack.header.rest.SDK; - -@SDK(sdkClassName = "PolicyStatementEffect") -public enum StatementEffect { - Allow, - Deny, -} diff --git a/header/src/main/java/org/zstack/header/identity/login/APICaptchaMessage.java b/header/src/main/java/org/zstack/header/identity/login/APICaptchaMessage.java new file mode 100644 index 00000000000..4f3cbe09470 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APICaptchaMessage.java @@ -0,0 +1,7 @@ +package org.zstack.header.identity.login; + +public interface APICaptchaMessage { + String getCaptchaUuid(); + + String getVerifyCode(); +} diff --git a/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresMsg.java b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresMsg.java new file mode 100644 index 00000000000..29998d5b7a6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresMsg.java @@ -0,0 +1,39 @@ +package org.zstack.header.identity.login; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.SuppressCredentialCheck; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/login/procedures", + method = HttpMethod.GET, + responseClass = APIGetLoginProceduresReply.class +) +@SuppressCredentialCheck +public class APIGetLoginProceduresMsg extends APISyncCallMessage { + @APIParam + private String username; + /** + * get procedures of specific login type + */ + @APIParam + private String loginType; + + public String getLoginType() { + return loginType; + } + + public void setLoginType(String loginType) { + this.loginType = loginType; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..bbcc093931c --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.identity.login + +import org.zstack.header.identity.login.APIGetLoginProceduresReply + +doc { + title "GetLoginProcedures" + + category "login" + + desc """获取登录的认证步骤""" + + rest { + request { + url "GET /v1/login/procedures" + + + + clz APIGetLoginProceduresMsg.class + + desc """""" + + params { + + column { + name "username" + enclosedIn "" + desc "用户名" + location "query" + type "String" + optional false + since "4.6.0" + } + column { + name "loginType" + enclosedIn "" + desc "认证用户类型" + location "query" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIGetLoginProceduresReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresReply.java b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresReply.java new file mode 100644 index 00000000000..a550c03d43a --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "procedures") +public class APIGetLoginProceduresReply extends APIReply { + List procedures; + + public List getProcedures() { + return procedures; + } + + public void setProcedures(List procedures) { + this.procedures = procedures; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..91ce7803c8b --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APIGetLoginProceduresReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.identity.login + +import org.zstack.header.identity.login.LoginAuthenticationProcedureDesc +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "登录的认证步骤的返回" + + ref { + name "procedures" + path "org.zstack.header.identity.login.APIGetLoginProceduresReply.procedures" + desc "null" + type "List" + since "4.6.0" + clz LoginAuthenticationProcedureDesc.class + } + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.header.identity.login.APIGetLoginProceduresReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/APILogInMsg.java b/header/src/main/java/org/zstack/header/identity/login/APILogInMsg.java new file mode 100644 index 00000000000..9a23ad4f10b --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APILogInMsg.java @@ -0,0 +1,128 @@ +package org.zstack.header.identity.login; + +import org.apache.commons.lang.StringUtils; +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.*; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APIReply; +import org.zstack.header.other.APILoginAuditor; +import org.zstack.header.rest.RestRequest; + +import java.util.HashMap; +import java.util.Map; + +@SuppressCredentialCheck +@RestRequest( + path = "/login", + isAction = true, + method = HttpMethod.PUT, + responseClass = APILogInReply.class +) +public class APILogInMsg extends APISessionMessage implements APILoginAuditor { + @APIParam + private String username; + @APIParam + @NoLogging + private String password; + @APIParam + private String loginType; + @APIParam(required = false) + private String captchaUuid; + @APIParam(required = false) + private String verifyCode; + @APIParam(required = false) + private Map clientInfo; + @APIParam(required = false) + private Map properties; + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setLoginType(String loginType) { + this.loginType = loginType; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getLoginType() { + return loginType; + } + + public String getCaptchaUuid() { + return captchaUuid; + } + + public void setCaptchaUuid(String captchaUuid) { + this.captchaUuid = captchaUuid; + } + + public String getVerifyCode() { + return verifyCode; + } + + public void setVerifyCode(String verifyCode) { + this.verifyCode = verifyCode; + } + + public Map getClientInfo() { + return clientInfo; + } + + public void setClientInfo(Map clientInfo) { + this.clientInfo = clientInfo; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + @Override + public LoginResult loginAudit(APIMessage msg, APIReply reply) { + String clientIp = ""; + String clientBrowser = ""; + APILogInMsg amsg = (APILogInMsg) msg; + Map clientInfo = amsg.getClientInfo(); + if (clientInfo != null && !clientInfo.isEmpty()) { + clientIp = StringUtils.isNotEmpty(clientInfo.get("clientIp")) ? clientInfo.get("clientIp") : ""; + clientBrowser = StringUtils.isNotEmpty(clientInfo.get("clientBrowser")) ? clientInfo.get("clientBrowser") : ""; + } else { + clientIp = StringUtils.isNotBlank(msg.getClientIp()) ? msg.getClientIp() : ""; + clientBrowser = StringUtils.isNotBlank(msg.getClientBrowser()) ? msg.getClientBrowser() : ""; + } + String resourceUuid = reply.isSuccess() ? ((APILogInReply) reply).getInventory().getUuid() : ""; + return new LoginResult(clientIp, clientBrowser, resourceUuid, SessionVO.class); + } + + @Override + public String getOperator() { + return username; + } + + public static APILogInMsg __example__() { + APILogInMsg msg = new APILogInMsg(); + msg.setUsername("admin"); + msg.setPassword("password"); + msg.setLoginType("account"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/APILogInMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/login/APILogInMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..1fc25d48af8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/APILogInMsgDoc_zh_cn.groovy @@ -0,0 +1,112 @@ +package org.zstack.header.identity.login + +import org.zstack.header.identity.APILogInReply + +doc { + title "LogIn" + + category "login" + + desc """登录""" + + rest { + request { + url "PUT /v1/login" + + + + clz APILogInMsg.class + + desc """""" + + params { + + column { + name "username" + enclosedIn "logIn" + desc "用户名" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "password" + enclosedIn "logIn" + desc "用户密码" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "loginType" + enclosedIn "logIn" + desc "用户类型" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "captchaUuid" + enclosedIn "logIn" + desc "验证码uuid" + location "body" + type "String" + optional true + since "4.6.0" + } + column { + name "verifyCode" + enclosedIn "logIn" + desc "验证码" + location "body" + type "String" + optional true + since "4.6.0" + } + column { + name "clientInfo" + enclosedIn "logIn" + desc "客户端信息" + location "body" + type "Map" + optional true + since "4.6.0" + } + column { + name "properties" + enclosedIn "logIn" + desc "登录属性" + location "body" + type "Map" + optional true + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APILogInReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/identity/login/AdditionalAuthFeature.java b/header/src/main/java/org/zstack/header/identity/login/AdditionalAuthFeature.java new file mode 100644 index 00000000000..116248a5e2d --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/AdditionalAuthFeature.java @@ -0,0 +1,53 @@ +package org.zstack.header.identity.login; + +import java.util.*; + +public class AdditionalAuthFeature { + private static final Map types = Collections.synchronizedMap(new HashMap()); + private final String typeName; + + public AdditionalAuthFeature(String typeName) { + this.typeName = typeName; + types.put(typeName, this); + } + + public static boolean hasType(String type) { + return types.containsKey(type); + } + + public static AdditionalAuthFeature valueOf(String typeName) { + AdditionalAuthFeature type = types.get(typeName); + if (type == null) { + throw new IllegalArgumentException(String.format("AdditionalAuthFeature type: %s not supported", typeName)); + } + return type; + } + + @Override + public String toString() { + return typeName; + } + + @Override + public boolean equals(Object t) { + if (!(t instanceof AdditionalAuthFeature)) { + return false; + } + + AdditionalAuthFeature type = (AdditionalAuthFeature) t; + return type.toString().equals(typeName); + } + + @Override + public int hashCode() { + return typeName.hashCode(); + } + + public static Set getAllTypeNames() { + HashSet exposedTypes = new HashSet<>(); + for (AdditionalAuthFeature type : types.values()) { + exposedTypes.add(type.toString()); + } + return exposedTypes; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LogInMsg.java b/header/src/main/java/org/zstack/header/identity/login/LogInMsg.java new file mode 100644 index 00000000000..ee2cb95e7b6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LogInMsg.java @@ -0,0 +1,104 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.identity.SessionInventory; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.NeedReplyMessage; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class LogInMsg extends NeedReplyMessage { + private String username; + @NoLogging + private String password; + private String loginType; + private SessionInventory session; + private String captchaUuid; + private String verifyCode; + private Map clientInfo; + private boolean validateOnly = false; + private List ignoreAdditionalFeatures; + private Map properties = new HashMap<>(); + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getLoginType() { + return loginType; + } + + public void setLoginType(String loginType) { + this.loginType = loginType; + } + + public SessionInventory getSession() { + return session; + } + + public void setSession(SessionInventory session) { + this.session = session; + } + + public String getCaptchaUuid() { + return captchaUuid; + } + + public void setCaptchaUuid(String captchaUuid) { + this.captchaUuid = captchaUuid; + } + + public String getVerifyCode() { + return verifyCode; + } + + public void setVerifyCode(String verifyCode) { + this.verifyCode = verifyCode; + } + + public Map getClientInfo() { + return clientInfo; + } + + public void setClientInfo(Map clientInfo) { + this.clientInfo = clientInfo; + } + + public boolean isValidateOnly() { + return validateOnly; + } + + public void setValidateOnly(boolean validateOnly) { + this.validateOnly = validateOnly; + } + + public List getIgnoreAdditionalFeatures() { + return ignoreAdditionalFeatures; + } + + public void setIgnoreAdditionalFeatures(List ignoreAdditionalFeatures) { + this.ignoreAdditionalFeatures = ignoreAdditionalFeatures; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LogInReply.java b/header/src/main/java/org/zstack/header/identity/login/LogInReply.java new file mode 100644 index 00000000000..6c079288e53 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LogInReply.java @@ -0,0 +1,16 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.identity.SessionInventory; +import org.zstack.header.message.MessageReply; + +public class LogInReply extends MessageReply { + private SessionInventory session; + + public SessionInventory getSession() { + return session; + } + + public void setSession(SessionInventory session) { + this.session = session; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginAPIAdapter.java b/header/src/main/java/org/zstack/header/identity/login/LoginAPIAdapter.java new file mode 100644 index 00000000000..d4899fd7f7c --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginAPIAdapter.java @@ -0,0 +1,9 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.message.APIMessage; + +public interface LoginAPIAdapter { + Class getMessageClass(); + + APILogInMsg transferToAPILogInMsg(APIMessage msg); +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginAuthConstant.java b/header/src/main/java/org/zstack/header/identity/login/LoginAuthConstant.java new file mode 100644 index 00000000000..94526e17c45 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginAuthConstant.java @@ -0,0 +1,16 @@ +package org.zstack.header.identity.login; + +public interface LoginAuthConstant { + String basicLoginControlAuth = "BASIC_LOGIN_CONTROL_AUTH"; + AdditionalAuthFeature basicLoginControl = new AdditionalAuthFeature(basicLoginControlAuth); + + String twoFactorAuth = "TWO_FACTOR_AUTH"; + AdditionalAuthFeature twoFactor = new AdditionalAuthFeature(twoFactorAuth); + + String ssoServerLoginControlAuth = "SSO_SERVER_LOGIN_CONTROL_AUTH"; + AdditionalAuthFeature ssoServerLoginControl = new AdditionalAuthFeature(ssoServerLoginControlAuth); + + String LOGIN_SESSION_INVENTORY = "LOGIN_SESSION_INVENTORY"; + String LOGIN_SESSION_INFO = "LOGIN_SESSION_INFO"; + String LOGIN_SESSION_UUID = "LOGIN_SESSION_UUID"; +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginAuthExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/login/LoginAuthExtensionPoint.java new file mode 100644 index 00000000000..4fffa038509 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginAuthExtensionPoint.java @@ -0,0 +1,24 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.errorcode.ErrorCode; + +/** + * Additional authentication extension point interface. + * + * This extension is used for additional authentications which do not + * need known user information or do user verification but only offer + * extra verification like captcha or verification code. + */ +public interface LoginAuthExtensionPoint { + ErrorCode beforeExecuteLogin(LoginContext loginContext); + + ErrorCode postLogin(LoginContext loginContext, LoginSessionInfo info); + + void afterLoginSuccess(LoginContext loginContext, LoginSessionInfo info); + + void afterLoginFailure(LoginContext loginContext, LoginSessionInfo info, ErrorCode errorCode); + + AdditionalAuthFeature getAdditionalAuthFeature(); + + LoginAuthenticationProcedureDesc getAdditionalAuthDesc(LoginContext loginContext); +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginAuthenticationProcedureDesc.java b/header/src/main/java/org/zstack/header/identity/login/LoginAuthenticationProcedureDesc.java new file mode 100644 index 00000000000..e75624a180f --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginAuthenticationProcedureDesc.java @@ -0,0 +1,38 @@ +package org.zstack.header.identity.login; + +import java.util.HashMap; +import java.util.Map; + +public class LoginAuthenticationProcedureDesc { + private int order = 0; + private String name; + private Map properties = new HashMap<>(); + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public void addProperty(String key, String value) { + this.properties.put(key, value); + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginAuthenticationProcedureDescDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/login/LoginAuthenticationProcedureDescDoc_zh_cn.groovy new file mode 100644 index 00000000000..996d68e3a4d --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginAuthenticationProcedureDescDoc_zh_cn.groovy @@ -0,0 +1,27 @@ +package org.zstack.header.identity.login + + + +doc { + + title "在这里输入结构的名称" + + field { + name "order" + desc "" + type "int" + since "0.6" + } + field { + name "name" + desc "资源名称" + type "String" + since "0.6" + } + field { + name "properties" + desc "" + type "Map" + since "0.6" + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginBackend.java b/header/src/main/java/org/zstack/header/identity/login/LoginBackend.java new file mode 100644 index 00000000000..b6b5a97de16 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginBackend.java @@ -0,0 +1,31 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.identity.LoginType; + +import java.util.*; + +/** + * Login implementation interface. + * + * Used for support a new kind of login, including authentication, user information and + * support involve several additional authentication features, like captcha, + * authentication code and so on. + */ +public interface LoginBackend { + LoginType getLoginType(); + + void login(LoginContext loginContext, ReturnValueCompletion completion); + + boolean authenticate(String username, String password); + + String getUserIdByName(String username); + + void collectUserInfoIntoContext(LoginContext loginContext); + + List getRequiredAdditionalAuthFeature(); + + default Set possibleUserUuidSetForGettingProcedures(LoginContext loginContext) { + return Collections.emptySet(); + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginContext.java b/header/src/main/java/org/zstack/header/identity/login/LoginContext.java new file mode 100644 index 00000000000..faa1cbdc30b --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginContext.java @@ -0,0 +1,256 @@ +package org.zstack.header.identity.login; + +import org.zstack.header.identity.APISessionMessage; +import org.zstack.header.identity.AccountConstant; +import org.zstack.header.identity.SessionInventory; + +import java.sql.Timestamp; +import java.util.*; +import java.util.function.Function; + +/** + * + */ +public class LoginContext { + /** + * + */ + private String username; + /** + * + */ + private String password; + /** + * + */ + private String loginBackendType; + /** + * + */ + private List systemTags; + /** + * + */ + private SessionInventory operatorSession; + /** + * + */ + private String loginPluginName; + + + private Map properties = new HashMap<>(); + private List ignoreFeatures = new ArrayList<>(); + + /** + * Only for {@link APIGetLoginProceduresMsg} + * + * This method is used to get possible users when not logged in, + * in order to set login rules for specific users. + * + * The input to this function is this, output is user uuid set. + */ + private Function> possibleUsersGetter; + + private String captchaUuid; + private String verifyCode; + + private boolean validateOnly; + + private String userUuid; + private String userType; + private Timestamp lastUpdatedTime; + + public String getUserUuid() { + return userUuid; + } + + public void setUserUuid(String userUuid) { + this.userUuid = userUuid; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + public Timestamp getLastUpdatedTime() { + return lastUpdatedTime; + } + + public void setLastUpdatedTime(Timestamp lastUpdatedTime) { + this.lastUpdatedTime = lastUpdatedTime; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getLoginBackendType() { + return loginBackendType; + } + + public void setLoginBackendType(String loginBackendType) { + this.loginBackendType = loginBackendType; + } + + public List getSystemTags() { + return systemTags; + } + + public void setSystemTags(List systemTags) { + this.systemTags = systemTags; + } + + public SessionInventory getOperatorSession() { + return operatorSession; + } + + public void setOperatorSession(SessionInventory operatorSession) { + this.operatorSession = operatorSession; + } + + public String getCaptchaUuid() { + return captchaUuid; + } + + public void setCaptchaUuid(String captchaUuid) { + this.captchaUuid = captchaUuid; + } + + public String getVerifyCode() { + return verifyCode; + } + + public void setVerifyCode(String verifyCode) { + this.verifyCode = verifyCode; + } + + public boolean isValidateOnly() { + return validateOnly; + } + + public void setValidateOnly(boolean validateOnly) { + this.validateOnly = validateOnly; + } + + public List getIgnoreFeatures() { + return ignoreFeatures; + } + + public void setIgnoreFeatures(List ignoreFeatures) { + this.ignoreFeatures = ignoreFeatures; + } + + public void setPossibleUsersGetter(Function> possibleUsersGetter) { + this.possibleUsersGetter = possibleUsersGetter; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public String getLoginPluginName() { + return loginPluginName; + } + + public void setLoginPluginName(String loginPluginName) { + this.loginPluginName = loginPluginName; + } + + public Set findPossibleUserUuidSet() { + if (this.userUuid != null) { + return Collections.singleton(userUuid); + } + if (this.possibleUsersGetter == null) { + return Collections.emptySet(); + } + return this.possibleUsersGetter.apply(this); + } + + public boolean isUserExisting() { + if (this.userUuid.equals(String.format(AccountConstant.NO_EXIST_ACCOUNT, this.username))) { + return false; + } + return true; + } + + public static LoginContext fromApiLoginMessage(APISessionMessage msg) { + LoginContext params = new LoginContext(); + params.setUsername(msg.getUsername()); + params.setPassword(msg.getPassword()); + params.setLoginBackendType(msg.getLoginType()); + params.setOperatorSession(msg.getSession()); + params.setSystemTags(msg.getSystemTags()); + + if (msg instanceof APICaptchaMessage) { + params.setCaptchaUuid(((APICaptchaMessage) msg).getCaptchaUuid()); + params.setVerifyCode(((APICaptchaMessage) msg).getVerifyCode()); + } + + if (msg instanceof APILogInMsg && (((APILogInMsg) msg).getProperties() != null)) { + params.getProperties().putAll(((APILogInMsg) msg).getProperties()); + } + + if (params.getSystemTags() == null) { + params.setSystemTags(Collections.emptyList()); + } + + return params; + } + + public static LoginContext fromAPIGetLoginProceduresMsg(APIGetLoginProceduresMsg msg) { + LoginContext params = new LoginContext(); + params.setUsername(msg.getUsername()); + params.setLoginBackendType(msg.getLoginType()); + params.setSystemTags(msg.getSystemTags()); + + if (params.getSystemTags() == null) { + params.setSystemTags(Collections.emptyList()); + } + + return params; + } + + public static LoginContext fromLoginMessage(LogInMsg msg) { + LoginContext params = new LoginContext(); + params.setUsername(msg.getUsername()); + params.setPassword(msg.getPassword()); + params.setLoginBackendType(msg.getLoginType()); + params.setOperatorSession(msg.getSession()); + params.setSystemTags(msg.getSystemTags()); + params.setCaptchaUuid(msg.getCaptchaUuid()); + params.setVerifyCode(msg.getVerifyCode()); + params.setValidateOnly(msg.isValidateOnly()); + + if (msg.getIgnoreAdditionalFeatures() != null) { + params.getIgnoreFeatures().addAll(msg.getIgnoreAdditionalFeatures()); + } + + params.getProperties().putAll(msg.getProperties()); + + if (params.getSystemTags() == null) { + params.setSystemTags(Collections.emptyList()); + } + + return params; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginManager.java b/header/src/main/java/org/zstack/header/identity/login/LoginManager.java new file mode 100644 index 00000000000..e26e8ff3ba3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginManager.java @@ -0,0 +1,9 @@ +package org.zstack.header.identity.login; + +public interface LoginManager { + String SERVICE_ID = "login"; + + LoginBackend getLoginBackend(String loginType); + + String getUserIdByName(String username, String loginType); +} diff --git a/header/src/main/java/org/zstack/header/identity/login/LoginSessionInfo.java b/header/src/main/java/org/zstack/header/identity/login/LoginSessionInfo.java new file mode 100644 index 00000000000..f9ff34c56b0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/login/LoginSessionInfo.java @@ -0,0 +1,41 @@ +package org.zstack.header.identity.login; + + +public class LoginSessionInfo { + private String accountUuid; + private String userUuid; + private String userType; + private boolean logoutOperatorSession; + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getUserUuid() { + return userUuid; + } + + public void setUserUuid(String userUuid) { + this.userUuid = userUuid; + } + + public boolean isLogoutOperatorSession() { + return logoutOperatorSession; + } + + public void setLogoutOperatorSession(boolean logoutOperatorSession) { + this.logoutOperatorSession = logoutOperatorSession; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/quota/FixedSizeRequiredRequest.java b/header/src/main/java/org/zstack/header/identity/quota/FixedSizeRequiredRequest.java new file mode 100644 index 00000000000..d18c5b5c2e2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/quota/FixedSizeRequiredRequest.java @@ -0,0 +1,28 @@ +package org.zstack.header.identity.quota; + +public class FixedSizeRequiredRequest implements QuotaRequiredRequest { + public FixedSizeRequiredRequest(String quotaName, Long value) { + this.quotaName = quotaName; + this.value = value; + } + + private String quotaName; + private Long value; + + @Override + public String getQuotaName() { + return quotaName; + } + + public void setQuotaName(String quotaName) { + this.quotaName = quotaName; + } + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/quota/FunctionalSizeRequiredRequest.java b/header/src/main/java/org/zstack/header/identity/quota/FunctionalSizeRequiredRequest.java new file mode 100644 index 00000000000..c738810e451 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/quota/FunctionalSizeRequiredRequest.java @@ -0,0 +1,25 @@ +package org.zstack.header.identity.quota; + +import org.zstack.utils.function.Function; + +public class FunctionalSizeRequiredRequest implements QuotaRequiredRequest { + private String quotaName; + private Function function; + + @Override + public String getQuotaName() { + return quotaName; + } + + public void setQuotaName(String quotaName) { + this.quotaName = quotaName; + } + + public Function getFunction() { + return function; + } + + public void setFunction(Function function) { + this.function = function; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/quota/QuotaDefBuilder.java b/header/src/main/java/org/zstack/header/identity/quota/QuotaDefBuilder.java new file mode 100644 index 00000000000..96cf2ba6852 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/quota/QuotaDefBuilder.java @@ -0,0 +1,99 @@ +package org.zstack.header.identity.quota; + +import org.zstack.utils.DebugUtils; + +public class QuotaDefBuilder { + private String name; + private Long defaultValue; + private Long repairValue; + private GetQuotaUsage getUsage; + + public static QuotaDefBuilder newBuilder() { + return new QuotaDefBuilder(); + } + + public QuotaDefBuilder name(String name) { + this.name = name; + return this; + } + + public QuotaDefBuilder defaultValue(Long defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + public QuotaDefBuilder repairValue(Long repairValue) { + this.repairValue = repairValue; + return this; + } + + public QuotaDefBuilder getUsage(GetQuotaUsage usage) { + this.getUsage = usage; + return this; + } + + public interface GetQuotaUsage { + Long apply(String accountUuid, String name); + } + + static class QuotaDefinitionImpl implements QuotaDefinition { + private String name; + private Long defaultValue; + private GetQuotaUsage getUsage; + private Long repairValue; + + @Override + public String getName() { + return this.name; + } + + @Override + public Long getDefaultValue() { + return this.defaultValue; + } + + @Override + public Long getQuotaUsage(String accountUuid) { + return getUsage.apply(accountUuid, name); + } + + public void setName(String name) { + this.name = name; + } + + public void setDefaultValue(Long defaultValue) { + this.defaultValue = defaultValue; + } + + public GetQuotaUsage getGetUsage() { + return getUsage; + } + + public void setGetUsage(GetQuotaUsage getUsage) { + this.getUsage = getUsage; + } + + @Override + public Long getRepairValue() { + return repairValue; + } + + public void setRepairValue(Long repairValue) { + this.repairValue = repairValue; + } + } + + public QuotaDefinition build() { + DebugUtils.Assert(this.name != null, "quota name is required"); + DebugUtils.Assert(this.defaultValue != null, "quota defaultValue is required"); + DebugUtils.Assert(this.getUsage != null, "quota getUsage is required"); + DebugUtils.Assert(this.repairValue != null, "quota repairValue is required"); + + QuotaDefinitionImpl quota = new QuotaDefinitionImpl(); + quota.name = this.name; + quota.defaultValue = this.defaultValue; + quota.getUsage = this.getUsage; + quota.repairValue = this.repairValue; + return quota; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/quota/QuotaDefinition.java b/header/src/main/java/org/zstack/header/identity/quota/QuotaDefinition.java new file mode 100644 index 00000000000..2cdefa2a24b --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/quota/QuotaDefinition.java @@ -0,0 +1,30 @@ +package org.zstack.header.identity.quota; + +/** + * quota interface + * + * define quota's name default value + * and how to get account's quota usage + */ +public interface QuotaDefinition { + String getName(); + + Long getDefaultValue(); + + /** + * get quota's usage by account + * @param accountUuid target account need get usage + * @return used value if return null means unavailable or + * no usage supported + */ + Long getQuotaUsage(String accountUuid); + + /** + * Gets the repair value for the quota. + * + * @return the repair value as a Long. If the value is null, it indicates that the repair value is unavailable or not supported. + */ + default Long getRepairValue() { + return null; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/quota/QuotaMessageHandler.java b/header/src/main/java/org/zstack/header/identity/quota/QuotaMessageHandler.java new file mode 100644 index 00000000000..ce70957f5b4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/quota/QuotaMessageHandler.java @@ -0,0 +1,97 @@ +package org.zstack.header.identity.quota; + +import org.zstack.header.message.Message; +import org.zstack.utils.function.Function; + +import java.util.ArrayList; +import java.util.List; + +/** + * QuotaMessageHandler used for messages that need quota check + * to define how to get message required values + * @param + */ +public class QuotaMessageHandler { + public Class messageClass; + + private List fixedSizeRequiredRequests = new ArrayList<>(); + private List> functionalSizeRequiredRequests = new ArrayList<>(); + private List> conditions = new ArrayList<>(); + + public QuotaMessageHandler(Class clazz) { + this.messageClass = clazz; + } + + /** + * when message invoked, count 1 to the quota + * @param quotaName required quota name + * @return this + */ + public QuotaMessageHandler addCounterQuota(String quotaName) { + fixedSizeRequiredRequests.add(new FixedSizeRequiredRequest(quotaName, 1L)); + return this; + } + + /** + * when message invoked, return a fixed required value + * @param quotaName required quota name + * @param value required value + * @return this + */ + public QuotaMessageHandler addFixedRequiredSize(String quotaName, Long value) { + FixedSizeRequiredRequest request = new FixedSizeRequiredRequest(quotaName, value); + fixedSizeRequiredRequests.add(request); + return this; + } + + /** + * when message invoked, apply function to get required value from message + * @param quotaName required quota name + * @param function function with message as input and Long as return to get + * required size + * @return this + */ + public QuotaMessageHandler addMessageRequiredQuotaHandler(String quotaName, Function function) { + FunctionalSizeRequiredRequest request = new FunctionalSizeRequiredRequest<>(); + request.setQuotaName(quotaName); + request.setFunction(function); + functionalSizeRequiredRequests.add(request); + return this; + } + + /** + * when message invoked, apply condition check to decide if need to + * skip this message's quota check + * @param function function with message as input and Boolean as return to + * tell whether we need skip this message's quota check + * @return this + */ + public QuotaMessageHandler addCheckCondition(Function function) { + conditions.add(function); + return this; + } + + public List getFixedSizeRequiredRequests() { + return fixedSizeRequiredRequests; + } + + public void setFixedSizeRequiredRequests(List fixedSizeRequiredRequests) { + this.fixedSizeRequiredRequests = fixedSizeRequiredRequests; + } + + public List> getFunctionalSizeRequiredRequests() { + return functionalSizeRequiredRequests; + } + + public void setFunctionalSizeRequiredRequests(List> functionalSizeRequiredRequests) { + this.functionalSizeRequiredRequests = functionalSizeRequiredRequests; + } + + public List> getConditions() { + return conditions; + } + + public void setConditions(List> conditions) { + this.conditions = conditions; + } +} diff --git a/header/src/main/java/org/zstack/header/identity/quota/QuotaRequiredRequest.java b/header/src/main/java/org/zstack/header/identity/quota/QuotaRequiredRequest.java new file mode 100644 index 00000000000..1f23522057d --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/quota/QuotaRequiredRequest.java @@ -0,0 +1,5 @@ +package org.zstack.header.identity.quota; + +public interface QuotaRequiredRequest { + String getQuotaName(); +} diff --git a/header/src/main/java/org/zstack/header/identity/rbac/RBAC.java b/header/src/main/java/org/zstack/header/identity/rbac/RBAC.java index 07bee62dd29..5e1183c8522 100755 --- a/header/src/main/java/org/zstack/header/identity/rbac/RBAC.java +++ b/header/src/main/java/org/zstack/header/identity/rbac/RBAC.java @@ -4,15 +4,13 @@ import org.zstack.header.core.StaticInit; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.PolicyStatement; -import org.zstack.header.identity.StatementEffect; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.SuppressCredentialCheck; import org.zstack.header.message.APIMessage; import org.zstack.utils.BeanUtils; import org.zstack.utils.DebugUtils; import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class RBAC { public static List permissions = new ArrayList<>(); @@ -113,12 +111,12 @@ public RoleBuilder permissionsByName(String...pnames) { } public RoleBuilder allow() { - role.effect = StatementEffect.Allow; + role.effect = PolicyStatementEffect.Allow; return this; } public RoleBuilder deny() { - role.effect = StatementEffect.Deny; + role.effect = PolicyStatementEffect.Deny; return this; } @@ -155,7 +153,7 @@ public static class Role { private String uuid; private String name; private Set allowedActions = new HashSet<>(); - private StatementEffect effect = StatementEffect.Allow; + private PolicyStatementEffect effect = PolicyStatementEffect.Allow; private boolean adminOnly; private boolean predefine = true; private List excludedActions = new ArrayList<>(); @@ -184,11 +182,11 @@ public void setAllowedActions(Set allowedActions) { this.allowedActions = allowedActions; } - public StatementEffect getEffect() { + public PolicyStatementEffect getEffect() { return effect; } - public void setEffect(StatementEffect effect) { + public void setEffect(PolicyStatementEffect effect) { this.effect = effect; } diff --git a/header/src/main/java/org/zstack/header/identity/role/RolePolicyRefInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/RolePolicyRefInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..3e4a7b81078 --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/role/RolePolicyRefInventoryDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.identity.role + +doc { + + title "角色策略引用清单" + + field { + name "roleUuid" + desc "角色的UUID" + type "String" + since "2.4.0" + } + field { + name "policyUuid" + desc "策略的UUID" + type "String" + since "2.4.0" + } + field { + name "createDate" + desc "创建日期" + type "Timestamp" + since "2.4.0" + } + field { + name "lastOpDate" + desc "最后操作日期" + type "Timestamp" + since "2.4.0" + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/identity/role/RoleStateDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/RoleStateDoc_zh_cn.groovy new file mode 100644 index 00000000000..88d0e15d4bb --- /dev/null +++ b/header/src/main/java/org/zstack/header/identity/role/RoleStateDoc_zh_cn.groovy @@ -0,0 +1,19 @@ +package org.zstack.header.identity.role + +doc { + + title "角色状态" + + field { + name "name" + desc "角色启用状态" + type "String" + since "2.4.0" + } + field { + name "ordinal" + desc "" + type "int" + since "2.4.0" + } +} diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsg.java index db8433f44f8..abaf94ccf91 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsg.java @@ -2,7 +2,7 @@ import org.springframework.http.HttpMethod; import org.zstack.header.identity.PolicyStatement; -import org.zstack.header.identity.StatementEffect; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.role.RoleVO; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; @@ -48,7 +48,7 @@ public static APIAddPolicyStatementsToRoleMsg __example__() { PolicyStatement state = new PolicyStatement(); state.setName("state-1"); - state.setEffect(StatementEffect.Allow); + state.setEffect(PolicyStatementEffect.Allow); state.setActions(asList("accpet")); msg.setStatements(asList(state)); diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsgDoc_zh_cn.groovy index a5d32cec281..189902b8cbe 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIAddPolicyStatementsToRoleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "statements" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsg.java index e64b8d828ff..7ed5cd971f9 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsg.java @@ -7,7 +7,12 @@ import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; -@RestRequest(path = "/identities/policies/{policyUuid}/roles/{roleUuid}", method = HttpMethod.POST, responseClass = APIAttachPolicyToRoleEvent.class) +@RestRequest( + path = "/identities/policies/{policyUuid}/roles/{roleUuid}", + method = HttpMethod.POST, + parameterName = "params", + responseClass = APIAttachPolicyToRoleEvent.class +) public class APIAttachPolicyToRoleMsg extends APIMessage implements RoleMessage { @APIParam(resourceType = RoleVO.class, checkAccount = true, operationTarget = true) private String roleUuid; diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsgDoc_zh_cn.groovy index 0698f7f00ca..e4c42d66b68 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachPolicyToRoleMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "roleUuid" - enclosedIn "" + enclosedIn "params" desc "" location "url" type "String" optional false since "0.6" - } column { name "policyUuid" - enclosedIn "" + enclosedIn "params" desc "权限策略UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsg.java index 5f3a70ba838..872f4001c8f 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsg.java @@ -1,13 +1,20 @@ package org.zstack.header.identity.role.api; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.identity.AccountVO; import org.zstack.header.identity.role.RoleVO; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; -@RestRequest(path = "/identities/accounts/{accountUuid}/roles/{roleUuid}", method = HttpMethod.POST, responseClass = APIAttachRoleToAccountEvent.class) +@RestRequest( + path = "/identities/accounts/{accountUuid}/roles/{roleUuid}", + method = HttpMethod.POST, + parameterName = "params", + responseClass = APIAttachRoleToAccountEvent.class, + morphTransform = Constants.MORPH_TRANSFORM_IAM1 +) public class APIAttachRoleToAccountMsg extends APIMessage implements RoleMessage { @APIParam(resourceType = RoleVO.class) private String roleUuid; diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsgDoc_zh_cn.groovy index f934da2b164..76cec092782 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIAttachRoleToAccountMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "roleUuid" - enclosedIn "" + enclosedIn "params" desc "" location "url" type "String" optional false since "0.6" - } column { name "accountUuid" - enclosedIn "" + enclosedIn "params" desc "账户UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateEvent.java b/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateEvent.java index b558f9cc2e5..def7e59ff3d 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateEvent.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateEvent.java @@ -1,7 +1,7 @@ package org.zstack.header.identity.role.api; import org.zstack.header.identity.PolicyStatement; -import org.zstack.header.identity.StatementEffect; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.role.RoleInventory; import org.zstack.header.identity.role.RolePolicyStatementInventory; import org.zstack.header.identity.role.RoleState; @@ -40,7 +40,7 @@ public static APIChangeRoleStateEvent __example__() { RolePolicyStatementInventory inv = new RolePolicyStatementInventory(); PolicyStatement statement = new PolicyStatement(); - statement.setEffect(StatementEffect.Allow); + statement.setEffect(PolicyStatementEffect.Allow); statement.setActions(asList("org.zstack.header.vm.APICreateVmInstanceMsg")); statement.setName("statement for test"); diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateMsgDoc_zh_cn.groovy index 8481e0db562..b24ff5b643a 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIChangeRoleStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleEvent.java b/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleEvent.java index ba32ecf9e46..6de9a7a4282 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleEvent.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleEvent.java @@ -1,7 +1,7 @@ package org.zstack.header.identity.role.api; import org.zstack.header.identity.PolicyStatement; -import org.zstack.header.identity.StatementEffect; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.role.RoleInventory; import org.zstack.header.identity.role.RolePolicyStatementInventory; import org.zstack.header.identity.role.RoleState; @@ -40,7 +40,7 @@ public static APICreateRoleEvent __example__() { role.setName("role-1"); RolePolicyStatementInventory inv = new RolePolicyStatementInventory(); PolicyStatement statement = new PolicyStatement(); - statement.setEffect(StatementEffect.Allow); + statement.setEffect(PolicyStatementEffect.Allow); statement.setActions(asList("org.zstack.header.vm.APICreateVmInstanceMsg")); statement.setName("statement for test"); diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsg.java index 439eb5011c1..e681b1781cc 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsg.java @@ -1,9 +1,10 @@ package org.zstack.header.identity.role.api; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.identity.PolicyStatement; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.PolicyVO; -import org.zstack.header.identity.StatementEffect; import org.zstack.header.message.APICreateMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; @@ -12,7 +13,7 @@ import static java.util.Arrays.asList; -@RestRequest(path = "/identities/roles", method = HttpMethod.POST, responseClass = APICreateRoleEvent.class, parameterName = "params") +@RestRequest(path = "/identities/roles", method = HttpMethod.POST, responseClass = APICreateRoleEvent.class, parameterName = "params", morphTransform = Constants.MORPH_TRANSFORM_IAM2) public class APICreateRoleMsg extends APICreateMessage { @APIParam(maxLength = 255) private String name; @@ -70,7 +71,7 @@ public static APICreateRoleMsg __example__() { msg.setPolicyUuids(asList(uuid())); PolicyStatement statement = new PolicyStatement(); - statement.setEffect(StatementEffect.Allow); + statement.setEffect(PolicyStatementEffect.Allow); statement.setActions(asList("org.zstack.header.vm.APICreateVmInstanceMsg")); statement.setName("statement for test"); msg.setStatements(asList(statement)); diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsgDoc_zh_cn.groovy index 774ccbc25cc..aacda1f472c 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APICreateRoleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "statements" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "policyUuids" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +83,24 @@ doc { type "List" optional true since "0.6" - + } + column { + name "identity" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "0.6" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsg.java index 480ca3f8f0f..9f5db41b10e 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsg.java @@ -1,13 +1,13 @@ package org.zstack.header.identity.role.api; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.identity.role.RoleVO; import org.zstack.header.message.APIDeleteMessage; import org.zstack.header.message.APIParam; -import org.zstack.header.network.l3.APIAddDnsToL3NetworkMsg; import org.zstack.header.rest.RestRequest; -@RestRequest(path = "/identities/roles/{uuid}", method = HttpMethod.DELETE, responseClass = APIDeleteRoleEvent.class) +@RestRequest(path = "/identities/roles/{uuid}", method = HttpMethod.DELETE, responseClass = APIDeleteRoleEvent.class, morphTransform = Constants.MORPH_TRANSFORM_IAM2) public class APIDeleteRoleMsg extends APIDeleteMessage implements RoleMessage { @APIParam(resourceType = RoleVO.class, successIfResourceNotExisting = true) private String uuid; diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsgDoc_zh_cn.groovy index dffffb3669e..5d09436fa4f 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIDeleteRoleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIDetachPolicyFromRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIDetachPolicyFromRoleMsgDoc_zh_cn.groovy index 784aa4ca8c3..aba09eedc1f 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIDetachPolicyFromRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIDetachPolicyFromRoleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "policyUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsg.java index 2b53ed34b1f..319ec0d6a98 100755 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsg.java @@ -1,15 +1,12 @@ package org.zstack.header.identity.role.api; import org.springframework.http.HttpMethod; -import org.zstack.header.identity.AccountVO; -import org.zstack.header.identity.role.RoleStateEvent; -import org.zstack.header.identity.role.RoleVO; +import org.zstack.header.Constants; import org.zstack.header.message.APIDeleteMessage; -import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; -@RestRequest(path = "/identities/accounts/{accountUuid}/roles/{roleUuid}", method = HttpMethod.DELETE, responseClass = APIDetachRoleFromAccountEvent.class) +@RestRequest(path = "/identities/accounts/{accountUuid}/roles/{roleUuid}", method = HttpMethod.DELETE, responseClass = APIDetachRoleFromAccountEvent.class, morphTransform = Constants.MORPH_TRANSFORM_IAM1) public class APIDetachRoleFromAccountMsg extends APIDeleteMessage implements RoleMessage { @APIParam private String roleUuid; diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsgDoc_zh_cn.groovy index 2dc4507f7fc..495d831f759 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIDetachRoleFromAccountMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "accountUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIQueryRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIQueryRoleMsgDoc_zh_cn.groovy index 20de2af3280..9391657b195 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIQueryRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIQueryRoleMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.identity.role.api import org.zstack.header.identity.role.api.APIQueryRoleReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryRole" diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIRemovePolicyStatementsFromRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIRemovePolicyStatementsFromRoleMsgDoc_zh_cn.groovy index 65f62d655c0..319ab2b4918 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIRemovePolicyStatementsFromRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIRemovePolicyStatementsFromRoleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "policyStatementUuids" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleEvent.java b/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleEvent.java index 488b2c027de..007dd62f6de 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleEvent.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleEvent.java @@ -1,7 +1,7 @@ package org.zstack.header.identity.role.api; import org.zstack.header.identity.PolicyStatement; -import org.zstack.header.identity.StatementEffect; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.role.RoleInventory; import org.zstack.header.identity.role.RolePolicyStatementInventory; import org.zstack.header.identity.role.RoleState; @@ -43,7 +43,7 @@ public static APIUpdateRoleEvent __example__() { role.setName("role-1"); RolePolicyStatementInventory inv = new RolePolicyStatementInventory(); PolicyStatement statement = new PolicyStatement(); - statement.setEffect(StatementEffect.Allow); + statement.setEffect(PolicyStatementEffect.Allow); statement.setActions(asList("org.zstack.header.vm.APICreateVmInstanceMsg")); statement.setName("statement for test"); diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsg.java b/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsg.java index 1800157f600..9064e8d56a9 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsg.java +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsg.java @@ -1,9 +1,10 @@ package org.zstack.header.identity.role.api; import org.springframework.http.HttpMethod; +import org.zstack.header.Constants; import org.zstack.header.identity.PolicyStatement; import org.zstack.header.identity.PolicyVO; -import org.zstack.header.identity.StatementEffect; +import org.zstack.header.identity.PolicyStatementEffect; import org.zstack.header.identity.role.RoleVO; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; @@ -18,7 +19,8 @@ @RestRequest(path = "/identities/roles/{uuid}/actions", method = HttpMethod.PUT, isAction = true, - responseClass = APIUpdateRoleEvent.class) + responseClass = APIUpdateRoleEvent.class, + morphTransform = Constants.MORPH_TRANSFORM_IAM1) public class APIUpdateRoleMsg extends APIMessage implements RoleMessage { @APIParam(resourceType = RoleVO.class) private String uuid; @@ -76,7 +78,7 @@ public static APIUpdateRoleMsg __example__() { msg.setName("role-1"); msg.setPolicyUuids(Arrays.asList(uuid())); PolicyStatement policy = new PolicyStatement(); - policy.setEffect(StatementEffect.Allow); + policy.setEffect(PolicyStatementEffect.Allow); policy.setName("test role"); policy.setActions(Arrays.asList("org.zstack.header.identity.role.api.APIUpdateRoleMsg")); msg.setStatements(Arrays.asList(new PolicyStatement())); diff --git a/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsgDoc_zh_cn.groovy index 34e8b0e0753..cb85994419d 100644 --- a/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/identity/role/api/APIUpdateRoleMsgDoc_zh_cn.groovy @@ -11,10 +11,9 @@ doc { rest { request { - url "PUT /v1/identities/roles/{uuid}" + url "PUT /v1/identities/roles/{uuid}/actions" - - header(Authorization: 'OAuth the-session-uuid') + header (Authorization: 'OAuth the-session-uuid') clz APIUpdateRoleMsg.class @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -38,9 +36,8 @@ doc { desc "资源名称" location "body" type "String" - optional false + optional true since "0.6" - } column { name "description" @@ -50,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "statements" @@ -60,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "policyUuids" @@ -70,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -80,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -90,7 +83,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APIAddImageMsg.java b/header/src/main/java/org/zstack/header/image/APIAddImageMsg.java index 4dc468207eb..1b06bdae020 100755 --- a/header/src/main/java/org/zstack/header/image/APIAddImageMsg.java +++ b/header/src/main/java/org/zstack/header/image/APIAddImageMsg.java @@ -22,7 +22,7 @@ parameterName = "params", responseClass = APIAddImageEvent.class ) -@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 3) +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 72) public class APIAddImageMsg extends APICreateMessage implements APIAuditor, AddImageMessage { @APIParam(maxLength = 255) private String name; @@ -35,7 +35,7 @@ public class APIAddImageMsg extends APICreateMessage implements APIAuditor, AddI private String mediaType; @APIParam(maxLength = 255, required = false) private String guestOsType; - @APIParam(required = false, maxLength = 32, validValues = {"x86_64", "aarch64", "mips64el"}) + @APIParam(required = false, maxLength = 32, validValues = {"x86_64", "aarch64", "mips64el", "loongarch64"}) private String architecture; private boolean system; @APIParam(required = false) diff --git a/header/src/main/java/org/zstack/header/image/APIAddImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIAddImageMsgDoc_zh_cn.groovy index 0a2028f1429..11bccf810ca 100644 --- a/header/src/main/java/org/zstack/header/image/APIAddImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIAddImageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "mediaType" @@ -69,7 +66,6 @@ doc { type "String" optional true since "0.6" - } column { name "system" @@ -79,7 +75,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "format" @@ -89,7 +84,6 @@ doc { type "String" optional true since "0.6" - } column { name "platform" @@ -109,7 +103,6 @@ doc { type "List" optional false since "0.6" - } column { name "type" @@ -119,7 +112,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -129,7 +121,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -139,7 +130,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -149,7 +139,6 @@ doc { type "List" optional true since "0.6" - } column { name "architecture" @@ -159,7 +148,7 @@ doc { type "String" optional true since "4.0" - values ("x86_64","aarch64","mips64el") + values ("x86_64","aarch64","mips64el","loongarch64") } column { name "tagUuids" @@ -168,8 +157,16 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" + } + column { + name "virtio" + enclosedIn "params" + desc "" + location "body" + type "boolean" + optional true + since "4.1.2" } } } @@ -178,4 +175,4 @@ doc { clz APIAddImageEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APICalculateImageHashEvent.java b/header/src/main/java/org/zstack/header/image/APICalculateImageHashEvent.java new file mode 100644 index 00000000000..4087f57f3ba --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICalculateImageHashEvent.java @@ -0,0 +1,56 @@ +package org.zstack.header.image; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.util.Collections; + +/** + * @ Author : yh.w + * @ Date : Created in 13:35 2023/11/10 + */ +@RestResponse(allTo = "inventory") +public class APICalculateImageHashEvent extends APIEvent { + private ImageInventory inventory; + + public APICalculateImageHashEvent(String apiId) { + super(apiId); + } + + public APICalculateImageHashEvent() { + super(null); + } + + public ImageInventory getInventory() { + return inventory; + } + + public void setInventory(ImageInventory inventory) { + this.inventory = inventory; + } + + public static APICalculateImageHashEvent __example__() { + APICalculateImageHashEvent event = new APICalculateImageHashEvent(); + + ImageInventory inv = new ImageInventory(); + inv.setUuid(uuid()); + + ImageBackupStorageRefInventory ref = new ImageBackupStorageRefInventory(); + ref.setBackupStorageUuid(uuid()); + ref.setImageUuid(inv.getUuid()); + ref.setInstallPath("ceph://zs-images/f0b149e053b34c7eb7fe694b182ebffd"); + ref.setStatus(ImageStatus.Ready.toString()); + + inv.setName("TinyLinux"); + inv.setBackupStorageRefs(Collections.singletonList(ref)); + inv.setUrl("http://192.168.1.20/share/images/tinylinux.qcow2"); + inv.setFormat(ImageConstant.QCOW2_FORMAT_STRING); + inv.setMediaType(ImageConstant.ImageMediaType.RootVolumeTemplate.toString()); + inv.setPlatform(ImagePlatform.Linux.toString()); + inv.setMd5Sum("6fc2357e711877c14c09eec960e51aed"); + + event.setInventory(inv); + return event; + } + +} diff --git a/header/src/main/java/org/zstack/header/image/APICalculateImageHashEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICalculateImageHashEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..7dd86d82438 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICalculateImageHashEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取镜像MD5值返回" + + ref { + name "inventory" + path "org.zstack.header.image.APICalculateImageHashEvent.inventory" + desc "null" + type "ImageInventory" + since "4.1.0" + clz ImageInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.1.0" + } + ref { + name "error" + path "org.zstack.header.image.APICalculateImageHashEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.1.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICalculateImageHashMsg.java b/header/src/main/java/org/zstack/header/image/APICalculateImageHashMsg.java new file mode 100644 index 00000000000..94a990f5974 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICalculateImageHashMsg.java @@ -0,0 +1,77 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.backup.BackupStorageVO; +import org.zstack.header.storage.backup.ImageHashAlgorithm; + +/** + * @ Author : yh.w + * @ Date : Created in 13:35 2023/11/10 + */ +@Action(category = ImageConstant.ACTION_CATEGORY) +@RestRequest( + path = "/images/{uuid}/actions", + isAction = true, + responseClass = APICalculateImageHashEvent.class, + method = HttpMethod.PUT +) +public class APICalculateImageHashMsg extends APIMessage implements ImageMessage, APIAuditor { + + @APIParam(resourceType = ImageVO.class, checkAccount = true) + private String uuid; + + @APIParam(resourceType = BackupStorageVO.class, checkAccount = true, operationTarget = true) + private String backupStorageUuid; + + @APIParam(required = false) + private String algorithm = ImageHashAlgorithm.MD5.toString(); + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public static APICalculateImageHashMsg __example__() { + APICalculateImageHashMsg msg = new APICalculateImageHashMsg(); + msg.setBackupStorageUuid(uuid()); + msg.setUuid(uuid()); + msg.setAlgorithm(ImageHashAlgorithm.MD5.toString()); + return msg; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new Result(((APICalculateImageHashMsg)msg).uuid, ImageVO.class); + } + + + @Override + public String getImageUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICalculateImageHashMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICalculateImageHashMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..b7c3ee2503a --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICalculateImageHashMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.image + +import org.zstack.header.image.APICalculateImageHashEvent + +doc { + title "CalculateImageHash" + + category "image" + + desc """计算镜像的MD5值""" + + rest { + request { + url "PUT /v1/images/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICalculateImageHashMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "calculateImageHash" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.1.0" + } + column { + name "backupStorageUuid" + enclosedIn "calculateImageHash" + desc "镜像存储UUID" + location "body" + type "String" + optional false + since "4.1.0" + } + column { + name "algorithm" + enclosedIn "calculateImageHash" + desc "" + location "body" + type "String" + optional true + since "4.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.1.0" + } + } + } + + response { + clz APICalculateImageHashEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIChangeImageStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIChangeImageStateMsgDoc_zh_cn.groovy index 498a249e76f..c4572210afa 100644 --- a/header/src/main/java/org/zstack/header/image/APIChangeImageStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIChangeImageStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APICloneImageEvent.java b/header/src/main/java/org/zstack/header/image/APICloneImageEvent.java new file mode 100644 index 00000000000..4798d138287 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICloneImageEvent.java @@ -0,0 +1,53 @@ +package org.zstack.header.image; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.util.Collections; + +@RestResponse(allTo = "inventory") +public class APICloneImageEvent extends APIEvent { + public APICloneImageEvent(String apiId) { + super(apiId); + } + + public APICloneImageEvent() { + super(null); + } + + private ImageInventory inventory; + + public ImageInventory getInventory() { + return inventory; + } + + public void setInventory(ImageInventory inventory) { + this.inventory = inventory; + } + + public static APICloneImageEvent __example__() { + APICloneImageEvent event = new APICloneImageEvent(); + + ImageInventory inv = new ImageInventory(); + inv.setUuid(uuid()); + + ImageBackupStorageRefInventory ref = new ImageBackupStorageRefInventory(); + ref.setBackupStorageUuid(uuid()); + ref.setImageUuid(inv.getUuid()); + ref.setInstallPath("ceph://zs-images/f0b149e053b34c7eb7fe694b182ebffd"); + ref.setStatus(ImageStatus.Ready.toString()); + + inv.setName("TinyLinux"); + inv.setBackupStorageRefs(Collections.singletonList(ref)); + inv.setUrl("http://192.168.1.20/share/images/tinylinux.qcow2"); + inv.setFormat(ImageConstant.QCOW2_FORMAT_STRING); + inv.setMediaType(ImageConstant.ImageMediaType.RootVolumeTemplate.toString()); + inv.setPlatform(ImagePlatform.Linux.toString()); + inv.setArchitecture(ImageArchitecture.x86_64.toString()); + + event.setInventory(inv); + return event; + } + +} + diff --git a/header/src/main/java/org/zstack/header/image/APICloneImageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICloneImageEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..f406289e561 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICloneImageEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "克隆镜像的执行结果" + + ref { + name "inventory" + path "org.zstack.header.image.APICloneImageEvent.inventory" + desc "null" + type "ImageInventory" + since "5.4.0" + clz ImageInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APICloneImageEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICloneImageMsg.java b/header/src/main/java/org/zstack/header/image/APICloneImageMsg.java new file mode 100644 index 00000000000..5f614e6f304 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICloneImageMsg.java @@ -0,0 +1,52 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.*; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +@TagResourceType(ImageVO.class) +@Action(category = ImageConstant.ACTION_CATEGORY) +@RestRequest( + path = "/image/clone/{imageUuid}", + method = HttpMethod.POST, + parameterName = "params", + responseClass = APICloneImageEvent.class +) +public class APICloneImageMsg extends APICreateMessage implements APIAuditor { + @APIParam(resourceType = ImageVO.class, noOwnerCheck = true) + private String imageUuid; + + @APIParam(required = false, validValues = {"DatabaseOnly"}) + private String strategy = ImageCloneStrategy.DatabaseOnly.toString(); + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return null; + } + + public String getImageUuid() { + return imageUuid; + } + + public void setImageUuid(String imageUuid) { + this.imageUuid = imageUuid; + } + + public String getStrategy() { + return strategy; + } + + public void setStrategy(String strategy) { + this.strategy = strategy; + } + + public static APICloneImageMsg __example__() { + APICloneImageMsg msg = new APICloneImageMsg(); + msg.setImageUuid(uuid()); + msg.setStrategy(ImageCloneStrategy.DatabaseOnly.toString()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICloneImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICloneImageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..22d7a47e1b0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICloneImageMsgDoc_zh_cn.groovy @@ -0,0 +1,95 @@ +package org.zstack.header.image + +import org.zstack.header.image.APICloneImageEvent + +doc { + title "CloneImage" + + category "image" + + desc """克隆镜像""" + + rest { + request { + url "POST /v1/image/clone/{imageUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICloneImageMsg.class + + desc """""" + + params { + + column { + name "imageUuid" + enclosedIn "params" + desc "镜像UUID" + location "url" + type "String" + optional false + since "5.4.0" + } + column { + name "imageGroupUuid" + enclosedIn "params" + desc "镜像组UUID" + location "body" + type "String" + optional false + since "5.4.0" + } + column { + name "strategy" + enclosedIn "params" + desc "克隆策略" + location "body" + type "String" + optional true + since "5.4.0" + values ("DatabaseOnly") + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.4.0" + } + } + } + + response { + clz APICloneImageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeMsgDoc_zh_cn.groovy index 1a8728ba849..d3654fc1b67 100644 --- a/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "volumeUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "backupStorageUuids" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +83,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy index 78ebb61fa4b..01c687c2719 100644 --- a/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APICreateDataVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "backupStorageUuids" @@ -59,7 +56,6 @@ doc { type "List" optional false since "0.6" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "tagUuids" @@ -78,8 +73,7 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageEvent.java b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageEvent.java new file mode 100644 index 00000000000..46641ac1ebb --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageEvent.java @@ -0,0 +1,35 @@ +package org.zstack.header.image; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APICreateImageGroupFromImageEvent extends APIEvent { + ImageGroupInventory inventory; + + public APICreateImageGroupFromImageEvent(String apiId) { + super(apiId); + } + + public APICreateImageGroupFromImageEvent() { + super(); + } + + public void setInventory(ImageGroupInventory imageGroup) { + this.inventory = imageGroup; + } + + public ImageGroupInventory getInventory() { + return inventory; + } + + public static APICreateImageGroupFromImageEvent __example__() { + APICreateImageGroupFromImageEvent event = new APICreateImageGroupFromImageEvent(); + ImageGroupInventory inv = new ImageGroupInventory(); + inv.setUuid("f0b149e0-53b3-4c7e-b7fe-694b182ebffd"); + inv.setName("example-image-group"); + inv.setDescription("example image group"); + event.setInventory(inv); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..7eafd031064 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "从镜像创建镜像组的返回" + + ref { + name "inventory" + path "org.zstack.header.image.APICreateImageGroupFromImageEvent.inventory" + desc "null" + type "ImageGroupInventory" + since "5.4.0" + clz ImageGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APICreateImageGroupFromImageEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageMsg.java b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageMsg.java new file mode 100644 index 00000000000..7f8d6fd8c39 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageMsg.java @@ -0,0 +1,72 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +import java.util.List; + +@Action(category = ImageConstant.ACTION_CATEGORY) +@RestRequest( + path = "/imagegroup/from/image/{rootVolumeTemplateUuid}", + method = HttpMethod.POST, + responseClass = APICreateImageGroupFromImageEvent.class, + parameterName = "params" +) +@TagResourceType(ImageVO.class) +public class APICreateImageGroupFromImageMsg extends APICreateMessage { + @APIParam(maxLength = 255) + private String name; + @APIParam(required = true, maxLength = 2048) + private String rootVolumeTemplateUuid; + @APIParam(required = false, maxLength = 2048) + private String description; + @APIParam(required = false) + private List dataVolumeTemplateUuids; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRootVolumeTemplateUuid() { + return rootVolumeTemplateUuid; + } + + public void setRootVolumeTemplateUuid(String rootVolumeTemplateUuid) { + this.rootVolumeTemplateUuid = rootVolumeTemplateUuid; + } + + public List getDataVolumeTemplateUuids() { + return dataVolumeTemplateUuids; + } + + public void setDataVolumeTemplateUuids(List dataVolumeTemplateUuids) { + this.dataVolumeTemplateUuids = dataVolumeTemplateUuids; + } + + public static APICreateImageGroupFromImageMsg __example__() { + APICreateImageGroupFromImageMsg msg = new APICreateImageGroupFromImageMsg(); + msg.setRootVolumeTemplateUuid("b7b9dcad-3c6d-4a7b-9a0a-1b9a20f5c002"); + msg.setName("example-image-group-from-image"); + msg.setDescription("create image group from root image template"); + msg.setDataVolumeTemplateUuids(java.util.Arrays.asList( + "c1b9dcad-3c6d-4a7b-9a0a-1b9a20f5c003", + "d2b9dcad-3c6d-4a7b-9a0a-1b9a20f5c004")); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..e41d9eed7f6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromImageMsgDoc_zh_cn.groovy @@ -0,0 +1,103 @@ +package org.zstack.header.image + +import org.zstack.header.image.APICreateImageGroupFromImageEvent + +doc { + title "CreateImageGroupFromImage" + + category "image" + + desc """从镜像创建镜像组""" + + rest { + request { + url "POST /v1/imagegroup/from/image/{rootVolumeTemplateUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateImageGroupFromImageMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "5.4.0" + } + column { + name "rootVolumeTemplateUuid" + enclosedIn "params" + desc "" + location "url" + type "String" + optional false + since "5.4.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "dataVolumeTemplateUuids" + enclosedIn "params" + desc "数据盘镜像模板 UUID 列表" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.4.0" + } + } + } + + response { + clz APICreateImageGroupFromImageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotEvent.java b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotEvent.java new file mode 100644 index 00000000000..aed70766b0c --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotEvent.java @@ -0,0 +1,34 @@ +package org.zstack.header.image; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APICreateImageGroupFromSnapshotEvent extends APIEvent { + ImageGroupInventory inventory; + + public APICreateImageGroupFromSnapshotEvent(String apiId) { + super(apiId); + } + + public APICreateImageGroupFromSnapshotEvent() { + super(); + } + + public void setInventory(ImageGroupInventory imageGroup) { + this.inventory = imageGroup; + } + + public ImageGroupInventory getInventory() { + return inventory; + } + + public static APICreateImageGroupFromSnapshotEvent __example__() { + APICreateImageGroupFromSnapshotEvent event = new APICreateImageGroupFromSnapshotEvent(); + ImageGroupInventory inv = new ImageGroupInventory(); + inv.setUuid("a4b149e0-53b3-4c7e-b7fe-694b182eb001"); + inv.setName("example-image-group-from-snapshot"); + event.setInventory(inv); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..601a0ea15c7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "从快照创建镜像组的返回" + + ref { + name "inventory" + path "org.zstack.header.image.APICreateImageGroupFromSnapshotEvent.inventory" + desc "null" + type "ImageGroupInventory" + since "5.4.0" + clz ImageGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APICreateImageGroupFromSnapshotEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotMsg.java b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotMsg.java new file mode 100644 index 00000000000..74fd042043c --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotMsg.java @@ -0,0 +1,73 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +import java.util.List; + +@Action(category = ImageConstant.ACTION_CATEGORY) +@RestRequest( + path = "/imagegroup/from/snapshot/{rootVolumeSnapshotUuid}", + method = HttpMethod.POST, + responseClass = APICreateImageGroupFromSnapshotEvent.class, + parameterName = "params" +) +@TagResourceType(ImageVO.class) +public class APICreateImageGroupFromSnapshotMsg extends APICreateMessage { + @APIParam(maxLength = 255) + private String name; + @APIParam(required = true, maxLength = 2048) + private String rootVolumeSnapshotUuid; + @APIParam(required = false, maxLength = 2048) + private String description; + @APIParam(required = false) + private List dataVolumeSnapshotUuids; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getRootVolumeSnapshotUuid() { + return rootVolumeSnapshotUuid; + } + + public void setRootVolumeSnapshotUuid(String rootVolumeSnapshotUuid) { + this.rootVolumeSnapshotUuid = rootVolumeSnapshotUuid; + } + + public List getDataVolumeSnapshotUuids() { + return dataVolumeSnapshotUuids; + } + + public void setDataVolumeSnapshotUuids(List dataVolumeSnapshotUuids) { + this.dataVolumeSnapshotUuids = dataVolumeSnapshotUuids; + } + + public static APICreateImageGroupFromSnapshotMsg __example__() { + APICreateImageGroupFromSnapshotMsg msg = new APICreateImageGroupFromSnapshotMsg(); + msg.setRootVolumeSnapshotUuid("aa12b3cd-3c6d-4a7b-9a0a-1b9a20f5c005"); + msg.setName("example-image-group-from-snapshot"); + msg.setDescription("create image group from root volume snapshot"); + msg.setDataVolumeSnapshotUuids(java.util.Arrays.asList( + "bb12b3cd-3c6d-4a7b-9a0a-1b9a20f5c006", + "cc12b3cd-3c6d-4a7b-9a0a-1b9a20f5c007" + )); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..a89468d1adc --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromSnapshotMsgDoc_zh_cn.groovy @@ -0,0 +1,103 @@ +package org.zstack.header.image + +import org.zstack.header.image.APICreateImageGroupFromSnapshotEvent + +doc { + title "CreateImageGroupFromSnapshot" + + category "image" + + desc """从快照创建镜像组""" + + rest { + request { + url "POST /v1/imagegroup/from/snapshot/{rootVolumeSnapshotUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateImageGroupFromSnapshotMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "5.4.0" + } + column { + name "rootVolumeSnapshotUuid" + enclosedIn "params" + desc "" + location "url" + type "String" + optional false + since "5.4.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "dataVolumeSnapshotUuids" + enclosedIn "params" + desc "数据盘快照 UUID 列表" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.4.0" + } + } + } + + response { + clz APICreateImageGroupFromSnapshotEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceEvent.java b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceEvent.java new file mode 100644 index 00000000000..21cc3c92b1e --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceEvent.java @@ -0,0 +1,25 @@ +package org.zstack.header.image; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APICreateImageGroupFromVmInstanceEvent extends APIEvent { + ImageGroupInventory inventory; + + public APICreateImageGroupFromVmInstanceEvent(String apiId) { + super(apiId); + } + + public APICreateImageGroupFromVmInstanceEvent() { + super(); + } + + public void setInventory(ImageGroupInventory imageGroup) { + this.inventory = imageGroup; + } + + public ImageGroupInventory getInventory() { + return inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..c7472afdbdc --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "从虚拟机创建镜像组的返回" + + ref { + name "inventory" + path "org.zstack.header.image.APICreateImageGroupFromVmInstanceEvent.inventory" + desc "null" + type "ImageGroupInventory" + since "5.4.0" + clz ImageGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APICreateImageGroupFromVmInstanceEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceMsg.java b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceMsg.java new file mode 100644 index 00000000000..b36db132359 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceMsg.java @@ -0,0 +1,58 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; +import org.zstack.header.vm.VmInstanceVO; + +@Action(category = ImageConstant.ACTION_CATEGORY) +@RestRequest( + path = "/images/groups/from/vm-instance", + method = HttpMethod.POST, + responseClass = APICreateImageGroupFromVmInstanceEvent.class, + parameterName = "params" +) +@TagResourceType(ImageVO.class) +public class APICreateImageGroupFromVmInstanceMsg extends APICreateMessage { + @APIParam(resourceType = VmInstanceVO.class, checkAccount = true, operationTarget = true) + private String vmInstanceUuid; + @APIParam(maxLength = 255) + private String name; + @APIParam(required = false, maxLength = 2048) + private String description; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public static APICreateImageGroupFromVmInstanceMsg __example__() { + APICreateImageGroupFromVmInstanceMsg msg = new APICreateImageGroupFromVmInstanceMsg(); + msg.setVmInstanceUuid("e7b9dcad-3c6d-4a7b-9a0a-1b9a20f5c001"); + msg.setName("example-image-group-from-vm"); + msg.setDescription("create image group from vm instance"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..cecf4966ac4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APICreateImageGroupFromVmInstanceMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.header.image + +import org.zstack.header.image.APICreateImageGroupFromVmInstanceEvent + +doc { + title "CreateImageGroupFromVmInstance" + + category "image" + + desc """从虚拟机创建镜像组""" + + rest { + request { + url "POST /v1/images/groups/from/vm-instance" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateImageGroupFromVmInstanceMsg.class + + desc """""" + + params { + + column { + name "vmInstanceUuid" + enclosedIn "params" + desc "云主机UUID" + location "body" + type "String" + optional false + since "5.4.0" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "5.4.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.4.0" + } + } + } + + response { + clz APICreateImageGroupFromVmInstanceEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromRootVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromRootVolumeMsgDoc_zh_cn.groovy index 8cc77899f8e..394b429a66e 100644 --- a/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromRootVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromRootVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "guestOsType" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "backupStorageUuids" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "rootVolumeUuid" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "platform" @@ -89,7 +84,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "resourceUuid" @@ -99,7 +93,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +102,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +111,6 @@ doc { type "List" optional true since "0.6" - } column { name "architecture" @@ -129,7 +120,6 @@ doc { type "String" optional true since "4.0" - } column { name "tagUuids" @@ -138,8 +128,16 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" + } + column { + name "virtio" + enclosedIn "params" + desc "" + location "body" + type "boolean" + optional true + since "4.1.2" } } } @@ -148,4 +146,4 @@ doc { clz APICreateRootVolumeTemplateFromRootVolumeEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy index 3d7908d82c4..c82438a6c10 100644 --- a/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APICreateRootVolumeTemplateFromVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "guestOsType" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "backupStorageUuids" @@ -69,7 +65,6 @@ doc { type "List" optional false since "0.6" - } column { name "platform" @@ -89,7 +84,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "resourceUuid" @@ -99,7 +93,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +102,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +111,6 @@ doc { type "List" optional true since "0.6" - } column { name "architecture" @@ -129,7 +120,6 @@ doc { type "String" optional true since "4.0" - } column { name "tagUuids" @@ -138,8 +128,16 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" + } + column { + name "virtio" + enclosedIn "params" + desc "" + location "body" + type "boolean" + optional true + since "4.1.2" } } } @@ -148,4 +146,4 @@ doc { clz APICreateRootVolumeTemplateFromVolumeSnapshotEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIDeleteImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIDeleteImageMsgDoc_zh_cn.groovy index d26bea2014e..313cd22c256 100644 --- a/header/src/main/java/org/zstack/header/image/APIDeleteImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIDeleteImageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "backupStorageUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "deleteMode" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupEvent.java b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupEvent.java new file mode 100644 index 00000000000..d6499a9505d --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupEvent.java @@ -0,0 +1,21 @@ +package org.zstack.header.image; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIExpungeImageGroupEvent extends APIEvent { + public APIExpungeImageGroupEvent() { + } + + public APIExpungeImageGroupEvent(String apiId) { + super(apiId); + } + + public static APIExpungeImageGroupEvent __example__() { + APIExpungeImageGroupEvent event = new APIExpungeImageGroupEvent(); + + + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..95b4c0d40ad --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.image + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "删除镜像组的返回" + + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APIExpungeImageGroupEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null" + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupMsg.java b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupMsg.java new file mode 100644 index 00000000000..849fd236442 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupMsg.java @@ -0,0 +1,33 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@Action(category = ImageConstant.ACTION_CATEGORY) +@RestRequest( + path = "/imagegroups/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIExpungeImageGroupEvent.class, + isAction = true +) +public class APIExpungeImageGroupMsg extends APIMessage { + @APIParam(required = true, resourceType = ImageGroupVO.class, checkAccount = true, operationTarget = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public static APIExpungeImageGroupMsg __example__() { + APIExpungeImageGroupMsg msg = new APIExpungeImageGroupMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..2a43cafb204 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIExpungeImageGroupMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.image + +import org.zstack.header.image.APIExpungeImageGroupEvent + +doc { + title "ExpungeImageGroup" + + category "image" + + desc """删除镜像组""" + + rest { + request { + url "PUT /v1/imagegroups/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIExpungeImageGroupMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "expungeImageGroup" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.4.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.4.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.4.0" + } + } + } + + response { + clz APIExpungeImageGroupEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIExpungeImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIExpungeImageMsgDoc_zh_cn.groovy index e3fb6df3106..832970008d6 100644 --- a/header/src/main/java/org/zstack/header/image/APIExpungeImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIExpungeImageMsgDoc_zh_cn.groovy @@ -15,7 +15,6 @@ doc { header (Authorization: 'OAuth the-session-uuid') - clz APIExpungeImageMsg.class desc """""" @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "backupStorageUuids" @@ -40,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -50,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -60,7 +56,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "uuid" + enclosedIn "expungeImage" + desc "资源的UUID,唯一标示该资源" + location "body" + type "String" + optional true + since "3.2.0" } } } diff --git a/header/src/main/java/org/zstack/header/image/APIGetCandidateBackupStorageForCreatingImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIGetCandidateBackupStorageForCreatingImageMsgDoc_zh_cn.groovy index fe2b2072491..37be8b8956c 100644 --- a/header/src/main/java/org/zstack/header/image/APIGetCandidateBackupStorageForCreatingImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIGetCandidateBackupStorageForCreatingImageMsgDoc_zh_cn.groovy @@ -31,7 +31,6 @@ doc { type "String" optional true since "0.6" - } column { name "volumeSnapshotUuid" @@ -41,7 +40,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -51,7 +49,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -61,7 +58,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APIGetUploadImageJobDetailsMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIGetUploadImageJobDetailsMsgDoc_zh_cn.groovy index dae5a27614b..869e0d59739 100644 --- a/header/src/main/java/org/zstack/header/image/APIGetUploadImageJobDetailsMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIGetUploadImageJobDetailsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.1.0" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupMsg.java b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupMsg.java new file mode 100644 index 00000000000..383e304d76d --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupMsg.java @@ -0,0 +1,25 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.Collections; +import java.util.List; + +@AutoQuery(replyClass = APIQueryImageGroupReply.class, inventoryClass = ImageGroupInventory.class) +@Action(category = ImageConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/imagegroups", + optionalPaths = {"/imagegroups/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryImageGroupReply.class +) +public class APIQueryImageGroupMsg extends APIQueryMessage { + public static List __example__() { + return Collections.singletonList("uuid=" + uuid()); + } + +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..8d081b59021 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.image + +import org.zstack.header.image.APIQueryImageGroupReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryImageGroup" + + category "image" + + desc """查询镜像组""" + + rest { + request { + url "GET /v1/imagegroups" + url "GET /v1/imagegroups/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryImageGroupMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryImageGroupReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefMsg.java b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefMsg.java new file mode 100644 index 00000000000..3fb9bf2466e --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefMsg.java @@ -0,0 +1,25 @@ +package org.zstack.header.image; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.Collections; +import java.util.List; + +@AutoQuery(replyClass = APIQueryImageGroupRefReply.class, inventoryClass = ImageGroupRefInventory.class) +@Action(category = ImageConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/imagegrouprefs", + optionalPaths = {"/imagegrouprefs/{imageGroupUuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryImageGroupRefReply.class +) +public class APIQueryImageGroupRefMsg extends APIQueryMessage { + public static List __example__() { + return Collections.singletonList("uuid=" + uuid()); + } + +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..0cfd9617faf --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.image + +import org.zstack.header.image.APIQueryImageGroupRefReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryImageGroupRef" + + category "image" + + desc """查询镜像组关联关系""" + + rest { + request { + url "GET /v1/imagegrouprefs" + url "GET /v1/imagegrouprefs/{imageGroupUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryImageGroupRefMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryImageGroupRefReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefReply.java b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefReply.java new file mode 100644 index 00000000000..3b6143b38dc --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefReply.java @@ -0,0 +1,27 @@ +package org.zstack.header.image; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQueryImageGroupRefReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryImageGroupRefReply __example__() { + APIQueryImageGroupRefReply reply = new APIQueryImageGroupRefReply(); + + + return reply; + } + +} diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..f8e6d9fac4e --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupRefReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageGroupRefInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询镜像组关联关系的返回" + + ref { + name "inventories" + path "org.zstack.header.image.APIQueryImageGroupRefReply.inventories" + desc "null" + type "List" + since "5.4.0" + clz ImageGroupRefInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APIQueryImageGroupRefReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null" + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupReply.java b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupReply.java new file mode 100644 index 00000000000..277e04885e9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupReply.java @@ -0,0 +1,27 @@ +package org.zstack.header.image; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQueryImageGroupReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryImageGroupReply __example__() { + APIQueryImageGroupReply reply = new APIQueryImageGroupReply(); + + + return reply; + } + +} diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageGroupReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..76e2651f944 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageGroupReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.image + +import org.zstack.header.image.ImageGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询镜像组的返回" + + ref { + name "inventories" + path "org.zstack.header.image.APIQueryImageGroupReply.inventories" + desc "null" + type "List" + since "5.4.0" + clz ImageGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.4.0" + } + ref { + name "error" + path "org.zstack.header.image.APIQueryImageGroupReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/image/APIQueryImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIQueryImageMsgDoc_zh_cn.groovy index 39e289a42ef..fd5cefe4d34 100644 --- a/header/src/main/java/org/zstack/header/image/APIQueryImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIQueryImageMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.image import org.zstack.header.image.APIQueryImageReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryImage" diff --git a/header/src/main/java/org/zstack/header/image/APIRecoverImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIRecoverImageMsgDoc_zh_cn.groovy index d4562e442a5..c8d4e495b47 100644 --- a/header/src/main/java/org/zstack/header/image/APIRecoverImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIRecoverImageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "backupStorageUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APISetImageBootModeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APISetImageBootModeMsgDoc_zh_cn.groovy index ef7a2081be7..0400f2617a2 100644 --- a/header/src/main/java/org/zstack/header/image/APISetImageBootModeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APISetImageBootModeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9.0" - } column { name "bootMode" @@ -49,7 +48,6 @@ doc { type "List" optional true since "3.9.0" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "3.9.0" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APISyncImageSizeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APISyncImageSizeMsgDoc_zh_cn.groovy index 8198c50d262..a2310dae3d3 100644 --- a/header/src/main/java/org/zstack/header/image/APISyncImageSizeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APISyncImageSizeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/image/APIUpdateImageMsg.java b/header/src/main/java/org/zstack/header/image/APIUpdateImageMsg.java index 8eb6a87d6a0..4d6fc2663c0 100755 --- a/header/src/main/java/org/zstack/header/image/APIUpdateImageMsg.java +++ b/header/src/main/java/org/zstack/header/image/APIUpdateImageMsg.java @@ -32,7 +32,7 @@ public class APIUpdateImageMsg extends APIMessage implements ImageMessage { private Boolean system; @APIParam(required = false, validValues = {"Linux", "Windows", "Other", "Paravirtualization", "WindowsVirtio"}) private String platform; - @APIParam(required = false, maxLength = 32, validValues = {"x86_64", "aarch64", "mips64el"}) + @APIParam(required = false, maxLength = 32, validValues = {"x86_64", "aarch64", "mips64el", "loongarch64"}) private String architecture; @APIParam(required = false) private Boolean virtio; diff --git a/header/src/main/java/org/zstack/header/image/APIUpdateImageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/APIUpdateImageMsgDoc_zh_cn.groovy index 7bb458ecee5..fde9191fc4c 100644 --- a/header/src/main/java/org/zstack/header/image/APIUpdateImageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/APIUpdateImageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "guestOsType" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "mediaType" @@ -89,7 +85,6 @@ doc { type "Boolean" optional true since "0.6" - } column { name "platform" @@ -109,7 +104,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +113,6 @@ doc { type "List" optional true since "0.6" - } column { name "architecture" @@ -129,7 +122,16 @@ doc { type "String" optional true since "4.0" - values ("x86_64","aarch64","mips64el") + values ("x86_64","aarch64","mips64el","loongarch64") + } + column { + name "virtio" + enclosedIn "updateImage" + desc "" + location "body" + type "Boolean" + optional true + since "4.1.2" } } } @@ -138,4 +140,4 @@ doc { clz APIUpdateImageEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/CalculateImageHashMsg.java b/header/src/main/java/org/zstack/header/image/CalculateImageHashMsg.java new file mode 100644 index 00000000000..cce96ad6624 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/CalculateImageHashMsg.java @@ -0,0 +1,52 @@ +package org.zstack.header.image; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @ Author : yh.w + * @ Date : Created in 11:34 2023/12/14 + */ +public class CalculateImageHashMsg extends NeedReplyMessage implements ImageMessage { + + private String uuid; + private String backupStorageUuid; + private String algorithm; + + public CalculateImageHashMsg(APICalculateImageHashMsg amsg) { + uuid = amsg.getUuid(); + backupStorageUuid = amsg.getBackupStorageUuid(); + algorithm = amsg.getAlgorithm(); + } + + public CalculateImageHashMsg() { + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + @Override + public String getImageUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/image/CalculateImageHashReply.java b/header/src/main/java/org/zstack/header/image/CalculateImageHashReply.java new file mode 100644 index 00000000000..cf61b2f3efe --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/CalculateImageHashReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.image; + +import org.zstack.header.message.MessageReply; + +/** + * @ Author : yh.w + * @ Date : Created in 11:44 2023/12/14 + */ +public class CalculateImageHashReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeReply.java b/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeReply.java index 8454b90e437..af1a1820551 100644 --- a/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeReply.java +++ b/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeReply.java @@ -4,9 +4,10 @@ /** */ -public class CreateDataVolumeTemplateFromVolumeReply extends MessageReply { +public class CreateDataVolumeTemplateFromVolumeReply extends MessageReply implements ImageReply { private ImageInventory inventory; + @Override public ImageInventory getInventory() { return inventory; } diff --git a/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeSnapshotMsg.java index 28eb5f1cbef..64a9641bfa6 100644 --- a/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/image/CreateDataVolumeTemplateFromVolumeSnapshotMsg.java @@ -8,7 +8,8 @@ /** * Created by MaJin on 2021/3/16. */ -public class CreateDataVolumeTemplateFromVolumeSnapshotMsg extends NeedReplyMessage implements CreateDataVolumeTemplateMessage{ +public class CreateDataVolumeTemplateFromVolumeSnapshotMsg extends NeedReplyMessage + implements CreateDataVolumeTemplateMessage, CreateTemplateFromSnapshotMessage { private String resourceUuid; private String snapshotUuid; private String name; diff --git a/header/src/main/java/org/zstack/header/image/CreateImageReply.java b/header/src/main/java/org/zstack/header/image/CreateImageReply.java new file mode 100644 index 00000000000..c7b2ff2b5c8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/CreateImageReply.java @@ -0,0 +1,16 @@ +package org.zstack.header.image; + +import org.zstack.header.message.MessageReply; + +public abstract class CreateImageReply extends MessageReply implements ImageReply { + private ImageInventory inventory; + + @Override + public ImageInventory getInventory() { + return inventory; + } + + public void setInventory(ImageInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromRootVolumeReply.java b/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromRootVolumeReply.java index e89dc442b52..1c8ec16a09a 100755 --- a/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromRootVolumeReply.java +++ b/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromRootVolumeReply.java @@ -5,9 +5,10 @@ /** * Created by camile on 2/6/2018. */ -public class CreateRootVolumeTemplateFromRootVolumeReply extends MessageReply { +public class CreateRootVolumeTemplateFromRootVolumeReply extends MessageReply implements ImageReply { private ImageInventory inventory; + @Override public ImageInventory getInventory() { return inventory; } diff --git a/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromVolumeSnapshotMsg.java index f3bd0efa3e7..1a3ca5653df 100644 --- a/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/image/CreateRootVolumeTemplateFromVolumeSnapshotMsg.java @@ -8,7 +8,8 @@ /** * Created by MaJin on 2021/3/16. */ -public class CreateRootVolumeTemplateFromVolumeSnapshotMsg extends NeedReplyMessage implements CreateRootVolumeTemplateMessage { +public class CreateRootVolumeTemplateFromVolumeSnapshotMsg extends NeedReplyMessage + implements CreateRootVolumeTemplateMessage, CreateTemplateFromSnapshotMessage { private String resourceUuid; private String snapshotUuid; private String name; diff --git a/header/src/main/java/org/zstack/header/image/CreateTemplateFromSnapshotMessage.java b/header/src/main/java/org/zstack/header/image/CreateTemplateFromSnapshotMessage.java new file mode 100644 index 00000000000..0ba999f8959 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/CreateTemplateFromSnapshotMessage.java @@ -0,0 +1,6 @@ +package org.zstack.header.image; + +public interface CreateTemplateFromSnapshotMessage { + void setSnapshotUuid(String snapshotUuid); + String getSnapshotUuid(); +} diff --git a/header/src/main/java/org/zstack/header/image/CreateTemporaryDataVolumeTemplateFromVolumeSnapshotReply.java b/header/src/main/java/org/zstack/header/image/CreateTemporaryDataVolumeTemplateFromVolumeSnapshotReply.java index 40f7887cca8..7f1fc575d36 100644 --- a/header/src/main/java/org/zstack/header/image/CreateTemporaryDataVolumeTemplateFromVolumeSnapshotReply.java +++ b/header/src/main/java/org/zstack/header/image/CreateTemporaryDataVolumeTemplateFromVolumeSnapshotReply.java @@ -5,7 +5,7 @@ /** * Created by MaJin on 2021/3/18. */ -public class CreateTemporaryDataVolumeTemplateFromVolumeSnapshotReply extends MessageReply { +public class CreateTemporaryDataVolumeTemplateFromVolumeSnapshotReply extends MessageReply implements ImageReply { private ImageInventory inventory; private String locateHostUuid; private String locatePsUuid; diff --git a/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg.java index 7fe8b8ced4e..2aa59085fad 100644 --- a/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg.java @@ -6,7 +6,8 @@ /** * Created by MaJin on 2021/3/18. */ -public class CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg extends NeedReplyMessage implements CreateTemporaryRootVolumeTemplateMessage { +public class CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg extends NeedReplyMessage + implements CreateTemporaryRootVolumeTemplateMessage, CreateTemplateFromSnapshotMessage { private String snapshotUuid; private String guestOsType; private String platform; @@ -15,10 +16,12 @@ public class CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg extends Need private SessionInventory session; private boolean virtio = true; + @Override public void setSnapshotUuid(String snapshotUuid) { this.snapshotUuid = snapshotUuid; } + @Override public String getSnapshotUuid() { return snapshotUuid; } diff --git a/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotReply.java b/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotReply.java index c04345e8c3c..7289cf67cce 100644 --- a/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotReply.java +++ b/header/src/main/java/org/zstack/header/image/CreateTemporaryRootVolumeTemplateFromVolumeSnapshotReply.java @@ -5,11 +5,12 @@ /** * Created by MaJin on 2021/3/18. */ -public class CreateTemporaryRootVolumeTemplateFromVolumeSnapshotReply extends MessageReply { +public class CreateTemporaryRootVolumeTemplateFromVolumeSnapshotReply extends MessageReply implements ImageReply { private ImageInventory inventory; private String locateHostUuid; private String locatePsUuid; + @Override public ImageInventory getInventory() { return inventory; } diff --git a/header/src/main/java/org/zstack/header/image/ImageArchitecture.java b/header/src/main/java/org/zstack/header/image/ImageArchitecture.java index 40e2ee6e304..efb83f5d5c4 100644 --- a/header/src/main/java/org/zstack/header/image/ImageArchitecture.java +++ b/header/src/main/java/org/zstack/header/image/ImageArchitecture.java @@ -3,7 +3,8 @@ public enum ImageArchitecture { x86_64, aarch64, - mips64el; + mips64el, + loongarch64; private static String defaultArch = System.getProperty("os.arch").equals("amd64") ? "x86_64" : System.getProperty("os.arch"); diff --git a/header/src/main/java/org/zstack/header/image/ImageCloneStrategy.java b/header/src/main/java/org/zstack/header/image/ImageCloneStrategy.java new file mode 100644 index 00000000000..abd9fe2d361 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageCloneStrategy.java @@ -0,0 +1,5 @@ +package org.zstack.header.image; + +public enum ImageCloneStrategy { + DatabaseOnly, +} diff --git a/header/src/main/java/org/zstack/header/image/ImageConstant.java b/header/src/main/java/org/zstack/header/image/ImageConstant.java index 4dc66b381cf..62640d2d4b9 100755 --- a/header/src/main/java/org/zstack/header/image/ImageConstant.java +++ b/header/src/main/java/org/zstack/header/image/ImageConstant.java @@ -20,7 +20,12 @@ enum ImageMediaType { String QCOW2_FORMAT_STRING = "qcow2"; String RAW_FORMAT_STRING = "raw"; String VMTX_FORMAT_STRING = "vmtx"; + String VMDK_FORMAT_STRING = "vmdk"; // image less than 1MB is useless long MINI_IMAGE_SIZE_IN_BYTE = 1048576L; + String EXPORTED_IMAGE_PREFIX = "image-"; + String EXPORTED_PACKAGE_PREFIX = "package-"; + + String SNAPSHOT_REUSE_IMAGE_SCHEMA = "volumeSnapshotReuse://"; } diff --git a/header/src/main/java/org/zstack/header/image/ImageEO.java b/header/src/main/java/org/zstack/header/image/ImageEO.java index acc78d4e409..b04867f6051 100755 --- a/header/src/main/java/org/zstack/header/image/ImageEO.java +++ b/header/src/main/java/org/zstack/header/image/ImageEO.java @@ -1,8 +1,6 @@ package org.zstack.header.image; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import javax.persistence.*; /** */ diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupInventory.java b/header/src/main/java/org/zstack/header/image/ImageGroupInventory.java new file mode 100644 index 00000000000..9489aad53e1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupInventory.java @@ -0,0 +1,104 @@ +package org.zstack.header.image; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = ImageGroupVO.class, collectionValueOfMethod = "valueOf1") +public class ImageGroupInventory implements Serializable { + private Integer imageCount; + private String name; + private String description; + private String status; + private Timestamp createDate; + private Timestamp lastOpDate; + private String uuid; + + protected ImageGroupInventory(ImageGroupVO vo) { + this.setImageCount(vo.getImageCount()); + this.setName(vo.getName()); + this.setStatus(vo.getStatus().toString()); + this.setDescription(vo.getDescription()); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + this.setUuid(vo.getUuid()); + } + + public static ImageGroupInventory valueOf(ImageGroupVO vo) { + return new ImageGroupInventory(vo); + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (ImageGroupVO vo : vos) { + invs.add(ImageGroupInventory.valueOf(vo)); + } + return invs; + } + + public ImageGroupInventory() { + } + + + public Integer getImageCount() { + return imageCount; + } + + public void setImageCount(Integer imageCount) { + this.imageCount = imageCount; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/ImageGroupInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..af9ac25cbc3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupInventoryDoc_zh_cn.groovy @@ -0,0 +1,52 @@ +package org.zstack.header.image + +import java.lang.Integer +import java.sql.Timestamp + +doc { + + title "镜像组清单" + + field { + name "imageCount" + desc "" + type "Integer" + since "5.4.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.4.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.4.0" + } + field { + name "status" + desc "" + type "String" + since "5.4.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.4.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.4.0" + } + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.4.0" + } +} diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupRefInventory.java b/header/src/main/java/org/zstack/header/image/ImageGroupRefInventory.java new file mode 100644 index 00000000000..c5d337cffc6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupRefInventory.java @@ -0,0 +1,74 @@ +package org.zstack.header.image; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = ImageGroupRefVO.class, collectionValueOfMethod = "valueOf1") +public class ImageGroupRefInventory implements Serializable { + private String imageUuid; + private String imageGroupUuid; + private Timestamp createDate; + private Timestamp lastOpDate; + + protected ImageGroupRefInventory(ImageGroupRefVO vo) { + this.setImageUuid(vo.getImageUuid()); + this.setImageGroupUuid(vo.getImageGroupUuid()); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + } + + public ImageGroupRefInventory() { + } + + public static ImageGroupRefInventory valueOf(ImageGroupRefVO vo) { + return new ImageGroupRefInventory(vo); + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (ImageGroupRefVO vo : vos) { + invs.add(ImageGroupRefInventory.valueOf(vo)); + } + return invs; + } + + public String getImageUuid() { + return imageUuid; + } + + public void setImageUuid(String imageUuid) { + this.imageUuid = imageUuid; + } + + public String getImageGroupUuid() { + return imageGroupUuid; + } + + public void setImageGroupUuid(String imageGroupUuid) { + this.imageGroupUuid = imageGroupUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + +} diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupRefInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/ImageGroupRefInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..eb3bc0d91b6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupRefInventoryDoc_zh_cn.groovy @@ -0,0 +1,33 @@ +package org.zstack.header.image + +import java.sql.Timestamp + +doc { + + title "镜像组引用结构清单" + + field { + name "imageUuid" + desc "镜像UUID" + type "String" + since "5.4.0" + } + field { + name "imageGroupUuid" + desc "" + type "String" + since "5.4.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.4.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.4.0" + } +} diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupRefVO.java b/header/src/main/java/org/zstack/header/image/ImageGroupRefVO.java new file mode 100644 index 00000000000..68050f3f6d5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupRefVO.java @@ -0,0 +1,75 @@ +package org.zstack.header.image; + +import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vo.*; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +@Entity +@Table +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = ImageGroupVO.class, myField = "imageGroupUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = ImageVO.class, myField = "imageUuid", targetField = "uuid"), + } +) +public class ImageGroupRefVO implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + private String imageUuid; + + @Column + private String imageGroupUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getImageUuid() { + return imageUuid; + } + + public void setImageUuid(String imageUuid) { + this.imageUuid = imageUuid; + } + + public String getImageGroupUuid() { + return imageGroupUuid; + } + + public void setImageGroupUuid(String imageGroupUuid) { + this.imageGroupUuid = imageGroupUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupRefVO_.java b/header/src/main/java/org/zstack/header/image/ImageGroupRefVO_.java new file mode 100644 index 00000000000..ae8a6f5310a --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupRefVO_.java @@ -0,0 +1,11 @@ +package org.zstack.header.image; + +import javax.persistence.metamodel.SingularAttribute; +import java.sql.Timestamp; + +public class ImageGroupRefVO_ { + public static volatile SingularAttribute imageUuid; + public static volatile SingularAttribute imageGroupUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupVO.java b/header/src/main/java/org/zstack/header/image/ImageGroupVO.java new file mode 100644 index 00000000000..25deb06dc8d --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupVO.java @@ -0,0 +1,86 @@ +package org.zstack.header.image; + +import org.zstack.header.vo.BaseResource; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ResourceVO; + +import javax.persistence.Column; +import java.sql.Timestamp; +import javax.persistence.*; + +@Entity +@Table +@BaseResource +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = ImageGroupRefVO.class, myField = "uuid", targetField = "imageGroupUuid") + } +) +public class ImageGroupVO extends ResourceVO { + @Column + private Integer imageCount; + @Column + private String name; + @Column + @Enumerated(EnumType.STRING) + private ImageStatus status; + @Column + private String description; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public Integer getImageCount() { + return imageCount; + } + + public void setImageCount(Integer imageCount) { + this.imageCount = imageCount; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public ImageStatus getStatus() { + return status; + } + + public void setStatus(ImageStatus status) { + this.status = status; + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/image/ImageGroupVO_.java b/header/src/main/java/org/zstack/header/image/ImageGroupVO_.java new file mode 100644 index 00000000000..d7d6112ebe0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageGroupVO_.java @@ -0,0 +1,14 @@ +package org.zstack.header.image; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import java.sql.Timestamp; + +public class ImageGroupVO_ extends ResourceVO_ { + public static volatile SingularAttribute imageCount; + public static volatile SingularAttribute name; + public static volatile SingularAttribute description; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/image/ImageHelper.java b/header/src/main/java/org/zstack/header/image/ImageHelper.java new file mode 100644 index 00000000000..bf8dc66da77 --- /dev/null +++ b/header/src/main/java/org/zstack/header/image/ImageHelper.java @@ -0,0 +1,88 @@ +package org.zstack.header.image; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.util.Strings; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.URLBuilder; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Optional; + +public class ImageHelper { + private static final HashMap updateImageFactory = new HashMap<>(); + + static { + buildUpdateImageFactory(); + } + + static abstract class AbstractImageUpdate { + abstract void doUpdateImageIfVirtioIsNull(ImageInventory imageInventory); + } + + private static void buildUpdateImageFactory() { + AbstractImageUpdate imagePlatformIsWindows = new AbstractImageUpdate() { + @Override + public void doUpdateImageIfVirtioIsNull(ImageInventory inv) { + inv.setVirtio(false); + inv.setGuestOsType("Windows"); + } + }; + AbstractImageUpdate imagePlatformIsWindowsVirtio = new AbstractImageUpdate() { + @Override + public void doUpdateImageIfVirtioIsNull(ImageInventory inv) { + inv.setPlatform(ImagePlatform.Windows.toString()); + inv.setVirtio(true); + inv.setGuestOsType("Windows"); + } + }; + AbstractImageUpdate imagePlatformIsLinux = new AbstractImageUpdate() { + @Override + public void doUpdateImageIfVirtioIsNull(ImageInventory inv) { + inv.setVirtio(true); + inv.setGuestOsType("Linux"); + } + }; + AbstractImageUpdate imagePlatformIsOther = new AbstractImageUpdate() { + @Override + public void doUpdateImageIfVirtioIsNull(ImageInventory inv) { + inv.setVirtio(false); + inv.setGuestOsType("Other"); + } + }; + AbstractImageUpdate imagePlatformIsParavirtualization = new AbstractImageUpdate() { + @Override + public void doUpdateImageIfVirtioIsNull(ImageInventory inv) { + inv.setPlatform(ImagePlatform.Other.toString()); + inv.setVirtio(true); + inv.setGuestOsType("Other"); + } + }; + + updateImageFactory.put(ImagePlatform.Windows.toString(), imagePlatformIsWindows); + updateImageFactory.put(ImagePlatform.WindowsVirtio.toString(), imagePlatformIsWindowsVirtio); + updateImageFactory.put(ImagePlatform.Linux.toString(), imagePlatformIsLinux); + updateImageFactory.put(ImagePlatform.Other.toString(), imagePlatformIsOther); + updateImageFactory.put(ImagePlatform.Paravirtualization.toString(), imagePlatformIsParavirtualization); + } + + public static void updateImageIfVirtioIsNull(ImageInventory imageInventory) { + if (imageInventory.getVirtio() == null && imageInventory.getPlatform() != null) { + updateImageFactory.get(imageInventory.getPlatform()).doUpdateImageIfVirtioIsNull(imageInventory); + } + } + + public static abstract class ExportUrl { + static public String addNameToExportUrl(String exportUrl, String name) { + if (Strings.isEmpty(name)) { + return exportUrl; + } + + String image = StringUtils.substringAfterLast(exportUrl, "/"); + String urlName = URLBuilder.buildUrlComponent(name); + return exportUrl.replace(image, String.format("%s-%s", urlName, image)); + } + + public abstract String removeNameFromExportUrl(String exportUrl); + } +} diff --git a/header/src/main/java/org/zstack/header/image/ImageInventory.java b/header/src/main/java/org/zstack/header/image/ImageInventory.java index 456190bf7b3..5acb06c38e9 100755 --- a/header/src/main/java/org/zstack/header/image/ImageInventory.java +++ b/header/src/main/java/org/zstack/header/image/ImageInventory.java @@ -49,29 +49,50 @@ public class ImageInventory implements Serializable { private List backupStorageRefs; private List systemTags; + public ImageInventory() { + + } + public ImageInventory(ImageVO vo) { + this.uuid = vo.getUuid(); + this.name = vo.getName(); + this.description = vo.getDescription(); + if (vo.getState() != null) { + this.state = vo.getState().toString(); + } else { + this.state = null; + } + if (vo.getStatus() != null) { + this.status = vo.getStatus().toString(); + } else { + this.status = null; + } + this.size = vo.getSize(); + this.actualSize = vo.getActualSize(); + this.md5Sum = vo.getMd5Sum(); + this.url = vo.getUrl(); + if (vo.getMediaType() != null) { + this.mediaType = vo.getMediaType().toString(); + } else { + this.mediaType = null; + } + this.guestOsType = vo.getGuestOsType(); + this.type = vo.getType(); + if (vo.getPlatform() != null) { + this.platform = vo.getPlatform().toString(); + } else { + this.platform = null; + } + this.architecture = vo.getArchitecture(); + this.format = vo.getFormat(); + this.system = vo.isSystem(); + this.virtio = vo.getVirtio(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + this.backupStorageRefs = ImageBackupStorageRefInventory.valueOf(vo.getBackupStorageRefs()); + } + public static ImageInventory valueOf(ImageVO vo) { - ImageInventory inv = new ImageInventory(); - inv.setCreateDate(vo.getCreateDate()); - inv.setDescription(vo.getDescription()); - inv.setMediaType(vo.getMediaType().toString()); - inv.setFormat(vo.getFormat()); - inv.setGuestOsType(vo.getGuestOsType()); - inv.setMd5Sum(vo.getMd5Sum()); - inv.setName(vo.getName()); - inv.setSize(vo.getSize()); - inv.setActualSize(vo.getActualSize()); - inv.setStatus(vo.getStatus().toString()); - inv.setState(vo.getState().toString()); - inv.setUrl(vo.getUrl()); - inv.setPlatform(vo.getPlatform() == null ? null : vo.getPlatform().toString()); - inv.setArchitecture(vo.getArchitecture()); - inv.setUuid(vo.getUuid()); - inv.setType(vo.getType()); - inv.setSystem(vo.isSystem()); - inv.setLastOpDate(vo.getLastOpDate()); - inv.setBackupStorageRefs(ImageBackupStorageRefInventory.valueOf(vo.getBackupStorageRefs())); - inv.setVirtio(vo.getVirtio()); - return inv; + return new ImageInventory(vo); } public static ImageInventory valueOf(ImageEO vo) { @@ -79,7 +100,7 @@ public static ImageInventory valueOf(ImageEO vo) { inv.setCreateDate(vo.getCreateDate()); inv.setDescription(vo.getDescription()); inv.setMediaType(vo.getMediaType().toString()); - inv.setPlatform(vo.getPlatform().toString()); + inv.setPlatform(vo.getPlatform() == null ? null : vo.getPlatform().toString()); inv.setArchitecture(vo.getArchitecture()); inv.setFormat(vo.getFormat()); inv.setGuestOsType(vo.getGuestOsType()); diff --git a/header/src/main/java/org/zstack/header/image/ImageInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/image/ImageInventoryDoc_zh_cn.groovy index 3dbbd7ce469..3ac173c4f87 100644 --- a/header/src/main/java/org/zstack/header/image/ImageInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/image/ImageInventoryDoc_zh_cn.groovy @@ -1,11 +1,10 @@ package org.zstack.header.image -import java.lang.Long import java.lang.Long import java.lang.Boolean import java.sql.Timestamp -import java.sql.Timestamp import org.zstack.header.image.ImageBackupStorageRefInventory +import org.zstack.header.tag.SystemTagInventory doc { @@ -87,7 +86,13 @@ doc { name "platform" desc "镜像的系统平台" type "String" - since "0.6" + since "4.1.0" + } + field { + name "architecture" + desc "镜像CPU架构" + type "String" + since "4.1.0" } field { name "format" @@ -101,6 +106,12 @@ doc { type "Boolean" since "0.6" } + field { + name "virtio" + desc "是否支持virtio" + type "Boolean" + since "0.6" + } field { name "createDate" desc "创建时间" diff --git a/header/src/main/java/org/zstack/header/image/ImageStoreMetadataHelper.java b/header/src/main/java/org/zstack/header/image/ImageStoreMetadataHelper.java index 865b8219500..66481252985 100644 --- a/header/src/main/java/org/zstack/header/image/ImageStoreMetadataHelper.java +++ b/header/src/main/java/org/zstack/header/image/ImageStoreMetadataHelper.java @@ -40,6 +40,9 @@ public static ImageInventory buildImageInventoryFromMetadata(String metadata) { if (imageInventory.getArchitecture() == null) { imageInventory.setArchitecture(ImageArchitecture.defaultArch()); } + + ImageHelper.updateImageIfVirtioIsNull(imageInventory); + return imageInventory; } } diff --git a/header/src/main/java/org/zstack/header/image/ImageVO.java b/header/src/main/java/org/zstack/header/image/ImageVO.java index 84b67648159..944be03a291 100755 --- a/header/src/main/java/org/zstack/header/image/ImageVO.java +++ b/header/src/main/java/org/zstack/header/image/ImageVO.java @@ -17,6 +17,7 @@ @EntityGraph.Neighbour(type = ImageBackupStorageRefVO.class, myField = "uuid", targetField = "imageUuid") } ) +@Inheritance(strategy = InheritanceType.JOINED) public class ImageVO extends ImageAO implements OwnedByAccount, ToInventory { @OneToMany(fetch = FetchType.EAGER) @JoinColumn(name = "imageUuid", insertable = false, updatable = false) diff --git a/header/src/main/java/org/zstack/header/image/PackageInfo.java b/header/src/main/java/org/zstack/header/image/PackageInfo.java index 272353553ce..d251c2fb4f6 100755 --- a/header/src/main/java/org/zstack/header/image/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/image/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "镜像") +@PackageAPIInfo( + APICategoryName = "镜像", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/log/MaskSensitiveInfo.java b/header/src/main/java/org/zstack/header/log/MaskSensitiveInfo.java new file mode 100644 index 00000000000..5be09a9de91 --- /dev/null +++ b/header/src/main/java/org/zstack/header/log/MaskSensitiveInfo.java @@ -0,0 +1,16 @@ +package org.zstack.header.log; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * mask sensitive on REST even if CoreGlobalProperty.MASK_SENSITIVE_INFO is set to false + * see also {@link NoLogging} + */ + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface MaskSensitiveInfo { +} diff --git a/header/src/main/java/org/zstack/header/longjob/APICancelLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APICancelLongJobMsgDoc_zh_cn.groovy index d13e79b059a..9797e21028c 100644 --- a/header/src/main/java/org/zstack/header/longjob/APICancelLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APICancelLongJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.2.4" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "2.2.4" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.2.4" - } } } diff --git a/header/src/main/java/org/zstack/header/longjob/APICleanLongJobEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APICleanLongJobEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..c9fe676a240 --- /dev/null +++ b/header/src/main/java/org/zstack/header/longjob/APICleanLongJobEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.longjob + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "清理Long Job的结果" + + field { + name "success" + desc "" + type "boolean" + since "4.3.0" + } + ref { + name "error" + path "org.zstack.header.longjob.APICleanLongJobEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.3.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/longjob/APICleanLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APICleanLongJobMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..09c01f19e71 --- /dev/null +++ b/header/src/main/java/org/zstack/header/longjob/APICleanLongJobMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.longjob + +import org.zstack.header.longjob.APICleanLongJobEvent + +doc { + title "CleanLongJob" + + category "longjob" + + desc """清理Long Job""" + + rest { + request { + url "PUT /v1/longjobs/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICleanLongJobMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "cleanLongJob" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.3.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.3.0" + } + } + } + + response { + clz APICleanLongJobEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/longjob/APIDeleteLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APIDeleteLongJobMsgDoc_zh_cn.groovy index 0ae15602856..d90aee6ff82 100644 --- a/header/src/main/java/org/zstack/header/longjob/APIDeleteLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APIDeleteLongJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.2.4" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "2.2.4" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.2.4" - } } } diff --git a/header/src/main/java/org/zstack/header/longjob/APIQueryLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APIQueryLongJobMsgDoc_zh_cn.groovy index f88d972cbe3..8f4ad07b42c 100644 --- a/header/src/main/java/org/zstack/header/longjob/APIQueryLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APIQueryLongJobMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.longjob import org.zstack.header.longjob.APIQueryLongJobReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryLongJob" diff --git a/header/src/main/java/org/zstack/header/longjob/APIRerunLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APIRerunLongJobMsgDoc_zh_cn.groovy index 14f8c636ce6..9bbac8e3087 100644 --- a/header/src/main/java/org/zstack/header/longjob/APIRerunLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APIRerunLongJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.0.1" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.0.1" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.0.1" - } } } diff --git a/header/src/main/java/org/zstack/header/longjob/APIResumeLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APIResumeLongJobMsgDoc_zh_cn.groovy index ba60f6da381..c5d36bc3c32 100644 --- a/header/src/main/java/org/zstack/header/longjob/APIResumeLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APIResumeLongJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.9.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.9.0" - } } } diff --git a/header/src/main/java/org/zstack/header/longjob/APISubmitLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APISubmitLongJobMsgDoc_zh_cn.groovy index e0e2e3404fd..d8ddb1da1a7 100644 --- a/header/src/main/java/org/zstack/header/longjob/APISubmitLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APISubmitLongJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "2.2.4" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "2.2.4" - } column { name "jobName" @@ -49,7 +47,6 @@ doc { type "String" optional false since "2.2.4" - } column { name "jobData" @@ -59,7 +56,6 @@ doc { type "String" optional false since "2.2.4" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "2.2.4" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "2.2.4" - } column { name "userTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "2.2.4" - } column { name "targetResourceUuid" @@ -99,7 +92,15 @@ doc { type "String" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/longjob/APIUpdateLongJobMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/longjob/APIUpdateLongJobMsgDoc_zh_cn.groovy index 605c12bf841..8a1e8b21a95 100644 --- a/header/src/main/java/org/zstack/header/longjob/APIUpdateLongJobMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/longjob/APIUpdateLongJobMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.9" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.9" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.9" - } } } @@ -78,4 +73,4 @@ doc { clz APIUpdateLongJobEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/longjob/LongJobConstants.java b/header/src/main/java/org/zstack/header/longjob/LongJobConstants.java index 801d5740291..d73b886923d 100644 --- a/header/src/main/java/org/zstack/header/longjob/LongJobConstants.java +++ b/header/src/main/java/org/zstack/header/longjob/LongJobConstants.java @@ -7,6 +7,8 @@ public class LongJobConstants { public static final String SERVICE_ID = "longjob"; public static final String ACTION_CATEGORY = "longjob"; + public static final String NO_JOB_TO_CANCEL = "no matched job to cancel"; + public enum LongJobOperation { Start, Resume, diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsg.java b/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsg.java index b234ca862cc..ec569b5d0ba 100755 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsg.java +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsg.java @@ -15,7 +15,7 @@ method = HttpMethod.PUT, responseClass = APIGetCurrentTimeReply.class ) -public class APIGetCurrentTimeMsg extends APISyncCallMessage { +public class APIGetCurrentTimeMsg extends APISyncCallMessage implements APIManagementNodeMessage { public static APIGetCurrentTimeMsg __example__() { APIGetCurrentTimeMsg msg = new APIGetCurrentTimeMsg(); diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsgDoc_zh_cn.groovy index e712e25a541..89fc26e8549 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetCurrentTimeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsg.java b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsg.java index f56eca7063f..2a928050d64 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsg.java +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsg.java @@ -17,7 +17,7 @@ responseClass = APIGetManagementNodeArchReply.class ) @SuppressCredentialCheck -public class APIGetManagementNodeArchMsg extends APISyncCallMessage { +public class APIGetManagementNodeArchMsg extends APISyncCallMessage implements APIManagementNodeMessage { public static APIGetManagementNodeArchMsg __example__() { APIGetManagementNodeArchMsg msg = new APIGetManagementNodeArchMsg(); diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..71b63f28a98 --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.header.managementnode + +import org.zstack.header.managementnode.APIGetManagementNodeArchReply + +doc { + title "GetManagementNodeArch" + + category "managementNode" + + desc """获取管理节点系统架构""" + + rest { + request { + url "PUT /v1/management-nodes/actions" + + + + clz APIGetManagementNodeArchMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.1.2" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.1.2" + } + } + } + + response { + clz APIGetManagementNodeArchReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..3207ccbe073 --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeArchReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.managementnode + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取管理节点系统架构的返回" + + field { + name "architecture" + desc "" + type "String" + since "4.1.2" + } + field { + name "success" + desc "" + type "boolean" + since "4.1.2" + } + ref { + name "error" + path "org.zstack.header.managementnode.APIGetManagementNodeArchReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.1.2" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsg.java b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsg.java index 22179bb6e94..407d63b3de6 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsg.java +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsg.java @@ -16,7 +16,7 @@ responseClass = APIGetManagementNodeOSReply.class ) @SuppressCredentialCheck -public class APIGetManagementNodeOSMsg extends APISyncCallMessage { +public class APIGetManagementNodeOSMsg extends APISyncCallMessage implements APIManagementNodeMessage { public static APIGetManagementNodeOSMsg __example__() { APIGetManagementNodeOSMsg msg = new APIGetManagementNodeOSMsg(); diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..3b1439d19db --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.header.managementnode + +import org.zstack.header.managementnode.APIGetManagementNodeOSReply + +doc { + title "GetManagementNodeOS" + + category "managementNode" + + desc """获取管理节点系统""" + + rest { + request { + url "PUT /v1/management/actions" + + + + clz APIGetManagementNodeOSMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.1.2" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.1.2" + } + } + } + + response { + clz APIGetManagementNodeOSReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..dcb1b48cbb7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetManagementNodeOSReplyDoc_zh_cn.groovy @@ -0,0 +1,35 @@ +package org.zstack.header.managementnode + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取管理节点系统的返回" + + field { + name "name" + desc "资源名称" + type "String" + since "4.1.2" + } + field { + name "version" + desc "" + type "String" + since "4.1.2" + } + field { + name "success" + desc "" + type "boolean" + since "4.1.2" + } + ref { + name "error" + path "org.zstack.header.managementnode.APIGetManagementNodeOSReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.1.2" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsg.java b/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsg.java index 79dabf86811..8e93957d06f 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsg.java +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsg.java @@ -12,7 +12,7 @@ method = HttpMethod.GET, responseClass = APIGetPlatformTimeZoneReply.class ) -public class APIGetPlatformTimeZoneMsg extends APISyncCallMessage { +public class APIGetPlatformTimeZoneMsg extends APISyncCallMessage implements APIManagementNodeMessage { public static APIGetPlatformTimeZoneMsg __example__() { APIGetPlatformTimeZoneMsg msg = new APIGetPlatformTimeZoneMsg(); return msg; diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsgDoc_zh_cn.groovy index 2791b82ddeb..21174eaa76c 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetPlatformTimeZoneMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.1.0" - } } } diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsMsg.java b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsMsg.java new file mode 100644 index 00000000000..7ff8adb7870 --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsMsg.java @@ -0,0 +1,20 @@ +package org.zstack.header.managementnode; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.SuppressCredentialCheck; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +@SuppressCredentialCheck +@RestRequest( + path = "/management-nodes/actions", + isAction = true, + method = HttpMethod.PUT, + responseClass = APIGetSupportAPIsReply.class +) +public class APIGetSupportAPIsMsg extends APISyncCallMessage implements APIManagementNodeMessage { + + public static APIGetSupportAPIsMsg __example__() { + return new APIGetSupportAPIsMsg(); + } +} diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..5d0327387fb --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsMsgDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.header.managementnode + +import org.zstack.header.managementnode.APIGetSupportAPIsReply + +doc { + title "GetSupportAPIs" + + category "managementNode" + + desc """获取所有支持的API""" + + rest { + request { + url "PUT /v1/management-nodes/actions" + + + + clz APIGetSupportAPIsMsg.class + + desc """""" + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APIGetSupportAPIsReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsReply.java b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsReply.java new file mode 100644 index 00000000000..b69efb1f1a0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsReply.java @@ -0,0 +1,26 @@ +package org.zstack.header.managementnode; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.ArrayList; +import java.util.List; + +@RestResponse(fieldsTo = "all") +public class APIGetSupportAPIsReply extends APIReply { + private List supportApis; + + public List getSupportApis() { + return supportApis; + } + + public void setSupportApis(List supportApis) { + this.supportApis = supportApis; + } + + public static APIGetSupportAPIsReply __example__ () { + APIGetSupportAPIsReply reply = new APIGetSupportAPIsReply(); + reply.setSupportApis(new ArrayList<>()); + return reply; + } +} diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..7c09f445a7a --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetSupportAPIsReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.managementnode + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "支持的API列表" + + field { + name "supportApis" + desc "" + type "List" + since "4.5.0" + } + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.header.managementnode.APIGetSupportAPIsReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsg.java b/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsg.java index 2693b109954..f9a9f3209d6 100755 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsg.java +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsg.java @@ -15,7 +15,7 @@ responseClass = APIGetVersionReply.class, method = HttpMethod.PUT ) -public class APIGetVersionMsg extends APISyncCallMessage { +public class APIGetVersionMsg extends APISyncCallMessage implements APIManagementNodeMessage { public static APIGetVersionMsg __example__() { APIGetVersionMsg msg = new APIGetVersionMsg(); diff --git a/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsgDoc_zh_cn.groovy index 16de62ed587..f52e6a0dbbc 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/managementnode/APIGetVersionMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/managementnode/APIManagementNodeMessage.java b/header/src/main/java/org/zstack/header/managementnode/APIManagementNodeMessage.java new file mode 100644 index 00000000000..3f006f2eafe --- /dev/null +++ b/header/src/main/java/org/zstack/header/managementnode/APIManagementNodeMessage.java @@ -0,0 +1,4 @@ +package org.zstack.header.managementnode; + +public interface APIManagementNodeMessage { +} diff --git a/header/src/main/java/org/zstack/header/managementnode/APIQueryManagementNodeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/managementnode/APIQueryManagementNodeMsgDoc_zh_cn.groovy index ea8d728bce0..bf5154939ca 100644 --- a/header/src/main/java/org/zstack/header/managementnode/APIQueryManagementNodeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/managementnode/APIQueryManagementNodeMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.managementnode import org.zstack.header.managementnode.APIQueryManagementNodeReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryManagementNode" diff --git a/header/src/main/java/org/zstack/header/managementnode/PackageInfo.java b/header/src/main/java/org/zstack/header/managementnode/PackageInfo.java index 921cf8d176b..253df539163 100755 --- a/header/src/main/java/org/zstack/header/managementnode/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/managementnode/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "管理节点") +@PackageAPIInfo( + APICategoryName = "管理节点", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/message/APIBatchRequest.java b/header/src/main/java/org/zstack/header/message/APIBatchRequest.java new file mode 100644 index 00000000000..a8b1be45c1d --- /dev/null +++ b/header/src/main/java/org/zstack/header/message/APIBatchRequest.java @@ -0,0 +1,75 @@ +package org.zstack.header.message; + +import org.zstack.header.errorcode.ErrorCode; + +public interface APIBatchRequest { + class BatchOperationResult { + private T inventory; + private String uuid; + private boolean success; + private ErrorCode error; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public ErrorCode getError() { + return error; + } + + public void setError(ErrorCode error) { + this.error = error; + } + + public T getInventory() { + return inventory; + } + + public void setInventory(T inventory) { + this.inventory = inventory; + } + } + + class Result { + private int totalCount; + private int successCount; + + public Result() { + } + + public Result(int totalCount, int successCount) { + this.totalCount = totalCount; + this.successCount = successCount; + } + + public int getTotalCount() { + return totalCount; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + public int getSuccessCount() { + return successCount; + } + + public void setSuccessCount(int successCount) { + this.successCount = successCount; + } + } + + APIBatchRequest.Result collectResult(APIMessage message, APIEvent rsp); +} diff --git a/header/src/main/java/org/zstack/header/message/APIBatchRequest_BatchOperationResultDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/message/APIBatchRequest_BatchOperationResultDoc_zh_cn.groovy new file mode 100644 index 00000000000..93c2e57faa6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/message/APIBatchRequest_BatchOperationResultDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.message + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "批量操作接口的结果" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.2.1" + } + field { + name "success" + desc "" + type "boolean" + since "5.2.1" + } + ref { + name "error" + path "org.zstack.header.message.APIBatchRequest.BatchOperationResult.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.1" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/message/APIMessage.java b/header/src/main/java/org/zstack/header/message/APIMessage.java index bfd5c354ba9..bffc2cc75d0 100755 --- a/header/src/main/java/org/zstack/header/message/APIMessage.java +++ b/header/src/main/java/org/zstack/header/message/APIMessage.java @@ -28,6 +28,10 @@ public abstract class APIMessage extends NeedReplyMessage implements Configurabl @NoJsonSchema @APINoSee private SessionInventory session; + @APINoSee + private String clientIp; + @APINoSee + private String clientBrowser; public SessionInventory getSession() { return session; @@ -215,6 +219,20 @@ public void validate(Collection validators) throws IllegalA value = ((String) value).trim(); f.set(this, value); } + + if (value instanceof List && !at.noTrim()) { + List valueList = (List) value; + if (!valueList.isEmpty()) { + boolean allStrings = valueList.stream().allMatch(element -> element instanceof String); + if (allStrings) { + List valueNew = new ArrayList<>(); + for (Object element : valueList) { + valueNew.add(((String) element).trim()); + } + f.set(this, valueNew); + } + } + } for (ApiMessageValidator validator : validators) { validator.validate(this, f, value, at); @@ -232,4 +250,20 @@ private static void validateValue(String[] validValues, String value, String fie public String getOperator() { return null; } + + public String getClientIp() { + return clientIp; + } + + public void setClientIp(String clientIp) { + this.clientIp = clientIp; + } + + public String getClientBrowser() { + return clientBrowser; + } + + public void setClientBrowser(String clientBrowser) { + this.clientBrowser = clientBrowser; + } } diff --git a/header/src/main/java/org/zstack/header/message/APIParam.java b/header/src/main/java/org/zstack/header/message/APIParam.java index 322a9b382b0..be4c81fd275 100755 --- a/header/src/main/java/org/zstack/header/message/APIParam.java +++ b/header/src/main/java/org/zstack/header/message/APIParam.java @@ -28,6 +28,8 @@ long[] numberRange() default {}; + double[] floatNumberRange() default {}; + String[] numberRangeUnit() default {}; boolean checkAccount() default false; diff --git a/header/src/main/java/org/zstack/header/message/ApiMessageParamValidator.java b/header/src/main/java/org/zstack/header/message/ApiMessageParamValidator.java index ec0e2c4a4f6..e8ee995a2f1 100644 --- a/header/src/main/java/org/zstack/header/message/ApiMessageParamValidator.java +++ b/header/src/main/java/org/zstack/header/message/ApiMessageParamValidator.java @@ -106,6 +106,23 @@ private void validateNonNullValue(APIMessage msg, Field f, Object value, APIPara } } } + + if (at.floatNumberRange().length > 0 && TypeUtils.isTypeOf(value, Float.TYPE, Float.class, Double.TYPE, Double.class)) { + DebugUtils.Assert(at.floatNumberRange().length == 2, String.format("invalid field[%s], APIParam.floatNumberRange must have and only have 2 items", f.getName())); + double low = at.floatNumberRange()[0]; + double high = at.floatNumberRange()[1]; + double val = ((Number) value).doubleValue(); + if (val < low || val > high) { + if (at.numberRangeUnit().length > 0) { + DebugUtils.Assert(at.numberRangeUnit().length == 2, String.format("invalid field[%s], APIParam.floatNumberRangeUnit must have and only have 2 items", f.getName())); + String lowUnit = at.numberRangeUnit()[0]; + String highUnit = at.numberRangeUnit()[1]; + throw new InvalidApiMessageException("field[%s] must be in range of [%s %s, %s %s]", f.getName(), low, lowUnit, high, highUnit); + } else { + throw new InvalidApiMessageException("field[%s] must be in range of [%s, %s]", f.getName(), low, high); + } + } + } } private void validateValue(String[] validValues, String value, String fieldName, String msgName) { diff --git a/header/src/main/java/org/zstack/header/message/ConfigurableTimeoutMessage.java b/header/src/main/java/org/zstack/header/message/ConfigurableTimeoutMessage.java index 5d6f2acc513..e99aa4eb302 100644 --- a/header/src/main/java/org/zstack/header/message/ConfigurableTimeoutMessage.java +++ b/header/src/main/java/org/zstack/header/message/ConfigurableTimeoutMessage.java @@ -4,4 +4,8 @@ public interface ConfigurableTimeoutMessage { long getTimeout(); void setTimeout(long timeout); + + long getMessageDeadline(); + + void setMessageDeadline(long messageDeadline); } diff --git a/header/src/main/java/org/zstack/header/message/JsonSchemaBuilder.java b/header/src/main/java/org/zstack/header/message/JsonSchemaBuilder.java index 8a9f5b98d39..668a5572868 100755 --- a/header/src/main/java/org/zstack/header/message/JsonSchemaBuilder.java +++ b/header/src/main/java/org/zstack/header/message/JsonSchemaBuilder.java @@ -27,7 +27,7 @@ public JsonSchemaBuilder(Object object) { private boolean isSkip(Field f) { return f.isAnnotationPresent(NoJsonSchema.class) || Modifier.isStatic(f.getModifiers()) - || f.isAnnotationPresent(GsonTransient.class); + || f.isAnnotationPresent(GsonTransient.class) || Modifier.isTransient(f.getModifiers()); } private void build(Object o, Stack paths) throws IllegalAccessException { diff --git a/header/src/main/java/org/zstack/header/message/Message.java b/header/src/main/java/org/zstack/header/message/Message.java index 29d9e102c15..42f9fcc6f08 100755 --- a/header/src/main/java/org/zstack/header/message/Message.java +++ b/header/src/main/java/org/zstack/header/message/Message.java @@ -8,10 +8,11 @@ import org.zstack.utils.DebugUtils; import java.io.Serializable; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; + +import static org.zstack.utils.BeanUtils.getProperty; +import static org.zstack.utils.BeanUtils.setProperty; +import static org.zstack.utils.gson.JSONObjectUtil.rehashObject; public abstract class Message implements Serializable, AsyncBackup, Cloneable { @@ -153,4 +154,25 @@ public void setProps(MessageProperties props) { public void setCreatedTime(long createdTime) { this.createdTime = createdTime; } + + public void restoreFromSchema(Map raw) throws ClassNotFoundException { + Map schema = this.getHeaderEntry("schema"); + if (schema == null || schema.isEmpty()) { + return; + } + + List paths = new ArrayList<>(schema.keySet()); + + for (String p : paths) { + Object dst = getProperty(this, p); + String type = schema.get(p); + + if (dst.getClass().getName().equals(type)) { + continue; + } + + Class clz = Class.forName(type); + setProperty(this, p, rehashObject(getProperty(raw, p), clz)); + } + } } \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/message/MulitpleOverlayMsg.java b/header/src/main/java/org/zstack/header/message/MulitpleOverlayMsg.java new file mode 100644 index 00000000000..726dfdfcd50 --- /dev/null +++ b/header/src/main/java/org/zstack/header/message/MulitpleOverlayMsg.java @@ -0,0 +1,42 @@ +package org.zstack.header.message; + +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.log.NoLogging; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.util.ArrayList; +import java.util.List; + +public class MulitpleOverlayMsg extends NeedReplyMessage { + @NoLogging(behavior = NoLogging.Behavior.Auto) + protected List messages; + protected String messageClassName; + + public void setMessages(List msgs) { + if (messages == null) { + messages = new ArrayList<>(); + } + messages.addAll(msgs); + messageClassName = msgs.get(0).getClass().getName(); + } + + public List getMessages() { + try { + Class clazz = Class.forName(messageClassName); + List msgs = new ArrayList<>(); + messages.forEach(msg -> { + NeedReplyMessage nmsg = (NeedReplyMessage) JSONObjectUtil.rehashObject(msg, clazz); + if (nmsg instanceof OverlayMessage) { + OverlayMessage omsg = (OverlayMessage)nmsg; + omsg.setMessage(omsg.getMessage()); + msgs.add(omsg); + } else { + msgs.add(nmsg); + } + }); + return msgs; + } catch (ClassNotFoundException e) { + throw new CloudRuntimeException(e); + } + } +} diff --git a/header/src/main/java/org/zstack/header/message/MulitpleOverlayReply.java b/header/src/main/java/org/zstack/header/message/MulitpleOverlayReply.java new file mode 100644 index 00000000000..810bde2fbe6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/message/MulitpleOverlayReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.message; + +import java.util.ArrayList; +import java.util.List; + +public class MulitpleOverlayReply extends MessageReply { + private List innerReplies; + + public List getInnerReplies() { + return innerReplies; + } + + public void setInnerReplies(List replies) { + if (innerReplies == null) { + innerReplies = new ArrayList<>(); + } + innerReplies.addAll(replies); + } +} diff --git a/header/src/main/java/org/zstack/header/message/NeedReplyMessage.java b/header/src/main/java/org/zstack/header/message/NeedReplyMessage.java index 6b81e9511d8..20aa9427295 100755 --- a/header/src/main/java/org/zstack/header/message/NeedReplyMessage.java +++ b/header/src/main/java/org/zstack/header/message/NeedReplyMessage.java @@ -15,6 +15,8 @@ public abstract class NeedReplyMessage extends Message { */ @APINoSee protected long timeout = -1; + @APINoSee + protected long messageDeadline = -1; protected List systemTags; protected List userTags; @@ -30,6 +32,14 @@ public boolean hasSystemTag(Predicate isMatch) { return systemTags != null && systemTags.stream().anyMatch(isMatch); } + public boolean removeSystemTag(Predicate isMatch) { + if (systemTags == null) { + return false; + } + + return systemTags.removeIf(isMatch); + } + public void addSystemTag(String systemTag){ if (systemTags == null) { systemTags = new ArrayList<>(); @@ -76,4 +86,12 @@ public long getTimeout() { public void setTimeout(long timeout) { this.timeout = timeout; } + + public long getMessageDeadline() { + return messageDeadline; + } + + public void setMessageDeadline(long messageDeadline) { + this.messageDeadline = messageDeadline; + } } diff --git a/header/src/main/java/org/zstack/header/message/OverlayMessage.java b/header/src/main/java/org/zstack/header/message/OverlayMessage.java index 9e9e5176b8a..a58a0bcd703 100755 --- a/header/src/main/java/org/zstack/header/message/OverlayMessage.java +++ b/header/src/main/java/org/zstack/header/message/OverlayMessage.java @@ -1,5 +1,6 @@ package org.zstack.header.message; +import com.google.common.base.CaseFormat; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.log.NoLogging; import org.zstack.utils.gson.JSONObjectUtil; @@ -32,4 +33,11 @@ public NeedReplyMessage getMessage() { throw new CloudRuntimeException(e); } } + + public String getTaskName() { + String simpleName = messageClassName.substring( + messageClassName.lastIndexOf(".") + 1, messageClassName.lastIndexOf("Msg")); + simpleName = simpleName.replaceFirst("API", ""); + return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, simpleName); + } } diff --git a/header/src/main/java/org/zstack/header/network/IpAllocatedReason.java b/header/src/main/java/org/zstack/header/network/IpAllocatedReason.java new file mode 100644 index 00000000000..452eeeb14c3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/IpAllocatedReason.java @@ -0,0 +1,5 @@ +package org.zstack.header.network; + +public enum IpAllocatedReason { + Reserved, +} diff --git a/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsg.java b/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsg.java index d7d78e7b82a..34e8351e095 100755 --- a/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsg.java +++ b/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsg.java @@ -53,6 +53,9 @@ public class APIAttachL2NetworkToClusterMsg extends APIMessage implements L2Netw @APIParam(resourceType = ClusterVO.class) private String clusterUuid; + @APIParam(required = false, validValues = {"LinuxBridge"}) + private String l2ProviderType; + @Override public String getL2NetworkUuid() { return l2NetworkUuid; @@ -69,7 +72,15 @@ public void setClusterUuid(String clusterUuid) { public void setL2NetworkUuid(String l2NetworkUuid) { this.l2NetworkUuid = l2NetworkUuid; } - + + public String getL2ProviderType() { + return l2ProviderType; + } + + public void setL2ProviderType(String l2ProviderType) { + this.l2ProviderType = l2ProviderType; + } + public static APIAttachL2NetworkToClusterMsg __example__() { APIAttachL2NetworkToClusterMsg msg = new APIAttachL2NetworkToClusterMsg(); diff --git a/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsgDoc_zh_cn.groovy index 82bcb27afcb..5ee0dfde647 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIAttachL2NetworkToClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "clusterUuid" @@ -39,7 +38,16 @@ doc { type "String" optional false since "0.6" - + } + column { + name "l2ProviderType" + enclosedIn "" + desc "二层网络实现类型" + location "body" + type "String" + optional true + since "4.7.21" + values ("LinuxBridge") } column { name "systemTags" @@ -49,7 +57,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +66,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdEvent.java b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdEvent.java new file mode 100644 index 00000000000..25553cf3a00 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdEvent.java @@ -0,0 +1,43 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * Created by boce.wang on 03/20/2024. + */ +@RestResponse(allTo = "inventory") +public class APIChangeL2NetworkVlanIdEvent extends APIEvent { + private L2NetworkInventory inventory; + + public L2NetworkInventory getInventory() { + return inventory; + } + + public void setInventory(L2NetworkInventory inventory) { + this.inventory = inventory; + } + + public APIChangeL2NetworkVlanIdEvent() { + super(); + } + + public APIChangeL2NetworkVlanIdEvent(String apiId) { + super(apiId); + } + + public static APIChangeL2NetworkVlanIdEvent __example__() { + APIChangeL2NetworkVlanIdEvent event = new APIChangeL2NetworkVlanIdEvent(); + L2VlanNetworkInventory net = new L2VlanNetworkInventory(); + + net.setName("Test-Net"); + net.setVlan(10); + net.setDescription("Test"); + net.setZoneUuid(uuid()); + net.setPhysicalInterface("eth0"); + net.setType("L2VlanNetwork"); + + event.setInventory(net); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..3a1c4c3e9b4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.network.l2 + +import org.zstack.header.network.l2.L2NetworkInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "修改二层物理VlanId结果" + + ref { + name "inventory" + path "org.zstack.header.network.l2.APIChangeL2NetworkVlanIdEvent.inventory" + desc "null" + type "L2NetworkInventory" + since "5.1.0" + clz L2NetworkInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.header.network.l2.APIChangeL2NetworkVlanIdEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdMsg.java b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdMsg.java new file mode 100644 index 00000000000..f8fc572dc2e --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdMsg.java @@ -0,0 +1,68 @@ +package org.zstack.header.network.l2; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +/** + * Created by boce.wang on 03/20/2024. + */ +@RestRequest( + path = "/l2-networks/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIChangeL2NetworkVlanIdEvent.class, + isAction = true +) +@Action(category = L2NetworkConstant.ACTION_CATEGORY) +public class APIChangeL2NetworkVlanIdMsg extends APIMessage implements L2NetworkMessage, APIAuditor { + @APIParam(resourceType = L2NetworkVO.class, checkAccount = true, operationTarget = true) + private String uuid; + @APIParam(required = false) + private Integer vlan; + @APIParam(required = false) + private String type; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public Integer getVlan() { + return vlan; + } + + public void setVlan(Integer vlan) { + this.vlan = vlan; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String getL2NetworkUuid() { + return uuid; + } + public static APIChangeL2NetworkVlanIdMsg __example__() { + APIChangeL2NetworkVlanIdMsg msg = new APIChangeL2NetworkVlanIdMsg(); + msg.setUuid(uuid()); + msg.setVlan(1); + return msg; + } + + @Override + public APIAuditor.Result audit(APIMessage msg, APIEvent rsp) { + return new APIAuditor.Result(rsp.isSuccess() ? ((APIChangeL2NetworkVlanIdEvent)rsp).getInventory().getUuid() : "", L2NetworkVO.class); + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..a6580744c7a --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/APIChangeL2NetworkVlanIdMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.network.l2 + +import org.zstack.header.network.l2.APIChangeL2NetworkVlanIdEvent + +doc { + title "ChangeL2NetworkVlanId" + + category "network.l2" + + desc """修改二层物理VlanId""" + + rest { + request { + url "PUT /v1/l2-networks/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeL2NetworkVlanIdMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "changeL2NetworkVlanId" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.1.0" + } + column { + name "vlan" + enclosedIn "changeL2NetworkVlanId" + desc "" + location "body" + type "Integer" + optional true + since "5.1.0" + } + column { + name "type" + enclosedIn "changeL2NetworkVlanId" + desc "" + location "body" + type "String" + optional true + since "5.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIChangeL2NetworkVlanIdEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEvent.java b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEvent.java index 9a937fc641d..b7ac20076e9 100755 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEvent.java +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEvent.java @@ -46,7 +46,7 @@ public L2NetworkInventory getInventory() { public void setInventory(L2NetworkInventory inventory) { this.inventory = inventory; } - + public static APICreateL2NetworkEvent __example__() { APICreateL2NetworkEvent event = new APICreateL2NetworkEvent(); L2NetworkInventory inv = new L2NetworkInventory(); @@ -54,7 +54,7 @@ public static APICreateL2NetworkEvent __example__() { inv.setPhysicalInterface("eth0"); inv.setUuid(uuid()); inv.setZoneUuid(uuid()); - event.setInventory(new L2NetworkInventory()); + event.setInventory(inv); return event; } diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEventDoc_zh_cn.groovy index 8648b2ce72b..f90c172f1de 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEventDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkEventDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.header.network.l2.L2NetworkInventory doc { - title "在这里输入结构的名称" + title "二层网络清单" field { name "success" diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkMsg.java b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkMsg.java index 7e60b3da381..b91f322a823 100755 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NetworkMsg.java @@ -71,9 +71,15 @@ public abstract class APICreateL2NetworkMsg extends APICreateMessage implements /** * @desc vSwitch type */ - @APIParam(required = false, maxLength = 1024, validValues = {"LinuxBridge", "OvsDpdk"}) + @APIParam(required = false, maxLength = 1024, validValues = {"LinuxBridge", "OvsDpdk", "MacVlan", "OvnDpdk"}) private String vSwitchType = "LinuxBridge"; + @APIParam(required = false) + private Boolean isolated = Boolean.FALSE; + + @APIParam(required = false, emptyString = false) + private String pvlan; + public String getName() { return name; } @@ -122,6 +128,23 @@ public void setvSwitchType(String vSwitchType) { this.vSwitchType = vSwitchType; } + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public String getPvlan() { + return pvlan; + } + + public void setPvlan(String pvlan) { + this.pvlan = pvlan; + } + + @Override public Result audit(APIMessage msg, APIEvent rsp) { return new Result(rsp.isSuccess() ? ((APICreateL2NetworkEvent)rsp).getInventory().getUuid() : "", L2NetworkVO.class); } diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsg.java b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsg.java index 1da72c4ef51..6f42e0c3a3d 100755 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsg.java @@ -1,12 +1,19 @@ package org.zstack.header.network.l2; import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.OverriddenApiParam; +import org.zstack.header.message.OverriddenApiParams; import org.zstack.header.rest.RestRequest; import org.zstack.header.tag.TagResourceType; +import org.zstack.header.zone.ZoneVO; /** */ @TagResourceType(L2NetworkVO.class) +@OverriddenApiParams({ + @OverriddenApiParam(field = "physicalInterface", param = @APIParam(maxLength = 1024, required = false)) +}) @RestRequest( path = "/l2-networks/no-vlan", method = HttpMethod.POST, diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsgDoc_zh_cn.groovy index 889bd6546a2..295f5e6a298 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2NoVlanNetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "physicalInterface" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "type" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "vSwitchType" @@ -79,7 +74,7 @@ doc { type "String" optional true since "4.1.0" - + values ("LinuxBridge","OvsDpdk","MacVlan") } column { name "resourceUuid" @@ -89,7 +84,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -99,7 +93,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +102,33 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkEvent.java b/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkEvent.java index d90c4355fb3..734da0d4013 100755 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkEvent.java +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkEvent.java @@ -1,6 +1,5 @@ package org.zstack.header.network.l2; -import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; /** @@ -27,11 +26,6 @@ */ @RestResponse(allTo = "inventory") public class APICreateL2VlanNetworkEvent extends APICreateL2NetworkEvent { - /** - * @desc see :ref:`L2VlanNetworkInventory` - */ - private L2VlanNetworkInventory inventory; - public APICreateL2VlanNetworkEvent(String apiId) { super(apiId); } @@ -40,14 +34,6 @@ public APICreateL2VlanNetworkEvent() { super(null); } - public L2VlanNetworkInventory getInventory() { - return inventory; - } - - public void setInventory(L2VlanNetworkInventory inventory) { - this.inventory = inventory; - } - public static APICreateL2VlanNetworkEvent __example__() { APICreateL2VlanNetworkEvent event = new APICreateL2VlanNetworkEvent(); L2VlanNetworkInventory net = new L2VlanNetworkInventory(); diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsg.java b/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsg.java index b3602e6b19e..58ce39044f5 100755 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsg.java @@ -2,8 +2,11 @@ import org.springframework.http.HttpMethod; import org.zstack.header.message.APIParam; +import org.zstack.header.message.OverriddenApiParam; +import org.zstack.header.message.OverriddenApiParams; import org.zstack.header.rest.RestRequest; import org.zstack.header.tag.TagResourceType; +import org.zstack.header.zone.ZoneVO; /** * @api create a l2VlanNetwork @@ -42,6 +45,9 @@ * @since 0.1.0 */ @TagResourceType(L2NetworkVO.class) +@OverriddenApiParams({ + @OverriddenApiParam(field = "physicalInterface", param = @APIParam(maxLength = 1024, required = false)) +}) @RestRequest( path = "/l2-networks/vlan", method = HttpMethod.POST, @@ -67,7 +73,7 @@ public void setVlan(int vlan) { public String getType() { return L2NetworkConstant.L2_VLAN_NETWORK_TYPE; } - + public static APICreateL2VlanNetworkMsg __example__() { APICreateL2VlanNetworkMsg msg = new APICreateL2VlanNetworkMsg(); @@ -79,5 +85,4 @@ public static APICreateL2VlanNetworkMsg __example__() { return msg; } - } diff --git a/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsgDoc_zh_cn.groovy index 17b45e6d479..4b25e29dd22 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APICreateL2VlanNetworkMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.header.network.l2 import org.zstack.header.network.l2.APICreateL2VlanNetworkEvent doc { - title "创建Vlan二层网络(CreateL2VlanNetwork)" + title "创建二层Vlan网络(CreateL2VlanNetwork)" category "二层网络" - desc """创建Vlan二层网络""" + desc """创建二层Vlan网络""" rest { request { @@ -29,7 +29,6 @@ doc { type "Integer" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "physicalInterface" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "type" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "vSwitchType" @@ -89,7 +83,7 @@ doc { type "String" optional true since "4.1.0" - + values ("LinuxBridge","OvsDpdk","MacVlan") } column { name "resourceUuid" @@ -99,7 +93,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +102,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +111,33 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIDeleteL2NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIDeleteL2NetworkMsgDoc_zh_cn.groovy index f8876f7babb..779ad56e492 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIDeleteL2NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIDeleteL2NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIDetachL2NetworkFromClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIDetachL2NetworkFromClusterMsgDoc_zh_cn.groovy index 6f68073bc25..700a69da1e0 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIDetachL2NetworkFromClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIDetachL2NetworkFromClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "clusterUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateClustersForAttachingL2NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateClustersForAttachingL2NetworkMsgDoc_zh_cn.groovy index 1250e4080cf..f008b113ff9 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateClustersForAttachingL2NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateClustersForAttachingL2NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0.0" - } column { name "clusterTypes" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.0.0" - } column { name "limit" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "4.0.0" - } column { name "start" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "4.0.0" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.0.0" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "4.0.0" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateL2NetworksForAttachingClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateL2NetworksForAttachingClusterMsgDoc_zh_cn.groovy index 6a8b1af3490..cacea0c7d26 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateL2NetworksForAttachingClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIGetCandidateL2NetworksForAttachingClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0.0" - } column { name "limit" @@ -39,7 +38,6 @@ doc { type "Integer" optional true since "4.0.0" - } column { name "start" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "4.0.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.0.0" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIGetL2NetworkTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIGetL2NetworkTypesMsgDoc_zh_cn.groovy index f5ebb0e68e9..f4649fdb87f 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIGetL2NetworkTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIGetL2NetworkTypesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesMsgDoc_zh_cn.groovy index 64347204f8f..2af3e3d0e74 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesMsgDoc_zh_cn.groovy @@ -11,37 +11,35 @@ doc { rest { request { - url "GET /v1/l2-networks/vSwitchTypes" + url "GET /v1/l2-networks/vSwitchTypes" - header (Authorization: 'OAuth the-session-uuid') + header (Authorization: 'OAuth the-session-uuid') clz APIGetVSwitchTypesMsg.class desc """""" - - params { - - column { - name "systemTags" - enclosedIn "" - desc "系统标签" - location "query" - type "List" - optional true - since "4.1.0" - - } - column { - name "userTags" - enclosedIn "" - desc "用户标签" - location "query" - type "List" - optional true - since "4.1.0" - - } - } + + params { + + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.1.0" + } + } } response { diff --git a/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesReplyDoc_zh_cn.groovy index b44dcb1bcb0..189588b9b95 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesReplyDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIGetVSwitchTypesReplyDoc_zh_cn.groovy @@ -4,7 +4,7 @@ import org.zstack.header.errorcode.ErrorCode doc { - title "虚拟交换机清单" + title "虚拟交换机类型清单" ref { name "error" diff --git a/header/src/main/java/org/zstack/header/network/l2/APIQueryL2NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIQueryL2NetworkMsgDoc_zh_cn.groovy index 2e986c53e58..0969becb962 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIQueryL2NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIQueryL2NetworkMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.l2 import org.zstack.header.network.l2.APIQueryL2NetworkReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询二层网络(QueryL2Network)" diff --git a/header/src/main/java/org/zstack/header/network/l2/APIQueryL2VlanNetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIQueryL2VlanNetworkMsgDoc_zh_cn.groovy index 4cbf3188f6d..a57f88b0f3d 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIQueryL2VlanNetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIQueryL2VlanNetworkMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.l2 import org.zstack.header.network.l2.APIQueryL2VlanNetworkReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询二层Vlan网络(QueryL2VlanNetwork)" diff --git a/header/src/main/java/org/zstack/header/network/l2/APIUpdateL2NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/APIUpdateL2NetworkMsgDoc_zh_cn.groovy index 51ba26dc831..0d0e4c8e80a 100644 --- a/header/src/main/java/org/zstack/header/network/l2/APIUpdateL2NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/APIUpdateL2NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l2/AfterL2NetworkRealizationExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l2/AfterL2NetworkRealizationExtensionPoint.java new file mode 100644 index 00000000000..2fa748d39c6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/AfterL2NetworkRealizationExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.core.Completion; + +/** + * Created by boce.wang on 11/10/2023. + */ +public interface AfterL2NetworkRealizationExtensionPoint { + void afterRealize(L2NetworkInventory l2Network, String hostUuid, Completion completion); + +} diff --git a/header/src/main/java/org/zstack/header/network/l2/AttachL2NetworkToClusterMsg.java b/header/src/main/java/org/zstack/header/network/l2/AttachL2NetworkToClusterMsg.java new file mode 100644 index 00000000000..af5a9290e55 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/AttachL2NetworkToClusterMsg.java @@ -0,0 +1,35 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.NeedReplyMessage; + +/** + */ +public class AttachL2NetworkToClusterMsg extends NeedReplyMessage implements L2NetworkMessage { + private String l2NetworkUuid; + private String clusterUuid; + private String l2ProviderType; + + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public String getL2ProviderType() { + return l2ProviderType; + } + + public void setL2ProviderType(String l2ProviderType) { + this.l2ProviderType = l2ProviderType; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/AttachL2NetworkToClusterReply.java b/header/src/main/java/org/zstack/header/network/l2/AttachL2NetworkToClusterReply.java new file mode 100644 index 00000000000..f3059984d5c --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/AttachL2NetworkToClusterReply.java @@ -0,0 +1,8 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.MessageReply; + +/** + */ +public class AttachL2NetworkToClusterReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO.java index 528daf90845..fd6fa59cd42 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO.java @@ -27,6 +27,16 @@ public class L2NetworkAO extends ResourceVO { @Column private String vSwitchType; + @Column + private Integer virtualNetworkId; + + + @Column + private Boolean isolated; + + @Column + private String pvlan; + @Column @ForeignKey(parentEntityClass = ZoneEO.class, onDeleteAction = ReferenceOption.RESTRICT) private String zoneUuid; @@ -96,6 +106,30 @@ public void setvSwitchType(String vSwitchType) { this.vSwitchType = vSwitchType; } + public Integer getVirtualNetworkId() { + return virtualNetworkId; + } + + public void setVirtualNetworkId(Integer virtualNetworkId){ + this.virtualNetworkId = virtualNetworkId; + } + + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public String getPvlan() { + return pvlan; + } + + public void setPvlan(String pvlan) { + this.pvlan = pvlan; + } + public Timestamp getCreateDate() { return createDate; } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO_.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO_.java index f4847fa95b7..1d6e4d237d3 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO_.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkAO_.java @@ -11,9 +11,12 @@ public class L2NetworkAO_ extends ResourceVO_ { public static volatile SingularAttribute name; public static volatile SingularAttribute type; public static volatile SingularAttribute vSwitchType; + public static volatile SingularAttribute virtualNetworkId; public static volatile SingularAttribute description; public static volatile SingularAttribute zoneUuid; public static volatile SingularAttribute physicalInterface; + public static volatile SingularAttribute isolated; + public static volatile SingularAttribute pvlan; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkAttachStatus.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkAttachStatus.java new file mode 100644 index 00000000000..85549ea3f20 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkAttachStatus.java @@ -0,0 +1,8 @@ +package org.zstack.header.network.l2; + +public enum L2NetworkAttachStatus { + None, + CheckFailed, + AttachFailed, + Attached, +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkClusterRefInventory.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkClusterRefInventory.java index fe28f3d9b09..5ca49b829e2 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkClusterRefInventory.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkClusterRefInventory.java @@ -20,6 +20,9 @@ public class L2NetworkClusterRefInventory { private String clusterUuid; private String l2NetworkUuid; + + private String l2ProviderType; + private Timestamp createDate; private Timestamp lastOpDate; @@ -28,6 +31,7 @@ public static L2NetworkClusterRefInventory valueOf(L2NetworkClusterRefVO vo) { L2NetworkClusterRefInventory inv = new L2NetworkClusterRefInventory(); inv.setClusterUuid(vo.getClusterUuid()); inv.setL2NetworkUuid(vo.getL2NetworkUuid()); + inv.setL2ProviderType(vo.getL2ProviderType()); inv.setCreateDate(vo.getCreateDate()); inv.setLastOpDate(vo.getLastOpDate()); return inv; @@ -41,6 +45,14 @@ public static List valueOf(Collection id; public static volatile SingularAttribute clusterUuid; public static volatile SingularAttribute l2NetworkUuid; + public static volatile SingularAttribute l2ProviderType; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkConstant.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkConstant.java index 7d749cd1612..e72b0b91396 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkConstant.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkConstant.java @@ -8,22 +8,56 @@ public interface L2NetworkConstant { public static final String SERVICE_ID = "network.l2"; public static final String L2_VLAN_NETWORK_FACTORY_SERVICE_ID = "network.l2.vlan"; + public static final String L2_PRIVATE_VLAN_SERVICE_ID = "network.l2.pvlan"; + public static final String ACTION_CATEGORY = "l2Network"; @PythonClass public static final String L2_NO_VLAN_NETWORK_TYPE = "L2NoVlanNetwork"; @PythonClass public static final String L2_VLAN_NETWORK_TYPE = "L2VlanNetwork"; + @PythonClass + public static final String HARDWARE_VXLAN_NETWORK_POOL_TYPE = "HardwareVxlanNetworkPool"; + @PythonClass + public static final String HARDWARE_VXLAN_NETWORK_TYPE = "HardwareVxlanNetwork"; + public static final String L2_TF_NETWORK_TYPE = "TfL2Network"; + @PythonClass + public static final String VXLAN_NETWORK_TYPE = "VxlanNetwork"; + @PythonClass + public static final String VXLAN_NETWORK_POOL_TYPE = "VxlanNetworkPool"; @PythonClass public static final String VSWITCH_TYPE_LINUX_BRIDGE = "LinuxBridge"; @PythonClass public static final String VSWITCH_TYPE_OVS_DPDK = "OvsDpdk"; @PythonClass + public static final String VSWITCH_TYPE_MACVLAN = "MacVlan"; + @PythonClass public static final String VSWITCH_TYPE_OVS_KERNEL = "OvsKernel"; + @PythonClass + public static final String VSWITCH_TYPE_OVN_DPDK = "OvnDpdk"; + public static final String OVN_DPDK_VNIC_SRC_PATH = "/var/run/openvswitch/"; + public static final String DETACH_L2NETWORK_CODE = "l2Network.detach"; // https://elixir.bootlin.com/linux/v5.6/source/include/uapi/linux/if.h#L33 public static final int LINUX_IF_NAME_MAX_SIZE = 15; + + public static final int VIRTUAL_NETWORK_ID_DEFAULT_VALUE = 0; + + public static final String KVM_HYPERVISOR_TYPE = "KVM"; + + public static final String BONDING_MODE_LACP = "802.3ad"; + public static final String BONDING_MODE_AB = "active-backup"; + public static final String BONDING_MODE_SLB = "balance-slb"; + public static final String BONDING_MODE_TCP = "balance-tcp"; + + public static final String LACP_MODE_OFF = "off"; + public static final String LACP_MODE_ACTIVE = "active"; + public static final String LACP_MODE_PASSIVE = "passive"; + + public static final Integer VLAN_ID_MAX = 4095; + public static final Integer VXLAN_ID_MAX = 16777215; + public static final Integer MAX_PARALLEL_HOST_MSG = 10; } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkCreateExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkCreateExtensionPoint.java index 84fd74ceedc..d50559128d9 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkCreateExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkCreateExtensionPoint.java @@ -1,9 +1,11 @@ package org.zstack.header.network.l2; +import org.zstack.header.core.Completion; import org.zstack.header.network.NetworkException; public interface L2NetworkCreateExtensionPoint { void beforeCreateL2Network(APICreateL2NetworkMsg msg) throws NetworkException; + default void postCreateL2Network(L2NetworkInventory l2Network, APICreateL2NetworkMsg msg, Completion completion) {completion.success();} void afterCreateL2Network(L2NetworkInventory l2Network); } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkDataDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/L2NetworkDataDoc_zh_cn.groovy new file mode 100644 index 00000000000..b2a1214b032 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkDataDoc_zh_cn.groovy @@ -0,0 +1,73 @@ +package org.zstack.header.network.l2 + +doc { + + title "二层网络结构" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.0.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "4.0.0" + } + field { + name "poolUuid" + desc "网络池UUID" + type "String" + since "4.0.0" + } + field { + name "zoneUuid" + desc "区域UUID" + type "String" + since "4.0.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "4.0.0" + } + field { + name "physicalInterface" + desc "网卡名称" + type "String" + since "4.0.0" + } + field { + name "type" + desc "二层网络类型" + type "String" + since "4.0.0" + } + field { + name "vni" + desc "" + type "String" + since "4.0.0" + } + field { + name "vlan" + desc "" + type "int" + since "4.0.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.0.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.0.0" + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkDateDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/L2NetworkDateDoc_zh_cn.groovy deleted file mode 100644 index e802c717665..00000000000 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkDateDoc_zh_cn.groovy +++ /dev/null @@ -1,76 +0,0 @@ -package org.zstack.header.network.l2 - -import java.sql.Timestamp -import java.sql.Timestamp - -doc { - - title "二层网络结构" - - field { - name "uuid" - desc "资源的UUID,唯一标示该资源" - type "String" - since "4.0.0" - } - field { - name "name" - desc "资源名称" - type "String" - since "4.0.0" - } - field { - name "poolUuid" - desc "网络池UUID" - type "String" - since "4.0.0" - } - field { - name "zoneUuid" - desc "区域UUID" - type "String" - since "4.0.0" - } - field { - name "description" - desc "资源的详细描述" - type "String" - since "4.0.0" - } - field { - name "physicalInterface" - desc "网卡名称" - type "String" - since "4.0.0" - } - field { - name "type" - desc "二层网络类型" - type "String" - since "4.0.0" - } - field { - name "vni" - desc "" - type "String" - since "4.0.0" - } - field { - name "vlan" - desc "" - type "int" - since "4.0.0" - } - field { - name "createDate" - desc "创建时间" - type "Timestamp" - since "4.0.0" - } - field { - name "lastOpDate" - desc "最后一次修改时间" - type "Timestamp" - since "4.0.0" - } -} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkDeleteExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkDeleteExtensionPoint.java index a780c4e9910..3e46f74b1e7 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkDeleteExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkDeleteExtensionPoint.java @@ -1,9 +1,14 @@ package org.zstack.header.network.l2; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; + public interface L2NetworkDeleteExtensionPoint { void preDeleteL2Network(L2NetworkInventory inventory) throws L2NetworkException; void beforeDeleteL2Network(L2NetworkInventory inventory); + default void deleteL2Network(L2NetworkInventory inv, NoErrorCompletion completion) {completion.done();} + void afterDeleteL2Network(L2NetworkInventory inventory); } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkFactory.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkFactory.java index c3f4eaf5d8b..c013389967a 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkFactory.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkFactory.java @@ -5,7 +5,7 @@ public interface L2NetworkFactory { L2NetworkType getType(); - void createL2Network(L2NetworkVO vo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion); + void createL2Network(L2NetworkVO vo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion); L2Network getL2Network(L2NetworkVO vo); } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefInventory.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefInventory.java new file mode 100644 index 00000000000..dcd5301ac28 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefInventory.java @@ -0,0 +1,98 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.host.HostInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = L2NetworkHostRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "host", inventoryClass = HostInventory.class, + foreignKey = "hostUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "l2Network", inventoryClass = L2NetworkInventory.class, + foreignKey = "l2NetworkUuid", expandedInventoryKey = "uuid"), +}) +public class L2NetworkHostRefInventory { + private String hostUuid; + private String l2NetworkUuid; + + private String l2ProviderType; + + private L2NetworkAttachStatus attachStatus; + + private Timestamp createDate; + private Timestamp lastOpDate; + + + public static L2NetworkHostRefInventory valueOf(L2NetworkHostRefVO vo) { + L2NetworkHostRefInventory inv = new L2NetworkHostRefInventory(); + inv.setHostUuid(vo.getHostUuid()); + inv.setL2NetworkUuid(vo.getL2NetworkUuid()); + inv.setL2ProviderType(vo.getL2ProviderType()); + inv.setAttachStatus(vo.getAttachStatus()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList(); + for (L2NetworkHostRefVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getL2ProviderType() { + return l2ProviderType; + } + + public void setL2ProviderType(String l2ProviderType) { + this.l2ProviderType = l2ProviderType; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public L2NetworkAttachStatus getAttachStatus() { + return attachStatus; + } + + public void setAttachStatus(L2NetworkAttachStatus attachStatus) { + this.attachStatus = attachStatus; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefVO.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefVO.java new file mode 100644 index 00000000000..3d66cb4afaa --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefVO.java @@ -0,0 +1,120 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.cluster.ClusterEO; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.host.HostEO; +import org.zstack.header.host.HostVO; +import org.zstack.header.search.SqlTrigger; +import org.zstack.header.search.TriggerIndex; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ForeignKey.ReferenceOption; +import org.zstack.header.vo.SoftDeletionCascade; +import org.zstack.header.vo.SoftDeletionCascades; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@TriggerIndex +@SqlTrigger(foreignVOClass = L2NetworkVO.class, foreignVOJoinColumn = "l2NetworkUuid") +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = L2NetworkVO.class, joinColumn = "l2NetworkUuid"), + @SoftDeletionCascade(parent = HostVO.class, joinColumn = "hostUuid") +}) +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = L2NetworkVO.class, myField = "l2NetworkUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = HostVO.class, myField = "hostUuid", targetField = "uuid"), + } +) +public class L2NetworkHostRefVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ReferenceOption.CASCADE) + private String hostUuid; + + @Column + @ForeignKey(parentEntityClass = L2NetworkEO.class, onDeleteAction = ReferenceOption.CASCADE) + private String l2NetworkUuid; + + @Column + private String l2ProviderType; + + @Column + @Enumerated + private L2NetworkAttachStatus attachStatus; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public String getL2ProviderType() { + return l2ProviderType; + } + + public void setL2ProviderType(String l2ProviderType) { + this.l2ProviderType = l2ProviderType; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public L2NetworkAttachStatus getAttachStatus() { + return attachStatus; + } + + public void setAttachStatus(L2NetworkAttachStatus attachStatus) { + this.attachStatus = attachStatus; + } + + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefVO_.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefVO_.java new file mode 100644 index 00000000000..c979a475861 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkHostRefVO_.java @@ -0,0 +1,16 @@ +package org.zstack.header.network.l2; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(L2NetworkHostRefVO.class) +public class L2NetworkHostRefVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute hostUuid; + public static volatile SingularAttribute l2NetworkUuid; + public static volatile SingularAttribute l2ProviderType; + public static volatile SingularAttribute attachStatus; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventory.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventory.java index 66190777a2a..d85d6fca496 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventory.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventory.java @@ -76,6 +76,18 @@ public class L2NetworkInventory implements Serializable { * @desc l2Network vSwitch Type */ private String vSwitchType; + /** + * @desc virtual id for vlan/vni + */ + private Integer virtualNetworkId; + /** + * @desc l2Network isolated flag + */ + private Boolean isolated; + /** + * @desc l2Network private vlan id + */ + private String pvlan; /** * @desc the time this resource gets created */ @@ -99,9 +111,12 @@ protected L2NetworkInventory(L2NetworkVO vo) { this.setZoneUuid(vo.getZoneUuid()); this.setType(vo.getType()); this.setvSwitchType(vo.getvSwitchType()); + this.setVirtualNetworkId(vo.getVirtualNetworkId()); this.setDescription(vo.getDescription()); this.setName(vo.getName()); this.setPhysicalInterface(vo.getPhysicalInterface()); + this.setIsolated(vo.getIsolated()); + this.setPvlan(vo.getPvlan()); this.setCreateDate(vo.getCreateDate()); this.setLastOpDate(vo.getLastOpDate()); this.attachedClusterUuids = new ArrayList(vo.getAttachedClusterRefs().size()); @@ -178,6 +193,14 @@ public void setvSwitchType(String vSwitchType) { this.vSwitchType = vSwitchType; } + public Integer getVirtualNetworkId() { + return virtualNetworkId; + } + + public void setVirtualNetworkId(Integer virtualNetworkId) { + this.virtualNetworkId = virtualNetworkId; + } + public Timestamp getCreateDate() { return createDate; } @@ -201,4 +224,20 @@ public List getAttachedClusterUuids() { public void setAttachedClusterUuids(List attachedClusterUuids) { this.attachedClusterUuids = attachedClusterUuids; } + + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public String getPvlan() { + return pvlan; + } + + public void setPvlan(String pvlan) { + this.pvlan = pvlan; + } } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventoryDoc_zh_cn.groovy index 78ed55d7c9b..5ee174aa8e8 100644 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkInventoryDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "二层网络清单" field { name "uuid" @@ -33,13 +33,13 @@ doc { } field { name "physicalInterface" - desc "" + desc "物理网卡" type "String" since "0.6" } field { name "type" - desc "" + desc "二层网络类型" type "String" since "0.6" } @@ -57,7 +57,7 @@ doc { } field { name "attachedClusterUuids" - desc "" + desc "挂载集群的UUID列表" type "List" since "0.6" } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedAttachOnHostMsg.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedAttachOnHostMsg.java new file mode 100644 index 00000000000..7b8219fb4d9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedAttachOnHostMsg.java @@ -0,0 +1,34 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; +import java.util.Map; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedAttachOnHostMsg extends NeedReplyMessage implements HostMessage { + private String hostUuid; + + private Map> isolatedL2NetworkMacMap; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public Map> getIsolatedL2NetworkMacMap() { + return isolatedL2NetworkMacMap; + } + + + public void setIsolatedL2NetworkMacMap(Map> isolatedL2NetworkMacMap) { + this.isolatedL2NetworkMacMap = isolatedL2NetworkMacMap; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedAttachOnHostReply.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedAttachOnHostReply.java new file mode 100644 index 00000000000..4232ad59f5b --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedAttachOnHostReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.MessageReply; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedAttachOnHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedDetachOnHostMsg.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedDetachOnHostMsg.java new file mode 100644 index 00000000000..bde30c4fdc2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedDetachOnHostMsg.java @@ -0,0 +1,34 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; +import java.util.Map; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedDetachOnHostMsg extends NeedReplyMessage implements HostMessage { + private String hostUuid; + + private Map> isolatedL2NetworkMacMap; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public Map> getIsolatedL2NetworkMacMap() { + return isolatedL2NetworkMacMap; + } + + + public void setIsolatedL2NetworkMacMap(Map> isolatedL2NetworkMacMap) { + this.isolatedL2NetworkMacMap = isolatedL2NetworkMacMap; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedDetachOnHostReply.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedDetachOnHostReply.java new file mode 100644 index 00000000000..0a01d76375e --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedDetachOnHostReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.MessageReply; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedDetachOnHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedMigrateOnHostMsg.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedMigrateOnHostMsg.java new file mode 100644 index 00000000000..6e4125e3176 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedMigrateOnHostMsg.java @@ -0,0 +1,44 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; +import java.util.Map; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedMigrateOnHostMsg extends NeedReplyMessage implements HostMessage { + private String hostUuid; + + private String migrateHostUuid; + + private Map> isolatedL2NetworkMacMap; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getMigrateHostUuid() { + return migrateHostUuid; + } + + public void setMigrateHostUuid(String migrateHostUuid) { + this.migrateHostUuid = migrateHostUuid; + } + + public Map> getIsolatedL2NetworkMacMap() { + return isolatedL2NetworkMacMap; + } + + + public void setIsolatedL2NetworkMacMap(Map> isolatedL2NetworkMacMap) { + this.isolatedL2NetworkMacMap = isolatedL2NetworkMacMap; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedMigrateOnHostReply.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedMigrateOnHostReply.java new file mode 100644 index 00000000000..887ed2b7f0c --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedMigrateOnHostReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.MessageReply; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedMigrateOnHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedSyncOnHostMsg.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedSyncOnHostMsg.java new file mode 100644 index 00000000000..3f1f130e61a --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedSyncOnHostMsg.java @@ -0,0 +1,33 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; +import java.util.Map; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedSyncOnHostMsg extends NeedReplyMessage implements HostMessage { + private String hostUuid; + + private Map> isolatedL2NetworkMacMap; + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public Map> getIsolatedL2NetworkMacMap() { + return isolatedL2NetworkMacMap; + } + + public void setIsolatedL2NetworkMacMap(Map> isolatedL2NetworkMacMap) { + this.isolatedL2NetworkMacMap = isolatedL2NetworkMacMap; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedSyncOnHostReply.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedSyncOnHostReply.java new file mode 100644 index 00000000000..e40eb5b1b01 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkIsolatedSyncOnHostReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.message.MessageReply; + +/** + * Created by boce.wang on 11/10/2023. + */ +public class L2NetworkIsolatedSyncOnHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkRealizationExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkRealizationExtensionPoint.java index 9e5f69b09b2..c39539977cb 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkRealizationExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkRealizationExtensionPoint.java @@ -16,5 +16,15 @@ default void realize(L2NetworkInventory l2Network, String hostUuid, boolean noSt HypervisorType getSupportedHypervisorType(); + VSwitchType getSupportedVSwitchType(); + + default L2ProviderType getL2ProviderType() { + return null; + }; + void delete(L2NetworkInventory l2Network, String hostUuid, Completion completion); + default void update(L2NetworkInventory oldL2Network, L2NetworkInventory newl2Network, String hostUuid, Completion completion) { + completion.success(); + } + } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkUpdateExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkUpdateExtensionPoint.java new file mode 100644 index 00000000000..1336bea1907 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkUpdateExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.header.network.l2; + +/** + * Created by boce.wang on 03/25/2024. + */ +public interface L2NetworkUpdateExtensionPoint { + + void beforeChangeL2NetworkVlanId(L2NetworkInventory l2Inv); + + void afterChangeL2NetworkVlanId(L2NetworkInventory l2Inv); +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2NetworkVO.java b/header/src/main/java/org/zstack/header/network/l2/L2NetworkVO.java index f060490108a..b01cba2853c 100755 --- a/header/src/main/java/org/zstack/header/network/l2/L2NetworkVO.java +++ b/header/src/main/java/org/zstack/header/network/l2/L2NetworkVO.java @@ -32,6 +32,8 @@ public class L2NetworkVO extends L2NetworkAO implements ToInventory, OwnedByAcco public L2NetworkVO() { this.setvSwitchType(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + this.setVirtualNetworkId(L2NetworkConstant.VIRTUAL_NETWORK_ID_DEFAULT_VALUE); + this.setIsolated(Boolean.FALSE); } public L2NetworkVO(L2NetworkVO vo) { @@ -44,6 +46,9 @@ public L2NetworkVO(L2NetworkVO vo) { this.setPhysicalInterface(vo.getPhysicalInterface()); this.setType(vo.getType()); this.setvSwitchType(vo.getvSwitchType()); + this.setVirtualNetworkId(vo.getVirtualNetworkId()); + this.setIsolated(vo.getIsolated()); + this.setPvlan(vo.getPvlan()); this.setZoneUuid(vo.getZoneUuid()); this.setAccountUuid(vo.getAccountUuid()); } diff --git a/header/src/main/java/org/zstack/header/network/l2/L2ProviderType.java b/header/src/main/java/org/zstack/header/network/l2/L2ProviderType.java new file mode 100644 index 00000000000..bfb09787630 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/L2ProviderType.java @@ -0,0 +1,69 @@ +package org.zstack.header.network.l2; + +import java.util.*; + +public class L2ProviderType { + private static Map types = Collections.synchronizedMap(new HashMap()); + private final String typeName; + private boolean exposed = true; + + public static boolean hasType(String typeName) { + return types.containsKey(typeName); + } + + public L2ProviderType(String typeName) { + this.typeName = typeName; + types.put(typeName, this); + } + + public L2ProviderType(String typeName, boolean exposed) { + this(typeName); + this.exposed = exposed; + } + + public boolean isExposed() { + return exposed; + } + + public void setExposed(boolean exposed) { + this.exposed = exposed; + } + + public static L2ProviderType valueOf(String typeName) { + L2ProviderType type = types.get(typeName); + if (type == null) { + throw new IllegalArgumentException("L2ProviderType type: " + typeName + " was not registered"); + } + return type; + } + + @Override + public String toString() { + return typeName; + } + + @Override + public boolean equals(Object t) { + if (t == null || !(t instanceof L2ProviderType)) { + return false; + } + + L2ProviderType type = (L2ProviderType) t; + return type.toString().equals(typeName); + } + + @Override + public int hashCode() { + return typeName.hashCode(); + } + + public static Set getAllTypeNames() { + HashSet exposedTypes = new HashSet(); + for (L2ProviderType type : types.values()) { + if (type.isExposed()) { + exposedTypes.add(type.toString()); + } + } + return exposedTypes; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l2/L2VlanNetworkInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l2/L2VlanNetworkInventoryDoc_zh_cn.groovy index a7792f8cc75..c13e6b9d837 100644 --- a/header/src/main/java/org/zstack/header/network/l2/L2VlanNetworkInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l2/L2VlanNetworkInventoryDoc_zh_cn.groovy @@ -6,11 +6,11 @@ import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "二层Vlan网络清单" field { name "vlan" - desc "" + desc "Vlan号" type "Integer" since "0.6" } @@ -40,13 +40,13 @@ doc { } field { name "physicalInterface" - desc "" + desc "物理网卡" type "String" since "0.6" } field { name "type" - desc "" + desc "二层网络类型" type "String" since "0.6" } @@ -64,7 +64,7 @@ doc { } field { name "attachedClusterUuids" - desc "" + desc "挂载集群的UUID列表" type "List" since "0.6" } diff --git a/header/src/main/java/org/zstack/header/network/l2/PackageInfo.java b/header/src/main/java/org/zstack/header/network/l2/PackageInfo.java index d777b0fdc67..8eebc29b1e1 100755 --- a/header/src/main/java/org/zstack/header/network/l2/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/network/l2/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "二层网络") +@PackageAPIInfo( + APICategoryName = "二层网络", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/network/l2/SdnControllerDeleteExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l2/SdnControllerDeleteExtensionPoint.java new file mode 100644 index 00000000000..c443878b0a3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l2/SdnControllerDeleteExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.header.network.l2; + +import org.zstack.header.core.Completion; + +public interface SdnControllerDeleteExtensionPoint { + void deleteNetworkServiceOfSdnController(String sdnControllerUuid, Completion completion); +} diff --git a/header/src/main/java/org/zstack/header/network/l2/VSwitch.java b/header/src/main/java/org/zstack/header/network/l2/VSwitch.java deleted file mode 100644 index eca006707ed..00000000000 --- a/header/src/main/java/org/zstack/header/network/l2/VSwitch.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.zstack.header.network.l2; - -import java.util.ArrayList; -import java.util.List; - -public interface VSwitch { - - VSwitchType linuxBridge = new VSwitchType(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); - VSwitchType ovsDpdk = new VSwitchType(L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK); - VSwitchType ovsKernel = new VSwitchType(L2NetworkConstant.VSWITCH_TYPE_OVS_KERNEL); - - default List getVSwitchTypes() { - List vSwitchTypes = new ArrayList(); - vSwitchTypes.add(linuxBridge); - //vSwitchTypes.add(ovsDpdk); - //vSwitchTypes.add(ovsKernel); - return vSwitchTypes; - } -} diff --git a/header/src/main/java/org/zstack/header/network/l2/VSwitchType.java b/header/src/main/java/org/zstack/header/network/l2/VSwitchType.java index 8a977a85568..530d926cbfd 100644 --- a/header/src/main/java/org/zstack/header/network/l2/VSwitchType.java +++ b/header/src/main/java/org/zstack/header/network/l2/VSwitchType.java @@ -1,24 +1,34 @@ package org.zstack.header.network.l2; +import org.zstack.header.vm.VmNicType; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + import java.util.*; public class VSwitchType { + private static final CLogger logger = Utils.getLogger(VSwitchType.class); private static Map types = Collections.synchronizedMap(new HashMap()); private final String typeName; private boolean exposed = true; - - public static boolean hasType(String typeName) { - return types.containsKey(typeName); - } + private boolean attachToCluster = true; + private String sdnControllerType = null; + private boolean useDpdk = false; + private Map nicTypes = Collections.synchronizedMap(new HashMap<>()); public VSwitchType(String typeName) { this.typeName = typeName; - types.put(typeName, this); + if (!types.containsKey(typeName)) { + types.put(typeName, this); + } } public VSwitchType(String typeName, boolean exposed) { this(typeName); - this.exposed = exposed; + if (!types.containsKey(typeName)) { + types.put(typeName, this); + } } public boolean isExposed() { @@ -29,6 +39,62 @@ public void setExposed(boolean exposed) { this.exposed = exposed; } + + public boolean isAttachToCluster() { + return attachToCluster; + } + + public void setAttachToCluster(boolean attachToCluster) { + this.attachToCluster = attachToCluster; + } + + public String getSdnControllerType() { + return sdnControllerType; + } + + public void setSdnControllerType(String sdnControllerType) { + this.sdnControllerType = sdnControllerType; + } + + public boolean isUseDpdk() { + return useDpdk; + } + + public void setUseDpdk(boolean useDpdk) { + this.useDpdk = useDpdk; + } + + public void addVmNicType(VmNicType.VmNicSubType subType, VmNicType nicType) { + VmNicType oldNicType = nicTypes.get(subType); + if (oldNicType != null) { + if (!oldNicType.toString().equals(nicType.toString())) { + throw new IllegalArgumentException("duplicated nic type: " + nicType + + " subtype " + subType + " for vSwitchType " + typeName + " " + + JSONObjectUtil.toJsonString(nicTypes)); + } else { + /* call addVmNicType duplicated */ + return; + } + } + logger.debug("addVmNicType nic type: " + nicType + + " subtype " + subType + " for vSwitchType " + typeName); + nicTypes.put(subType, nicType); + } + + public VmNicType getVmNicType(VmNicType.VmNicSubType subType) { + VmNicType nicType = nicTypes.get(subType); + if (nicType == null) { + /* for case, enableVHostUser is enabled, but vswitch type is linux bridge */ + nicType = nicTypes.get(VmNicType.VmNicSubType.NONE); + if (nicType == null) { + throw new IllegalArgumentException("unsupported nicSubType " + subType + " for vswitch type " + typeName); + } + } + + return nicType; + } + + public static VSwitchType valueOf(String typeName) { VSwitchType type = types.get(typeName); if (type == null) { @@ -44,7 +110,7 @@ public String toString() { @Override public boolean equals(Object t) { - if (t == null || !(t instanceof VSwitchType)) { + if (!(t instanceof VSwitchType)) { return false; } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddDnsToL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddDnsToL3NetworkMsgDoc_zh_cn.groovy index 68901b0f2d9..b4ca3e0ea44 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddDnsToL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddDnsToL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "dns" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddHostRouteToL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddHostRouteToL3NetworkMsgDoc_zh_cn.groovy index 137a6fd1c70..ca3380aec25 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddHostRouteToL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddHostRouteToL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "prefix" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.3" - } column { name "nexthop" @@ -49,7 +47,6 @@ doc { type "String" optional false since "2.3" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "2.3" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEvent.java b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEvent.java index 4de746ebb84..b54540cae5f 100755 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEvent.java +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEvent.java @@ -3,18 +3,31 @@ import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; +import java.util.ArrayList; +import java.util.List; + /** */ -@RestResponse(allTo = "inventory") +@RestResponse(fieldsTo = {"all"}) public class APIAddIpRangeByNetworkCidrEvent extends APIEvent { - private IpRangeInventory inventory; + private IpRangeInventory inventory; + + private List inventories; public IpRangeInventory getInventory() { return inventory; } - public void setInventory(IpRangeInventory inventory) { - this.inventory = inventory; + public void setInventory(IpRangeInventory ipRangeInventory) { + this.inventory = ipRangeInventory; + } + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; } public APIAddIpRangeByNetworkCidrEvent(String apiId) { @@ -27,13 +40,15 @@ public APIAddIpRangeByNetworkCidrEvent() { public static APIAddIpRangeByNetworkCidrEvent __example__() { APIAddIpRangeByNetworkCidrEvent event = new APIAddIpRangeByNetworkCidrEvent(); + List ipRanges = new ArrayList<>(); IpRangeInventory ipRange = new IpRangeInventory(); + ipRanges.add(ipRange); ipRange.setName("Test-IPRange"); ipRange.setL3NetworkUuid(uuid()); ipRange.setNetworkCidr("192.168.10.0/24"); - event.setInventory(ipRange); + event.setInventories(ipRanges); return event; } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEventDoc_zh_cn.groovy index 584c760624c..aac6a15c11e 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEventDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrEventDoc_zh_cn.groovy @@ -21,6 +21,14 @@ doc { since "0.6" clz ErrorCode.class } + ref { + name "inventories" + path "org.zstack.header.network.l3.APIAddIpRangeByNetworkCidrEvent.inventory" + desc "null" + type "IpRangeInventory" + since "0.6" + clz IpRangeInventory.class + } ref { name "inventory" path "org.zstack.header.network.l3.APIAddIpRangeByNetworkCidrEvent.inventory" @@ -29,4 +37,5 @@ doc { since "0.6" clz IpRangeInventory.class } + } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrMsgDoc_zh_cn.groovy index d146dc9d829..109811e6644 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeByNetworkCidrMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "l3NetworkUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "networkCidr" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "gateway" @@ -69,7 +65,6 @@ doc { type "String" optional true since "3.7" - } column { name "ipRangeType" @@ -89,7 +84,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -99,7 +93,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +102,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeMsgDoc_zh_cn.groovy index 525ce33a062..7a371abe610 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddIpRangeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "startIp" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "endIp" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "netmask" @@ -79,7 +74,6 @@ doc { type "String" optional false since "0.6" - } column { name "gateway" @@ -87,9 +81,8 @@ doc { desc "网关" location "body" type "String" - optional false + optional true since "0.6" - } column { name "ipRangeType" @@ -109,7 +102,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -119,7 +111,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -129,7 +120,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeByNetworkCidrMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeByNetworkCidrMsgDoc_zh_cn.groovy index 502a96f1814..7084b3d5c8a 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeByNetworkCidrMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeByNetworkCidrMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.1" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.1" - } column { name "l3NetworkUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "3.1" - } column { name "networkCidr" @@ -59,7 +56,6 @@ doc { type "String" optional false since "3.1" - } column { name "addressMode" @@ -89,7 +85,6 @@ doc { type "String" optional true since "3.1" - } column { name "systemTags" @@ -99,7 +94,6 @@ doc { type "List" optional true since "3.1" - } column { name "userTags" @@ -109,7 +103,15 @@ doc { type "List" optional true since "3.1" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeMsgDoc_zh_cn.groovy index 676b939381b..16e91143514 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddIpv6RangeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.1" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.1" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.1" - } column { name "startIp" @@ -59,7 +56,6 @@ doc { type "String" optional false since "3.1" - } column { name "endIp" @@ -69,7 +65,6 @@ doc { type "String" optional false since "3.1" - } column { name "gateway" @@ -79,7 +74,6 @@ doc { type "String" optional false since "3.1" - } column { name "prefixLen" @@ -89,7 +83,6 @@ doc { type "Integer" optional false since "3.1" - } column { name "addressMode" @@ -119,7 +112,6 @@ doc { type "String" optional true since "3.1" - } column { name "systemTags" @@ -129,7 +121,6 @@ doc { type "List" optional true since "3.1" - } column { name "userTags" @@ -139,7 +130,15 @@ doc { type "List" optional true since "3.1" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeEvent.java b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeEvent.java new file mode 100644 index 00000000000..587c0812c09 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeEvent.java @@ -0,0 +1,42 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIAddReservedIpRangeEvent extends APIEvent { + /** + * @desc see :ref:`IpRangeInventory` + */ + private ReservedIpRangeInventory inventory; + + public APIAddReservedIpRangeEvent(String apiId) { + super(apiId); + } + + public APIAddReservedIpRangeEvent() { + super(null); + } + + public ReservedIpRangeInventory getInventory() { + return inventory; + } + + public void setInventory(ReservedIpRangeInventory inventory) { + this.inventory = inventory; + } + + public static APIAddReservedIpRangeEvent __example__() { + APIAddReservedIpRangeEvent event = new APIAddReservedIpRangeEvent(); + ReservedIpRangeInventory ipRange = new ReservedIpRangeInventory(); + + ipRange.setL3NetworkUuid(uuid()); + ipRange.setName("Test-IP-Range"); + ipRange.setStartIp("192.168.100.10"); + ipRange.setEndIp("192.168.100.250"); + + event.setInventory(ipRange); + return event; + } + +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..37410bcbf75 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.network.l3 + +import org.zstack.header.network.l3.ReservedIpRangeInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "添加保留地址段清单" + + ref { + name "inventory" + path "org.zstack.header.network.l3.APIAddReservedIpRangeEvent.inventory" + desc "null" + type "ReservedIpRangeInventory" + since "5.1.0" + clz ReservedIpRangeInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.header.network.l3.APIAddReservedIpRangeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeMsg.java b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeMsg.java new file mode 100644 index 00000000000..58a220528c6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeMsg.java @@ -0,0 +1,77 @@ +package org.zstack.header.network.l3; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +@TagResourceType(L3NetworkVO.class) +@Action(category = L3NetworkConstant.ACTION_CATEGORY) +@RestRequest( + path = "/l3-networks/{l3NetworkUuid}/reserved-ip-ranges", + method = HttpMethod.POST, + responseClass = APIAddReservedIpRangeEvent.class, + parameterName = "params" +) +public class APIAddReservedIpRangeMsg extends APICreateMessage implements L3NetworkMessage, APIAuditor { + /** + * @desc l3Network uuid + */ + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, operationTarget = true) + private String l3NetworkUuid; + /** + * @desc start IPv4 address + */ + @APIParam + private String startIp; + /** + * @desc end IPv4 address + */ + @APIParam + private String endIp; + + @Override + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getStartIp() { + return startIp; + } + + public void setStartIp(String startIp) { + this.startIp = startIp; + } + + public String getEndIp() { + return endIp; + } + + public void setEndIp(String endIP) { + this.endIp = endIP; + } + + public static APIAddReservedIpRangeMsg __example__() { + APIAddReservedIpRangeMsg msg = new APIAddReservedIpRangeMsg(); + + msg.setL3NetworkUuid(uuid()); + msg.setStartIp("192.168.100.10"); + msg.setEndIp("192.168.100.250"); + + return msg; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new Result(rsp.isSuccess() ? ((APIAddReservedIpRangeEvent)rsp).getInventory().getL3NetworkUuid() : "", L3NetworkVO.class); + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..8e1b59e319e --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIAddReservedIpRangeMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.header.network.l3 + +import org.zstack.header.network.l3.APIAddReservedIpRangeEvent + +doc { + title "AddReservedIpRange" + + category "network.l3" + + desc """添加保留地址段""" + + rest { + request { + url "POST /v1/l3-networks/{l3NetworkUuid}/reserved-ip-ranges" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAddReservedIpRangeMsg.class + + desc """""" + + params { + + column { + name "l3NetworkUuid" + enclosedIn "params" + desc "三层网络UUID" + location "url" + type "String" + optional false + since "5.1.0" + } + column { + name "startIp" + enclosedIn "params" + desc "开始IP(包含在地址段内)" + location "body" + type "String" + optional false + since "5.1.0" + } + column { + name "endIp" + enclosedIn "params" + desc "结束IP(包含在地址段内)" + location "body" + type "String" + optional false + since "5.1.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.1.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIAddReservedIpRangeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/network/l3/APIChangeL3NetworkStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIChangeL3NetworkStateMsgDoc_zh_cn.groovy index 372050b79c7..02a434acbb5 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIChangeL3NetworkStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIChangeL3NetworkStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsg.java b/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsg.java index 01a9c3cd94d..8e62b9c857c 100755 --- a/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsg.java +++ b/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsg.java @@ -20,6 +20,10 @@ public class APICheckIpAvailabilityMsg extends APISyncCallMessage implements L3N private String l3NetworkUuid; @APIParam(maxLength = 255) private String ip; + @APIParam(required = false) + private Boolean arpCheck = false; + @APIParam(required = false) + private Boolean ipRangeCheck= true; @Override public String getL3NetworkUuid() { @@ -37,7 +41,23 @@ public String getIp() { public void setIp(String ip) { this.ip = ip; } - + + public Boolean getArpCheck() { + return arpCheck; + } + + public void setArpCheck(Boolean arpCheck) { + this.arpCheck = arpCheck; + } + + public Boolean getIpRangeCheck() { + return ipRangeCheck; + } + + public void setIpRangeCheck(Boolean ipRangeCheck) { + this.ipRangeCheck = ipRangeCheck; + } + public static APICheckIpAvailabilityMsg __example__() { APICheckIpAvailabilityMsg msg = new APICheckIpAvailabilityMsg(); diff --git a/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsgDoc_zh_cn.groovy index 6d6c36cb1d3..dc8f772bea4 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APICheckIpAvailabilityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "ip" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,24 @@ doc { type "List" optional true since "0.6" - + } + column { + name "arpCheck" + enclosedIn "" + desc "使用arping检测" + location "query" + type "Boolean" + optional true + since "5.1.0" + } + column { + name "ipRangeCheck" + enclosedIn "" + desc "在数据库可用地址段内检测" + location "query" + type "Boolean" + optional true + since "5.1.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsg.java b/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsg.java index 81532a7805a..4e5745a1b5b 100755 --- a/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsg.java @@ -82,6 +82,9 @@ public class APICreateL3NetworkMsg extends APICreateMessage implements APIAudito private String dnsDomain; + @APIParam(required = false) + private Boolean enableIPAM = Boolean.TRUE; + public String getDnsDomain() { return dnsDomain; } @@ -146,6 +149,14 @@ public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + public Boolean getEnableIPAM() { + return enableIPAM; + } + + public void setEnableIPAM(Boolean enableIPAM) { + this.enableIPAM = enableIPAM; + } + public static APICreateL3NetworkMsg __example__() { APICreateL3NetworkMsg msg = new APICreateL3NetworkMsg(); diff --git a/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsgDoc_zh_cn.groovy index a7e7ac565bd..e1abfd63ad9 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APICreateL3NetworkMsgDoc_zh_cn.groovy @@ -15,7 +15,6 @@ doc { header (Authorization: 'OAuth the-session-uuid') - clz APICreateL3NetworkMsg.class desc """""" @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -40,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -50,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "l2NetworkUuid" @@ -60,14 +56,13 @@ doc { type "String" optional false since "0.6" - } column { name "ipVersion" enclosedIn "params" desc "ip协议号" location "body" - type "String" + type "Integer" optional true since "3.1" values ("4","6") @@ -80,7 +75,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "dnsDomain" @@ -90,7 +84,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -100,7 +93,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -110,7 +102,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -120,7 +111,6 @@ doc { type "List" optional true since "0.6" - } column { name "category" @@ -132,6 +122,24 @@ doc { since "2.2" values ("Public","Private","System") } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "enableIPAM" + enclosedIn "params" + desc "IP地址管理是否启用" + location "body" + type "Boolean" + optional true + since "0.6" + } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressEvent.java b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressEvent.java new file mode 100644 index 00000000000..eddcff9ac89 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressEvent.java @@ -0,0 +1,22 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDeleteIpAddressEvent extends APIEvent { + + public APIDeleteIpAddressEvent(String apiId) { + super(apiId); + } + + public APIDeleteIpAddressEvent() { + super(null); + } + + public static APIDeleteIpAddressEvent __example__() { + + return new APIDeleteIpAddressEvent(); + } + +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..4e0d5e892c1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.network.l3 + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "删除IP地址" + + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.header.network.l3.APIDeleteIpAddressEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressMsg.java b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressMsg.java new file mode 100644 index 00000000000..15f0540bce8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressMsg.java @@ -0,0 +1,53 @@ +package org.zstack.header.network.l3; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.*; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +import java.util.List; + +@TagResourceType(L3NetworkVO.class) +@Action(category = L3NetworkConstant.ACTION_CATEGORY) +@RestRequest( + path = "/l3-networks/{l3NetworkUuid}/ip-address", + method = HttpMethod.DELETE, + responseClass = APIDeleteIpAddressEvent.class +) +public class APIDeleteIpAddressMsg extends APIDeleteMessage implements L3NetworkMessage { + /** + * @desc l3Network uuid + */ + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, operationTarget = true) + private String l3NetworkUuid; + + @APIParam(resourceType = UsedIpVO.class, checkAccount = true, operationTarget = true) + private List usedIpUuids; + + @Override + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public List getUsedIpUuids() { + return usedIpUuids; + } + + public void setUsedIpUuids(List usedIpUuids) { + this.usedIpUuids = usedIpUuids; + } + + public static APIDeleteIpAddressMsg __example__() { + APIDeleteIpAddressMsg msg = new APIDeleteIpAddressMsg(); + + msg.setL3NetworkUuid(uuid()); + + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..d49fe4a4743 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpAddressMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.network.l3 + +import org.zstack.header.network.l3.APIDeleteIpAddressEvent + +doc { + title "DeleteIpAddress" + + category "未知类别" + + desc """删除IP地址""" + + rest { + request { + url "DELETE /v1/l3-networks/{l3NetworkUuid}/ip-address" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeleteIpAddressMsg.class + + desc """""" + + params { + + column { + name "l3NetworkUuid" + enclosedIn "" + desc "三层网络UUID" + location "url" + type "String" + optional false + since "5.1.0" + } + column { + name "usedIpUuids" + enclosedIn "" + desc "被删除地址Uuid" + location "body" + type "List" + optional false + since "5.1.0" + } + column { + name "deleteMode" + enclosedIn "" + desc "删除模式(Permissive / Enforcing,Permissive)" + location "body" + type "String" + optional true + since "5.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIDeleteIpAddressEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpRangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpRangeMsgDoc_zh_cn.groovy index b86effd973d..585771d2d0b 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpRangeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteIpRangeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIDeleteL3NetworkMsgDoc_zh_cn.groovy index 3cc5b9be463..e0150eb23d8 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIDeleteL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeEvent.java b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeEvent.java new file mode 100644 index 00000000000..7233dcf404e --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeEvent.java @@ -0,0 +1,22 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDeleteReservedIpRangeEvent extends APIEvent { + public APIDeleteReservedIpRangeEvent(String apiId) { + super(apiId); + } + + public APIDeleteReservedIpRangeEvent() { + super(null); + } + + public static APIDeleteReservedIpRangeEvent __example__() { + APIDeleteReservedIpRangeEvent event = new APIDeleteReservedIpRangeEvent(); + event.setSuccess(true); + return event; + } + +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..6d5c26e48c6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.network.l3 + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "删除保留地址段" + + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.header.network.l3.APIDeleteReservedIpRangeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeMsg.java b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeMsg.java new file mode 100644 index 00000000000..7851156b421 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeMsg.java @@ -0,0 +1,64 @@ +package org.zstack.header.network.l3; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.APINoSee; +import org.zstack.header.rest.RestRequest; + +@Action(category = L3NetworkConstant.ACTION_CATEGORY) +@RestRequest( + path = "/l3-networks/reserved-ip-ranges/{uuid}", + method = HttpMethod.DELETE, + responseClass = APIDeleteReservedIpRangeEvent.class +) +public class APIDeleteReservedIpRangeMsg extends APIDeleteMessage implements L3NetworkMessage, IpRangeMessage { + /** + * @desc ip range uuid + */ + @APIParam(resourceType = ReservedIpRangeVO.class, successIfResourceNotExisting = true, + checkAccount = true, operationTarget = true) + private String uuid; + /** + * @ignore + */ + @APINoSee + private String l3NetworkUuid; + + public APIDeleteReservedIpRangeMsg() { + } + + public APIDeleteReservedIpRangeMsg(String uuid) { + super(); + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + @Override + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + @Override + public String getIpRangeUuid() { + return uuid; + } + + public static APIDeleteReservedIpRangeMsg __example__() { + APIDeleteReservedIpRangeMsg msg = new APIDeleteReservedIpRangeMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..4a121773302 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/APIDeleteReservedIpRangeMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.network.l3 + +import org.zstack.header.network.l3.APIDeleteReservedIpRangeEvent + +doc { + title "DeleteReservedIpRange" + + category "network.l3" + + desc """删除保留地址段""" + + rest { + request { + url "DELETE /v1/l3-networks/reserved-ip-ranges/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeleteReservedIpRangeMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.1.0" + } + column { + name "deleteMode" + enclosedIn "" + desc "删除模式(Permissive / Enforcing,Permissive)" + location "body" + type "String" + optional true + since "5.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIDeleteReservedIpRangeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/network/l3/APIGetFreeIpMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIGetFreeIpMsgDoc_zh_cn.groovy index 2744c1189cb..425b867af77 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIGetFreeIpMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIGetFreeIpMsgDoc_zh_cn.groovy @@ -31,7 +31,6 @@ doc { type "String" optional true since "0.6" - } column { name "ipRangeUuid" @@ -41,7 +40,6 @@ doc { type "String" optional true since "0.6" - } column { name "start" @@ -51,7 +49,6 @@ doc { type "String" optional true since "0.6" - } column { name "ipRangeType" @@ -81,7 +78,6 @@ doc { type "int" optional true since "0.6" - } column { name "systemTags" @@ -91,7 +87,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -101,7 +96,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIGetIpAddressCapacityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIGetIpAddressCapacityMsgDoc_zh_cn.groovy index 6e0c6c432ce..c9102c442d0 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIGetIpAddressCapacityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIGetIpAddressCapacityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "l3NetworkUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "ipRangeUuids" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "all" @@ -59,7 +56,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkMtuMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkMtuMsgDoc_zh_cn.groovy index 9e4b879b189..62e64670d82 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkMtuMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkMtuMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy index 3ccd2fd953a..4bfb8a054b1 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.2" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "2.2" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.2" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkTypesMsgDoc_zh_cn.groovy index 04e23d3c204..fae61192956 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIGetL3NetworkTypesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIQueryIpAddressMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIQueryIpAddressMsgDoc_zh_cn.groovy index b356c8d72c9..bcbb9137b28 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIQueryIpAddressMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIQueryIpAddressMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.l3 import org.zstack.header.network.l3.APIQueryIpAddressReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryIpAddress" diff --git a/header/src/main/java/org/zstack/header/network/l3/APIQueryIpRangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIQueryIpRangeMsgDoc_zh_cn.groovy index 15c91ee2f42..8b06159ea84 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIQueryIpRangeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIQueryIpRangeMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.l3 import org.zstack.header.network.l3.APIQueryIpRangeReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询IP地址范围(QueryIpRange)" diff --git a/header/src/main/java/org/zstack/header/network/l3/APIQueryL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIQueryL3NetworkMsgDoc_zh_cn.groovy index 0692a68c77a..098413627c2 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIQueryL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIQueryL3NetworkMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.l3 import org.zstack.header.network.l3.APIQueryL3NetworkReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询三层网络(QueryL3Network)" diff --git a/header/src/main/java/org/zstack/header/network/l3/APIRemoveDnsFromL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIRemoveDnsFromL3NetworkMsgDoc_zh_cn.groovy index 566148d5f29..1b87593bd37 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIRemoveDnsFromL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIRemoveDnsFromL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "dns" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIRemoveHostRouteFromL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIRemoveHostRouteFromL3NetworkMsgDoc_zh_cn.groovy index 130774afb8b..69f2fe3d34f 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIRemoveHostRouteFromL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIRemoveHostRouteFromL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "prefix" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.3" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkMtuMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkMtuMsgDoc_zh_cn.groovy index 0d25248453e..0dfe491a5f0 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkMtuMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkMtuMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "mtu" @@ -39,7 +38,6 @@ doc { type "Integer" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy index 64b85395197..15106d22cdf 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APISetL3NetworkRouterInterfaceIpMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.2" - } column { name "routerInterfaceIp" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.2" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.2" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.2" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIUpdateIpRangeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIUpdateIpRangeMsgDoc_zh_cn.groovy index 628a96e5e0e..4b90caf486b 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIUpdateIpRangeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIUpdateIpRangeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/APIUpdateL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/APIUpdateL3NetworkMsgDoc_zh_cn.groovy index b7b6610fcbf..08fce8f0711 100644 --- a/header/src/main/java/org/zstack/header/network/l3/APIUpdateL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/APIUpdateL3NetworkMsgDoc_zh_cn.groovy @@ -15,7 +15,6 @@ doc { header (Authorization: 'OAuth the-session-uuid') - clz APIUpdateL3NetworkMsg.class desc """""" @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -40,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -50,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "system" @@ -60,7 +56,6 @@ doc { type "Boolean" optional true since "0.6" - } column { name "systemTags" @@ -70,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -80,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "category" @@ -92,6 +85,15 @@ doc { since "2.2" values ("Public","Private","System") } + column { + name "dnsDomain" + enclosedIn "updateL3Network" + desc "" + location "body" + type "String" + optional true + since "2.6.0" + } } } diff --git a/header/src/main/java/org/zstack/header/network/l3/AfterDeleteIpRangeExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l3/AfterDeleteIpRangeExtensionPoint.java new file mode 100644 index 00000000000..70833859dfc --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/AfterDeleteIpRangeExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.core.Completion; + +/** + * Created by boce.wang on 07/01/2025. + */ +public interface AfterDeleteIpRangeExtensionPoint { + void afterDeleteIpRange(IpRangeInventory ipr); +} diff --git a/header/src/main/java/org/zstack/header/network/l3/AllocateIpMsg.java b/header/src/main/java/org/zstack/header/network/l3/AllocateIpMsg.java index ff7fc99ac2d..849ebe4c96c 100755 --- a/header/src/main/java/org/zstack/header/network/l3/AllocateIpMsg.java +++ b/header/src/main/java/org/zstack/header/network/l3/AllocateIpMsg.java @@ -10,12 +10,14 @@ public class AllocateIpMsg extends NeedReplyMessage implements L3NetworkMessage, private String excludedIp; private boolean duplicatedIpAllowed = false; private String ipRangeUuid; + private String ipRangeType; private int ipVersion = IPv6Constants.IPv4; public String getRequiredIp() { return requiredIp; } + @Override public void setRequiredIp(String requiredIp) { this.requiredIp = requiredIp; } @@ -60,6 +62,7 @@ public String getIpRangeUuid() { return ipRangeUuid; } + @Override public void setIpRangeUuid(String ipRangeUuid) { this.ipRangeUuid = ipRangeUuid; } diff --git a/header/src/main/java/org/zstack/header/network/l3/CheckIpAvailabilityMsg.java b/header/src/main/java/org/zstack/header/network/l3/CheckIpAvailabilityMsg.java index c8599e76ac1..2adfdd38aac 100755 --- a/header/src/main/java/org/zstack/header/network/l3/CheckIpAvailabilityMsg.java +++ b/header/src/main/java/org/zstack/header/network/l3/CheckIpAvailabilityMsg.java @@ -8,6 +8,8 @@ public class CheckIpAvailabilityMsg extends NeedReplyMessage implements L3NetworkMessage { private String l3NetworkUuid; private String ip; + private Boolean arpCheck = false; + private Boolean ipRangeCheck = true; @Override public String getL3NetworkUuid() { @@ -25,4 +27,20 @@ public String getIp() { public void setIp(String ip) { this.ip = ip; } + + public Boolean getArpCheck() { + return arpCheck; + } + + public void setArpCheck(Boolean arpCheck) { + this.arpCheck = arpCheck; + } + + public Boolean getIpRangeCheck() { + return ipRangeCheck; + } + + public void setIpRangeCheck(Boolean ipRangeCheck) { + this.ipRangeCheck = ipRangeCheck; + } } diff --git a/header/src/main/java/org/zstack/header/network/l3/IpAllocateMessage.java b/header/src/main/java/org/zstack/header/network/l3/IpAllocateMessage.java index a2db98e3f6c..4bb49d9fc8f 100755 --- a/header/src/main/java/org/zstack/header/network/l3/IpAllocateMessage.java +++ b/header/src/main/java/org/zstack/header/network/l3/IpAllocateMessage.java @@ -12,5 +12,10 @@ public interface IpAllocateMessage { default String getExcludedIp() { return null; } + default boolean isDuplicatedIpAllowed() {return false;} + + void setIpRangeUuid(String ipRangeUuid); + + void setRequiredIp(String requiredIp); } diff --git a/header/src/main/java/org/zstack/header/network/l3/IpRangeFactory.java b/header/src/main/java/org/zstack/header/network/l3/IpRangeFactory.java index ed6537164fd..6ad1a5507b7 100644 --- a/header/src/main/java/org/zstack/header/network/l3/IpRangeFactory.java +++ b/header/src/main/java/org/zstack/header/network/l3/IpRangeFactory.java @@ -1,9 +1,12 @@ package org.zstack.header.network.l3; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.message.APICreateMessage; +import java.util.List; + public interface IpRangeFactory { IpRangeType getType(); - IpRangeInventory createIpRange(IpRangeInventory ipr, APICreateMessage msg); + void createIpRange(List iprs, APICreateMessage msg, ReturnValueCompletion> completion); } diff --git a/header/src/main/java/org/zstack/header/network/l3/IpRangeInventory.java b/header/src/main/java/org/zstack/header/network/l3/IpRangeInventory.java index 7df0fa27606..fb36ea67066 100755 --- a/header/src/main/java/org/zstack/header/network/l3/IpRangeInventory.java +++ b/header/src/main/java/org/zstack/header/network/l3/IpRangeInventory.java @@ -256,7 +256,7 @@ public static IpRangeInventory fromMessage(APIAddIpRangeMsg msg) { ipr.setStartIp(msg.getStartIp()); ipr.setEndIp(msg.getEndIp()); ipr.setNetmask(msg.getNetmask()); - ipr.setPrefixLen(NetworkUtils.getPrefixLengthFromNetwork(msg.getNetmask())); + ipr.setPrefixLen(NetworkUtils.getPrefixLengthFromNetmask(msg.getNetmask())); ipr.setGateway(msg.getGateway()); ipr.setL3NetworkUuid(msg.getL3NetworkUuid()); SubnetUtils su = new SubnetUtils(msg.getStartIp(), msg.getNetmask()); @@ -270,44 +270,69 @@ public static IpRangeInventory fromMessage(APIAddIpRangeMsg msg) { return ipr; } - public static IpRangeInventory fromMessage(APIAddIpRangeByNetworkCidrMsg msg) { - SubnetUtils utils = new SubnetUtils(msg.getNetworkCidr()); - SubnetInfo subnet = utils.getInfo(); - utils = new SubnetUtils(subnet.getNetworkAddress(), subnet.getNetmask()); - subnet = utils.getInfo(); - + private static IpRangeInventory createAndSetIpv4RangeAttribute(APIAddIpRangeByNetworkCidrMsg msg, SubnetInfo subnet, + String startIp, String endIp, String gateway) { IpRangeInventory ipr = new IpRangeInventory(); ipr.setNetworkCidr(subnet.getCidrSignature()); ipr.setName(msg.getName()); ipr.setDescription(msg.getDescription()); - ipr.setIpRangeType(IpRangeType.valueOf(msg.getIpRangeType())); - if (ipr.getIpRangeType() == IpRangeType.Normal) { - String lowAddress = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress())); - String highAddress = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getHighAddress())); - if (msg.getGateway() == null || msg.getGateway().equals(lowAddress)) { - ipr.setGateway(lowAddress); - ipr.setStartIp(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress()) + 1)); - ipr.setEndIp(subnet.getHighAddress()); - } else if (msg.getGateway().equals(highAddress)) { - ipr.setGateway(highAddress); - ipr.setStartIp(lowAddress); - ipr.setEndIp(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getHighAddress()) - 1)); - } - } else { - ipr.setGateway(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress()))); - ipr.setStartIp(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress()) - 1)); - ipr.setEndIp(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getHighAddress()) + 1)); - } + ipr.setGateway(gateway); + ipr.setStartIp(startIp); + ipr.setEndIp(endIp); + ipr.setNetmask(subnet.getNetmask()); - ipr.setPrefixLen(NetworkUtils.getPrefixLengthFromNetwork(subnet.getNetmask())); + ipr.setPrefixLen(NetworkUtils.getPrefixLengthFromNetmask(subnet.getNetmask())); ipr.setL3NetworkUuid(msg.getL3NetworkUuid()); ipr.setUuid(msg.getResourceUuid()); ipr.setIpVersion(IPv6Constants.IPv4); + return ipr; } + public static List fromMessage(APIAddIpRangeByNetworkCidrMsg msg) { + List iprs = new ArrayList<>(); + SubnetUtils utils = new SubnetUtils(msg.getNetworkCidr()); + SubnetInfo subnet = utils.getInfo(); + utils = new SubnetUtils(subnet.getNetworkAddress(), subnet.getNetmask()); + subnet = utils.getInfo(); + + String lowAddress = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress())); + String highAddress = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getHighAddress())); + + if (IpRangeType.valueOf(msg.getIpRangeType()) == IpRangeType.Normal) { + if (msg.getGateway() == null || msg.getGateway().equals(lowAddress)) { + String gateway = lowAddress; + String startIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(lowAddress) + 1); + String endIp = highAddress; + IpRangeInventory ipr = createAndSetIpv4RangeAttribute(msg, subnet, startIp, endIp, gateway); + iprs.add(ipr); + } else if (msg.getGateway().equals(highAddress)) { + String gateway = highAddress; + String startIp = lowAddress; + String endIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(highAddress) - 1); + IpRangeInventory ipr = createAndSetIpv4RangeAttribute(msg, subnet, startIp, endIp, gateway); + iprs.add(ipr); + } else { + String gateway = msg.getGateway(); + String startIp = lowAddress; + String endIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(gateway) - 1); + iprs.add(createAndSetIpv4RangeAttribute(msg, subnet, startIp, endIp, gateway)); + + startIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(gateway) + 1); + endIp = highAddress; + iprs.add(createAndSetIpv4RangeAttribute(msg, subnet, startIp, endIp, gateway)); + } + } else { + String gateway = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(lowAddress)); + String startIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(lowAddress)); + String endIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(highAddress)); + iprs.add(createAndSetIpv4RangeAttribute(msg, subnet, startIp, endIp, gateway)); + } + return iprs; + } + public static IpRangeInventory fromMessage(APIAddIpv6RangeByNetworkCidrMsg msg) { IpRangeInventory ipr = new IpRangeInventory(); ipr.setNetworkCidr(IPv6NetworkUtils.getFormalCidrOfNetworkCidr(msg.getNetworkCidr())); diff --git a/header/src/main/java/org/zstack/header/network/l3/IpRangeState.java b/header/src/main/java/org/zstack/header/network/l3/IpRangeState.java new file mode 100644 index 00000000000..e32f59b3597 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/IpRangeState.java @@ -0,0 +1,6 @@ +package org.zstack.header.network.l3; + +public enum IpRangeState { + Enabled, + Disabled; +} diff --git a/header/src/main/java/org/zstack/header/network/l3/IpRangeVO.java b/header/src/main/java/org/zstack/header/network/l3/IpRangeVO.java index f034efde257..06d04bb02cd 100644 --- a/header/src/main/java/org/zstack/header/network/l3/IpRangeVO.java +++ b/header/src/main/java/org/zstack/header/network/l3/IpRangeVO.java @@ -4,6 +4,7 @@ import org.zstack.header.vo.BaseResource; import org.zstack.header.vo.EO; import org.zstack.header.vo.EntityGraph; +import org.zstack.utils.network.NetworkUtils; import javax.persistence.Entity; import javax.persistence.Table; @@ -31,5 +32,4 @@ public String getAccountUuid() { public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; } - } diff --git a/header/src/main/java/org/zstack/header/network/l3/L3Network.java b/header/src/main/java/org/zstack/header/network/l3/L3Network.java index 7ce95f43180..f6e1a3dcf1c 100755 --- a/header/src/main/java/org/zstack/header/network/l3/L3Network.java +++ b/header/src/main/java/org/zstack/header/network/l3/L3Network.java @@ -6,4 +6,6 @@ public interface L3Network { void handleMessage(Message msg); void deleteHook(); + + CheckIpAvailabilityReply checkIpAvailability(CheckIpAvailabilityMsg msg); } diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO.java index 1d912980835..52050b4ddd9 100755 --- a/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO.java +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO.java @@ -16,6 +16,9 @@ public class L3NetworkAO extends ResourceVO { @Index private String name; + @Column + private Integer internalId; + @Column private String description; @@ -43,6 +46,12 @@ public class L3NetworkAO extends ResourceVO { @Column private Integer ipVersion; + @Column + private Boolean enableIPAM = Boolean.TRUE; + + @Column + private Boolean isolated = Boolean.FALSE; + @Column private Timestamp createDate; @@ -153,4 +162,28 @@ public Integer getIpVersion() { public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + + public Boolean getEnableIPAM() { + return enableIPAM; + } + + public void setEnableIPAM(Boolean enableIPAM) { + this.enableIPAM = enableIPAM; + } + + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public Integer getInternalId() { + return internalId; + } + + public void setInternalId(Integer internalId) { + this.internalId = internalId; + } } diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO_.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO_.java index 298a11333bb..8268dc4fe3a 100755 --- a/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO_.java +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkAO_.java @@ -9,6 +9,7 @@ @StaticMetamodel(L3NetworkAO.class) public class L3NetworkAO_ extends ResourceVO_ { public static volatile SingularAttribute name; + public static volatile SingularAttribute internalId; public static volatile SingularAttribute type; public static volatile SingularAttribute system; public static volatile SingularAttribute state; @@ -18,6 +19,8 @@ public class L3NetworkAO_ extends ResourceVO_ { public static volatile SingularAttribute zoneUuid; public static volatile SingularAttribute l2NetworkUuid; public static volatile SingularAttribute ipVersion; + public static volatile SingularAttribute enableIPAM; + public static volatile SingularAttribute isolated; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkConstant.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkConstant.java index 61e68201033..c06e8aaf4c8 100755 --- a/header/src/main/java/org/zstack/header/network/l3/L3NetworkConstant.java +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkConstant.java @@ -13,6 +13,8 @@ public interface L3NetworkConstant { @PythonClass public static final String L3_BASIC_NETWORK_TYPE = "L3BasicNetwork"; @PythonClass + public static final String ASC_DELAY_RECYCLE_IP_ALLOCATOR_STRATEGY = "AscDelayRecycleIpAllocatorStrategy"; + @PythonClass public static final String FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY = "FirstAvailableIpAllocatorStrategy"; @PythonClass public static final String RANDOM_IP_ALLOCATOR_STRATEGY = "RandomIpAllocatorStrategy"; diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkCreateExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkCreateExtensionPoint.java new file mode 100644 index 00000000000..db9e4f24bff --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkCreateExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.network.l3; + +public interface L3NetworkCreateExtensionPoint { + void afterCreateL3Network(L3NetworkInventory inventory); +} diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventory.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventory.java index ffb1e04a1e6..f1662f6421f 100755 --- a/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventory.java +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventory.java @@ -3,6 +3,7 @@ import org.zstack.header.configuration.PythonClassInventory; import org.zstack.header.network.l2.L2NetworkInventory; import org.zstack.header.network.service.NetworkServiceL3NetworkRefInventory; +import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.query.*; import org.zstack.header.search.Inventory; import org.zstack.header.vm.VmNicInventory; @@ -84,6 +85,9 @@ public class L3NetworkInventory implements Serializable { * @desc max length of 255 characters */ private String name; + + private Integer internalId; + /** * @desc max length of 2048 characters */ @@ -117,6 +121,10 @@ public class L3NetworkInventory implements Serializable { @Deprecated private Integer ipVersion; + private Boolean enableIPAM; + + private Boolean isolated; + /** * @desc the time this resource gets created */ @@ -150,9 +158,14 @@ public class L3NetworkInventory implements Serializable { joinColumn = @JoinColumn(name = "l3NetworkUuid")) private List hostRoute; + @Queryable(mappingClass = ReservedIpRangeInventory.class, + joinColumn = @JoinColumn(name = "l3NetworkUuid")) + private List reservedIpRanges; + public static L3NetworkInventory valueOf(L3NetworkVO vo) { L3NetworkInventory inv = new L3NetworkInventory(); inv.setUuid(vo.getUuid()); + inv.setInternalId(vo.getInternalId()); inv.setCreateDate(vo.getCreateDate()); inv.setDescription(vo.getDescription()); inv.setL2NetworkUuid(vo.getL2NetworkUuid()); @@ -170,6 +183,9 @@ public static L3NetworkInventory valueOf(L3NetworkVO vo) { inv.setCategory(vo.getCategory().toString()); inv.setHostRoute(L3NetworkHostRouteInventory.valueOf(vo.getHostRoutes())); inv.setIpVersion(vo.getIpVersion()); + inv.setEnableIPAM(vo.getEnableIPAM()); + inv.setIsolated(vo.getIsolated()); + inv.setReservedIpRanges(ReservedIpRangeInventory.valueOf(vo.getReservedIpRanges())); return inv; } @@ -281,6 +297,14 @@ public void setIpRanges(List ipRanges) { this.ipRanges = ipRanges; } + public List getReservedIpRanges() { + return reservedIpRanges; + } + + public void setReservedIpRanges(List reservedIpRanges) { + this.reservedIpRanges = reservedIpRanges; + } + public List getNetworkServices() { return networkServices; } @@ -368,4 +392,54 @@ public List getIpVersions() { return ipVersions; } + + public Boolean getEnableIPAM() { + return enableIPAM; + } + + public void setEnableIPAM(Boolean enableIPAM) { + this.enableIPAM = enableIPAM; + } + + public Boolean getSystem() { + return system; + } + + public void setSystem(Boolean system) { + this.system = system; + } + + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public boolean enableIpAddressAllocation() { + if (getCategory().equals(L3NetworkCategory.System.toString())) { + return true; + } + + if (!getType().equals(L3NetworkConstant.L3_BASIC_NETWORK_TYPE)) { + return true; + } + + for (NetworkServiceL3NetworkRefInventory ref : networkServices) { + if (ref.getNetworkServiceType().equals(NetworkServiceType.DHCP.toString())) { + return true; + } + } + + return false; + } + + public Integer getInternalId() { + return internalId; + } + + public void setInternalId(Integer internalId) { + this.internalId = internalId; + } } diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventoryDoc_zh_cn.groovy index 93bdbbd1670..72fdc78ac05 100644 --- a/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkInventoryDoc_zh_cn.groovy @@ -3,10 +3,10 @@ package org.zstack.header.network.l3 import java.lang.Boolean import java.lang.Integer import java.sql.Timestamp -import java.sql.Timestamp import org.zstack.header.network.l3.IpRangeInventory import org.zstack.header.network.service.NetworkServiceL3NetworkRefInventory import org.zstack.header.network.l3.L3NetworkHostRouteInventory +import org.zstack.header.network.l3.ReservedIpRangeInventory doc { @@ -76,7 +76,19 @@ doc { name "ipVersion" desc "ip协议号" type "Integer" - since "3.1" + since "3.1.0" + } + field { + name "enableIPAM" + desc "打开IP地址管理功能" + type "Boolean" + since "5.1.0" + } + field { + name "isolated" + desc "打开PVLAN功能" + type "Boolean" + since "5.1.0" } field { name "createDate" @@ -120,4 +132,12 @@ doc { since "2.3" clz L3NetworkHostRouteInventory.class } + ref { + name "reservedIpRanges" + path "org.zstack.header.network.l3.L3NetworkInventory.reservedIpRanges" + desc "保留地址段" + type "List" + since "5.1.0" + clz ReservedIpRangeInventory.class + } } diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkSequenceNumberVO.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkSequenceNumberVO.java new file mode 100644 index 00000000000..b388eebff63 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkSequenceNumberVO.java @@ -0,0 +1,20 @@ +package org.zstack.header.network.l3; + +import javax.persistence.*; + +@Entity +@Table +public class L3NetworkSequenceNumberVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkUpdateExtensionPoint.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkUpdateExtensionPoint.java new file mode 100644 index 00000000000..6699c0b0021 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkUpdateExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.network.l3; + +public interface L3NetworkUpdateExtensionPoint { + void updateL3NetworkMtu(L3NetworkInventory inventory); +} diff --git a/header/src/main/java/org/zstack/header/network/l3/L3NetworkVO.java b/header/src/main/java/org/zstack/header/network/l3/L3NetworkVO.java index 85d5109e574..0df379851dd 100755 --- a/header/src/main/java/org/zstack/header/network/l3/L3NetworkVO.java +++ b/header/src/main/java/org/zstack/header/network/l3/L3NetworkVO.java @@ -1,6 +1,7 @@ package org.zstack.header.network.l3; import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.vo.EntityGraph; import org.zstack.header.network.l2.L2NetworkVO; import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO; @@ -8,15 +9,12 @@ import org.zstack.header.vo.EO; import org.zstack.header.vo.NoView; import org.zstack.header.zone.ZoneVO; -import org.zstack.utils.network.IPv6Constants; import javax.persistence.*; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; + @Entity @Table @EO(EOClazz = L3NetworkEO.class) @@ -48,6 +46,11 @@ public class L3NetworkVO extends L3NetworkAO implements OwnedByAccount { @NoView private Set hostRoutes = new HashSet(); + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "l3NetworkUuid", insertable = false, updatable = false) + @NoView + private Set reservedIpRanges = new HashSet(); + @Transient private String accountUuid; @@ -93,17 +96,34 @@ public void setHostRoutes(Set hostRoutes) { this.hostRoutes = hostRoutes; } + public Set getReservedIpRanges() { + return reservedIpRanges; + } + + public void setReservedIpRanges(Set reservedIpRanges) { + this.reservedIpRanges = reservedIpRanges; + } + public List getIpVersions() { - List ipVersions = new ArrayList<>(); - if (super.getIpVersion() == IPv6Constants.IPv4) { - ipVersions.add(IPv6Constants.IPv4); - } else if (super.getIpVersion() == IPv6Constants.IPv6) { - ipVersions.add(IPv6Constants.IPv6); - } else if (super.getIpVersion() == IPv6Constants.DUAL_STACK) { - ipVersions.add(IPv6Constants.IPv4); - ipVersions.add(IPv6Constants.IPv6); + return getIpRanges().stream().map(IpRangeAO::getIpVersion).distinct() + .sorted().collect(Collectors.toList()); + } + + public boolean enableIpAddressAllocation() { + if (getCategory() == L3NetworkCategory.System) { + return true; + } + + if (!getType().equals(L3NetworkConstant.L3_BASIC_NETWORK_TYPE)) { + return true; + } + + for (NetworkServiceL3NetworkRefVO ref : networkServices) { + if (ref.getNetworkServiceType().equals(NetworkServiceType.DHCP.toString())) { + return true; + } } - return ipVersions; + return false; } } diff --git a/header/src/main/java/org/zstack/header/network/l3/PackageInfo.java b/header/src/main/java/org/zstack/header/network/l3/PackageInfo.java index fffc3464d59..45825ea4b76 100755 --- a/header/src/main/java/org/zstack/header/network/l3/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/network/l3/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "三层网络") +@PackageAPIInfo( + APICategoryName = "三层网络", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeInventory.java b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeInventory.java new file mode 100644 index 00000000000..abe7a574464 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeInventory.java @@ -0,0 +1,158 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = ReservedIpRangeVO.class) +@PythonClassInventory +@ExpandedQueries({ + @ExpandedQuery(expandedField = "l3Network", inventoryClass = L3NetworkInventory.class, + foreignKey = "l3NetworkUuid", expandedInventoryKey = "uuid") +}) +public class ReservedIpRangeInventory implements Serializable { + /** + * @desc ip range uuid + */ + private String uuid; + /** + * @desc uuid of l3Network this ip range belongs to. See :ref:`L3NetworkInventory` + */ + private String l3NetworkUuid; + /** + * @desc max length of 255 characters + */ + private String name; + /** + * @desc max length of 2048 characters + */ + private String description; + /** + * @desc start ip address, in IPv4 + */ + private String startIp; + /** + * @desc end ip address, in IPv4 + */ + private String endIp; + + private Integer ipVersion; + + /** + * @desc the time this resource gets created + */ + private Timestamp createDate; + /** + * @desc last time this resource gets operated + */ + private Timestamp lastOpDate; + + public static ReservedIpRangeInventory valueOf(ReservedIpRangeVO vo) { + ReservedIpRangeInventory inv = new ReservedIpRangeInventory(); + inv.setUuid(vo.getUuid()); + inv.setL3NetworkUuid(vo.getL3NetworkUuid()); + inv.setName(vo.getName()); + inv.setDescription(vo.getDescription()); + inv.setIpVersion(vo.getIpVersion()); + inv.setStartIp(vo.getStartIp()); + inv.setEndIp(vo.getEndIp()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList(vos.size()); + for (ReservedIpRangeVO vo : vos) { + invs.add(ReservedIpRangeInventory.valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getStartIp() { + return startIp; + } + + public void setStartIp(String startIp) { + this.startIp = startIp; + } + + public String getEndIp() { + return endIp; + } + + public void setEndIp(String endIp) { + this.endIp = endIp; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public int getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + + @Override + public String toString() { + return JSONObjectUtil.toJsonString(this); + } + +} diff --git a/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..03a50ce428f --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeInventoryDoc_zh_cn.groovy @@ -0,0 +1,64 @@ +package org.zstack.header.network.l3 + +import java.lang.Integer +import java.sql.Timestamp + +doc { + + title "保留地址段清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.1.0" + } + field { + name "l3NetworkUuid" + desc "三层网络UUID" + type "String" + since "5.1.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.1.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.1.0" + } + field { + name "startIp" + desc "起始IP(包含在保留地址段内)" + type "String" + since "5.1.0" + } + field { + name "endIp" + desc "结束IP(包含在保留地址段内)" + type "String" + since "5.1.0" + } + field { + name "ipVersion" + desc "ip协议号" + type "Integer" + since "5.1.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.1.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.1.0" + } +} diff --git a/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeVO.java b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeVO.java new file mode 100644 index 00000000000..5d44d8ecae9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeVO.java @@ -0,0 +1,127 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ForeignKey.ReferenceOption; +import org.zstack.header.vo.Index; +import org.zstack.header.vo.ResourceVO; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.NetworkUtils; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@org.zstack.header.vo.EntityGraph( + parents = { + @EntityGraph.Neighbour(type = L3NetworkVO.class, myField = "l3NetworkUuid", targetField = "uuid") + } +) +public class ReservedIpRangeVO extends ResourceVO { + @Column + @ForeignKey(parentEntityClass = L3NetworkEO.class, onDeleteAction = ReferenceOption.CASCADE) + private String l3NetworkUuid; + + @Column + @Index + private String name; + + @Column + private String description; + + @Column + private Integer ipVersion; + + @Column + @Index + private String startIp; + + @Column + @Index + private String endIp; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getStartIp() { + return startIp; + } + + public void setStartIp(String startIp) { + this.startIp = startIp; + } + + public String getEndIp() { + return endIp; + } + + public void setEndIp(String endIp) { + this.endIp = endIp; + } + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + + public int size() { + if (getIpVersion() == IPv6Constants.IPv4) { + return NetworkUtils.getTotalIpInRange(getStartIp(), getEndIp()); + } else { + return 0; + } + } + +} diff --git a/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeVO_.java b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeVO_.java new file mode 100644 index 00000000000..fd09ae4b023 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/ReservedIpRangeVO_.java @@ -0,0 +1,19 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(ReservedIpRangeVO.class) +public class ReservedIpRangeVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute l3NetworkUuid; + public static volatile SingularAttribute description; + public static volatile SingularAttribute ipVersion; + public static volatile SingularAttribute startIp; + public static volatile SingularAttribute endIp; + public static volatile SingularAttribute lastOpDate; + public static volatile SingularAttribute createDate; +} diff --git a/header/src/main/java/org/zstack/header/network/l3/SdnControllerL3.java b/header/src/main/java/org/zstack/header/network/l3/SdnControllerL3.java new file mode 100644 index 00000000000..228b05aa98d --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/l3/SdnControllerL3.java @@ -0,0 +1,12 @@ +package org.zstack.header.network.l3; + +import org.zstack.header.core.Completion; + +import java.util.List; + +public interface SdnControllerL3 { + void createL3Network(L3NetworkInventory inv, List systemTags, Completion completion); + void deleteL3Network(L3NetworkInventory inv, Completion completion); + void createIpRange(IpRangeInventory inv, Completion completion); + void deleteIpRange(IpRangeInventory inv, Completion completion); +} diff --git a/header/src/main/java/org/zstack/header/network/l3/UsedIpInventory.java b/header/src/main/java/org/zstack/header/network/l3/UsedIpInventory.java index 2e9b72e303b..775dc66d9c5 100755 --- a/header/src/main/java/org/zstack/header/network/l3/UsedIpInventory.java +++ b/header/src/main/java/org/zstack/header/network/l3/UsedIpInventory.java @@ -35,6 +35,7 @@ public class UsedIpInventory implements Serializable { @APINoSee private String metaData; private long ipInLong; + private byte[] ipInBinary; private String vmNicUuid; private Timestamp createDate; private Timestamp lastOpDate; @@ -46,6 +47,7 @@ public static UsedIpInventory valueOf(UsedIpVO vo) { inv.setIpVersion(vo.getIpVersion()); inv.setIp(vo.getIp()); inv.setIpInLong(vo.getIpInLong()); + inv.setIpInBinary(vo.getIpInBinary()); inv.setIpRangeUuid(vo.getIpRangeUuid()); inv.setL3NetworkUuid(vo.getL3NetworkUuid()); inv.setGateway(vo.getGateway()); @@ -98,6 +100,13 @@ public void setIpInLong(long ipInLong) { this.ipInLong = ipInLong; } + public byte[] getIpInBinary() { + return ipInBinary; + } + + public void setIpInBinary(byte[] ipInBinary) { + this.ipInBinary = ipInBinary; + } public Timestamp getCreateDate() { return createDate; } diff --git a/header/src/main/java/org/zstack/header/network/l3/UsedIpInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/l3/UsedIpInventoryDoc_zh_cn.groovy index 9daec59ed05..1814dbb822b 100644 --- a/header/src/main/java/org/zstack/header/network/l3/UsedIpInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/l3/UsedIpInventoryDoc_zh_cn.groovy @@ -2,82 +2,87 @@ package org.zstack.header.network.l3 import java.lang.Integer import java.sql.Timestamp -import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "已使用IP的结构清单" field { name "uuid" desc "资源的UUID,唯一标示该资源" type "String" - since "0.6" + since "5.0.0" } field { name "ipRangeUuid" desc "IP段UUID" type "String" - since "0.6" + since "5.0.0" } field { name "l3NetworkUuid" desc "三层网络UUID" type "String" - since "0.6" + since "5.0.0" } field { name "ipVersion" - desc "IP协议号" + desc "" type "Integer" - since "3.1" + since "5.0.0" } field { name "ip" - desc "IP地址" + desc "" type "String" - since "0.6" + since "5.0.0" } field { name "netmask" - desc "网络掩码" + desc "" type "String" - since "0.6" + since "5.0.0" } field { name "gateway" - desc "网关地址" + desc "" type "String" - since "0.6" + since "5.0.0" } field { name "usedFor" - desc "" + desc "分配原因" type "String" - since "0.6" + since "5.0.0" } field { name "ipInLong" desc "" type "long" - since "0.6" + since "5.0.0" + } + field { + name "ipInBinary" + desc "" + type "byte[]" + since "5.2.0" } field { name "vmNicUuid" desc "云主机网卡UUID" type "String" - since "3.1" + since "5.0.0" } field { name "createDate" desc "创建时间" type "Timestamp" - since "0.6" + since "5.0.0" } field { name "lastOpDate" desc "最后一次修改时间" type "Timestamp" - since "0.6" + since "5.0.0" } } diff --git a/header/src/main/java/org/zstack/header/network/l3/UsedIpVO.java b/header/src/main/java/org/zstack/header/network/l3/UsedIpVO.java index 98239a0a146..c35346301ff 100755 --- a/header/src/main/java/org/zstack/header/network/l3/UsedIpVO.java +++ b/header/src/main/java/org/zstack/header/network/l3/UsedIpVO.java @@ -52,6 +52,10 @@ public class UsedIpVO { @Index private long ipInLong; + @Column + @Index + private byte[] ipInBinary; + @Column private String usedFor; @@ -111,6 +115,14 @@ public void setIpInLong(long ipInLong) { this.ipInLong = ipInLong; } + public byte[] getIpInBinary() { + return ipInBinary; + } + + public void setIpInBinary(byte[] ipInBinary) { + this.ipInBinary = ipInBinary; + } + public String getL3NetworkUuid() { return l3NetworkUuid; } diff --git a/header/src/main/java/org/zstack/header/network/l3/UsedIpVO_.java b/header/src/main/java/org/zstack/header/network/l3/UsedIpVO_.java index ac4c9dea4fc..4186a4a6d54 100755 --- a/header/src/main/java/org/zstack/header/network/l3/UsedIpVO_.java +++ b/header/src/main/java/org/zstack/header/network/l3/UsedIpVO_.java @@ -15,6 +15,7 @@ public class UsedIpVO_ { public static volatile SingularAttribute metaData; public static volatile SingularAttribute ipInLong; public static volatile SingularAttribute vmNicUuid; + public static volatile SingularAttribute gateway; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerConstant.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerConstant.java new file mode 100644 index 00000000000..b6a6ddbe6ad --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerConstant.java @@ -0,0 +1,66 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.configuration.PythonClass; + +/** + * Created by shixin on 09/17/2019. + */ +@PythonClass +public class SdnControllerConstant { + @PythonClass + public static final String HARDWARE_VXLAN_NETWORK_POOL_TYPE = "HardwareVxlanNetworkPool"; + @PythonClass + public static final String HARDWARE_VXLAN_NETWORK_TYPE = "HardwareVxlanNetwork"; + + public static final String DEFAULT_VENDOR_VERSION = "V1"; + + public static final String ACTION_CATEGORY = "SdnController"; + + public static final String SERVICE_ID = "SdnController"; + + public static final String H3C_VCFC_CONTROLLER = "H3C VCFC"; + + public static final String H3C_VCFC_VENDOR_VERSION_V1 = DEFAULT_VENDOR_VERSION; + public static final String H3C_VCFC_VENDOR_VERSION_V2 = "V2"; + + public static final String H3C_VCFC_DEFAULT_TENANT_NAME = "default"; + public static final String H3C_VCFC_DEFAULT_TENANT_TYPE = "default"; + + // H3C SDN Controller Tenant Status + public static final String H3C_SDN_CONTROLLER_TENANT_STATE_ENABLE = "Enabled"; + public static final String H3C_SDN_CONTROLLER_TENANT_STATE_DISABLE = "Disabled"; + + // H3C SDN Controller Default Tenant ID (cannot be deleted) + public static final String H3C_SDN_CONTROLLER_DEFAULT_TENANT_ID = "ffffffff-0000-0000-0000-000000000001"; + + public static final String TF_CONTROLLER = "TF"; + + public static final String SDN_CONTROLLER_VROUTER_PREFIX = "VR_"; + + public static final String DEFAULT_SDN_CONTROLLER_VERSION = "V1"; + + public enum Processes{ + Pre, + Post + } + + public enum Operations { + Init, + Create, + AttachToCluster, + DetachFromCluster, + Delete + } + + public enum ResourceTypes{ + SdnController, + VxlanNetworkPool, + VxlanNetwork + } + + public enum Params { + HARDWARE_VXLAN_POOLS, + VXLAN_NETWORK, + SDN_CONTROLLER, + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerDeletionMsg.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerDeletionMsg.java new file mode 100644 index 00000000000..104233ad9a8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerDeletionMsg.java @@ -0,0 +1,16 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.message.DeletionMessage; + +public class SdnControllerDeletionMsg extends DeletionMessage implements SdnControllerMessage { + String sdnControllerUuid; + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerDeletionReply.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerDeletionReply.java new file mode 100644 index 00000000000..950b69084b0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerDeletionReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.message.MessageReply; + +public class SdnControllerDeletionReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefInventory.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefInventory.java new file mode 100644 index 00000000000..840d2f72cda --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefInventory.java @@ -0,0 +1,126 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.host.HostInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = SdnControllerHostRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "host", inventoryClass = HostInventory.class, + foreignKey = "uuid", expandedInventoryKey = "hostUuid"), + @ExpandedQuery(expandedField = "sdnController", inventoryClass = SdnControllerInventory.class, + foreignKey = "sdnControllerUuid", expandedInventoryKey = "uuid"), +}) +public class SdnControllerHostRefInventory implements Serializable { + private String sdnControllerUuid; + private String hostUuid; + private String vSwitchType; + private String vtepIp; + private String nicPciAddresses; + private String nicDrivers; + private String netmask; + private String bondMode; + private String lacpMode; + + public static SdnControllerHostRefInventory valueOf(SdnControllerHostRefVO vo) { + SdnControllerHostRefInventory inv = new SdnControllerHostRefInventory(); + inv.setSdnControllerUuid(vo.getSdnControllerUuid()); + inv.setHostUuid(vo.getHostUuid()); + inv.setvSwitchType(vo.getvSwitchType()); + inv.setVtepIp(vo.getVtepIp()); + inv.setNetmask(vo.getNetmask()); + inv.setNicPciAddresses(vo.getNicPciAddresses()); + inv.setNicDrivers(vo.getNicDrivers()); + inv.setBondMode(vo.getBondMode()); + inv.setLacpMode(vo.getLacpMode()); + return inv; + } + + public static List valueOf(Collection vos) { + List lst = new ArrayList(vos.size()); + for (SdnControllerHostRefVO vo : vos) { + lst.add(SdnControllerHostRefInventory.valueOf(vo)); + } + return lst; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + public String getNicPciAddresses() { + return nicPciAddresses; + } + + public void setNicPciAddresses(String nicPciAddresses) { + this.nicPciAddresses = nicPciAddresses; + } + + public String getNicDrivers() { + return nicDrivers; + } + + public void setNicDrivers(String nicDrivers) { + this.nicDrivers = nicDrivers; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getBondMode() { + return bondMode; + } + + public void setBondMode(String bondMode) { + this.bondMode = bondMode; + } + + public String getLacpMode() { + return lacpMode; + } + + public void setLacpMode(String lacpMode) { + this.lacpMode = lacpMode; + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..d6fa745e440 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefInventoryDoc_zh_cn.groovy @@ -0,0 +1,63 @@ +package org.zstack.header.network.sdncontroller + + + +doc { + + title "SDN控制器与物理机关联关系清单" + + field { + name "sdnControllerUuid" + desc "SDN控制器Uuid" + type "String" + since "5.3.0" + } + field { + name "hostUuid" + desc "物理机UUID" + type "String" + since "5.3.0" + } + field { + name "vSwitchType" + desc "虚拟交换机类型" + type "String" + since "5.3.0" + } + field { + name "vtepIp" + desc "物理机VTEP IP" + type "String" + since "5.3.0" + } + field { + name "nicPciAddresses" + desc "物理机网卡和PCI地址映射" + type "String" + since "5.3.0" + } + field { + name "nicDrivers" + desc "物理机网卡和驱动类型映射" + type "String" + since "5.3.0" + } + field { + name "netmask" + desc "物理机VTEP IP掩码" + type "String" + since "5.3.0" + } + field { + name "bondMode" + desc "物理机网卡bond模式" + type "String" + since "5.3.0" + } + field { + name "lacpMode" + desc "物理机网卡LACP模式" + type "String" + since "5.3.0" + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefVO.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefVO.java new file mode 100644 index 00000000000..6d932d02d90 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefVO.java @@ -0,0 +1,163 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.host.HostEO; +import org.zstack.header.search.SqlTrigger; +import org.zstack.header.search.TriggerIndex; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.SoftDeletionCascade; +import org.zstack.header.vo.SoftDeletionCascades; + +import javax.persistence.*; + +/** + * Created by shixin.ruan on 09/30/2019. + */ +@Entity +@Table +@TriggerIndex +@SqlTrigger(foreignVOClass = SdnControllerVO.class, foreignVOJoinColumn = "sdnControllerUuid") +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = SdnControllerVO.class, joinColumn = "sdnControllerUuid"), + @SoftDeletionCascade(parent = HostEO.class, joinColumn = "hostUuid") +}) +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = SdnControllerVO.class, myField = "sdnControllerUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = HostEO.class, myField = "hostUuid", targetField = "uuid"), + } +) +public class SdnControllerHostRefVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + @ForeignKey(parentEntityClass = SdnControllerVO.class, onDeleteAction = ForeignKey.ReferenceOption.RESTRICT) + private String sdnControllerUuid; + + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String hostUuid; + + @Column + private String vSwitchType; + + @Column + private String vtepIp; + + @Column + private String netmask; + + @Column + private String nicPciAddresses; + + @Column + private String nicDrivers; + + @Column + private String bondMode; + + @Column + private String lacpMode; + + + public SdnControllerHostRefVO() { + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + public String getNicPciAddresses() { + return nicPciAddresses; + } + + public void setNicPciAddresses(String nicPciAddresses) { + this.nicPciAddresses = nicPciAddresses; + } + + public String getNicDrivers() { + return nicDrivers; + } + + public void setNicDrivers(String nicDrivers) { + this.nicDrivers = nicDrivers; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getBondMode() { + return bondMode; + } + + public void setBondMode(String bondMode) { + this.bondMode = bondMode; + } + + public String getLacpMode() { + return lacpMode; + } + + public void setLacpMode(String lacpMode) { + this.lacpMode = lacpMode; + } + + public static SdnControllerHostRefVO fromOther(SdnControllerHostRefVO vo) { + SdnControllerHostRefVO newRef = new SdnControllerHostRefVO(); + newRef.sdnControllerUuid = vo.getSdnControllerUuid(); + newRef.hostUuid = vo.getHostUuid(); + newRef.vSwitchType = vo.getvSwitchType(); + newRef.vtepIp = vo.getVtepIp(); + newRef.netmask = vo.getNetmask(); + newRef.bondMode = vo.getBondMode(); + newRef.nicPciAddresses = vo.nicPciAddresses; + newRef.nicDrivers = vo.getNicDrivers(); + newRef.lacpMode = vo.getLacpMode(); + + return newRef; + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefVO_.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefVO_.java new file mode 100644 index 00000000000..c0348a6efdf --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerHostRefVO_.java @@ -0,0 +1,18 @@ +package org.zstack.header.network.sdncontroller; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(SdnControllerHostRefVO.class) +public class SdnControllerHostRefVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute hostUuid; + public static volatile SingularAttribute sdnControllerUuid; + public static volatile SingularAttribute vSwitchType; + public static volatile SingularAttribute vtepIp; + public static volatile SingularAttribute netmask; + public static volatile SingularAttribute nicPciAddresses; + public static volatile SingularAttribute nicDrivers; + public static volatile SingularAttribute bondMode; + public static volatile SingularAttribute lacpMode; +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerInventory.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerInventory.java new file mode 100644 index 00000000000..9f364f79136 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerInventory.java @@ -0,0 +1,153 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = SdnControllerVO.class) +@PythonClassInventory +public class SdnControllerInventory implements Serializable { + private String uuid; + private String vendorType; + private String vendorVersion; + private String name; + private String description; + private String ip; + private String username; + private String password; + private SdnControllerStatus status; + private List hostRefs; + private Timestamp createDate; + private Timestamp lastOpDate; + + public SdnControllerInventory() { + } + + public SdnControllerInventory(SdnControllerVO vo) { + this.setUuid(vo.getUuid()); + this.setVendorType(vo.getVendorType()); + this.setVendorVersion(vo.getVendorVersion()); + this.setDescription(vo.getDescription()); + this.setName(vo.getName()); + this.setIp(vo.getIp()); + this.setUsername(vo.getUsername()); + this.setPassword(vo.getPassword()); + this.setStatus(vo.getStatus()); + this.setHostRefs(SdnControllerHostRefInventory.valueOf(vo.getHostRefVOS())); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + } + + public static SdnControllerInventory valueOf(SdnControllerVO vo) { + return new SdnControllerInventory(vo); + } + + public static List valueOf(Collection vos) { + List lst = new ArrayList(vos.size()); + for (SdnControllerVO vo : vos) { + lst.add(SdnControllerInventory.valueOf(vo)); + } + return lst; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVendorType() { + return vendorType; + } + + public void setVendorType(String vendorType) { + this.vendorType = vendorType; + } + + public String getVendorVersion() { + return vendorVersion; + } + + public void setVendorVersion(String vendorVersion) { + this.vendorVersion = vendorVersion; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public SdnControllerStatus getStatus() { + return status; + } + + public void setStatus(SdnControllerStatus status) { + this.status = status; + } + + public List getHostRefs() { + return hostRefs; + } + + public void setHostRefs(List hostRefs) { + this.hostRefs = hostRefs; + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..ca9a031f59e --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerInventoryDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.network.sdncontroller + + +doc { + + title "SDN控制器清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "3.7" + } + field { + name "vendorType" + desc "" + type "String" + since "3.7" + } + field { + name "vendorVersion" + desc "厂商版本" + type "String" + since "5.4" + } + field { + name "name" + desc "资源名称" + type "String" + since "3.7" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "3.7" + } + field { + name "ip" + desc "" + type "String" + since "3.7" + } + field { + name "username" + desc "" + type "String" + since "3.7" + } + field { + name "password" + desc "" + type "String" + since "3.7" + } + ref { + name "status" + path "org.zstack.header.network.sdncontroller.SdnControllerInventory.status" + desc "null" + type "SdnControllerStatus" + since "5.3.0" + clz SdnControllerStatus.class + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "3.7" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "3.7" + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerMessage.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerMessage.java new file mode 100644 index 00000000000..cddec39c551 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerMessage.java @@ -0,0 +1,5 @@ +package org.zstack.header.network.sdncontroller; + +public interface SdnControllerMessage { + String getSdnControllerUuid(); +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerRemoveHostMsg.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerRemoveHostMsg.java new file mode 100644 index 00000000000..69a11e7bdc6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerRemoveHostMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.message.NeedReplyMessage; + +public class SdnControllerRemoveHostMsg extends NeedReplyMessage implements SdnControllerMessage { + private String sdnControllerUuid; + private String hostUuid; + private String vSwitchType; + private boolean createChain = true; + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public boolean isCreateChain() { + return createChain; + } + + public void setCreateChain(boolean createChain) { + this.createChain = createChain; + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerRemoveHostReply.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerRemoveHostReply.java new file mode 100644 index 00000000000..9376a4d0649 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerRemoveHostReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.message.MessageReply; + +public class SdnControllerRemoveHostReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerStatus.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerStatus.java new file mode 100644 index 00000000000..5bc0c7ebda0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerStatus.java @@ -0,0 +1,7 @@ +package org.zstack.header.network.sdncontroller; + +public enum SdnControllerStatus { + Connecting, + Connected, + Disconnected +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerStatusDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerStatusDoc_zh_cn.groovy new file mode 100644 index 00000000000..c049e771f1b --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerStatusDoc_zh_cn.groovy @@ -0,0 +1,27 @@ +package org.zstack.header.network.sdncontroller + + + +doc { + + title "SDN控制器状态" + + field { + name "Connecting" + desc "连接中" + type "SdnControllerStatus" + since "5.3.0" + } + field { + name "Connected" + desc "已连接" + type "SdnControllerStatus" + since "5.3.0" + } + field { + name "Disconnected" + desc "已失联" + type "SdnControllerStatus" + since "5.3.0" + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerVO.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerVO.java new file mode 100644 index 00000000000..f9a911436d2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerVO.java @@ -0,0 +1,165 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.BaseResource; +import org.zstack.header.vo.NoView; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by shixin.ruan on 09/17/2019. + */ +@Entity +@Table +@BaseResource +public class SdnControllerVO extends ResourceVO implements OwnedByAccount, ToInventory { + @Transient + private String accountUuid; + + @Column + private String vendorType; + + @Column + private String vendorVersion; + + @Column + private String name; + + @Column + private String description; + + @Column + private String ip; + + @Column + private String username; + + @Column + private String password; + + @OneToMany(fetch=FetchType.EAGER) + @JoinColumn(name="sdnControllerUuid", insertable=false, updatable=false) + @NoView + private Set hostRefVOS = new HashSet(); + + @Column + @Enumerated(EnumType.STRING) + private SdnControllerStatus status; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public SdnControllerVO() { + } + + public String getVendorType() { + return vendorType; + } + + public void setVendorType(String vendorType) { + this.vendorType = vendorType; + } + + public String getVendorVersion() { + return vendorVersion; + } + + public void setVendorVersion(String vendorVersion) { + this.vendorVersion = vendorVersion; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public SdnControllerStatus getStatus() { + return status; + } + + public void setStatus(SdnControllerStatus status) { + this.status = status; + } + + public Set getHostRefVOS() { + return hostRefVOS; + } + + public void setHostRefVOS(Set hostRefVOS) { + this.hostRefVOS = hostRefVOS; + } +} diff --git a/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerVO_.java b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerVO_.java new file mode 100644 index 00000000000..27eb3abfbcb --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/sdncontroller/SdnControllerVO_.java @@ -0,0 +1,21 @@ +package org.zstack.header.network.sdncontroller; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(SdnControllerVO.class) +public class SdnControllerVO_ extends ResourceVO_ { + public static volatile SingularAttribute vendorType; + public static volatile SingularAttribute vendorVersion; + public static volatile SingularAttribute name; + public static volatile SingularAttribute description; + public static volatile SingularAttribute ip; + public static volatile SingularAttribute username; + public static volatile SingularAttribute password; + public static volatile SingularAttribute status; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsgDoc_zh_cn.groovy index c79aa25238b..33b24858fc4 100644 --- a/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/service/APIAttachNetworkServiceToL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "networkServices" @@ -39,7 +38,6 @@ doc { type "Map" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } @@ -68,4 +64,4 @@ doc { clz APIAttachNetworkServiceToL3NetworkEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsg.java b/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsg.java index 67d822f00db..00f2b148e2e 100755 --- a/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsg.java +++ b/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsg.java @@ -19,6 +19,7 @@ @Action(category = L3NetworkConstant.ACTION_CATEGORY) @RestRequest( path = "/l3-networks/{l3NetworkUuid}/network-services", + optionalPaths = "/l3-networks/{l3NetworkUuid}/network-services/{service}", method = HttpMethod.DELETE, responseClass = APIDetachNetworkServiceFromL3NetworkEvent.class ) @@ -31,10 +32,13 @@ public class APIDetachNetworkServiceFromL3NetworkMsg extends APIMessage implemen /** * @desc a map where key is network service provider uuid and value is list of network service types */ - @APIParam + @APIParam(required = false) @MapField(keyType = String.class, valueType = List.class) private Map> networkServices; + @APIParam(required = false) + private String service; + @Override public String getL3NetworkUuid() { return l3NetworkUuid; @@ -51,7 +55,15 @@ public Map> getNetworkServices() { public void setNetworkServices(Map> networkServices) { this.networkServices = networkServices; } - + + public String getService() { + return service; + } + + public void setService(String service) { + this.service = service; + } + public static APIDetachNetworkServiceFromL3NetworkMsg __example__() { APIDetachNetworkServiceFromL3NetworkMsg msg = new APIDetachNetworkServiceFromL3NetworkMsg(); @@ -60,7 +72,7 @@ public static APIDetachNetworkServiceFromL3NetworkMsg __example__() { msg.setL3NetworkUuid(uuid()); msg.setNetworkServices(m); - + msg.setService("PortForwarding"); return msg; } diff --git a/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsgDoc_zh_cn.groovy index a985754a3d9..3d58e4187e1 100644 --- a/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/service/APIDetachNetworkServiceFromL3NetworkMsgDoc_zh_cn.groovy @@ -12,6 +12,7 @@ doc { rest { request { url "DELETE /v1/l3-networks/{l3NetworkUuid}/network-services" + url "DELETE /v1/l3-networks/{l3NetworkUuid}/network-services/{service}" header (Authorization: 'OAuth the-session-uuid') @@ -29,7 +30,6 @@ doc { type "String" optional false since "0.6" - } column { name "networkServices" @@ -37,9 +37,8 @@ doc { desc "网络服务" location "body" type "Map" - optional false + optional true since "0.6" - } column { name "systemTags" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "service" + enclosedIn "" + desc "服务类型" + location "body" + type "String" + optional true + since "5.1.0" } } } diff --git a/header/src/main/java/org/zstack/header/network/service/APIGetNetworkServiceTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/service/APIGetNetworkServiceTypesMsgDoc_zh_cn.groovy index 81cbdaf2eed..c7f271645ef 100644 --- a/header/src/main/java/org/zstack/header/network/service/APIGetNetworkServiceTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/service/APIGetNetworkServiceTypesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceL3NetworkRefMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceL3NetworkRefMsgDoc_zh_cn.groovy index 00d645b20f6..1c7070dafb4 100644 --- a/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceL3NetworkRefMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceL3NetworkRefMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.service import org.zstack.header.network.service.APIQueryNetworkServiceL3NetworkRefReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询网络服务与三层网络引用(QueryNetworkServiceL3NetworkRef)" diff --git a/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceProviderMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceProviderMsgDoc_zh_cn.groovy index e2e3b8efbca..0cc54fcd55d 100644 --- a/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceProviderMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/network/service/APIQueryNetworkServiceProviderMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.network.service import org.zstack.header.network.service.APIQueryNetworkServiceProviderReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询网络服务模块(QueryNetworkServiceProvider)" diff --git a/header/src/main/java/org/zstack/header/network/service/AfterApplyFlatEipExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/AfterApplyFlatEipExtensionPoint.java index c013af92502..c643b7be0e4 100644 --- a/header/src/main/java/org/zstack/header/network/service/AfterApplyFlatEipExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/network/service/AfterApplyFlatEipExtensionPoint.java @@ -4,4 +4,5 @@ public interface AfterApplyFlatEipExtensionPoint { void AfterApplyFlatEip(List vipUuids, String hostUuid); + default void cleanGatewayArpEntry(String vmUuid, String gatewayIp) {}; } diff --git a/header/src/main/java/org/zstack/header/network/service/DhcpStruct.java b/header/src/main/java/org/zstack/header/network/service/DhcpStruct.java index bfc875959ef..c004ab1c5e2 100755 --- a/header/src/main/java/org/zstack/header/network/service/DhcpStruct.java +++ b/header/src/main/java/org/zstack/header/network/service/DhcpStruct.java @@ -24,6 +24,7 @@ public class DhcpStruct implements Serializable { private String dnsDomain; private Integer mtu; private String raMode; + private boolean enableRa; private String firstIp; private String endIP; private Integer prefixLength; @@ -141,6 +142,14 @@ public void setRaMode(String raMode) { this.raMode = raMode; } + public boolean isEnableRa() { + return enableRa; + } + + public void setEnableRa(boolean enableRa) { + this.enableRa = enableRa; + } + public String getFirstIp() { return firstIp; } diff --git a/header/src/main/java/org/zstack/header/network/service/DnsServiceExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/DnsServiceExtensionPoint.java new file mode 100644 index 00000000000..64d8e224826 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/service/DnsServiceExtensionPoint.java @@ -0,0 +1,9 @@ +package org.zstack.header.network.service; + +import org.zstack.header.network.l3.L3NetworkInventory; + +import java.util.List; + +public interface DnsServiceExtensionPoint { + List getDnsAddress(L3NetworkInventory inv); +} diff --git a/header/src/main/java/org/zstack/header/network/service/FlatDhcpGetDnsAddressExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/FlatDhcpGetDnsAddressExtensionPoint.java deleted file mode 100644 index ce70d687a78..00000000000 --- a/header/src/main/java/org/zstack/header/network/service/FlatDhcpGetDnsAddressExtensionPoint.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.zstack.header.network.service; - -import org.zstack.header.network.l3.L3NetworkInventory; - -import java.util.List; - -public interface FlatDhcpGetDnsAddressExtensionPoint { - List getDnsAddress(L3NetworkInventory inv); -} diff --git a/header/src/main/java/org/zstack/header/network/service/GetSdnControllerExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/GetSdnControllerExtensionPoint.java new file mode 100644 index 00000000000..42b45b254b7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/service/GetSdnControllerExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.network.service; + +import org.zstack.header.network.l3.SdnControllerL3; + +public interface GetSdnControllerExtensionPoint { + SdnControllerDhcp getSdnControllerDhcp(String l3Uuid); + SdnControllerL3 getSdnControllerL3(String l2Uuid); +} diff --git a/header/src/main/java/org/zstack/header/network/service/NetworkServiceDhcpBackend.java b/header/src/main/java/org/zstack/header/network/service/NetworkServiceDhcpBackend.java index b1a6c6fde18..77076cb400a 100755 --- a/header/src/main/java/org/zstack/header/network/service/NetworkServiceDhcpBackend.java +++ b/header/src/main/java/org/zstack/header/network/service/NetworkServiceDhcpBackend.java @@ -2,6 +2,7 @@ import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.vm.VmInstanceSpec; @@ -21,4 +22,8 @@ public interface NetworkServiceDhcpBackend { void releaseDhcpService(List dhcpStructsList, VmInstanceSpec spec, NoErrorCompletion completion); void vmDefaultL3NetworkChanged(VmInstanceInventory vm, String previousL3, String nowL3, Completion completion); + + void enableNetworkService(L3NetworkVO l3VO, List systemTags, Completion completion); + + void disableNetworkService(L3NetworkVO l3VO, Completion completion); } diff --git a/header/src/main/java/org/zstack/header/network/service/NetworkServiceExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/NetworkServiceExtensionPoint.java index d3f60f99908..0b2f066dde8 100755 --- a/header/src/main/java/org/zstack/header/network/service/NetworkServiceExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/network/service/NetworkServiceExtensionPoint.java @@ -2,8 +2,10 @@ import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.vm.VmInstanceSpec; +import java.util.List; import java.util.Map; /** @@ -25,4 +27,8 @@ public static enum NetworkServiceExtensionPosition { void applyNetworkService(VmInstanceSpec servedVm, Map data, Completion completion); void releaseNetworkService(VmInstanceSpec servedVm, Map data, NoErrorCompletion completion); + + void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion); + + void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion); } diff --git a/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java b/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java index 1512ba53865..852bd09c401 100755 --- a/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java +++ b/header/src/main/java/org/zstack/header/network/service/NetworkServiceProviderType.java @@ -8,6 +8,8 @@ public class NetworkServiceProviderType { private static Map types = Collections.synchronizedMap(new HashMap()); private final String typeName; + private boolean createDhcpNameSpace = true; + private boolean allocateDhcpServerIp = true; public NetworkServiceProviderType(String typeName) { this.typeName = typeName; @@ -29,7 +31,7 @@ public String toString() { @Override public boolean equals(Object t) { - if (t == null || !(t instanceof NetworkServiceProviderType)) { + if (!(t instanceof NetworkServiceProviderType)) { return false; } @@ -37,6 +39,22 @@ public boolean equals(Object t) { return type.toString().equals(typeName); } + public boolean isCreateDhcpNameSpace() { + return createDhcpNameSpace; + } + + public void setCreateDhcpNameSpace(boolean createDhcpNameSpace) { + this.createDhcpNameSpace = createDhcpNameSpace; + } + + public boolean isAllocateDhcpServerIp() { + return allocateDhcpServerIp; + } + + public void setAllocateDhcpServerIp(boolean allocateDhcpServerIp) { + this.allocateDhcpServerIp = allocateDhcpServerIp; + } + @Override public int hashCode() { return typeName.hashCode(); diff --git a/header/src/main/java/org/zstack/header/network/service/PackageInfo.java b/header/src/main/java/org/zstack/header/network/service/PackageInfo.java index f362ba8b43f..6b10c8e741d 100755 --- a/header/src/main/java/org/zstack/header/network/service/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/network/service/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "网络服务") +@PackageAPIInfo( + APICategoryName = "网络服务", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/network/service/SdnControllerDhcp.java b/header/src/main/java/org/zstack/header/network/service/SdnControllerDhcp.java new file mode 100644 index 00000000000..065d90e17d9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/service/SdnControllerDhcp.java @@ -0,0 +1,52 @@ +package org.zstack.header.network.service; + +import org.zstack.header.core.Completion; +import org.zstack.header.network.l3.IpRangeInventory; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; + +import java.util.List; + +/** + * 该接口定义了 SDN 控制器处理 DHCP 服务的方法。 + * 实现该接口的类负责在 SDN 环境中分配、启用和禁用 DHCP 服务。 + + */ +public interface SdnControllerDhcp { + + /** + * 为 L3 网络分配 DHCP 服务并启用 + * @param vo L3 网络 VO 对象 + * @param systemTags 系统标签列表 + * @param completion 操作完成后的回调 + * */ + + void allocateDhcpAndEnableDhcp(L3NetworkVO vo, List systemTags, Completion completion); + + /** + * 启用指定 L3 网络的 DHCP 服务 + * @param l3_min L3 网络索引 + * @param l3_max L3 网络索引 + * @param invs L3 网络清单列表 + * @param sync 是否同步操作 + * @param completion 操作完成后的回调 + * */ + + void enableDhcp(long l3Min, long l3Max, List invs, boolean sync, Completion completion); + + /** + * 启用指定 L3 网络的 DHCP 服务 + * @param invs L3 网络清单列表 + * @param completion 操作完成后的回调 + * */ + + void enableDhcp(List invs, Completion completion); + + /** + * 禁用指定 L3 网络的 DHCP 服务 + * @param invs L3 网络清单列表 + * @param ipversion IP 版本 + * @param completion 操作完成后的回调 + * */ + + void disableDhcp(List invs, int ipversion, Completion completion); +} diff --git a/header/src/main/java/org/zstack/header/network/service/VirtualRouterHaGroupExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/VirtualRouterHaGroupExtensionPoint.java index 9f46c2ed535..a7a97000597 100644 --- a/header/src/main/java/org/zstack/header/network/service/VirtualRouterHaGroupExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/network/service/VirtualRouterHaGroupExtensionPoint.java @@ -23,6 +23,7 @@ public interface VirtualRouterHaGroupExtensionPoint { void attachNetworkServiceToHaRouter(String type, List uuids, String vrUuid); void attachNetworkServiceToHaRouter(String type, List uuids, String vrUuid, boolean override); void detachNetworkServiceFromHaRouter(String type, List uuids, String vrUuid); + List getAllVrUuidsFromNetworkService(String type, String Uuid); List getHaVrUuidsFromNetworkService(String type, String Uuid); List getHaVrUuidsFromNetworkService(String type); List getNetworkServicesFromHaVrUuid(String type, String vrUuid); diff --git a/header/src/main/java/org/zstack/header/network/service/VirtualRouterLoadBalancerExtensionPoint.java b/header/src/main/java/org/zstack/header/network/service/VirtualRouterLoadBalancerExtensionPoint.java new file mode 100644 index 00000000000..d3840068954 --- /dev/null +++ b/header/src/main/java/org/zstack/header/network/service/VirtualRouterLoadBalancerExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.network.service; + +import org.zstack.header.core.Completion; + +/** + * Created by boce.wang on 11/25/2024. + */ +public interface VirtualRouterLoadBalancerExtensionPoint { + void afterRefreshLoadBalancerListener(String vrUuid, Completion completion); +} diff --git a/header/src/main/java/org/zstack/header/observabilityServer/ObservabilityServerConstant.java b/header/src/main/java/org/zstack/header/observabilityServer/ObservabilityServerConstant.java new file mode 100644 index 00000000000..76ff8dfa432 --- /dev/null +++ b/header/src/main/java/org/zstack/header/observabilityServer/ObservabilityServerConstant.java @@ -0,0 +1,17 @@ +package org.zstack.header.observabilityServer; + +import org.zstack.header.configuration.PythonClass; + +/** + * Created by boce.wang on 11/25/2024. + */ +public interface ObservabilityServerConstant { + @PythonClass + public static final String OBSERVABILITY_SERVER_VM_TYPE = "ObservabilityServer"; + @PythonClass + public static final String OBSERVABILITY_SERVER_OFFERING_TYPE = "ObservabilityServer"; + @PythonClass + public static final String SERVICE_ID = "observabilityServer"; + public static final String ACTION_CATEGORY = "observabilityServer"; + +} diff --git a/header/src/main/java/org/zstack/header/os/OSArchitecture.java b/header/src/main/java/org/zstack/header/os/OSArchitecture.java new file mode 100644 index 00000000000..57776bf301f --- /dev/null +++ b/header/src/main/java/org/zstack/header/os/OSArchitecture.java @@ -0,0 +1,65 @@ +package org.zstack.header.os; + +import java.util.Locale; + +/** + * Represents the operating system architecture type obtained from System.getProperty("os.arch"). + */ +public enum OSArchitecture { + X86_64(new String[]{"amd64", "x86_64"}, "x86_64"), + AARCH64(new String[]{"aarch64"}, "aarch64"), + LOONGARCH64(new String[]{"loongarch64"}, "loongarch64"), + MIPS64EL(new String[]{"mips64el"}, "mips64el"), + UNKNOWN(null, "unknown"); + + private final String[] archNames; + private final String normalizedName; + + /** + * Private constructor for OSArchitecture enum. + * + * @param archNames An array of possible raw architecture names from System.getProperty("os.arch"). Can be null for UNKNOWN. + * @param normalizedName The standardized, simplified name for this architecture. + */ + OSArchitecture(String[] archNames, String normalizedName) { + this.archNames = archNames; + this.normalizedName = normalizedName; + } + + /** + * Gets the current OS architecture based on System.getProperty("os.arch"). + * Returns UNKNOWN if no match is found. + * + * @return The corresponding OSArchitecture enum constant. + */ + public static OSArchitecture getCurrent() { + String currentArch = System.getProperty("os.arch"); + if (currentArch == null) { + return UNKNOWN; + } + + String lowerCaseArch = currentArch.toLowerCase(Locale.ROOT); + + for (OSArchitecture arch : values()) { + if (arch.archNames == null) { + continue; + } + for (String name : arch.archNames) { + if (lowerCaseArch.equals(name.toLowerCase())) { + return arch; + } + } + } + return UNKNOWN; + } + + /** + * Returns a normalized string representation of the architecture, as defined in the enum constant. + * For example, for X86_64, this will always return "x86_64". + * + * @return A normalized string name for the architecture. + */ + public String normalizedArchName() { + return this.normalizedName; + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/other/APILoginAuditor.java b/header/src/main/java/org/zstack/header/other/APILoginAuditor.java index cc3d7f03c07..a37f3ab5ccc 100644 --- a/header/src/main/java/org/zstack/header/other/APILoginAuditor.java +++ b/header/src/main/java/org/zstack/header/other/APILoginAuditor.java @@ -9,8 +9,6 @@ */ public interface APILoginAuditor { class LoginResult { - - public String clientIp; public String clientBrowser; public String resourceUuid; diff --git a/header/src/main/java/org/zstack/header/rest/RESTFacade.java b/header/src/main/java/org/zstack/header/rest/RESTFacade.java index 863a5390d07..e9d3120f9d6 100755 --- a/header/src/main/java/org/zstack/header/rest/RESTFacade.java +++ b/header/src/main/java/org/zstack/header/rest/RESTFacade.java @@ -4,6 +4,8 @@ import org.apache.http.impl.client.HttpClients; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; @@ -34,6 +36,8 @@ public interface RESTFacade { void asyncJsonDelete(String url, String body, Map headers, AsyncRESTCallback callback, TimeUnit unit, long timeout); void asyncJsonGet(String url, String body, Map headers, AsyncRESTCallback callback, TimeUnit unit, long timeout); + void asyncJson(final String url, final String body, Map headers, HttpMethod method, final AsyncRESTCallback callback, final TimeUnit unit, final long timeout); + T syncJsonPost(String url, Object body, Class returnClass); T syncJsonPost(String url, Object body, Class returnClass, TimeUnit unit, long timeout); @@ -56,6 +60,14 @@ public interface RESTFacade { T syncJsonGet(String url, String body, Map headers, Class returnClass, TimeUnit unit, long timeout); + T syncJsonPut(String url, String body, Map headers, Class returnClass); + + T syncJsonPut(String url, String body, Map headers, Class returnClass, TimeUnit unit, long timeout); + + RestHttp http(Class returnClass); + + ResponseEntity syncRawJson(String url, HttpEntity req, HttpMethod method, TimeUnit unit, long timeout); + HttpHeaders syncHead(String url); HttpEntity httpServletRequestToHttpEntity(HttpServletRequest req); diff --git a/header/src/main/java/org/zstack/header/rest/RestHttp.java b/header/src/main/java/org/zstack/header/rest/RestHttp.java new file mode 100644 index 00000000000..7c7527698fc --- /dev/null +++ b/header/src/main/java/org/zstack/header/rest/RestHttp.java @@ -0,0 +1,221 @@ +package org.zstack.header.rest; + +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.zstack.header.Confirm; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorableValue; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.utils.DebugUtils; +import org.zstack.utils.TypeUtils; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Function; + +import static org.zstack.header.Confirm.*; + +public class RestHttp { + public final Class returnClass; + + // basic info + protected String path; + protected Map headers = new HashMap<>(); + protected String body; + protected HttpMethod method; + + // request parameters + protected boolean timeoutEnabled = true; + protected long timeoutInMillis = 1800000L; // -1 means never timeout + protected boolean retry = true; + protected int retryTimes = 5; + protected int retryIntervalInSeconds = 1; + + // response handlers + protected BiFunction, ErrorCode> errorCodeBuilder; + protected Function, ResponseEntity> handler; + protected final List> retryIfExceptionMatched = new ArrayList<>(); + + public RestHttp(Class returnClass) { + this.returnClass = Objects.requireNonNull(returnClass); + } + + public RestHttp withPath(String path) { + this.path = path; + return this; + } + + public RestHttp withHeader(String key, String value) { + this.headers.put(key, value); + return this; + } + + public RestHttp withBody(String body) { + this.body = body; + return this; + } + + public RestHttp withBodyJson(Object body) { + this.body = JSONObjectUtil.toJsonString(body); + return this; + } + + public RestHttp withTimeoutInMillis(long timeoutInMillis) { + this.timeoutEnabled = true; + this.timeoutInMillis = timeoutInMillis; + return this; + } + + /** + * Not recommended + */ + public RestHttp withoutTimeout() { + this.timeoutEnabled = false; + this.timeoutInMillis = -1L; + return this; + } + + public RestHttp withRetry(int retryTimes, int retryIntervalInSeconds) { + this.retry = true; + this.retryTimes = retryTimes; + this.retryIntervalInSeconds = retryIntervalInSeconds; + return this; + } + + public RestHttp withoutRetry() { + this.retry = false; + return this; + } + + public RestHttp retryIfException(Function checker) { + this.retryIfExceptionMatched.add(checker); + return this; + } + + public RestHttp retryIfException(Class... classes) { + return retryIfException(e -> TypeUtils.isTypeOf(e, classes) ? Yes : No); + } + + public RestHttp withHandler(Function, ResponseEntity> handler) { + this.handler = handler; + return this; + } + + public RestHttp withErrorCodeBuilder(BiFunction, ErrorCode> errorCodeBuilder) { + this.errorCodeBuilder = errorCodeBuilder; + return this; + } + + @SuppressWarnings("unchecked") + protected ErrorableValue handleWithErrorCode() { + try { + DebugUtils.Assert(this.handler != null, "handler cannot be null"); + final ResponseEntity entity = this.handler.apply(this); + if (returnClass == Void.class) { + return ErrorableValue.of(null); + } + + return returnClass == String.class ? + ((ErrorableValue) ErrorableValue.of(entity.getBody())) : + ErrorableValue.of(JSONObjectUtil.toObject(entity.getBody(), returnClass)); + } catch (OperationFailureException e) { + return ErrorableValue.ofErrorCode(e.getErrorCode()); + } + } + + public T get() { + return call(HttpMethod.GET); + } + + public ErrorableValue getWithErrorCode() { + return callWithErrorCode(HttpMethod.GET); + } + + public T post() { + return call(HttpMethod.POST); + } + + public ErrorableValue postWithErrorCode() { + return callWithErrorCode(HttpMethod.POST); + } + + public T put() { + return call(HttpMethod.PUT); + } + + public ErrorableValue putWithErrorCode() { + return callWithErrorCode(HttpMethod.PUT); + } + + public T delete() { + return call(HttpMethod.DELETE); + } + + public ErrorableValue deleteWithErrorCode() { + return callWithErrorCode(HttpMethod.DELETE); + } + + public T call(HttpMethod method) { + this.method = method; + ErrorableValue result = handleWithErrorCode(); + if (!result.isSuccess()) { + throw new OperationFailureException(result.error); + } + return result.result; + } + + public ErrorableValue callWithErrorCode(HttpMethod method) { + this.method = method; + return handleWithErrorCode(); + } + + public ResponseEntity exchange(HttpMethod method) { + this.method = method; + return this.handler.apply(this); + } + + public String getPath() { + return path; + } + + public Map getHeaders() { + return headers; + } + + public String getBody() { + return body; + } + + public HttpMethod getMethod() { + return method; + } + + public boolean isTimeoutEnabled() { + return timeoutEnabled; + } + + public long getTimeoutInMillis() { + return timeoutInMillis; + } + + public boolean isRetry() { + return retry; + } + + public int getRetryTimes() { + return retryTimes; + } + + public int getRetryIntervalInSeconds() { + return retryIntervalInSeconds; + } + + public BiFunction, ErrorCode> getErrorCodeBuilder() { + return errorCodeBuilder; + } + + public List> getRetryIfExceptionMatched() { + return retryIfExceptionMatched; + } +} diff --git a/header/src/main/java/org/zstack/header/rest/RestRequest.java b/header/src/main/java/org/zstack/header/rest/RestRequest.java index d606b570170..e2e062e4624 100755 --- a/header/src/main/java/org/zstack/header/rest/RestRequest.java +++ b/header/src/main/java/org/zstack/header/rest/RestRequest.java @@ -21,4 +21,5 @@ String[] mappingFields() default {}; Class responseClass(); String category() default ""; + String morphTransform() default ""; } diff --git a/header/src/main/java/org/zstack/header/storage/addon/BlockRemoteTarget.java b/header/src/main/java/org/zstack/header/storage/addon/BlockRemoteTarget.java new file mode 100644 index 00000000000..50e9669eba9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/BlockRemoteTarget.java @@ -0,0 +1,19 @@ +package org.zstack.header.storage.addon; + +public class BlockRemoteTarget implements RemoteTarget { + protected String installPath; + + @Override + public String getInstallPath() { + return installPath; + } + + @Override + public String getResourceURI() { + return null; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/ImageDescriptor.java b/header/src/main/java/org/zstack/header/storage/addon/ImageDescriptor.java new file mode 100644 index 00000000000..4d1ad59a501 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/ImageDescriptor.java @@ -0,0 +1,49 @@ +package org.zstack.header.storage.addon; + +public class ImageDescriptor { + private long size; + private Long actualSize; + private String installPath; + private String md5sum; + private String format; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public Long getActualSize() { + return actualSize; + } + + public void setActualSize(Long actualSize) { + this.actualSize = actualSize; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public String getMd5sum() { + return md5sum; + } + + public void setMd5sum(String md5sum) { + this.md5sum = md5sum; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/IscsiRemoteTarget.java b/header/src/main/java/org/zstack/header/storage/addon/IscsiRemoteTarget.java new file mode 100644 index 00000000000..c35816b09ae --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/IscsiRemoteTarget.java @@ -0,0 +1,125 @@ +package org.zstack.header.storage.addon; + +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.net.URI; + +public class IscsiRemoteTarget extends BlockRemoteTarget { + private final static CLogger logger = Utils.getLogger(IscsiRemoteTarget.class); + private String transport = "tcp"; + + private String iqn; + + private String ip; + + private int port; + + private String diskId; + + private String diskIdType; + + public String getDiskIdType() { + return diskIdType; + } + + public void setDiskIdType(String diskIdType) { + this.diskIdType = diskIdType; + } + + public String getTransport() { + return transport; + } + + public void setTransport(String transport) { + this.transport = transport; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + @Override + public String getResourceURI() { + return String.format("iscsi://%s:%s/%s/%s_%s", ip, port, iqn, diskIdType, diskId); + } + + public String getDiskId() { + return diskId; + } + + public void setDiskId(String diskId) { + this.diskId = diskId; + } + + public String getIqn() { + return iqn; + } + + public void setIqn(String iqn) { + this.iqn = iqn; + } + + public enum DiskIdType { + wwn, + serial + } + + public static IscsiRemoteTarget fromUri(String uriString) { + try { + URI uri = URI.create(uriString); + + if (!"iscsi".equalsIgnoreCase(uri.getScheme())) { + logger.info("Invalid URI scheme. Expected 'iscsi', got: " + uri.getScheme()); + return null; + } + + IscsiRemoteTarget target = new IscsiRemoteTarget(); + String authority = uri.getAuthority(); + if (authority == null || authority.isEmpty()) { + logger.info("Invalid URI authority: " + uri.getAuthority()); + return null; + } + String[] serverHostNames = authority.split(":")[0].split(","); + target.setIp(serverHostNames[0]); + target.setPort(uri.getPort() == -1 ? 3260 : uri.getPort()); + + // parse: /{iqn}/{diskIdType}_{diskId} + String path = uri.getPath(); + if (path != null && path.startsWith("/")) { + String[] pathParts = path.substring(1).split("/"); + if (pathParts.length >= 2) { + target.setIqn(pathParts[0]); + String[] diskParts = pathParts[1].split("_", 2); + if (diskParts.length == 2) { + target.setDiskIdType(diskParts[0]); + target.setDiskId(diskParts[1]); + } else { + logger.info("Invalid diskId format in URI path: " + pathParts[1]); + return null; + } + } else { + logger.info("Invalid URI path format: " + path); + return null; + } + } + + return target; + } catch (Exception e) { + logger.error("Failed to parse URI: " + uriString, e); + return null; + } + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/NbdRemoteTarget.java b/header/src/main/java/org/zstack/header/storage/addon/NbdRemoteTarget.java new file mode 100644 index 00000000000..b1224c2b84a --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/NbdRemoteTarget.java @@ -0,0 +1,33 @@ +package org.zstack.header.storage.addon; + +public class NbdRemoteTarget extends BlockRemoteTarget { + private String ip; + private int port; + private String installPath; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + @Override + public String getInstallPath() { + return installPath; + } + + @Override + public String getResourceURI() { + return String.format("nbd://%s:%s", ip, port); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/NodeHealthy.java b/header/src/main/java/org/zstack/header/storage/addon/NodeHealthy.java new file mode 100644 index 00000000000..14a7385d152 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/NodeHealthy.java @@ -0,0 +1,29 @@ +package org.zstack.header.storage.addon; + +import org.zstack.header.volume.VolumeProtocol; + +import java.util.HashMap; +import java.util.Map; + +public class NodeHealthy { + private Map healthy; + + public void setHealthy(Map healthy) { + this.healthy = healthy; + } + + public Map getHealthy() { + return healthy; + } + + public StorageHealthy getHealthy(VolumeProtocol protocol) { + return healthy.get(protocol); + } + + public void setHealthy(VolumeProtocol protocol, StorageHealthy healthy) { + if (this.healthy == null) { + this.healthy = new HashMap<>(); + } + this.healthy.put(protocol, healthy); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/NvmeRemoteTarget.java b/header/src/main/java/org/zstack/header/storage/addon/NvmeRemoteTarget.java new file mode 100644 index 00000000000..6e9a8729ced --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/NvmeRemoteTarget.java @@ -0,0 +1,70 @@ +package org.zstack.header.storage.addon; + +import java.net.URLEncoder; + +public class NvmeRemoteTarget extends BlockRemoteTarget { + private String transport; + + private String nqn; + + private String ip; + + private int port; + + private String hostNqn; + + private String diskId; + + public String getTransport() { + return transport; + } + + public void setTransport(String transport) { + this.transport = transport; + } + + public String getNqn() { + return nqn; + } + + public void setNqn(String nqn) { + this.nqn = nqn; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getHostNqn() { + return hostNqn; + } + + public void setHostNqn(String hostNqn) { + this.hostNqn = hostNqn; + } + + @Override + public String getResourceURI() { + return String.format("nvme://%s@%s:%s/%s/%s", URLEncoder.encode(hostNqn), ip, port, nqn, diskId); + } + + public String getDiskId() { + return diskId; + } + + public void setDiskId(String diskId) { + this.diskId = diskId; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/RbdRemoteTarget.java b/header/src/main/java/org/zstack/header/storage/addon/RbdRemoteTarget.java new file mode 100644 index 00000000000..148ba7e7058 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/RbdRemoteTarget.java @@ -0,0 +1,15 @@ +package org.zstack.header.storage.addon; + +public class RbdRemoteTarget implements RemoteTarget { + private String installPath; + + @Override + public String getInstallPath() { + return installPath; + } + + @Override + public String getResourceURI() { + return null; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/RemoteTarget.java b/header/src/main/java/org/zstack/header/storage/addon/RemoteTarget.java new file mode 100644 index 00000000000..e4edf6ac2b0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/RemoteTarget.java @@ -0,0 +1,13 @@ +package org.zstack.header.storage.addon; + +public interface RemoteTarget { + // unique identifier - how to identify image/volume. + String getInstallPath(); + + // URI to access the image/volume, e.g.: + // - sftp://host/path/to/file + // - nbd://host/export-name + // - rbd://pool/image + // - nvme://host-nqn@ip:port/nqn/diskId + String getResourceURI(); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/SingleFlightExecutor.java b/header/src/main/java/org/zstack/header/storage/addon/SingleFlightExecutor.java new file mode 100644 index 00000000000..60a47413db7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/SingleFlightExecutor.java @@ -0,0 +1,21 @@ +package org.zstack.header.storage.addon; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +public interface SingleFlightExecutor { + /** + * the last parameter of m must be ReturnValueCompletion, return type must be void + */ + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + @interface SingleFlight { + } + + /** + * @return the zstack uuid of the resource + */ + String getResourceUuid(); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/StorageCapacity.java b/header/src/main/java/org/zstack/header/storage/addon/StorageCapacity.java new file mode 100644 index 00000000000..59388eaa758 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/StorageCapacity.java @@ -0,0 +1,31 @@ +package org.zstack.header.storage.addon; + +public class StorageCapacity { + private long totalCapacity; + private long availableCapacity; + private StorageHealthy healthy; + + public long getTotalCapacity() { + return totalCapacity; + } + + public void setTotalCapacity(long totalCapacity) { + this.totalCapacity = totalCapacity; + } + + public long getAvailableCapacity() { + return availableCapacity; + } + + public void setAvailableCapacity(long availableCapacity) { + this.availableCapacity = availableCapacity; + } + + public StorageHealthy getHealthy() { + return healthy; + } + + public void setHealthy(StorageHealthy healthy) { + this.healthy = healthy; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/StorageHealthy.java b/header/src/main/java/org/zstack/header/storage/addon/StorageHealthy.java new file mode 100644 index 00000000000..fbbcab6dc0d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/StorageHealthy.java @@ -0,0 +1,5 @@ +package org.zstack.header.storage.addon; + +public enum StorageHealthy { + Ok, Unknown, Warn, Failed +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageEvent.java b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageEvent.java new file mode 100755 index 00000000000..77012467f56 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageEvent.java @@ -0,0 +1,37 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.rest.RestResponse; +import org.zstack.header.storage.backup.APIAddBackupStorageEvent; + +@RestResponse(allTo = "inventory") +public class APIAddExternalBackupStorageEvent extends APIAddBackupStorageEvent { + public APIAddExternalBackupStorageEvent(String apiId) { + super(apiId); + } + + public APIAddExternalBackupStorageEvent() { + super(null); + } + + private ExternalBackupStorageInventory inventory; + + public ExternalBackupStorageInventory getInventory() { + return inventory; + } + + public void setInventory(ExternalBackupStorageInventory inventory) { + this.inventory = inventory; + } + + public static APIAddExternalBackupStorageEvent __example__() { + APIAddExternalBackupStorageEvent event = new APIAddExternalBackupStorageEvent(); + ExternalBackupStorageInventory ssInventory = new ExternalBackupStorageInventory(); + ssInventory.setAvailableCapacity(1099511627776L); + ssInventory.setTotalCapacity(1099511627776L); + ssInventory.setUrl("zbd:pool/my-vol:/etc/foo.conf"); + ssInventory.setIdentity("zbd"); + event.setInventory(ssInventory); + return event; + } + +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..eeac8791cbf --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.storage.addon.backup + +import org.zstack.header.storage.addon.backup.ExternalBackupStorageInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "添加外部镜像存储结果" + + ref { + name "inventory" + path "org.zstack.header.storage.addon.backup.APIAddExternalBackupStorageEvent.inventory" + desc "null" + type "ExternalBackupStorageInventory" + since "5.0.0" + clz ExternalBackupStorageInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.header.storage.addon.backup.APIAddExternalBackupStorageEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageMsg.java b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageMsg.java new file mode 100755 index 00000000000..08f50f3c1d2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageMsg.java @@ -0,0 +1,41 @@ +package org.zstack.header.storage.addon.backup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.backup.APIAddBackupStorageMsg; +import org.zstack.header.storage.backup.BackupStorageConstant; + +@RestRequest( + path = "/backup-storage/addon", + method = HttpMethod.POST, + responseClass = APIAddExternalBackupStorageEvent.class, + parameterName = "params" +) +public class APIAddExternalBackupStorageMsg extends APIAddBackupStorageMsg { + @APIParam(maxLength = 255, emptyString = false) + private String identity; + + @Override + public String getType() { + return BackupStorageConstant.EXTERNAL_BACKUP_STORAGE_TYPE; + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public static APIAddExternalBackupStorageMsg __example__() { + APIAddExternalBackupStorageMsg msg = new APIAddExternalBackupStorageMsg(); + msg.setIdentity("zbd"); + msg.setName("my backup storage"); + msg.setUrl("zbd:pool/my-vol:/etc/foo.conf"); + + return msg; + } + +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..0befd27b794 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/APIAddExternalBackupStorageMsgDoc_zh_cn.groovy @@ -0,0 +1,121 @@ +package org.zstack.header.storage.addon.backup + +import org.zstack.header.storage.addon.backup.APIAddExternalBackupStorageEvent + +doc { + title "AddExternalBackupStorage" + + category "storage.backup" + + desc """添加外部镜像存储""" + + rest { + request { + url "POST /v1/backup-storage/addon" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAddExternalBackupStorageMsg.class + + desc """""" + + params { + + column { + name "identity" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "url" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "type" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "importImages" + enclosedIn "params" + desc "" + location "body" + type "boolean" + optional true + since "5.0.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIAddExternalBackupStorageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/BackupStorageController.java b/header/src/main/java/org/zstack/header/storage/addon/backup/BackupStorageController.java new file mode 100644 index 00000000000..0c12e0b1fa9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/BackupStorageController.java @@ -0,0 +1,19 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.image.ImageInventory; +import org.zstack.header.storage.addon.ImageDescriptor; +import org.zstack.header.storage.addon.StorageCapacity; +import org.zstack.header.storage.addon.StorageHealthy; + +public interface BackupStorageController { + String getIdentity(); + void connect(boolean newAdded, String url, Completion comp); + + void reportCapacity(ReturnValueCompletion comp); + void reportHealthy(ReturnValueCompletion comp); + + void importImage(ImageInventory image, ReturnValueCompletion comp); + void cancelImport(ImageInventory image, Completion comp); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageInventory.java b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageInventory.java new file mode 100644 index 00000000000..3a3dfc34386 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageInventory.java @@ -0,0 +1,44 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; +import org.zstack.header.search.Parent; +import org.zstack.header.storage.backup.BackupStorageConstant; +import org.zstack.header.storage.backup.BackupStorageInventory; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Inventory(mappingVOClass = ExternalBackupStorageVO.class, collectionValueOfMethod="valueOf1", + parent = {@Parent(inventoryClass = BackupStorageInventory.class, type = BackupStorageConstant.EXTERNAL_BACKUP_STORAGE_TYPE)}) +@PythonClassInventory +public class ExternalBackupStorageInventory extends BackupStorageInventory { + private String identity; + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + protected ExternalBackupStorageInventory(ExternalBackupStorageVO vo) { + super(vo); + identity = vo.getIdentity(); + } + + public ExternalBackupStorageInventory() { + } + + public static ExternalBackupStorageInventory valueOf(ExternalBackupStorageVO vo) { + return new ExternalBackupStorageInventory(vo); + } + + public static List valueOf1(Collection vos) { + return vos.stream() + .map(ExternalBackupStorageInventory::valueOf) + .collect(Collectors.toList()); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..8b5c0e5e536 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageInventoryDoc_zh_cn.groovy @@ -0,0 +1,88 @@ +package org.zstack.header.storage.addon.backup + +import java.lang.Long +import java.sql.Timestamp + +doc { + + title "外部镜像存储" + + field { + name "identity" + desc "" + type "String" + since "5.0.0" + } + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.0.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.0.0" + } + field { + name "url" + desc "" + type "String" + since "5.0.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.0.0" + } + field { + name "totalCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "availableCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "type" + desc "" + type "String" + since "5.0.0" + } + field { + name "state" + desc "" + type "String" + since "5.0.0" + } + field { + name "status" + desc "" + type "String" + since "5.0.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.0.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.0.0" + } + field { + name "attachedZoneUuids" + desc "" + type "List" + since "5.0.0" + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageVO.java b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageVO.java new file mode 100755 index 00000000000..f9b05d02c4d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageVO.java @@ -0,0 +1,33 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.storage.backup.BackupStorageVO; + +import javax.persistence.Column; + +/* +@Entity +@Table +@PrimaryKeyJoinColumn(name="uuid", referencedColumnName="uuid") +@EO(EOClazz = BackupStorageEO.class, needView = false) +@AutoDeleteTag + */ +public class ExternalBackupStorageVO extends BackupStorageVO { + + @Column + private String identity; + + public ExternalBackupStorageVO() { + } + + public ExternalBackupStorageVO(BackupStorageVO vo) { + super(vo); + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageVO_.java b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageVO_.java new file mode 100755 index 00000000000..369b571bf31 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/ExternalBackupStorageVO_.java @@ -0,0 +1,11 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.storage.backup.BackupStorageVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(ExternalBackupStorageVO.class) +public class ExternalBackupStorageVO_ extends BackupStorageVO_ { + public static volatile SingularAttribute identity; +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/PackageInfo.java b/header/src/main/java/org/zstack/header/storage/addon/backup/PackageInfo.java new file mode 100644 index 00000000000..2e2c50db672 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/PackageInfo.java @@ -0,0 +1,10 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.PackageAPIInfo; + +@PackageAPIInfo( + APICategoryName = "镜像服务器", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) +public class PackageInfo { +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/backup/RBACInfo.java b/header/src/main/java/org/zstack/header/storage/addon/backup/RBACInfo.java new file mode 100644 index 00000000000..7ddcd752959 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/backup/RBACInfo.java @@ -0,0 +1,29 @@ +package org.zstack.header.storage.addon.backup; + +import org.zstack.header.identity.rbac.RBACDescription; +import org.zstack.header.storage.backup.BackupStorageVO; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .adminOnlyAPIs("org.zstack.header.storage.addon.backup.**") + .build(); + } + + @Override + public void contributeToRoles() { + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + globalReadableResourceBuilder() + .resources(BackupStorageVO.class) + .build(); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIAddExternalPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/addon/primary/APIAddExternalPrimaryStorageMsg.java new file mode 100644 index 00000000000..d791846f10d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIAddExternalPrimaryStorageMsg.java @@ -0,0 +1,63 @@ +package org.zstack.header.storage.addon.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.primary.APIAddPrimaryStorageEvent; +import org.zstack.header.storage.primary.APIAddPrimaryStorageMsg; +import org.zstack.header.storage.primary.PrimaryStorageConstant; + +@RestRequest( + path = "/primary-storage/addon", + method = HttpMethod.POST, + responseClass = APIAddPrimaryStorageEvent.class, + parameterName = "params" +) +public class APIAddExternalPrimaryStorageMsg extends APIAddPrimaryStorageMsg { + @APIParam(maxLength = 255, emptyString = false) + private String identity; + + @APIParam(validValues = {"Vhost", "iSCSI", "NVMEoF", "CBD", "file"}) + private String defaultOutputProtocol; + + @APIParam(required = false) + private String config; + + @Override + public String getType() { + return PrimaryStorageConstant.EXTERNAL_PRIMARY_STORAGE_TYPE; + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public static APIAddExternalPrimaryStorageMsg __example__() { + APIAddExternalPrimaryStorageMsg msg = new APIAddExternalPrimaryStorageMsg(); + msg.setIdentity("zbd"); + msg.setName("my primary storage"); + msg.setUrl("vendorname://user:password@host:port/pool"); + + return msg; + } + + public String getDefaultOutputProtocol() { + return defaultOutputProtocol; + } + + public void setDefaultOutputProtocol(String defaultOutputProtocol) { + this.defaultOutputProtocol = defaultOutputProtocol; + } + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIAddExternalPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/primary/APIAddExternalPrimaryStorageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..2ef5c7ca1b1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIAddExternalPrimaryStorageMsgDoc_zh_cn.groovy @@ -0,0 +1,140 @@ +package org.zstack.header.storage.addon.primary + +import org.zstack.header.storage.primary.APIAddPrimaryStorageEvent + +doc { + title "AddExternalPrimaryStorage" + + category "storage.primary" + + desc """添加外部存储""" + + rest { + request { + url "POST /v1/primary-storage/addon" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAddExternalPrimaryStorageMsg.class + + desc """""" + + params { + + column { + name "identity" + enclosedIn "params" + desc "存储标识" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "defaultOutputProtocol" + enclosedIn "params" + desc "默认输出协议" + location "body" + type "String" + optional false + since "5.0.0" + values ("Vhost","Scsi","Nvme","CBD","file") + } + column { + name "config" + enclosedIn "params" + desc "配置" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "url" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "type" + enclosedIn "params" + desc "类型" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "zoneUuid" + enclosedIn "params" + desc "区域UUID" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIAddPrimaryStorageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageEvent.java b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageEvent.java new file mode 100644 index 00000000000..2b501cb51e3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageEvent.java @@ -0,0 +1,45 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.utils.data.SizeUnit; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.sql.Timestamp; +import java.util.LinkedHashMap; + +@RestResponse(allTo = "inventory") +public class APIDiscoverExternalPrimaryStorageEvent extends APIEvent { + private ExternalPrimaryStorageInventory inventory; + + public ExternalPrimaryStorageInventory getInventory() { + return inventory; + } + + public void setInventory(ExternalPrimaryStorageInventory inventory) { + this.inventory = inventory; + } + + public APIDiscoverExternalPrimaryStorageEvent(String apiId) { + super(apiId); + } + + public APIDiscoverExternalPrimaryStorageEvent() { + super(); + } + + public static APIDiscoverExternalPrimaryStorageEvent __example__() { + APIDiscoverExternalPrimaryStorageEvent event = new APIDiscoverExternalPrimaryStorageEvent(); + ExternalPrimaryStorageInventory inv = new ExternalPrimaryStorageInventory(); + inv.setUuid(uuid()); + inv.setUrl("http://operator:*****@172.25.1.5:80"); + inv.setIdentity("expon"); + inv.setAddonInfo(JSONObjectUtil.toObject("{\"pools\":[{\"name\":\"pool1\",\"availableCapacity\":100,\"totalCapacity\":200},{\"name\":\"pool2\",\"availableCapacity\":100,\"totalCapacity\":200}]}", LinkedHashMap.class)); + inv.setTotalCapacity(SizeUnit.GIGABYTE.toByte(100L)); + inv.setAvailableCapacity(SizeUnit.GIGABYTE.toByte(50L)); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + event.setInventory(inv); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..4f7cab03e2c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageEventDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.storage.addon.primary + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "发现外部存储" + + ref { + name "inventory" + path "org.zstack.header.storage.addon.primary.APIDiscoverExternalPrimaryStorageEvent.inventory" + desc "null" + type "ExternalPrimaryStorageInventory" + since "5.0.0" + clz ExternalPrimaryStorageInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.header.storage.addon.primary.APIDiscoverExternalPrimaryStorageEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageMsg.java new file mode 100644 index 00000000000..62a894a2fff --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageMsg.java @@ -0,0 +1,53 @@ +package org.zstack.header.storage.addon.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/primary-storage/addon/discover", + method = HttpMethod.POST, + responseClass = APIDiscoverExternalPrimaryStorageEvent.class, + parameterName = "params" +) +public class APIDiscoverExternalPrimaryStorageMsg extends APIMessage { + @APIParam + @NoLogging(type = NoLogging.Type.Uri) + private String url; + @APIParam(required = false) + private String identity; + @APIParam(required = false) + private String config; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } + + public static APIDiscoverExternalPrimaryStorageMsg __example__() { + APIDiscoverExternalPrimaryStorageMsg msg = new APIDiscoverExternalPrimaryStorageMsg(); + msg.setUrl("http://operator:password@172.25.1.5:80"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..a47313fe348 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIDiscoverExternalPrimaryStorageMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.storage.addon.primary + +import org.zstack.header.storage.addon.primary.APIDiscoverExternalPrimaryStorageEvent + +doc { + title "DiscoverExternalPrimaryStorage" + + category "storage.primary" + + desc """发现外部存储""" + + rest { + request { + url "POST /v1/primary-storage/addon/discover" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDiscoverExternalPrimaryStorageMsg.class + + desc """""" + + params { + + column { + name "url" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "5.0.0" + } + column { + name "identity" + enclosedIn "params" + desc "存储标识" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "config" + enclosedIn "params" + desc "配置" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIDiscoverExternalPrimaryStorageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageEvent.java b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageEvent.java new file mode 100644 index 00000000000..c28a41f72d5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageEvent.java @@ -0,0 +1,50 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.log.MaskSensitiveInfo; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.utils.data.SizeUnit; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.sql.Timestamp; +import java.util.LinkedHashMap; + +@RestResponse(allTo = "inventory") +@MaskSensitiveInfo +public class APIUpdateExternalPrimaryStorageEvent extends APIEvent { + @NoLogging(behavior = NoLogging.Behavior.Auto) + private ExternalPrimaryStorageInventory inventory; + + public APIUpdateExternalPrimaryStorageEvent(String id) { + super(id); + } + + public APIUpdateExternalPrimaryStorageEvent() { + super(); + } + + public void setInventory(ExternalPrimaryStorageInventory inventory) { + this.inventory = inventory; + } + + public ExternalPrimaryStorageInventory getInventory() { + return inventory; + } + + public static APIUpdateExternalPrimaryStorageEvent __example__() { + APIUpdateExternalPrimaryStorageEvent event = new APIUpdateExternalPrimaryStorageEvent(); + ExternalPrimaryStorageInventory inv = new ExternalPrimaryStorageInventory(); + inv.setUuid(uuid()); + inv.setUrl("http://operator:*****@172.25.1.5:80"); + inv.setIdentity("expon"); + inv.setConfig(JSONObjectUtil.toObject("{\"pools\":[{\"name\":\"pool1\",\"aliasName\":\"pool-high\"},{\"name\":\"pool2\"}]}", LinkedHashMap.class)); + inv.setAddonInfo(JSONObjectUtil.toObject("{\"pools\":[{\"name\":\"pool1\",\"availableCapacity\":100,\"totalCapacity\":200},{\"name\":\"pool2\",\"availableCapacity\":100,\"totalCapacity\":200}]}", LinkedHashMap.class)); + inv.setTotalCapacity(SizeUnit.GIGABYTE.toByte(100L)); + inv.setAvailableCapacity(SizeUnit.GIGABYTE.toByte(50L)); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + event.setInventory(inv); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..9db9ade3450 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageEventDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.storage.addon.primary + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "更新外部存储结果" + + ref { + name "inventory" + path "org.zstack.header.storage.addon.primary.APIUpdateExternalPrimaryStorageEvent.inventory" + desc "null" + type "ExternalPrimaryStorageInventory" + since "5.0.0" + clz ExternalPrimaryStorageInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.header.storage.addon.primary.APIUpdateExternalPrimaryStorageEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageMsg.java new file mode 100644 index 00000000000..eba3533747d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageMsg.java @@ -0,0 +1,47 @@ +package org.zstack.header.storage.addon.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.primary.APIUpdatePrimaryStorageMsg; +import org.zstack.header.storage.primary.PrimaryStorageMessage; + +@RestRequest( + path = "/primary-storage/addon/{uuid}/actions", + isAction = true, + method = HttpMethod.PUT, + responseClass = APIUpdateExternalPrimaryStorageEvent.class +) +public class APIUpdateExternalPrimaryStorageMsg extends APIUpdatePrimaryStorageMsg implements PrimaryStorageMessage { + @APIParam(required = false) + private String config; + + @APIParam(required = false, maxLength = 255, validValues = {"Vhost", "Scsi", "Nvme", "CBD", "file"}) + private String defaultProtocol; + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } + + public String getDefaultProtocol() { + return defaultProtocol; + } + + public void setDefaultProtocol(String defaultProtocol) { + this.defaultProtocol = defaultProtocol; + } + + public static APIUpdateExternalPrimaryStorageMsg __example__() { + APIUpdateExternalPrimaryStorageMsg msg = new APIUpdateExternalPrimaryStorageMsg(); + msg.setUuid(uuid()); + msg.setName("My Primary Storage"); + msg.setDescription("New description"); + msg.setDefaultProtocol("Vhost"); + msg.setConfig("{\"pools\":[{\"name\":\"pool1\",\"aliasName\":\"pool-high\"}]}"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..faf8dbc3e31 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/APIUpdateExternalPrimaryStorageMsgDoc_zh_cn.groovy @@ -0,0 +1,104 @@ +package org.zstack.header.storage.addon.primary + +import org.zstack.header.storage.addon.primary.APIUpdateExternalPrimaryStorageEvent + +doc { + title "UpdateExternalPrimaryStorage" + + category "storage.primary" + + desc """更新外部存储""" + + rest { + request { + url "PUT /v1/primary-storage/addon/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateExternalPrimaryStorageMsg.class + + desc """""" + + params { + + column { + name "config" + enclosedIn "updateExternalPrimaryStorage" + desc "配置" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "defaultProtocol" + enclosedIn "updateExternalPrimaryStorage" + desc "默认协议" + location "body" + type "String" + optional true + since "5.0.0" + values ("Vhost","Scsi","Nvme","CBD","file") + } + column { + name "uuid" + enclosedIn "updateExternalPrimaryStorage" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.0.0" + } + column { + name "name" + enclosedIn "updateExternalPrimaryStorage" + desc "资源名称" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "description" + enclosedIn "updateExternalPrimaryStorage" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "url" + enclosedIn "updateExternalPrimaryStorage" + desc "" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIUpdateExternalPrimaryStorageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ActiveVolumeClient.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ActiveVolumeClient.java new file mode 100644 index 00000000000..11451c517ba --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ActiveVolumeClient.java @@ -0,0 +1,40 @@ +package org.zstack.header.storage.addon.primary; + +public class ActiveVolumeClient { + protected String managerIp; + protected String qualifiedName; + protected boolean inBlacklist; + protected String path; + + public void setManagerIp(String managerIp) { + this.managerIp = managerIp; + } + + public String getManagerIp() { + return managerIp; + } + + public void setQualifiedName(String qualifiedName) { + this.qualifiedName = qualifiedName; + } + + public String getQualifiedName() { + return qualifiedName; + } + + public void setInBlacklist(boolean inBlacklist) { + this.inBlacklist = inBlacklist; + } + + public boolean isInBlacklist() { + return inBlacklist; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return path; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ActiveVolumeTO.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ActiveVolumeTO.java new file mode 100644 index 00000000000..4ccfa813ce9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ActiveVolumeTO.java @@ -0,0 +1,40 @@ +package org.zstack.header.storage.addon.primary; + +public abstract class ActiveVolumeTO { + protected String installPath; + protected boolean shareable; + protected String metadata; + protected String protocol; + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public boolean isShareable() { + return shareable; + } + + public void setShareable(boolean shareable) { + this.shareable = shareable; + } + + public String getMetadata() { + return metadata; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/AllocateSpaceSpec.java b/header/src/main/java/org/zstack/header/storage/addon/primary/AllocateSpaceSpec.java new file mode 100644 index 00000000000..c06592c1227 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/AllocateSpaceSpec.java @@ -0,0 +1,43 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.PrimaryStorageAllocationPurpose; + +public class AllocateSpaceSpec { + private long size; + private boolean dryRun; + private String requiredUrl; + + private PrimaryStorageAllocationPurpose purpose; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public boolean isDryRun() { + return dryRun; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public String getRequiredUrl() { + return requiredUrl; + } + + public void setRequiredUrl(String requiredUrl) { + this.requiredUrl = requiredUrl; + } + + public PrimaryStorageAllocationPurpose getPurpose() { + return purpose; + } + + public void setPurpose(PrimaryStorageAllocationPurpose purpose) { + this.purpose = purpose; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/BackupStorageSelector.java b/header/src/main/java/org/zstack/header/storage/addon/primary/BackupStorageSelector.java new file mode 100644 index 00000000000..a32dc35285a --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/BackupStorageSelector.java @@ -0,0 +1,9 @@ +package org.zstack.header.storage.addon.primary; + +import java.util.List; + +public interface BackupStorageSelector { + List getPreferBackupStorageTypes(); + + String getIdentity(); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/BaseVolumeInfo.java b/header/src/main/java/org/zstack/header/storage/addon/primary/BaseVolumeInfo.java new file mode 100644 index 00000000000..f75a3b2a3b3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/BaseVolumeInfo.java @@ -0,0 +1,131 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.ImageCacheInventory; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.cdrom.VmCdRomVO; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeQos; +import org.zstack.header.volume.VolumeStats; + +import java.util.Collection; +import java.util.List; + +public class BaseVolumeInfo extends VolumeStats { + // optional, zsUUid + String uuid; + // optional + VolumeQos qos; + + protected String primaryStorageUuid; + protected String protocol; + // volume or image + protected String type; + protected boolean shareable; + + public BaseVolumeInfo(VolumeStats stats) { + super(stats.getInstallPath(), stats.getActualSize()); + } + + public BaseVolumeInfo() { + super(); + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return protocol; + } + + public void setQos(VolumeQos qos) { + this.qos = qos; + } + + public VolumeQos getQos() { + return qos; + } + + public void setShareable(boolean shareable) { + this.shareable = shareable; + } + + public boolean isShareable() { + return shareable; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public static BaseVolumeInfo valueOf(VolumeInventory vol) { + BaseVolumeInfo info = new BaseVolumeInfo(); + info.uuid = vol.getUuid(); + info.setActualSize(vol.getActualSize()); + info.setInstallPath(vol.getInstallPath()); + info.setProtocol(vol.getProtocol()); + info.setQos(VolumeQos.valueOf(vol.getVolumeQos())); + info.setShareable(vol.isShareable()); + info.setPrimaryStorageUuid(vol.getPrimaryStorageUuid()); + info.setType("volume"); + return info; + } + + public static BaseVolumeInfo valueOf(ImageCacheInventory image, String protocol) { + BaseVolumeInfo info = new BaseVolumeInfo(); + info.uuid = image.getImageUuid(); + info.setActualSize(image.getSize()); + info.setInstallPath(image.getInstallUrl()); + info.setProtocol(protocol); + info.setShareable(true); + info.setPrimaryStorageUuid(image.getPrimaryStorageUuid()); + info.setType("image"); + return info; + } + + public static BaseVolumeInfo valueOf(VmInstanceSpec.CdRomSpec image) { + BaseVolumeInfo info = new BaseVolumeInfo(); + info.uuid = image.getImageUuid(); + info.setInstallPath(image.getInstallPath()); + info.setProtocol(image.getProtocol()); + info.setShareable(true); + info.setPrimaryStorageUuid(image.getPrimaryStorageUuid()); + info.setType("image"); + return info; + } + + public static BaseVolumeInfo valueOf(VmCdRomVO image) { + BaseVolumeInfo info = new BaseVolumeInfo(); + info.uuid = image.getIsoUuid(); + info.setInstallPath(image.getIsoInstallPath()); + info.setProtocol(image.getProtocol()); + info.setShareable(true); + info.setType("image"); + return info; + } + + public static List valueOf(Collection vols) { + return vols.stream().map(BaseVolumeInfo::valueOf).collect(java.util.stream.Collectors.toList()); + } + +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/BaseVolumeSnapshotInfo.java b/header/src/main/java/org/zstack/header/storage/addon/primary/BaseVolumeSnapshotInfo.java new file mode 100644 index 00000000000..35f5b0b3509 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/BaseVolumeSnapshotInfo.java @@ -0,0 +1,11 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.snapshot.VolumeSnapshotStats; + +public class BaseVolumeSnapshotInfo extends VolumeSnapshotStats { + protected BaseVolumeInfo volume; + // optional + protected String id; + // optional + protected String name; +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/CreateVolumeSnapshotSpec.java b/header/src/main/java/org/zstack/header/storage/addon/primary/CreateVolumeSnapshotSpec.java new file mode 100644 index 00000000000..f5f20935e6e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/CreateVolumeSnapshotSpec.java @@ -0,0 +1,31 @@ +package org.zstack.header.storage.addon.primary; + +public class CreateVolumeSnapshotSpec { + private String name; + private String uuid; + private String volumeInstallPath; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVolumeInstallPath() { + return volumeInstallPath; + } + + public void setVolumeInstallPath(String volumeInstallPath) { + this.volumeInstallPath = volumeInstallPath; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/CreateVolumeSpec.java b/header/src/main/java/org/zstack/header/storage/addon/primary/CreateVolumeSpec.java new file mode 100644 index 00000000000..81587db27c8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/CreateVolumeSpec.java @@ -0,0 +1,61 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.volume.VolumeQos; + +public class CreateVolumeSpec { + private String name; + private String uuid; + private long size; + private VolumeQos qos; + + private String allocatedUrl; + private boolean dryRun; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public VolumeQos getQos() { + return qos; + } + + public void setQos(VolumeQos qos) { + this.qos = qos; + } + + public String getAllocatedUrl() { + return allocatedUrl; + } + + public void setAllocatedUrl(String allocatedUrl) { + this.allocatedUrl = allocatedUrl; + } + + public boolean isDryRun() { + return dryRun; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExportSpec.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExportSpec.java new file mode 100644 index 00000000000..ff88bf3399e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExportSpec.java @@ -0,0 +1,40 @@ +package org.zstack.header.storage.addon.primary; + +public class ExportSpec { + private String installPath; + private String clientMnIp; + private String clientQualifiedName; + private String format; + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public void setClientQualifiedName(String clientQualifiedName) { + this.clientQualifiedName = clientQualifiedName; + } + + public String getClientQualifiedName() { + return clientQualifiedName; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getClientMnIp() { + return clientMnIp; + } + + public void setClientMnIp(String clientMnIp) { + this.clientMnIp = clientMnIp; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageHostRefVO.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageHostRefVO.java new file mode 100644 index 00000000000..035f89b1ff2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageHostRefVO.java @@ -0,0 +1,35 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.PrimaryStorageHostRefVO; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +@Entity +@Table +@PrimaryKeyJoinColumn(name = "id", referencedColumnName = "id") +public class ExternalPrimaryStorageHostRefVO extends PrimaryStorageHostRefVO { + @Column + private String protocol; + + @Column + private int hostId; + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public int getHostId() { + return hostId; + } + + public void setHostId(int hostId) { + this.hostId = hostId; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageHostRefVO_.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageHostRefVO_.java new file mode 100644 index 00000000000..0701135df99 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageHostRefVO_.java @@ -0,0 +1,12 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.PrimaryStorageHostRefVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(ExternalPrimaryStorageHostRefVO.class) +public class ExternalPrimaryStorageHostRefVO_ extends PrimaryStorageHostRefVO_ { + public static volatile SingularAttribute hostId; + public static volatile SingularAttribute protocol; +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java new file mode 100644 index 00000000000..7808c227623 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventory.java @@ -0,0 +1,110 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.search.Inventory; +import org.zstack.header.storage.primary.PrimaryStorageInventory; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.stream.Collectors; + +@Inventory(mappingVOClass = ExternalPrimaryStorageVO.class) +public class ExternalPrimaryStorageInventory extends PrimaryStorageInventory { + private String identity; + + /** + * @example { + * "config": "{ + * "pools": [ + * { + * "name": "pool1", + * "aliasName": "pool-high", + * }, + * { + * "name": "pool2", + * } + * ] + * } + */ + private LinkedHashMap config; + + /** + * @example { + * "addonInfo": { + * "pools": [ + * { + * "name": "pool1", + * "availableCapacity": 100, + * "totalCapacity": 200 + * }, + * { + * "name": "pool2", + * "availableCapacity": 100, + * "totalCapacity": 200 + * } + * ] + * } + */ + private LinkedHashMap addonInfo; + + private List outputProtocols; + + private String defaultProtocol; + + public ExternalPrimaryStorageInventory() { + super(); + } + + public ExternalPrimaryStorageInventory(ExternalPrimaryStorageVO lvo) { + super(lvo); + identity = lvo.getIdentity(); + config = JSONObjectUtil.toObject(lvo.getConfig(), LinkedHashMap.class); + addonInfo = JSONObjectUtil.toObject(lvo.getAddonInfo(), LinkedHashMap.class); + outputProtocols = lvo.getOutputProtocols().stream().map(PrimaryStorageOutputProtocolRefVO::getOutputProtocol).collect(Collectors.toList()); + defaultProtocol = lvo.getDefaultProtocol(); + } + + public static ExternalPrimaryStorageInventory valueOf(ExternalPrimaryStorageVO lvo) { + return new ExternalPrimaryStorageInventory(lvo); + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public LinkedHashMap getConfig() { + return config; + } + + public void setConfig(LinkedHashMap config) { + this.config = config; + } + + public List getOutputProtocols() { + return outputProtocols; + } + + public void setOutputProtocols(List outputProtocols) { + this.outputProtocols = outputProtocols; + } + + public String getDefaultProtocol() { + return defaultProtocol; + } + + public void setDefaultProtocol(String defaultProtocol) { + this.defaultProtocol = defaultProtocol; + } + + public LinkedHashMap getAddonInfo() { + return addonInfo; + } + + public void setAddonInfo(LinkedHashMap addonInfo) { + this.addonInfo = addonInfo; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..73c4aeab617 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageInventoryDoc_zh_cn.groovy @@ -0,0 +1,139 @@ +package org.zstack.header.storage.addon.primary + +doc { + + title "外部主存储" + + field { + name "identity" + desc "存储标识" + type "String" + since "5.0.0" + } + field { + name "config" + desc "配置" + type "String" + since "5.0.0" + } + field { + name "addonInfo" + desc "额外信息" + type "String" + since "5.0.0" + } + field { + name "outputProtocols" + desc "可输出协议" + type "List" + since "5.0.0" + } + field { + name "defaultProtocol" + desc "默认协议" + type "String" + since "5.0.0" + } + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.0.0" + } + field { + name "zoneUuid" + desc "区域UUID" + type "String" + since "5.0.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.0.0" + } + field { + name "url" + desc "" + type "String" + since "5.0.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.0.0" + } + field { + name "totalCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "availableCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "totalPhysicalCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "availablePhysicalCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "systemUsedCapacity" + desc "" + type "Long" + since "5.0.0" + } + field { + name "type" + desc "类型" + type "String" + since "5.0.0" + } + field { + name "state" + desc "" + type "String" + since "5.0.0" + } + field { + name "status" + desc "" + type "String" + since "5.0.0" + } + field { + name "mountPath" + desc "" + type "String" + since "5.0.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.0.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.0.0" + } + field { + name "attachedClusterUuids" + desc "" + type "List" + since "5.0.0" + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageSvcBuilder.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageSvcBuilder.java new file mode 100644 index 00000000000..041438d7420 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageSvcBuilder.java @@ -0,0 +1,15 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.core.ReturnValueCompletion; + +import java.util.LinkedHashMap; + +public interface ExternalPrimaryStorageSvcBuilder { + PrimaryStorageControllerSvc buildControllerSvc(ExternalPrimaryStorageVO vo); + + PrimaryStorageNodeSvc buildNodeSvc(ExternalPrimaryStorageVO vo); + + void discover(String url, String config, ReturnValueCompletion completion); + + String getIdentity(); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageVO.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageVO.java new file mode 100644 index 00000000000..1977210226f --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageVO.java @@ -0,0 +1,95 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.PrimaryStorageEO; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.EO; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table +@PrimaryKeyJoinColumn(name="uuid", referencedColumnName="uuid") +@EO(EOClazz = PrimaryStorageEO.class, needView = false) +@AutoDeleteTag +public class ExternalPrimaryStorageVO extends PrimaryStorageVO implements ToInventory { + @Column + private String identity; + + @Column + private String config; + + @Column + private String addonInfo; + + @Column + //@Convert(converter = PasswordConverter.class) + private String password; + + @Column + private String defaultProtocol; + + @Column + @OneToMany(fetch= FetchType.EAGER) + @JoinColumn(name="primaryStorageUuid", insertable=false, updatable=false) + private Set outputProtocols = new HashSet<>(); + + public ExternalPrimaryStorageVO(PrimaryStorageVO vo) { + super(vo); + } + + public ExternalPrimaryStorageVO() { + super(); + } + + public String getIdentity() { + return identity; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } + + public Set getOutputProtocols() { + return outputProtocols; + } + + public void setOutputProtocols(Set outputProtocols) { + this.outputProtocols = outputProtocols; + } + + public String getDefaultProtocol() { + return defaultProtocol; + } + + public void setDefaultProtocol(String defaultProtocol) { + this.defaultProtocol = defaultProtocol; + } + + public String getAddonInfo() { + return addonInfo; + } + + public void setAddonInfo(String addonInfo) { + this.addonInfo = addonInfo; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageVO_.java b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageVO_.java new file mode 100644 index 00000000000..52b1946405c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/ExternalPrimaryStorageVO_.java @@ -0,0 +1,14 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.PrimaryStorageVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(ExternalPrimaryStorageVO.class) +public class ExternalPrimaryStorageVO_ extends PrimaryStorageVO_ { + public static volatile SingularAttribute identity; + public static volatile SingularAttribute config; + public static volatile SingularAttribute addonInfo; + public static volatile SingularAttribute defaultProtocol; +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/HeartbeatVolumeTO.java b/header/src/main/java/org/zstack/header/storage/addon/primary/HeartbeatVolumeTO.java new file mode 100644 index 00000000000..4ad2b24eca8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/HeartbeatVolumeTO.java @@ -0,0 +1,34 @@ +package org.zstack.header.storage.addon.primary; + +import java.util.List; + +public abstract class HeartbeatVolumeTO extends ActiveVolumeTO { + private Integer hostId; + private Long heartbeatRequiredSpace; + private List coveringPaths; + + public Integer getHostId() { + return hostId; + } + + public void setHostId(Integer hostId) { + this.hostId = hostId; + } + + + public Long getHeartbeatRequiredSpace() { + return heartbeatRequiredSpace; + } + + public void setHeartbeatRequiredSpace(Long heartbeatRequiredSpace) { + this.heartbeatRequiredSpace = heartbeatRequiredSpace; + } + + public List getCoveringPaths() { + return coveringPaths; + } + + public void setCoveringPaths(List coveringPaths) { + this.coveringPaths = coveringPaths; + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/NodeHealthyCheckProtocolExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/addon/primary/NodeHealthyCheckProtocolExtensionPoint.java new file mode 100644 index 00000000000..8e5692d85b8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/NodeHealthyCheckProtocolExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.host.HypervisorType; + +public interface NodeHealthyCheckProtocolExtensionPoint { + HypervisorType getHypervisorType(); + String getHealthyProtocol(); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/PackageInfo.java b/header/src/main/java/org/zstack/header/storage/addon/primary/PackageInfo.java new file mode 100644 index 00000000000..0dd159d0eda --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/PackageInfo.java @@ -0,0 +1,10 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.PackageAPIInfo; + +@PackageAPIInfo( + APICategoryName = "主存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) +public class PackageInfo { +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageControllerSvc.java b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageControllerSvc.java new file mode 100644 index 00000000000..5d6896960ce --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageControllerSvc.java @@ -0,0 +1,57 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.host.HostInventory; +import org.zstack.header.storage.addon.*; +import org.zstack.header.storage.snapshot.VolumeSnapshotStats; +import org.zstack.header.volume.VolumeProtocol; +import org.zstack.header.volume.VolumeStats; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; + +public interface PrimaryStorageControllerSvc { + String getIdentity(); + void connect(String config, String url, ReturnValueCompletion comp); + void ping(Completion completion); + + void reportCapacity(ReturnValueCompletion comp); + void reportHealthy(ReturnValueCompletion comp); + void reportNodeHealthy(HostInventory host, ReturnValueCompletion comp); + StorageCapabilities reportCapabilities(); + + String allocateSpace(AllocateSpaceSpec aspec); + + void createVolume(CreateVolumeSpec v, ReturnValueCompletioncomp); + void deleteVolume(String installPath, Completion comp); + void deleteVolumeAndSnapshot(String installPath, Completion comp); + void trashVolume(String installPath, Completion comp); + void cloneVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletioncomp); + void copyVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletioncomp); + void flattenVolume(String installPath, ReturnValueCompletioncomp); + + // support uri or path + void stats(String installPath, ReturnValueCompletion comp); + + void batchStats(Collection installPath, ReturnValueCompletion> comp); + + void expandVolume(String installPath, long size, ReturnValueCompletion comp); + void setVolumeQos(BaseVolumeInfo v, Completion comp); + void deleteVolumeQos(BaseVolumeInfo v, Completion comp); + void export(ExportSpec espec, VolumeProtocol protocol, ReturnValueCompletion comp); + void unexport(ExportSpec espec, RemoteTarget remoteTarget, VolumeProtocol protocol, Completion comp); + + void createSnapshot(CreateVolumeSnapshotSpec spec, ReturnValueCompletion comp); + void deleteSnapshot(String installPath, Completion comp); + void expungeSnapshot(String installPath, Completion comp); + void revertVolumeSnapshot(String snapshotInstallPath, ReturnValueCompletion comp); + + void validateConfig(String config); + + void setTrashExpireTime(int timeInSeconds, Completion completion); + void onFirstAdditionConfigure(Completion completion); + + long alignSize(long size); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageNodeSvc.java b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageNodeSvc.java new file mode 100644 index 00000000000..f292e694183 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageNodeSvc.java @@ -0,0 +1,35 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.host.HostInventory; + +import java.util.List; + +public interface PrimaryStorageNodeSvc { + void activate(BaseVolumeInfo v, HostInventory h, boolean shareable, ReturnValueCompletion comp); + + void deactivate(String installPath, String protocol, HostInventory h, Completion comp); + + void deactivate(String installPath, String protocol, ActiveVolumeClient client, Completion comp); + + void blacklist(String installPath, String protocol, HostInventory h, Completion comp); + + String getActivePath(BaseVolumeInfo v, HostInventory h, boolean shareable); + BaseVolumeInfo getActiveVolumeInfo(String activePath, HostInventory h, boolean shareable); + + // TODO use HostInventory + List getActiveClients(String installPath, String protocol); + + List getActiveVolumesLocation(HostInventory h); + + void deployClient(HostInventory h, Completion comp); + + void activateHeartbeatVolume(HostInventory h, ReturnValueCompletion comp); + + void deactivateHeartbeatVolume(HostInventory h, Completion comp); + + HeartbeatVolumeTO getHeartbeatVolumeActiveInfo(HostInventory h); + + String getIdentity(); +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageOutputProtocolRefVO.java b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageOutputProtocolRefVO.java new file mode 100644 index 00000000000..9ff0c16e99e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageOutputProtocolRefVO.java @@ -0,0 +1,52 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.vo.EntityGraph; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = ExternalPrimaryStorageVO.class, myField = "primaryStorageUuid", targetField = "uuid") + } +) +public class PrimaryStorageOutputProtocolRefVO { + @Column + @Id + private long id; + + @Column + //@ForeignKey(parentEntityClass = ExternalPrimaryStorageVO.class, parentKey = "uuid", onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String primaryStorageUuid; + + @Column + private String outputProtocol; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getOutputProtocol() { + return outputProtocol; + } + + public void setOutputProtocol(String outputProtocol) { + this.outputProtocol = outputProtocol; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageOutputProtocolRefVO_.java b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageOutputProtocolRefVO_.java new file mode 100644 index 00000000000..86e3e706609 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/PrimaryStorageOutputProtocolRefVO_.java @@ -0,0 +1,11 @@ +package org.zstack.header.storage.addon.primary; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(PrimaryStorageOutputProtocolRefVO.class) +public class PrimaryStorageOutputProtocolRefVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute primaryStorageUuid; + public static volatile SingularAttribute outputProtocol; +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/RBACInfo.java b/header/src/main/java/org/zstack/header/storage/addon/primary/RBACInfo.java new file mode 100644 index 00000000000..a5fa85618af --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/RBACInfo.java @@ -0,0 +1,28 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .adminOnlyAPIs("org.zstack.header.storage.addon.primary.**") + .build(); + } + + @Override + public void contributeToRoles() { + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + globalReadableResourceBuilder() + .resources(ExternalPrimaryStorageVO.class) + .build(); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/addon/primary/StorageCapabilities.java b/header/src/main/java/org/zstack/header/storage/addon/primary/StorageCapabilities.java new file mode 100644 index 00000000000..b2a6b7fe64a --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/addon/primary/StorageCapabilities.java @@ -0,0 +1,94 @@ +package org.zstack.header.storage.addon.primary; + +import org.zstack.header.storage.primary.VolumeSnapshotCapability; +import org.zstack.header.volume.VolumeProtocol; + +import java.util.List; + +// TODO Merge with PrimaryStorageFeature +public class StorageCapabilities { + private VolumeSnapshotCapability snapshotCapability; + + private boolean supportCloneFromVolume; + + private boolean supportStorageQos; + + private boolean supportLiveExpandVolume; + private boolean supportShareableVolume; + private boolean supportExportVolumeSnapshot; + public List supportedImageFormats; + private VolumeProtocol defaultIsoActiveProtocol; + private VolumeProtocol defaultImageExportProtocol; + + public boolean isSupportShareableVolume() { + return supportShareableVolume; + } + + public void setSupportShareableVolume(boolean supportShareableVolume) { + this.supportShareableVolume = supportShareableVolume; + } + + public VolumeProtocol getDefaultIsoActiveProtocol() { + return defaultIsoActiveProtocol; + } + + public void setDefaultIsoActiveProtocol(VolumeProtocol defaultIsoActiveProtocol) { + this.defaultIsoActiveProtocol = defaultIsoActiveProtocol; + } + + public VolumeProtocol getDefaultImageExportProtocol() { + return defaultImageExportProtocol; + } + + public void setDefaultImageExportProtocol(VolumeProtocol defaultImageExportProtocol) { + this.defaultImageExportProtocol = defaultImageExportProtocol; + } + + public VolumeSnapshotCapability getSnapshotCapability() { + return snapshotCapability; + } + + public void setSnapshotCapability(VolumeSnapshotCapability snapshotCapability) { + this.snapshotCapability = snapshotCapability; + } + + public boolean isSupportExportVolumeSnapshot() { + return supportExportVolumeSnapshot; + } + + public void setSupportExportVolumeSnapshot(boolean supportExportVolumeSnapshot) { + this.supportExportVolumeSnapshot = supportExportVolumeSnapshot; + } + + public boolean isSupportCloneFromVolume() { + return supportCloneFromVolume; + } + + public void setSupportCloneFromVolume(boolean supportCloneFromVolume) { + this.supportCloneFromVolume = supportCloneFromVolume; + } + + public List getSupportedImageFormats() { + return supportedImageFormats; + } + + public void setSupportedImageFormats(List supportedImageFormats) { + this.supportedImageFormats = supportedImageFormats; + } + + public boolean isSupportStorageQos() { + return supportStorageQos; + } + + public void setSupportStorageQos(boolean supportStorageQos) { + this.supportStorageQos = supportStorageQos; + } + + public boolean isSupportLiveExpandVolume() { + return supportLiveExpandVolume; + } + + public void setSupportLiveExpandVolume(boolean supportLiveExpandVolume) { + this.supportLiveExpandVolume = supportLiveExpandVolume; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsg.java b/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsg.java index c22547a1733..029c1da5706 100755 --- a/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsg.java +++ b/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsg.java @@ -37,6 +37,7 @@ @RestRequest( path = "/zones/{zoneUuid}/backup-storage/{backupStorageUuid}", method = HttpMethod.POST, + parameterName = "params", responseClass = APIAttachBackupStorageToZoneEvent.class ) public class APIAttachBackupStorageToZoneMsg extends APIMessage implements BackupStorageMessage { diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsgDoc_zh_cn.groovy index 7f714a44ec3..77b7cae4fb4 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIAttachBackupStorageToZoneMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "zoneUuid" - enclosedIn "" + enclosedIn "params" desc "区域UUID" location "url" type "String" optional false since "0.6" - } column { name "backupStorageUuid" - enclosedIn "" + enclosedIn "params" desc "镜像存储UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIChangeBackupStorageStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIChangeBackupStorageStateMsgDoc_zh_cn.groovy index 1eba55d0672..96a666edbe6 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIChangeBackupStorageStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIChangeBackupStorageStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEvent.java b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEvent.java index 5b3d2035ab9..e2c926d12d8 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEvent.java +++ b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEvent.java @@ -1,18 +1,22 @@ package org.zstack.header.storage.backup; import org.zstack.header.core.trash.CleanTrashResult; +import org.zstack.header.core.trash.TrashCleanupResult; import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; import java.util.Collections; +import java.util.List; /** * Created by mingjian.deng on 2018/12/10. */ -@RestResponse(allTo = "result") +@RestResponse(fieldsTo = {"all"}) public class APICleanUpTrashOnBackupStorageEvent extends APIEvent { private CleanTrashResult result; + private List results; + public CleanTrashResult getResult() { return result; } @@ -21,6 +25,14 @@ public void setResult(CleanTrashResult result) { this.result = result; } + public List getResults() { + return results; + } + + public void setResults(List results) { + this.results = results; + } + public APICleanUpTrashOnBackupStorageEvent(String apiId) { super(apiId); } @@ -37,6 +49,7 @@ public static APICleanUpTrashOnBackupStorageEvent __example__() { cleaned.setSize(1024000L); event.setResult(cleaned); + event.setResults(Collections.singletonList(new TrashCleanupResult(uuid, 1, 1024000L))); return event; } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEventDoc_zh_cn.groovy index 7f40e95b2d2..cc48f576a81 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEventDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageEventDoc_zh_cn.groovy @@ -1,5 +1,6 @@ package org.zstack.header.storage.backup +import org.zstack.header.core.trash.TrashCleanupResult import org.zstack.header.errorcode.ErrorCode import org.zstack.header.core.trash.CleanTrashResult @@ -29,4 +30,12 @@ doc { since "3.3.0" clz CleanTrashResult.class } + ref { + name "results" + path "org.zstack.header.storage.backup.APICleanUpTrashOnBackupStorageEvent.results" + desc "清理数据的返回信息" + type "List" + since "4.7.0" + clz TrashCleanupResult.class + } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsg.java b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsg.java index b1b80150c0b..afa4b935cfa 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsg.java @@ -1,6 +1,9 @@ package org.zstack.header.storage.backup; import org.springframework.http.HttpMethod; +import org.zstack.header.core.trash.TrashCleanupResult; +import org.zstack.header.message.APIBatchRequest; +import org.zstack.header.message.APIEvent; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; @@ -14,7 +17,7 @@ responseClass = APICleanUpTrashOnBackupStorageEvent.class, method = HttpMethod.PUT ) -public class APICleanUpTrashOnBackupStorageMsg extends APIMessage implements BackupStorageMessage { +public class APICleanUpTrashOnBackupStorageMsg extends APIMessage implements BackupStorageMessage, APIBatchRequest { @APIParam(resourceType = BackupStorageVO.class, checkAccount = true) private String uuid; @APIParam(required = false) @@ -47,4 +50,14 @@ public static APICleanUpTrashOnBackupStorageMsg __example__() { return msg; } + + @Override + public Result collectResult(APIMessage message, APIEvent rsp) { + APICleanUpTrashOnBackupStorageEvent evt = (APICleanUpTrashOnBackupStorageEvent) rsp; + return new Result(evt.getResults().size(), + evt.getResults().stream() + .filter(TrashCleanupResult::isSuccess) + .toArray().length + ); + } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsgDoc_zh_cn.groovy index 87465fe8f26..1f4e8982f16 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APICleanUpTrashOnBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.2.0" - } column { name "trashId" @@ -39,7 +38,6 @@ doc { type "Long" optional true since "3.3.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.2.0" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.2.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIDeleteBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIDeleteBackupStorageMsgDoc_zh_cn.groovy index 1ce59016460..9ea4606f85f 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIDeleteBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIDeleteBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIDeleteExportedImageFromBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIDeleteExportedImageFromBackupStorageMsgDoc_zh_cn.groovy index 2c3c9b3a0ef..c661e4bc9b2 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIDeleteExportedImageFromBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIDeleteExportedImageFromBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "1.7" - } column { name "imageUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "1.7" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "1.7" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "1.7" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIDetachBackupStorageFromZoneMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIDetachBackupStorageFromZoneMsgDoc_zh_cn.groovy index 9769490260b..16b94c88fd5 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIDetachBackupStorageFromZoneMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIDetachBackupStorageFromZoneMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "zoneUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIExportImageFromBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIExportImageFromBackupStorageMsgDoc_zh_cn.groovy index e7ca5421e0f..2069ae338a4 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIExportImageFromBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIExportImageFromBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "1.7" - } column { name "imageUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "1.7" - } column { name "exportFormat" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.9.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "1.7" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "1.7" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageCapacityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageCapacityMsgDoc_zh_cn.groovy index a5668700f34..7ba3728827e 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageCapacityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageCapacityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "backupStorageUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "all" @@ -49,7 +47,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageTypesMsgDoc_zh_cn.groovy index 971b1c19e9e..32d599d5e3e 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIGetBackupStorageTypesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIGetTrashOnBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIGetTrashOnBackupStorageMsgDoc_zh_cn.groovy index 77407454b10..61b2a62c47b 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIGetTrashOnBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIGetTrashOnBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.2.0" - } column { name "resourceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.5.0" - } column { name "resourceType" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.5.0" - } column { name "trashType" @@ -69,7 +66,6 @@ doc { type "List" optional true since "3.2.0" - } column { name "userTags" @@ -79,7 +75,6 @@ doc { type "List" optional true since "3.2.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIQueryBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIQueryBackupStorageMsgDoc_zh_cn.groovy index 089c11e8875..872da080c5c 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIQueryBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIQueryBackupStorageMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.storage.backup import org.zstack.header.storage.backup.APIQueryBackupStorageReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询镜像服务器(QueryBackupStorage)" diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIReconnectBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIReconnectBackupStorageMsgDoc_zh_cn.groovy index 23b4c00557d..b85165830e5 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIReconnectBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIReconnectBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/APIUpdateBackupStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/backup/APIUpdateBackupStorageMsgDoc_zh_cn.groovy index b1fc2b62258..a6425398411 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/APIUpdateBackupStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/backup/APIUpdateBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/BackupStorageConstant.java b/header/src/main/java/org/zstack/header/storage/backup/BackupStorageConstant.java index 64796d6fb54..4e4f30cbe9a 100755 --- a/header/src/main/java/org/zstack/header/storage/backup/BackupStorageConstant.java +++ b/header/src/main/java/org/zstack/header/storage/backup/BackupStorageConstant.java @@ -10,6 +10,8 @@ public interface BackupStorageConstant { public static final String SCHEME_SFTP = "sftp"; public static final String SCHEME_FTP = "ftp"; + String EXTERNAL_BACKUP_STORAGE_TYPE = "Addon"; + public static final String DEFAULT_ALLOCATOR_STRATEGY = "defaultAllocatorStrategy"; public static final BackupStorageAllocatorStrategyType DEFAULT_ALLOCATOR_STRATEGY_TYPE = new BackupStorageAllocatorStrategyType(DEFAULT_ALLOCATOR_STRATEGY); @@ -19,4 +21,7 @@ public static enum AllocatorParams { } public static final String ACTION_CATEGORY = "backupStorage"; + + public static final String IMPORT_IMAGES_FAKE_RESOURCE_UUID = "0a1150d12623319995c9386bf55cb03c"; + public static final String RESTORE_IMAGES_BACKUP_STORAGE_METADATA_TO_DATABASE = "restore_images_backup_storage_metadata_to_database"; } diff --git a/header/src/main/java/org/zstack/header/storage/backup/BackupStorageErrors.java b/header/src/main/java/org/zstack/header/storage/backup/BackupStorageErrors.java index 8242608d9a2..b3b5cd4f0d7 100755 --- a/header/src/main/java/org/zstack/header/storage/backup/BackupStorageErrors.java +++ b/header/src/main/java/org/zstack/header/storage/backup/BackupStorageErrors.java @@ -21,6 +21,6 @@ public String toString() { } public enum Opaque { - RECONNECT_AGENT + NEED_RECONNECT_CHECKING } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/CalculateImageHashOnBackupStorageMsg.java b/header/src/main/java/org/zstack/header/storage/backup/CalculateImageHashOnBackupStorageMsg.java new file mode 100644 index 00000000000..68d4c7c3b54 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/CalculateImageHashOnBackupStorageMsg.java @@ -0,0 +1,39 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @ Author : yh.w + * @ Date : Created in 17:53 2023/11/10 + */ +public class CalculateImageHashOnBackupStorageMsg extends NeedReplyMessage implements BackupStorageMessage { + private String imageUuid; + private String algorithm; + + private String backupStorageUuid; + + public String getAlgorithm() { + return algorithm; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public String getImageUuid() { + return imageUuid; + } + + public void setImageUuid(String imageUuid) { + this.imageUuid = imageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/CalculateImageHashOnBackupStorageReply.java b/header/src/main/java/org/zstack/header/storage/backup/CalculateImageHashOnBackupStorageReply.java new file mode 100644 index 00000000000..1b8fd674e08 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/CalculateImageHashOnBackupStorageReply.java @@ -0,0 +1,18 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; +/** + * @ Author : yh.w + * @ Date : Created in 17:53 2023/11/10 + */ +public class CalculateImageHashOnBackupStorageReply extends MessageReply { + private String hashValue; + + public String getHashValue() { + return hashValue; + } + + public void setHashValue(String hashValue) { + this.hashValue = hashValue; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/CleanUpVmBackupExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/backup/CleanUpVmBackupExtensionPoint.java new file mode 100644 index 00000000000..1f0df16514b --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/CleanUpVmBackupExtensionPoint.java @@ -0,0 +1,10 @@ +package org.zstack.header.storage.backup; + +import java.util.List; + +/** + * Created by LiangHanYu on 2023/2/10 17:48 + */ +public interface CleanUpVmBackupExtensionPoint { + void afterCleanUpVmBackup(String groupUuid); +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/DownloadImageFromRemoteTargetMsg.java b/header/src/main/java/org/zstack/header/storage/backup/DownloadImageFromRemoteTargetMsg.java new file mode 100644 index 00000000000..693ff8f4dc7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/DownloadImageFromRemoteTargetMsg.java @@ -0,0 +1,35 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.image.ImageInventory; +import org.zstack.header.message.NeedReplyMessage; + +public class DownloadImageFromRemoteTargetMsg extends NeedReplyMessage implements BackupStorageMessage { + private ImageInventory image; + private String backupStorageUuid; + private String remoteTargetUrl; + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + + public ImageInventory getImage() { + return image; + } + + public void setImage(ImageInventory image) { + this.image = image; + } + + public String getRemoteTargetUrl() { + return remoteTargetUrl; + } + + public void setRemoteTargetUrl(String remoteTargetUrl) { + this.remoteTargetUrl = remoteTargetUrl; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/DownloadImageFromRemoteTargetReply.java b/header/src/main/java/org/zstack/header/storage/backup/DownloadImageFromRemoteTargetReply.java new file mode 100644 index 00000000000..5eddd42b923 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/DownloadImageFromRemoteTargetReply.java @@ -0,0 +1,51 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class DownloadImageFromRemoteTargetReply extends MessageReply { + private String installPath; + private long size; + private long actualSize; + private String format; + private String md5sum; + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public String getInstallPath() { + return installPath; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getMd5sum() { + return md5sum; + } + + public void setMd5sum(String md5sum) { + this.md5sum = md5sum; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/ExportImageFromBackupStorageMsg.java b/header/src/main/java/org/zstack/header/storage/backup/ExportImageFromBackupStorageMsg.java index c2d7885d7a6..6abb6fd4360 100644 --- a/header/src/main/java/org/zstack/header/storage/backup/ExportImageFromBackupStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/backup/ExportImageFromBackupStorageMsg.java @@ -10,6 +10,17 @@ public class ExportImageFromBackupStorageMsg extends NeedReplyMessage implements private String imageUuid; private String rawPath; private String exportFormat; + private Long requiredSize; + private String imageName; + private RemoteTargetProtocol targetProtocol = RemoteTargetProtocol.HTTP; + + public RemoteTargetProtocol getTargetProtocol() { + return targetProtocol; + } + + public void setTargetProtocol(RemoteTargetProtocol targetProtocol) { + this.targetProtocol = targetProtocol; + } @Override public String getBackupStorageUuid() { @@ -43,4 +54,20 @@ public String getRawPath() { public void setRawPath(String rawPath) { this.rawPath = rawPath; } + + public Long getRequiredSize() { + return requiredSize; + } + + public void setRequiredSize(Long requiredSize) { + this.requiredSize = requiredSize; + } + + public String getImageName() { + return imageName; + } + + public void setImageName(String imageName) { + this.imageName = imageName; + } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/GetBackupStorageManagerHostnameMsg.java b/header/src/main/java/org/zstack/header/storage/backup/GetBackupStorageManagerHostnameMsg.java new file mode 100644 index 00000000000..e8777e234d0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/GetBackupStorageManagerHostnameMsg.java @@ -0,0 +1,20 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.NeedReplyMessage; + +public class GetBackupStorageManagerHostnameMsg extends NeedReplyMessage implements BackupStorageMessage { + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getBackupStorageUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/GetBackupStorageManagerHostnameReply.java b/header/src/main/java/org/zstack/header/storage/backup/GetBackupStorageManagerHostnameReply.java new file mode 100644 index 00000000000..75bf6fc0709 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/GetBackupStorageManagerHostnameReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class GetBackupStorageManagerHostnameReply extends MessageReply { + private String hostname; + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/ImageHashAlgorithm.java b/header/src/main/java/org/zstack/header/storage/backup/ImageHashAlgorithm.java new file mode 100644 index 00000000000..80823809d43 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/ImageHashAlgorithm.java @@ -0,0 +1,11 @@ +package org.zstack.header.storage.backup; + +/** + * @ Author : yh.w + * @ Date : Created in 17:43 2023/11/10 + */ +public enum ImageHashAlgorithm { + MD5, + SHA1, + SHA256 +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/NbdRemoteTarget.java b/header/src/main/java/org/zstack/header/storage/backup/NbdRemoteTarget.java new file mode 100644 index 00000000000..4b716f209b2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/NbdRemoteTarget.java @@ -0,0 +1,97 @@ +package org.zstack.header.storage.backup; + +import org.apache.commons.lang.StringUtils; +import org.zstack.header.exception.CloudRuntimeException; + +import java.net.URI; +import java.net.URISyntaxException; + +/** + * @ Author : yh.w + * @ Date : Created in 16:56 2023/10/11 + */ +public class NbdRemoteTarget implements RemoteTarget { + private String host; + private int port; + private String exportName; + private String options; + + public NbdRemoteTarget(String host, int port, String device, String options) { + this.host = host; + this.port = port; + this.exportName = device; + this.options = options; + } + + public NbdRemoteTarget(String nbdUri) { + URI uri; + try { + uri = new URI(nbdUri); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("NBD URI syntax is incorrect: " + nbdUri, e); + } + + this.host = uri.getHost(); + this.port = uri.getPort(); + this.exportName = StringUtils.isEmpty(uri.getPath()) ? null : uri.getPath().substring(1); + this.options = uri.getQuery(); + } + + @Override + public String getInstallPath() { + return null; + } + + @Override + public String getTargetUri() { + return getTargetUri(this.host); + } + + @Override + public String getTargetUri(String hostname) { + StringBuilder uriBuilder = new StringBuilder(); + uriBuilder.append("nbd://"); + uriBuilder.append(hostname); + uriBuilder.append(":").append(this.port); + if (!StringUtils.isEmpty(this.exportName)) { + uriBuilder.append("/").append(this.getExportName()); + } + + if (!StringUtils.isEmpty(this.options)) { + uriBuilder.append("?").append(this.options); + } + return uriBuilder.toString(); + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getExportName() { + return exportName; + } + + public void setExportName(String exportName) { + this.exportName = exportName; + } + + public String getOptions() { + return options; + } + + public void setOptions(String options) { + this.options = options; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/PackageInfo.java b/header/src/main/java/org/zstack/header/storage/backup/PackageInfo.java index f1276350c06..11bad2ebd58 100755 --- a/header/src/main/java/org/zstack/header/storage/backup/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/storage/backup/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "镜像服务器") +@PackageAPIInfo( + APICategoryName = "镜像服务器", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/storage/backup/PingBackupStorageReply.java b/header/src/main/java/org/zstack/header/storage/backup/PingBackupStorageReply.java index e5f956365ce..822b3177880 100755 --- a/header/src/main/java/org/zstack/header/storage/backup/PingBackupStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/backup/PingBackupStorageReply.java @@ -6,7 +6,6 @@ */ public class PingBackupStorageReply extends MessageReply { private boolean available; - private boolean connected; public boolean isAvailable() { return available; @@ -15,12 +14,4 @@ public boolean isAvailable() { public void setAvailable(boolean available) { this.available = available; } - - public boolean isConnected() { - return connected; - } - - public void setConnected(boolean connected) { - this.connected = connected; - } } diff --git a/header/src/main/java/org/zstack/header/storage/backup/RemoteTarget.java b/header/src/main/java/org/zstack/header/storage/backup/RemoteTarget.java new file mode 100644 index 00000000000..d44482742ec --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/RemoteTarget.java @@ -0,0 +1,10 @@ +package org.zstack.header.storage.backup; + +public interface RemoteTarget { + String getInstallPath(); + + String getTargetUri(); + + // for data network hostname + String getTargetUri(String hostname); +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/RemoteTargetProtocol.java b/header/src/main/java/org/zstack/header/storage/backup/RemoteTargetProtocol.java new file mode 100644 index 00000000000..02933e56a6d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/RemoteTargetProtocol.java @@ -0,0 +1,10 @@ +package org.zstack.header.storage.backup; + +/** + * @ Author : yh.w + * @ Date : Created in 15:16 2023/10/11 + */ +public enum RemoteTargetProtocol { + NBD, + HTTP +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/RestoreImagesBackupStorageMetadataToDatabaseMsg.java b/header/src/main/java/org/zstack/header/storage/backup/RestoreImagesBackupStorageMetadataToDatabaseMsg.java new file mode 100644 index 00000000000..ef4264c32e0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/RestoreImagesBackupStorageMetadataToDatabaseMsg.java @@ -0,0 +1,25 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.NeedReplyMessage; + +public class RestoreImagesBackupStorageMetadataToDatabaseMsg extends NeedReplyMessage implements BackupStorageMessage { + String imagesMetadata; + String backupStorageUuid; + + public String getImagesMetadata() { + return imagesMetadata; + } + + public void setImagesMetadata(String imagesMetadata) { + this.imagesMetadata = imagesMetadata; + } + + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/RestoreImagesBackupStorageMetadataToDatabaseReply.java b/header/src/main/java/org/zstack/header/storage/backup/RestoreImagesBackupStorageMetadataToDatabaseReply.java new file mode 100644 index 00000000000..83611f1a637 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/RestoreImagesBackupStorageMetadataToDatabaseReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class RestoreImagesBackupStorageMetadataToDatabaseReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/UploadImageToRemoteTargetMsg.java b/header/src/main/java/org/zstack/header/storage/backup/UploadImageToRemoteTargetMsg.java new file mode 100644 index 00000000000..847ddae23cb --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/UploadImageToRemoteTargetMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.image.ImageInventory; +import org.zstack.header.message.NeedReplyMessage; + +public class UploadImageToRemoteTargetMsg extends NeedReplyMessage implements BackupStorageMessage { + private ImageInventory image; + private String backupStorageUuid; + private String remoteTargetUrl; + private String format; + @Override + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public void setImage(ImageInventory image) { + this.image = image; + } + + public ImageInventory getImage() { + return image; + } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getRemoteTargetUrl() { + return remoteTargetUrl; + } + + public void setRemoteTargetUrl(String remoteTargetUrl) { + this.remoteTargetUrl = remoteTargetUrl; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/UploadImageToRemoteTargetReply.java b/header/src/main/java/org/zstack/header/storage/backup/UploadImageToRemoteTargetReply.java new file mode 100644 index 00000000000..9405181a49e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/UploadImageToRemoteTargetReply.java @@ -0,0 +1,24 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.MessageReply; + +public class UploadImageToRemoteTargetReply extends MessageReply { + private String installPath; + private long size; + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/backup/VolumeBackupOverlayMsg.java b/header/src/main/java/org/zstack/header/storage/backup/VolumeBackupOverlayMsg.java new file mode 100755 index 00000000000..207205f7b8a --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/backup/VolumeBackupOverlayMsg.java @@ -0,0 +1,17 @@ +package org.zstack.header.storage.backup; + +import org.zstack.header.message.OverlayMessage; +import org.zstack.header.volume.VolumeMessage; + +public class VolumeBackupOverlayMsg extends OverlayMessage implements VolumeMessage { + private String volumeUuid; + + @Override + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAddPrimaryStorageEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APIAddPrimaryStorageEvent.java index 8c5e0f0ccc9..35928cf6e0c 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APIAddPrimaryStorageEvent.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAddPrimaryStorageEvent.java @@ -1,5 +1,7 @@ package org.zstack.header.storage.primary; +import org.zstack.header.log.MaskSensitiveInfo; +import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; @@ -30,10 +32,13 @@ * @since 0.1.0 */ @RestResponse(allTo = "inventory") +@MaskSensitiveInfo public class APIAddPrimaryStorageEvent extends APIEvent { /** * @desc see :ref:`PrimaryStorageInventory` */ + + @NoLogging(behavior = NoLogging.Behavior.Auto) private PrimaryStorageInventory inventory; public APIAddPrimaryStorageEvent(String apiId) { diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolEvent.java new file mode 100644 index 00000000000..6c2c2d3823f --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolEvent.java @@ -0,0 +1,19 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIAddStorageProtocolEvent extends APIEvent { + public APIAddStorageProtocolEvent() { + } + + public APIAddStorageProtocolEvent(String apiId) { + super(apiId); + } + + public static APIAddStorageProtocolEvent __example__() { + APIAddStorageProtocolEvent event = new APIAddStorageProtocolEvent(); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..9b1ea49ecc0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.storage.primary + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "添加存储协议event" + + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.header.storage.primary.APIAddStorageProtocolEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolMsg.java b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolMsg.java new file mode 100644 index 00000000000..5f885d338e1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolMsg.java @@ -0,0 +1,52 @@ +package org.zstack.header.storage.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.volume.VolumeProtocol; + +@RestRequest( + path = "/primary-storage/protocol", + responseClass = APIAddStorageProtocolEvent.class, + method = HttpMethod.POST, + parameterName = "params" +) +public class APIAddStorageProtocolMsg extends APIMessage implements PrimaryStorageMessage { + /** + * @desc primary storage uuid + */ + @APIParam(resourceType = PrimaryStorageVO.class) + private String uuid; + + @APIParam + private String outputProtocol; + + @Override + public String getPrimaryStorageUuid() { + return uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getOutputProtocol() { + return outputProtocol; + } + + public void setOutputProtocol(String outputProtocol) { + this.outputProtocol = outputProtocol; + } + + public static APIAddStorageProtocolMsg __example__() { + APIAddStorageProtocolMsg msg = new APIAddStorageProtocolMsg(); + msg.setUuid(uuid()); + msg.setOutputProtocol(VolumeProtocol.iSCSI.toString()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..728d3f6bfe0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAddStorageProtocolMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.storage.primary + +import org.zstack.header.storage.primary.APIAddStorageProtocolEvent + +doc { + title "AddStorageProtocol" + + category "storage.primary" + + desc """添加存储协议""" + + rest { + request { + url "POST /v1/primary-storage/protocol" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAddStorageProtocolMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "params" + desc "资源的UUID,唯一标示该资源" + location "body" + type "String" + optional false + since "5.1.0" + } + column { + name "outputProtocol" + enclosedIn "params" + desc "输出协议" + location "body" + type "String" + optional false + since "5.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIAddStorageProtocolEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterEvent.java index 2ed4883d143..fa70af583ea 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterEvent.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterEvent.java @@ -1,5 +1,7 @@ package org.zstack.header.storage.primary; +import org.zstack.header.log.MaskSensitiveInfo; +import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; @@ -32,10 +34,12 @@ * @since 0.1.0 */ @RestResponse(allTo = "inventory") +@MaskSensitiveInfo public class APIAttachPrimaryStorageToClusterEvent extends APIEvent { /** * @desc see :ref:`PrimaryStorageInventory` */ + @NoLogging(behavior = NoLogging.Behavior.Auto) private PrimaryStorageInventory inventory; public APIAttachPrimaryStorageToClusterEvent() { diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsg.java b/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsg.java index fcbaf2c7e0a..05a32a3e5cc 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsg.java @@ -36,6 +36,7 @@ @RestRequest( path = "/clusters/{clusterUuid}/primary-storage/{primaryStorageUuid}", method = HttpMethod.POST, + parameterName = "params", responseClass = APIAttachPrimaryStorageToClusterEvent.class ) public class APIAttachPrimaryStorageToClusterMsg extends APIMessage implements PrimaryStorageMessage { diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsgDoc_zh_cn.groovy index 5afdc760d5a..eaab006002d 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIAttachPrimaryStorageToClusterMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "clusterUuid" - enclosedIn "" + enclosedIn "params" desc "集群UUID" location "url" type "String" optional false since "0.6" - } column { name "primaryStorageUuid" - enclosedIn "" + enclosedIn "params" desc "主存储UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIChangePrimaryStorageStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIChangePrimaryStorageStateMsgDoc_zh_cn.groovy index 13ffdd259d5..951d4bfbc63 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIChangePrimaryStorageStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIChangePrimaryStorageStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsg.java index 0604aa016c3..981f6ad1943 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsg.java @@ -41,8 +41,6 @@ public String getPrimaryStorageUuid() { return uuid; } - - public static APICleanUpImageCacheOnPrimaryStorageMsg __example__() { APICleanUpImageCacheOnPrimaryStorageMsg msg = new APICleanUpImageCacheOnPrimaryStorageMsg(); msg.setUuid(uuid()); diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsgDoc_zh_cn.groovy index 8b79076e09d..3462a7a2e15 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpImageCacheOnPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,17 +47,15 @@ doc { type "List" optional true since "0.6" - } column { name "force" - enclosedIn "" + enclosedIn "cleanUpImageCacheOnPrimaryStorage" desc "是否强制删除" - location "url" + location "body" type "boolean" - optional false + optional true since "4.0.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageEvent.java new file mode 100644 index 00000000000..547b9da04ea --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageEvent.java @@ -0,0 +1,42 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.util.List; +import java.util.Map; + +@RestResponse(fieldsTo = {"all"}) +public class APICleanUpStorageTrashOnPrimaryStorageEvent extends APIEvent { + private Map> result; + private Integer total; + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + public Map> getResult() { + return result; + } + + public void setResult(Map> result) { + this.result = result; + } + + public APICleanUpStorageTrashOnPrimaryStorageEvent(String apiId) { + super(apiId); + } + + public APICleanUpStorageTrashOnPrimaryStorageEvent() { + } + + public static APICleanUpStorageTrashOnPrimaryStorageEvent __example__() { + APICleanUpStorageTrashOnPrimaryStorageEvent event = new APICleanUpStorageTrashOnPrimaryStorageEvent(); + event.setTotal(1); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..3320b2ad425 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageEventDoc_zh_cn.groovy @@ -0,0 +1,35 @@ +package org.zstack.header.storage.primary + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "清空主存储垃圾结果" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.header.storage.primary.APICleanUpStorageTrashOnPrimaryStorageEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } + field { + name "result" + desc "清理成功的存储垃圾的集合" + type "Map" + since "4.8.0" + } + field { + name "total" + desc "清理成功的存储垃圾的数量" + type "Integer" + since "4.8.0" + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..4d2b219d76b --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageMsg.java @@ -0,0 +1,46 @@ +package org.zstack.header.storage.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/primary-storage/{uuid}/storagetrash/actions", + isAction = true, + responseClass = APICleanUpStorageTrashOnPrimaryStorageEvent.class, + method = HttpMethod.PUT +) +public class APICleanUpStorageTrashOnPrimaryStorageMsg extends APIMessage implements PrimaryStorageMessage { + @APIParam(resourceType = PrimaryStorageVO.class, checkAccount = true) + private String uuid; + @APIParam(required = false) + private boolean force; + + @Override + public String getPrimaryStorageUuid() { + return uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public static APICleanUpStorageTrashOnPrimaryStorageMsg __example__() { + APICleanUpStorageTrashOnPrimaryStorageMsg msg = new APICleanUpStorageTrashOnPrimaryStorageMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..621df951eb2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpStorageTrashOnPrimaryStorageMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.storage.primary + +import org.zstack.header.storage.primary.APICleanUpStorageTrashOnPrimaryStorageEvent + +doc { + title "清空主存储垃圾(CleanUpStorageTrashOnPrimaryStorage)" + + category "storage.primary" + + desc """清空主存储垃圾""" + + rest { + request { + url "PUT /v1/primary-storage/{uuid}/storagetrash/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICleanUpStorageTrashOnPrimaryStorageMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "cleanUpStorageTrashOnPrimaryStorage" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.8.0" + } + column { + name "force" + enclosedIn "cleanUpStorageTrashOnPrimaryStorage" + desc "是否强制清理主存储垃圾" + location "body" + type "boolean" + optional true + since "4.8.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APICleanUpStorageTrashOnPrimaryStorageEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEvent.java index 5bd4f587228..0c1b3e6efb1 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEvent.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEvent.java @@ -1,17 +1,20 @@ package org.zstack.header.storage.primary; import org.zstack.header.core.trash.CleanTrashResult; +import org.zstack.header.core.trash.TrashCleanupResult; import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; import java.util.Collections; +import java.util.List; /** * Created by mingjian.deng on 2018/12/10. */ -@RestResponse(allTo = "result") +@RestResponse(fieldsTo = {"all"}) public class APICleanUpTrashOnPrimaryStorageEvent extends APIEvent { private CleanTrashResult result; + private List results; public CleanTrashResult getResult() { return result; @@ -21,6 +24,14 @@ public void setResult(CleanTrashResult result) { this.result = result; } + public List getResults() { + return results; + } + + public void setResults(List results) { + this.results = results; + } + public APICleanUpTrashOnPrimaryStorageEvent(String apiId) { super(apiId); } @@ -37,6 +48,7 @@ public static APICleanUpTrashOnPrimaryStorageEvent __example__() { cleaned.setSize(1024000L); event.setResult(cleaned); + event.setResults(Collections.singletonList(new TrashCleanupResult(uuid, 1, 1024000L))); return event; } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEventDoc_zh_cn.groovy index ef73397a544..676b3be8d99 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEventDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageEventDoc_zh_cn.groovy @@ -1,5 +1,6 @@ package org.zstack.header.storage.primary +import org.zstack.header.core.trash.TrashCleanupResult import org.zstack.header.errorcode.ErrorCode import org.zstack.header.core.trash.CleanTrashResult @@ -29,4 +30,12 @@ doc { since "3.3.0" clz CleanTrashResult.class } + ref { + name "results" + path "org.zstack.header.storage.primary.APICleanUpTrashOnPrimaryStorageEvent.results" + desc "清理数据返回信息" + type "List" + since "4.7.0" + clz TrashCleanupResult.class + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsg.java index f0c4901a6e3..bfe7a8bec73 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsg.java @@ -1,6 +1,9 @@ package org.zstack.header.storage.primary; import org.springframework.http.HttpMethod; +import org.zstack.header.core.trash.TrashCleanupResult; +import org.zstack.header.message.APIBatchRequest; +import org.zstack.header.message.APIEvent; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.rest.RestRequest; @@ -14,7 +17,7 @@ responseClass = APICleanUpTrashOnPrimaryStorageEvent.class, method = HttpMethod.PUT ) -public class APICleanUpTrashOnPrimaryStorageMsg extends APIMessage implements PrimaryStorageMessage { +public class APICleanUpTrashOnPrimaryStorageMsg extends APIMessage implements PrimaryStorageMessage, APIBatchRequest { @APIParam(resourceType = PrimaryStorageVO.class, checkAccount = true) private String uuid; @APIParam(required = false) @@ -47,4 +50,14 @@ public static APICleanUpTrashOnPrimaryStorageMsg __example__() { return msg; } + + @Override + public Result collectResult(APIMessage message, APIEvent rsp) { + APICleanUpTrashOnPrimaryStorageEvent evt = (APICleanUpTrashOnPrimaryStorageEvent) rsp; + return new Result(evt.getResults().size(), + evt.getResults().stream() + .filter(TrashCleanupResult::isSuccess) + .toArray().length + ); + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsgDoc_zh_cn.groovy index 7029e83671b..a55c4084367 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APICleanUpTrashOnPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.2.0" - } column { name "trashId" @@ -39,7 +38,6 @@ doc { type "Long" optional true since "3.3.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.2.0" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.2.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIDeletePrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIDeletePrimaryStorageMsgDoc_zh_cn.groovy index 7cce7ea0e08..e40b1b76051 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIDeletePrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIDeletePrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterEvent.java index b5fc15c8d34..226908e831b 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterEvent.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterEvent.java @@ -1,5 +1,7 @@ package org.zstack.header.storage.primary; +import org.zstack.header.log.MaskSensitiveInfo; +import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; @@ -33,6 +35,7 @@ * @since 0.1.0 */ @RestResponse(allTo = "inventory") +@MaskSensitiveInfo public class APIDetachPrimaryStorageFromClusterEvent extends APIEvent { public APIDetachPrimaryStorageFromClusterEvent() { super(null); @@ -45,6 +48,7 @@ public APIDetachPrimaryStorageFromClusterEvent(String apiId) { /** * @desc see :ref:`PrimaryStorageInventory` */ + @NoLogging(behavior = NoLogging.Behavior.Auto) private PrimaryStorageInventory inventory; public PrimaryStorageInventory getInventory() { diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterMsgDoc_zh_cn.groovy index bbbdf0d2f31..12fbd5b1245 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIDetachPrimaryStorageFromClusterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "clusterUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageAllocatorStrategiesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageAllocatorStrategiesMsgDoc_zh_cn.groovy index 2da09828739..f85edefa701 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageAllocatorStrategiesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageAllocatorStrategiesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageCapacityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageCapacityMsgDoc_zh_cn.groovy index bdc2428688f..1bcf2b39332 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageCapacityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageCapacityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "clusterUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "primaryStorageUuids" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "all" @@ -59,7 +56,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageLicenseInfoMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageLicenseInfoMsgDoc_zh_cn.groovy index fbacfdea213..a3f9cc33e7d 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageLicenseInfoMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageLicenseInfoMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.6.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageTypesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageTypesMsgDoc_zh_cn.groovy index db8d6d97302..b38de6a6ece 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageTypesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageTypesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportMsg.java b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportMsg.java new file mode 100644 index 00000000000..e330ad9f53c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportMsg.java @@ -0,0 +1,42 @@ +package org.zstack.header.storage.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +@RestRequest( + path = "/primary-storage/{primaryStorageUuid}/usage/report", + method = HttpMethod.GET, + responseClass = APIGetPrimaryStorageUsageReportReply.class +) +public class APIGetPrimaryStorageUsageReportMsg extends APISyncCallMessage { + @APIParam(resourceType = PrimaryStorageVO.class) + private String primaryStorageUuid; + @APIParam(required = false) + private List uris; + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public List getUris() { + return uris; + } + + public void setUris(List uris) { + this.uris = uris; + } + + public static APIGetPrimaryStorageUsageReportMsg __example__() { + APIGetPrimaryStorageUsageReportMsg msg = new APIGetPrimaryStorageUsageReportMsg(); + msg.setPrimaryStorageUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..376bf1699fb --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.storage.primary + +import org.zstack.header.storage.primary.APIGetPrimaryStorageUsageReportReply + +doc { + title "GetPrimaryStorageUsageReport" + + category "storage.primary" + + desc """获取主存储预测容量报告""" + + rest { + request { + url "GET /v1/primary-storage/{primaryStorageUuid}/usage/report" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetPrimaryStorageUsageReportMsg.class + + desc """""" + + params { + + column { + name "primaryStorageUuid" + enclosedIn "" + desc "主存储UUID" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "uris" + enclosedIn "" + desc "存储协议" + location "query" + type "List" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIGetPrimaryStorageUsageReportReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportReply.java b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportReply.java new file mode 100644 index 00000000000..a1b7c09dcbe --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportReply.java @@ -0,0 +1,38 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.Map; + +@RestResponse(fieldsTo = {"all"}) +public class APIGetPrimaryStorageUsageReportReply extends APIReply { + private Map uriUsageForecast; + private UsageReport usageReport; + + public Map getUriUsageForecast() { + return uriUsageForecast; + } + + public void setUriUsageForecast(Map uriUsageForecast) { + this.uriUsageForecast = uriUsageForecast; + } + + public UsageReport getUsageReport() { + return usageReport; + } + + public void setUsageReport(UsageReport usageReport) { + this.usageReport = usageReport; + } + + public static APIGetPrimaryStorageUsageReportReply __example__() { + APIGetPrimaryStorageUsageReportReply reply = new APIGetPrimaryStorageUsageReportReply(); + + reply.setUsageReport(new UsageReport()); + reply.setUriUsageForecast(new java.util.HashMap()); + + return reply; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..4a52a5b7f1b --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetPrimaryStorageUsageReportReplyDoc_zh_cn.groovy @@ -0,0 +1,40 @@ +package org.zstack.header.storage.primary + +import org.zstack.header.storage.primary.UsageReport +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取主存储预测容量报告返回" + + ref { + name "uriUsageForecast" + path "org.zstack.header.storage.primary.APIGetPrimaryStorageUsageReportReply.uriUsageForecast" + desc "null" + type "Map" + since "4.7.21" + clz UsageReport.class + } + ref { + name "usageReport" + path "org.zstack.header.storage.primary.APIGetPrimaryStorageUsageReportReply.usageReport" + desc "null" + type "UsageReport" + since "4.7.21" + clz UsageReport.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.storage.primary.APIGetPrimaryStorageUsageReportReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIGetTrashOnPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIGetTrashOnPrimaryStorageMsgDoc_zh_cn.groovy index e84214c3712..8a868918e57 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIGetTrashOnPrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIGetTrashOnPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.2.0" - } column { name "resourceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.5.0" - } column { name "resourceType" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.5.0" - } column { name "trashType" @@ -59,7 +56,7 @@ doc { type "String" optional true since "3.5.0" - values ("MigrateVolume", "MigrateVolumeSnapshot", "RevertVolume", "VolumeSnapshot") + values ("MigrateVolume","MigrateVolumeSnapshot","RevertVolume","VolumeSnapshot") } column { name "systemTags" @@ -69,7 +66,6 @@ doc { type "List" optional true since "3.2.0" - } column { name "userTags" @@ -79,7 +75,6 @@ doc { type "List" optional true since "3.2.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIQueryImageCacheMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIQueryImageCacheMsgDoc_zh_cn.groovy index 79b131431cb..b43531edfff 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIQueryImageCacheMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIQueryImageCacheMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.storage.primary import org.zstack.header.storage.primary.APIQueryImageCacheReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryImageCache" diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageMsgDoc_zh_cn.groovy index e0fa4973a7c..d712eb383f7 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.storage.primary import org.zstack.header.storage.primary.APIQueryPrimaryStorageReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryPrimaryStorage" diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageReply.java index 3ee438b6576..2b770f72537 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APIQueryPrimaryStorageReply.java @@ -1,5 +1,7 @@ package org.zstack.header.storage.primary; +import org.zstack.header.log.MaskSensitiveInfo; +import org.zstack.header.log.NoLogging; import org.zstack.header.query.APIQueryReply; import org.zstack.header.rest.RestResponse; @@ -7,7 +9,9 @@ import java.util.List; @RestResponse(allTo = "inventories") +@MaskSensitiveInfo public class APIQueryPrimaryStorageReply extends APIQueryReply { + @NoLogging(behavior = NoLogging.Behavior.Auto) private List inventories; public List getInventories() { diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIReconnectPrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIReconnectPrimaryStorageMsgDoc_zh_cn.groovy index 6f70574f57f..feacb5310e5 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIReconnectPrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIReconnectPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APISyncPrimaryStorageCapacityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APISyncPrimaryStorageCapacityMsgDoc_zh_cn.groovy index 15aa1954cf3..1d658b097bc 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APISyncPrimaryStorageCapacityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APISyncPrimaryStorageCapacityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageEvent.java b/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageEvent.java index b0371d8eaa9..4812f336958 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageEvent.java +++ b/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageEvent.java @@ -1,5 +1,7 @@ package org.zstack.header.storage.primary; +import org.zstack.header.log.MaskSensitiveInfo; +import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIEvent; import org.zstack.header.rest.RestResponse; @@ -9,7 +11,9 @@ * Created by frank on 6/14/2015. */ @RestResponse(allTo = "inventory") +@MaskSensitiveInfo public class APIUpdatePrimaryStorageEvent extends APIEvent { + @NoLogging(behavior = NoLogging.Behavior.Auto) private PrimaryStorageInventory inventory; public PrimaryStorageInventory getInventory() { diff --git a/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageMsgDoc_zh_cn.groovy index 552400ac182..198aab582d4 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/primary/APIUpdatePrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/AfterCreateImageCacheExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/primary/AfterCreateImageCacheExtensionPoint.java index 0e0d36615c0..516be2ac0dd 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/AfterCreateImageCacheExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/storage/primary/AfterCreateImageCacheExtensionPoint.java @@ -8,7 +8,7 @@ * @Date: 2021/11/16 */ public interface AfterCreateImageCacheExtensionPoint { - void saveEncryptAfterCreateImageCache(String hostUuid, ImageCacheInventory inventory); + void saveEncryptAfterCreateImageCache(String hostUuid, ImageCacheInventory inventory, Completion completion); void checkEncryptImageCache(String hostUuid, ImageCacheInventory inventory, Completion completion); } diff --git a/header/src/main/java/org/zstack/header/storage/primary/AllocatePrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/AllocatePrimaryStorageMsg.java index 66f0cf1b0c0..5126ffa2883 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/AllocatePrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/AllocatePrimaryStorageMsg.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; /** * Allocate PrimaryStorage @@ -17,10 +18,11 @@ public class AllocatePrimaryStorageMsg extends NeedReplyMessage { private String requiredZoneUuid; private List requiredClusterUuids; private String requiredHostUuid; - private String requiredPrimaryStorageUuid; + private final List candidatePrimaryStorageUuids = new ArrayList<>(); private String backupStorageUuid; private List possiblePrimaryStorageTypes; private List excludePrimaryStorageTypes; + private Set requiredFeatures; private Long totalSize = null; private long size; @@ -32,10 +34,25 @@ public class AllocatePrimaryStorageMsg extends NeedReplyMessage { private List excludePrimaryStorageUuids; private List excludeAllocatorStrategies; private String imageUuid; + /** + * Allocate PrimaryStorage + * * @deprecated + * * This parameter is no longer acceptable to allocate PrimaryStorage. + * *

    Use msg.setRequiredInstallUri("volume://volumeUuid") instead. + */ + @Deprecated private String volumeUuid; private boolean noOverProvisioning; private String purpose; + public Set getRequiredFeatures() { + return requiredFeatures; + } + + public void setRequiredFeatures(Set requiredFeatures) { + this.requiredFeatures = requiredFeatures; + } + public List getExcludePrimaryStorageTypes() { return excludePrimaryStorageTypes; } @@ -130,12 +147,27 @@ public void setDiskOfferingUuid(String diskOfferingUuid) { this.diskOfferingUuid = diskOfferingUuid; } + @Deprecated public String getRequiredPrimaryStorageUuid() { - return requiredPrimaryStorageUuid; + return this.candidatePrimaryStorageUuids.isEmpty() ? null : this.candidatePrimaryStorageUuids.get(0); } public void setRequiredPrimaryStorageUuid(String requiredPrimaryStorageUuid) { - this.requiredPrimaryStorageUuid = requiredPrimaryStorageUuid; + this.candidatePrimaryStorageUuids.clear(); + if (requiredPrimaryStorageUuid != null) { + this.candidatePrimaryStorageUuids.add(requiredPrimaryStorageUuid); + } + } + + public List getCandidatePrimaryStorageUuids() { + return candidatePrimaryStorageUuids; + } + + public void setCandidatePrimaryStorageUuids(List candidatePrimaryStorageUuids) { + this.candidatePrimaryStorageUuids.clear(); + if (candidatePrimaryStorageUuids != null) { + this.candidatePrimaryStorageUuids.addAll(candidatePrimaryStorageUuids); + } } public String getAllocationStrategy() { diff --git a/header/src/main/java/org/zstack/header/storage/primary/CheckChangeVolumeTypeOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/CheckChangeVolumeTypeOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..79386adb624 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CheckChangeVolumeTypeOnPrimaryStorageMsg.java @@ -0,0 +1,31 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeType; + +public class CheckChangeVolumeTypeOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private VolumeInventory volume; + private VolumeType targetType; + + @Override + public String getPrimaryStorageUuid() { + return volume.getPrimaryStorageUuid(); + } + + public VolumeType getTargetType() { + return targetType; + } + + public void setTargetType(VolumeType targetType) { + this.targetType = targetType; + } + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CheckChangeVolumeTypeOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/CheckChangeVolumeTypeOnPrimaryStorageReply.java new file mode 100644 index 00000000000..48b078cf68c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CheckChangeVolumeTypeOnPrimaryStorageReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +/** + * Created by MaJin on 2021/6/4. + */ +public class CheckChangeVolumeTypeOnPrimaryStorageReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CheckInstallPathInTrashReply.java b/header/src/main/java/org/zstack/header/storage/primary/CheckInstallPathInTrashReply.java index f1e0372a5c8..7eebf88e616 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/CheckInstallPathInTrashReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/CheckInstallPathInTrashReply.java @@ -2,12 +2,15 @@ import org.zstack.header.message.MessageReply; +import java.util.List; + /** * Created by mingjian.deng on 2018/12/25. */ public class CheckInstallPathInTrashReply extends MessageReply { private Long trashId; private String resourceUuid; + private List relatedTrashPaths; public Long getTrashId() { return trashId; @@ -24,4 +27,12 @@ public String getResourceUuid() { public void setResourceUuid(String resourceUuid) { this.resourceUuid = resourceUuid; } + + public List getRelatedTrashPaths() { + return relatedTrashPaths; + } + + public void setRelatedTrashPaths(List relatedTrashPaths) { + this.relatedTrashPaths = relatedTrashPaths; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/CleanUpStorageTrashOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/CleanUpStorageTrashOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..10fdd1ed797 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CleanUpStorageTrashOnPrimaryStorageMsg.java @@ -0,0 +1,26 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.primary.PrimaryStorageMessage; + +public class CleanUpStorageTrashOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + String primaryStorageUuid; + boolean force; + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CleanUpStorageTrashOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/CleanUpStorageTrashOnPrimaryStorageReply.java new file mode 100644 index 00000000000..e3881d3486b --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CleanUpStorageTrashOnPrimaryStorageReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CleanUpStorageTrashOnPrimaryStorageReply extends MessageReply { + private Map> result = new HashMap<>(); + + public Map> getResult() { + return result; + } + + public void setResult(Map> result) { + this.result = result; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CommitVolumeSnapshotOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/CommitVolumeSnapshotOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..8e1595df39c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CommitVolumeSnapshotOnPrimaryStorageMsg.java @@ -0,0 +1,52 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeInventory; + +import java.util.ArrayList; +import java.util.List; + +public class CommitVolumeSnapshotOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private VolumeInventory volume; + private VolumeSnapshotInventory srcSnapshot; + private VolumeSnapshotInventory dstSnapshot; + private List srcChildrenInstallPathInDb = new ArrayList<>(); + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } + + public VolumeSnapshotInventory getSrcSnapshot() { + return srcSnapshot; + } + + public void setSrcSnapshot(VolumeSnapshotInventory srcSnapshot) { + this.srcSnapshot = srcSnapshot; + } + + public VolumeSnapshotInventory getDstSnapshot() { + return dstSnapshot; + } + + public void setDstSnapshot(VolumeSnapshotInventory dstSnapshot) { + this.dstSnapshot = dstSnapshot; + } + + public List getSrcChildrenInstallPathInDb() { + return srcChildrenInstallPathInDb; + } + + public void setSrcChildrenInstallPathInDb(List srcChildrenInstallPathInDb) { + this.srcChildrenInstallPathInDb = srcChildrenInstallPathInDb; + } + + @Override + public String getPrimaryStorageUuid() { + return srcSnapshot.getPrimaryStorageUuid(); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CommitVolumeSnapshotOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/CommitVolumeSnapshotOnPrimaryStorageReply.java new file mode 100644 index 00000000000..d5f87e1ab9f --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CommitVolumeSnapshotOnPrimaryStorageReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class CommitVolumeSnapshotOnPrimaryStorageReply extends MessageReply { + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply.java index 00dcb29743d..ed4d91edb99 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply.java @@ -8,7 +8,8 @@ */ public class CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply extends MessageReply { private String locateHostUuid; - private long actualSize; + private ImageCacheInventory inventory; + private boolean incremental; public String getLocateHostUuid() { return locateHostUuid; @@ -19,10 +20,22 @@ public void setLocateHostUuid(String locateHostUuid) { } public long getActualSize() { - return actualSize; + return inventory == null ? 0 : inventory.getSize(); } - public void setActualSize(long actualSize) { - this.actualSize = actualSize; + public void setInventory(ImageCacheInventory inventory) { + this.inventory = inventory; + } + + public ImageCacheInventory getInventory() { + return inventory; + } + + public void setIncremental(boolean incremental) { + this.incremental = incremental; + } + + public boolean isIncremental() { + return incremental; } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..b1e6831d5d2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg.java @@ -0,0 +1,13 @@ +package org.zstack.header.storage.primary; + +public class CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg extends CreateTemplateFromVolumeOnPrimaryStorageMsg { + private String snapshotUuid; + + public String getSnapshotUuid() { + return snapshotUuid; + } + + public void setSnapshotUuid(String snapshotUuid) { + this.snapshotUuid = snapshotUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply.java index 42ed37b6fa6..32626d98ce5 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply.java @@ -8,6 +8,8 @@ public class CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply extends Message private String installPath; private long size; private long actualSize; + private String protocol; + private boolean incremental; public long getActualSize() { return actualSize; @@ -32,4 +34,20 @@ public long getSize() { public void setSize(long size) { this.size = size; } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public void setIncremental(boolean incremental) { + this.incremental = incremental; + } + + public boolean isIncremental() { + return incremental; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/DecreasePrimaryStorageCapacityMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DecreasePrimaryStorageCapacityMsg.java index cb38ee1f68a..c276eb4695e 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/DecreasePrimaryStorageCapacityMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DecreasePrimaryStorageCapacityMsg.java @@ -4,7 +4,9 @@ /** * Created by AlanJager on 2017/3/28. + * *

    Use {@link AllocatePrimaryStorageSpaceMsg} instead. */ +@Deprecated public class DecreasePrimaryStorageCapacityMsg extends Message { private String primaryStorageUuid; private long diskSize; diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteBitsOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteBitsOnPrimaryStorageMsg.java index 3953e611a59..513e8c9b73d 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/DeleteBitsOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteBitsOnPrimaryStorageMsg.java @@ -7,12 +7,16 @@ * we just delete bits * @see DeleteVolumeBitsOnPrimaryStorageMsg */ +@Deprecated public class DeleteBitsOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { private String primaryStorageUuid; private String installPath; private String hostUuid; + private String format; private boolean folder; + private boolean recycle = true; + @Override public String getPrimaryStorageUuid() { return primaryStorageUuid; @@ -46,4 +50,19 @@ public void setHostUuid(String hostUuid) { this.hostUuid = hostUuid; } + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public boolean isRecycle() { + return recycle; + } + + public void setRecycle(boolean recycle) { + this.recycle = recycle; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteOnPrimaryStorageMessage.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteOnPrimaryStorageMessage.java new file mode 100644 index 00000000000..e3e6acec382 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteOnPrimaryStorageMessage.java @@ -0,0 +1,5 @@ +package org.zstack.header.storage.primary; + +public interface DeleteOnPrimaryStorageMessage extends PrimaryStorageMessage { + boolean isGcOnFailure(); +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageMsg.java index ff8302a44ba..839eecf6e85 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageMsg.java @@ -5,8 +5,9 @@ /** */ -public class DeleteSnapshotOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { +public class DeleteSnapshotOnPrimaryStorageMsg extends NeedReplyMessage implements DeleteOnPrimaryStorageMessage { private VolumeSnapshotInventory snapshot; + private boolean gcOnFailure = false; @Override public String getPrimaryStorageUuid() { @@ -20,4 +21,13 @@ public VolumeSnapshotInventory getSnapshot() { public void setSnapshot(VolumeSnapshotInventory snapshot) { this.snapshot = snapshot; } + + @Override + public boolean isGcOnFailure() { + return gcOnFailure; + } + + public void setGcOnFailure(boolean gcOnFailure) { + this.gcOnFailure = gcOnFailure; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageReply.java index ed29cbe5e69..39a8a89bf44 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteSnapshotOnPrimaryStorageReply.java @@ -5,4 +5,13 @@ /** */ public class DeleteSnapshotOnPrimaryStorageReply extends MessageReply { + private boolean gcSubmitted = false; + + public void setGcSubmitted(boolean gcSubmitted) { + this.gcSubmitted = gcSubmitted; + } + + public boolean isGcSubmitted() { + return gcSubmitted; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeBitsOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeBitsOnPrimaryStorageMsg.java index df564547915..41db725eacc 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeBitsOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeBitsOnPrimaryStorageMsg.java @@ -17,6 +17,15 @@ public class DeleteVolumeBitsOnPrimaryStorageMsg extends NeedReplyMessage implem private String hostUuid; // used for recycle, true means only delete install path, not delete volume private boolean fromRecycle; + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } public String getBitsUuid() { return bitsUuid; diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeChainOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeChainOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..f635eb61318 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeChainOnPrimaryStorageMsg.java @@ -0,0 +1,71 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.utils.CollectionUtils; + +import java.util.List; + +public class DeleteVolumeChainOnPrimaryStorageMsg extends NeedReplyMessage implements DeleteOnPrimaryStorageMessage { + private String primaryStorageUuid; + // TODO remove this field, use url instead + private String hostUuid; + + private List installPaths; + + private String volumeFormat; + + // TODO refactor, remove it + // for gc, used to deduplicate GC + private String chainTop; + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setInstallPaths(List installPaths) { + this.installPaths = installPaths; + } + + public List getInstallPaths() { + return installPaths; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVolumeFormat() { + return volumeFormat; + } + + public void setVolumeFormat(String volumeFormat) { + this.volumeFormat = volumeFormat; + } + + public String getChainTop() { + if (chainTop != null) { + return chainTop; + } else if (!CollectionUtils.isEmpty(installPaths)) { + return installPaths.get(0); + } + return null; + } + + public void setChainTop(String chainTop) { + this.chainTop = chainTop; + } + + @Override + public boolean isGcOnFailure() { + return true; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeChainOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeChainOnPrimaryStorageReply.java new file mode 100644 index 00000000000..3602f203e85 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeChainOnPrimaryStorageReply.java @@ -0,0 +1,18 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +import java.util.ArrayList; +import java.util.List; + +public class DeleteVolumeChainOnPrimaryStorageReply extends MessageReply { + private List undeletedInstallPaths = new ArrayList<>(); + + public List getUndeletedInstallPaths() { + return undeletedInstallPaths; + } + + public void setUndeletedInstallPaths(List undeletedInstallPaths) { + this.undeletedInstallPaths = undeletedInstallPaths; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeQosOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeQosOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..9f6008e2e1a --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeQosOnPrimaryStorageMsg.java @@ -0,0 +1,25 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; + +public class DeleteVolumeQosOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private String volumeUuid; + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getVolumeUuid() { + return volumeUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeQosOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeQosOnPrimaryStorageReply.java new file mode 100644 index 00000000000..0aea01cae27 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DeleteVolumeQosOnPrimaryStorageReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class DeleteVolumeQosOnPrimaryStorageReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DownloadBitsFromRemoteTargetOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DownloadBitsFromRemoteTargetOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..1f532cf81c6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DownloadBitsFromRemoteTargetOnPrimaryStorageMsg.java @@ -0,0 +1,40 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.message.NeedReplyMessage; + +import java.util.concurrent.TimeUnit; + +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 72) +public class DownloadBitsFromRemoteTargetOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private String primaryStorageInstallPath; + @NoLogging + private String remoteTargetUri; + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getPrimaryStorageInstallPath() { + return primaryStorageInstallPath; + } + + public void setPrimaryStorageInstallPath(String primaryStorageInstallPath) { + this.primaryStorageInstallPath = primaryStorageInstallPath; + } + + public String getRemoteTargetUri() { + return remoteTargetUri; + } + + public void setRemoteTargetUri(String remoteTargetUri) { + this.remoteTargetUri = remoteTargetUri; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DownloadBitsFromRemoteTargetOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/DownloadBitsFromRemoteTargetOnPrimaryStorageReply.java new file mode 100644 index 00000000000..6c71417a2c7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/DownloadBitsFromRemoteTargetOnPrimaryStorageReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class DownloadBitsFromRemoteTargetOnPrimaryStorageReply extends MessageReply { + private long diskSize; + + public long getDiskSize() { + return diskSize; + } + + public void setDiskSize(long diskSize) { + this.diskSize = diskSize; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageMsg.java index 6f3ea9aac6f..2dd1e359eed 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageMsg.java @@ -11,6 +11,15 @@ public class DownloadDataVolumeToPrimaryStorageMsg extends NeedReplyMessage impl private ImageInventory image; private String volumeUuid; private String hostUuid; + private String allocatedInstallUrl; + + public String getAllocatedInstallUrl() { + return allocatedInstallUrl; + } + + public void setAllocatedInstallUrl(String allocatedInstallUrl) { + this.allocatedInstallUrl = allocatedInstallUrl; + } public String getHostUuid() { return hostUuid; diff --git a/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageReply.java index 0a912149827..d1ae53ea591 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DownloadDataVolumeToPrimaryStorageReply.java @@ -7,6 +7,7 @@ public class DownloadDataVolumeToPrimaryStorageReply extends MessageReply { private String installPath; private String format; + private String protocol; public String getFormat() { return format; @@ -23,4 +24,12 @@ public String getInstallPath() { public void setInstallPath(String installPath) { this.installPath = installPath; } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/DownloadIsoToPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/DownloadIsoToPrimaryStorageReply.java index e91e4104963..c40e6e8ead6 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/DownloadIsoToPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/DownloadIsoToPrimaryStorageReply.java @@ -8,6 +8,8 @@ public class DownloadIsoToPrimaryStorageReply extends MessageReply { private String installPath; + private String protocol; + public String getInstallPath() { return installPath; } @@ -15,4 +17,12 @@ public String getInstallPath() { public void setInstallPath(String installPath) { this.installPath = installPath; } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/FlattenVolumeOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/FlattenVolumeOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..81f03fc227d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/FlattenVolumeOnPrimaryStorageMsg.java @@ -0,0 +1,22 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeInventory; + +public class FlattenVolumeOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private VolumeInventory volume; + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } + + public VolumeInventory getVolume() { + return volume; + } + + @Override + public String getPrimaryStorageUuid() { + return volume.getPrimaryStorageUuid(); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/FlattenVolumeOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/FlattenVolumeOnPrimaryStorageReply.java new file mode 100644 index 00000000000..fd2afbc16ef --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/FlattenVolumeOnPrimaryStorageReply.java @@ -0,0 +1,24 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class FlattenVolumeOnPrimaryStorageReply extends MessageReply { + private long size; + private long actualSize; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetInstallPathForDataVolumeDownloadMsg.java b/header/src/main/java/org/zstack/header/storage/primary/GetInstallPathForDataVolumeDownloadMsg.java index 3918e7d6090..9ead5a964b2 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/GetInstallPathForDataVolumeDownloadMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/GetInstallPathForDataVolumeDownloadMsg.java @@ -13,6 +13,15 @@ public class GetInstallPathForDataVolumeDownloadMsg extends NeedReplyMessage imp private ImageInventory image; private String volumeUuid; private String hostUuid; + private String allocatedInstallUrl; + + public String getAllocatedInstallUrl() { + return allocatedInstallUrl; + } + + public void setAllocatedInstallUrl(String allocatedInstallUrl) { + this.allocatedInstallUrl = allocatedInstallUrl; + } public void setPrimaryStorageUuid(String primaryStorageUuid) { this.primaryStorageUuid = primaryStorageUuid; diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetOwningVolumePathFromInternalSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/primary/GetOwningVolumePathFromInternalSnapshotMsg.java new file mode 100644 index 00000000000..8e82eafac9d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/GetOwningVolumePathFromInternalSnapshotMsg.java @@ -0,0 +1,27 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; + +public class GetOwningVolumePathFromInternalSnapshotMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private List snapshotPaths; + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public List getSnapshotPaths() { + return snapshotPaths; + } + + public void setSnapshotPaths(List snapshotPaths) { + this.snapshotPaths = snapshotPaths; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetOwningVolumePathFromInternalSnapshotReply.java b/header/src/main/java/org/zstack/header/storage/primary/GetOwningVolumePathFromInternalSnapshotReply.java new file mode 100644 index 00000000000..00836233185 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/GetOwningVolumePathFromInternalSnapshotReply.java @@ -0,0 +1,22 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +import java.util.HashMap; +import java.util.Map; + +public class GetOwningVolumePathFromInternalSnapshotReply extends MessageReply { + private Map owningVolumePaths = new HashMap<>(); + + public Map getOwningVolumePaths() { + return owningVolumePaths; + } + + public void setOwningVolumePaths(Map owningVolumePaths) { + this.owningVolumePaths = owningVolumePaths; + } + + public void putOwningVolumePath(String snapshotPath, String volumePath) { + this.owningVolumePaths.put(snapshotPath, volumePath); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetPrimaryStorageUsageReportMsg.java b/header/src/main/java/org/zstack/header/storage/primary/GetPrimaryStorageUsageReportMsg.java new file mode 100644 index 00000000000..35605e60520 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/GetPrimaryStorageUsageReportMsg.java @@ -0,0 +1,27 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; + +public class GetPrimaryStorageUsageReportMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private List uris; + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public List getUris() { + return uris; + } + + public void setUris(List uris) { + this.uris = uris; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetPrimaryStorageUsedPhysicalCapacityForecastReply.java b/header/src/main/java/org/zstack/header/storage/primary/GetPrimaryStorageUsedPhysicalCapacityForecastReply.java new file mode 100644 index 00000000000..6c38b5dbd5d --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/GetPrimaryStorageUsedPhysicalCapacityForecastReply.java @@ -0,0 +1,17 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +import java.util.Map; + +public class GetPrimaryStorageUsedPhysicalCapacityForecastReply extends MessageReply { + private Map usageReportMap; + + public Map getUsageReportMap() { + return usageReportMap; + } + + public void setUsageReportMap(Map usageReportMap) { + this.usageReportMap = usageReportMap; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetVolumeBackingChainFromPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/GetVolumeBackingChainFromPrimaryStorageMsg.java index b236d78c74a..d928fea28c7 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/GetVolumeBackingChainFromPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/GetVolumeBackingChainFromPrimaryStorageMsg.java @@ -12,6 +12,9 @@ public class GetVolumeBackingChainFromPrimaryStorageMsg extends NeedReplyMessage private String volumeUuid; private List rootInstallPaths = new ArrayList<>(); private String primaryStorageUuid; + // TODO remove it + private String hostUuid; + private String volumeFormat; public List getRootInstallPaths() { return rootInstallPaths; @@ -37,4 +40,20 @@ public String getVolumeUuid() { public void setVolumeUuid(String volumeUuid) { this.volumeUuid = volumeUuid; } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVolumeFormat() { + return volumeFormat; + } + + public void setVolumeFormat(String volumeFormat) { + this.volumeFormat = volumeFormat; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/GetVolumeRootImageUuidFromPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/GetVolumeRootImageUuidFromPrimaryStorageReply.java index e4ae3abbb4c..e84e4dd0c00 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/GetVolumeRootImageUuidFromPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/GetVolumeRootImageUuidFromPrimaryStorageReply.java @@ -2,12 +2,17 @@ import org.zstack.header.message.MessageReply; +import java.util.List; + /** * Created by xing5 on 2016/7/20. */ public class GetVolumeRootImageUuidFromPrimaryStorageReply extends MessageReply { private String imageUuid; + // maybe other snapshot tree based image uuids + private List otherImageUuids; + public String getImageUuid() { return imageUuid; } @@ -15,4 +20,12 @@ public String getImageUuid() { public void setImageUuid(String imageUuid) { this.imageUuid = imageUuid; } + + public List getOtherImageUuids() { + return otherImageUuids; + } + + public void setOtherImageUuids(List otherImageUuids) { + this.otherImageUuids = otherImageUuids; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/HistoricalUsageAO.java b/header/src/main/java/org/zstack/header/storage/primary/HistoricalUsageAO.java new file mode 100644 index 00000000000..2cca133d90f --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/HistoricalUsageAO.java @@ -0,0 +1,101 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.vo.Index; + +import javax.persistence.*; +import java.sql.Timestamp; + +@MappedSuperclass +public abstract class HistoricalUsageAO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + @Index + protected String resourceType; + + @Column + private long totalPhysicalCapacity; + + @Column + private long usedPhysicalCapacity; + + @Column + private Timestamp recordDate; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public HistoricalUsageAO() { + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public long getTotalPhysicalCapacity() { + return totalPhysicalCapacity; + } + + public void setTotalPhysicalCapacity(long totalPhysicalCapacity) { + this.totalPhysicalCapacity = totalPhysicalCapacity; + } + + public long getUsedPhysicalCapacity() { + return usedPhysicalCapacity; + } + + public void setUsedPhysicalCapacity(long usedPhysicalCapacity) { + this.usedPhysicalCapacity = usedPhysicalCapacity; + } + + public Timestamp getRecordDate() { + return recordDate; + } + + public void setRecordDate(Timestamp recordDate) { + this.recordDate = recordDate; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public abstract String getResourceUuid(); + + public abstract void setResourceUuid(String resourceUuid); +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/HistoricalUsageAO_.java b/header/src/main/java/org/zstack/header/storage/primary/HistoricalUsageAO_.java new file mode 100644 index 00000000000..9926390ceff --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/HistoricalUsageAO_.java @@ -0,0 +1,18 @@ +package org.zstack.header.storage.primary; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(HistoricalUsageAO.class) +public class HistoricalUsageAO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute resourceUuid; + public static volatile SingularAttribute resourceType; + public static volatile SingularAttribute totalPhysicalCapacity; + public static volatile SingularAttribute usedPhysicalCapacity; + public static volatile SingularAttribute historicalForecast; + public static volatile SingularAttribute recordDate; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/ImageCacheState.java b/header/src/main/java/org/zstack/header/storage/primary/ImageCacheState.java index a476889bb4b..6fba19571ab 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/ImageCacheState.java +++ b/header/src/main/java/org/zstack/header/storage/primary/ImageCacheState.java @@ -1,6 +1,7 @@ package org.zstack.header.storage.primary; public enum ImageCacheState { + creating, ready, deleting, } diff --git a/header/src/main/java/org/zstack/header/storage/primary/ImageCacheVolumeRefVO.java b/header/src/main/java/org/zstack/header/storage/primary/ImageCacheVolumeRefVO.java index bcf88fe73f9..5156afdaed2 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/ImageCacheVolumeRefVO.java +++ b/header/src/main/java/org/zstack/header/storage/primary/ImageCacheVolumeRefVO.java @@ -19,6 +19,7 @@ @SoftDeletionCascade(parent = PrimaryStorageVO.class, joinColumn = "primaryStorageUuid"), @SoftDeletionCascade(parent = VolumeVO.class, joinColumn = "volumeUuid") }) +@Deprecated public class ImageCacheVolumeRefVO { @Id @Column diff --git a/header/src/main/java/org/zstack/header/storage/primary/InstantiateBlockVolumeOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/InstantiateBlockVolumeOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..8b5a6d383dd --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/InstantiateBlockVolumeOnPrimaryStorageMsg.java @@ -0,0 +1,8 @@ +package org.zstack.header.storage.primary; + +/** + * @author shenjin + * @date 2023/6/15 11:32 + */ +public class InstantiateBlockVolumeOnPrimaryStorageMsg extends InstantiateVolumeOnPrimaryStorageMsg{ +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/InstantiateVolumeOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/InstantiateVolumeOnPrimaryStorageMsg.java index b96c9d93e7f..ee0d3ae796f 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/InstantiateVolumeOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/InstantiateVolumeOnPrimaryStorageMsg.java @@ -10,6 +10,15 @@ public class InstantiateVolumeOnPrimaryStorageMsg extends NeedReplyMessage imple private VolumeInventory volume; private String primaryStorageUuid; private boolean skipIfExisting; + private String allocatedInstallUrl; + + public String getAllocatedInstallUrl() { + return allocatedInstallUrl; + } + + public void setAllocatedInstallUrl(String allocatedInstallUrl) { + this.allocatedInstallUrl = allocatedInstallUrl; + } public void setPrimaryStorageUuid(String primaryStorageUuid) { this.primaryStorageUuid = primaryStorageUuid; diff --git a/header/src/main/java/org/zstack/header/storage/primary/MediatorDowloadParam.java b/header/src/main/java/org/zstack/header/storage/primary/MediatorDowloadParam.java deleted file mode 100644 index 1af37fd3e26..00000000000 --- a/header/src/main/java/org/zstack/header/storage/primary/MediatorDowloadParam.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.zstack.header.storage.primary; - -import org.zstack.header.vm.VmInstanceSpec; - -/** - * Created by mingjian.deng on 2017/11/24. - */ -public class MediatorDowloadParam implements MediatorParam{ - private VmInstanceSpec.ImageSpec image; - private String installPath; - private String primaryStorageUuid; - private boolean isShareable; - - public boolean isShareable() { - return isShareable; - } - - public void setShareable(boolean shareable) { - isShareable = shareable; - } - - public VmInstanceSpec.ImageSpec getImage() { - return image; - } - - public void setImage(VmInstanceSpec.ImageSpec image) { - this.image = image; - } - - public String getInstallPath() { - return installPath; - } - - public void setInstallPath(String installPath) { - this.installPath = installPath; - } - - public String getPrimaryStorageUuid() { - return primaryStorageUuid; - } - - public void setPrimaryStorageUuid(String primaryStorageUuid) { - this.primaryStorageUuid = primaryStorageUuid; - } -} diff --git a/header/src/main/java/org/zstack/header/storage/primary/MediatorDownloadParam.java b/header/src/main/java/org/zstack/header/storage/primary/MediatorDownloadParam.java new file mode 100644 index 00000000000..396448ba790 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/MediatorDownloadParam.java @@ -0,0 +1,45 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.vm.VmInstanceSpec; + +/** + * Created by mingjian.deng on 2017/11/24. + */ +public class MediatorDownloadParam implements MediatorParam { + private VmInstanceSpec.ImageSpec image; + private String installPath; + private String primaryStorageUuid; + private boolean isShareable; + + public boolean isShareable() { + return isShareable; + } + + public void setShareable(boolean shareable) { + isShareable = shareable; + } + + public VmInstanceSpec.ImageSpec getImage() { + return image; + } + + public void setImage(VmInstanceSpec.ImageSpec image) { + this.image = image; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/MediatorUploadParam.java b/header/src/main/java/org/zstack/header/storage/primary/MediatorUploadParam.java new file mode 100644 index 00000000000..e52473c6cae --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/MediatorUploadParam.java @@ -0,0 +1,11 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.image.ImageInventory; + +public class MediatorUploadParam implements MediatorParam { + public ImageInventory image; + public String primaryStorageUuid; + public String primaryStorageInstallPath; + public String backupStorageInstallPath; + public String backupStorageUuid; +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PackageInfo.java b/header/src/main/java/org/zstack/header/storage/primary/PackageInfo.java index 42c1d85a6b1..7f0c15770fa 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "主存储") +@PackageAPIInfo( + APICategoryName = "主存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocateConfigType.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocateConfigType.java index 009f1ce7b87..8bf50302729 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocateConfigType.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocateConfigType.java @@ -7,6 +7,7 @@ public enum PrimaryStorageAllocateConfigType { LOCAL(DefaultPrimaryStorageAllocateConfig.class, "LocalStorage"), NFS(DefaultPrimaryStorageAllocateConfig.class, "NFS"), SHBK(DefaultPrimaryStorageAllocateConfig.class, "SharedBlock"), + Block(DefaultPrimaryStorageAllocateConfig.class, "Block"), CEPH(CephPrimaryStorageAllocateConfig.class, "Ceph"); private Class type; diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationPurpose.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationPurpose.java index 37b74d48f83..4b18c85f38d 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationPurpose.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationPurpose.java @@ -5,7 +5,8 @@ */ public enum PrimaryStorageAllocationPurpose { CreateNewVm, // Be careful: purpose CreateNewVm has very special logic - CreateVolume, + CreateRootVolume, + CreateDataVolume, DownloadSnapshot, DownloadImage } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationSpec.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationSpec.java index b17e50c5381..13bc292157b 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationSpec.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocationSpec.java @@ -1,6 +1,8 @@ package org.zstack.header.storage.primary; +import java.util.Collections; import java.util.List; +import java.util.Set; /** */ @@ -10,7 +12,7 @@ public class PrimaryStorageAllocationSpec { private String requiredZoneUuid; private List requiredClusterUuids; private String requiredHostUuid; - private String requiredPrimaryStorageUuid; + private List candidatePrimaryStorageUuids; private List tags; private AllocatePrimaryStorageMsg allocationMessage; private String vmInstanceUuid; @@ -22,6 +24,23 @@ public class PrimaryStorageAllocationSpec { private List possiblePrimaryStorageTypes; private List excludePrimaryStorageTypes; private String backupStorageUuid; + private Set requiredFeatures; + + public Set getRequiredFeatures() { + return requiredFeatures; + } + + public void setRequiredFeatures(Set requiredFeatures) { + this.requiredFeatures = requiredFeatures; + } + + public List getCandidatePrimaryStorageUuids() { + return candidatePrimaryStorageUuids == null ? Collections.emptyList() : candidatePrimaryStorageUuids; + } + + public void setCandidatePrimaryStorageUuids(List candidatePrimaryStorageUuids) { + this.candidatePrimaryStorageUuids = candidatePrimaryStorageUuids; + } public List getExcludePrimaryStorageTypes() { return excludePrimaryStorageTypes; @@ -95,14 +114,6 @@ public void setDiskOfferingUuid(String diskOfferingUuid) { this.diskOfferingUuid = diskOfferingUuid; } - public String getRequiredPrimaryStorageUuid() { - return requiredPrimaryStorageUuid; - } - - public void setRequiredPrimaryStorageUuid(String requiredPrimaryStorageUuid) { - this.requiredPrimaryStorageUuid = requiredPrimaryStorageUuid; - } - public long getSize() { return size; } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocatorStrategy.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocatorStrategy.java index f6992f4d504..d799274d28e 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocatorStrategy.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageAllocatorStrategy.java @@ -5,5 +5,7 @@ public interface PrimaryStorageAllocatorStrategy { PrimaryStorageInventory allocate(PrimaryStorageAllocationSpec spec); + void sort(PrimaryStorageAllocationSpec spec, List candidates); + List allocateAllCandidates(PrimaryStorageAllocationSpec spec); } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO.java index 7d7400cbba4..113d07dd420 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO.java @@ -18,7 +18,7 @@ @EntityGraph.Neighbour(type = PrimaryStorageVO.class, myField = "uuid", targetField = "uuid") } ) -public class PrimaryStorageCapacityVO implements ShadowEntity { +public class PrimaryStorageCapacityVO extends StorageCapacityAO implements ShadowEntity { @Column @Id @ForeignKey(parentEntityClass = PrimaryStorageEO.class, onDeleteAction = ReferenceOption.CASCADE) @@ -32,14 +32,6 @@ public class PrimaryStorageCapacityVO implements ShadowEntity { @Index private long availableCapacity; - @Column - @Index - private long totalPhysicalCapacity; - - @Column - @Index - private long availablePhysicalCapacity; - @Column private Long systemUsedCapacity; @@ -69,22 +61,6 @@ public void setSystemUsedCapacity(Long systemUsedCapacity) { this.systemUsedCapacity = systemUsedCapacity; } - public long getTotalPhysicalCapacity() { - return totalPhysicalCapacity; - } - - public void setTotalPhysicalCapacity(long totalPhysicalCapacity) { - this.totalPhysicalCapacity = totalPhysicalCapacity; - } - - public long getAvailablePhysicalCapacity() { - return availablePhysicalCapacity; - } - - public void setAvailablePhysicalCapacity(long availablePhysicalCapacity) { - this.availablePhysicalCapacity = availablePhysicalCapacity; - } - public String getUuid() { return uuid; } @@ -129,4 +105,14 @@ public void setLastOpDate(Timestamp lastOpDate) { public void setShadow(Object o) { shadow = (PrimaryStorageCapacityVO) o; } + + @Override + public String getResourceUuid() { + return uuid; + } + + @Override + public String getPrimaryStorageUuid() { + return uuid; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO_.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO_.java index f8175f5f811..eed00a707a8 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO_.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCapacityVO_.java @@ -7,7 +7,7 @@ /** */ @StaticMetamodel(PrimaryStorageCapacityVO.class) -public class PrimaryStorageCapacityVO_ { +public class PrimaryStorageCapacityVO_ extends StorageCapacityAO_ { public static volatile SingularAttribute uuid; public static volatile SingularAttribute totalCapacity; public static volatile SingularAttribute availableCapacity; diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCommitExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCommitExtensionPoint.java deleted file mode 100644 index af7a403ccfc..00000000000 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageCommitExtensionPoint.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.zstack.header.storage.primary; - -/** - * Created by mingjian.deng on 2017/10/25. - */ -public interface PrimaryStorageCommitExtensionPoint { - String getCommitAgentPath(String psType); - String getHostName(String bsUuid); -} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageConstant.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageConstant.java index 2bd6df41194..33c9f2f55b5 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageConstant.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageConstant.java @@ -10,6 +10,9 @@ public interface PrimaryStorageConstant { String SERVICE_ID = "storage.primary"; @PythonClass String DEFAULT_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE = "DefaultPrimaryStorageAllocationStrategy"; + String LEAST_VOLUME_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE = "LeastVolumePrimaryStorageAllocationStrategy"; + String MAXIMUM_AVAILABLE_CAPACITY_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE = "MaximumAvailableCapacityAllocationStrategy"; + String CUSTOM_ORDER_PRIMARY_STORAGE_ALLOCATION_STRATEGY_TYPE = "CustomOrderPrimaryStorageAllocationStrategy"; String VM_FOLDER = "vm"; String PRIMARY_STORAGE_DETACH_CODE = "primaryStorage.detach"; @@ -23,6 +26,7 @@ public interface PrimaryStorageConstant { String MIGRATE_VOLUME_GET_MD5_STAGE = "0-10"; String MIGRATE_VOLUME_COPY_STAGE = "10-90"; String MIGRATE_VOLUME_CHECK_MD5_STAGE = "90-100"; + String EXTERNAL_PRIMARY_STORAGE_TYPE = "Addon"; enum AllocatorParams { SPEC, diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageExtensionFactory.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageExtensionFactory.java new file mode 100644 index 00000000000..29c1a69f11c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageExtensionFactory.java @@ -0,0 +1,11 @@ +package org.zstack.header.storage.primary; + +import java.util.List; + +public interface PrimaryStorageExtensionFactory { + String getPrimaryStorageType(); + + PrimaryStorage getPrimaryStorage(PrimaryStorageVO vo); + + List getMessageClasses(); +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFactory.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFactory.java index a95b832692e..a937de17830 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFactory.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFactory.java @@ -9,4 +9,6 @@ public interface PrimaryStorageFactory { PrimaryStorage getPrimaryStorage(PrimaryStorageVO vo); PrimaryStorageInventory getInventory(String uuid); + + void validateStorageProtocol(String protocol); } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFeature.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFeature.java new file mode 100644 index 00000000000..1dbee35303c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageFeature.java @@ -0,0 +1,9 @@ +package org.zstack.header.storage.primary; + +/** + * @ Author : yh.w + * @ Date : Created in 10:42 2025/7/15 + */ +public enum PrimaryStorageFeature { + SHARED_VOLUME, +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO.java new file mode 100644 index 00000000000..008740cf18c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO.java @@ -0,0 +1,45 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; +import javax.persistence.Table; + +@org.zstack.header.vo.EntityGraph( + parents = { + @EntityGraph.Neighbour(type = PrimaryStorageEO.class, myField = "primaryStorageUuid", targetField = "uuid") + } +) +@Table +@MappedSuperclass +public class PrimaryStorageHistoricalUsageBaseVO extends HistoricalUsageAO { + + public PrimaryStorageHistoricalUsageBaseVO() { + resourceType = PrimaryStorageHistoricalUsageBaseVO.class.getSimpleName(); + } + + @Column + @Index + @org.zstack.header.vo.ForeignKey(parentEntityClass = PrimaryStorageEO.class, parentKey = "uuid", onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + protected String primaryStorageUuid; + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + @Override + public String getResourceUuid() { + return primaryStorageUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.primaryStorageUuid = resourceUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO_.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO_.java new file mode 100644 index 00000000000..c0a2a7b1bff --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageBaseVO_.java @@ -0,0 +1,9 @@ +package org.zstack.header.storage.primary; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(PrimaryStorageHistoricalUsageBaseVO.class) +public class PrimaryStorageHistoricalUsageBaseVO_ extends HistoricalUsageAO_ { + public static volatile SingularAttribute primaryStorageUuid; +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageVO.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageVO.java new file mode 100644 index 00000000000..fdefe606b18 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageVO.java @@ -0,0 +1,18 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.BaseResource; + +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table +@BaseResource +@AutoDeleteTag +public class PrimaryStorageHistoricalUsageVO extends PrimaryStorageHistoricalUsageBaseVO { + + public PrimaryStorageHistoricalUsageVO() { + resourceType = PrimaryStorageVO.class.getSimpleName(); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageVO_.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageVO_.java new file mode 100644 index 00000000000..87444f76def --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageHistoricalUsageVO_.java @@ -0,0 +1,7 @@ +package org.zstack.header.storage.primary; + +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(PrimaryStorageHistoricalUsageVO.class) +public class PrimaryStorageHistoricalUsageVO_ extends PrimaryStorageHistoricalUsageBaseVO_ { +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageInventory.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageInventory.java index ed9b3a1ff7f..643c8709e68 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageInventory.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageInventory.java @@ -1,6 +1,7 @@ package org.zstack.header.storage.primary; import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.log.NoLogging; import org.zstack.header.query.*; import org.zstack.header.search.Inventory; import org.zstack.header.search.TypeField; @@ -73,6 +74,7 @@ public class PrimaryStorageInventory implements Serializable { * @desc depending on primary storage type, url may have various formats. For example, * nfs primary storage uses url as *server_ip:/share_path* */ + @NoLogging(type = NoLogging.Type.Uri) private String url; /** * @desc max length of 2048 characters diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageSortExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageSortExtensionPoint.java new file mode 100644 index 00000000000..3d0263b74f5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageSortExtensionPoint.java @@ -0,0 +1,9 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.vm.VmInstanceSpec; + +import java.util.List; + +public interface PrimaryStorageSortExtensionPoint { + void sort(List candidates, VmInstanceSpec.ImageSpec imageSpec, String allocateStrategy); +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageType.java b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageType.java index 4492c0b9e44..d1db5fcd67a 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageType.java +++ b/header/src/main/java/org/zstack/header/storage/primary/PrimaryStorageType.java @@ -4,6 +4,7 @@ import org.zstack.utils.function.Function; import java.util.*; +import java.util.function.Predicate; import java.util.stream.Collectors; @@ -19,10 +20,13 @@ public class PrimaryStorageType { private boolean supportConfigVolumeProvisionStrategy; private boolean supportSharedVolume; private boolean supportConfigVolumeProvisioningStrategy; + private boolean supportStorageTrash; private int order; private PrimaryStorageFindBackupStorage primaryStorageFindBackupStorage; private boolean supportCreateVolumeSnapshotCheckCapacity = true; + private boolean supportCheckHostStatus=false; + public boolean isSupportSharedVolume() { return supportSharedVolume; } @@ -40,6 +44,9 @@ public void setOrder(int order) { } public PrimaryStorageType(String typeName) { + if (types.containsKey(typeName)) { + throw new IllegalArgumentException(String.format("duplicate PrimaryStorageType for typeName[%s]", typeName)); + } this.typeName = typeName; types.put(typeName, this); } @@ -103,10 +110,10 @@ public int compare(PrimaryStorageType o1, PrimaryStorageType o2) { return exposedTypes; } - public static List getSupportSharedVolumePSTypeNames() { + public static List getSupportFeaturesTypes(Predicate predicate) { List exposedTypes = getExposedTypes(); return exposedTypes.stream() - .filter(PrimaryStorageType::isSupportSharedVolume) + .filter(predicate) .map(PrimaryStorageType::toString) .collect(Collectors.toList()); } @@ -193,4 +200,20 @@ public boolean isSupportCreateVolumeSnapshotCheckCapacity() { public void setSupportCreateVolumeSnapshotCheckCapacity(boolean supportCreateVolumeSnapshotCheckCapacity) { this.supportCreateVolumeSnapshotCheckCapacity = supportCreateVolumeSnapshotCheckCapacity; } + + public boolean isSupportStorageTrash() { + return supportStorageTrash; + } + + public void setSupportStorageTrash(boolean supportStorageTrash) { + this.supportStorageTrash = supportStorageTrash; + } + + public boolean isSupportCheckHostStatus(){ + return supportCheckHostStatus; + } + + public void setSupportCheckHostStatus(boolean supportCheckHostStatus) { + this.supportCheckHostStatus = supportCheckHostStatus; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/PullVolumeSnapshotOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/PullVolumeSnapshotOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..2c06c26286e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PullVolumeSnapshotOnPrimaryStorageMsg.java @@ -0,0 +1,52 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeInventory; + +public class PullVolumeSnapshotOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private VolumeInventory volume; + private String srcSnapshotParentPath; + private VolumeSnapshotInventory srcSnapshot; + private VolumeSnapshotInventory dstSnapshot; + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } + + public String getSrcSnapshotParentPath() { + return srcSnapshotParentPath; + } + + public void setSrcSnapshotParentPath(String srcSnapshotParentPath) { + this.srcSnapshotParentPath = srcSnapshotParentPath; + } + + public VolumeSnapshotInventory getSrcSnapshot() { + return srcSnapshot; + } + + public void setSrcSnapshot(VolumeSnapshotInventory srcSnapshot) { + this.srcSnapshot = srcSnapshot; + } + + public VolumeSnapshotInventory getDstSnapshot() { + return dstSnapshot; + } + + public void setDstSnapshot(VolumeSnapshotInventory dstSnapshot) { + this.dstSnapshot = dstSnapshot; + } + + @Override + public String getPrimaryStorageUuid() { + if (volume == null) { + throw new IllegalArgumentException("volume cannot be null"); + } + return volume.getPrimaryStorageUuid(); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/PullVolumeSnapshotOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/PullVolumeSnapshotOnPrimaryStorageReply.java new file mode 100644 index 00000000000..0cae40ce2e4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/PullVolumeSnapshotOnPrimaryStorageReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class PullVolumeSnapshotOnPrimaryStorageReply extends MessageReply { + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/ReInitRootVolumeFromTemplateOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/ReInitRootVolumeFromTemplateOnPrimaryStorageMsg.java index 0a884a11a06..ba07327a0e8 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/ReInitRootVolumeFromTemplateOnPrimaryStorageMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/ReInitRootVolumeFromTemplateOnPrimaryStorageMsg.java @@ -7,6 +7,15 @@ public class ReInitRootVolumeFromTemplateOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { private VolumeInventory volume; private long originSize; + private String allocatedInstallUrl; + + public String getAllocatedInstallUrl() { + return allocatedInstallUrl; + } + + public void setAllocatedInstallUrl(String allocatedInstallUrl) { + this.allocatedInstallUrl = allocatedInstallUrl; + } @Override public String getPrimaryStorageUuid() { diff --git a/header/src/main/java/org/zstack/header/storage/primary/ResizeVolumeOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/ResizeVolumeOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..d8d2e91c650 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/ResizeVolumeOnPrimaryStorageMsg.java @@ -0,0 +1,47 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.volume.VolumeInventory; + +/** + * Created by kayo on 2017/9/12. + */ +public class ResizeVolumeOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private long size; + private boolean force; + private VolumeInventory volume; + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/ResizeVolumeOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/ResizeVolumeOnPrimaryStorageReply.java new file mode 100644 index 00000000000..7e4e6dc4583 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/ResizeVolumeOnPrimaryStorageReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; +import org.zstack.header.volume.VolumeInventory; + +/** + * Created by kayo on 2017/9/12. + */ +public class ResizeVolumeOnPrimaryStorageReply extends MessageReply { + private VolumeInventory volume; + + public VolumeInventory getVolume() { + return volume; + } + + public void setVolume(VolumeInventory volume) { + this.volume = volume; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/SetTrashExpirationTimeMsg.java b/header/src/main/java/org/zstack/header/storage/primary/SetTrashExpirationTimeMsg.java new file mode 100644 index 00000000000..c12187354de --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/SetTrashExpirationTimeMsg.java @@ -0,0 +1,29 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; + +public class SetTrashExpirationTimeMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String uuid; + private int expirationTime; + + @Override + public String getPrimaryStorageUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setExpirationTime(int expirationTime) { + this.expirationTime = expirationTime; + } + + public int getExpirationTime() { + return expirationTime; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/SetTrashExpirationTimeReply.java b/header/src/main/java/org/zstack/header/storage/primary/SetTrashExpirationTimeReply.java new file mode 100644 index 00000000000..3899d43f58b --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/SetTrashExpirationTimeReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class SetTrashExpirationTimeReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/SetVolumeQosOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/SetVolumeQosOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..d091fc88515 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/SetVolumeQosOnPrimaryStorageMsg.java @@ -0,0 +1,90 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; + +public class SetVolumeQosOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private String volumeUuid; + private Long totalBandWidth; + private Long readBandwidth; + private Long writeBandwidth; + private Long readIOPS; + private Long writeIOPS; + private Long totalIOPS; + + // total, read, write, all, overwrite + private String mode; + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getVolumeUuid() { + return volumeUuid; + } + + public Long getTotalBandWidth() { + return totalBandWidth; + } + + public void setTotalBandWidth(Long totalBandWidth) { + this.totalBandWidth = totalBandWidth; + } + + public Long getReadBandwidth() { + return readBandwidth; + } + + public void setReadBandwidth(Long readBandwidth) { + this.readBandwidth = readBandwidth; + } + + public Long getWriteBandwidth() { + return writeBandwidth; + } + + public void setWriteBandwidth(Long writeBandwidth) { + this.writeBandwidth = writeBandwidth; + } + + public Long getReadIOPS() { + return readIOPS; + } + + public void setReadIOPS(Long readIOPS) { + this.readIOPS = readIOPS; + } + + public Long getWriteIOPS() { + return writeIOPS; + } + + public void setWriteIOPS(Long writeIOPS) { + this.writeIOPS = writeIOPS; + } + + public Long getTotalIOPS() { + return totalIOPS; + } + + public void setTotalIOPS(Long totalIOPS) { + this.totalIOPS = totalIOPS; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/SetVolumeQosOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/SetVolumeQosOnPrimaryStorageReply.java new file mode 100644 index 00000000000..5155d8c951b --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/SetVolumeQosOnPrimaryStorageReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class SetVolumeQosOnPrimaryStorageReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/StorageCapacityAO.java b/header/src/main/java/org/zstack/header/storage/primary/StorageCapacityAO.java new file mode 100644 index 00000000000..990eb6af028 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/StorageCapacityAO.java @@ -0,0 +1,35 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.vo.Index; + +import javax.persistence.*; + +@MappedSuperclass +public abstract class StorageCapacityAO { + @Column + @Index + protected long totalPhysicalCapacity; + + @Column + @Index + protected long availablePhysicalCapacity; + + public long getTotalPhysicalCapacity() { + return totalPhysicalCapacity; + } + + public void setTotalPhysicalCapacity(long totalPhysicalCapacity) { + this.totalPhysicalCapacity = totalPhysicalCapacity; + } + + public long getAvailablePhysicalCapacity() { + return availablePhysicalCapacity; + } + + public void setAvailablePhysicalCapacity(long availablePhysicalCapacity) { + this.availablePhysicalCapacity = availablePhysicalCapacity; + } + + public abstract String getResourceUuid(); + public abstract String getPrimaryStorageUuid(); +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/StorageCapacityAO_.java b/header/src/main/java/org/zstack/header/storage/primary/StorageCapacityAO_.java new file mode 100644 index 00000000000..c44b2d15763 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/StorageCapacityAO_.java @@ -0,0 +1,13 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.storage.snapshot.VolumeSnapshotTreeAO_; +import org.zstack.header.storage.snapshot.VolumeSnapshotTreeEO; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(StorageCapacityAO.class) +public class StorageCapacityAO_ { + public static volatile SingularAttribute totalPhysicalCapacity; + public static volatile SingularAttribute availablePhysicalCapacity; +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/SyncVolumeSizeOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/SyncVolumeSizeOnPrimaryStorageReply.java index f3b7b029c4b..cabc95120a2 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/SyncVolumeSizeOnPrimaryStorageReply.java +++ b/header/src/main/java/org/zstack/header/storage/primary/SyncVolumeSizeOnPrimaryStorageReply.java @@ -8,6 +8,7 @@ public class SyncVolumeSizeOnPrimaryStorageReply extends MessageReply { private long actualSize; private long size; + private boolean withInternalSnapshot; public long getSize() { return size; @@ -24,4 +25,12 @@ public long getActualSize() { public void setActualSize(long actualSize) { this.actualSize = actualSize; } + + public void setWithInternalSnapshot(boolean withInternalSnapshot) { + this.withInternalSnapshot = withInternalSnapshot; + } + + public boolean isWithInternalSnapshot() { + return withInternalSnapshot; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/TakeSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/primary/TakeSnapshotMsg.java index 6aa11aea603..7052a411f9b 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/TakeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/TakeSnapshotMsg.java @@ -8,6 +8,8 @@ public class TakeSnapshotMsg extends NeedReplyMessage implements PrimaryStorageMessage { private String primaryStorageUuid; private VolumeSnapshotStruct struct; + private String name; + private String description; @Override public String getPrimaryStorageUuid() { @@ -25,4 +27,20 @@ public VolumeSnapshotStruct getStruct() { public void setStruct(VolumeSnapshotStruct struct) { this.struct = struct; } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } } diff --git a/header/src/main/java/org/zstack/header/storage/primary/UnlinkBitsOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/storage/primary/UnlinkBitsOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..14725003ab2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/UnlinkBitsOnPrimaryStorageMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.NeedReplyMessage; + +public class UnlinkBitsOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String primaryStorageUuid; + private String resourceUuid; + private String resourceType; + private String installPath; + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public String getInstallPath() { + return installPath; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/UnlinkBitsOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/storage/primary/UnlinkBitsOnPrimaryStorageReply.java new file mode 100644 index 00000000000..35519262392 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/UnlinkBitsOnPrimaryStorageReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class UnlinkBitsOnPrimaryStorageReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusMsg.java b/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusMsg.java index c64472ed011..d7a2e8720d0 100644 --- a/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusMsg.java +++ b/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusMsg.java @@ -3,12 +3,10 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.message.NeedReplyMessage; -import java.util.List; - /** * Created by Administrator on 2017-05-12. */ -public class UpdatePrimaryStorageHostStatusMsg extends NeedReplyMessage implements PrimaryStorageMessage{ +public class UpdatePrimaryStorageHostStatusMsg extends NeedReplyMessage implements PrimaryStorageMessage { private String primaryStorageUuid; private String hostUuid; private PrimaryStorageHostStatus status; diff --git a/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusReply.java b/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusReply.java new file mode 100644 index 00000000000..01846273dcb --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/UpdatePrimaryStorageHostStatusReply.java @@ -0,0 +1,7 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.message.MessageReply; + +public class UpdatePrimaryStorageHostStatusReply extends MessageReply { + +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/UsageReport.java b/header/src/main/java/org/zstack/header/storage/primary/UsageReport.java new file mode 100644 index 00000000000..5f462ff968f --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/UsageReport.java @@ -0,0 +1,57 @@ +package org.zstack.header.storage.primary; + +import org.zstack.header.rest.SDK; + +import java.util.List; + +@SDK +public class UsageReport { + List usedPhysicalCapacitiesForecast; + List usedPhysicalCapacitiesHistory; + List totalPhysicalCapacitiesHistory; + Long startTime; + Long interval; + + public UsageReport() { + } + + public List getUsedPhysicalCapacitiesForecast() { + return usedPhysicalCapacitiesForecast; + } + + public void setUsedPhysicalCapacitiesForecast(List usedPhysicalCapacitiesForecast) { + this.usedPhysicalCapacitiesForecast = usedPhysicalCapacitiesForecast; + } + + public List getUsedPhysicalCapacitiesHistory() { + return usedPhysicalCapacitiesHistory; + } + + public void setUsedPhysicalCapacitiesHistory(List usedPhysicalCapacitiesHistory) { + this.usedPhysicalCapacitiesHistory = usedPhysicalCapacitiesHistory; + } + + public List getTotalPhysicalCapacitiesHistory() { + return totalPhysicalCapacitiesHistory; + } + + public void setTotalPhysicalCapacitiesHistory(List totalPhysicalCapacitiesHistory) { + this.totalPhysicalCapacitiesHistory = totalPhysicalCapacitiesHistory; + } + + public Long getStartTime() { + return startTime; + } + + public void setStartTime(Long startTime) { + this.startTime = startTime; + } + + public Long getInterval() { + return interval; + } + + public void setInterval(Long interval) { + this.interval = interval; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/UsageReportDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/primary/UsageReportDoc_zh_cn.groovy new file mode 100644 index 00000000000..9a744484758 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/UsageReportDoc_zh_cn.groovy @@ -0,0 +1,39 @@ +package org.zstack.header.storage.primary + +import java.lang.Long + +doc { + + title "存储预测容量报告" + + field { + name "usedPhysicalCapacitiesForecast" + desc "" + type "List" + since "4.7.21" + } + field { + name "UsedPhysicalCapacitiesHistory" + desc "" + type "List" + since "4.7.21" + } + field { + name "TotalPhysicalCapacitiesHistory" + desc "" + type "List" + since "4.7.21" + } + field { + name "startTime" + desc "" + type "Long" + since "4.7.21" + } + field { + name "interval" + desc "" + type "Long" + since "4.7.21" + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/UsedPhysicalCapacityForecastsWithDates.java b/header/src/main/java/org/zstack/header/storage/primary/UsedPhysicalCapacityForecastsWithDates.java new file mode 100644 index 00000000000..116913ab379 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/primary/UsedPhysicalCapacityForecastsWithDates.java @@ -0,0 +1,30 @@ +package org.zstack.header.storage.primary; + +import java.util.Date; +import java.util.List; + +public class UsedPhysicalCapacityForecastsWithDates { + List forecastList; + List forecastFutureDateList; + + public UsedPhysicalCapacityForecastsWithDates(List forecastList, List forecastFutureDateList) { + this.forecastList = forecastList; + this.forecastFutureDateList = forecastFutureDateList; + } + + public List getForecastList() { + return forecastList; + } + + public void setForecastList(List forecastList) { + this.forecastList = forecastList; + } + + public List getForecastFutureDateList() { + return forecastFutureDateList; + } + + public void setForecastFutureDateList(List forecastFutureDateList) { + this.forecastFutureDateList = forecastFutureDateList; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/primary/VolumeSnapshotCapability.java b/header/src/main/java/org/zstack/header/storage/primary/VolumeSnapshotCapability.java index 8d150e47b80..79050146db5 100755 --- a/header/src/main/java/org/zstack/header/storage/primary/VolumeSnapshotCapability.java +++ b/header/src/main/java/org/zstack/header/storage/primary/VolumeSnapshotCapability.java @@ -1,5 +1,7 @@ package org.zstack.header.storage.primary; +import java.util.function.Function; + /** * Created by frank on 6/9/2015. */ @@ -8,10 +10,38 @@ public static enum VolumeSnapshotArrangementType { CHAIN, INDIVIDUAL } + + public static enum VolumeSnapshotPlacementType { + INTERNAL, + EXTERNAL, + } private boolean support; + + /*** + * Whether the primary storage supports creating volume snapshots by hypervisor. + */ + private boolean supportCreateOnHypervisor; + + + /*** + * Whether the primary storage supports lazy delete for volume snapshots. + * even if snapshot is not ready for delete, it can be auto-deleted in storage backend. + * so client can delete snapshot immediately without waiting for reference cleaned. + */ + private boolean supportLazyDelete; + private VolumeSnapshotArrangementType arrangementType; + private VolumeSnapshotPlacementType placementType; + + /*** + * If volume snapshot is inner snapshot on volume, it must be set. + * A regex match volume install path from inner volume snapshot install path. + * such as pool/vol from pool/vol@snapshot can be extracted by regex ^[^@]+ + */ + private String volumePathFromInternalSnapshotRegex; + public boolean isSupport() { return support; } @@ -27,4 +57,38 @@ public VolumeSnapshotArrangementType getArrangementType() { public void setArrangementType(VolumeSnapshotArrangementType arrangementType) { this.arrangementType = arrangementType; } + + public VolumeSnapshotPlacementType getPlacementType() { + return placementType; + } + + public void setPlacementType(VolumeSnapshotPlacementType placementType) { + this.placementType = placementType; + } + + public boolean isSupportCreateOnHypervisor() { + return supportCreateOnHypervisor; + } + + public void setSupportCreateOnHypervisor(boolean supportCreateOnHypervisor) { + this.supportCreateOnHypervisor = supportCreateOnHypervisor; + } + + public boolean isSupportLazyDelete() { + return supportLazyDelete; + } + + public void setSupportLazyDelete(boolean supportLazyDelete) { + this.supportLazyDelete = supportLazyDelete; + } + + @Deprecated + public String getVolumePathFromInternalSnapshotRegex() { + return volumePathFromInternalSnapshotRegex; + } + + @Deprecated + public void setVolumePathFromInternalSnapshotRegex(String volumePathFromInternalSnapshotRegex) { + this.volumePathFromInternalSnapshotRegex = volumePathFromInternalSnapshotRegex; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotEvent.java b/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotEvent.java index 721d623e165..c08758276fe 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotEvent.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotEvent.java @@ -35,5 +35,4 @@ public static APIBatchDeleteVolumeSnapshotEvent __example__() { event.setResults(Arrays.asList(r1)); return event; } - } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsg.java index f692773d6f5..91215620c4c 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsg.java @@ -2,7 +2,12 @@ import org.springframework.http.HttpMethod; import org.zstack.header.identity.Action; -import org.zstack.header.message.*; +import org.zstack.header.message.APIBatchRequest; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.DefaultTimeout; import org.zstack.header.other.APIAuditor; import org.zstack.header.other.APIMultiAuditor; import org.zstack.header.rest.APINoSee; @@ -22,7 +27,7 @@ responseClass = APIBatchDeleteVolumeSnapshotEvent.class ) @DefaultTimeout(timeunit = TimeUnit.HOURS, value = 6) -public class APIBatchDeleteVolumeSnapshotMsg extends APIDeleteMessage implements APIMultiAuditor { +public class APIBatchDeleteVolumeSnapshotMsg extends APIDeleteMessage implements APIMultiAuditor, APIBatchRequest { /** * @desc volume snapshot uuid */ @@ -70,4 +75,14 @@ public List multiAudit(APIMessage msg, APIEvent rsp) { return res; } + + @Override + public Result collectResult(APIMessage message, APIEvent rsp) { + APIBatchDeleteVolumeSnapshotEvent evt = (APIBatchDeleteVolumeSnapshotEvent) rsp; + return new Result(evt.getResults().size(), + evt.getResults().stream() + .filter(BatchDeleteVolumeSnapshotStruct::isSuccess) + .toArray().length + ); + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsgDoc_zh_cn.groovy index 4ad63e94450..2ab96c3d60f 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIBatchDeleteVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "3.3" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.3" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsg.java index f9ed4e674fa..93003c6211c 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsg.java @@ -61,6 +61,12 @@ public class APIDeleteVolumeSnapshotMsg extends APIDeleteMessage implements Dele @APINoSee private String treeUuid; + @APIParam(required = false, validValues = {"pull", "commit", "auto"}) + private String direction = "auto"; + + @APIParam(required = false, validValues = {"single", "chain", "auto"}) + private String scope = "chain"; + @Override public String getTreeUuid() { return treeUuid; @@ -84,6 +90,22 @@ public String getSnapshotUuid() { return uuid; } + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + @Override public String getVolumeUuid() { return volumeUuid; diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsgDoc_zh_cn.groovy index 8dd6a191b4f..36b1322fc02 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIDeleteVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,24 @@ doc { type "String" optional true since "0.6" - + } + column { + name "direction" + enclosedIn "" + desc "数据合并方向。pull:向前合并;commit:向后合并;auto:自动选择最优合并方向" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "scope" + enclosedIn "" + desc "数据合并方式。single:仅合并单个快照;chain:合并整个快照链;auto:自动判断最佳合并范围" + location "body" + type "String" + optional true + since "5.4.0" } column { name "systemTags" @@ -49,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIGetVolumeSnapshotSizeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIGetVolumeSnapshotSizeMsgDoc_zh_cn.groovy index 30d356719f0..7f10a2be913 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIGetVolumeSnapshotSizeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIGetVolumeSnapshotSizeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.5" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.5" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.5" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotMsgDoc_zh_cn.groovy index b7301e17446..e65088726aa 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.storage.snapshot import org.zstack.header.storage.snapshot.APIQueryVolumeSnapshotReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询云盘快照(QueryVolumeSnapshot)" diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotTreeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotTreeMsgDoc_zh_cn.groovy index 15ad41426cc..3bfa4d9806d 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotTreeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIQueryVolumeSnapshotTreeMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.storage.snapshot import org.zstack.header.storage.snapshot.APIQueryVolumeSnapshotTreeReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询快照树(QueryVolumeSnapshotTree)" diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIRevertVolumeFromSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIRevertVolumeFromSnapshotMsgDoc_zh_cn.groovy index 1c958feca52..debdc040bb9 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIRevertVolumeFromSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIRevertVolumeFromSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIShrinkVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIShrinkVolumeSnapshotMsgDoc_zh_cn.groovy index ef8f5164a42..b093ab658e6 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIShrinkVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIShrinkVolumeSnapshotMsgDoc_zh_cn.groovy @@ -23,13 +23,12 @@ doc { column { name "uuid" - enclosedIn "" + enclosedIn "shrinkVolumeSnapshot" desc "资源的UUID,唯一标示该资源" location "url" type "String" optional false since "3.10" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.10" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.10" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/APIUpdateVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/APIUpdateVolumeSnapshotMsgDoc_zh_cn.groovy index 1b86679945b..6b404846391 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/APIUpdateVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/APIUpdateVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/AfterTakeLiveSnapshotsOnVolumes.java b/header/src/main/java/org/zstack/header/storage/snapshot/AfterTakeLiveSnapshotsOnVolumes.java deleted file mode 100644 index 388fca7d425..00000000000 --- a/header/src/main/java/org/zstack/header/storage/snapshot/AfterTakeLiveSnapshotsOnVolumes.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.zstack.header.storage.snapshot; - -import org.zstack.header.core.Completion; - -/** - * Create by weiwang at 2018/6/14 - */ -public interface AfterTakeLiveSnapshotsOnVolumes { - void afterTakeLiveSnapshotsOnVolumes(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply, Completion completion); -} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/AfterTakeLiveSnapshotsOnVolumesFailed.java b/header/src/main/java/org/zstack/header/storage/snapshot/AfterTakeLiveSnapshotsOnVolumesFailed.java deleted file mode 100644 index 1290d8dbf16..00000000000 --- a/header/src/main/java/org/zstack/header/storage/snapshot/AfterTakeLiveSnapshotsOnVolumesFailed.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.zstack.header.storage.snapshot; - -import org.zstack.header.core.Completion; - -/** - * Create by weiwang at 2018/6/14 - */ -public interface AfterTakeLiveSnapshotsOnVolumesFailed { - void afterTakeLiveSnapshotsOnVolumesFailed(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply); -} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/AfterUpdateVolumeSnapshotExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/snapshot/AfterUpdateVolumeSnapshotExtensionPoint.java new file mode 100644 index 00000000000..ff251f5a771 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/AfterUpdateVolumeSnapshotExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.header.storage.snapshot; + +import org.zstack.header.core.Completion; + +public interface AfterUpdateVolumeSnapshotExtensionPoint { + void afterUpdateVolumeSnapshot(VolumeSnapshotVO vo, APIUpdateVolumeSnapshotMsg msg, Completion completion); +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotMsg.java deleted file mode 100644 index ee2880a3a87..00000000000 --- a/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotMsg.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.zstack.header.storage.snapshot; - -import org.zstack.header.message.NeedReplyMessage; - -import java.util.List; - -/** - * Create by weiwang at 2018-12-21 - */ -public class BatchDeleteVolumeSnapshotMsg extends NeedReplyMessage { - private List uuids; - - private String volumeUuid; - - public List getUuids() { - return uuids; - } - - public void setUuids(List uuids) { - this.uuids = uuids; - } - - public String getVolumeUuid() { - return volumeUuid; - } - - public void setVolumeUuid(String volumeUuid) { - this.volumeUuid = volumeUuid; - } -} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotReply.java b/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotReply.java deleted file mode 100644 index 7e041f01a45..00000000000 --- a/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotReply.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.zstack.header.storage.snapshot; - -import org.zstack.header.message.MessageReply; - -import java.util.List; - -/** - * Create by weiwang at 2018-12-21 - */ -public class BatchDeleteVolumeSnapshotReply extends MessageReply { - private List results; - - public List getResults() { - return results; - } - - public void setResults(List results) { - this.results = results; - } -} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotStruct.java b/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotStruct.java index 53e2afea4b5..c2a3579b454 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotStruct.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/BatchDeleteVolumeSnapshotStruct.java @@ -7,7 +7,7 @@ */ public class BatchDeleteVolumeSnapshotStruct { private String snapshotUuid; - private boolean success; + private boolean success = true; private ErrorCode error; public String getSnapshotUuid() { @@ -31,6 +31,7 @@ public ErrorCode getError() { } public void setError(ErrorCode error) { + this.success = false; this.error = error; } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/CreateImageCacheFromVolumeSnapshotReply.java b/header/src/main/java/org/zstack/header/storage/snapshot/CreateImageCacheFromVolumeSnapshotReply.java index e3cab027d10..6b05c0cbadf 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/CreateImageCacheFromVolumeSnapshotReply.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/CreateImageCacheFromVolumeSnapshotReply.java @@ -8,6 +8,7 @@ public class CreateImageCacheFromVolumeSnapshotReply extends MessageReply { private long actualSize; private String locationHostUuid; + private String imageUrl; public long getActualSize() { return actualSize; @@ -24,4 +25,12 @@ public String getLocationHostUuid() { public void setLocationHostUuid(String locationHostUuid) { this.locationHostUuid = locationHostUuid; } + + public String getImageUrl() { + return imageUrl; + } + + public void setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/CreateVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/CreateVolumeSnapshotMsg.java index 441741f656a..46cc937aee8 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/CreateVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/CreateVolumeSnapshotMsg.java @@ -9,6 +9,15 @@ public class CreateVolumeSnapshotMsg extends NeedReplyMessage implements NeedQuo private String volumeUuid; private String name; private String description; + private SnapshotMode requiredSnapshotMode = SnapshotMode.AUTO; + + public SnapshotMode getRequiredSnapshotMode() { + return requiredSnapshotMode; + } + + public void setRequiredSnapshotMode(SnapshotMode requiredSnapshotMode) { + this.requiredSnapshotMode = requiredSnapshotMode; + } public String getAccountUuid() { return accountUuid; diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotDirection.java b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotDirection.java new file mode 100644 index 00000000000..09fa7efe320 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotDirection.java @@ -0,0 +1,30 @@ +package org.zstack.header.storage.snapshot; + +public enum DeleteVolumeSnapshotDirection { + Pull("pull"), + Commit("commit"), + Auto("auto"); + + private final String direction; + + DeleteVolumeSnapshotDirection(String direction) { + this.direction = direction; + } + + @Override + public String toString() { + return direction; + } + + public static DeleteVolumeSnapshotDirection fromString(String value) { + if (value == null || value.trim().isEmpty()) { + throw new IllegalArgumentException(String.format("direction must be one of [pull, commit, auto], but value is %s", value)); + } + for (DeleteVolumeSnapshotDirection direction : DeleteVolumeSnapshotDirection.values()) { + if (direction.direction.equalsIgnoreCase(value)) { + return direction; + } + } + throw new IllegalArgumentException("Invalid direction: " + value); + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMessage.java b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMessage.java index 78fe7375d56..b6efff2c386 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMessage.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMessage.java @@ -7,4 +7,8 @@ */ public interface DeleteVolumeSnapshotMessage extends VolumeSnapshotMessage { DeletionMode getDeletionMode(); + + String getDirection(); + + String getScope(); } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMsg.java index 3bb86662266..78af874890e 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotMsg.java @@ -1,6 +1,7 @@ package org.zstack.header.storage.snapshot; import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIParam; import org.zstack.header.message.NeedReplyMessage; /** @@ -11,6 +12,8 @@ public class DeleteVolumeSnapshotMsg extends NeedReplyMessage implements DeleteV private String volumeUuid; private String treeUuid; private String deletionMode; + private String direction; + private String scope; public void setSnapshotUuid(String snapshotUuid) { this.snapshotUuid = snapshotUuid; @@ -49,4 +52,22 @@ public void setTreeUuid(String treeUuid) { public String getTreeUuid() { return treeUuid; } + + @Override + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + @Override + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotScope.java b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotScope.java new file mode 100644 index 00000000000..1cf6b15dcf4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/DeleteVolumeSnapshotScope.java @@ -0,0 +1,18 @@ +package org.zstack.header.storage.snapshot; + +public enum DeleteVolumeSnapshotScope { + Single("single"), + Chain("chain"), + Auto("auto"); + + private final String scope; + + DeleteVolumeSnapshotScope(String scope) { + this.scope = scope; + } + + @Override + public String toString() { + return scope; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/PackageInfo.java b/header/src/main/java/org/zstack/header/storage/snapshot/PackageInfo.java index 45125870f33..b3fea57ae71 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "磁盘快照") +@PackageAPIInfo( + APICategoryName = "磁盘快照", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/SnapshotMode.java b/header/src/main/java/org/zstack/header/storage/snapshot/SnapshotMode.java new file mode 100644 index 00000000000..3555fe62afe --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/SnapshotMode.java @@ -0,0 +1,23 @@ +package org.zstack.header.storage.snapshot; + +import java.util.function.Supplier; + +/** + * @ Author : yh.w + * @ Date : Created in 16:05 2023/8/21 + */ +public enum SnapshotMode { + FULL, + INCREMENTAL, + AUTO; + + public static boolean isFullSnapShot(SnapshotMode mode, Supplier supplier) { + if (mode == FULL) { + return true; + } else if (mode == INCREMENTAL) { + return false; + } else { + return supplier.get(); + } + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotAfterDeleteExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotAfterDeleteExtensionPoint.java index 0c1a57c2d5b..da1592442ad 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotAfterDeleteExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotAfterDeleteExtensionPoint.java @@ -1,11 +1,14 @@ package org.zstack.header.storage.snapshot; import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; + +import java.util.List; /** * Created by xing5 on 2016/5/3. */ public interface VolumeSnapshotAfterDeleteExtensionPoint { - void volumeSnapshotAfterDeleteExtensionPoint(VolumeSnapshotInventory snapshot, Completion completion); - void volumeSnapshotAfterFailedDeleteExtensionPoint(VolumeSnapshotInventory snapshot); + void volumeSnapshotAfterDeleteExtensionPoint(VolumeSnapshotInventory snapshot, NoErrorCompletion completion); + void volumeSnapshotAfterCleanUpExtensionPoint(String volumeUuid, List snapshots); } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java index c4bece2fd09..8f784a72051 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotConstant.java @@ -11,6 +11,7 @@ public interface VolumeSnapshotConstant { VolumeSnapshotType STORAGE_SNAPSHOT_TYPE = new VolumeSnapshotType("Storage"); String SNAPSHOT_MESSAGE_ROUTED = "SNAPSHOT_MESSAGE_ROUTED"; + String SNAPSHOT_UUID = "SNAPSHOT_UUID"; String VOLUME_SNAPSHOT_STRUCT = "VolumeSnapshotStruct"; String NEED_TAKE_SNAPSHOTS_ON_HYPERVISOR = "needTakeSnapshotOnHypervisor"; diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotCreationExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotCreationExtensionPoint.java new file mode 100644 index 00000000000..1aab7cb44ab --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotCreationExtensionPoint.java @@ -0,0 +1,22 @@ +package org.zstack.header.storage.snapshot; + +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupInventory; +import org.zstack.header.volume.CreateVolumeSnapshotGroupMessage; + +import java.util.List; + +public interface VolumeSnapshotCreationExtensionPoint { + void afterVolumeLiveSnapshotGroupCreatedOnBackend(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply, Completion completion); + + void afterVolumeLiveSnapshotGroupCreationFailsOnBackend(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply); + + void afterVolumeSnapshotGroupCreated(VolumeSnapshotGroupInventory snapshotGroup, ConsistentType consistentType, Completion completion); + + void afterVolumeSnapshotCreated(VolumeSnapshotInventory snapshot, Completion completion); + + default List beforeCreateVolumeSnapshotFlow(CreateVolumeSnapshotGroupMessage msg) { + return null; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionMsg.java index 07099be40ca..7c1cf7f6244 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionMsg.java @@ -9,6 +9,8 @@ public class VolumeSnapshotDeletionMsg extends DeletionMessage implements Volume private String volumeUuid; private boolean volumeDeletion; private boolean dbOnly; + private String direction; + private String scope; /** * @ignore */ @@ -57,4 +59,20 @@ public boolean isDbOnly() { public void setDbOnly(boolean dbOnly) { this.dbOnly = dbOnly; } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionOverlayVolumeMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionOverlayVolumeMsg.java new file mode 100644 index 00000000000..5f2d267cfec --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionOverlayVolumeMsg.java @@ -0,0 +1,17 @@ +package org.zstack.header.storage.snapshot; + +import org.zstack.header.message.OverlayMessage; +import org.zstack.header.volume.VolumeMessage; + +public class VolumeSnapshotDeletionOverlayVolumeMsg extends OverlayMessage implements VolumeMessage { + private String volumeUuid; + + @Override + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionStructs.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionStructs.java new file mode 100644 index 00000000000..cd1b03ef05a --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotDeletionStructs.java @@ -0,0 +1,39 @@ +package org.zstack.header.storage.snapshot; + +import java.util.List; + +public class VolumeSnapshotDeletionStructs { + private List snapshotInventories; + private String direction; + private String scope; + + public VolumeSnapshotDeletionStructs(List snapshotInventories, String direction, String scope) { + this.snapshotInventories = snapshotInventories; + this.direction = direction; + this.scope = scope; + } + + public List getSnapshotInventories() { + return snapshotInventories; + } + + public void setSnapshotInventories(List snapshotInventories) { + this.snapshotInventories = snapshotInventories; + } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotInventory.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotInventory.java old mode 100755 new mode 100644 index 414e2e7da0b..d37ba70d14e --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotInventory.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotInventory.java @@ -195,6 +195,18 @@ public static VolumeSnapshotInventory valueOf(VolumeSnapshotVO vo) { return inv; } + public static VolumeSnapshotInventory valueOf(VolumeSnapshotGroupRefInventory ref) { + VolumeSnapshotInventory inv = new VolumeSnapshotInventory(); + inv.setCreateDate(ref.getCreateDate()); + inv.setLastOpDate(ref.getLastOpDate()); + inv.setName(ref.getVolumeSnapshotName()); + inv.setVolumeUuid(ref.getVolumeUuid()); + inv.setUuid(ref.getVolumeSnapshotUuid()); + inv.setVolumeType(ref.getVolumeType()); + inv.setGroupUuid(ref.getVolumeSnapshotGroupUuid()); + return inv; + + } public static List valueOf(Collection vos) { List invs = new ArrayList(); for (VolumeSnapshotVO vo : vos) { diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotOverlayMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotOverlayMsg.java index f60a71387dc..737e3221c15 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotOverlayMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotOverlayMsg.java @@ -1,12 +1,12 @@ package org.zstack.header.storage.snapshot; -import org.zstack.header.message.OverlayMessage; +import org.zstack.header.message.MulitpleOverlayMsg; import org.zstack.header.volume.VolumeMessage; /** * Created by david on 11/25/16. */ -public class VolumeSnapshotOverlayMsg extends OverlayMessage implements VolumeMessage { +public class VolumeSnapshotOverlayMsg extends MulitpleOverlayMsg implements VolumeMessage { private String volumeUuid; @Override diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotPreDeleteExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotPreDeleteExtensionPoint.java deleted file mode 100755 index fdd6c422490..00000000000 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotPreDeleteExtensionPoint.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.zstack.header.storage.snapshot; - -/** - * Created by xing5 on 2016/5/3. - */ -public interface VolumeSnapshotPreDeleteExtensionPoint { - void volumeSnapshotPreDeleteExtensionPoint(VolumeSnapshotInventory snapshot); -} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotRevertOverlayVolumeMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotRevertOverlayVolumeMsg.java new file mode 100644 index 00000000000..c3a19becf5f --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotRevertOverlayVolumeMsg.java @@ -0,0 +1,16 @@ +package org.zstack.header.storage.snapshot; + +import org.zstack.header.message.OverlayMessage; +import org.zstack.header.volume.VolumeMessage; + +public class VolumeSnapshotRevertOverlayVolumeMsg extends OverlayMessage implements VolumeMessage { + private String volumeUuid; + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStats.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStats.java new file mode 100644 index 00000000000..8b4e3778ef3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStats.java @@ -0,0 +1,22 @@ +package org.zstack.header.storage.snapshot; + +public class VolumeSnapshotStats { + private String installPath; + private long actualSize; + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStruct.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStruct.java index c8e1d40eb93..0024c8f0d1b 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStruct.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotStruct.java @@ -6,6 +6,7 @@ public class VolumeSnapshotStruct { private VolumeSnapshotInventory parent; private VolumeSnapshotInventory current; private boolean fullSnapshot; + private boolean newChain; public boolean isFullSnapshot() { return fullSnapshot; @@ -30,4 +31,12 @@ public VolumeSnapshotInventory getCurrent() { public void setCurrent(VolumeSnapshotInventory current) { this.current = current; } + + public boolean isNewChain() { + return newChain; + } + + public void setNewChain(boolean newChain) { + this.newChain = newChain; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTree.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTree.java index ff5c11a693a..57b4fab4099 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTree.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTree.java @@ -217,13 +217,13 @@ public void setUuid(String uuid) { inventory.setUuid(uuid); } - private void walkDown(SnapshotLeaf me, Consumer consumer) { + private static void walkDownAll(SnapshotLeaf me, Consumer consumer) { consumer.accept(me); - me.children.forEach(c -> walkDown(c, consumer)); + me.children.forEach(c -> walkDownAll(c, consumer)); } - public void walkDown(Consumer consumer) { - walkDown(this, consumer); + public void walkDownAll(Consumer consumer) { + walkDownAll(this, consumer); } public VolumeSnapshotTree toSubTree() { @@ -348,6 +348,7 @@ private VolumeSnapshotInventory getInventory(Set filterUuids) { private SnapshotLeaf root; private String volumeUuid; + private String uuid; public static VolumeSnapshotTree fromInventories(List invs) { VolumeSnapshotTree tree = new VolumeSnapshotTree(); @@ -377,6 +378,7 @@ public static VolumeSnapshotTree fromInventories(List i } tree.volumeUuid = inv.getVolumeUuid(); + tree.uuid = inv.getTreeUuid(); } DebugUtils.Assert(tree.root != null, "why tree root is null???"); @@ -403,6 +405,14 @@ public void setVolumeUuid(String volumeUuid) { this.volumeUuid = volumeUuid; } + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + private SnapshotLeaf findSnapshot(final List leafs, final Function func) { for (SnapshotLeaf leaf : leafs) { SnapshotLeaf ret = findSnapshot(leaf.children, func); @@ -424,4 +434,12 @@ public SnapshotLeaf findSnapshot(Function func } return findSnapshot(root.children, func); } + + public SnapshotLeaf findSnapshot(String snapshotUuid) { + if (snapshotUuid == null) { + return null; + } + + return findSnapshot(arg -> arg.getUuid().equals(snapshotUuid)); + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTreeAO.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTreeAO.java index 6b2fcc458d0..fbf7ce6d480 100755 --- a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTreeAO.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeSnapshotTreeAO.java @@ -16,6 +16,9 @@ public class VolumeSnapshotTreeAO extends ResourceVO { @ForeignKey(parentEntityClass = VolumeEO.class, onDeleteAction = ReferenceOption.SET_NULL) private String volumeUuid; + @Column + private String rootImageUuid; + @Column private boolean current; @@ -42,6 +45,14 @@ public void setVolumeUuid(String volumeUuid) { this.volumeUuid = volumeUuid; } + public void setRootImageUuid(String rootImageUuid) { + this.rootImageUuid = rootImageUuid; + } + + public String getRootImageUuid() { + return rootImageUuid; + } + public Timestamp getCreateDate() { return createDate; } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/VolumeTemplateOverlayMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeTemplateOverlayMsg.java new file mode 100644 index 00000000000..c232c351d91 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/VolumeTemplateOverlayMsg.java @@ -0,0 +1,17 @@ +package org.zstack.header.storage.snapshot; + +import org.zstack.header.message.OverlayMessage; +import org.zstack.header.volume.VolumeMessage; + +public class VolumeTemplateOverlayMsg extends OverlayMessage implements VolumeMessage { + private String volumeUuid; + + @Override + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APICheckVolumeSnapshotGroupAvailabilityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/group/APICheckVolumeSnapshotGroupAvailabilityMsgDoc_zh_cn.groovy index 26b3d81fd69..6e276bb181a 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APICheckVolumeSnapshotGroupAvailabilityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APICheckVolumeSnapshotGroupAvailabilityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "3.6.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.6.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsg.java index 1a5d3c16f7e..42fe3df00a9 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsg.java @@ -5,6 +5,7 @@ import org.zstack.header.message.APIDeleteMessage; import org.zstack.header.message.APIParam; import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; import org.zstack.header.storage.snapshot.SnapshotBackendOperation; import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; @@ -25,6 +26,15 @@ public class APIDeleteVolumeSnapshotGroupMsg extends APIDeleteMessage implements @APIParam(resourceType = VolumeSnapshotGroupVO.class, successIfResourceNotExisting = true) private String uuid; + @APIParam(required = false, validValues = {"pull", "commit", "auto"}) + private String direction = "auto"; + + @APIParam(required = false, validValues = {"single", "chain", "auto"}) + private String scope = "chain"; + + @APINoSee + private String vmUuid; + public String getUuid() { return uuid; } @@ -33,6 +43,30 @@ public void setUuid(String uuid) { this.uuid = uuid; } + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + @Override public String getGroupUuid() { return uuid; diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsgDoc_zh_cn.groovy index c193c1541a7..11e71e4c39d 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIDeleteVolumeSnapshotGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,24 @@ doc { type "String" optional false since "3.6.0" - + } + column { + name "direction" + enclosedIn "" + desc "数据合并方向。pull:向前合并;commit:向后合并;auto:自动选择最优合并方向" + location "body" + type "String" + optional true + since "5.4.0" + } + column { + name "scope" + enclosedIn "" + desc "数据合并方式。single:仅合并单个快照;chain:合并整个快照链;auto:自动判断最佳合并范围" + location "body" + type "String" + optional true + since "5.4.0" } column { name "deleteMode" @@ -39,7 +56,6 @@ doc { type "String" optional true since "3.6.0" - } column { name "systemTags" @@ -49,7 +65,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -59,7 +74,6 @@ doc { type "List" optional true since "3.6.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsg.java index 17c58e5f8b1..b19b4a9584d 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsg.java @@ -6,12 +6,16 @@ import org.springframework.http.HttpMethod; import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; import org.zstack.header.storage.snapshot.SnapshotBackendOperation; import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; +import org.zstack.header.vm.VmInstanceVO; import java.util.concurrent.TimeUnit; @@ -24,10 +28,13 @@ ) @DefaultTimeout(timeunit = TimeUnit.HOURS, value = 24) -public class APIRevertVmFromSnapshotGroupMsg extends APIMessage implements VolumeSnapshotGroupMessage { +public class APIRevertVmFromSnapshotGroupMsg extends APIMessage implements VolumeSnapshotGroupMessage, APIAuditor { @APIParam(resourceType = VolumeSnapshotGroupVO.class) private String uuid; + @APINoSee + private String vmInstanceUuid; + @Override public String getGroupUuid() { return uuid; @@ -46,9 +53,35 @@ public void setUuid(String uuid) { this.uuid = uuid; } + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + public static APIRevertVmFromSnapshotGroupMsg __example__() { APIRevertVmFromSnapshotGroupMsg result = new APIRevertVmFromSnapshotGroupMsg(); result.uuid = uuid(); return result; } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + if (!rsp.isSuccess()) { + return null; + } + + APIRevertVmFromSnapshotGroupEvent evt = (APIRevertVmFromSnapshotGroupEvent) rsp; + if (!evt.getResults().stream().allMatch(RevertSnapshotGroupResult::isSuccess)) { + return null; + } + + if (((APIRevertVmFromSnapshotGroupMsg) msg).getVmInstanceUuid() == null) { + return null; + } + + return new Result(((APIRevertVmFromSnapshotGroupMsg) msg).getVmInstanceUuid(), VmInstanceVO.class); + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsgDoc_zh_cn.groovy index 6cf3ff5371c..7870eccc77f 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIRevertVmFromSnapshotGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.6.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.6.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUngroupVolumeSnapshotGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUngroupVolumeSnapshotGroupMsgDoc_zh_cn.groovy index 474a5dbb08e..7c2cc69168e 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUngroupVolumeSnapshotGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUngroupVolumeSnapshotGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.6.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.6.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUpdateVolumeSnapshotGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUpdateVolumeSnapshotGroupMsgDoc_zh_cn.groovy index 6abfd5ba280..9976ff32e47 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUpdateVolumeSnapshotGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/APIUpdateVolumeSnapshotGroupMsgDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.header.storage.snapshot.group.APIUpdateVolumeSnapshotGroupEven doc { title "UpdateVolumeSnapshotGroup" - category "snapshot.volume" + category "snapshot.volume" desc """更新云盘快照组信息""" @@ -29,7 +29,6 @@ doc { type "String" optional true since "3.6.0" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.6.0" - } column { name "uuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "3.6.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.6.0" - } } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/DeleteVolumeSnapshotGroupInnerMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/DeleteVolumeSnapshotGroupInnerMsg.java index cddf37f9ff1..6f1129a8911 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/DeleteVolumeSnapshotGroupInnerMsg.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/DeleteVolumeSnapshotGroupInnerMsg.java @@ -10,6 +10,8 @@ public class DeleteVolumeSnapshotGroupInnerMsg extends NeedReplyMessage implements VolumeSnapshotGroupMessage { private String uuid; private String deletionMode; + private String direction; + private String scope; public String getUuid() { return uuid; @@ -36,4 +38,20 @@ public void setDeletionMode(APIDeleteMessage.DeletionMode deletionMode) { public APIDeleteMessage.DeletionMode getDeletionMode() { return APIDeleteMessage.DeletionMode.valueOf(deletionMode); } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java new file mode 100644 index 00000000000..0d3698457f7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/MemorySnapshotValidatorExtensionPoint.java @@ -0,0 +1,16 @@ +package org.zstack.header.storage.snapshot.group; + +import org.zstack.header.errorcode.ErrorCode; + +/** + * Created by LiangHanYu on 2022/6/9 18:30 + */ +public interface MemorySnapshotValidatorExtensionPoint { + default ErrorCode checkVmWhereMemorySnapshotExistExternalDevices(String VmInstanceUuid) { + return null; + } + + default ErrorCode checkL3IfReferencedByMemorySnapshot(String l3Uuid) { + return null; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefInventory.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefInventory.java index 75df893e5d6..a6cde2ad2c7 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefInventory.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefInventory.java @@ -32,6 +32,7 @@ public class VolumeSnapshotGroupRefInventory { private String volumeSnapshotName; private Timestamp createDate; private Timestamp lastOpDate; + private Timestamp volumeLastAttachDate; public String getVolumeSnapshotUuid() { return volumeSnapshotUuid; @@ -78,6 +79,7 @@ public static VolumeSnapshotGroupRefInventory valueOf(VolumeSnapshotGroupRefVO v ref.volumeSnapshotName = vo.getVolumeSnapshotName(); ref.createDate = vo.getCreateDate(); ref.lastOpDate = vo.getLastOpDate(); + ref.volumeLastAttachDate = vo.getVolumeLastAttachDate(); return ref; } @@ -140,4 +142,12 @@ public String getVolumeSnapshotName() { public void setVolumeSnapshotName(String volumeSnapshotName) { this.volumeSnapshotName = volumeSnapshotName; } + + public Timestamp getVolumeLastAttachDate() { + return volumeLastAttachDate; + } + + public void setVolumeLastAttachDate(Timestamp volumeLastAttachDate) { + this.volumeLastAttachDate = volumeLastAttachDate; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO.java index 3b66508846f..46ca80c8baf 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO.java @@ -55,6 +55,9 @@ public class VolumeSnapshotGroupRefVO implements Serializable { @Column private Timestamp lastOpDate; + @Column + private Timestamp volumeLastAttachDate; + @PreUpdate private void preUpdate() { lastOpDate = null; @@ -147,4 +150,12 @@ public boolean isSnapshotDeleted() { public void setSnapshotDeleted(boolean snapshotDeleted) { this.snapshotDeleted = snapshotDeleted; } + + public Timestamp getVolumeLastAttachDate() { + return volumeLastAttachDate; + } + + public void setVolumeLastAttachDate(Timestamp volumeLastAttachDate) { + this.volumeLastAttachDate = volumeLastAttachDate; + } } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO_.java b/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO_.java index ba76c9bedba..b37d4f2d505 100644 --- a/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO_.java +++ b/header/src/main/java/org/zstack/header/storage/snapshot/group/VolumeSnapshotGroupRefVO_.java @@ -22,4 +22,5 @@ public class VolumeSnapshotGroupRefVO_ { public static volatile SingularAttribute volumeSnapshotInstallPath; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; + public static volatile SingularAttribute volumeLastAttachDate; } diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/DeleteVolumeSnapshotReferenceLeafMsg.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/DeleteVolumeSnapshotReferenceLeafMsg.java new file mode 100644 index 00000000000..6cb37c918e7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/DeleteVolumeSnapshotReferenceLeafMsg.java @@ -0,0 +1,46 @@ +package org.zstack.header.storage.snapshot.reference; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.volume.VolumeInventory; + +import java.util.List; + +public class DeleteVolumeSnapshotReferenceLeafMsg extends NeedReplyMessage implements VolumeSnapshotReferenceMessage { + private VolumeSnapshotReferenceInventory leaf; + private List otherLeafs; + private VolumeSnapshotReferenceTreeInventory tree; + private VolumeInventory deletedVolume; + + @Override + public VolumeSnapshotReferenceTreeInventory getTree() { + return tree; + } + + public void setTree(VolumeSnapshotReferenceTreeInventory tree) { + this.tree = tree; + } + + public VolumeSnapshotReferenceInventory getLeaf() { + return leaf; + } + + public void setLeaf(VolumeSnapshotReferenceInventory leaf) { + this.leaf = leaf; + } + + public List getOtherLeafs() { + return otherLeafs; + } + + public void setOtherLeafs(List otherLeafs) { + this.otherLeafs = otherLeafs; + } + + public VolumeInventory getDeletedVolume() { + return deletedVolume; + } + + public void setDeletedVolume(VolumeInventory deletedVolume) { + this.deletedVolume = deletedVolume; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/DeleteVolumeSnapshotReferenceLeafReply.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/DeleteVolumeSnapshotReferenceLeafReply.java new file mode 100644 index 00000000000..ac0629b91d7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/DeleteVolumeSnapshotReferenceLeafReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.storage.snapshot.reference; + +import org.zstack.header.message.MessageReply; + +public class DeleteVolumeSnapshotReferenceLeafReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceInventory.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceInventory.java new file mode 100644 index 00000000000..e8b12800b12 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceInventory.java @@ -0,0 +1,179 @@ +package org.zstack.header.storage.snapshot.reference; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeInventory; + +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Inventory(mappingVOClass = VolumeSnapshotReferenceVO.class) +@PythonClassInventory +@ExpandedQueries({ + @ExpandedQuery(expandedField = "volume", inventoryClass = VolumeInventory.class, + foreignKey = "volumeUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "referenceVolume", inventoryClass = VolumeInventory.class, + foreignKey = "referenceVolumeUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "volumeSnapshot", inventoryClass = VolumeSnapshotInventory.class, + foreignKey = "volumeSnapshotUuid", expandedInventoryKey = "uuid"), +}) +public class VolumeSnapshotReferenceInventory { + private long id; + + private Long parentId; + private String volumeUuid; + + private String volumeSnapshotUuid; + + private String volumeSnapshotInstallUrl; + + private String directSnapshotUuid; + + private String directSnapshotInstallUrl; + + /** + * the UUID of resource referencing @volumeUuid. + */ + private String referenceUuid; + + private String referenceType; + + private String referenceInstallUrl; + + private String referenceVolumeUuid; + + private Timestamp createDate; + + private Timestamp lastOpDate; + + public static VolumeSnapshotReferenceInventory valueOf(VolumeSnapshotReferenceVO vo) { + VolumeSnapshotReferenceInventory inv = new VolumeSnapshotReferenceInventory(); + inv.id = vo.getId(); + inv.parentId = vo.getParentId(); + inv.volumeUuid = vo.getVolumeUuid(); + inv.volumeSnapshotUuid = vo.getVolumeSnapshotUuid(); + inv.directSnapshotUuid = vo.getDirectSnapshotUuid(); + inv.volumeSnapshotInstallUrl = vo.getVolumeSnapshotInstallUrl(); + inv.directSnapshotInstallUrl = vo.getDirectSnapshotInstallUrl(); + inv.referenceUuid = vo.getReferenceUuid(); + inv.referenceType = vo.getReferenceType(); + inv.referenceInstallUrl = vo.getReferenceInstallUrl(); + inv.referenceVolumeUuid = vo.getReferenceVolumeUuid(); + inv.createDate = vo.getCreateDate(); + inv.lastOpDate = vo.getLastOpDate(); + return inv; + } + + public static List valueOf(Collection vos) { + return vos.stream().map(VolumeSnapshotReferenceInventory::valueOf).collect(Collectors.toList()); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getVolumeSnapshotUuid() { + return volumeSnapshotUuid; + } + + public void setVolumeSnapshotUuid(String volumeSnapshotUuid) { + this.volumeSnapshotUuid = volumeSnapshotUuid; + } + + public String getVolumeSnapshotInstallUrl() { + return volumeSnapshotInstallUrl; + } + + public void setVolumeSnapshotInstallUrl(String volumeSnapshotInstallUrl) { + this.volumeSnapshotInstallUrl = volumeSnapshotInstallUrl; + } + + public String getReferenceUuid() { + return referenceUuid; + } + + public void setReferenceUuid(String referenceUuid) { + this.referenceUuid = referenceUuid; + } + + public String getReferenceType() { + return referenceType; + } + + public void setReferenceType(String referenceType) { + this.referenceType = referenceType; + } + + public String getReferenceInstallUrl() { + return referenceInstallUrl; + } + + public void setReferenceInstallUrl(String referenceInstallUrl) { + this.referenceInstallUrl = referenceInstallUrl; + } + + public String getReferenceVolumeUuid() { + return referenceVolumeUuid; + } + + public void setReferenceVolumeUuid(String referenceVolumeUuid) { + this.referenceVolumeUuid = referenceVolumeUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getDirectSnapshotUuid() { + return directSnapshotUuid; + } + + public void setDirectSnapshotUuid(String directSnapshotUuid) { + this.directSnapshotUuid = directSnapshotUuid; + } + + public String getDirectSnapshotInstallUrl() { + return directSnapshotInstallUrl; + } + + public void setDirectSnapshotInstallUrl(String directSnapshotInstallUrl) { + this.directSnapshotInstallUrl = directSnapshotInstallUrl; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceMessage.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceMessage.java new file mode 100644 index 00000000000..56779fe93ae --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceMessage.java @@ -0,0 +1,5 @@ +package org.zstack.header.storage.snapshot.reference; + +public interface VolumeSnapshotReferenceMessage { + VolumeSnapshotReferenceTreeInventory getTree(); +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeInventory.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeInventory.java new file mode 100644 index 00000000000..aa04b41c251 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeInventory.java @@ -0,0 +1,93 @@ +package org.zstack.header.storage.snapshot.reference; + + +import org.zstack.header.search.Inventory; +import org.zstack.header.vo.ResourceInventory; + +import java.util.List; +import java.util.stream.Collectors; + +@Inventory(mappingVOClass = VolumeSnapshotReferenceTreeVO.class) +public class VolumeSnapshotReferenceTreeInventory extends ResourceInventory { + + private String primaryStorageUuid; + private String hostUuid; + private String rootImageUuid; + private String rootVolumeUuid; + private String rootVolumeSnapshotUuid; + private String rootVolumeSnapshotTreeUuid; + private String rootInstallUrl; + + public String getRootImageUuid() { + return rootImageUuid; + } + + public void setRootImageUuid(String rootImageUuid) { + this.rootImageUuid = rootImageUuid; + } + + public String getRootVolumeSnapshotUuid() { + return rootVolumeSnapshotUuid; + } + + public void setRootVolumeSnapshotUuid(String rootVolumeSnapshotUuid) { + this.rootVolumeSnapshotUuid = rootVolumeSnapshotUuid; + } + + public String getRootVolumeUuid() { + return rootVolumeUuid; + } + + public void setRootVolumeUuid(String rootVolumeUuid) { + this.rootVolumeUuid = rootVolumeUuid; + } + + public String getRootVolumeSnapshotTreeUuid() { + return rootVolumeSnapshotTreeUuid; + } + + public void setRootVolumeSnapshotTreeUuid(String rootVolumeSnapshotTreeUuid) { + this.rootVolumeSnapshotTreeUuid = rootVolumeSnapshotTreeUuid; + } + + public String getRootInstallUrl() { + return rootInstallUrl; + } + + public void setRootInstallUrl(String rootInstallUrl) { + this.rootInstallUrl = rootInstallUrl; + } + + public static VolumeSnapshotReferenceTreeInventory valueOf(VolumeSnapshotReferenceTreeVO vo) { + VolumeSnapshotReferenceTreeInventory inv = new VolumeSnapshotReferenceTreeInventory(); + inv.setUuid(vo.getUuid()); + inv.setRootImageUuid(vo.getRootImageUuid()); + inv.setRootVolumeSnapshotUuid(vo.getRootVolumeSnapshotUuid()); + inv.setRootVolumeUuid(vo.getRootVolumeUuid()); + inv.setRootVolumeSnapshotTreeUuid(vo.getRootVolumeSnapshotTreeUuid()); + inv.setRootInstallUrl(vo.getRootInstallUrl()); + inv.setPrimaryStorageUuid(vo.getPrimaryStorageUuid()); + inv.setHostUuid(vo.getHostUuid()); + return inv; + } + + public static List valueOf(List vos) { + return vos.stream().map(VolumeSnapshotReferenceTreeInventory::valueOf).collect(Collectors.toList()); + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeVO.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeVO.java new file mode 100644 index 00000000000..021a611446e --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeVO.java @@ -0,0 +1,109 @@ +package org.zstack.header.storage.snapshot.reference; + +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class VolumeSnapshotReferenceTreeVO extends ResourceVO implements ToInventory { + @Column + private String primaryStorageUuid; + @Column + private String hostUuid; + @Column + private String rootImageUuid; + @Column + private String rootVolumeSnapshotTreeUuid; + @Column + private String rootVolumeSnapshotUuid; + @Column + private String rootVolumeUuid; + @Column + private String rootInstallUrl; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public String getRootImageUuid() { + return rootImageUuid; + } + + public void setRootImageUuid(String rootImageUuid) { + this.rootImageUuid = rootImageUuid; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getRootVolumeSnapshotTreeUuid() { + return rootVolumeSnapshotTreeUuid; + } + + public void setRootVolumeSnapshotTreeUuid(String rootVolumeSnapshotTreeUuid) { + this.rootVolumeSnapshotTreeUuid = rootVolumeSnapshotTreeUuid; + } + + public String getRootVolumeSnapshotUuid() { + return rootVolumeSnapshotUuid; + } + + public void setRootVolumeSnapshotUuid(String rootVolumeSnapshotUuid) { + this.rootVolumeSnapshotUuid = rootVolumeSnapshotUuid; + } + + public String getRootInstallUrl() { + return rootInstallUrl; + } + + public void setRootInstallUrl(String rootVolumeSnapshotInstallUrl) { + this.rootInstallUrl = rootVolumeSnapshotInstallUrl; + } + + public String getRootVolumeUuid() { + return rootVolumeUuid; + } + + public void setRootVolumeUuid(String rootVolumeUuid) { + this.rootVolumeUuid = rootVolumeUuid; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeVO_.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeVO_.java new file mode 100644 index 00000000000..0020210791c --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceTreeVO_.java @@ -0,0 +1,19 @@ +package org.zstack.header.storage.snapshot.reference; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + + +@StaticMetamodel(VolumeSnapshotReferenceTreeVO.class) +public class VolumeSnapshotReferenceTreeVO_ extends ResourceVO_ { + public static volatile SingularAttribute rootImageUuid; + public static volatile SingularAttribute rootVolumeSnapshotUuid; + public static volatile SingularAttribute rootVolumeUuid; + public static volatile SingularAttribute rootVolumeSnapshotTreeUuid; + public static volatile SingularAttribute rootVolumeSnapshotInstallUrl; + + public static volatile SingularAttribute primaryStorageUuid; + public static volatile SingularAttribute hostUuid; +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceVO.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceVO.java new file mode 100644 index 00000000000..c646c440847 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceVO.java @@ -0,0 +1,206 @@ +package org.zstack.header.storage.snapshot.reference; + + +import org.zstack.header.storage.snapshot.VolumeSnapshotVO; +import org.zstack.header.vo.BaseResource; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.volume.VolumeEO; +import org.zstack.header.volume.VolumeVO; + +import javax.persistence.*; +import java.sql.Timestamp; + + +@Entity +@Table +@BaseResource +@EntityGraph( + parents = { + @EntityGraph.Neighbour(type = VolumeVO.class, myField = "volumeUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = VolumeVO.class, myField = "referenceVolumeUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = VolumeSnapshotVO.class, myField = "volumeSnapshotUuid", targetField = "uuid"), + } +) +public class VolumeSnapshotReferenceVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + private String volumeUuid; + + @Column + private String volumeSnapshotUuid; + + @Column + private String volumeSnapshotInstallUrl; + + @Column + private String directSnapshotUuid; + + @Column + private String directSnapshotInstallUrl; + + @Column + @ForeignKey(parentEntityClass = VolumeSnapshotReferenceTreeVO.class, onDeleteAction = ForeignKey.ReferenceOption.RESTRICT) + private String treeUuid; + + @Column + @ForeignKey(parentEntityClass = VolumeSnapshotReferenceVO.class, onDeleteAction = ForeignKey.ReferenceOption.SET_NULL) + private Long parentId; + + + /** + * the UUID of resource referencing @volumeUuid. + */ + @Column + private String referenceUuid; + + @Column + private String referenceType; + + @Column + private String referenceInstallUrl; + + @Column + @ForeignKey(parentEntityClass = VolumeEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String referenceVolumeUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getVolumeSnapshotUuid() { + return volumeSnapshotUuid; + } + + public void setVolumeSnapshotUuid(String volumeSnapshotUuid) { + this.volumeSnapshotUuid = volumeSnapshotUuid; + } + + public String getTreeUuid() { + return treeUuid; + } + + public void setTreeUuid(String treeUuid) { + this.treeUuid = treeUuid; + } + + public String getVolumeSnapshotInstallUrl() { + return volumeSnapshotInstallUrl; + } + + public void setVolumeSnapshotInstallUrl(String volumeSnapshotInstallUrl) { + this.volumeSnapshotInstallUrl = volumeSnapshotInstallUrl; + } + + public String getReferenceUuid() { + return referenceUuid; + } + + public void setReferenceUuid(String referenceUuid) { + this.referenceUuid = referenceUuid; + } + + public String getReferenceType() { + return referenceType; + } + + public void setReferenceType(String referenceType) { + this.referenceType = referenceType; + } + + public String getReferenceInstallUrl() { + return referenceInstallUrl; + } + + public void setReferenceInstallUrl(String referenceInstallUrl) { + this.referenceInstallUrl = referenceInstallUrl; + } + + public String getReferenceVolumeUuid() { + return referenceVolumeUuid; + } + + public void setReferenceVolumeUuid(String referenceVolumeUuid) { + this.referenceVolumeUuid = referenceVolumeUuid; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public VolumeSnapshotReferenceVO clone() { + VolumeSnapshotReferenceVO vo = new VolumeSnapshotReferenceVO(); + vo.volumeUuid = this.volumeUuid; + vo.volumeSnapshotUuid = this.volumeSnapshotUuid; + vo.directSnapshotUuid = this.directSnapshotUuid; + vo.directSnapshotInstallUrl = this.directSnapshotInstallUrl; + vo.volumeSnapshotInstallUrl = this.volumeSnapshotInstallUrl; + vo.referenceUuid = this.referenceUuid; + vo.referenceType = this.referenceType; + vo.referenceInstallUrl = this.referenceInstallUrl; + vo.referenceVolumeUuid = this.referenceVolumeUuid; + return vo; + } + + public String getDirectSnapshotUuid() { + return directSnapshotUuid; + } + + public void setDirectSnapshotUuid(String directSnapshotUuid) { + this.directSnapshotUuid = directSnapshotUuid; + } + + public String getDirectSnapshotInstallUrl() { + return directSnapshotInstallUrl; + } + + public void setDirectSnapshotInstallUrl(String directSnapshotInstallUrl) { + this.directSnapshotInstallUrl = directSnapshotInstallUrl; + } +} diff --git a/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceVO_.java b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceVO_.java new file mode 100644 index 00000000000..35a2e878ec1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/storage/snapshot/reference/VolumeSnapshotReferenceVO_.java @@ -0,0 +1,22 @@ +package org.zstack.header.storage.snapshot.reference; + + +import org.zstack.header.storage.snapshot.VolumeSnapshotBackupStorageRefVO; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(VolumeSnapshotReferenceVO.class) +public class VolumeSnapshotReferenceVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute parentId; + public static volatile SingularAttribute volumeUuid; + public static volatile SingularAttribute volumeSnapshotUuid; + public static volatile SingularAttribute volumeSnapshotInstallUrl; + public static volatile SingularAttribute treeUuid; + public static volatile SingularAttribute referenceUuid; + public static volatile SingularAttribute referenceType; + public static volatile SingularAttribute referenceInstallUrl; + public static volatile SingularAttribute referenceVolumeUuid; + +} diff --git a/header/src/main/java/org/zstack/header/tag/APIAbstractCreateTagMsg.java b/header/src/main/java/org/zstack/header/tag/APIAbstractCreateTagMsg.java new file mode 100755 index 00000000000..511efb1ae7b --- /dev/null +++ b/header/src/main/java/org/zstack/header/tag/APIAbstractCreateTagMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.tag; + +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.vo.ResourceVO; + +/** + */ +public abstract class APIAbstractCreateTagMsg extends APIMessage { + @APIParam + private String resourceType; + @APIParam(checkAccount = true, resourceType = ResourceVO.class) + private String resourceUuid; + @APIParam + @NoLogging(type = NoLogging.Type.Tag) + private String tag; + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getTag() { + return tag; + } + + public void setTag(String tag) { + this.tag = tag; + } + +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsg.java b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsg.java index ffdc084f232..6af21bd7786 100755 --- a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsg.java +++ b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsg.java @@ -13,7 +13,7 @@ responseClass = APICreateSystemTagEvent.class, parameterName = "params" ) -public class APICreateSystemTagMsg extends APICreateTagMsg { +public class APICreateSystemTagMsg extends APIAbstractCreateTagMsg { public static APICreateSystemTagMsg __example__() { APICreateSystemTagMsg msg = new APICreateSystemTagMsg(); diff --git a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsgDoc_zh_cn.groovy index 17f8338377b..4341a8bf703 100644 --- a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "tag" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsEvent.java b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsEvent.java new file mode 100644 index 00000000000..b8e4e9d67df --- /dev/null +++ b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsEvent.java @@ -0,0 +1,44 @@ +package org.zstack.header.tag; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APICreateSystemTagsEvent extends APIEvent { + private List inventories; + + public APICreateSystemTagsEvent(String apiId) { + super(apiId); + } + + public APICreateSystemTagsEvent() { + super(null); + } + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APICreateSystemTagsEvent __example__() { + APICreateSystemTagsEvent event = new APICreateSystemTagsEvent(); + SystemTagInventory tag = new SystemTagInventory(); + tag.setInherent(false); + tag.setType("System"); + tag.setResourceType(uuid()); + tag.setResourceType("HostVO"); + tag.setTag("reservedMemory::1G"); + tag.setUuid(uuid() ); + tag.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + tag.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + event.setInventories(Collections.singletonList(tag)); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..2f79144bc1a --- /dev/null +++ b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.tag + +import org.zstack.header.tag.SystemTagInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "标签清单" + + ref { + name "inventories" + path "org.zstack.header.tag.APICreateSystemTagsEvent.inventories" + desc "null" + type "List" + since "4.7.0" + clz SystemTagInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.tag.APICreateSystemTagsEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsMsg.java b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsMsg.java new file mode 100644 index 00000000000..edd7ea7992c --- /dev/null +++ b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsMsg.java @@ -0,0 +1,51 @@ +package org.zstack.header.tag; +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vo.ResourceVO; + +import java.util.List; + +@Action(category = TagConstant.ACTION_CATEGORY) +@RestRequest( + path = "/system-tags/{resourceUuid}/tags", + method = HttpMethod.POST, + responseClass = APICreateSystemTagsEvent.class, + parameterName = "params" +) +public class APICreateSystemTagsMsg extends APIMessage { + @APIParam + private String resourceType; + @APIParam(checkAccount = true, resourceType = ResourceVO.class) + private String resourceUuid; + @APIParam(nonempty = true) + @NoLogging(type = NoLogging.Type.Tag) + private List tags; + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } +} diff --git a/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..df0d3ef6cb7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/tag/APICreateSystemTagsMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.tag + +import org.zstack.header.tag.APICreateSystemTagsEvent + +doc { + title "CreateSystemTags" + + category "tag" + + desc """批量创建系统标签""" + + rest { + request { + url "POST /v1/system-tags/{resourceUuid}/tags" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateSystemTagsMsg.class + + desc """""" + + params { + + column { + name "resourceType" + enclosedIn "params" + desc "当创建一个标签时, 用户必须制定标签所关联的资源类型" + location "body" + type "String" + optional false + since "4.7.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "用户指定的资源UUID,若指定,系统不会为该资源随机分配UUID" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "tags" + enclosedIn "params" + desc "标签字符串列表" + location "body" + type "List" + optional false + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APICreateSystemTagsEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/tag/APICreateTagEvent.java b/header/src/main/java/org/zstack/header/tag/APICreateTagEvent.java deleted file mode 100755 index c72d8c8e076..00000000000 --- a/header/src/main/java/org/zstack/header/tag/APICreateTagEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.zstack.header.tag; - -import org.zstack.header.message.APIEvent; -import org.zstack.header.rest.RestResponse; - -import java.sql.Timestamp; - -/** - */ -public class APICreateTagEvent extends APIEvent { - private TagInventory inventory; - - public TagInventory getInventory() { - return inventory; - } - - public void setInventory(TagInventory inventory) { - this.inventory = inventory; - } - - public APICreateTagEvent(String apiId) { - super(apiId); - } - - public APICreateTagEvent() { - super(null); - } - - public static APICreateTagEvent __example__() { - APICreateTagEvent event = new APICreateTagEvent(); - SystemTagInventory tag = new SystemTagInventory(); - tag.setInherent(false); - tag.setType("System"); - tag.setResourceType(uuid()); - tag.setResourceType("HostVO"); - tag.setTag("reservedMemory::1G"); - tag.setUuid(uuid() ); - tag.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); - tag.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); - event.setInventory(tag); - - - return event; - } - -} diff --git a/header/src/main/java/org/zstack/header/tag/APICreateTagMsg.java b/header/src/main/java/org/zstack/header/tag/APICreateTagMsg.java deleted file mode 100755 index 1456efc4427..00000000000 --- a/header/src/main/java/org/zstack/header/tag/APICreateTagMsg.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.zstack.header.tag; - -import org.zstack.header.log.NoLogging; -import org.zstack.header.message.APIMessage; -import org.zstack.header.message.APIParam; -import org.zstack.header.vo.ResourceVO; - -/** - */ -public abstract class APICreateTagMsg extends APIMessage { - @APIParam - private String resourceType; - @APIParam(checkAccount = true, resourceType = ResourceVO.class) - private String resourceUuid; - @APIParam - @NoLogging(type = NoLogging.Type.Tag) - private String tag; - - public String getResourceType() { - return resourceType; - } - - public void setResourceType(String resourceType) { - this.resourceType = resourceType; - } - - public String getResourceUuid() { - return resourceUuid; - } - - public void setResourceUuid(String resourceUuid) { - this.resourceUuid = resourceUuid; - } - - public String getTag() { - return tag; - } - - public void setTag(String tag) { - this.tag = tag; - } - -} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsg.java b/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsg.java index ed1d0750cb8..3bcc5f944c8 100755 --- a/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsg.java +++ b/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsg.java @@ -13,7 +13,7 @@ responseClass = APICreateUserTagEvent.class, parameterName = "params" ) -public class APICreateUserTagMsg extends APICreateTagMsg { +public class APICreateUserTagMsg extends APIAbstractCreateTagMsg { public static APICreateUserTagMsg __example__() { APICreateUserTagMsg msg = new APICreateUserTagMsg(); diff --git a/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsgDoc_zh_cn.groovy index 6121e8fcce4..fcb45652b6a 100644 --- a/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/tag/APICreateUserTagMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "tag" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/tag/APIDeleteTagMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APIDeleteTagMsgDoc_zh_cn.groovy index bcba8f849ac..bcb7d861e37 100644 --- a/header/src/main/java/org/zstack/header/tag/APIDeleteTagMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/tag/APIDeleteTagMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagMsgDoc_zh_cn.groovy index e8008bd39d7..8d7fcd00e6f 100644 --- a/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.tag import org.zstack.header.tag.APIQuerySystemTagReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QuerySystemTag" diff --git a/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagReply.java b/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagReply.java index 2200054f4a0..d363fbd8a64 100755 --- a/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagReply.java +++ b/header/src/main/java/org/zstack/header/tag/APIQuerySystemTagReply.java @@ -1,5 +1,6 @@ package org.zstack.header.tag; +import org.zstack.header.log.NoLogging; import org.zstack.header.query.APIQueryReply; import org.zstack.header.rest.RestResponse; @@ -12,6 +13,7 @@ */ @RestResponse(allTo = "inventories") public class APIQuerySystemTagReply extends APIQueryReply { + @NoLogging(behavior = NoLogging.Behavior.Auto) private List inventories; public List getInventories() { diff --git a/header/src/main/java/org/zstack/header/tag/APIQueryUserTagMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APIQueryUserTagMsgDoc_zh_cn.groovy index 026270c6327..0a80214dbd0 100644 --- a/header/src/main/java/org/zstack/header/tag/APIQueryUserTagMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/tag/APIQueryUserTagMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.tag import org.zstack.header.tag.APIQueryUserTagReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryUserTag" diff --git a/header/src/main/java/org/zstack/header/tag/APIUpdateSystemTagMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/tag/APIUpdateSystemTagMsgDoc_zh_cn.groovy index 09e3f1c4830..109f26fdc37 100644 --- a/header/src/main/java/org/zstack/header/tag/APIUpdateSystemTagMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/tag/APIUpdateSystemTagMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "tag" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/tag/PackageInfo.java b/header/src/main/java/org/zstack/header/tag/PackageInfo.java index a621f9d07f2..b7783fab29a 100755 --- a/header/src/main/java/org/zstack/header/tag/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/tag/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "标签") +@PackageAPIInfo( + APICategoryName = "标签", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/vm/APIAttachIsoToVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIAttachIsoToVmInstanceMsgDoc_zh_cn.groovy index ec4475779b1..ce9b9b6b8cc 100755 --- a/header/src/main/java/org/zstack/header/vm/APIAttachIsoToVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIAttachIsoToVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "isoUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsg.java b/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsg.java index 900de004c53..639b3740f34 100755 --- a/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsg.java @@ -7,6 +7,7 @@ import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; +import org.zstack.utils.network.NicIpAddressInfo; import java.util.List; import java.util.Map; @@ -66,6 +67,9 @@ public class APIAttachL3NetworkToVmMsg extends APIMessage implements VmInstanceM @APIParam(required = false) private String customMac; + @APIParam(required = false) + private String vmNicParams; + @APINoSee @Deprecated private List secondaryL3Uuids; @@ -73,6 +77,9 @@ public class APIAttachL3NetworkToVmMsg extends APIMessage implements VmInstanceM @APINoSee private Map> staticIpMap; + @APINoSee + private Map nicNetworkInfo; + @APINoSee private boolean applyToBackend = true; @@ -92,6 +99,14 @@ public void setCustomMac(String customMac) { this.customMac = customMac; } + public String getVmNicParams() { + return vmNicParams; + } + + public void setVmNicParams(String vmNicParams) { + this.vmNicParams = vmNicParams; + } + @Override public String getVmInstanceUuid() { return vmInstanceUuid; @@ -141,6 +156,14 @@ public void setDriverType(String driverType) { this.driverType = driverType; } + public Map getNicNetworkInfo() { + return nicNetworkInfo; + } + + public void setNicNetworkInfo(Map nicNetworkInfo) { + this.nicNetworkInfo = nicNetworkInfo; + } + public static APIAttachL3NetworkToVmMsg __example__() { APIAttachL3NetworkToVmMsg msg = new APIAttachL3NetworkToVmMsg(); msg.vmInstanceUuid = uuid(); diff --git a/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsgDoc_zh_cn.groovy index 4a3f0094212..f1c213b1579 100755 --- a/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "staticIp" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "driverType" @@ -79,7 +74,6 @@ doc { type "String" optional true since "4.0.0" - } column { name "customMac" @@ -89,7 +83,15 @@ doc { type "String" optional true since "4.0.0" - + } + column { + name "vmNicParams" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.7.0" } } } @@ -98,4 +100,4 @@ doc { clz APIAttachL3NetworkToVmEvent.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmNicMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmNicMsgDoc_zh_cn.groovy index d4e118372a0..b033387964a 100644 --- a/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmNicMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIAttachL3NetworkToVmNicMsgDoc_zh_cn.groovy @@ -11,10 +11,9 @@ doc { rest { request { - url "POST /v1/vm-instances/{vmNicUuid}/l3-networks/{l3NetworkUuid}" + url "POST /v1/nics/{vmNicUuid}/l3-networks/{l3NetworkUuid}" - - header(Authorization: 'OAuth the-session-uuid') + header (Authorization: 'OAuth the-session-uuid') clz APIAttachL3NetworkToVmNicMsg.class @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuid" @@ -40,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "staticIp" @@ -50,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -60,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -70,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIAttachVmNicToVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIAttachVmNicToVmMsgDoc_zh_cn.groovy index f4d039f1d1a..76f1ed04a31 100644 --- a/header/src/main/java/org/zstack/header/vm/APIAttachVmNicToVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIAttachVmNicToVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "vmInstanceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "4.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIChangeInstanceOfferingMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIChangeInstanceOfferingMsgDoc_zh_cn.groovy index 43c7e9a4301..26bc40d7b24 100644 --- a/header/src/main/java/org/zstack/header/vm/APIChangeInstanceOfferingMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIChangeInstanceOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "instanceOfferingUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIChangeVmNicNetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicNetworkMsgDoc_zh_cn.groovy index ebcd98d21f6..893596734c7 100644 --- a/header/src/main/java/org/zstack/header/vm/APIChangeVmNicNetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicNetworkMsgDoc_zh_cn.groovy @@ -11,7 +11,7 @@ doc { rest { request { - url "POST /v1/vm-instances/nics/{vmNicUuid}/l3-networks/{l3NetworkUuid}" + url "POST /v1/vm-instances/nics/{vmNicUuid}/l3-networks/{destL3NetworkUuid}" header (Authorization: 'OAuth the-session-uuid') @@ -29,17 +29,15 @@ doc { type "String" optional false since "4.1.0" - } column { name "destL3NetworkUuid" enclosedIn "params" desc "" - location "body" + location "url" type "String" optional false since "4.1.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -59,7 +56,15 @@ doc { type "List" optional true since "4.1.0" - + } + column { + name "staticIp" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "0.6" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateEvent.java b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateEvent.java new file mode 100644 index 00000000000..ca513aa0438 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateEvent.java @@ -0,0 +1,107 @@ +package org.zstack.header.vm; + +import org.zstack.header.allocator.HostAllocatorConstant; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeState; +import org.zstack.header.volume.VolumeStatus; +import org.zstack.header.volume.VolumeType; +import org.zstack.utils.data.SizeUnit; + +import java.sql.Timestamp; + +import static java.util.Arrays.asList; + +/** + * Created by boce.wang on 11/09/2022. + */ +@RestResponse(allTo = "inventory") +public class APIChangeVmNicStateEvent extends APIEvent { + private VmInstanceInventory inventory; + + public VmInstanceInventory getInventory() { + return inventory; + } + + public void setInventory(VmInstanceInventory inventory) { + this.inventory = inventory; + } + + public APIChangeVmNicStateEvent() { + } + + public APIChangeVmNicStateEvent(String apiId) { + super(apiId); + } + + public static APIChangeVmNicStateEvent __example__() { + APIChangeVmNicStateEvent event = new APIChangeVmNicStateEvent(); + + + String defaultL3Uuid = uuid(); + String rootVolumeUuid = uuid(); + + VmInstanceInventory vm = new VmInstanceInventory(); + vm.setName("Test-VM"); + vm.setUuid(uuid()); + vm.setAllocatorStrategy(HostAllocatorConstant.LAST_HOST_PREFERRED_ALLOCATOR_STRATEGY_TYPE); + vm.setClusterUuid(uuid()); + vm.setCpuNum(1); + vm.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vm.setDefaultL3NetworkUuid(defaultL3Uuid); + vm.setDescription("web server VM"); + vm.setHostUuid(uuid()); + vm.setHypervisorType("KVM"); + vm.setImageUuid(uuid()); + vm.setInstanceOfferingUuid(uuid()); + vm.setLastHostUuid(uuid()); + vm.setMemorySize(SizeUnit.GIGABYTE.toByte(8)); + vm.setPlatform("Linux"); + vm.setRootVolumeUuid(rootVolumeUuid); + vm.setState(VmInstanceState.Running.toString()); + vm.setType(VmInstanceConstant.USER_VM_TYPE); + vm.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vm.setZoneUuid(uuid()); + + VolumeInventory vol = new VolumeInventory(); + vol.setName(String.format("Root-Volume-For-VM-%s", vm.getUuid())); + vol.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setType(VolumeType.Root.toString()); + vol.setUuid(rootVolumeUuid); + vol.setSize(SizeUnit.GIGABYTE.toByte(100)); + vol.setActualSize(SizeUnit.GIGABYTE.toByte(20)); + vol.setDeviceId(0); + vol.setState(VolumeState.Enabled.toString()); + vol.setFormat("qcow2"); + vol.setDiskOfferingUuid(uuid()); + vol.setInstallPath(String.format("/zstack_ps/rootVolumes/acct-36c27e8ff05c4780bf6d2fa65700f22e/vol-%s/%s.qcow2", rootVolumeUuid, rootVolumeUuid)); + vol.setStatus(VolumeStatus.Ready.toString()); + vol.setPrimaryStorageUuid(uuid()); + vol.setVmInstanceUuid(vm.getUuid()); + vol.setRootImageUuid(vm.getImageUuid()); + vm.setAllVolumes(asList(vol)); + + VmNicInventory nic = new VmNicInventory(); + nic.setVmInstanceUuid(vm.getUuid()); + nic.setCreateDate(vm.getCreateDate()); + nic.setLastOpDate(vm.getLastOpDate()); + nic.setDeviceId(0); + nic.setGateway("192.168.1.1"); + nic.setIp("192.168.1.10"); + nic.setL3NetworkUuid(defaultL3Uuid); + nic.setNetmask("255.255.255.0"); + nic.setMac("00:0c:29:bd:99:fc"); + nic.setHypervisorType("KVM"); + nic.setUsedIpUuid(uuid()); + nic.setUuid(uuid()); + nic.setState("disable"); + vm.setVmNics(asList(nic)); + + event.setInventory(vm); + + return event; + } + +} diff --git a/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..c6b2c318677 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.VmInstanceInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "云主机清单" + + ref { + name "inventory" + path "org.zstack.header.vm.APIChangeVmNicStateEvent.inventory" + desc "null" + type "VmInstanceInventory" + since "0.6" + clz VmInstanceInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.header.vm.APIChangeVmNicStateEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateMsg.java b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateMsg.java new file mode 100644 index 00000000000..9e8dfee3962 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateMsg.java @@ -0,0 +1,79 @@ +package org.zstack.header.vm; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.other.APIMultiAuditor; +import org.zstack.header.rest.APINoSee; +import org.zstack.header.rest.RestRequest; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by boce.wang on 11/09/2022. + */ +@Action(category = VmInstanceConstant.ACTION_CATEGORY) +@RestRequest( + path = "/vm-instances/nics/{vmNicUuid}/actions", + method = HttpMethod.PUT, + responseClass = APIChangeVmNicStateEvent.class, + isAction = true +) +public class APIChangeVmNicStateMsg extends APIMessage implements VmInstanceMessage, APIMultiAuditor { + @APIParam(resourceType = VmNicVO.class, checkAccount = true, operationTarget = true) + private String vmNicUuid; + @APIParam(validValues = {"enable", "disable"}) + private String state; + @APINoSee + private String vmInstanceUuid; + + @APINoSee + public String l3Uuid; + + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public static APIChangeVmNicStateMsg __example__() { + APIChangeVmNicStateMsg msg = new APIChangeVmNicStateMsg(); + msg.vmNicUuid = uuid(); + msg.state = "disable"; + return msg; + } + + @Override + public List multiAudit(APIMessage msg, APIEvent rsp) { + APIChangeVmNicStateMsg amsg = (APIChangeVmNicStateMsg) msg; + List res = new ArrayList<>(); + res.add(new APIAuditor.Result(amsg.getVmInstanceUuid(), VmInstanceVO.class)); + res.add(new APIAuditor.Result(amsg.l3Uuid, L3NetworkVO.class)); + + return res; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..147c8f5b1ea --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIChangeVmNicStateMsgDoc_zh_cn.groovy @@ -0,0 +1,68 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APIChangeVmNicStateEvent + +doc { + title "ChangeVmNicState" + + category "vmInstance" + + desc """修改云主机网卡状态""" + + rest { + request { + url "PUT /v1/vm-instances/nics/{vmNicUuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeVmNicStateMsg.class + + desc """""" + + params { + + column { + name "vmNicUuid" + enclosedIn "changeVmNicState" + desc "云主机网卡UUID" + location "url" + type "String" + optional false + since "0.6" + } + column { + name "state" + enclosedIn "changeVmNicState" + desc "云主机网卡状态" + location "body" + type "String" + optional false + since "4.5" + values ("enable","disable") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APIChangeVmNicStateEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsg.java b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsg.java index efd78290078..6b8f4a8e29e 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsg.java @@ -18,8 +18,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import static java.util.Arrays.asList; - /** * Created by MaJin on 2020/6/29. */ @@ -54,11 +52,17 @@ public class APICreateVmInstanceFromVolumeMsg extends APICreateMessage implement @APIParam(required = false) private Long memorySize; + @APIParam(required = false, numberRange = {0, Long.MAX_VALUE}) + private Long reservedMemorySize; + /** * @desc a list of L3Network uuid the vm will create nic on. See :ref:`L3NetworkInventory` */ - @APIParam(resourceType = L3NetworkVO.class, nonempty = true, checkAccount = true) + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, required = false) private List l3NetworkUuids; + + @APIParam(required = false) + private String vmNicParams; /** * @desc see type of :ref:`VmInstanceInventory` * @choices - UserVm @@ -139,6 +143,11 @@ public Long getMemorySize() { return memorySize; } + @Override + public Long getReservedMemorySize() { + return reservedMemorySize; + } + @Override public String getZoneUuid() { return zoneUuid; @@ -148,6 +157,11 @@ public void setMemorySize(Long memorySize) { this.memorySize = memorySize; } + @Override + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public List getL3NetworkUuids() { return l3NetworkUuids; } @@ -156,6 +170,15 @@ public void setL3NetworkUuids(List l3NetworkUuids) { this.l3NetworkUuids = l3NetworkUuids; } + @Override + public String getVmNicParams() { + return vmNicParams; + } + + public void setVmNicParams(String vmNicParams) { + this.vmNicParams = vmNicParams; + } + public String getType() { return type; } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsgDoc_zh_cn.groovy index 16c8385921c..04ecc5e3abc 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.10.0" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "instanceOfferingUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "cpuNum" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "3.10.0" - } column { name "memorySize" @@ -69,7 +65,6 @@ doc { type "Long" optional true since "3.10.0" - } column { name "l3NetworkUuids" @@ -77,9 +72,17 @@ doc { desc "三层网络UUID" location "body" type "List" - optional false + optional true since "3.10.0" - + } + column { + name "vmNicParams" + enclosedIn "params" + desc "网卡信息" + location "body" + type "String" + optional true + since "4.7.0" } column { name "type" @@ -99,7 +102,6 @@ doc { type "String" optional false since "3.10.0" - } column { name "platform" @@ -119,7 +121,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "clusterUuid" @@ -129,7 +130,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "hostUuid" @@ -139,7 +139,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "primaryStorageUuid" @@ -149,7 +148,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "defaultL3NetworkUuid" @@ -159,7 +157,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "strategy" @@ -179,7 +176,6 @@ doc { type "String" optional true since "3.10.0" - } column { name "tagUuids" @@ -189,7 +185,6 @@ doc { type "List" optional true since "3.10.0" - } column { name "systemTags" @@ -199,7 +194,6 @@ doc { type "List" optional true since "3.10.0" - } column { name "userTags" @@ -209,7 +203,15 @@ doc { type "List" optional true since "3.10.0" - + } + column { + name "reservedMemorySize" + enclosedIn "params" + desc "" + location "body" + type "Long" + optional true + since "4.7.21" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsg.java b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsg.java index 4f3399f72a8..6c0155ca41b 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsg.java @@ -17,6 +17,7 @@ import org.zstack.header.tag.TagResourceType; import org.zstack.header.zone.ZoneVO; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -54,10 +55,13 @@ public class APICreateVmInstanceFromVolumeSnapshotGroupMsg extends APICreateMess @APIParam(required = false) private Long memorySize; + @APIParam(required = false, numberRange = {0, Long.MAX_VALUE}) + private Long reservedMemorySize; + /** * @desc a list of L3Network uuid the vm will create nic on. See :ref:`L3NetworkInventory` */ - @APIParam(resourceType = L3NetworkVO.class, nonempty = true, checkAccount = true) + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, required = false) private List l3NetworkUuids; /** * @desc see type of :ref:`VmInstanceInventory` @@ -142,6 +146,11 @@ public Long getMemorySize() { return memorySize; } + @Override + public Long getReservedMemorySize() { + return reservedMemorySize; + } + @Override public String getZoneUuid() { return zoneUuid; @@ -151,6 +160,11 @@ public void setMemorySize(Long memorySize) { this.memorySize = memorySize; } + @Override + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public List getL3NetworkUuids() { return l3NetworkUuids; } @@ -159,6 +173,11 @@ public void setL3NetworkUuids(List l3NetworkUuids) { this.l3NetworkUuids = l3NetworkUuids; } + @Override + public String getVmNicParams() { + return null; + } + public String getType() { return type; } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsgDoc_zh_cn.groovy index 27f7e2b0254..b47385fc846 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "instanceOfferingUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "cpuNum" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "4.1.0" - } column { name "memorySize" @@ -69,7 +65,6 @@ doc { type "Long" optional true since "4.1.0" - } column { name "l3NetworkUuids" @@ -77,9 +72,8 @@ doc { desc "三层网络UUID" location "body" type "List" - optional false + optional true since "4.1.0" - } column { name "type" @@ -99,7 +93,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "zoneUuid" @@ -109,7 +102,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "clusterUuid" @@ -119,7 +111,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "hostUuid" @@ -129,7 +120,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "primaryStorageUuidForRootVolume" @@ -139,7 +129,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "defaultL3NetworkUuid" @@ -149,7 +138,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "strategy" @@ -169,7 +157,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "tagUuids" @@ -179,7 +166,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "systemTags" @@ -189,7 +175,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -199,7 +184,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "rootVolumeSystemTags" @@ -209,7 +193,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "dataVolumeSystemTags" @@ -219,7 +202,15 @@ doc { type "Map" optional true since "4.1.0" - + } + column { + name "reservedMemorySize" + enclosedIn "params" + desc "" + location "body" + type "Long" + optional true + since "4.7.21" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsg.java index 79e28701d60..c0638aa3ab5 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsg.java @@ -51,11 +51,18 @@ public class APICreateVmInstanceFromVolumeSnapshotMsg extends APICreateMessage i @APIParam(required = false) private Long memorySize; + @APIParam(required = false, numberRange = {0, Long.MAX_VALUE}) + private Long reservedMemorySize; + /** * @desc a list of L3Network uuid the vm will create nic on. See :ref:`L3NetworkInventory` */ - @APIParam(resourceType = L3NetworkVO.class, nonempty = true, checkAccount = true) + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, required = false) private List l3NetworkUuids; + + @APIParam(required = false) + private String vmNicParams; + /** * @desc see type of :ref:`VmInstanceInventory` * @choices - UserVm @@ -139,6 +146,11 @@ public Long getMemorySize() { return memorySize; } + @Override + public Long getReservedMemorySize() { + return reservedMemorySize; + } + @Override public String getZoneUuid() { return zoneUuid; @@ -148,6 +160,11 @@ public void setMemorySize(Long memorySize) { this.memorySize = memorySize; } + @Override + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public List getL3NetworkUuids() { return l3NetworkUuids; } @@ -156,6 +173,15 @@ public void setL3NetworkUuids(List l3NetworkUuids) { this.l3NetworkUuids = l3NetworkUuids; } + @Override + public String getVmNicParams() { + return vmNicParams; + } + + public void setVmNicParams(String vmNicParams) { + this.vmNicParams = vmNicParams; + } + public String getType() { return type; } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsgDoc_zh_cn.groovy index f165c63ced5..83209081335 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceFromVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "instanceOfferingUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "cpuNum" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "4.1.0" - } column { name "memorySize" @@ -69,7 +65,6 @@ doc { type "Long" optional true since "4.1.0" - } column { name "l3NetworkUuids" @@ -77,9 +72,17 @@ doc { desc "三层网络UUID" location "body" type "List" - optional false + optional true since "4.1.0" - + } + column { + name "vmNicParams" + enclosedIn "params" + desc "网卡信息" + location "body" + type "String" + optional true + since "4.7.0" } column { name "type" @@ -99,7 +102,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "platform" @@ -119,7 +121,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "clusterUuid" @@ -129,7 +130,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "hostUuid" @@ -139,7 +139,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "primaryStorageUuid" @@ -149,7 +148,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "defaultL3NetworkUuid" @@ -159,7 +157,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "strategy" @@ -179,7 +176,6 @@ doc { type "String" optional true since "4.1.0" - } column { name "tagUuids" @@ -189,7 +185,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "systemTags" @@ -199,7 +194,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -209,7 +203,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "rootVolumeSystemTags" @@ -219,7 +212,15 @@ doc { type "List" optional true since "4.1.0" - + } + column { + name "reservedMemorySize" + enclosedIn "params" + desc "" + location "body" + type "Long" + optional true + since "4.7.21" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsg.java index 115afa91950..d6c0a4fd7a7 100755 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsg.java @@ -4,19 +4,23 @@ import org.zstack.header.cluster.ClusterVO; import org.zstack.header.configuration.DiskOfferingVO; import org.zstack.header.configuration.InstanceOfferingVO; +import org.zstack.header.configuration.PythonClassInventory; import org.zstack.header.host.HostVO; import org.zstack.header.identity.Action; import org.zstack.header.image.ImageVO; import org.zstack.header.message.*; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.header.tag.TagResourceType; +import org.zstack.header.volume.VolumeInventory; import org.zstack.header.zone.ZoneVO; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import static java.util.Arrays.asList; @@ -96,16 +100,22 @@ public class APICreateVmInstanceMsg extends APICreateMessage implements APIAudit @APIParam(required = false) private Long memorySize; + @APIParam(required = false, numberRange = {0, Long.MAX_VALUE}) + private Long reservedMemorySize; + /** * @desc uuid of image. See :ref:`ImageInventory` */ - @APIParam(resourceType = ImageVO.class, checkAccount = true) + @APIParam(resourceType = ImageVO.class, checkAccount = true, required = false, emptyString = false) private String imageUuid; /** * @desc a list of L3Network uuid the vm will create nic on. See :ref:`L3NetworkInventory` */ - @APIParam(resourceType = L3NetworkVO.class, nonempty = true, checkAccount = true) + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, required = false) private List l3NetworkUuids; + + @APIParam(required = false) + private String vmNicParams; /** * @desc see type of :ref:`VmInstanceInventory` * @choices - UserVm @@ -124,6 +134,9 @@ public class APICreateVmInstanceMsg extends APICreateMessage implements APIAudit @APIParam(required = false) private Long rootDiskSize; + @APIParam(required = false) + private List dataDiskSizes; + /** * @desc disk offering uuid for data volumes. See :ref:`DiskOfferingInventory` */ @@ -178,6 +191,147 @@ public class APICreateVmInstanceMsg extends APICreateMessage implements APIAudit @APIParam(required = false) private List dataVolumeSystemTags; + @APIParam(required = false) + private Map> dataVolumeSystemTagsOnIndex; + + @APIParam(required = false) + private List sshKeyPairUuids; + + @APIParam(required = false, validValues = {"Linux", "Windows", "Other", "Paravirtualization", "WindowsVirtio"}) + private String platform; + + @APIParam(required = false, maxLength = 255) + private String guestOsType; + + @APIParam(required = false, maxLength = 32, validValues = {"x86_64", "aarch64", "mips64el", "loongarch64"}) + private String architecture; + + @APIParam(required = false) + private Boolean virtio; + + @PythonClassInventory + public static class DiskAO { + private boolean boot; + private String platform; + private String guestOsType; + private String architecture; + private String primaryStorageUuid; + private long size; + private String templateUuid; + private String diskOfferingUuid; + private String sourceType; + private String sourceUuid; + private List systemTags; + private String name; + + public boolean isBoot() { + return boot; + } + + public void setBoot(boolean boot) { + this.boot = boot; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getGuestOsType() { + return guestOsType; + } + + public void setGuestOsType(String guestOsType) { + this.guestOsType = guestOsType; + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getTemplateUuid() { + return templateUuid; + } + + public void setTemplateUuid(String templateUuid) { + this.templateUuid = templateUuid; + } + + public String getDiskOfferingUuid() { + return diskOfferingUuid; + } + + public void setDiskOfferingUuid(String diskOfferingUuid) { + this.diskOfferingUuid = diskOfferingUuid; + } + + public String getSourceType() { + return sourceType; + } + + public void setSourceType(String sourceType) { + this.sourceType = sourceType; + } + + public String getSourceUuid() { + return sourceUuid; + } + + public void setSourceUuid(String sourceUuid) { + this.sourceUuid = sourceUuid; + } + + public List getSystemTags() { + return systemTags; + } + + public void setSystemTags(List systemTags) { + this.systemTags = systemTags; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + @APIParam(required = false) + private List diskAOs; + + public List getDiskAOs() { + return diskAOs; + } + + public void setDiskAOs(List diskAOs) { + this.diskAOs = diskAOs; + } + public String getStrategy() { return strategy; } @@ -226,6 +380,14 @@ public void setMemorySize(Long memorySize) { this.memorySize = memorySize; } + public Long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public String getImageUuid() { return imageUuid; } @@ -282,6 +444,15 @@ public void setL3NetworkUuids(List l3NetworkUuids) { this.l3NetworkUuids = l3NetworkUuids; } + @Override + public String getVmNicParams() { + return vmNicParams; + } + + public void setVmNicParams(String vmNicParams) { + this.vmNicParams = vmNicParams; + } + public List getDataDiskOfferingUuids() { return dataDiskOfferingUuids; } @@ -306,6 +477,14 @@ public void setRootDiskSize(Long rootDiskSize) { this.rootDiskSize = rootDiskSize; } + public List getDataDiskSizes() { + return dataDiskSizes; + } + + public void setDataDiskSizes(List dataDiskSizes) { + this.dataDiskSizes = dataDiskSizes; + } + public String getPrimaryStorageUuidForRootVolume() { return primaryStorageUuidForRootVolume; } @@ -330,6 +509,58 @@ public void setDataVolumeSystemTags(List dataVolumeSystemTags) { this.dataVolumeSystemTags = dataVolumeSystemTags; } + public Map> getDataVolumeSystemTagsOnIndex() { + return dataVolumeSystemTagsOnIndex; + } + + public void setDataVolumeSystemTagsOnIndex(Map> dataVolumeSystemTagsOnIndex) { + this.dataVolumeSystemTagsOnIndex = dataVolumeSystemTagsOnIndex; + } + + public List getSshKeyPairUuids() { + return sshKeyPairUuids; + } + + public void setSshKeyPairUuids(List sshKeyPairUuids) { + this.sshKeyPairUuids = sshKeyPairUuids; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getGuestOsType() { + return guestOsType; + } + + public void setGuestOsType(String guestOsType) { + this.guestOsType = guestOsType; + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public boolean isVirtio() { + return virtio; + } + + public Boolean getVirtio() { + return virtio; + } + + public void setVirtio(boolean virtio) { + this.virtio = virtio; + } + public static APICreateVmInstanceMsg __example__() { APICreateVmInstanceMsg msg = new APICreateVmInstanceMsg(); msg.setName("vm1"); @@ -348,4 +579,5 @@ public static APICreateVmInstanceMsg __example__() { public Result audit(APIMessage msg, APIEvent rsp) { return new Result(rsp.isSuccess() ? ((APICreateVmInstanceEvent)rsp).getInventory().getUuid() : "", VmInstanceVO.class); } + } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsgDoc_zh_cn.groovy index 9859de47c47..2242d207b84 100755 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "instanceOfferingUuid" @@ -37,9 +36,8 @@ doc { desc "计算规格UUID。指定云主机的CPU、内存等参数。" location "body" type "String" - optional false + optional true since "0.6" - } column { name "imageUuid" @@ -47,9 +45,8 @@ doc { desc "镜像UUID。云主机的根云盘会从该字段指定的镜像创建。" location "body" type "String" - optional false + optional true since "0.6" - } column { name "l3NetworkUuids" @@ -57,9 +54,17 @@ doc { desc "三层网络UUID列表。可以指定一个或多个三层网络,云主机会在每个网络上创建一个网卡。" location "body" type "List" - optional false + optional true since "0.6" - + } + column { + name "vmNicParams" + enclosedIn "params" + desc "网卡信息" + location "body" + type "String" + optional true + since "4.7.0" } column { name "type" @@ -79,7 +84,15 @@ doc { type "String" optional true since "0.6" - + } + column { + name "dataDiskSizes" + enclosedIn "params" + desc "自定义云盘大小列表。可以指定一个或多个云盘大小(可重复)为云主机创建一个或多个数据云盘。" + location "body" + type "List" + optional true + since "4.4.6" } column { name "dataDiskOfferingUuids" @@ -89,7 +102,6 @@ doc { type "List" optional true since "0.6" - } column { name "zoneUuid" @@ -99,7 +111,6 @@ doc { type "String" optional true since "0.6" - } column { name "clusterUuid" @@ -109,7 +120,6 @@ doc { type "String" optional true since "0.6" - } column { name "hostUuid" @@ -119,7 +129,6 @@ doc { type "String" optional true since "0.6" - } column { name "primaryStorageUuidForRootVolume" @@ -129,7 +138,6 @@ doc { type "String" optional true since "1.8" - } column { name "description" @@ -139,7 +147,6 @@ doc { type "String" optional true since "0.6" - } column { name "defaultL3NetworkUuid" @@ -149,7 +156,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -159,7 +165,6 @@ doc { type "String" optional true since "0.6" - } column { name "tagUuids" @@ -169,7 +174,6 @@ doc { type "List" optional true since "3.4" - } column { name "systemTags" @@ -179,7 +183,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -189,7 +192,6 @@ doc { type "List" optional true since "0.6" - } column { name "strategy" @@ -209,7 +211,6 @@ doc { type "List" optional true since "3.0" - } column { name "dataVolumeSystemTags" @@ -219,7 +220,114 @@ doc { type "List" optional true since "3.0" - + } + column { + name "cpuNum" + enclosedIn "params" + desc "" + location "body" + type "Integer" + optional true + since "3.4.0" + } + column { + name "memorySize" + enclosedIn "params" + desc "" + location "body" + type "Long" + optional true + since "3.4.0" + } + column { + name "rootDiskSize" + enclosedIn "params" + desc "" + location "body" + type "Long" + optional true + since "3.4.0" + } + column { + name "dataVolumeSystemTagsOnIndex" + enclosedIn "params" + desc "" + location "body" + type "Map" + optional true + since "4.4.24" + } + column { + name "sshKeyPairUuids" + enclosedIn "params" + desc "" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "dataVolumeTemplateUuids" + enclosedIn "params" + desc "" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "diskAOs" + enclosedIn "params" + desc "boot=true表示diskAO用于设置云主机平台、架构、操作系统与根盘总线;diskAO.boot=false表示加载的硬盘" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "platform" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.7.0" + } + column { + name "guestOsType" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.7.0" + } + column { + name "architecture" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "reservedMemorySize" + enclosedIn "params" + desc "" + location "body" + type "Long" + optional true + since "4.7.21" + } + column { + name "virtio" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.7.0" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APICreateVmNicMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APICreateVmNicMsgDoc_zh_cn.groovy index 0c71a0c4438..f465049ec7f 100644 --- a/header/src/main/java/org/zstack/header/vm/APICreateVmNicMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APICreateVmNicMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "ip" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.0" - } column { name "resourceUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "4.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -69,7 +65,15 @@ doc { type "List" optional true since "4.0" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDeleteVmBootModeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDeleteVmBootModeMsgDoc_zh_cn.groovy index 8c803d0ba65..3efde4f87f2 100644 --- a/header/src/main/java/org/zstack/header/vm/APIDeleteVmBootModeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDeleteVmBootModeMsgDoc_zh_cn.groovy @@ -13,8 +13,7 @@ doc { request { url "DELETE /v1/vm-instances/{uuid}/bootmode" - - header(Authorization: 'OAuth the-session-uuid') + header (Authorization: 'OAuth the-session-uuid') clz APIDeleteVmBootModeMsg.class @@ -30,17 +29,15 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" enclosedIn "" desc "" - location "url" + location "body" type "String" optional true since "0.6" - } column { name "systemTags" @@ -50,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -60,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDeleteVmConsolePasswordMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDeleteVmConsolePasswordMsgDoc_zh_cn.groovy index a562946442e..2c88cd0d944 100755 --- a/header/src/main/java/org/zstack/header/vm/APIDeleteVmConsolePasswordMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDeleteVmConsolePasswordMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDeleteVmHostnameMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDeleteVmHostnameMsgDoc_zh_cn.groovy index fa1cbaa3bec..1d4a0705096 100755 --- a/header/src/main/java/org/zstack/header/vm/APIDeleteVmHostnameMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDeleteVmHostnameMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "deleteMode" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDeleteVmNicMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDeleteVmNicMsgDoc_zh_cn.groovy index dac4c8ce15a..230347faa4a 100644 --- a/header/src/main/java/org/zstack/header/vm/APIDeleteVmNicMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDeleteVmNicMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDeleteVmSshKeyMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDeleteVmSshKeyMsgDoc_zh_cn.groovy index 729b7b77c01..e8843a77c83 100755 --- a/header/src/main/java/org/zstack/header/vm/APIDeleteVmSshKeyMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDeleteVmSshKeyMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDeleteVmStaticIpMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDeleteVmStaticIpMsgDoc_zh_cn.groovy index 93135cda608..70055fb3db3 100644 --- a/header/src/main/java/org/zstack/header/vm/APIDeleteVmStaticIpMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDeleteVmStaticIpMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "deleteMode" @@ -69,7 +65,15 @@ doc { type "String" optional true since "0.6" - + } + column { + name "staticIp" + enclosedIn "" + desc "" + location "body" + type "String" + optional true + since "3.10.0" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDestroyVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDestroyVmInstanceMsgDoc_zh_cn.groovy index b7b3ce92300..403807586af 100755 --- a/header/src/main/java/org/zstack/header/vm/APIDestroyVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDestroyVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "deleteMode" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDetachIsoFromVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDetachIsoFromVmInstanceMsgDoc_zh_cn.groovy index eb68ef780fc..a81e0b0b4f4 100755 --- a/header/src/main/java/org/zstack/header/vm/APIDetachIsoFromVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDetachIsoFromVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "isoUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "2.3.1" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIDetachL3NetworkFromVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIDetachL3NetworkFromVmMsgDoc_zh_cn.groovy index 186c5acd3fa..063ab04603d 100644 --- a/header/src/main/java/org/zstack/header/vm/APIDetachL3NetworkFromVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIDetachL3NetworkFromVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIExpungeVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIExpungeVmInstanceMsgDoc_zh_cn.groovy index edec56fd4ee..7ffbbc5c72d 100755 --- a/header/src/main/java/org/zstack/header/vm/APIExpungeVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIExpungeVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceEvent.java b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceEvent.java new file mode 100644 index 00000000000..dc2b5d3d614 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceEvent.java @@ -0,0 +1,101 @@ +package org.zstack.header.vm; + +import org.zstack.header.allocator.HostAllocatorConstant; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeState; +import org.zstack.header.volume.VolumeStatus; +import org.zstack.header.volume.VolumeType; +import org.zstack.utils.data.SizeUnit; + +import java.sql.Timestamp; + +import static java.util.Arrays.asList; + +@RestResponse(allTo = "inventory") +public class APIFlattenVmInstanceEvent extends APIEvent { + private VmInstanceInventory inventory; + + public void setInventory(VmInstanceInventory inventory) { + this.inventory = inventory; + } + + public VmInstanceInventory getInventory() { + return inventory; + } + + public APIFlattenVmInstanceEvent(String apiId) { + super(apiId); + } + + public APIFlattenVmInstanceEvent() { + super(); + } + + public static APIFlattenVmInstanceEvent __example__() { + APIFlattenVmInstanceEvent evt = new APIFlattenVmInstanceEvent(uuid()); + + String defaultL3Uuid = uuid(); + String rootVolumeUuid = uuid(); + + VmInstanceInventory vm = new VmInstanceInventory(); + vm.setName("Test-VM"); + vm.setUuid(uuid()); + vm.setAllocatorStrategy(HostAllocatorConstant.LAST_HOST_PREFERRED_ALLOCATOR_STRATEGY_TYPE); + vm.setClusterUuid(uuid()); + vm.setCpuNum(1); + vm.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vm.setDefaultL3NetworkUuid(defaultL3Uuid); + vm.setDescription("web server VM"); + vm.setHostUuid(uuid()); + vm.setHypervisorType("KVM"); + vm.setImageUuid(uuid()); + vm.setInstanceOfferingUuid(uuid()); + vm.setLastHostUuid(uuid()); + vm.setMemorySize(SizeUnit.GIGABYTE.toByte(8)); + vm.setPlatform("Linux"); + vm.setRootVolumeUuid(rootVolumeUuid); + vm.setState(VmInstanceState.Running.toString()); + vm.setType(VmInstanceConstant.USER_VM_TYPE); + vm.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vm.setZoneUuid(uuid()); + + VolumeInventory vol = new VolumeInventory(); + vol.setName(String.format("Root-Volume-For-VM-%s", vm.getUuid())); + vol.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setType(VolumeType.Root.toString()); + vol.setUuid(rootVolumeUuid); + vol.setSize(SizeUnit.GIGABYTE.toByte(100)); + vol.setActualSize(SizeUnit.GIGABYTE.toByte(20)); + vol.setDeviceId(0); + vol.setState(VolumeState.Enabled.toString()); + vol.setFormat("qcow2"); + vol.setDiskOfferingUuid(uuid()); + vol.setInstallPath(String.format("/zstack_ps/rootVolumes/acct-36c27e8ff05c4780bf6d2fa65700f22e/vol-%s/%s.qcow2", rootVolumeUuid, rootVolumeUuid)); + vol.setStatus(VolumeStatus.Ready.toString()); + vol.setPrimaryStorageUuid(uuid()); + vol.setVmInstanceUuid(vm.getUuid()); + vol.setRootImageUuid(vm.getImageUuid()); + vm.setAllVolumes(asList(vol)); + + VmNicInventory nic = new VmNicInventory(); + nic.setVmInstanceUuid(vm.getUuid()); + nic.setCreateDate(vm.getCreateDate()); + nic.setLastOpDate(vm.getLastOpDate()); + nic.setDeviceId(0); + nic.setGateway("192.168.1.1"); + nic.setIp("192.168.1.10"); + nic.setL3NetworkUuid(defaultL3Uuid); + nic.setNetmask("255.255.255.0"); + nic.setMac("00:0c:29:bd:99:fc"); + nic.setHypervisorType("KVM"); + nic.setUsedIpUuid(uuid()); + nic.setUuid(uuid()); + vm.setVmNics(asList(nic)); + + evt.setInventory(vm); + return evt; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..9e61ea15f90 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.VmInstanceInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "扁平合并云主机结果" + + ref { + name "inventory" + path "org.zstack.header.vm.APIFlattenVmInstanceEvent.inventory" + desc "null" + type "VmInstanceInventory" + since "4.7.0" + clz VmInstanceInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.vm.APIFlattenVmInstanceEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceMsg.java new file mode 100644 index 00000000000..dade965a8a6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceMsg.java @@ -0,0 +1,78 @@ +package org.zstack.header.vm; + + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +import java.util.concurrent.TimeUnit; + +@Action(category = VmInstanceConstant.ACTION_CATEGORY) +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 36) +@RestRequest(path = "/vm-instances/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIFlattenVmInstanceEvent.class, + isAction = true +) +public class APIFlattenVmInstanceMsg extends APIMessage implements VmInstanceMessage, APIAuditor { + @APIParam(resourceType = VmInstanceVO.class, checkAccount = true, operationTarget = true) + private String uuid; + + @APIParam(required = false) + private boolean full = true; + + @APIParam(required = false) + private boolean dryRun; + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setFull(boolean full) { + this.full = full; + } + + public boolean isFull() { + return full; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public boolean isDryRun() { + return dryRun; + } + + @Override + public String getVmInstanceUuid() { + return uuid; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + APIFlattenVmInstanceMsg amsg = (APIFlattenVmInstanceMsg) msg; + if (amsg.isDryRun()) { + return null; + } + + return new Result(amsg.getUuid(), VmInstanceVO.class); + } + + public static APIFlattenVmInstanceMsg __example__() { + APIFlattenVmInstanceMsg msg = new APIFlattenVmInstanceMsg(); + msg.setUuid(uuid()); + msg.setFull(true); + msg.setDryRun(false); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..15bd53540ea --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFlattenVmInstanceMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APIFlattenVmInstanceEvent + +doc { + title "FlattenVmInstance" + + category "vmInstance" + + desc """扁平合并云主机""" + + rest { + request { + url "PUT /v1/vm-instances/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIFlattenVmInstanceMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "flattenVmInstance" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "full" + enclosedIn "flattenVmInstance" + desc "扁平合并云主机上所有云盘" + location "body" + type "boolean" + optional true + since "4.7.0" + } + column { + name "dryRun" + enclosedIn "flattenVmInstance" + desc "试运行,可用于预测数据用量" + location "body" + type "boolean" + optional true + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIFlattenVmInstanceEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIFstrimVmEvent.java b/header/src/main/java/org/zstack/header/vm/APIFstrimVmEvent.java new file mode 100644 index 00000000000..dac48a06603 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFstrimVmEvent.java @@ -0,0 +1,18 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse() +public class APIFstrimVmEvent extends APIEvent { + public APIFstrimVmEvent() { + } + + public APIFstrimVmEvent(String apiId) { + super(apiId); + } + + public static APIFstrimVmEvent __example__() { + return new APIFstrimVmEvent(); + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIFstrimVmEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIFstrimVmEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..1e328fc984c --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFstrimVmEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.vm + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "回收云主机磁盘空间返回" + + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.vm.APIVmFstrimEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIFstrimVmMsg.java b/header/src/main/java/org/zstack/header/vm/APIFstrimVmMsg.java new file mode 100644 index 00000000000..3e6e9e50960 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFstrimVmMsg.java @@ -0,0 +1,50 @@ +package org.zstack.header.vm; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.APINoSee; +import org.zstack.header.rest.RestRequest; + +@Action(category = VmInstanceConstant.ACTION_CATEGORY) +@RestRequest( + path = "/vm-instances/{uuid}/actions", + responseClass = APIFstrimVmEvent.class, + method = HttpMethod.POST, + parameterName = "params" +) +public class APIFstrimVmMsg extends APIMessage implements VmInstanceMessage { + @APIParam(resourceType = VmInstanceVO.class) + private String uuid; + + @APINoSee + private String hostUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + @Override + public String getVmInstanceUuid() { + return uuid; + } + + public static APIFstrimVmMsg __example__() { + APIFstrimVmMsg msg = new APIFstrimVmMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIFstrimVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIFstrimVmMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..4e63bf7da06 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIFstrimVmMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APIFstrimVmEvent + +doc { + title "FstrimVm" + + category "vmInstance" + + desc """回收云主机磁盘空间""" + + rest { + request { + url "POST /v1/vm-instances/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIFstrimVmMsg.class + + desc """回收云主机磁盘空间""" + + params { + + column { + name "uuid" + enclosedIn "params" + desc "云主机UUID" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIFstrimVmEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetCandidateIsoForAttachingVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetCandidateIsoForAttachingVmMsgDoc_zh_cn.groovy index c3c539c64c4..b01ba6c7da9 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetCandidateIsoForAttachingVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetCandidateIsoForAttachingVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetCandidateL3NetworksForChangeVmNicNetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetCandidateL3NetworksForChangeVmNicNetworkMsgDoc_zh_cn.groovy index e0185db9497..11c4d352109 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetCandidateL3NetworksForChangeVmNicNetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetCandidateL3NetworksForChangeVmNicNetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.1.0" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsg.java b/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsg.java index 45168b08aaf..3ea3c9375c0 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsg.java @@ -2,13 +2,13 @@ import org.springframework.http.HttpMethod; import org.zstack.header.configuration.DiskOfferingVO; +import org.zstack.header.configuration.InstanceOfferingVO; import org.zstack.header.identity.Action; import org.zstack.header.image.ImageVO; import org.zstack.header.message.APIParam; import org.zstack.header.message.APISyncCallMessage; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.rest.RestRequest; -import org.zstack.header.storage.backup.BackupStorageVO; import java.util.List; @@ -41,6 +41,17 @@ public class APIGetCandidatePrimaryStoragesForCreatingVmMsg extends APISyncCallM private String clusterUuid; private String defaultL3NetworkUuid; + @APIParam(required = false, resourceType = InstanceOfferingVO.class, checkAccount = true) + private String instanceOfferingUuid; + + public String getInstanceOfferingUuid() { + return instanceOfferingUuid; + } + + public void setInstanceOfferingUuid(String instanceOfferingUuid) { + this.instanceOfferingUuid = instanceOfferingUuid; + } + public List getDataDiskSizes() { return dataDiskSizes; } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsgDoc_zh_cn.groovy index b16d18b89a2..d0b146235af 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetCandidatePrimaryStoragesForCreatingVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.1" - } column { name "l3NetworkUuids" @@ -39,7 +38,6 @@ doc { type "List" optional false since "2.1" - } column { name "rootDiskOfferingUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "2.1" - } column { name "rootDiskSize" @@ -59,7 +56,6 @@ doc { type "Long" optional true since "4.1.2" - } column { name "dataDiskOfferingUuids" @@ -69,7 +65,6 @@ doc { type "List" optional true since "2.1" - } column { name "dataDiskSizes" @@ -79,7 +74,6 @@ doc { type "List" optional true since "4.3.9" - } column { name "zoneUuid" @@ -89,7 +83,6 @@ doc { type "String" optional true since "2.1" - } column { name "clusterUuid" @@ -99,7 +92,6 @@ doc { type "String" optional true since "2.1" - } column { name "defaultL3NetworkUuid" @@ -109,7 +101,6 @@ doc { type "String" optional true since "2.1" - } column { name "systemTags" @@ -119,7 +110,6 @@ doc { type "List" optional true since "2.1" - } column { name "userTags" @@ -129,7 +119,15 @@ doc { type "List" optional true since "2.1" - + } + column { + name "instanceOfferingUuid" + enclosedIn "" + desc "计算规格UUID" + location "query" + type "String" + optional true + since "5.4.0" } } } @@ -138,4 +136,4 @@ doc { clz APIGetCandidatePrimaryStoragesForCreatingVmReply.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetCandidateVmForAttachingIsoMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetCandidateVmForAttachingIsoMsgDoc_zh_cn.groovy index c219a68a159..f093f62df68 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetCandidateVmForAttachingIsoMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetCandidateVmForAttachingIsoMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetCandidateZonesClustersHostsForCreatingVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetCandidateZonesClustersHostsForCreatingVmMsgDoc_zh_cn.groovy index 96729621820..afb478bf293 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetCandidateZonesClustersHostsForCreatingVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetCandidateZonesClustersHostsForCreatingVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "imageUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuids" @@ -49,7 +47,6 @@ doc { type "List" optional false since "0.6" - } column { name "rootDiskOfferingUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "dataDiskOfferingUuids" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "zoneUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "clusterUuid" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "defaultL3NetworkUuid" @@ -99,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "cpuNum" @@ -109,7 +101,6 @@ doc { type "Integer" optional true since "3.10.0" - } column { name "memorySize" @@ -119,7 +110,6 @@ doc { type "Long" optional true since "3.10.0" - } column { name "systemTags" @@ -129,7 +119,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -139,7 +128,6 @@ doc { type "List" optional true since "0.6" - } column { name "rootDiskSize" @@ -149,7 +137,6 @@ doc { type "Long" optional true since "4.1.2" - } } } @@ -158,4 +145,4 @@ doc { clz APIGetCandidateZonesClustersHostsForCreatingVmReply.class } } -} +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesMsg.java b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesMsg.java new file mode 100644 index 00000000000..6ba5674650d --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesMsg.java @@ -0,0 +1,61 @@ +package org.zstack.header.vm; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.backup.BackupStorageVO; +import org.zstack.header.zone.ZoneVO; + +import java.util.List; + +/** + * Created by Qi Le on 2022/3/9 + */ +@Action(category = VmInstanceConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/backupStorage-l3networks/dependencies", + method = HttpMethod.GET, + responseClass = APIGetInterdependentL3NetworksBackupStoragesReply.class +) +public class APIGetInterdependentL3NetworksBackupStoragesMsg extends APISyncCallMessage { + @APIParam(resourceType = ZoneVO.class) + private String zoneUuid; + @APIParam(resourceType = BackupStorageVO.class, required = false) + private String backupStorageUuid; + @APIParam(resourceType = L3NetworkVO.class, required = false, nonempty = true) + private List l3NetworkUuids; + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public List getL3NetworkUuids() { + return l3NetworkUuids; + } + + public void setL3NetworkUuids(List l3NetworkUuids) { + this.l3NetworkUuids = l3NetworkUuids; + } + + public static APIGetInterdependentL3NetworksBackupStoragesMsg __example__() { + APIGetInterdependentL3NetworksBackupStoragesMsg msg = new APIGetInterdependentL3NetworksBackupStoragesMsg(); + msg.setZoneUuid(uuid()); + msg.setBackupStorageUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..c74a33d83b9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APIGetInterdependentL3NetworksBackupStoragesReply + +doc { + title "GetInterdependentL3NetworksBackupStorages" + + category "vmInstance" + + desc """获取内部依赖的L3网络或者镜像服务器信息""" + + rest { + request { + url "GET /v1/backupStorage-l3networks/dependencies" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetInterdependentL3NetworksBackupStoragesMsg.class + + desc """""" + + params { + + column { + name "zoneUuid" + enclosedIn "" + desc "区域UUID" + location "query" + type "String" + optional false + since "0.6" + } + column { + name "backupStorageUuid" + enclosedIn "" + desc "镜像存储UUID" + location "query" + type "String" + optional true + since "0.6" + } + column { + name "l3NetworkUuids" + enclosedIn "" + desc "" + location "query" + type "List" + optional true + since "0.6" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APIGetInterdependentL3NetworksBackupStoragesReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesReply.java b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesReply.java new file mode 100644 index 00000000000..fd039791be9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesReply.java @@ -0,0 +1,87 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.APIReply; +import org.zstack.header.network.l3.IpRangeInventory; +import org.zstack.header.network.l3.L3NetworkConstant; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkState; +import org.zstack.header.network.service.NetworkServiceL3NetworkRefInventory; +import org.zstack.header.network.service.NetworkServiceType; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Created by Qi Le on 2022/3/9 + */ +@RestResponse(allTo = "inventories") +public class APIGetInterdependentL3NetworksBackupStoragesReply extends APIReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIGetInterdependentL3NetworksBackupStoragesReply __example__() { + APIGetInterdependentL3NetworksBackupStoragesReply reply = new APIGetInterdependentL3NetworksBackupStoragesReply(); + L3NetworkInventory l3 = new L3NetworkInventory(); + l3.setName("private L3"); + + Timestamp time = new Timestamp(org.zstack.header.message.DocUtils.date); + + String l3Uuid = uuid(); + l3.setUuid(l3Uuid); + l3.setType(L3NetworkConstant.L3_BASIC_NETWORK_TYPE); + l3.setState(L3NetworkState.Enabled.toString()); + l3.setL2NetworkUuid(uuid()); + l3.setZoneUuid(uuid()); + l3.setCreateDate(time); + l3.setLastOpDate(time); + + IpRangeInventory ipr = new IpRangeInventory(); + ipr.setName("ip range"); + ipr.setUuid(uuid()); + ipr.setL3NetworkUuid(l3Uuid); + ipr.setStartIp("192.168.0.10"); + ipr.setEndIp("192.168.0.100"); + ipr.setNetmask("255.255.255.0"); + ipr.setGateway("192.168.0.1"); + ipr.setCreateDate(time); + ipr.setLastOpDate(time); + l3.setIpRanges(Collections.singletonList(ipr)); + + List refs = new ArrayList<>(); + String puuid = uuid(); + + NetworkServiceL3NetworkRefInventory ref = new NetworkServiceL3NetworkRefInventory(); + ref.setL3NetworkUuid(l3Uuid); + ref.setNetworkServiceProviderUuid(puuid); + ref.setNetworkServiceType(NetworkServiceType.DHCP.toString()); + refs.add(ref); + + ref = new NetworkServiceL3NetworkRefInventory(); + ref.setL3NetworkUuid(l3Uuid); + ref.setNetworkServiceProviderUuid(puuid); + ref.setNetworkServiceType(NetworkServiceType.DNS.toString()); + refs.add(ref); + + ref = new NetworkServiceL3NetworkRefInventory(); + ref.setL3NetworkUuid(l3Uuid); + ref.setNetworkServiceProviderUuid(puuid); + ref.setNetworkServiceType(NetworkServiceType.SNAT.toString()); + refs.add(ref); + + l3.setNetworkServices(refs); + + reply.inventories = Collections.singletonList(l3); + + return reply; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..e92aa5bc0c2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksBackupStoragesReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.vm + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取内部依赖的L3网络或者镜像服务器信息" + + field { + name "inventories" + desc "" + type "List" + since "0.6" + } + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.header.vm.APIGetInterdependentL3NetworksBackupStoragesReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsg.java b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsg.java index cc2baa5b7cf..f4879f61e66 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsg.java @@ -11,8 +11,6 @@ import java.util.List; -import static java.util.Arrays.asList; - /** * Created by xing5 on 2016/8/23. */ @@ -29,6 +27,8 @@ public class APIGetInterdependentL3NetworksImagesMsg extends APISyncCallMessage private List l3NetworkUuids; @APIParam(required = false, resourceType = ImageVO.class) private String imageUuid; + @APIParam(required = false) + private boolean raiseException; public String getZoneUuid() { return zoneUuid; @@ -53,11 +53,21 @@ public String getImageUuid() { public void setImageUuid(String imageUuid) { this.imageUuid = imageUuid; } - + + public boolean getRaiseException() { + return raiseException; + } + + public void setRaiseException(boolean raiseException) { + this.raiseException = raiseException; + } + public static APIGetInterdependentL3NetworksImagesMsg __example__() { APIGetInterdependentL3NetworksImagesMsg msg = new APIGetInterdependentL3NetworksImagesMsg(); msg.zoneUuid = uuid(); msg.imageUuid = uuid(); + msg.raiseException = true; + return msg; } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsgDoc_zh_cn.groovy index 740851845a0..173e83955b3 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetInterdependentL3NetworksImagesMsgDoc_zh_cn.groovy @@ -34,7 +34,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuids" @@ -44,7 +43,6 @@ doc { type "List" optional true since "0.6" - } column { name "imageUuid" @@ -54,7 +52,15 @@ doc { type "String" optional true since "0.6" - + } + column { + name "raiseException" + enclosedIn "" + desc "是否引发异常" + location "query" + type "boolean" + optional true + since "4.6.11" } column { name "systemTags" @@ -64,7 +70,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -74,7 +79,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceMsg.java b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceMsg.java new file mode 100644 index 00000000000..2cbf1dfdbd3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceMsg.java @@ -0,0 +1,50 @@ +package org.zstack.header.vm; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; +import org.zstack.header.vo.ResourceVO; + +/** + * Created by LiangHanYu on 2022/7/5 17:44 + */ +@Action(category = VolumeSnapshotConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/memory-snapshots/group/reference", + method = HttpMethod.GET, + responseClass = APIGetMemorySnapshotGroupReferenceReply.class +) +public class APIGetMemorySnapshotGroupReferenceMsg extends APISyncCallMessage { + @APIParam(resourceType = ResourceVO.class) + private String resourceUuid; + + @APIParam + private String resourceType; + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public static APIGetMemorySnapshotGroupReferenceMsg __example__() { + APIGetMemorySnapshotGroupReferenceMsg msg = new APIGetMemorySnapshotGroupReferenceMsg(); + msg.setResourceUuid(uuid()); + msg.setResourceType(L3NetworkVO.class.getSimpleName()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..1ca829dac61 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APIGetMemorySnapshotGroupReferenceReply + +doc { + title "GetMemorySnapshotGroupReference" + + category "snapshot.volume" + + desc """获取资源被引用的内存快照组""" + + rest { + request { + url "GET /v1/memory-snapshots/group/reference" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetMemorySnapshotGroupReferenceMsg.class + + desc """""" + + params { + + column { + name "resourceUuid" + enclosedIn "" + desc "资源UUID" + location "query" + type "String" + optional false + since "4.4.24" + } + column { + name "resourceType" + enclosedIn "" + desc "资源类型" + location "query" + type "String" + optional false + since "4.4.24" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.4.24" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.4.24" + } + } + } + + response { + clz APIGetMemorySnapshotGroupReferenceReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceReply.java b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceReply.java new file mode 100644 index 00000000000..d30abe4aca4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceReply.java @@ -0,0 +1,72 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.header.storage.snapshot.group.APIQueryVolumeSnapshotGroupReply; +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupInventory; +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupRefInventory; +import org.zstack.header.volume.VolumeType; + +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; + +/** + * Created by LiangHanYu on 2022/7/5 17:45 + */ +@RestResponse(fieldsTo = {"all"}) +public class APIGetMemorySnapshotGroupReferenceReply extends APIReply { + private List inventories; + private String resourceUuid; + + public APIGetMemorySnapshotGroupReferenceReply(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public APIGetMemorySnapshotGroupReferenceReply() { + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIGetMemorySnapshotGroupReferenceReply __example__() { + APIGetMemorySnapshotGroupReferenceReply reply = new APIGetMemorySnapshotGroupReferenceReply(); + VolumeSnapshotGroupInventory inv = new VolumeSnapshotGroupInventory(); + inv.setName("group"); + inv.setSnapshotCount(1); + inv.setUuid(uuid()); + inv.setVmInstanceUuid(uuid()); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + VolumeSnapshotGroupRefInventory ref = new VolumeSnapshotGroupRefInventory(); + ref.setDeviceId(0); + ref.setSnapshotDeleted(false); + ref.setVolumeName("ROOT-volume"); + ref.setVolumeUuid(uuid()); + ref.setVolumeSnapshotInstallPath("/zstack_ps/to/path/snap.qcow2"); + ref.setVolumeSnapshotUuid(uuid()); + ref.setVolumeSnapshotName("group-ROOT-volume"); + ref.setVolumeSnapshotGroupUuid(inv.getUuid()); + ref.setVolumeType(VolumeType.Root.toString()); + ref.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + ref.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setVolumeSnapshotRefs(Collections.singletonList(ref)); + reply.setResourceUuid(uuid()); + reply.setInventories(Collections.singletonList(inv)); + return reply; + } + +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..7e4e530f2a9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetMemorySnapshotGroupReferenceReplyDoc_zh_cn.groovy @@ -0,0 +1,38 @@ +package org.zstack.header.vm + +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取资源引用快照组列表返回" + + ref { + name "inventories" + path "org.zstack.header.vm.APIGetMemorySnapshotGroupReferenceReply.inventories" + desc "被引用的内存快照组列表" + type "List" + since "4.4.24" + clz VolumeSnapshotGroupInventory.class + } + field { + name "resourceUuid" + desc "资源UUID" + type "String" + since "4.4.24" + } + field { + name "success" + desc "" + type "boolean" + since "4.4.24" + } + ref { + name "error" + path "org.zstack.header.vm.APIGetMemorySnapshotGroupReferenceReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.4.24" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetSpiceCertificatesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetSpiceCertificatesMsgDoc_zh_cn.groovy index 5d368d8d9c5..a4d89dc85c8 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetSpiceCertificatesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetSpiceCertificatesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "3.7" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.7" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableDataVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableDataVolumeMsgDoc_zh_cn.groovy index 5a219502002..bf5452358d8 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableDataVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableDataVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableL3NetworkMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableL3NetworkMsgDoc_zh_cn.groovy index e76ee931983..92275aeb418 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableL3NetworkMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmAttachableL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmBootOrderMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmBootOrderMsgDoc_zh_cn.groovy index d7365fe625b..149a5b2d3fe 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmBootOrderMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmBootOrderMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmCapabilitiesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmCapabilitiesMsgDoc_zh_cn.groovy index 3388868cc7d..393ae9d4b5d 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmCapabilitiesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmCapabilitiesMsgDoc_zh_cn.groovy @@ -35,7 +35,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -45,7 +44,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -55,7 +53,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressMsgDoc_zh_cn.groovy index 376d2a0d07a..43f82784432 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressMsgDoc_zh_cn.groovy @@ -32,7 +32,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -42,7 +41,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -52,7 +50,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressReply.java b/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressReply.java index d1644b3aa5c..07632177238 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressReply.java +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmConsoleAddressReply.java @@ -10,6 +10,7 @@ public class APIGetVmConsoleAddressReply extends APIReply { private String hostIp; private int port; + private String path; private String protocol; private VdiPortInfo vdiPortInfo; @@ -37,6 +38,14 @@ public void setProtocol(String protocol) { this.protocol = protocol; } + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + public VdiPortInfo getVdiPortInfo() { return vdiPortInfo; } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmConsolePasswordMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmConsolePasswordMsgDoc_zh_cn.groovy index 717a90aad16..6ce93c01bba 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmConsolePasswordMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmConsolePasswordMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmDeviceAddressMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmDeviceAddressMsgDoc_zh_cn.groovy index 881d1c52b5d..f9084f77f14 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmDeviceAddressMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmDeviceAddressMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.10.0" - } column { name "resourceTypes" @@ -49,7 +48,6 @@ doc { type "List" optional true since "3.10.0" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "3.10.0" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmHostnameMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmHostnameMsgDoc_zh_cn.groovy index bb3a6fda11b..d75897163d9 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmHostnameMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmHostnameMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmMigrationCandidateHostsMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmMigrationCandidateHostsMsgDoc_zh_cn.groovy index 395e88a737f..83384a50e87 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmMigrationCandidateHostsMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmMigrationCandidateHostsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmNicAttachedNetworkServiceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmNicAttachedNetworkServiceMsgDoc_zh_cn.groovy index 333991aee37..87796a155f2 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmNicAttachedNetworkServiceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmNicAttachedNetworkServiceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.1.0" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.1.0" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.1.0" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmSshKeyMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmSshKeyMsgDoc_zh_cn.groovy index 8fe91971a16..2b074d0a5ea 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmSshKeyMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmSshKeyMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmStartingCandidateClustersHostsMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmStartingCandidateClustersHostsMsgDoc_zh_cn.groovy index 5ef613a5d42..a55e91f2c4a 100755 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmStartingCandidateClustersHostsMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmStartingCandidateClustersHostsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmTaskMsg.java b/header/src/main/java/org/zstack/header/vm/APIGetVmTaskMsg.java new file mode 100644 index 00000000000..482871149fb --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmTaskMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.vm; + +import org.springframework.http.HttpMethod; +import org.zstack.header.core.APIGetChainTaskReply; +import org.zstack.header.identity.Action; +import org.zstack.header.core.APIGetChainTaskMsg; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +@Action(category = VmInstanceConstant.ACTION_CATEGORY, adminOnly = true) +@RestRequest( + path = "/vm-instances/task-details", + method = HttpMethod.GET, + responseClass = APIGetChainTaskReply.class +) +public class APIGetVmTaskMsg extends APIGetChainTaskMsg { + @APIParam(nonempty = true, resourceType = VmInstanceVO.class) + private List vmInstanceUuids; + + public void setVmInstanceUuids(List vmInstanceUuids) { + this.vmInstanceUuids = vmInstanceUuids; + } + + public List getVmInstanceUuids() { + return vmInstanceUuids; + } + + @Override + public List getSyncSignatures() { + List syncSignatures = new ArrayList<>(); + vmInstanceUuids.forEach(vmUuid -> syncSignatures.add((VmInstanceConstant.VM_SYNC_SIGNATURE_PREFIX + vmUuid))); + return syncSignatures; + } + + @Override + public Function getResourceUuidMaker() { + return s -> s.substring(s.lastIndexOf("-") + 1); + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmTaskMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmTaskMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..deab09d8f72 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmTaskMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.vm + +import org.zstack.header.core.APIGetChainTaskReply + +doc { + title "GetVmTask" + + category "vmInstance" + + desc """获取虚拟机上的任务信息""" + + rest { + request { + url "GET /v1/vm-instances/task-details" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetVmTaskMsg.class + + desc """""" + + params { + + column { + name "vmInstanceUuids" + enclosedIn "" + desc "" + location "query" + type "List" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.6.0" + } + column { + name "syncSignatures" + enclosedIn "" + desc "" + location "query" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIGetChainTaskReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesEvent.java b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesEvent.java deleted file mode 100644 index e288ab17eda..00000000000 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.zstack.header.vm; - -import com.google.common.collect.Maps; -import org.zstack.header.message.APIEvent; -import org.zstack.header.rest.RestResponse; - -import java.util.Map; - -/** - * @ Author : yh.w - * @ Date : Created in 10:29 2021/2/3 - */ -@RestResponse(allTo = "vmsCaps") -public class APIGetVmsCapabilitiesEvent extends APIEvent { - public APIGetVmsCapabilitiesEvent() { - } - - public APIGetVmsCapabilitiesEvent(String apiId) { - super(apiId); - } - - private Map vmsCaps; - - public Map getVmsCaps() { - return vmsCaps; - } - - public void setVmsCaps(Map vmsCaps) { - this.vmsCaps = vmsCaps; - } - - public static APIGetVmsCapabilitiesEvent __example__() { - APIGetVmsCapabilitiesEvent evt = new APIGetVmsCapabilitiesEvent(); - VmCapabilities vmCapabilities = new VmCapabilities(); - vmCapabilities.setSupportLiveMigration(true); - vmCapabilities.setSupportMemorySnapshot(false); - Map vmsCpas = Maps.newHashMap(); - vmsCpas.put(uuid(), vmCapabilities); - evt.setVmsCaps(vmsCpas); - return evt; - } -} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesEventDoc_zh_cn.groovy deleted file mode 100644 index 5791944af5b..00000000000 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesEventDoc_zh_cn.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package org.zstack.header.vm - -import org.zstack.header.errorcode.ErrorCode -import org.zstack.header.vm.VmCapabilities - -doc { - - title "批量获取云主机能力返回" - - field { - name "success" - desc "" - type "boolean" - since "0.6" - } - ref { - name "error" - path "org.zstack.header.vm.APIGetVmsCapabilitiesEvent.error" - desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false - type "ErrorCode" - since "4.0" - clz ErrorCode.class - } - ref { - name "vmsCaps" - path "org.zstack.header.vm.APIGetVmsCapabilitiesEvent.vmsCaps" - desc "null" - type "Map" - since "4.0" - clz VmCapabilities.class - } -} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsg.java b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsg.java index b8266c66e8e..417e69fc971 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsg.java @@ -1,8 +1,9 @@ package org.zstack.header.vm; import org.springframework.http.HttpMethod; -import org.zstack.header.message.APIMessage; +import org.zstack.header.identity.Action; import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; import org.zstack.header.rest.RestRequest; import java.util.Arrays; @@ -12,13 +13,13 @@ * @ Author : yh.w * @ Date : Created in 21:33 2021/2/2 */ +@Action(category = VmInstanceConstant.ACTION_CATEGORY, names = {"read"}) @RestRequest( path = "/vm-instances/capabilities", - method = HttpMethod.POST, - responseClass = APIGetVmsCapabilitiesEvent.class, - parameterName = "params" + responseClass = APIGetVmsCapabilitiesReply.class, + method = HttpMethod.GET ) -public class APIGetVmsCapabilitiesMsg extends APIMessage { +public class APIGetVmsCapabilitiesMsg extends APISyncCallMessage { @APIParam(nonempty = true) private List vmUuids; diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsgDoc_zh_cn.groovy index f7a0ed062a8..a0bb99e1a79 100644 --- a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesMsgDoc_zh_cn.groovy @@ -1,6 +1,6 @@ package org.zstack.header.vm -import org.zstack.header.vm.APIGetVmsCapabilitiesEvent +import org.zstack.header.vm.APIGetVmsCapabilitiesReply doc { title "GetVmsCapabilities" @@ -11,7 +11,7 @@ doc { rest { request { - url "POST /v1/vm-instances/capabilities" + url "GET /v1/vm-instances/capabilities" header (Authorization: 'OAuth the-session-uuid') @@ -23,39 +23,36 @@ doc { column { name "vmUuids" - enclosedIn "params" + enclosedIn "" desc "" - location "body" + location "query" type "List" optional false since "4.0" - } column { name "systemTags" enclosedIn "" desc "系统标签" - location "body" + location "query" type "List" optional true since "4.0" - } column { name "userTags" enclosedIn "" desc "用户标签" - location "body" + location "query" type "List" optional true since "4.0" - } } } response { - clz APIGetVmsCapabilitiesEvent.class + clz APIGetVmsCapabilitiesReply.class } } } \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesReply.java b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesReply.java new file mode 100644 index 00000000000..dc7c26d8f5f --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesReply.java @@ -0,0 +1,37 @@ +package org.zstack.header.vm; + +import com.google.common.collect.Maps; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 10:29 2021/2/3 + */ +@RestResponse(allTo = "vmsCaps") +public class APIGetVmsCapabilitiesReply extends APIReply { + + private Map vmsCaps; + + public Map getVmsCaps() { + return vmsCaps; + } + + public void setVmsCaps(Map vmsCaps) { + this.vmsCaps = vmsCaps; + } + + public static APIGetVmsCapabilitiesReply __example__() { + APIGetVmsCapabilitiesReply evt = new APIGetVmsCapabilitiesReply(); + VmCapabilities vmCapabilities = new VmCapabilities(); + vmCapabilities.setSupportLiveMigration(true); + vmCapabilities.setSupportMemorySnapshot(false); + Map vmsCpas = Maps.newHashMap(); + vmsCpas.put(uuid(), vmCapabilities); + evt.setVmsCaps(vmsCpas); + return evt; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..d587ccb72b5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APIGetVmsCapabilitiesReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.VmCapabilities +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "批量获取云主机能力返回" + + ref { + name "vmsCaps" + path "org.zstack.header.vm.APIGetVmsCapabilitiesReply.vmsCaps" + desc "null" + type "Map" + since "4.0" + clz VmCapabilities.class + } + field { + name "success" + desc "" + type "boolean" + since "4.0" + } + ref { + name "error" + path "org.zstack.header.vm.APIGetVmsCapabilitiesReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsg.java b/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsg.java index 567af1dd69e..763a5757476 100755 --- a/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsg.java @@ -46,7 +46,7 @@ ) @SkipVmTracer(replyClass = APIMigrateVmEvent.class) @DefaultTimeout(timeunit = TimeUnit.HOURS, value = 1) -public class APIMigrateVmMsg extends APIMessage implements VmInstanceMessage, MigrateVmMessage { +public class APIMigrateVmMsg extends APIMessage implements VmInstanceMessage, MigrateVmMessage, CheckAttachedVolumesMessage { /** * @desc vm uuid */ @@ -69,9 +69,12 @@ public class APIMigrateVmMsg extends APIMessage implements VmInstanceMessage, Mi @APIParam(required = false) private boolean allowUnknown; - @APIParam(required = false, validValues = {"auto-converge"}) + @APIParam(required = false, validValues = {"auto-converge", "no-converge"}) private String strategy; + @APIParam(required = false) + private Integer downTime; + public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; } @@ -122,12 +125,21 @@ public void setStrategy(String strategy) { public String getVmInstanceUuid() { return getVmUuid(); } - + + public Integer getDownTime() { + return downTime; + } + + public void setDownTime(Integer downTime) { + this.downTime = downTime; + } + public static APIMigrateVmMsg __example__() { APIMigrateVmMsg msg = new APIMigrateVmMsg(); msg.vmInstanceUuid = uuid(); msg.hostUuid = uuid(); msg.setMigrateFromDestination(false); + msg.setDownTime(300); return msg; } diff --git a/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsgDoc_zh_cn.groovy index 2e98d9b978c..6b948fc0699 100644 --- a/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIMigrateVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "hostUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "migrateFromDestination" @@ -49,7 +47,6 @@ doc { type "Boolean" optional true since "2.3" - } column { name "allowUnknown" @@ -59,7 +56,6 @@ doc { type "boolean" optional true since "3.6.0" - } column { name "strategy" @@ -69,7 +65,7 @@ doc { type "String" optional true since "3.6.0" - values ("auto-converge") + values ("auto-converge","no-converge") } column { name "systemTags" @@ -79,7 +75,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +84,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "downTime" + enclosedIn "migrateVm" + desc "热迁移物理机停机时间" + location "body" + type "Integer" + optional true + since "4.6.21" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIPauseVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIPauseVmInstanceMsgDoc_zh_cn.groovy index 786be8d4dec..b1668cdad1e 100755 --- a/header/src/main/java/org/zstack/header/vm/APIPauseVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIPauseVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIQueryVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIQueryVmInstanceMsgDoc_zh_cn.groovy index 187c6731cfa..178227d1c24 100644 --- a/header/src/main/java/org/zstack/header/vm/APIQueryVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIQueryVmInstanceMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.vm import org.zstack.header.vm.APIQueryVmInstanceReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询云主机(QueryVmInstance)" diff --git a/header/src/main/java/org/zstack/header/vm/APIQueryVmNicMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIQueryVmNicMsgDoc_zh_cn.groovy index 315abce4e4b..04b4e727a5e 100755 --- a/header/src/main/java/org/zstack/header/vm/APIQueryVmNicMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIQueryVmNicMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.vm import org.zstack.header.vm.APIQueryVmNicReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询云主机网卡(QueryVmNic)" diff --git a/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsg.java index e718ff741fa..2e2f2065782 100755 --- a/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsg.java @@ -40,7 +40,7 @@ responseClass = APIRebootVmInstanceEvent.class ) @SkipVmTracer(replyClass = APIRebootVmInstanceEvent.class) -public class APIRebootVmInstanceMsg extends APIMessage implements VmInstanceMessage { +public class APIRebootVmInstanceMsg extends APIMessage implements VmInstanceMessage, CheckAttachedVolumesMessage { /** * @desc vm uuid */ diff --git a/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsgDoc_zh_cn.groovy index 455b8e7c5f6..e5a332c02e2 100755 --- a/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIRebootVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIRecoverVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIRecoverVmInstanceMsgDoc_zh_cn.groovy index 87d06c29874..41e6a9705e2 100755 --- a/header/src/main/java/org/zstack/header/vm/APIRecoverVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIRecoverVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIReimageVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIReimageVmInstanceMsgDoc_zh_cn.groovy index cf20ec47874..31c856fef3a 100755 --- a/header/src/main/java/org/zstack/header/vm/APIReimageVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIReimageVmInstanceMsgDoc_zh_cn.groovy @@ -32,7 +32,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -42,7 +41,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -52,7 +50,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIResumeVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIResumeVmInstanceMsgDoc_zh_cn.groovy index b497ec09369..8c1577138ef 100755 --- a/header/src/main/java/org/zstack/header/vm/APIResumeVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIResumeVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmBootModeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmBootModeMsgDoc_zh_cn.groovy index c813effdac1..1b944ffc265 100644 --- a/header/src/main/java/org/zstack/header/vm/APISetVmBootModeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmBootModeMsgDoc_zh_cn.groovy @@ -13,8 +13,7 @@ doc { request { url "PUT /v1/vm-instances/{uuid}/actions" - - header(Authorization: 'OAuth the-session-uuid') + header (Authorization: 'OAuth the-session-uuid') clz APISetVmBootModeMsg.class @@ -30,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "bootMode" @@ -40,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -50,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -60,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmBootOrderMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmBootOrderMsgDoc_zh_cn.groovy index 54f8c1b10b9..7dbdd21cce2 100755 --- a/header/src/main/java/org/zstack/header/vm/APISetVmBootOrderMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmBootOrderMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "bootOrder" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmBootVolumeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmBootVolumeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..a56434af81e --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APISetVmBootVolumeEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.VmInstanceInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "设置云主机启动盘的结果" + + ref { + name "inventory" + path "org.zstack.header.vm.APISetVmBootVolumeEvent.inventory" + desc "null" + type "VmInstanceInventory" + since "4.2.0" + clz VmInstanceInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.2.0" + } + ref { + name "error" + path "org.zstack.header.vm.APISetVmBootVolumeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.2.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmBootVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmBootVolumeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..acff819a165 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APISetVmBootVolumeMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APISetVmBootVolumeEvent + +doc { + title "SetVmBootVolume" + + category "vmInstance" + + desc """设置云主机启动盘""" + + rest { + request { + url "PUT /v1/vm-instances/{vmInstanceUuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APISetVmBootVolumeMsg.class + + desc """""" + + params { + + column { + name "vmInstanceUuid" + enclosedIn "setVmBootVolume" + desc "云主机UUID" + location "url" + type "String" + optional false + since "4.2.0" + } + column { + name "volumeUuid" + enclosedIn "setVmBootVolume" + desc "云盘UUID" + location "body" + type "String" + optional false + since "4.2.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.2.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.2.0" + } + } + } + + response { + clz APISetVmBootVolumeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..ef57066a2ef --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.VmInstanceInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "设置云主机时钟同步的结果" + + ref { + name "inventory" + path "org.zstack.header.vm.APISetVmClockTrackEvent.inventory" + desc "null" + type "VmInstanceInventory" + since "4.1.0" + clz VmInstanceInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.1.0" + } + ref { + name "error" + path "org.zstack.header.vm.APISetVmClockTrackEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.1.0" + clz ErrorCode.class + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsg.java b/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsg.java index 2f2b7d26766..216ab558e48 100644 --- a/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsg.java @@ -18,6 +18,10 @@ public class APISetVmClockTrackMsg extends APIMessage implements VmInstanceMessa private String uuid; @APIParam(validValues = {"guest", "host"}) private String track; + @APIParam(required = false) + private Boolean syncAfterVMResume; + @APIParam(validValues = {"0", "60", "600", "1800", "3600", "7200", "21600", "43200", "86400"}, required = false) + private Integer intervalInSeconds; @Override public String getVmInstanceUuid() { @@ -40,10 +44,28 @@ public void setTrack(String track) { this.track = track; } + public Boolean isSyncAfterVMResume() { + return syncAfterVMResume; + } + + public void setSyncAfterVMResume(boolean syncAfterVMResume) { + this.syncAfterVMResume = syncAfterVMResume; + } + + public Integer getIntervalInSeconds() { + return intervalInSeconds; + } + + public void setIntervalInSeconds(Integer intervalInSeconds) { + this.intervalInSeconds = intervalInSeconds; + } + public static APISetVmClockTrackMsg __example__() { APISetVmClockTrackMsg msg = new APISetVmClockTrackMsg(); msg.uuid = uuid(); msg.track = "guest"; + msg.syncAfterVMResume = true; + msg.intervalInSeconds = 60; return msg; } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..e385874671d --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APISetVmClockTrackMsgDoc_zh_cn.groovy @@ -0,0 +1,87 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APISetVmClockTrackEvent + +doc { + title "SetVmClockTrack" + + category "vmInstance" + + desc """设置云主机时钟同步""" + + rest { + request { + url "PUT /v1/vm-instances/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APISetVmClockTrackMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "setVmClockTrack" + desc "vmUuid" + location "url" + type "String" + optional false + since "4.1.0" + } + column { + name "track" + enclosedIn "setVmClockTrack" + desc "BIOS时钟同步策略" + location "body" + type "String" + optional false + since "4.1.0" + values ("guest","host") + } + column { + name "syncAfterVMResume" + enclosedIn "setVmClockTrack" + desc "暂停到恢复是否同步" + location "body" + type "Boolean" + optional true + since "4.4.12" + } + column { + name "intervalInSeconds" + enclosedIn "setVmClockTrack" + desc "定期同步时间间隔" + location "body" + type "Integer" + optional true + since "4.4.12" + values ("0","60","600","1800","3600","7200","21600","43200","86400") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.1.0" + } + } + } + + response { + clz APISetVmClockTrackEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmConsolePasswordMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmConsolePasswordMsgDoc_zh_cn.groovy index 53c08f572fc..e784a031301 100755 --- a/header/src/main/java/org/zstack/header/vm/APISetVmConsolePasswordMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmConsolePasswordMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "consolePassword" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmHostnameMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmHostnameMsgDoc_zh_cn.groovy index eece95446d2..81e76924cce 100755 --- a/header/src/main/java/org/zstack/header/vm/APISetVmHostnameMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmHostnameMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "hostname" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmQxlMemoryMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmQxlMemoryMsgDoc_zh_cn.groovy index b020038cc1c..1f8c395d91b 100644 --- a/header/src/main/java/org/zstack/header/vm/APISetVmQxlMemoryMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmQxlMemoryMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.7" - } column { name "ram" @@ -39,7 +38,6 @@ doc { type "Integer" optional true since "3.7" - } column { name "vram" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "3.7" - } column { name "vgamem" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "3.7" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.7" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "3.7" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmSoundTypeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmSoundTypeMsgDoc_zh_cn.groovy index 6eca9b20b0b..28925155410 100644 --- a/header/src/main/java/org/zstack/header/vm/APISetVmSoundTypeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmSoundTypeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.7" - } column { name "soundType" @@ -49,7 +48,6 @@ doc { type "List" optional true since "3.7" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "3.7" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmSshKeyMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmSshKeyMsgDoc_zh_cn.groovy index 643959f7c02..52cfb8bc5d1 100644 --- a/header/src/main/java/org/zstack/header/vm/APISetVmSshKeyMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmSshKeyMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "SshKey" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsg.java b/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsg.java index 2875ac7bd0f..a4e0d71b209 100755 --- a/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsg.java @@ -2,7 +2,6 @@ import org.springframework.http.HttpMethod; import org.zstack.header.identity.Action; -import org.zstack.header.message.APIEvent; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.network.l3.L3NetworkVO; @@ -27,6 +26,14 @@ public class APISetVmStaticIpMsg extends APIMessage implements VmInstanceMessage private String ip; @APIParam(required = false) private String ip6; + @APIParam(required = false) + private String netmask; + @APIParam(required = false) + private String gateway; + @APIParam(required = false) + private String ipv6Gateway; + @APIParam(required = false) + private String ipv6Prefix; public String getIp() { return ip; @@ -61,6 +68,38 @@ public void setIp6(String ip6) { this.ip6 = ip6; } + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getIpv6Gateway() { + return ipv6Gateway; + } + + public void setIpv6Gateway(String ipv6Gateway) { + this.ipv6Gateway = ipv6Gateway; + } + + public String getIpv6Prefix() { + return ipv6Prefix; + } + + public void setIpv6Prefix(String ipv6Prefix) { + this.ipv6Prefix = ipv6Prefix; + } + public static APISetVmStaticIpMsg __example__() { APISetVmStaticIpMsg msg = new APISetVmStaticIpMsg(); msg.vmInstanceUuid = uuid(); diff --git a/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsgDoc_zh_cn.groovy index d1c45d74565..9415e501788 100644 --- a/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APISetVmStaticIpMsgDoc_zh_cn.groovy @@ -32,7 +32,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuid" @@ -42,7 +41,6 @@ doc { type "String" optional false since "0.6" - } column { name "ip" @@ -50,9 +48,8 @@ doc { desc "指定IP地址" location "body" type "String" - optional false + optional true since "0.6" - } column { name "ip6" @@ -62,7 +59,6 @@ doc { type "String" optional true since "3.10" - } column { name "systemTags" @@ -72,7 +68,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -82,7 +77,42 @@ doc { type "List" optional true since "0.6" - + } + column { + name "netmask" + enclosedIn "setVmStaticIp" + desc "IPv4子网掩码" + location "body" + type "String" + optional true + since "0.6" + } + column { + name "gateway" + enclosedIn "setVmStaticIp" + desc "IPv4网关" + location "body" + type "String" + optional true + since "0.6" + } + column { + name "ipv6Gateway" + enclosedIn "setVmStaticIp" + desc "IPv6网关" + location "body" + type "String" + optional true + since "0.6" + } + column { + name "ipv6Prefix" + enclosedIn "setVmStaticIp" + desc "IPv6前缀长度" + location "body" + type "String" + optional true + since "0.6" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsg.java index 541c2d8132e..36380c66bdc 100755 --- a/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsg.java @@ -42,7 +42,7 @@ isAction = true ) @SkipVmTracer(replyClass = APIStartVmInstanceEvent.class) -public class APIStartVmInstanceMsg extends APIMessage implements VmInstanceMessage { +public class APIStartVmInstanceMsg extends APIMessage implements VmInstanceMessage, CheckAttachedVolumesMessage { /** * @desc vm uuid */ diff --git a/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsgDoc_zh_cn.groovy index 7b2b026b152..2b096a36557 100755 --- a/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIStartVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "clusterUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "hostUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIStopVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIStopVmInstanceMsgDoc_zh_cn.groovy index 56f1f1a4e89..c9c704b70d4 100755 --- a/header/src/main/java/org/zstack/header/vm/APIStopVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIStopVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "type" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } column { name "stopHA" @@ -69,7 +66,6 @@ doc { type "String" optional true since "2.2" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotEvent.java b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotEvent.java new file mode 100644 index 00000000000..b03cad02a3f --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotEvent.java @@ -0,0 +1,34 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shanshan.ning + * @date 2023-09-11 + */ +@RestResponse(fieldsTo = {"imageData"}) +public class APITakeVmConsoleScreenshotEvent extends APIEvent { + private String imageData; + + public APITakeVmConsoleScreenshotEvent() { + } + + public APITakeVmConsoleScreenshotEvent(String apiId) { + super(apiId); + } + + public String getImageData() { + return imageData; + } + + public void setImageData(String imageData) { + this.imageData = imageData; + } + + public static APITakeVmConsoleScreenshotEvent __example__() { + APITakeVmConsoleScreenshotEvent event = new APITakeVmConsoleScreenshotEvent(); + event.setImageData("data:image/jpg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABEAHgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDxKQwkMEt7dQCG/wBcp49BTcwb1P2eHrjAnXBOOv06/pWdRQBbmaAPh4APlP8AqpQRn16H8qhLW+eI5cf749Pp61FRQBKWt9mFjkD7cZLjGfXp+lRUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//Z"); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..d0a75c1f9ae --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotEventDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.header.vm + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取虚拟机控制台截图" + + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.console.APITakeVmConsoleScreenshotEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } + field { + name "imageData" + desc "控制台截图的base64" + type "String" + since "4.7.0" + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotMsg.java b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotMsg.java new file mode 100644 index 00000000000..ec94cb74946 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotMsg.java @@ -0,0 +1,42 @@ +package org.zstack.header.vm; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @author shanshan.ning + * @date 2023-09-11 + */ +@Action(category = VmInstanceConstant.ACTION_CATEGORY) +@RestRequest( + path = "/vm-instances/{uuid}/actions", + isAction = true, + method = HttpMethod.PUT, + responseClass = APITakeVmConsoleScreenshotEvent.class +) +public class APITakeVmConsoleScreenshotMsg extends APIMessage implements VmInstanceMessage { + @APIParam(resourceType = VmInstanceVO.class, checkAccount = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getVmInstanceUuid() { + return getUuid(); + } + + public static APITakeVmConsoleScreenshotMsg __example__() { + APITakeVmConsoleScreenshotMsg msg = new APITakeVmConsoleScreenshotMsg(); + msg.setUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..bac272d4e86 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/APITakeVmConsoleScreenshotMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.APITakeVmConsoleScreenshotEvent + +doc { + title "TakeVmConsoleScreenshot" + + category "vmInstance" + + desc """获取虚拟机控制台截图""" + + rest { + request { + url "PUT /v1/vm-instances/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APITakeVmConsoleScreenshotMsg.class + + desc """获取虚拟机控制台截图""" + + params { + + column { + name "uuid" + enclosedIn "takeVmConsoleScreenshot" + desc "虚拟机UUID" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APITakeVmConsoleScreenshotEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/APIUpdatePriorityConfigMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIUpdatePriorityConfigMsgDoc_zh_cn.groovy index f77858b9dd9..6fd11a171a5 100644 --- a/header/src/main/java/org/zstack/header/vm/APIUpdatePriorityConfigMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIUpdatePriorityConfigMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.7" - } column { name "cpuShares" @@ -39,7 +38,6 @@ doc { type "Integer" optional true since "3.7" - } column { name "oomScoreAdj" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "3.7" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.7" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.7" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsg.java index 7cdb359f357..abaed1be881 100755 --- a/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsg.java @@ -35,6 +35,8 @@ public class APIUpdateVmInstanceMsg extends APIMessage implements VmInstanceMess private Integer cpuNum; @APIParam(required = false, numberRange = {1, Long.MAX_VALUE}) private Long memorySize; + @APIParam(required = false, numberRange = {0, Long.MAX_VALUE}) + private Long reservedMemorySize; @APIParam(required = false, maxLength = 255) private String guestOsType; @@ -114,7 +116,15 @@ public String getGuestOsType() { public void setGuestOsType(String guestOsType) { this.guestOsType = guestOsType; } - + + public Long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public static APIUpdateVmInstanceMsg __example__() { APIUpdateVmInstanceMsg msg = new APIUpdateVmInstanceMsg(); msg.uuid = uuid(); diff --git a/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsgDoc_zh_cn.groovy index 2f33e187fd6..96fb87818a7 100755 --- a/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIUpdateVmInstanceMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "state" @@ -69,7 +66,6 @@ doc { type "String" optional true since "0.6" - } column { name "platform" @@ -89,7 +85,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "memorySize" @@ -99,7 +94,6 @@ doc { type "Long" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +103,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +112,24 @@ doc { type "List" optional true since "0.6" - + } + column { + name "guestOsType" + enclosedIn "updateVmInstance" + desc "" + location "body" + type "String" + optional true + since "4.1.2" + } + column { + name "reservedMemorySize" + enclosedIn "updateVmInstance" + desc "" + location "body" + type "Long" + optional true + since "4.7.21" } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIUpdateVmNicDriverMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIUpdateVmNicDriverMsgDoc_zh_cn.groovy index 521823808df..ac778d4f9e8 100644 --- a/header/src/main/java/org/zstack/header/vm/APIUpdateVmNicDriverMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIUpdateVmNicDriverMsgDoc_zh_cn.groovy @@ -11,7 +11,7 @@ doc { rest { request { - url "PUT /vm-instances/{vmInstanceUuid}/actions" + url "PUT /v1/vm-instances/{vmInstanceUuid}/actions" header (Authorization: 'OAuth the-session-uuid') @@ -23,27 +23,25 @@ doc { column { name "vmInstanceUuid" - enclosedIn "params" + enclosedIn "updateVmNicDriver" desc "云主机UUID" location "url" type "String" optional false since "3.9" - } column { name "vmNicUuid" - enclosedIn "params" + enclosedIn "updateVmNicDriver" desc "云主机网卡UUID" - location "url" + location "body" type "String" optional false since "3.9" - } column { name "driverType" - enclosedIn "params" + enclosedIn "updateVmNicDriver" desc "" location "body" type "String" @@ -58,7 +56,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -68,7 +65,6 @@ doc { type "List" optional true since "3.9" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/APIUpdateVmPriorityMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/APIUpdateVmPriorityMsgDoc_zh_cn.groovy index 7b2870ddfc5..1c0081fff3b 100644 --- a/header/src/main/java/org/zstack/header/vm/APIUpdateVmPriorityMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/APIUpdateVmPriorityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.7" - } column { name "priority" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.7" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.7" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.7" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/ArchiveResourceConfigBundle.java b/header/src/main/java/org/zstack/header/vm/ArchiveResourceConfigBundle.java new file mode 100644 index 00000000000..8c531514972 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ArchiveResourceConfigBundle.java @@ -0,0 +1,52 @@ +package org.zstack.header.vm; + +import java.util.List; + +public class ArchiveResourceConfigBundle { + public static class ResourceConfigBundle { + String resourceUuid; + String identity; + String value; + + public String getIdentity() { + return identity; + } + + public String getValue() { + return value; + } + + public void setIdentity(String identity) { + this.identity = identity; + } + + public void setValue(String value) { + this.value = value; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + } + + List resourceConfigBundles; + + public List getResourceConfigBundles() { + return resourceConfigBundles; + } + + public void setResourceConfigBundles(List resourceConfigBundles) { + this.resourceConfigBundles = resourceConfigBundles; + } + + public ArchiveResourceConfigBundle() { + } + + public ArchiveResourceConfigBundle(List resourceConfigBundles) { + this.resourceConfigBundles = resourceConfigBundles; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/ArchiveVmBundle.java b/header/src/main/java/org/zstack/header/vm/ArchiveVmBundle.java new file mode 100644 index 00000000000..216c57c3387 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ArchiveVmBundle.java @@ -0,0 +1,36 @@ +package org.zstack.header.vm; + +/** + * Created by LiangHanYu on 2022/9/21 15:52 + */ +public class ArchiveVmBundle { + VmInstanceInventory vmInventory; + + public ArchiveVmBundle() { + } + + public ArchiveVmBundle(VmInstanceInventory vmInventory) { + this.vmInventory = vmInventory; + } + + public VmInstanceInventory getVmInventory() { + return vmInventory; + } + + public void setVmInventory(VmInstanceInventory vmInventory) { + this.vmInventory = vmInventory; + } + + public UpdateVmInstanceMsg getUpdateVmMessage() { + UpdateVmInstanceMsg umsg = new UpdateVmInstanceMsg(); + umsg.setUuid(getVmInventory().getUuid()); + umsg.setName(getVmInventory().getName()); + umsg.setDescription(getVmInventory().getDescription()); + umsg.setDefaultL3NetworkUuid(getVmInventory().getDefaultL3NetworkUuid()); + umsg.setCpuNum(getVmInventory().getCpuNum()); + umsg.setMemorySize(getVmInventory().getMemorySize()); + umsg.setPlatform(getVmInventory().getPlatform()); + umsg.setGuestOsType(getVmInventory().getGuestOsType()); + return umsg; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/ArchiveVmCdRomBundle.java b/header/src/main/java/org/zstack/header/vm/ArchiveVmCdRomBundle.java new file mode 100644 index 00000000000..1029c3e9e08 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ArchiveVmCdRomBundle.java @@ -0,0 +1,25 @@ +package org.zstack.header.vm; + +import org.zstack.header.vm.cdrom.VmCdRomInventory; + +/** + * Created by LiangHanYu on 2022/9/26 17:44 + */ +public class ArchiveVmCdRomBundle { + VmCdRomInventory cdRomInventory; + + public ArchiveVmCdRomBundle() { + } + + public ArchiveVmCdRomBundle(VmCdRomInventory cdRomInventory) { + this.cdRomInventory = cdRomInventory; + } + + public VmCdRomInventory getCdRomInventory() { + return cdRomInventory; + } + + public void setCdRomInventory(VmCdRomInventory cdRomInventory) { + this.cdRomInventory = cdRomInventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/ArchiveVmNicBundle.java b/header/src/main/java/org/zstack/header/vm/ArchiveVmNicBundle.java new file mode 100644 index 00000000000..db238154609 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ArchiveVmNicBundle.java @@ -0,0 +1,61 @@ +package org.zstack.header.vm; + +/** + * Created by LiangHanYu on 2022/7/1 13:33 + */ +public class ArchiveVmNicBundle { + VmNicInventory vmNicInventory; + long outboundBandwidth; + long inboundBandwidth; + boolean isVmDefaultL3Network = false; + + public ArchiveVmNicBundle() { + } + + public ArchiveVmNicBundle(VmNicInventory vmNicInventory) { + this.vmNicInventory = vmNicInventory; + } + + public ArchiveVmNicBundle(VmNicInventory vmNicInventory, boolean isVmDefaultL3Network) { + this.vmNicInventory = vmNicInventory; + this.isVmDefaultL3Network = isVmDefaultL3Network; + } + + public ArchiveVmNicBundle(VmNicInventory vmNicInventory, long outboundBandwidth, long inboundBandwidth) { + this.vmNicInventory = vmNicInventory; + this.outboundBandwidth = outboundBandwidth; + this.inboundBandwidth = inboundBandwidth; + } + + public VmNicInventory getVmNicInventory() { + return vmNicInventory; + } + + public void setVmNicInventory(VmNicInventory vmNicInventory) { + this.vmNicInventory = vmNicInventory; + } + + public long getOutboundBandwidth() { + return outboundBandwidth; + } + + public void setOutboundBandwidth(long outboundBandwidth) { + this.outboundBandwidth = outboundBandwidth; + } + + public long getInboundBandwidth() { + return inboundBandwidth; + } + + public void setInboundBandwidth(long inboundBandwidth) { + this.inboundBandwidth = inboundBandwidth; + } + + public boolean isVmDefaultL3Network() { + return isVmDefaultL3Network; + } + + public void setVmDefaultL3Network(boolean vmDefaultL3Network) { + isVmDefaultL3Network = vmDefaultL3Network; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/ArchiveVolumeBundle.java b/header/src/main/java/org/zstack/header/vm/ArchiveVolumeBundle.java new file mode 100644 index 00000000000..c26b36a682c --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ArchiveVolumeBundle.java @@ -0,0 +1,25 @@ +package org.zstack.header.vm; + +import org.zstack.header.volume.VolumeInventory; + +/** + * Created by LiangHanYu on 2022/9/26 17:49 + */ +public class ArchiveVolumeBundle { + VolumeInventory volumeInventory; + + public ArchiveVolumeBundle() { + } + + public ArchiveVolumeBundle(VolumeInventory volumeInventory) { + this.volumeInventory = volumeInventory; + } + + public VolumeInventory getVolumeInventory() { + return volumeInventory; + } + + public void setVolumeInventory(VolumeInventory volumeInventory) { + this.volumeInventory = volumeInventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/AttachVolumeToVmOnHypervisorReply.java b/header/src/main/java/org/zstack/header/vm/AttachVolumeToVmOnHypervisorReply.java index 1e054694741..f519b13c2ac 100755 --- a/header/src/main/java/org/zstack/header/vm/AttachVolumeToVmOnHypervisorReply.java +++ b/header/src/main/java/org/zstack/header/vm/AttachVolumeToVmOnHypervisorReply.java @@ -1,6 +1,18 @@ package org.zstack.header.vm; import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.devices.VirtualDeviceInfo; + +import java.util.List; public class AttachVolumeToVmOnHypervisorReply extends MessageReply { + List virtualDeviceInfoList; + + public List getVirtualDeviceInfoList() { + return virtualDeviceInfoList; + } + + public void setVirtualDeviceInfoList(List virtualDeviceInfoList) { + this.virtualDeviceInfoList = virtualDeviceInfoList; + } } diff --git a/header/src/main/java/org/zstack/header/vm/CancelFlattenVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/CancelFlattenVmInstanceMsg.java new file mode 100644 index 00000000000..edf015d6d3b --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CancelFlattenVmInstanceMsg.java @@ -0,0 +1,21 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.CancelMessage; +import org.zstack.header.message.NeedReplyMessage; + +public class CancelFlattenVmInstanceMsg extends CancelMessage implements VmInstanceMessage { + private String uuid; + + @Override + public String getVmInstanceUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CancelFlattenVmInstanceReply.java b/header/src/main/java/org/zstack/header/vm/CancelFlattenVmInstanceReply.java new file mode 100644 index 00000000000..0b33d638adc --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CancelFlattenVmInstanceReply.java @@ -0,0 +1,7 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; + +public class CancelFlattenVmInstanceReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/ChangeVmNicNetworkMsg.java b/header/src/main/java/org/zstack/header/vm/ChangeVmNicNetworkMsg.java new file mode 100644 index 00000000000..1e7f7b1772f --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ChangeVmNicNetworkMsg.java @@ -0,0 +1,58 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; +import java.util.Map; + +/** + * Created by LiangHanYu on 2022/6/24 10:58 + */ +public class ChangeVmNicNetworkMsg extends NeedReplyMessage implements VmInstanceMessage { + private String vmNicUuid; + private String destL3NetworkUuid; + private String vmInstanceUuid; + private Map> requiredIpMap; + private String staticIp; + + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public String getDestL3NetworkUuid() { + return destL3NetworkUuid; + } + + public void setDestL3NetworkUuid(String destL3NetworkUuid) { + this.destL3NetworkUuid = destL3NetworkUuid; + } + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public Map> getRequiredIpMap() { + return requiredIpMap; + } + + public void setRequiredIpMap(Map> requiredIpMap) { + this.requiredIpMap = requiredIpMap; + } + + public String getStaticIp() { + return staticIp; + } + + public void setStaticIp(String staticIp) { + this.staticIp = staticIp; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/ChangeVmNicNetworkReply.java b/header/src/main/java/org/zstack/header/vm/ChangeVmNicNetworkReply.java new file mode 100644 index 00000000000..36c150ed2a5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ChangeVmNicNetworkReply.java @@ -0,0 +1,18 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2022/6/24 10:59 + */ +public class ChangeVmNicNetworkReply extends MessageReply { + private VmNicInventory inventory; + + public VmNicInventory getInventory() { + return inventory; + } + + public void setInventory(VmNicInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CheckAndStartVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/CheckAndStartVmInstanceMsg.java new file mode 100644 index 00000000000..72cb37b14ed --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CheckAndStartVmInstanceMsg.java @@ -0,0 +1,17 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +@SkipVmTracer(replyClass = CheckAndStartVmInstanceReply.class) +public class CheckAndStartVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage { + private String vmInstanceUuid; + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CheckAndStartVmInstanceReply.java b/header/src/main/java/org/zstack/header/vm/CheckAndStartVmInstanceReply.java new file mode 100644 index 00000000000..63a7669d9c0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CheckAndStartVmInstanceReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +public class CheckAndStartVmInstanceReply extends MessageReply { + private VmInstanceInventory inventory; + + public VmInstanceInventory getInventory() { + return inventory; + } + + public void setInventory(VmInstanceInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CheckAttachedVolumesMessage.java b/header/src/main/java/org/zstack/header/vm/CheckAttachedVolumesMessage.java new file mode 100644 index 00000000000..ddd1cb415e2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CheckAttachedVolumesMessage.java @@ -0,0 +1,4 @@ +package org.zstack.header.vm; + +public interface CheckAttachedVolumesMessage { +} diff --git a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeSnapShotVmMsg.java b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeSnapShotVmMsg.java new file mode 100644 index 00000000000..ce068985b80 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeSnapShotVmMsg.java @@ -0,0 +1,13 @@ +package org.zstack.header.vm; + +public class CreateTemplateFromRootVolumeSnapShotVmMsg extends CreateTemplateFromRootVolumeVmMsg { + private String snapshotUuid; + + public String getSnapshotUuid() { + return snapshotUuid; + } + + public void setSnapshotUuid(String snapshotUuid) { + this.snapshotUuid = snapshotUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeVmMsg.java b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeVmMsg.java new file mode 100755 index 00000000000..e3eeb26c4d8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeVmMsg.java @@ -0,0 +1,40 @@ +package org.zstack.header.vm; + +import org.zstack.header.image.ImageInventory; +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.volume.VolumeInventory; + +public class CreateTemplateFromRootVolumeVmMsg extends NeedReplyMessage implements VmInstanceMessage { + private ImageInventory imageInventory; + private VolumeInventory rootVolumeInventory; + private String backupStorageUuid; + + public VolumeInventory getRootVolumeInventory() { + return rootVolumeInventory; + } + + public void setRootVolumeInventory(VolumeInventory rootVolumeInventory) { + this.rootVolumeInventory = rootVolumeInventory; + } + + @Override + public String getVmInstanceUuid() { + return rootVolumeInventory.getVmInstanceUuid(); + } + + public String getBackupStorageUuid() { + return backupStorageUuid; + } + + public void setBackupStorageUuid(String backupStorageUuid) { + this.backupStorageUuid = backupStorageUuid; + } + + public ImageInventory getImageInventory() { + return imageInventory; + } + + public void setImageInventory(ImageInventory imageInventory) { + this.imageInventory = imageInventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeVmReply.java b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeVmReply.java new file mode 100755 index 00000000000..eaecaa5f2ca --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromRootVolumeVmReply.java @@ -0,0 +1,24 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +public class CreateTemplateFromRootVolumeVmReply extends MessageReply { + private String installPath; + private String format; + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromVmRootVolumeMsg.java b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromVmRootVolumeMsg.java deleted file mode 100755 index 7fb4a94ed61..00000000000 --- a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromVmRootVolumeMsg.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.zstack.header.vm; - -import org.zstack.header.image.ImageInventory; -import org.zstack.header.message.NeedReplyMessage; -import org.zstack.header.volume.VolumeInventory; - -public class CreateTemplateFromVmRootVolumeMsg extends NeedReplyMessage implements VmInstanceMessage { - private ImageInventory imageInventory; - private VolumeInventory rootVolumeInventory; - private String backupStorageUuid; - - public VolumeInventory getRootVolumeInventory() { - return rootVolumeInventory; - } - - public void setRootVolumeInventory(VolumeInventory rootVolumeInventory) { - this.rootVolumeInventory = rootVolumeInventory; - } - - @Override - public String getVmInstanceUuid() { - return rootVolumeInventory.getVmInstanceUuid(); - } - - public String getBackupStorageUuid() { - return backupStorageUuid; - } - - public void setBackupStorageUuid(String backupStorageUuid) { - this.backupStorageUuid = backupStorageUuid; - } - - public ImageInventory getImageInventory() { - return imageInventory; - } - - public void setImageInventory(ImageInventory imageInventory) { - this.imageInventory = imageInventory; - } -} diff --git a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromVmRootVolumeReply.java b/header/src/main/java/org/zstack/header/vm/CreateTemplateFromVmRootVolumeReply.java deleted file mode 100755 index 8bd404c6fbf..00000000000 --- a/header/src/main/java/org/zstack/header/vm/CreateTemplateFromVmRootVolumeReply.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.zstack.header.vm; - -import org.zstack.header.message.MessageReply; - -public class CreateTemplateFromVmRootVolumeReply extends MessageReply { - private String installPath; - private String format; - - public String getFormat() { - return format; - } - - public void setFormat(String format) { - this.format = format; - } - - public String getInstallPath() { - return installPath; - } - - public void setInstallPath(String installPath) { - this.installPath = installPath; - } -} diff --git a/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMessage.java b/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMessage.java index ce3de0573ab..b6e7ed04977 100644 --- a/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMessage.java +++ b/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMessage.java @@ -20,6 +20,8 @@ public interface CreateVmInstanceMessage { long getMemorySize(); + long getReservedMemorySize(); + List getL3NetworkSpecs(); String getType(); diff --git a/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMsg.java index f7d24f51b13..dc364097a8f 100755 --- a/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/CreateVmInstanceMsg.java @@ -2,6 +2,7 @@ import org.zstack.header.message.NeedReplyMessage; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -16,25 +17,74 @@ public class CreateVmInstanceMsg extends NeedReplyMessage implements CreateVmIns private int cpuNum; private long cpuSpeed; private long memorySize; + private long reservedMemorySize; private List l3NetworkSpecs; private String type; private String rootDiskOfferingUuid; private long rootDiskSize; + private List dataDiskSizes; private List dataDiskOfferingUuids; private List dataVolumeTemplateUuids; private Map> dataVolumeFromTemplateSystemTags; private String zoneUuid; private String clusterUuid; private String hostUuid; - private String primaryStorageUuidForRootVolume; - private String primaryStorageUuidForDataVolume; private String description; private String resourceUuid; private String defaultL3NetworkUuid; private String allocatorStrategy; private String strategy; + private String platform; + private String guestOsType; + private String architecture; + private Boolean virtio; private List rootVolumeSystemTags; private List dataVolumeSystemTags; + private Map> dataVolumeSystemTagsOnIndex; + private List disableL3Networks; + private List sshKeyPairUuids; + private final List candidatePrimaryStorageUuidsForRootVolume = new ArrayList<>(); + private final List candidatePrimaryStorageUuidsForDataVolume = new ArrayList<>(); + + public List getCandidatePrimaryStorageUuidsForRootVolume() { + return candidatePrimaryStorageUuidsForRootVolume; + } + + public void setCandidatePrimaryStorageUuidsForRootVolume(List candidatePrimaryStorageUuidsForRootVolume) { + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (candidatePrimaryStorageUuidsForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.addAll(candidatePrimaryStorageUuidsForRootVolume); + } + } + + public List getCandidatePrimaryStorageUuidsForDataVolume() { + return candidatePrimaryStorageUuidsForDataVolume; + } + + public void setCandidatePrimaryStorageUuidsForDataVolume(List candidatePrimaryStorageUuidsForDataVolume) { + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (candidatePrimaryStorageUuidsForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.addAll(candidatePrimaryStorageUuidsForDataVolume); + } + } + + public String getGuestOsType() { + return guestOsType; + } + + public void setGuestOsType(String guestOsType) { + this.guestOsType = guestOsType; + } + + private List diskAOs; + + public List getDiskAOs() { + return diskAOs; + } + + public void setDiskAOs(List diskAOs) { + this.diskAOs = diskAOs; + } public List getRootVolumeSystemTags() { return rootVolumeSystemTags; @@ -123,6 +173,14 @@ public void setDataDiskOfferingUuids(List dataDiskOfferingUuids) { this.dataDiskOfferingUuids = dataDiskOfferingUuids; } + public List getDataDiskSizes() { + return dataDiskSizes; + } + + public void setDataDiskSizes(List dataDiskSizes) { + this.dataDiskSizes = dataDiskSizes; + } + @Override public long getRootDiskSize() { return rootDiskSize; @@ -194,6 +252,15 @@ public void setMemorySize(long memorySize) { this.memorySize = memorySize; } + @Override + public long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + @Override public String getAllocatorStrategy() { return allocatorStrategy; @@ -230,20 +297,28 @@ public void setResourceUuid(String resourceUuid) { this.resourceUuid = resourceUuid; } + @Deprecated public String getPrimaryStorageUuidForRootVolume() { - return primaryStorageUuidForRootVolume; + return this.candidatePrimaryStorageUuidsForRootVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForRootVolume.get(0); } public void setPrimaryStorageUuidForRootVolume(String primaryStorageUuidForRootVolume) { - this.primaryStorageUuidForRootVolume = primaryStorageUuidForRootVolume; + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (primaryStorageUuidForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.add(primaryStorageUuidForRootVolume); + } } + @Deprecated public String getPrimaryStorageUuidForDataVolume() { - return primaryStorageUuidForDataVolume; + return this.candidatePrimaryStorageUuidsForDataVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForDataVolume.get(0); } public void setPrimaryStorageUuidForDataVolume(String primaryStorageUuidForDataVolume) { - this.primaryStorageUuidForDataVolume = primaryStorageUuidForDataVolume; + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (primaryStorageUuidForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.add(primaryStorageUuidForDataVolume); + } } public List getDataVolumeTemplateUuids() { @@ -261,4 +336,52 @@ public Map> getDataVolumeFromTemplateSystemTags() { public void setDataVolumeFromTemplateSystemTags(Map> dataVolumeFromTemplateSystemTags) { this.dataVolumeFromTemplateSystemTags = dataVolumeFromTemplateSystemTags; } + + public Map> getDataVolumeSystemTagsOnIndex() { + return dataVolumeSystemTagsOnIndex; + } + + public void setDataVolumeSystemTagsOnIndex(Map> dataVolumeSystemTagsOnIndex) { + this.dataVolumeSystemTagsOnIndex = dataVolumeSystemTagsOnIndex; + } + + public List getDisableL3Networks() { + return disableL3Networks; + } + + public void setDisableL3Networks(List disableL3Networks) { + this.disableL3Networks = disableL3Networks; + } + + public List getSshKeyPairUuids() { + return sshKeyPairUuids; + } + + public void setSshKeyPairUuids(List sshKeyPairUuids) { + this.sshKeyPairUuids = sshKeyPairUuids; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public boolean getVirtio() { + return virtio; + } + + public void setVirtio(boolean virtio) { + this.virtio = virtio; + } } diff --git a/header/src/main/java/org/zstack/header/vm/FlattenVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/FlattenVmInstanceMsg.java new file mode 100644 index 00000000000..dd1700c9df5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/FlattenVmInstanceMsg.java @@ -0,0 +1,38 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +public class FlattenVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage { + private String uuid; + private boolean dryRun; + private boolean full; + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public boolean isDryRun() { + return dryRun; + } + + public void setFull(boolean full) { + this.full = full; + } + + public boolean isFull() { + return full; + } + + @Override + public String getVmInstanceUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/FlattenVmInstanceReply.java b/header/src/main/java/org/zstack/header/vm/FlattenVmInstanceReply.java new file mode 100644 index 00000000000..16c8877dec8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/FlattenVmInstanceReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +public class FlattenVmInstanceReply extends MessageReply { + private VmInstanceInventory inventory; + + public void setInventory(VmInstanceInventory inventory) { + this.inventory = inventory; + } + + public VmInstanceInventory getInventory() { + return inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/FstrimVmMsg.java b/header/src/main/java/org/zstack/header/vm/FstrimVmMsg.java new file mode 100644 index 00000000000..7e9c052fa6e --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/FstrimVmMsg.java @@ -0,0 +1,26 @@ +package org.zstack.header.vm; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +public class FstrimVmMsg extends NeedReplyMessage implements HostMessage { + private String vmUuid; + private String hostUuid; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + @Override + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/FstrimVmReply.java b/header/src/main/java/org/zstack/header/vm/FstrimVmReply.java new file mode 100644 index 00000000000..a50417c474b --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/FstrimVmReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +public class FstrimVmReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/HaStartVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/HaStartVmInstanceMsg.java index 5d1144d86ee..a358249cdf9 100644 --- a/header/src/main/java/org/zstack/header/vm/HaStartVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/HaStartVmInstanceMsg.java @@ -8,10 +8,11 @@ * Created by xing5 on 2016/3/29. */ @SkipVmTracer(replyClass = HaStartVmInstanceReply.class) -public class HaStartVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage { +public class HaStartVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage, CheckAttachedVolumesMessage{ private String vmInstanceUuid; private String judgerClassName; private List softAvoidHostUuids; + private String haReason; public String getJudgerClassName() { return judgerClassName; @@ -37,4 +38,12 @@ public String getVmInstanceUuid() { public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; } + + public String getHaReason() { + return haReason; + } + + public void setHaReason(String haReason) { + this.haReason = haReason; + } } diff --git a/header/src/main/java/org/zstack/header/vm/HypervisorBasedVmConfigurationFactory.java b/header/src/main/java/org/zstack/header/vm/HypervisorBasedVmConfigurationFactory.java new file mode 100644 index 00000000000..799d6f44c2a --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/HypervisorBasedVmConfigurationFactory.java @@ -0,0 +1,7 @@ +package org.zstack.header.vm; + +public interface HypervisorBasedVmConfigurationFactory { + String getHypervisorType(); + + void createVmConfigurations(VmInstanceSpec spec); +} diff --git a/header/src/main/java/org/zstack/header/vm/InstantiateNewCreatedVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/InstantiateNewCreatedVmInstanceMsg.java index a5686155d52..f27bebf9802 100755 --- a/header/src/main/java/org/zstack/header/vm/InstantiateNewCreatedVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/InstantiateNewCreatedVmInstanceMsg.java @@ -2,6 +2,7 @@ import org.zstack.header.message.NeedReplyMessage; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -13,13 +14,47 @@ public class InstantiateNewCreatedVmInstanceMsg extends NeedReplyMessage impleme private Map> dataVolumeFromTemplateSystemTags; private String rootDiskOfferingUuid; private String hostUuid; - private String primaryStorageUuidForRootVolume; - private String primaryStorageUuidForDataVolume; private String strategy; private List rootVolumeSystemTags; private List dataVolumeSystemTags; private List softAvoidHostUuids; private List avoidHostUuids; + private Map> dataVolumeSystemTagsOnIndex; + private List disableL3Networks; + private final List candidatePrimaryStorageUuidsForRootVolume = new ArrayList<>(); + private final List candidatePrimaryStorageUuidsForDataVolume = new ArrayList<>(); + + public List getCandidatePrimaryStorageUuidsForRootVolume() { + return candidatePrimaryStorageUuidsForRootVolume; + } + + public void setCandidatePrimaryStorageUuidsForRootVolume(List candidatePrimaryStorageUuidsForRootVolume) { + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (candidatePrimaryStorageUuidsForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.addAll(candidatePrimaryStorageUuidsForRootVolume); + } + } + + public List getCandidatePrimaryStorageUuidsForDataVolume() { + return candidatePrimaryStorageUuidsForDataVolume; + } + + public void setCandidatePrimaryStorageUuidsForDataVolume(List candidatePrimaryStorageUuidsForDataVolume) { + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (candidatePrimaryStorageUuidsForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.addAll(candidatePrimaryStorageUuidsForDataVolume); + } + } + + private List diskAOs; + + public List getDiskAOs() { + return diskAOs; + } + + public void setDiskAOs(List diskAOs) { + this.diskAOs = diskAOs; + } public List getSoftAvoidHostUuids() { return softAvoidHostUuids; @@ -74,20 +109,28 @@ public String getVmInstanceUuid() { return getVmInstanceInventory().getUuid(); } + @Deprecated public String getPrimaryStorageUuidForRootVolume() { - return primaryStorageUuidForRootVolume; + return this.candidatePrimaryStorageUuidsForRootVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForRootVolume.get(0); } public void setPrimaryStorageUuidForRootVolume(String primaryStorageUuidForRootVolume) { - this.primaryStorageUuidForRootVolume = primaryStorageUuidForRootVolume; + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (primaryStorageUuidForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.add(primaryStorageUuidForRootVolume); + } } + @Deprecated public String getPrimaryStorageUuidForDataVolume() { - return primaryStorageUuidForDataVolume; + return this.candidatePrimaryStorageUuidsForDataVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForDataVolume.get(0); } public void setPrimaryStorageUuidForDataVolume(String primaryStorageUuidForDataVolume) { - this.primaryStorageUuidForDataVolume = primaryStorageUuidForDataVolume; + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (primaryStorageUuidForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.add(primaryStorageUuidForDataVolume); + } } public void setStrategy(String strategy) { @@ -137,4 +180,21 @@ public Map> getDataVolumeFromTemplateSystemTags() { public void setDataVolumeFromTemplateSystemTags(Map> dataVolumeFromTemplateSystemTags) { this.dataVolumeFromTemplateSystemTags = dataVolumeFromTemplateSystemTags; } + + public Map> getDataVolumeSystemTagsOnIndex() { + return dataVolumeSystemTagsOnIndex; + } + + public void setDataVolumeSystemTagsOnIndex(Map> dataVolumeSystemTagsOnIndex) { + this.dataVolumeSystemTagsOnIndex = dataVolumeSystemTagsOnIndex; + } + + public List getDisableL3Networks() { + return disableL3Networks; + } + + public void setDisableL3Networks(List disableL3Networks) { + this.disableL3Networks = disableL3Networks; + } } + diff --git a/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventExtensionPoint.java new file mode 100644 index 00000000000..f489d8d2eca --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventExtensionPoint.java @@ -0,0 +1,9 @@ +package org.zstack.header.vm; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/3/4 13:14 + */ +public interface KvmReportVmShutdownEventExtensionPoint { + void kvmReportVmShutdownEvent(String vmUuid); +} diff --git a/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventMsg.java b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventMsg.java new file mode 100644 index 00000000000..7d54880da0c --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventMsg.java @@ -0,0 +1,19 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/3/6 13:42 + */ +public class KvmReportVmShutdownEventMsg extends NeedReplyMessage implements VmInstanceMessage{ + private String vmInstanceUuid; + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventReply.java b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventReply.java new file mode 100644 index 00000000000..33c47c523bc --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownEventReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/3/6 13:43 + */ +public class KvmReportVmShutdownEventReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventExtensionPoint.java new file mode 100644 index 00000000000..aa43eb42be5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventExtensionPoint.java @@ -0,0 +1,9 @@ +package org.zstack.header.vm; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/4/12 17:17 + */ +public interface KvmReportVmShutdownFromGuestEventExtensionPoint { + void kvmReportVmShutdownEvent(String vmUuid); +} diff --git a/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventMsg.java b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventMsg.java new file mode 100644 index 00000000000..1f75580b26e --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventMsg.java @@ -0,0 +1,20 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/4/12 17:05 + */ +public class KvmReportVmShutdownFromGuestEventMsg extends NeedReplyMessage implements VmInstanceMessage { + private String vmInstanceUuid; + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventReply.java b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventReply.java new file mode 100644 index 00000000000..afaf4cbb04d --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/KvmReportVmShutdownFromGuestEventReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/4/12 17:06 + */ +public class KvmReportVmShutdownFromGuestEventReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/MigrateVmInnerMsg.java b/header/src/main/java/org/zstack/header/vm/MigrateVmInnerMsg.java index 09f038ebecb..8aeed12c273 100755 --- a/header/src/main/java/org/zstack/header/vm/MigrateVmInnerMsg.java +++ b/header/src/main/java/org/zstack/header/vm/MigrateVmInnerMsg.java @@ -7,12 +7,13 @@ * copy by APIMigrateVmMsg for LongJob */ @SkipVmTracer(replyClass = MigrateVmInnerReply.class) -public class MigrateVmInnerMsg extends NeedReplyMessage implements VmInstanceMessage, MigrateVmMessage { +public class MigrateVmInnerMsg extends NeedReplyMessage implements VmInstanceMessage, MigrateVmMessage, CheckAttachedVolumesMessage { private String vmInstanceUuid; private String hostUuid; private String strategy; private Boolean migrateFromDestination; private boolean allowUnknown; + private Integer downTime; public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; @@ -55,6 +56,15 @@ public String getStrategy() { return strategy; } + @Override + public Integer getDownTime() { + return null; + } + + public void setDownTime(Integer downTime) { + this.downTime = downTime; + } + public void setStrategy(String strategy) { this.strategy = strategy; } diff --git a/header/src/main/java/org/zstack/header/vm/MigrateVmMessage.java b/header/src/main/java/org/zstack/header/vm/MigrateVmMessage.java index d395b609172..0060aea6a19 100644 --- a/header/src/main/java/org/zstack/header/vm/MigrateVmMessage.java +++ b/header/src/main/java/org/zstack/header/vm/MigrateVmMessage.java @@ -5,6 +5,7 @@ public interface MigrateVmMessage { String getHostUuid(); String getStrategy(); + Integer getDownTime(); boolean isMigrateFromDestination(); boolean isAllowUnknown(); diff --git a/header/src/main/java/org/zstack/header/vm/MigrateVmMsg.java b/header/src/main/java/org/zstack/header/vm/MigrateVmMsg.java index 74ae8213db7..7787cd53d7c 100755 --- a/header/src/main/java/org/zstack/header/vm/MigrateVmMsg.java +++ b/header/src/main/java/org/zstack/header/vm/MigrateVmMsg.java @@ -16,6 +16,16 @@ public class MigrateVmMsg extends NeedReplyMessage implements VmInstanceMessage, private String targetHostUuid; private boolean migrateFromDestination; private boolean allowUnknown; + private Integer downTime; + + @Override + public Integer getDownTime() { + return downTime; + } + + public void setDownTime(Integer downTime) { + this.downTime = downTime; + } @Override public AllocationScene getAllocationScene() { diff --git a/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage.java b/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage.java index 510a051eed2..b150ea7ba3f 100644 --- a/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage.java +++ b/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage.java @@ -6,6 +6,7 @@ public interface NewVmInstanceMessage { String getName(); String getDescription(); List getL3NetworkUuids(); + String getVmNicParams(); String getDefaultL3NetworkUuid(); String getType(); List getSystemTags(); diff --git a/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage2.java b/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage2.java index 6bc46c7082f..c86c80e7931 100644 --- a/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage2.java +++ b/header/src/main/java/org/zstack/header/vm/NewVmInstanceMessage2.java @@ -6,6 +6,7 @@ public interface NewVmInstanceMessage2 extends NewVmInstanceMessage { Integer getCpuNum(); Long getMemorySize(); + Long getReservedMemorySize(); String getZoneUuid(); String getClusterUuid(); String getHostUuid(); @@ -14,6 +15,7 @@ public interface NewVmInstanceMessage2 extends NewVmInstanceMessage { void setCpuNum(Integer cpuNum); void setMemorySize(Long memorySize); + void setReservedMemorySize(Long reservedMemorySize); void setZoneUuid(String zoneUuid); void setClusterUuid(String clusterUuid); void setDefaultL3NetworkUuid(String defaultL3NetworkUuid); diff --git a/header/src/main/java/org/zstack/header/vm/NicManageExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/NicManageExtensionPoint.java new file mode 100644 index 00000000000..9a1ce1e7c68 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/NicManageExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.vm; + + +public interface NicManageExtensionPoint { + void beforeCreateNic(VmNicInventory nic, APICreateVmNicMsg msg); + + void beforeDeleteNic(VmNicInventory nic); +} diff --git a/header/src/main/java/org/zstack/header/vm/PackageInfo.java b/header/src/main/java/org/zstack/header/vm/PackageInfo.java index 07107b62436..332c1a49f4c 100755 --- a/header/src/main/java/org/zstack/header/vm/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/vm/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "云主机") +@PackageAPIInfo( + APICategoryName = "云主机", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/vm/RebootVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/RebootVmInstanceMsg.java index 1c4978a8a23..8362bc56e44 100755 --- a/header/src/main/java/org/zstack/header/vm/RebootVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/RebootVmInstanceMsg.java @@ -12,6 +12,7 @@ public class RebootVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage { private String vmInstanceUuid; private String type = StopVmType.grace.toString(); + private boolean debug; public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; @@ -30,4 +31,11 @@ public void setType(String type) { this.type = type; } + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } } diff --git a/header/src/main/java/org/zstack/header/vm/ReleaseNetworkServiceOnDeletingNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/ReleaseNetworkServiceOnDeletingNicExtensionPoint.java index 9f2a7cb17f6..a38cd8b339a 100644 --- a/header/src/main/java/org/zstack/header/vm/ReleaseNetworkServiceOnDeletingNicExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/vm/ReleaseNetworkServiceOnDeletingNicExtensionPoint.java @@ -1,7 +1,7 @@ package org.zstack.header.vm; -import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; public interface ReleaseNetworkServiceOnDeletingNicExtensionPoint { - void releaseNetworkServiceOnDeletingNic(VmNicInventory nic, Completion completion); + void releaseNetworkServiceOnDeletingNic(VmNicInventory nic, NoErrorCompletion completion); } diff --git a/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java new file mode 100644 index 00000000000..7f45aa3d96d --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/ResourceConfigMemorySnapshotExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.header.vm; + +import java.util.List; + +public interface ResourceConfigMemorySnapshotExtensionPoint { + List getNeedToArchiveResourceConfig(String resourceUuid); +} diff --git a/header/src/main/java/org/zstack/header/vm/RestoreVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/RestoreVmInstanceMsg.java index 2280be2fbb7..9f3dba48b8e 100644 --- a/header/src/main/java/org/zstack/header/vm/RestoreVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/RestoreVmInstanceMsg.java @@ -3,7 +3,7 @@ import org.zstack.header.message.NeedReplyMessage; @SkipVmTracer(replyClass = StartVmInstanceReply.class) -public class RestoreVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage { +public class RestoreVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage, CheckAttachedVolumesMessage { private String vmInstanceUuid; private String memorySnapshotUuid; diff --git a/header/src/main/java/org/zstack/header/vm/SetVmHostNameFlowInterface.java b/header/src/main/java/org/zstack/header/vm/SetVmHostNameFlowInterface.java new file mode 100644 index 00000000000..03f38903844 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SetVmHostNameFlowInterface.java @@ -0,0 +1,7 @@ +package org.zstack.header.vm; + +import org.zstack.header.core.workflow.Flow; + +public interface SetVmHostNameFlowInterface { + Flow getSetVmHostNameFlow(); +} diff --git a/header/src/main/java/org/zstack/header/vm/SetVmQgaSyncClockTaskMsg.java b/header/src/main/java/org/zstack/header/vm/SetVmQgaSyncClockTaskMsg.java new file mode 100644 index 00000000000..817b0af3b09 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SetVmQgaSyncClockTaskMsg.java @@ -0,0 +1,43 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by Wenhao.Zhang on 22/06/29 + */ +public class SetVmQgaSyncClockTaskMsg extends NeedReplyMessage implements VmInstanceMessage { + private String vmInstanceUuid; + /** + * null if not set + */ + private Boolean syncAfterVMResume; + /** + * interval for sync clock. null if not set + */ + private Integer intervalInSeconds; + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public Boolean getSyncAfterVMResume() { + return syncAfterVMResume; + } + + public void setSyncAfterVMResume(Boolean syncAfterVMResume) { + this.syncAfterVMResume = syncAfterVMResume; + } + + public Integer getIntervalInSeconds() { + return intervalInSeconds; + } + + public void setIntervalInSeconds(Integer intervalInSeconds) { + this.intervalInSeconds = intervalInSeconds; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/SetVmQgaSyncClockTaskReply.java b/header/src/main/java/org/zstack/header/vm/SetVmQgaSyncClockTaskReply.java new file mode 100644 index 00000000000..5d163434b66 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SetVmQgaSyncClockTaskReply.java @@ -0,0 +1,9 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * Created by Wenhao.Zhang on 22/06/29 + */ +public class SetVmQgaSyncClockTaskReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/SetVmStaticIpMsg.java b/header/src/main/java/org/zstack/header/vm/SetVmStaticIpMsg.java new file mode 100644 index 00000000000..dd27c3c0c48 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SetVmStaticIpMsg.java @@ -0,0 +1,82 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by LiangHanYu on 2022/6/22 17:12 + */ +public class SetVmStaticIpMsg extends NeedReplyMessage implements VmInstanceMessage { + private String vmInstanceUuid; + private String l3NetworkUuid; + private String ip; + private String ip6; + private String netmask; + private String gateway; + private String ipv6Gateway; + private String ipv6Prefix; + + @Override + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getIp6() { + return ip6; + } + + public void setIp6(String ip6) { + this.ip6 = ip6; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getIpv6Gateway() { + return ipv6Gateway; + } + + public void setIpv6Gateway(String ipv6Gateway) { + this.ipv6Gateway = ipv6Gateway; + } + + public String getIpv6Prefix() { + return ipv6Prefix; + } + + public void setIpv6Prefix(String ipv6Prefix) { + this.ipv6Prefix = ipv6Prefix; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/SetVmStaticIpReply.java b/header/src/main/java/org/zstack/header/vm/SetVmStaticIpReply.java new file mode 100644 index 00000000000..cd25a962d82 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SetVmStaticIpReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.cdrom.VmCdRomInventory; + +/** + * Created by LiangHanYu on 2022/6/22 17:12 + */ +public class SetVmStaticIpReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/StartVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/StartVmInstanceMsg.java index 2f42840ee74..8b38b567da8 100755 --- a/header/src/main/java/org/zstack/header/vm/StartVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/StartVmInstanceMsg.java @@ -13,7 +13,7 @@ * To change this template use File | Settings | File Templates. */ @SkipVmTracer(replyClass = StartVmInstanceReply.class) -public class StartVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage, NeedQuotaCheckMessage { +public class StartVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage, NeedQuotaCheckMessage, CheckAttachedVolumesMessage { private String vmInstanceUuid; private String accountUuid; private String hostUuid; diff --git a/header/src/main/java/org/zstack/header/vm/StopVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/StopVmInstanceMsg.java index 36d3244fd53..551523d9c3d 100755 --- a/header/src/main/java/org/zstack/header/vm/StopVmInstanceMsg.java +++ b/header/src/main/java/org/zstack/header/vm/StopVmInstanceMsg.java @@ -14,6 +14,8 @@ public class StopVmInstanceMsg extends NeedReplyMessage implements VmInstanceMes private boolean gcOnFailure; private String type = StopVmType.grace.toString(); private boolean ignoreResourceReleaseFailure; + private boolean debug; + private boolean stopHA; public boolean isGcOnFailure() { return gcOnFailure; @@ -49,4 +51,21 @@ public boolean isIgnoreResourceReleaseFailure() { public void setIgnoreResourceReleaseFailure(boolean ignoreResourceReleaseFailure) { this.ignoreResourceReleaseFailure = ignoreResourceReleaseFailure; } + + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + + public boolean isStopHA() { + return stopHA; + } + + public void setStopHA(boolean stopHA) { + this.stopHA = stopHA; + } } diff --git a/header/src/main/java/org/zstack/header/vm/StopVmOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/vm/StopVmOnHypervisorMsg.java index 84144a28f78..bffd82dce1f 100755 --- a/header/src/main/java/org/zstack/header/vm/StopVmOnHypervisorMsg.java +++ b/header/src/main/java/org/zstack/header/vm/StopVmOnHypervisorMsg.java @@ -6,6 +6,7 @@ public class StopVmOnHypervisorMsg extends NeedReplyMessage implements HostMessage { private VmInstanceInventory vmInventory; private String type; + private boolean debug; public VmInstanceInventory getVmInventory() { return vmInventory; @@ -27,4 +28,12 @@ public void setType(String type) { public String getHostUuid() { return vmInventory.getHostUuid(); } + + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } } diff --git a/header/src/main/java/org/zstack/header/vm/SyncVmDeviceInfoMsg.java b/header/src/main/java/org/zstack/header/vm/SyncVmDeviceInfoMsg.java new file mode 100644 index 00000000000..f76e52ae97c --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SyncVmDeviceInfoMsg.java @@ -0,0 +1,30 @@ +package org.zstack.header.vm; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +/** + * @Author: DaoDao + * @Date: 2022/7/26 + */ +public class SyncVmDeviceInfoMsg extends NeedReplyMessage implements HostMessage { + private String vmInstanceUuid; + private String hostUuid; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + @Override + public String getHostUuid() { + return hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/SyncVmDeviceInfoReply.java b/header/src/main/java/org/zstack/header/vm/SyncVmDeviceInfoReply.java new file mode 100644 index 00000000000..5574e6446a6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/SyncVmDeviceInfoReply.java @@ -0,0 +1,10 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * @Author: DaoDao + * @Date: 2022/7/26 + */ +public class SyncVmDeviceInfoReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/vm/TakeVmConsoleScreenshotMsg.java b/header/src/main/java/org/zstack/header/vm/TakeVmConsoleScreenshotMsg.java new file mode 100644 index 00000000000..e1a5ffff99e --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/TakeVmConsoleScreenshotMsg.java @@ -0,0 +1,30 @@ +package org.zstack.header.vm; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +/** + * @author shanshan.ning + * @date 2023-09-11 + */ +public class TakeVmConsoleScreenshotMsg extends NeedReplyMessage implements HostMessage { + private String vmInstanceUuid; + private String hostUuid; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + @Override + public String getHostUuid() { + return hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/TakeVmConsoleScreenshotReply.java b/header/src/main/java/org/zstack/header/vm/TakeVmConsoleScreenshotReply.java new file mode 100644 index 00000000000..69ad7def25f --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/TakeVmConsoleScreenshotReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * @author shanshan.ning + * @date 2023-09-11 + */ +public class TakeVmConsoleScreenshotReply extends MessageReply { + private String imageData; + + public String getImageData() { + return imageData; + } + + public void setImageData(String imageData) { + this.imageData = imageData; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceMsg.java b/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceMsg.java new file mode 100644 index 00000000000..2bdbdd1b4b6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceMsg.java @@ -0,0 +1,104 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by LiangHanYu on 2022/9/22 10:03 + */ +public class UpdateVmInstanceMsg extends NeedReplyMessage implements VmInstanceMessage { + private String uuid; + private String name; + private String description; + private String state; + private String defaultL3NetworkUuid; + private String platform; + private Integer cpuNum; + private Long memorySize; + private Long reservedMemorySize; + private String guestOsType; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getDefaultL3NetworkUuid() { + return defaultL3NetworkUuid; + } + + public void setDefaultL3NetworkUuid(String defaultL3NetworkUuid) { + this.defaultL3NetworkUuid = defaultL3NetworkUuid; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public Integer getCpuNum() { + return cpuNum; + } + + public void setCpuNum(Integer cpuNum) { + this.cpuNum = cpuNum; + } + + public Long getMemorySize() { + return memorySize; + } + + public void setMemorySize(Long memorySize) { + this.memorySize = memorySize; + } + + public Long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + + public String getGuestOsType() { + return guestOsType; + } + + public void setGuestOsType(String guestOsType) { + this.guestOsType = guestOsType; + } + + @Override + public String getVmInstanceUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceReply.java b/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceReply.java new file mode 100644 index 00000000000..7b91f300575 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceReply.java @@ -0,0 +1,18 @@ +package org.zstack.header.vm; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2022/9/22 10:04 + */ +public class UpdateVmInstanceReply extends MessageReply { + private VmInstanceInventory inventory; + + public VmInstanceInventory getInventory() { + return inventory; + } + + public void setInventory(VmInstanceInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceSpec.java b/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceSpec.java new file mode 100644 index 00000000000..9532d2b46eb --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/UpdateVmInstanceSpec.java @@ -0,0 +1,78 @@ +package org.zstack.header.vm; + +/** + * Created by Wenhao.Zhang on 23/10/16 + */ +public class UpdateVmInstanceSpec { + private String hostUuid; + private String vmInstanceUuid; + + private String name; + private Integer cpuNum; + private Long memorySize; + private Long reservedMemorySize; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getCpuNum() { + return cpuNum; + } + + public void setCpuNum(Integer cpuNum) { + this.cpuNum = cpuNum; + } + + public Long getMemorySize() { + return memorySize; + } + + public void setMemorySize(Long memorySize) { + this.memorySize = memorySize; + } + + public Long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + + public boolean isNameChanged() { + return name != null; + } + + public boolean isCpuChanged() { + return cpuNum != null; + } + + public boolean isMemoryChanged() { + return memorySize != null; + } + + public boolean isReservedMemoryChanged() { + return reservedMemorySize != null; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/UpdateVmOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/vm/UpdateVmOnHypervisorMsg.java new file mode 100644 index 00000000000..cd724dd4fc7 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/UpdateVmOnHypervisorMsg.java @@ -0,0 +1,24 @@ +package org.zstack.header.vm; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by Wenhao.Zhang on 23/10/16 + */ +public class UpdateVmOnHypervisorMsg extends NeedReplyMessage implements HostMessage { + private UpdateVmInstanceSpec spec; + + @Override + public String getHostUuid() { + return spec.getHostUuid(); + } + + public UpdateVmInstanceSpec getSpec() { + return spec; + } + + public void setSpec(UpdateVmInstanceSpec spec) { + this.spec = spec; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/UpdateVmOnHypervisorReply.java b/header/src/main/java/org/zstack/header/vm/UpdateVmOnHypervisorReply.java new file mode 100644 index 00000000000..971166b21b3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/UpdateVmOnHypervisorReply.java @@ -0,0 +1,61 @@ +package org.zstack.header.vm; + +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.MessageReply; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Wenhao.Zhang on 23/10/16 + */ +public class UpdateVmOnHypervisorReply extends MessageReply { + private Integer cpuUpdatedTo; + private Long memoryUpdatedTo; + private String nameUpdatedTo; + private final List ignoredErrors = new ArrayList<>(); + + public boolean isCpuUpdated() { + return cpuUpdatedTo != null; + } + + public boolean isMemoryUpdated() { + return memoryUpdatedTo != null; + } + + public boolean isNameUpdated() { + return nameUpdatedTo != null; + } + + public boolean hasAnythingUpdated() { + return isCpuUpdated() || isMemoryUpdated() || isNameUpdated(); + } + + public Integer getCpuUpdatedTo() { + return cpuUpdatedTo; + } + + public void setCpuUpdatedTo(Integer cpuUpdatedTo) { + this.cpuUpdatedTo = cpuUpdatedTo; + } + + public Long getMemoryUpdatedTo() { + return memoryUpdatedTo; + } + + public void setMemoryUpdatedTo(Long memoryUpdatedTo) { + this.memoryUpdatedTo = memoryUpdatedTo; + } + + public String getNameUpdatedTo() { + return nameUpdatedTo; + } + + public void setNameUpdatedTo(String nameUpdatedTo) { + this.nameUpdatedTo = nameUpdatedTo; + } + + public List getIgnoredErrors() { + return ignoredErrors; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmAbnormalLifeCycleStruct.java b/header/src/main/java/org/zstack/header/vm/VmAbnormalLifeCycleStruct.java index 9373b50b1d2..a268e6421dc 100755 --- a/header/src/main/java/org/zstack/header/vm/VmAbnormalLifeCycleStruct.java +++ b/header/src/main/java/org/zstack/header/vm/VmAbnormalLifeCycleStruct.java @@ -1,28 +1,225 @@ package org.zstack.header.vm; +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Stream; + /** * Created by frank on 11/1/2015. */ public class VmAbnormalLifeCycleStruct { public enum VmAbnormalLifeCycleOperation { - VmStoppedOnTheSameHost, - VmRunningFromIntermediateState, - VmStoppedFromIntermediateState, - VmPausedFromUnknownStateHostNotChanged, - VmRunningFromUnknownStateHostNotChanged, - VmRunningFromUnknownStateHostChanged, - VmStoppedFromUnknownStateHostNotChanged, - VmStoppedFromPausedStateHostNotChanged, - VmMigrateToAnotherHost, - VmRunningOnTheHost, - VmRunningFromDestroyed, - VmPausedFromRunningStateHostNotChanged, - VmRunningFromPausedStateHostNotChanged, - VmPausedFromStoppedStateHostNotChanged, - VmPausedFromMigratingStateHostNotChanged, - VmCrashedFromRunningStateHostNotChanged, - VmRunningFromCrashedStateHostNotChanged, - VmStoppedFromCrashedStateHostNotChanged, + VmStoppedOnTheSameHost { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return (struct.getOriginalState() == VmInstanceState.Running + || struct.getOriginalState() == VmInstanceState.Starting + || struct.getOriginalState() == VmInstanceState.NoState + || struct.getOriginalState() == VmInstanceState.Unknown) + && struct.getCurrentState() == VmInstanceState.Stopped + && Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }, + VmRunningFromIntermediateState { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return VmInstanceState.intermediateStates.contains(struct.getOriginalState()) + && struct.getCurrentState() == VmInstanceState.Running; + } + }, + VmStoppedFromIntermediateState { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return VmInstanceState.intermediateStates.contains(struct.getOriginalState()) + && struct.getCurrentState() == VmInstanceState.Stopped; + } + }, + VmPausedFromUnknownStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Unknown + && struct.getCurrentState() == VmInstanceState.Paused + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmRunningFromUnknownStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Unknown + && struct.getCurrentState() == VmInstanceState.Running + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmRunningFromUnknownStateHostChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Unknown + && struct.getCurrentState() == VmInstanceState.Running + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmStoppedFromUnknownStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Unknown + && struct.getCurrentState() == VmInstanceState.Stopped + && struct.getOriginalHostUuid() == null + && struct.getCurrentHostUuid().equals(struct.getVmLastHostUuid()); + } + }, + VmStoppedFromPausedStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Paused + && struct.getCurrentState() == VmInstanceState.Stopped + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmMigrateToAnotherHost { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Running + && struct.getOriginalState() == struct.getCurrentState() + && !Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }, + VmRunningOnTheHost { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Stopped + && (struct.getCurrentState() == VmInstanceState.Running + || struct.getCurrentState() == VmInstanceState.Paused); + } + }, + VmRunningFromDestroyed { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Destroyed && + (struct.getCurrentState() == VmInstanceState.Running + || struct.getCurrentState() == VmInstanceState.Paused); + } + }, + VmPausedFromRunningStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Running + && struct.getCurrentState() == VmInstanceState.Paused + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmRunningFromPausedStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Paused + && struct.getCurrentState() == VmInstanceState.Running + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmPausedFromMigratingStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Migrating + && struct.getCurrentState() == VmInstanceState.Paused + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmCrashedFromRunningStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Running + && struct.getCurrentState() == VmInstanceState.Crashed + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmRunningFromCrashedStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Crashed + && struct.getCurrentState() == VmInstanceState.Running + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmRunningWithoutOriginalHost { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Running + && struct.getCurrentState() == VmInstanceState.Running + && struct.getOriginalHostUuid() == null; + } + }, + VmStoppedFromCrashedStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Crashed + && struct.getCurrentState() == VmInstanceState.Stopped + && struct.getCurrentHostUuid().equals(struct.getOriginalHostUuid()); + } + }, + VmNoStateFromRunningStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Running + && struct.getCurrentState() == VmInstanceState.NoState + && Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }, + VmNoStateFromUnknownStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Unknown + && struct.getCurrentState() == VmInstanceState.NoState + && Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }, + VmNoStateFromCrashedStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Crashed + && struct.getCurrentState() == VmInstanceState.NoState + && Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }, + VmNoStateFromIntermediateState { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return VmInstanceState.intermediateStates.contains(struct.getOriginalState()) + && struct.getCurrentState() == VmInstanceState.NoState + && Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }, + VmNoStateFromStoppedStateHostNotChanged { + @Override + boolean match(VmAbnormalLifeCycleStruct struct) { + return struct.getOriginalState() == VmInstanceState.Stopped + && struct.getCurrentState() == VmInstanceState.NoState + && Objects.equals(struct.getCurrentHostUuid(), struct.getOriginalHostUuid()); + } + }; + + abstract boolean match(VmAbnormalLifeCycleStruct struct); + } + + public static VmAbnormalLifeCycleOperation getVmAbnormalLifeCycleOperationFromStruct( + VmAbnormalLifeCycleStruct struct) { + return Arrays.stream(VmAbnormalLifeCycleOperation.values()) + .filter(operation -> operation.match(struct)) + .findFirst() + .orElse(null); + } + + public static VmAbnormalLifeCycleOperation getVmAbnormalLifeCycleOperation( + String lastHostUuid, + VmInstanceState originalState, + VmInstanceState currentState, + String originalHostUuid, + String currentHostUuid) { + VmAbnormalLifeCycleStruct struct = new VmAbnormalLifeCycleStruct(); + struct.setCurrentHostUuid(currentHostUuid); + struct.setCurrentState(currentState); + struct.setOriginalHostUuid(originalHostUuid); + struct.setOriginalState(originalState); + struct.setVmLastHostUuid(lastHostUuid); + return getVmAbnormalLifeCycleOperationFromStruct(struct); } private VmAbnormalLifeCycleOperation operation; @@ -32,6 +229,8 @@ public enum VmAbnormalLifeCycleOperation { private VmInstanceState originalState; private VmInstanceState currentState; + private String vmLastHostUuid; + public VmAbnormalLifeCycleOperation getOperation() { return operation; } @@ -79,4 +278,12 @@ public VmInstanceState getCurrentState() { public void setCurrentState(VmInstanceState currentState) { this.currentState = currentState; } + + public String getVmLastHostUuid() { + return vmLastHostUuid; + } + + public void setVmLastHostUuid(String vmLastHostUuid) { + this.vmLastHostUuid = vmLastHostUuid; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java new file mode 100644 index 00000000000..1e553790aa1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmAfterAttachNicExtensionPoint.java @@ -0,0 +1,13 @@ +package org.zstack.header.vm; + +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; + +/** + * Created by LiangHanYu on 2022/4/13 13:24 + */ +public interface VmAfterAttachNicExtensionPoint { + void afterAttachNic(String nicUuid, VmInstanceInventory vmInstanceInventory, Completion completion); + + void afterAttachNicRollback(String nicUuid, VmInstanceInventory vmInstanceInventory, NoErrorCompletion completion); +} diff --git a/header/src/main/java/org/zstack/header/vm/VmAttachNicOnHypervisorReply.java b/header/src/main/java/org/zstack/header/vm/VmAttachNicOnHypervisorReply.java index 6c40ee2c002..325f4110024 100755 --- a/header/src/main/java/org/zstack/header/vm/VmAttachNicOnHypervisorReply.java +++ b/header/src/main/java/org/zstack/header/vm/VmAttachNicOnHypervisorReply.java @@ -1,8 +1,20 @@ package org.zstack.header.vm; import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.devices.VirtualDeviceInfo; + +import java.util.List; /** */ public class VmAttachNicOnHypervisorReply extends MessageReply { + List virtualDeviceInfoList; + + public List getVirtualDeviceInfoList() { + return virtualDeviceInfoList; + } + + public void setVirtualDeviceInfoList(List virtualDeviceInfoList) { + this.virtualDeviceInfoList = virtualDeviceInfoList; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmAttachOtherDiskExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmAttachOtherDiskExtensionPoint.java new file mode 100644 index 00000000000..46c6dd4a7ad --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmAttachOtherDiskExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.vm; + +import org.zstack.header.core.Completion; + +public interface VmAttachOtherDiskExtensionPoint { + void attachOtherDiskToVm(APICreateVmInstanceMsg.DiskAO diskAO, String vmInstanceUuid, Completion completion); + String getDiskType(); +} diff --git a/header/src/main/java/org/zstack/header/vm/VmAttachVolumeExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmAttachVolumeExtensionPoint.java index bbf824de9f7..1627fa0e77c 100755 --- a/header/src/main/java/org/zstack/header/vm/VmAttachVolumeExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/vm/VmAttachVolumeExtensionPoint.java @@ -1,5 +1,6 @@ package org.zstack.header.vm; +import org.zstack.header.core.Completion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.volume.VolumeInventory; @@ -9,11 +10,23 @@ * Created by frank on 6/10/2015. */ public interface VmAttachVolumeExtensionPoint { - void preAttachVolume(VmInstanceInventory vm, VolumeInventory volume); + default void preAttachVolume(VmInstanceInventory vm, VolumeInventory volume) {} + + default void preAttachVolume(VmInstanceInventory vm, VolumeInventory volume, Completion completion) { + preAttachVolume(vm, volume); + completion.success(); + } void beforeAttachVolume(VmInstanceInventory vm, VolumeInventory volume, Map data); - void afterInstantiateVolume(VmInstanceInventory vm, VolumeInventory volume); + default void afterInstantiateVolume(VmInstanceInventory vm, VolumeInventory volume) {} + + default void afterInstantiateVolume(VmInstanceInventory vm, VolumeInventory volume, Completion completion) { + afterInstantiateVolume(vm, volume); + completion.success(); + } + + default void afterInstantiateVolumeForNewCreatedVm(VmInstanceInventory vm, VolumeInventory volume) {} void afterAttachVolume(VmInstanceInventory vm, VolumeInventory volume); diff --git a/header/src/main/java/org/zstack/header/vm/VmCanonicalEvents.java b/header/src/main/java/org/zstack/header/vm/VmCanonicalEvents.java index c67a5e3ffb3..e6fe6a92272 100755 --- a/header/src/main/java/org/zstack/header/vm/VmCanonicalEvents.java +++ b/header/src/main/java/org/zstack/header/vm/VmCanonicalEvents.java @@ -14,7 +14,12 @@ public class VmCanonicalEvents { public static final String VM_INSTANCE_OFFERING_CHANGED_PATH = "/vm/instanceoffering/change"; public static final String VM_CONFIG_CHANGED_PATH = "/vm/config/change"; public static final String VM_LIBVIRT_REPORT_REBOOT = "/vm/libvirtReportReboot"; + public static final String VM_LIBVIRT_REPORT_START = "/vm/libvirtReportStart"; public static final String VM_LIBVIRT_REPORT_CRASH = "/vm/libvirtReportCrash"; + public static final String VM_NIC_INFO_CHANGED_PATH = "/vm/nicinfo/change"; + public static final String VM_NIC_INFO_DUPLICATE_PATH = "/vm/nicinfo/duplicate"; + public static final String VM_NIC_INFO_IPRANGE_CONFLICT_PATH = "/vm/nicinfo/iprangeConflict"; + public static final String VM_GPU_STATUS_ABNORMAL = "/vm/gpu/status/abnormal"; @NeedJsonSchema public static class VmCrashReportData { @@ -193,4 +198,155 @@ public void setNewState(String newState) { this.newState = newState; } } + + @NeedJsonSchema + public static class VmInternalIpChangedData { + private String vmUuid; + private String l3NetworkUuid; + private String oldInternalIp; + private String newInternalIp; + private String relateResourceUuid; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getOldInternalIp() { + return oldInternalIp; + } + + public void setOldInternalIp(String oldInternalIp) { + this.oldInternalIp = oldInternalIp; + } + + public String getNewInternalIp() { + return newInternalIp; + } + + public void setNewInternalIp(String newInternalIp) { + this.newInternalIp = newInternalIp; + } + + public String getRelateResourceUuid() { + return relateResourceUuid; + } + + public void setRelateResourceUuid(String relateResourceUuid) { + this.relateResourceUuid = relateResourceUuid; + } + } + + @NeedJsonSchema + public static class VmInternalIpDuplicateData { + private String vmUuid; + private String l3NetworkUuid; + private String internalIp; + private String relateResourceUuid; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getInternalIp() { + return internalIp; + } + + public void setInternalIp(String internalIp) { + this.internalIp = internalIp; + } + + public String getRelateResourceUuid() { + return relateResourceUuid; + } + + public void setRelateResourceUuid(String relateResourceUuid) { + this.relateResourceUuid = relateResourceUuid; + } + } + + @NeedJsonSchema + public static class VmInternalIpRangeConflictData { + private String vmUuid; + private String l3NetworkUuid; + private String internalIp; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getInternalIp() { + return internalIp; + } + + public void setInternalIp(String internalIp) { + this.internalIp = internalIp; + } + } + + @NeedJsonSchema + public static class VmGpuStatusAbnormalData { + private String vmUuid; + private String pciDeviceAddress; + private String status; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public String getPciDeviceAddress() { + return pciDeviceAddress; + } + + public void setPciDeviceAddress(String pciDeviceAddress) { + this.pciDeviceAddress = pciDeviceAddress; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmCapabilitiesDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/VmCapabilitiesDoc_zh_cn.groovy new file mode 100644 index 00000000000..a6d208d5d32 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmCapabilitiesDoc_zh_cn.groovy @@ -0,0 +1,33 @@ +package org.zstack.header.vm + +import org.zstack.header.vm.VmCapabilities + +doc { + + title "云主机能力" + + field { + name "supportLiveMigration" + desc "是否支持热迁移" + type "boolean" + since "3.1.0" + } + field { + name "supportVolumeMigration" + desc "是否支持卷迁移" + type "boolean" + since "3.1.0" + } + field { + name "supportReimage" + desc "是否支持重装" + type "boolean" + since "3.1.0" + } + field { + name "supportMemorySnapshot" + desc "是否支持内存快照" + type "boolean" + since "3.1.0" + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmDetachVolumeExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmDetachVolumeExtensionPoint.java index d9bf804aa6a..411d54ccbbd 100755 --- a/header/src/main/java/org/zstack/header/vm/VmDetachVolumeExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/vm/VmDetachVolumeExtensionPoint.java @@ -8,9 +8,11 @@ * Created by frank on 6/10/2015. */ public interface VmDetachVolumeExtensionPoint { - void preDetachVolume(VmInstanceInventory vm, VolumeInventory volume); + default void preDetachVolume(VmInstanceInventory vm, VolumeInventory volume, Completion completion) { + completion.success(); + } - void beforeDetachVolume(VmInstanceInventory vm, VolumeInventory volume); + default void beforeDetachVolume(VmInstanceInventory vm, VolumeInventory volume){} void afterDetachVolume(VmInstanceInventory vm, VolumeInventory volume, Completion completion); diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceAO.java b/header/src/main/java/org/zstack/header/vm/VmInstanceAO.java index ef437bee9ad..001dbe2298b 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceAO.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceAO.java @@ -74,6 +74,9 @@ public class VmInstanceAO extends ResourceVO { @Column private long memorySize; + @Column + private long reservedMemorySize; + @Column private String platform; @@ -117,12 +120,14 @@ public VmInstanceAO(VmInstanceAO other) { this.cpuNum = other.cpuNum; this.cpuSpeed = other.cpuSpeed; this.memorySize = other.memorySize; + this.reservedMemorySize = other.getReservedMemorySize(); this.allocatorStrategy = other.allocatorStrategy; this.createDate = other.createDate; this.lastOpDate = other.lastOpDate; this.state = other.state; this.platform = other.platform; this.guestOsType = other.guestOsType; + this.architecture = other.architecture; } @PreUpdate @@ -170,6 +175,14 @@ public void setMemorySize(long memorySize) { this.memorySize = memorySize; } + public long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public String getDefaultL3NetworkUuid() { return defaultL3NetworkUuid; } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceAO_.java b/header/src/main/java/org/zstack/header/vm/VmInstanceAO_.java index fbfce95af8b..90dee2c2ef6 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceAO_.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceAO_.java @@ -26,6 +26,7 @@ public class VmInstanceAO_ extends ResourceVO_ { public static volatile SingularAttribute allocatorStrategy; public static volatile SingularAttribute internalId; public static volatile SingularAttribute memorySize; + public static volatile SingularAttribute reservedMemorySize; public static volatile SingularAttribute cpuNum; public static volatile SingularAttribute cpuSpeed; public static volatile SingularAttribute createDate; diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceConstant.java b/header/src/main/java/org/zstack/header/vm/VmInstanceConstant.java index 1332c0f4033..896e60e414e 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceConstant.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceConstant.java @@ -8,6 +8,7 @@ public interface VmInstanceConstant { String ACTION_CATEGORY = "instance"; @PythonClass String USER_VM_TYPE = "UserVm"; + String APPLIANCE_VM_TYPE = "ApplianceVm"; Integer VM_MONITOR_NUMBER = 1; // System limit @@ -17,6 +18,11 @@ public interface VmInstanceConstant { String VIRTUAL_NIC_TYPE = "VNIC"; + String VM_SYNC_SIGNATURE_PREFIX = "Vm-"; + + String L2_TF_VSWITCH_TYPE = "TfL2Network"; + String TF_VIRTUAL_NIC_TYPE = "TFVNIC"; + enum Params { VmInstanceSpec, AttachingVolumeInventory, @@ -32,11 +38,16 @@ enum Params { L3NetworkInventory, UsedIPInventory, vmInventory, + vmInstanceUuid, VmAllocateNicFlow_ips, VmAllocateNicFlow_nics, VmAllocateNicFlow_allowDuplicatedAddress, + VmAllocateNicFlow_nicNetworkInfo, ApplianceVmSyncHaConfig_applianceVm, ApplianceVmSyncHaConfig_haUuid, + AllocatedUrlForAttachingVolume, + + VmInstanceUuid, } enum VmOperation { @@ -51,7 +62,9 @@ enum VmOperation { AttachVolume, AttachNic, ChangeNicNetwork, + ChangeNicIp, DetachNic, + ChangeNicState, AttachIso, DetachIso, Expunge, @@ -74,4 +87,10 @@ enum Capability { String EMPTY_CDROM = "empty"; String NONE_CDROM = "none"; + + String MEMORY_ACCESS_MODE_SHARED = "shared"; + String MEMORY_ACCESS_MODE_PRIVATE = "private"; + + Long VM_NIC_QOS_MIN = 8000L; + Long VM_NIC_QOS_MAX = 30000000000L; } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceInventory.java b/header/src/main/java/org/zstack/header/vm/VmInstanceInventory.java index ac6710d2e02..3042c96636b 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceInventory.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceInventory.java @@ -217,6 +217,8 @@ public class VmInstanceInventory implements Serializable, Cloneable { private Long memorySize; + private Long reservedMemorySize; + private Integer cpuNum; private Long cpuSpeed; @@ -294,6 +296,11 @@ protected VmInstanceInventory(VmInstanceVO vo) { this.setCpuNum(vo.getCpuNum()); this.setCpuSpeed(vo.getCpuSpeed()); this.setMemorySize(vo.getMemorySize()); + if (vo.getReservedMemorySize() == 0) { + this.setReservedMemorySize(null); + } else { + this.setReservedMemorySize(vo.getReservedMemorySize()); + } this.setAllocatorStrategy(vo.getAllocatorStrategy()); this.setPlatform(vo.getPlatform()); this.setArchitecture(vo.getArchitecture()); @@ -380,6 +387,7 @@ public VmInstanceInventory(VmInstanceInventory origin) { this.setCpuNum(inv.getCpuNum()); this.setCpuSpeed(inv.getCpuSpeed()); this.setMemorySize(inv.getMemorySize()); + this.setReservedMemorySize(inv.getReservedMemorySize()); this.setAllocatorStrategy(inv.getAllocatorStrategy()); this.setArchitecture(inv.getArchitecture()); this.setGuestOsType(inv.getGuestOsType()); @@ -411,6 +419,14 @@ public void setMemorySize(Long memorySize) { this.memorySize = memorySize; } + public Long getReservedMemorySize() { + return reservedMemorySize; + } + + public void setReservedMemorySize(Long reservedMemorySize) { + this.reservedMemorySize = reservedMemorySize; + } + public Integer getCpuNum() { return cpuNum; } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/VmInstanceInventoryDoc_zh_cn.groovy index fda6f8a6b9d..130414f677d 100644 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceInventoryDoc_zh_cn.groovy @@ -7,10 +7,11 @@ import java.sql.Timestamp import java.sql.Timestamp import org.zstack.header.vm.VmNicInventory import org.zstack.header.volume.VolumeInventory +import org.zstack.header.vm.cdrom.VmCdRomInventory doc { - title "在这里输入结构的名称" + title "云主机实例清单" field { name "uuid" @@ -78,6 +79,12 @@ doc { type "String" since "0.6" } + field { + name "architecture" + desc "" + type "String" + since "0.6" + } field { name "defaultL3NetworkUuid" desc "" @@ -154,4 +161,18 @@ doc { since "0.6" clz VolumeInventory.class } + ref { + name "vmCdRoms" + path "org.zstack.header.vm.VmInstanceInventory.vmCdRoms" + desc "null" + type "List" + since "0.6" + clz VmCdRomInventory.class + } + field { + name "guestOsType" + desc "" + type "String" + since "4.1.2" + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceMigrateExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmInstanceMigrateExtensionPoint.java index a5576c9aa92..705483bd0a3 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceMigrateExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceMigrateExtensionPoint.java @@ -1,13 +1,37 @@ package org.zstack.header.vm; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.errorcode.ErrorCode; public interface VmInstanceMigrateExtensionPoint { - void preMigrateVm(VmInstanceInventory inv, String destHostUuid); + default void preMigrateVm(VmInstanceInventory inv, String destHostUuid) {}; + + default void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { + preMigrateVm(inv, destHostUuid); + completion.success(); + } void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid); - void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid); + default void postMigrateVm(VmInstanceInventory inv, String destHostUuid) {} + + default void postMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { + postMigrateVm(inv, destHostUuid); + completion.success(); + } + + default void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) {} + + default void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid, NoErrorCompletion completion) { + afterMigrateVm(inv, srcHostUuid); + completion.done(); + } + + default void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) {}; - void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason); + default void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason, NoErrorCompletion completion) { + failedToMigrateVm(inv, destHostUuid, reason); + completion.done(); + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceNicFactory.java b/header/src/main/java/org/zstack/header/vm/VmInstanceNicFactory.java index d8318b9fed7..44ce4a8831e 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceNicFactory.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceNicFactory.java @@ -1,12 +1,13 @@ package org.zstack.header.vm; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.l3.UsedIpInventory; import java.util.List; public interface VmInstanceNicFactory { VmNicType getType(); - VmNicVO createVmNic(VmNicInventory inv, VmInstanceSpec spec, List ips); + VmNicVO createVmNic(VmNicInventory inv, VmInstanceSpec spec); static VmNicVO createVmNic(VmNicInventory nic) { VmNicVO vnic = new VmNicVO(); @@ -23,6 +24,8 @@ static VmNicVO createVmNic(VmNicInventory nic) { vnic.setIpVersion(nic.getIpVersion()); vnic.setInternalName(nic.getInternalName()); vnic.setDriverType(nic.getDriverType()); + vnic.setMetaData(nic.getMetaData()); + vnic.setState(VmNicState.fromState(nic.getState())); return vnic; } @@ -33,4 +36,8 @@ default boolean addFdbForEipNameSpace(VmNicInventory nic) { default String getPhysicalNicName(VmNicInventory nic) { return null; } + + default void releaseVmNic(VmNicInventory nic) { + return; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceResumeExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmInstanceResumeExtensionPoint.java new file mode 100644 index 00000000000..bd938eaa18f --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceResumeExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.vm; + +public interface VmInstanceResumeExtensionPoint { + void afterResumeVm(VmInstanceInventory inv); +} diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceSpec.java b/header/src/main/java/org/zstack/header/vm/VmInstanceSpec.java index ea0947de320..96da4293fa8 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceSpec.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceSpec.java @@ -1,9 +1,11 @@ package org.zstack.header.vm; +import org.apache.commons.collections.CollectionUtils; import org.zstack.header.allocator.AllocationScene; import org.zstack.header.configuration.DiskOfferingInventory; import org.zstack.header.host.HostInventory; import org.zstack.header.image.ImageBackupStorageRefInventory; +import org.zstack.header.image.ImageConstant; import org.zstack.header.image.ImageInventory; import org.zstack.header.log.NoLogging; import org.zstack.header.message.Message; @@ -11,15 +13,13 @@ import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.storage.primary.PrimaryStorageInventory; import org.zstack.header.vm.VmInstanceConstant.VmOperation; +import org.zstack.header.volume.VolumeFormat; import org.zstack.header.volume.VolumeInventory; import org.zstack.header.volume.VolumeType; import org.zstack.utils.JsonWrapper; import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class VmInstanceSpec implements Serializable { @@ -48,6 +48,15 @@ public static class VolumeSpec { private boolean isVolumeCreated; private List tags; private String allocatedInstallUrl; + private String associatedVolumeUuid; + + public String getAssociatedVolumeUuid() { + return associatedVolumeUuid; + } + + public void setAssociatedVolumeUuid(String associatedVolumeUuid) { + this.associatedVolumeUuid = associatedVolumeUuid; + } public String getAllocatedInstallUrl() { return allocatedInstallUrl; @@ -139,6 +148,18 @@ public boolean isNeedDownload() { public void setNeedDownload(boolean needDownload) { this.needDownload = needDownload; } + + public boolean relyOnImageCache() { + return !needDownload && inventory != null && CollectionUtils.isEmpty(inventory.getBackupStorageRefs()); + } + + public boolean isIso() { + return inventory != null && ImageConstant.ImageMediaType.ISO.toString().equals(inventory.getMediaType()); + } + + public boolean relayOnImage() { + return inventory != null; + } } public static class IsoSpec implements Serializable { @@ -146,6 +167,7 @@ public static class IsoSpec implements Serializable { private String imageUuid; private String primaryStorageUuid; private String backupStorageUuid; + private String protocol; private int deviceId; public String getBackupStorageUuid() { @@ -180,6 +202,14 @@ public void setInstallPath(String installPath) { this.installPath = installPath; } + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return protocol; + } + public int getDeviceId() { return deviceId; } @@ -196,6 +226,7 @@ public static class CdRomSpec implements Serializable { private String imageUuid; private String primaryStorageUuid; private String backupStorageUuid; + private String protocol; public boolean isAttachedIso() { return imageUuid != null; @@ -248,6 +279,14 @@ public int getDeviceId() { public void setDeviceId(int deviceId) { this.deviceId = deviceId; } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return protocol; + } } public static class HostName implements Serializable { @@ -283,12 +322,15 @@ public void setHostname(String hostname) { private ImageSpec imageSpec = new ImageSpec(); private List volumeSpecs = new ArrayList<>(); private String requiredClusterUuid; + private List requiredClusterUuids; private String requiredHostUuid; private List softAvoidHostUuids; private List avoidHostUuids; private String memorySnapshotUuid; - private String requiredPrimaryStorageUuidForRootVolume; - private String requiredPrimaryStorageUuidForDataVolume; + private String allocatedPrimaryStorageUuidForRootVolume; + private String allocatedPrimaryStorageUuidForDataVolume; + private final List candidatePrimaryStorageUuidsForRootVolume = new ArrayList<>(); + private final List candidatePrimaryStorageUuidsForDataVolume = new ArrayList<>(); private String bootMode; private List hostnames = new ArrayList<>(); @@ -309,6 +351,7 @@ public void setHostname(String hostname) { private boolean gcOnStopFailure; private boolean ignoreResourceReleaseFailure; private boolean usbRedirect = false; + private boolean enableSecurityElement = false; private String enableRDP = "false"; private String VDIMonitorNumber = "1"; @NoLogging @@ -321,8 +364,54 @@ public void setHostname(String hostname) { private List rootVolumeSystemTags; private List dataVolumeSystemTags; + private Map> dataVolumeSystemTagsOnIndex; private boolean skipIpAllocation = false; + // if true, implementation will be required to offer debug info during operation + private boolean debug; + private VmCreationStrategy strategy; + + public List getRequiredClusterUuids() { + return requiredClusterUuids; + } + + public void setRequiredClusterUuids(List requiredClusterUuids) { + this.requiredClusterUuids = requiredClusterUuids; + } + + public List getCandidatePrimaryStorageUuidsForRootVolume() { + return candidatePrimaryStorageUuidsForRootVolume; + } + + public void setCandidatePrimaryStorageUuidsForRootVolume(List candidatePrimaryStorageUuidsForRootVolume) { + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (candidatePrimaryStorageUuidsForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.addAll(candidatePrimaryStorageUuidsForRootVolume); + } + } + + public List getCandidatePrimaryStorageUuidsForDataVolume() { + return candidatePrimaryStorageUuidsForDataVolume; + } + + public void setCandidatePrimaryStorageUuidsForDataVolume(List candidatePrimaryStorageUuidsForDataVolume) { + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (candidatePrimaryStorageUuidsForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.addAll(candidatePrimaryStorageUuidsForDataVolume); + } + } + + private List disableL3Networks; + private List diskAOs; + + public List getDiskAOs() { + return diskAOs; + } + + public void setDiskAOs(List diskAOs) { + this.diskAOs = diskAOs; + } + public boolean isSkipIpAllocation() { return skipIpAllocation; } @@ -362,6 +451,14 @@ public boolean isUsbRedirect() { public void setUsbRedirect(boolean usbRedirect) { this.usbRedirect = usbRedirect; } + + public boolean isEnableSecurityElement() { + return enableSecurityElement; + } + + public void setEnableSecurityElement(boolean enableSecurityElement) { + this.enableSecurityElement = enableSecurityElement; + } public void setCreatePaused(boolean createPaused) { this.createPaused = createPaused; @@ -474,6 +571,15 @@ public List getVolumeSpecs() { return volumeSpecs; } + public String getAllocatedUrlFromVolumeSpecs(String associatedVolumeUuid) { + VolumeSpec vspec = volumeSpecs.stream() + .filter(v -> associatedVolumeUuid.equals(v.getAssociatedVolumeUuid())) + .findFirst() + .orElse(null); + + return vspec != null ? vspec.getAllocatedInstallUrl() : null; + } + public void setVolumeSpecs(List volumeSpecs) { this.volumeSpecs = volumeSpecs; } @@ -634,20 +740,28 @@ public List getRequiredNetworkServiceTypes() { return nsTypes; } + @Deprecated public String getRequiredPrimaryStorageUuidForRootVolume() { - return requiredPrimaryStorageUuidForRootVolume; + return this.candidatePrimaryStorageUuidsForRootVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForRootVolume.get(0); } - public void setRequiredPrimaryStorageUuidForRootVolume(String requiredPrimaryStorageUuidForRootVolume) { - this.requiredPrimaryStorageUuidForRootVolume = requiredPrimaryStorageUuidForRootVolume; + public void setRequiredPrimaryStorageUuidForRootVolume(String primaryStorageUuidForRootVolume) { + this.candidatePrimaryStorageUuidsForRootVolume.clear(); + if (primaryStorageUuidForRootVolume != null) { + this.candidatePrimaryStorageUuidsForRootVolume.add(primaryStorageUuidForRootVolume); + } } + @Deprecated public String getRequiredPrimaryStorageUuidForDataVolume() { - return requiredPrimaryStorageUuidForDataVolume; + return this.candidatePrimaryStorageUuidsForDataVolume.isEmpty() ? null : this.candidatePrimaryStorageUuidsForDataVolume.get(0); } - public void setRequiredPrimaryStorageUuidForDataVolume(String requiredPrimaryStorageUuidForDataVolume) { - this.requiredPrimaryStorageUuidForDataVolume = requiredPrimaryStorageUuidForDataVolume; + public void setRequiredPrimaryStorageUuidForDataVolume(String primaryStorageUuidForDataVolume) { + this.candidatePrimaryStorageUuidsForDataVolume.clear(); + if (primaryStorageUuidForDataVolume != null) { + this.candidatePrimaryStorageUuidsForDataVolume.add(primaryStorageUuidForDataVolume); + } } public HostInventory getSrcHost() { @@ -682,6 +796,14 @@ public void setDataVolumeSystemTags(List dataVolumeSystemTags) { this.dataVolumeSystemTags = dataVolumeSystemTags; } + public Map> getDataVolumeSystemTagsOnIndex() { + return dataVolumeSystemTagsOnIndex; + } + + public void setDataVolumeSystemTagsOnIndex(Map> dataVolumeSystemTagsOnIndex) { + this.dataVolumeSystemTagsOnIndex = dataVolumeSystemTagsOnIndex; + } + public boolean isInstantiateResourcesSuccess() { return instantiateResourcesSuccess; } @@ -705,4 +827,68 @@ public String getBootMode() { public void setBootMode(String bootMode) { this.bootMode = bootMode; } + + public long getRootDiskAllocateSize() { + if (rootDiskOffering == null) { + return this.getImageSpec().getInventory().getSize(); + } + return rootDiskOffering.getDiskSize(); + } + + public List getDisableL3Networks() { + return disableL3Networks; + } + + public void setDisableL3Networks(List disableL3Networks) { + this.disableL3Networks = disableL3Networks; + } + + public String getAllocatedPrimaryStorageUuidForRootVolume() { + return allocatedPrimaryStorageUuidForRootVolume; + } + + public void setAllocatedPrimaryStorageUuidForRootVolume(String allocatedPrimaryStorageUuidForRootVolume) { + this.allocatedPrimaryStorageUuidForRootVolume = allocatedPrimaryStorageUuidForRootVolume; + } + + public String getAllocatedPrimaryStorageUuidForDataVolume() { + return allocatedPrimaryStorageUuidForDataVolume; + } + + public void setAllocatedPrimaryStorageUuidForDataVolume(String allocatedPrimaryStorageUuidForDataVolume) { + this.allocatedPrimaryStorageUuidForDataVolume = allocatedPrimaryStorageUuidForDataVolume; + } + + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public VmCreationStrategy getStrategy() { + return strategy; + } + + public void setStrategy(VmCreationStrategy strategy) { + this.strategy = strategy; + } + + public String getVolumeFormatFromImage() { + ImageSpec image = getImageSpec(); + // if no image is specified, use default format + if (!image.relayOnImage()) { + return ImageConstant.QCOW2_FORMAT_STRING; + } + + if (image.isIso()) { + return VolumeFormat.getVolumeFormatByMasterHypervisorType(getDestHost().getHypervisorType()).toString(); + } else if (image.getInventory().getFormat() != null) { + VolumeFormat imageFormat = VolumeFormat.valueOf(getImageSpec().getInventory().getFormat()); + return imageFormat.getOutputFormat(getDestHost().getHypervisorType()); + } else { + return ImageConstant.QCOW2_FORMAT_STRING; + } + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceState.java b/header/src/main/java/org/zstack/header/vm/VmInstanceState.java index 226a169b096..8a755b52fda 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceState.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceState.java @@ -3,10 +3,7 @@ import org.zstack.header.configuration.PythonClass; import org.zstack.header.exception.CloudRuntimeException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @PythonClass public enum VmInstanceState { @@ -26,11 +23,14 @@ public enum VmInstanceState { VolumeMigrating(VmInstanceStateEvent.volumeMigrating), VolumeRecovering(VmInstanceStateEvent.volumeRecovering), Error(null), + NoState(VmInstanceStateEvent.noState), Unknown(VmInstanceStateEvent.unknown), Crashed(VmInstanceStateEvent.crashed); public static List intermediateStates = new ArrayList(); + public static Set offlineStates = new HashSet<>(); + static { intermediateStates.add(Starting); intermediateStates.add(Stopping); @@ -42,6 +42,12 @@ public enum VmInstanceState { intermediateStates.add(VolumeMigrating); intermediateStates.add(VolumeRecovering); + offlineStates.add(Created); + offlineStates.add(Stopped); + offlineStates.add(Destroyed); + offlineStates.add(VolumeMigrating); + offlineStates.add(Crashed); + Created.transactions( new Transaction(VmInstanceStateEvent.starting, VmInstanceState.Starting), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying), @@ -66,6 +72,7 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.pausing, VmInstanceState.Pausing), new Transaction(VmInstanceStateEvent.paused, VmInstanceState.Paused), new Transaction(VmInstanceStateEvent.crashed, VmInstanceState.Crashed), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown) ); Stopping.transactions( @@ -82,6 +89,7 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying), new Transaction(VmInstanceStateEvent.volumeMigrating, VmInstanceState.VolumeMigrating), new Transaction(VmInstanceStateEvent.volumeRecovering, VmInstanceState.VolumeRecovering), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown) ); Migrating.transactions( @@ -90,27 +98,32 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), new Transaction(VmInstanceStateEvent.paused, VmInstanceState.Paused), new Transaction(VmInstanceStateEvent.stopped, VmInstanceState.Stopped), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying) ); VolumeMigrating.transactions( new Transaction(VmInstanceStateEvent.volumeMigrated, VmInstanceState.Stopped), new Transaction(VmInstanceStateEvent.stopped, VmInstanceState.Stopped), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying) ); VolumeRecovering.transactions( new Transaction(VmInstanceStateEvent.starting, VmInstanceState.VolumeRecovering), new Transaction(VmInstanceStateEvent.running, VmInstanceState.VolumeRecovering), + new Transaction(VmInstanceStateEvent.volumeRecovering, VmInstanceState.VolumeRecovering), new Transaction(VmInstanceStateEvent.volumeRecovered, VmInstanceState.Running), new Transaction(VmInstanceStateEvent.stopping, VmInstanceState.Stopping), new Transaction(VmInstanceStateEvent.stopped, VmInstanceState.Stopped), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying) ); Rebooting.transactions( new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), new Transaction(VmInstanceStateEvent.stopped, VmInstanceState.Stopped), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying) ); @@ -121,6 +134,7 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), new Transaction(VmInstanceStateEvent.stopping, VmInstanceState.Stopping), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown), new Transaction(VmInstanceStateEvent.migrating, VmInstanceState.Migrating), new Transaction(VmInstanceStateEvent.volumeMigrated, VmInstanceState.Running) @@ -129,12 +143,14 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.paused, VmInstanceState.Paused), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying), new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown) ); Resuming.transactions( new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying), new Transaction(VmInstanceStateEvent.paused, VmInstanceState.Paused), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown) ); Unknown.transactions( @@ -144,6 +160,7 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.paused,VmInstanceState.Paused), new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), new Transaction(VmInstanceStateEvent.migrating, VmInstanceState.Migrating), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.stopped, VmInstanceState.Stopped) ); Destroying.transactions( @@ -164,6 +181,18 @@ public enum VmInstanceState { new Transaction(VmInstanceStateEvent.rebooting, VmInstanceState.Rebooting), new Transaction(VmInstanceStateEvent.crashed, VmInstanceState.Crashed), new Transaction(VmInstanceStateEvent.destroyed, VmInstanceState.Destroyed), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), + new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying) + ); + NoState.transactions( + new Transaction(VmInstanceStateEvent.running, VmInstanceState.Running), + new Transaction(VmInstanceStateEvent.unknown, VmInstanceState.Unknown), + new Transaction(VmInstanceStateEvent.stopping, VmInstanceState.Stopping), + new Transaction(VmInstanceStateEvent.stopped, VmInstanceState.Stopped), + new Transaction(VmInstanceStateEvent.rebooting, VmInstanceState.Rebooting), + new Transaction(VmInstanceStateEvent.crashed, VmInstanceState.Crashed), + new Transaction(VmInstanceStateEvent.destroyed, VmInstanceState.Destroyed), + new Transaction(VmInstanceStateEvent.noState, VmInstanceState.NoState), new Transaction(VmInstanceStateEvent.destroying, VmInstanceState.Destroying) ); } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceStateEvent.java b/header/src/main/java/org/zstack/header/vm/VmInstanceStateEvent.java index c5e897583ec..56ed65d2d47 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceStateEvent.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceStateEvent.java @@ -25,4 +25,5 @@ public enum VmInstanceStateEvent { stopped, paused, crashed, + noState, } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceType.java b/header/src/main/java/org/zstack/header/vm/VmInstanceType.java index b7d7c1b16d2..e42d9cc82d5 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceType.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceType.java @@ -8,6 +8,8 @@ public class VmInstanceType { private static Map types = Collections.synchronizedMap(new HashMap()); private final String typeName; + private boolean supportUpdateOnHypervisor = true; + public VmInstanceType(String typeName) { this.typeName = typeName; types.put(typeName, this); @@ -40,4 +42,12 @@ public boolean equals(Object t) { public int hashCode() { return typeName.hashCode(); } + + public boolean isSupportUpdateOnHypervisor() { + return supportUpdateOnHypervisor; + } + + public void setSupportUpdateOnHypervisor(boolean supportUpdateOnHypervisor) { + this.supportUpdateOnHypervisor = supportUpdateOnHypervisor; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmInstanceVO.java b/header/src/main/java/org/zstack/header/vm/VmInstanceVO.java index 674201a57c9..39dc0607e25 100755 --- a/header/src/main/java/org/zstack/header/vm/VmInstanceVO.java +++ b/header/src/main/java/org/zstack/header/vm/VmInstanceVO.java @@ -8,8 +8,7 @@ import org.zstack.header.vm.cdrom.VmCdRomVO; import org.zstack.header.vo.*; import org.zstack.header.vo.EntityGraph; -import org.zstack.header.volume.VolumeInventory; -import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.*; import org.zstack.header.zone.ZoneVO; import javax.persistence.*; @@ -107,6 +106,13 @@ public Set getAllDiskVolumes() { return getAllVolumes(VolumeVO::isDisk); } + public VolumeVO getMemoryVolume() { + if (allVolumes == null) { + return null; + } + return allVolumes.stream().filter(v -> v.getType().equals(VolumeType.Memory)).findAny().orElse(null); + } + public VolumeVO getRootVolume() { if (allVolumes == null) { return null; @@ -115,6 +121,10 @@ public VolumeVO getRootVolume() { return allVolumes.stream().filter(v -> v.getUuid().equals(getRootVolumeUuid())).findAny().orElse(null); } + public Set getAllDataVolumes() { + return getAllVolumes(VolumeAO::isDataVolume); + } + public Set getVmCdRoms() { return vmCdRoms; } diff --git a/header/src/main/java/org/zstack/header/vm/VmMacVlanNicConstant.java b/header/src/main/java/org/zstack/header/vm/VmMacVlanNicConstant.java new file mode 100644 index 00000000000..0c4e869c537 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmMacVlanNicConstant.java @@ -0,0 +1,17 @@ +package org.zstack.header.vm; + +import org.zstack.header.configuration.PythonClass; +import org.zstack.header.network.l2.L2NetworkConstant; + +import java.util.Arrays; +import java.util.List; + +@PythonClass +public interface VmMacVlanNicConstant { + String MACVLAN_NIC_TYPE = "MACVLAN"; + + List MACVLAN_L2_NETWORK_TYPES = Arrays.asList( + L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE, + L2NetworkConstant.L2_VLAN_NETWORK_TYPE + ); +} diff --git a/header/src/main/java/org/zstack/header/vm/VmMigrationType.java b/header/src/main/java/org/zstack/header/vm/VmMigrationType.java new file mode 100644 index 00000000000..ca831553ef1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmMigrationType.java @@ -0,0 +1,6 @@ +package org.zstack.header.vm; + +public enum VmMigrationType { + HostMigration, + PrimaryStorageMigration, +} diff --git a/header/src/main/java/org/zstack/header/vm/VmNicChangeStateExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmNicChangeStateExtensionPoint.java new file mode 100644 index 00000000000..d4b83313adc --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmNicChangeStateExtensionPoint.java @@ -0,0 +1,8 @@ +package org.zstack.header.vm; + +/** + * Created by boce.wang on 12/14/22. + */ +public interface VmNicChangeStateExtensionPoint { + void afterChangeVmNicState(String vmNic, String state); +} diff --git a/header/src/main/java/org/zstack/header/vm/VmNicDriverType.java b/header/src/main/java/org/zstack/header/vm/VmNicDriverType.java new file mode 100644 index 00000000000..a47238e6038 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmNicDriverType.java @@ -0,0 +1,37 @@ +package org.zstack.header.vm; + +public enum VmNicDriverType { + VIRTIO("virtio"), + E1000_KVM("e1000"), + PCNET("pcnet"), + + E1000_ESX("E1000"), + VMXNET3("Vmxnet3"); + + private String type; + + VmNicDriverType(String type) { + this.type = type; + } + + boolean isKvmType() { + if (type.equals("virtio") || type.equals("e1000") || type.equals("pcnet")) { + return true; + } + + return false; + } + + boolean isESXType() { + if (type.equals("E1000") || type.equals("Vmxnet3")) { + return true; + } + + return false; + } + + @Override + public String toString() { + return type; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmNicHelper.java b/header/src/main/java/org/zstack/header/vm/VmNicHelper.java index da05cb368bf..48af03d6e69 100644 --- a/header/src/main/java/org/zstack/header/vm/VmNicHelper.java +++ b/header/src/main/java/org/zstack/header/vm/VmNicHelper.java @@ -67,11 +67,11 @@ public static boolean isL3AttachedToVmNic(VmNicInventory nic, String l3Uuid) { } } - if (nic.getL3NetworkUuid().equals(l3Uuid)) { - return true; + if (nic.getL3NetworkUuid() == null) { + return false; } - return false; + return nic.getL3NetworkUuid().equals(l3Uuid); } public static List getUsedIpUuids(VmNicInventory nic) { diff --git a/header/src/main/java/org/zstack/header/vm/VmNicInventory.java b/header/src/main/java/org/zstack/header/vm/VmNicInventory.java index 845ca765348..5ce7ef4a8eb 100755 --- a/header/src/main/java/org/zstack/header/vm/VmNicInventory.java +++ b/header/src/main/java/org/zstack/header/vm/VmNicInventory.java @@ -12,7 +12,9 @@ import java.sql.Timestamp; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; @Inventory(mappingVOClass = VmNicVO.class) @ExpandedQueries({ @@ -42,6 +44,7 @@ public class VmNicInventory implements Serializable { private String internalName; private Integer deviceId; private String type; + private String state; private Timestamp createDate; private Timestamp lastOpDate; @@ -66,6 +69,7 @@ public VmNicInventory(VmNicVO vo) { this.setUsedIps(UsedIpInventory.valueOf(vo.getUsedIps())); this.setDriverType(vo.getDriverType()); this.setType(vo.getType()); + this.setState(vo.getState().toString()); } public static VmNicInventory valueOf(VmNicVO vo) { @@ -74,6 +78,7 @@ public static VmNicInventory valueOf(VmNicVO vo) { public static List valueOf(Collection vos) { List invs = new ArrayList(vos.size()); + vos = vos.stream().sorted(Comparator.comparingInt(VmNicVO::getDeviceId)).collect(Collectors.toList()); for (VmNicVO vo : vos) { invs.add(VmNicInventory.valueOf(vo)); } @@ -233,4 +238,12 @@ public boolean isIpv6OnlyNic() { public boolean isIpv4OnlyNic() { return this.usedIps.size() == 1 && this.usedIps.get(0).getIpVersion() == IPv6Constants.IPv4; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmNicInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/VmNicInventoryDoc_zh_cn.groovy index e9bf22a6b17..9974647a021 100644 --- a/header/src/main/java/org/zstack/header/vm/VmNicInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/VmNicInventoryDoc_zh_cn.groovy @@ -2,8 +2,6 @@ package org.zstack.header.vm import java.lang.Integer import org.zstack.header.network.l3.UsedIpInventory -import java.lang.Integer -import java.sql.Timestamp import java.sql.Timestamp doc { @@ -14,92 +12,110 @@ doc { name "uuid" desc "资源的UUID,唯一标示该资源" type "String" - since "0.6" + since "4.7.13" } field { name "vmInstanceUuid" desc "云主机UUID" type "String" - since "0.6" + since "4.7.13" } field { name "l3NetworkUuid" desc "三层网络UUID" type "String" - since "0.6" + since "4.7.13" } field { name "ip" - desc "IP地址" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "mac" - desc "MAC地址" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "hypervisorType" - desc "虚拟化类型" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "netmask" - desc "子网掩码" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "gateway" - desc "网关" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "metaData" desc "" type "String" - since "0.6" + since "4.7.13" } field { name "ipVersion" - desc "IP地址版本" + desc "" type "Integer" - since "0.6" + since "4.7.13" + } + field { + name "driverType" + desc "" + type "String" + since "4.7.13" } ref { name "usedIps" path "org.zstack.header.vm.VmNicInventory.usedIps" desc "null" type "List" - since "0.6" + since "4.7.13" clz UsedIpInventory.class } + field { + name "internalName" + desc "" + type "String" + since "4.7.13" + } field { name "deviceId" - desc "设备ID" + desc "" type "Integer" - since "0.6" + since "4.7.13" } field { name "type" - desc "网卡类型" + desc "" + type "String" + since "4.7.13" + } + field { + name "state" + desc "网卡状态" type "String" - since "0.6" + since "4.7.13" } field { name "createDate" desc "创建时间" type "Timestamp" - since "0.6" + since "4.7.13" } field { name "lastOpDate" desc "最后一次修改时间" type "Timestamp" - since "0.6" + since "4.7.13" } } diff --git a/header/src/main/java/org/zstack/header/vm/VmNicParam.java b/header/src/main/java/org/zstack/header/vm/VmNicParam.java new file mode 100644 index 00000000000..174d417d43b --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmNicParam.java @@ -0,0 +1,205 @@ +package org.zstack.header.vm; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.rest.APINoSee; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@PythonClassInventory +public class VmNicParam implements Serializable { + private String l3NetworkUuid; + + private String mac; + + private String ip; + + private String netmask; + + private String gateway; + + private String ip6; + + private String prefix6; + + private String gateway6; + + private String metaData; + + private String driverType; + + private String VmNicType; + + private String state = VmNicState.enable.toString(); + + private Long outboundBandwidth; + + private Long inboundBandwidth; + + private Integer multiQueueNum; + + private Boolean isDefaultNic; + + private List sgUuids = new ArrayList<>(); + + @APINoSee + private Map IpMap = new HashMap<>(); /* filled for cloned vms more than 2 */ + + @APINoSee + private Map Ip6Map = new HashMap<>(); /* filled for cloned vms more than 2 */ + + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getMetaData() { + return metaData; + } + + public void setMetaData(String metaData) { + this.metaData = metaData; + } + + public String getDriverType() { + return driverType; + } + + public void setDriverType(String driverType) { + this.driverType = driverType; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Long getOutboundBandwidth() { + return outboundBandwidth; + } + + public void setOutboundBandwidth(Long outboundBandwidth) { + this.outboundBandwidth = outboundBandwidth; + } + + public Long getInboundBandwidth() { + return inboundBandwidth; + } + + public void setInboundBandwidth(Long inboundBandwidth) { + this.inboundBandwidth = inboundBandwidth; + } + + public Integer getMultiQueueNum() { + return multiQueueNum; + } + + public void setMultiQueueNum(Integer multiQueueNum) { + this.multiQueueNum = multiQueueNum; + } + + public String getIp6() { + return ip6; + } + + public void setIp6(String ip6) { + this.ip6 = ip6; + } + + public Boolean getDefaultNic() { + return isDefaultNic; + } + + public void setDefaultNic(Boolean defaultNic) { + this.isDefaultNic = defaultNic; + } + + public String getVmNicType() { + return VmNicType; + } + + public void setVmNicType(String vmNicType) { + VmNicType = vmNicType; + } + + public List getSgUuids() { + return sgUuids; + } + + public void setSgUuids(List sgUuids) { + this.sgUuids = sgUuids; + } + + public Map getIpMap() { + return IpMap; + } + + public void setIpMap(Map ipMap) { + IpMap = ipMap; + } + + public Map getIp6Map() { + return Ip6Map; + } + + public void setIp6Map(Map ip6Map) { + Ip6Map = ip6Map; + } + + public String getPrefix6() { + return prefix6; + } + + public void setPrefix6(String prefix6) { + this.prefix6 = prefix6; + } + + public String getGateway6() { + return gateway6; + } + + public void setGateway6(String gateway6) { + this.gateway6 = gateway6; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmNicSetDriverExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmNicSetDriverExtensionPoint.java new file mode 100644 index 00000000000..9d455af587f --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmNicSetDriverExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.vm; + +public interface VmNicSetDriverExtensionPoint { + String getPreferredVmNicDriver(VmInstanceInventory vm); +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/VmNicSpec.java b/header/src/main/java/org/zstack/header/vm/VmNicSpec.java index 869fdddddb9..6a932466506 100644 --- a/header/src/main/java/org/zstack/header/vm/VmNicSpec.java +++ b/header/src/main/java/org/zstack/header/vm/VmNicSpec.java @@ -14,6 +14,10 @@ public class VmNicSpec implements Serializable { public List l3Invs; public String nicDriverType; + //from api msg + /* due to the design changed, single nic will only has 1 l3 network */ + public List vmNicParams; + public VmNicSpec(List l3Invs) { this.l3Invs = l3Invs; } @@ -65,7 +69,7 @@ public static List getFirstL3NetworkInventoryOfSpec(List s List nicSpecs = new ArrayList<>(); for (VmNicSpec spec: specs) { if (spec.l3Invs != null && !spec.l3Invs.isEmpty()) { - nicSpecs.add(new VmNicSpec(spec.l3Invs.get(0), spec.getNicDriverType())); + nicSpecs.add(spec); } } return nicSpecs; @@ -80,4 +84,12 @@ public static List getL3UuidsOfSpec(List specs) { } return res; } + + public List getVmNicParams() { + return vmNicParams; + } + + public void setVmNicParams(List vmNicParams) { + this.vmNicParams = vmNicParams; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmNicState.java b/header/src/main/java/org/zstack/header/vm/VmNicState.java new file mode 100644 index 00000000000..ac2d85ef262 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmNicState.java @@ -0,0 +1,20 @@ +package org.zstack.header.vm; + +/** + * Created by boce.wang on 11/23/2022. + */ +public enum VmNicState { + enable, + disable; + + public static VmNicState fromState(String state) { + if (state.equals(VmNicState.enable.toString())) { + return VmNicState.enable; + } else if (state.equals(VmNicState.disable.toString())) { + return VmNicState.disable; + } else { + return VmNicState.enable; + } + } + +} diff --git a/header/src/main/java/org/zstack/header/vm/VmNicType.java b/header/src/main/java/org/zstack/header/vm/VmNicType.java index 31e40a2f615..3fd9612742a 100755 --- a/header/src/main/java/org/zstack/header/vm/VmNicType.java +++ b/header/src/main/java/org/zstack/header/vm/VmNicType.java @@ -1,38 +1,24 @@ package org.zstack.header.vm; -import org.zstack.header.network.l2.VSwitchType; - import java.util.*; public class VmNicType { + public enum VmNicSubType { + NONE, + SRIOV, + VHOSTUSER, + } private static Map types = Collections.synchronizedMap(new HashMap<>()); - private static Map vSwitchAndSriovTypes = Collections.synchronizedMap(new HashMap<>()); private final String typeName; + private boolean hasAddon = false; + private boolean useSRIOV = false; public VmNicType(String typeName) { this.typeName = typeName; types.put(typeName, this); } - public VmNicType(String typeName, String vSwitchType) { - this.typeName = typeName; - types.put(typeName, this); - vSwitchAndSriovTypes.put(vSwitchType, typeName); - } - - public VmNicType(String typeName, String vSwitchType, Boolean enableSriov) { - this.typeName = typeName; - types.put(typeName, this); - if (!enableSriov) { - vSwitchAndSriovTypes.put(vSwitchType, typeName); - }else{ - vSwitchType += "sriov"; - vSwitchAndSriovTypes.put(vSwitchType, typeName); - - } - } - public static VmNicType valueOf(String typeName) { VmNicType type = types.get(typeName); if (type == null) { @@ -41,17 +27,20 @@ public static VmNicType valueOf(String typeName) { return type; } - public static VmNicType valueOf(VSwitchType vSwitchType) { - String typeName = vSwitchAndSriovTypes.get(vSwitchType.toString()); - return valueOf(typeName); + public boolean isHasAddon() { + return hasAddon; } - public static VmNicType valueOf(VSwitchType vSwitchType, Boolean enableSriov) { - String typeName = vSwitchAndSriovTypes.get(vSwitchType.toString()); - if (enableSriov) { - typeName = vSwitchAndSriovTypes.get(vSwitchType + "sriov"); - } - return valueOf(typeName); + public void setHasAddon(boolean hasAddon) { + this.hasAddon = hasAddon; + } + + public boolean isUseSRIOV() { + return useSRIOV; + } + + public void setUseSRIOV(boolean useSRIOV) { + this.useSRIOV = useSRIOV; } @Override diff --git a/header/src/main/java/org/zstack/header/vm/VmNicVO.java b/header/src/main/java/org/zstack/header/vm/VmNicVO.java index 712ae503450..e5b2edc9085 100755 --- a/header/src/main/java/org/zstack/header/vm/VmNicVO.java +++ b/header/src/main/java/org/zstack/header/vm/VmNicVO.java @@ -73,6 +73,10 @@ public class VmNicVO extends ResourceVO implements OwnedByAccount { @Column private String type; + @Column + @Enumerated(EnumType.STRING) + private VmNicState state = VmNicState.enable; + @Column private Timestamp createDate; @@ -223,10 +227,12 @@ public static String generateNicInternalName(long vmInternalId, long nicDeviceId return String.format("vnic%s.%s", vmInternalId, nicDeviceId); } + @Deprecated public Integer getIpVersion() { return ipVersion; } + @Deprecated public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } @@ -254,4 +260,12 @@ public String getType() { public void setType(String type) { this.type = type; } + + public VmNicState getState() { + return state; + } + + public void setState(VmNicState enable) { + this.state = enable; + } } diff --git a/header/src/main/java/org/zstack/header/vm/VmNicVO_.java b/header/src/main/java/org/zstack/header/vm/VmNicVO_.java index 54d904f6cb9..96fb6f20c26 100755 --- a/header/src/main/java/org/zstack/header/vm/VmNicVO_.java +++ b/header/src/main/java/org/zstack/header/vm/VmNicVO_.java @@ -22,6 +22,7 @@ public class VmNicVO_ extends ResourceVO_ { public static volatile SingularAttribute deviceId; public static volatile SingularAttribute driverType; public static volatile SingularAttribute type; + public static volatile SingularAttribute state; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/vm/VmOvsNicConstant.java b/header/src/main/java/org/zstack/header/vm/VmOvsNicConstant.java new file mode 100644 index 00000000000..964a41e8861 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmOvsNicConstant.java @@ -0,0 +1,9 @@ +package org.zstack.header.vm; + +import org.zstack.header.configuration.PythonClass; + +@PythonClass +public class VmOvsNicConstant { + public static final String ACCEL_TYPE_VDPA = "vDPA"; + public static final String ACCEL_TYPE_VHOST_USER_SPACE = "dpdkvhostuserclient"; +} diff --git a/header/src/main/java/org/zstack/header/vm/VmPreMigrationExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmPreMigrationExtensionPoint.java index 7a560c570de..a368c458703 100755 --- a/header/src/main/java/org/zstack/header/vm/VmPreMigrationExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/vm/VmPreMigrationExtensionPoint.java @@ -6,5 +6,5 @@ * Created by frank on 1/2/2016. */ public interface VmPreMigrationExtensionPoint { - void preVmMigration(VmInstanceInventory vm, Completion completion); + void preVmMigration(VmInstanceInventory vm, VmMigrationType type, String dstHostUuid, Completion completion); } diff --git a/header/src/main/java/org/zstack/header/vm/VmPriorityLevel.java b/header/src/main/java/org/zstack/header/vm/VmPriorityLevel.java index 29d2a4be7b5..86b2b4e721c 100644 --- a/header/src/main/java/org/zstack/header/vm/VmPriorityLevel.java +++ b/header/src/main/java/org/zstack/header/vm/VmPriorityLevel.java @@ -2,6 +2,8 @@ public enum VmPriorityLevel { Normal(512, 0), + CpuHigh(1024, 0), + MemoryHigh(512, -900), High(1024, -900), ApplianceVmHigh(1536, -950); diff --git a/header/src/main/java/org/zstack/header/vm/VmSchedHistoryInventory.java b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryInventory.java new file mode 100644 index 00000000000..df1afef1b19 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryInventory.java @@ -0,0 +1,158 @@ +package org.zstack.header.vm; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.zone.ZoneInventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Inventory(mappingVOClass = VmSchedHistoryVO.class) +@PythonClassInventory +@ExpandedQueries({ + @ExpandedQuery(expandedField = "zone", inventoryClass = ZoneInventory.class, + foreignKey = "zoneUuid", expandedInventoryKey = "uuid"), +}) +public class VmSchedHistoryInventory implements Serializable { + private long id; + private String vmInstanceUuid; + private String accountUuid; + private String schedType; + private String schedReason; + private String failReason; + private Boolean success; + private String lastHostUuid; + private String destHostUuid; + private Timestamp createDate; + private Timestamp lastOpDate; + + /** + * uuid of zone this vm is in. See :ref:`ZoneInventory` + */ + private String zoneUuid; + + public VmSchedHistoryInventory() { + } + + public static VmSchedHistoryInventory valueOf(VmSchedHistoryVO vo) { + VmSchedHistoryInventory inv = new VmSchedHistoryInventory(); + inv.setId(vo.getId()); + inv.setVmInstanceUuid(vo.getVmInstanceUuid()); + inv.setAccountUuid(vo.getAccountUuid()); + inv.setSchedType(vo.getSchedType()); + inv.setSchedReason(vo.getSchedReason()); + inv.setFailReason(vo.getFailReason()); + inv.setSuccess(vo.getSuccess()); + inv.setLastHostUuid(vo.getLastHostUuid()); + inv.setDestHostUuid(vo.getDestHostUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + inv.setZoneUuid(vo.getZoneUuid()); + return inv; + } + + public static List valueOf(Collection vos) { + return vos.stream().map(VmSchedHistoryInventory::valueOf).collect(Collectors.toList()); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getSchedType() { + return schedType; + } + + public void setSchedType(String schedType) { + this.schedType = schedType; + } + + public String getSchedReason() { + return schedReason; + } + + public void setSchedReason(String schedReason) { + this.schedReason = schedReason; + } + + public String getFailReason() { + return failReason; + } + + public void setFailReason(String failReason) { + this.failReason = failReason; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getLastHostUuid() { + return lastHostUuid; + } + + public void setLastHostUuid(String lastHostUuid) { + this.lastHostUuid = lastHostUuid; + } + + public String getDestHostUuid() { + return destHostUuid; + } + + public void setDestHostUuid(String destHostUuid) { + this.destHostUuid = destHostUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmSchedHistoryInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..4b22668d95d --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryInventoryDoc_zh_cn.groovy @@ -0,0 +1,71 @@ +package org.zstack.header.vm + +import java.lang.Boolean +import java.sql.Timestamp +import java.sql.Timestamp + +doc { + + title "虚拟机调度历史清单" + + field { + name "vmInstanceUuid" + desc "云主机UUID" + type "String" + since "4.4.24" + } + field { + name "accountUuid" + desc "账户UUID" + type "String" + since "4.4.24" + } + field { + name "schedType" + desc "调度原因" + type "String" + since "4.4.24" + } + field { + name "schedReason" + desc "调度的详情,具体说明为什么进行虚拟机的调度" + type "String" + since "zsv 4.1.6" + } + field { + name "failReason" + desc "调度失败的原因" + type "String" + since "zsv 4.1.6" + } + field { + name "success" + desc "是否成功" + type "Boolean" + since "4.4.24" + } + field { + name "lastHostUuid" + desc "上次所在物理机UUID" + type "String" + since "4.4.24" + } + field { + name "destHostUuid" + desc "目标物理机UUID" + type "String" + since "4.4.24" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.4.24" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.4.24" + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmSchedHistoryVO.java b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryVO.java new file mode 100644 index 00000000000..4a0e9aca638 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryVO.java @@ -0,0 +1,164 @@ +package org.zstack.header.vm; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; +import org.zstack.header.vo.ToInventory; +import org.zstack.header.zone.ZoneEO; +import org.zstack.header.zone.ZoneInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@ExpandedQueries({ + @ExpandedQuery(expandedField = "zone", inventoryClass = ZoneInventory.class, + foreignKey = "zoneUuid", expandedInventoryKey = "uuid"), +}) +public class VmSchedHistoryVO implements ToInventory { + @Id + @Column + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + @Column + @Index + private String vmInstanceUuid; + + @Column + @ForeignKey(parentEntityClass = ZoneEO.class, onDeleteAction = ForeignKey.ReferenceOption.SET_NULL) + private String zoneUuid; + + @Column + private String accountUuid; + + @Column + private String schedType; + + /** + * @since zsv_4.1.6 + */ + @Column + private String schedReason; + + @Column + private String failReason; + + @Column + private Boolean success; + + @Column + private String lastHostUuid; + + @Column + private String destHostUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getSchedType() { + return schedType; + } + + public void setSchedType(String schedType) { + this.schedType = schedType; + } + + public String getSchedReason() { + return schedReason; + } + + public void setSchedReason(String schedReason) { + this.schedReason = schedReason; + } + + public String getFailReason() { + return failReason; + } + + public void setFailReason(String failReason) { + this.failReason = failReason; + } + + public Boolean getSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getLastHostUuid() { + return lastHostUuid; + } + + public void setLastHostUuid(String lastHostUuid) { + this.lastHostUuid = lastHostUuid; + } + + public String getDestHostUuid() { + return destHostUuid; + } + + public void setDestHostUuid(String destHostUuid) { + this.destHostUuid = destHostUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/VmSchedHistoryVO_.java b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryVO_.java new file mode 100644 index 00000000000..6ac5b8662bb --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmSchedHistoryVO_.java @@ -0,0 +1,21 @@ +package org.zstack.header.vm; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(VmSchedHistoryVO.class) +public class VmSchedHistoryVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute vmInstanceUuid; + public static volatile SingularAttribute zoneUuid; + public static volatile SingularAttribute accountUuid; + public static volatile SingularAttribute schedType; + public static volatile SingularAttribute schedReason; + public static volatile SingularAttribute failReason; + public static volatile SingularAttribute success; + public static volatile SingularAttribute lastHostUuid; + public static volatile SingularAttribute destHostUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/vm/VmUpdateNicExtensionPoint.java b/header/src/main/java/org/zstack/header/vm/VmUpdateNicExtensionPoint.java new file mode 100644 index 00000000000..352174e2ca5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/VmUpdateNicExtensionPoint.java @@ -0,0 +1,12 @@ +package org.zstack.header.vm; + +import org.zstack.header.network.l3.L3NetworkInventory; + +/** + * Created by boce.wang on 11/29/2023. + */ +public interface VmUpdateNicExtensionPoint { + void beforeUpdateNic(VmInstanceSpec spec, VmNicInventory nic, L3NetworkInventory destL3); + + void afterUpdateNic(VmInstanceSpec spec, VmNicInventory nic, L3NetworkInventory destL3); +} diff --git a/header/src/main/java/org/zstack/header/vm/VmUpdateNicOnHypervisorMsg.java b/header/src/main/java/org/zstack/header/vm/VmUpdateNicOnHypervisorMsg.java index f061d731a36..4ece5fd8b29 100644 --- a/header/src/main/java/org/zstack/header/vm/VmUpdateNicOnHypervisorMsg.java +++ b/header/src/main/java/org/zstack/header/vm/VmUpdateNicOnHypervisorMsg.java @@ -3,9 +3,13 @@ import org.zstack.header.host.HostMessage; import org.zstack.header.message.NeedReplyMessage; +import java.util.List; +import java.util.ArrayList; + public class VmUpdateNicOnHypervisorMsg extends NeedReplyMessage implements HostMessage { private String hostUuid; private String vmInstanceUuid; + private List nicsUuid = new ArrayList<>(); @Override public String getHostUuid() { @@ -23,4 +27,12 @@ public String getVmInstanceUuid() { public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; } -} + + public void setNicsUuid(List nicsUuid) { + this.nicsUuid = nicsUuid; + } + + public List getNicsUuid() { + return nicsUuid; + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/APICreateVmCdRomMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/cdrom/APICreateVmCdRomMsgDoc_zh_cn.groovy index 4336dce8ec0..a7cc8a3bedf 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/APICreateVmCdRomMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/cdrom/APICreateVmCdRomMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.3" - } column { name "vmInstanceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.3" - } column { name "isoUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.3" - } column { name "description" @@ -59,7 +56,6 @@ doc { type "String" optional true since "3.3" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "3.3" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "3.3" - } column { name "userTags" @@ -89,7 +83,15 @@ doc { type "List" optional true since "3.3" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/APIDeleteVmCdRomMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/cdrom/APIDeleteVmCdRomMsgDoc_zh_cn.groovy index 9e5d8f65d34..3bda1db3aec 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/APIDeleteVmCdRomMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/cdrom/APIDeleteVmCdRomMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.3" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.3" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/APISetVmInstanceDefaultCdRomMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/cdrom/APISetVmInstanceDefaultCdRomMsgDoc_zh_cn.groovy index 10c36eb7aa4..511f25e228f 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/APISetVmInstanceDefaultCdRomMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/cdrom/APISetVmInstanceDefaultCdRomMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.3" - } column { name "vmInstanceUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.3" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/APIUpdateVmCdRomMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/cdrom/APIUpdateVmCdRomMsgDoc_zh_cn.groovy index 71b5d273f93..8d2f0001106 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/APIUpdateVmCdRomMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/cdrom/APIUpdateVmCdRomMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.3" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.3" - } column { name "name" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.3" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.3" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.3" - } } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventory.java b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventory.java index 05c5e0ab681..c067d231528 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventory.java +++ b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventory.java @@ -30,6 +30,8 @@ public class VmCdRomInventory implements Serializable { private String description; + private String protocol; + private Timestamp createDate; private Timestamp lastOpDate; @@ -43,6 +45,7 @@ public static VmCdRomInventory valueOf(VmCdRomVO vo) { inv.setName(vo.getName()); inv.setIsoUuid(vo.getIsoUuid()); inv.setIsoInstallPath(vo.getIsoInstallPath()); + inv.setProtocol(vo.getProtocol()); inv.setCreateDate(vo.getCreateDate()); inv.setLastOpDate(vo.getLastOpDate()); @@ -132,4 +135,12 @@ public String getDescription() { public void setDescription(String description) { this.description = description; } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventoryDoc_zh_cn.groovy index 100a44daab2..3abe48df0ad 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomInventoryDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.vm.cdrom import java.lang.Integer import java.sql.Timestamp -import java.sql.Timestamp doc { @@ -12,54 +11,54 @@ doc { name "uuid" desc "资源的UUID,唯一标示该资源" type "String" - since "3.3" + since "4.7.13" } field { name "vmInstanceUuid" desc "云主机UUID" type "String" - since "3.3" + since "4.7.13" } field { name "deviceId" - desc "光驱顺序号" + desc "" type "Integer" - since "3.3" + since "4.7.13" } field { name "isoUuid" - desc "ISO镜像UUID" + desc "" type "String" - since "3.3" + since "4.7.13" } field { name "isoInstallPath" - desc "ISO镜像挂载路径" + desc "" type "String" - since "3.3" + since "4.7.13" } field { name "name" desc "资源名称" type "String" - since "3.3" + since "4.7.13" } field { name "description" desc "资源的详细描述" type "String" - since "3.3" + since "4.7.13" } field { name "createDate" desc "创建时间" type "Timestamp" - since "3.3" + since "4.7.13" } field { name "lastOpDate" desc "最后一次修改时间" type "Timestamp" - since "3.3" + since "4.7.13" } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO.java b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO.java index c43b6462fbe..38032b73cee 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO.java +++ b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO.java @@ -45,6 +45,9 @@ public class VmCdRomVO extends ResourceVO implements OwnedByAccount { @Column private String description; + @Column + private String protocol; + @Column private Timestamp createDate; @@ -115,6 +118,9 @@ public String getIsoInstallPath() { public void setIsoInstallPath(String isoInstallPath) { this.isoInstallPath = isoInstallPath; + if (isoInstallPath == null) { + this.protocol = null; + } } public String getName() { @@ -132,4 +138,12 @@ public String getDescription() { public void setDescription(String description) { this.description = description; } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO_.java b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO_.java index 017eb7d36c3..585ac0f78dc 100644 --- a/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO_.java +++ b/header/src/main/java/org/zstack/header/vm/cdrom/VmCdRomVO_.java @@ -1,6 +1,5 @@ package org.zstack.header.vm.cdrom; -import org.zstack.header.vm.VmNicVO; import org.zstack.header.vo.ResourceVO_; import javax.persistence.metamodel.SingularAttribute; @@ -16,8 +15,9 @@ public class VmCdRomVO_ extends ResourceVO_ { public static volatile SingularAttribute name; public static volatile SingularAttribute isoUuid; public static volatile SingularAttribute isoInstallPath; - public static volatile SingularAttribute description; - public static volatile SingularAttribute deviceId; + public static volatile SingularAttribute description; + public static volatile SingularAttribute deviceId; + public static volatile SingularAttribute protocol; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveMsg.java b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveMsg.java new file mode 100644 index 00000000000..2e9a98a6cbe --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveMsg.java @@ -0,0 +1,29 @@ +package org.zstack.header.vm.devices; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; + +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created by LiangHanYu on 2022/6/17 17:31 + */ +@AutoQuery(replyClass = APIQueryVmInstanceDeviceAddressArchiveReply.class, inventoryClass = VmInstanceDeviceAddressArchiveInventory.class) +@Action(category = VolumeSnapshotConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/vmInstance/device/address/archive", + optionalPaths = {"/vmInstance/device/address/archive/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryVmInstanceDeviceAddressArchiveReply.class +) +public class APIQueryVmInstanceDeviceAddressArchiveMsg extends APIQueryMessage { + public static List __example__() { + return asList("uuid=" + uuid()); + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..33b7889586e --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.vm.devices + +import org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressArchiveReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryVmInstanceDeviceAddressArchive" + + category "snapshot.volume" + + desc """查询云主机设备地址归档""" + + rest { + request { + url "GET /v1/vmInstance/device/address/archive" + url "GET /v1/vmInstance/device/address/archive/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryVmInstanceDeviceAddressArchiveMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryVmInstanceDeviceAddressArchiveReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveReply.java b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveReply.java new file mode 100644 index 00000000000..dcdce075fdc --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveReply.java @@ -0,0 +1,47 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; +import java.util.Collections; +import java.util.List; + +/** + * Created by LiangHanYu on 2022/6/17 17:31 + */ +@RestResponse(allTo = "inventories") +public class APIQueryVmInstanceDeviceAddressArchiveReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryVmInstanceDeviceAddressArchiveReply __example__() { + VmInstanceDeviceAddressArchiveInventory inv = new VmInstanceDeviceAddressArchiveInventory(); + inv.setId(1); + inv.setResourceUuid(uuid()); + + DeviceAddress address = new DeviceAddress(); + address.bus = "00"; + address.domain = "0000"; + address.slot = "0d"; + address.function = "0"; + + inv.setDeviceAddress(address.toString()); + inv.setAddressGroupUuid(uuid()); + inv.setMetadata("Metadata"); + inv.setMetadataClass(VmInstanceDeviceAddressArchiveInventory.class.getCanonicalName()); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + + APIQueryVmInstanceDeviceAddressArchiveReply result = new APIQueryVmInstanceDeviceAddressArchiveReply(); + result.inventories = Collections.singletonList(inv); + return result; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..d0a0d67f427 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressArchiveReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm.devices + +import org.zstack.header.vm.devices.VmInstanceDeviceAddressArchiveInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询云主机设备地址归档的返回" + + ref { + name "inventories" + path "org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressArchiveReply.inventories" + desc "null" + type "List" + since "4.4.24" + clz VmInstanceDeviceAddressArchiveInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.4.24" + } + ref { + name "error" + path "org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressArchiveReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.4.24" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupMsg.java b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupMsg.java new file mode 100644 index 00000000000..b52499bb8d1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupMsg.java @@ -0,0 +1,29 @@ +package org.zstack.header.vm.devices; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; + +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created by LiangHanYu on 2022/6/20 18:03 + */ +@AutoQuery(replyClass = APIQueryVmInstanceDeviceAddressGroupReply.class, inventoryClass = VmInstanceDeviceAddressGroupInventory.class) +@Action(category = VolumeSnapshotConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/vmInstance/device/address/group", + optionalPaths = {"/vmInstance/device/address/group/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryVmInstanceDeviceAddressGroupReply.class +) +public class APIQueryVmInstanceDeviceAddressGroupMsg extends APIQueryMessage { + public static List __example__() { + return asList("uuid=" + uuid()); + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..00b8610bbf1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.vm.devices + +import org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressGroupReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryVmInstanceDeviceAddressGroup" + + category "snapshot.volume" + + desc """查询云主机设备地址组""" + + rest { + request { + url "GET /v1/vmInstance/device/address/group" + url "GET /v1/vmInstance/device/address/group/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryVmInstanceDeviceAddressGroupMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryVmInstanceDeviceAddressGroupReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupReply.java b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupReply.java new file mode 100644 index 00000000000..4602c026cbe --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupReply.java @@ -0,0 +1,81 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeState; +import org.zstack.header.volume.VolumeStatus; +import org.zstack.header.volume.VolumeType; +import org.zstack.utils.data.SizeUnit; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Created by LiangHanYu on 2022/6/20 18:03 + */ +@RestResponse(allTo = "inventories") +public class APIQueryVmInstanceDeviceAddressGroupReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryVmInstanceDeviceAddressGroupReply __example__() { + VmInstanceDeviceAddressGroupInventory inv = new VmInstanceDeviceAddressGroupInventory(); + inv.setUuid(uuid()); + inv.setResourceUuid(uuid()); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + + VmInstanceDeviceAddressArchiveInventory archiveInventory = new VmInstanceDeviceAddressArchiveInventory(); + archiveInventory.setId(1); + archiveInventory.setResourceUuid(uuid()); + + DeviceAddress address = new DeviceAddress(); + address.bus = "00"; + address.domain = "0000"; + address.slot = "0d"; + address.function = "0"; + + archiveInventory.setDeviceAddress(address.toString()); + archiveInventory.setAddressGroupUuid(inv.getUuid()); + archiveInventory.setVmInstanceUuid(uuid()); + archiveInventory.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + archiveInventory.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + + String vmUuid = uuid(); + VolumeInventory vol = new VolumeInventory(); + vol.setName(String.format("Root-Volume-For-VM-%s", vmUuid)); + vol.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setType(VolumeType.Root.toString()); + vol.setUuid(uuid()); + vol.setSize(SizeUnit.GIGABYTE.toByte(100)); + vol.setActualSize(SizeUnit.GIGABYTE.toByte(20)); + vol.setDeviceId(0); + vol.setState(VolumeState.Enabled.toString()); + vol.setFormat("qcow2"); + vol.setDiskOfferingUuid(uuid()); + vol.setInstallPath(String.format("/zstack_ps/rootVolumes/acct-36c27e8ff05c4780bf6d2fa65700f22e/vol-%s/%s.qcow2", vol.getUuid(), vol.getUuid())); + vol.setStatus(VolumeStatus.Ready.toString()); + vol.setPrimaryStorageUuid(uuid()); + vol.setVmInstanceUuid(vmUuid); + vol.setRootImageUuid(uuid()); + + archiveInventory.setMetadata(JSONObjectUtil.toJsonString(vol)); + archiveInventory.setMetadataClass(VmInstanceDeviceAddressGroupInventory.class.getCanonicalName()); + inv.setAddressList(Arrays.asList(archiveInventory)); + APIQueryVmInstanceDeviceAddressGroupReply result = new APIQueryVmInstanceDeviceAddressGroupReply(); + result.inventories = Collections.singletonList(inv); + return result; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..e4c8f82b1a9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/APIQueryVmInstanceDeviceAddressGroupReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.vm.devices + +import org.zstack.header.vm.devices.VmInstanceDeviceAddressGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询云主机设备地址组的返回" + + ref { + name "inventories" + path "org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressGroupReply.inventories" + desc "null" + type "List" + since "4.4.24" + clz VmInstanceDeviceAddressGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.4.24" + } + ref { + name "error" + path "org.zstack.header.vm.devices.APIQueryVmInstanceDeviceAddressGroupReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.4.24" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/DeviceAddress.java b/header/src/main/java/org/zstack/header/vm/devices/DeviceAddress.java new file mode 100644 index 00000000000..ad9f19fc9f8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/DeviceAddress.java @@ -0,0 +1,33 @@ +package org.zstack.header.vm.devices; + +import org.zstack.utils.gson.JSONObjectUtil; + +/** + * structure to match device address + */ +public class DeviceAddress { + public String type; + + public String bus; + + // for pci address + public String domain; + public String slot; + public String function; + + // for driver address + public String controller; + public String target; + public String unit; + + + public static DeviceAddress fromString(String address) { + return JSONObjectUtil.toObject(address, DeviceAddress.class); + } + + public String toString() { + return JSONObjectUtil.toJsonString(this); + } + + +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VirtualDeviceInfo.java b/header/src/main/java/org/zstack/header/vm/devices/VirtualDeviceInfo.java new file mode 100644 index 00000000000..7398554d628 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VirtualDeviceInfo.java @@ -0,0 +1,34 @@ +package org.zstack.header.vm.devices; + +public class VirtualDeviceInfo { + private String resourceUuid; + private DeviceAddress deviceAddress; + + public VirtualDeviceInfo(String resourceUuid, DeviceAddress deviceAddress) { + this.resourceUuid = resourceUuid; + this.deviceAddress = deviceAddress; + } + + public VirtualDeviceInfo() { + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public DeviceAddress getDeviceAddress() { + return deviceAddress; + } + + public void setDeviceAddress(DeviceAddress deviceAddress) { + this.deviceAddress = deviceAddress; + } + + public boolean isValid() { + return resourceUuid != null && deviceAddress != null; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveInventory.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveInventory.java new file mode 100644 index 00000000000..d1560422e0e --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveInventory.java @@ -0,0 +1,114 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.search.Inventory; + +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by LiangHanYu on 2022/6/17 17:24 + */ +@Inventory(mappingVOClass = VmInstanceDeviceAddressArchiveVO.class) +public class VmInstanceDeviceAddressArchiveInventory { + private long id; + private String resourceUuid; + private String vmInstanceUuid; + private String deviceAddress; + private String addressGroupUuid; + private String metadata; + private String metadataClass; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static VmInstanceDeviceAddressArchiveInventory valueOf(VmInstanceDeviceAddressArchiveVO vo) { + VmInstanceDeviceAddressArchiveInventory inv = new VmInstanceDeviceAddressArchiveInventory(); + inv.setId(1); + inv.setResourceUuid(vo.getResourceUuid()); + inv.setDeviceAddress(vo.getDeviceAddress()); + inv.setAddressGroupUuid(vo.getAddressGroupUuid()); + inv.setVmInstanceUuid(vo.getVmInstanceUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + inv.setMetadata(vo.getMetadata()); + inv.setMetadataClass(vo.getMetadataClass()); + return inv; + } + + public static List valueOf(Collection vos) { + return vos.stream().map(VmInstanceDeviceAddressArchiveInventory::valueOf).collect(Collectors.toList()); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getDeviceAddress() { + return deviceAddress; + } + + public void setDeviceAddress(String deviceAddress) { + this.deviceAddress = deviceAddress; + } + + public String getAddressGroupUuid() { + return addressGroupUuid; + } + + public void setAddressGroupUuid(String addressGroupUuid) { + this.addressGroupUuid = addressGroupUuid; + } + + public String getMetadata() { + return metadata; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + public String getMetadataClass() { + return metadataClass; + } + + public void setMetadataClass(String metadataClass) { + this.metadataClass = metadataClass; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..80dbc913e33 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveInventoryDoc_zh_cn.groovy @@ -0,0 +1,64 @@ +package org.zstack.header.vm.devices + +import java.sql.Timestamp +import java.sql.Timestamp + +doc { + + title "云主机设备地址归档清单" + + field { + name "id" + desc "" + type "long" + since "4.4.24" + } + field { + name "resourceUuid" + desc "资源UUID" + type "String" + since "4.4.24" + } + field { + name "vmInstanceUuid" + desc "云主机UUID" + type "String" + since "4.4.24" + } + field { + name "deviceAddress" + desc "" + type "String" + since "4.4.24" + } + field { + name "addressGroupUuid" + desc "" + type "String" + since "4.4.24" + } + field { + name "metadata" + desc "" + type "String" + since "4.4.24" + } + field { + name "metadataClass" + desc "" + type "String" + since "4.4.24" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.4.24" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.4.24" + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveVO.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveVO.java new file mode 100644 index 00000000000..11961ebe0e4 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveVO.java @@ -0,0 +1,134 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class VmInstanceDeviceAddressArchiveVO implements ToInventory { + @Id + @Column + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + /** + * uuid of vm device + */ + @Column + private String resourceUuid; + + /** + * vm instance uuid that the resourceUuid related resource attached + */ + @Column + private String vmInstanceUuid; + + /** + * pciAddress used to store a string format by PciAddressConfig + */ + @Column + private String deviceAddress; + + /** + * normally a json string of resource inventory + */ + @Column + private String metadata; + + /** + * canonical name of metadata + */ + @Column + private String metadataClass; + + /** + * use to mark a group of vm device archives + */ + @Column + private String addressGroupUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getDeviceAddress() { + return deviceAddress; + } + + public void setDeviceAddress(String deviceAddress) { + this.deviceAddress = deviceAddress; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getAddressGroupUuid() { + return addressGroupUuid; + } + + public void setAddressGroupUuid(String addressGroupUuid) { + this.addressGroupUuid = addressGroupUuid; + } + + public String getMetadata() { + return metadata; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + public String getMetadataClass() { + return metadataClass; + } + + public void setMetadataClass(String metadataClass) { + this.metadataClass = metadataClass; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveVO_.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveVO_.java new file mode 100644 index 00000000000..ae772636de9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressArchiveVO_.java @@ -0,0 +1,14 @@ +package org.zstack.header.vm.devices; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(VmInstanceDeviceAddressArchiveVO.class) +public class VmInstanceDeviceAddressArchiveVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute resourceUuid; + public static volatile SingularAttribute addressGroupUuid; + public static volatile SingularAttribute metadata; + public static volatile SingularAttribute metadataClass; + public static volatile SingularAttribute vmInstanceUuid; +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupInventory.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupInventory.java new file mode 100644 index 00000000000..3f0dd39cf93 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupInventory.java @@ -0,0 +1,95 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.query.Queryable; +import org.zstack.header.search.Inventory; + +import javax.persistence.JoinColumn; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by LiangHanYu on 2022/6/20 18:03 + */ +@Inventory(mappingVOClass = VmInstanceDeviceAddressGroupVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "volumeSnapshotRef", inventoryClass = VmInstanceDeviceAddressArchiveInventory.class, + foreignKey = "uuid", expandedInventoryKey = "addressGroupUuid", hidden = true), +}) +public class VmInstanceDeviceAddressGroupInventory { + private String uuid; + private String resourceUuid; + private String vmInstanceUuid; + private Timestamp createDate; + private Timestamp lastOpDate; + + @Queryable(mappingClass = VmInstanceDeviceAddressArchiveInventory.class, + joinColumn = @JoinColumn(name = "addressGroupUuid")) + private List addressList; + + public static VmInstanceDeviceAddressGroupInventory valueOf(VmInstanceDeviceAddressGroupVO vo) { + VmInstanceDeviceAddressGroupInventory inv = new VmInstanceDeviceAddressGroupInventory(); + inv.setUuid(vo.getUuid()); + inv.setResourceUuid(vo.getResourceUuid()); + inv.setVmInstanceUuid(vo.getVmInstanceUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + inv.setAddressList(VmInstanceDeviceAddressArchiveInventory.valueOf(vo.getAddressList())); + return inv; + } + + public static List valueOf(Collection vos) { + return vos.stream().map(VmInstanceDeviceAddressGroupInventory::valueOf).collect(Collectors.toList()); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public List getAddressList() { + return addressList; + } + + public void setAddressList(List addressList) { + this.addressList = addressList; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..9d806b9fa12 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupInventoryDoc_zh_cn.groovy @@ -0,0 +1,49 @@ +package org.zstack.header.vm.devices + +import java.sql.Timestamp +import java.sql.Timestamp +import org.zstack.header.vm.devices.VmInstanceDeviceAddressArchiveInventory + +doc { + + title "云主机设备地址组清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.4.24" + } + field { + name "resourceUuid" + desc "资源UUID" + type "String" + since "4.4.24" + } + field { + name "vmInstanceUuid" + desc "云主机UUID" + type "String" + since "4.4.24" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.4.24" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.4.24" + } + ref { + name "addressList" + path "org.zstack.header.vm.devices.VmInstanceDeviceAddressGroupInventory.addressList" + desc "null" + type "List" + since "4.4.24" + clz VmInstanceDeviceAddressArchiveInventory.class + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupVO.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupVO.java new file mode 100644 index 00000000000..9394f42d7a0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupVO.java @@ -0,0 +1,86 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; +import java.util.List; + +@Entity +@Table +public class VmInstanceDeviceAddressGroupVO implements ToInventory { + @Id + @Column + private String uuid; + + /** + * vm instance uuid + */ + @Column + private String resourceUuid; + + /** + * vm device address archive that referred by this group + */ + @Column + private String vmInstanceUuid; + + @Column + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "addressGroupUuid", insertable = false, updatable = false) + private List addressList; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public List getAddressList() { + return addressList; + } + + public void setAddressList(List addressList) { + this.addressList = addressList; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupVO_.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupVO_.java new file mode 100644 index 00000000000..558474bcd82 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressGroupVO_.java @@ -0,0 +1,11 @@ +package org.zstack.header.vm.devices; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(VmInstanceDeviceAddressGroupVO.class) +public class VmInstanceDeviceAddressGroupVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute resourceUuid; + public static volatile SingularAttribute vmInstanceUuid; +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressVO.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressVO.java new file mode 100644 index 00000000000..cc51d8afba9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressVO.java @@ -0,0 +1,120 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class VmInstanceDeviceAddressVO implements ToInventory { + @Id + @Column + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long id; + + /** + * uuid of vm device + */ + @Column + private String resourceUuid; + + /** + * vm instance uuid that the resourceUuid related resource attached + */ + @Column + private String vmInstanceUuid; + + /** + * pciAddress used to store a string format by PciAddressConfig + */ + @Column + private String deviceAddress; + + /** + * normally a json string of resource inventory + */ + @Column + private String metadata; + + /** + * canonical name of metadata + */ + @Column + private String metadataClass; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getDeviceAddress() { + return deviceAddress; + } + + public void setDeviceAddress(String deviceAddress) { + this.deviceAddress = deviceAddress; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getMetadata() { + return metadata; + } + + public void setMetadata(String metadata) { + this.metadata = metadata; + } + + public String getMetadataClass() { + return metadataClass; + } + + public void setMetadataClass(String metadataClass) { + this.metadataClass = metadataClass; + } +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressVO_.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressVO_.java new file mode 100644 index 00000000000..afca8003d64 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceAddressVO_.java @@ -0,0 +1,14 @@ +package org.zstack.header.vm.devices; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(VmInstanceDeviceAddressVO.class) +public class VmInstanceDeviceAddressVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute resourceUuid; + public static volatile SingularAttribute vmInstanceUuid; + public static volatile SingularAttribute deviceAddress; + public static volatile SingularAttribute metadata; + public static volatile SingularAttribute metadataClass; +} diff --git a/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceManager.java b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceManager.java new file mode 100644 index 00000000000..c7b6b2ea527 --- /dev/null +++ b/header/src/main/java/org/zstack/header/vm/devices/VmInstanceDeviceManager.java @@ -0,0 +1,139 @@ +package org.zstack.header.vm.devices; + +import org.zstack.header.errorcode.ErrorCode; + +import java.util.List; +import java.util.Map; + +public interface VmInstanceDeviceManager { + String MEM_BALLOON_UUID = "4780bf6d2fa65700f22e36c27e8ff05c"; + + String RESOURCE_CONFIG_UUID = "65700f22e34780bf6d2fa6c27e8ff05c"; + + /** + * create or update vm device address, + * if no VmInstanceDeviceAddressVO with current resource, a new + * record will be created, else update the existing one. + * + * @param resourceUuid uuid of resource need record device address + * @param deviceAddress a instance of deviceAddressConfig record device address + * @param vmInstanceUuid vm uuid of resource need record device address + * @param metadata a string of anything request to be record with the device + * @param metadataClass the canonical class name of metadata + * @return VmInstanceDeviceAddressVO result vo of device address + */ + VmInstanceDeviceAddressVO createOrUpdateVmDeviceAddress(String resourceUuid, DeviceAddress deviceAddress, String vmInstanceUuid, String metadata, String metadataClass); + + /** + * create or update vm device address, + * if no VmInstanceDeviceAddressVO with current resource, a new + * record will be created, else update the existing one. + * + * @param virtualDeviceInfo contains resourceUuid and deviceInfo a structure oriented method + * @param vmInstanceUuid vm uuid of resource + * @return VmInstanceDeviceAddressVO result vo of device address + */ + VmInstanceDeviceAddressVO createOrUpdateVmDeviceAddress(VirtualDeviceInfo virtualDeviceInfo, String vmInstanceUuid); + + /** + * get vm device address + * + * @param resourceUuid the uuid of resource that want to get device address + * @param vmInstanceUuid vm uuid of resource + * @return DeviceAddressConfig device address of resourceUuid + */ + DeviceAddress getVmDeviceAddress(String resourceUuid, String vmInstanceUuid); + + /** + * delete vm device address + * + * @param resourceUuid the uuid of resource that want to delete device address + * @param vmInstanceUuid vm uuid of resource + * @return ErrorCode if success it is null else not + */ + ErrorCode deleteVmDeviceAddress(String resourceUuid, String vmInstanceUuid); + + /** + * delete vm device address + * + * @param resourceUuid the uuid of resource that want to delete device address + * @return ErrorCode if success it is null else not + */ + ErrorCode deleteVmDeviceAddress(String resourceUuid); + + /** + * delete vm related all devices' address + * + * @param vmInstanceUuid vm uuid will be used to find related device address + * @return ErrorCode if success it is null else not + */ + ErrorCode deleteAllDeviceAddressesByVm(String vmInstanceUuid); + + /** + * modify virtio ,pci address is modify, need vm clean related devices + * + * @param vmInstanceUuid vm uuid will be used to find related device address + * @return ErrorCode if success it is null else not + */ + + ErrorCode deleteDeviceAddressesByVmModifyVirtIO(String vmInstanceUuid); + + /** + * archive current device address + * + * @param vmInstanceUuid vm uuid will be used to find related device address + * @param archiveForResourceUuid this uuid will be used to mark those vm related + * address as a group. note: do not use a duplicate + * archiveForResourceUuid to confuse yourself + * @return VmInstanceDeviceAddressGroupVO the group marked by archiveForResourceUuid + * and has references with all vm current related address + */ + VmInstanceDeviceAddressGroupVO archiveCurrentDeviceAddress(String vmInstanceUuid, String archiveForResourceUuid); + + /** + * revert current vm device address to a specific device + * address group + * + * @param vmInstanceUuid vm uuid will be used to find related device address + * @param archiveForResourceUuid this uuid will be used to find a specific group + * of device address + * @return List a list of vm device address + */ + List revertDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid); + + List revertExistingDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid); + + + List revertRequestedDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid, List needRevertResourceUuidList); + /** + * create device address from archive + * + * @param vmInstanceUuid vm uuid will be used to find related device address and create device address for + * @param archiveForResourceUuid this uuid will be used to find a specific group + * of device address + * @param resourceMap resource map will be used for uuid mapping, for example if new vm use uuidA to mark the + * first disk which use uuidB, resourceMap.put(uuidB, uuidA), when create device address, + * address with uuidB will be used to create a record with uuidA + * @return List a list of vm device address + */ + List createDeviceAddressFromArchive(String vmInstanceUuid, String archiveForResourceUuid, Map resourceMap); + + /** + * delete archive device address group + * + * @param archiveForResourceUuid this uuid will be used to find a specific group + * of device address + */ + void deleteArchiveVmInstanceDeviceAddressGroup(String archiveForResourceUuid); + + /** + * get archive info from archiveForResourceUuid + * + * @param vmInstanceUuid vm uuid will be used to find related device address + * @param archiveForResourceUuid this uuid will be used to find a specific group + * of device address + * @param metadataClass the canonical class name of metadata + * @return List a list of vm archive device address + */ + List getAddressArchiveInfoFromArchiveForResourceUuid(String vmInstanceUuid, String archiveForResourceUuid, String metadataClass); +} diff --git a/header/src/main/java/org/zstack/header/vo/APIGetResourceNamesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vo/APIGetResourceNamesMsgDoc_zh_cn.groovy index 384ca8f9276..7f84854efff 100755 --- a/header/src/main/java/org/zstack/header/vo/APIGetResourceNamesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vo/APIGetResourceNamesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/vo/ResourceInventory.java b/header/src/main/java/org/zstack/header/vo/ResourceInventory.java index 201c92429b0..12ab9f146ab 100755 --- a/header/src/main/java/org/zstack/header/vo/ResourceInventory.java +++ b/header/src/main/java/org/zstack/header/vo/ResourceInventory.java @@ -14,11 +14,13 @@ public class ResourceInventory { protected String uuid; private String resourceName; private String resourceType; + private String concreteResourceType; public static ResourceInventory valueOf(ResourceVO vo) { ResourceInventory inv = new ResourceInventory(); inv.setResourceName(vo.getResourceName()); inv.setResourceType(vo.getResourceType()); + inv.setConcreteResourceType(vo.getConcreteResourceType()); inv.setUuid(vo.getUuid()); return inv; } @@ -54,4 +56,12 @@ public String getResourceType() { public void setResourceType(String resourceType) { this.resourceType = resourceType; } + + public String getConcreteResourceType() { + return concreteResourceType; + } + + public void setConcreteResourceType(String concreteResourceType) { + this.concreteResourceType = concreteResourceType; + } } diff --git a/header/src/main/java/org/zstack/header/vo/ResourceInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/vo/ResourceInventoryDoc_zh_cn.groovy index 817e01ea8df..51da354cc93 100755 --- a/header/src/main/java/org/zstack/header/vo/ResourceInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/vo/ResourceInventoryDoc_zh_cn.groovy @@ -24,4 +24,10 @@ doc { type "String" since "2.0" } + field { + name "concreteResourceType" + desc "资源具体类型,例如VPC为org.zstack.header.vpc.VpcRouterVmVO" + type "String" + since "5.0.0" + } } diff --git a/header/src/main/java/org/zstack/header/vo/ResourceVO.java b/header/src/main/java/org/zstack/header/vo/ResourceVO.java index 668ba2dca92..640b78155b8 100755 --- a/header/src/main/java/org/zstack/header/vo/ResourceVO.java +++ b/header/src/main/java/org/zstack/header/vo/ResourceVO.java @@ -38,6 +38,7 @@ public ResourceVO(Object[] objs) { uuid = (String) objs[0]; resourceName = (String) objs[1]; resourceType = (String) objs[2]; + concreteResourceType = objs.length == 4 ? (String) objs[3] : ""; } private Field getNameField() { diff --git a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostEvent.java b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostEvent.java new file mode 100644 index 00000000000..3c3377659ed --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostEvent.java @@ -0,0 +1,19 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIAttachDataVolumeToHostEvent extends APIEvent { + public APIAttachDataVolumeToHostEvent() { + } + + public APIAttachDataVolumeToHostEvent(String apiId) { + super(apiId); + } + public static APIAttachDataVolumeToHostEvent __example__() { + APIAttachDataVolumeToHostEvent event = new APIAttachDataVolumeToHostEvent(); + event.setSuccess(true); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..0d08afa24ec --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.volume + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "加载数据云盘到物理机返回" + + field { + name "success" + desc "加载数据云盘到物理机返回" + type "boolean" + since "4.5.0" + } + ref { + name "error" + path "org.zstack.header.volume.APIAttachDataVolumeToHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.5.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostMsg.java b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostMsg.java new file mode 100644 index 00000000000..25385fc5daa --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostMsg.java @@ -0,0 +1,59 @@ +package org.zstack.header.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostVO; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@Action(category = VolumeConstant.ACTION_CATEGORY) +@RestRequest( + path = "/volumes/{volumeUuid}/hosts/{hostUuid}", + method = HttpMethod.POST, + responseClass = APIAttachDataVolumeToHostEvent.class, + parameterName = "params" +) +public class APIAttachDataVolumeToHostMsg extends APIMessage implements VolumeMessage { + @APIParam(resourceType = VolumeVO.class) + private String volumeUuid; + + @APIParam(resourceType = HostVO.class) + private String hostUuid; + + @APIParam(maxLength = 512) + private String mountPath; + + @Override + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getMountPath() { + return mountPath; + } + + public void setMountPath(String mountPath) { + this.mountPath = mountPath; + } + + public static APIAttachDataVolumeToHostMsg __example__() { + APIAttachDataVolumeToHostMsg msg = new APIAttachDataVolumeToHostMsg(); + msg.setVolumeUuid(uuid()); + msg.setHostUuid(uuid()); + msg.setMountPath("/test/mount/path"); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..200a156d09c --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToHostMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.APIAttachDataVolumeToHostEvent + +doc { + title "AttachDataVolumeToHost" + + category "volume" + + desc """加载数据云盘到物理机""" + + rest { + request { + url "POST /v1/volumes/{volumeUuid}/hosts/{hostUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAttachDataVolumeToHostMsg.class + + desc """加载数据云盘到物理机""" + + params { + + column { + name "volumeUuid" + enclosedIn "params" + desc "云盘UUID" + location "url" + type "String" + optional false + since "4.5.0" + } + column { + name "hostUuid" + enclosedIn "params" + desc "物理机UUID" + location "url" + type "String" + optional false + since "4.5.0" + } + column { + name "mountPath" + enclosedIn "params" + desc "物理机上的挂载路径" + location "body" + type "String" + optional false + since "4.5.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.5.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.5.0" + } + } + } + + response { + clz APIAttachDataVolumeToHostEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsg.java b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsg.java index ca9301713ec..3cd89293889 100755 --- a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsg.java +++ b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsg.java @@ -38,6 +38,7 @@ @RestRequest( path = "/volumes/{volumeUuid}/vm-instances/{vmInstanceUuid}", method = HttpMethod.POST, + parameterName = "params", responseClass = APIAttachDataVolumeToVmEvent.class ) public class APIAttachDataVolumeToVmMsg extends APIMessage implements VolumeMessage { diff --git a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsgDoc_zh_cn.groovy index 9cb246999e4..5985f85fa57 100644 --- a/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIAttachDataVolumeToVmMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "vmInstanceUuid" - enclosedIn "" + enclosedIn "params" desc "云主机UUID" location "url" type "String" optional false since "0.6" - } column { name "volumeUuid" - enclosedIn "" + enclosedIn "params" desc "云盘UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeMsg.java b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeMsg.java new file mode 100644 index 00000000000..caa933da7e1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeMsg.java @@ -0,0 +1,27 @@ +package org.zstack.header.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +@Action(category = VolumeConstant.ACTION_CATEGORY) +@RestRequest( + path = "/volumes/batch-sync-volumes", + method = HttpMethod.POST, + responseClass = APIBatchSyncVolumeSizeReply.class +) +public class APIBatchSyncVolumeSizeMsg extends APISyncCallMessage { + @APIParam(resourceType = ClusterVO.class) + private String clusterUuid; + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..841944cab02 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.APIBatchSyncVolumeSizeReply + +doc { + title "BatchSyncVolumeSize" + + category "volume" + + desc """批量刷新云盘容量""" + + rest { + request { + url "POST /v1/volumes/batch-sync-volumes" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIBatchSyncVolumeSizeMsg.class + + desc """""" + + params { + + column { + name "clusterUuid" + enclosedIn "" + desc "集群UUID" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIBatchSyncVolumeSizeReply.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeReply.java b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeReply.java new file mode 100644 index 00000000000..b4fdda182b3 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeReply.java @@ -0,0 +1,35 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +@RestResponse(fieldsTo = "all") +public class APIBatchSyncVolumeSizeReply extends APIReply { + private int successCount; + + private int failCount; + + public void setSuccessCount(int successCount) { + this.successCount = successCount; + } + + public int getSuccessCount() { + return successCount; + } + + public void setFailCount(int failCount) { + this.failCount = failCount; + } + + public int getFailCount() { + return failCount; + } + + public synchronized void addSuccessCount(int successCount) { + this.successCount = this.successCount + successCount; + } + + public synchronized void addFailCount(int failCount) { + this.failCount = this.failCount + failCount; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeReplyDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..34f985dacf6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIBatchSyncVolumeSizeReplyDoc_zh_cn.groovy @@ -0,0 +1,35 @@ +package org.zstack.header.volume + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "批量刷新云盘容量返回" + + field { + name "successCount" + desc "成功数量" + type "int" + since "4.6.0" + } + field { + name "failCount" + desc "失败数量" + type "int" + since "4.6.0" + } + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.header.volume.APIBatchSyncVolumeSizeReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIChangeVolumeStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIChangeVolumeStateMsgDoc_zh_cn.groovy index 82550a7124b..1295b2a8139 100644 --- a/header/src/main/java/org/zstack/header/volume/APIChangeVolumeStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIChangeVolumeStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeSnapshotMsgDoc_zh_cn.groovy index 79c9e7a9f43..e683c618936 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeSnapshotMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "volumeSnapshotUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "primaryStorageUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +83,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java index 2fd1587d0fa..7a3e81085b1 100755 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsg.java @@ -23,7 +23,7 @@ parameterName = "params" ) @DefaultTimeout(timeunit = TimeUnit.HOURS, value = 72) -public class APICreateDataVolumeFromVolumeTemplateMsg extends APICreateMessage implements APIAuditor { +public class APICreateDataVolumeFromVolumeTemplateMsg extends APICreateMessage implements APIAuditor, VolumeCreateMessage { @APIParam(resourceType = ImageVO.class, checkAccount = true) private String imageUuid; @APIParam(maxLength = 255) @@ -67,6 +67,16 @@ public void setDescription(String description) { this.description = description; } + @Override + public String getDiskOfferingUuid() { + return null; + } + + @Override + public void setDiskOfferingUuid(String diskOfferingUuid) { + + } + public String getPrimaryStorageUuid() { return primaryStorageUuid; } @@ -74,7 +84,17 @@ public String getPrimaryStorageUuid() { public void setPrimaryStorageUuid(String primaryStorageUuid) { this.primaryStorageUuid = primaryStorageUuid; } - + + @Override + public long getDiskSize() { + return 0; + } + + @Override + public void setDiskSize(long diskSize) { + + } + public static APICreateDataVolumeFromVolumeTemplateMsg __example__() { APICreateDataVolumeFromVolumeTemplateMsg msg = new APICreateDataVolumeFromVolumeTemplateMsg(); msg.setDescription("dataVolume-from-volume-template"); diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy index 6c2af7d0d56..d5d5349b2e0 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeFromVolumeTemplateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "primaryStorageUuid" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "hostUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java index a2b2638381f..9fbb753f19d 100755 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsg.java @@ -3,15 +3,14 @@ import org.springframework.http.HttpMethod; import org.zstack.header.configuration.DiskOfferingVO; import org.zstack.header.identity.Action; -import org.zstack.header.message.APICreateMessage; -import org.zstack.header.message.APIEvent; -import org.zstack.header.message.APIMessage; -import org.zstack.header.message.APIParam; +import org.zstack.header.message.*; import org.zstack.header.other.APIAuditor; import org.zstack.header.rest.RestRequest; import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.header.tag.TagResourceType; +import java.util.concurrent.TimeUnit; + /** * @api create a new data volume * @category volume @@ -48,7 +47,8 @@ parameterName = "params", responseClass = APICreateDataVolumeEvent.class ) -public class APICreateDataVolumeMsg extends APICreateMessage implements APIAuditor { +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 3) +public class APICreateDataVolumeMsg extends APICreateMessage implements APIAuditor, VolumeCreateMessage { /** * @desc max length of 255 characters */ diff --git a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy index 4576d785a52..e919ce27b7b 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateDataVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "diskOfferingUuid" @@ -47,9 +45,8 @@ doc { desc "云盘规格UUID" location "body" type "String" - optional false + optional true since "0.6" - } column { name "primaryStorageUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "tagUuids" @@ -79,7 +74,6 @@ doc { type "List" optional true since "3.4" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "diskSize" + enclosedIn "params" + desc "" + location "body" + type "long" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotGroupMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotGroupMsgDoc_zh_cn.groovy index 8aef3ee934c..d315e11b920 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotGroupMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.6.0" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.6.0" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.6.0" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "3.6.0" - } column { name "tagUuids" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "3.6.0" - } column { name "userTags" @@ -89,7 +83,15 @@ doc { type "List" optional true since "3.6.0" - + } + column { + name "withMemory" + enclosedIn "params" + desc "" + location "body" + type "boolean" + optional true + since "3.8.0" } } } diff --git a/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotMsgDoc_zh_cn.groovy index a7e3547babf..25671a83309 100644 --- a/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APICreateVolumeSnapshotMsgDoc_zh_cn.groovy @@ -7,7 +7,7 @@ doc { category "volume" - desc """在这里填写API描述""" + desc """创建云盘快照""" rest { request { @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIDeleteDataVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIDeleteDataVolumeMsgDoc_zh_cn.groovy index 6253959fa08..82fa9108421 100644 --- a/header/src/main/java/org/zstack/header/volume/APIDeleteDataVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIDeleteDataVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostEvent.java b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostEvent.java new file mode 100644 index 00000000000..d869b4e1b3f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostEvent.java @@ -0,0 +1,19 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDetachDataVolumeFromHostEvent extends APIEvent { + public APIDetachDataVolumeFromHostEvent() { + } + + public APIDetachDataVolumeFromHostEvent(String apiId) { + super(apiId); + } + public static APIDetachDataVolumeFromHostEvent __example__() { + APIDetachDataVolumeFromHostEvent event = new APIDetachDataVolumeFromHostEvent(); + event.setSuccess(true); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..673b9f99aed --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.volume + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "从物理机卸载数据云盘返回" + + field { + name "success" + desc "从物理机卸载数据云盘返回" + type "boolean" + since "4.5.0" + } + ref { + name "error" + path "org.zstack.header.volume.APIDetachDataVolumeFromHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.5.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostMsg.java b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostMsg.java new file mode 100644 index 00000000000..38ffef3dcee --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostMsg.java @@ -0,0 +1,46 @@ +package org.zstack.header.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostVO; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@Action(category = VolumeConstant.ACTION_CATEGORY) +@RestRequest( + path = "/volumes/{volumeUuid}/hosts", + method = HttpMethod.DELETE, + responseClass = APIDetachDataVolumeFromHostEvent.class +) +public class APIDetachDataVolumeFromHostMsg extends APIMessage implements VolumeMessage { + @APIParam(resourceType = VolumeVO.class) + private String volumeUuid; + + @APIParam(required = false, resourceType = HostVO.class) + private String hostUuid; + + @Override + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public static APIDetachDataVolumeFromHostMsg __example__() { + APIDetachDataVolumeFromHostMsg msg = new APIDetachDataVolumeFromHostMsg(); + msg.setVolumeUuid(uuid()); + msg.setHostUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..9616406b1aa --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromHostMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.APIDetachDataVolumeFromHostEvent + +doc { + title "DetachDataVolumeFromHost" + + category "volume" + + desc """从物理机卸载数据云盘""" + + rest { + request { + url "DELETE /v1/volumes/{volumeUuid}/hosts" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDetachDataVolumeFromHostMsg.class + + desc """从物理机卸载数据云盘""" + + params { + + column { + name "volumeUuid" + enclosedIn "" + desc "云盘UUID" + location "url" + type "String" + optional false + since "4.5.0" + } + column { + name "hostUuid" + enclosedIn "" + desc "物理机UUID" + location "body" + type "String" + optional true + since "4.5.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.5.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.5.0" + } + } + } + + response { + clz APIDetachDataVolumeFromHostEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromVmMsgDoc_zh_cn.groovy index bfa60aa4404..ea39839c06f 100644 --- a/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIDetachDataVolumeFromVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "vmUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIExpungeDataVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIExpungeDataVolumeMsgDoc_zh_cn.groovy index b162b3e16b2..7f786321005 100644 --- a/header/src/main/java/org/zstack/header/volume/APIExpungeDataVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIExpungeDataVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeEvent.java b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeEvent.java new file mode 100644 index 00000000000..8cf171ca6c2 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeEvent.java @@ -0,0 +1,54 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.utils.data.SizeUnit; + +import java.sql.Timestamp; + +@RestResponse(allTo = "inventory") +public class APIFlattenVolumeEvent extends APIEvent { + private VolumeInventory inventory; + + public void setInventory(VolumeInventory inventory) { + this.inventory = inventory; + } + + public VolumeInventory getInventory() { + return inventory; + } + + public APIFlattenVolumeEvent() { + super(); + } + + public APIFlattenVolumeEvent(String id) { + super(id); + } + + public static APIFlattenVolumeEvent __example__() { + APIFlattenVolumeEvent event = new APIFlattenVolumeEvent(); + + String volumeUuid = uuid(); + VolumeInventory vol = new VolumeInventory(); + vol.setName("test-volume"); + vol.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setType(VolumeType.Root.toString()); + vol.setUuid(volumeUuid); + vol.setSize(SizeUnit.GIGABYTE.toByte(100)); + vol.setActualSize(SizeUnit.GIGABYTE.toByte(20)); + vol.setDeviceId(0); + vol.setState(VolumeState.Enabled.toString()); + vol.setFormat("qcow2"); + vol.setDiskOfferingUuid(uuid()); + vol.setInstallPath(String.format("/zstack_ps/rootVolumes/acct-36c27e8ff05c4780bf6d2fa65700f22e/vol-%s/%s.qcow2", volumeUuid, volumeUuid)); + vol.setStatus(VolumeStatus.Ready.toString()); + vol.setPrimaryStorageUuid(uuid()); + vol.setVmInstanceUuid(uuid()); + vol.setRootImageUuid(uuid()); + + event.setInventory(vol); + return event; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..985100c0f4c --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.VolumeInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "扁平合并云盘结果" + + ref { + name "inventory" + path "org.zstack.header.volume.APIFlattenVolumeEvent.inventory" + desc "null" + type "VolumeInventory" + since "4.7.0" + clz VolumeInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.volume.APIFlattenVolumeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeMsg.java new file mode 100644 index 00000000000..0f167cdc55c --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeMsg.java @@ -0,0 +1,66 @@ +package org.zstack.header.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +import java.util.concurrent.TimeUnit; + +@Action(category = VolumeConstant.ACTION_CATEGORY) +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 36) +@RestRequest( + path = "/volumes/{uuid}/actions", + isAction = true, + method = HttpMethod.PUT, + responseClass = APIFlattenVolumeEvent.class +) +public class APIFlattenVolumeMsg extends APIMessage implements VolumeMessage, APIAuditor { + @APIParam(resourceType = VolumeVO.class, checkAccount = true, operationTarget = true) + private String uuid; + + @APIParam(required = false) + private boolean dryRun; + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public boolean isDryRun() { + return dryRun; + } + + @Override + public String getVolumeUuid() { + return uuid; + } + + @Override + public APIAuditor.Result audit(APIMessage msg, APIEvent rsp) { + APIFlattenVolumeMsg amsg = (APIFlattenVolumeMsg) msg; + if (amsg.isDryRun()) { + return null; + } + + return new APIAuditor.Result(amsg.getUuid(), VolumeVO.class); + } + + public static APIFlattenVolumeMsg __example__() { + APIFlattenVolumeMsg msg = new APIFlattenVolumeMsg(); + msg.setUuid(uuid()); + msg.setDryRun(false); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..c1789e546d6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIFlattenVolumeMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.APIFlattenVolumeEvent + +doc { + title "FlattenVolume" + + category "volume" + + desc """扁平合并云盘""" + + rest { + request { + url "PUT /v1/volumes/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIFlattenVolumeMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "flattenVolume" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "dryRun" + enclosedIn "flattenVolume" + desc "试运行,可用于预测数据用量" + location "body" + type "boolean" + optional true + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIFlattenVolumeEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/volume/APIGetDataVolumeAttachableVmMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIGetDataVolumeAttachableVmMsgDoc_zh_cn.groovy index 6f4cb45b22c..9a67ac0d96f 100644 --- a/header/src/main/java/org/zstack/header/volume/APIGetDataVolumeAttachableVmMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIGetDataVolumeAttachableVmMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIGetVolumeCapabilitiesMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIGetVolumeCapabilitiesMsgDoc_zh_cn.groovy index 830cf5c0a21..27c446ff124 100644 --- a/header/src/main/java/org/zstack/header/volume/APIGetVolumeCapabilitiesMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIGetVolumeCapabilitiesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIGetVolumeFormatMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIGetVolumeFormatMsgDoc_zh_cn.groovy index a5e930b490c..231c6628457 100644 --- a/header/src/main/java/org/zstack/header/volume/APIGetVolumeFormatMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIGetVolumeFormatMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIQueryVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIQueryVolumeMsgDoc_zh_cn.groovy index 3958b3eaa0d..7f868e05599 100644 --- a/header/src/main/java/org/zstack/header/volume/APIQueryVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIQueryVolumeMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.volume import org.zstack.header.volume.APIQueryVolumeReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "获取云盘清单(QueryVolume)" diff --git a/header/src/main/java/org/zstack/header/volume/APIRecoverDataVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIRecoverDataVolumeMsgDoc_zh_cn.groovy index a9265efa5bc..68783f0c9ab 100644 --- a/header/src/main/java/org/zstack/header/volume/APIRecoverDataVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIRecoverDataVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APISyncVolumeSizeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APISyncVolumeSizeMsgDoc_zh_cn.groovy index 75ea907d39e..9f53f087c29 100644 --- a/header/src/main/java/org/zstack/header/volume/APISyncVolumeSizeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APISyncVolumeSizeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationEvent.java b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationEvent.java new file mode 100644 index 00000000000..652ee4d422f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationEvent.java @@ -0,0 +1,58 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.utils.data.SizeUnit; + +import java.sql.Timestamp; + +/** + * @ Author : yh.w + * @ Date : Created in 15:40 2023/8/21 + */ +@RestResponse(allTo = "inventory") +public class APIUndoSnapshotCreationEvent extends APIEvent { + private VolumeInventory inventory; + + public APIUndoSnapshotCreationEvent() { + } + + public APIUndoSnapshotCreationEvent(String apiId) { + super(apiId); + } + + public VolumeInventory getInventory() { + return inventory; + } + + public void setInventory(VolumeInventory inventory) { + this.inventory = inventory; + } + + public static APIUndoSnapshotCreationEvent __example__() { + APIUndoSnapshotCreationEvent event = new APIUndoSnapshotCreationEvent(); + String volumeUuid = uuid(); + VolumeInventory vol = new VolumeInventory(); + vol.setName("test-volume"); + vol.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + vol.setType(VolumeType.Root.toString()); + vol.setUuid(volumeUuid); + vol.setSize(SizeUnit.GIGABYTE.toByte(100)); + vol.setActualSize(SizeUnit.GIGABYTE.toByte(20)); + vol.setDeviceId(0); + vol.setState(VolumeState.Enabled.toString()); + vol.setFormat("qcow2"); + vol.setDiskOfferingUuid(uuid()); + vol.setInstallPath(String.format("/zstack_ps/rootVolumes/acct-36c27e8ff05c4780bf6d2fa65700f22e/vol-%s/%s.qcow2", volumeUuid, volumeUuid)); + vol.setStatus(VolumeStatus.Ready.toString()); + vol.setPrimaryStorageUuid(uuid()); + vol.setVmInstanceUuid(uuid()); + vol.setRootImageUuid(uuid()); + + event.setInventory(vol); + + return event; + } + +} diff --git a/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationEventDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..ab922752020 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.VolumeInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "在这里输入结构的名称" + + ref { + name "inventory" + path "org.zstack.header.volume.APIUndoSnapshotCreationEvent.inventory" + desc "null" + type "VolumeInventory" + since "4.7.0" + clz VolumeInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.header.volume.APIUndoSnapshotCreationEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationMsg.java b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationMsg.java new file mode 100644 index 00000000000..5e64ecb9ec0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationMsg.java @@ -0,0 +1,55 @@ +package org.zstack.header.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO; + +/** + * @ Author : yh.w + * @ Date : Created in 15:40 2023/8/21 + */ +@Action(category = VolumeConstant.ACTION_CATEGORY) +@RestRequest( + path = "/volumes/{uuid}/actions", + isAction = true, + method = HttpMethod.PUT, + responseClass = APIUndoSnapshotCreationEvent.class +) +public class APIUndoSnapshotCreationMsg extends APIMessage implements VolumeMessage { + + @APIParam(resourceType = VolumeVO.class, checkAccount = true, operationTarget = true) + private String uuid; + @APIParam(resourceType = VolumeSnapshotVO.class, checkAccount = true, operationTarget = true) + private String snapShotUuid; + + public String getSnapShotUuid() { + return snapShotUuid; + } + + public void setSnapShotUuid(String snapShotUuid) { + this.snapShotUuid = snapShotUuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getVolumeUuid() { + return uuid; + } + + public static APIUndoSnapshotCreationMsg __example__() { + APIUndoSnapshotCreationMsg msg = new APIUndoSnapshotCreationMsg(); + msg.setUuid(uuid()); + msg.setSnapShotUuid(uuid()); + return msg; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..5d479b0218f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/APIUndoSnapshotCreationMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.volume + +import org.zstack.header.volume.APIUndoSnapshotCreationEvent + +doc { + title "UndoSnapshotCreation" + + category "volume" + + desc """在这里填写API描述""" + + rest { + request { + url "PUT /v1/volumes/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUndoSnapshotCreationMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "undoSnapshotCreation" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.0" + } + column { + name "snapShotUuid" + enclosedIn "undoSnapshotCreation" + desc "" + location "body" + type "String" + optional false + since "4.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.0" + } + } + } + + response { + clz APIUndoSnapshotCreationEvent.class + } + } +} \ No newline at end of file diff --git a/header/src/main/java/org/zstack/header/volume/APIUpdateVolumeMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/APIUpdateVolumeMsgDoc_zh_cn.groovy index c45c0d49af2..70d9d462b21 100644 --- a/header/src/main/java/org/zstack/header/volume/APIUpdateVolumeMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/APIUpdateVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/volume/BatchSyncActiveVolumeSizeOnHostMsg.java b/header/src/main/java/org/zstack/header/volume/BatchSyncActiveVolumeSizeOnHostMsg.java new file mode 100644 index 00000000000..a8b070bdbae --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/BatchSyncActiveVolumeSizeOnHostMsg.java @@ -0,0 +1,15 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +public class BatchSyncActiveVolumeSizeOnHostMsg extends NeedReplyMessage { + private String hostUuid; + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getHostUuid() { + return hostUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/BatchSyncActiveVolumeSizeOnHostReply.java b/header/src/main/java/org/zstack/header/volume/BatchSyncActiveVolumeSizeOnHostReply.java new file mode 100644 index 00000000000..25dec3d2d87 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/BatchSyncActiveVolumeSizeOnHostReply.java @@ -0,0 +1,33 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +public class BatchSyncActiveVolumeSizeOnHostReply extends MessageReply { + private Integer successCount = 0; + + private Integer failCount = 0; + + public void setSuccessCount(Integer successCount) { + this.successCount = successCount; + } + + public Integer getSuccessCount() { + return successCount; + } + + public void setFailCount(Integer failCount) { + this.failCount = failCount; + } + + public Integer getFailCount() { + return failCount; + } + + public synchronized void addSuccessCount(Integer successCount) { + this.successCount = this.successCount + successCount; + } + + public synchronized void addFailCount(Integer failCount) { + this.failCount = this.failCount + failCount; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/BatchSyncManagedActiveVolumeSizeMsg.java b/header/src/main/java/org/zstack/header/volume/BatchSyncManagedActiveVolumeSizeMsg.java new file mode 100644 index 00000000000..1d66e1acc12 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/BatchSyncManagedActiveVolumeSizeMsg.java @@ -0,0 +1,15 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +public class BatchSyncManagedActiveVolumeSizeMsg extends NeedReplyMessage { + private String clusterUuid; + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/BatchSyncManagedActiveVolumeSizeReply.java b/header/src/main/java/org/zstack/header/volume/BatchSyncManagedActiveVolumeSizeReply.java new file mode 100644 index 00000000000..c8192139709 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/BatchSyncManagedActiveVolumeSizeReply.java @@ -0,0 +1,33 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +public class BatchSyncManagedActiveVolumeSizeReply extends MessageReply { + private int successCount; + + private int failCount; + + public void setSuccessCount(int successCount) { + this.successCount = successCount; + } + + public int getSuccessCount() { + return successCount; + } + + public void setFailCount(int failCount) { + this.failCount = failCount; + } + + public int getFailCount() { + return failCount; + } + + public synchronized void addSuccessCount(int successCount) { + this.successCount = this.successCount + successCount; + } + + public synchronized void addFailCount(int failCount) { + this.failCount = this.failCount + failCount; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/BatchSyncVolumeSizeOnPrimaryStorageMsg.java b/header/src/main/java/org/zstack/header/volume/BatchSyncVolumeSizeOnPrimaryStorageMsg.java new file mode 100644 index 00000000000..4ab12a3b2a8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/BatchSyncVolumeSizeOnPrimaryStorageMsg.java @@ -0,0 +1,38 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.primary.PrimaryStorageMessage; + +import java.util.Map; + +public class BatchSyncVolumeSizeOnPrimaryStorageMsg extends NeedReplyMessage implements PrimaryStorageMessage { + private String hostUuid; + + private String primaryStorageUuid; + + private Map volumeUuidInstallPaths; + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setVolumeUuidInstallPaths(Map volumeUuidInstallPaths) { + this.volumeUuidInstallPaths = volumeUuidInstallPaths; + } + + public Map getVolumeUuidInstallPaths() { + return volumeUuidInstallPaths; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/BatchSyncVolumeSizeOnPrimaryStorageReply.java b/header/src/main/java/org/zstack/header/volume/BatchSyncVolumeSizeOnPrimaryStorageReply.java new file mode 100644 index 00000000000..ee543ba398a --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/BatchSyncVolumeSizeOnPrimaryStorageReply.java @@ -0,0 +1,18 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +import java.util.HashMap; +import java.util.Map; + +public class BatchSyncVolumeSizeOnPrimaryStorageReply extends MessageReply { + private Map actualSizes = new HashMap<>(); + + public void setActualSizes(Map actualSizes) { + this.actualSizes = actualSizes; + } + + public Map getActualSizes() { + return actualSizes; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/CancelFlattenVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/CancelFlattenVolumeMsg.java new file mode 100644 index 00000000000..231c92e7ad1 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/CancelFlattenVolumeMsg.java @@ -0,0 +1,20 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.CancelMessage; + +public class CancelFlattenVolumeMsg extends CancelMessage implements VolumeMessage { + private String uuid; + + @Override + public String getVolumeUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/CancelFlattenVolumeReply.java b/header/src/main/java/org/zstack/header/volume/CancelFlattenVolumeReply.java new file mode 100644 index 00000000000..14fd0fe657c --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/CancelFlattenVolumeReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +public class CancelFlattenVolumeReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/volume/ChangeVolumeTypeMsg.java b/header/src/main/java/org/zstack/header/volume/ChangeVolumeTypeMsg.java new file mode 100644 index 00000000000..75bc4e3018e --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/ChangeVolumeTypeMsg.java @@ -0,0 +1,29 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +public class ChangeVolumeTypeMsg extends NeedReplyMessage implements VolumeMessage { + private String uuid; + private VolumeType type; + + @Override + public String getVolumeUuid() { + return uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public VolumeType getType() { + return type; + } + + public void setType(VolumeType type) { + this.type = type; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/ChangeVolumeTypeReply.java b/header/src/main/java/org/zstack/header/volume/ChangeVolumeTypeReply.java new file mode 100644 index 00000000000..3ef1a98afc6 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/ChangeVolumeTypeReply.java @@ -0,0 +1,6 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +public class ChangeVolumeTypeReply extends MessageReply { +} diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeExtensionPoint.java index c3a56429254..6ce8ed6ab7f 100644 --- a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeExtensionPoint.java @@ -4,7 +4,7 @@ * Created by mingjian.deng on 2017/9/20. */ public interface CreateDataVolumeExtensionPoint { - void preCreateVolume(APICreateDataVolumeMsg msg); + void preCreateVolume(VolumeCreateMessage msg); void beforeCreateVolume(VolumeInventory volume); diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeSnapshotReply.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeSnapshotReply.java index 76f4dd077c1..745a7562337 100644 --- a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeSnapshotReply.java +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeSnapshotReply.java @@ -2,14 +2,5 @@ import org.zstack.header.message.MessageReply; -public class CreateDataVolumeFromVolumeSnapshotReply extends MessageReply { - private VolumeInventory inventory; - - public VolumeInventory getInventory() { - return inventory; - } - - public void setInventory(VolumeInventory inventory) { - this.inventory = inventory; - } +public class CreateDataVolumeFromVolumeSnapshotReply extends CreateDataVolumeReply { } diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateReply.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateReply.java index 730dc8fd194..25f58db5f4a 100644 --- a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateReply.java +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeFromVolumeTemplateReply.java @@ -5,14 +5,5 @@ /** * Create by weiwang at 2018/6/19 */ -public class CreateDataVolumeFromVolumeTemplateReply extends MessageReply { - private VolumeInventory inventory; - - public VolumeInventory getInventory() { - return inventory; - } - - public void setInventory(VolumeInventory inventory) { - this.inventory = inventory; - } +public class CreateDataVolumeFromVolumeTemplateReply extends CreateDataVolumeReply { } diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java new file mode 100644 index 00000000000..833df491428 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeMsg.java @@ -0,0 +1,78 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +public class CreateDataVolumeMsg extends NeedReplyMessage implements VolumeCreateMessage { + private String name; + private String description; + private String diskOfferingUuid; + private long diskSize; + private String primaryStorageUuid; + private String accountUuid; + private String resourceUuid; + private APICreateDataVolumeMsg apiMsg; + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDiskOfferingUuid() { + return diskOfferingUuid; + } + + public void setDiskOfferingUuid(String diskOfferingUuid) { + this.diskOfferingUuid = diskOfferingUuid; + } + + public long getDiskSize() { + return diskSize; + } + + public void setDiskSize(long diskSize) { + this.diskSize = diskSize; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public APICreateDataVolumeMsg getApiMsg() { + return apiMsg; + } + + public void setApiMsg(APICreateDataVolumeMsg apiMsg) { + this.apiMsg = apiMsg; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeReply.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeReply.java new file mode 100644 index 00000000000..95f336adbfd --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +public abstract class CreateDataVolumeReply extends MessageReply { + private VolumeInventory inventory; + + public VolumeInventory getInventory() { + return inventory; + } + + public void setInventory(VolumeInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeMsg.java index 80f30f5b714..1873579b980 100755 --- a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeMsg.java @@ -6,6 +6,15 @@ public class CreateDataVolumeTemplateFromDataVolumeMsg extends NeedReplyMessage private String volumeUuid; private String backupStorageUuid; private String imageUuid; + private boolean queuedInVolume = true; + + public boolean isQueuedInVolume() { + return queuedInVolume; + } + + public void setQueuedInVolume(boolean queuedInVolume) { + this.queuedInVolume = queuedInVolume; + } public String getImageUuid() { return imageUuid; diff --git a/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeSnapshotMsg.java b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeSnapshotMsg.java new file mode 100644 index 00000000000..85d41d70fdc --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/CreateDataVolumeTemplateFromDataVolumeSnapshotMsg.java @@ -0,0 +1,13 @@ +package org.zstack.header.volume; + +public class CreateDataVolumeTemplateFromDataVolumeSnapshotMsg extends CreateDataVolumeTemplateFromDataVolumeMsg { + private String snapshotUuid; + + public String getSnapshotUuid() { + return snapshotUuid; + } + + public void setSnapshotUuid(String snapshotUuid) { + this.snapshotUuid = snapshotUuid; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/CreateVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/CreateVolumeMsg.java index 43b54aad7e8..e8d22cb9a99 100755 --- a/header/src/main/java/org/zstack/header/volume/CreateVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/CreateVolumeMsg.java @@ -2,7 +2,7 @@ import org.zstack.header.message.NeedReplyMessage; -public class CreateVolumeMsg extends NeedReplyMessage { +public class CreateVolumeMsg extends NeedReplyMessage implements VolumeCreateMessage { private long size; private long actualSize; private String primaryStorageUuid; @@ -15,6 +15,7 @@ public class CreateVolumeMsg extends NeedReplyMessage { private String diskOfferingUuid; private String format; private String resourceUuid; + private String protocol; public String getFormat() { return format; @@ -48,6 +49,16 @@ public void setPrimaryStorageUuid(String primaryStorageUuid) { this.primaryStorageUuid = primaryStorageUuid; } + @Override + public long getDiskSize() { + return getSize(); + } + + @Override + public void setDiskSize(long diskSize) { + setSize(diskSize); + } + public String getVmInstanceUuid() { return vmInstanceUuid; } @@ -111,4 +122,12 @@ public long getActualSize() { public void setActualSize(long actualSize) { this.actualSize = actualSize; } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeMsg.java b/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeMsg.java index e931e534cc8..530faf12e4e 100644 --- a/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeMsg.java @@ -5,6 +5,8 @@ public class EstimateVolumeTemplateSizeMsg extends NeedReplyMessage implements VolumeMessage { private String volumeUuid; + private boolean ignoreError = true; + @Override public String getVolumeUuid() { return volumeUuid; @@ -13,4 +15,12 @@ public String getVolumeUuid() { public void setVolumeUuid(String volumeUuid) { this.volumeUuid = volumeUuid; } + + public boolean isIgnoreError() { + return ignoreError; + } + + public void setIgnoreError(boolean ignoreError) { + this.ignoreError = ignoreError; + } } diff --git a/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeReply.java b/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeReply.java index 180cebe3591..700e489b600 100644 --- a/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeReply.java +++ b/header/src/main/java/org/zstack/header/volume/EstimateVolumeTemplateSizeReply.java @@ -5,6 +5,7 @@ public class EstimateVolumeTemplateSizeReply extends MessageReply { private long actualSize; private long size; + private boolean withInternalSnapshot; public long getSize() { return size; @@ -21,4 +22,12 @@ public long getActualSize() { public void setActualSize(long actualSize) { this.actualSize = actualSize; } + + public void setWithInternalSnapshot(boolean withInternalSnapshot) { + this.withInternalSnapshot = withInternalSnapshot; + } + + public boolean isWithInternalSnapshot() { + return withInternalSnapshot; + } } diff --git a/header/src/main/java/org/zstack/header/volume/FlattenVolumeExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/FlattenVolumeExtensionPoint.java new file mode 100644 index 00000000000..79c86c73a89 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/FlattenVolumeExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.volume; + +public interface FlattenVolumeExtensionPoint { + void afterFlattenVolume(VolumeInventory volume); +} diff --git a/header/src/main/java/org/zstack/header/volume/FlattenVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/FlattenVolumeMsg.java new file mode 100644 index 00000000000..151245878bc --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/FlattenVolumeMsg.java @@ -0,0 +1,29 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +public class FlattenVolumeMsg extends NeedReplyMessage implements VolumeMessage { + private String uuid; + private boolean dryRun; + + @Override + public String getVolumeUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + + public void setDryRun(boolean dryRun) { + this.dryRun = dryRun; + } + + public boolean isDryRun() { + return dryRun; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/FlattenVolumeReply.java b/header/src/main/java/org/zstack/header/volume/FlattenVolumeReply.java new file mode 100644 index 00000000000..d01a3db7f5c --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/FlattenVolumeReply.java @@ -0,0 +1,15 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +public class FlattenVolumeReply extends MessageReply { + private VolumeInventory inventory; + + public void setInventory(VolumeInventory inventory) { + this.inventory = inventory; + } + + public VolumeInventory getInventory() { + return inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/GetVolumeLocalTaskMsg.java b/header/src/main/java/org/zstack/header/volume/GetVolumeLocalTaskMsg.java new file mode 100644 index 00000000000..eddacb81ec8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/GetVolumeLocalTaskMsg.java @@ -0,0 +1,17 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; + +public class GetVolumeLocalTaskMsg extends NeedReplyMessage { + List volumeUuids; + + public void setVolumeUuids(List volumeUuids) { + this.volumeUuids = volumeUuids; + } + + public List getVolumeUuids() { + return volumeUuids; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/GetVolumeLocalTaskReply.java b/header/src/main/java/org/zstack/header/volume/GetVolumeLocalTaskReply.java new file mode 100644 index 00000000000..0cdac0de08d --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/GetVolumeLocalTaskReply.java @@ -0,0 +1,23 @@ +package org.zstack.header.volume; + +import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.message.MessageReply; + +import java.util.HashMap; +import java.util.Map; + +public class GetVolumeLocalTaskReply extends MessageReply { + private Map results = new HashMap<>(); + + public Map getResults() { + return results; + } + + public void setResults(Map results) { + this.results = results; + } + + public void putResults(String hostUuid, ChainInfo info) { + results.put(hostUuid, info); + } +} diff --git a/header/src/main/java/org/zstack/header/volume/GetVolumeTaskMsg.java b/header/src/main/java/org/zstack/header/volume/GetVolumeTaskMsg.java new file mode 100644 index 00000000000..910e8e8bdb0 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/GetVolumeTaskMsg.java @@ -0,0 +1,17 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +import java.util.List; + +public class GetVolumeTaskMsg extends NeedReplyMessage { + List volumeUuids; + + public void setVolumeUuids(List volumeUuids) { + this.volumeUuids = volumeUuids; + } + + public List getVolumeUuids() { + return volumeUuids; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/GetVolumeTaskReply.java b/header/src/main/java/org/zstack/header/volume/GetVolumeTaskReply.java new file mode 100644 index 00000000000..49d669bea49 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/GetVolumeTaskReply.java @@ -0,0 +1,19 @@ +package org.zstack.header.volume; + +import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.message.MessageReply; + +import java.util.HashMap; +import java.util.Map; + +public class GetVolumeTaskReply extends MessageReply { + private Map results = new HashMap<>(); + + public Map getResults() { + return results; + } + + public void setResults(Map results) { + this.results = results; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/InstantiateVolumeMsg.java b/header/src/main/java/org/zstack/header/volume/InstantiateVolumeMsg.java index 701296b1477..13e6f557b24 100755 --- a/header/src/main/java/org/zstack/header/volume/InstantiateVolumeMsg.java +++ b/header/src/main/java/org/zstack/header/volume/InstantiateVolumeMsg.java @@ -11,14 +11,14 @@ public class InstantiateVolumeMsg extends NeedReplyMessage implements VolumeMess private String hostUuid; private boolean primaryStorageAllocated; private boolean skipIfExisting; - private String installUrl; + private String allocatedInstallUrl; - public String getInstallUrl() { - return installUrl; + public String getAllocatedInstallUrl() { + return allocatedInstallUrl; } - public void setInstallUrl(String installUrl) { - this.installUrl = installUrl; + public void setAllocatedInstallUrl(String allocatedInstallUrl) { + this.allocatedInstallUrl = allocatedInstallUrl; } public boolean isPrimaryStorageAllocated() { diff --git a/header/src/main/java/org/zstack/header/volume/OverwriteVolumeExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/OverwriteVolumeExtensionPoint.java index 384b94f89b5..c90f3566c3b 100644 --- a/header/src/main/java/org/zstack/header/volume/OverwriteVolumeExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/volume/OverwriteVolumeExtensionPoint.java @@ -1,8 +1,9 @@ package org.zstack.header.volume; - +import org.zstack.header.volume.VolumeDeletionPolicyManager.VolumeDeletionPolicy; /** * Created by MaJin on 2019/4/2. */ public interface OverwriteVolumeExtensionPoint { + void innerOverwriteVolume(VolumeInventory originVolume, VolumeInventory transientVolume, VolumeDeletionPolicy originVolumeDeletionPolicy); void afterOverwriteVolume(VolumeInventory volume, VolumeInventory transientVolume); } diff --git a/header/src/main/java/org/zstack/header/volume/PackageInfo.java b/header/src/main/java/org/zstack/header/volume/PackageInfo.java index 478de369540..daf195afe21 100755 --- a/header/src/main/java/org/zstack/header/volume/PackageInfo.java +++ b/header/src/main/java/org/zstack/header/volume/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "云硬盘") +@PackageAPIInfo( + APICategoryName = "云硬盘", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/header/src/main/java/org/zstack/header/volume/SetVolumeQosMsg.java b/header/src/main/java/org/zstack/header/volume/SetVolumeQosMsg.java new file mode 100644 index 00000000000..9869c83c08c --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/SetVolumeQosMsg.java @@ -0,0 +1,113 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * Created by LiangHanYu on 2022/7/3 16:52 + */ +public class SetVolumeQosMsg extends NeedReplyMessage implements VolumeMessage { + private String uuid; + + private String mode = null; + + private Long volumeBandwidth; + + private Long readBandwidth; + + private Long writeBandwidth; + + private Long totalBandwidth; + + private Long readIOPS; + + private Long writeIOPS; + + private Long totalIOPS; + + private Integer version; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public Long getVolumeBandwidth() { + return volumeBandwidth; + } + + public void setVolumeBandwidth(Long volumeBandwidth) { + this.volumeBandwidth = volumeBandwidth; + } + + public Long getReadBandwidth() { + return readBandwidth; + } + + public void setReadBandwidth(Long readBandwidth) { + this.readBandwidth = readBandwidth; + } + + public Long getWriteBandwidth() { + return writeBandwidth; + } + + public void setWriteBandwidth(Long writeBandwidth) { + this.writeBandwidth = writeBandwidth; + } + + public Long getTotalBandwidth() { + return totalBandwidth; + } + + public void setTotalBandwidth(Long totalBandwidth) { + this.totalBandwidth = totalBandwidth; + } + + public Long getReadIOPS() { + return readIOPS; + } + + public void setReadIOPS(Long readIOPS) { + this.readIOPS = readIOPS; + } + + public Long getWriteIOPS() { + return writeIOPS; + } + + public void setWriteIOPS(Long writeIOPS) { + this.writeIOPS = writeIOPS; + } + + public Long getTotalIOPS() { + return totalIOPS; + } + + public void setTotalIOPS(Long totalIOPS) { + this.totalIOPS = totalIOPS; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + @Override + public String getVolumeUuid() { + return uuid; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/SetVolumeQosReply.java b/header/src/main/java/org/zstack/header/volume/SetVolumeQosReply.java new file mode 100644 index 00000000000..51e28d2d758 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/SetVolumeQosReply.java @@ -0,0 +1,18 @@ +package org.zstack.header.volume; + +import org.zstack.header.message.MessageReply; + +/** + * Created by LiangHanYu on 2022/7/3 16:52 + */ +public class SetVolumeQosReply extends MessageReply { + private VolumeInventory inventory; + + public VolumeInventory getInventory() { + return inventory; + } + + public void setInventory(VolumeInventory inventory) { + this.inventory = inventory; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeAO.java b/header/src/main/java/org/zstack/header/volume/VolumeAO.java index 51faf681bce..3ddcdbccad3 100755 --- a/header/src/main/java/org/zstack/header/volume/VolumeAO.java +++ b/header/src/main/java/org/zstack/header/volume/VolumeAO.java @@ -10,6 +10,7 @@ import javax.persistence.*; import java.sql.Timestamp; +import java.text.SimpleDateFormat; @MappedSuperclass public class VolumeAO extends ResourceVO implements ShadowEntity { @@ -73,12 +74,18 @@ public class VolumeAO extends ResourceVO implements ShadowEntity { @Column private Timestamp lastDetachDate; + @Column + private Timestamp lastAttachDate; + @Column private boolean isShareable; @Column private String volumeQos; + @Column + private String protocol; + @Transient private VolumeAO shadow; @@ -184,6 +191,14 @@ public boolean isDisk() { return type == VolumeType.Data || type == VolumeType.Root; } + public boolean isDataVolume() { + return type == VolumeType.Data; + } + + public boolean isMemoryVolume() { + return type == VolumeType.Memory; + } + public long getSize() { return size; } @@ -267,4 +282,20 @@ public String getVolumeQos() { public void setVolumeQos(String volumeQos) { this.volumeQos = volumeQos; } + + public Timestamp getLastAttachDate() { + return lastAttachDate; + } + + public void setLastAttachDate(Timestamp lastAttachDate) { + this.lastAttachDate = lastAttachDate; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/volume/VolumeAO_.java b/header/src/main/java/org/zstack/header/volume/VolumeAO_.java index c96f901a0ef..729d50eefbf 100755 --- a/header/src/main/java/org/zstack/header/volume/VolumeAO_.java +++ b/header/src/main/java/org/zstack/header/volume/VolumeAO_.java @@ -26,7 +26,9 @@ public class VolumeAO_ extends ResourceVO_ { public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; public static volatile SingularAttribute lastDetachDate; + public static volatile SingularAttribute lastAttachDate; public static volatile SingularAttribute lastVmInstanceUuid; public static volatile SingularAttribute isShareable; public static volatile SingularAttribute volumeQos; + public static volatile SingularAttribute protocol; } diff --git a/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java index c5f20e956a6..673c7cbf9bd 100755 --- a/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java +++ b/header/src/main/java/org/zstack/header/volume/VolumeBeforeExpungeExtensionPoint.java @@ -1,11 +1,16 @@ package org.zstack.header.volume; import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; /** * Created by xing5 on 2016/5/3. */ public interface VolumeBeforeExpungeExtensionPoint { void volumePreExpunge(VolumeInventory volume); - void volumeBeforeExpunge(VolumeInventory volume, Completion completion); + void volumeBeforeExpunge(VolumeInventory volume, NoErrorCompletion completion); + + default boolean skipExpungeVolume(VolumeInventory volume) { + return false; + } } diff --git a/header/src/main/java/org/zstack/header/volume/VolumeConfigs.java b/header/src/main/java/org/zstack/header/volume/VolumeConfigs.java new file mode 100644 index 00000000000..0693125b54f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeConfigs.java @@ -0,0 +1,17 @@ +package org.zstack.header.volume; + +/** + * @ Author : yh.w + * @ Date : Created in 16:38 2025/1/24 + */ +public class VolumeConfigs { + private int queueNum = 1; + + public int getQueueNum() { + return queueNum; + } + + public void setQueueNum(int queueNum) { + this.queueNum = queueNum; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeConfigsExtensionPoint.java b/header/src/main/java/org/zstack/header/volume/VolumeConfigsExtensionPoint.java new file mode 100644 index 00000000000..961515ab198 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeConfigsExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.header.volume; + +public interface VolumeConfigsExtensionPoint { + void setVolumeConfigs(VolumeConfigs vcs, String volUuid); +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeConstant.java b/header/src/main/java/org/zstack/header/volume/VolumeConstant.java index 233c3b0cdb0..15d3062975c 100755 --- a/header/src/main/java/org/zstack/header/volume/VolumeConstant.java +++ b/header/src/main/java/org/zstack/header/volume/VolumeConstant.java @@ -8,6 +8,9 @@ public interface VolumeConstant { String VOLUME_FORMAT_RAW = "raw"; String VOLUME_FORMAT_QCOW2 = "qcow2"; String VOLUME_FORMAT_VMTX = "vmtx"; + String VOLUME_FORMAT_VMDK = "vmdk"; + int DEFAULT_MAX_DATA_VOLUME_NUMBER = 24; + String BLOCK_VOLUME_TYPE = "blockVolume"; enum Capability { MigrationInCurrentPrimaryStorage, diff --git a/header/src/main/java/org/zstack/header/volume/VolumeCreateMessage.java b/header/src/main/java/org/zstack/header/volume/VolumeCreateMessage.java new file mode 100644 index 00000000000..a93217a6166 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeCreateMessage.java @@ -0,0 +1,23 @@ +package org.zstack.header.volume; + +import java.util.List; + +public interface VolumeCreateMessage { + String getDiskOfferingUuid(); + + void setDiskOfferingUuid(String diskOfferingUuid); + + String getPrimaryStorageUuid(); + + void setPrimaryStorageUuid(String primaryStorageUuid); + + long getDiskSize(); + + void setDiskSize(long diskSize); + + List getSystemTags(); + + void setSystemTags(List systemTags); + + void addSystemTag(String tag); +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeCreateSnapshotMsg.java b/header/src/main/java/org/zstack/header/volume/VolumeCreateSnapshotMsg.java index ecfbe874c0c..a538f3cf1ee 100755 --- a/header/src/main/java/org/zstack/header/volume/VolumeCreateSnapshotMsg.java +++ b/header/src/main/java/org/zstack/header/volume/VolumeCreateSnapshotMsg.java @@ -1,22 +1,37 @@ package org.zstack.header.volume; -import org.zstack.header.message.DefaultTimeout; import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.message.NeedReplyMessage; - -import java.util.concurrent.TimeUnit; +import org.zstack.header.storage.snapshot.SnapshotMode; /** * Created by david on 10/7/16. */ -@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 3) public class VolumeCreateSnapshotMsg extends NeedReplyMessage implements VolumeMessage, NeedQuotaCheckMessage { private String accountUuid; private String resourceUuid; private String name; private String description; private String volumeUuid; + private SnapshotMode requiredSnapshotMode = SnapshotMode.AUTO; + private boolean queuedInVolume = true; + + public boolean isQueuedInVolume() { + return queuedInVolume; + } + + public void setQueuedInVolume(boolean queuedInVolume) { + this.queuedInVolume = queuedInVolume; + } + + public SnapshotMode getRequiredSnapshotMode() { + return requiredSnapshotMode; + } + + public void setRequiredSnapshotMode(SnapshotMode requiredSnapshotMode) { + this.requiredSnapshotMode = requiredSnapshotMode; + } @Override public String getVolumeUuid() { diff --git a/header/src/main/java/org/zstack/header/volume/VolumeHostRefInventory.java b/header/src/main/java/org/zstack/header/volume/VolumeHostRefInventory.java new file mode 100644 index 00000000000..30035d8031f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeHostRefInventory.java @@ -0,0 +1,90 @@ +package org.zstack.header.volume; + +import org.zstack.header.host.HostInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@Inventory(mappingVOClass = VolumeHostRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "host", inventoryClass = HostInventory.class, + foreignKey = "hostUuid", expandedInventoryKey = "uuid") +}) +public class VolumeHostRefInventory implements Serializable { + private String hostUuid; + private String volumeUuid; + private String mountPath; + private String device; + private Timestamp createDate; + private Timestamp lastOpDate; + + public VolumeHostRefInventory() { + } + + public static VolumeHostRefInventory valueOf(VolumeHostRefVO vo) { + VolumeHostRefInventory inv = new VolumeHostRefInventory(); + inv.setHostUuid(vo.getHostUuid()); + inv.setVolumeUuid(vo.getVolumeUuid()); + inv.setMountPath(vo.getMountPath()); + inv.setDevice(vo.getDevice()); + return inv; + } + + public static List valueOf(Collection vos) { + return vos.stream().map(VolumeHostRefInventory::valueOf).collect(Collectors.toList()); + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getMountPath() { + return mountPath; + } + + public void setMountPath(String mountPath) { + this.mountPath = mountPath; + } + + public String getDevice() { + return device; + } + + public void setDevice(String device) { + this.device = device; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeHostRefVO.java b/header/src/main/java/org/zstack/header/volume/VolumeHostRefVO.java new file mode 100644 index 00000000000..47ac182cf20 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeHostRefVO.java @@ -0,0 +1,95 @@ +package org.zstack.header.volume; + +import org.zstack.header.host.HostEO; +import org.zstack.header.host.HostVO; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; +import java.io.Serializable; +import java.sql.Timestamp; + +@Entity +@Table +@org.zstack.header.vo.EntityGraph( + parents = { + @EntityGraph.Neighbour(type = HostEO.class, myField = "hostUuid", targetField = "uuid") + } +) +public class VolumeHostRefVO { + @Column + @Id + private String volumeUuid; + + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String hostUuid; + + @Column + private String mountPath; + + @Column + private String device; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public VolumeHostRefVO() { + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getMountPath() { + return mountPath; + } + + public void setMountPath(String mountPath) { + this.mountPath = mountPath; + } + + public String getDevice() { + return device; + } + + public void setDevice(String device) { + this.device = device; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeHostRefVO_.java b/header/src/main/java/org/zstack/header/volume/VolumeHostRefVO_.java new file mode 100644 index 00000000000..17b3f482fc8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeHostRefVO_.java @@ -0,0 +1,15 @@ +package org.zstack.header.volume; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(VolumeHostRefVO.class) +public class VolumeHostRefVO_ { + public static volatile SingularAttribute hostUuid; + public static volatile SingularAttribute volumeUuid; + public static volatile SingularAttribute mountPath; + public static volatile SingularAttribute device; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeInfo.java b/header/src/main/java/org/zstack/header/volume/VolumeInfo.java new file mode 100644 index 00000000000..4e1dd9c15c9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeInfo.java @@ -0,0 +1,37 @@ +package org.zstack.header.volume; + +public class VolumeInfo { + private String installPath; + private Long actualSize; + private Long size; + + public VolumeInfo(String installPath, Long actualSize, Long size) { + this.installPath = installPath; + this.actualSize = actualSize; + this.size = size; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public Long getActualSize() { + return actualSize; + } + + public void setActualSize(Long actualSize) { + this.actualSize = actualSize; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeInventory.java b/header/src/main/java/org/zstack/header/volume/VolumeInventory.java index e5f90b89e90..96d2ae67a62 100755 --- a/header/src/main/java/org/zstack/header/volume/VolumeInventory.java +++ b/header/src/main/java/org/zstack/header/volume/VolumeInventory.java @@ -1,5 +1,6 @@ package org.zstack.header.volume; +import com.fasterxml.jackson.annotation.JsonFormat; import org.zstack.header.configuration.DiskOfferingInventory; import org.zstack.header.configuration.PythonClassInventory; import org.zstack.header.image.ImageInventory; @@ -152,6 +153,9 @@ public class VolumeInventory implements Serializable { private String lastVmInstanceUuid; + private Timestamp lastAttachDate; + private String protocol; + public VolumeInventory() { } @@ -177,10 +181,13 @@ public VolumeInventory(VolumeInventory other) { this.volumeQos = other.volumeQos; this.lastDetachDate = other.lastDetachDate; this.lastVmInstanceUuid = other.lastVmInstanceUuid; + this.lastAttachDate = other.lastAttachDate; + this.protocol = other.protocol; } - public static VolumeInventory valueOf(VolumeVO vo) { + public static VolumeInventory + valueOf(VolumeVO vo) { VolumeInventory inv = new VolumeInventory(); inv.setRootImageUuid(vo.getRootImageUuid()); inv.setCreateDate(vo.getCreateDate()); @@ -204,6 +211,8 @@ public static VolumeInventory valueOf(VolumeVO vo) { inv.setVolumeQos(vo.getVolumeQos()); inv.setLastDetachDate(vo.getLastDetachDate()); inv.setLastVmInstanceUuid(vo.getLastVmInstanceUuid()); + inv.setLastAttachDate(vo.getLastAttachDate()); + inv.setProtocol(vo.getProtocol()); return inv; } @@ -300,7 +309,11 @@ public boolean isDisk() { } public long getSize() { - return size; + if (size != null) { + return size; + } + + return 0L; } public void setSize(long size) { @@ -408,4 +421,20 @@ public void setLastVmInstanceUuid(String lastVmInstanceUuid) { public static void setAttachedJudgers(List attachedJudgers) { VolumeInventory.attachedJudgers = attachedJudgers; } + + public Timestamp getLastAttachDate() { + return lastAttachDate; + } + + public void setLastAttachDate(Timestamp lastAttachDate) { + this.lastAttachDate = lastAttachDate; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } } diff --git a/header/src/main/java/org/zstack/header/volume/VolumeInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/VolumeInventoryDoc_zh_cn.groovy index 6d91534b8e6..90929e175a5 100644 --- a/header/src/main/java/org/zstack/header/volume/VolumeInventoryDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/volume/VolumeInventoryDoc_zh_cn.groovy @@ -1,121 +1,138 @@ package org.zstack.header.volume +import java.lang.Long +import java.lang.Integer +import java.sql.Timestamp +import java.lang.Boolean + doc { - title "云盘清单" + title "在这里输入结构的名称" field { name "uuid" desc "资源的UUID,唯一标示该资源" type "String" - since "0.6" + since "4.7.13" } field { name "name" desc "资源名称" type "String" - since "0.6" + since "4.7.13" } field { name "description" desc "资源的详细描述" type "String" - since "0.6" + since "4.7.13" } field { name "primaryStorageUuid" desc "主存储UUID" type "String" - since "0.6" + since "4.7.13" } field { name "vmInstanceUuid" desc "云主机UUID" type "String" - since "0.6" + since "4.7.13" } field { name "diskOfferingUuid" desc "云盘规格UUID" type "String" - since "0.6" + since "4.7.13" } field { name "rootImageUuid" - desc "云盘根镜像UUID" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "installPath" - desc "云盘在主存储上的路径" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "type" - desc "云盘类型,数据云盘/根云盘" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "format" - desc "云盘格式" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "size" - desc "云盘大小" + desc "" type "Long" - since "0.6" + since "4.7.13" } field { name "actualSize" - desc "云盘真实大小" + desc "" type "Long" - since "0.6" + since "4.7.13" } field { name "deviceId" desc "" type "Integer" - since "0.6" + since "4.7.13" } field { name "state" - desc "云盘是否开启" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "status" - desc "云盘状态" + desc "" type "String" - since "0.6" + since "4.7.13" } field { name "createDate" desc "创建时间" type "Timestamp" - since "0.6" + since "4.7.13" } field { name "lastOpDate" desc "最后一次修改时间" type "Timestamp" - since "0.6" + since "4.7.13" } field { name "isShareable" - desc "是否共享云盘" + desc "" type "Boolean" - since "0.6" + since "4.7.13" } field { name "volumeQos" - desc "云盘Qos,格式如total=1048576" + desc "" + type "String" + since "4.7.13" + } + field { + name "lastDetachDate" + desc "" + type "Timestamp" + since "4.7.13" + } + field { + name "lastVmInstanceUuid" + desc "" type "String" - since "3.2.0" + since "4.7.13" } } diff --git a/header/src/main/java/org/zstack/header/volume/VolumeProtocol.java b/header/src/main/java/org/zstack/header/volume/VolumeProtocol.java new file mode 100644 index 00000000000..8cfebdf6080 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeProtocol.java @@ -0,0 +1,9 @@ +package org.zstack.header.volume; + +public enum VolumeProtocol { + NVMEoF, + iSCSI, + Vhost, + CBD, + NBD +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeProtocolCapability.java b/header/src/main/java/org/zstack/header/volume/VolumeProtocolCapability.java new file mode 100644 index 00000000000..c0ce747a9bb --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeProtocolCapability.java @@ -0,0 +1,68 @@ +package org.zstack.header.volume; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class VolumeProtocolCapability { + private static Map types = new ConcurrentHashMap<>(); + + private final String protocol; + private final String hypervisor; + + private boolean supportQosOnHypervisor; + + private boolean supportResizeOnHypervisor; + + private boolean supportReadonly; + + public VolumeProtocolCapability(String protocol, String hypervisor) { + this.protocol = protocol; + this.hypervisor = hypervisor; + } + + private static String makeKey(String protocol, String hypervisor) { + return String.format("%s-%s", protocol, hypervisor); + } + + public static VolumeProtocolCapability get(String protocol, String hypervisor) { + String key = makeKey(protocol, hypervisor); + VolumeProtocolCapability capability = types.get(key); + if (capability == null) { + return null; + } + return capability; + } + + public static VolumeProtocolCapability register(String protocol, String hypervisor) { + String key = makeKey(protocol, hypervisor); + if (types.containsKey(key)) { + throw new IllegalArgumentException(String.format("Duplicate VolumeProtocolCapability for protocol[%s] hypervisor[%s]", protocol, hypervisor)); + } + types.put(key, new VolumeProtocolCapability(protocol, hypervisor)); + return types.get(key); + } + + public boolean isSupportQosOnHypervisor() { + return supportQosOnHypervisor; + } + + public void setSupportQosOnHypervisor(boolean supportQosOnHypervisor) { + this.supportQosOnHypervisor = supportQosOnHypervisor; + } + + public boolean isSupportResizeOnHypervisor() { + return supportResizeOnHypervisor; + } + + public void setSupportResizeOnHypervisor(boolean supportResizeOnHypervisor) { + this.supportResizeOnHypervisor = supportResizeOnHypervisor; + } + + public boolean isSupportReadonly() { + return supportReadonly; + } + + public void setSupportReadonly(boolean supportReadonly) { + this.supportReadonly = supportReadonly; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeQos.java b/header/src/main/java/org/zstack/header/volume/VolumeQos.java new file mode 100644 index 00000000000..32cb255e4e8 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeQos.java @@ -0,0 +1,134 @@ +package org.zstack.header.volume; + +import org.zstack.utils.DebugUtils; + +import static org.zstack.header.volume.VolumeQosConstant.*; + +public class VolumeQos { + private Long readBandwidth = -1L; + private Long writeBandwidth = -1L; + private Long totalBandwidth = -1L; + private Long readIOPS = -1L; + private Long writeIOPS = -1L; + private Long totalIOPS = -1L; + + public VolumeQos(Long readBandwidth, Long writeBandwidth, Long totalBandwidth, Long readIOPS, Long writeIOPS, Long totalIOPS) { + this.readBandwidth = readBandwidth != null ? readBandwidth : -1L; + this.writeBandwidth = writeBandwidth != null ? writeBandwidth : -1L; + this.totalBandwidth = totalBandwidth != null ? totalBandwidth : -1L; + this.readIOPS = readIOPS != null ? readIOPS : -1L; + this.writeIOPS = writeIOPS != null ? writeIOPS : -1L; + this.totalIOPS = totalIOPS != null ? totalIOPS : -1L; + } + + public VolumeQos() { + } + + public static VolumeQos valueOf(String volumeQos) { + VolumeQos qos = new VolumeQos(); + if (volumeQos == null) { + return qos; + } + String[] vqoss = volumeQos.split(","); + for (String vqos: vqoss) { + String[] v = vqos.trim().split("="); + DebugUtils.Assert(v.length == 2, + String.format("qos must be formatted as read=xxxx,write=xxx, but got %s", volumeQos) + ); + + if (v[0] == null || v[1] == null) { + continue; + } + switch (v[0]) { + case BANDWIDTH_TOTAL: + qos.setTotalBandwidth(Long.parseLong(v[1])); + break; + case BANDWIDTH_READ: + qos.setReadBandwidth(Long.parseLong(v[1])); + break; + case BANDWIDTH_WRITE: + qos.setWriteBandwidth(Long.parseLong(v[1])); + break; + case IOPS_TOTAL: + qos.setTotalIOPS(Long.parseLong(v[1])); + break; + case IOPS_READ: + qos.setReadIOPS(Long.parseLong(v[1])); + break; + case IOPS_WRITE: + qos.setWriteIOPS(Long.parseLong(v[1])); + break; + } + } + + return qos; + } + + public Long getReadBandwidth() { + return readBandwidth; + } + + public void setReadBandwidth(Long readBandwidth) { + this.readBandwidth = readBandwidth; + } + + public Long getWriteBandwidth() { + return writeBandwidth; + } + + public void setWriteBandwidth(Long writeBandwidth) { + this.writeBandwidth = writeBandwidth; + } + + public Long getTotalBandwidth() { + return totalBandwidth; + } + + public void setTotalBandwidth(Long totalBandwidth) { + this.totalBandwidth = totalBandwidth; + } + + public Long getReadIOPS() { + return readIOPS; + } + + public void setReadIOPS(Long readIOPS) { + this.readIOPS = readIOPS; + } + + public Long getWriteIOPS() { + return writeIOPS; + } + + public void setWriteIOPS(Long writeIOPS) { + this.writeIOPS = writeIOPS; + } + + public Long getTotalIOPS() { + return totalIOPS; + } + + public void setTotalIOPS(Long totalIOPS) { + this.totalIOPS = totalIOPS; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof VolumeQos) { + VolumeQos other = (VolumeQos) obj; + return (other.readBandwidth.longValue() == readBandwidth.longValue()) + && (other.writeBandwidth.longValue() == writeBandwidth.longValue()) + && (other.totalBandwidth.longValue() == totalBandwidth.longValue()) + && (other.totalIOPS.longValue() == totalIOPS.longValue()) + && (other.readIOPS.longValue() == readIOPS.longValue()) + && (other.writeIOPS.longValue() == readIOPS.longValue()); + } else { + return super.equals(obj); + } + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeQosConstant.java b/header/src/main/java/org/zstack/header/volume/VolumeQosConstant.java new file mode 100644 index 00000000000..0443257cd3f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeQosConstant.java @@ -0,0 +1,10 @@ +package org.zstack.header.volume; + +public interface VolumeQosConstant { + String BANDWIDTH_READ = "read"; + String BANDWIDTH_WRITE = "write"; + String BANDWIDTH_TOTAL = "total"; + String IOPS_READ = "readIOPS"; + String IOPS_WRITE = "writeIOPS"; + String IOPS_TOTAL = "totalIOPS"; +} diff --git a/header/src/main/java/org/zstack/header/volume/VolumeStats.java b/header/src/main/java/org/zstack/header/volume/VolumeStats.java new file mode 100644 index 00000000000..2931945e7ed --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/VolumeStats.java @@ -0,0 +1,80 @@ +package org.zstack.header.volume; + +public class VolumeStats { + protected String installPath; + protected String format; + protected Long actualSize; + protected Long size; + /** + * The parent uri of the volume, vendor://pool/path@snapshot or snapshot://uuid + */ + protected String parentUri; + + // TODO(shenjin): remove it + @Deprecated + protected String runStatus; + + public VolumeStats(String installPath, Long actualSize) { + this.installPath = installPath; + this.actualSize = actualSize; + } + + + public VolumeStats(String installPath, Long actualSize, Long size) { + this.installPath = installPath; + this.actualSize = actualSize; + this.size = size; + } + + public VolumeStats() { + } + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public Long getActualSize() { + return actualSize; + } + + public void setActualSize(Long actualSize) { + this.actualSize = actualSize; + } + + public Long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public void setFormat(String format) { + this.format = format; + } + + public String getFormat() { + return format; + } + + public void setParentUri(String parentUri) { + this.parentUri = parentUri; + } + + public String getParentUri() { + return parentUri; + } + + @Deprecated + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/block/AccessPathInfo.java b/header/src/main/java/org/zstack/header/volume/block/AccessPathInfo.java new file mode 100644 index 00000000000..8e8f945b8ea --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/AccessPathInfo.java @@ -0,0 +1,60 @@ +package org.zstack.header.volume.block; + +import java.util.List; + +/** + * @author shenjin + * @date 2023/6/21 13:27 + */ +public class AccessPathInfo { + private String name; + + private Integer accessPathId; + + private String accessPathIqn; + + private Integer targetCount; + + private List gatewayIps; + + public List getGatewayIps() { + return gatewayIps; + } + + public void setGatewayIps(List gatewayIps) { + this.gatewayIps = gatewayIps; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAccessPathId() { + return accessPathId; + } + + public void setAccessPathId(Integer accessPathId) { + this.accessPathId = accessPathId; + } + + public String getAccessPathIqn() { + return accessPathIqn; + } + + public void setAccessPathIqn(String accessPathIqn) { + this.accessPathIqn = accessPathIqn; + } + + public Integer getTargetCount() { + return targetCount; + } + + public void setTargetCount(Integer targetCount) { + this.targetCount = targetCount; + } +} + diff --git a/header/src/main/java/org/zstack/header/volume/block/BlockVolumeInventory.java b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeInventory.java new file mode 100644 index 00000000000..b4bed57f82e --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeInventory.java @@ -0,0 +1,57 @@ +package org.zstack.header.volume.block; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; +import org.zstack.header.search.Parent; +import org.zstack.header.volume.VolumeConstant; +import org.zstack.header.volume.VolumeInventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = BlockVolumeVO.class, collectionValueOfMethod="valueOf1", + parent = {@Parent(inventoryClass = VolumeInventory.class, type = VolumeConstant.BLOCK_VOLUME_TYPE)}) +@PythonClassInventory +public class BlockVolumeInventory extends VolumeInventory { + private String iscsiPath; + + private String vendor; + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public String getIscsiPath() { + return iscsiPath; + } + + public void setIscsiPath(String iscsiPath) { + this.iscsiPath = iscsiPath; + } + + public static BlockVolumeInventory valueOf(BlockVolumeVO vo) { + return new BlockVolumeInventory(vo); + } + + public BlockVolumeInventory() { + } + + public BlockVolumeInventory(BlockVolumeVO other) { + super(VolumeInventory.valueOf(other)); + this.vendor = other.getVendor(); + this.iscsiPath = other.getIscsiPath(); + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (BlockVolumeVO vo : vos) { + invs.add(new BlockVolumeInventory(vo)); + } + return invs; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/block/BlockVolumeInventoryDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..7dacb678bdd --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeInventoryDoc_zh_cn.groovy @@ -0,0 +1,150 @@ +package org.zstack.header.volume.block + +import java.lang.Integer +import java.lang.Long +import java.sql.Timestamp +import java.lang.Boolean + +doc { + + title "块存储卷" + + field { + name "iscsiPath" + desc "" + type "String" + since "4.7.11" + } + field { + name "vendor" + desc "" + type "String" + since "4.7.11" + } + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.7.11" + } + field { + name "name" + desc "资源名称" + type "String" + since "4.7.11" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "4.7.11" + } + field { + name "primaryStorageUuid" + desc "主存储UUID" + type "String" + since "4.7.11" + } + field { + name "vmInstanceUuid" + desc "云主机UUID" + type "String" + since "4.7.11" + } + field { + name "diskOfferingUuid" + desc "云盘规格UUID" + type "String" + since "4.7.11" + } + field { + name "rootImageUuid" + desc "" + type "String" + since "4.7.11" + } + field { + name "installPath" + desc "" + type "String" + since "4.7.11" + } + field { + name "type" + desc "" + type "String" + since "4.7.11" + } + field { + name "format" + desc "" + type "String" + since "4.7.11" + } + field { + name "size" + desc "" + type "Long" + since "4.7.11" + } + field { + name "actualSize" + desc "" + type "Long" + since "4.7.11" + } + field { + name "deviceId" + desc "" + type "Integer" + since "4.7.11" + } + field { + name "state" + desc "" + type "String" + since "4.7.11" + } + field { + name "status" + desc "" + type "String" + since "4.7.11" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.7.11" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.7.11" + } + field { + name "isShareable" + desc "" + type "Boolean" + since "4.7.11" + } + field { + name "volumeQos" + desc "" + type "String" + since "4.7.11" + } + field { + name "lastDetachDate" + desc "" + type "Timestamp" + since "4.7.11" + } + field { + name "lastVmInstanceUuid" + desc "" + type "String" + since "4.7.11" + } +} diff --git a/header/src/main/java/org/zstack/header/volume/block/BlockVolumeVO.java b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeVO.java new file mode 100644 index 00000000000..a308a00843f --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeVO.java @@ -0,0 +1,65 @@ +package org.zstack.header.volume.block; + +import org.zstack.header.volume.VolumeStatus; +import org.zstack.header.volume.VolumeType; +import org.zstack.header.volume.VolumeVO; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +/** + * @author shenjin + * @date 2023/6/13 16:03 + */ +@Entity +@Table +@PrimaryKeyJoinColumn(name="uuid", referencedColumnName="uuid") +public class BlockVolumeVO extends VolumeVO { + @Column + private String iscsiPath; + @Column + private String vendor; + + public BlockVolumeVO() { + } + + public BlockVolumeVO(VolumeVO vo) { + this.setUuid(vo.getUuid()); + this.setDescription(vo.getDescription()); + this.setName(vo.getName()); + this.setDiskOfferingUuid(vo.getDiskOfferingUuid()); + this.setSize(vo.getSize()); + this.setActualSize(vo.getActualSize()); + this.setType(vo.getType()); + this.setState(vo.getState()); + this.setPrimaryStorageUuid(vo.getPrimaryStorageUuid()); + this.setStatus(vo.getStatus()); + this.setAccountUuid(vo.getAccountUuid()); + this.setDeviceId(vo.getDeviceId()); + this.setFormat(vo.getFormat()); + this.setInstallPath(vo.getInstallPath()); + this.setRootImageUuid(vo.getRootImageUuid()); + this.setVmInstanceUuid(vo.getVmInstanceUuid()); + this.setLastVmInstanceUuid(vo.getLastVmInstanceUuid()); + this.setShareable(vo.isShareable()); + this.setProtocol(vo.getProtocol()); + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public String getIscsiPath() { + return iscsiPath; + } + + public void setIscsiPath(String iscsiPath) { + this.iscsiPath = iscsiPath; + } +} diff --git a/header/src/main/java/org/zstack/header/volume/block/BlockVolumeVO_.java b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeVO_.java new file mode 100644 index 00000000000..7045974299e --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/BlockVolumeVO_.java @@ -0,0 +1,16 @@ +package org.zstack.header.volume.block; + +import org.zstack.header.volume.VolumeVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +/** + * @author shenjin + * @date 2023/6/13 16:54 + */ +@StaticMetamodel(BlockVolumeVO.class) +public class BlockVolumeVO_ extends VolumeVO_ { + public static volatile SingularAttribute iscsiPath; + public static volatile SingularAttribute vendor; +} diff --git a/header/src/main/java/org/zstack/header/volume/block/GetAccessPathMsg.java b/header/src/main/java/org/zstack/header/volume/block/GetAccessPathMsg.java new file mode 100644 index 00000000000..89df392c9a9 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/GetAccessPathMsg.java @@ -0,0 +1,30 @@ +package org.zstack.header.volume.block; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.storage.primary.PrimaryStorageMessage; + +/** + * @author shenjin + * @date 2023/6/21 13:13 + */ +public class GetAccessPathMsg extends NeedReplyMessage implements PrimaryStorageMessage { + String primaryStorageUuid; + String volumeUuid; + + public String getVolumeUuid() { + return volumeUuid; + } + + public void setVolumeUuid(String volumeUuid) { + this.volumeUuid = volumeUuid; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + +} diff --git a/header/src/main/java/org/zstack/header/volume/block/GetAccessPathReply.java b/header/src/main/java/org/zstack/header/volume/block/GetAccessPathReply.java new file mode 100644 index 00000000000..04c2955e8c5 --- /dev/null +++ b/header/src/main/java/org/zstack/header/volume/block/GetAccessPathReply.java @@ -0,0 +1,22 @@ +package org.zstack.header.volume.block; + +import org.zstack.header.message.MessageReply; +import org.zstack.header.volume.block.AccessPathInfo; + +import java.util.List; + +/** + * @author shenjin + * @date 2023/6/18 16:11 + */ +public class GetAccessPathReply extends MessageReply { + private List infos; + + public List getInfos() { + return infos; + } + + public void setInfos(List infos) { + this.infos = infos; + } +} diff --git a/header/src/main/java/org/zstack/header/zone/APIChangeZoneStateMsgDoc_zh_cn.groovy b/header/src/main/java/org/zstack/header/zone/APIChangeZoneStateMsgDoc_zh_cn.groovy index 3eec3b43588..afad3ad8225 100644 --- a/header/src/main/java/org/zstack/header/zone/APIChangeZoneStateMsgDoc_zh_cn.groovy +++ b/header/src/main/java/org/zstack/header/zone/APIChangeZoneStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/header/src/main/java/org/zstack/header/zone/APICreateZoneMsg.java b/header/src/main/java/org/zstack/header/zone/APICreateZoneMsg.java index ecd7495653c..aa0edd62b81 100755 --- a/header/src/main/java/org/zstack/header/zone/APICreateZoneMsg.java +++ b/header/src/main/java/org/zstack/header/zone/APICreateZoneMsg.java @@ -47,7 +47,7 @@ public class APICreateZoneMsg extends APICreateMessage implements APIAuditor { * @desc max length of 255 characters * @required */ - @APIParam(maxLength = 255) + @APIParam(maxLength = 255, validRegexValues = "^(?! )[\\u4e00-\\u9fa5a-zA-Z0-9\\-_.():+\" ]*(? name; public static volatile SingularAttribute type; public static volatile SingularAttribute state; + public static volatile SingularAttribute isDefault; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/header/src/main/java/org/zstack/header/zone/ZoneInventory.java b/header/src/main/java/org/zstack/header/zone/ZoneInventory.java index d80b1cfa8b9..e33611e1e2f 100755 --- a/header/src/main/java/org/zstack/header/zone/ZoneInventory.java +++ b/header/src/main/java/org/zstack/header/zone/ZoneInventory.java @@ -84,6 +84,11 @@ public class ZoneInventory implements Serializable { */ private String type; + /** + * @desc true if this zone is the default zone + */ + private boolean isDefault; + /** * @desc the time this resource gets created */ @@ -101,6 +106,7 @@ public static ZoneInventory valueOf(ZoneVO vo) { inv.setUuid(vo.getUuid()); inv.setState(vo.getState().toString()); inv.setType(vo.getType()); + inv.setDefault(vo.isDefault()); inv.setCreateDate(vo.getCreateDate()); inv.setLastOpDate(vo.getLastOpDate()); return inv; @@ -169,4 +175,12 @@ public Timestamp getLastOpDate() { public void setLastOpDate(Timestamp lastOpDate) { this.lastOpDate = lastOpDate; } + + public boolean isDefault() { + return isDefault; + } + + public void setDefault(boolean aDefault) { + isDefault = aDefault; + } } diff --git a/header/src/main/java/org/zstack/header/zql/ASTNode.groovy b/header/src/main/java/org/zstack/header/zql/ASTNode.groovy index b518f655b51..3148ec77ab2 100755 --- a/header/src/main/java/org/zstack/header/zql/ASTNode.groovy +++ b/header/src/main/java/org/zstack/header/zql/ASTNode.groovy @@ -25,20 +25,19 @@ class ASTNode { interface ReturnWithExpr { } - interface Function { - } - - static class Distinct extends ASTNode implements Function { + static class Function extends ASTNode { + String functionName } static class QueryTarget extends ASTNode { - String entity - List fields + String entity + List fields } static class QueryTargetWithFunction extends QueryTarget { Function function QueryTargetWithFunction subTarget + List joinClauseList static QueryTargetWithFunction valueOf(QueryTarget q) { return new QueryTargetWithFunction(entity: q.entity, fields: q.fields) @@ -64,7 +63,7 @@ class ASTNode { } static class ComplexValue extends ASTNode implements Value { - SubQuery subQuery + SubQuery subQuery } static class PlainValue extends ASTNode implements Value { @@ -74,28 +73,36 @@ class ASTNode { } static class ListValue extends ASTNode implements Value { - List values + List values } static class Expr extends ASTNode implements Condition { - String operator - List left - Value right + String operator + List left + Value right } static class LogicalOperator extends ASTNode implements Condition { - String operator - Condition left - Condition right + String operator + Condition left + Condition right + } + + static class JoinExpr extends ASTNode implements Condition { + QueryTarget left + String operator + QueryTarget right } static class ExprAtom extends ASTNode { String text List fields = new ArrayList<>() + QueryTarget queryTarget + Function function } static class OrderByExpr extends ASTNode { - ExprAtom target + ExprAtom expr String direction } @@ -104,18 +111,18 @@ class ASTNode { } static class Limit extends ASTNode { - int limit + int limit } static class Offset extends ASTNode { - int offset + int offset } static class RestrictExpr extends ASTNode { - String entity - String field - String operator - Value value + String entity + String field + String operator + Value value } static class RestrictBy extends ASTNode { @@ -132,7 +139,7 @@ class ASTNode { } static class ReturnWith extends ASTNode { - List exprs + List exprs } static class Sum extends Query { @@ -156,7 +163,7 @@ class ASTNode { GroupByExpr groupBy void addRestrictExpr(RestrictExpr expr) { - if (restrictBy == null) { + if (restrictBy == null) { restrictBy = new RestrictBy() } @@ -169,22 +176,22 @@ class ASTNode { } static class SubQueryTarget extends ASTNode { - String entity - List fields + String entity + List fields } static class SubQuery extends ASTNode { - SubQueryTarget target - List conditions + SubQueryTarget target + List conditions } static class FilterByExpr extends ASTNode { - String filterName - String content + String filterName + String content } static class FilterBy extends ASTNode { - List exprs + List exprs } static class Search extends ASTNode { @@ -202,4 +209,12 @@ class ASTNode { static class Index extends ASTNode { List indexs } + + static class JoinClause extends ASTNode { + String joinType + String join + QueryTarget queryTarget + String on + List conditions + } } diff --git a/identity/pom.xml b/identity/pom.xml index 79735f2fa9f..2f06a0008cb 100755 --- a/identity/pom.xml +++ b/identity/pom.xml @@ -4,7 +4,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. identity diff --git a/identity/src/main/java/org/zstack/identity/AccountBase.java b/identity/src/main/java/org/zstack/identity/AccountBase.java index 659c9ee2ca5..ca4d7c59ed0 100755 --- a/identity/src/main/java/org/zstack/identity/AccountBase.java +++ b/identity/src/main/java/org/zstack/identity/AccountBase.java @@ -12,18 +12,27 @@ import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.db.*; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQLBatch; +import org.zstack.core.db.SQLBatchWithReturn; +import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.core.Completion; -import org.zstack.header.core.workflow.*; +import org.zstack.header.core.workflow.FlowChain; +import org.zstack.header.core.workflow.FlowDoneHandler; +import org.zstack.header.core.workflow.FlowErrorHandler; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.identity.*; import org.zstack.header.identity.IdentityCanonicalEvents.AccountDeletedData; import org.zstack.header.identity.IdentityCanonicalEvents.UserDeletedData; +import org.zstack.header.identity.quota.QuotaDefinition; import org.zstack.header.identity.role.RolePolicyStatementVO; import org.zstack.header.identity.role.RolePolicyStatementVO_; import org.zstack.header.identity.role.RoleVO; @@ -31,18 +40,20 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.utils.CollectionUtils; -import org.zstack.utils.DebugUtils; import org.zstack.utils.ExceptionDSL; import org.zstack.utils.Utils; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; -import static org.zstack.core.Platform.*; import javax.persistence.Query; import javax.persistence.Tuple; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import static org.zstack.core.Platform.argerr; import static org.zstack.utils.CollectionDSL.list; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) @@ -112,6 +123,11 @@ private void handle(APIUpdateAccountMsg msg) { } } + // execute tf extension point + final AccountInventory inventory = AccountInventory.valueOf(account); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(BeforeUpdateAccountExtensionPoint.class), + arg -> arg.beforeUpdateAccount(inventory)); + APIUpdateAccountEvent evt = new APIUpdateAccountEvent(msg.getId()); evt.setInventory(AccountInventory.valueOf(account)); bus.publish(evt); @@ -205,6 +221,11 @@ private void handle(final APIDeleteAccountMsg msg) { deleteAccount(new Completion(msg) { @Override public void success() { + // execute tf extension point + final AccountInventory inventory = new AccountInventory(); + inventory.setUuid(msg.getUuid() ); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(BeforeDeleteAccountExtensionPoint.class), + arg -> arg.beforeDeleteAccount(inventory)); bus.publish(evt); } @@ -380,13 +401,18 @@ private void handle(APIAttachPoliciesToUserMsg msg) { private void handle(APIGetAccountQuotaUsageMsg msg) { APIGetAccountQuotaUsageReply reply = new APIGetAccountQuotaUsageReply(); - List quotas = acntMgr.getQuotas(); - List usages = new ArrayList(); + List usages = new ArrayList<>(); + for (QuotaDefinition q : acntMgr.getQuotasDefinitions().values()) { + Long used = q.getQuotaUsage(msg.getAccountUuid()); + + if (used == null) { + continue; + } - for (Quota q : quotas) { - List us = q.getOperator().getQuotaUsageByAccount(msg.getAccountUuid()); - DebugUtils.Assert(us != null, String.format("%s returns null quotas", q.getOperator().getClass())); - usages.addAll(us); + Quota.QuotaUsage usage = new Quota.QuotaUsage(); + usage.setUsed(used); + usage.setName(q.getName()); + usages.add(usage); } Map umap = new HashMap(); @@ -417,6 +443,10 @@ private void handle(APIGetAccountQuotaUsageMsg msg) { } private void handle(APIUpdateQuotaMsg msg) { + for (QuotaExtensionPoint ext : pluginRgty.getExtensionList(QuotaExtensionPoint.class)) { + ext.beforeUpdateQuota(msg.getQuotaVO().getName(), msg.getValue(), msg.getIdentityUuid()); + } + QuotaVO quota = msg.getQuotaVO(); quota.setValue(msg.getValue()); quota = dbf.updateAndRefresh(quota); diff --git a/identity/src/main/java/org/zstack/identity/AccountLoginBackend.java b/identity/src/main/java/org/zstack/identity/AccountLoginBackend.java new file mode 100644 index 00000000000..0cbaf8b45aa --- /dev/null +++ b/identity/src/main/java/org/zstack/identity/AccountLoginBackend.java @@ -0,0 +1,149 @@ +package org.zstack.identity; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.Q; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.identity.*; +import org.zstack.header.identity.login.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; + +import static org.zstack.core.Platform.err; + +/** + * Created by kayo on 2018/7/10. + */ +public class AccountLoginBackend implements LoginBackend { + private static final CLogger logger = Utils.getLogger(AccountLoginBackend.class); + + public static final LoginType loginType = new LoginType(AccountConstant.LOGIN_TYPE); + + @Autowired + private PluginRegistry pluginRgty; + + @Override + public LoginType getLoginType() { + return loginType; + } + + @Override + public void login(LoginContext loginContext, ReturnValueCompletion completion) { + AccountVO vo = Q.New(AccountVO.class) + .eq(AccountVO_.name, loginContext.getUsername()) + .eq(AccountVO_.password, loginContext.getPassword()) + .find(); + + String accountType = loginContext.getProperties().get(AccountConstant.ACCOUNT_TYPE); + LoginSessionInfo info = new LoginSessionInfo(); + boolean accountLogin = accountType == null || AccountConstant.LOGIN_TYPE.equals(accountType); + if (vo != null && accountLogin) { + info.setUserUuid(vo.getUuid()); + info.setAccountUuid(vo.getUuid()); + info.setUserType(AccountVO.class.getSimpleName()); + } else { + logger.debug(String.format("login account type is %s, use AccountLoginExtensionPoint", accountLogin)); + for (AccountLoginExtensionPoint ext : pluginRgty.getExtensionList(AccountLoginExtensionPoint.class)) { + AccountLoginStruct struct = ext.getLoginEntry(loginContext.getUsername(), loginContext.getPassword(), null); + + if (struct != null) { + info.setAccountUuid(struct.getAccountUuid()); + info.setUserType(struct.getResourceType()); + info.setUserUuid(struct.getUserUuid()); + break; + } + } + } + + if (info.getUserUuid() == null) { + completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR, "wrong account name or password")); + return; + } + + completion.success(info); + } + + @Override + public Set possibleUserUuidSetForGettingProcedures(LoginContext loginContext) { + List userUuidList = Q.New(AccountVO.class) + .select(AccountVO_.uuid) + .eq(AccountVO_.name, loginContext.getUsername()) + .listValues(); + return new HashSet<>(userUuidList); + } + + protected String getResourceIdentity(String name) { + String resourceIdentity = Q.New(AccountVO.class).select(AccountVO_.uuid).eq(AccountVO_.name, name).findValue(); + + if (resourceIdentity == null) { + for(AccountLoginExtensionPoint ext : pluginRgty.getExtensionList(AccountLoginExtensionPoint.class)) { + AccountLoginStruct struct = ext.getLoginEntryByName(name, null); + if (struct == null) { + continue; + } + + resourceIdentity = struct.getUserUuid(); + if(resourceIdentity != null) { + break; + } + } + } + + return resourceIdentity; + } + + @Override + public boolean authenticate(String name, String password) { + return Q.New(AccountVO.class).eq(AccountVO_.name, name) + .eq(AccountVO_.password, password).isExists(); + } + + @Override + public String getUserIdByName(String username) { + return getResourceIdentity(username); + } + + private AccountLoginStruct getLoginEntryByName(String username, String accountType) { + AccountVO vo = Q.New(AccountVO.class).eq(AccountVO_.name, username).find(); + + AccountLoginStruct struct = null; + boolean accountLogin = accountType == null || AccountConstant.LOGIN_TYPE.equals(accountType); + if (vo != null && accountLogin) { + struct = new AccountLoginStruct(); + struct.setUserUuid(vo.getUuid()); + struct.setAccountUuid(vo.getUuid()); + struct.setResourceType(AccountVO.class.getSimpleName()); + struct.setLastOpTime(vo.getLastOpDate()); + } else { + for (AccountLoginExtensionPoint ext : pluginRgty.getExtensionList(AccountLoginExtensionPoint.class)) { + struct = ext.getLoginEntryByName(username, accountType); + if (struct != null) { + break; + } + } + } + + return struct; + } + + @Override + public void collectUserInfoIntoContext(LoginContext loginContext) { + AccountLoginStruct struct = getLoginEntryByName(loginContext.getUsername(), + loginContext.getProperties().get(AccountConstant.ACCOUNT_TYPE)); + + if (struct == null) { + return; + } + + loginContext.setUserUuid(struct.getUserUuid()); + loginContext.setLastUpdatedTime(struct.getLastOpTime()); + loginContext.setUserType(struct.getResourceType()); + } + + @Override + public List getRequiredAdditionalAuthFeature() { + return Arrays.asList(LoginAuthConstant.basicLoginControl, LoginAuthConstant.twoFactor, LoginAuthConstant.ssoServerLoginControl); + } +} diff --git a/identity/src/main/java/org/zstack/identity/AccountLoginExtensionPoint.java b/identity/src/main/java/org/zstack/identity/AccountLoginExtensionPoint.java index cdc8bd4faad..395c8df3da0 100644 --- a/identity/src/main/java/org/zstack/identity/AccountLoginExtensionPoint.java +++ b/identity/src/main/java/org/zstack/identity/AccountLoginExtensionPoint.java @@ -2,4 +2,6 @@ public interface AccountLoginExtensionPoint { AccountLoginStruct getLoginEntry(String name, String password, String type); + + AccountLoginStruct getLoginEntryByName(String name, String type); } diff --git a/identity/src/main/java/org/zstack/identity/AccountLoginProcessor.java b/identity/src/main/java/org/zstack/identity/AccountLoginProcessor.java deleted file mode 100644 index 6b38c7e32d6..00000000000 --- a/identity/src/main/java/org/zstack/identity/AccountLoginProcessor.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.zstack.identity; - -import org.springframework.beans.factory.annotation.Autowire; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.db.Q; -import org.zstack.header.identity.*; -import org.zstack.header.message.APIMessage; - -import java.sql.Timestamp; - -/** - * Created by kayo on 2018/7/10. - */ -@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class AccountLoginProcessor implements LoginProcessor { - public static final LoginType loginType = new LoginType(AccountConstant.LOGIN_TYPE); - - @Autowired - private PluginRegistry pluginRgty; - - @Override - public LoginType getLoginType() { - return loginType; - } - - @Override - public Class getMessageClass() { - return APILogInByAccountMsg.class; - } - - @Override - public String resourceChecker(String resourceName) { - return getResourceIdentity(resourceName); - } - - protected String getResourceIdentity(String name) { - String resourceIdentity = Q.New(AccountVO.class).select(AccountVO_.uuid).eq(AccountVO_.name, name).findValue(); - - if (resourceIdentity == null) { - for(AccountLoginProcessorExtensionPoint ext : pluginRgty.getExtensionList(AccountLoginProcessorExtensionPoint.class)) { - resourceIdentity = ext.getResourceIdentity(name); - - if(resourceIdentity != null) { - break; - } - } - } - - return resourceIdentity; - } - - protected Timestamp getLastOperatedTime(String resourceIdentity) { - Timestamp lastUpdatedTime = Q.New(AccountVO.class).select(AccountVO_.lastOpDate).eq(AccountVO_.uuid, resourceIdentity).findValue(); - - if (lastUpdatedTime == null) { - for(AccountLoginProcessorExtensionPoint ext : pluginRgty.getExtensionList(AccountLoginProcessorExtensionPoint.class)) { - lastUpdatedTime = ext.getLastOperatedTime(resourceIdentity); - - if(lastUpdatedTime != null) { - break; - } - } - } - - return lastUpdatedTime; - } - - @Override - public Result getMessageParams(APIMessage message) { - APILogInByAccountMsg msg = (APILogInByAccountMsg) message; - - Result r = new Result(); - r.setCaptchaUuid(msg.getCaptchaUuid()); - r.setTargetResourceIdentity(getResourceIdentity(msg.getAccountName())); - r.setVerifyCode(msg.getVerifyCode()); - r.setLastUpdatedTime(getLastOperatedTime(r.getTargetResourceIdentity())); - - return r; - } - - @Override - public boolean authenticate(String name, String password) { - AccountVO acvo = Q.New(AccountVO.class).eq(AccountVO_.name, name) - .eq(AccountVO_.password, password).find(); - - if (acvo != null) { - return true; - } - return false; - } -} diff --git a/identity/src/main/java/org/zstack/identity/AccountLoginProcessorExtensionPoint.java b/identity/src/main/java/org/zstack/identity/AccountLoginProcessorExtensionPoint.java deleted file mode 100644 index b517fcc6084..00000000000 --- a/identity/src/main/java/org/zstack/identity/AccountLoginProcessorExtensionPoint.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.zstack.identity; - -import java.sql.Timestamp; - -public interface AccountLoginProcessorExtensionPoint { - String getResourceIdentity(String name); - - Timestamp getLastOperatedTime(String resourceIdentity); -} diff --git a/identity/src/main/java/org/zstack/identity/AccountLoginStruct.java b/identity/src/main/java/org/zstack/identity/AccountLoginStruct.java index 558d6afd97c..3e48256ef1b 100644 --- a/identity/src/main/java/org/zstack/identity/AccountLoginStruct.java +++ b/identity/src/main/java/org/zstack/identity/AccountLoginStruct.java @@ -1,9 +1,12 @@ package org.zstack.identity; +import java.sql.Timestamp; + public class AccountLoginStruct { private String accountUuid; private String userUuid; private String resourceType; + private Timestamp lastOpTime; public String getAccountUuid() { return accountUuid; @@ -28,4 +31,12 @@ public String getResourceType() { public void setResourceType(String resourceType) { this.resourceType = resourceType; } + + public Timestamp getLastOpTime() { + return lastOpTime; + } + + public void setLastOpTime(Timestamp lastOpTime) { + this.lastOpTime = lastOpTime; + } } diff --git a/identity/src/main/java/org/zstack/identity/AccountManager.java b/identity/src/main/java/org/zstack/identity/AccountManager.java index 7c3af4ebbf2..feb61018d8e 100755 --- a/identity/src/main/java/org/zstack/identity/AccountManager.java +++ b/identity/src/main/java/org/zstack/identity/AccountManager.java @@ -1,9 +1,10 @@ package org.zstack.identity; -import org.zstack.header.identity.AccountResourceRefInventory; -import org.zstack.header.identity.Quota; -import org.zstack.header.identity.SessionInventory; +import org.zstack.header.identity.*; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; import java.util.List; import java.util.Map; @@ -17,7 +18,9 @@ public interface AccountManager { Map> getMessageQuotaMap(); - List getQuotas(); + Map>> getQuotaMessageHandlerMap(); + + Map getQuotasDefinitions(); AccountResourceRefInventory changeResourceOwner(String resourceUuid, String newOwnerUuid); @@ -28,4 +31,6 @@ public interface AccountManager { void adminAdoptAllOrphanedResource(List resourceUuid, String originAccountUuid); Class getBaseResourceType(Class clz); + + AccountInventory createAccount(CreateAccountMsg msg); } diff --git a/identity/src/main/java/org/zstack/identity/AccountManagerImpl.java b/identity/src/main/java/org/zstack/identity/AccountManagerImpl.java index c437a806555..c00a6e11dd2 100755 --- a/identity/src/main/java/org/zstack/identity/AccountManagerImpl.java +++ b/identity/src/main/java/org/zstack/identity/AccountManagerImpl.java @@ -4,6 +4,7 @@ import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; @@ -18,6 +19,7 @@ import org.zstack.header.APIIsOpensourceVersionMsg; import org.zstack.header.APIIsOpensourceVersionReply; import org.zstack.header.AbstractService; +import org.zstack.header.apimediator.ApiMediatorConstant; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; import org.zstack.header.core.NoErrorCompletion; @@ -28,10 +30,13 @@ import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.*; import org.zstack.header.identity.Quota.QuotaPair; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.identity.quota.QuotaMessageHandler; +import org.zstack.header.identity.login.LogInMsg; +import org.zstack.header.identity.login.LogInReply; +import org.zstack.header.identity.login.LoginManager; import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; -import org.zstack.header.message.APIMessage; -import org.zstack.header.message.APIParam; -import org.zstack.header.message.Message; +import org.zstack.header.message.*; import org.zstack.header.rest.RestAuthenticationBackend; import org.zstack.header.rest.RestAuthenticationParams; import org.zstack.header.rest.RestAuthenticationType; @@ -48,6 +53,7 @@ import java.lang.reflect.Field; import java.sql.Timestamp; import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -77,10 +83,15 @@ public class AccountManagerImpl extends AbstractService implements AccountManage private final List resourceTypes = new ArrayList<>(); private final Map> messageQuotaMap = new HashMap<>(); private final Map nameQuotaMap = new HashMap<>(); + + private final Map>> messageHandlerMap = new HashMap<>(); + private final HashSet accountApiControl = new HashSet<>(); private final HashSet accountApiControlInternal = new HashSet<>(); private final List definedQuotas = new ArrayList<>(); + private static final Map quotaDefinitionMap = new HashMap<>(); + @Override public void prepareDbInitialValue() { new SQLBatch() { @@ -132,7 +143,12 @@ public void handleMessage(Message msg) { } private void handleLocalMessage(Message msg) { - bus.dealWithUnknownMessage(msg); + if (msg instanceof CreateAccountMsg) { + handle((CreateAccountMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } @Override @@ -140,9 +156,13 @@ public Map> getMessageQuotaMap() { return messageQuotaMap; } + public Map>> getQuotaMessageHandlerMap() { + return messageHandlerMap; + } + @Override - public List getQuotas() { - return definedQuotas; + public Map getQuotasDefinitions() { + return quotaDefinitionMap; } @Override @@ -246,7 +266,7 @@ private void handle(APIGetResourceNamesMsg msg) { List invs = new SQLBatchWithReturn>() { @Override protected List scripts() { - Query q = dbf.getEntityManager().createNativeQuery("select uuid, resourceName, resourceType from ResourceVO where uuid in (:uuids)"); + Query q = dbf.getEntityManager().createNativeQuery("select uuid, resourceName, resourceType, concreteResourceType from ResourceVO where uuid in (:uuids)"); q.setParameter("uuids", msg.getUuids()); List objs = q.getResultList(); @@ -315,11 +335,7 @@ public void run(FlowTrigger trigger, Map data) { return; } // check quota - Map pairs = new QuotaUtil().makeQuotaPairs(resourceTargetOwnerAccountUuid); - for (Quota quota : messageQuotaMap.get(APIChangeResourceOwnerMsg.class)) { - quota.getOperator().checkQuota(msg, pairs); - } - + new QuotaUtil().checkQuota(msg, resourceOriginalOwnerAccountUuid, msg.getAccountUuid()); trigger.next(); } }).then(new NoRollbackFlow() { @@ -414,10 +430,10 @@ private void handle(APICheckApiPermissionMsg msg) { try { new Auth().check(api); - ret.put(apiName, StatementEffect.Allow.toString()); + ret.put(apiName, PolicyStatementEffect.Allow.toString()); } catch (ApiMessageInterceptionException e) { logger.debug(e.getMessage()); - ret.put(apiName, StatementEffect.Deny.toString()); + ret.put(apiName, PolicyStatementEffect.Deny.toString()); } } catch (ClassNotFoundException e) { throw new OperationFailureException(argerr("%s is not an API", apiName)); @@ -458,6 +474,11 @@ private void handle(APILogOutMsg msg) { session = svo == null ? null : SessionInventory.valueOf(svo); } msg.setSession(session); + + for (LogoutExtensionPoint ext : pluginRgty.getExtensionList(LogoutExtensionPoint.class)) { + ext.beforeLogout(session); + } + logOutSession(msg.getSessionUuid()); bus.reply(msg, reply); } @@ -506,63 +527,51 @@ private void handle(APILogInByUserMsg msg) { private void handle(APILogInByAccountMsg msg) { APILogInReply reply = new APILogInReply(); - AccountLoginStruct struct = null; - - SimpleQuery q = dbf.createQuery(AccountVO.class); - q.add(AccountVO_.name, Op.EQ, msg.getAccountName()); - q.add(AccountVO_.password, Op.EQ, msg.getPassword()); - AccountVO vo = q.find(); - - // if accountName/password not exists or specific type is set - // use extension to get login structure - if (vo == null || (msg.getAccountType() != null && !msg.getAccountType().equals(AccountConstant.LOGIN_TYPE))) { - for (AccountLoginExtensionPoint ext : pluginRgty.getExtensionList(AccountLoginExtensionPoint.class)) { - struct = ext.getLoginEntry(msg.getAccountName(), msg.getPassword(), msg.getAccountType()); - - if (struct != null) { - break; + LogInMsg logInMsg = new LogInMsg(); + logInMsg.setVerifyCode(msg.getVerifyCode()); + logInMsg.setCaptchaUuid(msg.getCaptchaUuid()); + logInMsg.setPassword(msg.getPassword()); + logInMsg.setUsername(msg.getAccountName()); + logInMsg.setLoginType(msg.getLoginType()); + logInMsg.setSystemTags(msg.getSystemTags()); + logInMsg.setClientInfo(msg.getClientInfo()); + logInMsg.getProperties().put(AccountConstant.ACCOUNT_TYPE, msg.getAccountType()); + bus.makeTargetServiceIdByResourceUuid(logInMsg, LoginManager.SERVICE_ID, logInMsg.getUsername()); + bus.send(logInMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + reply.setError(r.getError()); + bus.reply(msg, reply); + return; } - } - } else { - struct = new AccountLoginStruct(); - struct.setAccountUuid(vo.getUuid()); - struct.setUserUuid(vo.getUuid()); - struct.setResourceType(AccountVO.class.getSimpleName()); - } - if (struct == null) { - reply.setError(err(IdentityErrors.AUTHENTICATION_ERROR, "wrong account name or password")); - bus.reply(msg, reply); - return; - } + LogInReply logInReply = r.castReply(); + IdentityCanonicalEvents.AccountLoginData data = new IdentityCanonicalEvents.AccountLoginData(); + data.setAccountUuid(logInReply.getSession().getAccountUuid()); + data.setUserUuid(logInReply.getSession().getUserUuid()); + evtf.fire(IdentityCanonicalEvents.ACCOUNT_LOGIN_PATH, data); - for (AdditionalLoginExtensionPoint exp : pluginRgty.getExtensionList(AdditionalLoginExtensionPoint.class)){ - ErrorCode errorCode = exp.authenticate(msg, struct.getUserUuid(), struct.getResourceType()); - if (errorCode != null) { - reply.setError(errorCode); + reply.setInventory(logInReply.getSession()); bus.reply(msg, reply); - return; } - } - - SessionInventory session = getSession(struct.getAccountUuid(), struct.getUserUuid()); - msg.setSession(session); - IdentityCanonicalEvents.AccountLoginData data = new IdentityCanonicalEvents.AccountLoginData(); - data.setAccountUuid(struct.getAccountUuid()); - data.setUserUuid(struct.getUserUuid()); - evtf.fire(IdentityCanonicalEvents.ACCOUNT_LOGIN_PATH, data); + }); + } - reply.setInventory(session); + private void handle(CreateAccountMsg msg) { + AccountInventory inv = createAccount(msg); + CreateAccountReply reply = new CreateAccountReply(); + reply.setInventory(inv); bus.reply(msg, reply); } - private void handle(APICreateAccountMsg msg) { + public AccountInventory createAccount(CreateAccountMsg msg) { final AccountInventory inv = new SQLBatchWithReturn() { @Override protected AccountInventory scripts() { AccountVO vo = new AccountVO(); - if (msg.getResourceUuid() != null) { - vo.setUuid(msg.getResourceUuid()); + if (msg.getUuid() != null) { + vo.setUuid(msg.getUuid()); } else { vo.setUuid(Platform.getUuid()); } @@ -604,13 +613,41 @@ protected AccountInventory scripts() { } }.execute(); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(BeforeCreateAccountExtensionPoint.class), + arg -> arg.beforeCreateAccount(inv)); CollectionUtils.safeForEach(pluginRgty.getExtensionList(AfterCreateAccountExtensionPoint.class), arg -> arg.afterCreateAccount(inv)); - APICreateAccountEvent evt = new APICreateAccountEvent(msg.getId()); - evt.setInventory(inv); - bus.publish(evt); + return inv; + } + + private void handle(APICreateAccountMsg msg) { + CreateAccountMsg accountMsg = new CreateAccountMsg(); + if (msg.getResourceUuid() != null) { + accountMsg.setUuid(msg.getResourceUuid()); + } else { + accountMsg.setUuid(Platform.getUuid()); + } + accountMsg.setName(msg.getName()); + accountMsg.setDescription(msg.getDescription()); + accountMsg.setPassword(msg.getPassword()); + accountMsg.setType(msg.getType()); + bus.makeTargetServiceIdByResourceUuid(accountMsg, AccountConstant.SERVICE_ID, accountMsg.getUuid()); + bus.send(accountMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + APICreateAccountEvent evt = new APICreateAccountEvent(msg.getId()); + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + } else { + CreateAccountReply reply1 = reply.castReply(); + evt.setInventory(reply1.getInventory()); + } + bus.publish(evt); + } + }); + } @Override @@ -653,12 +690,45 @@ public boolean start() { accountApiControlInternal.addAll(apis); } + installNeedQuotaCheckMessageHandlers(); } catch (Exception e) { throw new CloudRuntimeException(e); } return true; } + private void installNeedQuotaCheckMessageHandlers() { + bus.installBeforeDeliveryMessageInterceptor(new BeforeDeliveryMessageInterceptor() { + @Override + public int orderOfBeforeDeliveryMessageInterceptor() { + return -100; + } + + @Override + public void beforeDeliveryMessage(Message msg) { + if (msg.getServiceId().equals(ApiMediatorConstant.SERVICE_ID)) { + // the API message will be routed by ApiMediator, + // filter out this message to avoid reporting the same + // API message twice + return; + } + + if (!(msg instanceof NeedQuotaCheckMessage)) { + return; + } + + String accountUuid = ((NeedQuotaCheckMessage) msg).getAccountUuid(); + if (accountUuid == null) { + logger.warn(String.format("missing accountUuid of message[id: %s]," + + " skip quota check to keep compatible", msg.getId())); + return; + } + + new QuotaUtil().checkQuota(msg, accountUuid, accountUuid); + } + }, new ArrayList<>()); + } + private void updateResourceVONameOnEntityUpdate() { dbf.installEntityLifeCycleCallback(null, EntityEvent.PRE_UPDATE, (evt, o) -> { if (o instanceof ResourceVO) { @@ -729,68 +799,65 @@ public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { } private void collectDefaultQuota() { - Map defaultQuota = new HashMap<>(); - - // Add quota and quota checker + // Add quota definition and quota message checker for (ReportQuotaExtensionPoint ext : pluginRgty.getExtensionList(ReportQuotaExtensionPoint.class)) { List quotas = ext.reportQuota(); - DebugUtils.Assert(quotas != null, String.format("%s.getQuotaPairs() returns null", ext.getClass())); - + DebugUtils.Assert(quotas != null, String.format("%s.reportQuota() returns null", ext.getClass())); definedQuotas.addAll(quotas); for (Quota quota : quotas) { - DebugUtils.Assert(quota.getQuotaPairs() != null, - String.format("%s reports a quota containing a null quotaPairs", ext.getClass())); - - for (QuotaPair p : quota.getQuotaPairs()) { - if (defaultQuota.containsKey(p.getName())) { - throw new CloudRuntimeException(String.format("duplicate DefaultQuota[resourceType: %s] reported by %s", p.getName(), ext.getClass())); - } - - defaultQuota.put(p.getName(), p.getValue()); - nameQuotaMap.put(p.getName(), quota); - } + DebugUtils.Assert(quota.getQuotaDefinitions() != null + || !quota.getQuotaMessageCheckerList().isEmpty(), + String.format("%s reports a quota containing a null quotaDefinitions and message handlers", ext.getClass())); + collectQuotaDefinitions(quota, ext); + checkDeprecatedQuotaPairs(quota); + collectQuotaMessageCheckers(quota); + } + } - for (Class clz : quota.getMessagesNeedValidation()) { - if (messageQuotaMap.containsKey(clz)) { - messageQuotaMap.get(clz).add(quota); - } else { - ArrayList quotaArrayList = new ArrayList<>(); - quotaArrayList.add(quota); - messageQuotaMap.put(clz, quotaArrayList); - } + // repairAccountQuota(); + } - } + private void collectQuotaMessageCheckers(Quota quota) { + for (QuotaMessageHandler checker : quota.getQuotaMessageCheckerList()) { + if (messageHandlerMap.containsKey(checker.messageClass)) { + messageHandlerMap.get(checker.messageClass).add(checker); + } else { + List> checkers = new ArrayList<>(); + checkers.add(checker); + messageHandlerMap.put(checker.messageClass, checkers); } } + } - // Add additional quota checker to quota - for (RegisterQuotaCheckerExtensionPoint ext : pluginRgty.getExtensionList(RegisterQuotaCheckerExtensionPoint.class)) { - // Map> - Map> m = ext.registerQuotaValidator(); - for (Map.Entry> entry : m.entrySet()) { - Quota quota = nameQuotaMap.get(entry.getKey()); - quota.addQuotaValidators(entry.getValue()); - for (Quota.QuotaValidator q : entry.getValue()) { - for (Class clz : q.getMessagesNeedValidation()) { - if (messageQuotaMap.containsKey(clz)) { - messageQuotaMap.get(clz).add(quota); - } else { - ArrayList quotaArrayList = new ArrayList<>(); - quotaArrayList.add(quota); - messageQuotaMap.put(clz, quotaArrayList); - } - } - } + private void collectQuotaDefinitions(Quota quota, ReportQuotaExtensionPoint ext) { + if (quota.getQuotaDefinitions() == null) { + return; + } + + for (QuotaDefinition d : quota.getQuotaDefinitions()) { + if (nameQuotaMap.containsKey(d.getName())) { + throw new CloudRuntimeException(String.format("duplicate DefaultQuota[resourceType: %s] reported by %s", d.getName(), ext.getClass())); } + nameQuotaMap.put(d.getName(), quota); + quotaDefinitionMap.put(d.getName(), d); } - - repairAccountQuota(defaultQuota); } + private void checkDeprecatedQuotaPairs(Quota quota) { + if (quota.getQuotaPairs() == null) { + return; + } + + for (QuotaPair d : quota.getQuotaPairs()) { + logger.warn(String.format("Deprecated QuotaPair[name: %s, value: %d] is still used", + d.getName(), d.getValue())); + } + throw new CloudRuntimeException("QuotaPair is not supported now, use QuotaDefinition instead"); + } - private void repairAccountQuota(Map defaultQuota) { + private void repairAccountQuota() { new SQLBatch() { @Override protected void scripts() { @@ -799,14 +866,15 @@ protected void scripts() { .count(); sql("select uuid from AccountVO account where account.type = :type", String.class) .param("type", AccountType.Normal) - .limit(1000) + .limit(2000) .paginate(count, (List normalAccounts) -> { - List needPersistQuotas = new ArrayList<>(); + ConcurrentLinkedQueue needPersistQuotas = new ConcurrentLinkedQueue<>(); normalAccounts.parallelStream().forEach(nA -> { List existingQuota = q(QuotaVO.class).select(QuotaVO_.name).eq(QuotaVO_.identityUuid, nA).listValues(); - for (Map.Entry e : defaultQuota.entrySet()) { + for (Map.Entry e : quotaDefinitionMap.entrySet()) { String rtype = e.getKey(); - Long value = e.getValue(); + Long value = e.getValue().getRepairValue() != null ? + e.getValue().getRepairValue() : e.getValue().getDefaultValue(); if (existingQuota.contains(rtype)) { continue; } @@ -825,6 +893,7 @@ protected void scripts() { } } }); + needPersistQuotas.forEach(this::persist); }); } @@ -1195,7 +1264,7 @@ private void accountFieldCheck() throws IllegalAccessException { private void useDecision(Decision d, boolean userPolicy) { String policyCategory = userPolicy ? "user policy" : "group policy"; - if (d.effect == StatementEffect.Allow) { + if (d.effect == PolicyStatementEffect.Allow) { logger.debug(String.format("API[name: %s, action: %s] is approved by a %s[name: %s, uuid: %s]," + " statement[name: %s, action: %s]", msg.getClass().getSimpleName(), d.action, policyCategory, d.policy.getName(), d.policy.getUuid(), d.statement.getName(), d.actionRule)); @@ -1310,7 +1379,7 @@ class Decision { String action; PolicyStatement statement; String actionRule; - StatementEffect effect; + PolicyStatementEffect effect; } private Decision decide(List userPolicies) { diff --git a/identity/src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java b/identity/src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java index 6a956bb3c5a..b56d11c65cd 100644 --- a/identity/src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java +++ b/identity/src/main/java/org/zstack/identity/AccountQuotaUpdateChecker.java @@ -4,10 +4,11 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.AccountVO; -import org.zstack.header.identity.Quota; import org.zstack.header.identity.QuotaVO; +import org.zstack.header.identity.quota.QuotaDefinition; -import java.util.*; +import java.util.HashSet; +import java.util.Set; import static org.zstack.core.Platform.argerr; @@ -40,20 +41,18 @@ public ErrorCode check(QuotaVO quota, long updatedValue) { * TODO duplicate code with APIGetAccountQuotaUsageMsg's implement refactor requested */ private ErrorCode checkQuotaChangeForAccount(String accountUuid, String quotaName, long updatedValue) { - List quotas = accountManager.getQuotas(); - Quota.QuotaUsage usage = quotas.stream() - .map(q -> q.getOperator().getQuotaUsageByAccount(accountUuid)) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .filter(u -> quotaName.equals(u.getName())) - .findAny().orElse(null); - if (usage == null) { + QuotaDefinition quota = accountManager.getQuotasDefinitions().get(quotaName); + if (quota == null) { throw new CloudRuntimeException(String.format("cannot find usage[name:%s]", quotaName)); } + Long used = quota.getQuotaUsage(accountUuid); + if (used == null) { + used = 0L; + } - if (usage.getUsed() > updatedValue) { + if (used > updatedValue) { return argerr("the account[uuid:%s] used [name:%s, usedValue:%s] exceeds request quota: %d", - accountUuid, quotaName, usage.getUsed(), updatedValue); + accountUuid, quotaName, used, updatedValue); } return null; diff --git a/identity/src/main/java/org/zstack/identity/AuthorizationManager.java b/identity/src/main/java/org/zstack/identity/AuthorizationManager.java index 7fa7cc58a45..fe7f727b7ce 100755 --- a/identity/src/main/java/org/zstack/identity/AuthorizationManager.java +++ b/identity/src/main/java/org/zstack/identity/AuthorizationManager.java @@ -11,10 +11,8 @@ import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.identity.IdentityByPassCheck; -import org.zstack.header.identity.IdentityErrors; -import org.zstack.header.identity.SessionInventory; -import org.zstack.header.identity.SuppressCredentialCheck; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.identity.*; import org.zstack.header.identity.extension.AuthorizationBackend; import org.zstack.header.message.APIMessage; import org.zstack.header.zql.ZQLQueryExtensionPoint; @@ -40,6 +38,7 @@ public class AuthorizationManager implements GlobalApiMessageInterceptor, Compon private DefaultAuthorizationBackend defaultAuthorizationBackend; private List authorizationBackends; + private List renewSessionPreAuthExtensionPoints; private Cache authorizationBackendsCache = CacheBuilder.newBuilder() .maximumSize(IdentityGlobalProperty.AUTHORIZATION_SESSION_CACHE_SIZE) @@ -72,6 +71,13 @@ private SessionInventory evaluateSession(APIMessage msg) { "session uuid is null")); } + for (RenewSessionPreAuthExtensionPoint ext : renewSessionPreAuthExtensionPoints) { + ErrorCode errorCode= ext.checkAuth(msg.getSession()); + if (errorCode != null) { + throw new OperationFailureException(errorCode); + } + } + msg.setSession(Session.renewSession(msg.getSession().getUuid(), null)); return msg.getSession(); } @@ -109,6 +115,10 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti session = evaluateSession(msg); } + logger.trace(String.format("authorizing message[%s] with user[accountUuid:%s, uuid:%s] session", + msg.getMessageName(), + session.getAccountUuid(), + session.getUserUuid())); return findAuthorizationBackend(session).authorize(msg); } @@ -116,6 +126,7 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti public boolean start() { authorizationBackends = pluginRegistry.getExtensionList(AuthorizationBackend.class); authorizationBackends.remove(defaultAuthorizationBackend); + renewSessionPreAuthExtensionPoints = pluginRegistry.getExtensionList(RenewSessionPreAuthExtensionPoint.class); return true; } @@ -138,12 +149,12 @@ public void beforeQueryExtensionPoint(List queryTargetInventoryClass, Ses findAuthorizationBackend(session).validatePermission(targetApis, session); } - public static ErrorCode createAdditionAuthErrorCode(String credentials, String... authentications) { + public static ErrorCode createAdditionAuthErrorCode(Map properties, String... authentications) { JsonObject o = new JsonObject(); JsonArray authArray = new JsonArray(authentications.length); Arrays.asList(authentications).forEach(authArray::add); o.add("authentications", authArray); - o.addProperty("credentials", credentials); + properties.forEach(o::addProperty); return err(IdentityErrors.NEED_ADDITION_AUTHENTICATION, "%s", o.toString()); } } diff --git a/identity/src/main/java/org/zstack/identity/IAMIdentityResourceGenerator.java b/identity/src/main/java/org/zstack/identity/IAMIdentityResourceGenerator.java index 8c6b9e5f26a..ca045613d5f 100644 --- a/identity/src/main/java/org/zstack/identity/IAMIdentityResourceGenerator.java +++ b/identity/src/main/java/org/zstack/identity/IAMIdentityResourceGenerator.java @@ -10,7 +10,6 @@ import org.zstack.utils.logging.CLogger; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import static org.zstack.utils.CollectionDSL.list; @@ -49,7 +48,7 @@ private void makeReadAPIsForNormalAccountJSONStatement() { readAPIs.add(APIUpdateUserMsg.class.getName()); PolicyStatement s = PolicyStatement.builder().name("read-apis-for-normal-account") - .effect(StatementEffect.Allow) + .effect(PolicyStatementEffect.Allow) .actions(readAPIs) .build(); diff --git a/identity/src/main/java/org/zstack/identity/LogoutExtensionPoint.java b/identity/src/main/java/org/zstack/identity/LogoutExtensionPoint.java new file mode 100644 index 00000000000..8ffb20b7965 --- /dev/null +++ b/identity/src/main/java/org/zstack/identity/LogoutExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.identity; + +import org.zstack.header.identity.SessionInventory; + +/** + * @Author: DaoDao + * @Date: 2023/8/31 + */ +public interface LogoutExtensionPoint { + void beforeLogout(SessionInventory session); +} diff --git a/identity/src/main/java/org/zstack/identity/QuotaAPIRequestChecker.java b/identity/src/main/java/org/zstack/identity/QuotaAPIRequestChecker.java index 691c9cd9fdf..4cc1e60a84e 100755 --- a/identity/src/main/java/org/zstack/identity/QuotaAPIRequestChecker.java +++ b/identity/src/main/java/org/zstack/identity/QuotaAPIRequestChecker.java @@ -3,14 +3,13 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.header.identity.Quota; import org.zstack.header.identity.rbac.RBACEntity; -import java.util.List; -import java.util.Map; - @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class QuotaAPIRequestChecker implements APIRequestChecker { + + private final QuotaUtil util = new QuotaUtil(); + @Autowired private AccountManager acntMgr; @@ -20,19 +19,6 @@ public void check(RBACEntity entity) { return; } - List quotas = acntMgr.getMessageQuotaMap().get(entity.getApiMessage().getClass()); - if (quotas == null || quotas.isEmpty()) { - return; - } - - quotas.forEach(quota -> { - Map pairs = new QuotaUtil().makeQuotaPairs(entity.getApiMessage().getSession().getAccountUuid()); - quota.getOperator().checkQuota(entity.getApiMessage(), pairs); - if (quota.getQuotaValidators() != null) { - for (Quota.QuotaValidator q : quota.getQuotaValidators()) { - q.checkQuota(entity.getApiMessage(), pairs); - } - } - }); + util.checkQuota(entity.getApiMessage()); } } diff --git a/identity/src/main/java/org/zstack/identity/QuotaExtensionPoint.java b/identity/src/main/java/org/zstack/identity/QuotaExtensionPoint.java new file mode 100644 index 00000000000..b49a39ce967 --- /dev/null +++ b/identity/src/main/java/org/zstack/identity/QuotaExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.identity; + +import org.zstack.header.identity.QuotaVO; + +public interface QuotaExtensionPoint { + void beforeUpdateQuota(String quotaName, long newValue, String accountUuid); +} diff --git a/identity/src/main/java/org/zstack/identity/QuotaUtil.java b/identity/src/main/java/org/zstack/identity/QuotaUtil.java index d4826eff79b..94313ab1915 100644 --- a/identity/src/main/java/org/zstack/identity/QuotaUtil.java +++ b/identity/src/main/java/org/zstack/identity/QuotaUtil.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; @@ -12,30 +13,38 @@ import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; -import org.zstack.header.identity.AccountResourceRefVO; -import org.zstack.header.identity.AccountResourceRefVO_; -import org.zstack.header.identity.AccountType; -import org.zstack.header.identity.AccountVO; -import org.zstack.header.identity.AccountVO_; -import org.zstack.header.identity.IdentityErrors; -import org.zstack.header.identity.Quota; -import org.zstack.header.identity.QuotaVO; -import org.zstack.header.identity.QuotaVO_; +import org.zstack.header.identity.*; +import org.zstack.header.identity.quota.FixedSizeRequiredRequest; +import org.zstack.header.identity.quota.FunctionalSizeRequiredRequest; +import org.zstack.header.identity.quota.QuotaMessageHandler; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.message.NeedQuotaCheckMessage; +import org.zstack.utils.Utils; +import org.zstack.utils.function.Function; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; import javax.persistence.Tuple; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; + import static org.zstack.core.Platform.err; /** * Created by miao on 16-10-9. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class QuotaUtil { + private static final CLogger logger = Utils.getLogger(QuotaUtil.class); + @Autowired private ErrorFacade errf; @Autowired private DatabaseFacade dbf; + @Autowired + private AccountManager acntMgr; public static class QuotaCompareInfo { public String currentAccountUuid; @@ -61,7 +70,10 @@ public String getResourceOwnerAccountUuid(String resourceUuid) { } } + @Transactional(readOnly = true) public void CheckQuota(QuotaCompareInfo quotaCompareInfo) { + logger.trace(String.format("dump quota QuotaCompareInfo: \n %s", + JSONObjectUtil.toJsonString(quotaCompareInfo))); String accountName = Q.New(AccountVO.class) .select(AccountVO_.name) .eq(AccountVO_.uuid, quotaCompareInfo.resourceTargetOwnerAccountUuid) @@ -130,4 +142,107 @@ public ErrorCode buildQuataExceedError(String currentAccountUuid, String quotaNa currentAccountUuid, quotaName, quotaValue, currentUsed, request); } + @Transactional(readOnly = true) + public void checkQuota(APIMessage msg) { + checkQuota(msg, msg.getSession().getAccountUuid(), msg.getSession().getAccountUuid()); + } + + @Transactional(readOnly = true) + public void checkQuota(Message msg, String currentAccountUuid, String targetAccountUuid) { + if (!(msg instanceof APIMessage) && !(msg instanceof NeedQuotaCheckMessage)) { + return; + } + + if (AccountConstant.isAdminPermission(targetAccountUuid)) { + return; + } + + List> handlers = acntMgr.getQuotaMessageHandlerMap().entrySet().stream() + .filter((entry) -> entry.getKey().isAssignableFrom(msg.getClass())) + .map((Map.Entry::getValue)) + .flatMap(List::stream) + .collect(Collectors.toList()); + if (handlers.isEmpty()) { + return; + } + + Map pairs = makeQuotaPairs(targetAccountUuid); + logger.trace("dump quota pairs of before handle" + targetAccountUuid + " :\n" + JSONObjectUtil.toJsonString(pairs)); + for (QuotaMessageHandler checker : handlers) { + if (needSkipCheck(msg, checker)) { + logger.trace(String.format("skip quota message[name: %s] check[name: %s]", msg.getClass(), checker.getClass())); + continue; + } + + logger.trace(String.format("start quota message[name: %s] check[name: %s]", msg.getClass(), checker.getClass())); + for (Object request : checker.getFunctionalSizeRequiredRequests()) { + checkFunctionalSizeRequest(msg, (FunctionalSizeRequiredRequest) request, currentAccountUuid, targetAccountUuid, pairs); + } + + for (Object request : checker.getFixedSizeRequiredRequests()) { + checkFixedSizeRequest((FixedSizeRequiredRequest) request, currentAccountUuid, targetAccountUuid, pairs); + } + } + } + + private boolean needSkipCheck(Message msg, QuotaMessageHandler checker) { + for (Object condition : checker.getConditions()) { + Boolean result = (Boolean) ((Function) condition).call(msg); + + // if condition not match return skip + if (result == Boolean.FALSE) { + return true; + } + } + + return false; + } + + @Transactional(readOnly = true) + private void checkFunctionalSizeRequest(Message msg, + FunctionalSizeRequiredRequest requiredRequest, + String currentAccountUuid, + String targetAccountUuid, + Map pairs) { + Long asked = (Long) requiredRequest.getFunction().call(msg); + Long used = acntMgr.getQuotasDefinitions().get(requiredRequest.getQuotaName()).getQuotaUsage(targetAccountUuid); + + if (used == null) { + used = 0L; + } + + if (asked == null || asked == 0) { + logger.trace("skip quota check because no required"); + return; + } + + QuotaUtil.QuotaCompareInfo quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); + quotaCompareInfo.currentAccountUuid = currentAccountUuid; + quotaCompareInfo.resourceTargetOwnerAccountUuid = targetAccountUuid; + quotaCompareInfo.quotaName = requiredRequest.getQuotaName(); + quotaCompareInfo.quotaValue = pairs.get(requiredRequest.getQuotaName()).getValue(); + quotaCompareInfo.currentUsed = used; + quotaCompareInfo.request = asked; + CheckQuota(quotaCompareInfo); + } + + @Transactional(readOnly = true) + private void checkFixedSizeRequest(FixedSizeRequiredRequest fixedSizeRequiredRequest, String currentAccountUuid, String targetAccountUuid, Map pairs) { + Long asked = fixedSizeRequiredRequest.getValue(); + Long used = acntMgr.getQuotasDefinitions().get(fixedSizeRequiredRequest.getQuotaName()).getQuotaUsage(targetAccountUuid); + if (asked == 0) { + return; + } + + QuotaUtil.QuotaCompareInfo quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); + quotaCompareInfo.currentAccountUuid = currentAccountUuid; + quotaCompareInfo.resourceTargetOwnerAccountUuid = targetAccountUuid; + quotaCompareInfo.quotaName = fixedSizeRequiredRequest.getQuotaName(); + Quota.QuotaPair pair = pairs.get(fixedSizeRequiredRequest.getQuotaName()); + logger.debug("get quota pair of " + fixedSizeRequiredRequest.getQuotaName() + ":\n" + JSONObjectUtil.toJsonString(pair)); + quotaCompareInfo.quotaValue = pairs.get(fixedSizeRequiredRequest.getQuotaName()).getValue(); + quotaCompareInfo.currentUsed = used; + quotaCompareInfo.request = asked; + CheckQuota(quotaCompareInfo); + } } diff --git a/identity/src/main/java/org/zstack/identity/Session.java b/identity/src/main/java/org/zstack/identity/Session.java index a56f3e3730b..2b27931beef 100755 --- a/identity/src/main/java/org/zstack/identity/Session.java +++ b/identity/src/main/java/org/zstack/identity/Session.java @@ -1,5 +1,7 @@ package org.zstack.identity; +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; @@ -38,8 +40,13 @@ public class Session implements Component { private DatabaseFacade dbf; @Autowired private EventFacade evtf; + @Autowired + private PluginRegistry pluginRgty; + + private static List logoutExtensionPoints; private Future expiredSessionCollector; + private static Interner sessionLock = Interners.newWeakInterner(); private static Map sessions = new ConcurrentHashMap<>(); @@ -112,13 +119,14 @@ private Timestamp getCurrentSqlDate() { @Override protected SessionInventory scripts() { - Timestamp expiredDate = new Timestamp(TimeUnit.SECONDS.toMillis(finalExtendPeriod) + getCurrentSqlDate().getTime()); - SessionInventory s = getSession(uuid); - s.setExpiredDate(expiredDate); - - sql(SessionVO.class).eq(SessionVO_.uuid, uuid).set(SessionVO_.expiredDate, expiredDate).update(); + Timestamp expiredDate = new Timestamp(TimeUnit.SECONDS.toMillis(finalExtendPeriod) + getCurrentSqlDate().getTime()); + SessionInventory s = getSession(uuid); + if (s != null) { + s.setExpiredDate(expiredDate); + sql(SessionVO.class).eq(SessionVO_.uuid, uuid).set(SessionVO_.expiredDate, expiredDate).update(); + } - return s; + return s; } }.execute(); @@ -149,6 +157,12 @@ public static void logoutUser(String userUuid) { } public static void logout(String uuid) { + synchronized (sessionLock.intern(uuid)) { + deleteSession(uuid); + } + } + + private static void deleteSession(String uuid) { new SQLBatch() { @Override protected void scripts() { @@ -211,6 +225,11 @@ protected ErrorCode scripts() { } logout(s.getUuid()); + + for (LogoutExtensionPoint ext : logoutExtensionPoints) { + ext.beforeLogout(s); + } + return err(IdentityErrors.INVALID_SESSION, "Session expired"); } @@ -234,8 +253,12 @@ public static Map getSessionsCopy() { } public static SessionInventory getSession(String uuid) { - SessionInventory s = sessions.get(uuid); - if (s == null) { + synchronized (sessionLock.intern(uuid)) { + SessionInventory s = sessions.get(uuid); + if (s != null) { + return s; + } + SessionVO vo = Q.New(SessionVO.class).eq(SessionVO_.uuid, uuid).find(); if (vo == null) { return null; @@ -243,9 +266,8 @@ public static SessionInventory getSession(String uuid) { s = SessionInventory.valueOf(vo); sessions.put(s.getUuid(), s); + return s; } - - return s; } @Override @@ -253,6 +275,7 @@ public boolean start() { setupGlobalConfig(); startCleanUpStaleSessionTask(); setupCanonicalEvents(); + logoutExtensionPoints = pluginRgty.getExtensionList(LogoutExtensionPoint.class); return true; } @@ -260,7 +283,7 @@ private void setupGlobalConfig() { IdentityGlobalConfig.SESSION_CLEANUP_INTERVAL.installUpdateExtension((oldConfig, newConfig) -> startCleanUpStaleSessionTask()); } - private void startCleanUpStaleSessionTask() { + private synchronized void startCleanUpStaleSessionTask() { if (expiredSessionCollector != null) { expiredSessionCollector.cancel(true); } diff --git a/identity/src/main/java/org/zstack/identity/login/LoginManagerImpl.java b/identity/src/main/java/org/zstack/identity/login/LoginManagerImpl.java new file mode 100644 index 00000000000..42b127de4cd --- /dev/null +++ b/identity/src/main/java/org/zstack/identity/login/LoginManagerImpl.java @@ -0,0 +1,334 @@ +package org.zstack.identity.login; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.AbstractService; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.identity.APILogInReply; +import org.zstack.header.identity.APISessionMessage; +import org.zstack.header.identity.AccountConstant; +import org.zstack.header.identity.SessionInventory; +import org.zstack.header.identity.login.*; +import org.zstack.header.message.Message; +import org.zstack.identity.Session; +import org.zstack.utils.BeanUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +public class LoginManagerImpl extends AbstractService implements LoginManager { + private static final CLogger logger = Utils.getLogger(LoginManagerImpl.class); + + @Autowired + private CloudBus bus; + @Autowired + private PluginRegistry pluginRgty; + + private final Map loginBackends = new HashMap<>(); + private final Map loginAPIAdapters = new HashMap<>(); + private final List loginAuthExtensionPoints = new ArrayList<>(); + + @Override + public LoginBackend getLoginBackend(String loginType) { + LoginBackend loginBackend = loginBackends.get(loginType); + + if (loginBackend == null) { + throw new OperationFailureException(operr("unsupported login type %s", loginType)); + } + + return loginBackend; + } + + @Override + public String getUserIdByName(String username, String loginType) { + LoginBackend loginBackend = getLoginBackend(loginType); + + String userId = loginBackend.getUserIdByName(username); + if (userId != null) { + return userId; + } + + return String.format(AccountConstant.NO_EXIST_ACCOUNT, username); + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof APILogInMsg) { + handle((APILogInMsg) msg); + } else if (msg instanceof LogInMsg) { + handle((LogInMsg) msg); + } else if (msg instanceof APIGetLoginProceduresMsg) { + handle((APIGetLoginProceduresMsg) msg); + } else if (msg instanceof APISessionMessage) { + handle((APISessionMessage) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIGetLoginProceduresMsg msg) { + APIGetLoginProceduresReply reply = new APIGetLoginProceduresReply(); + + LoginContext loginContext = LoginContext.fromAPIGetLoginProceduresMsg(msg); + LoginBackend loginBackend = getLoginBackend(msg.getLoginType()); + loginContext.setPossibleUsersGetter(loginBackend::possibleUserUuidSetForGettingProcedures); + List matchedAuthExtensions = + getBackendSupportedLoginAuthExtension( + loginBackend.getRequiredAdditionalAuthFeature(), + new ArrayList<>()); + + List descList = matchedAuthExtensions + .stream() + .map(ext -> ext.getAdditionalAuthDesc(loginContext)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + reply.setProcedures(descList); + bus.reply(msg, reply); + } + + private void handle(APISessionMessage msg) { + LoginAPIAdapter apiAdapter = loginAPIAdapters.get(msg.getClass().getCanonicalName()); + + if (apiAdapter == null) { + logger.debug(String.format("no LoginAPIAdapter found for msg: %s", msg.getClass().getCanonicalName())); + bus.dealWithUnknownMessage(msg); + return; + } + + APILogInMsg apiLogInMsg = apiAdapter.transferToAPILogInMsg(msg); + LoginContext loginContext = LoginContext.fromApiLoginMessage(apiLogInMsg); + APILogInReply reply = new APILogInReply(); + doLogIn(loginContext, new ReturnValueCompletion(msg) { + @Override + public void success(SessionInventory session) { + reply.setInventory(session); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(LogInMsg msg) { + LoginContext loginContext = LoginContext.fromLoginMessage(msg); + LogInReply reply = new LogInReply(); + doLogIn(loginContext, new ReturnValueCompletion(msg) { + @Override + public void success(SessionInventory session) { + reply.setSession(session); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(APILogInMsg msg) { + LoginContext loginContext = LoginContext.fromApiLoginMessage(msg); + APILogInReply reply = new APILogInReply(); + doLogIn(loginContext, new ReturnValueCompletion(msg) { + @Override + public void success(SessionInventory session) { + reply.setInventory(session); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private List getBackendSupportedLoginAuthExtension(List types, List ignoreFeatures) { + if (types == null || types.isEmpty()) { + return new ArrayList<>(); + } + + return loginAuthExtensionPoints + .stream() + .filter(ext -> types.contains(ext.getAdditionalAuthFeature()) + && !ignoreFeatures.contains(ext.getAdditionalAuthFeature())) + .collect(Collectors.toList()); + } + + private void doLogIn(LoginContext loginContext, ReturnValueCompletion completion) { + LoginBackend loginBackend = getLoginBackend(loginContext.getLoginBackendType()); + List matchedAuthExtensions = + getBackendSupportedLoginAuthExtension( + loginBackend.getRequiredAdditionalAuthFeature(), + loginContext.getIgnoreFeatures()); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + loginBackend.collectUserInfoIntoContext(loginContext); + + if (loginContext.getUserUuid() != null) { + logger.debug(String.format("login user[uuid: %s, type: %s]", loginContext.getUserUuid(), loginContext.getUserType())); + } else { + logger.debug("no user uuid exists," + + " treat this login as a not existing user login operation"); + loginContext.setUserUuid(String.format(AccountConstant.NO_EXIST_ACCOUNT, + loginContext.getUsername())); + } + + chain.setName(String.format("login-%s-with-backend-%s", loginContext.getUsername(), loginContext.getLoginBackendType())); + chain.then(new NoRollbackFlow() { + String __name__ = "run-before-login-extensions"; + + @Override + public void run(FlowTrigger trigger, Map data) { + for (LoginAuthExtensionPoint ext : matchedAuthExtensions) { + ErrorCode errorCode = ext.beforeExecuteLogin(loginContext); + + if (errorCode != null) { + trigger.fail(errorCode); + return; + } + } + + trigger.next(); + } + }).then(new NoRollbackFlow() { + String __name__ = "process-login"; + + @Override + public void run(FlowTrigger trigger, Map data) { + loginBackend.login(loginContext, new ReturnValueCompletion(trigger) { + @Override + public void success(LoginSessionInfo info) { + data.put(LoginAuthConstant.LOGIN_SESSION_INFO, info); + + ErrorCode errorCode = runPostLoginExtensions(loginContext, info); + if (errorCode != null) { + trigger.fail(errorCode); + return; + } + + SessionInventory session = processSession(info); + data.put(LoginAuthConstant.LOGIN_SESSION_INVENTORY, session); + loginContext.getProperties().put(LoginAuthConstant.LOGIN_SESSION_UUID, session.getUuid()); + for (LoginAuthExtensionPoint ext : matchedAuthExtensions) { + ext.afterLoginSuccess(loginContext, info); + } + + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + + private ErrorCode runPostLoginExtensions(LoginContext context, LoginSessionInfo info) { + for (LoginAuthExtensionPoint ext : matchedAuthExtensions) { + ErrorCode errorCode = ext.postLogin(loginContext, info); + + if (errorCode == null) { + continue; + } + + return errorCode; + } + + return null; + } + + private SessionInventory processSession(LoginSessionInfo info) { + if (info.isLogoutOperatorSession()) { + Session.logout(loginContext.getOperatorSession().getUuid()); + } + + SessionInventory session; + // manually create a SessionInventory as validation result + if (loginContext.isValidateOnly()) { + session = new SessionInventory(); + session.setAccountUuid(info.getAccountUuid()); + session.setUserUuid(info.getUserUuid()); + session.setUserType(info.getUserType()); + } else { + session = Session.login(info.getAccountUuid(), info.getUserUuid()); + } + + return session; + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success((SessionInventory) data.get(LoginAuthConstant.LOGIN_SESSION_INVENTORY)); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + LoginSessionInfo info = (LoginSessionInfo) data.get(LoginAuthConstant.LOGIN_SESSION_INFO); + for (LoginAuthExtensionPoint ext : matchedAuthExtensions) { + ext.afterLoginFailure(loginContext, info, errCode); + } + + completion.fail(errCode); + } + }).start(); + + } + + @Override + public String getId() { + return bus.makeLocalServiceId(LoginManager.SERVICE_ID); + } + + @Override + public boolean start() { + populateExtensions(); + return true; + } + + private void populateExtensions() { + loginAuthExtensionPoints.addAll(pluginRgty.getExtensionList(LoginAuthExtensionPoint.class)); + + for (LoginBackend backend : pluginRgty.getExtensionList(LoginBackend.class)) { + LoginBackend oldBackend = loginBackends.get(backend.getLoginType().toString()); + if (oldBackend != null) { + throw new CloudRuntimeException(String.format + ("duplicate backend with login type %s", oldBackend.getLoginType())); + } + + loginBackends.put(backend.getLoginType().toString(), backend); + } + + BeanUtils.reflections.getSubTypesOf(LoginAPIAdapter.class).forEach(clz -> { + LoginAPIAdapter apiAdapter; + try { + apiAdapter = clz.getConstructor().newInstance(); + } catch (Exception e) { + throw new CloudRuntimeException(e); + } + + loginAPIAdapters.put(apiAdapter.getMessageClass().getCanonicalName(), apiAdapter); + }); + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/identity/src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java b/identity/src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java index 79916a414d1..a9fbd8bf1c3 100755 --- a/identity/src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java +++ b/identity/src/main/java/org/zstack/identity/rbac/OperationTargetAPIRequestChecker.java @@ -237,6 +237,9 @@ private void checkIfTheAccountCanAccessTheResource(APIMessage.FieldParam param) if (RBAC.isResourceGlobalReadable(resourceType)) { return; } + if (!OwnedByAccount.class.isAssignableFrom(resourceType)){ + return; + } List uuids = getResourceUuids(param); if (uuids.isEmpty()) { diff --git a/identity/src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java b/identity/src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java index 97f6227f2e2..c2eb1e54b08 100755 --- a/identity/src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java +++ b/identity/src/main/java/org/zstack/identity/rbac/RBACAPIRequestChecker.java @@ -36,8 +36,10 @@ public void check(RBACEntity entity) { return; } - if (PolicyUtils.isAdminOnlyAction(entity.getApiName()) && !AccountConstant.isAdminPermission(entity.getApiMessage().getSession())) { - throw new OperationFailureException(err(IdentityErrors.PERMISSION_DENIED, "request api is admin only, can not be executed by current user")); + if (!AccountConstant.isAdminPermission(entity.getApiMessage().getSession()) && PolicyUtils.isAdminOnlyAction(entity.getApiName())) { + throw new OperationFailureException(err(IdentityErrors.PERMISSION_DENIED, + "request api[name: %s] is admin only, can not be executed by current user", + entity.getApiName())); } check(); diff --git a/identity/src/main/java/org/zstack/identity/rbac/RBACManager.java b/identity/src/main/java/org/zstack/identity/rbac/RBACManager.java index 35903c19835..7f136f9ec15 100755 --- a/identity/src/main/java/org/zstack/identity/rbac/RBACManager.java +++ b/identity/src/main/java/org/zstack/identity/rbac/RBACManager.java @@ -3,7 +3,6 @@ import org.zstack.core.db.SQLBatchWithReturn; import org.zstack.header.identity.*; import org.zstack.header.message.APIMessage; -import org.zstack.identity.Session; import java.util.ArrayList; import java.util.HashMap; @@ -21,20 +20,14 @@ static List getPoliciesByAPI(APIMessage message) { } static List getPoliciesBySession(final SessionInventory session) { + if (session.getAccountUuid().equals(AccountConstant.INITIAL_SYSTEM_ADMIN_UUID) || session.isAccountSession()) { + return new ArrayList<>(internalPolices); + + } + return new SQLBatchWithReturn>() { @Override protected List scripts() { - List ret = new ArrayList<>(); - if (!session.getAccountUuid().equals(AccountConstant.INITIAL_SYSTEM_ADMIN_UUID) && !session.isAccountSession()) { - ret.addAll(getPoliciesForUser(session)); - } else { - ret.addAll(internalPolices); - } - - return ret; - } - - private List getPoliciesForUser(SessionInventory session) { // polices attached to the user List vos = sql("select p from PolicyVO p, UserPolicyRefVO r where r.policyUuid = p.uuid" + " and r.userUuid = :uuid", PolicyVO.class).param("uuid", session.getUserUuid()).list(); @@ -51,7 +44,7 @@ private List getPoliciesForUser(SessionInventory session) { static Map> collectDenyStatements(List polices) { Map> ret = new HashMap<>(); polices.forEach(p -> { - List ss = p.getStatements().stream().filter(s->s.getEffect() == StatementEffect.Deny).collect(Collectors.toList()); + List ss = p.getStatements().stream().filter(s->s.getEffect() == PolicyStatementEffect.Deny).collect(Collectors.toList()); if (!ss.isEmpty()) { ret.put(p, ss); } @@ -63,7 +56,7 @@ static Map> collectDenyStatements(List> collectAllowedStatements(List polices) { Map> ret = new HashMap<>(); polices.forEach(p -> { - List ss = p.getStatements().stream().filter(s->s.getEffect() == StatementEffect.Allow).collect(Collectors.toList()); + List ss = p.getStatements().stream().filter(s->s.getEffect() == PolicyStatementEffect.Allow).collect(Collectors.toList()); if (!ss.isEmpty()) { ret.put(p, ss); } diff --git a/identity/src/main/java/org/zstack/identity/rbac/SystemInternalPolicy.groovy b/identity/src/main/java/org/zstack/identity/rbac/SystemInternalPolicy.groovy index e47b71a19e0..932c85c56b3 100755 --- a/identity/src/main/java/org/zstack/identity/rbac/SystemInternalPolicy.groovy +++ b/identity/src/main/java/org/zstack/identity/rbac/SystemInternalPolicy.groovy @@ -3,7 +3,7 @@ package org.zstack.identity.rbac import org.zstack.header.identity.AccountConstant import org.zstack.header.identity.InternalPolicy import org.zstack.header.identity.PolicyInventory -import org.zstack.header.identity.StatementEffect +import org.zstack.header.identity.PolicyStatementEffect import org.zstack.header.identity.rbac.RBAC class SystemInternalPolicy implements InternalPolicy { @@ -15,7 +15,7 @@ class SystemInternalPolicy implements InternalPolicy { statement { name = "normal-account-allowed-apis" - effect = StatementEffect.Allow + effect = PolicyStatementEffect.Allow RBAC.permissions.each { info -> info.normalAPIs.each { action(it) } @@ -24,7 +24,7 @@ class SystemInternalPolicy implements InternalPolicy { statement { name = "give-admin-all-apis" - effect = StatementEffect.Allow + effect = PolicyStatementEffect.Allow action("**") diff --git a/image/pom.xml b/image/pom.xml index b0d4a58c582..917fbc74fac 100755 --- a/image/pom.xml +++ b/image/pom.xml @@ -3,7 +3,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. image diff --git a/image/src/main/java/org/zstack/image/AddImageLongJob.java b/image/src/main/java/org/zstack/image/AddImageLongJob.java index 424df4483c2..a47c51e015d 100644 --- a/image/src/main/java/org/zstack/image/AddImageLongJob.java +++ b/image/src/main/java/org/zstack/image/AddImageLongJob.java @@ -10,15 +10,18 @@ import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; -import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.image.*; -import org.zstack.header.longjob.*; +import org.zstack.header.longjob.LongJob; +import org.zstack.header.longjob.LongJobFor; +import org.zstack.header.longjob.LongJobVO; +import org.zstack.header.longjob.UseApiTimeout; import org.zstack.header.message.APIEvent; import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.backup.ImageHashAlgorithm; import org.zstack.longjob.LongJobGlobalConfig; import org.zstack.longjob.LongJobUtils; import org.zstack.utils.Utils; @@ -29,15 +32,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import static org.zstack.core.Platform.err; import static org.zstack.core.Platform.operr; import static org.zstack.longjob.LongJobUtils.*; -import static org.zstack.longjob.LongJobUtils.setJobResult; /** * Created by on camile 2018/2/2. */ +@UseApiTimeout(APIAddImageMsg.class) @LongJobFor(APIAddImageMsg.class) @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class AddImageLongJob implements LongJob { @@ -71,6 +73,7 @@ public void success(ImageInventory image) { event.setInventory(image); job = setJobResult(job.getUuid(), event); completion.success(event); + calculateImageHash(image); } } @@ -116,6 +119,17 @@ private void handleResult(ImageCanonicalEvents.ImageTrackData data) { } }); } + + void calculateImageHash(ImageInventory image) { + for (ImageBackupStorageRefInventory ref : image.getBackupStorageRefs()) { + CalculateImageHashMsg msg = new CalculateImageHashMsg(); + msg.setAlgorithm(ImageHashAlgorithm.MD5.toString()); + msg.setUuid(image.getUuid()); + msg.setBackupStorageUuid(ref.getBackupStorageUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, ImageConstant.SERVICE_ID, msg.getImageUuid()); + bus.send(msg); + } + } } @Override diff --git a/image/src/main/java/org/zstack/image/ImageBase.java b/image/src/main/java/org/zstack/image/ImageBase.java index 6804a357e4f..c4ca5fcb840 100755 --- a/image/src/main/java/org/zstack/image/ImageBase.java +++ b/image/src/main/java/org/zstack/image/ImageBase.java @@ -3,8 +3,7 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.compute.vm.IsoOperator; -import org.zstack.compute.vm.VmSystemTags; +import org.zstack.compute.vm.*; import org.zstack.core.asyncbatch.While; import org.zstack.core.cascade.CascadeConstant; import org.zstack.core.cascade.CascadeFacade; @@ -36,8 +35,7 @@ import org.zstack.header.image.ImageDeletionPolicyManager.ImageDeletionPolicy; import org.zstack.header.message.*; import org.zstack.header.storage.backup.*; -import org.zstack.header.vm.DetachIsoFromVmInstanceMsg; -import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.*; import org.zstack.header.volume.VolumeType; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; @@ -51,8 +49,7 @@ import java.util.concurrent.TimeUnit; import static org.zstack.core.Platform.*; -import static org.zstack.utils.CollectionDSL.e; -import static org.zstack.utils.CollectionDSL.map; +import static org.zstack.utils.CollectionDSL.*; /** * Created with IntelliJ IDEA. @@ -130,6 +127,8 @@ private void handleLocalMessage(Message msg) { handle((UpdateImageMsg) msg); } else if (msg instanceof GetImageEncryptedMsg) { handle((GetImageEncryptedMsg) msg); + } else if (msg instanceof CalculateImageHashMsg) { + handle((CalculateImageHashMsg) msg); } else { bus.dealWithUnknownMessage(msg); } @@ -154,6 +153,34 @@ public void fail(ErrorCode errorCode) { } + private void handle(CalculateImageHashMsg msg) { + CalculateImageHashReply reply = new CalculateImageHashReply(); + if (self.getMd5Sum() != null) { + bus.reply(msg, reply); + return; + } + + CalculateImageHashOnBackupStorageMsg cmsg = new CalculateImageHashOnBackupStorageMsg(); + cmsg.setImageUuid(msg.getUuid()); + cmsg.setBackupStorageUuid(msg.getBackupStorageUuid()); + cmsg.setAlgorithm(msg.getAlgorithm()); + bus.makeTargetServiceIdByResourceUuid(cmsg, BackupStorageConstant.SERVICE_ID, msg.getBackupStorageUuid()); + bus.send(cmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + reply.setError(r.getError()); + bus.reply(msg, reply); + return; + } + + CalculateImageHashOnBackupStorageReply breply = r.castReply(); + SQL.New(ImageVO.class).eq(ImageVO_.uuid, msg.getImageUuid()).set(ImageVO_.md5Sum, breply.getHashValue()).update(); + bus.reply(msg, reply); + } + }); + } + private void getImageMd5(GetImageEncryptedMsg msg, final ReturnValueCompletion completion) { GetImageEncryptedOnBackupStorageMsg backupStorageMsg = new GetImageEncryptedOnBackupStorageMsg(); String backupStorageUuid = Q.New(ImageBackupStorageRefVO.class) @@ -265,6 +292,7 @@ private void handle(final ExpungeImageMsg msg) { bus.reply(msg, reply); return; } + dbf.remove(ref); DeleteBitsOnBackupStorageMsg dmsg = new DeleteBitsOnBackupStorageMsg(); dmsg.setBackupStorageUuid(ref.getBackupStorageUuid()); @@ -284,7 +312,6 @@ public void run(MessageReply r) { } returnBackupStorageCapacity(ref.getBackupStorageUuid(), self.getActualSize()); - dbf.remove(ref); //TODO remove ref from metadata, this logic should after all refs deleted runAfterExpungeImageExtension(ref.getBackupStorageUuid()); @@ -423,9 +450,7 @@ public void done(ErrorCodeList errorCodeList) { } }); - List refs = new ArrayList<>(); - for (final ImageBackupStorageRefVO ref : toDelete) { chain.then(new NoRollbackFlow() { String __name__ = String.format("delete-image-%s-from-backup-storage-%s", self.getUuid(), ref.getBackupStorageUuid()); @@ -433,6 +458,8 @@ public void done(ErrorCodeList errorCodeList) { @Override public void run(final FlowTrigger trigger, Map data) { if (deletionPolicy == ImageDeletionPolicy.Direct) { + dbf.remove(ref); + DeleteBitsOnBackupStorageMsg dmsg = new DeleteBitsOnBackupStorageMsg(); dmsg.setBackupStorageUuid(ref.getBackupStorageUuid()); dmsg.setInstallPath(ref.getInstallPath()); @@ -441,16 +468,22 @@ public void run(final FlowTrigger trigger, Map data) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { - //TODO logger.warn(String.format("failed to delete image[uuid:%s, name:%s] from backup storage[uuid:%s] because %s," + " need to garbage collect it", self.getUuid(), self.getName(), reply.getError(), ref.getBackupStorageUuid())); - } else { - returnBackupStorageCapacity(ref.getBackupStorageUuid(), self.getActualSize()); - dbf.remove(ref); - // now delete ref in metadata - runAfterExpungeImageExtension(ref.getBackupStorageUuid()); + + BackupStorageDeleteBitGC gc = new BackupStorageDeleteBitGC(); + gc.NAME = String.format("gc-delete-bits-%s-on-backup-storage-%s", msg.getImageUuid(), ref.getBackupStorageUuid()); + gc.backupStorageUuid = ref.getBackupStorageUuid(); + gc.imageUuid = msg.getImageUuid(); + gc.installPath = ref.getInstallPath(); + gc.deduplicateSubmit(ImageGlobalConfig.DELETION_GARBAGE_COLLECTION_INTERVAL.value(Long.class), + TimeUnit.SECONDS); } + + returnBackupStorageCapacity(ref.getBackupStorageUuid(), self.getActualSize()); + // now delete ref in metadata + runAfterExpungeImageExtension(ref.getBackupStorageUuid()); trigger.next(); } }); @@ -462,7 +495,6 @@ public void run(MessageReply reply) { } else { ref.setStatus(ImageStatus.Deleted); refs.add(ref); - trigger.next(); } } @@ -549,10 +581,8 @@ public void done(ErrorCodeList errorCodeList) { bus.reply(msg, reply); } }); - } - private void handle(OverlayMessage msg) { thdf.chainSubmit(new ChainTask(msg) { @Override @@ -657,6 +687,8 @@ private void handleApiMessage(APIMessage msg) { handle((APISyncImageSizeMsg) msg); } else if (msg instanceof APISetImageBootModeMsg) { handle((APISetImageBootModeMsg) msg); + } else if (msg instanceof APICalculateImageHashMsg) { + handle((APICalculateImageHashMsg) msg); } else { bus.dealWithUnknownMessage(msg); } @@ -673,6 +705,25 @@ private void handle(APISetImageBootModeMsg msg) { bus.publish(evt); } + private void handle(final APICalculateImageHashMsg msg) { + final APICalculateImageHashEvent evt = new APICalculateImageHashEvent(msg.getId()); + CalculateImageHashMsg cmsg = new CalculateImageHashMsg(msg); + bus.makeTargetServiceIdByResourceUuid(cmsg, ImageConstant.SERVICE_ID, cmsg.getImageUuid()); + bus.send(cmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + bus.publish(evt); + return; + } + + evt.setInventory(ImageInventory.valueOf(dbf.reload(self))); + bus.publish(evt); + } + }); + } + private void handle(APISyncImageSizeMsg msg) { final APISyncImageSizeEvent evt = new APISyncImageSizeEvent(msg.getId()); syncImageSize(null, new ReturnValueCompletion(msg) { @@ -764,7 +815,7 @@ public String call(ImageBackupStorageRefVO arg) { if (bsUuids.isEmpty()) { throw new OperationFailureException(operr("the image[uuid:%s, name:%s] is not deleted on any backup storage", - self.getUuid(), self.getName())); + self.getUuid(), self.getName())); } } else { for (final String bsUuid : msg.getBackupStorageUuids()) { @@ -780,12 +831,12 @@ public ImageBackupStorageRefVO call(ImageBackupStorageRefVO arg) { if (ref == null) { throw new OperationFailureException(argerr("the image[uuid:%s, name:%s] is not on the backup storage[uuid:%s]", - self.getUuid(), self.getName(), bsUuid)); + self.getUuid(), self.getName(), bsUuid)); } if (ref.getStatus() != ImageStatus.Deleted) { throw new OperationFailureException(argerr("the image[uuid:%s, name:%s] is not deleted on the backup storage[uuid:%s]", - self.getUuid(), self.getName(), bsUuid)); + self.getUuid(), self.getName(), bsUuid)); } bsUuids.add(bsUuid); diff --git a/image/src/main/java/org/zstack/image/ImageDefaultBehavior.java b/image/src/main/java/org/zstack/image/ImageDefaultBehavior.java new file mode 100644 index 00000000000..8c4682f6a20 --- /dev/null +++ b/image/src/main/java/org/zstack/image/ImageDefaultBehavior.java @@ -0,0 +1,25 @@ +package org.zstack.image; + +import org.zstack.header.image.ImageBootMode; +import org.zstack.header.image.ImagePlatform; + +public class ImageDefaultBehavior { + static String defaultPlatform = ImagePlatform.Linux.toString(); + static String defaultBootMode = ImageBootMode.Legacy.toString(); + + public static String getDefaultPlatform() { + return defaultPlatform; + } + + public static void setDefaultPlatform(String defaultPlatform) { + ImageDefaultBehavior.defaultPlatform = defaultPlatform; + } + + public static String getDefaultBootMode() { + return defaultBootMode; + } + + public static void setDefaultBootMode(String defaultBootMode) { + ImageDefaultBehavior.defaultBootMode = defaultBootMode; + } +} diff --git a/image/src/main/java/org/zstack/image/ImageGlobalConfig.java b/image/src/main/java/org/zstack/image/ImageGlobalConfig.java index 09be492c21e..eb5ec1ecc0f 100755 --- a/image/src/main/java/org/zstack/image/ImageGlobalConfig.java +++ b/image/src/main/java/org/zstack/image/ImageGlobalConfig.java @@ -32,4 +32,9 @@ public class ImageGlobalConfig { @GlobalConfigValidation() public static GlobalConfig DOWNLOAD_LOCALPATH_CUSTOMFILTER = new GlobalConfig(CATEGORY, "download.localPath.customFilter"); + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig UPLOAD_FAILURE_TOLERANCE_COUNT = new GlobalConfig(CATEGORY, "upload.failure.tolerance.count"); + + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig UPLOAD_MAX_IDLE_IN_SECONDS = new GlobalConfig(CATEGORY, "upload.max.idle.duration.in.seconds"); } diff --git a/image/src/main/java/org/zstack/image/ImageManagerImpl.java b/image/src/main/java/org/zstack/image/ImageManagerImpl.java index 47d7057e2c6..0f1f87975d0 100755 --- a/image/src/main/java/org/zstack/image/ImageManagerImpl.java +++ b/image/src/main/java/org/zstack/image/ImageManagerImpl.java @@ -1,4 +1,5 @@ package org.zstack.image; + import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -10,7 +11,10 @@ import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.*; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.config.*; +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigException; +import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; +import org.zstack.core.config.GlobalConfigValidatorExtensionPoint; import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.defer.Defer; @@ -20,6 +24,7 @@ import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.AbstractService; import org.zstack.header.allocator.HostAllocatorFilterExtensionPoint; import org.zstack.header.allocator.HostAllocatorSpec; @@ -30,16 +35,20 @@ import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostVO; import org.zstack.header.identity.*; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.image.*; import org.zstack.header.image.ImageConstant.ImageMediaType; import org.zstack.header.image.ImageDeletionPolicyManager.ImageDeletionPolicy; -import org.zstack.header.longjob.*; +import org.zstack.header.longjob.LongJobInventory; +import org.zstack.header.longjob.LongJobState; import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; import org.zstack.header.message.*; +import org.zstack.header.network.l3.IpRangeVO; import org.zstack.header.rest.RESTFacade; import org.zstack.header.storage.backup.*; import org.zstack.header.storage.primary.CancelJobOnPrimaryStorageMsg; @@ -49,37 +58,42 @@ import org.zstack.header.storage.snapshot.*; import org.zstack.header.tag.SystemTagCreateMessageValidator; import org.zstack.header.tag.SystemTagValidator; -import org.zstack.header.vm.CreateTemplateFromVmRootVolumeMsg; -import org.zstack.header.vm.CreateTemplateFromVmRootVolumeReply; -import org.zstack.header.vm.VmInstanceConstant; -import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.*; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ResourceVO_; import org.zstack.header.volume.*; import org.zstack.identity.AccountManager; -import org.zstack.identity.QuotaUtil; import org.zstack.tag.TagManager; import org.zstack.utils.*; import org.zstack.utils.function.Function; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; import org.zstack.zql.ZQL; import javax.persistence.Tuple; import javax.persistence.TypedQuery; +import javax.xml.ws.ResponseWrapper; import java.net.URI; import java.net.URISyntaxException; import java.sql.Timestamp; +import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.stream.Collectors; +import static java.util.Arrays.asList; import static org.zstack.core.Platform.*; -import static org.zstack.core.progress.ProgressReportService.getTaskStage; -import static org.zstack.core.progress.ProgressReportService.reportProgress; +import static org.zstack.core.progress.ProgressReportService.*; +import static org.zstack.core.progress.ProgressReportService.markTaskStage; import static org.zstack.longjob.LongJobUtils.buildErrIfCanceled; import static org.zstack.longjob.LongJobUtils.noncancelableErr; import static org.zstack.utils.CollectionDSL.list; @@ -212,36 +226,91 @@ private void handle(CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg msg) imgvo.setUrl(String.format("volumeSnapshot://%s", msg.getSnapshotUuid())); }); - createSysTag(msg, vo); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("create-temporary-volume-template-from-volume-snapshot-%s", msg.getSnapshotUuid())); + chain.then(new Flow() { + final String __name__ = "create-image-in-database"; - CreateImageCacheFromVolumeSnapshotMsg cmsg = new CreateImageCacheFromVolumeSnapshotMsg(); - cmsg.setSnapshotUuid(msg.getSnapshotUuid()); - cmsg.setImageUuid(vo.getUuid()); - cmsg.setVolumeUuid(volumeUuid); - cmsg.setTreeUuid(treeUuid); - String resourceUuid = volumeUuid != null ? volumeUuid : treeUuid; - bus.makeTargetServiceIdByResourceUuid(cmsg, VolumeSnapshotConstant.SERVICE_ID, resourceUuid); - bus.send(cmsg, new CloudBusCallBack(msg) { @Override - public void run(MessageReply r) { - if (!r.isSuccess()) { - reply.setError(r.getError()); - bus.reply(msg, reply); - return; - } + public void run(FlowTrigger trigger, Map data) { + // created before + createSysTag(msg, vo); + trigger.next(); + } - CreateImageCacheFromVolumeSnapshotReply cr = r.castReply(); + @Override + public void rollback(FlowRollback trigger, Map data) { + dbf.remove(vo); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + final String __name__ = "create-image-cache-from-volume-snapshot"; - vo.setActualSize(cr.getActualSize()); - vo.setStatus(ImageStatus.Ready); - dbf.update(vo); - reply.setInventory(ImageInventory.valueOf(vo)); - reply.setLocateHostUuid(cr.getLocationHostUuid()); - reply.setLocatePsUuid(volumePsUuid); + @Override + public void run(FlowTrigger trigger, Map data) { + CreateImageCacheFromVolumeSnapshotMsg cmsg = new CreateImageCacheFromVolumeSnapshotMsg(); + cmsg.setSnapshotUuid(msg.getSnapshotUuid()); + cmsg.setImageUuid(vo.getUuid()); + cmsg.setVolumeUuid(volumeUuid); + cmsg.setTreeUuid(treeUuid); + cmsg.setSystemTags(msg.getSystemTags()); + String resourceUuid = volumeUuid != null ? volumeUuid : treeUuid; + bus.makeTargetServiceIdByResourceUuid(cmsg, VolumeSnapshotConstant.SERVICE_ID, resourceUuid); + bus.send(cmsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + trigger.fail(r.getError()); + return; + } + + CreateImageCacheFromVolumeSnapshotReply cr = r.castReply(); + + vo.setActualSize(cr.getActualSize()); + vo.setStatus(ImageStatus.Ready); + if (cr.getImageUrl() != null) { + vo.setUrl(cr.getImageUrl()); + } + dbf.update(vo); + reply.setInventory(ImageInventory.valueOf(vo)); + reply.setLocateHostUuid(cr.getLocationHostUuid()); + reply.setLocatePsUuid(volumePsUuid); + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + final String __name__ = "sync-volume-system-tag"; + + @Override + public void run(FlowTrigger trigger, Map data) { + SyncSystemTagFromVolumeMsg smsg = new SyncSystemTagFromVolumeMsg(); + smsg.setImageUuid(vo.getUuid()); + smsg.setVolumeUuid(volumeUuid); + bus.makeLocalServiceId(smsg, ImageConstant.SERVICE_ID); + bus.send(smsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("sync image[uuid:%s]system tag fail", volumeUuid)); + } + trigger.next(); + } + }); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + reply.setError(errCode); bus.reply(msg, reply); } - }); + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + } + }).start(); } private void handleLocalMessage(Message msg) { @@ -251,12 +320,12 @@ private void handleLocalMessage(Message msg) { handle((CreateRootVolumeTemplateFromRootVolumeMsg) msg); } else if (msg instanceof CancelCreateRootVolumeTemplateFromRootVolumeMsg) { handle((CancelCreateRootVolumeTemplateFromRootVolumeMsg) msg); + } else if (msg instanceof CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg) { + handle((CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg) msg); } else if (msg instanceof CreateRootVolumeTemplateFromVolumeSnapshotMsg) { handle((CreateRootVolumeTemplateFromVolumeSnapshotMsg) msg); } else if (msg instanceof CreateDataVolumeTemplateFromVolumeMsg){ handle ((CreateDataVolumeTemplateFromVolumeMsg) msg); - } else if (msg instanceof CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg) { - handle((CreateTemporaryRootVolumeTemplateFromVolumeSnapshotMsg) msg); } else if (msg instanceof CreateTemporaryRootVolumeTemplateFromVolumeMsg) { handle((CreateTemporaryRootVolumeTemplateFromVolumeMsg) msg); } else if (msg instanceof CreateDataVolumeTemplateFromVolumeSnapshotMsg) { @@ -268,6 +337,79 @@ private void handleLocalMessage(Message msg) { } } + private void handle(final APIExpungeImageGroupMsg msg) { + final APIExpungeImageGroupEvent evt = new APIExpungeImageGroupEvent(msg.getId()); + List imageUuids = Q.New(ImageGroupRefVO.class) + .eq(ImageGroupRefVO_.imageGroupUuid, msg.getUuid()) + .select(ImageGroupRefVO_.imageUuid) + .listValues(); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("delete-image-group-%s", msg.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = String.format("delete-images-from-image-group-%s", msg.getUuid()); + + @Override + public boolean skip(Map data) { + return CollectionUtils.isEmpty(imageUuids); + } + + @Override + public void run(final FlowTrigger trigger, Map data) { + new While<>(imageUuids).all((uuid, compl) -> { + ImageDeletionMsg msg = new ImageDeletionMsg(); + msg.setImageUuid(uuid); + msg.setDeletionPolicy(ImageDeletionPolicyManager.ImageDeletionPolicy.Direct.toString()); + msg.setForceDelete(true); + bus.makeTargetServiceIdByResourceUuid(msg, ImageConstant.SERVICE_ID, uuid); + bus.send(msg, new CloudBusCallBack(compl) { + @Override + public void run(MessageReply reply) { + compl.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "database-clean"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + new SQLBatch() { + @Override + protected void scripts() { + if (!CollectionUtils.isEmpty(imageUuids)) { + sql(ImageGroupRefVO.class) + .eq(ImageGroupRefVO_.imageGroupUuid, msg.getUuid()) + .hardDelete(); + } + + sql(ImageGroupVO.class) + .eq(ImageGroupVO_.uuid, msg.getUuid()) + .hardDelete(); + } + }.execute(); + trigger.next(); + } + }); + chain.done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.publish(evt); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + evt.setError(errCode); + bus.publish(evt); + } + }).start(); + } + private void handle(CreateDataVolumeTemplateFromVolumeMsg msg) { CreateDataVolumeTemplateFromVolumeReply reply = new CreateDataVolumeTemplateFromVolumeReply(); createDataVolumeTemplateFromVolume(msg, msg.getVolumeUuid(), new ReturnValueCompletion(msg) { @@ -434,6 +576,10 @@ public void fail(ErrorCode errorCode) { private void handleApiMessage(Message msg) { if (msg instanceof APIAddImageMsg) { handle((APIAddImageMsg) msg); + } else if (msg instanceof APIExpungeImageGroupMsg) { + handle((APIExpungeImageGroupMsg) msg); + } else if (msg instanceof APICloneImageMsg) { + handle((APICloneImageMsg) msg); } else if (msg instanceof APIGetUploadImageJobDetailsMsg) { handle((APIGetUploadImageJobDetailsMsg) msg); } else if (msg instanceof APICreateRootVolumeTemplateFromRootVolumeMsg) { @@ -444,11 +590,510 @@ private void handleApiMessage(Message msg) { handle((APICreateDataVolumeTemplateFromVolumeMsg) msg); } else if (msg instanceof APICreateDataVolumeTemplateFromVolumeSnapshotMsg) { handle((APICreateDataVolumeTemplateFromVolumeSnapshotMsg) msg); + } else if (msg instanceof APICreateImageGroupFromVmInstanceMsg){ + handle((APICreateImageGroupFromVmInstanceMsg) msg); + } else if (msg instanceof APICreateImageGroupFromImageMsg){ + handle((APICreateImageGroupFromImageMsg) msg); + } else if (msg instanceof APICreateImageGroupFromSnapshotMsg){ + handle((APICreateImageGroupFromSnapshotMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } + private void handle(APICreateImageGroupFromSnapshotMsg msg) { + APICreateImageGroupFromSnapshotEvent evt = new APICreateImageGroupFromSnapshotEvent(msg.getId()); + createImageGroupFromSnapshot(msg, new ReturnValueCompletion(evt) { + @Override + public void success(ImageGroupInventory imageGroup) { + evt.setInventory(imageGroup); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); + } + + private void handle(APICreateImageGroupFromVmInstanceMsg msg) { + APICreateImageGroupFromVmInstanceEvent evt = new APICreateImageGroupFromVmInstanceEvent(msg.getId()); + createImageGroupFromVmInstance(msg, msg.getVmInstanceUuid(), new ReturnValueCompletion(evt) { + @Override + public void success(ImageGroupInventory imageGroup) { + evt.setInventory(imageGroup); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); + } + + private void handle(APICreateImageGroupFromImageMsg msg) { + APICreateImageGroupFromImageEvent evt = new APICreateImageGroupFromImageEvent(msg.getId()); + + ImageGroupVO gvo = new SQLBatchWithReturn() { + @Override + protected ImageGroupVO scripts() { + List dataVolumeTemplateUuids = msg.getDataVolumeTemplateUuids(); + List volumesUuids = new ArrayList<>(); + volumesUuids.add(msg.getRootVolumeTemplateUuid()); + String groupUuid = Platform.getUuid(); + ImageGroupVO vo = new ImageGroupVO(); + vo.setUuid(groupUuid); + vo.setName(msg.getName()); + vo.setStatus(ImageStatus.Ready); + vo.setDescription(msg.getDescription()); + vo.setImageCount(1); + if (!CollectionUtils.isEmpty(dataVolumeTemplateUuids)) { + vo.setImageCount(1 + dataVolumeTemplateUuids.size()); + volumesUuids.addAll(msg.getDataVolumeTemplateUuids()); + } + vo = persist(vo); + + new HashSet(volumesUuids).forEach( + uuid -> { + ImageVO image = q(ImageVO.class) + .eq(ImageVO_.uuid, uuid) + .find(); + + ImageGroupRefVO refVO = new ImageGroupRefVO(); + refVO.setImageGroupUuid(groupUuid); + refVO.setImageUuid(uuid); + persist(refVO); + } + ); + return vo; + } + }.execute(); + evt.setInventory(ImageGroupInventory.valueOf(gvo)); + bus.publish(evt); + } + + private void createImageGroupFromSnapshot(APICreateImageGroupFromSnapshotMsg msg, ReturnValueCompletion completion) { + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("create-image-group-from-snapshot-%s", msg.getRootVolumeSnapshotUuid())); + chain.then(new ShareFlow() { + ImageGroupVO imageGroupVO = new ImageGroupVO(); + String rootVolumeSnapshotUuid = msg.getRootVolumeSnapshotUuid(); + List dataVolumeSnapshotUuids = msg.getDataVolumeSnapshotUuids(); + List newImageUuids = new ArrayList(); + + @Override + public void setup() { + flow(new Flow() { + String __name__ = "prepare-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + imageGroupVO = new SQLBatchWithReturn() { + @Override + protected ImageGroupVO scripts() { + String groupUuid = StringUtils.isEmpty(msg.getResourceUuid()) ? Platform.getUuid() : msg.getResourceUuid(); + ImageGroupVO vo = new ImageGroupVO(); + vo.setUuid(groupUuid); + vo.setName(msg.getName()); + vo.setStatus(ImageStatus.Creating); + vo.setDescription(msg.getDescription()); + vo.setImageCount(1); + if (!CollectionUtils.isEmpty(dataVolumeSnapshotUuids)) { + vo.setImageCount(1 + dataVolumeSnapshotUuids.size()); + } + vo = persist(vo); + return vo; + } + }.execute(); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + dbf.removeByPrimaryKey(imageGroupVO.getUuid(), ImageGroupVO.class); + trigger.rollback(); + } + }); + flow(new Flow() { + String __name__ = "create-root-template-from-snapshot"; + + @Override + public void run(FlowTrigger trigger, Map data) { + CreateRootVolumeTemplateFromVolumeSnapshotMsg cmsg = new CreateRootVolumeTemplateFromVolumeSnapshotMsg(); + cmsg.setName("create-from-snap-" + rootVolumeSnapshotUuid); + cmsg.setSnapshotUuid(rootVolumeSnapshotUuid); + cmsg.setSession(msg.getSession()); + bus.makeLocalServiceId(cmsg, ImageConstant.SERVICE_ID); + bus.send(cmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + trigger.fail(r.getError()); + return; + } + + CreateRootVolumeTemplateFromVolumeSnapshotReply reply = r.castReply(); + ImageInventory imageInv = ((CreateRootVolumeTemplateFromVolumeSnapshotReply) reply).getInventory(); + newImageUuids.add(imageInv.getUuid()); + trigger.next(); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (CollectionUtils.isEmpty(newImageUuids)) { + trigger.rollback(); + return; + } + for (String uuid : new ArrayList<>(newImageUuids)) { + ImageDeletionMsg delMsg = new ImageDeletionMsg(); + delMsg.setImageUuid(uuid); + delMsg.setDeletionPolicy(ImageDeletionPolicyManager.ImageDeletionPolicy.Direct.toString()); + delMsg.setForceDelete(true); + bus.makeTargetServiceIdByResourceUuid(delMsg, ImageConstant.SERVICE_ID, uuid); + bus.send(delMsg); + newImageUuids.remove(uuid); + } + trigger.rollback(); + } + }); + + flow(new Flow() { + String __name__ = "create-data-templates-from-snapshots"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (CollectionUtils.isEmpty(dataVolumeSnapshotUuids)) { + trigger.next(); + return; + } + + List errors = new ArrayList<>(); + new While<>(dataVolumeSnapshotUuids).each((iUuid, compl) -> { + CreateDataVolumeTemplateFromVolumeSnapshotMsg csmsg = new CreateDataVolumeTemplateFromVolumeSnapshotMsg(); + csmsg.setName(String.format("create-from-snapshot-%s", iUuid)); + csmsg.setSnapshotUuid(iUuid); + csmsg.setSession(msg.getSession()); + bus.makeLocalServiceId(csmsg, ImageConstant.SERVICE_ID); + bus.send(csmsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + errors.add(reply.getError()); + compl.allDone(); + } + + ImageInventory imageInv = ((CreateDataVolumeTemplateFromVolumeSnapshotReply) reply).getInventory(); + newImageUuids.add(imageInv.getUuid()); + compl.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errors.isEmpty()) { + trigger.fail(errors.get(0)); + return; + } + trigger.next(); + } + }); + + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (CollectionUtils.isEmpty(newImageUuids)) { + trigger.rollback(); + return; + } + for (String uuid : new ArrayList<>(newImageUuids)) { + ImageDeletionMsg delMsg = new ImageDeletionMsg(); + delMsg.setImageUuid(uuid); + delMsg.setDeletionPolicy(ImageDeletionPolicyManager.ImageDeletionPolicy.Direct.toString()); + delMsg.setForceDelete(true); + bus.makeTargetServiceIdByResourceUuid(delMsg, ImageConstant.SERVICE_ID, uuid); + bus.send(delMsg); + newImageUuids.remove(uuid); + } + trigger.rollback(); + } + }); + + flow(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + String __name__ = "create-image-group-in-database"; + + imageGroupVO = new SQLBatchWithReturn() { + @Override + protected ImageGroupVO scripts() { + ImageGroupVO vo = findByUuid(imageGroupVO.getUuid(), ImageGroupVO.class); + vo.setStatus(ImageStatus.Ready); + vo = merge(vo); + + new HashSet(newImageUuids).forEach( + resourceUuid -> { + ImageGroupRefVO refVO = new ImageGroupRefVO(); + refVO.setImageGroupUuid(imageGroupVO.getUuid()); + refVO.setImageUuid(resourceUuid); + persist(refVO); + } + ); + return vo; + } + }.execute(); + trigger.next(); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + ImageGroupInventory inv = ImageGroupInventory.valueOf(imageGroupVO); + completion.success(inv); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + + private void createImageGroupFromVmInstance(APICreateImageGroupFromVmInstanceMsg msg, String vmUuid, ReturnValueCompletion completion) { + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("create-image-group-from-vm-instance-%s", vmUuid)); + chain.then(new ShareFlow() { + ImageGroupVO imageGroupVO = new ImageGroupVO(); + String rootVolumeUuid; + List dataVolumeUuids = new ArrayList(); + List newVolumeUuids = new ArrayList(); + + @Override + public void setup() { + flow(new Flow() { + String __name__ = "prepare-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List volumes = Q.New(VolumeVO.class).eq(VolumeVO_.vmInstanceUuid, vmUuid).list(); + if (CollectionUtils.isEmpty(volumes)) { + trigger.fail(operr("vm instance[uuid:%s] has no volume", vmUuid)); + return; + } + + for (VolumeVO vol : volumes) { + if (vol.getType() == VolumeType.Root) { + rootVolumeUuid = vol.getUuid(); + } else { + dataVolumeUuids.add(vol.getUuid()); + } + } + + if (rootVolumeUuid == null) { + trigger.fail(operr("vm instance[uuid:%s] has no root volume", vmUuid)); + return; + } + + imageGroupVO = new SQLBatchWithReturn() { + @Override + protected ImageGroupVO scripts() { + String groupUuid = StringUtils.isEmpty(msg.getResourceUuid()) ? Platform.getUuid() : msg.getResourceUuid(); + ImageGroupVO vo = new ImageGroupVO(); + vo.setUuid(groupUuid); + vo.setName(msg.getName()); + vo.setStatus(ImageStatus.Creating); + vo.setDescription(msg.getDescription()); + vo.setImageCount(1); + if (!CollectionUtils.isEmpty(dataVolumeUuids)) { + vo.setImageCount(1 + dataVolumeUuids.size()); + } + vo = persist(vo); + return vo; + } + }.execute(); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + dbf.removeByPrimaryKey(imageGroupVO.getUuid(), ImageGroupVO.class); + trigger.rollback(); + } + }); + + flow(new Flow() { + String __name__ = "create-root-template-from-volume"; + + @Override + public void run(FlowTrigger trigger, Map data) { + VmInstanceVO vmVO = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, vmUuid).find(); + CreateRootVolumeTemplateFromRootVolumeMsg crtMsg = new CreateRootVolumeTemplateFromRootVolumeMsg(); + crtMsg.setRootVolumeUuid(rootVolumeUuid); + crtMsg.setName(String.format("create-from-root-volume-%s", rootVolumeUuid)); + crtMsg.setArchitecture(vmVO.getArchitecture()); + crtMsg.setPlatform(vmVO.getPlatform()); + crtMsg.setGuestOsType(vmVO.getGuestOsType()); + crtMsg.setDescription(msg.getDescription()); + crtMsg.setSession(msg.getSession()); + bus.makeLocalServiceId(crtMsg, ImageConstant.SERVICE_ID); + bus.send(crtMsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + + ImageInventory imageInv = ((CreateRootVolumeTemplateFromRootVolumeReply) reply).getInventory(); + newVolumeUuids.add(imageInv.getUuid()); + trigger.next(); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (CollectionUtils.isEmpty(newVolumeUuids)) { + trigger.rollback(); + return; + } + for (String uuid : newVolumeUuids) { + ImageDeletionMsg delMsg = new ImageDeletionMsg(); + delMsg.setImageUuid(uuid); + delMsg.setDeletionPolicy(ImageDeletionPolicyManager.ImageDeletionPolicy.Direct.toString()); + delMsg.setForceDelete(true); + bus.makeTargetServiceIdByResourceUuid(delMsg, ImageConstant.SERVICE_ID, uuid); + bus.send(delMsg); + newVolumeUuids.remove(uuid); + } + trigger.rollback(); + } + }); + + flow(new Flow() { + String __name__ = "create-data-templates-from-volumes"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (CollectionUtils.isEmpty(dataVolumeUuids)) { + trigger.next(); + return; + } + + List errors = new ArrayList<>(); + new While<>(dataVolumeUuids).each((volUuid, compl) -> { + CreateDataVolumeTemplateFromVolumeMsg cdtMsg = new CreateDataVolumeTemplateFromVolumeMsg(); + cdtMsg.setVolumeUuid(volUuid); + cdtMsg.setName(String.format("create-from-data-volume-%s", volUuid)); + cdtMsg.setDescription(msg.getDescription()); + cdtMsg.setSession(msg.getSession()); + bus.makeLocalServiceId(cdtMsg, ImageConstant.SERVICE_ID); + bus.send(cdtMsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + errors.add(reply.getError()); + compl.allDone(); + } + + ImageInventory imageInv = ((CreateDataVolumeTemplateFromVolumeReply) reply).getInventory(); + newVolumeUuids.add(imageInv.getUuid()); + compl.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errors.isEmpty()) { + trigger.fail(errors.get(0)); + return; + } + trigger.next(); + } + }); + + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (CollectionUtils.isEmpty(newVolumeUuids)) { + trigger.rollback(); + return; + } + for (String uuid : newVolumeUuids) { + ImageDeletionMsg delMsg = new ImageDeletionMsg(); + delMsg.setImageUuid(uuid); + delMsg.setDeletionPolicy(ImageDeletionPolicyManager.ImageDeletionPolicy.Direct.toString()); + delMsg.setForceDelete(true); + bus.makeTargetServiceIdByResourceUuid(delMsg, ImageConstant.SERVICE_ID, uuid); + bus.send(delMsg); + newVolumeUuids.remove(uuid); + } + trigger.rollback(); + } + }); + + flow(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + String __name__ = "create-image-group-ref-in-database"; + + imageGroupVO = new SQLBatchWithReturn() { + @Override + protected ImageGroupVO scripts() { + ImageGroupVO vo = findByUuid(imageGroupVO.getUuid(), ImageGroupVO.class); + vo.setStatus(ImageStatus.Ready); + vo = merge(vo); + + new HashSet(newVolumeUuids).forEach( + resourceUuid -> { + ImageVO image = q(ImageVO.class) + .eq(ImageVO_.uuid, resourceUuid) + .find(); + + ImageGroupRefVO refVO = new ImageGroupRefVO(); + refVO.setImageGroupUuid(imageGroupVO.getUuid()); + refVO.setImageUuid(resourceUuid); + persist(refVO); + } + ); + return vo; + } + }.execute(); + trigger.next(); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + ImageGroupInventory inv = ImageGroupInventory.valueOf(imageGroupVO); + completion.success(inv); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + private void handle(final APICreateDataVolumeTemplateFromVolumeMsg msg) { APICreateDataVolumeTemplateFromVolumeEvent evt = new APICreateDataVolumeTemplateFromVolumeEvent(msg.getId()); createDataVolumeTemplateFromVolume(msg, msg.getVolumeUuid(), new ReturnValueCompletion(evt) { @@ -746,6 +1391,87 @@ private void handle(final APIAddImageMsg msg) { handleAddImageMsg(data, evt); } + private void handle(final APICloneImageMsg msg) { + APICloneImageEvent evt = new APICloneImageEvent(msg.getId()); + Set copiedRefs; + ImageVO sourceImage = dbf.findByUuid(msg.getImageUuid(), ImageVO.class); + if (sourceImage == null) { + throw new OperationFailureException(operr("source image [%s] not existed", msg.getImageUuid())); + } + if (sourceImage.getStatus() != ImageStatus.Ready) { + throw new OperationFailureException(operr("cannot clone image, because image [%s] status is not ready", msg.getImageUuid())); + } + + ImageVO vo = new ImageVO(); + if (msg.getResourceUuid() != null) { + dbf.eoCleanup(ImageVO.class, msg.getResourceUuid()); + vo.setUuid(msg.getResourceUuid()); + } else { + vo.setUuid(Platform.getUuid()); + } + vo.setName(String.format("Clone-from-%s", sourceImage.getName())); + vo.setDescription(sourceImage.getDescription()); + vo.setStatus(ImageStatus.Ready); + vo.setState(sourceImage.getState()); + vo.setSize(sourceImage.getSize()); + vo.setActualSize(sourceImage.getActualSize()); + vo.setMd5Sum(sourceImage.getMd5Sum()); + vo.setPlatform(sourceImage.getPlatform()); + vo.setType(sourceImage.getType()); + vo.setFormat(sourceImage.getFormat()); + vo.setUrl(sourceImage.getUrl()); + vo.setSystem(sourceImage.isSystem()); + vo.setMediaType(sourceImage.getMediaType()); + vo.setCreateDate(sourceImage.getCreateDate()); + vo.setLastOpDate(sourceImage.getLastOpDate()); + vo.setGuestOsType(sourceImage.getGuestOsType()); + vo.setArchitecture(sourceImage.getArchitecture()); + vo.setVirtio(sourceImage.getVirtio()); + vo.setAccountUuid(sourceImage.getAccountUuid()); + copiedRefs = sourceImage.getBackupStorageRefs(); + + ImageFactory factory = getImageFacotry(ImageType.valueOf(sourceImage.getType())); + final ImageVO ivo = new SQLBatchWithReturn() { + @Override + protected ImageVO scripts() { + Set rvos = new HashSet<>(); + vo.setAccountUuid(sourceImage.getAccountUuid()); + tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), ImageVO.class.getSimpleName()); + ImageVO ivo = factory.createImage(vo); + for (ImageBackupStorageRefVO ref : copiedRefs) { + ImageBackupStorageRefVO rvo = copyImageBackupStorageRefVO(ref); + rvo.setImageUuid(vo.getUuid()); + + persist(rvo); + rvos.add(rvo); + } + + ivo.setBackupStorageRefs(rvos); + ivo = merge(ivo); + return ivo; + } + }.execute(); + + evt.setInventory(ImageInventory.valueOf(ivo)); + bus.publish(evt); + } + + private static ImageBackupStorageRefVO copyImageBackupStorageRefVO(ImageBackupStorageRefVO original) { + if (original == null) { + return null; + } + + ImageBackupStorageRefVO copy = new ImageBackupStorageRefVO(); + copy.setBackupStorageUuid(original.getBackupStorageUuid()); + copy.setStatus(original.getStatus()); + copy.setInstallPath(original.getInstallPath()); + Timestamp now = Timestamp.valueOf(LocalDateTime.now()); + copy.setCreateDate(now); + copy.setLastOpDate(now); + + return copy; + } + @Override public String getId() { return bus.makeLocalServiceId(ImageConstant.SERVICE_ID); @@ -843,12 +1569,6 @@ public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { startExpungeTask(); } }); - ImageGlobalConfig.EXPUNGE_PERIOD.installUpdateExtension(new GlobalConfigUpdateExtensionPoint() { - @Override - public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { - startExpungeTask(); - } - }); } private void installGlobalConfigValidator() { @@ -886,7 +1606,7 @@ public void validateGlobalConfig(String category, String name, String oldValue, }; } - private void startExpungeTask() { + private synchronized void startExpungeTask() { if (expungeTask != null) { expungeTask.cancel(true); } @@ -1007,241 +1727,39 @@ public void managementNodeReady() { @Override public List reportQuota() { - Quota.QuotaOperator checker = new Quota.QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APIAddImageMsg) { - check((APIAddImageMsg) msg, pairs); - } else if (msg instanceof APIRecoverImageMsg) { - check((APIRecoverImageMsg) msg, pairs); - } else if (msg instanceof APIChangeResourceOwnerMsg) { - check((APIChangeResourceOwnerMsg) msg, pairs); - } else if (msg instanceof APICreateRootVolumeTemplateFromRootVolumeMsg) { - check((APICreateRootVolumeTemplateFromRootVolumeMsg) msg, pairs); - } else if (msg instanceof APICreateDataVolumeTemplateFromVolumeMsg) { - check((APICreateDataVolumeTemplateFromVolumeMsg) msg, pairs); - } - } else { - if (msg instanceof APIChangeResourceOwnerMsg) { - check((APIChangeResourceOwnerMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - List usages = new ArrayList<>(); - - ImageQuotaUtil.ImageQuota imageQuota = new ImageQuotaUtil().getUsed(accountUuid); - - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(ImageQuotaConstant.IMAGE_NUM); - usage.setUsed(imageQuota.imageNum); - usages.add(usage); - - usage = new Quota.QuotaUsage(); - usage.setName(ImageQuotaConstant.IMAGE_SIZE); - usage.setUsed(imageQuota.imageSize); - usages.add(usage); - - return usages; - } - - @Transactional(readOnly = true) - private void check(APIChangeResourceOwnerMsg msg, Map pairs) { - String currentAccountUuid = msg.getSession().getAccountUuid(); - String resourceTargetOwnerAccountUuid = msg.getAccountUuid(); - if (new QuotaUtil().isAdminAccount(resourceTargetOwnerAccountUuid)) { - return; - } - - SimpleQuery q = dbf.createQuery(AccountResourceRefVO.class); - q.add(AccountResourceRefVO_.resourceUuid, Op.EQ, msg.getResourceUuid()); - AccountResourceRefVO accResRefVO = q.find(); - - - if (accResRefVO.getResourceType().equals(ImageVO.class.getSimpleName())) { - long imageNumQuota = pairs.get(ImageQuotaConstant.IMAGE_NUM).getValue(); - long imageSizeQuota = pairs.get(ImageQuotaConstant.IMAGE_SIZE).getValue(); - - long imageNumUsed = new ImageQuotaUtil().getUsedImageNum(resourceTargetOwnerAccountUuid); - long imageSizeUsed = new ImageQuotaUtil().getUsedImageSize(resourceTargetOwnerAccountUuid); - - ImageVO image = dbf.getEntityManager().find(ImageVO.class, msg.getResourceUuid()); - long imageNumAsked = 1; - long imageSizeAsked = image.getSize(); - - - QuotaUtil.QuotaCompareInfo quotaCompareInfo; - { - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = ImageQuotaConstant.IMAGE_NUM; - quotaCompareInfo.quotaValue = imageNumQuota; - quotaCompareInfo.currentUsed = imageNumUsed; - quotaCompareInfo.request = imageNumAsked; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - - { - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = ImageQuotaConstant.IMAGE_SIZE; - quotaCompareInfo.quotaValue = imageSizeQuota; - quotaCompareInfo.currentUsed = imageSizeUsed; - quotaCompareInfo.request = imageSizeAsked; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - } - - } - - @Transactional(readOnly = true) - private void check(APIRecoverImageMsg msg, Map pairs) { - String currentAccountUuid = msg.getSession().getAccountUuid(); - String resourceTargetOwnerAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(msg.getImageUuid()); - - long imageNumQuota = pairs.get(ImageQuotaConstant.IMAGE_NUM).getValue(); - long imageSizeQuota = pairs.get(ImageQuotaConstant.IMAGE_SIZE).getValue(); - long imageNumUsed = new ImageQuotaUtil().getUsedImageNum(resourceTargetOwnerAccountUuid); - long imageSizeUsed = new ImageQuotaUtil().getUsedImageSize(resourceTargetOwnerAccountUuid); - - ImageVO image = dbf.getEntityManager().find(ImageVO.class, msg.getImageUuid()); - long imageNumAsked = 1; - long imageSizeAsked = image.getSize(); - - QuotaUtil.QuotaCompareInfo quotaCompareInfo; - { - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = ImageQuotaConstant.IMAGE_NUM; - quotaCompareInfo.quotaValue = imageNumQuota; - quotaCompareInfo.currentUsed = imageNumUsed; - quotaCompareInfo.request = imageNumAsked; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - - { - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = ImageQuotaConstant.IMAGE_SIZE; - quotaCompareInfo.quotaValue = imageSizeQuota; - quotaCompareInfo.currentUsed = imageSizeUsed; - quotaCompareInfo.request = imageSizeAsked; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - } - - @Transactional(readOnly = true) - private void check(APIAddImageMsg msg, Map pairs) { - String currentAccountUuid = msg.getSession().getAccountUuid(); - String resourceTargetOwnerAccountUuid = msg.getSession().getAccountUuid(); - - checkImageNumQuota(currentAccountUuid, resourceTargetOwnerAccountUuid, pairs); - new ImageQuotaUtil().checkImageSizeQuotaUseHttpHead(msg, pairs); - } - - @Transactional(readOnly = true) - private void check(APICreateRootVolumeTemplateFromRootVolumeMsg msg, Map pairs) { - checkImageNumQuota(msg.getSession().getAccountUuid(), - msg.getSession().getAccountUuid(), - pairs); - - Long templateSize = Q.New(VolumeVO.class) + Quota quota = new Quota(); + quota.defineQuota(new ImageNumQuotaDefinition()); + quota.defineQuota(new ImageSizeQuotaDefinition()); + + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIAddImageMsg.class) + .addCounterQuota(ImageQuotaConstant.IMAGE_NUM) + .addMessageRequiredQuotaHandler(ImageQuotaConstant.IMAGE_SIZE, (msg) -> new ImageQuotaUtil().getImageActualSizeOnBs(msg.getUrl().trim(), msg.getBackupStorageUuids()))); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIRecoverImageMsg.class) + .addMessageRequiredQuotaHandler(ImageQuotaConstant.IMAGE_SIZE, (msg) -> { + ImageVO image = dbf.getEntityManager().find(ImageVO.class, msg.getImageUuid()); + return image.getSize(); + })); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateRootVolumeTemplateFromRootVolumeMsg.class) + .addCounterQuota(ImageQuotaConstant.IMAGE_NUM) + .addMessageRequiredQuotaHandler(ImageQuotaConstant.IMAGE_SIZE, (msg) -> Q.New(VolumeVO.class) .select(VolumeVO_.size) .eq(VolumeVO_.uuid, msg.getRootVolumeUuid()) - .findValue(); - - checkImageSizeQuota(templateSize == null ? 0 : templateSize, - msg.getSession().getAccountUuid(), - msg.getSession().getAccountUuid(), - pairs); - } - - @Transactional(readOnly = true) - private void check(APICreateDataVolumeTemplateFromVolumeMsg msg, Map pairs) { - checkImageNumQuota(msg.getSession().getAccountUuid(), - msg.getSession().getAccountUuid(), - pairs); - - Long templateSize = Q.New(VolumeVO.class) + .findValue())); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateDataVolumeTemplateFromVolumeMsg.class) + .addCounterQuota(ImageQuotaConstant.IMAGE_NUM) + .addMessageRequiredQuotaHandler(ImageQuotaConstant.IMAGE_SIZE, (msg) -> Q.New(VolumeVO.class) .select(VolumeVO_.size) .eq(VolumeVO_.uuid, msg.getVolumeUuid()) - .findValue(); - - checkImageSizeQuota(templateSize == null ? 0 : templateSize, - msg.getSession().getAccountUuid(), - msg.getSession().getAccountUuid(), - pairs); - } - - @Transactional(readOnly = true) - private void checkImageSizeQuota(long requiredImageSize, - String currentAccountUuid, - String resourceTargetOwnerAccountUuid, - Map pairs) { - long imageSizeQuota = pairs.get(ImageQuotaConstant.IMAGE_SIZE).getValue(); - long imageSizeUsed = new ImageQuotaUtil().getUsedImageSize(resourceTargetOwnerAccountUuid); - - QuotaUtil.QuotaCompareInfo quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = ImageQuotaConstant.IMAGE_SIZE; - quotaCompareInfo.quotaValue = imageSizeQuota; - quotaCompareInfo.currentUsed = imageSizeUsed; - quotaCompareInfo.request = requiredImageSize; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - - @Transactional(readOnly = true) - private void checkImageNumQuota(String currentAccountUuid, - String resourceTargetOwnerAccountUuid, - Map pairs) { - long imageNumQuota = pairs.get(ImageQuotaConstant.IMAGE_NUM).getValue(); - long imageNumUsed = new ImageQuotaUtil().getUsedImageNum(resourceTargetOwnerAccountUuid); - long imageNumAsked = 1; - - QuotaUtil.QuotaCompareInfo quotaCompareInfo; - { - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = ImageQuotaConstant.IMAGE_NUM; - quotaCompareInfo.quotaValue = imageNumQuota; - quotaCompareInfo.currentUsed = imageNumUsed; - quotaCompareInfo.request = imageNumAsked; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - } - }; - - Quota quota = new Quota(); - quota.setOperator(checker); - quota.addMessageNeedValidation(APIAddImageMsg.class); - quota.addMessageNeedValidation(APIRecoverImageMsg.class); - quota.addMessageNeedValidation(APIChangeResourceOwnerMsg.class); - quota.addMessageNeedValidation(APICreateRootVolumeTemplateFromRootVolumeMsg.class); - quota.addMessageNeedValidation(APICreateDataVolumeTemplateFromVolumeMsg.class); - - Quota.QuotaPair p = new Quota.QuotaPair(); - p.setName(ImageQuotaConstant.IMAGE_NUM); - p.setValue(ImageQuotaGlobalConfig.IMAGE_NUM.defaultValue(Long.class)); - quota.addPair(p); - - p = new Quota.QuotaPair(); - p.setName(ImageQuotaConstant.IMAGE_SIZE); - p.setValue(ImageQuotaGlobalConfig.IMAGE_SIZE.defaultValue(Long.class)); - quota.addPair(p); + .findValue())); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(ImageVO.class) + .eq(ImageVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(ImageQuotaConstant.IMAGE_NUM) + .addMessageRequiredQuotaHandler(ImageQuotaConstant.IMAGE_SIZE, (msg) -> { + ImageVO image = dbf.getEntityManager().find(ImageVO.class, msg.getResourceUuid()); + return image.getSize(); + })); return list(quota); } @@ -1329,6 +1847,9 @@ void reply(Message reply) { vo.setPlatform(ImagePlatform.valueOf(msgData.getPlatform())); } + long asize = new ImageQuotaUtil().getImageActualSizeOnBs(msgData.getUrl().trim(), msgData.getBackupStorageUuids()); + vo.setActualSize(asize); + ImageFactory factory = getImageFacotry(ImageType.valueOf(imageType)); final ImageVO ivo = new SQLBatchWithReturn() { @Override @@ -1392,78 +1913,75 @@ protected Collection collect() { @Override protected AsyncBatchRunner forEach(DownloadImageMsg dmsg) { - return new AsyncBatchRunner() { - @Override - public void run(NoErrorCompletion completion) { - ImageBackupStorageRefVO ref = Q.New(ImageBackupStorageRefVO.class) - .eq(ImageBackupStorageRefVO_.imageUuid, ivo.getUuid()) - .eq(ImageBackupStorageRefVO_.backupStorageUuid, dmsg.getBackupStorageUuid()) - .find(); - bus.send(dmsg, new CloudBusCallBack(completion) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - errors.add(reply.getError()); - dbf.remove(ref); - } else { - DownloadImageReply re = reply.castReply(); - ref.setInstallPath(re.getInstallPath()); - - if (isUpload(msgData.getUrl())) { - tracker.addTrackTask(ivo, ref); - } else { - ref.setStatus(ImageStatus.Ready); - } - - if (dbf.reload(ref) == null) { - logger.debug(String.format("image[uuid: %s] has been deleted", ref.getImageUuid())); - completion.done(); - return; - } - - dbf.update(ref); + return (completion) -> { + ImageBackupStorageRefVO ref = Q.New(ImageBackupStorageRefVO.class) + .eq(ImageBackupStorageRefVO_.imageUuid, ivo.getUuid()) + .eq(ImageBackupStorageRefVO_.backupStorageUuid, dmsg.getBackupStorageUuid()) + .find(); + bus.send(dmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + errors.add(reply.getError()); + dbf.remove(ref); + completion.done(); + return; + } - if (resultMap.get(ref.getBackupStorageUuid()).compareAndSet(false, true)) { - // In case 'Platform' etc. is changed. - ImageVO vo = dbf.reload(ivo); - vo.setMd5Sum(re.getMd5sum()); - vo.setSize(re.getSize()); - vo.setActualSize(re.getActualSize()); - vo.setUrl(URLBuilder.hideUrlPassword(vo.getUrl())); - if (StringUtils.isNotEmpty(re.getFormat())) { - vo.setFormat(re.getFormat()); - } - if (vo.getFormat().equals(ImageConstant.ISO_FORMAT_STRING) - && ImageMediaType.RootVolumeTemplate.equals(vo.getMediaType())) { - vo.setMediaType(ImageMediaType.ISO); - } - if (ImageConstant.QCOW2_FORMAT_STRING.equals(vo.getFormat()) - && ImageMediaType.ISO.equals(vo.getMediaType())) { - vo.setMediaType(ImageMediaType.RootVolumeTemplate); - } + DownloadImageReply re = reply.castReply(); + ref.setInstallPath(re.getInstallPath()); - if (resultMap.entrySet().stream().allMatch(entry -> entry.getValue().get())) { - vo.setStatus(ref.getStatus()); - } + if (isUpload(msgData.getUrl())) { + tracker.addTrackTask(ivo, ref); + } else { + ref.setStatus(ImageStatus.Ready); + } - dbf.update(vo); - } + if (dbf.reload(ref) == null) { + logger.debug(String.format("image[uuid: %s] has been deleted", ref.getImageUuid())); + completion.done(); + return; + } - if (isUpload(msgData.getUrl())) { - logger.debug(String.format("created upload request, image[uuid:%s, name:%s] to backup storage[uuid:%s]", - inv.getUuid(), inv.getName(), dmsg.getBackupStorageUuid())); - } else { - logger.debug(String.format("successfully downloaded image[uuid:%s, name:%s] to backup storage[uuid:%s]", - inv.getUuid(), inv.getName(), dmsg.getBackupStorageUuid())); - } - pluginRgty.getExtensionList(AfterAddImageExtensionPoint.class).forEach(exp -> exp.saveEncryptAfterAddImage(vo.getUuid())); + dbf.update(ref); + + if (resultMap.get(ref.getBackupStorageUuid()).compareAndSet(false, true)) { + // In case 'Platform' etc. is changed. + ImageVO vo1 = dbf.reload(ivo); + vo1.setMd5Sum(re.getMd5sum()); + vo1.setSize(re.getSize()); + vo1.setActualSize(re.getActualSize()); + vo1.setUrl(URLBuilder.hideUrlPassword(vo1.getUrl())); + if (StringUtils.isNotEmpty(re.getFormat())) { + vo1.setFormat(re.getFormat()); + } + if (vo1.getFormat().equals(ImageConstant.ISO_FORMAT_STRING) + && ImageMediaType.RootVolumeTemplate.equals(vo1.getMediaType())) { + vo1.setMediaType(ImageMediaType.ISO); + } + if (ImageConstant.QCOW2_FORMAT_STRING.equals(vo1.getFormat()) + && ImageMediaType.ISO.equals(vo1.getMediaType())) { + vo1.setMediaType(ImageMediaType.RootVolumeTemplate); + } + if (resultMap.entrySet().stream().allMatch(entry -> entry.getValue().get())) { + vo1.setStatus(ref.getStatus()); } - completion.done(); + dbf.update(vo1); } - }); - } + + if (isUpload(msgData.getUrl())) { + logger.debug(String.format("created upload request, image[uuid:%s, name:%s] to backup storage[uuid:%s]", + inv.getUuid(), inv.getName(), dmsg.getBackupStorageUuid())); + } else { + logger.debug(String.format("successfully downloaded image[uuid:%s, name:%s] to backup storage[uuid:%s]", + inv.getUuid(), inv.getName(), dmsg.getBackupStorageUuid())); + } + + completion.done(); + } + }); }; } @@ -1488,6 +2006,7 @@ protected void done() { if (vo.getStatus() == ImageStatus.Ready) { extEmitter.afterAddImage(einv); + pluginRgty.getExtensionList(AfterAddImageExtensionPoint.class).forEach(exp -> exp.saveEncryptAfterAddImage(vo.getUuid())); } event.inv = einv; @@ -1713,10 +2232,10 @@ public void run(FlowTrigger trigger, Map data) { @Override public void run(final FlowTrigger trigger, Map data) { - List cmsgs = CollectionUtils.transformToList(targetBackupStorages, new Function() { + List cmsgs = CollectionUtils.transformToList(targetBackupStorages, new Function() { @Override - public CreateTemplateFromVmRootVolumeMsg call(BackupStorageInventory arg) { - CreateTemplateFromVmRootVolumeMsg cmsg = new CreateTemplateFromVmRootVolumeMsg(); + public CreateTemplateFromRootVolumeVmMsg call(BackupStorageInventory arg) { + CreateTemplateFromRootVolumeVmMsg cmsg = new CreateTemplateFromRootVolumeVmMsg(); cmsg.setRootVolumeInventory(rootVolume); cmsg.setBackupStorageUuid(arg.getUuid()); cmsg.setImageInventory(ImageInventory.valueOf(imageVO)); @@ -1755,7 +2274,7 @@ public void run(List replies) { continue; } - CreateTemplateFromVmRootVolumeReply reply = (CreateTemplateFromVmRootVolumeReply) r; + CreateTemplateFromRootVolumeVmReply reply = (CreateTemplateFromRootVolumeVmReply) r; ref.setStatus(ImageStatus.Ready); ref.setInstallPath(reply.getInstallPath()); dbf.update(ref); @@ -1971,7 +2490,7 @@ public void run(MessageReply reply) { saveRefVOByBsInventorys(backupStorages, image.getUuid()); trigger.next(); } else { - trigger.fail(operr(reply.getError(), "cannot find proper backup storage")); + trigger.fail(operr("cannot find proper backup storage").causedBy(reply.getError())); } } }); @@ -2072,7 +2591,7 @@ public CreateDataVolumeTemplateFromDataVolumeMsg call(BackupStorageInventory bs) } }); - bus.send(cmsgs, new CloudBusListCallBack(null) { + bus.send(cmsgs, new CloudBusListCallBack(trigger) { @Override public void run(List replies) { int fail = 0; diff --git a/image/src/main/java/org/zstack/image/ImageMessageFiller.java b/image/src/main/java/org/zstack/image/ImageMessageFiller.java index 6bfce3fd57b..afbdceb164e 100644 --- a/image/src/main/java/org/zstack/image/ImageMessageFiller.java +++ b/image/src/main/java/org/zstack/image/ImageMessageFiller.java @@ -1,6 +1,5 @@ package org.zstack.image; -import edu.emory.mathcs.backport.java.util.Collections; import org.zstack.compute.vm.VmExtraInfoGetter; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.config.schema.GuestOsCategory; @@ -12,22 +11,25 @@ import org.zstack.header.volume.VolumeVO; import org.zstack.header.volume.VolumeVO_; +import java.util.Collections; + /** * Created by MaJin on 2021/3/16. */ public class ImageMessageFiller { + public static void fillDefault(AddImageMessage msg) { if (ImageConstant.ImageMediaType.DataVolumeTemplate.toString().equals(msg.getMediaType())) { return; } if (msg.getPlatform() == null) { - msg.setPlatform(ImagePlatform.Linux.toString()); + msg.setPlatform(ImageDefaultBehavior.getDefaultPlatform()); } - - if (msg.getPlatform().equals(ImagePlatform.Paravirtualization.toString())) { + if (msg.getPlatform() != null && msg.getPlatform().equals(ImagePlatform.Paravirtualization.toString())) { msg.setPlatform(ImagePlatform.Other.toString()); - } else if (msg.getPlatform().equals(ImagePlatform.WindowsVirtio.toString())) { + } + if (msg.getPlatform() != null && msg.getPlatform().equals(ImagePlatform.WindowsVirtio.toString())) { msg.setPlatform(ImagePlatform.Windows.toString()); } @@ -37,7 +39,7 @@ public static void fillDefault(AddImageMessage msg) { } if (msg.getGuestOsType() == null) { - msg.setGuestOsType(GuestOsCategory.getDefaultGuestOsTypeByPlatform(msg.getPlatform())); + msg.setGuestOsType(msg.getPlatform() == null ? null : GuestOsCategory.getDefaultGuestOsTypeByPlatform(msg.getPlatform())); } setBootModeIfAarch64(msg); diff --git a/image/src/main/java/org/zstack/image/ImageNumQuotaDefinition.java b/image/src/main/java/org/zstack/image/ImageNumQuotaDefinition.java new file mode 100644 index 00000000000..9bf679dabf1 --- /dev/null +++ b/image/src/main/java/org/zstack/image/ImageNumQuotaDefinition.java @@ -0,0 +1,32 @@ +package org.zstack.image; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.image.ImageVO; + +public class ImageNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return ImageQuotaConstant.IMAGE_NUM; + } + + @Override + public Long getDefaultValue() { + return ImageQuotaGlobalConfig.IMAGE_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(image) " + + " from ImageVO image, AccountResourceRefVO ref " + + " where image.uuid = ref.resourceUuid " + + " and ref.accountUuid = :auuid " + + " and ref.resourceType = :rtype "; + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", ImageVO.class.getSimpleName()); + Long imageNum = q.find(); + imageNum = imageNum == null ? 0 : imageNum; + return imageNum; + } +} diff --git a/image/src/main/java/org/zstack/image/ImageQuotaUtil.java b/image/src/main/java/org/zstack/image/ImageQuotaUtil.java index 3c7d3163a76..df45e2f1a39 100644 --- a/image/src/main/java/org/zstack/image/ImageQuotaUtil.java +++ b/image/src/main/java/org/zstack/image/ImageQuotaUtil.java @@ -5,23 +5,21 @@ import org.springframework.beans.factory.annotation.Configurable; import org.springframework.http.HttpHeaders; import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.CoreGlobalProperty; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.header.apimediator.ApiMessageInterceptionException; -import org.zstack.header.core.BypassWhenUnitTest; import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.identity.Quota; -import org.zstack.header.image.APIAddImageMsg; import org.zstack.header.image.ImageVO; import org.zstack.header.rest.RESTFacade; -import org.zstack.header.storage.backup.*; -import org.zstack.identity.QuotaUtil; +import org.zstack.header.storage.backup.BackupStorageConstant; +import org.zstack.header.storage.backup.GetLocalFileSizeOnBackupStorageMsg; +import org.zstack.header.storage.backup.GetLocalFileSizeOnBackupStorageReply; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import javax.persistence.TypedQuery; -import java.util.Map; +import java.util.List; /** * Created by miao on 16-10-9. @@ -84,31 +82,21 @@ public long getUsedImageSize(String accountUuid) { return imageSize; } - @BypassWhenUnitTest - public void checkImageSizeQuotaUseHttpHead(APIAddImageMsg msg, Map pairs) { - long imageSizeQuota = pairs.get(ImageQuotaConstant.IMAGE_SIZE).getValue(); - long imageSizeUsed = new ImageQuotaUtil().getUsedImageSize(msg.getSession().getAccountUuid()); - long imageSizeAsked = getLocalImageSizeOnBackupStorage(msg); - if ((imageSizeQuota == 0) || (imageSizeUsed + imageSizeAsked > imageSizeQuota)) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), ImageQuotaConstant.IMAGE_SIZE, imageSizeQuota)); - } - } + public long getImageActualSizeOnBs(String url, List bsUuids) { + long imageSizeAsked = 0; + if (CoreGlobalProperty.UNIT_TEST_ON) { + return 1; + } - public long getLocalImageSizeOnBackupStorage(APIAddImageMsg msg) { - long imageSizeAsked = 0; - final String url = msg.getUrl().trim(); if (url.startsWith("file:///")) { GetLocalFileSizeOnBackupStorageMsg gmsg = new GetLocalFileSizeOnBackupStorageMsg(); - String bsUuid = msg.getBackupStorageUuids().get(0); - gmsg.setBackupStorageUuid(bsUuid); + gmsg.setBackupStorageUuid(bsUuids.get(0)); gmsg.setUrl(url.split("://")[1]); - bus.makeTargetServiceIdByResourceUuid(gmsg, BackupStorageConstant.SERVICE_ID, bsUuid); + bus.makeTargetServiceIdByResourceUuid(gmsg, BackupStorageConstant.SERVICE_ID, bsUuids.get(0)); GetLocalFileSizeOnBackupStorageReply reply = (GetLocalFileSizeOnBackupStorageReply) bus.call(gmsg); if (!reply.isSuccess()) { - logger.warn(String.format("cannot get image. The image url : %s. description: %s.name: %s", - url, msg.getDescription(), msg.getName())); + logger.warn(String.format("cannot get image. The image url: %s", url)); throw new OperationFailureException(reply.getError()); } else { imageSizeAsked = reply.getSize(); @@ -119,8 +107,7 @@ public long getLocalImageSizeOnBackupStorage(APIAddImageMsg msg) { try { len = header.getFirst("Content-Length"); } catch (Exception e) { - logger.warn(String.format("cannot get image. The image url : %s. description: %s.name: %s", - url, msg.getDescription(), msg.getName())); + logger.warn(String.format("cannot get image. The image url: %s", url)); } imageSizeAsked = len == null ? 0 : Long.parseLong(len); } diff --git a/image/src/main/java/org/zstack/image/ImageSizeQuotaDefinition.java b/image/src/main/java/org/zstack/image/ImageSizeQuotaDefinition.java new file mode 100644 index 00000000000..737a524cea6 --- /dev/null +++ b/image/src/main/java/org/zstack/image/ImageSizeQuotaDefinition.java @@ -0,0 +1,32 @@ +package org.zstack.image; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.image.ImageVO; + +public class ImageSizeQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return ImageQuotaConstant.IMAGE_SIZE; + } + + @Override + public Long getDefaultValue() { + return ImageQuotaGlobalConfig.IMAGE_SIZE.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select sum(image.actualSize) " + + " from ImageVO image ,AccountResourceRefVO ref " + + " where image.uuid = ref.resourceUuid " + + " and ref.accountUuid = :auuid " + + " and ref.resourceType = :rtype "; + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", ImageVO.class.getSimpleName()); + Long imageSize = q.find(); + imageSize = imageSize == null ? 0 : imageSize; + return imageSize; + } +} diff --git a/image/src/main/java/org/zstack/image/ImageSystemTags.java b/image/src/main/java/org/zstack/image/ImageSystemTags.java index faf08ef144f..64c26c6f8d7 100755 --- a/image/src/main/java/org/zstack/image/ImageSystemTags.java +++ b/image/src/main/java/org/zstack/image/ImageSystemTags.java @@ -53,4 +53,10 @@ public class ImageSystemTags { public static String IMAGE_ID ="imageId"; public static PatternedSystemTag UPLOAD_IMAGE_INFO = new PatternedSystemTag(String.format("uploadImage::{%s}", IMAGE_ID), LongJobVO.class); + + public static final String MARKET_PLACE_TOKEN = "marketplace::true"; + + public static PatternedSystemTag CREATED_BY_MARKETPLACE = new PatternedSystemTag( + MARKET_PLACE_TOKEN, ImageVO.class + ); } diff --git a/image/src/main/java/org/zstack/image/UploadImageTracker.java b/image/src/main/java/org/zstack/image/UploadImageTracker.java index 841fde3a1f8..5541a64577e 100644 --- a/image/src/main/java/org/zstack/image/UploadImageTracker.java +++ b/image/src/main/java/org/zstack/image/UploadImageTracker.java @@ -5,7 +5,6 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.core.CoreGlobalProperty; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.componentloader.PluginRegistry; @@ -101,8 +100,8 @@ void trackUpload(ImageVO image, ImageBackupStorageRefVO ref) { } void trackUpload(String name, String imageUuid, String bsUuid, String hostname) { - final int maxNumOfFailure = CoreGlobalProperty.UNIT_TEST_ON ? 1 : 3; - final int maxIdleSecond = CoreGlobalProperty.UNIT_TEST_ON ? 1 : 30; + final int maxNumOfFailure = ImageGlobalConfig.UPLOAD_FAILURE_TOLERANCE_COUNT.value(Integer.class); + final long maxIdleSecond = ImageGlobalConfig.UPLOAD_MAX_IDLE_IN_SECONDS.value(Long.class); thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask() { private long numError = 0; @@ -144,6 +143,7 @@ protected ImageVO scripts() { fireEvent(einv, null); CollectionUtils.safeForEach(pluginRgty.getExtensionList(AddImageExtensionPoint.class), ext -> ext.afterAddImage(einv)); + pluginRgty.getExtensionList(AfterAddImageExtensionPoint.class).forEach(exp -> exp.saveEncryptAfterAddImage(einv.getUuid())); } private void markFailure(ErrorCode reason) { diff --git a/longjob/pom.xml b/longjob/pom.xml index 3d4665f41d6..867476237b4 100755 --- a/longjob/pom.xml +++ b/longjob/pom.xml @@ -3,7 +3,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. longjob diff --git a/longjob/src/main/java/org/zstack/longjob/LongJobFlowContextHandler.java b/longjob/src/main/java/org/zstack/longjob/LongJobFlowContextHandler.java new file mode 100644 index 00000000000..76a370d4d28 --- /dev/null +++ b/longjob/src/main/java/org/zstack/longjob/LongJobFlowContextHandler.java @@ -0,0 +1,34 @@ +package org.zstack.longjob; + +import org.zstack.header.core.workflow.FlowContextHandler; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.longjob.LongJobErrors; + +public abstract class LongJobFlowContextHandler implements FlowContextHandler { + private final String longJobUuid; + + public LongJobFlowContextHandler(String longJobUuid) { + this.longJobUuid = longJobUuid; + } + + @Override + public String getJobUuid() { + return longJobUuid; + } + + @Override + public boolean cancelled() { + return LongJobUtils.jobCanceled(getJobUuid()); + } + + @Override + public ErrorCode getCancelError() { + return LongJobUtils.cancelErr(getJobUuid()); + } + + @Override + public boolean skipRollback(ErrorCode errorCode) { + return errorCode.isError(SysErrors.MANAGEMENT_NODE_UNAVAILABLE_ERROR, LongJobErrors.INTERRUPTED); + } +} diff --git a/longjob/src/main/java/org/zstack/longjob/LongJobManager.java b/longjob/src/main/java/org/zstack/longjob/LongJobManager.java index 440e20c0124..bfa502d5d4a 100644 --- a/longjob/src/main/java/org/zstack/longjob/LongJobManager.java +++ b/longjob/src/main/java/org/zstack/longjob/LongJobManager.java @@ -1,16 +1,14 @@ package org.zstack.longjob; import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.header.core.SafeConsumer; import org.zstack.header.longjob.SubmitLongJobMsg; import org.zstack.header.message.APIEvent; -import java.util.function.Consumer; -import java.util.function.Function; - /** * Created by GuoYi on 11/14/17. */ public interface LongJobManager { void loadLongJob(); - void submitLongJob(SubmitLongJobMsg msg, CloudBusCallBack submitCallBack, Consumer jobCallBack); + void submitLongJob(SubmitLongJobMsg msg, CloudBusCallBack submitCallBack, SafeConsumer jobCallBack); } diff --git a/longjob/src/main/java/org/zstack/longjob/LongJobManagerImpl.java b/longjob/src/main/java/org/zstack/longjob/LongJobManagerImpl.java index 972ef8a8e22..a755a0b9270 100755 --- a/longjob/src/main/java/org/zstack/longjob/LongJobManagerImpl.java +++ b/longjob/src/main/java/org/zstack/longjob/LongJobManagerImpl.java @@ -26,7 +26,7 @@ import org.zstack.header.Constants; import org.zstack.header.core.*; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.APIDeleteAccountEvent; import org.zstack.header.longjob.*; @@ -41,6 +41,7 @@ import org.zstack.utils.BeanUtils; import org.zstack.utils.ThreadContextUtils; import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import javax.persistence.Tuple; @@ -50,9 +51,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.err; import static org.zstack.core.db.DBSourceUtils.isDBConnected; import static org.zstack.core.db.DBSourceUtils.waitDBConnected; @@ -91,7 +90,7 @@ public class LongJobManagerImpl extends AbstractService implements LongJobManage private List longJobClasses = new ArrayList(); private Map> useApiTimeout = new HashMap<>(); - private Map> longJobCallBacks = new ConcurrentHashMap<>(); + private Map> longJobCallBacks = new ConcurrentHashMap<>(); private void collectLongJobs() { Set> subs = BeanUtils.reflections.getTypesAnnotatedWith(LongJobFor.class); @@ -338,6 +337,11 @@ public void success(Boolean cancelled) { @Override public void fail(ErrorCode errorCode) { + if (Q.New(LongJobVO.class).eq(LongJobVO_.uuid, vo.getUuid()).eq(LongJobVO_.state, LongJobState.Canceled).isExists()){ + completion.success(); + return; + } + logger.error(String.format("failed to cancel longjob [uuid:%s, name:%s]", vo.getUuid(), vo.getName())); completion.fail(errorCode); } @@ -472,9 +476,14 @@ private void handle(APISubmitLongJobMsg msg) { bus.send(smsg, new CloudBusCallBack(msg) { @Override public void run(MessageReply rly) { - SubmitLongJobReply reply = rly.castReply(); - evt.setInventory(reply.getInventory()); - evt.setNeedAudit(reply.isNeedAudit()); + if (rly.isSuccess()) { + SubmitLongJobReply reply = rly.castReply(); + evt.setInventory(reply.getInventory()); + evt.setNeedAudit(reply.isNeedAudit()); + } else { + evt.setError(rly.getError()); + } + bus.publish(evt); } }); @@ -495,6 +504,7 @@ private void handle(SubmitLongJobMsg msg) { Timestamp now = Timestamp.valueOf(LocalDateTime.now()); vo.setCreateDate(now); vo.setLastOpDate(now); + vo.setJobResult(null); vo = dbf.updateAndRefresh(vo); logger.info(String.format("longjob [uuid:%s, name:%s] has been re-submitted", vo.getUuid(), vo.getName())); } else { @@ -610,14 +620,18 @@ private ReturnValueCompletion buildJobOverCompletion(LongJob job, Long public void success(APIEvent evt) { reportProgress("100"); changeState(longJobUuid, LongJobStateEvent.succeed, it -> { - if (Strings.isEmpty(it.getJobResult())) { + if (!Strings.isEmpty(it.getJobResult())) { + it.setJobResult(it.getJobResult()); + } else if (evt != null) { + it.setJobResult(JSONObjectUtil.toJsonString(evt)); + } else { it.setJobResult(LongJobUtils.succeeded); } }); if (evt != null) { exts.forEach(ext -> ext.afterJobFinished(job, vo, evt)); - Optional.ofNullable(longJobCallBacks.remove(vo.getApiId())).ifPresent(it -> it.accept(evt)); + runLongJobCallBack(vo, evt); } else { exts.forEach(ext -> ext.afterJobFinished(job, vo)); } @@ -642,15 +656,31 @@ public void fail(ErrorCode errorCode) { evt.setError(errorCode); exts.forEach(ext -> ext.afterJobFailed(job, vo, evt)); - Optional.ofNullable(longJobCallBacks.remove(vo.getApiId())).ifPresent(it -> it.accept(evt)); + runLongJobCallBack(vo, evt); logger.info(String.format("failed to run longjob [uuid:%s, name:%s]", vo.getUuid(), vo.getName())); } }; } + private void runLongJobCallBack(LongJobVO vo, APIEvent evt) { + Optional.ofNullable(longJobCallBacks.remove(vo.getApiId())).ifPresent(it -> { + logger.debug(String.format("run callback for longjob [uuid:%s, name:%s]", vo.getUuid(), vo.getName())); + it.safeAccept(evt); + }); + } + + private void runLongJobCallBack(LongJobVO vo, ErrorCode err) { + Optional.ofNullable(longJobCallBacks.remove(vo.getApiId())).ifPresent(it -> { + APIEvent evt = new APIEvent(vo.getApiId()); + evt.setError(err); + logger.debug(String.format("run callback for longjob [uuid:%s, name:%s]", vo.getUuid(), vo.getName())); + it.safeAccept(evt); + }); + } + @Override - public void submitLongJob(SubmitLongJobMsg msg, CloudBusCallBack submitCallBack, Consumer jobCallBack) { + public void submitLongJob(SubmitLongJobMsg msg, CloudBusCallBack submitCallBack, SafeConsumer jobCallBack) { String apiId = Platform.getUuid(); String originApiId = ThreadContext.get(Constants.THREAD_CONTEXT_API); @@ -825,21 +855,34 @@ private void doLoadLongJob(LongJobVO vo, LongJobOperation operation) { if (operation == LongJobOperation.Start) { doStartJob(vo.getUuid(), new NopeCompletion()); - } else if (operation == LongJobOperation.Resume) { - if (longJobFactory.supportResume(vo.getJobName())) { - doResumeJob(vo.getUuid(), new NopeCompletion()); - } else if (longJobFactory.supportClean(vo.getJobName())) { - doCleanJob(vo, new NopeCompletion()); - } else { - changeState(vo.getUuid(), LongJobStateEvent.fail); + return; + } + + if (operation == LongJobOperation.Resume && longJobFactory.supportResume(vo.getJobName())) { + doResumeJob(vo.getUuid(), new NopeCompletion()); + return; + } + + if (!longJobFactory.supportClean(vo.getJobName())) { + changeState(vo.getUuid(), LongJobStateEvent.fail); + runLongJobCallBack(vo, err(SysErrors.MANAGEMENT_NODE_UNAVAILABLE_ERROR, + "management node is unavailable")); + return; + } + + doCleanJob(vo, new Completion(null) { + @Override + public void success() { + runLongJobCallBack(vo, err(SysErrors.MANAGEMENT_NODE_UNAVAILABLE_ERROR, + "management node is unavailable")); } - } else if (operation == LongJobOperation.Cancel) { - if (longJobFactory.supportClean(vo.getJobName())) { - doCleanJob(vo, new NopeCompletion()); - } else { - changeState(vo.getUuid(), LongJobStateEvent.canceled); + + @Override + public void fail(ErrorCode errorCode) { + runLongJobCallBack(vo, err(SysErrors.MANAGEMENT_NODE_UNAVAILABLE_ERROR, + "management node is unavailable")); } - } + }); } private LongJobOperation getLoadOperation(LongJobVO vo) { diff --git a/longjob/src/main/java/org/zstack/longjob/LongJobUtils.java b/longjob/src/main/java/org/zstack/longjob/LongJobUtils.java index e131c0ea53d..c99cd6589e0 100644 --- a/longjob/src/main/java/org/zstack/longjob/LongJobUtils.java +++ b/longjob/src/main/java/org/zstack/longjob/LongJobUtils.java @@ -107,12 +107,13 @@ public static LongJobVO setJobResult(String uuid, Object result) { return updateByUuid(uuid, vo -> vo.setJobResult(JSONObjectUtil.toJsonString(result))); } - static boolean jobCompleted(LongJobVO vo) { + public static boolean jobCompleted(LongJobVO vo) { return completedStates.contains(vo.getState()); } static LongJobVO updateByUuid(String uuid, Consumer consumer) { - return new SQLBatchWithReturn(){ + final boolean[] jobCompleted = {false}; + LongJobVO job = new SQLBatchWithReturn(){ @Override protected LongJobVO scripts() { @@ -123,7 +124,7 @@ protected LongJobVO scripts() { if (jobCompleted(job)) { setExecuteTimeIfNeed(job); - cleanProgress(job); + jobCompleted[0] = true; } if (originState != newState) { @@ -134,6 +135,10 @@ protected LongJobVO scripts() { return job; } }.execute(); + if (jobCompleted[0]) { + cleanProgress(job); + } + return job; } static LongJobVO changeState(String uuid, LongJobStateEvent stateEvent) { diff --git a/network/pom.xml b/network/pom.xml index 2f61d1d395a..009efab142c 100755 --- a/network/pom.xml +++ b/network/pom.xml @@ -3,7 +3,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. network diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java b/network/src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java index 3cac1d5608f..b67aea2b6ef 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkApiInterceptor.java @@ -1,19 +1,29 @@ package org.zstack.network.l2; +import org.apache.commons.lang.StringUtils; +import org.apache.poi.util.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; import org.zstack.header.apimediator.StopRoutingException; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.cluster.ClusterVO_; +import org.zstack.header.host.HostStatus; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; import org.zstack.header.message.APIMessage; import org.zstack.header.network.l2.*; -import org.zstack.resourceconfig.ResourceConfig; -import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.utils.network.NetworkUtils; + +import java.util.List; +import java.util.stream.Collectors; import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; @@ -49,6 +59,8 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIDetachL2NetworkFromClusterMsg)msg); } else if (msg instanceof APIAttachL2NetworkToClusterMsg) { validate((APIAttachL2NetworkToClusterMsg) msg); + } else if (msg instanceof APIChangeL2NetworkVlanIdMsg) { + validate((APIChangeL2NetworkVlanIdMsg) msg); } setServiceId(msg); @@ -62,6 +74,23 @@ private void validate(final APIAttachL2NetworkToClusterMsg msg) { if (q.isExists()) { throw new ApiMessageInterceptionException(operr("l2Network[uuid:%s] has attached to cluster[uuid:%s], can't attach again", msg.getL2NetworkUuid(), msg.getClusterUuid())); } + + /* current ovs only support vlan, vxlan*/ + L2NetworkVO l2 = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); + if (!StringUtils.isEmpty(l2.getPhysicalInterface())) { + /* find l2 network with same physical interface, but different vswitch Type */ + List otherL2s = Q.New(L2NetworkVO.class).select(L2NetworkVO_.uuid) + .eq(L2NetworkVO_.physicalInterface, l2.getPhysicalInterface()) + .notEq(L2NetworkVO_.vSwitchType, l2.getvSwitchType()).listValues(); + if (!otherL2s.isEmpty()) { + if (Q.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) + .in(L2NetworkClusterRefVO_.l2NetworkUuid, otherL2s).isExists()) { + throw new ApiMessageInterceptionException(argerr("could not attach l2 network, because there " + + "is another network [uuid:%s] on physical interface [%s] with different vswitch type", + otherL2s.get(0), l2.getPhysicalInterface())); + } + } + } } private void validate(APIDetachL2NetworkFromClusterMsg msg) { @@ -85,14 +114,77 @@ private void validate(APICreateL2NetworkMsg msg) { if (!L2NetworkType.hasType(msg.getType())) { throw new ApiMessageInterceptionException(argerr("unsupported l2Network type[%s]", msg.getType())); } - // once we already created a linux bridge with a physical interface, - // we can not use it to create a OvsDpdk bridge - boolean isConflict = Q.New(L2NetworkVO.class) - .eq(L2NetworkVO_.physicalInterface, msg.getPhysicalInterface()) - .notEq(L2NetworkVO_.vSwitchType, msg.getvSwitchType()) - .isExists(); - if (isConflict) { - throw new ApiMessageInterceptionException(argerr("can not create %s L2Network with physicalInterface:[%s] which was already been used by another vSwitchType.", msg.getvSwitchType(), msg.getPhysicalInterface())); + + try { + VSwitchType.valueOf(msg.getvSwitchType()); + } catch (Exception e) { + throw new ApiMessageInterceptionException(argerr("unsupported vSwitch type[%s]", msg.getvSwitchType())); + } + } + + private void validate(APIChangeL2NetworkVlanIdMsg msg) { + L2NetworkVO l2 = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); + l2.getAttachedClusterRefs().forEach(ref -> { + if (Q.New(HostVO.class).eq(HostVO_.clusterUuid, ref.getClusterUuid()) + .notEq(HostVO_.status, HostStatus.Connected).isExists()) { + throw new ApiMessageInterceptionException(operr("cannot change vlan for l2Network[uuid:%s]" + + " because there are hosts status in Connecting or Disconnected", l2.getUuid())); + } + if (!Q.New(ClusterVO.class).eq(ClusterVO_.uuid, ref.getClusterUuid()) + .eq(ClusterVO_.hypervisorType, L2NetworkConstant.KVM_HYPERVISOR_TYPE).isExists()) { + throw new ApiMessageInterceptionException(operr("cannot change vlan for l2Network[uuid:%s]" + + " because it only supports an L2Network that is exclusively attached to a kvm cluster", l2.getUuid())); + } + }); + // pvlan isolated not support change vlan + if (l2.getIsolated()) { + throw new ApiMessageInterceptionException(argerr("cannot change vlan for l2Network[uuid:%s]" + + " because this l2Network is isolated", l2.getUuid())); + } + if (msg.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE)) { + if (msg.getVlan() == null) { + throw new ApiMessageInterceptionException(argerr("vlan is required for " + + "ChangeL2NetworkVlanId with type[%s]", msg.getType())); + } + if (!NetworkUtils.isValidVlan(msg.getVlan())) { + throw new ApiMessageInterceptionException(argerr("vlan[%s] is invalid", msg.getVlan())); + } + List attachedClusters = l2.getAttachedClusterRefs().stream() + .map(L2NetworkClusterRefVO::getClusterUuid).collect(Collectors.toList()); + List l2s = SQL.New("select l2" + + " from L2NetworkVO l2, L2NetworkClusterRefVO ref" + + " where l2.virtualNetworkId = :virtualNetworkId" + + " and l2.physicalInterface = :physicalInterface" + + " and ref.clusterUuid in (:clusterUuids)" + + " and l2.type = 'L2VlanNetwork'") + .param("virtualNetworkId", msg.getVlan()) + .param("physicalInterface", l2.getPhysicalInterface()) + .param("clusterUuids", attachedClusters).list(); + l2s = l2s.stream().filter(l -> !l.getUuid().equals(msg.getUuid())).collect(Collectors.toList()); + if (!l2s.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("There has been a l2Network attached to cluster with virtual network id[%s] and physical interface[%s]. Failed to change L2 network[uuid:%s]", + msg.getVlan(), l2.getPhysicalInterface(), l2.getUuid())); + } + } else if (msg.getType().equals(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE)) { + if (msg.getVlan() != null) { + throw new ApiMessageInterceptionException(argerr("vlan is not allowed for " + + "ChangeL2NetworkVlanId with type[%s]", msg.getType())); + } + List attachedClusters = l2.getAttachedClusterRefs().stream() + .map(L2NetworkClusterRefVO::getClusterUuid).collect(Collectors.toList()); + List l2s = SQL.New("select l2" + + " from L2NetworkVO l2, L2NetworkClusterRefVO ref" + + " where l2.uuid = ref.l2NetworkUuid" + + " and l2.physicalInterface = :physicalInterface" + + " and ref.clusterUuid in (:clusterUuids)" + + " and type = 'L2NoVlanNetwork'") + .param("physicalInterface", l2.getPhysicalInterface()) + .param("clusterUuids", attachedClusters).list(); + l2s = l2s.stream().filter(l -> !l.getUuid().equals(msg.getUuid())).collect(Collectors.toList()); + if (!l2s.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("There has been a l2Network attached to cluster that has physical interface[%s]. Failed to change l2Network[uuid:%s]", + l2.getPhysicalInterface(), l2.getUuid())); + } } } } diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkCascadeExtension.java b/network/src/main/java/org/zstack/network/l2/L2NetworkCascadeExtension.java index 5d1cdf4cd72..309fb83477e 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NetworkCascadeExtension.java +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkCascadeExtension.java @@ -9,6 +9,7 @@ import org.zstack.core.cloudbus.CloudBusListCallBack; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SQL; import org.zstack.core.db.SimpleQuery; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.Completion; @@ -16,6 +17,8 @@ import org.zstack.header.identity.AccountVO; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.*; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.network.sdncontroller.SdnControllerVO; import org.zstack.header.zone.ZoneInventory; import org.zstack.header.zone.ZoneVO; import org.zstack.utils.CollectionUtils; @@ -72,7 +75,9 @@ public DetachL2NetworkFromClusterMsg call(L2NetworkDetachStruct arg) { DetachL2NetworkFromClusterMsg msg = new DetachL2NetworkFromClusterMsg(); msg.setClusterUuid(arg.getClusterUuid()); msg.setL2NetworkUuid(arg.getL2NetworkUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, arg.getL2NetworkUuid()); + // vlan bridges and novlan bridge use the same bridge in ovs, so before delete l2 network we should check if the PhysicalInterface is used by another l2 network. + // and different l2 will send to different management node, so use cluster uuid for hash key instead of l2uuid + bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, arg.getClusterUuid()); return msg; } }); @@ -176,7 +181,9 @@ private void handleDeletionCheck(CascadeAction action, Completion completion) { @Override public List getEdgeNames() { - return Arrays.asList(ZoneVO.class.getSimpleName(), AccountVO.class.getSimpleName()); + return Arrays.asList(ZoneVO.class.getSimpleName(), + AccountVO.class.getSimpleName(), + SdnControllerVO.class.getSimpleName()); } @Override @@ -226,6 +233,32 @@ public List call() { if (!vos.isEmpty()) { ret = L2NetworkInventory.valueOf(vos); } + } else if (SdnControllerVO.class.getSimpleName().equals(action.getParentIssuer())) { + List controllerUuids = CollectionUtils.transformToList((List) action.getParentIssuerContext(), new Function() { + @Override + public String call(SdnControllerInventory arg) { + return arg.getUuid(); + } + }); + if (controllerUuids.isEmpty()) { + return null; + } + + ret = new ArrayList<>(); + for (String controllerUuid : controllerUuids) { + String tag = String.format("%s::%s", L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN, controllerUuid); + List l2Vos = SQL.New("select l2 from L2NetworkVO l2, SystemTagVO tag " + + "where tag.resourceUuid=l2.uuid " + + "and tag.resourceType='L2NetworkVO' " + + "and tag.tag=:tag", L2NetworkVO.class) + .param("tag", tag).list(); + if (!l2Vos.isEmpty()) { + ret.addAll(L2NetworkInventory.valueOf(l2Vos)); + } + } + if (ret.isEmpty()) { + ret = null; + } } return ret; diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkExtensionPointEmitter.java b/network/src/main/java/org/zstack/network/l2/L2NetworkExtensionPointEmitter.java index ecb34e136db..fa864bafaf2 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NetworkExtensionPointEmitter.java +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkExtensionPointEmitter.java @@ -6,6 +6,7 @@ import org.zstack.header.network.l2.L2NetworkDeleteExtensionPoint; import org.zstack.header.network.l2.L2NetworkException; import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.L2NetworkUpdateExtensionPoint; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.ForEachFunction; @@ -16,7 +17,9 @@ public class L2NetworkExtensionPointEmitter implements Component { private static final CLogger logger = Utils.getLogger(L2NetworkExtensionPointEmitter.class); private List extensions = null; - + + private List updateExtensions = null; + @Autowired private PluginRegistry pluginRgty; @@ -50,6 +53,10 @@ public void run(L2NetworkDeleteExtensionPoint arg) { }); } + public void afterUpdate(final L2NetworkInventory inv) { + CollectionUtils.safeForEach(updateExtensions, arg -> arg.afterChangeL2NetworkVlanId(inv)); + } + @Override public boolean start() { populateExtensions(); @@ -57,7 +64,8 @@ public boolean start() { } private void populateExtensions() { - extensions = pluginRgty.getExtensionList(L2NetworkDeleteExtensionPoint.class); + extensions = pluginRgty.getExtensionList(L2NetworkDeleteExtensionPoint.class); + updateExtensions = pluginRgty.getExtensionList(L2NetworkUpdateExtensionPoint.class); } @Override diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkGlobalConfig.java b/network/src/main/java/org/zstack/network/l2/L2NetworkGlobalConfig.java index c2b99c09644..953219f6a30 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NetworkGlobalConfig.java +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkGlobalConfig.java @@ -12,4 +12,13 @@ public class L2NetworkGlobalConfig { @GlobalConfigValidation public static GlobalConfig DeleteL2BridgePhysically = new GlobalConfig(CATEGORY, "deleteL2.bridge"); + + @GlobalConfigValidation + public static GlobalConfig L2IsolatedWithPhysicalSwitch = new GlobalConfig(CATEGORY, "l2.isolated"); + + @GlobalConfigValidation + public static GlobalConfig IGMPVersion = new GlobalConfig(CATEGORY, "igmp.version"); + + @GlobalConfigValidation + public static GlobalConfig MLDVersion = new GlobalConfig(CATEGORY, "mld.version"); } diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkHostHelper.java b/network/src/main/java/org/zstack/network/l2/L2NetworkHostHelper.java new file mode 100644 index 00000000000..a612b3847c5 --- /dev/null +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkHostHelper.java @@ -0,0 +1,95 @@ +package org.zstack.network.l2; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.host.HostState; +import org.zstack.header.host.HostStatus; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.network.l2.*; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; + + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class L2NetworkHostHelper { + @Autowired + DatabaseFacade dbf; + + public void attachL2NetworkToHost(String l2NetworkUuid, String hostUuid, + String providerType, + L2NetworkAttachStatus status) { + L2NetworkHostRefVO ref = Q.New(L2NetworkHostRefVO.class) + .eq(L2NetworkHostRefVO_.l2NetworkUuid, l2NetworkUuid) + .eq(L2NetworkHostRefVO_.hostUuid, hostUuid).find(); + if (ref != null) { + ref.setAttachStatus(status); + dbf.updateAndRefresh(ref); + } else { + L2NetworkHostRefVO vo = new L2NetworkHostRefVO(); + vo.setHostUuid(hostUuid); + vo.setL2NetworkUuid(l2NetworkUuid); + vo.setL2ProviderType(providerType); + vo.setAttachStatus(status); + dbf.persist(vo); + } + } + + public void attachL2NetworksToHost(List l2NetworkUuids, String hostUuid, + String providerType, + L2NetworkAttachStatus status) { + List newAdded = new ArrayList<>(); + List updated = new ArrayList<>(); + for (String uuid : l2NetworkUuids) { + L2NetworkHostRefVO ref = Q.New(L2NetworkHostRefVO.class) + .eq(L2NetworkHostRefVO_.l2NetworkUuid, uuid) + .eq(L2NetworkHostRefVO_.hostUuid, hostUuid).find(); + if (ref != null) { + ref.setAttachStatus(status); + updated.add(ref); + } else { + L2NetworkHostRefVO vo = new L2NetworkHostRefVO(); + vo.setHostUuid(hostUuid); + vo.setL2NetworkUuid(uuid); + vo.setL2ProviderType(providerType); + vo.setAttachStatus(status); + newAdded.add(vo); + } + } + + if (!newAdded.isEmpty()) { + dbf.persistCollection(newAdded); + } + + if (!updated.isEmpty()) { + dbf.updateCollection(updated); + } + } + + public L2NetworkHostRefInventory getL2NetworkHostRef(String l2NetworkUuid, String hostUuid) { + L2NetworkHostRefVO ref = Q.New(L2NetworkHostRefVO.class) + .eq(L2NetworkHostRefVO_.l2NetworkUuid, l2NetworkUuid) + .eq(L2NetworkHostRefVO_.hostUuid, hostUuid).find(); + if (ref == null) { + return null; + } else { + return L2NetworkHostRefInventory.valueOf(ref); + } + } + + public static Set getHostsByL2NetworkAttachedCluster(L2NetworkInventory l2NetworkInventory) { + return new HashSet<>(Q.New(HostVO.class) + .in(HostVO_.clusterUuid, l2NetworkInventory.getAttachedClusterUuids()) + .notIn(HostVO_.state,asList(HostState.PreMaintenance, HostState.Maintenance)) + .eq(HostVO_.status, HostStatus.Connected).list()); + } +} diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkManager.java b/network/src/main/java/org/zstack/network/l2/L2NetworkManager.java index f9a42811f73..fa6211b20dd 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NetworkManager.java +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkManager.java @@ -1,14 +1,18 @@ package org.zstack.network.l2; import org.zstack.header.host.HypervisorType; -import org.zstack.header.network.l2.L2NetworkAttachClusterExtensionPoint; -import org.zstack.header.network.l2.L2NetworkFactory; -import org.zstack.header.network.l2.L2NetworkRealizationExtensionPoint; -import org.zstack.header.network.l2.L2NetworkType; +import org.zstack.header.network.l2.*; public interface L2NetworkManager { L2NetworkFactory getL2NetworkFactory(L2NetworkType type); + L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, VSwitchType vSwitchType, HypervisorType hvType); + + L2NetworkRealizationExtensionPoint getRealizationExtension(L2ProviderType providerType); + L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, HypervisorType hvType); + + L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, HypervisorType hvType, String providerType); + L2NetworkAttachClusterExtensionPoint getAttachClusterExtension(L2NetworkType l2Type, HypervisorType hvType); } diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkManagerImpl.java b/network/src/main/java/org/zstack/network/l2/L2NetworkManagerImpl.java index e53c1452f70..78b64e5ee7a 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NetworkManagerImpl.java +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkManagerImpl.java @@ -54,7 +54,8 @@ public class L2NetworkManagerImpl extends AbstractService implements L2NetworkMa private ResourceConfigFacade rcf; private Map l2NetworkFactories = Collections.synchronizedMap(new HashMap()); - private Map> realizationExts = new HashMap<>(); + private Map>> realizationExts = new HashMap<>(); + private final Map l2ProviderMap = new HashMap<>(); private Map> attachClusterExts = new HashMap<>(); private List createExtensions = new ArrayList(); private static final Set allowedMessageAfterSoftDeletion = new HashSet(); @@ -109,7 +110,7 @@ private List getClusterCandidates(APIGetCandidateClustersForAt String l2Uuid = msg.getL2NetworkUuid(); L2NetworkVO l2NetworkVO = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, l2Uuid).find(); - if (l2NetworkVO == null || l2NetworkVO.getType().equals("VxlanNetwork")) { + if (l2NetworkVO == null || l2NetworkVO.getType().equals(L2NetworkConstant.VXLAN_NETWORK_TYPE)) { return new ArrayList<>(); } @@ -146,30 +147,35 @@ private List getClusterCandidates(APIGetCandidateClustersForAt return ret; } - private boolean canAttachL2ToThisCluster(L2NetworkVO l2NetworkVO, ClusterVO clusterVO) { + private boolean ovsDpdkSupport(ClusterVO clusterVO) { + String memAccessMode = "private"; - String vSwitchType = l2NetworkVO.getvSwitchType(); - if (vSwitchType.equals(L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK)) { + ResourceConfig memAccess = rcf.getResourceConfig("premiumCluster.memAccess.mode"); + if (memAccess != null) { + memAccessMode = memAccess.getResourceConfigValue(clusterVO.getUuid(), String.class); + } - String memAccessMode = "private"; + ResourceConfig numa = rcf.getResourceConfig("vm.numa"); + boolean isNumaEnable = numa.getResourceConfigValue(clusterVO.getUuid(), Boolean.class); - ResourceConfig memAccess = rcf.getResourceConfig("premiumCluster.memAccess.mode"); - if (memAccess != null) { - memAccessMode = memAccess.getResourceConfigValue(clusterVO.getUuid(), String.class); - } + boolean isOvsDpdkSup = false; + ResourceConfig ovsDpdkSup = rcf.getResourceConfig("premiumCluster.network.ovsdpdk"); + if (ovsDpdkSup != null) { + isOvsDpdkSup = ovsDpdkSup.getResourceConfigValue(clusterVO.getUuid(), Boolean.class); + } - ResourceConfig numa = rcf.getResourceConfig("vm.numa"); - boolean isNumaEnable = numa.getResourceConfigValue(clusterVO.getUuid(), Boolean.class); + if (memAccessMode.equals("private") || !isNumaEnable || !isOvsDpdkSup){ + return false; + } - boolean isOvsDpdkSup = false; - ResourceConfig ovsDpdkSup = rcf.getResourceConfig("premiumCluster.network.ovsdpdk"); - if (ovsDpdkSup != null) { - isOvsDpdkSup = ovsDpdkSup.getResourceConfigValue(clusterVO.getUuid(), Boolean.class); - } + return true; + } - if (memAccessMode.equals("private") || !isNumaEnable || !isOvsDpdkSup){ - return false; - } + private boolean canAttachL2ToThisCluster(L2NetworkVO l2NetworkVO, ClusterVO clusterVO) { + + String vSwitchType = l2NetworkVO.getvSwitchType(); + if (vSwitchType.equals(L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK) && !ovsDpdkSupport(clusterVO)) { + return false; } StringBuilder sqlBuilder = new StringBuilder(); @@ -252,24 +258,7 @@ private List getCandidateL2ForAttachingCluster(String clusterUuid .contains(l2.getUuid())) .collect(Collectors.toList()); - //if cluster set memeAccess to 'private', filter l2 with OVSDPDK vSwitch type - String memAccessMode = "private"; - - ResourceConfig memAccess = rcf.getResourceConfig("premiumCluster.memAccess.mode"); - if (memAccess != null) { - memAccessMode = memAccess.getResourceConfigValue(clusterVO.getUuid(), String.class); - } - - ResourceConfig numa = rcf.getResourceConfig("vm.numa"); - boolean isNumaEnable = numa.getResourceConfigValue(clusterVO.getUuid(), Boolean.class); - - boolean isOvsDpdkSup = false; - ResourceConfig ovsDpdkSup = rcf.getResourceConfig("premiumCluster.network.ovsdpdk"); - if (ovsDpdkSup != null) { - isOvsDpdkSup = ovsDpdkSup.getResourceConfigValue(clusterVO.getUuid(), Boolean.class); - } - - if (memAccessMode.equals("private") || !isNumaEnable || !isOvsDpdkSup) { + if (!ovsDpdkSupport(clusterVO)) { final List DpdkL2s = SQL.New("select distinct l2 from L2NetworkVO l2 where" + " l2.vSwitchType = :l2vSwitchType") .param("l2vSwitchType", "OvsDpdk") @@ -384,7 +373,7 @@ private void classifyL2(List allL2s, List noVlanL2s, vlanL2s.add(l2); } else if (l2.getType().equals(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE)) { noVlanL2s.add(l2); - } else if (l2.getType().equals("VxlanNetworkPool") || l2.getType().equals("HardwareVxlanNetworkPool")) { + } else if (l2.getType().equals(L2NetworkConstant.VXLAN_NETWORK_POOL_TYPE) || l2.getType().equals(L2NetworkConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE)) { vxlanL2s.add(l2); } } @@ -393,11 +382,6 @@ private void classifyL2(List allL2s, List noVlanL2s, private void handle(APIGetVSwitchTypesMsg msg) { List vSwitchTypes = new ArrayList(); - /* maybe we should get supported vSwitch type according to the L2Network type. - * L2NetworkFactory factory = getL2NetworkFactory(L2NetworkType.valueOf(msg.getType())); - * APIGetVSwitchTypesReply reply = new APIGetVSwitchTypesReply(); - * reply.setVSwitchTypes(factory.getVSwitchTypes()); - */ vSwitchTypes.addAll(VSwitchType.getAllTypeNames()); APIGetVSwitchTypesReply reply = new APIGetVSwitchTypesReply(); reply.setVSwitchTypes(vSwitchTypes); @@ -460,6 +444,8 @@ private void handle(APICreateL2NetworkMsg msg) { vo.setvSwitchType(vSwitchType.toString()); vo.setZoneUuid(msg.getZoneUuid()); vo.setAccountUuid(msg.getSession().getAccountUuid()); + vo.setIsolated(msg.getIsolated()); + vo.setPvlan(msg.getPvlan()); factory.createL2Network(vo, msg, new ReturnValueCompletion(msg) { @Override public void success(L2NetworkInventory returnValue) { @@ -515,20 +501,49 @@ public L2NetworkFactory getL2NetworkFactory(L2NetworkType type) { } @Override - public L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, HypervisorType hvType) { - Map map = realizationExts.get(l2Type); + public L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, VSwitchType vSwitchType, HypervisorType hvType) { + Map> map = realizationExts.get(l2Type); if (map == null) { throw new IllegalArgumentException(String.format("Cannot find L2NetworkRealizationExtensionPoint supporting L2NetworkType[%s]", l2Type)); } - L2NetworkRealizationExtensionPoint extp = map.get(hvType); - if (extp == null) { + Map vSwitchTypeL2ExtMap = map.get(hvType); + if (vSwitchTypeL2ExtMap == null) { throw new IllegalArgumentException(String.format("Cannot find L2NetworkRealizationExtensionPoint for L2NetworkType[%s] supporting hypervisor[%s]", l2Type, hvType)); } + L2NetworkRealizationExtensionPoint extp = vSwitchTypeL2ExtMap.get(vSwitchType); + if (extp == null) { + throw new IllegalArgumentException(String.format("Cannot find L2NetworkRealizationExtensionPoint for L2NetworkType[%s] vSwitch type[%s] supporting hypervisor[%s]", l2Type, vSwitchType,hvType)); + } + return extp; } + @Override + public L2NetworkRealizationExtensionPoint getRealizationExtension(L2ProviderType providerType) { + L2NetworkRealizationExtensionPoint extp = l2ProviderMap.get(providerType); + if (extp == null) { + throw new IllegalArgumentException(String.format("Cannot find L2NetworkRealizationExtensionPoint for L2ProviderType[%s]", providerType)); + } + + return extp; + } + + @Override + public L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, HypervisorType hvType) { + return null; + } + + @Override + public L2NetworkRealizationExtensionPoint getRealizationExtension(L2NetworkType l2Type, HypervisorType hvType, String providerType) { + if (providerType == null) { + return getRealizationExtension(l2Type, hvType); + } + + return getRealizationExtension(L2ProviderType.valueOf(providerType)); + } + @Override public L2NetworkAttachClusterExtensionPoint getAttachClusterExtension(L2NetworkType l2Type, HypervisorType hvType) { Map map = attachClusterExts.get(l2Type); @@ -557,12 +572,31 @@ private void populateExtensions() { } for (L2NetworkRealizationExtensionPoint extp : pluginRgty.getExtensionList(L2NetworkRealizationExtensionPoint.class)) { - Map map = realizationExts.get(extp.getSupportedL2NetworkType()); + Map> map = realizationExts.get(extp.getSupportedL2NetworkType()); if (map == null) { - map = new HashMap(1); + map = new HashMap>(1); realizationExts.put(extp.getSupportedL2NetworkType(), map); } - map.put(extp.getSupportedHypervisorType(), extp); + Map vSwitchL2ExtMap = map.get(extp.getSupportedHypervisorType()); + if (vSwitchL2ExtMap == null) { + vSwitchL2ExtMap = new HashMap(1); + map.put(extp.getSupportedHypervisorType(), vSwitchL2ExtMap); + } + vSwitchL2ExtMap.put(extp.getSupportedVSwitchType(), extp); + } + + for (L2NetworkRealizationExtensionPoint extp : pluginRgty.getExtensionList(L2NetworkRealizationExtensionPoint.class)) { + L2ProviderType providerType = extp.getL2ProviderType(); + if (providerType == null) { + continue; + } + + L2NetworkRealizationExtensionPoint old = l2ProviderMap.get(providerType); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate l2 network provider for type[%s]", providerType)); + } + logger.debug(String.format("add exp: %s for l2 provideType:%s", extp.getClass().getSimpleName(), providerType)); + l2ProviderMap.put(providerType, extp); } for (L2NetworkAttachClusterExtensionPoint extp : pluginRgty.getExtensionList(L2NetworkAttachClusterExtensionPoint.class)) { diff --git a/network/src/main/java/org/zstack/network/l2/L2NetworkSystemTags.java b/network/src/main/java/org/zstack/network/l2/L2NetworkSystemTags.java new file mode 100644 index 00000000000..77d38d03e69 --- /dev/null +++ b/network/src/main/java/org/zstack/network/l2/L2NetworkSystemTags.java @@ -0,0 +1,11 @@ +package org.zstack.network.l2; + +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.tag.TagDefinition; +import org.zstack.tag.PatternedSystemTag; + +@TagDefinition +public class L2NetworkSystemTags { + public static String L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN = "SdnControllerUuid"; + public static PatternedSystemTag L2_NETWORK_SDN_CONTROLLER_UUID = new PatternedSystemTag(String.format("SdnControllerUuid::{%s}", L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN), L2NetworkVO.class); +} diff --git a/network/src/main/java/org/zstack/network/l2/L2NoVlanL2NetworkFactory.java b/network/src/main/java/org/zstack/network/l2/L2NoVlanL2NetworkFactory.java index 0952bf1b098..3d5720ccd26 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NoVlanL2NetworkFactory.java +++ b/network/src/main/java/org/zstack/network/l2/L2NoVlanL2NetworkFactory.java @@ -1,10 +1,18 @@ package org.zstack.network.l2; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.Component; +import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.network.l2.*; import org.zstack.network.service.NetworkServiceGlobalConfig; import org.zstack.resourceconfig.ResourceConfigFacade; @@ -12,10 +20,9 @@ import org.zstack.utils.data.FieldPrinter; import org.zstack.utils.logging.CLogger; -import java.util.ArrayList; -import java.util.List; +import java.util.Map; -public class L2NoVlanL2NetworkFactory implements L2NetworkFactory, Component, L2NetworkDefaultMtu, L2NetworkGetVniExtensionPoint, VSwitch { +public class L2NoVlanL2NetworkFactory implements L2NetworkFactory, Component, L2NetworkDefaultMtu, L2NetworkGetVniExtensionPoint { private static L2NetworkType type = new L2NetworkType(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE); private static CLogger logger = Utils.getLogger(L2NoVlanL2NetworkFactory.class); private static FieldPrinter printer = Utils.getFieldPrinter(); @@ -26,14 +33,8 @@ public class L2NoVlanL2NetworkFactory implements L2NetworkFactory, Component, L2 private DatabaseFacade dbf; @Autowired private ResourceConfigFacade rcf; - - @Override - public List getVSwitchTypes() { - List vSwitchTypes = new ArrayList<>(); - vSwitchTypes.add(linuxBridge); - vSwitchTypes.add(ovsDpdk); - return vSwitchTypes; - } + @Autowired + protected PluginRegistry pluginRgty; @Override public L2NetworkType getType() { @@ -41,11 +42,65 @@ public L2NetworkType getType() { } @Override - public void createL2Network(L2NetworkVO vo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { - vo = dbf.persistAndRefresh(vo); - L2NetworkInventory inv = L2NetworkInventory.valueOf(vo); - logger.debug("Successfully created NoVlanL2Network: " + printer.print(inv)); - completion.success(inv); + public void createL2Network(L2NetworkVO vo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + + FlowChain chain = new SimpleFlowChain(); + chain.setName("create-no-vlan-network"); + chain.then(new Flow() { + String __name__ = "write-db"; + @Override + public void run(FlowTrigger trigger, Map data) { + dbf.persist(vo); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + dbf.removeByPrimaryKey(vo.getUuid(), L2NetworkVO.class); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "create-l2-network-extension"; + + @Override + public void run(FlowTrigger trigger, Map data) { + new While<>(pluginRgty.getExtensionList(L2NetworkCreateExtensionPoint.class)) + .each((exp, wcompl) -> exp.postCreateL2Network(L2NetworkInventory.valueOf(vo), msg, new Completion(trigger) { + @Override + public void success() { + wcompl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcompl.addError(errorCode); + wcompl.allDone(); + } + })).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + L2NetworkInventory inv = L2NetworkInventory.valueOf( + dbf.findByUuid(vo.getUuid(), L2NetworkVO.class)); + logger.debug("Successfully created NoVlanL2Network: " + printer.print(inv)); + completion.success(inv); + } + }).start(); } @Override diff --git a/network/src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java b/network/src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java index 6f9b29d12ed..c3449db0145 100755 --- a/network/src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java +++ b/network/src/main/java/org/zstack/network/l2/L2NoVlanNetwork.java @@ -9,6 +9,7 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.CloudBusListCallBack; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; @@ -16,6 +17,8 @@ import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; @@ -34,10 +37,16 @@ import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.network.l3.ServiceTypeExtensionPoint; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import javax.transaction.Transactional; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; import static java.util.Arrays.asList; import static org.zstack.core.Platform.*; @@ -45,6 +54,7 @@ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class L2NoVlanNetwork implements L2Network { private static final CLogger logger = Utils.getLogger(L2NoVlanNetwork.class); + private static final L2NetworkHostHelper l2NetworkHostHelper = new L2NetworkHostHelper(); @Autowired protected L2NetworkExtensionPointEmitter extpEmitter; @@ -55,6 +65,8 @@ public class L2NoVlanNetwork implements L2Network { @Autowired protected L2NetworkManager l2Mgr; @Autowired + protected PluginRegistry pluginRgty; + @Autowired protected CascadeFacade casf; @Autowired protected ErrorFacade errf; @@ -74,6 +86,10 @@ protected L2NetworkInventory getSelfInventory() { return L2NetworkInventory.valueOf(self); } + public VSwitchType getVSwitchType() { + return VSwitchType.valueOf(self.getvSwitchType()); + } + @Override public void handleMessage(Message msg) { try { @@ -101,6 +117,8 @@ private void handleLocalMessage(Message msg) { handle((DeleteL2NetworkMsg) msg); } else if (msg instanceof L2NetworkDetachFromClusterMsg) { handle((L2NetworkDetachFromClusterMsg) msg); + } else if (msg instanceof AttachL2NetworkToClusterMsg) { + handle((AttachL2NetworkToClusterMsg) msg); } else { bus.dealWithUnknownMessage(msg); } @@ -203,8 +221,27 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } + private void syncManagementServiceType(ServiceTypeExtensionPoint ext, L2NetworkVO l2NetworkVO, List hostUuids, boolean isDelete) { + String l2NetworkType = l2NetworkVO.getType(); + switch (l2NetworkType) { + case L2NetworkConstant.VXLAN_NETWORK_TYPE: + case L2NetworkConstant.HARDWARE_VXLAN_NETWORK_TYPE: + ext.syncManagementServiceTypeExtensionPoint(hostUuids, "vxlan" + l2NetworkVO.getVirtualNetworkId(), null, isDelete); + break; + + case L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE: + case L2NetworkConstant.L2_VLAN_NETWORK_TYPE: + ext.syncManagementServiceTypeExtensionPoint(hostUuids, l2NetworkVO.getPhysicalInterface(), l2NetworkVO.getVirtualNetworkId(), isDelete); + break; + + default: + break; + } + } + private void handle(DetachL2NetworkFromClusterMsg msg) { - if (!L2NetworkGlobalConfig.DeleteL2BridgePhysically.value(Boolean.class)) { + if (!L2NetworkGlobalConfig.DeleteL2BridgePhysically.value(Boolean.class) || + !getVSwitchType().isAttachToCluster()) { SQL.New(L2NetworkClusterRefVO.class) .eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()) @@ -220,6 +257,17 @@ private void handle(DetachL2NetworkFromClusterMsg msg) { new Completion(msg) { @Override public void success() { + L2NetworkVO l2NetworkVO = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); + List hostUuids = Q.New(HostVO.class).select(HostVO_.uuid) + .eq(HostVO_.clusterUuid, msg.getClusterUuid()).listValues(); + boolean isExistSystemL3 = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.system, true) + .eq(L3NetworkVO_.l2NetworkUuid, l2NetworkVO.getUuid()).isExists(); + if (isExistSystemL3) { + for (ServiceTypeExtensionPoint ext : pluginRgty.getExtensionList(ServiceTypeExtensionPoint.class)) { + syncManagementServiceType(ext, l2NetworkVO, hostUuids, true); + } + } + SQL.New(L2NetworkClusterRefVO.class) .eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()) @@ -239,7 +287,11 @@ public void fail(ErrorCode errorCode) { private void handle(final PrepareL2NetworkOnHostMsg msg) { final PrepareL2NetworkOnHostReply reply = new PrepareL2NetworkOnHostReply(); - prepareL2NetworkOnHosts(Arrays.asList(msg.getHost()), new Completion(msg) { + L2NetworkClusterRefVO ref = Q.New(L2NetworkClusterRefVO.class) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()) + .eq(L2NetworkClusterRefVO_.clusterUuid, msg.getHost().getClusterUuid()).find(); + + prepareL2NetworkOnHosts(Arrays.asList(msg.getHost()), ref.getL2ProviderType(), new Completion(msg) { @Override public void success() { bus.reply(msg, reply); @@ -261,8 +313,15 @@ private void handle(final CheckL2NetworkOnHostMsg msg) { final HypervisorType hvType = HypervisorType.valueOf(htype); final L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); + L2NetworkHostRefInventory hostRef = l2NetworkHostHelper.getL2NetworkHostRef(msg.getL2NetworkUuid(), msg.getHostUuid()); + String providerType = null; + if (hostRef != null) { + providerType = hostRef.getL2ProviderType(); + } + final CheckL2NetworkOnHostReply reply = new CheckL2NetworkOnHostReply(); - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, hvType); + // TODO: this should be fixed + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, getVSwitchType(), hvType); ext.check(getSelfInventory(), msg.getHostUuid(), new Completion(msg) { @Override public void success() { @@ -281,19 +340,63 @@ private void handle(L2NetworkDeletionMsg msg) { L2NetworkInventory inv = L2NetworkInventory.valueOf(self); extpEmitter.beforeDelete(inv); L2NetworkDeletionReply reply = new L2NetworkDeletionReply(); - deleteHook(new Completion(msg) { + + FlowChain chain = new SimpleFlowChain(); + chain.setName("delete-l2-network-" + inv.getUuid()); + chain.then(new NoRollbackFlow() { + String __name__ = "delete-l2-network-extension"; + @Override - public void success() { - extpEmitter.afterDelete(inv); - bus.reply(msg, reply); + public void run(FlowTrigger trigger, Map data) { + new While<>(pluginRgty.getExtensionList(L2NetworkDeleteExtensionPoint.class)) + .each((exp, wcompl) -> exp.deleteL2Network(inv, new NoErrorCompletion(trigger) { + @Override + public void done() { + wcompl.done(); + } + })).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); } + }).then(new NoRollbackFlow() { + String __name__ = "delete-l2-network"; @Override - public void fail(ErrorCode errorCode) { - reply.setError(errorCode); + public void run(FlowTrigger trigger, Map data) { + deleteHook(new Completion(msg) { + @Override + public void success() { + extpEmitter.afterDelete(inv); + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + trigger.fail(errorCode); + } + }); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + reply.setError(errCode); bus.reply(msg, reply); } - }); + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + } + }).start(); } private void handleApiMessage(APIMessage msg) { @@ -305,11 +408,64 @@ private void handleApiMessage(APIMessage msg) { handle((APIDetachL2NetworkFromClusterMsg) msg); } else if (msg instanceof APIUpdateL2NetworkMsg) { handle((APIUpdateL2NetworkMsg) msg); + } else if (msg instanceof APIChangeL2NetworkVlanIdMsg) { + handle((APIChangeL2NetworkVlanIdMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } + + private void handle(APIChangeL2NetworkVlanIdMsg msg){ + APIChangeL2NetworkVlanIdEvent event = new APIChangeL2NetworkVlanIdEvent(msg.getId()); + if (msg.getVlan() == null + && msg.getType().equals(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE) + && self.getVirtualNetworkId().equals(0)) { + event.setInventory(getSelfInventory()); + bus.publish(event); + return; + } + if (msg.getVlan() != null + && msg.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE) + && self.getVirtualNetworkId().equals(msg.getVlan())) { + event.setInventory(getSelfInventory()); + bus.publish(event); + return; + } + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format("change-l2-network-%s-vlan", msg.getL2NetworkUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + changeL2NetworkVlanId(msg, new Completion(chain) { + @Override + public void success() { + changeL2NetworkVlanIdInDb(msg); + extpEmitter.afterUpdate(getSelfInventory()); + event.setInventory(getSelfInventory()); + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + private void handle(APIUpdateL2NetworkMsg msg) { boolean update = false; if (msg.getName() != null) { @@ -355,11 +511,16 @@ public void fail(ErrorCode errorCode) { }); } - protected void realizeNetwork(String hostUuid, String htype, Completion completion) { + protected void updateVlanNetwork(L2NetworkInventory oldl2, L2NetworkInventory newl2, String hostUuid, String htype, Completion completion) { final HypervisorType hvType = HypervisorType.valueOf(htype); final L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); - - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, hvType); + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, getVSwitchType(), hvType); + ext.update(oldl2, newl2, hostUuid, completion); + } + protected void realizeNetwork(String hostUuid, String htype, String providerType, Completion completion) { + final HypervisorType hvType = HypervisorType.valueOf(htype); + final L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, getVSwitchType(), hvType); ext.realize(getSelfInventory(), hostUuid, completion); } @@ -375,10 +536,154 @@ protected void afterAttachNetwork(String hostUuid, String htype, Completion comp } } - private void prepareL2NetworkOnHosts(final List hosts, final Completion completion) { + @Transactional + private void changeL2NetworkVlanIdInDb(final APIChangeL2NetworkVlanIdMsg msg) { + String currentType = self.getType(); + String targetType = msg.getType(); + int targetVlan = msg.getVlan() == null ? 0 : msg.getVlan(); + + if (!currentType.equals(targetType)) { + // change to L2VlanNetwork or L2NoVlanNetwork + L2NetworkVO l2Vo = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, self.getUuid()).find(); + l2Vo.setType(targetType); + l2Vo.setVirtualNetworkId(targetVlan); + self = dbf.updateAndRefresh(l2Vo); + // can not operate L2VlanNetworkVO directly due to it extends from L2NetworkVO + // use native sql to insert or delete + if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(targetType)) { + // L2VlanNetwork change to L2NoVlanNetwork + dbf.getEntityManager().createNativeQuery( + String.format("insert into L2VlanNetworkVO (uuid, vlan) " + + "values ('%s', %d)", l2Vo.getUuid(), targetVlan) + ).executeUpdate(); + } else if (L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(targetType)) { + // L2NoVlanNetwork change to L2VlanNetwork + dbf.getEntityManager().createNativeQuery( + String.format("delete from L2VlanNetworkVO where uuid = '%s'", l2Vo.getUuid()) + ).executeUpdate(); + } + } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(currentType)) { + // update L2VlanNetwork vlan id + L2VlanNetworkVO l2VlanNetworkVO = Q.New(L2VlanNetworkVO.class).eq(L2VlanNetworkVO_.uuid, self.getUuid()).find(); + l2VlanNetworkVO.setVirtualNetworkId(targetVlan); + l2VlanNetworkVO.setVlan(targetVlan); + self = dbf.updateAndRefresh(l2VlanNetworkVO); + } + } + + private void changeL2NetworkVlanId(final APIChangeL2NetworkVlanIdMsg msg, final Completion completion) { + final FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("change-l2-%s-vlan-on-hosts", self.getUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + final Map updatedHosts = new ConcurrentHashMap<>(); + L2NetworkInventory oldInv = self.toInventory(); + L2NetworkInventory newInv = self.toInventory(); + if (msg.getType() != null) { + newInv.setType(msg.getType()); + } + if (msg.getVlan() != null) { + newInv.setVirtualNetworkId(msg.getVlan()); + } + + flow(new Flow() { + String __name__ = "update-l2-network-vlan"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + new While<>(L2NetworkHostHelper.getHostsByL2NetworkAttachedCluster(newInv)).step((host, whileCompletion) -> { + updateVlanNetwork(oldInv, newInv, host.getUuid(), host.getHypervisorType(), new Completion(whileCompletion) { + @Override + public void success() { + logger.debug(String.format("successfully updated l2 network vlan on host[uuid:%s]", host.getUuid())); + updatedHosts.put(host, true); + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("update l2 network in host:[%s] failed", host.getUuid())); + updatedHosts.put(host, false); + whileCompletion.addError(errorCode); + whileCompletion.done(); + } + }); + }, 5).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + } else { + trigger.next(); + } + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + List successfulHosts = updatedHosts.entrySet().stream() + .filter(Map.Entry::getValue) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + if(successfulHosts.isEmpty()) { + trigger.rollback(); + return; + } + logger.debug(String.format("rollback l2 network vlan changes on %d hosts", successfulHosts.size())); + new While<>(successfulHosts).step((host, whileCompletion) -> { + logger.debug(String.format("rolling back l2 network vlan on host[uuid:%s]", host.getUuid())); + updateVlanNetwork(newInv, oldInv, host.getUuid(), host.getHypervisorType(), new Completion(whileCompletion) { + @Override + public void success() { + logger.debug(String.format("successfully rolled back l2 network vlan on host[uuid:%s]", host.getUuid())); + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("failed to rollback l2 network vlan on host[uuid:%s], because %s", + host.getUuid(), errorCode.toString())); + whileCompletion.done(); + } + }); + }, 5).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + logger.debug("finished rolling back l2 network vlan changes"); + trigger.rollback(); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + protected void prepareL2NetworkOnHosts(final List hosts, String providerType, final Completion completion) { FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName(String.format("prepare-l2-%s-on-hosts", self.getUuid())); chain.then(new NoRollbackFlow() { + @Override + public boolean skip(Map data) { + return !getVSwitchType().isAttachToCluster(); + } + @Override public void run(final FlowTrigger trigger, Map data) { List cmsgs = new ArrayList(); @@ -410,30 +715,41 @@ public void run(List replies) { }); } }).then(new NoRollbackFlow() { - private void realize(final Iterator it, final FlowTrigger trigger) { - if (!it.hasNext()) { - trigger.next(); - return; - } - HostInventory host = it.next(); - realizeNetwork(host.getUuid(), host.getHypervisorType(), new Completion(trigger) { - @Override - public void success() { - realize(it, trigger); - } + @Override + public boolean skip(Map data) { + return !getVSwitchType().isAttachToCluster(); + } + + @Override + public void run(final FlowTrigger trigger, Map data) { + new While<>(hosts).step((host, whileCompletion) -> { + realizeNetwork(host.getUuid(), host.getHypervisorType(), providerType, new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("attach l2 network to host:[%s] failed", host.getUuid())); + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + },L2NetworkConstant.MAX_PARALLEL_HOST_MSG).run(new WhileDoneCompletion(trigger) { @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + } else { + trigger.next(); + } } + }); } - @Override - public void run(FlowTrigger trigger, Map data) { - realize(hosts.iterator(), trigger); - } }).then(new NoRollbackFlow() { String __name__ = "after-l2-network-attached"; @@ -475,17 +791,51 @@ public void handle(ErrorCode errCode, Map data) { } private void handle(final APIAttachL2NetworkToClusterMsg msg) { + AttachL2NetworkToClusterMsg amsg = new AttachL2NetworkToClusterMsg(); + final APIAttachL2NetworkToClusterEvent evt = new APIAttachL2NetworkToClusterEvent(msg.getId()); + + amsg.setL2NetworkUuid(msg.getL2NetworkUuid()); + amsg.setClusterUuid(msg.getClusterUuid()); + amsg.setL2ProviderType(msg.getL2ProviderType()); + + bus.makeTargetServiceIdByResourceUuid(amsg, L2NetworkConstant.SERVICE_ID, amsg.getL2NetworkUuid()); + bus.send(amsg, new CloudBusCallBack(amsg) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + evt.setInventory(getSelfInventory()); + bus.publish(evt); + } else { + evt.setError(err(L2Errors.ATTACH_ERROR, reply.getError(),"attach l2 network failed:%s", reply.getError())); + bus.publish(evt); + } + } + }); + + } + + private void handle(final AttachL2NetworkToClusterMsg msg) { thdf.chainSubmit(new ChainTask(msg) { @Override public String getSyncSignature() { - return String.format("attach-l2-network-to-cluster-%s", msg.getClusterUuid()); + return String.format("attach-l2-network-%s-to-cluster-%s", msg.getL2NetworkUuid(), msg.getClusterUuid()); } @Override public void run(SyncTaskChain chain) { - attachL2NetworkToCluster(msg, new NoErrorCompletion(msg,chain) { + AttachL2NetworkToClusterReply reply = new AttachL2NetworkToClusterReply(); + + attachL2NetworkToCluster(msg, new Completion(chain) { @Override - public void done() { + public void success() { + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); chain.next(); } }); @@ -571,15 +921,11 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } - private void attachL2NetworkToCluster(final APIAttachL2NetworkToClusterMsg msg, final NoErrorCompletion completion){ - final APIAttachL2NetworkToClusterEvent evt = new APIAttachL2NetworkToClusterEvent(msg.getId()); - + private void attachL2NetworkToCluster(final AttachL2NetworkToClusterMsg msg, final Completion completion){ long count = Q.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()).count(); if (count != 0) { - evt.setInventory(self.toInventory()); - bus.publish(evt); - completion.done(); + completion.success(); return; } @@ -633,37 +979,46 @@ protected void scripts() { }.execute(); + L2NetworkVO l2NetworkVO = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); + List hostUuids = Q.New(HostVO.class).select(HostVO_.uuid) + .eq(HostVO_.clusterUuid, msg.getClusterUuid()).listValues(); + boolean isExistSystemL3 = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.system, true) + .eq(L3NetworkVO_.l2NetworkUuid, l2NetworkVO.getUuid()).isExists(); + if (isExistSystemL3) { + for (ServiceTypeExtensionPoint ext : pluginRgty.getExtensionList(ServiceTypeExtensionPoint.class)) { + syncManagementServiceType(ext, l2NetworkVO, hostUuids, false); + } + } + List hosts = Q.New(HostVO.class).eq(HostVO_.clusterUuid,msg.getClusterUuid()) .notIn(HostVO_.state,asList(HostState.PreMaintenance, HostState.Maintenance)) .eq(HostVO_.status,HostStatus.Connected).list(); List hvinvs = HostInventory.valueOf(hosts); - prepareL2NetworkOnHosts(hvinvs, new Completion(msg,completion) { + prepareL2NetworkOnHosts(hvinvs, msg.getL2ProviderType(), new Completion(msg,completion) { @Override public void success() { L2NetworkClusterRefVO rvo = new L2NetworkClusterRefVO(); rvo.setClusterUuid(msg.getClusterUuid()); rvo.setL2NetworkUuid(self.getUuid()); + rvo.setL2ProviderType(msg.getL2ProviderType()); dbf.persist(rvo); logger.debug(String.format("successfully attached L2Network[uuid:%s] to cluster [uuid:%s]", self.getUuid(), msg.getClusterUuid())); self = dbf.findByUuid(self.getUuid(), L2NetworkVO.class); - evt.setInventory(self.toInventory()); - bus.publish(evt); - completion.done(); + completion.success(); } @Override public void fail(ErrorCode errorCode) { - evt.setError(err(L2Errors.ATTACH_ERROR, errorCode, errorCode.getDetails())); - bus.publish(evt); - completion.done(); + completion.fail(errorCode); } }); } @Override public void deleteHook(Completion completion) { - if (L2NetworkGlobalConfig.DeleteL2BridgePhysically.value(Boolean.class)) { + if (L2NetworkGlobalConfig.DeleteL2BridgePhysically.value(Boolean.class) + && getVSwitchType().isAttachToCluster()) { deleteL2Bridge(completion); } else { completion.success(); @@ -674,7 +1029,7 @@ protected void deleteL2Bridge(Completion completion) { deleteL2Bridge(null, completion); } - private void deleteL2Bridge(List clusterUuids, Completion completion) { + protected void deleteL2Bridge(List clusterUuids, Completion completion) { if (clusterUuids == null) { L2NetworkInventory l2NetworkInventory = getSelfInventory(); clusterUuids = l2NetworkInventory.getAttachedClusterUuids(); @@ -685,15 +1040,27 @@ private void deleteL2Bridge(List clusterUuids, Completion completion) { } } - List hosts = Q.New(HostVO.class) - .in(HostVO_.clusterUuid, clusterUuids) - .list(); + Map> providerClusterMap = new HashMap<>(); + for (L2NetworkClusterRefVO ref : self.getAttachedClusterRefs()) { + if (!clusterUuids.contains(ref.getClusterUuid())) { + continue; + } + + providerClusterMap.computeIfAbsent(ref.getL2ProviderType(), k -> new ArrayList<>()).add(ref.getClusterUuid()); + } + + List hostss = new ArrayList<>(); + for (Map.Entry> e : providerClusterMap.entrySet()) { + List hosts = Q.New(HostVO.class) + .in(HostVO_.clusterUuid, e.getValue()).list(); + hostss.addAll(hosts); + } + List errs = new ArrayList<>(); - new While<>(hosts).step((host,compl) -> { + new While<>(hostss).step((host,compl) -> { HypervisorType hvType = HypervisorType.valueOf(host.getHypervisorType()); L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); - - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, hvType); + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, getVSwitchType(), hvType); ext.delete(getSelfInventory(), host.getUuid(), new Completion(compl){ @Override public void success() { @@ -707,7 +1074,7 @@ public void fail(ErrorCode errorCode) { } }); - },10).run((new WhileDoneCompletion(completion) { + },L2NetworkConstant.MAX_PARALLEL_HOST_MSG).run((new WhileDoneCompletion(completion) { @Override public void done(ErrorCodeList errorCodeList) { if (errs.size() > 0) { diff --git a/network/src/main/java/org/zstack/network/l2/L2VlanNetworkFactory.java b/network/src/main/java/org/zstack/network/l2/L2VlanNetworkFactory.java index 76875dcabc8..35c34f1799a 100755 --- a/network/src/main/java/org/zstack/network/l2/L2VlanNetworkFactory.java +++ b/network/src/main/java/org/zstack/network/l2/L2VlanNetworkFactory.java @@ -1,13 +1,20 @@ package org.zstack.network.l2; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.AbstractService; import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.network.l2.*; @@ -20,6 +27,7 @@ import org.zstack.utils.logging.CLogger; import java.util.List; +import java.util.Map; public class L2VlanNetworkFactory extends AbstractService implements L2NetworkFactory, L2NetworkDefaultMtu, L2NetworkGetVniExtensionPoint { private static CLogger logger = Utils.getLogger(L2VlanNetworkFactory.class); @@ -33,6 +41,8 @@ public class L2VlanNetworkFactory extends AbstractService implements L2NetworkFa private QueryFacade qf; @Autowired private ResourceConfigFacade rcf; + @Autowired + protected PluginRegistry pluginRgty; @Override public L2NetworkType getType() { @@ -40,15 +50,72 @@ public L2NetworkType getType() { } @Override - public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { - APICreateL2VlanNetworkMsg amsg = (APICreateL2VlanNetworkMsg) msg; - L2VlanNetworkVO vo = new L2VlanNetworkVO(ovo); - vo.setVlan(amsg.getVlan()); - vo = dbf.persistAndRefresh(vo); - L2VlanNetworkInventory inv = L2VlanNetworkInventory.valueOf(vo); - String info = String.format("successfully create L2VlanNetwork, %s", JSONObjectUtil.toJsonString(inv)); - logger.debug(info); - completion.success(inv); + public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + FlowChain chain = new SimpleFlowChain(); + chain.setName("create-no-vlan-network"); + chain.then(new Flow() { + String __name__ = "write-db"; + @Override + public void run(FlowTrigger trigger, Map data) { + APICreateL2VlanNetworkMsg amsg = (APICreateL2VlanNetworkMsg) msg; + L2VlanNetworkVO vo = new L2VlanNetworkVO(ovo); + vo.setVlan(amsg.getVlan()); + vo.setVirtualNetworkId(vo.getVlan()); + dbf.persist(vo); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + dbf.removeByPrimaryKey(ovo.getUuid(), L2VlanNetworkVO.class); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "create-l2-network-extension"; + + @Override + public void run(FlowTrigger trigger, Map data) { + L2VlanNetworkInventory inv = L2VlanNetworkInventory.valueOf( + dbf.findByUuid(ovo.getUuid(), L2VlanNetworkVO.class)); + new While<>(pluginRgty.getExtensionList(L2NetworkCreateExtensionPoint.class)) + .each((exp, wcompl) -> exp.postCreateL2Network(inv, msg, new Completion(trigger) { + @Override + public void success() { + wcompl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcompl.addError(errorCode); + wcompl.allDone(); + } + })).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + L2VlanNetworkInventory inv = L2VlanNetworkInventory.valueOf( + dbf.findByUuid(ovo.getUuid(), L2VlanNetworkVO.class)); + logger.debug(String.format("Successfully created VlanL2Network[uuid:%s, name:%s]", + inv.getUuid(), inv.getName())); + completion.success(inv); + } + }).start(); + } @Override diff --git a/network/src/main/java/org/zstack/network/l2/SdnControllerCascadeExtension.java b/network/src/main/java/org/zstack/network/l2/SdnControllerCascadeExtension.java new file mode 100644 index 00000000000..2fd70fb4c7c --- /dev/null +++ b/network/src/main/java/org/zstack/network/l2/SdnControllerCascadeExtension.java @@ -0,0 +1,202 @@ +package org.zstack.network.l2; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.AbstractAsyncCascadeExtension; +import org.zstack.core.cascade.CascadeAction; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.identity.AccountInventory; +import org.zstack.header.identity.AccountVO; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.TypedQuery; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.stream.Collectors; + +public class SdnControllerCascadeExtension extends AbstractAsyncCascadeExtension { + private static final CLogger logger = Utils.getLogger(SdnControllerCascadeExtension.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + private static final String NAME = SdnControllerVO.class.getSimpleName(); + + @Override + public void asyncCascade(CascadeAction action, Completion completion) { + if (action.isActionCode(CascadeConstant.DELETION_CHECK_CODE)) { + handleDeletionCheck(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_DELETE_CODE, CascadeConstant.DELETION_FORCE_DELETE_CODE)) { + handleDeletion(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_CLEANUP_CODE)) { + handleDeletionCleanup(action, completion); + } else { + completion.success(); + } + } + + private void handleDeletionCleanup(CascadeAction action, Completion completion) { + completion.success(); + } + + private void handleDeletion(final CascadeAction action, final Completion completion) { + if (HostVO.class.getSimpleName().equals(action.getParentIssuer())) { + List hosts = action.getParentIssuerContext(); + List hostUuids = hosts.stream().map(HostInventory::getUuid).collect(Collectors.toList()); + List refVOS = Q.New(SdnControllerHostRefVO.class) + .in(SdnControllerHostRefVO_.hostUuid, hostUuids).list(); + if (refVOS.isEmpty()) { + completion.success(); + return; + } + + List msgs = new ArrayList<>(); + for (SdnControllerHostRefVO ref : refVOS) { + SdnControllerRemoveHostMsg msg = new SdnControllerRemoveHostMsg(); + msg.setSdnControllerUuid(ref.getSdnControllerUuid()); + msg.setHostUuid(ref.getHostUuid()); + msg.setvSwitchType(ref.getvSwitchType()); + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, ref.getSdnControllerUuid()); + msgs.add(msg); + } + + new While<>(msgs).each((msg, wcomp) -> { + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.debug(String.format("delete host [uuid:%s] from sdn controller[uuid:%s] failed, error:%s", + msg.getHostUuid(), msg.getSdnControllerUuid(), reply.getError().getDetails())); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + completion.success(); + } else { + completion.fail(errorCodeList.getCauses().get(0)); + } + } + }); + + return; + } + + final List sdnControllers = sdnControllerFromAction(action); + if (sdnControllers == null) { + completion.success(); + return; + } + + List msgs = new ArrayList(); + for (SdnControllerInventory sdn : sdnControllers) { + SdnControllerDeletionMsg msg = new SdnControllerDeletionMsg(); + msg.setForceDelete(action.isActionCode(CascadeConstant.DELETION_FORCE_DELETE_CODE)); + msg.setSdnControllerUuid(sdn.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, sdn.getUuid()); + msgs.add(msg); + } + + new While<>(msgs).all((msg, wcomp) -> { + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.debug(String.format("delete sdn controller failed, %s", + reply.getError().getDetails())); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + dbf.removeByPrimaryKeys(sdnControllers.stream().map(SdnControllerInventory::getUuid).collect(Collectors.toList()), SdnControllerVO.class); + completion.success(); + } + }); + } + + private void handleDeletionCheck(CascadeAction action, Completion completion) { + completion.success(); + } + + @Override + public List getEdgeNames() { + List ret = new ArrayList<>(); + ret.add(AccountVO.class.getSimpleName()); + ret.add(HostVO.class.getSimpleName()); + return ret; + } + + @Override + public String getCascadeResourceName() { + return NAME; + } + + private List sdnControllerFromAction(CascadeAction action) { + List ret = null; + if (NAME.equals(action.getParentIssuer())) { + ret = action.getParentIssuerContext(); + } else if (AccountVO.class.getSimpleName().equals(action.getParentIssuer())) { + final List auuids = CollectionUtils.transformToList((List) action.getParentIssuerContext(), new Function() { + @Override + public String call(AccountInventory arg) { + return arg.getUuid(); + } + }); + + List vos = new Callable>() { + @Override + @Transactional(readOnly = true) + public List call() { + String sql = "select d from SdnControllerVO d, AccountResourceRefVO r where d.uuid = r.resourceUuid and" + + " r.resourceType = :rtype and r.accountUuid in (:auuids)"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, SdnControllerVO.class); + q.setParameter("auuids", auuids); + q.setParameter("rtype", SdnControllerVO.class.getSimpleName()); + return q.getResultList(); + } + }.call(); + + if (!vos.isEmpty()) { + ret = SdnControllerInventory.valueOf(vos); + } + } + + return ret; + } + + @Override + public CascadeAction createActionForChildResource(CascadeAction action) { + if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { + List ctx = sdnControllerFromAction(action); + if (ctx != null) { + return action.copy().setParentIssuer(NAME).setParentIssuerContext(ctx); + } + } + + return null; + } +} diff --git a/network/src/main/java/org/zstack/network/l3/AbstractIpAllocatorStrategy.java b/network/src/main/java/org/zstack/network/l3/AbstractIpAllocatorStrategy.java index dce234c6057..cdc688470d1 100755 --- a/network/src/main/java/org/zstack/network/l3/AbstractIpAllocatorStrategy.java +++ b/network/src/main/java/org/zstack/network/l3/AbstractIpAllocatorStrategy.java @@ -16,7 +16,9 @@ import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; +import java.util.Comparator; import java.util.List; +import java.util.stream.Collectors; import static org.zstack.core.Platform.err; @@ -34,15 +36,50 @@ public abstract class AbstractIpAllocatorStrategy implements IpAllocatorStrategy @Autowired private PluginRegistry pluginRgty; - protected UsedIpInventory allocateRequiredIp(IpAllocateMessage msg) { + protected String getReqIpRangeType(IpAllocateMessage msg) { + if (msg.getIpRangeUuid() != null) { + return IpRangeHelper.getIpRangeType(msg.getIpRangeUuid()); + } else { + return IpRangeType.Normal.toString(); + } + } + + protected List getIpRanges(String ipRangeType, String l3NetworkUuid, int ipVersion, boolean needStrip) { + List iprs; + if (ipRangeType.equals(IpRangeType.Normal.toString())) { + iprs = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, l3NetworkUuid) + .eq(NormalIpRangeVO_.ipVersion, ipVersion).list(); + } else { + iprs = Q.New(AddressPoolVO.class).eq(AddressPoolVO_.l3NetworkUuid, l3NetworkUuid) + .eq(AddressPoolVO_.ipVersion, ipVersion).list(); + } + if (ipVersion == IPv6Constants.IPv4) { + if (needStrip) { + iprs = iprs.stream().filter(ipr -> IpRangeHelper.stripNetworkAndBroadcastAddress(ipr)).collect(Collectors.toList()); + } + iprs.sort(AbstractIpAllocatorStrategy::compareIpv4Range); + } else { + iprs.sort(Comparator.comparing(r -> IPv6NetworkUtils.ipv6AddressToBigInteger(r.getStartIp()))); + } + return iprs; + } + + protected List getReqIpRanges(IpAllocateMessage msg, int ipVersion) { List iprs; - /* when allocate ip address from address pool, ipRangeUuid is not null */ + if (msg.getIpRangeUuid() != null) { iprs = Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, msg.getIpRangeUuid()).list(); } else { - iprs = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) - .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv4).list(); + iprs = getIpRanges(getReqIpRangeType(msg), msg.getL3NetworkUuid(), ipVersion, false); + } + if (ipVersion == IPv6Constants.IPv4) { + iprs = iprs.stream().filter(ipr -> IpRangeHelper.stripNetworkAndBroadcastAddress(ipr)).collect(Collectors.toList()); } + return iprs; + } + + protected UsedIpInventory allocateRequiredIp(IpAllocateMessage msg) { + List iprs = getReqIpRanges(msg, IPv6Constants.IPv4); final long rip = NetworkUtils.ipv4StringToLong(msg.getRequiredIp()); IpRangeVO ipr = CollectionUtils.find(iprs, new Function() { @@ -73,15 +110,7 @@ public IpRangeVO call(IpRangeVO arg) { } protected UsedIpInventory allocateRequiredIpv6(IpAllocateMessage msg) { - List iprs; - /* when allocate ip address from address pool, ipRangeUuid is not null */ - if (msg.getIpRangeUuid() != null) { - iprs = Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, msg.getIpRangeUuid()).list(); - } else { - iprs = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) - .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); - } - + List iprs = getReqIpRanges(msg, IPv6Constants.IPv6); IpRangeVO ipr = CollectionUtils.find(iprs, new Function() { @Override public IpRangeVO call(IpRangeVO arg) { @@ -110,4 +139,9 @@ public IpRangeVO call(IpRangeVO arg) { return l3NwMgr.reserveIp(ipr, msg.getRequiredIp(), msg.isDuplicatedIpAllowed()); } + + public static int compareIpv4Range(IpRangeVO r1, IpRangeVO r2) { + long diff = NetworkUtils.ipv4StringToLong(r1.getStartIp()) - NetworkUtils.ipv4StringToLong(r2.getStartIp()); + return diff > 0 ? 1 : diff == 0 ? 0 : -1; + } } diff --git a/network/src/main/java/org/zstack/network/l3/AddressPoolIpRangeFactory.java b/network/src/main/java/org/zstack/network/l3/AddressPoolIpRangeFactory.java index 838c2a9a309..aae2711248b 100644 --- a/network/src/main/java/org/zstack/network/l3/AddressPoolIpRangeFactory.java +++ b/network/src/main/java/org/zstack/network/l3/AddressPoolIpRangeFactory.java @@ -5,11 +5,15 @@ import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.SQLBatchWithReturn; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.message.APICreateMessage; import org.zstack.header.network.l3.*; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.ForEachFunction; +import java.util.ArrayList; +import java.util.List; + public class AddressPoolIpRangeFactory implements IpRangeFactory { @Autowired DatabaseFacade dbf; @@ -22,32 +26,45 @@ public IpRangeType getType() { } @Override - public IpRangeInventory createIpRange(IpRangeInventory ipr, APICreateMessage msg) { - AddressPoolVO vo = new SQLBatchWithReturn() { - @Override - protected AddressPoolVO scripts() { - AddressPoolVO vo = new AddressPoolVO(); - vo.setUuid(ipr.getUuid() == null ? Platform.getUuid() : ipr.getUuid()); - vo.setDescription(ipr.getDescription()); - vo.setEndIp(ipr.getEndIp()); - vo.setGateway(ipr.getStartIp()); - vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); - vo.setName(ipr.getName()); - vo.setNetmask(ipr.getNetmask()); - vo.setStartIp(ipr.getStartIp()); - vo.setNetworkCidr(ipr.getNetworkCidr()); - vo.setAccountUuid(msg.getSession().getAccountUuid()); - vo.setIpVersion(ipr.getIpVersion()); - vo.setAddressMode(ipr.getAddressMode()); - vo.setPrefixLen(ipr.getPrefixLen()); - dbf.getEntityManager().persist(vo); - dbf.getEntityManager().flush(); - dbf.getEntityManager().refresh(vo); - - return vo; - } - }.execute(); - - return AddressPoolInventory.valueOf1(vo); + public void createIpRange(List iprs, APICreateMessage msg, ReturnValueCompletion> completion) { + List vos = new ArrayList<>(); + for (IpRangeInventory ipr : iprs) { + AddressPoolVO vo = new SQLBatchWithReturn() { + @Override + protected AddressPoolVO scripts() { + AddressPoolVO vo = new AddressPoolVO(); + vo.setUuid(ipr.getUuid() == null ? Platform.getUuid() : ipr.getUuid()); + vo.setDescription(ipr.getDescription()); + vo.setEndIp(ipr.getEndIp()); + vo.setGateway(ipr.getStartIp()); + vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); + vo.setName(ipr.getName()); + vo.setNetmask(ipr.getNetmask()); + vo.setStartIp(ipr.getStartIp()); + vo.setNetworkCidr(ipr.getNetworkCidr()); + vo.setAccountUuid(msg.getSession().getAccountUuid()); + vo.setIpVersion(ipr.getIpVersion()); + vo.setAddressMode(ipr.getAddressMode()); + vo.setPrefixLen(ipr.getPrefixLen()); + dbf.getEntityManager().persist(vo); + dbf.getEntityManager().flush(); + dbf.getEntityManager().refresh(vo); + + return vo; + } + }.execute(); + + vos.add(vo); + + final IpRangeInventory finalIpr = AddressPoolInventory.valueOf1(vo); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(AfterAddIpRangeExtensionPoint.class), new ForEachFunction() { + @Override + public void run(AfterAddIpRangeExtensionPoint ext) { + ext.afterAddIpRange(finalIpr, msg.getSystemTags()); + } + }); + } + + completion.success(IpRangeInventory.valueOf(vos)); } } diff --git a/network/src/main/java/org/zstack/network/l3/AscDelayRecycleIpAllocatorStrategy.java b/network/src/main/java/org/zstack/network/l3/AscDelayRecycleIpAllocatorStrategy.java new file mode 100755 index 00000000000..47337b221e3 --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/AscDelayRecycleIpAllocatorStrategy.java @@ -0,0 +1,323 @@ +package org.zstack.network.l3; + +import org.zstack.core.db.Q; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.network.l3.*; +import org.zstack.header.tag.SystemTagVO; +import org.zstack.header.tag.SystemTagVO_; +import org.zstack.tag.PatternedSystemTag; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.TagUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.NetworkUtils; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +public class AscDelayRecycleIpAllocatorStrategy extends AbstractIpAllocatorStrategy implements IpRangeDeletionExtensionPoint { + private static final CLogger logger = Utils.getLogger(AscDelayRecycleIpAllocatorStrategy.class); + private static final IpAllocatorType type = new IpAllocatorType(L3NetworkConstant.ASC_DELAY_RECYCLE_IP_ALLOCATOR_STRATEGY); + + private static class IpCursorStruct { + private String ipRangeUuid; + + private String nextIp; + + public static final String NULL_VALUE = "null"; + + public IpCursorStruct() { + this.ipRangeUuid = NULL_VALUE; + this.nextIp = NULL_VALUE; + } + + public String getIpRangeUuid() { + return this.ipRangeUuid; + } + + public String getNextIp() { + return this.nextIp; + } + + public void setIpRangeUuid(String ipRangeUuid) { + this.ipRangeUuid = ipRangeUuid; + } + + public void setNextIp(String nextIp) { + this.nextIp = nextIp; + } + } + + private IpCursorStruct getIpCursorStruct(String l3NetworkUuid, String reqRangeType) { + IpCursorStruct ipCursorStruct = new IpCursorStruct(); + + PatternedSystemTag pst; + String rangeUuidToken; + String nextIpToken; + + if (reqRangeType.equals(IpRangeType.Normal.toString())) { + pst = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IP; + rangeUuidToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IPRANGE_UUID_TOKEN; + nextIpToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IP_TOKEN; + } else { + pst = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP; + rangeUuidToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IPRANGE_UUID_TOKEN; + nextIpToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP_TOKEN; + } + + String tag = pst.getTag(l3NetworkUuid); + if (tag == null) { + SystemTagCreator creator = pst.newSystemTagCreator(l3NetworkUuid); + creator.setTagByTokens(map( + e(rangeUuidToken, IpCursorStruct.NULL_VALUE), + e(nextIpToken, IpCursorStruct.NULL_VALUE) + )); + creator.create(); + } else { + ipCursorStruct.setIpRangeUuid(pst.getTokenByTag(tag, rangeUuidToken)); + ipCursorStruct.setNextIp(pst.getTokenByTag(tag, nextIpToken)); + } + + return ipCursorStruct; + } + + private void updateIpCursorStruct(String l3NetworkUuid, String ipRangeType, String ipRangeUuid, String ip) { + PatternedSystemTag pst; + String rangeUuidToken; + String nextIpToken; + + if (ipRangeType.equals(IpRangeType.Normal.toString())) { + pst = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IP; + rangeUuidToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IPRANGE_UUID_TOKEN; + nextIpToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IP_TOKEN; + } else { + pst = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP; + rangeUuidToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IPRANGE_UUID_TOKEN; + nextIpToken = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP_TOKEN; + } + + String tag = pst.getTag(l3NetworkUuid); + + final String tagUuid = Q.New(SystemTagVO.class) + .select(SystemTagVO_.uuid) + .eq(SystemTagVO_.resourceUuid, l3NetworkUuid) + .eq(SystemTagVO_.resourceType, L3NetworkVO.class.getSimpleName()) + .like(SystemTagVO_.tag, TagUtils.tagPatternToSqlPattern(tag)) + .findValue(); + + pst.updateByTagUuid(tagUuid, pst.instantiateTag(map( + e(rangeUuidToken, ipRangeUuid), + e(nextIpToken, ip) + ))); + } + + @Override + public IpAllocatorType getType() { + return type; + } + + private String allocateIpByAsc(IpRangeVO vo, String excludeIp) { + List used = l3NwMgr.getUsedIpInRange(vo); + if (excludeIp != null) { + used.add(new BigInteger(String.valueOf(NetworkUtils.ipv4StringToLong(excludeIp)))); + Collections.sort(used); + } + List usedIP = used.stream().map(BigInteger::longValue).filter(ip -> ip.longValue() >= NetworkUtils.ipv4StringToLong(vo.getStartIp())).collect(Collectors.toList()); + return NetworkUtils.findFirstAvailableIpv4Address(vo.getStartIp(), vo.getEndIp(), usedIP.toArray(new Long[usedIP.size()])); + } + + private UsedIpInventory allocateIpByAsc(IpAllocateMessage msg, List ranges) { + String excludeIp = msg.getExcludedIp(); + do { + String ip = null; + IpRangeVO tr; + + for (IpRangeVO r : ranges) { + if (l3NwMgr.isIpRangeFull(r)) { + logger.debug(String.format("Ip range[uuid:%s, name: %s] is exhausted, try next one", r.getUuid(), r.getName())); + continue; + } + + ip = allocateIpByAsc(r, excludeIp); + tr = r; + if (ip != null) { + UsedIpInventory inv = l3NwMgr.reserveIp(tr, ip, msg.isDuplicatedIpAllowed()); + if (inv != null) { + return inv; + } + } + } + + if (ip == null) { + /* No available ip in ranges */ + return null; + } + } while (true); + } + + private boolean findNextAndUpdateByAscDelayRecycle(IpAllocateMessage msg, List ranges, String curUsedIpRangeUuid, String curUsedIp) { + String ip; + String excludeIp = msg.getExcludedIp(); + for (IpRangeVO r : ranges) { + if (l3NwMgr.isIpRangeFull(r)) { + logger.debug(String.format("Ip range[uuid:%s, name: %s] is exhausted, try next one", r.getUuid(), r.getName())); + continue; + } + if (r.getUuid().equals(curUsedIpRangeUuid)) { + IpRangeVO cloneRange = new IpRangeVO(); + cloneRange.setUuid(r.getUuid()); + long startIp = NetworkUtils.ipv4StringToLong(curUsedIp)+1; + if (startIp > NetworkUtils.ipv4StringToLong(r.getEndIp())) { + continue; + } + cloneRange.setStartIp(NetworkUtils.longToIpv4String(startIp)); + cloneRange.setEndIp(r.getEndIp()); + cloneRange.setIpVersion(r.getIpVersion()); + ip = allocateIpByAsc(cloneRange, excludeIp); + } else { + ip = allocateIpByAsc(r, excludeIp); + } + if (ip != null) { + updateIpCursorStruct(msg.getL3NetworkUuid(), getReqIpRangeType(msg), r.getUuid(), ip); + return true; + } + } + return false; + } + + private boolean findNextAndUpdateByFirstAvailable(List ranges, String l3NetworkUuid, String rangeType, String excludeIp) { + String ip; + for (IpRangeVO r : ranges) { + if (l3NwMgr.isIpRangeFull(r)) { + logger.debug(String.format("Ip range[uuid:%s, name: %s] is exhausted, try next one", r.getUuid(), r.getName())); + continue; + } + + ip = allocateIpByAsc(r, excludeIp); + if (ip != null) { + updateIpCursorStruct(l3NetworkUuid, rangeType, r.getUuid(), ip); + return true; + } + } + return false; + } + + private void updateNextIp(IpAllocateMessage msg, String curUsedIpRangeUuid, String curUsedIp, List ranges) { + String excludeIp = msg.getExcludedIp(); + String rangeType = getReqIpRangeType(msg); + + long curIp = NetworkUtils.ipv4StringToLong(curUsedIp); + List rightRanges = new ArrayList<>(); + + for (IpRangeVO ipr : ranges) { + if (NetworkUtils.ipv4StringToLong(ipr.getStartIp()) <= curIp && curIp <= NetworkUtils.ipv4StringToLong(ipr.getEndIp())) { + rightRanges.add(ipr); + } else if (curIp < NetworkUtils.ipv4StringToLong(ipr.getStartIp())) { + rightRanges.add(ipr); + } + } + + if (findNextAndUpdateByAscDelayRecycle(msg, rightRanges, curUsedIpRangeUuid, curUsedIp)) { + return; + } + if (findNextAndUpdateByFirstAvailable(ranges, msg.getL3NetworkUuid(), rangeType, excludeIp)) { + return; + } + + updateIpCursorStruct(msg.getL3NetworkUuid(), rangeType, IpCursorStruct.NULL_VALUE, IpCursorStruct.NULL_VALUE); + } + + @Override + public UsedIpInventory allocateIp(IpAllocateMessage msg) { + UsedIpInventory ret; + + IpCursorStruct ipCursorStruct = getIpCursorStruct(msg.getL3NetworkUuid(), getReqIpRangeType(msg)); + List ranges; + boolean needToUpdateIpCursor = true; + + if (msg.getRequiredIp() != null) { + ret = allocateRequiredIp(msg); + if (ret == null || !ret.getIp().equals(ipCursorStruct.getNextIp())) { + return ret; + } + ranges = getReqIpRanges(msg, IPv6Constants.IPv4); + } else if ( msg.getIpRangeUuid() != null) { + ranges = getReqIpRanges(msg, IPv6Constants.IPv4); + if (ipCursorStruct.getIpRangeUuid().equals(msg.getIpRangeUuid())) { + msg.setRequiredIp(ipCursorStruct.getNextIp()); + ret = allocateRequiredIp(msg); + } else { + ret = allocateIpByAsc(msg, ranges); + if (!ipCursorStruct.getIpRangeUuid().equals(IpCursorStruct.NULL_VALUE)) { + needToUpdateIpCursor = false; + } + } + } else { + ranges = getReqIpRanges(msg, IPv6Constants.IPv4); + if (!ipCursorStruct.getNextIp().equals(IpCursorStruct.NULL_VALUE)) { + msg.setIpRangeUuid(ipCursorStruct.getIpRangeUuid()); + msg.setRequiredIp(ipCursorStruct.getNextIp()); + ret = allocateRequiredIp(msg); + } else { + ret = allocateIpByAsc(msg, ranges); + } + } + + if (ret != null && needToUpdateIpCursor) { + updateNextIp(msg, ret.getIpRangeUuid(), ret.getIp(), ranges); + } + return ret; + } + + @Override + public void preDeleteIpRange(IpRangeInventory ipRange) { + } + + @Override + public void beforeDeleteIpRange(IpRangeInventory ipRange) { + } + @Override + public void afterDeleteIpRange(IpRangeInventory ipRange) { + String l3NetworkUuid = ipRange.getL3NetworkUuid(); + String rangeType; + + IpCursorStruct normalIpCursorStruct = getIpCursorStruct(l3NetworkUuid, IpRangeType.Normal.toString()); + IpCursorStruct addressPoolIpCursorStruct = getIpCursorStruct(l3NetworkUuid, IpRangeType.AddressPool.toString()); + + if (normalIpCursorStruct.getIpRangeUuid().equals(ipRange.getUuid())) { + rangeType = IpRangeType.Normal.toString(); + } else if (addressPoolIpCursorStruct.getIpRangeUuid().equals(ipRange.getUuid())) { + rangeType = IpRangeType.AddressPool.toString(); + } else { + return; + } + + List ranges = getIpRanges(rangeType, l3NetworkUuid, IPv6Constants.IPv4, true); + List rightRanges = new ArrayList<>(); + + for (IpRangeVO ipr : ranges) { + if (NetworkUtils.ipv4StringToLong(ipr.getStartIp()) > NetworkUtils.ipv4StringToLong(ipRange.getStartIp())) { + rightRanges.add(ipr); + } + } + + if (findNextAndUpdateByFirstAvailable(rightRanges, l3NetworkUuid, rangeType, null)) { + return; + } + if (findNextAndUpdateByFirstAvailable(ranges, l3NetworkUuid, rangeType, null)) { + return; + } + + updateIpCursorStruct(l3NetworkUuid, rangeType, IpCursorStruct.NULL_VALUE, IpCursorStruct.NULL_VALUE); + } + + public void failedToDeleteIpRange(IpRangeInventory ipRange, ErrorCode errorCode) { + } +} diff --git a/network/src/main/java/org/zstack/network/l3/AttachNetworkServiceToL3Msg.java b/network/src/main/java/org/zstack/network/l3/AttachNetworkServiceToL3Msg.java index c3d14924f47..24a40b3faf2 100644 --- a/network/src/main/java/org/zstack/network/l3/AttachNetworkServiceToL3Msg.java +++ b/network/src/main/java/org/zstack/network/l3/AttachNetworkServiceToL3Msg.java @@ -3,6 +3,8 @@ import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.network.l3.L3NetworkMessage; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -13,6 +15,8 @@ public class AttachNetworkServiceToL3Msg extends NeedReplyMessage implements L3N private String l3NetworkUuid; private Map> networkServices; + private List apiSystemTags = new ArrayList<>(); + public void setL3NetworkUuid(String l3NetworkUuid) { this.l3NetworkUuid = l3NetworkUuid; } @@ -29,4 +33,12 @@ public Map> getNetworkServices() { public void setNetworkServices(Map> networkServices) { this.networkServices = networkServices; } + + public List getApiSystemTags() { + return apiSystemTags; + } + + public void setApiSystemTags(List apiSystemTags) { + this.apiSystemTags = apiSystemTags; + } } diff --git a/network/src/main/java/org/zstack/network/l3/CheckIpAddressAvailabilityExtensionPoint.java b/network/src/main/java/org/zstack/network/l3/CheckIpAddressAvailabilityExtensionPoint.java new file mode 100644 index 00000000000..1cdf641f85d --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/CheckIpAddressAvailabilityExtensionPoint.java @@ -0,0 +1,9 @@ +package org.zstack.network.l3; + +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.network.l3.CheckIpAvailabilityMsg; +import org.zstack.header.network.l3.CheckIpAvailabilityReply; + +public interface CheckIpAddressAvailabilityExtensionPoint { + public void check(CheckIpAvailabilityMsg msg, ReturnValueCompletion completion); +} diff --git a/network/src/main/java/org/zstack/network/l3/FirstAvailableIpAllocatorStrategy.java b/network/src/main/java/org/zstack/network/l3/FirstAvailableIpAllocatorStrategy.java index be96e20f379..20a9cffc1fb 100755 --- a/network/src/main/java/org/zstack/network/l3/FirstAvailableIpAllocatorStrategy.java +++ b/network/src/main/java/org/zstack/network/l3/FirstAvailableIpAllocatorStrategy.java @@ -1,5 +1,6 @@ package org.zstack.network.l3; +import org.apache.commons.math3.analysis.function.Add; import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; @@ -11,13 +12,14 @@ import java.math.BigInteger; import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; public class FirstAvailableIpAllocatorStrategy extends AbstractIpAllocatorStrategy{ private static final CLogger logger = Utils.getLogger(FirstAvailableIpAllocatorStrategy.class); private static final IpAllocatorType type = new IpAllocatorType(L3NetworkConstant.FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY); - + @Override public IpAllocatorType getType() { return type; @@ -25,12 +27,14 @@ public IpAllocatorType getType() { private String allocateIp(IpRangeVO vo, String excludeIp) { List used = l3NwMgr.getUsedIpInRange(vo); - used.add(new BigInteger(String.valueOf(NetworkUtils.ipv4StringToLong(excludeIp)))); + if (excludeIp != null) { + used.add(new BigInteger(String.valueOf(NetworkUtils.ipv4StringToLong(excludeIp)))); + Collections.sort(used); + } List usedIP = used.stream().map(BigInteger::longValue).collect(Collectors.toList()); - Collections.sort(used); return NetworkUtils.findFirstAvailableIpv4Address(vo.getStartIp(), vo.getEndIp(), usedIP.toArray(new Long[usedIP.size()])); } - + @Override public UsedIpInventory allocateIp(IpAllocateMessage msg) { if (msg.getRequiredIp() != null) { @@ -38,14 +42,8 @@ public UsedIpInventory allocateIp(IpAllocateMessage msg) { } String excludeIp = msg.getExcludedIp(); - List ranges; - /* when allocate ip address from address pool, ipRangeUuid is not null */ - if (msg.getIpRangeUuid() != null) { - ranges = Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, msg.getIpRangeUuid()).list(); - } else { - ranges = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) - .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv4).list(); - } + List ranges = getReqIpRanges(msg, IPv6Constants.IPv4); + do { String ip = null; IpRangeVO tr = null; diff --git a/network/src/main/java/org/zstack/network/l3/FirstAvailableIpv6AllocatorStrategy.java b/network/src/main/java/org/zstack/network/l3/FirstAvailableIpv6AllocatorStrategy.java index ac9d50f6537..63723dc7073 100755 --- a/network/src/main/java/org/zstack/network/l3/FirstAvailableIpv6AllocatorStrategy.java +++ b/network/src/main/java/org/zstack/network/l3/FirstAvailableIpv6AllocatorStrategy.java @@ -6,9 +6,11 @@ import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; import java.math.BigInteger; import java.util.Collections; +import java.util.Comparator; import java.util.List; public class FirstAvailableIpv6AllocatorStrategy extends AbstractIpAllocatorStrategy{ @@ -22,7 +24,9 @@ public IpAllocatorType getType() { private String allocateIp(IpRangeVO vo, String excludeIp) { List used = l3NwMgr.getUsedIpInRange(vo); - used.add(new BigInteger(String.valueOf(IPv6NetworkUtils.ipv6AddressToBigInteger(excludeIp)))); + if (excludeIp != null) { + used.add(new BigInteger(String.valueOf(IPv6NetworkUtils.ipv6AddressToBigInteger(excludeIp)))); + } BigInteger start = IPv6NetworkUtils.ipv6AddressToBigInteger(vo.getStartIp()); BigInteger end = IPv6NetworkUtils.ipv6AddressToBigInteger(vo.getEndIp()); Collections.sort(used); @@ -41,14 +45,8 @@ public UsedIpInventory allocateIp(IpAllocateMessage msg) { } String excludeIp = msg.getExcludedIp(); - List ranges; - /* when allocate ip address from address pool, ipRangeUuid is not null */ - if (msg.getIpRangeUuid() != null) { - ranges = Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, msg.getIpRangeUuid()).list(); - } else { - ranges = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) - .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); - } + List ranges = getReqIpRanges(msg, IPv6Constants.IPv6); + do { String ip = null; IpRangeVO tr = null; diff --git a/network/src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java b/network/src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java index 427cfbc0612..aed1354119b 100644 --- a/network/src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java +++ b/network/src/main/java/org/zstack/network/l3/IpNotAvailabilityReason.java @@ -23,7 +23,7 @@ public String toi18nString() { return i18n("it is gateway"); } else if (this.equals(NO_IN_RANGE)) { return i18n("it is not in this range"); - } else if (this.equals(NO_IN_RANGE)) { + } else if (this.equals(USED)) { return i18n("it is used"); } else { return this.toString(); diff --git a/network/src/main/java/org/zstack/network/l3/IpRangeCascadeExtension.java b/network/src/main/java/org/zstack/network/l3/IpRangeCascadeExtension.java index 9a63a07bca9..115dea698ee 100755 --- a/network/src/main/java/org/zstack/network/l3/IpRangeCascadeExtension.java +++ b/network/src/main/java/org/zstack/network/l3/IpRangeCascadeExtension.java @@ -62,11 +62,11 @@ private void deleteIpRanges(final CascadeAction action,List ip msg.setForceDelete(action.isActionCode(CascadeConstant.DELETION_FORCE_DELETE_CODE)); msg.setL3NetworkUuid(iprinv.getL3NetworkUuid()); msg.setIpRangeUuid(iprinv.getUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, iprinv.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, iprinv.getL3NetworkUuid()); msgs.add(msg); } - new While<>(msgs).all((msg, compl) -> { + new While<>(msgs).each((msg, compl) -> { bus.send(msg, new CloudBusCallBack(compl) { @Override public void run(MessageReply reply) { diff --git a/network/src/main/java/org/zstack/network/l3/IpRangeHelper.java b/network/src/main/java/org/zstack/network/l3/IpRangeHelper.java index 883ff7622fc..fffbff32665 100644 --- a/network/src/main/java/org/zstack/network/l3/IpRangeHelper.java +++ b/network/src/main/java/org/zstack/network/l3/IpRangeHelper.java @@ -1,13 +1,28 @@ package org.zstack.network.l3; +import org.zstack.core.Platform; +import org.zstack.header.exception.CloudRuntimeException; +import javax.persistence.Tuple; +import javax.persistence.TupleElement; + +import org.apache.commons.net.util.SubnetUtils; import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.header.network.l3.*; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.function.Function; import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; +import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.*; + +import static org.junit.runner.Request.aClass; public class IpRangeHelper { @@ -59,7 +74,7 @@ public static List getAddressPools(L3NetworkInventory l3inv) { } List uuids = l3inv.getIpRanges().stream().map(IpRangeInventory::getUuid).collect(Collectors.toList()); - return AddressPoolInventory.valueOf1(Q.New(AddressPoolVO.class).in(NormalIpRangeVO_.uuid, uuids).list()); + return AddressPoolInventory.valueOf1(Q.New(AddressPoolVO.class).in(AddressPoolVO_.uuid, uuids).list()); } public static List getAddressPools(L3NetworkVO vo) { @@ -68,7 +83,7 @@ public static List getAddressPools(L3NetworkVO vo) { } List uuids = vo.getIpRanges().stream().map(IpRangeVO::getUuid).collect(Collectors.toList()); - return AddressPoolInventory.valueOf1(Q.New(AddressPoolVO.class).in(NormalIpRangeVO_.uuid, uuids).list()); + return AddressPoolInventory.valueOf1(Q.New(AddressPoolVO.class).in(AddressPoolVO_.uuid, uuids).list()); } public static void updateL3NetworkIpversion(IpRangeVO ipr) { @@ -95,8 +110,175 @@ public static void updateL3NetworkIpversion(IpRangeInventory ipr) { ipVersion = IPv6Constants.IPv6; } - if (l3VO.getIpVersion() != ipVersion) { + if (!ipVersion.equals(l3VO.getIpVersion())) { SQL.New(L3NetworkVO.class).set(L3NetworkVO_.ipVersion, ipVersion).eq(L3NetworkVO_.uuid, l3VO.getUuid()).update(); } } + + public static String getIpRangeType(String ipRangeUuid) { + List normalRanges = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.uuid, ipRangeUuid).list(); + return normalRanges.size() > 0 ? IpRangeType.Normal.toString() : IpRangeType.AddressPool.toString(); + } + + public static List getUsedIpInRange(String ipRangeUuid, int ipVersion) { + Q q = Q.New(UsedIpVO.class).eq(UsedIpVO_.ipRangeUuid, ipRangeUuid); + if (!getIpRangeType(ipRangeUuid).equals(IpRangeType.AddressPool.toString())) { + String gateway = Q.New(IpRangeVO.class).select(IpRangeVO_.gateway) + .eq(IpRangeVO_.uuid, ipRangeUuid).findValue(); + q.notEq(UsedIpVO_.ip, gateway); + } + if (ipVersion == IPv6Constants.IPv4) { + q.select(UsedIpVO_.ipInLong); + List used = q.listValues(); + Collections.sort(used); + return used.stream().distinct().map(l -> new BigInteger(String.valueOf(l))).collect(Collectors.toList()); + } else { + q.select(UsedIpVO_.ip); + List used = q.listValues(); + return used.stream().distinct().map(IPv6NetworkUtils::getBigIntegerFromString).sorted().collect(Collectors.toList()); + } + } + + public static List getFreeIp(final IpRangeVO ipr, int limit, String start) { + List usedIps = Q.New(UsedIpVO.class).select(UsedIpVO_.ip).eq(UsedIpVO_.ipRangeUuid, ipr.getUuid()).listValues(); + usedIps = usedIps.stream().distinct().collect(Collectors.toList()); + + List spareIps = new ArrayList<>(); + if (ipr.getIpVersion() == IPv6Constants.IPv6) { + spareIps.addAll(NetworkUtils.getFreeIpv6InRange(ipr.getStartIp(), ipr.getEndIp(), usedIps, limit, start)); + } else { + IpRangeVO cloneIpr = new IpRangeVO(); + cloneIpr.setStartIp(ipr.getStartIp()); + cloneIpr.setEndIp(ipr.getEndIp()); + cloneIpr.setNetmask(ipr.getNetmask()); + IpRangeHelper.stripNetworkAndBroadcastAddress(cloneIpr); + spareIps.addAll(NetworkUtils.getFreeIpInRange(cloneIpr.getStartIp(), cloneIpr.getEndIp(), usedIps, limit, start)); + } + + return CollectionUtils.transformToList(spareIps, (Function) arg -> { + FreeIpInventory f = new FreeIpInventory(); + f.setGateway(ipr.getGateway()); + f.setIp(arg); + f.setNetmask(ipr.getNetmask()); + f.setIpRangeUuid(ipr.getUuid()); + return f; + }); + } + + public static boolean stripNetworkAndBroadcastAddress(IpRangeVO ipr) { + SubnetUtils sub = new SubnetUtils(ipr.getStartIp(), ipr.getNetmask()); + SubnetUtils.SubnetInfo info = sub.getInfo(); + boolean ret = true; + + if (ipr.getStartIp().equals(ipr.getEndIp())) { + if (ipr.getStartIp().equals(info.getNetworkAddress()) || ipr.getEndIp().equals(info.getBroadcastAddress())) { + ret = false; + } + } + + if (ipr.getStartIp().equals(info.getNetworkAddress())) { + ipr.setStartIp(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(ipr.getStartIp())+1)); + } + if (ipr.getEndIp().equals(info.getBroadcastAddress())) { + ipr.setEndIp(NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(ipr.getEndIp())-1)); + } + + return ret; + } + + public static List stripNetworkAndBroadcastAddress(List tuples) { + List ret = new ArrayList<>(); + for (Tuple tuple : tuples) { + String sip = tuple.get(0, String.class); + String eip = tuple.get(1, String.class); + String netmask = tuple.get(2, String.class); + int ipVersion = tuple.get(3, Integer.class); + if (ipVersion == IPv6Constants.IPv4) { + IpRangeVO ipr = new IpRangeVO(); + ipr.setStartIp(sip); + ipr.setEndIp(eip); + ipr.setNetmask(netmask); + stripNetworkAndBroadcastAddress(ipr); + + Tuple myTuple = new Tuple() { + + private Map data = new HashMap<>(); + + { + data.put(0, ipr.getStartIp()); + data.put(1, ipr.getEndIp()); + data.put(2, tuple.get(2)); + data.put(3, tuple.get(3)); + data.put(4, tuple.get(4)); + } + + @Override + public X get(TupleElement tupleElement) { + return null; + } + + @Override + public X get(String s, Class aClass) { + return null; + } + + @Override + public Object get(String s) { + return null; + } + + @Override + public X get(int i, Class aClass) { + return aClass.cast(data.get(i)); + } + + @Override + public Object get(int i) { + return data.get(i); + } + + @Override + public Object[] toArray() { + return new Object[0]; + } + + @Override + public List> getElements() { + return null; + } + }; + + ret.add(myTuple); + } else { + ret.add(tuple); + } + } + return ret; + } + + public static boolean isIpAddressAllocationEnableOnL3(String l3Uuid) { + L3NetworkVO l3NetworkVO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, l3Uuid).find(); + if (l3NetworkVO == null) { + return false; + } + return l3NetworkVO.enableIpAddressAllocation(); + } + + public static IpRangeVO fromIpRangeInventory(IpRangeInventory ipr, String accountUuid) { + NormalIpRangeVO vo = new NormalIpRangeVO(); + vo.setUuid(ipr.getUuid() == null ? Platform.getUuid() : ipr.getUuid()); + vo.setDescription(ipr.getDescription()); + vo.setEndIp(ipr.getEndIp()); + vo.setGateway(ipr.getGateway()); + vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); + vo.setName(ipr.getName()); + vo.setNetmask(ipr.getNetmask()); + vo.setStartIp(ipr.getStartIp()); + vo.setNetworkCidr(ipr.getNetworkCidr()); + vo.setAccountUuid(accountUuid); + vo.setIpVersion(ipr.getIpVersion()); + vo.setAddressMode(ipr.getAddressMode()); + vo.setPrefixLen(ipr.getPrefixLen()); + return vo; + } } diff --git a/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java b/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java index 5c3a96e718b..19b9e530a59 100755 --- a/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java +++ b/network/src/main/java/org/zstack/network/l3/L3BasicNetwork.java @@ -1,8 +1,11 @@ package org.zstack.network.l3; +import com.googlecode.ipv6.IPv6Address; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cascade.CascadeConstant; import org.zstack.core.cascade.CascadeFacade; import org.zstack.core.cloudbus.CloudBus; @@ -10,6 +13,8 @@ import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.core.defer.Defer; +import org.zstack.core.defer.Deferred; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.retry.Retry; import org.zstack.core.retry.RetryCondition; @@ -18,36 +23,51 @@ import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.core.Completion; import org.zstack.header.core.NopeCompletion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; import org.zstack.header.identity.SharedResourceVO; import org.zstack.header.identity.SharedResourceVO_; import org.zstack.header.message.*; +import org.zstack.header.network.IpAllocatedReason; +import org.zstack.header.network.l2.L2NetworkClusterRefVO; +import org.zstack.header.network.l2.L2NetworkClusterRefVO_; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.L2NetworkVO; import org.zstack.header.network.l3.*; import org.zstack.header.network.service.*; import org.zstack.identity.AccountManager; +import org.zstack.network.service.NetworkServiceManager; +import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.data.FieldPrinter; import org.zstack.utils.function.ForEachFunction; -import org.zstack.utils.function.Function; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; +import org.zstack.utils.stopwatch.StopWatch; import javax.persistence.Tuple; +import java.math.BigInteger; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static org.codehaus.groovy.runtime.InvokerHelper.asList; import static org.zstack.core.Platform.err; -import static org.zstack.utils.CollectionDSL.e; -import static org.zstack.utils.CollectionDSL.map; +import static org.zstack.utils.CollectionDSL.*; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class L3BasicNetwork implements L3Network { @@ -74,11 +94,18 @@ public class L3BasicNetwork implements L3Network { protected PluginRegistry pluginRgty; @Autowired private ThreadFacade thdf; + @Autowired + private ResourceConfigFacade rcf; + @Autowired + private NetworkServiceManager nsMgr; private L3NetworkVO self; + protected String syncThreadName; + public L3BasicNetwork(L3NetworkVO vo) { this.self = vo; + syncThreadName = "l3-" + vo.getUuid(); } protected L3NetworkVO getSelf() { @@ -134,17 +161,25 @@ private void setIpRangeSharedResource(String L3NetworkUuid, String IpRangeUuid) private void handle(APIAddIpRangeMsg msg) { IpRangeInventory ipr = IpRangeInventory.fromMessage(msg); + APIAddIpRangeEvent evt = new APIAddIpRangeEvent(msg.getId()); IpRangeFactory factory = l3NwMgr.getIpRangeFactory(ipr.getIpRangeType()); - IpRangeInventory inv = factory.createIpRange(ipr, msg); - - tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); - - setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + factory.createIpRange(Collections.singletonList(ipr), msg, new ReturnValueCompletion>(msg) { + @Override + public void success(List invs) { + IpRangeInventory inv = invs.get(0); + tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); + setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + evt.setInventory(inv); + bus.publish(evt); + } - APIAddIpRangeEvent evt = new APIAddIpRangeEvent(msg.getId()); - evt.setInventory(inv); - bus.publish(evt); + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } private void handleLocalMessage(Message msg) { @@ -166,25 +201,44 @@ private void handleLocalMessage(Message msg) { } private void handle(CheckIpAvailabilityMsg msg) { - CheckIpAvailabilityReply reply = checkIpAvailability(msg.getIp()); + CheckIpAvailabilityReply reply = checkIpAvailability(msg); bus.reply(msg, reply); } + private boolean isLastNormalIpRangeOfVersion(String ipRangeUuid, int ipVersion) { + List normalIpRanges = IpRangeHelper.getNormalIpRanges(self); + normalIpRanges = normalIpRanges.stream() + .filter(r -> r.getIpVersion() == ipVersion) + .collect(Collectors.toList()); + return normalIpRanges.size() == 1 && + normalIpRanges.get(0).getUuid().equals(ipRangeUuid); + } + private void handle(IpRangeDeletionMsg msg) { - thdf.chainSubmit(new ChainTask(msg) { + IpRangeDeletionReply reply = new IpRangeDeletionReply(); + doDeleteIpRange(msg, new Completion(msg) { @Override - public String getSyncSignature() { - return getSyncId(); + public void success() { + bus.reply(msg, reply); } @Override - public void run(SyncTaskChain chain) { - IpRangeDeletionReply reply = new IpRangeDeletionReply(); + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + private void doDeleteIpRange(IpRangeDeletionMsg msg, Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public void run(SyncTaskChain chainTask) { List exts = pluginRgty.getExtensionList(IpRangeDeletionExtensionPoint.class); IpRangeVO iprvo = dbf.findByUuid(msg.getIpRangeUuid(), IpRangeVO.class); if (iprvo == null) { - bus.reply(msg, reply); + completion.success(); + chainTask.next(); return; } @@ -201,37 +255,227 @@ public void run(IpRangeDeletionExtensionPoint arg) { } }); + FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("del-ip-range-%s", inv.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "disable-sdn-dhcp"; - dbf.remove(iprvo); - IpRangeHelper.updateL3NetworkIpversion(iprvo); + @Override + public void run(FlowTrigger trigger, Map data) { + boolean isLastIpRange = isLastNormalIpRangeOfVersion(msg.getIpRangeUuid(), inv.getIpVersion()); + data.put("isLastIpRange", isLastIpRange); + + if (!self.enableIpAddressAllocation()) { + trigger.next(); + return; + } + + SdnControllerDhcp sdnDhcp = l3NwMgr.getSdnControllerDhcp(self.getUuid()); + if (sdnDhcp == null) { + trigger.next(); + return; + } + + if (isLastIpRange) { + sdnDhcp.disableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(self)), inv.getIpVersion(), + new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } else { + trigger.next(); + } + } + }).then(new NoRollbackFlow() { + String __name__ = "delete-ip-range"; - CollectionUtils.safeForEach(exts, new ForEachFunction() { @Override - public void run(IpRangeDeletionExtensionPoint arg) { - arg.afterDeleteIpRange(inv); + public void run(FlowTrigger trigger, Map data) { + SdnControllerL3 sdnL3 = l3NwMgr.getSdnControllerL3(self.getL2NetworkUuid()); + if (sdnL3 == null) { + trigger.next(); + return; + } + + boolean isLastIpRange = (boolean) data.get("isLastIpRange"); + if (isLastIpRange) { + sdnL3.deleteIpRange(inv, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.debug(String.format("delete ip range [uuid:%s] failed because %s", + inv.getUuid(), errorCode.getDetails())); + trigger.next(); + } + }); + } else { + trigger.next(); + } } - }); + }).then(new NoRollbackFlow() { + String __name__ = "remove-db"; - bus.reply(msg, reply); - chain.next(); + @Override + public void run(FlowTrigger trigger, Map data) { + dbf.remove(iprvo); + IpRangeHelper.updateL3NetworkIpversion(iprvo); + + CollectionUtils.safeForEach(exts, new ForEachFunction() { + @Override + public void run(IpRangeDeletionExtensionPoint arg) { + arg.afterDeleteIpRange(inv); + } + }); + trigger.next(); + } + }).then(new NoRollbackFlow() { + String __name__ = "after-delete-ip-range"; + + @Override + public void run (FlowTrigger trigger, Map data){ + CollectionUtils.safeForEach( + pluginRgty.getExtensionList(AfterDeleteIpRangeExtensionPoint.class), + ext -> ext.afterDeleteIpRange(inv) + ); + trigger.next(); + } + }).error(new FlowErrorHandler(msg) { + @Override + @Deferred + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + chainTask.next(); + } + }).done(new FlowDoneHandler(msg) { + @Override + @Deferred + public void handle(Map data) { + completion.success(); + chainTask.next(); + } + }).start(); + } + + @Override + public String getSyncSignature() { + return syncThreadName; } @Override public String getName() { - return String.format("ip-range-%s-deletion", msg.getIpRangeUuid()); + return "delete-ip-range"; } }); - } private void handle(L3NetworkDeletionMsg msg) { - L3NetworkInventory inv = L3NetworkInventory.valueOf(self); - extpEmitter.beforeDelete(inv); - deleteHook(); - extpEmitter.afterDelete(inv); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + L3NetworkDeletionReply reply = new L3NetworkDeletionReply(); + L3NetworkVO l3NetworkVO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + L2NetworkVO l2NetworkVO = dbf.findByUuid(l3NetworkVO.getL2NetworkUuid(), L2NetworkVO.class); + + FlowChain fchain = new SimpleFlowChain(); + fchain.setName(String.format("del-l3-network-%s", msg.getL3NetworkUuid())); + fchain.then(new NoRollbackFlow() { + String __name__ = "remove-from-sdn-controller"; + + @Override + @Deferred + public void run(FlowTrigger trigger, Map data) { + SdnControllerL3 controllerL3 = l3NwMgr.getSdnControllerL3(self.getL2NetworkUuid()); + if (controllerL3 == null) { + trigger.next(); + return; + } + + controllerL3.deleteL3Network(L3NetworkInventory.valueOf(l3NetworkVO), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next();//ignore error + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "remove-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + boolean isExistSystemL3 = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.system, true) + .eq(L3NetworkVO_.l2NetworkUuid, l2NetworkVO.getUuid()).isExists(); + List clusterUuids = Q.New(L2NetworkClusterRefVO.class).select(L2NetworkClusterRefVO_.clusterUuid) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2NetworkVO.getUuid()).listValues(); + if (isExistSystemL3) { + if (clusterUuids != null && !clusterUuids.isEmpty()) { + for (ServiceTypeExtensionPoint ext : pluginRgty.getExtensionList(ServiceTypeExtensionPoint.class)) { + List hostUuids = Q.New(HostVO.class).select(HostVO_.uuid).in(HostVO_.clusterUuid, clusterUuids).listValues(); + if (l2NetworkVO.getType().equals(L2NetworkConstant.VXLAN_NETWORK_TYPE) || l2NetworkVO.getType().equals(L2NetworkConstant.HARDWARE_VXLAN_NETWORK_TYPE)) { + ext.syncManagementServiceTypeExtensionPoint(hostUuids, "vxlan" + l2NetworkVO.getVirtualNetworkId(), null, true); + } + if (l2NetworkVO.getType().equals(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE) || l2NetworkVO.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE)) { + ext.syncManagementServiceTypeExtensionPoint(hostUuids, l2NetworkVO.getPhysicalInterface(), l2NetworkVO.getVirtualNetworkId(), true); + } + } + } + } + + if (!self.getReservedIpRanges().isEmpty()) { + SQL.New(ReservedIpRangeVO.class) + .in(ReservedIpRangeVO_.uuid, self.getReservedIpRanges().stream().map(ReservedIpRangeVO::getUuid).collect(Collectors.toList())) + .delete(); + } + + L3NetworkInventory inv = L3NetworkInventory.valueOf(self); + extpEmitter.beforeDelete(inv); + deleteHook(); + extpEmitter.afterDelete(inv); + + trigger.next(); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + reply.setError(errCode); + bus.reply(msg, reply); + chain.next(); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + chain.next(); + } + }).start(); + } + + @Override + public String getSyncSignature() { + return getSyncId(); + } + + @Override + public String getName() { + return "delete-l3-network-" + msg.getL3NetworkUuid(); + } + }); - L3NetworkDeletionReply reply = new L3NetworkDeletionReply(); - bus.reply(msg, reply); } private void handle(ReturnIpMsg msg) { @@ -242,7 +486,32 @@ private void handle(ReturnIpMsg msg) { @Override @RetryCondition(times = 6) protected Void call() { - SQL.New(UsedIpVO.class).eq(UsedIpVO_.uuid, msg.getUsedIpUuid()).hardDelete(); + String reserveRangeUuid = null; + Tuple t = Q.New(UsedIpVO.class).select(UsedIpVO_.ip, UsedIpVO_.ipVersion) + .eq(UsedIpVO_.uuid, msg.getUsedIpUuid()).findTuple(); + if (t != null) { + String ip = t.get(0, String.class); + Integer ipVersion = t.get(1, Integer.class); + List ranges = self.getReservedIpRanges() + .stream().filter(r -> r.getIpVersion() == ipVersion).collect(Collectors.toList()); + for (ReservedIpRangeVO ripr : ranges) { + if (NetworkUtils.isInRange(ip, ripr.getStartIp(), ripr.getEndIp())) { + reserveRangeUuid = ripr.getUuid(); + break; + } + } + } + + if (reserveRangeUuid != null) { + SQL.New(UsedIpVO.class).eq(UsedIpVO_.uuid, msg.getUsedIpUuid()) + .set(UsedIpVO_.vmNicUuid, null) + .set(UsedIpVO_.usedFor, IpAllocatedReason.Reserved.toString()) + .set(UsedIpVO_.metaData, reserveRangeUuid) + .update(); + } else { + SQL.New(UsedIpVO.class).eq(UsedIpVO_.uuid, msg.getUsedIpUuid()).hardDelete(); + } + return null; } }.run(); @@ -256,29 +525,56 @@ private IpAllocatorType getIpAllocatorType(AllocateIpMsg msg) { } if (msg.getIpVersion() == IPv6Constants.IPv4) { + String ias = rcf.getResourceConfigValue(L3NetworkGlobalConfig.IP_ALLOCATE_STRATEGY, msg.getL3NetworkUuid(), String.class); + if (ias != null) { + return IpAllocatorType.valueOf(ias); + } return RandomIpAllocatorStrategy.type; } + String ias = rcf.getResourceConfigValue(L3NetworkGlobalConfig.IPV6_ALLOCATE_STRATEGY, msg.getL3NetworkUuid(), String.class); + if (ias != null) { + return IpAllocatorType.valueOf(ias); + } return RandomIpv6AllocatorStrategy.type; } private void handle(AllocateIpMsg msg) { - IpAllocatorType strategyType = getIpAllocatorType(msg); - IpAllocatorStrategy ias = l3NwMgr.getIpAllocatorStrategy(strategyType); AllocateIpReply reply = new AllocateIpReply(); - UsedIpInventory ip = ias.allocateIp(msg); - if (ip == null) { - String reason = msg.getRequiredIp() == null ? - String.format("no ip is available in this l3Network[name:%s, uuid:%s]", self.getName(), self.getUuid()) : - String.format("IP[%s] is not available", msg.getRequiredIp()); - reply.setError(err(L3Errors.ALLOCATE_IP_ERROR, - "IP allocator strategy[%s] failed, because %s", strategyType, reason)); - } else { - logger.debug(String.format("Ip allocator strategy[%s] successfully allocates an ip[%s]", strategyType, printer.print(ip))); - reply.setIpInventory(ip); - } - bus.reply(msg, reply); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSyncId(); + } + + @Override + public void run(SyncTaskChain chain) { + IpAllocatorType strategyType = getIpAllocatorType(msg); + IpAllocatorStrategy ias = l3NwMgr.getIpAllocatorStrategy(strategyType); + UsedIpInventory ip = ias.allocateIp(msg); + if (ip == null) { + String reason = msg.getRequiredIp() == null ? + String.format("no ip is available in this l3Network[name:%s, uuid:%s]", self.getName(), self.getUuid()) : + String.format("IP[%s] is not available", msg.getRequiredIp()); + reply.setError(err(L3Errors.ALLOCATE_IP_ERROR, + "IP allocator strategy[%s] failed, because %s", strategyType, reason)); + bus.reply(msg, reply); + chain.next(); + return; + } + + logger.debug(String.format("Ip allocator strategy[%s] successfully allocates an ip[%s]", strategyType, ip.getIp())); + reply.setIpInventory(ip); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public String getName() { + return "allocate-ip-of-l3-" + msg.getL3NetworkUuid(); + } + }); } private void handleApiMessage(APIMessage msg) { @@ -320,15 +616,168 @@ private void handleApiMessage(APIMessage msg) { handle((APIAddHostRouteToL3NetworkMsg) msg); } else if (msg instanceof APIRemoveHostRouteFromL3NetworkMsg) { handle((APIRemoveHostRouteFromL3NetworkMsg) msg); + } else if (msg instanceof APIAddReservedIpRangeMsg) { + handle((APIAddReservedIpRangeMsg) msg); + } else if (msg instanceof APIDeleteIpAddressMsg) { + handle((APIDeleteIpAddressMsg) msg); + } else if (msg instanceof APIDeleteReservedIpRangeMsg) { + handle((APIDeleteReservedIpRangeMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } - protected CheckIpAvailabilityReply checkIpAvailability(String ip) { + private void handle(APIAddReservedIpRangeMsg msg) { + APIAddReservedIpRangeEvent event = new APIAddReservedIpRangeEvent(msg.getId()); + + /* step 1: create reservedIpRangeVO */ + ReservedIpRangeVO reservedIpRangeVO = new ReservedIpRangeVO(); + reservedIpRangeVO.setUuid(Platform.getUuid()); + reservedIpRangeVO.setL3NetworkUuid(msg.getL3NetworkUuid()); + reservedIpRangeVO.setStartIp(msg.getStartIp()); + reservedIpRangeVO.setEndIp(msg.getEndIp()); + if (NetworkUtils.isIpv4Address(msg.getStartIp())) { + reservedIpRangeVO.setIpVersion(IPv6Constants.IPv4); + } else { + reservedIpRangeVO.setIpVersion(IPv6Constants.IPv6); + } + reservedIpRangeVO = dbf.persistAndRefresh(reservedIpRangeVO); + + /* step 2: allocate usedIpVO */ + List ipv4Ranges = self.getIpRanges().stream() + .filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv4) + .collect(Collectors.toList()); + List ipv6Ranges = self.getIpRanges().stream() + .filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv6).collect(Collectors.toList()); + List usedIpVOS = new ArrayList<>(); + if(IPv6NetworkUtils.isValidIpv4(msg.getStartIp()) && !ipv4Ranges.isEmpty()) { + long start = NetworkUtils.ipv4StringToLong(msg.getStartIp()); + long end = NetworkUtils.ipv4StringToLong(msg.getEndIp()); + Comparator ipv4Comparator + = Comparator.comparing( + IpRangeVO::getStartIp, (s1, s2) -> { + return NetworkUtils.compareIpv4Address(s1, s2); + }); + ipv4Ranges.sort(ipv4Comparator); + Iterator ip4 = ipv4Ranges.iterator(); + IpRangeVO ipr = ip4.next(); + + for (long i = start; i <= end && ipr != null; i++) { + String newIp = NetworkUtils.longToIpv4String(i); + /* ip address is used, can not be reserved */ + if (Q.New(UsedIpVO.class) + .eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(UsedIpVO_.ip, newIp).isExists()) { + continue; + } + + if (NetworkUtils.isInRange(newIp, ipr.getStartIp(), ipr.getEndIp())) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIpRangeUuid(ipr.getUuid()); + vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); + //vo.setVmNicUuid(nic.getUuid()); + vo.setIpVersion(ipr.getIpVersion()); + vo.setIp(newIp); + vo.setNetmask(ipr.getNetmask()); + vo.setGateway(ipr.getGateway()); + vo.setIpInLong(i); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setUsedFor(IpAllocatedReason.Reserved.toString()); + vo.setMetaData(reservedIpRangeVO.getUuid()); + + usedIpVOS.add(vo); + } else if (ip4.hasNext()) { + ipr = ip4.next(); + } else { + ipr = null; + } + } + } else if (IPv6NetworkUtils.isValidIpv6(msg.getStartIp()) && !ipv6Ranges.isEmpty()){ + BigInteger start = IPv6Address.fromString(msg.getStartIp()).toBigInteger(); + BigInteger end = IPv6Address.fromString(msg.getEndIp()).toBigInteger(); + Comparator ipv6Comparator + = Comparator.comparing( + IpRangeVO::getStartIp, (s1, s2) -> { + return IPv6NetworkUtils.compareIpv6Address(msg.getStartIp(), msg.getEndIp()); + }); + ipv6Ranges.sort(ipv6Comparator); + Iterator ip6 = ipv6Ranges.iterator(); + IpRangeVO ipr = ip6.next(); + + for (BigInteger i = start; i.compareTo(end) <= 0 && ipr != null; i = i.add(BigInteger.ONE)) { + String newIp = IPv6NetworkUtils.IPv6AddressToString(i); + /* ip address is used, can not be reserved */ + if (Q.New(UsedIpVO.class) + .eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(UsedIpVO_.ip, newIp).isExists()) { + continue; + } + + if (IPv6NetworkUtils.isIpv6InRange(newIp, ipr.getStartIp(), ipr.getEndIp())) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIpRangeUuid(ipr.getUuid()); + vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); + //vo.setVmNicUuid(nic.getUuid()); + vo.setIpVersion(ipr.getIpVersion()); + vo.setIp(newIp); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setNetmask(ipr.getNetmask()); + vo.setGateway(ipr.getGateway()); + vo.setUsedFor(IpAllocatedReason.Reserved.toString()); + vo.setMetaData(reservedIpRangeVO.getUuid()); + + usedIpVOS.add(vo); + } else if (ip6.hasNext()) { + ipr = ip6.next(); + } else { + ipr = null; + } + } + } + + if (!usedIpVOS.isEmpty()) { + StopWatch watch = Utils.getStopWatch(); + watch.start(); + dbf.persistCollection(usedIpVOS); + watch.stop(); + logger.debug(String.format("it takes %d microseconds to save %d ip addresses", watch.getLapse(), usedIpVOS.size())); + } + + event.setInventory(ReservedIpRangeInventory.valueOf(reservedIpRangeVO)); + + bus.publish(event); + } + + private void handle(APIDeleteReservedIpRangeMsg msg) { + APIDeleteIpAddressEvent event = new APIDeleteIpAddressEvent(msg.getId()); + + SQL.New(UsedIpVO.class).eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(UsedIpVO_.metaData, msg.getIpRangeUuid()) + .delete(); + + SQL.New(ReservedIpRangeVO.class).eq(ReservedIpRangeVO_.uuid, msg.getIpRangeUuid()).delete(); + + bus.publish(event); + } + + private void handle(APIDeleteIpAddressMsg msg) { + APIDeleteIpAddressEvent event = new APIDeleteIpAddressEvent(msg.getId()); + + SQL.New(UsedIpVO.class).eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .in(UsedIpVO_.uuid, msg.getUsedIpUuids()) + .isNull(UsedIpVO_.vmNicUuid) + .delete(); + + bus.publish(event); + } + + @Override + public CheckIpAvailabilityReply checkIpAvailability(CheckIpAvailabilityMsg msg) { CheckIpAvailabilityReply reply = new CheckIpAvailabilityReply(); int ipversion = IPv6Constants.IPv4; - if (IPv6NetworkUtils.isIpv6Address(ip)) { + if (IPv6NetworkUtils.isIpv6Address(msg.getIp())) { ipversion = IPv6Constants.IPv6; } SimpleQuery rq = dbf.createQuery(IpRangeVO.class); @@ -343,18 +792,31 @@ protected CheckIpAvailabilityReply checkIpAvailability(String ip) { boolean inRange = false; boolean isGateway = false; - for (Tuple t : ts) { - String sip = t.get(0, String.class); - String eip = t.get(1, String.class); - String gw = t.get(2, String.class); - if (ip.equals(gw) && !addressPoolGateways.contains(gw)) { - isGateway = true; - break; - } + /* disable ip range check */ + if (!msg.getIpRangeCheck()) { + inRange = true; + } - if (NetworkUtils.isInRange(ip, sip, eip)) { - inRange = true; - break; + if (!self.enableIpAddressAllocation()) { + inRange = true; + } + + if (ts.isEmpty()) { + inRange = true; + } else { + for (Tuple t : ts) { + String sip = t.get(0, String.class); + String eip = t.get(1, String.class); + String gw = t.get(2, String.class); + if (msg.getIp().equals(gw) && !addressPoolGateways.contains(gw)) { + isGateway = true; + break; + } + + if (NetworkUtils.isInRange(msg.getIp(), sip, eip)) { + inRange = true; + break; + } } } @@ -366,28 +828,75 @@ protected CheckIpAvailabilityReply checkIpAvailability(String ip) { } else { reply.setReason(IpNotAvailabilityReason.NO_IN_RANGE.toString()); } - return reply; } else { SimpleQuery q = dbf.createQuery(UsedIpVO.class); q.add(UsedIpVO_.l3NetworkUuid, Op.EQ, self.getUuid()); - q.add(UsedIpVO_.ip, Op.EQ, ip); + q.add(UsedIpVO_.ip, Op.EQ, msg.getIp()); if (q.isExists()) { reply.setAvailable(false); reply.setReason(IpNotAvailabilityReason.USED.toString()); } else { reply.setAvailable(true); } - - return reply; } + return reply; } private void handle(APICheckIpAvailabilityMsg msg) { APICheckIpAvailabilityReply reply = new APICheckIpAvailabilityReply(); - CheckIpAvailabilityReply r = checkIpAvailability(msg.getIp()); - reply.setAvailable(r.isAvailable()); - reply.setReason(r.getReason()); - bus.reply(msg, reply); + reply.setAvailable(true); + reply.setReason(""); + CheckIpAvailabilityMsg imsg = new CheckIpAvailabilityMsg(); + imsg.setL3NetworkUuid(msg.getL3NetworkUuid()); + imsg.setIp(msg.getIp()); + imsg.setArpCheck(msg.getArpCheck()); + imsg.setIpRangeCheck(msg.getIpRangeCheck()); + + FlowChain flowChain = new SimpleFlowChain(); + flowChain.setName(String.format("check-ip-address-availability-%s-%s", + msg.getL3NetworkUuid(), msg.getIp())); + for (CheckIpAddressAvailabilityExtensionPoint exp : pluginRgty.getExtensionList(CheckIpAddressAvailabilityExtensionPoint.class)) { + flowChain.then(new NoRollbackFlow() { + String __name__ = "check-ip-address-availability-" + exp.getClass().getSimpleName(); + + @Override + public boolean skip(Map data) { + return !reply.isAvailable(); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + exp.check(imsg, new ReturnValueCompletion(trigger) { + @Override + public void success(CheckIpAvailabilityReply r) { + if (!r.isAvailable()) { + reply.setAvailable(r.isAvailable()); + reply.setReason(r.getReason()); + trigger.next(); + } else { + trigger.next(); + } + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next(); + } + }); + } + }); + } + flowChain.done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + bus.reply(msg, reply); + } + }).start(); } private void handle(final APIGetL3NetworkRouterInterfaceIpMsg msg) { @@ -427,28 +936,75 @@ private void handle(final APISetL3NetworkRouterInterfaceIpMsg msg) { bus.publish(event); } + private void detachNetworkServiceFromL3NetworkMsg(L3NetworkVO l3VO, List refs, Completion completion) { + List networkServiceProviderVOS = Q.New(NetworkServiceProviderVO.class).list(); + Map providerUuidTypeMap = new HashMap<>(); + for (NetworkServiceProviderVO providerVO : networkServiceProviderVOS) { + providerUuidTypeMap.put(providerVO.getUuid(), providerVO.getType()); + } + + new While<>(refs).each((ref, wcomp) -> { + NetworkServiceProviderType pType = NetworkServiceProviderType.valueOf(providerUuidTypeMap.get(ref.getNetworkServiceProviderUuid())); + NetworkServiceType nsType = NetworkServiceType.valueOf(ref.getNetworkServiceType()); + + nsMgr.disableNetworkService(l3VO, pType, nsType, new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.success(); + } + }); + } + private void handle(APIDetachNetworkServiceFromL3NetworkMsg msg) { + APIDetachNetworkServiceFromL3NetworkEvent evt = new APIDetachNetworkServiceFromL3NetworkEvent(msg.getId()); + + List refs = new ArrayList<>(); + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + for (Map.Entry> e : msg.getNetworkServices().entrySet()) { SimpleQuery q = dbf.createQuery(NetworkServiceL3NetworkRefVO.class); q.add(NetworkServiceL3NetworkRefVO_.networkServiceProviderUuid, Op.EQ, e.getKey()); q.add(NetworkServiceL3NetworkRefVO_.l3NetworkUuid, Op.EQ, self.getUuid()); q.add(NetworkServiceL3NetworkRefVO_.networkServiceType, Op.IN, e.getValue()); - List refs = q.list(); + refs.addAll(q.list()); + } - if (refs.isEmpty()) { - logger.warn(String.format("no network service references found for the provider[uuid:%s] and L3 network[uuid:%s]", - e.getKey(), self.getUuid())); - } else { + if (refs.isEmpty()) { + self = dbf.reload(self); + evt.setInventory(L3NetworkInventory.valueOf(self)); + bus.publish(evt); + return; + } + + detachNetworkServiceFromL3NetworkMsg(l3VO, refs, new Completion(msg) { + @Override + public void success() { dbf.removeCollection(refs, NetworkServiceL3NetworkRefVO.class); + logger.debug(String.format("successfully detached network service provider[uuid:%s]", JSONObjectUtil.dumpPretty(refs))); + self = dbf.reload(self); + evt.setInventory(L3NetworkInventory.valueOf(self)); + bus.publish(evt); } - logger.debug(String.format("successfully detached network service provider[uuid:%s] to l3network[uuid:%s, name:%s] with services%s", e.getKey(), self.getUuid(), self.getName(), e.getValue())); - } - - self = dbf.reload(self); - APIDetachNetworkServiceFromL3NetworkEvent evt = new APIDetachNetworkServiceFromL3NetworkEvent(msg.getId()); - evt.setInventory(L3NetworkInventory.valueOf(self)); - bus.publish(evt); + @Override + public void fail(ErrorCode errorCode) { + logger.debug(String.format("detached network service provider[uuid:%s] failed:%s", JSONObjectUtil.dumpPretty(refs), errorCode.getDetails())); + self = dbf.reload(self); + evt.setInventory(L3NetworkInventory.valueOf(self)); + bus.publish(evt); + } + }); } private void handle(APIUpdateIpRangeMsg msg) { @@ -470,33 +1026,6 @@ private void handle(APIUpdateIpRangeMsg msg) { bus.publish(evt); } - private List getFreeIp(final IpRangeVO ipr, int limit, String start) { - SimpleQuery q = dbf.createQuery(UsedIpVO.class); - q.select(UsedIpVO_.ip); - q.add(UsedIpVO_.ipRangeUuid, Op.EQ, ipr.getUuid()); - - List used = q.listValue(); - used = used.stream().distinct().collect(Collectors.toList()); - - List spareIps = new ArrayList<>(); - if (ipr.getIpVersion() == IPv6Constants.IPv6) { - spareIps.addAll(NetworkUtils.getFreeIpv6InRange(ipr.getStartIp(), ipr.getEndIp(), used, limit, start)); - } else { - spareIps.addAll(NetworkUtils.getFreeIpInRange(ipr.getStartIp(), ipr.getEndIp(), used, limit, start)); - } - return CollectionUtils.transformToList(spareIps, new Function() { - @Override - public FreeIpInventory call(String arg) { - FreeIpInventory f = new FreeIpInventory(); - f.setGateway(ipr.getGateway()); - f.setIp(arg); - f.setNetmask(ipr.getNetmask()); - f.setIpRangeUuid(ipr.getUuid()); - return f; - } - }); - } - private void handle(APIGetFreeIpMsg msg) { APIGetFreeIpReply reply = new APIGetFreeIpReply(); @@ -548,7 +1077,7 @@ private void handle(APIGetFreeIpMsg msg) { start = "0.0.0.0"; } } - List tempFreeIpInventorys = getFreeIp(ipRangeVO, limit,start); + List tempFreeIpInventorys = IpRangeHelper.getFreeIp(ipRangeVO, limit,start); freeIpInventorys.addAll(tempFreeIpInventorys); if (freeIpInventorys.size() >= msg.getLimit()) { break; @@ -590,45 +1119,73 @@ private void handle(APIUpdateL3NetworkMsg msg) { private void handle(APIAddIpRangeByNetworkCidrMsg msg) { - IpRangeInventory ipr = IpRangeInventory.fromMessage(msg); - IpRangeFactory factory = l3NwMgr.getIpRangeFactory(ipr.getIpRangeType()); - IpRangeInventory inv = factory.createIpRange(ipr, msg); - - tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); + List iprs = IpRangeInventory.fromMessage(msg); + APIAddIpRangeByNetworkCidrEvent evt = new APIAddIpRangeByNetworkCidrEvent(msg.getId()); - setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + IpRangeFactory factory = l3NwMgr.getIpRangeFactory(iprs.get(0).getIpRangeType()); + factory.createIpRange(iprs, msg, new ReturnValueCompletion>(msg) { + @Override + public void success(List invs) { + IpRangeInventory inv = invs.get(0); + tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); + setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + evt.setInventory(inv); + evt.setInventories(invs); + bus.publish(evt); + } - APIAddIpRangeByNetworkCidrEvent evt = new APIAddIpRangeByNetworkCidrEvent(msg.getId()); - evt.setInventory(inv); - bus.publish(evt); + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } private void handle(APIAddIpv6RangeByNetworkCidrMsg msg) { IpRangeInventory ipr = IpRangeInventory.fromMessage(msg); - IpRangeFactory factory = l3NwMgr.getIpRangeFactory(ipr.getIpRangeType()); - IpRangeInventory inv = factory.createIpRange(ipr, msg); - - tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName());; + APIAddIpRangeByNetworkCidrEvent evt = new APIAddIpRangeByNetworkCidrEvent(msg.getId()); - setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + IpRangeFactory factory = l3NwMgr.getIpRangeFactory(ipr.getIpRangeType()); + factory.createIpRange(Collections.singletonList(ipr), msg, new ReturnValueCompletion>(msg) { + @Override + public void success(List invs) { + IpRangeInventory inv = invs.get(0); + tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); + setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + evt.setInventory(inv); + bus.publish(evt); + } - APIAddIpRangeByNetworkCidrEvent evt = new APIAddIpRangeByNetworkCidrEvent(msg.getId()); - evt.setInventory(inv); - bus.publish(evt); + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } private void handle(APIAddIpv6RangeMsg msg) { IpRangeInventory ipr = IpRangeInventory.fromMessage(msg); - IpRangeFactory factory = l3NwMgr.getIpRangeFactory(ipr.getIpRangeType()); - IpRangeInventory inv = factory.createIpRange(ipr, msg); - - tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); + APIAddIpRangeEvent evt = new APIAddIpRangeEvent(msg.getId()); - setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + IpRangeFactory factory = l3NwMgr.getIpRangeFactory(ipr.getIpRangeType()); + factory.createIpRange(Collections.singletonList(ipr), msg, new ReturnValueCompletion>(msg) { + @Override + public void success(List invs) { + IpRangeInventory inv = invs.get(0); + tagMgr.createTagsFromAPICreateMessage(msg, inv.getL3NetworkUuid(), L3NetworkVO.class.getSimpleName()); + setIpRangeSharedResource(msg.getL3NetworkUuid(), inv.getUuid()); + evt.setInventory(inv); + bus.publish(evt); + } - APIAddIpRangeEvent evt = new APIAddIpRangeEvent(msg.getId()); - evt.setInventory(inv); - bus.publish(evt); + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } @@ -651,6 +1208,8 @@ private void handle(APIChangeL3NetworkStateMsg msg) { private void handle(final APIRemoveDnsFromL3NetworkMsg msg) { final APIRemoveDnsFromL3NetworkEvent evt = new APIRemoveDnsFromL3NetworkEvent(msg.getId()); + SdnControllerDhcp sdnDhcp = l3NwMgr.getSdnControllerDhcp(msg.getL3NetworkUuid()); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("remove-dns-%s-from-l3-%s", msg.getDns(), msg.getL3NetworkUuid())); chain.then(new ShareFlow() { @@ -673,10 +1232,50 @@ public void run(FlowTrigger trigger, Map data) { } }); - if (!self.getNetworkServices().isEmpty()) { + flow(new NoRollbackFlow() { + String __name__ = "remove-dns-from-sdn"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (!self.enableIpAddressAllocation()) { + trigger.next(); + return; + } + + if (sdnDhcp == null) { + trigger.next(); + return; + } + + List iprs = IpRangeHelper.getNormalIpRanges(self); + if (iprs.isEmpty()) { + trigger.next(); + return; + } + + sdnDhcp.enableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(self)), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + if (L3NetworkConstant.L3_BASIC_NETWORK_TYPE.equals(self.getType()) && !self.getNetworkServices().isEmpty()) { flow(new NoRollbackFlow() { String __name__ = "remove-dns-from-backend"; + @Override + public boolean skip(Map data) { + return sdnDhcp != null; + } + @Override public void run(final FlowTrigger trigger, Map data) { RemoveDnsMsg rmsg = new RemoveDnsMsg(); @@ -719,6 +1318,8 @@ public void handle(ErrorCode errCode, Map data) { private void handle(final APIAddDnsToL3NetworkMsg msg) { final APIAddDnsToL3NetworkEvent evt = new APIAddDnsToL3NetworkEvent(msg.getId()); + SdnControllerDhcp sdnDhcp = l3NwMgr.getSdnControllerDhcp(msg.getL3NetworkUuid()); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("add-dns-%s-to-l3-%s", msg.getDns(), msg.getL3NetworkUuid())); chain.then(new ShareFlow() { @@ -749,10 +1350,50 @@ public void rollback(FlowRollback trigger, Map data) { } }); - if (!self.getNetworkServices().isEmpty()) { + flow(new NoRollbackFlow() { + String __name__ = "apply-to-sdn"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (!self.enableIpAddressAllocation()) { + trigger.next(); + return; + } + + if (sdnDhcp == null) { + trigger.next(); + return; + } + + List iprs = IpRangeHelper.getNormalIpRanges(self); + if (iprs.isEmpty()) { + trigger.next(); + return; + } + + sdnDhcp.enableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(self)), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + if (L3NetworkConstant.L3_BASIC_NETWORK_TYPE.equals(self.getType()) && !self.getNetworkServices().isEmpty()) { flow(new NoRollbackFlow() { String __name__ = "apply-to-backend"; + @Override + public boolean skip(Map data) { + return sdnDhcp != null; + } + @Override public void run(final FlowTrigger trigger, Map data) { AddDnsMsg amsg = new AddDnsMsg(); @@ -796,17 +1437,75 @@ public void handle(ErrorCode errCode, Map data) { private void handle(final AttachNetworkServiceToL3Msg msg) { MessageReply reply = new MessageReply(); + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + List networkServiceProviderVOS = Q.New(NetworkServiceProviderVO.class).list(); + Map providerUuidTypeMap = new HashMap<>(); + for (NetworkServiceProviderVO providerVO : networkServiceProviderVOS) { + providerUuidTypeMap.put(providerVO.getUuid(), providerVO.getType()); + } + + List refVOS = new ArrayList<>(); for (Map.Entry> e : msg.getNetworkServices().entrySet()) { for (String nsType : e.getValue()) { NetworkServiceL3NetworkRefVO ref = new NetworkServiceL3NetworkRefVO(); ref.setL3NetworkUuid(self.getUuid()); ref.setNetworkServiceProviderUuid(e.getKey()); ref.setNetworkServiceType(nsType); - dbf.persist(ref); + refVOS.add(ref); } logger.debug(String.format("successfully attached network service provider[uuid:%s] to l3network[uuid:%s, name:%s] with services%s", e.getKey(), self.getUuid(), self.getName(), e.getValue())); } - bus.reply(msg, reply); + + dbf.persistCollection(refVOS); + + new While<>(refVOS).each((ref, wcomp) -> { + String provideType = providerUuidTypeMap.get(ref.getNetworkServiceProviderUuid()); + NetworkServiceProviderType ptype = NetworkServiceProviderType.valueOf(provideType); + NetworkServiceType nsType = null; + try { + /* some network service are not in NetworkServiceType + * if it need enable/disable, then add it later */ + nsType = NetworkServiceType.valueOf(ref.getNetworkServiceType()); + } catch (Exception e) { + logger.debug(e.toString()); + wcomp.done(); + return; + } + + nsMgr.enableNetworkService(l3VO, ptype, nsType, msg.getApiSystemTags(), new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.addError(errorCode); + wcomp.allDone(); + } + }); + }).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + bus.reply(msg, reply); + } else { + detachNetworkServiceFromL3NetworkMsg(l3VO, refVOS, new Completion(msg) { + @Override + public void success() { + reply.setError(errorCodeList.getCauses().get(0)); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCodeList.getCauses().get(0)); + bus.reply(msg, reply); + } + }); + } + } + }); } private void handle(APIAttachNetworkServiceToL3NetworkMsg msg) { @@ -814,6 +1513,9 @@ private void handle(APIAttachNetworkServiceToL3NetworkMsg msg) { AttachNetworkServiceToL3Msg amsg = new AttachNetworkServiceToL3Msg(); amsg.setL3NetworkUuid(msg.getL3NetworkUuid()); amsg.setNetworkServices(msg.getNetworkServices()); + if (msg.getSystemTags() != null) { + amsg.setApiSystemTags(msg.getSystemTags()); + } bus.makeTargetServiceIdByResourceUuid(amsg, L3NetworkConstant.SERVICE_ID, msg.getL3NetworkUuid()); bus.send(amsg, new CloudBusCallBack(msg) { @@ -832,15 +1534,12 @@ public void run(MessageReply reply) { } - private void handle(APIDeleteIpRangeMsg msg) { + private void doDeleteIpRange(APIDeleteIpRangeMsg msg, Completion completion) { IpRangeVO vo = dbf.findByUuid(msg.getUuid(), IpRangeVO.class); - self = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); - - final APIDeleteIpRangeEvent evt = new APIDeleteIpRangeEvent(msg.getId()); final String issuer = IpRangeVO.class.getSimpleName(); final List ctx = IpRangeInventory.valueOf(Arrays.asList(vo)); FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); - chain.setName(String.format("delete-ip-range-%s", msg.getUuid())); + chain.setName(String.format("delete-ip-range-%s", vo.getUuid())); if (msg.getDeletionMode() == APIDeleteMessage.DeletionMode.Permissive) { chain.then(new NoRollbackFlow() { @Override @@ -896,22 +1595,71 @@ public void fail(ErrorCode errorCode) { @Override public void handle(Map data) { casf.asyncCascadeFull(CascadeConstant.DELETION_CLEANUP_CODE, issuer, ctx, new NopeCompletion()); - bus.publish(evt); + completion.success(); } }).error(new FlowErrorHandler(msg) { @Override public void handle(ErrorCode errCode, Map data) { - evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errCode, errCode.getDetails())); - bus.publish(evt); + completion.fail(errCode); } }).start(); } - private void handle(APIDeleteL3NetworkMsg msg) { - final APIDeleteL3NetworkEvent evt = new APIDeleteL3NetworkEvent(msg.getId()); + private void syncManagementServiceTypeWhileDelete(ServiceTypeExtensionPoint ext, L2NetworkVO l2NetworkVO, List hostUuids) { + String l2NetworkType = l2NetworkVO.getType(); + switch (l2NetworkType) { + case L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE: + case L2NetworkConstant.HARDWARE_VXLAN_NETWORK_TYPE: + case L2NetworkConstant.L2_VLAN_NETWORK_TYPE: + ext.syncManagementServiceTypeExtensionPoint(hostUuids, l2NetworkVO.getPhysicalInterface(), l2NetworkVO.getVirtualNetworkId(), true); + break; + + default: + break; + } + } + + private void handle(APIDeleteIpRangeMsg msg) { + self = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + final APIDeleteIpRangeEvent evt = new APIDeleteIpRangeEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSyncId(); + } + + @Override + public String getName() { + return "delete-ip-range-" + msg.getIpRangeUuid(); + } + + @Override + public void run(SyncTaskChain chain) { + doDeleteIpRange(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + } + ); + } + + private void doDeleteL3Network(APIDeleteL3NetworkMsg msg, Completion completion) { final String issuer = L3NetworkVO.class.getSimpleName(); final List ctx = L3NetworkInventory.valueOf(Arrays.asList(self)); FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + L3NetworkVO l3NetworkVO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + L2NetworkVO l2NetworkVO = dbf.findByUuid(l3NetworkVO.getL2NetworkUuid(), L2NetworkVO.class); chain.setName(String.format("delete-l3-network-%s", msg.getUuid())); if (msg.getDeletionMode() == APIDeleteMessage.DeletionMode.Permissive) { chain.then(new NoRollbackFlow() { @@ -968,16 +1716,44 @@ public void fail(ErrorCode errorCode) { @Override public void handle(Map data) { casf.asyncCascadeFull(CascadeConstant.DELETION_CLEANUP_CODE, issuer, ctx, new NopeCompletion()); - bus.publish(evt); + boolean isExistSystemL3 = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.system, true) + .eq(L3NetworkVO_.l2NetworkUuid, l2NetworkVO.getUuid()).isExists(); + List clusterUuids = Q.New(L2NetworkClusterRefVO.class).select(L2NetworkClusterRefVO_.clusterUuid) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2NetworkVO.getUuid()).listValues(); + if (!isExistSystemL3) { + if (clusterUuids != null && !clusterUuids.isEmpty()) { + List hostUuids = Q.New(HostVO.class).select(HostVO_.uuid) + .in(HostVO_.clusterUuid, clusterUuids).listValues(); + for (ServiceTypeExtensionPoint ext : pluginRgty.getExtensionList(ServiceTypeExtensionPoint.class)) { + syncManagementServiceTypeWhileDelete(ext, l2NetworkVO, hostUuids); + } + } + } + completion.success(); } }).error(new FlowErrorHandler(msg) { @Override public void handle(ErrorCode errCode, Map data) { - evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errCode, errCode.getDetails())); - bus.publish(evt); + completion.fail(errCode); } }).start(); } + private void handle(APIDeleteL3NetworkMsg msg) { + final APIDeleteL3NetworkEvent evt = new APIDeleteL3NetworkEvent(msg.getId()); + + doDeleteL3Network(msg, new Completion(msg) { + @Override + public void success() { + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); + } private void handle(APIAddHostRouteToL3NetworkMsg msg) { final APIAddHostRouteToL3NetworkEvent evt = new APIAddHostRouteToL3NetworkEvent(msg.getId()); diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java b/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java index cd495d35162..267f67f1aa4 100755 --- a/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkApiInterceptor.java @@ -7,17 +7,19 @@ import org.apache.commons.validator.routines.DomainValidator; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; -import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; import org.zstack.header.apimediator.StopRoutingException; +import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.message.APIMessage; import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.*; +import org.zstack.header.storage.snapshot.group.MemorySnapshotValidatorExtensionPoint; import org.zstack.header.zone.ZoneVO; import org.zstack.header.zone.ZoneVO_; import org.zstack.network.service.MtuGetter; @@ -28,10 +30,7 @@ import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import static org.zstack.core.Platform.argerr; @@ -49,21 +48,27 @@ public class L3NetworkApiInterceptor implements ApiMessageInterceptor { @Autowired private DatabaseFacade dbf; @Autowired - private ErrorFacade errf; + protected PluginRegistry pluginRgty; private final static CLogger logger = Utils.getLogger(L3NetworkApiInterceptor.class); private void setServiceId(APIMessage msg) { if (msg instanceof IpRangeMessage) { - IpRangeMessage dmsg = (IpRangeMessage)msg; + IpRangeMessage dmsg = (IpRangeMessage) msg; SimpleQuery q = dbf.createQuery(IpRangeVO.class); q.select(IpRangeVO_.l3NetworkUuid); q.add(IpRangeVO_.uuid, SimpleQuery.Op.EQ, dmsg.getIpRangeUuid()); String l3NwUuid = q.findValue(); + if (l3NwUuid == null) { + SimpleQuery rq = dbf.createQuery(ReservedIpRangeVO.class); + rq.select(ReservedIpRangeVO_.l3NetworkUuid); + rq.add(ReservedIpRangeVO_.uuid, SimpleQuery.Op.EQ, dmsg.getIpRangeUuid()); + l3NwUuid = rq.findValue(); + } dmsg.setL3NetworkUuid(l3NwUuid); bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, l3NwUuid); } else if (msg instanceof L3NetworkMessage) { - L3NetworkMessage l3msg = (L3NetworkMessage)msg; + L3NetworkMessage l3msg = (L3NetworkMessage) msg; bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, l3msg.getL3NetworkUuid()); } } @@ -104,6 +109,10 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIDeleteIpRangeMsg) msg); } else if (msg instanceof APISetL3NetworkMtuMsg) { validate((APISetL3NetworkMtuMsg) msg); + } else if (msg instanceof APIAddReservedIpRangeMsg) { + validate((APIAddReservedIpRangeMsg) msg); + } else if (msg instanceof APIDeleteIpAddressMsg) { + validate((APIDeleteIpAddressMsg) msg); } setServiceId(msg); @@ -111,6 +120,102 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti return msg; } + private void validate(APIDeleteIpAddressMsg msg) { + for (String uuid : msg.getUsedIpUuids()) { + UsedIpVO vo = dbf.findByUuid(uuid, UsedIpVO.class); + if (vo.getVmNicUuid() != null) { + throw new ApiMessageInterceptionException(argerr("could delete ip address, " + + "because it's used by vmnic[uuid:%s]", vo.getVmNicUuid())); + } + } + } + + private void validate(APIAddReservedIpRangeMsg msg) { + L3NetworkVO l3NetworkVO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + if (!NetworkUtils.isValidIPAddress(msg.getStartIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because start ip[%s] is not valid ip address", msg.getStartIp())); + } + + if (!NetworkUtils.isValidIPAddress(msg.getEndIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because start ip[%s] is not valid ip address", msg.getStartIp())); + } + + if (NetworkUtils.isIpv4Address(msg.getStartIp()) && !NetworkUtils.isIpv4Address(msg.getEndIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because end ip[%s] is not ipv4 address", msg.getEndIp())); + } + + if (IPv6NetworkUtils.isIpv6Address(msg.getStartIp()) && !IPv6NetworkUtils.isIpv6Address(msg.getEndIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because end ip[%s] is not ipv6 address", msg.getEndIp())); + } + + if (!IPv6NetworkUtils.isValidIpRange(msg.getStartIp(), msg.getEndIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because end ip[%s] is less than start ip[%s]", msg.getEndIp(), msg.getStartIp())); + } + + if (NetworkUtils.isIpv4Address(msg.getStartIp())) { + List ipv4Ranges = l3NetworkVO.getIpRanges().stream() + .filter(ipr -> (ipr.getIpVersion() == IPv6Constants.IPv4)) + .collect(Collectors.toList()); + if (ipv4Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because there is no ipv4 range")); + } + + if (!NetworkUtils.isIpv4InCidr(msg.getStartIp(), ipv4Ranges.get(0).getNetworkCidr()) || + !NetworkUtils.isIpv4InCidr(msg.getEndIp(), ipv4Ranges.get(0).getNetworkCidr())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because reserve ip is not in ip range[%s]", ipv4Ranges.get(0).getNetworkCidr())); + } + + List reservedIpv4Ranges = l3NetworkVO.getReservedIpRanges().stream() + .filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv4) + .collect(Collectors.toList()); + for (ReservedIpRangeVO reserveRange : reservedIpv4Ranges) { + if (NetworkUtils.isIpv4RangeOverlap(msg.getStartIp(), msg.getEndIp(), + reserveRange.getStartIp(), reserveRange.getEndIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because new range [%s:%s] is overlapped with old range", + msg.getStartIp(), msg.getEndIp(), + reserveRange.getStartIp(), reserveRange.getEndIp())); + } + } + } + + if (IPv6NetworkUtils.isIpv6Address(msg.getStartIp())) { + List ipv6Ranges = l3NetworkVO.getIpRanges().stream() + .filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv6) + .collect(Collectors.toList()); + if (ipv6Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because there is no ipv6 range")); + } + + if (!IPv6NetworkUtils.isIpv6InCidrRange(msg.getStartIp(), ipv6Ranges.get(0).getNetworkCidr()) || + !IPv6NetworkUtils.isIpv6InCidrRange(msg.getEndIp(), ipv6Ranges.get(0).getNetworkCidr())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because reserve ip is not in ip range[%s]", ipv6Ranges.get(0).getNetworkCidr())); + } + + List reservedIpv6Ranges = l3NetworkVO.getReservedIpRanges().stream() + .filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv6) + .collect(Collectors.toList()); + for (ReservedIpRangeVO reserveRange : reservedIpv6Ranges) { + if (IPv6NetworkUtils.isIpv6RangeOverlap(msg.getStartIp(), msg.getEndIp(), + reserveRange.getStartIp(), reserveRange.getEndIp())) { + throw new ApiMessageInterceptionException(argerr("could not reserve ip range, " + + "because new range [%s:%s] is overlapped with old range", + msg.getStartIp(), msg.getEndIp(), + reserveRange.getStartIp(), reserveRange.getEndIp())); + } + } + } + } + private void validate(APISetL3NetworkMtuMsg msg) { L3NetworkVO l3Vo = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); L2NetworkVO l2VO = dbf.findByUuid(l3Vo.getL2NetworkUuid(), L2NetworkVO.class); @@ -145,7 +250,7 @@ private void validate(APISetL3NetworkMtuMsg msg) { Integer mtu; if (novlanL2 == null) { mtu = NetworkServiceGlobalConfig.DHCP_MTU_NO_VLAN.value(Integer.class); - }else { + } else { mtu = new MtuGetter().getL2Mtu(L2NetworkInventory.valueOf(novlanL2)); } @@ -184,9 +289,9 @@ private void validate(APIUpdateL3NetworkMsg msg) { } Boolean currentSystem = Q.New(L3NetworkVO.class) - .select(L3NetworkVO_.system) - .eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()) - .findValue(); + .select(L3NetworkVO_.system) + .eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()) + .findValue(); if (msg.getSystem() != null && msg.getCategory() == null && !msg.getSystem().equals(currentSystem)) { throw new ApiMessageInterceptionException(argerr("you must update system and category both")); } @@ -248,7 +353,7 @@ private void validate(APIGetFreeIpMsg msg) { if (msg.getIpRangeUuid() != null && msg.getL3NetworkUuid() == null) { IpRangeVO ipRangeVO = Q.New(IpRangeVO.class) - .eq(IpRangeVO_.uuid,msg.getIpRangeUuid()) + .eq(IpRangeVO_.uuid, msg.getIpRangeUuid()) .find(); msg.setL3NetworkUuid(ipRangeVO.getL3NetworkUuid()); msg.setIpVersion(ipRangeVO.getIpVersion()); @@ -261,20 +366,20 @@ private void validate(APIGetFreeIpMsg msg) { if (msg.getIpVersion() == null) { if (msg.getL3NetworkUuid() != null) { int l3Version = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()) - .select(L3NetworkVO_.ipVersion).findValue(); + .select(L3NetworkVO_.ipVersion).findValue(); msg.setIpVersion(l3Version); - }else { + } else { msg.setIpVersion(IPv6Constants.IPv4); } } - if(msg.getStart() != null){ - if(msg.getIpVersion() == IPv6Constants.DUAL_STACK){ - throw new ApiMessageInterceptionException(argerr("could not get free ip with start[ip:%s],because l3Network[uuid:%s] is dual stack",msg.getStart(),msg.getL3NetworkUuid())); - } else if(msg.getIpVersion() == IPv6Constants.IPv4 && !NetworkUtils.isIpv4Address(msg.getStart())){ - throw new ApiMessageInterceptionException(argerr("could not get free ip with start[ip:%s],because start[ip:%s] is not a correct ipv4 address",msg.getStart(),msg.getStart())); - } else if(msg.getIpVersion() == IPv6Constants.IPv6 && !IPv6NetworkUtils.isIpv6Address(msg.getStart())){ - throw new ApiMessageInterceptionException(argerr("could not get free ip with start[ip:%s],because start[ip:%s] is not a correct ipv6 address",msg.getStart(),msg.getStart())); + if (msg.getStart() != null) { + if (msg.getIpVersion() == IPv6Constants.DUAL_STACK) { + throw new ApiMessageInterceptionException(argerr("could not get free ip with start[ip:%s],because l3Network[uuid:%s] is dual stack", msg.getStart(), msg.getL3NetworkUuid())); + } else if (msg.getIpVersion() == IPv6Constants.IPv4 && !NetworkUtils.isIpv4Address(msg.getStart())) { + throw new ApiMessageInterceptionException(argerr("could not get free ip with start[ip:%s],because start[ip:%s] is not a correct ipv4 address", msg.getStart(), msg.getStart())); + } else if (msg.getIpVersion() == IPv6Constants.IPv6 && !IPv6NetworkUtils.isIpv6Address(msg.getStart())) { + throw new ApiMessageInterceptionException(argerr("could not get free ip with start[ip:%s],because start[ip:%s] is not a correct ipv6 address", msg.getStart(), msg.getStart())); } } } @@ -401,9 +506,8 @@ private void validate(APIAddIpRangeByNetworkCidrMsg msg) { if (subnet.getAddressCount() == 0) { throw new ApiMessageInterceptionException(argerr("%s is not an allowed network cidr, because it doesn't have usable ip range", msg.getNetworkCidr())); } - - if (msg.getGateway() != null && !(msg.getGateway().equals(subnet.getLowAddress()) || msg.getGateway().equals(subnet.getHighAddress()))) { - throw new ApiMessageInterceptionException(argerr("%s is not the first or last address of the cidr %s", msg.getGateway(), msg.getNetworkCidr())); + if (msg.getGateway() != null && !subnet.isInRange(msg.getGateway())) { + throw new ApiMessageInterceptionException(argerr("the gateway[%s] is not in the subnet %s", msg.getGateway(), subnet.getCidrSignature())); } } catch (IllegalArgumentException e) { throw new ApiMessageInterceptionException(argerr("%s is not a valid network cidr", msg.getNetworkCidr())); @@ -413,8 +517,10 @@ private void validate(APIAddIpRangeByNetworkCidrMsg msg) { msg.setIpRangeType(IpRangeType.Normal.toString()); } - IpRangeInventory ipr = IpRangeInventory.fromMessage(msg); - validate(ipr); + List iprs = IpRangeInventory.fromMessage(msg); + for (IpRangeInventory ipr : iprs) { + validate(ipr); + } } private void validate(APIGetIpAddressCapacityMsg msg) { @@ -494,6 +600,13 @@ private void validate(APIDeleteL3NetworkMsg msg) { bus.publish(evt); throw new StopRoutingException(); } + + for (MemorySnapshotValidatorExtensionPoint ext : pluginRgty.getExtensionList(MemorySnapshotValidatorExtensionPoint.class)) { + ErrorCode errorCode = ext.checkL3IfReferencedByMemorySnapshot(msg.getL3NetworkUuid()); + if (errorCode != null) { + throw new ApiMessageInterceptionException(errorCode); + } + } } private void validateAddressPool(IpRangeInventory ipr) { @@ -531,16 +644,14 @@ private void validate(IpRangeInventory ipr) { SubnetUtils sub = new SubnetUtils(ipr.getStartIp(), ipr.getNetmask()); SubnetInfo info = sub.getInfo(); - if (ipr.getIpRangeType() == IpRangeType.Normal) { - if (!info.isInRange(ipr.getGateway())) { - throw new ApiMessageInterceptionException(argerr("the gateway[%s] is not in the subnet %s/%s", ipr.getGateway(), ipr.getStartIp(), ipr.getNetmask())); - } + if (!info.isInRange(ipr.getGateway())) { + throw new ApiMessageInterceptionException(argerr("the gateway[%s] is not in the subnet %s/%s", ipr.getGateway(), ipr.getStartIp(), ipr.getNetmask())); + } - if (ipr.getStartIp().equals(info.getNetworkAddress()) || ipr.getEndIp().equals(info.getBroadcastAddress())) { - throw new ApiMessageInterceptionException(argerr( - "ip allocation can not contain network address or broadcast address") - ); - } + if (ipr.getStartIp().equals(info.getNetworkAddress()) || ipr.getEndIp().equals(info.getBroadcastAddress())) { + throw new ApiMessageInterceptionException(argerr( + "ip allocation can not contain network address or broadcast address") + ); } if (!NetworkUtils.isIpv4Address(ipr.getStartIp())) { @@ -614,7 +725,7 @@ private void validate(IpRangeInventory ipr) { throw new ApiMessageInterceptionException(argerr("new add ip range gateway %s is different from old gateway %s", ipr.getGateway(), r.getGateway())); } } - } else if (ipr.getIpRangeType() == IpRangeType.AddressPool){ + } else if (ipr.getIpRangeType() == IpRangeType.AddressPool) { validateAddressPool(ipr); } } @@ -635,31 +746,31 @@ private void validate(APIAddIpRangeMsg msg) { msg.setGateway(msg.getStartIp()); } - IpRangeInventory ipr =IpRangeInventory.fromMessage(msg); + IpRangeInventory ipr = IpRangeInventory.fromMessage(msg); validate(ipr); } private void validate(APIAddDnsToL3NetworkMsg msg) { - if ( !NetworkUtils.isIpAddress(msg.getDns()) ) { + if (!NetworkUtils.isIpAddress(msg.getDns())) { throw new ApiMessageInterceptionException(argerr("dns[%s] is not a IP address", msg.getDns())); } List l3NetworkDnsVOS = Q.New(L3NetworkDnsVO.class).eq(L3NetworkDnsVO_.l3NetworkUuid, msg.getL3NetworkUuid()).list(); - if ( l3NetworkDnsVOS.isEmpty() ) { + if (l3NetworkDnsVOS.isEmpty()) { return; } - if ( NetworkUtils.isIpv4Address(msg.getDns()) ) { + if (NetworkUtils.isIpv4Address(msg.getDns())) { boolean exist = l3NetworkDnsVOS.stream().anyMatch(l3NetworkDnsVO -> msg.getDns().equals(l3NetworkDnsVO.getDns())); - if ( exist ) { + if (exist) { throw new ApiMessageInterceptionException(operr("there has been a DNS[%s] on L3 network[uuid:%s]", msg.getDns(), msg.getL3NetworkUuid())); } } else { - for ( L3NetworkDnsVO l3NetworkDnsVO : l3NetworkDnsVOS ) { - if ( !IPv6NetworkUtils.isIpv6Address(l3NetworkDnsVO.getDns()) ) { + for (L3NetworkDnsVO l3NetworkDnsVO : l3NetworkDnsVOS) { + if (!IPv6NetworkUtils.isIpv6Address(l3NetworkDnsVO.getDns())) { continue; } - if ( IPv6Address.fromString(msg.getDns()).toBigInteger().equals(IPv6Address.fromString(l3NetworkDnsVO.getDns()).toBigInteger()) ) { + if (IPv6Address.fromString(msg.getDns()).toBigInteger().equals(IPv6Address.fromString(l3NetworkDnsVO.getDns()).toBigInteger())) { throw new ApiMessageInterceptionException(operr("there has been a DNS[%s] on L3 network[uuid:%s]", msg.getDns(), msg.getL3NetworkUuid())); } } diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkExtensionPointEmitter.java b/network/src/main/java/org/zstack/network/l3/L3NetworkExtensionPointEmitter.java index 81ab4519235..34dc9f35674 100755 --- a/network/src/main/java/org/zstack/network/l3/L3NetworkExtensionPointEmitter.java +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkExtensionPointEmitter.java @@ -3,6 +3,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.header.Component; +import org.zstack.header.network.l3.L3NetworkCreateExtensionPoint; import org.zstack.header.network.l3.L3NetworkDeleteExtensionPoint; import org.zstack.header.network.l3.L3NetworkException; import org.zstack.header.network.l3.L3NetworkInventory; @@ -15,13 +16,23 @@ public class L3NetworkExtensionPointEmitter implements Component { private static final CLogger logger = Utils.getLogger(L3NetworkExtensionPointEmitter.class); - private List extensions = null; + private List createExtensions = null; + private List deleteExtensions = null; @Autowired private PluginRegistry pluginRgty; + public void afterCreate(L3NetworkInventory inv) { + CollectionUtils.safeForEach(createExtensions, new ForEachFunction() { + @Override + public void run(L3NetworkCreateExtensionPoint arg) { + arg.afterCreateL3Network(inv); + } + }); + } + public void preDelete(L3NetworkInventory inv) throws L3NetworkException { - for (L3NetworkDeleteExtensionPoint ext : extensions) { + for (L3NetworkDeleteExtensionPoint ext : deleteExtensions) { try { ext.preDeleteL3Network(inv); } catch (L3NetworkException l3e) { @@ -34,7 +45,7 @@ public void preDelete(L3NetworkInventory inv) throws L3NetworkException { } public void beforeDelete(final L3NetworkInventory inv) { - CollectionUtils.safeForEach(extensions, new ForEachFunction() { + CollectionUtils.safeForEach(deleteExtensions, new ForEachFunction() { @Override public void run(L3NetworkDeleteExtensionPoint arg) { arg.beforeDeleteL3Network(inv); @@ -43,7 +54,7 @@ public void run(L3NetworkDeleteExtensionPoint arg) { } public void afterDelete(final L3NetworkInventory inv) { - CollectionUtils.safeForEach(extensions, new ForEachFunction() { + CollectionUtils.safeForEach(deleteExtensions, new ForEachFunction() { @Override public void run(L3NetworkDeleteExtensionPoint arg) { arg.afterDeleteL3Network(inv); @@ -58,7 +69,8 @@ public boolean start() { } private void populateExtensions() { - extensions = pluginRgty.getExtensionList(L3NetworkDeleteExtensionPoint.class); + createExtensions = pluginRgty.getExtensionList(L3NetworkCreateExtensionPoint.class); + deleteExtensions = pluginRgty.getExtensionList(L3NetworkDeleteExtensionPoint.class); } @Override diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkGlobalConfig.java b/network/src/main/java/org/zstack/network/l3/L3NetworkGlobalConfig.java new file mode 100644 index 00000000000..4c7ad6fe4ea --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkGlobalConfig.java @@ -0,0 +1,27 @@ +package org.zstack.network.l3; + +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; +import org.zstack.core.config.GlobalConfigDefinition; +import org.zstack.core.config.GlobalConfigValidation; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkConstant; +import org.zstack.resourceconfig.BindResourceConfig; + +@GlobalConfigDefinition +public class L3NetworkGlobalConfig { + public static final String CATEGORY = "l3Network"; + + @GlobalConfigDef(defaultValue = L3NetworkConstant.RANDOM_IP_ALLOCATOR_STRATEGY, type = String.class, description = "ip allocate strategy") + @GlobalConfigValidation(validValues = {L3NetworkConstant.FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY, L3NetworkConstant.RANDOM_IP_ALLOCATOR_STRATEGY, L3NetworkConstant.ASC_DELAY_RECYCLE_IP_ALLOCATOR_STRATEGY}) + @BindResourceConfig({L3NetworkVO.class}) + public static GlobalConfig IP_ALLOCATE_STRATEGY = new GlobalConfig(CATEGORY, "ipAllocateStrategy"); + + @GlobalConfigDef(defaultValue = L3NetworkConstant.RANDOM_IPV6_ALLOCATOR_STRATEGY, type = String.class, description = "ipv6 allocate strategy") + @GlobalConfigValidation(validValues = {L3NetworkConstant.FIRST_AVAILABLE_IPV6_ALLOCATOR_STRATEGY, L3NetworkConstant.RANDOM_IPV6_ALLOCATOR_STRATEGY}) + @BindResourceConfig({L3NetworkVO.class}) + public static GlobalConfig IPV6_ALLOCATE_STRATEGY = new GlobalConfig(CATEGORY, "ipv6AllocateStrategy"); + + @GlobalConfigValidation + public static GlobalConfig BASIC_NETWORK_ENABLE_RA = new GlobalConfig(CATEGORY, "basic.network.enable.ra"); +} diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkHelper.java b/network/src/main/java/org/zstack/network/l3/L3NetworkHelper.java new file mode 100644 index 00000000000..3863c0bb4d6 --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkHelper.java @@ -0,0 +1,35 @@ +package org.zstack.network.l3; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.Q; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.network.l2.L2NetworkSystemTags; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class L3NetworkHelper { + + public static String getL3networkVSwitchType(String l3Uuid) { + String l2Uuid = Q.New(L3NetworkVO.class) + .select(L3NetworkVO_.l2NetworkUuid) + .eq(L3NetworkVO_.uuid, l3Uuid).findValue(); + return Q.New(L2NetworkVO.class) + .select(L2NetworkVO_.vSwitchType) + .eq(L2NetworkVO_.uuid, l2Uuid).findValue(); + } + + public static String getSdnControllerUuidFromL2Uuid(String l2Uuid) { + return L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2Uuid, L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + } + + public static String getSdnControllerUuidFromL3Uuid(String l3Uuid) { + String l2Uuid = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, l3Uuid) + .select(L3NetworkVO_.l2NetworkUuid).findValue(); + + return getSdnControllerUuidFromL2Uuid(l2Uuid); + } +} diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkManager.java b/network/src/main/java/org/zstack/network/l3/L3NetworkManager.java index e79212fc90b..eebbb11b747 100755 --- a/network/src/main/java/org/zstack/network/l3/L3NetworkManager.java +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkManager.java @@ -1,7 +1,10 @@ package org.zstack.network.l3; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.network.l3.*; +import org.zstack.header.network.service.SdnControllerDhcp; import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.vm.VmNicVO; import java.math.BigInteger; import java.util.List; @@ -21,9 +24,21 @@ public interface L3NetworkManager { void updateIpAllocationMsg(AllocateIpMsg msg, String mac); + void reAllocateNicIp(VmNicVO nicVO, ReturnValueCompletion> completion); + IpRangeFactory getIpRangeFactory(IpRangeType type); List filterVmNicByIpVersion(List vmNics, int ipVersion); boolean applyNetworkServiceWhenVmStateChange(String type); + + SdnControllerDhcp getSdnControllerDhcp(String l3Uuid); + + /** + * Resolve SDN controller L3 service bound to the given L2 network. + * + * @param l2Uuid L2Network UUID used to locate the SDN controller + * @return SdnControllerL3 implementation, or null if none is available + */ + SdnControllerL3 getSdnControllerL3(String l2Uuid); } diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkManagerImpl.java b/network/src/main/java/org/zstack/network/l3/L3NetworkManagerImpl.java index 0d1b179aa80..7c1ee6da361 100755 --- a/network/src/main/java/org/zstack/network/l3/L3NetworkManagerImpl.java +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkManagerImpl.java @@ -1,48 +1,59 @@ package org.zstack.network.l3; -import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException; +import java.sql.SQLIntegrityConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.*; -import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.core.defer.Deferred; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.AbstractService; -import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; -import org.zstack.header.identity.AccountResourceRefInventory; -import org.zstack.header.identity.Quota; -import org.zstack.header.identity.Quota.QuotaOperator; -import org.zstack.header.identity.Quota.QuotaPair; -import org.zstack.header.identity.ReportQuotaExtensionPoint; -import org.zstack.header.identity.ResourceOwnerPreChangeExtensionPoint; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.identity.*; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; -import org.zstack.header.message.NeedQuotaCheckMessage; -import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.*; import org.zstack.header.network.l3.datatypes.IpCapacityData; +import org.zstack.header.network.service.GetSdnControllerExtensionPoint; +import org.zstack.header.network.service.SdnControllerDhcp; import org.zstack.header.vm.VmNicInventory; import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; import org.zstack.header.zone.ZoneVO; import org.zstack.identity.AccountManager; import org.zstack.identity.ResourceSharingExtensionPoint; -import org.zstack.identity.QuotaUtil; import org.zstack.network.service.MtuGetter; import org.zstack.network.service.NetworkServiceSystemTag; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.resourceconfig.ResourceConfigUpdateExtensionPoint; +import org.zstack.tag.PatternedSystemTag; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; import org.zstack.utils.ExceptionDSL; import org.zstack.utils.ObjectUtils; import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; @@ -60,7 +71,7 @@ import static org.zstack.utils.CollectionDSL.*; public class L3NetworkManagerImpl extends AbstractService implements L3NetworkManager, ReportQuotaExtensionPoint, - ResourceOwnerPreChangeExtensionPoint, PrepareDbInitialValueExtensionPoint, ResourceSharingExtensionPoint { + ResourceOwnerPreChangeExtensionPoint, PrepareDbInitialValueExtensionPoint, ResourceSharingExtensionPoint, CheckIpAddressAvailabilityExtensionPoint { private static final CLogger logger = Utils.getLogger(L3NetworkManagerImpl.class); @Autowired @@ -77,6 +88,10 @@ public class L3NetworkManagerImpl extends AbstractService implements L3NetworkMa private ErrorFacade errf; @Autowired private TagManager tagMgr; + @Autowired + private ResourceConfigFacade rcf; + @Autowired + protected L3NetworkExtensionPointEmitter extpEmitter; private Map ipRangeFactories = Collections.synchronizedMap(new HashMap()); private Map l3NetworkFactories = Collections.synchronizedMap(new HashMap()); @@ -129,6 +144,7 @@ private void handleApiMessage(APIMessage msg) { private void handle(final APISetL3NetworkMtuMsg msg) { final APISetL3NetworkMtuEvent evt = new APISetL3NetworkMtuEvent(msg.getId()); + String oldmtu = NetworkServiceSystemTag.L3_MTU.getTokenByResourceUuid(msg.getL3NetworkUuid(), NetworkServiceSystemTag.MTU_TOKEN); NetworkServiceSystemTag.L3_MTU.delete(msg.getL3NetworkUuid()); SystemTagCreator creator = NetworkServiceSystemTag.L3_MTU.newSystemTagCreator(msg.getL3NetworkUuid()); creator.ignoreIfExisting = true; @@ -141,7 +157,66 @@ private void handle(final APISetL3NetworkMtuMsg msg) { ); creator.create(); - bus.publish(evt); + L3NetworkVO l3Vo = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName("change-l3-network-mtu"); + chain.then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + if (!l3Vo.enableIpAddressAllocation()) { + trigger.next(); + return; + } + + SdnControllerDhcp dhcp = getSdnControllerDhcp(msg.getL3NetworkUuid()); + if (dhcp == null) { + trigger.next(); + return; + } + + List iprs = IpRangeHelper.getNormalIpRanges(l3Vo); + if (iprs.isEmpty()) { + trigger.next(); + return; + } + + dhcp.enableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(l3Vo)), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.publish(evt); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + if (oldmtu != null) { + NetworkServiceSystemTag.L3_MTU.delete(msg.getL3NetworkUuid()); + SystemTagCreator creator = NetworkServiceSystemTag.L3_MTU.newSystemTagCreator(msg.getL3NetworkUuid()); + creator.recreate = true; + creator.inherent = false; + creator.setTagByTokens( + map( + e(NetworkServiceSystemTag.MTU_TOKEN, oldmtu), + e(NetworkServiceSystemTag.L3_UUID_TOKEN, msg.getL3NetworkUuid()) + ) + ); + creator.create(); + } + evt.setError(errCode); + bus.publish(evt); + } + }).start(); } private void handle(final APIGetL3NetworkMtuMsg msg) { @@ -199,23 +274,25 @@ private void calcElementTotalIp(List tuples, IpCapacity capacity) { for (Tuple tuple : tuples) { String sip = tuple.get(0, String.class); String eip = tuple.get(1, String.class); - int ipVersion = tuple.get(2, Integer.class); - String elementUuid = tuple.get(3, String.class); + int ipVersion = tuple.get(3, Integer.class); + String elementUuid = tuple.get(4, String.class); IpCapacity element = elements.getOrDefault(elementUuid, new IpCapacity()); elements.put(elementUuid, element); if (ipVersion == IPv6Constants.IPv4) { - int t = NetworkUtils.getTotalIpInRange(sip, eip); - element.total += t; - element.total = Math.min(element.total, Integer.MAX_VALUE); - element.avail = element.total; - element.ipv4TotalCapacity += t; - element.ipv4TotalCapacity = Math.min(element.ipv4TotalCapacity, Integer.MAX_VALUE); - element.ipv4AvailableCapacity = element.ipv4TotalCapacity; - ipv4TotalCapacity += t; - total += t; - ipv4TotalCapacity = Math.min(ipv4TotalCapacity, (long)Integer.MAX_VALUE); - total = Math.min(total, (long)Integer.MAX_VALUE); + if (NetworkUtils.isValidIpv4Range(sip, eip)) { + int t = NetworkUtils.getTotalIpInRange(sip, eip); + element.total += t; + element.total = Math.min(element.total, Integer.MAX_VALUE); + element.avail = element.total; + element.ipv4TotalCapacity += t; + element.ipv4TotalCapacity = Math.min(element.ipv4TotalCapacity, Integer.MAX_VALUE); + element.ipv4AvailableCapacity = element.ipv4TotalCapacity; + ipv4TotalCapacity += t; + total += t; + ipv4TotalCapacity = Math.min(ipv4TotalCapacity, (long) Integer.MAX_VALUE); + total = Math.min(total, (long) Integer.MAX_VALUE); + } } else { long t = IPv6NetworkUtils.getIpv6RangeSize(sip, eip); element.total += t; @@ -291,10 +368,11 @@ public IpCapacity call() { if (msg.getIpRangeUuids() != null && !msg.getIpRangeUuids().isEmpty()) { reply.setResourceType(IpRangeVO.class.getSimpleName()); - String sql = "select ipr.startIp, ipr.endIp, ipr.ipVersion, ipr.uuid from IpRangeVO ipr where ipr.uuid in (:uuids)"; + String sql = "select ipr.startIp, ipr.endIp, ipr.netmask, ipr.ipVersion, ipr.uuid from IpRangeVO ipr where ipr.uuid in (:uuids)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); q.setParameter("uuids", msg.getIpRangeUuids()); List ts = q.getResultList(); + ts = IpRangeHelper.stripNetworkAndBroadcastAddress(ts); calcElementTotalIp(ts, ret); sql = "select count(distinct uip.ip), uip.ipRangeUuid, uip.ipVersion from UsedIpVO uip where uip.ipRangeUuid in (:uuids) and (uip.metaData not in (:notAccountMetaData) or uip.metaData IS NULL) group by uip.ipRangeUuid, uip.ipVersion"; @@ -306,10 +384,11 @@ public IpCapacity call() { return ret; } else if (msg.getL3NetworkUuids() != null && !msg.getL3NetworkUuids().isEmpty()) { reply.setResourceType(L3NetworkVO.class.getSimpleName()); - String sql = "select ipr.startIp, ipr.endIp, ipr.ipVersion, l3.uuid from IpRangeVO ipr, L3NetworkVO l3 where ipr.l3NetworkUuid = l3.uuid and l3.uuid in (:uuids)"; + String sql = "select ipr.startIp, ipr.endIp, ipr.netmask, ipr.ipVersion, l3.uuid from IpRangeVO ipr, L3NetworkVO l3 where ipr.l3NetworkUuid = l3.uuid and l3.uuid in (:uuids)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); q.setParameter("uuids", msg.getL3NetworkUuids()); List ts = q.getResultList(); + ts = IpRangeHelper.stripNetworkAndBroadcastAddress(ts); calcElementTotalIp(ts, ret); sql = "select count(distinct uip.ip), uip.l3NetworkUuid, uip.ipVersion from UsedIpVO uip where uip.l3NetworkUuid in (:uuids) and (uip.metaData not in (:notAccountMetaData) or uip.metaData IS NULL) group by uip.l3NetworkUuid, uip.ipVersion"; @@ -321,10 +400,11 @@ public IpCapacity call() { return ret; } else if (msg.getZoneUuids() != null && !msg.getZoneUuids().isEmpty()) { reply.setResourceType(ZoneVO.class.getSimpleName()); - String sql = "select ipr.startIp, ipr.endIp, ipr.ipVersion, zone.uuid from IpRangeVO ipr, L3NetworkVO l3, ZoneVO zone where ipr.l3NetworkUuid = l3.uuid and l3.zoneUuid = zone.uuid and zone.uuid in (:uuids)"; + String sql = "select ipr.startIp, ipr.endIp, ipr.netmask, ipr.ipVersion, zone.uuid from IpRangeVO ipr, L3NetworkVO l3, ZoneVO zone where ipr.l3NetworkUuid = l3.uuid and l3.zoneUuid = zone.uuid and zone.uuid in (:uuids)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); q.setParameter("uuids", msg.getZoneUuids()); List ts = q.getResultList(); + ts = IpRangeHelper.stripNetworkAndBroadcastAddress(ts); calcElementTotalIp(ts, ret); sql = "select count(distinct uip.ip), zone.uuid, uip.ipVersion from UsedIpVO uip, L3NetworkVO l3, ZoneVO zone where uip.l3NetworkUuid = l3.uuid and l3.zoneUuid = zone.uuid and zone.uuid in (:uuids) and (uip.metaData not in (:notAccountMetaData) or uip.metaData IS NULL) group by zone.uuid, uip.ipVersion"; @@ -401,13 +481,28 @@ private void passThrough(L3NetworkMessage msg) { passThrough(msg.getL3NetworkUuid(), (Message) msg); } + private void syncManagementServiceTypeWhileCreate(ServiceTypeExtensionPoint ext, L2NetworkVO l2NetworkVO, List hostUuids) { + String l2NetworkType = l2NetworkVO.getType(); + switch (l2NetworkType) { + case L2NetworkConstant.VXLAN_NETWORK_TYPE: + ext.syncManagementServiceTypeExtensionPoint(hostUuids, "vxlan" + l2NetworkVO.getVirtualNetworkId(), null, false); + break; + case L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE: + case L2NetworkConstant.HARDWARE_VXLAN_NETWORK_TYPE: + case L2NetworkConstant.L2_VLAN_NETWORK_TYPE: + ext.syncManagementServiceTypeExtensionPoint(hostUuids, l2NetworkVO.getPhysicalInterface(), l2NetworkVO.getVirtualNetworkId(), false); + break; + + default: + break; + } + } private void handle(APICreateL3NetworkMsg msg) { - SimpleQuery query = dbf.createQuery(L2NetworkVO.class); - query.select(L2NetworkVO_.zoneUuid); - query.add(L2NetworkVO_.uuid, Op.EQ, msg.getL2NetworkUuid()); - String zoneUuid = query.findValue(); - assert zoneUuid != null; + APICreateL3NetworkEvent evt = new APICreateL3NetworkEvent(msg.getId()); + + L2NetworkVO l2Vo = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).find(); + assert l2Vo.getZoneUuid() != null; L3NetworkVO vo = new L3NetworkVO(); if (msg.getResourceUuid() != null) { @@ -420,31 +515,93 @@ private void handle(APICreateL3NetworkMsg msg) { vo.setL2NetworkUuid(msg.getL2NetworkUuid()); vo.setName(msg.getName()); vo.setSystem(msg.isSystem()); - vo.setZoneUuid(zoneUuid); + vo.setZoneUuid(l2Vo.getZoneUuid()); vo.setState(L3NetworkState.Enabled); vo.setCategory(L3NetworkCategory.valueOf(msg.getCategory())); + vo.setEnableIPAM(msg.getEnableIPAM()); + vo.setIsolated(l2Vo.getIsolated()); if (msg.getIpVersion() != null) { vo.setIpVersion(msg.getIpVersion()); } else { vo.setIpVersion(IPv6Constants.IPv4); } + vo.setInternalId((int)dbf.generateSequenceNumber(L3NetworkSequenceNumberVO.class)); + + FlowChain fchain = new SimpleFlowChain(); + fchain.setName(String.format("create-l3-network-%s", vo.getUuid())); + fchain.then(new NoRollbackFlow() { + String __name__ = "add-l3-to-sdn-controller"; - L3NetworkFactory factory = getL3NetworkFactory(L3NetworkType.valueOf(msg.getType())); - L3NetworkInventory inv = new SQLBatchWithReturn() { @Override - protected L3NetworkInventory scripts() { - vo.setAccountUuid(msg.getSession().getAccountUuid()); - L3NetworkInventory inv = factory.createL3Network(vo, msg); - tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), L3NetworkVO.class.getSimpleName()); - return inv; + @Deferred + public void run(FlowTrigger trigger, Map data) { + SdnControllerL3 controllerL3 = getSdnControllerL3(msg.getL2NetworkUuid()); + if (controllerL3 == null) { + trigger.next(); + return; + } + + controllerL3.createL3Network(L3NetworkInventory.valueOf(vo), msg.getSystemTags(), + new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); } - }.execute(); + }).then(new NoRollbackFlow() { + String __name__ = "save-db"; + @Override + public void run(FlowTrigger trigger, Map data) { + L3NetworkFactory factory = getL3NetworkFactory(L3NetworkType.valueOf(msg.getType())); + L3NetworkInventory inv = new SQLBatchWithReturn() { + @Override + protected L3NetworkInventory scripts() { + vo.setAccountUuid(msg.getSession().getAccountUuid()); + L3NetworkInventory inv = factory.createL3Network(vo, msg); + tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), L3NetworkVO.class.getSimpleName()); + return inv; + } + }.execute(); + + if (msg.isSystem()) { + L2NetworkVO l2NetworkVO = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); + List clusterUuids = Q.New(L2NetworkClusterRefVO.class).select(L2NetworkClusterRefVO_.clusterUuid) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2NetworkVO.getUuid()).listValues(); + if (clusterUuids != null && !clusterUuids.isEmpty()) { + List hostUuids = Q.New(HostVO.class).select(HostVO_.uuid) + .in(HostVO_.clusterUuid, clusterUuids).listValues(); + for (ServiceTypeExtensionPoint ext : pluginRgty.getExtensionList(ServiceTypeExtensionPoint.class)) { + syncManagementServiceTypeWhileCreate(ext, l2NetworkVO, hostUuids); + } + } + } + + extpEmitter.afterCreate(inv); + evt.setInventory(inv); + + trigger.next(); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + evt.setError(errCode); + bus.publish(evt); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + logger.debug(String.format("Successfully created L3Network[name:%s, uuid:%s]", vo.getName(), vo.getUuid())); + bus.publish(evt); + } + }).start(); - APICreateL3NetworkEvent evt = new APICreateL3NetworkEvent(msg.getId()); - evt.setInventory(inv); - logger.debug(String.format("Successfully created L3Network[name:%s, uuid:%s]", inv.getName(), inv.getUuid())); - bus.publish(evt); } @Override @@ -455,6 +612,7 @@ public String getId() { @Override public boolean start() { populateExtensions(); + installResourceConfigExtensions(); return true; } @@ -500,6 +658,26 @@ private void populateExtensions() { } } + private void installResourceConfigExtensions() { + ResourceConfig resourceConfig = rcf.getResourceConfig(L3NetworkGlobalConfig.IP_ALLOCATE_STRATEGY.getIdentity()); + resourceConfig.installUpdateExtension(new ResourceConfigUpdateExtensionPoint() { + @Override + public void updateResourceConfig(ResourceConfig config, String resourceUuid, String resourceType, String oldValue, String newValue) { + cleanUpIpCursorOfAcsStrategy(resourceUuid, oldValue, newValue); + } + }); + } + + private void cleanUpIpCursorOfAcsStrategy(String resourceUuid, String oldValue, String newValue) { + if (oldValue.equals(L3NetworkConstant.ASC_DELAY_RECYCLE_IP_ALLOCATOR_STRATEGY) && + !newValue.equals(L3NetworkConstant.ASC_DELAY_RECYCLE_IP_ALLOCATOR_STRATEGY)) { + PatternedSystemTag pst = L3NetworkSystemTags.NETWORK_ASC_DELAY_NORMAL_NEXT_IP; + pst.delete(resourceUuid); + pst = L3NetworkSystemTags.NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP; + pst.delete(resourceUuid); + } + } + @Override public boolean stop() { return true; @@ -549,6 +727,7 @@ private UsedIpInventory reserveIpv6(IpRangeVO ipRange, String ip, boolean allowD vo.setUuid(uuid); vo.setIpRangeUuid(ipRange.getUuid()); vo.setIp(IPv6NetworkUtils.getIpv6AddressCanonicalString(ip)); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); vo.setL3NetworkUuid(ipRange.getL3NetworkUuid()); vo.setNetmask(ipRange.getNetmask()); vo.setGateway(ipRange.getGateway()); @@ -556,7 +735,7 @@ private UsedIpInventory reserveIpv6(IpRangeVO ipRange, String ip, boolean allowD vo = dbf.persistAndRefresh(vo); return UsedIpInventory.valueOf(vo); } catch (PersistenceException e) { - if (ExceptionDSL.isCausedBy(e, MySQLIntegrityConstraintViolationException.class)) { + if (ExceptionDSL.isCausedBy(e, SQLIntegrityConstraintViolationException.class)) { logger.debug(String.format("Concurrent ip allocation. " + "Ip[%s] in ip range[uuid:%s] has been allocated, try allocating another one. " + "The error[Duplicate entry] printed by jdbc.spi.SqlExceptionHelper is no harm, " + @@ -573,6 +752,7 @@ private UsedIpInventory reserveIpv4(IpRangeVO ipRange, String ip, boolean allowD try { UsedIpVO vo = new UsedIpVO(ipRange.getUuid(), ip); vo.setIpInLong(NetworkUtils.ipv4StringToLong(ip)); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); String uuid; if (allowDuplicatedAddress) { uuid = Platform.getUuid(); @@ -588,7 +768,7 @@ private UsedIpInventory reserveIpv4(IpRangeVO ipRange, String ip, boolean allowD vo = dbf.persistAndRefresh(vo); return UsedIpInventory.valueOf(vo); } catch (PersistenceException e) { - if (ExceptionDSL.isCausedBy(e, MySQLIntegrityConstraintViolationException.class)) { + if (ExceptionDSL.isCausedBy(e, SQLIntegrityConstraintViolationException.class)) { logger.debug(String.format("Concurrent ip allocation. " + "Ip[%s] in ip range[uuid:%s] has been allocated, try allocating another one. " + "The error[Duplicate entry] printed by jdbc.spi.SqlExceptionHelper is no harm, " + @@ -619,11 +799,7 @@ public UsedIpInventory reserveIp(IpRangeVO ipRange, String ip, boolean allowDupl @Override public boolean isIpRangeFull(IpRangeVO vo) { - SimpleQuery query = dbf.createQuery(UsedIpVO.class); - query.add(UsedIpVO_.ipRangeUuid, Op.EQ, vo.getUuid()); - query.select(UsedIpVO_.ip); - List used = query.listValue(); - used = used.stream().distinct().collect(Collectors.toList()); + List used = getUsedIpInRange(vo); if (vo.getIpVersion() == IPv6Constants.IPv4) { int total = NetworkUtils.getTotalIpInRange(vo.getStartIp(), vo.getEndIp()); @@ -635,20 +811,7 @@ public boolean isIpRangeFull(IpRangeVO vo) { @Override public List getUsedIpInRange(IpRangeVO vo) { - if (vo.getIpVersion() == IPv6Constants.IPv4) { - SimpleQuery query = dbf.createQuery(UsedIpVO.class); - query.select(UsedIpVO_.ipInLong); - query.add(UsedIpVO_.ipRangeUuid, Op.EQ, vo.getUuid()); - List used = query.listValue(); - Collections.sort(used); - return used.stream().distinct().map(l -> new BigInteger(String.valueOf(l))).collect(Collectors.toList()); - } else { - SimpleQuery query = dbf.createQuery(UsedIpVO.class); - query.select(UsedIpVO_.ip); - query.add(UsedIpVO_.ipRangeUuid, Op.EQ, vo.getUuid()); - List used = query.listValue(); - return used.stream().distinct().map(IPv6NetworkUtils::getBigIntegerFromString).sorted().collect(Collectors.toList()); - } + return IpRangeHelper.getUsedIpInRange(vo.getUuid(), vo.getIpVersion()); } @Override @@ -671,60 +834,15 @@ public void updateIpAllocationMsg(AllocateIpMsg msg, String mac) { @Override public List reportQuota() { - QuotaOperator checker = new QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreateL3NetworkMsg) { - check((APICreateL3NetworkMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(L3NetworkQuotaConstant.L3_NUM); - usage.setUsed(getUsedL3(accountUuid)); - return list(usage); - } - - @Transactional(readOnly = true) - private long getUsedL3(String accountUuid) { - String sql = "select count(l3) from L3NetworkVO l3, AccountResourceRefVO ref where l3.uuid = ref.resourceUuid and " + - "ref.accountUuid = :auuid and ref.resourceType = :rtype"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", L3NetworkVO.class.getSimpleName()); - Long l3n = q.getSingleResult(); - l3n = l3n == null ? 0 : l3n; - return l3n; - } - - private void check(APICreateL3NetworkMsg msg, Map pairs) { - long l3Num = pairs.get(L3NetworkQuotaConstant.L3_NUM).getValue(); - long l3n = getUsedL3(msg.getSession().getAccountUuid()); - - if (l3n + 1 > l3Num) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), L3NetworkQuotaConstant.L3_NUM, l3Num)); - } - } - }; - Quota quota = new Quota(); - quota.setOperator(checker); - quota.addMessageNeedValidation(APICreateL3NetworkMsg.class); - - QuotaPair p = new QuotaPair(); - p.setName(L3NetworkQuotaConstant.L3_NUM); - p.setValue(L3NetworkQuotaGlobalConfig.L3_NUM.defaultValue(Long.class)); - quota.addPair(p); + quota.defineQuota(new L3NumQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateL3NetworkMsg.class) + .addCounterQuota(L3NetworkQuotaConstant.L3_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(L3NetworkVO.class) + .eq(L3NetworkVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(L3NetworkQuotaConstant.L3_NUM)); return list(quota); } @@ -738,7 +856,7 @@ public void resourceOwnerPreChange(AccountResourceRefInventory ref, String newOw public void prepareDbInitialValue() { List ipRangeVOS = Q.New(IpRangeVO.class).isNull(IpRangeVO_.prefixLen).list(); for (IpRangeVO ipr : ipRangeVOS) { - ipr.setPrefixLen(NetworkUtils.getPrefixLengthFromNetwork(ipr.getNetmask())); + ipr.setPrefixLen(NetworkUtils.getPrefixLengthFromNetmask(ipr.getNetmask())); } if (!ipRangeVOS.isEmpty()) { dbf.updateCollection(ipRangeVOS); @@ -791,4 +909,144 @@ public List beforeResourceSharingExtensionPoint(Map uuid @Override public void afterResourceSharingExtensionPoint(Map uuidType, List accountUuids, boolean isToPublic) { } + + @Override + public void reAllocateNicIp(VmNicVO nicVO, ReturnValueCompletion> completion) { + List oldIps = new ArrayList<>(nicVO.getUsedIps()); + List newIps = new ArrayList<>(); + L3NetworkVO l3VO = dbf.findByUuid(nicVO.getL3NetworkUuid(), L3NetworkVO.class); + + FlowChain chain = new SimpleFlowChain(); + chain.setName("reallocate-nic-ip"); + + chain.then(new Flow() { + String __name__ = "allocate-new-nic-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List msgs = new ArrayList<>(); + for (int ipversion : l3VO.getIpVersions()) { + AllocateIpMsg msg = new AllocateIpMsg(); + msg.setL3NetworkUuid(l3VO.getUuid()); + if (ipversion == IPv6Constants.IPv6) { + updateIpAllocationMsg(msg, nicVO.getMac()); + } + msg.setIpVersion(ipversion); + bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, l3VO.getUuid()); + msgs.add(msg); + } + List errs = new ArrayList<>(); + new While<>(msgs).each((msg, wcompl) -> { + bus.send(msg, new CloudBusCallBack(wcompl) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + AllocateIpReply areply = reply.castReply(); + newIps.add(areply.getIpInventory()); + wcompl.done(); + } else { + errs.add(reply.getError()); + wcompl.allDone(); + } + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errs.isEmpty()) { + trigger.fail(errs.get(0)); + } else { + UsedIpInventory ip = newIps.get(0); + SQL.New(VmNicVO.class).eq(VmNicVO_.uuid, nicVO.getUuid()) + .set(VmNicVO_.ip, ip.getIp()) + .set(VmNicVO_.usedIpUuid, ip.getUuid()) + .set(VmNicVO_.netmask, ip.getNetmask()) + .set(VmNicVO_.gateway, ip.getGateway()) + .update(); + for (UsedIpInventory usedIp : newIps) { + /* update usedIpVo */ + SQL.New(UsedIpVO.class) + .eq(UsedIpVO_.uuid, usedIp.getUuid()) + .set(UsedIpVO_.vmNicUuid, nicVO.getUuid()) + .update(); + } + trigger.next(); + } + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + for (UsedIpInventory ip : newIps) { + ReturnIpMsg rmsg = new ReturnIpMsg(); + rmsg.setL3NetworkUuid(ip.getL3NetworkUuid()); + rmsg.setUsedIpUuid(ip.getUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, L3NetworkConstant.SERVICE_ID, ip.getL3NetworkUuid()); + bus.call(rmsg); + } + + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "release-old-nic-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + new While<>(oldIps).each((ip, wcomp) -> { + ReturnIpMsg rmsg = new ReturnIpMsg(); + rmsg.setL3NetworkUuid(ip.getL3NetworkUuid()); + rmsg.setUsedIpUuid(ip.getUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, L3NetworkConstant.SERVICE_ID, ip.getL3NetworkUuid()); + bus.send(rmsg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + trigger.next(); + } + }); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(newIps); + } + }).start(); + } + + @Override + public void check(CheckIpAvailabilityMsg msg, ReturnValueCompletion completion) { + L3NetworkVO vo = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + L3NetworkFactory factory = getL3NetworkFactory(L3NetworkType.valueOf(vo.getType())); + L3Network nw = factory.getL3Network(vo); + completion.success(nw.checkIpAvailability(msg)); + } + + @Override + public SdnControllerDhcp getSdnControllerDhcp(String l3Uuid) { + for (GetSdnControllerExtensionPoint exp : pluginRgty.getExtensionList(GetSdnControllerExtensionPoint.class)) { + return exp.getSdnControllerDhcp(l3Uuid); + } + + return null; + } + + @Override + public SdnControllerL3 getSdnControllerL3(String l2Uuid) { + for (GetSdnControllerExtensionPoint exp : pluginRgty.getExtensionList(GetSdnControllerExtensionPoint.class)) { + return exp.getSdnControllerL3(l2Uuid); + } + + return null; + } } diff --git a/network/src/main/java/org/zstack/network/l3/L3NetworkSystemTags.java b/network/src/main/java/org/zstack/network/l3/L3NetworkSystemTags.java index 86730721856..f6712c54053 100644 --- a/network/src/main/java/org/zstack/network/l3/L3NetworkSystemTags.java +++ b/network/src/main/java/org/zstack/network/l3/L3NetworkSystemTags.java @@ -1,5 +1,6 @@ package org.zstack.network.l3; +import org.zstack.header.network.l2.L2NetworkVO; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.tag.TagDefinition; import org.zstack.tag.PatternedSystemTag; @@ -15,4 +16,20 @@ public class L3NetworkSystemTags { public static String PUBLIC_NETWORK_DHCP_SERVER_UUID_TOKEN = "dhcpServerUuid"; public static PatternedSystemTag PUBLIC_NETWORK_DHCP_SERVER_UUID = new PatternedSystemTag(String.format("dhcpServerUuid::{%s}", PUBLIC_NETWORK_DHCP_SERVER_UUID_TOKEN), L3NetworkVO.class); + + public static String NETWORK_ASC_DELAY_NORMAL_NEXT_IPRANGE_UUID_TOKEN = "ascDelayNormalNextIpRangeUuid"; + public static String NETWORK_ASC_DELAY_NORMAL_NEXT_IP_TOKEN = "ascDelayNormalNextIp"; + public static PatternedSystemTag NETWORK_ASC_DELAY_NORMAL_NEXT_IP = new PatternedSystemTag(String.format("ascDelayNormalNextIp::{%s}::{%s}", NETWORK_ASC_DELAY_NORMAL_NEXT_IPRANGE_UUID_TOKEN, NETWORK_ASC_DELAY_NORMAL_NEXT_IP_TOKEN), L3NetworkVO.class); + + public static String NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IPRANGE_UUID_TOKEN = "ascDelayAddressPoolNextIpRangeUuid"; + public static String NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP_TOKEN = "ascDelayAddressPoolNextIp"; + public static PatternedSystemTag NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP = new PatternedSystemTag(String.format("ascDelayAddressPoolNextIp::{%s}::{%s}", NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IPRANGE_UUID_TOKEN, NETWORK_ASC_DELAY_ADDRESS_POOL_NEXT_IP_TOKEN), L3NetworkVO.class); + + public static String ENABLE_DHCP_TOKEN = "enableDHCP"; + + public static PatternedSystemTag ENABLE_DHCP = new PatternedSystemTag(String.format("enableDHCP::{%s}",ENABLE_DHCP_TOKEN), L3NetworkVO.class); + + public static String L3_NETWORK_HUAWEI_LOGICAL_ROUTER_TOKEN = "logicalRouterUuid"; + public static PatternedSystemTag L3_NETWORK_HUAWEI_LOGICAL_ROUTER = new PatternedSystemTag(String.format("logicalRouterUuid::{%s}", + L3_NETWORK_HUAWEI_LOGICAL_ROUTER_TOKEN), L3NetworkVO.class); } diff --git a/network/src/main/java/org/zstack/network/l3/L3NumQuotaDefinition.java b/network/src/main/java/org/zstack/network/l3/L3NumQuotaDefinition.java new file mode 100644 index 00000000000..4ca8eb1c413 --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/L3NumQuotaDefinition.java @@ -0,0 +1,30 @@ +package org.zstack.network.l3; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.network.l3.L3NetworkQuotaConstant; +import org.zstack.header.network.l3.L3NetworkVO; + +public class L3NumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return L3NetworkQuotaConstant.L3_NUM; + } + + @Override + public Long getDefaultValue() { + return L3NetworkQuotaGlobalConfig.L3_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(l3) from L3NetworkVO l3, AccountResourceRefVO ref where l3.uuid = ref.resourceUuid and " + + "ref.accountUuid = :auuid and ref.resourceType = :rtype"; + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", L3NetworkVO.class.getSimpleName()); + Long l3n = q.find(); + l3n = l3n == null ? 0 : l3n; + return l3n; + } +} diff --git a/network/src/main/java/org/zstack/network/l3/NetworkGlobalProperty.java b/network/src/main/java/org/zstack/network/l3/NetworkGlobalProperty.java index 0c62383e3e1..4cf7cd892de 100644 --- a/network/src/main/java/org/zstack/network/l3/NetworkGlobalProperty.java +++ b/network/src/main/java/org/zstack/network/l3/NetworkGlobalProperty.java @@ -15,4 +15,7 @@ public class NetworkGlobalProperty { @GlobalProperty(name = "bridge.disable.iptables", defaultValue = "false") public static boolean BRIDGE_DISABLE_IPTABLES; + + @GlobalProperty(name = "bridge.disable.ip6tables", defaultValue = "false") + public static boolean BRIDGE_DISABLE_IP6TABLES; } diff --git a/network/src/main/java/org/zstack/network/l3/NormalIpRangeFactory.java b/network/src/main/java/org/zstack/network/l3/NormalIpRangeFactory.java index 25a6d7b42ea..b27778e644a 100644 --- a/network/src/main/java/org/zstack/network/l3/NormalIpRangeFactory.java +++ b/network/src/main/java/org/zstack/network/l3/NormalIpRangeFactory.java @@ -1,24 +1,40 @@ package org.zstack.network.l3; import org.springframework.beans.factory.annotation.Autowired; -import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.SQL; +import org.zstack.core.db.Q; import org.zstack.core.db.SQLBatchWithReturn; +import org.zstack.core.workflow.SimpleFlowChain; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.message.APICreateMessage; import org.zstack.header.network.l3.*; +import org.zstack.header.network.service.SdnControllerDhcp; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; public class NormalIpRangeFactory implements IpRangeFactory { @Autowired DatabaseFacade dbf; @Autowired protected PluginRegistry pluginRgty; + @Autowired + protected L3NetworkManager l3Mgr; @Override public IpRangeType getType() { @@ -26,42 +42,137 @@ public IpRangeType getType() { } @Override - public IpRangeInventory createIpRange(IpRangeInventory ipr, APICreateMessage msg) { - NormalIpRangeVO vo = new SQLBatchWithReturn() { + public void createIpRange(List iprs, APICreateMessage msg, ReturnValueCompletion> completion) { + FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("add-iprange-to-l3-%s", iprs.get(0).getL3NetworkUuid())); + chain.then(new Flow() { + String __name__ = "save-db"; @Override - protected NormalIpRangeVO scripts() { - NormalIpRangeVO vo = new NormalIpRangeVO(); - vo.setUuid(ipr.getUuid() == null ? Platform.getUuid() : ipr.getUuid()); - vo.setDescription(ipr.getDescription()); - vo.setEndIp(ipr.getEndIp()); - vo.setGateway(ipr.getGateway()); - vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); - vo.setName(ipr.getName()); - vo.setNetmask(ipr.getNetmask()); - vo.setStartIp(ipr.getStartIp()); - vo.setNetworkCidr(ipr.getNetworkCidr()); - vo.setAccountUuid(msg.getSession().getAccountUuid()); - vo.setIpVersion(ipr.getIpVersion()); - vo.setAddressMode(ipr.getAddressMode()); - vo.setPrefixLen(ipr.getPrefixLen()); - dbf.getEntityManager().persist(vo); - dbf.getEntityManager().flush(); - dbf.getEntityManager().refresh(vo); - - return vo; + public void run(FlowTrigger trigger, Map data) { + List vos = new ArrayList<>(); + for (IpRangeInventory ipr : iprs) { + NormalIpRangeVO vo = new SQLBatchWithReturn() { + @Override + protected NormalIpRangeVO scripts() { + NormalIpRangeVO vo = (NormalIpRangeVO) IpRangeHelper + .fromIpRangeInventory(ipr, msg.getSession().getAccountUuid()); + dbf.getEntityManager().persist(vo); + dbf.getEntityManager().flush(); + dbf.getEntityManager().refresh(vo); + + return vo; + } + }.execute(); + + IpRangeHelper.updateL3NetworkIpversion(vo); + + List usedIpVos = Q.New(UsedIpVO.class) + .eq(UsedIpVO_.l3NetworkUuid, vo.getL3NetworkUuid()) + .eq(UsedIpVO_.ipVersion, vo.getIpVersion()).list(); + List updateVos = new ArrayList<>(); + for (UsedIpVO ipvo : usedIpVos) { + if (ipvo.getIpVersion() == IPv6Constants.IPv4) { + if (NetworkUtils.isInRange(ipvo.getIp(), vo.getStartIp(), vo.getEndIp())) { + ipvo.setIpRangeUuid(vo.getUuid()); + updateVos.add(ipvo); + } + } else { + if (IPv6NetworkUtils.isIpv6InRange(ipvo.getIp(), vo.getStartIp(), vo.getEndIp())) { + ipvo.setIpRangeUuid(vo.getUuid()); + updateVos.add(ipvo); + } + } + } + + if (!updateVos.isEmpty()) { + dbf.updateCollection(updateVos); + } + + CollectionUtils.safeForEach(pluginRgty.getExtensionList(AfterAddIpRangeExtensionPoint.class), new ForEachFunction() { + @Override + public void run(AfterAddIpRangeExtensionPoint ext) { + ext.afterAddIpRange(IpRangeInventory.valueOf(vo), msg.getSystemTags()); + } + }); + + vos.add(vo); + } + + data.put("IpRangeVO", vos); + trigger.next(); } - }.execute(); - IpRangeHelper.updateL3NetworkIpversion(ipr); + @Override + public void rollback(FlowRollback trigger, Map data) { + List vos = (List) data.get("IpRangeVO"); + dbf.removeCollection(vos, IpRangeVO.class); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "enable-sdn-dhcp"; - final IpRangeInventory finalIpr = NormalIpRangeInventory.valueOf1(vo); - CollectionUtils.safeForEach(pluginRgty.getExtensionList(AfterAddIpRangeExtensionPoint.class), new ForEachFunction() { @Override - public void run(AfterAddIpRangeExtensionPoint ext) { - ext.afterAddIpRange(finalIpr, msg.getSystemTags()); + public void run(FlowTrigger trigger, Map data) { + L3NetworkVO l3vo = dbf.findByUuid(iprs.get(0).getL3NetworkUuid(), L3NetworkVO.class); + if (!l3vo.enableIpAddressAllocation()) { + trigger.next(); + return; + } + + SdnControllerDhcp sdnDhcp = l3Mgr.getSdnControllerDhcp(l3vo.getUuid()); + if (sdnDhcp == null) { + trigger.next(); + return; + } + + sdnDhcp.enableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(l3vo)), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); } - }); + }).then(new NoRollbackFlow() { + String __name__ = "add-sdn-subnet"; + + @Override + public void run(FlowTrigger trigger, Map data) { + L3NetworkVO l3vo = dbf.findByUuid(iprs.get(0).getL3NetworkUuid(), L3NetworkVO.class); + SdnControllerL3 sdnL3 = l3Mgr.getSdnControllerL3(l3vo.getL2NetworkUuid()); + if (sdnL3 == null) { + trigger.next(); + return; + } + + List vos = (List) data.get("IpRangeVO"); + sdnL3.createIpRange(IpRangeInventory.valueOf(vos.get(0)), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } - return finalIpr; + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + List vos = (List) data.get("IpRangeVO"); + completion.success(IpRangeInventory.valueOf(vos)); + } + }).start(); } } diff --git a/network/src/main/java/org/zstack/network/l3/RandomIpAllocatorStrategy.java b/network/src/main/java/org/zstack/network/l3/RandomIpAllocatorStrategy.java index f73bfecd3d2..e4b8d1562f6 100755 --- a/network/src/main/java/org/zstack/network/l3/RandomIpAllocatorStrategy.java +++ b/network/src/main/java/org/zstack/network/l3/RandomIpAllocatorStrategy.java @@ -1,6 +1,5 @@ package org.zstack.network.l3; -import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.header.network.l3.*; @@ -9,6 +8,7 @@ import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.NetworkUtils; +import java.math.BigInteger; import java.util.Collections; import java.util.List; import java.util.Random; @@ -17,6 +17,7 @@ public class RandomIpAllocatorStrategy extends AbstractIpAllocatorStrategy { private static final CLogger logger = Utils.getLogger(RandomIpAllocatorStrategy.class); public static final IpAllocatorType type = new IpAllocatorType(L3NetworkConstant.RANDOM_IP_ALLOCATOR_STRATEGY); + private static final Random random = new Random(); @Override public IpAllocatorType getType() { @@ -29,14 +30,7 @@ public UsedIpInventory allocateIp(IpAllocateMessage msg) { return allocateRequiredIp(msg); } - List ranges; - /* when allocate ip address from address pool, ipRangeUuid is not null */ - if (msg.getIpRangeUuid() != null) { - ranges = Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, msg.getIpRangeUuid()).list(); - } else { - ranges = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) - .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv4).list(); - } + List ranges = getReqIpRanges(msg, IPv6Constants.IPv4); Collections.shuffle(ranges); @@ -76,11 +70,7 @@ private String steppingAllocate(long s, long e, Long ex, int total, String range // have to count the used IP every time allocating a IP, and count operation // is a full scan in DB, which is very costly if (failureCheckPoint == failureCount++) { - SimpleQuery q = dbf.createQuery(UsedIpVO.class); - q.select(UsedIpVO_.ipInLong); - q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid); - List used = q.listValue(); - used = used.stream().distinct().collect(Collectors.toList()); + List used = IpRangeHelper.getUsedIpInRange(rangeUuid, IPv6Constants.IPv4); long count = used.size(); if (count == total) { logger.debug(String.format("ip range[uuid:%s] has no ip available, try next one", rangeUuid)); @@ -118,7 +108,6 @@ private String steppingAllocate(long s, long e, Long ex, int total, String range private String allocateIp(IpRangeAO vo, String excludeIp) { int total = vo.size(); - Random random = new Random(); long s = random.nextInt(total) + NetworkUtils.ipv4StringToLong(vo.getStartIp()); long e = NetworkUtils.ipv4StringToLong(vo.getEndIp()); diff --git a/network/src/main/java/org/zstack/network/l3/RandomIpv6AllocatorStrategy.java b/network/src/main/java/org/zstack/network/l3/RandomIpv6AllocatorStrategy.java index 298d72b96b7..b9ea4737ec7 100755 --- a/network/src/main/java/org/zstack/network/l3/RandomIpv6AllocatorStrategy.java +++ b/network/src/main/java/org/zstack/network/l3/RandomIpv6AllocatorStrategy.java @@ -15,6 +15,7 @@ public class RandomIpv6AllocatorStrategy extends AbstractIpAllocatorStrategy { public static final IpAllocatorType type = new IpAllocatorType(L3NetworkConstant.RANDOM_IPV6_ALLOCATOR_STRATEGY); + private static final Random random = new Random(); @Autowired private PluginRegistry pluginRgty; @@ -29,15 +30,7 @@ public UsedIpInventory allocateIp(IpAllocateMessage msg) { return allocateRequiredIpv6(msg); } - String excludeIp = msg.getExcludedIp(); - List ranges; - /* when allocate ip address from address pool, ipRangeUuid is not null */ - if (msg.getIpRangeUuid() != null) { - ranges = Q.New(IpRangeVO.class).eq(IpRangeVO_.uuid, msg.getIpRangeUuid()).list(); - } else { - ranges = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) - .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); - } + List ranges = getReqIpRanges(msg, IPv6Constants.IPv6); Collections.shuffle(ranges); @@ -46,7 +39,7 @@ public UsedIpInventory allocateIp(IpAllocateMessage msg) { IpRangeVO tr = null; for (IpRangeVO r : ranges) { - ip = allocateIp(r, excludeIp); + ip = allocateIp(r, msg.getExcludedIp()); tr = r; if (ip != null) { break; @@ -92,7 +85,6 @@ private String allocateIp(IpRangeVO vo, String excludeIp) { usedIps.add(exclude); } - Random rnd = new Random(); /* a stateful dhcp range with 2^24 is big enough */ int total = end.subtract(start).intValue(); if ((total > (1 << 23)) || (total < 0)) { @@ -100,7 +92,7 @@ private String allocateIp(IpRangeVO vo, String excludeIp) { } String address = null; do { - num = start.add(new BigInteger(String.valueOf(rnd.nextInt(total + 1)))); + num = start.add(new BigInteger(String.valueOf(random.nextInt(total + 1)))); if (!usedIps.contains(num)) { address = IPv6NetworkUtils.ipv6AddressToString(num); break; diff --git a/network/src/main/java/org/zstack/network/l3/ServiceTypeExtensionPoint.java b/network/src/main/java/org/zstack/network/l3/ServiceTypeExtensionPoint.java new file mode 100644 index 00000000000..3725f73e946 --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/ServiceTypeExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.network.l3; + +import org.zstack.header.host.HostNetworkInterfaceServiceType; + +import java.util.List; + +public interface ServiceTypeExtensionPoint { + void syncManagementServiceTypeExtensionPoint(List hostUuids, String interfaceName, Integer virtualNetworkId, boolean isDelete); + Boolean checkHostServiceTypeExtensionPoint(String hostUuid, String interfaceName, List serviceTypeList); +} + diff --git a/network/src/main/java/org/zstack/network/l3/VmNicSystemTags.java b/network/src/main/java/org/zstack/network/l3/VmNicSystemTags.java new file mode 100644 index 00000000000..09b268e4ccf --- /dev/null +++ b/network/src/main/java/org/zstack/network/l3/VmNicSystemTags.java @@ -0,0 +1,23 @@ +package org.zstack.network.l3; + +import org.zstack.header.tag.TagDefinition; +import org.zstack.header.vm.VmNicVO; +import org.zstack.tag.PatternedSystemTag; + +/** + * Created by boce.wang on 2023/04/23 + */ +@TagDefinition +public class VmNicSystemTags { + public static String VM_NIC_INTERNAL_IP_TOKEN = "internalIp"; + public static PatternedSystemTag VM_NIC_INTERNAL_IP = + new PatternedSystemTag(String.format( + "internalIp::{%s}", VM_NIC_INTERNAL_IP_TOKEN), + VmNicVO.class); + + public static String VM_NIC_INTERNAL_IPV6_TOKEN = "internalIpv6"; + public static PatternedSystemTag VM_NIC_INTERNAL_IPV6 = + new PatternedSystemTag(String.format( + "internalIpv6::{%s}", VM_NIC_INTERNAL_IPV6_TOKEN), + VmNicVO.class); +} diff --git a/network/src/main/java/org/zstack/network/service/CentralizedDnsExtension.java b/network/src/main/java/org/zstack/network/service/CentralizedDnsExtension.java index 6984b08230e..05ffadc42b0 100644 --- a/network/src/main/java/org/zstack/network/service/CentralizedDnsExtension.java +++ b/network/src/main/java/org/zstack/network/service/CentralizedDnsExtension.java @@ -6,6 +6,7 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.service.ForwardDnsStruct; import org.zstack.header.network.service.NetworkServiceCentralizedDnsBackend; import org.zstack.header.network.service.NetworkServiceProviderType; @@ -35,9 +36,7 @@ public NetworkServiceType getNetworkServiceType() { @Override public void applyNetworkService(VmInstanceSpec spec, Map data, Completion completion) { - Map> entries = workoutForwardDns(spec); - data.put(RESULT, entries); - doForwardDns(entries.entrySet().iterator(), spec, completion); + completion.success(); } @@ -111,11 +110,7 @@ private ForwardDnsStruct makeForwardDnsStruct(VmInstanceSpec spec, final L3Netwo @Override public void releaseNetworkService(VmInstanceSpec spec, Map data, NoErrorCompletion completion) { - Map> entries = (Map>) data.get(RESULT); - if (entries == null) { - entries = workoutForwardDns(spec); - } - releaseForwardDns(entries.entrySet().iterator(), spec, completion); + completion.done(); } private void releaseForwardDns(final Iterator>> it, final VmInstanceSpec spec, final NoErrorCompletion complete) { @@ -160,4 +155,14 @@ private void populateExtensions() { cDnsBackends.put(extp.getProviderType(), extp); } } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/network/src/main/java/org/zstack/network/service/DhcpExtension.java b/network/src/main/java/org/zstack/network/service/DhcpExtension.java index e6281526b6d..0dfbb39c1a5 100755 --- a/network/src/main/java/org/zstack/network/service/DhcpExtension.java +++ b/network/src/main/java/org/zstack/network/service/DhcpExtension.java @@ -1,5 +1,6 @@ package org.zstack.network.service; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.Q; @@ -11,13 +12,12 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.network.l3.*; -import org.zstack.header.network.service.DhcpStruct; -import org.zstack.header.network.service.NetworkServiceDhcpBackend; -import org.zstack.header.network.service.NetworkServiceProviderType; -import org.zstack.header.network.service.NetworkServiceType; +import org.zstack.header.network.service.*; import org.zstack.header.vm.*; import org.zstack.header.vm.VmInstanceSpec.HostName; import org.zstack.network.l3.IpRangeHelper; +import org.zstack.network.l3.L3NetworkGlobalConfig; +import org.zstack.network.l3.L3NetworkManager; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; @@ -28,6 +28,8 @@ import java.util.*; import java.util.stream.Collectors; +import static org.zstack.core.Platform.operr; + /** * Created with IntelliJ IDEA. * User: frank @@ -39,6 +41,8 @@ public class DhcpExtension extends AbstractNetworkServiceExtension implements Co @Autowired private PluginRegistry pluginRgty; + @Autowired + private L3NetworkManager l3Mgr; private final Map dhcpBackends = new HashMap(); @@ -156,6 +160,20 @@ public String call(HostName arg) { return struct; } + private boolean isEnableRa(String l3Uuid) { + String l3Type = Q.New(L3NetworkVO.class) + .select(L3NetworkVO_.type) + .eq(L3NetworkVO_.uuid, l3Uuid) + .findValue(); + // vpc network does not need to enable ra + boolean isBasicNetwork = L3NetworkConstant.L3_BASIC_NETWORK_TYPE.equals(l3Type); + if (!isBasicNetwork) { + return false; + } + + return L3NetworkGlobalConfig.BASIC_NETWORK_ENABLE_RA.value(Boolean.class); + } + private void setDualStackNicOfSingleL3Network(DhcpStruct struct, VmNicVO nic) { struct.setIpVersion(IPv6Constants.DUAL_STACK); List sortedIps = nic.getUsedIps().stream().sorted(Comparator.comparingLong(UsedIpVO::getIpVersionl)).collect(Collectors.toList()); @@ -170,11 +188,13 @@ private void setDualStackNicOfSingleL3Network(DhcpStruct struct, VmNicVO nic) { } else { List iprs = Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.l3NetworkUuid, ip.getL3NetworkUuid()) .eq(NormalIpRangeVO_.ipVersion, ip.getIpVersion()).list(); - if (iprs.get(0).getAddressMode().equals(IPv6Constants.SLAAC)) { - continue; - } + struct.setGateway6(ip.getGateway()); struct.setIp6(ip.getIp()); + struct.setEnableRa(isEnableRa(ip.getL3NetworkUuid())); + if (iprs.isEmpty() || iprs.get(0).getAddressMode().equals(IPv6Constants.SLAAC)) { + continue; + } struct.setRaMode(iprs.get(0).getAddressMode()); struct.setPrefixLength(iprs.get(0).getPrefixLen()); struct.setFirstIp(NetworkUtils.getSmallestIp(iprs.stream().map(IpRangeVO::getStartIp).collect(Collectors.toList()))); @@ -196,6 +216,10 @@ private void setNicDhcp(DhcpStruct struct, UsedIpVO ip) { .eq(NormalIpRangeVO_.ipVersion, IPv6Constants.IPv6).list(); struct.setGateway6(ip.getGateway()); struct.setIp6(ip.getIp()); + struct.setEnableRa(isEnableRa(ip.getL3NetworkUuid())); + if (iprs.isEmpty()) { + return; + } struct.setRaMode(iprs.get(0).getAddressMode()); struct.setPrefixLength(iprs.get(0).getPrefixLen()); struct.setFirstIp(NetworkUtils.getSmallestIp(iprs.stream().map(IpRangeVO::getStartIp).collect(Collectors.toList()))); @@ -212,15 +236,48 @@ public List makeDhcpStruct(VmInstanceInventory vm, List> workoutDhcp(VmInstanceS for (Map.Entry> e : providerMap.entrySet()) { NetworkServiceProviderType ptype = e.getKey(); + if (!ptype.isCreateDhcpNameSpace()) { + continue; + } + List lst = new ArrayList(); List nics = new ArrayList<>(); @@ -331,4 +392,52 @@ public void fail(ErrorCode errorCode) { }); } } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + SdnControllerDhcp sdnDhcp = l3Mgr.getSdnControllerDhcp(l3VO.getUuid()); + if (sdnDhcp != null) { + List normalIpRange = IpRangeHelper.getNormalIpRanges(l3VO); + if (normalIpRange.isEmpty()) { + completion.success(); + return; + } + + sdnDhcp.allocateDhcpAndEnableDhcp(l3VO, systemTags, completion); + return; + } + + NetworkServiceDhcpBackend bkd = dhcpBackends.get(providerType); + if (bkd == null) { + completion.fail(operr("unable to find NetworkServiceDhcpBackend[provider type: %s]", providerType)); + return; + } + + bkd.enableNetworkService(l3VO, systemTags, completion); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + SdnControllerDhcp sdnDhcp = l3Mgr.getSdnControllerDhcp(l3VO.getUuid()); + if (sdnDhcp != null) { + List normalIpRange = IpRangeHelper.getNormalIpRanges(l3VO); + if (normalIpRange.isEmpty()) { + completion.success(); + return; + } + + sdnDhcp.disableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(l3VO)), IPv6Constants.DUAL_STACK, completion); + return; + } + + NetworkServiceDhcpBackend bkd = dhcpBackends.get(providerType); + if (bkd == null) { + completion.fail(operr("unable to find NetworkServiceDhcpBackend[provider type: %s]", providerType)); + return; + } + + logger.debug(String.format("[%s] disable dhcp service for l3 network[uuid:%s]", + bkd.getClass().getSimpleName(), l3VO.getUuid())); + bkd.disableNetworkService(l3VO, completion); + } } diff --git a/network/src/main/java/org/zstack/network/service/DnsExtension.java b/network/src/main/java/org/zstack/network/service/DnsExtension.java index e36534a3e20..1083bc43f5b 100755 --- a/network/src/main/java/org/zstack/network/service/DnsExtension.java +++ b/network/src/main/java/org/zstack/network/service/DnsExtension.java @@ -222,4 +222,14 @@ public int getSyncLevel() { public List getAliasIds() { return null; } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/network/src/main/java/org/zstack/network/service/HostRouteExtension.java b/network/src/main/java/org/zstack/network/service/HostRouteExtension.java index 82e7cb26a70..78985e07d6e 100755 --- a/network/src/main/java/org/zstack/network/service/HostRouteExtension.java +++ b/network/src/main/java/org/zstack/network/service/HostRouteExtension.java @@ -144,4 +144,14 @@ public int getSyncLevel() { public List getAliasIds() { return null; } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java b/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java index a14a50f2a1d..3ae0dd90750 100755 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceApiInterceptor.java @@ -1,28 +1,30 @@ package org.zstack.network.service; import org.springframework.beans.factory.annotation.Autowired; -import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.db.Q; -import org.zstack.core.errorcode.ErrorFacade; -import org.zstack.header.errorcode.SysErrors; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; import org.zstack.header.message.APIMessage; +import org.zstack.header.network.l3.*; import org.zstack.header.network.service.*; +import org.zstack.header.vm.*; +import org.zstack.network.l3.IpRangeHelper; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; import org.zstack.utils.Utils; +import org.zstack.utils.network.IPv6Constants; - +import static java.util.Arrays.asList; import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; import java.util.*; +import java.util.stream.Collectors; /** */ @@ -30,14 +32,27 @@ public class NetworkServiceApiInterceptor implements ApiMessageInterceptor { private final static CLogger logger = Utils.getLogger(NetworkServiceApiInterceptor.class); @Autowired private DatabaseFacade dbf; - @Autowired - private ErrorFacade errf; @Override public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { if (msg instanceof APIAttachNetworkServiceToL3NetworkMsg) { - convertNetworkProviderTypeToUuid((APIAttachNetworkServiceToL3NetworkMsg)msg); - validate((APIAttachNetworkServiceToL3NetworkMsg)msg); + APIAttachNetworkServiceToL3NetworkMsg attachMsg = (APIAttachNetworkServiceToL3NetworkMsg)msg; + attachMsg.setNetworkServices(convertNetworkProviderTypeToUuid(attachMsg.getNetworkServices())); + validate(attachMsg); + } else if (msg instanceof APIDetachNetworkServiceFromL3NetworkMsg) { + APIDetachNetworkServiceFromL3NetworkMsg detachMsg = (APIDetachNetworkServiceFromL3NetworkMsg)msg; + if (detachMsg.getService() != null) { + Map> services = new HashMap<>(); + NetworkServiceL3NetworkRefVO ref = Q.New(NetworkServiceL3NetworkRefVO.class) + .eq(NetworkServiceL3NetworkRefVO_.l3NetworkUuid, detachMsg.getL3NetworkUuid()) + .eq(NetworkServiceL3NetworkRefVO_.networkServiceType, detachMsg.getService()).find(); + if (ref != null) { + services.put(ref.getNetworkServiceProviderUuid(), asList(ref.getNetworkServiceType())); + } + detachMsg.setNetworkServices(services); + } else { + detachMsg.setNetworkServices(convertNetworkProviderTypeToUuid(detachMsg.getNetworkServices())); + } } return msg; @@ -99,37 +114,61 @@ public String call(String type) { if (existingNwsTypes.contains(type)) { throw new ApiMessageInterceptionException(operr("there has been a network service[%s] attached to L3 network[uuid:%s]", type, msg.getL3NetworkUuid())); } + + if (type.equals(NetworkServiceType.DHCP.toString())) { + List ipRangeVOS = Q.New(IpRangeVO.class). + eq(IpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .list(); + if (ipRangeVOS.isEmpty()) { + continue; + } + + boolean isUseForUserVm = false; + List usedVmNicUuids = Q.New(UsedIpVO.class).select(UsedIpVO_.vmNicUuid) + .in(UsedIpVO_.ipRangeUuid, ipRangeVOS.stream().map(IpRangeVO::getUuid).collect(Collectors.toList())) + .listValues(); + if (!usedVmNicUuids.isEmpty() && usedVmNicUuids.stream().anyMatch(Objects::nonNull)) { + List usedVmInstanceUuids = Q.New(VmNicVO.class).select(VmNicVO_.vmInstanceUuid) + .in(VmNicVO_.uuid, usedVmNicUuids) + .listValues(); + isUseForUserVm = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.type, VmInstanceConstant.USER_VM_TYPE) + .in(VmInstanceVO_.uuid, usedVmInstanceUuids) + .isExists(); + } + + List freeIpInventories = new ArrayList<>(); + for (IpRangeVO ipRangeVO : ipRangeVOS) { + List tempFreeIpInventories; + if (ipRangeVO.getIpVersion() == IPv6Constants.IPv6) { + tempFreeIpInventories = IpRangeHelper.getFreeIp(ipRangeVO, 2, "::"); + } else { + tempFreeIpInventories = IpRangeHelper.getFreeIp(ipRangeVO, 2, "0.0.0.0"); + } + freeIpInventories.addAll(tempFreeIpInventories); + } + + if ((isUseForUserVm && freeIpInventories.isEmpty())) { + throw new ApiMessageInterceptionException(operr("there are not enough IPs for allocation when attaching the DHCP service to L3 network[uuid:%s].", msg.getL3NetworkUuid())); + } + } } } } - private void convertNetworkProviderTypeToUuid(APIAttachNetworkServiceToL3NetworkMsg msg){ - Map> map = msg.getNetworkServices(); + private Map> convertNetworkProviderTypeToUuid(Map> map){ if (map.isEmpty()) { throw new ApiMessageInterceptionException(argerr("networkServices cannot be empty")); } - boolean isNetworkServiceProveiderType = false; - + Map> mapNew = new HashMap<>(map); List networkServiceProviderVOs = Q.New(NetworkServiceProviderVO.class).list(); - - List keys = new ArrayList(map.keySet()); - List uuids = new ArrayList(); - for (NetworkServiceProviderVO vo :networkServiceProviderVOs){ - uuids.add(vo.getUuid()); - } - - if(Collections.disjoint(keys,uuids)) { - isNetworkServiceProveiderType = true; - } - if(isNetworkServiceProveiderType){ - for (NetworkServiceProviderVO vo :networkServiceProviderVOs) { - if(map.containsKey(vo.getType())){ - map.put(vo.getUuid(), map.remove(vo.getType())); - } + for (NetworkServiceProviderVO vo :networkServiceProviderVOs) { + if (mapNew.containsKey(vo.getType())){ + mapNew.put(vo.getUuid(), mapNew.remove(vo.getType())); } - msg.setNetworkServices(map); } + + return mapNew; } } diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceFilter.java b/network/src/main/java/org/zstack/network/service/NetworkServiceFilter.java index b97f8715ee9..f6cafadc20a 100755 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceFilter.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceFilter.java @@ -21,8 +21,8 @@ public class NetworkServiceFilter { @Transactional(readOnly = true) public List filterNicByServiceTypeAndProviderType(Collection nicUuids, String serviceType, String providerType) { String sql = "select nic.uuid from VmNicVO nic, NetworkServiceL3NetworkRefVO l3ref, NetworkServiceProviderVO provider," + - " NetworkServiceProviderL2NetworkRefVO l2ref, L3NetworkVO l3, UsedIpVO ip where nic.uuid = ip.vmNicUuid and " + - " ip.l3NetworkUuid = l3.uuid and nic.uuid in (:uuids)" + + " NetworkServiceProviderL2NetworkRefVO l2ref, L3NetworkVO l3 where nic.l3NetworkUuid = l3.uuid" + + " and nic.uuid in (:uuids)" + " and l3.uuid = l3ref.l3NetworkUuid and l3ref.networkServiceType = :serviceType and l3ref.networkServiceProviderUuid = provider.uuid" + " and provider.uuid = l2ref.networkServiceProviderUuid and l2ref.l2NetworkUuid = l3.l2NetworkUuid" + " and provider.type = :providerType"; @@ -37,8 +37,8 @@ public List filterNicByServiceTypeAndProviderType(Collection nic @Transactional(readOnly = true) public List filterVmByServiceTypeAndProviderType(Collection vmUuids, String serviceType, String providerType) { String sql = "select distinct vm.uuid from VmNicVO nic, VmInstanceVO vm, NetworkServiceL3NetworkRefVO l3ref, NetworkServiceProviderVO provider," + - " NetworkServiceProviderL2NetworkRefVO l2ref, L3NetworkVO l3, UsedIpVO ip " + - " where nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = l3.uuid and ip.l3NetworkUuid = vm.defaultL3NetworkUuid" + + " NetworkServiceProviderL2NetworkRefVO l2ref, L3NetworkVO l3 " + + " where nic.l3NetworkUuid = l3.uuid and nic.l3NetworkUuid = vm.defaultL3NetworkUuid" + " and nic.vmInstanceUuid = vm.uuid and vm.uuid in (:uuids)" + " and l3.uuid = l3ref.l3NetworkUuid and l3ref.networkServiceType = :serviceType and l3ref.networkServiceProviderUuid = provider.uuid" + " and provider.uuid = l2ref.networkServiceProviderUuid and l2ref.l2NetworkUuid = l3.l2NetworkUuid" + diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceGlobalConfig.java b/network/src/main/java/org/zstack/network/service/NetworkServiceGlobalConfig.java index dd0102b483f..47cc1def9a2 100644 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceGlobalConfig.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceGlobalConfig.java @@ -1,8 +1,7 @@ package org.zstack.network.service; -import org.zstack.core.GlobalProperty; -import org.zstack.core.GlobalPropertyDefinition; import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; import org.zstack.header.network.l2.L2NetworkVO; @@ -29,4 +28,7 @@ public class NetworkServiceGlobalConfig { @GlobalConfigValidation public static GlobalConfig DHCP_MTU_DUMMY = new GlobalConfig(CATEGORY, "defaultDhcpMtu.dummyNetwork"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig ENABLE_VHOSTUSER = new GlobalConfig(CATEGORY, "enableVHostUser"); } diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceHelper.java b/network/src/main/java/org/zstack/network/service/NetworkServiceHelper.java new file mode 100644 index 00000000000..2347ea2ff2f --- /dev/null +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceHelper.java @@ -0,0 +1,40 @@ +package org.zstack.network.service; + +import org.zstack.core.db.Q; +import org.zstack.header.network.l3.L3NetworkHostRouteVO; +import org.zstack.header.network.l3.L3NetworkHostRouteVO_; + +import java.util.ArrayList; +import java.util.List; + +public class NetworkServiceHelper { + public static class HostRouteInfo { + public String prefix; + public String nexthop; + + @Override + public String toString() { + return "HostRouteInfo{" + + "prefix='" + prefix + '\'' + + ", nexthop='" + nexthop + '\'' + + '}'; + } + } + + public static List getL3NetworkHostRoute(String l3NetworkUuid){ + List vos = Q.New(L3NetworkHostRouteVO.class).eq(L3NetworkHostRouteVO_.l3NetworkUuid, l3NetworkUuid).list(); + if (vos == null || vos.isEmpty()) { + return new ArrayList<>(); + } + + List res = new ArrayList<>(); + for (L3NetworkHostRouteVO vo : vos) { + HostRouteInfo info = new HostRouteInfo(); + info.prefix = vo.getPrefix(); + info.nexthop = vo.getNexthop(); + res.add(info); + } + + return res; + } +} diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceManager.java b/network/src/main/java/org/zstack/network/service/NetworkServiceManager.java index 47d30eee2c4..cd80c9b184f 100755 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceManager.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceManager.java @@ -1,9 +1,27 @@ package org.zstack.network.service; +import org.zstack.header.core.Completion; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.service.NetworkServiceExtensionPoint; import org.zstack.header.network.service.NetworkServiceProviderType; import org.zstack.header.network.service.NetworkServiceType; +import org.zstack.header.vm.VmInstanceSpec; + +import java.util.List; +import java.util.Set; public interface NetworkServiceManager { NetworkServiceProviderType getTypeOfNetworkServiceProviderForService(String l3NetworkUuid, NetworkServiceType serviceType); boolean isVmNeedNetworkService(String vmType, NetworkServiceType serviceType); + + void releaseNetworkServiceOnChangeIP(VmInstanceSpec spec, NetworkServiceExtensionPoint.NetworkServiceExtensionPosition position, Completion completion); + void applyNetworkServiceOnChangeIP(VmInstanceSpec spec, NetworkServiceExtensionPoint.NetworkServiceExtensionPosition position, Completion completion); + List getL3NetworkDns(String l3NetworkUuid); + + void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, + NetworkServiceType nsType, List systemTags, Completion completion); + + void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, NetworkServiceType nsType, Completion completion); + + Set getSupportedVmTypes(); } diff --git a/network/src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java b/network/src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java index 97a010cdf8c..787ee313cd6 100755 --- a/network/src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java +++ b/network/src/main/java/org/zstack/network/service/NetworkServiceManagerImpl.java @@ -1,7 +1,6 @@ package org.zstack.network.service; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; @@ -22,9 +21,7 @@ import org.zstack.header.network.NetworkException; import org.zstack.header.network.l2.L2NetworkInventory; import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.network.l3.L3NetworkInventory; -import org.zstack.header.network.l3.L3NetworkVO; -import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.network.l3.*; import org.zstack.header.network.service.*; import org.zstack.header.network.service.NetworkServiceExtensionPoint.NetworkServiceExtensionPosition; import org.zstack.header.vm.*; @@ -56,8 +53,7 @@ public class NetworkServiceManagerImpl extends AbstractService implements Networ private Set supportedVmTypes = new HashSet<>(); private List nsExts = new ArrayList(); - - private void populateExtensions() { + private void populateExtensions() { for (NetworkServiceProviderFactory extp : pluginRgty.getExtensionList(NetworkServiceProviderFactory.class)) { NetworkServiceProviderFactory old = providerFactories.get(extp.getType().toString()); if (old != null) { @@ -230,6 +226,7 @@ public boolean stop() { public void preBeforeInstantiateVmResource(VmInstanceSpec spec) { } + /* AFTER_VM_CREATED will apply security group, where BEFORE_VM_CREATED will apply other network service */ private void applyNetworkServices(final VmInstanceSpec spec, NetworkServiceExtensionPosition position, final Completion completion) { if (!supportedVmTypes.contains(spec.getVmInventory().getType())) { completion.success(); @@ -258,7 +255,7 @@ private void applyNetworkServices(final VmInstanceSpec spec, NetworkServiceExten FlowChain schain = FlowChainBuilder.newSimpleFlowChain().setName(String.format("apply-network-service-to-vm-%s", spec.getVmInventory().getUuid())); schain.allowEmptyFlow(); for (final NetworkServiceExtensionPoint ns : nsExts) { - if (ns.getNetworkServiceExtensionPosition() != position) { + if (position != null && ns.getNetworkServiceExtensionPosition() != position) { continue; } @@ -280,7 +277,10 @@ public void success() { @Override public void fail(ErrorCode errorCode) { - chain.fail(errorCode); + chain.fail(operr("Failed to apply network service[%s] to vm[uuid: %s]", + ns.getNetworkServiceType(), + spec.getVmInventory().getUuid()) + .causedBy(errorCode)); } }); } @@ -319,7 +319,6 @@ public void preInstantiateVmResource(final VmInstanceSpec spec, final Completion } @Override - @Transactional(readOnly = true) public NetworkServiceProviderType getTypeOfNetworkServiceProviderForService(String l3NetworkUuid, NetworkServiceType serviceType) { L3NetworkVO l3vo = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, l3NetworkUuid).find(); L3NetworkInventory l3inv = L3NetworkInventory.valueOf(l3vo); @@ -446,6 +445,43 @@ public void releaseResourceOnDetachingNic(VmInstanceSpec spec, VmNicInventory ni releaseNetworkServices(spec, null, completion); } + @Override + public void releaseNetworkServiceOnChangeIP(VmInstanceSpec spec, NetworkServiceExtensionPosition position, Completion completion) { + releaseNetworkServices(spec, position, new NoErrorCompletion(completion) { + @Override + public void done() { + completion.success(); + } + }); + } + + @Override + public void applyNetworkServiceOnChangeIP(VmInstanceSpec spec, NetworkServiceExtensionPosition position, Completion completion) { + applyNetworkServices(spec, position, completion); + } + + @Override + public List getL3NetworkDns(String l3NetworkUuid){ + List dns = Q.New(L3NetworkDnsVO.class).eq(L3NetworkDnsVO_.l3NetworkUuid, l3NetworkUuid) + .select(L3NetworkDnsVO_.dns).orderBy(L3NetworkDnsVO_.id, SimpleQuery.Od.ASC).listValues(); + if (dns == null) { + dns = new ArrayList(); + } + + L3NetworkVO l3VO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, l3NetworkUuid).find(); + L3NetworkInventory l3Inv = L3NetworkInventory.valueOf(l3VO); + + for (DnsServiceExtensionPoint exp : pluginRgty.getExtensionList(DnsServiceExtensionPoint.class)) { + List dnsExt = exp.getDnsAddress(l3Inv); + if (!dnsExt.isEmpty()) { + dns.addAll(dnsExt); + break; + } + } + + return dns; + } + @Override public void instantiateResourceOnAttachingNic(VmInstanceSpec spec, L3NetworkInventory l3, Completion completion) { preInstantiateVmResource(spec, completion); @@ -473,4 +509,35 @@ public boolean isVmNeedNetworkService(String vmType, NetworkServiceType serviceT /* serviceType is not used now, maybe used in future */ return supportedVmTypes.contains(vmType); } + + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, + NetworkServiceType nsType, List systemTags, Completion completion) { + for (final NetworkServiceExtensionPoint ns : nsExts) { + if (ns.getNetworkServiceType() == nsType) { + ns.enableNetworkService(l3VO, providerType, systemTags, completion); + return; + } + } + logger.debug(String.format("there is no backend[provideType:%s, serviceType:%S] to enable service", providerType.toString(), nsType.toString())); + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, NetworkServiceType nsType, Completion completion) { + for (final NetworkServiceExtensionPoint ns : nsExts) { + if (ns.getNetworkServiceType() == nsType) { + ns.disableNetworkService(l3VO, providerType, completion); + return; + } + } + logger.debug(String.format("there is no backend[provideType:%s, serviceType:%S] to disable service", providerType.toString(), nsType.toString())); + completion.success(); + } + + @Override + public Set getSupportedVmTypes() { + return supportedVmTypes; + } } diff --git a/network/src/main/java/org/zstack/network/service/SnatExtension.java b/network/src/main/java/org/zstack/network/service/SnatExtension.java index 5b4a48a2058..188573203d9 100755 --- a/network/src/main/java/org/zstack/network/service/SnatExtension.java +++ b/network/src/main/java/org/zstack/network/service/SnatExtension.java @@ -8,6 +8,7 @@ import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.network.l3.IpRangeInventory; import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.service.NetworkServiceProviderType; import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.network.service.NetworkServiceSnatBackend; @@ -96,10 +97,12 @@ private SnatStruct makeSnatStruct(VmInstanceSpec spec, L3NetworkInventory l3) { SnatStruct struct = new SnatStruct(); struct.setL3Network(l3); - struct.setGuestGateway(nic.getGateway()); - struct.setGuestIp(nic.getIp()); - struct.setGuestMac(nic.getMac()); - struct.setGuestNetmask(nic.getNetmask()); + if (nic != null) { + struct.setGuestGateway(nic.getGateway()); + struct.setGuestIp(nic.getIp()); + struct.setGuestMac(nic.getMac()); + struct.setGuestNetmask(nic.getNetmask()); + } return struct; } @@ -141,4 +144,14 @@ public boolean start() { public boolean stop() { return true; } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/plugin/acl/pom.xml b/plugin/acl/pom.xml index f5f58a55749..1af18880f15 100644 --- a/plugin/acl/pom.xml +++ b/plugin/acl/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/acl/src/main/java/org/zstack/acl/AccessControlListManagerImpl.java b/plugin/acl/src/main/java/org/zstack/acl/AccessControlListManagerImpl.java index b953caef9c3..5e90711f200 100644 --- a/plugin/acl/src/main/java/org/zstack/acl/AccessControlListManagerImpl.java +++ b/plugin/acl/src/main/java/org/zstack/acl/AccessControlListManagerImpl.java @@ -73,6 +73,8 @@ public void handleMessage(Message msg) { protected void handleApiMessage(APIMessage msg) { if (msg instanceof APICreateAccessControlListMsg) { handle((APICreateAccessControlListMsg) msg); + } else if (msg instanceof APIUpdateAccessControlListMsg) { + handle((APIUpdateAccessControlListMsg) msg); } else if (msg instanceof APIDeleteAccessControlListMsg) { handle((APIDeleteAccessControlListMsg) msg); } else if (msg instanceof APIAddAccessControlListEntryMsg) { @@ -119,6 +121,26 @@ protected void scripts() { bus.publish(evt); } + private void handle(APIUpdateAccessControlListMsg msg) { + AccessControlListVO vo = dbf.findByUuid(msg.getUuid(), AccessControlListVO.class); + boolean update = false; + if (msg.getName() != null) { + vo.setName(msg.getName()); + update = true; + } + if (msg.getDescription() != null) { + vo.setDescription(msg.getDescription()); + update = true; + } + if (update) { + vo = dbf.updateAndRefresh(vo); + } + + APIUpdateAccessControlListEvent event = new APIUpdateAccessControlListEvent(msg.getId()); + event.setInventory(vo.toInventory()); + bus.publish(event); + } + private void handle(APIDeleteAccessControlListMsg msg) { APIDeleteAccessControlListEvent evt = new APIDeleteAccessControlListEvent(msg.getId()); deleteAccessControlList(msg.getUuid(), msg.getDeletionMode(), new Completion(msg) { @@ -411,6 +433,18 @@ public void fail(ErrorCode errorCode) { fchain.done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { + // Call extensions before deleting entries + List entries = Q.New(AccessControlListEntryVO.class) + .eq(AccessControlListEntryVO_.aclUuid, aclVO.getUuid()).list(); + + entries.forEach(entry -> { + CollectionUtils.safeForEach(pluginRgty.getExtensionList(RefreshAccessControlListExtensionPoint.class), + ext -> { + logger.debug(String.format("execute before del acl ip entry extension point %s", ext)); + ext.beforeDeleteIpEntry(aclVO.toInventory(), entry.toInventory()); + }); + }); + new SQLBatch() { @Override protected void scripts() { @@ -419,6 +453,14 @@ protected void scripts() { if (!entrys.isEmpty()) { entrys.forEach( entry-> remove(entry)); } + // Call extensions after deleting entries + entries.forEach(entry -> { + CollectionUtils.safeForEach(pluginRgty.getExtensionList(RefreshAccessControlListExtensionPoint.class), + ext -> { + logger.debug(String.format("execute after del acl ip entry extension point %s", ext)); + ext.afterDeleteIpEntry(aclVO.toInventory(), entry.toInventory()); + }); + }); remove(aclVO); } }.execute(); diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListEntryMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListEntryMsgDoc_zh_cn.groovy index d03735e67f4..9849042001f 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListEntryMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListEntryMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9" - } column { name "entries" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.9" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.9" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "3.9" - } column { name "tagUuids" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.9" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "3.9" - } } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListRedirectRuleMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListRedirectRuleMsgDoc_zh_cn.groovy index 715cba37f8c..a4ff4563da6 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListRedirectRuleMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIAddAccessControlListRedirectRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "4.1.3" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.1.3" - } column { name "domain" @@ -49,7 +47,6 @@ doc { type "String" optional true since "4.1.3" - } column { name "url" @@ -59,7 +56,6 @@ doc { type "String" optional true since "4.1.3" - } column { name "aclUuid" @@ -69,7 +65,6 @@ doc { type "String" optional false since "4.1.3" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "4.1.3" - } column { name "tagUuids" @@ -89,7 +83,6 @@ doc { type "List" optional true since "4.1.3" - } column { name "systemTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "4.1.3" - } column { name "userTags" @@ -109,7 +101,6 @@ doc { type "List" optional true since "4.1.3" - } } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsg.java b/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsg.java index f84f4e7e9ae..eab75961dfd 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsg.java +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsg.java @@ -41,4 +41,11 @@ public void setName(String name) { public Result audit(APIMessage msg, APIEvent rsp) { return null; } + + public static APIChangeAccessControlListRedirectRuleMsg __example__() { + APIChangeAccessControlListRedirectRuleMsg msg = new APIChangeAccessControlListRedirectRuleMsg(); + msg.setUuid(uuid()); + msg.setName("redirectRule"); + return msg; + } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsgDoc_zh_cn.groovy index bc35a96b4b4..e7725a04abf 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIChangeAccessControlListRedirectRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.1.3" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.1.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.1.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.1.3" - } } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APICreateAccessControlListMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APICreateAccessControlListMsgDoc_zh_cn.groovy index 3c573abbb05..1c35a65e4b4 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APICreateAccessControlListMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APICreateAccessControlListMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.9" - } column { name "ipVersion" @@ -59,7 +57,6 @@ doc { type "String" optional true since "3.9" - } column { name "tagUuids" @@ -69,7 +66,6 @@ doc { type "List" optional true since "3.9" - } column { name "systemTags" @@ -79,7 +75,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -89,7 +84,6 @@ doc { type "List" optional true since "3.9" - } } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIDeleteAccessControlListMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIDeleteAccessControlListMsgDoc_zh_cn.groovy index 5776a5bf454..af2e21cbbd3 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIDeleteAccessControlListMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIDeleteAccessControlListMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.9" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.9" - } } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIQueryAccessControlListMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIQueryAccessControlListMsgDoc_zh_cn.groovy index 388bbfbb5c4..2500ca4d033 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIQueryAccessControlListMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIQueryAccessControlListMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.header.acl import org.zstack.header.acl.APIQueryAccessControlListReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryAccessControlList" diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIRemoveAccessControlListEntryMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIRemoveAccessControlListEntryMsgDoc_zh_cn.groovy index 18c6c4b198d..fb689347d6f 100644 --- a/plugin/acl/src/main/java/org/zstack/header/acl/APIRemoveAccessControlListEntryMsgDoc_zh_cn.groovy +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIRemoveAccessControlListEntryMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9" - } column { name "uuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.9" - } column { name "deleteMode" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.9" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.9" - } } } diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListEvent.java b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListEvent.java new file mode 100644 index 00000000000..5fe80081dcc --- /dev/null +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListEvent.java @@ -0,0 +1,37 @@ +package org.zstack.header.acl; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * Created by boce.wang on 05/13/2025. + */ +@RestResponse(allTo = "inventory") +public class APIUpdateAccessControlListEvent extends APIEvent { + private AccessControlListInventory inventory; + + public APIUpdateAccessControlListEvent() { } + + public APIUpdateAccessControlListEvent(String apiId) { + super(apiId); + } + + public void setInventory(AccessControlListInventory inventory) { + this.inventory = inventory; + } + + public AccessControlListInventory getInventory() { + return inventory; + } + + public static APIUpdateAccessControlListEvent __example__() { + APIUpdateAccessControlListEvent event = new APIUpdateAccessControlListEvent(); + AccessControlListInventory inv = new AccessControlListInventory(); + + inv.setName("acl-group"); + inv.setIpVersion(4); + + event.setInventory(inv); + return event; + } +} diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListEventDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..fae86438d4a --- /dev/null +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.acl + +import org.zstack.header.acl.AccessControlListInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "访问控制策略组清单" + + ref { + name "inventory" + path "org.zstack.header.acl.APIUpdateAccessControlListEvent.inventory" + desc "更新后的访问控制策略组详细信息" + type "AccessControlListInventory" + since "5.3.28" + clz AccessControlListInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.28" + } + ref { + name "error" + path "org.zstack.header.acl.APIUpdateAccessControlListEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.28" + clz ErrorCode.class + } +} diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListMsg.java b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListMsg.java new file mode 100644 index 00000000000..5525b72adf4 --- /dev/null +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListMsg.java @@ -0,0 +1,65 @@ +package org.zstack.header.acl; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +/** + * Created by boce.wang on 05/13/2025. + */ + +@Action(category = AccessControlListConstants.ACTION_CATEGORY) +@RestRequest( + path = "/access-control-lists/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIUpdateAccessControlListEvent.class, + isAction = true +) +public class APIUpdateAccessControlListMsg extends APIMessage implements APIAuditor { + @APIParam(resourceType = AccessControlListVO.class, checkAccount = true) + private String uuid; + @APIParam(required = false, maxLength = 255, emptyString = false) + private String name; + @APIParam(maxLength = 2048, required = false) + private String description; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new Result(rsp.isSuccess() ? ((APIUpdateAccessControlListEvent)rsp).getInventory().getUuid() : "", AccessControlListVO.class); + } + + public static APIUpdateAccessControlListMsg __example__() { + APIUpdateAccessControlListMsg msg = new APIUpdateAccessControlListMsg(); + msg.setName("acl-1"); + msg.setDescription("acl-1 description"); + return msg; + } +} diff --git a/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListMsgDoc_zh_cn.groovy b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..31f76a1c9f0 --- /dev/null +++ b/plugin/acl/src/main/java/org/zstack/header/acl/APIUpdateAccessControlListMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.acl + +import org.zstack.header.acl.APIUpdateAccessControlListEvent + +doc { + title "UpdateAccessControlList" + + category "acl" + + desc """更新访问控制策略组""" + + rest { + request { + url "PUT /v1/access-control-lists/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateAccessControlListMsg.class + + desc """用于更新指定UUID的访问控制策略组的名称和描述""" + + params { + + column { + name "uuid" + enclosedIn "updateAccessControlList" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.3.28" + } + column { + name "name" + enclosedIn "updateAccessControlList" + desc "资源名称" + location "body" + type "String" + optional true + since "5.3.28" + } + column { + name "description" + enclosedIn "updateAccessControlList" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.3.28" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.28" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.28" + } + } + } + + response { + clz APIUpdateAccessControlListEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/applianceVm/pom.xml b/plugin/applianceVm/pom.xml index e5a05001ba9..d6529929856 100755 --- a/plugin/applianceVm/pom.xml +++ b/plugin/applianceVm/pom.xml @@ -6,7 +6,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 .. applianceVm diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/APIQueryApplianceVmMsgDoc_zh_cn.groovy b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/APIQueryApplianceVmMsgDoc_zh_cn.groovy index edb05a8022d..4048e82e66a 100644 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/APIQueryApplianceVmMsgDoc_zh_cn.groovy +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/APIQueryApplianceVmMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.appliancevm import org.zstack.appliancevm.APIQueryApplianceVmReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询系统云主机(QueryApplianceVm)" diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java index 9da72835a20..5f2b1e29088 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmAllocateNicFlow.java @@ -4,32 +4,38 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; +import org.zstack.compute.vm.MacOperator; +import org.zstack.compute.vm.VmInstanceManager; import org.zstack.compute.vm.VmNicManager; import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.db.*; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.db.SQLBatch; import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowException; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.image.ImagePlatform; import org.zstack.header.message.MessageReply; -import org.zstack.header.network.l2.L2NetworkConstant; import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.l3.*; +import org.zstack.header.tag.SystemTagVO; +import org.zstack.header.tag.SystemTagVO_; import org.zstack.header.vm.*; -import org.zstack.identity.Account; import org.zstack.network.l3.L3NetworkManager; +import org.zstack.network.service.NetworkServiceGlobalConfig; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.NetworkUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -48,6 +54,8 @@ public class ApplianceVmAllocateNicFlow implements Flow { private L3NetworkManager l3nm; @Autowired private VmNicManager nicManager; + @Autowired + protected VmInstanceManager vmMgr; private UsedIpInventory acquireIp(String l3NetworkUuid, String mac, Integer version, String staticIp, String stratgey, boolean allowDuplicatedAddress) { AllocateIpMsg msg = new AllocateIpMsg(); @@ -79,19 +87,16 @@ private VmNicInventory makeNicInventory(VmInstanceSpec vmSpec, ApplianceVmNicSpe inv.setDeviceId(deviceId[0]); inv.setMetaData(nicSpec.getMetaData()); inv.setInternalName(VmNicVO.generateNicInternalName(vmSpec.getVmInventory().getInternalId(), inv.getDeviceId())); - inv.setMac(NetworkUtils.generateMacWithDeviceId((short) inv.getDeviceId())); + inv.setMac(MacOperator.generateMacWithDeviceId((short) inv.getDeviceId())); inv.setHypervisorType(vmSpec.getVmInventory().getHypervisorType()); inv.setDriverType(ImagePlatform.valueOf(vmSpec.getVmInventory().getPlatform()).isParaVirtualization() ? nicManager.getDefaultPVNicDriver() : nicManager.getDefaultNicDriver()); + inv.setState(VmNicState.enable.toString()); L3NetworkVO l3NetworkVO = dbf.findByUuid(nicSpec.getL3NetworkUuid(), L3NetworkVO.class); - L2NetworkVO l2NetworkVO = dbf.findByUuid(l3NetworkVO.getL2NetworkUuid(), L2NetworkVO.class); - if (l2NetworkVO.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK)) { - inv.setType("vDPA"); - } else { - inv.setType(VmInstanceConstant.VIRTUAL_NIC_TYPE); - } - + VmNicType vmNicType = nicManager.getVmNicType(vmSpec.getVmInventory().getUuid(), + L3NetworkInventory.valueOf(l3NetworkVO)); + inv.setType(vmNicType.toString()); inv.setUsedIps(new ArrayList<>()); if (nicSpec.getIp() == null) { @@ -99,13 +104,6 @@ private VmNicInventory makeNicInventory(VmInstanceSpec vmSpec, ApplianceVmNicSpe List ipVersions = l3NetworkVO.getIpVersions(); for (Integer version : ipVersions) { String strategy = nicSpec.getAllocatorStrategy(); - if (strategy == null) { - if (version == IPv6Constants.IPv4) { - strategy = L3NetworkConstant.RANDOM_IP_ALLOCATOR_STRATEGY; - } else { - strategy = L3NetworkConstant.RANDOM_IPV6_ALLOCATOR_STRATEGY; - } - } UsedIpInventory ip = acquireIp(nicSpec.getL3NetworkUuid(), inv.getMac(), version, nicSpec.getStaticIp().get(version), strategy, nicSpec.isAllowDuplicatedAddress()); /* save first ip to nic */ if (inv.getGateway() == null) { @@ -137,8 +135,13 @@ private VmNicInventory makeNicInventory(VmInstanceSpec vmSpec, ApplianceVmNicSpe return inv; } - @Transactional private void removeNicFromDb(List nics) { + for (VmNicInventory vmNic : nics) { + VmNicType type = VmNicType.valueOf(vmNic.getType()); + VmInstanceNicFactory vnicFactory = vmMgr.getVmInstanceNicFactory(type); + vnicFactory.releaseVmNic(vmNic); + } + SQL.New(VmNicVO.class).in(VmNicVO_.uuid, nics.stream().map(VmNicInventory::getUuid).collect(Collectors.toList())).delete(); } @@ -148,40 +151,36 @@ public void run(FlowTrigger chain, Map data) { ApplianceVmSpec aspec = spec.getExtensionData(ApplianceVmConstant.Params.applianceVmSpec.toString(), ApplianceVmSpec.class); int[] deviceId = {0}; + List nics = new ArrayList(); VmNicInventory mgmtNic = makeNicInventory(spec, aspec.getManagementNic(), deviceId); - spec.getDestNics().add(mgmtNic); + nics.add(mgmtNic); for (ApplianceVmNicSpec nicSpec : aspec.getAdditionalNics()) { - spec.getDestNics().add(makeNicInventory(spec, nicSpec, deviceId)); + nics.add(makeNicInventory(spec, nicSpec, deviceId)); } new SQLBatch() { @Override protected void scripts() { - String acntUuid = Account.getAccountUuidOfResource(spec.getVmInventory().getUuid()); - spec.getDestNics().forEach(nic -> { - VmNicVO nvo = new VmNicVO(); - nvo.setUuid(nic.getUuid()); - nvo.setDeviceId(nic.getDeviceId()); - nvo.setIp(nic.getIp()); - nvo.setL3NetworkUuid(nic.getL3NetworkUuid()); - nvo.setMac(nic.getMac()); - nvo.setHypervisorType(nic.getHypervisorType()); - nvo.setUsedIpUuid(nic.getUsedIpUuid()); - nvo.setGateway(nic.getGateway()); - nvo.setNetmask(nic.getNetmask()); - nvo.setVmInstanceUuid(nic.getVmInstanceUuid()); - nvo.setMetaData(nic.getMetaData()); - nvo.setInternalName(nic.getInternalName()); - nvo.setAccountUuid(acntUuid); - nvo.setIpVersion(nic.getIpVersion()); - nvo.setDriverType(nic.getDriverType()); - nvo.setType(nic.getType()); - persist(nvo); - for (UsedIpInventory ip : nic.getUsedIps()) { - SQL.New(UsedIpVO.class).eq(UsedIpVO_.uuid, ip.getUuid()).set(UsedIpVO_.vmNicUuid, nvo.getUuid()).update(); + Set ipVOS = new HashSet<>(); + nics.forEach(nic -> { + VmNicType vmNicType = VmNicType.valueOf(nic.getType()); + VmInstanceNicFactory vnicFactory = vmMgr.getVmInstanceNicFactory(vmNicType); + vnicFactory.createVmNic(nic, spec); + List ipInvList = new ArrayList<>(); + if (nic.getUsedIps() != null) { + for (UsedIpInventory ip : nic.getUsedIps()) { + UsedIpVO ipVO = dbf.findByUuid(ip.getUuid(), UsedIpVO.class); + ipVO.setVmNicUuid(nic.getUuid()); + ipVOS.add(ipVO); + ipInvList.add(UsedIpInventory.valueOf(ipVO)); + } } + nic.setUsedIps(ipInvList); + spec.getDestNics().removeIf(inv -> nic.getUuid().equals(inv.getUuid())); + spec.getDestNics().add(nic); }); + dbf.updateCollection(ipVOS); } }.execute(); chain.next(); @@ -189,47 +188,47 @@ protected void scripts() { @Override public void rollback(FlowRollback chain, Map data) { - try { - VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - List nics = spec.getDestNics(); - if (nics.isEmpty()) { - return; - } - - List rmsgs = new ArrayList<>(); - for (VmNicInventory nic : nics) { - if (nic.getUsedIps() == null || nic.getUsedIps().isEmpty()) { - continue; - } + VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + List nics = spec.getDestNics(); + if (nics.isEmpty()) { + chain.rollback(); + return; + } - for (UsedIpInventory ip : nic.getUsedIps()) { - ReturnIpMsg msg = new ReturnIpMsg(); - msg.setL3NetworkUuid(nic.getL3NetworkUuid()); - msg.setUsedIpUuid(ip.getUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, nic.getL3NetworkUuid()); - rmsgs.add(msg); - } + List rmsgs = new ArrayList<>(); + for (VmNicInventory nic : nics) { + if (nic.getUsedIps() == null || nic.getUsedIps().isEmpty()) { + continue; } - if (!rmsgs.isEmpty()) { - new While<>(rmsgs).each((msg, compl) -> { - bus.send(msg, new CloudBusCallBack(compl) { - @Override - public void run(MessageReply reply) { - compl.done(); - } - }); - }).run(new WhileDoneCompletion(null) { - @Override - public void done(ErrorCodeList errorCodeList) { - removeNicFromDb(nics); - } - }); - } else { - removeNicFromDb(nics); + for (UsedIpInventory ip : nic.getUsedIps()) { + ReturnIpMsg msg = new ReturnIpMsg(); + msg.setL3NetworkUuid(nic.getL3NetworkUuid()); + msg.setUsedIpUuid(ip.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, nic.getL3NetworkUuid()); + rmsgs.add(msg); } - } finally { + } + + if (rmsgs.isEmpty()) { + removeNicFromDb(nics); chain.rollback(); + return; } + + new While<>(rmsgs).each((msg, compl) -> { + bus.send(msg, new CloudBusCallBack(compl) { + @Override + public void run(MessageReply reply) { + compl.done(); + } + }); + }).run(new WhileDoneCompletion(chain) { + @Override + public void done(ErrorCodeList errorCodeList) { + removeNicFromDb(nics); + chain.rollback(); + } + }); } } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmBase.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmBase.java index 2bbaf1db361..6f3f6e09242 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmBase.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmBase.java @@ -12,6 +12,8 @@ import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.upgrade.UpgradeChecker; +import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.configuration.DiskOfferingInventory; import org.zstack.header.configuration.DiskOfferingVO; import org.zstack.header.configuration.DiskOfferingVO_; @@ -46,6 +48,9 @@ public abstract class ApplianceVmBase extends VmInstanceBase implements ApplianceVm { @Autowired private RESTFacade restf; + + @Autowired + private UpgradeChecker upgradeChecker; static { allowedOperations.addState(VmInstanceState.Created, StartNewCreatedApplianceVmMsg.class.getName()); @@ -425,10 +430,6 @@ protected FlowChain getStopVmWorkFlowChain(VmInstanceInventory inv) { @Override public void run(FlowTrigger trigger, Map data) { changeApplianceVmStatus(ApplianceVmStatus.Disconnected); - if (originStatus.equals(ApplianceVmStatus.Connected)) { - fireDisconnectedCanonicalEvent(operr("appliance vm %s stopped", - getSelf().getUuid())); - } trigger.next(); } @@ -463,7 +464,7 @@ protected void fireServiceUnhealthyCanonicalEvent(ErrorCode err) { data.setHealthy(false); data.setReason(err); - evtf.fire(ApplianceVmCanonicalEvents.SERVICE_UNHEALTHY_PATH, data); + evtf.fire(ApplianceVmCanonicalEvents.SERVICE_HEALTHY_PATH, data); } protected void fireServicehealthyCanonicalEvent() { @@ -493,11 +494,7 @@ protected FlowChain getDestroyVmWorkFlowChain(VmInstanceInventory inv) { ApplianceVmStatus originStatus = getSelf().getStatus(); public void run(FlowTrigger trigger, Map data) { - changeApplianceVmStatus(ApplianceVmStatus.Disconnected); - if (originStatus.equals(ApplianceVmStatus.Connected)) { - fireDisconnectedCanonicalEvent(operr("appliance vm %s destroyed", - getSelf().getUuid())); - } + changeApplianceVmStatus(ApplianceVmStatus.Destroying); trigger.next(); } @@ -544,8 +541,148 @@ protected FlowChain getMigrateVmWorkFlowChain(VmInstanceInventory inv) { return chain; } + protected void provisionAfterRebootVm(VmInstanceSpec spec, NoErrorCompletion completion) { + if (ApplianceVmGlobalConfig.AUTO_ROLLBACK.value(Boolean.class)) { + completion.done(); + return; + } + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); + chain.setName(String.format("provision-appliancevm-after-reboot-%s", spec.getVmInventory().getUuid())); + chain.insert(new Flow() { + String __name__ = "change-appliancevm-status-to-disconnected"; + ApplianceVmStatus originStatus = getSelf().getStatus(); + + @Override + public void run(FlowTrigger trigger, Map data) { + changeApplianceVmStatus(ApplianceVmStatus.Disconnected); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + trigger.rollback(); + } + }); + + prepareLifeCycleInfo(chain); + prepareFirewallInfo(chain); + + chain.then(setApplianceStateRunningFlow()); + addBootstrapFlows(chain, HypervisorType.valueOf(spec.getVmInventory().getHypervisorType())); + + List subRebootFlows = getPostRebootFlows(); + if (subRebootFlows != null) { + for (Flow f : subRebootFlows) { + chain.then(f); + } + } + + chain.then(new NoRollbackFlow() { + String __name__ = "change-appliancevm-status-to-connected"; + + @Override + public void run(FlowTrigger trigger, Map data) { + changeApplianceVmStatus(ApplianceVmStatus.Connected); + trigger.next(); + } + }); + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.done(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + logger.debug(String.format("provision applianceVm[uuid:%s, name:%s] failed because %s", + spec.getVmInventory().getUuid(), + spec.getVmInventory().getName(), errCode.getDetails())); + completion.done(); + } + }).start(); + } + + protected void provisionAfterStartVm(VmInstanceSpec spec, NoErrorCompletion completion) { + if (ApplianceVmGlobalConfig.AUTO_ROLLBACK.value(Boolean.class)) { + completion.done(); + return; + } + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); + chain.setName(String.format("provision-appliancevm-after-start-%s", spec.getVmInventory().getUuid())); + chain.insert(new ApplianceVmSyncConfigToHaGroupFlow()); + chain.insert(new Flow() { + String __name__ = "change-appliancevm-status-to-connecting"; + ApplianceVmStatus originStatus = getSelf().getStatus(); + + @Override + public void run(FlowTrigger trigger, Map data) { + changeApplianceVmStatus(ApplianceVmStatus.Connecting); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + changeApplianceVmStatus(ApplianceVmStatus.Disconnected); + trigger.rollback(); + } + }); + + chain.then(setApplianceStateRunningFlow()); + prepareLifeCycleInfo(chain); + prepareFirewallInfo(chain); + + addBootstrapFlows(chain, HypervisorType.valueOf(spec.getVmInventory().getHypervisorType())); + + List subStartFlows = getPostStartFlows(); + if (subStartFlows != null) { + for (Flow f : subStartFlows) { + chain.then(f); + } + } + + chain.then(new NoRollbackFlow() { + String __name__ = "change-appliancevm-status-to-connected"; + + @Override + public void run(FlowTrigger trigger, Map data) { + changeApplianceVmStatus(ApplianceVmStatus.Connected); + trigger.next(); + } + }); + chain.then(new ApplianceVmSyncConfigAfterAddToHaGroupFlow()); + + boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; + chain.noRollback(noRollbackOnFailure); + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.done(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + logger.debug(String.format("provision applianceVm[uuid:%s, name:%s] failed because %s", + spec.getVmInventory().getUuid(), + spec.getVmInventory().getName(), errCode.getDetails())); + completion.done(); + } + }).start(); + } + @Override protected FlowChain getRebootVmWorkFlowChain(VmInstanceInventory inv) { + if (!ApplianceVmGlobalConfig.AUTO_ROLLBACK.value(Boolean.class)) { + FlowChain chain = super.getRebootVmWorkFlowChain(inv); + chain.setName(String.format("reboot-appliancevm-%s", inv.getUuid())); + boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; + chain.noRollback(noRollbackOnFailure); + return chain; + } + FlowChain chain = super.getRebootVmWorkFlowChain(inv); chain.setName(String.format("reboot-appliancevm-%s", inv.getUuid())); chain.insert(new Flow() { @@ -554,21 +691,12 @@ protected FlowChain getRebootVmWorkFlowChain(VmInstanceInventory inv) { @Override public void run(FlowTrigger trigger, Map data) { - changeApplianceVmStatus(ApplianceVmStatus.Connecting); - if (originStatus.equals(ApplianceVmStatus.Connected)) { - fireDisconnectedCanonicalEvent(operr("appliance vm %s reboot", - getSelf().getUuid())); - } + changeApplianceVmStatus(ApplianceVmStatus.Disconnected); trigger.next(); } @Override public void rollback(FlowRollback trigger, Map data) { - changeApplianceVmStatus(ApplianceVmStatus.Disconnected); - if (originStatus.equals(ApplianceVmStatus.Connected)) { - fireDisconnectedCanonicalEvent(operr("appliance vm %s reboot failed", - getSelf().getUuid())); - } trigger.rollback(); } }); @@ -603,6 +731,14 @@ public void run(FlowTrigger trigger, Map data) { @Override protected FlowChain getStartVmWorkFlowChain(VmInstanceInventory inv) { + if (!ApplianceVmGlobalConfig.AUTO_ROLLBACK.value(Boolean.class)) { + FlowChain chain = super.getStartVmWorkFlowChain(inv); + chain.setName(String.format("start-appliancevm-%s", inv.getUuid())); + boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; + chain.noRollback(noRollbackOnFailure); + return chain; + } + FlowChain chain = super.getStartVmWorkFlowChain(inv); chain.setName(String.format("start-appliancevm-%s", inv.getUuid())); chain.insert(new ApplianceVmSyncConfigToHaGroupFlow()); @@ -619,10 +755,6 @@ public void run(FlowTrigger trigger, Map data) { @Override public void rollback(FlowRollback trigger, Map data) { changeApplianceVmStatus(ApplianceVmStatus.Disconnected); - if (originStatus.equals(ApplianceVmStatus.Connected)) { - fireDisconnectedCanonicalEvent(operr("appliance vm %s start failed", - getSelf().getUuid())); - } trigger.rollback(); } }); @@ -672,6 +804,59 @@ private FlowChain addAfterConnectNewCreatedVirtualRouterFlows(FlowChain chain) { return chain; } + protected void provisionApplianceVmAfterCreate(VmInstanceSpec spec, ApplianceVmSpec aspec, HypervisorType htype, NoErrorCompletion completion) { + if (ApplianceVmGlobalConfig.AUTO_ROLLBACK.value(Boolean.class)) { + completion.done(); + return; + } + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + + chain.setName(String.format("provision-appliancevm-after-create-%s", spec.getVmInventory().getUuid())); + chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); + chain.getData().put(ApplianceVmConstant.Params.applianceVmFirewallRules.toString(), aspec.getFirewallRules()); + + addBootstrapFlows(chain, htype); + + List subCreateFlows = getPostCreateFlows(); + if (subCreateFlows != null) { + for (Flow f : subCreateFlows) { + chain.then(f); + } + } + + chain.then(new NoRollbackFlow() { + String __name__ = "change-appliancevm-status-to-connected"; + + @Override + public void run(FlowTrigger trigger, Map data) { + // must reload here, otherwise it will override changes created by previous flows + changeApplianceVmStatus(ApplianceVmStatus.Connected); + trigger.next(); + } + }); + + addAfterConnectNewCreatedVirtualRouterFlows(chain); + + boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; + chain.noRollback(noRollbackOnFailure); + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.done(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + logger.debug(String.format("provision applianceVm[uuid:%s, name:%s] failed because %s", + spec.getVmInventory().getUuid(), + spec.getVmInventory().getName(), errCode.getDetails())); + completion.done(); + } + }).start(); + } + + @Override protected void instantiateVmFromNewCreate(final InstantiateNewCreatedVmInstanceMsg msg, final SyncTaskChain taskChain) { boolean callNext = true; @@ -693,6 +878,8 @@ protected void instantiateVmFromNewCreate(final InstantiateNewCreatedVmInstanceM final VmInstanceSpec spec = new VmInstanceSpec(); spec.setVmInventory(msg.getVmInstanceInventory()); + spec.setRequiredPrimaryStorageUuidForRootVolume(smsg.getApplianceVmSpec().getPrimaryStorageUuidForRootVolume()); + spec.setRootVolumeSystemTags(smsg.getApplianceVmSpec().getRootVolumeSystemTags()); spec.setRequiredHostUuid(smsg.getApplianceVmSpec().getRequiredHostUuid()); List nicSpecs = new ArrayList<>(); if (msg.getL3NetworkUuids() != null && !msg.getL3NetworkUuids().isEmpty()) { @@ -742,6 +929,7 @@ public DiskOfferingVO call(DiskOfferingVO arg) { changeVmStateInDb(VmInstanceStateEvent.starting); + HypervisorType htype = VolumeFormat.getMasterHypervisorTypeByVolumeFormat(imvo.getFormat()); extEmitter.beforeStartNewCreatedVm(VmInstanceInventory.valueOf(self)); FlowChain chain = apvmf.getCreateApplianceVmWorkFlowBuilder().build(); setFlowMarshaller(chain); @@ -751,54 +939,61 @@ public DiskOfferingVO call(DiskOfferingVO arg) { chain.getData().put(ApplianceVmConstant.Params.applianceVmFirewallRules.toString(), aspec.getFirewallRules()); chain.then(setApplianceStateRunningFlow()); - addBootstrapFlows(chain, VolumeFormat.getMasterHypervisorTypeByVolumeFormat(imvo.getFormat())); + if (ApplianceVmGlobalConfig.AUTO_ROLLBACK.value(Boolean.class)) { + addBootstrapFlows(chain, VolumeFormat.getMasterHypervisorTypeByVolumeFormat(imvo.getFormat())); - List subCreateFlows = getPostCreateFlows(); - if (subCreateFlows != null) { - for (Flow f : subCreateFlows) { - chain.then(f); + List subCreateFlows = getPostCreateFlows(); + if (subCreateFlows != null) { + for (Flow f : subCreateFlows) { + chain.then(f); + } } - } - chain.then(new NoRollbackFlow() { - String __name__ = "change-appliancevm-status-to-connected"; + chain.then(new NoRollbackFlow() { + String __name__ = "change-appliancevm-status-to-connected"; - @Override - public void run(FlowTrigger trigger, Map data) { - // must reload here, otherwise it will override changes created by previous flows - changeApplianceVmStatus(ApplianceVmStatus.Connected); - trigger.next(); - } - }); + @Override + public void run(FlowTrigger trigger, Map data) { + // must reload here, otherwise it will override changes created by previous flows + changeApplianceVmStatus(ApplianceVmStatus.Connected); + trigger.next(); + } + }); - addAfterConnectNewCreatedVirtualRouterFlows(chain); + addAfterConnectNewCreatedVirtualRouterFlows(chain); + } boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; chain.noRollback(noRollbackOnFailure); chain.done(new FlowDoneHandler(msg, taskChain) { @Override public void handle(Map data) { - VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - changeVmStateInDb(VmInstanceStateEvent.running, () -> new SQLBatch() { + provisionApplianceVmAfterCreate(spec, aspec, htype, new NoErrorCompletion(taskChain) { @Override - protected void scripts() { - self.setLastHostUuid(spec.getDestHost().getUuid()); - self.setHostUuid(spec.getDestHost().getUuid()); - self.setClusterUuid(spec.getDestHost().getClusterUuid()); - self.setZoneUuid(spec.getDestHost().getZoneUuid()); - self.setHypervisorType(spec.getDestHost().getHypervisorType()); - self.setRootVolumeUuid(spec.getDestRootVolume().getUuid()); + public void done() { + VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + changeVmStateInDb(VmInstanceStateEvent.running, () -> new SQLBatch() { + @Override + protected void scripts() { + self.setLastHostUuid(spec.getDestHost().getUuid()); + self.setHostUuid(spec.getDestHost().getUuid()); + self.setClusterUuid(spec.getDestHost().getClusterUuid()); + self.setZoneUuid(spec.getDestHost().getZoneUuid()); + self.setHypervisorType(spec.getDestHost().getHypervisorType()); + self.setRootVolumeUuid(spec.getDestRootVolume().getUuid()); + } + }.execute()); + + logger.debug(String.format("appliance vm[uuid:%s, name: %s, type:%s] is running ..", + self.getUuid(), self.getName(), getSelf().getApplianceVmType())); + VmInstanceInventory inv = VmInstanceInventory.valueOf(self); + extEmitter.afterStartNewCreatedVm(inv); + InstantiateNewCreatedVmInstanceReply reply = new InstantiateNewCreatedVmInstanceReply(); + reply.setVmInventory(inv); + bus.reply(msg, reply); + taskChain.next(); } - }.execute()); - - logger.debug(String.format("appliance vm[uuid:%s, name: %s, type:%s] is running ..", - self.getUuid(), self.getName(), getSelf().getApplianceVmType())); - VmInstanceInventory inv = VmInstanceInventory.valueOf(self); - extEmitter.afterStartNewCreatedVm(inv); - InstantiateNewCreatedVmInstanceReply reply = new InstantiateNewCreatedVmInstanceReply(); - reply.setVmInventory(inv); - bus.reply(msg, reply); - taskChain.next(); + }); } }).error(new FlowErrorHandler(msg, taskChain) { @Override @@ -837,6 +1032,7 @@ protected void changeApplianceVmStatus(ApplianceVmStatus newStatus) { self = dbf.updateAndRefresh(self); ApplianceVmCanonicalEvents.ApplianceVmStatusChangedData d = new ApplianceVmCanonicalEvents.ApplianceVmStatusChangedData(); d.setApplianceVmUuid(self.getUuid()); + d.setApplianceVmType(getSelf().getApplianceVmType()); d.setOldStatus(oldStatus.toString()); d.setNewStatus(newStatus.toString()); d.setInv(ApplianceVmInventory.valueOf(getSelf())); diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCanonicalEvents.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCanonicalEvents.java index 31575d88d0c..d4346118537 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCanonicalEvents.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCanonicalEvents.java @@ -30,6 +30,14 @@ default void fire(String path) { public static class NewVmCreatedData implements FireEvent { public ApplianceVmInventory vm; + public void setVm(ApplianceVmInventory vm) { + this.vm = vm; + } + + public ApplianceVmInventory getVm() { + return this.vm; + } + @Override public void fire() { fire(NEW_VM_CREATED); @@ -66,6 +74,7 @@ public void fire() { @NeedJsonSchema public static class ApplianceVmStatusChangedData { private String applianceVmUuid; + private String applianceVmType; private String oldStatus; private String newStatus; private ApplianceVmInventory inv; @@ -78,6 +87,14 @@ public void setApplianceVmUuid(String applianceVmUuid) { this.applianceVmUuid = applianceVmUuid; } + public String getApplianceVmType() { + return applianceVmType; + } + + public void setApplianceVmType(String applianceVmType) { + this.applianceVmType = applianceVmType; + } + public String getOldStatus() { return oldStatus; } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCascadeExtension.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCascadeExtension.java index f93f24e063c..d2134ad3f8c 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCascadeExtension.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCascadeExtension.java @@ -43,9 +43,13 @@ import org.zstack.header.volume.VolumeType; import org.zstack.header.zone.ZoneInventory; import org.zstack.header.zone.ZoneVO; +import org.zstack.network.service.vip.VipConstant; +import org.zstack.network.service.vip.VipDeletionMsg; +import org.zstack.network.service.vip.VipInventory; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; @@ -70,6 +74,8 @@ public class ApplianceVmCascadeExtension extends AbstractAsyncCascadeExtension { private PluginRegistry pluginRgty; @Autowired protected ThreadFacade thdf; + @Autowired + private ApplianceVmFacade apvmFacade; private static String NAME = ApplianceVmVO.class.getSimpleName(); @@ -283,9 +289,22 @@ private void handleL2NetworkDetach(CascadeAction action, final Completion comple .map(VmInstanceVO::getUuid).collect(Collectors.toList())).list(); if (!applianceVmVOS.isEmpty()) { - for (ApvmCascadeFilterExtensionPoint ext : pluginRgty.getExtensionList(ApvmCascadeFilterExtensionPoint.class)) { - applianceVmVOS = ext.filterApplianceVmCascade(applianceVmVOS, action, action.getParentIssuer(), l3uuids, new ArrayList<>()); + List toMigrateVms = new ArrayList<>(); + Map> apvmsByType = applianceVmVOS.stream() + .collect(Collectors.groupingBy(ApplianceVmVO::getApplianceVmType)); + + for (Map.Entry> entry : apvmsByType.entrySet()) { + ApplianceVmType vmType = ApplianceVmType.valueOf(entry.getKey()); + List vmsOfType = entry.getValue(); + + ApvmCascadeFilterExtensionPoint ext = apvmFacade.getApvmCascadeFilterExtensionPoint(vmType); + if (ext != null) { + vmsOfType = ext.filterApplianceVmCascade(vmsOfType, action, action.getParentIssuer(), l3uuids, + new ArrayList<>(), new ArrayList<>()); + } + toMigrateVms.addAll(vmsOfType); } + applianceVmVOS = toMigrateVms; } if (applianceVmVOS.isEmpty()) { @@ -374,6 +393,104 @@ public String getName() { }); } + protected Flow returnUsedIpFlow() { + return new NoRollbackFlow() { + + String __name__ = "delete-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List toDeleteIps = (List) + data.get(VmInstanceConstant.Params.UsedIPInventory.toString()); + + if (toDeleteIps.isEmpty()) { + logger.debug("no ip need to delete"); + trigger.next(); + return; + } + + List dmsgs = new ArrayList<>(); + for (UsedIpInventory ip : toDeleteIps) { + ReturnIpMsg msg = new ReturnIpMsg(); + msg.setL3NetworkUuid(ip.getL3NetworkUuid()); + msg.setUsedIpUuid(ip.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, L3NetworkConstant.SERVICE_ID, msg.getL3NetworkUuid()); + dmsgs.add(msg); + } + + List errorCodes = Collections.synchronizedList(new LinkedList()); + new While<>(dmsgs).step((deleteMsg, whileCompletion) -> { + bus.send(deleteMsg, new CloudBusCallBack(whileCompletion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.debug(String.format("delete ip [uuid:%s] failed %s", deleteMsg.getUsedIpUuid(), + reply.getError().getDetails())); + } + whileCompletion.done(); + } + }); + }, 10).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + trigger.next(); + } + }); + } + }; + } + + protected Flow deleteVmNicFlow() { + return new NoRollbackFlow() { + String __name__ = "delete-vmnic"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List toDeleteNics = (List) + data.get(VmInstanceConstant.Params.VmNicInventory.toString()); + + if(toDeleteNics.isEmpty()) { + logger.debug(String.format("no nic need for delete")); + trigger.next(); + return; + } + + List dmsgs = new ArrayList<>(); + for (VmNicInventory nic : toDeleteNics) { + DetachNicFromVmMsg msg = new DetachNicFromVmMsg(); + msg.setVmNicUuid(nic.getUuid()); + msg.setVmInstanceUuid(nic.getVmInstanceUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, nic.getVmInstanceUuid()); + dmsgs.add(msg); + } + + List errorCodes = Collections.synchronizedList(new LinkedList()); + new While<>(dmsgs).step((deleteMsg, whileCompletion) -> { + bus.send(deleteMsg, new CloudBusCallBack(whileCompletion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + errorCodes.add(reply.getError()); + } + whileCompletion.done(); + } + }); + }, 10).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodes.isEmpty()) { + logger.debug(String.format("detach nic for " + + "delete l3 success")); + trigger.next(); + return; + } + trigger.fail(errorCodes.get(0)); + } + }); + } + }; + } + protected void handleDeletion(final CascadeAction action, final Completion completion) { int op = toDeleteOpCode(action); @@ -382,8 +499,11 @@ protected void handleDeletion(final CascadeAction action, final Completion compl return; } List toDeleteNics = new ArrayList<>(); - final List apvms = apvmFromDeleteAction(action, toDeleteNics); + List toDeleteIps = new ArrayList<>(); + + final List apvms = apvmFromDeleteAction(action, toDeleteNics, toDeleteIps); if (apvms == null) { + logger.debug("no apvms to delete"); completion.success(); return; } @@ -391,7 +511,9 @@ protected void handleDeletion(final CascadeAction action, final Completion compl final List apvmToMigrate = new ArrayList(); final List apvmToDelete = new ArrayList(); FlowChain chain = FlowChainBuilder.newShareFlowChain(); - chain.setName(String.format("delete-cascade-for-appliance-vm")); + chain.setName("delete-cascade-for-appliance-vm"); + chain.getData().put(VmInstanceConstant.Params.UsedIPInventory.toString(), toDeleteIps); + chain.getData().put(VmInstanceConstant.Params.VmNicInventory.toString(), toDeleteNics); if (op == OP_MIGRATE) { chain.then(new ShareFlow() { @@ -506,52 +628,8 @@ public void run(List replies) { chain.then(new ShareFlow() { @Override public void setup() { - flow(new NoRollbackFlow() { - String __name__ = "delete-vmnic"; - - @Override - public void run(FlowTrigger trigger, Map data) { - if(toDeleteNics.isEmpty()) { - logger.debug(String.format("no nic need for delete")); - trigger.next(); - return; - } - - List dmsgs = new ArrayList<>(); - for (VmNicInventory nic : toDeleteNics) { - DetachNicFromVmMsg msg = new DetachNicFromVmMsg(); - msg.setVmNicUuid(nic.getUuid()); - msg.setVmInstanceUuid(nic.getVmInstanceUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, nic.getVmInstanceUuid()); - dmsgs.add(msg); - } - - List errorCodes = Collections.synchronizedList(new LinkedList()); - new While<>(dmsgs).step((deleteMsg, whileCompletion) -> { - bus.send(deleteMsg, new CloudBusCallBack(whileCompletion) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - errorCodes.add(reply.getError()); - } - whileCompletion.done(); - } - }); - }, 10).run(new WhileDoneCompletion(completion) { - @Override - public void done(ErrorCodeList errorCodeList) { - if (errorCodes.isEmpty()) { - logger.debug(String.format("detach nic for " + - "delete l3 success")); - trigger.next(); - return; - } - trigger.fail(errorCodes.get(0)); - return; - } - }); - } - }); + flow(returnUsedIpFlow()); + flow(deleteVmNicFlow()); flow(new NoRollbackFlow() { String __name__ = "delete-appliancevm"; @@ -627,7 +705,8 @@ public String getCascadeResourceName() { } @Transactional - protected List apvmFromDeleteAction(CascadeAction action, List toDeleteNics) { + protected List apvmFromDeleteAction(CascadeAction action, List toDeleteNics, + List toDeleteIps) { /* * return null or non-empty list * */ @@ -723,11 +802,32 @@ public String call(L3NetworkInventory arg) { q.setParameter("l3Uuids", l3uuids); List apvms = q.getResultList(); if (!apvms.isEmpty()) { - for (ApvmCascadeFilterExtensionPoint ext : pluginRgty.getExtensionList(ApvmCascadeFilterExtensionPoint.class)) { - apvms = ext.filterApplianceVmCascade(apvms, action, action.getParentIssuer(), l3uuids, toDeleteNics); + List toDeleteVms = new ArrayList<>(); + List vmNics = new ArrayList<>(); + List ips = new ArrayList<>(); + Map> apvmsByType = apvms.stream() + .collect(Collectors.groupingBy(ApplianceVmVO::getApplianceVmType)); + + for (Map.Entry> entry : apvmsByType.entrySet()) { + ApplianceVmType vmType = ApplianceVmType.valueOf(entry.getKey()); + List vmsOfType = entry.getValue(); + + ApvmCascadeFilterExtensionPoint ext = apvmFacade.getApvmCascadeFilterExtensionPoint(vmType); + if (ext != null) { + vmsOfType = ext.filterApplianceVmCascade(vmsOfType, action, action.getParentIssuer(), l3uuids, + vmNics, ips); + if (!vmNics.isEmpty()) { + toDeleteNics.addAll(vmNics); + } + if (!ips.isEmpty()) { + toDeleteIps.addAll(ips); + } + } + toDeleteVms.addAll(vmsOfType); } - if (!apvms.isEmpty()) { - ret = ApplianceVmInventory.valueOf1(apvms); + + if (!toDeleteVms.isEmpty()) { + ret = ApplianceVmInventory.valueOf1(toDeleteVms); } } } else if (IpRangeVO.class.getSimpleName().equals(action.getParentIssuer())) { @@ -791,12 +891,32 @@ public List call() { } } } - for (ApvmCascadeFilterExtensionPoint ext : pluginRgty.getExtensionList(ApvmCascadeFilterExtensionPoint.class)) { - vmvos = ext.filterApplianceVmCascade(vmvos, action, action.getParentIssuer(), ipruuids, toDeleteNics); + + List toDeleteVms = new ArrayList<>(); + Map> vmvosByType = vmvos.stream() + .collect(Collectors.groupingBy(ApplianceVmVO::getApplianceVmType)); + + for (Map.Entry> entry : vmvosByType.entrySet()) { + ApplianceVmType vmType = ApplianceVmType.valueOf(entry.getKey()); + List vmsOfType = entry.getValue(); + List vmNics = new ArrayList<>(); + List ips = new ArrayList<>(); + ApvmCascadeFilterExtensionPoint ext = apvmFacade.getApvmCascadeFilterExtensionPoint(vmType); + if (ext != null) { + vmsOfType = ext.filterApplianceVmCascade(vmsOfType, action, action.getParentIssuer(), ipruuids, + vmNics, ips); + if (!vmNics.isEmpty()) { + toDeleteNics.addAll(vmNics); + } + if (!ips.isEmpty()) { + toDeleteIps.addAll(ips); + } + } + toDeleteVms.addAll(vmsOfType); } - if (!vmvos.isEmpty()) { - ret = ApplianceVmInventory.valueOf1(vmvos); + if (!toDeleteVms.isEmpty()) { + ret = ApplianceVmInventory.valueOf1(toDeleteVms); } } else if (AccountVO.class.getSimpleName().equals(action.getParentIssuer())) { final List auuids = CollectionUtils.transformToList((List) action.getParentIssuerContext(), new Function() { @@ -832,7 +952,8 @@ public CascadeAction createActionForChildResource(CascadeAction action) { if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { int op = toDeleteOpCode(action); if (op != OP_NOPE) { - List apvms = apvmFromDeleteAction(action, new ArrayList<>()); + List apvms = apvmFromDeleteAction(action, new ArrayList<>(), + new ArrayList<>()); if (!apvms.isEmpty()) { return action.copy().setParentIssuer(NAME).setParentIssuerContext(apvms); diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCommands.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCommands.java index 4141d0a4262..e70d3443d51 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCommands.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmCommands.java @@ -28,4 +28,73 @@ public static class InitCmd extends AgentCommand { public static class InitRsp extends AgentResponse { } + + public static class ApplianceVmAbnormalFilesCmd extends AgentCommand { + private String applianceVmUuid; + private List abnormalFiles; + private String diskTotal; + private String diskUsed; + private String diskUsedutilization; + + public String getApplianceVmUuid() { + return applianceVmUuid; + } + + public void setApplianceVmUuid(String virtualRouterUuid) { + this.applianceVmUuid = virtualRouterUuid; + } + + static class AbnormalFile { + private String filePath; + private String fileSize; + + public String getFilePath() { + return filePath; + } + + public void setFilePath(String filePath) { + this.filePath = filePath; + } + + public String getFileSize() { + return fileSize; + } + + public void setFileSize(String fileSize) { + this.fileSize = fileSize; + } + } + + public List getAbnormalFiles() { + return abnormalFiles; + } + + public void setAbnormalFiles(List abnormalFiles) { + this.abnormalFiles = abnormalFiles; + } + + public String getDiskTotal() { + return diskTotal; + } + + public void setDiskTotal(String diskTotal) { + this.diskTotal = diskTotal; + } + + public String getDiskUsed() { + return diskUsed; + } + + public void setDiskUsed(String diskUsed) { + this.diskUsed = diskUsed; + } + + public String getDiskUsedutilization() { + return diskUsedutilization; + } + + public void setDiskUsedutilization(String diskUsedutilization) { + this.diskUsedutilization = diskUsedutilization; + } + } } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConnectFlow.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConnectFlow.java index 0e0131ace83..be67c45a9f2 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConnectFlow.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConnectFlow.java @@ -144,6 +144,7 @@ public boolean run() { logger.warn(e1.getMessage(), e1); ErrorCode err = e1 instanceof OperationFailureException ? ((OperationFailureException)e1).getErrorCode() : err(ApplianceVmErrors.UNABLE_TO_START, e1.getMessage()); chain.fail(err); + Thread.currentThread().interrupt(); return true; } } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConstant.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConstant.java index 7d7781b0045..7aaa282d77d 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConstant.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmConstant.java @@ -11,11 +11,17 @@ public class ApplianceVmConstant { public static final String SERVICE_ID = "applianceVm"; public static final String KVM_CHANNEL_AGENT_PATH = "/var/lib/zstack/kvm/agentSocket"; + public static final String KVM_CHANNEL_QEMU_GA_PATH = "/var/lib/libvirt/qemu"; public static final String ANSIBLE_PLAYBOOK_NAME = "appliancevm.py"; public static final String ANSIBLE_MODULE_PATH = "ansible/appliancevm"; + public static final String APPLIANCE_VM_ABNORMAL_FILE_REPORT = "/appliancevm/abnormalfiles/report"; + public static final String ABNORMAL_FILE_MAX_SIZE = "abnormalFileMaxSize"; + + public static final String APPLIANCE_VM_CPUMODE = "cpuMode"; + public enum BootstrapParams { managementNic, additionalNics, @@ -37,6 +43,7 @@ public static enum Params { applianceVmUuid, timeout, rebuildSnat, + fromApi, } public static final String REFRESH_FIREWALL_PATH = "/appliancevm/refreshfirewall"; diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployAgentFlow.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployAgentFlow.java index 9e3ec2bdc37..63e1b72f9d2 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployAgentFlow.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployAgentFlow.java @@ -190,14 +190,7 @@ public VmNicInventory call(VmNicInventory arg) { runner.setPrivateKey(privKey); runner.setAgentPort(ApplianceVmGlobalProperty.AGENT_PORT); runner.setTargetIp(mgmtIp); - runner.putArgument("pkg_appliancevm", ApplianceVmGlobalProperty.AGENT_PACKAGE_NAME); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - trigger.fail(operr("chrony server not configured!")); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } + runner.setDeployArguments(new ApplianceVmDeployArguments()); runner.run(new ReturnValueCompletion(trigger) { @Override public void success(Boolean deployed) { diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployArguments.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployArguments.java new file mode 100644 index 00000000000..a4cd62e026c --- /dev/null +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmDeployArguments.java @@ -0,0 +1,18 @@ +package org.zstack.appliancevm; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; + +public class ApplianceVmDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_appliancevm") + private String packageName = ApplianceVmGlobalProperty.AGENT_PACKAGE_NAME; + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + @Override + public String getPackageName() { + return packageName; + } +} diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacade.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacade.java index 261c1ee638e..fa8411218ca 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacade.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacade.java @@ -43,4 +43,6 @@ public interface ApplianceVmFacade { void attachApplianceVmToHaGroup(String vmUuid, String haGroupUuid); void dettachVmInstanceFromAffinityGroup(String vmUuid); void detachVirtualRouterFromHaGroup(String vmUuid, String haGroupUuid); + + ApvmCascadeFilterExtensionPoint getApvmCascadeFilterExtensionPoint(ApplianceVmType applianceVmType); } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacadeImpl.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacadeImpl.java index ca729c70de8..9a415a48bfe 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacadeImpl.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmFacadeImpl.java @@ -1,5 +1,6 @@ package org.zstack.appliancevm; +import com.google.gson.Gson; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.appliancevm.ApplianceVmConstant.BootstrapParams; @@ -7,10 +8,7 @@ import org.zstack.core.CoreGlobalProperty; import org.zstack.core.Platform; import org.zstack.core.ansible.AnsibleFacade; -import org.zstack.core.cloudbus.CloudBus; -import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.cloudbus.MessageSafe; -import org.zstack.core.cloudbus.ResourceDestinationMaker; +import org.zstack.core.cloudbus.*; import org.zstack.core.componentloader.PluginExtension; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.config.GlobalConfigFacade; @@ -35,20 +33,19 @@ import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.rest.RESTFacade; +import org.zstack.header.rest.SyncHttpCallHandler; import org.zstack.header.vm.*; import org.zstack.network.l2.L2NetworkManager; import org.zstack.network.service.MtuGetter; import org.zstack.header.vm.hooks.VmInstanceAfterCreateHook; import org.zstack.header.vm.hooks.VmInstanceAfterDestroyHook; -import org.zstack.header.vm.hooks.VmInstanceBeforeCreateHook; import org.zstack.header.vm.hooks.VmInstanceBeforeDestroyHook; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; -import org.zstack.utils.zsha2.ZSha2Helper; -import org.zstack.utils.zsha2.ZSha2Info; import javax.persistence.Query; import java.util.*; @@ -79,11 +76,16 @@ public class ApplianceVmFacadeImpl extends AbstractService implements ApplianceV private L2NetworkManager l2Mgr; @Autowired private VmInstanceHookManager vmHookMgr; + @Autowired + protected EventFacade evtf; + @Autowired + private RESTFacade restf; private List createApplianceVmWorkFlow; private FlowChainBuilder createApplianceVmWorkFlowBuilder; private Map bootstrapInfoFlowFactories = new HashMap(); private Map l2NetworkGetVniExtensionPointMap = new HashMap<>(); + private Map apvmCascadeFilterExtensionPointMap = new HashMap<>(); private String OWNER = String.format("ApplianceVm.%s", Platform.getManagementServerId()); @@ -220,6 +222,18 @@ private void populateExtensions() { l2NetworkGetVniExtensionPointMap.put(ext.getL2NetworkVniType(), ext); logger.debug(String.format("add new l2NetworkGetVniExtensionPoint, %s: %s", ext.getL2NetworkVniType(), ext.getClass().getCanonicalName())); } + + for (ApvmCascadeFilterExtensionPoint ext : pluginRgty.getExtensionList(ApvmCascadeFilterExtensionPoint.class)) { + ApplianceVmType type = ext.getApplianceVmType(); + ApvmCascadeFilterExtensionPoint old = apvmCascadeFilterExtensionPointMap.get(type); + if (old != null) { + throw new CloudRuntimeException(String.format("two extensions[%s, %s] declare ApvmCascadeFilterExtensionPoint for appliance vm type[%s]", old.getClass().getName(), ext.getClass().getName(), type)); + } + + apvmCascadeFilterExtensionPointMap.put(type, ext); + logger.debug(String.format("add new apvmCascadeFilterExtensionPoint, %s: %s", type, ext.getClass().getCanonicalName())); + + } } private void deployAnsible() { @@ -236,6 +250,23 @@ public boolean start() { populateExtensions(); deployAnsible(); hookVmEvents(); + + restf.registerSyncHttpCallHandler(ApplianceVmConstant.APPLIANCE_VM_ABNORMAL_FILE_REPORT, ApplianceVmCommands.ApplianceVmAbnormalFilesCmd.class, new SyncHttpCallHandler() { + @Override + public String handleSyncHttpCall(ApplianceVmCommands.ApplianceVmAbnormalFilesCmd cmd) { + if (cmd == null) { + return null; + } + + if (!ApplianceVmGlobalConfig.ENABLE_ABNORMAL_FILE_REPORTER.value(Boolean.class)) { + return null; + } + + fireApplianceVmAbnormalFilesExistsEvent(cmd); + return null; + } + }); + return true; } @@ -279,6 +310,22 @@ public void beforeDestroy(VmInstanceInventory vm) { vmHookMgr.hookDestroyEvent(VmDestroyHook::new); } + private void fireApplianceVmAbnormalFilesExistsEvent(ApplianceVmCommands.ApplianceVmAbnormalFilesCmd cmd) { + ApplianceVmCanonicalEvents.ApplianceVmAbnormalFilesDate data = new ApplianceVmCanonicalEvents.ApplianceVmAbnormalFilesDate(); + String applianceVmType = Q.New(ApplianceVmVO.class).eq(ApplianceVmVO_.uuid, cmd.getApplianceVmUuid()).select(ApplianceVmVO_.applianceVmType).findValue(); + if (applianceVmType == null) { + return; + } + data.setApplianceVmUuid(cmd.getApplianceVmUuid()); + data.setApplianceVmType(applianceVmType); + data.setDiskTotal(cmd.getDiskTotal()); + data.setDiskUsed(cmd.getDiskUsed()); + data.setDiskUsedutilization(cmd.getDiskUsedutilization()); + data.setAbnormalFiles(new Gson().toJson(cmd.getAbnormalFiles())); + + evtf.fire(ApplianceVmCanonicalEvents.APPLIANCEVM_ABNORMAL_FILE_REPORT_PATH, data); + } + @Override public boolean stop() { return true; @@ -304,7 +351,6 @@ private List reduceNic(List nics, VmNicInventory public Map prepareBootstrapInformation(VmInstanceSpec spec) { VmNicInventory mgmtNic = null; String defaultL3Uuid; - int sshPort; String applianceVmSubType; if (spec.getCurrentVmOperation() == VmInstanceConstant.VmOperation.NewCreate) { ApplianceVmSpec aspec = spec.getExtensionData(ApplianceVmConstant.Params.applianceVmSpec.toString(), ApplianceVmSpec.class); @@ -317,7 +363,6 @@ public Map prepareBootstrapInformation(VmInstanceSpec spec) { DebugUtils.Assert(mgmtNic!=null, String.format("cannot find management nic for appliance vm[uuid:%s]", aspec.getUuid())); defaultL3Uuid = aspec.getDefaultRouteL3Network() != null ? aspec.getDefaultRouteL3Network().getUuid() : mgmtNic.getL3NetworkUuid(); - sshPort = aspec.getSshPort(); applianceVmSubType = spec.getExtensionData(ApplianceVmConstant.Params.applianceVmSubType.toString(), String.class); } else { ApplianceVmVO avo = dbf.findByUuid(spec.getVmInventory().getUuid(), ApplianceVmVO.class); @@ -325,8 +370,6 @@ public Map prepareBootstrapInformation(VmInstanceSpec spec) { ApplianceVmInventory ainv = ApplianceVmInventory.valueOf(avo); mgmtNic = ainv.getManagementNic(); defaultL3Uuid = ainv.getDefaultRouteL3NetworkUuid(); - //TODO: make it configurable - sshPort = 22; } Map ret = new HashMap(); @@ -404,7 +447,6 @@ public Map prepareBootstrapInformation(VmInstanceSpec spec) { String publicKey = asf.getPublicKey(); ret.put(ApplianceVmConstant.BootstrapParams.publicKey.toString(), publicKey); - ret.put(BootstrapParams.sshPort.toString(), sshPort); ret.put(BootstrapParams.uuid.toString(), spec.getVmInventory().getUuid()); ret.put(BootstrapParams.managementNodeIp.toString(), Platform.getManagementServerIp()); ret.put(BootstrapParams.managementNodeCidr.toString(), Platform.getManagementServerCidr()); @@ -595,4 +637,8 @@ public void detachVirtualRouterFromHaGroup(String vmUuid, String haGroupUuid) { ext.detachVirtualRouterFromHaGroup(vmUuid, haGroupUuid); } } + + public ApvmCascadeFilterExtensionPoint getApvmCascadeFilterExtensionPoint(ApplianceVmType type) { + return apvmCascadeFilterExtensionPointMap.get(type); + } } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalConfig.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalConfig.java index b206e5db4e9..6ae0ab0ee9d 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalConfig.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalConfig.java @@ -26,4 +26,13 @@ public class ApplianceVmGlobalConfig { public static GlobalConfig DELETE_TIMEOUT = new GlobalConfig(CATEGORY, "deletion.timeout"); @GlobalConfigValidation public static GlobalConfig APPLIANCENUMA = new GlobalConfig(CATEGORY, "applianceVmNuma"); + + @GlobalConfigValidation + public static GlobalConfig AUTO_ROLLBACK = new GlobalConfig(CATEGORY, "auto.rollback"); + + @GlobalConfigValidation() + public static GlobalConfig ENABLE_ABNORMAL_FILE_REPORTER = new GlobalConfig(CATEGORY, "enableAbnormalFileReporter"); + + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig ABNORMAL_FILE_MAX_SIZE = new GlobalConfig(CATEGORY, "abnormalFileMaxSize"); } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalProperty.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalProperty.java index 48dfd0bb177..6658e2608fe 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalProperty.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmGlobalProperty.java @@ -11,7 +11,7 @@ public class ApplianceVmGlobalProperty { public static boolean NO_ROLLBACK_ON_POST_FAILURE; @GlobalProperty(name = "ApplianceVm.connectVerbose", defaultValue = "false") public static boolean CONNECT_VERBOSE; - @GlobalProperty(name="ApplianceVm.agentPackageName", defaultValue = "appliancevm-4.4.0.tar.gz") + @GlobalProperty(name="ApplianceVm.agentPackageName", defaultValue = "appliancevm-5.4.0.tar.gz") public static String AGENT_PACKAGE_NAME; @GlobalProperty(name="ApplianceVm.agentPort", defaultValue = "7759") public static int AGENT_PORT; diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmBackend.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmBackend.java index de36360860d..35deb659c11 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmBackend.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmBackend.java @@ -27,14 +27,24 @@ public void addAddon(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommand } KVMAddons.Channel chan = new KVMAddons.Channel(); + KVMAddons.Channel chan_vr = new KVMAddons.Channel(); cmd.setEmulateHyperV(false); + chan.setSocketPath(makeChannelSocketPath(spec.getVmInventory().getUuid())); chan.setTargetName("applianceVm.vport"); cmd.getAddons().put(KVMAddons.Channel.NAME, chan); logger.debug(String.format("make kvm channel device[path:%s, target:%s]", chan.getSocketPath(), chan.getTargetName())); + + chan_vr.setSocketPath(makeChannelVRSocketPath(spec.getVmInventory().getUuid())); + chan_vr.setTargetName("org.qemu.guest_agent.0"); // this channel name must keep org.qemu.guest_agent to use qemu-ga + cmd.getAddons().put(KVMAddons.Channel.VR_NAME, chan_vr); + logger.debug(String.format("make kvm channel device[path:%s, target:%s]", chan_vr.getSocketPath(), chan_vr.getTargetName())); } public String makeChannelSocketPath(String apvmuuid) { return PathUtil.join(ApplianceVmConstant.KVM_CHANNEL_AGENT_PATH, String.format("applianceVm.%s", apvmuuid)); } + private String makeChannelVRSocketPath(String apvmuuid) { + return PathUtil.join(ApplianceVmConstant.KVM_CHANNEL_QEMU_GA_PATH, apvmuuid); + } } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmCommands.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmCommands.java index 4a6a3997a97..9a849b670d8 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmCommands.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmKvmCommands.java @@ -1,5 +1,6 @@ package org.zstack.appliancevm; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.kvm.KVMAgentCommands; import java.util.Map; @@ -9,9 +10,11 @@ public interface ApplianceVmKvmCommands { public static class PrepareBootstrapInfoCmd extends KVMAgentCommands.AgentCommand { public static final String PATH = "/appliancevm/setbootstrapinfo"; - + @GrayVersion(value = "5.0.0") private Map info; + @GrayVersion(value = "5.0.0") private String socketPath; + @GrayVersion(value = "5.0.0") private Integer bootStrapInfoTimeout; public Map getInfo() { diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmManagementIpChecker.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmManagementIpChecker.java index d822cb9eac2..7767c8a7fa5 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmManagementIpChecker.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmManagementIpChecker.java @@ -3,14 +3,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.vm.VmBeforeCreateOnHypervisorExtensionPoint; import org.zstack.header.vm.VmBeforeStartOnHypervisorExtensionPoint; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmNicInventory; -import org.zstack.utils.CollectionUtils; -import org.zstack.utils.DebugUtils; +import org.zstack.utils.*; import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.NetworkUtils; import static org.zstack.core.Platform.err; @@ -18,9 +19,12 @@ /** */ public class ApplianceVmManagementIpChecker implements VmBeforeCreateOnHypervisorExtensionPoint, VmBeforeStartOnHypervisorExtensionPoint { + private static final CLogger logger = Utils.getLogger(ApplianceVmManagementIpChecker.class); @Autowired private DatabaseFacade dbf; + @Autowired + private ErrorFacade errf; private void checkManagementIp(VmInstanceSpec spec, boolean isNewCreated) { if (CoreGlobalProperty.UNIT_TEST_ON) { @@ -47,7 +51,8 @@ public VmNicInventory call(VmNicInventory arg) { DebugUtils.Assert(mgmtNic!=null, String.format("cannot find management nic of appliance vm[uuid:%s, newCreated: %s]", spec.getVmInventory().getUuid(), isNewCreated)); - if (NetworkUtils.isReachable(mgmtNic.getIp(), 1000)) { + ShellResult ret = ShellUtils.runAndReturn(String.format("ping -c 1 -W 1 %s", mgmtNic.getIp())); + if (ret.isReturnCode(0) || NetworkUtils.isReachable(mgmtNic.getIp(), 1000)) { throw new OperationFailureException(err(ApplianceVmErrors.MANAGEMENT_IP_OCCUPIED, "the management nic IP[%s] has been occupied by another device in the data center, we can ping it", mgmtNic.getIp() )); diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmPriorityUpgradeConfigExtensionPoint.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmPriorityUpgradeConfigExtensionPoint.java index ea511d8cb56..354a68e340c 100644 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmPriorityUpgradeConfigExtensionPoint.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmPriorityUpgradeConfigExtensionPoint.java @@ -1,13 +1,12 @@ package org.zstack.appliancevm; import org.springframework.beans.factory.annotation.Autowired; -import org.zstack.compute.vm.VmPriorityGlobalProperty; +import org.zstack.compute.vm.VmGlobalProperty; import org.zstack.compute.vm.VmPriorityOperator; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.*; import org.zstack.core.db.Q; import org.zstack.header.Component; -import org.zstack.header.core.NopeNoErrorCompletion; import org.zstack.header.core.NopeWhileDoneCompletion; import org.zstack.header.core.WhileCompletion; import org.zstack.header.errorcode.ErrorCode; @@ -103,7 +102,7 @@ public void run(MessageReply reply) { } private void initRunningApplianceVmPriority() { - if (!VmPriorityGlobalProperty.initRunningApplianceVmPriority) { + if (!VmGlobalProperty.initRunningApplianceVmPriority) { return; } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSpec.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSpec.java index 44bc8b9ef92..889b2963c4d 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSpec.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSpec.java @@ -45,6 +45,8 @@ public class ApplianceVmSpec implements Serializable { private String requiredZoneUuid; private String requiredClusterUuid; private String requiredHostUuid; + private String primaryStorageUuidForRootVolume; + private List rootVolumeSystemTags; @NoJsonSchema private Map applianceData = new HashMap<>(); @@ -239,6 +241,14 @@ public void setDefaultL3Network(L3NetworkInventory defaultL3Network) { public void setRequiredHostUuid(String requiredHostUuid) { this.requiredHostUuid = requiredHostUuid; } + public String getPrimaryStorageUuidForRootVolume() { return primaryStorageUuidForRootVolume; } + + public void setPrimaryStorageUuidForRootVolume(String primaryStorageUuidForRootVolume) { this.primaryStorageUuidForRootVolume = primaryStorageUuidForRootVolume; } + + public List getRootVolumeSystemTags() { return rootVolumeSystemTags; } + + public void setRootVolumeSystemTags(List rootVolumeSystemTags) { this.rootVolumeSystemTags = rootVolumeSystemTags; } + public T getExtensionData(String key, Class clazz) { JsonWrapper wrapper = applianceData.get(key); if (wrapper == null) { diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmStatus.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmStatus.java index 5c865dfb25a..363036b4650 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmStatus.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmStatus.java @@ -5,5 +5,6 @@ public enum ApplianceVmStatus { Connecting, Connected, - Disconnected + Disconnected, + Destroying } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSyncConfigToHaGroupFlow.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSyncConfigToHaGroupFlow.java index b2efff75d25..f6433296b5e 100644 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSyncConfigToHaGroupFlow.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSyncConfigToHaGroupFlow.java @@ -42,6 +42,7 @@ public void run(final FlowTrigger chain, Map data) { List exps = pluginRgty.getExtensionList(ApplianceVmSyncConfigToHaGroupExtensionPoint.class); if (exps == null || exps.isEmpty()) { + logger.debug(String.format("there is no exp for ApplianceVmSyncConfigToHaGroupExtensionPoint")); chain.next(); return; } @@ -50,11 +51,13 @@ public void run(final FlowTrigger chain, Map data) { if (spec.getMessage() instanceof APIStartVmInstanceMsg) { systemTags = ((APIStartVmInstanceMsg)spec.getMessage()).getSystemTags(); } else { + logger.debug("msg is not APIStartVmInstanceMsg"); chain.next(); return; } if (systemTags == null || systemTags.isEmpty()) { + logger.debug("there is no systemTags"); chain.next(); return; } @@ -63,6 +66,7 @@ public void run(final FlowTrigger chain, Map data) { ApplianceVmVO applianceVmVO = dbf.findByUuid(inv.getUuid(), ApplianceVmVO.class); /* only handle first join ha group */ if (applianceVmVO.isHaEnabled()) { + logger.debug(String.format("applianceVm[uuid:%s] is in hastatus", inv.getUuid())); chain.next(); return; } @@ -77,6 +81,7 @@ public void run(final FlowTrigger chain, Map data) { haUuid = token.get(ApplianceVmSystemTags.APPLIANCEVM_HA_UUID_TOKEN); } if (haUuid == null) { + logger.debug(String.format("there is not ha group uuid")); chain.next(); return; } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSystemTags.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSystemTags.java index d04a9eb52c8..4dafb10c8ba 100644 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSystemTags.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmSystemTags.java @@ -2,6 +2,7 @@ import org.zstack.header.tag.TagDefinition; import org.zstack.tag.PatternedSystemTag; +import org.zstack.tag.SystemTag; /** * Created by shixin on 2019/06/11 @@ -22,4 +23,7 @@ public class ApplianceVmSystemTags { public static String APPLIANCEVM_STATIC_IP_L3_TOKEN = "l3Uuid"; public static PatternedSystemTag APPLIANCEVM_STATIC_IP = new PatternedSystemTag(String.format( "staticIp::{%s}::{%s}", APPLIANCEVM_STATIC_IP_L3_TOKEN, APPLIANCEVM_STATIC_IP_TOKEN), ApplianceVmVO.class); + + public static SystemTag APPLIANCEVM_DEPLOY_AGENT_ON_START = + new SystemTag("needDeployAgentOnStart", ApplianceVmVO.class); } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmType.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmType.java index 4b49ea64ca2..8bdadfae1f9 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmType.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApplianceVmType.java @@ -1,9 +1,8 @@ package org.zstack.appliancevm; import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; /** * Created with IntelliJ IDEA. @@ -14,12 +13,23 @@ public class ApplianceVmType implements Serializable { private static Map types = Collections.synchronizedMap(new HashMap()); private final String typeName; + private boolean needOverlay = false; public ApplianceVmType(String typeName) { this.typeName = typeName; types.put(typeName, this); } + public ApplianceVmType(String typeName, boolean needOverlay) { + this.typeName = typeName; + this.needOverlay = needOverlay; + types.put(typeName, this); + } + + public boolean isNeedOverlay() { + return needOverlay; + } + public static ApplianceVmType valueOf(String typeName) { ApplianceVmType type = types.get(typeName); if (type == null) { @@ -28,6 +38,10 @@ public static ApplianceVmType valueOf(String typeName) { return type; } + public static List values() { + return new ArrayList<>(types.values()); + } + @Override public String toString() { return typeName; diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApvmCascadeFilterExtensionPoint.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApvmCascadeFilterExtensionPoint.java index 9718e079df9..cd6d8903599 100644 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApvmCascadeFilterExtensionPoint.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/ApvmCascadeFilterExtensionPoint.java @@ -1,13 +1,37 @@ package org.zstack.appliancevm; import org.zstack.core.cascade.CascadeAction; +import org.zstack.header.network.l3.UsedIpInventory; import org.zstack.header.vm.VmNicInventory; import java.util.List; /** + * Appliance VM cascade deletion filter extension point - Factory pattern + * Each implementation handles cascade deletion logic for specific appliance VM type + * * Created by weiwang on 22/10/2017 */ public interface ApvmCascadeFilterExtensionPoint { - List filterApplianceVmCascade(List applianceVmVOS, CascadeAction action, String parentIssuer, List parentIssuerUuids, List toDeleteNics); + /** + * Filter appliance VMs that need to be cascade deleted + * + * @param applianceVmVOS appliance VM list to process + * @param action cascade action + * @param parentIssuer parent resource type + * @param parentIssuerUuids parent resource UUID list + * @param toDeleteNics nics to be deleted (output parameter) + * @param toDeleteIps IPs to be deleted (output parameter) + * @return filtered VM list to delete + */ + List filterApplianceVmCascade(List applianceVmVOS, CascadeAction action, + String parentIssuer, List parentIssuerUuids, + List toDeleteNics, + List toDeleteIps); + + /** + * Check if this factory supports the specified appliance VM type + * @return true if supported, false otherwise + */ + ApplianceVmType getApplianceVmType(); } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/CreateApplianceVmJob.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/CreateApplianceVmJob.java index c0cf830da6d..f25d80f4818 100755 --- a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/CreateApplianceVmJob.java +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/CreateApplianceVmJob.java @@ -118,6 +118,7 @@ public void run(FlowTrigger trigger, Map data) { ImageVO imageVO = Q.New(ImageVO.class).eq(ImageVO_.uuid, spec.getTemplate().getUuid()).find(); avo.setPlatform(imageVO.getPlatform().toString()); avo.setGuestOsType(imageVO.getGuestOsType()); + avo.setArchitecture(imageVO.getArchitecture()); InstanceOfferingVO iovo = dbf.findByUuid(spec.getInstanceOffering().getUuid(), InstanceOfferingVO.class); avo.setCpuNum(iovo.getCpuNum()); @@ -144,6 +145,12 @@ protected ApplianceVmVO scripts() { rc.updateValue(finalAvo1.getUuid(), Boolean.TRUE.toString()); } + String cpuMode = spec.getExtensionData(ApplianceVmConstant.APPLIANCE_VM_CPUMODE, String.class); + if (cpuMode != null) { + ResourceConfig rc = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + rc.updateValue(finalAvo1.getUuid(), cpuMode); + } + return reload(vo); } }.execute(); @@ -175,12 +182,6 @@ protected ApplianceVmVO scripts() { } } - ResourceConfig multiQueues = rcf.getResourceConfig(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM.getIdentity()); - - // set VPC router's CPU mode to default NONE - ResourceConfig rc = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); - rc.updateValue(avo.getUuid(), KVMConstant.CPU_MODE_NONE); - trigger.next(); } diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/HypervisorBasedApplianceVmConfigurationFactory.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/HypervisorBasedApplianceVmConfigurationFactory.java new file mode 100644 index 00000000000..dbfd9688a37 --- /dev/null +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/HypervisorBasedApplianceVmConfigurationFactory.java @@ -0,0 +1,9 @@ +package org.zstack.appliancevm; + +import org.zstack.header.vm.VmInstanceSpec; + +public interface HypervisorBasedApplianceVmConfigurationFactory { + ApplianceVmType getApplianceVmType(); + + void createHypervisorBasedConfigurations(VmInstanceSpec spec); +} diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/kvm/KvmApplianceVmFactory.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/kvm/KvmApplianceVmFactory.java new file mode 100644 index 00000000000..51539dd85b0 --- /dev/null +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/kvm/KvmApplianceVmFactory.java @@ -0,0 +1,57 @@ +package org.zstack.appliancevm.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.appliancevm.ApplianceVmFactory; +import org.zstack.appliancevm.ApplianceVmVO; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.Component; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.kvm.KVMSubTypeVmConfigurationFactory; + +import java.util.HashMap; +import java.util.Map; + +public class KvmApplianceVmFactory implements KVMSubTypeVmConfigurationFactory, Component { + private final Map kvmApplianceVmSubTypeFactoryMap = new HashMap<>(); + + @Autowired + private PluginRegistry pluginRgty; + @Autowired + private DatabaseFacade dbf; + + @Override + public String getVmInstanceType() { + return ApplianceVmFactory.type.toString(); + } + + @Override + public void createConfigurations(VmInstanceSpec spec) { + ApplianceVmVO self = dbf.findByUuid(spec.getVmInventory().getUuid(), ApplianceVmVO.class); + KvmApplianceVmSubTypeFactory kvmApplianceVmSubTypeFactory = kvmApplianceVmSubTypeFactoryMap.get(self.getApplianceVmType().toString()); + kvmApplianceVmSubTypeFactory.createHypervisorBasedConfigurations(spec); + } + + private void populateExtensions() { + for (KvmApplianceVmSubTypeFactory ext : pluginRgty.getExtensionList(KvmApplianceVmSubTypeFactory.class)) { + KvmApplianceVmSubTypeFactory old = kvmApplianceVmSubTypeFactoryMap.get(ext.getApplianceVmType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VmInstanceFactory[%s, %s] for vm of type[%s]", + old.getClass().getName(), ext.getClass().getName(), ext.getApplianceVmType())); + } + kvmApplianceVmSubTypeFactoryMap.put(ext.getApplianceVmType().toString(), ext); + } + } + + @Override + public boolean start() { + populateExtensions(); + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/applianceVm/src/main/java/org/zstack/appliancevm/kvm/KvmApplianceVmSubTypeFactory.java b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/kvm/KvmApplianceVmSubTypeFactory.java new file mode 100644 index 00000000000..56827bd4434 --- /dev/null +++ b/plugin/applianceVm/src/main/java/org/zstack/appliancevm/kvm/KvmApplianceVmSubTypeFactory.java @@ -0,0 +1,6 @@ +package org.zstack.appliancevm.kvm; + +import org.zstack.appliancevm.HypervisorBasedApplianceVmConfigurationFactory; + +public interface KvmApplianceVmSubTypeFactory extends HypervisorBasedApplianceVmConfigurationFactory { +} diff --git a/plugin/cbd/pom.xml b/plugin/cbd/pom.xml new file mode 100644 index 00000000000..cdd77c86b4b --- /dev/null +++ b/plugin/cbd/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + org.zstack + plugin + 5.4.0 + + + cbd + + + + org.zstack + kvm + ${project.version} + + + org.zstack + storage + ${project.version} + + + org.zstack + externalStorage + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + \ No newline at end of file diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/AddonInfo.java b/plugin/cbd/src/main/java/org/zstack/cbd/AddonInfo.java new file mode 100644 index 00000000000..c08f5c37c66 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/AddonInfo.java @@ -0,0 +1,38 @@ +package org.zstack.cbd; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Xingwei Yu + * @date 2024/4/1 18:12 + */ +public class AddonInfo { + private ClusterInfo clusterInfo; + private List mdsInfos = new ArrayList<>(); + private List logicalPoolInfos = new ArrayList<>(); + + public ClusterInfo getClusterInfo() { + return clusterInfo; + } + + public void setClusterInfo(ClusterInfo clusterInfo) { + this.clusterInfo = clusterInfo; + } + + public List getMdsInfos() { + return mdsInfos; + } + + public void setMdsInfos(List mdsInfos) { + this.mdsInfos = mdsInfos; + } + + public List getLogicalPoolInfos() { + return logicalPoolInfos; + } + + public void setLogicalPoolInfos(List logicalPoolInfos) { + this.logicalPoolInfos = logicalPoolInfos; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/CbdConstants.java b/plugin/cbd/src/main/java/org/zstack/cbd/CbdConstants.java new file mode 100644 index 00000000000..4e96f6cf85b --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/CbdConstants.java @@ -0,0 +1,12 @@ +package org.zstack.cbd; + +import org.zstack.header.configuration.PythonClass; + +/** + * @author Xingwei Yu + * @date 2024/4/10 23:28 + */ +@PythonClass +public interface CbdConstants { + String MDS_PARAM_MDS_PORT = "mdsPort"; +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/ClusterInfo.java b/plugin/cbd/src/main/java/org/zstack/cbd/ClusterInfo.java new file mode 100644 index 00000000000..6907f7e7e0a --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/ClusterInfo.java @@ -0,0 +1,26 @@ +package org.zstack.cbd; + +/** + * @author Xingwei Yu + * @date 2025/8/8 14:03 + */ +public class ClusterInfo { + private String uuid; + private String version; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/Config.java b/plugin/cbd/src/main/java/org/zstack/cbd/Config.java new file mode 100644 index 00000000000..99a08cf62da --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/Config.java @@ -0,0 +1,28 @@ +package org.zstack.cbd; + +import java.util.List; + +/** + * @author Xingwei Yu + * @date 2024/4/2 11:13 + */ +public class Config { + private List mdsUrls; + private String logicalPoolName; + + public List getMdsUrls() { + return mdsUrls; + } + + public void setMdsUrls(List mdsUrls) { + this.mdsUrls = mdsUrls; + } + + public String getLogicalPoolName() { + return logicalPoolName; + } + + public void setLogicalPoolName(String logicalPoolName) { + this.logicalPoolName = logicalPoolName; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/LogicalPoolInfo.java b/plugin/cbd/src/main/java/org/zstack/cbd/LogicalPoolInfo.java new file mode 100644 index 00000000000..8725ca0aaa3 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/LogicalPoolInfo.java @@ -0,0 +1,173 @@ +package org.zstack.cbd; + +/** + * @author Xingwei Yu + * @date 2025/1/7 13:17 + */ +public class LogicalPoolInfo { + private long physicalPoolID; + private RedundanceAndPlaceMentPolicy redundanceAndPlaceMentPolicy; + private long logicalPoolID; + private long usedSize; + private long quota; + private long createTime; + private int type; + private long rawWalUsedSize; + private int allocateStatus; + private long rawUsedSize; + private String physicalPoolName; + private long capacity; + private String logicalPoolName; + private String userPolicy; + private long allocatedSize; + + public long getPhysicalPoolID() { + return physicalPoolID; + } + + public void setPhysicalPoolID(long physicalPoolID) { + this.physicalPoolID = physicalPoolID; + } + + public RedundanceAndPlaceMentPolicy getRedundanceAndPlaceMentPolicy() { + return redundanceAndPlaceMentPolicy; + } + + public void setRedundanceAndPlaceMentPolicy(RedundanceAndPlaceMentPolicy redundanceAndPlaceMentPolicy) { + this.redundanceAndPlaceMentPolicy = redundanceAndPlaceMentPolicy; + } + + public long getLogicalPoolID() { + return logicalPoolID; + } + + public void setLogicalPoolID(long logicalPoolID) { + this.logicalPoolID = logicalPoolID; + } + + public long getUsedSize() { + return usedSize; + } + + public void setUsedSize(long usedSize) { + this.usedSize = usedSize; + } + + public long getQuota() { + return quota; + } + + public void setQuota(long quota) { + this.quota = quota; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public long getRawWalUsedSize() { + return rawWalUsedSize; + } + + public void setRawWalUsedSize(long rawWalUsedSize) { + this.rawWalUsedSize = rawWalUsedSize; + } + + public int getAllocateStatus() { + return allocateStatus; + } + + public void setAllocateStatus(int allocateStatus) { + this.allocateStatus = allocateStatus; + } + + public long getRawUsedSize() { + return rawUsedSize; + } + + public void setRawUsedSize(long rawUsedSize) { + this.rawUsedSize = rawUsedSize; + } + + public String getPhysicalPoolName() { + return physicalPoolName; + } + + public void setPhysicalPoolName(String physicalPoolName) { + this.physicalPoolName = physicalPoolName; + } + + public long getCapacity() { + return capacity; + } + + public void setCapacity(long capacity) { + this.capacity = capacity; + } + + public String getLogicalPoolName() { + return logicalPoolName; + } + + public void setLogicalPoolName(String logicalPoolName) { + this.logicalPoolName = logicalPoolName; + } + + public String getUserPolicy() { + return userPolicy; + } + + public void setUserPolicy(String userPolicy) { + this.userPolicy = userPolicy; + } + + public long getAllocatedSize() { + return allocatedSize; + } + + public void setAllocatedSize(long allocatedSize) { + this.allocatedSize = allocatedSize; + } + + public static class RedundanceAndPlaceMentPolicy { + private int copysetNum; + private int replicaNum; + private int zoneNum; + + public int getCopysetNum() { + return copysetNum; + } + + public void setCopysetNum(int copysetNum) { + this.copysetNum = copysetNum; + } + + public int getReplicaNum() { + return replicaNum; + } + + public void setReplicaNum(int replicaNum) { + this.replicaNum = replicaNum; + } + + public int getZoneNum() { + return zoneNum; + } + + public void setZoneNum(int zoneNum) { + this.zoneNum = zoneNum; + } + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/MdsInfo.java b/plugin/cbd/src/main/java/org/zstack/cbd/MdsInfo.java new file mode 100644 index 00000000000..a41fff09303 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/MdsInfo.java @@ -0,0 +1,81 @@ +package org.zstack.cbd; + +import java.util.Objects; + +/** + * @author Xingwei Yu + * @date 2024/4/10 23:18 + */ +public class MdsInfo { + private String username; + private String password; + private int port = 22; + private String addr; + private String externalAddr; + private MdsStatus status; + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + + MdsInfo other = (MdsInfo) obj; + return Objects.equals(addr, other.addr) && + Objects.equals(port, other.port) && + Objects.equals(username, other.username) && + Objects.equals(password, other.password); + } + + @Override + public int hashCode() { + return Objects.hash(addr, port, username, password); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getAddr() { + return addr; + } + + public void setAddr(String addr) { + this.addr = addr; + } + + public String getExternalAddr() { + return externalAddr; + } + + public void setExternalAddr(String externalAddr) { + this.externalAddr = externalAddr; + } + + public MdsStatus getStatus() { + return status; + } + + public void setStatus(MdsStatus status) { + this.status = status; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/MdsStatus.java b/plugin/cbd/src/main/java/org/zstack/cbd/MdsStatus.java new file mode 100644 index 00000000000..7ed70af64c4 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/MdsStatus.java @@ -0,0 +1,11 @@ +package org.zstack.cbd; + +/** + * @author Xingwei Yu + * @date 2024/4/10 23:18 + */ +public enum MdsStatus { + Connecting, + Connected, + Disconnected +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/MdsUri.java b/plugin/cbd/src/main/java/org/zstack/cbd/MdsUri.java new file mode 100644 index 00000000000..9fef3451b01 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/MdsUri.java @@ -0,0 +1,139 @@ +package org.zstack.cbd; + +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URLEncodedUtils; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.exception.CloudRuntimeException; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import static org.zstack.core.Platform.argerr; +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.list; + +/** + * @author Xingwei Yu + * @date 2024/3/21 13:10 + */ +public class MdsUri { + private String hostname; + private int mdsPort = DEFAULT_MDS_PORT; + private int sshPort = DEFAULT_SSH_PORT; + private String username; + private String password; + + private static final String MDS_URL_FORMAT = "sshUsername:sshPassword@hostname:[sshPort]/?[mdsPort=]"; + private static final Integer DEFAULT_MDS_PORT = 6666; + private static final Integer DEFAULT_SSH_PORT = 22; + + private static List allowedQueryParameter; + static { + allowedQueryParameter = list(CbdConstants.MDS_PARAM_MDS_PORT); + } + + public static String getQueryValue(URI uri, String name) { + List params = URLEncodedUtils.parse(uri, "UTF-8"); + for (NameValuePair p : params) { + if (!allowedQueryParameter.contains(p.getName())) { + throw new CloudRuntimeException(String.format("unknown parameter[%s]", p.getName())); + } + + if (p.getName().equals(name)) { + return p.getValue(); + } + } + + return null; + } + + private ErrorCode errorCode(String err) { + return argerr(err); + } + + public MdsUri(String url) { + try { + int at = url.lastIndexOf("@"); + if (at == -1) { + throw new OperationFailureException(operr("invalid mdsUrl[%s], the sshUsername:sshPassword part is invalid. A valid mdsUrl is" + + " in format of %s", url, MDS_URL_FORMAT)); + } + + String userInfo = url.substring(0, at); + if (!userInfo.contains(":")) { + throw new OperationFailureException(operr("invalid mdsUrl[%s], the sshUsername:sshPassword part is invalid. A valid mdsUrl is" + + " in format of %s", url, MDS_URL_FORMAT)); + } + + String rest = url.substring(at+1); + String[] ssh = userInfo.split(":", 2); + if (ssh.length != 2 || ssh[0].isEmpty() || ssh[1].isEmpty()) { + throw new OperationFailureException(operr("invalid mdsUrl[%s]. SSH username and password must be separated by ':' and cannot be empty. A valid monUrl format is %s", url, MDS_URL_FORMAT)); + } + + username = ssh[0]; + password = ssh[1]; + + URI uri = new URI(String.format("ssh://%s", rest)); + hostname = uri.getHost(); + if (hostname == null) { + throw new OperationFailureException(operr("invalid mdsUrl[%s], hostname cannot be null. A valid mdsUrl is" + + " in format of %s", url, MDS_URL_FORMAT) + ); + } + + sshPort = uri.getPort() == -1 ? sshPort : uri.getPort(); + if (sshPort < 1 || sshPort > 65535) { + throw new OperationFailureException(operr("invalid mdsUrl[%s], the ssh port is greater than 65535 or smaller than 1. A valid mdsUrl is" + + " in format of %s", url, MDS_URL_FORMAT) + ); + } + String v = getQueryValue(uri, CbdConstants.MDS_PARAM_MDS_PORT); + mdsPort = v == null ? mdsPort : Integer.parseInt(v); + } catch (URISyntaxException e) { + throw new CloudRuntimeException(e); + } + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public int getMdsPort() { + return mdsPort; + } + + public void setMdsPort(int mdsPort) { + this.mdsPort = mdsPort; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getSshPort() { + return sshPort; + } + + public void setSshPort(int sshPort) { + this.sshPort = sshPort; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/kvm/CbdHeartbeatVolumeTO.java b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/CbdHeartbeatVolumeTO.java new file mode 100644 index 00000000000..9db0112ab35 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/CbdHeartbeatVolumeTO.java @@ -0,0 +1,13 @@ +package org.zstack.cbd.kvm; + +import org.zstack.header.storage.addon.primary.HeartbeatVolumeTO; + +/** + * @author Xingwei Yu + * @date 2024/4/10 10:42 + */ +public class CbdHeartbeatVolumeTO extends HeartbeatVolumeTO { + { + protocol = "cbd"; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/kvm/CbdVolumeTo.java b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/CbdVolumeTo.java new file mode 100644 index 00000000000..5daecd4a301 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/CbdVolumeTo.java @@ -0,0 +1,14 @@ +package org.zstack.cbd.kvm; + +import org.zstack.header.storage.addon.primary.ActiveVolumeTO; +import org.zstack.header.volume.VolumeProtocol; + +/** + * @author Xingwei Yu + * @date 2024/5/17 16:36 + */ +public class CbdVolumeTo extends ActiveVolumeTO { + { + protocol = VolumeProtocol.CBD.name(); + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/kvm/KvmCbdCommands.java b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/KvmCbdCommands.java new file mode 100644 index 00000000000..52653a0bc40 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/KvmCbdCommands.java @@ -0,0 +1,53 @@ +package org.zstack.cbd.kvm; + +import org.zstack.cbd.MdsInfo; +import org.zstack.kvm.KVMAgentCommands; + +import java.util.List; + +/** + * @author Xingwei Yu + * @date 2024/4/10 15:40 + */ +public class KvmCbdCommands { + public static final String SETUP_CBD_SELF_FENCER_PATH = "/ha/cbd/setupselffencer"; + public static final String CANCEL_CBD_SELF_FENCER_PATH = "/ha/cbd/cancelselffencer"; + public static final String CBD_CHECK_VMSTATE_PATH = "/cbd/check/vmstate"; + + public static class AgentRsp { + public boolean success = true; + public String error; + } + + public static class KvmUpdateClientConfCmd extends AgentCmd { + private List mdsInfos; + + public List getMdsInfos() { + return mdsInfos; + } + + public void setMdsInfos(List mdsInfos) { + this.mdsInfos = mdsInfos; + } + } + + public static class KvmSetupSelfFencerCmd extends AgentCmd { + public long interval; + public int maxAttempts; + public List coveringPaths; + public String heartbeatUrl; + public int storageCheckerTimeout; + public String hostUuid; + public Integer hostId; + public Long heartbeatRequiredSpace; + public String strategy; + public List fencers; + } + + public static class KvmCancelSelfFencerCmd extends AgentCmd { + } + + public static class AgentCmd extends KVMAgentCommands.AgentCommand { + public String uuid; + } +} diff --git a/plugin/cbd/src/main/java/org/zstack/cbd/kvm/KvmCbdNodeServer.java b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/KvmCbdNodeServer.java new file mode 100644 index 00000000000..006d7260547 --- /dev/null +++ b/plugin/cbd/src/main/java/org/zstack/cbd/kvm/KvmCbdNodeServer.java @@ -0,0 +1,223 @@ +package org.zstack.cbd.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.cbd.kvm.KvmCbdCommands.AgentRsp; +import org.zstack.cbd.kvm.KvmCbdCommands.KvmSetupSelfFencerCmd; +import org.zstack.cbd.kvm.KvmCbdCommands.KvmCancelSelfFencerCmd; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.header.Component; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.addon.primary.HeartbeatVolumeTO; +import org.zstack.header.storage.addon.primary.PrimaryStorageNodeSvc; +import org.zstack.header.storage.addon.primary.ExternalPrimaryStorageHostRefVO; +import org.zstack.header.storage.addon.primary.ExternalPrimaryStorageHostRefVO_; +import org.zstack.header.volume.VolumeProtocol; +import org.zstack.kvm.KVMAgentCommands; +import org.zstack.kvm.KVMHostAsyncHttpCallMsg; +import org.zstack.kvm.KVMHostAsyncHttpCallReply; +import org.zstack.kvm.KvmSetupSelfFencerExtensionPoint; +import org.zstack.storage.addon.primary.ExternalHostIdGetter; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; +import org.zstack.utils.DebugUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.Map; + +import static org.zstack.core.Platform.operr; + +/** + * @author Xingwei Yu + * @date 2024/4/9 16:22 + */ +public class KvmCbdNodeServer implements Component, KvmSetupSelfFencerExtensionPoint { + private static final CLogger logger = Utils.getLogger(KvmCbdNodeServer.class); + + @Autowired + private ExternalPrimaryStorageFactory extPsFactory; + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String kvmSetupSelfFencerStorageType() { + return VolumeProtocol.CBD.toString(); + } + + @Override + public void kvmSetupSelfFencer(KvmSetupSelfFencerParam param, Completion completion) { + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(param.getPrimaryStorage().getUuid()); + HostInventory host = HostInventory.valueOf(dbf.findByUuid(param.getHostUuid(), HostVO.class)); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("setup-self-fencer-for-external-primary-storage-%s-on-kvm-%s", param.getPrimaryStorage().getUuid(), host.getUuid())); + chain.then(new ShareFlow() { + HeartbeatVolumeTO heartbeatVol; + + @Override + public void setup() { + flow(new NoRollbackFlow() { + final String __name__ = "deploy-client"; + + @Override + public void run(FlowTrigger trigger, Map data) { + nodeSvc.deployClient(host, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + final String __name__ = "activate-cbd-heartbeat-volume"; + + @Override + public void run(FlowTrigger trigger, Map data) { + nodeSvc.activateHeartbeatVolume(host, new ReturnValueCompletion(trigger) { + @Override + public void success(HeartbeatVolumeTO returnValue) { + heartbeatVol = returnValue; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + final String __name__ = "setup-cbd-self-fencer-on-kvm"; + + @Override + public void run(FlowTrigger trigger, Map data) { + ExternalPrimaryStorageHostRefVO ref = Q.New(ExternalPrimaryStorageHostRefVO.class) + .eq(ExternalPrimaryStorageHostRefVO_.hostUuid, param.getHostUuid()) + .eq(ExternalPrimaryStorageHostRefVO_.primaryStorageUuid, param.getPrimaryStorage().getUuid()) + .find(); + if (ref == null || ref.getHostId() == 0) { + logger.warn(String.format("not found hostId for hostUuid[%s] and primaryStorageUuid[%s]", param.getHostUuid(), param.getPrimaryStorage().getUuid())); + ref = new ExternalHostIdGetter(999).getOrAllocateHostIdRef(param.getHostUuid(), param.getPrimaryStorage().getUuid()); + } + + KvmSetupSelfFencerCmd cmd = new KvmSetupSelfFencerCmd(); + cmd.interval = param.getInterval(); + cmd.maxAttempts = param.getMaxAttempts(); + cmd.coveringPaths = heartbeatVol.getCoveringPaths(); + cmd.heartbeatUrl = heartbeatVol.getInstallPath(); + cmd.storageCheckerTimeout = param.getStorageCheckerTimeout(); + cmd.heartbeatRequiredSpace = heartbeatVol.getHeartbeatRequiredSpace(); + cmd.hostUuid = param.getHostUuid(); + cmd.hostId = ref.getHostId(); + cmd.strategy = param.getStrategy(); + cmd.uuid = param.getPrimaryStorage().getUuid(); + cmd.fencers = param.getFencers(); + httpCall(KvmCbdCommands.SETUP_CBD_SELF_FENCER_PATH, param.getHostUuid(), cmd, true, AgentRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(AgentRsp returnValue) { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + @Override + public void kvmCancelSelfFencer(KvmCancelSelfFencerParam param, Completion completion) { + KvmCancelSelfFencerCmd cmd = new KvmCancelSelfFencerCmd(); + cmd.uuid = param.getPrimaryStorage().getUuid(); + httpCall(KvmCbdCommands.CANCEL_CBD_SELF_FENCER_PATH, param.getHostUuid(), cmd, true, AgentRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp rsp) { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + protected void httpCall(String path, final String hostUuid, KVMAgentCommands.AgentCommand cmd, final Class respType, final ReturnValueCompletion completion) { + httpCall(path, hostUuid, cmd, false, respType, completion); + } + + protected void httpCall(String path, final String hostUuid, KVMAgentCommands.AgentCommand cmd, boolean noCheckStatus, final Class respType, final ReturnValueCompletion completion) { + DebugUtils.Assert(hostUuid != null, "Host must be set here"); + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setPath(path); + msg.setNoStatusCheck(noCheckStatus); + msg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + KVMHostAsyncHttpCallReply rep = reply.castReply(); + final T rsp = rep.toResponse(respType); + if (!rsp.success) { + completion.fail(operr("operation error, because:%s", rsp.error)); + return; + } + completion.success(rsp); + } + }); + } +} diff --git a/plugin/ceph/pom.xml b/plugin/ceph/pom.xml index 5b00974b052..4bf8fde202f 100755 --- a/plugin/ceph/pom.xml +++ b/plugin/ceph/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java index 2ff084fe77b..5c0ca0c39d5 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephApiInterceptor.java @@ -63,8 +63,6 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIAddCephPrimaryStoragePoolMsg) msg); } else if (msg instanceof APIUpdateCephPrimaryStoragePoolMsg) { validate((APIUpdateCephPrimaryStoragePoolMsg) msg); - } else if (msg instanceof APIAttachPrimaryStorageToClusterMsg) { - validate((APIAttachPrimaryStorageToClusterMsg) msg); } return msg; @@ -254,22 +252,6 @@ private void validate(APIAddCephBackupStorageMsg msg) { checkExistingBackupStorage(msg.getMonUrls()); } - private void validate(APIAttachPrimaryStorageToClusterMsg msg) { - List existPSs = Q.New(PrimaryStorageClusterRefVO.class) - .eq(PrimaryStorageClusterRefVO_.clusterUuid, msg.getClusterUuid()) - .select(PrimaryStorageClusterRefVO_.primaryStorageUuid) - .listValues(); - - if (existPSs.isEmpty()) { - return; - } - - existPSs.add(msg.getPrimaryStorageUuid()); - if (existPSs.stream().anyMatch(v -> CephSystemTags.THIRDPARTY_PLATFORM.hasTag(v))) { - throw new ApiMessageInterceptionException(argerr("Third-party ceph cannot mixed with other primary storage.")); - } - } - @Override public List getMessageClassToIntercept() { return CollectionDSL.list(APIAttachPrimaryStorageToClusterMsg.class); diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephCapacity.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephCapacity.java index 13c596d9120..fb11015c51c 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephCapacity.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephCapacity.java @@ -3,6 +3,7 @@ import org.zstack.storage.ceph.backup.CephBackupStorageBase; import org.zstack.storage.ceph.primary.CephPrimaryStorageBase; +import java.util.ArrayList; import java.util.List; /** @@ -12,7 +13,7 @@ public class CephCapacity { private String fsid; private Long totalCapacity; private Long availableCapacity; - private List poolCapacities; + private final List poolCapacities = new ArrayList<>(); private String cephManufacturer; public CephCapacity() { @@ -23,7 +24,7 @@ public CephCapacity(String fsid, CephPrimaryStorageBase.AgentResponse rsp) { this.fsid = fsid; this.availableCapacity = rsp.getAvailableCapacity(); this.totalCapacity = rsp.getTotalCapacity(); - this.poolCapacities = rsp.getPoolCapacities(); + this.setPoolCapacities(rsp.getPoolCapacities()); this.cephManufacturer = rsp.getType(); } @@ -31,7 +32,7 @@ public CephCapacity(String fsid, CephBackupStorageBase.AgentResponse rsp) { this.fsid = fsid; this.availableCapacity = rsp.getAvailableCapacity(); this.totalCapacity = rsp.getTotalCapacity(); - this.poolCapacities = rsp.getPoolCapacities(); + this.setPoolCapacities(rsp.getPoolCapacities()); this.cephManufacturer = rsp.getType(); } @@ -56,7 +57,10 @@ public List getPoolCapacities() { } public void setPoolCapacities(List poolCapacities) { - this.poolCapacities = poolCapacities; + this.poolCapacities.clear(); + if (poolCapacities != null) { + this.poolCapacities.addAll(poolCapacities); + } } public boolean isXsky() { diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephConstants.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephConstants.java index 3a7f8437b9d..5eefb5fa45f 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephConstants.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephConstants.java @@ -30,4 +30,7 @@ public interface CephConstants { String CEPH_MANUFACTURER_XSKY = "xsky"; String CEPH_MANUFACTURER_SANDSTONE = "sandstone"; String CEPH_MANUFACTURER_OPENSOURCE = "open-source"; + String CEPH_MANUFACTURER_ZSTONE = "zstone"; + + String CEPH_ISCSI_PATH_PREFIX = "iscsi://"; } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java index 9e44eb2b430..c3a42f79013 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalConfig.java @@ -26,6 +26,10 @@ public class CephGlobalConfig { public static GlobalConfig BACKUP_STORAGE_MON_AUTO_RECONNECT = new GlobalConfig(CATEGORY, "backupStorage.mon.autoReconnect"); @GlobalConfigValidation public static GlobalConfig GC_INTERVAL = new GlobalConfig(CATEGORY, "deletion.gcInterval"); + @GlobalConfigValidation(numberGreaterThan = 1) + public static GlobalConfig TRASH_CLEANUP_INTERVAL = new GlobalConfig(CATEGORY, "trash.cleanup.interval"); + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig IMAGE_EXPIRATION_TIME = new GlobalConfig(CATEGORY, "image.expiration.time"); @GlobalConfigValidation public static GlobalConfig CEPH_BS_ALLOW_PORTS = new GlobalConfig(CATEGORY, "cephbs.allow.ports"); @GlobalConfigValidation diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalProperty.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalProperty.java index 627706ff640..4219f67cc33 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalProperty.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephGlobalProperty.java @@ -18,13 +18,13 @@ public class CephGlobalProperty { public static String PRIMARY_STORAGE_AGENT_URL_ROOT_PATH; @GlobalProperty(name="Ceph.primaryStorageAgent.port", defaultValue = "7762") public static int PRIMARY_STORAGE_AGENT_PORT; - @GlobalProperty(name="Ceph.backupStorage.agentPackageName", defaultValue = "cephbackupstorage-4.4.0.tar.gz") + @GlobalProperty(name="Ceph.backupStorage.agentPackageName", defaultValue = "cephbackupstorage-5.4.0.tar.gz") public static String BACKUP_STORAGE_PACKAGE_NAME; @GlobalProperty(name="Ceph.backupStorage.ansiblePlaybook", defaultValue = "cephb.py") public static String BACKUP_STORAGE_PLAYBOOK_NAME; @GlobalProperty(name="Ceph.backupStorage.ansibleModulePath", defaultValue = "ansible/cephb") public static String BACKUP_STORAGE_MODULE_PATH; - @GlobalProperty(name="Ceph.primaryStorage.agentPackageName", defaultValue = "cephprimarystorage-4.4.0.tar.gz") + @GlobalProperty(name="Ceph.primaryStorage.agentPackageName", defaultValue = "cephprimarystorage-5.4.0.tar.gz") public static String PRIMARY_STORAGE_PACKAGE_NAME; @GlobalProperty(name="Ceph.primaryStorage.ansiblePlaybook", defaultValue = "cephp.py") public static String PRIMARY_STORAGE_PLAYBOOK_NAME; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonAO.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonAO.java index 0f67ea3ba5c..fe1f41b8303 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonAO.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonAO.java @@ -1,6 +1,7 @@ package org.zstack.storage.ceph; import org.zstack.core.convert.PasswordConverter; +import org.zstack.header.core.encrypt.EncryptColumn; import org.zstack.header.vo.ResourceVO; import javax.persistence.*; @@ -14,6 +15,7 @@ public class CephMonAO extends ResourceVO { @Column private String sshUsername; + @EncryptColumn @Column @Convert(converter = PasswordConverter.class) private String sshPassword; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonBase.java index 724fb597e20..dca3dce6f48 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonBase.java @@ -77,11 +77,11 @@ protected void checkHealth() { } } - public void httpCall(final String path, final Object cmd, final Class retClass, final ReturnValueCompletion completion) { + public void httpCall(final String path, final Object cmd, final Class retClass, final ReturnValueCompletion completion) { httpCall(path, cmd, retClass, completion, null, 0); } - public void httpCall(final String path, final Object cmd, final Class retClass, final ReturnValueCompletion completion, TimeUnit unit, long timeout) { + public void httpCall(final String path, final Object cmd, final Class retClass, final ReturnValueCompletion completion, TimeUnit unit, long timeout) { JsonAsyncRESTCallback callback = new JsonAsyncRESTCallback(completion) { @Override public void fail(ErrorCode err) { @@ -90,6 +90,11 @@ public void fail(ErrorCode err) { @Override public void success(T ret) { + ErrorCode errorCode = ret.buildErrorCode(); + if (errorCode != null) { + completion.fail(errorCode); + return; + } completion.success(ret); } @@ -106,18 +111,21 @@ public Class getReturnClass() { } } - private static class AgentResponse { - String error; - boolean success = true; + public static class AgentResponse { + private String error; + @Deprecated + private boolean success = true; public String getError() { return error; } public void setError(String error) { + this.success = false; this.error = error; } + @Deprecated public boolean isSuccess() { return success; } @@ -125,6 +133,13 @@ public boolean isSuccess() { public void setSuccess(boolean success) { this.success = success; } + + public ErrorCode buildErrorCode() { + if (success) { + return null; + } + return operr("operation error, because:%s", error); + } } public void httpCall(final String path, final Object cmd, final Completion completion) { diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonSystemTags.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonSystemTags.java new file mode 100644 index 00000000000..a06013da505 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephMonSystemTags.java @@ -0,0 +1,12 @@ +package org.zstack.storage.ceph; + +import org.zstack.header.tag.TagDefinition; +import org.zstack.storage.ceph.primary.CephPrimaryStorageMonVO; +import org.zstack.tag.PatternedSystemTag; + +@TagDefinition +public class CephMonSystemTags { + public static String EXTRA_IPS_TOKEN = "extraips"; + public static PatternedSystemTag EXTRA_IPS = + new PatternedSystemTag(String.format("extraips::{%s}", EXTRA_IPS_TOKEN), CephPrimaryStorageMonVO.class); +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephPoolCapacity.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephPoolCapacity.java index 63e8d3bf399..2838aa1567d 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephPoolCapacity.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephPoolCapacity.java @@ -1,5 +1,7 @@ package org.zstack.storage.ceph; +import java.util.Map; + /** * Created by lining on 2018/4/1. */ @@ -11,6 +13,61 @@ public class CephPoolCapacity { Long availableCapacity; Long usedCapacity; Long totalCapacity; + String relatedOsds; + Map relatedOsdCapacity; + + public static class OsdCapacity { + Long availableCapacity; + Long usedCapacity; + Long size; + + public OsdCapacity(){} + public OsdCapacity(Long availableCapacity, Long usedCapacity, Long size) { + this.availableCapacity = availableCapacity; + this.usedCapacity = usedCapacity; + this.size = size; + } + + public Long getAvailableCapacity() { + return availableCapacity; + } + + public void setAvailableCapacity(Long availableCapacity) { + this.availableCapacity = availableCapacity; + } + + public Long getUsedCapacity() { + return usedCapacity; + } + + public void setUsedCapacity(Long usedCapacity) { + this.usedCapacity = usedCapacity; + } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } + } + + public Map getRelatedOsdCapacity() { + return relatedOsdCapacity; + } + + public void setRelatedOsdCapacity(Map relatedOsdCapacity) { + this.relatedOsdCapacity = relatedOsdCapacity; + } + + public String getRelatedOsds() { + return relatedOsds; + } + + public void setRelatedOsds(String relatedOsds) { + this.relatedOsds = relatedOsds; + } public String getName() { return name; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephSystemTags.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephSystemTags.java index 0b815b901d7..4a19224437f 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephSystemTags.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/CephSystemTags.java @@ -46,4 +46,7 @@ public class CephSystemTags { public static final String THIRDPARTY_PLATFORM_TOKEN = "thirdPartyPlatformToken"; public static PatternedSystemTag THIRDPARTY_PLATFORM = new PatternedSystemTag(String.format("ceph::thirdPartyPlatform::{%s}", THIRDPARTY_PLATFORM_TOKEN), PrimaryStorageVO.class); + + public static final String CUSTOM_INITIALIZATION_POOL_NAME_TOKEN= "customInitializationPoolNameToken"; + public static PatternedSystemTag CUSTOM_INITIALIZATION_POOL_NAME = new PatternedSystemTag(String.format("ceph::customInitializationPoolName::{%s}", CUSTOM_INITIALIZATION_POOL_NAME_TOKEN), PrimaryStorageVO.class); } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/MonUri.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/MonUri.java index c15efe2cc76..b60166d657c 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/MonUri.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/MonUri.java @@ -11,6 +11,7 @@ import java.util.List; import static org.zstack.core.Platform.argerr; +import static org.zstack.core.Platform.operr; import static org.zstack.utils.CollectionDSL.list; /** @@ -62,36 +63,38 @@ public MonUri(String url) { try { int at = url.lastIndexOf("@"); if (at == -1) { - throw new OperationFailureException(errorCode(String.format("invalid monUrl[%s], the sshUsername:sshPassword part is invalid. A valid monUrl is" + - " in format of %s", url, MON_URL_FORMAT))); + throw new OperationFailureException(operr("invalid monUrl[%s], the sshUsername:sshPassword part is invalid. A valid monUrl is" + + " in format of %s", url, MON_URL_FORMAT)); } String userInfo = url.substring(0, at); if (!userInfo.contains(":")) { - throw new OperationFailureException(errorCode(String.format("invalid monUrl[%s], the sshUsername:sshPassword part is invalid. A valid monUrl is" + - " in format of %s", url, MON_URL_FORMAT))); + throw new OperationFailureException(operr("invalid monUrl[%s], the sshUsername:sshPassword part is invalid. A valid monUrl is" + + " in format of %s", url, MON_URL_FORMAT)); + } + + String rest = url.substring(at+1); + String[] ssh = userInfo.split(":", 2); + if (ssh.length != 2 || ssh[0].isEmpty() || ssh[1].isEmpty()) { + throw new OperationFailureException(operr("invalid monUrl[%s]. SSH username and password must be separated by ':' and cannot be empty. A valid monUrl format is %s", url, MON_URL_FORMAT)); } - String rest = url.substring(at+1, url.length()); - String[] ssh = userInfo.split(":"); sshUsername = ssh[0]; sshPassword = ssh[1]; URI uri = new URI(String.format("ssh://%s", rest)); hostname = uri.getHost(); if (hostname == null) { - throw new OperationFailureException(errorCode( - String.format("invalid monUrl[%s], hostname cannot be null. A valid monUrl is" + + throw new OperationFailureException(operr("invalid monUrl[%s], hostname cannot be null. A valid monUrl is" + " in format of %s", url, MON_URL_FORMAT) - )); + ); } sshPort = uri.getPort() == -1 ? sshPort : uri.getPort(); if (sshPort < 1 || sshPort > 65535) { - throw new OperationFailureException(errorCode( - String.format("invalid monUrl[%s], the ssh port is greater than 65535 or smaller than 1. A valid monUrl is" + + throw new OperationFailureException(operr("invalid monUrl[%s], the ssh port is greater than 65535 or smaller than 1. A valid monUrl is" + " in format of %s", url, MON_URL_FORMAT) - )); + ); } String v = getQueryValue(uri, CephConstants.MON_PARAM_MON_PORT); monPort = v == null ? monPort : Integer.parseInt(v); diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/PackageInfo.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/PackageInfo.java index 4715dec255a..024c5d7ff52 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/PackageInfo.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "CEPH分布式存储") +@PackageAPIInfo( + APICategoryName = "CEPH分布式存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddCephBackupStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddCephBackupStorageMsgDoc_zh_cn.groovy index 73921f40fe7..e7c98871102 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddCephBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddCephBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "poolName" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "importImages" @@ -89,7 +83,6 @@ doc { type "boolean" optional true since "1.9" - } column { name "resourceUuid" @@ -99,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +101,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +110,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddMonToCephBackupStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddMonToCephBackupStorageMsgDoc_zh_cn.groovy index 16dfa631bd8..4b9c9156a34 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddMonToCephBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIAddMonToCephBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "monUrls" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIQueryCephBackupStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIQueryCephBackupStorageMsgDoc_zh_cn.groovy index c3625906500..072abe9bc2a 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIQueryCephBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIQueryCephBackupStorageMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.storage.ceph.backup import org.zstack.header.storage.backup.APIQueryBackupStorageReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询 Ceph 镜像服务器(QueryCephBackupStorage)" diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIRemoveMonFromCephBackupStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIRemoveMonFromCephBackupStorageMsgDoc_zh_cn.groovy index b448821c5f9..7df66d85e85 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIRemoveMonFromCephBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIRemoveMonFromCephBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "monHostnames" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIUpdateCephBackupStorageMonMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIUpdateCephBackupStorageMonMsgDoc_zh_cn.groovy index 0d50e3cee0a..65f502e051b 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIUpdateCephBackupStorageMonMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/APIUpdateCephBackupStorageMonMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "hostname" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshUsername" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshPassword" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshPort" @@ -69,7 +65,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "monPort" @@ -79,7 +74,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackStorageHelper.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackStorageHelper.java new file mode 100644 index 00000000000..1328fce533a --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackStorageHelper.java @@ -0,0 +1,13 @@ +package org.zstack.storage.ceph.backup; + +import org.zstack.header.image.ImageHelper; + +public class CephBackStorageHelper { + + public static class CephBackStorageExportUrl extends ImageHelper.ExportUrl { + @Override + public String removeNameFromExportUrl(String exportUrl) { + return exportUrl; + } + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java index 717e2478c0c..9dba4c22ad4 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageBase.java @@ -18,20 +18,18 @@ import org.zstack.core.thread.AsyncThread; import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.SyncThread; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.Constants; import org.zstack.header.HasThreadContext; -import org.zstack.header.core.AsyncLatch; -import org.zstack.header.core.Completion; -import org.zstack.header.core.NoErrorCompletion; -import org.zstack.header.core.WhileDoneCompletion; -import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.*; import org.zstack.header.core.progress.TaskProgressRange; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.image.*; import org.zstack.header.log.NoLogging; @@ -61,8 +59,10 @@ import java.util.concurrent.atomic.AtomicBoolean; import static org.zstack.core.Platform.operr; -import static org.zstack.core.progress.ProgressReportService.*; +import static org.zstack.core.progress.ProgressReportService.getTaskStage; import static org.zstack.core.progress.ProgressReportService.reportProgress; +import static org.zstack.header.storage.backup.BackupStorageConstant.IMPORT_IMAGES_FAKE_RESOURCE_UUID; +import static org.zstack.header.storage.backup.BackupStorageConstant.RESTORE_IMAGES_BACKUP_STORAGE_METADATA_TO_DATABASE; import static org.zstack.utils.CollectionDSL.list; /** @@ -120,9 +120,7 @@ public void setUuid(String uuid) { } } - public static class AgentResponse { - String error; - boolean success = true; + public static class AgentResponse extends CephMonBase.AgentResponse { Long totalCapacity; Long availableCapacity; List poolCapacities; @@ -136,23 +134,6 @@ public AgentResponse() { } } - public String getError() { - return error; - } - - public void setError(String error) { - this.success = false; - this.error = error; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - public Long getTotalCapacity() { return totalCapacity; } @@ -784,8 +765,7 @@ private List prepareMons() { private void doCall() { if (!it.hasNext()) { - callback.fail(operr("all mons failed to execute http call[%s], errors are %s", - path, JSONObjectUtil.toJsonString(errorCodes))); + callback.fail(operr("all monitors cannot execute http call[%s]", path)); return; } @@ -795,15 +775,6 @@ private void doCall() { ReturnValueCompletion completion = new ReturnValueCompletion(callback) { @Override public void success(T ret) { - if (!ret.success) { - if (tryNext) { - doCall(); - } else { - callback.fail(operr("operation error, because:%s", ret.error)); - } - return; - } - if (!(cmd instanceof InitCmd)) { updateCapacityIfNeeded(ret); } @@ -814,10 +785,19 @@ public void success(T ret) { @Override public void fail(ErrorCode errorCode) { - String details = String.format("[mon:%s], %s", base.getSelf().getHostname(), errorCode.getDetails()); - errorCode.setDetails(details); - errorCodes.add(errorCode); - doCall(); + if (!errorCode.isError(SysErrors.OPERATION_ERROR)) { + String details = String.format("[mon:%s], %s", base.getSelf().getHostname(), errorCode.getDetails()); + errorCode.setDetails(details); + errorCodes.add(errorCode); + doCall(); + return; + } + + if (tryNext) { + doCall(); + } else { + callback.fail(errorCode); + } } }; @@ -893,19 +873,15 @@ protected void handle(final GetImageDownloadProgressMsg msg) { new CephBackupStorageMonBase(monvo).httpCall(GET_DOWNLOAD_PROGRESS_PATH, cmd, GetDownloadProgressRsp.class, new ReturnValueCompletion(msg) { @Override public void success(GetDownloadProgressRsp resp) { - if (resp.isSuccess()) { - r.setCompleted(resp.isCompleted()); - r.setProgress(resp.getProgress()); - r.setActualSize(resp.getActualSize()); - r.setSize(resp.getSize()); - r.setInstallPath(resp.getInstallPath()); - r.setFormat(resp.getFormat()); - r.setDownloadSize(resp.getDownloadSize()); - r.setLastOpTime(resp.getLastOpTime()); - r.setSupportSuspend(true); - } else { - r.setError(operr("operation error, because:%s", resp.getError())); - } + r.setCompleted(resp.isCompleted()); + r.setProgress(resp.getProgress()); + r.setActualSize(resp.getActualSize()); + r.setSize(resp.getSize()); + r.setInstallPath(resp.getInstallPath()); + r.setFormat(resp.getFormat()); + r.setDownloadSize(resp.getDownloadSize()); + r.setLastOpTime(resp.getLastOpTime()); + r.setSupportSuspend(true); bus.reply(msg, r); } @@ -956,7 +932,13 @@ public void fail(ErrorCode err) { public void success(GetImagesMetaDataRsp ret) { logger.error(String.format("get images metadata: %s successfully", ret.getImagesMetadata())); reply.setImagesMetadata(ret.getImagesMetadata()); - metaDataMaker.restoreImagesBackupStorageMetadataToDatabase(ret.getImagesMetadata(), msg.getBackupStorageUuid()); + + RestoreImagesBackupStorageMetadataToDatabaseMsg rmsg = new RestoreImagesBackupStorageMetadataToDatabaseMsg(); + rmsg.setImagesMetadata(ret.getImagesMetadata()); + rmsg.setBackupStorageUuid(msg.getBackupStorageUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, BackupStorageConstant.SERVICE_ID, IMPORT_IMAGES_FAKE_RESOURCE_UUID); + bus.send(rmsg); + bus.reply(msg, reply); chain.next(); } @@ -1243,7 +1225,8 @@ protected void handle(GetLocalFileSizeOnBackupStorageMsg msg) { GetLocalFileSizeOnBackupStorageReply reply = new GetLocalFileSizeOnBackupStorageReply(); GetLocalFileSizeCmd cmd = new GetLocalFileSizeCmd(); cmd.path = msg.getUrl(); - httpCall(GET_LOCAL_FILE_SIZE, cmd, GetLocalFileSizeRsp.class, new ReturnValueCompletion(msg) { + String apiId = ThreadContext.get(Constants.THREAD_CONTEXT_API); + new HttpCaller<>(GET_LOCAL_FILE_SIZE, cmd, GetLocalFileSizeRsp.class, new ReturnValueCompletion(msg) { @Override public void fail(ErrorCode err) { reply.setError(err); @@ -1255,7 +1238,7 @@ public void success(GetLocalFileSizeRsp ret) { reply.setSize(ret.size); bus.reply(msg, reply); } - }); + }).tryNext().specifyOrder(apiId).call(); } @Override @@ -1282,14 +1265,14 @@ public CephBackupStorageMonBase call(CephBackupStorageMonVO arg) { }); class Connector { - List errorCodes = new ArrayList(); + private ErrorCodeList errorCodes = new ErrorCodeList(); Iterator it = mons.iterator(); void connect(final FlowTrigger trigger) { if (!it.hasNext()) { - if (errorCodes.size() == mons.size()) { - trigger.fail(operr("unable to connect to the ceph backup storage[uuid:%s]. Failed to connect all ceph mons. Errors are %s", - self.getUuid(), JSONObjectUtil.toJsonString(errorCodes))); + if (errorCodes.getCauses().size() == mons.size()) { + trigger.fail(operr(errorCodes, "unable to connect to the ceph backup storage[uuid:%s], failed to connect all ceph monitors.", + self.getUuid())); } else { // reload because mon status changed self = dbf.reload(self); @@ -1307,7 +1290,7 @@ public void success() { @Override public void fail(ErrorCode errorCode) { - errorCodes.add(errorCode); + errorCodes.getCauses().add(errorCode); if (newAdded) { // the mon fails to connect, remove it @@ -1358,13 +1341,6 @@ public CephBackupStorageMonBase call(CephBackupStorageMonVO arg) { mon.httpCall(GET_FACTS, cmd, GetFactsRsp.class, new ReturnValueCompletion(coml) { @Override public void success(GetFactsRsp rsp) { - if (!rsp.success) { - // one mon cannot get the facts, directly error out - errs.add(operr("operation error, because:%s", rsp.error)); - coml.allDone(); - return; - } - CephBackupStorageMonVO monVO = mon.getSelf(); fsids.put(monVO.getUuid(), rsp.fsid); monVO.setMonAddr(rsp.monAddr == null ? monVO.getHostname() : rsp.monAddr); @@ -1374,9 +1350,8 @@ public void success(GetFactsRsp rsp) { @Override public void fail(ErrorCode errorCode) { - // one mon cannot get the facts, directly error out errs.add(errorCode); - coml.allDone(); + coml.done(); } }); }).run(new WhileDoneCompletion(trigger) { @@ -1565,6 +1540,7 @@ public void done() { TimeUnit.SECONDS.sleep(CephGlobalConfig.BACKUP_STORAGE_MON_RECONNECT_DELAY.value(Long.class)); } catch (InterruptedException e) { e.printStackTrace(); + Thread.currentThread().interrupt(); } } @@ -1587,6 +1563,7 @@ public void fail(ErrorCode errorCode) { } catch (Throwable t) { releaseLock.done(); logger.warn(t.getMessage(), t); + Thread.currentThread().interrupt(); } } @@ -1752,6 +1729,7 @@ private void handle(APIExportImageFromBackupStorageMsg msg) { emsg.setBackupStorageUuid(msg.getBackupStorageUuid()); emsg.setImageUuid(msg.getImageUuid()); emsg.setExportFormat(msg.getExportFormat()); + emsg.setImageName(Q.New(ImageVO.class).select(ImageVO_.name).eq(ImageVO_.uuid, msg.getImageUuid()).findValue()); bus.send(emsg, new CloudBusCallBack(msg) { @Override @@ -1797,13 +1775,15 @@ protected void exportImage(ExportImageFromBackupStorageMsg msg) { @Override public void success(AddImageExportTokenRsp rsp) { String url = buildUrl(rsp.handleMon.getHostname(), cmd.token); + String imageName = Q.New(ImageVO.class).select(ImageVO_.name).eq(ImageVO_.uuid, msg.getImageUuid()).findValue(); + String exportUrl = CephBackStorageHelper.CephBackStorageExportUrl.addNameToExportUrl(url, imageName); SQL.New(ImageBackupStorageRefVO.class).eq(ImageBackupStorageRefVO_.imageUuid, msg.getImageUuid()) .eq(ImageBackupStorageRefVO_.backupStorageUuid, msg.getBackupStorageUuid()) - .set(ImageBackupStorageRefVO_.exportUrl, url) + .set(ImageBackupStorageRefVO_.exportUrl, exportUrl) .set(ImageBackupStorageRefVO_.exportMd5Sum, rsp.md5sum) .update(); - reply.setImageUrl(url); + reply.setImageUrl(exportUrl); reply.setMd5sum(rsp.md5sum); reportProgress(parentStage.getEnd().toString()); bus.reply(msg, reply); @@ -1974,14 +1954,10 @@ public void done() { base.httpCall(GET_FACTS, cmd, GetFactsRsp.class, new ReturnValueCompletion(latch) { @Override public void success(GetFactsRsp rsp) { - if (!rsp.isSuccess()) { - errors.add(operr("operation error, because:%s", rsp.getError())); - } else { - String fsid = rsp.fsid; - if (!getSelf().getFsid().equals(fsid)) { - errors.add(operr("the mon[ip:%s] returns a fsid[%s] different from the current fsid[%s] of the cep cluster," + - "are you adding a mon not belonging to current cluster mistakenly?", base.getSelf().getHostname(), fsid, getSelf().getFsid())); - } + String fsid = rsp.fsid; + if (!getSelf().getFsid().equals(fsid)) { + errors.add(operr("the mon[ip:%s] returns a fsid[%s] different from the current fsid[%s] of the cep cluster," + + "are you adding a mon not belonging to current cluster mistakenly?", base.getSelf().getHostname(), fsid, getSelf().getFsid())); } CephBackupStorageMonVO monVO = base.getSelf(); @@ -2058,4 +2034,23 @@ protected void scripts() { dbf.removeCollection(getSelf().getMons(), CephBackupStorageMonVO.class); } + + @Override + protected void handle(RestoreImagesBackupStorageMetadataToDatabaseMsg msg) { + RestoreImagesBackupStorageMetadataToDatabaseReply reply = new RestoreImagesBackupStorageMetadataToDatabaseReply(); + doRestoreImagesBackupStorageMetadataToDatabase(msg); + bus.reply(msg, reply); + } + + @Override + protected void handle(CalculateImageHashOnBackupStorageMsg msg) { + CalculateImageHashOnBackupStorageReply reply = new CalculateImageHashOnBackupStorageReply(); + reply.setError(operr("ceph backup storage do not support calculate image hash")); + bus.reply(msg, reply); + } + + @SyncThread(signature = RESTORE_IMAGES_BACKUP_STORAGE_METADATA_TO_DATABASE) + private void doRestoreImagesBackupStorageMetadataToDatabase(RestoreImagesBackupStorageMetadataToDatabaseMsg msg) { + metaDataMaker.restoreImagesBackupStorageMetadataToDatabase(msg.getImagesMetadata(), msg.getBackupStorageUuid()); + } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageDeployArguments.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageDeployArguments.java new file mode 100644 index 00000000000..3ff722bd976 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageDeployArguments.java @@ -0,0 +1,15 @@ +package org.zstack.storage.ceph.backup; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; +import org.zstack.storage.ceph.CephGlobalProperty; + +public class CephBackupStorageDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_cephbagent") + private final String packageName = CephGlobalProperty.BACKUP_STORAGE_PACKAGE_NAME; + + @Override + public String getPackageName() { + return packageName; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageFactory.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageFactory.java index 0a392ad9535..4e30d6bf998 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageFactory.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageFactory.java @@ -116,22 +116,28 @@ public void update(CephCapacity cephCapacity) { vo.setTotalCapacity(total); vo.setAvailableCapacity(avail); - if (poolCapacities != null) { - if (poolCapacities.stream().anyMatch((e) -> vo.getPoolName().equals(e.getName()))) { - CephPoolCapacity poolCapacity = poolCapacities.stream() - .filter(e -> vo.getPoolName().equals(e.getName())) - .findAny().get(); - - if (enterpriseCeph) { - vo.setTotalCapacity(poolCapacity.getTotalCapacity()); - vo.setAvailableCapacity(poolCapacity.getAvailableCapacity()); + if (poolCapacities != null && poolCapacities.stream().anyMatch((e) -> vo.getPoolName().equals(e.getName()))) { + CephPoolCapacity poolCapacity = poolCapacities.stream() + .filter(e -> vo.getPoolName().equals(e.getName())) + .findAny().get(); + if (poolCapacity.getRelatedOsdCapacity() != null) { + total = 0; + avail = 0; + for (String osdName : poolCapacity.getRelatedOsdCapacity().keySet()) { + total += poolCapacity.getRelatedOsdCapacity().get(osdName).getSize() * poolCapacity.getDiskUtilization(); + avail += poolCapacity.getRelatedOsdCapacity().get(osdName).getAvailableCapacity() * poolCapacity.getDiskUtilization(); } - vo.setPoolAvailableCapacity(poolCapacity.getAvailableCapacity()); - vo.setPoolReplicatedSize(poolCapacity.getReplicatedSize()); - vo.setPoolUsedCapacity(poolCapacity.getUsedCapacity()); - vo.setPoolSecurityPolicy(poolCapacity.getSecurityPolicy()); - vo.setPoolDiskUtilization(poolCapacity.getDiskUtilization()); + vo.setTotalCapacity(total); + vo.setAvailableCapacity(avail); + } else { + vo.setTotalCapacity(poolCapacity.getTotalCapacity()); + vo.setAvailableCapacity(poolCapacity.getAvailableCapacity()); } + vo.setPoolAvailableCapacity(poolCapacity.getAvailableCapacity()); + vo.setPoolReplicatedSize(poolCapacity.getReplicatedSize()); + vo.setPoolUsedCapacity(poolCapacity.getUsedCapacity()); + vo.setPoolSecurityPolicy(poolCapacity.getSecurityPolicy()); + vo.setPoolDiskUtilization(poolCapacity.getDiskUtilization()); } dbf.getEntityManager().merge(vo); diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMetaDataMaker.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMetaDataMaker.java index d853cdac666..2b346280ce9 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMetaDataMaker.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMetaDataMaker.java @@ -108,7 +108,7 @@ protected String getBackupStorageUuidFromImageInventory(ImageInventory img) { return backupStorageUuid; } - protected void restoreImagesBackupStorageMetadataToDatabase(String imagesMetadata, String backupStorageUuid) { + public void restoreImagesBackupStorageMetadataToDatabase(String imagesMetadata, String backupStorageUuid) { List imageVOs = new ArrayList(); List backupStorageRefVOs = new ArrayList(); List systemTagVOs = new ArrayList<>(); @@ -116,6 +116,7 @@ protected void restoreImagesBackupStorageMetadataToDatabase(String imagesMetada for ( String metadata : metadatas) { if (metadata.contains("backupStorageRefs")) { ImageInventory imageInventory = JSONObjectUtil.toObject(metadata, ImageInventory.class); + ImageHelper.updateImageIfVirtioIsNull(imageInventory); if (!imageInventory.getStatus().equals(ImageStatus.Ready.toString()) || imageVOs.stream().anyMatch(image -> image.getUuid().equals(imageInventory.getUuid()))) { @@ -155,7 +156,10 @@ protected void restoreImagesBackupStorageMetadataToDatabase(String imagesMetada imageVO.setMd5Sum(imageInventory.getMd5Sum()); imageVO.setMediaType(ImageConstant.ImageMediaType.valueOf(imageInventory.getMediaType())); imageVO.setName(imageInventory.getName()); - imageVO.setPlatform(ImagePlatform.valueOf(imageInventory.getPlatform())); + if (imageInventory.getPlatform() != null) { + imageVO.setPlatform(ImagePlatform.valueOf(imageInventory.getPlatform())); + } + imageVO.setArchitecture(imageInventory.getArchitecture()); imageVO.setSize(imageInventory.getSize()); imageVO.setState(ImageState.valueOf(imageInventory.getState())); imageVO.setSystem(imageInventory.isSystem()); @@ -221,9 +225,8 @@ protected Integer getMonPortFromImageInventory(ImageInventory img) { protected String getBackupStorageTypeFromImageInventory(ImageInventory img) { String sql = "select bs.type from BackupStorageVO bs, ImageBackupStorageRefVO refVo where " + "bs.uuid = refVo.backupStorageUuid and refVo.imageUuid = :uuid"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); - q.setParameter("uuid", img.getUuid()); - return q.getSingleResult(); + + return SQL.New(sql, String.class).param("uuid", img.getUuid()).find(); } protected void dumpImagesBackupStorageInfoToMetaDataFile(ImageInventory img, boolean allImagesInfo, String hostName, String bsUuid ) { @@ -306,7 +309,7 @@ public void run(MessageReply reply) { @Override public void afterAddImage(ImageInventory img) { - if (!getBackupStorageTypeFromImageInventory(img).equals(CephConstants.CEPH_BACKUP_STORAGE_TYPE)) { + if (!CephConstants.CEPH_BACKUP_STORAGE_TYPE.equals(getBackupStorageTypeFromImageInventory(img))) { return; } @@ -410,7 +413,7 @@ public void failedToExpungeImage(ImageInventory img, ErrorCode err) { @Override public void afterCreateTemplate(ImageInventory inv) { - if (!getBackupStorageTypeFromImageInventory(inv).equals(CephConstants.CEPH_BACKUP_STORAGE_TYPE)) { + if (!CephConstants.CEPH_BACKUP_STORAGE_TYPE.equals(getBackupStorageTypeFromImageInventory(inv))) { return; } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java index 21b7cf55411..bcdb5453f3c 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageMonBase.java @@ -26,7 +26,6 @@ import org.zstack.header.rest.JsonAsyncRESTCallback; import org.zstack.storage.backup.BackupStorageGlobalConfig; import org.zstack.storage.ceph.*; -import org.zstack.storage.ceph.backup.CephBackupStorageBase.PingOperationFailure; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.path.PathUtil; @@ -36,6 +35,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; import static org.zstack.core.Platform.operr; @@ -60,6 +60,8 @@ public class CephBackupStorageMonBase extends CephMonBase { public static final String ECHO_PATH = "/ceph/backupstorage/echo"; public static final String PING_PATH = "/ceph/backupstorage/ping"; + public static final String CONNECT_PATH = "/ceph/backupstorage/connect"; + public static final String EXPORT = "/ceph/export"; public static class AgentCmd { @@ -67,9 +69,7 @@ public static class AgentCmd { public String backupStorageUuid; } - public static class AgentRsp { - public boolean success; - public String error; + public static class AgentRsp extends CephBackupStorageBase.AgentResponse { } public static class PingCmd extends AgentCmd { @@ -78,7 +78,13 @@ public static class PingCmd extends AgentCmd { } public static class PingRsp extends AgentRsp { - public PingOperationFailure failure; + public CephBackupStorageBase.PingOperationFailure failure; + } + + public static class ConnectCmd extends AgentCmd { + } + + public static class ConnectRsp extends AgentRsp { } public CephBackupStorageMonBase(CephMonAO self) { @@ -208,14 +214,7 @@ public void run(final FlowTrigger trigger, Map data) { runner.setSshPort(getSelf().getSshPort()); runner.setAgentPort(CephGlobalProperty.BACKUP_STORAGE_AGENT_PORT); runner.setPlayBookName(CephGlobalProperty.BACKUP_STORAGE_PLAYBOOK_NAME); - runner.putArgument("pkg_cephbagent", CephGlobalProperty.BACKUP_STORAGE_PACKAGE_NAME); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - trigger.fail(operr("chrony server not configured!")); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } + runner.setDeployArguments(new CephBackupStorageDeployArguments()); runner.run(new ReturnValueCompletion(trigger) { @Override public void success(Boolean deployed) { @@ -320,6 +319,27 @@ public void fail(ErrorCode errorCode) { }); } }); + + flow(new NoRollbackFlow() { + String __name__ = "connect-agent"; + @Override + public void run(FlowTrigger trigger, Map data) { + ConnectCmd cmd = new ConnectCmd(); + cmd.monUuid = self.getUuid(); + cmd.backupStorageUuid = getSelf().getBackupStorageUuid(); + httpCall(CONNECT_PATH, cmd, ConnectRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(ConnectRsp returnValue) { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); } done(new FlowDoneHandler(completion) { @@ -345,7 +365,7 @@ private void httpCall(String path, AgentCmd cmd, final ReturnValueCompletion void httpCall(String path, AgentCmd cmd, final Class rspClass, final ReturnValueCompletion completion) { + private void httpCall(String path, AgentCmd cmd, final Class rspClass, final ReturnValueCompletion completion) { restf.asyncJsonPost(CephAgentUrl.backupStorageUrl(self.getHostname(), path), cmd, new JsonAsyncRESTCallback(completion) { @Override @@ -355,6 +375,10 @@ public void fail(ErrorCode err) { @Override public void success(T ret) { + if (!ret.isSuccess()) { + completion.fail(Platform.operr("operation error, because:%s", ret.getError())); + return; + } completion.success(ret); } @@ -365,26 +389,6 @@ public Class getReturnClass() { }); } - private void httpCall(String path, AgentCmd cmd, final Class rspClass, final ReturnValueCompletion completion, TimeUnit unit, Long timeout) { - restf.asyncJsonPost(CephAgentUrl.backupStorageUrl(self.getHostname(), path), - cmd, new JsonAsyncRESTCallback(completion) { - @Override - public void fail(ErrorCode err) { - completion.fail(err); - } - - @Override - public void success(T ret) { - completion.success(ret); - } - - @Override - public Class getReturnClass() { - return rspClass; - } - }, unit, timeout); - } - @Override public void ping(final ReturnValueCompletion completion) { thdf.chainSubmit(new ChainTask(completion) { @@ -460,6 +464,7 @@ public void fail(ErrorCode errorCode) { try { TimeUnit.SECONDS.sleep(sleep); } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); } } compl.done(); @@ -493,25 +498,27 @@ public void doPing(final ReturnValueCompletion completion) { cmd.monUuid = getSelf().getUuid(); cmd.backupStorageUuid = getSelf().getBackupStorageUuid(); - httpCall(PING_PATH, cmd, PingRsp.class, new ReturnValueCompletion(completion) { - @Override - public void success(PingRsp rsp) { - PingResult res = new PingResult(); - if (rsp.success) { - res.success = true; - } else { - res.success = false; - res.error = rsp.error; - res.failure = rsp.failure.toString(); - } + restf.asyncJsonPost(CephAgentUrl.backupStorageUrl(self.getHostname(), PING_PATH), + cmd, new JsonAsyncRESTCallback(completion) { + @Override + public void fail(ErrorCode err) { + completion.fail(err); + } - completion.success(res); - } + @Override + public void success(CephBackupStorageMonBase.PingRsp rsp) { + PingResult res = new PingResult(); + res.success = rsp.isSuccess(); + res.error = rsp.getError(); + // if agent met unexpected error, no failure will be set + res.failure = Objects.toString(rsp.failure, null); + completion.success(res); + } - @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); - } - }, TimeUnit.SECONDS, 60); + @Override + public Class getReturnClass() { + return CephBackupStorageMonBase.PingRsp.class; + } + }, TimeUnit.SECONDS, 60); } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageSimulator.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageSimulator.java index ea02d388890..5fe7283f8db 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageSimulator.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/backup/CephBackupStorageSimulator.java @@ -5,7 +5,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @@ -19,8 +18,6 @@ import org.zstack.header.storage.backup.BackupStorageVO_; import org.zstack.storage.ceph.backup.CephBackupStorageBase.*; import org.zstack.storage.ceph.backup.CephBackupStorageSimulatorConfig.CephBackupStorageConfig; -import org.zstack.storage.ceph.primary.CephPrimaryStorageBase; -import org.zstack.storage.ceph.primary.CephPrimaryStorageSimulatorConfig; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.gson.JSONObjectUtil; @@ -92,9 +89,9 @@ String pingMon(HttpEntity entity) { CephBackupStorageMonBase.PingCmd cmd = JSONObjectUtil.toObject(entity.getBody(), CephBackupStorageMonBase.PingCmd.class); Boolean success = config.pingCmdSuccess.get(cmd.monUuid); CephBackupStorageMonBase.PingRsp rsp = new CephBackupStorageMonBase.PingRsp(); - rsp.success = success == null ? true : success; - if (!rsp.success) { - rsp.error = "on purpose"; + rsp.setSuccess(success == null ? true : success); + if (!rsp.isSuccess()) { + rsp.setError("on purpose"); } rsp.failure = config.pingCmdOperationFailure.get(cmd.monUuid); reply(entity, rsp); @@ -128,8 +125,8 @@ String initialize(HttpEntity entity) { InitRsp rsp = new InitRsp(); if (!config.monInitSuccess) { - rsp.error = "on purpose"; - rsp.success = false; + rsp.setError("on purpose"); + rsp.setSuccess(false); } else { rsp.fsid = cbc.fsid; rsp.totalCapacity = cbc.totalCapacity; @@ -148,10 +145,9 @@ String checkPool(HttpEntity entity) { CheckRsp rsp = new CheckRsp(); if (!config.monInitSuccess) { - rsp.error = "on purpose"; - rsp.success = false; + rsp.setError("on purpose"); } else { - rsp.success = true; + rsp.setSuccess(true); } reply(entity, rsp); diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStorageMsgDoc_zh_cn.groovy index a0a7cd514e4..48f2209cc0b 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "rootVolumePoolName" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "dataVolumePoolName" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "imageCachePoolName" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -79,7 +74,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -99,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -109,7 +101,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -119,7 +110,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -129,7 +119,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -139,7 +128,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStoragePoolMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStoragePoolMsgDoc_zh_cn.groovy index 3f063e8b3ec..f1dcaa7b473 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStoragePoolMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddCephPrimaryStoragePoolMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "poolName" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "aliasName" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "isCreate" @@ -69,7 +65,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } column { name "type" @@ -111,6 +103,15 @@ doc { since "0.6" values ("Root","Data") } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddMonToCephPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddMonToCephPrimaryStorageMsgDoc_zh_cn.groovy index bf395f360fe..60d13e526f5 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddMonToCephPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIAddMonToCephPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "monUrls" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIDeleteCephPrimaryStoragePoolMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIDeleteCephPrimaryStoragePoolMsgDoc_zh_cn.groovy index 63b7a0a703d..81c6a0815e3 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIDeleteCephPrimaryStoragePoolMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIDeleteCephPrimaryStoragePoolMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupMsg.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupMsg.java new file mode 100644 index 00000000000..c4d995c7ebd --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupMsg.java @@ -0,0 +1,23 @@ +package org.zstack.storage.ceph.primary; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.Collections; +import java.util.List; + +@RestRequest( + path = "/primary-storage/ceph/osdgroups", + optionalPaths = {"/primary-storage/ceph/osdgroups/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryCephOsdGroupReply.class +) +@AutoQuery(replyClass = APIQueryCephOsdGroupReply.class, inventoryClass = CephOsdGroupInventory.class) +public class APIQueryCephOsdGroupMsg extends APIQueryMessage { + + public static List __example__() { + return Collections.singletonList("uuid=" + uuid()); + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..1b73489113a --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.storage.ceph.primary + +import org.zstack.storage.ceph.primary.APIQueryCephOsdGroupReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryCephOsdGroup" + + category "未知类别" + + desc """查询CephOsdGroup相关信息""" + + rest { + request { + url "GET /v1/primary-storage/ceph/osdgroups" + url "GET /v1/primary-storage/ceph/osdgroups/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryCephOsdGroupMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryCephOsdGroupReply.class + } + } +} \ No newline at end of file diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupReply.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupReply.java new file mode 100644 index 00000000000..66130493d63 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupReply.java @@ -0,0 +1,38 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.storage.ceph.DataSecurityPolicy; + +import java.sql.Timestamp; +import java.util.List; + +import static java.util.Arrays.asList; + +@RestResponse(allTo = "inventories") +public class APIQueryCephOsdGroupReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryCephOsdGroupReply __example__() { + APIQueryCephOsdGroupReply reply = new APIQueryCephOsdGroupReply(); + CephOsdGroupInventory cephOsdGroup = new CephOsdGroupInventory(); + cephOsdGroup.setOsds("osd.1"); + cephOsdGroup.setAvailablePhysicalCapacity(1024); + cephOsdGroup.setTotalPhysicalCapacity(1024); + cephOsdGroup.setAvailableCapacity(0); + cephOsdGroup.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + cephOsdGroup.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + reply.setInventories(asList(cephOsdGroup)); + reply.setSuccess(true); + return reply; + } + +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupReplyDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..57a2d6f1ce5 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephOsdGroupReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.storage.ceph.primary + +import org.zstack.storage.ceph.primary.CephOsdGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询CephOsdGroup返回" + + ref { + name "inventories" + path "org.zstack.storage.ceph.primary.APIQueryCephOsdGroupReply.inventories" + desc "null" + type "List" + since "0.6" + clz CephOsdGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.storage.ceph.primary.APIQueryCephOsdGroupReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStorageMsgDoc_zh_cn.groovy index 2b7be90bf0e..11b0142d690 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStorageMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.storage.ceph.primary import org.zstack.header.storage.primary.APIQueryPrimaryStorageReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询 Ceph 主存储(QueryCephPrimaryStorage)" diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStoragePoolMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStoragePoolMsgDoc_zh_cn.groovy index 0b5f6082fbe..a20ddab7ae6 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStoragePoolMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIQueryCephPrimaryStoragePoolMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.storage.ceph.primary import org.zstack.storage.ceph.primary.APIQueryCephPrimaryStoragePoolReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryCephPrimaryStoragePool" diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIRemoveMonFromCephPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIRemoveMonFromCephPrimaryStorageMsgDoc_zh_cn.groovy index cbeda45939b..1f50ebca4b1 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIRemoveMonFromCephPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIRemoveMonFromCephPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "monHostnames" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStorageMonMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStorageMonMsgDoc_zh_cn.groovy index e624bf870f0..332dfa6e40a 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStorageMonMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStorageMonMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "hostname" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshUsername" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshPassword" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshPort" @@ -69,7 +65,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "monPort" @@ -79,7 +74,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStoragePoolMsgDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStoragePoolMsgDoc_zh_cn.groovy index ba438a01e31..55d44b25fa2 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStoragePoolMsgDoc_zh_cn.groovy +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/APIUpdateCephPrimaryStoragePoolMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "aliasName" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephChangeVolumeProcessingMethodExtension.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephChangeVolumeProcessingMethodExtension.java new file mode 100644 index 00000000000..fff14152d5c --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephChangeVolumeProcessingMethodExtension.java @@ -0,0 +1,27 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.core.db.Q; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.storage.primary.PrimaryStorageVO_; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO_; +import org.zstack.header.volume.VolumeDeletionPolicyManager; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.storage.ceph.CephConstants; +import org.zstack.storage.volume.ChangeVolumeProcessingMethodExtensionPoint; + +public class CephChangeVolumeProcessingMethodExtension implements ChangeVolumeProcessingMethodExtensionPoint { + @Override + public VolumeDeletionPolicyManager.VolumeDeletionPolicy getTransientVolumeDeletionPolicy(VolumeInventory transientVolume) { + String psType = Q.New(PrimaryStorageVO.class).eq(PrimaryStorageVO_.uuid, transientVolume.getPrimaryStorageUuid()).select(PrimaryStorageVO_.type).findValue(); + if (!psType.equals(CephConstants.CEPH_PRIMARY_STORAGE_TYPE)) { + return null; + } + boolean hasSnapshots = Q.New(VolumeSnapshotVO.class).eq(VolumeSnapshotVO_.primaryStorageUuid, transientVolume.getPrimaryStorageUuid()) + .like(VolumeSnapshotVO_.primaryStorageInstallPath, String.format("%s@%%", transientVolume.getInstallPath())).isExists(); + if (!hasSnapshots) { + return VolumeDeletionPolicyManager.VolumeDeletionPolicy.Direct; + } + return VolumeDeletionPolicyManager.VolumeDeletionPolicy.DBOnly; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeChainGC.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeChainGC.java new file mode 100644 index 00000000000..4d09485cd95 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeChainGC.java @@ -0,0 +1,61 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.gc.GC; +import org.zstack.core.gc.GCCompletion; +import org.zstack.core.gc.TimeBasedGarbageCollector; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.primary.DeleteVolumeChainOnPrimaryStorageMsg; +import org.zstack.header.storage.primary.DeleteVolumeChainOnPrimaryStorageReply; +import org.zstack.header.storage.primary.PrimaryStorageConstant; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.List; + +public class CephDeleteVolumeChainGC extends TimeBasedGarbageCollector { + @GC + public String primaryStorageUuid; + @GC + public List installPaths; + @GC + public String chainTop; + + private static final CLogger logger = Utils.getLogger(CephDeleteVolumeChainGC.class); + + @Override + protected void triggerNow(GCCompletion completion) { + if (!dbf.isExist(primaryStorageUuid, PrimaryStorageVO.class) || CollectionUtils.isEmpty(installPaths)) { + completion.cancel(); + return; + } + + DeleteVolumeChainOnPrimaryStorageMsg msg = new DeleteVolumeChainOnPrimaryStorageMsg(); + msg.setPrimaryStorageUuid(primaryStorageUuid); + msg.setChainTop(chainTop); + msg.setInstallPaths(installPaths); + bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, primaryStorageUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + DeleteVolumeChainOnPrimaryStorageReply r = reply.castReply(); + if (CollectionUtils.isEmpty(r.getUndeletedInstallPaths())) { + completion.success(); + } else { + installPaths = r.getUndeletedInstallPaths(); + updateContext(); + completion.fail(Platform.operr("delete volume chain error, continue to delete")); + } + } + }); + } +} + diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeGC.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeGC.java index ce14500c08f..33f5fdf0a6c 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeGC.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephDeleteVolumeGC.java @@ -1,15 +1,20 @@ package org.zstack.storage.ceph.primary; +import org.apache.commons.lang.StringUtils; +import org.bouncycastle.util.Strings; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.gc.GC; import org.zstack.core.gc.GCCompletion; import org.zstack.core.gc.TimeBasedGarbageCollector; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.primary.DeleteVolumeBitsOnPrimaryStorageMsg; -import org.zstack.header.storage.primary.DeleteVolumeOnPrimaryStorageMsg; import org.zstack.header.storage.primary.PrimaryStorageConstant; import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.header.volume.VolumeInventory; +import org.zstack.storage.volume.VolumeErrors; +import org.zstack.storage.volume.VolumeSystemTags; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; /** * Created by kayo on 2018/7/24. @@ -20,21 +25,33 @@ public class CephDeleteVolumeGC extends TimeBasedGarbageCollector { @GC public VolumeInventory volume; + private static final CLogger logger = Utils.getLogger(CephDeleteVolumeGC.class); + @Override protected void triggerNow(GCCompletion completion) { if (!dbf.isExist(primaryStorageUuid, PrimaryStorageVO.class)) { completion.cancel(); return; } + if (StringUtils.isEmpty(volume.getInstallPath())) { + completion.cancel(); + return; + } DeleteVolumeBitsOnPrimaryStorageMsg msg = new DeleteVolumeBitsOnPrimaryStorageMsg(); msg.setPrimaryStorageUuid(primaryStorageUuid); msg.setInstallPath(volume.getInstallPath()); + msg.setSize(volume.getSize()); bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, primaryStorageUuid); bus.send(msg, new CloudBusCallBack(completion) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { + if (reply.getError().isError(VolumeErrors.VOLUME_IN_USE) && !VolumeSystemTags.FAST_REVERT.hasTag(volume.getUuid())) { + logger.warn(String.format("unable to delete path:%s right now, cancel this GC job because it's in use", msg.getInstallPath())); + completion.cancel(); + return; + } completion.fail(reply.getError()); return; } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephImageCacheCleaner.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephImageCacheCleaner.java index 9e4bfd950f9..81cec9a040c 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephImageCacheCleaner.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephImageCacheCleaner.java @@ -7,6 +7,7 @@ import org.zstack.header.storage.primary.ImageCacheVO; import org.zstack.storage.ceph.CephConstants; import org.zstack.storage.ceph.CephGlobalConfig; +import org.zstack.storage.primary.ImageCacheCleanParam; import org.zstack.storage.primary.ImageCacheCleaner; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -32,8 +33,8 @@ protected GlobalConfig cleanupIntervalConfig() { @Transactional @Override - protected List createShadowImageCacheVOs(String psUuid) { - List staleImageCacheIds = getStaleImageCacheIds(psUuid); + protected List createShadowImageCacheVOsForNewDeletedAndOld(String psUuid, ImageCacheCleanParam param) { + List staleImageCacheIds = getStaleImageCacheIds(psUuid, false); if (staleImageCacheIds == null || staleImageCacheIds.isEmpty()) { return null; } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephKvmExtension.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephKvmExtension.java index 27fcf55eb54..461e841f69f 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephKvmExtension.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephKvmExtension.java @@ -25,11 +25,11 @@ import org.zstack.kvm.KVMHostConnectedContext; import org.zstack.kvm.KVMHostFactory; import org.zstack.storage.ceph.CephConstants; +import org.zstack.storage.primary.CheckHostStorageConnectionMsg; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; import javax.persistence.TypedQuery; -import java.util.ArrayList; import java.util.List; import java.util.Map; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupHistoricalUsageVO.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupHistoricalUsageVO.java new file mode 100644 index 00000000000..a83dfcdef4a --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupHistoricalUsageVO.java @@ -0,0 +1,41 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.storage.primary.PrimaryStorageHistoricalUsageBaseVO; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.BaseResource; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table +@BaseResource +@AutoDeleteTag +public class CephOsdGroupHistoricalUsageVO extends PrimaryStorageHistoricalUsageBaseVO { + + public CephOsdGroupHistoricalUsageVO() { + resourceType = CephOsdGroupVO.class.getSimpleName(); + } + + @Column + private String osdGroupUuid; + + public String getOsdGroupUuid() { + return osdGroupUuid; + } + + public void setOsdGroupUuid(String osdGroupUuid) { + this.osdGroupUuid = osdGroupUuid; + } + + @Override + public String getResourceUuid() { + return osdGroupUuid; + } + + @Override + public void setResourceUuid(String resourceUuid) { + this.osdGroupUuid = resourceUuid; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupHistoricalUsageVO_.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupHistoricalUsageVO_.java new file mode 100644 index 00000000000..1358ce25951 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupHistoricalUsageVO_.java @@ -0,0 +1,11 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.storage.primary.PrimaryStorageHistoricalUsageBaseVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(CephOsdGroupHistoricalUsageVO.class) +public class CephOsdGroupHistoricalUsageVO_ extends PrimaryStorageHistoricalUsageBaseVO_ { + public static volatile SingularAttribute osdGroupUuid; +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupInventory.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupInventory.java new file mode 100644 index 00000000000..fa73dafeb6a --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupInventory.java @@ -0,0 +1,115 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = CephOsdGroupVO.class, collectionValueOfMethod = "valueOf1") +public class CephOsdGroupInventory implements Serializable { + private String primaryStorageUuid; + private String osds; + private long availableCapacity; + private long availablePhysicalCapacity; + private long totalPhysicalCapacity; + private Timestamp createDate; + private Timestamp lastOpDate; + private String uuid; + + protected CephOsdGroupInventory(CephOsdGroupVO vo) { + this.setPrimaryStorageUuid(vo.getPrimaryStorageUuid()); + this.setOsds(vo.getOsds()); + this.setAvailableCapacity(vo.getAvailableCapacity()); + this.setAvailablePhysicalCapacity(vo.getAvailablePhysicalCapacity()); + this.setTotalPhysicalCapacity(vo.getTotalPhysicalCapacity()); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + this.setUuid(vo.getUuid()); + } + + public static CephOsdGroupInventory valueOf(CephOsdGroupVO vo) { + return new CephOsdGroupInventory(vo); + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (CephOsdGroupVO vo : vos) { + invs.add(CephOsdGroupInventory.valueOf(vo)); + } + return invs; + } + + public CephOsdGroupInventory() { + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String $paramName) { + primaryStorageUuid = $paramName; + } + + public String getOsds() { + return osds; + } + + public void setOsds(String $paramName) { + osds = $paramName; + } + + public long getAvailableCapacity() { + return availableCapacity; + } + + public void setAvailableCapacity(long availableCapacity) { + this.availableCapacity = availableCapacity; + } + + public long getAvailablePhysicalCapacity() { + return availablePhysicalCapacity; + } + + public void setAvailablePhysicalCapacity(long $paramName) { + availablePhysicalCapacity = $paramName; + } + + public long getTotalPhysicalCapacity() { + return totalPhysicalCapacity; + } + + public void setTotalPhysicalCapacity(long $paramName) { + totalPhysicalCapacity = $paramName; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp $paramName) { + createDate = $paramName; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp $paramName) { + lastOpDate = $paramName; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String $paramName) { + uuid = $paramName; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupInventoryDoc_zh_cn.groovy b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..ca53a8bce3f --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupInventoryDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.storage.ceph.primary + +import java.sql.Timestamp +import java.sql.Timestamp + +doc { + + title "CephOsdGroup结构体" + + field { + name "primaryStorageUuid" + desc "主存储UUID" + type "String" + since "0.6" + } + field { + name "osds" + desc "" + type "String" + since "0.6" + } + field { + name "availableCapacity" + desc "" + type "long" + since "0.6" + } + field { + name "availablePhysicalCapacity" + desc "" + type "long" + since "0.6" + } + field { + name "totalPhysicalCapacity" + desc "" + type "long" + since "0.6" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "0.6" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "0.6" + } + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "0.6" + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupVO.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupVO.java new file mode 100644 index 00000000000..8e024873283 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupVO.java @@ -0,0 +1,107 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.storage.primary.PrimaryStorageEO; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.storage.primary.StorageCapacityAO; +import org.zstack.header.vo.*; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; + +import javax.persistence.*; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.Set; + +/** + * @ Author : yh.w + * @ Date : Created in 18:18 2022/8/1 + */ +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = PrimaryStorageVO.class, joinColumn = "primaryStorageUuid") +}) +public class CephOsdGroupVO extends StorageCapacityAO { + @Id + @Column + @Index + private String uuid; + + @Column + @ForeignKey(parentEntityClass = PrimaryStorageEO.class, parentKey = "uuid", onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String primaryStorageUuid; + + @Column + private String osds; + + @Column + private long availableCapacity; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public CephOsdGroupVO() { + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + @Override + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getOsds() { + return osds; + } + + public void setOsds(String osds) { + this.osds = osds; + } + + public long getAvailableCapacity() { + return availableCapacity; + } + + public void setAvailableCapacity(long availableCapacity) { + this.availableCapacity = availableCapacity; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getResourceUuid() { + return uuid; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupVO_.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupVO_.java new file mode 100644 index 00000000000..b41ab601ae2 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephOsdGroupVO_.java @@ -0,0 +1,18 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.storage.primary.StorageCapacityAO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(CephOsdGroupVO.class) +public class CephOsdGroupVO_ extends StorageCapacityAO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute primaryStorageUuid; + public static volatile SingularAttribute osds; + public static volatile SingularAttribute availableCapacity; + public static volatile SingularAttribute availablePhysicalCapacity; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java index da4735b5e3c..6579e941392 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageBase.java @@ -17,14 +17,9 @@ import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.thread.*; -import org.zstack.core.thread.AsyncThread; -import org.zstack.core.thread.ChainTask; -import org.zstack.core.thread.SyncTaskChain; -import org.zstack.core.thread.ThreadFacade; -import org.zstack.core.timeout.ApiTimeoutManager; -import org.zstack.core.trash.TrashType; -import org.zstack.header.core.trash.InstallPathRecycleInventory; import org.zstack.core.trash.StorageTrash; +import org.zstack.core.trash.TrashType; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.Constants; @@ -35,17 +30,21 @@ import org.zstack.header.cluster.ClusterVO_; import org.zstack.header.core.*; import org.zstack.header.core.progress.TaskProgressRange; -import org.zstack.header.core.trash.CleanTrashResult; import org.zstack.header.core.trash.InstallPathRecycleInventory; +import org.zstack.header.core.trash.TrashCleanupResult; import org.zstack.header.core.validation.Validation; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.*; -import org.zstack.header.image.*; +import org.zstack.header.image.ImageBackupStorageRefInventory; import org.zstack.header.image.ImageConstant.ImageMediaType; +import org.zstack.header.image.ImageInventory; +import org.zstack.header.image.ImageStatus; +import org.zstack.header.image.ImageVO; import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; @@ -55,7 +54,9 @@ import org.zstack.header.storage.primary.*; import org.zstack.header.storage.primary.VolumeSnapshotCapability.VolumeSnapshotArrangementType; import org.zstack.header.storage.snapshot.*; +import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmInstanceSpec.ImageSpec; +import org.zstack.header.vo.ResourceVO; import org.zstack.header.volume.*; import org.zstack.identity.AccountManager; import org.zstack.kvm.*; @@ -69,13 +70,20 @@ import org.zstack.storage.ceph.backup.CephBackupStorageVO; import org.zstack.storage.ceph.backup.CephBackupStorageVO_; import org.zstack.storage.ceph.primary.CephPrimaryStorageMonBase.PingOperationFailure; +import org.zstack.storage.ceph.primary.capacity.CephOsdGroupCapacityHelper; import org.zstack.storage.primary.*; +import org.zstack.storage.snapshot.DeleteVolumeSnapshotGC; +import org.zstack.storage.snapshot.VolumeSnapshotGlobalConfig; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; +import org.zstack.tag.SystemTag; import org.zstack.tag.SystemTagCreator; +import org.zstack.tag.TagManager; import org.zstack.utils.*; import org.zstack.utils.function.Function; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; import java.io.Serializable; import java.net.URI; @@ -109,6 +117,13 @@ public class CephPrimaryStorageBase extends PrimaryStorageBase { private PluginRegistry pluginRgty; @Autowired private StorageTrash trash; + @Autowired + private PoolUsageReport poolUsageCollector; + @Autowired + protected PrimaryStoragePhysicalCapacityManager psPhysicalCapacityMgr; + @Autowired + private TagManager tagMgr; + public CephPrimaryStorageBase() { } @@ -129,6 +144,8 @@ void unlock() { private final String queueId = "Ceph-" + self.getUuid(); + private CephOsdGroupCapacityHelper osdHelper; + protected RunInQueue inQueue() { return new RunInQueue(queueId, thdf, getCephSyncLevel()); } @@ -194,38 +211,18 @@ public void setUuid(String uuid) { } } - public static class AgentResponse { - String error; - boolean success = true; + public static class AgentResponse extends CephMonBase.AgentResponse { Long totalCapacity; Long availableCapacity; List poolCapacities; String type; public AgentResponse() { - boolean unitTestOn = CoreGlobalProperty.UNIT_TEST_ON; - if (unitTestOn && type == null) { + if (CoreGlobalProperty.UNIT_TEST_ON) { type = CephConstants.CEPH_MANUFACTURER_OPENSOURCE; } } - public String getError() { - return error; - } - - public void setError(String error) { - this.success = false; - this.error = error; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - public Long getTotalCapacity() { return totalCapacity; } @@ -275,6 +272,10 @@ public static class GetVolumeSizeCmd extends AgentCommand { public String installPath; } + public static class GetBatchVolumeSizeCmd extends AgentCommand { + public Map volumeUuidInstallPaths; + } + public static class GetVolumeSnapshotSizeCmd extends AgentCommand { public String volumeSnapshotUuid; public String installPath; @@ -285,6 +286,10 @@ public static class GetVolumeSizeRsp extends AgentResponse { public Long actualSize; } + public static class GetBatchVolumeSizeRsp extends AgentResponse { + public Map actualSizes; + } + public static class GetVolumeSnapshotSizeRsp extends AgentResponse { public Long size; public Long actualSize; @@ -367,6 +372,7 @@ public static class CreateEmptyVolumeCmd extends AgentCommand { long size; boolean shareable; boolean skipIfExisting; + String format = VolumeConstant.VOLUME_FORMAT_RAW; public boolean isShareable() { return shareable; @@ -399,10 +405,19 @@ public void setSkipIfExisting(boolean skipIfExisting) { public boolean isSkipIfExisting() { return skipIfExisting; } + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } } public static class CreateEmptyVolumeRsp extends AgentResponse { public String installPath; + public Long actualSize; public String getInstallPath() { return installPath; @@ -415,6 +430,15 @@ public void setInstallPath(String installPath) { public static class DeleteCmd extends AgentCommand { String installPath; + long expirationTime; + + public long getExpirationTime() { + return expirationTime; + } + + public void setExpirationTime(long expirationTime) { + this.expirationTime = expirationTime; + } public String getInstallPath() { return installPath; @@ -426,7 +450,13 @@ public void setInstallPath(String installPath) { } public static class DeleteRsp extends AgentResponse { - + public boolean inUse; + public ErrorCode buildErrorCode() { + if (inUse) { + return Platform.err(VolumeErrors.VOLUME_IN_USE, getError()); + } + return super.buildErrorCode(); + } } public static class CloneCmd extends AgentCommand { @@ -464,7 +494,7 @@ public void setInstallPath(String installPath) { } } - public static class FlattenCmd extends AgentCommand { + public static class FlattenCmd extends AgentCommand implements HasThreadContext { String path; public String getPath() { @@ -622,6 +652,8 @@ public static class CreateSnapshotCmd extends AgentCommand { boolean skipOnExisting; String snapshotPath; String volumeUuid; + String name; + String description; public String getVolumeUuid() { return volumeUuid; @@ -646,6 +678,22 @@ public String getSnapshotPath() { public void setSnapshotPath(String snapshotPath) { this.snapshotPath = snapshotPath; } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } } public static class CreateSnapshotRsp extends AgentResponse { @@ -678,6 +726,39 @@ public void setSize(long size) { } } + public static class UpdateSnapshotCmd extends AgentCommand { + String snapshotPath; + String name; + String description; + + public String getSnapshotPath() { + return snapshotPath; + } + + public void setSnapshotPath(String snapshotPath) { + this.snapshotPath = snapshotPath; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } + + public static class UpdateSnapshotRsp extends AgentResponse { + } + public static class DeleteSnapshotCmd extends AgentCommand { String snapshotPath; @@ -740,15 +821,6 @@ public static class CpCmd extends AgentCommand implements HasThreadContext { boolean shareable; } - public static class UploadCmd extends AgentCommand implements HasThreadContext { - public String sendCommandUrl; - public String imageUuid; - public String hostname; - public String srcPath; - public String dstPath; - public String description; - } - public static class CpRsp extends AgentResponse { public Long size; public Long actualSize; @@ -757,6 +829,7 @@ public static class CpRsp extends AgentResponse { public static class RollbackSnapshotCmd extends AgentCommand implements HasThreadContext { String snapshotPath; + double capacityThreshold; public String getSnapshotPath() { return snapshotPath; @@ -765,6 +838,14 @@ public String getSnapshotPath() { public void setSnapshotPath(String snapshotPath) { this.snapshotPath = snapshotPath; } + + public void setCapacityThreshold(double capacityThreshold) { + this.capacityThreshold = capacityThreshold; + } + + public double getCapacityThreshold() { + return capacityThreshold; + } } public static class RollbackSnapshotRsp extends AgentResponse { @@ -846,7 +927,9 @@ public static class CheckHostStorageConnectionRsp extends AgentResponse { } public static class CreateKvmSecretCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") String userKey; + @GrayVersion(value = "5.0.0") String uuid; public String getUserKey() { @@ -893,6 +976,7 @@ public static class KvmSetupSelfFencerCmd extends AgentCommand implements Serial public List monUrls; public String strategy; public String manufacturer; + public List fencers; } public static class KvmCancelSelfFencerCmd extends AgentCommand { @@ -905,6 +989,7 @@ public static class GetFactsCmd extends AgentCommand { public static class GetFactsRsp extends AgentResponse { public String fsid; public String monAddr; + public List ipAddresses; } public static class DeleteImageCacheCmd extends AgentCommand { @@ -928,6 +1013,33 @@ public static class GetVolumeWatchersRsp extends AgentResponse { public List watchers; } + public static class GetBackingChainCmd extends AgentCommand { + public String volumePath; + } + + public static class GetBackingChainRsp extends AgentResponse { + public List backingChain; + + public long totalSize; + } + + public static class DeleteVolumeChainCmd extends AgentCommand { + public List installPaths; + } + + public static class DeleteVolumeChainRsp extends AgentResponse { + public List undeletedInstallPaths; + } + + public static class CleanTrashCmd extends AgentCommand { + public List pools; + public boolean force; + } + + public static class CleanTrashRsp extends AgentResponse { + public Map> pool2TrashResult; + } + public static class CephToCephMigrateVolumeSegmentCmd extends AgentCommand implements HasThreadContext, Serializable { String parentUuid; String resourceUuid; @@ -1097,6 +1209,41 @@ public String getSendCommandUrl() { } } + public static class DownloadBitsFromRemoteTargetRsp extends AgentResponse { + public long diskSize; + } + + public static class DownloadBitsFromRemoteTargetCmd extends AgentCommand implements HasThreadContext, Serializable { + @NoLogging + private String remoteTargetUri; + private String primaryStorageInstallPath; + private String sendCommandUrl; + + public String getPrimaryStorageInstallPath() { + return primaryStorageInstallPath; + } + + public void setPrimaryStorageInstallPath(String primaryStorageInstallPath) { + this.primaryStorageInstallPath = primaryStorageInstallPath; + } + + public String getRemoteTargetUri() { + return remoteTargetUri; + } + + public void setRemoteTargetUri(String remoteTargetUri) { + this.remoteTargetUri = remoteTargetUri; + } + + public void setSendCommandUrl(String sendCommandUrl) { + this.sendCommandUrl = sendCommandUrl; + } + + public String getSendCommandUrl() { + return sendCommandUrl; + } + } + public static class DownloadBitsFromKVMHostCmd extends AgentCommand implements ReloadableCommand { private String hostname; private String username; @@ -1244,6 +1391,7 @@ public int compareTo(SnapInfo snapInfo) { public static final String CHECK_HOST_STORAGE_CONNECTION_PATH = "/ceph/primarystorage/check/host/connection"; public static final String DELETE_POOL_PATH = "/ceph/primarystorage/deletepool"; public static final String GET_VOLUME_SIZE_PATH = "/ceph/primarystorage/getvolumesize"; + public static final String BATCH_GET_VOLUME_SIZE_PATH = "/ceph/primarystorage/batchgetvolumesize"; public static final String GET_VOLUME_SNAPSHOT_SIZE_PATH = "/ceph/primarystorage/getvolumesnapshotsize"; public static final String KVM_HA_SETUP_SELF_FENCER = "/ha/ceph/setupselffencer"; public static final String KVM_HA_CANCEL_SELF_FENCER = "/ha/ceph/cancelselffencer"; @@ -1256,10 +1404,14 @@ public int compareTo(SnapInfo snapInfo) { public static final String GET_VOLUME_SNAPINFOS_PATH = "/ceph/primarystorage/volume/getsnapinfos"; public static final String DOWNLOAD_BITS_FROM_KVM_HOST_PATH = "/ceph/primarystorage/kvmhost/download"; public static final String DOWNLOAD_BITS_FROM_NBD_EXPT_PATH = "/ceph/primarystorage/nbd/download"; + public static final String DOWNLOAD_BITS_FROM_REMOTE_TARGET_PATH = "/ceph/primarystorage/remotetarget/download"; public static final String CANCEL_DOWNLOAD_BITS_FROM_KVM_HOST_PATH = "/ceph/primarystorage/kvmhost/download/cancel"; public static final String CHECK_SNAPSHOT_COMPLETED = "/ceph/primarystorage/check/snapshot"; public static final String GET_DOWNLOAD_BITS_FROM_KVM_HOST_PROGRESS_PATH = "/ceph/primarystorage/kvmhost/download/progress"; public static final String GET_IMAGE_WATCHERS_PATH = "/ceph/primarystorage/getvolumewatchers"; + public static final String GET_BACKING_CHAIN_PATH = "/ceph/primarystorage/volume/getbackingchain"; + public static final String DELETE_VOLUME_CHAIN_PATH = "/ceph/primarystorage/volume/deletechain"; + public static final String CLAEN_TRASH_PATH = "/ceph/primarystorage/trash/clean"; private final Map backupStorageMediators = new HashMap(); @@ -1273,12 +1425,6 @@ public int compareTo(SnapInfo snapInfo) { licenseExts = pluginRgty.getExtensionList(PrimaryStorageLicenseInfoFactory.class); } - static class UploadParam implements MediatorParam { - ImageInventory image; - String primaryStorageInstallPath; - String backupStorageInstallPath; - } - class SftpBackupStorageMediator extends BackupStorageMediator { private void getSftpCredentials(final ReturnValueCompletion completion) { GetSftpBackupStorageDownloadCredentialMsg gmsg = new GetSftpBackupStorageDownloadCredentialMsg(); @@ -1299,7 +1445,7 @@ public void run(MessageReply reply) { @Override public void download(final ReturnValueCompletion completion) { checkParam(); - final MediatorDowloadParam dparam = (MediatorDowloadParam) param; + final MediatorDownloadParam dparam = (MediatorDownloadParam) param; FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("download-image-from-sftp-%s-to-ceph-%s", backupStorage.getUuid(), dparam.getPrimaryStorageUuid())); @@ -1383,7 +1529,7 @@ public void handle(ErrorCode errCode, Map data) { public void upload(final ReturnValueCompletion completion) { checkParam(); - final UploadParam uparam = (UploadParam) param; + final MediatorUploadParam uparam = (MediatorUploadParam) param; final TaskProgressRange parentStage = getTaskStage(); final TaskProgressRange PREPARATION_STAGE = new TaskProgressRange(0, 10); final TaskProgressRange UPLOAD_STAGE = new TaskProgressRange(10, 100); @@ -1525,7 +1671,7 @@ public void checkParam() { public void download(final ReturnValueCompletion completion) { checkParam(); - final MediatorDowloadParam dparam = (MediatorDowloadParam) param; + final MediatorDownloadParam dparam = (MediatorDownloadParam) param; if (ImageMediaType.DataVolumeTemplate.toString().equals(dparam.getImage().getInventory().getMediaType())) { CpCmd cmd = new CpCmd(); cmd.srcPath = dparam.getImage().getSelectedBackupStorage().getInstallPath(); @@ -1550,79 +1696,26 @@ public void fail(ErrorCode errorCode) { @Override public void upload(final ReturnValueCompletion completion) { checkParam(); + final MediatorUploadParam uparam = (MediatorUploadParam) param; - final UploadParam uparam = (UploadParam) param; - final TaskProgressRange parentStage = getTaskStage(); - FlowChain chain = FlowChainBuilder.newShareFlowChain(); - chain.setName(String.format("upload-image-ceph-%s-to-ceph-%s", self.getUuid(), backupStorage.getUuid())); - chain.then(new ShareFlow() { - String backupStorageInstallPath; + CpCmd cmd = new CpCmd(); + cmd.sendCommandUrl = restf.getSendCommandUrl(); + cmd.fsId = getSelf().getFsid(); + cmd.srcPath = uparam.primaryStorageInstallPath; + cmd.dstPath = uparam.backupStorageInstallPath; + final String apiId = ThreadContext.get(Constants.THREAD_CONTEXT_API); + new HttpCaller<>(CP_PATH, cmd, CpRsp.class, new ReturnValueCompletion(completion) { @Override - public void setup() { - flow(new NoRollbackFlow() { - String __name__ = "get-backup-storage-install-path"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - BackupStorageAskInstallPathMsg msg = new BackupStorageAskInstallPathMsg(); - msg.setBackupStorageUuid(backupStorage.getUuid()); - msg.setImageUuid(uparam.image.getUuid()); - msg.setImageMediaType(uparam.image.getMediaType()); - bus.makeTargetServiceIdByResourceUuid(msg, BackupStorageConstant.SERVICE_ID, backupStorage.getUuid()); - bus.send(msg, new CloudBusCallBack(trigger) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - trigger.fail(reply.getError()); - } else { - backupStorageInstallPath = ((BackupStorageAskInstallPathReply) reply).getInstallPath(); - trigger.next(); - } - } - }); - } - }); - - flow(new NoRollbackFlow() { - String __name__ = "cp-to-the-image"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - CpCmd cmd = new CpCmd(); - cmd.sendCommandUrl = restf.getSendCommandUrl(); - cmd.srcPath = uparam.primaryStorageInstallPath; - cmd.dstPath = backupStorageInstallPath; - httpCall(CP_PATH, cmd, CpRsp.class, new ReturnValueCompletion(trigger) { - @Override - public void success(CpRsp returnValue) { - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - }); - - done(new FlowDoneHandler(completion) { - @Override - public void handle(Map data) { - reportProgress(parentStage.getEnd().toString()); - completion.success(backupStorageInstallPath); - } - }); + public void success(CpRsp rsp) { + completion.success(rsp.installPath); + } - error(new FlowErrorHandler(completion) { - @Override - public void handle(ErrorCode errCode, Map data) { - completion.fail(errCode); - } - }); + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); } - }).start(); + }).specifyOrder(apiId).call(); } @Override @@ -1642,141 +1735,29 @@ private BackupStorageMediator getBackupStorageMediator(String bsUuid) { return mediator; } - private String makeRootVolumeInstallPath(String volUuid, String volumePath) { - return String.format("ceph://%s/%s", getRootVolumeTargetPoolName(volUuid), volumePath); - } - - private String makeRootVolumeInstallPath(String volUuid) { - return String.format("ceph://%s/%s", getRootVolumeTargetPoolName(volUuid), volUuid); - } - - private String makeVolumeInstallPathByTargetPool(String volUuid, String targetPoolName) { - return String.format("ceph://%s/%s", targetPoolName, volUuid); - } - - private String getRootVolumeTargetPoolName(String volUuid) { - String poolName = CephSystemTags.USE_CEPH_ROOT_POOL.getTokenByResourceUuid(volUuid, CephSystemTags.USE_CEPH_ROOT_POOL_TOKEN); - return getPoolName(poolName, getDefaultRootVolumePoolName()); - } - - private String makeResetImageRootVolumeInstallPath(String volUuid, String volumePath) { - return String.format("ceph://%s/%s", - getDefaultRootVolumePoolName(), - volumePath); - } - - private String makeResetImageRootVolumeInstallPath(String volUuid) { - return String.format("ceph://%s/reset-image-%s-%s", - getDefaultRootVolumePoolName(), - volUuid, - System.currentTimeMillis()); - } - - private String makeDataVolumeInstallPath(String volUuid, String installPath) { - return String.format("ceph://%s/%s", getDataVolumeTargetPoolName(volUuid), installPath); - } - - private String makeDataVolumeInstallPath(String volUuid) { - return String.format("ceph://%s/%s", getDataVolumeTargetPoolName(volUuid), volUuid); - } - - private String getDataVolumeTargetPoolName(String volUuid) { - String poolName = CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL.getTokenByResourceUuid(volUuid, CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL_TOKEN); - return getPoolName(poolName, getDefaultDataVolumePoolName()); - } - - private String getPoolName(String customPoolName, String defaultPoolName){ - return customPoolName != null ? customPoolName : defaultPoolName; - } - - private String makeCacheInstallPath(String uuid) { - return String.format("ceph://%s/%s", - getDefaultImageCachePoolName(), - uuid); - } public CephPrimaryStorageBase(PrimaryStorageVO self) { super(self); + osdHelper = new CephOsdGroupCapacityHelper(self.getUuid()); } protected CephPrimaryStorageVO getSelf() { return (CephPrimaryStorageVO) self; } - private String getDefaultImageCachePoolName() { - return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_IMAGE_CACHE_POOL.getTokenByResourceUuid(self.getUuid(), CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_IMAGE_CACHE_POOL_TOKEN); - } - - private String getDefaultDataVolumePoolName() { - return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_DATA_VOLUME_POOL.getTokenByResourceUuid(self.getUuid(), CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_DATA_VOLUME_POOL_TOKEN); - } - - private String getDefaultRootVolumePoolName() { - return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_ROOT_VOLUME_POOL.getTokenByResourceUuid(self.getUuid(), CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_ROOT_VOLUME_POOL_TOKEN); - } - protected CephPrimaryStorageInventory getSelfInventory() { return CephPrimaryStorageInventory.valueOf(getSelf()); } - private void checkCephPoolCapacityForNewVolume(String poolName, long volumeSize) { - List poolVOS = Q.New(CephPrimaryStoragePoolVO.class) - .eq(CephPrimaryStoragePoolVO_.poolName, poolName) - .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, self.getUuid()) - .list(); - - if (poolVOS.size() == 0) { - throw new OperationFailureException(operr("cannot find cephPrimaryStorage pool[poolName=%s]", poolName)); - } - - CephPrimaryStoragePoolVO poolVO = poolVOS.get(0); - boolean capacityChecked = PrimaryStorageCapacityChecker.New(self.getUuid(), - poolVO.getAvailableCapacity(), poolVO.getTotalCapacity(), poolVO.getAvailableCapacity()) - .checkRequiredSize(volumeSize); - - if (!capacityChecked) { - throw new OperationFailureException(operr("cephPrimaryStorage pool[poolName=%s] available capacity not enough", poolName)); - } - } - - private String getPoolNameFromSystemTags(List systemTags, String volumeType) { - if (systemTags == null || systemTags.isEmpty()) { - return null; - } - - if (VolumeType.Root.toString().equals(volumeType)) { - return systemTags.stream().filter(tag -> TagUtils.isMatch(CephSystemTags.USE_CEPH_ROOT_POOL.getTagFormat(), tag)) - .map(tag -> TagUtils.parse(CephSystemTags.USE_CEPH_ROOT_POOL.getTagFormat(), tag).get(CephSystemTags.USE_CEPH_ROOT_POOL_TOKEN)) - .findFirst().orElse(null); - } else if (VolumeType.Data.toString().equals(volumeType)) { - return systemTags.stream().filter(tag -> TagUtils.isMatch(CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL.getTagFormat(), tag)) - .map(tag -> TagUtils.parse(CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL.getTagFormat(), tag).get(CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL_TOKEN)) - .findFirst().orElse(null); - } - return null; - } - private void createEmptyVolume(final InstantiateVolumeOnPrimaryStorageMsg msg) { final CreateEmptyVolumeCmd cmd = new CreateEmptyVolumeCmd(); String volumeUuid = msg.getVolume().getUuid(); - - String targetCephPoolName = getPoolNameFromSystemTags(msg.getSystemTags(), msg.getVolume().getType()); - - if (targetCephPoolName != null) { - cmd.installPath = makeVolumeInstallPathByTargetPool(volumeUuid, targetCephPoolName); - } else if (VolumeType.Root.toString().equals(msg.getVolume().getType())) { - targetCephPoolName = getRootVolumeTargetPoolName(volumeUuid); - cmd.installPath = makeRootVolumeInstallPath(msg.getVolume().getUuid()); - } else { - targetCephPoolName = getDataVolumeTargetPoolName(volumeUuid); - cmd.installPath = makeDataVolumeInstallPath(msg.getVolume().getUuid()); - } - - checkCephPoolCapacityForNewVolume(targetCephPoolName, msg.getVolume().getSize()); - + final String finalPoolName = getTargetPoolNameFromAllocatedUrl(msg.getAllocatedInstallUrl()); + cmd.installPath = makeVolumeInstallPathByTargetPool(volumeUuid, finalPoolName); cmd.size = msg.getVolume().getSize(); cmd.setShareable(msg.getVolume().isShareable()); cmd.skipIfExisting = msg.isSkipIfExisting(); + cmd.format = msg.hasSystemTag(VolumeSystemTags.FORMAT_QCOW2.getTagFormat()) ? VolumeConstant.VOLUME_FORMAT_QCOW2 : VolumeConstant.VOLUME_FORMAT_RAW ; final InstantiateVolumeOnPrimaryStorageReply reply = new InstantiateVolumeOnPrimaryStorageReply(); @@ -1790,38 +1771,33 @@ public void fail(ErrorCode err) { @Override public void success(CreateEmptyVolumeRsp ret) { VolumeInventory vol = msg.getVolume(); - vol.setInstallPath(buildEmptyVolumeInstallPath(msg.getVolume(), cmd.installPath, ret.getInstallPath())); + vol.setInstallPath(buildEmptyVolumeInstallPath(finalPoolName, cmd.installPath, ret.getInstallPath())); vol.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + vol.setActualSize(ret.actualSize); reply.setVolume(vol); bus.reply(msg, reply); } }); } - private String buildEmptyVolumeInstallPath(VolumeInventory vo,String canonicalPath, String installPath) { + protected String buildEmptyVolumeInstallPath(String targetCephPoolName,String canonicalPath, String installPath) { if (StringUtils.isEmpty(installPath)) { return canonicalPath; } - if (VolumeType.Root.toString().equals(vo.getType())) { - return makeRootVolumeInstallPath(vo.getUuid(), installPath); - } else { - return makeDataVolumeInstallPath(vo.getUuid(), installPath); - } + return makeVolumeInstallPathByTargetPool(installPath, targetCephPoolName); } - private void cleanTrash(Long trashId, final ReturnValueCompletion completion) { - CleanTrashResult result = new CleanTrashResult(); + private void cleanTrash(Long trashId, final ReturnValueCompletion completion) { InstallPathRecycleInventory inv = trash.getTrash(trashId); if (inv == null) { - completion.success(result); + completion.success(new TrashCleanupResult(trashId)); return; } String details = trash.makeSureInstallPathNotUsed(inv); if (details != null) { - result.getDetails().add(details); - completion.success(result); + completion.success(new TrashCleanupResult(inv.getResourceUuid(), inv.getTrashId(), operr(details))); return; } @@ -1852,6 +1828,7 @@ public void run(FlowTrigger trigger, Map data) { DeleteVolumeBitsOnPrimaryStorageMsg msg = new DeleteVolumeBitsOnPrimaryStorageMsg(); msg.setPrimaryStorageUuid(self.getUuid()); msg.setInstallPath(inv.getInstallPath()); + msg.setSize(inv.getSize()); bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, self.getUuid()); bus.send(msg, new CloudBusCallBack(trigger) { @Override @@ -1860,6 +1837,7 @@ public void run(MessageReply reply) { logger.info(String.format("Deleted volume %s in Trash.", inv.getInstallPath())); } else { logger.warn(String.format("Failed to delete volume %s in Trash.", inv.getInstallPath())); + submitCephDeleteVolumeGC(inv, self); } trigger.next(); } @@ -1878,9 +1856,7 @@ public void handle(Map data) { logger.info(String.format("Returned space[size:%s] to PS %s after volume migration", inv.getSize(), self.getUuid())); trash.removeFromDb(trashId); - result.setSize(inv.getSize()); - result.setResourceUuids(CollectionDSL.list(inv.getResourceUuid())); - completion.success(result); + completion.success(new TrashCleanupResult(inv.getResourceUuid(), inv.getTrashId(), inv.getSize())); } }).error(new FlowErrorHandler(completion) { @Override @@ -1890,23 +1866,33 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } - private void cleanUpTrash(Long trashId, final ReturnValueCompletion completion) { + private void cleanUpTrash(Long trashId, final ReturnValueCompletion> completion) { if (trashId != null) { - cleanTrash(trashId, completion); + cleanTrash(trashId, new ReturnValueCompletion(completion) { + @Override + public void success(TrashCleanupResult res) { + completion.success(CollectionDSL.list(res)); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); return; } - CleanTrashResult result = new CleanTrashResult(); + List results = Collections.synchronizedList(new ArrayList<>()); List trashs = trash.getTrashList(self.getUuid(), trashLists); if (trashs.isEmpty()) { - completion.success(result); + completion.success(results); return; } new While<>(trashs).step((inv, coml) -> { String details = trash.makeSureInstallPathNotUsed(inv); if (details != null) { - result.getDetails().add(details); + results.add(new TrashCleanupResult(inv.getResourceUuid(), inv.getTrashId(), operr(details))); coml.done(); return; } @@ -1938,6 +1924,7 @@ public void run(FlowTrigger trigger, Map data) { DeleteVolumeBitsOnPrimaryStorageMsg msg = new DeleteVolumeBitsOnPrimaryStorageMsg(); msg.setPrimaryStorageUuid(self.getUuid()); msg.setInstallPath(inv.getInstallPath()); + msg.setSize(inv.getSize()); bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, self.getUuid()); bus.send(msg, new CloudBusCallBack(trigger) { @Override @@ -1946,6 +1933,7 @@ public void run(MessageReply reply) { logger.info(String.format("Deleted volume %s in Trash.", inv.getInstallPath())); } else { logger.warn(String.format("Failed to delete volume %s in Trash.", inv.getInstallPath())); + submitCephDeleteVolumeGC(inv, self); } trigger.next(); } @@ -1963,8 +1951,7 @@ public void handle(Map data) { bus.send(imsg); logger.info(String.format("Returned space[size:%s] to PS %s after volume migration", inv.getSize(), self.getUuid())); - result.getResourceUuids().add(inv.getResourceUuid()); - updateTrashSize(result, inv.getSize()); + results.add(new TrashCleanupResult(inv.getResourceUuid(), inv.getTrashId(), inv.getSize())); trash.removeFromDb(inv.getTrashId()); coml.done(); } @@ -1979,7 +1966,7 @@ public void handle(ErrorCode errCode, Map data) { @Override public void done(ErrorCodeList errorCodeList) { if (errorCodeList.getCauses().isEmpty()) { - completion.success(result); + completion.success(results); } else { completion.fail(errorCodeList.getCauses().get(0)); } @@ -1987,6 +1974,18 @@ public void done(ErrorCodeList errorCodeList) { }); } + private void submitCephDeleteVolumeGC(InstallPathRecycleInventory inv, PrimaryStorageVO self) { + CephDeleteVolumeGC gc = new CephDeleteVolumeGC(); + gc.NAME = String.format("gc-ceph-%s-volume-path-%s", self.getUuid(), inv.getInstallPath()); + gc.primaryStorageUuid = self.getUuid(); + VolumeInventory volume = new VolumeInventory(); + volume.setUuid(inv.getResourceUuid()); + volume.setInstallPath(inv.getInstallPath()); + volume.setSize(inv.getSize()); + gc.volume = volume; + gc.deduplicateSubmit(CephGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); + } + protected void handle(final CleanUpTrashOnPrimaryStroageMsg msg) { MessageReply reply = new MessageReply(); thdf.chainSubmit(new ChainTask(msg) { @@ -1999,9 +1998,9 @@ public String getSyncSignature() { @Override public void run(SyncTaskChain chain) { - cleanUpTrash(msg.getTrashId(), new ReturnValueCompletion(msg) { + cleanUpTrash(msg.getTrashId(), new ReturnValueCompletion>(msg) { @Override - public void success(CleanTrashResult returnValue) { + public void success(List returnValues) { bus.reply(msg, reply); chain.next(); } @@ -2078,14 +2077,14 @@ public String getSyncSignature() { @Override public void run(SyncTaskChain chain) { - cleanUpTrash(msg.getTrashId(), new ReturnValueCompletion(chain) { + cleanUpTrash(msg.getTrashId(), new ReturnValueCompletion>(chain) { @Override - public void success(CleanTrashResult result) { - evt.setResult(result); + public void success(List results) { + evt.setResult(TrashCleanupResult.buildCleanTrashResult(results)); + evt.setResults(results); bus.publish(evt); chain.next(); } - @Override public void fail(ErrorCode errorCode) { evt.setError(errorCode); @@ -2102,10 +2101,40 @@ public String getName() { }); } + protected void handle(final APICleanUpStorageTrashOnPrimaryStorageMsg msg) { + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature("cleanup-ceph-trash-for-ps-" + msg.getPrimaryStorageUuid()) + .run(comp -> { + cleanUpStorageTrash(new ReturnValueCompletion(comp) { + @Override + public void success(Map result) { + comp.success(result); + } + + @Override + public void fail(ErrorCode errorCode) { + comp.fail(errorCode); + } + }, msg.isForce()); + }) + .done(result -> { + APICleanUpStorageTrashOnPrimaryStorageEvent event = new APICleanUpStorageTrashOnPrimaryStorageEvent(msg.getId()); + if (result.isSuccess()) { + Map> res = (Map>) result.getResult(); + event.setResult(res); + event.setTotal(res.values().stream().mapToInt(List::size).sum()); + bus.publish(event); + } else { + event.setError(result.getErrorCode()); + bus.publish(event); + } + })); + } + @Override protected void handle(APICleanUpImageCacheOnPrimaryStorageMsg msg) { APICleanUpImageCacheOnPrimaryStorageEvent evt = new APICleanUpImageCacheOnPrimaryStorageEvent(msg.getId()); - imageCacheCleaner.cleanup(msg.getUuid(), false); + imageCacheCleaner.cleanup(msg.getUuid(), new ImageCacheCleanParam(true, msg.isForce())); bus.publish(evt); } @@ -2121,6 +2150,7 @@ protected void handle(final InstantiateVolumeOnPrimaryStorageMsg msg) { class DownloadToCache { ImageSpec image; VolumeSnapshotInventory snapshot; + boolean incremental; private void doDownload(final ReturnValueCompletion completion) { ImageCacheVO cache = Q.New(ImageCacheVO.class) .eq(ImageCacheVO_.primaryStorageUuid, self.getUuid()) @@ -2136,6 +2166,7 @@ private void doDownload(final ReturnValueCompletion completion) { String cachePath; String snapshotPath; long actualSize = image.getInventory().getActualSize(); + String allocatedInstall; @Override public void setup() { @@ -2146,7 +2177,7 @@ public void setup() { @Override public void run(final FlowTrigger trigger, Map data) { - AllocatePrimaryStorageMsg amsg = new AllocatePrimaryStorageMsg(); + AllocatePrimaryStorageSpaceMsg amsg = new AllocatePrimaryStorageSpaceMsg(); amsg.setRequiredPrimaryStorageUuid(self.getUuid()); amsg.setSize(image.getInventory().getActualSize()); amsg.setPurpose(PrimaryStorageAllocationPurpose.DownloadImage.toString()); @@ -2160,6 +2191,8 @@ public void run(MessageReply reply) { trigger.fail(reply.getError()); } else { s = true; + AllocatePrimaryStorageSpaceReply ar = (AllocatePrimaryStorageSpaceReply) reply; + allocatedInstall = ar.getAllocatedInstallUrl(); trigger.next(); } } @@ -2169,12 +2202,13 @@ public void run(MessageReply reply) { @Override public void rollback(FlowRollback trigger, Map data) { if (s) { - IncreasePrimaryStorageCapacityMsg imsg = new IncreasePrimaryStorageCapacityMsg(); - imsg.setNoOverProvisioning(true); - imsg.setPrimaryStorageUuid(self.getUuid()); - imsg.setDiskSize(image.getInventory().getActualSize()); - bus.makeLocalServiceId(imsg, PrimaryStorageConstant.SERVICE_ID); - bus.send(imsg); + ReleasePrimaryStorageSpaceMsg rmsg = new ReleasePrimaryStorageSpaceMsg(); + rmsg.setNoOverProvisioning(true); + rmsg.setAllocatedInstallUrl(allocatedInstall); + rmsg.setPrimaryStorageUuid(self.getUuid()); + rmsg.setDiskSize(image.getInventory().getActualSize()); + bus.makeLocalServiceId(rmsg, PrimaryStorageConstant.SERVICE_ID); + bus.send(rmsg); } trigger.rollback(); @@ -2185,52 +2219,86 @@ public void rollback(FlowRollback trigger, Map data) { String __name__ = "download-from-" + (snapshot != null ? "volume" : "backup-storage"); boolean deleteOnRollback; + String dstPath; @Override public void run(final FlowTrigger trigger, Map data) { + dstPath = makeVolumeInstallPathByTargetPool(image.getInventory().getUuid(), + getTargetPoolNameFromAllocatedUrl(allocatedInstall)); if (snapshot != null) { - deleteOnRollback = true; - CpCmd cmd = new CpCmd(); - cmd.srcPath = snapshot.getPrimaryStorageInstallPath(); - cmd.dstPath = makeCacheInstallPath(image.getInventory().getUuid()); - cmd.shareable = false; - httpCall(CP_PATH, cmd, CpRsp.class, new ReturnValueCompletion(completion) { - @Override - public void success(CpRsp rsp) { - if (rsp.actualSize != null) { - actualSize = rsp.actualSize; - } - cachePath = rsp.installPath; - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); + if (incremental) { + incrementalCreateFromVolumeSnapshot(trigger); + } else { + createFromVolumeSnapshot(trigger); + } } else { - MediatorDowloadParam param = new MediatorDowloadParam(); - param.setImage(image); - param.setInstallPath(makeCacheInstallPath(image.getInventory().getUuid())); - param.setPrimaryStorageUuid(self.getUuid()); - BackupStorageMediator mediator = getBackupStorageMediator(image.getSelectedBackupStorage().getBackupStorageUuid()); - mediator.param = param; - - deleteOnRollback = mediator.deleteWhenRollbackDownload(); - mediator.download(new ReturnValueCompletion(trigger) { - @Override - public void success(String path) { - cachePath = path; - trigger.next(); + downloadFromBackupStorage(trigger); + } + } + + private void incrementalCreateFromVolumeSnapshot(FlowTrigger trigger) { + cloneAndProtectSnaphost(snapshot.getPrimaryStorageInstallPath(), dstPath, new ReturnValueCompletion(trigger) { + @Override + public void success(CloneRsp rsp) { + if (rsp.actualSize != null) { + actualSize = rsp.actualSize; } + cachePath = rsp.installPath; + trigger.next(); + } - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + + private void createFromVolumeSnapshot(FlowTrigger trigger) { + deleteOnRollback = true; + CpCmd cmd = new CpCmd(); + cmd.srcPath = snapshot.getPrimaryStorageInstallPath(); + cmd.dstPath = dstPath; + cmd.shareable = false; + httpCall(CP_PATH, cmd, CpRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(CpRsp rsp) { + if (rsp.actualSize != null) { + actualSize = rsp.actualSize; } - }); - } + cachePath = rsp.installPath; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + private void downloadFromBackupStorage(FlowTrigger trigger) { + MediatorDownloadParam param = new MediatorDownloadParam(); + param.setImage(image); + param.setInstallPath(dstPath); + param.setPrimaryStorageUuid(self.getUuid()); + BackupStorageMediator mediator = getBackupStorageMediator(image.getSelectedBackupStorage().getBackupStorageUuid()); + mediator.param = param; + + deleteOnRollback = mediator.deleteWhenRollbackDownload(); + mediator.download(new ReturnValueCompletion(trigger) { + @Override + public void success(String path) { + cachePath = path; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); } @Override @@ -2327,10 +2395,13 @@ public void fail(ErrorCode errorCode) { } }); - done(new FlowDoneHandler(completion) { + flow(new Flow() { + String __name__ = "persist-db"; + + ImageCacheVO cvo = new ImageCacheVO(); + @Override - public void handle(Map data) { - ImageCacheVO cvo = new ImageCacheVO(); + public void run(final FlowTrigger trigger, Map data) { cvo.setMd5sum("not calculated"); cvo.setSize(image.getInventory().getActualSize()); cvo.setInstallUrl(snapshotPath); @@ -2340,12 +2411,53 @@ public void handle(Map data) { cvo.setState(ImageCacheState.ready); cvo.setSize(actualSize); cvo = dbf.persistAndRefresh(cvo); + data.put(ImageCacheVO.class.getSimpleName(),cvo); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + dbf.remove(cvo); + trigger.rollback(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "save-encryption-Integrity-after-create-image-cache"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + ImageCacheVO finalCvo = (ImageCacheVO) (data.get(ImageCacheVO.class.getSimpleName())); + new While<>(pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class)).each((ext, whileCompletion) -> { + ext.saveEncryptAfterCreateImageCache(null, ImageCacheInventory.valueOf(finalCvo), new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } - ImageCacheVO finalCvo = cvo; - pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class) - .forEach(exp -> exp.saveEncryptAfterCreateImageCache(null, ImageCacheInventory.valueOf(finalCvo))); + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(operr(String.format("failed to saveEncryptAfterCreateImageCache: %s", errorCodeList.getCauses().get(0)))); + return; + } + trigger.next(); + } + }); + } + }); - completion.success(cvo); + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success((ImageCacheVO) (data.get(ImageCacheVO.class.getSimpleName()))); } }); @@ -2400,7 +2512,7 @@ public void run(final SyncTaskChain chain) { if (cache != null) { final CheckIsBitsExistingCmd cmd = new CheckIsBitsExistingCmd(); - cmd.setInstallPath(cache.getInstallUrl()); + cmd.setInstallPath(ImageCacheUtil.getImageCachePath(cache.toInventory())); httpCall(CHECK_BITS_PATH, cmd, CheckIsBitsExistingRsp.class, new ReturnValueCompletion(chain) { @Override public void success(CheckIsBitsExistingRsp returnValue) { @@ -2472,16 +2584,16 @@ public String getName() { private void createVolumeFromTemplate(final InstantiateRootVolumeFromTemplateOnPrimaryStorageMsg msg) { final InstantiateVolumeOnPrimaryStorageReply reply = new InstantiateVolumeOnPrimaryStorageReply(); - - String targetCephPoolName = getRootVolumeTargetPoolName(msg.getVolume().getUuid()); - checkCephPoolCapacityForNewVolume(targetCephPoolName, msg.getVolume().getSize()); + final VmInstanceSpec.ImageSpec ispec = msg.getTemplateSpec(); + String targetCephPoolName = getTargetPoolNameFromAllocatedUrl(msg.getAllocatedInstallUrl()); FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("create-root-volume-%s", msg.getVolume().getUuid())); chain.then(new ShareFlow() { String cloneInstallPath; - String volumePath = makeRootVolumeInstallPath(msg.getVolume().getUuid()); + String volumePath = makeVolumeInstallPathByTargetPool(msg.getVolume().getUuid(), targetCephPoolName); ImageCacheInventory cache; + Long actualSize; @Override public void setup() { @@ -2493,7 +2605,7 @@ public void run(final FlowTrigger trigger, Map data) { DownloadVolumeTemplateToPrimaryStorageMsg dmsg = new DownloadVolumeTemplateToPrimaryStorageMsg(); dmsg.setPrimaryStorageUuid(msg.getPrimaryStorageUuid()); dmsg.setHostUuid(msg.getDestHost().getUuid()); - dmsg.setTemplateSpec(msg.getTemplateSpec()); + dmsg.setTemplateSpec(ispec); bus.makeTargetServiceIdByResourceUuid(dmsg, PrimaryStorageConstant.SERVICE_ID, dmsg.getPrimaryStorageUuid()); bus.send(dmsg, new CloudBusCallBack(trigger) { @Override @@ -2504,7 +2616,7 @@ public void run(MessageReply reply) { } cache = ((DownloadVolumeTemplateToPrimaryStorageReply) reply).getImageCache(); - cloneInstallPath = cache.getInstallUrl(); + cloneInstallPath = ImageCacheUtil.getImageCachePath(cache); trigger.next(); } }); @@ -2529,23 +2641,50 @@ public void fail(ErrorCode err) { @Override public void success(CloneRsp ret) { - if (StringUtils.isNotEmpty(ret.getInstallPath()) && - !ret.getInstallPath().equals(volumePath)) { - volumePath = makeRootVolumeInstallPath(msg.getVolume().getUuid(), ret.getInstallPath()); - } - + actualSize = ret.actualSize; trigger.next(); } }); } }); + flow(new NoRollbackFlow() { + String __name__ = "resize-volume-on-primary-storage"; + + @Override + public boolean skip(Map data) { + ImageInventory image = ispec.getInventory(); + return image.getSize() >= msg.getVolume().getSize(); + } + + @Override + public void run(final FlowTrigger trigger, Map data) { + ResizeVolumeOnPrimaryStorageMsg rmsg = new ResizeVolumeOnPrimaryStorageMsg(); + rmsg.setVolume(msg.getVolume()); + rmsg.setSize(msg.getVolume().getSize()); + rmsg.setPrimaryStorageUuid(msg.getVolume().getPrimaryStorageUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, PrimaryStorageConstant.SERVICE_ID, msg.getVolume().getPrimaryStorageUuid()); + bus.send(rmsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + trigger.next(); + } else { + trigger.fail(reply.getError()); + } + } + }); + trigger.next(); + } + }); + done(new FlowDoneHandler(msg) { @Override public void handle(Map data) { VolumeInventory vol = msg.getVolume(); vol.setInstallPath(volumePath); vol.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + vol.setActualSize(actualSize); reply.setVolume(vol); ImageCacheVolumeRefVO ref = new ImageCacheVolumeRefVO(); @@ -2582,6 +2721,7 @@ public void done() { } protected void deleteVolumeOnPrimaryStorage(final DeleteVolumeOnPrimaryStorageMsg msg, final NoErrorCompletion completion) { + msg.getVolume().getUuid(); DeleteCmd cmd = new DeleteCmd(); cmd.installPath = msg.getVolume().getInstallPath(); @@ -2590,6 +2730,13 @@ protected void deleteVolumeOnPrimaryStorage(final DeleteVolumeOnPrimaryStorageMs httpCall(DELETE_PATH, cmd, DeleteRsp.class, new ReturnValueCompletion(msg) { @Override public void fail(ErrorCode err) { + if (err.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete volume[uuid:%s] right now, skip this GC job because it's in use", msg.getVolume().getUuid())); + reply.setError(err); + bus.reply(msg, reply); + completion.done(); + return; + } CephDeleteVolumeGC gc = new CephDeleteVolumeGC(); gc.NAME = String.format("gc-ceph-%s-volume-%s", self.getUuid(), msg.getVolume().getUuid()); gc.primaryStorageUuid = self.getUuid(); @@ -2602,6 +2749,7 @@ public void fail(ErrorCode err) { @Override public void success(DeleteRsp ret) { + osdHelper.releaseAvailableCapWithRatio(msg.getVolume().getInstallPath(), msg.getVolume().getSize()); bus.reply(msg, reply); completion.done(); } @@ -2779,14 +2927,41 @@ public void handle(ErrorCode errCode, Map data) { protected void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg) { CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply reply = new CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply(); + boolean incremental = msg.hasSystemTag(VolumeSystemTags.FAST_CREATE.getTagFormat()); + if (incremental && PrimaryStorageGlobalProperty.USE_SNAPSHOT_AS_INCREMENTAL_CACHE) { + ProtectSnapshotCmd cmd = new ProtectSnapshotCmd(); + cmd.snapshotPath = msg.getVolumeSnapshot().getPrimaryStorageInstallPath(); + cmd.ignoreError = true; + httpCall(PROTECT_SNAPSHOT_PATH, cmd, ProtectSnapshotRsp.class, new ReturnValueCompletion(msg) { + @Override + public void success(ProtectSnapshotRsp returnValue) { + ImageCacheVO cache = createTemporaryImageCacheFromVolumeSnapshot(msg.getImageInventory(), msg.getVolumeSnapshot()); + dbf.persist(cache); + reply.setInventory(cache.toInventory()); + reply.setIncremental(true); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + return; + } + DownloadToCache cache = new DownloadToCache(); cache.image = new ImageSpec(); cache.image.setInventory(msg.getImageInventory()); cache.snapshot = msg.getVolumeSnapshot(); + cache.incremental = incremental; cache.download(new ReturnValueCompletion(msg) { @Override - public void success(ImageCacheVO cache) { + public void success(ImageCacheVO inv) { reportProgress(getTaskStage().getEnd().toString()); + reply.setIncremental(cache.incremental); + reply.setInventory(inv.toInventory()); bus.reply(msg, reply); } @@ -2806,7 +2981,8 @@ protected void handle(final CreateTemplateFromVolumeOnPrimaryStorageMsg msg) { final CreateTemplateFromVolumeOnPrimaryStorageReply reply = new CreateTemplateFromVolumeOnPrimaryStorageReply(); final TaskProgressRange parentStage = getTaskStage(); final TaskProgressRange CREATE_SNAPSHOT_STAGE = new TaskProgressRange(0, 10); - final TaskProgressRange CREATE_IMAGE_STAGE = new TaskProgressRange(10, 100); + final TaskProgressRange CREATE_IMAGE_STAGE = new TaskProgressRange(10, 90); + final TaskProgressRange UNDO_SNAPSHOT_CREATION_STAGE = new TaskProgressRange(90, 100); checkCephFsId(msg.getPrimaryStorageUuid(), msg.getBackupStorageUuid()); @@ -2824,9 +3000,19 @@ protected void handle(final CreateTemplateFromVolumeOnPrimaryStorageMsg msg) { @Override public void setup() { - flow(new NoRollbackFlow() { + flow(new Flow() { String __name__ = "create-volume-snapshot"; + @Override + public boolean skip(Map data) { + if (msg instanceof CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg) { + CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg vsmsg = (CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg) msg; + VolumeSnapshotVO snapshotVO = dbf.findByUuid(vsmsg.getSnapshotUuid(), VolumeSnapshotVO.class); + snapshot = VolumeSnapshotInventory.valueOf(snapshotVO); + return true; + } + return false; + } @Override public void run(final FlowTrigger trigger, Map data) { String volumeAccountUuid = acntMgr.getOwnerAccountUuidOfResource(volumeUuid); @@ -2863,6 +3049,28 @@ public void run(MessageReply r) { }); } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (msg instanceof CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg || + !PrimaryStorageGlobalConfig.UNDO_TEMP_SNAPSHOT.value(Boolean.class)) { + trigger.rollback(); + return; + } + VolumeSnapshotDeletionMsg dmsg = new VolumeSnapshotDeletionMsg(); + dmsg.setTreeUuid(snapshot.getTreeUuid()); + dmsg.setVolumeUuid(snapshot.getVolumeUuid()); + dmsg.setSnapshotUuid(snapshot.getUuid()); + dmsg.setDirection(DeleteVolumeSnapshotDirection.Commit.toString()); + dmsg.setScope(DeleteVolumeSnapshotScope.Single.toString()); + bus.makeTargetServiceIdByResourceUuid(dmsg, VolumeSnapshotConstant.SERVICE_ID, snapshot.getUuid()); + bus.send(dmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + trigger.rollback(); + } + }); + } }); flow(new NoRollbackFlow() { @@ -2901,6 +3109,41 @@ public void run(MessageReply r) { } }); + flow(new NoRollbackFlow() { + String __name__ = "delete-temp-snapshot"; + + @Override + public boolean skip(Map data) { + return msg instanceof CreateTemplateFromVolumeSnapshotOnPrimaryStorageMsg || + !PrimaryStorageGlobalConfig.UNDO_TEMP_SNAPSHOT.value(Boolean.class); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + TaskProgressRange stage = markTaskStage(parentStage, UNDO_SNAPSHOT_CREATION_STAGE); + + VolumeSnapshotDeletionMsg dmsg = new VolumeSnapshotDeletionMsg(); + dmsg.setTreeUuid(snapshot.getTreeUuid()); + dmsg.setVolumeUuid(snapshot.getVolumeUuid()); + dmsg.setSnapshotUuid(snapshot.getUuid()); + dmsg.setScope(DeleteVolumeSnapshotScope.Single.toString()); + dmsg.setDirection(DeleteVolumeSnapshotDirection.Commit.toString()); + bus.makeTargetServiceIdByResourceUuid(dmsg, VolumeSnapshotConstant.SERVICE_ID, snapshot.getUuid()); + bus.send(dmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + + reportProgress(stage.getEnd().toString()); + trigger.next(); + } + }); + } + }); + done(new FlowDoneHandler(msg) { @Override public void handle(Map data) { @@ -2974,9 +3217,10 @@ protected void downloadDataVolumeToPrimaryStorage(final DownloadDataVolumeToPrim ImageSpec spec = new ImageSpec(); spec.setInventory(msg.getImage()); spec.setSelectedBackupStorage(msg.getBackupStorageRef()); - MediatorDowloadParam param = new MediatorDowloadParam(); + MediatorDownloadParam param = new MediatorDownloadParam(); param.setImage(spec); - param.setInstallPath(makeDataVolumeInstallPath(msg.getVolumeUuid())); + param.setInstallPath(makeVolumeInstallPathByTargetPool(msg.getVolumeUuid(), + getTargetPoolNameFromAllocatedUrl(msg.getAllocatedInstallUrl()))); param.setPrimaryStorageUuid(self.getUuid()); param.setShareable(dbf.findByUuid(msg.getVolumeUuid(), VolumeVO.class).isShareable()); mediator.param = param; @@ -3001,7 +3245,8 @@ public void fail(ErrorCode errorCode) { @Override protected void handle(GetInstallPathForDataVolumeDownloadMsg msg) { GetInstallPathForDataVolumeDownloadReply reply = new GetInstallPathForDataVolumeDownloadReply(); - reply.setInstallPath(makeDataVolumeInstallPath(msg.getVolumeUuid())); + reply.setInstallPath(makeVolumeInstallPathByTargetPool(msg.getVolumeUuid(), + getTargetPoolNameFromAllocatedUrl(msg.getAllocatedInstallUrl()))); bus.reply(msg, reply); } @@ -3033,6 +3278,7 @@ public void fail(ErrorCode err) { @Override public void success(DeleteRsp ret) { + osdHelper.releaseAvailableCapWithRatio(msg.getInstallPath(), msg.getSize()); bus.reply(msg, reply); completion.done(); } @@ -3074,6 +3320,8 @@ protected void handle(AskVolumeSnapshotCapabilityMsg msg) { if (VolumeType.Data.toString().equals(volumeType) || VolumeType.Root.toString().equals(volumeType)) { cap.setSupport(true); cap.setArrangementType(VolumeSnapshotArrangementType.INDIVIDUAL); + cap.setPlacementType(VolumeSnapshotCapability.VolumeSnapshotPlacementType.INTERNAL); + cap.setVolumePathFromInternalSnapshotRegex("^[^@]+"); } else if (VolumeType.Memory.toString().equals(volumeType)) { cap.setSupport(false); } else { @@ -3086,9 +3334,64 @@ protected void handle(AskVolumeSnapshotCapabilityMsg msg) { @Override protected void handle(SyncVolumeSizeOnPrimaryStorageMsg msg) { - inQueue().name(String.format("sync-volume-size-on-primarystorage-%s", self.getUuid())) + SyncVolumeSizeOnPrimaryStorageReply reply = new SyncVolumeSizeOnPrimaryStorageReply(); + syncVolumeSize(msg.getVolumeUuid(), msg.getInstallPath(), new ReturnValueCompletion(msg) { + @Override + public void success(GetVolumeSizeRsp rsp) { + markVolumeActualSize(msg.getVolumeUuid(), rsp.actualSize); + + // some ceph version has no way to get actual size + long asize = rsp.actualSize != null ? rsp.actualSize : Q.New(VolumeVO.class) + .select(VolumeVO_.actualSize) + .eq(VolumeVO_.uuid, msg.getVolumeUuid()) + .findValue(); + reply.setActualSize(asize); + reply.setSize(rsp.size); + reply.setWithInternalSnapshot(true); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg) { + EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + // TODO: estimate template size + syncVolumeSize(msg.getVolumeUuid(), msg.getInstallPath(), new ReturnValueCompletion(msg) { + @Override + public void success(GetVolumeSizeRsp rsp) { + markVolumeActualSize(msg.getVolumeUuid(), rsp.actualSize); + + // some ceph version has no way to get actual size + long asize = rsp.actualSize != null ? rsp.actualSize : Q.New(VolumeVO.class) + .select(VolumeVO_.actualSize) + .eq(VolumeVO_.uuid, msg.getVolumeUuid()) + .findValue(); + reply.setActualSize(asize); + reply.setSize(rsp.size); + reply.setWithInternalSnapshot(true); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(BatchSyncVolumeSizeOnPrimaryStorageMsg msg) { + inQueue().name(String.format("batch-sync-volume-size-on-primarystorage-%s", self.getUuid())) .asyncBackup(msg) - .run(chain -> syncVolumeSizeOnPrimaryStorage(msg, new NoErrorCompletion(chain) { + .run(chain -> BatchSyncVolumeSizeOnPrimaryStorage(msg, new NoErrorCompletion(chain) { @Override public void done() { chain.next(); @@ -3096,26 +3399,35 @@ public void done() { })); } - protected void syncVolumeSizeOnPrimaryStorage(final SyncVolumeSizeOnPrimaryStorageMsg msg, final NoErrorCompletion completion) { + protected void syncVolumeSize(String volumeUuid, String installPath, final ReturnValueCompletion completion) { final SyncVolumeSizeOnPrimaryStorageReply reply = new SyncVolumeSizeOnPrimaryStorageReply(); - final VolumeVO vol = dbf.findByUuid(msg.getVolumeUuid(), VolumeVO.class); - - String installPath = vol.getInstallPath(); GetVolumeSizeCmd cmd = new GetVolumeSizeCmd(); cmd.fsId = getSelf().getFsid(); cmd.uuid = self.getUuid(); - cmd.volumeUuid = msg.getVolumeUuid(); + cmd.volumeUuid = volumeUuid; cmd.installPath = installPath; - httpCall(GET_VOLUME_SIZE_PATH, cmd, GetVolumeSizeRsp.class, new ReturnValueCompletion(msg) { + httpCall(GET_VOLUME_SIZE_PATH, cmd, GetVolumeSizeRsp.class, completion); + } + + private void BatchSyncVolumeSizeOnPrimaryStorage(BatchSyncVolumeSizeOnPrimaryStorageMsg msg, NoErrorCompletion completion) { + BatchSyncVolumeSizeOnPrimaryStorageReply reply = new BatchSyncVolumeSizeOnPrimaryStorageReply(); + + GetBatchVolumeSizeCmd cmd = new GetBatchVolumeSizeCmd(); + cmd.volumeUuidInstallPaths = msg.getVolumeUuidInstallPaths(); + cmd.fsId = getSelf().getFsid(); + cmd.uuid = self.getUuid(); + + httpCall(BATCH_GET_VOLUME_SIZE_PATH, cmd, GetBatchVolumeSizeRsp.class, new ReturnValueCompletion(msg) { @Override - public void success(GetVolumeSizeRsp rsp) { - markVolumeActualSize(vol.getUuid(), rsp.actualSize); + public void success(GetBatchVolumeSizeRsp rsp) { + for (Map.Entry e : rsp.actualSizes.entrySet()) { + String volumeUuid = e.getKey(); + Long actualSize = e.getValue(); + markVolumeActualSize(volumeUuid, actualSize); + } - // current ceph has no way to get actual size - long asize = rsp.actualSize == null ? vol.getActualSize() : rsp.actualSize; - reply.setActualSize(asize); - reply.setSize(rsp.size); + reply.setActualSizes(rsp.actualSizes); bus.reply(msg, reply); completion.done(); } @@ -3127,6 +3439,7 @@ public void fail(ErrorCode errorCode) { completion.done(); } }); + } private void markVolumeActualSize(String volumeUuid, Long actualSize) { @@ -3157,8 +3470,9 @@ protected void httpCall(final String path, final Agent new HttpCaller<>(path, cmd, retClass, callback, unit, timeout).call(); } - protected class HttpCaller { + public class HttpCaller { private Iterator it; + private final List monVOs; private final ErrorCodeList errorCodes = new ErrorCodeList(); private final String path; @@ -3168,32 +3482,36 @@ protected class HttpCaller { private final TimeUnit unit; private final long timeout; - private String randomFactor = null; private boolean tryNext = false; - private List avoidMonUuids = null; - HttpCaller(String path, AgentCommand cmd, Class retClass, ReturnValueCompletion callback) { + public HttpCaller(String path, AgentCommand cmd, Class retClass, ReturnValueCompletion callback) { this(path, cmd, retClass, callback, null, 0); } - HttpCaller(String path, AgentCommand cmd, Class retClass, ReturnValueCompletion callback, TimeUnit unit, long timeout) { + public HttpCaller(String path, AgentCommand cmd, Class retClass, ReturnValueCompletion callback, TimeUnit unit, long timeout) { this.path = path; this.cmd = cmd; this.retClass = retClass; this.callback = callback; this.unit = unit; this.timeout = timeout; + this.monVOs = prepareMons(); } - void call() { - it = prepareMons().iterator(); + public void call() { + prepareMonsIterator(); prepareCmd(); doCall(); } // specify mons order by randomFactor to ensure that the same mon receive cmd every time. HttpCaller specifyOrder(String randomFactor) { - this.randomFactor = randomFactor; + CollectionUtils.shuffleByKeySeed(monVOs, randomFactor, ResourceVO::getUuid); + return this; + } + + HttpCaller specifyOrder(Comparator c) { + monVOs.sort(c); return this; } @@ -3203,49 +3521,42 @@ HttpCaller tryNext() { } HttpCaller setAvoidMonUuids(List avoidMonUuids) { - this.avoidMonUuids = avoidMonUuids; + if (monVOs.size() > 1 && avoidMonUuids != null) { + monVOs.removeIf(it -> avoidMonUuids.contains(it.getUuid())); + } return this; } private void prepareCmd() { + if (cmd instanceof DeleteCmd) { + ((DeleteCmd) cmd).setExpirationTime(CephGlobalConfig.IMAGE_EXPIRATION_TIME.value(Long.class)); + } cmd.setUuid(self.getUuid()); cmd.setFsId(getSelf().getFsid()); - if (CephSystemTags.THIRDPARTY_PLATFORM.hasTag(self.getUuid())) { - cmd.setToken(CephSystemTags.THIRDPARTY_PLATFORM.getTokenByResourceUuid(self.getUuid(), - CephSystemTags.THIRDPARTY_PLATFORM_TOKEN)); - cmd.setTpTimeout(CephGlobalConfig.THIRD_PARTY_SDK_TIMEOUT.value(String.class)); - } } - private List prepareMons() { - final List mons = new ArrayList(); - for (CephPrimaryStorageMonVO monvo : getSelf().getMons()) { - mons.add(new CephPrimaryStorageMonBase(monvo)); - } + private List prepareMons() { + final List mons = new ArrayList<>(getSelf().getMons()); - if (randomFactor != null) { - CollectionUtils.shuffleByKeySeed(mons, randomFactor, it -> it.getSelf().getUuid()); - } else { - Collections.shuffle(mons); - } + Collections.shuffle(mons); - mons.removeIf(it -> it.getSelf().getStatus() != MonStatus.Connected); + mons.removeIf(it -> it.getStatus() != MonStatus.Connected); if (mons.isEmpty()) { throw new OperationFailureException(operr( "all ceph mons of primary storage[uuid:%s] are not in Connected state", self.getUuid()) ); } - if (mons.size() > 1 && avoidMonUuids != null) { - mons.removeIf(it -> avoidMonUuids.contains(it.getSelf().getUuid())); - } - return mons; } + private void prepareMonsIterator() { + it = monVOs.stream().map(CephPrimaryStorageMonBase::new).collect(Collectors.toList()).iterator(); + } + private void doCall() { if (!it.hasNext()) { - callback.fail(operr(errorCodes, "all mons failed to execute http call[%s], errors are %s", path) + callback.fail(operr(errorCodes, "all monitors cannot execute http call[%s]", path) ); return; @@ -3258,27 +3569,29 @@ private void doCall() { ReturnValueCompletion completion = new ReturnValueCompletion(callback) { @Override public void success(T ret) { - if (!ret.success) { - if (tryNext) { - doCall(); - } else { - callback.fail(operr("operation error, because:%s", ret.error)); - } - return; - } - if (!(cmd instanceof InitCmd)) { updateCapacityIfNeeded(ret); } + callback.success(ret); } @Override public void fail(ErrorCode errorCode) { - logger.warn(String.format("mon[%s] failed to execute http call[%s], error is: %s", - base.getSelf().getHostname(), path, JSONObjectUtil.toJsonString(errorCode))); - errorCodes.getCauses().add(errorCode); - doCall(); + if (!errorCode.isError(SysErrors.OPERATION_ERROR) && !errorCode.isError(VolumeErrors.VOLUME_IN_USE) + && !errorCode.isError(SysErrors.TIMEOUT)) { + logger.warn(String.format("mon[%s] failed to execute http call[%s], error is: %s", + base.getSelf().getHostname(), path, JSONObjectUtil.toJsonString(errorCode))); + errorCodes.getCauses().add(errorCode); + doCall(); + return; + } + + if (tryNext) { + doCall(); + } else { + callback.fail(errorCode); + } } }; @@ -3288,12 +3601,12 @@ public void fail(ErrorCode errorCode) { base.httpCall(path, cmd, retClass, completion, unit, timeout); } } - } - private void updateCapacityIfNeeded(AgentResponse rsp) { - if (rsp.totalCapacity != null && rsp.availableCapacity != null) { - CephCapacity cephCapacity = new CephCapacity(getSelf().getFsid(), rsp); - new CephCapacityUpdater().update(cephCapacity); + private void updateCapacityIfNeeded(AgentResponse rsp) { + if (rsp.totalCapacity != null && rsp.availableCapacity != null) { + CephCapacity cephCapacity = new CephCapacity(getSelf().getFsid(), rsp); + new CephCapacityUpdater().update(cephCapacity); + } } } @@ -3309,11 +3622,11 @@ void connect(final FlowTrigger trigger) { if (!it.hasNext()) { if (errorCodes.getCauses().size() == mons.size()) { if (errorCodes.getCauses().isEmpty()) { - trigger.fail(operr("unable to connect to the ceph primary storage[uuid:%s]." + - " Failed to connect all ceph mons.", self.getUuid())); + trigger.fail(operr("unable to connect to the ceph primary storage[uuid:%s]," + + " failed to connect all ceph monitors.", self.getUuid())); } else { - trigger.fail(operr(errorCodes, "unable to connect to the ceph primary storage[uuid:%s]." + - " Failed to connect all ceph mons. Errors are %s", + trigger.fail(operr(errorCodes, "unable to connect to the ceph primary storage[uuid:%s]," + + " failed to connect all ceph monitors.", self.getUuid())); } } else { @@ -3395,19 +3708,16 @@ public CephPrimaryStorageMonBase call(CephPrimaryStorageMonVO arg) { mon.httpCall(GET_FACTS, cmd, GetFactsRsp.class, new ReturnValueCompletion(compl) { @Override public void success(GetFactsRsp rsp) { - if (!rsp.success) { - // one mon cannot get the facts, directly error out - errors.add(Platform.operr("%s", rsp.getError())); - compl.allDone(); - return; - } - CephPrimaryStorageMonVO monVO = dbf.reload(mon.getSelf()); if (monVO != null) { fsids.put(monVO.getUuid(), rsp.fsid); monVO.setMonAddr(rsp.monAddr == null ? monVO.getHostname() : rsp.monAddr); dbf.update(monVO); - } + + if (rsp.ipAddresses != null) { + updateMonExtraIps(monVO, rsp.ipAddresses); + } + } compl.done(); } @@ -3556,6 +3866,7 @@ public void success(InitRsp ret) { CephCapacityUpdater updater = new CephCapacityUpdater(); CephCapacity cephCapacity = new CephCapacity(ret.fsid, ret); updater.update(cephCapacity, true); + osdHelper.recalculateAvailableCapacity(); createPrimaryStorageLicenseVendor(ret.getType()); trigger.next(); } @@ -3594,6 +3905,20 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } + private void updateMonExtraIps(CephPrimaryStorageMonVO mon, List ips) { + ips.remove(mon.getHostname()); + if (CoreGlobalProperty.MN_VIP != null) { + ips.remove(CoreGlobalProperty.MN_VIP); + } + if (ips.isEmpty()) { + CephMonSystemTags.EXTRA_IPS.delete(mon.getUuid()); + return; + } + recreateNonInherentTag( + CephMonSystemTags.EXTRA_IPS, CephMonSystemTags.EXTRA_IPS_TOKEN, + StringUtils.join(ips, ","), mon.getUuid()); + } + @Override protected void connectHook(ConnectParam param, final Completion completion) { connect(param.isNewAdded(), completion); @@ -3634,6 +3959,7 @@ public void done() { try { TimeUnit.SECONDS.sleep(CephGlobalConfig.PRIMARY_STORAGE_MON_RECONNECT_DELAY.value(Long.class)); } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); } } @@ -3655,6 +3981,7 @@ public void fail(ErrorCode errorCode) { } catch (Throwable t) { releaseLock.done(); logger.warn(t.getMessage(), t); + Thread.currentThread().interrupt(); } } @@ -3812,6 +4139,8 @@ protected void handleApiMessage(APIMessage msg) { handle((APIUpdateCephPrimaryStoragePoolMsg) msg); } else if (msg instanceof APICleanUpTrashOnPrimaryStorageMsg) { handle((APICleanUpTrashOnPrimaryStorageMsg) msg); + } else if (msg instanceof APICleanUpStorageTrashOnPrimaryStorageMsg) { + handle((APICleanUpStorageTrashOnPrimaryStorageMsg) msg); } else { super.handleApiMessage(msg); } @@ -3839,6 +4168,12 @@ private void handle(APIDeleteCephPrimaryStoragePoolMsg msg) { CephPrimaryStoragePoolVO vo = dbf.findByUuid(msg.getUuid(), CephPrimaryStoragePoolVO.class); dbf.remove(vo); + osdHelper.recalculateAvailableCapacity(); + + for(CephPrimaryStorageMonAfterModifiedExtensionPoint ext : pluginRgty.getExtensionList(CephPrimaryStorageMonAfterModifiedExtensionPoint.class)) { + ext.afterModified(getSelf()); + } + bus.publish(evt); } @@ -3877,6 +4212,12 @@ private void addCephPrimaryStoragePool(APIAddCephPrimaryStoragePoolMsg msg, fina httpCall(ADD_POOL_PATH, cmd, AddPoolRsp.class, new ReturnValueCompletion(msg) { @Override public void success(AddPoolRsp rsp) { + osdHelper.recalculateAvailableCapacity(); + + for(CephPrimaryStorageMonAfterModifiedExtensionPoint ext : pluginRgty.getExtensionList(CephPrimaryStorageMonAfterModifiedExtensionPoint.class)) { + ext.afterModified(getSelf()); + } + evt.setInventory(CephPrimaryStoragePoolInventory.valueOf(finalVo)); bus.publish(evt); completion.done(); @@ -4041,19 +4382,19 @@ public void done() { base.httpCall(GET_FACTS, cmd, GetFactsRsp.class, new ReturnValueCompletion(latch) { @Override public void success(GetFactsRsp rsp) { - if (!rsp.isSuccess()) { - errors.add(operr("operation error, because:%s", rsp.getError())); - } else { - String fsid = rsp.fsid; - if (!getSelf().getFsid().equals(fsid)) { - errors.add(operr("the mon[ip:%s] returns a fsid[%s] different from the current fsid[%s] of the cep cluster," + - "are you adding a mon not belonging to current cluster mistakenly?", base.getSelf().getHostname(), fsid, getSelf().getFsid()) - ); - } - CephPrimaryStorageMonVO monVO = dbf.reload(base.getSelf()); - if (monVO != null) { - monVO.setMonAddr(rsp.monAddr == null ? monVO.getHostname() : rsp.monAddr); - dbf.update(monVO); + String fsid = rsp.fsid; + if (!getSelf().getFsid().equals(fsid)) { + errors.add(operr("the mon[ip:%s] returns a fsid[%s] different from the current fsid[%s] of the cep cluster," + + "are you adding a mon not belonging to current cluster mistakenly?", base.getSelf().getHostname(), fsid, getSelf().getFsid()) + ); + } + CephPrimaryStorageMonVO monVO = dbf.reload(base.getSelf()); + if (monVO != null) { + monVO.setMonAddr(rsp.monAddr == null ? monVO.getHostname() : rsp.monAddr); + dbf.update(monVO); + + if (rsp.ipAddresses != null) { + updateMonExtraIps(monVO, rsp.ipAddresses); } } @@ -4093,6 +4434,18 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } + private void recreateNonInherentTag(SystemTag tag, String token, String value, String resourceUuid) { + recreateTag(tag, token, value, resourceUuid, false); + } + + private void recreateTag(SystemTag tag, String token, String value, String resourceUuid, boolean inherent) { + SystemTagCreator creator = tag.newSystemTagCreator(resourceUuid); + Optional.ofNullable(token).ifPresent(it -> creator.setTagByTokens(Collections.singletonMap(token, value))); + creator.inherent = inherent; + creator.recreate = true; + creator.create(); + } + @Override protected void handleLocalMessage(Message msg) { if (msg instanceof TakeSnapshotMsg) { @@ -4127,6 +4480,8 @@ protected void handleLocalMessage(Message msg) { handle((DownloadBitsFromKVMHostToPrimaryStorageMsg) msg); } else if (msg instanceof DownloadBitsFromNbdToPrimaryStorageMsg) { handle((DownloadBitsFromNbdToPrimaryStorageMsg) msg); + } else if (msg instanceof DownloadBitsFromRemoteTargetOnPrimaryStorageMsg) { + handle((DownloadBitsFromRemoteTargetOnPrimaryStorageMsg) msg); } else if (msg instanceof CancelDownloadBitsFromKVMHostToPrimaryStorageMsg) { handle((CancelDownloadBitsFromKVMHostToPrimaryStorageMsg) msg); } else if ((msg instanceof CleanUpTrashOnPrimaryStroageMsg)) { @@ -4137,7 +4492,15 @@ protected void handleLocalMessage(Message msg) { handle((GetDownloadBitsFromKVMHostProgressMsg) msg); } else if (msg instanceof GetVolumeWatchersMsg) { handle((GetVolumeWatchersMsg) msg); - }else { + } else if (msg instanceof GetVolumeBackingChainFromPrimaryStorageMsg) { + handle((GetVolumeBackingChainFromPrimaryStorageMsg) msg); + } else if (msg instanceof DeleteVolumeChainOnPrimaryStorageMsg) { + handle((DeleteVolumeChainOnPrimaryStorageMsg) msg); + } else if (msg instanceof GetPrimaryStorageUsageReportMsg) { + handle((GetPrimaryStorageUsageReportMsg) msg); + } else if (msg instanceof CleanUpStorageTrashOnPrimaryStorageMsg) { + handle((CleanUpStorageTrashOnPrimaryStorageMsg)msg); + } else { super.handleLocalMessage(msg); } @@ -4317,6 +4680,32 @@ public void fail(ErrorCode errorCode) { }); } + private void handle(DownloadBitsFromRemoteTargetOnPrimaryStorageMsg msg) { + DownloadBitsFromNbdToPrimaryStorageReply reply = new DownloadBitsFromNbdToPrimaryStorageReply(); + DownloadBitsFromRemoteTargetCmd cmd = new DownloadBitsFromRemoteTargetCmd(); + cmd.setSendCommandUrl(restf.getSendCommandUrl()); + cmd.setPrimaryStorageInstallPath(msg.getPrimaryStorageInstallPath()); + cmd.setRemoteTargetUri(msg.getRemoteTargetUri()); + + httpCall(DOWNLOAD_BITS_FROM_REMOTE_TARGET_PATH, cmd, DownloadBitsFromRemoteTargetRsp.class, new ReturnValueCompletion(msg) { + @Override + public void success(DownloadBitsFromRemoteTargetRsp rsp) { + if (!rsp.isSuccess()) { + reply.setError(operr("%s", rsp.getError())); + } else { + reply.setDiskSize(rsp.diskSize); + } + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + private void handle(DeleteImageCacheOnPrimaryStorageMsg msg) { inQueue().name(String.format("delete-image-cache-on-primarystorage-%s", self.getUuid())) .asyncBackup(msg) @@ -4334,7 +4723,7 @@ private void deleteImageCacheOnPrimaryStorage(DeleteImageCacheOnPrimaryStorageMs DeleteImageCacheCmd cmd = new DeleteImageCacheCmd(); cmd.setFsId(getSelf().getFsid()); cmd.setUuid(self.getUuid()); - cmd.imagePath = msg.getInstallPath().split("@")[0]; + cmd.imagePath = getVolumePathFromSnapshot(msg.getInstallPath()); cmd.snapshotPath = msg.getInstallPath(); httpCall(DELETE_IMAGE_CACHE, cmd, AgentResponse.class, new ReturnValueCompletion(msg) { @Override @@ -4427,6 +4816,7 @@ public String call(CephPrimaryStorageMonVO arg) { } }); cmd.strategy = param.getStrategy(); + cmd.fencers = param.getFencers(); if (CephSystemTags.CEPH_MANUFACTURER.hasTag(self.getUuid())) { cmd.manufacturer = CephSystemTags.CEPH_MANUFACTURER.getTokenByResourceUuid(self.getUuid(), CephSystemTags.CEPH_MANUFACTURER_TOKEN); @@ -4467,62 +4857,19 @@ public void done() { } private void uploadBitsToBackupStorage(final UploadBitsToBackupStorageMsg msg, final NoErrorCompletion completion) { - checkCephFsId(msg.getPrimaryStorageUuid(), msg.getBackupStorageUuid()); - SimpleQuery q = dbf.createQuery(BackupStorageVO.class); - q.select(BackupStorageVO_.type); - q.add(BackupStorageVO_.uuid, Op.EQ, msg.getBackupStorageUuid()); - String bsType = q.findValue(); - - String path = CP_PATH; - String hostname = null; - - if (!CephConstants.CEPH_BACKUP_STORAGE_TYPE.equals(bsType)) { - List exts = pluginRgty.getExtensionList(PrimaryStorageCommitExtensionPoint.class); - DebugUtils.Assert(exts.size() <= 1, "PrimaryStorageCommitExtensionPoint mustn't > 1"); - if (exts.size() == 0) { - throw new OperationFailureException(operr( - "unable to upload bits to the backup storage[type:%s], we only support CEPH", bsType - )); - } else { - path = exts.get(0).getCommitAgentPath(self.getType()); - hostname = exts.get(0).getHostName(msg.getBackupStorageUuid()); - DebugUtils.Assert(path != null, String.format("found the extension point: [%s], but return null path", - exts.get(0).getClass().getSimpleName())); - } - } - - UploadCmd cmd = new UploadCmd(); - cmd.sendCommandUrl = restf.getSendCommandUrl(); - cmd.fsId = getSelf().getFsid(); - cmd.srcPath = msg.getPrimaryStorageInstallPath(); - cmd.dstPath = msg.getBackupStorageInstallPath(); - - if (msg.getImageUuid() != null) { - cmd.imageUuid = msg.getImageUuid(); - ImageInventory inv = ImageInventory.valueOf(dbf.findByUuid(msg.getImageUuid(), ImageVO.class)); - - StringBuilder desc = new StringBuilder(); - for (CreateImageExtensionPoint ext : pluginRgty.getExtensionList(CreateImageExtensionPoint.class)) { - String tmp = ext.getImageDescription(inv); - if (tmp != null && !tmp.trim().equals("")) { - desc.append(tmp); - } - } - cmd.description = desc.toString(); - } - if (hostname != null) { - // imagestore hostname - cmd.hostname = hostname; - } - - final String apiId = ThreadContext.get(Constants.THREAD_CONTEXT_API); - final UploadBitsToBackupStorageReply reply = new UploadBitsToBackupStorageReply(); - new HttpCaller<>(path, cmd, CpRsp.class, new ReturnValueCompletion(msg) { + UploadBitsToBackupStorageReply reply = new UploadBitsToBackupStorageReply(); + BackupStorageMediator mediator = getBackupStorageMediator(msg.getBackupStorageUuid()); + + MediatorUploadParam param = new MediatorUploadParam(); + param.image = dbf.findByUuid(msg.getImageUuid(), ImageVO.class).toInventory(); + param.primaryStorageUuid = msg.getPrimaryStorageUuid(); + param.primaryStorageInstallPath = msg.getPrimaryStorageInstallPath(); + param.backupStorageInstallPath = msg.getBackupStorageInstallPath(); + mediator.param = param; + mediator.upload(new ReturnValueCompletion(msg) { @Override - public void success(CpRsp rsp) { - if (rsp.installPath != null) { - reply.setInstallPath(rsp.installPath); - } + public void success(String installPath) { + reply.setInstallPath(installPath); bus.reply(msg, reply); completion.done(); } @@ -4533,7 +4880,7 @@ public void fail(ErrorCode errorCode) { bus.reply(msg, reply); completion.done(); } - }).specifyOrder(apiId).call(); + }); } private void handle(final CheckHostStorageConnectionMsg msg) { @@ -4646,18 +4993,30 @@ private void checkHostStorageConnection(List hostUuids, final Completion new While<>(msgs).each((msg, wc) -> bus.send(msg, new CloudBusCallBack(wc) { @Override public void run(MessageReply reply) { - KVMHostAsyncHttpCallReply kr = reply.castReply(); - CheckHostStorageConnectionRsp rsp = kr.toResponse(CheckHostStorageConnectionRsp.class); - if (!rsp.isSuccess()) { - wc.addError(operr("operation error, because:%s", rsp.getError())); - wc.done(); - return; - } - UpdatePrimaryStorageHostStatusMsg umsg = new UpdatePrimaryStorageHostStatusMsg(); umsg.setHostUuid(msg.getHostUuid()); umsg.setPrimaryStorageUuid(self.getUuid()); - umsg.setStatus(PrimaryStorageHostStatus.Connected); + if (!reply.isSuccess()) { + wc.addError(reply.getError()); + umsg.setStatus(PrimaryStorageHostStatus.Disconnected); + } else { + KVMHostAsyncHttpCallReply kr = reply.castReply(); + CheckHostStorageConnectionRsp rsp = kr.toResponse(CheckHostStorageConnectionRsp.class); + + if (rsp == null) { + wc.addError(operr("operation error, because: failed to get response")); + umsg.setStatus(PrimaryStorageHostStatus.Disconnected); + } else { + ErrorCode errorCode = rsp.buildErrorCode(); + if (errorCode != null) { + wc.addError(operr("operation error, because:%s", errorCode)); + umsg.setStatus(PrimaryStorageHostStatus.Disconnected); + } else { + umsg.setStatus(PrimaryStorageHostStatus.Connected); + } + } + } + bus.makeTargetServiceIdByResourceUuid(umsg, PrimaryStorageConstant.SERVICE_ID, umsg.getPrimaryStorageUuid()); bus.send(umsg); wc.done(); @@ -4666,8 +5025,7 @@ public void run(MessageReply reply) { @Override public void done(ErrorCodeList errorCodeList) { if (!errorCodeList.getCauses().isEmpty()) { - completion.fail(errorCodeList.getCauses().get(0)); - return; + logger.warn(String.format("check host storage connection failed, because: %s", errorCodeList.getCauses())); } completion.success(); @@ -4722,77 +5080,57 @@ public void done() { private void fastCreateVolumeFromSnapshot(final CreateVolumeFromVolumeSnapshotOnPrimaryStorageMsg msg, final NoErrorCompletion completion) { final CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply reply = new CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply(); - - final String volPath = makeDataVolumeInstallPath(msg.getVolumeUuid()); + // create volume first, then reserve size for it, so we use snapshot poolName for volume create + String snapShotPath = msg.getSnapshot().getPrimaryStorageInstallPath(); + final String volPath = makeVolumeInstallPathByTargetPool(msg.getVolumeUuid(), getTargetPoolNameFromAllocatedUrl(snapShotPath)); VolumeSnapshotInventory sp = msg.getSnapshot(); - - FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); - chain.then(new NoRollbackFlow() { - String __name__ = "protect-snapshot"; - + cloneAndProtectSnaphost(sp.getPrimaryStorageInstallPath(), volPath, new ReturnValueCompletion(completion) { @Override - public void run(FlowTrigger trigger, Map data) { - ProtectSnapshotCmd cmd = new ProtectSnapshotCmd(); - cmd.snapshotPath = sp.getPrimaryStorageInstallPath(); - cmd.ignoreError = true; - httpCall(PROTECT_SNAPSHOT_PATH, cmd, ProtectSnapshotRsp.class, new ReturnValueCompletion(trigger) { - @Override - public void success(ProtectSnapshotRsp returnValue) { - trigger.next(); - completion.done(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - completion.done(); - } - }); + public void success(CloneRsp rsp) { + reply.setInstallPath(volPath); + reply.setSize(rsp.size); + // current ceph has no way to get the actual size + long asize = rsp.actualSize == null ? 1 : rsp.actualSize; + reply.setActualSize(asize); + reply.setIncremental(true); + bus.reply(msg, reply); + completion.done(); } - }).then(new NoRollbackFlow() { - String __name__ = "clone-snapshot"; @Override - public void run(FlowTrigger trigger, Map data) { - CloneCmd cmd = new CloneCmd(); - cmd.srcPath = sp.getPrimaryStorageInstallPath(); - cmd.dstPath = volPath; - httpCall(CLONE_PATH, cmd, CloneRsp.class, new ReturnValueCompletion(msg) { - @Override - public void success(CloneRsp rsp) { - reply.setInstallPath(volPath); - reply.setSize(rsp.size); + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + }); - // current ceph has no way to get the actual size - long asize = rsp.actualSize == null ? 1 : rsp.actualSize; - reply.setActualSize(asize); - trigger.next(); - } + } - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - }).error(new FlowErrorHandler(msg) { + private void cloneAndProtectSnaphost(String snapshotPath, String dstPath, ReturnValueCompletion completion) { + ProtectSnapshotCmd cmd = new ProtectSnapshotCmd(); + cmd.snapshotPath = snapshotPath; + cmd.ignoreError = true; + httpCall(PROTECT_SNAPSHOT_PATH, cmd, ProtectSnapshotRsp.class, new ReturnValueCompletion(completion) { @Override - public void handle(ErrorCode errCode, Map data) { - reply.setError(errCode); - bus.reply(msg, reply); + public void success(ProtectSnapshotRsp returnValue) { + CloneCmd cmd = new CloneCmd(); + cmd.srcPath = snapshotPath; + cmd.dstPath = dstPath; + httpCall(CLONE_PATH, cmd, CloneRsp.class, completion); } - }).done(new FlowDoneHandler(msg) { + @Override - public void handle(Map data) { - bus.reply(msg, reply); + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); } - }).start(); + }); } private void createVolumeFromSnapshot(final CreateVolumeFromVolumeSnapshotOnPrimaryStorageMsg msg, final NoErrorCompletion completion) { final CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply reply = new CreateVolumeFromVolumeSnapshotOnPrimaryStorageReply(); - - final String volPath = makeDataVolumeInstallPath(msg.getVolumeUuid()); + String snapShotPath = msg.getSnapshot().getPrimaryStorageInstallPath(); + final String volPath = makeVolumeInstallPathByTargetPool(msg.getVolumeUuid(), getTargetPoolNameFromAllocatedUrl(snapShotPath)); VolumeSnapshotInventory sp = msg.getSnapshot(); CpCmd cmd = new CpCmd(); cmd.resourceUuid = msg.getSnapshot().getVolumeUuid(); @@ -4803,7 +5141,6 @@ private void createVolumeFromSnapshot(final CreateVolumeFromVolumeSnapshotOnPrim public void success(CpRsp rsp) { reply.setInstallPath(volPath); reply.setSize(rsp.size); - // current ceph has no way to get the actual size long asize = rsp.actualSize == null ? 1 : rsp.actualSize; reply.setActualSize(asize); @@ -4824,7 +5161,7 @@ protected void handle(final RevertVolumeFromSnapshotOnPrimaryStorageMsg msg) { final RevertVolumeFromSnapshotOnPrimaryStorageReply reply = new RevertVolumeFromSnapshotOnPrimaryStorageReply(); final TaskProgressRange parentStage = getTaskStage(); - final TaskProgressRange ROLLBACK_SNAPSHOT_STAGE = new TaskProgressRange(0, 70); + final TaskProgressRange UNDO_SNAPSHOT_CREATION_STAGE = new TaskProgressRange(0, 70); final TaskProgressRange DELETE_ORIGINAL_SNAPSHOT_STAGE = new TaskProgressRange(30, 100); final FlowChain chain = FlowChainBuilder.newShareFlowChain(); @@ -4833,20 +5170,36 @@ protected void handle(final RevertVolumeFromSnapshotOnPrimaryStorageMsg msg) { chain.then(new ShareFlow() { @Override public void setup() { + boolean fastRevert = VolumeSnapshotGlobalConfig.ENABLE_FAST_REVERT.value(Boolean.class); + String snapShotPath = msg.getSnapshot().getPrimaryStorageInstallPath(); // get volume path from snapshot path, just split @ - String volumePath = msg.getSnapshot().getPrimaryStorageInstallPath().split("@")[0]; + String volumePath = getVolumePathFromSnapshot(snapShotPath); + final String newVolumePath = makeVolumeInstallPathByTargetPool(Platform.getUuid(), getTargetPoolNameFromAllocatedUrl(snapShotPath)); flow(new NoRollbackFlow() { + String __name__ = "revert-volume-from-snapshot"; + + @Override + public boolean skip(Map data) { + return fastRevert; + } + @Override public void run(FlowTrigger trigger, Map data) { - TaskProgressRange stage = markTaskStage(parentStage, ROLLBACK_SNAPSHOT_STAGE); + TaskProgressRange stage = markTaskStage(parentStage, UNDO_SNAPSHOT_CREATION_STAGE); RollbackSnapshotCmd cmd = new RollbackSnapshotCmd(); - cmd.snapshotPath = msg.getSnapshot().getPrimaryStorageInstallPath(); + cmd.snapshotPath = snapShotPath; + cmd.capacityThreshold = psPhysicalCapacityMgr.getRatio(getSelf().getUuid()); httpCall(ROLLBACK_SNAPSHOT_PATH, cmd, RollbackSnapshotRsp.class, new ReturnValueCompletion(msg) { @Override public void success(RollbackSnapshotRsp returnValue) { + Long trashId = trash.getTrashId(self.getUuid(), volumePath); + if (trashId != null) { + trash.removeFromDb(trashId); + } reply.setSize(returnValue.getSize()); + reply.setNewVolumeInstallPath(volumePath); reportProgress(stage.getEnd().toString()); trigger.next(); } @@ -4859,15 +5212,41 @@ public void fail(ErrorCode errorCode) { } }); + + flow(new NoRollbackFlow() { + String __name__ = "fast-revert-volume-from-snapshot"; + + @Override + public boolean skip(Map data) { + return !fastRevert; + } + + @Override + public void run(final FlowTrigger trigger, Map data) { + TaskProgressRange stage = markTaskStage(parentStage, UNDO_SNAPSHOT_CREATION_STAGE); + + VolumeSnapshotInventory sp = msg.getSnapshot(); + cloneAndProtectSnaphost(sp.getPrimaryStorageInstallPath(), newVolumePath, new ReturnValueCompletion(trigger) { + @Override + public void success(CloneRsp rsp) { + reply.setNewVolumeInstallPath(newVolumePath); + reply.setSize(rsp.size); + tagMgr.createNonInherentSystemTag(sp.getVolumeUuid(), VolumeSystemTags.FAST_REVERT.getTagFormat(), VolumeVO.class.getSimpleName()); + reportProgress(stage.getEnd().toString()); + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + done(new FlowDoneHandler(msg) { @Override public void handle(Map data) { - Long trashId = trash.getTrashId(self.getUuid(), volumePath); - if (trashId != null) { - trash.removeFromDb(trashId); - } - - reply.setNewVolumeInstallPath(volumePath); bus.reply(msg, reply); } }); @@ -4895,23 +5274,30 @@ private ImageSpec makeImageSpec(VolumeInventory volume) { ImageSpec imageSpec = new ImageSpec(); imageSpec.setInventory(ImageInventory.valueOf(image)); - ImageBackupStorageRefInventory ref = CollectionUtils.find(image.getBackupStorageRefs(), new Function() { - @Override - public ImageBackupStorageRefInventory call(ImageBackupStorageRefVO arg) { - String fsid = Q.New(CephBackupStorageVO.class).eq(CephBackupStorageVO_.uuid, arg.getBackupStorageUuid()).select(CephBackupStorageVO_.fsid).findValue(); - if (fsid != null && fsid.equals(getSelf().getFsid()) && ImageStatus.Ready == arg.getStatus()) { - return ImageBackupStorageRefInventory.valueOf(arg); - } - return null; - } - }); - - if (ref == null) { - throw new OperationFailureException(operr("cannot find backupstorage to download image [%s] to primarystorage [%s]", volume.getRootImageUuid(), getSelf().getUuid())); - } + // mismatch fsid means the image is not available for this primary storage. + // normally this happens due to primary storage migration which do + // not migrate images stored in ceph backup storage. + List sameCephBsUuids = Q.New(CephBackupStorageVO.class).select(CephBackupStorageVO_.uuid) + .eq(CephBackupStorageVO_.fsid, getSelf().getFsid()) + .listValues(); + List supportBsUuids = Q.New(BackupStorageVO.class).select(BackupStorageVO_.uuid) + .in(BackupStorageVO_.type, backupStorageMediators.keySet()) + .listValues(); - imageSpec.setSelectedBackupStorage(ImageBackupStorageRefInventory.valueOf(image.getBackupStorageRefs().iterator().next())); + ImageBackupStorageRefInventory ref = imageSpec.getInventory().getBackupStorageRefs().stream() + .filter(it -> ImageStatus.Ready.toString().equals(it.getStatus())) + .filter(it -> supportBsUuids.contains(it.getBackupStorageUuid())) + .filter(it -> !it.getInstallPath().startsWith("ceph://") || sameCephBsUuids.contains(it.getBackupStorageUuid())) + .min(Comparator.comparing(it -> { + if (it.getInstallPath().startsWith("ceph://")) { + return -1; + } else { + return 1; + } + })).orElseThrow(() -> new OperationFailureException(operr("cannot find backupstorage to download image [%s] " + + "to primarystorage [%s] due to lack of Ready and accessible image", volume.getRootImageUuid(), getSelf().getUuid()))); + imageSpec.setSelectedBackupStorage(ref); return imageSpec; } @@ -4922,7 +5308,8 @@ protected void handle(final ReInitRootVolumeFromTemplateOnPrimaryStorageMsg msg) chain.setName(String.format("reimage-vm-root-volume-%s", msg.getVolume().getUuid())); chain.then(new ShareFlow() { final String originalVolumePath = msg.getVolume().getInstallPath(); - String volumePath = makeResetImageRootVolumeInstallPath(msg.getVolume().getUuid()); + final String targetPoolName = getTargetPoolNameFromAllocatedUrl(msg.getAllocatedInstallUrl()); + String volumePath = makeResetImageRootVolumeInstallPath(msg.getVolume().getUuid(), targetPoolName); String installUrl; @Override @@ -4967,7 +5354,6 @@ public void run(final FlowTrigger trigger, Map data) { CloneCmd cmd = new CloneCmd(); cmd.srcPath = installUrl; cmd.dstPath = volumePath; - httpCall(CLONE_PATH, cmd, CloneRsp.class, new ReturnValueCompletion(trigger) { @Override public void fail(ErrorCode err) { @@ -4976,11 +5362,6 @@ public void fail(ErrorCode err) { @Override public void success(CloneRsp ret) { - if (StringUtils.isNotEmpty(ret.getInstallPath()) && - !ret.getInstallPath().equals(volumePath)) { - volumePath = makeResetImageRootVolumeInstallPath(msg.getVolume().getUuid(), ret.getInstallPath()); - } - trigger.next(); } }); @@ -5050,20 +5431,27 @@ public void done() { })); } - protected void deleteSnapshotOnPrimaryStorage(final DeleteSnapshotOnPrimaryStorageMsg msg, final NoErrorCompletion completion) { + private void deleteSnapshotOnPrimaryStorage(final DeleteSnapshotOnPrimaryStorageMsg msg, final NoErrorCompletion completion) { final DeleteSnapshotOnPrimaryStorageReply reply = new DeleteSnapshotOnPrimaryStorageReply(); DeleteSnapshotCmd cmd = new DeleteSnapshotCmd(); cmd.snapshotPath = msg.getSnapshot().getPrimaryStorageInstallPath(); httpCall(DELETE_SNAPSHOT_PATH, cmd, DeleteSnapshotRsp.class, new ReturnValueCompletion(msg) { @Override public void success(DeleteSnapshotRsp returnValue) { + osdHelper.releaseAvailableCapWithRatio(msg.getSnapshot().getPrimaryStorageInstallPath(), msg.getSnapshot().getSize()); bus.reply(msg, reply); completion.done(); } @Override public void fail(ErrorCode errorCode) { - reply.setError(errorCode); + // ceph has trash, so children may not be deleted immediately. + DeleteVolumeSnapshotGC snapshotGC = new DeleteVolumeSnapshotGC(); + snapshotGC.NAME = String.format("gc-ceph-%s-volumesnapshot-path-%s", self.getUuid(), cmd.snapshotPath); + snapshotGC.primaryStorageUuid = self.getUuid(); + snapshotGC.volumeSnapshot = msg.getSnapshot(); + snapshotGC.deduplicateSubmit(CephGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); + reply.setGcSubmitted(true); bus.reply(msg, reply); completion.done(); } @@ -5107,12 +5495,33 @@ protected void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg) { bus.reply(msg, reply); } + @Override + protected void handle(FlattenVolumeOnPrimaryStorageMsg msg) { + FlattenVolumeOnPrimaryStorageReply reply = new FlattenVolumeOnPrimaryStorageReply(); + FlattenCmd cmd = new FlattenCmd(); + cmd.path = msg.getVolume().getInstallPath(); + + // TODO unprotect snapshot + httpCall(FLATTEN_PATH, cmd, FlattenRsp.class, new ReturnValueCompletion(msg) { + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + } + + @Override + public void success(FlattenRsp rsp) { + bus.reply(msg, reply); + } + }); + } + private void handle(CheckSnapshotMsg msg) { CheckSnapshotReply reply = new CheckSnapshotReply(); bus.reply(msg, reply); } - private void handle(TakeSnapshotMsg msg) { + protected void handle(TakeSnapshotMsg msg) { inQueue().name(String.format("take-snapshot-%s", self.getUuid())) .asyncBackup(msg) .run(chain -> takeSnapshot(msg, new NoErrorCompletion(chain) { @@ -5136,6 +5545,8 @@ private void takeSnapshot(final TakeSnapshotMsg msg, final NoErrorCompletion com CreateSnapshotCmd cmd = new CreateSnapshotCmd(); cmd.volumeUuid = sp.getVolumeUuid(); cmd.snapshotPath = spPath; + cmd.name = msg.getName(); + cmd.description = msg.getName(); httpCall(CREATE_SNAPSHOT_PATH, cmd, CreateSnapshotRsp.class, new ReturnValueCompletion(msg) { @Override public void success(CreateSnapshotRsp rsp) { @@ -5384,10 +5795,25 @@ private void cephToCephMigrateVolumeSegment(CephToCephMigrateVolumeSegmentMsg ms cmd.setResourceUuid(msg.getResourceUuid()); cmd.setSrcInstallPath(msg.getSrcInstallPath()); cmd.setDstInstallPath(msg.getDstInstallPath()); - cmd.setDstMonHostname(msg.getDstMonHostname()); - cmd.setDstMonSshUsername(msg.getDstMonSshUsername()); - cmd.setDstMonSshPassword(msg.getDstMonSshPassword()); - cmd.setDstMonSshPort(msg.getDstMonSshPort()); + + MonMigrateIpInfo dstMonMigrateIpInfo = new MonMigrateIpInfo(msg.getDstPrimaryStorageUuid()); + CephPrimaryStorageMonVO dstMon = dstMonMigrateIpInfo.monMap.values().iterator().next(); + String dstMonMigrateIp = dstMon.getHostname(); + if (!dstMonMigrateIpInfo.getMonsMigrateIpInCidr().isEmpty()) { + dstMon = dstMonMigrateIpInfo.getMonsMigrateIpInCidr().get(0); + dstMonMigrateIp = dstMonMigrateIpInfo.getMigrateIp(dstMon.getUuid()); + } + cmd.setDstMonHostname(dstMonMigrateIp); + cmd.setDstMonSshUsername(dstMon.getSshUsername()); + cmd.setDstMonSshPassword(dstMon.getSshPassword()); + cmd.setDstMonSshPort(dstMon.getSshPort()); + + final MonMigrateIpInfo srcMonMigrateIpInfo = new MonMigrateIpInfo(msg.getPrimaryStorageUuid()); + List srcMonsWithMigrateIp = new ArrayList<>(); + if (!srcMonMigrateIpInfo.monMigrateIpMap.isEmpty()) { + srcMonsWithMigrateIp.addAll(srcMonMigrateIpInfo.monMigrateIpMap.keySet()); + } + Comparator containFirst = Comparator.comparing(mon -> !srcMonsWithMigrateIp.contains(mon.getUuid())); final String apiId = ThreadContext.get(Constants.THREAD_CONTEXT_API); final CephToCephMigrateVolumeSegmentReply reply = new CephToCephMigrateVolumeSegmentReply(); @@ -5404,7 +5830,52 @@ public void fail(ErrorCode errorCode) { bus.reply(msg, reply); completion.done(); } - }, TimeUnit.MILLISECONDS, msg.getTimeout()).specifyOrder(apiId).call(); + }, TimeUnit.MILLISECONDS, msg.getTimeout()).specifyOrder(apiId).specifyOrder(containFirst).call(); + } + + static class MonMigrateIpInfo { + private final Map monMap; + + private final Map monMigrateIpMap = new HashMap<>(); + + public MonMigrateIpInfo(String psUuid) { + CephPrimaryStorageVO psVO = Q.New(CephPrimaryStorageVO.class) + .eq(CephPrimaryStorageVO_.uuid, psUuid).find(); + List monVOS = new ArrayList<>(psVO.getMons()); + Collections.shuffle(monVOS); + this.monMap = monVOS.stream().collect( + Collectors.toMap(CephPrimaryStorageMonVO::getUuid, CephPrimaryStorageMonVO -> CephPrimaryStorageMonVO)); + + String migrateCidr = PrimaryStorageSystemTags.PRIMARY_STORAGE_MIGRATE_NETWORK_CIDR + .getTokenByResourceUuid(psUuid, PrimaryStorageSystemTags.PRIMARY_STORAGE_MIGRATE_NETWORK_CIDR_TOKEN); + if (migrateCidr == null) { + return; + } + + for (CephPrimaryStorageMonVO mon : monVOS) { + List ips = new ArrayList<>(); + ips.add(mon.getHostname()); + final String extraIps = CephMonSystemTags.EXTRA_IPS + .getTokenByResourceUuid(mon.getUuid(), CephMonSystemTags.EXTRA_IPS_TOKEN); + Optional.ofNullable(extraIps).ifPresent(it -> ips.addAll(Arrays.asList(it.split(",")))); + List cidrIps = NetworkUtils.filterIpv4sInCidr(ips, migrateCidr); + if (!cidrIps.isEmpty()) { + monMigrateIpMap.put(mon.getUuid(), cidrIps.get(0)); + } + } + } + + public List getMonsMigrateIpInCidr() { + if (monMigrateIpMap.isEmpty()) { + return Collections.emptyList(); + } + + return monMigrateIpMap.keySet().stream().map(monMap::get).collect(Collectors.toList()); + } + + public String getMigrateIp(String monUuid) { + return monMigrateIpMap.get(monUuid); + } } private void handle(GetVolumeSnapshotInfoMsg msg) { @@ -5518,4 +5989,206 @@ public void fail(ErrorCode errorCode) { } }).setAvoidMonUuids(msg.getAvoidCephMonUuids()).tryNext().call(); } + + protected void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + new While<>(msg.getRootInstallPaths()).each((installPath, compl) -> { + GetBackingChainCmd cmd = new GetBackingChainCmd(); + cmd.volumePath = installPath; + new HttpCaller<>(GET_BACKING_CHAIN_PATH, cmd, GetBackingChainRsp.class, new ReturnValueCompletion(msg) { + @Override + public void success(GetBackingChainRsp rsp) { + if (CollectionUtils.isEmpty(rsp.backingChain)) { + reply.putBackingChainInstallPath(installPath, Collections.emptyList()); + reply.putBackingChainSize(installPath, 0L); + } else { + reply.putBackingChainInstallPath(installPath, rsp.backingChain.stream() + .map(it -> makeCephPath(it)).collect(Collectors.toList())); + reply.putBackingChainSize(installPath, rsp.totalSize); + } + + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.done(); + } + }).call(); + }).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + reply.setError(errorCodeList.getCauses().get(0)); + } + + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(DeleteVolumeChainOnPrimaryStorageMsg msg) { + DeleteVolumeChainOnPrimaryStorageReply reply = new DeleteVolumeChainOnPrimaryStorageReply(); + DeleteVolumeChainCmd cmd = new DeleteVolumeChainCmd(); + cmd.installPaths = msg.getInstallPaths(); + new HttpCaller<>(DELETE_VOLUME_CHAIN_PATH, cmd, DeleteVolumeChainRsp.class, new ReturnValueCompletion(msg) { + private void submitGcForUndeletedInstallPaths(List undeletedInstallPaths) { + CephDeleteVolumeChainGC volumeChainGC = new CephDeleteVolumeChainGC(); + volumeChainGC.primaryStorageUuid = self.getUuid(); + volumeChainGC.installPaths = undeletedInstallPaths; + volumeChainGC.NAME = String.format("gc-ceph-%s-volume-chain-%s", self.getUuid(), msg.getChainTop()); + volumeChainGC.chainTop = msg.getChainTop(); + volumeChainGC.deduplicateSubmit(CephGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); + logger.debug(String.format("unable to delete installPaths %s, now add GC to delete", undeletedInstallPaths)); + } + + @Override + public void success(DeleteVolumeChainRsp rsp) { + if (CollectionUtils.isEmpty(rsp.undeletedInstallPaths)) { + bus.reply(msg, reply); + return; + } + submitGcForUndeletedInstallPaths(rsp.undeletedInstallPaths); + reply.setUndeletedInstallPaths(rsp.undeletedInstallPaths); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + submitGcForUndeletedInstallPaths(cmd.installPaths); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }).call(); + } + + private void handle(GetPrimaryStorageUsageReportMsg msg) { + GetPrimaryStorageUsedPhysicalCapacityForecastReply reply = new GetPrimaryStorageUsedPhysicalCapacityForecastReply(); + List poolVOs = Q.New(CephPrimaryStoragePoolVO.class) + .in(CephPrimaryStoragePoolVO_.uuid, getPoolUuidsFromPoolUris(msg.getUris())).list(); + + Map osdUsageReport = poolUsageCollector + .getUsageReportByResourceUuids(poolVOs.stream().map(vo -> vo.getOsdGroup().getUuid()).collect(Collectors.toList())); + + Map poolUsageReport = new HashMap<>(); + poolVOs.forEach(poolVO -> poolUsageReport.put(poolVO.getUuid(), osdUsageReport.get(poolVO.getOsdGroup().getUuid()))); + + reply.setUsageReportMap(poolUsageReport); + bus.reply(msg, reply); + } + + @Override + protected void handle(GetOwningVolumePathFromInternalSnapshotMsg msg) { + GetOwningVolumePathFromInternalSnapshotReply reply = new GetOwningVolumePathFromInternalSnapshotReply(); + if (msg.getSnapshotPaths() != null) { + for (String snapshotPath : msg.getSnapshotPaths()) { + reply.putOwningVolumePath(snapshotPath, getVolumePathFromSnapshot(snapshotPath)); + } + } + + bus.reply(msg, reply); + } + + protected void handle(CleanUpStorageTrashOnPrimaryStorageMsg msg) { + CleanUpStorageTrashOnPrimaryStorageReply reply = new CleanUpStorageTrashOnPrimaryStorageReply(); + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature("cleanup-ceph-trash-for-ps-" + msg.getPrimaryStorageUuid()) + .run(completion -> + cleanUpStorageTrash(new ReturnValueCompletion(completion) { + @Override + public void success(Map result) { + completion.success(result); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }, msg.isForce()) + ).done(result -> { + if (result.isSuccess()) { + reply.setResult((Map) result.getResult()); + bus.reply(msg, reply); + } else { + reply.setError(result.getErrorCode()); + bus.reply(msg, reply); + } + })); + } + + private void cleanUpStorageTrash(ReturnValueCompletion completion, boolean force) { + List pools = Q.New(CephPrimaryStoragePoolVO.class) + .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, self.getUuid()) + .select(CephPrimaryStoragePoolVO_.poolName) + .listValues(); + CleanTrashCmd cmd = new CleanTrashCmd(); + cmd.pools = pools; + cmd.force = force; + new HttpCaller<>(CLAEN_TRASH_PATH, cmd, CleanTrashRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(CleanTrashRsp rsp) { + completion.success(rsp.pool2TrashResult); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }).call(); + } + + private List getPoolUuidsFromPoolUris(List poolUris) { + return poolUris.stream().map(uri -> uri.replace("ceph://", "")).collect(Collectors.toList()); + } + + protected String makeVolumeInstallPathByTargetPool(String volUuid, String targetPoolName) { + return String.format("ceph://%s/%s", targetPoolName, volUuid); + } + + private String makeCephPath(String originPath) { + if (originPath.startsWith("ceph://")) { + return originPath; + } + + return String.format("ceph://%s", originPath); + } + + private static String getVolumePathFromSnapshot(String snapshotPath) { + return snapshotPath.split("@")[0]; + } + + protected String getTargetPoolNameFromAllocatedUrl(String allocatedUrl) { + if (allocatedUrl == null) { + throw new OperationFailureException(operr("allocated url not found")); + } + + + if (!allocatedUrl.startsWith("ceph://")) { + throw new OperationFailureException(operr("invalid allocated url:%s", allocatedUrl)); + } + + String path = allocatedUrl.replaceFirst("ceph://", ""); + return path.substring(0, path.lastIndexOf("/")); + } + + private String makeResetImageRootVolumeInstallPath(String volUuid, String targetPoolName) { + return String.format("ceph://%s/reset-image-%s-%s", + targetPoolName, + volUuid, + System.currentTimeMillis()); + } + + private String getDefaultImageCachePoolName() { + return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_IMAGE_CACHE_POOL.getTokenByResourceUuid(self.getUuid(), CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_IMAGE_CACHE_POOL_TOKEN); + } + + private String getDefaultDataVolumePoolName() { + return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_DATA_VOLUME_POOL.getTokenByResourceUuid(self.getUuid(), CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_DATA_VOLUME_POOL_TOKEN); + } + + private String getDefaultRootVolumePoolName() { + return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_ROOT_VOLUME_POOL.getTokenByResourceUuid(self.getUuid(), CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_ROOT_VOLUME_POOL_TOKEN); + } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCanonicalEvents.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCanonicalEvents.java index 55eada184b5..304a5167090 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCanonicalEvents.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageCanonicalEvents.java @@ -12,6 +12,14 @@ public static class ImageInnerSnapshotCreated { public VolumeSnapshotInventory snapshot; public String primaryStorageUuid; + public void setSnapshot(VolumeSnapshotInventory snapshot) { + this.snapshot = snapshot; + } + + public VolumeSnapshotInventory getSnapshot() { + return this.snapshot; + } + public void fire() { EventFacade evtf = Platform.getComponentLoader().getComponent(EventFacade.class); evtf.fire(IMAGE_INNER_SNAPSHOT_CREATED, this); diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageDeployArguments.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageDeployArguments.java new file mode 100644 index 00000000000..130dd144b01 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageDeployArguments.java @@ -0,0 +1,15 @@ +package org.zstack.storage.ceph.primary; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; +import org.zstack.storage.ceph.CephGlobalProperty; + +public class CephPrimaryStorageDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_cephpagent") + private final String packageName = CephGlobalProperty.PRIMARY_STORAGE_PACKAGE_NAME; + + @Override + public String getPackageName() { + return packageName; + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java index 29db8db43cf..cb7dde9c5cc 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageFactory.java @@ -7,7 +7,6 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.host.HostSystemTags; -import org.zstack.header.vm.VmCapabilities; import org.zstack.compute.vm.VmCapabilitiesExtensionPoint; import org.zstack.configuration.DiskOfferingSystemTags; import org.zstack.configuration.InstanceOfferingSystemTags; @@ -16,9 +15,15 @@ import org.zstack.core.Platform; import org.zstack.core.ansible.AnsibleFacade; import org.zstack.core.asyncbatch.While; -import org.zstack.core.cloudbus.*; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.EventCallback; +import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.db.*; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQLBatch; +import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.thread.ThreadFacade; @@ -36,7 +41,10 @@ import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; -import org.zstack.header.host.*; +import org.zstack.header.host.HostCanonicalEvents; +import org.zstack.header.host.HostStatus; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.backup.*; import org.zstack.header.storage.primary.*; @@ -47,18 +55,18 @@ import org.zstack.kvm.*; import org.zstack.storage.ceph.*; import org.zstack.storage.ceph.primary.KVMCephVolumeTO.MonInfo; +import org.zstack.storage.ceph.primary.capacity.CephOsdGroupCapacityHelper; import org.zstack.storage.ceph.primary.capacity.CephPrimaryCapacityUpdater; -import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; import org.zstack.storage.snapshot.MarkRootVolumeAsSnapshotExtension; import org.zstack.storage.snapshot.PostMarkRootVolumeAsSnapshotExtension; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.SystemTagUtils; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; +import org.zstack.utils.TagUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; -import org.zstack.utils.network.NetworkUtils; import javax.persistence.Tuple; import javax.persistence.TypedQuery; @@ -81,13 +89,15 @@ public class CephPrimaryStorageFactory implements PrimaryStorageFactory, CephCap KvmSetupSelfFencerExtensionPoint, KVMPreAttachIsoExtensionPoint, Component, PostMarkRootVolumeAsSnapshotExtension, BeforeTakeLiveSnapshotsOnVolumes, VmInstanceCreateExtensionPoint, CreateDataVolumeExtensionPoint, InstanceOfferingUserConfigValidator, DiskOfferingUserConfigValidator, MarkRootVolumeAsSnapshotExtension, - VmCapabilitiesExtensionPoint, PreVmInstantiateResourceExtensionPoint, PSCapacityExtensionPoint { + VmCapabilitiesExtensionPoint, PreVmInstantiateResourceExtensionPoint, PSCapacityExtensionPoint, + RecalculatePrimaryStorageCapacityExtensionPoint { private static final CLogger logger = Utils.getLogger(CephPrimaryStorageFactory.class); public static final PrimaryStorageType type = new PrimaryStorageType(CephConstants.CEPH_PRIMARY_STORAGE_TYPE); { type.setSupportSharedVolume(true); + type.setSupportCheckHostStatus(true); } @Autowired @@ -146,6 +156,18 @@ public PrimaryStorageType getPrimaryStorageType() { return type; } + private String getInitializationPoolName(String existPoolName, String customName, String systemDefinedPoolName) { + if (existPoolName != null) { + return existPoolName; + } + + if (customName != null) { + return customName; + } + + return systemDefinedPoolName; + } + @Override @Transactional public PrimaryStorageInventory createPrimaryStorage(PrimaryStorageVO vo, APIAddPrimaryStorageMsg msg) { @@ -158,7 +180,16 @@ public PrimaryStorageInventory createPrimaryStorage(PrimaryStorageVO vo, APIAddP dbf.getEntityManager().persist(cvo); - String rootVolumePoolName = cmsg.getRootVolumePoolName() == null ? String.format("pri-v-r-%s", vo.getUuid()) : cmsg.getRootVolumePoolName(); + String customName = msg.getSystemTags() == null ? null : msg.getSystemTags() + .stream().filter(v -> CephSystemTags.CUSTOM_INITIALIZATION_POOL_NAME.isMatch(v)) + .map(v -> CephSystemTags.CUSTOM_INITIALIZATION_POOL_NAME.getTokenByTag(v, CephSystemTags.CUSTOM_INITIALIZATION_POOL_NAME_TOKEN)) + .findFirst().orElse(null); + + if (customName != null) { + msg.getSystemTags().removeIf(t -> CephSystemTags.CUSTOM_INITIALIZATION_POOL_NAME.isMatch(t)); + } + + String rootVolumePoolName = getInitializationPoolName(cmsg.getRootVolumePoolName(), customName, String.format("pri-v-r-%s", vo.getUuid())); CephPrimaryStoragePoolVO rootVolumePoolVO = new CephPrimaryStoragePoolVO(); rootVolumePoolVO.setUuid(Platform.getUuid()); rootVolumePoolVO.setPrimaryStorageUuid(cvo.getUuid()); @@ -171,7 +202,7 @@ public PrimaryStorageInventory createPrimaryStorage(PrimaryStorageVO vo, APIAddP creator.recreate = true; creator.create(); - String dataVolumePoolName = cmsg.getDataVolumePoolName() == null ? String.format("pri-v-d-%s", vo.getUuid()) : cmsg.getDataVolumePoolName(); + String dataVolumePoolName = getInitializationPoolName(cmsg.getDataVolumePoolName(), customName, String.format("pri-v-d-%s", vo.getUuid())); CephPrimaryStoragePoolVO dataVolumePoolVO = new CephPrimaryStoragePoolVO(); dataVolumePoolVO.setUuid(Platform.getUuid()); dataVolumePoolVO.setPrimaryStorageUuid(cvo.getUuid()); @@ -249,6 +280,11 @@ public PrimaryStorageInventory getInventory(String uuid) { return CephPrimaryStorageInventory.valueOf(dbf.findByUuid(uuid, CephPrimaryStorageVO.class)); } + @Override + public void validateStorageProtocol(String protocol) { + + } + @Override public void update(CephCapacity cephCapacity) { DebugUtils.Assert(cephCapacity.getCephManufacturer() != null, @@ -359,12 +395,11 @@ private VolumeTO convertVolumeToCephIfNeeded(VolumeInventory vol, VolumeTO to) { } SimpleQuery q = dbf.createQuery(CephPrimaryStorageMonVO.class); - q.select(CephPrimaryStorageMonVO_.monAddr, CephPrimaryStorageMonVO_.monPort); + q.select(CephPrimaryStorageMonVO_.monAddr, CephPrimaryStorageMonVO_.monPort, CephPrimaryStorageMonVO_.status); q.add(CephPrimaryStorageMonVO_.primaryStorageUuid, Op.EQ, vol.getPrimaryStorageUuid()); - q.add(CephPrimaryStorageMonVO_.status, Op.EQ, MonStatus.Connected); List ts = q.listTuple(); - if (ts.isEmpty()) { + if (ts.isEmpty() || ts.stream().noneMatch(t -> t.get(2, MonStatus.class) == MonStatus.Connected)) { throw new OperationFailureException(operr( "cannot find any Connected ceph mon for the primary storage[uuid:%s]", vol.getPrimaryStorageUuid()) ); @@ -587,7 +622,7 @@ public void run(final FlowTrigger trigger, Map data) { ask.setImageUuid(paramIn.getImage().getUuid()); ask.setBackupStorageUuid(paramIn.getBackupStorageUuid()); ask.setImageMediaType(paramIn.getImage().getMediaType()); - bus.makeTargetServiceIdByResourceUuid(ask, BackupStorageConstant.SERVICE_ID, paramIn.getBackupStorageUuid()); + bus.makeLocalServiceId(ask, BackupStorageConstant.SERVICE_ID); MessageReply ar = bus.call(ask); if (!ar.isSuccess()) { trigger.fail(ar.getError()); @@ -708,7 +743,7 @@ public void beforeTakeLiveSnapshotsOnVolumes(CreateVolumesSnapshotOverlayInnerMs return; } - if (cephStructs.size() == msg.getVolumeSnapshotJobs().size()) { + if (otmsg.getSnapshotJobs().isEmpty()) { flowData.put(VolumeSnapshotConstant.NEED_BLOCK_STREAM_ON_HYPERVISOR, false); flowData.put(VolumeSnapshotConstant.NEED_TAKE_SNAPSHOTS_ON_HYPERVISOR, false); } else if (msg.getConsistentType() != ConsistentType.None) { @@ -904,7 +939,7 @@ private void settingDataVolume(CreateVmInstanceMsg msg) { } @Override - public void preCreateVolume(APICreateDataVolumeMsg msg) { + public void preCreateVolume(VolumeCreateMessage msg) { String diskOffering = msg.getDiskOfferingUuid(); if (diskOffering == null) { return; @@ -1215,17 +1250,167 @@ public void preReleaseVmResource(VmInstanceSpec spec, Completion completion) { @Override public String buildAllocatedInstallUrl(AllocatePrimaryStorageSpaceMsg msg, PrimaryStorageInventory psInv) { - return Q.New(PrimaryStorageVO.class).select(PrimaryStorageVO_.url).eq(PrimaryStorageVO_.uuid, psInv.getUuid()).findValue(); + if (msg.getRequiredInstallUri() != null) { + CephRequiredUrlParser.InstallPath path = CephRequiredUrlParser.getInstallPathFromUri(msg.getRequiredInstallUri()); + checkCephPoolCapacityForNewVolume(path.poolName, msg.getSize(), psInv.getUuid()); + return path.fullPath; + } + + return getPreAllocatedInstallUrl(msg, psInv.getUuid()); } @Override @Transactional(propagation = Propagation.MANDATORY) public long reserveCapacity(AllocatePrimaryStorageSpaceMsg msg, String allocatedInstallUrl, long size, String psUuid) { - return size; + return new CephOsdGroupCapacityHelper(psUuid).reserveAvailableCapacity(allocatedInstallUrl, size); } @Override @Transactional(propagation = Propagation.MANDATORY) public void releaseCapacity(String allocatedInstallUrl, long size, String psUuid) { + new CephOsdGroupCapacityHelper(psUuid).releaseAvailableCapacity(allocatedInstallUrl, size); + } + + @Override + public String getPrimaryStorageTypeForRecalculateCapacityExtensionPoint() { + return type.toString(); + } + + @Override + public void afterRecalculatePrimaryStorageCapacity(RecalculatePrimaryStorageCapacityStruct struct) { + new CephOsdGroupCapacityHelper(struct.getPrimaryStorageUuid()).recalculateAvailableCapacity(); + } + + @Override + public void beforeRecalculatePrimaryStorageCapacity(RecalculatePrimaryStorageCapacityStruct struct) { + + } + + private String getPoolName(String customPoolName, String defaultPoolName, long volumeSize, String poolType, String psUuid) { + CephOsdGroupCapacityHelper osdHelper = new CephOsdGroupCapacityHelper(psUuid); + if (customPoolName != null) { + checkCephPoolCapacityForNewVolume(customPoolName, volumeSize, psUuid); + return customPoolName; + } + + CephPrimaryStoragePoolVO pool = getPoolFromPoolName(defaultPoolName, psUuid, poolType); + + boolean capacityChecked = osdHelper.checkVirtualSizeByRatio(pool.getUuid(), volumeSize); + + if (!capacityChecked) { + //try to find other pool + List pools = Q.New(CephPrimaryStoragePoolVO.class) + .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, psUuid) + .eq(CephPrimaryStoragePoolVO_.type, poolType) + .notEq(CephPrimaryStoragePoolVO_.poolName, defaultPoolName) + .list(); + + Optional opt = pools.stream() + .filter(v -> osdHelper.checkVirtualSizeByRatio(v.getUuid(), volumeSize)) + .map(CephPrimaryStoragePoolVO::getPoolName) + .findFirst(); + + if (opt.isPresent()) { + return opt.get(); + } + + logger.debug(String.format("unable to find a %s pool with the required size %s", poolType, volumeSize)); + return null; + } + + return defaultPoolName; + } + + private String getDefaultImageCachePoolName(String psUuid) { + return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_IMAGE_CACHE_POOL.getTokenByResourceUuid(psUuid, CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_IMAGE_CACHE_POOL_TOKEN); + } + + private String getDefaultDataVolumePoolName(String psUuid) { + return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_DATA_VOLUME_POOL.getTokenByResourceUuid(psUuid, CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_DATA_VOLUME_POOL_TOKEN); + } + + private String getDefaultRootVolumePoolName(String psUuid) { + return CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_ROOT_VOLUME_POOL.getTokenByResourceUuid(psUuid, CephSystemTags.DEFAULT_CEPH_PRIMARY_STORAGE_ROOT_VOLUME_POOL_TOKEN); + } + + private CephPrimaryStoragePoolVO getPoolFromPoolName(String poolName, String psUuid, String poolType) { + Q q = Q.New(CephPrimaryStoragePoolVO.class) + .eq(CephPrimaryStoragePoolVO_.poolName, poolName) + .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, psUuid); + + if (poolType != null) { + q.eq(CephPrimaryStoragePoolVO_.type, poolType); + } + + List poolVOS = q.list(); + + if (poolVOS.size() == 0) { + throw new OperationFailureException(operr("cannot find cephPrimaryStorage pool[poolName=%s]", poolName)); + } + + return poolVOS.get(0); + } + + private void checkCephPoolCapacityForNewVolume(String poolName, long volumeSize, String psUuid) { + CephPrimaryStoragePoolVO poolVO = getPoolFromPoolName(poolName, psUuid, null); + + if (!new CephOsdGroupCapacityHelper(psUuid).checkVirtualSizeByRatio(poolVO.getUuid(), volumeSize)) { + throw new OperationFailureException(operr("cephPrimaryStorage pool[poolName=%s] available virtual capacity not enough for size %s", + poolName, volumeSize)); + } + } + + private String getPoolNameFromSystemTags(List systemTags, String volumeType) { + if (systemTags == null || systemTags.isEmpty()) { + return null; + } + + if (VolumeType.Root.toString().equals(volumeType)) { + return systemTags.stream().filter(tag -> TagUtils.isMatch(CephSystemTags.USE_CEPH_ROOT_POOL.getTagFormat(), tag)) + .map(tag -> TagUtils.parse(CephSystemTags.USE_CEPH_ROOT_POOL.getTagFormat(), tag).get(CephSystemTags.USE_CEPH_ROOT_POOL_TOKEN)) + .findFirst().orElse(null); + } else if (VolumeType.Data.toString().equals(volumeType)) { + return systemTags.stream().filter(tag -> TagUtils.isMatch(CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL.getTagFormat(), tag)) + .map(tag -> TagUtils.parse(CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL.getTagFormat(), tag).get(CephSystemTags.USE_CEPH_PRIMARY_STORAGE_POOL_TOKEN)) + .findFirst().orElse(null); + } + return null; + } + + private String getDataVolumeTargetPoolName(List systemTags, long volumeSize, String psUuid) { + String poolName = getPoolNameFromSystemTags(systemTags, VolumeType.Data.toString()); + return getPoolName(poolName, getDefaultDataVolumePoolName(psUuid), volumeSize, CephPrimaryStoragePoolType.Data.toString(), psUuid); + } + + private String getRootVolumeTargetPoolName(List systemTags, long volumeSize, String psUuid) { + String poolName = getPoolNameFromSystemTags(systemTags, VolumeType.Root.toString()); + return getPoolName(poolName, getDefaultRootVolumePoolName(psUuid), volumeSize, CephPrimaryStoragePoolType.Root.toString(), psUuid); + } + + private String getImageCachePoolTargetPoolName(String psUuid, long volumeSize) { + String imageCachePool = getDefaultImageCachePoolName(psUuid); + return getPoolName(null, imageCachePool, volumeSize, CephPrimaryStoragePoolType.ImageCache.toString(), psUuid); + } + + private String getPreAllocatedInstallUrl(AllocatePrimaryStorageSpaceMsg msg, String psUuid) { + final String purpose = msg.getPurpose(); + if (purpose.equals(PrimaryStorageAllocationPurpose.CreateNewVm.toString())|| + purpose.equals(PrimaryStorageAllocationPurpose.CreateRootVolume.toString())) { + return makePreAllocatedInstallUrl(getRootVolumeTargetPoolName(msg.getSystemTags(), msg.getSize(), psUuid)); + } else if (purpose.equals(PrimaryStorageAllocationPurpose.CreateDataVolume.toString())) { + return makePreAllocatedInstallUrl(getDataVolumeTargetPoolName(msg.getSystemTags(), msg.getSize(), psUuid)); + } else if (purpose.equals(PrimaryStorageAllocationPurpose.DownloadImage.toString())) { + return makePreAllocatedInstallUrl(getImageCachePoolTargetPoolName(psUuid, msg.getSize())); + } + + throw new OperationFailureException(operr("cannot allocate pool for primaryStorage[%s], purpose: %s", psUuid, purpose)); + } + + private String makePreAllocatedInstallUrl(String poolName) { + if (poolName == null) { + return null; + } + + return String.format("ceph://%s/", poolName); } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java index e8692af7e1f..2719c6cb77d 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageMonBase.java @@ -33,6 +33,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; import static org.zstack.core.Platform.operr; @@ -56,6 +57,7 @@ public class CephPrimaryStorageMonBase extends CephMonBase { public static final String ECHO_PATH = "/ceph/primarystorage/echo"; public static final String PING_PATH = "/ceph/primarystorage/ping"; + public static final String CONNECT_PATH = "/ceph/primarystorage/connect"; public enum PingOperationFailure { UnableToCreateFile, @@ -81,6 +83,12 @@ public static class PingRsp extends AgentRsp { public PingOperationFailure failure; } + public static class ConnectCmd extends AgentCmd { + } + + public static class ConnectRsp extends AgentRsp { + } + public CephPrimaryStorageMonVO getSelf() { return (CephPrimaryStorageMonVO) self; } @@ -203,14 +211,9 @@ public void run(final FlowTrigger trigger, Map data) { runner.setTargetUuid(getSelf().getUuid()); runner.setAgentPort(CephGlobalProperty.PRIMARY_STORAGE_AGENT_PORT); runner.setPlayBookName(CephGlobalProperty.PRIMARY_STORAGE_PLAYBOOK_NAME); - runner.putArgument("pkg_cephpagent", CephGlobalProperty.PRIMARY_STORAGE_PACKAGE_NAME); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - trigger.fail(operr("chrony server not configured!")); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } + + CephPrimaryStorageDeployArguments deployArguments = new CephPrimaryStorageDeployArguments(); + runner.setDeployArguments(deployArguments); runner.run(new ReturnValueCompletion(trigger) { @Override public void success(Boolean deployed) { @@ -320,6 +323,28 @@ public void fail(ErrorCode errorCode) { } }); + flow(new NoRollbackFlow() { + String __name__ = "connect-agent"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + ConnectCmd cmd = new ConnectCmd(); + cmd.monUuid = getSelf().getUuid(); + httpCall(CONNECT_PATH, cmd, new ReturnValueCompletion(trigger) { + @Override + public void success(AgentRsp rsp) { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { @@ -343,7 +368,7 @@ private void httpCall(String path, AgentCmd cmd, final ReturnValueCompletion void httpCall(String path, AgentCmd cmd, final Class rspClass, final ReturnValueCompletion completion) { + private void httpCall(String path, AgentCmd cmd, final Class rspClass, final ReturnValueCompletion completion) { restf.asyncJsonPost(CephAgentUrl.primaryStorageUrl(self.getHostname(), path), cmd, new JsonAsyncRESTCallback(completion) { @Override @@ -353,6 +378,10 @@ public void fail(ErrorCode err) { @Override public void success(T ret) { + if (!ret.isSuccess()) { + completion.fail(Platform.operr("operation error, because:%s", ret.getError())); + return; + } completion.success(ret); } @@ -363,26 +392,6 @@ public Class getReturnClass() { }); } - private void httpCall(String path, AgentCmd cmd, final Class rspClass, final ReturnValueCompletion completion, TimeUnit unit, long timeout) { - restf.asyncJsonPost(CephAgentUrl.primaryStorageUrl(self.getHostname(), path), - cmd, new JsonAsyncRESTCallback(completion) { - @Override - public void fail(ErrorCode err) { - completion.fail(err); - } - - @Override - public void success(T ret) { - completion.success(ret); - } - - @Override - public Class getReturnClass() { - return rspClass; - } - }, unit, timeout); - } - @Override public void ping(final ReturnValueCompletion completion) { thdf.chainSubmit(new ChainTask(completion) { @@ -458,6 +467,7 @@ public void fail(ErrorCode errorCode) { try { TimeUnit.SECONDS.sleep(sleep); } catch (InterruptedException ignored) { + Thread.currentThread().interrupt(); } } compl.done(); @@ -497,39 +507,37 @@ private void doPing(final ReturnValueCompletion completion) { cmd.primaryStorageUuid = getSelf().getPrimaryStorageUuid(); cmd.monAddr = String.format("%s:%s", getSelf().getMonAddr(), getSelf().getMonPort()); - httpCall(PING_PATH, cmd, PingRsp.class, new ReturnValueCompletion(completion) { - @Override - public void success(PingRsp rsp) { - PingResult res = new PingResult(); - if (rsp.success) { - res.success = true; - } else { - res.success = false; - res.error = rsp.error; - - // if agent met unexpected error, no failure will be set - if (rsp.failure != null) { - res.failure = rsp.failure.toString(); + restf.asyncJsonPost(CephAgentUrl.primaryStorageUrl(self.getHostname(), PING_PATH), + cmd, new JsonAsyncRESTCallback(completion) { + @Override + public void fail(ErrorCode err) { + completion.fail(err); } - } - if (rsp.success && rsp.availableCapacity != null && rsp.totalCapacity != null) { - String fsid = Q.New(CephPrimaryStorageVO.class) - .select(CephPrimaryStorageVO_.fsid) - .eq(CephPrimaryStorageVO_.uuid, primaryStorageUuid) - .findValue(); - CephCapacity cephCapacity = new CephCapacity(fsid, rsp); - new CephCapacityUpdater().update(cephCapacity); - } - - completion.success(res); - } + @Override + public void success(PingRsp rsp) { + PingResult res = new PingResult(); + res.success = rsp.isSuccess(); + res.error = rsp.getError(); + // if agent met unexpected error, no failure will be set + res.failure = Objects.toString(rsp.failure, null); + completion.success(res); + + if (rsp.isSuccess() && rsp.availableCapacity != null && rsp.totalCapacity != null) { + String fsid = Q.New(CephPrimaryStorageVO.class) + .select(CephPrimaryStorageVO_.fsid) + .eq(CephPrimaryStorageVO_.uuid, primaryStorageUuid) + .findValue(); + CephCapacity cephCapacity = new CephCapacity(fsid, rsp); + new CephCapacityUpdater().update(cephCapacity); + } + } - @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); - } - }, TimeUnit.SECONDS, 60); + @Override + public Class getReturnClass() { + return PingRsp.class; + } + }, TimeUnit.SECONDS, 60); } public CephPrimaryStorageMonBase(CephMonAO self) { diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolInventory.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolInventory.java index b308c7d2d1b..0c483662402 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolInventory.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolInventory.java @@ -38,12 +38,14 @@ public static CephPrimaryStoragePoolInventory valueOf(CephPrimaryStoragePoolVO v inv.lastOpDate = vo.getLastOpDate(); inv.aliasName = vo.getAliasName(); inv.type = vo.getType(); - inv.availableCapacity = vo.getAvailableCapacity(); inv.usedCapacity = vo.getUsedCapacity(); inv.replicatedSize = vo.getReplicatedSize(); inv.totalCapacity = vo.getTotalCapacity(); inv.diskUtilization = vo.getDiskUtilization(); inv.securityPolicy = vo.getSecurityPolicy(); + if (vo.getOsdGroup() != null) { + inv.availableCapacity = vo.getOsdGroup().getAvailableCapacity(); + } return inv; } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO.java index 689c53ace3a..55746aeb1bf 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO.java @@ -1,13 +1,12 @@ package org.zstack.storage.ceph.primary; +import org.zstack.header.allocator.HostCapacityVO; import org.zstack.header.storage.primary.PrimaryStorageEO; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.vo.*; import org.zstack.header.vo.ForeignKey; -import org.zstack.header.vo.ResourceVO; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.PreUpdate; -import javax.persistence.Table; +import javax.persistence.*; import java.sql.Timestamp; /** @@ -15,6 +14,9 @@ */ @Entity @Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = PrimaryStorageVO.class, joinColumn = "primaryStorageUuid") +}) public class CephPrimaryStoragePoolVO extends ResourceVO { @Column @ForeignKey(parentEntityClass = PrimaryStorageEO.class, parentKey = "uuid", onDeleteAction = ForeignKey.ReferenceOption.CASCADE) @@ -44,6 +46,18 @@ public class CephPrimaryStoragePoolVO extends ResourceVO { @Column private Float diskUtilization; + @ManyToOne + @JoinColumn(name = "osdGroupUuid") + private CephOsdGroupVO osdGroup; + + public CephOsdGroupVO getOsdGroup() { + return osdGroup; + } + + public void setOsdGroup(CephOsdGroupVO osdGroup) { + this.osdGroup = osdGroup; + } + public CephPrimaryStoragePoolVO() { } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO_.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO_.java index d24717d9169..a162554e255 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO_.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStoragePoolVO_.java @@ -15,6 +15,7 @@ public class CephPrimaryStoragePoolVO_ extends ResourceVO_ { public static volatile SingularAttribute poolName; public static volatile SingularAttribute aliasName; public static volatile SingularAttribute description; + public static volatile SingularAttribute osdGroup; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; public static volatile SingularAttribute type; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageSimulator.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageSimulator.java index 1c2ae18517e..a299050dd8d 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageSimulator.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephPrimaryStorageSimulator.java @@ -5,7 +5,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @@ -107,8 +106,7 @@ String initialize(HttpEntity entity) { InitRsp rsp = new InitRsp(); if (!config.monInitSuccess) { - rsp.error = "on purpose"; - rsp.success = false; + rsp.setError("on purpose"); } else { rsp.fsid = cpc.fsid; rsp.userKey = Platform.getUuid(); @@ -128,10 +126,9 @@ String checkPool(HttpEntity entity) { CheckRsp rsp = new CheckRsp(); if (!config.monInitSuccess) { - rsp.error = "on purpose"; - rsp.success = false; + rsp.setError("on purpose"); } else { - rsp.success = true; + rsp.setSuccess(true); } reply(entity, rsp); @@ -151,9 +148,9 @@ String pingMon(HttpEntity entity) { PingCmd cmd = JSONObjectUtil.toObject(entity.getBody(), PingCmd.class); Boolean success = config.pingCmdSuccess.get(cmd.monUuid); PingRsp rsp = new PingRsp(); - rsp.success = success == null ? true : success; - if (!rsp.success) { - rsp.error = "on purpose"; + rsp.setSuccess(success == null ? true : success); + if (!rsp.isSuccess()) { + rsp.setError("on purpose"); } rsp.failure = config.pingCmdOperationFailure.get(cmd.monUuid); reply(entity, rsp); @@ -183,8 +180,7 @@ String doCreateEmptyVolume(HttpEntity entity) throws InterruptedExceptio if (!path.equals(cmd.getInstallPath())) { continue; } - rsp.error = String.format("File exists[%s]", cmd.getInstallPath()); - rsp.setSuccess(false); + rsp.setError(String.format("File exists[%s]", cmd.getInstallPath())); reply(entity, rsp); return null; } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephRequiredUrlParser.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephRequiredUrlParser.java new file mode 100644 index 00000000000..d9b37f5cac5 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephRequiredUrlParser.java @@ -0,0 +1,89 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.core.db.Q; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.VolumeVO_; +import org.zstack.utils.DebugUtils; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; + +import static org.zstack.core.Platform.argerr; + +/** + * @ Author : yh.w + * @ Date : Created in 16:44 2022/8/30 + */ +public class CephRequiredUrlParser { + private static final HashMap uriParsers = new HashMap<>(); + + static { + parseRequiredInstallUri(); + } + + public static InstallPath getInstallPathFromUri(String requiredUrl) { + String protocol; + try { + protocol = new URI(requiredUrl).getScheme(); + } catch (URISyntaxException e) { + throw new OperationFailureException( + argerr("invalid uri, correct example is ceph://$POOLNAME/$VOLUMEUUID or volume://$VOLUMEUUID")); + } + + return uriParsers.get(protocol).parseUri(requiredUrl); + } + + public static class InstallPath { + public String fullPath; + public String poolName; + + public InstallPath disassemble() { + DebugUtils.Assert(fullPath != null, "fullPath cannot be null"); + String path = fullPath.replaceFirst("ceph://", ""); + poolName = path.substring(0, path.lastIndexOf("/")); + return this; + } + + public String makeFullPath() { + DebugUtils.Assert(poolName != null, "poolName cannot be null"); + fullPath = String.format("ceph://%s/", poolName); + return fullPath; + } + } + + abstract static class AbstractUriParser { + abstract InstallPath parseUri(String uri); + } + + private static void parseRequiredInstallUri() { + String protocolVolume = "volume"; + String protocolCeph = "ceph"; + + AbstractUriParser volumeParser = new AbstractUriParser() { + @Override + InstallPath parseUri(String uri) { + String volumeUuid = uri.replaceFirst("volume://", ""); + String path = Q.New(VolumeVO.class).select(VolumeVO_.installPath).eq(VolumeVO_.uuid, volumeUuid).findValue(); + InstallPath p = new InstallPath(); + p.fullPath = path; + p.disassemble(); + return p; + } + }; + + AbstractUriParser cephParser = new AbstractUriParser() { + @Override + InstallPath parseUri(String uri) { + InstallPath p = new InstallPath(); + p.fullPath = uri; + p.disassemble(); + return p; + } + }; + + uriParsers.put(protocolVolume, volumeParser); + uriParsers.put(protocolCeph, cephParser); + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephSnapshotProtector.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephSnapshotProtector.java index af991e60f1b..c08a1528399 100755 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephSnapshotProtector.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephSnapshotProtector.java @@ -1,7 +1,6 @@ package org.zstack.storage.ceph.primary; import org.zstack.header.core.Completion; -import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.storage.snapshot.VolumeSnapshotDeletionProtector; import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; import org.zstack.storage.ceph.CephConstants; @@ -29,7 +28,7 @@ public void protect(VolumeSnapshotInventory snapshot, Completion completion) { completion.success(); } - if (volUuids.stream().noneMatch(it -> snapshot.getPrimaryStorageInstallPath().contains(it))) { + if (volUuids.stream().noneMatch(it -> snapshot.getPrimaryStorageInstallPath().contains(it)) && !VolumeSystemTags.FAST_REVERT.hasTag(snapshot.getVolumeUuid())) { completion.fail(inerr("the snapshot[name:%s, uuid:%s, path: %s] seems not belong to the volume[uuid:%s]", snapshot.getName(), snapshot.getUuid(), snapshot.getPrimaryStorageInstallPath(), snapshot.getVolumeUuid())); return; diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java index eb588b65b94..0a8695b80aa 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephStorageAttachKvmClusterMetric.java @@ -9,15 +9,9 @@ import static org.zstack.core.Platform.argerr; public class CephStorageAttachKvmClusterMetric implements StorageAttachClusterMetric { - private boolean isThirdPartyCephWithToken(String psUuid) { - return CephSystemTags.THIRDPARTY_PLATFORM.hasTag(psUuid); - } @Override - public void checkSupport(String psUuid, String clusterUuid) throws ApiMessageInterceptionException { - if(isThirdPartyCephWithToken(psUuid)){ - throw new ApiMessageInterceptionException(argerr("Can not attach third-party ceph with token into kvm cluster.")); - } + public void checkSupport(String psUuid, String clusterUuid) { } @Override diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephToCephMigrateVolumeSegmentMsg.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephToCephMigrateVolumeSegmentMsg.java index 6f2925295d9..de4896f463f 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephToCephMigrateVolumeSegmentMsg.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephToCephMigrateVolumeSegmentMsg.java @@ -5,6 +5,7 @@ import org.zstack.header.storage.primary.PrimaryStorageMessage; import java.io.Serializable; +import java.util.List; /** * Created by GuoYi on 10/19/17. @@ -14,13 +15,9 @@ public class CephToCephMigrateVolumeSegmentMsg extends NeedReplyMessage implemen private String resourceUuid; private String srcInstallPath; private String dstInstallPath; - private String dstMonHostname; - private String dstMonSshUsername; - @NoLogging - private String dstMonSshPassword; - private int dstMonSshPort; private String primaryStorageUuid; private boolean isXsky; + private String dstPrimaryStorageUuid; public String getParentUuid() { return parentUuid; @@ -54,38 +51,6 @@ public void setDstInstallPath(String dstInstallPath) { this.dstInstallPath = dstInstallPath; } - public String getDstMonHostname() { - return dstMonHostname; - } - - public void setDstMonHostname(String dstMonHostname) { - this.dstMonHostname = dstMonHostname; - } - - public String getDstMonSshUsername() { - return dstMonSshUsername; - } - - public void setDstMonSshUsername(String dstMonSshUsername) { - this.dstMonSshUsername = dstMonSshUsername; - } - - public String getDstMonSshPassword() { - return dstMonSshPassword; - } - - public void setDstMonSshPassword(String dstMonSshPassword) { - this.dstMonSshPassword = dstMonSshPassword; - } - - public int getDstMonSshPort() { - return dstMonSshPort; - } - - public void setDstMonSshPort(int dstMonSshPort) { - this.dstMonSshPort = dstMonSshPort; - } - @Override public String getPrimaryStorageUuid() { return primaryStorageUuid; @@ -102,4 +67,12 @@ public boolean isXsky() { public void setXsky(boolean xsky) { isXsky = xsky; } + + public String getDstPrimaryStorageUuid() { + return dstPrimaryStorageUuid; + } + + public void setDstPrimaryStorageUuid(String dstPrimaryStorageUuid) { + this.dstPrimaryStorageUuid = dstPrimaryStorageUuid; + } } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephTrashCleaner.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephTrashCleaner.java new file mode 100644 index 00000000000..b11df97fcfa --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephTrashCleaner.java @@ -0,0 +1,114 @@ +package org.zstack.storage.ceph.primary; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.ResourceDestinationMaker; +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.db.Q; +import org.zstack.core.thread.PeriodicTask; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.primary.CleanUpStorageTrashOnPrimaryStorageMsg; +import org.zstack.header.storage.primary.PrimaryStorageConstant; +import org.zstack.storage.ceph.CephGlobalConfig; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public class CephTrashCleaner implements ManagementNodeReadyExtensionPoint { + private static final CLogger logger = Utils.getLogger(CephTrashCleaner.class); + @Autowired + protected ThreadFacade thdf; + @Autowired + protected ResourceDestinationMaker destMaker; + @Autowired + protected CloudBus bus; + + private Future gcThread; + + private GlobalConfig cleanupIntervalConfig() { + return CephGlobalConfig.TRASH_CLEANUP_INTERVAL; + } + + @Override + public void managementNodeReady() { + startGC(); + } + + private void startGC() { + cleanupIntervalConfig().installUpdateExtension((oldConfig, newConfig) -> startGCThread()); + startGCThread(); + } + + synchronized private void startGCThread() { + if (gcThread != null) { + gcThread.cancel(true); + } + + logger.debug(String.format("%s starts with the interval %s secs", this.getClass().getSimpleName(), cleanupIntervalConfig().value(Long.class))); + + gcThread = thdf.submitPeriodicTask(new PeriodicTask() { + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + public long getInterval() { + return cleanupIntervalConfig().value(Long.class); + } + + @Override + public String getName() { + return "ceph-trash-cleanup-thread"; + } + + @Override + public void run() { + cleanup(null, true); + } + }); + } + + protected void cleanup(String primaryStorageUuid, boolean needDestinationCheck) { + List cephPsUuids = new ArrayList<>(); + if (primaryStorageUuid == null) { + cephPsUuids = Q.New(CephPrimaryStorageVO.class) + .select(CephPrimaryStorageVO_.uuid) + .listValues(); + } else { + cephPsUuids.add(primaryStorageUuid); + } + + new While<>(cephPsUuids).step((psUuid, comp) -> { + if (needDestinationCheck && !destMaker.isManagedByUs(psUuid)) { + comp.done(); + return; + } + + CleanUpStorageTrashOnPrimaryStorageMsg cmsg = new CleanUpStorageTrashOnPrimaryStorageMsg(); + cmsg.setForce(false); + cmsg.setPrimaryStorageUuid(psUuid); + bus.makeTargetServiceIdByResourceUuid(cmsg, PrimaryStorageConstant.SERVICE_ID, psUuid); + bus.send(cmsg, new CloudBusCallBack(comp) { + @Override + public void run(MessageReply reply) { + comp.done(); + } + }); + }, 3).run(new WhileDoneCompletion(null) { + @Override + public void done(ErrorCodeList errorCodeList) { + } + }); + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephVolumeSnapshotAfterDeleteExtension.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephVolumeSnapshotAfterDeleteExtension.java new file mode 100644 index 00000000000..71287bce671 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CephVolumeSnapshotAfterDeleteExtension.java @@ -0,0 +1,72 @@ +package org.zstack.storage.ceph.primary; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.SQL; +import org.zstack.core.trash.StorageTrash; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.storage.primary.DeleteVolumeBitsOnPrimaryStorageMsg; +import org.zstack.header.storage.primary.PrimaryStorageConstant; +import org.zstack.header.storage.snapshot.VolumeSnapshotAfterDeleteExtensionPoint; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeVO; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.zstack.storage.ceph.CephConstants.CEPH_PRIMARY_STORAGE_TYPE; + +public class CephVolumeSnapshotAfterDeleteExtension implements VolumeSnapshotAfterDeleteExtensionPoint { + @Autowired + private CloudBus bus; + @Autowired + private StorageTrash trash; + + private static final CLogger logger = Utils.getLogger(CephVolumeSnapshotAfterDeleteExtension.class); + + @Override + public void volumeSnapshotAfterDeleteExtensionPoint(VolumeSnapshotInventory snapshot, NoErrorCompletion completion) { + completion.done(); + } + + private String getVolumeInstallPathFromSnapshot(String snapshotInstallPath) { + return snapshotInstallPath.split("@")[0]; + } + + private boolean isCephPs(String volumeUuid) { + String sql = "select ps.type from PrimaryStorageVO ps, VolumeVO vol where vol.primaryStorageUuid = ps.uuid and vol.uuid = :volUuid"; + return CEPH_PRIMARY_STORAGE_TYPE.equals(SQL.New(sql, String.class).param("volUuid", volumeUuid).find()); + } + + @Override + public void volumeSnapshotAfterCleanUpExtensionPoint(String volumeUuid, List snapshots) { + if (CollectionUtils.isEmpty(snapshots) || !isCephPs(volumeUuid)) { + return; + } + + Set volumeInstallPaths = snapshots.stream().map(sp -> getVolumeInstallPathFromSnapshot(sp.getPrimaryStorageInstallPath())) + .collect(Collectors.toSet()); + if (volumeInstallPaths.isEmpty()) { + return; + } + + volumeInstallPaths.forEach(volumeInstallPath -> { + String details = trash.makeSureInstallPathNotUsed(volumeInstallPath, VolumeVO.class.getSimpleName()); + + if (StringUtils.isBlank(details)) { + logger.debug(String.format("delete volume[InstallPath:%s] after cleaning up snapshots", volumeInstallPath)); + DeleteVolumeBitsOnPrimaryStorageMsg msg = new DeleteVolumeBitsOnPrimaryStorageMsg(); + msg.setPrimaryStorageUuid(snapshots.get(0).getPrimaryStorageUuid()); + msg.setInstallPath(volumeInstallPath); + bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, snapshots.get(0).getPrimaryStorageUuid()); + bus.send(msg); + } + }); + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CheckHostStorageConnectionReply.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CheckHostStorageConnectionReply.java deleted file mode 100644 index 7766a0eea9e..00000000000 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/CheckHostStorageConnectionReply.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.zstack.storage.ceph.primary; - -import org.zstack.header.message.MessageReply; - -public class CheckHostStorageConnectionReply extends MessageReply { -} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/PoolUsageReport.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/PoolUsageReport.java new file mode 100644 index 00000000000..303c32eadc0 --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/PoolUsageReport.java @@ -0,0 +1,21 @@ +package org.zstack.storage.ceph.primary; + +import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.storage.primary.AbstractUsageReport; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class PoolUsageReport extends + AbstractUsageReport implements ManagementNodeReadyExtensionPoint { + private static final CLogger logger = Utils.getLogger(PoolUsageReport.class); + + { + capacityClass = CephOsdGroupVO.class; + usageClass = CephOsdGroupHistoricalUsageVO.class; + } + + @Override + public void managementNodeReady() { + start(); + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java new file mode 100644 index 00000000000..1ca0a262c1d --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/CephOsdGroupCapacityHelper.java @@ -0,0 +1,326 @@ +package org.zstack.storage.ceph.primary.capacity; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.logging.log4j.util.Strings; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.DeadlockAutoRestart; +import org.zstack.core.db.Q; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.storage.primary.ImageCacheVO; +import org.zstack.header.storage.primary.ImageCacheVO_; +import org.zstack.header.storage.primary.PrimaryStorageOverProvisioningManager; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO_; +import org.zstack.header.volume.VolumeStatus; +import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.VolumeVO_; +import org.zstack.storage.ceph.CephCapacity; +import org.zstack.storage.ceph.CephPoolCapacity; +import org.zstack.storage.ceph.primary.CephOsdGroupVO; +import org.zstack.storage.ceph.primary.CephOsdGroupVO_; +import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO; +import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO_; +import org.zstack.storage.primary.PrimaryStorageCapacityChecker; +import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.stopwatch.StopWatch; + +import javax.transaction.Transactional; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.operr; + +/** + * @ Author : yh.w + * @ Date : Created in 18:35 2022/8/2 + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class CephOsdGroupCapacityHelper { + @Autowired + protected PrimaryStorageOverProvisioningManager ratioMgr; + @Autowired + protected DatabaseFacade dbf; + + private String primaryStorageUuid; + + private static final CLogger logger = Utils.getLogger(CephOsdGroupCapacityHelper.class); + + public CephOsdGroupCapacityHelper() { + } + + public CephOsdGroupCapacityHelper(String psUuid) { + this.primaryStorageUuid = psUuid; + } + + private List getOsdGroupRelatedPools(String osdGroupUuid) { + List pools = Q.New(CephPrimaryStoragePoolVO.class) + .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, primaryStorageUuid) + .list(); + return pools.stream() + .filter(v -> v.getOsdGroup() != null && v.getOsdGroup().getUuid().equals(osdGroupUuid)) + .sorted(Comparator.comparing(CephPrimaryStoragePoolVO::getTotalCapacity)) + .collect(Collectors.toList()); + } + + public void fillCapacityFromPool() { + List osdgs = Q.New(CephOsdGroupVO.class) + .eq(CephOsdGroupVO_.primaryStorageUuid, primaryStorageUuid) + .list(); + for (CephOsdGroupVO osdg : osdgs) { + List pools = getOsdGroupRelatedPools(osdg.getUuid()); + if (CollectionUtils.isEmpty(pools)) { + logger.warn(String.format("it seems that osd group[%s] has no related pools", osdg.getUuid())); + continue; + } + CephPrimaryStoragePoolVO poolVO = pools.get(0); + osdg.setAvailablePhysicalCapacity(poolVO.getAvailableCapacity()); + osdg.setTotalPhysicalCapacity(poolVO.getTotalCapacity()); + dbf.getEntityManager().merge(osdg); + } + } + + private String getPoolUuidFromInstallPath(String installPath) { + String path = installPath.replaceFirst("ceph://", ""); + String poolName = path.substring(0, path.lastIndexOf("/")); + + String poolUuid = Q.New(CephPrimaryStoragePoolVO.class) + .select(CephPrimaryStoragePoolVO_.uuid) + .eq(CephPrimaryStoragePoolVO_.poolName, poolName) + .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, primaryStorageUuid) + .limit(1) + .findValue(); + + if (poolUuid == null) { + logger.info(String.format("cannot find path[%s] related pool, maybe pool has been deleted", path)); + return null; + } + + return poolUuid; + } + + @DeadlockAutoRestart + public void releaseAvailableCapWithRatio(String installPath, long size) { + long ratioSize = ratioMgr.calculateByRatio(primaryStorageUuid, size); + _release(installPath, ratioSize); + } + + @DeadlockAutoRestart + public void releaseAvailableCapacity(String installPath, long size) { + _release(installPath, size); + } + + @Transactional + private void _release(String installPath, long size) { + if (installPath == null) { + logger.debug("no install path found, skip release ceph pool capacity"); + return; + } + + String poolUuid = getPoolUuidFromInstallPath(installPath); + if (poolUuid == null) { + return; + } + + CephPrimaryStoragePoolVO pool = dbf.findByUuid(poolUuid, CephPrimaryStoragePoolVO.class); + if (pool.getOsdGroup() == null) { + logger.warn(String.format("cannot find ceph pool [%s] related osdgroup", poolUuid)); + return; + } + CephOsdGroupVO osdGroupVO = pool.getOsdGroup(); + osdGroupVO.setAvailableCapacity(osdGroupVO.getAvailableCapacity() + size); + if (osdGroupVO.getAvailableCapacity() > osdGroupVO.getTotalPhysicalCapacity()) { + logger.warn(String.format("invalid pool[uuid:%s] capacity after release size %s, available capacity[%s] > total capacity[%s], " + + "try to reconnect ceph ps to recalculate pool capacity", + poolUuid, size, osdGroupVO.getAvailableCapacity(), osdGroupVO.getTotalPhysicalCapacity())); + } + + logger.debug(String.format("ceph osd group[%s] release capacity: %s, updated: %s", + osdGroupVO.getUuid(), size, osdGroupVO.getAvailableCapacity())); + dbf.getEntityManager().merge(osdGroupVO); + } + + @DeadlockAutoRestart + public long reserveAvailableCapacity(String installPath, long size) { + return _reserve(installPath, size); + } + + @Transactional + private long _reserve(String installPath, long size) { + if (installPath == null) { + logger.debug("no install path found, skip reserve ceph pool capacity"); + return 0; + } + + String poolUuid = getPoolUuidFromInstallPath(installPath); + if (poolUuid == null) { + return 0; + } + + CephPrimaryStoragePoolVO pool = dbf.findByUuid(poolUuid, CephPrimaryStoragePoolVO.class); + if (pool.getOsdGroup() == null) { + logger.warn(String.format("cannot find ceph pool [%s] related osdgroup", poolUuid)); + return 0; + } + CephOsdGroupVO osdGroupVO = dbf.findByUuid(pool.getOsdGroup().getUuid(), CephOsdGroupVO.class); + long originAvailableCapacity = osdGroupVO.getAvailableCapacity(); + if (originAvailableCapacity < size) { + throw new OperationFailureException(operr("required ceph pool[uuid:%s] cannot satisfy conditions [availableSize > %s bytes], " + + "current available size %s", poolUuid, size, originAvailableCapacity)); + } + + osdGroupVO.setAvailableCapacity(osdGroupVO.getAvailableCapacity() - size); + dbf.getEntityManager().merge(osdGroupVO); + + logger.debug(String.format("ceph osd group[%s] reserve capacity: %s, origin: %s, updated: %s", + osdGroupVO.getUuid(), size, originAvailableCapacity, osdGroupVO.getAvailableCapacity())); + return originAvailableCapacity; + } + + public void recalculateAvailableCapacity() { + List osdGroups = Q.New(CephOsdGroupVO.class) + .eq(CephOsdGroupVO_.primaryStorageUuid, primaryStorageUuid) + .list(); + + for (CephOsdGroupVO osdGroupVO : osdGroups) { + Long size = calculateAvailableCapacityByRatio(osdGroupVO, primaryStorageUuid); + logger.info(String.format("ceph[%s] get osd group[%s] available virtual size: %s", primaryStorageUuid, osdGroupVO.getOsds(), size)); + osdGroupVO.setAvailableCapacity(size); + dbf.update(osdGroupVO); + } + } + + public boolean checkVirtualSizeByRatio(String poolUuid, long requiredSize) { + CephPrimaryStoragePoolVO pool = dbf.findByUuid(poolUuid, CephPrimaryStoragePoolVO.class); + if (pool.getOsdGroup() == null) { + throw new OperationFailureException(operr("cannot find ceph pool [%s] related osdgroup", poolUuid)); + } + + CephOsdGroupVO osdGroupVO = dbf.findByUuid(pool.getOsdGroup().getUuid(), CephOsdGroupVO.class); + return PrimaryStorageCapacityChecker.New(osdGroupVO.getPrimaryStorageUuid(), + osdGroupVO.getAvailableCapacity(), osdGroupVO.getTotalPhysicalCapacity(), osdGroupVO.getAvailablePhysicalCapacity()) + .checkRequiredSize(requiredSize); + } + + public Long calculateAvailableCapacityByRatio(CephOsdGroupVO osdGroup, String primaryStorageUuid) { + StopWatch watch = Utils.getStopWatch(); + watch.start(); + List pools = getOsdGroupRelatedPools(osdGroup.getUuid()); + + if (pools.isEmpty()) { + logger.warn(String.format("ceph osd group[%s] has no related pools, skip it", osdGroup.getUuid())); + return 0L; + } + + List poolNames = pools.stream() + .map(CephPrimaryStoragePoolVO::getPoolName) + .collect(Collectors.toList()); + + poolNames = poolNames.stream().distinct().collect(Collectors.toList()); + + long usedSize = 0; + + List needCountVolumeStates = asList(VolumeStatus.Creating, VolumeStatus.Ready, VolumeStatus.Deleted); + List volumes = Q.New(VolumeVO.class) + .in(VolumeVO_.status, needCountVolumeStates) + .eq(VolumeVO_.primaryStorageUuid, primaryStorageUuid) + .list(); + List imageCaches = Q.New(ImageCacheVO.class).eq(ImageCacheVO_.primaryStorageUuid, primaryStorageUuid).list(); + List snapshots = Q.New(VolumeSnapshotVO.class).eq(VolumeSnapshotVO_.primaryStorageUuid, primaryStorageUuid).list(); + + for (String poolName : poolNames) { + String installPathPrefix = String.format("ceph://%s", poolName); + long volSize = volumes.parallelStream() + .filter(v -> Strings.isNotEmpty(v.getInstallPath()) && v.getInstallPath() + .substring(0, v.getInstallPath().lastIndexOf("/")) + .equals((installPathPrefix))) + .map(VolumeVO::getSize) + .map(v -> Long.parseLong(String.valueOf(v))) + .reduce(0L, Long::sum); + + long imageCacheSize = imageCaches.parallelStream() + .filter(v -> Strings.isNotEmpty(v.getInstallUrl()) && v.getInstallUrl() + .substring(0, v.getInstallUrl().lastIndexOf("/")) + .equals((installPathPrefix))) + .map(ImageCacheVO::getSize) + .map(v -> Long.parseLong(String.valueOf(v))) + .reduce(0L, Long::sum); + + long snapShotSize = snapshots.parallelStream() + .filter(v -> Strings.isNotEmpty(v.getPrimaryStorageInstallPath()) && v.getPrimaryStorageInstallPath() + .substring(0, v.getPrimaryStorageInstallPath().lastIndexOf("/")) + .equals((installPathPrefix))) + .map(VolumeSnapshotVO::getSize) + .map(v -> Long.parseLong(String.valueOf(v))) + .reduce(0L, Long::sum); + + usedSize = usedSize + ratioMgr.calculateByRatio(primaryStorageUuid, volSize) + imageCacheSize + snapShotSize; + } + + watch.stop(); + logger.info(String.format("it cost %d ms to calculate osdGroup[%s] used virtual size", watch.getLapse() ,osdGroup.getUuid())); + return osdGroup.getTotalPhysicalCapacity() - usedSize; + } + + public void calculatePrimaryStorageCapacityByOsds(CephCapacity cephCapacity) { + long total = cephCapacity.getTotalCapacity(); + long avail = cephCapacity.getAvailableCapacity(); + List poolCapacities = cephCapacity.getPoolCapacities(); + + PrimaryStorageCapacityUpdater updater = new PrimaryStorageCapacityUpdater(primaryStorageUuid); + updater.run(cap -> { + Map osdPoolCapacity = new HashMap<>(); + List poolsName = Q.New(CephPrimaryStoragePoolVO.class) + .select(CephPrimaryStoragePoolVO_.poolName) + .eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, primaryStorageUuid) + .listValues(); + for (CephPoolCapacity poolCapacitiy : poolCapacities) { + if (poolCapacitiy.getRelatedOsdCapacity() == null || !poolsName.contains(poolCapacitiy.getName())) { + continue; + } + + Map osdPoolCap = poolCapacitiy.getRelatedOsdCapacity().keySet().stream() + .collect(Collectors.toMap(osdName -> osdName, osdName -> { + if (!osdPoolCapacity.containsKey(osdName)) { + return poolCapacitiy; + } + // osd multiplexing + Float diskUtilization = osdPoolCapacity.get(osdName).getDiskUtilization(); + return diskUtilization > poolCapacitiy.getDiskUtilization() ? poolCapacitiy : osdPoolCapacity.get(osdName); + })); + osdPoolCapacity.putAll(osdPoolCap); + } + + long osdsTotalSize = 0; + long osdsAvailCap = 0; + for (String osdName : osdPoolCapacity.keySet()) { + CephPoolCapacity cephPoolCapacity = osdPoolCapacity.get(osdName); + osdsTotalSize += cephPoolCapacity.getRelatedOsdCapacity().get(osdName).getSize() * cephPoolCapacity.getDiskUtilization(); + osdsAvailCap += cephPoolCapacity.getRelatedOsdCapacity().get(osdName).getAvailableCapacity() * cephPoolCapacity.getDiskUtilization(); + } + if (osdsTotalSize == 0) { + logger.debug("no osds related to pool found, using bare capacity instead, fsid: " + cephCapacity.getFsid()); + osdsTotalSize = total; + osdsAvailCap = avail; + } + + if (cap.getTotalCapacity() == 0 || cap.getAvailableCapacity() == 0) { + // init + cap.setAvailableCapacity(osdsAvailCap); + } + + cap.setTotalCapacity(osdsTotalSize); + cap.setTotalPhysicalCapacity(osdsTotalSize); + cap.setAvailablePhysicalCapacity(osdsAvailCap); + return cap; + }); + } +} diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/EnterpriseCephPrimaryCapacityBaseUpdater.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/EnterpriseCephPrimaryCapacityBaseUpdater.java index 8b61d2b2f7d..163a013691c 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/EnterpriseCephPrimaryCapacityBaseUpdater.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/EnterpriseCephPrimaryCapacityBaseUpdater.java @@ -3,19 +3,27 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.db.SQLBatch; import org.zstack.header.storage.primary.PrimaryStorageCapacityUpdaterRunnable; import org.zstack.header.storage.primary.PrimaryStorageCapacityVO; import org.zstack.storage.ceph.CephCapacity; import org.zstack.storage.ceph.CephPoolCapacity; -import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO; -import org.zstack.storage.ceph.primary.CephPrimaryStorageVO; +import org.zstack.storage.ceph.primary.*; import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.groupingBy; /** * Created by lining on 2021/1/22. @@ -25,6 +33,8 @@ public abstract class EnterpriseCephPrimaryCapacityBaseUpdater implements CephPr @Autowired private DatabaseFacade dbf; + private static final CLogger logger = Utils.getLogger(EnterpriseCephPrimaryCapacityBaseUpdater.class); + @Override public void update(CephCapacity cephCapacity) { String fsid = cephCapacity.getFsid(); @@ -41,29 +51,47 @@ public void update(CephCapacity cephCapacity) { return; } + CephOsdGroupCapacityHelper osdHelper = new CephOsdGroupCapacityHelper(cephPs.getUuid()); + osdHelper.calculatePrimaryStorageCapacityByOsds(cephCapacity); + List poolNames = new ArrayList<>(); - List poolTotalCapacities = new ArrayList<>(); - List poolAvailableCapacities = new ArrayList<>(); new SQLBatch() { @Override protected void scripts() { - List pools = sql("select pool from CephPrimaryStoragePoolVO pool, CephPrimaryStorageVO ps" + - " where pool.primaryStorageUuid = ps.uuid and ps.fsid = :fsid", CephPrimaryStoragePoolVO.class) - .param("fsid", fsid) - .list(); - if (pools == null) { - pools = new ArrayList<>(); + Map> caps = poolCapacities.stream().collect(groupingBy(CephPoolCapacity::getRelatedOsds)); + + Set osdGroups = caps.keySet(); + logger.info(String.format("ceph[%s] primary storage found osd groups %s", cephPs.getUuid(), osdGroups)); + + List existedOsdGroups = Q.New(CephOsdGroupVO.class).eq(CephOsdGroupVO_.primaryStorageUuid, cephPs.getUuid()).list(); + List needDeleteOsds = existedOsdGroups.stream() + .filter(v -> !osdGroups.contains(v.getOsds())).collect(Collectors.toList()); + List needCreateOsds = osdGroups.stream() + .filter(v -> existedOsdGroups.stream().noneMatch(a -> a.getOsds().equals(v))).collect(Collectors.toList()); + + if (!needDeleteOsds.isEmpty()) { + logger.info(String.format("remove %s stale osd groups", needDeleteOsds.size())); + needDeleteOsds.forEach(this::remove); + } + + List newOsdGroups = new ArrayList<>(); + for (String osds : needCreateOsds) { + CephOsdGroupVO vo = new CephOsdGroupVO(); + vo.setUuid(Platform.getUuid()); + vo.setOsds(osds); + vo.setPrimaryStorageUuid(cephPs.getUuid()); + newOsdGroups.add(vo); } + newOsdGroups.forEach(this::persist); + List pools = Q.New(CephPrimaryStoragePoolVO.class).eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, cephPs.getUuid()).list(); for (CephPrimaryStoragePoolVO poolVO : pools) { if (!poolCapacities.stream().anyMatch((e) -> poolVO.getPoolName().equals(e.getName()))) { if (poolNames.contains(poolVO.getPoolName())) { continue; } poolNames.add(poolVO.getPoolName()); - poolAvailableCapacities.add(poolVO.getAvailableCapacity()); - poolTotalCapacities.add(poolVO.getTotalCapacity()); continue; } @@ -73,8 +101,17 @@ protected void scripts() { if (!poolNames.contains(poolVO.getPoolName())) { poolNames.add(poolVO.getPoolName()); - poolAvailableCapacities.add(poolCapacity.getAvailableCapacity()); - poolTotalCapacities.add(poolCapacity.getTotalCapacity()); + } + + CephOsdGroupVO osdGroupVO = Q.New(CephOsdGroupVO.class) + .eq(CephOsdGroupVO_.osds, poolCapacity.getRelatedOsds()) + .eq(CephOsdGroupVO_.primaryStorageUuid, cephPs.getUuid()) + .find(); + + // ceph pool related osds has changed + if (poolVO.getOsdGroup() == null || (poolVO.getOsdGroup() != null && + !poolVO.getOsdGroup().getUuid().equals(osdGroupVO.getUuid()))) { + poolVO.setOsdGroup(osdGroupVO); } poolVO.setAvailableCapacity(poolCapacity.getAvailableCapacity()); @@ -83,27 +120,11 @@ protected void scripts() { poolVO.setTotalCapacity(poolCapacity.getTotalCapacity()); poolVO.setDiskUtilization(poolCapacity.getDiskUtilization()); poolVO.setSecurityPolicy(poolCapacity.getSecurityPolicy()); + dbf.getEntityManager().merge(poolVO); } - long psTotalPhysicalCapacity = poolTotalCapacities.stream().mapToLong(Long::longValue).sum(); - long psAvailablePhysicalCapacity = poolAvailableCapacities.stream().mapToLong(Long::longValue).sum(); - - PrimaryStorageCapacityUpdater updater = new PrimaryStorageCapacityUpdater(cephPs.getUuid()); - updater.run(new PrimaryStorageCapacityUpdaterRunnable() { - @Override - public PrimaryStorageCapacityVO call(PrimaryStorageCapacityVO cap) { - if (cap.getTotalCapacity() == 0 || cap.getAvailableCapacity() == 0) { - // init - cap.setAvailableCapacity(psTotalPhysicalCapacity); - } - cap.setTotalCapacity(psTotalPhysicalCapacity); - cap.setTotalPhysicalCapacity(psTotalPhysicalCapacity); - cap.setAvailablePhysicalCapacity(psAvailablePhysicalCapacity); - - return cap; - } - }); + osdHelper.fillCapacityFromPool(); } }.execute(); } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/OpenSourceCephPrimaryCapacityUpdater.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/OpenSourceCephPrimaryCapacityUpdater.java index 9ef276fd983..a3b065d5120 100644 --- a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/OpenSourceCephPrimaryCapacityUpdater.java +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/OpenSourceCephPrimaryCapacityUpdater.java @@ -1,22 +1,26 @@ package org.zstack.storage.ceph.primary.capacity; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.db.SQLBatch; -import org.zstack.header.storage.primary.PrimaryStorageCapacityUpdaterRunnable; -import org.zstack.header.storage.primary.PrimaryStorageCapacityVO; import org.zstack.storage.ceph.CephCapacity; import org.zstack.storage.ceph.CephConstants; import org.zstack.storage.ceph.CephPoolCapacity; -import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO; -import org.zstack.storage.ceph.primary.CephPrimaryStorageVO; +import org.zstack.storage.ceph.primary.*; import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.groupingBy; /** * Created by lining on 2021/1/22. @@ -26,6 +30,8 @@ public class OpenSourceCephPrimaryCapacityUpdater implements CephPrimaryCapacity @Autowired private DatabaseFacade dbf; + private static final CLogger logger = Utils.getLogger(OpenSourceCephPrimaryCapacityUpdater.class); + @Override public String getCephManufacturer() { return CephConstants.CEPH_MANUFACTURER_OPENSOURCE; @@ -34,8 +40,6 @@ public String getCephManufacturer() { @Override public void update(CephCapacity cephCapacity) { String fsid = cephCapacity.getFsid(); - long total = cephCapacity.getTotalCapacity(); - long avail = cephCapacity.getAvailableCapacity(); List poolCapacities = cephCapacity.getPoolCapacities(); CephPrimaryStorageVO cephPs = SQL.New("select pri from CephPrimaryStorageVO pri where pri.fsid = :fsid",CephPrimaryStorageVO.class) @@ -47,37 +51,42 @@ public void update(CephCapacity cephCapacity) { List poolNames = new ArrayList<>(); - PrimaryStorageCapacityUpdater updater = new PrimaryStorageCapacityUpdater(cephPs.getUuid()); - updater.run(new PrimaryStorageCapacityUpdaterRunnable() { - @Override - public PrimaryStorageCapacityVO call(PrimaryStorageCapacityVO cap) { - if (cap.getTotalCapacity() == 0 || cap.getAvailableCapacity() == 0) { - // init - cap.setAvailableCapacity(avail); - } - - cap.setTotalCapacity(total); - cap.setTotalPhysicalCapacity(total); - cap.setAvailablePhysicalCapacity(avail); - return cap; - } - }); - if (poolCapacities == null) { return; } + CephOsdGroupCapacityHelper osdHelper = new CephOsdGroupCapacityHelper(cephPs.getUuid()); + osdHelper.calculatePrimaryStorageCapacityByOsds(cephCapacity); new SQLBatch() { @Override protected void scripts() { - List pools = sql("select pool from CephPrimaryStoragePoolVO pool, CephPrimaryStorageVO ps" + - " where pool.primaryStorageUuid = ps.uuid and ps.fsid = :fsid", CephPrimaryStoragePoolVO.class) - .param("fsid", fsid) - .list(); - if (pools == null) { - pools = new ArrayList<>(); + Map> caps = poolCapacities.stream().collect(groupingBy(CephPoolCapacity::getRelatedOsds)); + + Set osdGroups = caps.keySet(); + logger.info(String.format("ceph[%s] primary storage found osd groups %s", cephPs.getUuid(), osdGroups)); + + List existedOsdGroups = Q.New(CephOsdGroupVO.class).eq(CephOsdGroupVO_.primaryStorageUuid, cephPs.getUuid()).list(); + List needDeleteOsds = existedOsdGroups.stream() + .filter(v -> !osdGroups.contains(v.getOsds())).collect(Collectors.toList()); + List needCreateOsds = osdGroups.stream() + .filter(v -> existedOsdGroups.stream().noneMatch(a -> a.getOsds().equals(v))).collect(Collectors.toList()); + + if (!needDeleteOsds.isEmpty()) { + logger.info(String.format("remove %s stale osd groups", needDeleteOsds.size())); + needDeleteOsds.forEach(this::remove); + } + + List newOsdGroups = new ArrayList<>(); + for (String osds : needCreateOsds) { + CephOsdGroupVO vo = new CephOsdGroupVO(); + vo.setUuid(Platform.getUuid()); + vo.setOsds(osds); + vo.setPrimaryStorageUuid(cephPs.getUuid()); + newOsdGroups.add(vo); } + newOsdGroups.forEach(this::persist); + List pools = Q.New(CephPrimaryStoragePoolVO.class).eq(CephPrimaryStoragePoolVO_.primaryStorageUuid, cephPs.getUuid()).list(); for (CephPrimaryStoragePoolVO poolVO : pools) { if (!poolCapacities.stream().anyMatch((e) -> poolVO.getPoolName().equals(e.getName()))) { if (poolNames.contains(poolVO.getPoolName())) { @@ -91,6 +100,17 @@ protected void scripts() { .filter(e -> poolVO.getPoolName().equals(e.getName())) .findAny().get(); + CephOsdGroupVO osdGroupVO = Q.New(CephOsdGroupVO.class) + .eq(CephOsdGroupVO_.osds, poolCapacity.getRelatedOsds()) + .eq(CephOsdGroupVO_.primaryStorageUuid, cephPs.getUuid()) + .find(); + + // ceph pool related osds has changed + if (poolVO.getOsdGroup() == null || (poolVO.getOsdGroup() != null && + !poolVO.getOsdGroup().getUuid().equals(osdGroupVO.getUuid()))) { + poolVO.setOsdGroup(osdGroupVO); + } + if (!poolNames.contains(poolVO.getPoolName())) { poolNames.add(poolVO.getPoolName()); } @@ -103,6 +123,8 @@ protected void scripts() { poolVO.setSecurityPolicy(poolCapacity.getSecurityPolicy()); dbf.getEntityManager().merge(poolVO); } + + osdHelper.fillCapacityFromPool(); } }.execute(); } diff --git a/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/ZStoneCephPrimaryCapacityBaseUpdater.java b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/ZStoneCephPrimaryCapacityBaseUpdater.java new file mode 100644 index 00000000000..0834608181b --- /dev/null +++ b/plugin/ceph/src/main/java/org/zstack/storage/ceph/primary/capacity/ZStoneCephPrimaryCapacityBaseUpdater.java @@ -0,0 +1,27 @@ +package org.zstack.storage.ceph.primary.capacity; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SQL; +import org.zstack.core.db.SQLBatch; +import org.zstack.header.storage.primary.PrimaryStorageCapacityUpdaterRunnable; +import org.zstack.header.storage.primary.PrimaryStorageCapacityVO; +import org.zstack.storage.ceph.CephCapacity; +import org.zstack.storage.ceph.CephConstants; +import org.zstack.storage.ceph.CephPoolCapacity; +import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO; +import org.zstack.storage.ceph.primary.CephPrimaryStorageVO; +import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +public class ZStoneCephPrimaryCapacityBaseUpdater extends EnterpriseCephPrimaryCapacityBaseUpdater { + @Override + public String getCephManufacturer() { + return CephConstants.CEPH_MANUFACTURER_ZSTONE; + } +} diff --git a/plugin/directory/pom.xml b/plugin/directory/pom.xml new file mode 100644 index 00000000000..17d8f511076 --- /dev/null +++ b/plugin/directory/pom.xml @@ -0,0 +1,76 @@ + + + + plugin + org.zstack + 5.4.0 + + 4.0.0 + + directory + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryEvent.java new file mode 100644 index 00000000000..937e5d3d41d --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryEvent.java @@ -0,0 +1,23 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:32 + */ +@RestResponse +public class APIAddResourcesToDirectoryEvent extends APIEvent { + public APIAddResourcesToDirectoryEvent(){ + } + + public APIAddResourcesToDirectoryEvent(String apiId) { + super(apiId); + } + + public static APIAddResourcesToDirectoryEvent __example__() { + APIAddResourcesToDirectoryEvent event = new APIAddResourcesToDirectoryEvent(); + return event; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..dcaa4ccc33b --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.directory + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "资源加入目录返回" + + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.directory.APIAddResourcesToDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryMsg.java new file mode 100644 index 00000000000..0c8728555b1 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryMsg.java @@ -0,0 +1,55 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.zone.ZoneVO; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author shenjin + * @date 2022/11/29 14:07 + */ +@RestRequest( + path = "/add/resources/directory", + method = HttpMethod.POST, + responseClass = APIAddResourcesToDirectoryEvent.class, + parameterName = "params" +) +public class APIAddResourcesToDirectoryMsg extends APIMessage implements DirectoryMessage { + @APIParam(resourceType = ResourceVO.class, nonempty = true) + private List resourceUuids; + @APIParam(resourceType = DirectoryVO.class) + private String directoryUuid; + + public List getResourceUuids() { + return resourceUuids; + } + + public void setResourceUuids(List resourceUuids) { + this.resourceUuids = resourceUuids; + } + + public String getDirectoryUuid() { + return directoryUuid; + } + + public void setDirectoryUuid(String directoryUuid) { + this.directoryUuid = directoryUuid; + } + + public static APIAddResourcesToDirectoryMsg __example__() { + APIAddResourcesToDirectoryMsg msg = new APIAddResourcesToDirectoryMsg(); + List resourceUuids = new ArrayList<>(); + resourceUuids.add(uuid()); + resourceUuids.add(uuid()); + msg.resourceUuids = resourceUuids; + msg.directoryUuid = uuid(); + return msg; + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..48dacf0c128 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIAddResourcesToDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.directory + +import org.zstack.directory.APIAddResourcesToDirectoryEvent + +doc { + title "AddResourcesToDirectory" + + category "directory" + + desc """资源加入指定目录""" + + rest { + request { + url "POST /v1/add/resources/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAddResourcesToDirectoryMsg.class + + desc """""" + + params { + + column { + name "resourceUuids" + enclosedIn "params" + desc "批量资源UUID" + location "body" + type "List" + optional false + since "4.6.0" + } + column { + name "directoryUuid" + enclosedIn "params" + desc "目录UUID" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APIAddResourcesToDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryEvent.java new file mode 100644 index 00000000000..33607a2337b --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryEvent.java @@ -0,0 +1,42 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:32 + */ +@RestResponse(allTo = "inventory") +public class APICreateDirectoryEvent extends APIEvent { + private DirectoryInventory inventory; + + public static APICreateDirectoryEvent __example__() { + APICreateDirectoryEvent ret = new APICreateDirectoryEvent(); + DirectoryInventory inventory = new DirectoryInventory(); + inventory.setUuid(uuid()); + inventory.setName("test"); + inventory.setGroupName("admin/first/second"); + inventory.setParentUuid(uuid()); + inventory.setRootDirectoryUuid(uuid()); + inventory.setZoneUuid(uuid()); + inventory.setType("vminstance"); + ret.setInventory(inventory); + return ret; + } + + public APICreateDirectoryEvent() { + } + + public APICreateDirectoryEvent(String apiId) { + super(apiId); + } + + public DirectoryInventory getInventory() { + return inventory; + } + + public void setInventory(DirectoryInventory inventory) { + this.inventory = inventory; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..b7b774274bd --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.directory + +import org.zstack.directory.DirectoryInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "创建目录返回" + + ref { + name "inventory" + path "org.zstack.directory.APICreateDirectoryEvent.inventory" + desc "null" + type "DirectoryInventory" + since "4.6.0" + clz DirectoryInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.directory.APICreateDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryMsg.java new file mode 100644 index 00000000000..fc2dfefddf0 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryMsg.java @@ -0,0 +1,69 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.zone.ZoneVO; + +/** + * @author shenjin + * @date 2022/11/29 14:05 + */ +@RestRequest( + path = "/create/directory", + method = HttpMethod.POST, + responseClass = APICreateDirectoryEvent.class, + parameterName = "params" +) +public class APICreateDirectoryMsg extends APICreateMessage implements OperateDirectoryMessage { + @APIParam(maxLength = 255) + private String name; + @APIParam(required = false) + private String parentUuid; + @APIParam(resourceType = ZoneVO.class) + private String zoneUuid; + @APIParam(required = true) + private String type; + + public static APICreateDirectoryMsg __example__() { + APICreateDirectoryMsg ret = new APICreateDirectoryMsg(); + ret.name = "directory"; + ret.parentUuid = uuid(); + ret.zoneUuid = uuid(); + ret.type = "vminstance"; + return ret; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getParentUuid() { + return parentUuid; + } + + public void setParentUuid(String parentUuid) { + this.parentUuid = parentUuid; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..b29bec2143a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APICreateDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,103 @@ +package org.zstack.directory + +import org.zstack.directory.APICreateDirectoryEvent + +doc { + title "CreateDirectory" + + category "directory" + + desc """创建目录""" + + rest { + request { + url "POST /v1/create/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateDirectoryMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "parentUuid" + enclosedIn "params" + desc "父级目录UUID" + location "body" + type "String" + optional true + since "4.6.0" + } + column { + name "zoneUuid" + enclosedIn "params" + desc "区域UUID" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "type" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "4.6.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APICreateDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryEvent.java new file mode 100644 index 00000000000..17e36800037 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryEvent.java @@ -0,0 +1,23 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:33 + */ +@RestResponse +public class APIDeleteDirectoryEvent extends APIEvent { + public APIDeleteDirectoryEvent() { + } + + public APIDeleteDirectoryEvent(String apiId) { + super(apiId); + } + + public static APIDeleteDirectoryEvent __example__() { + APIDeleteDirectoryEvent event = new APIDeleteDirectoryEvent(); + return event; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..133348e729f --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.directory + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "删除目录返回" + + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.directory.APIDeleteDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryMsg.java new file mode 100644 index 00000000000..ba650511b47 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryMsg.java @@ -0,0 +1,39 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @author shenjin + * @date 2022/11/29 14:05 + */ +@RestRequest( + path = "/delete/directory", + method = HttpMethod.DELETE, + responseClass = APIDeleteDirectoryEvent.class +) +public class APIDeleteDirectoryMsg extends APIDeleteMessage implements DirectoryMessage, OperateDirectoryMessage { + @APIParam(resourceType = DirectoryVO.class, successIfResourceNotExisting = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public static APIDeleteDirectoryMsg __example__() { + APIDeleteDirectoryMsg msg = new APIDeleteDirectoryMsg(); + msg.setUuid(uuid()); + return msg; + } + + @Override + public String getDirectoryUuid() { + return uuid; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..5ba4cc1cc3e --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIDeleteDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.directory + +import org.zstack.directory.APIDeleteDirectoryEvent + +doc { + title "DeleteDirectory" + + category "directory" + + desc """删除目录""" + + rest { + request { + url "DELETE /v1/delete/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeleteDirectoryMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "deleteMode" + enclosedIn "" + desc "删除模式(Permissive / Enforcing,Permissive)" + location "body" + type "String" + optional true + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIDeleteDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryEvent.java new file mode 100644 index 00000000000..36f7788b82c --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryEvent.java @@ -0,0 +1,23 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:33 + */ +@RestResponse +public class APIMoveDirectoryEvent extends APIEvent { + public APIMoveDirectoryEvent() { + } + + public APIMoveDirectoryEvent(String apiId) { + super(apiId); + } + + public static APIMoveDirectoryEvent __example__() { + APIMoveDirectoryEvent event = new APIMoveDirectoryEvent(); + return event; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..eff52f9ce8a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.directory + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "移动目录返回" + + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.directory.APIMoveDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryMsg.java new file mode 100644 index 00000000000..c850db04ec5 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryMsg.java @@ -0,0 +1,48 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @author shenjin + * @date 2022/11/29 14:07 + * Move a directory to another directory and become its subdirectory + */ +@RestRequest( + path = "/move/directory", + method = HttpMethod.PUT, + isAction = true, + responseClass = APIMoveDirectoryEvent.class +) +public class APIMoveDirectoryMsg extends APIMessage implements DirectoryMessage, OperateDirectoryMessage { + @APIParam(resourceType = DirectoryVO.class) + private String targetParentUuid; + @APIParam(resourceType = DirectoryVO.class) + private String directoryUuid; + + public String getTargetParentUuid() { + return targetParentUuid; + } + + public void setTargetParentUuid(String targetParentUuid) { + this.targetParentUuid = targetParentUuid; + } + + @Override + public String getDirectoryUuid() { + return directoryUuid; + } + + public void setDirectoryUuid(String directoryUuid) { + this.directoryUuid = directoryUuid; + } + + public static APIMoveDirectoryMsg __example__() { + APIMoveDirectoryMsg msg = new APIMoveDirectoryMsg(); + msg.setDirectoryUuid(uuid()); + msg.setTargetParentUuid(uuid()); + return msg; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..17af3c33da7 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.directory + +import org.zstack.directory.APIMoveDirectoryEvent + +doc { + title "MoveDirectory" + + category "directory" + + desc """移动目录""" + + rest { + request { + url "PUT /v1/move/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIMoveDirectoryMsg.class + + desc """""" + + params { + + column { + name "targetParentUuid" + enclosedIn "moveDirectory" + desc "" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "directoryUuid" + enclosedIn "moveDirectory" + desc "" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIMoveDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryEvent.java new file mode 100644 index 00000000000..8cd95c65ec9 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryEvent.java @@ -0,0 +1,23 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:35 + */ +@RestResponse +public class APIMoveResourcesToDirectoryEvent extends APIEvent { + public APIMoveResourcesToDirectoryEvent() { + } + + public APIMoveResourcesToDirectoryEvent(String apiId) { + super(apiId); + } + + public static APIMoveResourcesToDirectoryEvent __example__() { + APIMoveResourcesToDirectoryEvent event = new APIMoveResourcesToDirectoryEvent(); + return event; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..43fd13d4d08 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.directory + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "移动资源到指定目录返回" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.directory.APIMoveResourcesToDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "0.6" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryMsg.java new file mode 100644 index 00000000000..20ccb1ad421 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryMsg.java @@ -0,0 +1,54 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.zone.ZoneVO; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author shenjin + * @date 2022/11/29 14:09 + */ +@RestRequest( + path = "/move/resources/directory", + method = HttpMethod.PUT, + isAction = true, + responseClass = APIMoveResourcesToDirectoryEvent.class +) +public class APIMoveResourcesToDirectoryMsg extends APIMessage implements DirectoryMessage { + @APIParam(resourceType = ResourceVO.class, nonempty = true) + private List resourceUuids; + @APIParam(resourceType = DirectoryVO.class) + private String directoryUuid; + + public List getResourceUuids() { + return resourceUuids; + } + + public void setResourceUuids(List resourceUuids) { + this.resourceUuids = resourceUuids; + } + + public String getDirectoryUuid() { + return directoryUuid; + } + + public void setDirectoryUuid(String directoryUuid) { + this.directoryUuid = directoryUuid; + } + + public static APIMoveResourcesToDirectoryMsg __example__() { + APIMoveResourcesToDirectoryMsg msg = new APIMoveResourcesToDirectoryMsg(); + msg.directoryUuid = uuid(); + List resourceUuids = new ArrayList<>(); + resourceUuids.add(uuid()); + resourceUuids.add(uuid()); + msg.resourceUuids = resourceUuids; + return msg; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..0dad6742393 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIMoveResourcesToDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.directory + +import org.zstack.directory.APIMoveResourcesToDirectoryEvent + +doc { + title "MoveResourcesToDirectory" + + category "directory" + + desc """移动资源到指定目录""" + + rest { + request { + url "PUT /v1/move/resources/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIMoveResourcesToDirectoryMsg.class + + desc """""" + + params { + + column { + name "resourceUuids" + enclosedIn "moveResourcesToDirectory" + desc "批量资源UUID" + location "body" + type "List" + optional false + since "4.6.0" + } + column { + name "directoryUuid" + enclosedIn "moveResourcesToDirectory" + desc "目录UUID" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APIMoveResourcesToDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryMsg.java new file mode 100644 index 00000000000..98eb042d0e2 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryMsg.java @@ -0,0 +1,28 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * @author shenjin + * @date 2023/1/11 11:25 + */ +@AutoQuery(replyClass = APIQueryDirectoryReply.class, inventoryClass = DirectoryInventory.class) +@RestRequest( + path = "/directories", + optionalPaths = {"/directories/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryDirectoryReply.class +) +public class APIQueryDirectoryMsg extends APIQueryMessage { + + public static List __example__() { + return asList("uuid=" + uuid()); + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..7790f71afb1 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.directory + +import org.zstack.directory.APIQueryDirectoryReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryDirectory" + + category "directory" + + desc """查询目录分组""" + + rest { + request { + url "GET /v1/directories" + url "GET /v1/directories/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryDirectoryMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryDirectoryReply.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryReply.java b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryReply.java new file mode 100644 index 00000000000..80094b68d2a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryReply.java @@ -0,0 +1,39 @@ +package org.zstack.directory; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +import static org.zstack.utils.CollectionDSL.list; + +/** + * @author shenjin + * @date 2023/1/12 10:25 + */ +@RestResponse(allTo = "inventories") +public class APIQueryDirectoryReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryDirectoryReply __example__() { + APIQueryDirectoryReply reply = new APIQueryDirectoryReply(); + DirectoryInventory inventory = new DirectoryInventory(); + inventory.setName("test"); + inventory.setUuid(uuid()); + inventory.setGroupName("admin/test"); + inventory.setParentUuid(uuid()); + inventory.setRootDirectoryUuid(uuid()); + inventory.setZoneUuid(uuid()); + inventory.setType("vminstance"); + reply.setInventories(list(inventory)); + return reply; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryReplyDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..435b51fb4e1 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIQueryDirectoryReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.directory + +import org.zstack.directory.DirectoryInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询目录分组的返回" + + ref { + name "inventories" + path "org.zstack.directory.APIQueryDirectoryReply.inventories" + desc "null" + type "List" + since "4.7.0" + clz DirectoryInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.0" + } + ref { + name "error" + path "org.zstack.directory.APIQueryDirectoryReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryEvent.java new file mode 100644 index 00000000000..b391f22f5e6 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryEvent.java @@ -0,0 +1,23 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:34 + */ +@RestResponse +public class APIRemoveResourcesFromDirectoryEvent extends APIEvent { + public APIRemoveResourcesFromDirectoryEvent() { + } + + public APIRemoveResourcesFromDirectoryEvent(String apiId) { + super(apiId); + } + + public static APIRemoveResourcesFromDirectoryEvent __example__() { + APIRemoveResourcesFromDirectoryEvent event = new APIRemoveResourcesFromDirectoryEvent(); + return event; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..de53fdce7d8 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.directory + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "资源从指定目录中移除返回" + + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.directory.APIRemoveResourcesFromDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryMsg.java new file mode 100644 index 00000000000..4adf9ac55a2 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryMsg.java @@ -0,0 +1,53 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.zone.ZoneVO; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author shenjin + * @date 2022/11/29 14:08 + */ +@RestRequest( + path = "/remove/resources/directory", + method = HttpMethod.DELETE, + responseClass = APIRemoveResourcesFromDirectoryEvent.class +) +public class APIRemoveResourcesFromDirectoryMsg extends APIMessage implements DirectoryMessage{ + @APIParam(resourceType = ResourceVO.class, nonempty = true) + private List resourceUuids; + @APIParam(resourceType = DirectoryVO.class) + private String directoryUuid; + + public List getResourceUuids() { + return resourceUuids; + } + + public void setResourceUuids(List resourceUuids) { + this.resourceUuids = resourceUuids; + } + + public String getDirectoryUuid() { + return directoryUuid; + } + + public void setDirectoryUuid(String directoryUuid) { + this.directoryUuid = directoryUuid; + } + + public static APIRemoveResourcesFromDirectoryMsg __example__() { + APIRemoveResourcesFromDirectoryMsg msg = new APIRemoveResourcesFromDirectoryMsg(); + msg.directoryUuid = uuid(); + List resourceUuids = new ArrayList<>(); + resourceUuids.add(uuid()); + resourceUuids.add(uuid()); + msg.resourceUuids = resourceUuids; + return msg; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..43c4a0d0cb0 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIRemoveResourcesFromDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.directory + +import org.zstack.directory.APIRemoveResourcesFromDirectoryEvent + +doc { + title "RemoveResourcesFromDirectory" + + category "directory" + + desc """资源从指定目录中移除""" + + rest { + request { + url "DELETE /v1/remove/resources/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIRemoveResourcesFromDirectoryMsg.class + + desc """""" + + params { + + column { + name "resourceUuids" + enclosedIn "" + desc "批量资源UUID" + location "body" + type "List" + optional false + since "4.6.0" + } + column { + name "directoryUuid" + enclosedIn "" + desc "目录UUID" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "0.6" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "0.6" + } + } + } + + response { + clz APIRemoveResourcesFromDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryEvent.java b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryEvent.java new file mode 100644 index 00000000000..e31beb50dd6 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryEvent.java @@ -0,0 +1,42 @@ +package org.zstack.directory; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +/** + * @author shenjin + * @date 2022/11/29 14:34 + */ +@RestResponse(allTo = "inventory") +public class APIUpdateDirectoryEvent extends APIEvent { + private DirectoryInventory inventory; + + public DirectoryInventory getInventory() { + return inventory; + } + + public void setInventory(DirectoryInventory inventory) { + this.inventory = inventory; + } + + public APIUpdateDirectoryEvent() { + } + + public APIUpdateDirectoryEvent(String apiId) { + super(apiId); + } + + public static APIUpdateDirectoryEvent __example__() { + APIUpdateDirectoryEvent event = new APIUpdateDirectoryEvent(); + DirectoryInventory inventory = new DirectoryInventory(); + inventory.setUuid(uuid()); + inventory.setName("test"); + inventory.setParentUuid(uuid()); + inventory.setRootDirectoryUuid(uuid()); + inventory.setZoneUuid(uuid()); + inventory.setType("vminstance"); + inventory.setGroupName("admin/first/second"); + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryEventDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..ad71ea8c75a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.directory + +import org.zstack.directory.DirectoryInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "更新目录名称返回" + + ref { + name "inventory" + path "org.zstack.directory.APIUpdateDirectoryEvent.inventory" + desc "null" + type "DirectoryInventory" + since "4.6.0" + clz DirectoryInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.6.0" + } + ref { + name "error" + path "org.zstack.directory.APIUpdateDirectoryEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.0" + clz ErrorCode.class + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryMsg.java new file mode 100644 index 00000000000..40ef5220240 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryMsg.java @@ -0,0 +1,51 @@ +package org.zstack.directory; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +/** + * @author shenjin + * @date 2022/11/29 14:06 + */ +@RestRequest( + path = "/update/directory", + method = HttpMethod.PUT, + isAction = true, + responseClass = APIUpdateDirectoryEvent.class +) +public class APIUpdateDirectoryMsg extends APIMessage implements DirectoryMessage, OperateDirectoryMessage { + @APIParam(resourceType = DirectoryVO.class) + private String uuid; + @APIParam(maxLength = 255) + private String name; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static APIUpdateDirectoryMsg __example__() { + APIUpdateDirectoryMsg msg = new APIUpdateDirectoryMsg(); + msg.setName("test"); + msg.setUuid(uuid()); + return msg; + } + + @Override + public String getDirectoryUuid() { + return uuid; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryMsgDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..a3cc6144bfd --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/APIUpdateDirectoryMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.directory + +import org.zstack.directory.APIUpdateDirectoryEvent + +doc { + title "UpdateDirectory" + + category "directory" + + desc """更新目录名称""" + + rest { + request { + url "PUT /v1/update/directory" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateDirectoryMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "updateDirectory" + desc "资源的UUID,唯一标示该资源" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "name" + enclosedIn "updateDirectory" + desc "资源名称" + location "body" + type "String" + optional false + since "4.6.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.6.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.6.0" + } + } + } + + response { + clz APIUpdateDirectoryEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/directory/src/main/java/org/zstack/directory/CreateDirectoryMsg.java b/plugin/directory/src/main/java/org/zstack/directory/CreateDirectoryMsg.java new file mode 100644 index 00000000000..bc5016f2809 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/CreateDirectoryMsg.java @@ -0,0 +1,59 @@ +package org.zstack.directory; + +import org.zstack.header.message.NeedReplyMessage; + +/** + * @author shenjin + * @date 2022/12/1 14:20 + */ +public class CreateDirectoryMsg extends NeedReplyMessage { + private String uuid; + + private String name; + + private String parentUuid; + + private String type; + + private String zoneUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getParentUuid() { + return parentUuid; + } + + public void setParentUuid(String parentUuid) { + this.parentUuid = parentUuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/CreateDirectoryReply.java b/plugin/directory/src/main/java/org/zstack/directory/CreateDirectoryReply.java new file mode 100644 index 00000000000..031ca509b3d --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/CreateDirectoryReply.java @@ -0,0 +1,19 @@ +package org.zstack.directory; + +import org.zstack.header.message.MessageReply; + +/** + * @author shenjin + * @date 2022/12/1 14:24 + */ +public class CreateDirectoryReply extends MessageReply { + private DirectoryInventory inventory; + + public DirectoryInventory getInventory() { + return inventory; + } + + public void setInventory(DirectoryInventory inventory) { + this.inventory = inventory; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryApiInterceptor.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryApiInterceptor.java new file mode 100644 index 00000000000..e9749deb12a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryApiInterceptor.java @@ -0,0 +1,134 @@ +package org.zstack.directory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.APIMessage; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ResourceVO_; +import org.zstack.utils.CharacterUtils; + +import java.util.List; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.argerr; + +/** + * @author shenjin + * @date 2022/12/8 11:31 + */ +public class DirectoryApiInterceptor implements ApiMessageInterceptor { + @Autowired + private CloudBus bus; + @Autowired + private DirectoryFactory factory; + + String regex = "^[\\u4e00-\\u9fa5a-zA-Z0-9\\s()()【】@._+-]+$"; + //indicates the resource types that the directory allows to bind + private static final List ALLOW_RESOURCE_TYPES = asList(VmInstanceVO.class.getSimpleName()); + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APICreateDirectoryMsg) { + validate((APICreateDirectoryMsg) msg); + } else if (msg instanceof APIUpdateDirectoryMsg) { + validate((APIUpdateDirectoryMsg) msg); + } else if (msg instanceof APIAddResourcesToDirectoryMsg) { + validate((APIAddResourcesToDirectoryMsg) msg); + } else if (msg instanceof APIMoveResourcesToDirectoryMsg) { + validate((APIMoveResourcesToDirectoryMsg) msg); + } else if (msg instanceof APIRemoveResourcesFromDirectoryMsg) { + validate((APIRemoveResourcesFromDirectoryMsg) msg); + } + setServiceId(msg); + return msg; + } + + private void validate(APIRemoveResourcesFromDirectoryMsg msg) { + List types = Q.New(ResourceVO.class).select(ResourceVO_.resourceType).in(ResourceVO_.uuid, msg.getResourceUuids()).listValues(); + types = types.stream().distinct().collect(Collectors.toList()); + checkType(types); + for (String type : types) { + DirectoryChecker checker = factory.directoryCheckers.get(type); + ErrorCode result = checker.check(msg.getDirectoryUuid(), msg.getResourceUuids()); + if (result != null) { + throw new ApiMessageInterceptionException(result); + } + } + } + + private void validate(APIMoveResourcesToDirectoryMsg msg) { + List types = Q.New(ResourceVO.class).select(ResourceVO_.resourceType).in(ResourceVO_.uuid, msg.getResourceUuids()).listValues(); + types = types.stream().distinct().collect(Collectors.toList()); + checkType(types); + for (String type : types) { + DirectoryChecker checker = factory.directoryCheckers.get(type); + ErrorCode result = checker.check(msg.getDirectoryUuid(), msg.getResourceUuids()); + if (result != null) { + throw new ApiMessageInterceptionException(result); + } + } + } + + private void setServiceId(APIMessage msg) { + if (msg instanceof OperateDirectoryMessage) { + bus.makeTargetServiceIdByResourceUuid(msg, DirectoryManager.SERVICE_ID, DirectoryConstant.OPERATE_DIRECTORY_THREAD_NAME); + } else if (msg instanceof DirectoryMessage) { + DirectoryMessage dmsg = (DirectoryMessage) msg; + bus.makeTargetServiceIdByResourceUuid(msg, DirectoryManager.SERVICE_ID, dmsg.getDirectoryUuid()); + } + } + + private void validate(APIAddResourcesToDirectoryMsg msg) { + List types = Q.New(ResourceVO.class).select(ResourceVO_.resourceType).in(ResourceVO_.uuid, msg.getResourceUuids()).listValues(); + types = types.stream().distinct().collect(Collectors.toList()); + checkType(types); + for (String type : types) { + DirectoryChecker checker = factory.directoryCheckers.get(type); + ErrorCode result = checker.check(msg.getDirectoryUuid(), msg.getResourceUuids()); + if (result != null) { + throw new ApiMessageInterceptionException(result); + } + } + List resourceUuids = msg.getResourceUuids(); + List resources = Q.New(ResourceDirectoryRefVO.class).in(ResourceDirectoryRefVO_.resourceUuid, resourceUuids).list(); + if (!resources.isEmpty()) { + List list = resources.stream().map(ResourceDirectoryRefVO::getResourceUuid).collect(Collectors.toList()); + throw new ApiMessageInterceptionException(argerr("resources %s has already been bound to directory uuid[%s] , multiple paths are not supported", list, msg.getDirectoryUuid())); + } + } + + private void checkType(List types) { + if (!ALLOW_RESOURCE_TYPES.containsAll(types)) { + List list = types.stream().filter(s -> !ALLOW_RESOURCE_TYPES.contains(s)).collect(Collectors.toList()); + throw new ApiMessageInterceptionException(argerr("resource types %s are not supported by directory, allowed types are %s", list, ALLOW_RESOURCE_TYPES)); + } + } + + private void validate(APIUpdateDirectoryMsg msg) { + boolean result = CharacterUtils.checkCharactersByRegex(regex, msg.getName()); + if (!result) { + throw new ApiMessageInterceptionException(argerr("name contains unsupported characters," + + " name can only contain Chinese characters, English letters, " + + "numbers, spaces, and the following characters: ()()【】@._-+ ")); + } + } + + private void validate(APICreateDirectoryMsg msg) { + //judge whether special characters are included + boolean result = CharacterUtils.checkCharactersByRegex(regex, msg.getName()); + if (!result) { + throw new ApiMessageInterceptionException(argerr("name contains unsupported characters," + + " name can only contain Chinese characters, English letters, " + + "numbers, spaces, and the following characters: ()()【】@._-+ ")); + } + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryBase.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryBase.java new file mode 100644 index 00000000000..02ff0f69ec9 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryBase.java @@ -0,0 +1,444 @@ +package org.zstack.directory; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.util.StringUtils; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ResourceVO_; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +/** + * @author shenjin + * @date 2022/12/5 11:18 + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class DirectoryBase { + + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + protected ThreadFacade thdf; + + protected DirectoryVO self; + protected String syncThreadName; + + public DirectoryBase(DirectoryVO self) { + this.self = self; + this.syncThreadName = "Directory-" + self.getUuid(); + } + + @MessageSafe + void handleMessage(Message msg) { + if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleLocalMessage(Message msg) { + bus.dealWithUnknownMessage(msg); + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APIDeleteDirectoryMsg) { + handle((APIDeleteDirectoryMsg) msg); + } else if (msg instanceof APIMoveDirectoryMsg) { + handle((APIMoveDirectoryMsg) msg); + } else if (msg instanceof APIUpdateDirectoryMsg) { + handle((APIUpdateDirectoryMsg) msg); + } else if (msg instanceof APIAddResourcesToDirectoryMsg) { + handle((APIAddResourcesToDirectoryMsg) msg); + } else if (msg instanceof APIMoveResourcesToDirectoryMsg) { + handle((APIMoveResourcesToDirectoryMsg) msg); + } else if (msg instanceof APIRemoveResourcesFromDirectoryMsg) { + handle((APIRemoveResourcesFromDirectoryMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIRemoveResourcesFromDirectoryMsg msg) { + APIRemoveResourcesFromDirectoryEvent event = new APIRemoveResourcesFromDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public void run(SyncTaskChain chain) { + removeResourcesFromDirectory(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("remove-resources-from-directory-%s", msg.getDirectoryUuid()); + } + }); + } + + private void removeResourcesFromDirectory(APIRemoveResourcesFromDirectoryMsg msg, Completion completion) { + SQL.New(ResourceDirectoryRefVO.class) + .eq(ResourceDirectoryRefVO_.directoryUuid, msg.getDirectoryUuid()) + .in(ResourceDirectoryRefVO_.resourceUuid, msg.getResourceUuids()) + .delete(); + completion.success(); + } + + private void handle(APIMoveResourcesToDirectoryMsg msg) { + APIMoveResourcesToDirectoryEvent event = new APIMoveResourcesToDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public void run(SyncTaskChain chain) { + moveResourcesToDirectory(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("move-resource-to-directory-%s", msg.getDirectoryUuid()); + } + }); + } + + private void moveResourcesToDirectory(APIMoveResourcesToDirectoryMsg msg, Completion completion) { + SQL.New(ResourceDirectoryRefVO.class) + .set(ResourceDirectoryRefVO_.directoryUuid, msg.getDirectoryUuid()) + .in(ResourceDirectoryRefVO_.resourceUuid, msg.getResourceUuids()) + .update(); + completion.success(); + } + + private void handle(APIAddResourcesToDirectoryMsg msg) { + APIAddResourcesToDirectoryEvent event = new APIAddResourcesToDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public void run(SyncTaskChain chain) { + addResourcesToDirectory(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("add-resources-to-directory-%s", msg.getDirectoryUuid()); + } + }); + } + + private void addResourcesToDirectory(APIAddResourcesToDirectoryMsg msg, Completion completion) { + List resourceUuids = msg.getResourceUuids(); + String resourceType = Q.New(ResourceVO.class) + .select(ResourceVO_.resourceType) + .in(ResourceVO_.uuid, resourceUuids) + .limit(1) + .findValue(); + List list = new ArrayList<>(); + for (String resourceUuid : resourceUuids) { + ResourceDirectoryRefVO refVO = new ResourceDirectoryRefVO(); + refVO.setDirectoryUuid(msg.getDirectoryUuid()); + refVO.setResourceUuid(resourceUuid); + refVO.setResourceType(resourceType); + refVO.setCreateDate(new Timestamp(new Date().getTime())); + list.add(refVO); + } + dbf.persistCollection(list); + completion.success(); + } + + private void handle(APIUpdateDirectoryMsg msg) { + APIUpdateDirectoryEvent event = new APIUpdateDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return DirectoryConstant.OPERATE_DIRECTORY_THREAD_NAME; + } + + @Override + public void run(SyncTaskChain chain) { + updateDirectory(msg, event, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("update-directory-name-%s", msg.getUuid()); + } + }); + } + + private void updateDirectory(APIUpdateDirectoryMsg msg, APIUpdateDirectoryEvent event, Completion completion) { + DirectoryVO vo = dbf.findByUuid(msg.getUuid(), DirectoryVO.class); + //if the renamed name is unchanged, it is returned successfully + if (msg.getName().equals(vo.getName())) { + completion.success(); + return; + } + //judge whether the same level directory has the same name + List directoryVOS; + if (StringUtils.isEmpty(vo.getParentUuid())) { + directoryVOS = Q.New(DirectoryVO.class).isNull(DirectoryVO_.parentUuid).list(); + } else { + directoryVOS = Q.New(DirectoryVO.class).eq(DirectoryVO_.parentUuid, vo.getParentUuid()).list(); + } + List list = directoryVOS.stream() + .filter(s -> s.getName().equals(msg.getName()) && s.getType().equals(vo.getType())) + .collect(Collectors.toList()); + if (!list.isEmpty()) { + completion.fail(operr("duplicate directory name, directory[uuid: %s] with name %s already exists", list.get(0).getUuid(), msg.getName())); + return; + } + updateGroupName(msg, vo); + vo.setName(msg.getName()); + dbf.update(vo); + event.setInventory(DirectoryInventory.valueOf(vo)); + completion.success(); + } + + private void updateGroupName(APIUpdateDirectoryMsg msg, DirectoryVO vo) { + String oldGroupName = vo.getGroupName(); + String oldName = vo.getName(); + String substring = oldGroupName.substring(0, oldGroupName.length() - oldName.length()); + String newGroupName = substring + msg.getName(); + vo.setGroupName(newGroupName); + updateChildrenGroupName(oldGroupName, newGroupName, msg.getUuid()); + } + + private void updateChildrenGroupName(String oldGroupName, String newGroupName, String uuid) { + List vos = Q.New(DirectoryVO.class).like(DirectoryVO_.groupName, oldGroupName + "/%").list(); + List list = new ArrayList<>(); + if (!vos.isEmpty()) { + for(DirectoryVO vo : vos) { + // admin/test/test1 -> admin1/test/test1 + String groupName = vo.getGroupName(); + int length = groupName.length(); + String nowGroupName = newGroupName + groupName.substring(oldGroupName.length(), length); + vo.setGroupName(nowGroupName); + list.add(vo); + } + dbf.updateCollection(list); + } + } + + private void handle(APIMoveDirectoryMsg msg) { + APIMoveDirectoryEvent event = new APIMoveDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return DirectoryConstant.OPERATE_DIRECTORY_THREAD_NAME; + } + + @Override + public void run(SyncTaskChain chain) { + moveDirectory(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("move-directory-%s", msg.getDirectoryUuid()); + } + }); + } + + private void moveDirectory(APIMoveDirectoryMsg msg, Completion completion) { + DirectoryVO vo = dbf.findByUuid(msg.getDirectoryUuid(), DirectoryVO.class); + //avoid looping + List list = new ArrayList<>(); + List uuids = Q.New(DirectoryVO.class) + .select(DirectoryVO_.uuid) + .eq(DirectoryVO_.parentUuid, vo.getUuid()) + .listValues(); + if (!uuids.isEmpty()) { + list.addAll(uuids); + findSubUuids(uuids, list); + } + if (list.contains(msg.getTargetParentUuid())) { + completion.fail(operr("circular dependency detected, directory %s and directory %s will cause circular dependency", msg.getDirectoryUuid(), msg.getTargetParentUuid())); + return; + } + vo.setParentUuid(msg.getTargetParentUuid()); + DirectoryVO parentVO = Q.New(DirectoryVO.class).eq(DirectoryVO_.uuid, msg.getTargetParentUuid()).find(); + String newGroupName = String.format("%s/%s", parentVO.getGroupName(), vo.getName()); + vo.setGroupName(newGroupName); + dbf.update(vo); + completion.success(); + } + + private void findSubUuids(List uuids, List list) { + List subUuids = Q.New(DirectoryVO.class) + .select(DirectoryVO_.uuid) + .in(DirectoryVO_.parentUuid, uuids) + .listValues(); + if (!subUuids.isEmpty()) { + list.addAll(subUuids); + findSubUuids(subUuids, list); + } + } + + private void handle(APIDeleteDirectoryMsg msg) { + APIDeleteDirectoryEvent event = new APIDeleteDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return DirectoryConstant.OPERATE_DIRECTORY_THREAD_NAME; + } + + @Override + public void run(SyncTaskChain chain) { + deleteDirectory(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("delete-directory-%s",msg.getUuid()); + } + }); + } + + private void deleteDirectory(APIDeleteDirectoryMsg msg, Completion completion) { + doDeleteDirectory(msg.getUuid()); + completion.success(); + } + + //TODO:Limit the number + private void doDeleteDirectory(String uuid) { + List subDirectorys; + List list = new ArrayList<>(); + subDirectorys = Q.New(DirectoryVO.class) + .eq(DirectoryVO_.parentUuid, uuid) + .list(); + if(!subDirectorys.isEmpty()) { + list.addAll(subDirectorys); + List uuids = subDirectorys.stream().map(DirectoryVO::getUuid).collect(Collectors.toList()); + findSubDirectorys(uuids, list); + dbf.removeCollection(list, DirectoryVO.class); + } + DirectoryVO vo = dbf.findByUuid(uuid, DirectoryVO.class); + dbf.remove(vo); + } + + private void findSubDirectorys(List uuids, List list) { + List subDirectorys = Q.New(DirectoryVO.class).in(DirectoryVO_.parentUuid, uuids).list(); + if (subDirectorys.isEmpty()) { + return; + } + list.addAll(subDirectorys); + List subUuids = subDirectorys.stream().map(DirectoryVO::getUuid).collect(Collectors.toList()); + findSubDirectorys(subUuids, list); + } +} + diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryChecker.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryChecker.java new file mode 100644 index 00000000000..f904488e082 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryChecker.java @@ -0,0 +1,20 @@ +package org.zstack.directory; + +import org.zstack.header.Component; +import org.zstack.header.errorcode.ErrorCode; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author shenjin + * @date 2022/12/10 23:43 + */ +public interface DirectoryChecker { + + ErrorCode check(String directoryUuid, List resourceUuids); + + DirectoryType getType(); +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryConstant.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryConstant.java new file mode 100644 index 00000000000..9946fc4afee --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryConstant.java @@ -0,0 +1,14 @@ +package org.zstack.directory; + +import org.zstack.header.configuration.PythonClass; + +/** + * @author shenjin + * @date 2022/12/20 14:20 + */ +@PythonClass +public interface DirectoryConstant { + String DEFAULT_DIRECTORY = "default"; + String VCENTER_DIRECTORY = "vcenter"; + String OPERATE_DIRECTORY_THREAD_NAME = "create-update-delete-move-directory"; +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryFactory.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryFactory.java new file mode 100644 index 00000000000..a0be21854d3 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryFactory.java @@ -0,0 +1,43 @@ +package org.zstack.directory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.Component; +import org.zstack.header.exception.CloudRuntimeException; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author shenjin + * @date 2022/12/12 12:41 + */ +public class DirectoryFactory implements Component { + @Autowired + private PluginRegistry pluginRgty; + + Map directoryCheckers = Collections.synchronizedMap(new HashMap()); + + @Override + public boolean start() { + populateExtensions(); + return false; + } + + @Override + public boolean stop() { + return false; + } + + private void populateExtensions() { + for (DirectoryChecker checker : pluginRgty.getExtensionList(DirectoryChecker.class)) { + DirectoryChecker old = directoryCheckers.get(checker.getType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate DirectoryChecker[%s, %s] for type[%s]", + checker.getClass().getName(), old.getClass().getName(), checker.getType())); + } + directoryCheckers.put(checker.getType().toString(), checker); + } + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryInventory.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryInventory.java new file mode 100644 index 00000000000..73fd0ee6ff8 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryInventory.java @@ -0,0 +1,127 @@ +package org.zstack.directory; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.zone.ZoneInventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author shenjin + * @date 2022/11/29 13:21 + */ +@Inventory(mappingVOClass = DirectoryVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "zone", inventoryClass = ZoneInventory.class, + foreignKey = "zoneUuid", expandedInventoryKey = "uuid") +}) +public class DirectoryInventory implements Serializable { + private String uuid; + private String name; + private String groupName; + private String parentUuid; + private String rootDirectoryUuid; + private String zoneUuid; + private String type; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static DirectoryInventory valueOf(DirectoryVO vo) { + DirectoryInventory inv = new DirectoryInventory(); + inv.setName(vo.getName()); + inv.setUuid(vo.getUuid()); + inv.setGroupName(vo.getGroupName()); + inv.setParentUuid(vo.getParentUuid()); + inv.setRootDirectoryUuid(vo.getRootDirectoryUuid()); + inv.setZoneUuid(vo.getZoneUuid()); + inv.setType(vo.getType()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (DirectoryVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getParentUuid() { + return parentUuid; + } + + public void setParentUuid(String parentUuid) { + this.parentUuid = parentUuid; + } + + public String getRootDirectoryUuid() { + return rootDirectoryUuid; + } + + public void setRootDirectoryUuid(String rootDirectoryUuid) { + this.rootDirectoryUuid = rootDirectoryUuid; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryInventoryDoc_zh_cn.groovy b/plugin/directory/src/main/java/org/zstack/directory/DirectoryInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..818b52aee95 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryInventoryDoc_zh_cn.groovy @@ -0,0 +1,63 @@ +package org.zstack.directory + + + +doc { + + title "目录" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.6.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "4.6.0" + } + field { + name "groupName" + desc "所属分组" + type "String" + since "4.6.0" + } + field { + name "parentUuid" + desc "父级目录UUID" + type "String" + since "4.6.0" + } + field { + name "rootDirectoryUuid" + desc "根目录UUID" + type "String" + since "4.6.0" + } + field { + name "zoneUuid" + desc "区域UUID" + type "String" + since "4.6.0" + } + field { + name "type" + desc "目录类型" + type "String" + since "4.6.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.6.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.6.0" + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryManager.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryManager.java new file mode 100644 index 00000000000..f23b18c6c45 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryManager.java @@ -0,0 +1,9 @@ +package org.zstack.directory; + +/** + * @author shenjin + * @date 2022/11/28 17:53 + */ +public interface DirectoryManager { + String SERVICE_ID = "directory"; +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryManagerImpl.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryManagerImpl.java new file mode 100644 index 00000000000..9901798bcab --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryManagerImpl.java @@ -0,0 +1,184 @@ +package org.zstack.directory; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.AbstractService; +import org.zstack.header.Component; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ResourceVO_; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.sql.Timestamp; +import java.util.*; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.err; +import static org.zstack.core.Platform.operr; + +/** + * @author shenjin + * @date 2022/11/28 17:54 + */ +public class DirectoryManagerImpl extends AbstractService implements DirectoryManager, Component { + private static final CLogger logger = Utils.getLogger(DirectoryManagerImpl.class); + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + protected ThreadFacade thdf; + + private static final List DIRECTORY_TYPES = asList( + DirectoryConstant.DEFAULT_DIRECTORY, DirectoryConstant.VCENTER_DIRECTORY + ); + + @Override + @MessageSafe + public void handleMessage(Message msg) { + if (msg instanceof DirectoryMessage) { + passThrough((DirectoryMessage) msg); + } else if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleLocalMessage(Message msg) { + bus.dealWithUnknownMessage(msg); + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APICreateDirectoryMsg) { + handle((APICreateDirectoryMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void passThrough(DirectoryMessage msg) { + DirectoryVO vo = dbf.findByUuid(msg.getDirectoryUuid(), DirectoryVO.class); + if (vo == null) { + bus.replyErrorByMessageType((Message) msg, err(SysErrors.RESOURCE_NOT_FOUND, "unable to find directory[uuid=%s]", msg.getDirectoryUuid())); + return; + } + + DirectoryBase base = new DirectoryBase(vo); + base.handleMessage((Message) msg); + } + + private void handle(APICreateDirectoryMsg msg) { + APICreateDirectoryEvent event = new APICreateDirectoryEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + + @Override + public String getSyncSignature() { + return DirectoryConstant.OPERATE_DIRECTORY_THREAD_NAME; + } + + @Override + public void run(SyncTaskChain chain) { + createDirectory(msg, event, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("update-directory-name-%s", msg.getName()); + } + }); + } + + private void createDirectory(APICreateDirectoryMsg msg, APICreateDirectoryEvent event, Completion completion) { + DirectoryVO vo = new DirectoryVO(); + vo.setUuid(msg.getResourceUuid() == null ? Platform.getUuid() : msg.getResourceUuid()); + String name = msg.getName(); + vo.setName(name); + List directoryVOS; + if(StringUtils.isEmpty(msg.getParentUuid())){ + //first-level directory + vo.setGroupName(name); + //judge whether the same level directory has the same name + directoryVOS = Q.New(DirectoryVO.class).isNull(DirectoryVO_.parentUuid).list(); + vo.setRootDirectoryUuid(Platform.getUuid()); + } else { + String groupName = String.format("/%s", msg.getName()); + DirectoryVO parentVO = dbf.findByUuid(msg.getParentUuid(), DirectoryVO.class); + vo.setRootDirectoryUuid(parentVO.getRootDirectoryUuid()); + vo.setGroupName(parentVO.getGroupName() + groupName); + vo.setParentUuid(msg.getParentUuid()); + //judge whether the same level directory has the same name + directoryVOS = Q.New(DirectoryVO.class).eq(DirectoryVO_.parentUuid, parentVO.getUuid()).list(); + } + List list = directoryVOS.stream() + .filter(s -> s.getName().equals(name) && s.getType().equals(msg.getType())) + .collect(Collectors.toList()); + if (!list.isEmpty()) { + completion.fail(operr("duplicate directory name, directory[uuid: %s] with name %s already exists", list.get(0).getUuid(), msg.getName())); + return; + } + //judge whether the maximum level is exceeded + String[] split = vo.getGroupName().split("/"); + // the directory cannot exceed 4 floors (contains the default directory) + if(split.length > 3) { + completion.fail(operr("fail to create directory, directories are up to four levels")); + return; + } + if (!DIRECTORY_TYPES.contains(msg.getType())) { + completion.fail(operr("the type of directory %s is not supported, the supported directory types are %s", msg.getType(), DIRECTORY_TYPES)); + return; + } + vo.setType(msg.getType()); + vo.setAccountUuid(msg.getSession().getAccountUuid()); + vo.setZoneUuid(msg.getZoneUuid()); + vo.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(vo); + event.setInventory(DirectoryInventory.valueOf(vo)); + completion.success(); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getId() { + return bus.makeLocalServiceId(SERVICE_ID); + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryMessage.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryMessage.java new file mode 100644 index 00000000000..f8bb8b05b4d --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryMessage.java @@ -0,0 +1,9 @@ +package org.zstack.directory; + +/** + * @author shenjin + * @date 2022/12/5 10:46 + */ +public interface DirectoryMessage { + String getDirectoryUuid(); +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryType.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryType.java new file mode 100644 index 00000000000..479c4dd589a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryType.java @@ -0,0 +1,47 @@ +package org.zstack.directory; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author shenjin + * @date 2022/12/11 20:00 + */ +public class DirectoryType { + private static Map types = Collections.synchronizedMap(new HashMap()); + private final String typeName; + + public DirectoryType(String typeName) { + this.typeName = typeName; + types.put(typeName, this); + } + + public static DirectoryType valueOf(String typeName) { + DirectoryType type = types.get(typeName); + if (type == null) { + throw new IllegalArgumentException("DirectoryType type: " + typeName + " was not registered by any DirectoryChecker"); + } + return type; + } + + @Override + public String toString() { + return typeName; + } + + @Override + public boolean equals(Object t) { + if (t == null || !(t instanceof DirectoryType)) { + return false; + } + + DirectoryType type = (DirectoryType) t; + return type.toString().equals(typeName); + } + + @Override + public int hashCode() { + return typeName.hashCode(); + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryVO.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryVO.java new file mode 100644 index 00000000000..4958161029a --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryVO.java @@ -0,0 +1,118 @@ +package org.zstack.directory; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; +import org.zstack.header.zone.ZoneVO; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * @author shenjin + * @date 2022/11/29 10:12 + */ +@Entity +@Table +public class DirectoryVO extends ResourceVO implements OwnedByAccount, ToInventory { + @Column + private String name; + @Column + private String groupName; + @Column + private String parentUuid; + @Column + private String rootDirectoryUuid; + @Column + @org.zstack.header.vo.ForeignKey(parentEntityClass = ZoneVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String zoneUuid; + @Column + private String type; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + @Transient + private String accountUuid; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getParentUuid() { + return parentUuid; + } + + public void setParentUuid(String parentUuid) { + this.parentUuid = parentUuid; + } + + public String getRootDirectoryUuid() { + return rootDirectoryUuid; + } + + public void setRootDirectoryUuid(String rootDirectoryUuid) { + this.rootDirectoryUuid = rootDirectoryUuid; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/DirectoryVO_.java b/plugin/directory/src/main/java/org/zstack/directory/DirectoryVO_.java new file mode 100644 index 00000000000..3e631187744 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/DirectoryVO_.java @@ -0,0 +1,23 @@ +package org.zstack.directory; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * @author shenjin + * @date 2022/11/29 10:48 + */ +@StaticMetamodel(DirectoryVO.class) +public class DirectoryVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute groupName; + public static volatile SingularAttribute parentUuid; + public static volatile SingularAttribute rootDirectoryUuid; + public static volatile SingularAttribute zoneUuid; + public static volatile SingularAttribute type; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/OperateDirectoryMessage.java b/plugin/directory/src/main/java/org/zstack/directory/OperateDirectoryMessage.java new file mode 100644 index 00000000000..31aae710cec --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/OperateDirectoryMessage.java @@ -0,0 +1,8 @@ +package org.zstack.directory; + +/** + * @author shenjin + * @date 2022/12/28 13:30 + */ +public interface OperateDirectoryMessage { +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/RBAInfo.java b/plugin/directory/src/main/java/org/zstack/directory/RBAInfo.java new file mode 100644 index 00000000000..510c495f6e2 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/RBAInfo.java @@ -0,0 +1,31 @@ +package org.zstack.directory; + +import org.zstack.header.identity.rbac.RBACDescription; + +/** + * @author shenjin + * @date 2022/12/7 11:27 + */ +public class RBAInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .adminOnlyAPIs("org.zstack.directory.**") + .build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefInventory.java b/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefInventory.java new file mode 100644 index 00000000000..7d324557e72 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefInventory.java @@ -0,0 +1,98 @@ +package org.zstack.directory; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.vo.ResourceInventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author shenjin + * @date 2022/11/29 11:53 + */ +@Inventory(mappingVOClass = ResourceDirectoryRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "resource", inventoryClass = ResourceInventory.class, + foreignKey = "resourceUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "directory", inventoryClass = DirectoryInventory.class, + foreignKey = "directoryUuid", expandedInventoryKey = "uuid") +}) +public class ResourceDirectoryRefInventory { + private Long id; + private String resourceUuid; + private String directoryUuid; + private String resourceType; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static ResourceDirectoryRefInventory valueOf(ResourceDirectoryRefVO vo) { + ResourceDirectoryRefInventory inv = new ResourceDirectoryRefInventory(); + inv.setId(vo.getId()); + inv.setResourceUuid(vo.getResourceUuid()); + inv.setDirectoryUuid(vo.getDirectoryUuid()); + inv.setResourceType(vo.getResourceType()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (ResourceDirectoryRefVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getDirectoryUuid() { + return directoryUuid; + } + + public void setDirectoryUuid(String directoryUuid) { + this.directoryUuid = directoryUuid; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefVO.java b/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefVO.java new file mode 100644 index 00000000000..593e67f836e --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefVO.java @@ -0,0 +1,95 @@ +package org.zstack.directory; + + +import org.zstack.header.vo.*; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * @author shenjin + * @date 2022/11/29 10:54 + */ +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = ResourceVO.class, joinColumn = "resourceUuid"), + @SoftDeletionCascade(parent = DirectoryVO.class, joinColumn = "directoryUuid") +}) +public class ResourceDirectoryRefVO implements ToInventory { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private Long id; + + @Column + @ForeignKey(parentEntityClass = ResourceVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String resourceUuid; + + @Column + @ForeignKey(parentEntityClass = DirectoryVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String directoryUuid; + + @Column + private String resourceType; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getDirectoryUuid() { + return directoryUuid; + } + + public void setDirectoryUuid(String directoryUuid) { + this.directoryUuid = directoryUuid; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefVO_.java b/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefVO_.java new file mode 100644 index 00000000000..19cd708ce61 --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/ResourceDirectoryRefVO_.java @@ -0,0 +1,22 @@ +package org.zstack.directory; + + + + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * @author shenjin + * @date 2022/11/29 11:36 + */ +@StaticMetamodel(ResourceDirectoryRefVO.class) +public class ResourceDirectoryRefVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute resourceUuid; + public static volatile SingularAttribute directoryUuid; + public static volatile SingularAttribute resourceType; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/directory/src/main/java/org/zstack/directory/VmDirectoryChecker.java b/plugin/directory/src/main/java/org/zstack/directory/VmDirectoryChecker.java new file mode 100644 index 00000000000..6b017522d9d --- /dev/null +++ b/plugin/directory/src/main/java/org/zstack/directory/VmDirectoryChecker.java @@ -0,0 +1,35 @@ +package org.zstack.directory; + +import org.zstack.core.db.Q; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; + +import java.util.List; + +import static org.zstack.core.Platform.argerr; + +/** + * @author shenjin + * @date 2022/12/11 11:17 + */ +public class VmDirectoryChecker implements DirectoryChecker{ + public static DirectoryType type = new DirectoryType(VmInstanceVO.class.getSimpleName()); + + @Override + public ErrorCode check(String directoryUuid, List resourceUuids) { + DirectoryVO vo = Q.New(DirectoryVO.class).eq(DirectoryVO_.uuid, directoryUuid).find(); + List zoneUuids = Q.New(VmInstanceVO.class).select(VmInstanceVO_.zoneUuid) + .in(VmInstanceVO_.uuid, resourceUuids).listValues(); + if(zoneUuids.stream().allMatch(s -> s.equals(vo.getZoneUuid()))) { + return null; + } else { + return argerr("all resources zoneUuid must be consistent with the directory zoneUuid[%s]", vo.getZoneUuid()); + } + } + + @Override + public DirectoryType getType() { + return type; + } +} diff --git a/plugin/eip/pom.xml b/plugin/eip/pom.xml index 1215274ee96..08aa87feb87 100755 --- a/plugin/eip/pom.xml +++ b/plugin/eip/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIAttachEipMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIAttachEipMsgDoc_zh_cn.groovy index c4d96a6c20d..f450d0a735f 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIAttachEipMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIAttachEipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "vmNicUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "usedIpUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.1" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIChangeEipStateMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIChangeEipStateMsgDoc_zh_cn.groovy index 327289e7dd7..69427d7696f 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIChangeEipStateMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIChangeEipStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APICreateEipMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APICreateEipMsgDoc_zh_cn.groovy index a48461f56b9..89a08588fe0 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APICreateEipMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APICreateEipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "vipUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "vmNicUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "usedIpUuid" @@ -69,7 +65,6 @@ doc { type "String" optional true since "3.1" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDeleteEipMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDeleteEipMsgDoc_zh_cn.groovy index 4c70bb88cf8..e0b5d477cdd 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDeleteEipMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDeleteEipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDetachEipMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDetachEipMsgDoc_zh_cn.groovy index bb7518da639..e76288cf5eb 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDetachEipMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIDetachEipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetEipAttachableVmNicsMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetEipAttachableVmNicsMsgDoc_zh_cn.groovy index c5b025a439d..d6c7071b7ad 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetEipAttachableVmNicsMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetEipAttachableVmNicsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "vipUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "vmUuid" @@ -49,7 +47,6 @@ doc { type "String" optional true since "3.8" - } column { name "vmName" @@ -59,7 +56,6 @@ doc { type "String" optional true since "3.8" - } column { name "limit" @@ -69,7 +65,6 @@ doc { type "Integer" optional true since "3.8" - } column { name "start" @@ -79,7 +74,6 @@ doc { type "Integer" optional true since "3.8" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,24 @@ doc { type "List" optional true since "0.6" - + } + column { + name "networkServiceProvider" + enclosedIn "" + desc "" + location "query" + type "String" + optional true + since "3.9.0" + } + column { + name "attachedToVm" + enclosedIn "" + desc "" + location "query" + type "boolean" + optional true + since "3.9.0" } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetVmNicAttachableEipsMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetVmNicAttachableEipsMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..7f41ea1e413 --- /dev/null +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetVmNicAttachableEipsMsgDoc_zh_cn.groovy @@ -0,0 +1,86 @@ +package org.zstack.network.service.eip + +import org.zstack.network.service.eip.APIGetVmNicAttachableEipsReply + +doc { + title "GetVmNicAttachableEips" + + category "eip" + + desc """获取云主机网卡可挂载弹性IP""" + + rest { + request { + url "GET /v1/vm-instances/nics/{vmNicUuid}/candidate-eips" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetVmNicAttachableEipsMsg.class + + desc """""" + + params { + + column { + name "vmNicUuid" + enclosedIn "" + desc "云主机网卡UUID" + location "url" + type "String" + optional false + since "4.3.18" + } + column { + name "ipVersion" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.3.18" + values ("4","6") + } + column { + name "limit" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.3.18" + } + column { + name "start" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.3.18" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.3.18" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.3.18" + } + } + } + + response { + clz APIGetVmNicAttachableEipsReply.class + } + } +} \ No newline at end of file diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetVmNicAttachableEipsReplyDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetVmNicAttachableEipsReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..bd6b47ef5b2 --- /dev/null +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIGetVmNicAttachableEipsReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.service.eip + +import org.zstack.network.service.eip.EipInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取云主机网卡可挂载弹性IP的返回" + + ref { + name "inventories" + path "org.zstack.network.service.eip.APIGetVmNicAttachableEipsReply.inventories" + desc "null" + type "List" + since "4.3.18" + clz EipInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.3.18" + } + ref { + name "error" + path "org.zstack.network.service.eip.APIGetVmNicAttachableEipsReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.3.18" + clz ErrorCode.class + } +} diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIQueryEipMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIQueryEipMsgDoc_zh_cn.groovy index 92626b3cdc5..27d7dcb16d8 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIQueryEipMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIQueryEipMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.eip import org.zstack.network.service.eip.APIQueryEipReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询弹性IP(QueryEip)" diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIUpdateEipMsgDoc_zh_cn.groovy b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIUpdateEipMsgDoc_zh_cn.groovy index 963f52489a4..3aff526939e 100644 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/APIUpdateEipMsgDoc_zh_cn.groovy +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/APIUpdateEipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java index e7d2b71b387..9fc0614c5d0 100755 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipApiInterceptor.java @@ -32,6 +32,7 @@ import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; import javax.persistence.Tuple; import javax.persistence.TypedQuery; @@ -101,26 +102,16 @@ private void validate(APIGetEipAttachableVmNicsMsg msg) { } boolean isAddressPool = false; - boolean isIpv6 = false; if (msg.getVipUuid() != null) { VipVO vip = dbf.findByUuid(msg.getVipUuid(), VipVO.class); isAddressPool = Q.New(AddressPoolVO.class).eq(AddressPoolVO_.uuid, vip.getIpRangeUuid()).isExists(); - if (IPv6NetworkUtils.isIpv6Address(vip.getIp())) { - isIpv6 = true; - } } else if (msg.getEipUuid() != null) { EipVO eipVO = dbf.findByUuid(msg.getEipUuid(), EipVO.class); VipVO vip = dbf.findByUuid(eipVO.getVipUuid(), VipVO.class); isAddressPool = Q.New(AddressPoolVO.class).eq(AddressPoolVO_.uuid, vip.getIpRangeUuid()).isExists(); - if (IPv6NetworkUtils.isIpv6Address(vip.getIp())) { - isIpv6 = true; - } } if (isAddressPool) { msg.setNetworkServiceProvider("vrouter"); - } else if (isIpv6) { - /* TODO, temp hard code */ - msg.setNetworkServiceProvider("Flat"); } } @@ -155,16 +146,6 @@ private void validate(final APIAttachEipMsg msg) { msg.getEipUuid(), EipState.Enabled, state)); } - if (msg.getUsedIpUuid() == null) { - VmNicVO nic = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); - msg.setUsedIpUuid(nic.getUsedIpUuid()); - } else { - validateEipGuestIpUuid(msg.getVmNicUuid(), msg.getUsedIpUuid()); - } - - String vipUuid = t.get(2, String.class); - isVipInVmNicSubnet(vipUuid, msg.getUsedIpUuid()); - VipVO vip = new Callable() { @Override @Transactional(readOnly = true) @@ -179,6 +160,21 @@ public VipVO call() { } }.call(); + if (msg.getUsedIpUuid() == null) { + VmNicVO nic = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); + UsedIpVO usedIp = nic.getUsedIps().stream() + .filter(usedIpVO -> usedIpVO.getIpVersion().equals(NetworkUtils.getIpversion(vip.getIp()))) + .findFirst() + .orElseThrow(() -> new ApiMessageInterceptionException(argerr("vm nic[uuid:%s] does not have a compatible usedIp for eip[uuid:%s]", + msg.getVmNicUuid(), msg.getEipUuid()))); + msg.setUsedIpUuid(usedIp.getUuid()); + } else { + validateEipGuestIpUuid(msg.getVmNicUuid(), msg.getUsedIpUuid()); + } + + String vipUuid = t.get(2, String.class); + isVipInVmNicSubnet(vipUuid, msg.getUsedIpUuid()); + VmNicVO nic = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); if (VmNicHelper.getL3Uuids(nic).contains(vip.getL3NetworkUuid())){ throw new ApiMessageInterceptionException(argerr("guest l3Network of vm nic[uuid:%s] and vip l3Network of EIP[uuid:%s] are the same network", @@ -230,26 +226,27 @@ private void validate(APIDeleteEipMsg msg) { private void isVipInVmNicSubnet(String vipUuid, String guestIpUuid) { VipVO vip = dbf.findByUuid(vipUuid, VipVO.class); UsedIpVO vipIp = dbf.findByUuid(vip.getUsedIpUuid(), UsedIpVO.class); - NormalIpRangeVO vipRange = dbf.findByUuid(vipIp.getIpRangeUuid(), NormalIpRangeVO.class); UsedIpVO guestIp = dbf.findByUuid(guestIpUuid, UsedIpVO.class); - NormalIpRangeVO guestRange = dbf.findByUuid(guestIp.getIpRangeUuid(), NormalIpRangeVO.class); if (!vipIp.getIpVersion().equals(guestIp.getIpVersion())) { throw new ApiMessageInterceptionException(operr("vip ipVersion [%d] is different from guestIp ipVersion [%d].", vipIp.getIpVersion(), guestIp.getIpVersion())); } - if (vipIp.getIpVersion() == IPv6Constants.IPv4) { - SubnetUtils guestSub = new SubnetUtils(guestRange.getGateway(), guestRange.getNetmask()); - if (guestSub.getInfo().isInRange(vipIp.getIp())) { - throw new ApiMessageInterceptionException(operr("Vip[%s] is in the guest ip range [%s, %s]", - vipIp.getIp(), guestRange.getStartIp(), guestRange.getEndIp())); - } - } else { - if (IPv6NetworkUtils.isIpv6InCidrRange(vipIp.getIp(), guestRange.getNetworkCidr())){ - throw new ApiMessageInterceptionException(operr("Vip[%s] is in the guest ip range [%s, %s]", - vipIp.getIp(), guestRange.getStartIp(), guestRange.getEndIp())); + if (guestIp.getIpRangeUuid() != null) { + NormalIpRangeVO guestRange = dbf.findByUuid(guestIp.getIpRangeUuid(), NormalIpRangeVO.class); + if (vipIp.getIpVersion() == IPv6Constants.IPv4) { + SubnetUtils guestSub = new SubnetUtils(guestRange.getGateway(), guestRange.getNetmask()); + if (guestSub.getInfo().isInRange(vipIp.getIp())) { + throw new ApiMessageInterceptionException(operr("Vip[%s] is in the guest ip range [%s, %s]", + vipIp.getIp(), guestRange.getStartIp(), guestRange.getEndIp())); + } + } else { + if (IPv6NetworkUtils.isIpv6InCidrRange(vipIp.getIp(), guestRange.getNetworkCidr())){ + throw new ApiMessageInterceptionException(operr("Vip[%s] is in the guest ip range [%s, %s]", + vipIp.getIp(), guestRange.getStartIp(), guestRange.getEndIp())); + } } } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipConstant.java b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipConstant.java index 25366221ce3..14ed2fbeab3 100755 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipConstant.java +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipConstant.java @@ -42,6 +42,7 @@ public static enum Params { public final List vmOperationForDetachEip = asList( VmInstanceConstant.VmOperation.Destroy, - VmInstanceConstant.VmOperation.DetachNic + VmInstanceConstant.VmOperation.DetachNic, + VmInstanceConstant.VmOperation.ChangeNicIp ); } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipExtension.java b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipExtension.java index 5dfd5ea84cc..129859cd508 100755 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipExtension.java +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipExtension.java @@ -4,8 +4,7 @@ import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.vm.StaticIpOperator; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.db.SQL; -import org.zstack.core.db.SimpleQuery; +import org.zstack.core.db.Q; import org.zstack.header.Component; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; @@ -20,6 +19,7 @@ import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.network.l3.L3NetworkManager; import org.zstack.network.service.AbstractNetworkServiceExtension; +import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.vip.VipInventory; import org.zstack.network.service.vip.VipVO; import org.zstack.utils.CollectionUtils; @@ -31,6 +31,9 @@ import javax.persistence.Query; import javax.persistence.TypedQuery; import java.util.*; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; /** */ @@ -43,6 +46,8 @@ public class EipExtension extends AbstractNetworkServiceExtension implements Com private PluginRegistry pluginRgty; @Autowired L3NetworkManager l3Mgr; + @Autowired + private NetworkServiceManager nwServiceMgr; private static final String SUCCESS = EipExtension.class.getName(); @@ -79,18 +84,13 @@ private EipStruct eipVOtoEipStruct(EipVO vo) { return struct; } - private EipStruct workOutEipStruct(VmNicInventory vmNic) { - EipVO eipVO = SQL.New("select eip from EipVO eip, VmNicVO nic, UsedIpVO ip" + - " where nic.uuid = ip.vmNicUuid " + - " and ip.l3NetworkUuid = :l3uuid " + - " and nic.uuid = eip.vmNicUuid and nic.uuid = :nicUuid") - .param("l3uuid", vmNic.getL3NetworkUuid()) - .param("nicUuid", vmNic.getUuid()) - .find(); - if (eipVO == null) { + private List workOutEipStruct(VmNicInventory vmNic) { + List vos = Q.New(EipVO.class).eq(EipVO_.vmNicUuid, vmNic.getUuid()).list(); + if (vos == null || vos.isEmpty()) { return null; } - return eipVOtoEipStruct(eipVO); + + return vos.stream().map(eipVO -> eipVOtoEipStruct(eipVO)).collect(Collectors.toList()); } private boolean isEipShouldBeAttachedToBackend(String vmUuid, String l3Uuid, VmOperation operation) { @@ -315,20 +315,28 @@ public void releaseNetworkService(VmInstanceSpec spec, Map data, } @Override - public void releaseNetworkServiceOnDeletingNic(VmNicInventory nic, Completion completion) { - String networkServiceProviderType = SQL.New("select provider.type from NetworkServiceProviderVO provider, NetworkServiceL3NetworkRefVO ref" + - " where ref.l3NetworkUuid = :l3Uuid" + - " and ref.networkServiceProviderUuid = provider.uuid" + - " and ref.networkServiceType = :networkServiceType") - .param("l3Uuid", nic.getL3NetworkUuid()) - .param("networkServiceType", EipConstant.EIP_NETWORK_SERVICE_TYPE) - .find(); - EipStruct struct = workOutEipStruct(nic); - if (struct == null) { - logger.debug(String.format("vmNic[%s] dont need release eip",nic.getUuid())); - completion.success(); + public void releaseNetworkServiceOnDeletingNic(VmNicInventory nic, NoErrorCompletion completion) { + List structs = workOutEipStruct(nic); + if (structs == null) { + logger.debug(String.format("vmNic[%s] does not need release eip",nic.getUuid())); + completion.done(); return; } - eipMgr.detachEipAndUpdateDb(struct, networkServiceProviderType, DetachEipOperation.FORCE_DB_UPDATE, completion); + final NetworkServiceProviderType providerType = nwServiceMgr.getTypeOfNetworkServiceProviderForService(nic.getL3NetworkUuid(), + EipConstant.EIP_TYPE); + Map> map = new HashMap>(); + + map.put(providerType.toString(), structs); + releaseNetworkService(map.entrySet().iterator(), true, completion); + } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); } } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipManagerImpl.java b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipManagerImpl.java index 419da91689a..a44fc71f75a 100755 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/EipManagerImpl.java +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/EipManagerImpl.java @@ -21,12 +21,10 @@ import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.*; -import org.zstack.header.identity.Quota.QuotaOperator; -import org.zstack.header.identity.Quota.QuotaPair; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; -import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.network.l2.L2NetworkClusterRefVO; import org.zstack.header.network.l2.L2NetworkClusterRefVO_; import org.zstack.header.network.l3.*; @@ -36,7 +34,6 @@ import org.zstack.header.query.ExpandedQueryStruct; import org.zstack.header.vm.*; import org.zstack.identity.AccountManager; -import org.zstack.identity.QuotaUtil; import org.zstack.network.l3.L3NetworkManager; import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.vip.*; @@ -55,7 +52,7 @@ import java.util.stream.Collectors; import static org.zstack.core.Platform.operr; -import static org.zstack.utils.CollectionDSL.*; +import static org.zstack.utils.CollectionDSL.list; /** */ @@ -228,7 +225,7 @@ private List getVmNicAttachableEips(APIGetVmNicAttachableEipsMsg m } List eipVOS = Q.New(EipVO.class).in(EipVO_.uuid, ret).list(); - return EipInventory.valueOf(eipVOS); + return filterEipsForVmNicInVirtualRouterExtensionPoint(vmNicInv, EipInventory.valueOf(eipVOS)); } private HashMap> getL3NetworkForVmNicAttachableEip(VmNicInventory vmNicInv) { @@ -237,8 +234,9 @@ private HashMap> getL3NetworkForVmNicAttachableEip(VmNicI HashMap> ret = new HashMap<>(); for (GetEipAttachableL3UuidsForVmNicExtensionPoint extp : pluginRgty.getExtensionList(GetEipAttachableL3UuidsForVmNicExtensionPoint.class)) { - if(!extp.getEipAttachableL3UuidsForVmNic(vmNicInv, l3Network).isEmpty()){ - ret.putAll(extp.getEipAttachableL3UuidsForVmNic(vmNicInv, l3Network)); + HashMap> res = extp.getEipAttachableL3UuidsForVmNic(vmNicInv, l3Network); + if(!res.isEmpty()){ + ret.putAll(res); } } return ret; @@ -432,6 +430,17 @@ private List filterVmNicsForEipInVirtualRouterExtensionPoint(Vip return ret; } + private List filterEipsForVmNicInVirtualRouterExtensionPoint(VmNicInventory vmNic, List eips) { + if (eips.isEmpty()){ + return eips; + } + List ret = new ArrayList<>(eips); + for (FilterVmNicsForEipInVirtualRouterExtensionPoint extp : pluginRgty.getExtensionList(FilterVmNicsForEipInVirtualRouterExtensionPoint.class)) { + ret = extp.filterEipsForVmNicInVirtualRouter(vmNic, ret); + } + return ret; + } + private List filterVmNicsOnFlatNetworkForEip(final String networkProviderType, VipInventory vip, List vmNics) { if (vmNics.isEmpty()){ return vmNics; @@ -597,11 +606,6 @@ public EipStruct generateEipStruct(VmNicInventory nic, VipInventory vip, EipInve struct.setVip(vip); struct.setEip(eip); if (guestIp != null) { - /* when delete l3 network, ip range is deleted, then release network, so can not get iprange */ - NormalIpRangeVO ipr = dbf.findByUuid(guestIp.getIpRangeUuid(), NormalIpRangeVO.class); - if (ipr != null) { - struct.setGuestIpRange(IpRangeInventory.valueOf(ipr)); - } struct.setGuestIp(guestIp); } @@ -1585,125 +1589,15 @@ public List getExpandedQueryAliasesStructs() { @Override public List reportQuota() { - QuotaOperator checker = new QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreateEipMsg) { - check((APICreateEipMsg) msg, pairs); - } else if (msg instanceof APIChangeResourceOwnerMsg) { - check((APIChangeResourceOwnerMsg) msg, pairs); - } - } else { - if (msg instanceof APIChangeResourceOwnerMsg) { - check((APIChangeResourceOwnerMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(EipQuotaConstant.EIP_NUM); - usage.setUsed(getUsedEipNum(accountUuid)); - return list(usage); - } - - @Transactional(readOnly = true) - private long getUsedEipNum(String accountUuid) { - String sql = "select count(eip)" + - " from EipVO eip, AccountResourceRefVO ref" + - " where ref.resourceUuid = eip.uuid" + - " and ref.accountUuid = :auuid" + - " and ref.resourceType = :rtype"; - - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", EipVO.class.getSimpleName()); - Long usedEipNum = q.getSingleResult(); - usedEipNum = usedEipNum == null ? 0 : usedEipNum; - return usedEipNum; - } - - @Transactional(readOnly = true) - private long getVmEipNum(String vmUuid) { - String sql = "select count(eip)" + - " from EipVO eip, VmNicVO vmnic" + - " where vmnic.vmInstanceUuid = :vmuuid" + - " and vmnic.uuid = eip.vmNicUuid"; - - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("vmuuid", vmUuid); - Long vmEipNum = q.getSingleResult(); - vmEipNum = vmEipNum == null ? 0 : vmEipNum; - return vmEipNum; - } - - @Transactional(readOnly = true) - private void check(APICreateEipMsg msg, Map pairs) { - String currentAccountUuid = msg.getSession().getAccountUuid(); - String resourceTargetOwnerAccountUuid = msg.getSession().getAccountUuid(); - - long eipNumQuota = pairs.get(EipQuotaConstant.EIP_NUM).getValue(); - long usedEipNum = getUsedEipNum(msg.getSession().getAccountUuid()); - long askedEipNum = 1; - - QuotaUtil.QuotaCompareInfo quotaCompareInfo; - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = EipQuotaConstant.EIP_NUM; - quotaCompareInfo.quotaValue = eipNumQuota; - quotaCompareInfo.currentUsed = usedEipNum; - quotaCompareInfo.request = askedEipNum; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - - @Transactional(readOnly = true) - private void check(APIChangeResourceOwnerMsg msg, Map pairs) { - String currentAccountUuid = msg.getSession().getAccountUuid(); - String resourceTargetOwnerAccountUuid = msg.getAccountUuid(); - if (new QuotaUtil().isAdminAccount(resourceTargetOwnerAccountUuid)) { - return; - } - - SimpleQuery q = dbf.createQuery(AccountResourceRefVO.class); - q.add(AccountResourceRefVO_.resourceUuid, Op.EQ, msg.getResourceUuid()); - AccountResourceRefVO accResRefVO = q.find(); - - - if (accResRefVO.getResourceType().equals(VmInstanceVO.class.getSimpleName())) { - long eipNumQuota = pairs.get(EipQuotaConstant.EIP_NUM).getValue(); - long usedEipNum = getUsedEipNum(resourceTargetOwnerAccountUuid); - long askedEipNum = getVmEipNum(msg.getResourceUuid()); - - QuotaUtil.QuotaCompareInfo quotaCompareInfo; - quotaCompareInfo = new QuotaUtil.QuotaCompareInfo(); - quotaCompareInfo.currentAccountUuid = currentAccountUuid; - quotaCompareInfo.resourceTargetOwnerAccountUuid = resourceTargetOwnerAccountUuid; - quotaCompareInfo.quotaName = EipQuotaConstant.EIP_NUM; - quotaCompareInfo.quotaValue = eipNumQuota; - quotaCompareInfo.currentUsed = usedEipNum; - quotaCompareInfo.request = askedEipNum; - new QuotaUtil().CheckQuota(quotaCompareInfo); - } - } - }; - Quota quota = new Quota(); - quota.addMessageNeedValidation(APICreateEipMsg.class); - quota.addMessageNeedValidation(APIChangeResourceOwnerMsg.class); - quota.setOperator(checker); - - QuotaPair p = new QuotaPair(); - p.setName(EipQuotaConstant.EIP_NUM); - p.setValue(EipQuotaGlobalConfig.EIP_NUM.defaultValue(Long.class)); - quota.addPair(p); + quota.defineQuota(new EipNumQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateEipMsg.class). + addCounterQuota(EipQuotaConstant.EIP_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(EipVO.class) + .eq(EipVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(EipQuotaConstant.EIP_NUM)); return list(quota); } @@ -1784,11 +1678,26 @@ public void vmIpChanged(VmInstanceInventory vm, VmNicInventory nic, Map filterVmNicsForEipInVirtualRouter(VipInventory vip, List vmNics); - + List filterEipsForVmNicInVirtualRouter(VmNicInventory vmNic, List eips); } diff --git a/plugin/eip/src/main/java/org/zstack/network/service/eip/PackageInfo.java b/plugin/eip/src/main/java/org/zstack/network/service/eip/PackageInfo.java index ffbf80c4d68..458918b453d 100755 --- a/plugin/eip/src/main/java/org/zstack/network/service/eip/PackageInfo.java +++ b/plugin/eip/src/main/java/org/zstack/network/service/eip/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "弹性IP") +@PackageAPIInfo( + APICategoryName = "弹性IP", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/expon/pom.xml b/plugin/expon/pom.xml new file mode 100644 index 00000000000..48c98522980 --- /dev/null +++ b/plugin/expon/pom.xml @@ -0,0 +1,109 @@ + + + + plugin + org.zstack + 5.4.0 + + 4.0.0 + + expon + + + + org.zstack + kvm + ${project.version} + + + javax.servlet + javax.servlet-api + 3.1.0 + + + com.squareup.okhttp3 + okhttp + 4.9.3 + + + org.zstack + vhost + ${project.version} + + + org.zstack + iscsi + ${project.version} + + + org.zstack + externalStorage + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + diff --git a/plugin/expon/src/main/java/org/zstack/expon/AccountInfo.java b/plugin/expon/src/main/java/org/zstack/expon/AccountInfo.java new file mode 100644 index 00000000000..79244e21a68 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/AccountInfo.java @@ -0,0 +1,6 @@ +package org.zstack.expon; + +public class AccountInfo { + public String username; + public String password; +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponAddonInfo.java b/plugin/expon/src/main/java/org/zstack/expon/ExponAddonInfo.java new file mode 100644 index 00000000000..07259255377 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponAddonInfo.java @@ -0,0 +1,214 @@ +package org.zstack.expon; + +import org.zstack.expon.sdk.cluster.TianshuClusterModule; +import org.zstack.expon.sdk.pool.FailureDomainModule; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +public class ExponAddonInfo { + private List clusters = new ArrayList<>(); + + private List pools = new ArrayList<>(); + + private String currentIscsiTargetId; + private int currentIscsiTargetIndex; + + private String currentImageIscsiTargetId; + private int currentImageIscsiTargetIndex; + + public List getPools() { + return pools; + } + + public void setPools(List pools) { + this.pools = pools; + } + + public void setClusters(List clusters) { + this.clusters = clusters; + } + + public List getClusters() { + return clusters; + } + + public String getCurrentIscsiTargetId() { + return currentIscsiTargetId; + } + + public void setCurrentIscsiTargetId(String currentIscsiTargetId) { + this.currentIscsiTargetId = currentIscsiTargetId; + } + + public int getCurrentIscsiTargetIndex() { + return currentIscsiTargetIndex; + } + + public void setCurrentIscsiTargetIndex(int currentIscsiTargetIndex) { + this.currentIscsiTargetIndex = currentIscsiTargetIndex; + } + + public String getCurrentImageIscsiTargetId() { + return currentImageIscsiTargetId; + } + + public void setCurrentImageIscsiTargetId(String currentImageIscsiTargetId) { + this.currentImageIscsiTargetId = currentImageIscsiTargetId; + } + + public int getCurrentImageIscsiTargetIndex() { + return currentImageIscsiTargetIndex; + } + + public void setCurrentImageIscsiTargetIndex(int currentImageIscsiTargetIndex) { + this.currentImageIscsiTargetIndex = currentImageIscsiTargetIndex; + } + + public static class Pool { + private String id; + private String name; + private long availableCapacity; + private long totalCapacity; + private String tianshuId; + private String healthStatus; + private String redundancyPolicy; + private int replicatedSize; + private Timestamp createDate; + private Timestamp lastOpDate; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getAvailableCapacity() { + return availableCapacity; + } + + public void setAvailableCapacity(long availableCapacity) { + this.availableCapacity = availableCapacity; + } + + public long getTotalCapacity() { + return totalCapacity; + } + + public void setTotalCapacity(long totalCapacity) { + this.totalCapacity = totalCapacity; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public static Pool valueOf(FailureDomainModule failureDomainModule) { + Pool pool = new Pool(); + pool.setId(failureDomainModule.getId()); + pool.setName(failureDomainModule.getFailureDomainName()); + pool.setAvailableCapacity(failureDomainModule.getAvailableCapacity()); + pool.setTotalCapacity(failureDomainModule.getValidSize()); + pool.setTianshuId(failureDomainModule.getTianshuId()); + pool.setHealthStatus(failureDomainModule.getHealthStatus()); + pool.setRedundancyPolicy(failureDomainModule.getRedundancyPloy()); + pool.setReplicatedSize(failureDomainModule.getReplicateSize()); + pool.setCreateDate(new Timestamp(failureDomainModule.getCreateTime())); + pool.setLastOpDate(new Timestamp(failureDomainModule.getUpdateTime())); + return pool; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getRedundancyPolicy() { + return redundancyPolicy; + } + + public void setRedundancyPolicy(String redundancyPolicy) { + this.redundancyPolicy = redundancyPolicy; + } + + public int getReplicatedSize() { + return replicatedSize; + } + + public void setReplicatedSize(int replicatedSize) { + this.replicatedSize = replicatedSize; + } + } + + public static class TianshuCluster { + private String id; + private String name; + private String healthStatus; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public static TianshuCluster valueOf(TianshuClusterModule tianshuClusterModule) { + TianshuCluster tianshuCluster = new TianshuCluster(); + tianshuCluster.setId(tianshuClusterModule.getId()); + tianshuCluster.setName(tianshuClusterModule.getName()); + tianshuCluster.setHealthStatus(tianshuClusterModule.getHealthStatus()); + return tianshuCluster; + } + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponApiHelper.java b/plugin/expon/src/main/java/org/zstack/expon/ExponApiHelper.java new file mode 100644 index 00000000000..a75fb54f7fc --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponApiHelper.java @@ -0,0 +1,1000 @@ +package org.zstack.expon; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.Lists; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.singleflight.MultiNodeSingleFlightImpl; +import org.zstack.expon.sdk.*; +import org.zstack.expon.sdk.cluster.QueryTianshuClusterRequest; +import org.zstack.expon.sdk.cluster.QueryTianshuClusterResponse; +import org.zstack.expon.sdk.cluster.TianshuClusterModule; +import org.zstack.expon.sdk.config.SetTrashExpireTimeRequest; +import org.zstack.expon.sdk.config.SetTrashExpireTimeResponse; +import org.zstack.expon.sdk.iscsi.*; +import org.zstack.expon.sdk.nvmf.*; +import org.zstack.expon.sdk.pool.*; +import org.zstack.expon.sdk.uss.QueryUssGatewayRequest; +import org.zstack.expon.sdk.uss.QueryUssGatewayResponse; +import org.zstack.expon.sdk.uss.UssGatewayModule; +import org.zstack.expon.sdk.vhost.*; +import org.zstack.expon.sdk.volume.*; +import org.zstack.header.core.Completion; +import org.zstack.header.core.FutureCompletion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.expon.ExponError; +import org.zstack.header.storage.addon.SingleFlightExecutor; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + +import java.time.LocalDate; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class ExponApiHelper implements SingleFlightExecutor { + private static CLogger logger = Utils.getLogger(ExponApiHelper.class); + AccountInfo accountInfo; + ExponClient client; + String sessionId; + String refreshToken; + private String storageUuid; + + @Autowired + private MultiNodeSingleFlightImpl singleFlight; + + private static final Cache snapshotClientCache = CacheBuilder.newBuilder() + .maximumSize(1000) + .build(); + + ExponApiHelper(AccountInfo accountInfo, ExponClient client) { + this.accountInfo = accountInfo; + this.client = client; + this.client.setSessionRefresher(this::refreshSessionInQueue); + this.client.setSessionGetter(() -> sessionId); + } + + void setStorageUuid(String storageUuid) { + this.storageUuid = storageUuid; + } + + private T callWithExpiredSessionRetry(ExponRequest req, Class clz) { + req.setSessionId(sessionId); + T rsp = client.call(req, clz); + + if (!rsp.isSuccess() && rsp.sessionExpired()) { + refreshSessionInQueue(); + req.setSessionId(sessionId); + rsp = client.call(req, clz); + } + return rsp; + } + + private synchronized String refreshSessionInQueue() { + FutureCompletion fcompl = new FutureCompletion(null); + ReturnValueCompletion completion = new ReturnValueCompletion(fcompl) { + @Override + public void success(Object returnValue) { + sessionId = (String) returnValue; + fcompl.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + fcompl.fail(errorCode); + } + }; + + singleFlight.run(this, "refreshSession", completion); + + fcompl.await(TimeUnit.MILLISECONDS.toSeconds(30)); + if (!fcompl.isSuccess()) { + throw new OperationFailureException(fcompl.getErrorCode()); + } + return sessionId; + } + + @SingleFlightExecutor.SingleFlight + public void refreshSession(ReturnValueCompletion completion) { + if (sessionExpired()) { + login(); + } + completion.success(sessionId); + } + + private boolean sessionExpired() { + if (sessionId == null) { + return true; + } + + QueryTianshuClusterRequest req = new QueryTianshuClusterRequest(); + + req.setSessionId(sessionId); + QueryTianshuClusterResponse rsp = client.call(req, QueryTianshuClusterResponse.class); + return rsp.sessionExpired(); + } + + public T call(ExponRequest req, Class clz) { + return callWithExpiredSessionRetry(req, clz); + } + + public T callErrorOut(ExponRequest req, Class clz) { + T rsp = callWithExpiredSessionRetry(req, clz); + errorOut(rsp); + return rsp; + } + + public T callIgnoringSpecificErrors(ExponRequest req, Class clz, ExponError... specificErrors) { + T rsp = callWithExpiredSessionRetry(req, clz); + if (rsp.isError(specificErrors)) { + return rsp; + } + + errorOut(rsp); + return rsp; + } + + public void call(ExponRequest req, Completion completion) { + req.setSessionId(sessionId); + client.call(req, result -> { + if (result.error == null) { + completion.success(); + return; + } + + if (!result.error.sessionExpired()) { + completion.fail(operr("expon request failed, code %s, message: %s.", result.error.getRetCode(), result.error.getMessage())); + return; + } + + refreshSessionInQueue(); + req.setSessionId(sessionId); + client.call(req, retryRes -> { + if (retryRes.error != null) { + completion.fail(operr("expon request failed, code %s, message: %s.", retryRes.error.getRetCode(), retryRes.error.getMessage())); + return; + } + + completion.success(); + }); + }); + } + + public void errorOut(ExponResponse rsp) { + if (!rsp.isSuccess()) { + throw new OperationFailureException(operr("expon request failed, code %s, message: %s.", rsp.getRetCode(), rsp.getMessage())); + } + } + + public T query(ExponQueryRequest req, Class clz) { + return call(req, clz); + } + + public T queryErrorOut(ExponQueryRequest req, Class clz) { + return callErrorOut(req, clz); + } + + public void login() { + LoginExponRequest req = new LoginExponRequest(); + req.setName(accountInfo.username); + req.setPassword(accountInfo.password); + LoginExponResponse rsp = callErrorOut(req, LoginExponResponse.class); + sessionId = rsp.getAccessToken(); + } + + public List queryPools() { + QueryFailureDomainRequest req = new QueryFailureDomainRequest(); + return queryErrorOut(req, QueryFailureDomainResponse.class).getFailureDomains(); + } + + public FailureDomainModule getPool(String id) { + GetFailureDomainRequest req = new GetFailureDomainRequest(); + req.setId(id); + return callErrorOut(req, GetFailureDomainResponse.class).getMembers(); + } + + public List queryClusters() { + QueryTianshuClusterRequest req = new QueryTianshuClusterRequest(); + return queryErrorOut(req, QueryTianshuClusterResponse.class).getResult(); + } + + public UssGatewayModule queryUssGateway(String name) { + QueryUssGatewayRequest q = new QueryUssGatewayRequest(); + q.addCond("name", name); + QueryUssGatewayResponse rsp = queryErrorOut(q, QueryUssGatewayResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getUssGateways().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public List listUssGateway() { + QueryUssGatewayRequest q = new QueryUssGatewayRequest(); + QueryUssGatewayResponse rsp = queryErrorOut(q, QueryUssGatewayResponse.class); + + return rsp.getUssGateways(); + } + + public VhostControllerModule queryVhostController(String name) { + QueryVhostControllerRequest q = new QueryVhostControllerRequest(); + q.addCond("name", name); + QueryVhostControllerResponse rsp = queryErrorOut(q, QueryVhostControllerResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getVhosts().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public VhostControllerModule createVhostController(String name) { + CreateVhostControllerRequest req = new CreateVhostControllerRequest(); + req.setName(name); + CreateVhostControllerResponse rsp = callErrorOut(req, CreateVhostControllerResponse.class); + + VhostControllerModule inv = new VhostControllerModule(); + inv.setId(rsp.getId()); + inv.setName(name); + inv.setPath("/var/run/wds/" + name); + return inv; + } + + public void deleteVhostController(String id) { + DeleteVhostControllerRequest req = new DeleteVhostControllerRequest(); + req.setId(id); + callErrorOut(req, DeleteVhostControllerResponse.class); + } + + public VolumeModule queryVolume(String name) { + QueryVolumeRequest req = new QueryVolumeRequest(); + req.addCond("name", name); + QueryVolumeResponse rsp = queryErrorOut(req, QueryVolumeResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getVolumes().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public VolumeModule getVolumeOrElseNull(String id) { + GetVolumeRequest req = new GetVolumeRequest(); + req.setVolId(id); + return callIgnoringSpecificErrors(req, GetVolumeResponse.class, ExponError.VOLUME_NOT_FOUND).getVolumeDetail(); + } + + public VolumeModule getVolume(String id) { + GetVolumeRequest req = new GetVolumeRequest(); + req.setVolId(id); + return callErrorOut(req, GetVolumeResponse.class).getVolumeDetail(); + } + + public boolean addVhostVolumeToUss(String volumeId, String vhostId, String ussGwId) { + AddVhostControllerToUssRequest req = new AddVhostControllerToUssRequest(); + req.setLunId(volumeId); + req.setVhostId(vhostId); + req.setUssGwId(ussGwId); + AddVhostControllerToUssResponse rsp = call(req, AddVhostControllerToUssResponse.class); + if (rsp.isError(ExponError.VHOST_BIND_USS_FAILED) && rsp.getMessage().contains("already bind")) { + return true; + } + + errorOut(rsp); + return true; + } + + public boolean removeVhostVolumeFromUss(String volumeId, String vhostId, String ussGwId) { + RemoveVhostControllerFromUssRequest req = new RemoveVhostControllerFromUssRequest(); + req.setLunId(volumeId); + req.setVhostId(vhostId); + req.setUssGwId(ussGwId); + RemoveVhostControllerFromUssResponse rsp = call(req, RemoveVhostControllerFromUssResponse.class); + if (rsp.isError(ExponError.VHOST_ALREADY_UNBIND_USS)) { + return true; + } + + errorOut(rsp); + return true; + } + + public List getVhostControllerBoundUss(String vhostId) { + GetVhostControllerBoundUssRequest req = new GetVhostControllerBoundUssRequest(); + req.setVhostId(vhostId); + GetVhostControllerBoundUssResponse rsp = call(req, GetVhostControllerBoundUssResponse.class); + return rsp.getUss(); + } + + public VolumeModule createVolume(String name, String poolId, long size) { + CreateVolumeRequest req = new CreateVolumeRequest(); + req.setName(name); + req.setPhyPoolId(poolId); + req.setVolumeSize(size); + CreateVolumeResponse rsp = callErrorOut(req, CreateVolumeResponse.class); + + return getVolume(rsp.getId()); + } + + public void deleteVolume(String volId, boolean force) { + DeleteVolumeRequest req = new DeleteVolumeRequest(); + req.setVolId(volId); + req.setForce(force); + callErrorOut(req, DeleteVolumeResponse.class); + } + + public void deleteVolumeAndSnapshots(String volId, boolean force) { + List snaps = queryVolumeSnapshots(volId); + snaps.forEach(snap -> { + String addedIscsiClientId = getSnapshotAttachedIscsiClientGroups(snap.getId()).stream().findFirst().orElse(null); + if (addedIscsiClientId != null) { + removeSnapshotFromIscsiClientGroup(snap.getId(), addedIscsiClientId); + } + deleteVolumeSnapshot(snap.getId(), true); + }); + deleteVolume(volId, force); + } + + public VolumeModule cloneVolume(String snapId, String name, ExponVolumeQos qos) { + CloneVolumeRequest req = new CloneVolumeRequest(); + req.setSnapshotId(snapId); + if (qos != null) { + req.setQos(qos); + } + req.setName(name); + CloneVolumeResponse rsp = callErrorOut(req, CloneVolumeResponse.class); + + return getVolume(rsp.getId()); + } + + public void copySnapshot(String snapId, String poolId, String name, ExponVolumeQos qos, ReturnValueCompletion completion) { + CopyVolumeSnapshotRequest req = new CopyVolumeSnapshotRequest(); + req.setSnapshotId(snapId); + req.setPhyPoolId(poolId); + if (qos != null) { + req.setQos(qos); + } + req.setName(name); + + call(req, new Completion(completion) { + @Override + public void success() { + VolumeModule vol = queryVolume(name); + if (vol == null) { + completion.fail(operr("cannot find volume[name:%s] after copy snapshot", name)); + return; + } + + completion.success(vol); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + public VolumeModule expandVolume(String volId, long size) { + ExpandVolumeRequest req = new ExpandVolumeRequest(); + req.setId(volId); + req.setSize(size); + ExpandVolumeResponse rsp = callErrorOut(req, ExpandVolumeResponse.class); + + return getVolume(volId); + } + + public VolumeModule setVolumeQos(String volId, ExponVolumeQos qos) { + SetVolumeQosRequest req = new SetVolumeQosRequest(); + req.setQos(qos); + req.setVolId(volId); + callErrorOut(req, SetVolumeQosResponse.class); + return getVolume(volId); + } + + public void deleteVolumeQos(String volId) { + SetVolumeQosRequest req = new SetVolumeQosRequest(); + req.setVolId(volId); + req.setQos(new ExponVolumeQos()); + callErrorOut(req, SetVolumeQosResponse.class); + } + + public VolumeModule recoverySnapshot(String volId, String snapId) { + RecoveryVolumeSnapshotRequest req = new RecoveryVolumeSnapshotRequest(); + req.setSnapId(snapId); + req.setVolumeId(volId); + RecoveryVolumeSnapshotResponse rsp = callErrorOut(req, RecoveryVolumeSnapshotResponse.class); + + return getVolume(volId); + } + + public VolumeSnapshotModule createVolumeSnapshot(String volId, String name, String description) { + CreateVolumeSnapshotRequest req = new CreateVolumeSnapshotRequest(); + req.setName(name); + req.setDescription(description); + req.setVolumeId(volId); + CreateVolumeSnapshotResponse rsp = callErrorOut(req, CreateVolumeSnapshotResponse.class); + + return queryVolumeSnapshot(name); + } + + // TODO change to async + public void deleteVolumeSnapshot(String snapId, boolean force) { + DeleteVolumeSnapshotRequest req = new DeleteVolumeSnapshotRequest(); + req.setSnapshotId(snapId); + req.setForce(force); + callIgnoringSpecificErrors(req, DeleteVolumeSnapshotResponse.class, ExponError.SNAPSHOT_NOT_FOUND); + } + + public List queryVolumeSnapshots(String volId) { + QueryVolumeSnapshotRequest req = new QueryVolumeSnapshotRequest(); + req.addCond("volume_id", volId); + QueryVolumeSnapshotResponse rsp = queryErrorOut(req, QueryVolumeSnapshotResponse.class); + if (rsp.getTotal() == 0) { + return new ArrayList<>(); + } + return rsp.getSnaps().stream().filter(it -> it.getVolumeId().equals(volId)).collect(Collectors.toList()); + } + + public VolumeSnapshotModule queryVolumeSnapshot(String name) { + QueryVolumeSnapshotRequest req = new QueryVolumeSnapshotRequest(); + req.addCond("name", name); + QueryVolumeSnapshotResponse rsp = queryErrorOut(req, QueryVolumeSnapshotResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getSnaps().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public VolumeSnapshotModule getVolumeSnapshot(String snapshotId) { + GetVolumeSnapshotRequest req = new GetVolumeSnapshotRequest(); + req.setId(snapshotId); + GetVolumeSnapshotResponse rsp = callErrorOut(req, GetVolumeSnapshotResponse.class); + + return JSONObjectUtil.rehashObject(rsp, VolumeSnapshotModule.class); + } + + public NvmfModule queryNvmfController(String name) { + QueryNvmfTargetRequest req = new QueryNvmfTargetRequest(); + req.addCond("name", name); + QueryNvmfTargetResponse rsp = queryErrorOut(req, QueryNvmfTargetResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getNvmfs().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public NvmfModule createNvmfController(String name, String tianshuId, String nqnSuffix) { + CreateNvmfTargetRequest req = new CreateNvmfTargetRequest(); + req.setName(name); + LocalDate d = LocalDate.now(); + String nqn = String.format("nqn.%d-%d.com.sds.wds:%s", d.getYear(), d.getMonthValue(), nqnSuffix); + req.setNqn(nqn); + req.setTianshuId(tianshuId); + CreateNvmfTargetResponse rsp = callErrorOut(req, CreateNvmfTargetResponse.class); + + NvmfModule nvmf = new NvmfModule(); + nvmf.setId(rsp.getId()); + nvmf.setName(name); + nvmf.setNqn(nqn); + return nvmf; + } + + public void deleteNvmfController(String id) { + DeleteNvmfTargetRequest req = new DeleteNvmfTargetRequest(); + req.setNvmfId(id); + callErrorOut(req, DeleteNvmfTargetResponse.class); + } + + public NvmfClientGroupModule queryNvmfClient(String name) { + QueryNvmfClientGroupRequest req = new QueryNvmfClientGroupRequest(); + req.addCond("name", name); + QueryNvmfClientGroupResponse rsp = queryErrorOut(req, QueryNvmfClientGroupResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getClients().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public NvmfClientGroupModule createNvmfClient(String name, String tianshuId, List hostNqns) { + CreateNvmfClientGroupRequest req = new CreateNvmfClientGroupRequest(); + req.setName(name); + req.setDescription("description"); + req.setTianshuId(tianshuId); + List hosts = new ArrayList<>(); + if (!CollectionUtils.isEmpty(hostNqns)) { + for (String hostNqn : hostNqns) { + NvmfClient host = new NvmfClient(); + host.setHostType("nqn"); + host.setHost(hostNqn); + hosts.add(host); + } + req.setHosts(hosts); + } + CreateNvmfClientGroupResponse rsp = callErrorOut(req, CreateNvmfClientGroupResponse.class); + + NvmfClientGroupModule client = new NvmfClientGroupModule(); + client.setId(rsp.getId()); + client.setName(name); + return client; + } + + public NvmfClientGroupModule addNvmfClientHost(String clientId, String nqn) { + ChangeNvmeClientGroupRequest req = new ChangeNvmeClientGroupRequest(); + req.setClientId(clientId); + req.setAction(ExponAction.add.name()); + NvmfClient host = new NvmfClient(); + host.setHostType("nqn"); + host.setHost(nqn); + req.setHosts(Collections.singletonList(host)); + ChangeNvmeClientGroupResponse rsp = callErrorOut(req, ChangeNvmeClientGroupResponse.class); + + return queryNvmfClient(clientId); + } + + public NvmfClientGroupModule removeNvmfClientHost(String clientId, String nqn) { + ChangeNvmeClientGroupRequest req = new ChangeNvmeClientGroupRequest(); + req.setClientId(clientId); + req.setAction(ExponAction.remove.name()); + NvmfClient host = new NvmfClient(); + host.setHostType("nqn"); + host.setHost(nqn); + req.setHosts(Collections.singletonList(host)); + ChangeNvmeClientGroupResponse rsp = callErrorOut(req, ChangeNvmeClientGroupResponse.class); + + return queryNvmfClient(clientId); + } + + public void deleteNvmfClient(String clientId) { + DeleteNvmfClientGroupRequest req = new DeleteNvmfClientGroupRequest(); + req.setClientId(clientId); + callErrorOut(req, DeleteNvmfClientGroupResponse.class); + } + + public void addNvmfClientToNvmfTarget(String clientId, String targetId) { + AddNvmeClientGroupToNvmfTargetRequest req = new AddNvmeClientGroupToNvmfTargetRequest(); + req.setClients(Collections.singletonList(clientId)); + req.setGatewayId(targetId); + callErrorOut(req, AddNvmeClientGroupToNvmfTargetResponse.class); + } + + public void removeNvmfClientFromNvmfTarget(String clientId, String targetId) { + RemoveNvmeClientGroupFromNvmfTargetRequest req = new RemoveNvmeClientGroupFromNvmfTargetRequest(); + req.setClients(Collections.singletonList(clientId)); + req.setGatewayId(targetId); + callErrorOut(req, RemoveNvmeClientGroupFromNvmfTargetResponse.class); + } + + public void addVolumeToNvmfClientGroup(String volId, String clientId, String targetId) { + ChangeVolumeInNvmfClientGroupRequest req = new ChangeVolumeInNvmfClientGroupRequest(); + req.setClientId(clientId); + req.setAction(ExponAction.add.name()); + req.setLuns(Collections.singletonList(new LunResource(volId, "volume"))); + req.setGateways(Collections.singletonList(targetId)); + callErrorOut(req, ChangeVolumeInNvmfClientGroupResponse.class); + } + + public void addSnapshotToNvmfClientGroup(String snapId, String clientId, String targetId) { + ChangeVolumeInNvmfClientGroupRequest req = new ChangeVolumeInNvmfClientGroupRequest(); + req.setClientId(clientId); + req.setAction(ExponAction.add.name()); + req.setLuns(Collections.singletonList(new LunResource(snapId, "snapshot"))); + req.setGateways(Collections.singletonList(targetId)); + callErrorOut(req, ChangeVolumeInNvmfClientGroupResponse.class); + } + + public void removeVolumeFromNvmfClientGroup(String volId, String clientId) { + ChangeVolumeInNvmfClientGroupRequest req = new ChangeVolumeInNvmfClientGroupRequest(); + req.setClientId(clientId); + req.setAction(ExponAction.remove.name()); + req.setLuns(Collections.singletonList(new LunResource(volId, "volume"))); + callErrorOut(req, ChangeVolumeInNvmfClientGroupResponse.class); + } + + public void removeSnapshotFromNvmfClientGroup(String snapId, String clientId) { + ChangeVolumeInNvmfClientGroupRequest req = new ChangeVolumeInNvmfClientGroupRequest(); + req.setClientId(clientId); + req.setAction(ExponAction.remove.name()); + req.setLuns(Collections.singletonList(new LunResource(snapId, "snapshot"))); + callErrorOut(req, ChangeVolumeInNvmfClientGroupResponse.class); + } + + public NvmfBoundUssGatewayRefModule bindNvmfTargetToUss(String nvmfId, String ussGwId, int port) { + BindNvmfTargetToUssRequest req = new BindNvmfTargetToUssRequest(); + req.setNvmfId(nvmfId); + req.setUssGwId(Collections.singletonList(ussGwId)); + req.setPort(port); + callErrorOut(req, BindNvmfTargetToUssResponse.class); + NvmfBoundUssGatewayRefModule ref = getNvmfBoundUssGateway(nvmfId, ussGwId); + if (ref == null) { + throw new ExponApiException(String.format("cannot find nvmf[id:%s] bound uss gateway[id:%s] ref after bind success", nvmfId, ussGwId)); + } + return ref; + } + + public void unbindNvmfTargetToUss(String nvmfId, String ussGwId) { + UnbindNvmfTargetFromUssRequest req = new UnbindNvmfTargetFromUssRequest(); + req.setNvmfId(nvmfId); + req.setUssGwId(Collections.singletonList(ussGwId)); + callErrorOut(req, UnbindNvmfTargetFromUssResponse.class); + } + + public List getNvmfBoundUssGateway(String nvmfId) { + GetNvmfTargetBoundUssRequest req = new GetNvmfTargetBoundUssRequest(); + req.setNvmfId(nvmfId); + GetNvmfTargetBoundUssResponse rsp = callErrorOut(req, GetNvmfTargetBoundUssResponse.class); + return rsp.getResult(); + } + + public NvmfBoundUssGatewayRefModule getNvmfBoundUssGateway(String nvmfId, String ussGwId) { + GetNvmfTargetBoundUssRequest req = new GetNvmfTargetBoundUssRequest(); + req.setNvmfId(nvmfId); + GetNvmfTargetBoundUssResponse rsp = callErrorOut(req, GetNvmfTargetBoundUssResponse.class); + return rsp.getResult().stream().filter(it -> it.getUssGwId().equals(ussGwId)).findFirst().orElse(null); + } + + public List getIscsiTargetServer(String tianshuId) { + GetIscsiTargetServerRequest req = new GetIscsiTargetServerRequest(); + req.setTianshuId(tianshuId); + GetIscsiTargetServerResponse rsp = callErrorOut(req, GetIscsiTargetServerResponse.class); + return rsp.getNodes(); + } + + + public IscsiModule createIscsiController(String name, String tianshuId, int port, List uss) { + CreateIscsiTargetRequest req = new CreateIscsiTargetRequest(); + req.setName(name); + req.setTianshuId(tianshuId); + req.setPort(port); + req.setNodes(uss); + CreateIscsiTargetResponse rsp = callErrorOut(req, CreateIscsiTargetResponse.class); + return queryIscsiController(name); + } + + public IscsiModule queryIscsiController(String name) { + QueryIscsiTargetRequest req = new QueryIscsiTargetRequest(); + req.addCond("name", name); + QueryIscsiTargetResponse rsp = queryErrorOut(req, QueryIscsiTargetResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getGateways().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public List listIscsiController() { + QueryIscsiTargetRequest req = new QueryIscsiTargetRequest(); + QueryIscsiTargetResponse rsp = queryErrorOut(req, QueryIscsiTargetResponse.class); + if (rsp.getTotal() == 0) { + return Collections.emptyList(); + } + + return rsp.getGateways(); + } + + public IscsiModule getIscsiController(String id) { + GetIscsiTargetRequest req = new GetIscsiTargetRequest(); + req.setId(id); + + GetIscsiTargetResponse rsp = callErrorOut(req, GetIscsiTargetResponse.class); + return JSONObjectUtil.rehashObject(rsp, IscsiModule.class); + } + + public void deleteIscsiController(String id) { + DeleteIscsiTargetRequest req = new DeleteIscsiTargetRequest(); + req.setId(id); + callErrorOut(req, DeleteIscsiTargetResponse.class); + } + + public IscsiClientGroupModule queryIscsiClient(String name) { + QueryIscsiClientGroupRequest req = new QueryIscsiClientGroupRequest(); + req.addCond("name", name); + QueryIscsiClientGroupResponse rsp = queryErrorOut(req, QueryIscsiClientGroupResponse.class); + if (rsp.getTotal() == 0) { + return null; + } + + return rsp.getClients().stream().filter(it -> it.getName().equals(name)).findFirst().orElse(null); + } + + public IscsiClientGroupModule getIscsiClient(String id) { + GetIscsiClientGroupRequest req = new GetIscsiClientGroupRequest(); + req.setId(id); + GetIscsiClientGroupResponse rsp = callErrorOut(req, GetIscsiClientGroupResponse.class); + + return JSONObjectUtil.rehashObject(rsp, IscsiClientGroupModule.class); + } + + public IscsiClientGroupModule createIscsiClient(String name, String tianshuId, List clients) { + CreateIscsiClientGroupRequest req = new CreateIscsiClientGroupRequest(); + req.setName(name); + req.setTianshuId(tianshuId); + List hosts = new ArrayList<>(); + if (!CollectionUtils.isEmpty(clients)) { + for (String client : clients) { + IscsiClient host = new IscsiClient(); + host.setHostType(client.contains("iqn") ? "iqn" : "ip"); + host.setHost(client); + hosts.add(host); + } + req.setHosts(hosts); + } + CreateIscsiClientGroupResponse rsp = callErrorOut(req, CreateIscsiClientGroupResponse.class); + return queryIscsiClient(name); + } + + public void deleteIscsiClient(String id) { + DeleteIscsiClientGroupRequest req = new DeleteIscsiClientGroupRequest(); + req.setId(id); + req.setForce(true); + callErrorOut(req, DeleteIscsiClientGroupResponse.class); + } + + public void addIscsiClientToIscsiTarget(String clientId, String targetId) { + AddIscsiClientGroupToIscsiTargetRequest req = new AddIscsiClientGroupToIscsiTargetRequest(); + req.setClients(Collections.singletonList(clientId)); + req.setId(targetId); + callErrorOut(req, AddIscsiClientGroupToIscsiTargetResponse.class); + } + + public void removeIscsiClientFromIscsiTarget(String clientId, String targetId) { + RemoveIscsiClientGroupFromIscsiTargetRequest req = new RemoveIscsiClientGroupFromIscsiTargetRequest(); + req.setClients(Collections.singletonList(clientId)); + req.setId(targetId); + callErrorOut(req, RemoveIscsiClientGroupFromIscsiTargetResponse.class); + } + + public void addHostToIscsiClient(String host, String clientId) { + ChangeIscsiClientGroupRequest req = new ChangeIscsiClientGroupRequest(); + req.setId(clientId); + req.setAction(ExponAction.add.name()); + IscsiClient iscsiClient = new IscsiClient(); + iscsiClient.setHostType(host.contains("iqn") ? "iqn" : "ip"); + iscsiClient.setHost(host); + req.setHosts(Collections.singletonList(iscsiClient)); + callErrorOut(req, ChangeIscsiClientGroupResponse.class); + } + + public void removeHostFromIscsiClient(String host, String clientId) { + ChangeIscsiClientGroupRequest req = new ChangeIscsiClientGroupRequest(); + req.setId(clientId); + req.setAction(ExponAction.remove.name()); + IscsiClient iscsiClient = new IscsiClient(); + iscsiClient.setHostType(host.contains("iqn") ? "iqn" : "ip"); + iscsiClient.setHost(host); + req.setHosts(Collections.singletonList(iscsiClient)); + callErrorOut(req, ChangeIscsiClientGroupResponse.class); + } + + public List getIscsiClientAttachedTargets(String clientId) { + GetIscsiClientGroupAttachedTargetRequest req = new GetIscsiClientGroupAttachedTargetRequest(); + req.setId(clientId); + GetIscsiClientGroupAttachedTargetResponse rsp = callErrorOut(req, GetIscsiClientGroupAttachedTargetResponse.class); + return rsp.getGateways(); + } + + public void addVolumeToIscsiClientGroup(String volId, String clientId, String targetId, boolean readonly) { + ChangeVolumeInIscsiClientGroupRequest req = new ChangeVolumeInIscsiClientGroupRequest(); + req.setId(clientId); + req.setAction(ExponAction.add.name()); + req.setLuns(Collections.singletonList(new LunResource(volId, "volume", readonly))); + req.setGateways(Collections.singletonList(targetId)); + ChangeVolumeInIscsiClientGroupResponse rsp = call(req, ChangeVolumeInIscsiClientGroupResponse.class); + if (!rsp.isSuccess() && rsp.isError(ExponError.LUN_ALREADY_MAPPED_SOME_ISCSI_CLIENT) && + getIscsiClientGroupAttachedVolumes(clientId).contains(volId)) { + return; + } + + errorOut(rsp); + } + + public void addSnapshotToIscsiClientGroup(String snapId, String clientId, String targetId) { + ChangeSnapshotInIscsiClientGroupRequest req = new ChangeSnapshotInIscsiClientGroupRequest(); + req.setId(clientId); + req.setAction(ExponAction.add.name()); + req.setLuns(Collections.singletonList(new LunResource(snapId, "snapshot", true))); + req.setGateways(Collections.singletonList(targetId)); + ChangeVolumeInIscsiClientGroupResponse rsp = call(req, ChangeVolumeInIscsiClientGroupResponse.class); + if (!rsp.isSuccess() && rsp.isError(ExponError.LUN_ALREADY_MAPPED_SOME_ISCSI_CLIENT) && + getIscsiClientGroupAttachedSnapshots(clientId).contains(snapId)) { + return; + } + + errorOut(rsp); + } + + public Set getIscsiClientGroupAttachedVolumes(String clientId) { + GetVolumesInIscsiClientGroupRequest req = new GetVolumesInIscsiClientGroupRequest(); + req.setId(clientId); + GetVolumesInIscsiClientGroupResponse rsp = callErrorOut(req, GetVolumesInIscsiClientGroupResponse.class); + return rsp.getLuns().stream().map(IscsiClientMappedLunModule::getId).collect(Collectors.toSet()); + } + + public Set getIscsiClientGroupAttachedSnapshots(String clientId) { + GetSnapshotsInIscsiClientGroupRequest req = new GetSnapshotsInIscsiClientGroupRequest(); + req.setId(clientId); + req.limit = 100L; // iscsi client group lun limit is 64 + GetSnapshotsInIscsiClientGroupResponse rsp = callErrorOut(req, GetSnapshotsInIscsiClientGroupResponse.class); + return rsp.getLuns().stream().map(IscsiClientMappedLunModule::getId).collect(Collectors.toSet()); + } + + public List getVolumeAttachedIscsiClientGroups(String volId) { + GetVolumeBoundIscsiClientGroupRequest req = new GetVolumeBoundIscsiClientGroupRequest(); + req.setVolumeId(volId); + GetVolumeBoundIscsiClientGroupResponse rsp = callErrorOut(req, GetVolumeBoundIscsiClientGroupResponse.class); + return rsp.getClients().stream().map(LunBoundIscsiClientGroupModule::getId).collect(Collectors.toList()); + } + + public List getSnapshotAttachedIscsiClientGroups(String snapId) { + String cacheClientId = snapshotClientCache.getIfPresent(snapId); + if (cacheClientId != null) { + if (getIscsiClientGroupAttachedSnapshots(cacheClientId).contains(snapId)) { + return Collections.singletonList(cacheClientId); + } else { + snapshotClientCache.invalidate(snapId); + } + } + + // TODO + QueryIscsiClientGroupRequest req = new QueryIscsiClientGroupRequest(); + QueryIscsiClientGroupResponse rsp = queryErrorOut(req, QueryIscsiClientGroupResponse.class); + for (IscsiClientGroupModule client : rsp.getClients()) { + if (client.getSnapNum() > 0) { + if (getIscsiClientGroupAttachedSnapshots(client.getId()).contains(snapId)) { + snapshotClientCache.put(snapId, client.getId()); + return Collections.singletonList(client.getId()); + } + } + } + + return Collections.emptyList(); + } + + public void removeVolumeFromIscsiClientGroup(String volId, String clientId) { + ChangeVolumeInIscsiClientGroupRequest req = new ChangeVolumeInIscsiClientGroupRequest(); + req.setId(clientId); + req.setAction(ExponAction.remove.name()); + req.setLuns(Collections.singletonList(new LunResource(volId, "volume"))); + ChangeVolumeInIscsiClientGroupResponse rsp = call(req, ChangeVolumeInIscsiClientGroupResponse.class); + if (rsp.isError(ExponError.LUN_ALREADY_UNMAPPED_ISCSI_CLIENT)) { + return; + } + + errorOut(rsp); + } + + public void removeSnapshotFromIscsiClientGroup(String snapId, String clientId) { + ChangeSnapshotInIscsiClientGroupRequest req = new ChangeSnapshotInIscsiClientGroupRequest(); + req.setId(clientId); + req.setAction(ExponAction.remove.name()); + req.setLuns(Collections.singletonList(new LunResource(snapId, "snapshot"))); + ChangeSnapshotInIscsiClientGroupResponse rsp = call(req, ChangeSnapshotInIscsiClientGroupResponse.class); + if (rsp.isError(ExponError.LUN_ALREADY_UNMAPPED_ISCSI_CLIENT)) { + return; + } + + errorOut(rsp); + } + + public List getVolumeBoundPath(String volId, List pools) { + VolumeModule volume = getVolume(volId); + List paths = Lists.newArrayList(); + for (FailureDomainModule pool : pools) { + GetFailureDomainBlacklistRequest req = new GetFailureDomainBlacklistRequest(); + req.setId(pool.getId()); + GetFailureDomainBlacklistResponse rsp = callErrorOut(req, GetFailureDomainBlacklistResponse.class); + paths.addAll(rsp.getEntries().stream() + .map(BlacklistModule::getPath) + .filter(path -> ExponNameHelper.getVolumeNameFromBoundPath(path).equals(volume.getVolumeName())) + .collect(Collectors.toList())); + } + + return paths; + } + + public void addVolumePathToBlacklist(String path) { + AddVolumePathToBlacklistRequest req = new AddVolumePathToBlacklistRequest(); + req.setPath(path); + callErrorOut(req, AddVolumePathToBlacklistResponse.class); + } + + public void removeVolumePathFromBlacklist(String path, String volId, List pools) { + List paths = getVolumeBoundPath(volId, pools); + if (!paths.contains(path)) { + return; + } + + RemoveVolumePathFromBlacklistRequest req = new RemoveVolumePathFromBlacklistRequest(); + req.setPath(path); + + RemoveVolumePathFromBlacklistResponse rsp = call(req, RemoveVolumePathFromBlacklistResponse.class); + // {\"code\":200502,\"msg\":\"Black list not exist\"} + if (rsp.isError(ExponError.BLACK_LIST_OPERATION_FAILED) && rsp.getMessage().contains("list not exist")) { + return; + } + + errorOut(rsp); + } + + public void removeVolumePathsFromBlacklist(List paths) { + if (paths.isEmpty()) { + return; + } + for (String p : paths) { + RemoveVolumePathFromBlacklistRequest req = new RemoveVolumePathFromBlacklistRequest(); + req.setPath(p); + + RemoveVolumePathFromBlacklistResponse rsp = call(req, RemoveVolumePathFromBlacklistResponse.class); + // {\"code\":200502,\"msg\":\"Black list not exist\"} + if (rsp.isError(ExponError.BLACK_LIST_OPERATION_FAILED) && rsp.getMessage().contains("list not exist")) { + return; + } + + errorOut(rsp); + } + } + + public List getFailureDomainBlacklist() { + GetFailureDomainBlacklistRequest req = new GetFailureDomainBlacklistRequest(); + GetFailureDomainBlacklistResponse rsp = callErrorOut(req, GetFailureDomainBlacklistResponse.class); + return rsp.getEntries(); + } + + public void clearFailureDomainBlacklist() { + ClearFailureDomainBlacklistRequest req = new ClearFailureDomainBlacklistRequest(); + callErrorOut(req, ClearFailureDomainBlacklistResponse.class); + } + + public void setTrashExpireTime(int days) { + SetTrashExpireTimeRequest req = new SetTrashExpireTimeRequest(); + req.setTrashRecycle(days); + callErrorOut(req, SetTrashExpireTimeResponse.class); + } + + public VolumeModule updateVolume(String volId, String name) { + UpdateVolumeRequest req = new UpdateVolumeRequest(); + req.setSessionId(sessionId); + req.setId(volId); + req.setName(name); + UpdateVolumeResponse rsp = callErrorOut(req, UpdateVolumeResponse.class); + + return getVolume(volId); + } + + public VolumeSnapshotModule updateVolumeSnapshot(String snapshotId, String name, String description) { + UpdateVolumeSnapshotRequest req = new UpdateVolumeSnapshotRequest(); + req.setSessionId(sessionId); + req.setDescription(description); + req.setId(snapshotId); + if (queryVolumeSnapshot(name) == null) { + req.setName(name); + } + UpdateVolumeSnapshotResponse rsp = callErrorOut(req, UpdateVolumeSnapshotResponse.class); + + return queryVolumeSnapshot(name); + } + + public VolumeLunModule getVolumeLunDetail(String volId) { + GetVolumeLunDetailRequest req = new GetVolumeLunDetailRequest(); + req.setSessionId(sessionId); + req.setVolId(volId); + GetVolumeLunDetailResponse rsp = callErrorOut(req, GetVolumeLunDetailResponse.class); + + return rsp.getLunDetails().get(0); + } + + @Override + public String getResourceUuid() { + return storageUuid != null ? storageUuid : + UUID.nameUUIDFromBytes(client.getConfig().hostname.getBytes()).toString().replace("-", ""); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponConfig.java b/plugin/expon/src/main/java/org/zstack/expon/ExponConfig.java new file mode 100644 index 00000000000..81d578c5924 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponConfig.java @@ -0,0 +1,47 @@ +package org.zstack.expon; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @example + * {"pools":[{"name":"pool", "aliasName":"test"}]} + */ +public class ExponConfig { + public static class Pool { + private String name; + private String aliasName; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAliasName() { + return aliasName; + } + + public void setAliasName(String aliasName) { + this.aliasName = aliasName; + } + } + + private List pools; + + public void setPools(List pools) { + this.pools = pools; + } + + public List getPools() { + return pools; + } + + public Set getPoolNames() { + return pools == null ? Collections.emptySet() : pools.stream().map(Pool::getName).collect(Collectors.toSet()); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponConstants.java b/plugin/expon/src/main/java/org/zstack/expon/ExponConstants.java new file mode 100644 index 00000000000..f299678033d --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponConstants.java @@ -0,0 +1,7 @@ +package org.zstack.expon; + +public interface ExponConstants { + String IDENTITY = "expon"; + + String EXPON_MANUFACTURER = "expon"; +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponIscsiHelper.java b/plugin/expon/src/main/java/org/zstack/expon/ExponIscsiHelper.java new file mode 100644 index 00000000000..71c3a304dad --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponIscsiHelper.java @@ -0,0 +1,38 @@ +package org.zstack.expon; + +public class ExponIscsiHelper { + + static String iscsiTargetPrefix = "iscsi_zstack_active"; + + static String iscsiTargetImagePrefix = "iscsi_zstack_image_active"; + + static String iscsiExportTargetName = "iscsi_zstack_export"; + + static String iscsiHeartbeatTargetName = "iscsi_zstack_heartbeat"; + + static String iscsiHeartbeatClientName = "iscsi_zstack_heartbeat"; + + static String iscsiHeartbeatVolumeName = "iscsi_zstack_heartbeat"; + + static String iscsiPrefix = "iscsi_zstack"; + + static String buildIscsiExportClientName(String clientIp) { + return "iscsi_" + clientIp.replace(".", "_"); + } + + public static String buildIscsiVolumeClientName(String volumeUuid) { + return "volume_" + volumeUuid; + } + + static String buildVolumeIscsiTargetName(int index) { + return String.format("%s_%d", iscsiTargetPrefix, index); + } + + static String buildImageIscsiTargetName(int index) { + return String.format("%s_%d", iscsiTargetImagePrefix, index); + } + + static int getIndexFromIscsiTargetName(String name) { + return Integer.parseInt(name.substring(name.lastIndexOf("_") + 1)); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponNameHelper.java b/plugin/expon/src/main/java/org/zstack/expon/ExponNameHelper.java new file mode 100644 index 00000000000..be88a2f2896 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponNameHelper.java @@ -0,0 +1,68 @@ +package org.zstack.expon; + +import org.zstack.expon.sdk.uss.UssGatewayModule; + +public class ExponNameHelper { + + public static String buildVhostControllerName(String zsVolumeUuid) { + return "volume-" + zsVolumeUuid; + } + + public static String buildVhostControllerPath(String zsVolumeUuid) { + return "/var/run/wds/volume-" + zsVolumeUuid; + } + + public static String getVolumeUuidFromVhostControllerPath(String path) { + return path.replace("/var/run/wds/volume-", ""); + } + + public static String buildUssGwName(String protocol, String managerIp) { + return protocol + "_" + managerIp.replace(".", "_"); + } + + public static String getUssManagerIp(String name) { + return name.split("_", 2)[1].replace("_", "."); + } + + public static String buildExponPath(String poolName, String volId) { + String base = volId.replace("-", ""); + return String.format("expon://%s/%s", poolName, base); + } + + public static String buildExponSnapshotPath(String volPath, String snapId) { + return volPath + "@" + snapId.replace("-", ""); + } + + public static String getPoolNameFromPath(String url) { + return url.replace("expon://", "").split("/")[0]; + } + + public static String getVolIdFromPath(String url) { + String volId = url.replace("expon://", "").split("/")[1].split("@")[0]; + return getExponId(volId); + } + + public static String getSnapIdFromPath(String url) { + String snapId = url.replace("expon://", "").split("/")[1].split("@")[1]; + return getExponId(snapId); + } + + public static String getExponId(String uuid) { + return uuid.substring(0, 8) + "-" + uuid.substring(8, 12) + "-" + uuid.substring(12, 16) + "-" + uuid.substring(16, 20) + "-" + uuid.substring(20); + } + + /** + * @see org.zstack.expon.sdk.pool.BlacklistModule + */ + public static String buildExponVolumeBoundPath(UssGatewayModule uss, String volumeName) { + return String.format("%s:%s/%s/VOLUME/%s", + uss.getBusinessNetwork().split("/")[0], + uss.getBusinessPort(), + uss.getUssId(), + volumeName); + } + + public static String getVolumeNameFromBoundPath(String path) { + return path.split("/")[3]; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponStorageController.java b/plugin/expon/src/main/java/org/zstack/expon/ExponStorageController.java new file mode 100644 index 00000000000..2a3762f98ff --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponStorageController.java @@ -0,0 +1,1356 @@ +package org.zstack.expon; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.expon.sdk.ExponClient; +import org.zstack.expon.sdk.ExponConnectConfig; +import org.zstack.expon.sdk.cluster.TianshuClusterModule; +import org.zstack.expon.sdk.iscsi.IscsiClientGroupModule; +import org.zstack.expon.sdk.iscsi.IscsiModule; +import org.zstack.expon.sdk.iscsi.IscsiSeverNode; +import org.zstack.expon.sdk.iscsi.IscsiUssResource; +import org.zstack.expon.sdk.nvmf.NvmfBoundUssGatewayRefModule; +import org.zstack.expon.sdk.nvmf.NvmfClientGroupModule; +import org.zstack.expon.sdk.nvmf.NvmfModule; +import org.zstack.expon.sdk.pool.FailureDomainModule; +import org.zstack.expon.sdk.uss.UssGatewayModule; +import org.zstack.expon.sdk.vhost.VhostControllerModule; +import org.zstack.expon.sdk.volume.ExponVolumeQos; +import org.zstack.expon.sdk.volume.VolumeLunModule; +import org.zstack.expon.sdk.volume.VolumeModule; +import org.zstack.expon.sdk.volume.VolumeSnapshotModule; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.expon.HealthStatus; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.image.ImageConstant; +import org.zstack.header.storage.addon.*; +import org.zstack.header.storage.addon.primary.*; +import org.zstack.header.storage.primary.ImageCacheInventory; +import org.zstack.header.storage.primary.VolumeSnapshotCapability; +import org.zstack.header.storage.snapshot.VolumeSnapshotStats; +import org.zstack.header.volume.*; +import org.zstack.header.volume.block.BlockVolumeVO; +import org.zstack.iscsi.IscsiUtils; +import org.zstack.iscsi.kvm.IscsiHeartbeatVolumeTO; +import org.zstack.iscsi.kvm.IscsiVolumeTO; +import org.zstack.kvm.KVMConstant; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.data.SizeUnit; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.path.PathUtil; +import org.zstack.vhost.kvm.VhostVolumeTO; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLDecoder; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; +import static org.zstack.expon.ExponIscsiHelper.*; +import static org.zstack.expon.ExponNameHelper.*; +import static org.zstack.iscsi.IscsiUtils.getHostMnIpFromInitiatorName; +import static org.zstack.storage.addon.primary.ExternalPrimaryStorageNameHelper.*; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class ExponStorageController implements PrimaryStorageControllerSvc, PrimaryStorageNodeSvc { + private static CLogger logger = Utils.getLogger(ExponStorageController.class); + + @Autowired + private DatabaseFacade dbf; + private ExternalPrimaryStorageVO self; + private ExponConfig config; + public ExponAddonInfo addonInfo; + public final ExponApiHelper apiHelper; + + // TODO static nqn + private final static String hostNqn = "nqn.2014-08.org.nvmexpress:uuid:zstack"; + private final static String vhostSocketDir = "/var/run/wds/"; + + private static final StorageCapabilities capabilities = new StorageCapabilities(); + + private final static long MIN_SIZE = 1024 * 1024 * 1024L; + + private final static long MAX_ISCSI_TARGET_LUN_COUNT = 64; + + static { + VolumeSnapshotCapability scap = new VolumeSnapshotCapability(); + scap.setSupport(true); + scap.setArrangementType(VolumeSnapshotCapability.VolumeSnapshotArrangementType.INDIVIDUAL); + scap.setPlacementType(VolumeSnapshotCapability.VolumeSnapshotPlacementType.INTERNAL); + scap.setSupportCreateOnHypervisor(false); + scap.setSupportLazyDelete(true); + scap.setVolumePathFromInternalSnapshotRegex("^[^@]+"); + capabilities.setSnapshotCapability(scap); + capabilities.setSupportCloneFromVolume(false); + capabilities.setSupportStorageQos(true); + capabilities.setSupportLiveExpandVolume(false); + capabilities.setSupportedImageFormats(Collections.singletonList(ImageConstant.RAW_FORMAT_STRING)); + capabilities.setSupportExportVolumeSnapshot(true); + } + + enum LunType { + Volume, + Snapshot + } + + public ExponStorageController(ExternalPrimaryStorageVO self) { + this(self.getUrl()); + this.self = self; + this.apiHelper.setStorageUuid(self.getUuid()); + this.reloadDbInfo(); + } + + public ExponStorageController(String url) { + URI uri = URI.create(url); + + ExponConnectConfig clientConfig = new ExponConnectConfig(); + clientConfig.hostname = uri.getHost(); + clientConfig.port = uri.getPort(); + clientConfig.readTimeout = TimeUnit.MINUTES.toMillis(10); + clientConfig.writeTimeout = TimeUnit.MINUTES.toMillis(10); + ExponClient client = new ExponClient(); + client.configure(clientConfig); + + AccountInfo accountInfo = new AccountInfo(); + accountInfo.username = uri.getUserInfo().split(":")[0]; + try { + accountInfo.password = URLDecoder.decode(uri.getUserInfo().split(":")[1], "utf-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + + apiHelper = new ExponApiHelper(accountInfo, client); + } + + private String protocolToString(VolumeProtocol protocol) { + if (protocol == VolumeProtocol.NVMEoF) { + return "nvmf"; + } else if (protocol == VolumeProtocol.Vhost) { + return "vhost"; + } else if (protocol == VolumeProtocol.iSCSI) { + return "iscsi"; + } else { + throw new RuntimeException("not supported protocol " + protocol); + } + } + + // TODO cache uss + private UssGatewayModule getUssGateway(VolumeProtocol protocol, String managerIp) { + UssGatewayModule uss = apiHelper.queryUssGateway(buildUssGwName(protocolToString(protocol), managerIp)); + if (uss == null) { + throw new RuntimeException(String.format("cannot find uss gateway for manager ip[%s] and protocol[%s]", managerIp, protocol)); + } + + return uss; + } + + private VhostControllerModule getOrCreateVhostController(String name) { + VhostControllerModule vhost = apiHelper.queryVhostController(name); + if (vhost == null) { + vhost = apiHelper.createVhostController(name); + } + + return vhost; + } + + @Override + public void activate(BaseVolumeInfo v, HostInventory h, boolean shareable, ReturnValueCompletion comp) { + ActiveVolumeTO to; + if (VolumeProtocol.Vhost.toString().equals(v.getProtocol())) { + to = activeVhostVolume(h, v); + comp.success(to); + return; + } else if (VolumeProtocol.iSCSI.toString().equals(v.getProtocol())) { + to = activeIscsiVolume(h, v, shareable); + comp.success(to); + return; + } + + comp.fail(operr("not supported protocol[%s]", v.getProtocol())); + } + + + private ActiveVolumeTO activeVhostVolume(HostInventory h, BaseVolumeInfo vol) { + String vhostName = buildVhostControllerName(vol.getUuid()); + + UssGatewayModule uss = getUssGateway(VolumeProtocol.Vhost, h.getManagementIp()); + VolumeModule exponVol = getVolumeModule(vol); + if (exponVol == null) { + throw new RuntimeException("volume not found"); + } + + VhostControllerModule vhost = getOrCreateVhostController(vhostName); + + List boundUss = apiHelper.getVhostControllerBoundUss(vhost.getId()); + if (boundUss.stream().noneMatch(it -> it.getId().equals(uss.getId()))) { + apiHelper.addVhostVolumeToUss(exponVol.getId(), vhost.getId(), uss.getId()); + } + + // TODO not remove every time + apiHelper.removeVolumePathFromBlacklist(buildExponVolumeBoundPath(uss, exponVol.getVolumeName()), exponVol.getId(), getSelfPools()); + + VhostVolumeTO to = new VhostVolumeTO(); + to.setInstallPath(vhost.getPath()); + return to; + } + + public List getIscsiServers(String tianshuId) { + List nodes = apiHelper.getIscsiTargetServer(tianshuId); + nodes.removeIf(it -> !it.getUssName().startsWith("iscsi_zstack")); + if (nodes.isEmpty()) { + throw new RuntimeException("no zstack iscsi uss server found, please create a iscsi uss with prefix iscsi_zstack"); + } + + List uss = apiHelper.listUssGateway(); + Map ussIdAndNetwork = uss.stream() + .filter(it -> !it.getStatus().equals(HealthStatus.error.name())) + .collect(Collectors.toMap(UssGatewayModule::getId, UssGatewayModule::getBusinessNetwork)); + nodes.removeIf(it -> !ussIdAndNetwork.containsKey(it.getUssGwId())); + + if (nodes.isEmpty()) { + throw new RuntimeException("no healthy uss server found"); + } + + // deduplicate same uss iscsi server. + return nodes.stream().collect(Collectors.groupingBy(IscsiSeverNode::getUssGwId)) + .entrySet().stream().map(it -> { + String businessIp = ussIdAndNetwork.get(it.getKey()).split("/")[0]; + List ns = it.getValue(); + // prefer business network + return ns.stream().filter(n -> n.getGatewayIp().equals(businessIp)).findFirst().orElse(ns.get(0)); + }).collect(Collectors.toList()); + } + + private synchronized ActiveVolumeTO activeIscsiVolume(HostInventory h, BaseVolumeInfo vol, boolean shareable) { + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (!KVMConstant.KVM_HYPERVISOR_TYPE.equals(h.getHypervisorType())) { + VolumeVO volume = dbf.findByUuid(vol.getUuid(), VolumeVO.class); + clientIqn = IscsiUtils.getBMInitiatorName(volume.getVmInstanceUuid()); + } + if (clientIqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + return activeIscsiVolume(clientIqn, vol, shareable); + } + + public synchronized ActiveVolumeTO activeIscsiVolume(String clientIqn, BaseVolumeInfo vol, boolean shareable) { + String lunId; + LunType lunType; + String source = vol.getInstallPath(); + String addedIscsiClientId; + if (source.contains("@")) { + lunId = getSnapIdFromPath(source); + lunType = LunType.Snapshot; + addedIscsiClientId = apiHelper.getSnapshotAttachedIscsiClientGroups(lunId).stream().findFirst().orElse(null); + } else { + lunId = getVolIdFromPath(source); + lunType = LunType.Volume; + addedIscsiClientId = apiHelper.getVolumeAttachedIscsiClientGroups(lunId).stream().findFirst().orElse(null); + } + + String tianshuId = addonInfo.getClusters().get(0).getId(); + List nodes = getIscsiServers(tianshuId); + + IscsiModule iscsi; + + if (addedIscsiClientId != null) { + IscsiClientGroupModule client = apiHelper.getIscsiClient(addedIscsiClientId); + if (!client.getHosts().contains(clientIqn)) { + apiHelper.addHostToIscsiClient(clientIqn, client.getId()); + } + iscsi = apiHelper.getIscsiClientAttachedTargets(addedIscsiClientId).get(0); + } else { + iscsi = "image".equals(vol.getType()) ? allocateImageIscsiTarget(nodes) : allocateIscsiTarget(nodes); + + // for active image, we use one iscsi client group for one iscsi target to save client group count + String iscsiClientName = "image".equals(vol.getType()) ? iscsi.getName() : buildIscsiVolumeClientName(vol.getUuid()); + IscsiClientGroupModule client = prepareOneToOneIscsiClientGroup(iscsiClientName, iscsi.getId(), tianshuId, clientIqn); + + if (lunType == LunType.Volume && !apiHelper.getVolumeAttachedIscsiClientGroups(lunId).contains(client.getId())) { + apiHelper.addVolumeToIscsiClientGroup(lunId, client.getId(), iscsi.getId(), shareable); + } else if (lunType == LunType.Snapshot && !apiHelper.getSnapshotAttachedIscsiClientGroups(lunId).contains(client.getId())) { + apiHelper.addSnapshotToIscsiClientGroup(lunId, client.getId(), iscsi.getId()); + } + } + + IscsiVolumeTO to = new IscsiVolumeTO(); + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(3260); + target.setTransport("tcp"); + target.setIqn(iscsi.getIqn()); + target.setIp(nodes.stream().map(IscsiSeverNode::getGatewayIp).collect(Collectors.joining(","))); + target.setDiskId(getDiskId(lunId, lunType)); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.wwn.toString()); + to.setInstallPath(target.getResourceURI()); + return to; + } + + private IscsiClientGroupModule prepareOneToOneIscsiClientGroup(String iscsiClientName, String iscsiTargetId, String tianshuId, String clientIqn) { + IscsiClientGroupModule client = apiHelper.queryIscsiClient(iscsiClientName); + if (client == null) { + client = apiHelper.createIscsiClient(iscsiClientName, tianshuId, Collections.singletonList(clientIqn)); + } else if (!client.getHosts().contains(clientIqn)) { + apiHelper.addHostToIscsiClient(clientIqn, client.getId()); + } + + // one iscsi client group can only attach one iscsi target + if (client.getiscsiGwCount() == 0) { + apiHelper.addIscsiClientToIscsiTarget(client.getId(), iscsiTargetId); + } + return client; + } + + private String getDiskId(String lunId, LunType lunType) { + if (lunType == LunType.Volume) { + VolumeModule vol = apiHelper.getVolume(lunId); + return vol.getWwn(); + } else { + VolumeSnapshotModule snap = apiHelper.getVolumeSnapshot(lunId); + return snap.getWwn(); + } + } + + private synchronized IscsiModule allocateIscsiTarget(List nodes) { + IscsiModule iscsi; + String tianshuId = addonInfo.getClusters().get(0).getId(); + if (addonInfo.getCurrentIscsiTargetId() == null) { + return createIscsiTarget(1, tianshuId, nodes); + } + + iscsi = apiHelper.getIscsiController(addonInfo.getCurrentIscsiTargetId()); + if (iscsi == null) { + int currentIscsiTargetIndex = addonInfo.getCurrentIscsiTargetIndex(); + return createIscsiTarget(currentIscsiTargetIndex + 1, tianshuId, nodes); + } + + if (iscsi.getLunCount() < MAX_ISCSI_TARGET_LUN_COUNT) { + return iscsi; + } + + int index = getIndexFromIscsiTargetName(iscsi.getName()); + return createIscsiTarget(index + 1, tianshuId, nodes); + } + + private IscsiModule createIscsiTarget(int index, String tianshuId, List nodes) { + IscsiModule iscsi = apiHelper.createIscsiController(buildVolumeIscsiTargetName(index), + tianshuId, 3260, IscsiUssResource.valueOf(nodes)); + addonInfo.setCurrentIscsiTargetId(iscsi.getId()); + addonInfo.setCurrentIscsiTargetIndex(index); + SQL.New(ExternalPrimaryStorageVO.class).eq(ExternalPrimaryStorageVO_.uuid, self.getUuid()) + .set(ExternalPrimaryStorageVO_.addonInfo, JSONObjectUtil.toJsonString(addonInfo)).update(); + return iscsi; + } + + private synchronized IscsiModule allocateImageIscsiTarget(List nodes) { + IscsiModule iscsi; + String tianshuId = addonInfo.getClusters().get(0).getId(); + if (addonInfo.getCurrentImageIscsiTargetId() == null) { + return createImageIscsiTarget(1, tianshuId, nodes); + } + + iscsi = apiHelper.getIscsiController(addonInfo.getCurrentImageIscsiTargetId()); + if (iscsi == null) { + int currentIscsiImageTargetIndex = addonInfo.getCurrentImageIscsiTargetIndex(); + return createImageIscsiTarget(currentIscsiImageTargetIndex + 1, tianshuId, nodes); + } + + if (iscsi.getLunCount() < MAX_ISCSI_TARGET_LUN_COUNT) { + return iscsi; + } + + int index = getIndexFromIscsiTargetName(iscsi.getName()); + return createImageIscsiTarget(index + 1, tianshuId, nodes); + } + + private IscsiModule createImageIscsiTarget(int index, String tianshuId, List nodes) { + IscsiModule iscsi = apiHelper.createIscsiController(buildImageIscsiTargetName(index), + tianshuId, 3260, IscsiUssResource.valueOf(nodes)); + addonInfo.setCurrentImageIscsiTargetId(iscsi.getId()); + addonInfo.setCurrentImageIscsiTargetIndex(index); + SQL.New(ExternalPrimaryStorageVO.class).eq(ExternalPrimaryStorageVO_.uuid, self.getUuid()) + .set(ExternalPrimaryStorageVO_.addonInfo, JSONObjectUtil.toJsonString(addonInfo)).update(); + return iscsi; + } + + synchronized IscsiRemoteTarget exportIscsi(ExportSpec espec) { + String lunId; + LunType lunType; + String source = espec.getInstallPath(); + if (source.contains("@")) { + lunId = getSnapIdFromPath(source); + lunType = LunType.Snapshot; + } else { + lunId = getVolIdFromPath(source); + lunType = LunType.Volume; + } + + String tianshuId = addonInfo.getClusters().get(0).getId(); + List nodes = getIscsiServers(tianshuId); + + IscsiModule iscsi = apiHelper.queryIscsiController(iscsiExportTargetName); + if (iscsi == null) { + iscsi = apiHelper.createIscsiController(iscsiExportTargetName, tianshuId, 3260, IscsiUssResource.valueOf(nodes)); + } + + String iscsiClientName = buildIscsiExportClientName(espec.getClientMnIp()); + IscsiClientGroupModule client = prepareOneToOneIscsiClientGroup(iscsiClientName, iscsi.getId(), tianshuId, espec.getClientQualifiedName()); + + if (lunType == LunType.Volume) { + apiHelper.addVolumeToIscsiClientGroup(lunId, client.getId(), iscsi.getId(), false); + } else { + apiHelper.addSnapshotToIscsiClientGroup(lunId, client.getId(), iscsi.getId()); + } + + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(3260); + target.setTransport("tcp"); + target.setIqn(iscsi.getIqn()); + target.setIp(nodes.stream().map(IscsiSeverNode::getGatewayIp).collect(Collectors.joining(","))); + target.setDiskId(getDiskId(lunId, lunType)); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.wwn.toString()); + + return target; + } + + @Override + public String getActivePath(BaseVolumeInfo v, HostInventory h, boolean shareable) { + if (VolumeProtocol.Vhost.toString().equals(v.getProtocol())) { + String vhostName = buildVhostControllerName(v.getUuid()); + VhostControllerModule vhost = getOrCreateVhostController(vhostName); + return vhost.getPath(); + } else if (VolumeProtocol.iSCSI.toString().equals(v.getProtocol())) { + String lunId; + LunType lunType; + List clientIds; + if (v.getInstallPath().contains("@")) { + lunId = getSnapIdFromPath(v.getInstallPath()); + lunType = LunType.Snapshot; + clientIds = apiHelper.getSnapshotAttachedIscsiClientGroups(lunId); + } else { + lunId = getVolIdFromPath(v.getInstallPath()); + lunType = LunType.Volume; + clientIds = apiHelper.getVolumeAttachedIscsiClientGroups(lunId); + } + + if (clientIds.isEmpty()) { + return null; + } + + IscsiModule iscsi = apiHelper.getIscsiClientAttachedTargets(clientIds.get(0)).get(0); + List nodes = getIscsiServers(addonInfo.getClusters().get(0).getId()); + + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(3260); + target.setTransport("tcp"); + target.setIqn(iscsi.getIqn()); + target.setIp(nodes.stream().map(IscsiSeverNode::getGatewayIp).collect(Collectors.joining(","))); + target.setDiskId((getDiskId(lunId, lunType))); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.wwn.toString()); + return target.getResourceURI(); + } + + throw new OperationFailureException(operr("not supported protocol[%s]", v.getProtocol())); + } + + @Override + public BaseVolumeInfo getActiveVolumeInfo(String activePath, HostInventory h, boolean shareable) { + BaseVolumeInfo info = new BaseVolumeInfo(); + String volUuid = null; + if (activePath.startsWith(vhostSocketDir)) { + volUuid = getVolumeUuidFromVhostControllerPath(activePath); + info.setUuid(volUuid); + info.setProtocol(VolumeProtocol.Vhost.toString()); + info.setShareable(shareable); + } else { + // TODO support other protocols + } + + + VolumeModule vol = apiHelper.queryVolume(buildVolumeName(volUuid)); + if (vol == null) { + return info; + } + + info.setInstallPath(buildExponPath(vol.getPoolName(), vol.getId())); + return info; + } + + @Override + public List getActiveVolumesLocation(HostInventory h) { + // TODO support other protocols + return Collections.singletonList("file://" + PathUtil.join(vhostSocketDir, "volume-*")); + } + + @Override + public void deployClient(HostInventory h, Completion comp) { + comp.success(); + } + + @Override + public List getActiveClients(String installPath, String protocol) { + if (VolumeProtocol.Vhost.toString().equals(protocol)) { + VolumeModule vol = apiHelper.getVolumeOrElseNull(getVolIdFromPath(installPath)); + if (vol == null) { + return Collections.emptyList(); + } + + String volUuid = getVolumeInfo(vol.getName()).getUuid(); + String vhostName = buildVhostControllerName(volUuid); + VhostControllerModule vhost = apiHelper.queryVhostController(vhostName); + if (vhost == null) { + return Collections.emptyList(); + } + + List uss = apiHelper.getVhostControllerBoundUss(vhost.getId()); + return uss.stream().map(it -> { + ActiveVolumeClient client = new ActiveVolumeClient(); + client.setManagerIp(getUssManagerIp(it.getName())); + return client; + }).collect(Collectors.toList()); + } else if (VolumeProtocol.iSCSI.toString().equals(protocol)) { + IscsiClientGroupModule client = getLunAttachedIscsiClient(installPath); + if (client == null) { + return Collections.emptyList(); + } + + return client.getHosts().stream().map(it -> { + ActiveVolumeClient c = new ActiveVolumeClient(); + if (it.contains("iqn")) { + c.setQualifiedName(it); + c.setManagerIp(getHostMnIpFromInitiatorName(it)); + } else { + c.setManagerIp(it); + } + VolumeLunModule lunDetail = apiHelper.getVolumeLunDetail(getVolIdFromPath(installPath)); + // path: uuid/poolId/lunid + c.setPath(String.format("%s/%s/%s", lunDetail.getUuid(), lunDetail.getPoolId(), lunDetail.getLunId())); + return c; + }).collect(Collectors.toList()); + } else { + throw new OperationFailureException(operr("not supported protocol[%s] for active", protocol)); + } + } + + private IscsiClientGroupModule getLunAttachedIscsiClient(String installPath) { + List clientIds; + if (installPath.contains("@")) { + String lunId = getSnapIdFromPath(installPath); + clientIds = apiHelper.getSnapshotAttachedIscsiClientGroups(lunId); + } else { + String lunId = getVolIdFromPath(installPath); + clientIds = apiHelper.getVolumeAttachedIscsiClientGroups(lunId); + } + + if (clientIds.isEmpty()) { + return null; + } + + // one lun can only attach to one client group + return apiHelper.getIscsiClient(clientIds.get(0)); + } + + @Override + public void deactivate(String installPath, String protocol, HostInventory h, Completion comp) { + logger.debug(String.format("deactivating volume[path: %s, protocol:%s] on host[uuid:%s, ip:%s]", + installPath, protocol, h.getUuid(), h.getManagementIp())); + if (VolumeProtocol.Vhost.toString().equals(protocol)) { + deactivateVhost(installPath, h); + comp.success(); + return; + } else if (VolumeProtocol.iSCSI.toString().equals(protocol)) { + // iscsi target is shared by all hosts, we cannot control one volume on one host for now. + deactivateIscsi(installPath, h); + comp.success(); + return; + } + + comp.fail(operr("not supported protocol[%s] for deactivate", protocol)); + } + + @Override + public void deactivate(String installPath, String protocol, ActiveVolumeClient client, Completion comp) { + if (VolumeProtocol.iSCSI.toString().equals(protocol)) { + deactivateIscsi(installPath, client.getQualifiedName()); + comp.success(); + return; + } + HostVO host = Q.New(HostVO.class).eq(HostVO_.managementIp, client.getManagerIp()).find(); + deactivate(installPath, protocol, HostInventory.valueOf(host), comp); + } + + public void cleanActiveRecord(VolumeInventory vol) { + if (vol.getProtocol().equals(VolumeProtocol.Vhost.toString())) { + String vhostName = buildVhostControllerName(vol.getUuid()); + VhostControllerModule vhost = apiHelper.queryVhostController(vhostName); + if (vhost != null) { + apiHelper.deleteVhostController(vhost.getId()); + } + } else if (vol.getProtocol().equals(VolumeProtocol.iSCSI.toString())) { + String iscsiClientName = buildIscsiVolumeClientName(vol.getUuid()); + IscsiClientGroupModule client = apiHelper.queryIscsiClient(iscsiClientName); + if (client != null) { + apiHelper.deleteIscsiClient(client.getId()); + } + } + } + + public void cleanActiveRecord(ImageCacheInventory cache) { + // TODO + } + + @Override + public void blacklist(String installPath, String protocol, HostInventory h, Completion comp) { + logger.debug(String.format("blacklisting volume[path: %s, protocol:%s] on host[uuid:%s, ip:%s]", + installPath, protocol, h.getUuid(), h.getManagementIp())); + + UssGatewayModule uss = getUssGateway(VolumeProtocol.valueOf(protocol), h.getManagementIp()); + VolumeModule exponVol = apiHelper.getVolume(getVolIdFromPath(installPath)); + apiHelper.addVolumePathToBlacklist(buildExponVolumeBoundPath(uss, exponVol.getVolumeName())); + comp.success(); + } + + @Override + public synchronized void activateHeartbeatVolume(HostInventory h, ReturnValueCompletion comp) { + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (clientIqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + + String tianshuId = addonInfo.getClusters().get(0).getId(); + List nodes = getIscsiServers(tianshuId); + + IscsiModule iscsi = apiHelper.queryIscsiController(iscsiHeartbeatTargetName); + if (iscsi == null) { + iscsi = apiHelper.createIscsiController(iscsiHeartbeatTargetName, tianshuId, 3260, IscsiUssResource.valueOf(nodes)); + } + + VolumeModule heartbeatVol = apiHelper.queryVolume(iscsiHeartbeatVolumeName); + if (heartbeatVol == null) { + long size = SizeUnit.GIGABYTE.toByte(2); + heartbeatVol = apiHelper.createVolume(iscsiHeartbeatVolumeName, allocateFreePool(size).getId(), size); + } + + IscsiClientGroupModule client = prepareOneToOneIscsiClientGroup(iscsiHeartbeatClientName, iscsi.getId(), tianshuId, clientIqn); + if (client.getVolNum() == 0) { + apiHelper.addVolumeToIscsiClientGroup(heartbeatVol.getId(), client.getId(), iscsi.getId(), false); + } + + IscsiHeartbeatVolumeTO to = new IscsiHeartbeatVolumeTO(); + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(3260); + target.setTransport("tcp"); + target.setIqn(iscsi.getIqn()); + target.setIp(nodes.stream().map(IscsiSeverNode::getGatewayIp).collect(Collectors.joining(","))); + target.setDiskId(heartbeatVol.getWwn()); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.wwn.toString()); + to.setInstallPath(target.getResourceURI()); + to.setHostId(getHostId(h)); + to.setHeartbeatRequiredSpace(SizeUnit.MEGABYTE.toByte(1)); + to.setCoveringPaths(Collections.singletonList(vhostSocketDir)); + comp.success(to); + } + + // hardcode + private int getHostId(HostInventory host) { + UssGatewayModule uss = getUssGateway(VolumeProtocol.Vhost, host.getManagementIp()); + return uss.getServerNo(); + } + + @Override + public void deactivateHeartbeatVolume(HostInventory h, Completion comp) { + VolumeModule heartbeatVol = apiHelper.queryVolume(iscsiHeartbeatVolumeName); + if (heartbeatVol == null) { + comp.success(); + return; + } + + IscsiModule iscsi = apiHelper.queryIscsiController(iscsiHeartbeatTargetName); + if (iscsi == null) { + comp.success(); + return; + } + + IscsiClientGroupModule client = apiHelper.queryIscsiClient(iscsiHeartbeatClientName); + if (client == null) { + comp.success(); + return; + } + + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (clientIqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + + if (client.getHosts().contains(clientIqn)) { + apiHelper.removeHostFromIscsiClient(clientIqn, client.getId()); + } + + comp.success(); + } + + @Override + public HeartbeatVolumeTO getHeartbeatVolumeActiveInfo(HostInventory h) { + String tianshuId = addonInfo.getClusters().get(0).getId(); + List nodes = getIscsiServers(tianshuId); + + IscsiModule iscsi = apiHelper.queryIscsiController(iscsiHeartbeatTargetName); + if (iscsi == null) { + throw new RuntimeException("heartbeat iscsi target not found"); + } + + VolumeModule heartbeatVol = apiHelper.queryVolume(iscsiHeartbeatVolumeName); + if (heartbeatVol == null) { + throw new RuntimeException("heartbeat volume not found"); + } + + IscsiHeartbeatVolumeTO to = new IscsiHeartbeatVolumeTO(); + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(3260); + target.setTransport("tcp"); + target.setIqn(iscsi.getIqn()); + target.setIp(nodes.stream().map(IscsiSeverNode::getGatewayIp).collect(Collectors.joining(","))); + target.setDiskId(heartbeatVol.getWwn()); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.wwn.toString()); + to.setInstallPath(target.getResourceURI()); + to.setHostId(getHostId(h)); + to.setHeartbeatRequiredSpace(SizeUnit.MEGABYTE.toByte(1)); + to.setCoveringPaths(Collections.singletonList(vhostSocketDir)); + return to; + } + + private void deactivateVhost(String installPath, HostInventory h) { + String volId = getVolIdFromPath(installPath); + VolumeModule vol = apiHelper.getVolumeOrElseNull(volId); + if (vol == null) { + return; + } + + String volUuid = getVolumeInfo(vol.getName()).getUuid(); + String vhostName = buildVhostControllerName(volUuid); + + UssGatewayModule uss = getUssGateway(VolumeProtocol.Vhost, h.getManagementIp()); + VhostControllerModule vhost = apiHelper.queryVhostController(vhostName); + if (vhost == null) { + return; + } + + retry(() -> apiHelper.removeVhostVolumeFromUss(volId, vhost.getId(), uss.getId())); + + apiHelper.removeVolumePathFromBlacklist(buildExponVolumeBoundPath(uss, vol.getVolumeName()), volId, getSelfPools()); +} + + private void deactivateIscsi(String installPath, HostInventory h) { + String iqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (!KVMConstant.KVM_HYPERVISOR_TYPE.equals(h.getHypervisorType())) { + VolumeVO volume = Q.New(VolumeVO.class).eq(VolumeVO_.installPath, installPath).find(); + iqn = IscsiUtils.getBMInitiatorName(volume.getLastVmInstanceUuid()); + } + if (iqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + deactivateIscsi(installPath, iqn); + } + + public void deactivateIscsi(String installPath, String iqn) { + IscsiClientGroupModule client = getLunAttachedIscsiClient(installPath); + if (client == null) { + return; + } + + int lunCount = client.getSnapNum() + client.getVolNum(); + if (lunCount > 1) { + logger.debug(String.format("%s attached sharable iscsi client group[lun count: %d], skip deactivate", installPath, lunCount)); + return; + } + + if (!client.getHosts().contains(iqn)) { + return; + } + + if (client.getHosts().size() == 1) { + apiHelper.deleteIscsiClient(client.getId()); + return; + } + + retry(() -> apiHelper.removeHostFromIscsiClient(iqn, client.getId())); + } + + private synchronized void unexportIscsi(String source, String clientIp) { + String lunId; + LunType lunType; + if (source.contains("@")) { + lunId = getSnapIdFromPath(source); + lunType = LunType.Snapshot; + } else { + lunId = getVolIdFromPath(source); + lunType = LunType.Volume; + } + + String iscsiClientName = buildIscsiExportClientName(clientIp); + IscsiClientGroupModule client = apiHelper.queryIscsiClient(iscsiClientName); + if (client == null) { + return; + } + + if (lunType == LunType.Volume) { + apiHelper.removeVolumeFromIscsiClientGroup(lunId, client.getId()); + } else { + apiHelper.removeSnapshotFromIscsiClientGroup(lunId, client.getId()); + } + + /* + apiHelper.removeIscsiClientFromIscsiTarget(client.getId(), iscsi.getId()); + apiHelper.unbindIscsiTargetToUss(iscsi.getId(), uss.getId()); + apiHelper.deleteIscsiController(iscsi.getId()); + apiHelper.deleteIscsiClient(client.getId()); + */ + } + + private VolumeModule getVolumeModule(BaseVolumeInfo vol) { + if (vol.getInstallPath() != null) { + String volId = getVolIdFromPath(vol.getInstallPath()); + return apiHelper.getVolume(volId); + } + + if ("image".equals(vol.getType())) { + return apiHelper.queryVolume(buildImageName(vol.getUuid())); + } else { + return apiHelper.queryVolume(buildVolumeName(vol.getUuid())); + } + } + + @Override + public String getIdentity() { + return ExponConstants.IDENTITY; + } + + @Override + public void connect(String config, String url, ReturnValueCompletion comp) { + apiHelper.login(); + ExponAddonInfo info = new ExponAddonInfo(); + + List pools = apiHelper.queryPools(); + if (CollectionUtils.isEmpty(pools)) { + comp.fail(operr("no pool found")); + return; + } + + pools = pools.stream().map(it -> apiHelper.getPool(it.getId())).collect(Collectors.toList()); + info.setPools(pools.stream().map(ExponAddonInfo.Pool::valueOf).collect(Collectors.toList())); + List clusters = apiHelper.queryClusters(); + info.setClusters(clusters.stream().map(ExponAddonInfo.TianshuCluster::valueOf).collect(Collectors.toList())); + + List iscsiTargets = apiHelper.listIscsiController(); + iscsiTargets.removeIf(it -> !it.getName().startsWith(iscsiTargetPrefix) && !it.getName().startsWith(iscsiTargetImagePrefix)); + if (!iscsiTargets.isEmpty()) { + iscsiTargets.stream().filter(it -> it.getName().startsWith(iscsiTargetPrefix)) + .max(Comparator.comparingInt(o -> Integer.parseInt(o.getName().substring(o.getName().lastIndexOf("_") + 1)))).ifPresent(i -> { + info.setCurrentIscsiTargetId(i.getId()); + info.setCurrentIscsiTargetIndex(Integer.parseInt(i.getName().substring(i.getName().lastIndexOf("_") + 1))); + }); + + iscsiTargets.stream().filter(it -> it.getName().startsWith(iscsiTargetImagePrefix)) + .max(Comparator.comparingInt(o -> Integer.parseInt(o.getName().substring(o.getName().lastIndexOf("_") + 1)))).ifPresent(i -> { + info.setCurrentImageIscsiTargetId(i.getId()); + info.setCurrentImageIscsiTargetIndex(Integer.parseInt(i.getName().substring(i.getName().lastIndexOf("_") + 1))); + }); + } + addonInfo = info; + comp.success(JSONObjectUtil.rehashObject(addonInfo, LinkedHashMap.class)); + } + + @Override + public void ping(Completion completion) { + completion.success(); + } + + private void reloadDbInfo() { + self = dbf.reload(self); + addonInfo = StringUtils.isEmpty(self.getAddonInfo()) ? new ExponAddonInfo() : JSONObjectUtil.toObject(self.getAddonInfo(), ExponAddonInfo.class); + config = StringUtils.isEmpty(self.getConfig()) ? new ExponConfig() : JSONObjectUtil.toObject(self.getConfig(), ExponConfig.class); + } + + @Override + public void reportCapacity(ReturnValueCompletion comp) { + reloadDbInfo(); + + List pools = getSelfPools(); + long total = pools.stream().mapToLong(FailureDomainModule::getValidSize).sum(); + long avail = total - pools.stream().mapToLong(FailureDomainModule::getRealDataSize).sum(); + StorageCapacity cap = new StorageCapacity(); + cap.setHealthy(getHealthy(pools)); + cap.setAvailableCapacity(avail); + cap.setTotalCapacity(total); + comp.success(cap); + } + + private StorageHealthy getHealthy(List pools) { + if (pools.stream().allMatch(it -> it.getHealthStatus().equals(HealthStatus.health.name()))) { + return StorageHealthy.Ok; + } else if (pools.stream().allMatch(it -> it.getHealthStatus().equals(HealthStatus.error.name()))) { + return StorageHealthy.Failed; + } else { + return StorageHealthy.Warn; + } + } + + @Override + public void reportHealthy(ReturnValueCompletion comp) { + self = dbf.reload(self); + addonInfo = JSONObjectUtil.toObject(self.getAddonInfo(), ExponAddonInfo.class); + config = JSONObjectUtil.toObject(self.getConfig(), ExponConfig.class); + + List pools = getSelfPools(); + comp.success(getHealthy(pools)); + } + + @Override + public void reportNodeHealthy(HostInventory host, ReturnValueCompletion comp) { + String hostProtocol = getProtocolByHypervisorType(host.getHypervisorType()); + NodeHealthy healthy = new NodeHealthy(); + if (VolumeProtocol.Vhost.toString().equals(hostProtocol)) { + setNodeHealthyByVhost(host, healthy); + } + + if (VolumeProtocol.iSCSI.toString().equals(hostProtocol)) { + setNodeHealthyByIscsi(host, healthy); + } + comp.success(healthy); + } + + private void setNodeHealthyByIscsi(HostInventory host, NodeHealthy healthy) { + // for iscsi protocol , just judge exist or not + VolumeProtocol protocol = VolumeProtocol.iSCSI; + String tianshuId = addonInfo.getClusters().get(0).getId(); + List nodes = apiHelper.getIscsiTargetServer(tianshuId); + if (nodes.stream().anyMatch(it -> it.getUssName().startsWith(iscsiPrefix) + && it.getManagerIp().equals(host.getManagementIp()))) { + healthy.setHealthy(protocol, StorageHealthy.Ok); + } else { + healthy.setHealthy(protocol, StorageHealthy.Unknown); + } + } + + private void setNodeHealthyByVhost(HostInventory host, NodeHealthy healthy) { + VolumeProtocol protocol = VolumeProtocol.Vhost; + String ussName = buildUssGwName(protocolToString(protocol), host.getManagementIp()); + UssGatewayModule uss = apiHelper.queryUssGateway(ussName); + if (uss == null) { + healthy.setHealthy(protocol, StorageHealthy.Failed); + } else if (uss.getStatus().equals(HealthStatus.health.name())) { + healthy.setHealthy(protocol, StorageHealthy.Ok); + } else if (uss.getStatus().equals(HealthStatus.error.name())) { + healthy.setHealthy(protocol, StorageHealthy.Failed); + } else if (uss.getStatus().equals(HealthStatus.warning.name())){ + healthy.setHealthy(protocol, StorageHealthy.Warn); + } else { + healthy.setHealthy(protocol, StorageHealthy.Unknown); + } + } + + private String getProtocolByHypervisorType(String type) { + if (!KVMConstant.KVM_HYPERVISOR_TYPE.equals(type)) { + return VolumeProtocol.iSCSI.toString(); + } + + return VolumeProtocol.Vhost.toString(); + } + + private List getSelfPools() { + Set configPoolNames = config.getPoolNames(); + Set poolIds = addonInfo.getPools().stream().filter(it -> configPoolNames.contains(it.getName())) + .map(ExponAddonInfo.Pool::getId).collect(Collectors.toSet()); + + List pools = apiHelper.queryPools(); + pools.removeIf(it -> !poolIds.contains(it.getId())); + pools = pools.stream().map(it -> apiHelper.getPool(it.getId())).collect(Collectors.toList()); + return pools; + } + + private String getPoolId(String name) { + return addonInfo.getPools().stream().filter(it -> it.getName().equals(name)).findFirst() + .orElseThrow(() -> new RuntimeException(String.format("cannot find pool[name:%s]", name))).getId(); + } + + @Override + public StorageCapabilities reportCapabilities() { + return capabilities; + } + + @Override + public String allocateSpace(AllocateSpaceSpec aspec) { + // TODO allocate pool + FailureDomainModule pool = allocateFreePool(aspec.getSize()); + if (pool == null) { + throw new OperationFailureException(operr("no available pool with enough space[%d] and healthy status", aspec.getSize())); + } + + return buildExponPath(pool.getFailureDomainName(), ""); + } + + private FailureDomainModule allocateFreePool(long size) { + List pools = getSelfPools(); + return pools.stream().filter(it -> !it.getHealthStatus().equals(HealthStatus.error.name()) && + it.getValidSize() - it.getRealDataSize() > size) + .max(Comparator.comparingLong(FailureDomainModule::getAvailableCapacity)) + .orElse(null); + } + + @Override + public void createVolume(CreateVolumeSpec v, ReturnValueCompletion comp) { + String poolName; + v.setSize(Math.max(v.getSize(), MIN_SIZE)); + + if (v.getAllocatedUrl() == null) { + FailureDomainModule pool = allocateFreePool(v.getSize()); + if (pool == null) { + comp.fail(operr("no available pool with enough space[%d] and healthy status", v.getSize())); + return; + } + poolName = pool.getFailureDomainName(); + } else { + poolName = getPoolNameFromPath(v.getAllocatedUrl()); + } + + String poolId = getPoolId(poolName); + + VolumeModule exponVol = apiHelper.createVolume(v.getName(), poolId, v.getSize()); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildExponPath(poolName, exponVol.getId())); + stats.setSize(exponVol.getVolumeSize()); + stats.setActualSize(exponVol.getDataSize()); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + stats.setRunStatus(exponVol.getRunStatus()); + comp.success(stats); + } + + @Override + public void deleteVolume(String installPath, Completion comp) { + String volId = getVolIdFromPath(installPath); + apiHelper.deleteVolume(volId, true); + comp.success(); + } + + @Override + public void deleteVolumeAndSnapshot(String installPath, Completion comp) { + String volId = getVolIdFromPath(installPath); + apiHelper.deleteVolumeAndSnapshots(volId, true); + comp.success(); + } + + @Override + public void trashVolume(String installPath, Completion comp) { + String volId = getVolIdFromPath(installPath); + apiHelper.deleteVolume(volId, false); + comp.success(); + } + + @Override + public void cloneVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletion comp) { + String snapId = getSnapIdFromPath(srcInstallPath); + VolumeModule vol = apiHelper.cloneVolume(snapId, dst.getName(), ExponVolumeQos.valueOf(dst.getQos())); + if (vol.getVolumeSize() < dst.getSize()) { + vol = apiHelper.expandVolume(vol.getId(), dst.getSize()); + } + + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildExponPath(getPoolNameFromPath(srcInstallPath), vol.getId())); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + stats.setSize(vol.getVolumeSize()); + stats.setActualSize(vol.getDataSize()); + stats.setParentUri(srcInstallPath); + comp.success(stats); + } + + @Override + public void copyVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletion comp) { + String snapId = getSnapIdFromPath(srcInstallPath); + VolumeSnapshotModule snap = apiHelper.getVolumeSnapshot(snapId); + + apiHelper.copySnapshot(snapId, snap.getPoolId(), dst.getName(), ExponVolumeQos.valueOf(dst.getQos()), new ReturnValueCompletion(comp) { + @Override + public void success(VolumeModule vol) { + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildExponPath(getPoolNameFromPath(srcInstallPath), vol.getId())); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + stats.setSize(vol.getVolumeSize()); + stats.setActualSize(vol.getDataSize()); + comp.success(stats); + } + + @Override + public void fail(ErrorCode errorCode) { + comp.fail(errorCode); + } + }); + } + + @Override + public void flattenVolume(String installPath, ReturnValueCompletion comp) { + // TODO flatten snapshot + stats(installPath, comp); + } + + @Override + public void stats(String installPath, ReturnValueCompletion comp) { + VolumeModule vol = apiHelper.getVolume(getVolIdFromPath(installPath)); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(installPath); + stats.setSize(vol.getVolumeSize()); + stats.setActualSize(vol.getDataSize()); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + comp.success(stats); + } + + @Override + public void batchStats(Collection installPath, ReturnValueCompletion> comp) { + List stats = installPath.stream().map(it -> { + VolumeModule vol = apiHelper.getVolume(getVolIdFromPath(it)); + VolumeStats s = new VolumeStats(); + s.setInstallPath(it); + s.setSize(vol.getVolumeSize()); + s.setActualSize(vol.getDataSize()); + s.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + return s; + }).collect(Collectors.toList()); + comp.success(stats); + } + + @Override + public void expandVolume(String installPath, long size, ReturnValueCompletion comp) { + VolumeModule vol = apiHelper.expandVolume(getVolIdFromPath(installPath), size); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(installPath); + stats.setSize(vol.getVolumeSize()); + comp.success(stats); + } + + @Override + public void setVolumeQos(BaseVolumeInfo v, Completion comp) { + apiHelper.setVolumeQos(getVolIdFromPath(v.getInstallPath()), ExponVolumeQos.valueOf(v.getQos())); + comp.success(); + } + + @Override + public void deleteVolumeQos(BaseVolumeInfo v, Completion comp) { + apiHelper.deleteVolumeQos(getVolIdFromPath(v.getInstallPath())); + comp.success(); + } + + @Override + public void export(ExportSpec espec, VolumeProtocol protocol, ReturnValueCompletion comp) { + if (protocol == VolumeProtocol.NVMEoF) { + NvmeRemoteTarget target = exportNvmf(espec); + comp.success(target); + } else if (protocol == VolumeProtocol.iSCSI) { + IscsiRemoteTarget target = exportIscsi(espec); + comp.success(target); + } else { + throw new RuntimeException("unsupport target " + protocol.name()); + } + } + + synchronized NvmeRemoteTarget exportNvmf(ExportSpec espec) { + String lunId; + LunType lunType; + String source = espec.getInstallPath(); + if (source.contains("@")) { + lunId = getSnapIdFromPath(source); + lunType = LunType.Snapshot; + } else { + lunId = getVolIdFromPath(source); + lunType = LunType.Volume; + } + + String tianshuId = addonInfo.getClusters().get(0).getId(); + UssGatewayModule uss = getUssGateway(VolumeProtocol.NVMEoF, "zstack"); + + String nvmfControllerName = "nvmf_zstack"; + NvmfModule nvmf = apiHelper.queryNvmfController(nvmfControllerName); + if (nvmf == null) { + nvmf = apiHelper.createNvmfController(nvmfControllerName, tianshuId, lunId); + } + + NvmfBoundUssGatewayRefModule ref = apiHelper.getNvmfBoundUssGateway(nvmf.getId(), uss.getId()); + if (ref == null) { + ref = apiHelper.bindNvmfTargetToUss(nvmf.getId(), uss.getId(), 4420); + } + + String nvmfClientName = "nvmf_zstack"; + NvmfClientGroupModule client = apiHelper.queryNvmfClient(nvmfClientName); + if (client == null) { + client = apiHelper.createNvmfClient(nvmfClientName, tianshuId, Collections.singletonList(hostNqn)); + apiHelper.addNvmfClientToNvmfTarget(client.getId(), nvmf.getId()); + } + + if (lunType == LunType.Volume) { + apiHelper.addVolumeToNvmfClientGroup(lunId, client.getId(), nvmf.getId()); + } else { + apiHelper.addSnapshotToNvmfClientGroup(lunId, client.getId(), nvmf.getId()); + } + + NvmeRemoteTarget target = new NvmeRemoteTarget(); + target.setHostNqn(hostNqn); + target.setPort(4420); + target.setTransport("tcp"); + target.setNqn(nvmf.getNqn()); + target.setIp(ref.getBindIp()); + target.setDiskId(lunId); + return target; + } + + @Override + public void unexport(ExportSpec espec, RemoteTarget remoteTarget, VolumeProtocol protocol, Completion comp) { + if (protocol == VolumeProtocol.NVMEoF) { + unexportNvmf(espec.getInstallPath()); + } else if (protocol == VolumeProtocol.iSCSI) { + unexportIscsi(espec.getInstallPath(), espec.getClientMnIp()); + } else { + comp.fail(operr("unsupported protocol %s", protocol.name())); + return; + } + comp.success(); + } + + private synchronized void unexportNvmf(String source) { + String lunId; + LunType lunType; + if (source.contains("@")) { + lunId = getSnapIdFromPath(source); + lunType = LunType.Snapshot; + } else { + lunId = getVolIdFromPath(source); + lunType = LunType.Volume; + } + + // UssGatewayModule uss = getUssGateway(VolumeProtocol.NVMEoF, "zstack"); + + String nvmfControllerName = "nvmf_zstack"; + NvmfModule nvmf = apiHelper.queryNvmfController(nvmfControllerName); + + String nvmfClientName = "nvmf_zstack"; + NvmfClientGroupModule client = apiHelper.queryNvmfClient(nvmfClientName); + if (nvmf == null || client == null) { + return; + } + + if (lunType == LunType.Volume) { + apiHelper.removeVolumeFromNvmfClientGroup(lunId, client.getId()); + } else { + apiHelper.removeSnapshotFromNvmfClientGroup(lunId, client.getId()); + } + + /* + apiHelper.removeNvmfClientFromNvmfTarget(client.getId(), nvmf.getId()); + apiHelper.unbindNvmfTargetToUss(nvmf.getId(), uss.getId()); + apiHelper.deleteNvmfController(nvmf.getId()); + apiHelper.deleteNvmfClient(client.getId()); + */ + } + + @Override + public void createSnapshot(CreateVolumeSnapshotSpec spec, ReturnValueCompletion comp) { + VolumeSnapshotModule snapshot = apiHelper.createVolumeSnapshot( + getVolIdFromPath(spec.getVolumeInstallPath()), spec.getName(), "todo"); + VolumeSnapshotStats stats = new VolumeSnapshotStats(); + stats.setInstallPath(buildExponSnapshotPath(spec.getVolumeInstallPath(), snapshot.getId())); + stats.setActualSize(snapshot.getDataSize()); + comp.success(stats); + } + + @Override + public void deleteSnapshot(String installPath, Completion comp) { + apiHelper.deleteVolumeSnapshot(getSnapIdFromPath(installPath), false); + comp.success(); + } + + @Override + public void expungeSnapshot(String installPath, Completion comp) { + apiHelper.deleteVolumeSnapshot(getSnapIdFromPath(installPath), true); + comp.success(); + } + + @Override + public void revertVolumeSnapshot(String snapshotInstallPath, ReturnValueCompletion comp) { + String volId = getVolIdFromPath(snapshotInstallPath); + String snapId = getSnapIdFromPath(snapshotInstallPath); + String poolName = getPoolNameFromPath(snapshotInstallPath); + // hardcode: clean blacklist before recovery snapshot + List paths = apiHelper.getVolumeBoundPath(volId, getSelfPools()); + apiHelper.removeVolumePathsFromBlacklist(paths); + + try { + VolumeModule vol = apiHelper.recoverySnapshot(volId, snapId); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildExponPath(poolName, volId)); + stats.setSize(vol.getVolumeSize()); + stats.setActualSize(vol.getDataSize()); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + comp.success(stats); + } finally { + for (String path : paths) { + apiHelper.addVolumePathToBlacklist(path); + } + } + } + + @Override + public void validateConfig(String config) { + + } + + @Override + public void setTrashExpireTime(int timeInSeconds, Completion completion) { + // set trash expire time in days in advanced method + int days = timeInSeconds / 3600 / 24; + if (timeInSeconds % (3600 * 24) > 0) { + days++; + } + + apiHelper.setTrashExpireTime(days); + completion.success(); + } + + @Override + public void onFirstAdditionConfigure(Completion completion) { + completion.success(); + } + + @Override + public long alignSize(long size) { + return size; + } + + private void retry(Runnable r) { + retry(r, 3); + } + + private void retry(Runnable r, int retry) { + while (retry-- > 0) { + try { + r.run(); + return; + } catch (Exception e) { + logger.warn("runnable failed, try ", e); + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException ignore) {} + } + } + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/ExponStorageFactory.java b/plugin/expon/src/main/java/org/zstack/expon/ExponStorageFactory.java new file mode 100644 index 00000000000..6d24fbe824a --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/ExponStorageFactory.java @@ -0,0 +1,67 @@ +package org.zstack.expon; + +import org.zstack.core.singleflight.MultiNodeSingleFlightImpl; +import org.zstack.externalStorage.primary.ExternalStorageFencerType; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.storage.addon.primary.*; +import org.zstack.header.volume.VolumeAfterExpungeExtensionPoint; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeProtocol; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ExponStorageFactory implements ExternalPrimaryStorageSvcBuilder, BackupStorageSelector, VolumeAfterExpungeExtensionPoint { + public static final ExternalStorageFencerType fencerType = new ExternalStorageFencerType(ExponConstants.IDENTITY, VolumeProtocol.iSCSI.toString()); + + private List preferBackupStorageTypes; + + private static Map controllers = new ConcurrentHashMap<>(); + + + @Override + public PrimaryStorageControllerSvc buildControllerSvc(ExternalPrimaryStorageVO vo) { + ExponStorageController svc = new ExponStorageController(vo); + MultiNodeSingleFlightImpl.register(svc.apiHelper); + controllers.put(vo.getUuid(), svc); + return svc; + } + + @Override + public PrimaryStorageNodeSvc buildNodeSvc(ExternalPrimaryStorageVO vo) { + return new ExponStorageController(vo); + } + + @Override + public void discover(String url, String config, ReturnValueCompletion completion) { + ExponStorageController controller = new ExponStorageController(url); + MultiNodeSingleFlightImpl.register(controller.apiHelper); + controller.connect(config, url, completion); + } + + @Override + public String getIdentity() { + return ExponConstants.IDENTITY; + } + + @Override + public List getPreferBackupStorageTypes() { + return preferBackupStorageTypes; + } + + public void setPreferBackupStorageTypes(List preferBackupStorageTypes) { + this.preferBackupStorageTypes = preferBackupStorageTypes; + } + + // TODO: hard code for less http call. + @Override + public void volumeAfterExpunge(VolumeInventory volume) { + if (volume.getInstallPath() == null || !volume.getInstallPath().startsWith("expon://")) { + return; + } + + controllers.get(volume.getPrimaryStorageUuid()).cleanActiveRecord(volume); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ApiResult.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ApiResult.java new file mode 100644 index 00000000000..be291f31045 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ApiResult.java @@ -0,0 +1,98 @@ +package org.zstack.expon.sdk; + +import org.apache.commons.beanutils.PropertyUtils; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.util.Arrays.asList; + +public class ApiResult { + public ExponErrorCode error; + private String resultString; + + public ExponErrorCode getError() { + return error; + } + + void setError(ExponErrorCode error) { + this.error = error; + } + + void setResultString(String resultString) { + this.resultString = resultString; + } + + private static Object getProperty(Object bean, Iterator it) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + String path = it.next(); + if (bean instanceof Map) { + Pattern re = Pattern.compile("(.*)\\[(\\d+)]"); + Matcher m = re.matcher(path); + if (m.find()) { + path = String.format("(%s)[%s]", m.group(1), m.group(2)); + } + } + + Object val = PropertyUtils.getProperty(bean, path); + + if (it.hasNext()) { + return getProperty(val, it); + } else { + return val; + } + } + + public static Object getProperty(Object bean, String path) { + List paths = asList(path.split("\\.")); + try { + return getProperty(bean, paths.iterator()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void setProperty(Object bean, Iterator it, String fieldName, Object val) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + if (it.hasNext()) { + bean = getProperty(bean, it); + } + + if (bean instanceof Map) { + Pattern re = Pattern.compile("(.*)\\[(\\d+)]"); + Matcher m = re.matcher(fieldName); + if (m.find()) { + fieldName = String.format("(%s)[%s]", m.group(1), m.group(2)); + } + } + + PropertyUtils.setProperty(bean, fieldName, val); + } + + public static void setProperty(Object bean, String path, Object val) { + List paths = asList(path.split("\\.")); + String fieldName = paths.get(paths.size()-1); + paths = paths.subList(0, paths.size()-1); + + try { + setProperty(bean, paths.iterator(), fieldName, val); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public T getResult(Class clz) { + if (resultString == null || resultString.isEmpty()) { + return null; + } + + T ret = ExponClient.gson.fromJson(resultString, clz); + return ret; + } + + public String getResultString() { + return resultString; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponAction.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponAction.java new file mode 100644 index 00000000000..aa1d05dd983 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponAction.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk; + +public enum ExponAction { + add, + remove +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponApiException.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponApiException.java new file mode 100644 index 00000000000..2441e517330 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponApiException.java @@ -0,0 +1,11 @@ +package org.zstack.expon.sdk; + +public class ExponApiException extends RuntimeException { + public ExponApiException(String format) { + super(format); + } + + public ExponApiException(Exception e) { + super(e); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponAsyncResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponAsyncResponse.java new file mode 100644 index 00000000000..4f59cbdd034 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponAsyncResponse.java @@ -0,0 +1,13 @@ +package org.zstack.expon.sdk; + +public class ExponAsyncResponse extends ExponResponse { + private String taskId; + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponClient.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponClient.java new file mode 100644 index 00000000000..53d087cceac --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponClient.java @@ -0,0 +1,550 @@ +package org.zstack.expon.sdk; + +import com.google.common.base.CaseFormat; +import okhttp3.*; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.springframework.http.HttpMethod; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.Platform; +import org.zstack.expon.sdk.volume.GetVolumeTaskProgressRequest; +import org.zstack.expon.sdk.volume.GetVolumeTaskProgressResponse; +import org.zstack.externalStorage.sdk.ExternalStorageApiClient; +import org.zstack.header.expon.Constants; +import org.zstack.header.rest.DefaultSSLVerifier; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ExponClient extends ExternalStorageApiClient { + private static final CLogger logger = Utils.getLogger(ExponClient.class); + + private ExponConnectConfig config; + + private Supplier sessionRefresher; + + private Supplier sessionGetter; + + public ExponConnectConfig getConfig() { + return config; + } + + public void configure(ExponConnectConfig c) { + config = c; + + if (c.readTimeout != null || c.writeTimeout != null) { + OkHttpClient.Builder b = new OkHttpClient.Builder(); + + if (c.readTimeout != null) { + b.readTimeout(c.readTimeout, TimeUnit.MILLISECONDS); + } + if (c.writeTimeout != null) { + b.writeTimeout(c.writeTimeout, TimeUnit.MILLISECONDS); + } + + SSLSocketFactory factory = DefaultSSLVerifier.getSSLFactory(DefaultSSLVerifier.trustAllCerts); + if (factory != null) { + http = b.sslSocketFactory(factory, (X509TrustManager) DefaultSSLVerifier.trustAllCerts[0]) + .hostnameVerifier(DefaultSSLVerifier::verify) + .followRedirects(true) + .followSslRedirects(true) + .build(); + } else { + http = b.followRedirects(true) + .followSslRedirects(true) + .build(); + } + } + } + + public void setSessionRefresher(Supplier sessionRefresher) { + this.sessionRefresher = sessionRefresher; + } + + public void setSessionGetter(Supplier sessionGetter) { + this.sessionGetter = sessionGetter; + } + + public T call(ExponRequest req, Class clz) { + errorIfNotConfigured(); + ApiResult ret = new Api(req).call(); + + if (ret.error != null) { + ExponResponse rsp = new ExponResponse(); + rsp.retCode = ret.error.retCode; + rsp.message = ret.error.message; + return JSONObjectUtil.rehashObject(rsp, clz); + } + + return ret.getResult(clz); + } + + public void call(ExponRequest req, InternalCompletion completion) { + errorIfNotConfigured(); + new Api(req).call(completion); + } + + class Api { + ExponRequest action; + ExponRestRequest restInfo; + + InternalCompletion completion; + + final String taskIdForLog = Platform.getUuid(); + String reqBody; // for log + + Api(ExponRequest action) { + this.action = action; + this.restInfo = action.getClass().getAnnotation(ExponRestRequest.class); + } + + private String substituteUrl(String url, Map tokens) { + Pattern pattern = Pattern.compile("\\{(.+?)\\}"); + Matcher matcher = pattern.matcher(url); + StringBuffer buffer = new StringBuffer(); + while (matcher.find()) { + String varName = matcher.group(1); + Object replacement = tokens.get(varName); + if (replacement == null) { + throw new ExponApiException(String.format("cannot find value for URL variable[%s]", varName)); + } + + matcher.appendReplacement(buffer, ""); + buffer.append(replacement.toString()); + } + + matcher.appendTail(buffer); + return buffer.toString(); + } + + private List getVarNamesFromUrl(String url) { + Pattern pattern = Pattern.compile("\\{(.+?)\\}"); + Matcher matcher = pattern.matcher(url); + + List urlVars = new ArrayList<>(); + while (matcher.find()) { + urlVars.add(matcher.group(1)); + } + + return urlVars; + } + + + ApiResult doCall() { + if (action.sessionId == null && action.getParameterMap().containsKey("sessionId")) { + logger.info("session id is null, refresh it"); + action.sessionId = sessionRefresher.get(); + logger.info(String.format("refresh session id[%s] success", action.sessionId)); + } + + Request.Builder reqBuilder = new Request.Builder(); + action.checkParameters(); + + try { + if (action instanceof ExponQueryRequest) { + fillQueryApiRequestBuilder(reqBuilder); + } else { + fillNonQueryApiRequestBuilder(reqBuilder); + } + } catch (Exception e) { + throw new ExponApiException(e); + } + + Request request = reqBuilder.build(); + + logger.debug(String.format("call request[%s: %s]: %s, body: %s", action.getClass().getSimpleName(), taskIdForLog, + request.toString(), reqBody)); + + try { + try (Response response = http.newCall(request).execute()) { + if (!response.isSuccessful()) { + if (response.body() == null) { + return httpError(response.code(), null); + } else { + return httpError(response.code(), response.body().string()); + } + } + + if (response.code() != 200 && response.code() != 204) { + throw new ExponApiException(String.format("[Internal Error] the server returns an unknown status code[%s]", response.code())); + } + + ApiResult res = writeApiResult(response); + if (res.error != null) { + return res; + } + + boolean async = !restInfo.sync() && restInfo.method() != HttpMethod.GET; + Map rsp = res.getResult(LinkedHashMap.class); + Object taskId = rsp.getOrDefault("task_id", null); + if (async && taskId != null) { + logger.debug(String.format("request[%s: %s] async result: %s", action.getClass().getSimpleName(), + taskIdForLog, res.getResultString())); + return pollResult(taskId.toString()); + } else { + return res; + } + } + } catch (IOException e) { + throw new ExponApiException(e); + } + } + + private ApiResult pollResult(String taskId) { + if (this.completion == null) { + return syncPollResult(taskId); + } else { + asyncPollResult(taskId); + return null; + } + } + + private void fillQueryApiRequestBuilder(Request.Builder reqBuilder) throws Exception { + ExponQueryRequest qaction = (ExponQueryRequest) action; + + HttpUrl.Builder urlBuilder = new HttpUrl.Builder().scheme("https") + .host(config.hostname) + .port(config.port); + + urlBuilder.addPathSegment("api"); + urlBuilder.addPathSegment(restInfo.version()); + + List varNames = getVarNamesFromUrl(restInfo.path()); + String path = restInfo.path(); + if (!varNames.isEmpty()) { + Map vars = new HashMap<>(); + for (String vname : varNames) { + Object value = action.getParameterValue(vname); + + if (value == null) { + throw new ExponApiException(String.format("missing required field[%s]", vname)); + } + + vars.put(vname, value); + } + + path = substituteUrl(path, vars); + } + urlBuilder.addPathSegments(path.replaceFirst("/", "")); + + if (!qaction.conditions.isEmpty()) { + for (String cond : qaction.conditions) { + String[] kv = cond.split("="); + urlBuilder.addQueryParameter(kv[0], kv[1]); + } + } + if (qaction.limit != null) { + urlBuilder.addQueryParameter("offset", String.format("%s", qaction.limit)); + } + if (qaction.start != null) { + urlBuilder.addQueryParameter("index", String.format("%s", qaction.start)); + } + if (qaction.sortBy != null) { + urlBuilder.addQueryParameter("sort_by", String.format("%s", qaction.sortBy)); + } + if (qaction.sortDirection != null) { + urlBuilder.addQueryParameter("order_by", String.format("%s", qaction.sortBy)); + } + + reqBuilder.addHeader(Constants.HEADER_AUTHORIZATION, String.format("%s %s", Constants.BEARER, qaction.sessionId)); + + reqBuilder.url(urlBuilder.build()).get(); + } + + private void fillNonQueryApiRequestBuilder(Request.Builder reqBuilder) throws Exception { + HttpUrl.Builder builder = new HttpUrl.Builder() + .scheme("https") + .host(config.hostname) + .port(config.port); + builder.addPathSegment("api"); + builder.addPathSegment(restInfo.version()); + if (restInfo.sync()) { + builder.addPathSegment("sync"); + } + + List varNames = getVarNamesFromUrl(restInfo.path()); + String path = restInfo.path(); + if (!varNames.isEmpty()) { + Map vars = new HashMap<>(); + for (String vname : varNames) { + Object value = action.getParameterValue(vname); + + if (value == null) { + throw new ExponApiException(String.format("missing required field[%s]", vname)); + } + + vars.put(vname, value); + } + + path = substituteUrl(path, vars); + builder.addPathSegments(path.replaceFirst("/", "")); + } else { + builder.addPathSegments(path.replaceFirst("/", "")); + } + + final Map params = new HashMap<>(); + + for (String pname : action.getAllParameterNames()) { + if (varNames.contains(pname) || Constants.SESSION_ID.equals(pname)) { + // the field is set in URL variables + continue; + } + + Object value = action.getParameterValue(pname); + if (value != null) { + params.put(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pname), value); + } + } + + if (restInfo.method().equals(HttpMethod.GET)) { + reqBuilder.url(builder.build()).get(); + } else if (restInfo.method().equals(HttpMethod.DELETE) && !restInfo.hasBody()) { + params.forEach((k, v) -> builder.addQueryParameter(k, v.toString())); + reqBuilder.url(builder.build()).delete(); + } else { + reqBody = gson.toJson(params); + reqBuilder.url(builder.build()).method(restInfo.method().toString(), RequestBody.create(Constants.JSON, reqBody)); + } + + if (action instanceof LoginExponRequest) { + return; + } + reqBuilder.addHeader(Constants.HEADER_AUTHORIZATION, String.format("%s %s", Constants.BEARER, action.sessionId)); + } + + private ExponErrorCode errorCode(String id, String s) { + ExponErrorCode err = new ExponErrorCode(); + err.retCode = id; + err.message = s; + return err; + } + + private ApiResult syncPollResult(String taskId) { + long current = System.currentTimeMillis(); + long timeout = this.getTimeout(); + long expiredTime = current + timeout; + long interval = this.getInterval(); + + ApiResult ret = new ApiResult(); + ExponResponse rsp = new ExponResponse(); + while (current < expiredTime) { + ExponTask trsp = getTaskStatus(taskId); + if (TaskStatus.SUCCESS.name().equals(trsp.getStatus()) || TaskStatus.FAILED.name().equals(trsp.getStatus())) { + rsp.setRetCode(trsp.getRetCode()); + rsp.setMessage(trsp.getRetMsg()); + ret.setResultString(gson.toJson(rsp)); + return ret; + } + + try { + TimeUnit.MILLISECONDS.sleep(interval); + } catch (InterruptedException e) { + // ignore + } + current += interval; + } + + ApiResult res = new ApiResult(); + res.error = errorCode( + Constants.POLLING_TIMEOUT_ERROR, + String.format("polling result of api[%s] timeout after %s ms", action.getClass().getSimpleName(), timeout) + ); + + return res; + } + + private void asyncPollResult(final String taskId) { + final long current = System.currentTimeMillis(); + final long timeout = this.getTimeout(); + final long expiredTime = current + timeout; + final long i = this.getInterval(); + final int[] pollTimes = {0}; + + final Timer timer = new Timer(); + + timer.schedule(new TimerTask() { + long count = current; + final long interval = i; + + private void done(ApiResult res) { + logger.debug(String.format("request[%s: %s] result: %s", action.getClass().getSimpleName(), + taskIdForLog, res.getResultString())); + completion.complete(res); + timer.cancel(); + } + + @Override + public void run() { + try { + ExponTask trsp = getTaskStatus(taskId); + // TODO: remove this when the expon server is ready for zero copy + if (CoreGlobalProperty.UNIT_TEST_ON && pollTimes[0]++ > 2) { + trsp.setStatus(TaskStatus.SUCCESS.name()); + } + + if (TaskStatus.SUCCESS.name().equals(trsp.getStatus()) || TaskStatus.FAILED.name().equals(trsp.getStatus())) { + + ApiResult ret = new ApiResult(); + ExponResponse rsp = new ExponResponse(); + + rsp.setRetCode(trsp.getRetCode()); + rsp.setMessage(trsp.getRetMsg()); + if (!trsp.isSuccess()) { + ret.error = errorCode(trsp.getRetCode(), trsp.getRetMsg()); + } + ret.setResultString(gson.toJson(rsp)); + done(ret); + return; + } + + count += interval; + if (count >= expiredTime) { + ApiResult res = new ApiResult(); + res.error = errorCode( + Constants.POLLING_TIMEOUT_ERROR, + String.format("polling result of api[%s] timeout after %s ms", action.getClass().getSimpleName(), timeout) + ); + + done(res); + } + } catch (Throwable e) { + ApiResult res = new ApiResult(); + res.error = errorCode( + Constants.INTERNAL_ERROR, + "an internal error happened: " + e.getMessage() + ); + + done(res); + } + } + }, 0, i); + } + + private ExponTask getTaskStatus(String taskId) { + ExponTask task; + if (NumberUtils.isNumber(taskId)) { + GetVolumeTaskProgressResponse rsp = getVolumeTaskProgress(Float.valueOf(taskId).intValue()); + if (!rsp.isSuccess()) { + throw new ExponApiException(String.format("failed to get task status, %s", rsp.getMessage())); + } + + task = ExponTask.valueOf(rsp.getTask()); + } else { + GetTaskStatusResponse rsp = getTaskDetail(taskId); + if (!rsp.isSuccess()) { + throw new ExponApiException(String.format("failed to get task status, %s", rsp.getMessage())); + } + + task = ExponTask.valueOf(rsp); + } + + return task; + } + + private GetTaskStatusResponse getTaskDetail(String taskId) { + GetTaskStatusRequest req = new GetTaskStatusRequest(); + req.setId(taskId); + req.setSessionId(sessionGetter.get()); + return retrySessionGetResult(req, GetTaskStatusResponse.class); + } + + private GetVolumeTaskProgressResponse getVolumeTaskProgress(int taskId) { + GetVolumeTaskProgressRequest req = new GetVolumeTaskProgressRequest(); + req.setTaskId(taskId); + req.setSessionId(sessionGetter.get()); + return retrySessionGetResult(req, GetVolumeTaskProgressResponse.class); + } + + private T retrySessionGetResult(ExponRequest req, Class clz) { + T rsp = ExponClient.this.call(req, clz); + if (!rsp.sessionExpired()) { + return rsp; + } + + logger.debug(String.format("session[%s] expired, login again", req.sessionId)); + this.action.sessionId = sessionRefresher.get(); + req.setSessionId(sessionGetter.get()); + return ExponClient.this.call(req, clz); + } + + private ApiResult writeApiResult(Response response) throws IOException { + ApiResult res = new ApiResult(); + + if (response.code() == 200) { + String body = response.body().string(); + ExponResponse rsp = gson.fromJson(body, ExponResponse.class); + if (rsp.isSuccess()) { + res.setResultString(body); + } else { + res.error = errorCode(rsp.getRetCode(), StringEscapeUtils.unescapeJava(rsp.getMessage())); + } + } else { + throw new ExponApiException(String.format("unknown status code: %s", response.code())); + } + return res; + } + + private ApiResult httpError(int code, String details) { + ApiResult res = new ApiResult(); + if (details != null && details.startsWith("{")) { + ExponResponse rsp = gson.fromJson(details, ExponResponse.class); + if (rsp.message != null) { + res.error = errorCode( + rsp.retCode, + StringEscapeUtils.unescapeJava(rsp.message) + ); + return res; + } + } + + res.error = errorCode( + Constants.HTTP_ERROR, + String.format("the http status code[%s] details[%s] indicates a failure happened", code, details) + ); + return res; + } + + ApiResult call() { + ApiResult ret = doCall(); + if (ret.error != null) { + logger.debug(String.format("request[%s: %s] error: %s result: %s", action.getClass().getSimpleName(), + taskIdForLog, gson.toJson(ret.error), ret.getResultString())); + } else { + logger.debug(String.format("request[%s: %s] result: %s", action.getClass().getSimpleName(), + taskIdForLog, ret.getResultString())); + } + return ret; + } + + void call(InternalCompletion completion) { + this.completion = completion; + ApiResult res = doCall(); + if (res != null) { + completion.complete(res); + } + } + + private long getTimeout(){ + return action.timeout == ACTION_DEFAULT_TIMEOUT ? config.getDefaultPollingTimeout(): action.timeout; + } + + private long getInterval(){ + return config.getDefaultPollingInterval(); + } + } + + private void errorIfNotConfigured() { + if (config == null) { + throw new RuntimeException("setConfig() must be called before any methods"); + } + } +} \ No newline at end of file diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponConnectConfig.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponConnectConfig.java new file mode 100644 index 00000000000..91725847302 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponConnectConfig.java @@ -0,0 +1,67 @@ +package org.zstack.expon.sdk; + +import java.util.concurrent.TimeUnit; + +public class ExponConnectConfig { + public String hostname = "localhost"; + public int port = 443; + long defaultPollingTimeout = TimeUnit.HOURS.toMillis(3); + long defaultPollingInterval = TimeUnit.SECONDS.toMillis(1); + public Long readTimeout; + public Long writeTimeout; + + public String getHostname() { + return hostname; + } + + public int getPort() { + return port; + } + + public long getDefaultPollingTimeout() { + return defaultPollingTimeout; + } + + public long getDefaultPollingInterval() { + return defaultPollingInterval; + } + + public static class Builder { + ExponConnectConfig config = new ExponConnectConfig(); + + public Builder setHostname(String hostname) { + config.hostname = hostname; + return this; + } + + public Builder setPort(int port) { + config.port = port; + return this; + } + + public Builder setDefaultPollingTimeout(long value, TimeUnit unit) { + config.defaultPollingTimeout = unit.toMillis(value); + return this; + } + + public Builder setDefaultPollingInterval(long value, TimeUnit unit) { + config.defaultPollingInterval = unit.toMillis(value); + return this; + } + + public Builder setReadTimeout(long value, TimeUnit unit) { + config.readTimeout = unit.toMillis(value); + return this; + } + + public Builder setWriteTimeout(long value, TimeUnit unit) { + config.writeTimeout = unit.toMillis(value); + return this; + } + + + public ExponConnectConfig build() { + return config; + } + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponErrorCode.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponErrorCode.java new file mode 100644 index 00000000000..dd577e3cc19 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponErrorCode.java @@ -0,0 +1,38 @@ +package org.zstack.expon.sdk; + +import org.zstack.header.expon.ExponError; + +public class ExponErrorCode { + String retCode; + String message; + + public String getRetCode() { + return retCode; + } + + public void setRetCode(String retCode) { + this.retCode = retCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean sessionExpired() { + return isError(ExponError.SESSION_EXPIRED, ExponError.SESSION_NOTFOUND, ExponError.INVALID_SESSION); + } + + public boolean isError(ExponError... errorEnums) { + for (ExponError e : errorEnums) { + if (e.toString().equals(retCode)) { + return true; + } + } + + return false; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponParam.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponParam.java new file mode 100644 index 00000000000..8d9071aeecb --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponParam.java @@ -0,0 +1,7 @@ +package org.zstack.expon.sdk; + +import org.zstack.externalStorage.sdk.ExternalStorageParam; + +public interface ExponParam extends ExternalStorageParam { + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQuery.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQuery.java new file mode 100644 index 00000000000..cc4ddf72ac2 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQuery.java @@ -0,0 +1,14 @@ +package org.zstack.expon.sdk; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExponQuery { + Class replyClass(); + + Class inventoryClass(); +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQueryRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQueryRequest.java new file mode 100644 index 00000000000..732f153ce37 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQueryRequest.java @@ -0,0 +1,16 @@ +package org.zstack.expon.sdk; + +import java.util.ArrayList; +import java.util.List; + +public abstract class ExponQueryRequest extends ExponRequest { + public List conditions = new ArrayList<>(); + public Long limit; + public Long start; + public String sortBy; + public String sortDirection; + + public void addCond(String key, String value) { + conditions.add(key + "=" + value); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQueryResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQueryResponse.java new file mode 100644 index 00000000000..b6641594759 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponQueryResponse.java @@ -0,0 +1,21 @@ +package org.zstack.expon.sdk; + +public class ExponQueryResponse extends ExponResponse { + protected long total; + protected long count; + public void setTotal(long total) { + this.total = total; + } + + public long getTotal() { + return total; + } + + public void setCount(long count) { + this.count = count; + } + + public long getCount() { + return count; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponRequest.java new file mode 100644 index 00000000000..d1b4e44d2c8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponRequest.java @@ -0,0 +1,21 @@ +package org.zstack.expon.sdk; + +import org.zstack.externalStorage.sdk.Param; + +/** + * Created by xing5 on 2016/12/9. + */ +public abstract class ExponRequest implements ExponParam { + @Param + String sessionId; + + long timeout = -1; + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public String getSessionId() { + return sessionId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponResponse.java new file mode 100644 index 00000000000..12e8cc3c5fa --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponResponse.java @@ -0,0 +1,49 @@ +package org.zstack.expon.sdk; + +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.expon.ExponError; + +import static org.zstack.core.Platform.operr; + +public class ExponResponse { + protected String retCode; + protected String message; + + public String getRetCode() { + return retCode; + } + + public void setRetCode(String retCode) { + this.retCode = retCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return "0".equals(retCode) || retCode == null; + } + + public ErrorCode getError() { + return operr(message); + } + + public boolean sessionExpired() { + return isError(ExponError.SESSION_EXPIRED, ExponError.SESSION_NOTFOUND, ExponError.INVALID_SESSION); + } + + public boolean isError(ExponError... errorEnums) { + for (ExponError e : errorEnums) { + if (e.toString().equals(retCode)) { + return true; + } + } + + return false; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponRestRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponRestRequest.java new file mode 100644 index 00000000000..36d038ca483 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponRestRequest.java @@ -0,0 +1,16 @@ +package org.zstack.expon.sdk; + +import org.springframework.http.HttpMethod; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface ExponRestRequest { + String path(); + HttpMethod method(); + Class responseClass(); + String version() default "v2"; + boolean sync() default true; + boolean hasBody() default false; +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponSyncCreateResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponSyncCreateResponse.java new file mode 100644 index 00000000000..71acba288d2 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponSyncCreateResponse.java @@ -0,0 +1,13 @@ +package org.zstack.expon.sdk; + +public class ExponSyncCreateResponse extends ExponResponse { + protected String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponTask.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponTask.java new file mode 100644 index 00000000000..80a7619b3f9 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/ExponTask.java @@ -0,0 +1,185 @@ +package org.zstack.expon.sdk; + +import org.zstack.expon.sdk.volume.VolumeTask; + +import java.util.List; + +public class ExponTask { + private String id; + private String taskId; + private String name; + private String description; + private String operand; + private long beginTime; + private long endTime; + private String status; + private int progress; + private String retCode; + private String retMsg; + private List steps; + private int curStep; + private boolean processing; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOperand() { + return operand; + } + + public void setOperand(String operand) { + this.operand = operand; + } + + public int getProgress() { + return progress; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + + + public List getSteps() { + return steps; + } + + public void setSteps(List steps) { + this.steps = steps; + } + + public int getCurStep() { + return curStep; + } + + public void setCurStep(int curStep) { + this.curStep = curStep; + } + + public boolean isProcessing() { + return processing; + } + + public void setProcessing(boolean processing) { + this.processing = processing; + } + + public String getRetCode() { + return retCode; + } + + public void setRetCode(String retCode) { + this.retCode = retCode; + } + + public boolean isSuccess() { + return "0".equals(retCode); + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + public long getBeginTime() { + return beginTime; + } + + public void setBeginTime(long beginTime) { + this.beginTime = beginTime; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public static ExponTask valueOf(GetTaskStatusResponse rsp) { + ExponTask task = new ExponTask(); + task.setId(rsp.getId()); + task.setTaskId(rsp.getTaskId()); + task.setName(rsp.getName()); + task.setDescription(rsp.getDescription()); + task.setOperand(rsp.getOperand()); + task.setBeginTime(rsp.getBeginTime()); + task.setEndTime(rsp.getEndTime()); + task.setStatus(rsp.getStatus()); + task.setProgress(rsp.getProgress()); + task.setRetCode(rsp.getRetCode()); + task.setRetMsg(rsp.getRetMsg()); + task.setCurStep(rsp.getCurStep()); + return task; + } + + public static ExponTask valueOf(VolumeTask volumeTask) { + ExponTask task = new ExponTask(); + task.setName(volumeTask.getVolName()); + task.setProgress(volumeTask.getProgress()); + task.setRetCode(Integer.toString(volumeTask.getCode())); + task.setRetMsg(volumeTask.getMsg()); + + switch (volumeTask.getState()) { + case "TASK_COMPLETE": + task.setStatus(TaskStatus.SUCCESS.toString()); + break; + case "TASK_FAILED": + task.setStatus(TaskStatus.FAILED.toString()); + break; + case "TASK_STATE_TORUN": + case "TASK_STATE_RUNNING": + task.setStatus(TaskStatus.RUNNING.toString()); + break; + default: + task.setStatus(TaskStatus.FAILED.toString()); + task.setRetMsg("Unknown task state: " + volumeTask.getState()); + task.setRetCode("1"); + break; + } + return task; + + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/GetTaskStatusRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/GetTaskStatusRequest.java new file mode 100644 index 00000000000..6960102f858 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/GetTaskStatusRequest.java @@ -0,0 +1,34 @@ +package org.zstack.expon.sdk; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/tasks/{id}", + method = HttpMethod.GET, + responseClass = GetTaskStatusResponse.class, + version = "v1", + sync = false +) +public class GetTaskStatusRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/GetTaskStatusResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/GetTaskStatusResponse.java new file mode 100644 index 00000000000..9e044819de9 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/GetTaskStatusResponse.java @@ -0,0 +1,152 @@ +package org.zstack.expon.sdk; + + +/** @example + * { + * "begin_time": 1689936631393, + * "cur_step": 1, + * "description": "", + * "end_time": 1689936631622, + * "id": "349a69c9-fa88-48f3-bae7-8e6e0a7f952c", + * "name": "Delete block storage volume", + * "operand": "volume:testclone", + * "private": "", + * "progress": 100, + * "ret_code": "0", + * "ret_msg": "", + * "status": "SUCCESS", + * "steps": ["pool delete volume", "database delete volume"], + * "task_id": "b01.003", + * "message": "" + * } + */ +public class GetTaskStatusResponse extends ExponResponse { + private String id; + private String taskId; + private String name; + private String description; + private String operand; + private long beginTime; + private long endTime; + private String status; + private int progress; + private String retMsg; + private int curStep; + private String private_; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOperand() { + return operand; + } + + public void setOperand(String operand) { + this.operand = operand; + } + + public long getBeginTime() { + return beginTime; + } + + public void setBeginTime(long beginTime) { + this.beginTime = beginTime; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public int getProgress() { + return progress; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + @Override + public String getRetCode() { + return retCode; + } + + @Override + public void setRetCode(String retCode) { + this.retCode = retCode; + } + + public String getRetMsg() { + return retMsg; + } + + public void setRetMsg(String retMsg) { + this.retMsg = retMsg; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public void setMessage(String message) { + this.message = message; + } + + public int getCurStep() { + return curStep; + } + + public void setCurStep(int curStep) { + this.curStep = curStep; + } + + public String getPrivate_() { + return private_; + } + + public void setPrivate_(String private_) { + this.private_ = private_; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/InternalCompletion.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/InternalCompletion.java new file mode 100644 index 00000000000..395da20977e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/InternalCompletion.java @@ -0,0 +1,5 @@ +package org.zstack.expon.sdk; + +public interface InternalCompletion { + void complete(ApiResult result); +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/LoginExponRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/LoginExponRequest.java new file mode 100644 index 00000000000..27871774fdf --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/LoginExponRequest.java @@ -0,0 +1,46 @@ +package org.zstack.expon.sdk; + + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/login", + method = HttpMethod.POST, + responseClass = LoginExponResponse.class, + version = "v1", + sync = false +) +public class LoginExponRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + @Param + private String password; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public Map getParameterMap() { + parameterMap.remove("sessionId"); + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/LoginExponResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/LoginExponResponse.java new file mode 100644 index 00000000000..6ab1554224f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/LoginExponResponse.java @@ -0,0 +1,31 @@ +package org.zstack.expon.sdk; + +public class LoginExponResponse extends ExponResponse { + private String accessToken; + private String refreshToken; + private String tokenType; + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getRefreshToken() { + return refreshToken; + } + + public void setRefreshToken(String refreshToken) { + this.refreshToken = refreshToken; + } + + public String getTokenType() { + return tokenType; + } + + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/LogoutExponRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/LogoutExponRequest.java new file mode 100644 index 00000000000..a763f394ec8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/LogoutExponRequest.java @@ -0,0 +1,22 @@ +package org.zstack.expon.sdk; + +import org.springframework.http.HttpMethod; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/v2/logout", + method = HttpMethod.POST, + responseClass = LogoutExponResponse.class, + version = "v1", + sync = false +) +public class LogoutExponRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/LogoutExponResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/LogoutExponResponse.java new file mode 100644 index 00000000000..24576734367 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/LogoutExponResponse.java @@ -0,0 +1,4 @@ +package org.zstack.expon.sdk; + +public class LogoutExponResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/TaskStatus.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/TaskStatus.java new file mode 100644 index 00000000000..11aa8f09bdf --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/TaskStatus.java @@ -0,0 +1,7 @@ +package org.zstack.expon.sdk; + +public enum TaskStatus { + SUCCESS, + FAILED, + RUNNING, +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/QueryTianshuClusterRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/QueryTianshuClusterRequest.java new file mode 100644 index 00000000000..de808f404ac --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/QueryTianshuClusterRequest.java @@ -0,0 +1,23 @@ +package org.zstack.expon.sdk.cluster; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/tianshu", + method = HttpMethod.GET, + responseClass = QueryTianshuClusterResponse.class, + sync = false +) +public class QueryTianshuClusterRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/QueryTianshuClusterResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/QueryTianshuClusterResponse.java new file mode 100644 index 00000000000..ebb539a1b4e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/QueryTianshuClusterResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.cluster; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryTianshuClusterResponse extends ExponQueryResponse { + private List result; + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/TianshuClusterModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/TianshuClusterModule.java new file mode 100644 index 00000000000..db968d3d186 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/cluster/TianshuClusterModule.java @@ -0,0 +1,109 @@ +package org.zstack.expon.sdk.cluster; + +/** + * @example + * { + * "cluster_mode": "normal", + * "create_time": 1658073607684, + * "domain_name": "sdfo.sgo.dfog", + * "health_status": "health", + * "id": "b64ec569-ec33-445e-b62c-59c8ebbda702", + * "name": "tianshu", + * "node": 3, + * "run_status": "complete", + * "tikv_name": "isdfofdg", + * "update_time": 1658073697076 + * } + */ +public class TianshuClusterModule { + private String id; + private String name; + private String domainName; + private String tikvName; + private String clusterMode; + private String healthStatus; + private String runStatus; + private int node; + private long createTime; + private long updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public String getTikvName() { + return tikvName; + } + + public void setTikvName(String tikvName) { + this.tikvName = tikvName; + } + + public String getClusterMode() { + return clusterMode; + } + + public void setClusterMode(String clusterMode) { + this.clusterMode = clusterMode; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public int getNode() { + return node; + } + + public void setNode(int node) { + this.node = node; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/config/SetTrashExpireTimeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/config/SetTrashExpireTimeRequest.java new file mode 100644 index 00000000000..734518db728 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/config/SetTrashExpireTimeRequest.java @@ -0,0 +1,37 @@ +package org.zstack.expon.sdk.config; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/sys_config/trash_recycle", + method = HttpMethod.PUT, + responseClass = SetTrashExpireTimeResponse.class, + sync = false, + version = "v1" +) +public class SetTrashExpireTimeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private int trashRecycle; + + public void setTrashRecycle(int trashRecycle) { + this.trashRecycle = trashRecycle; + } + + public int getTrashRecycle() { + return trashRecycle; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/config/SetTrashExpireTimeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/config/SetTrashExpireTimeResponse.java new file mode 100644 index 00000000000..7aa6b51cddc --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/config/SetTrashExpireTimeResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.config; + +import org.zstack.expon.sdk.ExponResponse; + +public class SetTrashExpireTimeResponse extends ExponResponse { + private int trashRecycle; + + public int getTrashRecycle() { + return trashRecycle; + } + + public void setTrashRecycle(int trashRecycle) { + this.trashRecycle = trashRecycle; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/AddIscsiClientGroupToIscsiTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/AddIscsiClientGroupToIscsiTargetRequest.java new file mode 100644 index 00000000000..69bc2f553a7 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/AddIscsiClientGroupToIscsiTargetRequest.java @@ -0,0 +1,56 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponAction; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}/add_clients", + method = HttpMethod.PUT, + responseClass = AddIscsiClientGroupToIscsiTargetResponse.class +) +public class AddIscsiClientGroupToIscsiTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + @Param + private String action = ExponAction.add.name(); + @Param + private List clients; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/AddIscsiClientGroupToIscsiTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/AddIscsiClientGroupToIscsiTargetResponse.java new file mode 100644 index 00000000000..6c397400e5e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/AddIscsiClientGroupToIscsiTargetResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class AddIscsiClientGroupToIscsiTargetResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/BindIscsiTargetToUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/BindIscsiTargetToUssRequest.java new file mode 100644 index 00000000000..ef8a602cb1c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/BindIscsiTargetToUssRequest.java @@ -0,0 +1,44 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}/add_nodes", + method = HttpMethod.PUT, + responseClass = BindIscsiTargetToUssResponse.class +) +public class BindIscsiTargetToUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String id; + @Param + private List nodes; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/BindIscsiTargetToUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/BindIscsiTargetToUssResponse.java new file mode 100644 index 00000000000..a0883d27f48 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/BindIscsiTargetToUssResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class BindIscsiTargetToUssResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeIscsiClientGroupRequest.java new file mode 100644 index 00000000000..23eb5d6ca39 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeIscsiClientGroupRequest.java @@ -0,0 +1,55 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}/hosts", + method = HttpMethod.PUT, + responseClass = ChangeIscsiClientGroupResponse.class +) +public class ChangeIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + @Param(validValues = {"add", "remove"}) + private String action; + @Param + private List hosts; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeIscsiClientGroupResponse.java new file mode 100644 index 00000000000..596d8b9ad96 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeIscsiClientGroupResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class ChangeIscsiClientGroupResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeSnapshotInIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeSnapshotInIscsiClientGroupRequest.java new file mode 100644 index 00000000000..3f60230582b --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeSnapshotInIscsiClientGroupRequest.java @@ -0,0 +1,66 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.expon.sdk.volume.LunResource; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}/snapshots", + method = HttpMethod.PUT, + responseClass = ChangeSnapshotInIscsiClientGroupResponse.class +) +public class ChangeSnapshotInIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + @Param(validValues = {"add", "remove"}) + private String action; + @Param + private List luns; + @Param(required = false) + private List gateways; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getLuns() { + return luns; + } + + public void setLuns(List luns) { + this.luns = luns; + } + + public void setGateways(List gateways) { + this.gateways = gateways; + } + + public List getGateways() { + return gateways; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeSnapshotInIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeSnapshotInIscsiClientGroupResponse.java new file mode 100644 index 00000000000..3e28b711551 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeSnapshotInIscsiClientGroupResponse.java @@ -0,0 +1,7 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class ChangeSnapshotInIscsiClientGroupResponse extends ExponResponse { + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeVolumeInIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeVolumeInIscsiClientGroupRequest.java new file mode 100644 index 00000000000..d4e6cfeed4c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeVolumeInIscsiClientGroupRequest.java @@ -0,0 +1,66 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.expon.sdk.volume.LunResource; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}/luns", + method = HttpMethod.PUT, + responseClass = ChangeVolumeInIscsiClientGroupResponse.class +) +public class ChangeVolumeInIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + @Param(validValues = {"add", "remove"}) + private String action; + @Param + private List luns; + @Param(required = false) + private List gateways; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getLuns() { + return luns; + } + + public void setLuns(List luns) { + this.luns = luns; + } + + public void setGateways(List gateways) { + this.gateways = gateways; + } + + public List getGateways() { + return gateways; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeVolumeInIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeVolumeInIscsiClientGroupResponse.java new file mode 100644 index 00000000000..b1944dc4bc8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/ChangeVolumeInIscsiClientGroupResponse.java @@ -0,0 +1,7 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class ChangeVolumeInIscsiClientGroupResponse extends ExponResponse { + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiClientGroupRequest.java new file mode 100644 index 00000000000..e51a9491911 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiClientGroupRequest.java @@ -0,0 +1,75 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients", + method = HttpMethod.POST, + responseClass = CreateIscsiClientGroupResponse.class +) +public class CreateIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + @Param(required = false) + private String description; + @Param + private String tianshuId; + @Param + private boolean isChap; + @Param + private List hosts; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setChap(boolean chap) { + isChap = chap; + } + + public boolean isChap() { + return isChap; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiClientGroupResponse.java new file mode 100644 index 00000000000..fd1a9773115 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiClientGroupResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponSyncCreateResponse; + +public class CreateIscsiClientGroupResponse extends ExponSyncCreateResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiTargetRequest.java new file mode 100644 index 00000000000..a81a57c1425 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiTargetRequest.java @@ -0,0 +1,90 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways", + method = HttpMethod.POST, + responseClass = CreateIscsiClientGroupResponse.class +) +public class CreateIscsiTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + + @Param(required = false) + private String description; + + @Param + private int port = 3260; + + @Param(required = false) + private String iqn; + + @Param + private String tianshuId; + + @Param + private List nodes; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public void setIqn(String iqn) { + this.iqn = iqn; + } + + public String getIqn() { + return iqn; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiTargetResponse.java new file mode 100644 index 00000000000..9ea3624d4ba --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/CreateIscsiTargetResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class CreateIscsiTargetResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiClientGroupRequest.java new file mode 100644 index 00000000000..fe5e6cb2ba1 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiClientGroupRequest.java @@ -0,0 +1,46 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}", + method = HttpMethod.DELETE, + responseClass = CreateIscsiClientGroupResponse.class, + sync = false +) +public class DeleteIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + @Param + private boolean force; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiClientGroupResponse.java new file mode 100644 index 00000000000..e851099dce0 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiClientGroupResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteIscsiClientGroupResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiTargetRequest.java new file mode 100644 index 00000000000..c6996724d24 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiTargetRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}", + method = HttpMethod.DELETE, + responseClass = DeleteIscsiTargetResponse.class +) +public class DeleteIscsiTargetRequest extends ExponRequest { + + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiTargetResponse.java new file mode 100644 index 00000000000..a0022b1169e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/DeleteIscsiTargetResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteIscsiTargetResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupAttachedTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupAttachedTargetRequest.java new file mode 100644 index 00000000000..2370f718f1f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupAttachedTargetRequest.java @@ -0,0 +1,36 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}/gateways", + method = HttpMethod.GET, + responseClass = GetIscsiClientGroupAttachedTargetResponse.class, + sync = false +) +public class GetIscsiClientGroupAttachedTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } + +} \ No newline at end of file diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupAttachedTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupAttachedTargetResponse.java new file mode 100644 index 00000000000..95218e15422 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupAttachedTargetResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetIscsiClientGroupAttachedTargetResponse extends ExponResponse { + private List gateways; + + public void setGateways(List gateways) { + this.gateways = gateways; + } + + public List getGateways() { + return gateways; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupRequest.java new file mode 100644 index 00000000000..5f4c873c4df --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}", + method = HttpMethod.GET, + responseClass = GetIscsiClientGroupResponse.class, + sync = false +) +public class GetIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupResponse.java new file mode 100644 index 00000000000..3ffdd9d7dae --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiClientGroupResponse.java @@ -0,0 +1,182 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + + +/** + * @example { + * "audit_result": "consistent", + * "audit_result_reason": "", + * "chap_password": "", + * "chap_username": "", + * "client_name": "iscsi_zstack_heartbeat", + * "client_node_count": 3, + * "create_from": "csm", + * "create_time": 1705314720041, + * "description": "", + * "hosts": ["iqn.1994-05.com.redhat:77cacce6c29", "iqn.1994-05.com.redhat:c24c919fc248", "iqn.1994-05.com.redhat:278979fd2069"], + * "id": "413f59f4-90ae-4ee7-9388-07065d25bd3e", + * "ig_id": 1, + * "iqn_prefix": null, + * "is_chap": false, + * "iscsi_gw_count": 2, + * "lun_count": 1, + * "message": "", + * "name": "iscsi_zstack_heartbeat", + * "ret_code": "0", + * "run_status": "normal", + * "snap_num": 0, + * "tianshu_id": "5ba1db5c-7672-4a2b-bceb-015aa3234275", + * "tianshu_name": "VUZhh", + * "update_time": 1708411159610, + * "vol_num": 1 + * } + */ +public class GetIscsiClientGroupResponse extends ExponResponse { + private String id; + private String name; + private String description; + private List hosts; + private String runStatus; + private int volNum; + private int snapNum; + private String auditResult; + private String auditResultReason; + private int iscsiGwCount; + private int clientNodeCount; + private String createFrom; + private String tianshuId; + private String tianshuName; + private long createTime; + private long updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public int getVolNum() { + return volNum; + } + + public void setVolNum(int volNum) { + this.volNum = volNum; + } + + public int getSnapNum() { + return snapNum; + } + + public void setSnapNum(int snapNum) { + this.snapNum = snapNum; + } + + public String getAuditResult() { + return auditResult; + } + + public void setAuditResult(String auditResult) { + this.auditResult = auditResult; + } + + public String getAuditResultReason() { + return auditResultReason; + } + + public void setAuditResultReason(String auditResultReason) { + this.auditResultReason = auditResultReason; + } + + public int getiscsiGwCount() { + return iscsiGwCount; + } + + public void setiscsiGwCount(int iscsiGwCount) { + this.iscsiGwCount = iscsiGwCount; + } + + public int getClientNodeCount() { + return clientNodeCount; + } + + public void setClientNodeCount(int clientNodeCount) { + this.clientNodeCount = clientNodeCount; + } + + public String getCreateFrom() { + return createFrom; + } + + public void setCreateFrom(String createFrom) { + this.createFrom = createFrom; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getTianshuName() { + return tianshuName; + } + + public void setTianshuName(String tianshuName) { + this.tianshuName = tianshuName; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetBoundUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetBoundUssRequest.java new file mode 100644 index 00000000000..5c92fa24b93 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetBoundUssRequest.java @@ -0,0 +1,36 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}/nodes", + method = HttpMethod.GET, + responseClass = GetIscsiTargetBoundUssResponse.class, + sync = false +) +public class GetIscsiTargetBoundUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetBoundUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetBoundUssResponse.java new file mode 100644 index 00000000000..35d73d824ac --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetBoundUssResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetIscsiTargetBoundUssResponse extends ExponResponse { + private List nodes; + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public List getNodes() { + return nodes; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetRequest.java new file mode 100644 index 00000000000..6b10eae11c7 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}", + method = HttpMethod.GET, + responseClass = GetIscsiTargetResponse.class, + sync = false +) +public class GetIscsiTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetResponse.java new file mode 100644 index 00000000000..091424a63ff --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetResponse.java @@ -0,0 +1,217 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +/** copy from @class: IscsiModule + * + */ +public class GetIscsiTargetResponse extends ExponResponse { + private String id; + private String name; + private String description; + private long createTime; + private long updateTime; + private String iqn; + private int port; + private String chapPassword; + private String chapUsername; + private int clientCount; + private String clientIds; + + private String gatewayName; + private String healthStatus; + private String healthStatusReason; + private boolean isChap; + private boolean isEnabled; + private int lunCount; + private int nodeCount; + private int queueDepth; + private String runStatus; + private String tianshuClusterName; + private String tianshuId; + private String vendor; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } + + public String getIqn() { + return iqn; + } + + public void setIqn(String iqn) { + this.iqn = iqn; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getChapPassword() { + return chapPassword; + } + + public void setChapPassword(String chapPassword) { + this.chapPassword = chapPassword; + } + + public String getChapUsername() { + return chapUsername; + } + + public void setChapUsername(String chapUsername) { + this.chapUsername = chapUsername; + } + + public int getClientCount() { + return clientCount; + } + + public void setClientCount(int clientCount) { + this.clientCount = clientCount; + } + + public String getClientIds() { + return clientIds; + } + + public void setClientIds(String clientIds) { + this.clientIds = clientIds; + } + + public String getGatewayName() { + return gatewayName; + } + + public void setGatewayName(String gatewayName) { + this.gatewayName = gatewayName; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public String getHealthStatusReason() { + return healthStatusReason; + } + + public void setHealthStatusReason(String healthStatusReason) { + this.healthStatusReason = healthStatusReason; + } + + public boolean isChap() { + return isChap; + } + + public void setChap(boolean chap) { + isChap = chap; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean enabled) { + isEnabled = enabled; + } + + public int getLunCount() { + return lunCount; + } + + public void setLunCount(int lunCount) { + this.lunCount = lunCount; + } + + public int getNodeCount() { + return nodeCount; + } + + public void setNodeCount(int nodeCount) { + this.nodeCount = nodeCount; + } + + public int getQueueDepth() { + return queueDepth; + } + + public void setQueueDepth(int queueDepth) { + this.queueDepth = queueDepth; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public String getTianshuClusterName() { + return tianshuClusterName; + } + + public void setTianshuClusterName(String tianshuClusterName) { + this.tianshuClusterName = tianshuClusterName; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetServerRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetServerRequest.java new file mode 100644 index 00000000000..d71655411ac --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetServerRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{tianshuId}/server", + method = HttpMethod.GET, + responseClass = QueryIscsiClientGroupResponse.class, + sync = false +) +public class GetIscsiTargetServerRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String tianshuId; + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getTianshuId() { + return tianshuId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetServerResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetServerResponse.java new file mode 100644 index 00000000000..27349f60a45 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetIscsiTargetServerResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetIscsiTargetServerResponse extends ExponResponse { + List nodes; + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public List getNodes() { + return nodes; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetSnapshotsInIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetSnapshotsInIscsiClientGroupRequest.java new file mode 100644 index 00000000000..0955e67d411 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetSnapshotsInIscsiClientGroupRequest.java @@ -0,0 +1,34 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}/snapshots", + method = HttpMethod.GET, + responseClass = GetSnapshotsInIscsiClientGroupResponse.class +) +public class GetSnapshotsInIscsiClientGroupRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetSnapshotsInIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetSnapshotsInIscsiClientGroupResponse.java new file mode 100644 index 00000000000..57942eba163 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetSnapshotsInIscsiClientGroupResponse.java @@ -0,0 +1,26 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetSnapshotsInIscsiClientGroupResponse extends ExponResponse { + private List luns; + private int count; + + public List getLuns() { + return luns; + } + + public void setLuns(List luns) { + this.luns = luns; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumeBoundIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumeBoundIscsiClientGroupRequest.java new file mode 100644 index 00000000000..dd64f15c2d7 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumeBoundIscsiClientGroupRequest.java @@ -0,0 +1,36 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/block/volumes/{volumeId}/clients", + method = HttpMethod.GET, + responseClass = GetVolumeBoundIscsiClientGroupResponse.class, + sync = false +) +public class GetVolumeBoundIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String volumeId; + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public String getVolumeId() { + return volumeId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumeBoundIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumeBoundIscsiClientGroupResponse.java new file mode 100644 index 00000000000..8b0baa587ce --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumeBoundIscsiClientGroupResponse.java @@ -0,0 +1,55 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + + +/** + * @example { + * "clients": [{ + * "chap_username": "", + * "create_time": 1705314720041, + * "description": "", + * "id": "413f59f4-90ae-4ee7-9388-07065d25bd3e", + * "is_chap": false, + * "is_readonly": false, + * "name": "iscsi_zstack_heartbeat", + * "node_num": 3, + * "update_time": 1708411159610, + * "volume_id": "40b388e3-c7ee-4c44-bed9-6d4b88088f8f" + * }], + * "count": 1, + * "message": "", + * "ret_code": "0", + * "total": 1 + * } + */ +public class GetVolumeBoundIscsiClientGroupResponse extends ExponResponse { + private int count; + private int total; + private List clients; + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumesInIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumesInIscsiClientGroupRequest.java new file mode 100644 index 00000000000..e0920ceb486 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumesInIscsiClientGroupRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponParam; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients/{id}/luns", + method = HttpMethod.GET, + responseClass = GetVolumesInIscsiClientGroupResponse.class +) +public class GetVolumesInIscsiClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumesInIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumesInIscsiClientGroupResponse.java new file mode 100644 index 00000000000..5e94d3edc07 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/GetVolumesInIscsiClientGroupResponse.java @@ -0,0 +1,26 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetVolumesInIscsiClientGroupResponse extends ExponResponse { + private List luns; + private int count; + + public List getLuns() { + return luns; + } + + public void setLuns(List luns) { + this.luns = luns; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiBoundUssGatewayRefModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiBoundUssGatewayRefModule.java new file mode 100644 index 00000000000..d3d07dd643c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiBoundUssGatewayRefModule.java @@ -0,0 +1,92 @@ +package org.zstack.expon.sdk.iscsi; + +/** + * {@code @example:{ + * "create_time": 1658053009572, + * "gateway_ip": "10.1.28.108", + * "health_status": "health", + * "health_status_reason": "", + * "iscsi_gw_id": "db63d92f-8e00-444a-9d52-6a8fa5ae6f3f", + * "manager_ip": "10.1.22.108", + * "name": "node108", + * "node_id": "17c35f03-40e4-40e9-b92a-000045df0570", + * "pg_tag": 14, + * "port": 3260, + * "server_id": "7a471b9a-96df-47f2-bdcd-0799c956de13", + * "update_time": 1658055193723, + * "uss_gw_id": "80ba4d41-95df-464e-b8f8-2d1df37eeeb1", + * "uss_id": "17" + * }} + */ +public class IscsiBoundUssGatewayRefModule { + private String name; + private String managerIp; + private String gatewayIp; + private int port; + private String serverId; + private String nodeId; + private String iscsiGwId; + private String healthStatus; + private String healthStatusReason; + private int pgTag; + private String ussGwId; + private String ussId; + private long createTime; + private long updateTime; + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getCreateTime() { + return createTime; + } + + public void setGatewayIp(String gatewayIp) { + this.gatewayIp = gatewayIp; + } + + public String getGatewayIp() { + return gatewayIp; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatusReason(String healthStatusReason) { + this.healthStatusReason = healthStatusReason; + } + + public String getHealthStatusReason() { + return healthStatusReason; + } + + public void setIscsiGwId(String iscsiGwId) { + this.iscsiGwId = iscsiGwId; + } + + public String getIscsiGwId() { + return iscsiGwId; + } + + public void setManagerIp(String managerIp) { + this.managerIp = managerIp; + } + + public String getManagerIp() { + return managerIp; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClient.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClient.java new file mode 100644 index 00000000000..d6a67d42938 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClient.java @@ -0,0 +1,26 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.externalStorage.sdk.Param; + +public class IscsiClient { + @Param(validValues = {"ip"}) + private String hostType; + @Param + private String host; + + public String getHostType() { + return hostType; + } + + public void setHostType(String hostType) { + this.hostType = hostType; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClientGroupModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClientGroupModule.java new file mode 100644 index 00000000000..d3e34a17ee4 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClientGroupModule.java @@ -0,0 +1,179 @@ +package org.zstack.expon.sdk.iscsi; + +import java.util.List; + +/** + * @example + * { + * "audit_result": "consistent", + * "audit_result_reason": "", + * "chap_password": "", + * "chap_username": "", + * "client_name": "iscsi_172_25_16_110", + * "client_node_count": 1, + * "create_from": "csm", + * "create_time": 1700498026144, + * "description": "", + * "hosts": ["iqn.1994-05.com.redhat:b31a3f136997"], + * "id": "90b745ad-7e2a-410d-9146-1ca15dd095b6", + * "ig_id": 7, + * "iqn_prefix": null, + * "is_chap": false, + * "iscsi_gw_count": 1, + * "lun_count": 0, + * "name": "iscsi_172_25_16_110", + * "run_status": "normal", + * "snap_num": 0, + * "tianshu_id": "5e59b7ef-e599-4847-8ab5-f1eb727f2e90", + * "tianshu_name": "qRJbA", + * "update_time": 1700498031024, + * "vol_num": 0 + * } + */ + +public class IscsiClientGroupModule { + private String id; + private String name; + private String description; + private List hosts; + private String runStatus; + private int volNum; + private int snapNum; + private String auditResult; + private String auditResultReason; + private int iscsiGwCount; + private int clientNodeCount; + private String createFrom; + private String tianshuId; + private String tianshuName; + private long createTime; + private long updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public int getVolNum() { + return volNum; + } + + public void setVolNum(int volNum) { + this.volNum = volNum; + } + + public int getSnapNum() { + return snapNum; + } + + public void setSnapNum(int snapNum) { + this.snapNum = snapNum; + } + + public String getAuditResult() { + return auditResult; + } + + public void setAuditResult(String auditResult) { + this.auditResult = auditResult; + } + + public String getAuditResultReason() { + return auditResultReason; + } + + public void setAuditResultReason(String auditResultReason) { + this.auditResultReason = auditResultReason; + } + + public int getiscsiGwCount() { + return iscsiGwCount; + } + + public void setiscsiGwCount(int iscsiGwCount) { + this.iscsiGwCount = iscsiGwCount; + } + + public int getClientNodeCount() { + return clientNodeCount; + } + + public void setClientNodeCount(int clientNodeCount) { + this.clientNodeCount = clientNodeCount; + } + + public String getCreateFrom() { + return createFrom; + } + + public void setCreateFrom(String createFrom) { + this.createFrom = createFrom; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getTianshuName() { + return tianshuName; + } + + public void setTianshuName(String tianshuName) { + this.tianshuName = tianshuName; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClientMappedLunModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClientMappedLunModule.java new file mode 100644 index 00000000000..a855c9c74d5 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiClientMappedLunModule.java @@ -0,0 +1,86 @@ +package org.zstack.expon.sdk.iscsi; + +/** + * @example { + * "cap_health_status": "health", + * "cap_health_status_reason": "", + * "client_id": "bdec2cad-cac1-4c38-8ce9-8e8d78232d15", + * "create_time": 1705473244611, + * "data_size": 0, + * "delete_time": null, + * "description": "", + * "id": "41f0edc2-79e1-4e81-add3-2950110b23d8", + * "io_priority": "default", + * "is_delete": false, + * "is_readonly": false, + * "iscsi_gw_id": "fcdea7d0-5200-4f14-b326-6ee8e2bc53dd", + * "name": "test", + * "perf_health_status": "health", + * "perf_health_status_reason": "", + * "pool_name": "pool", + * "qos_status": false, + * "run_status": "normal", + * "update_time": 1705567347995, + * "use_status": "offline", + * "verify_enabled": false, + * "volume_name": "volume-687d4349-3c73-4c23-9a0f-c5836b6beb1e", + * "volume_size": 1073741824, + * "volume_type": "normal_volume" + * } + */ +public class IscsiClientMappedLunModule { + private String id; + private String name; + private String description; + private String volumeName; + private String poolName; + private String iscsiGwId; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVolumeName() { + return volumeName; + } + + public void setVolumeName(String volumeName) { + this.volumeName = volumeName; + } + + public String getPoolName() { + return poolName; + } + + public void setPoolName(String poolName) { + this.poolName = poolName; + } + + public String getIscsiGwId() { + return iscsiGwId; + } + + public void setIscsiGwId(String iscsiGwId) { + this.iscsiGwId = iscsiGwId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiModule.java new file mode 100644 index 00000000000..351603d6c24 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiModule.java @@ -0,0 +1,241 @@ +package org.zstack.expon.sdk.iscsi; + + +/** + * @example + * { + * "chap_password": "", + * "chap_username": "", + * "client_count": 0, + * "client_ids": "", + * "create_time": 1657866241243, + * "description": "", + * "gateway_name": "gw1", + * "health_status": "health", + * "health_status_reason": "", + * "id": "67b7fe91-cb05-4b64-ae1b-5a513945ee34", + * "iqn": "iqn.2022-07.com.expontech.wds:742889ee8614", + * "is_chap": false, + * "is_enabled": true, + * "lun_count": 0, + * "name": "gw1", + * "node_count": 1, + * "port": 3260, + * "queue_depth": 512, + * "run_status": "normal", + * "tianshu_cluster_name": "tianshu", + * "tianshu_id": "7a2be52e-745b-44d6-b2ac-08dc42fb00f7", + * "update_time": 1657867417674, + * "vendor": "ET_WDS" + * } + */ +public class IscsiModule { + private String id; + private String name; + private String description; + private long createTime; + private long updateTime; + private String iqn; + private int port; + private String chapPassword; + private String chapUsername; + private int clientCount; + private String clientIds; + + private String gatewayName; + private String healthStatus; + private String healthStatusReason; + private boolean isChap; + private boolean isEnabled; + private int lunCount; + private int nodeCount; + private int queueDepth; + private String runStatus; + private String tianshuClusterName; + private String tianshuId; + private String vendor; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } + + public String getIqn() { + return iqn; + } + + public void setIqn(String iqn) { + this.iqn = iqn; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getChapPassword() { + return chapPassword; + } + + public void setChapPassword(String chapPassword) { + this.chapPassword = chapPassword; + } + + public String getChapUsername() { + return chapUsername; + } + + public void setChapUsername(String chapUsername) { + this.chapUsername = chapUsername; + } + + public int getClientCount() { + return clientCount; + } + + public void setClientCount(int clientCount) { + this.clientCount = clientCount; + } + + public String getClientIds() { + return clientIds; + } + + public void setClientIds(String clientIds) { + this.clientIds = clientIds; + } + + public String getGatewayName() { + return gatewayName; + } + + public void setGatewayName(String gatewayName) { + this.gatewayName = gatewayName; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public String getHealthStatusReason() { + return healthStatusReason; + } + + public void setHealthStatusReason(String healthStatusReason) { + this.healthStatusReason = healthStatusReason; + } + + public boolean isChap() { + return isChap; + } + + public void setChap(boolean chap) { + isChap = chap; + } + + public boolean isEnabled() { + return isEnabled; + } + + public void setEnabled(boolean enabled) { + isEnabled = enabled; + } + + public int getLunCount() { + return lunCount; + } + + public void setLunCount(int lunCount) { + this.lunCount = lunCount; + } + + public int getNodeCount() { + return nodeCount; + } + + public void setNodeCount(int nodeCount) { + this.nodeCount = nodeCount; + } + + public int getQueueDepth() { + return queueDepth; + } + + public void setQueueDepth(int queueDepth) { + this.queueDepth = queueDepth; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public String getTianshuClusterName() { + return tianshuClusterName; + } + + public void setTianshuClusterName(String tianshuClusterName) { + this.tianshuClusterName = tianshuClusterName; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiSeverNode.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiSeverNode.java new file mode 100644 index 00000000000..44dbe0e0073 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiSeverNode.java @@ -0,0 +1,77 @@ +package org.zstack.expon.sdk.iscsi; + +/** + * @example + *{"gateway_ip": "172.26.12.22", + * "manager_ip": "172.25.12.22", + * "name": "172-25-12-22", + * "server_id": "12eb6291-c928-4439-91b5-968c8ebd418a", + * "tianshu_id": "5e59b7ef-e599-4847-8ab5-f1eb727f2e90", + * "uss_gw_id": "e06c9f5a-d18f-4531-91f2-b940a98d047c", + * "uss_name": "iscsi_zstack"} + */ +public class IscsiSeverNode { + private String gatewayIp; + private String managerIp; + private String name; + private String serverId; + private String tianshuId; + private String ussGwId; + private String ussName; + + public String getGatewayIp() { + return gatewayIp; + } + + public void setGatewayIp(String gatewayIp) { + this.gatewayIp = gatewayIp; + } + + public String getManagerIp() { + return managerIp; + } + + public void setManagerIp(String managerIp) { + this.managerIp = managerIp; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getServerId() { + return serverId; + } + + public void setServerId(String serverId) { + this.serverId = serverId; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getUssGwId() { + return ussGwId; + } + + public void setUssGwId(String ussGwId) { + this.ussGwId = ussGwId; + } + + public String getUssName() { + return ussName; + } + + public void setUssName(String ussName) { + this.ussName = ussName; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiUssResource.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiUssResource.java new file mode 100644 index 00000000000..709bf60d62a --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/IscsiUssResource.java @@ -0,0 +1,40 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.externalStorage.sdk.Param; + +import java.util.List; +import java.util.stream.Collectors; + +public class IscsiUssResource { + @Param + private String serverId; + @Param + private String gatewayIp; + + public String getServerId() { + return serverId; + } + + public void setServerId(String serverId) { + this.serverId = serverId; + } + + public String getGatewayIp() { + return gatewayIp; + } + + public void setGatewayIp(String gatewayIp) { + this.gatewayIp = gatewayIp; + } + + public static IscsiUssResource valueOf(IscsiSeverNode node) { + IscsiUssResource resource = new IscsiUssResource(); + resource.setServerId(node.getServerId()); + resource.setGatewayIp(node.getGatewayIp()); + return resource; + } + + public static List valueOf(List nodes) { + return nodes.stream().map(IscsiUssResource::valueOf).collect(Collectors.toList()); + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/LunBoundIscsiClientGroupModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/LunBoundIscsiClientGroupModule.java new file mode 100644 index 00000000000..47ae6b6516b --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/LunBoundIscsiClientGroupModule.java @@ -0,0 +1,108 @@ +package org.zstack.expon.sdk.iscsi; + +/** + * @example { + * "chap_username": "", + * "create_time": 1705314720041, + * "description": "", + * "id": "413f59f4-90ae-4ee7-9388-07065d25bd3e", + * "is_chap": false, + * "is_readonly": false, + * "name": "iscsi_zstack_heartbeat", + * "node_num": 3, + * "update_time": 1708411159610, + * "volume_id": "40b388e3-c7ee-4c44-bed9-6d4b88088f8f" + * } + */ +public class LunBoundIscsiClientGroupModule { + private String id; + private String name; + private String description; + private String volumeId; + private boolean isChap; + private boolean isReadonly; + private String chapUsername; + private int nodeNum; + private long createTime; + private long updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public boolean isChap() { + return isChap; + } + + public void setChap(boolean chap) { + isChap = chap; + } + + public boolean isReadonly() { + return isReadonly; + } + + public void setReadonly(boolean readonly) { + isReadonly = readonly; + } + + public String getChapUsername() { + return chapUsername; + } + + public void setChapUsername(String chapUsername) { + this.chapUsername = chapUsername; + } + + public int getNodeNum() { + return nodeNum; + } + + public void setNodeNum(int nodeNum) { + this.nodeNum = nodeNum; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiClientGroupRequest.java new file mode 100644 index 00000000000..1714d4d670f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiClientGroupRequest.java @@ -0,0 +1,23 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/clients", + method = HttpMethod.GET, + responseClass = QueryIscsiClientGroupResponse.class, + sync = false +) +public class QueryIscsiClientGroupRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiClientGroupResponse.java new file mode 100644 index 00000000000..969634e8653 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiClientGroupResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryIscsiClientGroupResponse extends ExponQueryResponse { + private List clients; + + public void setClients(List clients) { + this.clients = clients; + } + + public List getClients() { + return clients; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiTargetRequest.java new file mode 100644 index 00000000000..0ee21453c64 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiTargetRequest.java @@ -0,0 +1,22 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; +@ExponRestRequest( + path = "/block/iscsi/gateways", + method = HttpMethod.GET, + responseClass = QueryIscsiTargetResponse.class, + sync = true +) +public class QueryIscsiTargetRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiTargetResponse.java new file mode 100644 index 00000000000..f60869eed89 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/QueryIscsiTargetResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryIscsiTargetResponse extends ExponQueryResponse { + private List gateways; + + public List getGateways() { + return gateways; + } + + public void setGateways(List gateways) { + this.gateways = gateways; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/RemoveIscsiClientGroupFromIscsiTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/RemoveIscsiClientGroupFromIscsiTargetRequest.java new file mode 100644 index 00000000000..f4ce8bf60a2 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/RemoveIscsiClientGroupFromIscsiTargetRequest.java @@ -0,0 +1,56 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponAction; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}/remove_clients", + method = HttpMethod.PUT, + responseClass = RemoveIscsiClientGroupFromIscsiTargetResponse.class +) +public class RemoveIscsiClientGroupFromIscsiTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + @Param + private String action = ExponAction.remove.name(); + @Param + private List clients; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/RemoveIscsiClientGroupFromIscsiTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/RemoveIscsiClientGroupFromIscsiTargetResponse.java new file mode 100644 index 00000000000..2597d29f2b9 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/RemoveIscsiClientGroupFromIscsiTargetResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class RemoveIscsiClientGroupFromIscsiTargetResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/UnbindIscsiTargetFromUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/UnbindIscsiTargetFromUssRequest.java new file mode 100644 index 00000000000..23e677c472f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/UnbindIscsiTargetFromUssRequest.java @@ -0,0 +1,54 @@ +package org.zstack.expon.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/iscsi/gateways/{id}/remove_nodes", + method = HttpMethod.PUT, + responseClass = UnbindIscsiTargetFromUssResponse.class +) +public class UnbindIscsiTargetFromUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String id; + @Param + private List nodes; + @Param + private boolean force; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/UnbindIscsiTargetFromUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/UnbindIscsiTargetFromUssResponse.java new file mode 100644 index 00000000000..c684e0df809 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/iscsi/UnbindIscsiTargetFromUssResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.iscsi; + +import org.zstack.expon.sdk.ExponResponse; + +public class UnbindIscsiTargetFromUssResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/AddNvmeClientGroupToNvmfTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/AddNvmeClientGroupToNvmfTargetRequest.java new file mode 100644 index 00000000000..b230d0ea019 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/AddNvmeClientGroupToNvmfTargetRequest.java @@ -0,0 +1,56 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponAction; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf/{gatewayId}/add_clients", + method = HttpMethod.PUT, + responseClass = AddNvmeClientGroupToNvmfTargetResponse.class +) +public class AddNvmeClientGroupToNvmfTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String action = ExponAction.add.name(); + @Param + private List clients; + @Param + private String gatewayId; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } + + public String getGatewayId() { + return gatewayId; + } + + public void setGatewayId(String gatewayId) { + this.gatewayId = gatewayId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/AddNvmeClientGroupToNvmfTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/AddNvmeClientGroupToNvmfTargetResponse.java new file mode 100644 index 00000000000..69eb9890581 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/AddNvmeClientGroupToNvmfTargetResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class AddNvmeClientGroupToNvmfTargetResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/BindNvmfTargetToUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/BindNvmfTargetToUssRequest.java new file mode 100644 index 00000000000..01e95231f79 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/BindNvmfTargetToUssRequest.java @@ -0,0 +1,54 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf/bind_uss", + method = HttpMethod.PUT, + responseClass = BindNvmfTargetToUssResponse.class +) +public class BindNvmfTargetToUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String nvmfId; + @Param + private int port; + @Param + private List ussGwId; + + public String getNvmfId() { + return nvmfId; + } + + public void setNvmfId(String nvmfId) { + this.nvmfId = nvmfId; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public List getUssGwId() { + return ussGwId; + } + + public void setUssGwId(List ussGwId) { + this.ussGwId = ussGwId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/BindNvmfTargetToUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/BindNvmfTargetToUssResponse.java new file mode 100644 index 00000000000..bd3888d3a31 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/BindNvmfTargetToUssResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class BindNvmfTargetToUssResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeNvmeClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeNvmeClientGroupRequest.java new file mode 100644 index 00000000000..dd092c4c8f8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeNvmeClientGroupRequest.java @@ -0,0 +1,55 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf_client/{clientId}/hosts", + method = HttpMethod.PUT, + responseClass = ChangeNvmeClientGroupResponse.class +) +public class ChangeNvmeClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String clientId; + @Param(validValues = {"add", "remove"}) + private String action; + @Param + private List hosts; + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeNvmeClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeNvmeClientGroupResponse.java new file mode 100644 index 00000000000..b9539b7eebd --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeNvmeClientGroupResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class ChangeNvmeClientGroupResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeVolumeInNvmfClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeVolumeInNvmfClientGroupRequest.java new file mode 100644 index 00000000000..aa2c1de865f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeVolumeInNvmfClientGroupRequest.java @@ -0,0 +1,67 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.expon.sdk.volume.LunResource; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf_client/{clientId}/luns", + method = HttpMethod.PUT, + responseClass = ChangeVolumeInNvmfClientGroupResponse.class +) +public class ChangeVolumeInNvmfClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String clientId; + @Param(validValues = {"add", "remove"}) + private String action; + @Param + private List luns; + @Param(required = false) + private List gateways; + + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getLuns() { + return luns; + } + + public void setLuns(List luns) { + this.luns = luns; + } + + public void setGateways(List gateways) { + this.gateways = gateways; + } + + public List getGateways() { + return gateways; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeVolumeInNvmfClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeVolumeInNvmfClientGroupResponse.java new file mode 100644 index 00000000000..817279607b4 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/ChangeVolumeInNvmfClientGroupResponse.java @@ -0,0 +1,7 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class ChangeVolumeInNvmfClientGroupResponse extends ExponResponse { + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfClientGroupRequest.java new file mode 100644 index 00000000000..efe4f301f06 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfClientGroupRequest.java @@ -0,0 +1,66 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf_client", + method = HttpMethod.POST, + responseClass = CreateNvmfClientGroupResponse.class +) +public class CreateNvmfClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + @Param(required = false) + private String description; + @Param + private String tianshuId; + + @Param + private List hosts; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfClientGroupResponse.java new file mode 100644 index 00000000000..f0962844e93 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfClientGroupResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponSyncCreateResponse; + +public class CreateNvmfClientGroupResponse extends ExponSyncCreateResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfTargetRequest.java new file mode 100644 index 00000000000..c22691ddf31 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfTargetRequest.java @@ -0,0 +1,54 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf", + method = HttpMethod.POST, + responseClass = CreateNvmfTargetResponse.class +) +public class CreateNvmfTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + @Param + private String nqn; + @Param + private String tianshuId; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNqn() { + return nqn; + } + + public void setNqn(String nqn) { + this.nqn = nqn; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfTargetResponse.java new file mode 100644 index 00000000000..92071e2c424 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/CreateNvmfTargetResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponSyncCreateResponse; + +public class CreateNvmfTargetResponse extends ExponSyncCreateResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfClientGroupRequest.java new file mode 100644 index 00000000000..65b599e812c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfClientGroupRequest.java @@ -0,0 +1,34 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf_client/{clientId}", + method = HttpMethod.DELETE, + responseClass = CreateNvmfClientGroupResponse.class +) +public class DeleteNvmfClientGroupRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String clientId; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientId() { + return clientId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfClientGroupResponse.java new file mode 100644 index 00000000000..a93ad491d0a --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfClientGroupResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteNvmfClientGroupResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfTargetRequest.java new file mode 100644 index 00000000000..9edb1d1715e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfTargetRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf/{nvmfId}", + method = HttpMethod.DELETE, + responseClass = CreateNvmfTargetResponse.class +) +public class DeleteNvmfTargetRequest extends ExponRequest { + + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String nvmfId; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public void setNvmfId(String nvmfId) { + this.nvmfId = nvmfId; + } + + public String getNvmfId() { + return nvmfId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfTargetResponse.java new file mode 100644 index 00000000000..99263cad170 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/DeleteNvmfTargetResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteNvmfTargetResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/GetNvmfTargetBoundUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/GetNvmfTargetBoundUssRequest.java new file mode 100644 index 00000000000..7dd6a025001 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/GetNvmfTargetBoundUssRequest.java @@ -0,0 +1,38 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.expon.sdk.volume.GetVolumeResponse; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf/{nvmfId}/nvmf_binded_uss", + method = HttpMethod.GET, + responseClass = GetVolumeResponse.class, + sync = false +) +public class GetNvmfTargetBoundUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String nvmfId; + + + public String getNvmfId() { + return nvmfId; + } + + public void setNvmfId(String nvmfId) { + this.nvmfId = nvmfId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/GetNvmfTargetBoundUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/GetNvmfTargetBoundUssResponse.java new file mode 100644 index 00000000000..680c4b2131d --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/GetNvmfTargetBoundUssResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetNvmfTargetBoundUssResponse extends ExponResponse { + private List result; + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfBoundUssGatewayRefModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfBoundUssGatewayRefModule.java new file mode 100644 index 00000000000..4d3f93701d8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfBoundUssGatewayRefModule.java @@ -0,0 +1,94 @@ +package org.zstack.expon.sdk.nvmf; + +/** + * {@code @example:{ + * "bind_ip": "172.26.12.90", + * "bind_port": 4421, + * "business_network": "172.27.12.90/16", + * "business_port": 9000, + * "core": "0xf0", + * "create_time": 1698735992254, + * "domain_name": "172.27.29.66:8082", + * "id": "8fb252ff-da4d-4cfd-a36b-262d9f742a54", + * "manager_ip": "172.25.12.90", + * "name": "test", + * "nqn": "nqn.2023-10.com.sds.wds:test", + * "nvmf_id": "746c817c-acfa-418f-88d2-d5eb39fc5cab", + * "protocol": "NVMe-oF", + * "protocol_network": "TCP", + * "server_name": "172-25-12-90", + * "server_no": 1, + * "sn": "SDS9a5e66a3", + * "specification": "standard", + * "status": "health", + * "tianshu_id": "e4aba79c-ff0d-4e21-adbc-159f74226377", + * "tianshu_name": "tianshu", + * "update_time": 1698735992254, + * "uss_gw_id": "cae6f136-69b3-4d83-ae64-04cb38e27312", + * "uss_id": "1", + * "uss_name": "nvmf_zstack", + * "vendor": "SDS" + * }} + */ +public class NvmfBoundUssGatewayRefModule { + private String id; + private String name; + private String protocol; + private String managerIp; + private String bindIp; + private Integer bindPort; + private String businessNetwork; + private Integer businessPort; + private String serverName; + private String ussGwId; + private String ussName; + private String nvmfId; + + public String getNvmfId() { + return nvmfId; + } + + public void setNvmfId(String nvmfId) { + this.nvmfId = nvmfId; + } + + public String getUssGwId() { + return ussGwId; + } + + public void setUssGwId(String ussGwId) { + this.ussGwId = ussGwId; + } + + public String getUssName() { + return ussName; + } + + public void setUssName(String ussName) { + this.ussName = ussName; + } + + public String getBusinessNetwork() { + return businessNetwork; + } + + public void setBusinessNetwork(String businessNetwork) { + this.businessNetwork = businessNetwork; + } + + public Integer getBusinessPort() { + return businessPort; + } + + public void setBusinessPort(Integer businessPort) { + this.businessPort = businessPort; + } + + public String getBindIp() { + return bindIp; + } + + public void setBindIp(String bindIp) { + this.bindIp = bindIp; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfClient.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfClient.java new file mode 100644 index 00000000000..6da9bca04ce --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfClient.java @@ -0,0 +1,22 @@ +package org.zstack.expon.sdk.nvmf; + +public class NvmfClient { + private String hostType; + private String host; + + public String getHostType() { + return hostType; + } + + public void setHostType(String hostType) { + this.hostType = hostType; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfClientGroupModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfClientGroupModule.java new file mode 100644 index 00000000000..46afb99af02 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfClientGroupModule.java @@ -0,0 +1,185 @@ +package org.zstack.expon.sdk.nvmf; + +import java.util.List; + +/** + * @example + * { + * "audit_result": "consistent", + * "audit_result_reason": "", + * "client_node_count": 2, + * "create_from": "csm", + * "create_time": 1692330357308, + * "description": "", + * "hg_id": 2, + * "hosts": [ + * "nqn.2021-05.com.domain:796b81929e1", + * "nqn.2021-05.com.domain:796b81929e4" + * ], + * "id": "a484930c-d8f7-4a70-80cc-bec0bf6a90b0", + * "name": "ttt", + * "nvmf_gw_count": 1, + * "run_status": "normal", + * "snap_num": 0, + * "tianshu_id": "2f2efcde-87bb-42fc-a558-6cec67432965", + * "tianshu_name": "ts", + * "update_time": 1692928700632, + * "vol_num": 0 + * } + */ + +public class NvmfClientGroupModule { + private String id; + private String name; + private String description; + private List hosts; + private String runStatus; + private int volNum; + private int snapNum; + private String auditResult; + private String auditResultReason; + private int nvmfGwCount; + private int clientNodeCount; + private String createFrom; + private String hgId; + private String tianshuId; + private String tianshuName; + private long createTime; + private long updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public int getVolNum() { + return volNum; + } + + public void setVolNum(int volNum) { + this.volNum = volNum; + } + + public int getSnapNum() { + return snapNum; + } + + public void setSnapNum(int snapNum) { + this.snapNum = snapNum; + } + + public String getAuditResult() { + return auditResult; + } + + public void setAuditResult(String auditResult) { + this.auditResult = auditResult; + } + + public String getAuditResultReason() { + return auditResultReason; + } + + public void setAuditResultReason(String auditResultReason) { + this.auditResultReason = auditResultReason; + } + + public int getNvmfGwCount() { + return nvmfGwCount; + } + + public void setNvmfGwCount(int nvmfGwCount) { + this.nvmfGwCount = nvmfGwCount; + } + + public int getClientNodeCount() { + return clientNodeCount; + } + + public void setClientNodeCount(int clientNodeCount) { + this.clientNodeCount = clientNodeCount; + } + + public String getCreateFrom() { + return createFrom; + } + + public void setCreateFrom(String createFrom) { + this.createFrom = createFrom; + } + + public String getHgId() { + return hgId; + } + + public void setHgId(String hgId) { + this.hgId = hgId; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getTianshuName() { + return tianshuName; + } + + public void setTianshuName(String tianshuName) { + this.tianshuName = tianshuName; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfModule.java new file mode 100644 index 00000000000..56d17688800 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/NvmfModule.java @@ -0,0 +1,60 @@ +package org.zstack.expon.sdk.nvmf; + + +/** + * @example + * { + * "id": "e209db89-992c-4a1d-a4d4-303efd78d2df", + * "name": "nvmf_1", + * "nqn": "nqn.2022-03.com.sds.wds:nvmf", + * "sn": "ETWDS34aac3e7", + * "vendor": "ET_WDS" + * } + */ +public class NvmfModule { + private String id; + private String name; + private String nqn; + private String sn; + private String vendor; + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getNqn() { + return nqn; + } + + public String getSn() { + return sn; + } + + public String getVendor() { + return vendor; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setNqn(String nqn) { + this.nqn = nqn; + } + + public void setSn(String sn) { + this.sn = sn; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfClientGroupRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfClientGroupRequest.java new file mode 100644 index 00000000000..842fc743110 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfClientGroupRequest.java @@ -0,0 +1,23 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf_client/", + method = HttpMethod.GET, + responseClass = QueryNvmfClientGroupResponse.class, + sync = true +) +public class QueryNvmfClientGroupRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfClientGroupResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfClientGroupResponse.java new file mode 100644 index 00000000000..95a31c8e327 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfClientGroupResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryNvmfClientGroupResponse extends ExponQueryResponse { + private List clients; + + public void setClients(List clients) { + this.clients = clients; + } + + public List getClients() { + return clients; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfTargetRequest.java new file mode 100644 index 00000000000..96372e0dd22 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfTargetRequest.java @@ -0,0 +1,22 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; +@ExponRestRequest( + path = "/block/nvmf", + method = HttpMethod.GET, + responseClass = QueryNvmfTargetResponse.class, + sync = true +) +public class QueryNvmfTargetRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfTargetResponse.java new file mode 100644 index 00000000000..81845e5d098 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/QueryNvmfTargetResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryNvmfTargetResponse extends ExponQueryResponse { + private List nvmfs; + + public List getNvmfs() { + return nvmfs; + } + + public void setNvmfs(List nvmfs) { + this.nvmfs = nvmfs; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/RemoveNvmeClientGroupFromNvmfTargetRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/RemoveNvmeClientGroupFromNvmfTargetRequest.java new file mode 100644 index 00000000000..7247f0a2ce9 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/RemoveNvmeClientGroupFromNvmfTargetRequest.java @@ -0,0 +1,56 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponAction; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf/{gatewayId}/remove_clients", + method = HttpMethod.PUT, + responseClass = RemoveNvmeClientGroupFromNvmfTargetResponse.class +) +public class RemoveNvmeClientGroupFromNvmfTargetRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String action = ExponAction.remove.name(); + @Param + private List clients; + @Param + private String gatewayId; + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public List getClients() { + return clients; + } + + public void setClients(List clients) { + this.clients = clients; + } + + public String getGatewayId() { + return gatewayId; + } + + public void setGatewayId(String gatewayId) { + this.gatewayId = gatewayId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/RemoveNvmeClientGroupFromNvmfTargetResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/RemoveNvmeClientGroupFromNvmfTargetResponse.java new file mode 100644 index 00000000000..1cdb7da7bdd --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/RemoveNvmeClientGroupFromNvmfTargetResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class RemoveNvmeClientGroupFromNvmfTargetResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/UnbindNvmfTargetFromUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/UnbindNvmfTargetFromUssRequest.java new file mode 100644 index 00000000000..50071b8296c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/UnbindNvmfTargetFromUssRequest.java @@ -0,0 +1,44 @@ +package org.zstack.expon.sdk.nvmf; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ExponRestRequest( + path = "/block/nvmf/unbind_uss", + method = HttpMethod.PUT, + responseClass = UnbindNvmfTargetFromUssResponse.class +) +public class UnbindNvmfTargetFromUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String nvmfId; + @Param + private List ussGwId; + + public String getNvmfId() { + return nvmfId; + } + + public void setNvmfId(String nvmfId) { + this.nvmfId = nvmfId; + } + + public void setUssGwId(List ussGwId) { + this.ussGwId = ussGwId; + } + + public List getUssGwId() { + return ussGwId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/UnbindNvmfTargetFromUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/UnbindNvmfTargetFromUssResponse.java new file mode 100644 index 00000000000..8ef6cc46050 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/nvmf/UnbindNvmfTargetFromUssResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.nvmf; + +import org.zstack.expon.sdk.ExponResponse; + +public class UnbindNvmfTargetFromUssResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/BlacklistModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/BlacklistModule.java new file mode 100644 index 00000000000..eb57c276da4 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/BlacklistModule.java @@ -0,0 +1,128 @@ +package org.zstack.expon.sdk.pool; + +/** + * @example { + * "clone_id": 0, + * "expire_time": 0, + * "nid": 1, + * "path": "10.1.107.48:9001/13/VOLUME/volume-5fa313cc-8da4-4212-9605-5a6b8e3ba917", + * "snap_id": 0, + * "tree_id": 1, + * "type": "VOLUME", + * "uss_id": 13, + * "uss_ip": "10.1.107.48", + * "uss_port": 9001, + * "vol_namespace": "ussns", + * "volname": "volume-5fa313cc-8da4-4212-9605-5a6b8e3ba917" + * } + */ +public class BlacklistModule { + private String cloneId; + private String expireTime; + private String nid; + private String path; + private String snapId; + private String treeId; + private String type; + private String ussId; + private String ussIp; + private String ussPort; + private String volNamespace; + private String volname; + + public String getCloneId() { + return cloneId; + } + + public void setCloneId(String cloneId) { + this.cloneId = cloneId; + } + + public String getExpireTime() { + return expireTime; + } + + public void setExpireTime(String expireTime) { + this.expireTime = expireTime; + } + + public String getNid() { + return nid; + } + + public void setNid(String nid) { + this.nid = nid; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getSnapId() { + return snapId; + } + + public void setSnapId(String snapId) { + this.snapId = snapId; + } + + public String getTreeId() { + return treeId; + } + + public void setTreeId(String treeId) { + this.treeId = treeId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUssId() { + return ussId; + } + + public void setUssId(String ussId) { + this.ussId = ussId; + } + + public String getUssIp() { + return ussIp; + } + + public void setUssIp(String ussIp) { + this.ussIp = ussIp; + } + + public String getUssPort() { + return ussPort; + } + + public void setUssPort(String ussPort) { + this.ussPort = ussPort; + } + + public String getVolNamespace() { + return volNamespace; + } + + public void setVolNamespace(String volNamespace) { + this.volNamespace = volNamespace; + } + + public String getVolname() { + return volname; + } + + public void setVolname(String volname) { + this.volname = volname; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/ClearFailureDomainBlacklistRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/ClearFailureDomainBlacklistRequest.java new file mode 100644 index 00000000000..b02c1faba9c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/ClearFailureDomainBlacklistRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.pool; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/failure_domain/black_list/clean", + responseClass = ClearFailureDomainBlacklistResponse.class, + method = HttpMethod.PUT, + sync = false +) +public class ClearFailureDomainBlacklistRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String poolUuid; + + public void setPoolUuid(String poolUuid) { + this.poolUuid = poolUuid; + } + + public String getPoolUuid() { + return poolUuid; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/ClearFailureDomainBlacklistResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/ClearFailureDomainBlacklistResponse.java new file mode 100644 index 00000000000..af26168a4d7 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/ClearFailureDomainBlacklistResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.pool; + +import org.zstack.expon.sdk.ExponResponse; + +public class ClearFailureDomainBlacklistResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/FailureDomainModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/FailureDomainModule.java new file mode 100644 index 00000000000..a0c033cd345 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/FailureDomainModule.java @@ -0,0 +1,208 @@ +package org.zstack.expon.sdk.pool; + + +/** + * @example + * {"cache_data": false, "cache_meta_data": false, "cache_ratio": 0.0, "cap_change_comment": "", "create_time": 1692933406637, "custom_qos": "", + * "data_centers": "DC1", "data_size": 1352663040, + * "db_cache_size": 0, "exclusivity": "", "failure_domain_cache_type": 450887680, "failure_domain_name": "pool", "failure_domain_network": "TCP", + * "failure_domain_type": "SATA_SSD", + * "health_status": "health", "health_status_reason": "", "id": "1ad18b89-6e88-4066-b68f-1bf3d2c440ae", "osd_count": 3, "perf_mode": "normal", + * "physical_pool_type": "local_pool", "pool_id": 1, "pool_uuid": "9a55f8c7-a7fd-46ca-bc10-0c0bdf2370cb", + * "raw_size": 5761150230528, "real_data_size": 450887680, "recovery_strategy": "low", "redundancy_ploy": "replicated", "replicate_size": 3, + * "run_status": "normal", "safe_level": "host", "status": "health", "thin_provisioning": 2, "tianshu_id": "0e780e97-c670-4341-960a-6f223baea940", + * "tianshu_name": "tianshu", "update_time": 1695188453814, "valid_size": 1920383410176} + */ +public class FailureDomainModule { + private String id; + private String failureDomainName; + + private long dataSize; + private long realDataSize; + private long rawSize; + private long validSize; + + private String redundancyPloy; + private int replicateSize; + + private String healthStatus; + private String healthStatusReason; + + private String perfMode; + private String customQos; + private String recoveryStrategy; + private String runStatus; + private String failureDomainNetwork; + + private int osdCount; + + private String tianshuId; + private String tianshuName; + + private long updateTime; + private long createTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFailureDomainName() { + return failureDomainName; + } + + public void setFailureDomainName(String failureDomainName) { + this.failureDomainName = failureDomainName; + } + + public long getDataSize() { + return dataSize; + } + + public void setDataSize(long dataSize) { + this.dataSize = dataSize; + } + + public long getRawSize() { + return rawSize; + } + + public void setRawSize(long rawSize) { + this.rawSize = rawSize; + } + + public long getRealDataSize() { + return realDataSize; + } + + public void setRealDataSize(long realDataSize) { + this.realDataSize = realDataSize; + } + + public String getRedundancyPloy() { + return redundancyPloy; + } + + public void setRedundancyPloy(String redundancyPloy) { + this.redundancyPloy = redundancyPloy; + } + + public int getReplicateSize() { + return replicateSize; + } + + public void setReplicateSize(int replicateSize) { + this.replicateSize = replicateSize; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public String getHealthStatusReason() { + return healthStatusReason; + } + + public void setHealthStatusReason(String healthStatusReason) { + this.healthStatusReason = healthStatusReason; + } + + public String getPerfMode() { + return perfMode; + } + + public void setPerfMode(String perfMode) { + this.perfMode = perfMode; + } + + public String getCustomQos() { + return customQos; + } + + public void setCustomQos(String customQos) { + this.customQos = customQos; + } + + public String getRecoveryStrategy() { + return recoveryStrategy; + } + + public void setRecoveryStrategy(String recoveryStrategy) { + this.recoveryStrategy = recoveryStrategy; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } + + public String getFailureDomainNetwork() { + return failureDomainNetwork; + } + + public void setFailureDomainNetwork(String failureDomainNetwork) { + this.failureDomainNetwork = failureDomainNetwork; + } + + public int getOsdCount() { + return osdCount; + } + + public void setOsdCount(int osdCount) { + this.osdCount = osdCount; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getValidSize() { + return validSize; + } + + public void setValidSize(long validSize) { + this.validSize = validSize; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } + + public long getAvailableCapacity() { + return validSize - realDataSize; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getTianshuName() { + return tianshuName; + } + + public void setTianshuName(String tianshuName) { + this.tianshuName = tianshuName; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainBlacklistRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainBlacklistRequest.java new file mode 100644 index 00000000000..f59eb280873 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainBlacklistRequest.java @@ -0,0 +1,36 @@ +package org.zstack.expon.sdk.pool; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/failure_domain/black_list/{id}", + method = HttpMethod.GET, + responseClass = GetFailureDomainBlacklistResponse.class, + sync = false +) +public class GetFailureDomainBlacklistRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainBlacklistResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainBlacklistResponse.java new file mode 100644 index 00000000000..116fc5c41c8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainBlacklistResponse.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.pool; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetFailureDomainBlacklistResponse extends ExponResponse { + private List entries; + private String poolId; + private String bepoch; + + public List getEntries() { + return entries; + } + + public void setEntries(List entries) { + this.entries = entries; + } + + public String getPoolId() { + return poolId; + } + + public void setPoolId(String poolId) { + this.poolId = poolId; + } + + public String getBepoch() { + return bepoch; + } + + public void setBepoch(String bepoch) { + this.bepoch = bepoch; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainRequest.java new file mode 100644 index 00000000000..bc499afe305 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.pool; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/failure_domain/{id}", + method = HttpMethod.GET, + responseClass = GetFailureDomainResponse.class, + sync = false +) +public class GetFailureDomainRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainResponse.java new file mode 100644 index 00000000000..811c0933e3b --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/GetFailureDomainResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.pool; + +import org.zstack.expon.sdk.ExponResponse; + +public class GetFailureDomainResponse extends ExponResponse { + private FailureDomainModule members; + + public FailureDomainModule getMembers() { + return members; + } + + public void setMembers(FailureDomainModule members) { + this.members = members; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/QueryFailureDomainRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/QueryFailureDomainRequest.java new file mode 100644 index 00000000000..cca3ee31040 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/QueryFailureDomainRequest.java @@ -0,0 +1,27 @@ +package org.zstack.expon.sdk.pool; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQuery; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.expon.sdk.volume.VolumeModule; +import org.zstack.expon.sdk.volume.QueryVolumeResponse; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/failure_domain", + method = HttpMethod.GET, + responseClass = QueryFailureDomainResponse.class, + sync = true +) +@ExponQuery(inventoryClass = VolumeModule.class, replyClass = QueryVolumeResponse.class) +public class QueryFailureDomainRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/QueryFailureDomainResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/QueryFailureDomainResponse.java new file mode 100644 index 00000000000..2d00d3e4acc --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/pool/QueryFailureDomainResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.pool; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryFailureDomainResponse extends ExponQueryResponse { + private List failureDomains; + + public List getFailureDomains() { + return failureDomains; + } + + public void setFailureDomains(List failureDomains) { + this.failureDomains = failureDomains; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/QueryUssGatewayRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/QueryUssGatewayRequest.java new file mode 100644 index 00000000000..9c8a54f408b --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/QueryUssGatewayRequest.java @@ -0,0 +1,24 @@ +package org.zstack.expon.sdk.uss; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQuery; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/wds/uss", + method = HttpMethod.GET, + responseClass = QueryUssGatewayResponse.class +) +@ExponQuery(replyClass = QueryUssGatewayResponse.class, inventoryClass = UssGatewayModule.class) +public class QueryUssGatewayRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/QueryUssGatewayResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/QueryUssGatewayResponse.java new file mode 100644 index 00000000000..5cb01865370 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/QueryUssGatewayResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.uss; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryUssGatewayResponse extends ExponQueryResponse { + private List ussGateways; + + public void setUssGateways(List ussGateways) { + this.ussGateways = ussGateways; + } + + public List getUssGateways() { + return ussGateways; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/UssGatewayModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/UssGatewayModule.java new file mode 100644 index 00000000000..df1520e1bcf --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/uss/UssGatewayModule.java @@ -0,0 +1,228 @@ +package org.zstack.expon.sdk.uss; + +/** @example + * { + * "business_network": "172.27.106.107/16", + * "business_port": 9001, + * "core": "0x780", + * "create_time": 1696833401345, + * "domain_name": "172.25.106.113:8089", + * "id": "10074567-580e-4bcf-85a7-2c23b2c32caf", + * "manager_ip": "172.25.106.107", + * "name": "vhost_localhost", + * "protocol": "Vhost", + * "protocol_network": "TCP", + * "server_id": "4705682e-92fb-4e9e-baea-4f30ecad813a", + * "server_name": "node107", + * "server_no": 1, + * "specification": "standard", + * "status": "health", + * "tianshu_id": "0e780e97-c670-4341-960a-6f223baea940", + * "tianshu_name": "tianshu", + * "type": "uss", + * "update_time": 1699987942432, + * "user_type": "uss", + * "uss_id": "11", + * "uss_network": "TCP" + * } + */ +public class UssGatewayModule { + private String id; + private String name; + private String type; + private String status; + private String protocol; + private String protocolNetwork; + private String businessNetwork; + private String ussNetwork; + private String domainName; + private String core; + private String specification; + private String serverId; + private String serverName; + private int serverNo; + private String managerIp; + private int businessPort; + private String tianshuId; + private String tianshuName; + private int ussId; + private String userType; + private long createTime; + private long updateTime; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocolNetwork() { + return protocolNetwork; + } + + public void setProtocolNetwork(String protocolNetwork) { + this.protocolNetwork = protocolNetwork; + } + + public String getBusinessNetwork() { + return businessNetwork; + } + + public void setBusinessNetwork(String businessNetwork) { + this.businessNetwork = businessNetwork; + } + + public String getUssNetwork() { + return ussNetwork; + } + + public void setUssNetwork(String ussNetwork) { + this.ussNetwork = ussNetwork; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public String getCore() { + return core; + } + + public void setCore(String core) { + this.core = core; + } + + public String getSpecification() { + return specification; + } + + public void setSpecification(String specification) { + this.specification = specification; + } + + public String getServerId() { + return serverId; + } + + public void setServerId(String serverId) { + this.serverId = serverId; + } + + public String getServerName() { + return serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public int getServerNo() { + return serverNo; + } + + public void setServerNo(int serverNo) { + this.serverNo = serverNo; + } + + public String getManagerIp() { + return managerIp; + } + + public void setManagerIp(String managerIp) { + this.managerIp = managerIp; + } + + public int getBusinessPort() { + return businessPort; + } + + public void setBusinessPort(int businessPort) { + this.businessPort = businessPort; + } + + public String getTianshuId() { + return tianshuId; + } + + public void setTianshuId(String tianshuId) { + this.tianshuId = tianshuId; + } + + public String getTianshuName() { + return tianshuName; + } + + public void setTianshuName(String tianshuName) { + this.tianshuName = tianshuName; + } + + public int getUssId() { + return ussId; + } + + public void setUssId(int ussId) { + this.ussId = ussId; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } + + public long getCreateTime() { + return createTime; + } + + public void setCreateTime(long createTime) { + this.createTime = createTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/AddVhostControllerToUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/AddVhostControllerToUssRequest.java new file mode 100644 index 00000000000..ef6a2aa3c52 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/AddVhostControllerToUssRequest.java @@ -0,0 +1,64 @@ +package org.zstack.expon.sdk.vhost; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/vhost/bind_uss", + method = HttpMethod.PUT, + responseClass = AddVhostControllerToUssResponse.class +) +public class AddVhostControllerToUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String vhostId; + @Param + private String ussGwId; + @Param + private String lunId; + @Param + private boolean isSnapshot; + + public String getVhostId() { + return vhostId; + } + + public void setVhostId(String vhostId) { + this.vhostId = vhostId; + } + + public String getUssGwId() { + return ussGwId; + } + + public void setUssGwId(String ussGwId) { + this.ussGwId = ussGwId; + } + + public String getLunId() { + return lunId; + } + + public void setLunId(String lunId) { + this.lunId = lunId; + } + + public void setSnapshot(boolean snapshot) { + isSnapshot = snapshot; + } + + public boolean isSnapshot() { + return isSnapshot; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/AddVhostControllerToUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/AddVhostControllerToUssResponse.java new file mode 100644 index 00000000000..8bcc4d5cd0c --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/AddVhostControllerToUssResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.vhost; + +import org.zstack.expon.sdk.ExponResponse; + +public class AddVhostControllerToUssResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/CreateVhostControllerRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/CreateVhostControllerRequest.java new file mode 100644 index 00000000000..b286189006b --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/CreateVhostControllerRequest.java @@ -0,0 +1,34 @@ +package org.zstack.expon.sdk.vhost; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/vhost", + method = HttpMethod.POST, + responseClass = CreateVhostControllerResponse.class +) +public class CreateVhostControllerRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/CreateVhostControllerResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/CreateVhostControllerResponse.java new file mode 100644 index 00000000000..4a996bbd66f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/CreateVhostControllerResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.vhost; + +import org.zstack.expon.sdk.ExponResponse; + +public class CreateVhostControllerResponse extends ExponResponse { + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/DeleteVhostControllerRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/DeleteVhostControllerRequest.java new file mode 100644 index 00000000000..6768ab9b93d --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/DeleteVhostControllerRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.vhost; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/block/vhost/{id}", + method = HttpMethod.DELETE, + responseClass = DeleteVhostControllerResponse.class +) +public class DeleteVhostControllerRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/DeleteVhostControllerResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/DeleteVhostControllerResponse.java new file mode 100644 index 00000000000..3bca3a0af8f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/DeleteVhostControllerResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.vhost; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteVhostControllerResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/GetVhostControllerBoundUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/GetVhostControllerBoundUssRequest.java new file mode 100644 index 00000000000..1593e902409 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/GetVhostControllerBoundUssRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.vhost; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/block/vhost/{vhostId}/vhost_binded_uss", + method = HttpMethod.GET, + responseClass = GetVhostControllerBoundUssResponse.class +) +public class GetVhostControllerBoundUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String vhostId; + + public void setVhostId(String vhostId) { + this.vhostId = vhostId; + } + + public String getVhostId() { + return vhostId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/GetVhostControllerBoundUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/GetVhostControllerBoundUssResponse.java new file mode 100644 index 00000000000..bcb3fca1674 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/GetVhostControllerBoundUssResponse.java @@ -0,0 +1,18 @@ +package org.zstack.expon.sdk.vhost; + +import org.zstack.expon.sdk.ExponResponse; +import org.zstack.expon.sdk.uss.UssGatewayModule; + +import java.util.List; + +public class GetVhostControllerBoundUssResponse extends ExponResponse { + private List uss; + + public List getUss() { + return uss; + } + + public void setUss(List uss) { + this.uss = uss; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/QueryVhostControllerRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/QueryVhostControllerRequest.java new file mode 100644 index 00000000000..65a5ca57d47 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/QueryVhostControllerRequest.java @@ -0,0 +1,26 @@ +package org.zstack.expon.sdk.vhost; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQuery; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.expon.sdk.volume.VolumeModule; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/vhost", + method = HttpMethod.GET, + responseClass = QueryVhostControllerResponse.class, + sync = true +) +@ExponQuery(inventoryClass = VolumeModule.class, replyClass = QueryVhostControllerResponse.class) +public class QueryVhostControllerRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/QueryVhostControllerResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/QueryVhostControllerResponse.java new file mode 100644 index 00000000000..7e562ff2243 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/QueryVhostControllerResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.vhost; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryVhostControllerResponse extends ExponQueryResponse { + private List vhosts; + + public List getVhosts() { + return vhosts; + } + + public void setVhosts(List vhosts) { + this.vhosts = vhosts; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/RemoveVhostControllerFromUssRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/RemoveVhostControllerFromUssRequest.java new file mode 100644 index 00000000000..d3035b27078 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/RemoveVhostControllerFromUssRequest.java @@ -0,0 +1,64 @@ +package org.zstack.expon.sdk.vhost; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/vhost/unbind_uss", + method = HttpMethod.PUT, + responseClass = RemoveVhostControllerFromUssResponse.class +) +public class RemoveVhostControllerFromUssRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String vhostId; + @Param + private String ussGwId; + @Param + private String lunId; + @Param + private boolean isSnapshot; + + public String getVhostId() { + return vhostId; + } + + public void setVhostId(String vhostId) { + this.vhostId = vhostId; + } + + public String getUssGwId() { + return ussGwId; + } + + public void setUssGwId(String ussGwId) { + this.ussGwId = ussGwId; + } + + public String getLunId() { + return lunId; + } + + public void setLunId(String lunId) { + this.lunId = lunId; + } + + public void setSnapshot(boolean snapshot) { + isSnapshot = snapshot; + } + + public boolean isSnapshot() { + return isSnapshot; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/RemoveVhostControllerFromUssResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/RemoveVhostControllerFromUssResponse.java new file mode 100644 index 00000000000..c410cb9c279 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/RemoveVhostControllerFromUssResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.vhost; + +import org.zstack.expon.sdk.ExponResponse; + +public class RemoveVhostControllerFromUssResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/VhostControllerModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/VhostControllerModule.java new file mode 100644 index 00000000000..7d12dc5910a --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/vhost/VhostControllerModule.java @@ -0,0 +1,31 @@ +package org.zstack.expon.sdk.vhost; + +public class VhostControllerModule { + private String name; + private String id; + private String path; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/AddVolumePathToBlacklistRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/AddVolumePathToBlacklistRequest.java new file mode 100644 index 00000000000..a8e06a4ebd0 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/AddVolumePathToBlacklistRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/failure_domain/black_list", + method = HttpMethod.PUT, + responseClass = AddVolumePathToBlacklistResponse.class, + sync = false +) +public class AddVolumePathToBlacklistRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String path; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return path; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/AddVolumePathToBlacklistResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/AddVolumePathToBlacklistResponse.java new file mode 100644 index 00000000000..cc75eeee5b1 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/AddVolumePathToBlacklistResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class AddVolumePathToBlacklistResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CloneVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CloneVolumeRequest.java new file mode 100644 index 00000000000..af0558be5fe --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CloneVolumeRequest.java @@ -0,0 +1,58 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/snaps/{snapshotId}/clone", + method = HttpMethod.POST, + responseClass = CloneVolumeResponse.class, + sync = true +) +public class CloneVolumeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String snapshotId; + + @Param + private String name; + + @Param + private ExponVolumeQos qos = new ExponVolumeQos(); + + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getSnapshotId() { + return snapshotId; + } + + public void setSnapshotId(String snapshotId) { + this.snapshotId = snapshotId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ExponVolumeQos getQos() { + return qos; + } + + public void setQos(ExponVolumeQos qos) { + this.qos = qos; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CloneVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CloneVolumeResponse.java new file mode 100644 index 00000000000..99d754411fc --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CloneVolumeResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class CloneVolumeResponse extends ExponResponse { + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CopyVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CopyVolumeSnapshotRequest.java new file mode 100644 index 00000000000..614caf90e61 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CopyVolumeSnapshotRequest.java @@ -0,0 +1,80 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/sync/block/snaps/{snapshotId}/copy_clone", + method = HttpMethod.PUT, + responseClass = CopyVolumeSnapshotResponse.class, + sync = false // for async request +) +public class CopyVolumeSnapshotRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String snapshotId; + + @Param + private String name; + + @Param + private String phyPoolId; + + @Param + private int speed = 8; + + @Param + private ExponVolumeQos qos = new ExponVolumeQos(); + + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getSnapshotId() { + return snapshotId; + } + + public void setSnapshotId(String snapshotId) { + this.snapshotId = snapshotId; + } + + public String getPhyPoolId() { + return phyPoolId; + } + + public void setPhyPoolId(String phyPoolId) { + this.phyPoolId = phyPoolId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ExponVolumeQos getQos() { + return qos; + } + + public void setQos(ExponVolumeQos qos) { + this.qos = qos; + } + + public int getSpeed() { + return speed; + } + + public void setSpeed(int speed) { + this.speed = speed; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CopyVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CopyVolumeSnapshotResponse.java new file mode 100644 index 00000000000..87381a34d27 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CopyVolumeSnapshotResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponAsyncResponse; + +public class CopyVolumeSnapshotResponse extends ExponAsyncResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeRequest.java new file mode 100644 index 00000000000..5ea8f64d4a4 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeRequest.java @@ -0,0 +1,65 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes", + method = HttpMethod.POST, + responseClass = CreateVolumeResponse.class, + sync = true +) +public class CreateVolumeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + @Param + private String phyPoolId; + @Param + private long volumeSize; + @Param + private ExponVolumeQos qos = new ExponVolumeQos(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPhyPoolId() { + return phyPoolId; + } + + public void setPhyPoolId(String phyPoolId) { + this.phyPoolId = phyPoolId; + } + + public long getVolumeSize() { + return volumeSize; + } + + public void setVolumeSize(long volumeSize) { + this.volumeSize = volumeSize; + } + + public ExponVolumeQos getQos() { + return qos; + } + + public void setQos(ExponVolumeQos qos) { + this.qos = qos; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeResponse.java new file mode 100644 index 00000000000..ac0900ca4af --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class CreateVolumeResponse extends ExponResponse { + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeSnapshotRequest.java new file mode 100644 index 00000000000..8363021a335 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeSnapshotRequest.java @@ -0,0 +1,57 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/snaps", + method = HttpMethod.POST, + responseClass = CreateVolumeSnapshotResponse.class, + sync = true +) +public class CreateVolumeSnapshotRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String name; + + @Param + private String volumeId; + + @Param(required = false) + private String description; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeSnapshotResponse.java new file mode 100644 index 00000000000..8d2d620e4ab --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/CreateVolumeSnapshotResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class CreateVolumeSnapshotResponse extends ExponResponse { + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeRequest.java new file mode 100644 index 00000000000..42694cacfa5 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeRequest.java @@ -0,0 +1,45 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{volId}", + responseClass = DeleteVolumeResponse.class, + method = HttpMethod.DELETE, + sync = true +) +public class DeleteVolumeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String volId; + + @Param + private boolean force; + + public String getVolId() { + return volId; + } + + public void setVolId(String volId) { + this.volId = volId; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeResponse.java new file mode 100644 index 00000000000..291bb97c92a --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeResponse.java @@ -0,0 +1,7 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteVolumeResponse extends ExponResponse { + +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeSnapshotRequest.java new file mode 100644 index 00000000000..a260f97a864 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeSnapshotRequest.java @@ -0,0 +1,45 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/snaps/{snapshotId}", + method = HttpMethod.DELETE, + responseClass = DeleteVolumeSnapshotResponse.class, + sync = true +) +public class DeleteVolumeSnapshotRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + @Param + private String snapshotId; + + @Param(required = false) + private boolean force; + + public String getSnapshotId() { + return snapshotId; + } + + public void setSnapshotId(String snapshotId) { + this.snapshotId = snapshotId; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeSnapshotResponse.java new file mode 100644 index 00000000000..0ef9eab7742 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/DeleteVolumeSnapshotResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class DeleteVolumeSnapshotResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExpandVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExpandVolumeRequest.java new file mode 100644 index 00000000000..accb7226a45 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExpandVolumeRequest.java @@ -0,0 +1,47 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{id}/expand", + method = HttpMethod.PUT, + responseClass = ExpandVolumeResponse.class, + sync = true +) +public class ExpandVolumeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + @Param + private long size; + + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setSize(long size) { + this.size = size; + } + + public long getSize() { + return size; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExpandVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExpandVolumeResponse.java new file mode 100644 index 00000000000..6ff00af08c3 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExpandVolumeResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class ExpandVolumeResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExponVolumeQos.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExponVolumeQos.java new file mode 100644 index 00000000000..81cec30870d --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/ExponVolumeQos.java @@ -0,0 +1,101 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponParam; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.header.volume.VolumeQos; + +import java.util.HashMap; +import java.util.Map; + +public class ExponVolumeQos implements ExponParam { + private static final HashMap parameterMap = new HashMap<>(); + + @Param(required = false, numberRange = {10485760, 107374182400L}) + private Long bpsLimit; + @Param(required = false, numberRange = {10485760, 107374182400L}) + private Long readBpsLimit; + @Param(required = false, numberRange = {10485760, 107374182400L}) + private Long writeBpsLimit; + @Param(required = false, numberRange = {100, 10000000}) + private Long iopsLimit; + @Param(required = false, numberRange = {100, 10000000}) + private Long readIopsLimit; + @Param(required = false, numberRange = {100, 10000000}) + private Long writeIopsLimit; + + public static ExponVolumeQos valueOf(VolumeQos qos) { + if (qos == null) { + return null; + } + + ExponVolumeQos ret = new ExponVolumeQos(); + ret.bpsLimit = qos.getTotalBandwidth() == null || qos.getTotalBandwidth() < 0 ? 0 : qos.getTotalBandwidth(); + ret.readBpsLimit = qos.getReadBandwidth() == null || qos.getReadBandwidth() < 0 ? 0 : qos.getReadBandwidth(); + ret.writeBpsLimit = qos.getWriteBandwidth() == null || qos.getWriteBandwidth() < 0 ? 0 : qos.getWriteBandwidth(); + ret.iopsLimit = qos.getTotalIOPS() == null || qos.getTotalIOPS() < 0 ? 0 : qos.getTotalIOPS(); + ret.readIopsLimit = qos.getReadIOPS() == null || qos.getReadIOPS() < 0 ? 0 : qos.getReadIOPS(); + ret.writeIopsLimit = qos.getWriteIOPS() == null || qos.getWriteIOPS() < 0 ? 0 : qos.getWriteIOPS(); + return ret; + } + + public Long getBpsLimit() { + return bpsLimit; + } + + public void setBpsLimit(long bpsLimit) { + this.bpsLimit = bpsLimit; + } + + public Long getIopsLimit() { + return iopsLimit; + } + + public void setIopsLimit(long iopsLimit) { + this.iopsLimit = iopsLimit; + } + + public void setBpsLimit(Long bpsLimit) { + this.bpsLimit = bpsLimit; + } + + public Long getReadBpsLimit() { + return readBpsLimit; + } + + public void setReadBpsLimit(Long readBpsLimit) { + this.readBpsLimit = readBpsLimit; + } + + public Long getWriteBpsLimit() { + return writeBpsLimit; + } + + public void setWriteBpsLimit(Long writeBpsLimit) { + this.writeBpsLimit = writeBpsLimit; + } + + public void setIopsLimit(Long iopsLimit) { + this.iopsLimit = iopsLimit; + } + + public Long getReadIopsLimit() { + return readIopsLimit; + } + + public void setReadIopsLimit(Long readIopsLimit) { + this.readIopsLimit = readIopsLimit; + } + + public Long getWriteIopsLimit() { + return writeIopsLimit; + } + + public void setWriteIopsLimit(Long writeIopsLimit) { + this.writeIopsLimit = writeIopsLimit; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeBoundPathRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeBoundPathRequest.java new file mode 100644 index 00000000000..175b88e8d2e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeBoundPathRequest.java @@ -0,0 +1,33 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; +@ExponRestRequest( + path = "/block/volumes/{volId}/bind_status", + method = HttpMethod.GET, + responseClass = GetVolumeBoundPathResponse.class +) +public class GetVolumeBoundPathRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String volId; + + public String getVolId() { + return volId; + } + + public void setVolId(String volId) { + this.volId = volId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeBoundPathResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeBoundPathResponse.java new file mode 100644 index 00000000000..446369245db --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeBoundPathResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetVolumeBoundPathResponse extends ExponResponse { + List path; + + public void setPath(List path) { + this.path = path; + } + + public List getPath() { + return path; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeLunDetailRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeLunDetailRequest.java new file mode 100644 index 00000000000..5e58659f7f7 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeLunDetailRequest.java @@ -0,0 +1,34 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{volId}/lun_detail", + method = HttpMethod.GET, + responseClass = GetVolumeLunDetailResponse.class +) +public class GetVolumeLunDetailRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String volId; + + public String getVolId() { + return volId; + } + + public void setVolId(String volId) { + this.volId = volId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeLunDetailResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeLunDetailResponse.java new file mode 100644 index 00000000000..5387faf3782 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeLunDetailResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +import java.util.List; + +public class GetVolumeLunDetailResponse extends ExponResponse { + private List lunDetails; + + public List getLunDetails() { + return lunDetails; + } + + public void setLunDetails(List lunDetails) { + this.lunDetails = lunDetails; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeRequest.java new file mode 100644 index 00000000000..033a50eafd1 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeRequest.java @@ -0,0 +1,35 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{volId}", + method = HttpMethod.GET, + responseClass = GetVolumeResponse.class, + sync = false +) +public class GetVolumeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String volId; + + public String getVolId() { + return volId; + } + + public void setVolId(String volId) { + this.volId = volId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeResponse.java new file mode 100644 index 00000000000..9cc6059c370 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class GetVolumeResponse extends ExponResponse { + private VolumeModule volumeDetail; + + public VolumeModule getVolumeDetail() { + return volumeDetail; + } + + public void setVolumeDetail(VolumeModule volumeDetail) { + this.volumeDetail = volumeDetail; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeSnapshotRequest.java new file mode 100644 index 00000000000..f448f59d311 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeSnapshotRequest.java @@ -0,0 +1,38 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQuery; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/block/snaps/{id}", + method = HttpMethod.GET, + responseClass = GetVolumeSnapshotResponse.class, + sync = true +) +@ExponQuery(inventoryClass = VolumeModule.class, replyClass = QueryVolumeResponse.class) +public class GetVolumeSnapshotRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + public void setId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeSnapshotResponse.java new file mode 100644 index 00000000000..89989787b47 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeSnapshotResponse.java @@ -0,0 +1,115 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class GetVolumeSnapshotResponse extends ExponResponse { + private String id; + private String name; + private String snapName; + private long snapSize; + private long dataSize; + private String volumeId; + private String volumeName; + private String volumeDispName; + private boolean isDelete; + private String poolId; + private String poolName; + private String wwn; + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSnapName() { + return snapName; + } + + public void setSnapName(String snapName) { + this.snapName = snapName; + } + + public long getSnapSize() { + return snapSize; + } + + public void setSnapSize(long snapSize) { + this.snapSize = snapSize; + } + + public long getDataSize() { + return dataSize; + } + + public void setDataSize(long dataSize) { + this.dataSize = dataSize; + } + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public String getVolumeName() { + return volumeName; + } + + public void setVolumeName(String volumeName) { + this.volumeName = volumeName; + } + + public String getVolumeDispName() { + return volumeDispName; + } + + public void setVolumeDispName(String volumeDispName) { + this.volumeDispName = volumeDispName; + } + + public boolean isDelete() { + return isDelete; + } + + public void setDelete(boolean delete) { + isDelete = delete; + } + + public String getPoolId() { + return poolId; + } + + public void setPoolId(String poolId) { + this.poolId = poolId; + } + + public String getPoolName() { + return poolName; + } + + public void setPoolName(String poolName) { + this.poolName = poolName; + } + + public String getWwn() { + return wwn; + } + + public void setWwn(String wwn) { + this.wwn = wwn; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeTaskProgressRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeTaskProgressRequest.java new file mode 100644 index 00000000000..38aaa23b7f0 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeTaskProgressRequest.java @@ -0,0 +1,36 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + + +@ExponRestRequest( + path = "/block/volumes/tasks/{taskId}", + method = HttpMethod.GET, + responseClass = GetVolumeTaskProgressResponse.class, + sync = true +) +public class GetVolumeTaskProgressRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private int taskId; + + public int getTaskId() { + return taskId; + } + + public void setTaskId(int taskId) { + this.taskId = taskId; + } + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeTaskProgressResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeTaskProgressResponse.java new file mode 100644 index 00000000000..66b31e3dd44 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/GetVolumeTaskProgressResponse.java @@ -0,0 +1,48 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +/** + * @example + * { + * "message": "", + * "ret_code": "0", + * "task": { + * "cloneid": 0, + * "code": 0, + * "dest_vol": "volume-e6a6c343-0eae-4505-be84-022e85dabf83", + * "first_blockid": 0, + * "last_blockid": 255, + * "msg": "", + * "namespace": "ussns", + * "path": "", + * "pool_id": 1, + * "progress": 100, + * "progress_blockid": 233, + * "rw_iops": 0, + * "rw_mbytes": 0, + * "snap_source_vol": "", + * "snapid": 0, + * "speed": 8, + * "state": "TASK_COMPLETE", + * "task_id": 1, + * "task_type": 3, + * "treeid": 2, + * "update_at": 1704699092, + * "uss_id": 1, + * "vol_name": "snapshot-1f0ba3d1-bff4-473b-af71-d1a74788f8a0", + * "vol_size": 1073741824 + * } + * } + */ +public class GetVolumeTaskProgressResponse extends ExponResponse { + private VolumeTask task; + + public VolumeTask getTask() { + return task; + } + + public void setTask(VolumeTask task) { + this.task = task; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/LunResource.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/LunResource.java new file mode 100644 index 00000000000..8f8d347fede --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/LunResource.java @@ -0,0 +1,52 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.externalStorage.sdk.Param; + +public class LunResource { + @Param + private String lunId; + + @Param(validValues = {"volume", "snapshot"}) + private String lunType; + + @Param(required = false) + private boolean isReadonly; + + public String getLunId() { + return lunId; + } + + public void setLunId(String lunId) { + this.lunId = lunId; + } + + public String getLunType() { + return lunType; + } + + public void setLunType(String lunType) { + this.lunType = lunType; + } + + public void setIsReadonly(boolean isReadonly) { + this.isReadonly = isReadonly; + } + + public boolean getIsReadonly() { + return isReadonly; + } + + public LunResource() { + } + + public LunResource(String lunId, String lunType) { + this.lunId = lunId; + this.lunType = lunType; + } + + public LunResource(String lunId, String lunType, boolean isReadonly) { + this.lunId = lunId; + this.lunType = lunType; + this.isReadonly = isReadonly; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeRequest.java new file mode 100644 index 00000000000..a758e224432 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeRequest.java @@ -0,0 +1,25 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQuery; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes", + method = HttpMethod.GET, + responseClass = QueryVolumeResponse.class, + sync = true +) +@ExponQuery(inventoryClass = VolumeModule.class, replyClass = QueryVolumeResponse.class) +public class QueryVolumeRequest extends ExponQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeResponse.java new file mode 100644 index 00000000000..edbe4a4e5e8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeResponse.java @@ -0,0 +1,17 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponQueryResponse; + +import java.util.List; + +public class QueryVolumeResponse extends ExponQueryResponse { + private List volumes; + + public List getVolumes() { + return volumes; + } + + public void setVolumes(List volumes) { + this.volumes = volumes; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeSnapshotRequest.java new file mode 100644 index 00000000000..84a28fc9d8d --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeSnapshotRequest.java @@ -0,0 +1,26 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponQuery; +import org.zstack.expon.sdk.ExponQueryRequest; +import org.zstack.expon.sdk.ExponRestRequest; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/snaps", + method = HttpMethod.GET, + responseClass = QueryVolumeSnapshotResponse.class, + sync = true +) +@ExponQuery(inventoryClass = VolumeModule.class, replyClass = QueryVolumeResponse.class) +public class QueryVolumeSnapshotRequest extends ExponQueryRequest { + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeSnapshotResponse.java new file mode 100644 index 00000000000..9330399667f --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/QueryVolumeSnapshotResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import java.util.List; + +public class QueryVolumeSnapshotResponse extends QueryVolumeResponse { + private List snaps; + + public List getSnaps() { + return snaps; + } + + public void setSnaps(List snaps) { + this.snaps = snaps; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RecoveryVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RecoveryVolumeSnapshotRequest.java new file mode 100644 index 00000000000..613d4cc1eb7 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RecoveryVolumeSnapshotRequest.java @@ -0,0 +1,46 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{volumeId}/recovery", + method = HttpMethod.PUT, + responseClass = RecoveryVolumeSnapshotResponse.class, + sync = true +) +public class RecoveryVolumeSnapshotRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String volumeId; + @Param + private String snapId; + + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public String getSnapId() { + return snapId; + } + + public void setSnapId(String snapId) { + this.snapId = snapId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RecoveryVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RecoveryVolumeSnapshotResponse.java new file mode 100644 index 00000000000..d749ec11bd2 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RecoveryVolumeSnapshotResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class RecoveryVolumeSnapshotResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RemoveVolumePathFromBlacklistRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RemoveVolumePathFromBlacklistRequest.java new file mode 100644 index 00000000000..fb9728a2d7d --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RemoveVolumePathFromBlacklistRequest.java @@ -0,0 +1,36 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/failure_domain/black_list", + method = HttpMethod.DELETE, + responseClass = RemoveVolumePathFromBlacklistResponse.class, + hasBody = true, + sync = false +) +public class RemoveVolumePathFromBlacklistRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String path; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return path; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RemoveVolumePathFromBlacklistResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RemoveVolumePathFromBlacklistResponse.java new file mode 100644 index 00000000000..7fe753adf3e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/RemoveVolumePathFromBlacklistResponse.java @@ -0,0 +1,6 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class RemoveVolumePathFromBlacklistResponse extends ExponResponse { +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/SetVolumeQosRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/SetVolumeQosRequest.java new file mode 100644 index 00000000000..c9372e246da --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/SetVolumeQosRequest.java @@ -0,0 +1,45 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{volId}/qos", + method = HttpMethod.PUT, + responseClass = SetVolumeQosResponse.class +) +public class SetVolumeQosRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String volId; + @Param + private ExponVolumeQos qos; + + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getVolId() { + return volId; + } + + public void setVolId(String volId) { + this.volId = volId; + } + + public ExponVolumeQos getQos() { + return qos; + } + + public void setQos(ExponVolumeQos qos) { + this.qos = qos; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/SetVolumeQosResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/SetVolumeQosResponse.java new file mode 100644 index 00000000000..92502c76968 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/SetVolumeQosResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class SetVolumeQosResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeRequest.java new file mode 100644 index 00000000000..a9b7128d75e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeRequest.java @@ -0,0 +1,46 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/volumes/{id}/name", + method = HttpMethod.PUT, + responseClass = UpdateVolumeResponse.class, + sync = false +) +public class UpdateVolumeRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + @Param + private String name; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeResponse.java new file mode 100644 index 00000000000..d658a465490 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class UpdateVolumeResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeSnapshotRequest.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeSnapshotRequest.java new file mode 100644 index 00000000000..2935942d609 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeSnapshotRequest.java @@ -0,0 +1,57 @@ +package org.zstack.expon.sdk.volume; + +import org.springframework.http.HttpMethod; +import org.zstack.expon.sdk.ExponRequest; +import org.zstack.expon.sdk.ExponRestRequest; +import org.zstack.externalStorage.sdk.Param; + +import java.util.HashMap; +import java.util.Map; + +@ExponRestRequest( + path = "/block/snaps/{id}", + method = HttpMethod.PUT, + responseClass = UpdateVolumeSnapshotResponse.class, + sync = false +) +public class UpdateVolumeSnapshotRequest extends ExponRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Param + private String id; + + @Param + private String name; + + @Param(required = false) + private String description; + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeSnapshotResponse.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeSnapshotResponse.java new file mode 100644 index 00000000000..bdeb1da5673 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/UpdateVolumeSnapshotResponse.java @@ -0,0 +1,15 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.ExponResponse; + +public class UpdateVolumeSnapshotResponse extends ExponResponse { + private boolean result; + + public boolean isResult() { + return result; + } + + public void setResult(boolean result) { + this.result = result; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeLunModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeLunModule.java new file mode 100644 index 00000000000..ed1ade2e15b --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeLunModule.java @@ -0,0 +1,109 @@ +package org.zstack.expon.sdk.volume; + +/** + * @example + * { + * "VolumeNamespace": "ussns", + * "blkSize": 512, + * "lun_id": "19", + * "poolId": 1, + * "size": 28991029248, + * "target": "iqn.2024-04.com.sds.wds:100bbf2da6e1", + * "treeId": 43, + * "uuid": "5550f3ec-af9a-4d9e-8638-ba4cf76293e0", + * "volId": 51, + * "volName": "volume-0462cfeb-98f9-4f70-b5cc-2a42feeec376" + * } + */ +public class VolumeLunModule { + private String volumeNamespace; + private int blockSize; + private String lunId; + private int poolId; + private long size; + private String target; + private int treeId; + private String uuid; + private int volId; + private String volName; + + public String getVolumeNamespace() { + return volumeNamespace; + } + + public void setVolumeNamespace(String volumeNamespace) { + this.volumeNamespace = volumeNamespace; + } + + public int getBlockSize() { + return blockSize; + } + + public void setBlockSize(int blockSize) { + this.blockSize = blockSize; + } + + public String getLunId() { + return lunId; + } + + public void setLunId(String lunId) { + this.lunId = lunId; + } + + public int getPoolId() { + return poolId; + } + + public void setPoolId(int poolId) { + this.poolId = poolId; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public int getTreeId() { + return treeId; + } + + public void setTreeId(int treeId) { + this.treeId = treeId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public int getVolId() { + return volId; + } + + public void setVolId(int volId) { + this.volId = volId; + } + + public String getVolName() { + return volName; + } + + public void setVolName(String volName) { + this.volName = volName; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeModule.java new file mode 100644 index 00000000000..aa9efe98263 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeModule.java @@ -0,0 +1,129 @@ +package org.zstack.expon.sdk.volume; + + +/** + * @example + * { + * "data_size": 0, + * "id": "ae747374-6c5f-46e2-b9c4-6a033a0bdcdd", + * "is_delete": false, + * "name": "csac_00001", + * "pool_id": "990273f1-3665-4c56-97a5-9c56b2a35954", + * "pool_name": "zxc", + * "qos_status": false, + * "volume_name": "volume-ae747374-6c5f-46e2-b9c4-6a033a0bdcdd", + * "volume_size": 1073741824, + * "wwn": "600140501e000000b9c46a033a0bdcdd" + * } + */ +public class VolumeModule { + private String id; + private String name; + private String poolId; + private String poolName; + private String volumeName; + private String wwn; + private long volumeSize; + private long dataSize; + private boolean isDelete; + private boolean qosStatus; + private ExponVolumeQos qos; + + private String runStatus; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPoolId() { + return poolId; + } + + public void setPoolId(String poolId) { + this.poolId = poolId; + } + + public String getPoolName() { + return poolName; + } + + public void setPoolName(String poolName) { + this.poolName = poolName; + } + + public String getVolumeName() { + return volumeName; + } + + public void setVolumeName(String volumeName) { + this.volumeName = volumeName; + } + + public String getWwn() { + return wwn; + } + + public void setWwn(String wwn) { + this.wwn = wwn; + } + + public long getVolumeSize() { + return volumeSize; + } + + public void setVolumeSize(long volumeSize) { + this.volumeSize = volumeSize; + } + + public long getDataSize() { + return dataSize; + } + + public void setDataSize(long dataSize) { + this.dataSize = dataSize; + } + + public boolean isDelete() { + return isDelete; + } + + public void setDelete(boolean delete) { + isDelete = delete; + } + + public boolean isQosStatus() { + return qosStatus; + } + + public void setQosStatus(boolean qosStatus) { + this.qosStatus = qosStatus; + } + + public ExponVolumeQos getQos() { + return qos; + } + + public void setQos(ExponVolumeQos qos) { + this.qos = qos; + } + + public String getRunStatus() { + return runStatus; + } + + public void setRunStatus(String runStatus) { + this.runStatus = runStatus; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeSnapshotModule.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeSnapshotModule.java new file mode 100644 index 00000000000..8975010f3b8 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeSnapshotModule.java @@ -0,0 +1,129 @@ +package org.zstack.expon.sdk.volume; + +/** + * @example + * { + * "id": "ae747374-6c5f-46e2-b9c4-6a033a0bdcdd", + * "name": "csac_00001", + * "snap_name": "snapshot-ae747374-6c5f-46e2-b9c4-6a033a0bdcdd ", + * "snap_size": 107372100, + * "data_size": 107372100, + * "volume_id": "990273f1-3665-4c56-97a5-9c56b2a35954", + * "volume_name": "volume-ae747374-6c5f-46e2-b9c4-6a033a0bdcdd", + * "volume_disp_name": "volume1", + * "is_delete": false, + * "pool_id": "978273f1-3665-4c56-97a5-9c56b2a35954", + * "pool_name": "zxc" + * } + */ +public class VolumeSnapshotModule { + private String id; + private String name; + private String snapName; + private long snapSize; + private long dataSize; + private String volumeId; + private String volumeName; + private String volumeDispName; + private boolean isDelete; + private String poolId; + private String poolName; + + private String wwn; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSnapName() { + return snapName; + } + + public void setSnapName(String snapName) { + this.snapName = snapName; + } + + public long getSnapSize() { + return snapSize; + } + + public void setSnapSize(long snapSize) { + this.snapSize = snapSize; + } + + public long getDataSize() { + return dataSize; + } + + public void setDataSize(long dataSize) { + this.dataSize = dataSize; + } + + public String getVolumeId() { + return volumeId; + } + + public void setVolumeId(String volumeId) { + this.volumeId = volumeId; + } + + public String getVolumeName() { + return volumeName; + } + + public void setVolumeName(String volumeName) { + this.volumeName = volumeName; + } + + public String getVolumeDispName() { + return volumeDispName; + } + + public void setVolumeDispName(String volumeDispName) { + this.volumeDispName = volumeDispName; + } + + public boolean isDelete() { + return isDelete; + } + + public void setDelete(boolean delete) { + isDelete = delete; + } + + public String getPoolId() { + return poolId; + } + + public void setPoolId(String poolId) { + this.poolId = poolId; + } + + public String getPoolName() { + return poolName; + } + + public void setPoolName(String poolName) { + this.poolName = poolName; + } + + public String getWwn() { + return wwn; + } + + public void setWwn(String wwn) { + this.wwn = wwn; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeTask.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeTask.java new file mode 100644 index 00000000000..3861eca8250 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeTask.java @@ -0,0 +1,257 @@ +package org.zstack.expon.sdk.volume; + +/** + * @example + * { + * "cloneid": 0, + * "code": 0, + * "dest_vol": "volume-e6a6c343-0eae-4505-be84-022e85dabf83", + * "first_blockid": 0, + * "last_blockid": 255, + * "msg": "", + * "namespace": "ussns", + * "path": "", + * "pool_id": 1, + * "progress": 100, + * "progress_blockid": 233, + * "rw_iops": 0, + * "rw_mbytes": 0, + * "snap_source_vol": "", + * "snapid": 0, + * "speed": 8, + * "state": "TASK_COMPLETE", + * "task_id": 1, + * "task_type": 3, + * "treeid": 2, + * "update_at": 1704699092, + * "uss_id": 1, + * "vol_name": "snapshot-1f0ba3d1-bff4-473b-af71-d1a74788f8a0", + * "vol_size": 1073741824 + * } + */ +public class VolumeTask { + public enum TaskState { + TASK_STATE_TORUN, + TASK_STATE_RUNNING, + TASK_FAILED, + TASK_COMPLETE, + } + + + private String volName; + private long volSize; + private int cloneid; + private int code; + private String destVol; + private int firstBlockid; + private int lastBlockid; + private String msg; + private String namespace; + private String path; + private int poolId; + private int progress; + private int progressBlockid; + private int rwIops; + private int rwMbytes; + private String snapSourceVol; + private int snapid; + private int speed; + private String state; + private int taskId; + private int taskType; + private int treeid; + private long updateAt; + private int ussId; + + public String getVolName() { + return volName; + } + + public void setVolName(String volName) { + this.volName = volName; + } + + public long getVolSize() { + return volSize; + } + + public void setVolSize(long volSize) { + this.volSize = volSize; + } + + public int getCloneid() { + return cloneid; + } + + public void setCloneid(int cloneid) { + this.cloneid = cloneid; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getDestVol() { + return destVol; + } + + public void setDestVol(String destVol) { + this.destVol = destVol; + } + + public int getFirstBlockid() { + return firstBlockid; + } + + public void setFirstBlockid(int firstBlockid) { + this.firstBlockid = firstBlockid; + } + + public int getLastBlockid() { + return lastBlockid; + } + + public void setLastBlockid(int lastBlockid) { + this.lastBlockid = lastBlockid; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getPoolId() { + return poolId; + } + + public void setPoolId(int poolId) { + this.poolId = poolId; + } + + public int getProgress() { + return progress; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + public int getProgressBlockid() { + return progressBlockid; + } + + public void setProgressBlockid(int progressBlockid) { + this.progressBlockid = progressBlockid; + } + + public int getRwIops() { + return rwIops; + } + + public void setRwIops(int rwIops) { + this.rwIops = rwIops; + } + + public int getRwMbytes() { + return rwMbytes; + } + + public void setRwMbytes(int rwMbytes) { + this.rwMbytes = rwMbytes; + } + + public String getSnapSourceVol() { + return snapSourceVol; + } + + public void setSnapSourceVol(String snapSourceVol) { + this.snapSourceVol = snapSourceVol; + } + + public int getSnapid() { + return snapid; + } + + public void setSnapid(int snapid) { + this.snapid = snapid; + } + + public int getSpeed() { + return speed; + } + + public void setSpeed(int speed) { + this.speed = speed; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public int getTaskId() { + return taskId; + } + + public void setTaskId(int taskId) { + this.taskId = taskId; + } + + public int getTaskType() { + return taskType; + } + + public void setTaskType(int taskType) { + this.taskType = taskType; + } + + public int getTreeid() { + return treeid; + } + + public void setTreeid(int treeid) { + this.treeid = treeid; + } + + public long getUpdateAt() { + return updateAt; + } + + public void setUpdateAt(long updateAt) { + this.updateAt = updateAt; + } + + public int getUssId() { + return ussId; + } + + public void setUssId(int ussId) { + this.ussId = ussId; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeTaskState.java b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeTaskState.java new file mode 100644 index 00000000000..6df8bc7244e --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/expon/sdk/volume/VolumeTaskState.java @@ -0,0 +1,25 @@ +package org.zstack.expon.sdk.volume; + +import org.zstack.expon.sdk.TaskStatus; + +public enum VolumeTaskState { + TASK_COMPLETE, + TASK_FAILED, + TASK_RUNNING, + TASK_TORUN; + + public TaskStatus toTaskStatus() { + switch (this) { + case TASK_COMPLETE: + return TaskStatus.SUCCESS; + case TASK_FAILED: + return TaskStatus.FAILED; + case TASK_RUNNING: + return TaskStatus.RUNNING; + case TASK_TORUN: + return TaskStatus.RUNNING; + default: + return TaskStatus.FAILED; + } + } +} diff --git a/plugin/expon/src/main/java/org/zstack/header/expon/Constants.java b/plugin/expon/src/main/java/org/zstack/header/expon/Constants.java new file mode 100644 index 00000000000..0e60dcc8784 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/header/expon/Constants.java @@ -0,0 +1,13 @@ +package org.zstack.header.expon; + +import okhttp3.MediaType; + +public interface Constants { + String HEADER_AUTHORIZATION = "Authorization"; + String BEARER = "Bearer"; + String SESSION_ID = "sessionId"; + MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + String HTTP_ERROR = "sdk.1000"; + String POLLING_TIMEOUT_ERROR = "sdk.1001"; + String INTERNAL_ERROR = "sdk.1002"; +} diff --git a/plugin/expon/src/main/java/org/zstack/header/expon/ExponError.java b/plugin/expon/src/main/java/org/zstack/header/expon/ExponError.java new file mode 100644 index 00000000000..dd2f8976f82 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/header/expon/ExponError.java @@ -0,0 +1,25 @@ +package org.zstack.header.expon; + +public enum ExponError { + INVALID_SESSION("02.0c.02.0001"), + SESSION_NOTFOUND("02.0c.02.0004"), + SESSION_EXPIRED("02.0c.02.0005"), + VHOST_ALREADY_UNBIND_USS("02.e0.03.0010"), + VHOST_BIND_USS_FAILED("02.e0.03.0008"), + LUN_ALREADY_MAPPED_SOME_ISCSI_CLIENT("02.b8.06.0001"), + LUN_ALREADY_UNMAPPED_ISCSI_CLIENT("02.b8.06.0004"), + BLACK_LIST_OPERATION_FAILED("02.02.03.0013"), + VOLUME_NOT_FOUND("02.b1.02.0002"), + SNAPSHOT_NOT_FOUND("02.b1.03.0004"); + + private String code; + + ExponError(String code) { + this.code = code; + } + + @Override + public String toString() { + return code; + } +} diff --git a/plugin/expon/src/main/java/org/zstack/header/expon/HealthStatus.java b/plugin/expon/src/main/java/org/zstack/header/expon/HealthStatus.java new file mode 100644 index 00000000000..9a9c376f421 --- /dev/null +++ b/plugin/expon/src/main/java/org/zstack/header/expon/HealthStatus.java @@ -0,0 +1,7 @@ +package org.zstack.header.expon; + +public enum HealthStatus { + health, + warning, + error +} diff --git a/plugin/externalStorage/pom.xml b/plugin/externalStorage/pom.xml new file mode 100644 index 00000000000..76c238c9c2b --- /dev/null +++ b/plugin/externalStorage/pom.xml @@ -0,0 +1,87 @@ + + 4.0.0 + + + plugin + org.zstack + 5.4.0 + .. + + + externalStorage + + + org.zstack + kvm + ${project.version} + + + org.zstack + storage + ${project.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + \ No newline at end of file diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/ExternalStorageConstant.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/ExternalStorageConstant.java new file mode 100644 index 00000000000..3f1b53f0b30 --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/ExternalStorageConstant.java @@ -0,0 +1,13 @@ +package org.zstack.externalStorage.primary; + +import org.zstack.header.configuration.PythonClass; + +/** + * @author Xingwei Yu + * @date 2024/8/16 11:07 + */ +@PythonClass +public interface ExternalStorageConstant { + String ISCSI_PROTOCOL = "iSCSI"; + String CBD_PROTOCOL = "CBD"; +} diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/ExternalStorageFencerType.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/ExternalStorageFencerType.java new file mode 100644 index 00000000000..7c0e17cd173 --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/ExternalStorageFencerType.java @@ -0,0 +1,35 @@ +package org.zstack.externalStorage.primary; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Xingwei Yu + * @date 2024/8/21 10:38 + */ +// TODO refactor it, use controller interface not this fencer type class +public class ExternalStorageFencerType { + private static Map types = Collections.synchronizedMap(new HashMap()); + + private final String identity; + private final String protocol; + + public ExternalStorageFencerType(String identity, String protocol) { + if (types.containsKey(identity)) { + throw new IllegalArgumentException(String.format("duplicate ExternalStorageNodeServer for identity[%s]", identity)); + } + + this.identity = identity; + this.protocol = protocol; + types.put(identity, protocol); + } + + public static String getProtocolFromIdentity(String identity) { + String protocol = types.get(identity); + if (protocol == null) { + throw new IllegalArgumentException("ExternalStorageNodeServer identity: " + identity + " was not registered by any ExternalStorageFactory"); + } + return protocol; + } +} diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/kvm/ExternalPrimaryStorageKvmFactory.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/kvm/ExternalPrimaryStorageKvmFactory.java new file mode 100644 index 00000000000..c6eb04a8557 --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/primary/kvm/ExternalPrimaryStorageKvmFactory.java @@ -0,0 +1,419 @@ +package org.zstack.externalStorage.primary.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.externalStorage.primary.ExternalStorageConstant; +import org.zstack.header.core.*; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.addon.NodeHealthy; +import org.zstack.header.storage.addon.StorageHealthy; +import org.zstack.header.storage.addon.primary.*; +import org.zstack.header.storage.primary.*; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.VolumeVO_; +import org.zstack.kvm.*; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +public class ExternalPrimaryStorageKvmFactory implements KVMHostConnectExtensionPoint, KVMPingAgentNoFailureExtensionPoint, + KvmVmActiveVolumeSyncExtensionPoint, KVMStartVmExtensionPoint { + private static final CLogger logger = Utils.getLogger(ExternalPrimaryStorageKvmFactory.class); + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + @Autowired + private ExternalPrimaryStorageFactory extPsFactory; + + + @Transactional(readOnly = true) + private List findExternalPsByClusterUuid(String clusterUuid) { + return SQL.New("select pri from ExternalPrimaryStorageVO pri, PrimaryStorageClusterRefVO ref" + + " where pri.uuid = ref.primaryStorageUuid" + + " and ref.clusterUuid = :cuuid", ExternalPrimaryStorageVO.class) + .param("cuuid", clusterUuid) + .list(); + } + + private Map getHostStatus(List extPss) { + return Q.New(PrimaryStorageHostRefVO.class) + .select(PrimaryStorageHostRefVO_.hostUuid, PrimaryStorageHostRefVO_.status) + .in(PrimaryStorageHostRefVO_.primaryStorageUuid, + extPss.stream().map(ExternalPrimaryStorageVO::getUuid).collect(Collectors.toList())) + .listTuple().stream() + .collect(Collectors.toMap( + t -> t.get(0, String.class), + t -> t.get(1, PrimaryStorageHostStatus.class), + (o, n) -> n + )); + } + + @Override + public Flow createKvmHostConnectingFlow(KVMHostConnectedContext context) { + List extPss = findExternalPsByClusterUuid(context.getInventory().getClusterUuid()); + if (extPss.isEmpty()) { + return new NopeFlow(); + } + + return new NoRollbackFlow() { + final String __name__ = "prepare-external-primary-storage"; + + @Override + public void run(FlowTrigger trigger, Map data) { + doPrepareExternalPrimaryStorage(context, extPss, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }; + } + + @Override + public void kvmPingAgentNoFailure(KVMHostInventory host, NoErrorCompletion completion) { + List extPss = findExternalPsByClusterUuid(host.getClusterUuid()); + if (extPss.isEmpty()) { + completion.done(); + return; + } + + checkHostStatus(host, extPss, new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errList) { + completion.done(); + } + }); + } + + private void doPrepareExternalPrimaryStorage(final KVMHostConnectedContext context, List extPss, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName("do-prepare-external-primary-storage"); + chain.then(new NoRollbackFlow() { + String __name__ = "deploy-client"; + + @Override + public void run(FlowTrigger trigger, Map data) { + deployClient(context, extPss, new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + // todo rollback + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "check-host-status"; + + @Override + public void run(FlowTrigger trigger, Map data) { + checkHostStatus(context.getInventory(), extPss, new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errList) { + data.put(KVMConstant.CONNECT_HOST_PRIMARYSTORAGE_ERROR, errList); + trigger.next(); + } + }); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).start(); + } + + private void deployClient(final KVMHostConnectedContext context, List extPss, WhileDoneCompletion completion) { + new While<>(extPss).each((extPs, compl) -> { + logger.debug(String.format("deploying client for external primary storage[uuid:%s, name:%s] on KVM host[uuid:%s, name:%s]", + extPs.getUuid(), extPs.getName(), context.getInventory().getUuid(), context.getInventory().getName())); + extPsFactory.getNodeSvc(extPs.getUuid()).deployClient(context.getInventory(), new Completion(compl) { + @Override + public void success() { + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.done(); + } + }); + }).run(completion); + } + + private void checkHostStatus(KVMHostInventory host, List extPss, WhileDoneCompletion completion) { + Map hostStatus = getHostStatus(extPss); + new While<>(extPss).each((extPs, compl) -> { + logger.debug(String.format("checking host status for external primary storage[uuid:%s, name:%s] on KVM host[uuid:%s, name:%s]", + extPs.getUuid(), extPs.getName(), host.getUuid(), host.getName())); + extPsFactory.getControllerSvc(extPs.getUuid()).reportNodeHealthy(host, new ReturnValueCompletion(compl) { + @Override + public void success(NodeHealthy returnValue) { + ErrorCode err = null; + PrimaryStorageHostStatus status; + // TODO add multi protocol support + if (returnValue.getHealthy().values().stream().allMatch(h -> h == StorageHealthy.Ok)) { + status = PrimaryStorageHostStatus.Connected; + } else { + status = PrimaryStorageHostStatus.Disconnected; + err = operr("external primary storage[uuid:%s, name:%s] returns unhealthy status: %s", + extPs.getUuid(), extPs.getName(), returnValue.getHealthy()); + compl.addError(err); + } + + if (hostStatus.get(extPs.getUuid()) != status) { + updateHostStatus(host.getUuid(), extPs.getUuid(), status, err, compl); + } else { + compl.done(); + } + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.done(); + } + + private void updateHostStatus(String hostUuid, String psUuid, PrimaryStorageHostStatus status, ErrorCode reason, NoErrorCompletion completion) { + UpdatePrimaryStorageHostStatusMsg msg = new UpdatePrimaryStorageHostStatusMsg(); + msg.setPrimaryStorageUuid(psUuid); + msg.setHostUuid(hostUuid); + msg.setStatus(status); + msg.setReason(reason); + bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, psUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + completion.done(); + } + }); + } + }); + }).run(completion); + } + + @Override + public List getStoragePathsForVolumeSync(HostInventory host, PrimaryStorageInventory attachedPs) { + if (!PrimaryStorageConstant.EXTERNAL_PRIMARY_STORAGE_TYPE.equals(attachedPs.getType())) { + return null; + } + + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(attachedPs.getUuid()); + if (nodeSvc == null) { + return null; + } + + return nodeSvc.getActiveVolumesLocation(host); + } + + @Override + public void handleInactiveVolume(HostInventory host, Map> inactiveVolumePaths, Completion completion) { + if (inactiveVolumePaths.isEmpty()) { + completion.success(); + return; + } + + new While<>(inactiveVolumePaths.entrySet()).all((entry, compl) -> { + PrimaryStorageInventory ps = entry.getKey(); + List paths = entry.getValue(); + + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(ps.getUuid()); + if (nodeSvc == null) { + compl.done(); + return; + } + + List infos = paths.stream() + .map(path -> nodeSvc.getActiveVolumeInfo(path, host, false)) + .collect(Collectors.toList()); + if (infos.isEmpty()) { + compl.done(); + return; + } + + // TODO: move to pre-check + List vmInUseVolUuids = SQL.New("select vol.uuid from VolumeVO vol, VmInstanceVO vm" + + " where vol.uuid in :volUuids" + + " and vol.vmInstanceUuid = vm.uuid" + + " and (vm.state in (:vmStates) or vm.hostUuid = :huuid)", String.class) + .param("vmStates", Arrays.asList(VmInstanceState.Starting, VmInstanceState.Migrating)) + .param("huuid", host.getUuid()) + .param("volUuids", infos.stream().map(BaseVolumeInfo::getUuid).collect(Collectors.toList())) + .list(); + if (!vmInUseVolUuids.isEmpty()) { + logger.debug(String.format("volumes[uuids:%s] are still in use by VMs, skip deactivating them", + vmInUseVolUuids)); + } + + infos.removeIf(info -> vmInUseVolUuids.contains(info.getUuid())); + new While<>(infos).each((info, c) -> { + if (info.getInstallPath() == null) { + VolumeVO volume = Q.New(VolumeVO.class).eq(VolumeVO_.uuid, info.getUuid()).find(); + if (volume == null) { + c.done(); + return; + } + + info.setInstallPath(volume.getInstallPath()); + info.setProtocol(volume.getProtocol()); + } + + nodeSvc.deactivate(info.getInstallPath(), info.getProtocol(), host, new Completion(c) { + @Override + public void success() { + c.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + c.addError(errorCode); + c.done(); + } + }); + }).run(new WhileDoneCompletion(compl) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + compl.addError(errorCodeList.getCauses().get(0)); + } + compl.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.success(); + } + }); + } + + @Override + public void beforeStartVmOnKvm(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommands.StartVmCmd cmd) { + List vols = getManagerExclusiveVolume(spec); + + for (VolumeInventory vol : vols) { + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(vol.getPrimaryStorageUuid()); + if (nodeSvc == null) { + continue; + } + + List clients = nodeSvc.getActiveClients(vol.getInstallPath(), vol.getProtocol()); + clients.forEach(client -> { + if (!client.getManagerIp().equals(host.getManagementIp()) && !client.isInBlacklist()) { + // hard code for zbs, zbs not support deactive and blacklist yet + if (vol.getProtocol().equals(ExternalStorageConstant.CBD_PROTOCOL)) { + throw new OperationFailureException(operr("find active clients for volume[uuid:%s, installPath %s, client:%s]", + vol.getUuid(), vol.getInstallPath(), client.getManagerIp())); + } + // TODO use async call + HostVO clientHost = Q.New(HostVO.class).eq(HostVO_.managementIp, client.getManagerIp()).find(); + if (clientHost != null) { + logger.debug(String.format("because volume[uuid:%s, installPath:%s] is in use by other KVM " + + "host[uuid:%s, ip:%s], but to start on host[uuid:%s, ip:%s], " + + "add it to blacklist if deactivate failed", + vol.getUuid(), vol.getInstallPath(), + clientHost.getUuid(), clientHost.getManagementIp(), + host.getUuid(), host.getManagementIp())); + + nodeSvc.deactivate(vol.getInstallPath(), vol.getProtocol(), client, new Completion(null) { + @Override + public void success() { + logger.info(String.format("successfully deactivate volume[uuid:%s, installPath:%s] on host[uuid:%s, ip:%s]", + vol.getUuid(), vol.getInstallPath(), clientHost.getUuid(), clientHost.getManagementIp())); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("failed to deactivate volume[uuid:%s, installPath:%s] on host[uuid:%s, ip:%s], add it to blacklist", + vol.getUuid(), vol.getInstallPath(), clientHost.getUuid(), clientHost.getManagementIp())); + nodeSvc.blacklist(vol.getInstallPath(), vol.getProtocol(), HostInventory.valueOf(clientHost), new NopeCompletion()); + } + }); + } + } + }); + } + } + + @Override + public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { + } + + @Override + public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { + } + + private PrimaryStorageNodeSvc getNodeService(VolumeInventory volumeInventory) { + String identity = volumeInventory.getInstallPath().split("://")[0]; + if (!extPsFactory.support(identity)) { + return null; + } + + return extPsFactory.getNodeSvc(volumeInventory.getPrimaryStorageUuid()); + } + + private List getManagerExclusiveVolume(VmInstanceSpec spec) { + List vols = new ArrayList<>(); + vols.add(spec.getDestRootVolume()); + vols.addAll(spec.getDestDataVolumes()); + + List pss = Q.New(ExternalPrimaryStorageVO.class) + .in(ExternalPrimaryStorageVO_.uuid, vols.stream().map(VolumeInventory::getPrimaryStorageUuid).collect(Collectors.toList())) + .list(); + Map psIdentities = pss.stream() + .collect(Collectors.toMap(ExternalPrimaryStorageVO::getUuid, ExternalPrimaryStorageVO::getIdentity)); + vols.removeIf(info -> { + if (info.getInstallPath() == null || info.isShareable() || !psIdentities.containsKey(info.getPrimaryStorageUuid())) { + return true; + } + return !extPsFactory.support(psIdentities.get(info.getPrimaryStorageUuid())); + }); + + return vols; + } + +} diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageApiClient.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageApiClient.java new file mode 100644 index 00000000000..3d1a5ffbf7f --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageApiClient.java @@ -0,0 +1,36 @@ +package org.zstack.externalStorage.sdk; + +import com.google.gson.FieldNamingPolicy; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import okhttp3.OkHttpClient; +import org.apache.poi.ss.formula.functions.T; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.Locale; + +/** + * @ Author : yh.w + * @ Date : Created in 15:14 2024/5/14 + */ +public abstract class ExternalStorageApiClient { + private static final CLogger logger = Utils.getLogger(ExternalStorageApiClient.class); + public static OkHttpClient http = new OkHttpClient(); + + public static final Gson gson; + public static final DateTimeFormatter formatter; + + public static final long ACTION_DEFAULT_TIMEOUT = -1; + public static final long ACTION_DEFAULT_POLLINGINTERVAL = -1; + + static { + gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create(); + formatter = new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .appendPattern("EEE, dd MMM yyyy HH:mm:ss VV") + .toFormatter(Locale.ENGLISH); + } +} diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageApiException.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageApiException.java new file mode 100644 index 00000000000..92d27afece2 --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageApiException.java @@ -0,0 +1,11 @@ +package org.zstack.externalStorage.sdk; + +public class ExternalStorageApiException extends RuntimeException { + public ExternalStorageApiException(String format) { + super(format); + } + + public ExternalStorageApiException(Exception e) { + super(e); + } +} diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageParam.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageParam.java new file mode 100644 index 00000000000..27c7c8e25bd --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/ExternalStorageParam.java @@ -0,0 +1,161 @@ +package org.zstack.externalStorage.sdk; + +import java.lang.reflect.Field; +import java.util.*; + +public interface ExternalStorageParam { + class Parameter { + Field field; + Param annotation; + } + + // API parameter + Map getParameterMap(); + + // TODO + default void initializeParametersIfNot() { + synchronized (getParameterMap()) { + if (getParameterMap().isEmpty()) { + List fields = getAllFields(); + + for (Field f : fields) { + Param at = f.getAnnotation(Param.class); + if (at == null) { + continue; + } + + Parameter p = new Parameter(); + p.field = f; + p.field.setAccessible(true); + + + + /* + NonAPIParam nonAPIParamAnnotation = f.getAnnotation(NonAPIParam.class); + + if(at == null){ + if(nonAPIParamAnnotation != null){ + getNonAPIParameterMap().put(f.getName(), p); + } + continue; + } + */ + + p.annotation = at; + + getParameterMap().put(f.getName(), p); + } + } + } + } + + default List getAllFields() { + Class c = getClass(); + List fs = new ArrayList<>(); + while (c != Object.class) { + Collections.addAll(fs, c.getDeclaredFields()); + c = c.getSuperclass(); + } + + return fs; + } + + default Set getAllParameterNames() { + initializeParametersIfNot(); + return getParameterMap().keySet(); + } + + default Object getParameterValue(String name){ + return getParameterValue(name, true); + } + + default boolean isQueryableParam(String name) { + return getParameterMap().get(name).annotation.queryable(); + } + + default Object getParameterValue(String name, boolean exceptionOnNotFound){ + return getParameterValue(getParameterMap(), name, exceptionOnNotFound); + } + + default Object getParameterValue(Map map, String name, boolean exceptionOnNotFound){ + Parameter p = map.get(name); + if (p == null) { + if (exceptionOnNotFound) { + throw new ExternalStorageApiException(String.format("no such parameter[%s]", name)); + } else { + return null; + } + } + + try { + return p.field.get(this); + } catch (IllegalAccessException e) { + throw new ExternalStorageApiException(e); + } + } + + default void checkParameters() { + initializeParametersIfNot(); + + try { + for (Parameter p : getParameterMap().values()) { + Object value = p.field.get(this); + Param at = p.annotation; + + if (at.required() && value == null) { + throw new ExternalStorageApiException(String.format("missing mandatory field[%s]", p.field.getName())); + } + + if (value == null) { + continue; + } + + if (value instanceof ExternalStorageParam) { + ((ExternalStorageParam) value).checkParameters(); + } + + if (at.validValues().length > 0) { + if (value instanceof Collection) { + for (Object v : (Collection) value) { + validateValue(at.validValues(), v.toString(), p.field.getName()); + } + } else { + validateValue(at.validValues(), value.toString(), p.field.getName()); + } + } + + if (at.numberRange().length > 0 && value instanceof Number) { + if (((Number) value).intValue() == 0) { + if (!at.nonempty()) { + continue; + } + } + + validateNumberRange(at.numberRange(), (Number) value, p.field.getName()); + } + } + } catch (ExternalStorageApiException e) { + throw e; + } catch (Exception e) { + throw new ExternalStorageApiException(e); + } + } + + static void validateValue(String[] validValues, String value, String fieldName) { + List vals = new ArrayList<>(); + for (String val: validValues) { + vals.add(val.toLowerCase()); + } + if (!vals.contains(value.toLowerCase())) { + throw new ExternalStorageApiException(String.format("invalid value of the field[%s], valid values are %s", + fieldName, vals)); + } + } + + static void validateNumberRange(long[] numberRange, Number value, String name) { + if (value.longValue() < numberRange[0] || value.longValue() > numberRange[1]) { + throw new ExternalStorageApiException(String.format("invalid value of the field[%s], valid range is [%s, %s]", + name, numberRange[0], numberRange[1])); + } + } +} diff --git a/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/Param.java b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/Param.java new file mode 100644 index 00000000000..0daaae1474d --- /dev/null +++ b/plugin/externalStorage/src/main/java/org/zstack/externalStorage/sdk/Param.java @@ -0,0 +1,18 @@ +package org.zstack.externalStorage.sdk; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target(java.lang.annotation.ElementType.FIELD) +@Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +public @interface Param { + boolean required() default true; + + String[] validValues() default {}; + + long[] numberRange() default {}; + + boolean nonempty() default false; + + boolean queryable() default false; +} diff --git a/plugin/flatNetworkProvider/pom.xml b/plugin/flatNetworkProvider/pom.xml index 2d2e91c84f9..1e768f5b2ea 100755 --- a/plugin/flatNetworkProvider/pom.xml +++ b/plugin/flatNetworkProvider/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 @@ -26,6 +26,11 @@ kvm ${project.version} + + org.zstack + sdnController + ${project.version} + diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressEvent.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressEvent.java new file mode 100644 index 00000000000..2df136e2637 --- /dev/null +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressEvent.java @@ -0,0 +1,43 @@ +package org.zstack.network.service.flat; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(fieldsTo = {"all"}) +public class APIChangeL3NetworkDhcpIpAddressEvent extends APIEvent { + private String dhcpServerIp; + private String dhcpv6ServerIp; + + public String getDhcpServerIp() { + return dhcpServerIp; + } + + public void setDhcpServerIp(String dhcpServerIp) { + this.dhcpServerIp = dhcpServerIp; + } + + public String getDhcpv6ServerIp() { + return dhcpv6ServerIp; + } + + public void setDhcpv6ServerIp(String dhcpv6ServerIp) { + this.dhcpv6ServerIp = dhcpv6ServerIp; + } + + public APIChangeL3NetworkDhcpIpAddressEvent() { + } + + public APIChangeL3NetworkDhcpIpAddressEvent(String apiId) { + super(apiId); + } + + public static APIChangeL3NetworkDhcpIpAddressEvent __example__() { + APIChangeL3NetworkDhcpIpAddressEvent reply = new APIChangeL3NetworkDhcpIpAddressEvent(); + + reply.setDhcpServerIp("192.168.100.3"); + reply.setDhcpv6ServerIp("2024:04:28:01::100"); + + return reply; + } + +} diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressEventDoc_zh_cn.groovy b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..22f04f48688 --- /dev/null +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressEventDoc_zh_cn.groovy @@ -0,0 +1,35 @@ +package org.zstack.network.service.flat + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "修改DHCP服务器地址清单" + + field { + name "dhcpServerIp" + desc "" + type "String" + since "5.1.0" + } + field { + name "dhcpv6ServerIp" + desc "" + type "String" + since "5.1.0" + } + field { + name "success" + desc "" + type "boolean" + since "5.1.0" + } + ref { + name "error" + path "org.zstack.network.service.flat.APIChangeL3NetworkDhcpIpAddressEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.1.0" + clz ErrorCode.class + } +} diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressMsg.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressMsg.java new file mode 100644 index 00000000000..5161c3c4fbf --- /dev/null +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressMsg.java @@ -0,0 +1,62 @@ +package org.zstack.network.service.flat; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l3.L3NetworkConstant; +import org.zstack.header.network.l3.L3NetworkMessage; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.rest.RestRequest; + +@Action(category = L3NetworkConstant.ACTION_CATEGORY) +@RestRequest( + path = "/l3-networks/{l3NetworkUuid}/dhcp-ip", + method = HttpMethod.PUT, + isAction = true, + responseClass = APIChangeL3NetworkDhcpIpAddressEvent.class +) +public class APIChangeL3NetworkDhcpIpAddressMsg extends APIMessage implements L3NetworkMessage { + @APIParam(resourceType = L3NetworkVO.class, checkAccount = true, operationTarget = true) + private String l3NetworkUuid; + @APIParam(required = false, nonempty = true) + private String dhcpServerIp; + @APIParam(required = false, nonempty = true) + private String dhcpv6ServerIp; + + @Override + public String getL3NetworkUuid() { + return l3NetworkUuid; + } + + public void setL3NetworkUuid(String l3NetworkUuid) { + this.l3NetworkUuid = l3NetworkUuid; + } + + public String getDhcpServerIp() { + return dhcpServerIp; + } + + public void setDhcpServerIp(String dhcpServerIp) { + this.dhcpServerIp = dhcpServerIp; + } + + public String getDhcpv6ServerIp() { + return dhcpv6ServerIp; + } + + public void setDhcpv6ServerIp(String dhcpv6ServerIp) { + this.dhcpv6ServerIp = dhcpv6ServerIp; + } + + public static APIChangeL3NetworkDhcpIpAddressMsg __example__() { + APIChangeL3NetworkDhcpIpAddressMsg msg = new APIChangeL3NetworkDhcpIpAddressMsg(); + + msg.setL3NetworkUuid(uuid()); + msg.setDhcpServerIp("192.168.1.100"); + msg.setDhcpv6ServerIp("2024:04:28:01::100"); + + return msg; + } + +} diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..d6c78c5c177 --- /dev/null +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIChangeL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.network.service.flat + +import org.zstack.network.service.flat.APIChangeL3NetworkDhcpIpAddressEvent + +doc { + title "ChangeL3NetworkDhcpIpAddress" + + category "flat.dhcp" + + desc """修改DHCP服务器地址""" + + rest { + request { + url "PUT /v1/l3-networks/{l3NetworkUuid}/dhcp-ip" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeL3NetworkDhcpIpAddressMsg.class + + desc """""" + + params { + + column { + name "l3NetworkUuid" + enclosedIn "changeL3NetworkDhcpIpAddress" + desc "三层网络UUID" + location "url" + type "String" + optional false + since "5.1.0" + } + column { + name "dhcpServerIp" + enclosedIn "changeL3NetworkDhcpIpAddress" + desc "DHCP v4 服务器地址" + location "body" + type "String" + optional true + since "5.1.0" + } + column { + name "dhcpv6ServerIp" + enclosedIn "changeL3NetworkDhcpIpAddress" + desc "DHCP v6 服务器地址" + location "body" + type "String" + optional true + since "5.1.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.1.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.1.0" + } + } + } + + response { + clz APIChangeL3NetworkDhcpIpAddressEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy index fe1a816d5b5..3d4e3557e0c 100644 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkDhcpIpAddressMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkIpStatisticMsgDoc_zh_cn.groovy b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkIpStatisticMsgDoc_zh_cn.groovy index 6c42e9d4f4a..45946569c0c 100644 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkIpStatisticMsgDoc_zh_cn.groovy +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/APIGetL3NetworkIpStatisticMsgDoc_zh_cn.groovy @@ -11,117 +11,110 @@ doc { rest { request { - url "GET /v1/l3-networks/{l3NetworkUuid}/ip-statistic" + url "GET /v1/l3-networks/{l3NetworkUuid}/ip-statistic" - header (Authorization: 'OAuth the-session-uuid') + header (Authorization: 'OAuth the-session-uuid') clz APIGetL3NetworkIpStatisticMsg.class desc """""" - - params { - - column { - name "l3NetworkUuid" - enclosedIn "" - desc "三层网络UUID" - location "url" - type "String" - optional false - since "3.7.0" - - } - column { - name "resourceType" - enclosedIn "" - desc "统计资源类型" - location "query" - type "String" - optional true - since "3.7.0" - values ("All","Vip","VM") - } - column { - name "ip" - enclosedIn "" - desc "指定IP地址" - location "query" - type "String" - optional true - since "3.7.0" - - } - column { - name "sortBy" - enclosedIn "" - desc "排序方式" - location "query" - type "String" - optional true - since "3.7.0" - values ("Ip","CreateDate") - } - column { - name "sortDirection" - enclosedIn "" - desc "排序方向" - location "query" - type "String" - optional true - since "3.7.0" - values ("asc","desc") - } - column { - name "start" - enclosedIn "" - desc "统计结果起始位置" - location "query" - type "Integer" - optional true - since "3.7.0" - - } - column { - name "limit" - enclosedIn "" - desc "统计结果数量" - location "query" - type "Integer" - optional true - since "3.7.0" - - } - column { - name "replyWithCount" - enclosedIn "" - desc "同时返回统计结果总数" - location "query" - type "boolean" - optional true - since "3.7.0" - - } - column { - name "systemTags" - enclosedIn "" - desc "系统标签" - location "query" - type "List" - optional true - since "3.7.0" - - } - column { - name "userTags" - enclosedIn "" - desc "用户标签" - location "query" - type "List" - optional true - since "3.7.0" - - } - } + + params { + + column { + name "l3NetworkUuid" + enclosedIn "" + desc "三层网络UUID" + location "url" + type "String" + optional false + since "3.7.0" + } + column { + name "resourceType" + enclosedIn "" + desc "统计资源类型" + location "query" + type "String" + optional true + since "3.7.0" + values ("All","Vip","VM") + } + column { + name "ip" + enclosedIn "" + desc "指定IP地址" + location "query" + type "String" + optional true + since "3.7.0" + } + column { + name "sortBy" + enclosedIn "" + desc "排序方式" + location "query" + type "String" + optional true + since "3.7.0" + values ("Ip","CreateDate") + } + column { + name "sortDirection" + enclosedIn "" + desc "排序方向" + location "query" + type "String" + optional true + since "3.7.0" + values ("asc","desc") + } + column { + name "start" + enclosedIn "" + desc "统计结果起始位置" + location "query" + type "Integer" + optional true + since "3.7.0" + } + column { + name "limit" + enclosedIn "" + desc "统计结果数量" + location "query" + type "Integer" + optional true + since "3.7.0" + } + column { + name "replyWithCount" + enclosedIn "" + desc "同时返回统计结果总数" + location "query" + type "boolean" + optional true + since "3.7.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "3.7.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "3.7.0" + } + } } response { diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/BridgeVlanIdFinder.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/BridgeVlanIdFinder.java new file mode 100644 index 00000000000..02e71a1a217 --- /dev/null +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/BridgeVlanIdFinder.java @@ -0,0 +1,71 @@ +package org.zstack.network.service.flat; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.kvm.KVMSystemTags; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.codehaus.groovy.runtime.InvokerHelper.asList; + +/** + * Created by boce.wang on 03/12/2024. + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class BridgeVlanIdFinder { + @Autowired + private DatabaseFacade dbf; + + public String findByL2Uuid(String l2Uuid) { + return findByL2Uuid(l2Uuid, true); + } + + public String findByL2Uuid(String l2Uuid, boolean exceptionOnNotFound) { + Map bridgesVlan = findByL2Uuids(asList(l2Uuid)); + String bridge = KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2Uuid, KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + if (bridgesVlan.get(bridge) == null && exceptionOnNotFound) { + throw new CloudRuntimeException(String.format("cannot find L2 bridge vlan id for the L2 network[uuid:%s]", + l2Uuid)); + } + return bridgesVlan.get(bridge); + } + + @Transactional(readOnly = true) + public Map findByL2Uuids(Collection l2Uuids) { + if (l2Uuids == null || l2Uuids.isEmpty()) { + return new HashMap<>(); + } + Map bridgesVlan = new HashMap<>(); + List l2Vos = Q.New(L2NetworkVO.class).in(L2NetworkVO_.uuid, asList(l2Uuids)).list(); + l2Vos.forEach(l2 -> { + String bridge = KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2.getUuid(), KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + if (bridge != null && l2.getVirtualNetworkId() != null && !l2.getVirtualNetworkId().equals(0)) { + // ugly if condition due to history vlan usage which embed in the legacy bridge name + if (!bridge.contains(l2.getVirtualNetworkId().toString())) { + String vlanId = ""; + if (l2.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE)) { + vlanId = "vlan" + l2.getVirtualNetworkId(); + } else if (l2.getType().equals(L2NetworkConstant.VXLAN_NETWORK_POOL_TYPE) || + l2.getType().equals(L2NetworkConstant.VXLAN_NETWORK_TYPE)) { + vlanId = "vxlan" + l2.getVirtualNetworkId(); + } + if (!vlanId.isEmpty()) { + bridgesVlan.put(bridge, vlanId); + } + } + } + }); + return bridgesVlan; + } +} diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/DhcpApply.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/DhcpApply.java index c43b09b5f3b..018d0f0d59e 100644 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/DhcpApply.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/DhcpApply.java @@ -92,6 +92,9 @@ FlatDhcpBackend.PrepareDhcpCmd getPrepareDhcpCmd() { FlatDhcpBackend.PrepareDhcpCmd cmd = new FlatDhcpBackend.PrepareDhcpCmd(); cmd.bridgeName = i.bridgeName; + if (i.vlanId != null) { + cmd.vlanId = i.vlanId; + } cmd.namespaceName = i.namespaceName; if (dhcp4Server != null) { cmd.dhcpServerIp = dhcp4Server.getIp(); diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDHCPDeleteNamespaceGC.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDHCPDeleteNamespaceGC.java index c91e2d08faf..15f6bca7a7f 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDHCPDeleteNamespaceGC.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDHCPDeleteNamespaceGC.java @@ -19,6 +19,8 @@ public class FlatDHCPDeleteNamespaceGC extends EventBasedGarbageCollector { @GC public FlatDhcpBackend.DeleteNamespaceCmd command; @GC + public String path; + @GC public String hostUuid; @Override @@ -29,7 +31,7 @@ protected void triggerNow(GCCompletion completion) { return; } - new KvmCommandSender(hostUuid).send(command, FlatDhcpBackend.DHCP_DELETE_NAMESPACE_PATH, + new KvmCommandSender(hostUuid).send(command, path, wrapper -> { FlatDhcpBackend.DeleteNamespaceRsp rsp = wrapper.getResponse(FlatDhcpBackend.DeleteNamespaceRsp.class); return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java index 42fb838e770..2300f17cae2 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpBackend.java @@ -1,36 +1,43 @@ package org.zstack.network.service.flat; +import com.googlecode.ipv6.IPv6Address; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.vm.StaticIpOperator; import org.zstack.compute.vm.VmSystemTags; +import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; -import org.zstack.core.db.*; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.GLock; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; import org.zstack.core.defer.Defer; import org.zstack.core.defer.Deferred; import org.zstack.core.thread.SyncTask; import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.AbstractService; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.core.*; -import org.zstack.header.core.workflow.Flow; -import org.zstack.header.core.workflow.FlowRollback; -import org.zstack.header.core.workflow.FlowTrigger; -import org.zstack.header.core.workflow.NoRollbackFlow; +import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.host.HostConstant; -import org.zstack.header.host.HostErrors; +import org.zstack.header.host.*; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; +import org.zstack.header.network.IpAllocatedReason; +import org.zstack.header.network.l2.L2NetworkClusterRefVO; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.L2NetworkVO; import org.zstack.header.network.l3.*; import org.zstack.header.network.service.*; import org.zstack.header.vm.*; @@ -38,12 +45,17 @@ import org.zstack.identity.AccountManager; import org.zstack.kvm.*; import org.zstack.kvm.KvmCommandSender.SteppingSendCallback; +import org.zstack.network.l3.CheckIpAddressAvailabilityExtensionPoint; +import org.zstack.network.l3.L3NetworkManager; import org.zstack.network.service.DhcpExtension; import org.zstack.network.service.NetworkProviderFinder; +import org.zstack.network.service.NetworkServiceHelper.HostRouteInfo; import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.NetworkServiceProviderLookup; import org.zstack.network.service.flat.IpStatisticConstants.VmType; import org.zstack.network.service.vip.VipVO; +import org.zstack.header.network.service.SdnControllerDhcp; +import org.zstack.sdnController.SdnControllerManager; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; @@ -58,13 +70,19 @@ import javax.persistence.Query; import javax.persistence.Tuple; import javax.persistence.TypedQuery; +import java.math.BigInteger; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import static org.zstack.core.Platform.*; +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.argerr; +import static org.zstack.core.Platform.operr; +import static org.zstack.network.service.NetworkServiceHelper.getL3NetworkHostRoute; import static org.zstack.network.service.flat.IpStatisticConstants.ResourceType; import static org.zstack.network.service.flat.IpStatisticConstants.SortBy; import static org.zstack.utils.CollectionDSL.*; @@ -74,7 +92,7 @@ */ public class FlatDhcpBackend extends AbstractService implements NetworkServiceDhcpBackend, KVMHostConnectExtensionPoint, L3NetworkDeleteExtensionPoint, VmInstanceMigrateExtensionPoint, VmAbnormalLifeCycleExtensionPoint, IpRangeDeletionExtensionPoint, - BeforeStartNewCreatedVmExtensionPoint, GlobalApiMessageInterceptor, AfterAddIpRangeExtensionPoint { + BeforeStartNewCreatedVmExtensionPoint, GlobalApiMessageInterceptor, AfterAddIpRangeExtensionPoint, DnsServiceExtensionPoint, CheckIpAddressAvailabilityExtensionPoint { private static final CLogger logger = Utils.getLogger(FlatDhcpBackend.class); @Autowired @@ -91,6 +109,10 @@ public class FlatDhcpBackend extends AbstractService implements NetworkServiceDh private DhcpExtension dhcpExtension; @Autowired private NetworkServiceManager nwServiceMgr; + @Autowired + protected L3NetworkManager l3NwMgr; + @Autowired + protected SdnControllerManager sdnMgr; private Map getIpStatisticExts = new HashMap<>(); @@ -102,16 +124,18 @@ public class FlatDhcpBackend extends AbstractService implements NetworkServiceDh public static final String DHCP_CONNECT_PATH = "/flatnetworkprovider/dhcp/connect"; public static final String RESET_DEFAULT_GATEWAY_PATH = "/flatnetworkprovider/dhcp/resetDefaultGateway"; public static final String DHCP_DELETE_NAMESPACE_PATH = "/flatnetworkprovider/dhcp/deletenamespace"; + public static final String DHCP_FLUSH_NAMESPACE_PATH = "/flatnetworkprovider/dhcp/flush"; + public static final String ARPING_NAMESPACE_PATH = "/flatnetworkprovider/arping"; public static String makeNamespaceName(String brName, String l3Uuid) { return String.format("%s_%s", brName, l3Uuid); } @Transactional(readOnly = true) - private List getDhcpInfoForConnectedKvmHost(KVMHostConnectedContext context) { + private List getDhcpInfoForConnectedKvmHost(HostInventory hostInv, String l3Uuid) { String sql = "select vm from VmInstanceVO vm where vm.hostUuid = :huuid and vm.state in (:states) and vm.type = :vtype"; TypedQuery q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); - q.setParameter("huuid", context.getInventory().getUuid()); + q.setParameter("huuid", hostInv.getUuid()); q.setParameter("states", list(VmInstanceState.Running, VmInstanceState.Unknown, VmInstanceState.Starting, VmInstanceState.Rebooting, VmInstanceState.Resuming, VmInstanceState.Migrating, VmInstanceState.VolumeMigrating)); q.setParameter("vtype", VmInstanceConstant.USER_VM_TYPE); @@ -122,17 +146,21 @@ private List getDhcpInfoForConnectedKvmHost(KVMHostConnectedContext co List vmUuids = vmVos.stream().map(VmInstanceVO::getUuid).collect(Collectors.toList()); sql = "select nic.uuid from VmNicVO nic, L3NetworkVO l3, NetworkServiceL3NetworkRefVO ref, NetworkServiceProviderVO provider, UsedIpVO ip" + - " where nic.uuid = ip.vmNicUuid and nic.type <> :nicType and ip.l3NetworkUuid = l3.uuid" + + " where nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = l3.uuid" + " and ref.l3NetworkUuid = l3.uuid and ref.networkServiceProviderUuid = provider.uuid " + - " and ref.networkServiceType = :dhcpType " + - " and provider.type = :ptype and nic.vmInstanceUuid in (:vmUuids) group by nic.uuid"; + " and ref.networkServiceType = :dhcpType "; + if (l3Uuid != null) { + sql += " and l3.uuid = :l3Uuid "; + } + sql += " and provider.type = :ptype and nic.vmInstanceUuid in (:vmUuids) group by nic.uuid"; TypedQuery nq = dbf.getEntityManager().createQuery(sql, String.class); nq.setParameter("ptype", FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING); nq.setParameter("dhcpType", NetworkServiceType.DHCP.toString()); nq.setParameter("vmUuids", vmUuids); - // TODO: we will support vDPA dhcp in future - nq.setParameter("nicType", "vDPA"); + if (l3Uuid != null) { + nq.setParameter("l3Uuid", l3Uuid); + } List nicUuids = nq.getResultList(); if (nicUuids.isEmpty()) { return null; @@ -174,11 +202,207 @@ private void handleApiMessage(APIMessage msg) { handle((APIGetL3NetworkDhcpIpAddressMsg) msg); } else if (msg instanceof APIGetL3NetworkIpStatisticMsg) { handle((APIGetL3NetworkIpStatisticMsg) msg); + } else if (msg instanceof APIChangeL3NetworkDhcpIpAddressMsg) { + handle((APIChangeL3NetworkDhcpIpAddressMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } + private void handle(APIChangeL3NetworkDhcpIpAddressMsg msg) { + APIChangeL3NetworkDhcpIpAddressEvent event = new APIChangeL3NetworkDhcpIpAddressEvent(msg.getId()); + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + List ip4Ranges = l3VO.getIpRanges().stream().filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv4).collect(Collectors.toList()); + List ip6Ranges = l3VO.getIpRanges().stream().filter( + ipr -> ipr.getIpVersion() == IPv6Constants.IPv6 && !ipr.getAddressMode().equals(IPv6Constants.SLAAC)) + .collect(Collectors.toList()); + + SdnControllerDhcp sdnDhcp = sdnMgr.getSdnControllerDhcp(msg.getL3NetworkUuid()); + + /* + * step #1, delete old dhcp server ip + * step #2, allocate new dhcp server ip + * step #3, flush new dhcp config to host + * */ + FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("change-dhcp-server-ip-fo-l3-%s", msg.getL3NetworkUuid())); + + chain.then(new Flow() { + String __name__ = "delete-old-dhcp-server-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + Map dhcpMap = getExistingDhcpServerIp(msg.getL3NetworkUuid(), IPv6Constants.DUAL_STACK); + if (dhcpMap.isEmpty()) { + trigger.next(); + return; + } + + data.put("oldServerIp", dhcpMap); + for (Map.Entry e : dhcpMap.entrySet()) { + if (IPv6NetworkUtils.isValidIpv4(e.getKey()) && msg.getDhcpServerIp() != null) { + deleteDhcpServerIp(msg.getL3NetworkUuid(), e.getKey(), e.getValue()); + } else if (IPv6NetworkUtils.isIpv6Address(e.getKey()) && msg.getDhcpv6ServerIp() != null) { + deleteDhcpServerIp(msg.getL3NetworkUuid(), e.getKey(), e.getValue()); + } + } + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + Map dhcpMap = (Map) data.get("oldServerIp"); + if (dhcpMap == null || dhcpMap.isEmpty()) { + trigger.rollback(); + return; + } + + for (Map.Entry e : dhcpMap.entrySet()) { + String dhcpIp = null; + if (IPv6NetworkUtils.isValidIpv4(e.getKey()) && msg.getDhcpServerIp() != null) { + boolean allocate_ip = false; + for (IpRangeVO ipr : ip4Ranges) { + if (NetworkUtils.isInRange(e.getKey(), ipr.getStartIp(), ipr.getEndIp())) { + allocate_ip = true; + break; + } + } + dhcpIp = allocateDhcpIp(msg.getL3NetworkUuid(), IPv6Constants.IPv4, allocate_ip, e.getKey(), null); + } else if (IPv6NetworkUtils.isIpv6Address(e.getKey()) && msg.getDhcpv6ServerIp() != null){ + boolean allocate_ip = false; + for (IpRangeVO ipr : ip6Ranges) { + if (IPv6NetworkUtils.isIpv6InRange(e.getKey(), ipr.getStartIp(), ipr.getEndIp())) { + allocate_ip = true; + break; + } + } + dhcpIp = allocateDhcpIp(msg.getL3NetworkUuid(), IPv6Constants.IPv6, allocate_ip, e.getKey(), null); + } + + if (dhcpIp == null || !dhcpIp.equals(e.getKey())) { + logger.error(String.format("roll back dhcp server ip to [%s], but got [%s]", e.getKey(), dhcpIp)); + } + } + + trigger.rollback(); + } + }).then(new Flow() { + String __name__ = "allocate-new-dhcp-server-ip"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (msg.getDhcpServerIp() != null) { + boolean allocate_ip = false; + for (IpRangeVO ipr : ip4Ranges) { + if (NetworkUtils.isInRange(msg.getDhcpServerIp(), ipr.getStartIp(), ipr.getEndIp())) { + allocate_ip = true; + break; + } + } + + String dhcpIp = allocateDhcpIp(msg.getL3NetworkUuid(), IPv6Constants.IPv4, allocate_ip, msg.getDhcpServerIp(), null); + if (dhcpIp == null || !dhcpIp.equals(msg.getDhcpServerIp())) { + trigger.fail(operr("change dhcp server ip to [%s], but got [%s]", msg.getDhcpServerIp(), dhcpIp)); + return; + } + } + + if (msg.getDhcpv6ServerIp() != null) { + boolean allocate_ip = false; + for (IpRangeVO ipr : ip6Ranges) { + if (IPv6NetworkUtils.isIpv6InRange(msg.getDhcpv6ServerIp(), ipr.getStartIp(), ipr.getEndIp())) { + allocate_ip = true; + break; + } + } + + String dhcpIp = allocateDhcpIp(msg.getL3NetworkUuid(), IPv6Constants.IPv6, allocate_ip, msg.getDhcpv6ServerIp(), null); + if (dhcpIp == null || !dhcpIp.equals(msg.getDhcpv6ServerIp())) { + trigger.fail(operr("change dhcp server ip to [%s], but got [%s]", msg.getDhcpv6ServerIp(), dhcpIp)); + } + } + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (msg.getDhcpServerIp() != null) { + deleteDhcpServerIp(msg.getL3NetworkUuid(), msg.getDhcpServerIp()); + } + + if (msg.getDhcpv6ServerIp() != null) { + deleteDhcpServerIp(msg.getL3NetworkUuid(), msg.getDhcpv6ServerIp()); + } + + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "refresh-dhcp-server-on-hosts"; + + @Override + public boolean skip(Map data) { + return sdnDhcp != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + refreshDhcpInfoToHosts(l3VO, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "refresh-dhcp-server-on-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnDhcp == null) { + trigger.next(); + return; + } + + sdnDhcp.enableDhcp(Collections.singletonList(L3NetworkInventory.valueOf(l3VO)), + new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + event.setError(errCode); + bus.publish(event); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + Map dhcpMap = getExistingDhcpServerIp(msg.getL3NetworkUuid(), IPv6Constants.DUAL_STACK); + for (Map.Entry e : dhcpMap.entrySet()) { + if (IPv6NetworkUtils.isValidIpv4(e.getKey())) { + event.setDhcpServerIp(e.getKey()); + } else { + event.setDhcpv6ServerIp(e.getKey()); + } + } + bus.publish(event); + } + }).start(); + } + private void handle(APIGetL3NetworkIpStatisticMsg msg) { APIGetL3NetworkIpStatisticReply reply = new APIGetL3NetworkIpStatisticReply(); List ipStatistics = doStatistic(msg); @@ -244,29 +468,33 @@ private Long countResource(APIGetL3NetworkIpStatisticMsg msg) { private List ipStatisticAll(APIGetL3NetworkIpStatisticMsg msg, String sortBy) { /* select uip.ip, vip.uuid as vipUuid, vip.name as vipName, it.uuid as vmInstanceUuid, it.name as vmInstanceName, it.type, uip.createDate - from (select uuid, ip, IpInLong, createDate, vmNicUuid + from (select uuid, ip, IpInLong, ipInBinary, createDate, vmNicUuid from UsedIpVO where l3NetworkUuid = '{uuid}' [and ip like '{ip}'] - order by {sortBy} {direction} + order by LENGTH({sortBy}) {direction}, {sortBy} {direction} limit {limit} offset {start}) uip left join (select uuid, name, usedIpUuid from VipVO where l3NetworkUuid = '{l3Uuid}') vip on uip.uuid = vip.usedIpUuid left join (select uuid, vmInstanceUuid from VmNicVO) nic on uip.vmNicUuid = nic.uuid left join (select uuid, name, type from VmInstanceVO) it on nic.vmInstanceUuid = it.uuid - order by {sortBy} {direction}; + order by LENGTH({sortBy}) {direction}, {sortBy} {direction}; */ + if (SortBy.IP.equals(msg.getSortBy())) { + sortBy = "ipInBinary"; + } Map dhcpMap = getExistingDhcpServerIp(msg.getL3NetworkUuid(), IPv6Constants.DUAL_STACK); Set dhcp = dhcpMap.keySet(); StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.append("select uip.ip, vip.uuid as vipUuid, vip.name as vipName, it.uuid as vmUuid, it.name as vmName, it.type, uip.createDate ") - .append("from (select uuid, ip, ipInLong, createDate, vmNicUuid from UsedIpVO where l3NetworkUuid = '") + .append("from (select uuid, ip, ipInLong, ipInBinary, createDate, vmNicUuid from UsedIpVO where l3NetworkUuid = '") .append(msg.getL3NetworkUuid()).append('\''); if (StringUtils.isNotEmpty(msg.getIp())) { sqlBuilder.append(" and ip like '").append(msg.getIp()).append('\''); } - sqlBuilder.append(" order by ").append(sortBy).append(' ').append(msg.getSortDirection()).append(" limit ") + sqlBuilder.append(" order by LENGTH(").append(sortBy).append(") ").append(msg.getSortDirection()) + .append(", ").append(sortBy).append(" ").append(msg.getSortDirection()).append(" limit ") .append(msg.getLimit()).append(" offset ").append(msg.getStart()).append(") uip ") .append("left join ") .append("(select uuid, name, usedIpUuid from VipVO ") @@ -276,7 +504,8 @@ left join (select uuid, name, type from VmInstanceVO) it on nic.vmInstanceUuid = .append("(select uuid, vmInstanceUuid from VmNicVO) nic on uip.vmNicUuid = nic.uuid ") .append("left join ") .append("(select uuid, name, type from VmInstanceVO) it on it.uuid = nic.vmInstanceUuid ") - .append("order by ").append(sortBy).append(' ').append(msg.getSortDirection()); + .append("order by LENGTH(").append(sortBy).append(") ").append(msg.getSortDirection()) + .append(", ").append(sortBy).append(" ").append(msg.getSortDirection()); Query q = dbf.getEntityManager().createNativeQuery(sqlBuilder.toString()); List results = q.getResultList(); @@ -292,10 +521,14 @@ left join (select uuid, name, type from VmInstanceVO) it on nic.vmInstanceUuid = ownedVips.addAll(acntMgr.getResourceUuidsCanAccessByAccount(msg.getSession().getAccountUuid(), VipVO.class)); } + Map ipToVip= new HashMap<>(); for (Object[] result : results) { IpStatisticData element = new IpStatisticData(); ipStatistics.add(element); element.setIp((String) result[0]); + if(result[1] != null) { + ipToVip.put((String) result[0], (String) result[1]); + } List resourceTypes = new ArrayList<>(); element.setResourceTypes(resourceTypes); if (dhcp.contains(element.getIp())) { @@ -334,6 +567,7 @@ left join (select uuid, name, type from VmInstanceVO) it on nic.vmInstanceUuid = Map vrInfos = getApplianceVmInfo(vmUuids); + List copiedElements = new ArrayList<>(); for (IpStatisticData element : ipStatistics) { if (element.getVmInstanceUuid() != null) { Tuple vrInfo = vrInfos.get(element.getVmInstanceUuid()); @@ -355,9 +589,36 @@ left join (select uuid, name, type from VmInstanceVO) it on nic.vmInstanceUuid = L3NetworkGetIpStatisticExtensionPoint exp = getExtensionPointFactory(element.getVmInstanceType()); if (exp != null) { - element.setApplianceVmOwnerUuid(exp.getParentUuid(element.getVmInstanceUuid())); + List ownerUuids = exp.getParentUuid(element.getVmInstanceUuid(), element.getVipUuid()); + if (ownerUuids.size() == 0) { + element.setApplianceVmOwnerUuid(element.getVmInstanceUuid()); + } else if (ownerUuids.size() == 1) { + element.setApplianceVmOwnerUuid(ownerUuids.get(0)); + } else { + element.setApplianceVmOwnerUuid(ownerUuids.get(0)); + int cn = 1; + while(cn < ownerUuids.size()) { + IpStatisticData copy = new IpStatisticData(); + copy.setIp(element.getIp()); + copy.setVipUuid(element.getVipUuid()); + copy.setVipName(element.getVipName()); + copy.setVmInstanceUuid(element.getVmInstanceUuid()); + copy.setVmInstanceName(element.getVmInstanceName()); + copy.setVmInstanceType(element.getVmInstanceType()); + copy.setResourceTypes(element.getResourceTypes()); + copy.setState(element.getState()); + copy.setUseFor(element.getUseFor()); + copy.setCreateDate(element.getCreateDate()); + copy.setOwnerName(element.getOwnerName()); + copy.setVmDefaultIp(element.getVmDefaultIp()); + copy.setApplianceVmOwnerUuid(ownerUuids.get(cn)); + copiedElements.add(copy); + cn = cn + 1; + } + } } } + ipStatistics.addAll(copiedElements); return ipStatistics; } @@ -501,7 +762,7 @@ left join (select uuid, name, state, type, createDate from VmInstanceVO) vm on n sqlBuilder.append(") nic ") .append("left join (select uuid, name from AccountVO) ac on ac.uuid = nic.accountUuid ") .append("left join (select uuid, name, createDate, state, type from VmInstanceVO) vm ") - .append("on vm.uuid = nic.vmInstanceUuid") + .append("on vm.uuid = nic.vmInstanceUuid where vm.type = 'UserVm'") .append(" order by ").append(sortBy).append(' ').append(msg.getSortDirection()); if (!byIp) { sqlBuilder.append(" limit ").append(msg.getLimit()).append(" offset ").append(msg.getStart()); @@ -541,7 +802,6 @@ left join (select uuid, name, state, type, createDate from VmInstanceVO) vm on n Map vmvos = vms.stream() .collect(Collectors.toMap(VmInstanceVO::getUuid, inv -> inv)); Map> vmToDefaultIpMap = new HashMap<>(); - Map vrInfos = getApplianceVmInfo(vmUuids); for (IpStatisticData element : ipStatistics) { VmInstanceVO vmvo = vmvos.get(element.getVmInstanceUuid()); @@ -570,18 +830,6 @@ left join (select uuid, name, state, type, createDate from VmInstanceVO) vm on n } else { element.setVmDefaultIp(vmToDefaultIpMap.get(vmvo.getUuid())); } - - if (element.getVmInstanceUuid() != null) { - Tuple vrInfo = vrInfos.get(element.getVmInstanceUuid()); - if (vrInfo != null) { - String vmInstanceType = vrInfo.get(1, String.class); - L3NetworkGetIpStatisticExtensionPoint exp = getExtensionPointFactory(vmInstanceType); - if (exp != null) { - element.setApplianceVmOwnerUuid(exp.getParentUuid(element.getVmInstanceUuid())); - } - } - } - } return ipStatistics; @@ -604,8 +852,9 @@ private Map getApplianceVmInfo(List vmUuids) { private Long countVMNicIp(APIGetL3NetworkIpStatisticMsg msg) { if (acntMgr.isAdmin(msg.getSession())) { - String sql = "select count(*) from UsedIpVO u, VmNicVO n " + - "where u.l3NetworkUuid = :l3Uuid and u.vmNicUuid = n.uuid"; + String sql = "select count(*) from UsedIpVO u, VmNicVO n, VmInstanceVO i " + + "where u.l3NetworkUuid = :l3Uuid and u.vmNicUuid = n.uuid and n.vmInstanceUuid = i.uuid " + + "and i.type = 'UserVm'"; if (StringUtils.isNotEmpty(msg.getIp())) { sql += " and u.ip like '" + msg.getIp() + '\''; } @@ -613,9 +862,9 @@ private Long countVMNicIp(APIGetL3NetworkIpStatisticMsg msg) { .param("l3Uuid", msg.getL3NetworkUuid()) .find(); } else { - String sql = "select count(*) from UsedIpVO u, VmNicVO n, AccountResourceRefVO a " + - "where a.accountUuid = :accUuid and u.l3NetworkUuid = :l3Uuid " + - "and u.vmNicUuid = n.uuid and n.uuid = a.resourceUuid"; + String sql = "select count(*) from UsedIpVO u, VmNicVO n, VmInstanceVO i, AccountResourceRefVO a " + + "where a.accountUuid = :accUuid and u.l3NetworkUuid = :l3Uuid and i.type = 'UserVm'" + + "and u.vmNicUuid = n.uuid and n.vmInstanceUuid = i.uuid and n.uuid = a.resourceUuid"; if (StringUtils.isNotEmpty(msg.getIp())) { sql += " and u.ip like '" + msg.getIp() + '\''; } @@ -646,20 +895,16 @@ private void handle(APIGetL3NetworkDhcpIpAddressMsg msg) { } Map dhcpServerMap = getExistingDhcpServerIp(msg.getL3NetworkUuid(), IPv6Constants.DUAL_STACK); - if (dhcpServerMap.isEmpty()) { - reply.setError(operr("Cannot find DhcpIp for l3 network[uuid:%s]", msg.getL3NetworkUuid())); - } else { - for (Map.Entry entry : dhcpServerMap.entrySet()) { - String ip = entry.getKey(); - if (NetworkUtils.isIpv4Address(ip)) { + for (Map.Entry entry : dhcpServerMap.entrySet()) { + String ip = entry.getKey(); + if (NetworkUtils.isIpv4Address(ip)) { + reply.setIp(ip); + } else { + reply.setIp6(ip); + int l3IpVersion = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).select(L3NetworkVO_.ipVersion).findValue(); + if (l3IpVersion == IPv6Constants.IPv6) { + /* to be compatible with old version, dhcp server address of ipv6 only l3 network is filled in this field */ reply.setIp(ip); - } else { - reply.setIp6(ip); - int l3IpVersion = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).select(L3NetworkVO_.ipVersion).findValue(); - if (l3IpVersion == IPv6Constants.IPv6) { - /* to be compitable with old version, dhcp server address of ipv6 only l3 network is filled in this field */ - reply.setIp(ip); - } } } } @@ -675,7 +920,7 @@ String allocateDhcpIp(String l3Uuid, int ipVersion, String excludedIp) { return allocateDhcpIp(l3Uuid, ipVersion, true, null, excludedIp); } - private static Map getExistingDhcpServerIp(String l3Uuid, int ipVersion) { + public static Map getExistingDhcpServerIp(String l3Uuid, int ipVersion) { Map ret = new HashMap<>(); List tags = FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.getTags(l3Uuid); if (tags != null) { @@ -702,7 +947,7 @@ private static Map getExistingDhcpServerIp(String l3Uuid, int ip @Deferred private String allocateDhcpIp(String l3Uuid, int ipVersion, boolean allocate_ip, String requiredIp, String excludedIp) { - if (!isProvidedByMe(l3Uuid)) { + if (!isAllocateDhcpServerIp(l3Uuid)) { return null; } @@ -732,11 +977,16 @@ private String allocateDhcpIp(String l3Uuid, int ipVersion, boolean allocate_ip, amsg.setRequiredIp(requiredIp); } amsg.setIpVersion(ipVersion); + if (ipVersion == IPv6Constants.IPv4) { + amsg.setAllocateStrategy(L3NetworkConstant.FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY); + } else { + amsg.setAllocateStrategy(L3NetworkConstant.FIRST_AVAILABLE_IPV6_ALLOCATOR_STRATEGY); + } amsg.setExcludedIp(excludedIp); bus.makeTargetServiceIdByResourceUuid(amsg, L3NetworkConstant.SERVICE_ID, l3Uuid); MessageReply reply = bus.call(amsg); if (!reply.isSuccess()) { - throw new OperationFailureException(reply.getError()); + return null; } AllocateIpReply r = reply.castReply(); @@ -821,11 +1071,131 @@ public String getId() { return bus.makeLocalServiceId(FlatNetworkServiceConstant.SERVICE_ID); } + public void upgradeFlatDhcpServerIp() { + NetworkServiceProviderVO nsVO = Q.New(NetworkServiceProviderVO.class) + .eq(NetworkServiceProviderVO_.type, FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE.toString()) + .find(); + List l3NetworkVos = Q.New(L3NetworkVO.class).list(); + for (L3NetworkVO l3vo : l3NetworkVos) { + List dhcps = l3vo.getNetworkServices().stream() + .filter(ref -> ref.getNetworkServiceType().equals(NetworkServiceType.DHCP.toString()) + && ref.getNetworkServiceProviderUuid().equals(nsVO.getUuid())) + .collect(Collectors.toList()); + if (dhcps.isEmpty()) { + /* no dhcp service */ + continue; + } + + List ipVersions = l3vo.getIpVersions(); + if (ipVersions.size() == 1) { + Integer ipVersion = ipVersions.get(0); + if (ipVersion == IPv6Constants.IPv4) { + Map dhcpMap = getExistingDhcpServerIp(l3vo.getUuid(), IPv6Constants.IPv4); + if (dhcpMap.isEmpty()) { + AllocateIpMsg msg = new AllocateIpMsg(); + msg.setL3NetworkUuid(l3vo.getUuid()); + IpAllocatorType strategyType = IpAllocatorType.valueOf(L3NetworkConstant.FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY); + IpAllocatorStrategy ias = l3NwMgr.getIpAllocatorStrategy(strategyType); + UsedIpInventory ip = ias.allocateIp(msg); + + SystemTagCreator creator = FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.newSystemTagCreator(l3vo.getUuid()); + creator.inherent = true; + creator.setTagByTokens( + map( + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN, ip.getIp()), + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_UUID_TOKEN, ip.getUuid()) + ) + ); + creator.create(); + + for (DhcpServerExtensionPoint exp : pluginRgty.getExtensionList(DhcpServerExtensionPoint.class)) { + exp.afterAllocateDhcpServerIP(l3vo.getUuid(), ip.getIp()); + } + } + } else { + Map dhcpMap = getExistingDhcpServerIp(l3vo.getUuid(), IPv6Constants.IPv6); + if (dhcpMap.isEmpty()) { + AllocateIpMsg msg = new AllocateIpMsg(); + msg.setL3NetworkUuid(l3vo.getUuid()); + IpAllocatorType strategyType = IpAllocatorType.valueOf(L3NetworkConstant.FIRST_AVAILABLE_IPV6_ALLOCATOR_STRATEGY); + IpAllocatorStrategy ias = l3NwMgr.getIpAllocatorStrategy(strategyType); + UsedIpInventory ip = ias.allocateIp(msg); + + SystemTagCreator creator = FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.newSystemTagCreator(l3vo.getUuid()); + creator.inherent = true; + creator.setTagByTokens( + map( + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN, IPv6NetworkUtils.ipv6AddessToTagValue(ip.getIp())), + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_UUID_TOKEN, ip.getUuid()) + ) + ); + creator.create(); + } + } + } else if (ipVersions.size() == 2) { + /* dual stack */ + Map dhcpMap = getExistingDhcpServerIp(l3vo.getUuid(), IPv6Constants.DUAL_STACK); + boolean hasIpv4 = false; + boolean hasIpv6 = false; + for (Map.Entry e : dhcpMap.entrySet()) { + if (IPv6NetworkUtils.isValidIpv4(e.getKey())) { + hasIpv4 = true; + } else if (IPv6NetworkUtils.isIpv6Address(e.getKey())) { + hasIpv6 = true; + } + } + if (!hasIpv4) { + AllocateIpMsg msg = new AllocateIpMsg(); + msg.setL3NetworkUuid(l3vo.getUuid()); + IpAllocatorType strategyType = IpAllocatorType.valueOf(L3NetworkConstant.FIRST_AVAILABLE_IP_ALLOCATOR_STRATEGY); + IpAllocatorStrategy ias = l3NwMgr.getIpAllocatorStrategy(strategyType); + UsedIpInventory ip = ias.allocateIp(msg); + + SystemTagCreator creator = FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.newSystemTagCreator(l3vo.getUuid()); + creator.inherent = true; + creator.setTagByTokens( + map( + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN, ip.getIp()), + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_UUID_TOKEN, ip.getUuid()) + ) + ); + creator.create(); + + for (DhcpServerExtensionPoint exp : pluginRgty.getExtensionList(DhcpServerExtensionPoint.class)) { + exp.afterAllocateDhcpServerIP(l3vo.getUuid(), ip.getIp()); + } + } + if (!hasIpv6) { + AllocateIpMsg msg = new AllocateIpMsg(); + msg.setL3NetworkUuid(l3vo.getUuid()); + IpAllocatorType strategyType = IpAllocatorType.valueOf(L3NetworkConstant.FIRST_AVAILABLE_IPV6_ALLOCATOR_STRATEGY); + IpAllocatorStrategy ias = l3NwMgr.getIpAllocatorStrategy(strategyType); + UsedIpInventory ip = ias.allocateIp(msg); + + SystemTagCreator creator = FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.newSystemTagCreator(l3vo.getUuid()); + creator.inherent = true; + creator.setTagByTokens( + map( + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN, IPv6NetworkUtils.ipv6AddessToTagValue(ip.getIp())), + e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_UUID_TOKEN, ip.getUuid()) + ) + ); + creator.create(); + } + } + } + } + @Override public boolean start() { for (L3NetworkGetIpStatisticExtensionPoint ext : pluginRgty.getExtensionList(L3NetworkGetIpStatisticExtensionPoint.class)) { getIpStatisticExts.put(ext.getApplianceVmInstanceType(), ext); } + + if (FlatDhcpGlobalProperty.UPGRADE_FLAT_DHCP_SERVER_IP) { + upgradeFlatDhcpServerIp(); + } + return true; } @@ -847,38 +1217,58 @@ public String preDeleteL3Network(L3NetworkInventory inventory) { public void beforeDeleteL3Network(L3NetworkInventory inventory) { } - private boolean isProvidedByMe(String l3Uuid) { + private boolean isAllocateDhcpServerIp(String l3Uuid) { + String providerType = new NetworkProviderFinder().getNetworkProviderTypeByNetworkServiceType(l3Uuid, NetworkServiceType.DHCP.toString()); + if (providerType == null) { + return false; + } + + NetworkServiceProviderType type = NetworkServiceProviderType.valueOf(providerType); + return type.isAllocateDhcpServerIp(); + } + + private boolean isCreateDhcpNameSpace(String l3Uuid) { String providerType = new NetworkProviderFinder().getNetworkProviderTypeByNetworkServiceType(l3Uuid, NetworkServiceType.DHCP.toString()); - return FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING.equals(providerType); + if (providerType == null) { + return false; + } + + NetworkServiceProviderType type = NetworkServiceProviderType.valueOf(providerType); + return type.isCreateDhcpNameSpace(); } @Override public void afterDeleteL3Network(L3NetworkInventory inventory) { - if (!isProvidedByMe(inventory.getUuid())) { - return; + if (isAllocateDhcpServerIp(inventory.getUuid())) { + Map dhcpMap = getExistingDhcpServerIp(inventory.getUuid(), IPv6Constants.DUAL_STACK); + for (Map.Entry entry : dhcpMap.entrySet()) { + String dhcpIp = entry.getKey(); + String dhcpIpUuid = entry.getValue(); + deleteDhcpServerIp(inventory.getUuid(), dhcpIp, dhcpIpUuid); + logger.debug(String.format("delete DHCP server ip[%s] of the flat network[uuid:%s] as the L3 network is deleted", + dhcpIp, inventory.getUuid())); + } } - Map dhcpMap = getExistingDhcpServerIp(inventory.getUuid(), IPv6Constants.DUAL_STACK); - for (Map.Entry entry : dhcpMap.entrySet()) { - String dhcpIp = entry.getKey(); - String dhcpIpUuid = entry.getValue(); - deleteDhcpServerIp(inventory.getUuid(), dhcpIp, dhcpIpUuid); - logger.debug(String.format("delete DHCP server ip[%s] of the flat network[uuid:%s] as the L3 network is deleted", - dhcpIp, inventory.getUuid())); + if (isCreateDhcpNameSpace(inventory.getUuid())) { + deleteNameSpace(inventory, new NopeCompletion()); } + } - deleteNameSpace(inventory); + private void deleteNameSpace(L3NetworkInventory inventory, Completion completion) { + deleteNameSpace(inventory, DHCP_DELETE_NAMESPACE_PATH, completion); } - private void deleteNameSpace(L3NetworkInventory inventory) { + private void deleteNameSpace(L3NetworkInventory inventory, String path, Completion completion) { List huuids = new Callable>() { @Override @Transactional(readOnly = true) public List call() { String sql = "select host.uuid from HostVO host, L2NetworkVO l2, L2NetworkClusterRefVO ref where l2.uuid = ref.l2NetworkUuid" + - " and ref.clusterUuid = host.clusterUuid and l2.uuid = :uuid"; + " and ref.clusterUuid = host.clusterUuid and host.hypervisorType = :hType and l2.uuid = :uuid"; TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("uuid", inventory.getL2NetworkUuid()); + q.setParameter("hType", KVMConstant.KVM_HYPERVISOR_TYPE); return q.getResultList(); } }.call(); @@ -892,35 +1282,42 @@ public List call() { cmd.bridgeName = brName; cmd.namespaceName = makeNamespaceName(brName, inventory.getUuid()); - new While<>(huuids).all((huuid, comp) -> { - new KvmCommandSender(huuid).send(cmd, DHCP_DELETE_NAMESPACE_PATH, wrapper -> { + new While<>(huuids).step((huuid, comp) -> { + new KvmCommandSender(huuid).send(cmd, path, wrapper -> { DeleteNamespaceRsp rsp = wrapper.getResponse(DeleteNamespaceRsp.class); + if (rsp == null) { + return null; + } return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); }, new SteppingSendCallback() { @Override public void success(KvmResponseWrapper w) { logger.debug(String.format("successfully deleted namespace for L3 network[uuid:%s, name:%s] on the " + "KVM host[uuid:%s]", inventory.getUuid(), inventory.getName(), getHostUuid())); + comp.done(); } @Override public void fail(ErrorCode errorCode) { if (!errorCode.isError(HostErrors.OPERATION_FAILURE_GC_ELIGIBLE)) { + comp.done(); return; } FlatDHCPDeleteNamespaceGC gc = new FlatDHCPDeleteNamespaceGC(); + gc.path = path; gc.hostUuid = getHostUuid(); gc.command = cmd; gc.NAME = String.format("gc-namespace-on-host-%s", getHostUuid()); gc.submit(); + + comp.done(); } }); - comp.done(); - }).run(new WhileDoneCompletion(new NopeCompletion()){ + }, 10).run(new WhileDoneCompletion(new NopeCompletion(completion)){ @Override public void done(ErrorCodeList errorCodeList) { - + completion.success(); } }); @@ -938,7 +1335,7 @@ private List getVmDhcpInfo(VmInstanceInventory vm, String l3Uuid) { } String sql = "select nic from VmNicVO nic, L3NetworkVO l3, NetworkServiceL3NetworkRefVO ref, NetworkServiceProviderVO provider, UsedIpVO ip" + - " where nic.uuid = ip.vmNicUuid and nic.type <> :nicType and ip.l3NetworkUuid = l3.uuid" + + " where nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = l3.uuid" + " and ref.l3NetworkUuid = l3.uuid and ref.networkServiceProviderUuid = provider.uuid " + " and ref.networkServiceType = :dhcpType " + " and provider.type = :ptype and nic.vmInstanceUuid = :vmUuid group by nic.uuid"; @@ -947,8 +1344,6 @@ private List getVmDhcpInfo(VmInstanceInventory vm, String l3Uuid) { nq.setParameter("dhcpType", NetworkServiceType.DHCP.toString()); nq.setParameter("ptype", FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING); nq.setParameter("vmUuid", vm.getUuid()); - // TODO: we will support vDPA dhcp in future - nq.setParameter("nicType", "vDPA"); List nics = nq.getResultList(); if (l3Uuid != null) { @@ -983,19 +1378,25 @@ private List getVmDhcpInfo(VmInstanceInventory vm, String l3Uuid) { } @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { List info = getVmDhcpInfo(inv); if (info == null || info.isEmpty()) { + completion.success(); return; } - FutureCompletion completion = new FutureCompletion(null); - applyDhcpToHosts(info, destHostUuid, false, completion); - completion.await(TimeUnit.MINUTES.toMillis(30)); - if (!completion.isSuccess()) { - throw new OperationFailureException(operr("cannot configure DHCP for vm[uuid:%s] on the destination host[uuid:%s]", - inv.getUuid(), destHostUuid).causedBy(completion.getErrorCode())); - } + applyDhcpToHosts(info, destHostUuid, false, new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(operr("cannot configure DHCP for vm[uuid:%s] on the destination host[uuid:%s]", + inv.getUuid(), destHostUuid).causedBy(errorCode)); + } + }); } @Override @@ -1003,18 +1404,14 @@ public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { } @Override - public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { + public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid, NoErrorCompletion completion) { List info = getVmDhcpInfo(inv); if (info == null || info.isEmpty()) { + completion.done(); return; } - releaseDhcpService(info, inv.getUuid(), srcHostUuid, new NoErrorCompletion() { - @Override - public void done() { - // ignore - } - }); + releaseDhcpService(info, inv.getUuid(), srcHostUuid, completion); } @Override @@ -1202,11 +1599,33 @@ public void beforeDeleteIpRange(IpRangeInventory ipRange) { } + private void deleteDhcpServerIp(String l3Uuid, String dhcpServerIp) { + FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.deleteInherentTag(l3Uuid); + for (DhcpServerExtensionPoint exp : pluginRgty.getExtensionList(DhcpServerExtensionPoint.class)) { + exp.afterRemoveDhcpServerIP(l3Uuid, dhcpServerIp); + } + } + private void deleteDhcpServerIp(String l3Uuid, String dhcpServerIp, String dhcpServerIpUuid) { + if (dhcpServerIpUuid == null) { + dhcpServerIpUuid = Q.New(UsedIpVO.class).select(UsedIpVO_.uuid) + .eq(UsedIpVO_.l3NetworkUuid, l3Uuid) + .eq(UsedIpVO_.ip, dhcpServerIp).findValue(); + } + ReturnIpMsg rmsg = new ReturnIpMsg(); + rmsg.setL3NetworkUuid(l3Uuid); + rmsg.setUsedIpUuid(dhcpServerIpUuid); + bus.makeTargetServiceIdByResourceUuid(rmsg, L3NetworkConstant.SERVICE_ID, l3Uuid); + MessageReply reply = bus.call(rmsg); + if (!reply.isSuccess()) { + throw new OperationFailureException(reply.getError()); + } + FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.deleteInherentTag(l3Uuid, FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.instantiateTag(map( e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN, IPv6NetworkUtils.ipv6AddessToTagValue(dhcpServerIp)), e(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_UUID_TOKEN, dhcpServerIpUuid)))); + for (DhcpServerExtensionPoint exp : pluginRgty.getExtensionList(DhcpServerExtensionPoint.class)) { exp.afterRemoveDhcpServerIP(l3Uuid, dhcpServerIp); } @@ -1231,6 +1650,37 @@ public void failedToDeleteIpRange(IpRangeInventory ipRange, ErrorCode errorCode) } + private void refreshDhcpInfoForConnectedHost(String hostUuid, List dhcpInfoList, Completion completion) { + // to flush ebtables + ConnectCmd cmd = new ConnectCmd(); + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setCommand(cmd); + msg.setNoStatusCheck(true); + msg.setPath(DHCP_CONNECT_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + } else { + applyDhcpToHosts(dhcpInfoList, hostUuid, true, new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + } + }); + } + @Override public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { return new NoRollbackFlow() { @@ -1238,7 +1688,12 @@ public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { @Override public void run(final FlowTrigger trigger, Map data) { - final List dhcpInfoList = getDhcpInfoForConnectedKvmHost(context); + if (!context.getInventory().getHypervisorType().equals(KVMConstant.KVM_HYPERVISOR_TYPE)) { + trigger.next(); + return; + } + + final List dhcpInfoList = getDhcpInfoForConnectedKvmHost(context.getInventory(), null); if (dhcpInfoList == null) { trigger.next(); return; @@ -1295,14 +1750,10 @@ public void beforeStartNewCreatedVm(VmInstanceSpec spec) { } } - public static class HostRouteInfo { - public String prefix; - public String nexthop; - } - public static class DhcpInfo { public int ipVersion; public String raMode; + public boolean enableRa; public String ip; public String ip6; public String mac; @@ -1324,15 +1775,20 @@ public static class DhcpInfo { public boolean vmMultiGateway; public List hostRoutes; public String nicType; + public String vlanId; } public static class ApplyDhcpCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public List dhcp; + @GrayVersion(value = "5.0.0") public boolean rebuild; + @GrayVersion(value = "5.0.0") public String l3NetworkUuid; } public static class BatchApplyDhcpCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public List dhcpInfos; } @@ -1340,6 +1796,7 @@ public static class ApplyDhcpRsp extends KVMAgentCommands.AgentResponse { } public static class ReleaseDhcpCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public List dhcp; } @@ -1347,17 +1804,28 @@ public static class ReleaseDhcpRsp extends KVMAgentCommands.AgentResponse { } public static class PrepareDhcpCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String bridgeName; + @GrayVersion(value = "5.1.0") + public String vlanId; + @GrayVersion(value = "5.0.0") public String dhcpServerIp; + @GrayVersion(value = "5.0.0") public String dhcpNetmask; + @GrayVersion(value = "5.0.0") public String namespaceName; + @GrayVersion(value = "5.0.0") public Integer ipVersion; + @GrayVersion(value = "5.0.0") public String dhcp6ServerIp; + @GrayVersion(value = "5.0.0") public Integer prefixLen; + @GrayVersion(value = "5.0.0") public String addressMode; } public static class BatchPrepareDhcpCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public List dhcpInfos; } @@ -1371,13 +1839,21 @@ public static class ConnectRsp extends KVMAgentCommands.AgentResponse { } public static class ResetDefaultGatewayCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String bridgeNameOfGatewayToRemove; + @GrayVersion(value = "5.0.0") public String namespaceNameOfGatewayToRemove; + @GrayVersion(value = "5.0.0") public String gatewayToRemove; + @GrayVersion(value = "5.0.0") public String macOfGatewayToRemove; + @GrayVersion(value = "5.0.0") public String gatewayToAdd; + @GrayVersion(value = "5.0.0") public String macOfGatewayToAdd; + @GrayVersion(value = "5.0.0") public String bridgeNameOfGatewayToAdd; + @GrayVersion(value = "5.0.0") public String namespaceNameOfGatewayToAdd; } @@ -1385,65 +1861,82 @@ public static class ResetDefaultGatewayRsp extends KVMAgentCommands.AgentRespons } public static class DeleteNamespaceCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String bridgeName; + @GrayVersion(value = "5.0.0") public String namespaceName; } public static class DeleteNamespaceRsp extends KVMAgentCommands.AgentResponse { } + public static class FlushDhcpNamespaceCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.1.8") + public String bridgeName; + @GrayVersion(value = "5.1.8") + public String namespaceName; + } + + public static class FlushDhcpNamespaceRsp extends KVMAgentCommands.AgentResponse { + } + + public static class ArpingCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.1.8") + public String bridgeName; + @GrayVersion(value = "5.1.8") + public String vlanId; + @GrayVersion(value = "5.1.8") + public String namespaceName; + @GrayVersion(value = "5.1.8") + public List targetIps; + } + + public static class ArpingRsp extends KVMAgentCommands.AgentResponse { + @GrayVersion(value = "5.1.8") + /* key: arping target ip: + * value: arping result macs */ + public Map> result; + } + public NetworkServiceProviderType getProviderType() { return FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE; } - private List getL3NetworkDns(String l3NetworkUuid){ - List dns = Q.New(L3NetworkDnsVO.class).eq(L3NetworkDnsVO_.l3NetworkUuid, l3NetworkUuid) - .select(L3NetworkDnsVO_.dns).orderBy(L3NetworkDnsVO_.id, SimpleQuery.Od.ASC).listValues(); - if (dns == null) { - dns = new ArrayList(); - } - - L3NetworkVO l3VO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, l3NetworkUuid).find(); - if (FlatNetwordProviderGlobalConfig.ALLOW_DEFAULT_DNS.value(Boolean.class) && l3VO.getIpVersions().contains(IPv6Constants.IPv4)) { - Map dhcpIpMap = getExistingDhcpServerIp(l3NetworkUuid, IPv6Constants.IPv4); + @Override + public List getDnsAddress(L3NetworkInventory l3Inv) { + List dns = new ArrayList(); + + String providerUuid = Q.New(NetworkServiceProviderVO.class) + .select(NetworkServiceProviderVO_.uuid) + .eq(NetworkServiceProviderVO_.type, FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING) + .findValue(); + if (l3Inv.getNetworkServiceTypesFromProvider(providerUuid).contains(NetworkServiceType.DHCP.toString()) + && FlatNetwordProviderGlobalConfig.ALLOW_DEFAULT_DNS.value(Boolean.class) + && l3Inv.getIpVersions().contains(IPv6Constants.IPv4)){ + Map dhcpIpMap = getExistingDhcpServerIp(l3Inv.getUuid(), IPv6Constants.IPv4); if (!dhcpIpMap.isEmpty()) { Map.Entry entry = dhcpIpMap.entrySet().iterator().next(); dns.add(entry.getKey()); } } - for (FlatDhcpGetDnsAddressExtensionPoint exp : pluginRgty.getExtensionList(FlatDhcpGetDnsAddressExtensionPoint.class)) { - dns.addAll(exp.getDnsAddress(L3NetworkInventory.valueOf(l3VO))); - } - return dns; } - private List getL3NetworkHostRoute(String l3NetworkUuid){ - List vos = Q.New(L3NetworkHostRouteVO.class).eq(L3NetworkHostRouteVO_.l3NetworkUuid, l3NetworkUuid).list(); - if (vos == null || vos.isEmpty()) { - return new ArrayList<>(); - } - - List res = new ArrayList<>(); - for (L3NetworkHostRouteVO vo : vos) { - HostRouteInfo info = new HostRouteInfo(); - info.prefix = vo.getPrefix(); - info.nexthop = vo.getNexthop(); - res.add(info); - } - - return res; - } - private List toDhcpInfo(List structs) { final Map l3Bridges = new HashMap(); + final List l2Uuids = new ArrayList<>(); for (DhcpStruct s : structs) { if (!l3Bridges.containsKey(s.getL3Network().getUuid())) { + l2Uuids.add(s.getL3Network().getL2NetworkUuid()); l3Bridges.put(s.getL3Network().getUuid(), KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(s.getL3Network().getL2NetworkUuid(), KVMSystemTags.L2_BRIDGE_NAME_TOKEN)); } } + if (l2Uuids.isEmpty()) { + return new ArrayList<>(); + } + Map bridgesVlan = new BridgeVlanIdFinder().findByL2Uuids(l2Uuids); return CollectionUtils.transformToList(structs, new Function() { @Override @@ -1467,6 +1960,7 @@ public DhcpInfo call(DhcpStruct arg) { DhcpInfo info = new DhcpInfo(); info.ipVersion = arg.getIpVersion(); info.raMode = arg.getRaMode(); + info.enableRa = arg.isEnableRa(); info.dnsDomain = arg.getDnsDomain(); info.gateway = arg.getGateway(); info.hostname = arg.getHostname(); @@ -1489,7 +1983,7 @@ public DhcpInfo call(DhcpStruct arg) { List dns = new ArrayList<>(); List dns6 = new ArrayList<>(); - for (String dnsIp : getL3NetworkDns(arg.getL3Network().getUuid())) { + for (String dnsIp : nwServiceMgr.getL3NetworkDns(arg.getL3Network().getUuid())) { if (NetworkUtils.isIpv4Address(dnsIp)) { dns.add(dnsIp); } else { @@ -1502,6 +1996,9 @@ public DhcpInfo call(DhcpStruct arg) { info.dns = dns; info.l3NetworkUuid = arg.getL3Network().getUuid(); info.bridgeName = l3Bridges.get(arg.getL3Network().getUuid()); + if (bridgesVlan.containsKey(info.bridgeName)) { + info.vlanId = bridgesVlan.get(info.bridgeName); + } info.namespaceName = makeNamespaceName(info.bridgeName, arg.getL3Network().getUuid()); info.mtu = arg.getMtu(); info.hostRoutes = getL3NetworkHostRoute(arg.getL3Network().getUuid()); @@ -1529,10 +2026,11 @@ private void applyDhcpToHosts(List dhcpInfo, final String hostUuid, fi final Map> l3DhcpMap = new HashMap<>(); for (DhcpInfo d : dhcpInfo) { - // TODO: vDPA do not support flat dhcp service yet; - if (d.nicType.equals("vDPA")) { + if (!isCreateDhcpNameSpace(d.l3NetworkUuid)) { + /* there are vm in this l3, but dhcp is disabled */ continue; } + List lst = l3DhcpMap.get(d.l3NetworkUuid); if (lst == null) { lst = new ArrayList<>(); @@ -1541,6 +2039,10 @@ private void applyDhcpToHosts(List dhcpInfo, final String hostUuid, fi lst.add(d); } + if (l3DhcpMap.isEmpty()) { + completion.success(); + return; + } DhcpApply dhcpApply = new DhcpApply(); dhcpApply.bus = bus; @@ -1629,6 +2131,17 @@ public void vmDefaultL3NetworkChanged(VmInstanceInventory vm, String previousL3, VmNicInventory nnic = null; for (VmNicInventory nic : vm.getVmNics()) { + try { + NetworkServiceProviderType pType = nwServiceMgr.getTypeOfNetworkServiceProviderForService( + nic.getL3NetworkUuid(), NetworkServiceType.DHCP); + if (pType != FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE) { + continue; + } + } catch (OperationFailureException exception) { + logger.debug(String.format("dhcp is not enable on l3 network %s", nic.getL3NetworkUuid())); + continue; + } + if (VmNicHelper.getL3Uuids(nic).contains(previousL3)) { pnic = nic; } else if (VmNicHelper.getL3Uuids(nic).contains(nowL3)) { @@ -1636,6 +2149,11 @@ public void vmDefaultL3NetworkChanged(VmInstanceInventory vm, String previousL3, } } + if (pnic == null && nnic == null) { + completion.success(); + return; + } + ResetDefaultGatewayCmd cmd = new ResetDefaultGatewayCmd(); if (pnic != null) { cmd.gatewayToRemove = pnic.getGateway(); @@ -1653,7 +2171,7 @@ public void vmDefaultL3NetworkChanged(VmInstanceInventory vm, String previousL3, KvmCommandSender sender = new KvmCommandSender(vm.getHostUuid()); sender.send(cmd, RESET_DEFAULT_GATEWAY_PATH, wrapper -> { ResetDefaultGatewayRsp rsp = wrapper.getResponse(ResetDefaultGatewayRsp.class); - return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); + return rsp.isSuccess() ? null : operr(rsp.getError(), "operation error, because:%s", rsp.getError()); }, new ReturnValueCompletion(completion) { @Override public void success(KvmResponseWrapper returnValue) { @@ -1735,6 +2253,10 @@ public List getMessageClassToIntercept() { ret.add(APIAddIpv6RangeMsg.class); ret.add(APIAddIpv6RangeByNetworkCidrMsg.class); ret.add(APIDeleteIpRangeMsg.class); + ret.add(APIChangeL3NetworkDhcpIpAddressMsg.class); + ret.add(APIDetachNetworkServiceFromL3NetworkMsg.class); + ret.add(APIAttachNetworkServiceToL3NetworkMsg.class); + ret.add(APIDeleteIpAddressMsg.class); return ret; } @@ -1821,8 +2343,8 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti IpRangeInventory inv = IpRangeInventory.fromMessage((APIAddIpRangeMsg)msg); validateDhcpServerIp(inv, msg.getSystemTags()); } else if (msg instanceof APIAddIpRangeByNetworkCidrMsg) { - IpRangeInventory inv = IpRangeInventory.fromMessage((APIAddIpRangeByNetworkCidrMsg)msg); - validateDhcpServerIp(inv, msg.getSystemTags()); + List invs = IpRangeInventory.fromMessage((APIAddIpRangeByNetworkCidrMsg)msg); + validateDhcpServerIp(invs.get(0), msg.getSystemTags()); } else if (msg instanceof APIAddIpv6RangeMsg) { IpRangeInventory inv = IpRangeInventory.fromMessage((APIAddIpv6RangeMsg)msg); validateDhcpServerIp(inv, msg.getSystemTags()); @@ -1831,11 +2353,145 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti IpRangeInventory inv = IpRangeInventory.fromMessage((APIAddIpv6RangeByNetworkCidrMsg)msg); validateDhcpServerIp(inv, msg.getSystemTags()); validateIpv6PrefixLength(inv); + } else if (msg instanceof APIChangeL3NetworkDhcpIpAddressMsg) { + validate((APIChangeL3NetworkDhcpIpAddressMsg) msg); + } else if (msg instanceof APIDetachNetworkServiceFromL3NetworkMsg) { + validate((APIDetachNetworkServiceFromL3NetworkMsg) msg); + } else if (msg instanceof APIAttachNetworkServiceToL3NetworkMsg) { + validate((APIAttachNetworkServiceToL3NetworkMsg) msg); + } else if (msg instanceof APIDeleteIpAddressMsg) { + validate((APIDeleteIpAddressMsg) msg); } return msg; } + private void validate(APIDeleteIpAddressMsg msg) { + for (String uuid : msg.getUsedIpUuids()) { + UsedIpVO vo = dbf.findByUuid(uuid, UsedIpVO.class); + Map dhcpMap = getExistingDhcpServerIp(vo.getL3NetworkUuid(), vo.getIpVersion()); + if (!dhcpMap.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could delete ip address, " + + "because ip [%s] is dhcp server ip", vo.getIp())); + } + } + } + + private void validate(APIAttachNetworkServiceToL3NetworkMsg msg) { + String owner = acntMgr.getOwnerAccountUuidOfResource(msg.getL3NetworkUuid()); + if (!acntMgr.isAdmin(msg.getSession()) && !msg.getSession().getAccountUuid().equals(owner)) { + throw new ApiMessageInterceptionException(argerr("could change dhcp server ip, because %s is not the owner of l3 network[uuid:%s]", + msg.getSession().getAccountUuid(), msg.getL3NetworkUuid())); + } + + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + List ipv4Ranges = l3VO.getIpRanges().stream().filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv4).collect(Collectors.toList()); + List ipv6Ranges = l3VO.getIpRanges().stream().filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv6).collect(Collectors.toList()); + + String dhcpIp = null; + String dhcp6Ip = null; + if (msg.getSystemTags() != null) { + for (String sysTag : msg.getSystemTags()) { + if (!FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.isMatch(sysTag)) { + continue; + } + + Map token = TagUtils.parse(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.getTagFormat(), sysTag); + String dhcpServerIp = token.get(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN); + dhcpServerIp = IPv6NetworkUtils.ipv6TagValueToAddress(dhcpServerIp); + if (NetworkUtils.isIpv4Address(dhcpServerIp)) { + dhcpIp = dhcpServerIp; + } else if (IPv6NetworkUtils.isIpv6Address(dhcpServerIp)) { + dhcp6Ip = dhcpServerIp; + } + } + } + + if (dhcpIp != null && ipv4Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v4 server ip, because there is no ipv4 range")); + } + + if (dhcpIp != null) { + if (!NetworkUtils.isIpv4InCidr(dhcpIp, ipv4Ranges.get(0).getNetworkCidr())) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v4 server ip, because ip[%s] is not the cidr of l3 [%s]", + dhcpIp, ipv4Ranges.get(0).getNetworkCidr())); + } + } + + if (dhcp6Ip != null && ipv6Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v6 server ip, because there is no ipv6 range")); + } + + if (dhcp6Ip != null) { + if (!IPv6NetworkUtils.isIpv6InCidrRange(dhcp6Ip, ipv6Ranges.get(0).getNetworkCidr())) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v6 server ip, because ip[%s] is not the cidr of l3 [%s]", + dhcpIp, ipv6Ranges.get(0).getNetworkCidr())); + } + } + } + + private void validate(APIDetachNetworkServiceFromL3NetworkMsg msg) { + String owner = acntMgr.getOwnerAccountUuidOfResource(msg.getL3NetworkUuid()); + if (!acntMgr.isAdmin(msg.getSession()) && !msg.getSession().getAccountUuid().equals(owner)) { + throw new ApiMessageInterceptionException(argerr("could change dhcp server ip, because %s is not the owner of l3 network[uuid:%s]", + msg.getSession().getAccountUuid(), msg.getL3NetworkUuid())); + } + } + + private void validate(APIChangeL3NetworkDhcpIpAddressMsg msg) { + if (!isAllocateDhcpServerIp(msg.getL3NetworkUuid())) { + throw new ApiMessageInterceptionException(argerr("could change dhcp server ip, because flat dhcp is not enabled")); + } + + String owner = acntMgr.getOwnerAccountUuidOfResource(msg.getL3NetworkUuid()); + if (!acntMgr.isAdmin(msg.getSession()) && !msg.getSession().getAccountUuid().equals(owner)) { + throw new ApiMessageInterceptionException(argerr("could change dhcp server ip, because %s is not the owner of l3 network[uuid:%s]", + msg.getSession().getAccountUuid(), msg.getL3NetworkUuid())); + } + + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + List ipv4Ranges = l3VO.getIpRanges().stream().filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv4).collect(Collectors.toList()); + List ipv6Ranges = l3VO.getIpRanges().stream().filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv6).collect(Collectors.toList()); + + if (msg.getDhcpServerIp() != null && ipv4Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could change dhcp v4 server ip, because there is no ipv4 range")); + } + + if (msg.getDhcpServerIp() != null) { + if (!NetworkUtils.isIpv4InCidr(msg.getDhcpServerIp(), ipv4Ranges.get(0).getNetworkCidr())) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v4 server ip, because ip[%s] is not the cidr of l3 [%s]", + msg.getDhcpServerIp(), ipv4Ranges.get(0).getNetworkCidr())); + } + } + + if (msg.getDhcpv6ServerIp() != null && ipv6Ranges.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could change dhcp v6 server ip, because there is no ipv6 range")); + } + + if (msg.getDhcpv6ServerIp() != null) { + if (!IPv6NetworkUtils.isIpv6InCidrRange(msg.getDhcpv6ServerIp(), ipv6Ranges.get(0).getNetworkCidr())) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v6 server ip, because ip[%s] is not the cidr of l3 [%s]", + msg.getDhcpv6ServerIp(), ipv6Ranges.get(0).getNetworkCidr())); + } + } + + if (msg.getDhcpServerIp() != null) { + if (Q.New(UsedIpVO.class).eq(UsedIpVO_.ip, msg.getDhcpServerIp()) + .eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could set dhcp server ip, because ip[%s] is used", + msg.getDhcpServerIp())); + } + } + + if (msg.getDhcpv6ServerIp() != null) { + if (Q.New(UsedIpVO.class).eq(UsedIpVO_.ip, msg.getDhcpv6ServerIp()) + .eq(UsedIpVO_.l3NetworkUuid, msg.getL3NetworkUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could set dhcp v6 server ip, because ip[%s] is used", + msg.getDhcpServerIp())); + } + } + } + /* when add an iprage, there are 2 cases: * #1 include dhcp server ip, it means there is no dhcp server yet. and it include 2 sub-cases: * $1.1 dhcp server ip is in this range, actions: @@ -1845,13 +2501,85 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti * b) create systemtag L3_NETWORK_DHCP_IP, but usedIp set to null * * #2 doesn't include dhcp server ip, it include 2 sub-cases: - * $2.1 dhcp server ip is not config, actions: NONE + * $2.1 dhcp server ip is not config, actions: allocate dhcp server ip * $2.2 dhcp server ip is configured, but no in this range, actions: None * $2.3 dhcp server ip is configured and in this range, actions: * a) allocate dhcp server ip in db * */ @Override public void afterAddIpRange(IpRangeInventory ipr, List systemTags) { + L3NetworkVO l3NetworkVO = dbf.findByUuid(ipr.getL3NetworkUuid(), L3NetworkVO.class); + List reservedIpRanges = null; + if (ipr.getIpVersion() == IPv6Constants.IPv4) { + reservedIpRanges = l3NetworkVO.getReservedIpRanges() + .stream().filter(r -> r.getIpVersion() == IPv6Constants.IPv4).collect(Collectors.toList()); + for (ReservedIpRangeVO reservedIpRange : reservedIpRanges) { + List usedIpVOS = new ArrayList<>(); + if (NetworkUtils.isIpv4RangeOverlap(ipr.getStartIp(), ipr.getEndIp(), + reservedIpRange.getStartIp(), reservedIpRange.getEndIp())) { + long start = NetworkUtils.ipv4StringToLong(reservedIpRange.getStartIp()); + long end = NetworkUtils.ipv4StringToLong(reservedIpRange.getEndIp()); + + for (long i = start; i <= end; i++){ + String newIp = NetworkUtils.longToIpv4String(i); + if (NetworkUtils.isInRange(newIp, ipr.getStartIp(), ipr.getEndIp())) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIpRangeUuid(ipr.getUuid()); + vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); + //vo.setVmNicUuid(nic.getUuid()); + vo.setIpVersion(ipr.getIpVersion()); + vo.setIp(newIp); + vo.setNetmask(ipr.getNetmask()); + vo.setGateway(ipr.getGateway()); + vo.setIpInLong(i); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setUsedFor(IpAllocatedReason.Reserved.toString()); + vo.setMetaData(reservedIpRange.getUuid()); + usedIpVOS.add(vo); + } + } + } + if (!usedIpVOS.isEmpty()) { + dbf.persistCollection(usedIpVOS); + } + } + } else { + List ipv6ReservedIpRange = l3NetworkVO.getReservedIpRanges() + .stream().filter(r -> r.getIpVersion() == IPv6Constants.IPv6).collect(Collectors.toList()); + for (ReservedIpRangeVO reservedIpRange : ipv6ReservedIpRange) { + List usedIpVOS = new ArrayList<>(); + if (IPv6NetworkUtils.isIpv6RangeOverlap(ipr.getStartIp(), ipr.getEndIp(), + reservedIpRange.getStartIp(), reservedIpRange.getEndIp())) { + BigInteger start = IPv6Address.fromString(reservedIpRange.getStartIp()).toBigInteger(); + BigInteger end = IPv6Address.fromString(reservedIpRange.getEndIp()).toBigInteger(); + + for (BigInteger i = start; i.compareTo(end) <= 0 && ipr != null; i = i.add(BigInteger.ONE)) { + String newIp = IPv6NetworkUtils.IPv6AddressToString(i); + if (IPv6NetworkUtils.isIpv6InRange(newIp, ipr.getStartIp(), ipr.getEndIp())) { + UsedIpVO vo = new UsedIpVO(); + vo.setUuid(Platform.getUuid()); + vo.setIpRangeUuid(ipr.getUuid()); + vo.setL3NetworkUuid(ipr.getL3NetworkUuid()); + //vo.setVmNicUuid(nic.getUuid()); + vo.setIpVersion(ipr.getIpVersion()); + vo.setIp(newIp); + vo.setIpInBinary(NetworkUtils.ipStringToBytes(vo.getIp())); + vo.setNetmask(ipr.getNetmask()); + vo.setGateway(ipr.getGateway()); + vo.setUsedFor(IpAllocatedReason.Reserved.toString()); + vo.setMetaData(reservedIpRange.getUuid()); + + usedIpVOS.add(vo); + } + } + } + if (!usedIpVOS.isEmpty()) { + dbf.persistCollection(usedIpVOS); + } + } + } + if (!Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.uuid, ipr.getUuid()).isExists()) { return; } @@ -1888,6 +2616,8 @@ public void afterAddIpRange(IpRangeInventory ipr, List systemTags) { } else { Map oldDhcpServerIpMap = getExistingDhcpServerIp(ipr.getL3NetworkUuid(), ipr.getIpVersion()); if (oldDhcpServerIpMap.isEmpty()) { + /* case #2.1 */ + allocateDhcpIp(ipr.getL3NetworkUuid(), ipr.getIpVersion()); return; } @@ -1899,4 +2629,349 @@ public void afterAddIpRange(IpRangeInventory ipr, List systemTags) { } } } + + private void refreshDhcpInfoToHosts(L3NetworkVO l3VO, Completion completion) { + L2NetworkVO l2VO = dbf.findByUuid(l3VO.getL2NetworkUuid(), L2NetworkVO.class); + List clusterUuids = l2VO.getAttachedClusterRefs().stream() + .map(L2NetworkClusterRefVO::getClusterUuid).collect(Collectors.toList()); + if (clusterUuids.isEmpty()) { + logger.debug(String.format("l2 network[uuid:%s] did not attach any cluster", l3VO.getL2NetworkUuid())); + completion.success(); + return; + } + + List hosts = Q.New(HostVO.class).eq(HostVO_.hypervisorType, KVMConstant.KVM_HYPERVISOR_TYPE) + .notIn(HostVO_.state,asList(HostState.PreMaintenance, HostState.Maintenance)) + .eq(HostVO_.status,HostStatus.Connected) + .in(HostVO_.clusterUuid, clusterUuids).list(); + if (hosts.isEmpty()) { + logger.debug(String.format("there is no host connected for l3 network[uuid:%s]", l3VO.getUuid())); + completion.success(); + return; + } + + Map> dhcpInfoMap = new HashMap<>(); + for (HostVO vo : hosts) { + List dhcpInfoList = getDhcpInfoForConnectedKvmHost(KVMHostInventory.valueOf(vo), l3VO.getUuid()); + if (dhcpInfoList != null) { + dhcpInfoMap.put(vo.getUuid(), dhcpInfoList); + } + } + if (dhcpInfoMap.isEmpty()) { + logger.debug(String.format("there is no host has vm for l3 network[uuid:%s]", l3VO.getUuid())); + completion.success(); + return; + } + + + new While<>(dhcpInfoMap.entrySet()).step((entry, wcomp) -> { + String hostUuid = entry.getKey(); + List dhcpInfos = entry.getValue(); + refreshDhcpInfoForConnectedHost(hostUuid, dhcpInfos, new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.addError(errorCode); + wcomp.allDone(); + } + }); + }, 10).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + completion.success(); + } else { + completion.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + + /* TODO: + * 1. disable/enable dhcp will disable ipam for flat, public network. VPC network will not + * 2. if ipam is disabled, can not attach l3 network to applianceVm: vRouter, and SLB + * 3. after enable/disable/enable dhcp, there are 3 kinds vmnic: + * 3.a) vmnic without ip + * 3.b) vmnic with ip specified by UI, this ip is not belong to any ip range + * 3.c) vmnic with ip allocated from ip range + * 4. 3.a, 3.b vmnic can not be eip/slb backend + * 5. 3.a, 3.b vmnic will not has dhcp/userdata functionality + * */ + + @Override + public void enableNetworkService(L3NetworkVO l3VO, List systemTags, Completion completion) { + List ip4Ranges = l3VO.getIpRanges().stream().filter(ipr -> ipr.getIpVersion() == IPv6Constants.IPv4).collect(Collectors.toList()); + List ip6Ranges = l3VO.getIpRanges().stream().filter(ipr -> + ipr.getIpVersion() == IPv6Constants.IPv6 && !ipr.getAddressMode().equals(IPv6Constants.SLAAC)) + .collect(Collectors.toList()); + + String dhcpIp = null; + String dhcp6Ip = null; + if (systemTags != null && !systemTags.isEmpty()){ + for (String sysTag : systemTags) { + if (!FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.isMatch(sysTag)) { + continue; + } + + Map token = TagUtils.parse(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP.getTagFormat(), sysTag); + String dhcpServerIp = token.get(FlatNetworkSystemTags.L3_NETWORK_DHCP_IP_TOKEN); + dhcpServerIp = IPv6NetworkUtils.ipv6TagValueToAddress(dhcpServerIp); + if (NetworkUtils.isIpv4Address(dhcpServerIp)) { + dhcpIp = dhcpServerIp; + } else if (IPv6NetworkUtils.isIpv6Address(dhcpServerIp)) { + dhcp6Ip = dhcpServerIp; + } + } + } + + if (!ip4Ranges.isEmpty()) { + boolean allocate_ip = false; + if (dhcpIp != null) { + for (IpRangeVO ipr : ip4Ranges) { + if (NetworkUtils.isInRange(dhcpIp, ipr.getStartIp(), ipr.getEndIp())) { + allocate_ip = true; + break; + } + } + } else { + allocate_ip = true; + } + dhcpIp = allocateDhcpIp(l3VO.getUuid(), IPv6Constants.IPv4, allocate_ip, dhcpIp, null); + if (dhcpIp == null) { + completion.fail(argerr("allocated dhcp server ip failed")); + return; + } + } + + if (!ip6Ranges.isEmpty()) { + boolean allocate_ip = false; + if (dhcp6Ip != null) { + for (IpRangeVO ipr : ip6Ranges) { + if (NetworkUtils.isInRange(dhcp6Ip, ipr.getStartIp(), ipr.getEndIp())) { + allocate_ip = true; + break; + } + } + } else { + allocate_ip = true; + } + dhcp6Ip = allocateDhcpIp(l3VO.getUuid(), IPv6Constants.IPv6, allocate_ip, dhcp6Ip, null); + if (dhcp6Ip == null) { + completion.fail(argerr("allocated dhcp server ip failed")); + return; + } + } + + if (!isCreateDhcpNameSpace(l3VO.getUuid())) { + completion.success(); + return; + } + + refreshDhcpInfoToHosts(l3VO, new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void flushDhcpConfig(L3NetworkInventory inventory, Completion completion) { + List huuids = new Callable>() { + @Override + @Transactional(readOnly = true) + public List call() { + String sql = "select host.uuid from HostVO host, L2NetworkVO l2, L2NetworkClusterRefVO ref where l2.uuid = ref.l2NetworkUuid" + + " and ref.clusterUuid = host.clusterUuid and host.hypervisorType = :hType and l2.uuid = :uuid"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); + q.setParameter("uuid", inventory.getL2NetworkUuid()); + q.setParameter("hType", KVMConstant.KVM_HYPERVISOR_TYPE); + return q.getResultList(); + } + }.call(); + + if (huuids.isEmpty()) { + completion.success(); + return; + } + + String brName = new BridgeNameFinder().findByL3Uuid(inventory.getUuid()); + FlushDhcpNamespaceCmd cmd = new FlushDhcpNamespaceCmd(); + cmd.bridgeName = brName; + cmd.namespaceName = makeNamespaceName(brName, inventory.getUuid()); + + new While<>(huuids).step((huuid, comp) -> { + new KvmCommandSender(huuid).send(cmd, DHCP_FLUSH_NAMESPACE_PATH, wrapper -> { + FlushDhcpNamespaceRsp rsp = wrapper.getResponse(FlushDhcpNamespaceRsp.class); + if (rsp == null) { + return null; + } + return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); + }, new SteppingSendCallback() { + @Override + public void success(KvmResponseWrapper w) { + logger.debug(String.format("successfully deleted namespace for L3 network[uuid:%s, name:%s] on the " + + "KVM host[uuid:%s]", inventory.getUuid(), inventory.getName(), getHostUuid())); + comp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.debug(String.format("delete namespace for L3 network[uuid:%s, name:%s] on the " + + "KVM host[uuid:%s], failed: %s", inventory.getUuid(), + inventory.getName(), getHostUuid(), errorCode.getDetails())); + comp.done(); + } + }); + }, 10).run(new WhileDoneCompletion(new NopeCompletion(completion)){ + @Override + public void done(ErrorCodeList errorCodeList) { + completion.success(); + } + }); + + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, Completion completion) { + if (!isCreateDhcpNameSpace(l3VO.getUuid())) { + completion.success(); + return; + } + + flushDhcpConfig(L3NetworkInventory.valueOf(l3VO), new Completion(completion) { + @Override + public void success() { + Map dhcpServerMap = getExistingDhcpServerIp(l3VO.getUuid(), IPv6Constants.DUAL_STACK); + if (dhcpServerMap.isEmpty()) { + completion.success(); + return; + } + + for (Map.Entry e : dhcpServerMap.entrySet()) { + deleteDhcpServerIp(l3VO.getUuid(), e.getKey(), e.getValue()); + } + + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void doArpingOnHost(CheckIpAvailabilityMsg msg, HostInventory host, L2NetworkInventory l2Inv, ReturnValueCompletion> completion) { + ArpingCmd cmd = new ArpingCmd(); + cmd.bridgeName = new BridgeNameFinder().findByL3Uuid(msg.getL3NetworkUuid()); + cmd.vlanId = new BridgeVlanIdFinder().findByL2Uuid(l2Inv.getUuid(), false); + cmd.namespaceName = makeNamespaceName(cmd.bridgeName, msg.getL3NetworkUuid()); + cmd.targetIps = Collections.singletonList(msg.getIp()); + + KvmCommandSender sender = new KvmCommandSender(host.getUuid()); + sender.send(cmd, ARPING_NAMESPACE_PATH, wrapper -> { + ArpingRsp rsp = wrapper.getResponse(ArpingRsp.class); + return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); + }, new ReturnValueCompletion(completion) { + @Override + public void success(KvmResponseWrapper returnValue) { + ArpingRsp rsp = returnValue.getResponse(ArpingRsp.class); + List conflictMacs = new ArrayList<>(); + if (rsp.result == null || rsp.result.isEmpty()) { + completion.success(conflictMacs); + return; + } + + List macs = rsp.result.get(msg.getIp()); + for (String mac : macs) { + boolean localMac = Q.New(VmNicVO.class) + .eq(VmNicVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(VmNicVO_.ip, msg.getIp()) + .eq(VmNicVO_.mac, mac).isExists(); + if (!localMac) { + conflictMacs.add(mac); + } + } + completion.success(conflictMacs); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + public void check(CheckIpAvailabilityMsg msg, ReturnValueCompletion completion) { + CheckIpAvailabilityReply reply = new CheckIpAvailabilityReply(); + reply.setAvailable(true); + reply.setReason(""); + if (!msg.getArpCheck() || !NetworkUtils.isIpv4Address(msg.getIp())) { + completion.success(reply); + return; + } + + L3NetworkVO l3VO = dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class); + L2NetworkVO l2VO = dbf.findByUuid(l3VO.getL2NetworkUuid(), L2NetworkVO.class); + List clusterUuids = l2VO.getAttachedClusterRefs().stream() + .map(L2NetworkClusterRefVO::getClusterUuid).collect(Collectors.toList()); + if (clusterUuids.isEmpty()) { + logger.debug(String.format("l2 network[uuid:%s] did not attach any cluster", l3VO.getL2NetworkUuid())); + completion.success(reply); + return; + } + + /* find 3 hosts to do arping */ + List hosts = Q.New(HostVO.class).eq(HostVO_.hypervisorType, KVMConstant.KVM_HYPERVISOR_TYPE) + .notIn(HostVO_.state,asList(HostState.PreMaintenance, HostState.Maintenance)) + .eq(HostVO_.status,HostStatus.Connected) + .in(HostVO_.clusterUuid, clusterUuids).limit(3).list(); + if (hosts.isEmpty()) { + logger.debug(String.format("there is no host connected for l3 network[uuid:%s]", l3VO.getUuid())); + completion.success(reply); + return; + } + + ConcurrentHashMap> macMaps = new ConcurrentHashMap>(); + new While<>(hosts).step((hostVO, wcomp) -> { + doArpingOnHost(msg, HostInventory.valueOf(hostVO), L2NetworkInventory.valueOf(l2VO), new ReturnValueCompletion>(wcomp) { + @Override + public void success(List returnValue) { + if (returnValue != null && !returnValue.isEmpty()) { + if (macMaps.get(msg.getIp()) == null) { + macMaps.put(msg.getIp(), new CopyOnWriteArrayList<>()); + } + macMaps.get(msg.getIp()).addAll(returnValue); + logger.debug(String.format("found arp conflict on host[uuid:%s], result:%s", + hostVO.getUuid(), returnValue)); + } + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.done(); + } + }); + }, 10).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (macMaps.get(msg.getIp()) != null) { + reply.setAvailable(false); + reply.setReason(String.format("%s", macMaps.get(msg.getIp()))); + } + completion.success(reply); + } + }); + } } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpGlobalProperty.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpGlobalProperty.java new file mode 100644 index 00000000000..3c718c52355 --- /dev/null +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatDhcpGlobalProperty.java @@ -0,0 +1,10 @@ +package org.zstack.network.service.flat; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +@GlobalPropertyDefinition +public class FlatDhcpGlobalProperty { + @GlobalProperty(name="upgradeFlatDhcpServerIp", defaultValue = "false") + public static boolean UPGRADE_FLAT_DHCP_SERVER_IP; +} diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java index 9da2ba9b8f4..834ded414e6 100644 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipApiInterceptor.java @@ -1,6 +1,7 @@ package org.zstack.network.service.flat; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.db.Q; @@ -8,6 +9,7 @@ import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.message.APIMessage; +import org.zstack.header.network.l3.UsedIpVO; import org.zstack.header.network.service.NetworkServiceProviderType; import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; @@ -16,6 +18,7 @@ import org.zstack.network.service.vip.Vip; import org.zstack.network.service.vip.VipVO; import org.zstack.network.service.vip.VipVO_; +import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; @@ -52,6 +55,30 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti return msg; } + void validateNicGateway(String vipUuid, String nicUuid) { + VipVO vipVO = Q.New(VipVO.class).eq(VipVO_.uuid, vipUuid).find(); + VmNicVO nicVO = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, nicUuid).find(); + + String gateway = null; + if (NetworkUtils.isIpv4Address(vipVO.getIp())) { + for (UsedIpVO ip : nicVO.getUsedIps()) { + if (ip.getIpVersion() == IPv6Constants.IPv4) { + gateway = ip.getGateway(); + } + } + } else { + for (UsedIpVO ip : nicVO.getUsedIps()) { + if (ip.getIpVersion() == IPv6Constants.IPv6) { + gateway = ip.getGateway(); + } + } + } + + if (StringUtils.isEmpty(gateway)) { + throw new ApiMessageInterceptionException(argerr("could not attach eip because there is no gateway for nic[uuid:%s]", nicUuid)); + } + } + @Transactional(readOnly = true) protected void validate(APICreateEipMsg msg) { if (msg.getVmNicUuid() == null) { @@ -64,6 +91,8 @@ protected void validate(APICreateEipMsg msg) { return; } + validateNicGateway(msg.getVipUuid(), msg.getVmNicUuid()); + String pubL3Uuid = Q.New(VipVO.class).select(VipVO_.l3NetworkUuid).eq(VipVO_.uuid, msg.getVipUuid()).findValue(); checkVipPublicL3Network(msg.getVmNicUuid(), pubL3Uuid); checkFlatVmNicAlreadyHasEip(msg.getVmNicUuid(), null, msg.getVipUuid()); @@ -77,13 +106,16 @@ protected void validate(APIAttachEipMsg msg) { /* TODO: this is temp limitation, ipv6 eip can be only attached to flat eip */ EipVO eip = Q.New(EipVO.class).eq(EipVO_.uuid, msg.getEipUuid()).find(); if (IPv6NetworkUtils.isIpv6Address(eip.getVipIp()) && !providerType.toString().equals(FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING)) { - throw new ApiMessageInterceptionException(argerr("could not attach eip because ipv6 eip can ONLY be attached to flat network")); +// throw new ApiMessageInterceptionException(argerr("could not attach eip because ipv6 eip can ONLY be attached to flat network")); + return; } if (!providerType.toString().equals(FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING)) { return; } + validateNicGateway(eip.getVipUuid(), msg.getVmNicUuid()); + String pubL3Uuid = SQL.New("select vip.l3NetworkUuid from EipVO eip, VipVO vip" + " where eip.uuid = :eipUuid" + " and eip.vipUuid = vip.uuid", String.class) diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipBackend.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipBackend.java index 65dfda5f987..69dbf627c28 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipBackend.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatEipBackend.java @@ -2,6 +2,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; +import org.zstack.compute.allocator.GetL3NetworkForVmNetworkService; import org.zstack.compute.vm.VmInstanceManager; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; @@ -28,8 +29,7 @@ import org.zstack.header.network.l2.L2NetworkClusterRefVO; import org.zstack.header.network.l2.L2NetworkClusterRefVO_; import org.zstack.header.network.l3.*; -import org.zstack.header.network.service.AfterApplyFlatEipExtensionPoint; -import org.zstack.header.network.service.NetworkServiceProviderType; +import org.zstack.header.network.service.*; import org.zstack.header.vm.*; import org.zstack.header.vm.VmAbnormalLifeCycleStruct.VmAbnormalLifeCycleOperation; import org.zstack.kvm.KVMHostAsyncHttpCallMsg; @@ -43,19 +43,19 @@ import org.zstack.network.service.flat.FlatNetworkServiceConstant.AgentRsp; import org.zstack.network.service.vip.VipInventory; import org.zstack.network.service.vip.VipVO; +import org.zstack.network.service.vip.VipVO_; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; import javax.persistence.Tuple; import javax.persistence.TypedQuery; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import static java.util.Arrays.asList; @@ -66,7 +66,9 @@ * Created by xing5 on 2016/4/4. */ public class FlatEipBackend implements EipBackend, KVMHostConnectExtensionPoint, - VmAbnormalLifeCycleExtensionPoint, VmInstanceMigrateExtensionPoint, FilterVmNicsForEipInVirtualRouterExtensionPoint, GetL3NetworkForEipInVirtualRouterExtensionPoint, GetEipAttachableL3UuidsForVmNicExtensionPoint { + VmAbnormalLifeCycleExtensionPoint, VmInstanceMigrateExtensionPoint, + FilterVmNicsForEipInVirtualRouterExtensionPoint, GetL3NetworkForEipInVirtualRouterExtensionPoint, + GetEipAttachableL3UuidsForVmNicExtensionPoint, GetL3NetworkForVmNetworkService { private static final CLogger logger = Utils.getLogger(FlatEipBackend.class); @Autowired @@ -127,14 +129,8 @@ public static class BatchDeleteEipCmd extends AgentCmd { public static final String DELETE_EIP_PATH = "/flatnetworkprovider/eip/delete"; public static final String BATCH_APPLY_EIP_PATH = "/flatnetworkprovider/eip/batchapply"; public static final String BATCH_DELETE_EIP_PATH = "/flatnetworkprovider/eip/batchdelete"; - - @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } - @Override public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } @Override @@ -224,6 +220,8 @@ public void run(FlowTrigger trigger, Map data) { vmMigrateToAnotherHost(trigger); } else if (operation == VmAbnormalLifeCycleOperation.VmRunningFromIntermediateState) { vmRunningFromIntermediateState(trigger); + } else if (operation == VmAbnormalLifeCycleOperation.VmNoStateFromIntermediateState) { + vmRunningFromIntermediateState(trigger); } else { trigger.next(); } @@ -636,9 +634,10 @@ private EipTO eipStructToEipTO(EipStruct struct) { to.nicIp = struct.getEip().getGuestIp(); to.ipVersion = NetworkUtils.getIpversion(to.nicIp); } - if (struct.getGuestIpRange() != null) { - /* when delete eip, no need nicPrefixLen */ - to.nicPrefixLen = struct.getGuestIpRange().getPrefixLen(); + if (struct.getGuestIp().getIpVersion() == IPv6Constants.IPv4) { + to.nicPrefixLen = NetworkUtils.getPrefixLengthFromNetmask(struct.getGuestIp().getNetmask()); + } else { + to.nicPrefixLen = IPv6NetworkUtils.getPrefixLengthFromNetmask(struct.getGuestIp().getNetmask()); } to.vip = struct.getVip().getIp(); to.vipGateway = struct.getVip().getGateway(); @@ -682,7 +681,8 @@ public void run(MessageReply reply) { } for (AfterApplyFlatEipExtensionPoint ext : pluginRgty.getExtensionList(AfterApplyFlatEipExtensionPoint.class)) { - ext.AfterApplyFlatEip(asList(struct.getVip().getUuid()), hostUuid); + ext.AfterApplyFlatEip(Collections.singletonList(struct.getVip().getUuid()), hostUuid); + ext.cleanGatewayArpEntry(struct.getNic().getVmInstanceUuid(), struct.getGuestIp().getGateway()); } completion.success(); @@ -753,6 +753,11 @@ public String getNetworkServiceProviderType() { return FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING; } + @Override + public List filterEipsForVmNicInVirtualRouter(VmNicInventory vmNic, List eips) { + return eips; + } + @Override public List filterVmNicsForEipInVirtualRouter(VipInventory vip, List vmNics) { /* if vmnic is in flat network, it will be filtered out if it already has eip attached */ @@ -874,4 +879,44 @@ public List getL3NetworkForEipInVirtualRouter(String networkServiceProvi } return new ArrayList<>(); } + + @Override + public List getL3NetworkForVmNetworkService(VmInstanceInventory vm) { + List ret = new ArrayList<>(); + + if (vm == null || vm.getVmNics() == null || vm.getVmNics().isEmpty()) { + return ret; + } + + String flatProvideUuid = Q.New(NetworkServiceProviderVO.class) + .select(NetworkServiceProviderVO_.uuid) + .eq(NetworkServiceProviderVO_.type, FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING) + .findValue(); + + for (VmNicInventory nic : vm.getVmNics()) { + L3NetworkVO l3Vo = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + for (NetworkServiceL3NetworkRefVO ref : l3Vo.getNetworkServices()) { + if (!ref.getNetworkServiceProviderUuid().equals(flatProvideUuid)) { + continue; + } + + if (!ref.getNetworkServiceType().equals(EipConstant.EIP_NETWORK_SERVICE_TYPE)) { + continue; + } + + List eipVOs = Q.New(EipVO.class).eq(EipVO_.vmNicUuid, nic.getUuid()).list(); + if (eipVOs == null || eipVOs.isEmpty()) { + continue; + } + + for (EipVO vo : eipVOs) { + String pubL3Uuid = Q.New(VipVO.class).select(VipVO_.l3NetworkUuid) + .eq(VipVO_.uuid, vo.getVipUuid()).findValue(); + ret.add(L3NetworkInventory.valueOf(dbf.findByUuid(pubL3Uuid, L3NetworkVO.class))); + } + } + } + + return ret; + } } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulator.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulator.java index 996bc157665..2d75122d77f 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulator.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulator.java @@ -21,6 +21,10 @@ import org.zstack.network.service.flat.FlatUserdataBackend.*; import org.zstack.utils.gson.JSONObjectUtil; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /** * Created by frank on 9/19/2015. */ @@ -85,6 +89,26 @@ public void reply(HttpEntity entity, Object rsp) { return null; } + @RequestMapping(value = FlatDhcpBackend.DHCP_FLUSH_NAMESPACE_PATH, method = RequestMethod.POST) + public @ResponseBody String flushNamespace(HttpEntity entity) { + FlushDhcpNamespaceCmd cmd = JSONObjectUtil.toObject(entity.getBody(), FlushDhcpNamespaceCmd.class); + config.flushNamespaceCmds.add(cmd); + FlushDhcpNamespaceRsp rsp = new FlushDhcpNamespaceRsp(); + reply(entity, rsp); + return null; + } + + @RequestMapping(value = FlatDhcpBackend.ARPING_NAMESPACE_PATH, method = RequestMethod.POST) + public @ResponseBody String arpingNamespace(HttpEntity entity) { + ArpingCmd cmd = JSONObjectUtil.toObject(entity.getBody(), ArpingCmd.class); + config.arpingNamespaceCmds.add(cmd); + Map> result = new HashMap<>(); + ArpingRsp rsp = new ArpingRsp(); + rsp.result = result; + reply(entity, rsp); + return null; + } + @RequestMapping(value = FlatUserdataBackend.APPLY_USER_DATA, method = RequestMethod.POST) public @ResponseBody String applyUserdata(HttpEntity entity) { ApplyUserdataCmd cmd = JSONObjectUtil.toObject(entity.getBody(), ApplyUserdataCmd.class); diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulatorConfig.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulatorConfig.java index 3ca5b9a5c23..94f483f029c 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulatorConfig.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatNetworkServiceSimulatorConfig.java @@ -30,4 +30,6 @@ public class FlatNetworkServiceSimulatorConfig { public List resetDefaultGatewayCmds = new ArrayList(); public List batchApplyUserdataCmds = new ArrayList(); public List deleteNamespaceCmds = new ArrayList<>(); + public List flushNamespaceCmds = new ArrayList<>(); + public List arpingNamespaceCmds = new ArrayList<>(); } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatProviderFactory.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatProviderFactory.java index c1a05abf60a..dacc2d2a985 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatProviderFactory.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatProviderFactory.java @@ -10,6 +10,7 @@ import org.zstack.header.network.l2.APICreateL2NetworkMsg; import org.zstack.header.network.l2.L2NetworkCreateExtensionPoint; import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.service.*; import org.zstack.network.service.eip.EipConstant; import org.zstack.network.service.userdata.UserdataConstant; @@ -49,6 +50,9 @@ public NetworkServiceProvider getNetworkServiceProvider(NetworkServiceProviderVO @Override public void prepareDbInitialValue() { + FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE.setCreateDhcpNameSpace(true); + FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE.setAllocateDhcpServerIp(true); + SimpleQuery query = dbf.createQuery(NetworkServiceProviderVO.class); query.add(NetworkServiceProviderVO_.type, Op.EQ, FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING); NetworkServiceProviderVO rpvo = query.find(); @@ -112,6 +116,11 @@ public void beforeCreateL2Network(APICreateL2NetworkMsg msg) throws NetworkExcep @Override public void afterCreateL2Network(L2NetworkInventory l2Network) { + VSwitchType vSwitchType = VSwitchType.valueOf(l2Network.getvSwitchType()); + if (vSwitchType.getSdnControllerType() != null) { + return; + } + NetworkServiceProviderL2NetworkRefVO ref = new NetworkServiceProviderL2NetworkRefVO(); ref.setL2NetworkUuid(l2Network.getUuid()); ref.setNetworkServiceProviderUuid(flatProvider.getUuid()); diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java index 7f24a8e510a..c7b9181da1b 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatUserdataBackend.java @@ -1,44 +1,43 @@ package org.zstack.network.service.flat; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.vm.UserdataBuilder; import org.zstack.compute.vm.VmSystemTags; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; -import org.zstack.core.db.SQL; import org.zstack.core.gc.GC; import org.zstack.core.gc.GCCompletion; import org.zstack.core.gc.TimeBasedGarbageCollector; import org.zstack.core.timeout.ApiTimeoutManager; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.core.Completion; -import org.zstack.header.core.FutureCompletion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.host.HostConstant; import org.zstack.header.host.HostStatus; import org.zstack.header.host.HostVO; import org.zstack.header.host.HostVO_; import org.zstack.header.message.MessageReply; -import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.network.l2.L2NetworkVO_; -import org.zstack.header.network.l3.L3NetworkDeleteExtensionPoint; -import org.zstack.header.network.l3.L3NetworkInventory; -import org.zstack.header.network.service.NetworkServiceConstants; -import org.zstack.header.network.service.NetworkServiceL3NetworkRefInventory; -import org.zstack.header.network.service.NetworkServiceProviderType; -import org.zstack.header.network.service.NetworkServiceProviderVO; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.L2NetworkUpdateExtensionPoint; +import org.zstack.header.network.l3.*; +import org.zstack.header.network.service.*; import org.zstack.header.vm.*; +import org.zstack.header.zone.ZoneVO; import org.zstack.kvm.*; import org.zstack.kvm.KVMAgentCommands.AgentResponse; +import org.zstack.network.l2.L2NetworkHostHelper; import org.zstack.network.service.NetworkProviderFinder; import org.zstack.network.service.NetworkServiceFilter; import org.zstack.network.service.NetworkServiceManager; @@ -62,7 +61,7 @@ * Created by frank on 10/13/2015. */ public class FlatUserdataBackend implements UserdataBackend, KVMHostConnectExtensionPoint, - L3NetworkDeleteExtensionPoint, VmInstanceMigrateExtensionPoint { + L3NetworkDeleteExtensionPoint, L2NetworkUpdateExtensionPoint, VmInstanceMigrateExtensionPoint { private static final CLogger logger = Utils.getLogger(FlatUserdataBackend.class); @Autowired @@ -83,8 +82,120 @@ public class FlatUserdataBackend implements UserdataBackend, KVMHostConnectExten public static final String RELEASE_USER_DATA = "/flatnetworkprovider/userdata/release"; public static final String CLEANUP_USER_DATA = "/flatnetworkprovider/userdata/cleanup"; + private String getVmNicMacAddressByVmInstanceUuid(String vmInstanceUuid) { + String sql = "SELECT nic.mac " + + "FROM VmInstanceVO vm " + + "JOIN VmNicVO nic ON vm.uuid = nic.vmInstanceUuid " + + "WHERE vm.uuid = :vmInstanceUuid " + + "AND nic.l3NetworkUuid = vm.defaultL3NetworkUuid"; + + TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); + q.setParameter("vmInstanceUuid", vmInstanceUuid); + + List resultList = q.getResultList(); + if (resultList.isEmpty()) { + return null; + } + return resultList.get(0); + } + + + private String getZoneNameByVmInstanceUuid(String vmInstanceUuid) { + VmInstanceVO vmInstance = dbf.findByUuid(vmInstanceUuid, VmInstanceVO.class); + if (vmInstance == null || vmInstance.getZoneUuid() == null) { + return null; + } + + String zoneId = vmInstance.getZoneUuid(); + + ZoneVO zone = dbf.findByUuid(zoneId, ZoneVO.class); + if (zone == null) { + return null; + } + + return zone.getName(); + } + + private String getDnsServersIpFromVm(String vmInstanceUuid) { + String sql = "SELECT dns.dns FROM VmInstanceVO AS v " + + "JOIN L3NetworkDnsVO AS dns ON v.defaultL3NetworkUuid = dns.l3NetworkUuid " + + "WHERE v.uuid = :vmInstanceUuid"; + + TypedQuery query = dbf.getEntityManager().createQuery(sql, String.class); + query.setParameter("vmInstanceUuid", vmInstanceUuid); + List dnsServers = query.getResultList(); + if (dnsServers.isEmpty()) { + return null; + } + + StringBuilder dnsIpListBuilder = new StringBuilder(); + for (String dnsIp : dnsServers) { + dnsIpListBuilder.append(dnsIp).append("\n"); + } + // Delete the last extra newline character, if it exists. + if (dnsIpListBuilder.length() > 0) { + dnsIpListBuilder.setLength(dnsIpListBuilder.length() - 1); + } + + return dnsIpListBuilder.toString(); + } + + private String getVpcIdByVmInstanceUuid(String vmInstanceUuid) { + String sql = "SELECT DISTINCT vm.uuid " + + "FROM VmInstanceVO vm " + + "JOIN VmNicVO nic ON vm.uuid = nic.vmInstanceUuid " + + "WHERE vm.type = 'ApplianceVm' " + + "AND nic.l3NetworkUuid IN (" + + " SELECT v.defaultL3NetworkUuid " + + " FROM VmInstanceVO v " + + " WHERE v.uuid = :vmInstanceUuid" + + ")"; + + TypedQuery query = dbf.getEntityManager().createQuery(sql, String.class); + query.setParameter("vmInstanceUuid", vmInstanceUuid); + + List results = query.getResultList(); + if (results.isEmpty()) { + return null; + } + + return results.get(0); + } + + private List getNetworkInterfaceDetails(String vmInstanceUuid) { + String sql = "select DISTINCT nic.mac, nic.ip, nic.netmask, nic.gateway, ipr.networkCidr " + + "from VmNicVO nic " + + "join IpRangeVO ipr on nic.l3NetworkUuid = ipr.l3NetworkUuid " + + "where nic.vmInstanceUuid = :vmInstanceUuid " + + "and nic.ipVersion = :ipVersion "; + + TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); + q.setParameter("vmInstanceUuid", vmInstanceUuid); + q.setParameter("ipVersion", IPv6Constants.IPv4); + List ts = q.getResultList(); + + List networkInterfaceDetailsList = new ArrayList<>(); + + for (Tuple t : ts) { + NetworkInterfaceDetails details = new NetworkInterfaceDetails(); + details.macAddress = t.get(0, String.class); + details.ip = t.get(1, String.class); + details.netmask = t.get(2, String.class); + details.gateway = t.get(3, String.class); + details.vpcCidrBlock = t.get(4, String.class); + details.vSwitchCidrBlock = t.get(4, String.class); + networkInterfaceDetailsList.add(details); + } + + return networkInterfaceDetailsList; + } + @Override public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { + return createHostPrepareUserdataFlow(context.getInventory().getUuid()); + } + + private Flow createHostPrepareUserdataFlow(final String hostUuid) { return new NoRollbackFlow() { String __name__ = "prepare-userdata"; @@ -93,7 +204,7 @@ private List getVmsNeedUserdataOnHost() { String sql = "select vm.uuid from VmInstanceVO vm where vm.hostUuid = :huuid and vm.state = :state and vm.type = :type"; TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("state", VmInstanceState.Running); - q.setParameter("huuid", context.getInventory().getUuid()); + q.setParameter("huuid", hostUuid); q.setParameter("type", VmInstanceConstant.USER_VM_TYPE); List vmUuids = q.getResultList(); if (vmUuids.isEmpty()) { @@ -122,7 +233,7 @@ private Map getVmIpL3Uuid(List vmUuids) { "NetworkServiceProviderVO pro, UsedIpVO ip where " + " vm.uuid = nic.vmInstanceUuid and vm.uuid in (:uuids)" + " and nic.uuid = ip.vmNicUuid " + - " and ip.l3NetworkUuid = vm.defaultL3NetworkUuid and ip.ipVersion = :ipversion" + + " and ip.l3NetworkUuid = vm.defaultL3NetworkUuid and ip.ipVersion = :ipVersion" + " and ref.networkServiceProviderUuid = pro.uuid" + " and ref.l3NetworkUuid = vm.defaultL3NetworkUuid" + " and pro.type = :proType"; @@ -131,7 +242,7 @@ private Map getVmIpL3Uuid(List vmUuids) { q.setParameter("uuids", vmUuids); q.setParameter("proType", FlatNetworkServiceConstant.FLAT_NETWORK_SERVICE_TYPE_STRING); /* current only ipv4 has userdata */ - q.setParameter("ipversion", IPv6Constants.IPv4); + q.setParameter("ipVersion", IPv6Constants.IPv4); List ts = q.getResultList(); Map ret = new HashMap(); @@ -173,15 +284,24 @@ private List getUserData() { } l3Uuids.add(l.l3Uuid); } - + List tos = new ArrayList<>(); + if (l3Uuids.isEmpty()) { + return tos; + } Map bridgeNames = new BridgeNameFinder().findByL3Uuids(l3Uuids); + List l2Uuids = Q.New(L3NetworkVO.class) + .select(L3NetworkVO_.l2NetworkUuid).in(L3NetworkVO_.uuid, l3Uuids).listValues(); + Map bridgesVlan = new BridgeVlanIdFinder().findByL2Uuids(l2Uuids); - List tos = new ArrayList(); for (String vmuuid : vmUuids) { UserdataTO to = new UserdataTO(); MetadataTO mto = new MetadataTO(); mto.vmUuid = vmuuid; mto.vmHostname = VmSystemTags.HOSTNAME.getTokenByResourceUuid(vmuuid, VmSystemTags.HOSTNAME_TOKEN); + mto.regionName = getZoneNameByVmInstanceUuid(vmuuid); + mto.mac = getVmNicMacAddressByVmInstanceUuid(vmuuid); + mto.dnsServersIp = getDnsServersIpFromVm(vmuuid); + mto.vpcId = getVpcIdByVmInstanceUuid(vmuuid); to.metadata = mto; VmIpL3Uuid l = vmipl3.get(vmuuid); @@ -193,23 +313,19 @@ private List getUserData() { continue; } - // TODO: vDPA do not support Userdata service yet; - boolean isOvsDpdk = (Long) SQL.New("select count(l2.uuid)" + - " from L2NetworkVO l2, L3NetworkVO l3" + - " where l3.uuid = :l3Uuid" + - " and l2.uuid = l3.l2NetworkUuid" + - " and l2.vSwitchType = :vswitchType", Long.class) - .param("l3Uuid", l.l3Uuid) - .param("vswitchType", L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK) - .find() > 0; - if (isOvsDpdk) { + if (l.netmask == null) { + /* user data config need netmask */ + logger.info(String.format("can not get netmask for vmnic[ip:%s] for vm[uuid:%s]", + l.vmIp, vmuuid)); continue; } + to.networkInterfaces = getNetworkInterfaceDetails(vmuuid); to.dhcpServerIp = l.dhcpServerIp; to.vmIp = l.vmIp; to.netmask = l.netmask; to.bridgeName = bridgeNames.get(l.l3Uuid); + to.vlanId = bridgesVlan.get(to.bridgeName); to.namespaceName = FlatDhcpBackend.makeNamespaceName(to.bridgeName, l.l3Uuid); if (userdata.get(vmuuid) != null) { to.userdataList.addAll(userdata.get(vmuuid)); @@ -238,7 +354,7 @@ public void run(final FlowTrigger trigger, Map data) { cmd.userdata = tos; cmd.rebuild = true; - new KvmCommandSender(context.getInventory().getUuid(), true).send(cmd, BATCH_APPLY_USER_DATA, new KvmCommandFailureChecker() { + new KvmCommandSender(hostUuid, true).send(cmd, BATCH_APPLY_USER_DATA, new KvmCommandFailureChecker() { @Override public ErrorCode getError(KvmResponseWrapper wrapper) { AgentResponse rsp = wrapper.getResponse(AgentResponse.class); @@ -352,19 +468,14 @@ private UserdataStruct makeUserdataStructForMigratingVm(VmInstanceInventory inv, @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { UserdataStruct struct = makeUserdataStructForMigratingVm(inv, destHostUuid); if (struct == null) { + completion.success(); return; } - FutureCompletion completion = new FutureCompletion(null); applyUserdata(struct, completion); - completion.await(); - - if (!completion.isSuccess()) { - throw new OperationFailureException(completion.getErrorCode()); - } } @Override @@ -380,15 +491,6 @@ public static class UserdataReleseGC extends TimeBasedGarbageCollector { @Override protected void triggerNow(GCCompletion completion) { - // TODO: vDPA do not support Userdata service yet; - List tmp = new ArrayList<>(); - for (VmNicInventory vNic : struct.getVmNics()) { - if (vNic.getType().equals("vDPA")) { - continue; - } - tmp.add(vNic); - } - struct.setVmNics(tmp); HostStatus status = Q.New(HostVO.class).select(HostVO_.status).eq(HostVO_.uuid, struct.getHostUuid()).findValue(); if (status == null) { @@ -402,11 +504,17 @@ protected void triggerNow(GCCompletion completion) { return; } + String vmIp = CollectionUtils.find(struct.getVmNics(), arg -> arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null); + if (vmIp == null) { + completion.cancel(); + return; + } + ReleaseUserdataCmd cmd = new ReleaseUserdataCmd(); cmd.hostUuid = struct.getHostUuid(); cmd.bridgeName = new BridgeNameFinder().findByL3Uuid(struct.getL3NetworkUuid()); cmd.namespaceName = FlatDhcpBackend.makeNamespaceName(cmd.bridgeName, struct.getL3NetworkUuid()); - cmd.vmIp = CollectionUtils.find(struct.getVmNics(), arg -> arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null); + cmd.vmIp = vmIp; KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(struct.getHostUuid()); @@ -487,11 +595,13 @@ public void fail(ErrorCode errorCode) { public static class UserdataTO { public MetadataTO metadata; + public List networkInterfaces; public List userdataList = new ArrayList<>(); public String vmIp; public String netmask; public String dhcpServerIp; public String bridgeName; + public String vlanId; public String namespaceName; public String l3NetworkUuid; public Map agentConfig; @@ -501,11 +611,27 @@ public static class UserdataTO { public static class MetadataTO { public String vmUuid; public String vmHostname; + public String regionName; + public String mac; + public String dnsServersIp; + public String vpcId; + } + + public static class NetworkInterfaceDetails { + public String macAddress; + public String ip; + public String vpcCidrBlock; + public String vSwitchCidrBlock; + public String netmask; + public String gateway; } public static class CleanupUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String bridgeName; + @GrayVersion(value = "5.0.0") public String l3NetworkUuid; + @GrayVersion(value = "5.0.0") public String namespaceName; } @@ -514,12 +640,16 @@ public static class CleanupUserdataRsp extends KVMAgentCommands.AgentResponse { } public static class BatchApplyUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public List userdata; + @GrayVersion(value = "5.0.0") public boolean rebuild; } public static class ApplyUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String hostUuid; + @GrayVersion(value = "5.0.0") public UserdataTO userdata; } @@ -528,9 +658,13 @@ public static class ApplyUserdataRsp extends KVMAgentCommands.AgentResponse { } public static class ReleaseUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String hostUuid; + @GrayVersion(value = "5.0.0") public String vmIp; + @GrayVersion(value = "5.0.0") public String bridgeName; + @GrayVersion(value = "5.0.0") public String namespaceName; } @@ -553,7 +687,7 @@ private boolean hasUserdata(UserdataStruct struct) { @Override public void applyUserdata(final UserdataStruct struct, final Completion completion) { if (!UserdataGlobalConfig.OPEN_USERDATA_SERVICE_BY_DEFAULT.value(Boolean.class)) { - if ( !hasMetedata(struct) && !hasUserdata(struct)) { + if (!hasMetedata(struct) && !hasUserdata(struct)) { completion.success(); return; } @@ -564,15 +698,40 @@ public void applyUserdata(final UserdataStruct struct, final Completion completi return; } - // TODO: vDPA do not support Userdata service yet; - List tmp = new ArrayList<>(); - for (VmNicInventory vNic : struct.getVmNics()) { - if (vNic.getType().equals("vDPA")) { - continue; + VmNicInventory destNic = CollectionUtils.find(struct.getVmNics(), new Function() { + @Override + public VmNicInventory call(VmNicInventory arg) { + return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg : null; } - tmp.add(vNic); + }); + + if (destNic == null) { + completion.success(); + return; } - struct.setVmNics(tmp); + + L3NetworkVO defaultL3 = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, struct.getL3NetworkUuid()).find(); + if (defaultL3 != null && defaultL3.getNetworkServices().stream().noneMatch( + service -> Objects.equals(UserdataConstant.USERDATA_TYPE_STRING, service.getNetworkServiceType()))) { + completion.success(); + return; + } + + UsedIpVO ipv4 = Q.New(UsedIpVO.class).eq(UsedIpVO_.vmNicUuid, destNic.getUuid()) + .eq(UsedIpVO_.ipVersion, IPv6Constants.IPv4).limit(1).find(); + if (ipv4 == null) { + // userdata depends on the ipv4 address + completion.success(); + return; + } + if (StringUtils.isEmpty(ipv4.getNetmask())) { + // userdata depends on the ipv4 netmask + logger.info(String.format("can not get netmask for vmnic[ip:%s] for vm[uuid:%s]", + ipv4.getIp(), struct.getVmUuid())); + completion.success(); + return; + } + FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("flat-network-userdata-set-for-vm-%s", struct.getVmUuid())); @@ -620,23 +779,19 @@ public void run(final FlowTrigger trigger, Map data) { MetadataTO to = new MetadataTO(); to.vmUuid = struct.getVmUuid(); to.vmHostname = VmSystemTags.HOSTNAME.getTokenByResourceUuid(struct.getVmUuid(), VmSystemTags.HOSTNAME_TOKEN); + to.regionName = getZoneNameByVmInstanceUuid(struct.getVmUuid()); + to.mac = destNic.getMac(); + to.dnsServersIp = getDnsServersIpFromVm(struct.getVmUuid()); + to.vpcId = getVpcIdByVmInstanceUuid(struct.getVmUuid()); UserdataTO uto = new UserdataTO(); uto.metadata = to; + uto.networkInterfaces = getNetworkInterfaceDetails(struct.getVmUuid()); uto.userdataList = struct.getUserdataList(); uto.dhcpServerIp = dhcpServerIp; - uto.vmIp = CollectionUtils.find(struct.getVmNics(), new Function() { - @Override - public String call(VmNicInventory arg) { - return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null; - } - }); - uto.netmask = CollectionUtils.find(struct.getVmNics(), new Function() { - @Override - public String call(VmNicInventory arg) { - return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getNetmask() : null; - } - }); + uto.vmIp = ipv4.getIp(); + uto.netmask = ipv4.getNetmask(); uto.bridgeName = new BridgeNameFinder().findByL3Uuid(struct.getL3NetworkUuid()); + uto.vlanId = new BridgeVlanIdFinder().findByL2Uuid(defaultL3.getL2NetworkUuid(), false); uto.namespaceName = FlatDhcpBackend.makeNamespaceName(uto.bridgeName, struct.getL3NetworkUuid()); uto.port = UserdataGlobalProperty.HOST_PORT; uto.l3NetworkUuid = struct.getL3NetworkUuid(); @@ -696,15 +851,25 @@ public void releaseUserdata(final UserdataStruct struct, final Completion comple return; } - // TODO: vDPA do not support Userdata service yet; - List tmp = new ArrayList<>(); - for (VmNicInventory vNic : struct.getVmNics()) { - if (vNic.getType().equals("vDPA")) { - continue; + + VmNicInventory destNic = CollectionUtils.find(struct.getVmNics(), new Function() { + @Override + public VmNicInventory call(VmNicInventory arg) { + return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg : null; } - tmp.add(vNic); + }); + + if (destNic == null) { + completion.success(); + return; + } + + UsedIpInventory ipv4 = destNic.getUsedIps().stream().filter(ip -> ip.getIpVersion() == IPv6Constants.IPv4).findAny().orElse(null); + if (ipv4 == null) { + // userdata depends on the ipv4 address + completion.success(); + return; } - struct.setVmNics(tmp); FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("flat-network-userdata-release-for-vm-%s", struct.getVmUuid())); @@ -720,12 +885,7 @@ public void run(final FlowTrigger trigger, Map data) { cmd.hostUuid = struct.getHostUuid(); cmd.bridgeName = new BridgeNameFinder().findByL3Uuid(struct.getL3NetworkUuid()); cmd.namespaceName = FlatDhcpBackend.makeNamespaceName(cmd.bridgeName, struct.getL3NetworkUuid()); - cmd.vmIp = CollectionUtils.find(struct.getVmNics(), new Function() { - @Override - public String call(VmNicInventory arg) { - return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null; - } - }); + cmd.vmIp = ipv4.getIp(); KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(struct.getHostUuid()); @@ -769,4 +929,41 @@ public void handle(ErrorCode errCode, Map data) { } }).start(); } + + @Override + public void beforeChangeL2NetworkVlanId(L2NetworkInventory l2Inv) { + + } + + @Override + public void afterChangeL2NetworkVlanId(L2NetworkInventory l2Inv) { + new While<>(L2NetworkHostHelper.getHostsByL2NetworkAttachedCluster(l2Inv)).step((host, whileCompletion) -> { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("after-l2-%s-changed-flat-network-userdata-apply-in-host-%s", + l2Inv.getUuid(), host.getUuid())); + chain.then(createHostPrepareUserdataFlow(host.getUuid())); + chain.done(new FlowDoneHandler(whileCompletion) { + @Override + public void handle(Map data) { + whileCompletion.done(); + } + }).error(new FlowErrorHandler(whileCompletion) { + @Override + public void handle(ErrorCode errCode, Map data) { + whileCompletion.addError(errCode); + whileCompletion.allDone(); + } + }).start(); + }, 10).run(new WhileDoneCompletion(null) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + logger.error(String.format("apply userdata failed after L2Network changed, because:%s", + errorCodeList.getCauses().get(0))); + } else { + logger.debug("apply userdata successful after L2Network changed"); + } + } + }); + } } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatVipFactory.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatVipFactory.java index 852239dfd18..c7be44c3d74 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatVipFactory.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/FlatVipFactory.java @@ -33,6 +33,11 @@ protected void handleBackendSpecificMessage(Message msg) { bus.dealWithUnknownMessage(msg); } + @Override + protected void acquireVipOnSpecificBackend(String specificBackendUuid, Completion completion) { + completion.success(); + } + }; } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/L3NetworkGetIpStatisticExtensionPoint.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/L3NetworkGetIpStatisticExtensionPoint.java index 3903326c53d..030cead38dc 100644 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/L3NetworkGetIpStatisticExtensionPoint.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/L3NetworkGetIpStatisticExtensionPoint.java @@ -1,6 +1,9 @@ package org.zstack.network.service.flat; +import java.util.Map; +import java.util.List; + public interface L3NetworkGetIpStatisticExtensionPoint { String getApplianceVmInstanceType(); - String getParentUuid(String uuid); + List getParentUuid(String uuid, String vipUuid); } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/PackageInfo.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/PackageInfo.java index 75baa0fbe1a..f132501a7b3 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/PackageInfo.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/flat/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "扁平网络") +@PackageAPIInfo( + APICategoryName = "扁平网络", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataExtension.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataExtension.java index 2870b7ce513..8e75c4edd53 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataExtension.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataExtension.java @@ -1,7 +1,6 @@ package org.zstack.network.service.userdata; import org.springframework.beans.factory.annotation.Autowired; -import org.zstack.core.Platform; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; @@ -11,25 +10,21 @@ import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; -import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.network.l2.L2NetworkVO_; import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; import org.zstack.header.network.service.*; -import org.zstack.header.vm.*; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.vm.VmNicSpec; import org.zstack.network.securitygroup.SecurityGroupGetDefaultRuleExtensionPoint; -import org.zstack.network.securitygroup.SecurityGroupRuleProtocolType; -import org.zstack.network.securitygroup.SecurityGroupRuleType; -import org.zstack.network.securitygroup.SecurityGroupRuleVO; import org.zstack.network.service.AbstractNetworkServiceExtension; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; -import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import java.util.*; -import java.util.stream.Collectors; /** * Created by frank on 10/13/2015. @@ -73,14 +68,10 @@ public NetworkServiceType getNetworkServiceType() { return UserdataConstant.USERDATA_TYPE; } - private NetworkServiceProviderInventory findProvider(final VmInstanceSpec spec) { - L3NetworkInventory defaultL3 = CollectionUtils.find(VmNicSpec.getL3NetworkInventoryOfSpec(spec.getL3Networks()), - new Function() { - @Override - public L3NetworkInventory call(L3NetworkInventory arg) { - return arg.getUuid().equals(spec.getVmInventory().getDefaultL3NetworkUuid()) ? arg : null; - } - }); + private NetworkServiceProviderInventory findProvider(final L3NetworkInventory defaultL3) { + if (defaultL3 == null || defaultL3.getNetworkServices() == null) { + return null; + } for (NetworkServiceL3NetworkRefInventory ref : defaultL3.getNetworkServices()) { if (UserdataConstant.USERDATA_TYPE_STRING.equals(ref.getNetworkServiceType())) { @@ -103,12 +94,21 @@ private UserdataBackend getUserdataBackend(String providerType) { @Override public void applyNetworkService(final VmInstanceSpec servedVm, Map data, Completion completion) { L3NetworkInventory defaultL3 = CollectionUtils.find(VmNicSpec.getL3NetworkInventoryOfSpec(servedVm.getL3Networks()), - new Function() { - @Override - public L3NetworkInventory call(L3NetworkInventory arg) { - return arg.getUuid().equals(servedVm.getVmInventory().getDefaultL3NetworkUuid()) ? arg : null; + arg -> arg.getUuid().equals(servedVm.getVmInventory().getDefaultL3NetworkUuid()) ? arg : null); + VmNicInventory defaultNic = null; + if (defaultL3 == null && servedVm.getVmInventory().getDefaultL3NetworkUuid() != null && UserdataGlobalProperty.APPLY_WITH_NONE_DEFAULT_NIC) { + L3NetworkVO l3 = Q.New(L3NetworkVO.class) + .eq(L3NetworkVO_.uuid, servedVm.getVmInventory().getDefaultL3NetworkUuid()) + .find(); + if (l3 != null) { + defaultL3 = L3NetworkInventory.valueOf(l3); + final String defaultL3Uuid = defaultL3.getUuid(); + defaultNic = servedVm.getVmInventory().getVmNics().stream() + .filter(vmNic -> vmNic.getL3NetworkUuid().equals(defaultL3Uuid)) + .findFirst() + .orElse(null); } - }); + } if (defaultL3 == null) { // the L3 for operation is not the default L3 @@ -116,22 +116,13 @@ public L3NetworkInventory call(L3NetworkInventory arg) { return; } - // TODO: vDPA do not support Userdata service yet; - boolean isOvsDpdk = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, defaultL3.getL2NetworkUuid()) - .eq(L2NetworkVO_.vSwitchType, L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK) - .isExists(); - if (isOvsDpdk) { - completion.success(); - return; - } - if (!defaultL3.getIpVersions().contains(IPv6Constants.IPv4)) { // userdata depends on the ipv4 address completion.success(); return; } - NetworkServiceProviderInventory provider = findProvider(servedVm); + NetworkServiceProviderInventory provider = findProvider(defaultL3); if (provider == null) { completion.success(); return; @@ -141,7 +132,9 @@ public L3NetworkInventory call(L3NetworkInventory arg) { struct.setL3NetworkUuid(servedVm.getVmInventory().getDefaultL3NetworkUuid()); struct.setParametersFromVmSpec(servedVm); struct.setUserdataList(servedVm.getUserdataList()); - + if (defaultNic != null) { + struct.getVmNics().add(defaultNic); + } UserdataBackend bkd = getUserdataBackend(provider.getType()); bkd.applyUserdata(struct, completion); } @@ -160,12 +153,7 @@ public List getGroupMembers(String sgUuid, int ipVersion) { @Override public void releaseNetworkService(final VmInstanceSpec servedVm, Map data, final NoErrorCompletion completion) { L3NetworkInventory defaultL3 = CollectionUtils.find(VmNicSpec.getL3NetworkInventoryOfSpec(servedVm.getL3Networks()), - new Function() { - @Override - public L3NetworkInventory call(L3NetworkInventory arg) { - return arg.getUuid().equals(servedVm.getVmInventory().getDefaultL3NetworkUuid()) ? arg : null; - } - }); + arg -> arg.getUuid().equals(servedVm.getVmInventory().getDefaultL3NetworkUuid()) ? arg : null); if (!Optional.ofNullable(servedVm.getDestHost()).isPresent()){ completion.done(); return; @@ -182,7 +170,7 @@ public L3NetworkInventory call(L3NetworkInventory arg) { return; } - NetworkServiceProviderInventory provider = findProvider(servedVm); + NetworkServiceProviderInventory provider = findProvider(defaultL3); if (provider == null) { completion.done(); return; @@ -208,4 +196,14 @@ public void fail(ErrorCode errorCode) { } }); } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataGlobalProperty.java b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataGlobalProperty.java index 50bbd0c6862..c6d8e4edad2 100755 --- a/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataGlobalProperty.java +++ b/plugin/flatNetworkProvider/src/main/java/org/zstack/network/service/userdata/UserdataGlobalProperty.java @@ -10,4 +10,7 @@ public class UserdataGlobalProperty { @GlobalProperty(name="Userdata.hostPort", defaultValue = "1180") public static int HOST_PORT; + + @GlobalProperty(name="Userdata.applyWithNoneDefaultNic", defaultValue = "false") + public static boolean APPLY_WITH_NONE_DEFAULT_NIC; } diff --git a/plugin/hostNetworkInterface/pom.xml b/plugin/hostNetworkInterface/pom.xml new file mode 100644 index 00000000000..bb0d6ab3596 --- /dev/null +++ b/plugin/hostNetworkInterface/pom.xml @@ -0,0 +1,108 @@ + + + 4.0.0 + + org.zstack + plugin + 5.4.0 + + + hostNetworkInterface + + + + org.zstack + network + ${project.version} + + + org.zstack + vip + ${project.version} + + + org.zstack + acl + ${project.version} + + + org.zstack + compute + ${project.version} + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + + + org.zstack + kvm + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchMsg.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchMsg.java new file mode 100644 index 00000000000..a5dc969af22 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchMsg.java @@ -0,0 +1,34 @@ +package org.zstack.network.hostNetworkInterface; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostConstant; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created with IntelliJ IDEA. + * User: frank + * Time: 8:34 PM + * To change this template use File | Settings | File Templates. + */ +@AutoQuery(replyClass = APIQueryPhysicalSwitchReply.class, inventoryClass = PhysicalSwitchInventory.class) +@Action(category = HostConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/topo/physical-switches", + optionalPaths = {"/topo/physical-switches/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryPhysicalSwitchReply.class +) +public class APIQueryPhysicalSwitchMsg extends APIQueryMessage { + + public static List __example__() { + return asList("uuid=" + uuid()); + } + +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchMsgDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..31b125d3f80 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.network.hostNetworkInterface + +import org.zstack.network.hostNetworkInterface.APIQueryPhysicalSwitchReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryPhysicalSwitch" + + category "二层网络" + + desc """查询物理机交换机信息""" + + rest { + request { + url "GET /v1/topo/physical-switches" + url "GET /v1/topo/physical-switches/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryPhysicalSwitchMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryPhysicalSwitchReply.class + } + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchReply.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchReply.java new file mode 100644 index 00000000000..562c34887e8 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchReply.java @@ -0,0 +1,41 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +import static org.zstack.utils.CollectionDSL.list; + +/** + * Created with IntelliJ IDEA. + * User: frank + * Time: 8:35 PM + * To change this template use File | Settings | File Templates. + */ +@RestResponse(allTo = "inventories") +public class APIQueryPhysicalSwitchReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryPhysicalSwitchReply __example__() { + APIQueryPhysicalSwitchReply reply = new APIQueryPhysicalSwitchReply(); + + PhysicalSwitchInventory phySwitch = new PhysicalSwitchInventory(); + phySwitch.setName("test-sdn"); + phySwitch.setUuid(uuid()); + phySwitch.setDescription("sdn for test"); + phySwitch.setIp("192.168.1.1"); + + reply.setInventories(list(phySwitch)); + return reply; + } + +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchReplyDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..a3e9bfc00c0 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/APIQueryPhysicalSwitchReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.hostNetworkInterface + +import org.zstack.network.hostNetworkInterface.PhysicalSwitchInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "query physical switch" + + ref { + name "inventories" + path "org.zstack.network.hostNetworkInterface.APIQueryPhysicalSwitchReply.inventories" + desc "List of physical switch inventories returned by the query" + type "List" + since "5.3.28" + clz PhysicalSwitchInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.28" + } + ref { + name "error" + path "org.zstack.network.hostNetworkInterface.APIQueryPhysicalSwitchReply.error" + desc "Error code, null indicates success, non-null indicates operation failure" + type "ErrorCode" + since "5.3.28" + clz ErrorCode.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingInventory.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingInventory.java new file mode 100644 index 00000000000..a92752e7e70 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingInventory.java @@ -0,0 +1,230 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.Queryable; +import org.zstack.header.search.Inventory; + +import javax.persistence.JoinColumn; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Create by weiwang at 2019-04-25 + */ +@PythonClassInventory +@Inventory(mappingVOClass = HostNetworkBondingVO.class) +public class HostNetworkBondingInventory implements Serializable { + private String uuid; + private String hostUuid; + private String bondingName; + private String bondingType; + private Long speed; + private String mode; + private String xmitHashPolicy; + private String miiStatus; + private String mac; + private List ipAddresses; + private String gateway; + private String callBackIp; + private Long miimon; + private String type; + private Boolean allSlavesActive; + private String description; + private Timestamp createDate; + private Timestamp lastOpDate; + + @Queryable(mappingClass = HostNetworkInterfaceInventory.class, joinColumn = @JoinColumn(name = "bondingUuid")) + private List slaves; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getBondingName() { + return bondingName; + } + + public void setBondingName(String bondingName) { + this.bondingName = bondingName; + } + + public String getBondingType() { + return bondingType; + } + + public void setBondingType(String bondingType) { + this.bondingType = bondingType; + } + + public Long getSpeed() { + return speed; + } + + public void setSpeed(Long speed) { + this.speed = speed; + } + + public Long getMiimon() { + return miimon; + } + + public void setMiimon(Long miimon) { + this.miimon = miimon; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public String getXmitHashPolicy() { + return xmitHashPolicy; + } + + public void setXmitHashPolicy(String xmitHashPolicy) { + this.xmitHashPolicy = xmitHashPolicy; + } + + public String getMiiStatus() { + return miiStatus; + } + + public void setMiiStatus(String miiStatus) { + this.miiStatus = miiStatus; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public List getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(List ipAddresses) { + this.ipAddresses = ipAddresses; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getCallBackIp() { + return callBackIp; + } + + public void setCallBackIp(String callBackIp) { + this.callBackIp = callBackIp; + } + + public Boolean getAllSlavesActive() { + return allSlavesActive; + } + + public void setAllSlavesActive(Boolean allSlavesActive) { + this.allSlavesActive = allSlavesActive; + } + + public List getSlaves() { + return slaves; + } + + public void setSlaves(List slaves) { + this.slaves = slaves; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public HostNetworkBondingInventory() { + + } + + public HostNetworkBondingInventory(HostNetworkBondingVO vo) { + this.uuid = vo.getUuid(); + this.hostUuid = vo.getHostUuid(); + this.bondingName = vo.getBondingName(); + this.bondingType = vo.getBondingType(); + this.speed = vo.getSpeed(); + this.callBackIp = vo.getCallBackIp(); + this.mode = vo.getMode(); + this.mac = vo.getMac(); + this.miimon = vo.getMiimon(); + this.miiStatus = vo.getMiiStatus(); + this.xmitHashPolicy = vo.getXmitHashPolicy(); + this.allSlavesActive = vo.isAllSlavesActive(); + this.type = vo.getType(); + this.slaves = HostNetworkInterfaceInventory.valueOf(vo.getSlaves()); + this.description = vo.getDescription(); + if (vo.getIpAddresses() != null) { + this.ipAddresses = Arrays.asList(vo.getIpAddresses().split(",")); + } + this.gateway = vo.getGateway(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + } + + public static HostNetworkBondingInventory valueOf(HostNetworkBondingVO vo) { + return new HostNetworkBondingInventory(vo); + } + + public static List valueOf(Collection vos) { + return vos.stream().map(HostNetworkBondingInventory::valueOf).collect(Collectors.toList()); + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingInventoryDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..67445376be8 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingInventoryDoc_zh_cn.groovy @@ -0,0 +1,123 @@ +package org.zstack.network.hostNetworkInterface + +doc { + + title "物理机Bond设备清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "3.5.0" + } + field { + name "hostUuid" + desc "物理机UUID" + type "String" + since "3.5.0" + } + field { + name "bondingName" + desc "Bond名称" + type "String" + since "3.5.0" + } + field { + name "bondingType" + desc "Bond应用状态,有noBridge、bridgeSlave" + type "String" + since "4.7.0" + } + field { + name "speed" + desc "Bond速率" + type "Long" + since "4.7.0" + } + field { + name "mode" + desc "Bond模式" + type "String" + since "3.5.0" + } + field { + name "xmitHashPolicy" + desc "哈希策略" + type "String" + since "3.5.0" + } + field { + name "miiStatus" + desc "mii状态" + type "String" + since "3.5.0" + } + field { + name "mac" + desc "MAC地址" + type "String" + since "3.5.0" + } + field { + name "ipAddresses" + desc "IP地址" + type "List" + since "3.5.0" + } + field { + name "gateway" + desc "网关地址" + type "String" + since "4.7.0" + } + field { + name "callBackIp" + desc "回调地址" + type "String" + since "4.7.0" + } + field { + name "miimon" + desc "mii监控间隔" + type "Long" + since "3.5.0" + } + field { + name "type" + desc "Bond类型" + type "String" + since "4.7.0" + } + field { + name "allSlavesActive" + desc "" + type "Boolean" + since "3.5.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "4.7.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "3.5.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "3.5.0" + } + ref { + name "slaves" + path "org.zstack.network.hostNetworkInterface.HostNetworkBondingInventory.slaves" + desc "BOND Slaves" + type "List" + since "3.5.0" + clz HostNetworkInterfaceInventory.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingType.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingType.java new file mode 100644 index 00000000000..3dfc2e41bff --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingType.java @@ -0,0 +1,69 @@ +package org.zstack.network.hostNetworkInterface; + +import java.util.*; + +public class HostNetworkBondingType { + private static Map types = Collections.synchronizedMap(new HashMap()); + private final String typeName; + private boolean exposed = true; + + public static boolean hasType(String typeName) { + return types.containsKey(typeName); + } + + public HostNetworkBondingType(String typeName) { + this.typeName = typeName; + types.put(typeName, this); + } + + public HostNetworkBondingType(String typeName, boolean exposed) { + this(typeName); + this.exposed = exposed; + } + + public boolean isExposed() { + return exposed; + } + + public void setExposed(boolean exposed) { + this.exposed = exposed; + } + + public static HostNetworkBondingType valueOf(String typeName) { + HostNetworkBondingType type = types.get(typeName); + if (type == null) { + throw new IllegalArgumentException("HostNetworkBondingType type: " + typeName + " was not registered"); + } + return type; + } + + @Override + public String toString() { + return typeName; + } + + @Override + public boolean equals(Object t) { + if (t == null || !(t instanceof HostNetworkBondingType)) { + return false; + } + + HostNetworkBondingType type = (HostNetworkBondingType) t; + return type.toString().equals(typeName); + } + + @Override + public int hashCode() { + return typeName.hashCode(); + } + + public static Set getAllTypeNames() { + HashSet exposedTypes = new HashSet(); + for (HostNetworkBondingType type : types.values()) { + if (type.isExposed()) { + exposedTypes.add(type.toString()); + } + } + return exposedTypes; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingVO.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingVO.java new file mode 100644 index 00000000000..2424abc1b43 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingVO.java @@ -0,0 +1,243 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.host.HostEO; +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; +import org.zstack.header.vo.*; + +import javax.persistence.*; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by GuoYi on 4/23/20. + */ + +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = HostEO.class, joinColumn = "hostUuid") +}) +public class HostNetworkBondingVO extends ResourceVO implements ToInventory, OwnedByAccount { + @Index + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String hostUuid; + + @Column + private String bondingName; + + @Column + private String bondingType; + + @Column + private Long speed; + + @Column + private String mode; + + @Column + private String xmitHashPolicy; + + @Column + private String miiStatus; + + @Column + private String mac; + + @Column + private String ipAddresses; + + @Column + private String gateway; + + @Column + private String callBackIp; + + @Column + private long miimon; + + @Column + private String type; + + @Column + private boolean allSlavesActive; + + @Column + private String description; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @OneToMany(fetch= FetchType.EAGER) + @JoinColumn(name="bondingUuid", insertable=false, updatable=false) + @NoView + private Set slaves = new HashSet<>(); + + @Transient + private String accountUuid; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getBondingName() { + return bondingName; + } + + public void setBondingName(String bondingName) { + this.bondingName = bondingName; + } + + public String getBondingType() { + return bondingType; + } + + public void setBondingType(String bondingType) { + this.bondingType = bondingType; + } + + public Long getSpeed() { + return speed; + } + + public void setSpeed(Long speed) { + this.speed = speed; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public String getXmitHashPolicy() { + return xmitHashPolicy; + } + + public void setXmitHashPolicy(String xmitHashPolicy) { + this.xmitHashPolicy = xmitHashPolicy; + } + + public String getMiiStatus() { + return miiStatus; + } + + public void setMiiStatus(String miiStatus) { + this.miiStatus = miiStatus; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(String ipAddresses) { + this.ipAddresses = ipAddresses; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getCallBackIp() { + return callBackIp; + } + + public void setCallBackIp(String callBackIp) { + this.callBackIp = callBackIp; + } + + public long getMiimon() { + return miimon; + } + + public void setMiimon(long miimon) { + this.miimon = miimon; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isAllSlavesActive() { + return allSlavesActive; + } + + public void setAllSlavesActive(boolean allSlavesActive) { + this.allSlavesActive = allSlavesActive; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public Set getSlaves() { + return slaves; + } + + public void setSlaves(Set slaves) { + this.slaves = slaves; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingVO_.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingVO_.java new file mode 100644 index 00000000000..1bf9c5ad76a --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkBondingVO_.java @@ -0,0 +1,31 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by GuoYi on 4/24/20. + */ +@StaticMetamodel(HostNetworkBondingVO.class) +public class HostNetworkBondingVO_ extends ResourceVO_ { + public static volatile SingularAttribute hostUuid; + public static volatile SingularAttribute bondingName; + public static volatile SingularAttribute bondingType; + public static volatile SingularAttribute speed; + public static volatile SingularAttribute mode; + public static volatile SingularAttribute xmitHashPolicy; + public static volatile SingularAttribute miiStatus; + public static volatile SingularAttribute mac; + public static volatile SingularAttribute ipAddresses; + public static volatile SingularAttribute gateway; + public static volatile SingularAttribute callBackIp; + public static volatile SingularAttribute miimon; + public static volatile SingularAttribute allSlavesActive; + public static volatile SingularAttribute type; + public static volatile SingularAttribute description; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceCanonicalEvents.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceCanonicalEvents.java new file mode 100644 index 00000000000..eebf1f8ee76 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceCanonicalEvents.java @@ -0,0 +1,38 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.message.NeedJsonSchema; + +public class HostNetworkInterfaceCanonicalEvents { + public static final String PEER_PORT_CHANGED = "/network/host-network-interface/peer-changed"; + + @NeedJsonSchema + public static class PeerPortChangedData { + private String interfaceUuid; + private PhysicalSwitchPortInventory oldPhysicalSwitchPort; + private PhysicalSwitchPortInventory newPhysiaclSwitchPort; + + public String getInterfaceUuid() { + return interfaceUuid; + } + + public void setInterfaceUuid(String interfaceUuid) { + this.interfaceUuid = interfaceUuid; + } + + public PhysicalSwitchPortInventory getOldPhysicalSwitchPort() { + return oldPhysicalSwitchPort; + } + + public void setOldPhysicalSwitchPort(PhysicalSwitchPortInventory oldPhysicalSwitchPort) { + this.oldPhysicalSwitchPort = oldPhysicalSwitchPort; + } + + public PhysicalSwitchPortInventory getNewPhysiaclSwitchPort() { + return newPhysiaclSwitchPort; + } + + public void setNewPhysiaclSwitchPort(PhysicalSwitchPortInventory newPhysiaclSwitchPort) { + this.newPhysiaclSwitchPort = newPhysiaclSwitchPort; + } + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceConstant.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceConstant.java new file mode 100644 index 00000000000..995c2d945ff --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceConstant.java @@ -0,0 +1,11 @@ +package org.zstack.network.hostNetworkInterface; + +import java.util.Arrays; +import java.util.List; + +public interface HostNetworkInterfaceConstant { + String NIC_DRIVER_TYPE_VFIO_PCI = "vfio-pci"; + String NIC_DRIVER_TYPE_UIO_PCI = "uio_pci_generic"; + + List VFIO_DRIVER_TYPES = Arrays.asList(NIC_DRIVER_TYPE_VFIO_PCI, NIC_DRIVER_TYPE_UIO_PCI); +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceInventory.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceInventory.java new file mode 100644 index 00000000000..5ad59b9d668 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceInventory.java @@ -0,0 +1,282 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Create by weiwang at 2019-04-25 + */ +@PythonClassInventory +@Inventory(mappingVOClass = HostNetworkInterfaceVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "bonding", inventoryClass = HostNetworkBondingInventory.class, + foreignKey = "bondingUuid", expandedInventoryKey = "uuid"), +}) +public class HostNetworkInterfaceInventory implements Serializable { + private String uuid; + private String hostUuid; + private String bondingUuid; + private String interfaceModel; + private String vendorId; + private String deviceId; + private String subvendorId; + private String subdeviceId; + private String interfaceName; + private String interfaceType; + private Long speed; + private Boolean slaveActive; + private Boolean carrierActive; + private List ipAddresses; + private String gateway; + private String mac; + private String callBackIp; + private String pciDeviceAddress; + private String driverType; + private String offloadStatus; + private String virtStatus; + private String description; + private Timestamp createDate; + private Timestamp lastOpDate; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getBondingUuid() { + return bondingUuid; + } + + public void setBondingUuid(String bondingUuid) { + this.bondingUuid = bondingUuid; + } + + public String getInterfaceModel() { + return interfaceModel; + } + + public void setInterfaceModel(String interfaceModel) { + this.interfaceModel = interfaceModel; + } + + public String getVendorId() { + return vendorId; + } + + public void setVendorId(String vendorId) { + this.vendorId = vendorId; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getSubvendorId() { + return subvendorId; + } + + public void setSubvendorId(String subvendorId) { + this.subvendorId = subvendorId; + } + + public String getSubdeviceId() { + return subdeviceId; + } + + public void setSubdeviceId(String subdeviceId) { + this.subdeviceId = subdeviceId; + } + + public String getInterfaceName() { + return interfaceName; + } + + public void setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + } + + public String getInterfaceType() { + return interfaceType; + } + + public void setInterfaceType(String interfaceType) { + this.interfaceType = interfaceType; + } + + public Long getSpeed() { + return speed; + } + + public void setSpeed(Long speed) { + this.speed = speed; + } + + public Boolean getSlaveActive() { + return slaveActive; + } + + public void setSlaveActive(Boolean slaveActive) { + this.slaveActive = slaveActive; + } + + public Boolean getCarrierActive() { + return carrierActive; + } + + public void setCarrierActive(Boolean carrierActive) { + this.carrierActive = carrierActive; + } + + public List getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(List ipAddresses) { + this.ipAddresses = ipAddresses; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getCallBackIp() { + return callBackIp; + } + + public void setCallBackIp(String callBackIp) { + this.callBackIp = callBackIp; + } + + public String getPciDeviceAddress() { + return pciDeviceAddress; + } + + public void setPciDeviceAddress(String pciDeviceAddress) { + this.pciDeviceAddress = pciDeviceAddress; + } + + public String getOffloadStatus() { + return offloadStatus; + } + + public void setOffloadStatus(String offloadStatus) { + this.offloadStatus = offloadStatus; + } + + public String getVirtStatus() { + return virtStatus; + } + + public void setVirtStatus(String virtStatus) { + this.virtStatus = virtStatus; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public HostNetworkInterfaceInventory() { + + } + + public HostNetworkInterfaceInventory(HostNetworkInterfaceVO vo) { + this.uuid = vo.getUuid(); + this.hostUuid = vo.getHostUuid(); + this.bondingUuid = vo.getBondingUuid(); + this.interfaceModel = vo.getInterfaceModel(); + this.vendorId = vo.getVendorId(); + this.deviceId = vo.getDeviceId(); + this.subvendorId = vo.getSubvendorId(); + this.subdeviceId = vo.getSubdeviceId(); + this.interfaceName = vo.getInterfaceName(); + this.interfaceType = vo.getInterfaceType(); + this.mac = vo.getMac(); + this.pciDeviceAddress = vo.getPciDeviceAddress(); + this.driverType = vo.getDriverType(); + if (vo.getIpAddresses() != null) { + this.ipAddresses = Arrays.asList(vo.getIpAddresses().split(",")); + } + this.gateway = vo.getGateway(); + this.speed = vo.getSpeed(); + this.callBackIp = vo.getCallBackIp(); + this.slaveActive = vo.isSlaveActive(); + this.carrierActive = vo.isCarrierActive(); + this.offloadStatus = vo.getOffloadStatus(); + this.virtStatus = vo.getVirtStatus(); + this.description = vo.getDescription(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + } + + public static HostNetworkInterfaceInventory valueOf(HostNetworkInterfaceVO vo) { + return new HostNetworkInterfaceInventory(vo); + } + + public static List valueOf(Collection vos) { + return vos.stream().map(HostNetworkInterfaceInventory::valueOf).collect(Collectors.toList()); + } + + public String getDriverType() { + return driverType; + } + + public void setDriverType(String driverType) { + this.driverType = driverType; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceInventoryDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..5286ef2a408 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceInventoryDoc_zh_cn.groovy @@ -0,0 +1,139 @@ +package org.zstack.network.hostNetworkInterface + +doc { + + title "物理网卡设备清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "3.5.0" + } + field { + name "hostUuid" + desc "物理机UUID" + type "String" + since "3.5.0" + } + field { + name "bondingUuid" + desc "Bond UUID" + type "String" + since "3.5.0" + } + field { + name "interfaceModel" + desc "网卡型号" + type "String" + since "4.7.11" + } + field { + name "vendorId" + desc "产商Id" + type "String" + since "4.7.11" + } + field { + name "deviceId" + desc "设备Id" + type "String" + since "4.7.11" + } + field { + name "subvendorId" + desc "子产商Id" + type "String" + since "4.7.11" + } + field { + name "subdeviceId" + desc "子设备Id" + type "String" + since "4.7.11" + } + field { + name "interfaceName" + desc "网卡名称" + type "String" + since "3.5.0" + } + field { + name "interfaceType" + desc "网卡应用状态,有nomaster、bridgeSlave、bondSlave" + type "String" + since "3.5.0" + } + field { + name "speed" + desc "网卡速率" + type "Long" + since "3.5.0" + } + field { + name "slaveActive" + desc "Bond链路状态" + type "Boolean" + since "3.5.0" + } + field { + name "carrierActive" + desc "物理链路状态" + type "Boolean" + since "3.5.0" + } + field { + name "ipAddresses" + desc "IP地址" + type "List" + since "3.5.0" + } + field { + name "gateway" + desc "网关地址" + type "String" + since "4.7.0" + } + field { + name "mac" + desc "MAC地址" + type "String" + since "3.5.0" + } + field { + name "callBackIp" + desc "回调地址" + type "String" + since "4.7.0" + } + field { + name "pciDeviceAddress" + desc "网卡PCI地址" + type "String" + since "3.5.0" + } + field { + name "offloadStatus" + desc "" + type "String" + since "4.7.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "4.7.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "3.5.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "3.5.0" + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceUpdateExtensionPoint.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceUpdateExtensionPoint.java new file mode 100644 index 00000000000..fcf55b0a0e6 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceUpdateExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.network.hostNetworkInterface; + +import java.util.List; + +public interface HostNetworkInterfaceUpdateExtensionPoint { + public void afterCreated(String hostUuid, List interfaceVOS, List bondingVOS); +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceVO.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceVO.java new file mode 100644 index 00000000000..18a4c1e3269 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceVO.java @@ -0,0 +1,296 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.host.HostEO; +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; +import org.zstack.header.vo.*; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * Created by GuoYi on 4/23/20. + */ +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = HostEO.class, joinColumn = "hostUuid") +}) +public class HostNetworkInterfaceVO extends ResourceVO implements ToInventory, OwnedByAccount { + @Index + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String hostUuid; + + @Index + @Column + @ForeignKey(parentEntityClass = HostNetworkBondingVO.class, onDeleteAction = ForeignKey.ReferenceOption.SET_NULL) + private String bondingUuid; + + @Column + private String interfaceModel; + + @Column + private String vendorId; + + @Column + private String deviceId; + + @Column + private String subvendorId; + + @Column + private String subdeviceId; + + @Column + private String interfaceName; + + @Column + private String interfaceType; + + @Column + private Long speed; + + @Column + private boolean slaveActive; + + @Column + private boolean carrierActive; + + @Column + private String ipAddresses; + + @Column + private String gateway; + + @Column + private String mac; + + @Column + private String callBackIp; + + @Column + private String pciDeviceAddress; + + @Column + private String driverType; + + @Column + private String offloadStatus; + + @Column + private String virtStatus; + + @Column + private String description; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @Transient + private String accountUuid; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getBondingUuid() { + return bondingUuid; + } + + public void setBondingUuid(String bondingUuid) { + this.bondingUuid = bondingUuid; + } + + public String getInterfaceModel() { + return interfaceModel; + } + + public void setInterfaceModel(String interfaceModel) { + this.interfaceModel = interfaceModel; + } + + public String getVendorId() { + return vendorId; + } + + public void setVendorId(String vendorId) { + this.vendorId = vendorId; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getSubvendorId() { + return subvendorId; + } + + public void setSubvendorId(String subvendorId) { + this.subvendorId = subvendorId; + } + + public String getSubdeviceId() { + return subdeviceId; + } + + public void setSubdeviceId(String subdeviceId) { + this.subdeviceId = subdeviceId; + } + + public String getInterfaceName() { + return interfaceName; + } + + public void setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + } + + public String getInterfaceType() { + return interfaceType; + } + + public void setInterfaceType(String interfaceType) { + this.interfaceType = interfaceType; + } + + public Long getSpeed() { + return speed; + } + + public void setSpeed(Long speed) { + this.speed = speed; + } + + public boolean isSlaveActive() { + return slaveActive; + } + + public void setSlaveActive(boolean slaveActive) { + this.slaveActive = slaveActive; + } + + public boolean isCarrierActive() { + return carrierActive; + } + + public void setCarrierActive(boolean carrierActive) { + this.carrierActive = carrierActive; + } + + public String getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(String ipAddresses) { + this.ipAddresses = ipAddresses; + } + + public String getGateway() { + return gateway; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getCallBackIp() { + return callBackIp; + } + + public void setCallBackIp(String callBackIp) { + this.callBackIp = callBackIp; + } + + public String getPciDeviceAddress() { + return pciDeviceAddress; + } + + public void setPciDeviceAddress(String pciDeviceAddress) { + this.pciDeviceAddress = pciDeviceAddress; + } + + public String getOffloadStatus() { + return offloadStatus; + } + + public void setOffloadStatus(String offloadStatus) { + this.offloadStatus = offloadStatus; + } + + public String getVirtStatus() { + return virtStatus; + } + + public void setVirtStatus(String virtStatus) { + this.virtStatus = virtStatus; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getDriverType() { + return driverType; + } + + public void setDriverType(String driverType) { + this.driverType = driverType; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceVO_.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceVO_.java new file mode 100644 index 00000000000..d9980b06cdb --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/HostNetworkInterfaceVO_.java @@ -0,0 +1,37 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by GuoYi on 4/24/20. + */ +@StaticMetamodel(HostNetworkInterfaceVO.class) +public class HostNetworkInterfaceVO_ extends ResourceVO_ { + public static volatile SingularAttribute hostUuid; + public static volatile SingularAttribute bondingUuid; + public static volatile SingularAttribute interfaceModel; + public static volatile SingularAttribute vendorId; + public static volatile SingularAttribute deviceId; + public static volatile SingularAttribute subvendorId; + public static volatile SingularAttribute subdeviceId; + public static volatile SingularAttribute interfaceName; + public static volatile SingularAttribute interfaceType; + public static volatile SingularAttribute mac; + public static volatile SingularAttribute ipAddresses; + public static volatile SingularAttribute gateway; + public static volatile SingularAttribute callBackIp; + public static volatile SingularAttribute pciDeviceAddress; + public static volatile SingularAttribute driverType; + public static volatile SingularAttribute offloadStatus; + public static volatile SingularAttribute virtStatus; + public static volatile SingularAttribute speed; + public static volatile SingularAttribute slaveActive; + public static volatile SingularAttribute carrierActive; + public static volatile SingularAttribute description; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PackageInfo.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PackageInfo.java new file mode 100644 index 00000000000..04fe8bc246a --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PackageInfo.java @@ -0,0 +1,10 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.PackageAPIInfo; + +@PackageAPIInfo( + APICategoryName = "物理机网络", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) +public class PackageInfo { +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchInventory.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchInventory.java new file mode 100644 index 00000000000..47b4bff1fc7 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchInventory.java @@ -0,0 +1,143 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; +import org.zstack.header.vm.VmNicInventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Physical Switch Inventory + */ +@Inventory(mappingVOClass = PhysicalSwitchVO.class) +@PythonClassInventory +public class PhysicalSwitchInventory implements Serializable { + + private String uuid; + private String name; + private String description; + private String ip; + private String mac; + private String mode; + private String softwareVersion; + private String sdnControllerUuid; + private Timestamp createDate; + private Timestamp lastOpDate; + private List ports; + + public static PhysicalSwitchInventory valueOf(PhysicalSwitchVO vo) { + PhysicalSwitchInventory inv = new PhysicalSwitchInventory(); + inv.setUuid(vo.getUuid()); + inv.setName(vo.getName()); + inv.setDescription(vo.getDescription()); + inv.setIp(vo.getIp()); + inv.setMac(vo.getMac()); + inv.setMode(vo.getMode()); + inv.setSoftwareVersion(vo.getSoftwareVersion()); + inv.setSdnControllerUuid(vo.getSdnControllerUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + inv.setPorts(PhysicalSwitchPortInventory.valueOf(vo.getPorts())); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (PhysicalSwitchVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public String getSoftwareVersion() { + return softwareVersion; + } + + public void setSoftwareVersion(String softwareVersion) { + this.softwareVersion = softwareVersion; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public List getPorts() { + return ports; + } + + public void setPorts(List ports) { + this.ports = ports; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchInventoryDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..86520347a16 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchInventoryDoc_zh_cn.groovy @@ -0,0 +1,78 @@ +package org.zstack.network.hostNetworkInterface + +import java.sql.Timestamp +import org.zstack.network.hostNetworkInterface.PhysicalSwitchPortInventory + +doc { + + title "物理交换机清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.3.28" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.3.28" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.3.28" + } + field { + name "ip" + desc "物理交换机管理IP地址" + type "String" + since "5.3.28" + } + field { + name "mac" + desc "物理交换机MAC地址" + type "String" + since "5.3.28" + } + field { + name "mode" + desc "物理交换机工作模式(Switch,Router)" + type "String" + since "5.3.28" + } + field { + name "softwareVersion" + desc "物理交换机软件版本" + type "String" + since "5.3.28" + } + field { + name "sdnControllerUuid" + desc "SDN控制器uuid" + type "String" + since "5.3.28" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.3.28" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.3.28" + } + ref { + name "ports" + path "org.zstack.network.hostNetworkInterface.PhysicalSwitchInventory.ports" + desc "null" + type "List" + since "5.3.28" + clz PhysicalSwitchPortInventory.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortInventory.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortInventory.java new file mode 100644 index 00000000000..917b18ae891 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortInventory.java @@ -0,0 +1,135 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Physical Switch Port Inventory + */ +@Inventory(mappingVOClass = PhysicalSwitchPortVO.class) +@PythonClassInventory +public class PhysicalSwitchPortInventory implements Serializable { + + private String uuid; + private String name; + private String description; + private String ethTrunkName; + private String portType; + private String peerInterfaceUuid; + private String switchUuid; + private String sdnControllerUuid; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static PhysicalSwitchPortInventory valueOf(PhysicalSwitchPortVO vo) { + if (vo == null) { + return null; + } + PhysicalSwitchPortInventory inv = new PhysicalSwitchPortInventory(); + inv.setUuid(vo.getUuid()); + inv.setName(vo.getName()); + inv.setDescription(vo.getDescription()); + inv.setEthTrunkName(vo.getEthTrunkName()); + inv.setPortType(vo.getPortType()); + inv.setPeerInterfaceUuid(vo.getPeerInterfaceUuid()); + inv.setSwitchUuid(vo.getSwitchUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + inv.setSdnControllerUuid(vo.getSdnControllerUuid()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (PhysicalSwitchPortVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getEthTrunkName() { + return ethTrunkName; + } + + public void setEthTrunkName(String ethTrunkName) { + this.ethTrunkName = ethTrunkName; + } + + public String getPortType() { + return portType; + } + + public void setPortType(String portType) { + this.portType = portType; + } + + public String getPeerInterfaceUuid() { + return peerInterfaceUuid; + } + + public void setPeerInterfaceUuid(String peerInterfaceUuid) { + this.peerInterfaceUuid = peerInterfaceUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getSwitchUuid() { + return switchUuid; + } + + public void setSwitchUuid(String switchUuid) { + this.switchUuid = switchUuid; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortInventoryDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..8da98357885 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortInventoryDoc_zh_cn.groovy @@ -0,0 +1,69 @@ +package org.zstack.network.hostNetworkInterface + +import java.sql.Timestamp + +doc { + + title "物理交换机端口清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.3.28" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.3.28" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.3.28" + } + field { + name "ethTrunkName" + desc "物理交换机端口所属的trunk名称" + type "String" + since "5.3.28" + } + field { + name "portType" + desc "物理交换机端口链路类型" + type "String" + since "5.3.28" + } + field { + name "peerInterfaceUuid" + desc "物理交换机端口连接服务器接口uuid" + type "String" + since "5.3.28" + } + field { + name "switchUuid" + desc "物理交换机端口所属交换机uuid" + type "String" + since "5.3.28" + } + field { + name "sdnControllerUuid" + desc "SDN控制器uuid" + type "String" + since "5.3.28" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.3.28" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.3.28" + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortVO.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortVO.java new file mode 100644 index 00000000000..9480d946f2b --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortVO.java @@ -0,0 +1,150 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * Physical Switch Port Value Object + */ +@Entity +@Table(name = "PhysicalSwitchPortVO") +@AutoDeleteTag +public class PhysicalSwitchPortVO extends ResourceVO implements ToInventory, OwnedByAccount { + + @Column + private String name; + + @Column + private String description; + + @Column + private String ethTrunkName; + + @Column + private String portType; + + @Column + @ForeignKey(parentEntityClass = PhysicalSwitchVO.class, parentKey = "uuid", onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String switchUuid; + + @Column + @ForeignKey(parentEntityClass = HostNetworkInterfaceVO.class, parentKey = "uuid") + private String peerInterfaceUuid; + + @Column + private String sdnControllerUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @Transient + private String accountUuid; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getEthTrunkName() { + return ethTrunkName; + } + + public void setEthTrunkName(String ethTrunkName) { + this.ethTrunkName = ethTrunkName; + } + + public String getPortType() { + return portType; + } + + public void setPortType(String portType) { + this.portType = portType; + } + + public String getPeerInterfaceUuid() { + return peerInterfaceUuid; + } + + public void setPeerInterfaceUuid(String peerInterfaceUuid) { + this.peerInterfaceUuid = peerInterfaceUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getSwitchUuid() { + return switchUuid; + } + + public void setSwitchUuid(String switchUuid) { + this.switchUuid = switchUuid; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public void copyFromAnother(PhysicalSwitchPortVO vo) { + this.name = vo.name; + this.description = vo.description; + this.ethTrunkName = vo.ethTrunkName; + this.portType = vo.portType; + this.switchUuid = vo.switchUuid; + this.sdnControllerUuid = vo.sdnControllerUuid; + if (vo.getPeerInterfaceUuid() != null) { + this.peerInterfaceUuid = vo.getPeerInterfaceUuid(); + } + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortVO_.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortVO_.java new file mode 100644 index 00000000000..76d963b73e4 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchPortVO_.java @@ -0,0 +1,23 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Physical Switch Port VO Metamodel + */ +@StaticMetamodel(PhysicalSwitchPortVO.class) +public class PhysicalSwitchPortVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute description; + public static volatile SingularAttribute ethTrunkName; + public static volatile SingularAttribute portType; + public static volatile SingularAttribute peerInterfaceUuid; + public static volatile SingularAttribute switchUuid; + public static volatile SingularAttribute sdnControllerUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchVO.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchVO.java new file mode 100644 index 00000000000..8c8cb7bbce8 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchVO.java @@ -0,0 +1,162 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vo.NoView; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.Set; + +/** + * Physical Switch Value Object + */ +@Entity +@Table +@AutoDeleteTag +public class PhysicalSwitchVO extends ResourceVO implements ToInventory, OwnedByAccount { + + @Column + private String name; + + @Column + private String description; + + @Column + private String ip; + + @Column + private String mac; + + @Column + private String mode; + + @Column + private String softwareVersion; + + @Column + private String sdnControllerUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @Transient + private String accountUuid; + + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "switchUuid", insertable = false, updatable = false) + @NoView + private Set ports = new HashSet(); + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public String getSoftwareVersion() { + return softwareVersion; + } + + public void setSoftwareVersion(String softwareVersion) { + this.softwareVersion = softwareVersion; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public Set getPorts() { + return ports; + } + + public void setPorts(Set ports) { + this.ports = ports; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public void copyFromAnother(PhysicalSwitchVO vo) { + this.name = vo.name; + this.description = vo.description; + this.ip = vo.ip; + this.mac = vo.mac; + this.mode = vo.mode; + this.softwareVersion = vo.softwareVersion; + this.sdnControllerUuid = vo.sdnControllerUuid; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchVO_.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchVO_.java new file mode 100644 index 00000000000..ac2f1c68b4d --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/PhysicalSwitchVO_.java @@ -0,0 +1,23 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Physical Switch VO Metamodel + */ +@StaticMetamodel(PhysicalSwitchVO.class) +public class PhysicalSwitchVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute description; + public static volatile SingularAttribute ip; + public static volatile SingularAttribute mac; + public static volatile SingularAttribute mode; + public static volatile SingularAttribute softwareVersion; + public static volatile SingularAttribute sdnControllerUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/RBACInfo.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/RBACInfo.java new file mode 100644 index 00000000000..fd189fcb4d0 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/RBACInfo.java @@ -0,0 +1,32 @@ +package org.zstack.network.hostNetworkInterface; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .name("hostNetwork") + .adminOnlyAPIs("org.zstack.network.hostNetworkInterface.**") + .build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + roleBuilder() + .name("hostNetwork") + .uuid("4266a77e46cb4e68864899458287941e") + .permissionsByName("hostNetwork") + .build(); + } + + @Override + public void globalReadableResources() { + + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpApiInterceptor.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpApiInterceptor.java new file mode 100644 index 00000000000..23e7c487019 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpApiInterceptor.java @@ -0,0 +1,60 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.message.APIMessage; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO_; +import org.zstack.network.hostNetworkInterface.lldp.api.APIChangeHostNetworkInterfaceLldpModeMsg; +import org.zstack.network.hostNetworkInterface.lldp.api.APIGetHostNetworkInterfaceLldpMsg; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpVO; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpVO_; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.logging.CLoggerImpl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.zstack.core.Platform.argerr; + +public class LldpApiInterceptor implements ApiMessageInterceptor { + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + + private static final CLogger logger = CLoggerImpl.getLogger(LldpApiInterceptor.class); + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIChangeHostNetworkInterfaceLldpModeMsg) { + validate((APIChangeHostNetworkInterfaceLldpModeMsg)msg); + } else if (msg instanceof APIGetHostNetworkInterfaceLldpMsg) { + validate((APIGetHostNetworkInterfaceLldpMsg)msg); + } + + return msg; + } + + private void validate(APIChangeHostNetworkInterfaceLldpModeMsg msg) { + List hostUuids = Q.New(HostNetworkInterfaceVO.class).select(HostNetworkInterfaceVO_.hostUuid) + .in(HostNetworkInterfaceVO_.uuid, msg.getInterfaceUuids()) + .listValues(); + Set set = new HashSet<>(hostUuids); + if (set.size() > 1) { + throw new ApiMessageInterceptionException((argerr("could not change lldp mode for the interfaces of different hosts"))); + } + } + + private void validate(APIGetHostNetworkInterfaceLldpMsg msg) { + String mode = Q.New(HostNetworkInterfaceLldpVO.class).select(HostNetworkInterfaceLldpVO_.mode).eq(HostNetworkInterfaceLldpVO_.interfaceUuid, msg.getInterfaceUuid()).findValue(); + if (mode != null && !mode.contains("rx")) { + throw new ApiMessageInterceptionException((argerr("could not get interface lldp info which is not in receive mode"))); + } + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpConfigSyncStruct.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpConfigSyncStruct.java new file mode 100644 index 00000000000..e7b10f7fc01 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpConfigSyncStruct.java @@ -0,0 +1,27 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +public class LldpConfigSyncStruct { + + public static class LldpModeConfig{ + private String physicalInterfaceName; + + private String mode; + + public String getPhysicalInterfaceName() { + return physicalInterfaceName; + } + + public void setPhysicalInterfaceName(String physicalInterfaceName) { + this.physicalInterfaceName = physicalInterfaceName; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + } + +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpConstant.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpConstant.java new file mode 100644 index 00000000000..a3fc99e27a8 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpConstant.java @@ -0,0 +1,20 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +import org.zstack.header.configuration.PythonClass; + +@PythonClass +public interface LldpConstant { + String SERVICE_ID = "hostNetwork.lldp"; + String ACTION_CATEGORY = "hostNetwork.lldp"; + + enum mode { + rx_only, + tx_only, + rx_and_tx, + disable + } + + String CHANGE_LLDP_MODE_PATH = "/network/lldp/changemode"; + String GET_LLDP_INFO_PATH = "/network/lldp/get"; + String APPLY_LLDP_CONFIG_PATH = "/network/lldp/apply"; +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpGlobalConfig.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpGlobalConfig.java new file mode 100644 index 00000000000..0228ae0e20c --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpGlobalConfig.java @@ -0,0 +1,13 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; +import org.zstack.core.config.GlobalConfigDefinition; + +@GlobalConfigDefinition +public class LldpGlobalConfig { + public static final String CATEGORY = "lldp"; + + @GlobalConfigDef(defaultValue = "false", type = Boolean.class, description = "auto pull host network interface lldp neighbour if it's true") + public static GlobalConfig AUTO_GET_LLDP_NEIGHBOUR = new GlobalConfig(CATEGORY, "auto.get.lldp.neighbour"); +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpInfoStruct.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpInfoStruct.java new file mode 100644 index 00000000000..1cbf31bbe9f --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpInfoStruct.java @@ -0,0 +1,104 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +public class LldpInfoStruct { + private String chassisId; + private Integer timeToLive; + private String managementAddress; + private String systemName; + private String systemDescription; + private String systemCapabilities; + private String portId; + private String portDescription; + private Integer vlanId; + private Long aggregationPortId; + private Integer mtu; + + public String getChassisId() { + return chassisId; + } + + public void setChassisId(String chassisId) { + this.chassisId = chassisId; + } + + public Integer getTimeToLive() { + return timeToLive; + } + + public void setTimeToLive(Integer timeToLive) { + this.timeToLive = timeToLive; + } + + public String getManagementAddress() { + return managementAddress; + } + + public void setManagementAddress(String managementAddress) { + this.managementAddress = managementAddress; + } + + public String getSystemName() { + return systemName; + } + + public void setSystemName(String systemName) { + this.systemName = systemName; + } + + public String getSystemDescription() { + return systemDescription; + } + + public void setSystemDescription(String systemDescription) { + this.systemDescription = systemDescription; + } + + public String getSystemCapabilities() { + return systemCapabilities; + } + + public void setSystemCapabilities(String systemCapabilities) { + this.systemCapabilities = systemCapabilities; + } + + public String getPortId() { + return portId; + } + + public void setPortId(String portId) { + this.portId = portId; + } + + public String getPortDescription() { + return portDescription; + } + + public void setPortDescription(String portDescription) { + this.portDescription = portDescription; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public Long getAggregationPortId() { + return aggregationPortId; + } + + public void setAggregationPortId(Long aggregationPortId) { + this.aggregationPortId = aggregationPortId; + } + + public Integer getMtu() { + return mtu; + } + + public void setMtu(Integer mtu) { + this.mtu = mtu; + } + +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpKvmAgentCommands.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpKvmAgentCommands.java new file mode 100644 index 00000000000..8c65ffb3597 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpKvmAgentCommands.java @@ -0,0 +1,106 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.core.validation.ConditionalValidation; + +import java.util.List; + +public class LldpKvmAgentCommands { + + public static class AgentCommand { + } + + public static class AgentResponse implements ConditionalValidation { + private boolean success = true; + private String error; + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + @Override + public boolean needValidation() { + return success; + } + } + + public static class ChangeLldpModeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private List physicalInterfaceNames; + + private String mode; + + public List getPhysicalInterfaceNames() { + return physicalInterfaceNames; + } + + public void setPhysicalInterfaceNames(List physicalInterfaceNames) { + this.physicalInterfaceNames = physicalInterfaceNames; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + } + + public static class ChangeLldpModeResponse extends AgentResponse { + } + + public static class GetLldpInfoCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private String physicalInterfaceName; + + public String getPhysicalInterfaceName() { + return physicalInterfaceName; + } + + public void setPhysicalInterfaceName(String physicalInterfaceName) { + this.physicalInterfaceName = physicalInterfaceName; + } + } + + public static class GetLldpInfoResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") + private LldpInfoStruct lldpInfo; + + public LldpInfoStruct getLldpInfo() { + return lldpInfo; + } + + public void setLldpInfo(LldpInfoStruct lldpInfo) { + this.lldpInfo = lldpInfo; + } + } + + public static class ApplyLldpConfigCmd extends AgentCommand { + public List getLldpConfig() { + return lldpConfig; + } + + public void setLldpConfig(List lldpConfig) { + this.lldpConfig = lldpConfig; + } + + private List lldpConfig; + + } + + public static class ApplyLldpConfigResponse extends AgentResponse { + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpManagerImpl.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpManagerImpl.java new file mode 100644 index 00000000000..420a6ef544a --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/LldpManagerImpl.java @@ -0,0 +1,519 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.EventFacade; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.Platform; +import org.zstack.core.db.SQL; +import org.zstack.header.AbstractService; +import org.zstack.header.core.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.*; +import org.zstack.header.identity.AccountConstant; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; +import org.zstack.kvm.KVMHostAsyncHttpCallMsg; +import org.zstack.kvm.KVMHostAsyncHttpCallReply; +import org.zstack.kvm.KVMHostInventory; +import org.zstack.kvm.KVMPingAgentNoFailureExtensionPoint; +import org.zstack.network.hostNetworkInterface.*; +import org.zstack.network.hostNetworkInterface.lldp.api.*; +import org.zstack.network.hostNetworkInterface.lldp.entity.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.sql.Timestamp; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +public class LldpManagerImpl extends AbstractService implements HostAfterConnectedExtensionPoint, HostDeleteExtensionPoint, + KVMPingAgentNoFailureExtensionPoint { + private static final CLogger logger = Utils.getLogger(LldpManagerImpl.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + private EventFacade evtf; + + private enum LLDPGetNeighbourState { + None, + STARTING, + Done, + } + + private final Map getNeighbourStateMap = new ConcurrentHashMap<>(); + private final Map interfaceLocks = new ConcurrentHashMap<>(); + + private Object getInterfaceLock(String interfaceUuid) { + return interfaceLocks.computeIfAbsent(interfaceUuid, k -> new Object()); + } + + @Override + public int getSyncLevel() { + return super.getSyncLevel(); + } + + @MessageSafe + @Override + public void handleMessage(Message msg) { + if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleLocalMessage(Message msg) { + if (msg instanceof GetHostNetworkInterfaceLldpMsg) { + handle((GetHostNetworkInterfaceLldpMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APIChangeHostNetworkInterfaceLldpModeMsg) { + handle((APIChangeHostNetworkInterfaceLldpModeMsg) msg); + } else if (msg instanceof APIGetHostNetworkInterfaceLldpMsg) { + handle((APIGetHostNetworkInterfaceLldpMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIChangeHostNetworkInterfaceLldpModeMsg msg) { + APIChangeHostNetworkInterfaceLldpModeEvent event = new APIChangeHostNetworkInterfaceLldpModeEvent(msg.getId()); + + final LldpKvmAgentCommands.ChangeLldpModeCmd cmd = new LldpKvmAgentCommands.ChangeLldpModeCmd(); + List interfaceVOS = Q.New(HostNetworkInterfaceVO.class) + .in(HostNetworkInterfaceVO_.uuid, msg.getInterfaceUuids()) + .list(); + List interfaceNames = interfaceVOS.stream().map(HostNetworkInterfaceVO::getInterfaceName).collect(Collectors.toList()); + String hostUuid = interfaceVOS.get(0).getHostUuid(); + cmd.setPhysicalInterfaceNames(interfaceNames); + cmd.setMode(msg.getMode()); + + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setPath(LldpConstant.CHANGE_LLDP_MODE_PATH); + kmsg.setHostUuid(hostUuid); + kmsg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, hostUuid); + bus.send(kmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + event.setSuccess(false); + event.setError(reply.getError()); + bus.publish(event); + return; + } else { + List toCreate = new ArrayList<>(); + List toUpdate = new ArrayList<>(); + + for (HostNetworkInterfaceVO interfaceVO : interfaceVOS) { + HostNetworkInterfaceLldpVO vo = Q.New(HostNetworkInterfaceLldpVO.class).eq(HostNetworkInterfaceLldpVO_.interfaceUuid, interfaceVO.getUuid()).find(); + if (vo == null) { + vo = new HostNetworkInterfaceLldpVO(); + vo.setUuid(Platform.getUuid()); + vo.setInterfaceUuid(interfaceVO.getUuid()); + vo.setMode(msg.getMode()); + vo.setAccountUuid(AccountConstant.INITIAL_SYSTEM_ADMIN_UUID); + toCreate.add(vo); + } else { + vo.setMode(msg.getMode()); + toUpdate.add(vo); + } + } + + if (!toCreate.isEmpty()) { + dbf.persistCollection(toCreate); + } + if (!toUpdate.isEmpty()) { + dbf.updateCollection(toUpdate); + } + List combinedList = new ArrayList<>(toCreate); + combinedList.addAll(toUpdate); + event.setInventories(HostNetworkInterfaceLldpInventory.valueOf(combinedList)); + } + bus.publish(event); + } + }); + } + + private void copyInventoryToVO(HostNetworkInterfaceLldpRefVO vo, LldpInfoStruct inv) { + vo.setChassisId(inv.getChassisId()); + vo.setTimeToLive(inv.getTimeToLive()); + vo.setManagementAddress(inv.getManagementAddress()); + vo.setSystemName(inv.getSystemName()); + vo.setSystemDescription(inv.getSystemDescription()); + vo.setSystemCapabilities(inv.getSystemCapabilities()); + vo.setPortId(inv.getPortId()); + vo.setPortDescription(inv.getPortDescription()); + vo.setVlanId(inv.getVlanId()); + vo.setAggregationPortId(inv.getAggregationPortId()); + vo.setMtu(inv.getMtu()); + } + + private synchronized void syncHostNetworkInterfaceLldpInDb(String interfaceUuid, LldpInfoStruct lldpInfo) { + if (lldpInfo == null) { + return; + } + + Object interfaceLock = getInterfaceLock(interfaceUuid); + synchronized (interfaceLock) { + HostNetworkInterfaceLldpVO vo = Q.New(HostNetworkInterfaceLldpVO.class).eq(HostNetworkInterfaceLldpVO_.interfaceUuid, interfaceUuid).find(); + HostNetworkInterfaceLldpRefVO refVO = Q.New(HostNetworkInterfaceLldpRefVO.class).eq(HostNetworkInterfaceLldpRefVO_.lldpUuid, vo.getUuid()).find(); + if (refVO == null) { + refVO = new HostNetworkInterfaceLldpRefVO(); + refVO.setLldpUuid(vo.getUuid()); + copyInventoryToVO(refVO, lldpInfo); + dbf.persistAndRefresh(refVO); + } else { + copyInventoryToVO(refVO, lldpInfo); + // explicitly update the data to indicate the last refresh time + refVO.setLastOpDate(new Timestamp(System.currentTimeMillis())); + dbf.updateAndRefresh(refVO); + } + + /* link host network interface to physical interface based on: + HostNetworkInterfaceLldpRefVO.systemName == PhysicalSwitchVO.name + && HostNetworkInterfaceLldpRefVO.portId == PhysicalSwitchPortVO.name + > select lldpUuid,chassisId,systemName,portId,aggregationPortId from HostNetworkInterfaceLldpRefVO; +----------------------------------+-------------------+------------+------------+-------------------+ +| lldpUuid | chassisId | systemName | portId | aggregationPortId | ++----------------------------------+-------------------+------------+------------+-------------------+ +| 0a89ae9894274b608b3e5cd29b20e216 | c0:e3:fb:65:ab:d1 | huawei_152 | 10GE1/0/13 | NULL | +| d3905992b4c043099c86785b0ee3186d | c0:e3:fb:65:ab:d1 | huawei_152 | 10GE1/0/11 | 1 | ++----------------------------------+-------------------+------------+------------+-------------------+ + select uuid,name,mac from PhysicalSwitchVO; ++----------------------------------+------------+-------------------+ +| uuid | name | mac | ++----------------------------------+------------+-------------------+ +| b9d708c427c630b1b9fffe2d989c3a48 | huawei_152 | C0:E3:FB:65:AB:D1 | ++----------------------------------+------------+-------------------+ +1 row in set (0.000 sec) +select name,ethTrunkName,switchUuid from PhysicalSwitchPortVO limit 1; ++------------+--------------+----------------------------------+ +| name | ethTrunkName | switchUuid | ++------------+--------------+----------------------------------+ +| 10GE1/0/30 | NULL | b9d708c427c630b1b9fffe2d989c3a48 | ++------------+--------------+----------------------------------+ + */ + PhysicalSwitchVO switchVO = Q.New(PhysicalSwitchVO.class) + .eq(PhysicalSwitchVO_.name, refVO.getSystemName()).limit(1).find(); + if (switchVO != null) { + PhysicalSwitchPortVO oldPhysicalSwitchPortVO = Q.New(PhysicalSwitchPortVO.class) + .eq(PhysicalSwitchPortVO_.peerInterfaceUuid, interfaceUuid).find(); + PhysicalSwitchPortVO physicalSwitchPortVO = Q.New(PhysicalSwitchPortVO.class) + .eq(PhysicalSwitchPortVO_.switchUuid, switchVO.getUuid()) + .eq(PhysicalSwitchPortVO_.name, refVO.getPortId()).limit(1).find(); + if (physicalSwitchPortVO != null) { + logger.debug(String.format("link host network interface[uuid:%s] to physical switch port[uuid:%s,name:%s]", + interfaceUuid, physicalSwitchPortVO.getUuid(), physicalSwitchPortVO.getName())); + if (physicalSwitchPortVO.getPeerInterfaceUuid() != null && physicalSwitchPortVO.getPeerInterfaceUuid().equals(interfaceUuid)) { + logger.debug(String.format("physical switch port[uuid:%s,name:%s] is already linked to host network interface[uuid:%s], skip", + physicalSwitchPortVO.getUuid(), physicalSwitchPortVO.getName(), physicalSwitchPortVO.getPeerInterfaceUuid())); + return; + } + physicalSwitchPortVO.setPeerInterfaceUuid(interfaceUuid); + dbf.update(physicalSwitchPortVO); + + if (oldPhysicalSwitchPortVO != null) { + oldPhysicalSwitchPortVO.setPeerInterfaceUuid(null); + dbf.update(oldPhysicalSwitchPortVO); + } + + HostNetworkInterfaceCanonicalEvents.PeerPortChangedData data = new HostNetworkInterfaceCanonicalEvents.PeerPortChangedData(); + data.setInterfaceUuid(interfaceUuid); + data.setOldPhysicalSwitchPort(PhysicalSwitchPortInventory.valueOf(oldPhysicalSwitchPortVO)); + data.setNewPhysiaclSwitchPort(PhysicalSwitchPortInventory.valueOf(physicalSwitchPortVO)); + evtf.fire(HostNetworkInterfaceCanonicalEvents.PEER_PORT_CHANGED, data); + } + } + } + } + + void doGetHostNetworkInterfaceLLdpInfo(String interfaceUuid, ReturnValueCompletion completion) { + HostNetworkInterfaceVO interfaceVO = dbf.findByUuid(interfaceUuid, HostNetworkInterfaceVO.class); + final LldpKvmAgentCommands.GetLldpInfoCmd cmd = new LldpKvmAgentCommands.GetLldpInfoCmd(); + cmd.setPhysicalInterfaceName(interfaceVO.getInterfaceName()); + + getNeighbourStateMap.put(interfaceUuid, LLDPGetNeighbourState.STARTING); + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setPath(LldpConstant.GET_LLDP_INFO_PATH); + kmsg.setHostUuid(interfaceVO.getHostUuid()); + kmsg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, interfaceVO.getHostUuid()); + bus.send(kmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + getNeighbourStateMap.put(interfaceUuid, LLDPGetNeighbourState.Done); + return; + } else { + KVMHostAsyncHttpCallReply r = reply.castReply(); + LldpKvmAgentCommands.GetLldpInfoResponse rsp = r.toResponse(LldpKvmAgentCommands.GetLldpInfoResponse.class); + getNeighbourStateMap.put(interfaceUuid, LLDPGetNeighbourState.Done); + if (!rsp.isSuccess()) { + completion.fail(operr("operation error, because %s", rsp.getError())); + } else { + HostNetworkInterfaceLldpVO vo = Q.New(HostNetworkInterfaceLldpVO.class) + .eq(HostNetworkInterfaceLldpVO_.interfaceUuid, interfaceUuid).find(); + syncHostNetworkInterfaceLldpInDb(interfaceUuid, rsp.getLldpInfo()); + HostNetworkInterfaceLldpRefVO lldpRefVO = Q.New(HostNetworkInterfaceLldpRefVO.class) + .eq(HostNetworkInterfaceLldpRefVO_.lldpUuid, vo.getUuid()) + .find(); + if (lldpRefVO != null) { + completion.success(HostNetworkInterfaceLldpRefInventory.valueOf(lldpRefVO)); + } else { + completion.fail(operr("get lldp ref for[%s] failed", interfaceUuid)); + } + } + } + } + }); + } + + private void handle(GetHostNetworkInterfaceLldpMsg msg) { + GetHostNetworkInterfaceLldpReply reply = new GetHostNetworkInterfaceLldpReply(); + doGetHostNetworkInterfaceLLdpInfo(msg.getInterfaceUuid(), new ReturnValueCompletion(msg) { + @Override + public void success(HostNetworkInterfaceLldpRefInventory returnValue) { + reply.setLldp(returnValue); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(APIGetHostNetworkInterfaceLldpMsg msg) { + APIGetHostNetworkInterfaceLldpReply greply = new APIGetHostNetworkInterfaceLldpReply(); + + doGetHostNetworkInterfaceLLdpInfo(msg.getInterfaceUuid(), new ReturnValueCompletion(msg) { + @Override + public void success(HostNetworkInterfaceLldpRefInventory returnValue) { + greply.setLldp(returnValue); + bus.reply(msg, greply); + } + + @Override + public void fail(ErrorCode errorCode) { + greply.setError(errorCode); + bus.reply(msg, greply); + } + }); + } + + private void applyHostNetworkLldpConfig(List lldpVOS, String hostUuid, Completion completion) { + LldpKvmAgentCommands.ApplyLldpConfigCmd cmd = new LldpKvmAgentCommands.ApplyLldpConfigCmd(); + List configs = new ArrayList<>(); + for (HostNetworkInterfaceLldpVO lldpVO : lldpVOS) { + LldpConfigSyncStruct.LldpModeConfig config = new LldpConfigSyncStruct.LldpModeConfig(); + HostNetworkInterfaceVO interfaceVO = dbf.findByUuid(lldpVO.getInterfaceUuid(), HostNetworkInterfaceVO.class); + config.setPhysicalInterfaceName(interfaceVO.getInterfaceName()); + config.setMode(lldpVO.getMode()); + configs.add(config); + } + cmd.setLldpConfig(configs); + + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setPath(LldpConstant.APPLY_LLDP_CONFIG_PATH); + kmsg.setHostUuid(hostUuid); + kmsg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, hostUuid); + bus.send(kmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + completion.success(); + } else { + completion.fail(reply.getError()); + } + } + }); + } + + @Override + public void afterHostConnected(HostInventory host) { + List interfaceUuids = Q.New(HostNetworkInterfaceLldpVO.class) + .select(HostNetworkInterfaceLldpVO_.interfaceUuid) + .listValues(); + List interfaceUuidsOnHost = Q.New(HostNetworkInterfaceVO.class) + .select(HostNetworkInterfaceVO_.uuid) + .eq(HostNetworkInterfaceVO_.hostUuid, host.getUuid()) + .listValues(); + + if (interfaceUuids != null && !interfaceUuids.isEmpty()) { + interfaceUuids = Q.New(HostNetworkInterfaceVO.class) + .select(HostNetworkInterfaceVO_.uuid) + .eq(HostNetworkInterfaceVO_.hostUuid, host.getUuid()) + .notIn(HostNetworkInterfaceVO_.uuid, interfaceUuids) + .listValues(); + } else { + interfaceUuids = interfaceUuidsOnHost; + } + + List lldpVOS = new ArrayList<>(); + for (String interfaceUuid : interfaceUuids) { + HostNetworkInterfaceLldpVO vo = new HostNetworkInterfaceLldpVO(); + vo.setUuid(Platform.getUuid()); + vo.setInterfaceUuid(interfaceUuid); + vo.setMode(LldpConstant.mode.rx_only.toString()); + vo.setAccountUuid(AccountConstant.INITIAL_SYSTEM_ADMIN_UUID); + lldpVOS.add(vo); + } + dbf.persistCollection(lldpVOS); + + if (interfaceUuidsOnHost.isEmpty()) { + return; + } + + lldpVOS = Q.New(HostNetworkInterfaceLldpVO.class) + .in(HostNetworkInterfaceLldpVO_.interfaceUuid, interfaceUuidsOnHost) + .list(); + if (lldpVOS.isEmpty()) { + return; + } + + applyHostNetworkLldpConfig(lldpVOS, host.getUuid(), new Completion(null) { + @Override + public void success() { + logger.debug("apply the lldp configuration after host reconnected successfully"); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.debug(String.format("fail to apply the lldp configuration after host reconnected:%s", errorCode.toString())); + } + }); + } + + @Override + public void preDeleteHost(HostInventory inventory) throws HostException { + + } + + @Override + public void beforeDeleteHost(HostInventory inventory) { + List interfaceUuidsOnHost = Q.New(HostNetworkInterfaceVO.class) + .select(HostNetworkInterfaceVO_.uuid) + .eq(HostNetworkInterfaceVO_.hostUuid, inventory.getUuid()) + .listValues(); + if (interfaceUuidsOnHost == null || interfaceUuidsOnHost.isEmpty()) { + return; + } + List lldpUuidsOnHost = Q.New(HostNetworkInterfaceLldpVO.class) + .select(HostNetworkInterfaceLldpVO_.uuid) + .in(HostNetworkInterfaceLldpVO_.interfaceUuid, interfaceUuidsOnHost) + .listValues(); + SQL.New(HostNetworkInterfaceLldpVO.class) + .in(HostNetworkInterfaceLldpVO_.uuid, lldpUuidsOnHost) + .hardDelete(); + } + + @Override + public void afterDeleteHost(HostInventory inventory) { + + } + + @Override + public void kvmPingAgentNoFailure(KVMHostInventory host, NoErrorCompletion completion) { + boolean autoGetLldpNeighbor = LldpGlobalConfig.AUTO_GET_LLDP_NEIGHBOUR.value(Boolean.class); + if (!autoGetLldpNeighbor) { + completion.done(); + return; + } + + List interfaceUuids = Q.New(HostNetworkInterfaceVO.class) + .select(HostNetworkInterfaceVO_.uuid) + .eq(HostNetworkInterfaceVO_.hostUuid, host.getUuid()) + .listValues(); + if (interfaceUuids.isEmpty()) { + completion.done(); + return; + } + + List lldpVOS = Q.New(HostNetworkInterfaceLldpVO.class) + .in(HostNetworkInterfaceLldpVO_.interfaceUuid, interfaceUuids) + .list(); + List toUpdate = new ArrayList<>(); + for (HostNetworkInterfaceLldpVO lldpVO : lldpVOS) { + if (LldpConstant.mode.disable.toString().equals(lldpVO.getMode())) { + continue; + } + + if (lldpVO.getNeighborDevice() != null) { + continue; + } + + toUpdate.add(lldpVO); + } + + if (toUpdate.isEmpty()) { + completion.done(); + return; + } + + completion.done(); + + NopeCompletion nope = new NopeCompletion(); + new While<>(toUpdate).each((lldpVO, wcomp) -> { + LLDPGetNeighbourState state = getNeighbourStateMap.get(lldpVO.getInterfaceUuid()); + if (state == LLDPGetNeighbourState.STARTING) { + wcomp.done(); + return; + } + + doGetHostNetworkInterfaceLLdpInfo(lldpVO.getInterfaceUuid(), new ReturnValueCompletion(wcomp) { + @Override + public void success(HostNetworkInterfaceLldpRefInventory returnValue) { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.debug("get lldp info failed, ignore it"); + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(nope) { + @Override + public void done(ErrorCodeList errorCodeList) { + nope.success(); + } + }); + } + + @Override + public String getId() { + return bus.makeLocalServiceId(LldpConstant.SERVICE_ID); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/PackageInfo.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/PackageInfo.java new file mode 100644 index 00000000000..bce1a92ae9e --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/PackageInfo.java @@ -0,0 +1,10 @@ +package org.zstack.network.hostNetworkInterface.lldp; + +import org.zstack.header.PackageAPIInfo; + +@PackageAPIInfo( + APICategoryName = "lldp", + permissions = {PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE, PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE} +) +public class PackageInfo { +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeEvent.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeEvent.java new file mode 100644 index 00000000000..a229398acac --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeEvent.java @@ -0,0 +1,38 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpInventory; +import org.zstack.utils.CollectionDSL; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIChangeHostNetworkInterfaceLldpModeEvent extends APIEvent { + private List inventories; + + public APIChangeHostNetworkInterfaceLldpModeEvent() { } + + public APIChangeHostNetworkInterfaceLldpModeEvent(String apiId) { + super(apiId); + } + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIChangeHostNetworkInterfaceLldpModeEvent __example__() { + APIChangeHostNetworkInterfaceLldpModeEvent event = new APIChangeHostNetworkInterfaceLldpModeEvent(); + HostNetworkInterfaceLldpInventory inv = new HostNetworkInterfaceLldpInventory(); + + inv.setInterfaceUuid(uuid()); + inv.setMode("rx_only"); + + event.setInventories(CollectionDSL.list(inv)); + return event; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeEventDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..26912f19fd0 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.hostNetworkInterface.lldp.api + +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "修改lldp的工作模式" + + ref { + name "inventories" + path "org.zstack.network.hostNetworkInterface.lldp.api.APIChangeHostNetworkInterfaceLldpModeEvent.inventories" + desc "物理网卡lldp配置清单" + type "List" + since "5.0.0" + clz HostNetworkInterfaceLldpInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.network.hostNetworkInterface.lldp.api.APIChangeHostNetworkInterfaceLldpModeEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeMsg.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeMsg.java new file mode 100644 index 00000000000..fce7824092d --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeMsg.java @@ -0,0 +1,57 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO; +import org.zstack.network.hostNetworkInterface.lldp.LldpConstant; + +import java.util.Collections; +import java.util.List; + +@Action(category = LldpConstant.ACTION_CATEGORY) +@RestRequest( + path = "/hostNetworkInterface/lldp/actions", + method = HttpMethod.PUT, + responseClass = APIChangeHostNetworkInterfaceLldpModeEvent.class, + isAction = true +) +public class APIChangeHostNetworkInterfaceLldpModeMsg extends APIMessage implements APIAuditor { + @APIParam(resourceType = HostNetworkInterfaceVO.class) + private List interfaceUuids; + + @APIParam(required = false, validValues = {"rx_only", "tx_only", "rx_and_tx", "disable"}) + private String mode = "rx_only"; + + public List getInterfaceUuids() { + return interfaceUuids; + } + + public void setInterfaceUuids(List interfaceUuids) { + this.interfaceUuids = interfaceUuids; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return null; + } + + public static APIChangeHostNetworkInterfaceLldpModeMsg __example__() { + APIChangeHostNetworkInterfaceLldpModeMsg msg = new APIChangeHostNetworkInterfaceLldpModeMsg(); + msg.setInterfaceUuids(Collections.singletonList(uuid())); + msg.setMode("rx_only"); + return msg; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeMsgDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..908d8d27963 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIChangeHostNetworkInterfaceLldpModeMsgDoc_zh_cn.groovy @@ -0,0 +1,68 @@ +package org.zstack.network.hostNetworkInterface.lldp.api + +import org.zstack.network.hostNetworkInterface.lldp.api.APIChangeHostNetworkInterfaceLldpModeEvent + +doc { + title "ChangeHostNetworkInterfaceLldpMode" + + category "hostNetwork.lldp" + + desc """修改lldp的工作模式""" + + rest { + request { + url "PUT /v1/hostNetworkInterface/lldp/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeHostNetworkInterfaceLldpModeMsg.class + + desc """""" + + params { + + column { + name "interfaceUuids" + enclosedIn "changeHostNetworkInterfaceLldpMode" + desc "物理网口Uuids" + location "body" + type "List" + optional false + since "5.0.0" + } + column { + name "mode" + enclosedIn "changeHostNetworkInterfaceLldpMode" + desc "lldp工作模式" + location "body" + type "String" + optional true + since "5.0.0" + values ("rx_only","tx_only","rx_and_tx","disable") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIChangeHostNetworkInterfaceLldpModeEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpMsg.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpMsg.java new file mode 100644 index 00000000000..58799e167c1 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpMsg.java @@ -0,0 +1,35 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO; +import org.zstack.network.hostNetworkInterface.lldp.LldpConstant; + +@Action(category = LldpConstant.ACTION_CATEGORY) +@RestRequest( + path = "/hostNetworkInterface/lldp/{interfaceUuid}/info", + method = HttpMethod.GET, + responseClass = APIGetHostNetworkInterfaceLldpReply.class +) +public class APIGetHostNetworkInterfaceLldpMsg extends APISyncCallMessage { + @APIParam(resourceType = HostNetworkInterfaceVO.class) + private String interfaceUuid; + + public String getInterfaceUuid() { + return interfaceUuid; + } + + public void setInterfaceUuid(String interfaceUuid) { + this.interfaceUuid = interfaceUuid; + } + + public static APIGetHostNetworkInterfaceLldpMsg __example__() { + APIGetHostNetworkInterfaceLldpMsg msg = new APIGetHostNetworkInterfaceLldpMsg(); + msg.setInterfaceUuid(uuid()); + return msg; + } +} + diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpMsgDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..a5962d61420 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.network.hostNetworkInterface.lldp.api + +import org.zstack.network.hostNetworkInterface.lldp.api.APIGetHostNetworkInterfaceLldpReply + +doc { + title "GetHostNetworkInterfaceLldp" + + category "hostNetwork.lldp" + + desc """获取物理网口lldp信息""" + + rest { + request { + url "GET /v1/hostNetworkInterface/lldp/{interfaceUuid}/info" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetHostNetworkInterfaceLldpMsg.class + + desc """""" + + params { + + column { + name "interfaceUuid" + enclosedIn "" + desc "物理网口Uuid" + location "url" + type "String" + optional false + since "5.0.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIGetHostNetworkInterfaceLldpReply.class + } + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpReply.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpReply.java new file mode 100644 index 00000000000..e131b9af341 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpReply.java @@ -0,0 +1,39 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpRefInventory; + +@RestResponse(fieldsTo = {"all"}) +public class APIGetHostNetworkInterfaceLldpReply extends APIReply { + HostNetworkInterfaceLldpRefInventory lldp; + + public HostNetworkInterfaceLldpRefInventory getLldp() { + return lldp; + } + + public void setLldp(HostNetworkInterfaceLldpRefInventory lldp) { + this.lldp = lldp; + } + + public static APIGetHostNetworkInterfaceLldpReply __example__() { + APIGetHostNetworkInterfaceLldpReply reply = new APIGetHostNetworkInterfaceLldpReply(); + HostNetworkInterfaceLldpRefInventory inv = new HostNetworkInterfaceLldpRefInventory(); + + inv.setLldpUuid(uuid()); + inv.setChassisId("mac 00:1e:08:1d:05:ba"); + inv.setTimeToLive(120); + inv.setManagementAddress("172.25.2.4"); + inv.setSystemName("BM-MN-3"); + inv.setSystemDescription(" CentecOS software, E530, Version 7.4.7 Copyright (C) 2004-2021 Centec Networks Inc. All Rights Reserved."); + inv.setSystemCapabilities("Bridge, on Router, on"); + inv.setPortId("ifname eth-0-5"); + inv.setPortDescription("eth-0-4"); + inv.setVlanId(3999); + inv.setAggregationPortId(4294965248L); + inv.setMtu(9600); + + reply.setLldp(inv); + return reply; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpReplyDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..2641580d651 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIGetHostNetworkInterfaceLldpReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.hostNetworkInterface.lldp.api + +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpRefInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取物理网口lldp信息" + + ref { + name "lldp" + path "org.zstack.network.hostNetworkInterface.lldp.api.APIGetHostNetworkInterfaceLldpReply.lldp" + desc "物理网卡lldp信息清单" + type "HostNetworkInterfaceLldpRefInventory" + since "5.0.0" + clz HostNetworkInterfaceLldpRefInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.network.hostNetworkInterface.lldp.api.APIGetHostNetworkInterfaceLldpReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpMsg.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpMsg.java new file mode 100644 index 00000000000..959b7154f97 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpMsg.java @@ -0,0 +1,28 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpInventory; +import org.zstack.network.hostNetworkInterface.lldp.LldpConstant; + +import java.util.List; + +import static java.util.Arrays.asList; + +@AutoQuery(replyClass = APIQueryHostNetworkInterfaceLldpReply.class, inventoryClass = HostNetworkInterfaceLldpInventory.class) +@Action(category = LldpConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/hostNetworkInterface/lldp/all", + optionalPaths = {"/hostNetworkInterface/lldp/{interfaceUuid}"}, + method = HttpMethod.GET, + responseClass = APIQueryHostNetworkInterfaceLldpReply.class +) +public class APIQueryHostNetworkInterfaceLldpMsg extends APIQueryMessage { + public static List __example__() { + return asList(); + } + +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpMsgDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..b3b0c83d9e3 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.network.hostNetworkInterface.lldp.api + +import org.zstack.network.hostNetworkInterface.lldp.api.APIQueryHostNetworkInterfaceLldpReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryHostNetworkInterfaceLldp" + + category "hostNetwork.lldp" + + desc """查询物理网口lldp配置""" + + rest { + request { + url "GET /v1/hostNetworkInterface/lldp/all" + url "GET /v1/hostNetworkInterface/lldp/{interfaceUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryHostNetworkInterfaceLldpMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryHostNetworkInterfaceLldpReply.class + } + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpReply.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpReply.java new file mode 100644 index 00000000000..2997cf7750f --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpReply.java @@ -0,0 +1,31 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpInventory; + +import java.util.Collections; +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQueryHostNetworkInterfaceLldpReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryHostNetworkInterfaceLldpReply __example__() { + APIQueryHostNetworkInterfaceLldpReply reply = new APIQueryHostNetworkInterfaceLldpReply(); + HostNetworkInterfaceLldpInventory inv = new HostNetworkInterfaceLldpInventory(); + inv.setInterfaceUuid(uuid()); + inv.setMode("rx_only"); + + reply.setInventories(Collections.singletonList(inv)); + return reply; + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpReplyDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..bc617e6ccb5 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/APIQueryHostNetworkInterfaceLldpReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.hostNetworkInterface.lldp.api + +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询物理网口lldp配置" + + ref { + name "inventories" + path "org.zstack.network.hostNetworkInterface.lldp.api.APIQueryHostNetworkInterfaceLldpReply.inventories" + desc "物理网卡lldp配置清单" + type "List" + since "5.0.0" + clz HostNetworkInterfaceLldpInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.network.hostNetworkInterface.lldp.api.APIQueryHostNetworkInterfaceLldpReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/GetHostNetworkInterfaceLldpMsg.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/GetHostNetworkInterfaceLldpMsg.java new file mode 100644 index 00000000000..2efe1526b36 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/GetHostNetworkInterfaceLldpMsg.java @@ -0,0 +1,15 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.zstack.header.message.NeedReplyMessage; + +public class GetHostNetworkInterfaceLldpMsg extends NeedReplyMessage { + private String interfaceUuid; + + public String getInterfaceUuid() { + return interfaceUuid; + } + + public void setInterfaceUuid(String interfaceUuid) { + this.interfaceUuid = interfaceUuid; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/GetHostNetworkInterfaceLldpReply.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/GetHostNetworkInterfaceLldpReply.java new file mode 100644 index 00000000000..f182596b7e2 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/GetHostNetworkInterfaceLldpReply.java @@ -0,0 +1,18 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.zstack.header.message.MessageReply; +import org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpRefInventory; + +import java.io.Serializable; + +public class GetHostNetworkInterfaceLldpReply extends MessageReply implements Serializable { + private HostNetworkInterfaceLldpRefInventory lldp; + + public HostNetworkInterfaceLldpRefInventory getLldp() { + return lldp; + } + + public void setLldp(HostNetworkInterfaceLldpRefInventory lldp) { + this.lldp = lldp; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/RBACInfo.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/RBACInfo.java new file mode 100644 index 00000000000..f532117401b --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/api/RBACInfo.java @@ -0,0 +1,28 @@ +package org.zstack.network.hostNetworkInterface.lldp.api; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .name("lldp") + .adminOnlyAPIs("org.zstack.network.hostNetworkInterface.lldp.api.**") + .build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + + } +} \ No newline at end of file diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpInventory.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpInventory.java new file mode 100644 index 00000000000..abf73f59372 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpInventory.java @@ -0,0 +1,95 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.*; +import org.zstack.header.search.Inventory; + +import javax.persistence.JoinColumn; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@PythonClassInventory +@Inventory(mappingVOClass = HostNetworkInterfaceLldpVO.class) +public class HostNetworkInterfaceLldpInventory implements Serializable { + private String uuid; + private String interfaceUuid; + private String mode; + private Timestamp createDate; + private Timestamp lastOpDate; + + @Queryable(mappingClass = HostNetworkInterfaceLldpRefInventory.class, + joinColumn = @JoinColumn(name = "lldpUuid", referencedColumnName = "neighborDevice")) + private HostNetworkInterfaceLldpRefInventory neighborDevice; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getInterfaceUuid() { + return interfaceUuid; + } + + public void setInterfaceUuid(String interfaceUuid) { + this.interfaceUuid = interfaceUuid; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public HostNetworkInterfaceLldpRefInventory getNeighborDevice() { + return neighborDevice; + } + + public void setNeighborDevice(HostNetworkInterfaceLldpRefInventory neighborDevice) { + this.neighborDevice = neighborDevice; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public HostNetworkInterfaceLldpInventory() { + + } + + public HostNetworkInterfaceLldpInventory(HostNetworkInterfaceLldpVO vo) { + this.uuid = vo.getUuid(); + this.interfaceUuid = vo.getInterfaceUuid(); + this.mode = vo.getMode(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + this.neighborDevice = vo.getNeighborDevice() != null ? HostNetworkInterfaceLldpRefInventory.valueOf(vo.getNeighborDevice()) : null; + } + + public static HostNetworkInterfaceLldpInventory valueOf(HostNetworkInterfaceLldpVO vo) { + return new HostNetworkInterfaceLldpInventory(vo); + } + + public static List valueOf(Collection vos) { + return vos.stream().map(HostNetworkInterfaceLldpInventory::valueOf).collect(Collectors.toList()); + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpInventoryDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..f6f323a50bc --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpInventoryDoc_zh_cn.groovy @@ -0,0 +1,45 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity + +doc { + + title "物理网卡lldp配置清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.0.0" + } + field { + name "interfaceUuid" + desc "物理网口Uuid" + type "String" + since "5.0.0" + } + field { + name "mode" + desc "lldp工作模式" + type "String" + since "5.0.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.0.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.0.0" + } + ref { + name "lldp" + path "org.zstack.network.hostNetworkInterface.lldp.entity.HostNetworkInterfaceLldpInventory.neighborDevice" + desc "物理网口lldp信息清单" + type "HostNetworkInterfaceLldpRefInventory" + since "5.0.0" + clz HostNetworkInterfaceLldpRefInventory.class + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefInventory.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefInventory.java new file mode 100644 index 00000000000..29cabf59f6a --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefInventory.java @@ -0,0 +1,176 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +@PythonClassInventory +@Inventory(mappingVOClass = HostNetworkInterfaceLldpRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "neighborDevice", inventoryClass = HostNetworkInterfaceLldpInventory.class, + foreignKey = "lldpUuid", expandedInventoryKey = "uuid"), +}) +public class HostNetworkInterfaceLldpRefInventory implements Serializable { + private String lldpUuid; + private String chassisId; + private Integer timeToLive; + private String managementAddress; + private String systemName; + private String systemDescription; + private String systemCapabilities; + private String portId; + private String portDescription; + private Integer vlanId; + private Long aggregationPortId; + private Integer mtu; + private Timestamp createDate; + private Timestamp lastOpDate; + + public String getLldpUuid() { + return lldpUuid; + } + + public void setLldpUuid(String lldpUuid) { + this.lldpUuid = lldpUuid; + } + + public String getChassisId() { + return chassisId; + } + + public void setChassisId(String chassisId) { + this.chassisId = chassisId; + } + + public Integer getTimeToLive() { + return timeToLive; + } + + public void setTimeToLive(Integer timeToLive) { + this.timeToLive = timeToLive; + } + + public String getManagementAddress() { + return managementAddress; + } + + public void setManagementAddress(String managementAddress) { + this.managementAddress = managementAddress; + } + + public String getSystemName() { + return systemName; + } + + public void setSystemName(String systemName) { + this.systemName = systemName; + } + + public String getSystemDescription() { + return systemDescription; + } + + public void setSystemDescription(String systemDescription) { + this.systemDescription = systemDescription; + } + + public String getSystemCapabilities() { + return systemCapabilities; + } + + public void setSystemCapabilities(String systemCapabilities) { + this.systemCapabilities = systemCapabilities; + } + + public String getPortId() { + return portId; + } + + public void setPortId(String portId) { + this.portId = portId; + } + + public String getPortDescription() { + return portDescription; + } + + public void setPortDescription(String portDescription) { + this.portDescription = portDescription; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public Long getAggregationPortId() { + return aggregationPortId; + } + + public void setAggregationPortId(Long aggregationPortId) { + this.aggregationPortId = aggregationPortId; + } + + public Integer getMtu() { + return mtu; + } + + public void setMtu(Integer mtu) { + this.mtu = mtu; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public HostNetworkInterfaceLldpRefInventory() { + + } + + public HostNetworkInterfaceLldpRefInventory(HostNetworkInterfaceLldpRefVO vo) { + this.lldpUuid = vo.getLldpUuid(); + this.chassisId = vo.getChassisId(); + this.timeToLive = vo.getTimeToLive(); + this.managementAddress = vo.getManagementAddress(); + this.systemName = vo.getSystemName(); + this.systemDescription = vo.getSystemDescription(); + this.systemCapabilities = vo.getSystemCapabilities(); + this.portId = vo.getPortId(); + this.portDescription = vo.getPortDescription(); + this.vlanId = vo.getVlanId(); + this.aggregationPortId = vo.getAggregationPortId(); + this.mtu = vo.getMtu(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + } + + public static HostNetworkInterfaceLldpRefInventory valueOf(HostNetworkInterfaceLldpRefVO vo) { + return new HostNetworkInterfaceLldpRefInventory(vo); + } + + public static List valueOf(Collection vos) { + return vos.stream().map(HostNetworkInterfaceLldpRefInventory::valueOf).collect(Collectors.toList()); + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefInventoryDoc_zh_cn.groovy b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..482ea5edd1e --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefInventoryDoc_zh_cn.groovy @@ -0,0 +1,91 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity + +doc { + + title "物理网卡lldp信息清单" + + field { + name "lldpUuid" + desc "Lldp UUID" + type "String" + since "5.0.0" + } + field { + name "chassisId" + desc "机箱标识" + type "String" + since "5.0.0" + } + field { + name "timeToLive" + desc "生存时间" + type "Integer" + since "5.0.0" + } + field { + name "managementAddress" + desc "管理地址" + type "String" + since "5.0.0" + } + field { + name "systemName" + desc "系统名称" + type "String" + since "5.0.0" + } + field { + name "systemDescription" + desc "系统描述" + type "String" + since "5.0.0" + } + field { + name "systemCapabilities" + desc "系统能力" + type "String" + since "5.0.0" + } + field { + name "portId" + desc "端口标识" + type "String" + since "5.0.0" + } + field { + name "portDescription" + desc "端口描述" + type "String" + since "5.0.0" + } + field { + name "vlanId" + desc "VLAN标识" + type "Integer" + since "5.0.0" + } + field { + name "aggregationPortId" + desc "聚合端口标识" + type "Long" + since "5.0.0" + } + field { + name "mtu" + desc "最大传输单元" + type "Integer" + since "5.0.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.0.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.0.0" + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefVO.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefVO.java new file mode 100644 index 00000000000..f60cff647e2 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefVO.java @@ -0,0 +1,183 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity; + +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.Index; +import org.zstack.header.vo.*; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = HostNetworkInterfaceLldpVO.class, joinColumn = "lldpUuid") +}) +@EntityGraph( + parents = { + @EntityGraph.Neighbour(type = HostNetworkInterfaceLldpVO.class, myField = "lldpUuid", targetField = "uuid") + } +) +public class HostNetworkInterfaceLldpRefVO implements ToInventory { + @Id + @Column + @Index + @ForeignKey(parentEntityClass = HostNetworkInterfaceLldpVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String lldpUuid; + + @Column + private String chassisId; + + @Column + private Integer timeToLive; + + @Column + private String managementAddress; + + @Column + private String systemName; + + @Column + private String systemDescription; + + @Column + private String systemCapabilities; + + @Column + private String portId; + + @Column + private String portDescription; + + @Column + private Integer vlanId; + + @Column + private Long aggregationPortId; + + @Column + private Integer mtu; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public String getLldpUuid() { + return lldpUuid; + } + + public void setLldpUuid(String lldpUuid) { + this.lldpUuid = lldpUuid; + } + + public String getChassisId() { + return chassisId; + } + + public void setChassisId(String chassisId) { + this.chassisId = chassisId; + } + + public Integer getTimeToLive() { + return timeToLive; + } + + public void setTimeToLive(Integer timeToLive) { + this.timeToLive = timeToLive; + } + + public String getManagementAddress() { + return managementAddress; + } + + public void setManagementAddress(String managementAddress) { + this.managementAddress = managementAddress; + } + + public String getSystemName() { + return systemName; + } + + public void setSystemName(String systemName) { + this.systemName = systemName; + } + + public String getSystemDescription() { + return systemDescription; + } + + public void setSystemDescription(String systemDescription) { + this.systemDescription = systemDescription; + } + + public String getSystemCapabilities() { + return systemCapabilities; + } + + public void setSystemCapabilities(String systemCapabilities) { + this.systemCapabilities = systemCapabilities; + } + + public String getPortId() { + return portId; + } + + public void setPortId(String portId) { + this.portId = portId; + } + + public String getPortDescription() { + return portDescription; + } + + public void setPortDescription(String portDescription) { + this.portDescription = portDescription; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public Long getAggregationPortId() { + return aggregationPortId; + } + + public void setAggregationPortId(Long aggregationPortId) { + this.aggregationPortId = aggregationPortId; + } + + public Integer getMtu() { + return mtu; + } + + public void setMtu(Integer mtu) { + this.mtu = mtu; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefVO_.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefVO_.java new file mode 100644 index 00000000000..46036735b4a --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpRefVO_.java @@ -0,0 +1,24 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity; + + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(HostNetworkInterfaceLldpRefVO.class) +public class HostNetworkInterfaceLldpRefVO_ { + public static volatile SingularAttribute lldpUuid; + public static volatile SingularAttribute chassisId; + public static volatile SingularAttribute timeToLive; + public static volatile SingularAttribute managementAddress; + public static volatile SingularAttribute systemName; + public static volatile SingularAttribute systemDescription; + public static volatile SingularAttribute systemCapabilities; + public static volatile SingularAttribute portId; + public static volatile SingularAttribute portDescription; + public static volatile SingularAttribute vlanId; + public static volatile SingularAttribute aggregationPortId; + public static volatile SingularAttribute mtu; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpVO.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpVO.java new file mode 100644 index 00000000000..96a23965a47 --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpVO.java @@ -0,0 +1,94 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.*; +import org.zstack.header.vo.Index; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = HostNetworkInterfaceVO.class, joinColumn = "interfaceUuid") +}) +public class HostNetworkInterfaceLldpVO extends ResourceVO implements ToInventory, OwnedByAccount { + @Column + @Index + @ForeignKey(parentEntityClass = HostNetworkInterfaceVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String interfaceUuid; + + @Column + private String mode; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @Transient + private String accountUuid; + + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name="uuid", referencedColumnName = "lldpUuid", insertable=false, updatable=false) + @NoView + private HostNetworkInterfaceLldpRefVO neighborDevice; + + public String getInterfaceUuid() { + return interfaceUuid; + } + + public void setInterfaceUuid(String interfaceUuid) { + this.interfaceUuid = interfaceUuid; + } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public HostNetworkInterfaceLldpRefVO getNeighborDevice() { + return neighborDevice; + } + + public void setNeighborDevice(HostNetworkInterfaceLldpRefVO neighborDevice) { + this.neighborDevice = neighborDevice; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } +} diff --git a/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpVO_.java b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpVO_.java new file mode 100644 index 00000000000..128b6224bec --- /dev/null +++ b/plugin/hostNetworkInterface/src/main/java/org/zstack/network/hostNetworkInterface/lldp/entity/HostNetworkInterfaceLldpVO_.java @@ -0,0 +1,15 @@ +package org.zstack.network.hostNetworkInterface.lldp.entity; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(HostNetworkInterfaceLldpVO.class) +public class HostNetworkInterfaceLldpVO_ extends ResourceVO_ { + public static volatile SingularAttribute interfaceUuid; + public static volatile SingularAttribute mode; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/iscsi/pom.xml b/plugin/iscsi/pom.xml new file mode 100644 index 00000000000..bb7bacea0e7 --- /dev/null +++ b/plugin/iscsi/pom.xml @@ -0,0 +1,93 @@ + + 4.0.0 + + + + plugin + org.zstack + 5.4.0 + .. + + + iscsi + + + org.zstack + kvm + ${project.version} + + + org.zstack + storage + ${project.version} + + + org.zstack + externalStorage + ${project.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + \ No newline at end of file diff --git a/plugin/iscsi/src/main/java/org/zstack/iscsi/IscsiUtils.java b/plugin/iscsi/src/main/java/org/zstack/iscsi/IscsiUtils.java new file mode 100644 index 00000000000..1fa5af3d517 --- /dev/null +++ b/plugin/iscsi/src/main/java/org/zstack/iscsi/IscsiUtils.java @@ -0,0 +1,62 @@ +package org.zstack.iscsi; + +import org.zstack.compute.host.HostSystemTags; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.Q; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.backup.*; +import org.zstack.header.tag.SystemTagVO; +import org.zstack.header.tag.SystemTagVO_; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.storage.backup.BackupStorageSystemTags; + +import java.util.Collections; + +public class IscsiUtils { + public static String getHostInitiatorName(String hostUuid) { + return HostSystemTags.ISCSI_INITIATOR_NAME.getTokenByResourceUuid(hostUuid, HostVO.class, HostSystemTags.ISCSI_INITIATOR_NAME_TOKEN); + } + + public static String getHostMnIpFromInitiatorName(String initiatorName) { + String tag = HostSystemTags.ISCSI_INITIATOR_NAME.instantiateTag( + Collections.singletonMap(HostSystemTags.ISCSI_INITIATOR_NAME_TOKEN, initiatorName)); + + SystemTagVO tagVO = Q.New(SystemTagVO.class).eq(SystemTagVO_.tag, tag).find(); + if (tagVO == null) { + return null; + } + + if (tagVO.getResourceType().equals(HostVO.class.getSimpleName())) { + return Q.New(HostVO.class).eq(HostVO_.uuid, tagVO.getResourceUuid()).select(HostVO_.managementIp).findValue(); + } else if (tagVO.getResourceType().equals(BackupStorageVO.class.getSimpleName())) { + return getBsMnIp(tagVO.getResourceUuid()); + } + + return null; + } + + private static String getBsMnIp(String bsUuid) { + CloudBus bus = Platform.getComponentLoader().getComponent(CloudBus.class); + GetBackupStorageManagerHostnameMsg msg = new GetBackupStorageManagerHostnameMsg(); + msg.setUuid(bsUuid); + bus.makeLocalServiceId(msg, BackupStorageConstant.SERVICE_ID); + MessageReply reply = bus.call(msg); + if (!reply.isSuccess()) { + throw new OperationFailureException(reply.getError()); + } + return ((GetBackupStorageManagerHostnameReply) reply).getHostname(); + } + + public static String getBSInitiatorName(String bsUuid) { + return BackupStorageSystemTags.ISCSI_INITIATOR_NAME.getTokenByResourceUuid(bsUuid, BackupStorageVO.class, BackupStorageSystemTags.ISCSI_INITIATOR_NAME_TOKEN); + } + + public static String getBMInitiatorName(String vmUuid) { + return String.format("iqn.2015-01.io.zstack:initiator.instance.%s", vmUuid); + } +} diff --git a/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/IscsiHeartbeatVolumeTO.java b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/IscsiHeartbeatVolumeTO.java new file mode 100644 index 00000000000..b61127728f1 --- /dev/null +++ b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/IscsiHeartbeatVolumeTO.java @@ -0,0 +1,9 @@ +package org.zstack.iscsi.kvm; + +import org.zstack.header.storage.addon.primary.HeartbeatVolumeTO; + +public class IscsiHeartbeatVolumeTO extends HeartbeatVolumeTO { + { + protocol = "iscsi"; + } +} diff --git a/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/IscsiVolumeTO.java b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/IscsiVolumeTO.java new file mode 100644 index 00000000000..f84043c49af --- /dev/null +++ b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/IscsiVolumeTO.java @@ -0,0 +1,10 @@ +package org.zstack.iscsi.kvm; + +import org.zstack.header.storage.addon.primary.ActiveVolumeTO; +import org.zstack.header.volume.VolumeProtocol; + +public class IscsiVolumeTO extends ActiveVolumeTO { + { + protocol = VolumeProtocol.iSCSI.name(); + } +} diff --git a/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/KvmIscsiCommands.java b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/KvmIscsiCommands.java new file mode 100644 index 00000000000..891b6ee95dc --- /dev/null +++ b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/KvmIscsiCommands.java @@ -0,0 +1,39 @@ +package org.zstack.iscsi.kvm; + +import org.zstack.kvm.KVMAgentCommands; + +import java.util.List; + +public class KvmIscsiCommands { + public static final String ISCSI_SELF_FENCER_PATH = "/ha/iscsi/setupselffencer"; + public static final String CANCEL_ISCSI_SELF_FENCER_PATH = "/ha/iscsi/cancelselffencer"; + public static final String ISCSI_CHECK_VMSTATE_PATH = "/iscsi/check/vmstate"; + + public static class AgentCmd extends KVMAgentCommands.AgentCommand { + public String uuid; + } + + public static class AgentRsp { + public boolean success = true; + public String error; + } + + public static class KvmSetupSelfFencerCmd extends AgentCmd { + public long interval; + public int maxAttempts; + public List coveringPaths; + public String heartbeatUrl; + public int storageCheckerTimeout; + public String hostUuid; + public Integer hostId; + public Long heartbeatRequiredSpace; + public String strategy; + public List fencers; + } + + public static class KvmCancelSelfFencerCmd extends AgentCmd { + public String installPath; + public String hostUuid; + public Integer hostId; + } +} diff --git a/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/KvmIscsiNodeServer.java b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/KvmIscsiNodeServer.java new file mode 100644 index 00000000000..31dddaa0789 --- /dev/null +++ b/plugin/iscsi/src/main/java/org/zstack/iscsi/kvm/KvmIscsiNodeServer.java @@ -0,0 +1,428 @@ +package org.zstack.iscsi.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.externalStorage.primary.ExternalStorageConstant; +import org.zstack.header.Component; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.addon.primary.BaseVolumeInfo; +import org.zstack.header.storage.addon.primary.HeartbeatVolumeTO; +import org.zstack.header.storage.addon.primary.PrimaryStorageNodeSvc; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceMigrateExtensionPoint; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.cdrom.VmCdRomVO; +import org.zstack.header.vm.cdrom.VmCdRomVO_; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeProtocol; +import org.zstack.header.volume.VolumeProtocolCapability; +import org.zstack.iscsi.kvm.KvmIscsiCommands.AgentRsp; +import org.zstack.iscsi.kvm.KvmIscsiCommands.KvmCancelSelfFencerCmd; +import org.zstack.iscsi.kvm.KvmIscsiCommands.KvmSetupSelfFencerCmd; +import org.zstack.kvm.*; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; +import org.zstack.utils.DebugUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.zstack.core.Platform.operr; + +public class KvmIscsiNodeServer implements Component, KVMStartVmExtensionPoint, VmInstanceMigrateExtensionPoint, + KVMConvertVolumeExtensionPoint, KVMDetachVolumeExtensionPoint, KVMAttachVolumeExtensionPoint, + KVMPreAttachIsoExtensionPoint, KvmSetupSelfFencerExtensionPoint { + @Autowired + private ExternalPrimaryStorageFactory extPsFactory; + + @Autowired + private PluginRegistry pluginRgty; + + @Autowired + private CloudBus bus; + + @Autowired + private DatabaseFacade dbf; + + private static final VolumeProtocolCapability capability = VolumeProtocolCapability + .register(VolumeProtocol.iSCSI.name(), KVMConstant.KVM_HYPERVISOR_TYPE); + + static { + capability.setSupportQosOnHypervisor(true); + capability.setSupportResizeOnHypervisor(false); + capability.setSupportReadonly(true); + } + + @Override + public void beforeStartVmOnKvm(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommands.StartVmCmd cmd) { + cmd.setRootVolume(convertVolumeIfNeeded(spec.getDestRootVolume(), host, cmd.getRootVolume())); + + List dtos = new ArrayList<>(); + for (VolumeTO to : cmd.getDataVolumes()) { + for (VolumeInventory vol : spec.getDestDataVolumes()) { + if (vol.getUuid().equals(to.getVolumeUuid())) { + dtos.add(convertVolumeIfNeeded(vol, host, to)); + break; + } + } + } + + cmd.setDataVolumes(dtos); + + + + for (KVMAgentCommands.CdRomTO cdRomTO : cmd.getCdRoms()) { + if (cdRomTO.isEmpty()) { + continue; + } + convertIsoIfNeeded(cdRomTO, host); + } + } + + @Override + public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { + + } + + @Override + public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { + + } + + + private PrimaryStorageNodeSvc getNodeService(VolumeInventory volumeInventory) { + String identity = volumeInventory.getInstallPath().split("://")[0]; + if (!extPsFactory.support(identity)) { + return null; + } + + return extPsFactory.getNodeSvc(volumeInventory.getPrimaryStorageUuid()); + } + + private VolumeTO convertVolumeIfNeeded(VolumeInventory volumeInventory, HostInventory h, VolumeTO volumeTO) { + if (!VolumeProtocol.iSCSI.name().equals(volumeInventory.getProtocol())) { + return volumeTO; + } + + PrimaryStorageNodeSvc nodeSvc = getNodeService(volumeInventory); + if (nodeSvc == null) { + return volumeTO; + } + + String path = nodeSvc.getActivePath(BaseVolumeInfo.valueOf(volumeInventory), h, false); + volumeTO.setInstallPath(path); + return volumeTO; + } + + private KVMAgentCommands.IsoTO convertIsoIfNeeded(KVMAgentCommands.IsoTO isoTO, HostInventory h) { + if (!VolumeProtocol.iSCSI.name().equals(isoTO.getProtocol())) { + return isoTO; + } + + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(isoTO.getPrimaryStorageUuid()); + if (nodeSvc == null) { + return isoTO; + } + + BaseVolumeInfo iso = new BaseVolumeInfo(); + iso.setInstallPath(isoTO.getPath()); + iso.setUuid(isoTO.getImageUuid()); + iso.setProtocol(isoTO.getProtocol()); + iso.setShareable(true); + + String path = nodeSvc.getActivePath(iso, h, true); + isoTO.setPath(path); + return isoTO; + } + + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return false; + } + + @Override + public VolumeTO convertVolumeIfNeed(KVMHostInventory host, VolumeInventory inventory, VolumeTO to) { + return convertVolumeIfNeeded(inventory, host, to); + } + + @Override + public void beforeDetachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.DetachDataVolumeCmd cmd) { + cmd.setVolume(convertVolumeIfNeeded(volume, host, cmd.getVolume())); + } + + @Override + public void afterDetachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.DetachDataVolumeCmd cmd) { } + + @Override + public void detachVolumeFailed(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.DetachDataVolumeCmd cmd, ErrorCode err) { } + + @Override + public void beforeAttachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.AttachDataVolumeCmd cmd, Map data) { + cmd.setVolume(convertVolumeIfNeeded(volume, host, cmd.getVolume())); + } + + @Override + public void afterAttachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.AttachDataVolumeCmd cmd) {} + @Override + public void attachVolumeFailed(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.AttachDataVolumeCmd cmd, ErrorCode err, Map data) {} + + @Override + public void preAttachIsoExtensionPoint(KVMHostInventory host, KVMAgentCommands.AttachIsoCmd cmd) { + cmd.iso = convertIsoIfNeeded(cmd.iso, host); + } + + @Override + public String kvmSetupSelfFencerStorageType() { + return VolumeProtocol.iSCSI.toString(); + } + + @Override + public void kvmSetupSelfFencer(KvmSetupSelfFencerParam param, Completion completion) { + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(param.getPrimaryStorage().getUuid()); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("setup-self-fencer-for-external-primary-storage-%s", param.getPrimaryStorage().getUuid())); + chain.then(new ShareFlow() { + HostInventory host = HostInventory.valueOf(dbf.findByUuid(param.getHostUuid(), HostVO.class)); + HeartbeatVolumeTO heartbeatVol; + @Override + public void setup() { + flow(new NoRollbackFlow() { + final String __name__ = "activate-iscsi-heartbeat-volume"; + + @Override + public void run(FlowTrigger trigger, Map data) { + nodeSvc.activateHeartbeatVolume(host, new ReturnValueCompletion(trigger) { + @Override + public void success(HeartbeatVolumeTO vol) { + heartbeatVol = vol; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + final String __name__ = "setup-iscsi-self-fencer-on-kvm"; + + @Override + public void run(FlowTrigger trigger, Map data) { + KvmSetupSelfFencerCmd cmd = new KvmSetupSelfFencerCmd(); + cmd.interval = param.getInterval(); + cmd.maxAttempts = param.getMaxAttempts(); + cmd.coveringPaths = heartbeatVol.getCoveringPaths(); + cmd.heartbeatUrl = heartbeatVol.getInstallPath(); + cmd.storageCheckerTimeout = param.getStorageCheckerTimeout(); + cmd.hostId = heartbeatVol.getHostId(); + cmd.heartbeatRequiredSpace = heartbeatVol.getHeartbeatRequiredSpace(); + cmd.hostUuid = param.getHostUuid(); + cmd.strategy = param.getStrategy(); + cmd.uuid = param.getPrimaryStorage().getUuid(); + cmd.fencers = param.getFencers(); + + httpCall(KvmIscsiCommands.ISCSI_SELF_FENCER_PATH, param.getHostUuid(), cmd, true, AgentRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(AgentRsp rsp) { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + } + }).start(); + } + + @Override + public void kvmCancelSelfFencer(KvmCancelSelfFencerParam param, Completion completion) { + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("cancel-self-fencer-for-external-primary-storage-%s", param.getPrimaryStorage().getUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + + flow(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + KvmCancelSelfFencerCmd cmd = new KvmCancelSelfFencerCmd(); + cmd.uuid = param.getPrimaryStorage().getUuid(); + + httpCall(KvmIscsiCommands.CANCEL_ISCSI_SELF_FENCER_PATH, param.getHostUuid(), cmd, true, AgentRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(AgentRsp rsp) { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + } + }).start(); + } + + protected void httpCall(String path, final String hostUuid, KVMAgentCommands.AgentCommand cmd, final Class respType, final ReturnValueCompletion completion) { + httpCall(path, hostUuid, cmd, false, respType, completion); + } + + protected void httpCall(String path, final String hostUuid, KVMAgentCommands.AgentCommand cmd, boolean noCheckStatus, final Class respType, final ReturnValueCompletion completion) { + DebugUtils.Assert(hostUuid != null, "Host must be set here"); + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setPath(path); + msg.setNoStatusCheck(noCheckStatus); + msg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + KVMHostAsyncHttpCallReply rep = reply.castReply(); + final T rsp = rep.toResponse(respType); + if (!rsp.success) { + completion.fail(operr("operation error, because:%s", rsp.error)); + return; + } + completion.success(rsp); + } + }); + } + + @Override + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { + List vols = getIscsiVolume(inv); + if (vols.isEmpty()) { + completion.success(); + return; + } + + HostInventory host = HostInventory.valueOf(dbf.findByUuid(destHostUuid, HostVO.class)); + new While<>(vols).each((vol, compl) -> { + PrimaryStorageNodeSvc nodeSvc = extPsFactory.getNodeSvc(vol.getPrimaryStorageUuid()); + String path = nodeSvc.getActivePath(vol, host, vol.isShareable()); + if (!path.startsWith("iscsi")) { + compl.done(); + return; + } + + KVMAgentCommands.LoginIscsiTargetCmd cmd = new KVMAgentCommands.LoginIscsiTargetCmd(); + cmd.setUrl(path); + httpCall(KVMConstant.KVM_LOGIN_ISCSI_PATH, destHostUuid, cmd, AgentRsp.class, new ReturnValueCompletion(compl) { + @Override + public void success(AgentRsp rsp) { + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + completion.success(); + } else { + completion.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + + @Override + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { + } + + private List getIscsiVolume(VmInstanceInventory vm) { + List vols = new ArrayList<>(); + + vm.getAllDiskVolumes().forEach(vol -> vols.add(BaseVolumeInfo.valueOf(vol))); + + if (extPsFactory.getNodeSvc(vm.getRootVolume().getPrimaryStorageUuid()) != null) { + List cdRomVOS = Q.New(VmCdRomVO.class).eq(VmCdRomVO_.vmInstanceUuid, vm.getUuid()).list(); + cdRomVOS.forEach(cdRomVO -> { + if (cdRomVO.getIsoUuid() != null && VolumeProtocol.iSCSI.name().equals(cdRomVO.getProtocol())) { + BaseVolumeInfo info = BaseVolumeInfo.valueOf(cdRomVO); + info.setPrimaryStorageUuid(vm.getRootVolume().getPrimaryStorageUuid()); + vols.add(info); + } + }); + } + + vols.removeIf(info -> { + if (info.getInstallPath() == null || !VolumeProtocol.iSCSI.name().equals(info.getProtocol())) { + return true; + } + String identity = info.getInstallPath().split("://")[0]; + return !extPsFactory.support(identity); + }); + + return vols; + } +} diff --git a/plugin/kvm/pom.xml b/plugin/kvm/pom.xml index fc778ce93fa..12ca68055a9 100755 --- a/plugin/kvm/pom.xml +++ b/plugin/kvm/pom.xml @@ -4,7 +4,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 .. kvm @@ -29,6 +29,11 @@ resourceconfig ${project.version} + + org.apache.maven + maven-artifact + 3.0.5 + diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/APIAddKVMHostMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/APIAddKVMHostMsgDoc_zh_cn.groovy index 12415c6db70..fb03b3676ee 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/APIAddKVMHostMsgDoc_zh_cn.groovy +++ b/plugin/kvm/src/main/java/org/zstack/kvm/APIAddKVMHostMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "sshPort" @@ -49,7 +47,6 @@ doc { type "int" optional true since "0.6" - } column { name "name" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "managementIp" @@ -79,7 +74,6 @@ doc { type "String" optional false since "0.6" - } column { name "clusterUuid" @@ -89,7 +83,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -99,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -109,7 +101,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +110,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/APIKvmRunShellMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/APIKvmRunShellMsgDoc_zh_cn.groovy index 42cd483a92b..da60b1d7480 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/APIKvmRunShellMsgDoc_zh_cn.groovy +++ b/plugin/kvm/src/main/java/org/zstack/kvm/APIKvmRunShellMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "Set" optional false since "0.6" - } column { name "script" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/APIUpdateKVMHostMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/APIUpdateKVMHostMsgDoc_zh_cn.groovy index 689a5ad782a..4f5300e5b07 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/APIUpdateKVMHostMsgDoc_zh_cn.groovy +++ b/plugin/kvm/src/main/java/org/zstack/kvm/APIUpdateKVMHostMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshPort" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "uuid" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "managementIp" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +101,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/AbstractKVMConnectExtensionForL2Network.java b/plugin/kvm/src/main/java/org/zstack/kvm/AbstractKVMConnectExtensionForL2Network.java new file mode 100644 index 00000000000..0bec0e09099 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/AbstractKVMConnectExtensionForL2Network.java @@ -0,0 +1,299 @@ +package org.zstack.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HypervisorType; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.vm.*; +import org.zstack.network.l2.L2NetworkManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.TypedQuery; +import java.util.*; +import java.util.stream.Collectors; + +public abstract class AbstractKVMConnectExtensionForL2Network { + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + protected L2NetworkManager l2Mgr; + protected static final CLogger logger = Utils.getLogger(AbstractKVMConnectExtensionForL2Network.class); + + @Transactional(readOnly = true) + protected List getL2Networks(String clusterUuid) { + String sql = "select l2 from L2NetworkVO l2, L2NetworkClusterRefVO ref where l2.uuid = ref.l2NetworkUuid and ref.clusterUuid = :clusterUuid and l2.type in (:supportTypes)"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, L2NetworkVO.class); + q.setParameter("clusterUuid", clusterUuid); + q.setParameter("supportTypes", getSupportTypes()); + List vos = q.getResultList(); + List ret = new ArrayList(vos.size()); + List noVlanL2Networks = new ArrayList<>(); + for (L2NetworkVO vo : vos) { + VSwitchType vSwitchType = VSwitchType.valueOf(vo.getvSwitchType()); + if (!vSwitchType.isAttachToCluster()) { + continue; + } + if (L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(vo.getType())) { + noVlanL2Networks.add(L2NetworkInventory.valueOf(vo)); + } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(vo.getType())) { + L2VlanNetworkVO vlanvo = dbf.getEntityManager().find(L2VlanNetworkVO.class, vo.getUuid()); + ret.add(L2VlanNetworkInventory.valueOf(vlanvo)); + } else { + ret.add(L2NetworkInventory.valueOf(vo)); + } + } + + /* when prepare l2 network, first prepare no vlan network, because mtu of vlan network must less than + * no vlan network */ + if (!noVlanL2Networks.isEmpty()) { + noVlanL2Networks.addAll(ret); + return noVlanL2Networks; + } else { + return ret; + } + } + + protected List getSupportTypes() { + List types = Arrays.asList(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE, L2NetworkConstant.L2_VLAN_NETWORK_TYPE); + return types; + } + + protected void prepareNetwork(final List l2Networks, final String hostUuid, final Completion completion) { + if (l2Networks.isEmpty()) { + completion.success(); + return; + } + + HostVO hostVO = dbf.findByUuid(hostUuid, HostVO.class); + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("prepare-l2-for-kvm-%s-connect", hostUuid)); + chain.then(new NoRollbackFlow() { + String __name__ = "check-network-physical-interface"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + List batchCheckNetworkPhysicalInterfaceMsgs = new ArrayList<>(); + final List l2NetworksCheckList = + l2Networks.stream() + .collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(L2NetworkInventory::getPhysicalInterface))),ArrayList::new)); + int step = 100; + int size = l2NetworksCheckList.size(); + int count = size / 100; + if (size - count * 100 > 0) { + count++; + } + + for (int i = 0; i < count; i++) { + int end = (i + 1) * step; + List interfaces = l2NetworksCheckList.subList(i * step, Math.min(end, l2NetworksCheckList.size())) + .stream() + .map(L2NetworkInventory::getPhysicalInterface) + .collect(Collectors.toList()); + + BatchCheckNetworkPhysicalInterfaceMsg bmsg = new BatchCheckNetworkPhysicalInterfaceMsg(); + bmsg.setPhysicalInterfaces(interfaces); + bmsg.setHostUuid(hostUuid); + bus.makeTargetServiceIdByResourceUuid(bmsg, HostConstant.SERVICE_ID, hostUuid); + batchCheckNetworkPhysicalInterfaceMsgs.add(bmsg); + } + + new While<>(batchCheckNetworkPhysicalInterfaceMsgs).each((bmsg, c) -> { + bus.send(bmsg, new CloudBusCallBack(c) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + c.addError(reply.getError()); + c.allDone(); + return; + } + + c.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + return; + } + + trigger.next(); + } + }); + } + }); + + chain.then(new NoRollbackFlow() { + String __name__ = "realize_no_vlan"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List novlanNetworks = l2Networks.stream().filter(l2 -> l2.getType().equals(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE)).collect(Collectors.toList()); + new While<>(novlanNetworks).step((l2, c) -> { + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(L2NetworkType.valueOf(l2.getType()), VSwitchType.valueOf(l2.getvSwitchType()), HypervisorType.valueOf(hostVO.getHypervisorType())); + ext.realize(l2, hostUuid, true, new Completion(c) { + @Override + public void success() { + c.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + c.addError(errorCode); + c.allDone(); + } + }); + }, 10).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + return; + } + + trigger.next(); + } + }); + } + }); + + chain.then(new NoRollbackFlow() { + String __name__ = "realize_vlan"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List vlanNetworks = l2Networks.stream().filter(l2 -> l2.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE)).collect(Collectors.toList()); + new While<>(vlanNetworks).step((l2, c) -> { + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(L2NetworkType.valueOf(l2.getType()), VSwitchType.valueOf(l2.getvSwitchType()), HypervisorType.valueOf(hostVO.getHypervisorType())); + ext.realize(l2, hostUuid, true, new Completion(c) { + @Override + public void success() { + c.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + c.addError(errorCode); + c.allDone(); + } + }); + }, 10).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + return; + } + + trigger.next(); + } + }); + } + }); + + chain.then(new NoRollbackFlow() { + String __name__ = "sync_vlan_isolated"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List vlanNetworks = l2Networks.stream() + .filter(l2 -> l2.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE) && l2.getIsolated()) + .collect(Collectors.toList()); + List localVmUuidList = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.uuid) + .eq(VmInstanceVO_.hostUuid, hostUuid) + .notEq(VmInstanceVO_.state, VmInstanceState.Stopped) + .listValues(); + List localStopVmUuidList = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.uuid) + .eq(VmInstanceVO_.lastHostUuid, hostUuid) + .eq(VmInstanceVO_.state, VmInstanceState.Stopped) + .listValues(); + localVmUuidList.addAll(localStopVmUuidList); + Map> isolatedL2NetworkMacMap = buildIsolatedL2NetworkMacMap(vlanNetworks, localVmUuidList); + if (isolatedL2NetworkMacMap.isEmpty()) { + trigger.next(); + return; + } + L2NetworkIsolatedSyncOnHostMsg smsg= new L2NetworkIsolatedSyncOnHostMsg(); + smsg.setHostUuid(hostUuid); + smsg.setIsolatedL2NetworkMacMap(isolatedL2NetworkMacMap); + bus.makeTargetServiceIdByResourceUuid(smsg, L2NetworkConstant.L2_PRIVATE_VLAN_SERVICE_ID, hostUuid); + bus.send(smsg, new CloudBusCallBack(smsg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(reply.getError().toString()); + trigger.fail(reply.getError()); + return; + } + trigger.next(); + } + }); + } + }); + + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + private Map> buildIsolatedL2NetworkMacMap(List vlanNetworks, List localVmUuidList) { + Map> isolatedL2NetworkMacMap = new HashMap<>(); + for (L2NetworkInventory l2inv : vlanNetworks) { + List l3Uuids = Q.New(L3NetworkVO.class) + .select(L3NetworkVO_.uuid) + .eq(L3NetworkVO_.l2NetworkUuid, l2inv.getUuid()) + .listValues(); + if (l3Uuids == null || l3Uuids.isEmpty()) { + continue; + } + List macList; + if (localVmUuidList != null && !localVmUuidList.isEmpty()) { + macList = Q.New(VmNicVO.class) + .select(VmNicVO_.mac) + .in(VmNicVO_.l3NetworkUuid, l3Uuids) + .notIn(VmNicVO_.vmInstanceUuid, localVmUuidList) + .listValues(); + } else { + macList = Q.New(VmNicVO.class) + .select(VmNicVO_.mac) + .in(VmNicVO_.l3NetworkUuid, l3Uuids) + .listValues(); + } + if (macList != null && !macList.isEmpty()) { + isolatedL2NetworkMacMap.put(l2inv.getUuid(), macList); + } + } + return isolatedL2NetworkMacMap; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/BaseVirtualDeviceTO.java b/plugin/kvm/src/main/java/org/zstack/kvm/BaseVirtualDeviceTO.java new file mode 100644 index 00000000000..c960e71070d --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/BaseVirtualDeviceTO.java @@ -0,0 +1,24 @@ +package org.zstack.kvm; + +import org.zstack.header.vm.devices.DeviceAddress; + +public class BaseVirtualDeviceTO { + protected String resourceUuid; + protected DeviceAddress deviceAddress; + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public DeviceAddress getDeviceAddress() { + return deviceAddress; + } + + public void setDeviceAddress(DeviceAddress deviceAddress) { + this.deviceAddress = deviceAddress; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAddons.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAddons.java index 073c8d77b6a..5f4647a7f0d 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAddons.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAddons.java @@ -5,6 +5,7 @@ public interface KVMAddons { public static class Channel { public static final String NAME = "channel"; + public static final String VR_NAME = "channel_vr"; private String socketPath; private String targetName; diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java index 36f0be099a8..91e5d885bd8 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java @@ -1,5 +1,8 @@ package org.zstack.kvm; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import org.zstack.core.upgrade.GrayUpgradeAgent; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.validation.ConditionalValidation; import org.zstack.header.HasThreadContext; import org.zstack.header.agent.CancelCommand; @@ -7,15 +10,16 @@ import org.zstack.header.host.HostNUMANode; import org.zstack.header.host.VmNicRedirectConfig; import org.zstack.header.log.NoLogging; -import org.zstack.header.vm.PriorityConfigStruct; -import org.zstack.header.vm.VmBootDevice; -import org.zstack.header.vm.VmPriorityConfigVO; +import org.zstack.header.vm.*; +import org.zstack.header.vm.devices.DeviceAddress; +import org.zstack.header.vm.devices.VirtualDeviceInfo; +import org.zstack.network.securitygroup.RuleTO; import org.zstack.network.securitygroup.SecurityGroupMembersTO; -import org.zstack.network.securitygroup.SecurityGroupRuleTO; -import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.network.securitygroup.VmNicSecurityTO; import java.io.Serializable; import java.util.*; +import java.util.stream.Collectors; public class KVMAgentCommands { public enum BootDev { @@ -34,7 +38,7 @@ public VmBootDevice toVmBootDevice() { } } - public static class AgentResponse implements ConditionalValidation { + public static class AgentResponse extends GrayUpgradeAgent implements ConditionalValidation { private boolean success = true; private String error; @@ -61,28 +65,71 @@ public boolean needValidation() { } } - public static class AgentCommand { + public static class AgentCommand extends GrayUpgradeAgent { public LinkedHashMap kvmHostAddons; } public static class CheckVmStateCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public List vmUuids; + @GrayVersion(value = "5.0.0") public String hostUuid; } public static class CheckVmStateRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") public Map states; } public static class UpdateVmPriorityCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public List priorityConfigStructs; } public static class UpdateVmPriorityRsp extends AgentResponse { } + public static class ChangeVmNicStateCommand extends AgentCommand { + @GrayVersion(value = "5.0.0") + private String vmUuid; + @GrayVersion(value = "5.0.0") + private String state; + @GrayVersion(value = "5.0.0") + private NicTO nic; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public NicTO getNic() { + return nic; + } + + public void setNic(NicTO nic) { + this.nic = nic; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + } + + public static class ChangeVmNicStateRsp extends AgentResponse { + + } + public static class DetachNicCommand extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private NicTO nic; public String getVmUuid() { @@ -107,8 +154,13 @@ public static class DetachNicRsp extends AgentResponse { } public static class AttachNicCommand extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private NicTO nic; + @GrayVersion(value = "5.0.0") + private String accountUuid; + @GrayVersion(value = "5.0.0") private Map addons = new HashMap(); public Map getAddons() { @@ -134,40 +186,38 @@ public NicTO getNic() { public void setNic(NicTO nic) { this.nic = nic; } - } - public static class PciAddressConfig { - public String type; - public String domain; - public String bus; - public String slot; - public String function; - - public static PciAddressConfig fromString(String address) { - return JSONObjectUtil.toObject(address, PciAddressConfig.class); + public String getAccountUuid() { + return accountUuid; } - public String toString() { - return JSONObjectUtil.toJsonString(this); + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; } } public static class AttachNicResponse extends AgentResponse { - private PciAddressConfig pciAddress; + @GrayVersion(value = "5.0.0") + List virtualDeviceInfoList; - public PciAddressConfig getPciAddress() { - return pciAddress; + public List getVirtualDeviceInfoList() { + return virtualDeviceInfoList; } - public void setPciAddress(PciAddressConfig pciAddress) { - this.pciAddress = pciAddress; + public void setVirtualDeviceInfoList(List virtualDeviceInfoList) { + this.virtualDeviceInfoList = virtualDeviceInfoList; } } public static class UpdateNicCmd extends AgentCommand implements VmAddOnsCmd { + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private List nics; + @GrayVersion(value = "5.0.0") private Map addons = new HashMap<>(); + @GrayVersion(value = "5.0.0") + private String accountUuid; public List getNics() { return nics; @@ -196,6 +246,14 @@ public String getVmInstanceUuid() { public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } } public static class UpdateNicRsp extends AgentResponse { @@ -209,8 +267,17 @@ public static class ConnectCmd extends AgentCommand { private boolean ignoreMsrs; private boolean pageTableExtensionDisabled; private int tcpServerPort; + private boolean isInstallHostShutdownHook; private String version; + public boolean isInstallHostShutdownHook() { + return isInstallHostShutdownHook; + } + + public void setInstallHostShutdownHook(boolean installHostShutdownHook) { + isInstallHostShutdownHook = installHostShutdownHook; + } + public boolean isIgnoreMsrs() { return ignoreMsrs; } @@ -271,15 +338,6 @@ public void setVersion(String version) { public static class ConnectResponse extends AgentResponse { private String libvirtVersion; private String qemuVersion; - private boolean iptablesSucc; - - public boolean isIptablesSucc() { - return iptablesSucc; - } - - public void setIptablesSucc(boolean iptablesSucc) { - this.iptablesSucc = iptablesSucc; - } public String getLibvirtVersion() { return libvirtVersion; @@ -300,6 +358,8 @@ public void setQemuVersion(String qemuVersion) { public static class PingCmd extends AgentCommand { public String hostUuid; + public long kvmagentPhysicalMemoryUsageAlarmThreshold; + public long kvmagentPhysicalMemoryUsageHardLimit; } public static class PingResponse extends AgentResponse { @@ -358,6 +418,7 @@ public static class UpdateHostConfigurationResponse extends AgentResponse { } public static class CheckPhysicalNetworkInterfaceCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List interfaceNames = new ArrayList<>(2); public CheckPhysicalNetworkInterfaceCmd addInterfaceName(String name) { @@ -375,6 +436,7 @@ public void setInterfaceNames(List interfaceNames) { } public static class CheckPhysicalNetworkInterfaceResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private List failedInterfaceNames; public List getFailedInterfaceNames() { @@ -393,21 +455,71 @@ public static class HostFactCmd extends AgentCommand { } public static class HostFactResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private String osDistribution; + @GrayVersion(value = "5.0.0") private String osVersion; + @GrayVersion(value = "5.0.0") private String osRelease; + @GrayVersion(value = "5.0.0") private String qemuImgVersion; + @GrayVersion(value = "5.0.0") private String libvirtVersion; + @GrayVersion(value = "5.0.0") + private String libvirtPackageVersion; + @GrayVersion(value = "5.0.0") private String hvmCpuFlag; + @GrayVersion(value = "5.0.0") private String eptFlag; + @GrayVersion(value = "5.0.0") private String cpuArchitecture; + @GrayVersion(value = "5.0.0") private String cpuModelName; + @GrayVersion(value = "5.0.0") private String cpuGHz; + @GrayVersion(value = "5.0.0") + private String cpuProcessorNum; + @GrayVersion(value = "5.0.0") + private String powerSupplyModelName; + @GrayVersion(value = "5.0.0") + private String powerSupplyManufacturer; + @GrayVersion(value = "5.0.0") + private String ipmiAddress; + @GrayVersion(value = "5.0.0") + private String powerSupplyMaxPowerCapacity; + @GrayVersion(value = "5.0.0") private String hostCpuModelName; + @GrayVersion(value = "5.0.0") private String systemProductName; + @GrayVersion(value = "5.0.0") private String systemSerialNumber; + @GrayVersion(value = "5.0.0") + private String systemManufacturer; + @GrayVersion(value = "5.0.0") + private String systemUUID; + @GrayVersion(value = "5.0.0") + private String biosVendor; + @GrayVersion(value = "5.0.0") + private String biosVersion; + @GrayVersion(value = "5.0.0") + private String biosReleaseDate; + @GrayVersion(value = "5.0.0") + private String bmcVersion; + @GrayVersion(value = "5.0.0") + private String uptime; + @GrayVersion(value = "5.0.0") + private String memorySlotsMaximum; + @GrayVersion(value = "5.0.0") + private String cpuCache; + @GrayVersion(value = "5.0.0") + private String deployMode; + @GrayVersion(value = "5.0.0") private List ipAddresses; + @GrayVersion(value = "5.0.0") private List libvirtCapabilities; + @GrayVersion(value = "5.0.0") + private VirtualizerInfoTO virtualizerInfo; + private String iscsiInitiatorName; public String getOsDistribution() { return osDistribution; @@ -445,6 +557,10 @@ public String getEptFlag() { return eptFlag; } + public void setEptFlag(String eptFlag) { + this.eptFlag = eptFlag; + } + public String getLibvirtVersion() { return libvirtVersion; } @@ -481,6 +597,58 @@ public String getCpuGHz() { return cpuGHz; } + public void setCpuGHz(String cpuGHz) { + this.cpuGHz = cpuGHz; + } + + public String getCpuProcessorNum() { + return cpuProcessorNum; + } + + public void setCpuProcessorNum(String cpuProcessorNum) { + this.cpuProcessorNum = cpuProcessorNum; + } + + public String getCpuCache() { + return cpuCache; + } + + public void setCpuCache (String cpuCache) { + this.cpuCache = cpuCache; + } + + + public String getPowerSupplyModelName() { + return powerSupplyModelName; + } + + public void setPowerSupplyModelName(String powerSupplyModelName) { + this.powerSupplyModelName = powerSupplyModelName; + } + + + public String getPowerSupplyManufacturer() { + return powerSupplyManufacturer; + } + + public void setPowerSupplyManufacturer(String powerSupplyManufacturer) { + this.powerSupplyManufacturer = powerSupplyManufacturer; + } + + public String getIpmiAddress() {return ipmiAddress;} + + public void setIpmiAddress(String ipmiAddress) { + this.ipmiAddress = ipmiAddress; + } + + public String getPowerSupplyMaxPowerCapacity() { + return powerSupplyMaxPowerCapacity; + } + + public void setPowerSupplyMaxPowerCapacity(String powerSupplyMaxPowerCapacity) { + this.powerSupplyMaxPowerCapacity = powerSupplyMaxPowerCapacity; + } + public String getCpuArchitecture() { return cpuArchitecture; } @@ -489,6 +657,10 @@ public String getHostCpuModelName() { return hostCpuModelName; } + public void setHostCpuModelName (String hostCpuModelName) { + this.hostCpuModelName = hostCpuModelName; + } + public String getSystemProductName() { return systemProductName; } @@ -512,18 +684,131 @@ public List getLibvirtCapabilities() { public void setLibvirtCapabilities(List libvirtCapabilities) { this.libvirtCapabilities = libvirtCapabilities; } + + public VirtualizerInfoTO getVirtualizerInfo() { + return virtualizerInfo; + } + + public void setVirtualizerInfo(VirtualizerInfoTO virtualizerInfo) { + this.virtualizerInfo = virtualizerInfo; + + } + + public String getSystemManufacturer() { + return systemManufacturer; + } + + public void setSystemManufacturer(String systemManufacturer) { + this.systemManufacturer = systemManufacturer; + } + + public String getSystemUUID() { + return systemUUID; + } + + public void setSystemUUID(String systemUUID) { + this.systemUUID = systemUUID; + } + + public String getBiosVendor() { + return biosVendor; + } + + public void setBiosVendor(String biosVendor) { + this.biosVendor = biosVendor; + } + + public String getBiosVersion() { + return biosVersion; + } + + public void setBiosVersion(String biosVersion) { + this.biosVersion = biosVersion; + } + + public String getBiosReleaseDate() { + return biosReleaseDate; + } + + public void setBiosReleaseDate(String biosReleaseDate) { + this.biosReleaseDate = biosReleaseDate; + } + + public String getBmcVersion() { + return bmcVersion; + } + + public void setBmcVersion(String bmcVersion) { + this.bmcVersion = bmcVersion; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + + public String getMemorySlotsMaximum() { + return memorySlotsMaximum; + } + + public void setMemorySlotsMaximum(String memorySlotsMaximum) { + this.memorySlotsMaximum = memorySlotsMaximum; + } + + public String getIscsiInitiatorName() { + return iscsiInitiatorName; + } + + public void setIscsiInitiatorName(String iscsiInitiatorName) { + this.iscsiInitiatorName = iscsiInitiatorName; + } + + public String getLibvirtPackageVersion() { + return libvirtPackageVersion; + } + + public void setLibvirtPackageVersion(String libvirtPackageVersion) { + this.libvirtPackageVersion = libvirtPackageVersion; + } + + public String getDeployMode() { + return deployMode; + } + + public void setDeployMode(String deployMode) { + this.deployMode = deployMode; + } } public static class HostCapacityCmd extends AgentCommand { } public static class HostCapacityResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private long cpuNum; + @GrayVersion(value = "5.0.0") private long cpuSpeed; + @GrayVersion(value = "5.0.0") private long usedCpu; + @GrayVersion(value = "5.0.0") private long totalMemory; + @GrayVersion(value = "5.0.0") private long usedMemory; + @GrayVersion(value = "5.0.0") private int cpuSockets; + @GrayVersion(value = "5.4.0") + private int cpuCoreNum; + + public int getCpuCoreNum() { + return cpuCoreNum; + } + + public void setCpuCoreNum(int cpuCoreNum) { + this.cpuCoreNum = cpuCoreNum; + } public int getCpuSockets() { return cpuSockets; @@ -575,8 +860,11 @@ public void setUsedMemory(long usedMemory) { } public static class DeleteBridgeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String physicalInterfaceName; + @GrayVersion(value = "5.0.0") private String bridgeName; + @GrayVersion(value = "5.0.0") private String l2NetworkUuid; public String getPhysicalInterfaceName() { @@ -608,11 +896,24 @@ public void setL2NetworkUuid(String l2NetworkUuid) { public static class CreateBridgeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String physicalInterfaceName; + @GrayVersion(value = "5.0.0") private String bridgeName; + @GrayVersion(value = "5.0.0") private String l2NetworkUuid; + @GrayVersion(value = "5.0.0") private Boolean disableIptables; + @GrayVersion(value = "5.0.0") private Integer mtu; + @GrayVersion(value = "5.0.0") + private Boolean isolated; + @GrayVersion(value = "5.0.0") + private String pvlan; + @GrayVersion(value = "5.3.0") + private Integer igmpVersion; + @GrayVersion(value = "5.3.0") + private Integer mldVersion; public String getL2NetworkUuid() { return l2NetworkUuid; @@ -653,16 +954,110 @@ public Integer getMtu() { public void setMtu(Integer mtu) { this.mtu = mtu; } + + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public String getPvlan() { + return pvlan; + } + + public void setPvlan(String pvlan) { + this.pvlan = pvlan; + } + + public Integer getIgmpVersion() { + return igmpVersion; + } + + public void setIgmpVersion(Integer igmpVersion) { + this.igmpVersion = igmpVersion; + } + + public Integer getMldVersion() { + return mldVersion; + } + + public void setMldVersion(Integer mldVersion) { + this.mldVersion = mldVersion; + } } public static class CreateBridgeResponse extends AgentResponse { } + public static class UpdateL2NetworkCmd extends AgentCommand { + private String physicalInterfaceName; + private String bridgeName; + private String newVlan; + private String oldVlan; + private String l2NetworkUuid; + private List peers; + + public String getPhysicalInterfaceName() { + return physicalInterfaceName; + } + + public void setPhysicalInterfaceName(String physicalInterfaceName) { + this.physicalInterfaceName = physicalInterfaceName; + } + + public String getBridgeName() { + return bridgeName; + } + + public void setBridgeName(String bridgeName) { + this.bridgeName = bridgeName; + } + + public String getNewVlan() { + return newVlan; + } + + public void setNewVlan(String newVlan) { + this.newVlan = newVlan; + } + + public String getOldVlan() { + return oldVlan; + } + + public void setOldVlan(String oldVlan) { + this.oldVlan = oldVlan; + } + + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public List getPeers() { + return peers; + } + + public void setPeers(List peers) { + this.peers = peers; + } + } + + public static class UpdateL2NetworkResponse extends AgentResponse { + } + public static class DeleteBridgeResponse extends AgentResponse { } public static class CheckBridgeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String physicalInterfaceName; + @GrayVersion(value = "5.0.0") private String bridgeName; public String getPhysicalInterfaceName() { @@ -686,6 +1081,7 @@ public static class CheckBridgeResponse extends AgentResponse { } public static class CheckVlanBridgeCmd extends CheckBridgeCmd { + @GrayVersion(value = "5.0.0") private int vlan; public int getVlan() { @@ -702,7 +1098,9 @@ public static class CheckVlanBridgeResponse extends CheckBridgeResponse { } public static class AddInterfaceToBridgeCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") private String physicalInterfaceName; + @GrayVersion(value = "5.0.0") private String bridgeName; public String getPhysicalInterfaceName() { @@ -726,6 +1124,7 @@ public static class AddInterfaceToBridgeResponse extends KVMAgentCommands.AgentR } public static class DeleteVlanBridgeCmd extends DeleteBridgeCmd { + @GrayVersion(value = "5.0.0") private int vlan; public int getVlan() { @@ -742,6 +1141,7 @@ public static class DeleteVlanBridgeResponse extends DeleteBridgeResponse { public static class CreateVlanBridgeCmd extends CreateBridgeCmd { + @GrayVersion(value = "5.0.0") private int vlan; public int getVlan() { @@ -786,7 +1186,7 @@ public void setTxBufferSize(String txBufferSize) { } } - public static class NicTO { + public static class NicTO extends BaseVirtualDeviceTO { private String mac; private List ips; private String bridgeName; @@ -801,12 +1201,23 @@ public static class NicTO { private Integer mtu; private String driverType; private VHostAddOn vHostAddOn; - private PciAddressConfig pci; + private DeviceAddress pci; private String type; + private String state; // only for vf nic private String vlanId; private String pciDeviceAddress; + // only for tf nic + private String ipForTf; + private String l2NetworkUuid; + + // for vDPA & dpdkvhostuserclient nic + private String srcPath; + + private Boolean cleanTraffic; + + private Boolean isolated; public List getIps() { return ips; @@ -928,11 +1339,11 @@ public void setvHostAddOn(VHostAddOn vHostAddOn) { this.vHostAddOn = vHostAddOn; } - public PciAddressConfig getPci() { + public DeviceAddress getPci() { return pci; } - public void setPci(PciAddressConfig pci) { + public void setPci(DeviceAddress pci) { this.pci = pci; } @@ -943,6 +1354,65 @@ public String getType() { public void setType(String type) { this.type = type; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getSrcPath() { + return srcPath; + } + + public void setSrcPath(String srcPath) { + this.srcPath = srcPath; + } + + public Boolean getCleanTraffic() { + return cleanTraffic; + } + + public void setCleanTraffic(Boolean cleanTraffic) { + this.cleanTraffic = cleanTraffic; + } + + public Boolean getIsolated() { + return isolated; + } + + public void setIsolated(Boolean isolated) { + this.isolated = isolated; + } + + public String getIpForTf() { + return ipForTf; + } + + public void setIpForTf(String ipForTf) { + this.ipForTf = ipForTf; + } + + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public static NicTO fromVmNicInventory(VmNicInventory nic) { + KVMAgentCommands.NicTO to = new KVMAgentCommands.NicTO(); + to.setMac(nic.getMac()); + to.setUuid(nic.getUuid()); + to.setDeviceId(nic.getDeviceId()); + to.setNicInternalName(nic.getInternalName()); + to.setType(nic.getType()); + + return to; + } } public static class VolumeSnapshotJobTO { @@ -1006,7 +1476,9 @@ public void setFull(String full) { } public static class DetachDataVolumeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private VolumeTO volume; + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; public VolumeTO getVolume() { @@ -1030,8 +1502,11 @@ public static class DetachDataVolumeResponse extends AgentResponse { } public static class AttachDataVolumeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private VolumeTO volume; + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private Map addons; public Map getAddons() { @@ -1063,23 +1538,37 @@ public void setVmUuid(String vmInstanceUuid) { } public static class AttachDataVolumeResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") + List virtualDeviceInfoList; + + public List getVirtualDeviceInfoList() { + return virtualDeviceInfoList; + } + + public void setVirtualDeviceInfoList(List virtualDeviceInfoList) { + this.virtualDeviceInfoList = virtualDeviceInfoList; + } } - public static class IsoTO { - private String path; - private String imageUuid; - private int deviceId; + public static class IsoTO extends BaseVirtualDeviceTO { + protected String path; + protected String imageUuid; + protected String primaryStorageUuid; + protected String protocol; + protected int deviceId; public IsoTO() { } public IsoTO(IsoTO other) { + this.resourceUuid = other.resourceUuid; this.path = other.path; this.imageUuid = other.imageUuid; this.deviceId = other.deviceId; + this.primaryStorageUuid = other.primaryStorageUuid; + this.protocol = other.protocol; } - public String getImageUuid() { return imageUuid; } @@ -1103,12 +1592,25 @@ public int getDeviceId() { public void setDeviceId(int deviceId) { this.deviceId = deviceId; } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return protocol; + } } - public static class CdRomTO { - private String path; - private String imageUuid; - private int deviceId; + public static class CdRomTO extends IsoTO { // unmounted iso private boolean isEmpty; private int bootOrder; @@ -1124,41 +1626,16 @@ public CdRomTO(CdRomTO other) { this.bootOrder = other.bootOrder; } - - public String getImageUuid() { - return imageUuid; + public boolean isEmpty() { + return isEmpty; } - public void setImageUuid(String imageUuid) { - this.imageUuid = imageUuid; + public void setEmpty(boolean empty) { + this.isEmpty = empty; } - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public int getDeviceId() { - return deviceId; - } - - public void setDeviceId(int deviceId) { - this.deviceId = deviceId; - } - - public boolean isEmpty() { - return isEmpty; - } - - public void setEmpty(boolean empty) { - this.isEmpty = empty; - } - - public int getBootOrder() { - return bootOrder; + public int getBootOrder() { + return bootOrder; } public void setBootOrder(int bootOrder) { @@ -1167,7 +1644,9 @@ public void setBootOrder(int bootOrder) { } public static class GenerateVdpaCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String vmUuid; + @GrayVersion(value = "5.0.0") public List nics; public String getVmUuid() { @@ -1188,6 +1667,7 @@ public void setNics(List nics) { } public static class GenerateVdpaResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") public List vdpaPaths; public List getVdpaPaths() { @@ -1200,7 +1680,9 @@ public void setVdpaPaths(List vdpaPaths) { } public static class DeleteVdpaCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String vmUuid; + @GrayVersion(value = "5.0.0") public String nicInternalName; public String getVmUuid() { @@ -1223,15 +1705,79 @@ public void setNicInternalName(String nicInternalName) { public static class DeleteVdpaRsp extends AgentResponse { } + public static class GenerateVHostUserClientCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String vmUuid; + @GrayVersion(value = "5.0.0") + public List nics; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public List getNics() { + return nics; + } + + public void setNics(List nics) { + this.nics = nics; + } + } + + public static class GenerateVHostUserClientResponse extends AgentResponse { + + } + + public static class DeleteVHostUserClientCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String vmUuid; + @GrayVersion(value = "5.0.0") + public String nicInternalName; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public String getNicInternalName() { + return nicInternalName; + } + + public void setNicInternalName(String nicInternalName) { + this.nicInternalName = nicInternalName; + } + } + + public static class DeleteVHostUserClientRsp extends AgentResponse { + + } + public static class CleanVmFirmwareFlashCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String vmUuid; + } + public static class HardenVmConsoleCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String vmUuid; + @GrayVersion(value = "5.0.0") public Long vmInternalId; + @GrayVersion(value = "5.0.0") public String hostManagementIp; } public static class DeleteVmConsoleFirewallCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String vmUuid; + @GrayVersion(value = "5.0.0") public Long vmInternalId; + @GrayVersion(value = "5.0.0") public String hostManagementIp; } @@ -1278,14 +1824,22 @@ public void setVmUuid(String vmUuid) { } public static class vdiCmd extends AgentCommand implements Serializable { + @GrayVersion(value = "5.0.0") private String consoleMode; + @GrayVersion(value = "5.0.0") private String videoType; + @GrayVersion(value = "5.0.0") private String soundType; + @GrayVersion(value = "5.0.0") private String spiceStreamingMode; + @GrayVersion(value = "5.0.0") private Integer VDIMonitorNumber; @NoLogging + @GrayVersion(value = "5.0.0") private String consolePassword; + @GrayVersion(value = "5.0.0") private Map qxlMemory; + @GrayVersion(value = "5.0.0") private List spiceChannels; public String getConsoleMode() { @@ -1354,8 +1908,11 @@ public void setSpiceChannels(List spiceChannels) { } public static class ConfigPrimaryVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List configs; + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private String hostIp; public String getVmInstanceUuid() { @@ -1384,12 +1941,19 @@ public void setHostIp(String hostIp) { } public static class RegisterPrimaryVmHeartbeatCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String hostUuid; + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private Integer heartbeatPort; + @GrayVersion(value = "5.0.0") private String targetHostIp; + @GrayVersion(value = "5.0.0") private boolean coloPrimary; + @GrayVersion(value = "5.0.0") private Integer redirectNum; + @GrayVersion(value = "5.0.0") private List volumes; public Integer getRedirectNum() { @@ -1450,13 +2014,21 @@ public void setVolumes(List volumes) { } public static class StartColoSyncCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private Integer blockReplicationPort; + @GrayVersion(value = "5.0.0") private Integer nbdServerPort; + @GrayVersion(value = "5.0.0") private String secondaryVmHostIp; + @GrayVersion(value = "5.0.0") private Long checkpointDelay; + @GrayVersion(value = "5.0.0") private boolean fullSync; + @GrayVersion(value = "5.0.0") private List volumes = new ArrayList<>(); + @GrayVersion(value = "5.0.0") private List nics = new ArrayList<>(); public String getVmInstanceUuid() { @@ -1525,10 +2097,15 @@ public void setNics(List nics) { } public static class ConfigSecondaryVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private Integer mirrorPort; + @GrayVersion(value = "5.0.0") private Integer secondaryInPort; + @GrayVersion(value = "5.0.0") private Integer nbdServerPort; + @GrayVersion(value = "5.0.0") private String primaryVmHostIp; public Integer getMirrorPort() { @@ -1573,62 +2150,196 @@ public void setNbdServerPort(Integer nbdServerPort) { } public static class StartVmCmd extends vdiCmd implements VmAddOnsCmd { + @GrayVersion(value = "5.0.0") + private String accountUuid; + @GrayVersion(value = "5.0.0") private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") private long vmInternalId; + @GrayVersion(value = "5.0.0") private String vmName; + @GrayVersion(value = "5.0.0") private String imagePlatform; + @GrayVersion(value = "5.0.0") private String imageArchitecture; + @GrayVersion(value = "5.0.0") private long memory; + @GrayVersion(value = "5.0.0") private long maxMemory; + @GrayVersion(value = "5.0.0") + private Long reservedMemory; + @GrayVersion(value = "5.0.0") private int cpuNum; + @GrayVersion(value = "5.0.0") + private int maxVcpuNum; + @GrayVersion(value = "5.0.0") private long cpuSpeed; - private int socketNum; - private int cpuOnSocket; + // cpu topology + @GrayVersion(value = "5.0.0") + private Integer socketNum; + @GrayVersion(value = "5.0.0") + private Integer cpuOnSocket; + // set thread per core default 1 to keep backward compatibility + @GrayVersion(value = "5.0.0") + private Integer threadsPerCore = 1; + @GrayVersion(value = "5.0.0") private List bootDev; + @GrayVersion(value = "5.0.0") private VolumeTO rootVolume; - private List bootIso = new ArrayList<>(); + @GrayVersion(value = "5.0.0") + private VirtualDeviceInfo memBalloon; + @GrayVersion(value = "5.0.0") private List cdRoms = new ArrayList<>(); + @GrayVersion(value = "5.0.0") private List dataVolumes; + @GrayVersion(value = "5.0.0") private List cacheVolumes; - private List Volumes; private List nics; + @GrayVersion(value = "5.0.0") private long timeout; + @GrayVersion(value = "5.0.0") private Map addons; + @GrayVersion(value = "5.0.0") private boolean instanceOfferingOnlineChange; + @GrayVersion(value = "5.0.0") private String nestedVirtualization; + @GrayVersion(value = "5.0.0") private String hostManagementIp; + @GrayVersion(value = "5.0.0") private String clock; + @GrayVersion(value = "5.0.0") private String clockTrack; + @GrayVersion(value = "5.0.0") private boolean useNuma; + @GrayVersion(value = "5.0.0") private String MemAccess; + @GrayVersion(value = "5.1.0") + private Boolean noSharePages; + @GrayVersion(value = "5.0.0") private boolean usbRedirect; + @GrayVersion(value = "5.0.0") + private boolean enableSecurityElement; + @GrayVersion(value = "5.0.0") private boolean useBootMenu; + @GrayVersion(value = "5.0.0") + private Integer bootMenuSplashTimeout; + @GrayVersion(value = "5.0.0") private boolean createPaused; + @GrayVersion(value = "5.0.0") private boolean kvmHiddenState; + @GrayVersion(value = "5.0.0") private boolean vmPortOff; + @GrayVersion(value = "5.0.0") private String vmCpuModel; + @GrayVersion(value = "5.0.0") private boolean emulateHyperV; + + // hyperv features + @GrayVersion(value = "5.0.0") + private boolean hypervClock; + @GrayVersion(value = "5.0.0") private String vendorId; + + // suspend features + @GrayVersion(value = "5.0.0") + private boolean suspendToRam; + @GrayVersion(value = "5.0.0") + private boolean suspendToDisk; + + @GrayVersion(value = "5.0.0") private boolean additionalQmp; + @GrayVersion(value = "5.0.0") private boolean isApplianceVm; + @GrayVersion(value = "5.0.0") private String systemSerialNumber; + @GrayVersion(value = "5.0.0") private String bootMode; + // used when bootMode == 'UEFI' + @GrayVersion(value = "5.0.0") + private boolean secureBoot; + @GrayVersion(value = "5.0.0") private boolean fromForeignHypervisor; + @GrayVersion(value = "5.0.0") private String machineType; + @GrayVersion(value = "5.0.0") private Integer pciePortNums; + @GrayVersion(value = "5.0.0") private Integer predefinedPciBridgeNum; + @GrayVersion(value = "5.0.0") private boolean useHugePage; + @GrayVersion(value = "5.0.0") private String chassisAssetTag; + @GrayVersion(value = "5.0.0") private PriorityConfigStruct priorityConfigStruct; + @GrayVersion(value = "5.0.0") private String memorySnapshotPath; + @GrayVersion(value = "5.0.0") private boolean coloPrimary; + @GrayVersion(value = "5.0.0") private boolean coloSecondary; + @GrayVersion(value = "5.0.0") private boolean consoleLogToFile; + @GrayVersion(value = "5.0.0") private boolean acpi; - private boolean hygonCpu; + @GrayVersion(value = "5.0.0") + private boolean x2apic = true; + // cpuid hypervisor feature + @GrayVersion(value = "5.0.0") + private boolean cpuHypervisorFeature = true; + @GrayVersion(value = "5.0.0") + private List oemStrings = new ArrayList<>(); // TODO: only for test + @GrayVersion(value = "5.0.0") private boolean useColoBinary; + @GrayVersion(value = "5.0.0") + private String vmCpuVendorId; + @GrayVersion(value = "5.0.0") + private Boolean qemu64BitPciMmioSetup; + + public Boolean getQemu64BitPciMmioSetup() { + return qemu64BitPciMmioSetup; + } + + public void setQemu64BitPciMmioSetup(Boolean qemu64BitPciMmioSetup) { + this.qemu64BitPciMmioSetup = qemu64BitPciMmioSetup; + } + + public void setSocketNum(Integer socketNum) { + this.socketNum = socketNum; + } + + public void setCpuOnSocket(Integer cpuOnSocket) { + this.cpuOnSocket = cpuOnSocket; + } + + public void setThreadsPerCore(Integer threadsPerCore) { + this.threadsPerCore = threadsPerCore; + } + + public int getMaxVcpuNum() { + return maxVcpuNum; + } + + public void setMaxVcpuNum(int maxVcpuNum) { + this.maxVcpuNum = maxVcpuNum; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public List getOemStrings() { + return oemStrings; + } + + public void setOemStrings(List oemStrings) { + this.oemStrings = oemStrings.stream().distinct().collect(Collectors.toList());; + } public String getChassisAssetTag() { return chassisAssetTag; @@ -1694,6 +2405,14 @@ public void setBootMode(String bootMode) { this.bootMode = bootMode; } + public boolean isSecureBoot() { + return secureBoot; + } + + public void setSecureBoot(boolean secureBoot) { + this.secureBoot = secureBoot; + } + public boolean isEmulateHyperV() { return emulateHyperV; } @@ -1750,6 +2469,14 @@ public boolean isUseBootMenu() { return useBootMenu; } + public Integer getBootMenuSplashTimeout() { + return bootMenuSplashTimeout; + } + + public void setBootMenuSplashTimeout(Integer bootMenuSplashTimeout) { + this.bootMenuSplashTimeout = bootMenuSplashTimeout; + } + public void setCreatePaused(boolean createPaused) { this.createPaused = createPaused; } @@ -1766,6 +2493,13 @@ public void setUsbRedirect(boolean usbRedirect) { this.usbRedirect = usbRedirect; } + public boolean isEnableSecurityElement() { + return enableSecurityElement; + } + + public void setEnableSecurityElement(boolean enableSecurityElement) { + this.enableSecurityElement = enableSecurityElement; + } public boolean isUseNuma() { return useNuma; } @@ -1782,6 +2516,14 @@ public void setMemAccess(String memAccess) { MemAccess = memAccess; } + public Boolean getNoSharePages() { + return noSharePages; + } + + public void setNoSharePages(Boolean noSharePages) { + this.noSharePages = noSharePages; + } + public long getMaxMemory() { return maxMemory; } @@ -1790,6 +2532,14 @@ public void setMaxMemory(long maxMemory) { this.maxMemory = maxMemory; } + public Long getReservedMemory() { + return reservedMemory; + } + + public void setReservedMemory(Long reservedMemory) { + this.reservedMemory = reservedMemory; + } + public String getClock() { return clock; } @@ -1806,7 +2556,7 @@ public void setClockTrack(String clockTrack) { this.clockTrack = clockTrack; } - public int getSocketNum() { + public Integer getSocketNum() { return socketNum; } @@ -1814,7 +2564,7 @@ public void setSocketNum(int socketNum) { this.socketNum = socketNum; } - public int getCpuOnSocket() { + public Integer getCpuOnSocket() { return cpuOnSocket; } @@ -1822,6 +2572,14 @@ public void setCpuOnSocket(int cpuOnSocket) { this.cpuOnSocket = cpuOnSocket; } + public Integer getThreadsPerCore() { + return threadsPerCore; + } + + public void setThreadsPerCore(int threadsPerCore) { + this.threadsPerCore = threadsPerCore; + } + public String getVmName() { return vmName; } @@ -1886,16 +2644,6 @@ public void setInstanceOfferingOnlineChange(boolean instanceOfferingOnlineChange this.instanceOfferingOnlineChange = instanceOfferingOnlineChange; } - @Deprecated - public List getBootIso() { - return bootIso; - } - - @Deprecated - public void setBootIso(List bootIso) { - this.bootIso = bootIso; - } - public List getCdRoms() { return cdRoms; } @@ -1928,6 +2676,14 @@ public void setRootVolume(VolumeTO rootVolume) { this.rootVolume = rootVolume; } + public VirtualDeviceInfo getMemBalloon() { + return memBalloon; + } + + public void setMemBalloon(VirtualDeviceInfo memBalloon) { + this.memBalloon = memBalloon; + } + public List getDataVolumes() { return dataVolumes; } @@ -2025,14 +2781,6 @@ public void setConsoleLogToFile(boolean consoleLogToFile) { this.consoleLogToFile = consoleLogToFile; } - public boolean getHygonCpu() { - return hygonCpu; - } - - public void setHygonCpu(boolean hygonCpu) { - this.hygonCpu = hygonCpu; - } - public boolean getAcpi() { return acpi; } @@ -2041,6 +2789,30 @@ public void setAcpi(boolean acpi) { this.acpi = acpi; } + public boolean getX2apic() { + return x2apic; + } + + public void setX2apic(boolean x2apic) { + this.x2apic = x2apic; + } + + public boolean isCpuHypervisorFeature() { + return cpuHypervisorFeature; + } + + public void setCpuHypervisorFeature(boolean cpuHypervisorFeature) { + this.cpuHypervisorFeature = cpuHypervisorFeature; + } + + public boolean isHypervClock() { + return hypervClock; + } + + public void setHypervClock(boolean hypervClock) { + this.hypervClock = hypervClock; + } + public String getVendorId() { return vendorId; } @@ -2049,6 +2821,22 @@ public void setVendorId(String vendorId) { this.vendorId = vendorId; } + public boolean isSuspendToRam() { + return suspendToRam; + } + + public void setSuspendToRam(boolean suspendToRam) { + this.suspendToRam = suspendToRam; + } + + public boolean isSuspendToDisk() { + return suspendToDisk; + } + + public void setSuspendToDisk(boolean suspendToDisk) { + this.suspendToDisk = suspendToDisk; + } + @Override public Map getAddons() { if (addons == null) { @@ -2060,10 +2848,36 @@ public Map getAddons() { public void setAddons(Map addons) { this.addons = addons; } + + public String getVmCpuVendorId() { + return vmCpuVendorId; + } + + public void setVmCpuVendorId(String vmCpuVendorId) { + this.vmCpuVendorId = vmCpuVendorId; + } + } + + public static class StartVmResponse extends VmDevicesInfoResponse { } - public static class StartVmResponse extends AgentResponse { + public static class VmDevicesInfoResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private List nicInfos; + @GrayVersion(value = "5.0.0") + private List virtualDeviceInfoList; + @GrayVersion(value = "5.0.0") + private VirtualDeviceInfo memBalloonInfo; + @GrayVersion(value = "5.0.0") + private VirtualizerInfoTO virtualizerInfo; + + public VirtualDeviceInfo getMemBalloonInfo() { + return memBalloonInfo; + } + + public void setMemBalloonInfo(VirtualDeviceInfo memBalloonInfo) { + this.memBalloonInfo = memBalloonInfo; + } public List getNicInfos() { return nicInfos; @@ -2072,11 +2886,43 @@ public List getNicInfos() { public void setNicInfos(List nicInfos) { this.nicInfos = nicInfos; } + + public List getVirtualDeviceInfoList() { + return virtualDeviceInfoList; + } + + public void setVirtualDeviceInfoList(List virtualDeviceInfoList) { + this.virtualDeviceInfoList = virtualDeviceInfoList; + } + + public VirtualizerInfoTO getVirtualizerInfo() { + return virtualizerInfo; + } + + public void setVirtualizerInfo(VirtualizerInfoTO virtualizerInfo) { + this.virtualizerInfo = virtualizerInfo; + } + } + + public static class SyncVmDeviceInfoCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private String vmInstanceUuid; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + } + + public static class SyncVmDeviceInfoResponse extends VmDevicesInfoResponse { } public static class VmNicInfo { private String macAddress; - private PciAddressConfig pciInfo; + private DeviceAddress deviceAddress; public String getMacAddress() { return macAddress; @@ -2086,19 +2932,21 @@ public void setMacAddress(String macAddress) { this.macAddress = macAddress; } - public PciAddressConfig getPciInfo() { - return pciInfo; + public DeviceAddress getDeviceAddress() { + return deviceAddress; } - public void setPciInfo(PciAddressConfig pciInfo) { - this.pciInfo = pciInfo; + public void setDeviceAddress(DeviceAddress deviceAddress) { + this.deviceAddress = deviceAddress; } } - public static class ChangeCpuMemoryCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private int cpuNum; + @GrayVersion(value = "5.0.0") private long memorySize; public void setVmUuid(String vmUuid) { @@ -2127,7 +2975,9 @@ public long getMemorySize() { } public static class ChangeCpuMemoryResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private int cpuNum; + @GrayVersion(value = "5.0.0") private long memorySize; public void setCpuNum(int cpuNum) { @@ -2148,7 +2998,9 @@ public long getMemorySize() { } public static class IncreaseCpuCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private int cpuNum; public void setVmUuid(String vmUuid) { @@ -2169,6 +3021,7 @@ public int getCpuNum() { } public static class IncreaseCpuResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private int cpuNum; public void setCpuNum(int cpuNum) { @@ -2181,7 +3034,9 @@ public int getCpuNum() { } public static class IncreaseMemoryCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private long memorySize; public void setVmUuid(String vmUuid) { @@ -2202,6 +3057,7 @@ public long getMemorySize() { } public static class IncreaseMemoryResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private long memorySize; public void setMemorySize(long memorySize) { @@ -2214,8 +3070,11 @@ public long getMemorySize() { } public static class ScanVmPortCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String ip; + @GrayVersion(value = "5.0.0") private String brname; + @GrayVersion(value = "5.0.0") private int port; public String getIp() { @@ -2244,6 +3103,7 @@ public void setBrname(String brname) { } public static class ScanVmPortResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private Map portStatus; public Map getPortStatus() { @@ -2256,6 +3116,7 @@ public void setPortStatus(Map portStatus) { } public static class GetVncPortCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; public String getVmUuid() { @@ -2268,10 +3129,15 @@ public void setVmUuid(String vmUuid) { } public static class GetVncPortResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private int port; + @GrayVersion(value = "5.0.0") private String protocol; + @GrayVersion(value = "5.0.0") private Integer vncPort; + @GrayVersion(value = "5.0.0") private Integer spicePort; + @GrayVersion(value = "5.0.0") private Integer spiceTlsPort; public int getPort() { @@ -2316,9 +3182,13 @@ public void setSpiceTlsPort(Integer spiceTlsPort) { } public static class StopVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") private String type; + @GrayVersion(value = "5.0.0") private long timeout; + private List vmNics; public String getUuid() { return uuid; @@ -2343,13 +3213,23 @@ public String getType() { public void setType(String type) { this.type = type; } + + public List getVmNics() { + return vmNics; + } + + public void setVmNics(List vmNics) { + this.vmNics = vmNics; + } } public static class StopVmResponse extends AgentResponse { } public static class PauseVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") private long timeout; public String getUuid() { @@ -2374,7 +3254,9 @@ public static class PauseVmResponse extends AgentResponse { } public static class ResumeVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") private long timeout; public String getUuid() { @@ -2399,8 +3281,11 @@ public static class ResumeVmResponse extends AgentResponse { } public static class RebootVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") private long timeout; + @GrayVersion(value = "5.0.0") private List bootDev; public List getBootDev() { @@ -2429,10 +3314,23 @@ public void setTimeout(long timeout) { } public static class RebootVmResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") + private VirtualizerInfoTO virtualizerInfo; + + public VirtualizerInfoTO getVirtualizerInfo() { + return virtualizerInfo; + } + + public void setVirtualizerInfo(VirtualizerInfoTO virtualizerInfo) { + this.virtualizerInfo = virtualizerInfo; + } } public static class DestroyVmCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") + private List vmNics; public String getUuid() { return uuid; @@ -2441,12 +3339,22 @@ public String getUuid() { public void setUuid(String uuid) { this.uuid = uuid; } + + public List getVmNics() { + return vmNics; + } + + public void setVmNics(List vmNics) { + this.vmNics = vmNics; + } + } public static class DestroyVmResponse extends AgentResponse { } public static class GetVmFirstBootDeviceCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; public String getUuid() { @@ -2459,6 +3367,7 @@ public void setUuid(String uuid) { } public static class GetVmFirstBootDeviceResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private String firstBootDevice; public String getFirstBootDevice() { @@ -2471,7 +3380,9 @@ public void setFirstBootDevice(String firstBootDevice) { } public static class GetVmDeviceAddressCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") private Map deviceTOs = new HashMap<>(); public void setUuid(String uuid) { @@ -2496,6 +3407,7 @@ public void setDeviceTOs(Map deviceTOs) { } public static class GetVmDeviceAddressRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") private Map> addresses; public Map> getAddresses() { @@ -2511,6 +3423,72 @@ public void setAddresses(Map> addresses) { } } + public static class GetVirtualizerInfoCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private List vmUuids; + + public List getVmUuids() { + return vmUuids; + } + + public void setVmUuids(List vmUuids) { + this.vmUuids = vmUuids; + } + } + + public static class GetVirtualizerInfoRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") + private VirtualizerInfoTO hostInfo; + @GrayVersion(value = "5.0.0") + private List vmInfoList; + + public VirtualizerInfoTO getHostInfo() { + return hostInfo; + } + + public void setHostInfo(VirtualizerInfoTO hostInfo) { + this.hostInfo = hostInfo; + } + + public List getVmInfoList() { + return vmInfoList; + } + + public void setVmInfoList(List vmInfoList) { + this.vmInfoList = vmInfoList; + } + } + + public static class VirtualizerInfoTO { + private String uuid; + private String virtualizer; + private String version; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setVirtualizer(String virtualizer) { + this.virtualizer = virtualizer; + } + + public String getVirtualizer() { + return virtualizer; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getVersion() { + return version; + } + } + public static class VmDeviceAddressTO { private String addressType; private String address; @@ -2554,8 +3532,9 @@ public static class VmSyncCmd extends AgentCommand { } public static class VmSyncResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private HashMap states; - + @GrayVersion(value = "5.0.0") private List vmInShutdowns; public HashMap getStates() { @@ -2575,39 +3554,85 @@ public void setVmInShutdowns(List vmInShutdowns) { } } - public static class RefreshAllRulesOnHostCmd extends AgentCommand { - private List ruleTOs; - private List ipv6RuleTOs; + public static class VolumeSyncCmd extends AgentCommand { + private List storagePaths; - public List getRuleTOs() { - return ruleTOs; + public void setStoragePaths(List storagePaths) { + this.storagePaths = storagePaths; } - public void setRuleTOs(List ruleTOs) { - this.ruleTOs = ruleTOs; + public List getStoragePaths() { + return storagePaths; } + } + + public static class VolumeSyncRsp extends AgentResponse { + private Map> inactiveVolumePaths; - public List getIpv6RuleTOs() { - return ipv6RuleTOs; + public void setInactiveVolumePaths(Map> inactiveVolumePaths) { + this.inactiveVolumePaths = inactiveVolumePaths; } - public void setIpv6RuleTOs(List ipv6RuleTOs) { - this.ipv6RuleTOs = ipv6RuleTOs; + public Map> getInactiveVolumePaths() { + return inactiveVolumePaths; } } - public static class RefreshAllRulesOnHostResponse extends AgentResponse { - } + public static class RefreshAllRulesOnHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private List vmNicTOs; + @GrayVersion(value = "5.0.0") + private Map> ruleTOs; + @GrayVersion(value = "5.0.0") + private Map> ip6RuleTOs; - public static class CheckDefaultSecurityGroupCmd extends AgentCommand { - Boolean skipIpv6; - } + public RefreshAllRulesOnHostCmd() { + vmNicTOs = new ArrayList(); + ruleTOs = new HashMap>(); + ip6RuleTOs = new HashMap>(); + } - public static class CheckDefaultSecurityGroupResponse extends AgentResponse { + public List getVmNicTOs() { + return vmNicTOs; + } - } + public void setVmNicTOs(List vmNicTOs) { + this.vmNicTOs = vmNicTOs; + } - public static class UpdateGroupMemberCmd extends AgentCommand { + public Map> getRuleTOs() { + return ruleTOs; + } + + public void setRuleTOs(Map> ruleTOs) { + this.ruleTOs = ruleTOs; + } + + public Map> getIp6RuleTOs() { + return ip6RuleTOs; + } + + public void setIp6RuleTOs(Map> ip6RuleTOs) { + this.ip6RuleTOs = ip6RuleTOs; + } + } + + public static class RefreshAllRulesOnHostResponse extends AgentResponse { + } + + public static class CheckDefaultSecurityGroupCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + Boolean skipIpv6; + @GrayVersion(value = "5.3.0") + Boolean disableIp6Tables; + } + + public static class CheckDefaultSecurityGroupResponse extends AgentResponse { + + } + + public static class UpdateGroupMemberCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List updateGroupTOs; public void setUpdateGroupTOs(List updateGroupTOs) { @@ -2623,7 +3648,10 @@ public static class UpdateGroupMemberResponse extends AgentResponse { } public static class CleanupUnusedRulesOnHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") Boolean skipIpv6; + @GrayVersion(value = "5.3.0") + Boolean disableIp6Tables; } public static class CleanupUnusedRulesOnHostResponse extends AgentResponse { @@ -2631,23 +3659,41 @@ public static class CleanupUnusedRulesOnHostResponse extends AgentResponse { public static class ApplySecurityGroupRuleCmd extends AgentCommand { - private List ruleTOs; - private List ipv6RuleTOs; + @GrayVersion(value = "5.0.0") + private List vmNicTOs; + @GrayVersion(value = "5.0.0") + private Map> ruleTOs; + @GrayVersion(value = "5.0.0") + private Map> ip6RuleTOs; + + public ApplySecurityGroupRuleCmd() { + vmNicTOs = new ArrayList(); + ruleTOs = new HashMap>(); + ip6RuleTOs = new HashMap>(); + } - public List getRuleTOs() { + public List getVmNicTOs() { + return vmNicTOs; + } + + public void setVmNicTOs(List vmNicTOs) { + this.vmNicTOs = vmNicTOs; + } + + public Map> getRuleTOs() { return ruleTOs; } - public void setRuleTOs(List ruleTOs) { + public void setRuleTOs(Map> ruleTOs) { this.ruleTOs = ruleTOs; } - public List getIpv6RuleTOs() { - return ipv6RuleTOs; + public Map> getIp6RuleTOs() { + return ip6RuleTOs; } - public void setIpv6RuleTOs(List ipv6RuleTOs) { - this.ipv6RuleTOs = ipv6RuleTOs; + public void setIp6RuleTOs(Map> ip6RuleTOs) { + this.ip6RuleTOs = ip6RuleTOs; } } @@ -2655,16 +3701,52 @@ public static class ApplySecurityGroupRuleResponse extends AgentResponse { } public static class MigrateVmCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private String destHostIp; + @GrayVersion(value = "5.0.0") + private String destHostManagementIp; + @GrayVersion(value = "5.0.0") private String storageMigrationPolicy; + @GrayVersion(value = "5.0.0") private String srcHostIp; + @GrayVersion(value = "5.0.0") private boolean useNuma; + @GrayVersion(value = "5.0.0") private boolean migrateFromDestination; + @GrayVersion(value = "5.0.0") private boolean autoConverge; + @GrayVersion(value = "5.0.0") + private Integer downTime; + @GrayVersion(value = "5.0.0") private boolean xbzrle; + @GrayVersion(value = "5.0.0") private List vdpaPaths; - private Long timeout; // in seconds + @GrayVersion(value = "5.0.0") + private List nics; + @GrayVersion(value = "5.0.0") + private Map disks; // A map from old install path to new volume + @GrayVersion(value = "5.0.0") + private boolean reload; + @GrayVersion(value = "5.0.0") + private long bandwidth; + + public Integer getDownTime() { + return downTime; + } + + public void setDownTime(Integer downTime) { + this.downTime = downTime; + } + + public boolean isReload() { + return reload; + } + + public void setReload(boolean reload) { + this.reload = reload; + } public boolean isUseNuma() { return useNuma; @@ -2738,29 +3820,117 @@ public void setVdpaPaths(List vdpaPaths) { this.vdpaPaths = vdpaPaths; } - public Long getTimeout() { - return timeout; + public Map getDisks() { + return disks; } - public void setTimeout(Long timeout) { - this.timeout = timeout; + public void setDisks(Map disks) { + this.disks = disks; + } + + public String getDestHostManagementIp() { + return destHostManagementIp; + } + + public void setDestHostManagementIp(String destHostManagementIp) { + this.destHostManagementIp = destHostManagementIp; + } + + public long getBandwidth() { + return bandwidth; + } + + public void setBandwidth(long bandwidth) { + this.bandwidth = bandwidth; + } + + public List getNics() { + return nics; + } + + public void setNics(List nics) { + this.nics = nics; } } public static class MigrateVmResponse extends AgentResponse { } + public static class VmGetCpuXmlCmd extends AgentCommand{ + } + + public static class VmGetCpuXmlResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") + private String cpuXml; + @GrayVersion(value = "5.0.0") + private String cpuModelName; + + public String getCpuModelName() { + return cpuModelName; + } + + public void setCpuModelName(String cpuModelName) { + this.cpuModelName = cpuModelName; + } + + public String getCpuXml() { + return cpuXml; + } + + public void setCpuXml(String cpuXml) { + this.cpuXml = cpuXml; + } + } + + public static class VmCompareCpuFunctionCmd extends AgentCommand{ + @GrayVersion(value = "5.0.0") + private String cpuXml; + + public String getCpuXml() { + return cpuXml; + } + + public void setCpuXml(String cpuXml) { + this.cpuXml = cpuXml; + } + } + + public static class VmCompareCpuFunctionResponse extends AgentResponse { + private boolean match = true; + private String compareError; + + public boolean isMatch() { + return match; + } + + public void setMatch(boolean match) { + this.match = match; + } + + public String getCompareError() { + return compareError; + } + + public void setCompareError(String compareError) { + this.compareError = compareError; + } + } + public static class MergeSnapshotRsp extends AgentResponse { + public long size; } - public static class MergeSnapshotCmd extends AgentCommand { + public static class MergeSnapshotCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private VolumeTO volume; + @GrayVersion(value = "5.0.0") private String srcPath; + @GrayVersion(value = "5.0.0") private String destPath; + @GrayVersion(value = "5.0.0") private boolean fullRebase; - // timeout seconds - private long timeout; public boolean isFullRebase() { return fullRebase; @@ -2801,21 +3971,18 @@ public VolumeTO getVolume() { public void setVolume(VolumeTO volume) { this.volume = volume; } - - public long getTimeout() { - return timeout; - } - - public void setTimeout(long timeout) { - this.timeout = timeout; - } } public static class CheckSnapshotCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private String currentInstallPath; + @GrayVersion(value = "5.0.0") private List excludeInstallPaths; + @GrayVersion(value = "5.0.0") private Map volumeChainToCheck; public String getVmUuid() { @@ -2859,20 +4026,153 @@ public void setExcludeInstallPaths(List excludeInstallPaths) { } } - public static class TakeSnapshotCmd extends AgentCommand { + public static class BlockCommitCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String vmUuid; + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private VolumeTO volume; + @GrayVersion(value = "5.0.0") + private String top; + @GrayVersion(value = "5.0.0") + private String base; + @GrayVersion(value = "5.4.0") + private List topChildrenInstallPathInDb = new ArrayList<>(); + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public VolumeTO getVolume() { + return volume; + } + + public void setVolume(VolumeTO volume) { + this.volume = volume; + } + + public String getTop() { + return top; + } + + public void setTop(String top) { + this.top = top; + } + + public String getBase() { + return base; + } + + public void setBase(String base) { + this.base = base; + } + + public List getTopChildrenInstallPathInDb() { + return topChildrenInstallPathInDb; + } + + public void setTopChildrenInstallPathInDb(List topChildrenInstallPathInDb) { + this.topChildrenInstallPathInDb = topChildrenInstallPathInDb; + } + } + + public static class BlockCommitResponse extends AgentResponse { + @Validation(notZero = true) + @GrayVersion(value = "5.0.0") + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + } + + public static class BlockPullCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.4.0") + private String vmUuid; + @GrayVersion(value = "5.4.0") + private VolumeTO volume; + @GrayVersion(value = "5.4.0") + private String base; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + + public VolumeTO getVolume() { + return volume; + } + + public void setVolume(VolumeTO volume) { + this.volume = volume; + } + + public String getBase() { + return base; + } + + public void setBase(String base) { + this.base = base; + } + } + + public static class BlockPullResponse extends AgentResponse { + @GrayVersion(value = "5.4.0") + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + } + + public static class TakeSnapshotCmd extends PrimaryStorageCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") + private String vmUuid; + @GrayVersion(value = "5.0.0") + private String volumeUuid; + @GrayVersion(value = "5.0.0") + private VolumeTO volume; + @GrayVersion(value = "5.0.0") private String installPath; + @GrayVersion(value = "5.0.0") private boolean fullSnapshot; + @GrayVersion(value = "5.0.0") private String volumeInstallPath; + @GrayVersion(value = "5.0.0") private String newVolumeUuid; + @GrayVersion(value = "5.0.0") private String newVolumeInstallPath; + @GrayVersion(value = "5.0.0") + private boolean online; + @GrayVersion(value = "5.0.0") + private long timeout; // for baremetal2 instance private boolean isBaremetal2InstanceOnlineSnapshot; - private long timeout; + public boolean isOnline() { + return online; + } + + public void setOnline(boolean online) { + this.online = online; + } public String getVolumeUuid() { return volumeUuid; @@ -2961,10 +4261,13 @@ public static class CheckSnapshotResponse extends AgentResponse { public static class TakeSnapshotResponse extends AgentResponse { @Validation + @GrayVersion(value = "5.0.0") private String newVolumeInstallPath; @Validation + @GrayVersion(value = "5.0.0") private String snapshotInstallPath; @Validation(notZero = true) + @GrayVersion(value = "5.0.0") private long size; public long getSize() { @@ -2993,8 +4296,11 @@ public void setNewVolumeInstallPath(String newVolumeInstallPath) { } public static class LogoutIscsiTargetCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String hostname; + @GrayVersion(value = "5.0.0") private int port; + @GrayVersion(value = "5.0.0") private String target; public String getHostname() { @@ -3026,11 +4332,18 @@ public static class LogoutIscsiTargetRsp extends AgentResponse { } public static class LoginIscsiTargetCmd extends AgentCommand implements Serializable { + @GrayVersion(value = "5.0.0") + private String url; + @GrayVersion(value = "5.0.0") private String hostname; + @GrayVersion(value = "5.0.0") private int port; + @GrayVersion(value = "5.0.0") private String target; + @GrayVersion(value = "5.0.0") private String chapUsername; @NoLogging + @GrayVersion(value = "5.0.0") private String chapPassword; public String getChapUsername() { @@ -3072,13 +4385,23 @@ public String getTarget() { public void setTarget(String target) { this.target = target; } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } } public static class LoginIscsiTargetRsp extends AgentResponse { } public static class AttachIsoCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public IsoTO iso; + @GrayVersion(value = "5.0.0") public String vmUuid; } @@ -3086,8 +4409,11 @@ public static class AttachIsoRsp extends AgentResponse { } public static class DetachIsoCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String vmUuid; + @GrayVersion(value = "5.0.0") public String isoUuid; + @GrayVersion(value = "5.0.0") public int deviceId; } @@ -3096,21 +4422,40 @@ public static class DetachIsoRsp extends AgentResponse { } public static class UpdateHostOSCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String hostUuid; + @GrayVersion(value = "5.0.0") public String excludePackages; + @GrayVersion(value = "5.0.0") public String updatePackages; + @GrayVersion(value = "5.0.0") public String releaseVersion; + @GrayVersion(value = "5.0.0") public boolean enableExpRepo; } public static class UpdateHostOSRsp extends AgentResponse { + public String libvirtVersion; + + public String getLibvirtVersion() { + return libvirtVersion; + } + + public void setLibvirtVersion(String libvirtVersion) { + this.libvirtVersion = libvirtVersion; + } } public static class UpdateDependencyCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String hostUuid; + @GrayVersion(value = "5.0.0") public boolean enableExpRepo; + @GrayVersion(value = "5.0.0") public String excludePackages; + @GrayVersion(value = "5.0.0") public String updatePackages; + @GrayVersion(value = "5.0.0") public String zstackRepo; } @@ -3166,29 +4511,66 @@ public static class ReportVmRebootEventCmd { public String vmUuid; } + public static class ReportVmStartEventCmd { + public String vmUuid; + } + public static class ReportVmCrashEventCmd { public String vmUuid; } + public static class ReportHostStopEventCmd { + public String hostUuid; + } + public static class ShutdownHostCmd extends AgentCommand { } + public static class RebootHostCmd extends AgentCommand { + } + public static class ShutdownHostResponse extends AgentResponse { } + public static class RebootHostResponse extends AgentResponse { + } + public static class UpdateSpiceChannelConfigCmd extends AgentCommand { } public static class UpdateSpiceChannelConfigResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") public boolean restartLibvirt = false; } public static class PrimaryStorageCommand extends AgentCommand { + @GrayVersion(value = "5.0.0") public String primaryStorageUuid; } public static class CancelCmd extends AgentCommand implements CancelCommand { + @GrayVersion(value = "5.0.0") private String cancellationApiId; + @GrayVersion(value = "5.0.0") + private Integer times; + @GrayVersion(value = "5.0.0") + private Integer interval; + + public Integer getTimes() { + return times; + } + + public void setTimes(Integer times) { + this.times = times; + } + + public Integer getInterval() { + return interval; + } + + public void setInterval(Integer interval) { + this.interval = interval; + } @Override public void setCancellationApiId(String cancellationApiId) { @@ -3205,25 +4587,33 @@ public static class TransmitVmOperationToMnCmd { } public static class GetDevCapacityCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String dirPath; } public static class GetDevCapacityResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") public long totalSize; + @GrayVersion(value = "5.0.0") public long availableSize; + @GrayVersion(value = "5.0.0") public long dirSize; } public static class CheckFileOnHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public Set paths; + @GrayVersion(value = "5.0.0") public boolean md5Return; } public static class CheckFileOnHostResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") public Map existPaths; } public static class GetHostNUMATopologyCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String HostUuid; public void setHostUuid(String hostUuid) { @@ -3236,6 +4626,7 @@ public String getHostUuid() { } public static class GetHostNUMATopologyResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") public Map topology; @@ -3295,4 +4686,358 @@ public void setStatus(String status) { this.status = status; } } + + public static class AttachVolumeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String volumePrimaryStorageUuid; + @GrayVersion(value = "5.0.0") + public String volumeInstallPath; + @GrayVersion(value = "5.0.0") + public String mountPath; + @GrayVersion(value = "5.0.0") + public String device; + } + + public static class AttachVolumeRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") + public String device; + } + + public static class DetachVolumeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String volumeInstallPath; + @GrayVersion(value = "5.0.0") + public String mountPath; + @GrayVersion(value = "5.0.0") + public String device; + } + + public static class DetachVolumeRsp extends AgentResponse { + } + + public static class VmFstrimCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String vmUuid; + } + + public static class VmFstrimRsp extends AgentResponse { + } + public static class TakeVmConsoleScreenshotCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private String vmUuid; + + public String getVmUuid() { + return vmUuid; + } + + public void setVmUuid(String vmUuid) { + this.vmUuid = vmUuid; + } + } + + public static class TakeVmConsoleScreenshotRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") + private String imageData; + + public String getImageData() { + return imageData; + } + + public void setImageData(String imageData) { + this.imageData = imageData; + } + } + + public static class SyncIpsetCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public Map> l2MacMap; + @GrayVersion(value = "5.0.0") + public Map interfaceMap; + @GrayVersion(value = "5.0.0") + public Map vlanMap; + @GrayVersion(value = "5.0.0") + public List nicList; + } + + public static class SyncIpsetRsp extends AgentResponse { + } + + public static class InstallOvsPackageCmd extends AgentCommand { + @GrayVersion(value = "5.4.0") + public String ovnControllerIp; + + public String getOvnControllerIp() { + return ovnControllerIp; + } + + public void setOvnControllerIp(String ovnControllerIp) { + this.ovnControllerIp = ovnControllerIp; + } + } + + public static class InstallOvsPackageRsp extends AgentResponse { + } + + public static class UnInstallOvsPackageCmd extends AgentCommand { + @GrayVersion(value = "5.4.0") + public String ovnControllerIp; + + public String getOvnControllerIp() { + return ovnControllerIp; + } + + public void setOvnControllerIp(String ovnControllerIp) { + this.ovnControllerIp = ovnControllerIp; + } + } + + public static class UnInstallOvsPackageRsp extends AgentResponse { + } + + public static class StartOvsServiceCmd extends AgentCommand { + @GrayVersion(value = "5.4.0") + public String vSwitchType; + @GrayVersion(value = "5.4.0") + public String hostIp; + @GrayVersion(value = "5.4.0") + public Map nicNamePciAddressMap; + @GrayVersion(value = "5.4.0") + public Map nicNameDriverMap; + @GrayVersion(value = "5.4.0") + public List restoreNicPciAddressList = new ArrayList<>(); + @GrayVersion(value = "5.4.0") + public String brExName; + @GrayVersion(value = "5.4.0") + public String ovnRemoteConnection; + @GrayVersion(value = "5.4.0") + public String ovnEncapIP; + @GrayVersion(value = "5.4.0") + public String ovnEncapNetmask; + @GrayVersion(value = "5.4.0") + public String ovnEncapType; + @GrayVersion(value = "5.4.0") + public Integer hugePageNumber; + @GrayVersion(value = "5.4.0") + public String bondingMode; + @GrayVersion(value = "5.4.0") + public String lacpMode; + @GrayVersion(value = "5.4.0") + public Integer hugePageSize; + @GrayVersion(value = "5.4.0") + public Integer socketMem; + @GrayVersion(value = "5.4.0") + public String lcores; + @GrayVersion(value = "5.4.0") + public String pmdcores; + @GrayVersion(value = "5.4.0") + public Integer nicRxQueueNumber; + @GrayVersion(value = "5.4.0") + public Integer nicRxQueueDescNumber; + + } + + public static class StartOvsServiceRsp extends AgentResponse { + } + + public static class OvsAddPortCmd extends AgentCommand { + @GrayVersion(value = "5.4.0") + public String vSwitchType; + @GrayVersion(value = "5.4.0") + public Boolean sync; + @GrayVersion(value = "5.4.0") + public Boolean reInstall; + @GrayVersion(value = "5.4.0") + public Map nicMap = new HashMap<>(); + } + + public static class OvsAddPortRsp extends AgentResponse { + } + + public static class OvsDelPortCmd extends AgentCommand { + @GrayVersion(value = "5.4.0") + public String vswitchType; + @GrayVersion(value = "5.4.0") + public Map nicMap = new HashMap<>(); + } + + public static class OvsDelPortRsp extends AgentResponse { + } + + public static class HardwareMonitorCmd extends KVMAgentCommands.AgentCommand { + } + + public static class HostPhysicalCpuStatusAlarmEventCmd { + public String host; + public String cpuName; + public String status; + } + + public static class HostPhysicalMemoryStatusAlarmEventCmd { + public String host; + public String locator; + public String status; + } + + public static class HostPhysicalFanStatusAlarmEventCmd { + public String host; + public String fan_name; + public String status; + } + + public static class HostPhysicalPowerSupplyStatusAlarmEventCmd { + public String host; + public String name; + public String status; + } + + public static class HostPhysicalDiskStatusAlarmEventCmd { + public String host; + public String slot_number; + public String enclosure_device_id; + public String drive_state; + public String serial_number; + } + + public static class HostPhysicalDiskInsertAlarmEventCmd { + public String host; + public Map additionalProperties = new HashMap<>(); + } + + public static class HostPhysicalDiskRemoveAlarmEventCmd { + public String host; + public Map additionalProperties = new HashMap<>(); + } + + public static class PhysicalMemoryEccErrorAlarmEventCmd { + public String host; + public String detail; + } + + public static class PhysicalGpuStatusAlarmEventCmd { + public String host; + public String pcideviceAddress; + public String status; + } + + public static class PhysicalGpuRemoveAlarmEventCmd { + public String host; + public String pcideviceAddress; + } + + public static class HostStorageDeviceHbaStateEventCmd { + public String host; + public String portName; + public String portState; + public String name; + } + + public static class HostPhysicalDeviceStatusAlarmEventCmd { + private String host; + private String type; + private Map additionalProperties = new HashMap<>(); + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Map getAdditionalProperties() { + return additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperties(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + } + + public static class HostProcessPhysicalMemoryUsageAlarmCmd { + private String hostUuid; + private String pid; + private String processName; + private long memoryUsage; + private Map additionalProperties = new HashMap<>(); + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public String getProcessName() { + return processName; + } + + public void setProcessName(String processName) { + this.processName = processName; + } + + public long getMemoryUsage() { + return memoryUsage; + } + + public void setMemoryUsage(long memoryUsage) { + this.memoryUsage = memoryUsage; + } + + public Map getAdditionalProperties() { + return additionalProperties; + } + + public void setAdditionalProperties(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + } + + public static class HostKvmagentStatusCmd { + private String status; + private String hostUuid; + private long memoryUsage; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public long getMemoryUsage() { + return memoryUsage; + } + + public void setMemoryUsage(long memoryUsage) { + this.memoryUsage = memoryUsage; + } + } + } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMApiInterceptor.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMApiInterceptor.java index 6abc898db1e..ca955e5d648 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMApiInterceptor.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMApiInterceptor.java @@ -1,7 +1,10 @@ package org.zstack.kvm; +import org.apache.commons.lang.StringUtils; +import org.apache.poi.util.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; @@ -13,12 +16,15 @@ import org.zstack.header.network.l2.APIAttachL2NetworkToClusterMsg; import org.zstack.header.network.l2.L2NetworkConstant; import org.zstack.header.network.l2.L2VlanNetworkVO; +import org.zstack.kvm.xmlhook.*; import org.zstack.utils.CollectionDSL; import org.zstack.utils.network.NetworkUtils; import java.util.List; +import java.util.stream.Collectors; import static org.zstack.core.Platform.argerr; +import static org.zstack.core.Platform.operr; /** */ @@ -34,10 +40,55 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIAddKVMHostMsg) msg); } else if (msg instanceof APIAttachL2NetworkToClusterMsg) { validate((APIAttachL2NetworkToClusterMsg) msg); + } else if (msg instanceof APICreateVmUserDefinedXmlHookScriptMsg) { + validate((APICreateVmUserDefinedXmlHookScriptMsg) msg); + } else if (msg instanceof APIUpdateVmUserDefinedXmlHookScriptMsg) { + validate((APIUpdateVmUserDefinedXmlHookScriptMsg) msg); + } else if (msg instanceof APIExpungeVmUserDefinedXmlHookScriptMsg) { + validate((APIExpungeVmUserDefinedXmlHookScriptMsg) msg); } return msg; } + private void validate(APIExpungeVmUserDefinedXmlHookScriptMsg msg) { + failIfChangeSystemDefinedHook(msg); + List refVOs = Q.New(XmlHookVmInstanceRefVO.class) + .eq(XmlHookVmInstanceRefVO_.xmlHookUuid, msg.getUuid()).list(); + if (refVOs != null && refVOs.size() > 0) { + List vmUuids = refVOs.stream() + .map(XmlHookVmInstanceRefVO::getVmInstanceUuid) + .collect(Collectors.toList()); + throw new ApiMessageInterceptionException(operr("the xml hook[%s] has been set to vm %s," + + " so unbind it before deleting it", msg.getUuid(), vmUuids)); + } + } + + private void validate(APIUpdateVmUserDefinedXmlHookScriptMsg msg) { + failIfChangeSystemDefinedHook(msg); + String name = Q.New(XmlHookVO.class).select(XmlHookVO_.name) + .eq(XmlHookVO_.name, msg.getName()) + .notEq(XmlHookVO_.uuid, msg.getUuid()) + .findValue(); + if (StringUtils.isNotEmpty(name)) { + throw new ApiMessageInterceptionException(argerr("the xml hook name[%s] already exists", msg.getName())); + } + } + + private static void failIfChangeSystemDefinedHook(XmlHookMessage msg) { + XmlHookVO vo = Q.New(XmlHookVO.class).eq(XmlHookVO_.uuid, msg.getXmlHookUuid()).find(); + if (XmlHookType.System.equals(vo.getType())) { + throw new ApiMessageInterceptionException(operr("System-type xml hooks are not allowed to be operated")); + } + } + + private void validate(APICreateVmUserDefinedXmlHookScriptMsg msg) { + String name = Q.New(XmlHookVO.class).select(XmlHookVO_.name) + .eq(XmlHookVO_.name, msg.getName()).findValue(); + if (StringUtils.isNotEmpty(name)) { + throw new ApiMessageInterceptionException(argerr("the xml hook name[%s] already exists", msg.getName())); + } + } + private void validate(APIAddKVMHostMsg msg) { SimpleQuery q = dbf.createQuery(KVMHostVO.class); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMBlockCommitExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMBlockCommitExtensionPoint.java new file mode 100644 index 00000000000..bab798b471a --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMBlockCommitExtensionPoint.java @@ -0,0 +1,14 @@ +package org.zstack.kvm; + +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.CommitVolumeSnapshotOnHypervisorMsg; +import org.zstack.header.host.CommitVolumeSnapshotOnHypervisorReply; + +public interface KVMBlockCommitExtensionPoint { + void beforeCommitVolume(KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, Completion completion); + + void afterCommitVolume(KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, CommitVolumeSnapshotOnHypervisorReply reply, Completion completion); + + void failedToCommitVolume(KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, KVMAgentCommands.BlockCommitResponse rsp, ErrorCode err); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMBlockPullExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMBlockPullExtensionPoint.java new file mode 100644 index 00000000000..c7146ea323e --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMBlockPullExtensionPoint.java @@ -0,0 +1,14 @@ +package org.zstack.kvm; + +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.PullVolumeSnapshotOnHypervisorMsg; +import org.zstack.header.host.PullVolumeSnapshotOnHypervisorReply; + +public interface KVMBlockPullExtensionPoint { + void beforePullVolume(KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, Completion completion); + + void afterPullVolume(KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, PullVolumeSnapshotOnHypervisorReply reply, Completion completion); + + void failedToPullVolume(KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, KVMAgentCommands.BlockPullResponse rsp, ErrorCode err); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMCompleteNicInformationExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMCompleteNicInformationExtensionPoint.java index 227135f35eb..66dee67958e 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMCompleteNicInformationExtensionPoint.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMCompleteNicInformationExtensionPoint.java @@ -2,6 +2,7 @@ import org.zstack.header.network.l2.L2NetworkInventory; import org.zstack.header.network.l2.L2NetworkType; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.vm.VmNicInventory; import org.zstack.kvm.KVMAgentCommands.NicTO; diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java index ab892a7f48b..133b05dc771 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConnectExtensionForL2Network.java @@ -1,252 +1,26 @@ package org.zstack.kvm; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.transaction.annotation.Transactional; -import org.zstack.core.asyncbatch.While; -import org.zstack.core.cloudbus.CloudBus; -import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.Q; -import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.core.Completion; -import org.zstack.header.core.FutureCompletion; -import org.zstack.header.core.NoErrorCompletion; -import org.zstack.header.core.WhileDoneCompletion; -import org.zstack.header.core.workflow.*; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.errorcode.ErrorCodeList; -import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.host.*; -import org.zstack.header.message.MessageReply; -import org.zstack.header.network.l2.*; +import org.zstack.header.network.l2.L2NetworkInventory; import org.zstack.network.l2.L2NetworkManager; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; -import javax.persistence.TypedQuery; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import static org.zstack.core.Platform.operr; +import java.util.List; +import java.util.Map; /** */ -public class KVMConnectExtensionForL2Network implements KVMHostConnectExtensionPoint, HostConnectionReestablishExtensionPoint { - @Autowired - private DatabaseFacade dbf; - @Autowired - private CloudBus bus; +public class KVMConnectExtensionForL2Network extends AbstractKVMConnectExtensionForL2Network implements KVMHostConnectExtensionPoint { @Autowired protected L2NetworkManager l2Mgr; protected static final CLogger logger = Utils.getLogger(KVMConnectExtensionForL2Network.class); - @Transactional(readOnly = true) - private List getL2Networks(String clusterUuid) { - String sql = "select l2 from L2NetworkVO l2, L2NetworkClusterRefVO ref where l2.uuid = ref.l2NetworkUuid and ref.clusterUuid = :clusterUuid and l2.type in (:supportTypes)"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, L2NetworkVO.class); - q.setParameter("clusterUuid", clusterUuid); - q.setParameter("supportTypes", getSupportTypes()); - List vos = q.getResultList(); - List ret = new ArrayList(vos.size()); - List noVlanL2Networks = new ArrayList<>(); - for (L2NetworkVO vo : vos) { - if (L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(vo.getType())) { - noVlanL2Networks.add(L2NetworkInventory.valueOf(vo)); - } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(vo.getType())) { - L2VlanNetworkVO vlanvo = dbf.getEntityManager().find(L2VlanNetworkVO.class, vo.getUuid()); - ret.add(L2VlanNetworkInventory.valueOf(vlanvo)); - } else { - ret.add(L2NetworkInventory.valueOf(vo)); - } - } - - /* when prepare l2 network, first prepare no vlan network, because mtu of vlan network must less than - * no vlan network */ - if (!noVlanL2Networks.isEmpty()) { - noVlanL2Networks.addAll(ret); - return noVlanL2Networks; - } else { - return ret; - } - } - - private List getSupportTypes() { - List types = Arrays.asList(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE, L2NetworkConstant.L2_VLAN_NETWORK_TYPE); - return types; - } - - private void prepareNetwork(final List l2Networks, final String hostUuid, final Completion completion) { - if (l2Networks.isEmpty()) { - completion.success(); - return; - } - - HostVO hostVO = dbf.findByUuid(hostUuid, HostVO.class); - - FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); - chain.setName(String.format("prepare-l2-for-kvm-%s-connect", hostUuid)); - chain.then(new NoRollbackFlow() { - String __name__ = "check-network-physical-interface"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - List batchCheckNetworkPhysicalInterfaceMsgs = new ArrayList<>(); - final List l2NetworksCheckList = - l2Networks.stream() - .collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(L2NetworkInventory::getPhysicalInterface))),ArrayList::new)); - int step = 100; - int size = l2NetworksCheckList.size(); - int count = size / 100; - if (size - count * 100 > 0) { - count++; - } - - for (int i = 0; i < count; i++) { - int end = (i + 1) * step - 1; - List interfaces = l2NetworksCheckList.subList(i * step, Math.min(end, l2NetworksCheckList.size())) - .stream() - .map(L2NetworkInventory::getPhysicalInterface) - .collect(Collectors.toList()); - - BatchCheckNetworkPhysicalInterfaceMsg bmsg = new BatchCheckNetworkPhysicalInterfaceMsg(); - bmsg.setPhysicalInterfaces(interfaces); - bmsg.setHostUuid(hostUuid); - bus.makeTargetServiceIdByResourceUuid(bmsg, HostConstant.SERVICE_ID, hostUuid); - batchCheckNetworkPhysicalInterfaceMsgs.add(bmsg); - } - - new While<>(batchCheckNetworkPhysicalInterfaceMsgs).each((bmsg, c) -> { - bus.send(bmsg, new CloudBusCallBack(c) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - c.addError(reply.getError()); - c.allDone(); - return; - } - - c.done(); - } - }); - }).run(new WhileDoneCompletion(trigger) { - @Override - public void done(ErrorCodeList errorCodeList) { - if (!errorCodeList.getCauses().isEmpty()) { - trigger.fail(errorCodeList.getCauses().get(0)); - return; - } - - trigger.next(); - } - }); - } - }); - - chain.then(new NoRollbackFlow() { - String __name__ = "realize_no_vlan"; - - @Override - public void run(FlowTrigger trigger, Map data) { - List novlanNetworks = l2Networks.stream().filter(l2 -> l2.getType().equals(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE)).collect(Collectors.toList()); - new While<>(novlanNetworks).step((l2, c) -> { - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(L2NetworkType.valueOf(l2.getType()), HypervisorType.valueOf(hostVO.getHypervisorType())); - ext.realize(l2, hostUuid, true, new Completion(c) { - @Override - public void success() { - c.done(); - } - - @Override - public void fail(ErrorCode errorCode) { - c.addError(errorCode); - c.allDone(); - } - }); - }, 10).run(new WhileDoneCompletion(trigger) { - @Override - public void done(ErrorCodeList errorCodeList) { - if (!errorCodeList.getCauses().isEmpty()) { - trigger.fail(errorCodeList.getCauses().get(0)); - return; - } - - trigger.next(); - } - }); - } - }); - - chain.then(new NoRollbackFlow() { - String __name__ = "realize_vlan"; - - @Override - public void run(FlowTrigger trigger, Map data) { - List vlanNetworks = l2Networks.stream().filter(l2 -> l2.getType().equals(L2NetworkConstant.L2_VLAN_NETWORK_TYPE)).collect(Collectors.toList()); - new While<>(vlanNetworks).step((l2, c) -> { - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(L2NetworkType.valueOf(l2.getType()), HypervisorType.valueOf(hostVO.getHypervisorType())); - ext.realize(l2, hostUuid, true, new Completion(c) { - @Override - public void success() { - c.done(); - } - - @Override - public void fail(ErrorCode errorCode) { - c.addError(errorCode); - c.allDone(); - } - }); - }, 10).run(new WhileDoneCompletion(trigger) { - @Override - public void done(ErrorCodeList errorCodeList) { - if (!errorCodeList.getCauses().isEmpty()) { - trigger.fail(errorCodeList.getCauses().get(0)); - return; - } - - trigger.next(); - } - }); - } - }); - - chain.done(new FlowDoneHandler(completion) { - @Override - public void handle(Map data) { - completion.success(); - } - }).error(new FlowErrorHandler(completion) { - @Override - public void handle(ErrorCode errCode, Map data) { - completion.fail(errCode); - } - }).start(); - } - - - @Override - public void connectionReestablished(HostInventory inv) throws HostException { - //TODO: make connect async - List l2s = getL2Networks(inv.getClusterUuid()); - if (l2s.isEmpty()) { - return; - } - - FutureCompletion completion = new FutureCompletion(null); - prepareNetwork(l2s, inv.getUuid(), completion); - completion.await(TimeUnit.SECONDS.toMillis(600)); - if (!completion.isSuccess()) { - throw new OperationFailureException(completion.getErrorCode()); - } - } - - @Override - public HypervisorType getHypervisorTypeForReestablishExtensionPoint() { - return new HypervisorType(KVMConstant.KVM_HYPERVISOR_TYPE); - } - @Override public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { return new NoRollbackFlow() { diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java index 30e696b30f3..46092d74bc3 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConsoleHypervisorBackend.java @@ -48,6 +48,7 @@ public void generateConsoleUrl(final VmInstanceInventory vm, final ReturnValueCo KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(vm.getHostUuid()); msg.setCommand(cmd); + msg.setNoStatusCheck(true); msg.setPath(KVMConstant.KVM_GET_VNC_PORT_PATH); bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, vm.getHostUuid()); bus.send(msg, new CloudBusCallBack(complete) { diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java index bd7dd3e9f39..f40157764ea 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMConstant.java @@ -21,6 +21,8 @@ public interface KVMConstant { String KVM_HOST_CHECK_FILE_PATH = "/host/checkfile"; String KVM_HOST_REPORT_DEVICE_EVENT_PATH = "/host/reportdeviceevent"; String KVM_HOST_NUMA_PATH = "/numa/topology"; + String KVM_UPDATE_L2VLAN_NETWORK_PATH = "/network/l2vlan/updatebridge"; + String KVM_UPDATE_L2VXLAN_NETWORK_PATH = "/network/l2vxlan/updatebridge"; String KVM_REALIZE_L2NOVLAN_NETWORK_PATH = "/network/l2novlan/createbridge"; String KVM_CHECK_L2NOVLAN_NETWORK_PATH = "/network/l2novlan/checkbridge"; String KVM_REALIZE_L2VLAN_NETWORK_PATH = "/network/l2vlan/createbridge"; @@ -32,8 +34,17 @@ public interface KVMConstant { String KVM_DELETE_OVSDPDK_NETWORK_PATH = "/network/ovsdpdk/deletebridge"; String KVM_GENERATE_VDPA_PATH = "/network/ovsdpdk/generatevdpa"; String KVM_DELETE_VDPA_PATH = "/network/ovsdpdk/deletevdpa"; + String KVM_GENERATE_VHOST_USER_CLIENT_PATH = "/network/ovsdpdk/addvhostuserclient"; + String KVM_DELETE_VHOST_USER_CLIENT_PATH = "/network/ovsdpdk/deletevhostuserclient"; + String KVM_INSTALL_OVS_PACKAGE_PATH = "/network/ovn/install"; + String KVM_UNINSTALL_OVS_PACKAGE_PATH = "/network/ovn/uninstall"; + String KVM_START_OVS_SERVICE_PATH = "/network/ovn/start"; + String KVM_STOP_OVS_SERVICE_PATH = "/network/ovn/stop"; + String KVM_OVS_ADD_PORT_PATH = "/network/ovn/addport"; + String KVM_OVS_DEL_PORT_PATH = "/network/ovn/delport"; String KVM_ATTACH_ISO_PATH = "/vm/iso/attach"; String KVM_DETACH_ISO_PATH = "/vm/iso/detach"; + String KVM_SYNC_VM_DEVICEINFO_PATH = "/sync/vm/deviceinfo"; String KVM_START_VM_PATH = "/vm/start"; String KVM_STOP_VM_PATH = "/vm/stop"; String KVM_PAUSE_VM_PATH = "/vm/pause"; @@ -41,14 +52,18 @@ public interface KVMConstant { String KVM_REBOOT_VM_PATH = "/vm/reboot"; String KVM_DESTROY_VM_PATH = "/vm/destroy"; String KVM_MIGRATE_VM_PATH = "/vm/migrate"; + String KVM_GET_CPU_XML_PATH = "/vm/get/cpu/xml"; + String KVM_COMPARE_CPU_FUNCTION_PATH = "/vm/compare/cpu/function"; String KVM_GET_VNC_PORT_PATH = "/vm/getvncport"; String KVM_VM_ONLINE_INCREASE_CPU = "/vm/increase/cpu"; String KVM_VM_ONLINE_INCREASE_MEMORY = "/vm/increase/mem"; String KVM_VM_SYNC_PATH = "/vm/vmsync"; + String KVM_VOLUME_SYNC_PATH = "/vm/volumesync"; String KVM_ATTACH_VOLUME = "/vm/attachdatavolume"; String KVM_DETACH_VOLUME = "/vm/detachdatavolume"; String KVM_ATTACH_NIC_PATH = "/vm/attachnic"; String KVM_DETACH_NIC_PATH = "/vm/detachnic"; + String KVM_CHANGE_NIC_STATE_PATH = "/vm/changenicstate"; String KVM_UPDATE_NIC_PATH = "/vm/updatenic"; String KVM_VM_CHECK_STATE = "/vm/checkstate"; String KVM_VM_UPDATE_PRIORITY_PATH = "/vm/priority"; @@ -62,15 +77,19 @@ public interface KVMConstant { String KVM_UPDATE_HOST_OS_PATH = "/host/updateos"; String KVM_HOST_UPDATE_DEPENDENCY_PATH = "/host/updatedependency"; String HOST_SHUTDOWN = "/host/shutdown"; + String HOST_REBOOT = "/host/reboot"; String HOST_UPDATE_SPICE_CHANNEL_CONFIG_PATH = "/host/updateSpiceChannelConfig"; String KVM_GET_VM_FIRST_BOOT_DEVICE_PATH = "/vm/getfirstbootdevice"; String GET_VM_DEVICE_ADDRESS_PATH = "/vm/getdeviceaddress"; + String GET_VIRTUALIZER_INFO_PATH = "/vm/getvirtualizerinfo"; String KVM_SCAN_VM_PORT_STATUS = "/host/vm/scanport"; String GET_DEV_CAPACITY = "/host/dev/capacity"; String KVM_CONFIG_PRIMARY_VM_PATH = "/primary/vm/config"; String KVM_CONFIG_SECONDARY_VM_PATH = "/secondary/vm/config"; String KVM_START_COLO_SYNC_PATH = "/start/colo/sync"; String KVM_REGISTER_PRIMARY_VM_HEARTBEAT = "/register/primary/vm/heartbeat"; + String CLEAN_FIRMWARE_FLASH = "/clean/firmware/flash"; + String FSTRIM_VM_PATH = "/vm/fstrim"; String ISO_TO = "kvm.isoto"; String ANSIBLE_PLAYBOOK_NAME = "kvm.py"; @@ -85,14 +104,38 @@ public interface KVMConstant { String KVM_RECONNECT_ME = "/kvm/reconnectme"; String KVM_REPORT_PS_STATUS = "/kvm/reportstoragestatus"; String KVM_REPORT_SELF_FENCER = "/kvm/reportselffencer"; + String KVM_REPORT_SELF_FENCER_STATE_CHANGED = "/kvm/reportselffencerstatechanged"; String KVM_REQUEST_MAINTAIN_HOST = "/kvm/requestmaintainhost"; String KVM_ANSIBLE_LOG_PATH_FROMAT = "/kvm/ansiblelog/{uuid}"; String KVM_REPORT_VM_SHUTDOWN_EVENT = "/kvm/reportvmshutdown"; + String KVM_REPORT_VM_SHUTDOWN_FROM_GUEST_EVENT = "/kvm/reportvmshutdown/from/guest"; String KVM_REPORT_VM_REBOOT_EVENT = "/kvm/reportvmreboot"; String KVM_REPORT_VM_CRASH_EVENT = "/kvm/reportvmcrash"; + String KVM_REPORT_VM_START_EVENT = "/kvm/reportvmstart"; + String KVM_REPORT_HOST_STOP_EVENT = "/kvm/reporthoststop"; String KVM_TRANSMIT_VM_OPERATION_TO_MN = "/host/transmitvmoperation"; String KVM_HOST_PHYSICAL_NIC_ALARM_EVENT = "/host/physicalNic/alarm"; + String KVM_HOST_ATTACH_VOLUME_PATH = "/host/volume/attach"; + String KVM_HOST_DETACH_VOLUME_PATH = "/host/volume/detach"; + String KVM_BLOCK_COMMIT_VOLUME_PATH = "/vm/volume/blockcommit"; + String KVM_BLOCK_PULL_VOLUME_PATH = "/vm/volume/blockpull"; + String TAKE_VM_CONSOLE_SCREENSHOT_PATH = "/vm/console/screenshot"; + + String KVM_HOST_IPSET_ATTACH_NIC_PATH = "/network/ipset/attach"; + String KVM_HOST_IPSET_DETACH_NIC_PATH = "/network/ipset/detach"; + String KVM_HOST_IPSET_SYNC_PATH = "/network/ipset/sync"; + + String SET_HOST_PHYSICAL_MEMORY_MONITOR = "/host/physical/memory/monitor/start"; + + String HOST_PHYSICAL_HARD_STATUS_ALARM_EVENT = "/host/physical/hardware/status/alarm"; + String HOST_PHYSICAL_DISK_INSERT_ALARM_EVENT = "/host/physical/disk/insert/alarm"; + String HOST_PHYSICAL_DISK_REMOVE_ALARM_EVENT = "/host/physical/disk/remove/alarm"; + String HOST_PHYSICAL_MEMORY_ECC_ERROR_ALARM_EVENT = "/host/physical/memory/ecc/error/alarm"; + String HOST_PHYSICAL_GPU_REMOVE_ALARM_EVENT = "/host/physical/gpu/remove/alarm"; + String HOST_STORAGEDEVICE_HBA_STATE_EVENT = "/storagedevice/hba/state/alarm"; + String HOST_PROCESS_PHYSICAL_MEMORY_USAGE_ALARM_PATH = "/host/process/physicalMemory/usage/alarm"; + String HOST_KVMAGENT_STATUS_PATH = "/host/kvmagent/status"; String KVM_AGENT_OWNER = "kvm"; @@ -105,6 +148,7 @@ public interface KVMConstant { String CPU_MODE_CUSTOM = "custom"; String CPU_MODE_HOST_MODEL = "host-model"; String CPU_MODE_HOST_PASSTHROUGH = "host-passthrough"; + String CPU_MODE_HYGON_CUSTOMIZED = "Hygon_Customized"; String IPTABLES_COMMENTS = "kvmagent.allow.port"; @@ -112,6 +156,34 @@ public interface KVMConstant { String CONNECT_HOST_PRIMARYSTORAGE_ERROR = "psError"; + String VIRTUALIZER_QEMU_KVM = "qemu-kvm"; + String VIRTUALIZER_QEMU = "qemu"; + + int IPMI_DEFAULT_PORT = 623; + int KVM_HOST_POWER_OPERATION_TIMEOUT_SECONDS = 300; + + String KVM_HOST_SKIP_PING_NO_FAILURE_EXTENSIONS = "kvm.host.skip.ping.no.failure.extensions"; + + String MEMORY_LOCATOR_NAME = "locator"; + String PHYSICAL_DEVICE_STATUS_NAME = "status"; + String PHYSICAL_DEVICE_STATE_NAME = "state"; + String PHYSICAL_DEVICE_DISK_UUIDS = "diskUuids"; + String CPU_NAME = "cpuName"; + String PCI_DEVICE_ADDRESS = "pcideviceAddress"; + String DEVICE_NAME = "name"; + String VOLUME_GROUP_NAME = "volumeGroup"; + String DEVICE_SERIAL_NUMBER = "serial_number"; + String ENCLOSURE_DEVICE_ID = "enclosure_device_id"; + String SLOT_NUMBER = "slot_number"; + String DRIVE_STATE = "drive_state"; + String TARGET_ID = "target_id"; + + + public static final String L2_PROVIDER_TYPE_LINUX_BRIDGE = "LinuxBridge"; + + public static final String DHCP_BIN_FILE_PATH = "/usr/local/zstack/dnsmasq"; + String KVM_HOST_NETWORK_INTERFACE_DEFAULT = "None"; + enum KvmVmState { NoState, Running, @@ -127,6 +199,8 @@ public static KvmVmState fromVmInstanceState(VmInstanceState state) { return null; } else if (state == VmInstanceState.Paused) { return Paused; + } else if (state == VmInstanceState.Migrating) { + return Running; } else { return null; } @@ -141,6 +215,8 @@ public VmInstanceState toVmInstanceState() { return VmInstanceState.Paused; } else if (this == Crashed) { return VmInstanceState.Crashed; + } else if (this == NoState) { + return VmInstanceState.NoState; } else { return VmInstanceState.Unknown; } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMExtensionEmitter.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMExtensionEmitter.java index dd9bc70a0ce..0e723cd16aa 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMExtensionEmitter.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMExtensionEmitter.java @@ -8,10 +8,7 @@ import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; -import org.zstack.header.host.CheckSnapshotOnHypervisorMsg; -import org.zstack.header.host.CheckVmStateOnHypervisorMsg; -import org.zstack.header.host.HostInventory; -import org.zstack.header.host.TakeSnapshotOnHypervisorMsg; +import org.zstack.header.host.*; import org.zstack.header.vm.VmInstanceInventory; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.volume.VolumeInventory; @@ -45,6 +42,9 @@ public class KVMExtensionEmitter implements Component { private List checkSnapshotExts = new ArrayList<>(); private List mergeSnapshotExts = new ArrayList<>(); private List checkVmStateExts = new ArrayList<>(); + private List syncVmDeviceInfoExts = new ArrayList<>(); + private List blockCommitExts = new ArrayList<>(); + private List blockPullExts = new ArrayList<>(); private void populateExtensions() { startVmExts = pluginRgty.getExtensionList(KVMStartVmExtensionPoint.class); @@ -58,6 +58,18 @@ private void populateExtensions() { mergeSnapshotExts = pluginRgty.getExtensionList(KVMMergeSnapshotExtensionPoint.class); checkVmStateExts = pluginRgty.getExtensionList(KVMCheckVmStateExtensionPoint.class); checkSnapshotExts = pluginRgty.getExtensionList(KVMCheckSnapshotExtensionPoint.class); + syncVmDeviceInfoExts = pluginRgty.getExtensionList(KVMSyncVmDeviceInfoExtensionPoint.class); + blockCommitExts = pluginRgty.getExtensionList(KVMBlockCommitExtensionPoint.class); + blockPullExts = pluginRgty.getExtensionList(KVMBlockPullExtensionPoint.class); + } + + public void afterReceiveSyncVmDeviceInfoResponse(final VmInstanceInventory vm, final KVMAgentCommands.VmDevicesInfoResponse rsp, VmInstanceSpec spec) { + CollectionUtils.safeForEach(syncVmDeviceInfoExts, new ForEachFunction() { + @Override + public void run(KVMSyncVmDeviceInfoExtensionPoint arg) { + arg.afterReceiveVmDeviceInfoResponse(vm, rsp, spec); + } + }); } public void beforeStartVmOnKvm(final KVMHostInventory host, final VmInstanceSpec spec, final StartVmCmd cmd) { @@ -66,6 +78,7 @@ public void beforeStartVmOnKvm(final KVMHostInventory host, final VmInstanceSpec } } + public void startVmOnKvmSuccess(final KVMHostInventory host, final VmInstanceSpec spec) { CollectionUtils.safeForEach(startVmExts, new ForEachFunction() { @Override @@ -144,13 +157,11 @@ public void beforeRebootVmOnKvm(KVMHostInventory host, VmInstanceInventory vm) t } } - public void rebootVmOnKvmSuccess(final KVMHostInventory host, final VmInstanceInventory vm) { - CollectionUtils.safeForEach(rebootVmExts, new ForEachFunction() { - @Override - public void run(KVMRebootVmExtensionPoint arg) { - arg.rebootVmOnKvmSuccess(host, vm); - } - }); + public void rebootVmOnKvmSuccess( + final KVMHostInventory host, + final VmInstanceInventory vm, + KVMAgentCommands.RebootVmResponse ret) { + CollectionUtils.safeForEach(rebootVmExts, arg -> arg.rebootVmOnKvmSuccess(host, vm, ret)); } public void rebootVmOnKvmFailed(final KVMHostInventory host, final VmInstanceInventory vm, final ErrorCode err) { @@ -173,7 +184,7 @@ public void run(KVMStartVmAddonExtensionPoint extp) { }); } - public void doBeforeTakeSnapshot(final Iterator it, KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, + private void doBeforeTakeSnapshot(final Iterator it, KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, Completion completion) { if (!it.hasNext()) { completion.success(); @@ -222,6 +233,118 @@ public void done(ErrorCodeList errorCodeList) { }); } + public void doBeforeCommitVolume(Iterator it, KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, Completion completion) { + if (!it.hasNext()) { + completion.success(); + return; + } + + KVMBlockCommitExtensionPoint ext = it.next(); + ext.beforeCommitVolume(host, msg, cmd, new Completion(completion) { + @Override + public void success() { + doBeforeCommitVolume(it, host, msg, cmd, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + public void beforeCommitVolume(KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, Completion completion) { + Iterator it = blockCommitExts.iterator(); + doBeforeCommitVolume(it, host, msg, cmd, completion); + } + + public void doAfterCommitVolume(Iterator it, KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, CommitVolumeSnapshotOnHypervisorReply reply, Completion completion) { + if (!it.hasNext()) { + completion.success(); + return; + } + + KVMBlockCommitExtensionPoint ext = it.next(); + ext.afterCommitVolume(host, msg, cmd, reply, new Completion(completion) { + @Override + public void success() { + doAfterCommitVolume(it, host, msg, cmd, reply, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + public void afterCommitVolume(KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, CommitVolumeSnapshotOnHypervisorReply reply, Completion completion) { + Iterator it = blockCommitExts.iterator(); + doAfterCommitVolume(it, host, msg, cmd, reply, completion); + } + + public void failedToCommitVolume(KVMHostInventory host, CommitVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockCommitCmd cmd, KVMAgentCommands.BlockCommitResponse rsp, ErrorCode err) { + for (KVMBlockCommitExtensionPoint ext : blockCommitExts) { + ext.failedToCommitVolume(host, msg, cmd, rsp, err); + } + } + + public void doBeforePullVolume(Iterator it, KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, Completion completion) { + if (!it.hasNext()) { + completion.success(); + return; + } + + KVMBlockPullExtensionPoint ext = it.next(); + ext.beforePullVolume(host, msg, cmd, new Completion(completion) { + @Override + public void success() { + doBeforePullVolume(it, host, msg, cmd, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + public void beforePullVolume(KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, Completion completion) { + Iterator it = blockPullExts.iterator(); + doBeforePullVolume(it, host, msg, cmd, completion); + } + + public void doAfterPullVolume(Iterator it, KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, PullVolumeSnapshotOnHypervisorReply reply, Completion completion) { + if (!it.hasNext()) { + completion.success(); + return; + } + + KVMBlockPullExtensionPoint ext = it.next(); + ext.afterPullVolume(host, msg, cmd, reply, new Completion(completion) { + @Override + public void success() { + doAfterPullVolume(it, host, msg, cmd, reply, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + public void afterPullVolume(KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, PullVolumeSnapshotOnHypervisorReply reply, Completion completion) { + Iterator it = blockPullExts.iterator(); + doAfterPullVolume(it, host, msg, cmd, reply, completion); + } + + public void failedToPullVolume(KVMHostInventory host, PullVolumeSnapshotOnHypervisorMsg msg, KVMAgentCommands.BlockPullCmd cmd, KVMAgentCommands.BlockPullResponse rsp, ErrorCode err) { + for (KVMBlockPullExtensionPoint ext : blockPullExts) { + ext.failedToPullVolume(host, msg, cmd, rsp, err); + } + } + public void beforeTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, Completion completion) { Iterator it = takeSnapshotExts.iterator(); doBeforeTakeSnapshot(it, host, msg, cmd, completion); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java index 49e2291fdba..aa0fd787bed 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java @@ -1,9 +1,11 @@ package org.zstack.kvm; import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.volume.VolumeVO; import org.zstack.resourceconfig.BindResourceConfig; import org.zstack.header.cluster.ClusterVO; import org.zstack.header.host.HostVO; @@ -39,8 +41,13 @@ public class KVMGlobalConfig { @GlobalConfigValidation public static GlobalConfig ALLOW_LIVE_SNAPSHOT_ON_REDHAT = new GlobalConfig(CATEGORY, "redhat.liveSnapshotOn"); @GlobalConfigValidation(validValues = {"none", "writethrough", "writeback"}) + @BindResourceConfig({VolumeVO.class, VmInstanceVO.class}) public static GlobalConfig LIBVIRT_CACHE_MODE = new GlobalConfig(CATEGORY, "vm.cacheMode"); - @GlobalConfigValidation(validValues = {"none", "host-model", "host-passthrough", "Haswell", "Haswell-noTSX", "Broadwell", "Broadwell-noTSX", "SandyBridge", "IvyBridge", "Conroe", "Penryn", "Nehalem", "Westmere", "Opteron_G1", "Opteron_G2", "Opteron_G3", "Opteron_G4"}) + @GlobalConfigValidation(validValues = {"none", "host-model", "host-passthrough", + "Dhyana", "EPYC", "EPYC-IBPB", "Haswell", "Haswell-noTSX", "Broadwell", "Broadwell-noTSX", + "SandyBridge", "IvyBridge", "Conroe", "Penryn", "Nehalem", "Westmere", "Opteron_G1", + "Opteron_G2", "Opteron_G3", "Opteron_G4", "pentium", "pentium2", "pentium3", + "Kunpeng-920", "FT-2000+", "Tengyun-S2500", "Tengyun-S5000C", "Loongson-3A5000", "Loongson-3A4000-COMP"}) @BindResourceConfig({VmInstanceVO.class, ClusterVO.class}) public static GlobalConfig NESTED_VIRTUALIZATION = new GlobalConfig(CATEGORY, "vm.cpuMode"); @GlobalConfigValidation @@ -48,11 +55,13 @@ public class KVMGlobalConfig { @GlobalConfigValidation public static GlobalConfig CHECK_HOST_CPU_MODEL_NAME = new GlobalConfig(CATEGORY, "checkHostCpuModelName"); @GlobalConfigValidation + @BindResourceConfig({ClusterVO.class}) public static GlobalConfig KVM_IGNORE_MSRS = new GlobalConfig(CATEGORY, "ignoreMsrs"); @GlobalConfigValidation(validValues = {"true", "false"}) @BindResourceConfig({ClusterVO.class}) public static GlobalConfig AUTO_VM_NIC_MULTIQUEUE = new GlobalConfig(CATEGORY, "auto.set.vm.nic.multiqueue"); @GlobalConfigValidation + @BindResourceConfig({VmInstanceVO.class}) public static GlobalConfig MIGRATE_AUTO_CONVERGE = new GlobalConfig(CATEGORY, "migrate.autoConverge"); @GlobalConfigValidation public static GlobalConfig MIGRATE_XBZRLE = new GlobalConfig(CATEGORY, "migrate.xbzrle"); @@ -72,4 +81,63 @@ public class KVMGlobalConfig { public static GlobalConfig HOST_CONNECTION_CHECK_INTERVAL = new GlobalConfig(CATEGORY, "host.connection.check.interval"); @GlobalConfigValidation public static GlobalConfig CONNECTION_SERVER_UPDATE_INTERVAL = new GlobalConfig(CATEGORY, "connection.server.update.interval"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + public static GlobalConfig ENABLE_VM_MIGRATION_HOST_CPU_FUNCTION_CHECK = new GlobalConfig(CATEGORY, "enable.vm.migration.host.cpu.function.check"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @BindResourceConfig({VmInstanceVO.class}) + public static GlobalConfig REDIRECT_CONSOLE_LOG_TO_FILE = new GlobalConfig(CATEGORY, "redirect.vm.log.to.file"); + + // vm cpu features stored in cpuid + @GlobalConfigValidation(validValues = {"true", "false"}) + @BindResourceConfig({VmInstanceVO.class, ClusterVO.class}) + public static GlobalConfig VM_CPU_HYPERVISOR_FEATURE = new GlobalConfig(CATEGORY, "vm.cpu.hypervisor.feature"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @BindResourceConfig({VmInstanceVO.class}) + public static GlobalConfig VM_HYPERV_CLOCK_FEATURE = new GlobalConfig(CATEGORY, "vm.hyperv.clock.feature"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @BindResourceConfig({VmInstanceVO.class}) + public static GlobalConfig SUSPEND_TO_RAM = new GlobalConfig(CATEGORY, "vm.suspend.to.ram"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @BindResourceConfig({VmInstanceVO.class}) + public static GlobalConfig SUSPEND_TO_DISK = new GlobalConfig(CATEGORY, "vm.suspend.to.disk"); + + @GlobalConfigValidation(numberGreaterThan = 0) + public static GlobalConfig WEBSSH_IDLE_TIMEOUT = new GlobalConfig(CATEGORY, "webssh.idleTimeout"); + + @GlobalConfigValidation(numberGreaterThan = 0) + @GlobalConfigDef(defaultValue = "8888", type = Long.class, description = "the default port used by web-based SSH server") + public static GlobalConfig HOST_WEBSSH_PORT = new GlobalConfig(CATEGORY, "host.webssh.port"); + @GlobalConfigValidation(numberGreaterThan = 0) + @GlobalConfigDef(defaultValue = "8889", type = Long.class, description = "the default https port used by web-based SSH server") + public static GlobalConfig HOST_WEBSSH_HTTPS_PORT = new GlobalConfig(CATEGORY, "host.webssh.https.port"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @GlobalConfigDef(defaultValue = "false", type = Boolean.class, description = "enable install host shutdown hook") + public static GlobalConfig INSTALL_HOST_SHUTDOWN_HOOK = new GlobalConfig(CATEGORY, "install.host.shutdown.hook"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @GlobalConfigDef(defaultValue = "false", type = Boolean.class, description = "enable memory auto balloon") + @BindResourceConfig({VmInstanceVO.class, HostVO.class, ClusterVO.class}) + public static GlobalConfig MEMORY_AUTO_BALLOON = new GlobalConfig(CATEGORY, "memory.auto.balloon"); + + @GlobalConfigValidation(validValues = {"true", "false", "none"}) + @GlobalConfigDef(defaultValue = "none", description = "enable host ksm") + @BindResourceConfig({HostVO.class}) + public static GlobalConfig HOST_KSM = new GlobalConfig(CATEGORY, "host.ksm"); + + @GlobalConfigValidation(validValues = {"true", "false"}) + @GlobalConfigDef(defaultValue = "false", description = "restart kvm host libvirtd service or not") + @BindResourceConfig({HostVO.class, ClusterVO.class}) + public static GlobalConfig RECONNECT_HOST_RESTART_LIBVIRTD_SERVICE = new GlobalConfig(CATEGORY, "reconnect.host.restart.libvirtd.service"); + + @GlobalConfigValidation + public static GlobalConfig KVMAGENT_PHYSICAL_MEMORY_USAGE_ALARM_THRESHOLD = new GlobalConfig(CATEGORY, "kvmagent.physicalmemory.usage.alarm.threshold"); + + @GlobalConfigValidation + public static GlobalConfig KVMAGENT_PHYSICAL_MEMORY_USAGE_HARD_LIMIT = new GlobalConfig(CATEGORY, "kvmagent.physicalmemory.usage.hardlimit"); } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalProperty.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalProperty.java index 8a99fb2ef54..7ee841b5051 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalProperty.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalProperty.java @@ -2,6 +2,7 @@ import org.zstack.core.GlobalProperty; import org.zstack.core.GlobalPropertyDefinition; +import org.zstack.core.propertyvalidator.AvailableValues; import java.util.List; @@ -9,7 +10,7 @@ */ @GlobalPropertyDefinition public class KVMGlobalProperty { - @GlobalProperty(name="KvmAgent.agentPackageName", defaultValue = "kvmagent-4.4.0.tar.gz") + @GlobalProperty(name="KvmAgent.agentPackageName", defaultValue = "kvmagent-5.4.0.tar.gz") public static String AGENT_PACKAGE_NAME; @GlobalProperty(name="KvmAgent.agentUrlRootPath", defaultValue = "") public static String AGENT_URL_ROOT_PATH; @@ -29,7 +30,13 @@ public class KVMGlobalProperty { public static String TAKEVOERFLAGPATH; @GlobalProperty(name="MN.network.", defaultValue = "") public static List MN_NETWORKS; - @GlobalProperty(name = "host.skip.packages", defaultValue = "qemu-kvm-ev, qemu-img-ev") + @GlobalProperty(name = "host.skip.packages", defaultValue = "qemu, qemu-kvm, qemu-kvm-ev, qemu-img, qemu-img-ev") public static String SKIP_PACKAGES; + @GlobalProperty(name = "host.stop.shutdown.vm", defaultValue = "false") + public static boolean HOST_STOP_SHUTDOWN_VM; + + @GlobalProperty(name = "host.network.need.alarm.interface.service", defaultListValue = {"ManagementNetwork", "MigrationNetwork"}) + @AvailableValues(value = {"ManagementNetwork", "TenantNetwork", "StorageNetwork", "BackupNetwork", "MigrationNetwork"}) + public static List HOST_NETWORK_NEED_ALARM_INTERFACE_SERVICE; } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMGuestOsCharacterExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMGuestOsCharacterExtensionPoint.java new file mode 100644 index 00000000000..4c74d1d24cc --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMGuestOsCharacterExtensionPoint.java @@ -0,0 +1,71 @@ +package org.zstack.kvm; + +import org.zstack.core.config.GuestOsHelper; +import org.zstack.core.config.schema.GuestOsCharacter; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.vm.VmAfterAttachNicExtensionPoint; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicSetDriverExtensionPoint; +import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vm.VmNicVO_; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class KVMGuestOsCharacterExtensionPoint implements + VmAfterAttachNicExtensionPoint, + VmNicSetDriverExtensionPoint +{ + private static final CLogger logger = Utils.getLogger(KVMGuestOsCharacterExtensionPoint.class); + + private String getNicDriverFromConfig(VmInstanceInventory vm) { + GuestOsCharacter.Config config = GuestOsHelper.getInstance() + .getGuestOsCharacter( + vm.getArchitecture(), + vm.getPlatform(), + vm.getGuestOsType()); + if (config == null) { + logger.warn(String.format("cannot find guest os character for vm[uuid:%s, arch:%s, platform:%s, guestOsType:%s]", + vm.getUuid(), vm.getArchitecture(), vm.getPlatform(), vm.getGuestOsType())); + return null; + } + + return config.getNicDriver(); + } + + @Override + public void afterAttachNic(String nicUuid, VmInstanceInventory vmInstanceInventory, Completion completion) { + if (!Q.New(VmNicVO.class) + .eq(VmNicVO_.uuid, nicUuid) + .isExists()) { + logger.warn(String.format("cannot find nic[uuid:%s]", nicUuid)); + completion.success(); + return; + } + + String driver = getNicDriverFromConfig(vmInstanceInventory); + if (driver == null) { + completion.success(); + return; + } + + SQL.New(VmNicVO.class) + .eq(VmNicVO_.uuid, nicUuid) + .set(VmNicVO_.driverType, driver) + .update(); + logger.debug(String.format("set nic[uuid:%s] driver type to %s", nicUuid, driver)); + completion.success(); + } + + @Override + public void afterAttachNicRollback(String nicUuid, VmInstanceInventory vmInstanceInventory, NoErrorCompletion completion) { + completion.done(); + } + + @Override + public String getPreferredVmNicDriver(VmInstanceInventory vm) { + return getNicDriverFromConfig(vm); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java index dac1e6fa18b..ab8c29640f3 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java @@ -1,5 +1,6 @@ package org.zstack.kvm; +import okhttp3.Response; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.util.Strings; import org.springframework.beans.factory.annotation.Autowired; @@ -8,31 +9,48 @@ import org.springframework.web.client.RestClientException; import org.springframework.web.util.UriComponentsBuilder; import org.zstack.compute.cluster.ClusterGlobalConfig; +import org.zstack.compute.cluster.arch.ClusterResourceConfigInitializer; import org.zstack.compute.host.*; import org.zstack.compute.vm.*; +import org.zstack.core.timeout.TimeHelper; +import org.zstack.header.core.*; +import org.zstack.header.vm.devices.VirtualDeviceInfo; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.MessageCommandRecorder; import org.zstack.core.Platform; import org.zstack.core.agent.AgentConstant; import org.zstack.core.ansible.*; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.CloudBusGlobalProperty; +import org.zstack.core.cloudbus.ResourceDestinationMaker; import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.config.GuestOsHelper; +import org.zstack.core.config.schema.GuestOsCharacter; import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.db.SQLBatch; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.thread.*; import org.zstack.core.timeout.ApiTimeoutManager; +import org.zstack.core.timeout.TimeHelper; +import org.zstack.core.upgrade.UpgradeChecker; +import org.zstack.core.upgrade.UpgradeGlobalConfig; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.Constants; +import org.zstack.header.allocator.DesignatedAllocateHostMsg; import org.zstack.header.allocator.HostAllocatorConstant; +import org.zstack.header.allocator.ReturnHostCapacityMsg; +import org.zstack.header.cluster.ClusterInventory; import org.zstack.header.cluster.ClusterVO; import org.zstack.header.cluster.ReportHostCapacityMessage; -import org.zstack.header.core.AsyncLatch; -import org.zstack.header.core.Completion; -import org.zstack.header.core.NoErrorCompletion; -import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.*; +import org.zstack.header.core.progress.ChainInfo; +import org.zstack.header.core.progress.TaskInfo; import org.zstack.header.core.progress.TaskProgressRange; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; @@ -42,9 +60,7 @@ import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.*; import org.zstack.header.host.MigrateVmOnHypervisorMsg.StorageMigrationPolicy; -import org.zstack.header.image.ImageArchitecture; -import org.zstack.header.image.ImageBootMode; -import org.zstack.header.image.ImagePlatform; +import org.zstack.header.image.*; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; @@ -55,23 +71,31 @@ import org.zstack.header.rest.JsonAsyncRESTCallback; import org.zstack.header.rest.RESTFacade; import org.zstack.header.storage.primary.*; -import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; import org.zstack.header.tag.SystemTagInventory; import org.zstack.header.vm.*; -import org.zstack.header.volume.VolumeInventory; -import org.zstack.header.volume.VolumeType; -import org.zstack.header.volume.VolumeVO; +import org.zstack.header.vm.devices.DeviceAddress; +import org.zstack.header.vm.devices.VirtualDeviceInfo; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; +import org.zstack.header.volume.*; +import org.zstack.identity.AccountManager; import org.zstack.kvm.KVMAgentCommands.*; import org.zstack.kvm.KVMConstant.KvmVmState; +import org.zstack.kvm.hypervisor.KvmHypervisorInfoHelper; +import org.zstack.kvm.hypervisor.KvmHypervisorInfoManager; import org.zstack.network.l3.NetworkGlobalProperty; import org.zstack.resourceconfig.ResourceConfig; import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.resourceconfig.ResourceConfigVO; +import org.zstack.resourceconfig.ResourceConfigVO_; +import org.zstack.tag.PatternedSystemTag; import org.zstack.tag.SystemTag; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; import org.zstack.utils.*; +import org.zstack.utils.data.SizeUnit; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.message.OperationChecker; import org.zstack.utils.network.NetworkUtils; import org.zstack.utils.path.PathUtil; import org.zstack.utils.ssh.Ssh; @@ -81,19 +105,26 @@ import org.zstack.utils.tester.ZTester; import javax.persistence.TypedQuery; +import java.io.IOException; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Consumer; import java.util.stream.Collectors; import static org.zstack.core.Platform.*; import static org.zstack.core.progress.ProgressReportService.*; -import static org.zstack.kvm.KVMHostFactory.allGuestOsCharacter; +import static org.zstack.header.host.GetVirtualizerInfoReply.VmVirtualizerInfo; +import static org.zstack.kvm.KvmHostUpdateOsExtensionPoint.UPDATE_OS_RSP; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; public class KVMHost extends HostBase implements Host { private static final CLogger logger = Utils.getLogger(KVMHost.class); private static final ZTester tester = Utils.getTester(); + protected static OperationChecker allowedOperations = new OperationChecker(true); + protected static OperationChecker skipOperations = new OperationChecker(true); @Autowired @Qualifier("KVMHostFactory") @@ -118,6 +149,22 @@ public class KVMHost extends HostBase implements Host { private DeviceBootOrderOperator deviceBootOrderOperator; @Autowired private VmNicManager nicManager; + @Autowired + private ClusterResourceConfigInitializer crci; + @Autowired + private VmInstanceDeviceManager vidm; + @Autowired + private KvmHypervisorInfoManager hypervisorManager; + @Autowired + private KvmHostIpmiPowerExecutor kvmHostIpmiPowerExecutor; + @Autowired + private TimeHelper timeHelper; + @Autowired + private AccountManager accountMgr; + @Autowired + private UpgradeChecker upgradeChecker; + @Autowired + private ResourceDestinationMaker destMaker; private KVMHostContext context; @@ -138,7 +185,10 @@ public class KVMHost extends HostBase implements Host { private String echoPath; private String attachNicPath; private String detachNicPath; + private String changeNicStatePath; private String migrateVmPath; + private String getCpuXmlPath; + private String compareCpuFunctionPath; private String snapshotPath; private String checkSnapshotPath; private String mergeSnapshotPath; @@ -155,11 +205,13 @@ public class KVMHost extends HostBase implements Host { private String updateHostOSPath; private String updateDependencyPath; private String shutdownHost; + private String rebootHost; private String updateVmPriorityPath; private String updateSpiceChannelConfigPath; private String cancelJob; private String getVmFirstBootDevicePath; private String getVmDeviceAddressPath; + private String getVirtualizerInfo; private String scanVmPortPath; private String getDevCapacityPath; private String configPrimaryVmPath; @@ -167,7 +219,12 @@ public class KVMHost extends HostBase implements Host { private String startColoSyncPath; private String registerPrimaryVmHeartbeatPath; private String getHostNumaPath; - + private String syncVmDeviceInfo; + private String attachVolumePath; + private String detachVolumePath; + private String vmFstrimPath; + private String blockCommitPath; + private String blockPullPath; private String agentPackageName = KVMGlobalProperty.AGENT_PACKAGE_NAME; private String hostTakeOverFlagPath = KVMGlobalProperty.TAKEVOERFLAGPATH; @@ -237,10 +294,22 @@ public KVMHost(KVMHostVO self, KVMHostContext context) { ub.path(KVMConstant.KVM_DETACH_NIC_PATH); detachNicPath = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_CHANGE_NIC_STATE_PATH); + changeNicStatePath = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); ub.path(KVMConstant.KVM_MIGRATE_VM_PATH); migrateVmPath = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_GET_CPU_XML_PATH); + getCpuXmlPath = ub.build().toString(); + + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_COMPARE_CPU_FUNCTION_PATH); + compareCpuFunctionPath = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); ub.path(KVMConstant.KVM_TAKE_VOLUME_SNAPSHOT_PATH); snapshotPath = ub.build().toString(); @@ -305,6 +374,10 @@ public KVMHost(KVMHostVO self, KVMHostContext context) { ub.path(KVMConstant.HOST_SHUTDOWN); shutdownHost = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.HOST_REBOOT); + rebootHost = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); ub.path(KVMConstant.KVM_VM_UPDATE_PRIORITY_PATH); updateVmPriorityPath = ub.build().toString(); @@ -325,6 +398,10 @@ public KVMHost(KVMHostVO self, KVMHostContext context) { ub.path(KVMConstant.GET_VM_DEVICE_ADDRESS_PATH); getVmDeviceAddressPath = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.GET_VIRTUALIZER_INFO_PATH); + getVirtualizerInfo = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); ub.path(KVMConstant.KVM_SCAN_VM_PORT_STATUS); scanVmPortPath = ub.build().toString(); @@ -353,6 +430,37 @@ public KVMHost(KVMHostVO self, KVMHostContext context) { ub.path(KVMConstant.KVM_HOST_NUMA_PATH); getHostNumaPath = ub.build().toString(); + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_SYNC_VM_DEVICEINFO_PATH); + syncVmDeviceInfo = ub.build().toString(); + + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_HOST_ATTACH_VOLUME_PATH); + attachVolumePath = ub.build().toString(); + + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_HOST_DETACH_VOLUME_PATH); + detachVolumePath = ub.build().toString(); + + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.FSTRIM_VM_PATH); + vmFstrimPath = ub.build().toString(); + + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_BLOCK_COMMIT_VOLUME_PATH); + blockCommitPath = ub.build().toString(); + + ub = UriComponentsBuilder.fromHttpUrl(baseUrl); + ub.path(KVMConstant.KVM_BLOCK_PULL_VOLUME_PATH); + blockPullPath = ub.build().toString(); + } + + static { + allowedOperations + .addState(VmInstanceState.Running, AttachVolumeToVmOnHypervisorMsg.class.getName()) + .addState(VmInstanceState.Paused, AttachVolumeToVmOnHypervisorMsg.class.getName()); + skipOperations + .addState(VmInstanceState.Stopped, AttachVolumeToVmOnHypervisorMsg.class.getName()); } class Http { @@ -360,10 +468,12 @@ class Http { AgentCommand cmd; Class responseClass; String commandStr; + String commandName; - public Http(String path, String cmd, Class rspClz) { + public Http(String path, String cmd, String commandName, Class rspClz) { this.path = path; this.commandStr = cmd; + this.commandName = commandName; this.responseClass = rspClz; } @@ -371,6 +481,7 @@ public Http(String path, AgentCommand cmd, Class rspClz) { this.path = path; this.cmd = cmd; this.responseClass = rspClz; + this.commandName = cmd.getClass().getName(); } void call(ReturnValueCompletion completion) { @@ -378,6 +489,12 @@ void call(ReturnValueCompletion completion) { } void call(String resourceUuid, ReturnValueCompletion completion) { + ErrorCode errorCode = upgradeChecker.checkAgentHttpParamChanges(self.getUuid(), commandName, commandStr != null ? commandStr : cmd); + if (errorCode != null) { + completion.fail(errorCode); + return; + } + Map header = new HashMap<>(); header.put(Constants.AGENT_HTTP_HEADER_RESOURCE_UUID, resourceUuid == null ? self.getUuid() : resourceUuid); runBeforeAsyncJsonPostExts(header); @@ -457,7 +574,7 @@ void runBeforeAsyncJsonPostExts(Map header) { } } } - + @Override protected void handleApiMessage(APIMessage msg) { super.handleApiMessage(msg); @@ -473,6 +590,8 @@ protected void handleLocalMessage(Message msg) { handle((StartVmOnHypervisorMsg) msg); } else if (msg instanceof CreateVmOnHypervisorMsg) { handle((CreateVmOnHypervisorMsg) msg); + } else if (msg instanceof UpdateVmOnHypervisorMsg) { + handle((UpdateVmOnHypervisorMsg) msg); } else if (msg instanceof UpdateSpiceChannelConfigMsg) { handle((UpdateSpiceChannelConfigMsg) msg); } else if (msg instanceof StopVmOnHypervisorMsg) { @@ -491,6 +610,12 @@ protected void handleLocalMessage(Message msg) { handle((VmUpdateNicOnHypervisorMsg) msg); } else if (msg instanceof MigrateVmOnHypervisorMsg) { handle((MigrateVmOnHypervisorMsg) msg); + } else if (msg instanceof GetCpuFunctionXmlOnHostMsg) { + handle((GetCpuFunctionXmlOnHostMsg) msg); + } else if (msg instanceof CompareCpuFunctionOnHostMsg) { + handle((CompareCpuFunctionOnHostMsg) msg); + } else if (msg instanceof CreateCpuFeaturesHistoryMsg) { + handle((CreateCpuFeaturesHistoryMsg) msg); } else if (msg instanceof TakeSnapshotOnHypervisorMsg) { handle((TakeSnapshotOnHypervisorMsg) msg); } else if (msg instanceof CheckSnapshotOnHypervisorMsg) { @@ -503,6 +628,8 @@ protected void handleLocalMessage(Message msg) { handle((KVMHostSyncHttpCallMsg) msg); } else if (msg instanceof DetachNicFromVmOnHypervisorMsg) { handle((DetachNicFromVmOnHypervisorMsg) msg); + } else if (msg instanceof ChangeVmNicStateOnHypervisorMsg) { + handle((ChangeVmNicStateOnHypervisorMsg) msg); } else if (msg instanceof AttachIsoOnHypervisorMsg) { handle((AttachIsoOnHypervisorMsg) msg); } else if (msg instanceof DetachIsoOnHypervisorMsg) { @@ -529,12 +656,18 @@ protected void handleLocalMessage(Message msg) { handle((GetKVMHostDownloadCredentialMsg) msg); } else if (msg instanceof ShutdownHostMsg) { handle((ShutdownHostMsg) msg); - } else if (msg instanceof CancelHostTaskMsg) { + } else if (msg instanceof RebootHostMsg) { + handle((RebootHostMsg) msg); + } else if (msg instanceof PowerOnHostMsg) { + handle((PowerOnHostMsg) msg); + }else if (msg instanceof CancelHostTaskMsg) { handle((CancelHostTaskMsg) msg); } else if (msg instanceof GetVmFirstBootDeviceOnHypervisorMsg) { handle((GetVmFirstBootDeviceOnHypervisorMsg) msg); } else if (msg instanceof GetVmDeviceAddressMsg) { handle((GetVmDeviceAddressMsg) msg); + } else if (msg instanceof GetVirtualizerInfoMsg) { + handle((GetVirtualizerInfoMsg) msg); } else if (msg instanceof CheckHostCapacityMsg) { handle((CheckHostCapacityMsg) msg); } else if (msg instanceof ConfigPrimaryVmMsg) { @@ -551,168 +684,308 @@ protected void handleLocalMessage(Message msg) { handle((CheckFileOnHostMsg) msg); } else if (msg instanceof GetHostNumaTopologyMsg) { handle((GetHostNumaTopologyMsg) msg); + } else if (msg instanceof SyncVmDeviceInfoMsg) { + handle((SyncVmDeviceInfoMsg) msg); + } else if (msg instanceof AttachDataVolumeToHostMsg) { + handle((AttachDataVolumeToHostMsg) msg); + } else if (msg instanceof DetachDataVolumeFromHostMsg) { + handle((DetachDataVolumeFromHostMsg) msg); + } else if (msg instanceof GetHostWebSshUrlMsg) { + handle((GetHostWebSshUrlMsg) msg); + } else if (msg instanceof GetHostPowerStatusMsg) { + handle((GetHostPowerStatusMsg) msg); + } else if (msg instanceof FstrimVmMsg) { + handle((FstrimVmMsg) msg); + } else if (msg instanceof CommitVolumeSnapshotOnHypervisorMsg) { + handle((CommitVolumeSnapshotOnHypervisorMsg) msg); + } else if (msg instanceof PullVolumeSnapshotOnHypervisorMsg) { + handle((PullVolumeSnapshotOnHypervisorMsg) msg); + } else if (msg instanceof TakeVmConsoleScreenshotMsg) { + handle((TakeVmConsoleScreenshotMsg) msg); + } else if (msg instanceof RestartKvmAgentMsg) { + handle((RestartKvmAgentMsg) msg); } else { super.handleLocalMessage(msg); } } - private void handle(GetHostNumaTopologyMsg msg) { - GetHostNumaTopologyReply reply = new GetHostNumaTopologyReply(); - FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + private void handle(RestartKvmAgentMsg msg) { + RestartKvmAgentReply reply = new RestartKvmAgentReply(); + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("restart-kvmagent-on-host-%s", msg.getHostUuid())) + .run(completion -> { + if (!destMaker.isManagedByUs(msg.getHostUuid())) { + completion.fail(operr("host %s is not managed by current mn node", msg.getHostUuid())); + return; + } - GetHostNUMATopologyCmd cmd = new GetHostNUMATopologyCmd(); - cmd.setHostUuid(msg.getHostUuid()); + restartKvmAgentOnHost(msg.isForce(), new Completion(completion) { + @Override + public void success() { + completion.success(null); + } - new Http<>(getHostNumaPath, cmd, GetHostNUMATopologyResponse.class).call(msg.getHostUuid(), new ReturnValueCompletion(msg) { - @Override - public void success(GetHostNUMATopologyResponse ret) { - if (!ret.isSuccess()) { - ErrorCode err = Platform.err(SysErrors.OPERATION_ERROR, ret.getError()); - reply.setError(err); - } else { - reply.setNuma(ret.getTopology()); + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + }).done(result -> { + if (!result.isSuccess()) { + reply.setError(result.getErrorCode()); + } + bus.reply(msg, reply); + }) + ); + } + + private void noRunningTaskOnHost(ReturnValueCompletion completion) { + String syncSignature = Host.buildId(self.getUuid()); + List nodeUuids = destMaker.getAllNodeInfo().stream().map(ResourceDestinationMaker.NodeInfo::getNodeUuid) + .collect(Collectors.toList()); + + AtomicBoolean queueIsEmpty = new AtomicBoolean(true); + new While<>(nodeUuids).step((mnId, compl) -> { + GetLocalTaskMsg gmsg = new GetLocalTaskMsg(); + gmsg.setOnlyRunningTask(true); + gmsg.setSyncSignatures(Collections.singletonList(syncSignature)); + bus.makeServiceIdByManagementNodeId(gmsg, CoreConstant.SERVICE_ID, mnId); + bus.send(gmsg, new CloudBusCallBack(compl) { + private String buildTaskInfo(List tasks) { + return tasks.stream().map(TaskInfo::getContext).collect(Collectors.joining("\n")); } - bus.reply(msg, reply); - } + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + compl.addError(r.getError()); + compl.allDone(); + return; + } + GetLocalTaskReply gr = r.castReply(); + ChainInfo chainInfo = gr.getResults().get(syncSignature); + if (!chainInfo.getRunningTask().isEmpty()) { + logger.debug(String.format("%s tasks exist on the running task of host %s, mnNodeId %s: %s...", chainInfo.getRunningTask().size(), + self.getUuid(), mnId, buildTaskInfo(chainInfo.getRunningTask()))); + queueIsEmpty.set(false); + compl.allDone(); + return; + } + compl.done(); + } + }); + }, 2).run(new WhileDoneCompletion(completion) { @Override - public void fail(ErrorCode errorCode) { - reply.setError(errorCode); - bus.reply(msg, reply); + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList); + return; + } + completion.success(queueIsEmpty.get()); } }); } - private void handle(AllocateHostPortMsg msg) { - thdf.chainSubmit(new ChainTask(msg) { + private void restartKvmAgentOnHost(boolean force, Completion completion) { + SimpleFlowChain chain = new SimpleFlowChain(); + chain.setChainName("try-restart-kvmagent-on-host-" + self.getUuid()); + chain.then(new Flow() { + // changing the host connection status to 'Connecting' is to prevent sending HTTP requests to the kvmagent, + // which needs to be done before checking the host task queue + String __name__ = "change host state to connecting"; + @Override - public String getSyncSignature() { - return String.format("allocate-host-%s-port", msg.getHostUuid()); + public void run(FlowTrigger trigger, Map data) { + if (self.getStatus() != HostStatus.Connected) { + trigger.fail(operr("host %s is not connected, skip to restart kvmagent", self.getUuid())); + return; + } + changeConnectionState(HostStatusEvent.connecting); + trigger.next(); } @Override - public void run(SyncTaskChain chain) { - AllocateHostPortReply reply = new AllocateHostPortReply(); - reply.setHostPortIds(new ArrayList<>()); - HostPortGetter portGetter = new HostPortGetter(); - for (int i = 0; i < msg.getAllocateCount(); i++) { - HostPortVO vo = portGetter.getNextHostPort(msg.getHostUuid(), ""); - reply.getHostPortIds().add(vo.getId()); + public void rollback(FlowRollback trigger, Map data) { + if (self.getStatus() == HostStatus.Connecting) { + changeConnectionState(HostStatusEvent.connected); } - - bus.reply(msg, reply); - chain.next(); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "check if the host task queue is empty"; + @Override + public boolean skip(Map data) { + return force; } @Override - public String getName() { - return String.format("allocate-host-%s-port", msg.getHostUuid()); + public void run(FlowTrigger trigger, Map data) { + noRunningTaskOnHost(new ReturnValueCompletion(trigger) { + @Override + public void success(Boolean noTask) { + if (noTask) { + trigger.next(); + } else { + trigger.fail(operr("running task exists on host %s", self.getUuid())); + } + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "restart kvmagent on host " + self.getUuid(); + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; } - }); - } - private void handle(CheckHostCapacityMsg msg) { - CheckHostCapacityReply re = new CheckHostCapacityReply(); - KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); - kmsg.setHostUuid(msg.getHostUuid()); - kmsg.setPath(KVMConstant.KVM_HOST_CAPACITY_PATH); - kmsg.setNoStatusCheck(true); - kmsg.setCommand(new HostCapacityCmd()); - bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, msg.getHostUuid()); - bus.send(kmsg, new CloudBusCallBack(msg) { @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - throw new OperationFailureException(operr("check host capacity failed, because:%s", reply.getError())); + public void run(FlowTrigger trigger, Map data) { + SshShell sshShell = new SshShell(); + sshShell.setHostname(getSelf().getManagementIp()); + sshShell.setUsername(getSelf().getUsername()); + sshShell.setPassword(getSelf().getPassword()); + sshShell.setPort(getSelf().getPort()); + SshResult ret = sshShell.runCommand("sudo service zstack-kvmagent restart"); + + if (ret.isSshFailure() || ret.getReturnCode() != 0) { + trigger.fail(operr(ret.getExitErrorMessage())); + } else { + trigger.next(); } + } + }).then(new NoRollbackFlow() { + String __name__ = "wait for kvmagent to be ready"; - KVMHostAsyncHttpCallReply r = reply.castReply(); - HostCapacityResponse rsp = r.toResponse(HostCapacityResponse.class); - if (!rsp.isSuccess()) { - throw new OperationFailureException(operr("operation error, because:%s", rsp.getError())); - } + @Override + public void run(FlowTrigger trigger, Map data) { + int retryCount = 60; + While.makeRetryWhile(retryCount).each((currentStep, compl) -> { + PingCmd cmd = new PingCmd(); + cmd.hostUuid = self.getUuid(); + restf.asyncJsonPost(pingPath, cmd, new JsonAsyncRESTCallback(compl) { + @Override + public void fail(ErrorCode err) { + try { + if (currentStep < retryCount) { + TimeUnit.SECONDS.sleep(1); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + compl.addError(err); + compl.done(); + } + } - long reservedSize = SizeUtils.sizeStringToBytes(rcf.getResourceConfigValue(KVMGlobalConfig.RESERVED_MEMORY_CAPACITY, msg.getHostUuid(), String.class)); - if (rsp.getTotalMemory() < reservedSize) { - throw new OperationFailureException(operr("The host[uuid:%s]'s available memory capacity[%s] is lower than the reserved capacity[%s]", - msg.getHostUuid(), rsp.getTotalMemory(), reservedSize)); - } + @Override + public void success(PingResponse ret) { + compl.allDone(); + } - ReportHostCapacityMessage rmsg = new ReportHostCapacityMessage(); - rmsg.setHostUuid(msg.getHostUuid()); - rmsg.setCpuNum((int) rsp.getCpuNum()); - rmsg.setUsedCpu(rsp.getUsedCpu()); - rmsg.setTotalMemory(rsp.getTotalMemory()); - rmsg.setUsedMemory(rsp.getUsedMemory()); - rmsg.setCpuSockets(rsp.getCpuSockets()); - rmsg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); - bus.send(rmsg, new CloudBusCallBack(msg) { + @Override + public Class getReturnClass() { + return PingResponse.class; + } + }, TimeUnit.SECONDS, HostGlobalConfig.PING_HOST_TIMEOUT.value(Long.class)); + }).run(new WhileDoneCompletion(trigger) { @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - re.setError(reply.getError()); + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().size() == retryCount) { + logger.debug("waiting for kvmagent to start timeout: " + errorCodeList.getCauses().get(0).getDetails()); } - - bus.reply(msg, re); + trigger.next(); } }); } - }); + }).then(new NoRollbackFlow() { + String __name__ = String.format("reconnect host %s after restart kvmagent", self.getUuid()); + + public void run(FlowTrigger trigger, Map data) { + ReconnectHostMsg rmsg = new ReconnectHostMsg(); + rmsg.setHostUuid(self.getUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, HostConstant.SERVICE_ID, self.getUuid()); + bus.send(rmsg); + trigger.next(); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); } - private void handle(RegisterColoPrimaryCheckMsg msg) { - inQueue().name(String.format("register-vm-heart-beat-on-%s", self.getUuid())) - .asyncBackup(msg) - .run(chain -> registerPrimaryVmHeartbeat(msg, new NoErrorCompletion(chain) { - @Override - public void done() { - chain.next(); + private void handle(TakeVmConsoleScreenshotMsg msg) { + TakeVmConsoleScreenshotReply reply = new TakeVmConsoleScreenshotReply(); + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("take-vm-%s-console-screenshot-on-host-%s", msg.getVmInstanceUuid(), msg.getHostUuid())) + .run(completion -> { + takeVmConsoleScreenshot(msg.getVmInstanceUuid(), msg.getHostUuid(), new ReturnValueCompletion(completion) { + @Override + public void success(TakeVmConsoleScreenshotRsp returnValue) { + completion.success(returnValue.getImageData()); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + }) + .done(result -> { + if (result.isSuccess()) { + String returnValue = (String)result.getResult(); + reply.setImageData(returnValue); + } else { + reply.setError(result.getErrorCode()); } - })); + bus.reply(msg, reply); + }) + ); } - private void registerPrimaryVmHeartbeat(RegisterColoPrimaryCheckMsg msg, NoErrorCompletion completion) { - RegisterPrimaryVmHeartbeatCmd cmd = new RegisterPrimaryVmHeartbeatCmd(); - cmd.setHostUuid(msg.getHostUuid()); - cmd.setVmInstanceUuid(msg.getVmInstanceUuid()); - cmd.setHeartbeatPort(msg.getHeartbeatPort()); - cmd.setTargetHostIp(msg.getTargetHostIp()); - cmd.setColoPrimary(msg.isColoPrimary()); - cmd.setRedirectNum(msg.getRedirectNum()); - - VmInstanceVO vm = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); - List volumes = vm.getAllVolumes().stream().filter(v -> v.getType() == VolumeType.Data || v.getType() == VolumeType.Root).map(VolumeInventory::valueOf).collect(Collectors.toList()); - cmd.setVolumes(VolumeTO.valueOf(volumes, KVMHostInventory.valueOf(getSelf()))); + private void takeVmConsoleScreenshot(String vmInstanceUuid, String hostUuid, ReturnValueCompletion completion) { + TakeVmConsoleScreenshotCmd cmd = new TakeVmConsoleScreenshotCmd(); + cmd.setVmUuid(vmInstanceUuid); - new Http<>(registerPrimaryVmHeartbeatPath, cmd, AgentResponse.class).call(new ReturnValueCompletion(msg, completion) { + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setCommand(cmd); + kmsg.setPath(KVMConstant.TAKE_VM_CONSOLE_SCREENSHOT_PATH); + kmsg.setHostUuid(hostUuid); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, hostUuid); + bus.send(kmsg, new CloudBusCallBack(completion) { @Override - public void success(AgentResponse ret) { - final StartColoSyncReply reply = new StartColoSyncReply(); - if (!ret.isSuccess()) { - reply.setError(operr("unable to register colo heartbeat for vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", - msg.getVmInstanceUuid(), self.getUuid(), self.getManagementIp(), ret.getError())); - } else { - logger.debug(String.format("unable to register colo heartbeat for vm[uuid:%s] on kvm host[uuid:%s] success", msg.getVmInstanceUuid(), self.getUuid())); + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; } - bus.reply(msg, reply); - completion.done(); - } - - @Override - public void fail(ErrorCode err) { - final StartColoSyncReply reply = new StartColoSyncReply(); - reply.setError(err); - bus.reply(msg, reply); - completion.done(); + KVMHostAsyncHttpCallReply r = reply.castReply(); + TakeVmConsoleScreenshotRsp rsp = r.toResponse(TakeVmConsoleScreenshotRsp.class); + if (!rsp.isSuccess()) { + completion.fail(operr(rsp.getError())); + } else { + completion.success(r.toResponse(TakeVmConsoleScreenshotRsp.class)); + } } }); } - private void handle(StartColoSyncMsg msg) { - inQueue().name(String.format("start-colo-sync-vm-%s-on-%s", msg.getVmInstanceUuid(), self.getUuid())) + private void handle(CommitVolumeSnapshotOnHypervisorMsg msg) { + inQueue().name(String.format("commit-volume-snapshot-on-kvm-%s", self.getUuid())) .asyncBackup(msg) - .run(chain -> startColoSync(msg, new NoErrorCompletion(chain) { + .run(chain -> commitVolumeSnapshot(msg, new NoErrorCompletion(chain) { @Override public void done() { chain.next(); @@ -720,26 +993,905 @@ public void done() { })); } - private void startColoSync(StartColoSyncMsg msg, NoErrorCompletion completion) { - StartColoSyncCmd cmd = new StartColoSyncCmd(); - cmd.setVmInstanceUuid(msg.getVmInstanceUuid()); - cmd.setBlockReplicationPort(msg.getBlockReplicationPort()); - cmd.setNbdServerPort(msg.getNbdServerPort()); - cmd.setSecondaryVmHostIp(msg.getSecondaryVmHostIp()); - cmd.setCheckpointDelay(msg.getCheckpointDelay()); - cmd.setFullSync(msg.isFullSync()); + private void commitVolumeSnapshot(final CommitVolumeSnapshotOnHypervisorMsg msg, final NoErrorCompletion completion) { + checkStateAndStatus(); - VmInstanceVO vm = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); - List volumes = vm.getAllVolumes().stream().filter(v -> v.getType() == VolumeType.Data || v.getType() == VolumeType.Root).map(VolumeInventory::valueOf).collect(Collectors.toList()); - cmd.setVolumes(VolumeTO.valueOf(volumes, KVMHostInventory.valueOf(getSelf()))); + CommitVolumeSnapshotOnHypervisorReply reply = new CommitVolumeSnapshotOnHypervisorReply(); + BlockCommitCmd cmd = new BlockCommitCmd(); + cmd.setVmUuid(msg.getVolume().getVmInstanceUuid()); + cmd.setVolume(VolumeTO.valueOf(msg.getVolume(), (KVMHostInventory) getSelfInventory())); + cmd.setTop(msg.getSrcSnapshot().getPrimaryStorageInstallPath()); + cmd.setBase(msg.getDstSnapshot().getPrimaryStorageInstallPath()); + cmd.setTopChildrenInstallPathInDb(msg.getSrcChildrenInstallPathInDb()); - List nics = new ArrayList<>(); - for (VmNicInventory nic : msg.getNics()) { - NicTO to = completeNicInfo(nic); - nics.add(to); - } - nics = nics.stream().sorted(Comparator.comparing(NicTO::getDeviceId)).collect(Collectors.toList()); - cmd.setNics(nics); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("block-commit-for-volume-%s", msg.getVolume().getUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = String.format("before-block-commit-for-volume-%s", msg.getVolume().getUuid()); + + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.beforeCommitVolume((KVMHostInventory) getSelfInventory(), msg, cmd, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = String.format("do-block-commit-for-volume-%s", msg.getVolume().getUuid()); + + @Override + public void run(FlowTrigger trigger, Map data) { + new Http<>(blockCommitPath, cmd, BlockCommitResponse.class).call(new ReturnValueCompletion(msg, completion) { + @Override + public void success(BlockCommitResponse ret) { + if (!ret.isSuccess()) { + ErrorCode err = operr("operation error, because:%s", ret.getError()); + extEmitter.failedToCommitVolume((KVMHostInventory) getSelfInventory(), msg, cmd, ret, err); + trigger.fail(err); + return; + } + + reply.setSize(ret.getSize()); + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + extEmitter.failedToCommitVolume((KVMHostInventory) getSelfInventory(), msg, cmd, null, errorCode); + reply.setError(errorCode); + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = String.format("after-block-commit-for-volume-%s", msg.getVolume().getUuid()); + + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.afterCommitVolume((KVMHostInventory) getSelfInventory(), msg, cmd, reply, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + completion.done(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + reply.setError(errCode); + bus.reply(msg, reply); + completion.done(); + } + }); + } + }).start(); + } + + private void handle(final PullVolumeSnapshotOnHypervisorMsg msg) { + inQueue().name(String.format("pull-volume-snapshot-on-kvm-%s", self.getUuid())) + .asyncBackup(msg) + .run(chain -> pullVolumeSnapshot(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void pullVolumeSnapshot(PullVolumeSnapshotOnHypervisorMsg msg, final NoErrorCompletion completion) { + checkStateAndStatus(); + + final PullVolumeSnapshotOnHypervisorReply reply = new PullVolumeSnapshotOnHypervisorReply(); + BlockPullCmd cmd = new BlockPullCmd(); + cmd.setBase(msg.getSrcSnapshotParentPath()); + cmd.setVmUuid(msg.getVolume().getVmInstanceUuid()); + cmd.setVolume(VolumeTO.valueOf(msg.getVolume(), (KVMHostInventory) getSelfInventory())); + + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("block-pull-for-volume-%s", msg.getVolume().getUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = String.format("before-block-pull-for-volume-%s", msg.getVolume().getUuid()); + + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.beforePullVolume((KVMHostInventory) getSelfInventory(), msg, cmd, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = String.format("do-block-pull-for-volume-%s", msg.getVolume().getUuid()); + + @Override + public void run(FlowTrigger trigger, Map data) { + new Http<>(blockPullPath, cmd, BlockPullResponse.class).call(new ReturnValueCompletion(msg, completion) { + @Override + public void success(BlockPullResponse ret) { + if (!ret.isSuccess()) { + ErrorCode err = operr("operation error, because:%s", ret.getError()); + extEmitter.failedToPullVolume((KVMHostInventory) getSelfInventory(), msg, cmd, ret, err); + trigger.fail(err); + return; + } + + reply.setSize(ret.getSize()); + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + extEmitter.failedToPullVolume((KVMHostInventory) getSelfInventory(), msg, cmd, null, errorCode); + reply.setError(errorCode); + trigger.fail(errorCode); + } + }); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = String.format("after-block-pull-for-volume-%s", msg.getVolume().getUuid()); + + @Override + public void run(FlowTrigger trigger, Map data) { + extEmitter.afterPullVolume((KVMHostInventory) getSelfInventory(), msg, cmd, reply, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + completion.done(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + reply.setError(errCode); + bus.reply(msg, reply); + completion.done(); + } + }); + } + }).start(); + } + + private void handle(GetHostPowerStatusMsg msg) { + handleGetPowerStatusByIpmi(msg); + } + + private void handleGetPowerStatusByIpmi(GetHostPowerStatusMsg msg) { + GetHostPowerStatusReply reply = new GetHostPowerStatusReply(); + HostVO host = dbf.findByUuid(msg.getUuid(), HostVO.class); + HostIpmiVO ipmi = kvmHostIpmiPowerExecutor.refreshHostPowerStatus(host); + reply.setInventory(HostIpmiInventory.valueOf(ipmi)); + bus.reply(msg, reply); + } + + class WebSshResponseStruct { + String id; + String status; + String encoding; + } + + private void handle(GetHostWebSshUrlMsg msg) { + GetHostWebSshUrlReply reply = new GetHostWebSshUrlReply(); + String port; + String schema; + if (msg.getHttps()) { + port = KVMGlobalConfig.HOST_WEBSSH_HTTPS_PORT.value(); + schema = "wss"; + } else { + port = KVMGlobalConfig.HOST_WEBSSH_PORT.value(); + schema = "ws"; + } + if (CoreGlobalProperty.UNIT_TEST_ON) { + reply.setUrl(String.format("%s://{{ip}}:%s/ws?id=%s", schema, port, "mockId")); + bus.reply(msg, reply); + return; + } + + KVMHostVO host = dbf.findByUuid(msg.getHostUuid(), KVMHostVO.class); + + Map formMap = new HashMap<>(); + formMap.put("username", msg.getUserName()); + formMap.put("hostname", host.getManagementIp()); + formMap.put("port", host.getPort().toString()); + formMap.put("password", msg.getPassword()); + + HTTP.Builder hb = HTTP.post() + .url(String.format("http://localhost:%s", KVMGlobalConfig.HOST_WEBSSH_PORT.value())) + .formData(formMap); + + try (Response r = hb.callWithException()) { + // 1. webssh maybe is not running + if (!r.isSuccessful()) { + reply.setError(inerr("webssh server is unreachable for %s", r.message())); + reply.setSuccess(false); + bus.reply(msg, reply); + return; + } + + WebSshResponseStruct webSsh = JSONObjectUtil.toObject(Objects.requireNonNull(r.body()).string(), WebSshResponseStruct.class); + // 2. return id is null, because authentication fail or connections is full + if (null == webSsh.id) { + reply.setError(operr("ssh connect to host[%s] username[%s] on port[%s] failed, because %s", host.getUuid(), host.getUsername(), host.getPort(), webSsh.status)); + reply.setSuccess(false); + bus.reply(msg, reply); + return; + } + + reply.setUrl(String.format("%s://{{ip}}:%s/ws?id=%s", schema, port, webSsh.id)); + bus.reply(msg, reply); + } catch (IOException | NullPointerException e) { + throw new CloudRuntimeException( + String.format("get host[%s] webssh url failed. because %s", host.getUuid(), e.getMessage()) + ); + } + } + + private void handleRebootHostByIpmi(RebootHostMsg msg, NoErrorCompletion completion) { + RebootHostReply reply = new RebootHostReply(); + kvmHostIpmiPowerExecutor.powerReset(self, new Completion(msg, completion) { + @Override + public void success() { + changeConnectionState(HostStatusEvent.disconnected); + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + if (msg.isReturnEarly()) { + return; + } + reply.setSuccess(false); + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + }, msg.isReturnEarly()); + } + + private void handle(PowerOnHostMsg msg) { + inQueue().name(String.format("power-on-kvm-host-%s", self.getUuid())) + .asyncBackup(msg) + .run(chain -> handlePowerOnHost(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void handlePowerOnHost(PowerOnHostMsg msg, NoErrorCompletion completion) { + PowerOnHostReply reply = new PowerOnHostReply(); + Completion c = new Completion(msg, completion) { + @Override + public void success() { + if (msg.isReturnEarly()) { + bus.reply(msg, reply); + } else { + submitTaskWaitHostPowerOnByIpmi(); + } + completion.done(); + } + + private void submitTaskWaitHostPowerOnByIpmi() { + HostVO host = dbf.findByUuid(msg.getHostUuid(), HostVO.class); + long timeoutInSec = KVMConstant.KVM_HOST_POWER_OPERATION_TIMEOUT_SECONDS; + long ctimeout = TimeUnit.SECONDS.toMillis(timeoutInSec); + Long deadline = timeHelper.getCurrentTimeMillis() + ctimeout; + thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask() { + @Override + public boolean run() { + if (timeHelper.getCurrentTimeMillis() > deadline) { + reply.setError(operr(String.format("Host[%s] has not been power on within %d seconds for an unknown reason. Please check host status in BMC[%s]", msg.getHostUuid(), timeoutInSec, host.getIpmi().getIpmiAddress()))); + reply.setSuccess(false); + bus.reply(msg, reply); + HostIpmiVO ipmi = host.getIpmi(); + kvmHostIpmiPowerExecutor.updateIpmiPowerStatusInDB(ipmi, HostPowerStatus.POWER_OFF); + return true; + } + HostPowerStatus status = kvmHostIpmiPowerExecutor.refreshHostPowerStatus(host).getIpmiPowerStatus(); + if (HostPowerStatus.POWER_ON.equals(status)) { + bus.reply(msg, reply); + return true; + } + if (HostPowerStatus.POWER_OFF.equals(status)) { + HostIpmiVO ipmi = host.getIpmi(); + kvmHostIpmiPowerExecutor.updateIpmiPowerStatusInDB(ipmi, + HostPowerStatus.POWER_OFF.nextStatus(HostPowerStatusEvent.on)); + } + return false; + } + + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + public long getInterval() { + return 2; + } + + @Override + public String getName() { + return String.format("wait-host[%s]-power-on", msg.getHostUuid()); + } + }); + } + + @Override + public void fail(ErrorCode err) { + reply.setSuccess(false); + reply.setError(err); + bus.reply(msg, reply); + completion.done(); + } + }; + + kvmHostIpmiPowerExecutor.powerOn(self, c); + } + + private void handleShutdownHostByIpmi(ShutdownHostMsg msg, NoErrorCompletion completion) { + ShutdownHostReply reply = new ShutdownHostReply(); + Completion c = new Completion(msg, completion) { + @Override + public void success() { + if (msg.isReturnEarly()) { + bus.reply(msg, reply); + } + + submitTaskWaitHostShutdownByIpmi(); + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + if (msg.isReturnEarly()) { + return; + } + reply.setSuccess(false); + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + + private void submitTaskWaitHostShutdownByIpmi() { + long timeoutInSec = KVMConstant.KVM_HOST_POWER_OPERATION_TIMEOUT_SECONDS; + long ctimeout = TimeUnit.SECONDS.toMillis(timeoutInSec); + Long deadline = timeHelper.getCurrentTimeMillis() + ctimeout; + thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask() { + @Override + public boolean run() { + HostVO host = dbf.findByUuid(msg.getHostUuid(), HostVO.class); + + if (timeHelper.getCurrentTimeMillis() > deadline) { + HostIpmiVO ipmi = host.getIpmi(); + kvmHostIpmiPowerExecutor.updateIpmiPowerStatusInDB(ipmi, HostPowerStatus.POWER_ON); + if (!msg.isReturnEarly()) { + reply.setError(operr(String.format("Host[%s] has not been shut down within %d seconds for an unknown reason. Please check host status in BMC[%s]", msg.getHostUuid(), timeoutInSec, host.getIpmi().getIpmiAddress()))); + reply.setSuccess(false); + bus.reply(msg, reply); + } + return true; + } + HostPowerStatus status = kvmHostIpmiPowerExecutor.refreshHostPowerStatus(host).getIpmiPowerStatus(); + if (HostPowerStatus.POWER_OFF.equals(status)) { + Consumer c = msg.getOriginState() == null ? null : h -> { + logger.debug(String.format("host[uuid:%s, name:%s, ip:%s] is power off, set it to origin state %s", + h.getUuid(), h.getName(), h.getManagementIp(), msg.getOriginState())); + h.setState(HostState.valueOf(msg.getOriginState())); + }; + changeConnectionState(HostStatusEvent.disconnected, c); + if (!msg.isReturnEarly()) { + bus.reply(msg, reply); + } + return true; + } + if (HostPowerStatus.POWER_ON.equals(status)) { + HostIpmiVO ipmi = host.getIpmi(); + kvmHostIpmiPowerExecutor.updateIpmiPowerStatusInDB(ipmi, + HostPowerStatus.POWER_ON.nextStatus(HostPowerStatusEvent.off)); + } + return false; + } + + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + public long getInterval() { + return 2; + } + + @Override + public String getName() { + return String.format("wait-host[%s]-power-off", msg.getHostUuid()); + } + }); + } + }; + kvmHostIpmiPowerExecutor.powerOff(self, msg.isForce(), c, msg.isReturnEarly()); + } + + private void handle(RebootHostMsg msg) { + inQueue().name(String.format("reboot-kvm-host-%s", self.getUuid())) + .asyncBackup(msg) + .run(chain -> handleRebootMsg(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void handleRebootMsg(RebootHostMsg msg, NoErrorCompletion completion) { + switch (msg.getMethod()) { + case AGENT: + handleRebootHostByAgent(msg, completion); + break; + case IPMI: + handleRebootHostByIpmi(msg, completion); + break; + default: + HostIpmiVO ipmi = dbf.findByUuid(msg.getHostUuid(), HostIpmiVO.class); + if (null != ipmi && null != ipmi.getIpmiAddress() && null != ipmi.getIpmiUsername() && null != ipmi.getIpmiPassword()) { + handleRebootHostByIpmi(msg, completion); + } else { + handleRebootHostByAgent(msg, completion); + } + } + } + + private void handleRebootHostByAgent(RebootHostMsg msg, NoErrorCompletion completion) { + RebootHostReply reply = new RebootHostReply(); + KVMAgentCommands.RebootHostCmd cmd = new KVMAgentCommands.RebootHostCmd(); + new Http<>(rebootHost, cmd, RebootHostResponse.class).call(new ReturnValueCompletion(msg, completion) { + @Override + public void success(RebootHostResponse returnValue) { + if (!returnValue.isSuccess()) { + reply.setError(operr("operation error, because:%s", returnValue.getError())); + bus.reply(msg, reply); + completion.done(); + return; + } + changeConnectionState(HostStatusEvent.disconnected); + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + completion.done(); + } + }); + } + + private void handle(SyncVmDeviceInfoMsg msg) { + SyncVmDeviceInfoReply reply = new SyncVmDeviceInfoReply(); + + SyncVmDeviceInfoCmd cmd = new SyncVmDeviceInfoCmd(); + cmd.setVmInstanceUuid(msg.getVmInstanceUuid()); + new Http<>(syncVmDeviceInfo, cmd, SyncVmDeviceInfoResponse.class) + .call(msg.getHostUuid(), new ReturnValueCompletion(msg) { + @Override + public void success(SyncVmDeviceInfoResponse ret) { + if (!ret.isSuccess()) { + ErrorCode err = Platform.err(SysErrors.OPERATION_ERROR, ret.getError()); + reply.setError(err); + } + + extEmitter.afterReceiveSyncVmDeviceInfoResponse(VmInstanceInventory.valueOf(dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class)), ret, null); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + + } + + private void handle(GetHostNumaTopologyMsg msg) { + GetHostNumaTopologyReply reply = new GetHostNumaTopologyReply(); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + + GetHostNUMATopologyCmd cmd = new GetHostNUMATopologyCmd(); + cmd.setHostUuid(msg.getHostUuid()); + + new Http<>(getHostNumaPath, cmd, GetHostNUMATopologyResponse.class).call(msg.getHostUuid(), new ReturnValueCompletion(msg) { + @Override + public void success(GetHostNUMATopologyResponse ret) { + if (!ret.isSuccess()) { + ErrorCode err = Platform.err(SysErrors.OPERATION_ERROR, ret.getError()); + reply.setError(err); + } else { + reply.setNuma(ret.getTopology()); + } + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(CompareCpuFunctionOnHostMsg msg) { + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("compare-host-%s-cpu-function-xml-on-host-%s", msg.getSrcHostUuid(), msg.getDstHostUuid())) + .run((com) -> compareCpuFunctionOnHost(msg, new ReturnValueCompletion(com) { + @Override + public void success(VmCompareCpuFunctionResponse resp) { + com.success(resp); + } + + @Override + public void fail(ErrorCode errorCode) { + com.fail(errorCode); + } + })) + .done(((result) -> { + CompareCpuFunctionOnHostReply reply = new CompareCpuFunctionOnHostReply(); + if (!result.isSuccess()) { + reply.setError(result.getErrorCode()); + bus.reply(msg, reply); + return; + } + VmCompareCpuFunctionResponse resp = (VmCompareCpuFunctionResponse)result.getResult(); + reply.setMatch(resp.isMatch()); + reply.setCompareError(resp.getCompareError()); + bus.reply(msg, reply); + }))); + } + + private void compareCpuFunctionOnHost(final CompareCpuFunctionOnHostMsg msg, ReturnValueCompletion completion) { + VmCompareCpuFunctionCmd cmd = new VmCompareCpuFunctionCmd(); + cmd.setCpuXml(msg.getCpuXml()); + restf.asyncJsonPost(compareCpuFunctionPath, cmd, new JsonAsyncRESTCallback(completion) { + @Override + public void success(VmCompareCpuFunctionResponse ret) { + if (!ret.isSuccess()) { + completion.fail(operr(ret.getError())); + return; + } + completion.success(ret); + } + + @Override + public Class getReturnClass() { + return VmCompareCpuFunctionResponse.class; + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void getCpuFunctionXml(final GetCpuFunctionXmlOnHostMsg msg, ReturnValueCompletion completion) { + GetCpuFunctionXmlOnHostReply reply = new GetCpuFunctionXmlOnHostReply(); + restf.asyncJsonPost(getCpuXmlPath, new VmGetCpuXmlCmd(), new JsonAsyncRESTCallback(completion) { + @Override + public void success(VmGetCpuXmlResponse ret) { + if (!ret.isSuccess()) { + completion.fail(operr(ret.getError())); + return; + } + reply.setCpuXml(ret.getCpuXml()); + reply.setCpuModelName(ret.getCpuModelName()); + completion.success(reply); + } + + @Override + public Class getReturnClass() { + return VmGetCpuXmlResponse.class; + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void handle(GetCpuFunctionXmlOnHostMsg msg) { + GetCpuFunctionXmlOnHostReply reply = new GetCpuFunctionXmlOnHostReply(); + thdf.singleFlightSubmit(new SingleFlightTask(msg) + .setSyncSignature(String.format("get-cpu-function-xml-on-host-%s", self.getUuid())) + .run((com) -> getCpuFunctionXml(msg, new ReturnValueCompletion(msg) { + @Override + public void success(GetCpuFunctionXmlOnHostReply returnValue) { + com.success(returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + com.fail(errorCode); + } + })) + .done(((result) -> { + if (!result.isSuccess()) { + reply.setError(result.getErrorCode()); + bus.reply(msg, reply); + return; + } + + reply.setCpuModelName(((GetCpuFunctionXmlOnHostReply) result.getResult()).getCpuModelName()); + reply.setCpuXml(((GetCpuFunctionXmlOnHostReply) result.getResult()).getCpuXml()); + bus.reply(msg, reply); + }))); + } + + private void handle(CreateCpuFeaturesHistoryMsg msg) { + CreateCpuFeaturesHistoryReply reply = new CreateCpuFeaturesHistoryReply(); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format("create-migration-cpu-function-history-from-src-%s-to-dst-%s", msg.getHostUuid(), msg.getDstHostUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + CpuFeaturesHistoryVO vo = Q.New(CpuFeaturesHistoryVO.class) + .eq(CpuFeaturesHistoryVO_.srcHostUuid, msg.getHostUuid()) + .eq(CpuFeaturesHistoryVO_.dstHostUuid, msg.getDstHostUuid()) + .find(); + + if (vo == null) { + CpuFeaturesHistoryVO cfVO = new CpuFeaturesHistoryVO(); + cfVO.setSrcHostUuid(msg.getHostUuid()); + cfVO.setDstHostUuid(msg.getDstHostUuid()); + cfVO.setSupportLiveMigration(msg.isSupportLiveMigration()); + cfVO.setSrcCpuModelName(msg.getSrcCpuModelName()); + dbf.persist(cfVO); + logger.debug(String.format("successfully persist cpuFeaturesHistory info[src: %s, dst: %s]", msg.getSrcHostUuid(), msg.getDstHostUuid())); + bus.reply(msg, reply); + chain.next(); + return; + } + + vo.setSrcCpuModelName(msg.getSrcCpuModelName()); + vo.setSupportLiveMigration(msg.isSupportLiveMigration()); + dbf.update(vo); + logger.debug(String.format("successfully update cpuFeaturesHistory info[cpuModelName: %s, support: %s]", msg.getSrcCpuModelName(), msg.isSupportLiveMigration())); + bus.reply(msg, reply); + chain.next(); + } + + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + + + private void handle(AllocateHostPortMsg msg) { + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format("allocate-host-%s-port", msg.getHostUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + AllocateHostPortReply reply = new AllocateHostPortReply(); + reply.setHostPortIds(new ArrayList<>()); + HostPortGetter portGetter = new HostPortGetter(); + for (int i = 0; i < msg.getAllocateCount(); i++) { + HostPortVO vo = portGetter.getNextHostPort(msg.getHostUuid(), ""); + reply.getHostPortIds().add(vo.getId()); + } + + bus.reply(msg, reply); + chain.next(); + } + + @Override + public String getName() { + return String.format("allocate-host-%s-port", msg.getHostUuid()); + } + }); + } + + private void handle(CheckHostCapacityMsg msg) { + CheckHostCapacityReply re = new CheckHostCapacityReply(); + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setHostUuid(msg.getHostUuid()); + kmsg.setPath(KVMConstant.KVM_HOST_CAPACITY_PATH); + kmsg.setNoStatusCheck(true); + kmsg.setCommand(new HostCapacityCmd()); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, msg.getHostUuid()); + bus.send(kmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + throw new OperationFailureException(operr("check host capacity failed, because:%s", reply.getError())); + } + + KVMHostAsyncHttpCallReply r = reply.castReply(); + HostCapacityResponse rsp = r.toResponse(HostCapacityResponse.class); + if (!rsp.isSuccess()) { + throw new OperationFailureException(operr("operation error, because:%s", rsp.getError())); + } + + long reservedSize = SizeUtils.sizeStringToBytes(rcf.getResourceConfigValue(KVMGlobalConfig.RESERVED_MEMORY_CAPACITY, msg.getHostUuid(), String.class)); + if (rsp.getTotalMemory() < reservedSize) { + throw new OperationFailureException(operr("The host[uuid:%s]'s available memory capacity[%s] is lower than the reserved capacity[%s]", + msg.getHostUuid(), rsp.getTotalMemory(), reservedSize)); + } + + ReportHostCapacityMessage rmsg = new ReportHostCapacityMessage(); + rmsg.setHostUuid(msg.getHostUuid()); + rmsg.setCpuNum((int) rsp.getCpuNum()); + rmsg.setUsedCpu(rsp.getUsedCpu()); + rmsg.setTotalMemory(rsp.getTotalMemory()); + rmsg.setUsedMemory(rsp.getUsedMemory()); + rmsg.setCpuSockets(rsp.getCpuSockets()); + rmsg.setCpuCoreNum(rsp.getCpuCoreNum()); + rmsg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); + bus.send(rmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + re.setError(reply.getError()); + } + + bus.reply(msg, re); + } + }); + } + }); + } + + private void handle(RegisterColoPrimaryCheckMsg msg) { + inQueue().name(String.format("register-vm-heart-beat-on-%s", self.getUuid())) + .asyncBackup(msg) + .run(chain -> registerPrimaryVmHeartbeat(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void registerPrimaryVmHeartbeat(RegisterColoPrimaryCheckMsg msg, NoErrorCompletion completion) { + RegisterPrimaryVmHeartbeatCmd cmd = new RegisterPrimaryVmHeartbeatCmd(); + cmd.setHostUuid(msg.getHostUuid()); + cmd.setVmInstanceUuid(msg.getVmInstanceUuid()); + cmd.setHeartbeatPort(msg.getHeartbeatPort()); + cmd.setTargetHostIp(msg.getTargetHostIp()); + cmd.setColoPrimary(msg.isColoPrimary()); + cmd.setRedirectNum(msg.getRedirectNum()); + + VmInstanceVO vm = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); + List volumes = vm.getAllVolumes().stream().filter(v -> v.getType() == VolumeType.Data || v.getType() == VolumeType.Root).map(VolumeInventory::valueOf).collect(Collectors.toList()); + cmd.setVolumes(VolumeTO.valueOf(volumes, KVMHostInventory.valueOf(getSelf()))); + + new Http<>(registerPrimaryVmHeartbeatPath, cmd, AgentResponse.class).call(new ReturnValueCompletion(msg, completion) { + @Override + public void success(AgentResponse ret) { + final StartColoSyncReply reply = new StartColoSyncReply(); + if (!ret.isSuccess()) { + reply.setError(operr("unable to register colo heartbeat for vm[uuid:%s] on kvm host [uuid:%s, ip:%s], because %s", + msg.getVmInstanceUuid(), self.getUuid(), self.getManagementIp(), ret.getError())); + } else { + logger.debug(String.format("unable to register colo heartbeat for vm[uuid:%s] on kvm host[uuid:%s] success", msg.getVmInstanceUuid(), self.getUuid())); + } + + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode err) { + final StartColoSyncReply reply = new StartColoSyncReply(); + reply.setError(err); + bus.reply(msg, reply); + completion.done(); + } + }); + } + + private void handle(StartColoSyncMsg msg) { + inQueue().name(String.format("start-colo-sync-vm-%s-on-%s", msg.getVmInstanceUuid(), self.getUuid())) + .asyncBackup(msg) + .run(chain -> startColoSync(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void startColoSync(StartColoSyncMsg msg, NoErrorCompletion completion) { + StartColoSyncCmd cmd = new StartColoSyncCmd(); + cmd.setVmInstanceUuid(msg.getVmInstanceUuid()); + cmd.setBlockReplicationPort(msg.getBlockReplicationPort()); + cmd.setNbdServerPort(msg.getNbdServerPort()); + cmd.setSecondaryVmHostIp(msg.getSecondaryVmHostIp()); + cmd.setCheckpointDelay(msg.getCheckpointDelay()); + cmd.setFullSync(msg.isFullSync()); + + VmInstanceVO vm = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); + List volumes = vm.getAllVolumes().stream().filter(v -> v.getType() == VolumeType.Data || v.getType() == VolumeType.Root).map(VolumeInventory::valueOf).collect(Collectors.toList()); + cmd.setVolumes(VolumeTO.valueOf(volumes, KVMHostInventory.valueOf(getSelf()))); + + checkCleanTraffic(msg.getVmInstanceUuid()); + + List nics = new ArrayList<>(); + for (VmNicInventory nic : msg.getNics()) { + NicTO to = completeNicInfo(nic); + nics.add(to); + } + nics = nics.stream().sorted(Comparator.comparing(NicTO::getDeviceId)).collect(Collectors.toList()); + cmd.setNics(nics); new Http<>(startColoSyncPath, cmd, AgentResponse.class).call(new ReturnValueCompletion(msg, completion) { @Override public void success(AgentResponse ret) { @@ -921,6 +2073,13 @@ private void getVmDeviceAddress(final GetVmDeviceAddressMsg msg, final NoErrorCo new Http<>(getVmDeviceAddressPath, cmd, GetVmDeviceAddressRsp.class).call(new ReturnValueCompletion(msg, completion) { @Override public void success(GetVmDeviceAddressRsp rsp) { + if (!rsp.isSuccess()) { + reply.setError(operr("failed to get vm[uuid:%s] device address, because:%s", msg.getVmInstanceUuid(), rsp.getError())); + bus.reply(msg, reply); + completion.done(); + return; + } + for (String resourceType : msg.getInventories().keySet()) { reply.putAddresses(resourceType, rsp.getAddresses(resourceType).stream().map(it -> { VmDeviceAddress address = new VmDeviceAddress(); @@ -946,6 +2105,63 @@ public void fail(ErrorCode err) { }); } + private void handle(GetVirtualizerInfoMsg msg) { + inQueue().name(String.format("get-virtualizer-info-on-kvm-%s", self.getUuid())) + .asyncBackup(msg) + .run(chain -> getVirtualizerInfo(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + /** + * This command will send when host is connecting. + * + * DO NOT need to checkStatus() + */ + private void getVirtualizerInfo(final GetVirtualizerInfoMsg msg, final NoErrorCompletion completion) { + GetVirtualizerInfoReply reply = new GetVirtualizerInfoReply(); + GetVirtualizerInfoCmd cmd = new GetVirtualizerInfoCmd(); + cmd.setVmUuids(msg.getVmInstanceUuids()); + new Http<>(getVirtualizerInfo, cmd, GetVirtualizerInfoRsp.class).call(new ReturnValueCompletion(msg, completion) { + @Override + public void success(GetVirtualizerInfoRsp rsp) { + if (!rsp.isSuccess()) { + reply.setError(operr("failed to get host[uuid:%s] virtualizer info, because:%s", msg.getHostUuid(), rsp.getError())); + bus.reply(msg, reply); + completion.done(); + return; + } + + hypervisorManager.save(rsp); + + reply.setHostVirtualizer(rsp.getHostInfo().getVirtualizer()); + reply.setHostInstalledQemuVersion(rsp.getHostInfo().getVersion()); + reply.setVmInfoList(rsp.getVmInfoList().stream() + .map(info -> { + VmVirtualizerInfo to = new VmVirtualizerInfo(); + to.setVmInstanceUuid(info.getUuid()); + if (KvmHypervisorInfoHelper.isQemuBased(info.getVirtualizer())) { + to.setCurrentQemuVersion(info.getVersion()); + } + return to; + }).collect(Collectors.toList())); + + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode err) { + reply.setError(err); + bus.reply(msg, reply); + completion.done(); + } + }); + } + private void handle(GetKVMHostDownloadCredentialMsg msg) { final GetKVMHostDownloadCredentialReply reply = new GetKVMHostDownloadCredentialReply(); @@ -1067,6 +2283,10 @@ protected RunInQueue inQueue() { return new RunInQueue(id, thdf, getHostSyncLevel()); } + protected RunInQueue inQueue(int level) { + return new RunInQueue(id, thdf, level); + } + private void handle(final VmDirectlyDestroyOnHypervisorMsg msg) { inQueue().name(String.format("directly-delete-vm-%s-msg-on-kvm-%s", msg.getVmUuid(), self.getUuid())) .asyncBackup(msg) @@ -1281,6 +2501,8 @@ private void attachIso(final AttachIsoOnHypervisorMsg msg, final NoErrorCompleti iso.setImageUuid(msg.getIsoSpec().getImageUuid()); iso.setPath(msg.getIsoSpec().getInstallPath()); iso.setDeviceId(msg.getIsoSpec().getDeviceId()); + iso.setPrimaryStorageUuid(msg.getIsoSpec().getPrimaryStorageUuid()); + iso.setProtocol(msg.getIsoSpec().getProtocol()); AttachIsoCmd cmd = new AttachIsoCmd(); cmd.vmUuid = msg.getVmInstanceUuid(); @@ -1311,7 +2533,62 @@ public void fail(ErrorCode err) { }); } + private void handle(final ChangeVmNicStateOnHypervisorMsg msg) { + inQueue().name("set-nic-state-on-kvm-host-" + self.getUuid()) + .asyncBackup(msg) + .run(chain -> changeVmNicState(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + protected void changeVmNicState(final ChangeVmNicStateOnHypervisorMsg msg, final NoErrorCompletion completion) { + final ChangeVmNicStateOnHypervisorReply reply = new ChangeVmNicStateOnHypervisorReply(); + checkCleanTraffic(msg.getVmInstanceUuid()); + + NicTO to = completeNicInfo(msg.getNic()); + ChangeVmNicStateCommand cmd = new ChangeVmNicStateCommand(); + cmd.setVmUuid(msg.getVmInstanceUuid()); + cmd.setNic(to); + cmd.setState(msg.getState()); + new Http<>(changeNicStatePath, cmd, ChangeVmNicStateRsp.class).call(new ReturnValueCompletion(msg, completion) { + @Override + public void success(ChangeVmNicStateRsp ret) { + if (!ret.isSuccess()) { + reply.setError(operr("operation error, because:%s", ret.getError())); + } + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + }); + } + private void handle(final DetachNicFromVmOnHypervisorMsg msg) { + if (msg.getNic().getL3NetworkUuid() == null) { + logger.debug(String.format("Skip detach nic[uuid=%s] on hypervisor: This nic is not attach any networks", + msg.getNic().getUuid())); + bus.reply(msg, new DetachNicFromVmOnHypervisorReply()); + } + + boolean running = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()) + .notNull(VmInstanceVO_.hostUuid) + .isExists(); + if (!running) { + logger.debug(String.format("Skip detach nic[uuid=%s] on hypervisor: VM[uuid=%s] is not running", + msg.getNic().getUuid(), msg.getVmInstanceUuid())); + bus.reply(msg, new DetachNicFromVmOnHypervisorReply()); + return; + } + inQueue().name("detach-nic-on-kvm-host-" + self.getUuid()) .asyncBackup(msg) .run(chain -> detachNic(msg, new NoErrorCompletion(chain) { @@ -1324,6 +2601,9 @@ public void done() { protected void detachNic(final DetachNicFromVmOnHypervisorMsg msg, final NoErrorCompletion completion) { final DetachNicFromVmOnHypervisorReply reply = new DetachNicFromVmOnHypervisorReply(); + + checkCleanTraffic(msg.getVmInstanceUuid()); + NicTO to = completeNicInfo(msg.getNic()); DetachNicCommand cmd = new DetachNicCommand(); @@ -1381,6 +2661,11 @@ private void executeSyncHttpCall(KVMHostSyncHttpCallMsg msg, NoErrorCompletion c if (!msg.isNoStatusCheck()) { checkStatus(); } + + ErrorCode errorCode = upgradeChecker.checkAgentHttpParamChanges(self.getUuid(), msg.getCommandClassName(), msg.getCommand()); + if (errorCode != null) { + throw new OperationFailureException(errorCode); + } String url = buildUrl(msg.getPath()); MessageCommandRecorder.record(msg.getCommandClassName()); Map headers = new HashMap<>(); @@ -1428,7 +2713,7 @@ private void executeAsyncHttpCall(final KVMHostAsyncHttpCallMsg msg, final NoErr String url = buildUrl(msg.getPath()); MessageCommandRecorder.record(msg.getCommandClassName()); - new Http<>(url, msg.getCommand(), LinkedHashMap.class) + new Http<>(url, msg.getCommand(), msg.getCommandClassName(), LinkedHashMap.class) .call(new ReturnValueCompletion(msg, completion) { @Override public void success(LinkedHashMap ret) { @@ -1491,14 +2776,12 @@ private void mergeVolumeSnapshot(final MergeVolumeSnapshotOnKvmMsg msg, final No } } - VolumeSnapshotInventory snapshot = msg.getFrom(); MergeSnapshotCmd cmd = new MergeSnapshotCmd(); cmd.setFullRebase(msg.isFullRebase()); - cmd.setDestPath(volume.getInstallPath()); - cmd.setSrcPath(snapshot.getPrimaryStorageInstallPath()); + cmd.setSrcPath(msg.getFrom() != null ? msg.getFrom().getPrimaryStorageInstallPath() : null); cmd.setVmUuid(volume.getVmInstanceUuid()); cmd.setVolume(VolumeTO.valueOf(volume, (KVMHostInventory) getSelfInventory())); - cmd.setTimeout(timeoutManager.getTimeoutSeconds()); + cmd.setDestPath(cmd.getVolume().getInstallPath()); extEmitter.beforeMergeSnapshot((KVMHostInventory) getSelfInventory(), msg, cmd); new Http<>(mergeSnapshotPath, cmd, MergeSnapshotRsp.class) @@ -1713,8 +2996,8 @@ private void doTakeSnapshot(final TakeSnapshotOnHypervisorMsg msg, final NoError } } + cmd.setOnline(vmState != VmInstanceState.Stopped); cmd.setVmUuid(msg.getVmUuid()); - cmd.setVolume(VolumeTO.valueOf(msg.getVolume(), (KVMHostInventory) getSelfInventory())); } cmd.setVolumeInstallPath(msg.getVolume().getInstallPath()); @@ -1722,6 +3005,8 @@ private void doTakeSnapshot(final TakeSnapshotOnHypervisorMsg msg, final NoError cmd.setFullSnapshot(msg.isFullSnapshot()); cmd.setVolumeUuid(msg.getVolume().getUuid()); cmd.setTimeout(timeoutManager.getTimeout()); + cmd.setVolume(VolumeTO.valueOf(msg.getVolume(), (KVMHostInventory) getSelfInventory())); + cmd.primaryStorageUuid = msg.getVolume().getPrimaryStorageUuid(); completeTakeSnapshotCmd(msg, cmd); @@ -1821,16 +3106,8 @@ private void migrateVm(final MigrateStruct s, final Completion completion) { q.add(VmInstanceVO_.uuid, Op.EQ, vmUuid); final Long vmInternalId = q.findValue(); - List nics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, s.vmUuid) - .eq(VmNicVO_.type, "vDPA") - .list(); + List nics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, s.vmUuid).list(); List nicTos = VmNicInventory.valueOf(nics).stream().map(this::completeNicInfo).collect(Collectors.toList()); - List vDPANics = new ArrayList(); - for (NicTO nicTo : nicTos) { - if (nicTo.getType().equals("vDPA")) { - vDPANics.add(nicTo); - } - } FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("migrate-vm-%s-on-kvm-host-%s", vmUuid, self.getUuid())); @@ -1838,38 +3115,31 @@ private void migrateVm(final MigrateStruct s, final Completion completion) { @Override public void setup() { flow(new NoRollbackFlow() { - String __name__ = "generate-vDPA-on-dst-host"; + String __name__ = "clean-firmware-flash-before-migrate"; @Override public void run(final FlowTrigger trigger, Map data) { - if (vDPANics.isEmpty()) { - trigger.next(); - return; - } - GenerateVdpaCmd cmd = new GenerateVdpaCmd(); + CleanVmFirmwareFlashCmd cmd = new CleanVmFirmwareFlashCmd(); cmd.vmUuid = vmUuid; - cmd.setNics(nicTos); UriComponentsBuilder ub = UriComponentsBuilder.fromHttpUrl(baseUrl); ub.host(dstHostMnIp); - ub.path(KVMConstant.KVM_GENERATE_VDPA_PATH); + ub.path(KVMConstant.CLEAN_FIRMWARE_FLASH); String url = ub.build().toString(); - new Http<>(url, cmd, GenerateVdpaResponse.class).call(dstHostUuid, new ReturnValueCompletion(trigger) { + new Http<>(url, cmd, AgentResponse.class).call(dstHostUuid, new ReturnValueCompletion(trigger) { @Override - public void success(GenerateVdpaResponse ret) { + public void success(AgentResponse ret) { if (!ret.isSuccess()) { - logger.warn(String.format("generate vDPA for %s failed, %s", vmUuid, ret.getError())); + logger.warn(String.format("failed to clean VM[uuid:%s]'s firmware flash, %s", vmUuid, ret.getError())); } - data.put("vDPA_paths", ret.getVdpaPaths()); - trigger.next(); } @Override public void fail(ErrorCode errorCode) { - logger.warn(String.format("generate vDPA for %s failed, %s", vmUuid, errorCode)); - trigger.fail(errorCode); + logger.warn(String.format("failed to clean VM[uuid:%s]'s firmware flash, %s", vmUuid, errorCode)); + trigger.next(); } }); } @@ -1882,9 +3152,11 @@ public void fail(ErrorCode errorCode) { public void run(final FlowTrigger trigger, Map data) { TaskProgressRange stage = markTaskStage(parentStage, MIGRATE_VM_STAGE); - boolean autoConverage = KVMGlobalConfig.MIGRATE_AUTO_CONVERGE.value(Boolean.class); - if (!autoConverage) { - autoConverage = s.strategy != null && s.strategy.equals("auto-converge"); + boolean autoConverge; + if (s.strategy != null) { + autoConverge = s.strategy.equals("auto-converge"); + } else { + autoConverge = rcf.getResourceConfigValue(KVMGlobalConfig.MIGRATE_AUTO_CONVERGE, vmUuid, Boolean.class); } boolean xbzrle = KVMGlobalConfig.MIGRATE_XBZRLE.value(Boolean.class); @@ -1892,14 +3164,33 @@ public void run(final FlowTrigger trigger, Map data) { MigrateVmCmd cmd = new MigrateVmCmd(); cmd.setDestHostIp(dstHostMigrateIp); cmd.setSrcHostIp(srcHostMigrateIp); + cmd.setDestHostManagementIp(dstHostMnIp); cmd.setMigrateFromDestination(migrateFromDestination); cmd.setStorageMigrationPolicy(storageMigrationPolicy == null ? null : storageMigrationPolicy.toString()); cmd.setVmUuid(vmUuid); - cmd.setAutoConverge(autoConverage); + cmd.setAutoConverge(autoConverge); cmd.setXbzrle(xbzrle); cmd.setVdpaPaths((List) data.get("vDPA_paths")); cmd.setUseNuma(rcf.getResourceConfigValue(VmGlobalConfig.NUMA, vmUuid, Boolean.class)); - cmd.setTimeout(timeoutManager.getTimeout()); + cmd.setReload(s.reload); + cmd.setDownTime(s.downTime); + cmd.setBandwidth(s.bandwidth); + cmd.setNics(nicTos); + + if (s.diskMigrationMap != null) { + Map diskMigrationMap = new HashMap<>(); + new SQLBatch() { + @Override + protected void scripts() { + s.diskMigrationMap.forEach((oldVolumeInstallPath, newVolumeUuid) -> { + VolumeVO vo = findByUuid(newVolumeUuid, VolumeVO.class); + diskMigrationMap.put(oldVolumeInstallPath, + VolumeTO.valueOf(VolumeInventory.valueOf(vo), (KVMHostInventory) getSelfInventory())); + }); + } + }.execute(); + cmd.setDisks(diskMigrationMap); + } UriComponentsBuilder ub = UriComponentsBuilder.fromHttpUrl(migrateVmPath); ub.host(migrateFromDestination ? dstHostMnIp : srcHostMnIp); @@ -2004,41 +3295,6 @@ public void fail(ErrorCode errorCode) { } }); - flow(new NoRollbackFlow() { - String __name__ = "delete-vDPA-on-src-host"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - if (vDPANics.isEmpty()) { - trigger.next(); - return; - } - DeleteVdpaCmd cmd = new DeleteVdpaCmd(); - cmd.vmUuid = vmUuid; - - UriComponentsBuilder ub = UriComponentsBuilder.fromHttpUrl(baseUrl); - ub.host(srcHostMnIp); - ub.path(KVMConstant.KVM_DELETE_VDPA_PATH); - String url = ub.build().toString(); - new Http<>(url, cmd, AgentResponse.class).call(new ReturnValueCompletion(trigger) { - @Override - public void success(AgentResponse ret) { - if (!ret.isSuccess()) { - logger.warn(String.format("delete vDPA for %s failed, %s", vmUuid, ret.getError())); - } - - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - logger.warn(String.format("delete vDPA for %s failed, %s", vmUuid, errorCode)); - trigger.next(); - } - }); - } - }); - done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { @@ -2075,6 +3331,7 @@ class MigrateStruct { String vmUuid; String dstHostMigrateIp; String strategy; + Integer downTime; String dstHostMnIp; String dstHostUuid; StorageMigrationPolicy storageMigrationPolicy; @@ -2082,6 +3339,9 @@ class MigrateStruct { String srcHostMigrateIp; String srcHostMnIp; String srcHostUuid; + Map diskMigrationMap; + boolean reload; + long bandwidth; } private MigrateStruct buildMigrateStuct(final MigrateVmOnHypervisorMsg msg){ @@ -2092,6 +3352,10 @@ private MigrateStruct buildMigrateStuct(final MigrateVmOnHypervisorMsg msg){ s.storageMigrationPolicy = msg.getStorageMigrationPolicy(); s.migrateFromDestition = msg.isMigrateFromDestination(); s.strategy = msg.getStrategy(); + s.downTime = msg.getDownTime(); + s.diskMigrationMap = msg.getDiskMigrationMap(); + s.reload = msg.isReload(); + s.bandwidth = msg.getBandwidth(); MigrateNetworkExtensionPoint.MigrateInfo migrateIpInfo = null; for (MigrateNetworkExtensionPoint ext: pluginRgty.getExtensionList(MigrateNetworkExtensionPoint.class)) { @@ -2147,11 +3411,22 @@ private void updateNic(VmUpdateNicOnHypervisorMsg msg, NoErrorCompletion complet checkStateAndStatus(); final VmUpdateNicOnHypervisorReply reply = new VmUpdateNicOnHypervisorReply(); - List nics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, msg.getVmInstanceUuid()).list(); + List nics = new ArrayList<>(); + if (msg.getNicsUuid().isEmpty()) { + nics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, msg.getVmInstanceUuid()).list(); + } else { + for (String nicUuid : msg.getNicsUuid()) { + nics.add(dbf.findByUuid(nicUuid, VmNicVO.class)); + } + } + + + checkCleanTraffic(msg.getVmInstanceUuid()); UpdateNicCmd cmd = new UpdateNicCmd(); cmd.setVmInstanceUuid(msg.getVmInstanceUuid()); cmd.setNics(VmNicInventory.valueOf(nics).stream().map(this::completeNicInfo).collect(Collectors.toList())); + cmd.setAccountUuid(accountMgr.getOwnerAccountUuidOfResource(cmd.getVmInstanceUuid())); KVMHostInventory inv = (KVMHostInventory) getSelfInventory(); for (KVMPreUpdateNicExtensionPoint ext : pluginRgty.getExtensionList(KVMPreUpdateNicExtensionPoint.class)) { @@ -2180,6 +3455,17 @@ public void fail(ErrorCode errorCode) { } private void handle(final VmAttachNicOnHypervisorMsg msg) { + boolean running = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, msg.getNicInventory().getVmInstanceUuid()) + .notNull(VmInstanceVO_.hostUuid) + .isExists(); + if (!running) { + logger.debug(String.format("Skip attach nic[uuid=%s] on hypervisor: VM[uuid=%s] is not running", + msg.getNicInventory().getUuid(), msg.getNicInventory().getVmInstanceUuid())); + bus.reply(msg, new VmAttachNicOnHypervisorReply()); + return; + } + inQueue().name(String.format("attach-nic-on-kvm-%s", self.getUuid())) .asyncBackup(msg) .run(chain -> attachNic(msg, new NoErrorCompletion(chain) { @@ -2193,12 +3479,15 @@ public void done() { protected void attachNic(final VmAttachNicOnHypervisorMsg msg, final NoErrorCompletion completion) { checkStateAndStatus(); + checkCleanTraffic(msg.getNicInventory().getVmInstanceUuid()); + NicTO to = completeNicInfo(msg.getNicInventory()); final VmAttachNicOnHypervisorReply reply = new VmAttachNicOnHypervisorReply(); AttachNicCommand cmd = new AttachNicCommand(); cmd.setVmUuid(msg.getNicInventory().getVmInstanceUuid()); cmd.setNic(to); + cmd.setAccountUuid(accountMgr.getOwnerAccountUuidOfResource(cmd.getVmUuid())); KVMHostInventory inv = (KVMHostInventory) getSelfInventory(); for (KvmPreAttachNicExtensionPoint ext : pluginRgty.getExtensionList(KvmPreAttachNicExtensionPoint.class)) { @@ -2222,12 +3511,10 @@ public void success(AttachNicResponse ret) { bus.reply(msg, reply); - if (ret.getPciAddress() != null) { - SystemTagCreator creator = KVMSystemTags.VMNIC_PCI_ADDRESS.newSystemTagCreator(msg.getNicInventory().getUuid()); - creator.inherent = true; - creator.recreate = true; - creator.setTagByTokens(map(e(KVMSystemTags.VMNIC_PCI_ADDRESS_TOKEN, ret.getPciAddress().toString()))); - creator.create(); + if (ret.getVirtualDeviceInfoList() != null && !ret.getVirtualDeviceInfoList().isEmpty()) { + ret.getVirtualDeviceInfoList().forEach(info -> vidm.createOrUpdateVmDeviceAddress(msg.getNicInventory().getUuid(), + info.getDeviceAddress(), msg.getNicInventory().getVmInstanceUuid(), + null, null)); } completion.done(); @@ -2243,7 +3530,18 @@ public void fail(ErrorCode errorCode) { } - private void handle(final DetachVolumeFromVmOnHypervisorMsg msg) { + private void handle(DetachVolumeFromVmOnHypervisorMsg msg) { + VmInstanceState state = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, msg.getVmInventory().getUuid()) + .select(VmInstanceVO_.state) + .findValue(); + if (Objects.equals(state, VmInstanceState.Stopped)) { + logger.debug(String.format("skip detach volume[uuid=%s] on hypervisor when VM[uuid=%s] is stopped", + msg.getInventory().getUuid(), msg.getVmInventory().getUuid())); + bus.reply(msg, new DetachVolumeFromVmOnHypervisorReply()); + return; + } + inQueue().name(String.format("detach-volume-on-kvm-%s", self.getUuid())) .asyncBackup(msg) .run(chain -> detachVolume(msg, new NoErrorCompletion(chain) { @@ -2295,6 +3593,11 @@ public void fail(ErrorCode err) { } private void handle(final AttachVolumeToVmOnHypervisorMsg msg) { + if (!allowToAttachVolumeOnHypervisor(msg)) { + bus.reply(msg, new AttachVolumeToVmOnHypervisorReply()); + return; + } + inQueue().name(String.format("attach-volume-on-kvm-%s", self.getUuid())) .asyncBackup(msg) .run(chain -> attachVolume(msg, new NoErrorCompletion(chain) { @@ -2305,6 +3608,27 @@ public void done() { })); } + private boolean allowToAttachVolumeOnHypervisor(AttachVolumeToVmOnHypervisorMsg msg) { + final String state = msg.getVmInventory().getState(); + final boolean skipped = skipOperations.isOperationAllowed(msg.getClass().getName(), state); + if (skipped) { + logger.debug(String.format( + "Skip attach volume[uuid=%s] on hypervisor: state of VM[uuid=%s] is %s", + msg.getInventory().getUuid(), msg.getVmInventory().getUuid(), state)); + return false; + } + + boolean allowed = allowedOperations.isOperationAllowed(msg.getClass().getName(), state); + if (!allowed) { + ErrorCode errorCode = err(VmErrors.ATTACH_VOLUME_ERROR, + "In the hypervisorType[%s], attach volume is not allowed in the current vm instance state[%s].", + self.getHypervisorType(), state); + throw new OperationFailureException(errorCode); + } + + return true; + } + static String computeWwnIfAbsent(String volumeUUid) { String wwn; String tag = KVMSystemTags.VOLUME_WWN.getTag(volumeUUid); @@ -2364,6 +3688,7 @@ public void success(AttachDataVolumeResponse ret) { extEmitter.attachVolumeFailed((KVMHostInventory) getSelfInventory(), vm, vol, cmd, reply.getError(), data); } else { extEmitter.afterAttachVolume((KVMHostInventory) getSelfInventory(), vm, vol, cmd); + reply.setVirtualDeviceInfoList(ret.getVirtualDeviceInfoList()); } bus.reply(msg, reply); completion.done(); @@ -2397,6 +3722,7 @@ protected void destroyVm(final DestroyVmOnHypervisorMsg msg, final NoErrorComple DestroyVmCmd cmd = new DestroyVmCmd(); cmd.setUuid(vminv.getUuid()); + cmd.setVmNics(vminv.getVmNics()); try { extEmitter.beforeDestroyVmOnKvm(KVMHostInventory.valueOf(getSelf()), vminv, cmd); @@ -2493,7 +3819,7 @@ public void success(RebootVmResponse ret) { vminv.getName(), self.getUuid(), self.getManagementIp(), ret.getError())); extEmitter.rebootVmOnKvmFailed(KVMHostInventory.valueOf(getSelf()), vminv, reply.getError()); } else { - extEmitter.rebootVmOnKvmSuccess(KVMHostInventory.valueOf(getSelf()), vminv); + extEmitter.rebootVmOnKvmSuccess(KVMHostInventory.valueOf(getSelf()), vminv, ret); } bus.reply(msg, reply); completion.done(); @@ -2529,6 +3855,7 @@ protected void stopVm(final StopVmOnHypervisorMsg msg, final NoErrorCompletion c cmd.setUuid(vminv.getUuid()); cmd.setType(msg.getType()); cmd.setTimeout(120); + cmd.setVmNics(vminv.getVmNics()); try { extEmitter.beforeStopVmOnKvm(KVMHostInventory.valueOf(getSelf()), vminv, cmd); @@ -2607,28 +3934,213 @@ private void setVmNicMultiqueueNum(final VmInstanceSpec spec) { return; } - ResourceConfig multiQueues = rcf.getResourceConfig(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM.getIdentity()); - Integer queues = spec.getVmInventory().getCpuNum() > KVMConstant.DEFAULT_MAX_NIC_QUEUE_NUMBER ? KVMConstant.DEFAULT_MAX_NIC_QUEUE_NUMBER : spec.getVmInventory().getCpuNum(); - multiQueues.updateValue(spec.getVmInventory().getUuid(), queues.toString()); + ResourceConfig multiQueues = rcf.getResourceConfig(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM.getIdentity()); + Integer queues = spec.getVmInventory().getCpuNum() > KVMConstant.DEFAULT_MAX_NIC_QUEUE_NUMBER ? KVMConstant.DEFAULT_MAX_NIC_QUEUE_NUMBER : spec.getVmInventory().getCpuNum(); + multiQueues.updateValue(spec.getVmInventory().getUuid(), queues.toString()); + + } catch (Exception e) { + logger.warn(String.format("got exception when trying set nic multiqueue for vm: %s, %s", spec.getVmInventory().getUuid(), e)); + } + } + + private void handle(final CreateVmOnHypervisorMsg msg) { + inQueue().name(String.format("start-vm-on-kvm-%s", self.getUuid())) + .asyncBackup(msg) + .run(chain -> { + setDataVolumeUseVirtIOSCSI(msg.getVmSpec()); + setVmNicMultiqueueNum(msg.getVmSpec()); + startVm(msg.getVmSpec(), msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + }); + }); + } + + @SuppressWarnings("rawtypes") + private void handle(UpdateVmOnHypervisorMsg msg) { + UpdateVmOnHypervisorReply reply = new UpdateVmOnHypervisorReply(); + final UpdateVmInstanceSpec spec = msg.getSpec(); + + if (!spec.isCpuChanged() && !spec.isMemoryChanged() && !spec.isReservedMemoryChanged()) { + logger.debug("Neither CPU and memory is changed, skip updating VM on hypervisor."); + bus.reply(msg, reply); + return; + } + + final VmInstanceVO vm = dbf.findByUuid(spec.getVmInstanceUuid(), VmInstanceVO.class); + + final boolean cpuNeedChange = spec.isCpuChanged(); + final boolean memoryNeedChange = spec.isMemoryChanged(); + final int cpuChangeTo = cpuNeedChange ? spec.getCpuNum() : vm.getCpuNum(); + final long memoryChangeTo = memoryNeedChange ? spec.getMemorySize() : vm.getMemorySize(); + + if (vm.getState() == VmInstanceState.Stopped) { + if (cpuNeedChange) { + reply.setCpuUpdatedTo(cpuChangeTo); + } + if (memoryNeedChange) { + reply.setMemoryUpdatedTo(memoryChangeTo); + } + bus.reply(msg, reply); + return; + } + + final int oldCpuNum = vm.getCpuNum(); + final long oldMemorySize = vm.getMemorySize(); + final AtomicLong alignedMemory = new AtomicLong(memoryChangeTo); + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("change-cpu-and-memory-of-vm-%s-from-host-%s", vm.getUuid(), self.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "align-memory"; + + @Override + public void run(FlowTrigger chain, Map data) { + // align memory + long increaseMemory = memoryChangeTo - oldMemorySize; + long remainderMemory = increaseMemory % SizeUnit.MEGABYTE.toByte(128); + if (increaseMemory != 0 && remainderMemory != 0) { + if (remainderMemory < SizeUnit.MEGABYTE.toByte(128) / 2) { + increaseMemory = increaseMemory / SizeUnit.MEGABYTE.toByte(128) * SizeUnit.MEGABYTE.toByte(128); + } else { + increaseMemory = (increaseMemory / SizeUnit.MEGABYTE.toByte(128) + 1) * SizeUnit.MEGABYTE.toByte(128); + } + + if (increaseMemory == 0) { + alignedMemory.set(oldMemorySize + SizeUnit.MEGABYTE.toByte(128)); + } else { + alignedMemory.set(oldMemorySize + increaseMemory); + } + + logger.debug(String.format("automatically align memory from %d to %d", memoryChangeTo, alignedMemory.get())); + } + chain.next(); + } + }).then(new Flow() { + String __name__ = "allocate-host-capacity-on-host"; + boolean result = false; + + @Override + public void run(FlowTrigger chain, Map data) { + DesignatedAllocateHostMsg msg = new DesignatedAllocateHostMsg(); + msg.setCpuCapacity(cpuNeedChange ? (long) cpuChangeTo - oldCpuNum : 0); + msg.setMemoryCapacity(memoryNeedChange ? alignedMemory.get() - oldMemorySize : 0L); + msg.setOldMemoryCapacity(oldMemorySize); + msg.setAllocatorStrategy(HostAllocatorConstant.DESIGNATED_HOST_ALLOCATOR_STRATEGY_TYPE); + msg.setVmInstance(VmInstanceInventory.valueOf(vm)); + if (vm.getImageUuid() != null && dbf.isExist(vm.getImageUuid(), ImageVO.class)) { + msg.setImage(ImageInventory.valueOf(dbf.findByUuid(vm.getImageUuid(), ImageVO.class))); + } + msg.setAllowNoL3Networks(true); + msg.setHostUuid(self.getUuid()); + msg.setFullAllocate(false); + msg.setL3NetworkUuids(VmNicHelper.getL3Uuids(VmNicInventory.valueOf(vm.getVmNics()))); + msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); + bus.send(msg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + ErrorCode err = operr("host[uuid:%s] capacity is not enough to offer cpu[%s], memory[%s bytes]", + vm.getUuid(), cpuChangeTo - oldCpuNum, alignedMemory.get() - oldMemorySize); + err.setCause(reply.getError()); + chain.fail(err); + } else { + result = true; + logger.debug(String.format("reserve memory %s bytes and cpu %s on host[uuid:%s]", + memoryChangeTo - vm.getMemorySize(), cpuChangeTo - vm.getCpuNum(), self.getUuid())); + chain.next(); + } + } + }); + } + + @Override + public void rollback(FlowRollback chain, Map data) { + if (result) { + ReturnHostCapacityMsg msg = new ReturnHostCapacityMsg(); + msg.setCpuCapacity(cpuNeedChange ? (long) cpuChangeTo - oldCpuNum : 0); + msg.setMemoryCapacity(memoryNeedChange ? alignedMemory.get() - oldMemorySize : 0L); + msg.setHostUuid(self.getUuid()); + msg.setServiceId(bus.makeLocalServiceId(HostAllocatorConstant.SERVICE_ID)); + bus.send(msg); + } + + chain.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "change-vm-cpu"; + + @Override + public boolean skip(Map data) { + return !cpuNeedChange; + } + + @Override + public void run(FlowTrigger chain, Map data) { + IncreaseVmCpuMsg msg = new IncreaseVmCpuMsg(); + msg.setVmInstanceUuid(vm.getUuid()); + msg.setHostUuid(self.getUuid()); + msg.setCpuNum(cpuChangeTo); + bus.makeLocalServiceId(msg, HostConstant.SERVICE_ID); + bus.send(msg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply innerReply) { + if (!innerReply.isSuccess()) { + chain.fail(innerReply.getError()); + return; + } + IncreaseVmCpuReply casedReply = innerReply.castReply(); + reply.setCpuUpdatedTo(casedReply.getCpuNum()); + chain.next(); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "change-vm-memory"; - } catch (Exception e) { - logger.warn(String.format("got exception when trying set nic multiqueue for vm: %s, %s", spec.getVmInventory().getUuid(), e)); - } - } + @Override + public boolean skip(Map data) { + return !memoryNeedChange; + } - private void handle(final CreateVmOnHypervisorMsg msg) { - inQueue().name(String.format("start-vm-on-kvm-%s", self.getUuid())) - .asyncBackup(msg) - .run(chain -> { - setDataVolumeUseVirtIOSCSI(msg.getVmSpec()); - setVmNicMultiqueueNum(msg.getVmSpec()); - startVm(msg.getVmSpec(), msg, new NoErrorCompletion(chain) { - @Override - public void done() { - chain.next(); + @Override + public void run(FlowTrigger chain, Map data) { + IncreaseVmMemoryMsg msg = new IncreaseVmMemoryMsg(); + msg.setVmInstanceUuid(vm.getUuid()); + msg.setHostUuid(self.getUuid()); + msg.setMemorySize(alignedMemory.get()); + bus.makeLocalServiceId(msg, HostConstant.SERVICE_ID); + bus.send(msg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply innerReply) { + if (!innerReply.isSuccess()) { + chain.fail(innerReply.getError()); + return; } - }); + IncreaseVmMemoryReply casedReply = innerReply.castReply(); + reply.setMemoryUpdatedTo(casedReply.getMemorySize()); + chain.next(); + } }); + } + }).done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + bus.reply(msg, reply); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errorCode, Map data) { + if (reply.hasAnythingUpdated()) { + reply.getIgnoredErrors().add(errorCode); + } else { + reply.setError(errorCode); + } + bus.reply(msg, reply); + } + }).start(); } private void handle(final UpdateSpiceChannelConfigMsg msg) { @@ -2672,9 +4184,17 @@ private NicTO completeNicInfo(VmNicInventory nic) { if (to.getUseVirtio() == null) { to.setUseVirtio(VmSystemTags.VIRTIO.hasTag(nic.getVmInstanceUuid())); to.setIps(getCleanTrafficIp(nic)); + if (to.getUseVirtio() && Q.New(VmNicVO.class) + .eq(VmNicVO_.uuid, nic.getUuid()).eq(VmNicVO_.driverType, VmNicDriverType.VIRTIO.toString()).isExists()) { + to.setDriverType(VmNicDriverType.VIRTIO.toString()); + } } - if (!nic.getType().equals(VmInstanceConstant.VIRTUAL_NIC_TYPE)) { + String tagValue = VmSystemTags.CLEAN_TRAFFIC.getTokenByResourceUuid(nic.getVmInstanceUuid(), VmSystemTags.CLEAN_TRAFFIC_TOKEN); + to.setCleanTraffic(tagValue == null ? Boolean.FALSE : Boolean.parseBoolean(tagValue)); + + VmNicType nicType = VmNicType.valueOf(nic.getType()); + if (!nicType.isHasAddon()) { return to; } @@ -2690,7 +4210,18 @@ private NicTO completeNicInfo(VmNicInventory nic) { VHostAddOn vHostAddOn = new VHostAddOn(); if (to.getDriverType().equals(nicManager.getDefaultPVNicDriver())) { - vHostAddOn.setQueueNum(rcf.getResourceConfigValue(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM, nic.getVmInstanceUuid(), Integer.class)); + int nicMultiQueueNum = 1; + + List numInStrings = Q.New(ResourceConfigVO.class).eq(ResourceConfigVO_.name, VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM.getName()) + .eq(ResourceConfigVO_.resourceUuid, nic.getUuid()) + .select(ResourceConfigVO_.value).listValues(); + if (!numInStrings.isEmpty()) { + nicMultiQueueNum = TypeUtils.stringToValue(numInStrings.get(0), Integer.class); + } else { + nicMultiQueueNum = rcf.getResourceConfigValue(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM, nic.getVmInstanceUuid(), Integer.class); + } + + vHostAddOn.setQueueNum(nicMultiQueueNum); } else { vHostAddOn.setQueueNum(VmGlobalConfig.VM_NIC_MULTIQUEUE_NUM.defaultValue(Integer.class)); } @@ -2708,11 +4239,14 @@ private NicTO completeNicInfo(VmNicInventory nic) { to.setvHostAddOn(vHostAddOn); - String pci = KVMSystemTags.VMNIC_PCI_ADDRESS.getTokenByResourceUuid(nic.getUuid(), KVMSystemTags.VMNIC_PCI_ADDRESS_TOKEN); + DeviceAddress pci = vidm.getVmDeviceAddress(nic.getUuid(), nic.getVmInstanceUuid()); if (pci != null) { - to.setPci(PciAddressConfig.fromString(pci)); + to.setPci(pci); } - + to.setL2NetworkUuid(l2inv.getUuid()); + to.setResourceUuid(nic.getUuid()); + to.setState(nic.getState()); + to.setIsolated(l2inv.getIsolated()); return to; } @@ -2734,6 +4268,9 @@ private List getCleanTrafficIp(VmNicInventory nic) { } static String getVolumeTOType(VolumeInventory vol) { + if (vol.getProtocol() != null) { + return VolumeTO.deviceTypes.get(VolumeProtocol.valueOf(vol.getProtocol())); + } DebugUtils.Assert(vol.getInstallPath() != null, String.format("volume [%s] installPath is null, it has not been initialized", vol.getUuid())); return vol.getInstallPath().startsWith("iscsi") ? VolumeTO.ISCSI : VolumeTO.FILE; } @@ -2745,21 +4282,51 @@ private void checkPlatformWithOther(VmInstanceSpec spec) { } } - protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, final NoErrorCompletion completion) { - checkStateAndStatus(); + /** + * set cpu topology for vm, use the cpu topology from vm spec if it's not null, + * otherwise use the cpu topology from image platform + *

    + * TODO: image should support cpu topology to use a more suitable topology for + * applications inside it + *

    + * + * @param spec vm spec + * @param cmd start vm cmd + * @param platform image platform + */ + private void setStartVmCpuTopology(final VmInstanceSpec spec, final StartVmCmd cmd, String platform) { + int cpuNum = cmd.getCpuNum(); + + if (cmd.isUseNuma()) { + cmd.setMaxVcpuNum(rcf.getResourceConfigValue(VmGlobalConfig.VM_MAX_VCPU, spec.getVmInventory().getUuid(), Integer.class)); + } - final StartVmCmd cmd = new StartVmCmd(); + if (VmHardwareSystemTags.CPU_SOCKETS.hasTag(spec.getVmInventory().getUuid()) + || VmHardwareSystemTags.CPU_CORES.hasTag(spec.getVmInventory().getUuid()) + || VmHardwareSystemTags.CPU_THREADS.hasTag(spec.getVmInventory().getUuid())) { + String sockets = VmHardwareSystemTags.CPU_SOCKETS.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmHardwareSystemTags.CPU_SOCKETS_TOKEN); + String cores = VmHardwareSystemTags.CPU_CORES.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmHardwareSystemTags.CPU_CORES_TOKEN); + String threads = VmHardwareSystemTags.CPU_THREADS.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmHardwareSystemTags.CPU_THREADS_TOKEN); - String platform = spec.getVmInventory().getPlatform() == null ? spec.getImageSpec().getInventory().getPlatform() : - spec.getVmInventory().getPlatform(); - if(ImagePlatform.Other.toString().equals(platform)){ - checkPlatformWithOther(spec); - } + CpuTopology cpuTopology = new CpuTopology(cmd.getMaxVcpuNum() == 0 ? cpuNum : cmd.getMaxVcpuNum(), sockets, cores, threads); + cpuTopology.calculateValidTopology(true); + cmd.setSocketNum(cpuTopology.getCpuSockets()); + cmd.setCpuOnSocket(cpuTopology.getCpuCores()); + cmd.setThreadsPerCore(cpuTopology.getCpuThreads()); - String architecture = spec.getDestHost().getArchitecture(); + // change max vcpu num to the real vcpu num + if (cmd.isUseNuma()) { + cmd.setMaxVcpuNum(cmd.getSocketNum() * cmd.getCpuOnSocket() * cmd.getThreadsPerCore()); + } + return; + } - int cpuNum = spec.getVmInventory().getCpuNum(); - cmd.setCpuNum(cpuNum); + // keep back-compatible + // cpu topology is hard-coded in agent, so we only set max vcpu num here + // topology will be set in agent + if (cmd.isUseNuma()) { + return; + } int socket; int cpuOnSocket; @@ -2779,15 +4346,37 @@ protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, fi socket = 1; cpuOnSocket = cpuNum; } - cmd.setImagePlatform(platform); - cmd.setImageArchitecture(architecture); + cmd.setSocketNum(socket); cmd.setCpuOnSocket(cpuOnSocket); + } + + protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, final NoErrorCompletion completion) { + checkStateAndStatus(); + + final StartVmCmd cmd = new StartVmCmd(); + + String platform = spec.getVmInventory().getPlatform() == null ? spec.getImageSpec().getInventory().getPlatform() : + spec.getVmInventory().getPlatform(); + if(ImagePlatform.Other.toString().equals(platform)){ + checkPlatformWithOther(spec); + } + + String architecture = spec.getDestHost().getArchitecture(); + + int cpuNum = spec.getVmInventory().getCpuNum(); + cmd.setCpuNum(cpuNum); + cmd.setUseNuma(rcf.getResourceConfigValue(VmGlobalConfig.NUMA, spec.getVmInventory().getUuid(), Boolean.class)); + setStartVmCpuTopology(spec, cmd, platform); + + cmd.setImagePlatform(platform); + cmd.setImageArchitecture(architecture); cmd.setVmName(spec.getVmInventory().getName()); cmd.setVmInstanceUuid(spec.getVmInventory().getUuid()); cmd.setCpuSpeed(spec.getVmInventory().getCpuSpeed()); cmd.setMemory(spec.getVmInventory().getMemorySize()); cmd.setMaxMemory(self.getCapacity().getTotalPhysicalMemory()); + cmd.setReservedMemory(spec.getVmInventory().getReservedMemorySize()); cmd.setClock(ImagePlatform.isType(platform, ImagePlatform.Windows, ImagePlatform.WindowsVirtio) ? "localtime" : "utc"); VmClockTrack vmClockTrack = VmClockTrack.get(rcf.getResourceConfigValue(VmGlobalConfig.VM_CLOCK_TRACK, spec.getVmInventory().getUuid(), String.class)); if (vmClockTrack == VmClockTrack.guest) { @@ -2795,24 +4384,31 @@ protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, fi } cmd.setVideoType(rcf.getResourceConfigValue(VmGlobalConfig.VM_VIDEO_TYPE, spec.getVmInventory().getUuid(), String.class)); + cmd.setSoundType(rcf.getResourceConfigValue(VmGlobalConfig.VM_SOUND_TYPE, spec.getVmInventory().getUuid(), String.class)); if (VmSystemTags.QXL_MEMORY.hasTag(spec.getVmInventory().getUuid())) { Map qxlMemory = VmSystemTags.QXL_MEMORY.getTokensByResourceUuid(spec.getVmInventory().getUuid()); cmd.setQxlMemory(qxlMemory); } - if (VmSystemTags.SOUND_TYPE.hasTag(spec.getVmInventory().getUuid())) { - cmd.setSoundType(VmSystemTags.SOUND_TYPE.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmInstanceVO.class, VmSystemTags.SOUND_TYPE_TOKEN)); - } cmd.setInstanceOfferingOnlineChange(VmSystemTags.INSTANCEOFFERING_ONLIECHANGE.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmSystemTags.INSTANCEOFFERING_ONLINECHANGE_TOKEN) != null); cmd.setKvmHiddenState(rcf.getResourceConfigValue(VmGlobalConfig.KVM_HIDDEN_STATE, spec.getVmInventory().getUuid(), Boolean.class)); - cmd.setSpiceStreamingMode(VmGlobalConfig.VM_SPICE_STREAMING_MODE.value(String.class)); + cmd.setSpiceStreamingMode(rcf.getResourceConfigValue(VmGlobalConfig.VM_SPICE_STREAMING_MODE, spec.getVmInventory().getUuid(), String.class)); boolean emulateHyperV = false; - if (!ImagePlatform.isType(platform, ImagePlatform.Linux) && - ImageArchitecture.x86_64.toString().equals(architecture)) { + if (ImagePlatform.isType(platform, ImagePlatform.Windows, ImagePlatform.WindowsVirtio) + && ImageArchitecture.x86_64.toString().equals(architecture)) { emulateHyperV = rcf.getResourceConfigValue(VmGlobalConfig.EMULATE_HYPERV, spec.getVmInventory().getUuid(), Boolean.class); } cmd.setEmulateHyperV(emulateHyperV); + boolean enableHypervClock = rcf.getResourceConfigValue( + KVMGlobalConfig.VM_HYPERV_CLOCK_FEATURE, + spec.getVmInventory().getUuid(), Boolean.class); + cmd.setHypervClock(enableHypervClock); + + // suspend features + cmd.setSuspendToDisk(rcf.getResourceConfigValue(KVMGlobalConfig.SUSPEND_TO_DISK, spec.getVmInventory().getUuid(), Boolean.class)); + cmd.setSuspendToRam(rcf.getResourceConfigValue(KVMGlobalConfig.SUSPEND_TO_RAM, spec.getVmInventory().getUuid(), Boolean.class)); + cmd.setVendorId(rcf.getResourceConfigValue(VmGlobalConfig.VENDOR_ID, spec.getVmInventory().getUuid(), String.class)); cmd.setAdditionalQmp(VmGlobalConfig.ADDITIONAL_QMP.value(Boolean.class)); cmd.setApplianceVm(spec.getVmInventory().getType().equals("ApplianceVm")); @@ -2842,14 +4438,16 @@ protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, fi cmd.setPriorityConfigStruct(new PriorityConfigStruct(priorityVO, spec.getVmInventory().getUuid())); VolumeTO rootVolume = new VolumeTO(); + rootVolume.setResourceUuid(spec.getDestRootVolume().getUuid()); rootVolume.setInstallPath(spec.getDestRootVolume().getInstallPath()); rootVolume.setDeviceId(spec.getDestRootVolume().getDeviceId()); rootVolume.setDeviceType(getVolumeTOType(spec.getDestRootVolume())); + rootVolume.setFormat(spec.getDestRootVolume().getFormat()); rootVolume.setVolumeUuid(spec.getDestRootVolume().getUuid()); rootVolume.setUseVirtio(VmSystemTags.VIRTIO.hasTag(spec.getVmInventory().getUuid())); - rootVolume.setUseVirtioSCSI(ImagePlatform.Other.toString().equals(platform) ? false : KVMSystemTags.VOLUME_VIRTIO_SCSI.hasTag(spec.getDestRootVolume().getUuid())); + rootVolume.setUseVirtioSCSI(!ImagePlatform.Other.toString().equals(platform) && KVMSystemTags.VOLUME_VIRTIO_SCSI.hasTag(spec.getDestRootVolume().getUuid())); rootVolume.setWwn(computeWwnIfAbsent(spec.getDestRootVolume().getUuid())); - rootVolume.setCacheMode(KVMGlobalConfig.LIBVIRT_CACHE_MODE.value()); + rootVolume.setCacheMode(rcf.getResourceConfigValue(KVMGlobalConfig.LIBVIRT_CACHE_MODE, spec.getDestRootVolume().getUuid(), String.class)); String vmCpuMode = rcf.getResourceConfigValue(KVMGlobalConfig.NESTED_VIRTUALIZATION, spec.getVmInventory().getUuid(), String.class); if (vmCpuMode.equals(KVMConstant.CPU_MODE_NONE) || vmCpuMode.equals(KVMConstant.CPU_MODE_HOST_MODEL) || vmCpuMode.equals(KVMConstant.CPU_MODE_HOST_PASSTHROUGH)) { @@ -2862,6 +4460,13 @@ protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, fi cmd.setRootVolume(rootVolume); cmd.setUseBootMenu(VmGlobalConfig.VM_BOOT_MENU.value(Boolean.class)); + if (cmd.isUseBootMenu()) { + cmd.setBootMenuSplashTimeout(rcf.getResourceConfigValue( + VmGlobalConfig.VM_BOOT_MENU_SPLASH_TIMEOUT, + spec.getVmInventory().getUuid(), + Integer.class)); + } + List dataVolumes = new ArrayList<>(spec.getDestDataVolumes().size()); for (VolumeInventory data : spec.getDestDataVolumes()) { VolumeTO v = VolumeTO.valueOfWithOutExtension(data, (KVMHostInventory) getSelfInventory(), spec.getVmInventory().getPlatform()); @@ -2885,6 +4490,7 @@ protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, fi cmd.setVmInternalId(spec.getVmInventory().getInternalId()); + checkCleanTraffic(spec.getVmInventory().getUuid()); List nics = new ArrayList<>(spec.getDestNics().size()); for (VmNicInventory nic : spec.getDestNics()) { NicTO to = completeNicInfo(nic); @@ -2895,46 +4501,72 @@ protected void startVm(final VmInstanceSpec spec, final NeedReplyMessage msg, fi for (VmInstanceSpec.CdRomSpec cdRomSpec : spec.getCdRomSpecs()) { CdRomTO cdRomTO = new CdRomTO(); + cdRomTO.setResourceUuid(cdRomSpec.getUuid()); cdRomTO.setPath(cdRomSpec.getInstallPath()); cdRomTO.setImageUuid(cdRomSpec.getImageUuid()); cdRomTO.setDeviceId(cdRomSpec.getDeviceId()); cdRomTO.setEmpty(cdRomSpec.getImageUuid() == null); + cdRomTO.setPrimaryStorageUuid(cdRomSpec.getPrimaryStorageUuid()); + cdRomTO.setProtocol(cdRomSpec.getProtocol()); cmd.getCdRoms().add(cdRomTO); } String bootMode = VmSystemTags.BOOT_MODE.getTokenByResourceUuid(spec.getVmInventory().getUuid(), VmSystemTags.BOOT_MODE_TOKEN); cmd.setBootMode(bootMode == null ? ImageBootMode.Legacy.toString() : bootMode); + if (cmd.getBootMode().equals(ImageBootMode.UEFI.toString()) + || cmd.getBootMode().equals(ImageBootMode.UEFI_WITH_CSM.toString())) { + cmd.setSecureBoot(VmGlobalConfig.ENABLE_UEFI_SECURE_BOOT.value(Boolean.class)); + } + deviceBootOrderOperator.updateVmDeviceBootOrder(cmd, spec); cmd.setBootDev(toKvmBootDev(spec.getBootOrders())); cmd.setHostManagementIp(self.getManagementIp()); cmd.setConsolePassword(spec.getConsolePassword()); cmd.setUsbRedirect(spec.isUsbRedirect()); + cmd.setEnableSecurityElement(spec.isEnableSecurityElement()); cmd.setVDIMonitorNumber(Integer.valueOf(spec.getVDIMonitorNumber())); - cmd.setUseNuma(rcf.getResourceConfigValue(VmGlobalConfig.NUMA, spec.getVmInventory().getUuid(), Boolean.class)); - cmd.setVmPortOff(VmGlobalConfig.VM_PORT_OFF.value(Boolean.class)); + cmd.setVmPortOff(rcf.getResourceConfigValue(VmGlobalConfig.VM_PORT_OFF, spec.getVmInventory().getUuid(), Boolean.class)); cmd.setConsoleMode("vnc"); cmd.setTimeout(TimeUnit.MINUTES.toSeconds(5)); - cmd.setConsoleLogToFile(!VmInstanceConstant.USER_VM_TYPE.equals(spec.getVmInventory().getType())); + cmd.setConsoleLogToFile(rcf.getResourceConfigValue(KVMGlobalConfig.REDIRECT_CONSOLE_LOG_TO_FILE, spec.getVmInventory().getUuid(), Boolean.class)); if (spec.isCreatePaused()) { cmd.setCreatePaused(true); } - String vmArchPlatformRelease = String.format("%s_%s_%s", spec.getVmInventory().getArchitecture(), spec.getVmInventory().getPlatform(), spec.getVmInventory().getGuestOsType()); - if (allGuestOsCharacter.containsKey(vmArchPlatformRelease)) { - cmd.setAcpi(allGuestOsCharacter.get(vmArchPlatformRelease).getAcpi() != null && allGuestOsCharacter.get(vmArchPlatformRelease).getAcpi()); - cmd.setHygonCpu(allGuestOsCharacter.get(vmArchPlatformRelease).getHygonCpu() != null && allGuestOsCharacter.get(vmArchPlatformRelease).getHygonCpu()); + cmd.setAcpi(true); + + GuestOsCharacter.Config config = GuestOsHelper.getInstance().getGuestOsCharacter( + spec.getVmInventory().getArchitecture(), + spec.getVmInventory().getPlatform(), + spec.getVmInventory().getGuestOsType()); + if (config != null) { + cmd.setAcpi(config.getAcpi() == null || config.getAcpi()); + cmd.setX2apic(config.getX2apic() == null || config.getX2apic()); } + cmd.setCpuHypervisorFeature(rcf.getResourceConfigValue(KVMGlobalConfig.VM_CPU_HYPERVISOR_FEATURE, + spec.getVmInventory().getUuid(), + Boolean.class)); + + VirtualDeviceInfo memBalloon = new VirtualDeviceInfo(); + memBalloon.setResourceUuid(vidm.MEM_BALLOON_UUID); + memBalloon.setDeviceAddress(vidm.getVmDeviceAddress(vidm.MEM_BALLOON_UUID, spec.getVmInventory().getUuid())); + cmd.setMemBalloon(memBalloon); + addons(spec, cmd); KVMHostInventory khinv = KVMHostInventory.valueOf(getSelf()); extEmitter.beforeStartVmOnKvm(khinv, spec, cmd); extEmitter.addOn(khinv, spec, cmd); + //Set account uuid for kvm agent call vrouter agent api + cmd.setAccountUuid(accountMgr.getOwnerAccountUuidOfResource(cmd.getVmInstanceUuid())); new Http<>(startVmPath, cmd, StartVmResponse.class).call(new ReturnValueCompletion(msg, completion) { @Override public void success(StartVmResponse ret) { StartVmOnHypervisorReply reply = new StartVmOnHypervisorReply(); if (ret.isSuccess()) { + extEmitter.afterReceiveSyncVmDeviceInfoResponse(null, ret, spec); + String info = String.format("successfully start vm[uuid:%s name:%s] on kvm host[uuid:%s, ip:%s]", spec.getVmInventory().getUuid(), spec.getVmInventory().getName(), self.getUuid(), self.getManagementIp()); @@ -2963,7 +4595,7 @@ public void success(StartVmResponse ret) { SystemTagCreator creator = KVMSystemTags.VMNIC_PCI_ADDRESS.newSystemTagCreator(nic.getUuid()); creator.inherent = true; creator.recreate = true; - creator.setTagByTokens(map(e(KVMSystemTags.VMNIC_PCI_ADDRESS_TOKEN, vmNicInfo.getPciInfo().toString()))); + creator.setTagByTokens(map(e(KVMSystemTags.VMNIC_PCI_ADDRESS_TOKEN, vmNicInfo.getDeviceAddress().toString()))); creator.create(); } } @@ -2974,8 +4606,8 @@ public void success(StartVmResponse ret) { @Override public void fail(ErrorCode err) { StartVmOnHypervisorReply reply = new StartVmOnHypervisorReply(); - reply.setError(err); - reply.setSuccess(false); + reply.setError(err(HostErrors.FAILED_TO_START_VM_ON_HYPERVISOR, "failed to start vm[uuid: %s] on kvm host[uuid: %s], because %s", + spec.getVmInventory().getUuid(), self.getUuid(), err)); extEmitter.startVmOnKvmFailed(KVMHostInventory.valueOf(getSelf()), spec, err); bus.reply(msg, reply); completion.done(); @@ -3196,6 +4828,38 @@ protected HostInventory getSelfInventory() { return KVMHostInventory.valueOf(getSelf()); } + private void doReconnectHostDueToPingResult(PingResponse ret) { + String info = i18n("detected abnormal status[host uuid change, expected: %s but: %s or agent version change, expected: %s but: %s] of kvmagent," + + "it's mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon", + self.getUuid(), ret.getHostUuid(), dbf.getDbVersion(), ret.getVersion()); + logger.warn(info); + + // when host is connecting, skip handling agent config changed issue + // and agent config change will be detected by next ping + self = dbf.reload(self); + if (self.getStatus() == HostStatus.Connecting) { + logger.debug("host status is %s, ignore version or host uuid changed issue"); + return; + } + + if (UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + if (ret.getVersion() != null) { + logger.debug("skip fire host disconnected event and reconnect host during grayscale upgrade"); + return; + } + + logger.debug("still fire host disconnected event when kvmagent report version is null"); + } + + changeConnectionState(HostStatusEvent.disconnected); + new HostDisconnectedCanonicalEvent(self.getUuid(), argerr(info)).fire(); + + ReconnectHostMsg rmsg = new ReconnectHostMsg(); + rmsg.setHostUuid(self.getUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, HostConstant.SERVICE_ID, self.getUuid()); + bus.send(rmsg); + } + private void doUpdateHostConfiguration() { thdf.chainSubmit(new ChainTask(null) { @Override @@ -3253,8 +4917,37 @@ public String getName() { }); } - boolean needReconnectHost(PingResponse rsp) { - return !self.getUuid().equals(rsp.getHostUuid()) || !dbf.getDbVersion().equals(rsp.getVersion()); + enum ReconnectHostAction { + SkipPingExtensionAndReconnect, + DoPingExtensionAndReconnect, + DoNothing + } + + ReconnectHostAction needReconnectHost(PingResponse rsp) { + if (!self.getUuid().equals(rsp.getHostUuid())) { + return ReconnectHostAction.SkipPingExtensionAndReconnect; + } + + if (!dbf.getDbVersion().equals(rsp.getVersion())) { + return ReconnectHostAction.DoPingExtensionAndReconnect; + } + + return ReconnectHostAction.DoNothing; + } + + boolean inconsistentHostUuid(PingResponse rsp) { + return !self.getUuid().equals(rsp.getHostUuid()); + } + + @Override + protected void connectHostFailHook(ErrorCode errorCode) { + if (errorCode.getRootCause().isError(HostErrors.HOST_PASSWORD_HAS_BEEN_CHANGED)) { + logger.warn(String.format("fail to connect host[uuid:%s] due to wrong SSH password", self.getUuid())); + new HostDisconnectedCanonicalEvent(self.getUuid(), errorCode).fire(); + // stop tracking host by tracker.trackHost within the current tracking cycle + return; + } + super.connectHostFailHook(errorCode); } boolean needUpdateHostConfiguration(PingResponse rsp) { @@ -3279,6 +4972,8 @@ public void setup() { public void run(FlowTrigger trigger, Map data) { PingCmd cmd = new PingCmd(); cmd.hostUuid = self.getUuid(); + cmd.kvmagentPhysicalMemoryUsageAlarmThreshold = gcf.getConfigValue(KVMGlobalConfig.CATEGORY, KVMGlobalConfig.KVMAGENT_PHYSICAL_MEMORY_USAGE_ALARM_THRESHOLD.getName(), Long.class); + cmd.kvmagentPhysicalMemoryUsageHardLimit = gcf.getConfigValue(KVMGlobalConfig.CATEGORY, KVMGlobalConfig.KVMAGENT_PHYSICAL_MEMORY_USAGE_HARD_LIMIT.getName(), Long.class); restf.asyncJsonPost(pingPath, cmd, new JsonAsyncRESTCallback(trigger) { @Override public void fail(ErrorCode err) { @@ -3287,37 +4982,28 @@ public void fail(ErrorCode err) { @Override public void success(PingResponse ret) { - if (ret.isSuccess()) { - if (needUpdateHostConfiguration(ret)) { - afterDone.add(KVMHost.this::doUpdateHostConfiguration); - } else if (needReconnectHost(ret)) { - afterDone.add(() -> { - String info = i18n("detected abnormal status[host uuid change, expected: %s but: %s or agent version change, expected: %s but: %s] of kvmagent," + - "it's mainly caused by kvmagent restarts behind zstack management server. Report this to ping task, it will issue a reconnect soon", - self.getUuid(), ret.getHostUuid(), dbf.getDbVersion(), ret.getVersion()); - logger.warn(info); - - // when host is connecting, skip handling agent config changed issue - // and agent config change will be detected by next ping - self = dbf.reload(self); - if (self.getStatus() == HostStatus.Connecting) { - logger.debug("host status is %s, ignore version or host uuid changed issue"); - return; - } - - changeConnectionState(HostStatusEvent.disconnected); - new HostDisconnectedCanonicalEvent(self.getUuid(), argerr(info)).fire(); - - ReconnectHostMsg rmsg = new ReconnectHostMsg(); - rmsg.setHostUuid(self.getUuid()); - bus.makeTargetServiceIdByResourceUuid(rmsg, HostConstant.SERVICE_ID, self.getUuid()); - bus.send(rmsg); - }); - } - trigger.next(); - } else { + if (!ret.isSuccess()) { trigger.fail(operr("%s", ret.getError())); + return; + } + + // update host agent version when open grayScaleUpgrade + upgradeChecker.updateAgentVersion(self.getUuid(), AnsibleConstant.KVM_AGENT_NAME, dbf.getDbVersion(), ret.getVersion()); + + ReconnectHostAction action = needReconnectHost(ret); + if (!action.equals(ReconnectHostAction.DoNothing)) { + // reconnect host require many steps which may influence the results + // of extension points, so we skip them here and do it after next ping + if (action.equals(ReconnectHostAction.SkipPingExtensionAndReconnect)) { + data.put(KVMConstant.KVM_HOST_SKIP_PING_NO_FAILURE_EXTENSIONS, true); + } + + afterDone.add(() -> doReconnectHostDueToPingResult(ret)); + } else if (needUpdateHostConfiguration(ret)) { + afterDone.add(KVMHost.this::doUpdateHostConfiguration); } + + trigger.next(); } @Override @@ -3331,6 +5017,11 @@ public Class getReturnClass() { flow(new NoRollbackFlow() { String __name__ = "call-ping-no-failure-plugins"; + @Override + public boolean skip(Map data) { + return data.get(KVMConstant.KVM_HOST_SKIP_PING_NO_FAILURE_EXTENSIONS) != null; + } + @Override public void run(FlowTrigger trigger, Map data) { List exts = pluginRgty.getExtensionList(KVMPingAgentNoFailureExtensionPoint.class); @@ -3361,6 +5052,11 @@ public void done() { flow(new NoRollbackFlow() { String __name__ = "call-ping-plugins"; + @Override + public boolean skip(Map data) { + return data.get(KVMConstant.KVM_HOST_SKIP_PING_NO_FAILURE_EXTENSIONS) != null; + } + @Override public void run(FlowTrigger trigger, Map data) { List exts = pluginRgty.getExtensionList(KVMPingAgentExtensionPoint.class); @@ -3442,11 +5138,12 @@ private ErrorCode connectToAgent() { cmd.setIgnoreMsrs(KVMGlobalConfig.KVM_IGNORE_MSRS.value(Boolean.class)); cmd.setTcpServerPort(KVMGlobalProperty.TCP_SERVER_PORT); cmd.setVersion(dbf.getDbVersion()); + cmd.setInstallHostShutdownHook(KVMGlobalConfig.INSTALL_HOST_SHUTDOWN_HOOK.value(Boolean.class)); if (HostSystemTags.PAGE_TABLE_EXTENSION_DISABLED.hasTag(self.getUuid(), HostVO.class) || !KVMSystemTags.EPT_CPU_FLAG.hasTag(self.getUuid())) { cmd.setPageTableExtensionDisabled(true); } ConnectResponse rsp = restf.syncJsonPost(connectPath, cmd, ConnectResponse.class); - if (!rsp.isSuccess() || !rsp.isIptablesSucc()) { + if (!rsp.isSuccess()) { errCode = operr("unable to connect to kvm host[uuid:%s, ip:%s, url:%s], because %s", self.getUuid(), self.getManagementIp(), connectPath, rsp.getError()); } else { @@ -3455,8 +5152,7 @@ private ErrorCode connectToAgent() { boolean liveSnapshot = libvirtVersion.compare(KVMConstant.MIN_LIBVIRT_LIVESNAPSHOT_VERSION) >= 0 && qemuVersion.compare(KVMConstant.MIN_QEMU_LIVESNAPSHOT_VERSION) >= 0; - String hostOS = HostSystemTags.OS_DISTRIBUTION.getTokenByResourceUuid(self.getUuid(), HostSystemTags.OS_DISTRIBUTION_TOKEN); - //liveSnapshot = liveSnapshot && (!"CentOS".equals(hostOS) || KVMGlobalConfig.ALLOW_LIVE_SNAPSHOT_ON_REDHAT.value(Boolean.class)); + final HostOperationSystem hostOS = factory.getHostOS(self.getUuid()); if (liveSnapshot) { logger.debug(String.format("kvm host[OS:%s, uuid:%s, name:%s, ip:%s] supports live snapshot with libvirt[version:%s], qemu[version:%s]", @@ -3555,7 +5251,14 @@ private boolean noStorageAccessible(){ return inaccessiblePsCount == attachedPsCount && attachedPsCount > 0; } - private void createHostVersionSystemTags(String distro, String release, String version) { + private void updateHostOsInformation(String distro, String release, String version) { + final KVMHostVO kvmHostVO = getSelf(); + kvmHostVO.setOsDistribution(distro); + kvmHostVO.setOsRelease(release); + kvmHostVO.setOsVersion(version); + self = dbf.updateAndRefresh(kvmHostVO); + + // for compatibility createTagWithoutNonValue(HostSystemTags.OS_DISTRIBUTION, HostSystemTags.OS_DISTRIBUTION_TOKEN, distro, true); createTagWithoutNonValue(HostSystemTags.OS_RELEASE, HostSystemTags.OS_RELEASE_TOKEN, release, true); createTagWithoutNonValue(HostSystemTags.OS_VERSION, HostSystemTags.OS_VERSION_TOKEN, version, true); @@ -3572,20 +5275,237 @@ private void recreateNonInherentTag(SystemTag tag, String token, String value) { recreateTag(tag, token, value, false); } - private void recreateNonInherentTag(SystemTag tag) { - recreateTag(tag, null, null, false); - } + private void recreateNonInherentTag(SystemTag tag) { + recreateTag(tag, null, null, false); + } + + private void recreateInherentTag(SystemTag tag, String token, String value) { + recreateTag(tag, token, value, true); + } + + private void recreateTag(SystemTag tag, String token, String value, boolean inherent) { + SystemTagCreator creator = tag.newSystemTagCreator(self.getUuid()); + Optional.ofNullable(token).ifPresent(it -> creator.setTagByTokens(Collections.singletonMap(token, value))); + creator.inherent = inherent; + creator.recreate = true; + creator.create(); + } + + @Override + protected void checkConnectConditions(ConnectHostInfo info, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("check-connect-conditions-for-kvm-%s", self.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "test-if-ssh-port-open"; + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + long sshTimeout = TimeUnit.SECONDS.toMillis(KVMGlobalConfig.TEST_SSH_PORT_ON_OPEN_TIMEOUT.value(Long.class)); + long timeout = System.currentTimeMillis() + sshTimeout; + long ctimeout = TimeUnit.SECONDS.toMillis(KVMGlobalConfig.TEST_SSH_PORT_ON_CONNECT_TIMEOUT.value(Integer.class).longValue()); + + thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask(trigger) { + @Override + public boolean run() { + if (testPort()) { + trigger.next(); + return true; + } + + return ifTimeout(); + } + + private boolean testPort() { + if (!NetworkUtils.isRemotePortOpen(getSelf().getManagementIp(), getSelf().getPort(), (int) ctimeout)) { + logger.debug(String.format("host[uuid:%s, name:%s, ip:%s]'s ssh port[%s] is not ready yet", getSelf().getUuid(), getSelf().getName(), getSelf().getManagementIp(), getSelf().getPort())); + return false; + } else { + return true; + } + } + + private boolean ifTimeout() { + if (System.currentTimeMillis() > timeout) { + trigger.fail(operr("the host[%s] ssh port[%s] not open after %s seconds, connect timeout", getSelf().getManagementIp(), getSelf().getPort(), TimeUnit.MILLISECONDS.toSeconds(sshTimeout))); + return true; + } else { + return false; + } + } + + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.SECONDS; + } + + @Override + public long getInterval() { + return 2; + } + + @Override + public String getName() { + return "test-ssh-port-open-for-kvm-host"; + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "check-if-host-password-has-been-modified"; + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON || info.isNewAdded(); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + final ErrorCode errorCode = connectWithSSHPassword(); + if (errorCode == null) { + trigger.next(); + return; + } + + final ErrorCode privateKeyError = connectWithPrivateKey(); + if (privateKeyError == null) { + trigger.fail(err(HostErrors.HOST_PASSWORD_HAS_BEEN_CHANGED, + "host password has been changed. " + + "Please update host password in management node by UpdateKVMHostAction with host UUID[%s]", + self.getUuid())); + return; + } + trigger.fail(errorCode); + } + + ErrorCode connectWithSSHPassword() { + SshShell sshShell = new SshShell(); + sshShell.setHostname(getSelf().getManagementIp()); + sshShell.setUsername(getSelf().getUsername()); + sshShell.setPassword(getSelf().getPassword()); + sshShell.setPort(getSelf().getPort()); + sshShell.setWithSudo(false); + final String cmd = "echo hello"; + SshResult ret = sshShell.runCommand(cmd); + if (ret.isSshFailure()) { + return err(HostErrors.UNABLE_TO_RECONNECT_HOST, + "failed to connect host[UUID=%s] with SSH password", self.getUuid()); + } + return null; + } + + ErrorCode connectWithPrivateKey() { + SshShell sshShell = new SshShell(); + sshShell.setHostname(getSelf().getManagementIp()); + sshShell.setUsername(getSelf().getUsername()); + sshShell.setPrivateKey(asf.getPrivateKey()); + sshShell.setPort(getSelf().getPort()); + sshShell.setWithSudo(false); + final String cmd = "echo hello"; + SshResult ret = sshShell.runCommand(cmd); + if (ret.isSshFailure()) { + return err(HostErrors.UNABLE_TO_RECONNECT_HOST, + "failed to connect host[UUID=%s] with private key", self.getUuid()); + } + return null; + } + }).then(new NoRollbackFlow() { + String __name__ = "ping-DNS-check-list"; + @Override + public boolean skip(Map data) { + if (CoreGlobalProperty.UNIT_TEST_ON) { + return true; + } + if (!info.isNewAdded()) { + return true; + } + if (AnsibleGlobalProperty.ZSTACK_REPO.contains("zstack-mn") || AnsibleGlobalProperty.ZSTACK_REPO.equals("false")) { + return true; + } + return false; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + String checkList; + if (AnsibleGlobalProperty.ZSTACK_REPO.contains(KVMConstant.ALI_REPO)) { + checkList = KVMGlobalConfig.HOST_DNS_CHECK_ALIYUN.value(); + } else if (AnsibleGlobalProperty.ZSTACK_REPO.contains(KVMConstant.NETEASE_REPO)) { + checkList = KVMGlobalConfig.HOST_DNS_CHECK_163.value(); + } else { + checkList = KVMGlobalConfig.HOST_DNS_CHECK_LIST.value(); + } + + checkList = checkList.replaceAll(",", " "); + + SshShell sshShell = new SshShell(); + sshShell.setHostname(getSelf().getManagementIp()); + sshShell.setUsername(getSelf().getUsername()); + sshShell.setPassword(getSelf().getPassword()); + sshShell.setPort(getSelf().getPort()); + SshResult ret = sshShell.runScriptWithToken("scripts/check-public-dns-name.sh", + map(e("dnsCheckList", checkList))); + + if (ret.isSshFailure()) { + trigger.fail(operr("unable to connect to KVM[ip:%s, username:%s, sshPort: %d, ] to do DNS check, please check if username/password is wrong; %s", self.getManagementIp(), getSelf().getUsername(), getSelf().getPort(), ret.getExitErrorMessage())); + } else if (ret.getReturnCode() != 0) { + trigger.fail(operr("failed to ping all DNS/IP in %s; please check /etc/resolv.conf to make sure your host is able to reach public internet", checkList)); + } else { + trigger.next(); + } + } + }).then(new NoRollbackFlow() { + String __name__ = "check-if-host-can-reach-management-node"; + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + ShellUtils.run(String.format("arp -d %s || true", getSelf().getManagementIp())); + SshShell sshShell = new SshShell(); + sshShell.setHostname(getSelf().getManagementIp()); + sshShell.setUsername(getSelf().getUsername()); + sshShell.setPassword(getSelf().getPassword()); + sshShell.setPort(getSelf().getPort()); + sshShell.setWithSudo(false); + final String cmd = String.format("curl --connect-timeout 10 %s|| wget --spider -q --connect-timeout=10 %s|| test $? -eq 8", restf.getCallbackUrl(), restf.getCallbackUrl()); + SshResult ret = sshShell.runCommand(cmd); + if (ret.getStderr() != null && ret.getStderr().contains("No route to host")) { + // c.f. https://access.redhat.com/solutions/1120533 + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e.getMessage()); + } + ret = sshShell.runCommand(cmd); + } - private void recreateInherentTag(SystemTag tag, String token, String value) { - recreateTag(tag, token, value, true); - } + if (ret.isSshFailure()) { + throw new OperationFailureException(operr("unable to connect to KVM[ip:%s, username:%s, sshPort:%d] to check the management node connectivity," + + "please check if username/password is wrong; %s", self.getManagementIp(), getSelf().getUsername(), getSelf().getPort(), ret.getExitErrorMessage())); + } else if (ret.getReturnCode() != 0) { + throw new OperationFailureException(operr("the KVM host[ip:%s] cannot access the management node's callback url. It seems" + + " that the KVM host cannot reach the management IP[%s]. %s %s", restf.getHostName(), self.getManagementIp(), + ret.getStderr(), ret.getExitErrorMessage())); + } - private void recreateTag(SystemTag tag, String token, String value, boolean inherent) { - SystemTagCreator creator = tag.newSystemTagCreator(self.getUuid()); - Optional.ofNullable(token).ifPresent(it -> creator.setTagByTokens(Collections.singletonMap(token, value))); - creator.inherent = inherent; - creator.recreate = true; - creator.create(); + trigger.next(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).start(); } @Override @@ -3596,685 +5516,684 @@ public void connectHook(final ConnectHostInfo info, final Completion complete) { info.setSkipPackages(skipPackages); } - if (CoreGlobalProperty.UNIT_TEST_ON) { - if (info.isNewAdded()) { - createHostVersionSystemTags("zstack", "kvmSimulator", tester.get(ZTester.KVM_HostVersion, "0.1", String.class)); - if (null == KVMSystemTags.LIBVIRT_VERSION.getTokenByResourceUuid(self.getUuid(), KVMSystemTags.LIBVIRT_VERSION_TOKEN)) { - createTagWithoutNonValue(KVMSystemTags.LIBVIRT_VERSION, KVMSystemTags.LIBVIRT_VERSION_TOKEN, tester.get(ZTester.KVM_LibvirtVersion, "1.2.9", String.class), true); - } - if (null == KVMSystemTags.QEMU_IMG_VERSION.getTokenByResourceUuid(self.getUuid(), KVMSystemTags.QEMU_IMG_VERSION_TOKEN)) { - createTagWithoutNonValue(KVMSystemTags.QEMU_IMG_VERSION, KVMSystemTags.QEMU_IMG_VERSION_TOKEN, tester.get(ZTester.KVM_QemuImageVersion, "2.0.0", String.class), true); - } - if (null == KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(self.getUuid(), KVMSystemTags.CPU_MODEL_NAME_TOKEN)) { - createTagWithoutNonValue(KVMSystemTags.CPU_MODEL_NAME, KVMSystemTags.CPU_MODEL_NAME_TOKEN, tester.get(ZTester.KVM_CpuModelName, "Broadwell", String.class), true); - } - if (null == KVMSystemTags.EPT_CPU_FLAG.getTokenByResourceUuid(self.getUuid(), KVMSystemTags.EPT_CPU_FLAG_TOKEN)) { - createTagWithoutNonValue(KVMSystemTags.EPT_CPU_FLAG, KVMSystemTags.EPT_CPU_FLAG_TOKEN, "ept", false); - } - if (null == KVMSystemTags.LIBVIRT_CAPABILITIES.getTokenByResourceUuid(self.getUuid(), KVMSystemTags.LIBVIRT_CAPABILITIES_TOKEN)) { - createTagWithoutNonValue(KVMSystemTags.LIBVIRT_CAPABILITIES, KVMSystemTags.LIBVIRT_CAPABILITIES_TOKEN, "incrementaldrivemirror,blockcopynetworktarget", true); - } + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("run-ansible-for-kvm-%s", self.getUuid())); + chain.allowWatch(); + chain.then(new ShareFlow() { + boolean deployed = false; + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "check-host-is-taken-over"; - if (null == self.getArchitecture()) { - ClusterVO cluster = dbf.findByUuid(self.getClusterUuid(), ClusterVO.class); - HostVO host = dbf.findByUuid(self.getUuid(), HostVO.class); - if (null == cluster.getArchitecture()){ - host.setArchitecture(CpuArchitecture.x86_64.toString()); - } else { - host.setArchitecture(cluster.getArchitecture()); + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON || !info.isNewAdded(); } - dbf.update(host); - } - if (!checkQemuLibvirtVersionOfHost()) { - complete.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match", - self.getUuid(), self.getClusterUuid())); - return; - } + @Override + public void run(FlowTrigger trigger, Map data) { + try { + Ssh ssh = new Ssh().setUsername(getSelf().getUsername()) + .setPassword(getSelf().getPassword()).setPort(getSelf().getPort()) + .setHostname(getSelf().getManagementIp()); + ssh.command(String.format("grep -i ^uuid %s | sed 's/uuid://g'", hostTakeOverFlagPath)); + SshResult hostRet = ssh.run(); + if (hostRet.isSshFailure() || hostRet.getReturnCode() != 0) { + trigger.fail(operr("unable to Check whether the host is taken over, because %s", hostRet.getExitErrorMessage())); + return; + } + String hostOutput = hostRet.getStdout().replaceAll("\r|\n",""); + logger.debug(String.format("Uuid in the host take over flag file is %s ", hostOutput)); + if (hostOutput.contains("No such file or directory")) { + trigger.next(); + return; + } - if (KVMSystemTags.CHECK_CLUSTER_CPU_MODEL.hasTag(self.getClusterUuid())) { - if (KVMSystemTags.CHECK_CLUSTER_CPU_MODEL - .getTokenByResourceUuid(self.getClusterUuid(), KVMSystemTags.CHECK_CLUSTER_CPU_MODEL_TOKEN) - .equals("true") - && !checkCpuModelOfHost()) { - complete.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", - self.getUuid(), self.getClusterUuid())); - return; - } + ssh.command(String.format("date +%%s -r %s", hostTakeOverFlagPath)); + SshResult timeRet = ssh.run(); + logger.debug(String.format("Timestamp of the flag is %s ", timeRet.getStdout())); + if (timeRet.isSshFailure() || timeRet.getReturnCode() != 0) { + trigger.fail(operr("Unable to get the timestamp of the flag, because %s", timeRet.getExitErrorMessage())); + return; + } + String timestampOutput = timeRet.getStdout().replaceAll("\r|\n",""); + long currentTimeSeconds = new Date().getTime() / 1000; + long timestampSeconds = Long.parseLong(timestampOutput); - complete.success(); - return; - } + if (currentTimeSeconds < timestampSeconds) { + logger.warn(String.format("Current time is earlier than the timestamp. Possible clock synchronization issue. Current: %d, Timestamp: %d", currentTimeSeconds, timestampSeconds)); + } + long diff = Math.abs(currentTimeSeconds - timestampSeconds); + logger.debug(String.format("hostOutput is %s ,The time difference is %d(s) ", hostOutput, diff)); - if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && !checkCpuModelOfHost()) { - complete.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", - self.getUuid(), self.getClusterUuid())); - return; - } - } + if (diff < HostGlobalConfig.PING_HOST_INTERVAL.value(int.class)) { + trigger.fail(operr("the host[ip:%s] has been taken over, because the takeover flag[HostUuid:%s] already exists and utime[%d] has not exceeded host ping interval[%d]", + self.getManagementIp(), hostOutput, diff, HostGlobalConfig.PING_HOST_INTERVAL.value(int.class))); + return; + } - continueConnect(info, complete); - } else { - FlowChain chain = FlowChainBuilder.newShareFlowChain(); - chain.setName(String.format("run-ansible-for-kvm-%s", self.getUuid())); - chain.allowWatch(); - chain.then(new ShareFlow() { - boolean deployed = false; - @Override - public void setup() { + HostVO lastHostInv = Q.New(HostVO.class).eq(HostVO_.uuid, hostOutput).find(); + if (lastHostInv == null) { + trigger.next(); + } else { + trigger.fail(operr("the host[ip:%s] has been taken over, because flag[HostUuid:%s] exists in the database", + self.getManagementIp(), lastHostInv.getUuid())); + } + } catch (Exception e) { + logger.warn(e.getMessage(), e); + trigger.next(); + return; + } + } + }); - flow(new NoRollbackFlow() { - String __name__ = "test-if-ssh-port-open"; + flow(new NoRollbackFlow() { + String __name__ = "check-host-cpu-arch"; + + private Object getHostCpuArchitectureBySsh() { + SshShell sshShell = new SshShell(); + sshShell.setHostname(getSelf().getManagementIp()); + sshShell.setUsername(getSelf().getUsername()); + sshShell.setPassword(getSelf().getPassword()); + sshShell.setPort(getSelf().getPort()); + SshResult ret = sshShell.runCommand("uname -m"); + + if (ret.isSshFailure() || ret.getReturnCode() != 0) { + return operr("unable to get host cpu architecture, please check if username/password is wrong; %s", ret.getExitErrorMessage()); + } + return ret.getStdout().trim(); + } - @Override - public void run(FlowTrigger trigger, Map data) { - long sshTimeout = TimeUnit.SECONDS.toMillis(KVMGlobalConfig.TEST_SSH_PORT_ON_OPEN_TIMEOUT.value(Long.class)); - long timeout = System.currentTimeMillis() + sshTimeout; - long ctimeout = TimeUnit.SECONDS.toMillis(KVMGlobalConfig.TEST_SSH_PORT_ON_CONNECT_TIMEOUT.value(Integer.class).longValue()); + @Override + public void run(FlowTrigger trigger, Map data) { + ClusterVO cluster = dbf.findByUuid(self.getClusterUuid(), ClusterVO.class); + String hostArchitecture; - thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask(trigger) { - @Override - public boolean run() { - if (testPort()) { - trigger.next(); - return true; - } + if (CoreGlobalProperty.UNIT_TEST_ON) { + hostArchitecture = cluster.getArchitecture() == null ? + CpuArchitecture.x86_64.name() : cluster.getArchitecture(); + } else { + final Object ret = getHostCpuArchitectureBySsh(); + if (ret instanceof ErrorCode) { + trigger.fail((ErrorCode) ret); + return; + } + hostArchitecture = ret.toString(); + } - return ifTimeout(); - } + HostVO host = dbf.findByUuid(getSelf().getUuid(), HostVO.class); + host.setArchitecture(hostArchitecture); + dbf.update(host); + self.setArchitecture(hostArchitecture); + if (cluster.getArchitecture() != null && !hostArchitecture.equals(cluster.getArchitecture()) && !cluster.getHypervisorType().equals("baremetal2")) { + trigger.fail(operr("host cpu architecture[%s] is not matched the cluster[%s]", hostArchitecture, cluster.getArchitecture())); + return; + } - private boolean testPort() { - if (!NetworkUtils.isRemotePortOpen(getSelf().getManagementIp(), getSelf().getPort(), (int) ctimeout)) { - logger.debug(String.format("host[uuid:%s, name:%s, ip:%s]'s ssh port[%s] is not ready yet", getSelf().getUuid(), getSelf().getName(), getSelf().getManagementIp(), getSelf().getPort())); - return false; - } else { - return true; - } - } + // for upgrade case, prevent from add host failure. + if (cluster.getArchitecture() == null && !info.isNewAdded()) { + cluster.setArchitecture(hostArchitecture); + dbf.update(cluster); + ClusterInventory clusterInventory = ClusterInventory.valueOf(cluster); + crci.initClusterResourceConfigValue(clusterInventory); + } - private boolean ifTimeout() { - if (System.currentTimeMillis() > timeout) { - trigger.fail(operr("the host[%s] ssh port[%s] not open after %s seconds, connect timeout", getSelf().getManagementIp(), getSelf().getPort(), TimeUnit.MILLISECONDS.toSeconds(sshTimeout))); - return true; - } else { - return false; - } - } + trigger.next(); + } + }); - @Override - public TimeUnit getTimeUnit() { - return TimeUnit.SECONDS; - } + flow(new NoRollbackFlow() { + String __name__ = "apply-ansible-playbook"; - @Override - public long getInterval() { - return 2; - } + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } - @Override - public String getName() { - return "test-ssh-port-open-for-kvm-host"; - } - }); + @Override + public void run(final FlowTrigger trigger, Map data) { + String srcPath = PathUtil.findFileOnClassPath(String.format("ansible/kvm/%s", agentPackageName), true).getAbsolutePath(); + String destPath = String.format("/var/lib/zstack/kvm/package/%s", agentPackageName); + SshFileMd5Checker checker = new SshFileMd5Checker(); + checker.setUsername(getSelf().getUsername()); + checker.setPassword(getSelf().getPassword()); + checker.setSshPort(getSelf().getPort()); + checker.setTargetIp(getSelf().getManagementIp()); + checker.addSrcDestPair(SshFileMd5Checker.ZSTACKLIB_SRC_PATH, String.format("/var/lib/zstack/kvm/package/%s", AnsibleGlobalProperty.ZSTACKLIB_PACKAGE_NAME)); + checker.addSrcDestPair(srcPath, destPath); + + SshFileExistChecker dhcpChecker = new SshFileExistChecker(); + dhcpChecker.setUsername(getSelf().getUsername()); + dhcpChecker.setPassword(getSelf().getPassword()); + dhcpChecker.setSshPort(getSelf().getPort()); + dhcpChecker.setTargetIp(getSelf().getManagementIp()); + dhcpChecker.setFilePath(KVMConstant.DHCP_BIN_FILE_PATH); + + SshChronyConfigChecker chronyChecker = new SshChronyConfigChecker(); + chronyChecker.setTargetIp(getSelf().getManagementIp()); + chronyChecker.setUsername(getSelf().getUsername()); + chronyChecker.setPassword(getSelf().getPassword()); + chronyChecker.setSshPort(getSelf().getPort()); + + SshYumRepoChecker repoChecker = new SshYumRepoChecker(); + repoChecker.setTargetIp(getSelf().getManagementIp()); + repoChecker.setUsername(getSelf().getUsername()); + repoChecker.setPassword(getSelf().getPassword()); + repoChecker.setSshPort(getSelf().getPort()); + + CallBackNetworkChecker callbackChecker = new CallBackNetworkChecker(); + callbackChecker.setTargetIp(getSelf().getManagementIp()); + callbackChecker.setUsername(getSelf().getUsername()); + callbackChecker.setPassword(getSelf().getPassword()); + callbackChecker.setPort(getSelf().getPort()); + callbackChecker.setCallbackIp(Platform.getManagementServerIp()); + callbackChecker.setCallBackPort(CloudBusGlobalProperty.HTTP_PORT); + + KvmHostConfigChecker kvmHostConfigChecker = new KvmHostConfigChecker(); + kvmHostConfigChecker.setTargetIp(getSelf().getManagementIp()); + kvmHostConfigChecker.setUsername(getSelf().getUsername()); + kvmHostConfigChecker.setPassword(getSelf().getPassword()); + kvmHostConfigChecker.setSshPort(getSelf().getPort()); + kvmHostConfigChecker.setPrivateKey(asf.getPrivateKey()); + + AnsibleRunner runner = new AnsibleRunner(); + runner.installChecker(checker); + runner.installChecker(dhcpChecker); + runner.installChecker(chronyChecker); + runner.installChecker(repoChecker); + runner.installChecker(callbackChecker); + runner.installChecker(kvmHostConfigChecker); + + if (KVMGlobalConfig.ENABLE_HOST_TCP_CONNECTION_CHECK.value(Boolean.class)) { + CallBackNetworkChecker hostTcpConnectionCallbackChecker = new CallBackNetworkChecker(); + hostTcpConnectionCallbackChecker.setTargetIp(getSelf().getManagementIp()); + hostTcpConnectionCallbackChecker.setUsername(getSelf().getUsername()); + hostTcpConnectionCallbackChecker.setPassword(getSelf().getPassword()); + hostTcpConnectionCallbackChecker.setPort(getSelf().getPort()); + hostTcpConnectionCallbackChecker.setCallbackIp(Platform.getManagementServerIp()); + hostTcpConnectionCallbackChecker.setCallBackPort(KVMGlobalProperty.TCP_SERVER_PORT); + runner.installChecker(hostTcpConnectionCallbackChecker); } - }); - - if (info.isNewAdded()) { - - if ((!AnsibleGlobalProperty.ZSTACK_REPO.contains("zstack-mn")) && (!AnsibleGlobalProperty.ZSTACK_REPO.equals("false"))) { - flow(new NoRollbackFlow() { - String __name__ = "ping-DNS-check-list"; - @Override - public void run(FlowTrigger trigger, Map data) { - String checkList; - if (AnsibleGlobalProperty.ZSTACK_REPO.contains(KVMConstant.ALI_REPO)) { - checkList = KVMGlobalConfig.HOST_DNS_CHECK_ALIYUN.value(); - } else if (AnsibleGlobalProperty.ZSTACK_REPO.contains(KVMConstant.NETEASE_REPO)) { - checkList = KVMGlobalConfig.HOST_DNS_CHECK_163.value(); - } else { - checkList = KVMGlobalConfig.HOST_DNS_CHECK_LIST.value(); - } - - checkList = checkList.replaceAll(",", " "); - - SshShell sshShell = new SshShell(); - sshShell.setHostname(getSelf().getManagementIp()); - sshShell.setUsername(getSelf().getUsername()); - sshShell.setPassword(getSelf().getPassword()); - sshShell.setPort(getSelf().getPort()); - SshResult ret = sshShell.runScriptWithToken("scripts/check-public-dns-name.sh", - map(e("dnsCheckList", checkList))); - - if (ret.isSshFailure()) { - trigger.fail(operr("unable to connect to KVM[ip:%s, username:%s, sshPort: %d, ] to do DNS check, please check if username/password is wrong; %s", self.getManagementIp(), getSelf().getUsername(), getSelf().getPort(), ret.getExitErrorMessage())); - } else if (ret.getReturnCode() != 0) { - trigger.fail(operr("failed to ping all DNS/IP in %s; please check /etc/resolv.conf to make sure your host is able to reach public internet", checkList)); - } else { - trigger.next(); - } - } - }); + for (KVMHostAddSshFileMd5CheckerExtensionPoint exp : pluginRgty.getExtensionList(KVMHostAddSshFileMd5CheckerExtensionPoint.class)) { + SshFileMd5Checker sshFileMd5Checker = exp.getSshFileMd5Checker(getSelf()); + if (sshFileMd5Checker != null) { + runner.installChecker(sshFileMd5Checker); + } + } + runner.setAgentPort(KVMGlobalProperty.AGENT_PORT); + runner.setTargetIp(getSelf().getManagementIp()); + runner.setTargetUuid(getSelf().getUuid()); + runner.setPlayBookName(KVMConstant.ANSIBLE_PLAYBOOK_NAME); + runner.setUsername(getSelf().getUsername()); + runner.setPassword(getSelf().getPassword()); + runner.setSshPort(getSelf().getPort()); + + KVMHostDeployArguments deployArguments = new KVMHostDeployArguments(); + if (info.isNewAdded()) { + deployArguments.setInit("true"); + runner.setFullDeploy(true); + } + if (NetworkGlobalProperty.SKIP_IPV6 || NetworkGlobalProperty.BRIDGE_DISABLE_IP6TABLES) { + deployArguments.setDisableIp6Tables("true"); } - } - flow(new NoRollbackFlow() { - String __name__ = "check-if-host-can-reach-management-node"; + for (KvmHostAgentDeploymentExtensionPoint ext : pluginRegistry.getExtensionList(KvmHostAgentDeploymentExtensionPoint.class)) { + if (logger.isTraceEnabled()) { + logger.trace(String.format("Arguments before KvmHostAgentDeploymentExtensionPoint: %s", JSONObjectUtil.toJsonString(deployArguments))); + } - @Override - public void run(FlowTrigger trigger, Map data) { - ShellUtils.run(String.format("arp -d %s || true", getSelf().getManagementIp())); - SshShell sshShell = new SshShell(); - sshShell.setHostname(getSelf().getManagementIp()); - sshShell.setUsername(getSelf().getUsername()); - sshShell.setPassword(getSelf().getPassword()); - sshShell.setPort(getSelf().getPort()); - sshShell.setWithSudo(false); - final String cmd = String.format("curl --connect-timeout 10 %s|| wget --spider -q --connect-timeout=10 %s|| test $? -eq 8", restf.getCallbackUrl(), restf.getCallbackUrl()); - SshResult ret = sshShell.runCommand(cmd); - if (ret.getStderr() != null && ret.getStderr().contains("No route to host")) { - // c.f. https://access.redhat.com/solutions/1120533 - try { - TimeUnit.SECONDS.sleep(3); - } catch (InterruptedException e) { - throw new RuntimeException(e.getMessage()); - } - ret = sshShell.runCommand(cmd); + List extraPackagesFromExt = ext.appendExtraPackages(getSelfInventory()); + if (extraPackagesFromExt != null && !extraPackagesFromExt.isEmpty()) { + if (deployArguments.getExtraPackages() != null) + deployArguments.setExtraPackages(deployArguments.getExtraPackages() + " " + String.join(" ", extraPackagesFromExt)); + else + deployArguments.setExtraPackages(String.join(" ", extraPackagesFromExt)); } - if (ret.isSshFailure()) { - throw new OperationFailureException(operr("unable to connect to KVM[ip:%s, username:%s, sshPort:%d] to check the management node connectivity," + - "please check if username/password is wrong; %s", self.getManagementIp(), getSelf().getUsername(), getSelf().getPort(), ret.getExitErrorMessage())); - } else if (ret.getReturnCode() != 0) { - throw new OperationFailureException(operr("the KVM host[ip:%s] cannot access the management node's callback url. It seems" + - " that the KVM host cannot reach the management IP[%s]. %s %s", self.getManagementIp(), restf.getHostName(), - ret.getStderr(), ret.getExitErrorMessage())); + ext.modifyDeploymentArguments(getSelfInventory(), deployArguments); + + if (logger.isTraceEnabled()) { + logger.trace(String.format("Arguments after KvmHostAgentDeploymentExtensionPoint: %s", JSONObjectUtil.toJsonString(deployArguments))); } + } - trigger.next(); + if ("baremetal2".equals(self.getHypervisorType())) { + deployArguments.setIsBareMetal2Gateway("true"); } - }); - flow(new NoRollbackFlow() { - String __name__ = "check-Host-is-taken-over"; + String enableKsm = rcf.getResourceConfigValue(KVMGlobalConfig.HOST_KSM, self.getUuid(), String.class); + kvmHostConfigChecker.setRequireKsmCheck(enableKsm); + kvmHostConfigChecker.setRequireReservePorts("49152-49215"); + deployArguments.setIsEnableKsm(enableKsm); - @Override - public void run(FlowTrigger trigger, Map data) { - if (!info.isNewAdded() || CoreGlobalProperty.UNIT_TEST_ON) { - trigger.next(); - return; - } - try { - Ssh ssh = new Ssh().setUsername(getSelf().getUsername()) - .setPassword(getSelf().getPassword()).setPort(getSelf().getPort()) - .setHostname(getSelf().getManagementIp()); - ssh.command(String.format("grep -i ^uuid %s | sed 's/uuid://g'", hostTakeOverFlagPath)); - SshResult hostRet = ssh.run(); - if (hostRet.isSshFailure() || hostRet.getReturnCode() != 0) { - trigger.fail(operr("unable to Check whether the host is taken over, because %s", hostRet.getExitErrorMessage())); - return; - } - String hostOutput = hostRet.getStdout().replaceAll("\r|\n",""); - logger.debug(String.format("Uuid in the host take over flag file is %s ", hostOutput)); - if (hostOutput.contains("No such file or directory")) { - trigger.next(); - return; - } + if (NetworkGlobalProperty.BRIDGE_DISABLE_IPTABLES) { + deployArguments.setBridgeDisableIptables("true"); + } - ssh.command(String.format("date +%%s -r %s", hostTakeOverFlagPath)); - SshResult timeRet = ssh.run(); - logger.debug(String.format("Timestamp of the flag is %s ", timeRet.getStdout())); - if (timeRet.isSshFailure() || timeRet.getReturnCode() != 0) { - trigger.fail(operr("Unable to get the timestamp of the flag, because %s", timeRet.getExitErrorMessage())); - return; - } - String timestampOutput = timeRet.getStdout().replaceAll("\r|\n",""); + deployArguments.setRestartLibvirtd(rcf.getResourceConfigValue(KVMGlobalConfig.RECONNECT_HOST_RESTART_LIBVIRTD_SERVICE, self.getUuid(), String.class)); + deployArguments.setHostname(String.format("%s.zstack.org", self.getManagementIp().replaceAll("\\.", "-"))); + deployArguments.setSkipPackages(info.getSkipPackages()); + deployArguments.setUpdatePackages(String.valueOf(CoreGlobalProperty.UPDATE_PKG_WHEN_CONNECT)); - long diff = (new Date().getTime() / 1000) - Long.parseLong(timestampOutput); - logger.debug(String.format("hostOutput is %s ,The time difference is %d(s) ", hostOutput, diff)); + if (deployArguments.isForceRun()) { + runner.setForceRun(true); + } - if (diff < HostGlobalConfig.PING_HOST_INTERVAL.value(int.class)) { - trigger.fail(operr("the host[ip:%s] has been taken over, because the takeover flag[HostUuid:%s] already exists and utime[%d] has not exceeded host ping interval[%d]", - self.getManagementIp(), hostOutput, diff, HostGlobalConfig.PING_HOST_INTERVAL.value(int.class))); - return; - } + UriComponentsBuilder ub = UriComponentsBuilder.fromHttpUrl(restf.getBaseUrl()); + ub.path(new StringBind(KVMConstant.KVM_ANSIBLE_LOG_PATH_FROMAT).bind("uuid", self.getUuid()).toString()); + String postUrl = ub.build().toString(); - HostVO lastHostInv = Q.New(HostVO.class).eq(HostVO_.uuid, hostOutput).find(); - if (lastHostInv == null) { - trigger.next(); - } else { - trigger.fail(operr("the host[ip:%s] has been taken over, because flag[HostUuid:%s] exists in the database", - self.getManagementIp(), lastHostInv.getUuid())); + deployArguments.setPostUrl(postUrl); + runner.setDeployArguments(deployArguments); + runner.run(new ReturnValueCompletion(trigger) { + @Override + public void success(Boolean run) { + if (run != null) { + deployed = run; + } + if (deployed) { + // update host agent version when open grayScaleUpgrade + upgradeChecker.updateAgentVersion(self.getUuid(), AnsibleConstant.KVM_AGENT_NAME, dbf.getDbVersion(), dbf.getDbVersion()); } - } catch (Exception e) { - logger.warn(e.getMessage(), e); trigger.next(); - return; } - } - }); - flow(new NoRollbackFlow() { - String __name__ = "check-host-cpu-arch"; - - @Override - public void run(FlowTrigger trigger, Map data) { - SshShell sshShell = new SshShell(); - sshShell.setHostname(getSelf().getManagementIp()); - sshShell.setUsername(getSelf().getUsername()); - sshShell.setPassword(getSelf().getPassword()); - sshShell.setPort(getSelf().getPort()); - SshResult ret = sshShell.runCommand("uname -m"); - - if (ret.isSshFailure() || ret.getReturnCode() != 0) { - trigger.fail(operr("unable to get host cpu architecture, please check if username/password is wrong; %s", ret.getExitErrorMessage())); - return; + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); } + }); + } + }); - String hostArchitecture = ret.getStdout().trim(); - HostVO host = dbf.findByUuid(getSelf().getUuid(), HostVO.class); - host.setArchitecture(hostArchitecture); - dbf.update(host); - self.setArchitecture(hostArchitecture); - ClusterVO cluster = dbf.findByUuid(self.getClusterUuid(), ClusterVO.class); - if (cluster.getArchitecture() != null && !hostArchitecture.equals(cluster.getArchitecture()) && !cluster.getHypervisorType().equals("baremetal2")) { - trigger.fail(operr("host cpu architecture[%s] is not matched the cluster[%s]", hostArchitecture, cluster.getArchitecture())); - return; - } + flow(new NoRollbackFlow() { + String __name__ = "configure-iptables"; - // for upgrade case, prevent from add host failure. - if (cluster.getArchitecture() == null && !info.isNewAdded()) { - cluster.setArchitecture(hostArchitecture); - dbf.update(cluster); - } + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } - trigger.next(); + @Override + public void run(FlowTrigger trigger, Map data) { + String allowPorts = KVMGlobalConfig.KVMAGENT_ALLOW_PORTS_LIST.value(String.class) + ',' + HostGlobalConfig.NBD_PORT_RANGE.value(String.class); + StringBuilder builder = new StringBuilder(); + if (!KVMGlobalProperty.MN_NETWORKS.isEmpty()) { + builder.append(String.format("bash %s -m %s -p %s -s %s -c %s", + "/var/lib/zstack/kvm/kvmagent-iptables", + KVMConstant.IPTABLES_COMMENTS, + allowPorts, + KVMGlobalProperty.AGENT_PORT, + String.join(",", KVMGlobalProperty.MN_NETWORKS))); + } else { + builder.append(String.format("bash %s -m %s -p %s -s %s", + "/var/lib/zstack/kvm/kvmagent-iptables", + KVMConstant.IPTABLES_COMMENTS, + allowPorts, + KVMGlobalProperty.AGENT_PORT)); } - }); - flow(new NoRollbackFlow() { - String __name__ = "apply-ansible-playbook"; + try { + new Ssh() + .setUsername(getSelf().getUsername()) + .setPassword(getSelf().getPassword()) + .setHostname(getSelf().getManagementIp()) + .setPort(getSelf().getPort()) + .sudoCommand(builder.toString()) + .runErrorByExceptionAndClose(); + } catch (SshException ex) { + throw new OperationFailureException(operr(ex.toString())); + } - @Override - public void run(final FlowTrigger trigger, Map data) { - String srcPath = PathUtil.findFileOnClassPath(String.format("ansible/kvm/%s", agentPackageName), true).getAbsolutePath(); - String destPath = String.format("/var/lib/zstack/kvm/package/%s", agentPackageName); - SshFileMd5Checker checker = new SshFileMd5Checker(); - checker.setUsername(getSelf().getUsername()); - checker.setPassword(getSelf().getPassword()); - checker.setSshPort(getSelf().getPort()); - checker.setTargetIp(getSelf().getManagementIp()); - checker.addSrcDestPair(SshFileMd5Checker.ZSTACKLIB_SRC_PATH, String.format("/var/lib/zstack/kvm/package/%s", AnsibleGlobalProperty.ZSTACKLIB_PACKAGE_NAME)); - checker.addSrcDestPair(srcPath, destPath); - - SshChronyConfigChecker chronyChecker = new SshChronyConfigChecker(); - chronyChecker.setTargetIp(getSelf().getManagementIp()); - chronyChecker.setUsername(getSelf().getUsername()); - chronyChecker.setPassword(getSelf().getPassword()); - chronyChecker.setSshPort(getSelf().getPort()); - - SshYumRepoChecker repoChecker = new SshYumRepoChecker(); - repoChecker.setTargetIp(getSelf().getManagementIp()); - repoChecker.setUsername(getSelf().getUsername()); - repoChecker.setPassword(getSelf().getPassword()); - repoChecker.setSshPort(getSelf().getPort()); - - CallBackNetworkChecker callbackChecker = new CallBackNetworkChecker(); - callbackChecker.setTargetIp(getSelf().getManagementIp()); - callbackChecker.setUsername(getSelf().getUsername()); - callbackChecker.setPassword(getSelf().getPassword()); - callbackChecker.setPort(getSelf().getPort()); - callbackChecker.setCallbackIp(Platform.getManagementServerIp()); - callbackChecker.setCallBackPort(CloudBusGlobalProperty.HTTP_PORT); - - AnsibleRunner runner = new AnsibleRunner(); - runner.installChecker(checker); - runner.installChecker(chronyChecker); - runner.installChecker(repoChecker); - runner.installChecker(callbackChecker); - - if (KVMGlobalConfig.ENABLE_HOST_TCP_CONNECTION_CHECK.value(Boolean.class)) { - CallBackNetworkChecker hostTcpConnectionCallbackChecker = new CallBackNetworkChecker(); - hostTcpConnectionCallbackChecker.setTargetIp(getSelf().getManagementIp()); - hostTcpConnectionCallbackChecker.setUsername(getSelf().getUsername()); - hostTcpConnectionCallbackChecker.setPassword(getSelf().getPassword()); - hostTcpConnectionCallbackChecker.setPort(getSelf().getPort()); - hostTcpConnectionCallbackChecker.setCallbackIp(Platform.getManagementServerIp()); - hostTcpConnectionCallbackChecker.setCallBackPort(KVMGlobalProperty.TCP_SERVER_PORT); - runner.installChecker(hostTcpConnectionCallbackChecker); - } + trigger.next(); + } + }); - for (KVMHostAddSshFileMd5CheckerExtensionPoint exp : pluginRgty.getExtensionList(KVMHostAddSshFileMd5CheckerExtensionPoint.class)) { - SshFileMd5Checker sshFileMd5Checker = exp.getSshFileMd5Checker(getSelf()); - if (sshFileMd5Checker != null) { - runner.installChecker(sshFileMd5Checker); - } - } - runner.setAgentPort(KVMGlobalProperty.AGENT_PORT); - runner.setTargetIp(getSelf().getManagementIp()); - runner.setTargetUuid(getSelf().getUuid()); - runner.setPlayBookName(KVMConstant.ANSIBLE_PLAYBOOK_NAME); - runner.setUsername(getSelf().getUsername()); - runner.setPassword(getSelf().getPassword()); - runner.setSshPort(getSelf().getPort()); - if (info.isNewAdded()) { - runner.putArgument("init", "true"); - runner.setFullDeploy(true); - } - if (NetworkGlobalProperty.SKIP_IPV6) { - runner.putArgument("skipIpv6", "true"); - } - for (CheckMiniExtensionPoint ext : pluginRegistry.getExtensionList(CheckMiniExtensionPoint.class)) { - if (ext.isMini()) { - runner.putArgument("isMini", "true"); - } - } - if ("baremetal2".equals(self.getHypervisorType())) { - runner.putArgument("isBareMetal2Gateway", "true"); - } - if (NetworkGlobalProperty.BRIDGE_DISABLE_IPTABLES) { - runner.putArgument("bridgeDisableIptables", "true"); - } - runner.putArgument("pkg_kvmagent", agentPackageName); - runner.putArgument("hostname", String.format("%s.zstack.org", self.getManagementIp().replaceAll("\\.", "-"))); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - trigger.fail(operr("chrony server not configured!")); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } - runner.putArgument("skip_packages", info.getSkipPackages()); - runner.putArgument("update_packages", String.valueOf(CoreGlobalProperty.UPDATE_PKG_WHEN_CONNECT)); + flow(new NoRollbackFlow() { + String __name__ = "echo-host"; - UriComponentsBuilder ub = UriComponentsBuilder.fromHttpUrl(restf.getBaseUrl()); - ub.path(new StringBind(KVMConstant.KVM_ANSIBLE_LOG_PATH_FROMAT).bind("uuid", self.getUuid()).toString()); - String postUrl = ub.build().toString(); + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } - runner.putArgument("post_url", postUrl); - runner.run(new ReturnValueCompletion(trigger) { - @Override - public void success(Boolean run) { - if (run != null) { - deployed = run; - } - trigger.next(); - } + @Override + public void run(final FlowTrigger trigger, Map data) { + restf.echo(echoPath, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } - @Override - public void fail(ErrorCode errorCode) { + @Override + public void fail(ErrorCode errorCode) { + boolean needRestart = KVMGlobalConfig.RESTART_AGENT_IF_FAKE_DEAD.value(Boolean.class); + if (!deployed && needRestart) { + // if not deployed and echo failed, we thought it is fake dead, see: ZSTACK-18628 + AnsibleRunner runner = new AnsibleRunner(); + runner.setAgentPort(KVMGlobalProperty.AGENT_PORT); + runner.setTargetIp(getSelf().getManagementIp()); + runner.setTargetUuid(getSelf().getUuid()); + runner.setUsername(getSelf().getUsername()); + runner.setPassword(getSelf().getPassword()); + runner.setSshPort(getSelf().getPort()); + runner.restartAgent(AnsibleConstant.KVM_AGENT_NAME, new Completion(trigger) { + @Override + public void success() { + restf.echo(echoPath, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } else { trigger.fail(errorCode); } - }); - } - }); - - flow(new NoRollbackFlow() { - String __name__ = "configure-iptables"; - - @Override - public void run(FlowTrigger trigger, Map data) { - StringBuilder builder = new StringBuilder(); - if (!KVMGlobalProperty.MN_NETWORKS.isEmpty()) { - builder.append(String.format("sudo bash %s -m %s -p %s -c %s", - "/var/lib/zstack/kvm/kvmagent-iptables", - KVMConstant.IPTABLES_COMMENTS, - KVMGlobalConfig.KVMAGENT_ALLOW_PORTS_LIST.value(String.class), - String.join(",", KVMGlobalProperty.MN_NETWORKS))); - } else { - builder.append(String.format("sudo bash %s -m %s -p %s", - "/var/lib/zstack/kvm/kvmagent-iptables", - KVMConstant.IPTABLES_COMMENTS, - KVMGlobalConfig.KVMAGENT_ALLOW_PORTS_LIST.value(String.class))); } + }); + } + }); - try { - new Ssh().shell(builder.toString()) - .setUsername(getSelf().getUsername()) - .setPassword(getSelf().getPassword()) - .setHostname(getSelf().getManagementIp()) - .setPort(getSelf().getPort()).runErrorByExceptionAndClose(); - } catch (SshException ex) { - throw new OperationFailureException(operr(ex.toString())); - } + flow(new NoRollbackFlow() { + String __name__ = "update-kvmagent-dependencies"; + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + if (!CoreGlobalProperty.UPDATE_PKG_WHEN_CONNECT) { trigger.next(); + return; } - }); - - flow(new NoRollbackFlow() { - String __name__ = "echo-host"; - @Override - public void run(final FlowTrigger trigger, Map data) { - restf.echo(echoPath, new Completion(trigger) { - @Override - public void success() { - trigger.next(); - } + // new added need to update dependency if experimental repo enabled + if (info.isNewAdded() && !rcf.getResourceConfigValue( + ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_REPO, self.getClusterUuid(), Boolean.class)) { + trigger.next(); + return; + } - @Override - public void fail(ErrorCode errorCode) { - boolean needRestart = KVMGlobalConfig.RESTART_AGENT_IF_FAKE_DEAD.value(Boolean.class); - if (!deployed && needRestart) { - // if not deployed and echo failed, we thought it is fake dead, see: ZSTACK-18628 - AnsibleRunner runner = new AnsibleRunner(); - runner.setAgentPort(KVMGlobalProperty.AGENT_PORT); - runner.setTargetIp(getSelf().getManagementIp()); - runner.setTargetUuid(getSelf().getUuid()); - runner.setUsername(getSelf().getUsername()); - runner.setPassword(getSelf().getPassword()); - runner.setSshPort(getSelf().getPort()); - - runner.restartAgent(AnsibleConstant.KVM_AGENT_NAME, new Completion(trigger) { - @Override - public void success() { - restf.echo(echoPath, new Completion(trigger) { - @Override - public void success() { - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } else { + UpdateDependencyCmd cmd = new UpdateDependencyCmd(); + cmd.hostUuid = self.getUuid(); + cmd.zstackRepo = AnsibleGlobalProperty.ZSTACK_REPO; + + if (info.isNewAdded()) { + cmd.enableExpRepo = true; + cmd.updatePackages = rcf.getResourceConfigValue( + ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_UPDATE_DEPENDENCY, self.getClusterUuid(), String.class); + cmd.excludePackages = rcf.getResourceConfigValue( + ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_EXCLUDE_DEPENDENCY, self.getClusterUuid(), String.class); + } + new Http<>(updateDependencyPath, cmd, UpdateDependencyRsp.class) + .call(new ReturnValueCompletion(trigger) { + @Override + public void success(UpdateDependencyRsp ret) { + if (ret.isSuccess()) { + trigger.next(); + } else { + trigger.fail(Platform.operr("%s", ret.getError())); + } + } + + @Override + public void fail(ErrorCode errorCode) { trigger.fail(errorCode); } - } - }); - } - }); + }); + } + }); + + flow(createCollectHostFactsFlow(info)); + if (info.isNewAdded()) { flow(new NoRollbackFlow() { - String __name__ = "update-kvmagent-dependencies"; + String __name__ = "check-qemu-libvirt-version"; @Override public void run(FlowTrigger trigger, Map data) { - if (!CoreGlobalProperty.UPDATE_PKG_WHEN_CONNECT) { - trigger.next(); + if (!checkQemuLibvirtVersionOfHost()) { + trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match", + self.getUuid(), self.getClusterUuid())); return; } - // new added need to update dependency if experimental repo enabled - if (info.isNewAdded() && !rcf.getResourceConfigValue( - ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_REPO, self.getClusterUuid(), Boolean.class)) { + if (KVMSystemTags.CHECK_CLUSTER_CPU_MODEL.hasTag(self.getClusterUuid())) { + if (KVMSystemTags.CHECK_CLUSTER_CPU_MODEL + .getTokenByResourceUuid(self.getClusterUuid(), KVMSystemTags.CHECK_CLUSTER_CPU_MODEL_TOKEN) + .equals("true") + && !checkCpuModelOfHost()) { + trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", + self.getUuid(), self.getClusterUuid())); + return; + } + trigger.next(); return; } - UpdateDependencyCmd cmd = new UpdateDependencyCmd(); - cmd.hostUuid = self.getUuid(); - cmd.zstackRepo = AnsibleGlobalProperty.ZSTACK_REPO; - - if (info.isNewAdded()) { - cmd.enableExpRepo = true; - cmd.updatePackages = rcf.getResourceConfigValue( - ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_UPDATE_DEPENDENCY, self.getClusterUuid(), String.class); - cmd.excludePackages = rcf.getResourceConfigValue( - ClusterGlobalConfig.ZSTACK_EXPERIMENTAL_EXCLUDE_DEPENDENCY, self.getClusterUuid(), String.class); + if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && !checkCpuModelOfHost()) { + trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", + self.getUuid(), self.getClusterUuid())); + return; } - new Http<>(updateDependencyPath, cmd, UpdateDependencyRsp.class) - .call(new ReturnValueCompletion(trigger) { - @Override - public void success(UpdateDependencyRsp ret) { - if (ret.isSuccess()) { - trigger.next(); - } else { - trigger.fail(Platform.operr("%s", ret.getError())); - } - } - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); + trigger.next(); } }); + } - flow(new NoRollbackFlow() { - String __name__ = "collect-kvm-host-facts"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - HostFactCmd cmd = new HostFactCmd(); - new Http<>(hostFactPath, cmd, HostFactResponse.class) - .call(new ReturnValueCompletion(trigger) { - @Override - public void success(HostFactResponse ret) { - if (!ret.isSuccess()) { - trigger.fail(operr("operation error, because:%s", ret.getError())); - return; - } - - if (ret.getHvmCpuFlag() == null) { - trigger.fail(operr("cannot find either 'vmx' or 'svm' in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting")); - return; - } - - // create system tags of os::version etc - createHostVersionSystemTags(ret.getOsDistribution(), ret.getOsRelease(), ret.getOsVersion()); - - createTagWithoutNonValue(KVMSystemTags.QEMU_IMG_VERSION, KVMSystemTags.QEMU_IMG_VERSION_TOKEN, ret.getQemuImgVersion(), false); - createTagWithoutNonValue(KVMSystemTags.LIBVIRT_VERSION, KVMSystemTags.LIBVIRT_VERSION_TOKEN, ret.getLibvirtVersion(), false); - createTagWithoutNonValue(KVMSystemTags.HVM_CPU_FLAG, KVMSystemTags.HVM_CPU_FLAG_TOKEN, ret.getHvmCpuFlag(), false); - createTagWithoutNonValue(KVMSystemTags.EPT_CPU_FLAG, KVMSystemTags.EPT_CPU_FLAG_TOKEN, ret.getEptFlag(), false); - createTagWithoutNonValue(KVMSystemTags.CPU_MODEL_NAME, KVMSystemTags.CPU_MODEL_NAME_TOKEN, ret.getCpuModelName(), false); - createTagWithoutNonValue(HostSystemTags.HOST_CPU_MODEL_NAME, HostSystemTags.HOST_CPU_MODEL_NAME_TOKEN, ret.getHostCpuModelName(), true); - createTagWithoutNonValue(HostSystemTags.CPU_GHZ, HostSystemTags.CPU_GHZ_TOKEN, ret.getCpuGHz(), true); - createTagWithoutNonValue(HostSystemTags.SYSTEM_PRODUCT_NAME, HostSystemTags.SYSTEM_PRODUCT_NAME_TOKEN, ret.getSystemProductName(), true); - createTagWithoutNonValue(HostSystemTags.SYSTEM_SERIAL_NUMBER, HostSystemTags.SYSTEM_SERIAL_NUMBER_TOKEN, ret.getSystemSerialNumber(), true); - - if (ret.getLibvirtVersion().compareTo(KVMConstant.MIN_LIBVIRT_VIRTIO_SCSI_VERSION) >= 0) { - recreateNonInherentTag(KVMSystemTags.VIRTIO_SCSI); - } - - + flow(new NoRollbackFlow() { + String __name__ = "prepare-host-env"; - List ips = ret.getIpAddresses(); - if (ips != null) { - ips.remove(self.getManagementIp()); - if (CoreGlobalProperty.MN_VIP != null) { - ips.remove(CoreGlobalProperty.MN_VIP); - } - if (!ips.isEmpty()) { - recreateNonInherentTag(HostSystemTags.EXTRA_IPS, HostSystemTags.EXTRA_IPS_TOKEN, StringUtils.join(ips, ",")); - } else { - HostSystemTags.EXTRA_IPS.delete(self.getUuid()); - } - } + @Override + public boolean skip(Map data) { + return CoreGlobalProperty.UNIT_TEST_ON; + } - List libvirtCapabilities = ret.getLibvirtCapabilities(); - if (libvirtCapabilities != null) { - createTagWithoutNonValue(KVMSystemTags.LIBVIRT_CAPABILITIES, KVMSystemTags.LIBVIRT_CAPABILITIES_TOKEN, StringUtils.join(libvirtCapabilities, ","), true); - } + @Override + public void run(FlowTrigger trigger, Map data) { + String script = "which iptables > /dev/null && iptables -C FORWARD -j REJECT --reject-with icmp-host-prohibited > /dev/null 2>&1 && iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited > /dev/null 2>&1 || true"; + runShell(script); + trigger.next(); + } + }); - trigger.next(); - } + error(new FlowErrorHandler(complete) { + @Override + public void handle(ErrorCode errCode, Map data) { + complete.fail(errCode); + } + }); - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - }); + done(new FlowDoneHandler(complete) { + @Override + public void handle(Map data) { + continueConnect(info, complete); + } + }); + } + }).start(); + } - if (info.isNewAdded()) { - flow(new NoRollbackFlow() { - String __name__ = "check-qemu-libvirt-version"; + private NoRollbackFlow createCollectHostFactsFlow(final ConnectHostInfo info) { + return new NoRollbackFlow() { + String __name__ = "collect-kvm-host-facts"; + @Override + public void run(final FlowTrigger trigger, Map data) { + HostFactCmd cmd = new HostFactCmd(); + new Http<>(hostFactPath, cmd, HostFactResponse.class) + .call(new ReturnValueCompletion(trigger) { @Override - public void run(FlowTrigger trigger, Map data) { - if (!checkQemuLibvirtVersionOfHost()) { - trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match", - self.getUuid(), self.getClusterUuid())); + public void success(HostFactResponse ret) { + if (!ret.isSuccess()) { + trigger.fail(operr("operation error, because:%s", ret.getError())); return; } - if (KVMSystemTags.CHECK_CLUSTER_CPU_MODEL.hasTag(self.getClusterUuid())) { - if (KVMSystemTags.CHECK_CLUSTER_CPU_MODEL - .getTokenByResourceUuid(self.getClusterUuid(), KVMSystemTags.CHECK_CLUSTER_CPU_MODEL_TOKEN) - .equals("true") - && !checkCpuModelOfHost()) { - trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", - self.getUuid(), self.getClusterUuid())); - return; - } - - trigger.next(); + if (!checkVirtualizationEnabled(ret)) { + trigger.fail(operr("cannot find either 'vmx' or 'svm' in /proc/cpuinfo, please make sure you have enabled virtualization in your BIOS setting")); return; } - if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && !checkCpuModelOfHost()) { - trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match", - self.getUuid(), self.getClusterUuid())); - return; - } + saveKvmHostRelatedFacts(ret); + saveGeneralHostHardwareFacts(ret); + + ret.getVirtualizerInfo().setUuid(self.getUuid()); + hypervisorManager.saveHostInfo(ret.getVirtualizerInfo()); trigger.next(); } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } }); - } + } - flow(new NoRollbackFlow() { - String __name__ = "prepare-host-env"; + private void recordHardwareChangesAndCreateTag(PatternedSystemTag systemTag, String token, String newValue, ErrorCodeList errorCodeList) { + if (StringUtils.isEmpty(newValue)) { + return; + } - @Override - public void run(FlowTrigger trigger, Map data) { - String script = "which iptables > /dev/null && iptables -C FORWARD -j REJECT --reject-with icmp-host-prohibited > /dev/null 2>&1 && iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited > /dev/null 2>&1 || true"; - runShell(script); - trigger.next(); - } - }); + String oldValue = systemTag.getTokenByResourceUuid(self.getUuid(), token); + if (StringUtils.isEmpty(oldValue) || newValue.equals(oldValue)) { + logger.trace(String.format("host[uuid:%s]'s %s not changed or not recorded, old:%s, new:%s", + self.getUuid(), + systemTag.getTagFormat(), + oldValue, newValue)); + createTagWithoutNonValue(systemTag, token, newValue, true); + return; + } - error(new FlowErrorHandler(complete) { - @Override - public void handle(ErrorCode errCode, Map data) { - complete.fail(errCode); - } - }); + errorCodeList.getCauses().add(operr("host[uuid:%s]'s %s changed, old:%s, new:%s", + self.getUuid(), + systemTag.getTagFormat(), + oldValue, newValue)); + + createTagWithoutNonValue(systemTag, token, newValue, true); + } + + private void saveGeneralHostHardwareFacts(HostFactResponse ret) { + ErrorCodeList errorCodeList = new ErrorCodeList(); + + recordHardwareChangesAndCreateTag(HostSystemTags.HOST_CPU_MODEL_NAME, HostSystemTags.HOST_CPU_MODEL_NAME_TOKEN, ret.getHostCpuModelName(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.CPU_GHZ, HostSystemTags.CPU_GHZ_TOKEN, ret.getCpuGHz(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.CPU_PROCESSOR_NUM, HostSystemTags.CPU_PROCESSOR_NUM_TOKEN, ret.getCpuProcessorNum(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.CPU_CACHE, HostSystemTags.CPU_CACHE_TOKEN, ret.getCpuCache(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.SYSTEM_PRODUCT_NAME, HostSystemTags.SYSTEM_PRODUCT_NAME_TOKEN, ret.getSystemProductName(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.SYSTEM_SERIAL_NUMBER, HostSystemTags.SYSTEM_SERIAL_NUMBER_TOKEN, ret.getSystemSerialNumber(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.SYSTEM_MANUFACTURER, HostSystemTags.SYSTEM_MANUFACTURER_TOKEN, ret.getSystemManufacturer(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.SYSTEM_UUID, HostSystemTags.SYSTEM_UUID_TOKEN, ret.getSystemUUID(), errorCodeList); + recordHardwareChangesAndCreateTag(HostSystemTags.MEMORY_SLOTS_MAXIMUM, HostSystemTags.MEMORY_SLOTS_MAXIMUM_TOKEN, ret.getMemorySlotsMaximum(), errorCodeList); + createTagWithoutNonValue(HostSystemTags.POWER_SUPPLY_MODEL_NAME, HostSystemTags.POWER_SUPPLY_MODEL_NAME_TOKEN, ret.getPowerSupplyModelName(), true); + createTagWithoutNonValue(HostSystemTags.POWER_SUPPLY_MANUFACTURER, HostSystemTags.POWER_SUPPLY_MANUFACTURER_TOKEN, ret.getPowerSupplyManufacturer(), true); + createTagWithoutNonValue(HostSystemTags.IPMI_ADDRESS, HostSystemTags.IPMI_ADDRESS_TOKEN, ret.getIpmiAddress(), true); + createTagWithoutNonValue(HostSystemTags.POWER_SUPPLY_MAX_POWER_CAPACITY, HostSystemTags.POWER_SUPPLY_MAX_POWER_CAPACITY_TOKEN, ret.getPowerSupplyMaxPowerCapacity(), true); + createTagWithoutNonValue(HostSystemTags.BIOS_VENDOR, HostSystemTags.BIOS_VENDOR_TOKEN, ret.getBiosVendor(), true); + createTagWithoutNonValue(HostSystemTags.BIOS_VERSION, HostSystemTags.BIOS_VERSION_TOKEN, ret.getBiosVersion(), true); + createTagWithoutNonValue(HostSystemTags.BIOS_RELEASE_DATE, HostSystemTags.BIOS_RELEASE_DATE_TOKEN, ret.getBiosReleaseDate(), true); + createTagWithoutNonValue(HostSystemTags.BMC_VERSION, HostSystemTags.BMC_VERSION_TOKEN, ret.getBmcVersion(), true); + createTagWithoutNonValue(HostSystemTags.UPTIME, HostSystemTags.UPTIME_TOKEN, ret.getUptime(), true); + createTagWithoutNonValue(HostSystemTags.ISCSI_INITIATOR_NAME, HostSystemTags.ISCSI_INITIATOR_NAME_TOKEN, ret.getIscsiInitiatorName(), true); + createTagWithoutNonValue(HostSystemTags.DEPLOY_MODE, HostSystemTags.DEPLOY_MODE_TOKEN, ret.getDeployMode(), true); + + + saveHostExtraIps(ret); + + if (errorCodeList.getCauses().isEmpty()) { + return; + } - done(new FlowDoneHandler(complete) { - @Override - public void handle(Map data) { - continueConnect(info, complete); - } - }); + // only log the hardware info change for existing host + if (info.isNewAdded()) { + logger.debug(String.format("host[uuid:%s]'s hardware info changed, %s", self.getUuid(), errorCodeList.getCauses())); + return; } - }).start(); - } + + new HostHardwareChangedCanonicalEvent(self.getUuid(), errorCodeList).fire(); + } + + /** + * save host extra ips to host tag + * host management network ip address and management node vip should be excluded + * @param response + */ + private void saveHostExtraIps(HostFactResponse response) { + List ips = response.getIpAddresses(); + if (ips == null) { + return; + } + + ips.remove(self.getManagementIp()); + if (CoreGlobalProperty.MN_VIP != null) { + ips.remove(CoreGlobalProperty.MN_VIP); + } + + if (ips.isEmpty()) { + HostSystemTags.EXTRA_IPS.delete(self.getUuid()); + return; + } + + recreateNonInherentTag(HostSystemTags.EXTRA_IPS, HostSystemTags.EXTRA_IPS_TOKEN, StringUtils.join(ips, ",")); + } + + private boolean checkVirtualizationEnabled(HostFactResponse response) { + return response.getHvmCpuFlag() != null; + } + + private void saveKvmHostRelatedFacts(HostFactResponse ret) { + updateHostOsInformation(ret.getOsDistribution(), ret.getOsRelease(), ret.getOsVersion()); + + if (ret.getLibvirtPackageVersion() != null) { + createTagWithoutNonValue(KVMSystemTags.LIBVIRT_PACKAGE_VERSION, KVMSystemTags.LIBVIRT_PACKAGE_VERSION_TOKEN, ret.getLibvirtPackageVersion().trim(), false); + } + + createTagWithoutNonValue(KVMSystemTags.QEMU_IMG_VERSION, KVMSystemTags.QEMU_IMG_VERSION_TOKEN, ret.getQemuImgVersion(), false); + createTagWithoutNonValue(KVMSystemTags.LIBVIRT_VERSION, KVMSystemTags.LIBVIRT_VERSION_TOKEN, ret.getLibvirtVersion(), false); + createTagWithoutNonValue(KVMSystemTags.HVM_CPU_FLAG, KVMSystemTags.HVM_CPU_FLAG_TOKEN, ret.getHvmCpuFlag(), false); + createTagWithoutNonValue(KVMSystemTags.EPT_CPU_FLAG, KVMSystemTags.EPT_CPU_FLAG_TOKEN, ret.getEptFlag(), false); + createTagWithoutNonValue(KVMSystemTags.CPU_MODEL_NAME, KVMSystemTags.CPU_MODEL_NAME_TOKEN, ret.getCpuModelName(), false); + + if (ret.getLibvirtVersion().compareTo(KVMConstant.MIN_LIBVIRT_VIRTIO_SCSI_VERSION) >= 0) { + recreateNonInherentTag(KVMSystemTags.VIRTIO_SCSI); + } + + List libvirtCapabilities = ret.getLibvirtCapabilities(); + if (libvirtCapabilities != null) { + createTagWithoutNonValue(KVMSystemTags.LIBVIRT_CAPABILITIES, KVMSystemTags.LIBVIRT_CAPABILITIES_TOKEN, StringUtils.join(libvirtCapabilities, ","), true); + } + + deleteCpuHistoryVOIfCpuModeNameChange(ret.getCpuModelName()); + } + }; + } + + private void deleteCpuHistoryVOIfCpuModeNameChange(String cpuModelName){ + // delete all records that do not match the cpuModelName of the source physical machine + SQL.New(CpuFeaturesHistoryVO.class) + .eq(CpuFeaturesHistoryVO_.srcHostUuid, self.getUuid()) + .notEq(CpuFeaturesHistoryVO_.srcCpuModelName, cpuModelName) + .delete(); } private void handle(final ShutdownHostMsg msg) { @@ -4283,12 +6202,32 @@ private void handle(final ShutdownHostMsg msg) { .run(chain -> handleShutdownHost(msg, new NoErrorCompletion(chain) { @Override public void done() { + new HostBase.HostDisconnectedCanonicalEvent(msg.getHostUuid(), operr("host[uuid:%s] becomes power off, send notify", + msg.getHostUuid())).fire(); chain.next(); } })); } private void handleShutdownHost(final ShutdownHostMsg msg, final NoErrorCompletion completion) { + switch (msg.getMethod()) { + case AGENT: + handleShutdownHostByAgent(msg, completion); + break; + case IPMI: + handleShutdownHostByIpmi(msg, completion); + break; + default: + HostIpmiVO ipmi = dbf.findByUuid(msg.getHostUuid(), HostIpmiVO.class); + if (null != ipmi && null != ipmi.getIpmiAddress() && null != ipmi.getIpmiUsername() && null != ipmi.getIpmiPassword()) { + handleShutdownHostByIpmi(msg, completion); + } else { + handleShutdownHostByAgent(msg, completion); + } + } + } + + private void handleShutdownHostByAgent(ShutdownHostMsg msg, NoErrorCompletion completion) { ShutdownHostReply reply = new ShutdownHostReply(); KVMAgentCommands.ShutdownHostCmd cmd = new KVMAgentCommands.ShutdownHostCmd(); new Http<>(shutdownHost, cmd, ShutdownHostResponse.class).call(new ReturnValueCompletion(msg, completion) { @@ -4308,13 +6247,12 @@ public void success(KVMAgentCommands.ShutdownHostResponse ret) { return; } - changeConnectionState(HostStatusEvent.disconnected); if (msg.isReturnEarly()) { bus.reply(msg, reply); completion.done(); - } else { - waitForHostShutdown(reply, completion); } + + waitForHostShutdown(reply, completion); } private boolean testPort() { @@ -4333,18 +6271,43 @@ private boolean testPort() { } private void waitForHostShutdown(ShutdownHostReply reply, NoErrorCompletion noErrorCompletion) { - thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask(msg, noErrorCompletion) { + long timeoutInSec = KVMConstant.KVM_HOST_POWER_OPERATION_TIMEOUT_SECONDS; + long ctimeout = TimeUnit.SECONDS.toMillis(timeoutInSec); + Long deadline = timeHelper.getCurrentTimeMillis() + ctimeout; + thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask(msg, completion) { @Override public boolean run() { + if (isTimeout()) { + if (!msg.isReturnEarly()) { + reply.setSuccess(false); + reply.setError(operr("host[%s] not shutdown in %d seconds", msg.getHostUuid(), ctimeout)); + bus.reply(msg, reply); + noErrorCompletion.done(); + } + return true; + } + if (testPort()) { return false; } - bus.reply(msg, reply); - noErrorCompletion.done(); + Consumer c = msg.getOriginState() == null ? null : h -> { + logger.debug(String.format("host[uuid:%s, name:%s, ip:%s] is power off, set it to origin state %s", + h.getUuid(), h.getName(), h.getManagementIp(), msg.getOriginState())); + h.setState(HostState.valueOf(msg.getOriginState())); + }; + changeConnectionState(HostStatusEvent.disconnected, c); + if (!msg.isReturnEarly()) { + bus.reply(msg, reply); + noErrorCompletion.done(); + } return true; } + private boolean isTimeout() { + return timeHelper.getCurrentTimeMillis() > deadline; + } + @Override public TimeUnit getTimeUnit() { return TimeUnit.SECONDS; @@ -4366,7 +6329,7 @@ public String getName() { private void handle(final CancelHostTaskMsg msg) { CancelHostTaskReply reply = new CancelHostTaskReply(); - cancelJob(msg.getCancellationApiId(), new Completion(msg) { + cancelJob(msg, new Completion(msg) { @Override public void success() { bus.reply(msg, reply); @@ -4380,9 +6343,13 @@ public void fail(ErrorCode errorCode) { }); } - private void cancelJob(String apiId, Completion completion) { + private void cancelJob(CancelHostTaskMsg msg, Completion completion) { CancelCmd cmd = new CancelCmd(); - cmd.setCancellationApiId(apiId); + cmd.setCancellationApiId(msg.getCancellationApiId()); + if (msg.getInterval() != null && msg.getTimes() != null) { + cmd.setInterval(msg.getInterval()); + cmd.setTimes(msg.getTimes()); + } new Http<>(cancelJob, cmd, CancelRsp.class).call(new ReturnValueCompletion(completion) { @Override public void success(CancelRsp ret) { @@ -4547,6 +6514,7 @@ public void run(FlowTrigger trigger, Map data) { @Override public void success(UpdateHostOSRsp ret) { if (ret.isSuccess()) { + data.put(UPDATE_OS_RSP, ret); trigger.next(); } else { trigger.fail(Platform.operr("%s", ret.getError())); @@ -4561,6 +6529,19 @@ public void fail(ErrorCode errorCode) { } }); + flow(new NoRollbackFlow() { + String __name__ = "after-update-kvm-host-os"; + + @Override + public void run(FlowTrigger trigger, Map data) { + for (KvmHostUpdateOsExtensionPoint ext : pluginRegistry.getExtensionList(KvmHostUpdateOsExtensionPoint.class)) { + ext.afterUpdateOs(data, getSelfInventory()); + } + + trigger.next(); + } + }); + flow(new NoRollbackFlow() { String __name__ = "recover-host-state"; @@ -4747,4 +6728,169 @@ public void fail(ErrorCode errorCode) { } }); } + + private void handle(AttachDataVolumeToHostMsg msg) { + inQueue().name(String.format("attach-volume-to-kvm-host-%s", self.getUuid())).asyncBackup(msg) + .run(chain -> doAttachVolume(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void doAttachVolume(AttachDataVolumeToHostMsg msg, NoErrorCompletion completion) { + AttachDataVolumeToHostReply reply = new AttachDataVolumeToHostReply(); + VolumeVO volumeVO = Q.New(VolumeVO.class).eq(VolumeVO_.uuid, msg.getVolumeUuid()).find(); + + AttachVolumeCmd cmd = new AttachVolumeCmd(); + cmd.volumeInstallPath = volumeVO.getInstallPath(); + cmd.volumePrimaryStorageUuid = volumeVO.getPrimaryStorageUuid(); + cmd.mountPath = msg.getMountPath(); + cmd.device = msg.getDevice() == null ? null : msg.getDevice(); + new Http<>(attachVolumePath, cmd, AttachVolumeRsp.class).call(new ReturnValueCompletion(msg) { + @Override + public void success(AttachVolumeRsp rsp) { + if (!rsp.isSuccess()) { + reply.setError(operr("failed to attach volume to host, because:%s", rsp.getError())); + bus.reply(msg, reply); + completion.done(); + return; + } + + VolumeVO vo = dbf.findByUuid(volumeVO.getUuid(), VolumeVO.class); + vo.setState(VolumeState.Disabled); + vo = dbf.updateAndRefresh(vo); + + VolumeHostRefVO ref = dbf.findByUuid(vo.getUuid(), VolumeHostRefVO.class); + if (ref == null) { + ref = new VolumeHostRefVO(); + ref.setHostUuid(self.getUuid()); + ref.setVolumeUuid(vo.getUuid()); + ref.setMountPath(msg.getMountPath()); + ref.setDevice(rsp.device); + dbf.persistAndRefresh(ref); + } else { + if (!Objects.equals(ref.getDevice(), rsp.device)) { + ref.setDevice(rsp.device); + dbf.update(ref); + } + } + + CollectionUtils.safeForEach(pluginRgty.getExtensionList(KVMHostAttachVolumeExtensionPoint.class), + p -> p.afterAttachVolume(self.getUuid())); + + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + }); + } + + private void handle(DetachDataVolumeFromHostMsg msg) { + inQueue().name(String.format("detach-volume-from-kvm-host-%s", self.getUuid())).asyncBackup(msg) + .run(chain -> doDetachVolume(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void doDetachVolume(DetachDataVolumeFromHostMsg msg, NoErrorCompletion completion) { + DetachDataVolumeFromHostReply reply = new DetachDataVolumeFromHostReply(); + DetachVolumeCmd cmd = new DetachVolumeCmd(); + cmd.volumeInstallPath = msg.getVolumeInstallPath(); + cmd.mountPath = msg.getMountPath(); + cmd.device = msg.getDevice(); + new Http<>(detachVolumePath, cmd, DetachVolumeRsp.class).call(new ReturnValueCompletion(msg) { + @Override + public void success(DetachVolumeRsp rsp) { + if (!rsp.isSuccess()) { + reply.setError(operr("failed to detach volume from host, because:%s", rsp.getError())); + } else { + new SQLBatch() { + @Override + protected void scripts() { + sql(VolumeHostRefVO.class).eq(VolumeHostRefVO_.volumeUuid, msg.getVolumeUuid()).delete(); + sql(VolumeVO.class).eq(VolumeVO_.uuid, msg.getVolumeUuid()) + .set(VolumeVO_.state, VolumeState.Enabled).update(); + } + }.execute(); + + CollectionUtils.safeForEach(pluginRgty.getExtensionList(KVMHostDetachVolumeExtensionPoint.class), + p -> p.afterDetachVolume(self.getUuid())); + } + + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + }); + } + + private void checkCleanTraffic(String vmUuid) { + // if cleanTraffic tag is null, check global config value and create tag if it`s true + if (!VmSystemTags.CLEAN_TRAFFIC.hasTag(vmUuid) && + VmGlobalConfig.VM_CLEAN_TRAFFIC.value(Boolean.class)) { + if (!Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, vmUuid).select(VmInstanceVO_.type) + .findValue().equals(VmInstanceConstant.USER_VM_TYPE)) { + return; + } + SystemTagCreator creator = VmSystemTags.CLEAN_TRAFFIC.newSystemTagCreator(vmUuid); + creator.setTagByTokens(map(e(VmSystemTags.CLEAN_TRAFFIC_TOKEN, + String.valueOf(VmGlobalConfig.VM_CLEAN_TRAFFIC.value(Boolean.class)) + ))); + creator.recreate = true; + creator.create(); + } + } + + private void handle(FstrimVmMsg msg) { + inQueue().name(String.format("fstrim-vm-%s", self.getUuid())).asyncBackup(msg) + .run(chain -> doFstrimVm(msg, new NoErrorCompletion(chain) { + @Override + public void done() { + chain.next(); + } + })); + } + + private void doFstrimVm(FstrimVmMsg msg, NoErrorCompletion completion) { + FstrimVmReply reply = new FstrimVmReply(); + + VmFstrimCmd cmd = new VmFstrimCmd(); + cmd.vmUuid = msg.getVmUuid(); + + new Http<>(vmFstrimPath, cmd, VmFstrimRsp.class).call(new ReturnValueCompletion(msg) { + @Override + public void success(VmFstrimRsp rsp) { + if (!rsp.isSuccess()) { + reply.setError(operr("vm[%s] failed to fstrim, because:%s", msg.getVmUuid(), rsp.getError())); + } + bus.reply(msg, reply); + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + completion.done(); + } + }); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java index 5d03909ed42..5c12980bb50 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAllocatorFilterExtensionPoint.java @@ -8,12 +8,163 @@ import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; public class KVMHostAllocatorFilterExtensionPoint implements HostAllocatorFilterExtensionPoint { private CLogger logger = Utils.getLogger(KVMHostAllocatorFilterExtensionPoint.class); + private static Map propertyCheckerMap = new HashMap<>(); + + public enum KVMPropertyName { + EPT("ept"), + LIBVIRT_VERSION("libvirt version"), + QEMU_IMG_VERSION("qemu version"), + CPU_MODEL_NAME("cpu mode name"); + + String name; + + KVMPropertyName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + /** + * interface for kvm property check + */ + interface KVMPropertyChecker { + /** + * String value of KVMPropertyName matched property + * currently only system tag offers properties + * @param hostUuid host uuid need get property of + * @return currently only system used to record + * change the return type if needed + */ + String getKVMHostProperty(String hostUuid); + + /** + * return a defined value from KVMPropertyName + * @return value from KVMPropertyName + */ + KVMPropertyName getPropertyName(); + + /** + * used for condition check because some property + * check could be control by global config in order + * to not break the default usage + * @return need check this property return true else false + */ + default boolean needCheck() { + return true; + } + } + + static class QemuImgVersionChecker implements KVMPropertyChecker { + @Override + public String getKVMHostProperty(String hostUuid) { + return KVMSystemTags.QEMU_IMG_VERSION.getTokenByResourceUuid(hostUuid, KVMSystemTags.QEMU_IMG_VERSION_TOKEN); + } + + @Override + public KVMPropertyName getPropertyName() { + return KVMPropertyName.QEMU_IMG_VERSION; + } + } + + static class LibvirtVersionChecker implements KVMPropertyChecker { + @Override + public String getKVMHostProperty(String hostUuid) { + return KVMSystemTags.LIBVIRT_VERSION.getTokenByResourceUuid(hostUuid, KVMSystemTags.LIBVIRT_VERSION_TOKEN); + } + + @Override + public KVMPropertyName getPropertyName() { + return KVMPropertyName.LIBVIRT_VERSION; + } + } + + static class CPUModelChecker implements KVMPropertyChecker { + @Override + public String getKVMHostProperty(String hostUuid) { + return KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(hostUuid, KVMSystemTags.CPU_MODEL_NAME_TOKEN); + } + + @Override + public KVMPropertyName getPropertyName() { + return KVMPropertyName.CPU_MODEL_NAME; + } + + @Override + public boolean needCheck() { + return KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class); + } + } + + static class HostEPTChecker implements KVMPropertyChecker { + @Override + public String getKVMHostProperty(String hostUuid) { + return KVMSystemTags.EPT_CPU_FLAG.getTokenByResourceUuid(hostUuid, KVMSystemTags.EPT_CPU_FLAG_TOKEN); + } + + @Override + public KVMPropertyName getPropertyName() { + return KVMPropertyName.EPT; + } + } + + static { + List checkers = new ArrayList<>(); + checkers.add(new QemuImgVersionChecker()); + checkers.add(new LibvirtVersionChecker()); + checkers.add(new CPUModelChecker()); + checkers.add(new HostEPTChecker()); + checkers.forEach(checker -> propertyCheckerMap.put(checker.getPropertyName(), checker)); + } + + public static Map getPropertyMapOfHost(String hostUuid) { + Map hostPropertyMap = new HashMap<>(); + propertyCheckerMap.forEach((key, checker) -> { + if (!checker.needCheck()) { + return; + } + + hostPropertyMap.put(key, checker.getKVMHostProperty(hostUuid)); + }); + return hostPropertyMap; + } + + private boolean allPropertiesMatched(Map srcHostProperties, Map dstHostProperties) { + if (srcHostProperties == null || srcHostProperties.isEmpty()) { + return true; + } + + // find not empty property and compare with dest host + List> mismatchPropertyList = srcHostProperties.entrySet() + .stream() + .filter(entry -> !Objects.equals(entry.getValue(), dstHostProperties.get(entry.getKey()))) + .collect(Collectors.toList()); + + if (mismatchPropertyList.isEmpty()) { + return true; + } + + // add debug for mismatch properties + mismatchPropertyList.forEach(entry -> logger.debug(String.format("kvm host %s not match, src host[%s: %s], dst host [%s: %s]", + entry.getKey().getName(), + entry.getKey().getName(), entry.getValue(), + entry.getKey().getName(), dstHostProperties.get(entry.getKey())))); + + return false; + } + @Override public List filterHostCandidates(List candidates, HostAllocatorSpec spec) { if (spec.getHypervisorType() == null || !spec.getHypervisorType().equals(KVMConstant.KVM_HYPERVISOR_TYPE)) { @@ -24,33 +175,20 @@ public List filterHostCandidates(List candidates, HostAllocatorS return candidates; } - // vm can only live migrate to hosts that have the same version of qemu/libvirt + // note: for control plane use KVMPropertyName to define kvm host related property related to + // live migration + // vm can only live migrate to host that have the same version of qemu/libvirt, the + // same cpu model name and same ept state List result = new ArrayList<>(); String srcHostUuid = spec.getVmInstance().getHostUuid(); - String srcQemuVer = KVMSystemTags.QEMU_IMG_VERSION.getTokenByResourceUuid(srcHostUuid, KVMSystemTags.QEMU_IMG_VERSION_TOKEN); - String srcLibvirtVer = KVMSystemTags.LIBVIRT_VERSION.getTokenByResourceUuid(srcHostUuid, KVMSystemTags.LIBVIRT_VERSION_TOKEN); - String srcCpuModelName = KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(srcHostUuid, KVMSystemTags.CPU_MODEL_NAME_TOKEN); - // nothing to check - if (srcQemuVer == null && srcLibvirtVer == null && srcCpuModelName == null) { - return candidates; - } - + Map srcHostPropertyMap = getPropertyMapOfHost(srcHostUuid); for (HostVO host : candidates) { - String dstQemuVer = KVMSystemTags.QEMU_IMG_VERSION.getTokenByResourceUuid(host.getUuid(), KVMSystemTags.QEMU_IMG_VERSION_TOKEN); - String dstLibvirtVer = KVMSystemTags.LIBVIRT_VERSION.getTokenByResourceUuid(host.getUuid(), KVMSystemTags.LIBVIRT_VERSION_TOKEN); - String dstCpuModelName = KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(host.getUuid(), KVMSystemTags.CPU_MODEL_NAME_TOKEN); - if ((srcQemuVer == null || srcQemuVer.equals(dstQemuVer)) - && (srcLibvirtVer == null || srcLibvirtVer.equals(dstLibvirtVer))) { + Map candidateHostPropertyMap = getPropertyMapOfHost(host.getUuid()); + if (allPropertiesMatched(srcHostPropertyMap, candidateHostPropertyMap)) { result.add(host); } else { - logger.debug(String.format("cannot migrate vm[uuid:%s] to host[uuid:%s] because qemu/libvirt version not match", - spec.getVmInstance().getUuid(), host.getUuid())); - } - - if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && srcCpuModelName != null && !srcCpuModelName.equals(dstCpuModelName)) { - result.remove(host); - logger.debug(String.format("cannot migrate vm[uuid:%s] to host[uuid:%s] because cpu model name not match", + logger.debug(String.format("cannot migrate vm[uuid:%s] to host[uuid:%s] because kvm properties mismatch detected", spec.getVmInstance().getUuid(), host.getUuid())); } } @@ -60,6 +198,6 @@ public List filterHostCandidates(List candidates, HostAllocatorS @Override public String filterErrorReason() { - return Platform.i18n("cannot adapt version for the bellow rpm: livirt / qemu / cpumodel"); + return Platform.i18n("cannot adapt version for the bellow rpm: libvirt / qemu / cpumodel"); } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAsyncHttpCallReply.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAsyncHttpCallReply.java index af7db91ebe6..09f9ee37eff 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAsyncHttpCallReply.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAsyncHttpCallReply.java @@ -1,11 +1,15 @@ package org.zstack.kvm; +import org.zstack.header.errorcode.ErrorableValue; import org.zstack.header.message.MessageReply; import org.zstack.header.message.NoJsonSchema; +import org.zstack.kvm.KVMAgentCommands.AgentResponse; import org.zstack.utils.gson.JSONObjectUtil; import java.util.LinkedHashMap; +import static org.zstack.core.Platform.*; + /** */ public class KVMHostAsyncHttpCallReply extends MessageReply { @@ -23,4 +27,32 @@ public void setResponse(LinkedHashMap response) { public T toResponse(Class clz) { return JSONObjectUtil.rehashObject(response, clz); } + + public static ErrorableValue unwrap(MessageReply reply) { + return unwrap(reply, AgentResponse.class); + } + + public static ErrorableValue unwrap(MessageReply reply, Class responseClass) { + if (!reply.isSuccess()) { + return ErrorableValue.ofErrorCode(reply.getError()); + } + + if (!(reply instanceof KVMHostAsyncHttpCallReply)) { + return ErrorableValue.ofErrorCode( + operr("reply[%s] is not a KVMHostAsyncHttpCallReply", reply.getClass().getSimpleName())); + } + + final KVMHostAsyncHttpCallReply castReply = (KVMHostAsyncHttpCallReply) reply; + if (castReply.response == null) { + return ErrorableValue.ofErrorCode( + operr("reply[%s] return with empty response", reply.getClass().getSimpleName())); + } + + final T response = castReply.toResponse(responseClass); + if (!response.isSuccess()) { + return ErrorableValue.ofErrorCode( + operr("%s operation failed: %s", response.getClass().getSimpleName(), response.getError())); + } + return ErrorableValue.of(response); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAttachVolumeExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAttachVolumeExtensionPoint.java new file mode 100644 index 00000000000..ee7423a88b0 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostAttachVolumeExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.kvm; + +public interface KVMHostAttachVolumeExtensionPoint { + void afterAttachVolume(String hostUuid); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostConnectionReestablishExtensionForL2Network.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostConnectionReestablishExtensionForL2Network.java new file mode 100644 index 00000000000..754cf972496 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostConnectionReestablishExtensionForL2Network.java @@ -0,0 +1,54 @@ +package org.zstack.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.FutureCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.*; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.network.l2.L2NetworkManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.TypedQuery; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +public class KVMHostConnectionReestablishExtensionForL2Network extends AbstractKVMConnectExtensionForL2Network implements HostConnectionReestablishExtensionPoint { + @Autowired + protected L2NetworkManager l2Mgr; + protected static final CLogger logger = Utils.getLogger(KVMHostConnectionReestablishExtensionForL2Network.class); + + @Override + public void connectionReestablished(HostInventory inv) throws HostException { + //TODO: make connect async + List l2s = getL2Networks(inv.getClusterUuid()); + if (l2s.isEmpty()) { + return; + } + + FutureCompletion completion = new FutureCompletion(null); + prepareNetwork(l2s, inv.getUuid(), completion); + completion.await(TimeUnit.SECONDS.toMillis(600)); + if (!completion.isSuccess()) { + throw new OperationFailureException(completion.getErrorCode()); + } + } + + @Override + public HypervisorType getHypervisorTypeForReestablishExtensionPoint() { + return new HypervisorType(KVMConstant.KVM_HYPERVISOR_TYPE); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostDeployArguments.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostDeployArguments.java new file mode 100644 index 00000000000..13e929c1d5d --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostDeployArguments.java @@ -0,0 +1,176 @@ +package org.zstack.kvm; + +import com.google.gson.annotations.SerializedName; +import org.apache.commons.lang.StringUtils; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; +import org.zstack.header.errorcode.OperationFailureException; + +import static org.zstack.core.Platform.operr; + +public class KVMHostDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_kvmagent") + private final String packageName = KVMGlobalProperty.AGENT_PACKAGE_NAME; + @SerializedName("init") + private String init; + @SerializedName("skipIpv6") + private String skipIpv6; + @SerializedName("disableIp6Tables") + private String disableIp6Tables; + @SerializedName("isBareMetal2Gateway") + private String isBareMetal2Gateway; + @SerializedName("bridgeDisableIptables") + private String bridgeDisableIptables; + @SerializedName("hostname") + private String hostname; + @SerializedName("skip_packages") + private String skipPackages; + @SerializedName("update_packages") + private String updatePackages; + @SerializedName("post_url") + private String postUrl; + @SerializedName("isEnableKsm") + private String isEnableKsm; + @SerializedName("enable_spice_tls") + private String enableSpiceTls; + @SerializedName("enable_cgroup_device_acl") + private String enableCgroupDeviceAcl; + @SerializedName("restart_libvirtd") + private String restartLibvirtd; + @SerializedName("extra_packages") + private String extraPackages; + + private transient boolean forceRun = false; + + public String getInit() { + return init; + } + + public void setInit(String init) { + this.init = init; + } + + public String getSkipIpv6() { + return skipIpv6; + } + + public void setSkipIpv6(String skipIpv6) { + this.skipIpv6 = skipIpv6; + } + + public String getDisableIp6Tables() { + return disableIp6Tables; + } + + public void setDisableIp6Tables(String disableIp6Tables) { + this.disableIp6Tables = disableIp6Tables; + } + + public String getIsBareMetal2Gateway() { + return isBareMetal2Gateway; + } + + public void setIsBareMetal2Gateway(String isBareMetal2Gateway) { + this.isBareMetal2Gateway = isBareMetal2Gateway; + } + + public String getBridgeDisableIptables() { + return bridgeDisableIptables; + } + + public void setBridgeDisableIptables(String bridgeDisableIptables) { + this.bridgeDisableIptables = bridgeDisableIptables; + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getSkipPackages() { + return skipPackages; + } + + public void setSkipPackages(String skipPackages) { + this.skipPackages = skipPackages; + } + + public String getUpdatePackages() { + return updatePackages; + } + + public void setUpdatePackages(String updatePackages) { + this.updatePackages = updatePackages; + } + + public String getPostUrl() { + return postUrl; + } + + public void setPostUrl(String postUrl) { + this.postUrl = postUrl; + } + + public String getIsEnableKsm() { + return isEnableKsm; + } + + public void setIsEnableKsm(String isEnableKsm) { + this.isEnableKsm = isEnableKsm; + } + + @Override + public String getPackageName() { + return packageName; + } + + public String getExtraPackages() { + return extraPackages; + } + + public void setExtraPackages(String extraPackages) { + this.extraPackages = extraPackages; + } + + public String getEnableSpiceTls() { + return enableSpiceTls; + } + + public void setEnableSpiceTls(String enableSpiceTls) { + this.enableSpiceTls = enableSpiceTls; + } + + public String getEnableCgroupDeviceAcl() { + return enableCgroupDeviceAcl; + } + + public void setEnableCgroupDeviceAcl(String enableCgroupDeviceAcl) { + this.enableCgroupDeviceAcl = enableCgroupDeviceAcl; + } + + public String getRestartLibvirtd() { + return restartLibvirtd; + } + + public void setRestartLibvirtd(String restartLibvirtd) { + this.restartLibvirtd = restartLibvirtd; + } + + public boolean isForceRun() { + return forceRun; + } + + public void setForceRun(boolean forceRun) { + this.forceRun = forceRun; + } + + public void enableForceRunWithReason(String reason) { + this.forceRun = true; + if (StringUtils.isEmpty(reason)) { + throw new OperationFailureException(operr("the reason must be stated when setting force run")); + } + logger.info(String.format("set ansible to force run, because %s", reason)); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostDetachVolumeExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostDetachVolumeExtensionPoint.java new file mode 100644 index 00000000000..940838164de --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostDetachVolumeExtensionPoint.java @@ -0,0 +1,6 @@ +package org.zstack.kvm; + +public interface KVMHostDetachVolumeExtensionPoint { + void afterDetachVolume(String hostUuid); +} + diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostFactory.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostFactory.java index 88ca10b9427..4d4fa167b7e 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostFactory.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostFactory.java @@ -6,17 +6,22 @@ import org.zstack.compute.host.HostGlobalConfig; import org.zstack.compute.vm.CrashStrategy; import org.zstack.compute.vm.VmGlobalConfig; -import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.compute.vm.VmNicManager; import org.zstack.core.CoreGlobalProperty; -import org.zstack.core.Platform; import org.zstack.core.ansible.AnsibleFacade; -import org.zstack.core.cloudbus.*; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusListCallBack; +import org.zstack.core.cloudbus.CloudBusSteppingCallback; +import org.zstack.core.cloudbus.EventFacade; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.cloudbus.ResourceDestinationMaker; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.config.GlobalConfig; import org.zstack.core.config.GlobalConfigException; +import org.zstack.core.config.GlobalConfigFacade; import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; import org.zstack.core.config.GlobalConfigValidatorExtensionPoint; -import org.zstack.core.config.schema.GuestOsCategory; +import org.zstack.core.config.GuestOsExtensionPoint; import org.zstack.core.config.schema.GuestOsCharacter; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; @@ -29,36 +34,57 @@ import org.zstack.header.AbstractService; import org.zstack.header.Component; import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.*; -import org.zstack.header.image.GuestOsCategoryVO; -import org.zstack.header.image.GuestOsCategoryVO_; import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.network.l2.L2NetworkClusterRefVO; +import org.zstack.header.network.l2.L2NetworkClusterRefVO_; import org.zstack.header.network.l2.L2NetworkType; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.L2NetworkVO_; import org.zstack.header.rest.RESTFacade; import org.zstack.header.rest.SyncHttpCallHandler; import org.zstack.header.tag.FormTagExtensionPoint; -import org.zstack.header.vm.*; -import org.zstack.header.volume.*; -import org.zstack.kvm.KVMAgentCommands.ReconnectMeCmd; -import org.zstack.kvm.KVMAgentCommands.TransmitVmOperationToMnCmd; +import org.zstack.header.tag.SystemTagInventory; +import org.zstack.header.tag.SystemTagLifeCycleListener; +import org.zstack.header.tag.SystemTagValidator; +import org.zstack.header.vm.KvmReportVmShutdownEventMsg; +import org.zstack.header.vm.KvmReportVmShutdownFromGuestEventMsg; +import org.zstack.header.vm.RebootVmInstanceMsg; +import org.zstack.header.vm.StartVmInstanceMsg; +import org.zstack.header.vm.StopVmInstanceMsg; +import org.zstack.header.vm.VmCanonicalEvents; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; +import org.zstack.header.volume.MaxDataVolumeNumberExtensionPoint; +import org.zstack.header.volume.VolumeConstant; +import org.zstack.header.volume.VolumeFormat; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeVO; +import org.zstack.kvm.KVMAgentCommands.*; +import org.zstack.network.l3.ServiceTypeExtensionPoint; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.utils.CollectionUtils; import org.zstack.utils.IpRangeSet; import org.zstack.utils.SizeUtils; import org.zstack.utils.Utils; +import org.zstack.utils.data.SizeUnit; import org.zstack.utils.form.Form; import org.zstack.utils.function.Function; import org.zstack.utils.function.ValidateFunction; +import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; -import org.zstack.utils.path.PathUtil; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import java.io.File; +import javax.persistence.Tuple; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; @@ -68,7 +94,14 @@ import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -77,26 +110,30 @@ import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; - -public class KVMHostFactory extends AbstractService implements HypervisorFactory, Component, - ManagementNodeReadyExtensionPoint, MaxDataVolumeNumberExtensionPoint, HypervisorMessageFactory { +import static org.zstack.kvm.KVMAgentCommands.*; +import static org.zstack.kvm.KVMConstant.CPU_MODE_NONE; + +public class KVMHostFactory extends AbstractService implements HypervisorFactory, + Component, + ManagementNodeReadyExtensionPoint, + MaxDataVolumeNumberExtensionPoint, + GuestOsExtensionPoint, + HypervisorMessageFactory { private static final CLogger logger = Utils.getLogger(KVMHostFactory.class); public static final HypervisorType hypervisorType = new HypervisorType(KVMConstant.KVM_HYPERVISOR_TYPE); public static final VolumeFormat QCOW2_FORMAT = new VolumeFormat(VolumeConstant.VOLUME_FORMAT_QCOW2, hypervisorType); public static final VolumeFormat RAW_FORMAT = new VolumeFormat(VolumeConstant.VOLUME_FORMAT_RAW, hypervisorType); + public static final VolumeFormat VMDK_FORMAT = new VolumeFormat(VolumeConstant.VOLUME_FORMAT_VMDK, hypervisorType); private List connectExtensions = new ArrayList<>(); private final Map completeNicInfoExtensions = new HashMap<>(); private int maxDataVolumeNum; - private static final String GUEST_OS_CATEGORY_FILE = "guestOs/guestOsCategory.xml"; - private static final String GUEST_OS_CHARACTER_FILE = "guestOs/guestOsCharacter.xml"; - public static Map allGuestOsCategory = new ConcurrentHashMap<>(); - public static Map allGuestOsCharacter = new ConcurrentHashMap<>(); private final Map socketTimeoutMap = new ConcurrentHashMap<>(); static { RAW_FORMAT.newFormatInputOutputMapping(hypervisorType, QCOW2_FORMAT.toString()); + VMDK_FORMAT.newFormatInputOutputMapping(hypervisorType, QCOW2_FORMAT.toString()); QCOW2_FORMAT.setFirstChoice(hypervisorType); } @@ -120,8 +157,16 @@ public class KVMHostFactory extends AbstractService implements HypervisorFactory private ThreadFacade thdf; @Autowired private ResourceConfigFacade rcf; - + @Autowired + private VmInstanceDeviceManager vidm; + @Autowired + private VmNicManager vmNicManager; + @Autowired + private GlobalConfigFacade gcf; + @Autowired + KvmVmSyncPingTask pingTask; private Future checkSocketChannelTimeoutThread; + public static int skipHostPingTimeWhenKvmagentBusy = 300; @Override public HostVO createHost(HostVO vo, AddHostMessage msg) { @@ -186,7 +231,11 @@ private List loadMsgFromFile(String content, ValidateFunction getHostOsMap(Collection hostUuidList) { + if (CollectionUtils.isEmpty(hostUuidList)) { + return Collections.emptyMap(); + } + + List tuples = Q.New(KVMHostVO.class) + .select(KVMHostVO_.osDistribution, KVMHostVO_.osRelease, KVMHostVO_.osVersion, KVMHostVO_.uuid) + .in(KVMHostVO_.uuid, hostUuidList) + .listTuple(); + return tuples.stream().collect(Collectors.toMap( + tuple -> tuple.get(3, String.class), + tuple -> HostOperationSystem.of( + tuple.get(0, String.class), tuple.get(1, String.class), tuple.get(2, String.class)))); + } + + @Override + public ErrorCode checkNewAddedHost(HostVO vo) { + final HostOperationSystem os = getHostOS(vo.getUuid()); + if (!os.isValid()) { + return operr("the operation system[%s] of host[name:%s, ip:%s] is invalid", + os, vo.getName(), vo.getManagementIp()); + } + + String otherHostUuid = Q.New(HostVO.class) + .select(HostVO_.uuid) + .eq(HostVO_.clusterUuid, vo.getClusterUuid()) + .notEq(HostVO_.uuid, vo.getUuid()) + .notEq(HostVO_.status, HostStatus.Connecting) + .limit(1) + .findValue(); + if (otherHostUuid == null) { + // this the first host in cluster + return null; + } + + final HostOperationSystem otherOs = getHostOS(otherHostUuid); + if (!otherOs.isValid()) { + // this the first host in cluster + return null; + } + + if (os.equals(otherOs)) { + return null; + } + + return operr("cluster[uuid:%s] already has host with os version[%s], but new added host[name:%s ip:%s] has different host os version[%s]", + vo.getClusterUuid(), otherOs, vo.getName(), vo.getManagementIp(), os); + } + protected void populateExtensions() { connectExtensions = pluginRgty.getExtensionList(KVMHostConnectExtensionPoint.class); for (KVMCompleteNicInformationExtensionPoint ext : pluginRgty.getExtensionList(KVMCompleteNicInformationExtensionPoint.class)) { @@ -270,22 +383,85 @@ private void deployAnsibleModule() { asf.deployModule(KVMConstant.ANSIBLE_MODULE_PATH, KVMConstant.ANSIBLE_PLAYBOOK_NAME); } + void physicalCpuStatusAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalCpuStatusAbnormalData cdata = new HostCanonicalEvents.HostPhysicalCpuStatusAbnormalData(); + cdata.setCpuName(cmd.getAdditionalProperties().get(KVMConstant.CPU_NAME).toString()); + cdata.setHostUuid(cmd.getHost()); + cdata.setStatus(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_STATUS_NAME).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_CPU_STATUS_ABNORMAL, cdata); + } + + void physicalMemoryStatusAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalMemoryStatusAbnormalData cdata = new HostCanonicalEvents.HostPhysicalMemoryStatusAbnormalData(); + cdata.setHostUuid(cmd.getHost()); + cdata.setLocator(cmd.getAdditionalProperties().get(KVMConstant.MEMORY_LOCATOR_NAME).toString()); + cdata.setStatus(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_STATUS_NAME).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_MEMORY_STATUS_ABNORMAL, cdata); + } + + void physicalPowerSupplyStatusAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalPowerSupplyStatusAbnormalData cdata = new HostCanonicalEvents.HostPhysicalPowerSupplyStatusAbnormalData(); + cdata.setHostUuid(cmd.getHost()); + cdata.setStatus(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_STATUS_NAME).toString()); + cdata.setName(cmd.getAdditionalProperties().get(KVMConstant.DEVICE_NAME).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_POWER_SUPPLY_STATUS_ABNORMAL, cdata); + } + + void physicalFanStatusAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalFanStatusAbnormalData cdata = new HostCanonicalEvents.HostPhysicalFanStatusAbnormalData(); + cdata.setHostUuid(cmd.getHost()); + cdata.setFanName(cmd.getAdditionalProperties().get(KVMConstant.DEVICE_NAME).toString()); + cdata.setStatus(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_STATUS_NAME).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_FAN_STATUS_ABNORMAL, cdata); + } + + void physicalDiskStatusAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalDiskStatusAbnormalData cdata = new HostCanonicalEvents.HostPhysicalDiskStatusAbnormalData(); + cdata.setHostUuid(cmd.getHost()); + cdata.setSerialNumber(cmd.getAdditionalProperties().get(KVMConstant.DEVICE_SERIAL_NUMBER).toString()); + cdata.setEnclosureId(cmd.getAdditionalProperties().get(KVMConstant.ENCLOSURE_DEVICE_ID).toString()); + cdata.setSlotNumber(cmd.getAdditionalProperties().get(KVMConstant.SLOT_NUMBER).toString()); + cdata.setStatus(cmd.getAdditionalProperties().get(KVMConstant.DRIVE_STATE).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_DISK_STATUS_ABNORMAL, cdata); + } + + void physicalRaidStatusAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalRaidStatusAbnormalData cdata = new HostCanonicalEvents.HostPhysicalRaidStatusAbnormalData(); + cdata.setHostUuid(cmd.getHost()); + cdata.setStatus(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_STATUS_NAME).toString()); + cdata.setTargetId(cmd.getAdditionalProperties().get(KVMConstant.TARGET_ID).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_RAID_STATUS_ABNORMAL, cdata); + } + + void physicalVolumeStateAlarmEvent(HostPhysicalDeviceStatusAlarmEventCmd cmd) { + HostCanonicalEvents.HostPhysicalVolumeStateAbnormalData cdata = new HostCanonicalEvents.HostPhysicalVolumeStateAbnormalData(); + cdata.setHostUuid(cmd.getHost()); + cdata.setState(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_STATE_NAME).toString()); + cdata.setDiskUuids(cmd.getAdditionalProperties().get(KVMConstant.PHYSICAL_DEVICE_DISK_UUIDS).toString()); + cdata.setDiskName(cmd.getAdditionalProperties().get(KVMConstant.DEVICE_NAME).toString()); + cdata.setVgName(cmd.getAdditionalProperties().get(KVMConstant.VOLUME_GROUP_NAME).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_VOLUME_STATE_ABNORMAL, cdata); + } + + private void processKvmagentPhysicalMemUsageAbnormal(HostProcessPhysicalMemoryUsageAlarmCmd cmd) { + if (cmd.getMemoryUsage() <= gcf.getConfigValue(KVMGlobalConfig.CATEGORY, + KVMGlobalConfig.KVMAGENT_PHYSICAL_MEMORY_USAGE_HARD_LIMIT.getName(), Long.class)) { + return; + } + + logger.debug("The zstack-kvmagent service has exceeded the hard limit for physical memory usage, " + + "and we will try restart it later"); + RestartKvmAgentMsg restartKvmAgentMsg = new RestartKvmAgentMsg(); + restartKvmAgentMsg.setHostUuid(cmd.getHostUuid()); + bus.makeTargetServiceIdByResourceUuid(restartKvmAgentMsg, HostConstant.SERVICE_ID, restartKvmAgentMsg.getHostUuid()); + bus.send(restartKvmAgentMsg); + } + @Override public boolean start() { deployAnsibleModule(); populateExtensions(); configKVMDeviceType(); - initGuestOsCategory(); - initGuestOsCharacter(); - - if (KVMGlobalConfig.ENABLE_HOST_TCP_CONNECTION_CHECK.value(Boolean.class)) { - try { - startTcpServer(); - startTcpChannelTimeoutChecker(); - } catch (IOException e) { - throw new CloudRuntimeException("Failed to start tcp server on management node"); - } - } if (KVMGlobalConfig.ENABLE_HOST_TCP_CONNECTION_CHECK.value(Boolean.class)) { try { @@ -324,6 +500,34 @@ public void validateGlobalConfig(String category, String name, String oldValue, } } }); + ResourceConfig resourceConfig = rcf.getResourceConfig(KVMGlobalConfig.VM_CPU_HYPERVISOR_FEATURE.getIdentity()); + resourceConfig.installValidatorExtension((resourceUuid, oldValue, newValue) -> { + if (Boolean.TRUE.toString().equals(newValue)) { + return; + } + + ResourceConfig cpuMode = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + if (CPU_MODE_NONE.equals(cpuMode.getResourceConfigValue(resourceUuid, String.class))) { + throw new GlobalConfigException("Can not disable cpu hypervisor feature with vm.cpuMode none"); + } + }); + + resourceConfig = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + resourceConfig.installValidatorExtension((resourceUuid, oldValue, newValue) -> { + if (oldValue.equals(newValue)) { + return; + } + + VmInstanceState vmState = Q.New(VmInstanceVO.class).select(VmInstanceVO_.state) + .eq(VmInstanceVO_.uuid, resourceUuid) + .findValue(); + if (vmState != null + && vmState != VmInstanceState.Starting // some configs are set while vm is starting + && !VmInstanceState.offlineStates.contains(vmState)) { + throw new GlobalConfigException("Can not change vm.cpuMode while VM is living."); + } + }); + restf.registerSyncHttpCallHandler(KVMConstant.KVM_RECONNECT_ME, ReconnectMeCmd.class, new SyncHttpCallHandler() { @Override public String handleSyncHttpCall(ReconnectMeCmd cmd) { @@ -365,16 +569,45 @@ public String handleSyncHttpCall(TransmitVmOperationToMnCmd cmd) { } }); - restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_REBOOT_EVENT, KVMAgentCommands.ReportVmRebootEventCmd.class, new SyncHttpCallHandler() { - @Override - public String handleSyncHttpCall(KVMAgentCommands.ReportVmRebootEventCmd cmd) { - evf.fire(VmCanonicalEvents.VM_LIBVIRT_REPORT_REBOOT, cmd.vmUuid); + restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_REBOOT_EVENT, ReportVmRebootEventCmd.class, cmd -> { + evf.fire(VmCanonicalEvents.VM_LIBVIRT_REPORT_REBOOT, cmd.vmUuid); + + return null; + }); + restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_SHUTDOWN_EVENT, ReportVmShutdownEventCmd.class, cmd -> { + if (cmd.vmUuid == null || !Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, cmd.vmUuid) + .isExists()) { + logger.debug(String.format("vm[uuid:%s] not found, skip report vm shutdown event", cmd.vmUuid)); + } + + if (pingTask.isVmDoNotNeedToTrace(cmd.vmUuid)) { + logger.debug(String.format("vm[uuid:%s] is not in the list of vm that need to be traced, skip report vm shutdown event", cmd.vmUuid)); return null; } + + KvmReportVmShutdownEventMsg msg = new KvmReportVmShutdownEventMsg(); + msg.setVmInstanceUuid(cmd.vmUuid); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, cmd.vmUuid); + bus.send(msg); + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_SHUTDOWN_FROM_GUEST_EVENT, ReportVmShutdownEventCmd.class, cmd -> { + KvmReportVmShutdownFromGuestEventMsg msg = new KvmReportVmShutdownFromGuestEventMsg(); + msg.setVmInstanceUuid(cmd.vmUuid); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, cmd.vmUuid); + bus.send(msg); + return null; }); - restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_CRASH_EVENT, KVMAgentCommands.ReportVmCrashEventCmd.class, cmd -> { + restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_START_EVENT, ReportVmStartEventCmd.class, cmd -> { + evf.fire(VmCanonicalEvents.VM_LIBVIRT_REPORT_START, cmd.vmUuid); + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_VM_CRASH_EVENT, ReportVmCrashEventCmd.class, cmd -> { if (!CrashStrategy.valueOf(rcf.getResourceConfigValue(VmGlobalConfig.VM_CRASH_STRATEGY, cmd.vmUuid, String.class)).isCrashStrategyEnable()) { return null; } @@ -385,7 +618,24 @@ public String handleSyncHttpCall(KVMAgentCommands.ReportVmRebootEventCmd cmd) { return null; }); + restf.registerSyncHttpCallHandler(KVMConstant.KVM_REPORT_HOST_STOP_EVENT, ReportHostStopEventCmd.class, cmd -> { + if (StringUtils.isEmpty(cmd.hostUuid)) { + return null; + } + + ChangeHostStatusMsg cmsg = new ChangeHostStatusMsg(); + cmsg.setUuid(cmd.hostUuid); + cmsg.setStatusEvent(HostStatusEvent.disconnected.toString()); + bus.makeTargetServiceIdByResourceUuid(cmsg, HostConstant.SERVICE_ID, cmsg.getHostUuid()); + bus.send(cmsg); + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.KVM_HOST_PHYSICAL_NIC_ALARM_EVENT, KVMAgentCommands.PhysicalNicAlarmEventCmd.class, cmd -> { + if (!isNeedAlarmNic(cmd.host, cmd.nic, cmd.bond)) { + return null; + } HostCanonicalEvents.HostPhysicalNicStatusData cData = new HostCanonicalEvents.HostPhysicalNicStatusData(); cData.setHostUuid(cmd.host); cData.setInterfaceName(cmd.nic); @@ -400,6 +650,109 @@ public String handleSyncHttpCall(KVMAgentCommands.ReportVmRebootEventCmd cmd) { return null; }); + + + restf.registerSyncHttpCallHandler(KVMConstant.HOST_PHYSICAL_HARD_STATUS_ALARM_EVENT, HostPhysicalDeviceStatusAlarmEventCmd.class, cmd -> { + switch (HostHardware.fromString(cmd.getType())) { + case CPU: + physicalCpuStatusAlarmEvent(cmd); + break; + case MEMORY: + physicalMemoryStatusAlarmEvent(cmd); + break; + case GPU: + for (KvmHardwareStatusHandlerExtensionPoint ext : pluginRgty.getExtensionList(KvmHardwareStatusHandlerExtensionPoint.class)) { + ext.handleKvmHardwareStatus(HostHardware.GPU, cmd); + } + break; + case POWERSUPPLY: + physicalPowerSupplyStatusAlarmEvent(cmd); + break; + case FAN: + physicalFanStatusAlarmEvent(cmd); + break; + case DISK: + physicalDiskStatusAlarmEvent(cmd); + break; + case RAID: + physicalRaidStatusAlarmEvent(cmd); + break; + case PHYSICAL_VOLUME: + physicalVolumeStateAlarmEvent(cmd); + break; + + default: + logger.debug(String.format("unknown physical device type[%s] in host[uuid:%s]", cmd.getType(), cmd.getHost())); + + } + return null; + }); + + + restf.registerSyncHttpCallHandler(KVMConstant.HOST_PROCESS_PHYSICAL_MEMORY_USAGE_ALARM_PATH, HostProcessPhysicalMemoryUsageAlarmCmd.class, cmd -> { + HostCanonicalEvents.HostProcessPhysicalMemoryUsageAlarmData data = new HostCanonicalEvents.HostProcessPhysicalMemoryUsageAlarmData(); + data.setHostUuid(cmd.getHostUuid()); + data.setPid(cmd.getPid()); + data.setMemoryUsage(String.format("%s MB", cmd.getMemoryUsage() / 1048576)); + data.setProcessName(cmd.getProcessName()); + evf.fire(HostCanonicalEvents.HOST_PROCESS_PHYSICAL_MEMORY_USAGE_ABNORMAL, data); + + switch (data.getProcessName()) { + case "zstack-kvmagent": + processKvmagentPhysicalMemUsageAbnormal(cmd); + break; + default: + logger.debug(String.format("unknown process name[%s] in host[uuid:%s]", cmd.getProcessName(), cmd.getHostUuid())); + } + + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.HOST_KVMAGENT_STATUS_PATH, HostKvmagentStatusCmd.class, cmd -> { + if ("busy".equals(cmd.getStatus())) { + HostCanonicalEvents.HostPingSkipData data = new HostCanonicalEvents.HostPingSkipData(); + data.setHostUuid(cmd.getHostUuid()); + // this will skip host ping sometime if kvmagent busy + data.setSkipTimeInSec(skipHostPingTimeWhenKvmagentBusy * (int)(cmd.getMemoryUsage() / SizeUnit.GIGABYTE.toByte(4) + 1)); + evf.fire(HostCanonicalEvents.HOST_PING_SKIP, data); + } else if ("available".equals(cmd.getStatus())) { + HostCanonicalEvents.HostPingSkipData data = new HostCanonicalEvents.HostPingSkipData(); + data.setHostUuid(cmd.getHostUuid()); + evf.fire(HostCanonicalEvents.HOST_PING_CANCEL_SKIP, data); + } else { + logger.debug("unknown kvmagent status: " + cmd.getStatus()); + } + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.HOST_PHYSICAL_DISK_INSERT_ALARM_EVENT, HostPhysicalDiskInsertAlarmEventCmd.class, cmd -> { + HostCanonicalEvents.HostPhysicalDiskData cdata = new HostCanonicalEvents.HostPhysicalDiskData(); + cdata.setHostUuid(cmd.host); + cdata.setSerialNumber(cmd.additionalProperties.get(KVMConstant.DEVICE_SERIAL_NUMBER).toString()); + cdata.setEnclosureId(cmd.additionalProperties.get(KVMConstant.ENCLOSURE_DEVICE_ID).toString()); + cdata.setSlotNumber(cmd.additionalProperties.get(KVMConstant.SLOT_NUMBER).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_DISK_INSERT_TRIGGERED, cdata); + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.HOST_PHYSICAL_DISK_REMOVE_ALARM_EVENT, HostPhysicalDiskRemoveAlarmEventCmd.class, cmd -> { + HostCanonicalEvents.HostPhysicalDiskData cdata = new HostCanonicalEvents.HostPhysicalDiskData(); + cdata.setHostUuid(cmd.host); + cdata.setSerialNumber(cmd.additionalProperties.get(KVMConstant.DEVICE_SERIAL_NUMBER).toString()); + cdata.setEnclosureId(cmd.additionalProperties.get(KVMConstant.ENCLOSURE_DEVICE_ID).toString()); + cdata.setSlotNumber(cmd.additionalProperties.get(KVMConstant.SLOT_NUMBER).toString()); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_DISK_REMOVE_TRIGGERED, cdata); + return null; + }); + + restf.registerSyncHttpCallHandler(KVMConstant.HOST_PHYSICAL_MEMORY_ECC_ERROR_ALARM_EVENT, PhysicalMemoryEccErrorAlarmEventCmd.class, cmd -> { + HostCanonicalEvents.HostPhysicalMemoryEccErrorData cdata = new HostCanonicalEvents.HostPhysicalMemoryEccErrorData(); + cdata.setDetail(operr("host[uuid: %s] memory ecc triggered, detail: %s", cmd.host, cmd.detail)); + cdata.setHostUuid(cmd.host); + evf.fire(HostCanonicalEvents.HOST_PHYSICAL_MEMORY_ECC_ERROR_TRIGGERED, cdata); + return null; + }); + KVMSystemTags.CHECK_CLUSTER_CPU_MODEL.installValidator(((resourceUuid, resourceType, systemTag) -> { String check = KVMSystemTags.CHECK_CLUSTER_CPU_MODEL.getTokenByTag(systemTag, KVMSystemTags.CHECK_CLUSTER_CPU_MODEL_TOKEN); @@ -450,9 +803,47 @@ public String handleSyncHttpCall(KVMAgentCommands.ReportVmRebootEventCmd cmd) { } }); + KVMSystemTags.VOLUME_VIRTIO_SCSI.installLifeCycleListener(new SystemTagLifeCycleListener() { + @Override + public void tagCreated(SystemTagInventory tag) { + cleanDeviceAddress(tag); + } + + @Override + public void tagDeleted(SystemTagInventory tag) { + cleanDeviceAddress(tag); + } + + @Override + public void tagUpdated(SystemTagInventory old, SystemTagInventory newTag) { + + } + }); + + KVMSystemTags.VOLUME_VIRTIO_SCSI.installValidator(new SystemTagValidator() { + @Override + public void validateSystemTag(String resourceUuid, Class resourceType, String systemTag) { + VmInstanceVO vm = SQL.New("select vm from VmInstanceVO vm, VolumeVO volume " + + "where vm.uuid = volume.vmInstanceUuid and volume.uuid = :uuid", VmInstanceVO.class) + .param("uuid", resourceUuid) + .find(); + + if (vm != null && (vm.getState() == VmInstanceState.Running || vm.getState() == VmInstanceState.Unknown)) { + throw new OperationFailureException(argerr("vm current state[%s], " + + "modify virtioSCSI requires the vm state[%s]", vm.getState(), VmInstanceState.Stopped)); + } + + } + }); + return true; } + private void cleanDeviceAddress(SystemTagInventory tag) { + VolumeVO volume = dbf.findByUuid(tag.getResourceUuid(), VolumeVO.class); + vidm.deleteVmDeviceAddress(volume.getUuid(), volume.getVmInstanceUuid()); + } + private void configKVMDeviceType() { KVMVmDeviceType.New(VolumeVO.class.getSimpleName(), Collections.singletonList("disk"), (inventories, host) -> { List tos = new ArrayList(); @@ -463,49 +854,7 @@ private void configKVMDeviceType() { }); } - private void initGuestOsCategory() { - GuestOsCategory configs; - File guestOsCategoryFile = PathUtil.findFileOnClassPath(GUEST_OS_CATEGORY_FILE); - try { - JAXBContext context = JAXBContext.newInstance("org.zstack.core.config.schema"); - Unmarshaller unmarshaller = context.createUnmarshaller(); - configs = (GuestOsCategory) unmarshaller.unmarshal(guestOsCategoryFile); - } catch (Exception e){ - throw new CloudRuntimeException(e); - } - for (GuestOsCategory.Config config : configs.getOsInfo()) { - allGuestOsCategory.put(config.getOsRelease(), config); - if (!Q.New(GuestOsCategoryVO.class).eq(GuestOsCategoryVO_.osRelease, config.getOsRelease()).isExists()) { - GuestOsCategoryVO vo = new GuestOsCategoryVO(); - vo.setPlatform(config.getPlatform()); - vo.setName(config.getName()); - vo.setVersion(config.getVersion()); - vo.setOsRelease(config.getOsRelease()); - vo.setUuid(Platform.getUuid()); - dbf.persist(vo); - } - } - - //delete release not in config - SQL.New(GuestOsCategoryVO.class).notIn(GuestOsCategoryVO_.osRelease, allGuestOsCategory.keySet()).delete(); - } - - private void initGuestOsCharacter() { - GuestOsCharacter configs; - File guestOsCharacterFile = PathUtil.findFileOnClassPath(GUEST_OS_CHARACTER_FILE); - try { - JAXBContext context = JAXBContext.newInstance("org.zstack.core.config.schema"); - Unmarshaller unmarshaller = context.createUnmarshaller(); - configs = (GuestOsCharacter) unmarshaller.unmarshal(guestOsCharacterFile); - } catch (Exception e){ - throw new CloudRuntimeException(e); - } - for (GuestOsCharacter.Config config : configs.getOsInfo()) { - allGuestOsCharacter.put(String.format("%s_%s_%s", config.getArchitecture(), config.getPlatform(), config.getOsRelease()), config); - } - } - - private void startTcpChannelTimeoutChecker() { + private synchronized void startTcpChannelTimeoutChecker() { if (checkSocketChannelTimeoutThread != null) { checkSocketChannelTimeoutThread.cancel(true); } @@ -550,36 +899,30 @@ private boolean isTimeout(Long timeInMap, long currentTime) { @AsyncThread private void startTcpServer() throws IOException { - Selector selector = Selector.open(); - ServerSocketChannel serverSocket = ServerSocketChannel.open(); - serverSocket.bind(new InetSocketAddress("0.0.0.0", KVMGlobalProperty.TCP_SERVER_PORT)); - serverSocket.configureBlocking(false); - serverSocket.register(selector, SelectionKey.OP_ACCEPT); - ByteBuffer buffer = ByteBuffer.allocate(256); - - Integer interval = KVMGlobalConfig.CONNECTION_SERVER_UPDATE_INTERVAL.value(Integer.class); - while (true) { - if (!KVMGlobalConfig.ENABLE_HOST_TCP_CONNECTION_CHECK.value(Boolean.class)) { - serverSocket.close(); - selector.close(); - break; - } - - selector.select(interval); - Set selectedKeys = selector.selectedKeys(); - Iterator iter = selectedKeys.iterator(); - while (iter.hasNext()) { - SelectionKey key = iter.next(); - - if (key.isAcceptable()) { - register(selector, serverSocket); - } + try (Selector selector = Selector.open(); ServerSocketChannel serverSocket = ServerSocketChannel.open()) { + serverSocket.bind(new InetSocketAddress("0.0.0.0", KVMGlobalProperty.TCP_SERVER_PORT)); + serverSocket.configureBlocking(false); + serverSocket.register(selector, SelectionKey.OP_ACCEPT); + ByteBuffer buffer = ByteBuffer.allocate(256); + + Integer interval = KVMGlobalConfig.CONNECTION_SERVER_UPDATE_INTERVAL.value(Integer.class); + while (KVMGlobalConfig.ENABLE_HOST_TCP_CONNECTION_CHECK.value(Boolean.class)) { + selector.select(interval); + Set selectedKeys = selector.selectedKeys(); + Iterator iter = selectedKeys.iterator(); + while (iter.hasNext()) { + SelectionKey key = iter.next(); + + if (key.isAcceptable()) { + register(selector, serverSocket); + } - if (key.isReadable()) { - tryToRead(buffer, key); - } + if (key.isReadable()) { + tryToRead(buffer, key); + } - iter.remove(); + iter.remove(); + } } } } @@ -794,4 +1137,58 @@ public void run(List replies) { public String getId() { return bus.makeLocalServiceId(KVMConstant.SERVICE_ID); } + + @Override + public void validateGuestOsCharacter(GuestOsCharacter.Config config) { + if (config.getCpuModel() != null) { + try { + KVMGlobalConfig.NESTED_VIRTUALIZATION.validate(config.getCpuModel()); + } catch (GlobalConfigException e) { + throw new CloudRuntimeException(String.format("Invalid cpu model of config %s", JSONObjectUtil.toJsonString(config))); + } + } + + if (config.getNicDriver() == null) { + return; + } + + if (!vmNicManager.getSupportNicDriverTypes().contains(config.getNicDriver())) { + throw new CloudRuntimeException(String.format("Invalid nic driver of config %s, valid values are %s", JSONObjectUtil.toJsonString(config), vmNicManager.getSupportNicDriverTypes())); + } + } + + private Boolean isNeedAlarmNic(String hostUuid, String nicName, String bondName) { + boolean inUse = false; + String interfaceName; + List needAlarmServiceTypeList = + HostNetworkInterfaceServiceType.fromStrings(KVMGlobalProperty.HOST_NETWORK_NEED_ALARM_INTERFACE_SERVICE); + + if (StringUtils.isEmpty(bondName) || bondName.equals(KVMConstant.KVM_HOST_NETWORK_INTERFACE_DEFAULT)) { + if (StringUtils.isEmpty(nicName) || nicName.equals(KVMConstant.KVM_HOST_NETWORK_INTERFACE_DEFAULT)) { + return inUse; + } + interfaceName = nicName; + } else { + interfaceName = bondName; + } + logger.debug(String.format("Checking if alarm is needed for interface: %s on host: %s", interfaceName, hostUuid)); + for (ServiceTypeExtensionPoint ext : pluginRgty.getExtensionList(ServiceTypeExtensionPoint.class)) { + inUse = ext.checkHostServiceTypeExtensionPoint(hostUuid, interfaceName, needAlarmServiceTypeList); + } + if (inUse) { + return inUse; + } + + String hostClusterUuid = Q.New(HostVO.class).select(HostVO_.clusterUuid).eq(HostVO_.uuid, hostUuid).findValue(); + List l2Uuids = Q.New(L2NetworkClusterRefVO.class) + .select(L2NetworkClusterRefVO_.l2NetworkUuid) + .eq(L2NetworkClusterRefVO_.clusterUuid, hostClusterUuid) + .listValues(); + if (l2Uuids.isEmpty()) { + return inUse; + } + inUse = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.physicalInterface, interfaceName).in(L2NetworkVO_.uuid, l2Uuids).isExists(); + + return inUse; + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostInventory.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostInventory.java index 6137236fef2..a663e9197ed 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostInventory.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostInventory.java @@ -28,11 +28,20 @@ public class KVMHostInventory extends HostInventory { private Integer sshPort; + private String osDistribution; + + private String osRelease; + + private String osVersion; + protected KVMHostInventory(KVMHostVO vo) { super(vo); this.setUsername(vo.getUsername()); this.setPassword(vo.getPassword()); this.setSshPort(vo.getPort()); + this.setOsDistribution(vo.getOsDistribution()); + this.setOsRelease(vo.getOsRelease()); + this.setOsVersion(vo.getOsVersion()); } public KVMHostInventory() { @@ -73,4 +82,28 @@ public void setSshPort(Integer sshPort) { this.sshPort = sshPort; } + public String getOsDistribution() { + return osDistribution; + } + + public void setOsDistribution(String osDistribution) { + this.osDistribution = osDistribution; + } + + public String getOsRelease() { + return osRelease; + } + + public void setOsRelease(String osRelease) { + this.osRelease = osRelease; + } + + public String getOsVersion() { + return osVersion; + } + + public void setOsVersion(String osVersion) { + this.osVersion = osVersion; + } + } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostReconnectTaskFactory.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostReconnectTaskFactory.java index 9f9ca94d9fc..0d72fee4cf9 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostReconnectTaskFactory.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostReconnectTaskFactory.java @@ -4,13 +4,35 @@ import org.zstack.compute.host.HostReconnectTaskFactory; import org.zstack.core.Platform; import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostErrors; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; public class KVMHostReconnectTaskFactory implements HostReconnectTaskFactory { + protected static final CLogger logger = Utils.getLogger(KVMHostReconnectTaskFactory.class); + @Override public HostReconnectTask createTask(String uuid, NoErrorCompletion completion) { return Platform.New(() -> new KVMReconnectHostTask(uuid, completion)); } + @Override + public HostReconnectTask createTaskWithLastConnectError(String hostUuid, ErrorCode errorCode, NoErrorCompletion completion) { + if (errorCode.getRootCause().isError(HostErrors.HOST_PASSWORD_HAS_BEEN_CHANGED)) { + logger.warn(String.format( + "stop tracking host[uuid:%s] until its password is updated correctly", hostUuid)); + + return Platform.New(() -> new KVMReconnectHostTask(hostUuid, completion) { + @Override + protected CanDoAnswer canDoReconnect() { + return CanDoAnswer.NoReconnect; + } + }); + } + return HostReconnectTaskFactory.super.createTaskWithLastConnectError(hostUuid, errorCode, completion); + } + @Override public String getHypervisorType() { return KVMConstant.KVM_HYPERVISOR_TYPE; diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostUtils.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostUtils.java index 44a73c49a1b..cf6d16e7560 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostUtils.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostUtils.java @@ -2,14 +2,18 @@ import org.apache.commons.codec.digest.DigestUtils; import org.zstack.core.db.Q; -import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.header.network.l2.*; +import org.zstack.header.tag.SystemTagVO; +import org.zstack.header.tag.SystemTagVO_; +import org.zstack.header.tag.TagType; +import org.zstack.utils.TagUtils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.logging.CLoggerImpl; -import static org.zstack.core.Platform.operr; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * Created by GuoYi on 4/16/20. @@ -20,6 +24,8 @@ public class KVMHostUtils { /** * Get normalized bridge name for l2 network, which at most has 15 chars. * - if l2 network has L2_BRIDGE_NAME tag, then return it's value directly; + * - if l2Uuid does not have an L2_BRIDGE_NAME tag and conflict with existing bridge name, + * use the new naming convention : prefix 'l2_' plus the last 12 characters of l2Uuid; * - if l2 physical interface name is short, then no need for truncation; * - otherwise, get md5sum of interface name and use the top chars. * @param l2Uuid l2 network uuid @@ -27,25 +33,72 @@ public class KVMHostUtils { * @return normalized bridge name, or null if anything wrong */ public static String getNormalizedBridgeName(String l2Uuid, String format) { - if (KVMSystemTags.L2_BRIDGE_NAME.hasTag(l2Uuid, L2NetworkVO.class)) { - return KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2Uuid, KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + String current = KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2Uuid, KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + if (current != null) { + return current; } + validateFormatString(format); + + String physicalInterface = getPhysicalInterface(l2Uuid, format); + String preferredBridgeName = String.format(format, physicalInterface); + + if (!checkNameConflict(l2Uuid, preferredBridgeName)) { + return preferredBridgeName; + } + + current = KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2Uuid, KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + if (current != null) { + return current; + } + + return generateNewBridgeName(l2Uuid); + } + + private static void validateFormatString(String format) { if (!format.contains("%s") || format.indexOf("%s") != format.lastIndexOf("%s")) { - throw new OperationFailureException(operr("invalid format string %s", format)); + throw new IllegalArgumentException(String.format("invalid format string: %s", format)); } + } - int allowedLen = L2NetworkConstant.LINUX_IF_NAME_MAX_SIZE - format.length() + "%s".length(); + private static String generateNewBridgeName(String l2Uuid) { + return "l2_" + l2Uuid.substring(0, Math.min(l2Uuid.length(), 12)); + } + private static String getPhysicalInterface(String l2Uuid, String format) { String physicalInterface = Q.New(L2NetworkVO.class) .eq(L2NetworkVO_.uuid, l2Uuid) .select(L2NetworkVO_.physicalInterface) .findValue(); + int allowedLen = L2NetworkConstant.LINUX_IF_NAME_MAX_SIZE - format.length() + 2; // "%s" length is 2 + if (physicalInterface != null && physicalInterface.length() > allowedLen) { physicalInterface = DigestUtils.md5Hex(physicalInterface).substring(0, allowedLen); } + return physicalInterface; + } + + public static Boolean checkNameConflict(String l2Uuid, String bridgeName) { + String pattern = TagUtils.tagPatternToSqlPattern(KVMSystemTags.L2_BRIDGE_NAME.instantiateTag( + Collections.singletonMap(KVMSystemTags.L2_BRIDGE_NAME_TOKEN, bridgeName) + )); + List clusterUuids = Q.New(L2NetworkClusterRefVO.class) + .select(L2NetworkClusterRefVO_.clusterUuid) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, l2Uuid).listValues(); + if (clusterUuids.isEmpty()) { + return Boolean.FALSE; + } + Set relatedL2Uuids = new HashSet<>(Q.New(L2NetworkClusterRefVO.class) + .select(L2NetworkClusterRefVO_.l2NetworkUuid) + .in(L2NetworkClusterRefVO_.clusterUuid, clusterUuids).listValues()); + List tags = Q.New(SystemTagVO.class) + .in(SystemTagVO_.resourceUuid, relatedL2Uuids) + .eq(SystemTagVO_.resourceType, L2NetworkVO.class.getSimpleName()) + .like(SystemTagVO_.tag, pattern) + .eq(SystemTagVO_.type, TagType.System) + .list(); - return String.format(format, physicalInterface); + return !tags.isEmpty(); } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO.java index 24b695d4338..9d3b7166766 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO.java @@ -1,6 +1,7 @@ package org.zstack.kvm; import org.zstack.core.convert.PasswordConverter; +import org.zstack.header.core.encrypt.EncryptColumn; import org.zstack.header.host.HostEO; import org.zstack.header.host.HostVO; import org.zstack.header.vo.EO; @@ -14,7 +15,8 @@ public class KVMHostVO extends HostVO { @Column private String username; - + + @EncryptColumn @Column @Convert(converter = PasswordConverter.class) private String password; @@ -22,6 +24,15 @@ public class KVMHostVO extends HostVO { @Column private Integer port; + @Column + private String osDistribution; + + @Column + private String osRelease; + + @Column + private String osVersion; + public KVMHostVO() { } @@ -53,5 +64,28 @@ public void setPort(Integer port) { this.port = port; } + public String getOsDistribution() { + return osDistribution; + } + + public void setOsDistribution(String osDistribution) { + this.osDistribution = osDistribution; + } + + public String getOsRelease() { + return osRelease; + } + + public void setOsRelease(String osRelease) { + this.osRelease = osRelease; + } + + public String getOsVersion() { + return osVersion; + } + + public void setOsVersion(String osVersion) { + this.osVersion = osVersion; + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO_.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO_.java index 90771a7d61c..4101e992bb3 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO_.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMHostVO_.java @@ -13,4 +13,7 @@ public class KVMHostVO_ extends HostVO_ { //cannot get password by using this method,because password is encrypted public static volatile SingularAttribute password; public static volatile SingularAttribute port; + public static volatile SingularAttribute osDistribution; + public static volatile SingularAttribute osRelease; + public static volatile SingularAttribute osVersion; } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java index 3d5ce9f8e15..9ec57078f6e 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2NoVlanNetworkBackend.java @@ -4,9 +4,14 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.Q; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; import org.zstack.header.core.Completion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; import org.zstack.header.host.HypervisorType; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.*; @@ -18,12 +23,15 @@ import org.zstack.kvm.KVMAgentCommands.DeleteBridgeCmd; import org.zstack.kvm.KVMAgentCommands.DeleteBridgeResponse; import org.zstack.kvm.KVMAgentCommands.NicTO; +import org.zstack.network.l2.L2NetworkGlobalConfig; import org.zstack.network.l3.NetworkGlobalProperty; import org.zstack.network.service.MtuGetter; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import java.util.List; + import static org.zstack.core.Platform.operr; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -34,6 +42,9 @@ public class KVMRealizeL2NoVlanNetworkBackend implements L2NetworkRealizationExt @Autowired private CloudBus bus; + @Autowired + private ThreadFacade thdf; + private static String makeBridgeName(String l2Uuid) { return KVMHostUtils.getNormalizedBridgeName(l2Uuid, "br_%s"); } @@ -45,6 +56,9 @@ public void realize(final L2NetworkInventory l2Network, final String hostUuid, b cmd.setL2NetworkUuid(l2Network.getUuid()); cmd.setDisableIptables(NetworkGlobalProperty.BRIDGE_DISABLE_IPTABLES); cmd.setMtu(new MtuGetter().getL2Mtu(l2Network)); + cmd.setIsolated(l2Network.getIsolated()); + cmd.setIgmpVersion(L2NetworkGlobalConfig.IGMPVersion.value(Integer.class)); + cmd.setMldVersion(L2NetworkGlobalConfig.MLDVersion.value(Integer.class)); KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setCommand(cmd); @@ -100,6 +114,57 @@ public void realize(final L2NetworkInventory l2Network, final String hostUuid, f realize(l2Network, hostUuid, false, completion); } + @Override + public void update(L2NetworkInventory oldL2, L2NetworkInventory newL2, String hostUuid, Completion completion) { + final KVMAgentCommands.UpdateL2NetworkCmd cmd = new KVMAgentCommands.UpdateL2NetworkCmd(); + + cmd.setL2NetworkUuid(newL2.getUuid()); + cmd.setBridgeName(makeBridgeName(newL2.getUuid())); + cmd.setPhysicalInterfaceName(newL2.getPhysicalInterface()); + + if (L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(oldL2.getType()) && + L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(newL2.getType())) { + cmd.setNewVlan(newL2.getVirtualNetworkId().toString()); + } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(oldL2.getType()) && + L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(newL2.getType())) { + cmd.setOldVlan(oldL2.getVirtualNetworkId().toString()); + } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(oldL2.getType()) && + L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(newL2.getType())) { + cmd.setNewVlan(newL2.getVirtualNetworkId().toString()); + cmd.setOldVlan(oldL2.getVirtualNetworkId().toString()); + } + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setNoStatusCheck(false); + msg.setCommand(cmd); + msg.setHostUuid(hostUuid); + msg.setPath(KVMConstant.KVM_UPDATE_L2VLAN_NETWORK_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply hreply = reply.castReply(); + KVMAgentCommands.UpdateL2NetworkResponse rsp = hreply.toResponse(KVMAgentCommands.UpdateL2NetworkResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to update bridge[%s] for l2Network[uuid:%s, name:%s] on kvm host[uuid: %s], %s", + cmd.getBridgeName(), newL2.getUuid(), newL2.getName(), hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String info = String.format("successfully update bridge[%s] for l2Network[uuid:%s, name:%s] on kvm host[uuid: %s]", + cmd.getBridgeName(), newL2.getUuid(), newL2.getName(), hostUuid); + logger.debug(info); + completion.success(); + } + }); + } + public void check(final L2NetworkInventory l2Network, final String hostUuid, boolean noStatusCheck, final Completion completion, final String cmdPath) { final KVMAgentCommands.CheckBridgeCmd cmd = new KVMAgentCommands.CheckBridgeCmd(); cmd.setPhysicalInterfaceName(l2Network.getPhysicalInterface()); @@ -155,23 +220,24 @@ public HypervisorType getSupportedHypervisorType() { return HypervisorType.valueOf(KVMConstant.KVM_HYPERVISOR_TYPE); } + @Override + public VSwitchType getSupportedVSwitchType() { + return VSwitchType.valueOf(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + } + @Override public L2NetworkType getL2NetworkTypeVmNicOn() { return L2NetworkType.valueOf(L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE); } - @Override public NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { - NicTO to = new NicTO(); - to.setMac(nic.getMac()); - to.setUuid(nic.getUuid()); + NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); to.setBridgeName(makeBridgeName(l2Network.getUuid())); to.setPhysicalInterface(l2Network.getPhysicalInterface()); - to.setDeviceId(nic.getDeviceId()); - to.setNicInternalName(nic.getInternalName()); - to.setType(nic.getType()); - to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); + if (l2Network.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVN_DPDK)) { + to.setSrcPath(L2NetworkConstant.OVN_DPDK_VNIC_SRC_PATH + nic.getInternalName()); + } return to; } @@ -224,19 +290,74 @@ public void run(MessageReply reply) { @Override public void delete(L2NetworkInventory l2Network, String hostUuid, Completion completion) { if (l2Network.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK)) { - // vlan bridges and novlan bridge use the same bridge name - // in ovs, so before delete l2 network we should check if - // the PhysicalInterface is using by another l2 network. - boolean noNeedDelete = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.physicalInterface, l2Network.getPhysicalInterface()) - .notEq(L2NetworkVO_.uuid, l2Network.getUuid()).isExists(); - if (noNeedDelete) { - completion.success(); - return; - } - delete(l2Network, hostUuid, completion, KVMConstant.KVM_DELETE_OVSDPDK_NETWORK_PATH); + deleteOvsBridge(l2Network, hostUuid, completion); } else { delete(l2Network, hostUuid, completion, KVMConstant.KVM_DELETE_L2NOVLAN_NETWORK_PATH); } } + private void deleteOvsBridge(L2NetworkInventory l2Network, String hostUuid, Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public void run(SyncTaskChain chain) { + // vlan bridges and novlan bridge use the same bridge name + // in ovs, so before delete l2 network we should check if + // the PhysicalInterface is using by another l2 network. + List l2NetworkVOs = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.physicalInterface, l2Network.getPhysicalInterface()) + .notEq(L2NetworkVO_.uuid, l2Network.getUuid()).list(); + + if (l2NetworkVOs.isEmpty()) { + delete(l2Network, hostUuid, new Completion(completion) { + @Override + public void success() { + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }, KVMConstant.KVM_DELETE_OVSDPDK_NETWORK_PATH); + return; + } + boolean noNeedDelete = false; + String clusterUuid = Q.New(HostVO.class).eq(HostVO_.uuid, hostUuid).select(HostVO_.clusterUuid).findValue(); + for (L2NetworkVO l2 : l2NetworkVOs) { + boolean anotherl2AttachCluster = l2.getAttachedClusterRefs().stream().anyMatch(ref -> ref.getClusterUuid().equals(clusterUuid)); + if (anotherl2AttachCluster) { + noNeedDelete = true; + break; + } + } + if (noNeedDelete) { + completion.success(); + chain.next(); + return; + } + delete(l2Network, hostUuid, new Completion(completion) { + @Override + public void success() { + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }, KVMConstant.KVM_DELETE_OVSDPDK_NETWORK_PATH); + } + @Override + public String getSyncSignature() { + return String.format("delete-ovsbridge-interface-%s-in-host-%s",l2Network.getPhysicalInterface(),hostUuid); + } + @Override + public String getName() { + return getSyncSignature(); + } + }); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java index d24511fecdf..15c0214c538 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMRealizeL2VlanNetworkBackend.java @@ -7,6 +7,8 @@ import org.zstack.header.core.Completion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; import org.zstack.header.host.HypervisorType; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.*; @@ -24,6 +26,8 @@ import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import java.util.List; + import static org.zstack.core.Platform.operr; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -57,6 +61,8 @@ public void realize(final L2NetworkInventory l2Network, final String hostUuid, b cmd.setL2NetworkUuid(l2Network.getUuid()); cmd.setDisableIptables(NetworkGlobalProperty.BRIDGE_DISABLE_IPTABLES); cmd.setMtu(new MtuGetter().getL2Mtu(l2Network)); + cmd.setIsolated(l2vlan.getIsolated()); + cmd.setPvlan(l2vlan.getPvlan()); KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(hostUuid); @@ -149,6 +155,57 @@ public void run(MessageReply reply) { }); } + @Override + public void update(L2NetworkInventory oldL2, L2NetworkInventory newL2, String hostUuid, Completion completion) { + final KVMAgentCommands.UpdateL2NetworkCmd cmd = new KVMAgentCommands.UpdateL2NetworkCmd(); + + cmd.setL2NetworkUuid(newL2.getUuid()); + cmd.setBridgeName(makeBridgeName(newL2.getUuid(), oldL2.getVirtualNetworkId())); + cmd.setPhysicalInterfaceName(newL2.getPhysicalInterface()); + + if (L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(oldL2.getType()) && + L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(newL2.getType())) { + cmd.setNewVlan(newL2.getVirtualNetworkId().toString()); + } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(oldL2.getType()) && + L2NetworkConstant.L2_NO_VLAN_NETWORK_TYPE.equals(newL2.getType())) { + cmd.setOldVlan(oldL2.getVirtualNetworkId().toString()); + } else if (L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(oldL2.getType()) && + L2NetworkConstant.L2_VLAN_NETWORK_TYPE.equals(newL2.getType())) { + cmd.setNewVlan(newL2.getVirtualNetworkId().toString()); + cmd.setOldVlan(oldL2.getVirtualNetworkId().toString()); + } + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setNoStatusCheck(false); + msg.setCommand(cmd); + msg.setHostUuid(hostUuid); + msg.setPath(KVMConstant.KVM_UPDATE_L2VLAN_NETWORK_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply hreply = reply.castReply(); + KVMAgentCommands.UpdateL2NetworkResponse rsp = hreply.toResponse(KVMAgentCommands.UpdateL2NetworkResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to update bridge[%s] for l2Network[uuid:%s, name:%s] on kvm host[uuid: %s], %s", + cmd.getBridgeName(), newL2.getUuid(), newL2.getName(), hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String info = String.format("successfully update bridge[%s] for l2Network[uuid:%s, name:%s] on kvm host[uuid: %s]", + cmd.getBridgeName(), newL2.getUuid(), newL2.getName(), hostUuid); + logger.debug(info); + completion.success(); + } + }); + } + public void check(final L2NetworkInventory l2Network, final String hostUuid, boolean noStatusCheck, final Completion completion) { if (l2Network.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVS_DPDK)) { realize(l2Network, hostUuid, false, completion, KVMConstant.KVM_CHECK_OVSDPDK_NETWORK_PATH); @@ -172,25 +229,28 @@ public HypervisorType getSupportedHypervisorType() { return HypervisorType.valueOf(KVMConstant.KVM_HYPERVISOR_TYPE); } - @Override + @Override + public VSwitchType getSupportedVSwitchType() { + return VSwitchType.valueOf(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + } + + @Override public L2NetworkType getL2NetworkTypeVmNicOn() { return getSupportedL2NetworkType(); } - @Override + @Override public NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { final Integer vlanId = getVlanId(l2Network.getUuid()); - NicTO to = new NicTO(); - to.setMac(nic.getMac()); - to.setUuid(nic.getUuid()); + NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); to.setBridgeName(makeBridgeName(l2Network.getUuid(), vlanId)); to.setPhysicalInterface(l2Network.getPhysicalInterface()); - to.setDeviceId(nic.getDeviceId()); - to.setNicInternalName(nic.getInternalName()); to.setMetaData(String.valueOf(vlanId)); to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); - to.setType(nic.getType()); to.setVlanId(String.valueOf(vlanId)); + if (l2Network.getvSwitchType().equals(L2NetworkConstant.VSWITCH_TYPE_OVN_DPDK)) { + to.setSrcPath(L2NetworkConstant.OVN_DPDK_VNIC_SRC_PATH + nic.getInternalName()); + } return to; } @@ -254,8 +314,25 @@ public void delete(L2NetworkInventory l2Network, String hostUuid, Completion com // vlan bridges and novlan bridge use the same bridge name // in ovs, so before delete l2 network we should check if // the PhysicalInterface is using by another l2 network. - boolean noNeedDelete = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.physicalInterface, l2Network.getPhysicalInterface()) - .notEq(L2NetworkVO_.uuid, l2Network.getUuid()).isExists(); + //if another l2 attach l2,need to delete l2 in host + List l2NetworkVOs = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.physicalInterface, l2Network.getPhysicalInterface()) + .notEq(L2NetworkVO_.uuid, l2Network.getUuid()).list(); + + if (l2NetworkVOs.isEmpty()) { + delete(l2Network, hostUuid, completion, KVMConstant.KVM_DELETE_OVSDPDK_NETWORK_PATH); + return; + } + + boolean noNeedDelete = false; + String clusterUuid = Q.New(HostVO.class).eq(HostVO_.uuid, hostUuid).select(HostVO_.clusterUuid).findValue(); + for (L2NetworkVO l2 : l2NetworkVOs) { + boolean anotherl2AttachCluster = l2.getAttachedClusterRefs().stream().anyMatch(ref -> ref.getClusterUuid().equals(clusterUuid)); + if (anotherl2AttachCluster) { + noNeedDelete = true; + break; + } + } + if (noNeedDelete) { completion.success(); return; diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMRebootVmExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMRebootVmExtensionPoint.java index 258822a7a32..f34ebc54a1d 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMRebootVmExtensionPoint.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMRebootVmExtensionPoint.java @@ -6,7 +6,7 @@ public interface KVMRebootVmExtensionPoint { void beforeRebootVmOnKvm(KVMHostInventory host, VmInstanceInventory vm) throws KVMException; - void rebootVmOnKvmSuccess(KVMHostInventory host, VmInstanceInventory vm); + void rebootVmOnKvmSuccess(KVMHostInventory host, VmInstanceInventory vm, KVMAgentCommands.RebootVmResponse ret); void rebootVmOnKvmFailed(KVMHostInventory host, VmInstanceInventory vm, ErrorCode err); } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMReconnectHostTask.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMReconnectHostTask.java index cb98c29a5ff..9a66d7f0127 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMReconnectHostTask.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMReconnectHostTask.java @@ -4,6 +4,8 @@ import org.zstack.core.CoreGlobalProperty; import org.zstack.core.db.Q; import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostErrors; import org.zstack.utils.network.NetworkUtils; import javax.persistence.Tuple; @@ -31,4 +33,16 @@ protected CanDoAnswer canDoReconnect() { return NetworkUtils.isRemotePortOpen(ip, port, (int) TimeUnit.SECONDS.toMillis(2)) ? CanDoAnswer.Ready : CanDoAnswer.NotReady; } + + @Override + protected void whenConnectFail(ErrorCode errorCode) { + if (errorCode.getRootCause().isError(HostErrors.HOST_PASSWORD_HAS_BEEN_CHANGED)) { + logger.warn(String.format( + "stop reconnecting to the host[uuid:%s] until its password is updated correctly", uuid)); + completion.done(); + return; + } + + super.whenConnectFail(errorCode); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java index 0d2c37bcd72..410c23dbc7b 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSecurityGroupBackend.java @@ -6,12 +6,8 @@ import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.core.Completion; -import org.zstack.header.core.workflow.Flow; -import org.zstack.header.core.workflow.FlowTrigger; -import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.host.HostConstant; -import org.zstack.header.host.HypervisorType; +import org.zstack.header.host.*; import org.zstack.header.message.MessageReply; import org.zstack.kvm.KVMAgentCommands.ApplySecurityGroupRuleCmd; import org.zstack.kvm.KVMAgentCommands.CheckDefaultSecurityGroupCmd; @@ -27,9 +23,7 @@ import static java.util.Arrays.asList; import static org.zstack.core.Platform.operr; -import java.util.Map; - -public class KVMSecurityGroupBackend implements SecurityGroupHypervisorBackend, KVMHostConnectExtensionPoint { +public class KVMSecurityGroupBackend implements SecurityGroupHypervisorBackend, HostAfterConnectedExtensionPoint { private static CLogger logger = Utils.getLogger(KVMSecurityGroupBackend.class); public static final String SECURITY_GROUP_APPLY_RULE_PATH = "/securitygroup/applyrules"; @@ -47,11 +41,10 @@ public class KVMSecurityGroupBackend implements SecurityGroupHypervisorBackend, private void incrementallyApplyRules(final HostRuleTO hto, final Completion complete) { ApplySecurityGroupRuleCmd cmd = new ApplySecurityGroupRuleCmd(); - if (!hto.getRules().isEmpty()) { + if (!hto.getVmNics().isEmpty()) { + cmd.setVmNicTOs(hto.getVmNics()); cmd.setRuleTOs(hto.getRules()); - } - if (!hto.getIpv6Rules().isEmpty()) { - cmd.setIpv6RuleTOs(hto.getIpv6Rules()); + cmd.setIp6RuleTOs(hto.getIp6Rules()); } KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); @@ -84,11 +77,10 @@ public void run(MessageReply reply) { private void reApplyAllRulesOnHost(final HostRuleTO hto, final Completion complete) { RefreshAllRulesOnHostCmd cmd = new RefreshAllRulesOnHostCmd(); - if (!hto.getRules().isEmpty()) { + if (!hto.getVmNics().isEmpty()) { + cmd.setVmNicTOs(hto.getVmNics()); cmd.setRuleTOs(hto.getRules()); - } - if (!hto.getIpv6Rules().isEmpty()) { - cmd.setIpv6RuleTOs(hto.getIpv6Rules()); + cmd.setIp6RuleTOs(hto.getIp6Rules()); } KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); @@ -132,7 +124,7 @@ public void applyRules(final HostRuleTO hto, final Completion complete) { @Override public void checkDefaultRules(String hostUuid, Completion completion) { CheckDefaultSecurityGroupCmd cmd = new CheckDefaultSecurityGroupCmd(); - cmd.skipIpv6 = NetworkGlobalProperty.SKIP_IPV6; + cmd.disableIp6Tables = NetworkGlobalProperty.SKIP_IPV6 || NetworkGlobalProperty.BRIDGE_DISABLE_IP6TABLES; KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(hostUuid); @@ -196,7 +188,7 @@ public void run(MessageReply reply) { @Override public void cleanUpUnusedRuleOnHost(String hostUuid, final Completion completion) { KVMAgentCommands.CleanupUnusedRulesOnHostCmd cmd = new KVMAgentCommands.CleanupUnusedRulesOnHostCmd(); - cmd.skipIpv6 = NetworkGlobalProperty.SKIP_IPV6; + cmd.disableIp6Tables = NetworkGlobalProperty.SKIP_IPV6 || NetworkGlobalProperty.BRIDGE_DISABLE_IP6TABLES; KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(hostUuid); msg.setCommand(cmd); @@ -228,18 +220,18 @@ public HypervisorType getSecurityGroupBackendHypervisorType() { } @Override - public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { - return new NoRollbackFlow() { - String __name__ = "refresh-security-group-on-host"; - + public void afterHostConnected(HostInventory host) { + RefreshSecurityGroupRulesOnHostMsg msg = new RefreshSecurityGroupRulesOnHostMsg(); + msg.setHostUuid(host.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, host.getUuid()); + bus.send(msg, new CloudBusCallBack(msg) { @Override - public void run(FlowTrigger trigger, Map data) { - RefreshSecurityGroupRulesOnHostMsg msg = new RefreshSecurityGroupRulesOnHostMsg(); - msg.setHostUuid(context.getInventory().getUuid()); - bus.makeLocalServiceId(msg, SecurityGroupConstant.SERVICE_ID); - bus.send(msg); - trigger.next(); + public void run(MessageReply r) { + if (!r.isSuccess()) { + logger.warn(String.format("refresh seruity group on host[uuid:%s] failed: %s", + host.getUuid(), r.getError().toString())); + } } - }; + }); } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMStartVmExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMStartVmExtensionPoint.java index 477529e151f..1f3548c3bf0 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMStartVmExtensionPoint.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMStartVmExtensionPoint.java @@ -8,6 +8,6 @@ public interface KVMStartVmExtensionPoint { void beforeStartVmOnKvm(KVMHostInventory host, VmInstanceSpec spec, StartVmCmd cmd); void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec); - + void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err); } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSubTypeVmConfigurationFactory.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSubTypeVmConfigurationFactory.java new file mode 100644 index 00000000000..a183b2c96a5 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSubTypeVmConfigurationFactory.java @@ -0,0 +1,9 @@ +package org.zstack.kvm; + +import org.zstack.header.vm.VmInstanceSpec; + +public interface KVMSubTypeVmConfigurationFactory { + String getVmInstanceType(); + + void createConfigurations(VmInstanceSpec spec); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSyncVmDeviceInfoExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSyncVmDeviceInfoExtensionPoint.java new file mode 100644 index 00000000000..4f27a6fe18e --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSyncVmDeviceInfoExtensionPoint.java @@ -0,0 +1,13 @@ +package org.zstack.kvm; + +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceSpec; + +/** + * @Author: DaoDao + * @Date: 2022/7/26 + */ +public interface KVMSyncVmDeviceInfoExtensionPoint { + default void afterReceiveVmDeviceInfoResponse(VmInstanceInventory vm, KVMAgentCommands.VmDevicesInfoResponse rsp, VmInstanceSpec spec) { + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java index d184f62fdb1..d1dc3a495e8 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java @@ -7,6 +7,7 @@ import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmNicVO; import org.zstack.header.volume.VolumeVO; +import org.zstack.kvm.xmlhook.XmlHookVO; import org.zstack.tag.PatternedSystemTag; import org.zstack.tag.SystemTag; @@ -20,6 +21,11 @@ public class KVMSystemTags { public static final String LIBVIRT_VERSION_TOKEN = "version"; public static PatternedSystemTag LIBVIRT_VERSION = new PatternedSystemTag(String.format("libvirt::version::{%s}", LIBVIRT_VERSION_TOKEN), HostVO.class); + public static final String LIBVIRT_PACKAGE_VERSION_TOKEN = "version"; + public static PatternedSystemTag LIBVIRT_PACKAGE_VERSION = new PatternedSystemTag(String.format("libvirt::package::version::{%s}", LIBVIRT_PACKAGE_VERSION_TOKEN), HostVO.class); + + public static SystemTag FORCE_DEPLOYMENT_ONCE = new SystemTag("force::deployment::once", HostVO.class); + public static final String HVM_CPU_FLAG_TOKEN = "flag"; public static PatternedSystemTag HVM_CPU_FLAG = new PatternedSystemTag(String.format("hvm::{%s}", HVM_CPU_FLAG_TOKEN), HostVO.class); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KVMVmConfigurationFactory.java b/plugin/kvm/src/main/java/org/zstack/kvm/KVMVmConfigurationFactory.java new file mode 100644 index 00000000000..c4052e0a809 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KVMVmConfigurationFactory.java @@ -0,0 +1,61 @@ +package org.zstack.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.Component; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.vm.HypervisorBasedVmConfigurationFactory; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.HashMap; +import java.util.Map; + +public class KVMVmConfigurationFactory implements HypervisorBasedVmConfigurationFactory, Component { + private static final CLogger logger = Utils.getLogger(KVMVmConfigurationFactory.class); + + @Autowired + private PluginRegistry pluginRgty; + + private final Map kvmSubTypeVmConfigurationFactoryMap = new HashMap<>(); + + @Override + public String getHypervisorType() { + return KVMHostFactory.hypervisorType.toString(); + } + + @Override + public void createVmConfigurations(VmInstanceSpec spec) { + KVMSubTypeVmConfigurationFactory factory = kvmSubTypeVmConfigurationFactoryMap.get(spec.getVmInventory().getType()); + if (factory == null) { + logger.debug(String.format("no available KVMVmConfigurationFactory found for vm[uuid: %s, type: %s, hypervisor: %s]," + + " skip vm configuration", spec.getVmInventory().getUuid(), spec.getVmInventory().getType(), + spec.getDestHost().getHypervisorType())); + return; + } + factory.createConfigurations(spec); + } + + private void populateExtensions() { + for (KVMSubTypeVmConfigurationFactory ext : pluginRgty.getExtensionList(KVMSubTypeVmConfigurationFactory.class)) { + KVMSubTypeVmConfigurationFactory old = kvmSubTypeVmConfigurationFactoryMap.get(ext.getVmInstanceType()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VmInstanceFactory[%s, %s] for vm of type[%s]", + old.getClass().getName(), ext.getClass().getName(), ext.getVmInstanceType())); + } + kvmSubTypeVmConfigurationFactoryMap.put(ext.getVmInstanceType(), ext); + } + } + + @Override + public boolean start() { + populateExtensions(); + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHardwareStatusHandlerExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHardwareStatusHandlerExtensionPoint.java new file mode 100644 index 00000000000..ced5d78edb5 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHardwareStatusHandlerExtensionPoint.java @@ -0,0 +1,7 @@ +package org.zstack.kvm; + +import org.zstack.header.host.HostHardware; + +public interface KvmHardwareStatusHandlerExtensionPoint { + void handleKvmHardwareStatus(HostHardware hostHardwareType, KVMAgentCommands.HostPhysicalDeviceStatusAlarmEventCmd cmd); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostAgentDeploymentExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostAgentDeploymentExtensionPoint.java new file mode 100644 index 00000000000..a338a900cba --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostAgentDeploymentExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.kvm; + +import org.zstack.header.host.HostInventory; + +import java.util.List; + +public interface KvmHostAgentDeploymentExtensionPoint { + List appendExtraPackages(HostInventory host); + + void modifyDeploymentArguments(HostInventory host, KVMHostDeployArguments args); +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostConfigChecker.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostConfigChecker.java new file mode 100644 index 00000000000..79709692a12 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostConfigChecker.java @@ -0,0 +1,172 @@ +package org.zstack.kvm; + +import org.apache.logging.log4j.util.Strings; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.ansible.AnsibleChecker; +import org.zstack.utils.RangeSet; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.ssh.Ssh; +import org.zstack.utils.ssh.SshResult; + +import java.util.Objects; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class KvmHostConfigChecker implements AnsibleChecker { + private static final CLogger logger = Utils.getLogger(KvmHostConfigChecker.class); + + private String username; + private String password; + private String privateKey; + private String targetIp; + private String requireKsmCheck; + private String requireReservePorts; + private int sshPort = 22; + + @Override + public boolean needDeploy() { + return needDeployKsmCheck() || needDeployReservePorts(); + } + + private boolean needDeployKsmCheck() { + if ("none".equals(requireKsmCheck)) { + return false; + } + + Ssh ssh = new Ssh(); + ssh.setUsername(username).setPrivateKey(privateKey) + .setPassword(password).setPort(sshPort) + .setHostname(targetIp); + try { + ssh.sudoCommand("cat /sys/kernel/mm/ksm/run"); + SshResult ret = ssh.setTimeout(60).runAndClose(); + if (ret.getReturnCode() != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); + return true; + } + + boolean ksmEnabledOnHost = "1".equals(ret.getStdout()); + if (ksmEnabledOnHost && "true".equals(requireKsmCheck)) { + return false; + } + + if (!ksmEnabledOnHost && "false".equals(requireKsmCheck)) { + return false; + } + + logger.debug(String.format("KSM status is %s (%s), but requireKsmCheck is %s, need to re-deploy", + ret.getStdout(), + ksmEnabledOnHost ? "enabled" : "disabled", + requireKsmCheck) + ); + + ssh.reset(); + } finally { + ssh.close(); + } + + return true; + } + + private boolean needDeployReservePorts() { + if (Strings.isEmpty(requireReservePorts)) { + return false; + } + + Ssh ssh = new Ssh(); + ssh.setUsername(username).setPrivateKey(privateKey) + .setPassword(password).setPort(sshPort) + .setHostname(targetIp); + try { + ssh.sudoCommand("cat /proc/sys/net/ipv4/ip_local_reserved_ports"); + SshResult ret = ssh.setTimeout(60).runAndClose(); + if (ret.getReturnCode() != 0) { + logger.warn(String.format("exec ssh command failed, return code: %d, stdout: %s, stderr: %s", + ret.getReturnCode(), ret.getStdout(), ret.getStderr())); + return true; + } + String reservedPorts = ret.getStdout(); + RangeSet cur = RangeSet.valueOf(reservedPorts.trim()); + RangeSet expect = RangeSet.valueOf(requireReservePorts.trim()); + + for (RangeSet.Range range : cur.getRanges()) { + expect.closed(range.getStart(), range.getEnd()); + } + + cur.mergeAndSort(); + expect.mergeAndSort(); + + if (!Objects.equals(cur.getRanges(), expect.getRanges())) { + logger.debug(String.format("Reserved ports are not the same, need to deploy, current: %s, expect: %s", + cur.getRanges(), expect.getRanges())); + return true; + } + return false; + } finally { + ssh.close(); + } + } + + @Override + public void deleteDestFile() { + + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public String getTargetIp() { + return targetIp; + } + + public void setTargetIp(String targetIp) { + this.targetIp = targetIp; + } + + public String getRequireKsmCheck() { + return requireKsmCheck; + } + + public void setRequireKsmCheck(String requireKsmCheck) { + this.requireKsmCheck = requireKsmCheck; + } + + public String getRequireReservePorts() { + return requireReservePorts; + } + + public void setRequireReservePorts(String requireReservePorts) { + this.requireReservePorts = requireReservePorts; + } + + public int getSshPort() { + return sshPort; + } + + public void setSshPort(int sshPort) { + this.sshPort = sshPort; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostIpmiPowerExecutor.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostIpmiPowerExecutor.java new file mode 100644 index 00000000000..025d3913729 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostIpmiPowerExecutor.java @@ -0,0 +1,74 @@ +package org.zstack.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.host.HostIpmiPowerExecutor; +import org.zstack.compute.host.HostSystemTags; +import org.zstack.core.cloudbus.EventCallback; +import org.zstack.core.cloudbus.EventFacade; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.Component; +import org.zstack.header.host.*; +import org.zstack.utils.network.NetworkUtils; + +import java.util.Map; + + +/** + * @Author : jingwang + * @create 2023/4/13 2:25 PM + */ +public class KvmHostIpmiPowerExecutor extends HostIpmiPowerExecutor implements Component { + @Autowired + DatabaseFacade dbf; + @Autowired + EventFacade evtf; + + private void onHostStatusChanged() { + evtf.onLocal(HostCanonicalEvents.HOST_STATUS_CHANGED_PATH, new EventCallback() { + @Override + protected void run(Map tokens, Object data) { + HostCanonicalEvents.HostStatusChangedData d = (HostCanonicalEvents.HostStatusChangedData) data; + if (!d.getNewStatus().equals(HostStatus.Connected.name())) { + return; + } + + String hostUuid = d.getInventory().getUuid(); + String currentIpmiAddress = HostSystemTags.IPMI_ADDRESS.getTokenByResourceUuid(hostUuid, HostSystemTags.IPMI_ADDRESS_TOKEN); + HostPowerStatus status = HostPowerStatus.POWER_ON; + if (!NetworkUtils.isIpv4Address(currentIpmiAddress)) { + currentIpmiAddress = null; + } + + HostVO host = dbf.findByUuid(hostUuid, HostVO.class); + HostIpmiVO ipmi = host.getIpmi(); + if (isIpmiUnConfigured(ipmi)) { + status = HostPowerStatus.UN_CONFIGURED; + } + + if (ipmi != null) { + ipmi.setIpmiAddress(currentIpmiAddress); + ipmi.setIpmiPowerStatus(status); + dbf.update(ipmi); + } else { + final HostIpmiVO hostIpmiVO = new HostIpmiVO(); + hostIpmiVO.setUuid(hostUuid); + hostIpmiVO.setIpmiAddress(currentIpmiAddress); + hostIpmiVO.setIpmiPort(KVMConstant.IPMI_DEFAULT_PORT); + hostIpmiVO.setIpmiPowerStatus(status); + dbf.persist(hostIpmiVO); + } + } + }); + } + + @Override + public boolean start() { + onHostStatusChanged(); + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostReserveExtension.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostReserveExtension.java index 66fd98165d4..467b336eab7 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostReserveExtension.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostReserveExtension.java @@ -15,10 +15,19 @@ import org.zstack.header.host.RecalculateHostCapacityMsg; import org.zstack.header.zone.ZoneVO; import org.zstack.utils.SizeUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** */ public class KvmHostReserveExtension implements HostReservedCapacityExtensionPoint, Component { + private static CLogger logger = Utils.getLogger(KvmHostReserveExtension.class); + private ReservedHostCapacity reserve = new ReservedHostCapacity(); @Autowired @@ -40,6 +49,29 @@ public ReservedHostCapacity getReservedHostCapacity(String hostUuid) { return hc; } + @Override + public Map getReservedHostsCapacity(List hostUuids) { + Map results = new HashMap<>(); + Map values = rcf.getResourceConfigValues(KVMGlobalConfig.RESERVED_MEMORY_CAPACITY, hostUuids, String.class); + + if (logger.isTraceEnabled()) { + logger.trace(String.format("KvmHostReserveExtension get reserved memory capacity for hosts %s, resource config values are %s", hostUuids, JSONObjectUtil.toJsonString(values))); + } + + values.forEach((hostUuid, reserveMem) -> { + ReservedHostCapacity hc = new ReservedHostCapacity(); + hc.setReservedCpuCapacity(reserve.getReservedCpuCapacity()); + hc.setReservedMemoryCapacity(SizeUtils.sizeStringToBytes(reserveMem)); + results.put(hostUuid, hc); + }); + + if (logger.isTraceEnabled()) { + logger.trace(String.format("KvmHostReserveExtension returns %s for hosts %s", JSONObjectUtil.toJsonString(results), hostUuids)); + } + + return results; + } + @Override public boolean start() { long cpu = SizeUtils.sizeStringToBytes(KVMGlobalConfig.RESERVED_CPU_CAPACITY.value()); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostUpdateOsExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostUpdateOsExtensionPoint.java new file mode 100644 index 00000000000..2e66220e9ac --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmHostUpdateOsExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.kvm; + +import org.zstack.header.host.HostInventory; + +import java.util.Map; + +public interface KvmHostUpdateOsExtensionPoint { + String UPDATE_OS_RSP = "UPDATE_OS_RSP"; + + void afterUpdateOs(Map data, HostInventory host); +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmResourceConfigExtension.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmResourceConfigExtension.java new file mode 100644 index 00000000000..dde954bf718 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmResourceConfigExtension.java @@ -0,0 +1,25 @@ +package org.zstack.kvm; + +import org.zstack.header.vm.ArchiveResourceConfigBundle; +import org.zstack.header.vm.ResourceConfigMemorySnapshotExtensionPoint; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.resourceconfig.ResourceConfigFacade; + +import java.util.ArrayList; +import java.util.List; + +public class KvmResourceConfigExtension implements ResourceConfigMemorySnapshotExtensionPoint { + @Autowired + private ResourceConfigFacade rcf; + + @Override + public List getNeedToArchiveResourceConfig(String resourceUuid) { + List bundleList = new ArrayList<>(); + ArchiveResourceConfigBundle.ResourceConfigBundle bundle = new ArchiveResourceConfigBundle.ResourceConfigBundle(); + bundle.setResourceUuid(resourceUuid); + bundle.setIdentity(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + bundle.setValue(rcf.getResourceConfigValue(KVMGlobalConfig.NESTED_VIRTUALIZATION, resourceUuid, String.class)); + bundleList.add(bundle); + return bundleList; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmSetupSelfFencerExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmSetupSelfFencerExtensionPoint.java index 0a0750869b4..48ae2f68823 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KvmSetupSelfFencerExtensionPoint.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmSetupSelfFencerExtensionPoint.java @@ -3,6 +3,8 @@ import org.zstack.header.core.Completion; import org.zstack.header.storage.primary.PrimaryStorageInventory; +import java.util.List; + /** * Created by xing5 on 2016/5/10. */ @@ -35,6 +37,7 @@ class KvmSetupSelfFencerParam { private int storageCheckerTimeout; private PrimaryStorageInventory primaryStorage; private String strategy; + private List fencers; public String getHostUuid() { return hostUuid; @@ -83,6 +86,14 @@ public String getStrategy() { public void setStrategy(String strategy) { this.strategy = strategy; } + + public List getFencers() { + return fencers; + } + + public void setFencers(List fencers) { + this.fencers = fencers; + } } String kvmSetupSelfFencerStorageType(); diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmActiveVolumeSyncExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmActiveVolumeSyncExtensionPoint.java new file mode 100644 index 00000000000..ddf42e08672 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmActiveVolumeSyncExtensionPoint.java @@ -0,0 +1,13 @@ +package org.zstack.kvm; + +import org.zstack.header.core.Completion; +import org.zstack.header.host.HostInventory; +import org.zstack.header.storage.primary.PrimaryStorageInventory; + +import java.util.List; +import java.util.Map; + +public interface KvmVmActiveVolumeSyncExtensionPoint { + List getStoragePathsForVolumeSync(HostInventory host, PrimaryStorageInventory attachedPs); + void handleInactiveVolume(HostInventory host, Map> inactiveVolumePaths, Completion completion); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmActiveVolumeSyncPingTask.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmActiveVolumeSyncPingTask.java new file mode 100644 index 00000000000..783b456df1a --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmActiveVolumeSyncPingTask.java @@ -0,0 +1,174 @@ +package org.zstack.kvm; + +import org.apache.commons.collections.CollectionUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.Component; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostInventory; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.primary.PrimaryStorageInventory; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; +import java.util.stream.Collectors; + +public class KvmVmActiveVolumeSyncPingTask implements KVMPingAgentNoFailureExtensionPoint, Component { + private static final CLogger logger = Utils.getLogger(KvmVmActiveVolumeSyncPingTask.class); + @Autowired + private CloudBus bus; + @Autowired + private ThreadFacade thdf; + @Autowired + private PluginRegistry pluginRgty; + + private List exts; + + + private void syncVolume(final HostInventory host, final NoErrorCompletion completion) { + List psVOs = SQL.New("select ps from PrimaryStorageVO ps, PrimaryStorageClusterRefVO ref" + + " where ref.primaryStorageUuid = ps.uuid" + + " and ref.clusterUuid = :clusterUuid", PrimaryStorageVO.class) + .param("clusterUuid", host.getClusterUuid()).list(); + + Map> storagePaths = new HashMap<>(); + for (KvmVmActiveVolumeSyncExtensionPoint ext : exts) { + for (PrimaryStorageVO psVO : psVOs) { + PrimaryStorageInventory psInv = PrimaryStorageInventory.valueOf(psVO); + List paths = ext.getStoragePathsForVolumeSync(host, psInv); + if (CollectionUtils.isNotEmpty(paths)) { + storagePaths.computeIfAbsent(psInv, k -> new ArrayList<>()).addAll(paths); + } + } + } + + if (storagePaths.isEmpty()) { + completion.done(); + return; + } + + Map> psInvsByPath = new HashMap<>(); + storagePaths.forEach((psInv, paths) -> { + paths.forEach(path -> { + psInvsByPath.computeIfAbsent(path, k -> new ArrayList<>()).add(psInv); + }); + }); + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + KVMAgentCommands.VolumeSyncCmd cmd = new KVMAgentCommands.VolumeSyncCmd(); + cmd.setStoragePaths(storagePaths.values().stream().flatMap(Collection::stream).collect(Collectors.toList())); + + msg.setCommand(cmd); + msg.setNoStatusCheck(true); + msg.setHostUuid(host.getUuid()); + msg.setPath(KVMConstant.KVM_VOLUME_SYNC_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, host.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to sync volume on kvm host[uuid:%s, ip:%s], %s", + host.getUuid(), host.getManagementIp(), reply.getError())); + completion.done(); + return; + } + KVMHostAsyncHttpCallReply r = reply.castReply(); + KVMAgentCommands.VolumeSyncRsp ret = r.toResponse(KVMAgentCommands.VolumeSyncRsp.class); + if (!ret.isSuccess()) { + logger.warn(String.format("failed to sync volume on kvm host[uuid:%s, ip:%s], %s", + host.getUuid(), host.getManagementIp(), ret.getError())); + completion.done(); + return; + } + + if (ret.getInactiveVolumePaths() == null || ret.getInactiveVolumePaths().isEmpty() || + ret.getInactiveVolumePaths().values().stream().allMatch(List::isEmpty)) { + completion.done(); + return; + } + + Map> inactiveVolumePaths = new HashMap<>(); + ret.getInactiveVolumePaths().forEach((storagePath, volumePaths) -> { + psInvsByPath.get(storagePath).forEach(psInv -> + inactiveVolumePaths.computeIfAbsent(psInv, k -> new ArrayList<>()).addAll(volumePaths)); + }); + + new While<>(exts).each((ext, wcomp) -> { + ext.handleInactiveVolume(host, inactiveVolumePaths, new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.done(); + } + }); + } + }); + } + + + @Override + public boolean start() { + exts = pluginRgty.getExtensionList(KvmVmActiveVolumeSyncExtensionPoint.class); + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public void kvmPingAgentNoFailure(KVMHostInventory host, NoErrorCompletion completion) { + if (!KVMGlobalConfig.VM_SYNC_ON_HOST_PING.value(Boolean.class)) { + completion.done(); + return; + } + + thdf.chainSubmit(new ChainTask(null) { + @Override + public String getSyncSignature() { + return String.format("sync-volume-state-after-ping-host-%s-success", host.getUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + syncVolume(host, new NoErrorCompletion() { + @Override + public void done() { + chain.next(); + } + }); + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + completion.done(); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmHardwareVerifyExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmHardwareVerifyExtensionPoint.java new file mode 100644 index 00000000000..cf751787430 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmHardwareVerifyExtensionPoint.java @@ -0,0 +1,35 @@ +package org.zstack.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.vm.VmBeforeStartOnHypervisorExtensionPoint; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; + +import static org.zstack.core.Platform.operr; +import static org.zstack.kvm.KVMConstant.CPU_MODE_NONE; + +public class KvmVmHardwareVerifyExtensionPoint implements VmBeforeStartOnHypervisorExtensionPoint { + @Autowired + private ResourceConfigFacade rcf; + + @Override + public void beforeStartVmOnHypervisor(VmInstanceSpec spec) { + if (!spec.getVmInventory().getHypervisorType().equals(KVMConstant.KVM_HYPERVISOR_TYPE)) { + return; + } + + ResourceConfig resourceConfig = rcf.getResourceConfig(KVMGlobalConfig.VM_CPU_HYPERVISOR_FEATURE.getIdentity()); + Boolean enableHypervisor = resourceConfig.getResourceConfigValue(spec.getVmInventory().getUuid(), Boolean.class); + if (enableHypervisor) { + return; + } + + ResourceConfig cpuMode = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + if (CPU_MODE_NONE.equals(cpuMode.getResourceConfigValue(spec.getVmInventory().getUuid(), String.class))) { + throw new OperationFailureException(operr("Failed to start vm," + + " because can not disable vm.cpu.hypervisor.feature with vm.cpuMode none")); + } + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java index 5f605f22e34..af1a8718800 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/KvmVmSyncPingTask.java @@ -240,8 +240,12 @@ public void run(MessageReply reply) { } VmInstanceState state = KvmVmState.valueOf(e.getValue()).toVmInstanceState(); - if (state == VmInstanceState.Running || state == VmInstanceState.Paused - || state == VmInstanceState.Unknown || state == VmInstanceState.Stopped || state == VmInstanceState.Crashed) { + if (state == VmInstanceState.Running + || state == VmInstanceState.Paused + || state == VmInstanceState.Unknown + || state == VmInstanceState.Stopped + || state == VmInstanceState.Crashed + || state == VmInstanceState.NoState) { states.put(e.getKey(), state); } @@ -396,6 +400,7 @@ public void fail(ErrorCode errorCode) { @Override public void kvmPingAgentNoFailure(KVMHostInventory host, NoErrorCompletion completion) { if (!KVMGlobalConfig.VM_SYNC_ON_HOST_PING.value(Boolean.class)) { + logger.debug("vmSyncOnHostPing is disabled, skip sync vm state in kvmPingAgentNoFailure"); completion.done(); return; } @@ -452,4 +457,8 @@ public void iJoin(ManagementNodeInventory inv) { vmApis.putIfAbsent(inv.getUuid(), new ConcurrentHashMap<>()); vmsToSkip.putIfAbsent(inv.getUuid(), ConcurrentHashMap.newKeySet()); } + + public boolean isVmDoNotNeedToTrace(String vmUuid) { + return vmsToSkip.values().stream().anyMatch(vmsToSkipSet -> vmsToSkipSet.contains(vmUuid)); + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/MergeVolumeSnapshotOnKvmMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/MergeVolumeSnapshotOnKvmMsg.java index 9279721b8a6..38f276a9b27 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/MergeVolumeSnapshotOnKvmMsg.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/MergeVolumeSnapshotOnKvmMsg.java @@ -14,7 +14,7 @@ public class MergeVolumeSnapshotOnKvmMsg extends NeedReplyMessage implements Hos private boolean fullRebase; public boolean isFullRebase() { - return fullRebase; + return fullRebase || from == null; } public void setFullRebase(boolean fullRebase) { diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/PackageInfo.java b/plugin/kvm/src/main/java/org/zstack/kvm/PackageInfo.java index e2cb491b912..720de4f0a09 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/PackageInfo.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "KVM物理机") +@PackageAPIInfo( + APICategoryName = "KVM物理机", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/QemuKvmVersion.java b/plugin/kvm/src/main/java/org/zstack/kvm/QemuKvmVersion.java new file mode 100644 index 00000000000..602bc49036f --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/QemuKvmVersion.java @@ -0,0 +1,27 @@ +package org.zstack.kvm; + +import org.apache.maven.artifact.versioning.ComparableVersion; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class QemuKvmVersion { + final String version; + + private static final ComparableVersion supportMirrorBitmapVersion = new ComparableVersion("4.2.0-627"); + private static final ComparableVersion supportBackgroundBackupVersion = new ComparableVersion("6.2.0"); + + public QemuKvmVersion(String version) { + this.version = Arrays.stream(version.split("-")). + filter(it -> Character.isDigit(it.charAt(0))) + .collect(Collectors.joining("-")); + } + + public boolean supportMirrorBitmap() { + return new ComparableVersion(version).compareTo(supportMirrorBitmapVersion) >= 0; + } + + public boolean supportBackgroundBackup() { + return new ComparableVersion(version).compareTo(supportBackgroundBackupVersion) >= 0; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/RBACInfo.java b/plugin/kvm/src/main/java/org/zstack/kvm/RBACInfo.java index 98bd4f4cd30..4368c11b0a2 100755 --- a/plugin/kvm/src/main/java/org/zstack/kvm/RBACInfo.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/RBACInfo.java @@ -1,18 +1,24 @@ package org.zstack.kvm; import org.zstack.header.identity.rbac.RBACDescription; +import org.zstack.kvm.hypervisor.message.APIQueryHostOsCategoryMsg; +import org.zstack.kvm.hypervisor.message.APIQueryKvmHypervisorInfoMsg; public class RBACInfo implements RBACDescription { @Override public void permissions() { permissionBuilder() + .normalAPIs(APIQueryHostOsCategoryMsg.class, APIQueryKvmHypervisorInfoMsg.class) .adminOnlyAPIs("org.zstack.kvm.**") .build(); } @Override public void contributeToRoles() { - + roleContributorBuilder() + .roleName("other") + .actions(APIQueryHostOsCategoryMsg.class, APIQueryKvmHypervisorInfoMsg.class) + .build(); } @Override diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/RestartKvmAgentMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/RestartKvmAgentMsg.java new file mode 100644 index 00000000000..008b653af7f --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/RestartKvmAgentMsg.java @@ -0,0 +1,26 @@ +package org.zstack.kvm; + +import org.zstack.header.host.HostMessage; +import org.zstack.header.message.NeedReplyMessage; + +public class RestartKvmAgentMsg extends NeedReplyMessage implements HostMessage { + String hostUuid; + boolean force; + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + @Override + public String getHostUuid() { + return hostUuid; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/RestartKvmAgentReply.java b/plugin/kvm/src/main/java/org/zstack/kvm/RestartKvmAgentReply.java new file mode 100644 index 00000000000..e26f22981e0 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/RestartKvmAgentReply.java @@ -0,0 +1,6 @@ +package org.zstack.kvm; + +import org.zstack.header.message.MessageReply; + +public class RestartKvmAgentReply extends MessageReply { +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/VirtualPciDeviceKvmExtensionPoint.java b/plugin/kvm/src/main/java/org/zstack/kvm/VirtualPciDeviceKvmExtensionPoint.java new file mode 100644 index 00000000000..b05273289a1 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/VirtualPciDeviceKvmExtensionPoint.java @@ -0,0 +1,87 @@ +package org.zstack.kvm; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.vm.devices.DeviceAddress; +import org.zstack.header.vm.devices.VirtualDeviceInfo; +import org.zstack.header.vm.devices.VmInstanceDeviceManager; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.vm.VmInstanceSpec; + +public class VirtualPciDeviceKvmExtensionPoint implements KVMStartVmExtensionPoint, KVMSyncVmDeviceInfoExtensionPoint { + @Autowired + private VmInstanceDeviceManager vidManager; + + @Override + public void beforeStartVmOnKvm(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommands.StartVmCmd cmd) { + if (cmd.getRootVolume() != null) { + setDeviceAddress(cmd.getRootVolume(), cmd); + } + + if (cmd.getDataVolumes() != null) { + cmd.getDataVolumes().forEach(to -> setDeviceAddress(to, cmd)); + } + + if (cmd.getNics() != null) { + cmd.getNics().forEach(to -> setDeviceAddress(to, cmd)); + } + + if (cmd.getCdRoms() != null) { + cmd.getCdRoms().forEach(to -> setDeviceAddress(to, cmd)); + } + } + + private void setDeviceAddress(BaseVirtualDeviceTO to, KVMAgentCommands.StartVmCmd cmd) { + to.setDeviceAddress(vidManager.getVmDeviceAddress(to.getResourceUuid(), cmd.getVmInstanceUuid())); + } + + @Override + public void afterReceiveVmDeviceInfoResponse(VmInstanceInventory vm, KVMAgentCommands.VmDevicesInfoResponse rsp, VmInstanceSpec spec) { + if (rsp.getVirtualDeviceInfoList() == null) { + return; + } + + String vmUuid = spec != null ? spec.getVmInventory().getUuid() : vm.getUuid(); + // only update pci address, metadata is not mandatory in normal usage + // check its usage when create snapshot or backup + rsp.getVirtualDeviceInfoList().forEach(info -> { + if (info.isValid()) { + vidManager.createOrUpdateVmDeviceAddress(info, vmUuid); + } + }); + + if (rsp.getNicInfos() == null) { + return; + } + + rsp.getNicInfos().forEach(info -> { + VmNicInventory nic = (spec != null ? spec.getDestNics() : vm.getVmNics()) + .stream() + .filter(vmNicInventory -> vmNicInventory.getMac().equals(info.getMacAddress())) + .findFirst() + .orElse(null); + if (nic == null) { + return; + } + + vidManager.createOrUpdateVmDeviceAddress(new VirtualDeviceInfo(nic.getUuid(), info.getDeviceAddress()), vmUuid); + }); + + if (!StringUtils.isEmpty(rsp.getMemBalloonInfo().getDeviceAddress().toString())) { + vidManager.createOrUpdateVmDeviceAddress(new VirtualDeviceInfo(vidManager.MEM_BALLOON_UUID, + DeviceAddress.fromString(rsp.getMemBalloonInfo().getDeviceAddress().toString())), vmUuid); + } + } + + @Override + public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { + + } + + @Override + public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { + + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/VmCpuVendorKvmStartVmExtension.java b/plugin/kvm/src/main/java/org/zstack/kvm/VmCpuVendorKvmStartVmExtension.java new file mode 100644 index 00000000000..25e099a2940 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/VmCpuVendorKvmStartVmExtension.java @@ -0,0 +1,91 @@ +package org.zstack.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.host.HostSystemTags; +import org.zstack.compute.vm.VmGlobalConfig; +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigInitExtensionPoint; +import org.zstack.core.config.GlobalConfigVO; +import org.zstack.core.config.GlobalConfigVO_; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.resourceconfig.ResourceConfigVO; + +import java.util.ArrayList; +import java.util.List; + +import static org.zstack.kvm.KVMConstant.CPU_MODE_HOST_PASSTHROUGH; +import static org.zstack.kvm.KVMConstant.CPU_MODE_HYGON_CUSTOMIZED; + +public class VmCpuVendorKvmStartVmExtension implements KVMStartVmExtensionPoint, GlobalConfigInitExtensionPoint { + @Autowired + ResourceConfigFacade rcf; + + @Autowired + DatabaseFacade dbf; + + private static final String HYGON = "hygon"; + + @Override + public void beforeStartVmOnKvm(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommands.StartVmCmd cmd) { + String host_cpu_model_name = HostSystemTags.HOST_CPU_MODEL_NAME.getTokenByResourceUuid(host.getUuid(), HostSystemTags.HOST_CPU_MODEL_NAME_TOKEN); + if (host_cpu_model_name == null) { + return; + } + if (!host_cpu_model_name.toLowerCase().contains(HYGON)) { + return; + } + + ResourceConfig rc = rcf.getResourceConfig(VmGlobalConfig.VM_CPUID_VENDOR.getIdentity()); + String vmCpuIdVendor = rc.getResourceConfigValue(spec.getVmInventory().getUuid(), String.class); + + if (vmCpuIdVendor != null) { + cmd.setVmCpuVendorId(vmCpuIdVendor); + } + } + + @Override + public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { + + } + + @Override + public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { + + } + + + @Override + public List getGenerationGlobalConfig() { + // change 'Hygon_Customized' in db to 'Host_passthrough', otherwise the re-validation will fail. + changeHygonCustomizedForGlobalConfigAndResourceConfig(); + return new ArrayList<>(); + } + + private void changeHygonCustomizedForGlobalConfigAndResourceConfig() { + if (Q.New(GlobalConfigVO.class) + .eq(GlobalConfigVO_.category, KVMGlobalConfig.CATEGORY) + .eq(GlobalConfigVO_.name, "vm.cpuMode") + .eq(GlobalConfigVO_.value, CPU_MODE_HYGON_CUSTOMIZED) + .isExists()) { + KVMGlobalConfig.NESTED_VIRTUALIZATION.updateValue(CPU_MODE_HOST_PASSTHROUGH); + } + + String sql = "select rc from ResourceConfigVO rc where rc.name = :name " + + "and rc.category = :category and rc.value = :value"; + List rcs = SQL.New(sql). + param("name", "vm.cpuMode"). + param("category", KVMGlobalConfig.CATEGORY). + param("value", CPU_MODE_HYGON_CUSTOMIZED).list(); + + if (!rcs.isEmpty()) { + rcs.forEach(rc -> rc.setValue(CPU_MODE_HOST_PASSTHROUGH)); + dbf.updateCollection(rcs); + } + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java b/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java index 334a49a345e..2ea9238f167 100644 --- a/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java +++ b/plugin/kvm/src/main/java/org/zstack/kvm/VolumeTO.java @@ -9,11 +9,15 @@ import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.volume.VolumeInventory; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.header.volume.VolumeProtocol; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; -public class VolumeTO { +public class VolumeTO extends BaseVirtualDeviceTO { public static final String FILE = "file"; public static final String ISCSI = "iscsi"; public static final String CEPH = "ceph"; @@ -22,6 +26,9 @@ public class VolumeTO { public static final String BLOCK = "block"; public static final String MINISTORAGE = "mini"; public static final String QUORUM = "quorum"; + public static final String VHOST = "vhost"; + public static final String CBD = "cbd"; + public static final Map deviceTypes = new HashMap<>(); public static List exts; private String installPath; @@ -32,6 +39,7 @@ public class VolumeTO { private boolean useVirtioSCSI; private boolean shareable; private String cacheMode = "none"; + private boolean aioNative; private String wwn; private int bootOrder; private int physicalBlockSize; @@ -40,6 +48,15 @@ public class VolumeTO { private String type; private String format; private String primaryStorageType; + private String multiQueues; + private int ioThreadId; + private String ioThreadPin; + private int controllerIndex; + + static { + deviceTypes.put(VolumeProtocol.Vhost, VHOST); + deviceTypes.put(VolumeProtocol.CBD, CBD); + } public VolumeTO() { } @@ -52,6 +69,7 @@ public VolumeTO(VolumeTO other) { this.useVirtio = other.useVirtio; this.useVirtioSCSI = other.useVirtioSCSI; this.cacheMode = other.cacheMode; + this.aioNative = other.aioNative; this.wwn = other.wwn; this.shareable = other.shareable; this.bootOrder = other.bootOrder; @@ -59,6 +77,10 @@ public VolumeTO(VolumeTO other) { this.type = other.type; this.format = other.format; this.primaryStorageType = other.primaryStorageType; + this.multiQueues = other.multiQueues; + this.ioThreadId = other.ioThreadId; + this.ioThreadPin = other.ioThreadPin; + this.controllerIndex = other.controllerIndex; } public static List valueOf(List vols, KVMHostInventory host) { @@ -75,6 +97,7 @@ public static VolumeTO valueOfWithOutExtension(VolumeInventory vol, KVMHostInven public static VolumeTO valueOf(VolumeInventory vol, KVMHostInventory host, String platform, boolean withExtension) { VolumeTO to = new VolumeTO(); + to.setResourceUuid(vol.getUuid()); to.setInstallPath(vol.getInstallPath()); if (vol.getDeviceId() != null) { to.setDeviceId(vol.getDeviceId()); @@ -93,7 +116,8 @@ public static VolumeTO valueOf(VolumeInventory vol, KVMHostInventory host, Strin to.setUseVirtioSCSI(!ImagePlatform.Other.toString().equals(platform) && KVMSystemTags.VOLUME_VIRTIO_SCSI.hasTag(vol.getUuid())); to.setWwn(KVMHost.computeWwnIfAbsent(vol.getUuid())); to.setShareable(vol.isShareable()); - to.setCacheMode(KVMGlobalConfig.LIBVIRT_CACHE_MODE.value()); + ResourceConfigFacade rcf = Platform.getComponentLoader().getComponent(ResourceConfigFacade.class); + to.setCacheMode(rcf.getResourceConfigValue(KVMGlobalConfig.LIBVIRT_CACHE_MODE, vol.getUuid(), String.class)); String psType = Q.New(PrimaryStorageVO.class) .eq(PrimaryStorageVO_.uuid, vol.getPrimaryStorageUuid()) @@ -194,6 +218,14 @@ public void setCacheMode(String cacheMode) { this.cacheMode = cacheMode; } + public boolean setAioNative() { + return aioNative; + } + + public void setAioNative(boolean aioNative) { + this.aioNative = aioNative; + } + public int getBootOrder() { return bootOrder; } @@ -233,4 +265,36 @@ public String getPrimaryStorageType() { public void setPrimaryStorageType(String primaryStorageType) { this.primaryStorageType = primaryStorageType; } + + public void setMultiQueues(String multiQueues) { + this.multiQueues = multiQueues; + } + + public String getMultiQueues() { + return multiQueues; + } + + public void setIoThreadId(int ioThreadId) { + this.ioThreadId = ioThreadId; + } + + public int getIoThreadId() { + return ioThreadId; + } + + public void setIoThreadPin(String ioThreadPin) { + this.ioThreadPin = ioThreadPin; + } + + public String getIoThreadPin() { + return ioThreadPin; + } + + public int getControllerIndex() { + return controllerIndex; + } + + public void setControllerIndex(int controllerIndex) { + this.controllerIndex = controllerIndex; + } } diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollector.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollector.java new file mode 100644 index 00000000000..97441e67086 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollector.java @@ -0,0 +1,90 @@ +package org.zstack.kvm.hypervisor; + +import org.zstack.header.host.HostAO; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +/** + * Created by Wenhao.Zhang on 23/03/01 + */ +public interface HypervisorMetadataCollector { + List collect(); + + class HypervisorMetadataDefinition { + /** + * equals to {@link HostAO#getArchitecture()} + */ + private String architecture; + /** + * "centos 7.6.1810" / "centos 7.4.1708" ... + */ + private String osReleaseVersion; + /** + * "c76" / "c74" ... + */ + private String osReleaseSimpleVersion; + /** + * "qemu-kvm" + */ + private String hypervisor; + /** + * hypervisor version. "4.2.0-632" + */ + private String version; + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public String getOsReleaseSimpleVersion() { + return osReleaseSimpleVersion; + } + + public void setOsReleaseSimpleVersion(String osReleaseSimpleVersion) { + this.osReleaseSimpleVersion = osReleaseSimpleVersion; + } + + public String getOsReleaseVersion() { + return osReleaseVersion; + } + + public void setOsReleaseVersion(String osReleaseVersion) { + this.osReleaseVersion = osReleaseVersion; + } + + public String getHypervisor() { + return hypervisor; + } + + public void setHypervisor(String hypervisor) { + this.hypervisor = hypervisor; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Path virtualizerScriptPath() { + return Paths.get( + KvmHypervisorConstant.DVD_ROOT_PATH.toString(), + this.architecture, + this.osReleaseSimpleVersion, + KvmHypervisorConstant.VIRTUALIZER_INFO_SCRIPT_PATH.toString()); + } + + public boolean isValid() { + return Files.exists(virtualizerScriptPath()); + } + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollectorImpl.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollectorImpl.java new file mode 100644 index 00000000000..468025b01bd --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollectorImpl.java @@ -0,0 +1,141 @@ +package org.zstack.kvm.hypervisor; + +import org.zstack.kvm.KVMConstant; +import org.zstack.utils.ShellResult; +import org.zstack.utils.ShellUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.zstack.kvm.hypervisor.KvmHypervisorConstant.*; + +/** + * collect management node hypervisor metadata. + * + * 1. scan current hypervisor info (include Qemu version) + * in local file system at {@link KvmHypervisorConstant#DVD_ROOT_PATH} + * 2. collect hypervisor info by {@link KvmHypervisorConstant#VIRTUALIZER_INFO_SCRIPT_PATH} + * 3. save hypervisor info to table {@link org.zstack.kvm.hypervisor.datatype.KvmHostHypervisorMetadataVO} + * + * Created by Wenhao.Zhang on 23/03/01 + */ +public class HypervisorMetadataCollectorImpl implements HypervisorMetadataCollector { + private static final CLogger logger = Utils.getLogger(HypervisorMetadataCollectorImpl.class); + + @Override + public List collect() { + List definitions; + + try { + definitions = scanFolder(DVD_ROOT_PATH); + } catch (IOException e) { + logger.warn("failed to scan folder : " + DVD_ROOT_PATH, e); + return Collections.emptyList(); + } + + for (Iterator it = definitions.iterator(); it.hasNext(); ) { + HypervisorMetadataDefinition definition = it.next(); + + Exception exception = null; + boolean success = false; + try { + success = collectHypervisorMetadata(definition); + } catch (Exception e) { + exception = e; + } + + if (success) { + continue; + } + + if (exception != null) { + logger.warn("failed to collect hypervisor metadata at " + definition.virtualizerScriptPath(), exception); + } else { + logger.warn("failed to collect hypervisor metadata at " + definition.virtualizerScriptPath()); + } + it.remove(); + } + + return definitions; + } + + /** + * scan iso folder from specific root path + */ + protected List scanFolder(Path rootPath) throws IOException { + try (Stream stream = Files.list(rootPath)) { // /opt/zstack-dvd/x86_64 + return stream + .filter(path -> !IGNORE_DIR_AT_DVD.contains(path.getFileName().toString())) + .filter(path -> path.toFile().isDirectory()) + .flatMap(path -> { // /opt/zstack-dvd/x86_64/c76 + try { + return Files.list(path); + } catch (IOException e) { + return Arrays.stream(new Path[0]); + } + }) + .filter(path -> path.toFile().isDirectory()) + .map(this::mapFromPath) + .collect(Collectors.toList()); + } + } + + protected HypervisorMetadataDefinition mapFromPath(Path path) { + HypervisorMetadataDefinition definition = new HypervisorMetadataDefinition(); + definition.setOsReleaseSimpleVersion(path.getFileName().toString()); + definition.setArchitecture(path.getParent().getFileName().toString()); + return definition; + } + + /** + * use shell to read metadata properties. + * + * outputs like: + * qemu-kvm.version = 4.2.0-632.g6a6222b.el7 + * platform.distname: centos + * platform.version: 7.6.1810 + * platform.id: Core + */ + protected String collectHypervisorMetadataAsProperties(HypervisorMetadataDefinition definition) throws IOException { + String shellCmd = String.format("/bin/bash %s", definition.virtualizerScriptPath()); + ShellResult result = ShellUtils.runAndReturn(shellCmd); + result.raiseExceptionIfFail(); + + return result.getStdout(); + } + + private boolean collectHypervisorMetadata(HypervisorMetadataDefinition definition) throws IOException { + if (!definition.isValid()) { + return false; + } + + Properties properties = new Properties(); + properties.load(new ByteArrayInputStream( + collectHypervisorMetadataAsProperties(definition).getBytes())); + + Object qemuVersion = properties.get(KEY_QEMU_KVM_VERSION); + if (qemuVersion != null && !qemuVersion.getClass().isArray()) { + definition.setHypervisor(KVMConstant.VIRTUALIZER_QEMU_KVM); + definition.setVersion(qemuVersion.toString()); + } else { + return false; + } + + Object platformDistName = properties.get(KEY_PLATFORM_DIST_NAME); + Object platformVersion = properties.get(KEY_PLATFORM_VERSION); + if (platformDistName != null && platformVersion != null) { + definition.setOsReleaseVersion(String.format("%s %s", platformDistName, platformVersion)); + } else { + return false; + } + + return true; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorConstant.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorConstant.java new file mode 100644 index 00000000000..ddf071e942a --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorConstant.java @@ -0,0 +1,29 @@ +package org.zstack.kvm.hypervisor; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Constant set for KvmHypervisorInfo manager + * + * Created by Wenhao.Zhang on 23/03/01 + */ +public class KvmHypervisorConstant { + private KvmHypervisorConstant() {} + + public static final Path DVD_ROOT_PATH = + Paths.get("/opt", "zstack-dvd"); + public static final Path VIRTUALIZER_INFO_SCRIPT_PATH = + Paths.get("Extra", "virtualizer-info.sh"); + public static final Set IGNORE_DIR_AT_DVD = new HashSet<>( + Arrays.asList("native-repos") + ); + + public static final String KEY_QEMU_KVM_VERSION = "qemu-kvm.version"; + public static final String KEY_PLATFORM_DIST_NAME = "platform.distname"; + public static final String KEY_PLATFORM_VERSION = "platform.version"; + public static final String KEY_PLATFORM_ID = "platform.id"; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoExtensions.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoExtensions.java new file mode 100644 index 00000000000..b2d17693689 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoExtensions.java @@ -0,0 +1,160 @@ +package org.zstack.kvm.hypervisor; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.Q; +import org.zstack.header.core.workflow.Flow; +import org.zstack.header.core.workflow.FlowTrigger; +import org.zstack.header.core.workflow.NoRollbackFlow; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.GetVirtualizerInfoMsg; +import org.zstack.header.host.HostConstant; +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.*; +import org.zstack.kvm.KVMAgentCommands.DestroyVmCmd; +import org.zstack.kvm.KVMAgentCommands.RebootVmResponse; +import org.zstack.kvm.KVMAgentCommands.StopVmCmd; +import org.zstack.kvm.KVMAgentCommands.VmDevicesInfoResponse; +import org.zstack.kvm.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import static org.zstack.core.Platform.operr; + +/** + * Created by Wenhao.Zhang on 23/02/27 + */ +public class KvmHypervisorInfoExtensions implements + KVMSyncVmDeviceInfoExtensionPoint, + KVMRebootVmExtensionPoint, + KVMDestroyVmExtensionPoint, + KVMStopVmExtensionPoint, + VmAfterExpungeExtensionPoint, + KVMHostConnectExtensionPoint, + VmInstanceMigrateExtensionPoint +{ + private static final CLogger logger = Utils.getLogger(KvmHypervisorInfoExtensions.class); + + @Autowired + private KvmHypervisorInfoManager manager; + @Autowired + private CloudBus bus; + + @Override + public void afterReceiveVmDeviceInfoResponse(VmInstanceInventory vm, VmDevicesInfoResponse rsp, VmInstanceSpec spec) { + Optional.ofNullable(rsp.getVirtualizerInfo()).ifPresent(manager::saveVmInfo); + } + + @Override + public void beforeRebootVmOnKvm(KVMHostInventory host, VmInstanceInventory vm) throws KVMException {} + @Override + public void rebootVmOnKvmFailed(KVMHostInventory host, VmInstanceInventory vm, ErrorCode err) {} + + @Override + public void rebootVmOnKvmSuccess(KVMHostInventory host, VmInstanceInventory vm, RebootVmResponse rsp) { + Optional.ofNullable(rsp.getVirtualizerInfo()).ifPresent(manager::saveVmInfo); + } + + @Override + public void beforeDestroyVmOnKvm(KVMHostInventory host, VmInstanceInventory vm, DestroyVmCmd cmd) + throws KVMException {} + + @Override + public void beforeDirectlyDestroyVmOnKvm(DestroyVmCmd cmd) {} + + @Override + public void destroyVmOnKvmSuccess(KVMHostInventory host, VmInstanceInventory vm) { + manager.clean(vm.getUuid()); + } + + @Override + public void destroyVmOnKvmFailed(KVMHostInventory host, VmInstanceInventory vm, ErrorCode err) {} + + @Override + public void beforeStopVmOnKvm(KVMHostInventory host, VmInstanceInventory vm, StopVmCmd cmd) throws KVMException {} + + @Override + public void stopVmOnKvmSuccess(KVMHostInventory host, VmInstanceInventory vm) { + manager.clean(vm.getUuid()); + } + + @Override + public void stopVmOnKvmFailed(KVMHostInventory host, VmInstanceInventory vm, ErrorCode err) {} + + @Override + public void vmAfterExpunge(VmInstanceInventory vm) { + manager.clean(vm.getUuid()); + } + + @Override + @SuppressWarnings("rawtypes") + public Flow createKvmHostConnectingFlow(KVMHostConnectedContext context) { + final String hostUuid = context.getInventory().getUuid(); + final boolean newAdd = context.isNewAddedHost(); + + return new NoRollbackFlow() { + String __name__ = "collect-virtualizer-info-for-running-vm"; + @Override + public void run(FlowTrigger trigger, Map data) { + GetVirtualizerInfoMsg msg = new GetVirtualizerInfoMsg(); + msg.setHostUuid(hostUuid); + if (newAdd) { + msg.setVmInstanceUuids(Collections.emptyList()); + } else { + List vmUuids = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.hostUuid, hostUuid) + .select(VmInstanceVO_.uuid) + .listValues(); + msg.setVmInstanceUuids(vmUuids); + } + + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + trigger.next(); + } else { + trigger.fail(operr(reply.getError(), "failed to collect host virtualizer info")); + } + } + }); + } + }; + } + + @Override + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) {} + + @Override + public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { + final String hostUuid = inv.getHostUuid(); + if (hostUuid == null) { + return; + } + + GetVirtualizerInfoMsg msg = new GetVirtualizerInfoMsg(); + msg.setHostUuid(hostUuid); + msg.setVmInstanceUuids(Collections.singletonList(inv.getUuid())); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(null) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to get virtualizer info for VM[uuid:%s]: %s", + inv.getUuid(), reply.getError())); + } + } + }); + + } + + @Override + public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) {} +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoHelper.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoHelper.java new file mode 100644 index 00000000000..4c0b3613024 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoHelper.java @@ -0,0 +1,99 @@ +package org.zstack.kvm.hypervisor; + +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.host.HostVO_; +import org.zstack.header.host.HostOperationSystem; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.KVMHostVO; +import org.zstack.kvm.KVMHostVO_; +import org.zstack.kvm.hypervisor.datatype.HostOsCategoryVO; +import org.zstack.kvm.hypervisor.datatype.HostOsCategoryVO_; +import org.zstack.kvm.hypervisor.datatype.HypervisorVersionState; +import org.zstack.utils.data.Pair; + +import javax.persistence.Tuple; +import java.util.*; +import java.util.stream.Collectors; + + +/** + * Created by Wenhao.Zhang on 23/02/21 + */ +public class KvmHypervisorInfoHelper { + /** + * @return map + * key: host uuid + * value: HostOsCategoryVO, may be null + */ + public static Map collectExpectedHypervisorInfoForHosts( + Collection hostUuidList) { + List tuples = Q.New(KVMHostVO.class) + .select(KVMHostVO_.uuid, KVMHostVO_.architecture, + KVMHostVO_.osDistribution, KVMHostVO_.osRelease, KVMHostVO_.osVersion) + .notNull(HostVO_.architecture) + .in(KVMHostVO_.uuid, hostUuidList) + .listTuple(); + Map hostArchMap = tuples.stream() + .collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, String.class))); + Map hostOsMap = tuples.stream() + .collect(Collectors.toMap(tuple -> tuple.get(0, String.class), + tuple -> HostOperationSystem.of( + tuple.get(2, String.class), tuple.get(3, String.class), tuple.get(4, String.class)))); + + final Map, HostOsCategoryVO> caches = new HashMap<>(); + final Map results = new HashMap<>(); + DatabaseFacade dbf = Platform.getComponentLoader().getComponent(DatabaseFacade.class); + for (String hostUuid : hostUuidList) { + String architecture = hostArchMap.get(hostUuid); + if (architecture == null) { + results.put(hostUuid, null); + continue; + } + + HostOperationSystem os = hostOsMap.get(hostUuid); + String osReleaseVersion = String.format("%s %s", os.distribution, os.version); + + Pair key = new Pair<>(architecture, osReleaseVersion); + HostOsCategoryVO vo = caches.get(key); + if (vo != null) { + results.put(hostUuid, vo); + continue; + } + + String sql = " select h from HostOsCategoryVO h, KvmHostHypervisorMetadataVO k where k.categoryUuid = h.uuid " + + "and k.managementNodeUuid = :mnId " + + "and h.architecture = :arch " + + "and h.osReleaseVersion = :os " + + "order by k.createDate desc"; + + List resultList = dbf.getEntityManager().createQuery(sql, HostOsCategoryVO.class) + .setParameter("arch", architecture) + .setParameter("os", osReleaseVersion) + .setParameter("mnId", Platform.getManagementServerId()) + .setMaxResults(1) + .getResultList(); + if (!resultList.isEmpty()) { + vo = resultList.get(0); + } + + caches.put(key, vo); + results.put(hostUuid, vo); + } + + return results; + } + + public static HypervisorVersionState isQemuVersionMatched(String v1, String v2) { + if (v1 == null || v2 == null) { + return HypervisorVersionState.Unknown; + } + return Objects.equals(v1, v2) ? HypervisorVersionState.Matched : HypervisorVersionState.Unmatched; + } + + public static boolean isQemuBased(String virtualizerInfo) { + return KVMConstant.VIRTUALIZER_QEMU_KVM.equals(virtualizerInfo) || + KVMConstant.VIRTUALIZER_QEMU.equals(virtualizerInfo); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoManager.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoManager.java new file mode 100644 index 00000000000..c0370c550ac --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoManager.java @@ -0,0 +1,14 @@ +package org.zstack.kvm.hypervisor; + +import static org.zstack.kvm.KVMAgentCommands.GetVirtualizerInfoRsp; +import static org.zstack.kvm.KVMAgentCommands.VirtualizerInfoTO; + +public interface KvmHypervisorInfoManager { + void save(GetVirtualizerInfoRsp rsp); + void saveHostInfo(VirtualizerInfoTO info); + void saveVmInfo(VirtualizerInfoTO info); + + void clean(String uuid); + + void refreshMetadata(); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoManagerImpl.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoManagerImpl.java new file mode 100644 index 00000000000..f9501fe279e --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorInfoManagerImpl.java @@ -0,0 +1,426 @@ +package org.zstack.kvm.hypervisor; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.EventCallback; +import org.zstack.core.cloudbus.EventFacade; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.Component; +import org.zstack.header.host.GetVirtualizerInfoMsg; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostVO; +import org.zstack.header.vm.VmCanonicalEvents; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.hypervisor.datatype.*; +import org.zstack.utils.CollectionDSL; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.Tuple; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static java.util.Map.Entry; +import static org.zstack.kvm.KVMAgentCommands.GetVirtualizerInfoRsp; +import static org.zstack.kvm.KVMAgentCommands.VirtualizerInfoTO; +import static org.zstack.kvm.hypervisor.HypervisorMetadataCollector.HypervisorMetadataDefinition; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +public class KvmHypervisorInfoManagerImpl implements KvmHypervisorInfoManager, Component { + private static final CLogger logger = Utils.getLogger(KvmHypervisorInfoManagerImpl.class); + + @Autowired + private DatabaseFacade db; + @Autowired + private HypervisorMetadataCollector collector; + @Autowired + private EventFacade events; + @Autowired + private CloudBus bus; + + @Override + public void save(GetVirtualizerInfoRsp rsp) { + final String hostUuid = rsp.getHostInfo().getUuid(); + final List list = rsp.getVmInfoList().stream() + .map(info -> ResourceHypervisorInfo.fromVmVirtualizerInfo(info, hostUuid)) + .collect(Collectors.toList()); + list.add(ResourceHypervisorInfo.fromHostVirtualizerInfo(rsp.getHostInfo())); + save(list); + + logger.debug(String.format("save GetVirtualizerInfoRsp for host[uuid:%s] successfully", + rsp.getHostInfo().getUuid())); + } + + @Override + public void saveHostInfo(VirtualizerInfoTO info) { + save(Collections.singletonList(ResourceHypervisorInfo.fromHostVirtualizerInfo(info))); + logger.debug(String.format("save VirtualizerInfoTO for host[uuid:%s] successfully", info.getUuid())); + } + + @Override + public void saveVmInfo(VirtualizerInfoTO info) { + save(Collections.singletonList(ResourceHypervisorInfo.fromVmVirtualizerInfo(info))); + logger.debug(String.format("save VirtualizerInfoTO for vm[uuid:%s] successfully", info.getUuid())); + } + + @Transactional + private void save(List list) { + Map uuidInfoMap = list.stream() + .collect(Collectors.toMap(info -> info.uuid, Function.identity())); + + collectVmMatchTargetUuid(uuidInfoMap); + collectVmMatchTargetVersion(uuidInfoMap); + collectHostMatchTargetInfo(uuidInfoMap); + collectHypervisorInfoVo(uuidInfoMap); + + // Save + List toUpdateList = new ArrayList<>(); + List toPersistList = new ArrayList<>(); + + uuidInfoMap.forEach((uuid, info) -> { + List targets = (info.vo == null) ? toPersistList : toUpdateList; + targets.add(info); + }); + + if (!toUpdateList.isEmpty()) { + db.updateCollection(toUpdateList.stream() + .map(ResourceHypervisorInfo::generate) + .collect(Collectors.toList())); + } + + if (!toPersistList.isEmpty()) { + db.persistCollection(toPersistList.stream() + .map(ResourceHypervisorInfo::generate) + .collect(Collectors.toList())); + } + } + + private void collectVmMatchTargetUuid(Map uuidInfoMap) { + List vmUuidListNeedFindHost = uuidInfoMap.values().stream() + .filter(info -> HostVO.class.getSimpleName().equals(info.matchTargetResourceType)) + .filter(info -> VmInstanceVO.class.getSimpleName().equals(info.resourceType)) + .filter(info -> info.matchTargetUuid == null) + .map(info -> info.uuid) + .collect(Collectors.toList()); + if (vmUuidListNeedFindHost.isEmpty()) { + return; + } + + final List vmHostTuples = Q.New(VmInstanceVO.class) + .in(VmInstanceVO_.uuid, vmUuidListNeedFindHost) + .select(VmInstanceVO_.uuid, VmInstanceVO_.hostUuid) + .listTuple(); + vmHostTuples.forEach(tuple -> + uuidInfoMap.get(tuple.get(0, String.class)).matchTargetUuid = tuple.get(1, String.class)); + } + + private void collectVmMatchTargetVersion(Map uuidInfoMap) { + Map> targetUuidInfoMap = uuidInfoMap.values().stream() + .filter(info -> info.matchTargetVersion == null) + .filter(info -> HostVO.class.getSimpleName().equals(info.matchTargetResourceType)) + .filter(info -> VmInstanceVO.class.getSimpleName().equals(info.resourceType)) + .collect(Collectors.toMap(info -> info.matchTargetUuid, CollectionDSL::list, CollectionDSL::concat)); + if (targetUuidInfoMap.isEmpty()) { + return; + } + + // find match info from uuidInfoMap + for (Iterator>> it = targetUuidInfoMap.entrySet().iterator(); it.hasNext();) { + final Entry> next = it.next(); + final ResourceHypervisorInfo matchInfo = uuidInfoMap.get(next.getKey()); + if (matchInfo == null) { + continue; + } + + next.getValue().forEach(info -> info.matchTargetVersion = matchInfo.version); + it.remove(); + } + if (targetUuidInfoMap.isEmpty()) { + return; + } + + // find match info from database + List tuples = Q.New(KvmHypervisorInfoVO.class) + .in(KvmHypervisorInfoVO_.uuid, targetUuidInfoMap.keySet()) + .select(KvmHypervisorInfoVO_.uuid, KvmHypervisorInfoVO_.version) + .listTuple(); + for (Tuple tuple : tuples) { + String targetUuid = tuple.get(0, String.class); + targetUuidInfoMap.get(targetUuid).forEach(info -> info.matchTargetVersion = tuple.get(1, String.class)); + } + } + + private void collectHostMatchTargetInfo(Map uuidInfoMap) { + Set hostUuidSet = uuidInfoMap.values().stream() + .filter(info -> info.matchTargetVersion == null) + .filter(info -> HostVO.class.getSimpleName().equals(info.resourceType)) + .filter(info -> KvmHostHypervisorMetadataVO.class.getSimpleName().equals(info.matchTargetResourceType)) + .map(info -> info.uuid) + .collect(Collectors.toSet()); + if (hostUuidSet.isEmpty()) { + return; + } + + final Map uuidCategoryMap = + KvmHypervisorInfoHelper.collectExpectedHypervisorInfoForHosts(hostUuidSet); + uuidCategoryMap.forEach((uuid, category) -> { + if (category == null) { + return; + } + + ResourceHypervisorInfo info = uuidInfoMap.get(uuid); + final KvmHostHypervisorMetadataVO metadata = category.getMetadataList() + .stream() + .filter(m -> m.getHypervisor().equals(info.virtualizer)) + .findAny() + .orElse(null); + if (metadata == null) { + return; + } + + info.matchTargetUuid = metadata.getUuid(); + info.matchTargetVersion = metadata.getVersion(); + }); + } + + private void collectHypervisorInfoVo(Map uuidInfoMap) { + List voList = Q.New(KvmHypervisorInfoVO.class) + .in(KvmHypervisorInfoVO_.uuid, uuidInfoMap.keySet()) + .list(); + + for (KvmHypervisorInfoVO vo : voList) { + final ResourceHypervisorInfo info = uuidInfoMap.get(vo.getUuid()); + if (info != null) { + info.vo = vo; + } + } + } + + private KvmHypervisorInfoVO updateKvmHypervisorInfoVO(String uuid, KvmHypervisorInfoVO vo, VirtualizerInfoTO to) { + if (vo == null) { + vo = new KvmHypervisorInfoVO(); + vo.setUuid(uuid); + } + vo.setHypervisor(to.getVirtualizer()); + vo.setVersion(to.getVersion()); + return vo; + } + + @Override + public void clean(String uuid) { + SQL.New(KvmHypervisorInfoVO.class).eq(KvmHypervisorInfoVO_.uuid, uuid).delete(); + } + + @Override + public void refreshMetadata() { + List collected = collector.collect(); + boolean anyRecordUpdated = saveMetadataList(collected); + if (anyRecordUpdated) { + refreshHostMatchState(); + } + } + + private void registerRefreshVmHypervisorHooks() { + events.on(VmCanonicalEvents.VM_LIBVIRT_REPORT_REBOOT, new EventCallback() { + @Override + protected void run(Map tokens, Object data) { + onVmStart(data.toString()); + } + }); + events.on(VmCanonicalEvents.VM_LIBVIRT_REPORT_START, new EventCallback() { + @Override + protected void run(Map tokens, Object data) { + onVmStart(data.toString()); + } + }); + } + + private void onVmStart(String vmUuid) { + final String hostUuid = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, vmUuid) + .eq(VmInstanceVO_.hypervisorType, KVMConstant.KVM_HYPERVISOR_TYPE) + .select(VmInstanceVO_.hostUuid) + .findValue(); + if (hostUuid == null) { + // This is not a KVM VM (maybe bare-metal) + return; + } + + final GetVirtualizerInfoMsg message = new GetVirtualizerInfoMsg(); + message.setHostUuid(hostUuid); + message.setVmInstanceUuids(Collections.singletonList(vmUuid)); + bus.makeTargetServiceIdByResourceUuid(message, HostConstant.SERVICE_ID, hostUuid); + bus.send(message); // no need to reply + } + + private boolean saveMetadataList(List definitions) { + List categoryVOS = definitions.stream() + .map(this::mapToHostOsCategory) + .collect(Collectors.collectingAndThen( + Collectors.toCollection(() -> new TreeSet<>(Comparator + .comparing(HostOsCategoryVO::getArchitecture) + .thenComparing(HostOsCategoryVO::getOsReleaseVersion))), ArrayList::new)); + return saveHostOsCategoryList(categoryVOS); + } + + @Transactional + protected boolean saveHostOsCategoryList(List categoryVOS) { + // refresh all metadata with current management node + SQL.New(KvmHostHypervisorMetadataVO.class) + .eq(KvmHostHypervisorMetadataVO_.managementNodeUuid, Platform.getManagementServerId()) + .delete(); + if (CollectionUtils.isEmpty(categoryVOS)) { + return false; + } + + Set requestArchitectures = categoryVOS.stream() + .map(HostOsCategoryVO::getArchitecture) + .collect(Collectors.toSet()); + Set requestOsReleaseVersions = categoryVOS.stream() + .map(HostOsCategoryVO::getOsReleaseVersion) + .collect(Collectors.toSet()); + List existsCategories = Q.New(HostOsCategoryVO.class) + .in(HostOsCategoryVO_.architecture, requestArchitectures) + .in(HostOsCategoryVO_.osReleaseVersion, requestOsReleaseVersions) + .list(); + + List needPersistCategories = new ArrayList<>(); + List metadataList = new ArrayList<>(); + + // fill KvmHostHypervisorMetadataVO.categoryUuid + // fill HostOsCategoryVO.uuid if it is new + for (HostOsCategoryVO category : categoryVOS) { + HostOsCategoryVO realCategory = existsCategories.stream() + .filter(c -> c.getArchitecture().equals(category.getArchitecture())) + .filter(c -> c.getOsReleaseVersion().equals(category.getOsReleaseVersion())) + .findAny().orElse(null); + + if (realCategory == null) { + String newUuid = Platform.getUuid(); + category.setUuid(newUuid); + category.getMetadataList().forEach(m -> m.setCategoryUuid(newUuid)); + needPersistCategories.add(category); + } else { + String uuid = realCategory.getUuid(); + category.getMetadataList().forEach(m -> m.setCategoryUuid(uuid)); + } + + metadataList.addAll(category.getMetadataList()); + } + + boolean anyRecordUpdated = false; + if (!needPersistCategories.isEmpty()) { + db.persistCollection(needPersistCategories); + anyRecordUpdated = true; + } + if (!metadataList.isEmpty()) { + db.persistCollection(metadataList); + anyRecordUpdated = true; + } + return anyRecordUpdated; + } + + private void refreshHostMatchState() { + Function sqlGenerator = fragment -> String.format( + "select " + + "%s " + + "from " + + "KvmHypervisorInfoVO hyper," + + "ResourceVO resource " + + "where " + + "hyper.uuid = resource.uuid " + + "and resource.resourceType = :resourceType", fragment); + + Long count = SQL.New(sqlGenerator.apply("count(*)"), Long.class) + .param("resourceType", HostVO.class.getSimpleName()) + .find(); + + Map originStateMap = new HashMap<>(); + Map stateMap = new HashMap<>(); + SQL.New(sqlGenerator.apply("hyper.uuid, hyper.matchState "), Tuple.class) + .param("resourceType", HostVO.class.getSimpleName()) + .limit(100) + .paginate(count, (List tuples) -> { + final Map map = tuples.stream().collect(Collectors.toMap( + tuple -> tuple.get(0, String.class), + tuple -> tuple.get(1, HypervisorVersionState.class) + )); + originStateMap.putAll(map); + stateMap.putAll(refreshHostMatchStateFragment(map.keySet())); + }); + + // key: state, value: [KvmHypervisorInfoVO.uuid] + Map> updatedMap = new HashMap<>(); + originStateMap.forEach((uuid, originState) -> { + final HypervisorVersionState state = stateMap.get(uuid); + if (originState == state) { + return; + } + updatedMap.compute(state, (v, list) -> { + if (list == null) { + return new ArrayList<>(Arrays.asList(uuid)); + } + list.add(uuid); + return list; + }); + }); + + updatedMap.forEach((state, uuidList) -> + SQL.New(KvmHypervisorInfoVO.class) + .in(KvmHypervisorInfoVO_.uuid, uuidList) + .set(KvmHypervisorInfoVO_.matchState, state) + .update() + ); + } + + private Map refreshHostMatchStateFragment(Set hyperUuidSet) { + return ResourceHypervisorInfo.from(hyperUuidSet).stream() + .collect(Collectors.toMap( + hyper -> hyper.uuid, + hyper -> KvmHypervisorInfoHelper.isQemuVersionMatched(hyper.version, hyper.matchTargetVersion) + )); + } + + /** + * note: + * HostOsCategoryVO.uuid is empty + * KvmHostHypervisorMetadataVO.categoryUuid is empty + */ + private HostOsCategoryVO mapToHostOsCategory(HypervisorMetadataDefinition definition) { + HostOsCategoryVO vo = new HostOsCategoryVO(); + + vo.setArchitecture(definition.getArchitecture()); + vo.setOsReleaseVersion(definition.getOsReleaseVersion()); + + KvmHostHypervisorMetadataVO metadata = new KvmHostHypervisorMetadataVO(); + metadata.setUuid(Platform.getUuid()); + metadata.setManagementNodeUuid(Platform.getManagementServerId()); + metadata.setHypervisor(definition.getHypervisor()); + metadata.setVersion(definition.getVersion()); + vo.setMetadataList(Arrays.asList(metadata)); + + return vo; + } + + @Override + public boolean start() { + refreshMetadata(); + registerRefreshVmHypervisorHooks(); + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorZQLExtension.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorZQLExtension.java new file mode 100644 index 00000000000..d6703f4b92b --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmHypervisorZQLExtension.java @@ -0,0 +1,49 @@ +package org.zstack.kvm.hypervisor; + +import org.zstack.header.identity.AccountConstant; +import org.zstack.header.zql.ASTNode; +import org.zstack.header.zql.MarshalZQLASTTreeExtensionPoint; +import org.zstack.header.zql.RestrictByExprExtensionPoint; +import org.zstack.header.zql.ZQLExtensionContext; +import org.zstack.kvm.hypervisor.datatype.KvmHypervisorInfoInventory; +import org.zstack.zql.ZQLContext; +import org.zstack.zql.ast.ZQLMetadata; + +/** + * Created by Wenhao.Zhang on 23/03/09 + */ +public class KvmHypervisorZQLExtension implements MarshalZQLASTTreeExtensionPoint, RestrictByExprExtensionPoint { + private static final String KVM_RESOURCE_OWNER_NAME = "__KVM_RESOURCE_OWNER_NAME__"; + private static final String KVM_RESOURCE_OWNER_FIELD = "__KVM_RESOURCE_OWNER_FIELD__"; + + @Override + public void marshalZQLASTTree(ASTNode.Query node) { + if (KvmHypervisorInfoInventory.class.getName().equals(ZQLContext.getQueryTargetInventoryName())) { + ASTNode.RestrictExpr expr = new ASTNode.RestrictExpr(); + expr.setEntity(KVM_RESOURCE_OWNER_NAME); + expr.setField(KVM_RESOURCE_OWNER_FIELD); + node.addRestrictExpr(expr); + } + } + + @Override + public String restrictByExpr(ZQLExtensionContext context, ASTNode.RestrictExpr expr) { + if (KVM_RESOURCE_OWNER_FIELD.equals(expr.getField()) && KVM_RESOURCE_OWNER_NAME.equals(expr.getEntity())) { + return filterResourceOwner(context); + } + + return null; + } + + protected String filterResourceOwner(ZQLExtensionContext context) { + if (AccountConstant.isAdminPermission(context.getAPISession())) { + throw new SkipThisRestrictExprException(); + } + + ZQLMetadata.InventoryMetadata src = ZQLMetadata.getInventoryMetadataByName(context.getQueryTargetInventoryName()); + return String.format("%s.uuid in (select info.uuid from KvmHypervisorInfoVO info, AccountResourceRefVO ref" + + " where info.uuid = ref.resourceUuid" + + " and ref.accountUuid = '%s')", + src.simpleInventoryName(), context.getAPISession().getAccountUuid()); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmUserVmConfigurationFactory.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmUserVmConfigurationFactory.java new file mode 100644 index 00000000000..5261d71a98f --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/KvmUserVmConfigurationFactory.java @@ -0,0 +1,48 @@ +package org.zstack.kvm.hypervisor; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.vm.UserVmFactory; +import org.zstack.core.config.schema.GuestOsCharacter; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.kvm.KVMGlobalConfig; +import org.zstack.kvm.KVMSubTypeVmConfigurationFactory; +import org.zstack.core.config.GuestOsHelper; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class KvmUserVmConfigurationFactory implements KVMSubTypeVmConfigurationFactory { + private static final CLogger logger = Utils.getLogger(KvmUserVmConfigurationFactory.class); + + @Autowired + private UserVmFactory userVmFactory; + @Autowired + private ResourceConfigFacade rcf; + + @Override + public String getVmInstanceType() { + return userVmFactory.getType().toString(); + } + + @Override + public void createConfigurations(VmInstanceSpec spec) { + GuestOsCharacter.Config config = GuestOsHelper.getInstance() + .getGuestOsCharacter( + spec.getVmInventory().getArchitecture(), + spec.getVmInventory().getPlatform(), + spec.getVmInventory().getGuestOsType()); + if (config == null) { + logger.warn(String.format("cannot find guest os character for vm[uuid:%s, arch:%s, platform:%s, guestOsType:%s]", + spec.getVmInventory().getUuid(), spec.getVmInventory().getArchitecture(), spec.getVmInventory().getPlatform(), spec.getVmInventory().getGuestOsType())); + return; + } + + if (config.getCpuModel() == null) { + return; + } + + ResourceConfig resourceConfig = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + resourceConfig.updateValue(spec.getVmInventory().getUuid(), config.getCpuModel()); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryInventory.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryInventory.java new file mode 100644 index 00000000000..fb41cff6c43 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryInventory.java @@ -0,0 +1,90 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@PythonClassInventory +@Inventory(mappingVOClass = HostOsCategoryVO.class, collectionValueOfMethod = "valueOf1") +public class HostOsCategoryInventory implements Serializable { + private String uuid; + private String architecture; + private String osReleaseVersion; + private List metadataList; + private Timestamp createDate; + private Timestamp lastOpDate; + + public HostOsCategoryInventory() { + } + + public static HostOsCategoryInventory valueOf(HostOsCategoryVO vo) { + HostOsCategoryInventory inv = new HostOsCategoryInventory(); + inv.setUuid(vo.getUuid()); + inv.setArchitecture(vo.getArchitecture()); + inv.setOsReleaseVersion(vo.getOsReleaseVersion()); + inv.setMetadataList(KvmHostHypervisorMetadataInventory.valueOf1(vo.getMetadataList())); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf1(Collection vos) { + return vos.stream().map(HostOsCategoryInventory::valueOf).collect(Collectors.toList()); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public String getOsReleaseVersion() { + return osReleaseVersion; + } + + public void setOsReleaseVersion(String osReleaseVersion) { + this.osReleaseVersion = osReleaseVersion; + } + + public List getMetadataList() { + return metadataList; + } + + public void setMetadataList(List metadataList) { + this.metadataList = metadataList; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryInventoryDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..ad5d827c414 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryInventoryDoc_zh_cn.groovy @@ -0,0 +1,48 @@ +package org.zstack.kvm.hypervisor.datatype + +import org.zstack.kvm.hypervisor.datatype.KvmHostHypervisorMetadataInventory +import java.sql.Timestamp + +doc { + + title "支持的物理机类型条目" + + field { + name "uuid" + desc "资源的UUID,唯一标示该条目" + type "String" + since "4.6.21" + } + field { + name "architecture" + desc "物理机架构,比如 \"x86_64\"" + type "String" + since "4.6.21" + } + field { + name "osReleaseVersion" + desc "物理机操作系统版本,比如 \"centos Core 7.6.1810\"" + type "String" + since "4.6.21" + } + ref { + name "metadataList" + path "org.zstack.kvm.hypervisor.datatype.HostOsCategoryInventory.metadataList" + desc "null" + type "List" + since "4.6.21" + clz KvmHostHypervisorMetadataInventory.class + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.6.21" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.6.21" + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryVO.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryVO.java new file mode 100644 index 00000000000..e971d96c037 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryVO.java @@ -0,0 +1,91 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.zstack.header.host.HostAO; +import org.zstack.header.vo.Index; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; +import java.util.List; + +@Entity +@Table +public class HostOsCategoryVO implements ToInventory { + @Id + @Column + @Index + private String uuid; + /** + * equals to {@link HostAO#getArchitecture()} + */ + @Column + private String architecture; + /** + * "centos Core 7.6.1810" / "centos Core 7.4.1708" ... + */ + @Column + private String osReleaseVersion; + + @Column + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "categoryUuid", insertable = false, updatable = false) + private List metadataList; + + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getArchitecture() { + return architecture; + } + + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public String getOsReleaseVersion() { + return osReleaseVersion; + } + + public void setOsReleaseVersion(String osReleaseVersion) { + this.osReleaseVersion = osReleaseVersion; + } + + public List getMetadataList() { + return metadataList; + } + + public void setMetadataList(List metadataList) { + this.metadataList = metadataList; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryVO_.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryVO_.java new file mode 100644 index 00000000000..4faedea8b93 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HostOsCategoryVO_.java @@ -0,0 +1,14 @@ +package org.zstack.kvm.hypervisor.datatype; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(HostOsCategoryVO.class) +public class HostOsCategoryVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute architecture; + public static volatile SingularAttribute osReleaseVersion; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HypervisorVersionState.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HypervisorVersionState.java new file mode 100644 index 00000000000..39046a013c9 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/HypervisorVersionState.java @@ -0,0 +1,13 @@ +package org.zstack.kvm.hypervisor.datatype; + +public enum HypervisorVersionState { + // all virtualizer device version is matched + Matched, + + // at least one virtualizer device version is unmatched + Unmatched, + + // at least one virtualizer device info is unavailable, + // and none virtualizer device version is unmatched + Unknown +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataInventory.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataInventory.java new file mode 100644 index 00000000000..fdd8bca57d0 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataInventory.java @@ -0,0 +1,100 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@PythonClassInventory +@Inventory(mappingVOClass = KvmHostHypervisorMetadataVO.class, collectionValueOfMethod = "valueOf1") +public class KvmHostHypervisorMetadataInventory implements Serializable { + private String uuid; + private String categoryUuid; + private String managementNodeUuid; + private String hypervisor; + private String version; + private Timestamp createDate; + private Timestamp lastOpDate; + + public KvmHostHypervisorMetadataInventory() { + } + + public static KvmHostHypervisorMetadataInventory valueOf(KvmHostHypervisorMetadataVO vo) { + KvmHostHypervisorMetadataInventory inv = new KvmHostHypervisorMetadataInventory(); + inv.setUuid(vo.getUuid()); + inv.setCategoryUuid(vo.getCategoryUuid()); + inv.setManagementNodeUuid(vo.getManagementNodeUuid()); + inv.setHypervisor(vo.getHypervisor()); + inv.setVersion(vo.getVersion()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf1(Collection vos) { + return vos.stream().map(KvmHostHypervisorMetadataInventory::valueOf).collect(Collectors.toList()); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getCategoryUuid() { + return categoryUuid; + } + + public void setCategoryUuid(String categoryUuid) { + this.categoryUuid = categoryUuid; + } + + public String getManagementNodeUuid() { + return managementNodeUuid; + } + + public void setManagementNodeUuid(String managementNodeUuid) { + this.managementNodeUuid = managementNodeUuid; + } + + public String getHypervisor() { + return hypervisor; + } + + public void setHypervisor(String hypervisor) { + this.hypervisor = hypervisor; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataInventoryDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..a7144ff441f --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataInventoryDoc_zh_cn.groovy @@ -0,0 +1,51 @@ +package org.zstack.kvm.hypervisor.datatype + +import java.sql.Timestamp + +doc { + + title "支持的物理机元数据" + + field { + name "uuid" + desc "资源的UUID,唯一标示该条目" + type "String" + since "4.6.21" + } + field { + name "categoryUuid" + desc "支持的物理机类型条目 UUID" + type "String" + since "4.6.21" + } + field { + name "managementNodeUuid" + desc "管理节点 UUID" + type "String" + since "4.6.21" + } + field { + name "hypervisor" + desc "虚拟化软件名称,比如 \"qemu-kvm\"" + type "String" + since "4.6.21" + } + field { + name "version" + desc "版本号,比如 \"4.2.0-632.g6a6222b.el7\"" + type "String" + since "4.6.21" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.6.21" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.6.21" + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataVO.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataVO.java new file mode 100644 index 00000000000..87563f55ea8 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataVO.java @@ -0,0 +1,98 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.zstack.header.vo.Index; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class KvmHostHypervisorMetadataVO implements ToInventory { + @Id + @Column + @Index + private String uuid; + /** + * @see HostOsCategoryVO + */ + @Column + private String categoryUuid; + @Column + private String managementNodeUuid; + /** + * "qemu-kvm" + */ + @Column + private String hypervisor; + /** + * hypervisor version. "4.2.0-632.g6a6222b.el7" + */ + @Column + private String version; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getCategoryUuid() { + return categoryUuid; + } + + public void setCategoryUuid(String categoryUuid) { + this.categoryUuid = categoryUuid; + } + + public String getManagementNodeUuid() { + return managementNodeUuid; + } + + public void setManagementNodeUuid(String managementNodeUuid) { + this.managementNodeUuid = managementNodeUuid; + } + + public String getHypervisor() { + return hypervisor; + } + + public void setHypervisor(String hypervisor) { + this.hypervisor = hypervisor; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataVO_.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataVO_.java new file mode 100644 index 00000000000..c93baedf8ed --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHostHypervisorMetadataVO_.java @@ -0,0 +1,19 @@ +package org.zstack.kvm.hypervisor.datatype; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@StaticMetamodel(KvmHostHypervisorMetadataVO.class) +public class KvmHostHypervisorMetadataVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute categoryUuid; + public static volatile SingularAttribute managementNodeUuid; + public static volatile SingularAttribute hypervisor; + public static volatile SingularAttribute version; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoInventory.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoInventory.java new file mode 100644 index 00000000000..759c640f761 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoInventory.java @@ -0,0 +1,96 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.vo.ResourceInventory; + +import java.sql.Timestamp; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@PythonClassInventory +@Inventory(mappingVOClass = KvmHypervisorInfoVO.class, collectionValueOfMethod = "valueOf1") +@ExpandedQueries({ + @ExpandedQuery(expandedField = "resource", inventoryClass = ResourceInventory.class, + foreignKey = "resourceUuid", expandedInventoryKey = "uuid"), +}) +public class KvmHypervisorInfoInventory { + private String uuid; + private String hypervisor; + private String version; + private HypervisorVersionState matchState; + private Timestamp createDate; + private Timestamp lastOpDate; + + public KvmHypervisorInfoInventory() { + } + + public static KvmHypervisorInfoInventory valueOf(KvmHypervisorInfoVO vo) { + KvmHypervisorInfoInventory inv = new KvmHypervisorInfoInventory(); + inv.setUuid(vo.getUuid()); + inv.setHypervisor(vo.getHypervisor()); + inv.setVersion(vo.getVersion()); + inv.setMatchState(vo.getMatchState()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf1(Collection vos) { + return vos.stream().map(KvmHypervisorInfoInventory::valueOf).collect(Collectors.toList()); + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHypervisor() { + return hypervisor; + } + + public void setHypervisor(String hypervisor) { + this.hypervisor = hypervisor; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public HypervisorVersionState getMatchState() { + return matchState; + } + + public void setMatchState(HypervisorVersionState matchState) { + this.matchState = matchState; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoInventoryDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..a574aa8f7e9 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoInventoryDoc_zh_cn.groovy @@ -0,0 +1,45 @@ +package org.zstack.kvm.hypervisor.datatype + +import java.sql.Timestamp + +doc { + + title "当前物理机 / VM 使用的监控软件的信息" + + field { + name "uuid" + desc "资源的UUID,为物理机 / VM 的 UUID" + type "String" + since "4.6.21" + } + field { + name "hypervisor" + desc "虚拟化软件名称,比如 \"qemu-kvm\"" + type "String" + since "4.6.21" + } + field { + name "version" + desc "版本号,比如 \"4.2.0-632.g6a6222b.el7\"" + type "String" + since "4.6.21" + } + field { + name "matchState" + desc "和预期版本号的匹配状态,可能的值为 \"Matched\", \"Unmatched\", \"Unknown\"" + type "String" + since "4.6.21" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.6.21" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.6.21" + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoVO.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoVO.java new file mode 100644 index 00000000000..d0c23d180f7 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoVO.java @@ -0,0 +1,103 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.zstack.header.vo.*; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.Index; +import org.zstack.kvm.KVMConstant; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@EntityGraph( + parents = { + @EntityGraph.Neighbour(type = ResourceVO.class, myField = "uuid", targetField = "uuid"), + } +) +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = ResourceVO.class, joinColumn = "uuid"), +}) +public class KvmHypervisorInfoVO implements ToInventory { + /** + * Maybe host UUID or VM UUID + */ + @Id + @Column + @Index + private String uuid; + /** + * "qemu-kvm" + * @see KVMConstant#VIRTUALIZER_QEMU_KVM + */ + @Column + private String hypervisor; + /** + * hypervisor version. "4.2.0-632.g6a6222b.el7" + */ + @Column + private String version; + /** + * Is the version match with expected + */ + @Column + @Enumerated(EnumType.STRING) + private HypervisorVersionState matchState; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHypervisor() { + return hypervisor; + } + + public void setHypervisor(String hypervisor) { + this.hypervisor = hypervisor; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public HypervisorVersionState getMatchState() { + return matchState; + } + + public void setMatchState(HypervisorVersionState matchState) { + this.matchState = matchState; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoVO_.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoVO_.java new file mode 100644 index 00000000000..a4547d7be15 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/KvmHypervisorInfoVO_.java @@ -0,0 +1,18 @@ +package org.zstack.kvm.hypervisor.datatype; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@StaticMetamodel(KvmHypervisorInfoVO.class) +public class KvmHypervisorInfoVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute hypervisor; + public static volatile SingularAttribute version; + public static volatile SingularAttribute matchState; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/ResourceHypervisorInfo.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/ResourceHypervisorInfo.java new file mode 100644 index 00000000000..b25573c64d9 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/datatype/ResourceHypervisorInfo.java @@ -0,0 +1,186 @@ +package org.zstack.kvm.hypervisor.datatype; + +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.db.Q; +import org.zstack.header.host.HostVO; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ResourceVO_; +import org.zstack.kvm.hypervisor.KvmHypervisorInfoHelper; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.zstack.kvm.KVMAgentCommands.VirtualizerInfoTO; + +/** + * Created by Wenhao.Zhang on 23/07/06 + */ +public class ResourceHypervisorInfo { + public String uuid; + public String resourceType; + public String virtualizer; + public String version; + + public String matchTargetUuid; + public String matchTargetResourceType; + public String matchTargetVersion; + + public KvmHypervisorInfoVO vo; + + public static ResourceHypervisorInfo fromVmVirtualizerInfo(VirtualizerInfoTO info) { + return fromVmVirtualizerInfo(info, null); + } + + public static ResourceHypervisorInfo fromVmVirtualizerInfo(VirtualizerInfoTO info, String hostUuid) { + ResourceHypervisorInfo result = from(info); + result.resourceType = VmInstanceVO.class.getSimpleName(); + result.matchTargetResourceType = HostVO.class.getSimpleName(); + result.matchTargetUuid = hostUuid; + return result; + } + + public static ResourceHypervisorInfo fromHostVirtualizerInfo(VirtualizerInfoTO info) { + ResourceHypervisorInfo result = from(info); + result.resourceType = HostVO.class.getSimpleName(); + result.matchTargetResourceType = KvmHostHypervisorMetadataVO.class.getSimpleName(); + return result; + } + + public static ResourceHypervisorInfo from(VirtualizerInfoTO info) { + ResourceHypervisorInfo result = new ResourceHypervisorInfo(); + result.uuid = info.getUuid(); + result.virtualizer = info.getVirtualizer(); + result.version = info.getVersion(); + return result; + } + + @Transactional(readOnly = true) + public static List from(Collection uuidSet) { + List list = Q.New(KvmHypervisorInfoVO.class) + .in(KvmHypervisorInfoVO_.uuid, uuidSet) + .list(); + Map uuidVoMap = list.stream() + .collect(Collectors.toMap(KvmHypervisorInfoVO::getUuid, Function.identity())); + + List results = Q.New(ResourceVO.class) + .select(ResourceVO_.uuid, ResourceVO_.resourceType) + .in(ResourceVO_.uuid, uuidSet) + .listTuple() + .stream() + .map(tuple -> { + String uuid = tuple.get(0, String.class); + String type = tuple.get(1, String.class); + return mapResourceHypervisorInfo(uuid, type, uuidVoMap.get(uuid)); + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + + fillMatchTargetInfo(results); + return results; + } + + private static ResourceHypervisorInfo mapResourceHypervisorInfo(String uuid, String type, KvmHypervisorInfoVO vo) { + if (vo == null) { + // maybe vm is in stopped states + return null; + } + + ResourceHypervisorInfo target = new ResourceHypervisorInfo(); + target.uuid = uuid; + target.resourceType = type; + target.virtualizer = vo.getHypervisor(); + target.version = vo.getVersion(); + // matchTargetUuid, matchTargetResourceType, matchTargetVersion is empty + + return target; + } + + private static void fillMatchTargetInfo(List inventories) { + // collect expect version of VM : from host Kvm hypervisor info + List vmInventories = inventories.stream() + .filter(inv -> inv.resourceType.equals(VmInstanceVO.class.getSimpleName())) + .collect(Collectors.toList()); + if (!vmInventories.isEmpty()) { + collectMatchTargetOfVm(vmInventories); + } + + // collect expect version of Host : from HostOsCategoryVO + List hostInventories = inventories.stream() + .filter(inv -> inv.resourceType.equals(HostVO.class.getSimpleName())) + .collect(Collectors.toList()); + if (!hostInventories.isEmpty()) { + collectMatchTargetOfHost(hostInventories); + } + } + + private static void collectMatchTargetOfVm(List inventories) { + inventories.forEach(info -> info.matchTargetResourceType = HostVO.class.getSimpleName()); + + Set vmUuidSet = inventories.stream() + .map(info -> info.uuid) + .collect(Collectors.toSet()); + Map vmHostMap = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.uuid, VmInstanceVO_.hostUuid) + .in(VmInstanceVO_.uuid, vmUuidSet) + .listTuple() + .stream() + .collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, String.class))); + + List hostInfoList = Q.New(KvmHypervisorInfoVO.class) + .in(KvmHypervisorInfoVO_.uuid, vmHostMap.values()) + .list(); + for (ResourceHypervisorInfo vmInventory : inventories) { + String hostUuid = vmHostMap.get(vmInventory.uuid); + KvmHypervisorInfoVO hostVersion = hostInfoList.stream() + .filter(hostInfo -> hostInfo.getUuid().equals(hostUuid)) + .filter(hostInfo -> hostInfo.getHypervisor().equals(vmInventory.virtualizer)) + .findAny() + .orElse(null); + if (hostVersion == null) { + continue; + } + vmInventory.matchTargetVersion = hostVersion.getVersion(); + vmInventory.matchTargetUuid = hostVersion.getUuid(); + } + } + + private static void collectMatchTargetOfHost(List inventories) { + inventories.forEach(info -> info.matchTargetResourceType = KvmHostHypervisorMetadataVO.class.getSimpleName()); + + Map hostExpectedMap = + KvmHypervisorInfoHelper.collectExpectedHypervisorInfoForHosts(inventories.stream() + .map(info -> info.uuid) + .collect(Collectors.toSet())); + + for (ResourceHypervisorInfo hostInventory : inventories) { + HostOsCategoryVO category = hostExpectedMap.get(hostInventory.uuid); + if (category == null) { + continue; + } + KvmHostHypervisorMetadataVO metadata = category.getMetadataList().stream() + .filter(m -> m.getHypervisor().equals(hostInventory.virtualizer)) + .findAny() + .orElse(null); + if (metadata == null) { + continue; + } + hostInventory.matchTargetVersion = metadata.getVersion(); + hostInventory.matchTargetUuid = metadata.getUuid(); + } + } + + public KvmHypervisorInfoVO generate() { + if (vo == null) { + vo = new KvmHypervisorInfoVO(); + vo.setUuid(uuid); + } + vo.setHypervisor(virtualizer); + vo.setVersion(version); + vo.setMatchState(KvmHypervisorInfoHelper.isQemuVersionMatched(version, matchTargetVersion)); + + return vo; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/events/ClusterHostHypervisorMismatchData.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/events/ClusterHostHypervisorMismatchData.java new file mode 100644 index 00000000000..ab03cda655c --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/events/ClusterHostHypervisorMismatchData.java @@ -0,0 +1,58 @@ +package org.zstack.kvm.hypervisor.events; + +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.message.NeedJsonSchema; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.hypervisor.datatype.KvmHostHypervisorMetadataVO; +import org.zstack.kvm.hypervisor.datatype.KvmHypervisorInfoVO; + +/** + * Cluster host hypervisor version not match event data. + * + * Cluster is used as the unit of event reporting instead of host + * to reduce the frequency of event reporting. + * + * Created by Wenhao.Zhang on 23/03/06 + */ +@NeedJsonSchema +public class ClusterHostHypervisorMismatchData { + public static final String PATH = "cluster/hypervisor/mismatch"; + /** + * @see ClusterVO#getUuid() + */ + private String clusterUuid; + /** + * @see KvmHypervisorInfoVO#getHypervisor() + * @see KvmHostHypervisorMetadataVO#getHypervisor() + * @see KVMConstant#VIRTUALIZER_QEMU_KVM + */ + private String hypervisorType; + /** + * Total amount of host in the specific cluster whose hypervisor is expired + */ + private int hostCount; + + public String getClusterUuid() { + return clusterUuid; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public String getHypervisorType() { + return hypervisorType; + } + + public void setHypervisorType(String hypervisorType) { + this.hypervisorType = hypervisorType; + } + + public int getHostCount() { + return hostCount; + } + + public void setHostCount(int hostCount) { + this.hostCount = hostCount; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryMsg.java new file mode 100644 index 00000000000..faffc2ce0c2 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryMsg.java @@ -0,0 +1,26 @@ +package org.zstack.kvm.hypervisor.message; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostConstant; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; +import org.zstack.kvm.hypervisor.datatype.HostOsCategoryInventory; + +import java.util.List; + +import static java.util.Arrays.asList; + +@AutoQuery(replyClass = APIQueryHostOsCategoryReply.class, inventoryClass = HostOsCategoryInventory.class) +@RestRequest( + path = "/hosts/os/category", + responseClass = APIQueryHostOsCategoryReply.class, + method = HttpMethod.GET +) +@Action(category = HostConstant.ACTION_CATEGORY, names = {"read"}) +public class APIQueryHostOsCategoryMsg extends APIQueryMessage { + public static List __example__() { + return asList("architecture=x86_64", "osReleaseVersion=\"centos core 7.6.1810\""); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..44edf7e0245 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryMsgDoc_zh_cn.groovy @@ -0,0 +1,30 @@ +package org.zstack.kvm.hypervisor.message + +import org.zstack.kvm.hypervisor.message.APIQueryHostOsCategoryReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryHostOsCategory" + + category "host" + + desc """查询物理机系统类型""" + + rest { + request { + url "GET /v1/hosts/os/category" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryHostOsCategoryMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryHostOsCategoryReply.class + } + } +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryReply.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryReply.java new file mode 100644 index 00000000000..9755b612771 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryReply.java @@ -0,0 +1,48 @@ +package org.zstack.kvm.hypervisor.message; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.kvm.hypervisor.datatype.HostOsCategoryInventory; +import org.zstack.kvm.hypervisor.datatype.KvmHostHypervisorMetadataInventory; + +import java.sql.Timestamp; +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@RestResponse(allTo = "inventories") +public class APIQueryHostOsCategoryReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryHostOsCategoryReply __example__() { + APIQueryHostOsCategoryReply reply = new APIQueryHostOsCategoryReply(); + HostOsCategoryInventory inv = new HostOsCategoryInventory(); + inv.setArchitecture("x86_64"); + inv.setOsReleaseVersion("centos Core 7.6.1810"); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + + KvmHostHypervisorMetadataInventory metadata = new KvmHostHypervisorMetadataInventory(); + metadata.setManagementNodeUuid(uuid()); + metadata.setHypervisor("qemu-kvm"); + metadata.setVersion("4.2.0-632.g6a6222b.el7"); + metadata.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + metadata.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setMetadataList(asList(metadata)); + + reply.setSuccess(true); + reply.setInventories(asList(inv)); + return reply; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryReplyDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..042a8ed7e74 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryHostOsCategoryReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.kvm.hypervisor.message + +import org.zstack.kvm.hypervisor.datatype.HostOsCategoryInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询物理机系统类型结果" + + ref { + name "inventories" + path "org.zstack.kvm.hypervisor.message.APIQueryHostOsCategoryReply.inventories" + desc "null" + type "List" + since "4.6.21" + clz HostOsCategoryInventory.class + } + field { + name "success" + desc "查询是否成功" + type "boolean" + since "4.6.21" + } + ref { + name "error" + path "org.zstack.kvm.hypervisor.message.APIQueryHostOsCategoryReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.21" + clz ErrorCode.class + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoMsg.java new file mode 100644 index 00000000000..1e5b8b51eaf --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoMsg.java @@ -0,0 +1,29 @@ +package org.zstack.kvm.hypervisor.message; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostConstant; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; +import org.zstack.kvm.hypervisor.datatype.KvmHypervisorInfoInventory; + +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@AutoQuery(replyClass = APIQueryKvmHypervisorInfoReply.class, inventoryClass = KvmHypervisorInfoInventory.class) +@RestRequest( + path = "/hosts/kvm/hypervisor/info", + responseClass = APIQueryKvmHypervisorInfoReply.class, + method = HttpMethod.GET +) +@Action(category = HostConstant.ACTION_CATEGORY, names = {"read"}) +public class APIQueryKvmHypervisorInfoMsg extends APIQueryMessage { + public static List __example__() { + return asList("uuid=" + uuid()); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..d5c3085d39d --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoMsgDoc_zh_cn.groovy @@ -0,0 +1,30 @@ +package org.zstack.kvm.hypervisor.message + +import org.zstack.kvm.hypervisor.message.APIQueryKvmHypervisorInfoReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryKvmHypervisorInfo" + + category "host" + + desc """查询资源的虚拟化软件信息""" + + rest { + request { + url "GET /v1/hosts/kvm/hypervisor/info" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryKvmHypervisorInfoMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQueryKvmHypervisorInfoReply.class + } + } +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoReply.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoReply.java new file mode 100644 index 00000000000..ed3e1129c5b --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoReply.java @@ -0,0 +1,42 @@ +package org.zstack.kvm.hypervisor.message; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; +import org.zstack.kvm.hypervisor.datatype.HypervisorVersionState; +import org.zstack.kvm.hypervisor.datatype.KvmHypervisorInfoInventory; + +import java.sql.Timestamp; +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created by Wenhao.Zhang on 23/02/23 + */ +@RestResponse(allTo = "inventories") +public class APIQueryKvmHypervisorInfoReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryKvmHypervisorInfoReply __example__() { + APIQueryKvmHypervisorInfoReply reply = new APIQueryKvmHypervisorInfoReply(); + KvmHypervisorInfoInventory inv = new KvmHypervisorInfoInventory(); + inv.setUuid(uuid()); + inv.setHypervisor("qemu-kvm"); + inv.setVersion("4.2.0-632.g6a6222b.el7"); + inv.setMatchState(HypervisorVersionState.Matched); + inv.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inv.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + + reply.setSuccess(true); + reply.setInventories(asList(inv)); + return reply; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoReplyDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..2a2bddfe5d9 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/APIQueryKvmHypervisorInfoReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.kvm.hypervisor.message + +import org.zstack.kvm.hypervisor.datatype.KvmHypervisorInfoInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询资源的虚拟化软件信息结果" + + ref { + name "inventories" + path "org.zstack.kvm.hypervisor.message.APIQueryKvmHypervisorInfoReply.inventories" + desc "null" + type "List" + since "4.6.21" + clz KvmHypervisorInfoInventory.class + } + field { + name "success" + desc "查询是否成功" + type "boolean" + since "4.6.21" + } + ref { + name "error" + path "org.zstack.kvm.hypervisor.message.APIQueryKvmHypervisorInfoReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.6.21" + clz ErrorCode.class + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/PackageInfo.java b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/PackageInfo.java new file mode 100644 index 00000000000..59196d22411 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/hypervisor/message/PackageInfo.java @@ -0,0 +1,10 @@ +package org.zstack.kvm.hypervisor.message; + +import org.zstack.header.PackageAPIInfo; + +@PackageAPIInfo( + APICategoryName = "KVM物理机", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) +public class PackageInfo { +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptEvent.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptEvent.java new file mode 100644 index 00000000000..075d2f08825 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptEvent.java @@ -0,0 +1,31 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APICreateVmUserDefinedXmlHookScriptEvent extends APIEvent { + private XmlHookInventory inventory; + + public APICreateVmUserDefinedXmlHookScriptEvent() { + } + + public APICreateVmUserDefinedXmlHookScriptEvent(String apiId) { + super(apiId); + } + + public XmlHookInventory getInventory() { + return inventory; + } + + public void setInventory(XmlHookInventory inventory) { + this.inventory = inventory; + } + + public static APICreateVmUserDefinedXmlHookScriptEvent __example__() { + APICreateVmUserDefinedXmlHookScriptEvent event = new APICreateVmUserDefinedXmlHookScriptEvent(); + XmlHookInventory inventory = new XmlHookInventory(); + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..ee5ffc81172 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.XmlHookInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "创建用户自定义xml hook返回" + + ref { + name "inventory" + path "org.zstack.kvm.xmlhook.APCreateVmUserDefinedXmlHookScriptEvent.inventory" + desc "null" + type "XmlHookInventory" + since "5.2.0" + clz XmlHookInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.2.0" + } + ref { + name "error" + path "org.zstack.kvm.xmlhook.APCreateVmUserDefinedXmlHookScriptEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.0" + clz ErrorCode.class + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptMsg.java new file mode 100644 index 00000000000..7d4a95ac422 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptMsg.java @@ -0,0 +1,64 @@ +package org.zstack.kvm.xmlhook; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.*; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +import java.util.concurrent.TimeUnit; + +@RestRequest( + path = "/vm-instances/xml-hook-script", + method = HttpMethod.POST, + responseClass = APICreateVmUserDefinedXmlHookScriptEvent.class, + parameterName = "params" +) +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 12) +public class APICreateVmUserDefinedXmlHookScriptMsg extends APICreateMessage implements APIAuditor { + @APIParam(maxLength = 255) + private String name; + + @APIParam(required = false, maxLength = 2048) + private String description; + + @APIParam + private String hookScript; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getHookScript() { + return hookScript; + } + + public void setHookScript(String hookScript) { + this.hookScript = hookScript; + } + + public static APICreateVmUserDefinedXmlHookScriptMsg __example__() { + APICreateVmUserDefinedXmlHookScriptMsg msg = new APICreateVmUserDefinedXmlHookScriptMsg(); + msg.setName("hook"); + msg.setDescription("xml hook"); + msg.setHookScript("base64"); + return msg; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + APICreateVmUserDefinedXmlHookScriptEvent event = (APICreateVmUserDefinedXmlHookScriptEvent) rsp; + return new APIAuditor.Result(rsp.isSuccess() ? event.getInventory().getUuid() : "", XmlHookVO.class); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..f6b85e444ae --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APICreateVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.APICreateVmUserDefinedXmlHookScriptEvent + +doc { + title "APCreateVmUserDefinedXmlHookScript" + + category "未知类别" + + desc """创建用户自定义xml hook""" + + rest { + request { + url "POST /v1/vm-instances/xml-hook-script" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateVmUserDefinedXmlHookScriptMsg.class + + desc """创建用户自定义xml hook""" + + params { + + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "5.2.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.2.0" + } + column { + name "hookScript" + enclosedIn "params" + desc "xml hook脚本内容" + location "body" + type "String" + optional false + since "5.2.0" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "5.2.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "5.2.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.2.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.2.0" + } + } + } + + response { + clz APICreateVmUserDefinedXmlHookScriptEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptEvent.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptEvent.java new file mode 100644 index 00000000000..4db6b823499 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptEvent.java @@ -0,0 +1,19 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIExpungeVmUserDefinedXmlHookScriptEvent extends APIEvent { + public APIExpungeVmUserDefinedXmlHookScriptEvent() { + } + + public APIExpungeVmUserDefinedXmlHookScriptEvent(String apiId) { + super(apiId); + } + + public static APIExpungeVmUserDefinedXmlHookScriptEvent __example__() { + APIExpungeVmUserDefinedXmlHookScriptEvent event = new APIExpungeVmUserDefinedXmlHookScriptEvent(); + return event; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..91d50a7742e --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "彻底删除用户自定义xml hook脚本返回" + + field { + name "success" + desc "" + type "boolean" + since "5.2.0" + } + ref { + name "error" + path "org.zstack.kvm.xmlhook.APIExpungeVmUserDefinedXmlHookScriptEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.0" + clz ErrorCode.class + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptMsg.java new file mode 100644 index 00000000000..228b314fa0a --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptMsg.java @@ -0,0 +1,35 @@ +package org.zstack.kvm.xmlhook; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/vm-instances/xml-hook-script/{uuid}", + method = HttpMethod.DELETE, + responseClass = APIExpungeVmUserDefinedXmlHookScriptEvent.class +) +public class APIExpungeVmUserDefinedXmlHookScriptMsg extends APIMessage implements XmlHookMessage { + @APIParam(resourceType = XmlHookVO.class) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public static APIExpungeVmUserDefinedXmlHookScriptMsg __example__() { + APIExpungeVmUserDefinedXmlHookScriptMsg msg = new APIExpungeVmUserDefinedXmlHookScriptMsg(); + msg.setUuid(uuid()); + return msg; + } + + @Override + public String getXmlHookUuid() { + return uuid; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..2a1df417940 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIExpungeVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.APIExpungeVmUserDefinedXmlHookScriptEvent + +doc { + title "ExpungeVmUserDefinedXmlHookScript" + + category "host" + + desc """彻底删除用户自定义xml hook脚本""" + + rest { + request { + url "DELETE /v1/vm-instances/xml-hook-script/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIExpungeVmUserDefinedXmlHookScriptMsg.class + + desc """彻底删除用户自定义xml hook脚本""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.2.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.2.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.2.0" + } + } + } + + response { + clz APIExpungeVmUserDefinedXmlHookScriptEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptMsg.java new file mode 100644 index 00000000000..676d9b98fae --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptMsg.java @@ -0,0 +1,23 @@ +package org.zstack.kvm.xmlhook; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +@AutoQuery(replyClass = APIQueryVmUserDefinedXmlHookScriptReply.class, inventoryClass = XmlHookInventory.class) +@RestRequest( + path = "/vm-instances/xml-hook-script", + optionalPaths = {"/vm-instances/xml-hook-script/{uuid}"}, + responseClass = APIQueryVmUserDefinedXmlHookScriptReply.class, + method = HttpMethod.GET +) +public class APIQueryVmUserDefinedXmlHookScriptMsg extends APIQueryMessage { + public static List __example__() { + return asList("uuid=xxx", "name=xxx"); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..e7e43f1c3df --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.APIQueryVmUserDefinedXmlHookScriptReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryVmUserDefinedXmlHookScript" + + category "未知类别" + + desc """查询用户自定义xml hook脚本""" + + rest { + request { + url "GET /v1/vm-instances/xml-hook-script" + url "GET /v1/vm-instances/xml-hook-script/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryVmUserDefinedXmlHookScriptMsg.class + + desc """查询用户自定义xml hook脚本""" + + params APIQueryMessage.class + } + + response { + clz APIQueryVmUserDefinedXmlHookScriptReply.class + } + } +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptReply.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptReply.java new file mode 100644 index 00000000000..97ec73eed6c --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptReply.java @@ -0,0 +1,25 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQueryVmUserDefinedXmlHookScriptReply extends APIQueryReply { + + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryVmUserDefinedXmlHookScriptReply __example__() { + APIQueryVmUserDefinedXmlHookScriptReply reply = new APIQueryVmUserDefinedXmlHookScriptReply(); + return reply; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptReplyDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..66dd7b45d68 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIQueryVmUserDefinedXmlHookScriptReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.XmlHookInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询用户自定义xml hook脚本返回" + + ref { + name "inventories" + path "org.zstack.kvm.xmlhook.APIQueryVmUserDefinedXmlHookScriptReply.inventories" + desc "null" + type "List" + since "5.2.0" + clz XmlHookInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.2.0" + } + ref { + name "error" + path "org.zstack.kvm.xmlhook.APIQueryVmUserDefinedXmlHookScriptReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.0" + clz ErrorCode.class + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptEvent.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptEvent.java new file mode 100644 index 00000000000..7b6e26b931f --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptEvent.java @@ -0,0 +1,29 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIUpdateVmUserDefinedXmlHookScriptEvent extends APIEvent { + private XmlHookInventory inventory; + + public void setInventory(XmlHookInventory inventory) { + this.inventory = inventory; + } + + public APIUpdateVmUserDefinedXmlHookScriptEvent() { + } + + public APIUpdateVmUserDefinedXmlHookScriptEvent(String apiId) { + super(apiId); + } + + public XmlHookInventory getInventory() { + return inventory; + } + + public static APIUpdateVmUserDefinedXmlHookScriptEvent __example__() { + APIUpdateVmUserDefinedXmlHookScriptEvent event = new APIUpdateVmUserDefinedXmlHookScriptEvent(); + return event; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..555234162e2 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.XmlHookInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "更新用户自定义xml hook脚本返回" + + ref { + name "inventory" + path "org.zstack.kvm.xmlhook.APIUpdateVmUserDefinedXmlHookScriptEvent.inventory" + desc "null" + type "XmlHookInventory" + since "5.2.0" + clz XmlHookInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.2.0" + } + ref { + name "error" + path "org.zstack.kvm.xmlhook.APIUpdateVmUserDefinedXmlHookScriptEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.2.0" + clz ErrorCode.class + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptMsg.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptMsg.java new file mode 100644 index 00000000000..f8c59826f75 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptMsg.java @@ -0,0 +1,92 @@ +package org.zstack.kvm.xmlhook; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +import java.util.concurrent.TimeUnit; + +@RestRequest( + path = "/vm-instances/xml-hook-script", + method = HttpMethod.PUT, + isAction = true, + responseClass = APIUpdateVmUserDefinedXmlHookScriptEvent.class +) +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 12) +public class APIUpdateVmUserDefinedXmlHookScriptMsg extends APIMessage implements APIAuditor, XmlHookMessage { + @APIParam(resourceType = XmlHookVO.class) + private String uuid; + + @APIParam(required = false, maxLength = 255) + private String name; + + @APIParam(required = false, maxLength = 2048) + private String description; + + @APIParam(required = false) + private String hookScript; + + @APIParam(validValues = {"Reboot", "None"}, required = false) + private String startupStrategy; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getHookScript() { + return hookScript; + } + + public void setHookScript(String hookScript) { + this.hookScript = hookScript; + } + + public static APIUpdateVmUserDefinedXmlHookScriptMsg __example__() { + APIUpdateVmUserDefinedXmlHookScriptMsg msg = new APIUpdateVmUserDefinedXmlHookScriptMsg(); + msg.setUuid(uuid()); + msg.setName("example"); + return msg; + } + + @Override + public String getXmlHookUuid() { + return uuid; + } + + public String getStartupStrategy() { + return startupStrategy; + } + + public void setStartupStrategy(String startupStrategy) { + this.startupStrategy = startupStrategy; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new Result(((APIUpdateVmUserDefinedXmlHookScriptMsg) msg).getUuid(), XmlHookVO.class); + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..5309f885d0c --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/APIUpdateVmUserDefinedXmlHookScriptMsgDoc_zh_cn.groovy @@ -0,0 +1,95 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.APIUpdateVmUserDefinedXmlHookScriptEvent + +doc { + title "UpdateVmUserDefinedXmlHookScript" + + category "host" + + desc """更新用户自定义xml hook""" + + rest { + request { + url "PUT /v1/vm-instances/xml-hook-script" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateVmUserDefinedXmlHookScriptMsg.class + + desc """更新用户自定义xml hook""" + + params { + + column { + name "uuid" + enclosedIn "updateVmUserDefinedXmlHookScript" + desc "资源的UUID,唯一标示该资源" + location "body" + type "String" + optional false + since "5.2.0" + } + column { + name "name" + enclosedIn "updateVmUserDefinedXmlHookScript" + desc "资源名称" + location "body" + type "String" + optional true + since "5.2.0" + } + column { + name "description" + enclosedIn "updateVmUserDefinedXmlHookScript" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "5.2.0" + } + column { + name "hookScript" + enclosedIn "updateVmUserDefinedXmlHookScript" + desc "xml hook 脚本" + location "body" + type "String" + optional true + since "5.2.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.2.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "startupStrategy" + enclosedIn "updateVmUserDefinedXmlHookScript" + desc "启动策略" + location "body" + type "String" + optional true + since "5.2.0" + values ("Reboot","None") + } + } + } + + response { + clz APIUpdateVmUserDefinedXmlHookScriptEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/RBAInfo.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/RBAInfo.java new file mode 100644 index 00000000000..be83962e3b4 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/RBAInfo.java @@ -0,0 +1,28 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBAInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .adminOnlyAPIs("org.zstack.kvm.xmlhook.**") + .build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + + } +} + diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookBase.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookBase.java new file mode 100644 index 00000000000..96eae1a9821 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookBase.java @@ -0,0 +1,233 @@ +package org.zstack.kvm.xmlhook; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.workflow.SimpleFlowChain; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.CheckAndStartVmInstanceMsg; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.utils.CollectionUtils; + +import java.util.*; + +import static org.zstack.core.Platform.operr; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class XmlHookBase { + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + protected ThreadFacade thdf; + + protected XmlHookVO self; + + protected String syncThreadName; + + public XmlHookBase(XmlHookVO self) { + this.self = self; + this.syncThreadName = "Xml-Hook-" + self.getUuid(); + } + + @MessageSafe + public void handleMessage(Message msg) { + if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleLocalMessage(Message msg) { + bus.dealWithUnknownMessage(msg); + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APIUpdateVmUserDefinedXmlHookScriptMsg) { + handle((APIUpdateVmUserDefinedXmlHookScriptMsg) msg); + } else if (msg instanceof APIExpungeVmUserDefinedXmlHookScriptMsg) { + handle((APIExpungeVmUserDefinedXmlHookScriptMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIExpungeVmUserDefinedXmlHookScriptMsg msg) { + APIExpungeVmUserDefinedXmlHookScriptEvent event = new APIExpungeVmUserDefinedXmlHookScriptEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public void run(SyncTaskChain chain) { + expungeVmUserDefinedXmlHook(msg, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("expunge-xml-hook-%s",msg.getUuid()); + } + }); + + } + + private void expungeVmUserDefinedXmlHook(APIExpungeVmUserDefinedXmlHookScriptMsg msg, Completion completion) { + dbf.remove(self); + completion.success(); + } + + private void handle(APIUpdateVmUserDefinedXmlHookScriptMsg msg) { + APIUpdateVmUserDefinedXmlHookScriptEvent event = new APIUpdateVmUserDefinedXmlHookScriptEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return syncThreadName; + } + + @Override + public void run(SyncTaskChain chain) { + updateVmUserDefinedXmlHook(msg, new ReturnValueCompletion(chain) { + @Override + public void success(XmlHookInventory inv) { + event.setInventory(inv); + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("update-xml-hook-%s", msg.getUuid()); + } + }); + } + + private void updateVmUserDefinedXmlHook(APIUpdateVmUserDefinedXmlHookScriptMsg msg, ReturnValueCompletion completion) { + FlowChain chain = new SimpleFlowChain(); + chain.setName(String.format("update-user-defined-xml-hook-%s-script", msg.getXmlHookUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "refresh-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (msg.getName() != null) { + self.setName(msg.getName()); + } + if (msg.getDescription() != null) { + self.setDescription(msg.getDescription()); + } + if (msg.getHookScript() != null) { + self.setHookScript(msg.getHookScript()); + } + dbf.updateAndRefresh(self); + trigger.next(); + } + }).then(new NoRollbackFlow() { + String __name__ = "startup-vm-instances"; + + @Override + public boolean skip(Map data) { + return !Objects.equals(msg.getStartupStrategy(), VmInstanceConstant.VmOperation.Reboot.toString()); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + List vmUuids = SQL.New("select vm.uuid from XmlHookVmInstanceRefVO ref, VmInstanceVO vm" + + " where ref.xmlHookUuid = :hookUuid" + + " and ref.vmInstanceUuid = vm.uuid" + + " and vm.state in (:vmStates)") + .param("hookUuid", msg.getXmlHookUuid()) + .param("vmStates", Arrays.asList(VmInstanceState.Running, VmInstanceState.Stopped)) + .list(); + if (CollectionUtils.isEmpty(vmUuids)) { + trigger.next(); + return; + } + + List errs = new ArrayList<>(); + new While<>(vmUuids).step((vmUuid, wcompl) -> { + CheckAndStartVmInstanceMsg cmsg = new CheckAndStartVmInstanceMsg(); + cmsg.setVmInstanceUuid(vmUuid); + bus.makeTargetServiceIdByResourceUuid(cmsg, VmInstanceConstant.SERVICE_ID, vmUuid); + bus.send(cmsg, new CloudBusCallBack(wcompl) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + errs.add(operr("xml hook[uuid: %s] updated successfully, but failed to restart vm[uuid:%s]. details is: %s", + msg.getXmlHookUuid(), vmUuid, reply.getError().getDetails())); + wcompl.allDone(); + } else { + wcompl.done(); + } + } + }); + }, 10).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errs.isEmpty()) { + trigger.next(); + } else { + trigger.fail(errs.get(0)); + } + } + }); + } + }); + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(XmlHookInventory.valueOf(dbf.findByUuid(msg.getXmlHookUuid(), XmlHookVO.class))); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } +} + diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookConstant.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookConstant.java new file mode 100644 index 00000000000..22fa92eaae1 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookConstant.java @@ -0,0 +1,9 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.configuration.PythonClass; + +@PythonClass +public interface XmlHookConstant { + String SET_GPU_MEMORY = "Configure GPU Video Memory"; + String OPERATE_VM_WITH_HOOK = "operate_vm_with_hook"; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookInventory.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookInventory.java new file mode 100644 index 00000000000..ee543818abd --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookInventory.java @@ -0,0 +1,107 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = XmlHookVO.class) +@PythonClassInventory +public class XmlHookInventory implements Serializable { + private String uuid; + private String name; + private String description; + private XmlHookType type; + private String hookScript; + private String libvirtVersion; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static XmlHookInventory valueOf(XmlHookVO vo) { + XmlHookInventory inv = new XmlHookInventory(); + inv.setUuid(vo.getUuid()); + inv.setName(vo.getName()); + inv.setDescription(vo.getDescription()); + inv.setType(vo.getType()); + inv.setHookScript(vo.getHookScript()); + inv.setLibvirtVersion(vo.getLibvirtVersion()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (XmlHookVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public XmlHookType getType() { + return type; + } + + public void setType(XmlHookType type) { + this.type = type; + } + + public String getHookScript() { + return hookScript; + } + + public void setHookScript(String hookScript) { + this.hookScript = hookScript; + } + + public String getLibvirtVersion() { + return libvirtVersion; + } + + public void setLibvirtVersion(String libvirtVersion) { + this.libvirtVersion = libvirtVersion; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookInventoryDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..b79dfdef8c3 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookInventoryDoc_zh_cn.groovy @@ -0,0 +1,60 @@ +package org.zstack.kvm.xmlhook + +import org.zstack.kvm.xmlhook.XmlHookType +import java.sql.Timestamp + +doc { + + title "用户自定义xml hook" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.2.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.2.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.2.0" + } + ref { + name "type" + path "org.zstack.kvm.xmlhook.XmlHookInventory.type" + desc "null" + type "XmlHookType" + since "5.2.0" + clz XmlHookType.class + } + field { + name "hookScript" + desc "xml hook脚本内容" + type "String" + since "5.2.0" + } + field { + name "libvirtVersion" + desc "" + type "String" + since "5.2.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.2.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.2.0" + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookManager.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookManager.java new file mode 100644 index 00000000000..91fcec54752 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookManager.java @@ -0,0 +1,5 @@ +package org.zstack.kvm.xmlhook; + +public interface XmlHookManager { + String SERVICE_ID = "xmlhook"; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookManagerImpl.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookManagerImpl.java new file mode 100644 index 00000000000..c6fcdd08a8d --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookManagerImpl.java @@ -0,0 +1,177 @@ +package org.zstack.kvm.xmlhook; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.vm.VmSystemTags; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.AbstractService; +import org.zstack.header.Component; +import org.zstack.header.cluster.ClusterUpdateOSExtensionPoint; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.cluster.UpdateClusterOSStruct; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.vm.VmInstanceBeforeStartExtensionPoint; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.tag.PatternedSystemTag; +import org.zstack.tag.SystemTagUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.sql.Timestamp; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.err; + +public class XmlHookManagerImpl extends AbstractService implements XmlHookManager, Component, + PrepareDbInitialValueExtensionPoint, VmInstanceBeforeStartExtensionPoint, ClusterUpdateOSExtensionPoint { + private static final CLogger logger = Utils.getLogger(XmlHookManagerImpl.class); + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + protected ThreadFacade thdf; + + private void handleLocalMessage(Message msg) { + bus.dealWithUnknownMessage(msg); + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof XmlHookMessage) { + passThrough((XmlHookMessage) msg); + } else if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APICreateVmUserDefinedXmlHookScriptMsg) { + handle((APICreateVmUserDefinedXmlHookScriptMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void passThrough(XmlHookMessage msg) { + XmlHookVO vo = dbf.findByUuid(msg.getXmlHookUuid(), XmlHookVO.class); + if (vo == null) { + bus.replyErrorByMessageType((Message) msg, err(SysErrors.RESOURCE_NOT_FOUND, "unable to find xmlHook[uuid=%s]", msg.getXmlHookUuid())); + return; + } + + XmlHookBase base = new XmlHookBase(vo); + base.handleMessage((Message) msg); + } + + private void handle(APICreateVmUserDefinedXmlHookScriptMsg msg) { + APICreateVmUserDefinedXmlHookScriptEvent event = new APICreateVmUserDefinedXmlHookScriptEvent(msg.getId()); + XmlHookVO vo = new XmlHookVO(); + vo.setUuid(msg.getResourceUuid() == null ? Platform.getUuid() : msg.getResourceUuid()); + vo.setName(msg.getName()); + vo.setDescription(msg.getDescription()); + vo.setHookScript(msg.getHookScript()); + vo.setType(XmlHookType.Customization); + vo.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(vo); + event.setInventory(XmlHookInventory.valueOf(vo)); + bus.publish(event); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getId() { + return bus.makeLocalServiceId(SERVICE_ID); + } + + @Override + public void prepareDbInitialValue() { + } + + @Override + public ErrorCode handleSystemTag(String vmUuid, List tags) { + PatternedSystemTag tag = VmSystemTags.XML_HOOK; + String token = VmSystemTags.XML_HOOK_TOKEN; + + String xmlhookUuid = SystemTagUtils.findTagValue(tags, tag, token); + if (StringUtils.isEmpty(xmlhookUuid)) { + return null; + } + XmlHookVmInstanceRefVO refVO = new XmlHookVmInstanceRefVO(); + refVO.setXmlHookUuid(xmlhookUuid); + refVO.setVmInstanceUuid(vmUuid); + refVO.setLastOpDate(new Timestamp(new Date().getTime())); + refVO.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(refVO); + return null; + } + + @Override + public String preUpdateClusterOS(UpdateClusterOSStruct updateClusterOSStruct) { + if (updateClusterOSStruct.isForce()) { + return null; + } + String updatePackages = updateClusterOSStruct.getUpdatePackages(); + String excludePackages = updateClusterOSStruct.getExcludePackages(); + ClusterVO cluster = updateClusterOSStruct.getCluster(); + + boolean qemuOrLibvirtUpdated = updatePackages != null && (updatePackages.contains("qemu-kvm-ev") || updatePackages.contains("qemu-kvm") || updatePackages.contains("qemu") || updatePackages.contains("libvirt")); + boolean qemuAndLibvirtExcluded = excludePackages != null && (excludePackages.contains("qemu-kvm-ev") || excludePackages.contains("qemu-kvm") || excludePackages.contains("qemu")) && excludePackages.contains("libvirt"); + boolean osUpdatedWithHypervisor = StringUtils.isNotEmpty(updateClusterOSStruct.getReleaseVersion()) && !qemuAndLibvirtExcluded; + + if (qemuOrLibvirtUpdated || osUpdatedWithHypervisor) { + //Determine whether the VM in the cluster is bound to XML hook + List vms = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.clusterUuid, cluster.getUuid()).list(); + if (CollectionUtils.isEmpty(vms)) { + return null; + } + List vmList = vms.stream() + .filter(it -> Q.New(XmlHookVmInstanceRefVO.class) + .eq(XmlHookVmInstanceRefVO_.vmInstanceUuid, it.getUuid()).isExists()) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(vmList)) { + return String.format("detect %s vms in cluster[uuid: %s] have been set XML hook, " + + "if the upgrade QEMU or libvirt, the original XML hook " + + "may be unavailable and the vm service will be affected, " + + "please confirm whether to upgrade, " + + "and if so, add param [force=true] with the api", vmList.size(), cluster.getUuid()); + } + + } + return null; + } + + @Override + public void beforeUpdateClusterOS(ClusterVO cls) { + + } + + @Override + public void afterUpdateClusterOS(ClusterVO cls) { + + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookMessage.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookMessage.java new file mode 100644 index 00000000000..c938a25b88e --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookMessage.java @@ -0,0 +1,5 @@ +package org.zstack.kvm.xmlhook; + +public interface XmlHookMessage { + String getXmlHookUuid(); +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookType.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookType.java new file mode 100644 index 00000000000..15e280178f8 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookType.java @@ -0,0 +1,9 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.configuration.PythonClass; + +@PythonClass +public enum XmlHookType { + System, + Customization +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookTypeDoc_zh_cn.groovy b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookTypeDoc_zh_cn.groovy new file mode 100644 index 00000000000..2192fd1faa2 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookTypeDoc_zh_cn.groovy @@ -0,0 +1,21 @@ +package org.zstack.kvm.xmlhook + + + +doc { + + title "xml hook 类型" + + field { + name "System" + desc "" + type "XmlHookType" + since "5.2.0" + } + field { + name "Customization" + desc "" + type "XmlHookType" + since "5.2.0" + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVO.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVO.java new file mode 100644 index 00000000000..2db57fa5d08 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVO.java @@ -0,0 +1,88 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class XmlHookVO extends ResourceVO implements ToInventory { + @Column + private String name; + @Column + private String description; + @Column + @Enumerated(EnumType.STRING) + private XmlHookType type; + @Column + private String hookScript; + @Column + private String libvirtVersion; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public XmlHookType getType() { + return type; + } + + public void setType(XmlHookType type) { + this.type = type; + } + + public String getHookScript() { + return hookScript; + } + + public void setHookScript(String hookScript) { + this.hookScript = hookScript; + } + + public String getLibvirtVersion() { + return libvirtVersion; + } + + public void setLibvirtVersion(String libvirtVersion) { + this.libvirtVersion = libvirtVersion; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVO_.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVO_.java new file mode 100644 index 00000000000..7bef850b175 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVO_.java @@ -0,0 +1,18 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(XmlHookVO.class) +public class XmlHookVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute description; + public static volatile SingularAttribute type; + public static volatile SingularAttribute hookScript; + public static volatile SingularAttribute libvirtVersion; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefInventory.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefInventory.java new file mode 100644 index 00000000000..ff533792e8c --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefInventory.java @@ -0,0 +1,84 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.vm.VmInstanceInventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = XmlHookVmInstanceRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "xmlHook", inventoryClass = XmlHookInventory.class, + foreignKey = "xmlHookUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "vmInstance", inventoryClass = VmInstanceInventory.class, + foreignKey = "vmInstanceUuid", expandedInventoryKey = "uuid") +}) +public class XmlHookVmInstanceRefInventory { + private Long id; + private String xmlHookUuid; + private String vmInstanceUuid; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static XmlHookVmInstanceRefInventory valueOf(XmlHookVmInstanceRefVO vo) { + XmlHookVmInstanceRefInventory inv = new XmlHookVmInstanceRefInventory(); + inv.setId(vo.getId()); + inv.setXmlHookUuid(vo.getXmlHookUuid()); + inv.setVmInstanceUuid(vo.getVmInstanceUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (XmlHookVmInstanceRefVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getXmlHookUuid() { + return xmlHookUuid; + } + + public void setXmlHookUuid(String xmlHookUuid) { + this.xmlHookUuid = xmlHookUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefVO.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefVO.java new file mode 100644 index 00000000000..a1d53437880 --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefVO.java @@ -0,0 +1,80 @@ +package org.zstack.kvm.xmlhook; + +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vo.*; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = VmInstanceVO.class, joinColumn = "vmInstanceUuid"), + @SoftDeletionCascade(parent = XmlHookVO.class, joinColumn = "xmlHookUuid") +}) +public class XmlHookVmInstanceRefVO implements ToInventory { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private Long id; + + @Column + @ForeignKey(parentEntityClass = XmlHookVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String xmlHookUuid; + + @Column + @ForeignKey(parentEntityClass = VmInstanceVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String vmInstanceUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getXmlHookUuid() { + return xmlHookUuid; + } + + public void setXmlHookUuid(String xmlHookUuid) { + this.xmlHookUuid = xmlHookUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefVO_.java b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefVO_.java new file mode 100644 index 00000000000..9eb400f04ce --- /dev/null +++ b/plugin/kvm/src/main/java/org/zstack/kvm/xmlhook/XmlHookVmInstanceRefVO_.java @@ -0,0 +1,14 @@ +package org.zstack.kvm.xmlhook; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(XmlHookVmInstanceRefVO.class) +public class XmlHookVmInstanceRefVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute xmlHookUuid; + public static volatile SingularAttribute vmInstanceUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/ldap/pom.xml b/plugin/ldap/pom.xml index de9955fc5ba..ccfa2ca138d 100755 --- a/plugin/ldap/pom.xml +++ b/plugin/ldap/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 @@ -73,16 +73,11 @@ - - org.springframework.ldap - spring-ldap-core - 2.3.2.RELEASE - org.springframework.security spring-security-ldap - 4.1.5.RELEASE + 5.7.13 org.zstack diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIAddLdapServerMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIAddLdapServerMsgDoc_zh_cn.groovy index 67968c3cf95..343a8754b37 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIAddLdapServerMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIAddLdapServerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "base" @@ -59,7 +56,6 @@ doc { type "String" optional false since "0.6" - } column { name "username" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -79,7 +74,6 @@ doc { type "String" optional false since "0.6" - } column { name "encryption" @@ -99,7 +93,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +102,16 @@ doc { type "List" optional true since "0.6" - + } + column { + name "scope" + enclosedIn "params" + desc "Ldap服务器的作用范围(账户或者企业管理用户)" + location "body" + type "String" + optional false + since "3.6.0" + values ("account","IAM2") } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APICleanInvalidLdapBindingMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APICleanInvalidLdapBindingMsgDoc_zh_cn.groovy index e77be2a4e43..4e4dc2e87f4 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APICleanInvalidLdapBindingMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APICleanInvalidLdapBindingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsg.java b/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsg.java index c7013ddd8c5..98f4a691f07 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsg.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsg.java @@ -9,6 +9,7 @@ @RestRequest( path = "/ldap/bindings", method = HttpMethod.POST, + parameterName = "params", responseClass = APICreateLdapBindingEvent.class ) public class APICreateLdapBindingMsg extends APIMessage { diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsgDoc_zh_cn.groovy index bd039c4087d..5d94b421eef 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APICreateLdapBindingMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "ldapUid" - enclosedIn "" + enclosedIn "params" desc "LDAP UID" location "body" type "String" optional false since "0.6" - } column { name "accountUuid" - enclosedIn "" + enclosedIn "params" desc "账户UUID" location "body" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapBindingMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapBindingMsgDoc_zh_cn.groovy index 95689bd39f8..ce03bdf3b67 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapBindingMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapBindingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapServerMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapServerMsgDoc_zh_cn.groovy index 3f9c0a2d806..a00d4cf05d5 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapServerMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIDeleteLdapServerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIGetCandidateLdapEntryForBindingMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIGetCandidateLdapEntryForBindingMsgDoc_zh_cn.groovy index aacf2f98290..3b31e642ffc 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIGetCandidateLdapEntryForBindingMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIGetCandidateLdapEntryForBindingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "limit" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIGetLdapEntryMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIGetLdapEntryMsgDoc_zh_cn.groovy index 6b700486767..af3dc878d03 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIGetLdapEntryMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIGetLdapEntryMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "limit" @@ -59,7 +56,15 @@ doc { type "Integer" optional true since "0.6" - + } + column { + name "ldapServerUuid" + enclosedIn "" + desc "" + location "query" + type "String" + optional true + since "3.6.0" } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsg.java b/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsg.java index 65f12299c01..cc88b1dbfdd 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsg.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsg.java @@ -2,9 +2,11 @@ import org.apache.commons.lang.StringUtils; import org.springframework.http.HttpMethod; +import org.zstack.header.identity.APILogInReply; import org.zstack.header.identity.APISessionMessage; import org.zstack.header.identity.SessionVO; import org.zstack.header.identity.SuppressCredentialCheck; +import org.zstack.header.identity.login.APICaptchaMessage; import org.zstack.header.log.NoLogging; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; @@ -21,7 +23,7 @@ isAction = true, responseClass = APILogInByLdapReply.class ) -public class APILogInByLdapMsg extends APISessionMessage implements APILoginAuditor { +public class APILogInByLdapMsg extends APISessionMessage implements APILoginAuditor, APICaptchaMessage { @APIParam private String uid; @APIParam(password = true) @@ -34,10 +36,6 @@ public class APILogInByLdapMsg extends APISessionMessage implements APILoginAudi @APIParam(required = false) private Map clientInfo; - public String getPassword() { - return password; - } - public void setPassword(String password) { this.password = password; } @@ -97,8 +95,26 @@ public LoginResult loginAudit(APIMessage msg, APIReply reply) { if (clientInfo != null && !clientInfo.isEmpty()) { clientIp = StringUtils.isNotEmpty(clientInfo.get("clientIp")) ? clientInfo.get("clientIp") : ""; clientBrowser = StringUtils.isNotEmpty(clientInfo.get("clientBrowser")) ? clientInfo.get("clientBrowser") : ""; + } else { + clientIp = StringUtils.isNotBlank(msg.getClientIp()) ? msg.getClientIp() : ""; + clientBrowser = StringUtils.isNotBlank(msg.getClientBrowser()) ? msg.getClientBrowser() : ""; } - String resourceUuid = reply.isSuccess() ? amsg.getSession().getUuid() : ""; + String resourceUuid = reply.isSuccess() ? ((APILogInByLdapReply) reply).getInventory().getUuid() : ""; return new LoginResult(clientIp, clientBrowser, resourceUuid, SessionVO.class); } + + @Override + public String getUsername() { + return uid; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getLoginType() { + return LdapConstant.LOGIN_TYPE; + } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsgDoc_zh_cn.groovy index 81a44210683..d3196146574 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "verifyCode" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "captchaUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "clientInfo" @@ -69,7 +65,6 @@ doc { type "Map" optional true since "3.5.0" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapReply.java b/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapReply.java index ecbe6f8e7f7..af8e47288af 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapReply.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APILogInByLdapReply.java @@ -13,14 +13,6 @@ public class APILogInByLdapReply extends APILogInAuditorReply { private SessionInventory inventory; private AccountInventory accountInventory; - public SessionInventory getInventory() { - return inventory; - } - - public void setInventory(SessionInventory inventory) { - this.inventory = inventory; - } - public AccountInventory getAccountInventory() { return accountInventory; } @@ -29,6 +21,14 @@ public void setAccountInventory(AccountInventory accountInventory) { this.accountInventory = accountInventory; } + public SessionInventory getInventory() { + return inventory; + } + + public void setInventory(SessionInventory inventory) { + this.inventory = inventory; + } + public static APILogInByLdapReply __example__() { APILogInByLdapReply reply = new APILogInByLdapReply(); SessionInventory inventory = new SessionInventory(); diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapBindingMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapBindingMsgDoc_zh_cn.groovy index 64442dc09d3..d82e9183df2 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapBindingMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapBindingMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.ldap import org.zstack.ldap.APIQueryLdapBindingReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryLdapBinding" diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapServerMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapServerMsgDoc_zh_cn.groovy index 975f98fb3d0..290a59869d0 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapServerMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIQueryLdapServerMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.ldap import org.zstack.ldap.APIQueryLdapServerReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryLdapServer" diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/APIUpdateLdapServerMsgDoc_zh_cn.groovy b/plugin/ldap/src/main/java/org/zstack/ldap/APIUpdateLdapServerMsgDoc_zh_cn.groovy index 8adef1e45c9..1a182d45137 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/APIUpdateLdapServerMsgDoc_zh_cn.groovy +++ b/plugin/ldap/src/main/java/org/zstack/ldap/APIUpdateLdapServerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "url" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "base" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "username" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "password" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "encryption" @@ -109,7 +102,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -119,7 +111,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapApiInterceptor.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapApiInterceptor.java index 51448d0a709..2453704a341 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapApiInterceptor.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapApiInterceptor.java @@ -136,7 +136,7 @@ private void validateLdapServerExist(){ } } - private ErrorCode testAddLdapServerConnection(LdapServerInventory inv) { + public ErrorCode testAddLdapServerConnection(LdapServerInventory inv) { Map properties = new HashMap<>(); String timeout = Integer.toString(LdapGlobalProperty.LDAP_ADD_SERVER_CONNECT_TIMEOUT); properties.put("com.sun.jndi.ldap.connect.timeout", timeout); diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapEntrySearchMode.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapEntrySearchMode.java new file mode 100644 index 00000000000..9853150ba06 --- /dev/null +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapEntrySearchMode.java @@ -0,0 +1,7 @@ +package org.zstack.ldap; + +public enum LdapEntrySearchMode { + AUTO, + NONE, + PAGE +} diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalConfig.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalConfig.java index 14d1b2c7c16..fe38c4b9990 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalConfig.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalConfig.java @@ -23,4 +23,9 @@ public class LdapGlobalConfig { @GlobalConfigValidation @GlobalConfigDef(defaultValue = "false", type = Boolean.class) public static GlobalConfig SKIP_ALL_SSL_CERTS_CHECK = new GlobalConfig(CATEGORY, "skip.all.ssl.certs.check"); + + @GlobalConfigValidation(validValues = {"AUTO", "NONE", "PAGE"}) + @GlobalConfigDef(defaultValue = "AUTO", description = "set ldap preferred search mode") + public static GlobalConfig LDAP_ENTRY_SEARCH_MODE = new GlobalConfig(CATEGORY, "ldap.entry.search.mode"); + } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalProperty.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalProperty.java index d074a6f6341..5fd78fba8b7 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalProperty.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapGlobalProperty.java @@ -10,4 +10,13 @@ public class LdapGlobalProperty { @GlobalProperty(name = "Ldap.addServer.connectTimeout", defaultValue = "5000") public static int LDAP_ADD_SERVER_CONNECT_TIMEOUT; + + @GlobalProperty(name = "Ldap.addServer.readTimeout", defaultValue = "5000") + public static int LDAP_ADD_SERVER_READ_TIMEOUT; + + @GlobalProperty(name = "Ldap.referral", defaultValue = "follow") + public static String LDAP_REFERRAL; + + @GlobalProperty(name = "Ldap.connect.pool", defaultValue = "false") + public static boolean LDAP_CONNECT_POOL; } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapLoginProcessor.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapLoginProcessor.java deleted file mode 100644 index 0101370e3cd..00000000000 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapLoginProcessor.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.zstack.ldap; - -import org.springframework.beans.factory.annotation.Autowire; -import org.springframework.beans.factory.annotation.Configurable; -import org.zstack.core.Platform; -import org.zstack.header.identity.LoginProcessor; -import org.zstack.header.identity.LoginType; -import org.zstack.header.message.APIMessage; - -/** - * * Created by kayo on 2018/7/9. - * */ -@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class LdapLoginProcessor implements LoginProcessor { - public static final LoginType loginType = new LoginType(LdapConstant.LOGIN_TYPE); - public static LdapUtil ldapUtil = Platform.New(() -> new LdapUtil("IAM2")); - - @Override - public LoginType getLoginType() { - return loginType; - } - - @Override - public Class getMessageClass() { - return APILogInByLdapMsg.class; - } - - public String resourceChecker(String resourceName) { - String dn = LdapManager.ldapUtil.getFullUserDn(resourceName); - - LdapAccountRefVO vo = LdapManager.ldapUtil.findLdapAccountRefVO(dn); - - if (vo == null) { - return null; - } - - return dn; - } - - @Override - public Result getMessageParams(APIMessage message) { - Result r = new Result(); - - APILogInByLdapMsg msg = (APILogInByLdapMsg) message; - String dn = LdapManager.ldapUtil.getFullUserDn(msg.getUid()); - - LdapAccountRefVO vo = LdapManager.ldapUtil.findLdapAccountRefVO(dn); - - if (vo == null) { - r.setTargetResourceIdentity(null); - } else { - r.setTargetResourceIdentity(dn); - } - - r.setVerifyCode(msg.getVerifyCode()); - r.setCaptchaUuid(msg.getCaptchaUuid()); - - return r; - } - - @Override - public boolean authenticate(String name, String password) { - return ldapUtil.isValid(name, password); - } -} diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java index 7191bf22189..233460005a1 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapManagerImpl.java @@ -1,16 +1,15 @@ package org.zstack.ldap; -import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException; +import java.sql.SQLIntegrityConstraintViolationException; import org.apache.commons.lang.StringUtils; -import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ldap.filter.AndFilter; import org.springframework.ldap.filter.HardcodedFilter; -import org.springframework.orm.jpa.JpaSystemException; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.MessageSafe; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; @@ -20,18 +19,19 @@ import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.AbstractService; import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.captcha.Captcha; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; -import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.*; +import org.zstack.header.identity.login.*; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; import org.zstack.identity.AccountManager; -import org.zstack.identity.Session; import org.zstack.tag.PatternedSystemTag; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.SystemTagUtils; @@ -53,10 +53,11 @@ /** * Created by miao on 16-9-6. */ -public class LdapManagerImpl extends AbstractService implements LdapManager { +public class LdapManagerImpl extends AbstractService implements LdapManager, LoginBackend { private static final CLogger logger = Utils.getLogger(LdapManagerImpl.class); private static final LdapEffectiveScope scope = new LdapEffectiveScope(AccountConstant.LOGIN_TYPE); + private static final LoginType loginType = new LoginType(LdapConstant.LOGIN_TYPE); @Autowired private DatabaseFacade dbf; @@ -144,43 +145,33 @@ public boolean isValid(String uid, String password) { } private void handle(APILogInByLdapMsg msg) { - APILogInByLdapReply reply = new APILogInByLdapReply(); - - String ldapLoginName = msg.getUid(); - if (!isValid(ldapLoginName, msg.getPassword())) { - reply.setError(err(IdentityErrors.AUTHENTICATION_ERROR, - "Login validation failed in LDAP")); - bus.reply(msg, reply); - return; - } - - LdapTemplateContextSource ldapTemplateContextSource = ldapUtil.readLdapServerConfiguration(); - String dn = ldapUtil.getFullUserDn(ldapTemplateContextSource.getLdapTemplate(), ldapUtil.getLdapUseAsLoginName(), ldapLoginName); - LdapAccountRefVO vo = ldapUtil.findLdapAccountRefVO(dn); - - if (vo == null) { - reply.setError(err(IdentityErrors.AUTHENTICATION_ERROR, - "The ldapUid does not have a binding account.")); - bus.reply(msg, reply); - return; - } - - SimpleQuery sq = dbf.createQuery(AccountVO.class); - sq.add(AccountVO_.uuid, SimpleQuery.Op.EQ, vo.getAccountUuid()); - AccountVO avo = sq.find(); - if (avo == null) { - reply.setError(operr( - "Account[uuid:%s] Not Found!!!", vo.getAccountUuid())); - bus.reply(msg, reply); - return; - } - - SessionInventory inv = Session.login(vo.getAccountUuid(), vo.getAccountUuid()); - msg.setSession(inv); - reply.setInventory(inv); - reply.setAccountInventory(AccountInventory.valueOf(avo)); - - bus.reply(msg, reply); + LogInMsg logInMsg = new LogInMsg(); + logInMsg.setClientInfo(msg.getClientInfo()); + logInMsg.setPassword(msg.getPassword()); + logInMsg.setUsername(msg.getUsername()); + logInMsg.setCaptchaUuid(msg.getCaptchaUuid()); + logInMsg.setVerifyCode(msg.getVerifyCode()); + logInMsg.setSystemTags(msg.getSystemTags()); + logInMsg.setLoginType(msg.getLoginType()); + bus.makeTargetServiceIdByResourceUuid(logInMsg, LoginManager.SERVICE_ID, logInMsg.getUsername()); + bus.send(logInMsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + APILogInByLdapReply apiLogInReply = new APILogInByLdapReply(); + if (!reply.isSuccess()) { + apiLogInReply.setError(reply.getError()); + bus.reply(msg, apiLogInReply); + return; + } + + LogInReply logInReply = reply.castReply(); + apiLogInReply.setInventory(logInReply.getSession()); + msg.setSession(logInReply.getSession()); + AccountVO vo = dbf.findByUuid(logInReply.getSession().getAccountUuid(), AccountVO.class); + apiLogInReply.setAccountInventory(AccountInventory.valueOf(vo)); + bus.reply(msg, apiLogInReply); + } + }); } private void handle(APIAddLdapServerMsg msg) { @@ -212,6 +203,7 @@ private void handle(APIAddLdapServerMsg msg) { evt.setInventory(inv); this.saveLdapCleanBindingFilterTag(msg.getSystemTags(), ldapServerVO.getUuid()); + this.saveLdapAllowListFilterTag(msg.getSystemTags(), ldapServerVO.getUuid()); this.saveLdapServerTypeTag(msg.getSystemTags(), ldapServerVO.getUuid()); this.saveLdapUseAsLoginNameTag(msg.getSystemTags(), ldapServerVO.getUuid()); @@ -241,6 +233,25 @@ private void saveLdapCleanBindingFilterTag(List systemTags, String uuid) creator.create(); } + private void saveLdapAllowListFilterTag(List systemTags, String uuid){ + if(systemTags == null || systemTags.isEmpty()){ + return; + } + + PatternedSystemTag tag = LdapSystemTags.LDAP_ALLOW_LIST_FILTER; + String token = LdapSystemTags.LDAP_ALLOW_LIST_FILTER_TOKEN; + + String tagValue = SystemTagUtils.findTagValue(systemTags, tag, token); + if(StringUtils.isEmpty(tagValue)){ + return; + } + + SystemTagCreator creator = tag.newSystemTagCreator(uuid); + creator.recreate = true; + creator.setTagByTokens(map(CollectionDSL.e(token, tagValue))); + creator.create(); + } + private void saveLdapServerTypeTag(List systemTags, String uuid) { if(systemTags == null || systemTags.isEmpty()) { return; @@ -395,7 +406,7 @@ private void handle(APICreateLdapBindingMsg msg) { evt.setInventory(bindLdapAccount(msg.getAccountUuid(), fullDn)); logger.info(String.format("create ldap binding[ldapUid=%s, ldapUseAsLoginName=%s] success", fullDn, ldapUseAsLoginName)); } catch (PersistenceException e) { - if (ExceptionDSL.isCausedBy(e, MySQLIntegrityConstraintViolationException.class)) { + if (ExceptionDSL.isCausedBy(e, SQLIntegrityConstraintViolationException.class)) { evt.setError(err(LdapErrors.BIND_SAME_LDAP_UID_TO_MULTI_ACCOUNT, "The ldap uid has been bound to an account. ")); } else { @@ -439,14 +450,21 @@ private void handle(APICleanInvalidLdapBindingMsg msg) { // filter String filter = LdapSystemTags.LDAP_CLEAN_BINDING_FILTER.getTokenByResourceUuid(ldapAccRefVO.getLdapServerUuid(), LdapSystemTags.LDAP_CLEAN_BINDING_FILTER_TOKEN); - if(StringUtils.isEmpty(filter)){ - continue; + if(StringUtils.isNotEmpty(filter)){ + HardcodedFilter hardcodedFilter = new HardcodedFilter(filter); + if(ldapUtil.validateDnExist(ldapTemplateContextSource, ldapDn, hardcodedFilter)){ + accountUuidList.add(ldapAccRefVO.getAccountUuid()); + ldapAccountRefUuidList.add(ldapAccRefVO.getUuid()); + } } - - HardcodedFilter hardcodedFilter = new HardcodedFilter(filter); - if(ldapUtil.validateDnExist(ldapTemplateContextSource, ldapDn, hardcodedFilter)){ - accountUuidList.add(ldapAccRefVO.getAccountUuid()); - ldapAccountRefUuidList.add(ldapAccRefVO.getUuid()); + // allow list filter + String allowListFilter = LdapSystemTags.LDAP_ALLOW_LIST_FILTER.getTokenByResourceUuid(ldapAccRefVO.getLdapServerUuid(), LdapSystemTags.LDAP_ALLOW_LIST_FILTER_TOKEN); + if(StringUtils.isNotEmpty(allowListFilter)){ + HardcodedFilter hardcodedAllowListFilter = new HardcodedFilter(allowListFilter); + if(!ldapUtil.validateDnExist(ldapTemplateContextSource, ldapDn, hardcodedAllowListFilter)){ + accountUuidList.add(ldapAccRefVO.getAccountUuid()); + ldapAccountRefUuidList.add(ldapAccRefVO.getUuid()); + } } } @@ -501,6 +519,7 @@ private void handle(APIUpdateLdapServerMsg msg) { evt.setInventory(LdapServerInventory.valueOf(ldapServerVO)); this.saveLdapCleanBindingFilterTag(msg.getSystemTags(), ldapServerVO.getUuid()); + this.saveLdapAllowListFilterTag(msg.getSystemTags(), ldapServerVO.getUuid()); this.saveLdapServerTypeTag(msg.getSystemTags(), ldapServerVO.getUuid()); this.saveLdapUseAsLoginNameTag(msg.getSystemTags(), ldapServerVO.getUuid()); for (UpdateLdapServerExtensionPoint ext : pluginRgty.getExtensionList(UpdateLdapServerExtensionPoint.class)) { @@ -510,4 +529,63 @@ private void handle(APIUpdateLdapServerMsg msg) { bus.publish(evt); } + @Override + public LoginType getLoginType() { + return loginType; + } + + @Override + public void login(LoginContext loginContext, ReturnValueCompletion completion) { + String ldapLoginName = loginContext.getUsername(); + if (!isValid(ldapLoginName, loginContext.getPassword())) { + completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR, + "Login validation failed in LDAP")); + return; + } + + LdapTemplateContextSource ldapTemplateContextSource = ldapUtil.readLdapServerConfiguration(); + String dn = ldapUtil.getFullUserDn(ldapTemplateContextSource.getLdapTemplate(), ldapUtil.getLdapUseAsLoginName(), ldapLoginName); + LdapAccountRefVO vo = ldapUtil.findLdapAccountRefVO(dn); + + if (vo == null) { + completion.fail(err(IdentityErrors.AUTHENTICATION_ERROR, + "The ldapUid does not have a binding account.")); + return; + } + + SimpleQuery sq = dbf.createQuery(AccountVO.class); + sq.add(AccountVO_.uuid, SimpleQuery.Op.EQ, vo.getAccountUuid()); + AccountVO avo = sq.find(); + if (avo == null) { + completion.fail(operr( + "Account[uuid:%s] Not Found!!!", vo.getAccountUuid())); + return; + } + + LoginSessionInfo info = new LoginSessionInfo(); + info.setUserUuid(vo.getAccountUuid()); + info.setAccountUuid(vo.getAccountUuid()); + info.setUserType(AccountVO.class.getSimpleName()); + completion.success(info); + } + + @Override + public boolean authenticate(String username, String password) { + return ldapUtil.isValid(username, password); + } + + @Override + public String getUserIdByName(String username) { + return ldapUtil.getFullUserDn(username); + } + + @Override + public void collectUserInfoIntoContext(LoginContext loginContext) { + loginContext.setUserUuid(getUserIdByName(loginContext.getUsername())); + } + + @Override + public List getRequiredAdditionalAuthFeature() { + return Collections.singletonList(LoginAuthConstant.basicLoginControl); + } } diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapSystemTags.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapSystemTags.java index 669de1271ea..74bdf9e60b3 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapSystemTags.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapSystemTags.java @@ -8,9 +8,14 @@ @TagDefinition public class LdapSystemTags { + // clean binding filter, filter to get users who don't need to be synchronized public static String LDAP_CLEAN_BINDING_FILTER_TOKEN = "ldapCleanBindingFilter"; public static PatternedSystemTag LDAP_CLEAN_BINDING_FILTER = new PatternedSystemTag(String.format("ldapCleanBindingFilter::{%s}", LDAP_CLEAN_BINDING_FILTER_TOKEN), LdapServerVO.class); + // allow list filter, filter to get the users who need to be synchronized + public static String LDAP_ALLOW_LIST_FILTER_TOKEN = "ldapAllowListFilter"; + public static PatternedSystemTag LDAP_ALLOW_LIST_FILTER = new PatternedSystemTag(String.format("ldapAllowListFilter::{%s}", LDAP_ALLOW_LIST_FILTER_TOKEN), LdapServerVO.class); + /** * Support Types:OpenLdap, WindowsAD */ diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/LdapUtil.java b/plugin/ldap/src/main/java/org/zstack/ldap/LdapUtil.java index 3fb1c6b1b4d..1f5e1df7cf8 100644 --- a/plugin/ldap/src/main/java/org/zstack/ldap/LdapUtil.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/LdapUtil.java @@ -1,6 +1,7 @@ package org.zstack.ldap; import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.util.Strings; import org.springframework.ldap.NamingException; import org.springframework.ldap.control.PagedResultsDirContextProcessor; import org.springframework.ldap.core.DirContextOperations; @@ -43,6 +44,8 @@ public class LdapUtil { private static final CLogger logger = Utils.getLogger(LdapUtil.class); + static final String PAGED_RESULTS_CONTROL_OID = "1.2.840.113556.1.4.319"; + public LdapUtil() { } @@ -165,8 +168,11 @@ LdapContextSource buildLdapContextSource(LdapServerInventory inv, Map baseEnvironmentProperties) { LdapContextSource ldapContextSource = buildLdapContextSource(inv, baseEnvironmentProperties); @@ -267,7 +285,11 @@ public Map getBaseEnvProperties() { if(LdapConstant.WindowsAD.TYPE.equals(type)){ properties.put("java.naming.ldap.attributes.binary","objectGUID"); } - + // add socket timeout + String timeout = Integer.toString(LdapGlobalProperty.LDAP_ADD_SERVER_CONNECT_TIMEOUT); + properties.put("com.sun.jndi.ldap.connect.timeout", timeout); + String readTimeout = Integer.toString(LdapGlobalProperty.LDAP_ADD_SERVER_READ_TIMEOUT ); + properties.put("com.sun.jndi.ldap.read.timeout", readTimeout); return properties; } @@ -361,6 +383,98 @@ public String getGlobalUuidKey() { return LdapConstant.WindowsAD.GLOBAL_UUID_KEY; } + private LdapTemplate getRootBaseLdapTemplate(String ldapServerUuid) { + LdapTemplateContextSource ldapTemplateContextSource = readRootLdapServerConfiguration(ldapServerUuid); + LdapTemplate ldapTemplate = ldapTemplateContextSource.getLdapTemplate(); + ldapTemplate.setContextSource(new SingleContextSource(ldapTemplateContextSource.getLdapContextSource().getReadOnlyContext())); + + return ldapTemplate; + } + + private LdapEntrySearchMode getSuitableSearchMode(LdapTemplate ldapTemplate) { + if (isControlSupported(ldapTemplate, PAGED_RESULTS_CONTROL_OID)) { + logger.debug("[ldap] paged results control is supported"); + return LdapEntrySearchMode.PAGE; + } + + logger.debug("[ldap] no control matched, search without processor"); + return LdapEntrySearchMode.NONE; + } + + private boolean isControlSupported(LdapTemplate ldapTemplate, String dotOid) { + String[] returningAttributes = + { + "supportedControl", + "supportedExtension" + }; + + List> attributesResultList = ldapTemplate.search("", "(objectclass=*)", SearchControls.OBJECT_SCOPE, returningAttributes, new AbstractContextMapper>() { + @Override + protected Set doMapFromContext(DirContextOperations ctx) { + Set controlsSet = new HashSet<>(); + controlsSet.addAll(Arrays.asList(ctx.getStringAttributes("supportedControl"))); + controlsSet.addAll(Arrays.asList(ctx.getStringAttributes("supportedExtension"))); + + return controlsSet; + } + }); + + if (attributesResultList.isEmpty()) { + return false; + } + + return attributesResultList.get(0).remove(dotOid); + } + + private LdapSearchedResult searchWithoutProcessor(LdapTemplate ldapTemplate, String filter, SearchControls searchCtls, ResultFilter resultFilter, Integer count) { + LdapSearchedResult ldapSearchedResult = new LdapSearchedResult(); + ldapSearchedResult.setResult(new ArrayList<>()); + + List searchResult = new ArrayList<>(); + try { + searchResult = ldapTemplate.search("", filter, searchCtls, new AbstractContextMapper() { + @Override + protected Object doMapFromContext(DirContextOperations ctx) { + if (resultFilter != null && !resultFilter.needSelect(ctx.getNameInNamespace())){ + return null; + } + + Map result = new HashMap<>(); + result.put(LdapConstant.LDAP_DN_KEY, ctx.getNameInNamespace()); + + List list = new ArrayList<>(); + result.put("attributes", list); + + Attributes attributes = ctx.getAttributes(); + NamingEnumeration it = attributes.getAll(); + try { + while (it.hasMore()){ + list.add(it.next()); + } + } catch (javax.naming.NamingException e){ + logger.error("query ldap entry attributes fail", e.getCause()); + throw new OperationFailureException(operr("query ldap entry fail, %s", e.toString())); + } + + return result; + } + }); + } catch (Exception e){ + logger.error("legacy query ldap entry fail", e); + ldapSearchedResult.setSuccess(false); + ldapSearchedResult.setResult(null); + ldapSearchedResult.setError(e.getMessage()); + } + + if (count != null && searchResult.size() > count){ + ldapSearchedResult.setResult(searchResult.subList(0, count)); + } else { + ldapSearchedResult.setResult(searchResult); + } + + return ldapSearchedResult; + } + private LdapSearchedResult pagedSearch(LdapTemplate ldapTemplate, String filter, SearchControls searchCtls, ResultFilter resultFilter, Integer count) { LdapSearchedResult ldapSearchedResult = new LdapSearchedResult(); ldapSearchedResult.setResult(new ArrayList<>()); @@ -419,8 +533,8 @@ public List searchLdapEntry(String filter, Integer count, String[] retur return searchLdapEntry(ldapServerVO.getUuid(), filter, count, returningAttributes, resultFilter, searchAllAttributes); } - public List searchLdapEntry(String ldapSeverUuid, String filter, Integer count, String[] returningAttributes, ResultFilter resultFilter, boolean searchAllAttributes) { - LdapTemplateContextSource ldapTemplateContextSource = readLdapServerConfiguration(ldapSeverUuid); + public List searchLdapEntry(String ldapServerUuid, String filter, Integer count, String[] returningAttributes, ResultFilter resultFilter, boolean searchAllAttributes) { + LdapTemplateContextSource ldapTemplateContextSource = readLdapServerConfiguration(ldapServerUuid); LdapTemplate ldapTemplate = ldapTemplateContextSource.getLdapTemplate(); ldapTemplate.setContextSource(new SingleContextSource(ldapTemplateContextSource.getLdapContextSource().getReadOnlyContext())); @@ -434,7 +548,21 @@ public List searchLdapEntry(String ldapSeverUuid, String filter, Integer } String errorMessage = ""; - LdapSearchedResult ldapSearchedResult = pagedSearch(ldapTemplate, filter, searchCtls, resultFilter, count); + + LdapSearchedResult ldapSearchedResult; + LdapEntrySearchMode ldapEntrySearchMode = LdapEntrySearchMode.valueOf(LdapGlobalConfig.LDAP_ENTRY_SEARCH_MODE.value()); + if (ldapEntrySearchMode == LdapEntrySearchMode.AUTO) { + ldapEntrySearchMode = getSuitableSearchMode(getRootBaseLdapTemplate(ldapServerUuid)); + } + + if (ldapEntrySearchMode == LdapEntrySearchMode.PAGE) { + ldapSearchedResult = pagedSearch(ldapTemplate, filter, searchCtls, resultFilter, count); + } else if (ldapEntrySearchMode == LdapEntrySearchMode.NONE) { + ldapSearchedResult = searchWithoutProcessor(ldapTemplate, filter, searchCtls, resultFilter, count); + } else { + throw new CloudRuntimeException(String.format("unexpected LdapEntrySearchMode: %s", ldapEntrySearchMode)); + } + if (ldapSearchedResult.isSuccess()) { return ldapSearchedResult.getResult(); } @@ -511,6 +639,15 @@ public LdapTemplateContextSource readLdapServerConfiguration(String ldapServerUu return loadLdap(ldapServerInventory); } + // set LdapContextSource base as empty + public LdapTemplateContextSource readRootLdapServerConfiguration(String ldapServerUuid) { + LdapServerVO ldapServerVO = Q.New(LdapServerVO.class) + .eq(LdapServerVO_.uuid, ldapServerUuid) + .find(); + LdapServerInventory ldapServerInventory = LdapServerInventory.valueOf(ldapServerVO); + return loadRootLdap(ldapServerInventory); + } + @Transactional(readOnly = true) public LdapServerVO getLdapServer() { final DatabaseFacade dbf = Platform.getComponentLoader().getComponent(DatabaseFacade.class); @@ -583,9 +720,14 @@ protected Object doMapFromContext(DirContextOperations ctx) { } } + private String LdapEscape(String ldapDn) { + return ldapDn.replace("/", "\\2f"); + } + public boolean validateDnExist(LdapTemplateContextSource ldapTemplateContextSource, String fullDn){ try { String dn = fullDn.replace("," + ldapTemplateContextSource.getLdapContextSource().getBaseLdapPathAsString(), ""); + dn = LdapEscape(dn); Object result = ldapTemplateContextSource.getLdapTemplate().lookup(dn, new AbstractContextMapper() { @Override protected Object doMapFromContext(DirContextOperations ctx) { @@ -603,6 +745,7 @@ protected Object doMapFromContext(DirContextOperations ctx) { public boolean validateDnExist(LdapTemplateContextSource ldapTemplateContextSource, String fullDn, Filter filter){ try { String dn = fullDn.replace("," + ldapTemplateContextSource.getLdapContextSource().getBaseLdapPathAsString(), ""); + dn = LdapEscape(dn); List result = ldapTemplateContextSource.getLdapTemplate().search(dn, filter.toString(), new AbstractContextMapper() { @Override protected Object doMapFromContext(DirContextOperations ctx) { diff --git a/plugin/ldap/src/main/java/org/zstack/ldap/PackageInfo.java b/plugin/ldap/src/main/java/org/zstack/ldap/PackageInfo.java index ffb7c6c3852..f32d251c9e2 100755 --- a/plugin/ldap/src/main/java/org/zstack/ldap/PackageInfo.java +++ b/plugin/ldap/src/main/java/org/zstack/ldap/PackageInfo.java @@ -2,6 +2,11 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "LDAP") +import static org.zstack.header.PackageAPIInfo.*; + +@PackageAPIInfo( + APICategoryName = "LDAP", + permissions = {PERMISSION_COMMUNITY_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/loadBalancer/pom.xml b/plugin/loadBalancer/pom.xml index 655b236e0e1..65f09eeb277 100755 --- a/plugin/loadBalancer/pom.xml +++ b/plugin/loadBalancer/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddAccessControlListToLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddAccessControlListToLoadBalancerMsgDoc_zh_cn.groovy index 05f5a97eced..1a7ffad3536 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddAccessControlListToLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddAccessControlListToLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "3.9" - } column { name "aclType" @@ -49,7 +48,6 @@ doc { type "String" optional false since "3.9" - } column { name "systemTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -69,7 +66,6 @@ doc { type "List" optional true since "3.9" - } column { name "serverGroupUuids" @@ -79,7 +75,6 @@ doc { type "List" optional true since "4.1.3" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddBackendServerToServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddBackendServerToServerGroupMsgDoc_zh_cn.groovy index 71d9d2730d8..ec4e3284f95 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddBackendServerToServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddBackendServerToServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "vmNics" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.0" - } column { name "servers" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.0" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddCertificateToLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddCertificateToLoadBalancerListenerMsgDoc_zh_cn.groovy index 1a40f7c9fcd..abfffb508af 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddCertificateToLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddCertificateToLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.3" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddServerGroupToLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddServerGroupToLoadBalancerListenerMsgDoc_zh_cn.groovy index acea503e060..78aaee44186 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddServerGroupToLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddServerGroupToLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "4.0" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddVmNicToLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddVmNicToLoadBalancerMsgDoc_zh_cn.groovy index 3b7503a5b33..2adc5980b8d 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddVmNicToLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAddVmNicToLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerEvent.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerEvent.java new file mode 100644 index 00000000000..2df4384418c --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerEvent.java @@ -0,0 +1,39 @@ +package org.zstack.network.service.lb; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.util.Arrays; + +@RestResponse(allTo = "inventory") +public class APIAttachVipToLoadBalancerEvent extends APIEvent { + private LoadBalancerInventory inventory; + + public APIAttachVipToLoadBalancerEvent() { + } + + public APIAttachVipToLoadBalancerEvent(String apiId) { + super(apiId); + } + + public LoadBalancerInventory getInventory() { + return inventory; + } + + public void setInventory(LoadBalancerInventory inventory) { + this.inventory = inventory; + } + + public static APIAttachVipToLoadBalancerEvent __example__() { + APIAttachVipToLoadBalancerEvent event = new APIAttachVipToLoadBalancerEvent(); + LoadBalancerInventory lb = new LoadBalancerInventory(); + + lb.setName("Test-Lb"); + lb.setVipUuid(uuid()); + lb.setUuid(uuid()); + lb.setIpv6VipUuid(uuid()); + + return event; + } + +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerEventDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..80cafbfa531 --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.service.lb + +import org.zstack.network.service.lb.LoadBalancerInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "负载均衡器清单" + + ref { + name "inventory" + path "org.zstack.network.service.lb.APIAttachVipToLoadBalancerEvent.inventory" + desc "null" + type "LoadBalancerInventory" + since "5.0.0" + clz LoadBalancerInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.0.0" + } + ref { + name "error" + path "org.zstack.network.service.lb.APIAttachVipToLoadBalancerEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.0.0" + clz ErrorCode.class + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerMsg.java new file mode 100644 index 00000000000..11d839f2417 --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerMsg.java @@ -0,0 +1,55 @@ +package org.zstack.network.service.lb; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.network.service.vip.VipVO; + +@RestRequest( + path = "/load-balancers/{loadBalancerUuid}/vip/{vipUuid}", + method = HttpMethod.POST, + parameterName = "params", + responseClass = APIAttachVipToLoadBalancerEvent.class +) +public class APIAttachVipToLoadBalancerMsg extends APIMessage implements LoadBalancerMessage, APIAuditor{ + @APIParam(resourceType = LoadBalancerVO.class, checkAccount = true, operationTarget = true) + private String loadBalancerUuid; + + @APIParam(resourceType = VipVO.class, checkAccount = true, operationTarget = true, nonempty = true) + private String vipUuid; + + @Override + public String getLoadBalancerUuid() { + return loadBalancerUuid; + } + + public void setLoadBalancerUuid(String loadBalancerUuid) { + this.loadBalancerUuid = loadBalancerUuid; + } + + public String getVipUuid() { + return vipUuid; + } + + public void setVipUuid(String vipUuid) { + this.vipUuid = vipUuid; + } + + + public static APIAttachVipToLoadBalancerMsg __example__() { + APIAttachVipToLoadBalancerMsg msg = new APIAttachVipToLoadBalancerMsg(); + + msg.setVipUuid(uuid()); + msg.setLoadBalancerUuid(uuid()); + + return msg; + } + + @Override + public APIAuditor.Result audit(APIMessage msg, APIEvent rsp) { + return new APIAuditor.Result(((APIAttachVipToLoadBalancerMsg)msg).getLoadBalancerUuid(), LoadBalancerVO.class); + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..1b4dbf3097d --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIAttachVipToLoadBalancerMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.network.service.lb + +import org.zstack.network.service.lb.APIAttachVipToLoadBalancerEvent + +doc { + title "AttachVipToLoadBalancer" + + category "负载均衡" + + desc """加载VIP到负载均衡器""" + + rest { + request { + url "POST /v1/load-balancers/{loadBalancerUuid}/vip/{vipUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAttachVipToLoadBalancerMsg.class + + desc """""" + + params { + + column { + name "loadBalancerUuid" + enclosedIn "params" + desc "负载均衡器UUID" + location "url" + type "String" + optional false + since "5.0.0" + } + column { + name "vipUuid" + enclosedIn "params" + desc "VIP UUID" + location "url" + type "String" + optional false + since "5.0.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.0.0" + } + } + } + + response { + clz APIAttachVipToLoadBalancerEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeAccessControlListServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeAccessControlListServerGroupMsgDoc_zh_cn.groovy index a6278ee86ac..7febddd6327 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeAccessControlListServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeAccessControlListServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "4.1.3" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "4.1.3" - } column { name "aclUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "4.1.3" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.1.3" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.1.3" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerBackendServerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerBackendServerMsgDoc_zh_cn.groovy index b836756cc78..ba41fe6395e 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerBackendServerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerBackendServerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "vmNics" @@ -39,7 +38,6 @@ doc { type "List" optional true since "4.0" - } column { name "servers" @@ -49,7 +47,6 @@ doc { type "List" optional true since "4.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.0" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsg.java index 1529f30e63b..8228f15ae1a 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsg.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsg.java @@ -7,6 +7,8 @@ import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; +import java.util.List; + /** * Created by shixin.ruan on 02/25/2019. */ @@ -60,9 +62,36 @@ public class APIChangeLoadBalancerListenerMsg extends APIMessage implements Load @APIParam(numberRange = {LoadBalancerConstants.NUMBER_OF_PROCESS_MIN, LoadBalancerConstants.NUMBER_OF_PROCESS_MAX}, required = false) private Integer nbprocess; - @APIParam(validValues = {"http-keep-alive", "http-server-close", "http-tunnel", "httpclose", "forceclose"}, required = false) + @APIParam(validValues = {"http-keep-alive", "http-server-close", "httpclose"}, required = false) private String httpMode; + @APIParam(validValues = {"disable", "iphash", "insert", "rewrite"}, required = false) + private String sessionPersistence; + + @APIParam(numberRange = {LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN, LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX}, required = false) + private Integer sessionIdleTimeout; + + @APIParam(validRegexValues = LoadBalancerConstants.COOKIE_NAME_REGEX, maxLength = LoadBalancerConstants.COOKIE_NAME_MAX, required = false) + private String cookieName; + + @APIParam(required = false) + private List httpVersions; + + @APIParam(validValues = {"disable", "enable"}, required = false) + private String httpRedirectHttps; + + @APIParam(numberRange = {1, 65535}, required = false) + private Integer redirectPort; + + @APIParam(validValues = {"301", "302", "303", "307", "308"}, required = false) + private Integer statusCode; + + @APIParam(required = false) + private String tcpProxyProtocol; + + @APIParam(required = false) + private List httpCompressAlgos; + @APINoSee private String loadBalancerUuid; @@ -186,6 +215,54 @@ public void setSecurityPolicyType(String securityPolicyType) { this.securityPolicyType = securityPolicyType; } + public String getSessionPersistence() { + return sessionPersistence; + } + + public void setSessionPersistence(String sessionPersistence) { + this.sessionPersistence = sessionPersistence; + } + + public Integer getSessionIdleTimeout() { + return sessionIdleTimeout; + } + + public void setSessionIdleTimeout(Integer sessionIdleTimeout) { + this.sessionIdleTimeout = sessionIdleTimeout; + } + + public String getCookieName() { + return cookieName; + } + + public void setCookieName(String cookieName) { + this.cookieName = cookieName; + } + + public String getHttpRedirectHttps() { + return httpRedirectHttps; + } + + public void setHttpRedirectHttps(String httpRedirectHttps) { + this.httpRedirectHttps = httpRedirectHttps; + } + + public Integer getRedirectPort() { + return redirectPort; + } + + public void setRedirectPort(Integer redirectPort) { + this.redirectPort = redirectPort; + } + + public Integer getStatusCode() { + return statusCode; + } + + public void setStatusCode(Integer statusCode) { + this.statusCode = statusCode; + } + @Override public String getLoadBalancerListenerUuid() { return uuid; @@ -207,11 +284,36 @@ public void setHttpMode(String httpMode) { this.httpMode = httpMode; } + public List getHttpVersions() { + return httpVersions; + } + + public void setHttpVersions(List httpVersions) { + this.httpVersions = httpVersions; + } + + public String getTcpProxyProtocol() { + return tcpProxyProtocol; + } + + public void setTcpProxyProtocol(String tcpProxyProtocol) { + this.tcpProxyProtocol = tcpProxyProtocol; + } + public List getHttpCompressAlgos() { + return httpCompressAlgos; + } + + public void setHttpCompressAlgos(List httpCompressAlgos) { + this.httpCompressAlgos = httpCompressAlgos; + } + public static APIChangeLoadBalancerListenerMsg __example__() { APIChangeLoadBalancerListenerMsg msg = new APIChangeLoadBalancerListenerMsg(); msg.setUuid(uuid()); msg.setBalancerAlgorithm("roundrobin"); + msg.setSessionPersistence(LoadBalancerSessionPersistence.insert.toString()); + msg.setSessionIdleTimeout(60); msg.setConnectionIdleTimeout(300); msg.setHealthCheckInterval(5); msg.setHealthCheckTarget("default"); diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsgDoc_zh_cn.groovy index ed89474152b..bbe5abcf884 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIChangeLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,97 +29,70 @@ doc { type "String" optional false since "3.4" - } column { name "connectionIdleTimeout" enclosedIn "changeLoadBalancerListener" - desc "" + desc "空闲连接超时" location "body" type "Integer" optional true since "3.4" - } column { name "maxConnection" enclosedIn "changeLoadBalancerListener" - desc "" + desc "最大并发连接数" location "body" type "Integer" optional true since "3.4" - } column { name "balancerAlgorithm" enclosedIn "changeLoadBalancerListener" - desc "" + desc "负载均衡算法" location "body" type "String" optional true since "3.4" - values ("roundrobin","leastconn","source") + values ("weightroundrobin","roundrobin","leastconn","source") } column { name "healthCheckTarget" enclosedIn "changeLoadBalancerListener" - desc "" + desc "健康检查端口" location "body" type "String" optional true since "3.4" - } column { name "healthyThreshold" enclosedIn "changeLoadBalancerListener" - desc "" + desc "健康检查阈值" location "body" type "Integer" optional true since "3.4" - } column { name "unhealthyThreshold" enclosedIn "changeLoadBalancerListener" - desc "" + desc "非健康检查阈值" location "body" type "Integer" optional true since "3.4" - } column { name "healthCheckInterval" enclosedIn "changeLoadBalancerListener" - desc "" + desc "健康检查间隔时间" location "body" type "Integer" optional true since "3.4" - - } - column { - name "systemTags" - enclosedIn "" - desc "" - location "body" - type "List" - optional true - since "3.4" - - } - column { - name "userTags" - enclosedIn "" - desc "" - location "body" - type "List" - optional true - since "3.4" - } column { name "healthCheckProtocol" @@ -149,7 +122,6 @@ doc { type "String" optional true since "3.9" - } column { name "healthCheckHttpCode" @@ -159,7 +131,6 @@ doc { type "String" optional true since "3.9" - } column { name "aclStatus" @@ -171,6 +142,16 @@ doc { since "3.9" values ("enable","disable") } + column { + name "securityPolicyType" + enclosedIn "changeLoadBalancerListener" + desc "TLS安全策略" + location "body" + type "String" + optional true + since "4.1" + values ("tls_cipher_policy_default","tls_cipher_policy_1_0","tls_cipher_policy_1_1","tls_cipher_policy_1_2","tls_cipher_policy_1_2_strict","tls_cipher_policy_1_2_strict_with_1_3") + } column { name "nbprocess" enclosedIn "changeLoadBalancerListener" @@ -179,7 +160,6 @@ doc { type "Integer" optional true since "4.1" - } column { name "httpMode" @@ -189,17 +169,109 @@ doc { type "String" optional true since "4.1" - values ("http-keep-alive","http-server-close","http-tunnel","httpclose","forceclose") + values ("http-keep-alive","http-server-close","httpclose") } column { - name "securityPolicyType" + name "sessionPersistence" enclosedIn "changeLoadBalancerListener" - desc "TLS安全策略" + desc "会话保持模式" location "body" type "String" optional true - since "4.1" - values ("tls_cipher_policy_default","tls_cipher_policy_1_0","tls_cipher_policy_1_1","tls_cipher_policy_1_2","tls_cipher_policy_1_2_strict","tls_cipher_policy_1_2_strict_with_1_3") + since "4.6" + values ("disable","iphash","insert","rewrite") + } + column { + name "sessionIdleTimeout" + enclosedIn "changeLoadBalancerListener" + desc "会话保持超时时间" + location "body" + type "Integer" + optional true + since "4.6" + } + column { + name "cookieName" + enclosedIn "changeLoadBalancerListener" + desc "Cookie名称" + location "body" + type "String" + optional true + since "4.6" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "3.4" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "3.4" + } + column { + name "httpRedirectHttps" + enclosedIn "changeLoadBalancerListener" + desc "http重定向https" + location "body" + type "String" + optional true + since "4.7.21" + values ("disable","enable") + } + column { + name "redirectPort" + enclosedIn "changeLoadBalancerListener" + desc "重定向端口" + location "body" + type "Integer" + optional true + since "4.7.21" + } + column { + name "statusCode" + enclosedIn "changeLoadBalancerListener" + desc "重定向状态码" + location "body" + type "Integer" + optional true + since "4.7.21" + values ("301","302","303","307","308") + } + column { + name "httpVersions" + enclosedIn "changeLoadBalancerListener" + desc "" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "tcpProxyProtocol" + enclosedIn "changeLoadBalancerListener" + desc "" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "httpCompressAlgos" + enclosedIn "changeLoadBalancerListener" + desc "" + location "body" + type "List" + optional true + since "5.0.0" } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateCertificateMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateCertificateMsgDoc_zh_cn.groovy index 6b09a96d3c8..44210f65ec2 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateCertificateMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateCertificateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "certificate" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.3" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "2.3" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "2.3" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "2.3" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsg.java index 463e5548547..0b123054386 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsg.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsg.java @@ -58,6 +58,15 @@ public class APICreateLoadBalancerListenerMsg extends APICreateMessage implement LoadBalanceSecurityPolicyConstant.TLS_CIPHER_POLICY_1_2_STRICT_WITH_1_3}, required = false) private String securityPolicyType; + @APIParam(required = false) + private List httpVersions; + + @APIParam(required = false) + private String tcpProxyProtocol; + + @APIParam(required = false) + private List httpCompressAlgos; + @Override public String getLoadBalancerUuid() { return loadBalancerUuid; @@ -179,6 +188,34 @@ public void setSecurityPolicyType(String securityPolicyType) { this.securityPolicyType = securityPolicyType; } + public void setInstancePort(Integer instancePort) { + this.instancePort = instancePort; + } + + public List getHttpVersions() { + return httpVersions; + } + + public void setHttpVersions(List httpVersions) { + this.httpVersions = httpVersions; + } + + public String getTcpProxyProtocol() { + return tcpProxyProtocol; + } + + public void setTcpProxyProtocol(String tcpProxyProtocol) { + this.tcpProxyProtocol = tcpProxyProtocol; + } + + public List getHttpCompressAlgos() { + return httpCompressAlgos; + } + + public void setHttpCompressAlgos(List httpCompressAlgos) { + this.httpCompressAlgos = httpCompressAlgos; + } + public static APICreateLoadBalancerListenerMsg __example__() { APICreateLoadBalancerListenerMsg msg = new APICreateLoadBalancerListenerMsg(); diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsgDoc_zh_cn.groovy index e5ea2e26775..cfaae8626bb 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "instancePort" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "loadBalancerPort" @@ -69,7 +65,6 @@ doc { type "int" optional false since "0.6" - } column { name "protocol" @@ -89,7 +84,6 @@ doc { type "String" optional true since "2.3" - } column { name "healthCheckProtocol" @@ -119,7 +113,6 @@ doc { type "String" optional true since "3.9" - } column { name "healthCheckHttpCode" @@ -129,7 +122,6 @@ doc { type "String" optional true since "3.9" - } column { name "aclStatus" @@ -149,7 +141,6 @@ doc { type "List" optional true since "3.9" - } column { name "aclType" @@ -169,7 +160,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -179,7 +169,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -189,7 +178,6 @@ doc { type "List" optional true since "0.6" - } column { name "tagUuids" @@ -198,8 +186,7 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" } column { name "securityPolicyType" @@ -211,6 +198,33 @@ doc { since "4.1" values ("tls_cipher_policy_default","tls_cipher_policy_1_0","tls_cipher_policy_1_1","tls_cipher_policy_1_2","tls_cipher_policy_1_2_strict","tls_cipher_policy_1_2_strict_with_1_3") } + column { + name "httpVersions" + enclosedIn "params" + desc "" + location "body" + type "List" + optional true + since "5.0.0" + } + column { + name "tcpProxyProtocol" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "5.0.0" + } + column { + name "httpCompressAlgos" + enclosedIn "params" + desc "" + location "body" + type "List" + optional true + since "5.0.0" + } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsg.java index a76a228ed80..e8311340436 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsg.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsg.java @@ -1,5 +1,6 @@ package org.zstack.network.service.lb; +import org.apache.commons.lang.StringUtils; import org.springframework.http.HttpMethod; import org.zstack.header.identity.Action; import org.zstack.header.message.APICreateMessage; @@ -7,9 +8,15 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.APINoSee; import org.zstack.header.rest.RestRequest; import org.zstack.header.tag.TagResourceType; import org.zstack.network.service.vip.VipVO; +import org.zstack.utils.CollectionUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; /** * Created by frank on 8/8/2015. @@ -27,9 +34,15 @@ public class APICreateLoadBalancerMsg extends APICreateMessage implements APIAud private String name; @APIParam(maxLength = 2048, required = false) private String description; - @APIParam(resourceType = VipVO.class, checkAccount = true) + @APIParam(required = false, resourceType = VipVO.class, checkAccount = true) private String vipUuid; + @APIParam(required = false, resourceType = VipVO.class, checkAccount = true) + private String ipv6VipUuid; + + @APINoSee + private List vipUuids; + private String type; public String getName() { @@ -56,6 +69,28 @@ public void setVipUuid(String vipUuid) { this.vipUuid = vipUuid; } + public String getIpv6VipUuid() { + return ipv6VipUuid; + } + + public void setIpv6VipUuid(String ipv6VipUuid) { + this.ipv6VipUuid = ipv6VipUuid; + } + + public List getVipUuids() { + if (!CollectionUtils.isEmpty(vipUuids)) { + return vipUuids; + } + + vipUuids = new ArrayList<>(); + if (!StringUtils.isEmpty(vipUuid)) { + vipUuids.add(vipUuid); + } + if (!StringUtils.isEmpty(ipv6VipUuid)) { + vipUuids.add(ipv6VipUuid); + } + return vipUuids; + } public String getType() { return type; } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsgDoc_zh_cn.groovy index 20b33d90ff1..044ffdd32d3 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "vipUuid" @@ -47,9 +45,8 @@ doc { desc "VIP UUID" location "body" type "String" - optional false + optional true since "0.6" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,33 @@ doc { type "List" optional true since "0.6" - + } + column { + name "type" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "0.6" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "vip6Uuid" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.7.21" } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsg.java index cc8af59134e..a1eb07d1f96 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsg.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsg.java @@ -26,6 +26,8 @@ public class APICreateLoadBalancerServerGroupMsg extends APICreateMessage implem private String description; @APIParam(resourceType = LoadBalancerVO.class, checkAccount = true, operationTarget = true) private String loadBalancerUuid; + @APIParam(required = false) + private Integer ipVersion; public String getName() { return name; @@ -51,11 +53,20 @@ public void setLoadBalancerUuid(String loadBalancerUuid) { this.loadBalancerUuid = loadBalancerUuid; } + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + public static APICreateLoadBalancerServerGroupMsg __example__() { APICreateLoadBalancerServerGroupMsg msg = new APICreateLoadBalancerServerGroupMsg(); msg.setName("create-Lb"); msg.setLoadBalancerUuid(uuid()); + msg.setIpVersion(4); return msg; } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsgDoc_zh_cn.groovy index 508750e679e..94aca8fdb1e 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APICreateLoadBalancerServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "loadBalancerUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "tagUuids" @@ -68,8 +64,7 @@ doc { location "body" type "List" optional true - since "0.6" - + since "3.4.0" } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +83,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "ipVersion" + enclosedIn "params" + desc "IP版本" + location "body" + type "Integer" + optional true + since "5.1.0" } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteCertificateMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteCertificateMsgDoc_zh_cn.groovy index f3244075c32..5f10f164334 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteCertificateMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteCertificateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "2.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.3" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerListenerMsgDoc_zh_cn.groovy index 30c78519a2d..a12fe55e4b5 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerMsgDoc_zh_cn.groovy index aa7a184ea45..40e9c5b3ca0 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerServerGroupMsgDoc_zh_cn.groovy index cf91a6958d9..3afd75be6dd 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIDeleteLoadBalancerServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForLoadBalancerMsgDoc_zh_cn.groovy index 6780beef885..941766f0a2d 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.9.0" - } column { name "limit" @@ -39,7 +38,6 @@ doc { type "Integer" optional true since "3.9.0" - } column { name "start" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "3.9.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.9.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "3.9.0" - } } } @@ -78,4 +73,4 @@ doc { clz APIGetCandidateL3NetworksForLoadBalancerReply.class } } -} +} \ No newline at end of file diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForServerGroupMsgDoc_zh_cn.groovy index 661f1e2529c..54569028c5e 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateL3NetworksForServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "4.3.0" - } column { name "loadBalancerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.3.0" - } column { name "limit" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "4.3.0" - } column { name "start" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "4.3.0" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.3.0" - } column { name "userTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "4.3.0" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerMsgDoc_zh_cn.groovy index afe536c918e..fe6cf8b7a72 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsg.java index a571ee523be..1f45c4d9feb 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsg.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsg.java @@ -21,6 +21,8 @@ public class APIGetCandidateVmNicsForLoadBalancerServerGroupMsg extends APISyncC private String servergroupUuid; @APIParam(resourceType = LoadBalancerVO.class, required = false) private String loadBalancerUuid; + @APIParam(required = false, validValues = {"4", "6"}) + private Integer ipVersion; public String getServergroupUuid() { return servergroupUuid; @@ -37,7 +39,15 @@ public String getLoadBalancerUuid() { public void setLoadBalancerUuid(String loadBalancerUuid) { this.loadBalancerUuid = loadBalancerUuid; } - + + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + public static APIGetCandidateVmNicsForLoadBalancerServerGroupMsg __example__() { APIGetCandidateVmNicsForLoadBalancerServerGroupMsg msg = new APIGetCandidateVmNicsForLoadBalancerServerGroupMsg(); diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsgDoc_zh_cn.groovy index 2bfcf88e57a..82251e4b21d 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetCandidateVmNicsForLoadBalancerServerGroupMsgDoc_zh_cn.groovy @@ -7,7 +7,7 @@ doc { category "loadBalancer" - desc """在这里填写API描述""" + desc """查询负载均衡后端服务器组可以添加网卡列表""" rest { request { @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "loadBalancerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,16 @@ doc { type "List" optional true since "0.6" - + } + column { + name "ipVersion" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "5.1.0" + values ("4","6") } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetLoadBalancerListenerACLEntriesMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetLoadBalancerListenerACLEntriesMsgDoc_zh_cn.groovy index 2913c7495e3..00146ee0aef 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetLoadBalancerListenerACLEntriesMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIGetLoadBalancerListenerACLEntriesMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional true since "0.6" - } column { name "type" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryCertificateMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryCertificateMsgDoc_zh_cn.groovy index 436971f60a3..2ee7a282243 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryCertificateMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryCertificateMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.lb import org.zstack.network.service.lb.APIQueryCertificateReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryCertificate" diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerListenerMsgDoc_zh_cn.groovy index 0efeab000b0..6214c52d899 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.lb import org.zstack.network.service.lb.APIQueryLoadBalancerListenerReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询负载均衡监听器(QueryLoadBalancerListener)" diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerMsgDoc_zh_cn.groovy index ec2eeb6bc9a..c5e56799fa8 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIQueryLoadBalancerMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.lb import org.zstack.network.service.lb.APIQueryLoadBalancerReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询负载均衡器(QueryLoadBalancer)" diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRefreshLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRefreshLoadBalancerMsgDoc_zh_cn.groovy index cb80d5d1b05..4f5524ab06f 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRefreshLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRefreshLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveAccessControlListFromLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveAccessControlListFromLoadBalancerMsgDoc_zh_cn.groovy index 669b1c27bcc..62553f4666d 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveAccessControlListFromLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveAccessControlListFromLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "3.9" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "3.9" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.9" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.9" - } column { name "serverGroupUuids" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveBackendServerFromServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveBackendServerFromServerGroupMsgDoc_zh_cn.groovy index 5bd4afc7c3b..d22b64069c1 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveBackendServerFromServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveBackendServerFromServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "vmNicUuids" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "serverIps" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveCertificateFromLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveCertificateFromLoadBalancerListenerMsgDoc_zh_cn.groovy index 098f2667db9..09a8f1e9734 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveCertificateFromLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveCertificateFromLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "2.3" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "2.3" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveServerGroupFromLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveServerGroupFromLoadBalancerListenerMsgDoc_zh_cn.groovy index f8c2bb12dcf..a8434bb3741 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveServerGroupFromLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveServerGroupFromLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveVmNicFromLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveVmNicFromLoadBalancerMsgDoc_zh_cn.groovy index 3ed288c5c65..df2adca2b7c 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveVmNicFromLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIRemoveVmNicFromLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "listenerUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateCertificateMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateCertificateMsgDoc_zh_cn.groovy index 650c29ab04a..84ca86168d6 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateCertificateMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateCertificateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.3" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "2.3" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "2.3" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "2.3" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "2.3" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "2.3" - + } + column { + name "tagUuids" + enclosedIn "updateCertificate" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerListenerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerListenerMsgDoc_zh_cn.groovy index f6ac58971ca..cba7ddaa7c5 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerListenerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerListenerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerMsgDoc_zh_cn.groovy index 280559bef2d..7283c202208 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +74,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "updateLoadBalancer" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerServerGroupMsgDoc_zh_cn.groovy b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerServerGroupMsgDoc_zh_cn.groovy index ece17dd8869..3623bff0a42 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerServerGroupMsgDoc_zh_cn.groovy +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/APIUpdateLoadBalancerServerGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "4.0" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "4.0" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "4.0" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "4.0" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "4.0" - } } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/AttachVipToLoadBalancerMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/AttachVipToLoadBalancerMsg.java new file mode 100644 index 00000000000..a712856db61 --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/AttachVipToLoadBalancerMsg.java @@ -0,0 +1,29 @@ +package org.zstack.network.service.lb; + +import org.zstack.header.message.NeedReplyMessage; + +public class AttachVipToLoadBalancerMsg extends NeedReplyMessage implements LoadBalancerMessage{ + private String uuid; + private String vipUuid; + + @Override + public String getLoadBalancerUuid() { + return uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVipUuid() { + return vipUuid; + } + + public void setVipUuid(String vipUuid) { + this.vipUuid = vipUuid; + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/AttachVipToLoadBalancerReply.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/AttachVipToLoadBalancerReply.java new file mode 100644 index 00000000000..dd70962ff69 --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/AttachVipToLoadBalancerReply.java @@ -0,0 +1,15 @@ +package org.zstack.network.service.lb; + +import org.zstack.header.message.MessageReply; + +public class AttachVipToLoadBalancerReply extends MessageReply { + private LoadBalancerInventory inventory; + + public LoadBalancerInventory getInventory() { + return inventory; + } + + public void setInventory(LoadBalancerInventory inventory) { + this.inventory = inventory; + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/DetachVipFromLoadBalancerMsg.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/DetachVipFromLoadBalancerMsg.java new file mode 100644 index 00000000000..8fdc10c7589 --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/DetachVipFromLoadBalancerMsg.java @@ -0,0 +1,39 @@ +package org.zstack.network.service.lb; + +import org.zstack.header.message.NeedReplyMessage; + +public class DetachVipFromLoadBalancerMsg extends NeedReplyMessage implements LoadBalancerMessage{ + private String uuid; + private String vipUuid; + + private boolean hardDeleteDb; + + @Override + public String getLoadBalancerUuid() { + return uuid; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVipUuid() { + return vipUuid; + } + + public void setVipUuid(String vipUuid) { + this.vipUuid = vipUuid; + } + + public boolean isHardDeleteDb() { + return hardDeleteDb; + } + + public void setHardDeleteDb(boolean hardDeleteDb) { + this.hardDeleteDb = hardDeleteDb; + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/DetachVipFromLoadBalancerReply.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/DetachVipFromLoadBalancerReply.java new file mode 100644 index 00000000000..c5d3422bfdd --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/DetachVipFromLoadBalancerReply.java @@ -0,0 +1,15 @@ +package org.zstack.network.service.lb; + +import org.zstack.header.message.MessageReply; + +public class DetachVipFromLoadBalancerReply extends MessageReply { + private LoadBalancerInventory inventory; + + public LoadBalancerInventory getInventory() { + return inventory; + } + + public void setInventory(LoadBalancerInventory inventory) { + this.inventory = inventory; + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java index e33b13247a2..ea1168da036 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerApiInterceptor.java @@ -29,6 +29,8 @@ import org.zstack.header.network.l3.UsedIpVO_; import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO; import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO_; +import org.zstack.header.tag.SystemTagVO; +import org.zstack.header.tag.SystemTagVO_; import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; import org.zstack.network.service.vip.VipNetworkServicesRefVO; @@ -51,8 +53,7 @@ import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; -import static org.zstack.network.service.lb.LoadBalancerConstants.LB_PROTOCOL_HTTP; -import static org.zstack.network.service.lb.LoadBalancerConstants.LB_PROTOCOL_HTTPS; +import static org.zstack.network.service.lb.LoadBalancerConstants.*; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -89,6 +90,11 @@ public InterceptorPosition getPosition() { return InterceptorPosition.END; } + @Override + public int getPriority() { + return -1; + } + @Override public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { if (msg instanceof APIDeleteLoadBalancerListenerMsg) { @@ -173,6 +179,10 @@ private void validate(APIGetCandidateVmNicsForLoadBalancerServerGroupMsg msg) { throw new ApiMessageInterceptionException( operr("could not get candidate vmnic, because both load balancer uuid and server group uuid are not specified")); } + + if (msg.getIpVersion() == null) { + msg.setIpVersion(4); + } } private void validate(APIGetCandidateL3NetworksForLoadBalancerMsg msg) { @@ -221,31 +231,58 @@ private void validate(APIRemoveVmNicFromLoadBalancerMsg msg) { } private void validate(APICreateLoadBalancerMsg msg) { - List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, msg.getVipUuid()).listValues(); + if (StringUtils.isEmpty(msg.getVipUuid()) && StringUtils.isEmpty(msg.getIpv6VipUuid())) { + throw new ApiMessageInterceptionException(argerr("could not create loadbalancer, because param of vip and ipv6 vip is empty")); + } + + List l3Uuids = Q.New(VipVO.class).select(VipVO_.l3NetworkUuid).in(VipVO_.uuid, Arrays.asList(msg.getIpv6VipUuid(), msg.getVipUuid())).listValues(); + int countOfL3 = l3Uuids.stream().distinct().collect(Collectors.toList()).size(); + if (countOfL3 > 1) { + throw new ApiMessageInterceptionException(argerr("could not create loadbalancer, because l3 network of vip and ipv6 vip are not the same l3 network")); + } + + if (!StringUtils.isEmpty(msg.getVipUuid())) { + validateVipOfLoadBalancer(IPv6Constants.IPv4, msg.getVipUuid()); + } + + if (!StringUtils.isEmpty(msg.getIpv6VipUuid())) { + validateVipOfLoadBalancer(IPv6Constants.IPv6, msg.getIpv6VipUuid()); + } + } + + private void validateVipOfLoadBalancer(int vipIpVersion, String vipUuid) { + List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, vipUuid).listValues(); if(useFor != null && !useFor.isEmpty()){ VipUseForList useForList = new VipUseForList(useFor); if(!useForList.validateNewAdded(LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING)){ - throw new ApiMessageInterceptionException(argerr("the vip[uuid:%s] has been occupied other network service entity[%s]", msg.getVipUuid(), useForList.toString())); + throw new ApiMessageInterceptionException(argerr("the vip[uuid:%s] has been occupied other network service entity[%s]", vipUuid, useForList.toString())); } } /* the vip can not the first of the last ip of the cidr */ - VipVO vipVO = dbf.findByUuid(msg.getVipUuid(), VipVO.class); - if (NetworkUtils.isIpv4Address(vipVO.getIp())) { - AddressPoolVO addressPoolVO = dbf.findByUuid(vipVO.getIpRangeUuid(), AddressPoolVO.class); - if (addressPoolVO == null) { - return; - } + VipVO vipVO = dbf.findByUuid(vipUuid, VipVO.class); + if (IPv6Constants.IPv4 == vipIpVersion) { + if (NetworkUtils.isIpv4Address(vipVO.getIp())) { + AddressPoolVO addressPoolVO = dbf.findByUuid(vipVO.getIpRangeUuid(), AddressPoolVO.class); + if (addressPoolVO == null) { + return; + } - SubnetUtils utils = new SubnetUtils(addressPoolVO.getNetworkCidr()); - SubnetUtils.SubnetInfo subnet = utils.getInfo(); - String firstIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress()) - 1); - String lastIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getHighAddress()) + 1); - if (vipVO.getIp().equals(firstIp) || vipVO.getIp().equals(lastIp)) { - throw new ApiMessageInterceptionException(argerr("Load balancer VIP [%s] cannot be the first or the last IP of the CIDR with the public address pool type", vipVO.getIp())); + SubnetUtils utils = new SubnetUtils(addressPoolVO.getNetworkCidr()); + SubnetUtils.SubnetInfo subnet = utils.getInfo(); + String firstIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getLowAddress()) - 1); + String lastIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnet.getHighAddress()) + 1); + if (vipVO.getIp().equals(firstIp) || vipVO.getIp().equals(lastIp)) { + throw new ApiMessageInterceptionException(argerr("Load balancer VIP [%s] cannot be the first or the last IP of the CIDR with the public address pool type", vipVO.getIp())); + } + } else { + throw new ApiMessageInterceptionException(argerr("cloud not create loadbalancer, because param vipUuid point to VIP[%s] is not ipv4 VIP", vipVO.getUuid())); + } + } else if (IPv6Constants.IPv6 == vipIpVersion) { + if (!IPv6NetworkUtils.isIpv6Address(vipVO.getIp())) { + throw new ApiMessageInterceptionException(argerr("cloud not create loadbalancer, because param ipv6VipUuid point to VIP[%s] is not ipv6 VIP", vipVO.getUuid())); } } - } private boolean validateIpRange(String startIp, String endIp) { @@ -310,7 +347,7 @@ private void validateAcl(List newAclUuids, List oriAclUuids, Str .in(AccessControlListVO_.uuid, newAclUuids).list(); if (!acls.isEmpty()) { /*check if the ip version is same*/ - List aclUuids = acls.stream().filter(acl -> acl.getIpVersion() != NetworkUtils.getIpversion(vip.getIp())).map(AccessControlListVO::getUuid).collect(Collectors.toList()); + List aclUuids = acls.stream().filter(acl -> !acl.getIpVersion().equals(NetworkUtils.getIpversion(vip.getIp()))).map(AccessControlListVO::getUuid).collect(Collectors.toList()); if (!aclUuids.isEmpty()) { throw new ApiMessageInterceptionException(argerr("Can't attach the type access-control-list group[%s] whose ip version is different with LoadBalancer[%s]", aclUuids, lbUuid)); } @@ -638,12 +675,22 @@ private Boolean verifyHttpCode(String httpCode) { } private void validate(APICreateLoadBalancerListenerMsg msg) { + LoadBalancerVO lbVO = dbf.findByUuid(msg.getLoadBalancerUuid(), LoadBalancerVO.class); + if (msg.getInstancePort() == null) { msg.setInstancePort(msg.getLoadBalancerPort()); } if (msg.getProtocol() == null) { msg.setProtocol(LoadBalancerConstants.LB_PROTOCOL_TCP); } + + if (msg.getProtocol().equals(LB_PROTOCOL_UDP)) { + if (!StringUtils.isEmpty(lbVO.getVipUuid()) && !StringUtils.isEmpty(lbVO.getIpv6VipUuid())) { + throw new ApiMessageInterceptionException( + operr("can not create listener because udp listener can not have both ipv4 and ipv6 vip", + msg.getProtocol(), msg.getHealthCheckProtocol())); + } + } if (msg.getHealthCheckProtocol() == null) { if (LoadBalancerConstants.LB_PROTOCOL_UDP.equals(msg.getProtocol())) { msg.setHealthCheckProtocol(LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCL_UDP); @@ -773,6 +820,212 @@ private void validate(APICreateLoadBalancerListenerMsg msg) { ); } + /*can not modify l4's session persistence*/ + if (LoadBalancerConstants.LB_PROTOCOL_UDP.equals(msg.getProtocol()) || LoadBalancerConstants.LB_PROTOCOL_TCP.equals(msg.getProtocol())) { + for (String tag : msg.getSystemTags()) { + if (LoadBalancerSystemTags.SESSION_PERSISTENCE.isMatch(tag) || LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT.isMatch(tag) || LoadBalancerSystemTags.COOKIE_NAME.isMatch(tag)) { + throw new ApiMessageInterceptionException(argerr("l4[%s] loadBalancer listener[%s] doesn't support assigning session persistence state", msg.getProtocol(), msg.getName())); + } + } + } + + String algorithm = null, seessionPersistence = null, httpRedirectHttps = null, redirectPort = null, statusCode = null; + for (String tag : msg.getSystemTags()) { + if (LoadBalancerSystemTags.BALANCER_ALGORITHM.isMatch(tag)) { + algorithm = LoadBalancerSystemTags.BALANCER_ALGORITHM.getTokenByTag(tag, + LoadBalancerSystemTags.BALANCER_ALGORITHM_TOKEN); + } + if (LoadBalancerSystemTags.SESSION_PERSISTENCE.isMatch(tag)) { + seessionPersistence = LoadBalancerSystemTags.SESSION_PERSISTENCE.getTokenByTag(tag, + LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN); + } + if (LoadBalancerSystemTags.HTTP_REDIRECT_HTTPS.isMatch(tag)) { + httpRedirectHttps = LoadBalancerSystemTags.HTTP_REDIRECT_HTTPS.getTokenByTag(tag, + LoadBalancerSystemTags.HTTP_REDIRECT_HTTPS_TOKEN); + } + if (LoadBalancerSystemTags.REDIRECT_PORT.isMatch(tag)) { + redirectPort = LoadBalancerSystemTags.REDIRECT_PORT.getTokenByTag(tag, + LoadBalancerSystemTags.REDIRECT_PORT_TOKEN); + } + if (LoadBalancerSystemTags.STATUS_CODE.isMatch(tag)) { + statusCode = LoadBalancerSystemTags.STATUS_CODE.getTokenByTag(tag, + LoadBalancerSystemTags.STATUS_CODE_TOKEN); + } + } + + if ((redirectPort != null || statusCode != null) && (httpRedirectHttps == null || HttpRedirectHttps.disable.toString().equals(httpRedirectHttps))) { + throw new ApiMessageInterceptionException(argerr("could not assign redirect port or status code without specifying http redirect https")); + } + + List validRedirectValues = Arrays.asList("disable", "enable"); + if (httpRedirectHttps != null && !validRedirectValues.contains(httpRedirectHttps)) { + throw new ApiMessageInterceptionException(argerr("invalid redirect status [%s], it only support %s", httpRedirectHttps, validRedirectValues)); + } + + List validCodeValues = Arrays.asList("301", "302", "303", "307", "308"); + if (statusCode != null && !validCodeValues.contains(statusCode)) { + throw new ApiMessageInterceptionException(argerr("invalid status code [%s], it only support %s", statusCode, validCodeValues)); + } + + if (HttpRedirectHttps.enable.toString().equals(httpRedirectHttps)) { + if (!LB_PROTOCOL_HTTP.equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException(argerr("could not support protocols other than HTTP when specifying http redirect https")); + } + if (redirectPort == null) { + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.REDIRECT_PORT, + LoadBalancerSystemTags.REDIRECT_PORT.instantiateTag( + map(e(LoadBalancerSystemTags.REDIRECT_PORT_TOKEN, LoadBalancerConstants.REDIRECT_PORT_DEFAULT)) + ) + ); + } + if (statusCode == null) { + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.STATUS_CODE, + LoadBalancerSystemTags.STATUS_CODE.instantiateTag( + map(e(LoadBalancerSystemTags.STATUS_CODE_TOKEN, STATUS_CODE_DEFAULT)) + ) + ); + } + if (seessionPersistence != null && !LoadBalancerSessionPersistence.disable.toString().equals(seessionPersistence)) { + throw new ApiMessageInterceptionException(argerr("could not support both HTTP redirect HTTPS and session persistence at the same time")); + } + } + + List validPersistenceValues = Arrays.asList("disable", "iphash", "insert", "rewrite"); + if (seessionPersistence != null && !validPersistenceValues.contains(seessionPersistence)) { + throw new ApiMessageInterceptionException(argerr("invalid session persistence status [%s], it only support %s", seessionPersistence, validPersistenceValues)); + } + + /*can not modify session persistence when the listener algorithm is leastconn except disable*/ + if (LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_CONN.equals(algorithm)) { + for (String tag : msg.getSystemTags()) { + if ((!LoadBalancerSessionPersistence.disable.toString().equals(seessionPersistence) && seessionPersistence != null) || LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT.isMatch(tag) || LoadBalancerSystemTags.COOKIE_NAME.isMatch(tag)) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] %s algorithm doesn't support assigning session persistence state except assigning disable explicitly", msg.getLoadBalancerUuid(), msg.getName(), algorithm)); + } + } + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.SESSION_PERSISTENCE, + LoadBalancerSystemTags.SESSION_PERSISTENCE.instantiateTag( + map(e(LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN, LoadBalancerSessionPersistence.disable)) + ) + ); + } + + /*can not modify session persistence when the listener algorithm is source except iphash*/ + if (LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_SOURCE.equals(algorithm)) { + for (String tag : msg.getSystemTags()) { + if ((!LoadBalancerSessionPersistence.iphash.toString().equals(seessionPersistence) && seessionPersistence != null) || LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT.isMatch(tag) || LoadBalancerSystemTags.COOKIE_NAME.isMatch(tag)) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] %s algorithm doesn't support assigning session persistence state except assigning iphash explicitly", msg.getLoadBalancerUuid(), msg.getName(), algorithm)); + } + } + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.SESSION_PERSISTENCE, + LoadBalancerSystemTags.SESSION_PERSISTENCE.instantiateTag( + map(e(LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN, LoadBalancerSessionPersistence.iphash)) + ) + ); + } + + /*modify session persistence when the listener algorithm is roundrobin or weightroundrobin*/ + if (LB_PROTOCOL_HTTP.equals(msg.getProtocol()) || LB_PROTOCOL_HTTPS.equals(msg.getProtocol())) { + if (LoadBalancerConstants.BALANCE_ALGORITHM_ROUND_ROBIN.equals(algorithm) || LoadBalancerConstants.BALANCE_ALGORITHM_WEIGHT_ROUND_ROBIN.equals(algorithm)) { + String enableSession = null, timeout = null, cookieName = null, httpMode = null; + for (String tag : msg.getSystemTags()) { + if (LoadBalancerSystemTags.HTTP_MODE.isMatch(tag)) { + httpMode = LoadBalancerSystemTags.HTTP_MODE.getTokenByTag(tag, + LoadBalancerSystemTags.HTTP_MODE_TOKEN); + } + if (LoadBalancerSystemTags.SESSION_PERSISTENCE.isMatch(tag)) { + enableSession = LoadBalancerSystemTags.SESSION_PERSISTENCE.getTokenByTag(tag, + LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN); + try { + LoadBalancerSessionPersistence.valueOf(LoadBalancerSessionPersistence.class, enableSession); + } catch (Exception e) { + throw new ApiMessageInterceptionException(argerr("invalid session persistence type[%s], it only support %s", enableSession, Arrays.toString(LoadBalancerSessionPersistence.values()))); + } + } + if (LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT.isMatch(tag)) { + timeout = LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT.getTokenByTag(tag, + LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT_TOKEN); + if (Long.parseLong(timeout) < LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN || Long.parseLong(timeout) > LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX) { + throw new ApiMessageInterceptionException(argerr("invalid session idle timeout[%s], it must be the number between[%s~%s] ", timeout, LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN, LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX)); + } + } + if (LoadBalancerSystemTags.COOKIE_NAME.isMatch(tag)) { + cookieName = LoadBalancerSystemTags.COOKIE_NAME.getTokenByTag(tag, + LoadBalancerSystemTags.COOKIE_NAME_TOKEN); + if (cookieName.length() > 20) { + throw new ApiMessageInterceptionException(argerr("invalid session cookie name[%s], it must be shorter than [%s] characters", cookieName, COOKIE_NAME_MAX)); + } + if (!cookieName.matches(COOKIE_NAME_REGEX)) { + throw new ApiMessageInterceptionException(argerr("invalid session cookie name[%s], it must only contains letters, numbers and underscores", cookieName)); + } + } + if (enableSession != null && timeout != null && cookieName != null) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning idle timeout and cookie name at the same time", msg.getLoadBalancerUuid(), msg.getName())); + } + } + + /*can not assign session idle timeout and cookie name without specifying session persistence*/ + if (enableSession == null && (timeout != null || cookieName != null)) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning idle timeout and cookie name, it must specify session persistence", msg.getLoadBalancerUuid(), msg.getName())); + } + + if (LoadBalancerSessionPersistence.disable.toString().equals(enableSession) && (timeout != null || cookieName != null)) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning idle timeout and cookie name when the session persistence is disabled", msg.getLoadBalancerUuid(), msg.getName())); + } + + if (LoadBalancerSessionPersistence.insert.toString().equals(enableSession) && timeout == null) { + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT, + LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT.instantiateTag( + map(e(LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT_TOKEN, LoadBalancerConstants.SESSION_IDLE_TIMEOUT_DEFAULT)) + ) + ); + } + + /*can not assign session persistence rewrite without cookie name*/ + if (LoadBalancerSessionPersistence.rewrite.toString().equals(enableSession) && cookieName == null) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning session persistence rewrite without assigning cookie name", msg.getLoadBalancerUuid(), msg.getName())); + } + + /*can not assign session persistence idle timeout without insert mode*/ + if (LoadBalancerSessionPersistence.rewrite.toString().equals(enableSession) && timeout != null) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning session persistence idle timeout without assigning rewrite mode", msg.getLoadBalancerUuid(), msg.getName())); + } + + /*can not assign session persistence cookie name without rewrite mode*/ + if (LoadBalancerSessionPersistence.insert.toString().equals(enableSession) && cookieName != null) { + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning session persistence cookieName without assigning insert mode", msg.getLoadBalancerUuid(), msg.getName())); + } + + } + if (LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_SOURCE.equals(algorithm)) { + for (String tag : msg.getSystemTags()) { + if (LoadBalancerSystemTags.SESSION_PERSISTENCE.isMatch(tag)) { + String enableSession = LoadBalancerSystemTags.SESSION_PERSISTENCE.getTokenByTag(tag, + LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN); + if (!LoadBalancerSessionPersistence.iphash.toString().equals(enableSession)) { + /*can not assign other session persistence with source algorithm*/ + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning other session persistence when the source balancer algorithm is source", msg.getLoadBalancerUuid(), msg.getName())); + } + } + } + } + for (String tag : msg.getSystemTags()) { + if (LoadBalancerSystemTags.SESSION_PERSISTENCE.isMatch(tag)) { + String enableSession = LoadBalancerSystemTags.SESSION_PERSISTENCE.getTokenByTag(tag, + LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN); + if (LoadBalancerSessionPersistence.iphash.toString().equals(enableSession)) { + if (!LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_SOURCE.equals(algorithm)) { + /*can not assign session persistence iphash without source algorithm*/ + throw new ApiMessageInterceptionException(argerr("loadBalancer[%s] listener[%s] doesn't support assigning session persistence iphash", msg.getLoadBalancerUuid(), msg.getName())); + } + } + } + } + } /*check the validation of systemtags*/ for (String tag : msg.getSystemTags()) { @@ -815,6 +1068,70 @@ private void validate(APICreateLoadBalancerListenerMsg msg) { throw new ApiMessageInterceptionException(operr("the listener with protocol [%s] doesn't support select security policy", msg.getProtocol(), msg.getHealthCheckProtocol())); } } + + if (!CollectionUtils.isEmpty(msg.getHttpVersions())) { + if (!LoadBalancerConstants.LB_PROTOCOL_HTTPS.equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because the listener with protocol [%s] doesn't support select http version:[%s]", + msg.getProtocol(), msg.getHttpVersions())); + } + + if (hasNotSupportedHttpVersion(msg.getHttpVersions())) { + throw new ApiMessageInterceptionException( + argerr("cloud not create the loadbalancer listener, because the listener with protocol https only support http version:[h1, h2]")); + } + + String httpVersions = String.join(",", msg.getHttpVersions()); + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.HTTP_VERSIONS, + LoadBalancerSystemTags.HTTP_VERSIONS.instantiateTag( + map(e(LoadBalancerSystemTags.HTTP_VERSIONS_TOKEN, httpVersions)) + ) + ); + } + + if (!StringUtils.isEmpty(msg.getTcpProxyProtocol())) { + if (!LoadBalancerConstants.LB_PROTOCOL_TCP.equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not create the loadbalancer listener, because the listener with protocol tcp only support tcp proxy protocol param")); + } + + if (!LbSupportTcpProxyProtocol.contains(msg.getTcpProxyProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not create the loadbalancer listener, because only support tcp proxy protocol %s", LbSupportTcpProxyProtocol)); + } + + if (!msg.getTcpProxyProtocol().equals(DisableLbSupportTcpProxyProtocol)) { + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.TCP_PROXYPROTOCOL, + LoadBalancerSystemTags.TCP_PROXYPROTOCOL.instantiateTag( + map(e(LoadBalancerSystemTags.TCP_PROXYPROTOCOL_TOKEN, msg.getTcpProxyProtocol())) + ) + ); + } + } + + if (!CollectionUtils.isEmpty(msg.getHttpCompressAlgos())) { + if (!LoadBalancerConstants.LB_PROTOCOL_HTTPS.equals(msg.getProtocol()) && !LB_PROTOCOL_HTTP.equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not create the loadbalancer listener, because the listener with protocol [%s] doesn't support compress content", + msg.getProtocol(), msg.getHttpVersions())); + } + + if (hasNotSupportedHttpCompressAlgos(msg.getHttpCompressAlgos())) { + throw new ApiMessageInterceptionException( + argerr("cloud not create the loadbalancer listener, because only support compress algos[%s]", LbSupportHttpCompressAlgos)); + } + + if (!msg.getHttpCompressAlgos().contains(DisableLbSupportHttpCompressAlgos)) { + insertTagIfNotExisting( + msg, LoadBalancerSystemTags.HTTP_COMPRESS_ALGOS, + LoadBalancerSystemTags.HTTP_COMPRESS_ALGOS.instantiateTag( + map(e(LoadBalancerSystemTags.HTTP_COMPRESS_ALGOS_TOKEN, String.join(" ", msg.getHttpCompressAlgos()))) + ) + ); + } + } } private void validate(APIDeleteLoadBalancerListenerMsg msg) { @@ -879,6 +1196,119 @@ private void validate(APIChangeLoadBalancerListenerMsg msg) { } } + LoadBalancerListenerVO listener = Q.New(LoadBalancerListenerVO.class). + eq(LoadBalancerListenerVO_.uuid,msg.getUuid()) + .find(); + + if ((msg.getRedirectPort() != null || msg.getStatusCode() != null) && (msg.getHttpRedirectHttps() == null || HttpRedirectHttps.disable.toString().equals(msg.getHttpRedirectHttps()))) { + throw new ApiMessageInterceptionException(argerr("could not assign redirect port or status code without specifying http redirect https")); + } + + if (HttpRedirectHttps.enable.toString().equals(msg.getHttpRedirectHttps())) { + if (!LB_PROTOCOL_HTTP.equals(listener.getProtocol())) { + throw new ApiMessageInterceptionException(argerr("could not support protocols other than HTTP when specifying http redirect https")); + } + + if (msg.getRedirectPort() == null) { + msg.setRedirectPort(REDIRECT_PORT_DEFAULT); + } + + if (msg.getStatusCode() == null) { + msg.setStatusCode(STATUS_CODE_DEFAULT); + } + + Boolean sessionPersistence = Q.New(SystemTagVO.class).eq(SystemTagVO_.resourceType, LoadBalancerListenerVO.class.getSimpleName()) + .in(SystemTagVO_.tag, Arrays.asList("sessionPersistence::rewrite", "sessionPersistence::insert", "sessionPersistence::iphash")) + .eq(SystemTagVO_.resourceUuid, listener.getUuid()).isExists(); + if (sessionPersistence || (msg.getSessionPersistence() != null && !LoadBalancerSessionPersistence.disable.toString().equals(msg.getSessionPersistence()))) { + throw new ApiMessageInterceptionException(argerr("could not support both HTTP redirect HTTPS and session persistence at the same time")); + } + } + + /*can not modify l4's session persistence*/ + if (LoadBalancerConstants.LB_PROTOCOL_UDP.equals(listener.getProtocol()) || LoadBalancerConstants.LB_PROTOCOL_TCP.equals(listener.getProtocol())) { + if (msg.getSessionPersistence() != null || msg.getSessionIdleTimeout() != null || msg.getCookieName() != null) { + throw new ApiMessageInterceptionException(argerr("l4[%s] loadBalancer listener[%s] doesn't support modifying session persistence state", listener.getProtocol(), listener.getName())); + } + } + + /*must assign session persistence rewrite without http-tunnel*/ + if (LoadBalancerConstants.LB_PROTOCOL_HTTP.equals(listener.getProtocol())) { + Boolean httpRedirectHttps = Q.New(SystemTagVO.class).eq(SystemTagVO_.resourceType, LoadBalancerListenerVO.class.getSimpleName()) + .eq(SystemTagVO_.tag, "httpRedirectHttps::enable") + .eq(SystemTagVO_.resourceUuid, listener.getUuid()).isExists(); + if (httpRedirectHttps && (msg.getSessionPersistence() != null && !LoadBalancerSessionPersistence.disable.toString().equals(msg.getSessionPersistence()))) { + throw new ApiMessageInterceptionException(argerr("could not support both HTTP redirect HTTPS and session persistence at the same time")); + } + if (LoadBalancerSessionPersistence.rewrite.toString().equals(msg.getSessionPersistence()) && msg.getHttpMode() == null) { + Boolean httpModeTunnel = Q.New(SystemTagVO.class).eq(SystemTagVO_.resourceType, LoadBalancerListenerVO.class.getSimpleName()) + .eq(SystemTagVO_.tag, "httpMode::http-tunnel") + .eq(SystemTagVO_.resourceUuid, listener.getUuid()).isExists(); + if (httpModeTunnel) { + throw new ApiMessageInterceptionException(argerr("listener[%s] can not modifying session persistence rewrite when the http mode is http-tunnel", msg.getUuid())); + } + } + } + + /*can not assign session persistence iphash without source algorithm*/ + if (!LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_SOURCE.equals(msg.getBalancerAlgorithm()) && LoadBalancerSessionPersistence.iphash.toString().equals(msg.getSessionPersistence())) { + throw new ApiMessageInterceptionException(argerr("listener[%s] changes session persistence to iphash, it must specify source balancer algorithm", msg.getUuid())); + } + + /*can not modify session persistence without specifying balancer algorithm*/ + if (msg.getBalancerAlgorithm() == null && (msg.getSessionPersistence() != null || msg.getSessionIdleTimeout() != null || msg.getCookieName() != null)) { + throw new ApiMessageInterceptionException(argerr("listener[%s] modifies session persistence, it must specify balancer algorithm", msg.getUuid())); + } + + /*can not modify session persistence except iphash when the listener algorithm is source*/ + if (LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_SOURCE.equals(msg.getBalancerAlgorithm())) { + if ((!LoadBalancerSessionPersistence.iphash.toString().equals(msg.getSessionPersistence()) && msg.getSessionPersistence() != null) || msg.getSessionIdleTimeout() != null || msg.getCookieName() != null) { + throw new ApiMessageInterceptionException(argerr("listener[%s] %s algorithm doesn't support modifying session persistence except assigning iphash explicitly", msg.getUuid(), msg.getBalancerAlgorithm())); + } + msg.setSessionPersistence(LoadBalancerSessionPersistence.iphash.toString()); + } + + /*can not modify session persistence except disable when the listener algorithm is leastconn*/ + if (LoadBalancerConstants.BALANCE_ALGORITHM_LEAST_CONN.equals(msg.getBalancerAlgorithm())) { + if ((!LoadBalancerSessionPersistence.disable.toString().equals(msg.getSessionPersistence()) && msg.getSessionPersistence() != null) || msg.getSessionIdleTimeout() != null || msg.getCookieName() != null) { + throw new ApiMessageInterceptionException(argerr("listener[%s] %s algorithm doesn't support modifying session persistence except assigning disable explicitly", msg.getUuid(), msg.getBalancerAlgorithm())); + } + msg.setSessionPersistence(LoadBalancerSessionPersistence.disable.toString()); + } + + if (BALANCE_ALGORITHM_ROUND_ROBIN.equals(msg.getBalancerAlgorithm()) || BALANCE_ALGORITHM_WEIGHT_ROUND_ROBIN.equals(msg.getBalancerAlgorithm())) { + /*can not modify session idle timeout and cookie name without specifying session persistence*/ + if (msg.getSessionPersistence() == null && (msg.getSessionIdleTimeout() != null || msg.getCookieName() != null)) { + throw new ApiMessageInterceptionException(argerr("listener[%s] doesn't support modifying idle timeout and cookie name, it must specify session persistence", msg.getUuid())); + } + /*can not modify session idle timeout without specifying session persistence insert*/ + if (!LoadBalancerSessionPersistence.insert.toString().equals(msg.getSessionPersistence()) && msg.getSessionIdleTimeout() != null) { + throw new ApiMessageInterceptionException(argerr("listener[%s] doesn't support modifying idle timeout when the session persistence is not insert", msg.getUuid())); + } + /*can not modify session cookie name without specifying session persistence rewrite*/ + if (!LoadBalancerSessionPersistence.rewrite.toString().equals(msg.getSessionPersistence()) && msg.getCookieName() != null) { + throw new ApiMessageInterceptionException(argerr("listener[%s] doesn't support modifying cookie name when the session persistence is not rewrite", msg.getUuid())); + } + /*can not modify session persistence rewrite without modifying session cookie name*/ + if (LoadBalancerSessionPersistence.rewrite.toString().equals(msg.getSessionPersistence()) && msg.getCookieName() == null) { + throw new ApiMessageInterceptionException(argerr("listener[%s] doesn't support modifying session rewrite without modifying cookie name", msg.getUuid())); + } + if (LoadBalancerSessionPersistence.insert.toString().equals(msg.getSessionPersistence()) && msg.getSessionIdleTimeout() == null) { + msg.setSessionIdleTimeout(LoadBalancerConstants.SESSION_IDLE_TIMEOUT_DEFAULT); + } + + if (msg.getSessionPersistence() == null && msg.getBalancerAlgorithm() != null) { + msg.setSessionPersistence(LoadBalancerSessionPersistence.disable.toString()); + } + } + + Integer timeout = msg.getSessionIdleTimeout(); + if (timeout != null) { + if (timeout < LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN || timeout > LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX) { + throw new ApiMessageInterceptionException(argerr("invalid session idle timeout[%s], it must be the number between[%s~%s]", timeout, LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MIN, LoadBalancerConstants.SESSION_IDLE_TIMEOUT_MAX)); + } + } + if (msg.getHealthCheckProtocol() != null && LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCL_HTTP.equals(msg.getHealthCheckProtocol())) { if (msg.getHealthCheckMethod() == null) { msg.setHealthCheckMethod(LoadBalancerConstants.HealthCheckMothod.HEAD.toString()); @@ -928,13 +1358,72 @@ private void validate(APIChangeLoadBalancerListenerMsg msg) { } } + if (!CollectionUtils.isEmpty(msg.getHttpVersions())) { + if (!LoadBalancerConstants.LB_PROTOCOL_HTTPS.equals(listener.getProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because the listener with protocol [%s] doesn't support select http version:[%s]", + listenerVO.getProtocol(), msg.getHttpVersions())); + } + + if (hasNotSupportedHttpVersion(msg.getHttpVersions())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because the listener with protocol https only support http version:[%s]", LbSupportHttpVersion)); + } + } + + if (!StringUtils.isEmpty(msg.getTcpProxyProtocol())) { + if (!LoadBalancerConstants.LB_PROTOCOL_TCP.equals(listener.getProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because the listener with protocol tcp only support tcp proxy protocol for param")); + } + + if (!LbSupportTcpProxyProtocol.contains(msg.getTcpProxyProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because only support tcp proxy protocol %s", LbSupportTcpProxyProtocol)); + } + } + + if (!CollectionUtils.isEmpty(msg.getHttpCompressAlgos())) { + if (!LoadBalancerConstants.LB_PROTOCOL_HTTPS.equals(listener.getProtocol()) && !LB_PROTOCOL_HTTP.equals(listener.getProtocol())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because the listener with protocol [%s] doesn't support compress content", + listenerVO.getProtocol(), msg.getHttpVersions())); + } + + if (hasNotSupportedHttpCompressAlgos(msg.getHttpCompressAlgos())) { + throw new ApiMessageInterceptionException( + argerr("cloud not change the loadbalancer listener, because only support compress algos[%s]", LbSupportHttpCompressAlgos)); + } + } + msg.setLoadBalancerUuid(listenerVO.getLoadBalancerUuid()); bus.makeTargetServiceIdByResourceUuid(msg, LoadBalancerConstants.SERVICE_ID, listenerVO.getLoadBalancerUuid()); } + private boolean hasNotSupportedHttpVersion(List httpVersions) { + if (CollectionUtils.isEmpty(httpVersions)) { + return false; + } + + return !new HashSet<>(LbSupportHttpVersion).containsAll(httpVersions); + } + + private boolean hasNotSupportedHttpCompressAlgos(List httpCompressAlgos) { + if (CollectionUtils.isEmpty(httpCompressAlgos)) { + return false; + } + + return !new HashSet<>(LbSupportHttpCompressAlgos).containsAll(httpCompressAlgos); + } + private void validate(APICreateLoadBalancerServerGroupMsg msg){ isExist(msg.getLoadBalancerUuid()); + if (msg.getIpVersion() == null) { + msg.setIpVersion(IPv6Constants.IPv4); + } else if (!msg.getIpVersion().equals(IPv6Constants.IPv4) && !msg.getIpVersion().equals(IPv6Constants.IPv6)) { + throw new ApiMessageInterceptionException(argerr("invalid ip version[%s], it must be %s or %s", msg.getIpVersion(), IPv6Constants.IPv4, IPv6Constants.IPv6)); + } } private void validate(APIDeleteLoadBalancerServerGroupMsg msg){ @@ -1082,7 +1571,7 @@ private void validate(APIAddBackendServerToServerGroupMsg msg){ List serverIps = new ArrayList<>(); if(servers != null && !servers.isEmpty()){ for(Map server:servers){ - if(server.containsKey("ipAddress") && NetworkUtils.isIpv4Address(server.get("ipAddress"))){ + if(server.containsKey("ipAddress") && NetworkUtils.isIpAddress(server.get("ipAddress"))){ if(usedIps.contains(server.get("ipAddress"))){ throw new ApiMessageInterceptionException(operr("could not add backend server ip to serverGroup [uuid:%s], because ip [ipAddress:%s] is repeated",msg.getServerGroupUuid(),server.get("ipAddress"))); } @@ -1230,9 +1719,47 @@ private void validate(APIAddServerGroupToLoadBalancerListenerMsg msg){ .eq(LoadBalancerServerGroupVO_.uuid,msg.getServerGroupUuid()) .findValue(); msg.setLoadBalancerUuid(loadBalancerUuid); + + /* until 5.3.0, udp lb only has 2 use case: ipv4 vip --> ipv4 backend + + * ipv6 vip --> ipv6 backend */ + LoadBalancerListenerVO listenerVO = dbf.findByUuid(msg.getlistenerUuid(), + LoadBalancerListenerVO.class); + LoadBalancerVO lbVO = dbf.findByUuid(loadBalancerUuid, LoadBalancerVO.class); + LoadBalancerServerGroupVO groupVO = dbf.findByUuid(msg.getServerGroupUuid(), LoadBalancerServerGroupVO.class); + if (listenerVO.getProtocol().equals(LB_PROTOCOL_UDP)) { + if (!StringUtils.isEmpty(lbVO.getVipUuid()) && + !StringUtils.isEmpty(lbVO.getIpv6VipUuid())) { + throw new ApiMessageInterceptionException(operr( + "could not add server group[uuid:%s} to listener [uuid:%s], " + + "because udp listener can not has both ipv4 and ipv6 vip", + msg.getServerGroupUuid(),msg.getlistenerUuid())); + } + + if (groupVO.getIpVersion() == IPv6Constants.IPv4 && !StringUtils.isEmpty(lbVO.getIpv6VipUuid())) { + throw new ApiMessageInterceptionException(operr( + "could not add server group[uuid:%s} to listener [uuid:%s], " + + "because udp listener can not map ipv6 to ipv4 backend", + msg.getServerGroupUuid(),msg.getlistenerUuid())); + } + + if (groupVO.getIpVersion() == IPv6Constants.IPv6 && !StringUtils.isEmpty(lbVO.getVipUuid())) { + throw new ApiMessageInterceptionException(operr( + "could not add server group[uuid:%s} to listener [uuid:%s], " + + "because udp listener can not map ipv4 to ipv6 backend", + msg.getServerGroupUuid(),msg.getlistenerUuid())); + } + } + } private void validate(APIRemoveServerGroupFromLoadBalancerListenerMsg msg){ + Boolean httpRedirectHttps = Q.New(SystemTagVO.class).eq(SystemTagVO_.resourceType, LoadBalancerListenerVO.class.getSimpleName()) + .eq(SystemTagVO_.tag, "httpRedirectHttps::enable") + .eq(SystemTagVO_.resourceUuid, msg.getListenerUuid()).isExists(); + if (httpRedirectHttps) { + throw new ApiMessageInterceptionException(argerr("could not remove server groups[uuid:%s} from listener [uuid:%s] because it has enable HTTP redirect HTTPS", msg.getServerGroupUuid(), msg.getListenerUuid())); + } + List existingRefs = Q.New(LoadBalancerListenerServerGroupRefVO.class) .eq(LoadBalancerListenerServerGroupRefVO_.serverGroupUuid, msg.getServerGroupUuid()) diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBackend.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBackend.java index f8b53d1feaf..561226ca769 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBackend.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBackend.java @@ -1,10 +1,9 @@ package org.zstack.network.service.lb; import org.zstack.header.core.Completion; -import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.vm.VmNicInventory; import org.zstack.header.vm.VmNicVO; -import org.zstack.network.service.vip.VipInventory; +import org.zstack.network.service.vip.VipVO; import java.util.List; @@ -30,5 +29,12 @@ public interface LoadBalancerBackend { String getNetworkServiceProviderType(); - List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, LoadBalancerServerGroupVO groupVO); + List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, LoadBalancerServerGroupVO groupVO, int ipVersion); + + void detachVipFromLoadBalancer(LoadBalancerStruct struct, VipVO vip, Completion completion); + + void attachVipToLoadBalancer(LoadBalancerStruct struct, VipVO vip, Completion completion); + + //the method should put the service layer, but ha not abstract the business layer yet + boolean canDetachVipFromLb(LoadBalancerStruct struct, VipVO vip); } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java index fd1ab44408b..d8b43fa7464 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerBase.java @@ -1,10 +1,12 @@ package org.zstack.network.service.lb; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cascade.CascadeConstant; import org.zstack.core.cascade.CascadeFacade; import org.zstack.core.cloudbus.CloudBus; @@ -17,11 +19,14 @@ import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.NopeCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; @@ -36,9 +41,7 @@ import org.zstack.header.vo.ResourceVO; import org.zstack.identity.Account; import org.zstack.network.l3.L3NetworkManager; -import org.zstack.network.service.vip.ModifyVipAttributesStruct; -import org.zstack.network.service.vip.Vip; -import org.zstack.network.service.vip.VipVO; +import org.zstack.network.service.vip.*; import org.zstack.tag.PatternedSystemTag; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; @@ -46,16 +49,17 @@ import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; -import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; import javax.persistence.TypedQuery; import java.util.*; import java.util.stream.Collectors; import static java.util.Arrays.asList; +import static java.util.Arrays.stream; import static org.zstack.core.Platform.*; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -85,12 +89,12 @@ public class LoadBalancerBase { @Autowired private PluginRegistry pluginRgty; - public static String getSyncId(String vipUuid) { - return String.format("operate-lb-with-vip-%s", vipUuid); + public static String getSyncId(String lbUuid) { + return String.format("operate-lb-%s", lbUuid); } private String getSyncId() { - return getSyncId(self.getVipUuid()); + return getSyncId(self.getUuid()); } private LoadBalancerVO self; @@ -137,6 +141,10 @@ private void handleLocalMessage(Message msg) { handle((LoadBalancerGetPeerL3NetworksMsg) msg); } else if (msg instanceof RemoveAccessControlListFromLoadBalancerMsg) { handle((RemoveAccessControlListFromLoadBalancerMsg)msg); + } else if (msg instanceof AttachVipToLoadBalancerMsg) { + handle((AttachVipToLoadBalancerMsg)msg); + } else if (msg instanceof DetachVipFromLoadBalancerMsg) { + handle((DetachVipFromLoadBalancerMsg)msg); } else { bus.dealWithUnknownMessage(msg); } @@ -606,6 +614,8 @@ private void handleApiMessage(APIMessage msg) { handle((APIGetCandidateVmNicsForLoadBalancerServerGroupMsg) msg); } else if(msg instanceof APIChangeLoadBalancerBackendServerMsg){ handle((APIChangeLoadBalancerBackendServerMsg) msg); + } else if (msg instanceof APIAttachVipToLoadBalancerMsg) { + handle((APIAttachVipToLoadBalancerMsg)msg); } else { bus.dealWithUnknownMessage(msg); } @@ -614,11 +624,13 @@ private void handleApiMessage(APIMessage msg) { private void handle(APIGetCandidateVmNicsForLoadBalancerServerGroupMsg msg) { APIGetCandidateVmNicsForLoadBalancerServerGroupReply reply = new APIGetCandidateVmNicsForLoadBalancerServerGroupReply(); LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(self.getType().toString()); + int ipVersion = msg.getIpVersion(); LoadBalancerServerGroupVO groupVO = null; if (msg.getServergroupUuid() != null) { groupVO = dbf.findByUuid(msg.getServergroupUuid(), LoadBalancerServerGroupVO.class); + ipVersion = groupVO.getIpVersion(); } - List nicVOS = f.getAttachableVmNicsForServerGroup(self, groupVO); + List nicVOS = f.getAttachableVmNicsForServerGroup(self, groupVO, ipVersion); reply.setInventories(VmNicInventory.valueOf(nicVOS)); bus.reply(msg, reply); } @@ -664,7 +676,7 @@ private void handle(final LoadBalancerGetPeerL3NetworksMsg msg) { List guestNetworks = q.getResultList(); List ret = L3NetworkInventory.valueOf(guestNetworks); - if (ret != null && !ret.isEmpty()) { + if (!ret.isEmpty()) { for (GetPeerL3NetworksForLoadBalancerExtensionPoint extp : pluginRgty.getExtensionList(GetPeerL3NetworksForLoadBalancerExtensionPoint.class)) { ret = extp.getPeerL3NetworksForLoadBalancer(self.getUuid(), ret); } @@ -739,6 +751,264 @@ public String getName() { }); } + private void handle(AttachVipToLoadBalancerMsg msg) { + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSyncId(); + } + + @Override + public void run(SyncTaskChain chain) { + AttachVipToLoadBalancerReply reply = new AttachVipToLoadBalancerReply(); + + VipVO vipVO = Q.New(VipVO.class).eq(VipVO_.uuid, msg.getVipUuid()).find(); + if (StringUtils.isEmpty(vipVO.getIp())) { + throw new OperationFailureException(operr("fail to attach vip to lb , because vip[%s] has no ip", vipVO.getUuid())); + } + + if (NetworkUtils.isIpv4Address(vipVO.getIp())) { + if (!StringUtils.isEmpty(self.getVipUuid())) { + throw new OperationFailureException(operr("fail to attach ipv4 vip to lb , because lb[%s] has ipv4 vip[%s]", self.getUuid(), self.getVipUuid())); + } + self.setVipUuid(vipVO.getUuid()); + } else { + if (!StringUtils.isEmpty(self.getIpv6VipUuid())) { + throw new OperationFailureException(operr("fail to attach ipv6 vip to lb , because lb[%s] has ipv6 vip[%s]", self.getUuid(), self.getVipUuid())); + } + self.setIpv6VipUuid(vipVO.getUuid()); + } + LoadBalancerBackend bkd = getBackend(); + if (bkd == null) { + ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); + LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(self.getType().toString()); + vipStruct.setUseFor(f.getNetworkServiceType()); + vipStruct.setServiceUuid(self.getUuid()); + + Vip v = new Vip(msg.getVipUuid()); + v.setStruct(vipStruct); + + v.acquire(new Completion(msg) { + @Override + public void success() { + dbf.update(self); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + return; + } + + LoadBalancerStruct lbStruct = lbMgr.makeStruct(self); + + bkd.attachVipToLoadBalancer(lbStruct, vipVO, new Completion(chain) { + @Override + public void success() { + dbf.update(self); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } + + @Override + public String getName() { + return "attach-vip-to-lb"; + } + }); + } + + private void handle(DetachVipFromLoadBalancerMsg msg) { + final DetachVipFromLoadBalancerReply reply = new DetachVipFromLoadBalancerReply(); + LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(self.getType().toString()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSyncId(); + } + + @Override + public void run(SyncTaskChain chain) { + VipVO vipVO = Q.New(VipVO.class).eq(VipVO_.uuid, msg.getVipUuid()).find(); + + LoadBalancerStruct lbStruct = lbMgr.makeStruct(self); + + LoadBalancerBackend bkd = getBackend(); + + if (bkd != null) { + if (!bkd.canDetachVipFromLb(lbStruct, vipVO)) { + reply.setError(operr("cloud not delete vip[%s]", vipVO.getUuid())); + bus.reply(msg, reply); + chain.next(); + return; + } + } + + if (NetworkUtils.isIpv4Address(vipVO.getIp())) { + if (StringUtils.isEmpty(self.getVipUuid())) { + bus.reply(msg, reply); + chain.next(); + return; + } + self.setVipUuid(null); + lbStruct.setVip(null); + lbStruct.getLb().setVipUuid(null); + } else { + if (StringUtils.isEmpty(self.getIpv6VipUuid())) { + bus.reply(msg, reply); + chain.next(); + return; + } + self.setIpv6VipUuid(null); + lbStruct.setIpv6Vip(null); + lbStruct.getLb().setIpv6VipUuid(null); + } + + if (bkd == null) { + ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); + struct.setUseFor(f.getNetworkServiceType()); + struct.setServiceUuid(self.getUuid()); + + Vip v = new Vip(msg.getVipUuid()); + v.setStruct(struct); + v.release(new Completion(msg) { + @Override + public void success() { + dbf.update(self); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + return; + } + + FlowChain flowChain = new SimpleFlowChain(); + flowChain.setName("detach-vip-from-lb-and-release-vip"); + flowChain.then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + String __name__ = "detach-vip-from-lb"; + bkd.detachVipFromLoadBalancer(lbStruct, vipVO, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "release-vip"; + @Transactional(readOnly = true) + private List getGuestNetworkUuids() { + List vmNicUuids = new ArrayList<>(); + List groupVOS = Q.New(LoadBalancerServerGroupVO.class) + .eq(LoadBalancerServerGroupVO_.loadBalancerUuid, self.getUuid()).list(); + for (LoadBalancerServerGroupVO groupVO : groupVOS) { + vmNicUuids.addAll(groupVO.getLoadBalancerServerGroupVmNicRefs().stream() + .map(LoadBalancerServerGroupVmNicRefVO::getVmNicUuid).collect(Collectors.toList())); + } + if (vmNicUuids.isEmpty()) { + return new ArrayList<>(); + } + + List l3Uuids = Q.New(VmNicVO.class).select(VmNicVO_.l3NetworkUuid) + .in(VmNicVO_.uuid, vmNicUuids).listValues(); + return l3Uuids.stream().distinct().collect(Collectors.toList()); + } + @Override + public void run(FlowTrigger trigger, Map data) { + ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); + struct.setUseFor(f.getNetworkServiceType()); + struct.setServiceUuid(self.getUuid()); + if (self.getProviderType() != null) { + /* release vip peer networks */ + struct.setServiceProvider(self.getProviderType()); + List guestNetworkUuids = getGuestNetworkUuids(); + if (!guestNetworkUuids.isEmpty()) { + struct.setPeerL3NetworkUuids(guestNetworkUuids); + } + } + Vip v = new Vip(msg.getVipUuid()); + v.setStruct(struct); + v.release(new Completion(trigger) { + @Override + public void success() { + data.put("releaseVipResult", true); + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + //TODO add GC + data.put("releaseVipResult", false); + logger.warn(errorCode.toString()); + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(chain) { + @Override + public void handle(Map data) { + if (msg.getVipUuid().equals(self.getVipUuid())) { + self.setVipUuid(null); + } else if (msg.getVipUuid().equals(self.getIpv6VipUuid())) { + self.setIpv6VipUuid(null); + } + dbf.update(self); + bus.reply(msg, reply); + chain.next(); + } + }).error(new FlowErrorHandler(chain) { + @Override + public void handle(ErrorCode errCode, Map data) { + if (msg.isHardDeleteDb()) { + dbf.update(self); + //todo:add gc + + reply.setError(errCode); + bus.reply(msg, reply); + chain.next(); + return; + } + reply.setError(errCode); + bus.reply(msg, reply); + chain.next(); + } + }).start(); + } + + @Override + public String getName() { + return "detach-vip-to-lb"; + } + }); + } + private void handle(APIGetCandidateVmNicsForLoadBalancerMsg msg) { APIGetCandidateVmNicsForLoadBalancerReply reply = new APIGetCandidateVmNicsForLoadBalancerReply(); @@ -766,17 +1036,13 @@ protected void scripts() { .list(); } - /* TODO: lb only support ipv4 */ - LoadBalancerVO lbVO = dbf.findByUuid(msg.getLoadBalancerUuid(), LoadBalancerVO.class); - VipVO vipVO = dbf.findByUuid(lbVO.getVipUuid(), VipVO.class); - List nicInvs; - if (IPv6NetworkUtils.isIpv6Address(vipVO.getIp())) { - nicInvs = new ArrayList<>(); - } else { - nicInvs = l3Mgr.filterVmNicByIpVersion(VmNicInventory.valueOf(nics), IPv6Constants.IPv4); - } + /* filter out nics already attached to listener */ + LoadBalancerListenerVO listenerVO = dbf.findByUuid(msg.getListenerUuid(), LoadBalancerListenerVO.class); + nics = nics.stream() + .filter(nic -> !listenerVO.getAttachedVmNics().contains(nic.getUuid())) + .collect(Collectors.toList()); - reply.setInventories(callGetCandidateVmNicsForLoadBalancerExtensionPoint(msg, nicInvs)); + reply.setInventories(callGetCandidateVmNicsForLoadBalancerExtensionPoint(msg, VmNicInventory.valueOf(nics))); } }.execute(); @@ -970,30 +1236,47 @@ private List getGuestNetworkUuids() { return l3Uuids.stream().distinct().collect(Collectors.toList()); } + private final List releasedVipUuids = Collections.synchronizedList(new ArrayList()); + @Override public void run(FlowTrigger trigger, Map data) { - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(f.getNetworkServiceType()); - struct.setServiceUuid(self.getUuid()); - if (self.getProviderType() != null) { - /* release vip peer networks */ - struct.setServiceProvider(self.getProviderType()); - List guestNetworkUuids = getGuestNetworkUuids(); - if (!guestNetworkUuids.isEmpty()) { - struct.setPeerL3NetworkUuids(guestNetworkUuids); - } - } - Vip v = new Vip(self.getVipUuid()); - v.setStruct(struct); - v.release(new Completion(trigger) { - @Override - public void success() { - trigger.next(); + data.put("releasedVipUuids", releasedVipUuids); + new While<>(self.getVipUuids()).step((vipUuid, whileCompletion) -> { + ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); + struct.setUseFor(f.getNetworkServiceType()); + struct.setServiceUuid(self.getUuid()); + if (self.getProviderType() != null) { + /* release vip peer networks */ + struct.setServiceProvider(self.getProviderType()); + List guestNetworkUuids = getGuestNetworkUuids(); + if (!guestNetworkUuids.isEmpty()) { + struct.setPeerL3NetworkUuids(guestNetworkUuids); + } } + Vip v = new Vip(vipUuid); + v.setStruct(struct); + v.release(new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + releasedVipUuids.add(vipUuid); + } + @Override + public void fail(ErrorCode errorCode) { + //TODO add GC + logger.warn(errorCode.toString()); + whileCompletion.done(); + } + }); + }, 2).run(new WhileDoneCompletion(trigger) { @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + public void done(ErrorCodeList errorCodeList) { + if (!CollectionUtils.isEmpty(errorCodeList.getCauses())) { + trigger.fail(errorCodeList.getCauses().get(0)); + return; + } + trigger.next(); } }); } @@ -1042,6 +1325,14 @@ protected void scripts() { error(new FlowErrorHandler(completion) { @Override public void handle(ErrorCode errCode, Map data) { + // if release vip, it will delete the vip ref vo + List releasedVipUuids = (List) data.get("releasedVipUuids"); + if (releasedVipUuids != null && !releasedVipUuids.isEmpty()) { + for (String vip : releasedVipUuids) { + self.deleteVip(vip); + } + dbf.update(self); + } completion.fail(errCode); } }); @@ -1196,9 +1487,9 @@ private void removeNics(List serverGroupUuids, List listenerUuid } LoadBalancerBackend bkd = getBackend(); - if( (vmNicUuids.isEmpty() && serverIps.isEmpty() ) || bkd == null){ + if ((vmNicUuids != null && vmNicUuids.isEmpty() && serverIps.isEmpty()) || bkd == null) { completion.success(); - }else { + } else { bkd.removeVmNics(removeNicStruct(serverGroupUuids, listenerUuids, vmNicUuids, serverIps), nics, completion); } } @@ -1277,7 +1568,8 @@ public void run(final SyncTaskChain chain) { groupVO.setAccountUuid(accountUuid); groupVO.setDescription(String.format("default server group for load balancer listener %s", listenerVO.getName())); groupVO.setLoadBalancerUuid(listenerVO.getLoadBalancerUuid()); - groupVO.setName(String.format("default-server-group-%s", listenerVO.getName())); + groupVO.setName(String.format("default-server-group-%s-%s", listenerVO.getName(), listenerVO.getUuid().substring(0, 5))); + groupVO.setIpVersion(IPv6Constants.IPv4); dbf.persist(groupVO); listenerVO.setServerGroupUuid(groupVO.getUuid()); @@ -1292,13 +1584,21 @@ public void run(final SyncTaskChain chain) { } List refs = new ArrayList<>(); - Map weight = new LoadBalancerWeightOperator().getWeight(msg.getSystemTags()); + LoadBalancerWeightOperator ops = new LoadBalancerWeightOperator(); + Map weight = ops.getWeight(msg.getSystemTags()); + Map backendNicIpversion = ops.getBackendNicIpversion(msg.getSystemTags()); for (String nicUuid : msg.getVmNicUuids()) { LoadBalancerServerGroupVmNicRefVO ref = new LoadBalancerServerGroupVmNicRefVO(); ref.setServerGroupUuid(groupVO.getUuid()); ref.setVmNicUuid(nicUuid); ref.setStatus(LoadBalancerVmNicStatus.Active); + if (backendNicIpversion.get(nicUuid) != null) { + ref.setIpVersion(backendNicIpversion.get(nicUuid)); + } else { + ref.setIpVersion(LoadBalancerConstants.BALANCER_BACKEND_NIC_IPVERSION_DEFAULT); + } + if (weight.get(nicUuid) != null) { ref.setWeight(weight.get(nicUuid)); } else { @@ -1928,6 +2228,30 @@ public void run(SyncTaskChain chain) { updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.BALANCER_ALGORITHM, msg.getUuid(), LoadBalancerSystemTags.BALANCER_ALGORITHM_TOKEN, msg.getBalancerAlgorithm()); } + if (msg.getSessionPersistence() != null) { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.SESSION_PERSISTENCE, msg.getUuid(), LoadBalancerSystemTags.SESSION_PERSISTENCE_TOKEN, msg.getSessionPersistence()); + } + + if (msg.getSessionIdleTimeout() != null) { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT, msg.getUuid(), LoadBalancerSystemTags.SESSION_IDLE_TIMEOUT_TOKEN, msg.getSessionIdleTimeout()); + } + + if (msg.getCookieName() != null) { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.COOKIE_NAME, msg.getUuid(), LoadBalancerSystemTags.COOKIE_NAME_TOKEN, msg.getCookieName()); + } + + if (msg.getHttpRedirectHttps() != null) { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.HTTP_REDIRECT_HTTPS, msg.getUuid(), LoadBalancerSystemTags.HTTP_REDIRECT_HTTPS_TOKEN, msg.getHttpRedirectHttps()); + } + + if (msg.getRedirectPort() != null) { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.REDIRECT_PORT, msg.getUuid(), LoadBalancerSystemTags.REDIRECT_PORT_TOKEN, msg.getRedirectPort()); + } + + if (msg.getStatusCode() != null) { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.STATUS_CODE, msg.getUuid(), LoadBalancerSystemTags.STATUS_CODE_TOKEN, msg.getStatusCode()); + } + if (msg.getConnectionIdleTimeout() != null) { updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.CONNECTION_IDLE_TIMEOUT, msg.getUuid(), LoadBalancerSystemTags.CONNECTION_IDLE_TIMEOUT_TOKEN, msg.getConnectionIdleTimeout()); } @@ -1961,6 +2285,27 @@ public void run(SyncTaskChain chain) { updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.MAX_CONNECTION, msg.getUuid(), LoadBalancerSystemTags.MAX_CONNECTION_TOKEN, msg.getMaxConnection()); } + if (!CollectionUtils.isEmpty(msg.getHttpVersions())) { + String httpVersions = String.join(",", msg.getHttpVersions()); + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.HTTP_VERSIONS, msg.getUuid(), LoadBalancerSystemTags.HTTP_VERSIONS_TOKEN, httpVersions); + } + + if (!StringUtils.isEmpty(msg.getTcpProxyProtocol())) { + if (msg.getTcpProxyProtocol().equals(LoadBalancerConstants.DisableLbSupportTcpProxyProtocol)) { + LoadBalancerSystemTags.TCP_PROXYPROTOCOL.delete(msg.getUuid()); + } else { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.TCP_PROXYPROTOCOL, msg.getUuid(), LoadBalancerSystemTags.TCP_PROXYPROTOCOL_TOKEN, msg.getTcpProxyProtocol()); + } + } + + if (!CollectionUtils.isEmpty(msg.getHttpCompressAlgos())) { + if (msg.getHttpCompressAlgos().contains(LoadBalancerConstants.DisableLbSupportHttpCompressAlgos)) { + LoadBalancerSystemTags.HTTP_COMPRESS_ALGOS.delete(msg.getUuid()); + } else { + updateLoadBalancerListenerSystemTag(LoadBalancerSystemTags.HTTP_COMPRESS_ALGOS, msg.getUuid(), LoadBalancerSystemTags.HTTP_COMPRESS_ALGOS_TOKEN, String.join(" ", msg.getHttpCompressAlgos())); + } + } + String[] ts = getHeathCheckTarget(msg.getUuid()); if (msg.getHealthCheckProtocol() != null && !msg.getHealthCheckProtocol().equals(ts[0])) { if (LoadBalancerConstants.HEALTH_CHECK_TARGET_PROTOCL_TCP.equals(ts[0]) && @@ -2015,6 +2360,8 @@ public void run(SyncTaskChain chain) { } } + final String oldAclStatus = LoadBalancerSystemTags.BALANCER_ACL.getTokenByResourceUuid( + msg.getUuid(), LoadBalancerSystemTags.BALANCER_ACL_TOKEN); if (msg.getAclStatus() != null) { if (LoadBalancerSystemTags.BALANCER_ACL.hasTag(msg.getUuid())) { LoadBalancerSystemTags.BALANCER_ACL.update(msg.getUuid(), @@ -2042,15 +2389,26 @@ public void run(SyncTaskChain chain) { boolean refresh = isListenerNeedRefresh(lblVo, null); if (refresh) { - RefreshLoadBalancerMsg msg = new RefreshLoadBalancerMsg(); - msg.setUuid(lblVo.getLoadBalancerUuid()); - bus.makeLocalServiceId(msg, LoadBalancerConstants.SERVICE_ID); - bus.send(msg, new CloudBusCallBack(chain) { + RefreshLoadBalancerMsg rmsg = new RefreshLoadBalancerMsg(); + rmsg.setUuid(lblVo.getLoadBalancerUuid()); + bus.makeLocalServiceId(rmsg, LoadBalancerConstants.SERVICE_ID); + bus.send(rmsg, new CloudBusCallBack(chain) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { logger.warn(String.format( "update listener [uuid:%s] failed", lblVo.getUuid())); evt.setError(reply.getError()); + if (msg.getAclStatus() != null) { + logger.warn(String.format( "rollback acl status for listener [uuid:%s]", msg.getUuid())); + if (oldAclStatus != null) { + LoadBalancerSystemTags.BALANCER_ACL.update(msg.getUuid(), + LoadBalancerSystemTags.BALANCER_ACL.instantiateTag(map( + e(LoadBalancerSystemTags.BALANCER_ACL_TOKEN, oldAclStatus) + ))); + } else { + LoadBalancerSystemTags.BALANCER_ACL.delete(msg.getUuid()); + } + } } else { evt.setInventory(LoadBalancerListenerInventory.valueOf(lblVo)); } @@ -2234,6 +2592,7 @@ private void createLoadBalanacerServerGroup(final APICreateLoadBalancerServerGro vo.setName(msg.getName()); vo.setDescription(msg.getDescription()); vo.setLoadBalancerUuid(msg.getLoadBalancerUuid()); + vo.setIpVersion(msg.getIpVersion()); vo.setAccountUuid(msg.getSession().getAccountUuid()); vo.setUuid(msg.getResourceUuid() == null ? Platform.getUuid() : msg.getResourceUuid()); vo = dbf.persistAndRefresh(vo); @@ -2396,6 +2755,12 @@ public void run(FlowTrigger trigger, Map data) { } else { refVO.setWeight(LoadBalancerConstants.BALANCER_WEIGHT_default); } + if (vmNic.containsKey("ipVersion")) { + Integer ipVersion = Integer.valueOf(vmNic.get("ipVersion")); + refVO.setIpVersion(ipVersion); + } else { + refVO.setIpVersion(LoadBalancerConstants.BALANCER_BACKEND_NIC_IPVERSION_DEFAULT); + } refVO.setStatus(LoadBalancerVmNicStatus.Active); refVOs.add(refVO); } @@ -2472,7 +2837,7 @@ public void run(FlowTrigger trigger, Map data) { if(server.containsKey("weight")){ struct.getServerIpWeight().put(server.get("ipAddress"), Long.valueOf(server.get("weight"))); }else{ - struct.getVmNicWeight().put(server.get("ipAddress"), LoadBalancerConstants.BALANCER_WEIGHT_default); + struct.getServerIpWeight().put(server.get("ipAddress"), LoadBalancerConstants.BALANCER_WEIGHT_default); } } } @@ -2747,7 +3112,7 @@ public void run(SyncTaskChain chain) { .find(); if (vmNic.containsKey("weight")) { Long vmNicWeight = Long.valueOf(vmNic.get("weight")); - if (vmNicWeight != vmNicRefVO.getWeight()) { + if (!vmNicWeight.equals(vmNicRefVO.getWeight())) { vmNicRefVO.setWeight(vmNicWeight); dbf.update(vmNicRefVO); canRefresh = true; @@ -2765,7 +3130,7 @@ public void run(SyncTaskChain chain) { .find(); if (server.containsKey("weight")) { Long serverIpWeight = Long.valueOf(server.get("weight")); - if(serverIpWeight != serverIpVO.getWeight()){ + if(!serverIpWeight.equals(serverIpVO.getWeight())){ serverIpVO.setWeight(serverIpWeight); dbf.update(serverIpVO); canRefresh = true; @@ -2810,4 +3175,25 @@ public String getName() { } + private void handle(APIAttachVipToLoadBalancerMsg msg) { + APIAttachVipToLoadBalancerEvent event = new APIAttachVipToLoadBalancerEvent(msg.getId()); + AttachVipToLoadBalancerMsg amsg = new AttachVipToLoadBalancerMsg(); + amsg.setUuid(msg.getLoadBalancerUuid()); + amsg.setVipUuid(msg.getVipUuid()); + bus.makeLocalServiceId(amsg, LoadBalancerConstants.SERVICE_ID); + + bus.send(amsg, new CloudBusCallBack(amsg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + event.setError(reply.getError().getRootCause()); + bus.publish(event); + return; + } + LoadBalancerVO lbVO = dbf.reload(self); + event.setInventory(LoadBalancerInventory.valueOf(lbVO)); + bus.publish(event); + } + }); + } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerCascadeExtension.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerCascadeExtension.java index 9fa57671069..74acb10f15d 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerCascadeExtension.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerCascadeExtension.java @@ -1,5 +1,6 @@ package org.zstack.network.service.lb; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.asyncbatch.While; @@ -21,6 +22,8 @@ import org.zstack.header.identity.AccountInventory; import org.zstack.header.identity.AccountVO; import org.zstack.header.message.MessageReply; +import org.zstack.network.service.vip.ModifyVipAttributesStruct; +import org.zstack.network.service.vip.Vip; import org.zstack.network.service.vip.VipInventory; import org.zstack.network.service.vip.VipVO; import org.zstack.utils.CollectionUtils; @@ -29,10 +32,7 @@ import org.zstack.utils.logging.CLogger; import javax.persistence.TypedQuery; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.Callable; import java.util.stream.Collectors; @@ -46,7 +46,8 @@ public class LoadBalancerCascadeExtension extends AbstractAsyncCascadeExtension private DatabaseFacade dbf; @Autowired private CloudBus bus; - + @Autowired + private LoadBalancerManager lbMgr; public void asyncCascade(CascadeAction action, Completion completion) { if (action.isActionCode(CascadeConstant.DELETION_CHECK_CODE)) { handleDeletionCheck(action, completion); @@ -74,31 +75,50 @@ private void handleDeletion(CascadeAction action, final Completion completion) { completion.success(); return; } - - LoadBalancerListenerVO listenerVO = Q.New(LoadBalancerListenerVO.class).eq(LoadBalancerListenerVO_.uuid, refVOS.get(0).getListenerUuid()).find(); - if (listenerVO.getLoadBalancerUuid() == null) { + List refList = refVOS.stream().map(LoadBalancerListenerACLRefVO::getListenerUuid).collect(Collectors.toList()); + List listenerVOList = Q.New(LoadBalancerListenerVO.class).in(LoadBalancerListenerVO_.uuid, refList).list(); + if (listenerVOList.isEmpty()) { completion.success(); return; } + List msgs = new ArrayList<>(); + listenerVOList.forEach(listenerVO -> { + if (listenerVO.getLoadBalancerUuid() == null) { + return; + } + RemoveAccessControlListFromLoadBalancerMsg msg = new RemoveAccessControlListFromLoadBalancerMsg(); + msg.setLoadBalancerUuid(listenerVO.getLoadBalancerUuid()); + msg.setAclUuids(Collections.singletonList(acl.getUuid())); + msg.setServerGroupUuids(refVOS.stream().filter(ref -> ref.getServerGroupUuid() != null).map(LoadBalancerListenerACLRefVO::getServerGroupUuid).collect(Collectors.toList())); + msg.setListenerUuid(listenerVO.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, LoadBalancerConstants.SERVICE_ID, listenerVO.getLoadBalancerUuid()); + msgs.add(msg); + }); - RemoveAccessControlListFromLoadBalancerMsg msg = new RemoveAccessControlListFromLoadBalancerMsg(); - msg.setLoadBalancerUuid(listenerVO.getLoadBalancerUuid()); - msg.setAclUuids(Collections.singletonList(acl.getUuid())); - msg.setServerGroupUuids(refVOS.stream().filter(ref -> ref.getServerGroupUuid() != null).map(LoadBalancerListenerACLRefVO::getServerGroupUuid).collect(Collectors.toList())); - msg.setListenerUuid(listenerVO.getUuid()); - bus.makeTargetServiceIdByResourceUuid(msg, LoadBalancerConstants.SERVICE_ID, listenerVO.getLoadBalancerUuid()); - - bus.send(msg, new CloudBusCallBack(msg) { + List errors = new ArrayList<>(); + new While<>(msgs).each((msg, coml) -> { + bus.send(msg, new CloudBusCallBack(coml) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("Failed to delete ACL[uuids:%s] from listener[uuid:%s] of load balancer[uuid:%s], error: %s", + msg.getAclUuids(), msg.getListenerUuid(), msg.getLoadBalancerUuid(), reply.getError())); + errors.add(reply.getError()); + } + coml.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - completion.fail(reply.getError()); - return; + public void done(ErrorCodeList errorCodeList) { + if (!errors.isEmpty()) { + errorCodeList.getCauses().addAll(errors); + completion.fail(errorCodeList); + } else { + completion.success(); } - completion.success(); } }); - return; } @@ -106,6 +126,26 @@ public void run(MessageReply reply) { FlowChain chain = new SimpleFlowChain(); chain.setName("delete-lb-and-lb-certs"); chain.then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + Map vipLoadBalancerMap = vipDetachLoadBalancerMapFromAction(action); + if (vipLoadBalancerMap == null || vipLoadBalancerMap.isEmpty()) { + trigger.next(); + return; + } + releaseOnlyVipOfLb(vipLoadBalancerMap, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { @Override public void run(FlowTrigger trigger, Map data) { final List lbs = loadBalancerFromAction(action); @@ -289,6 +329,7 @@ public List call() { return LoadBalancerInventory.valueOf(vos); } } else if (VipVO.class.getSimpleName().equals(action.getParentIssuer())) { + final List vipUuids = CollectionUtils.transformToList((List) action.getParentIssuerContext(), new Function() { @Override public String call(VipInventory arg) { @@ -304,13 +345,25 @@ public String call(VipInventory arg) { @Override @Transactional(readOnly = true) public List call() { - String sql = "select d from LoadBalancerVO d where d.vipUuid in (:vipUuids)"; + String sql = "select d from LoadBalancerVO d where d.vipUuid in (:vipUuids) or d.ipv6VipUuid in (:vipUuids)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, LoadBalancerVO.class); q.setParameter("vipUuids", vipUuids); return q.getResultList(); } }.call(); + // if delete l3, will delete all vip of l3, and delete lb + // if delete iprange or delete vip, detach vip from lb ib lb has two vip + Iterator iterator = vos.iterator(); + while(iterator.hasNext()){ + LoadBalancerVO loadBalancerVO = iterator.next(); + if (!StringUtils.isEmpty(loadBalancerVO.getVipUuid()) && !StringUtils.isEmpty(loadBalancerVO.getIpv6VipUuid())) { + if (!(vipUuids.contains(loadBalancerVO.getVipUuid()) && vipUuids.contains(loadBalancerVO.getIpv6VipUuid()))) { + iterator.remove(); + } + } + } + if (!vos.isEmpty()) { return LoadBalancerInventory.valueOf(vos); } @@ -318,4 +371,87 @@ public List call() { return null; } + + private Map vipDetachLoadBalancerMapFromAction(CascadeAction action) { + HashMap vipLoadBalancerMap = new HashMap<>(); + if (VipVO.class.getSimpleName().equals(action.getParentIssuer())) { + + final List vipUuids = CollectionUtils.transformToList((List) action.getParentIssuerContext(), new Function() { + @Override + public String call(VipInventory arg) { + return arg.getUuid(); + } + }); + + if (vipUuids.isEmpty()) { + return vipLoadBalancerMap; + } + + List vos = new Callable>() { + @Override + @Transactional(readOnly = true) + public List call() { + String sql = "select d from LoadBalancerVO d where (d.vipUuid in (:vipUuids) or d.ipv6VipUuid in (:vipUuids))"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, LoadBalancerVO.class); + q.setParameter("vipUuids", vipUuids); + return q.getResultList(); + } + }.call(); + + // detach vip from lb only when lb has two vip, and one is not in the vips will delete + for (LoadBalancerVO loadBalancerVO : vos) { + if (!StringUtils.isEmpty(loadBalancerVO.getVipUuid()) && !StringUtils.isEmpty(loadBalancerVO.getIpv6VipUuid())) { + if (!(vipUuids.contains(loadBalancerVO.getVipUuid()) && vipUuids.contains(loadBalancerVO.getIpv6VipUuid()))) { + if (vipUuids.contains(loadBalancerVO.getVipUuid())) { + vipLoadBalancerMap.put(loadBalancerVO.getVipUuid(), loadBalancerVO); + } + if (vipUuids.contains(loadBalancerVO.getIpv6VipUuid())) { + vipLoadBalancerMap.put(loadBalancerVO.getIpv6VipUuid(), loadBalancerVO); + } + } + } + } + } + return vipLoadBalancerMap; + } + + private void releaseOnlyVipOfLb(Map vipLoadBalancerMap, Completion completion) { + if (vipLoadBalancerMap == null || vipLoadBalancerMap.isEmpty()) { + completion.success(); + return; + } + + ArrayList dMsgs = new ArrayList<>(); + for (String vipUuid : vipLoadBalancerMap.keySet()) { + LoadBalancerVO vo = vipLoadBalancerMap.get(vipUuid); + DetachVipFromLoadBalancerMsg dmsg = new DetachVipFromLoadBalancerMsg(); + dmsg.setVipUuid(vipUuid); + dmsg.setUuid(vo.getUuid()); + bus.makeTargetServiceIdByResourceUuid(dmsg, LoadBalancerConstants.SERVICE_ID, vipUuid); + dMsgs.add(dmsg); + } + + new While<>(dMsgs).step((dmsg, whileCompletion) -> { + bus.send(dmsg, new CloudBusCallBack(dmsg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.debug(String.format("detach vip[%s] from lb[%s] error, because %s", dmsg.getVipUuid(), dmsg.getUuid(), reply.getError())); + whileCompletion.addError(reply.getError()); + } + whileCompletion.done(); + } + }); + + }, dMsgs.size()).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList.getCauses().get(0)); + return; + } + completion.success(); + } + }); + } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerConstants.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerConstants.java index 0b38d09ec49..fe147c11cf4 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerConstants.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerConstants.java @@ -2,6 +2,7 @@ import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.utils.network.IPv6Constants; import java.util.ArrayList; import java.util.List; @@ -29,6 +30,14 @@ public class LoadBalancerConstants { public static final String HEALTH_CHECK_TARGET_PROTOCL_UDP = "udp"; public static final String HEALTH_CHECK_TARGET_PROTOCL_HTTP = "http"; + public static final String HTTP_MODE_HTTP_KEEP_ALIVE = "http-keep-alive"; + public static final String HTTP_MODE_HTTP_SERVER_CLOSE = "http-server-close"; + @Deprecated + public static final String HTTP_MODE_HTTP_TUNNEL = "http-tunnel"; + public static final String HTTP_MODE_HTTPCLOSE = "httpclose"; + @Deprecated + public static final String HTTP_MODE_FORCECLOSE = "forceclose"; + public static enum HealthCheckMothod { GET, HEAD @@ -47,10 +56,51 @@ public static enum HealthCheckStatusCode { http_5xx } + public static enum HttpRedirectHttps { + enable, + disable + } + + public static enum HttpVersions { + HTTP_1_1, + HTTP_2; + + @Override + public String toString() { + switch (this) { + case HTTP_1_1: + return "http1.1"; + case HTTP_2: + return "h2"; + default: + throw new IllegalArgumentException(); + } + } + } + + public static final String DisableLbSupportHttpCompressAlgos = "disable"; + public static final String DisableLbSupportTcpProxyProtocol = "disable"; + public static final List LbSupportHttpCompressAlgos = asList( + "deflate", "raw-deflate", "gzip" , DisableLbSupportHttpCompressAlgos + ); + + public static final List LbSupportTcpProxyProtocol = asList( + "v1", "v2" , DisableLbSupportTcpProxyProtocol + ); + + public static final List LbSupportHttpVersion = asList( + HttpVersions.HTTP_1_1.toString(), + HttpVersions.HTTP_2.toString() + ); + public static final String HEALTH_CHECK_URI_REGEX = "^/[A-Za-z0-9-/.%?#&]*"; + public static final String COOKIE_NAME_REGEX = "[A-Za-z0-9_-]+"; + public static final List HEALTH_CHECK_TARGET_PROTOCOLS = new ArrayList(); + public static final List HTTP_MODES = new ArrayList(); + public static final String ACTION_CATEGORY = "loadBalancer"; public static final String LB_PROTOCOL_UDP = "udp"; @@ -69,6 +119,9 @@ public static enum HealthCheckStatusCode { public static final long BALANCER_WEIGHT_MAX = 100; public static final long BALANCER_WEIGHT_MIN = 0; public static final long BALANCER_WEIGHT_default = 100; + + public static final Integer BALANCER_BACKEND_NIC_IPVERSION_DEFAULT = IPv6Constants.IPv4; + static { BALANCE_ALGORITHMS.add(BALANCE_ALGORITHM_ROUND_ROBIN); BALANCE_ALGORITHMS.add(BALANCE_ALGORITHM_LEAST_CONN); @@ -78,6 +131,10 @@ public static enum HealthCheckStatusCode { HEALTH_CHECK_TARGET_PROTOCOLS.add(HEALTH_CHECK_TARGET_PROTOCL_TCP); HEALTH_CHECK_TARGET_PROTOCOLS.add(HEALTH_CHECK_TARGET_PROTOCL_UDP); HEALTH_CHECK_TARGET_PROTOCOLS.add(HEALTH_CHECK_TARGET_PROTOCL_HTTP); + + HTTP_MODES.add(HTTP_MODE_HTTP_KEEP_ALIVE); + HTTP_MODES.add(HTTP_MODE_HTTP_SERVER_CLOSE); + HTTP_MODES.add(HTTP_MODE_HTTPCLOSE); } public static enum Param { @@ -103,10 +160,21 @@ public static enum Param { public static final int NUMBER_OF_PROCESS_MIN = 1; public static final int NUMBER_OF_PROCESS_MAX = 64; + public static final int SESSION_IDLE_TIMEOUT_MIN = 30; + public static final int SESSION_IDLE_TIMEOUT_MAX = 3600; + public static final int SESSION_IDLE_TIMEOUT_DEFAULT = 60; + + public static final int COOKIE_NAME_MAX = 20; + + public static final int REDIRECT_PORT_DEFAULT = 443; + public static final int STATUS_CODE_DEFAULT = 302; + public static final String HEALTH_CHECK_TARGET_DEFAULT = "default"; public static final List vmOperationForDetachListener = asList( VmInstanceConstant.VmOperation.Destroy, - VmInstanceConstant.VmOperation.DetachNic + VmInstanceConstant.VmOperation.DetachNic, + VmInstanceConstant.VmOperation.ChangeNicNetwork, + VmInstanceConstant.VmOperation.ChangeNicIp ); } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerExtension.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerExtension.java index 5be67694c0e..e20e57ce05a 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerExtension.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerExtension.java @@ -23,6 +23,7 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.service.NetworkServiceProviderType; import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.vm.VmInstanceSpec; @@ -76,11 +77,7 @@ public String call(VmNicInventory arg) { } private boolean isLbShouldBeAttachedToBackend(String vmUuid, String l3Uuid) { - boolean ipChanged = new StaticIpOperator().isIpChange(vmUuid, l3Uuid); - - L3NetworkVO l3Vo = dbf.findByUuid(l3Uuid, L3NetworkVO.class); - boolean l3Need = l3Mgr.applyNetworkServiceWhenVmStateChange(l3Vo.getType()); - return ipChanged || l3Need; + return !new StaticIpOperator().isIpChange(vmUuid, l3Uuid); } @Override @@ -104,7 +101,7 @@ public void applyNetworkService(final VmInstanceSpec servedVm, Map arg) { })); } + if (msgs.isEmpty()) { + completion.done(); + return; + } + bus.send(msgs, new CloudBusListCallBack(completion) { @Override public void run(List replies) { @@ -388,4 +390,15 @@ public void beforeDeleteAcl(AccessControlListInventory acl) { public void afterDeleteAcl(AccessControlListInventory acl) { return; } + + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerFactory.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerFactory.java index e8f1ebaa5db..835cafafe7b 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerFactory.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerFactory.java @@ -18,5 +18,5 @@ public interface LoadBalancerFactory { String getProviderTypeByVmNicUuid(String nicUuid); - List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, LoadBalancerServerGroupVO groupVO); + List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, LoadBalancerServerGroupVO groupVO, int ipVersion); } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerInventory.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerInventory.java index 4eec826cfe5..cdbe5bf751e 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerInventory.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerInventory.java @@ -1,9 +1,8 @@ package org.zstack.network.service.lb; +import org.apache.commons.lang.StringUtils; import org.zstack.header.query.ExpandedQueries; import org.zstack.header.query.ExpandedQuery; -import org.zstack.header.query.ExpandedQueryAlias; -import org.zstack.header.query.ExpandedQueryAliases; import org.zstack.header.search.Inventory; import org.zstack.network.service.vip.VipInventory; @@ -22,8 +21,10 @@ foreignKey = "uuid", expandedInventoryKey = "loadBalancerUuid"), @ExpandedQuery(expandedField = "vip", inventoryClass = VipInventory.class, foreignKey = "vipUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "ipv6Vip", inventoryClass = VipInventory.class, + foreignKey = "ipv6VipUuid", expandedInventoryKey = "uuid"), @ExpandedQuery(target = VipInventory.class, expandedField = "loadBalancer", - inventoryClass = LoadBalancerInventory.class, foreignKey = "uuid", expandedInventoryKey = "vipUuid") + inventoryClass = LoadBalancerInventory.class, foreignKey = "uuid", expandedInventoryKey = "vipUuid"), }) public class LoadBalancerInventory implements Serializable { private String name; @@ -33,6 +34,7 @@ public class LoadBalancerInventory implements Serializable { private String state; private String type; private String vipUuid; + private String ipv6VipUuid; private Timestamp createDate; private Timestamp lastOpDate; private List listeners; @@ -43,6 +45,7 @@ public LoadBalancerInventory(LoadBalancerVO vo) { this.setDescription(vo.getDescription()); this.setState(vo.getState().toString()); this.setVipUuid(vo.getVipUuid()); + this.setIpv6VipUuid(vo.getIpv6VipUuid()); this.setServerGroupUuid(vo.getServerGroupUuid()); this.setType(vo.getType().toString()); this.setCreateDate(vo.getCreateDate()); @@ -74,6 +77,13 @@ public void setVipUuid(String vipUuid) { this.vipUuid = vipUuid; } + public String getIpv6VipUuid() { + return ipv6VipUuid; + } + + public void setIpv6VipUuid(String ipv6VipUuid) { + this.ipv6VipUuid = ipv6VipUuid; + } public List getListeners() { return listeners; } @@ -145,4 +155,15 @@ public String getServerGroupUuid() { public void setServerGroupUuid(String serverGroupUuid) { this.serverGroupUuid = serverGroupUuid; } + + public List getVipUuids() { + ArrayList vipUuids = new ArrayList<>(); + if (!StringUtils.isEmpty(vipUuid)) { + vipUuids.add(vipUuid); + } + if (!StringUtils.isEmpty(ipv6VipUuid)) { + vipUuids.add(ipv6VipUuid); + } + return vipUuids; + } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerListenerVO.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerListenerVO.java index 3f42024328e..eb153fd6577 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerListenerVO.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerListenerVO.java @@ -26,10 +26,6 @@ @EntityGraph( parents = { @EntityGraph.Neighbour(type = LoadBalancerVO.class, myField = "loadBalancerUuid", targetField = "uuid"), - @EntityGraph.Neighbour(type = LoadBalancerListenerVmNicRefVO.class, myField = "uuid", targetField = "listenerUuid"), - @EntityGraph.Neighbour(type = LoadBalancerListenerCertificateRefVO.class, myField = "uuid", targetField = "listenerUuid"), - @EntityGraph.Neighbour(type = LoadBalancerListenerACLRefVO.class, myField = "uuid", targetField = "listenerUuid"), - @EntityGraph.Neighbour(type = LoadBalancerListenerServerGroupRefVO.class, myField = "uuid", targetField = "listenerUuid") } ) public class LoadBalancerListenerVO extends ResourceVO implements OwnedByAccount { diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManager.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManager.java index af731a780ca..c8488092c3c 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManager.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManager.java @@ -1,5 +1,8 @@ package org.zstack.network.service.lb; +import org.zstack.network.service.vip.ModifyVipAttributesStruct; +import org.zstack.network.service.vip.VipVO; + import java.util.List; /** diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java index 7827181a868..a250c07afcd 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerManagerImpl.java @@ -2,7 +2,6 @@ import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; @@ -28,14 +27,13 @@ import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.identity.APIChangeResourceOwnerMsg; import org.zstack.header.identity.Quota; -import org.zstack.header.identity.Quota.QuotaOperator; -import org.zstack.header.identity.Quota.QuotaPair; import org.zstack.header.identity.ReportQuotaExtensionPoint; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; -import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.query.AddExpandedQueryExtensionPoint; import org.zstack.header.query.ExpandedQueryAliasStruct; import org.zstack.header.query.ExpandedQueryStruct; @@ -45,7 +43,8 @@ import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; import org.zstack.identity.Account; -import org.zstack.identity.QuotaUtil; +import org.zstack.network.service.lb.quota.LoadBalanceListenerNumQuotaDefinition; +import org.zstack.network.service.lb.quota.LoadBalanceNumQuotaDefinition; import org.zstack.network.service.vip.*; import org.zstack.tag.TagManager; import org.zstack.utils.CollectionUtils; @@ -54,9 +53,9 @@ import org.zstack.utils.VipUseForList; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; import javax.persistence.Tuple; -import javax.persistence.TypedQuery; import java.util.*; import java.util.stream.Collectors; @@ -162,7 +161,7 @@ private void handle(APIGetLoadBalancerListenerACLEntriesMsg msg) { aclOfListenerUuids = loadBalancerListenerACLRefVOS.stream().filter(ref -> ref.getListenerUuid().equals(listenUuid)) .map(LoadBalancerListenerACLRefVO::getAclUuid).collect(Collectors.toList()); } else { - aclOfListenerUuids = loadBalancerListenerACLRefVOS.stream().filter(ref -> ref.getListenerUuid().equals(listenUuid) && ref.getType().equals(msg.getType())) + aclOfListenerUuids = loadBalancerListenerACLRefVOS.stream().filter(ref -> ref.getListenerUuid().equals(listenUuid) && msg.getType().equals(ref.getType().toString())) .map(LoadBalancerListenerACLRefVO::getAclUuid).collect(Collectors.toList()); } aclOfListenerUuids = aclOfListenerUuids.stream().distinct().collect(Collectors.toList()); @@ -191,7 +190,6 @@ private void handle(final APICreateLoadBalancerMsg msg) { String type = msg.getType() != null ? msg.getType() : LoadBalancerType.Shared.toString(); LoadBalancerFactory f = getLoadBalancerFactory(type); - final VipInventory vip = VipInventory.valueOf(dbf.findByUuid(msg.getVipUuid(), VipVO.class)); FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("create-lb-%s", msg.getName())); chain.then(new ShareFlow() { @@ -214,6 +212,7 @@ public void run(FlowTrigger trigger, Map data) { groupVO.setDescription(String.format("default server group for load balancer %s", msg.getName())); groupVO.setLoadBalancerUuid(vo.getUuid()); groupVO.setName(String.format("default-server-group-%s", msg.getName())); + groupVO.setIpVersion(IPv6Constants.IPv4); dbf.persist(groupVO); vo = dbf.reload(vo); @@ -239,47 +238,71 @@ public void rollback(FlowRollback trigger, Map data) { flow(new Flow() { String __name__ = "acquire-vip"; - boolean s = false; + List vipUuidsAcquireSuccess = Collections.synchronizedList(new ArrayList<>()); @Override public void run(FlowTrigger trigger, Map data) { - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(f.getNetworkServiceType()); - struct.setServiceUuid(vo.getUuid()); - Vip v = new Vip(vip.getUuid()); - v.setStruct(struct); - v.acquire(new Completion(trigger) { - @Override - public void success() { - s = true; - trigger.next(); - } + new While<>(msg.getVipUuids()).step((vipUuid, whileCompletion) -> { + ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); + struct.setUseFor(f.getNetworkServiceType()); + struct.setServiceUuid(vo.getUuid()); + Vip v = new Vip(vipUuid); + v.setStruct(struct); + v.acquire(new Completion(whileCompletion) { + @Override + public void success() { + vipUuidsAcquireSuccess.add(vipUuid); + whileCompletion.done(); + } + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }, 2).run(new WhileDoneCompletion(trigger) { @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + return; + } + trigger.next(); } }); } @Override public void rollback(FlowRollback trigger, Map data) { - LoadBalancerVO vo = (LoadBalancerVO)data.get(LoadBalancerConstants.Param.LOAD_BALANCER_VO); - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(f.getNetworkServiceType()); - struct.setServiceUuid(vo.getUuid()); - Vip v = new Vip(vip.getUuid()); - v.setStruct(struct); - v.release(new Completion(trigger) { - @Override - public void success() { - trigger.rollback(); - } + if (vipUuidsAcquireSuccess.isEmpty()) { + trigger.rollback(); + return; + } + new While<>(vipUuidsAcquireSuccess).step((vipUuid, whileCompletion) -> { + LoadBalancerVO vo = (LoadBalancerVO)data.get(LoadBalancerConstants.Param.LOAD_BALANCER_VO); + ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); + struct.setUseFor(f.getNetworkServiceType()); + struct.setServiceUuid(vo.getUuid()); + Vip v = new Vip(vipUuid); + v.setStruct(struct); + v.release(new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + //TODO add GC + logger.warn(errorCode.toString()); + whileCompletion.done(); + } + }); + }, 2).run(new WhileDoneCompletion(trigger) { @Override - public void fail(ErrorCode errorCode) { - //TODO add GC - logger.warn(errorCode.toString()); + public void done(ErrorCodeList errorCodeList) { trigger.rollback(); } }); @@ -466,9 +489,7 @@ private void installConfigValidateExtension(){ public void validateGlobalConfig(String category, String name, String oldValue, String value) throws GlobalConfigException { List httpModes = new ArrayList<>(Arrays.asList("http-keep-alive", "http-server-close", - "http-tunnel", - "httpclose", - "forceclose")); + "httpclose")); if (!httpModes.contains(value)) { throw new GlobalConfigException(String.format("%s must be in %s", LoadBalancerGlobalConfig.HTTP_MODE.getName(),String.join(", ",httpModes))); @@ -788,101 +809,25 @@ public List getExpandedQueryAliasesStructs() { @Override public List reportQuota() { - QuotaOperator checker = new QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreateLoadBalancerMsg) { - check((APICreateLoadBalancerMsg) msg, pairs); - } else if (msg instanceof APICreateLoadBalancerListenerMsg) { - check((APICreateLoadBalancerListenerMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - List usages = new ArrayList<>(); - - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(LoadBalanceQuotaConstant.LOAD_BALANCER_NUM); - usage.setUsed(getUsedLb(accountUuid)); - usages.add(usage); - - Quota.QuotaUsage listenerUsage = new Quota.QuotaUsage(); - listenerUsage.setName(LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM); - listenerUsage.setUsed(getUsedLbListener(accountUuid)); - usages.add(listenerUsage); - - return usages; - } - - @Transactional(readOnly = true) - private long getUsedLb(String accountUuid) { - String sql = "select count(lb.uuid) from LoadBalancerVO lb, AccountResourceRefVO ref where ref.resourceUuid = lb.uuid and " + - "ref.accountUuid = :auuid and ref.resourceType = :rtype"; - - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", LoadBalancerVO.class.getSimpleName()); - Long en = q.getSingleResult(); - en = en == null ? 0 : en; - return en; - } - - @Transactional(readOnly = true) - private long getUsedLbListener(String accountUuid) { - String sql = "select count(lb.uuid) from LoadBalancerListenerVO lb, AccountResourceRefVO ref where ref.resourceUuid = lb.uuid and " + - "ref.accountUuid = :auuid and ref.resourceType = :rtype"; - - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", LoadBalancerListenerVO.class.getSimpleName()); - Long en = q.getSingleResult(); - en = en == null ? 0 : en; - return en; - } - - private void check(APICreateLoadBalancerListenerMsg msg, Map pairs) { - long lbNum = pairs.get(LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM).getValue(); - long en = getUsedLbListener(msg.getSession().getAccountUuid()); - - if (en + 1 > lbNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM, lbNum)); - } - } - - private void check(APICreateLoadBalancerMsg msg, Map pairs) { - long lbNum = pairs.get(LoadBalanceQuotaConstant.LOAD_BALANCER_NUM).getValue(); - long en = getUsedLb(msg.getSession().getAccountUuid()); - - if (en + 1 > lbNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), LoadBalanceQuotaConstant.LOAD_BALANCER_NUM, lbNum)); - } - } - }; - Quota quota = new Quota(); - quota.addMessageNeedValidation(APICreateLoadBalancerMsg.class); - quota.addMessageNeedValidation(APICreateLoadBalancerListenerMsg.class); - quota.setOperator(checker); - - QuotaPair p = new QuotaPair(); - p.setName(LoadBalanceQuotaConstant.LOAD_BALANCER_NUM); - p.setValue(LoadBalanceQuotaGlobalConfig.LOAD_BALANCER_NUM.defaultValue(Long.class)); - quota.addPair(p); - - QuotaPair listener = new QuotaPair(); - listener.setName(LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM); - listener.setValue(LoadBalanceQuotaGlobalConfig.LOAD_BALANCER_LISTENER_NUM.defaultValue(Long.class)); - quota.addPair(listener); + quota.defineQuota(new LoadBalanceNumQuotaDefinition()); + quota.defineQuota(new LoadBalanceListenerNumQuotaDefinition()); + + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateLoadBalancerMsg.class) + .addCounterQuota(LoadBalanceQuotaConstant.LOAD_BALANCER_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateLoadBalancerListenerMsg.class) + .addCounterQuota(LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM)); + + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(LoadBalancerVO.class) + .eq(LoadBalancerVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(LoadBalanceQuotaConstant.LOAD_BALANCER_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(LoadBalancerListenerVO.class) + .eq(LoadBalancerListenerVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM)); return list(quota); } @@ -902,7 +847,7 @@ public RangeSet getVipUsePortRange(String vipUuid, String protocol, VipUseForLis } List lbPortList = SQL.New("select lbl.loadBalancerPort, lbl.loadBalancerPort from LoadBalancerListenerVO lbl, LoadBalancerVO lb " - + "where lbl.protocol in (:protocols) and lbl.loadBalancerUuid=lb.uuid and lb.vipUuid = :vipUuid", Tuple.class). + + "where lbl.protocol in (:protocols) and lbl.loadBalancerUuid=lb.uuid and (lb.vipUuid = :vipUuid or lb.ipv6VipUuid = :vipUuid)", Tuple.class). param("protocols", protocols). param("vipUuid", vipUuid).list(); @@ -921,36 +866,40 @@ public RangeSet getVipUsePortRange(String vipUuid, String protocol, VipUseForLis @Override public ServiceReference getServiceReference(String vipUuid) { long count = 0; - List l3Uuids = SQL.New("select nic.l3NetworkUuid" + - " from LoadBalancerVO lb, LoadBalancerServerGroupVO g, LoadBalancerListenerVO listener, VmNicVO nic, " + - " LoadBalancerListenerServerGroupRefVO lgref, LoadBalancerServerGroupVmNicRefVO nicRef" + - " where lb.vipUuid = :vipUuid and lb.uuid = listener.loadBalancerUuid" + - " and listener.uuid = lgref.listenerUuid and lgref.serverGroupUuid = g.uuid " + - " and g.uuid = nicRef.serverGroupUuid and nicRef.vmNicUuid = nic.uuid" + - " and nicRef.status != 'Pending'") + List l3Uuids = SQL.New("select distinct nic.l3NetworkUuid " + + "from LoadBalancerVO lb " + + "join LoadBalancerServerGroupVO g on lb.uuid = g.loadBalancerUuid " + + "join LoadBalancerListenerVO listener on lb.uuid = listener.loadBalancerUuid " + + "join LoadBalancerListenerServerGroupRefVO lgref on listener.uuid = lgref.listenerUuid " + + "join LoadBalancerServerGroupVmNicRefVO nicRef on g.uuid = nicRef.serverGroupUuid " + + "join VmNicVO nic on nicRef.vmNicUuid = nic.uuid " + + "where (lb.vipUuid = :vipUuid or lb.ipv6VipUuid = :vipUuid) " + + "and nicRef.status != 'Pending'") .param("vipUuid", vipUuid).list(); + if (l3Uuids != null && !l3Uuids.isEmpty()) { count = new HashSet<>(l3Uuids).size(); } - List uuids = SQL.New("select distinct lb.uuid" + - " from LoadBalancerVO lb, LoadBalancerServerGroupVO g, LoadBalancerListenerVO listener, VmNicVO nic, " + - " LoadBalancerListenerServerGroupRefVO lgref, LoadBalancerServerGroupVmNicRefVO nicRef" + - " where lb.vipUuid = :vipUuid and lb.uuid = listener.loadBalancerUuid" + - " and listener.uuid = lgref.listenerUuid and lgref.serverGroupUuid = g.uuid " + - " and g.uuid = nicRef.serverGroupUuid and nicRef.vmNicUuid = nic.uuid" + - " and nicRef.status != 'Pending'") - .param("vipUuid", vipUuid).list(); - + List uuids = SQL.New("select distinct lb.uuid " + + "from LoadBalancerVO lb " + + "join LoadBalancerServerGroupVO g on lb.uuid = g.loadBalancerUuid " + + "join LoadBalancerListenerVO listener on lb.uuid = listener.loadBalancerUuid " + + "join LoadBalancerListenerServerGroupRefVO lgref on listener.uuid = lgref.listenerUuid " + + "join LoadBalancerServerGroupVmNicRefVO nicRef on g.uuid = nicRef.serverGroupUuid " + + "join VmNicVO nic on nicRef.vmNicUuid = nic.uuid " + + "where (lb.vipUuid = :vipUuid or lb.ipv6VipUuid = :vipUuid) " + + "and nicRef.status != 'Pending'") + .param("vipUuid", vipUuid).list(); return new VipGetServiceReferencePoint.ServiceReference(LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING, count, uuids == null?new ArrayList<>() : uuids); } @Override public ServiceReference getServicePeerL3Reference(String vipUuid, String peerL3Uuid) { long count = 0; - List l3Uuids = SQL.New("select nic.l3NetworkUuid" + + List l3Uuids = SQL.New("select distinct nic.l3NetworkUuid" + " from LoadBalancerVO lb, LoadBalancerServerGroupVO g, LoadBalancerListenerVO listener, VmNicVO nic, " + " LoadBalancerListenerServerGroupRefVO lgref, LoadBalancerServerGroupVmNicRefVO nicRef" + - " where lb.vipUuid = :vipUuid and lb.uuid = listener.loadBalancerUuid" + + " where (lb.vipUuid = :vipUuid or lb.ipv6VipUuid = :vipUuid) and lb.uuid = listener.loadBalancerUuid" + " and listener.uuid = lgref.listenerUuid and lgref.serverGroupUuid = g.uuid " + " and g.uuid = nicRef.serverGroupUuid and nicRef.vmNicUuid = nic.uuid" + " and nicRef.status != 'Pending' and nic.l3NetworkUuid = :l3uuid") @@ -961,7 +910,7 @@ public ServiceReference getServicePeerL3Reference(String vipUuid, String peerL3U List uuids = SQL.New("select distinct lb.uuid" + " from LoadBalancerVO lb, LoadBalancerServerGroupVO g, LoadBalancerListenerVO listener, VmNicVO nic, " + " LoadBalancerListenerServerGroupRefVO lgref, LoadBalancerServerGroupVmNicRefVO nicRef" + - " where lb.vipUuid = :vipUuid and lb.uuid = listener.loadBalancerUuid" + + " where (lb.vipUuid = :vipUuid or lb.ipv6VipUuid = :vipUuid) and lb.uuid = listener.loadBalancerUuid" + " and listener.uuid = lgref.listenerUuid and lgref.serverGroupUuid = g.uuid " + " and g.uuid = nicRef.serverGroupUuid and nicRef.vmNicUuid = nic.uuid" + " and nicRef.status != 'Pending' and nic.l3NetworkUuid = :l3uuid") @@ -976,7 +925,8 @@ public LoadBalancerStruct makeStruct(LoadBalancerVO vo) { vo = dbf.reload(vo); LoadBalancerStruct struct = new LoadBalancerStruct(); struct.setLb(LoadBalancerInventory.valueOf(vo)); - struct.setVip(VipInventory.valueOf(dbf.findByUuid(vo.getVipUuid(), VipVO.class))); + struct.setVip(StringUtils.isEmpty(vo.getVipUuid()) ? null : VipInventory.valueOf(dbf.findByUuid(vo.getVipUuid(), VipVO.class))); + struct.setIpv6Vip(StringUtils.isEmpty(vo.getIpv6VipUuid()) ? null :VipInventory.valueOf(dbf.findByUuid(vo.getIpv6VipUuid(), VipVO.class))); List activeNicUuids = new ArrayList(); for (LoadBalancerListenerVO l : vo.getListeners()) { @@ -990,7 +940,7 @@ public LoadBalancerStruct makeStruct(LoadBalancerVO vo) { } groupInventories.add(LoadBalancerServerGroupInventory.valueOf(groupVO)); } - struct.getListenerServerGroupMap().put(l.getUuid(), groupInventories); + struct.getListenerServerGroupMap().put(l.getUuid(), groupInventories); } if (activeNicUuids.isEmpty()) { @@ -1067,10 +1017,10 @@ public void upgradeLoadBalancerServerGroup() { .map(LoadBalancerServerGroupVmNicRefVO::getVmNicUuid).collect(Collectors.toList())); } - if (!uuids.containsAll(nicUuids)) { + if (!new HashSet<>(uuids).containsAll(nicUuids)) { throw new CloudRuntimeException(String.format("load balancer listener [uuid:%s] upgraded failed," + - "vmnics directly attached are [%s], vmnic attached to its serverGroup are", - vo.getUuid(), uuids)); + "vmnics directly attached are [%s], vmnic attached to its serverGroup are %s", + vo.getUuid(), nicUuids, uuids)); } } } @@ -1092,6 +1042,7 @@ public void upgradeLoadBalancerServerGroup() { groupVO.setDescription(String.format("default server group for load balancer %s", vo.getName())); groupVO.setLoadBalancerUuid(vo.getUuid()); groupVO.setName(String.format("default-server-group-%s", vo.getName())); + groupVO.setIpVersion(IPv6Constants.IPv4); dbf.persist(groupVO); vo.setServerGroupUuid(groupVO.getUuid()); @@ -1101,7 +1052,7 @@ public void upgradeLoadBalancerServerGroup() { List listenerVOS = Q.New(LoadBalancerListenerVO.class).list(); List vmNicRefVOS = new ArrayList<>(); for (LoadBalancerListenerVO vo : listenerVOS) { - boolean isExist = Q.New(LoadBalancerServerGroupVO.class).eq(LoadBalancerServerGroupVO_.name, String.format("default-server-group-%s", vo.getName())) + boolean isExist = Q.New(LoadBalancerServerGroupVO.class).eq(LoadBalancerServerGroupVO_.name, String.format("default-server-group-%s-%s", vo.getName(), vo.getUuid().substring(0, 5))) .eq(LoadBalancerServerGroupVO_.description, String.format("default server group for load balancer listener %s", vo.getName())) .eq(LoadBalancerServerGroupVO_.loadBalancerUuid, vo.getLoadBalancerUuid()).isExists(); if (isExist) { @@ -1113,7 +1064,8 @@ public void upgradeLoadBalancerServerGroup() { groupVO.setAccountUuid(Account.getAccountUuidOfResource(vo.getUuid())); groupVO.setDescription(String.format("default server group for load balancer listener %s", vo.getName())); groupVO.setLoadBalancerUuid(vo.getLoadBalancerUuid()); - groupVO.setName(String.format("default-server-group-%s", vo.getName())); + groupVO.setIpVersion(IPv6Constants.IPv4); + groupVO.setName(String.format("default-server-group-%s-%s", vo.getName(), vo.getUuid().substring(0, 5))); dbf.persist(groupVO); vo.setServerGroupUuid(groupVO.getUuid()); diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupInventory.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupInventory.java index 369896711f0..bda7afd06b8 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupInventory.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupInventory.java @@ -34,6 +34,7 @@ public class LoadBalancerServerGroupInventory implements Serializable { private String description; private String loadBalancerUuid; + private Integer ipVersion; private Timestamp createDate; private Timestamp lastOpDate; private List listenerServerGroupRefs; @@ -46,6 +47,7 @@ public LoadBalancerServerGroupInventory(LoadBalancerServerGroupVO vo) { this.setUuid(vo.getUuid()); this.setDescription(vo.getDescription()); this.setLoadBalancerUuid(vo.getLoadBalancerUuid()); + this.setIpVersion(vo.getIpVersion()); this.setCreateDate(vo.getCreateDate()); this.setLastOpDate(vo.getLastOpDate()); this.setListenerServerGroupRefs(LoadBalancerListenerServerGroupRefInventory.valueOf(vo.getLoadBalancerListenerServerGroupRefs())); @@ -63,6 +65,7 @@ public static LoadBalancerServerGroupInventory valueOf(LoadBalancerServerGroupVO inv.setUuid(vo.getUuid()); inv.setDescription(vo.getDescription()); inv.setLoadBalancerUuid(vo.getLoadBalancerUuid()); + inv.setIpVersion(vo.getIpVersion()); inv.setCreateDate(vo.getCreateDate()); inv.setLastOpDate(vo.getLastOpDate()); inv.setListenerServerGroupRefs(LoadBalancerListenerServerGroupRefInventory.valueOf(vo.getLoadBalancerListenerServerGroupRefs())); @@ -165,4 +168,12 @@ public List getAttachedL3Uuids() { .in(VmNicVO_.uuid, attachedVmNics).listValues(); return l3Uuids.stream().distinct().collect(Collectors.toList()); } + + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO.java index d041d22d1a6..773b729b50b 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO.java @@ -11,6 +11,7 @@ import org.zstack.header.vo.ResourceVO; import javax.persistence.*; + import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashSet; @@ -21,14 +22,6 @@ @Entity @Table @BaseResource -@EntityGraph( - parents = { - @EntityGraph.Neighbour(type = LoadBalancerVO.class, myField = "loadBalancerUuid", targetField = "uuid"), - @EntityGraph.Neighbour(type = LoadBalancerListenerServerGroupRefVO.class, myField = "uuid", targetField = "serverGroupUuid"), - @EntityGraph.Neighbour(type = LoadBalancerServerGroupServerIpVO.class, myField = "uuid", targetField = "serverGroupUuid"), - @EntityGraph.Neighbour(type = LoadBalancerServerGroupVmNicRefVO.class, myField = "uuid", targetField = "serverGroupUuid"), - } -) public class LoadBalancerServerGroupVO extends ResourceVO implements OwnedByAccount { @Column private String name; @@ -40,6 +33,9 @@ public class LoadBalancerServerGroupVO extends ResourceVO implements OwnedByAcc @ForeignKey(parentEntityClass = LoadBalancerVO.class, parentKey = "uuid", onDeleteAction = ForeignKey.ReferenceOption.RESTRICT) private String loadBalancerUuid; + @Column + private Integer ipVersion; + @Column private Timestamp createDate; @@ -144,5 +140,13 @@ public String getLoadBalancerUuid() { public void setLoadBalancerUuid(String loadBalancerUuid) { this.loadBalancerUuid = loadBalancerUuid; } + + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } } \ No newline at end of file diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO_.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO_.java index 9fef9fc6d2a..84bfd5c852b 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO_.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVO_.java @@ -12,6 +12,7 @@ public class LoadBalancerServerGroupVO_ extends ResourceVO_ { public static volatile SingularAttribute name; public static volatile SingularAttribute description; public static volatile SingularAttribute loadBalancerUuid; + public static volatile SingularAttribute ipVersion; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefInventory.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefInventory.java index c4e4e986c39..d6863b11cbd 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefInventory.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefInventory.java @@ -28,6 +28,9 @@ public class LoadBalancerServerGroupVmNicRefInventory { private String serverGroupUuid; private String vmNicUuid; private Long weight; + + private Integer ipVersion; + private String status; private Timestamp createDate; private Timestamp lastOpDate; @@ -35,6 +38,7 @@ public class LoadBalancerServerGroupVmNicRefInventory { public static LoadBalancerServerGroupVmNicRefInventory valueOf(LoadBalancerServerGroupVmNicRefVO vo) { LoadBalancerServerGroupVmNicRefInventory inv = new LoadBalancerServerGroupVmNicRefInventory(); inv.setId(vo.getId()); + inv.setIpVersion(vo.getIpVersion()); inv.setListenerUuid(vo.getServerGroupUuid()); inv.setVmNicUuid(vo.getVmNicUuid()); inv.setWeight(vo.getWeight()); @@ -52,6 +56,14 @@ public static List valueOf(Collection< return invs; } + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + public String getStatus() { return status; } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO.java index af4152b286d..b6a38607a14 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO.java @@ -33,6 +33,9 @@ public class LoadBalancerServerGroupVmNicRefVO { @Column private Long weight; + @Column + private Integer ipVersion; + @Column @Enumerated(EnumType.STRING) private LoadBalancerVmNicStatus status; @@ -48,6 +51,14 @@ private void preUpdate() { lastOpDate = null; } + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + public LoadBalancerVmNicStatus getStatus() { return status; } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO_.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO_.java index 217873ae22e..2b8d32637e8 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO_.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerServerGroupVmNicRefVO_.java @@ -10,6 +10,7 @@ public class LoadBalancerServerGroupVmNicRefVO_ { public static volatile SingularAttribute serverGroupUuid; public static volatile SingularAttribute vmNicUuid; public static volatile SingularAttribute weight; + public static volatile SingularAttribute ipVersion; public static volatile SingularAttribute status; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSessionPersistence.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSessionPersistence.java new file mode 100644 index 00000000000..f6b299d03bb --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSessionPersistence.java @@ -0,0 +1,8 @@ +package org.zstack.network.service.lb; + +public enum LoadBalancerSessionPersistence { + disable, + iphash, + insert, + rewrite +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerStruct.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerStruct.java index 5e0eac70f9c..7603928123b 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerStruct.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerStruct.java @@ -1,13 +1,11 @@ package org.zstack.network.service.lb; +import com.google.common.collect.Lists; import org.zstack.header.vm.VmNicInventory; import org.zstack.network.service.vip.VipInventory; import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -16,6 +14,7 @@ public class LoadBalancerStruct implements Serializable { private LoadBalancerInventory lb; private VipInventory vip; + private VipInventory ipv6Vip; private Map vmNics; private List listeners; private Map> listenerServerGroupMap = new HashMap<>(); @@ -71,6 +70,14 @@ public void setVip(VipInventory vip) { this.vip = vip; } + public VipInventory getIpv6Vip() { + return ipv6Vip; + } + + public void setIpv6Vip(VipInventory ipv6Vip) { + this.ipv6Vip = ipv6Vip; + } + public Map> getListenerServerGroupMap() { return listenerServerGroupMap; } @@ -122,6 +129,15 @@ public List getAllVmNics() { return attachedVmNicUuids; } + public List getAllVmNicsInventory() { + if (vmNics == null || vmNics.isEmpty()) { + return Collections.EMPTY_LIST; + } + + Collection vmNicsIn = vmNics.values(); + return Lists.newArrayList(vmNicsIn); + } + public List getAllVmNicsOfListener(LoadBalancerListenerInventory listener) { List attachedVmNicUuids = new ArrayList<>(); List groupInvs = deletedListenerServerGroupMap.get(listener.getUuid()); diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSystemTags.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSystemTags.java index 67cd6677612..021f525b8fb 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSystemTags.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerSystemTags.java @@ -45,10 +45,31 @@ public class LoadBalancerSystemTags { public static final String BALANCER_ALGORITHM_TOKEN = "balancerAlgorithm"; public static PatternedSystemTag BALANCER_ALGORITHM = new PatternedSystemTag(String.format("balancerAlgorithm::{%s}", BALANCER_ALGORITHM_TOKEN), LoadBalancerListenerVO.class); + public static final String SESSION_PERSISTENCE_TOKEN = "sessionPersistence"; + public static PatternedSystemTag SESSION_PERSISTENCE = new PatternedSystemTag(String.format("sessionPersistence::{%s}", SESSION_PERSISTENCE_TOKEN), LoadBalancerListenerVO.class); + + public static final String SESSION_IDLE_TIMEOUT_TOKEN = "sessionIdleTimeout"; + public static PatternedSystemTag SESSION_IDLE_TIMEOUT = new PatternedSystemTag(String.format("sessionIdleTimeout::{%s}", SESSION_IDLE_TIMEOUT_TOKEN), LoadBalancerListenerVO.class); + + public static final String COOKIE_NAME_TOKEN = "cookieName"; + public static PatternedSystemTag COOKIE_NAME = new PatternedSystemTag(String.format("cookieName::{%s}", COOKIE_NAME_TOKEN), LoadBalancerListenerVO.class); + + public static final String HTTP_REDIRECT_HTTPS_TOKEN = "httpRedirectHttps "; + public static PatternedSystemTag HTTP_REDIRECT_HTTPS = new PatternedSystemTag(String.format("httpRedirectHttps::{%s}", HTTP_REDIRECT_HTTPS_TOKEN), LoadBalancerListenerVO.class); + + public static final String REDIRECT_PORT_TOKEN = "redirectPort"; + public static PatternedSystemTag REDIRECT_PORT = new PatternedSystemTag(String.format("redirectPort::{%s}", REDIRECT_PORT_TOKEN), LoadBalancerListenerVO.class); + + public static final String STATUS_CODE_TOKEN = "statusCode"; + public static PatternedSystemTag STATUS_CODE = new PatternedSystemTag(String.format("statusCode::{%s}", STATUS_CODE_TOKEN), LoadBalancerListenerVO.class); + public static final String BALANCER_WEIGHT_TOKEN = "balancerWeight"; public static final String BALANCER_NIC_TOKEN = "balancerNic"; public static PatternedSystemTag BALANCER_WEIGHT = new PatternedSystemTag(String.format("balancerWeight::{%s}::{%s}", BALANCER_NIC_TOKEN, BALANCER_WEIGHT_TOKEN), LoadBalancerListenerVO.class); + public static final String BALANCER_BACKEND_NIC_IPVERSION_TOKEN = "lbBackendNicIpversion"; + public static PatternedSystemTag BALANCER_BACKEND_NIC_IPVERSION = new PatternedSystemTag(String.format("lbBackendNicIpversion::{%s}::{%s}", BALANCER_NIC_TOKEN, BALANCER_BACKEND_NIC_IPVERSION_TOKEN), LoadBalancerServerGroupVmNicRefVO.class); + public static final String HEALTH_PARAMETER_TOKEN = "healthCheckParameter"; public static PatternedSystemTag HEALTH_PARAMETER = new PatternedSystemTag(String.format("healthCheckParameter::{%s}", HEALTH_PARAMETER_TOKEN), LoadBalancerListenerVO.class); @@ -58,4 +79,12 @@ public class LoadBalancerSystemTags { public static final String HTTP_MODE_TOKEN = "httpMode"; public static PatternedSystemTag HTTP_MODE= new PatternedSystemTag(String.format("httpMode::{%s}", HTTP_MODE_TOKEN), LoadBalancerListenerVO.class); + public static final String HTTP_VERSIONS_TOKEN = "httpVersion"; + public static PatternedSystemTag HTTP_VERSIONS= new PatternedSystemTag(String.format("httpVersions::{%s}", HTTP_VERSIONS_TOKEN), LoadBalancerListenerVO.class); + + public static final String TCP_PROXYPROTOCOL_TOKEN = "tcpProxyProtocol"; + public static PatternedSystemTag TCP_PROXYPROTOCOL = new PatternedSystemTag(String.format("tcpProxyProtocol::{%s}", TCP_PROXYPROTOCOL_TOKEN), LoadBalancerListenerVO.class); + + public static final String HTTP_COMPRESS_ALGOS_TOKEN = "httpCompressAlgos"; + public static PatternedSystemTag HTTP_COMPRESS_ALGOS= new PatternedSystemTag(String.format("httpCompressAlgos::{%s}", HTTP_COMPRESS_ALGOS_TOKEN), LoadBalancerListenerVO.class); } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO.java index d72154326ae..a1d97012179 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO.java @@ -1,5 +1,6 @@ package org.zstack.network.service.lb; +import org.apache.commons.lang.StringUtils; import org.zstack.header.identity.OwnedByAccount; import org.zstack.header.vo.BaseResource; import org.zstack.header.vo.EntityGraph; @@ -11,7 +12,9 @@ import javax.persistence.*; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -20,15 +23,6 @@ @Entity @Table @BaseResource -@EntityGraph( - parents = { - @EntityGraph.Neighbour(type = VipVO.class, myField = "vipUuid", targetField = "uuid"), - }, - - friends = { - @EntityGraph.Neighbour(type = LoadBalancerListenerVO.class, myField = "loadBalancerUuid", targetField = "uuid"), - } -) public class LoadBalancerVO extends ResourceVO implements OwnedByAccount { @Column private String name; @@ -48,9 +42,13 @@ public class LoadBalancerVO extends ResourceVO implements OwnedByAccount { private LoadBalancerType type; @Column - @ForeignKey(parentEntityClass = VipVO.class, parentKey = "uuid", onDeleteAction = ReferenceOption.CASCADE) + @ForeignKey(parentEntityClass = VipVO.class, parentKey = "uuid", onDeleteAction = ReferenceOption.SET_NULL) private String vipUuid; + @Column + @ForeignKey(parentEntityClass = VipVO.class, parentKey = "uuid", onDeleteAction = ReferenceOption.SET_NULL) + private String ipv6VipUuid; + @Column @ForeignKey(parentEntityClass = LoadBalancerServerGroupVO.class, parentKey = "uuid", onDeleteAction = ReferenceOption.CASCADE) private String serverGroupUuid; @@ -133,6 +131,14 @@ public void setVipUuid(String vipUuid) { this.vipUuid = vipUuid; } + public String getIpv6VipUuid() { + return ipv6VipUuid; + } + + public void setIpv6VipUuid(String vip6Uuid) { + this.ipv6VipUuid = vip6Uuid; + } + public Timestamp getCreateDate() { return createDate; } @@ -164,4 +170,28 @@ public String getServerGroupUuid() { public void setServerGroupUuid(String serverGroupUuid) { this.serverGroupUuid = serverGroupUuid; } + + public void deleteVip(String vipUuid) { + if (StringUtils.isEmpty(vipUuid)) { + return; + } + + if (vipUuid.equals(getVipUuid())) { + setVipUuid(null); + } else if (vipUuid.equals(getIpv6VipUuid())) { + setIpv6VipUuid(null); + } + } + + public List getVipUuids() { + ArrayList vipUuids = new ArrayList<>(); + if (!StringUtils.isEmpty(vipUuid)) { + vipUuids.add(vipUuid); + } + + if (!StringUtils.isEmpty(ipv6VipUuid)) { + vipUuids.add(ipv6VipUuid); + } + return vipUuids; + } } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO_.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO_.java index b98ca512125..0317775bc98 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO_.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerVO_.java @@ -15,6 +15,7 @@ public class LoadBalancerVO_ extends ResourceVO_ { public static volatile SingularAttribute description; public static volatile SingularAttribute providerType; public static volatile SingularAttribute vipUuid; + public static volatile SingularAttribute ipv6VipUuid; public static volatile SingularAttribute serverGroupUuid; public static volatile SingularAttribute state; public static volatile SingularAttribute type; diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java index 5b0c283403b..bc2e9d6e4e5 100644 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/LoadBalancerWeightOperator.java @@ -12,7 +12,9 @@ import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; import org.zstack.utils.DebugUtils; +import org.zstack.utils.IpRangeSet; import org.zstack.utils.TagUtils; +import org.zstack.utils.network.IPv6Constants; import java.util.HashMap; import java.util.List; @@ -82,6 +84,27 @@ public Map getWeight(List systemTags) { return ret; } + public Map getBackendNicIpversion(List systemTags) { + Map ret = new HashMap<>(); + + if (systemTags == null) { + return ret; + } + + for (String systemTag : systemTags) { + if(!LoadBalancerSystemTags.BALANCER_BACKEND_NIC_IPVERSION.isMatch(systemTag)) { + continue; + } + + Map token = TagUtils.parse(LoadBalancerSystemTags.BALANCER_BACKEND_NIC_IPVERSION.getTagFormat(), systemTag); + String nicUuid = token.get(LoadBalancerSystemTags.BALANCER_NIC_TOKEN); + String ipVersion = token.get(LoadBalancerSystemTags.BALANCER_BACKEND_NIC_IPVERSION_TOKEN); + ret.put(nicUuid, Integer.valueOf(ipVersion)); + } + + return ret; + } + public void setWeight(String listenerUuid, String nicUuid, Long weight) { DebugUtils.Assert(listenerUuid != null && nicUuid != null, String.format("invalid parameter listener uuid:%s nicUuid:%s", listenerUuid, nicUuid)); @@ -135,7 +158,7 @@ public void setWeight(List systemTags, String listenerUuid) { .eq(LoadBalancerServerGroupVmNicRefVO_.serverGroupUuid,defaultServerGroupUuid) .eq(LoadBalancerServerGroupVmNicRefVO_.vmNicUuid,nicUuid) .find(); - if(weight != vmNicRefVOS.getWeight()){ + if(!weight.equals(vmNicRefVOS.getWeight())){ vmNicRefVOS.setWeight(weight); dbf.update(vmNicRefVOS); } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/PackageInfo.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/PackageInfo.java index 0c5e6e5c8c9..daa40160b24 100755 --- a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/PackageInfo.java +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "负载均衡") +@PackageAPIInfo( + APICategoryName = "负载均衡", + permissions = {PackageAPIInfo.PERMISSION_ZSV_ADVANCED_AVAILABLE, PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/quota/LoadBalanceListenerNumQuotaDefinition.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/quota/LoadBalanceListenerNumQuotaDefinition.java new file mode 100644 index 00000000000..6a871adc58b --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/quota/LoadBalanceListenerNumQuotaDefinition.java @@ -0,0 +1,32 @@ +package org.zstack.network.service.lb.quota; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.network.service.lb.LoadBalanceQuotaConstant; +import org.zstack.network.service.lb.LoadBalanceQuotaGlobalConfig; +import org.zstack.network.service.lb.LoadBalancerListenerVO; + +public class LoadBalanceListenerNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return LoadBalanceQuotaConstant.LOAD_BALANCER_LISTENER_NUM; + } + + @Override + public Long getDefaultValue() { + return LoadBalanceQuotaGlobalConfig.LOAD_BALANCER_LISTENER_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(lb.uuid) from LoadBalancerListenerVO lb, AccountResourceRefVO ref where ref.resourceUuid = lb.uuid and " + + "ref.accountUuid = :auuid and ref.resourceType = :rtype"; + + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", LoadBalancerListenerVO.class.getSimpleName()); + Long en = q.find(); + en = en == null ? 0 : en; + return en; + } +} diff --git a/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/quota/LoadBalanceNumQuotaDefinition.java b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/quota/LoadBalanceNumQuotaDefinition.java new file mode 100644 index 00000000000..982a92e86f0 --- /dev/null +++ b/plugin/loadBalancer/src/main/java/org/zstack/network/service/lb/quota/LoadBalanceNumQuotaDefinition.java @@ -0,0 +1,32 @@ +package org.zstack.network.service.lb.quota; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.network.service.lb.LoadBalanceQuotaConstant; +import org.zstack.network.service.lb.LoadBalanceQuotaGlobalConfig; +import org.zstack.network.service.lb.LoadBalancerVO; + +public class LoadBalanceNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return LoadBalanceQuotaConstant.LOAD_BALANCER_NUM; + } + + @Override + public Long getDefaultValue() { + return LoadBalanceQuotaGlobalConfig.LOAD_BALANCER_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(lb.uuid) from LoadBalancerVO lb, AccountResourceRefVO ref where ref.resourceUuid = lb.uuid and " + + "ref.accountUuid = :auuid and ref.resourceType = :rtype"; + + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", LoadBalancerVO.class.getSimpleName()); + Long en = q.find(); + en = en == null ? 0 : en; + return en; + } +} diff --git a/plugin/localstorage/pom.xml b/plugin/localstorage/pom.xml index b9a7a2f3392..2fa49de85a0 100755 --- a/plugin/localstorage/pom.xml +++ b/plugin/localstorage/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIAddLocalPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIAddLocalPrimaryStorageMsgDoc_zh_cn.groovy index 2b63d1115bd..2c7c6e7d342 100644 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIAddLocalPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIAddLocalPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIGetLocalStorageHostDiskCapacityMsgDoc_zh_cn.groovy b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIGetLocalStorageHostDiskCapacityMsgDoc_zh_cn.groovy index d4690115128..ec8793df5a4 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIGetLocalStorageHostDiskCapacityMsgDoc_zh_cn.groovy +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIGetLocalStorageHostDiskCapacityMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "primaryStorageUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageGetVolumeMigratableHostsMsgDoc_zh_cn.groovy b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageGetVolumeMigratableHostsMsgDoc_zh_cn.groovy index 4f96a9aee6c..73e02c15a46 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageGetVolumeMigratableHostsMsgDoc_zh_cn.groovy +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageGetVolumeMigratableHostsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageMigrateVolumeMsgDoc_zh_cn.groovy b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageMigrateVolumeMsgDoc_zh_cn.groovy index 6c538a9ff8b..4f9517468c8 100644 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageMigrateVolumeMsgDoc_zh_cn.groovy +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APILocalStorageMigrateVolumeMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "destHostUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIQueryLocalStorageResourceRefMsgDoc_zh_cn.groovy b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIQueryLocalStorageResourceRefMsgDoc_zh_cn.groovy index 19862d3612f..176e160865b 100644 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIQueryLocalStorageResourceRefMsgDoc_zh_cn.groovy +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/APIQueryLocalStorageResourceRefMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.storage.primary.local import org.zstack.storage.primary.local.APIQueryLocalStorageResourceRefReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询本地存储资源引用(QueryLocalStorageResourceRef)" diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/InitPrimaryStorageOnHostConnectedMsg.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/InitPrimaryStorageOnHostConnectedMsg.java index f42555b0520..1842d79f74a 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/InitPrimaryStorageOnHostConnectedMsg.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/InitPrimaryStorageOnHostConnectedMsg.java @@ -9,6 +9,7 @@ public class InitPrimaryStorageOnHostConnectedMsg extends NeedReplyMessage implements PrimaryStorageMessage { private String primaryStorageUuid; private String hostUuid; + private boolean isNewAddedHost; @Override public String getPrimaryStorageUuid() { @@ -26,4 +27,12 @@ public String getHostUuid() { public void setHostUuid(String hostUuid) { this.hostUuid = hostUuid; } + + public boolean isNewAddedHost() { + return isNewAddedHost; + } + + public void setNewAddedHost(boolean isNewAddedHost) { + this.isNewAddedHost = isNewAddedHost; + } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocateCapacityForAttachingVolumeFlow.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocateCapacityForAttachingVolumeFlow.java index 0189e325bbd..0faf93884cb 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocateCapacityForAttachingVolumeFlow.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocateCapacityForAttachingVolumeFlow.java @@ -94,7 +94,7 @@ public void run(final FlowTrigger trigger, final Map data) { amsg.setRequiredHostUuid(hostUuid); amsg.setVmInstanceUuid(spec.getVmInventory().getUuid()); amsg.setSize(volume.getSize()); - amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString()); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); bus.send(amsg, new CloudBusCallBack(trigger) { @Override @@ -105,10 +105,10 @@ public void run(MessageReply reply) { } spec.setDestHost(HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class))); - AllocatePrimaryStorageSpaceReply ar = (AllocatePrimaryStorageSpaceReply) reply; allocatedInstallUrl = ar.getAllocatedInstallUrl(); data.put(VmInstanceConstant.Params.DestPrimaryStorageInventoryForAttachingVolume.toString(), ar.getPrimaryStorageInventory()); + data.put(VmInstanceConstant.Params.AllocatedUrlForAttachingVolume.toString(),allocatedInstallUrl); data.put(LocalStorageAllocateCapacityForAttachingVolumeFlow.class, ar.getSize()); trigger.next(); } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java index c64b7ffd8ea..9d84ec2a0fc 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorFactory.java @@ -264,11 +264,11 @@ public String getPrimaryStorageAllocatorStrategyName(final AllocatePrimaryStorag allocatorType = null; } else if (LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY.equals(msg.getAllocationStrategy())) { allocatorType = LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY; - } else if (msg.getRequiredPrimaryStorageUuid() != null) { + } else if (!msg.getCandidatePrimaryStorageUuids().isEmpty()) { SimpleQuery q = dbf.createQuery(PrimaryStorageVO.class); q.add(PrimaryStorageVO_.type, Op.EQ, LocalStorageConstants.LOCAL_STORAGE_TYPE); - q.add(PrimaryStorageVO_.uuid, Op.EQ, msg.getRequiredPrimaryStorageUuid()); - if (q.isExists()) { + q.add(PrimaryStorageVO_.uuid, Op.IN, msg.getCandidatePrimaryStorageUuids()); + if (q.count() == msg.getCandidatePrimaryStorageUuids().size()) { allocatorType = LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY; } } else if (msg.getRequiredHostUuid() != null) { @@ -285,9 +285,13 @@ public String call() { " from PrimaryStorageVO ps, PrimaryStorageClusterRefVO ref, HostVO host" + " where ps.uuid = ref.primaryStorageUuid" + " and ref.clusterUuid = host.clusterUuid" + - " and host.uuid = :huuid"; + " and host.uuid = :huuid" + + " and ps.state = :state" + + " and ps.status = :status"; TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("huuid", msg.getRequiredHostUuid()); + q.setParameter("state", PrimaryStorageState.Enabled); + q.setParameter("status", PrimaryStorageStatus.Connected); List types = q.getResultList(); for (String type : types) { if (type.equals(LocalStorageConstants.LOCAL_STORAGE_TYPE)) { @@ -342,7 +346,35 @@ public String getHostUuidByResourceUuid(String primaryStorageUuid, String resUui @Override public String buildAllocatedInstallUrl(AllocatePrimaryStorageSpaceMsg msg, PrimaryStorageInventory psInv) { + String hostUuid = getHostUuidFromAllocateMsg(msg); + + if (hostUuid == null) { + throw new OperationFailureException(argerr("To create volume on the local primary storage, " + + "you must specify the host that the volume is going to be created using the system tag [%s]", + LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat())); + } + + LocalStorageUtils.InstallPath path = new LocalStorageUtils.InstallPath(); + path.installPath = psInv.getUrl(); + path.hostUuid = hostUuid; + + return path.makeFullPath(); + } + + private String getHostUuidFromAllocateMsg(AllocatePrimaryStorageSpaceMsg msg) { String hostUuid = null; + + if (msg.getSystemTags() != null) { + PatternedSystemTag lsTag = LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME; + hostUuid = msg.getSystemTags().stream().filter(lsTag::isMatch) + .map(it -> lsTag.getTokenByTag(it, LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME_TOKEN)) + .findAny().orElse(null); + + } + if (hostUuid != null) { + return hostUuid; + } + if (msg.getRequiredInstallUri() != null) { String protocol; try { @@ -352,26 +384,13 @@ public String buildAllocatedInstallUrl(AllocatePrimaryStorageSpaceMsg msg, Prima argerr("invalid uri, correct example is file://$URL;hostUuid://$HOSTUUID or volume://$VOLUMEUUID ")); } hostUuid = uriParsers.get(protocol).parseUri(msg.getRequiredInstallUri()).hostUuid; - } else if (msg.getRequiredHostUuid() != null) { - hostUuid = msg.getRequiredHostUuid(); - } else if (msg.getSystemTags() != null) { - PatternedSystemTag lsTag = LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME; - hostUuid = msg.getSystemTags().stream().filter(lsTag::isMatch) - .map(it -> lsTag.getTokenByTag(it, LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME_TOKEN)) - .findAny().orElse(null); } - if (hostUuid == null) { - throw new OperationFailureException(argerr("To create volume on the local primary storage, " + - "you must specify the host that the volume is going to be created using the system tag [%s]", - LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME.getTagFormat())); + if (hostUuid != null) { + return hostUuid; } - LocalStorageUtils.InstallPath path = new LocalStorageUtils.InstallPath(); - path.installPath = psInv.getUrl(); - path.hostUuid = hostUuid; - - return path.makeFullPath(); + return msg.getRequiredHostUuid(); } @Override diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorStrategy.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorStrategy.java index 2ccc2c6b8b3..60c7fcce027 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorStrategy.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageAllocatorStrategy.java @@ -42,6 +42,10 @@ public PrimaryStorageInventory allocate(PrimaryStorageAllocationSpec spec) { return allocateAllCandidates(spec).get(0); } + @Override + public void sort(PrimaryStorageAllocationSpec spec, List candidates) { + } + @Override public List allocateAllCandidates(PrimaryStorageAllocationSpec spec) { class Result { diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java index 734c372f4a1..a009eb7c3af 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageApiInterceptor.java @@ -3,14 +3,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.compute.vm.IsoOperator; import org.zstack.core.cloudbus.CloudBus; -import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.db.Q; -import org.zstack.core.db.SQLBatch; -import org.zstack.core.db.SimpleQuery; +import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.apimediator.StopRoutingException; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.host.HostInventory; @@ -23,21 +21,22 @@ import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; -import org.zstack.header.volume.VolumeStatus; -import org.zstack.header.volume.VolumeType; -import org.zstack.header.volume.VolumeVO; -import org.zstack.header.volume.VolumeVO_; +import org.zstack.header.volume.*; import org.zstack.storage.primary.PrimaryStoragePhysicalCapacityManager; +import org.zstack.utils.CollectionDSL; +import javax.persistence.Tuple; import java.util.ArrayList; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; import static org.zstack.core.Platform.*; /** * Created by frank on 7/1/2015. */ -public class LocalStorageApiInterceptor implements ApiMessageInterceptor { +public class LocalStorageApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { @Autowired private ErrorFacade errf; @Autowired @@ -55,6 +54,8 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APILocalStorageMigrateVolumeMsg) msg); } else if (msg instanceof APILocalStorageGetVolumeMigratableHostsMsg) { validate((APILocalStorageGetVolumeMigratableHostsMsg) msg); + } else if (msg instanceof APIAttachDataVolumeToVmMsg) { + validate((APIAttachDataVolumeToVmMsg) msg); } return msg; @@ -193,4 +194,62 @@ private void validate(APIAddLocalPrimaryStorageMsg msg) { throw new ApiMessageInterceptionException(argerr(" the url contains an invalid folder[/dev or /proc or /sys]")); } } + + private void validate(APIAttachDataVolumeToVmMsg msg) { + String volumeHostUuid = Q.New(LocalStorageResourceRefVO.class) + .eq(LocalStorageResourceRefVO_.resourceUuid, msg.getVolumeUuid()) + .eq(LocalStorageResourceRefVO_.resourceType, VolumeVO.class.getSimpleName()) + .select(LocalStorageResourceRefVO_.hostUuid).findValue(); + if (volumeHostUuid == null) { + return; + } + + String vmHostUuid = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()) + .select(VmInstanceVO_.hostUuid).findValue(); + + if (volumeHostUuid.equals(vmHostUuid)) { + return; + } + + if (vmHostUuid != null && !Objects.equals(vmHostUuid, volumeHostUuid)) { + throw new ApiMessageInterceptionException(operr("the host of the vm[hostUuid:%s] is different from " + + "that of the volume[hostUuid:%s]. the volume cannot attach to the vm.", vmHostUuid, volumeHostUuid)); + } + + String sql = "select ref.resourceUuid,ref.hostUuid from LocalStorageResourceRefVO ref, VolumeVO volume " + + "where ref.resourceType = :resourceType " + + "and ref.resourceUuid = volume.uuid " + + "and volume.vmInstanceUuid = :vmUuid "; + List vmVolumeHostUuidTuples = SQL.New(sql, Tuple.class) + .param("resourceType", VolumeVO.class.getSimpleName()) + .param("vmUuid", msg.getVmInstanceUuid()) + .list(); + + List vmVolumeHostUuids = vmVolumeHostUuidTuples.stream().map(t -> t.get(1, String.class)).distinct().collect(Collectors.toList()); + + if (vmVolumeHostUuids.isEmpty()) { + return; + } + if (vmVolumeHostUuids.size() >= 2) { + List vmVolumes = vmVolumeHostUuidTuples.stream() + .map(t -> String.format("volume[%s] is on host[%s]", t.get(0, String.class), t.get(1, String.class))).collect(Collectors.toList()); + throw new ApiMessageInterceptionException( + operr("the vm has multiple local volumes on different hosts[%s]. " + + "please check the abnormal vm local volumes", vmVolumes.toString())); + } + if (!Objects.equals(vmVolumeHostUuids.get(0), volumeHostUuid)) { + throw new ApiMessageInterceptionException(operr("the volume on a host[hostUuid:%s] cannot be attached to the vm, " + + "because the vm has local volumes on other host[hostUuid:%s]", volumeHostUuid, vmVolumeHostUuids.get(0))); + } + } + + @Override + public List getMessageClassToIntercept() { + return CollectionDSL.list(APIAttachDataVolumeToVmMsg.class); + } + + @Override + public InterceptorPosition getPosition() { + return InterceptorPosition.END; + } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java index 0048fec9edf..5e4697ac8f5 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageBase.java @@ -11,8 +11,8 @@ import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.thread.AsyncThread; import org.zstack.core.thread.ChainTask; -import org.zstack.core.thread.MergeQueue; import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.upgrade.UpgradeChecker; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.core.workflow.SimpleFlowChain; @@ -40,11 +40,12 @@ import org.zstack.header.vm.*; import org.zstack.header.vo.ResourceVO; import org.zstack.header.volume.*; -import org.zstack.storage.primary.PrimaryStorageBase; -import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; -import org.zstack.storage.primary.PrimaryStoragePhysicalCapacityManager; +import org.zstack.storage.primary.*; import org.zstack.storage.primary.local.APIGetLocalStorageHostDiskCapacityReply.HostDiskCapacity; import org.zstack.storage.primary.local.MigrateBitsStruct.ResourceInfo; +import org.zstack.storage.snapshot.DeleteVolumeSnapshotGC; +import org.zstack.storage.snapshot.reference.VolumeSnapshotReferenceUtils; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionDSL; @@ -60,11 +61,11 @@ import javax.persistence.TypedQuery; import java.util.*; import java.util.concurrent.Callable; -import java.util.function.Supplier; import java.util.stream.Collectors; import static org.zstack.core.Platform.*; import static org.zstack.core.progress.ProgressReportService.createSubTaskProgress; +import static org.zstack.storage.primary.local.LocalStorageUtils.getHostUuidFromInstallUrl; import static org.zstack.utils.CollectionDSL.*; /** @@ -83,6 +84,10 @@ public class LocalStorageBase extends PrimaryStorageBase { private LocalStorageImageCleaner imageCacheCleaner; @Autowired private EventFacade eventf; + @Autowired + private LocalStorageHostUsageReport localForecaster; + @Autowired + private UpgradeChecker upgradeChecker; static class FactoryCluster { LocalStorageHypervisorFactory factory; @@ -310,6 +315,7 @@ public void setVmStateChanged(boolean vmStateChanged) { MigrateStruct struct = new MigrateStruct(); VolumeStatus originStatus = Q.New(VolumeVO.class).select(VolumeVO_.status).eq(VolumeVO_.uuid, msg.getVolumeUuid()).findValue(); + String lastHostUuid = Q.New(VmInstanceVO.class).select(VmInstanceVO_.lastHostUuid).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).findValue(); FlowChain chain = new SimpleFlowChain(); chain.setName(String.format("local-storage-%s-migrate-volume-%s-to-host-%s", msg.getPrimaryStorageUuid(), msg.getVolumeUuid(), msg.getDestHostUuid())); chain.then(new Flow() { @@ -494,7 +500,7 @@ public void handle(Map data) { /* update vm last host uuid */ SQL.New(VmInstanceVO.class) .eq(VmInstanceVO_.uuid, struct.getVmUuid()) - .set(VmInstanceVO_.lastHostUuid, msg.getDestHostUuid()) + .set(VmInstanceVO_.lastHostUuid, lastHostUuid) .update(); bus.publish(evt); @@ -839,6 +845,14 @@ public void handleLocalMessage(Message msg) { handle((GetDownloadBitsFromKVMHostProgressMsg) msg); } else if ((msg instanceof LocalStorageRecalculateCapacityMsg)) { handle((LocalStorageRecalculateCapacityMsg) msg); + } else if (msg instanceof GetVolumeBackingChainFromPrimaryStorageMsg) { + handle((GetVolumeBackingChainFromPrimaryStorageMsg) msg); + } else if (msg instanceof GetPrimaryStorageUsageReportMsg) { + handle((GetPrimaryStorageUsageReportMsg) msg); + } else if (msg instanceof CommitVolumeSnapshotOnPrimaryStorageMsg) { + handle((CommitVolumeSnapshotOnPrimaryStorageMsg) msg); + } else if (msg instanceof PullVolumeSnapshotOnPrimaryStorageMsg) { + handle((PullVolumeSnapshotOnPrimaryStorageMsg) msg); } else { super.handleLocalMessage(msg); } @@ -898,10 +912,9 @@ public void fail(ErrorCode errorCode) { @Override protected void handle(APICleanUpImageCacheOnPrimaryStorageMsg msg) { - APICleanUpImageCacheOnPrimaryStorageEvent evt = new APICleanUpImageCacheOnPrimaryStorageEvent(msg.getId()); - imageCacheCleaner.setForce(msg.isForce()); - imageCacheCleaner.cleanup(msg.getUuid(), false); - bus.publish(evt); + APICleanUpImageCacheOnPrimaryStorageEvent evt = new APICleanUpImageCacheOnPrimaryStorageEvent(msg.getId()); + imageCacheCleaner.cleanup(msg.getUuid(), new ImageCacheCleanParam(true, msg.isForce())); + bus.publish(evt); } @@ -940,6 +953,39 @@ public void fail(ErrorCode errorCode) { }); } + private void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg) { + String hostUuid; + if (msg.getHostUuid() == null) { + hostUuid = getHostUuidByResourceUuid(msg.getVolumeUuid()); + msg.setHostUuid(hostUuid); + } + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(msg.getHostUuid()); + LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + bkd.handle(msg, new ReturnValueCompletion(msg) { + @Override + public void success(GetVolumeBackingChainFromPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(GetPrimaryStorageUsageReportMsg msg) { + GetPrimaryStorageUsedPhysicalCapacityForecastReply reply = new GetPrimaryStorageUsedPhysicalCapacityForecastReply(); + reply.setUsageReportMap(localForecaster.getUsageReportByResourceUuids(getHostUuidsFromPoolUris(msg.getUris()))); + bus.reply(msg, reply); + } + + private List getHostUuidsFromPoolUris(List uris) { + return uris.stream().map(uri -> uri.replace("hostUuid://", "")).collect(Collectors.toList()); + } + private void handle(final UploadBitsFromLocalStorageToBackupStorageMsg msg) { LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(msg.getHostUuid()); LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); @@ -1216,15 +1262,36 @@ protected void handle(final MergeVolumeSnapshotOnPrimaryStorageMsg msg) { final String hostUuid = getHostUuidByResourceUuid(msg.getTo().getUuid()); LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid); LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); - bkd.handle(msg, hostUuid, new ReturnValueCompletion(msg) { + MergeVolumeSnapshotOnPrimaryStorageReply r = new MergeVolumeSnapshotOnPrimaryStorageReply(); + bkd.stream(msg.getFrom(), msg.getTo(), msg.isFullRebase(), hostUuid, new Completion(msg) { @Override - public void success(MergeVolumeSnapshotOnPrimaryStorageReply returnValue) { - bus.reply(msg, returnValue); + public void success() { + bus.reply(msg, r); + } + + @Override + public void fail(ErrorCode errorCode) { + r.setError(errorCode); + bus.reply(msg, r); + } + }); + } + + @Override + protected void handle(FlattenVolumeOnPrimaryStorageMsg msg) { + final String hostUuid = getHostUuidByResourceUuid(msg.getVolume().getUuid()); + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid); + LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + + FlattenVolumeOnPrimaryStorageReply r = new FlattenVolumeOnPrimaryStorageReply(); + bkd.stream(null, msg.getVolume(), true, hostUuid, new Completion(msg) { + @Override + public void success() { + bus.reply(msg, r); } @Override public void fail(ErrorCode errorCode) { - MergeVolumeSnapshotOnPrimaryStorageReply r = new MergeVolumeSnapshotOnPrimaryStorageReply(); r.setError(errorCode); bus.reply(msg, r); } @@ -1389,7 +1456,7 @@ protected void handle(final DeleteSnapshotOnPrimaryStorageMsg msg) { FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("delete-snapshot-%s-on-local-storage-%s", msg.getSnapshot().getUuid(), self.getUuid())); chain.then(new ShareFlow() { - DeleteSnapshotOnPrimaryStorageReply reply; + DeleteSnapshotOnPrimaryStorageReply reply = new DeleteSnapshotOnPrimaryStorageReply(); @Override public void setup() { @@ -1400,10 +1467,9 @@ public void setup() { public void run(final FlowTrigger trigger, Map data) { LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid); LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); - bkd.handle(msg, hostUuid, new ReturnValueCompletion(trigger) { + bkd.deleteBits(msg.getSnapshot().getPrimaryStorageInstallPath(), hostUuid, new Completion(trigger) { @Override - public void success(DeleteSnapshotOnPrimaryStorageReply returnValue) { - reply = returnValue; + public void success() { trigger.next(); } @@ -1486,6 +1552,46 @@ public void fail(ErrorCode errorCode) { }); } + private void handle(final CommitVolumeSnapshotOnPrimaryStorageMsg msg) { + final String hostUuid = getHostUuidByResourceUuid(msg.getVolume().getUuid()); + + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid); + LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + bkd.handle(msg, hostUuid, new ReturnValueCompletion(msg) { + @Override + public void success(CommitVolumeSnapshotOnPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + CommitVolumeSnapshotOnPrimaryStorageReply reply = new CommitVolumeSnapshotOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(final PullVolumeSnapshotOnPrimaryStorageMsg msg) { + final String hostUuid = getHostUuidByResourceUuid(msg.getVolume().getUuid()); + + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid); + LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + bkd.handle(msg, hostUuid, new ReturnValueCompletion(msg) { + @Override + public void success(PullVolumeSnapshotOnPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + PullVolumeSnapshotOnPrimaryStorageReply reply = new PullVolumeSnapshotOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + private void handle(RemoveHostFromLocalStorageMsg msg) { RemoveHostFromLocalStorageReply reply = new RemoveHostFromLocalStorageReply(); thdf.chainSubmit(new ChainTask(msg) { @@ -1811,12 +1917,21 @@ public void success(PhysicalCapacityUsage usage) { ref.setSystemUsedCapacity(c.totalPhysicalSize - c.availablePhysicalSize - c.localStorageUsedSize); dbf.persist(ref); - increaseCapacity( - c.totalPhysicalSize, - c.availablePhysicalSize, - c.totalPhysicalSize, - c.availablePhysicalSize, - ref.getSystemUsedCapacity()); + if (msg.isNewAddedHost()) { + increaseCapacity( + c.totalPhysicalSize, + c.availablePhysicalSize, + c.totalPhysicalSize, + c.availablePhysicalSize, + ref.getSystemUsedCapacity()); + } else { + // this happened when manually delete LocalStorageHostRefVO + LocalStorageRecalculateCapacityMsg rmsg = new LocalStorageRecalculateCapacityMsg(); + rmsg.setPrimaryStorageUuid(self.getUuid()); + rmsg.setNeedRecalculateRef(true); + bus.makeTargetServiceIdByResourceUuid(rmsg, PrimaryStorageConstant.SERVICE_ID, self.getUuid()); + bus.send(rmsg); + } } else { ref = refs.get(0); long originSystemUsed = ref.getSystemUsedCapacity(); @@ -1855,7 +1970,10 @@ public void fail(ErrorCode errorCode) { @Override public void run(FlowTrigger trigger, Map data) { HostInventory host = HostInventory.valueOf(dbf.findByUuid(msg.getHostUuid(), HostVO.class)); - checkLocalStoragePrimaryStorageInitilized(CollectionDSL.list(host), true, new Completion(trigger) { + LocalStorageInitParam param = new LocalStorageInitParam(); + param.setNewAdded(false); + param.setNeedInitOnHost(true); + checkLocalStoragePrimaryStorageInitilized(param, CollectionDSL.list(host), new Completion(trigger) { @Override public void success() { trigger.next(); @@ -1993,6 +2111,7 @@ protected void handle(final InstantiateVolumeOnPrimaryStorageMsg msg) { String hostUuid = msg.getDestHost().getUuid(); LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(hostUuid); final LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + final long size = msg.getVolume().getSize(); FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("instantiate-volume-%s-local-primary-storage-%s", msg.getVolume().getUuid(), self.getUuid())); @@ -2026,7 +2145,7 @@ public void fail(ErrorCode errorCode) { @Override public void handle(Map data) { createResourceRefVO(msg.getVolume().getUuid(), VolumeVO.class.getSimpleName(), - msg.getVolume().getSize(), finalHostUuid); + msg.getVolume().getSize() == 0 ? size : msg.getVolume().getSize(), finalHostUuid); bus.reply(msg, reply); } }); @@ -2203,11 +2322,15 @@ public void fail(ErrorCode errorCode) { @Override protected void handle(final DownloadDataVolumeToPrimaryStorageMsg msg) { - if (msg.getHostUuid() == null) { + if (msg.getHostUuid() == null && msg.getAllocatedInstallUrl() == null) { throw new OperationFailureException(operr("unable to create the data volume[uuid: %s] on a local primary storage[uuid:%s], because the hostUuid is not specified.", msg.getVolumeUuid(), self.getUuid())); } + if (msg.getAllocatedInstallUrl() != null) { + msg.setHostUuid(getHostUuidFromInstallUrl(msg.getAllocatedInstallUrl())); + } + FlowChain chain = FlowChainBuilder.newShareFlowChain(); chain.setName(String.format("download-data-volume-%s-to-local-storage-%s", msg.getVolumeUuid(), self.getUuid())); chain.then(new ShareFlow() { @@ -2262,11 +2385,15 @@ public void handle(ErrorCode errCode, Map data) { @Override protected void handle(GetInstallPathForDataVolumeDownloadMsg msg) { - if (msg.getHostUuid() == null) { + if (msg.getHostUuid() == null && msg.getAllocatedInstallUrl() == null) { throw new OperationFailureException(operr("unable to create the data volume[uuid: %s] on a local primary storage[uuid:%s], because the hostUuid is not specified.", msg.getVolumeUuid(), self.getUuid())); } + if (msg.getAllocatedInstallUrl() != null) { + msg.setHostUuid(getHostUuidFromInstallUrl(msg.getAllocatedInstallUrl())); + } + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(msg.getHostUuid()); LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); bkd.handle(msg, new ReturnValueCompletion(msg) { @@ -2545,6 +2672,7 @@ protected void handle(AskVolumeSnapshotCapabilityMsg msg) { String volumeType = msg.getVolume().getType(); if (VolumeType.Data.toString().equals(volumeType) || VolumeType.Root.toString().equals(volumeType)) { capability.setArrangementType(VolumeSnapshotArrangementType.CHAIN); + capability.setPlacementType(VolumeSnapshotCapability.VolumeSnapshotPlacementType.EXTERNAL); } else if (VolumeType.Memory.toString().equals(volumeType)) { capability.setArrangementType(VolumeSnapshotArrangementType.INDIVIDUAL); } else { @@ -2576,6 +2704,44 @@ public void fail(ErrorCode errorCode) { }); } + @Override + protected void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg) { + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByResourceUuid(msg.getVolumeUuid(), VolumeVO.class.getSimpleName()); + LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + String huuid = getHostUuidByResourceUuid(msg.getVolumeUuid()); + bkd.handle(msg, huuid, new ReturnValueCompletion(msg) { + @Override + public void success(EstimateVolumeTemplateSizeOnPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(BatchSyncVolumeSizeOnPrimaryStorageMsg msg) { + LocalStorageHypervisorFactory f = getHypervisorBackendFactoryByHostUuid(msg.getHostUuid()); + LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); + bkd.handle(msg, msg.getHostUuid(), new ReturnValueCompletion(msg) { + @Override + public void success(BatchSyncVolumeSizeOnPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + @Override + public void fail(ErrorCode errorCode) { + BatchSyncVolumeSizeOnPrimaryStorageReply reply = new BatchSyncVolumeSizeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + protected void saveVolumeProvisioningStrategy(String volumeUuid, VolumeProvisioningStrategy strategy) { if (!VolumeSystemTags.VOLUME_PROVISIONING_STRATEGY.hasTag(volumeUuid)) { SystemTagCreator tagCreator = VolumeSystemTags.VOLUME_PROVISIONING_STRATEGY.newSystemTagCreator(volumeUuid); @@ -2702,8 +2868,52 @@ protected List getAllFactoriesForAttachedClusters() { return new ArrayList(m.values()); } + enum ConnectReason { + Reconnect, + Other + } + + static class LocalStorageInitParam { + private boolean isNewAdded; + private boolean needInitOnHost; + private ConnectReason reason; + + public boolean isNewAdded() { + return isNewAdded; + } + + public void setNewAdded(boolean newAdded) { + isNewAdded = newAdded; + } + + public ConnectReason getReason() { + return reason; + } + + public void setReason(ConnectReason reason) { + this.reason = reason; + } + + public boolean isNeedInitOnHost() { + return needInitOnHost; + } + + public void setNeedInitOnHost(boolean needInitOnHost) { + this.needInitOnHost = needInitOnHost; + } + + static LocalStorageInitParam fromConnectParam(ConnectParam param) { + LocalStorageInitParam localStorageInitParam = new LocalStorageInitParam(); + localStorageInitParam.isNewAdded = param.isNewAdded(); + return localStorageInitParam; + } + } + @Override protected void connectHook(final ConnectParam param, final Completion completion) { + LocalStorageInitParam localStorageInitParam = LocalStorageInitParam.fromConnectParam(param); + localStorageInitParam.setReason(ConnectReason.Reconnect); + localStorageInitParam.setNeedInitOnHost(true); FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName("connect localstorage host hook"); chain.then(new NoRollbackFlow() { @@ -2711,7 +2921,7 @@ protected void connectHook(final ConnectParam param, final Completion completion @Override public void run(FlowTrigger trigger, Map data) { - checkLocalStoragePrimaryStorageInitilized(param.isNewAdded(), true, new Completion(trigger) { + checkLocalStoragePrimaryStorageInitilized(localStorageInitParam, new Completion(trigger) { @Override public void success() { trigger.next(); @@ -2783,34 +2993,41 @@ private boolean hostHasInitializedTag(String hostUuid) { return false; } - private void checkLocalStoragePrimaryStorageInitilized(boolean isNewAdded, boolean initialized, Completion completion) { + private void checkLocalStoragePrimaryStorageInitilized(LocalStorageInitParam param, Completion completion) { List hosts = getLocalStorageHosts(); - if (!isNewAdded && hosts.size() == 0) { + if (!param.isNewAdded && hosts.size() == 0) { completion.fail(operr("No Host state is Enabled, Please check the availability of the host")); } else { - checkLocalStoragePrimaryStorageInitilized(hosts, initialized, completion); + checkLocalStoragePrimaryStorageInitilized(param, hosts, completion); } } - private void checkLocalStoragePrimaryStorageInitilized(List hosts, boolean initialized, Completion completion) { + private void checkLocalStoragePrimaryStorageInitilized(LocalStorageInitParam param, List hosts, Completion completion) { new While<>(hosts).all((host, com) -> { + if (upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(host.getUuid())) { + com.done(); + return; + } + if (hostHasInitializedTag(host.getUuid())) { LocalStorageHypervisorFactory f = getHypervisorBackendFactory(host.getHypervisorType()); LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); - bkd.checkHostAttachedPSMountPath(host.getUuid(), new Completion(com) { + bkd.checkHostAttachedPSMountPath(host.getUuid(), new ReturnValueCompletion(com) { @Override - public void success() { + public void success(LocalStorageKvmBackend.CheckInitializedFileRsp rsp) { + if (!rsp.existed) { + sendWarnning(host.getUuid(), rsp.getError(), getSelfInventory()); + } com.done(); } @Override public void fail(ErrorCode errorCode) { - sendWarnning(host.getUuid(), errorCode.getDetails(), getSelfInventory()); com.done(); } }); } else { - if (initialized) { + if (param.isNeedInitOnHost()) { LocalStorageHypervisorFactory f = getHypervisorBackendFactory(host.getHypervisorType()); LocalStorageHypervisorBackend bkd = f.getHypervisorBackend(self); bkd.initializeHostAttachedPSMountPath(host.getUuid(), new Completion(com) { @@ -2844,7 +3061,10 @@ public void done(ErrorCodeList errorCodeList) { @Override protected void pingHook(Completion completion) { - checkLocalStoragePrimaryStorageInitilized(true, false, completion); + LocalStorageInitParam param = new LocalStorageInitParam(); + param.setNewAdded(true); + param.setNeedInitOnHost(false); + checkLocalStoragePrimaryStorageInitilized(param, completion); } @Override @@ -3049,8 +3269,38 @@ protected void handle(CheckVolumeSnapshotOperationOnPrimaryStorageMsg msg) { bus.reply(msg, r); } + private ErrorCode checkChangeVolumeType(String volumeUuid) { + List refVols = VolumeSnapshotReferenceUtils.getReferenceVolume(volumeUuid); + if (refVols.isEmpty()) { + return null; + } + + List infos = refVols.stream().map(v -> String.format("uuid:%s, name:%s", v.getUuid(), v.getName())).collect(Collectors.toList()); + return operr("volume[uuid:%s] has reference volume[%s], can not change volume type before flatten " + + "them and their descendants", volumeUuid, infos.toString()); + } + + @Override + protected void handle(CheckChangeVolumeTypeOnPrimaryStorageMsg msg) { + CheckChangeVolumeTypeOnPrimaryStorageReply reply = new CheckChangeVolumeTypeOnPrimaryStorageReply(); + ErrorCode errorCode = checkChangeVolumeType(msg.getVolume().getUuid()); + if (errorCode != null) { + reply.setError(errorCode);; + } + + bus.reply(msg, reply); + } + @Override protected void handle(ChangeVolumeTypeOnPrimaryStorageMsg msg) { + ErrorCode errorCode = checkChangeVolumeType(msg.getVolume().getUuid()); + if (errorCode != null) { + ChangeVolumeTypeOnPrimaryStorageReply reply = new ChangeVolumeTypeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + return; + } + LocalStorageHypervisorFactory factory = getHypervisorBackendFactoryByResourceUuid(msg.getVolume().getUuid(), VolumeVO.class.getSimpleName()); factory.getHypervisorBackend(self).handle(msg, new ReturnValueCompletion(msg) { @Override @@ -3066,6 +3316,23 @@ public void fail(ErrorCode errorCode) { } }); } + @Override + protected void handle(UnlinkBitsOnPrimaryStorageMsg msg) { + LocalStorageHypervisorFactory factory = getHypervisorBackendFactoryByResourceUuid(msg.getResourceUuid(), msg.getResourceType()); + factory.getHypervisorBackend(self).handle(msg, new ReturnValueCompletion(msg) { + @Override + public void success(UnlinkBitsOnPrimaryStorageReply reply) { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + UnlinkBitsOnPrimaryStorageReply r = new UnlinkBitsOnPrimaryStorageReply(); + r.setError(errorCode); + bus.reply(msg, r); + } + }); + } public static class LocalStoragePhysicalCapacityUsage extends PrimaryStorageBase.PhysicalCapacityUsage { public long localStorageUsedSize; diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageCanonicalEvents.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageCanonicalEvents.java index 3ecc81987cc..cc97d3eadce 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageCanonicalEvents.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageCanonicalEvents.java @@ -12,6 +12,14 @@ public static class LocalStorageImageDistributedToImageCacheEvent { public String localStorageUuid; public ImageInventory image; + public void setImage(ImageInventory image) { + this.image = image; + } + + public ImageInventory getImage() { + return this.image; + } + public void fire() { EventFacade evtf = Platform.getComponentLoader().getComponent(EventFacade.class); evtf.fire(IMAGE_DISTRIBUTED_TO_IMAGE_CACHE, this); diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java index f2d6fae8ddd..8db3bb843b3 100644 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDefaultAllocateCapacityFlow.java @@ -146,24 +146,24 @@ public void run(final FlowTrigger trigger, Map data) { rmsg.setAllocationStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY); rmsg.setVmInstanceUuid(spec.getVmInventory().getUuid()); if (spec.getImageSpec() != null) { - rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); + if (spec.getImageSpec().getInventory() != null) { + rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); + } Optional.ofNullable(spec.getImageSpec().getSelectedBackupStorage()) .ifPresent(it -> rmsg.setBackupStorageUuid(it.getBackupStorageUuid())); } rmsg.setRequiredPrimaryStorageUuid(localStorageUuid); rmsg.setRequiredHostUuid(spec.getDestHost().getUuid()); - if (ImageMediaType.ISO.toString().equals(spec.getImageSpec().getInventory().getMediaType())) { - rmsg.setSize(spec.getRootDiskOffering().getDiskSize()); + rmsg.setSize(spec.getRootDiskAllocateSize()); + rmsg.setSystemTags(spec.getRootVolumeSystemTags()); + if (spec.getRootDiskOffering() != null) { rmsg.setDiskOfferingUuid(spec.getRootDiskOffering().getUuid()); - } else { - //TODO: find a way to allow specifying strategy for root disk - rmsg.setSize(spec.getImageSpec().getInventory().getSize()); } if (spec.getCurrentVmOperation() == VmOperation.NewCreate) { rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateNewVm.toString()); } else if (spec.getCurrentVmOperation() == VmOperation.AttachVolume) { - rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString()); + rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); } bus.makeLocalServiceId(rmsg, PrimaryStorageConstant.SERVICE_ID); @@ -209,9 +209,14 @@ public void run(final FlowTrigger trigger, Map data) { amsg.setRequiredPrimaryStorageUuid(getRequiredStorageUuid(spec.getDestHost().getUuid(), spec.getRequiredPrimaryStorageUuidForDataVolume())); } - amsg.setPossiblePrimaryStorageTypes(primaryStorageTypes); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); amsg.setDiskOfferingUuid(dinv.getUuid()); - rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); + + if (spec.getImageSpec().getInventory() != null) { + rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); + } + + amsg.setSystemTags(spec.getDataVolumeSystemTags()); bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); msgs.add(amsg); } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDeleteBitsGC.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDeleteBitsGC.java index 1e324ce4191..4404e09ef3c 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDeleteBitsGC.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDeleteBitsGC.java @@ -1,5 +1,6 @@ package org.zstack.storage.primary.local; +import org.apache.commons.lang.StringUtils; import org.zstack.core.db.Q; import org.zstack.core.gc.EventBasedGarbageCollector; import org.zstack.core.gc.GC; @@ -9,14 +10,15 @@ import org.zstack.header.host.HostCanonicalEvents; import org.zstack.header.host.HostStatus; import org.zstack.header.host.HostVO; -import org.zstack.header.host.HostVO_; import org.zstack.header.storage.primary.PrimaryStorageCanonicalEvent; import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.header.storage.primary.PrimaryStorageVO_; import org.zstack.kvm.KvmCommandFailureChecker; import org.zstack.kvm.KvmCommandSender; import org.zstack.kvm.KvmResponseWrapper; -import static org.zstack.core.Platform.operr; +import org.zstack.storage.volume.VolumeErrors; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; /** * Created by xing5 on 2017/3/5. @@ -30,6 +32,7 @@ public class LocalStorageDeleteBitsGC extends EventBasedGarbageCollector { public String installPath; @GC public boolean isDir; + private static CLogger logger = Utils.getLogger(LocalStorageDeleteBitsGC.class); @Override protected void triggerNow(GCCompletion completion) { @@ -38,7 +41,7 @@ protected void triggerNow(GCCompletion completion) { return; } - if (!dbf.isExist(hostUuid, HostVO.class)) { + if (!dbf.isExist(hostUuid, HostVO.class) || StringUtils.isEmpty(installPath)) { completion.cancel(); return; } @@ -58,7 +61,7 @@ protected void triggerNow(GCCompletion completion) { @Override public ErrorCode getError(KvmResponseWrapper wrapper) { LocalStorageKvmBackend.DeleteBitsRsp rsp = wrapper.getResponse(LocalStorageKvmBackend.DeleteBitsRsp.class); - return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); + return rsp.buildErrorCode(); } }, @@ -70,6 +73,10 @@ public void success(KvmResponseWrapper ret) { @Override public void fail(ErrorCode errorCode) { + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + completion.cancel(); + return; + } completion.fail(errorCode); } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java index 06d2112009d..2c7b909827f 100644 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageDesignatedAllocateCapacityFlow.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.compute.allocator.HostAllocatorManager; +import org.zstack.compute.vm.VmAllocatePrimaryStorageFlow; import org.zstack.core.asyncbatch.AsyncLoop; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; @@ -28,7 +29,10 @@ import org.zstack.header.volume.VolumeType; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; +import org.zstack.utils.Utils; import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -44,6 +48,7 @@ */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class LocalStorageDesignatedAllocateCapacityFlow implements Flow { + private static final CLogger logger = Utils.getLogger(LocalStorageDesignatedAllocateCapacityFlow.class); @Autowired protected DatabaseFacade dbf; @@ -63,7 +68,7 @@ public void run(final FlowTrigger trigger, Map data) { return; } - AllocatePrimaryStorageSpaceMsg rootVolumeAllocationMsg =getRootVolumeAllocationMsg(spec); + AllocatePrimaryStorageSpaceMsg rootVolumeAllocationMsg = getRootVolumeAllocationMsg(spec); msgs.add(rootVolumeAllocationMsg); List dataVolumeAllocationMsgs = getDataVolumeAllocationMsgs(spec); msgs.addAll(dataVolumeAllocationMsgs); @@ -90,6 +95,7 @@ public void run(MessageReply reply) { if (msg == rootVolumeAllocationMsg) { vspec.setSize(ar.getSize()); vspec.setPrimaryStorageInventory(ar.getPrimaryStorageInventory()); + vspec.setDiskOfferingUuid(msg.getDiskOfferingUuid()); vspec.setType(VolumeType.Root.toString()); } else { vspec.setSize(ar.getSize()); @@ -116,8 +122,8 @@ protected void error(ErrorCode errorCode) { }.start(); } - private ErrorCode checkIfSpecifyPrimaryStorage(VmInstanceSpec spec){ - if(spec.getRequiredPrimaryStorageUuidForRootVolume() == null){ + private ErrorCode checkIfSpecifyPrimaryStorage(VmInstanceSpec spec) { + if (spec.getRequiredPrimaryStorageUuidForRootVolume() == null) { ErrorCode errorCode = operr("The cluster[uuid=%s] mounts multiple primary storage[LocalStorage, other non-LocalStorage primary storage], You must specify the primary storage where the root disk is located", spec.getDestHost().getClusterUuid()); return errorCode; @@ -145,23 +151,21 @@ private AllocatePrimaryStorageSpaceMsg getRootVolumeAllocationMsg(VmInstanceSpec AllocatePrimaryStorageSpaceMsg rmsg = new AllocatePrimaryStorageSpaceMsg(); rmsg.setVmInstanceUuid(spec.getVmInventory().getUuid()); - if (spec.getImageSpec() != null) { + if (spec.getImageSpec() != null && spec.getImageSpec().getInventory() != null) { rmsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); } rmsg.setRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForRootVolume()); rmsg.setRequiredHostUuid(spec.getDestHost().getUuid()); - if (ImageMediaType.ISO.toString().equals(spec.getImageSpec().getInventory().getMediaType())) { - rmsg.setSize(spec.getRootDiskOffering().getDiskSize()); + rmsg.setSize(spec.getRootDiskAllocateSize()); + rmsg.setSystemTags(spec.getRootVolumeSystemTags()); + if (spec.getRootDiskOffering() != null) { rmsg.setDiskOfferingUuid(spec.getRootDiskOffering().getUuid()); - } else { - //TODO: find a way to allow specifying strategy for root disk - rmsg.setSize(spec.getImageSpec().getInventory().getSize()); } if (spec.getCurrentVmOperation() == VmOperation.NewCreate) { rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateNewVm.toString()); } else if (spec.getCurrentVmOperation() == VmOperation.AttachVolume) { - rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateVolume.toString()); + rmsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); } String requiredPrimaryStorageType = Q.New(PrimaryStorageVO.class) @@ -185,17 +189,12 @@ private List getDataVolumeAllocationMsgs(VmInst return msgs; } - String bsType = Q.New(BackupStorageVO.class) - .select(BackupStorageVO_.type) - .eq(BackupStorageVO_.uuid,spec.getImageSpec().getSelectedBackupStorage().getBackupStorageUuid()) - .findValue(); - List primaryStorageTypes = hostAllocatorMgr.getBackupStoragePrimaryStorageMetrics().get(bsType); - for (DiskOfferingInventory dinv : spec.getDataDiskOfferings()) { AllocatePrimaryStorageSpaceMsg amsg = new AllocatePrimaryStorageSpaceMsg(); amsg.setSize(dinv.getDiskSize()); amsg.setRequiredHostUuid(spec.getDestHost().getUuid()); amsg.setRequiredPrimaryStorageUuid(spec.getRequiredPrimaryStorageUuidForDataVolume()); + amsg.setSystemTags(spec.getDataVolumeSystemTags()); String requiredPrimaryStorageType = Q.New(PrimaryStorageVO.class) .select(PrimaryStorageVO_.type) @@ -205,9 +204,9 @@ private List getDataVolumeAllocationMsgs(VmInst amsg.setAllocationStrategy(LocalStorageConstants.LOCAL_STORAGE_ALLOCATOR_STRATEGY); } - amsg.setPossiblePrimaryStorageTypes(primaryStorageTypes); + amsg.setPurpose(PrimaryStorageAllocationPurpose.CreateDataVolume.toString()); amsg.setDiskOfferingUuid(dinv.getUuid()); - if (spec.getImageSpec() != null) { + if (spec.getImageSpec() != null && spec.getImageSpec().getInventory() != null) { amsg.setImageUuid(spec.getImageSpec().getInventory().getUuid()); } bus.makeLocalServiceId(amsg, PrimaryStorageConstant.SERVICE_ID); diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java index 100bfe8dae4..c2ebefbc5c8 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageFactory.java @@ -1,7 +1,9 @@ package org.zstack.storage.primary.local; import com.google.common.collect.Lists; +import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.host.MigrateNetworkExtensionPoint; import org.zstack.compute.vm.*; @@ -18,9 +20,7 @@ import org.zstack.header.Component; import org.zstack.header.allocator.HostAllocatorError; import org.zstack.header.configuration.userconfig.DiskOfferingUserConfig; -import org.zstack.header.core.Completion; -import org.zstack.header.core.FutureCompletion; -import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.*; import org.zstack.header.core.trash.InstallPathRecycleVO; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; @@ -42,22 +42,27 @@ import org.zstack.header.storage.backup.DeleteBitsOnBackupStorageMsg; import org.zstack.header.storage.primary.*; import org.zstack.header.storage.snapshot.*; +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupInventory; import org.zstack.header.vm.*; import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.volume.*; import org.zstack.kvm.KVMConstant; import org.zstack.storage.primary.PrimaryStorageCapacityChecker; import org.zstack.storage.snapshot.PostMarkRootVolumeAsSnapshotExtension; +import org.zstack.storage.snapshot.reference.VolumeSnapshotReferenceUtils; +import org.zstack.storage.volume.ChangeVolumeInstallPathExtensionPoint; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; +import javax.persistence.Tuple; import javax.persistence.TypedQuery; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.err; @@ -72,8 +77,9 @@ public class LocalStorageFactory implements PrimaryStorageFactory, Component, GetAttachableVolumeExtensionPoint, HostMaintenancePolicyExtensionPoint, AddExpandedQueryExtensionPoint, VolumeGetAttachableVmExtensionPoint, RecoverDataVolumeExtensionPoint, RecoverVmExtensionPoint, VmPreMigrationExtensionPoint, CreateTemplateFromVolumeSnapshotExtensionPoint, HostAfterConnectedExtensionPoint, InstantiateDataVolumeOnCreationExtensionPoint, PrimaryStorageAttachExtensionPoint, - PostMarkRootVolumeAsSnapshotExtension, AfterTakeLiveSnapshotsOnVolumes, VmCapabilitiesExtensionPoint, PrimaryStorageDetachExtensionPoint, - CreateRecycleExtensionPoint, AfterInstantiateVolumeExtensionPoint, CreateDataVolumeExtensionPoint { + PostMarkRootVolumeAsSnapshotExtension, VolumeSnapshotCreationExtensionPoint, VmCapabilitiesExtensionPoint, PrimaryStorageDetachExtensionPoint, + CreateRecycleExtensionPoint, AfterInstantiateVolumeExtensionPoint, CreateDataVolumeExtensionPoint, OverwriteVolumeExtensionPoint { + private final static CLogger logger = Utils.getLogger(LocalStorageFactory.class); public static PrimaryStorageType type = new PrimaryStorageType(LocalStorageConstants.LOCAL_STORAGE_TYPE) { @Override @@ -283,6 +289,11 @@ public PrimaryStorageInventory getInventory(String uuid) { return PrimaryStorageInventory.valueOf(dbf.findByUuid(uuid, PrimaryStorageVO.class)); } + @Override + public void validateStorageProtocol(String protocol) { + + } + private String makeMediatorKey(String hvType, String bsType) { return hvType + "-" + bsType; } @@ -342,6 +353,10 @@ public void beforeDeliveryMessage(Message msg) { } }, ResizeVolumeOnHypervisorReply.class); + VolumeSnapshotReferenceUtils.setGetResourceLocateHostUuidGetter(resourceUuid -> Q.New(LocalStorageResourceRefVO.class) + .select(LocalStorageResourceRefVO_.hostUuid) + .eq(LocalStorageResourceRefVO_.resourceUuid, resourceUuid) + .findValue()); return true; } @@ -351,15 +366,19 @@ public boolean stop() { } @Transactional(readOnly = true) - private List getLocalStorageInCluster(String clusterUuid) { + private List getAvailableLocalStorageInCluster(String clusterUuid) { String sql = "select pri.uuid" + " from PrimaryStorageVO pri, PrimaryStorageClusterRefVO ref" + " where pri.uuid = ref.primaryStorageUuid" + " and ref.clusterUuid = :cuuid" + - " and pri.type = :ptype"; + " and pri.type = :ptype" + + " and pri.state = :state" + + " and pri.status = :status"; TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("cuuid", clusterUuid); q.setParameter("ptype", LocalStorageConstants.LOCAL_STORAGE_TYPE); + q.setParameter("state", PrimaryStorageState.Enabled); + q.setParameter("status", PrimaryStorageStatus.Connected); return q.getResultList(); } @@ -371,24 +390,69 @@ private boolean isRootVolumeOnLocalStorage(String rootVolumeUuid) { @Override public Flow marshalVmOperationFlow(String previousFlowName, String nextFlowName, FlowChain chain, VmInstanceSpec spec) { + if (VmAllocateHostFlow.class.getName().equals(nextFlowName) || VmAllocateHostAndPrimaryStorageFlow.class.getName().equals(nextFlowName)) { + if (spec.getCurrentVmOperation() != VmOperation.NewCreate || !spec.getImageSpec().relyOnImageCache()) { + return null; + } + + String imageUuid = spec.getImageSpec().getInventory().getUuid(); + String requirdHostUuid = spec.getRequiredHostUuid(); + List cacheUrls = Q.New(ImageCacheVO.class).select(ImageCacheVO_.installUrl) + .eq(ImageCacheVO_.imageUuid, imageUuid) + .listValues(); + + if (!cacheUrls.stream().allMatch(it -> it.contains("hostUuid://"))) { + return null; + } + + List cachedHostUuids = cacheUrls.stream().map(it -> LocalStorageUtils.getHostUuidFromInstallUrl(it)).collect(Collectors.toList()); + if (requirdHostUuid != null && !cachedHostUuids.contains(requirdHostUuid)) { + return new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + trigger.fail(operr("creation rely on image cache[uuid:%s, locate host uuids: [%s]], cannot create other places.", imageUuid, cachedHostUuids)); + + } + }; + } else if (requirdHostUuid == null) { + spec.setRequiredHostUuid(cachedHostUuids.get(0)); + } + } + if (VmAllocatePrimaryStorageFlow.class.getName().equals(nextFlowName)) { if (spec.getCurrentVmOperation() == VmOperation.NewCreate) { - List localStorageUuids = getLocalStorageInCluster(spec.getDestHost().getClusterUuid()); - if (localStorageUuids != null && !localStorageUuids.isEmpty()) { - boolean isOnlyLocalStorage = SQL.New("select pri.uuid" + - " from PrimaryStorageVO pri, PrimaryStorageClusterRefVO ref" + - " where pri.uuid = ref.primaryStorageUuid" + - " and ref.clusterUuid = :cuuid" + - " and pri.type != :ptype", String.class) - .param("cuuid", spec.getDestHost().getClusterUuid()) - .param("ptype", LocalStorageConstants.LOCAL_STORAGE_TYPE) - .list().isEmpty(); - - if(!isOnlyLocalStorage && (spec.getRequiredPrimaryStorageUuidForRootVolume() != null || spec.getRequiredPrimaryStorageUuidForDataVolume() != null)){ - return new LocalStorageDesignatedAllocateCapacityFlow(); - }else{ - return new LocalStorageDefaultAllocateCapacityFlow(); - } + List localStorageUuids = getAvailableLocalStorageInCluster(spec.getDestHost().getClusterUuid()); + if (CollectionUtils.isEmpty(localStorageUuids)) { + return null; + } + + boolean requireNoneLocalStorage = spec.getRequiredPrimaryStorageUuidForRootVolume() != null && Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.uuid, spec.getRequiredPrimaryStorageUuidForRootVolume()) + .notEq(PrimaryStorageVO_.type, LocalStorageConstants.LOCAL_STORAGE_TYPE) + .isExists(); + requireNoneLocalStorage = requireNoneLocalStorage && (spec.getDataDiskOfferings().isEmpty() || + spec.getRequiredPrimaryStorageUuidForDataVolume() != null && Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.uuid, spec.getRequiredPrimaryStorageUuidForDataVolume()) + .notEq(PrimaryStorageVO_.type, LocalStorageConstants.LOCAL_STORAGE_TYPE) + .isExists()); + if (requireNoneLocalStorage) { + return null; + } + + boolean isOnlyLocalStorage = SQL.New("select pri.uuid" + + " from PrimaryStorageVO pri, PrimaryStorageClusterRefVO ref" + + " where pri.uuid = ref.primaryStorageUuid" + + " and ref.clusterUuid = :cuuid" + + " and pri.type != :ptype", String.class) + .param("cuuid", spec.getDestHost().getClusterUuid()) + .param("ptype", LocalStorageConstants.LOCAL_STORAGE_TYPE) + .list().isEmpty(); + + if (!isOnlyLocalStorage && (spec.getRequiredPrimaryStorageUuidForRootVolume() != null || + spec.getRequiredPrimaryStorageUuidForDataVolume() != null)) { + return new LocalStorageDesignatedAllocateCapacityFlow(); + } else { + return new LocalStorageDefaultAllocateCapacityFlow(); } } } else if (spec.getCurrentVmOperation() == VmOperation.AttachVolume) { @@ -408,6 +472,24 @@ public Flow marshalVmOperationFlow(String previousFlowName, String nextFlowName, } } + if (VmImageSelectBackupStorageFlow.class.getName().equals(nextFlowName)) { + if (spec.getCurrentVmOperation() == VmOperation.ChangeImage) { + if (CollectionUtils.isEmpty(spec.getRootVolumeSystemTags())) { + return null; + } + + for (String tag : spec.getRootVolumeSystemTags()) { + if (LocalStorageSystemTags.DEST_HOST_FOR_CREATING_ROOT_VOLUME.isMatch(tag)) { + String hostUuid = LocalStorageSystemTags.DEST_HOST_FOR_CREATING_ROOT_VOLUME + .getTokenByTag(tag, LocalStorageSystemTags.DEST_HOST_FOR_CREATING_ROOT_VOLUME_TOKEN); + spec.setDestHost(HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class))); + break; + } + } + return null; + } + } + return null; } @@ -913,7 +995,7 @@ private ErrorCode checkVmMigrationCapability(VmInstanceInventory vm) { } // forbid live migration with data volumes for local storage - if (vm.getAllVolumes().size() > 1) { + if (vm.getAllDiskVolumes().size() > 1) { return operr("unable to live migrate vm[uuid:%s] with data volumes on local storage." + " Need detach all data volumes first.", vm.getUuid()); } @@ -932,7 +1014,12 @@ private ErrorCode checkVmMigrationCapability(VmInstanceInventory vm) { } @Override - public void preVmMigration(VmInstanceInventory vm, Completion completion) { + public void preVmMigration(VmInstanceInventory vm, VmMigrationType vmMigrationType, String dstHostUuid, Completion completion) { + if (!VmMigrationType.HostMigration.equals(vmMigrationType)) { + completion.success(); + return; + } + ErrorCode err = checkVmMigrationCapability(vm); if (err != null) { @@ -1171,34 +1258,6 @@ private Boolean isLocalStorage(String psUuid) { .isExists(); } - @Override - public void afterTakeLiveSnapshotsOnVolumes(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply, Completion completion) { - if (treply != null && !treply.isSuccess()) { - completion.success(); - return; - } - - for (CreateVolumesSnapshotsJobStruct job : msg.getVolumeSnapshotJobs()) { - if (!isLocalStorage(job.getPrimaryStorageUuid())) { - continue; - } - - LocalStorageResourceRefVO ref = new LocalStorageResourceRefVO(); - ref.setPrimaryStorageUuid(job.getPrimaryStorageUuid()); - ref.setResourceType(VolumeSnapshotVO.class.getSimpleName()); - VmInstanceVO vmInstanceVO = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getLockedVmInstanceUuids().get(0)).find(); - ref.setHostUuid(vmInstanceVO.getHostUuid() != null ? vmInstanceVO.getHostUuid() : vmInstanceVO.getLastHostUuid()); - ref.setCreateDate(job.getVolumeSnapshotStruct().getCurrent().getCreateDate()); - ref.setLastOpDate(job.getVolumeSnapshotStruct().getCurrent().getLastOpDate()); - ref.setResourceUuid(job.getVolumeSnapshotStruct().getCurrent().getUuid()); - ref.setSize(treply.getSnapshotsResults().stream() - .filter(r -> r.getVolumeUuid().equals(job.getVolumeUuid())) - .findFirst().get().getSize()); - dbf.persistAndRefresh(ref); - } - completion.success(); - } - @Override public void checkVmCapability(VmInstanceInventory inv, VmCapabilities capabilities) { if (capabilities.isSupportLiveMigration()) { @@ -1256,7 +1315,7 @@ public void setHostUuid(InstallPathRecycleVO vo, String primaryStorageUuid) { } @Override - public void preCreateVolume(APICreateDataVolumeMsg msg) { + public void preCreateVolume(VolumeCreateMessage msg) { String diskOffering = msg.getDiskOfferingUuid(); if (diskOffering == null || !DiskOfferingSystemTags.DISK_OFFERING_USER_CONFIG.hasTag(diskOffering)) { return; @@ -1267,11 +1326,12 @@ public void preCreateVolume(APICreateDataVolumeMsg msg) { return; } + msg.setPrimaryStorageUuid(config.getAllocate().getPrimaryStorage().getUuid()); String psUuid = msg.getPrimaryStorageUuid(); String psType = Q.New(PrimaryStorageVO.class).select(PrimaryStorageVO_.type) .eq(PrimaryStorageVO_.uuid,psUuid) .findValue(); - if (!psType.equals(type.toString())) { + if (!type.toString().equals(psType)) { return; } @@ -1305,4 +1365,73 @@ public void beforeCreateVolume(VolumeInventory volume) { public void afterCreateVolume(VolumeVO volume) { } + + @Override + public void afterVolumeLiveSnapshotGroupCreatedOnBackend(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply, Completion completion) { + if (treply != null && !treply.isSuccess()) { + completion.fail(treply.getError()); + return; + } + + for (CreateVolumesSnapshotsJobStruct job : msg.getVolumeSnapshotJobs()) { + if (!isLocalStorage(job.getPrimaryStorageUuid())) { + continue; + } + + LocalStorageResourceRefVO ref = new LocalStorageResourceRefVO(); + ref.setPrimaryStorageUuid(job.getPrimaryStorageUuid()); + ref.setResourceType(VolumeSnapshotVO.class.getSimpleName()); + VmInstanceVO vmInstanceVO = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getLockedVmInstanceUuids().get(0)).find(); + ref.setHostUuid(vmInstanceVO.getHostUuid() != null ? vmInstanceVO.getHostUuid() : vmInstanceVO.getLastHostUuid()); + ref.setCreateDate(job.getVolumeSnapshotStruct().getCurrent().getCreateDate()); + ref.setLastOpDate(job.getVolumeSnapshotStruct().getCurrent().getLastOpDate()); + ref.setResourceUuid(job.getVolumeSnapshotStruct().getCurrent().getUuid()); + ref.setSize(treply == null ? 0L : treply.getSnapshotsResults().stream() + .filter(r -> r.getVolumeUuid().equals(job.getVolumeUuid())) + .findFirst() + .map(TakeSnapshotsOnKvmResultStruct::getSize) + .orElse(0L)); + dbf.persistAndRefresh(ref); + } + completion.success(); + } + + @Override + public void afterVolumeLiveSnapshotGroupCreationFailsOnBackend(CreateVolumesSnapshotOverlayInnerMsg msg, TakeVolumesSnapshotOnKvmReply treply) { + + } + + @Override + public void afterVolumeSnapshotGroupCreated(VolumeSnapshotGroupInventory snapshotGroup, ConsistentType consistentType, Completion completion) { + completion.success(); + } + + @Override + public void afterVolumeSnapshotCreated(VolumeSnapshotInventory snapshot, Completion completion) { + completion.success(); + } + + @Override + public void innerOverwriteVolume(VolumeInventory originVolume, VolumeInventory transientVolume, VolumeDeletionPolicyManager.VolumeDeletionPolicy originVolumeDeletionPolicy) { + String sql = "select ref.hostUuid from LocalStorageResourceRefVO ref " + + "where ref.resourceUuid = :uuid " + + "and ref.resourceType = :resourceType"; + String originVolumeHostUuid = SQL.New(sql).param("uuid", originVolume.getUuid()).param("resourceType", VolumeVO.class.getSimpleName()).find(); + String transientVolumeHostUuid = SQL.New(sql).param("uuid", transientVolume.getUuid()).param("resourceType", VolumeVO.class.getSimpleName()).find(); + if (originVolumeHostUuid == null || transientVolumeHostUuid == null) { + return; + } + if (originVolumeHostUuid.equals(transientVolumeHostUuid)) { + return; + } + + SQL.New(LocalStorageResourceRefVO.class) + .eq(LocalStorageResourceRefVO_.resourceUuid, originVolume.getUuid()) + .eq(LocalStorageResourceRefVO_.resourceType, VolumeVO.class.getSimpleName()) + .set(LocalStorageResourceRefVO_.hostUuid, transientVolumeHostUuid).update(); + } + + @Override + public void afterOverwriteVolume(VolumeInventory volume, VolumeInventory transientVolume) { + } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostHistoricalUsageVO.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostHistoricalUsageVO.java new file mode 100644 index 00000000000..8bb429b4df4 --- /dev/null +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostHistoricalUsageVO.java @@ -0,0 +1,41 @@ +package org.zstack.storage.primary.local; + +import org.zstack.header.storage.primary.PrimaryStorageHistoricalUsageBaseVO; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.BaseResource; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table +@BaseResource +@AutoDeleteTag +public class LocalStorageHostHistoricalUsageVO extends PrimaryStorageHistoricalUsageBaseVO { + + public LocalStorageHostHistoricalUsageVO() { + resourceType = LocalStorageHostRefVO.class.getSimpleName(); + } + + @Column + private String hostUuid; + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + @Override + public String getResourceUuid() { + return hostUuid; + } + + @Override + public void setResourceUuid(String resourceUuid) { + this.hostUuid = resourceUuid; + } +} diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostHistoricalUsageVO_.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostHistoricalUsageVO_.java new file mode 100644 index 00000000000..98b62bc30c5 --- /dev/null +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostHistoricalUsageVO_.java @@ -0,0 +1,11 @@ +package org.zstack.storage.primary.local; + +import org.zstack.header.storage.primary.PrimaryStorageHistoricalUsageBaseVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(LocalStorageHostHistoricalUsageVO.class) +public class LocalStorageHostHistoricalUsageVO_ extends PrimaryStorageHistoricalUsageBaseVO_ { + public static volatile SingularAttribute hostUuid; +} diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostRefInventory.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostRefInventory.java index 70b3d1abb9c..8490c60146f 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostRefInventory.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostRefInventory.java @@ -1,5 +1,11 @@ package org.zstack.storage.primary.local; +import org.zstack.header.host.HostInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.storage.primary.PrimaryStorageInventory; + import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; @@ -7,8 +13,15 @@ /** * Created by frank on 6/30/2015. */ +@Inventory(mappingVOClass = LocalStorageHostRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "host", inventoryClass = HostInventory.class, + foreignKey = "hostUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "primaryStorage", inventoryClass = PrimaryStorageInventory.class, + foreignKey = "primaryStorageUuid", expandedInventoryKey = "uuid") +}) public class LocalStorageHostRefInventory { - private String uuid; + private String primaryStorageUuid; private String hostUuid; private Long totalCapacity; private Long availableCapacity; @@ -19,12 +32,12 @@ public class LocalStorageHostRefInventory { public static LocalStorageHostRefInventory valueOf(LocalStorageHostRefVO vo) { LocalStorageHostRefInventory inv = new LocalStorageHostRefInventory(); - inv.setUuid(vo.getPrimaryStorageUuid()); + inv.setPrimaryStorageUuid(vo.getPrimaryStorageUuid()); inv.setHostUuid(vo.getHostUuid()); inv.setAvailableCapacity(vo.getAvailableCapacity()); inv.setAvailablePhysicalCapacity(vo.getAvailablePhysicalCapacity()); inv.setTotalCapacity(vo.getTotalCapacity()); - inv.setTotalPhysicalCapacity(inv.getTotalPhysicalCapacity()); + inv.setTotalPhysicalCapacity(vo.getTotalPhysicalCapacity()); inv.setCreateDate(vo.getCreateDate()); inv.setLastOpDate(vo.getLastOpDate()); return inv; @@ -39,12 +52,12 @@ public static List valueOf(List primaryStorageUuid; public static volatile SingularAttribute hostUuid; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; public static volatile SingularAttribute totalCapacity; public static volatile SingularAttribute availableCapacity; - public static volatile SingularAttribute availablePhysicalCapacity; - public static volatile SingularAttribute totalPhysicalCapacity; } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostUsageReport.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostUsageReport.java new file mode 100644 index 00000000000..9cc1ec0d50a --- /dev/null +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHostUsageReport.java @@ -0,0 +1,23 @@ +package org.zstack.storage.primary.local; + +import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.storage.primary.AbstractUsageReport; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class LocalStorageHostUsageReport extends + AbstractUsageReport implements ManagementNodeReadyExtensionPoint { + private static final CLogger logger = Utils.getLogger(LocalStorageHostUsageReport.class); + + { + capacityClass = LocalStorageHostRefVO.class; + usageClass = LocalStorageHostHistoricalUsageVO.class; + } + + @Override + public void managementNodeReady() { + // UI only show localStoragePrimaryStorage Capacity Usage, don't show the localHost Capacity Usage. + // therefore, do not need to collect and forecast localHost Capacity Usage. + //start(); + } +} diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java index 5115a32b548..7760e28de93 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageHypervisorBackend.java @@ -6,6 +6,10 @@ import org.zstack.header.core.workflow.Flow; import org.zstack.header.image.ImageInventory; import org.zstack.header.storage.primary.*; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.*; +import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageMsg; +import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageReply; import java.util.List; @@ -56,7 +60,7 @@ public LocalStorageHypervisorBackend(PrimaryStorageVO self) { abstract void handle(CreateVolumeFromVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); - abstract void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); + abstract void stream(VolumeSnapshotInventory from, VolumeInventory to, boolean fullRebase, String hostUuid, Completion completion); abstract void handle(LocalStorageCreateEmptyVolumeMsg msg, ReturnValueCompletion completion); @@ -66,6 +70,10 @@ public LocalStorageHypervisorBackend(PrimaryStorageVO self) { abstract void handle(SyncVolumeSizeOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); + abstract void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg, String huuid, ReturnValueCompletion completion); + + abstract void handle(BatchSyncVolumeSizeOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); + abstract void handle(CreateImageCacheFromVolumeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); abstract void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg, ReturnValueCompletion completion); @@ -76,6 +84,8 @@ public LocalStorageHypervisorBackend(PrimaryStorageVO self) { abstract void handle(GetVolumeRootImageUuidFromPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); + abstract void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg, ReturnValueCompletion returnValueCompletion); + abstract void handleHypervisorSpecificMessage(LocalStorageHypervisorSpecificMessage msg); abstract void downloadImageToCache(ImageInventory img, String hostUuid, ReturnValueCompletion completion); @@ -90,15 +100,25 @@ public LocalStorageHypervisorBackend(PrimaryStorageVO self) { abstract void handle(ChangeVolumeTypeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract void handle(UnlinkBitsOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract List createMigrateBitsVolumeFlow(MigrateBitsStruct struct); abstract void deleteBits(String path, String hostUuid, Completion completion); - abstract void checkHostAttachedPSMountPath(String hostUuid, Completion completion); + abstract void createEmptyVolume(VolumeInventory volume, String hostUuid, ReturnValueCompletion completion); + + abstract void createEmptyVolumeWithBackingFile(VolumeInventory volume, String hostUuid, String backingFile, ReturnValueCompletion completion); + + abstract void checkHostAttachedPSMountPath(String hostUuid, ReturnValueCompletion completion); abstract void initializeHostAttachedPSMountPath(String hostUuid, Completion completion); abstract void handle(GetDownloadBitsFromKVMHostProgressMsg msg, ReturnValueCompletion completion); abstract void handle(GetVolumeSnapshotEncryptedOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + + abstract void handle(CommitVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); + + abstract void handle(PullVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageImageCleaner.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageImageCleaner.java index 3f26f65fe36..05d0342cbbc 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageImageCleaner.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageImageCleaner.java @@ -26,6 +26,7 @@ import org.zstack.header.storage.primary.*; import org.zstack.header.volume.VolumeStatus; import org.zstack.header.volume.VolumeVO; +import org.zstack.storage.primary.ImageCacheCleanParam; import org.zstack.storage.primary.ImageCacheCleaner; import org.zstack.storage.primary.local.LocalStorageUtils.InstallPath; import org.zstack.utils.CollectionUtils; @@ -37,6 +38,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** * Created by xing5 on 2016/7/20. @@ -55,29 +57,20 @@ protected String getPrimaryStorageType() { return LocalStorageConstants.LOCAL_STORAGE_TYPE; } - private boolean force; - - public boolean isForce() { - return force; - } - - public void setForce(boolean force) { - this.force = force; - } - @Transactional - protected List createShadowImageCacheVOsForNewDeletedAndOld(String psUUid) { - List staleImageCacheIds; - if (force){ - staleImageCacheIds = getStaleImageCacheIdsForLocalStorage(psUUid); - } else { - staleImageCacheIds = getStaleImageCacheIds(psUUid); + protected List createShadowImageCacheVOsForNewDeletedAndOld(String psUUid, ImageCacheCleanParam param) { + // 1. images has been deleted + List staleImageCacheIds = new ArrayList<>(); + List imageDeletedCacheIds = getStaleImageCacheIds(psUUid, param.includeReadyImage); + if (!CollectionUtils.isEmpty(imageDeletedCacheIds)) { + staleImageCacheIds.addAll(imageDeletedCacheIds); } - if (staleImageCacheIds == null || staleImageCacheIds.isEmpty()) { + if (staleImageCacheIds.isEmpty()) { return null; } + staleImageCacheIds = staleImageCacheIds.stream().distinct().collect(Collectors.toList()); String sql = "select c from ImageCacheVO c where c.id in (:ids)"; TypedQuery cq = dbf.getEntityManager().createQuery(sql, ImageCacheVO.class); cq.setParameter("ids", staleImageCacheIds); @@ -102,19 +95,73 @@ protected List createShadowImageCacheVOsForNewDeletedAndOld( sql = "select vol.rootImageUuid from VolumeVO vol where vol.rootImageUuid is not null and vol.status = :status"; TypedQuery query = dbf.getEntityManager().createQuery(sql, String.class); - query = dbf.getEntityManager().createQuery(sql, String.class); query.setParameter("status", VolumeStatus.NotInstantiated); List filterIds = query.getResultList(); - sql = "select c from ImageCacheVO c where c.imageUuid not in (select vol.rootImageUuid from VolumeVO vol, LocalStorageResourceRefVO ref" + - " where vol.uuid = ref.resourceUuid and ref.resourceType = :rtype and ref.hostUuid = :huuid and ref.primaryStorageUuid = :psUuid and vol.rootImageUuid is not null) and c.id in (:ids)"; + // 3. no volume reference + if (psUUid == null) { + sql = "select c.id from ImageCacheVO c" + + " where c.imageUuid not in" + + " (select vol.rootImageUuid from VolumeVO vol, LocalStorageResourceRefVO ref" + + " where vol.uuid = ref.resourceUuid" + + " and ref.resourceType = :rtype" + + " and ref.hostUuid = :huuid" + + " and vol.rootImageUuid is not null)" + + " and c.id in (:ids)"; + } else { + sql = "select c.id from ImageCacheVO c" + + " where c.imageUuid not in" + + " (select vol.rootImageUuid from VolumeVO vol, LocalStorageResourceRefVO ref" + + " where vol.uuid = ref.resourceUuid" + + " and ref.resourceType = :rtype" + + " and ref.hostUuid = :huuid" + + " and ref.primaryStorageUuid = :psUuid" + + " and vol.rootImageUuid is not null)" + + " and c.id in (:ids)"; + } + TypedQuery iq = dbf.getEntityManager().createQuery(sql, Long.class); + iq.setParameter("rtype", VolumeVO.class.getSimpleName()); + iq.setParameter("huuid", hostUuid); + if (psUUid != null) { + iq.setParameter("psUuid", psUUid); + } + iq.setParameter("ids", cacheIds); + cacheIds = iq.getResultList(); + if (cacheIds.isEmpty()) { + continue; + } + + // 4. no volume snapshot tree reference + if (psUUid == null) { + sql = "select c from ImageCacheVO c" + + " where c.imageUuid not in" + + " (select tree.rootImageUuid from VolumeSnapshotTreeVO tree, LocalStorageResourceRefVO ref" + + " where tree.volumeUuid = ref.resourceUuid" + + " and ref.resourceType = :rtype" + + " and ref.hostUuid = :huuid" + + " and tree.rootImageUuid is not null)" + + " and c.id in (:ids)"; + } else { + sql = "select c from ImageCacheVO c" + + " where c.imageUuid not in" + + " (select tree.rootImageUuid from VolumeSnapshotTreeVO tree, LocalStorageResourceRefVO ref" + + " where tree.volumeUuid = ref.resourceUuid" + + " and ref.resourceType = :rtype" + + " and ref.hostUuid = :huuid" + + " and ref.primaryStorageUuid = :psUuid" + + " and tree.rootImageUuid is not null)" + + " and c.id in (:ids)"; + } + cq = dbf.getEntityManager().createQuery(sql, ImageCacheVO.class); cq.setParameter("rtype", VolumeVO.class.getSimpleName()); cq.setParameter("huuid", hostUuid); - cq.setParameter("psUuid", psUUid); + if (psUUid != null) { + cq.setParameter("psUuid", psUUid); + } cq.setParameter("ids", cacheIds); - List results = cq.getResultList(); + List results = cq.getResultList(); results.removeIf(c -> filterIds.contains(c.getImageUuid())); stale.addAll(results); @@ -170,19 +217,20 @@ public void done(ErrorCodeList errorCodeList) { }); } - private void cleanUpVolumeCache(String psUuid, boolean needDestinationCheck, NoErrorCompletion completion) { - List shadowVOs = createShadowImageCacheVOs(psUuid); + @Override + protected void cleanUpVolumeCache(String psUuid, ImageCacheCleanParam param, NoErrorCompletion completion) { + List shadowVOs = createShadowImageCacheVOs(psUuid, param); if (shadowVOs == null || shadowVOs.isEmpty()) { completion.done(); return; } - new While<>(shadowVOs).each((vo, whileCompletion) -> { - if (needDestinationCheck && !destMaker.isManagedByUs(vo.getImageUuid())) { - whileCompletion.done(); - return; - } + if (!param.triggerByApi) { + shadowVOs.removeIf(vo -> !destMaker.isManagedByUs(vo.getImageUuid())); + } + + new While<>(shadowVOs).each((vo, whileCompletion) -> { InstallPath p = new InstallPath(); p.fullPath = vo.getInstallUrl(); p.disassemble(); @@ -223,13 +271,20 @@ public void done(ErrorCodeList errorCodeList) { } @Override - protected void doCleanup(String psUuid, boolean needDestinationCheck, NoErrorCompletion completion) { + protected void doCleanup(String psUuid, ImageCacheCleanParam param, NoErrorCompletion completion) { + List psUuids = new ArrayList<>(); + if (psUuid == null) { + psUuids.addAll(listPrimaryStoragesBySelfType()); + } else { + psUuids.add(psUuid); + } + SimpleFlowChain chain = new SimpleFlowChain(); chain.setName(String.format("do-clean-up-image-cache-on-local-storage-%s", psUuid)); chain.then(new NoRollbackFlow() { @Override public void run(FlowTrigger trigger, Map data) { - cleanUpVolumeCache(psUuid, needDestinationCheck, new NoErrorCompletion() { + cleanUpVolumeCache(psUuid, param, new NoErrorCompletion() { @Override public void done() { trigger.next(); @@ -239,15 +294,48 @@ public void done() { }).then(new NoRollbackFlow() { @Override public void run(FlowTrigger trigger, Map data) { - if (psUuid == null) { - logger.debug("no primary storage uuid specified, skip image cache clean up"); + if (psUuids.isEmpty()) { + logger.debug("cannot find any primary storage, skip image cache clean up"); trigger.next(); return; } - cleanUpImageCache(psUuid, new NoErrorCompletion() { + new While<>(psUuids).each((uuid, compl) -> { + cleanUpImageCache(uuid, new NoErrorCompletion() { + @Override + public void done() { + compl.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { @Override - public void done() { + public void done(ErrorCodeList errorCodeList) { + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + if (psUuids.isEmpty()) { + logger.debug("cannot find any primary storage, skip sync primary storage capacity"); + trigger.next(); + return; + } + + new While<>(psUuids).each((uuid, compl) -> { + SyncPrimaryStorageCapacityMsg msg = new SyncPrimaryStorageCapacityMsg(); + msg.setPrimaryStorageUuid(uuid); + bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, msg.getPrimaryStorageUuid()); + bus.send(msg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + compl.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { trigger.next(); } }); @@ -267,7 +355,7 @@ public void handle(ErrorCode errCode, Map data) { } @Override - public void cleanup(String psUuid, boolean needDestinationCheck) { + public void cleanup(String psUuid, ImageCacheCleanParam param) { ImageCacheCleaner self = this; thdf.chainSubmit(new ChainTask(null) { @Override @@ -278,7 +366,7 @@ public String getSyncSignature() { @Override public void run(SyncTaskChain chain) { logger.debug("start clean up cache"); - doCleanup(psUuid, needDestinationCheck, new NoErrorCompletion() { + doCleanup(psUuid, param, new NoErrorCompletion() { @Override public void done() { chain.next(); diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java index 134e27c5390..86d521b1a94 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmBackend.java @@ -3,6 +3,8 @@ import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.compute.vm.ImageBackupStorageSelector; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.CloudBusListCallBack; import org.zstack.core.cloudbus.MessageSafe; @@ -14,6 +16,7 @@ import org.zstack.core.thread.AsyncThread; import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.core.workflow.SimpleFlowChain; @@ -22,10 +25,12 @@ import org.zstack.header.core.Completion; import org.zstack.header.core.NopeCompletion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.progress.TaskProgressRange; import org.zstack.header.core.validation.Validation; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.*; @@ -39,9 +44,7 @@ import org.zstack.header.rest.RESTFacade; import org.zstack.header.storage.backup.*; import org.zstack.header.storage.primary.*; -import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; -import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; -import org.zstack.header.storage.snapshot.VolumeSnapshotVO; +import org.zstack.header.storage.snapshot.*; import org.zstack.header.vm.VmInstanceSpec.ImageSpec; import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceVO; @@ -49,13 +52,11 @@ import org.zstack.header.volume.*; import org.zstack.identity.AccountManager; import org.zstack.kvm.*; -import org.zstack.storage.primary.PrimaryStoragePathMaker; -import org.zstack.storage.primary.PrimaryStorageSystemTags; +import org.zstack.storage.primary.*; import org.zstack.storage.primary.local.LocalStorageKvmMigrateVmFlow.CopyBitsFromRemoteCmd; import org.zstack.storage.primary.local.MigrateBitsStruct.ResourceInfo; -import org.zstack.storage.snapshot.VolumeSnapshotSystemTags; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; -import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; @@ -89,7 +90,9 @@ public class LocalStorageKvmBackend extends LocalStorageHypervisorBackend { private PluginRegistry pluginRgty; public static class AgentCommand extends KVMAgentCommands.PrimaryStorageCommand { + @GrayVersion(value = "5.0.0") public String uuid; + @GrayVersion(value = "5.0.0") public String storagePath; } @@ -132,11 +135,21 @@ public Long getAvailableCapacity() { public void setAvailableCapacity(Long availableCapacity) { this.availableCapacity = availableCapacity; } + + protected ErrorCode buildErrorCode() { + if (success) { + return null; + } + return operr("operation error, because:%s", error); + } } public static class InitCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String path; + @GrayVersion(value = "5.0.0") private String hostUuid; + @GrayVersion(value = "5.0.0") private String initFilePath; public String getHostUuid() { @@ -177,6 +190,7 @@ public void setLocalStorageUsedCapacity(Long localStorageUsedCapacity) { } public static class CreateFolderCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String installUrl; public String getInstallUrl() { @@ -189,11 +203,17 @@ public void setInstallUrl(String installUrl) { } public static class CreateEmptyVolumeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String installUrl; + @GrayVersion(value = "5.0.0") private long size; + @GrayVersion(value = "5.0.0") private String accountUuid; + @GrayVersion(value = "5.0.0") private String name; + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private String backingFile; public String getBackingFile() { @@ -246,9 +266,12 @@ public void setVolumeUuid(String volumeUuid) { } public static class CreateEmptyVolumeRsp extends AgentResponse { + public Long actualSize; + public Long size; } public static class GetPhysicalCapacityCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String hostUuid; public String getHostUuid() { @@ -261,9 +284,14 @@ public void setHostUuid(String hostUuid) { } public static class CreateVolumeFromCacheCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String templatePathInCache; + @GrayVersion(value = "5.0.0") private String installUrl; + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") + private long virtualSize; public String getTemplatePathInCache() { return templatePathInCache; @@ -288,15 +316,27 @@ public String getVolumeUuid() { public void setVolumeUuid(String volumeUuid) { this.volumeUuid = volumeUuid; } + + public long getVirtualSize() { + return virtualSize; + } + + public void setVirtualSize(long virtualSize) { + this.virtualSize = virtualSize; + } } public static class CreateVolumeFromCacheRsp extends AgentResponse { - + public Long actualSize; + public Long size; } public static class CreateVolumeWithBackingCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String templatePathInCache; + @GrayVersion(value = "5.0.0") public String installPath; + @GrayVersion(value = "5.0.0") public String volumeUuid; } @@ -306,8 +346,11 @@ public static class CreateVolumeWithBackingRsp extends AgentResponse { } public static class DeleteBitsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String hostUuid; + @GrayVersion(value = "5.0.0") private String path; + @GrayVersion(value = "5.0.0") private String username; public String getHostUuid() { @@ -336,10 +379,29 @@ public void setUsername(String username) { } public static class DeleteBitsRsp extends AgentResponse { + public boolean inUse; + public ErrorCode buildErrorCode() { + if (inUse) { + return Platform.err(VolumeErrors.VOLUME_IN_USE, getError()); + } + return super.buildErrorCode(); + } + } + + public static class UnlinkBitsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String installPath; + @GrayVersion(value = "5.0.0") + public boolean onlyLinkedFile = true; + } + + public static class UnlinkBitsRsp extends AgentResponse { } public static class ListPathCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String path; + @GrayVersion(value = "5.0.0") private String hostUuid; public String getPath() { @@ -372,7 +434,9 @@ public void setPaths(List paths) { } public static class CreateTemplateFromVolumeCmd extends AgentCommand implements HasThreadContext{ + @GrayVersion(value = "5.0.0") private String installPath; + @GrayVersion(value = "5.0.0") private String volumePath; public String getInstallPath() { @@ -413,7 +477,42 @@ public void setSize(long size) { } } + public static class EstimateTemplateSizeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + private String volumePath; + + public String getVolumePath() { + return volumePath; + } + + public void setVolumePath(String rootVolumePath) { + this.volumePath = rootVolumePath; + } + } + + public static class EstimateTemplateSizeRsp extends AgentResponse { + private long size; + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + } + public static class RevertVolumeFromSnapshotCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String snapshotInstallPath; public String getSnapshotInstallPath() { @@ -426,7 +525,9 @@ public void setSnapshotInstallPath(String snapshotInstallPath) { } public static class ReinitImageCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String imagePath; + @GrayVersion(value = "5.0.0") private String volumePath; public String getImagePath() { @@ -484,8 +585,11 @@ public void setSize(long size) { } public static class MergeSnapshotCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private String snapshotInstallPath; + @GrayVersion(value = "5.0.0") private String workspaceInstallPath; public String getVolumeUuid() { @@ -535,8 +639,11 @@ public void setSize(long size) { } public static class RebaseAndMergeSnapshotsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private List snapshotInstallPaths; + @GrayVersion(value = "5.0.0") private String workspaceInstallPath; public String getVolumeUuid() { @@ -586,8 +693,11 @@ public void setSize(long size) { } public static class OfflineMergeSnapshotCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String srcPath; + @GrayVersion(value = "5.0.0") private String destPath; + @GrayVersion(value = "5.0.0") private boolean fullRebase; public boolean isFullRebase() { @@ -616,10 +726,44 @@ public void setDestPath(String destPath) { } public static class OfflineMergeSnapshotRsp extends AgentResponse { + @GrayVersion(value = "5.4.0") + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + } + + public static class OfflineCommitSnapshotCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.4.0") + public String top; + @GrayVersion(value = "5.4.0") + public String base; + @GrayVersion(value = "5.4.0") + public List topChildrenInstallPathInDb = new ArrayList<>(); + } + + public static class OfflineCommitSnapshotRsp extends AgentResponse { + @GrayVersion(value = "5.4.0") + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } } public static class CheckBitsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String path; + @GrayVersion(value = "5.0.0") public String username; } @@ -633,9 +777,13 @@ public static class GetMd5TO { } public static class GetMd5Cmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") public List md5s; + @GrayVersion(value = "5.0.0") public String sendCommandUrl; + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String stage; } @@ -651,14 +799,20 @@ public static class GetMd5Rsp extends AgentResponse { public static class CheckMd5sumCmd extends AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") public List md5s; + @GrayVersion(value = "5.0.0") public String sendCommandUrl; + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String stage; } public static class GetBackingFileCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String path; + @GrayVersion(value = "5.0.0") public String volumeUuid; } @@ -673,18 +827,38 @@ public static class GetBackingFileRsp extends AgentResponse { * This takes into consideration multiple snapshot chains and chain-based image. */ public static class GetVolumeBaseImagePathCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String imageCacheDir; + @GrayVersion(value = "5.0.0") public String volumeInstallDir; + @GrayVersion(value = "5.0.0") + public String volumeInstallPath; } public static class GetVolumeBaseImagePathRsp extends AgentResponse { public String path; + public List otherPaths; public Long size; } + public static class GetBackingChainCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public String volumeUuid; + @GrayVersion(value = "5.0.0") + public String installPath; + } + + public static class GetBackingChainRsp extends AgentResponse { + public List backingChain; + public long totalSize; + } + public static class GetVolumeSizeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String installPath; } @@ -693,8 +867,19 @@ public static class GetVolumeSizeRsp extends AgentResponse { public long size; } + public static class GetBatchVolumeSizeCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") + public Map volumeUuidInstallPaths; + } + + public static class GetBatchVolumeSizeRsp extends AgentResponse { + public Map actualSizes; + } + public static class GetQCOW2ReferenceCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String path; + @GrayVersion(value = "5.0.0") public String searchingDir; } @@ -703,6 +888,7 @@ public static class GetQCOW2ReferenceRsp extends AgentResponse { } public static class CheckInitializedFileCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String filePath; } @@ -711,22 +897,32 @@ public static class CheckInitializedFileRsp extends AgentResponse { } public static class CreateInitializedFileCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String filePath; } public static class Qcow2Cmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String preallocation = buildQcow2Options(); } public static class DownloadBitsFromKVMHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String hostname; + @GrayVersion(value = "5.0.0") public String username; + @GrayVersion(value = "5.0.0") public String sshKey; + @GrayVersion(value = "5.0.0") public int sshPort; // it's file path on kvm host actually + @GrayVersion(value = "5.0.0") public String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; + @GrayVersion(value = "5.0.0") public Long bandWidth; + @GrayVersion(value = "5.0.0") public String identificationCode; } @@ -735,10 +931,12 @@ public static class DownloadBitsFromKVMHostRsp extends AgentResponse { } public static class CancelDownloadBitsFromKVMHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; } public static class GetDownloadBitsFromKVMHostProgressCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public List volumePaths; } @@ -747,8 +945,11 @@ public static class GetDownloadBitsFromKVMHostProgressRsp extends AgentResponse } public static class LinkVolumeNewDirCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String srcDir; + @GrayVersion(value = "5.0.0") public String dstDir; } @@ -756,7 +957,9 @@ public static class LinkVolumeNewDirRsp extends AgentResponse { } public static class GetQcow2HashValueCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String hostUuid; + @GrayVersion(value = "5.0.0") private String installPath; public String getHostUuid() { @@ -797,17 +1000,22 @@ public void setHashValue(String hashValue) { public static final String DELETE_BITS_PATH = "/localstorage/delete"; public static final String DELETE_DIR_PATH = "/localstorage/deletedir"; public static final String CHECK_BITS_PATH = "/localstorage/checkbits"; + public static final String UNLINK_BITS_PATH = "/localstorage/unlink"; public static final String CREATE_TEMPLATE_FROM_VOLUME = "/localstorage/volume/createtemplate"; + public static final String ESTIMATE_TEMPLATE_SIZE_PATH = "/localstorage/volume/estimatetemplatesize"; public static final String REVERT_SNAPSHOT_PATH = "/localstorage/snapshot/revert"; public static final String REINIT_IMAGE_PATH = "/localstorage/reinit/image"; public static final String MERGE_SNAPSHOT_PATH = "/localstorage/snapshot/merge"; public static final String OFFLINE_MERGE_PATH = "/localstorage/snapshot/offlinemerge"; + public static final String OFFLINE_COMMIT_PATH = "/localstorage/snapshot/offlinecommit"; public static final String GET_MD5_PATH = "/localstorage/getmd5"; public static final String CHECK_MD5_PATH = "/localstorage/checkmd5"; public static final String GET_BACKING_FILE_PATH = "/localstorage/volume/getbackingfile"; public static final String GET_VOLUME_SIZE = "/localstorage/volume/getsize"; + public static final String BATCH_GET_VOLUME_SIZE = "/localstorage/volume/batchgetsize"; public static final String HARD_LINK_VOLUME = "/localstorage/volume/hardlink"; public static final String GET_BASE_IMAGE_PATH = "/localstorage/volume/getbaseimagepath"; + public static final String GET_BACKING_CHAIN_PATH = "/localstorage/volume/getbackingchain"; public static final String GET_QCOW2_REFERENCE = "/localstorage/getqcow2reference"; public static final String CHECK_INITIALIZED_FILE = "/localstorage/check/initializedfile"; public static final String CREATE_INITIALIZED_FILE = "/localstorage/create/initializedfile"; @@ -852,7 +1060,7 @@ public String getCachedImageDir(){ } public String makeCachedImageInstallUrl(ImageInventory iminv) { - return PathUtil.join(self.getUrl(), PrimaryStoragePathMaker.makeCachedImageInstallPath(iminv)); + return ImageCacheUtil.getImageCachePath(iminv, it -> PathUtil.join(self.getUrl(), PrimaryStoragePathMaker.makeCachedImageInstallPath(iminv))); } public String makeCachedImageInstallUrlFromImageUuidForTemplate(String imageUuid) { @@ -1004,8 +1212,9 @@ public void run(MessageReply reply) { KVMHostAsyncHttpCallReply r = reply.castReply(); T rsp = r.toResponse(rspType); - if (!rsp.isSuccess()) { - completion.fail(operr("operation error, because:%s", rsp.getError())); + ErrorCode errorCode = rsp.buildErrorCode(); + if (errorCode != null) { + completion.fail(errorCode); return; } @@ -1129,13 +1338,18 @@ private void createTemporaryEmptyVolume(InstantiateTemporaryVolumeOnPrimaryStora } private void createEmptyVolume(InstantiateVolumeOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { - createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), new ReturnValueCompletion(completion) { + createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), new ReturnValueCompletion(completion) { @Override - public void success(String returnValue) { + public void success(VolumeStats returnValue) { InstantiateVolumeOnPrimaryStorageReply r = new InstantiateVolumeOnPrimaryStorageReply(); VolumeInventory vol = msg.getVolume(); - vol.setInstallPath(returnValue); + vol.setInstallPath(returnValue.getInstallPath()); + vol.setActualSize(returnValue.getActualSize()); vol.setFormat(VolumeConstant.VOLUME_FORMAT_QCOW2); + if (returnValue.getSize() != null) { + vol.setSize(returnValue.getSize()); + } + r.setVolume(vol); completion.success(r); } @@ -1147,11 +1361,11 @@ public void fail(ErrorCode errorCode) { }); } - private void createEmptyVolume(final VolumeInventory volume, final String hostUuid, final ReturnValueCompletion completion) { - createEmptyVolume(volume, hostUuid, null, completion); + public void createEmptyVolume(final VolumeInventory volume, final String hostUuid, final ReturnValueCompletion completion) { + createEmptyVolumeWithBackingFile(volume, hostUuid, null, completion); } - private void createEmptyVolume(final VolumeInventory volume, final String hostUuid, final String backingFile, final ReturnValueCompletion completion) { + public void createEmptyVolumeWithBackingFile(final VolumeInventory volume, final String hostUuid, final String backingFile, final ReturnValueCompletion completion) { final CreateEmptyVolumeCmd cmd = new CreateEmptyVolumeCmd(); cmd.setAccountUuid(acntMgr.getOwnerAccountUuidOfResource(volume.getUuid())); if (volume.getInstallPath() != null && !volume.getInstallPath().equals("")) { @@ -1175,7 +1389,7 @@ private void createEmptyVolume(final VolumeInventory volume, final String hostUu httpCall(CREATE_EMPTY_VOLUME_PATH, hostUuid, cmd, CreateEmptyVolumeRsp.class, new ReturnValueCompletion(completion) { @Override public void success(CreateEmptyVolumeRsp returnValue) { - completion.success(cmd.getInstallUrl()); + completion.success(new VolumeStats(cmd.getInstallUrl(), returnValue.actualSize, returnValue.size)); } @Override @@ -1185,7 +1399,6 @@ public void fail(ErrorCode errorCode) { } }); } - private String getHostUuidByResourceUuid(String resUuid, String resType) { SimpleQuery q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid); @@ -1205,6 +1418,7 @@ class ImageCache { ImageInventory image; BackupStorageInventory backupStorage; String volumeResourceInstallPath; + boolean incremental; String hostUuid; String primaryStorageInstallPath; String backupStorageInstallPath; @@ -1290,12 +1504,37 @@ public void rollback(FlowRollback trigger, Map data) { @Override public void run(final FlowTrigger trigger, Map data) { if (volumeResourceInstallPath != null) { - downloadFromVolume(trigger); + if (incremental) { + incrementalDownloadFromVolume(trigger); + } else { + downloadFromVolume(trigger); + } } else { downloadFromBackupStorage(trigger); } } + private void incrementalDownloadFromVolume(FlowTrigger trigger) { + CreateVolumeWithBackingCmd cmd = new CreateVolumeWithBackingCmd(); + cmd.installPath = primaryStorageInstallPath; + cmd.templatePathInCache = volumeResourceInstallPath; + + httpCall(CREATE_VOLUME_WITH_BACKING_PATH, hostUuid, cmd, false, + CreateVolumeWithBackingRsp.class, + new ReturnValueCompletion(trigger) { + @Override + public void success(CreateVolumeWithBackingRsp rsp) { + actualSize = rsp.actualSize; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + private void downloadFromVolume(FlowTrigger trigger) { CreateTemplateFromVolumeCmd cmd = new CreateTemplateFromVolumeCmd(); cmd.setInstallPath(primaryStorageInstallPath); @@ -1358,11 +1597,29 @@ public void handle(Map data) { ImageCacheInventory inv = ImageCacheInventory.valueOf(vo); inv.setInstallUrl(primaryStorageInstallPath); - pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class) - .forEach(exp -> exp.saveEncryptAfterCreateImageCache(hostUuid, inv)); + new While<>(pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class)).each((ext, whileCompletion) -> { + ext.saveEncryptAfterCreateImageCache(hostUuid, inv, new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } - completion.success(inv); - chain.next(); + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + logger.warn(String.format("failed to saveEncryptAfterCreateImageCache: %s", errorCodeList.getCauses().get(0))); + } + completion.success(inv); + chain.next(); + } + }); } }); @@ -1441,14 +1698,10 @@ public void success(CheckBitsRsp rsp) { q.add(ImageCacheVO_.installUrl, Op.LIKE, String.format("%%hostUuid://%s%%", hostUuid)); ImageCacheVO cvo = q.find(); - LocalStorageUtils.InstallPath path = new LocalStorageUtils.InstallPath(); - path.installPath = cvo.getInstallUrl(); - path.hostUuid = hostUuid; - ReleasePrimaryStorageSpaceMsg rmsg = new ReleasePrimaryStorageSpaceMsg(); rmsg.setDiskSize(cvo.getSize()); rmsg.setPrimaryStorageUuid(cvo.getPrimaryStorageUuid()); - rmsg.setAllocatedInstallUrl(path.makeFullPath()); + rmsg.setAllocatedInstallUrl(cvo.getInstallUrl()); bus.makeTargetServiceIdByResourceUuid(rmsg, PrimaryStorageConstant.SERVICE_ID, cvo.getPrimaryStorageUuid()); bus.send(rmsg); @@ -1483,12 +1736,13 @@ private void createRootVolume(final InstantiateRootVolumeFromTemplateOnPrimarySt final ImageInventory image = ispec.getInventory(); if (!ImageMediaType.RootVolumeTemplate.toString().equals(image.getMediaType())) { - createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), new ReturnValueCompletion(completion) { + createEmptyVolume(msg.getVolume(), msg.getDestHost().getUuid(), new ReturnValueCompletion(completion) { @Override - public void success(String returnValue) { + public void success(VolumeStats returnValue) { InstantiateVolumeOnPrimaryStorageReply r = new InstantiateVolumeOnPrimaryStorageReply(); VolumeInventory vol = msg.getVolume(); - vol.setInstallPath(returnValue); + vol.setInstallPath(returnValue.getInstallPath()); + vol.setActualSize(returnValue.getActualSize()); vol.setFormat(VolumeConstant.VOLUME_FORMAT_QCOW2); r.setVolume(vol); completion.success(r); @@ -1512,6 +1766,7 @@ public void fail(ErrorCode errorCode) { String pathInCache = makeCachedImageInstallUrl(image); String installPath = StringUtils.isNotEmpty(volume.getInstallPath()) ? volume.getInstallPath() : makeRootVolumeInstallUrl(volume) ; + Long actualSize; @Override public void setup() { @@ -1548,10 +1803,18 @@ public void run(final FlowTrigger trigger, Map data) { cmd.setInstallUrl(installPath); cmd.setTemplatePathInCache(pathInCache); cmd.setVolumeUuid(volume.getUuid()); + if (image.getSize() < volume.getSize()) { + cmd.setVirtualSize(volume.getSize()); + } httpCall(CREATE_VOLUME_FROM_CACHE_PATH, hostUuid, cmd, CreateVolumeFromCacheRsp.class, new ReturnValueCompletion(trigger) { @Override public void success(CreateVolumeFromCacheRsp returnValue) { + actualSize = returnValue.actualSize; + if (returnValue.size != null) { + volume.setSize(returnValue.size); + } + trigger.next(); } @@ -1568,6 +1831,7 @@ public void fail(ErrorCode errorCode) { public void handle(Map data) { InstantiateVolumeOnPrimaryStorageReply reply = new InstantiateVolumeOnPrimaryStorageReply(); volume.setInstallPath(installPath); + volume.setActualSize(actualSize); reply.setVolume(volume); completion.success(reply); } @@ -1612,6 +1876,11 @@ public void fail(ErrorCode errorCode) { completion.fail(errorCode); return; } + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete path:%s right now, skip this GC job because it's in use", path)); + completion.fail(errorCode); + return; + } LocalStorageDeleteBitsGC gc = new LocalStorageDeleteBitsGC(); gc.isDir = dir; @@ -1931,7 +2200,7 @@ public void run(FlowTrigger trigger, Map data) { cmd.imagePath = makeCachedImageInstallUrlFromImageUuidForTemplate(msg.getVolume().getRootImageUuid()); cmd.volumePath = makeRootVolumeInstallUrl(msg.getVolume()); - httpCall(REINIT_IMAGE_PATH, hostUuid, cmd, ReinitImageRsp.class, new ReturnValueCompletion(completion) { + httpCall(REINIT_IMAGE_PATH, hostUuid, cmd, ReinitImageRsp.class, new ReturnValueCompletion(trigger) { @Override public void success(ReinitImageRsp rsp) { reply.setNewVolumeInstallPath(rsp.getNewVolumeInstallPath()); @@ -2031,14 +2300,13 @@ private void createIncrementalVolumeFromSnapshot(VolumeSnapshotInventory sp, Str cmd.volumeUuid = volumeUuid; cmd.installPath = installPath; cmd.templatePathInCache = sp.getPrimaryStorageInstallPath(); - httpCall(CREATE_VOLUME_WITH_BACKING_PATH, hostUuid, cmd, CreateVolumeWithBackingRsp.class, new ReturnValueCompletion(completion) { @Override public void success(CreateVolumeWithBackingRsp rsp) { reply.setActualSize(rsp.actualSize); reply.setSize(rsp.size); reply.setInstallPath(installPath); - createProtectTag(); + reply.setIncremental(true); completion.success(reply); } @@ -2046,26 +2314,21 @@ public void success(CreateVolumeWithBackingRsp rsp) { public void fail(ErrorCode errorCode) { completion.fail(errorCode); } - - private void createProtectTag() { - SystemTagCreator creator = VolumeSnapshotSystemTags.BACKING_TO_VOLUME.newSystemTagCreator(sp.getUuid()); - creator.unique = false; - creator.setTagByTokens(Collections.singletonMap(VolumeSnapshotSystemTags.BACKING_VOLUME_TOKEN, volumeUuid)); - creator.create(); - } }); } @Override - void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, final ReturnValueCompletion completion) { + void stream(VolumeSnapshotInventory from, VolumeInventory to, boolean fullRebase, String hostUuid, final Completion completion) { boolean offline = true; - VolumeInventory volume = msg.getTo(); + VolumeInventory volume = to; + VolumeSnapshotInventory sp = from != null ? from : new VolumeSnapshotInventory(); + fullRebase |= from == null; + if (volume.getType().equals(VolumeType.Memory.toString())) { - completion.success(new MergeVolumeSnapshotOnPrimaryStorageReply()); + completion.success(); return; } - VolumeSnapshotInventory sp = msg.getFrom(); if (volume.getVmInstanceUuid() != null) { SimpleQuery q = dbf.createQuery(VmInstanceVO.class); q.select(VmInstanceVO_.state); @@ -2081,18 +2344,16 @@ void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, final R offline = (state == VmInstanceState.Stopped || state == VmInstanceState.Destroyed); } - final MergeVolumeSnapshotOnPrimaryStorageReply ret = new MergeVolumeSnapshotOnPrimaryStorageReply(); - if (offline) { OfflineMergeSnapshotCmd cmd = new OfflineMergeSnapshotCmd(); - cmd.setFullRebase(msg.isFullRebase()); + cmd.setFullRebase(fullRebase); cmd.setSrcPath(sp.getPrimaryStorageInstallPath()); cmd.setDestPath(volume.getInstallPath()); httpCall(OFFLINE_MERGE_PATH, hostUuid, cmd, OfflineMergeSnapshotRsp.class, new ReturnValueCompletion(completion) { @Override public void success(OfflineMergeSnapshotRsp returnValue) { - completion.success(ret); + completion.success(); } @Override @@ -2102,7 +2363,7 @@ public void fail(ErrorCode errorCode) { }); } else { MergeVolumeSnapshotOnKvmMsg kmsg = new MergeVolumeSnapshotOnKvmMsg(); - kmsg.setFullRebase(msg.isFullRebase()); + kmsg.setFullRebase(fullRebase); kmsg.setHostUuid(hostUuid); kmsg.setFrom(sp); kmsg.setTo(volume); @@ -2111,7 +2372,7 @@ public void fail(ErrorCode errorCode) { @Override public void run(MessageReply reply) { if (reply.isSuccess()) { - completion.success(ret); + completion.success(); } else { completion.fail(reply.getError()); } @@ -2122,9 +2383,9 @@ public void run(MessageReply reply) { @Override void handle(LocalStorageCreateEmptyVolumeMsg msg, final ReturnValueCompletion completion) { - createEmptyVolume(msg.getVolume(), msg.getHostUuid(), msg.getBackingFile(), new ReturnValueCompletion(completion) { + createEmptyVolumeWithBackingFile(msg.getVolume(), msg.getHostUuid(), msg.getBackingFile(), new ReturnValueCompletion(completion) { @Override - public void success(String returnValue) { + public void success(VolumeStats returnValue) { LocalStorageCreateEmptyVolumeReply reply = new LocalStorageCreateEmptyVolumeReply(); completion.success(reply); } @@ -2186,10 +2447,7 @@ void handle(SyncVolumeSizeOnPrimaryStorageMsg msg, String hostUuid, final Return GetVolumeSizeCmd cmd = new GetVolumeSizeCmd(); cmd.installPath = msg.getInstallPath(); cmd.volumeUuid = msg.getVolumeUuid(); - cmd.storagePath = Q.New(PrimaryStorageVO.class) - .eq(PrimaryStorageVO_.uuid, msg.getPrimaryStorageUuid()) - .select(PrimaryStorageVO_.url) - .findValue(); + cmd.storagePath = self.getUrl(); KvmCommandSender sender = new KvmCommandSender(hostUuid); sender.send(cmd, GET_VOLUME_SIZE, new KvmCommandFailureChecker() { @@ -2214,6 +2472,47 @@ public void fail(ErrorCode errorCode) { }); } + @Override + void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg, String huuid, ReturnValueCompletion completion) { + final EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + EstimateTemplateSizeCmd cmd = new EstimateTemplateSizeCmd(); + cmd.volumePath = msg.getInstallPath(); + + httpCall(ESTIMATE_TEMPLATE_SIZE_PATH, huuid, cmd, EstimateTemplateSizeRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(EstimateTemplateSizeRsp rsp) { + reply.setSize(rsp.size); + reply.setActualSize(rsp.actualSize); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + void handle(BatchSyncVolumeSizeOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion) { + final BatchSyncVolumeSizeOnPrimaryStorageReply reply = new BatchSyncVolumeSizeOnPrimaryStorageReply(); + GetBatchVolumeSizeCmd cmd = new GetBatchVolumeSizeCmd(); + cmd.volumeUuidInstallPaths = msg.getVolumeUuidInstallPaths(); + + httpCall(BATCH_GET_VOLUME_SIZE, msg.getHostUuid(), cmd, GetBatchVolumeSizeRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(GetBatchVolumeSizeRsp rsp) { + reply.setActualSizes(rsp.actualSizes); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + @Override void handle(final UploadBitsFromLocalStorageToBackupStorageMsg msg, String hostUuid, final ReturnValueCompletion completion) { final BackupStorageVO bs = dbf.findByUuid(msg.getBackupStorageUuid(), BackupStorageVO.class); @@ -2242,6 +2541,7 @@ public void fail(ErrorCode errorCode) { void handle(final GetVolumeRootImageUuidFromPrimaryStorageMsg msg, String hostUuid, final ReturnValueCompletion completion) { GetVolumeBaseImagePathCmd cmd = new GetVolumeBaseImagePathCmd(); cmd.volumeInstallDir = makeVolumeInstallDir(msg.getVolume()); + cmd.volumeInstallPath = msg.getVolume().getInstallPath(); cmd.imageCacheDir = getCachedImageDir(); cmd.volumeUuid = msg.getVolume().getUuid(); cmd.storagePath = Q.New(PrimaryStorageVO.class) @@ -2249,23 +2549,19 @@ void handle(final GetVolumeRootImageUuidFromPrimaryStorageMsg msg, String hostUu .select(PrimaryStorageVO_.url) .findValue(); - new KvmCommandSender(hostUuid).send(cmd, GET_BASE_IMAGE_PATH, new KvmCommandFailureChecker() { + httpCall(GET_BASE_IMAGE_PATH, hostUuid, cmd, GetVolumeBaseImagePathRsp.class, new ReturnValueCompletion(completion) { @Override - public ErrorCode getError(KvmResponseWrapper w) { - GetVolumeBaseImagePathRsp rsp = w.getResponse(GetVolumeBaseImagePathRsp.class); - if (rsp.isSuccess() && StringUtils.isEmpty(rsp.path)) { - return operr("cannot get root image of volume[uuid:%s], may be it create from iso", msg.getVolume().getUuid()); - } - return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); - } - }, new ReturnValueCompletion(completion) { - @Override - public void success(KvmResponseWrapper w) { - GetVolumeBaseImagePathRsp rsp = w.getResponse(GetVolumeBaseImagePathRsp.class); - String rootImageUuid = new File(rsp.path).getName().split("\\.")[0]; + public void success(GetVolumeBaseImagePathRsp rsp) { GetVolumeRootImageUuidFromPrimaryStorageReply reply = new GetVolumeRootImageUuidFromPrimaryStorageReply(); - reply.setImageUuid(rootImageUuid); - bus.reply(msg, reply); + if (rsp.path != null) { + String rootImageUuid = new File(rsp.path).getName().split("\\.")[0]; + reply.setImageUuid(rootImageUuid); + } + + if (!CollectionUtils.isEmpty(rsp.otherPaths)) { + reply.setOtherImageUuids(rsp.otherPaths.stream().map(p -> new File(p).getName().split("\\.")[0]).collect(Collectors.toList())); + } + completion.success(reply); } @Override @@ -2275,6 +2571,44 @@ public void fail(ErrorCode errorCode) { }); } + @Override + void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg, ReturnValueCompletion completion) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + new While<>(msg.getRootInstallPaths()).each((installPath, compl) -> { + GetBackingChainCmd cmd = new GetBackingChainCmd(); + cmd.installPath = installPath; + cmd.volumeUuid = msg.getVolumeUuid(); + httpCall(GET_BACKING_CHAIN_PATH, msg.getHostUuid(), cmd, GetBackingChainRsp.class, new ReturnValueCompletion(compl) { + @Override + public void success(GetBackingChainRsp rsp) { + if (CollectionUtils.isEmpty(rsp.backingChain)) { + reply.putBackingChainInstallPath(installPath, Collections.emptyList()); + reply.putBackingChainSize(installPath, 0L); + } else { + reply.putBackingChainInstallPath(installPath, rsp.backingChain); + reply.putBackingChainSize(installPath, rsp.totalSize); + } + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.done(); + } + }); + }).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList err) { + if (!err.getCauses().isEmpty()) { + completion.fail(err.getCauses().get(0)); + } else { + completion.success(reply); + } + } + }); + } + @Override @MessageSafe void handleHypervisorSpecificMessage(LocalStorageHypervisorSpecificMessage msg) { @@ -2424,10 +2758,54 @@ class Context { downloadImage = false; } + flows.add(new NoRollbackFlow() { + String __name__ = "get-base-image-cache-of-root-volume"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + GetVolumeBaseImagePathCmd cmd = new GetVolumeBaseImagePathCmd(); + cmd.volumeInstallDir = makeVolumeInstallDir(struct.getVolume()); + cmd.volumeInstallPath = struct.getVolume().getInstallPath(); + cmd.imageCacheDir = getCachedImageDir(); + cmd.volumeUuid = struct.getVolume().getUuid(); + httpCall(GET_BASE_IMAGE_PATH, struct.getSrcHostUuid(), cmd, GetVolumeBaseImagePathRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(GetVolumeBaseImagePathRsp rsp) { + if (rsp.path != null && isCachedImageUrl(rsp.path)) { + context.baseImageCachePath = rsp.path; + context.baseImageCacheSize = rsp.size; + } else if (rsp.path == null && !CollectionUtils.isEmpty(rsp.otherPaths)) { + // TODO handle snapshot image + context.baseImageCachePath = rsp.otherPaths.get(0); + context.baseImageCacheSize = 0L; + } + + context.rootVolumeUuid = cmd.volumeUuid; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("cannot get volume base image %s, skip and continue", errorCode.getDetails())); + trigger.next(); + } + }); + } + }); + if (downloadImage) { flows.add(new NoRollbackFlow() { String __name__ = "download-base-image-to-dst-host"; + @Override + public boolean skip(Map data) { + if (context.baseImageCachePath == null) { + logger.debug("no base image cache, skip this flow"); + return true; + } + return false; + } + @Override public void run(final FlowTrigger trigger, Map data) { downloadImageToCache(ImageInventory.valueOf(context.image), struct.getDestHostUuid(), new ReturnValueCompletion(trigger) { @@ -2445,36 +2823,6 @@ public void fail(ErrorCode errorCode) { }); } else { context.hasbackingfile = true; - flows.add(new NoRollbackFlow() { - String __name__ = "get-base-image-cache-of-root-volume"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - GetVolumeBaseImagePathCmd cmd = new GetVolumeBaseImagePathCmd(); - cmd.volumeInstallDir = makeVolumeInstallDir(struct.getVolume()); - cmd.imageCacheDir = getCachedImageDir(); - cmd.volumeUuid = struct.getVolume().getUuid(); - httpCall(GET_BASE_IMAGE_PATH, struct.getSrcHostUuid(), cmd, GetVolumeBaseImagePathRsp.class, new ReturnValueCompletion(trigger) { - @Override - public void success(GetVolumeBaseImagePathRsp rsp) { - if (rsp.path != null && isCachedImageUrl(rsp.path)) { - context.baseImageCachePath = rsp.path; - context.baseImageCacheSize = rsp.size; - } - - context.rootVolumeUuid = cmd.volumeUuid; - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - logger.error(String.format("cannot get volume base image %s, skip and continue", errorCode.getDetails())); - trigger.next(); - } - }); - } - }); - flows.add(new Flow() { String __name__ = "reserve-capacity-for-base-image-cache-on-dst-host"; @@ -3080,15 +3428,33 @@ void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg, ReturnVal .eq(LocalStorageResourceRefVO_.resourceUuid, msg.getVolumeSnapshot().getUuid()) .find(); + boolean incremental = msg.hasSystemTag(VolumeSystemTags.FAST_CREATE.getTagFormat()); + if (incremental && PrimaryStorageGlobalProperty.USE_SNAPSHOT_AS_INCREMENTAL_CACHE) { + ImageCacheVO cache = createTemporaryImageCacheFromVolumeSnapshot(msg.getImageInventory(), msg.getVolumeSnapshot()); + LocalStorageUtils.InstallPath path = new LocalStorageUtils.InstallPath(); + path.volumeSnapshotUuid = msg.getVolumeSnapshot().getUuid(); + path.hostUuid = ref.getHostUuid(); + cache.setInstallUrl(path.makeFullPath()); + dbf.persist(cache); + reply.setLocateHostUuid(ref.getHostUuid()); + reply.setInventory(cache.toInventory()); + reply.setIncremental(true); + completion.success(reply); + return; + } + ImageCache cache = new ImageCache(); cache.primaryStorageInstallPath = makeCachedImageInstallUrl(msg.getImageInventory()); cache.hostUuid = ref.getHostUuid(); cache.image = msg.getImageInventory(); cache.volumeResourceInstallPath = msg.getVolumeSnapshot().getPrimaryStorageInstallPath(); + cache.incremental =incremental; cache.download(new ReturnValueCompletion(completion) { @Override - public void success(ImageCacheInventory cache) { + public void success(ImageCacheInventory inv) { reply.setLocateHostUuid(ref.getHostUuid()); + reply.setInventory(inv); + reply.setIncremental(cache.incremental); completion.success(reply); } @@ -3394,7 +3760,25 @@ public void fail(ErrorCode errorCode) { } @Override - void checkHostAttachedPSMountPath(String hostUuid, Completion completion) { + void handle(UnlinkBitsOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { + String hostUuid = getHostUuidByResourceUuid(msg.getResourceUuid(), msg.getResourceType()); + UnlinkBitsCmd cmd = new UnlinkBitsCmd(); + cmd.installPath = msg.getInstallPath(); + httpCall(UNLINK_BITS_PATH, hostUuid, cmd, UnlinkBitsRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(UnlinkBitsRsp rsp) { + completion.success(new UnlinkBitsOnPrimaryStorageReply()); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + void checkHostAttachedPSMountPath(String hostUuid, ReturnValueCompletion completion) { CheckInitializedFileCmd cmd = new CheckInitializedFileCmd(); cmd.uuid = self.getUuid(); cmd.filePath = makeInitializedFilePath(); @@ -3405,15 +3789,14 @@ void checkHostAttachedPSMountPath(String hostUuid, Completion completion) { @Override public void success(CheckInitializedFileRsp rsp) { if (!rsp.existed) { - completion.fail(operr("cannot find flag file [%s] on host [%s], it might not mount correct path", makeInitializedFilePath(), hostUuid)); - } else { - completion.success(); + rsp.setError(String.format("cannot find flag file [%s] on host [%s], it might not mount correct path", makeInitializedFilePath(), hostUuid)); } + completion.success(rsp); } @Override public void fail(ErrorCode errorCode) { - completion.fail(errorCode); + completion.fail(operr("cannot find flag file [%s] on host [%s], because: %s", makeInitializedFilePath(), hostUuid, errorCode.getCause().getDetails())); } }); } @@ -3434,7 +3817,7 @@ public void success(AgentResponse rsp) { @Override public void fail(ErrorCode errorCode) { - completion.fail(errorCode); + completion.fail(operr("cannot create flag file [%s] on host [%s], because: %s", makeInitializedFilePath(), hostUuid, errorCode.getCause().getDetails())); } }); } @@ -3485,4 +3868,47 @@ public void fail(ErrorCode errorCode) { private String makeInitializedFilePath() { return String.format("%s/%s-initialized-file", self.getMountPath(), self.getUuid()); } + + @Override + void handle(CommitVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, final ReturnValueCompletion completion) { + CommitVolumeSnapshotOnPrimaryStorageReply reply = new CommitVolumeSnapshotOnPrimaryStorageReply(); + OfflineCommitSnapshotCmd cmd = new OfflineCommitSnapshotCmd(); + cmd.top = msg.getSrcSnapshot().getPrimaryStorageInstallPath(); + cmd.base = msg.getDstSnapshot().getPrimaryStorageInstallPath(); + cmd.topChildrenInstallPathInDb = msg.getSrcChildrenInstallPathInDb(); + httpCall(OFFLINE_COMMIT_PATH, hostUuid, cmd, OfflineCommitSnapshotRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(OfflineCommitSnapshotRsp returnValue) { + reply.setSize(returnValue.getActualSize()); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + void handle(PullVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, final ReturnValueCompletion completion) { + PullVolumeSnapshotOnPrimaryStorageReply reply = new PullVolumeSnapshotOnPrimaryStorageReply(); + + OfflineMergeSnapshotCmd cmd = new OfflineMergeSnapshotCmd(); + cmd.srcPath = msg.getSrcSnapshotParentPath(); + cmd.destPath = msg.getDstSnapshot().getPrimaryStorageInstallPath(); + cmd.fullRebase = StringUtils.isEmpty(cmd.srcPath); + httpCall(OFFLINE_MERGE_PATH, hostUuid, cmd, OfflineMergeSnapshotRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(OfflineMergeSnapshotRsp rsp) { + reply.setSize(rsp.getActualSize()); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java index cefdaee4fed..8549d799eeb 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmFactory.java @@ -7,16 +7,26 @@ import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCode; -import org.zstack.header.host.*; +import org.zstack.header.host.AddHostMessage; +import org.zstack.header.host.FailToAddHostExtensionPoint; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.TakeSnapshotOnHypervisorMsg; import org.zstack.header.message.MessageReply; -import org.zstack.header.storage.primary.*; +import org.zstack.header.storage.primary.PrimaryStorageConstant; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.storage.primary.PrimaryStorageVO_; import org.zstack.header.storage.snapshot.VolumeSnapshotVO; import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeStats; import org.zstack.kvm.*; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -31,7 +41,7 @@ * Created by frank on 6/30/2015. */ public class LocalStorageKvmFactory implements LocalStorageHypervisorFactory, KVMHostConnectExtensionPoint, - FailToAddHostExtensionPoint, KVMStartVmExtensionPoint { + FailToAddHostExtensionPoint, KVMStartVmExtensionPoint, KVMTakeSnapshotExtensionPoint { private static final CLogger logger = Utils.getLogger(LocalStorageKvmFactory.class); @Autowired @@ -95,6 +105,7 @@ private void initLocalStorage(final Iterator iterator, InitPrimaryStorageOnHostConnectedMsg msg = new InitPrimaryStorageOnHostConnectedMsg(); msg.setPrimaryStorageUuid(priUuid); msg.setHostUuid(context.getInventory().getUuid()); + msg.setNewAddedHost(context.isNewAddedHost()); bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, priUuid); bus.send(msg, new CloudBusCallBack(trigger) { @Override @@ -159,4 +170,86 @@ public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { } + + private static boolean isLocalPrimaryStorage(String psUuid) { + return psUuid != null & Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.uuid, psUuid) + .eq(PrimaryStorageVO_.type, LocalStorageConstants.LOCAL_STORAGE_TYPE) + .isExists(); + } + + @Override + public void beforeTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, Completion completion) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isLocalPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + completion.success(); + return; + } + + VolumeInventory inv = msg.getVolume(); + inv.setInstallPath(msg.getInstallPath()); + PrimaryStorageVO primaryStorageVO = Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.type, LocalStorageConstants.LOCAL_STORAGE_TYPE) + .eq(PrimaryStorageVO_.uuid, msg.getVolume().getPrimaryStorageUuid()) + .find(); + + LocalStorageHypervisorBackend bkd = getHypervisorBackend(primaryStorageVO); + String backingFile = cmd.isOnline() ? cmd.getVolumeInstallPath() : null; + bkd.createEmptyVolumeWithBackingFile(inv, msg.getHostUuid(), backingFile, new ReturnValueCompletion(completion) { + @Override + public void success(VolumeStats returnValue) { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + ErrorCode err = operr("unable to create empty snapshot volume[name:%s, installpath: %s] on kvm host[uuid:%s, ip:%s], because %s", + msg.getSnapshotName(), msg.getInstallPath(), host.getUuid(), host.getManagementIp(), errorCode); + completion.fail(err); + } + }); + } + + @Override + public void afterTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, KVMAgentCommands.TakeSnapshotResponse rsp) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isLocalPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + return; + } + } + + @Override + public void afterTakeSnapshotFailed(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, KVMAgentCommands.TakeSnapshotResponse rsp, ErrorCode err) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isLocalPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + return; + } + + VolumeInventory inv = msg.getVolume(); + inv.setInstallPath(msg.getInstallPath()); + PrimaryStorageVO primaryStorageVO = Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.type, LocalStorageConstants.LOCAL_STORAGE_TYPE) + .eq(PrimaryStorageVO_.uuid, msg.getVolume().getPrimaryStorageUuid()) + .find(); + + LocalStorageHypervisorBackend bkd = getHypervisorBackend(primaryStorageVO); + + bkd.deleteBits(msg.getInstallPath(), host.getUuid(), new Completion(msg) { + @Override + public void success() { + logger.debug(String.format("successfully cleaned garbage snapshot volume[name: %s, installpath:%s] for take snapshot on volume[%s]", + msg.getSnapshotName(), cmd.getInstallPath(), msg.getVolume().getUuid())); + } + + @Override + public void fail(ErrorCode errorCode) { + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete path:%s right now, skip this GC job because it's in use", cmd.getInstallPath())); + return; + } + logger.debug(String.format("failed to clean garbage snapshot volume[name: %s, installpath:%s] for failed taking snapshot on volume[%s], "+ + "create gc job to clean garbage late", msg.getSnapshotName(), cmd.getInstallPath(), msg.getVolume().getUuid())); + } + }); + } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java index 8939c7c2ce2..789924c6d8e 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmMigrateVmFlow.java @@ -15,6 +15,7 @@ import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.HasThreadContext; @@ -85,22 +86,32 @@ public static class SnapshotTO { } public static class VerifySnapshotChainCmd extends LocalStorageKvmBackend.AgentCommand { + @GrayVersion(value = "5.0.0") public List snapshots; } public static class RebaseSnapshotBackingFilesCmd extends LocalStorageKvmBackend.AgentCommand { + @GrayVersion(value = "5.0.0") public List snapshots; } public static class CopyBitsFromRemoteCmd extends LocalStorageKvmBackend.AgentCommand implements HasThreadContext, Serializable { + @GrayVersion(value = "5.0.0") public String sendCommandUrl; + @GrayVersion(value = "5.0.0") public List paths; + @GrayVersion(value = "5.0.0") public String dstIp; @NoLogging + @GrayVersion(value = "5.0.0") public String dstPassword; + @GrayVersion(value = "5.0.0") public String dstUsername; + @GrayVersion(value = "5.0.0") public Integer dstPort = 22; + @GrayVersion(value = "5.0.0") public String stage; + @GrayVersion(value = "5.0.0") public String volumeUuid; } @@ -186,10 +197,53 @@ public void run(final FlowTrigger next, Map data) { @Override public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "get-base-image-cache-of-root-volume"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + GetVolumeBaseImagePathCmd cmd = new GetVolumeBaseImagePathCmd(); + cmd.volumeInstallDir = backend.makeVolumeInstallDir(rootVolume); + cmd.volumeInstallPath = rootVolume.getInstallPath(); + cmd.imageCacheDir = backend.getCachedImageDir(); + cmd.volumeUuid = rootVolume.getUuid(); + callKvmHost(srcHostUuid, ref.getPrimaryStorageUuid(), LocalStorageKvmBackend.GET_BASE_IMAGE_PATH, cmd, GetVolumeBaseImagePathRsp.class, new ReturnValueCompletion(trigger) { + @Override + public void success(GetVolumeBaseImagePathRsp rsp) { + if (rsp.path != null && backend.isCachedImageUrl(rsp.path)) { + backingImage.path = rsp.path; + backingImage.size = rsp.size; + } else if (rsp.path == null && !CollectionUtils.isEmpty(rsp.otherPaths)) { + // TODO handle snapshot image + backingImage.path = rsp.otherPaths.get(0); + backingImage.size = 0L; + } + + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("cannot get volume base image %s, skip and continue", errorCode.getDetails())); + trigger.next(); + } + }); + } + }); + if (downloadImage) { flow(new NoRollbackFlow() { String __name__ = "download-image-to-cache"; + @Override + public boolean skip(Map data) { + if (backingImage.path == null) { + logger.debug("no base image cache, skip this flow"); + return true; + } + return false; + } + @Override public void run(final FlowTrigger trigger, Map data) { DownloadImageToPrimaryStorageCacheMsg msg = new DownloadImageToPrimaryStorageCacheMsg(); @@ -215,34 +269,6 @@ public void run(MessageReply reply) { } }); } else { - flow(new NoRollbackFlow() { - String __name__ = "get-base-image-cache-of-root-volume"; - - @Override - public void run(final FlowTrigger trigger, Map data) { - GetVolumeBaseImagePathCmd cmd = new GetVolumeBaseImagePathCmd(); - cmd.volumeInstallDir = backend.makeVolumeInstallDir(rootVolume); - cmd.imageCacheDir = backend.getCachedImageDir(); - cmd.volumeUuid = rootVolume.getUuid(); - callKvmHost(srcHostUuid, ref.getPrimaryStorageUuid(), LocalStorageKvmBackend.GET_BASE_IMAGE_PATH, cmd, GetVolumeBaseImagePathRsp.class, new ReturnValueCompletion(trigger) { - @Override - public void success(GetVolumeBaseImagePathRsp rsp) { - if (rsp.path != null && backend.isCachedImageUrl(rsp.path)) { - backingImage.path = rsp.path; - backingImage.size = rsp.size; - } - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - logger.error(String.format("cannot get volume base image %s, skip and continue", errorCode.getDetails())); - trigger.next(); - } - }); - } - }); - flow(new Flow() { String __name__ = "reserve-capacity-for-base-image-cache-on-dst-host"; @@ -1329,10 +1355,11 @@ public void run(MessageReply r) { @Transactional(readOnly = true) private List getVolumeOnLocalStorage(VmInstanceSpec spec) { String sql = "select v from VolumeVO v, PrimaryStorageVO ps where v.primaryStorageUuid = ps.uuid" + - " and ps.type = :type and v.vmInstanceUuid = :vmUuid"; + " and ps.type = :type and v.vmInstanceUuid = :vmUuid and v.type != :memoryType"; TypedQuery q = dbf.getEntityManager().createQuery(sql, VolumeVO.class); q.setParameter("type", LocalStorageConstants.LOCAL_STORAGE_TYPE); q.setParameter("vmUuid", spec.getVmInventory().getUuid()); + q.setParameter("memoryType", VolumeType.Memory); return VolumeInventory.valueOf(q.getResultList()); } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java index 8bc6cc090b7..528d5a446e5 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageKvmSftpBackupStorageMediatorImpl.java @@ -6,6 +6,7 @@ import org.zstack.core.db.DatabaseFacade; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.timeout.ApiTimeoutManager; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.header.HasThreadContext; import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; @@ -43,11 +44,17 @@ public class LocalStorageKvmSftpBackupStorageMediatorImpl implements LocalStorag public static final String DOWNLOAD_BIT_PATH = "/localstorage/sftp/download"; public static class SftpDownloadBitsCmd extends LocalStorageKvmBackend.AgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String sshKey; + @GrayVersion(value = "5.0.0") private String username; + @GrayVersion(value = "5.0.0") private String hostname; + @GrayVersion(value = "5.0.0") private int sshPort; + @GrayVersion(value = "5.0.0") private String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") private String primaryStorageInstallPath; public String getUsername() { return username; @@ -99,12 +106,19 @@ public static class SftpDownloadBitsRsp extends LocalStorageKvmBackend.AgentResp } public static class SftpUploadBitsCmd extends LocalStorageKvmBackend.AgentCommand implements HasThreadContext{ + @GrayVersion(value = "5.0.0") private String primaryStorageInstallPath; + @GrayVersion(value = "5.0.0") private String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") private String hostname; + @GrayVersion(value = "5.0.0") private String sshKey; + @GrayVersion(value = "5.0.0") private String username; + @GrayVersion(value = "5.0.0") private String imageName; + @GrayVersion(value = "5.0.0") private int sshPort; public String getUsername() { return username; diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java index 8255c6c87c9..f73ea0e9c74 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageMainAllocatorFlow.java @@ -10,7 +10,6 @@ import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; -import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.host.HostState; import org.zstack.header.host.HostStatus; import org.zstack.header.storage.primary.*; @@ -57,34 +56,9 @@ private Result allocate(Map data) { Result ret = new Result(); long reservedCapacity = SizeUtils.sizeStringToBytes(PrimaryStorageGlobalConfig.RESERVED_CAPACITY.value()); - if (spec.getRequiredPrimaryStorageUuid() != null) { - String sql = "select ref" + - " from PrimaryStorageVO pri, LocalStorageHostRefVO ref, HostVO host" + - " where ref.primaryStorageUuid = pri.uuid" + - " and pri.state = :state" + - " and pri.status = :status" + - " and pri.uuid = :uuid" + - " and host.uuid = ref.hostUuid" + - " and host.state = :hstate" + - " and host.status = :hstatus" + - " and pri.type = :ptype"; - query = dbf.getEntityManager().createQuery(sql, LocalStorageHostRefVO.class); - query.setParameter("state", PrimaryStorageState.Enabled); - query.setParameter("status", PrimaryStorageStatus.Connected); - query.setParameter("uuid", spec.getRequiredPrimaryStorageUuid()); - query.setParameter("hstate", HostState.Enabled); - query.setParameter("hstatus", HostStatus.Connected); - query.setParameter("ptype", LocalStorageConstants.LOCAL_STORAGE_TYPE); - - ret.errStr = i18n("required local primary storage[uuid:%s] cannot satisfy conditions[state: %s, status: %s]," + - " or hosts providing the primary storage don't satisfy conditions[state: %s, status: %s, size > %s bytes]", - spec.getRequiredPrimaryStorageUuid(), - PrimaryStorageState.Enabled, - PrimaryStorageStatus.Connected, - HostState.Enabled, - HostStatus.Connected, - spec.getSize()); - } else if (spec.getRequiredHostUuid() != null) { + String primaryStorageCandidateSql = spec.getCandidatePrimaryStorageUuids().isEmpty() ? "" : String.format(" and pri.uuid in ('%s')", + String.join("','", spec.getCandidatePrimaryStorageUuids())); + if (spec.getRequiredHostUuid() != null) { String sql = "select lref" + " from PrimaryStorageVO pri, PrimaryStorageClusterRefVO pref, HostVO host, LocalStorageHostRefVO lref" + " where pri.uuid = pref.primaryStorageUuid" + @@ -94,6 +68,7 @@ private Result allocate(Map data) { " and host.clusterUuid = pref.clusterUuid" + " and pri.state = :pstate" + " and pri.status = :pstatus" + + primaryStorageCandidateSql + " and host.state = :hstate" + " and host.status = :hstatus" + " and pri.type = :ptype"; @@ -120,6 +95,7 @@ private Result allocate(Map data) { " and pri.state = :pstate" + " and pri.status = :pstatus" + " and pri.zoneUuid = :zoneUuid" + + primaryStorageCandidateSql + " and pri.type = :ptype" + " and host.uuid = ref.hostUuid" + " and host.state = :hstate" + @@ -146,6 +122,7 @@ private Result allocate(Map data) { " and host.uuid = ref.hostUuid" + " and pri.state = :pstate" + " and pri.status = :pstatus" + + primaryStorageCandidateSql + " and host.state = :hstate" + " and host.status = :hstatus" + " and pri.type = :ptype"; @@ -245,7 +222,7 @@ private Result allocate(Map data) { } } - if (spec.getRequiredPrimaryStorageUuid() == null && spec.getExcludePrimaryStorageTypes() != null && !spec.getExcludePrimaryStorageTypes().isEmpty()) { + if (spec.getCandidatePrimaryStorageUuids().isEmpty() && spec.getExcludePrimaryStorageTypes() != null && !spec.getExcludePrimaryStorageTypes().isEmpty()) { Iterator it = res.iterator(); while (it.hasNext()) { PrimaryStorageVO psvo = it.next(); @@ -262,6 +239,12 @@ private Result allocate(Map data) { } private Collection considerImageCache(PrimaryStorageAllocationSpec spec, List candidateHosts) { + if (spec.getImageUuid() == null) { + return candidateHosts.stream() + .map(LocalStorageHostRefVO::getPrimaryStorageUuid) + .collect(Collectors.toList()); + } + List ret = new ArrayList<>(); String sql = "select i.actualSize from ImageVO i where i.uuid = :uuid"; diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSnapshotDeletionProtector.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSnapshotDeletionProtector.java index d90bf1d79b1..2e59d6d8620 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSnapshotDeletionProtector.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSnapshotDeletionProtector.java @@ -20,14 +20,6 @@ public String getPrimaryStorageType() { @Override public void protect(VolumeSnapshotInventory snapshot, Completion completion) { - String backingToVolumeUuid = VolumeSnapshotSystemTags.BACKING_TO_VOLUME.getTokenByResourceUuid( - snapshot.getUuid(), VolumeSnapshotSystemTags.BACKING_VOLUME_TOKEN); - if (backingToVolumeUuid != null) { - completion.fail(operr("snapshot[uuid:%s] is backing file of volume[uuid:%s], cannot delete.", - snapshot.getUuid(), backingToVolumeUuid)); - return; - } - Path path = Paths.get(snapshot.getPrimaryStorageInstallPath()); if (!path.getParent().toString().contains(snapshot.getVolumeUuid())) { completion.fail(inerr("the snapshot[name:%s, uuid:%s, path: %s] seems not belong to the volume[uuid:%s]", diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSystemTags.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSystemTags.java index f52c4283aa5..849a763018e 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSystemTags.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageSystemTags.java @@ -1,8 +1,10 @@ package org.zstack.storage.primary.local; +import org.zstack.header.core.NonCloneable; import org.zstack.header.host.HostVO; import org.zstack.header.tag.TagDefinition; import org.zstack.header.volume.VolumeVO; +import org.zstack.tag.AllowDuplicateTag; import org.zstack.tag.PatternedSystemTag; /** @@ -11,11 +13,16 @@ @TagDefinition public class LocalStorageSystemTags { public static final String DEST_HOST_FOR_CREATING_DATA_VOLUME_TOKEN = "hostUuid"; + @NonCloneable public static PatternedSystemTag DEST_HOST_FOR_CREATING_DATA_VOLUME = new PatternedSystemTag( String.format("localStorage::hostUuid::{%s}", DEST_HOST_FOR_CREATING_DATA_VOLUME_TOKEN), VolumeVO.class ); + public static final String DEST_HOST_FOR_CREATING_ROOT_VOLUME_TOKEN = "hostUuid"; + @AllowDuplicateTag(defaultValue = true) + public static PatternedSystemTag DEST_HOST_FOR_CREATING_ROOT_VOLUME = DEST_HOST_FOR_CREATING_DATA_VOLUME; + public static final String LOCALSTORAGE_HOST_INITIALIZED_TOKEN = "primaryStorageUuid"; public static PatternedSystemTag LOCALSTORAGE_HOST_INITIALIZED = new PatternedSystemTag(String.format( "localStorage::{%s}::initialized", LOCALSTORAGE_HOST_INITIALIZED_TOKEN), HostVO.class); diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java index 4d70ad0ddf9..00ecbaea373 100644 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageUtils.java @@ -1,5 +1,6 @@ package org.zstack.storage.primary.local; +import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; @@ -11,8 +12,12 @@ import org.zstack.core.db.SQLBatchWithReturn; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.image.ImageConstant; import org.zstack.header.storage.primary.*; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO; +import org.zstack.header.storage.snapshot.VolumeSnapshotVO_; import org.zstack.storage.primary.PrimaryStoragePhysicalCapacityManager; +import org.zstack.tag.SystemTagUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -230,21 +235,51 @@ public static class InstallPath { public String fullPath; public String hostUuid; public String installPath; + public String volumeSnapshotUuid; public InstallPath disassemble() { DebugUtils.Assert(fullPath != null, "fullPath cannot be null"); String[] pair = fullPath.split(";"); DebugUtils.Assert(pair.length == 2, String.format("invalid cache path %s", fullPath)); - installPath = pair[0].replaceFirst("file://", ""); hostUuid = pair[1].replaceFirst("hostUuid://", ""); + + if (pair[0].startsWith(ImageConstant.SNAPSHOT_REUSE_IMAGE_SCHEMA)) { + String snapshotUuid = pair[0].replaceFirst(ImageConstant.SNAPSHOT_REUSE_IMAGE_SCHEMA, ""); + installPath = Q.New(VolumeSnapshotVO.class).eq(VolumeSnapshotVO_.uuid, snapshotUuid) + .select(VolumeSnapshotVO_.primaryStorageInstallPath) + .findValue(); + volumeSnapshotUuid = snapshotUuid; + } else { + installPath = pair[0].replaceFirst("file://", ""); + } return this; } public String makeFullPath() { - DebugUtils.Assert(installPath != null, "installPath cannot be null"); + DebugUtils.Assert(installPath != null || volumeSnapshotUuid != null, "installPath cannot be null"); DebugUtils.Assert(hostUuid != null, "hostUuid cannot be null"); - fullPath = String.format("file://%s;hostUuid://%s", installPath, hostUuid); + if (volumeSnapshotUuid == null) { + DebugUtils.Assert(!installPath.startsWith("file://"), "installPath cannot start with file://"); + fullPath = String.format("file://%s;hostUuid://%s", installPath, hostUuid); + } else { + fullPath = String.format("%s%s;hostUuid://%s", ImageConstant.SNAPSHOT_REUSE_IMAGE_SCHEMA, volumeSnapshotUuid, hostUuid); + } return fullPath; } } + + public static String getHostUuidFromInstallUrl(String installUrl) { + InstallPath p = new InstallPath(); + p.fullPath = installUrl; + p.disassemble(); + return p.hostUuid; + } + + public static String getHostUuidFromSystemTags(List systemTags) { + if (CollectionUtils.isEmpty(systemTags)) { + return null; + } + return SystemTagUtils.findTagValue(systemTags, LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME, + LocalStorageSystemTags.DEST_HOST_FOR_CREATING_DATA_VOLUME_TOKEN); + } } diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageVmMigrationMetric.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageVmMigrationMetric.java new file mode 100644 index 00000000000..e78b035b64b --- /dev/null +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/LocalStorageVmMigrationMetric.java @@ -0,0 +1,15 @@ +package org.zstack.storage.primary.local; + +import org.zstack.compute.vm.VmMigrationMetric; + +public class LocalStorageVmMigrationMetric implements VmMigrationMetric { + @Override + public boolean isCapable(String rootVolumePrimaryStorageType) { + return LocalStorageConstants.LOCAL_STORAGE_TYPE.equals(rootVolumePrimaryStorageType); + } + + @Override + public boolean isSupportWithSharedBlock() { + return false; + } +} diff --git a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/PackageInfo.java b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/PackageInfo.java index 9d34b599cc7..6f0770271d3 100755 --- a/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/PackageInfo.java +++ b/plugin/localstorage/src/main/java/org/zstack/storage/primary/local/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "本地存储") +@PackageAPIInfo( + APICategoryName = "本地存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/loginPlugin/pom.xml b/plugin/loginPlugin/pom.xml new file mode 100644 index 00000000000..3be14fc3082 --- /dev/null +++ b/plugin/loginPlugin/pom.xml @@ -0,0 +1,95 @@ + + 4.0.0 + + plugin + org.zstack + 5.4.0 + .. + + loginPlugin + + + org.zstack + kvm + ${project.version} + + + org.zstack + sftpBackupStorage + ${project.version} + + + org.zstack + storage + ${project.version} + + + org.zstack + header + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + diff --git a/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginPluginBackend.java b/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginPluginBackend.java new file mode 100644 index 00000000000..840b7d357f4 --- /dev/null +++ b/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginPluginBackend.java @@ -0,0 +1,91 @@ +package org.zstack.login.plugin; + +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.identity.LoginType; +import org.zstack.header.identity.login.AdditionalAuthFeature; +import org.zstack.header.identity.login.LoginBackend; +import org.zstack.header.identity.login.LoginContext; +import org.zstack.header.identity.login.LoginSessionInfo; +import org.zstack.utils.BeanUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.zstack.core.Platform.operr; + +public class LoginPluginBackend implements LoginBackend { + LoginType loginType = new LoginType("plugin"); + + private static final Map loginPluginExtensionMap = new HashMap<>(); + + static { + BeanUtils.reflections.getSubTypesOf(LoginPluginExtension.class).forEach(clz -> { + try { + LoginPluginExtension ext = clz.getConstructor().newInstance(); + LoginPluginExtension old = loginPluginExtensionMap.get(ext.getLoginPluginName()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate LoginPluginExtension[%s, %s] with type[%s]", + clz, old, ext.getLoginPluginName())); + } + + String type = ext.getLoginPluginName(); + if (type == null) { + return; + } + + loginPluginExtensionMap.put(ext.getLoginPluginName(), ext); + } catch (Exception e) { + throw new CloudRuntimeException(e); + } + }); + } + + @Override + public LoginType getLoginType() { + return loginType; + } + + @Override + public void login(LoginContext loginContext, ReturnValueCompletion completion) { + if (loginContext.getLoginPluginName() == null) { + throw new OperationFailureException(operr("missing loginPluginName")); + } + + LoginPluginExtension ext = loginPluginExtensionMap.get(loginContext.getLoginPluginName()); + if (ext == null) { + throw new OperationFailureException(operr("no login plugin named %s", loginContext.getLoginPluginName())); + } + + LoginUserInfo info = ext.login(loginContext.getUsername(), loginContext.getPassword()); + if (info == null || info.getUsername() == null) { + completion.fail(operr("missing LoginUserInfo when use plugin login", loginContext.getLoginPluginName())); + return; + } + + LoginSessionInfo session = new LoginSessionInfo(); + completion.success(session); + } + + @Override + public boolean authenticate(String username, String password) { + return true; + } + + @Override + public String getUserIdByName(String username) { + return null; + } + + @Override + public void collectUserInfoIntoContext(LoginContext loginContext) { + // plugin should not modify inner data + } + + @Override + public List getRequiredAdditionalAuthFeature() { + return null; + } +} diff --git a/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginPluginExtension.java b/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginPluginExtension.java new file mode 100644 index 00000000000..ac88c8e1030 --- /dev/null +++ b/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginPluginExtension.java @@ -0,0 +1,7 @@ +package org.zstack.login.plugin; + +public interface LoginPluginExtension { + String getLoginPluginName(); + + LoginUserInfo login(String username, String password); +} diff --git a/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginUserInfo.java b/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginUserInfo.java new file mode 100644 index 00000000000..2aef07394e9 --- /dev/null +++ b/plugin/loginPlugin/src/main/java/org/zstack/login/plugin/LoginUserInfo.java @@ -0,0 +1,22 @@ +package org.zstack.login.plugin; + +public class LoginUserInfo { + private String username; + private String userType; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } +} diff --git a/plugin/mediator/pom.xml b/plugin/mediator/pom.xml index 4f314a2a88d..c98247a956f 100755 --- a/plugin/mediator/pom.xml +++ b/plugin/mediator/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/mediator/src/main/java/org/zstack/mediator/ApiValidator.java b/plugin/mediator/src/main/java/org/zstack/mediator/ApiValidator.java index bc3e3b1cd85..a548c15a278 100755 --- a/plugin/mediator/src/main/java/org/zstack/mediator/ApiValidator.java +++ b/plugin/mediator/src/main/java/org/zstack/mediator/ApiValidator.java @@ -195,8 +195,15 @@ private void validate(APICreateEipMsg msg) { private void validate(APICreateLoadBalancerListenerMsg msg){ String vipUuid = Q.New(LoadBalancerVO.class).eq(LoadBalancerVO_.uuid, msg.getLoadBalancerUuid()).select(LoadBalancerVO_.vipUuid).findValue(); + String ipv6Uuid = Q.New(LoadBalancerVO.class).eq(LoadBalancerVO_.uuid, msg.getLoadBalancerUuid()).select(LoadBalancerVO_.ipv6VipUuid).findValue(); + RangeSet.Range cur = new RangeSet.Range(msg.getLoadBalancerPort(), msg.getLoadBalancerPort()); - checkVipPortConfliction(vipUuid, msg.getProtocol(), cur); + if (!StringUtils.isEmpty(vipUuid)) { + checkVipPortConfliction(vipUuid, msg.getProtocol(), cur); + } + if (!StringUtils.isEmpty(ipv6Uuid)) { + checkVipPortConfliction(ipv6Uuid, msg.getProtocol(), cur); + } } private RangeSet getVipPortRangeList(String vipUuid, String protocol){ diff --git a/plugin/nfsPrimaryStorage/pom.xml b/plugin/nfsPrimaryStorage/pom.xml index 9be6491c82a..2d63182f8e1 100755 --- a/plugin/nfsPrimaryStorage/pom.xml +++ b/plugin/nfsPrimaryStorage/pom.xml @@ -4,7 +4,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 .. nfsPrimaryStorage diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/APIAddNfsPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/APIAddNfsPrimaryStorageMsgDoc_zh_cn.groovy index f99dc17ac71..018dbcccad5 100644 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/APIAddNfsPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/APIAddNfsPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDeleteVolumeGC.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDeleteVolumeGC.java index d3922341de8..c561ca0bf2e 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDeleteVolumeGC.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDeleteVolumeGC.java @@ -1,5 +1,6 @@ package org.zstack.storage.primary.nfs; +import org.apache.commons.lang.StringUtils; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.gc.GC; import org.zstack.core.gc.GCCompletion; @@ -10,6 +11,9 @@ import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.header.volume.VolumeInventory; import org.zstack.header.volume.VolumeType; +import org.zstack.storage.volume.VolumeErrors; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; /** * Created by xing5 on 2017/3/5. @@ -22,12 +26,18 @@ public class NfsDeleteVolumeGC extends TimeBasedGarbageCollector { @GC public VolumeInventory volume; + private static final CLogger logger = Utils.getLogger(NfsDeleteVolumeGC.class); + @Override protected void triggerNow(GCCompletion completion) { if (!dbf.isExist(primaryStorageUuid, PrimaryStorageVO.class)) { completion.cancel(); return; } + if (StringUtils.isEmpty(volume.getInstallPath())) { + completion.cancel(); + return; + } DeleteVolumeBitsOnPrimaryStorageMsg msg = new DeleteVolumeBitsOnPrimaryStorageMsg(); msg.setInstallPath(volume.getInstallPath()); @@ -40,6 +50,11 @@ protected void triggerNow(GCCompletion completion) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { + if (reply.getError().isError(VolumeErrors.VOLUME_IN_USE)) { + logger.warn(String.format("unable to delete path:%s right now, cancel this GC job because it's in use", msg.getInstallPath())); + completion.cancel(); + return; + } completion.fail(reply.getError()); } else { completion.success(); diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDownloadImageToCacheJob.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDownloadImageToCacheJob.java index 1b70308a840..3ba33c480fc 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDownloadImageToCacheJob.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsDownloadImageToCacheJob.java @@ -3,6 +3,7 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.componentloader.PluginRegistry; @@ -10,13 +11,14 @@ import org.zstack.core.db.SimpleQuery; import org.zstack.core.job.Job; import org.zstack.core.job.JobContext; -import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.image.ImageConstant.ImageMediaType; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.backup.BackupStorageInventory; @@ -24,7 +26,7 @@ import org.zstack.header.storage.backup.BackupStorageVO; import org.zstack.header.storage.primary.*; import org.zstack.header.vm.VmInstanceSpec.ImageSpec; -import org.zstack.header.volume.VolumeInventory; +import org.zstack.storage.primary.ImageCacheUtil; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -43,6 +45,9 @@ public class NfsDownloadImageToCacheJob implements Job { private PrimaryStorageInventory primaryStorage; @JobContext private String volumeResourceInstallPath; + @JobContext + private boolean incremental; + @Autowired private NfsPrimaryStorageFactory nfsFactory; @@ -155,7 +160,7 @@ public void run(final FlowTrigger trigger, Map data) { private void downloadFromVolume(FlowTrigger trigger) { NfsPrimaryStorageBackend bkd = nfsFactory.getHypervisorBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid(image.getInventory().getFormat(), primaryStorage.getUuid())); - bkd.createImageCacheFromVolumeResource(primaryStorage, volumeResourceInstallPath, image.getInventory(), new ReturnValueCompletion(trigger) { + ReturnValueCompletion compl = new ReturnValueCompletion(trigger) { @Override public void success(NfsPrimaryStorageBackend.BitsInfo info) { cacheInstallPath = info.getInstallPath(); @@ -167,7 +172,13 @@ public void success(NfsPrimaryStorageBackend.BitsInfo info) { public void fail(ErrorCode errorCode) { trigger.fail(errorCode); } - }); + }; + + if (incremental) { + bkd.createIncrementalImageCacheFromVolumeResource(primaryStorage, volumeResourceInstallPath, image.getInventory(), compl); + } else { + bkd.createImageCacheFromVolumeResource(primaryStorage, volumeResourceInstallPath, image.getInventory(), compl); + } } private void downloadFromBackupStorage(FlowTrigger trigger) { @@ -207,9 +218,29 @@ public void handle(Map data) { image.getInventory().getUuid(), cvo.getId(), cvo.getInstallUrl())); ImageCacheVO finalCvo = cvo; - pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class) - .forEach(exp -> exp.saveEncryptAfterCreateImageCache(null, ImageCacheInventory.valueOf(finalCvo))); - completion.success(ImageCacheInventory.valueOf(cvo)); + + new While<>(pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class)).each((ext, whileCompletion) -> { + ext.saveEncryptAfterCreateImageCache(null, ImageCacheInventory.valueOf(finalCvo), new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + logger.warn(String.format("failed to saveEncryptAfterCreateImageCache: %s", errorCodeList.getCauses().get(0))); + } + completion.success(ImageCacheInventory.valueOf(finalCvo)); + } + }); } }); @@ -225,7 +256,7 @@ public void handle(ErrorCode errCode, Map data) { private void useExistingCache(final ImageCacheVO cvo, final ReturnValueCompletion completion) { NfsPrimaryStorageBackend bkd = nfsFactory.getHypervisorBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid(image.getInventory().getFormat(), primaryStorage.getUuid())); - bkd.checkIsBitsExisting(primaryStorage, cvo.getInstallUrl(), new ReturnValueCompletion(completion) { + bkd.checkIsBitsExisting(primaryStorage, ImageCacheUtil.getImageCachePath(cvo.toInventory()), new ReturnValueCompletion(completion) { @Override public void success(Boolean returnValue) { if (returnValue) { @@ -272,4 +303,12 @@ public void setPrimaryStorage(PrimaryStorageInventory primaryStorage) { public void setVolumeResourceInstallPath(String volumeResourceInstallPath) { this.volumeResourceInstallPath = volumeResourceInstallPath; } + + public void setIncremental(boolean incremental) { + this.incremental = incremental; + } + + public boolean isIncremental() { + return incremental; + } } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java index cd5a8cc09d7..1a1f39a18c0 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorage.java @@ -28,20 +28,16 @@ import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.*; -import org.zstack.header.image.ImageBackupStorageRefVO; -import org.zstack.header.image.ImageBackupStorageRefVO_; import org.zstack.header.image.ImageConstant.ImageMediaType; -import org.zstack.header.image.ImageEO; import org.zstack.header.image.ImageInventory; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.backup.BackupStorageInventory; import org.zstack.header.storage.backup.BackupStorageType; import org.zstack.header.storage.backup.BackupStorageVO; -import org.zstack.header.storage.backup.BackupStorageVO_; import org.zstack.header.storage.primary.*; import org.zstack.header.storage.primary.VolumeSnapshotCapability.VolumeSnapshotArrangementType; -import org.zstack.header.storage.snapshot.CreateImageCacheFromVolumeSnapshotReply; +import org.zstack.header.storage.snapshot.DeleteVolumeSnapshotDirection; import org.zstack.header.storage.snapshot.ShrinkVolumeSnapshotOnPrimaryStorageMsg; import org.zstack.header.storage.snapshot.VolumeSnapshotConstant; import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; @@ -50,9 +46,10 @@ import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.volume.*; -import org.zstack.kvm.KVMConstant; -import org.zstack.storage.primary.PrimaryStorageBase; -import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.kvm.*; +import org.zstack.storage.primary.*; +import org.zstack.storage.snapshot.reference.VolumeSnapshotReferenceUtils; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionUtils; @@ -64,10 +61,9 @@ import javax.persistence.Tuple; import javax.persistence.TypedQuery; import java.io.File; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import static org.zstack.core.Platform.err; import static org.zstack.core.Platform.operr; @@ -130,6 +126,12 @@ protected void handleLocalMessage(Message msg) { handle((CancelDownloadBitsFromKVMHostToPrimaryStorageMsg) msg); } else if ((msg instanceof GetDownloadBitsFromKVMHostProgressMsg)) { handle((GetDownloadBitsFromKVMHostProgressMsg) msg); + } else if (msg instanceof GetVolumeBackingChainFromPrimaryStorageMsg) { + handle((GetVolumeBackingChainFromPrimaryStorageMsg) msg); + } else if (msg instanceof CommitVolumeSnapshotOnPrimaryStorageMsg) { + handle((CommitVolumeSnapshotOnPrimaryStorageMsg) msg); + } else if (msg instanceof PullVolumeSnapshotOnPrimaryStorageMsg) { + handle((PullVolumeSnapshotOnPrimaryStorageMsg) msg); } else { super.handleLocalMessage(msg); } @@ -194,43 +196,49 @@ protected void done() { } @Override - protected void updatePrimaryStorage(APIUpdatePrimaryStorageMsg msg, ReturnValueCompletion completion) { - boolean update = false; - if (msg.getName() != null) { - self.setName(msg.getName()); - update = true; - } - if (msg.getDescription() != null) { - self.setDescription(msg.getDescription()); - update = true; - } - + protected void updatePrimaryStorage(APIUpdatePrimaryStorageMsg msg, ReturnValueCompletion completion) { if (msg.getUrl() != null && !self.getUrl().equals(msg.getUrl())) { - updateMountPoint(msg.getUrl(), new Completion(completion) { + thdf.chainSubmit(new ChainTask(msg) { + @Override - public void success() { - self.setUrl(msg.getUrl()); - self = dbf.updateAndRefresh(self); - for (UpdatePrimaryStorageExtensionPoint ext : pluginRgty.getExtensionList(UpdatePrimaryStorageExtensionPoint.class)) { - ext.afterUpdatePrimaryStorage(PrimaryStorageInventory.valueOf(self)); - } - completion.success(self); + public String getSyncSignature() { + return getSyncId(); } @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); + public String getName() { + return String.format("update-primary-storage-%s", self.getUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + updateMountPoint(msg.getUrl(), new Completion(completion) { + @Override + public void success() { + NfsPrimaryStorage.super.updatePrimaryStorage(msg, completion); + for (UpdatePrimaryStorageExtensionPoint ext : pluginRgty.getExtensionList(UpdatePrimaryStorageExtensionPoint.class)) { + ext.afterUpdatePrimaryStorage(PrimaryStorageInventory.valueOf(self)); + } + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }); } }); - return; + } else { + super.updatePrimaryStorage(msg, completion); } - completion.success(update ? self : null); } @Override protected void handle(APICleanUpImageCacheOnPrimaryStorageMsg msg) { APICleanUpImageCacheOnPrimaryStorageEvent evt = new APICleanUpImageCacheOnPrimaryStorageEvent(msg.getId()); - imageCacheCleaner.cleanup(msg.getUuid(), false); + imageCacheCleaner.cleanup(msg.getUuid(), new ImageCacheCleanParam(true, msg.isForce())); bus.publish(evt); } @@ -388,6 +396,24 @@ public void fail(ErrorCode errorCode) { }); } + @Override + protected void handle(FlattenVolumeOnPrimaryStorageMsg msg) { + final FlattenVolumeOnPrimaryStorageReply reply = new FlattenVolumeOnPrimaryStorageReply(); + final NfsPrimaryStorageBackend backend = getBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid(msg.getVolume().getFormat(), self.getUuid())); + backend.mergeSnapshotToVolume(getSelfInventory(), null, msg.getVolume(), true, new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + private void handle(final CreateVolumeFromVolumeSnapshotOnPrimaryStorageMsg msg) { final NfsPrimaryStorageBackend backend = getBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid(msg.getSnapshot().getFormat(), self.getUuid())); backend.handle(getSelfInventory(), msg, new ReturnValueCompletion(msg) { @@ -514,6 +540,7 @@ public void fail(ErrorCode errorCode) { gc.primaryStorageUuid = self.getUuid(); gc.hypervisorType = bkd.getHypervisorType().toString(); gc.submit(NfsPrimaryStorageGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); + reply.setGcSubmitted(true); logger.warn(String.format("NFS primary storage[uuid:%s] failed to delete a volume snapshot[uuid:%s], %s. A GC" + " job[uuid:%s] is scheduled to cleanup it in the interval of %s seconds", @@ -665,7 +692,7 @@ private void handle(PrimaryStorageRemoveCachedImageMsg msg) { @Transactional(readOnly = true) - private NfsPrimaryStorageBackend getUsableBackend() { + protected NfsPrimaryStorageBackend getUsableBackend() { List cuuids = CollectionUtils.transformToList(self.getAttachedClusterRefs(), new Function() { @Override public String call(PrimaryStorageClusterRefVO arg) { @@ -698,6 +725,13 @@ private NfsPrimaryStorageBackend getBackendByClusterUuid(String clusterUuid) { return getBackend(HypervisorType.valueOf(hvType)); } + private NfsPrimaryStorageBackend getBackendByHostUuid(String hostUuid) { + String hvType = Q.New(HostVO.class).select(HostVO_.hypervisorType) + .eq(HostVO_.uuid, hostUuid) + .findValue(); + return getBackend(HypervisorType.valueOf(hvType)); + } + private NfsPrimaryStorageBackend getBackend(HypervisorType hvType) { return factory.getHypervisorBackend(hvType); } @@ -753,6 +787,7 @@ private void handle(final InstantiateRootVolumeFromTemplateOnPrimaryStorageMsg m PrimaryStorageInventory primaryStorage = getSelfInventory(); ImageCacheInventory imageCache; String volumeInstallPath; + Long actualSize; @Override public void setup() { @@ -784,10 +819,15 @@ public void fail(ErrorCode errorCode) { @Override public void run(final FlowTrigger trigger, Map data) { NfsPrimaryStorageBackend backend = factory.getHypervisorBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid(image.getFormat(), self.getUuid())); - backend.createVolumeFromImageCache(primaryStorage, imageCache, volume, new ReturnValueCompletion(trigger) { + backend.createVolumeFromImageCache(primaryStorage, image, imageCache, volume, new ReturnValueCompletion(trigger) { @Override - public void success(String returnValue) { - volumeInstallPath = returnValue; + public void success(VolumeStats returnValue) { + volumeInstallPath = returnValue.getInstallPath(); + actualSize = returnValue.getActualSize(); + if (returnValue.getSize() != null) { + volume.setSize(returnValue.getSize()); + } + trigger.next(); } @@ -804,6 +844,7 @@ public void fail(ErrorCode errorCode) { public void handle(Map data) { volume.setInstallPath(volumeInstallPath); volume.setFormat(image.getFormat()); + volume.setActualSize(actualSize); reply.setVolume(volume); bus.reply(msg, reply); } @@ -882,7 +923,7 @@ private void createEmptyVolume(final InstantiateVolumeOnPrimaryStorageMsg msg) { VolumeInventory vol = msg.getVolume(); final InstantiateVolumeOnPrimaryStorageReply reply = new InstantiateVolumeOnPrimaryStorageReply(); - backend.instantiateVolume(PrimaryStorageInventory.valueOf(self), vol, new ReturnValueCompletion(msg) { + backend.instantiateVolume(PrimaryStorageInventory.valueOf(self), msg.getDestHost(), vol, new ReturnValueCompletion(msg) { @Override public void success(VolumeInventory returnValue) { reply.setVolume(returnValue); @@ -929,6 +970,12 @@ public void success() { @Override public void fail(ErrorCode errorCode) { + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete volume[uuid:%s] right now, skip this GC job because it's in use", msg.getVolume().getUuid())); + reply.setError(errorCode); + bus.reply(msg, reply); + return; + } NfsDeleteVolumeGC gc = new NfsDeleteVolumeGC(); gc.NAME = String.format("gc-nfs-%s-volume-%s", self.getUuid(), vol.getUuid()); gc.primaryStorageUuid = self.getUuid(); @@ -980,6 +1027,16 @@ public void fail(ErrorCode errorCode) { protected void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg) { CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply reply = new CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply(); + boolean incremental = msg.hasSystemTag(VolumeSystemTags.FAST_CREATE.getTagFormat()); + if (incremental && PrimaryStorageGlobalProperty.USE_SNAPSHOT_AS_INCREMENTAL_CACHE) { + ImageCacheVO cache = createTemporaryImageCacheFromVolumeSnapshot(msg.getImageInventory(), msg.getVolumeSnapshot()); + dbf.persist(cache); + reply.setInventory(cache.toInventory()); + reply.setIncremental(true); + bus.reply(msg, reply); + return; + } + ImageSpec spec = new ImageSpec(); spec.setInventory(msg.getImageInventory()); @@ -987,6 +1044,7 @@ protected void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg) job.setPrimaryStorage(getSelfInventory()); job.setImage(spec); job.setVolumeResourceInstallPath(msg.getVolumeSnapshot().getPrimaryStorageInstallPath()); + job.setIncremental(incremental); jobf.execute(NfsPrimaryStorageKvmHelper.makeDownloadImageJobName(msg.getImageInventory(), job.getPrimaryStorage()), NfsPrimaryStorageKvmHelper.makeJobOwnerName(job.getPrimaryStorage()), job, @@ -994,7 +1052,8 @@ protected void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg) @Override public void success(ImageCacheInventory cache) { - reply.setActualSize(cache.getSize()); + reply.setIncremental(job.isIncremental()); + reply.setInventory(cache); bus.reply(msg, reply); } @@ -1277,6 +1336,7 @@ protected void handle(AskVolumeSnapshotCapabilityMsg msg) { String volumeType = msg.getVolume().getType(); if (VolumeType.Data.toString().equals(volumeType) || VolumeType.Root.toString().equals(volumeType)) { capability.setArrangementType(VolumeSnapshotArrangementType.CHAIN); + capability.setPlacementType(VolumeSnapshotCapability.VolumeSnapshotPlacementType.EXTERNAL); } else if (VolumeType.Memory.toString().equals(volumeType)) { capability.setArrangementType(VolumeSnapshotArrangementType.INDIVIDUAL); } else { @@ -1316,6 +1376,47 @@ public void fail(ErrorCode errorCode) { }); } + @Override + protected void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg) { + NfsPrimaryStorageBackend backend = getUsableBackend(); + if (backend == null) { + throw new OperationFailureException(operr("the NFS primary storage[uuid:%s, name:%s] cannot find hosts in attached clusters to perform the operation", + self.getUuid(), self.getName())); + } + + backend.handle(getSelfInventory(), msg, new ReturnValueCompletion(msg) { + @Override + public void success(EstimateVolumeTemplateSizeOnPrimaryStorageReply reply) { + saveVolumeProvisioningStrategy(msg.getVolumeUuid(), reply.getActualSize() < reply.getSize() ? VolumeProvisioningStrategy.ThinProvisioning : VolumeProvisioningStrategy.ThickProvisioning); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(BatchSyncVolumeSizeOnPrimaryStorageMsg msg) { + NfsPrimaryStorageBackend backend = getBackendByHostUuid(msg.getHostUuid()); + backend.handle(getSelfInventory(), msg, new ReturnValueCompletion(msg) { + @Override + public void success(BatchSyncVolumeSizeOnPrimaryStorageReply reply) { + bus.reply(msg, reply); + } + @Override + public void fail(ErrorCode errorCode) { + BatchSyncVolumeSizeOnPrimaryStorageReply reply = new BatchSyncVolumeSizeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + protected void saveVolumeProvisioningStrategy(String volumeUuid, VolumeProvisioningStrategy strategy) { if (!VolumeSystemTags.VOLUME_PROVISIONING_STRATEGY.hasTag(volumeUuid)) { SystemTagCreator tagCreator = VolumeSystemTags.VOLUME_PROVISIONING_STRATEGY.newSystemTagCreator(volumeUuid); @@ -1453,6 +1554,27 @@ public void fail(ErrorCode errorCode) { }); } + private void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg) { + NfsPrimaryStorageBackend backend = getUsableBackend(); + if (backend == null) { + throw new OperationFailureException(operr("the NFS primary storage[uuid:%s, name:%s] cannot find hosts in attached clusters to perform the operation", + self.getUuid(), self.getName())); + } + backend.handle(getSelfInventory(), msg, new ReturnValueCompletion(msg) { + @Override + public void success(GetVolumeBackingChainFromPrimaryStorageReply reply) { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + protected void handle(NfsRecalculatePrimaryStorageCapacityMsg msg) { if (msg.isRelease()) { doReleasePrimaryStorageCapacity(); @@ -1479,6 +1601,33 @@ public PrimaryStorageCapacityVO call(PrimaryStorageCapacityVO cap) { }); } + public static class NfsConnectParam { + private StorageRemountReason reason; + private boolean newAdded; + + public StorageRemountReason getReason() { + return reason; + } + + public void setReason(StorageRemountReason reason) { + this.reason = reason; + } + + public boolean isNewAdded() { + return newAdded; + } + + public void setNewAdded(boolean newAdded) { + this.newAdded = newAdded; + } + + public static NfsConnectParam fromConnectParam(ConnectParam param) { + NfsConnectParam nfsConnectParam = new NfsConnectParam(); + nfsConnectParam.setNewAdded(param.isNewAdded()); + return nfsConnectParam; + } + } + @Override protected void connectHook(ConnectParam param, final Completion completion) { final NfsPrimaryStorageBackend backend = getUsableBackend(); @@ -1502,6 +1651,8 @@ protected void connectHook(ConnectParam param, final Completion completion) { return; } + NfsConnectParam nfsConnectParam = NfsConnectParam.fromConnectParam(param); + nfsConnectParam.setReason(StorageRemountReason.PrimaryStorageConnection); PrimaryStorageInventory inv = getSelfInventory(); new LoopAsyncBatch(completion) { boolean success; @@ -1517,7 +1668,7 @@ protected AsyncBatchRunner forEach(String cuuid) { @Override public void run(NoErrorCompletion completion) { NfsPrimaryStorageBackend bkd = getBackendByClusterUuid(cuuid); - bkd.remount(inv, cuuid, new Completion(completion) { + bkd.remount(inv, cuuid, nfsConnectParam, new Completion(completion) { @Override public void success() { success = true; @@ -1658,8 +1809,38 @@ protected void handle(CheckVolumeSnapshotOperationOnPrimaryStorageMsg msg) { bus.reply(msg, reply); } + private ErrorCode checkChangeVolumeType(String volumeUuid) { + List refVols = VolumeSnapshotReferenceUtils.getReferenceVolume(volumeUuid); + if (refVols.isEmpty()) { + return null; + } + + List infos = refVols.stream().map(v -> String.format("uuid:%s, name:%s", v.getUuid(), v.getName())).collect(Collectors.toList()); + return operr("volume[uuid:%s] has reference volume[%s], can not change volume type before flatten " + + "them and their descendants", volumeUuid, infos.toString()); + } + + @Override + protected void handle(CheckChangeVolumeTypeOnPrimaryStorageMsg msg) { + CheckChangeVolumeTypeOnPrimaryStorageReply reply = new CheckChangeVolumeTypeOnPrimaryStorageReply(); + ErrorCode errorCode = checkChangeVolumeType(msg.getVolume().getUuid()); + if (errorCode != null) { + reply.setError(errorCode);; + } + + bus.reply(msg, reply); + } + @Override protected void handle(ChangeVolumeTypeOnPrimaryStorageMsg msg) { + ErrorCode errorCode = checkChangeVolumeType(msg.getVolume().getUuid()); + if (errorCode != null) { + ChangeVolumeTypeOnPrimaryStorageReply reply = new ChangeVolumeTypeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + return; + } + NfsPrimaryStorageBackend backend = getUsableBackend(); if (backend == null) { throw new OperationFailureException(operr("the NFS primary storage[uuid:%s, name:%s] cannot find hosts in attached clusters to perform the operation", @@ -1680,4 +1861,111 @@ public void fail(ErrorCode errorCode) { } }); } + + protected void handle(UnlinkBitsOnPrimaryStorageMsg msg) { + UnlinkBitsOnPrimaryStorageReply reply = new UnlinkBitsOnPrimaryStorageReply(); + NfsPrimaryStorageBackend backend = getUsableBackend(); + if (backend == null) { + throw new OperationFailureException(operr("the NFS primary storage[uuid:%s, name:%s] cannot find hosts in attached clusters to perform the operation", + self.getUuid(), self.getName())); + } + + backend.unlink(getSelfInventory(), msg.getInstallPath(), new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + protected void handle(CommitVolumeSnapshotOnPrimaryStorageMsg msg) { + CommitVolumeSnapshotOnPrimaryStorageReply reply = new CommitVolumeSnapshotOnPrimaryStorageReply(); + + String hostUuid = getHostUuidFromVolume(msg.getVolume().getUuid()); + if (hostUuid == null || hostUuid.isEmpty()) { + reply.setError(operr("no host found for volume[uuid:%s]", msg.getVolume().getUuid())); + bus.reply(msg, reply); + return; + } + + final NfsPrimaryStorageBackend backend = getBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid( + msg.getVolume().getFormat(), self.getUuid())); + + backend.commitSnapshot(msg, hostUuid, new ReturnValueCompletion(msg) { + @Override + public void success(CommitVolumeSnapshotOnPrimaryStorageReply r) { + bus.reply(msg, r); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + protected void handle(PullVolumeSnapshotOnPrimaryStorageMsg msg) { + PullVolumeSnapshotOnPrimaryStorageReply reply = new PullVolumeSnapshotOnPrimaryStorageReply(); + + String hostUuid = getHostUuidFromVolume(msg.getVolume().getUuid()); + if (hostUuid == null || hostUuid.isEmpty()) { + reply.setError(operr("no host found for volume[uuid:%s]", msg.getVolume().getUuid())); + bus.reply(msg, reply); + return; + } + + final NfsPrimaryStorageBackend backend = getBackend(nfsMgr.findHypervisorTypeByImageFormatAndPrimaryStorageUuid( + msg.getVolume().getFormat(), self.getUuid())); + + backend.pullSnapshot(msg, hostUuid, new ReturnValueCompletion(msg) { + @Override + public void success(PullVolumeSnapshotOnPrimaryStorageReply r) { + bus.reply(msg, r); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private String getHostUuidFromVolume(String volumeUuid) { + VolumeVO vol = dbf.findByUuid(volumeUuid, VolumeVO.class); + + String hostUuid = ""; + List connectedHost = factory.getConnectedHostForOperation(getSelfInventory()); + if (connectedHost.isEmpty()) { + return hostUuid; + } + String connectedHostUuid = factory.getConnectedHostForOperation(getSelfInventory()).get(0).getUuid(); + if (vol.getVmInstanceUuid() != null) { + Tuple t = Q.New(VmInstanceVO.class) + .select(VmInstanceVO_.state, VmInstanceVO_.hostUuid) + .eq(VmInstanceVO_.uuid, vol.getVmInstanceUuid()) + .findTuple(); + VmInstanceState state = t.get(0, VmInstanceState.class); + String vmHostUuid = t.get(1, String.class); + + if (state == VmInstanceState.Running || state == VmInstanceState.Paused) { + DebugUtils.Assert(vmHostUuid != null, + String.format("vm[uuid:%s] is Running or Paused, but has no hostUuid", vol.getVmInstanceUuid())); + hostUuid = vmHostUuid; + } else if (state == VmInstanceState.Stopped) { + hostUuid = connectedHostUuid; + } + } else { + hostUuid = connectedHostUuid; + } + + return hostUuid; + } } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageBackend.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageBackend.java index 2edba7e4b00..6c26e682ce6 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageBackend.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageBackend.java @@ -7,7 +7,12 @@ import org.zstack.header.image.ImageInventory; import org.zstack.header.storage.primary.*; import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; +import org.zstack.header.volume.VolumeStats; +import org.zstack.header.volume.BatchSyncVolumeSizeOnPrimaryStorageMsg; +import org.zstack.header.volume.BatchSyncVolumeSizeOnPrimaryStorageReply; import org.zstack.header.volume.VolumeInventory; +import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageMsg; +import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageReply; import org.zstack.storage.primary.PrimaryStorageBase.PhysicalCapacityUsage; public interface NfsPrimaryStorageBackend { @@ -23,8 +28,14 @@ public interface NfsPrimaryStorageBackend { void handle(PrimaryStorageInventory inv, SyncVolumeSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + void handle(PrimaryStorageInventory inv, EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + + void handle(PrimaryStorageInventory inv, BatchSyncVolumeSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + void handle(PrimaryStorageInventory inv, GetVolumeRootImageUuidFromPrimaryStorageMsg msg, ReturnValueCompletion completion); + void handle(PrimaryStorageInventory inv, GetVolumeBackingChainFromPrimaryStorageMsg msg, ReturnValueCompletion completion); + void handle(PrimaryStorageInventory inv, NfsToNfsMigrateBitsMsg msg, ReturnValueCompletion completion); void handle(PrimaryStorageInventory inv, NfsRebaseVolumeBackingFileMsg msg, ReturnValueCompletion completion); @@ -51,19 +62,22 @@ public interface NfsPrimaryStorageBackend { void createMemoryVolume(PrimaryStorageInventory pinv, VolumeInventory volume, ReturnValueCompletion completion); - void instantiateVolume(PrimaryStorageInventory pinv, VolumeInventory volume, ReturnValueCompletion complete); + void instantiateVolume(PrimaryStorageInventory pinv, HostInventory hostInventory, VolumeInventory volume, ReturnValueCompletion complete); void deleteImageCache(ImageCacheInventory imageCache); void delete(PrimaryStorageInventory pinv, String installPath, Completion completion); void deleteFolder(PrimaryStorageInventory pinv, String installPath, Completion completion); + void unlink(PrimaryStorageInventory pinv, String installPath, Completion completion); void revertVolumeFromSnapshot(VolumeSnapshotInventory sinv, VolumeInventory vol, HostInventory host, ReturnValueCompletion completion); void resetRootVolumeFromImage(VolumeInventory vol, HostInventory host, ReturnValueCompletion completion); - void createVolumeFromImageCache(PrimaryStorageInventory primaryStorage, ImageCacheInventory image, VolumeInventory volume, ReturnValueCompletion completion); + void createVolumeFromImageCache(PrimaryStorageInventory primaryStorage, ImageInventory image, ImageCacheInventory imageCache, VolumeInventory volume, ReturnValueCompletion completion); + + void createIncrementalImageCacheFromVolumeResource(PrimaryStorageInventory primaryStorage, String volumeResourceInstallPath, ImageInventory image, ReturnValueCompletion completion); void createImageCacheFromVolumeResource(PrimaryStorageInventory primaryStorage, String volumeResourceInstallPath, ImageInventory image, ReturnValueCompletion completion); @@ -71,7 +85,11 @@ public interface NfsPrimaryStorageBackend { void mergeSnapshotToVolume(PrimaryStorageInventory pinv, VolumeSnapshotInventory snapshot, VolumeInventory volume, boolean fullRebase, Completion completion); - void remount(PrimaryStorageInventory pinv, String clusterUuid, Completion completion); + void remount(PrimaryStorageInventory pinv, String clusterUuid, NfsPrimaryStorage.NfsConnectParam param, Completion completion); + + void pullSnapshot(PullVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); + + void commitSnapshot(CommitVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion); void updateMountPoint(PrimaryStorageInventory pinv, String clusterUuid, String oldMountPoint, String newMountPoint, Completion completion); diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java index 991f83c6785..19a4ece30a3 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageFactory.java @@ -1,5 +1,6 @@ package org.zstack.storage.primary.nfs; +import org.apache.logging.log4j.ThreadContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.vm.VmExpungeRootVolumeValidator; @@ -18,6 +19,7 @@ import org.zstack.header.Component; import org.zstack.header.cluster.ClusterUpdateOSExtensionPoint; import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.cluster.UpdateClusterOSStruct; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; @@ -36,6 +38,7 @@ import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.header.vo.ResourceVO; import org.zstack.header.volume.*; import org.zstack.kvm.KVMConstant; import org.zstack.storage.primary.ChangePrimaryStorageStatusMsg; @@ -45,6 +48,7 @@ import org.zstack.storage.snapshot.PostMarkRootVolumeAsSnapshotExtension; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; +import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.path.PathUtil; @@ -54,6 +58,7 @@ import java.util.*; import java.util.concurrent.Callable; +import static org.zstack.header.Constants.THREAD_CONTEXT_API; import static org.zstack.utils.CollectionDSL.*; public class NfsPrimaryStorageFactory implements NfsPrimaryStorageManager, PrimaryStorageFactory, Component, CreateTemplateFromVolumeSnapshotExtensionPoint, RecalculatePrimaryStorageCapacityExtensionPoint, @@ -150,6 +155,11 @@ public PrimaryStorageInventory getInventory(String uuid) { return PrimaryStorageInventory.valueOf(vo); } + @Override + public void validateStorageProtocol(String protocol) { + + } + private void populateExtensions() { for (NfsPrimaryStorageBackend extp : pluginRgty.getExtensionList(NfsPrimaryStorageBackend.class)) { NfsPrimaryStorageBackend old = backends.get(extp.getHypervisorType().toString()); @@ -296,7 +306,12 @@ public List getConnectedHostForOperation(PrimaryStorageInventory operr("cannot find a host which has Connected host-NFS connection to execute command " + "for nfs primary storage[uuid:%s]", pri.getUuid())); } else { - Collections.shuffle(ret); + String apiId = ThreadContext.get(THREAD_CONTEXT_API); + if (apiId != null) { + CollectionUtils.shuffleByKeySeed(ret, apiId, ResourceVO::getUuid); + } else { + Collections.shuffle(ret); + } return HostInventory.valueOf(ret); } } @@ -697,7 +712,7 @@ private void recalculateCapacity(String psUuid){ } @Override - public String preUpdateClusterOS(ClusterVO cls) { + public String preUpdateClusterOS(UpdateClusterOSStruct updateClusterOSStruct) { // do not update hosts that also run nfs ps List matched = new ArrayList<>(); @@ -706,7 +721,7 @@ public String preUpdateClusterOS(ClusterVO cls) { protected void scripts() { List hostIps = q(HostVO.class) .select(HostVO_.managementIp) - .eq(HostVO_.clusterUuid, cls.getUuid()) + .eq(HostVO_.clusterUuid, updateClusterOSStruct.getCluster().getUuid()) .listValues(); for (String hostIp : hostIps) { diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java index 7edcc261a93..5ad1919dd0f 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackend.java @@ -2,9 +2,9 @@ import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Primary; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.Platform; import org.zstack.core.asyncbatch.AsyncBatchRunner; import org.zstack.core.asyncbatch.LoopAsyncBatch; import org.zstack.core.asyncbatch.While; @@ -13,6 +13,7 @@ import org.zstack.core.cloudbus.EventFacade; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; @@ -20,10 +21,9 @@ import org.zstack.core.step.StepRunCondition; import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.core.trash.StorageTrash; +import org.zstack.core.upgrade.UpgradeChecker; import org.zstack.header.core.*; -import org.zstack.header.core.workflow.Flow; -import org.zstack.header.core.workflow.FlowTrigger; -import org.zstack.header.core.workflow.NoRollbackFlow; +import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; @@ -41,20 +41,15 @@ import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmInstanceVO_; -import org.zstack.header.volume.VolumeConstant; -import org.zstack.header.volume.VolumeInventory; -import org.zstack.header.volume.VolumeType; -import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.*; import org.zstack.identity.AccountManager; import org.zstack.kvm.*; import org.zstack.kvm.KVMAgentCommands.AgentResponse; +import org.zstack.storage.primary.*; import org.zstack.storage.primary.PrimaryStorageBase.PhysicalCapacityUsage; -import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; -import org.zstack.storage.primary.PrimaryStorageSystemTags; import org.zstack.storage.primary.nfs.NfsPrimaryStorageKVMBackendCommands.*; -import org.zstack.storage.snapshot.VolumeSnapshotSystemTags; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; -import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; @@ -68,6 +63,8 @@ import java.util.*; import java.util.Map.Entry; import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import static java.lang.Integer.min; @@ -76,7 +73,7 @@ public class NfsPrimaryStorageKVMBackend implements NfsPrimaryStorageBackend, KVMHostConnectExtensionPoint, HostConnectionReestablishExtensionPoint, - KVMStartVmExtensionPoint { + KVMStartVmExtensionPoint, KVMTakeSnapshotExtensionPoint { private static final CLogger logger = Utils.getLogger(NfsPrimaryStorageKVMBackend.class); @Autowired @@ -99,6 +96,8 @@ public class NfsPrimaryStorageKVMBackend implements NfsPrimaryStorageBackend, private StorageTrash trash; @Autowired protected ApiTimeoutManager timeoutManager; + @Autowired + private UpgradeChecker upgradeChecker; public static final String MOUNT_PRIMARY_STORAGE_PATH = "/nfsprimarystorage/mount"; public static final String UNMOUNT_PRIMARY_STORAGE_PATH = "/nfsprimarystorage/unmount"; @@ -106,6 +105,7 @@ public class NfsPrimaryStorageKVMBackend implements NfsPrimaryStorageBackend, public static final String CREATE_FOLDER_PATH = "/nfsprimarystorage/createfolder"; public static final String GET_CAPACITY_PATH = "/nfsprimarystorage/getcapacity"; public static final String DELETE_PATH = "/nfsprimarystorage/delete"; + public static final String UNLINK_PATH = "/nfsprimarystorage/unlink"; public static final String CHECK_BITS_PATH = "/nfsprimarystorage/checkbits"; public static final String MOVE_BITS_PATH = "/nfsprimarystorage/movebits"; public static final String MERGE_SNAPSHOT_PATH = "/nfsprimarystorage/mergesnapshot"; @@ -113,13 +113,18 @@ public class NfsPrimaryStorageKVMBackend implements NfsPrimaryStorageBackend, public static final String REVERT_VOLUME_FROM_SNAPSHOT_PATH = "/nfsprimarystorage/revertvolumefromsnapshot"; public static final String REINIT_IMAGE_PATH = "/nfsprimarystorage/reinitimage"; public static final String CREATE_TEMPLATE_FROM_VOLUME_PATH = "/nfsprimarystorage/sftp/createtemplatefromvolume"; + public static final String ESTIMATE_TEMPLATE_SIZE_PATH = "/nfsprimarystorage/estimatetemplatesize"; public static final String CREATE_VOLUME_WITH_BACKING_PATH = "/nfsprimarystorage/createvolumewithbacking"; public static final String OFFLINE_SNAPSHOT_MERGE = "/nfsprimarystorage/offlinesnapshotmerge"; + public static final String OFFLINE_SNAPSHOT_COMMIT = "/nfsprimarystorage/offlinesnapshotcommit"; public static final String REMOUNT_PATH = "/nfsprimarystorage/remount"; public static final String GET_VOLUME_SIZE_PATH = "/nfsprimarystorage/getvolumesize"; + public static final String BATCH_GET_VOLUME_SIZE_PATH = "/nfsprimarystorage/batchgetvolumesize"; public static final String HARD_LINK_VOLUME = "/nfsprimarystorage/volume/hardlink"; public static final String PING_PATH = "/nfsprimarystorage/ping"; public static final String GET_VOLUME_BASE_IMAGE_PATH = "/nfsprimarystorage/getvolumebaseimage"; + + public static final String GET_BACKING_CHAIN_PATH = "/nfsprimarystorage/volume/getbackingchain"; public static final String UPDATE_MOUNT_POINT_PATH = "/nfsprimarystorage/updatemountpoint"; public static final String NFS_TO_NFS_MIGRATE_BITS_PATH = "/nfsprimarystorage/migratebits"; public static final String NFS_REBASE_VOLUME_BACKING_FILE_PATH = "/nfsprimarystorage/rebasevolumebackingfile"; @@ -418,7 +423,13 @@ public void fail(ErrorCode errorCode) { private void doPing(List hostUuids, PrimaryStorageInventory psInv, Completion completion){ List errs = new ArrayList<>(); + AtomicBoolean isCapacityUpdated = new AtomicBoolean(false); new While<>(hostUuids).each((huuid, compl) -> { + if (upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(huuid)) { + compl.done(); + return; + } + PingCmd cmd = new PingCmd(); cmd.setUuid(psInv.getUuid()); cmd.mountPath = psInv.getMountPath(); @@ -436,6 +447,9 @@ public void run(MessageReply reply) { NfsPrimaryStorageAgentResponse rsp = ((KVMHostAsyncHttpCallReply) reply).toResponse(NfsPrimaryStorageAgentResponse.class); if (rsp.isSuccess()) { nfsFactory.updateNfsHostStatus(psInv.getUuid(), huuid, PrimaryStorageHostStatus.Connected); + if (isCapacityUpdated.compareAndSet(false, true)) { + updatePrimaryStorageCapacity(psInv.getUuid(), rsp); + } } else { ErrorCode err = operr("failed to ping nfs primary storage[uuid:%s] from host[uuid:%s],because %s. " + "disconnect this host-ps connection", @@ -679,7 +693,7 @@ public void success(KvmResponseWrapper wrapper) { reply.setActualSize(rsp.getActualSize()); reply.setSize(rsp.getSize()); reply.setInstallPath(volPath); - createProtectTag(); + reply.setIncremental(true); completion.success(reply); } @@ -687,13 +701,6 @@ public void success(KvmResponseWrapper wrapper) { public void fail(ErrorCode errorCode) { completion.fail(errorCode); } - - private void createProtectTag() { - SystemTagCreator creator = VolumeSnapshotSystemTags.BACKING_TO_VOLUME.newSystemTagCreator(sp.getUuid()); - creator.unique = false; - creator.setTagByTokens(Collections.singletonMap(VolumeSnapshotSystemTags.BACKING_VOLUME_TOKEN, volumeUuid)); - creator.create(); - } }); } @@ -749,31 +756,73 @@ public void fail(ErrorCode errorCode) { }); } + @Override + public void handle(PrimaryStorageInventory inv, EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { + EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + + EstimateTemplateSizeCmd cmd = new EstimateTemplateSizeCmd(); + cmd.setVolumePath(msg.getInstallPath()); + + final HostInventory host = nfsFactory.getConnectedHostForOperation(inv).get(0); + asyncHttpCall(ESTIMATE_TEMPLATE_SIZE_PATH, host.getUuid(), cmd, EstimateTemplateSizeRsp.class, inv, new ReturnValueCompletion(completion) { + @Override + public void success(EstimateTemplateSizeRsp rsp) { + reply.setActualSize(rsp.getActualSize()); + reply.setSize(rsp.getSize()); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + public void handle(PrimaryStorageInventory inv, BatchSyncVolumeSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { + BatchSyncVolumeSizeOnPrimaryStorageReply reply = new BatchSyncVolumeSizeOnPrimaryStorageReply(); + + GetBatchVolumeActualSizeCmd cmd = new GetBatchVolumeActualSizeCmd(); + cmd.volumeUuidInstallPaths = msg.getVolumeUuidInstallPaths(); + cmd.setUuid(inv.getUuid()); + + asyncHttpCall(BATCH_GET_VOLUME_SIZE_PATH, msg.getHostUuid(), cmd, GetBatchVolumeActualSizeRsp.class, inv, new ReturnValueCompletion(completion) { + @Override + public void success(GetBatchVolumeActualSizeRsp rsp) { + reply.setActualSizes(rsp.actualSizes); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + @Override public void handle(PrimaryStorageInventory inv, GetVolumeRootImageUuidFromPrimaryStorageMsg msg, final ReturnValueCompletion completion) { GetVolumeBaseImagePathCmd cmd = new GetVolumeBaseImagePathCmd(); cmd.volumeUuid = msg.getVolume().getUuid(); cmd.volumeInstallDir = NfsPrimaryStorageKvmHelper.makeVolumeInstallDir(inv, msg.getVolume()); + cmd.volumeInstallPath = msg.getVolume().getInstallPath(); cmd.imageCacheDir = NfsPrimaryStorageKvmHelper.getCachedImageDir(inv); + cmd.setUuid(inv.getUuid()); final HostInventory host = nfsFactory.getConnectedHostForOperation(inv).get(0); - new KvmCommandSender(host.getUuid()).send(cmd, GET_VOLUME_BASE_IMAGE_PATH, new KvmCommandFailureChecker() { - @Override - public ErrorCode getError(KvmResponseWrapper wrapper) { - GetVolumeBaseImagePathRsp rsp = wrapper.getResponse(GetVolumeBaseImagePathRsp.class); - if (rsp.isSuccess() && StringUtils.isEmpty(rsp.path)) { - return operr("cannot get root image of volume[uuid:%s], may be it create from iso", msg.getVolume().getUuid()); - } - return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); - } - }, new ReturnValueCompletion(completion) { + asyncHttpCall(GET_VOLUME_BASE_IMAGE_PATH, host.getUuid(), cmd, GetVolumeBaseImagePathRsp.class, inv, new ReturnValueCompletion(completion) { @Override - public void success(KvmResponseWrapper w) { - GetVolumeBaseImagePathRsp rsp = w.getResponse(GetVolumeBaseImagePathRsp.class); - File f = new File(rsp.path); - String rootImageUuid = f.getName().split("\\.")[0]; + public void success(GetVolumeBaseImagePathRsp rsp) { GetVolumeRootImageUuidFromPrimaryStorageReply reply = new GetVolumeRootImageUuidFromPrimaryStorageReply(); - reply.setImageUuid(rootImageUuid); + if (rsp.path != null) { + String rootImageUuid = new File(rsp.path).getName().split("\\.")[0]; + reply.setImageUuid(rootImageUuid); + } + + if (!CollectionUtils.isEmpty(rsp.otherPaths)) { + reply.setOtherImageUuids(rsp.otherPaths.stream().map(p -> new File(p).getName().split("\\.")[0]).collect(Collectors.toList())); + } completion.success(reply); } @@ -784,6 +833,55 @@ public void fail(ErrorCode errorCode) { }); } + @Override + public void handle(PrimaryStorageInventory inv, GetVolumeBackingChainFromPrimaryStorageMsg msg, ReturnValueCompletion completion) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + + final HostInventory host = nfsFactory.getConnectedHostForOperation(inv).get(0); + new While<>(msg.getRootInstallPaths()).each((installPath, compl) -> { + GetBackingChainCmd cmd = new GetBackingChainCmd(); + cmd.volumeUuid = msg.getVolumeUuid(); + cmd.installPath = installPath; + cmd.setUuid(inv.getUuid()); + + new KvmCommandSender(host.getUuid()).send(cmd, GET_BACKING_CHAIN_PATH, new KvmCommandFailureChecker() { + @Override + public ErrorCode getError(KvmResponseWrapper wrapper) { + GetBackingChainRsp rsp = wrapper.getResponse(GetBackingChainRsp.class); + return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); + } + }, new ReturnValueCompletion(completion) { + @Override + public void success(KvmResponseWrapper w) { + GetBackingChainRsp rsp = w.getResponse(GetBackingChainRsp.class); + if (CollectionUtils.isEmpty(rsp.backingChain)) { + reply.putBackingChainInstallPath(installPath, Collections.emptyList()); + reply.putBackingChainSize(installPath, 0L); + } else { + reply.putBackingChainInstallPath(installPath, rsp.backingChain); + reply.putBackingChainSize(installPath, rsp.totalSize); + } + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.done(); + } + }); + }).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList err) { + if (!err.getCauses().isEmpty()) { + completion.fail(err.getCauses().get(0)); + } else { + completion.success(reply); + } + } + }); + } + @Override public void handle(PrimaryStorageInventory dstPsInv, NfsToNfsMigrateBitsMsg msg, ReturnValueCompletion completion) { HostVO hostVO = dbf.findByUuid(msg.getHostUuid(), HostVO.class); @@ -805,11 +903,14 @@ public void handle(PrimaryStorageInventory dstPsInv, NfsToNfsMigrateBitsMsg msg, } NfsToNfsMigrateBitsCmd cmd = new NfsToNfsMigrateBitsCmd(); - cmd.setUuid(msg.getSrcPrimaryStorageUuid()); + cmd.setUuid(dstPsInv.getUuid()); + cmd.srcPrimaryStorageUuid = msg.getSrcPrimaryStorageUuid(); cmd.srcFolderPath = msg.getSrcFolderPath(); cmd.dstFolderPath = msg.getDstFolderPath(); + cmd.independentPath = msg.getIndependentPath(); cmd.filtPaths = trash.findTrashInstallPath(msg.getSrcFolderPath(), msg.getSrcPrimaryStorageUuid()); cmd.isMounted = mounted; + cmd.volumeInstallPath = msg.getVolumeInstallPath(); if (!mounted) { cmd.options = NfsSystemTags.MOUNT_OPTIONS.getTokenByResourceUuid(dstPsInv.getUuid(), NfsSystemTags.MOUNT_OPTIONS_TOKEN); @@ -825,6 +926,7 @@ public void handle(PrimaryStorageInventory dstPsInv, NfsToNfsMigrateBitsMsg msg, public void success(KvmResponseWrapper w) { logger.info("successfully copyed volume folder to nfs ps " + dstPsInv.getUuid()); NfsToNfsMigrateBitsReply reply = new NfsToNfsMigrateBitsReply(); + reply.setDstFilesActualSize(w.getResponse(NfsToNfsMigrateBitsRsp.class).dstFilesActualSize); completion.success(reply); } @Override @@ -842,6 +944,7 @@ public void handle(PrimaryStorageInventory inv, NfsRebaseVolumeBackingFileMsg ms cmd.dstPsMountPath = Q.New(PrimaryStorageVO.class).select(PrimaryStorageVO_.mountPath).eq(PrimaryStorageVO_.uuid, msg.getDstPsUuid()).findValue(); cmd.dstVolumeFolderPath = msg.getDstVolumeFolderPath(); cmd.dstImageCacheTemplateFolderPath = msg.getDstImageCacheTemplateFolderPath(); + cmd.setUuid(inv.getUuid()); final HostInventory host = nfsFactory.getConnectedHostForOperation(inv).get(0); new KvmCommandSender(host.getUuid()).send(cmd, NFS_REBASE_VOLUME_BACKING_FILE_PATH, new KvmCommandFailureChecker() { @@ -996,7 +1099,7 @@ public List call() { } @Override - public void instantiateVolume(final PrimaryStorageInventory pinv, final VolumeInventory volume, final ReturnValueCompletion complete) { + public void instantiateVolume(final PrimaryStorageInventory pinv, HostInventory hostInventory, final VolumeInventory volume, final ReturnValueCompletion complete) { String accounUuid = acntMgr.getOwnerAccountUuidOfResource(volume.getUuid()); final CreateEmptyVolumeCmd cmd = new CreateEmptyVolumeCmd(); @@ -1022,7 +1125,7 @@ public void instantiateVolume(final PrimaryStorageInventory pinv, final VolumeIn cmd.setWithoutVolume(true); } - final HostInventory host = nfsFactory.getConnectedHostForOperation(pinv).get(0); + final HostInventory host = hostInventory == null ? nfsFactory.getConnectedHostForOperation(pinv).get(0) : hostInventory; KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setCommand(cmd); @@ -1047,6 +1150,10 @@ public void run(MessageReply reply) { volume.setInstallPath(cmd.getInstallUrl()); volume.setFormat(VolumeConstant.VOLUME_FORMAT_QCOW2); + volume.setActualSize(rsp.actualSize); + if (rsp.size != null) { + volume.setSize(rsp.size); + } nfsMgr.reportCapacityIfNeeded(pinv.getUuid(), rsp); complete.success(volume); @@ -1141,6 +1248,10 @@ public void run(MessageReply reply) { DeleteResponse rsp = ((KVMHostAsyncHttpCallReply) reply).toResponse(DeleteResponse.class); if (!rsp.isSuccess()) { + if (rsp.inUse) { + completion.fail(Platform.err(VolumeErrors.VOLUME_IN_USE, rsp.getError())); + return; + } logger.warn(String.format("failed to delete bits[%s] on nfs primary storage[uuid:%s], %s, will clean up", installPath, pinv.getUuid(), rsp.getError())); completion.fail(operr("failed to delete bits[%s] on nfs primary storage[uuid:%s], %s, will clean up " + @@ -1166,6 +1277,24 @@ public void deleteFolder(PrimaryStorageInventory pinv, String installPath, Compl delete(pinv, installPath, true, completion); } + @Override + public void unlink(PrimaryStorageInventory pinv, String installPath, Completion completion) { + HostInventory host = nfsFactory.getConnectedHostForOperation(pinv).get(0); + UnlinkBitsCmd cmd = new UnlinkBitsCmd(); + cmd.installPath = installPath; + asyncHttpCall(UNLINK_PATH, host.getUuid(), cmd, UnlinkBitsRsp.class, pinv, new ReturnValueCompletion(completion) { + @Override + public void success(UnlinkBitsRsp rsp) { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + @Override public void revertVolumeFromSnapshot(VolumeSnapshotInventory sinv, VolumeInventory vol, HostInventory host, ReturnValueCompletion completion) { RevertVolumeFromSnapshotCmd cmd = new RevertVolumeFromSnapshotCmd(); @@ -1235,20 +1364,23 @@ public void run(MessageReply reply) { } @Override - public void createVolumeFromImageCache(final PrimaryStorageInventory primaryStorage, final ImageCacheInventory image, - final VolumeInventory volume, final ReturnValueCompletion completion) { + public void createVolumeFromImageCache(final PrimaryStorageInventory primaryStorage, final ImageInventory image, final ImageCacheInventory imageCache, + final VolumeInventory volume, final ReturnValueCompletion completion) { HostInventory host = nfsFactory.getConnectedHostForOperation(primaryStorage).get(0); final String installPath = StringUtils.isNotEmpty(volume.getInstallPath()) ? volume.getInstallPath() : NfsPrimaryStorageKvmHelper.makeRootVolumeInstallUrl(primaryStorage, volume); final String accountUuid = acntMgr.getOwnerAccountUuidOfResource(volume.getUuid()); final CreateRootVolumeFromTemplateCmd cmd = new CreateRootVolumeFromTemplateCmd(); - cmd.setTemplatePathInCache(image.getInstallUrl()); + cmd.setTemplatePathInCache(ImageCacheUtil.getImageCachePath(imageCache)); cmd.setInstallUrl(installPath); cmd.setAccountUuid(accountUuid); cmd.setName(volume.getName()); cmd.setVolumeUuid(volume.getUuid()); cmd.setUuid(primaryStorage.getUuid()); + if (image.getSize() < volume.getSize()) { + cmd.setVirtualSize(volume.getSize()); + } KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setCommand(cmd); @@ -1266,37 +1398,44 @@ public void run(MessageReply reply) { CreateRootVolumeFromTemplateResponse rsp = ((KVMHostAsyncHttpCallReply)reply).toResponse(CreateRootVolumeFromTemplateResponse.class); if (!rsp.isSuccess()) { ErrorCode err = operr("fails to create root volume[uuid:%s] from cached image[path:%s] because %s", - volume.getUuid(), image.getImageUuid(), rsp.getError()); + volume.getUuid(), imageCache.getImageUuid(), rsp.getError()); completion.fail(err); return; } nfsMgr.reportCapacityIfNeeded(primaryStorage.getUuid(), rsp); - completion.success(installPath); + completion.success(new VolumeStats(installPath, rsp.actualSize, rsp.size)); } }); } + @Override + public void createIncrementalImageCacheFromVolumeResource(PrimaryStorageInventory primaryStorage, String volumeResource, ImageInventory image, ReturnValueCompletion completion) { + final String installPath = NfsPrimaryStorageKvmHelper.makeCachedImageInstallUrl(primaryStorage, image); + doCreateTemplateFromVolume(installPath, primaryStorage, volumeResource, image, true, completion); + } + @Override public void createImageCacheFromVolumeResource(PrimaryStorageInventory primaryStorage, String volumeResource, ImageInventory image, ReturnValueCompletion completion) { final String installPath = NfsPrimaryStorageKvmHelper.makeCachedImageInstallUrl(primaryStorage, image); - doCreateTemplateFromVolume(installPath, primaryStorage, volumeResource, image, completion); + doCreateTemplateFromVolume(installPath, primaryStorage, volumeResource, image, false, completion); } @Override public void createTemplateFromVolume(final PrimaryStorageInventory primaryStorage, final VolumeInventory volume, final ImageInventory image, final ReturnValueCompletion completion) { final String installPath = NfsPrimaryStorageKvmHelper.makeTemplateFromVolumeInWorkspacePath(primaryStorage, image.getUuid()); - doCreateTemplateFromVolume(installPath, primaryStorage, volume.getInstallPath(), image, completion); + doCreateTemplateFromVolume(installPath, primaryStorage, volume.getInstallPath(), image, false, completion); } - private void doCreateTemplateFromVolume(final String installPath, final PrimaryStorageInventory primaryStorage, final String volumeResourceInstallPath, final ImageInventory image, final ReturnValueCompletion completion) { + private void doCreateTemplateFromVolume(final String installPath, final PrimaryStorageInventory primaryStorage, final String volumeResourceInstallPath, final ImageInventory image, boolean incremental, final ReturnValueCompletion completion) { final HostInventory destHost = nfsFactory.getConnectedHostForOperation(primaryStorage).get(0); CreateTemplateFromVolumeCmd cmd = new CreateTemplateFromVolumeCmd(); cmd.setInstallPath(installPath); cmd.setVolumePath(volumeResourceInstallPath); cmd.setUuid(primaryStorage.getUuid()); + cmd.setIncremental(incremental); KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setCommand(cmd); @@ -1360,8 +1499,8 @@ public void mergeSnapshotToVolume(final PrimaryStorageInventory pinv, VolumeSnap HostInventory host = nfsFactory.getConnectedHostForOperation(pinv).get(0); OfflineMergeSnapshotCmd cmd = new OfflineMergeSnapshotCmd(); - cmd.setFullRebase(fullRebase); - cmd.setSrcPath(snapshot.getPrimaryStorageInstallPath()); + cmd.setFullRebase(fullRebase || snapshot == null); + cmd.setSrcPath(snapshot != null ? snapshot.getPrimaryStorageInstallPath() : null); cmd.setDestPath(volume.getInstallPath()); cmd.setUuid(pinv.getUuid()); @@ -1390,7 +1529,7 @@ public void run(MessageReply reply) { }); } else { MergeVolumeSnapshotOnKvmMsg msg = new MergeVolumeSnapshotOnKvmMsg(); - msg.setFullRebase(fullRebase); + msg.setFullRebase(fullRebase || snapshot == null); msg.setHostUuid(hostUuid); msg.setFrom(snapshot); msg.setTo(volume); @@ -1409,12 +1548,21 @@ public void run(MessageReply reply) { } @Override - public void remount(final PrimaryStorageInventory pinv, String clusterUuid, final Completion completion) { + public void remount(PrimaryStorageInventory pinv, String clusterUuid, NfsPrimaryStorage.NfsConnectParam param, Completion completion) { SimpleQuery q = dbf.createQuery(HostVO.class); q.select(HostVO_.uuid); q.add(HostVO_.clusterUuid, Op.EQ, clusterUuid); q.add(HostVO_.status, Op.EQ, HostStatus.Connected); - final List huuids = q.listValue(); + List huuids = q.listValue(); + + // note: createKvmHostConnectingFlow will help remount the storage if agent + // reconnected, just skip storage connection + if (StorageRemountReason.PrimaryStorageConnection.equals(param.getReason())) { + huuids = huuids.stream() + .filter(huuid -> !upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(huuid)) + .collect(Collectors.toList()); + } + if (huuids.isEmpty()) { completion.fail(operr("no hosts in the cluster[uuid:%s] are connected", clusterUuid)); return; @@ -1760,4 +1908,173 @@ public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { } + + private static boolean isNfsPrimaryStorage(String psUuid) { + return psUuid != null && Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.uuid, psUuid) + .eq(PrimaryStorageVO_.type, NfsPrimaryStorageConstant.NFS_PRIMARY_STORAGE_TYPE) + .isExists(); + } + + @Override + public void beforeTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, Completion completion) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isNfsPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + completion.success(); + return; + } + + String accountUuid = acntMgr.getOwnerAccountUuidOfResource(msg.getVolume().getUuid()); + + final CreateEmptyVolumeCmd scmd = new CreateEmptyVolumeCmd(); + scmd.setUuid(msg.getVolume().getPrimaryStorageUuid()); + scmd.setAccountUuid(accountUuid); + scmd.setHypervisorType(KVMConstant.KVM_HYPERVISOR_TYPE); + scmd.setName(msg.getSnapshotName()); + scmd.setSize(msg.getVolume().getSize()); + scmd.setVolumeUuid(cmd.getVolumeUuid()); + scmd.setInstallUrl(cmd.getInstallPath()); + scmd.setBackingFile(cmd.getVolumeInstallPath()); + + KVMHostAsyncHttpCallMsg smsg = new KVMHostAsyncHttpCallMsg(); + smsg.setCommand(scmd); + smsg.setPath(CREATE_EMPTY_VOLUME_PATH); + smsg.setHostUuid(host.getUuid()); + bus.makeTargetServiceIdByResourceUuid(smsg, HostConstant.SERVICE_ID, host.getUuid()); + bus.send(smsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + CreateEmptyVolumeResponse rsp = ((KVMHostAsyncHttpCallReply) reply).toResponse(CreateEmptyVolumeResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("unable to create empty snapshot volume[name:%s, installpath: %s] on kvm host[uuid:%s, ip:%s], because %s", + scmd.getName(), scmd.getInstallUrl(), host.getUuid(), host.getManagementIp(), rsp.getError()); + completion.fail(err); + return; + } + + completion.success(); + } + }); + } + + @Override + public void afterTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, KVMAgentCommands.TakeSnapshotResponse rsp) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isNfsPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + return; + } + } + + @Override + public void afterTakeSnapshotFailed(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, KVMAgentCommands.TakeSnapshotResponse rsp, ErrorCode err) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isNfsPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + return; + } + + PrimaryStorageVO primaryStorageVO = Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.type, NfsPrimaryStorageConstant.NFS_PRIMARY_STORAGE_TYPE) + .eq(PrimaryStorageVO_.uuid, msg.getVolume().getPrimaryStorageUuid()) + .find(); + PrimaryStorageInventory pinv = PrimaryStorageInventory.valueOf(primaryStorageVO); + delete(pinv, cmd.getInstallPath(), false, new Completion(msg) { + @Override + public void success() { + logger.debug(String.format("successfully cleaned garbage snapshot volume[name: %s, installpath:%s] for take snapshot on volume[%s]", + msg.getSnapshotName(), cmd.getInstallPath(), msg.getVolume().getUuid())); + } + + @Override + public void fail(ErrorCode errorCode) { + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete path:%s right now, skip this GC job because it's in use", cmd.getInstallPath())); + return; + } + logger.debug(String.format("failed to clean garbage snapshot volume[name: %s, installpath:%s] for failed taking snapshot on volume[%s], "+ + "create gc job to clean garbage late", msg.getSnapshotName(), cmd.getInstallPath(), msg.getVolume().getUuid())); + NfsDeleteVolumeSnapshotGC gc = new NfsDeleteVolumeSnapshotGC(); + gc.NAME = String.format("gc-nfs-%s-snapshot-%s", pinv.getUuid(), cmd.getInstallPath()); + gc.primaryStorageUuid = pinv.getUuid(); + gc.hypervisorType = VolumeFormat.getMasterHypervisorTypeByVolumeFormat(msg.getVolume().getFormat()).toString(); + VolumeSnapshotInventory inv = new VolumeSnapshotInventory(); + inv.setPrimaryStorageInstallPath(cmd.getInstallPath()); + gc.snapshot = inv; + gc.submit(NfsPrimaryStorageGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); + } + }); + } + + @Override + public void pullSnapshot(PullVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion) { + PullVolumeSnapshotOnPrimaryStorageReply reply = new PullVolumeSnapshotOnPrimaryStorageReply(); + + OfflineMergeSnapshotCmd cmd = new OfflineMergeSnapshotCmd(); + cmd.setSrcPath(msg.getSrcSnapshotParentPath()); + cmd.setDestPath(msg.getDstSnapshot().getPrimaryStorageInstallPath()); + cmd.setUuid(msg.getVolume().getPrimaryStorageUuid()); + cmd.setFullRebase(cmd.getSrcPath() == null); + + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setCommand(cmd); + kmsg.setPath(OFFLINE_SNAPSHOT_MERGE); + kmsg.setHostUuid(hostUuid); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, hostUuid); + bus.send(kmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + completion.fail(r.getError()); + return; + } + + OfflineMergeSnapshotRsp rsp = ((KVMHostAsyncHttpCallReply) r).toResponse(OfflineMergeSnapshotRsp.class); + if (!rsp.isSuccess()) { + completion.fail(operr("operation error, because:%s", rsp.getError())); + return; + } + + reply.setSize(rsp.getActualSize()); + completion.success(reply); + } + }); + } + + @Override + public void commitSnapshot(CommitVolumeSnapshotOnPrimaryStorageMsg msg, String hostUuid, ReturnValueCompletion completion) { + OfflineCommitSnapshotCmd cmd = new OfflineCommitSnapshotCmd(); + cmd.top = msg.getSrcSnapshot().getPrimaryStorageInstallPath(); + cmd.base = msg.getDstSnapshot().getPrimaryStorageInstallPath(); + cmd.topChildrenInstallPathInDb = msg.getSrcChildrenInstallPathInDb(); + cmd.setUuid(msg.getVolume().getPrimaryStorageUuid()); + + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setCommand(cmd); + kmsg.setPath(OFFLINE_SNAPSHOT_COMMIT); + kmsg.setHostUuid(hostUuid); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, hostUuid); + bus.send(kmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply r) { + if (!r.isSuccess()) { + completion.fail(r.getError()); + return; + } + + OfflineCommitSnapshotRsp rsp = ((KVMHostAsyncHttpCallReply) r).toResponse(OfflineCommitSnapshotRsp.class); + if (!rsp.isSuccess()) { + completion.fail(operr("operation error, because:%s", rsp.getError())); + return; + } + + CommitVolumeSnapshotOnPrimaryStorageReply reply = new CommitVolumeSnapshotOnPrimaryStorageReply(); + reply.setSize(rsp.getActualSize()); + completion.success(reply); + } + }); + } } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackendCommands.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackendCommands.java index e27d5fa6bed..1a31b5b6b7e 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackendCommands.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKVMBackendCommands.java @@ -1,17 +1,22 @@ package org.zstack.storage.primary.nfs; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.header.HasThreadContext; import org.zstack.header.core.validation.Validation; import org.zstack.kvm.KVMAgentCommands; import org.zstack.kvm.KVMAgentCommands.AgentCommand; import org.zstack.kvm.KVMAgentCommands.AgentResponse; +import java.util.ArrayList; import java.util.List; +import java.util.Map; public class NfsPrimaryStorageKVMBackendCommands { public static class NfsPrimaryStorageAgentResponse extends AgentResponse { + @GrayVersion(value = "5.0.0") private Long totalCapacity; + @GrayVersion(value = "5.0.0") private Long availableCapacity; public Long getTotalCapacity() { @@ -32,6 +37,7 @@ public void setAvailableCapacity(Long availableCapacity) { } public static class NfsPrimaryStorageAgentCommand extends KVMAgentCommands.PrimaryStorageCommand { + @GrayVersion(value = "5.0.0") private String uuid; public String getUuid() { @@ -45,36 +51,51 @@ public void setUuid(String uuid) { } public static class DownloadBitsFromKVMHostRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") public String format; } public static class DownloadBitsFromKVMHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String hostname; + @GrayVersion(value = "5.0.0") public String username; + @GrayVersion(value = "5.0.0") public String sshKey; + @GrayVersion(value = "5.0.0") public int sshPort; // it's file path on kvm host actually + @GrayVersion(value = "5.0.0") public String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; + @GrayVersion(value = "5.0.0") public Long bandWidth; + @GrayVersion(value = "5.0.0") public String identificationCode; } public static class CancelDownloadBitsFromKVMHostCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; } public static class GetDownloadBitsFromKVMHostProgressCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") public List volumePaths; } public static class GetDownloadBitsFromKVMHostProgressRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") public long totalSize; } public static class MountCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String url; + @GrayVersion(value = "5.0.0") private String mountPath; + @GrayVersion(value = "5.0.0") private String options; public String getOptions() { @@ -104,6 +125,7 @@ public static class MountAgentResponse extends NfsPrimaryStorageAgentResponse { } public static class GetCapacityCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String mountPath; public String getMountPath() { @@ -119,7 +141,9 @@ public static class GetCapacityResponse extends NfsPrimaryStorageAgentResponse { } public static class UnmountCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String mountPath; + @GrayVersion(value = "5.0.0") private String url; public String getUrl() { @@ -139,8 +163,12 @@ public static class UnmountResponse extends NfsPrimaryStorageAgentResponse { } public static class CreateTemplateFromVolumeCmd extends NfsPrimaryStorageAgentCommand implements HasThreadContext{ + @GrayVersion(value = "5.0.0") private String installPath; + @GrayVersion(value = "5.0.0") private String rootVolumePath; + @GrayVersion(value = "5.0.0") + private boolean incremental; public String getInstallPath() { return installPath; @@ -155,9 +183,55 @@ public String getRootVolumePath() { public void setVolumePath(String rootVolumePath) { this.rootVolumePath = rootVolumePath; } + + public void setIncremental(boolean incremental) { + this.incremental = incremental; + } + + public boolean isIncremental() { + return incremental; + } } public static class CreateTemplateFromVolumeRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private long size; + @GrayVersion(value = "5.0.0") + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + } + + public static class EstimateTemplateSizeCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") + private String volumePath; + + public String getVolumePath() { + return volumePath; + } + + public void setVolumePath(String volumePath) { + this.volumePath = volumePath; + } + } + + public static class EstimateTemplateSizeRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") + private long size; + @GrayVersion(value = "5.0.0") private long actualSize; public long getActualSize() { @@ -178,11 +252,17 @@ public void setSize(long size) { } public static class DownloadBitsFromSftpBackupStorageCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String sshKey; + @GrayVersion(value = "5.0.0") private String hostname; + @GrayVersion(value = "5.0.0") private String username; + @GrayVersion(value = "5.0.0") private int sshPort; + @GrayVersion(value = "5.0.0") private String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") private String primaryStorageInstallPath; public String getUsername() { @@ -234,7 +314,9 @@ public static class DownloadBitsFromSftpBackupStorageResponse extends NfsPrimary } public static class CheckIsBitsExistingCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String installPath; + @GrayVersion(value = "5.0.0") private String hostUuid; public String getHostUuid() { @@ -255,6 +337,7 @@ public void setInstallPath(String installPath) { } public static class CheckIsBitsExistingRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private boolean existing; public boolean isExisting() { @@ -267,6 +350,7 @@ public void setExisting(boolean existing) { } public static class CreateFolderCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String installUrl; public String getInstallUrl() { @@ -279,10 +363,15 @@ public void setInstallUrl(String installUrl) { } public abstract static class CreateVolumeCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String installUrl; + @GrayVersion(value = "5.0.0") private String accountUuid; + @GrayVersion(value = "5.0.0") private String hypervisorType; + @GrayVersion(value = "5.0.0") private String name; + @GrayVersion(value = "5.0.0") private String volumeUuid; public String getInstallUrl() { @@ -319,8 +408,12 @@ public void setVolumeUuid(String uuid) { } public static class CreateRootVolumeFromTemplateCmd extends CreateVolumeCmd { + @GrayVersion(value = "5.0.0") private String templatePathInCache; + @GrayVersion(value = "5.0.0") private long timeout; + @GrayVersion(value = "5.0.0") + private long virtualSize; public long getTimeout() { return timeout; @@ -334,12 +427,23 @@ public String getTemplatePathInCache() { public void setTemplatePathInCache(String templatePathInCache) { this.templatePathInCache = templatePathInCache; } + public long getVirtualSize() { + return virtualSize; + } + public void setVirtualSize(long virtualSize) { + this.virtualSize = virtualSize; + } } public static class CreateRootVolumeFromTemplateResponse extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") + public Long actualSize; + @GrayVersion(value = "5.0.0") + public Long size; } public static class CreateVolumeWithBackingCmd extends CreateVolumeCmd { + @GrayVersion(value = "5.0.0") private String templatePathInCache; public String getTemplatePathInCache() { @@ -351,7 +455,9 @@ public void setTemplatePathInCache(String templatePathInCache) { } public static class CreateVolumeWithBackingRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private long size; + @GrayVersion(value = "5.0.0") private long actualSize; public long getActualSize() { @@ -369,8 +475,11 @@ public long getSize() { } public static class CreateEmptyVolumeCmd extends CreateVolumeCmd { + @GrayVersion(value = "5.0.0") private long size; + @GrayVersion(value = "5.0.0") private boolean withoutVolume; + private String backingFile; public long getSize() { return size; @@ -386,12 +495,26 @@ public boolean isWithoutVolume() { public void setWithoutVolume(boolean withoutVolume) { this.withoutVolume = withoutVolume; } + + public String getBackingFile() { + return backingFile; + } + + public void setBackingFile(String backingFile) { + this.backingFile = backingFile; + } } public static class CreateEmptyVolumeResponse extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") + public Long actualSize; + @GrayVersion(value = "5.0.0") + public Long size; } public static class DeleteCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private boolean folder; + @GrayVersion(value = "5.0.0") private String installPath; public boolean isFolder() { @@ -412,9 +535,22 @@ public void setInstallPath(String installPath) { } public static class DeleteResponse extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") + public boolean inUse; + } + + public static class UnlinkBitsCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") + public String installPath; + @GrayVersion(value = "5.0.0") + public boolean onlyLinkedFile = true; + } + + public static class UnlinkBitsRsp extends NfsPrimaryStorageAgentResponse { } public static class ListDirectionCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String path; public String getPath() { @@ -427,6 +563,7 @@ public void setPath(String path) { } public static class ListDirectionResponse extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private List paths; public List getPaths() { @@ -439,6 +576,7 @@ public void setPaths(List paths) { } public static class RevertVolumeFromSnapshotCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String snapshotInstallPath; public String getSnapshotInstallPath() { @@ -452,9 +590,11 @@ public void setSnapshotInstallPath(String snapshotInstallPath) { public static class RevertVolumeFromSnapshotResponse extends NfsPrimaryStorageAgentResponse { @Validation + @GrayVersion(value = "5.0.0") private String newVolumeInstallPath; @Validation + @GrayVersion(value = "5.0.0") private long size; public String getNewVolumeInstallPath() { @@ -475,7 +615,9 @@ public void setSize(long size) { } public static class ReInitImageCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String imagePath; + @GrayVersion(value = "5.0.0") private String volumePath; public String getImagePath() { @@ -497,6 +639,7 @@ public void setVolumePath(String volumePath) { public static class ReInitImageRsp extends NfsPrimaryStorageAgentResponse { @Validation + @GrayVersion(value = "5.0.0") private String newVolumeInstallPath; public String getNewVolumeInstallPath() { @@ -509,11 +652,17 @@ public void setNewVolumeInstallPath(String newVolumeInstallPath) { } public static class UploadToSftpCmd extends NfsPrimaryStorageAgentCommand implements HasThreadContext{ + @GrayVersion(value = "5.0.0") private String primaryStorageInstallPath; + @GrayVersion(value = "5.0.0") private String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") private String backupStorageHostName; + @GrayVersion(value = "5.0.0") private String backupStorageUserName; + @GrayVersion(value = "5.0.0") private String backupStorageSshKey; + @GrayVersion(value = "5.0.0") private int backupStorageSshPort; public String getBackupStorageUserName() { return backupStorageUserName; @@ -564,8 +713,11 @@ public static class UploadToSftpResponse extends NfsPrimaryStorageAgentResponse } public static class MergeSnapshotCmd extends NfsPrimaryStorageAgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private String snapshotInstallPath; + @GrayVersion(value = "5.0.0") private String workspaceInstallPath; public String getVolumeUuid() { @@ -594,7 +746,9 @@ public void setWorkspaceInstallPath(String workspaceInstallPath) { } public static class MergeSnapshotResponse extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private long size; + @GrayVersion(value = "5.0.0") private long actualSize; public long getActualSize() { @@ -615,8 +769,11 @@ public void setSize(long size) { } public static class RebaseAndMergeSnapshotsCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String volumeUuid; + @GrayVersion(value = "5.0.0") private List snapshotInstallPaths; + @GrayVersion(value = "5.0.0") private String workspaceInstallPath; public String getVolumeUuid() { @@ -645,7 +802,9 @@ public void setWorkspaceInstallPath(String workspaceInstallPath) { } public static class RebaseAndMergeSnapshotsResponse extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private long size; + @GrayVersion(value = "5.0.0") private long actualSize; public long getActualSize() { @@ -666,7 +825,9 @@ public void setSize(long size) { } public static class MoveBitsCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String srcPath; + @GrayVersion(value = "5.0.0") private String destPath; public String getSrcPath() { @@ -690,8 +851,11 @@ public static class MoveBitsRsp extends NfsPrimaryStorageAgentResponse { } public static class OfflineMergeSnapshotCmd extends NfsPrimaryStorageAgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") private String srcPath; + @GrayVersion(value = "5.0.0") private String destPath; + @GrayVersion(value = "5.0.0") private boolean fullRebase; public boolean isFullRebase() { @@ -720,26 +884,77 @@ public void setDestPath(String destPath) { } public static class OfflineMergeSnapshotRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.4.0") + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + } + + public static class OfflineCommitSnapshotCmd extends NfsPrimaryStorageAgentCommand implements HasThreadContext { + @GrayVersion(value = "5.4.0") + public String top; + @GrayVersion(value = "5.4.0") + public String base; + @GrayVersion(value = "5.4.0") + public List topChildrenInstallPathInDb = new ArrayList<>(); + } + + public static class OfflineCommitSnapshotRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.4.0") + private Long actualSize; + + public Long getActualSize() { + return actualSize; + } + + public void setActualSize(Long actualSize) { + this.actualSize = actualSize; + } } public static class RemountCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String url; + @GrayVersion(value = "5.0.0") public String mountPath; + @GrayVersion(value = "5.0.0") public String options; } public static class GetVolumeActualSizeCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String installPath; } + public static class GetBatchVolumeActualSizeCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") + public Map volumeUuidInstallPaths; + } + public static class GetVolumeActualSizeRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") public long actualSize; + @GrayVersion(value = "5.0.0") public long size; } + public static class GetBatchVolumeActualSizeRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") + public Map actualSizes; + } + public static class PingCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String mountPath; + @GrayVersion(value = "5.0.0") public String url; } @@ -749,19 +964,45 @@ public static class PingCmd extends NfsPrimaryStorageAgentCommand { * This takes into consideration multiple snapshot chains and chain-based image. */ public static class GetVolumeBaseImagePathCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String volumeInstallDir; + @GrayVersion(value = "5.0.0") public String imageCacheDir; + @GrayVersion(value = "5.0.0") + public String volumeInstallPath; } public static class GetVolumeBaseImagePathRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") public String path; + @GrayVersion(value = "5.0.0") + public List otherPaths; + } + + public static class GetBackingChainCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") + public String volumeUuid; + @GrayVersion(value = "5.0.0") + public String installPath; + } + + public static class GetBackingChainRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") + public List backingChain; + @GrayVersion(value = "5.0.0") + public long totalSize; } public static class UpdateMountPointCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String oldMountPoint; + @GrayVersion(value = "5.0.0") public String newMountPoint; + @GrayVersion(value = "5.0.0") public String mountPath; + @GrayVersion(value = "5.0.0") public String options; } @@ -769,23 +1010,41 @@ public static class UpdateMountPointRsp extends NfsPrimaryStorageAgentResponse { } public static class NfsToNfsMigrateBitsCmd extends NfsPrimaryStorageAgentCommand implements HasThreadContext { + @GrayVersion(value = "5.0.0") public String srcFolderPath; + @GrayVersion(value = "5.0.0") public String dstFolderPath; + @GrayVersion(value = "5.0.0") public List filtPaths; + @GrayVersion(value = "5.0.0") + public String independentPath; + @GrayVersion(value = "5.0.0") public boolean isMounted = false; + @GrayVersion(value = "5.0.0") public String url; + @GrayVersion(value = "5.0.0") public String options; + @GrayVersion(value = "5.0.0") public String mountPath; + @GrayVersion(value = "5.0.0") + public String volumeInstallPath; + @GrayVersion(value = "5.0.0") + public String srcPrimaryStorageUuid; } public static class NfsToNfsMigrateBitsRsp extends NfsPrimaryStorageAgentResponse { - + @GrayVersion(value = "5.0.0") + public Map dstFilesActualSize; } public static class NfsRebaseVolumeBackingFileCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String srcPsMountPath; + @GrayVersion(value = "5.0.0") public String dstPsMountPath; + @GrayVersion(value = "5.0.0") public String dstVolumeFolderPath; + @GrayVersion(value = "5.0.0") public String dstImageCacheTemplateFolderPath; } @@ -794,8 +1053,11 @@ public static class NfsRebaseVolumeBackingFileRsp extends NfsPrimaryStorageAgent } public static class LinkVolumeNewDirCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String srcDir; + @GrayVersion(value = "5.0.0") public String dstDir; } @@ -803,7 +1065,9 @@ public static class LinkVolumeNewDirRsp extends NfsPrimaryStorageAgentResponse { } public static class GetQcow2HashValueCmd extends NfsPrimaryStorageAgentCommand { + @GrayVersion(value = "5.0.0") private String hostUuid; + @GrayVersion(value = "5.0.0") private String installPath; public String getHostUuid() { @@ -824,6 +1088,7 @@ public void setInstallPath(String installPath) { } public static class GetQcow2HashValueRsp extends NfsPrimaryStorageAgentResponse { + @GrayVersion(value = "5.0.0") private String hashValue; public String getHashValue() { diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKvmHelper.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKvmHelper.java index e4682915433..a58456a47db 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKvmHelper.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsPrimaryStorageKvmHelper.java @@ -8,6 +8,7 @@ import org.zstack.header.volume.Volume; import org.zstack.header.volume.VolumeInventory; import org.zstack.header.volume.VolumeType; +import org.zstack.storage.primary.ImageCacheUtil; import org.zstack.storage.primary.PrimaryStoragePathMaker; import org.zstack.utils.DebugUtils; import org.zstack.utils.path.PathUtil; @@ -40,7 +41,7 @@ public static String makeMemoryVolumeInstallUrl(PrimaryStorageInventory pinv, Vo } public static String makeCachedImageInstallUrl(PrimaryStorageInventory pinv, ImageInventory iminv) { - return PathUtil.join(pinv.getMountPath(), PrimaryStoragePathMaker.makeCachedImageInstallPath(iminv)); + return ImageCacheUtil.getImageCachePath(iminv, it -> PathUtil.join(pinv.getMountPath(), PrimaryStoragePathMaker.makeCachedImageInstallPath(iminv))); } public static String getCachedImageDir(PrimaryStorageInventory pinv){ diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsMsg.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsMsg.java index 1f04dd9fc06..0a7a6d2cb3a 100644 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsMsg.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsMsg.java @@ -12,6 +12,16 @@ public class NfsToNfsMigrateBitsMsg extends NeedReplyMessage implements PrimaryS private String dstFolderPath; private String srcPrimaryStorageUuid; private String primaryStorageUuid; + private String independentPath; + private String volumeInstallPath; + + public String getVolumeInstallPath() { + return volumeInstallPath; + } + + public void setVolumeInstallPath(String volumeInstallPath) { + this.volumeInstallPath = volumeInstallPath; + } public String getHostUuid() { return hostUuid; @@ -53,4 +63,12 @@ public String getSrcPrimaryStorageUuid() { public void setSrcPrimaryStorageUuid(String srcPrimaryStorageUuid) { this.srcPrimaryStorageUuid = srcPrimaryStorageUuid; } + + public String getIndependentPath() { + return independentPath; + } + + public void setIndependentPath(String independentPath) { + this.independentPath = independentPath; + } } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsReply.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsReply.java index eb74a80b47b..f566c8958a0 100644 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsReply.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsToNfsMigrateBitsReply.java @@ -2,8 +2,19 @@ import org.zstack.header.message.MessageReply; +import java.util.Map; + /** * Created by GuoYi on 10/19/17. */ public class NfsToNfsMigrateBitsReply extends MessageReply { + private Map dstFilesActualSize; + + public Map getDstFilesActualSize() { + return dstFilesActualSize; + } + + public void setDstFilesActualSize(Map dstFilesActualSize) { + this.dstFilesActualSize = dstFilesActualSize; + } } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsVolumeSnapshotProtector.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsVolumeSnapshotProtector.java index 4d9403b79b1..38ae46a9770 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsVolumeSnapshotProtector.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/NfsVolumeSnapshotProtector.java @@ -20,14 +20,6 @@ public String getPrimaryStorageType() { @Override public void protect(VolumeSnapshotInventory snapshot, Completion completion) { - String backingToVolumeUuid = VolumeSnapshotSystemTags.BACKING_TO_VOLUME.getTokenByResourceUuid( - snapshot.getUuid(), VolumeSnapshotSystemTags.BACKING_VOLUME_TOKEN); - if (backingToVolumeUuid != null) { - completion.fail(operr("snapshot[uuid:%s] is backing file of volume[uuid:%s], cannot delete.", - snapshot.getUuid(), backingToVolumeUuid)); - return; - } - Path path = Paths.get(snapshot.getPrimaryStorageInstallPath()); if (!path.getParent().toString().contains(snapshot.getVolumeUuid())) { completion.fail(inerr("the snapshot[name:%s, uuid:%s, path: %s] seems not belong to the volume[uuid:%s]", diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/PackageInfo.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/PackageInfo.java index 00e39e164c4..671c4be0edf 100755 --- a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/PackageInfo.java +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "NFS主存储") +@PackageAPIInfo( + APICategoryName = "NFS主存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/StorageRemountReason.java b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/StorageRemountReason.java new file mode 100644 index 00000000000..9032478c76e --- /dev/null +++ b/plugin/nfsPrimaryStorage/src/main/java/org/zstack/storage/primary/nfs/StorageRemountReason.java @@ -0,0 +1,6 @@ +package org.zstack.storage.primary.nfs; + +public enum StorageRemountReason { + PrimaryStorageConnection, + Other +} diff --git a/plugin/pom.xml b/plugin/pom.xml index 32b955d3b4d..c97c9a24421 100755 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -4,7 +4,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. plugin @@ -28,6 +28,17 @@ ldap vxlan acl + sdnController + sugonSdnController + directory + sshKeyPair + hostNetworkInterface + vhost + expon + externalStorage + zbs + cbd + xinfini diff --git a/plugin/portForwarding/pom.xml b/plugin/portForwarding/pom.xml index 228a9245583..051e60a74e7 100755 --- a/plugin/portForwarding/pom.xml +++ b/plugin/portForwarding/pom.xml @@ -4,7 +4,7 @@ org.zstack plugin - 4.4.0 + 5.4.0 portForwarding diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsg.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsg.java index 43333445e39..5091d4c6c61 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsg.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsg.java @@ -55,6 +55,7 @@ @RestRequest( path = "/port-forwarding/{ruleUuid}/vm-instances/nics/{vmNicUuid}", method = HttpMethod.POST, + parameterName = "params", responseClass = APIAttachPortForwardingRuleEvent.class ) public class APIAttachPortForwardingRuleMsg extends APIMessage { diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsgDoc_zh_cn.groovy index 8dad8f66996..cb094ff74ee 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIAttachPortForwardingRuleMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "ruleUuid" - enclosedIn "" + enclosedIn "params" desc "规则的uuid" location "url" type "String" optional false since "0.6" - } column { name "vmNicUuid" - enclosedIn "" + enclosedIn "params" desc "云主机网卡UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIChangePortForwardingRuleStateMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIChangePortForwardingRuleStateMsgDoc_zh_cn.groovy index 27f38c28ef7..1cf4e0cfc40 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIChangePortForwardingRuleStateMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIChangePortForwardingRuleStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APICreatePortForwardingRuleMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APICreatePortForwardingRuleMsgDoc_zh_cn.groovy index c2d3b82815a..78f48548707 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APICreatePortForwardingRuleMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APICreatePortForwardingRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "vipPortStart" @@ -39,7 +38,6 @@ doc { type "Integer" optional false since "0.6" - } column { name "vipPortEnd" @@ -49,7 +47,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "privatePortStart" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "privatePortEnd" @@ -69,7 +65,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "protocolType" @@ -89,7 +84,6 @@ doc { type "String" optional true since "0.6" - } column { name "allowedCidr" @@ -99,7 +93,6 @@ doc { type "String" optional true since "0.6" - } column { name "name" @@ -109,7 +102,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -119,7 +111,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -129,7 +120,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -139,7 +129,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -149,7 +138,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDeletePortForwardingRuleMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDeletePortForwardingRuleMsgDoc_zh_cn.groovy index 1676fc47e27..d8ca9893599 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDeletePortForwardingRuleMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDeletePortForwardingRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDetachPortForwardingRuleMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDetachPortForwardingRuleMsgDoc_zh_cn.groovy index 1819e530922..5ad53bb85aa 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDetachPortForwardingRuleMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIDetachPortForwardingRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIGetPortForwardingAttachableVmNicsMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIGetPortForwardingAttachableVmNicsMsgDoc_zh_cn.groovy index 551e36d99f9..bc07a2c4c8f 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIGetPortForwardingAttachableVmNicsMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIGetPortForwardingAttachableVmNicsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIQueryPortForwardingRuleMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIQueryPortForwardingRuleMsgDoc_zh_cn.groovy index e37e350049f..18cf5ddc458 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIQueryPortForwardingRuleMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIQueryPortForwardingRuleMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.portforwarding import org.zstack.network.service.portforwarding.APIQueryPortForwardingRuleReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryPortForwardingRule" diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIUpdatePortForwardingRuleMsgDoc_zh_cn.groovy b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIUpdatePortForwardingRuleMsgDoc_zh_cn.groovy index d7f01365883..51008432e4a 100644 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIUpdatePortForwardingRuleMsgDoc_zh_cn.groovy +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/APIUpdatePortForwardingRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PackageInfo.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PackageInfo.java index de93ab47db4..3b8b1e0ee0f 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PackageInfo.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "端口转发") +@PackageAPIInfo( + APICategoryName = "端口转发", + permissions = {PackageAPIInfo.PERMISSION_ZSV_ADVANCED_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java index a3869140f9e..e520c63ab60 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingApiInterceptor.java @@ -1,5 +1,6 @@ package org.zstack.network.service.portforwarding; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.cloudbus.CloudBus; @@ -15,14 +16,17 @@ import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.message.APIMessage; import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; import org.zstack.network.service.vip.*; import org.zstack.utils.VipUseForList; +import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.NetworkUtils; import javax.persistence.Tuple; import javax.persistence.TypedQuery; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; @@ -87,7 +91,9 @@ private void validate(APIDetachPortForwardingRuleMsg msg) { private void validate(final APIAttachPortForwardingRuleMsg msg) { SimpleQuery q = dbf.createQuery(PortForwardingRuleVO.class); - q.select(PortForwardingRuleVO_.vmNicUuid, PortForwardingRuleVO_.state, PortForwardingRuleVO_.allowedCidr); + q.select(PortForwardingRuleVO_.vmNicUuid, PortForwardingRuleVO_.state, PortForwardingRuleVO_.allowedCidr, + PortForwardingRuleVO_.privatePortStart, PortForwardingRuleVO_.privatePortEnd, + PortForwardingRuleVO_.protocolType); q.add(PortForwardingRuleVO_.uuid, Op.EQ, msg.getRuleUuid()); Tuple t = q.findTuple(); @@ -122,6 +128,8 @@ public VipVO call() { } checkIfAnotherVip(vip.getUuid(), msg.getVmNicUuid()); + checkForConflictsWithOtherRules(msg.getVmNicUuid(), t.get(3, Integer.class), t.get(4, Integer.class), + t.get(2, String.class), t.get(5, PortForwardingProtocolType.class)); if(t.get(2, String.class) != null) { checkNicRule(msg.getVmNicUuid()); @@ -148,12 +156,20 @@ private void validate(APICreatePortForwardingRuleMsg msg) { if (msg.getVipPortEnd() == null) { msg.setVipPortEnd(msg.getVipPortStart()); } - if (msg.getPrivatePortStart() == null) { + if (msg.getPrivatePortStart() == null && msg.getPrivatePortEnd() == null) { msg.setPrivatePortStart(msg.getVipPortStart()); - } - if (msg.getPrivatePortEnd() == null) { msg.setPrivatePortEnd(msg.getVipPortEnd()); } + if (msg.getPrivatePortStart() == null && msg.getPrivatePortEnd() != null) { + msg.setPrivatePortStart(msg.getPrivatePortEnd()); + } + if (msg.getPrivatePortEnd() == null && msg.getPrivatePortStart() != null) { + msg.setPrivatePortEnd(msg.getPrivatePortStart()); + } + if (msg.getVipPortEnd()-msg.getVipPortStart() != msg.getPrivatePortEnd()-msg.getPrivatePortStart()) { + throw new ApiMessageInterceptionException(argerr("could not create port forwarding rule, because vip port range[vipStartPort:%s, vipEndPort:%s] is incompatible with private port range[privateStartPort:%s, privateEndPort:%s]", + msg.getVipPortStart(), msg.getVipPortEnd(), msg.getPrivatePortStart(), msg.getPrivatePortEnd())); + } int vipStart = Math.min(msg.getVipPortStart(), msg.getVipPortEnd()); int vipEnd = Math.max(msg.getVipPortStart(), msg.getVipPortEnd()); @@ -176,6 +192,8 @@ private void validate(APICreatePortForwardingRuleMsg msg) { if (msg.getAllowedCidr() != null) { if (!NetworkUtils.isCidr(msg.getAllowedCidr())) { throw new ApiMessageInterceptionException(argerr("invalid CIDR[%s]", msg.getAllowedCidr())); + } else if (!NetworkUtils.isCidr(msg.getAllowedCidr(), IPv6Constants.IPv4)) { + throw new ApiMessageInterceptionException(argerr("invalid CIDR[%s], only ipv4 is supported", msg.getAllowedCidr())); } } @@ -222,36 +240,43 @@ private void validate(APICreatePortForwardingRuleMsg msg) { } checkIfAnotherVip(msg.getVipUuid(), msg.getVmNicUuid()); + checkForConflictsWithOtherRules(msg.getVmNicUuid(), msg.getPrivatePortStart(), msg.getPrivatePortEnd(), + msg.getAllowedCidr(), PortForwardingProtocolType.valueOf(msg.getProtocolType())); } if(msg.getAllowedCidr() != null){ checkNicRule(msg.getVmNicUuid()); } - } @Transactional(readOnly = true) private void checkIfAnotherVip(String vipUuid, String vmNicUuid) { - String sql = "select nic.uuid from VmNicVO nic where nic.vmInstanceUuid = (select n.vmInstanceUuid from VmNicVO n where" + - " n.uuid = :nicUuid)"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); - q.setParameter("nicUuid", vmNicUuid); - List nicUuids = q.getResultList(); - - sql = "select count(*) from VmNicVO nic, PortForwardingRuleVO pf where nic.uuid = pf.vmNicUuid and pf.vipUuid != :vipUuid and nic.uuid in (:nicUuids)"; - TypedQuery lq = dbf.getEntityManager().createQuery(sql, Long.class); - lq.setParameter("vipUuid", vipUuid); - lq.setParameter("nicUuids", nicUuids); - long count = lq.getSingleResult(); - - if (count > 0) { - sql = "select vm from VmInstanceVO vm, VmNicVO nic where vm.uuid = nic.vmInstanceUuid and nic.uuid = :nicUuid"; - TypedQuery vq = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); - vq.setParameter("nicUuid", vmNicUuid); - VmInstanceVO vm = vq.getSingleResult(); + final String vmUuid = Q.New(VmNicVO.class).select(VmNicVO_.vmInstanceUuid).eq(VmNicVO_.uuid, vmNicUuid).findValue(); + + List nicUuids = new ArrayList<>(); + if (StringUtils.isNotEmpty(vmUuid)) { + nicUuids = Q.New(VmNicVO.class).select(VmNicVO_.uuid).eq(VmNicVO_.vmInstanceUuid, vmUuid).listValues(); + } else { + nicUuids.add(vmNicUuid); + } + + boolean isAnotherVipExist = Q.New(PortForwardingRuleVO.class).notEq(PortForwardingRuleVO_.vipUuid, vipUuid) + .in(PortForwardingRuleVO_.vmNicUuid, nicUuids).isExists(); + + if (!isAnotherVipExist) { + return; + } + + if (StringUtils.isNotEmpty(vmUuid)) { + VmInstanceVO vm = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, vmUuid).find(); throw new ApiMessageInterceptionException(operr("the VM[name:%s uuid:%s] already has port forwarding rules that have different VIPs than the one[uuid:%s]", - vm.getName(), vm.getUuid(), vipUuid)); + vm.getName(), vm.getUuid(), vipUuid)); + } else { + VmNicVO vmNic = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, vmNicUuid).find(); + + throw new ApiMessageInterceptionException(operr("the VmNic[uuid:%s] already has port forwarding rules that have different VIPs than the one[uuid:%s]", + vmNic.getUuid(), vipUuid)); } } @@ -269,6 +294,45 @@ private void checkNicRule(String vmNicUuid) { } } + private void checkForConflictsWithOtherRules(String vmNicUuid, Integer privatePortStart, Integer privatePortEnd, + String allowedCidr, PortForwardingProtocolType protocolType) { + Q q; + if(privatePortStart.equals(privatePortEnd)) { + q = Q.New(PortForwardingRuleVO.class).eq(PortForwardingRuleVO_.vmNicUuid, vmNicUuid) + .eq(PortForwardingRuleVO_.protocolType, protocolType) + .lte(PortForwardingRuleVO_.privatePortStart, privatePortStart) + .gte(PortForwardingRuleVO_.privatePortEnd, privatePortEnd); + } + + else { + q = Q.New(PortForwardingRuleVO.class).eq(PortForwardingRuleVO_.vmNicUuid, vmNicUuid) + .eq(PortForwardingRuleVO_.protocolType, protocolType) + .lte(PortForwardingRuleVO_.privatePortEnd, privatePortEnd) + .gte(PortForwardingRuleVO_.privatePortStart, privatePortStart); + } + if (allowedCidr != null){ + if (q.isExists()) { + throw new ApiMessageInterceptionException(operr( + "could not attach port forwarding rule with allowedCidr, because vmNic[uuid:%s] " + + "already has rules that overlap the target private port ranges[%s, %s] " + + "and have the same protocol type[%s]", + vmNicUuid, privatePortStart, privatePortEnd, protocolType)); + } + } + else{ + q = q.notNull(PortForwardingRuleVO_.allowedCidr); + if (q.isExists()) { + throw new ApiMessageInterceptionException(operr( + "could not attach port forwarding rule, because vmNic[uuid:%s] already has a rule " + + "that overlaps the target private port ranges[%s, %s], " + + "has the same protocol type[%s] and has AllowedCidr", + vmNicUuid, privatePortStart, privatePortEnd, protocolType)); + } + } + + + } + private void validate(APIDeletePortForwardingRuleMsg msg) { if (!dbf.isExist(msg.getUuid(), PortForwardingRuleVO.class)) { bus.publish(new APIDeletePortForwardingRuleEvent(msg.getId())); diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingConstant.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingConstant.java index b2f73c37a93..909fa999da1 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingConstant.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingConstant.java @@ -24,6 +24,8 @@ public static enum Params { public final List vmOperationForDetachPortfordingRule = asList( VmInstanceConstant.VmOperation.Destroy, - VmInstanceConstant.VmOperation.DetachNic + VmInstanceConstant.VmOperation.DetachNic, + VmInstanceConstant.VmOperation.ChangeNicNetwork, + VmInstanceConstant.VmOperation.ChangeNicIp ); } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingExtension.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingExtension.java index bed5ae0e336..94b33838989 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingExtension.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingExtension.java @@ -2,6 +2,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.compute.vm.StaticIpOperator; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; @@ -14,12 +15,14 @@ import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.network.l3.L3NetworkManager; import org.zstack.network.service.AbstractNetworkServiceExtension; +import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.vip.VipInventory; import org.zstack.network.service.vip.VipVO; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import java.util.*; +import java.util.stream.Collectors; /** * Created with IntelliJ IDEA. @@ -27,13 +30,15 @@ * Time: 7:53 PM * To change this template use File | Settings | File Templates. */ -public class PortForwardingExtension extends AbstractNetworkServiceExtension { +public class PortForwardingExtension extends AbstractNetworkServiceExtension implements ReleaseNetworkServiceOnDeletingNicExtensionPoint { private static final CLogger logger = Utils.getLogger(PortForwardingExtension.class); @Autowired private PortForwardingManager pfMgr; @Autowired private L3NetworkManager l3Mgr; + @Autowired + private NetworkServiceManager nwServiceMgr; private final String SUCCESS = PortForwardingExtension.class.getName(); @@ -50,6 +55,9 @@ protected List makePortForwardingStruct(List(); + } SimpleQuery q = dbf.createQuery(PortForwardingRuleVO.class); q.add(PortForwardingRuleVO_.vmNicUuid, SimpleQuery.Op.EQ, nic.getUuid()); List pfvos = q.list(); @@ -229,4 +237,44 @@ private Map> workoutPortForwarding(VmInstance return map; } + + private List workoutPortForwarding(VmNicInventory vmNic) { + List vos = Q.New(PortForwardingRuleVO.class). + eq(PortForwardingRuleVO_.vmNicUuid, vmNic.getUuid()).list(); + if (vos == null || vos.isEmpty()) { + return null; + } + + return vos.stream().map(rule -> { + PortForwardingStruct struct = pfMgr.makePortForwardingStruct(PortForwardingRuleInventory.valueOf(rule)); + struct.setReleaseVmNicInfoWhenDetaching(true); + return struct; + }).collect(Collectors.toList()); + } + + @Override + public void releaseNetworkServiceOnDeletingNic(VmNicInventory nic, NoErrorCompletion completion) { + List structs = workoutPortForwarding(nic); + if (structs == null) { + logger.debug(String.format("vmNic[%s] does not need release port forwarding",nic.getUuid())); + completion.done(); + return; + } + final NetworkServiceProviderType providerType = nwServiceMgr.getTypeOfNetworkServiceProviderForService(nic.getL3NetworkUuid(), + NetworkServiceType.PortForwarding); + Map> map = new HashMap>(); + + map.put(providerType.toString(), structs); + releaseNetworkService(map.entrySet().iterator(), completion); + } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManager.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManager.java index 1270c485c6b..d441c83c6bf 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManager.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManager.java @@ -8,4 +8,6 @@ public interface PortForwardingManager { void attachPortForwardingRule(PortForwardingStruct struct, String providerType, Completion completion); void detachPortForwardingRule(PortForwardingStruct struct, String providerType, Completion completion); + + PortForwardingStruct makePortForwardingStruct(PortForwardingRuleInventory rule); } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java index 964cbb30b21..96e51bc6d86 100755 --- a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingManagerImpl.java @@ -15,20 +15,18 @@ import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.AbstractService; -import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.core.Completion; import org.zstack.header.core.NopeCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.identity.APIChangeResourceOwnerMsg; import org.zstack.header.identity.Quota; -import org.zstack.header.identity.Quota.QuotaOperator; -import org.zstack.header.identity.Quota.QuotaPair; import org.zstack.header.identity.ReportQuotaExtensionPoint; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; -import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.l3.UsedIpInventory; @@ -39,7 +37,6 @@ import org.zstack.header.query.ExpandedQueryStruct; import org.zstack.header.vm.*; import org.zstack.identity.AccountManager; -import org.zstack.identity.QuotaUtil; import org.zstack.network.l3.L3NetworkManager; import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.vip.*; @@ -59,7 +56,7 @@ import static java.util.Arrays.asList; import static org.zstack.core.Platform.err; import static org.zstack.core.Platform.operr; -import static org.zstack.utils.CollectionDSL.*; +import static org.zstack.utils.CollectionDSL.list; public class PortForwardingManagerImpl extends AbstractService implements PortForwardingManager, VipReleaseExtensionPoint, AddExpandedQueryExtensionPoint, ReportQuotaExtensionPoint, VipGetUsedPortRangeExtensionPoint, @@ -414,12 +411,10 @@ public void fail(ErrorCode errorCode) { }); } - @Transactional private VmInstanceState getVmStateFromVmNicUuid(String vmNicUuid) { - String sql = "select vm.state from VmInstanceVO vm, VmNicVO nic where vm.uuid = nic.vmInstanceUuid and nic.uuid = :nicuuid"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, VmInstanceState.class); - q.setParameter("nicuuid", vmNicUuid); - return q.getSingleResult(); + return SQL.New( "select vm.state from VmInstanceVO vm, VmNicVO nic " + + "where vm.uuid = nic.vmInstanceUuid and nic.uuid = :nicUuid", + VmInstanceState.class).param("nicUuid", vmNicUuid).find(); } private void handle(final APIAttachPortForwardingRuleMsg msg) { @@ -449,7 +444,6 @@ private void handle(final APIAttachPortForwardingRuleMsg msg) { public void success() { evt.setInventory(inv); bus.publish(evt); - return; } @Override @@ -458,6 +452,7 @@ public void fail(ErrorCode errorCode) { bus.publish(evt); } }); + return; } final PortForwardingStruct struct = makePortForwardingStruct(inv); @@ -985,7 +980,8 @@ public void releaseServicesOnVip(VipInventory vip, Completion complete) { releaseServicesOnVip(rules.iterator(), complete); } - private PortForwardingStruct makePortForwardingStruct(PortForwardingRuleInventory rule) { + @Override + public PortForwardingStruct makePortForwardingStruct(PortForwardingRuleInventory rule) { VipVO vipvo = dbf.findByUuid(rule.getVipUuid(), VipVO.class); L3NetworkVO vipL3vo = dbf.findByUuid(vipvo.getL3NetworkUuid(), L3NetworkVO.class); @@ -1279,60 +1275,15 @@ public List getExpandedQueryAliasesStructs() { @Override public List reportQuota() { - QuotaOperator checker = new QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreatePortForwardingRuleMsg) { - check((APICreatePortForwardingRuleMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(PortForwardingQuotaConstant.PF_NUM); - usage.setUsed(getUsedPf(accountUuid)); - return list(usage); - } - - @Transactional(readOnly = true) - private long getUsedPf(String accountUuid) { - String sql = "select count(pf) from PortForwardingRuleVO pf, AccountResourceRefVO ref where pf.uuid = ref.resourceUuid" + - " and ref.accountUuid = :auuid and ref.resourceType = :rtype"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", PortForwardingRuleVO.class.getSimpleName()); - Long pfn = q.getSingleResult(); - pfn = pfn == null ? 0 : pfn; - return pfn; - } - - private void check(APICreatePortForwardingRuleMsg msg, Map pairs) { - long pfNum = pairs.get(PortForwardingQuotaConstant.PF_NUM).getValue(); - long pfn = getUsedPf(msg.getSession().getAccountUuid()); - - if (pfn + 1 > pfNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), PortForwardingQuotaConstant.PF_NUM, pfNum)); - } - } - }; - Quota quota = new Quota(); - quota.setOperator(checker); - quota.addMessageNeedValidation(APICreatePortForwardingRuleMsg.class); - - QuotaPair p = new QuotaPair(); - p.setName(PortForwardingQuotaConstant.PF_NUM); - p.setValue(PortFowardingQuotaGlobalConfig.PF_NUM.defaultValue(Long.class)); - quota.addPair(p); + quota.defineQuota(new PortForwardingNumQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreatePortForwardingRuleMsg.class) + .addCounterQuota(PortForwardingQuotaConstant.PF_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(PortForwardingRuleVO.class) + .eq(PortForwardingRuleVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(PortForwardingQuotaConstant.PF_NUM)); return list(quota); } diff --git a/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingNumQuotaDefinition.java b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingNumQuotaDefinition.java new file mode 100644 index 00000000000..f5761ee90d2 --- /dev/null +++ b/plugin/portForwarding/src/main/java/org/zstack/network/service/portforwarding/PortForwardingNumQuotaDefinition.java @@ -0,0 +1,28 @@ +package org.zstack.network.service.portforwarding; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; + +public class PortForwardingNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return PortForwardingQuotaConstant.PF_NUM; + } + + @Override + public Long getDefaultValue() { + return PortFowardingQuotaGlobalConfig.PF_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(pf) from PortForwardingRuleVO pf, AccountResourceRefVO ref where pf.uuid = ref.resourceUuid" + + " and ref.accountUuid = :auuid and ref.resourceType = :rtype"; + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", PortForwardingRuleVO.class.getSimpleName()); + Long pfn = q.find(); + pfn = pfn == null ? 0 : pfn; + return pfn; + } +} diff --git a/plugin/sdnController/pom.xml b/plugin/sdnController/pom.xml new file mode 100644 index 00000000000..c6fb7c3f735 --- /dev/null +++ b/plugin/sdnController/pom.xml @@ -0,0 +1,114 @@ + + + + plugin + org.zstack + 5.4.0 + + 4.0.0 + + sdnController + + + + org.zstack + compute + ${project.version} + + + org.zstack + network + ${project.version} + + + org.zstack + tag + ${project.version} + + + org.zstack + kvm + ${project.version} + + + org.zstack + configuration + ${project.version} + + + org.zstack + vxlan + ${project.version} + + + org.zstack + hostNetworkInterface + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/PackageInfo.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/PackageInfo.java new file mode 100644 index 00000000000..2925fe87985 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/PackageInfo.java @@ -0,0 +1,13 @@ +package org.zstack.sdnController; + +import org.zstack.header.PackageAPIInfo; + +/** + * Created by shixin on 09/19/2019. + */ +@PackageAPIInfo( + APICategoryName = "sdnController", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE} +) +public class PackageInfo { +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/RBACInfo.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/RBACInfo.java new file mode 100644 index 00000000000..f8a39857c20 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/RBACInfo.java @@ -0,0 +1,30 @@ +package org.zstack.sdnController; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .name("sdnController") + .adminOnlyAPIs("org.zstack.sdnController.**") + .build(); + } + + @Override + public void contributeToRoles() { + } + + @Override + public void roles() { + roleBuilder() + .name("sdnController") + .uuid("4266a67e46cb4e68864899458287941e") + .permissionsByName("sdnController") + .build(); + } + + @Override + public void globalReadableResources() { + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnController.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnController.java new file mode 100644 index 00000000000..5de07d899f7 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnController.java @@ -0,0 +1,30 @@ +package org.zstack.sdnController; + +import org.zstack.header.core.Completion; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.sdnController.header.*; + + +public interface SdnController { + + void handleMessage(SdnControllerMessage msg); + /* + 有关sdn控制器的前置检查: pre-event + 对sdn控制器的控制: event + 有关sdn控制器的后置处理: post-event + */ + void preInitSdnController(APIAddSdnControllerMsg msg, Completion completion); + void createSdnControllerDb(APIAddSdnControllerMsg msg, SdnControllerVO vo, Completion completion); + void deleteSdnControllerDb(SdnControllerVO vo); + void initSdnController(APIAddSdnControllerMsg msg, Completion completion); + void postInitSdnController(SdnControllerVO vo, Completion completion); + + void deleteSdnController(SdnControllerDeletionMsg msg, SdnControllerInventory sdn, Completion completion); + + default void reconnectSdnController(Completion completion) {completion.success();}; + + default void addHost(APISdnControllerAddHostMsg msg, Completion completion) {completion.success();}; + default void removeHost(SdnControllerRemoveHostMsg msg, Completion completion) {completion.success();}; + + default void changeHost(SdnControllerHostRefVO oldRef, SdnControllerHostRefVO newRef, Completion completion) {completion.success();}; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java new file mode 100644 index 00000000000..741a99cdb70 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerApiInterceptor.java @@ -0,0 +1,373 @@ +package org.zstack.sdnController; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; +import org.zstack.header.message.APIMessage; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.header.vm.APIAttachL3NetworkToVmMsg; +import org.zstack.header.vm.APIChangeVmNicNetworkMsg; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmNicVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO_; +import org.zstack.network.l3.L3NetworkHelper; +import org.zstack.network.securitygroup.*; +import org.zstack.sdnController.header.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; + +import java.util.List; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; + +import static org.zstack.core.Platform.argerr; + +/** + * Created by shixin.ruan on 09/17/2019 + */ +public class SdnControllerApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { + private static final CLogger logger = Utils.getLogger(SdnControllerApiInterceptor.class); + + @Autowired + protected DatabaseFacade dbf; + @Autowired + protected CloudBus bus; + + private void setServiceId(APIMessage msg) { + if (msg instanceof SdnControllerMessage) { + SdnControllerMessage smsg = (SdnControllerMessage) msg; + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, smsg.getSdnControllerUuid()); + } + } + + @Override + public List getMessageClassToIntercept() { + List ret = new ArrayList<>(); + ret.add(APIAttachSecurityGroupToL3NetworkMsg.class); + ret.add(APIAddVmNicToSecurityGroupMsg.class); + ret.add(APISetVmNicSecurityGroupMsg.class); + ret.add(APIAddSecurityGroupRuleMsg.class); + ret.add(APIAttachL3NetworkToVmMsg.class); + ret.add(APIChangeVmNicNetworkMsg.class); + ret.add(APIPullSdnControllerTenantMsg.class); + + return ret; + } + + @Override + public InterceptorPosition getPosition() { + return InterceptorPosition.END; + } + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIAddSdnControllerMsg) { + validate((APIAddSdnControllerMsg)msg); + } else if (msg instanceof APISdnControllerAddHostMsg) { + validate((APISdnControllerAddHostMsg)msg); + } else if (msg instanceof APISdnControllerRemoveHostMsg) { + validate((APISdnControllerRemoveHostMsg)msg); + } else if (msg instanceof APISdnControllerChangeHostMsg) { + validate((APISdnControllerChangeHostMsg)msg); + } else if (msg instanceof APISetVmNicSecurityGroupMsg) { + validate((APISetVmNicSecurityGroupMsg) msg); + } else if (msg instanceof APIAddSecurityGroupRuleMsg) { + validate((APIAddSecurityGroupRuleMsg) msg); + } else if (msg instanceof APIChangeVmNicNetworkMsg) { + validate((APIChangeVmNicNetworkMsg) msg); + } else if (msg instanceof APIPullSdnControllerTenantMsg) { + validate((APIPullSdnControllerTenantMsg) msg); + } else if (msg instanceof APIChangeSdnControllerMsg) { + validate((APIChangeSdnControllerMsg) msg); + } + + setServiceId(msg); + + return msg; + } + + private void validate(APIAttachL3NetworkToVmMsg msg) { + String sdnControlerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(msg.getL3NetworkUuid()); + if (sdnControlerUuid == null) { + return; + } + + SdnControllerVO controllerVO = dbf.findByUuid(sdnControlerUuid, SdnControllerVO.class); + if (controllerVO == null) { + throw new ApiMessageInterceptionException(argerr("could not attach l3network to vm, " + + "because sdn controller[uuid:%s] is not find", sdnControlerUuid)); + } + + if (SdnControllerConstant.H3C_VCFC_CONTROLLER.equals(controllerVO.getVendorType()) && + SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(controllerVO.getVendorVersion())) { + validateH3cTenantStatus(msg.getL3NetworkUuid(), sdnControlerUuid); + return; + } + + if (SdnControllerConstant.H3C_VCFC_CONTROLLER.equals(controllerVO.getVendorType())) { + return; + } + + VmInstanceVO vmVo = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); + boolean found = false; + for (SdnControllerHostRefVO ref : controllerVO.getHostRefVOS()) { + if (ref.getHostUuid().equals(vmVo.getHostUuid())) { + found = true; + break; + } + } + if (!found) { + throw new ApiMessageInterceptionException(argerr("could not attach l3network to vm, " + + "because host[uuid:%s] of vm is not attached to sdn controller[uuid:%s]", + vmVo.getHostUuid(), sdnControlerUuid)); + } + } + + private void validate(APIChangeVmNicNetworkMsg msg) { + String sdnControlerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(msg.getDestL3NetworkUuid()); + if (sdnControlerUuid == null) { + return; + } + + SdnControllerVO controllerVO = dbf.findByUuid(sdnControlerUuid, SdnControllerVO.class); + if (controllerVO == null) { + throw new ApiMessageInterceptionException(argerr("could not change vmnic to l3network[uuid:%s], " + + "because sdn controller[uuid:%s] is not find", msg.getDestL3NetworkUuid(), sdnControlerUuid)); + } + + VmInstanceVO vmVo = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); + boolean found = false; + for (SdnControllerHostRefVO ref : controllerVO.getHostRefVOS()) { + if (ref.getHostUuid().equals(vmVo.getHostUuid())) { + found = true; + break; + } + } + if (!found) { + throw new ApiMessageInterceptionException(argerr("could not change vmnic to l3network[uuid:%s], " + + "because host[uuid:%s] of vm is not attached to sdn controller[uuid:%s]", + msg.getDestL3NetworkUuid(), vmVo.getHostUuid(), sdnControlerUuid)); + } + } + + private void validate(APISetVmNicSecurityGroupMsg msg) { + VmNicVO nicVO = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); + String nicControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(nicVO.getL3NetworkUuid()); + for (APISetVmNicSecurityGroupMsg.VmNicSecurityGroupRefAO ref : msg.getRefs()) { + String sgControllerUuid = SecurityGroupHelper.getSdnControllerUuid(ref.getSecurityGroupUuid()); + if (!StringUtils.equals(sgControllerUuid, nicControllerUuid)) { + throw new ApiMessageInterceptionException(argerr("could not add vmnic to securityGroup, " + + "because they have different sdn controller[nic controller uuid:%s, security group controller uuid:%s]", + nicControllerUuid, sgControllerUuid)); + } + } + } + + private void validate(APIAddSecurityGroupRuleMsg msg) { + String sgControllerUuid = SecurityGroupHelper.getSdnControllerUuid(msg.getSecurityGroupUuid()); + for (APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO rule : msg.getRules()) { + if (rule.getRemoteSecurityGroupUuid() == null) { + continue; + } + String remoteControllerUuid = SecurityGroupHelper.getSdnControllerUuid(rule.getRemoteSecurityGroupUuid()); + if (!StringUtils.equals(sgControllerUuid, remoteControllerUuid)) { + throw new ApiMessageInterceptionException(argerr("could not add securityGroup rule, " + + "because rule remote security group sdn controller uuid[:%s] is different from security group controller uuid[:%s]", + remoteControllerUuid, sgControllerUuid)); + } + } + } + + private void validate(APIAddSdnControllerMsg msg) { + if (!SdnControllerType.getAllTypeNames().contains(msg.getVendorType())) { + throw new ApiMessageInterceptionException(argerr("could not add sdn controller because type: %s in not in the supported list: %s", msg.getVendorType(), SdnControllerType.getAllTypeNames())); + } + + if (!NetworkUtils.isUnicastIPAddress(msg.getIp())) { + throw new ApiMessageInterceptionException(argerr("could not add sdn controller because ip[%s] is not an unicast address", msg.getIp())); + } + + boolean existed = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.ip, msg.getIp()).isExists(); + if (existed) { + throw new ApiMessageInterceptionException(argerr("could not add sdn controller because controller [ip:%s] is already added", msg.getIp())); + } + } + + private void validate(APISdnControllerAddHostMsg msg) { + if (Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.vSwitchType, msg.getvSwitchType()) + .eq(SdnControllerHostRefVO_.hostUuid, msg.getHostUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could not add host[uuid:%s] to sdn controller[uuid:%s], " + + " because host already attached to sdn controller", msg.getHostUuid(), msg.getSdnControllerUuid())); + } + + if (msg.getVtepIp() != null && msg.getNetmask() == null) { + throw new ApiMessageInterceptionException(argerr("could not add host[uuid:%s] to sdn controller[uuid:%s], " + + " because netmask is not specified", msg.getHostUuid(), msg.getSdnControllerUuid())); + } + + if (msg.getVtepIp() != null) { + SdnControllerHostRefVO refvo = Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .eq(SdnControllerHostRefVO_.vSwitchType, msg.getvSwitchType()) + .eq(SdnControllerHostRefVO_.vtepIp, msg.getVtepIp()).find(); + if (refvo != null) { + throw new ApiMessageInterceptionException(argerr("could not add host[uuid:%s] to sdn controller[uuid:%s], " + + " because vtepip is used by host[uuid:%s]", msg.getHostUuid(), + msg.getSdnControllerUuid(), refvo.getHostUuid())); + } + } + + if (msg.getNicNames().size() > 1 && msg.getBondMode() == null) { + msg.setBondMode(L2NetworkConstant.BONDING_MODE_AB); + } + + if (msg.getBondMode() != null && msg.getBondMode().equals(L2NetworkConstant.BONDING_MODE_TCP) && msg.getLacpMode() == null) { + msg.setLacpMode(L2NetworkConstant.LACP_MODE_ACTIVE); + } + } + + private void validate(APISdnControllerRemoveHostMsg msg) { + if (!Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .eq(SdnControllerHostRefVO_.hostUuid, msg.getHostUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could not remove host[uuid:%s] from sdn controller[uuid:%s], " + + " because host has not been added to sdn controller", msg.getHostUuid(), msg.getSdnControllerUuid())); + } + } + + private void validate(APISdnControllerChangeHostMsg msg) { + SdnControllerHostRefVO refVO = Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .eq(SdnControllerHostRefVO_.hostUuid, msg.getHostUuid()).find(); + if (refVO == null) { + throw new ApiMessageInterceptionException(argerr("could not change host[uuid:%s] of sdn controller[uuid:%s], " + + " because host has not been added to sdn controller", msg.getHostUuid(), msg.getSdnControllerUuid())); + } + + if (msg.getVtepIp() != null && msg.getNetmask() == null) { + throw new ApiMessageInterceptionException(argerr("could not change host[uuid:%s] of sdn controller[uuid:%s], " + + " because netmask is specified", msg.getHostUuid(), msg.getSdnControllerUuid())); + } + + if (msg.getNicNames() == null) { + Gson gson = new Gson(); + Type type = new TypeToken>(){}.getType(); + Map nicNamePciAddressMap = gson.fromJson(refVO.getNicPciAddresses(), type); + msg.setNicNames(new ArrayList<>(nicNamePciAddressMap.keySet())); + } + + if (msg.getNicNames().size() > 1 && msg.getBondMode() == null) { + msg.setBondMode(refVO.getBondMode()); + } + } + + private void validateH3cTenantStatus(String l3NetworkUuid, String sdnControllerUuid) { + String l2NetworkUuid = Q.New(L3NetworkVO.class) + .eq(L3NetworkVO_.uuid, l3NetworkUuid) + .select(L3NetworkVO_.l2NetworkUuid) + .findValue(); + if (l2NetworkUuid == null) { + return; + } + VxlanNetworkVO vxlanVO = Q.New(VxlanNetworkVO.class) + .eq(VxlanNetworkVO_.uuid, l2NetworkUuid) + .find(); + if (vxlanVO == null) { + return; + } + HardwareL2VxlanNetworkPoolVO poolVO = Q.New(HardwareL2VxlanNetworkPoolVO.class) + .eq(HardwareL2VxlanNetworkPoolVO_.uuid, vxlanVO.getPoolUuid()) + .find(); + if (vxlanVO.getPoolUuid() == null || poolVO == null || !sdnControllerUuid.equals(poolVO.getSdnControllerUuid())) { + return; + } + boolean hasDisabledTenants = Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.sdnControllerUuid, sdnControllerUuid) + .eq(H3cSdnControllerTenantVO_.state, SdnControllerConstant.H3C_SDN_CONTROLLER_TENANT_STATE_DISABLE) + .isExists(); + if (hasDisabledTenants) { + throw new ApiMessageInterceptionException(argerr("Cannot attach L3 network to VM because some tenants in SDN controller[uuid:%s] have been deleted. " + + "Please run tenant synchronization first to update tenant status", sdnControllerUuid)); + } + } + + private void validate(APIPullSdnControllerTenantMsg msg) { + SdnControllerVO sdnControllerVO = dbf.findByUuid(msg.getSdnControllerUuid(), SdnControllerVO.class); + if (sdnControllerVO == null) { + throw new ApiMessageInterceptionException(argerr("SDN controller[uuid:%s] not found", msg.getSdnControllerUuid())); + } + + // Only H3C_VCFC_CONTROLLER with vendorVersion H3C_VCFC_VENDOR_VERSION_V2 supports pull tenant operation + if (!SdnControllerConstant.H3C_VCFC_CONTROLLER.equals(sdnControllerVO.getVendorType()) || + !SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(sdnControllerVO.getVendorVersion())) { + throw new ApiMessageInterceptionException(argerr("Pull tenant operation is not supported for SDN controller[uuid:%s, vendorType:%s, vendorVersion:%s]. " + + "Only H3C VCFC V2 controllers support this operation", + msg.getSdnControllerUuid(), sdnControllerVO.getVendorType(), sdnControllerVO.getVendorVersion())); + } + } + + private void validateVlanRanges(List ranges) { + List sdnVlanRanges = new ArrayList<>(); + for (String range : ranges) { + List vlans = Arrays.asList(range.split("-")); + if (vlans.size() != 2) { + throw new ApiMessageInterceptionException(argerr("could not change sdn controller, " + + "because vlan range[%s] is not in the correct format", range)); + } + + try { + int start = Integer.parseInt(vlans.get(0)); + int end = Integer.parseInt(vlans.get(1)); + if (start > end) { + throw new ApiMessageInterceptionException(argerr("could not change sdn controller, " + + "because vlan range[%s] is not in the correct format", range)); + } + + for (SdnVlanRange vrange : sdnVlanRanges) { + if (isOverlappedVlanRange(start, end, vrange.startVlan, vrange.endVlan)) { + throw new ApiMessageInterceptionException(argerr("could not change sdn controller, " + + "because vlan range[%s] is overlapped with other vlan range", range)); + } + } + SdnVlanRange vlanRange = new SdnVlanRange(); + vlanRange.startVlan = start; + vlanRange.endVlan = end; + sdnVlanRanges.add(vlanRange); + } catch (Exception e) { + throw new ApiMessageInterceptionException(argerr("could not change sdn controller, " + + "because vlan range[%s] is not in the correct format", range)); + } + } + } + + private boolean isOverlappedVlanRange(int start, int end, Integer startVlan, Integer endVlan) { + // Two ranges [start, end] and [startVlan, endVlan] overlap if: + // 1. start is within [startVlan, endVlan], OR + // 2. end is within [startVlan, endVlan], OR + // 3. [start, end] completely contains [startVlan, endVlan] + return (start >= startVlan && start <= endVlan) || + (end >= startVlan && end <= endVlan) || + (start <= startVlan && end >= endVlan); + } + + private void validate(APIChangeSdnControllerMsg msg) { + if (msg.getVlanRanges() != null && !msg.getVlanRanges().isEmpty()) { + validateVlanRanges(msg.getVlanRanges()); + } + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerBase.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerBase.java new file mode 100644 index 00000000000..f4733f6a833 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerBase.java @@ -0,0 +1,1215 @@ +package org.zstack.sdnController; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cascade.CascadeFacade; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.EventFacade; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NopeCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.DeleteL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.SdnControllerDeleteExtensionPoint; +import org.zstack.header.network.l3.SdnControllerL3; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO; +import org.zstack.network.hostNetworkInterface.HostNetworkInterfaceVO_; +import org.zstack.sdnController.header.*; +import org.zstack.sdnController.h3cVcfc.H3cVcfcV2Commands; +import org.zstack.sdnController.h3cVcfc.H3cVcfcV2SdnController; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + +import javax.persistence.Tuple; +import java.lang.reflect.Type; +import java.util.*; +import java.util.stream.Collectors; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.argerr; +import static org.zstack.core.Platform.operr; +import static org.zstack.sdnController.header.SdnControllerFlowDataParam.SDN_CONTROLLER_UUID; +import static org.zstack.sdnController.header.SdnControllerFlowDataParam.*; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class SdnControllerBase { + private static final CLogger logger = Utils.getLogger(SdnControllerBase.class); + @Autowired + CloudBus bus; + @Autowired + DatabaseFacade dbf; + @Autowired + private CascadeFacade casf; + @Autowired + private ThreadFacade thdf; + @Autowired + private EventFacade evtf; + @Autowired + SdnControllerManager sdnMgr; + @Autowired + private PluginRegistry pluginRgty; + @Autowired + private SdnControllerPingTracker sdnPingTracker; + + public SdnControllerVO self; + + public SdnControllerBase(SdnControllerVO self) { + this.self = self; + } + + public String getSdnControllerSignature() { + return "sdn-controller-" + self.getUuid(); + } + + protected SdnController getSdnController() { + SdnControllerFactory factory = sdnMgr.getSdnControllerFactory(self.getVendorType()); + return factory.getSdnController(self); + } + + protected SdnControllerL2 getSdnControllerL2() { + SdnControllerFactory factory = sdnMgr.getSdnControllerFactory(self.getVendorType()); + return factory.getSdnControllerL2(self); + } + + protected SdnControllerL3 getSdnControllerL3() { + SdnControllerFactory factory = sdnMgr.getSdnControllerFactory(self.getVendorType()); + return factory.getSdnControllerL3(self); + } + + public void handleMessage(SdnControllerMessage msg) { + if (msg instanceof APIRemoveSdnControllerMsg) { + handle((APIRemoveSdnControllerMsg) msg); + } else if (msg instanceof APIUpdateSdnControllerMsg) { + handle((APIUpdateSdnControllerMsg) msg); + } else if (msg instanceof SdnControllerDeletionMsg) { + handle((SdnControllerDeletionMsg) msg); + } else if (msg instanceof APISdnControllerAddHostMsg) { + handle((APISdnControllerAddHostMsg) msg); + } else if (msg instanceof APISdnControllerRemoveHostMsg) { + handle((APISdnControllerRemoveHostMsg) msg); + } else if (msg instanceof APIReconnectSdnControllerMsg) { + handle((APIReconnectSdnControllerMsg) msg); + } else if (msg instanceof APISdnControllerChangeHostMsg) { + handle((APISdnControllerChangeHostMsg) msg); + } else if (msg instanceof APIPullSdnControllerTenantMsg) { + handle((APIPullSdnControllerTenantMsg) msg); + } else if (msg instanceof APIChangeSdnControllerMsg) { + handle((APIChangeSdnControllerMsg) msg); + } else if (msg instanceof SdnControllerRemoveHostMsg) { + handle((SdnControllerRemoveHostMsg) msg); + } else if (msg instanceof PullSdnControllerTenantMsg) { + handle((PullSdnControllerTenantMsg) msg); + } else if (msg instanceof ReconnectSdnControllerMsg) { + handle((ReconnectSdnControllerMsg) msg); + } else { + SdnController controller = getSdnController(); + controller.handleMessage(msg); + } + } + + public void changeSdnControllerStatus(SdnControllerStatus status) { + if (status == self.getStatus()) { + return; + } + + SdnControllerStatus oldStatus = self.getStatus(); + logger.debug(String.format("sdn controller [%s] changed status, old status: [%s], new status: [%s]", + self.getUuid(), oldStatus, status.toString())); + self.setStatus(status); + self = dbf.updateAndRefresh(self); + + SdnControllerCanonicalEvents.SdnControllerStatusChangedData d = new SdnControllerCanonicalEvents.SdnControllerStatusChangedData(); + d.setSdnControllerUuid(self.getUuid()); + d.setSdnControllerType(self.getVendorType()); + d.setOldStatus(oldStatus.toString()); + d.setNewStatus(status.toString()); + d.setInv(SdnControllerInventory.valueOf(self)); + evtf.fire(SdnControllerCanonicalEvents.SDNCONTROLLER_STATUS_CHANGED_PATH, d); + } + + private void doChangeSdnController(APIChangeSdnControllerMsg msg, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("change-sdn-controller-%s-%s", self.getUuid(), self.getName())); + chain.then(new Flow() { + String __name__ = "change-sdn-controller-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + boolean changed = false; + + // Handle name change + if (msg.getUserName() != null && !msg.getUserName().equals(self.getName())) { + chain.getData().put(SDN_CONTROLLER_USERNAME, self.getName()); + self.setUsername(msg.getUserName()); + changed = true; + } + + // Handle password change + if (msg.getPassword() != null && !msg.getPassword().equals(self.getPassword())) { + chain.getData().put(SDN_CONTROLLER_PASSWORD, self.getPassword()); + self.setPassword(msg.getPassword()); + changed = true; + } + + if (changed) { + self = dbf.updateAndRefresh(self); + chain.getData().put(SDN_CONTROLLER_CHANGED, changed); + } + + if (msg.getVlanRanges() != null && !msg.getVlanRanges().isEmpty()) { + SdnControllerSystemTags.VLAN_RANGE.delete(self.getUuid()); + for (String vlanRange : msg.getVlanRanges()) { + List vlans = Arrays.asList(vlanRange.split("-")); + SystemTagCreator creator = SdnControllerSystemTags.VLAN_RANGE.newSystemTagCreator(self.getUuid()); + creator.setTagByTokens(map( + e(SdnControllerSystemTags.START_VLAN_TOKEN, vlans.get(0)), + e(SdnControllerSystemTags.END_VLAN_TOKEN, vlans.get(1)))); + creator.inherent = false; + creator.recreate = false; + creator.ignoreIfExisting = true; + creator.create(); + } + } + + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + String username = (String)chain.getData().get(SDN_CONTROLLER_USERNAME); + String password = (String)chain.getData().get(SDN_CONTROLLER_PASSWORD); + if (password != null) { + self.setPassword(password); + } + if (username != null) { + self.setUsername(username); + } + if (password != null || username != null) { + self = dbf.updateAndRefresh(self); + } + + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "ping-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + boolean changed = data.get(SDN_CONTROLLER_CHANGED) == null ? false : (boolean) data.get(SDN_CONTROLLER_CHANGED); + if (!changed) { + // password not changed + trigger.next(); + return; + } + + SdnControllerPingMsg pmsg = new SdnControllerPingMsg(); + pmsg.setSdnControllerUuid(self.getUuid()); + bus.makeTargetServiceIdByResourceUuid(pmsg, SdnControllerConstant.SERVICE_ID, self.getUuid()); + bus.send(pmsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(operr("ping sdn controller failed, error: %s", reply.getError().getDetails())); + } else { + trigger.next(); + } + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + private void changeSdnController(APIChangeSdnControllerMsg msg, Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public String getSyncSignature() { + return getSdnControllerSignature(); + } + + @Override + public void run(SyncTaskChain chain) { + doChangeSdnController(msg, new Completion(completion) { + @Override + public void success() { + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("change-sdn-controller-%s", self.getUuid()); + } + }); + } + + private void handle(APIChangeSdnControllerMsg msg) { + APIChangeSdnControllerEvent event = new APIChangeSdnControllerEvent(msg.getId()); + changeSdnController(msg, new Completion(msg) { + @Override + public void success() { + event.setInventory(SdnControllerInventory.valueOf(dbf.findByUuid(msg.getSdnControllerUuid(), SdnControllerVO.class))); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + private void handle(APIReconnectSdnControllerMsg msg) { + APIReconnectSdnControllerEvent event = new APIReconnectSdnControllerEvent(msg.getId()); + reconnectSdnController(new Completion(msg) { + @Override + public void success() { + event.setInventory(SdnControllerInventory.valueOf(dbf.findByUuid(msg.getSdnControllerUuid(), SdnControllerVO.class))); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + private void handle(ReconnectSdnControllerMsg msg) { + ReconnectSdnControllerReply reply = new ReconnectSdnControllerReply(); + reconnectSdnController(new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void reconnectSdnController(Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public String getSyncSignature() { + return getSdnControllerSignature(); + } + + @Override + public void run(SyncTaskChain chain) { + doReconnectSdnController(new Completion(completion) { + @Override + public void success() { + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("reconnect-sdn-controller-%s", self.getUuid()); + } + }); + } + + private void doReconnectSdnController(Completion completion) { + FlowChain chain = sdnMgr.getSyncChain(self); + chain.getData().put(SDN_CONTROLLER_UUID, self.getUuid()); + chain.setName(String.format("sync-sdn-controller-%s-%s", self.getUuid(), self.getName())); + chain.insert(new Flow() { + String __name__ = "change-sdn-controller-status-to-connecting"; + + @Override + public void run(FlowTrigger trigger, Map data) { + changeSdnControllerStatus(SdnControllerStatus.Connecting); + trigger.next(); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + changeSdnControllerStatus(SdnControllerStatus.Disconnected); + trigger.rollback(); + } + }).then(new NoRollbackFlow() { + String __name__ = "reconnect-to-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + SdnController controller = getSdnController(); + controller.reconnectSdnController(new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "change-sdn-controller-status-to-connected"; + + @Override + public void run(FlowTrigger trigger, Map data) { + changeSdnControllerStatus(SdnControllerStatus.Connected); + trigger.next(); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + private void sdnControllerAddHost(APISdnControllerAddHostMsg msg, Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public String getSyncSignature() { + return getSdnControllerSignature(); + } + + @Override + public void run(SyncTaskChain chain) { + SdnControllerHostRefVO refvo = Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .eq(SdnControllerHostRefVO_.vSwitchType, msg.getvSwitchType()) + .eq(SdnControllerHostRefVO_.vtepIp, msg.getVtepIp()).find(); + if (refvo != null) { + completion.fail(argerr("could not add host[uuid:%s] to sdn controller[uuid:%s], " + + " because vtepip is used by host[uuid:%s]", msg.getHostUuid(), + msg.getSdnControllerUuid(), refvo.getHostUuid())); + return; + } + + SdnController controller = getSdnController(); + controller.addHost(msg, new Completion(completion) { + @Override + public void success() { + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("sdn-controller-%s-add-host-%s", + self.getUuid(), msg.getHostUuid()); + } + }); + } + + private void handle(APISdnControllerAddHostMsg msg) { + APISdnControllerAddHostEvent event = new APISdnControllerAddHostEvent(msg.getId()); + sdnControllerAddHost(msg, new Completion(msg) { + @Override + public void success() { + event.setInventory(SdnControllerInventory.valueOf(dbf.findByUuid(msg.getSdnControllerUuid(), SdnControllerVO.class))); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + private void sdnControllerRemoveHost(SdnControllerRemoveHostMsg msg, Completion completion) { + SdnController controller = getSdnController(); + controller.removeHost(msg, new Completion(completion) { + @Override + public void success() { + SQL.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .eq(SdnControllerHostRefVO_.hostUuid, msg.getHostUuid()) + .eq(SdnControllerHostRefVO_.vSwitchType, msg.getvSwitchType()).delete(); + self = dbf.reload(self); + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void sdnControllerRemoveHostInQueue(SdnControllerRemoveHostMsg msg, Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public String getSyncSignature() { + return getSdnControllerSignature(); + } + + @Override + public void run(SyncTaskChain chain) { + sdnControllerRemoveHost(msg, new Completion(completion) { + @Override + public void success() { + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("sdn-controller-%s-remove-host-%s", + self.getUuid(), msg.getHostUuid()); + } + }); + } + + private void handle(APISdnControllerRemoveHostMsg amsg) { + APISdnControllerRemoveHostEvent event = new APISdnControllerRemoveHostEvent(amsg.getId()); + + SdnControllerRemoveHostMsg msg = new SdnControllerRemoveHostMsg(); + msg.setSdnControllerUuid(amsg.getSdnControllerUuid()); + msg.setHostUuid(amsg.getHostUuid()); + msg.setvSwitchType(amsg.getvSwitchType()); + sdnControllerRemoveHostInQueue(msg, new Completion(msg) { + @Override + public void success() { + event.setInventory(SdnControllerInventory.valueOf(dbf.findByUuid(msg.getSdnControllerUuid(), SdnControllerVO.class))); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + private void handle(SdnControllerRemoveHostMsg msg) { + SdnControllerRemoveHostReply reply = new SdnControllerRemoveHostReply(); + + if (msg.isCreateChain()) { + sdnControllerRemoveHostInQueue(msg, new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } else { + sdnControllerRemoveHost(msg, new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + } + + private void doControllerChangeHost(APISdnControllerChangeHostMsg msg, Completion completion) { + thdf.chainSubmit(new ChainTask(completion) { + @Override + public String getSyncSignature() { + return getSdnControllerSignature(); + } + + @Override + public void run(SyncTaskChain chain) { + SdnControllerHostRefVO newRef = Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .eq(SdnControllerHostRefVO_.hostUuid, msg.getHostUuid()).find(); + SdnControllerHostRefVO oldRef = SdnControllerHostRefVO.fromOther(newRef); + + boolean changed = false; + Gson gson = new Gson(); + Type type = new TypeToken>(){}.getType(); + Map nicNamePciAddressMap = gson.fromJson(newRef.getNicPciAddresses(), type); + List oldNicNames = new ArrayList<>(nicNamePciAddressMap.keySet()); + Collections.sort(oldNicNames); + Collections.sort(msg.getNicNames()); + if (!oldNicNames.equals(msg.getNicNames())) { + changed = true; + Map nicNameDriverMap = new HashMap<>(); + nicNamePciAddressMap = new HashMap<>(); + List nicTuples = Q.New(HostNetworkInterfaceVO.class) + .eq(HostNetworkInterfaceVO_.hostUuid, msg.getHostUuid()) + .in(HostNetworkInterfaceVO_.interfaceName, msg.getNicNames()) + .select(HostNetworkInterfaceVO_.interfaceName, + HostNetworkInterfaceVO_.driverType, + HostNetworkInterfaceVO_.pciDeviceAddress) + .listTuple(); + for (Tuple t : nicTuples) { + nicNameDriverMap.put(t.get(0, String.class), t.get(1, String.class)); + nicNamePciAddressMap.put(t.get(0, String.class), t.get(2, String.class)); + } + newRef.setNicDrivers(JSONObjectUtil.toJsonString(nicNameDriverMap)); + newRef.setNicPciAddresses(JSONObjectUtil.toJsonString(nicNamePciAddressMap)); + } + + if (msg.getVtepIp() != null && !msg.getVtepIp().equals(newRef.getVtepIp())) { + changed = true; + newRef.setVtepIp(msg.getVtepIp()); + } + + if (msg.getNetmask() != null && !msg.getNetmask().equals(newRef.getNetmask())) { + changed = true; + newRef.setNetmask(msg.getNetmask()); + } + + if (msg.getBondMode() != null && !msg.getBondMode().equals(newRef.getBondMode())) { + changed = true; + newRef.setBondMode(msg.getBondMode()); + } + + if (msg.getLacpMode() != null && !msg.getLacpMode().equals(newRef.getLacpMode())) { + changed = true; + newRef.setLacpMode(msg.getLacpMode()); + } + + if (!changed) { + completion.success(); + chain.next(); + return; + } + + SdnController controller = getSdnController(); + controller.changeHost(oldRef, newRef, new Completion(msg) { + @Override + public void success() { + dbf.update(newRef); + completion.success(); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("sdn-controller-%s-change-host-%s", + self.getUuid(), msg.getHostUuid()); + } + }); + } + + private void handle(APISdnControllerChangeHostMsg msg) { + APISdnControllerChangeHostEvent event = new APISdnControllerChangeHostEvent(msg.getId()); + doControllerChangeHost(msg, new Completion(msg) { + @Override + public void success() { + self = dbf.reload(self); + event.setInventory(SdnControllerInventory.valueOf(self)); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + private void doDeletionSdnController(SdnControllerDeletionMsg msg, Completion completion) { + SdnController controller = getSdnController(); + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("sdn-controller-deletion-%s", msg.getSdnControllerUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = String.format("detach-hardvxlan-network-of-sdn-controller-%s", self.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + List poolVos = Q.New(HardwareL2VxlanNetworkPoolVO.class) + .eq(HardwareL2VxlanNetworkPoolVO_.sdnControllerUuid, msg.getSdnControllerUuid()).list(); + new While<>(poolVos).each((pool, wcomp) -> { + DeleteL2NetworkMsg msg = new DeleteL2NetworkMsg(); + msg.setUuid(pool.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, pool.getUuid()); + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.info(String.format("delete hardware vxpool[uuid:%s] failed, reason:%s", pool.getUuid(), reply.getError().getDetails())); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "delete-sdn-network"; + + @Override + public void run(FlowTrigger trigger, Map data) { + SdnControllerL2 sdnControllerL2 = getSdnControllerL2(); + List l2Tuples = sdnControllerL2.getL2NetworkOfSdnController(); + List l2Uuids = l2Tuples.stream().map(t -> t.get(0, String.class)).collect(Collectors.toList()); + if (l2Uuids.isEmpty()) { + trigger.next(); + return; + } + + new While<>(l2Uuids).each((uuid, wcomp) -> { + DeleteL2NetworkMsg msg = new DeleteL2NetworkMsg(); + msg.setUuid(uuid); + bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, uuid); + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.info(String.format("delete sdn l2 network[uuid:%s] failed, reason:%s", uuid, reply.getError().getDetails())); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "remove-host-from-sdn-controller"; + @Override + public void run(FlowTrigger trigger, Map data) { + List refVOS = Q.New(SdnControllerHostRefVO.class) + .eq(SdnControllerHostRefVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .list(); + if (refVOS.isEmpty()) { + trigger.next(); + return; + } + + new While<>(refVOS).each((ref, wcomp) -> { + SdnControllerRemoveHostMsg msg = new SdnControllerRemoveHostMsg(); + msg.setSdnControllerUuid(ref.getSdnControllerUuid()); + msg.setHostUuid(ref.getHostUuid()); + msg.setvSwitchType(ref.getvSwitchType()); + msg.setCreateChain(false); + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, ref.getSdnControllerUuid()); + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.debug(String.format("delete host [uuid:%s] from sdn controller[uuid:%s] failed, error:%s", + msg.getHostUuid(), msg.getSdnControllerUuid(), reply.getError().getDetails())); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = String.format("delete-network-service"); + + @Override + public void run(FlowTrigger trigger, Map data) { + List exps = pluginRgty.getExtensionList(SdnControllerDeleteExtensionPoint.class); + new While<>(exps).each((exp, wcomp) -> { + exp.deleteNetworkServiceOfSdnController(msg.getSdnControllerUuid(), new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("delete network service failed, error: %s", errorCode.getDetails())); + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = String.format("delete-from-sdn-controller"); + + @Override + public void run(FlowTrigger trigger, Map data) { + controller.deleteSdnController(msg, SdnControllerInventory.valueOf(self), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "delete-sdn-controller-on-db"; + @Override + public void run(FlowTrigger trigger, Map data) { + sdnPingTracker.untrack(msg.getSdnControllerUuid()); + dbf.removeByPrimaryKey(msg.getSdnControllerUuid(), SdnControllerVO.class); + trigger.next(); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + private void handle(SdnControllerDeletionMsg msg) { + SdnControllerDeletionReply reply = new SdnControllerDeletionReply(); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format("sdn-controller-%s", msg.getSdnControllerUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + doDeletionSdnController(msg, new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("delete-sdn-controller-%s", msg.getSdnControllerUuid()); + } + }); + } + + private void handle(APIRemoveSdnControllerMsg msg) { + APIRemoveSdnControllerEvent event = new APIRemoveSdnControllerEvent(msg.getId()); + + final String issuer = SdnControllerVO.class.getSimpleName(); + SdnControllerVO vo = dbf.findByUuid(msg.getUuid(), SdnControllerVO.class); + final List ctx = asList(SdnControllerInventory.valueOf(vo)); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("delete-sdn-controller-%s-name-%s", msg.getUuid(), vo.getName())); + if (msg.getDeletionMode() == APIDeleteMessage.DeletionMode.Permissive) { + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + casf.asyncCascade(CascadeConstant.DELETION_CHECK_CODE, issuer, ctx, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + casf.asyncCascade(CascadeConstant.DELETION_DELETE_CODE, issuer, ctx, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + } else { + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + casf.asyncCascade(CascadeConstant.DELETION_FORCE_DELETE_CODE, issuer, ctx, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + } + + chain.done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + casf.asyncCascadeFull(CascadeConstant.DELETION_CLEANUP_CODE, issuer, ctx, new NopeCompletion()); + bus.publish(event); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + event.setError(errCode); + bus.publish(event); + } + }).start(); + } + + private void handle(APIUpdateSdnControllerMsg msg) { + APIUpdateSdnControllerEvent event = new APIUpdateSdnControllerEvent(msg.getId()); + SdnControllerVO vo = dbf.findByUuid(msg.getUuid(), SdnControllerVO.class); + Boolean changed = false; + + if (msg.getName() != null && !msg.getName().equals(vo.getName())) { + vo.setName(msg.getName()); + changed = true; + } + + if (msg.getDescription() != null && !msg.getDescription().equals(vo.getDescription())) { + vo.setDescription(msg.getDescription()); + changed = true; + } + + if (changed) { + vo = dbf.updateAndRefresh(vo); + } + + event.setInventory(SdnControllerInventory.valueOf(vo)); + bus.publish(event); + } + + private void handle(APIPullSdnControllerTenantMsg amsg) { + APIPullSdnControllerTenantEvent event = new APIPullSdnControllerTenantEvent(amsg.getId()); + + PullSdnControllerTenantMsg msg = PullSdnControllerTenantMsg.fromApi(amsg); + pullSdnControllerTenant(msg, new Completion(msg) { + @Override + public void success() { + // After synchronization is complete, query and return the latest tenant data + List tenantVOs = Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .list(); + List inventories = H3cSdnControllerTenantInventory.valueOf(tenantVOs); + event.setInventories(inventories); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + private void handle(PullSdnControllerTenantMsg msg) { + PullSdnControllerTenantReply reply = new PullSdnControllerTenantReply(); + + pullSdnControllerTenant(msg, new Completion(msg) { + @Override + public void success() { + // After synchronization is complete, query and return the latest tenant data + List tenantVOs = Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.sdnControllerUuid, msg.getSdnControllerUuid()) + .list(); + List inventories = H3cSdnControllerTenantInventory.valueOf(tenantVOs); + reply.setInventories(inventories); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void pullSdnControllerTenant(PullSdnControllerTenantMsg msg, Completion completion) { + // Only H3C VCFC V2 controllers support this operation, already validated in interceptor + // But confirm again here to ensure type safety + if (!SdnControllerConstant.H3C_VCFC_CONTROLLER.equals(self.getVendorType()) || + !SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(self.getVendorVersion())) { + completion.fail(operr("Pull tenant operation is only supported for H3C VCFC V2 controllers")); + return; + } + + // Get the correct controller instance through factory + SdnControllerFactory factory = sdnMgr.getSdnControllerFactory(self.getVendorType()); + H3cVcfcV2SdnController h3cController = (H3cVcfcV2SdnController) factory.getSdnController(self); + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("pull-tenant-for-h3c-sdn-%s", self.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "pull-h3c-vds-tenant"; + + @Override + public void run(FlowTrigger trigger, Map data) { + try { + // Directly get all tenant information + h3cController.getH3cControllerToken(new Completion(trigger) { + @Override + public void success() { + List apiTenants = h3cController.getAllH3cTenants(); + List apiVds = h3cController.getAllH3cVds(); + syncTenantData(msg.getSdnControllerUuid(), apiTenants, apiVds, trigger); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } catch (Exception e) { + trigger.fail(operr("Failed to pull tenant data: %s", e.getMessage())); + } + } + }).then(new NoRollbackFlow() { + String __name__ = "pull-h3c-vni-ranges"; + + @Override + public void run(FlowTrigger trigger, Map data) { + h3cController.getH3cVniRanges(new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + private void syncTenantData(String sdnControllerUuid, List apiTenants, List apiVds, FlowTrigger trigger) { + // Check if API response is valid (non-empty list indicates valid response with default tenant) + if (apiTenants == null || apiTenants.isEmpty()) { + logger.warn(String.format("Failed to pull tenant data for sdn controller [%s], no tenant data returned by API", sdnControllerUuid)); + trigger.next(); + return; + } + + // Query existing tenant records in database + List existingTenants = Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.sdnControllerUuid, sdnControllerUuid) + .list(); + + // Create mapping table for easy lookup + Map existingTenantMap = new HashMap<>(); + for (H3cSdnControllerTenantVO tenant : existingTenants) { + String key = generateTenantKey(tenant.getTenantUuid(), tenant.getVdsUuid()); + existingTenantMap.put(key, tenant); + } + + Set apiTenantKeys = new HashSet<>(); + List tenantsToSave = new ArrayList<>(); + + // Process tenant data returned by API + for (H3cVcfcV2Commands.H3cTenantStruct apiTenant : apiTenants) { + if (apiTenant.vds_list != null && !apiTenant.vds_list.isEmpty()) { + String vdsUuid = apiTenant.vds_list.get(0); + String key = generateTenantKey(apiTenant.id, vdsUuid); + apiTenantKeys.add(key); + + H3cSdnControllerTenantVO existingTenant = existingTenantMap.get(key); + if (existingTenant == null) { + // New tenant, create record + H3cSdnControllerTenantVO newTenant = new H3cSdnControllerTenantVO(); + newTenant.setUuid(Platform.getUuid()); + newTenant.setSdnControllerUuid(sdnControllerUuid); + newTenant.setTenantUuid(apiTenant.id); + newTenant.setVdsUuid(vdsUuid); + newTenant.setTenantName(apiTenant.name); + // Find vdsName from apiVds, use vdsUuid as fallback + String vdsName = vdsUuid; + for (H3cVcfcV2Commands.H3cVdsStruct vds : apiVds) { + if (Objects.equals(vds.uuid, vdsUuid) && vds.name != null) { + vdsName = vds.name; + break; + } + } + newTenant.setVdsName(vdsName); + newTenant.setCloudDomainName(apiTenant.cloud_domain_name); + newTenant.setState(SdnControllerConstant.H3C_SDN_CONTROLLER_TENANT_STATE_ENABLE); + tenantsToSave.add(newTenant); + } else { + // Existing tenant, check if update is needed + boolean needUpdate = false; + if (!Objects.equals(existingTenant.getTenantName(), apiTenant.name)) { + existingTenant.setTenantName(apiTenant.name); + needUpdate = true; + } + if (!Objects.equals(existingTenant.getCloudDomainName(), apiTenant.cloud_domain_name)) { + existingTenant.setCloudDomainName(apiTenant.cloud_domain_name); + needUpdate = true; + } + // Ensure tenants found in API response are marked as enabled + if (!SdnControllerConstant.H3C_SDN_CONTROLLER_TENANT_STATE_ENABLE.equals(existingTenant.getState())) { + existingTenant.setState(SdnControllerConstant.H3C_SDN_CONTROLLER_TENANT_STATE_ENABLE); + needUpdate = true; + } + if (needUpdate) { + tenantsToSave.add(existingTenant); + } + } + } + } + + // Handle tenants that exist in database but not in API (soft delete) + for (H3cSdnControllerTenantVO existingTenant : existingTenants) { + String key = generateTenantKey(existingTenant.getTenantUuid(), existingTenant.getVdsUuid()); + if (!apiTenantKeys.contains(key) && !SdnControllerConstant.H3C_SDN_CONTROLLER_TENANT_STATE_DISABLE.equals(existingTenant.getState())) { + existingTenant.setState(SdnControllerConstant.H3C_SDN_CONTROLLER_TENANT_STATE_DISABLE); + tenantsToSave.add(existingTenant); + } + } + + // Batch save updates + if (!tenantsToSave.isEmpty()) { + dbf.updateCollection(tenantsToSave); + } + + trigger.next(); + } + + private String generateTenantKey(String tenantUuid, String vdsUuid) { + return String.format("%s-%s", tenantUuid != null ? tenantUuid : "", vdsUuid != null ? vdsUuid : ""); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerFactory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerFactory.java new file mode 100644 index 00000000000..6c25dcaddb9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerFactory.java @@ -0,0 +1,31 @@ +package org.zstack.sdnController; + +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.workflow.FlowChain; +import org.zstack.header.network.l3.SdnControllerL3; +import org.zstack.header.network.service.SdnControllerDhcp; +import org.zstack.network.securitygroup.SecurityGroupSdnBackend; +import org.zstack.header.network.sdncontroller.SdnControllerVO; + +public interface SdnControllerFactory { + SdnControllerType getVendorType(); + + SdnControllerVO persistSdnController(SdnControllerVO vo); + + SdnController getSdnController(SdnControllerVO vo); + + default SdnController getSdnController(String l2NetworkUuid) {return null;}; + + SdnControllerL2 getSdnControllerL2(SdnControllerVO vo); + default SdnControllerL2 getSdnControllerL2(String l2NetworkUuid) {return null;}; + + default SdnControllerL3 getSdnControllerL3(SdnControllerVO vo) {return null;}; + + SecurityGroupSdnBackend getSdnControllerSecurityGroup(SdnControllerVO vo); + + + default SdnControllerDhcp getSdnControllerDhcp(SdnControllerVO vo) {return null;}; + default SdnControllerDhcp getSdnControllerDhcp(String l2NetworkUuid) {return null;}; + + default FlowChain getSyncChain() {return FlowChainBuilder.newSimpleFlowChain();}; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerGlobalConfig.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerGlobalConfig.java new file mode 100644 index 00000000000..0b6a081c454 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerGlobalConfig.java @@ -0,0 +1,21 @@ +package org.zstack.sdnController; + +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; +import org.zstack.core.config.GlobalConfigDefinition; +import org.zstack.core.config.GlobalConfigValidation; + +/** + */ +@GlobalConfigDefinition +public class SdnControllerGlobalConfig { + public static final String CATEGORY = "sdnController"; + + @GlobalConfigValidation(numberGreaterThan = 1) + @GlobalConfigDef(defaultValue = "60", type = Long.class, description = "The interval management server sends ping command to sdn controller, in seconds") + public static GlobalConfig PING_INTERVAL = new GlobalConfig(CATEGORY, "ping.interval"); + + @GlobalConfigValidation(numberGreaterThan = 0, numberLessThan = 100) + @GlobalConfigDef(defaultValue = "5", type = Long.class, description = "The max number of management server sends ping commands to sdn controller in parallel") + public static GlobalConfig PING_PARALLELISM_DEGREE = new GlobalConfig(CATEGORY, "ping.parallelismDegree"); +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerL2.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerL2.java new file mode 100644 index 00000000000..502efb5f21f --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerL2.java @@ -0,0 +1,44 @@ +package org.zstack.sdnController; + +import org.zstack.header.core.Completion; +import org.zstack.header.host.HostInventory; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l3.IpRangeInventory; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.header.network.sdncontroller.SdnControllerDeletionMsg; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.sdnController.header.SdnVlanRange; +import org.zstack.sdnController.header.SdnVniRange; + +import javax.persistence.Tuple; +import java.util.ArrayList; +import java.util.List; + +public interface SdnControllerL2 { + void preCreateVxlanNetwork(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion); + void createL2Network(L2NetworkInventory inv, APICreateL2NetworkMsg msg, Completion completion); + void postCreateVxlanNetwork(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion); + + void preAttachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion); + void attachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List clusterUuids, List systemTags, Completion completion); + default void attachL2NetworkToHosts(L2VxlanNetworkInventory vxlan, List hinvs, List systemTags, Completion completion) {completion.success();}; + void postAttachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion); + + void deleteSdnController(SdnControllerDeletionMsg msg, SdnControllerInventory sdn, Completion completion); + void detachL2NetworkFromCluster(L2VxlanNetworkInventory vxlan, List clusterUuids, Completion completion); + void deleteL2Network(L2NetworkInventory inv, Completion completion); + + List getVniRange(SdnControllerInventory controller); + List getVlanRange(SdnControllerInventory controller); + + default List getL2NetworkOfSdnController() { return new ArrayList<>();}; + + default void addVmNics(List nics, Completion completion) {completion.success();}; + default void removeVmNics(List nics, Completion completion) {completion.success();}; + + default void addL3NetworkIpRange(L3NetworkInventory inv, IpRangeInventory ipr, Completion completion) {completion.success();}; + default void deleteL3NetworkIpRange(L3NetworkInventory inv, IpRangeInventory ipr, Completion completion) {completion.success();}; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerLog.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerLog.java new file mode 100644 index 00000000000..1973a0221cb --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerLog.java @@ -0,0 +1,12 @@ +package org.zstack.sdnController; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SdnControllerLog { + String value() default ""; +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerLogAspect.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerLogAspect.java new file mode 100644 index 00000000000..8eb382d76bc --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerLogAspect.java @@ -0,0 +1,80 @@ +package org.zstack.sdnController; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; + +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.sdnController.header.APIAddSdnControllerMsg; +import org.zstack.header.network.sdncontroller.SdnControllerConstant.Processes; +import org.zstack.header.network.sdncontroller.SdnControllerConstant.Operations; +import org.zstack.header.network.sdncontroller.SdnControllerConstant.ResourceTypes; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.lang.reflect.Method; +import java.util.Locale; + +@Aspect +@Component +public class SdnControllerLogAspect { + final CLogger logger = Utils.getLogger(this.getClass()); + + @Pointcut("@annotation(org.zstack.sdnController.SdnControllerLog)") + public void logPointCut() { + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + long beginTime = System.currentTimeMillis(); + Object result = joinPoint.proceed(); + long time = System.currentTimeMillis() - beginTime; + saveLog(joinPoint, time); + return result; + } + + void saveLog(ProceedingJoinPoint joinPoint, long time) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + String methodName = signature.getName(); + String className = joinPoint.getTarget().getClass().getName(); + String parseName = methodName.toUpperCase(Locale.ROOT); + String process = ""; + String operation = ""; + String resourceType = ""; + String name = ""; + for (Processes op : Processes.values()) { + if (parseName.contains(op.toString().toUpperCase(Locale.ROOT))){ + process = op.toString(); + } + } + for (Operations op : Operations.values()) { + if (parseName.contains(op.toString().toUpperCase(Locale.ROOT))){ + operation = op.toString(); + } + } + for (ResourceTypes type : ResourceTypes.values()) { + if (parseName.contains(type.toString().toUpperCase(Locale.ROOT))){ + resourceType = type.toString(); + } + } + Object[] args = joinPoint.getArgs(); + for (Object arg : args) { + if (arg instanceof APIAddSdnControllerMsg) { + name = ((APIAddSdnControllerMsg) arg).getName(); + break; + } + + if (arg instanceof L2VxlanNetworkInventory) { + name = ((L2VxlanNetworkInventory) arg).getName(); + break; + } + } + + SdnControllerLog sdnControllerLog = method.getAnnotation(SdnControllerLog.class); + logger.debug(String.format("sdn controller [%s]'s %s operation [%s-%s] for %s, the execution time is %s ms", className, process, operation, resourceType, name, time)); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerManager.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerManager.java new file mode 100644 index 00000000000..b2a5633bed2 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerManager.java @@ -0,0 +1,15 @@ +package org.zstack.sdnController; + +import org.zstack.header.core.workflow.FlowChain; +import org.zstack.header.network.service.SdnControllerDhcp; +import org.zstack.header.network.sdncontroller.SdnControllerVO; + +public interface SdnControllerManager { + SdnControllerFactory getSdnControllerFactory(String type); + SdnController getSdnController(SdnControllerVO sdnControllerVO); + SdnControllerL2 getSdnControllerL2(SdnControllerVO sdnControllerVO); + + SdnControllerDhcp getSdnControllerDhcp(String l3Uuid); + + FlowChain getSyncChain(SdnControllerVO sdnControllerVO); +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerManagerImpl.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerManagerImpl.java new file mode 100644 index 00000000000..c9e939b63f4 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerManagerImpl.java @@ -0,0 +1,869 @@ +package org.zstack.sdnController; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.header.AbstractService; +import org.zstack.header.core.Completion; +import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.message.Message; +import org.zstack.header.network.NetworkException; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.*; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.SdnControllerL3; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.header.network.service.GetSdnControllerExtensionPoint; +import org.zstack.header.network.service.SdnControllerDhcp; +import org.zstack.header.vm.*; +import org.zstack.network.l2.L2NetworkSystemTags; +import org.zstack.network.l3.L3NetworkHelper; +import org.zstack.network.securitygroup.SecurityGroupGetSdnBackendExtensionPoint; +import org.zstack.network.securitygroup.SecurityGroupManager; +import org.zstack.network.securitygroup.SecurityGroupSdnBackend; +import org.zstack.sdnController.header.*; +import org.zstack.tag.TagManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; + +import static org.zstack.core.Platform.operr; + +public class SdnControllerManagerImpl extends AbstractService implements SdnControllerManager, + L2NetworkCreateExtensionPoint, L2NetworkDeleteExtensionPoint, InstantiateResourceOnAttachingNicExtensionPoint, + PreVmInstantiateResourceExtensionPoint, VmReleaseResourceExtensionPoint, + ReleaseNetworkServiceOnDetachingNicExtensionPoint, SecurityGroupGetSdnBackendExtensionPoint, + AfterAddIpRangeExtensionPoint, IpRangeDeletionExtensionPoint, GetSdnControllerExtensionPoint { + private static final CLogger logger = Utils.getLogger(SdnControllerManagerImpl.class); + private static final Logger log = LoggerFactory.getLogger(SdnControllerManagerImpl.class); + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + private PluginRegistry pluginRgty; + @Autowired + private TagManager tagMgr; + @Autowired + private SecurityGroupManager sgMgr; + @Autowired + private SdnControllerPingTracker pingTracker; + + private Map sdnControllerFactories = Collections.synchronizedMap(new HashMap()); + + @Override + public int getSyncLevel() { + return super.getSyncLevel(); + } + + @Override + public List getAliasIds() { + return super.getAliasIds(); + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof APIAddSdnControllerMsg) { + handle((APIAddSdnControllerMsg) msg); + } else if (msg instanceof SdnControllerMessage) { + handleSdnControllerMessage((SdnControllerMessage) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handleSdnControllerMessage(SdnControllerMessage msg) { + SdnControllerVO vo = dbf.findByUuid(msg.getSdnControllerUuid(), SdnControllerVO.class); + if (vo == null) { + String err = String.format("Cannot find Sdn controller[uuid:%s], it may have been deleted", msg.getSdnControllerUuid()); + bus.replyErrorByMessageType((Message) msg, err); + return; + } + + SdnControllerBase sdnController = new SdnControllerBase(vo); + sdnController.handleMessage(msg); + } + + private void doCreateSdnController(SdnControllerVO vo, APIAddSdnControllerMsg msg, Completion completion) { + SdnControllerFactory factory = getSdnControllerFactory(msg.getVendorType()); + SdnController controller = factory.getSdnController(vo); + + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.setName(String.format("create-sdn-controller-%s", msg.getName())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = String.format("pre-process-for-create-sdn-controller-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + msg.setResourceUuid(vo.getUuid()); + controller.preInitSdnController(msg, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + flow(new Flow() { + String __name__ = String.format("create-sdn-controller-%s-on-db", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + controller.createSdnControllerDb(msg, vo, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.debug(String.format("create sdn controller db error: %s", errorCode.getDetails())); + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + controller.deleteSdnControllerDb(vo); + trigger.rollback(); + } + }); + flow(new Flow() { + String __name__ = String.format("init-sdn-controller-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + controller.initSdnController(msg, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + controller.deleteSdnControllerDb(vo); + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + trigger.rollback(); + } + }); + flow(new NoRollbackFlow() { + String __name__ = String.format("post-process-for-create-sdn-controller--%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + controller.postInitSdnController(vo, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + logger.debug(String.format("successfully create sdn controller")); + pingTracker.track(vo.getUuid()); + completion.success(); + } + }); + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + private void handle(APIAddSdnControllerMsg msg) { + APIAddSdnControllerEvent event = new APIAddSdnControllerEvent(msg.getId()); + + SdnControllerVO vo = new SdnControllerVO(); + vo.setVendorType(msg.getVendorType()); + vo.setVendorVersion(msg.getVendorVersion() == null ? SdnControllerConstant.DEFAULT_VENDOR_VERSION : msg.getVendorVersion()); + if (msg.getResourceUuid() != null) { + vo.setUuid(msg.getResourceUuid()); + } else { + vo.setUuid(Platform.getUuid()); + } + vo.setName(msg.getName()); + vo.setDescription(msg.getDescription()); + vo.setIp(msg.getIp()); + vo.setUsername(msg.getUserName()); + vo.setPassword(msg.getPassword()); + vo.setAccountUuid(msg.getSession().getAccountUuid()); + if (msg.getVendorVersion() != null) { + vo.setVendorVersion(msg.getVendorVersion()); + } else { + vo.setVendorVersion(SdnControllerConstant.DEFAULT_SDN_CONTROLLER_VERSION); + } + vo.setStatus(SdnControllerStatus.Connected); + + doCreateSdnController(vo, msg, new Completion(msg) { + @Override + public void success() { + tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), SdnControllerVO.class.getSimpleName()); + event.setInventory(SdnControllerInventory.valueOf(dbf.findByUuid(vo.getUuid(), SdnControllerVO.class))); + bus.publish(event); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + } + }); + } + + @Override + public void beforeCreateL2Network(APICreateL2NetworkMsg msg) throws NetworkException { + + } + + @Override + public void postCreateL2Network(L2NetworkInventory l2Network, APICreateL2NetworkMsg msg, Completion completion) { + VSwitchType vSwitchType = VSwitchType.valueOf(l2Network.getvSwitchType()); + if (vSwitchType.getSdnControllerType() == null) { + completion.success(); + return; + } + SdnControllerVO sdnControllerVO = getSdnControllerVO(l2Network); + if (sdnControllerVO == null) { + String sdnControllerUuid = null; + List sysTags = msg.getSystemTags(); + if (sysTags == null || sysTags.isEmpty()) { + completion.fail(operr("cannot create sdn l2 network because sdn controller uuid is missing from systemTags in API message")); + return; + } + for (String systag : sysTags) { + if (L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.isMatch(systag)) { + sdnControllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByTag( + systag, L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + } + } + + if (sdnControllerUuid == null) { + completion.fail(operr("cannot create sdn l2 network because sdn controller uuid is missing from API message")); + return; + } + sdnControllerVO = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (sdnControllerVO == null) { + completion.fail(operr("cannot find sdn controller for l2 network[uuid:%s, vswitchType:%s]", + l2Network.getUuid(), l2Network.getvSwitchType())); + return; + } + } + + SdnControllerFactory factory = getSdnControllerFactory(sdnControllerVO.getVendorType()); + SdnControllerL2 controller = factory.getSdnControllerL2(sdnControllerVO); + controller.createL2Network(l2Network, msg, completion); + } + + @Override + public void afterCreateL2Network(L2NetworkInventory l2Network) { + + } + + @Override + public void preDeleteL2Network(L2NetworkInventory inventory) throws L2NetworkException { + + } + + @Override + public void beforeDeleteL2Network(L2NetworkInventory inventory) { + + } + + @Override + public void deleteL2Network(L2NetworkInventory inv, NoErrorCompletion completion) { + VSwitchType vSwitchType = VSwitchType.valueOf(inv.getvSwitchType()); + if (vSwitchType.getSdnControllerType() == null) { + //hardware vxlan will go this path + completion.done(); + return; + } + + /* vswitch type: OvnDpdk will go here */ + SdnControllerFactory factory = getSdnControllerFactory(vSwitchType.getSdnControllerType()); + SdnControllerL2 controllerL2 = factory.getSdnControllerL2(inv.getUuid()); + if (controllerL2 == null) { + logger.warn(String.format("can not found sdn controller for l2 network[uuid:%s, vswitchType:%s]", + inv.getUuid(), inv.getvSwitchType())); + completion.done(); + return; + } + + controllerL2.deleteL2Network(inv, new Completion(completion) { + @Override + public void success() { + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("can not found sdn controller for l2 network[uuid:%s, vswitchType:%s]", + inv.getUuid(), inv.getvSwitchType())); + completion.done(); + } + }); + } + + @Override + public void afterDeleteL2Network(L2NetworkInventory inventory) { + + } + + private void sdnAddVmNic(String sdnControllerUuid, List nics, Completion completion) { + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + SdnControllerFactory factory = getSdnControllerFactory(vo.getVendorType()); + if (factory == null) { + completion.fail(operr("there is no sdn controller factory for sdn controller type:%s", vo.getVendorType())); + return; + } + + SdnControllerL2 controller = factory.getSdnControllerL2(vo); + controller.addVmNics(nics, completion); + } + + private void sdnAddVmNics(Map> nicMaps, Completion completion) { + new While<>(nicMaps.entrySet()).each((e, wcomp) -> { + sdnAddVmNic(e.getKey(), e.getValue(), new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.addError(errorCode); + wcomp.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + completion.success(); + } else { + completion.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + + private void removeOvnLogicalPorts(String controllerUuid, List nics, Completion completion) { + SdnControllerVO vo = dbf.findByUuid(controllerUuid, SdnControllerVO.class); + SdnControllerFactory factory = getSdnControllerFactory(vo.getVendorType()); + if (factory == null) { + completion.fail(operr("there is no sdn controller factory for sdn controller type:%s", vo.getVendorType())); + return; + } + + SdnControllerL2 controller = factory.getSdnControllerL2(vo); + controller.removeVmNics(nics, completion); + } + + private void removeLogicalPort(Map> nicMaps, Completion completion) { + new While<>(nicMaps.entrySet()).each((e, wcomp) -> { + removeOvnLogicalPorts(e.getKey(), e.getValue(), new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.addError(errorCode); + wcomp.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + completion.success(); + } else { + completion.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + + @Override + public void releaseVmResource(VmInstanceSpec spec, Completion completion) { + if (VmInstanceConstant.VmOperation.DetachNic != spec.getCurrentVmOperation() && + VmInstanceConstant.VmOperation.Destroy != spec.getCurrentVmOperation()) { + completion.success(); + return; + } + + if (spec.getL3Networks() == null || spec.getL3Networks().isEmpty()) { + completion.success(); + return; + } + + // we run into this situation when VM nics are all detached and the + // VM is being rebooted + if (spec.getDestNics().isEmpty()) { + completion.success(); + return; + } + + Map> nicMaps = new HashMap<>(); + for (VmNicInventory nic : spec.getDestNics()) { + L3NetworkVO l3Vo = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + if (l3Vo == null) { + continue; + } + + L2NetworkVO l2VO = dbf.findByUuid(l3Vo.getL2NetworkUuid(), L2NetworkVO.class); + if (l2VO == null) { + continue; + } + + VSwitchType vSwitchType = VSwitchType.valueOf(l2VO.getvSwitchType()); + if (vSwitchType.getSdnControllerType() == null) { + continue; + } + + String controllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2VO.getUuid(), L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + if (controllerUuid == null) { + completion.fail(operr("sdn l2 network[uuid:%s] is not attached controller", l2VO.getUuid())); + return; + } + + nicMaps.computeIfAbsent(controllerUuid, k -> new ArrayList<>()).add(nic); + } + + if (nicMaps.isEmpty()) { + completion.success(); + return; + } + + removeLogicalPort(nicMaps, completion); + } + + @Override + public void instantiateResourceOnAttachingNic(VmInstanceSpec spec, L3NetworkInventory l3, Completion completion) { + L2NetworkVO l2NetworkVO = dbf.findByUuid(l3.getL2NetworkUuid(), L2NetworkVO.class); + VSwitchType vSwitchType = VSwitchType.valueOf(l2NetworkVO.getvSwitchType()); + if (vSwitchType.getSdnControllerType() == null) { + completion.success(); + return; + } + + String controllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2NetworkVO.getUuid(), L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + if (controllerUuid == null) { + completion.fail(operr("sdn l2 network[uuid:%s] is not attached controller", l2NetworkVO.getUuid())); + return; + } + + Map> nicMaps = new HashMap<>(); + List nics = new ArrayList<>(); + nics.add(spec.getDestNics().get(0)); + nicMaps.put(controllerUuid, nics); + sdnAddVmNics(nicMaps, completion); + } + + @Override + public void releaseResourceOnAttachingNic(VmInstanceSpec spec, L3NetworkInventory l3, NoErrorCompletion completion) { + L2NetworkVO l2NetworkVO = dbf.findByUuid(l3.getL2NetworkUuid(), L2NetworkVO.class); + VSwitchType vSwitchType = VSwitchType.valueOf(l2NetworkVO.getvSwitchType()); + if (vSwitchType.getSdnControllerType() == null) { + completion.done(); + return; + } + + String controllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2NetworkVO.getUuid(), L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + if (controllerUuid == null) { + logger.warn(String.format("sdn l2 network[uuid:%s] is not attached controller", l2NetworkVO.getUuid())); + completion.done(); + return; + } + + Map> nicMaps = new HashMap<>(); + List nics = new ArrayList<>(); + nics.add(spec.getDestNics().get(0)); + nicMaps.put(controllerUuid, nics); + + removeLogicalPort(nicMaps, new Completion(completion) { + @Override + public void success() { + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.info(String.format("failed to remove logical port for vm[uuid:%s] nic[internalName:%s], because: %s", + spec.getVmInventory().getUuid(), spec.getDestNics().get(0).getInternalName(), errorCode.getDetails())); + completion.done(); + } + }); + } + + @Override + public void releaseResourceOnDetachingNic(VmInstanceSpec spec, VmNicInventory nic, NoErrorCompletion completion) { + L3NetworkVO l3Vo = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + L2NetworkVO l2NetworkVO = dbf.findByUuid(l3Vo.getL2NetworkUuid(), L2NetworkVO.class); + VSwitchType vSwitchType = VSwitchType.valueOf(l2NetworkVO.getvSwitchType()); + if (vSwitchType.getSdnControllerType() == null) { + completion.done(); + return; + } + + String controllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2NetworkVO.getUuid(), L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + if (controllerUuid == null) { + logger.warn(String.format("sdn l2 network[uuid:%s] is not attached controller", l2NetworkVO.getUuid())); + completion.done(); + return; + } + + Map> nicMaps = new HashMap<>(); + List nics = new ArrayList<>(); + nics.add(spec.getDestNics().get(0)); + nicMaps.put(controllerUuid, nics); + + removeLogicalPort(nicMaps, new Completion(completion) { + @Override + public void success() { + completion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.info(String.format("failed to remove logical port for vm[uuid:%s] nic[internalName:%s], because: %s", + spec.getVmInventory().getUuid(), spec.getDestNics().get(0).getInternalName(), errorCode.getDetails())); + completion.done(); + } + }); + } + + @Override + public void preBeforeInstantiateVmResource(VmInstanceSpec spec) throws VmInstantiateResourceException { + + } + + @Override + public void preInstantiateVmResource(VmInstanceSpec spec, Completion completion) { + if (spec.getL3Networks() == null || spec.getL3Networks().isEmpty()) { + completion.success(); + return; + } + + // we run into this situation when VM nics are all detached and the + // VM is being rebooted + if (spec.getDestNics().isEmpty()) { + completion.success(); + return; + } + + Map> nicMaps = new HashMap<>(); + for (VmNicInventory nic : spec.getDestNics()) { + L3NetworkVO l3Vo = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + if (l3Vo == null) { + continue; + } + + L2NetworkVO l2VO = dbf.findByUuid(l3Vo.getL2NetworkUuid(), L2NetworkVO.class); + if (l2VO == null) { + continue; + } + + VSwitchType vSwitchType = VSwitchType.valueOf(l2VO.getvSwitchType()); + if (vSwitchType.getSdnControllerType() ==null) { + continue; + } + + String controllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2VO.getUuid(), L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + if (controllerUuid == null) { + completion.fail(operr("sdn l2 network[uuid:%s] is not attached controller", l2VO.getUuid())); + return; + } + + nicMaps.computeIfAbsent(controllerUuid, k -> new ArrayList<>()).add(nic); + } + + if (nicMaps.isEmpty()) { + completion.success(); + return; + } + + sdnAddVmNics(nicMaps, completion); + } + + @Override + public void preReleaseVmResource(VmInstanceSpec spec, Completion completion) { + if (spec.getL3Networks() == null || spec.getL3Networks().isEmpty()) { + completion.success(); + return; + } + + // we run into this situation when VM nics are all detached and the + // VM is being rebooted + if (spec.getDestNics().isEmpty()) { + completion.success(); + return; + } + + Map> nicMaps = new HashMap<>(); + for (VmNicInventory nic : spec.getDestNics()) { + L3NetworkVO l3Vo = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + if (l3Vo == null) { + continue; + } + + L2NetworkVO l2VO = dbf.findByUuid(l3Vo.getL2NetworkUuid(), L2NetworkVO.class); + if (l2VO == null) { + continue; + } + + VSwitchType vSwitchType = VSwitchType.valueOf(l2VO.getvSwitchType()); + if (vSwitchType.getSdnControllerType() ==null) { + continue; + } + + String controllerUuid = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.getTokenByResourceUuid( + l2VO.getUuid(), L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN); + if (controllerUuid == null) { + completion.fail(operr("sdn l2 network[uuid:%s] is not attached controller", l2VO.getUuid())); + return; + } + + nicMaps.computeIfAbsent(controllerUuid, k -> new ArrayList<>()).add(nic); + } + + if (nicMaps.isEmpty()) { + completion.success(); + return; + } + + removeLogicalPort(nicMaps, completion); + } + + @Override + public SdnControllerFactory getSdnControllerFactory(String type) { + SdnControllerFactory factory = sdnControllerFactories.get(type); + if (factory == null) { + throw new CloudRuntimeException(String.format("Cannot find sdn controller for type(%s)", type)); + } + + return factory; + } + + @Override + public SdnController getSdnController(SdnControllerVO sdnControllerVO) { + SdnControllerFactory factory = getSdnControllerFactory(sdnControllerVO.getVendorType()); + return factory.getSdnController(sdnControllerVO); + } + + @Override + public SdnControllerL2 getSdnControllerL2(SdnControllerVO sdnControllerVO) { + SdnControllerFactory factory = getSdnControllerFactory(sdnControllerVO.getVendorType()); + return factory.getSdnControllerL2(sdnControllerVO); + } + + @Override + public SecurityGroupSdnBackend getSecurityGroupSdnBackend(String sdnControllerUuid) { + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (vo == null) { + return null; + } + SdnControllerFactory factory = getSdnControllerFactory(vo.getVendorType()); + return factory.getSdnControllerSecurityGroup(vo); + } + + @Override + public SdnControllerDhcp getSdnControllerDhcp(String l3Uuid) { + String controllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(l3Uuid); + if (controllerUuid == null) { + return null; + } + + SdnControllerVO vo = dbf.findByUuid(controllerUuid, SdnControllerVO.class); + if (vo == null) { + throw new CloudRuntimeException(String.format("can not find sdn controller[uuid:%s] for l3 network[uuid:%s]", + controllerUuid, l3Uuid)); + } + SdnControllerFactory factory = getSdnControllerFactory(vo.getVendorType()); + return factory.getSdnControllerDhcp(vo); + } + + @Override + public SdnControllerL3 getSdnControllerL3(String l2Uuid) { + String controllerUuid = L3NetworkHelper.getSdnControllerUuidFromL2Uuid(l2Uuid); + if (controllerUuid == null) { + return null; + } + + SdnControllerVO vo = dbf.findByUuid(controllerUuid, SdnControllerVO.class); + if (vo == null) { + throw new CloudRuntimeException(String.format("can not find sdn controller[uuid:%s] for l2 network[uuid:%s]", + controllerUuid, l2Uuid)); + } + SdnControllerFactory factory = getSdnControllerFactory(vo.getVendorType()); + return factory.getSdnControllerL3(vo); + } + + @Override + public FlowChain getSyncChain(SdnControllerVO sdnControllerVO) { + SdnControllerFactory f = getSdnControllerFactory(sdnControllerVO.getVendorType()); + return f.getSyncChain(); + } + + @Override + public String getId() { + return bus.makeLocalServiceId(SdnControllerConstant.SERVICE_ID); + } + + @Override + public boolean start() { + for (SdnControllerFactory f : pluginRgty.getExtensionList(SdnControllerFactory.class)) { + SdnControllerFactory old = sdnControllerFactories.get(f.getVendorType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate SdnControllerFactory[%s, %s] for type[%s]", + f.getClass().getName(), old.getClass().getName(), f.getVendorType())); + } + sdnControllerFactories.put(f.getVendorType().toString(), f); + } + + return true; + } + + @Override + public boolean stop() { + return true; + } + + + @Override + public void afterAddIpRange(IpRangeInventory ipr, List systemTags) { + L3NetworkVO l3vo = dbf.findByUuid(ipr.getL3NetworkUuid(), L3NetworkVO.class); + if (l3vo == null) { + logger.warn(String.format( + "l3 network[uuid:%s] not found when adding ipRange[uuid:%s], skip syncing to sdn controller", + ipr.getL3NetworkUuid(), ipr.getUuid())); + return; + } + L3NetworkInventory l3Network = L3NetworkInventory.valueOf(l3vo); + SdnControllerVO sdnControllerVO = getSdnControllerVO(l3Network); + if (sdnControllerVO == null) { + return; + } + SdnControllerFactory factory = getSdnControllerFactory(sdnControllerVO.getVendorType()); + SdnControllerL2 controller = factory.getSdnControllerL2(sdnControllerVO); + controller.addL3NetworkIpRange(l3Network, ipr, new Completion(null) { + @Override + public void success() { + logger.debug(String.format("success to create l3 network[uuid:%s] ipRange on sdn controller[uuid:%s]", + l3Network.getUuid(), sdnControllerVO.getUuid())); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("failed to create l3 network[uuid:%s] ipRange on sdn controller[uuid:%s], because: %s", + l3Network.getUuid(), sdnControllerVO.getUuid(), errorCode.getDetails())); + } + }); + } + + @Override + public void preDeleteIpRange(IpRangeInventory ipRange) { + } + + @Override + public void beforeDeleteIpRange(IpRangeInventory ipRange) { + } + + @Override + public void afterDeleteIpRange(IpRangeInventory ipRange) { + L3NetworkVO l3vo = dbf.findByUuid(ipRange.getL3NetworkUuid(), L3NetworkVO.class); + if (l3vo == null) { + logger.warn(String.format("l3 network[uuid:%s] not found when deleting ipRange[uuid:%s], skip syncing to sdn controller", + ipRange.getL3NetworkUuid(), ipRange.getUuid())); + return; + } + L3NetworkInventory l3Network = L3NetworkInventory.valueOf(l3vo); + SdnControllerVO sdnControllerVO = getSdnControllerVO(l3Network); + if (sdnControllerVO == null) { + return; + } + SdnControllerFactory factory = getSdnControllerFactory(sdnControllerVO.getVendorType()); + SdnControllerL2 controller = factory.getSdnControllerL2(sdnControllerVO); + controller.deleteL3NetworkIpRange(l3Network, ipRange, new Completion(null) { + @Override + public void success() { + logger.debug(String.format("success to delete l3 network[uuid:%s] ipRange on sdn controller[uuid:%s]", + l3Network.getUuid(), sdnControllerVO.getUuid())); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("failed to delete l3 network[uuid:%s] ipRange on sdn controller[uuid:%s], because: %s", + l3Network.getUuid(), sdnControllerVO.getUuid(), errorCode.getDetails())); + } + }); + } + + @Override + public void failedToDeleteIpRange(IpRangeInventory ipRange, ErrorCode errorCode) { + } + + private SdnControllerVO getSdnControllerVO(L2NetworkInventory l2Network) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL2Uuid(l2Network.getUuid()); + if (sdnControllerUuid == null) { + return null; + } + return dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + } + private SdnControllerVO getSdnControllerVO(L3NetworkInventory l3Network) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(l3Network.getUuid()); + if (sdnControllerUuid == null) { + return null; + } + return dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingMsg.java new file mode 100644 index 00000000000..22436283c17 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingMsg.java @@ -0,0 +1,20 @@ +package org.zstack.sdnController; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; + +/** + * Created by shixin.ruan on 06/26/2025. + */ +public class SdnControllerPingMsg extends NeedReplyMessage implements SdnControllerMessage { + private String sdnControllerUuid; + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingReply.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingReply.java new file mode 100644 index 00000000000..6046d785fcb --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingReply.java @@ -0,0 +1,18 @@ +package org.zstack.sdnController; + +import org.zstack.header.message.MessageReply; + +/** + * Created by shixin.ruan on 06/26/2025. + */ +public class SdnControllerPingReply extends MessageReply { + private boolean doReconnect = false; + + public boolean getDoReconnect() { + return doReconnect; + } + + public void setDoReconnect(boolean doReconnect) { + this.doReconnect = doReconnect; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingTracker.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingTracker.java new file mode 100644 index 00000000000..2deeb4602aa --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerPingTracker.java @@ -0,0 +1,160 @@ +package org.zstack.sdnController; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.ResourceDestinationMaker; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.thread.AsyncThread; +import org.zstack.core.tracker.PingTracker; +import org.zstack.header.core.Completion; +import org.zstack.header.managementnode.ManagementNodeChangeListener; +import org.zstack.header.managementnode.ManagementNodeInventory; +import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.header.message.MessageReply; +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.network.l2.SdnControllerDeleteExtensionPoint; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerStatus; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO_; +import org.zstack.sdnController.header.*; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; + +import java.util.List; + +/** + * Created by shixin on 06/26/2025. + */ +public class SdnControllerPingTracker extends PingTracker implements + ManagementNodeChangeListener, ManagementNodeReadyExtensionPoint, SdnControllerDeleteExtensionPoint { + private final static CLogger logger = Utils.getLogger(SdnControllerPingTracker.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private ResourceDestinationMaker destinationMaker; + @Autowired + protected PluginRegistry pluginRgty; + @Autowired + protected SdnControllerManager sdnMgr; + + public String getResourceName() { + return "sdn controller"; + } + + // sdn controller will only ping when it's connected or disconnected, + // if ping failed, it will send ReconnectSdnControllerMsg, + @Override + public NeedReplyMessage getPingMessage(String resUuid) { + SdnControllerVO vo = dbf.findByUuid(resUuid, SdnControllerVO.class); + if (vo.getStatus() == SdnControllerStatus.Connecting) { + return null; + } + + SdnControllerPingMsg msg = new SdnControllerPingMsg(); + msg.setSdnControllerUuid(resUuid); + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, resUuid); + return msg; + } + + @Override + public int getPingInterval() { + return SdnControllerGlobalConfig.PING_INTERVAL.value(Integer.class); + } + + @Override + public int getParallelismDegree() { + return SdnControllerGlobalConfig.PING_PARALLELISM_DEGREE.value(Integer.class); + } + + @Override + public void handleReply(final String resourceUuid, MessageReply reply) { + SdnControllerVO vo = dbf.findByUuid(resourceUuid, SdnControllerVO.class); + if (vo == null) { + logger.warn(String.format("SDN controller[uuid:%s] has been deleted, skip ping handling", resourceUuid)); + return; + } + + + if (!reply.isSuccess()) { + logger.warn(String.format("[SDN Ping Tracker]: unable to ping the sdn controller[uuid: %s], %s", resourceUuid, reply.getError())); + new SdnControllerBase(vo).changeSdnControllerStatus(SdnControllerStatus.Disconnected); + return; + } + + SdnControllerStatus oldStatus = vo.getStatus(); + new SdnControllerBase(vo).changeSdnControllerStatus(SdnControllerStatus.Connected); + if (oldStatus == SdnControllerStatus.Disconnected) { + ReconnectSdnControllerMsg msg = new ReconnectSdnControllerMsg(); + msg.setControllerUuid(resourceUuid); + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, resourceUuid); + bus.send(msg); + } + } + + private void trackOurs() { + List sdnControllerUuids = Q.New(SdnControllerVO.class) + .select(SdnControllerVO_.uuid).listValues(); + List toTrack = CollectionUtils.transformToList(sdnControllerUuids, new Function() { + @Override + public String call(String arg) { + return destinationMaker.isManagedByUs(arg) ? arg : null; + } + }); + + untrackAll(); + track(toTrack); + } + + @Override + public void nodeJoin(ManagementNodeInventory inv) { + trackOurs(); + } + + @Override + public void nodeLeft(ManagementNodeInventory inv) { + trackOurs(); + } + + @Override + public void iAmDead(ManagementNodeInventory inv) { + + } + + @Override + public void iJoin(ManagementNodeInventory inv) { + } + + @Override + protected void startHook() { + SdnControllerGlobalConfig.PING_INTERVAL.installUpdateExtension(new GlobalConfigUpdateExtensionPoint() { + @Override + public void updateGlobalConfig(GlobalConfig oldConfig, GlobalConfig newConfig) { + pingIntervalChanged(); + } + }); + } + + @Override + @AsyncThread + public void managementNodeReady() { + trackOurs(); + } + + @Override + protected void trackHook(String resourceUuid) { + super.trackHook(resourceUuid); + } + + @Override + public void deleteNetworkServiceOfSdnController(String sdnControllerUuid, Completion completion) { + super.untrack(sdnControllerUuid); + completion.success(); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerReply.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerReply.java new file mode 100644 index 00000000000..9caf040fd75 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerReply.java @@ -0,0 +1,7 @@ +package org.zstack.sdnController; + +import org.zstack.header.message.MessageReply; + +public class SdnControllerReply extends MessageReply { + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerSystemTags.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerSystemTags.java new file mode 100644 index 00000000000..1ced576c095 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerSystemTags.java @@ -0,0 +1,18 @@ +package org.zstack.sdnController; + +import org.zstack.header.tag.TagDefinition; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.tag.PatternedSystemTag; + +@TagDefinition +public class SdnControllerSystemTags { + public static String START_VNI_TOKEN = "startVni"; + public static String END_VNI_TOKEN = "endVni"; + public static PatternedSystemTag VNI_RANGE = new PatternedSystemTag(String.format("startVni::{%s}::endVni::{%s}", + START_VNI_TOKEN, END_VNI_TOKEN), SdnControllerVO.class); + + public static String START_VLAN_TOKEN = "startVlan"; + public static String END_VLAN_TOKEN = "endVlan"; + public static PatternedSystemTag VLAN_RANGE = new PatternedSystemTag(String.format("startVlan::{%s}::endVlan::{%s}", + START_VLAN_TOKEN, END_VLAN_TOKEN), SdnControllerVO.class); +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerType.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerType.java new file mode 100644 index 00000000000..d313464ae3c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/SdnControllerType.java @@ -0,0 +1,69 @@ +package org.zstack.sdnController; + +import java.util.*; + +public class SdnControllerType { + private static Map types = Collections.synchronizedMap(new HashMap()); + private final String typeName; + private boolean exposed = true; + + public SdnControllerType(String typeName) { + this.typeName = typeName; + types.put(typeName, this); + } + + public SdnControllerType(String typeName, boolean exposed) { + this(typeName); + this.exposed = exposed; + } + + public static boolean hasType(String type) { + return types.keySet().contains(type); + } + + public static SdnControllerType valueOf(String typeName) { + SdnControllerType type = types.get(typeName); + if (type == null) { + throw new IllegalArgumentException("SdnControllerType type: " + typeName + " was not registered by any SdnControllerFactory"); + } + return type; + } + + public boolean isExposed() { + return exposed; + } + + public void setExposed(boolean exposed) { + this.exposed = exposed; + } + + @Override + public String toString() { + return typeName; + } + + @Override + public boolean equals(Object t) { + if (t == null || !(t instanceof SdnControllerType)) { + return false; + } + + SdnControllerType type = (SdnControllerType) t; + return type.toString().equals(typeName); + } + + @Override + public int hashCode() { + return typeName.hashCode(); + } + + public static Set getAllTypeNames() { + HashSet exposedTypes = new HashSet(); + for (SdnControllerType type : types.values()) { + if (type.exposed) { + exposedTypes.add(type.toString()); + } + } + return exposedTypes; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java new file mode 100644 index 00000000000..8583a8b07ee --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcApiInterceptor.java @@ -0,0 +1,313 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; +import org.zstack.header.message.APIMessage; +import org.zstack.header.network.l2.APIAttachL2NetworkToClusterMsg; +import org.zstack.header.network.l2.APIDetachL2NetworkFromClusterMsg; +import org.zstack.header.network.l3.*; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.network.l2.L2NetworkSystemTags; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.APICreateL2VxlanNetworkMsg; +import org.zstack.network.l2.vxlan.vxlanNetwork.APIDeleteVxlanL2Network; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVniRangeMsg; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolVO; +import org.zstack.network.l3.L3NetworkHelper; +import org.zstack.sdnController.SdnControllerL2; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.sdnController.header.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.List; + +import static org.zstack.core.Platform.argerr; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +public class H3cVcfcApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { + private static final CLogger logger = Utils.getLogger(H3cVcfcApiInterceptor.class); + + @Autowired + protected DatabaseFacade dbf; + @Autowired + protected CloudBus bus; + @Autowired + SdnControllerManager sdnControllerManager; + + private void setServiceId(APIMessage msg) { + if (msg instanceof SdnControllerMessage) { + SdnControllerMessage smsg = (SdnControllerMessage) msg; + bus.makeTargetServiceIdByResourceUuid(msg, SdnControllerConstant.SERVICE_ID, smsg.getSdnControllerUuid()); + } + } + + public List getMessageClassToIntercept() { + List ret = new ArrayList<>(); + ret.add(APIAddSdnControllerMsg.class); + ret.add(APICreateL2HardwareVxlanNetworkPoolMsg.class); + ret.add(APICreateVniRangeMsg.class); + ret.add(APICreateL2VxlanNetworkMsg.class); + ret.add(APICreateL2HardwareVxlanNetworkMsg.class); + ret.add(APIAttachL2NetworkToClusterMsg.class); + ret.add(APIDetachL2NetworkFromClusterMsg.class); + ret.add(APIDeleteVxlanL2Network.class); + ret.add(APIRemoveSdnControllerMsg.class); + ret.add(APICreateL3NetworkMsg.class); + ret.add(APIAddIpRangeMsg.class); + ret.add(APIAddIpRangeByNetworkCidrMsg.class); + ret.add(APIAddIpv6RangeMsg.class); + ret.add(APIAddIpv6RangeByNetworkCidrMsg.class); + return ret; + } + + public InterceptorPosition getPosition() { + return InterceptorPosition.END; + } + + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIAddSdnControllerMsg) { + validate((APIAddSdnControllerMsg) msg); + } else if (msg instanceof APICreateL2HardwareVxlanNetworkPoolMsg){ + validate((APICreateL2HardwareVxlanNetworkPoolMsg)msg); + } else if (msg instanceof APICreateVniRangeMsg){ + validate((APICreateVniRangeMsg)msg); + } else if (msg instanceof APICreateL2VxlanNetworkMsg){ + validate((APICreateL2VxlanNetworkMsg)msg); + } else if (msg instanceof APICreateL2HardwareVxlanNetworkMsg) { + validate((APICreateL2HardwareVxlanNetworkMsg)msg); + } else if (msg instanceof APIAttachL2NetworkToClusterMsg) { + validate((APIAttachL2NetworkToClusterMsg) msg); + } else if (msg instanceof APIDetachL2NetworkFromClusterMsg) { + validate((APIDetachL2NetworkFromClusterMsg) msg); + } else if (msg instanceof APIDeleteVxlanL2Network) { + validate((APIDeleteVxlanL2Network) msg); + } else if (msg instanceof APIRemoveSdnControllerMsg) { + validate((APIRemoveSdnControllerMsg) msg); + } else if (msg instanceof APICreateL3NetworkMsg) { + validate((APICreateL3NetworkMsg) msg); + } else if (msg instanceof APIAddIpRangeMsg) { + validate((APIAddIpRangeMsg) msg); + } else if (msg instanceof APIAddIpRangeByNetworkCidrMsg) { + validate((APIAddIpRangeByNetworkCidrMsg) msg); + } else if (msg instanceof APIAddIpv6RangeMsg) { + validate((APIAddIpv6RangeMsg) msg); + } else if (msg instanceof APIAddIpv6RangeByNetworkCidrMsg) { + validate((APIAddIpv6RangeByNetworkCidrMsg) msg); + } + setServiceId(msg); + + return msg; + } + + public static boolean isOverlappedVniRange(Integer startVni1, Integer endVni1, Integer startVni2, Integer endVni2) { + if (startVni2 <= startVni1 && endVni1 <= endVni2) { + return true; + } + return false; + } + + private void validate(APICreateVniRangeMsg msg) { + VxlanNetworkPoolVO pool = dbf.findByUuid(msg.getL2NetworkUuid(), VxlanNetworkPoolVO.class); + if ( pool == null ) { + throw new ApiMessageInterceptionException(argerr("Could not create VNI range because the specified L2 network [uuid:%s] is not a VXLAN network pool", msg.getL2NetworkUuid())); + } + + HardwareL2VxlanNetworkPoolVO poolVO = dbf.findByUuid(msg.getL2NetworkUuid(), HardwareL2VxlanNetworkPoolVO.class); + if (poolVO == null) { + return; + } + + SdnControllerVO vo = dbf.findByUuid(poolVO.getSdnControllerUuid(), SdnControllerVO.class); + if (!vo.getVendorType().equals(SdnControllerConstant.H3C_VCFC_CONTROLLER)) { + return; + } + + // user's vni must <= 4094 + if (msg.getStartVni() > 4094 || msg.getEndVni() > 4094) { + throw new ApiMessageInterceptionException(argerr("Could not create VNI range [%s-%s] because H3C controllers use VNI as VLAN ID and the range must be within 1-4094", msg.getStartVni(), msg.getEndVni())); + } + + SdnControllerL2 sdnController = sdnControllerManager.getSdnControllerL2(vo); + SdnVniRange userVniRange = new SdnVniRange(); + userVniRange.startVni = msg.getStartVni(); + userVniRange.endVni = msg.getEndVni(); + + // user's vniRange must respectively covered by a sdn's vniRange + List legalList = sdnController.getVniRange(SdnControllerInventory.valueOf(vo)); + for (SdnVniRange legalRange : legalList) { + if (isOverlappedVniRange(userVniRange.startVni, userVniRange.endVni, legalRange.startVni, legalRange.endVni)) { + return; + } + } + throw new ApiMessageInterceptionException(argerr("Could not create VNI range [%s-%s] because it is not covered by any of the SDN controller's configured VNI ranges", userVniRange.startVni, userVniRange.endVni)); + } + + private void validate(APIAddIpv6RangeMsg msg) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(msg.getL3NetworkUuid()); + if (sdnControllerUuid == null) { + return; + } + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (vo == null) { + return; + } + if (!vo.getVendorType().equals(SdnControllerConstant.H3C_VCFC_CONTROLLER)) { + return; + } + if (vo.getStatus() != SdnControllerStatus.Connected) { + throw new ApiMessageInterceptionException(argerr("Could not add IPv6 range because the SDN controller [uuid:%s] is not connected. Current status: %s", + sdnControllerUuid, vo.getStatus())); + } + } + + private void validate(APIAddIpv6RangeByNetworkCidrMsg msg) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(msg.getL3NetworkUuid()); + if (sdnControllerUuid == null) { + return; + } + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (vo == null) { + return; + } + if (!vo.getVendorType().equals(SdnControllerConstant.H3C_VCFC_CONTROLLER)) { + return; + } + if (vo.getStatus() != SdnControllerStatus.Connected) { + throw new ApiMessageInterceptionException(argerr("Could not add IPv6 range by network CIDR because the SDN controller [uuid:%s] is not connected. Current status: %s", + sdnControllerUuid, vo.getStatus())); + } + } + + private void validate(APIAddIpRangeMsg msg) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(msg.getL3NetworkUuid()); + if (sdnControllerUuid == null) { + return; + } + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (vo == null) { + return; + } + if (!vo.getVendorType().equals(SdnControllerConstant.H3C_VCFC_CONTROLLER)) { + return; + } + if (vo.getStatus() != SdnControllerStatus.Connected) { + throw new ApiMessageInterceptionException(argerr("Could not add IP range because the SDN controller [uuid:%s] is not connected. Current status: %s", + sdnControllerUuid, vo.getStatus())); + } + } + + private void validate(APIAddIpRangeByNetworkCidrMsg msg) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(msg.getL3NetworkUuid()); + if (sdnControllerUuid == null) { + return; + } + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (vo == null) { + return; + } + if (!vo.getVendorType().equals(SdnControllerConstant.H3C_VCFC_CONTROLLER)) { + return; + } + if (vo.getStatus() != SdnControllerStatus.Connected) { + throw new ApiMessageInterceptionException(argerr("Could not add IP range by network CIDR because the SDN controller [uuid:%s] is not connected. Current status: %s", + sdnControllerUuid, vo.getStatus())); + } + } + + private void validate(APICreateL3NetworkMsg msg) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL2Uuid(msg.getL2NetworkUuid()); + if (sdnControllerUuid == null) { + return; + } + SdnControllerVO vo = dbf.findByUuid(sdnControllerUuid, SdnControllerVO.class); + if (SdnControllerConstant.H3C_VCFC_CONTROLLER.equals(vo.getVendorType()) && + SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(vo.getVendorVersion()) && + L3NetworkCategory.Public.toString().equals(msg.getCategory())) { + throw new ApiMessageInterceptionException(argerr("can not create l3 network" + + "because H3C VCFC V2 SDN controller does not support l3[type:%s, category:%s]", msg.getType(), msg.getCategory())); + } + } + + private void validate(APIRemoveSdnControllerMsg msg) { + } + + private void validate(APIDeleteVxlanL2Network msg) { + } + + private void validate(APIDetachL2NetworkFromClusterMsg msg) { + } + + private void validate(APICreateL2HardwareVxlanNetworkMsg msg) { + HardwareL2VxlanNetworkPoolVO poolVO = dbf.findByUuid(msg.getPoolUuid(), HardwareL2VxlanNetworkPoolVO.class); + if (poolVO == null) { + return; + } + + SdnControllerVO sdnControllerVO = dbf.findByUuid(poolVO.getSdnControllerUuid(), SdnControllerVO.class); + if (sdnControllerVO != null + && SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(sdnControllerVO.getVendorVersion())) { + boolean tenantExist = msg.getH3cTenantUuid() != null && + Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.uuid, msg.getH3cTenantUuid()) + .isExists(); + if (!tenantExist) { + throw new ApiMessageInterceptionException(argerr( + "Could not create hardware VXLAN network because tenant UUID is a mandatory parameter for the H3C VCFC V2 controller")); + } + } + + boolean hasSdnControllerTag = msg.getSystemTags() != null && + msg.getSystemTags().stream() + .anyMatch(L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID::isMatch); + + if (!hasSdnControllerTag && poolVO.getSdnControllerUuid() != null) { + if (msg.getSystemTags() == null) { + msg.setSystemTags(new ArrayList<>()); + } + String tag = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.instantiateTag( + map(e(L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN, poolVO.getSdnControllerUuid())) + ); + msg.getSystemTags().add(tag); + } + } + + private void validate(APICreateL2HardwareVxlanNetworkPoolMsg msg) { + } + + private void validate(APICreateL2VxlanNetworkMsg msg) { + } + + private void validate(APIAttachL2NetworkToClusterMsg msg) { + } + + private boolean validateH3cController(APIAddSdnControllerMsg msg) { + if (msg.getSystemTags() == null || msg.getSystemTags().isEmpty()) { + return false; + } + + boolean vds = false; + for (String tag : msg.getSystemTags()) { + if (H3cVcfcSdnControllerSystemTags.H3C_VDS_UUID.isMatch(tag)){ + vds = true; + } + } + return vds; + } + + private void validate(APIAddSdnControllerMsg msg) { + if (!msg.getVendorType().equals(SdnControllerConstant.H3C_VCFC_CONTROLLER)) { + return; + } + if (!validateH3cController(msg) && msg.getVendorVersion().equals(SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V1)) { + throw new ApiMessageInterceptionException(argerr("Could not add H3C VCFC controller because VDS UUID system tag is required for H3C VCFC V1 controllers")); + } + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcCommands.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcCommands.java new file mode 100644 index 00000000000..604bb4422ac --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcCommands.java @@ -0,0 +1,111 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.zstack.utils.gson.JSONObjectUtil; + +import java.util.ArrayList; +import java.util.List; + +public class H3cVcfcCommands { + public static final String H3C_VCFC_GET_TOKEN = "/sdn/v2.0/auth"; + public static final String H3C_VCFC_L2_NETWORKS = "/vds/1.0/networks"; + public static final String H3C_VCFC_VNI_RANGES = "/nem/v1.0/vlan_domains"; + public static final String H3C_VCFC_TENANTS = "/tenant/v1.0/tenants"; + public static final String H3C_VCFC_TEAM_LEADERIP = "/sdn/v2.0/team/leaderip"; + + public static class H3cCmd { + public String toString() { + return JSONObjectUtil.toJsonString(this); + } + } + + public static class H3cRsp { + } + + public static class LoginCmd { + public String user; + public String password; + public String domain; + } + + public static class GetH3cTokenCmd extends H3cCmd { + public LoginCmd login; + } + + public static class LoginReply { + public String token; + public String userName; + public String domainName; + } + + public static class LoginRsp extends H3cRsp { + public LoginReply record; + } + + public static class NetworkCmd { + String id; + String name; + String tenant_id; + Boolean distributed; + String network_type; + String original_network_type; + String domain; + Integer segmentation_id; + Boolean external; + Boolean force_flat; + } + + public static class CreateH3cNetworksCmd extends H3cCmd{ + List networks = new ArrayList<>(); + } + + public static class CreateH3cNetworksRsp extends H3cRsp{ + List networks = new ArrayList<>(); + } + + public static class DeleteH3cNetworksCmd extends H3cCmd{ + } + + public static class DeleteH3cNetworksRsp extends H3cRsp{ + } + + public static class GetH3cVniRangeCmd extends H3cCmd { + } + + public static class VniRangeStruct { + public String start_vlan; + public String end_vlan; + public String start_vxlan; + public String end_vxlan; + public String access_mode; + } + + public static class H3cVniRangeStruct { + public String type; + public String id; + public String name; + public List vlan_map_list; + } + public static class GetH3cVniRangeRsp extends H3cRsp { + public List domains; + } + + + public static class GetH3cTenantsCmd extends H3cCmd { + } + public static class H3cTenantStruct { + public String id; + public String name; + public String type; + } + public static class GetH3cTenantsRsp extends H3cRsp { + public List tenants; + } + + public static class GetH3cTeamLederIpCmd extends H3cCmd { + } + + public static class GetH3cTeamLederIpReply { + public String ip; + } +} + diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcHttpClient.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcHttpClient.java new file mode 100644 index 00000000000..8e43b7ed120 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcHttpClient.java @@ -0,0 +1,86 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.web.util.UriComponentsBuilder; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.MessageCommandRecorder; +import org.zstack.header.rest.RESTFacade; +import org.zstack.utils.gson.JSONObjectUtil; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class H3cVcfcHttpClient { + @Autowired + private RESTFacade restf; + private TimeUnit unit; + private Long timeout; + private Class responseClass; + + public H3cVcfcHttpClient(Class rspClz) { + this.responseClass = rspClz; + this.unit = TimeUnit.MILLISECONDS; + this.timeout = H3cVcfcSdnControllerGlobalProperty.H3C_CONTROLLER_TIMEOUT; + } + + private String buildUrl(String ip, String path) { + UriComponentsBuilder ub = UriComponentsBuilder.newInstance(); + ub.scheme(H3cVcfcSdnControllerGlobalProperty.H3C_CONTROLLER_SCHEME); + if (CoreGlobalProperty.UNIT_TEST_ON) { + ub.host("localhost"); + ub.port(8989); + } else { + ub.host(ip); + ub.port(H3cVcfcSdnControllerGlobalProperty.H3C_CONTROLLER_PORT); + } + + ub.path(path); + return ub.build().toUriString(); + } + + public T syncCall(String action, String ip, String url, Object body, Map headers) { + String httpBody = null; + // for unit test finding invocation chain + if (body != null) { + MessageCommandRecorder.record(body.getClass()); + httpBody = JSONObjectUtil.toJsonString(body); + } else { + return null; + } + + switch (action) { + case "GET": { + String fullUrl = buildUrl(ip, url); + if (body != null) { + Map params = JSONObjectUtil.rehashObject(body, Map.class); + UriComponentsBuilder ub = UriComponentsBuilder.fromUriString(fullUrl); + for (Map.Entry entry : params.entrySet()) { + ub.queryParam(entry.getKey(), entry.getValue()); + } + fullUrl = ub.build().toUriString(); + } + return restf.syncJsonGet(fullUrl, null, headers, responseClass); + } + case "DELETE": { + return restf.syncJsonDelete(buildUrl(ip, url), httpBody, headers, responseClass); + } + case "PUT": { + return restf.syncJsonPut(buildUrl(ip, url), httpBody, headers, responseClass); + } + default: { + if (url.equals(H3cVcfcCommands.H3C_VCFC_L2_NETWORKS)) { + httpBody = httpBody.replace("\"network_type\"", "\"provider:network_type\"") + .replace("\"original_network_type\"", "\"provider:original_network_type\"") + .replace("\"domain\"", "\"provider:domain\"") + .replace("\"segmentation_id\"", "\"provider:segmentation_id\""); + } + return restf.syncJsonPost(buildUrl(ip, url), httpBody, headers, responseClass); + } + } + + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java new file mode 100644 index 00000000000..f9afed355d9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnController.java @@ -0,0 +1,611 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.http.HttpMethod; +import org.springframework.web.util.UriComponentsBuilder; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.Message; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.header.rest.RESTFacade; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.sdnController.*; +import org.zstack.sdnController.header.*; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; + +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class H3cVcfcSdnController implements SdnController, SdnControllerL2 { + private static final CLogger logger = Utils.getLogger(H3cVcfcSdnController.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + CloudBus bus; + @Autowired + protected RESTFacade restf; + + private SdnControllerVO self; + private String token; + private String leaderIp; + + private String buildUrl(String path) { + UriComponentsBuilder ub = UriComponentsBuilder.newInstance(); + ub.scheme(H3cVcfcSdnControllerGlobalProperty.H3C_CONTROLLER_SCHEME); + if (CoreGlobalProperty.UNIT_TEST_ON) { + ub.host("localhost"); + ub.port(8989); + } else { + ub.host(self.getIp()); + ub.port(H3cVcfcSdnControllerGlobalProperty.H3C_CONTROLLER_PORT); + } + + ub.path(path); + return ub.build().toUriString(); + } + + public H3cVcfcSdnController(SdnControllerVO self) { + this.self = self; + } + + private Map getH3cHeaders() { + return getH3cHeaders(null); + } + + private Map getH3cHeaders(String token) { + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + headers.put("Accept", "application/json"); + headers.put("Cache-Control", "no-cache"); + if (token != null) { + headers.put("X-Auth-Token", token); + } + return headers; + } + + // from H3cCmd + public void getH3cVniRanges(Completion completion) { + H3cVcfcCommands.GetH3cVniRangeCmd cmd = getGetH3cVniRangeCmd(); + try { + H3cVcfcCommands.GetH3cVniRangeRsp rsp = new H3cVcfcHttpClient<>(getGetH3cVniRangeRspClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), getH3cVcfcVniRangesPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not retrieve VNI ranges because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + + int count = 0; + for (H3cVcfcCommands.H3cVniRangeStruct d : rsp.domains) { + for (H3cVcfcCommands.VniRangeStruct v : d.vlan_map_list) { + Integer startVni = Integer.valueOf(v.start_vxlan); + Integer endVni = Integer.valueOf(v.end_vxlan); + SystemTagCreator creator = SdnControllerSystemTags.VNI_RANGE.newSystemTagCreator(self.getUuid()); + creator.ignoreIfExisting = false; + creator.inherent = false; + creator.setTagByTokens( + map( + e(SdnControllerSystemTags.START_VNI_TOKEN, v.start_vxlan), + e(SdnControllerSystemTags.END_VNI_TOKEN, v.end_vxlan) + ) + ); + creator.create(); + count++; + } + } + + if (count == 0) { + completion.fail(operr("Could not initialize SDN controller because no VNI ranges are configured on controller [ip:%s]", self.getIp())); + return; + } + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not retrieve VNI ranges from SDN controller [ip:%s] because %s", self.getIp(), e.getLocalizedMessage())); + } + } + + private void getH3cDefaultTenant(Completion completion) { + H3cVcfcCommands.GetH3cTenantsCmd cmd = getGetH3cTenantsCmd(); + try { + H3cVcfcCommands.GetH3cTenantsRsp rsp = new H3cVcfcHttpClient<>(getGetH3cTenantsRspClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), getH3cVcfcTenantsPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not retrieve tenants because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + + boolean found = false; + for (H3cVcfcCommands.H3cTenantStruct d : rsp.tenants) { + if (SdnControllerConstant.H3C_VCFC_DEFAULT_TENANT_NAME.equals(d.name) + && SdnControllerConstant.H3C_VCFC_DEFAULT_TENANT_TYPE.equals(d.type)) { + SystemTagCreator creator = H3cVcfcSdnControllerSystemTags.H3C_TENANT_UUID.newSystemTagCreator(self.getUuid()); + creator.ignoreIfExisting = false; + creator.inherent = false; + creator.setTagByTokens( + map( + e(H3cVcfcSdnControllerSystemTags.H3C_TENANT_UUID_TOKEN, d.id) + ) + ); + creator.create(); + found = true; + break; + } + } + + if (!found) { + completion.fail(operr("Could not initialize SDN controller because no default tenant is configured on controller [ip:%s]", self.getIp())); + return; + } + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not retrieve default tenant from SDN controller [ip:%s] because of a communication error", self.getIp())); + } + } + + private void getH3cParameters(APIAddSdnControllerMsg msg, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("get-h3c-parameters-%s", self.getIp())); + chain.then(new NoRollbackFlow() { + String __name__ = "get_h3c_vni_ranges"; + + @Override + public void run(FlowTrigger trigger, Map data) { + getH3cVniRanges(new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + + } + }).then(new NoRollbackFlow() { + String __name__ = "get_h3c_default_tenant"; + + @Override + public void run(FlowTrigger trigger, Map data) { + for (String systemTag : msg.getSystemTags()) { + if (H3cVcfcSdnControllerSystemTags.H3C_TENANT_UUID.isMatch(systemTag)) { + trigger.next(); + return; + } + } + getH3cDefaultTenant(new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + @Override + public void handleMessage(SdnControllerMessage msg) { + if (msg instanceof SdnControllerPingMsg) { + handle((SdnControllerPingMsg)msg); + } else { + bus.dealWithUnknownMessage((Message) msg); + } + } + + @Override + @SdnControllerLog + public void preInitSdnController(APIAddSdnControllerMsg msg, Completion completion) { + completion.success(); + } + + @Override + public void createSdnControllerDb(APIAddSdnControllerMsg msg, SdnControllerVO vo, Completion completion) { + dbf.persist(vo); + completion.success(); + } + + @Override + public void deleteSdnControllerDb(SdnControllerVO vo) { + dbf.removeByPrimaryKey(vo.getUuid(), SdnControllerVO.class); + } + + @Override + @SdnControllerLog + public void initSdnController(APIAddSdnControllerMsg msg, Completion completion) { + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + getH3cParameters(msg, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + @SdnControllerLog + public void postInitSdnController(SdnControllerVO vo, Completion completion) { + completion.success(); + } + + @Override + @SdnControllerLog + public void preCreateVxlanNetwork(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + private void createVxlanNetworkOnController(L2NetworkInventory vxlan, Completion completion) { + getH3cControllerLeaderIp(new Completion(completion) { + @Override + public void success() { + doCreateVxlanNetworkOnController(vxlan, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + /* H3C VCFC backup node can not handle the create command */ + private void doCreateVxlanNetworkOnController(L2NetworkInventory vxlan, Completion completion) { + VxlanNetworkVO vo = dbf.findByUuid(vxlan.getUuid(), VxlanNetworkVO.class); + String tenantUuid = H3cVcfcSdnControllerSystemTags.H3C_TENANT_UUID.getTokenByResourceUuid(self.getUuid(), H3cVcfcSdnControllerSystemTags.H3C_TENANT_UUID_TOKEN); + String vdsUuid = H3cVcfcSdnControllerSystemTags.H3C_VDS_UUID.getTokenByResourceUuid(self.getUuid(), H3cVcfcSdnControllerSystemTags.H3C_VDS_TOKEN); + H3cVcfcCommands.CreateH3cNetworksCmd cmd = getCreateH3cNetworksCmd(); + H3cVcfcCommands.NetworkCmd networkCmd = getNetworkCmd(); + networkCmd.name = vxlan.getName(); + networkCmd.tenant_id = tenantUuid; + networkCmd.distributed = true; + networkCmd.network_type = "VXLAN"; + networkCmd.original_network_type = "VXLAN"; + networkCmd.domain = vdsUuid; + networkCmd.segmentation_id = vo.getVni(); + networkCmd.external = false; + networkCmd.force_flat = false; + + cmd.networks.add(networkCmd); + try { + H3cVcfcCommands.CreateH3cNetworksRsp rsp = new H3cVcfcHttpClient<>(getCreateH3cNetworksRspClass()) + .syncCall(HttpMethod.POST.name(), leaderIp, getH3cVcfcL2NetworksPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not create VXLAN network because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + H3cVcfcCommands.NetworkCmd network = rsp.networks.get(0); + SystemTagCreator creator = H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID.newSystemTagCreator(vxlan.getUuid()); + creator.ignoreIfExisting = false; + creator.inherent = false; + creator.setTagByTokens( + map( + e(H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID_TOKEN, network.id) + ) + ); + creator.create(); + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not create VXLAN network on SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + @Override + @SdnControllerLog + public void createL2Network(L2NetworkInventory inv, APICreateL2NetworkMsg msg, Completion completion) { + /* initSdnController get the token */ + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + createVxlanNetworkOnController(inv, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + @SdnControllerLog + public void postCreateVxlanNetwork(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + @Override + @SdnControllerLog + public void preAttachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + @Override + @SdnControllerLog + public void attachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List clusterUuids, List systemTags, Completion completion) { + completion.success(); + } + + @Override + @SdnControllerLog + public void postAttachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + @Override + @SdnControllerLog + public void deleteSdnController(SdnControllerDeletionMsg msg, SdnControllerInventory sdn, Completion completion) { + completion.success(); + } + + + @Override + @SdnControllerLog + public void detachL2NetworkFromCluster(L2VxlanNetworkInventory vxlan, List clusterUuid, Completion completion) { + completion.success(); + } + + private void deleteVxlanNetworkOnController(L2NetworkInventory vxlan, Completion completion) { + getH3cControllerLeaderIp(new Completion(completion) { + @Override + public void success() { + doDeleteVxlanNetworkOnController(vxlan, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void doDeleteVxlanNetworkOnController(L2NetworkInventory vxlan, Completion completion) { + H3cVcfcCommands.DeleteH3cNetworksCmd cmd = getDeleteH3cNetworksCmd(); + try { + String h3cL2NetworkUuid = H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID.getTokenByResourceUuid(vxlan.getUuid(), H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID_TOKEN); + H3cVcfcCommands.DeleteH3cNetworksRsp rsp = new H3cVcfcHttpClient<>(getDeleteH3cNetworksRspClass()) + .syncCall(HttpMethod.DELETE.name(), leaderIp, String.format("%s/%s", getH3cVcfcL2NetworksPath(), h3cL2NetworkUuid), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not delete VXLAN network because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not delete VXLAN network on SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + @Override + @SdnControllerLog + public void deleteL2Network(L2NetworkInventory vxlan, Completion completion) { + /* initSdnController get the token */ + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + deleteVxlanNetworkOnController(vxlan, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + public List getVniRange(SdnControllerInventory controller) { + List> tokenList = SdnControllerSystemTags.VNI_RANGE + .getTokensOfTagsByResourceUuid(controller.getUuid()); + List vniRanges = new ArrayList<>(); + for (Map tokens : tokenList) { + SdnVniRange range = new SdnVniRange(); + range.startVni = Integer.valueOf(tokens.get(SdnControllerSystemTags.START_VNI_TOKEN)); + range.endVni = Integer.valueOf(tokens.get(SdnControllerSystemTags.END_VNI_TOKEN)); + vniRanges.add(range); + } + return vniRanges; + } + + @Override + public List getVlanRange(SdnControllerInventory controller) { + // H3c: access vlan == vni + List> tokenList = SdnControllerSystemTags.VNI_RANGE + .getTokensOfTagsByResourceUuid(controller.getUuid()); + List vlanRanges = new ArrayList<>(); + for (Map tokens : tokenList) { + SdnVlanRange range = new SdnVlanRange(); + range.startVlan = Integer.valueOf(tokens.get(SdnControllerSystemTags.START_VNI_TOKEN)); + range.endVlan = Integer.valueOf(tokens.get(SdnControllerSystemTags.END_VNI_TOKEN)); + vlanRanges.add(range); + } + return vlanRanges; + } + + private void getH3cControllerLeaderIp(Completion completion) { + H3cVcfcCommands.GetH3cTeamLederIpCmd cmd = getGetH3cTeamLederIpCmd(); + + try { + H3cVcfcCommands.GetH3cTeamLederIpReply rsp = new H3cVcfcHttpClient<>(getGetH3cTeamLederIpReplyClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), getH3cVcfcTeamLeaderIpPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not determine cluster leader because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + + leaderIp = rsp.ip; + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not determine cluster leader for SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + public void getH3cControllerToken(Completion completion) { + H3cVcfcCommands.GetH3cTokenCmd cmd = getGetH3cTokenCmd(); + H3cVcfcCommands.LoginCmd loginCmd = getLoginCmd(); + loginCmd.user = self.getUsername(); + loginCmd.password = self.getPassword(); + cmd.login = loginCmd; + + try { + H3cVcfcCommands.LoginRsp rsp = new H3cVcfcHttpClient<>(getLoginRspClass()) + .syncCall(HttpMethod.POST.name(), self.getIp(), getH3cVcfcGetTokenPath(), cmd, getH3cHeaders()); + if (rsp == null) { + completion.fail(operr("Could not authenticate with SDN controller because controller [ip:%s] did not respond", self.getIp())); + return; + } + + token = rsp.record.token; + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not authenticate with SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + void handle(SdnControllerPingMsg msg) { + SdnControllerPingReply reply = new SdnControllerPingReply(); + + getH3cControllerToken(new Completion(msg) { + @Override + public void success() { + reply.setSuccess(true); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + public void reconnectSdnController(Completion completion) { + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + // Protected methods for H3cVcfcCommands access, for subclass override + protected Class getGetH3cVniRangeRspClass() { + return H3cVcfcCommands.GetH3cVniRangeRsp.class; + } + + protected H3cVcfcCommands.GetH3cVniRangeCmd getGetH3cVniRangeCmd() { + return new H3cVcfcCommands.GetH3cVniRangeCmd(); + } + + protected String getH3cVcfcVniRangesPath() { + return H3cVcfcCommands.H3C_VCFC_VNI_RANGES; + } + + private Class getGetH3cTenantsRspClass() { + return H3cVcfcCommands.GetH3cTenantsRsp.class; + } + + protected H3cVcfcCommands.GetH3cTenantsCmd getGetH3cTenantsCmd() { + return new H3cVcfcCommands.GetH3cTenantsCmd(); + } + + protected String getH3cVcfcTenantsPath() { + return H3cVcfcCommands.H3C_VCFC_TENANTS; + } + + private H3cVcfcCommands.NetworkCmd getNetworkCmd() { + return new H3cVcfcCommands.NetworkCmd(); + } + + private H3cVcfcCommands.CreateH3cNetworksCmd getCreateH3cNetworksCmd() { + return new H3cVcfcCommands.CreateH3cNetworksCmd(); + } + + private Class getCreateH3cNetworksRspClass() { + return H3cVcfcCommands.CreateH3cNetworksRsp.class; + } + + protected String getH3cVcfcL2NetworksPath() { + return H3cVcfcCommands.H3C_VCFC_L2_NETWORKS; + } + + private H3cVcfcCommands.DeleteH3cNetworksCmd getDeleteH3cNetworksCmd() { + return new H3cVcfcCommands.DeleteH3cNetworksCmd(); + } + + protected Class getDeleteH3cNetworksRspClass() { + return H3cVcfcCommands.DeleteH3cNetworksRsp.class; + } + + protected H3cVcfcCommands.GetH3cTeamLederIpCmd getGetH3cTeamLederIpCmd() { + return new H3cVcfcCommands.GetH3cTeamLederIpCmd(); + } + + protected Class getGetH3cTeamLederIpReplyClass() { + return H3cVcfcCommands.GetH3cTeamLederIpReply.class; + } + + protected String getH3cVcfcTeamLeaderIpPath() { + return H3cVcfcCommands.H3C_VCFC_TEAM_LEADERIP; + } + + protected H3cVcfcCommands.GetH3cTokenCmd getGetH3cTokenCmd() { + return new H3cVcfcCommands.GetH3cTokenCmd(); + } + + protected H3cVcfcCommands.LoginCmd getLoginCmd() { + return new H3cVcfcCommands.LoginCmd(); + } + + protected Class getLoginRspClass() { + return H3cVcfcCommands.LoginRsp.class; + } + + protected String getH3cVcfcGetTokenPath() { + return H3cVcfcCommands.H3C_VCFC_GET_TOKEN; + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerFactory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerFactory.java new file mode 100644 index 00000000000..2d297ca518c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerFactory.java @@ -0,0 +1,52 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.network.securitygroup.SecurityGroupSdnBackend; +import org.zstack.sdnController.SdnController; +import org.zstack.sdnController.SdnControllerFactory; +import org.zstack.sdnController.*; + +public class H3cVcfcSdnControllerFactory implements SdnControllerFactory { + SdnControllerType sdnControllerType = new SdnControllerType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + + @Autowired + DatabaseFacade dbf; + + @Override + public SdnControllerType getVendorType() { + return sdnControllerType; + } + + @Override + public SdnControllerVO persistSdnController(SdnControllerVO vo) { + vo = dbf.persistAndRefresh(vo); + return vo; + } + + + @Override + public SdnController getSdnController(SdnControllerVO vo) { + if (SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(vo.getVendorVersion())) { + return new H3cVcfcV2SdnController(vo); + } else { + return new H3cVcfcSdnController(vo); + } + } + + @Override + public SdnControllerL2 getSdnControllerL2(SdnControllerVO vo) { + if (SdnControllerConstant.H3C_VCFC_VENDOR_VERSION_V2.equals(vo.getVendorVersion())) { + return new H3cVcfcV2SdnController(vo); + } else { + return new H3cVcfcSdnController(vo); + } + } + + @Override + public SecurityGroupSdnBackend getSdnControllerSecurityGroup(SdnControllerVO vo) { + return null; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerGlobalProperty.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerGlobalProperty.java new file mode 100644 index 00000000000..f0c56fbfe4c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerGlobalProperty.java @@ -0,0 +1,20 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +@GlobalPropertyDefinition +public class H3cVcfcSdnControllerGlobalProperty { + @GlobalProperty(name="H3c.Scheme", defaultValue = "http") + public static String H3C_CONTROLLER_SCHEME; + + @GlobalProperty(name="H3c.Port", defaultValue = "80") + public static int H3C_CONTROLLER_PORT; + + /* default timeout 30 seconds */ + @GlobalProperty(name="H3c.Timeout", defaultValue = "30000000") + public static Long H3C_CONTROLLER_TIMEOUT; + + @GlobalProperty(name="H3c.Mgtip.Is.LeaderIp", defaultValue = "true") + public static Boolean H3C_MGT_IP_IS_LEADER_IP; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerSystemTags.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerSystemTags.java new file mode 100644 index 00000000000..cd504aa258b --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcSdnControllerSystemTags.java @@ -0,0 +1,24 @@ +package org.zstack.sdnController.h3cVcfc; + +import org.zstack.header.tag.TagDefinition; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.tag.PatternedSystemTag; + +@TagDefinition +public class H3cVcfcSdnControllerSystemTags { + public static String H3C_TENANT_UUID_TOKEN = "tenantUuid"; + public static PatternedSystemTag H3C_TENANT_UUID = new PatternedSystemTag(String.format("tenantUuid::{%s}", H3C_TENANT_UUID_TOKEN), SdnControllerVO.class); + + public static String H3C_VDS_TOKEN = "vdsUuid"; + public static PatternedSystemTag H3C_VDS_UUID = new PatternedSystemTag(String.format("vdsUuid::{%s}", H3C_VDS_TOKEN), SdnControllerVO.class); + + public static String H3C_L2_NETWORK_UUID_TOKEN = "h3cL2NetworkUuid"; + public static PatternedSystemTag H3C_L2_NETWORK_UUID = new PatternedSystemTag(String.format("h3cL2NetworkUuid::{%s}", H3C_L2_NETWORK_UUID_TOKEN), VxlanNetworkVO.class); + + public static String H3C_L2_VROUTER_UUID_TOKEN = "h3cL2RouterUuid"; + public static PatternedSystemTag H3C_L2_VROUTER_UUID = new PatternedSystemTag(String.format("h3cL2RouterUuid::{%s}", H3C_L2_VROUTER_UUID_TOKEN), VxlanNetworkVO.class); + + public static String H3C_L2_TENANT_UUID_TOKEN = "h3cL2TenantUuid"; + public static PatternedSystemTag H3C_L2_TENANT_UUID = new PatternedSystemTag(String.format("h3cL2TenantUuid::{%s}", H3C_L2_TENANT_UUID_TOKEN), VxlanNetworkVO.class); +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcV2Commands.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcV2Commands.java new file mode 100644 index 00000000000..1fcd577f96b --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcV2Commands.java @@ -0,0 +1,136 @@ +package org.zstack.sdnController.h3cVcfc; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by boce.wang on 04/28/2025. + */ +public class H3cVcfcV2Commands extends H3cVcfcCommands { + + public static final String H3C_VCFC_SUBNETS = "/vds/1.0/subnets"; + public static final String H3C_VCFC_ROUTERS = "/vds/1.0/routers"; + public static final String H3C_VCFC_VDS = "/vds/1.0/h3c_vdsconf"; + + public static class NetworkCmd extends H3cVcfcCommands.NetworkCmd { + String tenant_name; + String vds_name; + } + + public static class CreateH3cNetworksCmd extends H3cCmd { + List networks = new ArrayList<>(); + } + + public static class CreateH3cNetworksRsp extends H3cRsp { + List networks = new ArrayList<>(); + } + + public static class H3cTenantStruct extends H3cVcfcCommands.H3cTenantStruct { + public List vds_list; + public String cloud_region_name; + public String cloud_domain_name; + + public H3cTenantStruct() { + vds_list = new ArrayList<>(); + } + } + + public static class GetH3cTenantsRsp extends H3cRsp { + public List tenants; + } + + public static class AllocationPoolStruct { + public String start; + public String end; + } + + public static class SubnetCmd { + String id; + String name; + String network_id; + String nqa_profile_id; + String segment_id; + String cidr; + String gateway_ip; + Boolean enable_dhcp; + List allocation_pools; + List dns_nameservers; + List service_types; + String cloud_region_name; + List protocal_ips; + String tenant_name; + String vds_name; + } + + public static class CreateH3cSubnetsCmd extends H3cCmd { + public List subnets = new ArrayList<>(); + } + + public static class CreateH3cSubnetsRsp extends H3cRsp { + public List subnets = new ArrayList<>(); + } + + public static class GetH3cSubnetsCmd extends H3cCmd { + public String network_id; + } + public static class GetH3cSubnetsRsp extends H3cRsp { + public List subnets = new ArrayList<>(); + } + + public static class RouterCmd { + String id; + String name; + String tenant_id; + } + + public static class CreateH3cRoutersCmd extends H3cCmd { + public List routers = new ArrayList<>(); + } + + public static class CreateH3cRoutersRsp extends H3cRsp { + public List routers = new ArrayList<>(); + } + + public static class DeleteH3cRoutersCmd extends H3cCmd { + } + + public static class DeleteH3cRoutersRsp extends H3cRsp { + } + + public static class AddRouterInterfaceCmd extends H3cCmd { + public String subnet_id; + } + + public static class AddRouterInterfaceRsp extends H3cRsp { + public String id; + public String subnet_id; + public String tenant_id; + public String port_id; + } + + public static class RemoveRouterInterfaceCmd extends H3cCmd { + public String subnet_id; + } + + public static class RemoveRouterInterfaceRsp extends H3cRsp { + } + + public static class H3cVdsStruct { + public String uuid; + public String name; + public String bridge; + public String status; + public String openflow_hard_age; + public String vxlan_tunnel_name; + public String vxlan_range; + public String virtual_mac; + public String forwarding_mode; + } + + public static class GetH3cVdsCmd extends H3cCmd { + } + + public static class GetH3cVdsRsp extends H3cRsp { + public List vds; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcV2SdnController.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcV2SdnController.java new file mode 100644 index 00000000000..778d641c5e4 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/h3cVcfc/H3cVcfcV2SdnController.java @@ -0,0 +1,693 @@ +package org.zstack.sdnController.h3cVcfc; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.http.HttpMethod; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l3.IpRangeInventory; +import org.zstack.header.network.l3.L3NetworkConstant; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.sdnController.SdnControllerLog; +import org.zstack.sdnController.SdnControllerSystemTags; +import org.zstack.sdnController.header.*; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.codehaus.groovy.runtime.InvokerHelper.asList; +import static org.zstack.core.Platform.operr; +import static org.zstack.sdnController.h3cVcfc.H3cVcfcSdnControllerGlobalProperty.H3C_MGT_IP_IS_LEADER_IP; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +/** + * H3C VCFC SDN Controller V2 Implementation. + * Extends the base H3cVcfcSdnController to support newer versions or features. + */ +@Slf4j +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class H3cVcfcV2SdnController extends H3cVcfcSdnController { + private static final CLogger logger = Utils.getLogger(H3cVcfcV2SdnController.class); + + @Autowired + private DatabaseFacade dbf; + private SdnControllerVO self; + private String token; + private String leaderIp; + + private Map getH3cHeaders() { + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + headers.put("Accept", "application/json"); + headers.put("Cache-Control", "no-cache"); + + return headers; + } + + private Map getH3cHeaders(String token) { + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + headers.put("Accept", "application/json"); + headers.put("Cache-Control", "no-cache"); + headers.put("X-Auth-Token", token); + + return headers; + } + + public H3cVcfcV2SdnController(SdnControllerVO self) { + super(self); + this.self = self; + logger.debug(String.format("Instantiated H3C VCFC V2 Controller for VO [uuid:%s, name:%s]", self.getUuid(), self.getName())); + } + + @Override + @SdnControllerLog + public void addL3NetworkIpRange(L3NetworkInventory inv, IpRangeInventory ipr, Completion completion) { + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + addL3NetworkIpRangeOnController(inv, ipr, completion); + } + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + @SdnControllerLog + public void deleteL3NetworkIpRange(L3NetworkInventory inv, IpRangeInventory ipr, Completion completion) { + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + deleteL3NetworkIpRangeOnController(inv, ipr, completion); + } + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + @SdnControllerLog + public void createL2Network(L2NetworkInventory inv, APICreateL2NetworkMsg msg, Completion completion) { + /* initSdnController get the token */ + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + createVxlanNetworkOnController(inv, (APICreateL2HardwareVxlanNetworkMsg) msg, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + @SdnControllerLog + public void deleteL2Network(L2NetworkInventory vxlan, Completion completion) { + /* initSdnController get the token */ + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + deleteVxlanNetworkOnController(vxlan, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + @SdnControllerLog + public void initSdnController(APIAddSdnControllerMsg msg, Completion completion) { + getH3cControllerToken(new Completion(completion) { + @Override + public void success() { + getH3cParameters(msg, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void addL3NetworkIpRangeOnController(L3NetworkInventory inv, IpRangeInventory ipr, Completion completion) { + try { + String h3cL2NetworkUuid = H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID.getTokenByResourceUuid(inv.getL2NetworkUuid(), H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID_TOKEN); + List subnets = getSubnetsByNetworkUuid(h3cL2NetworkUuid); + H3cVcfcV2Commands.SubnetCmd subnet = subnets.stream() + .filter(s -> ipr.getNetworkCidr().equals(s.cidr)) + .findFirst() + .orElse(null); + if (subnet == null) { + logger.debug(String.format("addL3NetworkIpRangeOnController: subnet %s not exist in controller", ipr.getNetworkCidr())); + H3cVcfcV2Commands.SubnetCmd newSubnet = new H3cVcfcV2Commands.SubnetCmd(); + newSubnet.cidr = ipr.getNetworkCidr(); + newSubnet.gateway_ip = ipr.getGateway(); + newSubnet.name = ipr.getNetworkCidr(); + newSubnet.network_id = h3cL2NetworkUuid; + subnet = (H3cVcfcV2Commands.SubnetCmd) createSubnets(asList(newSubnet)).get(0); + } + if (subnet == null) { + completion.fail(operr("Could not add IP range because subnet creation failed on the SDN controller")); + return; + } + if (!Q.New(H3cSdnSubnetIpRangeRefVO.class) + .eq(H3cSdnSubnetIpRangeRefVO_.l2NetworkUuid, inv.getL2NetworkUuid()) + .eq(H3cSdnSubnetIpRangeRefVO_.ipRangeUuid, ipr.getUuid()) + .eq(H3cSdnSubnetIpRangeRefVO_.sdnControllerUuid, self.getUuid()) + .eq(H3cSdnSubnetIpRangeRefVO_.subnetUuid, subnet.id) + .isExists()) { + H3cSdnSubnetIpRangeRefVO newRef = new H3cSdnSubnetIpRangeRefVO(); + newRef.setL2NetworkUuid(inv.getL2NetworkUuid()); + newRef.setIpRangeUuid(ipr.getUuid()); + newRef.setSdnControllerUuid(self.getUuid()); + newRef.setSubnetUuid(subnet.id); + dbf.persist(newRef); + String h3cL2VRouterUuid = H3cVcfcSdnControllerSystemTags.H3C_L2_VROUTER_UUID.getTokenByResourceUuid(inv.getL2NetworkUuid(), H3cVcfcSdnControllerSystemTags.H3C_L2_VROUTER_UUID_TOKEN); + if(h3cL2VRouterUuid != null && !inv.getType().equals(L3NetworkConstant.L3_BASIC_NETWORK_TYPE)) { + addRouterInterface(h3cL2VRouterUuid, subnet.id); + } + } + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not add IP range to L3 network because %s", e.getMessage())); + } + } + + private void deleteL3NetworkIpRangeOnController(L3NetworkInventory inv, IpRangeInventory ipr, Completion completion) { + try { + String h3cL2NetworkUuid = H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID.getTokenByResourceUuid( + inv.getL2NetworkUuid(), H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID_TOKEN); + List subnets = getSubnetsByNetworkUuid(h3cL2NetworkUuid); + H3cVcfcV2Commands.SubnetCmd subnet = subnets.stream() + .filter(s -> ipr.getNetworkCidr().equals(s.cidr)) + .findFirst() + .orElse(null); + if (subnet == null) { + dbf.removeCollection( + Q.New(H3cSdnSubnetIpRangeRefVO.class).eq(H3cSdnSubnetIpRangeRefVO_.ipRangeUuid, ipr.getUuid()).list(), + H3cSdnSubnetIpRangeRefVO.class + ); + } else { + List refs = Q.New(H3cSdnSubnetIpRangeRefVO.class) + .eq(H3cSdnSubnetIpRangeRefVO_.l2NetworkUuid, inv.getL2NetworkUuid()) + .eq(H3cSdnSubnetIpRangeRefVO_.sdnControllerUuid, self.getUuid()) + .eq(H3cSdnSubnetIpRangeRefVO_.subnetUuid, subnet.id).list(); + List refsToDelete = refs.stream() + .filter(ref -> ref.getIpRangeUuid().equals(ipr.getUuid())) + .collect(Collectors.toList()); + refs.removeAll(refsToDelete); + if (refs.isEmpty()) { + deleteSubnet(subnet.id); + } + dbf.removeCollection(refsToDelete, H3cSdnSubnetIpRangeRefVO.class); + } + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not delete IP range from L3 network because %s", e.getMessage())); + } + } + + private void createVxlanNetworkOnController(L2NetworkInventory vxlan, APICreateL2HardwareVxlanNetworkMsg msg, Completion completion) { + getH3cControllerLeaderIp(new Completion(completion) { + @Override + public void success() { + doCreateVxlanNetworkOnController(vxlan, msg, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void getH3cControllerLeaderIp(Completion completion) { + if (H3C_MGT_IP_IS_LEADER_IP) { + leaderIp = self.getIp(); + completion.success(); + return; + } + + H3cVcfcV2Commands.GetH3cTeamLederIpCmd cmd = getGetH3cTeamLederIpCmd(); + + try { + H3cVcfcV2Commands.GetH3cTeamLederIpReply rsp = new H3cVcfcHttpClient<>(getGetH3cTeamLederIpReplyClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), getH3cVcfcTeamLeaderIpPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not determine cluster leader because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + + leaderIp = rsp.ip; + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not determine cluster leader for SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + @Override + public void getH3cControllerToken(Completion completion) { + H3cVcfcV2Commands.GetH3cTokenCmd cmd = getGetH3cTokenCmd(); + H3cVcfcV2Commands.LoginCmd loginCmd = getLoginCmd(); + loginCmd.user = self.getUsername(); + loginCmd.password = self.getPassword(); + cmd.login = loginCmd; + + try { + H3cVcfcV2Commands.LoginRsp rsp = new H3cVcfcHttpClient<>(getLoginRspClass()) + .syncCall(HttpMethod.POST.name(), self.getIp(), getH3cVcfcGetTokenPath(), cmd, getH3cHeaders()); + if (rsp == null) { + completion.fail(operr("Could not authenticate with SDN controller because controller [ip:%s] did not respond", self.getIp())); + return; + } + + token = rsp.record.token; + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not authenticate with SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + @Override + public void getH3cVniRanges(Completion completion) { + H3cVcfcV2Commands.GetH3cVniRangeCmd cmd = getGetH3cVniRangeCmd(); + try { + H3cVcfcV2Commands.GetH3cVniRangeRsp rsp = new H3cVcfcHttpClient<>(getGetH3cVniRangeRspClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), getH3cVcfcVniRangesPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not retrieve VNI ranges because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + // Delete previous inherent VNI range tags before creating new ones + SdnControllerSystemTags.VNI_RANGE.delete(self.getUuid()); + int count = 0; + for (H3cVcfcV2Commands.H3cVniRangeStruct d : rsp.domains) { + for (H3cVcfcV2Commands.VniRangeStruct v : d.vlan_map_list) { + SystemTagCreator creator = SdnControllerSystemTags.VNI_RANGE.newSystemTagCreator(self.getUuid()); + creator.ignoreIfExisting = false; + creator.inherent = false; + creator.setTagByTokens( + map( + e(SdnControllerSystemTags.START_VNI_TOKEN, v.start_vxlan), + e(SdnControllerSystemTags.END_VNI_TOKEN, v.end_vxlan) + ) + ); + creator.create(); + count++; + } + } + + if (count == 0) { + completion.fail(operr("Could not initialize SDN controller because no VNI ranges are configured on controller [ip:%s]", self.getIp())); + return; + } + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not retrieve VNI ranges from SDN controller [ip:%s] because %s", self.getIp(), e.getLocalizedMessage())); + } + } + + private void getH3cParameters(APIAddSdnControllerMsg msg, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("get-h3c-parameters-%s", self.getIp())); + chain.then(new NoRollbackFlow() { + String __name__ = "get_h3c_controller_token"; + + @Override + public void run(FlowTrigger trigger, Map data) { + getH3cControllerToken(new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "get_h3c_vni_ranges"; + + @Override + public void run(FlowTrigger trigger, Map data) { + getH3cVniRanges(new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + private void doCreateVxlanNetworkOnController(L2NetworkInventory vxlan, APICreateL2HardwareVxlanNetworkMsg msg, Completion completion) { + VxlanNetworkVO vo = dbf.findByUuid(vxlan.getUuid(), VxlanNetworkVO.class); + if (msg.getH3cTenantUuid() == null) { + completion.fail(operr("Could not create hardware VXLAN network because H3C tenant UUID is a mandatory parameter for the H3C VCFC V2 controller")); + return; + } + H3cSdnControllerTenantVO tenantVO = Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.uuid, msg.getH3cTenantUuid()) + .eq(H3cSdnControllerTenantVO_.sdnControllerUuid, self.getUuid()) + .limit(1) + .find(); + if (tenantVO == null) { + completion.fail(operr("Could not create hardware VXLAN network because the specified tenant does not exist in the SDN controller")); + return; + } + + H3cVcfcV2Commands.CreateH3cNetworksCmd cmd = getCreateH3cNetworksCmd(); + H3cVcfcV2Commands.NetworkCmd networkCmd = getNetworkCmd(); + networkCmd.name = vxlan.getName(); + networkCmd.tenant_id = tenantVO.getTenantUuid(); + networkCmd.distributed = true; + networkCmd.network_type = "VXLAN"; + networkCmd.original_network_type = "VXLAN"; + networkCmd.domain = tenantVO.getVdsUuid(); + networkCmd.segmentation_id = vo.getVni(); + networkCmd.external = false; + networkCmd.force_flat = false; + + cmd.networks.add(networkCmd); + try { + H3cVcfcV2Commands.CreateH3cNetworksRsp rsp = new H3cVcfcHttpClient<>(getCreateH3cNetworksRspClass()) + .syncCall(HttpMethod.POST.name(), leaderIp, getH3cVcfcL2NetworksPath(), cmd, getH3cHeaders(token)); + if (rsp == null) { + completion.fail(operr("Could not create VXLAN network because the SDN controller [ip:%s] did not respond", self.getIp())); + return; + } + H3cVcfcV2Commands.NetworkCmd network = rsp.networks.get(0); + SystemTagCreator creator = H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID.newSystemTagCreator(vxlan.getUuid()); + creator.ignoreIfExisting = false; + creator.inherent = false; + creator.setTagByTokens( + map( + e(H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID_TOKEN, network.id) + ) + ); + creator.create(); + + String routerId = createVirtualRouterOnController(SdnControllerConstant.SDN_CONTROLLER_VROUTER_PREFIX + network.name, tenantVO.getUuid()); + if (routerId != null) { + SystemTagCreator routerTagCreator = H3cVcfcSdnControllerSystemTags.H3C_L2_VROUTER_UUID.newSystemTagCreator(vxlan.getUuid()); + routerTagCreator.ignoreIfExisting = false; + routerTagCreator.inherent = false; + routerTagCreator.setTagByTokens(map(e(H3cVcfcSdnControllerSystemTags.H3C_L2_VROUTER_UUID_TOKEN, routerId))); + routerTagCreator.create(); + } + + if (tenantVO != null) { + SystemTagCreator tenantTagCreator = H3cVcfcSdnControllerSystemTags.H3C_L2_TENANT_UUID.newSystemTagCreator(vxlan.getUuid()); + tenantTagCreator.ignoreIfExisting = false; + tenantTagCreator.inherent = false; + tenantTagCreator.setTagByTokens(map(e(H3cVcfcSdnControllerSystemTags.H3C_L2_TENANT_UUID_TOKEN, tenantVO.getTenantUuid()))); + tenantTagCreator.create(); + } + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not create VXLAN network on SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + private void deleteVxlanNetworkOnController(L2NetworkInventory vxlan, Completion completion) { + getH3cControllerLeaderIp(new Completion(completion) { + @Override + public void success() { + doDeleteVxlanNetworkOnController(vxlan, completion); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + private void doDeleteVxlanNetworkOnController(L2NetworkInventory vxlan, Completion completion) { + H3cVcfcV2Commands.DeleteH3cNetworksCmd cmd = getDeleteH3cNetworksCmd(); + try { + String h3cL2NetworkUuid = H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID.getTokenByResourceUuid(vxlan.getUuid(), H3cVcfcSdnControllerSystemTags.H3C_L2_NETWORK_UUID_TOKEN); + H3cVcfcV2Commands.DeleteH3cNetworksRsp rsp = new H3cVcfcHttpClient<>(getDeleteH3cNetworksRspClass()) + .syncCall(HttpMethod.DELETE.name(), leaderIp, String.format("%s/%s", getH3cVcfcL2NetworksPath(), h3cL2NetworkUuid), cmd, getH3cHeaders(token)); + + String h3cL2VRouterUuid = H3cVcfcSdnControllerSystemTags.H3C_L2_VROUTER_UUID.getTokenByResourceUuid(vxlan.getUuid(), H3cVcfcSdnControllerSystemTags.H3C_L2_VROUTER_UUID_TOKEN); + if(h3cL2VRouterUuid != null) { + deleteVirtualRouterOnController(h3cL2VRouterUuid); + } + + completion.success(); + } catch (Exception e) { + completion.fail(operr("Could not delete VXLAN network on SDN controller [ip:%s] because %s", self.getIp(), e.getMessage())); + } + } + + private H3cVcfcCommands.DeleteH3cNetworksCmd getDeleteH3cNetworksCmd() { + return new H3cVcfcV2Commands.DeleteH3cNetworksCmd(); + } + + private H3cVcfcV2Commands.NetworkCmd getNetworkCmd() { + return new H3cVcfcV2Commands.NetworkCmd(); + } + + private H3cVcfcV2Commands.CreateH3cNetworksCmd getCreateH3cNetworksCmd() { + return new H3cVcfcV2Commands.CreateH3cNetworksCmd(); + } + + private Class getCreateH3cNetworksRspClass() { + return H3cVcfcV2Commands.CreateH3cNetworksRsp.class; + } + + private Class getGetH3cTenantsRspClass() { + return H3cVcfcV2Commands.GetH3cTenantsRsp.class; + } + + private Class getGetH3cSubnetsRspClass() { + return H3cVcfcV2Commands.GetH3cSubnetsRsp.class; + } + + @Override + protected String getH3cVcfcTenantsPath() { + return H3cVcfcV2Commands.H3C_VCFC_TENANTS; + } + + public List getAllH3cTenants() { + H3cVcfcV2Commands.GetH3cTenantsCmd cmd = new H3cVcfcV2Commands.GetH3cTenantsCmd(); + try { + H3cVcfcV2Commands.GetH3cTenantsRsp rsp = new H3cVcfcHttpClient<>(getGetH3cTenantsRspClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), H3cVcfcV2Commands.H3C_VCFC_TENANTS, cmd, getH3cHeaders(token)); + if (rsp == null || rsp.tenants == null) { + return new ArrayList<>(); + } + + // Validate response by checking for default tenant presence + boolean hasDefaultTenant = rsp.tenants.stream() + .anyMatch(tenant -> SdnControllerConstant.H3C_SDN_CONTROLLER_DEFAULT_TENANT_ID.equals(tenant.id)); + + if (!hasDefaultTenant) { + throw new RuntimeException(String.format("No default tenant found in SDN controller [ip:%s]", self.getIp())); + } + + return rsp.tenants; + } catch (Exception e) { + logger.error("Failed to get all tenants from SDN controller: " + e.getMessage(), e); + throw new RuntimeException(String.format("failed to get all tenants from SDN controller [ip:%s], error: %s", self.getIp(), e.getMessage()), e); + } + } + + public List getAllH3cVds() { + H3cVcfcV2Commands.GetH3cVdsCmd cmd = new H3cVcfcV2Commands.GetH3cVdsCmd(); + try { + H3cVcfcV2Commands.GetH3cVdsRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcV2Commands.GetH3cVdsRsp.class) + .syncCall(HttpMethod.GET.name(), self.getIp(), H3cVcfcV2Commands.H3C_VCFC_VDS, cmd, getH3cHeaders(token)); + if (rsp == null || rsp.vds == null) { + return new ArrayList<>(); + } + + return rsp.vds; + } catch (Exception e) { + logger.error("Failed to get all VDS from SDN controller: " + e.getMessage(), e); + throw new RuntimeException(String.format("failed to get all VDS from SDN controller [ip:%s], error: %s", self.getIp(), e.getMessage()), e); + } + } + + private List getSubnetsByNetworkUuid(String networkUuid) { + H3cVcfcV2Commands.GetH3cSubnetsCmd cmd = new H3cVcfcV2Commands.GetH3cSubnetsCmd(); + cmd.network_id = networkUuid; + try { + H3cVcfcV2Commands.GetH3cSubnetsRsp rsp = new H3cVcfcHttpClient<>(getGetH3cSubnetsRspClass()) + .syncCall(HttpMethod.GET.name(), self.getIp(), H3cVcfcV2Commands.H3C_VCFC_SUBNETS, cmd, getH3cHeaders(token)); + if (rsp == null || rsp.subnets == null) { + return new ArrayList<>(); + } + return rsp.subnets; + } catch (Exception e) { + logger.error("Failed to get all subnets from SDN controller: " + e.getMessage(), e); + throw new RuntimeException(String.format("failed to get all subnets from SDN controller [ip:%s], error: %s", self.getIp(), e.getMessage()), e); + } + } + + private List createSubnets(List subnets) { + H3cVcfcV2Commands.CreateH3cSubnetsCmd cmd = new H3cVcfcV2Commands.CreateH3cSubnetsCmd(); + cmd.subnets = subnets; + try { + H3cVcfcV2Commands.CreateH3cSubnetsRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcV2Commands.CreateH3cSubnetsRsp.class) + .syncCall(HttpMethod.POST.name(), self.getIp(), H3cVcfcV2Commands.H3C_VCFC_SUBNETS, cmd, getH3cHeaders(token)); + if (rsp == null || rsp.subnets == null) { + return new ArrayList<>(); + } + return rsp.subnets; + } catch (Exception e) { + logger.error("Failed to create subnets on SDN controller: " + e.getMessage(), e); + throw new RuntimeException(String.format("failed to create subnets on SDN controller [ip:%s], error: %s", self.getIp(), e.getMessage()), e); + } + } + + private void deleteSubnet(String subnetId) { + H3cVcfcCommands.H3cCmd cmd = new H3cVcfcCommands.H3cCmd(); + try { + H3cVcfcCommands.H3cRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcCommands.H3cRsp.class) + .syncCall(HttpMethod.DELETE.name(), self.getIp(), String.format("%s/%s", H3cVcfcV2Commands.H3C_VCFC_SUBNETS, subnetId), cmd, getH3cHeaders(token)); + } catch (Exception e) { + logger.error("Failed to delete subnets on SDN controller: " + e.getMessage(), e); + throw new RuntimeException(String.format("failed to delete subnets on SDN controller [ip:%s], error: %s", self.getIp(), e.getMessage()), e); + } + } + + private String createVirtualRouterOnController(String routerName, String tenantUuid) { + H3cSdnControllerTenantVO tenantVO = Q.New(H3cSdnControllerTenantVO.class) + .eq(H3cSdnControllerTenantVO_.uuid, tenantUuid) + .eq(H3cSdnControllerTenantVO_.sdnControllerUuid, self.getUuid()) + .limit(1) + .find(); + if (tenantVO == null) { + logger.warn(String.format("cannot find tenant in sdn controller for virtual router [name:%s]", routerName)); + return null; + } + + H3cVcfcV2Commands.CreateH3cRoutersCmd cmd = new H3cVcfcV2Commands.CreateH3cRoutersCmd(); + H3cVcfcV2Commands.RouterCmd routerCmd = new H3cVcfcV2Commands.RouterCmd(); + routerCmd.name = routerName; + routerCmd.tenant_id = tenantVO.getTenantUuid(); + + cmd.routers.add(routerCmd); + try { + H3cVcfcV2Commands.CreateH3cRoutersRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcV2Commands.CreateH3cRoutersRsp.class) + .syncCall(HttpMethod.POST.name(), leaderIp, H3cVcfcV2Commands.H3C_VCFC_ROUTERS, cmd, getH3cHeaders(token)); + if (rsp == null || rsp.routers == null || rsp.routers.isEmpty()) { + logger.warn(String.format("create virtual router on sdn controller [ip:%s] failed", self.getIp())); + return null; + } + + H3cVcfcV2Commands.RouterCmd router = rsp.routers.get(0); + logger.info(String.format("Successfully created virtual router [name:%s, id:%s] on sdn controller [ip:%s]", + router.name, router.id, self.getIp())); + return router.id; + } catch (Exception e) { + logger.warn(String.format("create virtual router on sdn controller [ip:%s] failed because %s", self.getIp(), e.getMessage())); + } + return null; + } + + private void deleteVirtualRouterOnController(String routerId) { + H3cVcfcV2Commands.DeleteH3cRoutersCmd cmd = new H3cVcfcV2Commands.DeleteH3cRoutersCmd(); + try { + H3cVcfcV2Commands.DeleteH3cRoutersRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcV2Commands.DeleteH3cRoutersRsp.class) + .syncCall(HttpMethod.DELETE.name(), leaderIp, String.format("%s/%s", H3cVcfcV2Commands.H3C_VCFC_ROUTERS, routerId), cmd, getH3cHeaders(token)); + if (rsp == null) { + logger.warn(String.format("delete virtual router on sdn controller [ip:%s] failed", self.getIp())); + return; + } + + logger.info(String.format("Successfully deleted virtual router [id:%s] on sdn controller [ip:%s]", + routerId, self.getIp())); + + } catch (Exception e) { + logger.warn(String.format("delete virtual router on sdn controller [ip:%s] failed because %s", self.getIp(), e.getMessage())); + } + } + + private void addRouterInterface(String routerId, String subnetId) { + H3cVcfcV2Commands.AddRouterInterfaceCmd cmd = new H3cVcfcV2Commands.AddRouterInterfaceCmd(); + cmd.subnet_id = subnetId; + + try { + H3cVcfcV2Commands.AddRouterInterfaceRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcV2Commands.AddRouterInterfaceRsp.class) + .syncCall(HttpMethod.PUT.name(), self.getIp(), String.format("%s/%s/add_router_interface", H3cVcfcV2Commands.H3C_VCFC_ROUTERS, routerId), cmd, getH3cHeaders(token)); + if (rsp == null) { + logger.warn(String.format("add router interface on sdn controller [ip:%s] failed for router [id:%s] subnet [id:%s]", + self.getIp(), routerId, subnetId)); + } else { + logger.info(String.format("Successfully added router interface for router [id:%s] subnet [id:%s] on sdn controller [ip:%s]", + routerId, subnetId, self.getIp())); + } + } catch (Exception e) { + logger.warn(String.format("add router interface on sdn controller [ip:%s] failed for router [id:%s] subnet [id:%s] because %s", + self.getIp(), routerId, subnetId, e.getMessage())); + } + } + + private void removeRouterInterface(String routerId, String subnetId) { + H3cVcfcV2Commands.RemoveRouterInterfaceCmd cmd = new H3cVcfcV2Commands.RemoveRouterInterfaceCmd(); + cmd.subnet_id = subnetId; + + try { + H3cVcfcV2Commands.RemoveRouterInterfaceRsp rsp = new H3cVcfcHttpClient<>(H3cVcfcV2Commands.RemoveRouterInterfaceRsp.class) + .syncCall(HttpMethod.PUT.name(), self.getIp(), String.format("%s/%s/remove_router_interface", H3cVcfcV2Commands.H3C_VCFC_ROUTERS, routerId), cmd, getH3cHeaders(token)); + if (rsp == null) { + logger.warn(String.format("remove router interface on sdn controller [ip:%s] failed for router [id:%s] subnet [id:%s]", + self.getIp(), routerId, subnetId)); + } else { + logger.info(String.format("Successfully removed router interface for router [id:%s] subnet [id:%s] on sdn controller [ip:%s]", + routerId, subnetId, self.getIp())); + } + } catch (Exception e) { + logger.warn(String.format("remove router interface on sdn controller [ip:%s] failed for router [id:%s] subnet [id:%s] because %s", + self.getIp(), routerId, subnetId, e.getMessage())); + } + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java new file mode 100644 index 00000000000..b21d317c240 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetwork.java @@ -0,0 +1,238 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.*; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.*; +import org.zstack.sdnController.SdnControllerL2; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.argerr; + +/** + * Created by shixin.ruan on 09/19/2019. + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class HardwareVxlanNetwork extends VxlanNetwork implements HardwareVxlanNetworkExtensionPoint { + @Autowired + SdnControllerManager sdnControllerManager; + + private static final CLogger logger = Utils.getLogger(HardwareVxlanNetwork.class); + + public HardwareVxlanNetwork(L2NetworkVO self) { + super(self); + } + + @Override + public void createVxlanNetworkOnSdnController(L2VxlanNetworkInventory vxlan, APICreateL2NetworkMsg msg, Completion completion) { + HardwareL2VxlanNetworkPoolVO poolVO = dbf.findByUuid(vxlan.getPoolUuid(), HardwareL2VxlanNetworkPoolVO.class); + SdnControllerVO sdn = dbf.findByUuid(poolVO.getSdnControllerUuid(), SdnControllerVO.class); + SdnControllerL2 sdnController = sdnControllerManager.getSdnControllerL2(sdn); + sdnController.createL2Network(vxlan, msg, completion); + } + + @Override + public void deleteVxlanNetworkOnSdnController(VxlanNetworkVO vo, Completion completion) { + HardwareL2VxlanNetworkPoolVO poolVO = dbf.findByUuid(vo.getPoolUuid(), HardwareL2VxlanNetworkPoolVO.class); + if (poolVO == null || poolVO.getSdnControllerUuid() == null) { + completion.fail(argerr("there is no sdn controller for vxlan pool [uuid:%s]", vo.getPoolUuid())); + return; + } + + SdnControllerVO sdn = dbf.findByUuid(poolVO.getSdnControllerUuid(), SdnControllerVO.class); + SdnControllerL2 sdnController = sdnControllerManager.getSdnControllerL2(sdn); + sdnController.deleteL2Network(L2VxlanNetworkInventory.valueOf(vo), completion); + } + + private void realizeNetwork(String hostUuid, String htype, L2VxlanNetworkInventory inv , Completion completion) { + final HypervisorType hvType = HypervisorType.valueOf(htype); + final L2NetworkType l2Type = L2NetworkType.valueOf(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE); + final VSwitchType vSwitchType = VSwitchType.valueOf(inv.getvSwitchType()); + + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, vSwitchType, hvType); + ext.realize(inv, hostUuid, completion); + } + + public void attachL2NetworkToHosts(L2VxlanNetworkInventory vxlan, List hvinvs, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("attach-hardware-vxlan-%s-on-hosts", vxlan.getUuid())); + chain.then(new NoRollbackFlow() { + final String __name__ = "realize-physical-interface"; + + private void realize(final Iterator it, final FlowTrigger trigger) { + if (!it.hasNext()) { + trigger.next(); + return; + } + + HostInventory host = it.next(); + realizeNetwork(host.getUuid(), host.getHypervisorType(), vxlan, new Completion(trigger) { + @Override + public void success() { + realize(it, trigger); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void run(FlowTrigger trigger, Map data) { + realize(hvinvs.iterator(), trigger); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + @Override + public void attachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, APICreateL2NetworkMsg msg, Completion completion) { + List clusterUuids = Q.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.l2NetworkUuid, vxlan.getPoolUuid()) + .select(L2NetworkClusterRefVO_.clusterUuid).listValues(); + if (clusterUuids == null || clusterUuids.isEmpty()) { + logger.debug(String.format("no cluster attached to hardware vxlan network[uuid:%s, name:%s]", + vxlan.getUuid(), vxlan.getName())); + completion.success(); + return; + } + + List hosts = Q.New(HostVO.class).in(HostVO_.clusterUuid, clusterUuids) + .notIn(HostVO_.state, asList(HostState.PreMaintenance, HostState.Maintenance)) + .eq(HostVO_.status, HostStatus.Connected).list(); + List hvinvs = HostInventory.valueOf(hosts); + + attachL2NetworkToHosts(vxlan, hvinvs, completion); + } + + @Override + public void deleteHook(Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("delete-hardware-vxlan")); + chain.then(new NoRollbackFlow() { + final String __name__ = "delete-hardware-vxlan-from-sdn"; + + @Override + public void run(FlowTrigger trigger, Map data) { + deleteVxlanNetworkOnSdnController((VxlanNetworkVO) self, new Completion(completion) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareVxlanNetwork.super.deleteL2Bridge(null, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next(); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + // called by handle(DetachL2NetworkFromClusterMsg msg) + @Override + protected void deleteL2Bridge(List clusterUuids, Completion completion) { + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("detach-hardware-vxlan")); + chain.then(new NoRollbackFlow() { + final String __name__ = "detach-hardware-vxlan-from-sdn"; + + @Override + public void run(FlowTrigger trigger, Map data) { + L2VxlanNetworkInventory vxlan = getSelfInventory(); + HardwareL2VxlanNetworkPoolVO poolVO = dbf.findByUuid(vxlan.getPoolUuid(), HardwareL2VxlanNetworkPoolVO.class); + SdnControllerVO sdn = dbf.findByUuid(poolVO.getSdnControllerUuid(), SdnControllerVO.class); + + SdnControllerL2 controller = sdnControllerManager.getSdnControllerL2(sdn); + controller.detachL2NetworkFromCluster(vxlan, clusterUuids, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next(); + } + }); + } + }).then(new NoRollbackFlow() { + final String __name__ = "detach-hardware-vxlan-from-host"; + + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareVxlanNetwork.super.deleteL2Bridge(clusterUuids, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next(); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkExtensionPoint.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkExtensionPoint.java new file mode 100644 index 00000000000..15da376c78e --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkExtensionPoint.java @@ -0,0 +1,14 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.zstack.header.core.Completion; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; + +import java.util.List; + +public interface HardwareVxlanNetworkExtensionPoint { + void createVxlanNetworkOnSdnController(L2VxlanNetworkInventory vxlan, APICreateL2NetworkMsg msg, Completion completion); + void attachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, APICreateL2NetworkMsg msg, Completion completion); + void deleteVxlanNetworkOnSdnController(VxlanNetworkVO vo, Completion completion); +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java new file mode 100644 index 00000000000..bc356a6a4c5 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkFactory.java @@ -0,0 +1,497 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.CascadeAction; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.identity.AccountVO; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceMigrateExtensionPoint; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.zone.ZoneVO; +import org.zstack.network.l2.L2NetworkCascadeFilterExtensionPoint; +import org.zstack.network.l2.L2NetworkDefaultMtu; +import org.zstack.network.l2.L2NetworkManager; +import org.zstack.network.l2.L2NetworkSystemTags; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.AllocateVniMsg; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.AllocateVniReply; +import org.zstack.network.service.NetworkServiceGlobalConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.sdnController.SdnControllerL2; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.sdnController.header.*; +import org.zstack.tag.SystemTagCreator; +import org.zstack.tag.TagManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +/** + * Created by shixin.ruan on 09/17/2019. + */ +public class HardwareVxlanNetworkFactory implements L2NetworkFactory, VmInstanceMigrateExtensionPoint, L2NetworkDefaultMtu, L2NetworkGetVniExtensionPoint, L2NetworkCascadeFilterExtensionPoint { + private static CLogger logger = Utils.getLogger(HardwareVxlanNetworkFactory.class); + public static L2NetworkType type = new L2NetworkType(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + private SdnControllerManager sdnControllerManager; + @Autowired + private L2NetworkManager l2Mgr; + @Autowired + private ResourceConfigFacade rcf; + @Autowired + private TagManager tagMgr; + + @Override + public L2NetworkType getType() { + return type; + } + + @Override + public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + APICreateL2HardwareVxlanNetworkMsg amsg = (APICreateL2HardwareVxlanNetworkMsg) msg; + HardwareL2VxlanNetworkVO vo = new HardwareL2VxlanNetworkVO(ovo); + HardwareL2VxlanNetworkPoolVO poolVO = dbf.findByUuid(amsg.getPoolUuid(), HardwareL2VxlanNetworkPoolVO.class); + SdnControllerVO sdn = dbf.findByUuid(poolVO.getSdnControllerUuid(), SdnControllerVO.class); + if (sdn == null) { + completion.fail(operr("can not find sdn controller %s", poolVO.getSdnControllerUuid())); + return; + } + SdnControllerL2 controller = sdnControllerManager.getSdnControllerL2(sdn); + + vo.setAccountUuid(msg.getSession().getAccountUuid()); + vo.setPoolUuid(amsg.getPoolUuid()); + vo.setPhysicalInterface(poolVO.getPhysicalInterface()); + vo.setVni(0); + if (amsg.getVlan() != null) { + vo.setVlan(amsg.getVlan()); + } + + HardwareVxlanNetwork hardwareVxlan = new HardwareVxlanNetwork(vo); + + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.setName(String.format("create-hardware-vxlan-network-%s", msg.getName())); + chain.then(new ShareFlow(){ + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = String.format("pre-process-for-create-hardware-vxlan-network-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + controller.preCreateVxlanNetwork(HardwareL2VxlanNetworkInventory.valueOf(vo), msg.getSystemTags(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + flow(new Flow() { + String __name__ = String.format("allocate-vni-for-%s-and-store-in-db", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + AllocateVniMsg vniMsg = new AllocateVniMsg(); + vniMsg.setL2NetworkUuid(amsg.getPoolUuid()); + vniMsg.setRequiredVni(amsg.getVni()); + bus.makeTargetServiceIdByResourceUuid(vniMsg, L2NetworkConstant.SERVICE_ID, amsg.getPoolUuid()); + bus.send(vniMsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + + AllocateVniReply r = reply.castReply(); + vo.setVni(r.getVni()); + vo.setVirtualNetworkId(r.getVni()); + dbf.persist(vo); + + tagMgr.createTagsFromAPICreateMessage(msg, vo.getUuid(), L2NetworkVO.class.getSimpleName()); + + SystemTagCreator creator = L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID.newSystemTagCreator(vo.getUuid()); + creator.ignoreIfExisting = true; + creator.inherent = false; + creator.setTagByTokens( + map( + e(L2NetworkSystemTags.L2_NETWORK_SDN_CONTROLLER_UUID_TOKEN, poolVO.getSdnControllerUuid()) + ) + ); + creator.create(); + + data.put(SdnControllerConstant.Params.VXLAN_NETWORK.toString(), vo); + trigger.next(); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + trigger.rollback(); + } + }); + flow(new Flow() { + String __name__ = String.format("create-hardware-vxlan-on-sdn-controller-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(ovo); + hardwareVxlan.createVxlanNetworkOnSdnController(vxlan, msg, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + hardwareVxlan.deleteVxlanNetworkOnSdnController(ovo, new Completion(trigger) { + @Override + public void success() { + trigger.rollback(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.rollback(); + } + }); + } + }); + flow(new NoRollbackFlow() { + String __name__ = String.format("post-process-for-create-sdn-controller--%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(ovo); + controller.postCreateVxlanNetwork(vxlan, msg.getSystemTags(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + flow(new NoRollbackFlow() { + String __name__ = String.format("pre-process-for-attach-hardware-vxlan-on-host-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(ovo); + controller.preAttachL2NetworkToCluster(vxlan, msg.getSystemTags(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + flow(new Flow() { + String __name__ = String.format("attach-hardware-vxlan-on-host-%s-and-store-in-db", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareL2VxlanNetworkVO vov = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(vov); + hardwareVxlan.attachL2NetworkToCluster(vxlan, msg, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + /* same to vlan network, when network is deleted, bridge is deleted from host */ + trigger.rollback(); + } + }); + flow(new Flow() { + String __name__ = String.format("attach-hardware-vxlan-on-host-on-sdn-controller-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + List clusterUuids = HardwareL2VxlanNetworkPoolInventory.valueOf(poolVO).getAttachedClusterUuids(); + if (clusterUuids.isEmpty()) { + trigger.next(); + return; + } + + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(ovo); + controller.attachL2NetworkToCluster(vxlan, clusterUuids, msg.getSystemTags(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(ovo); + + controller.detachL2NetworkFromCluster(vxlan, null, new Completion(trigger) { + @Override + public void success() { + trigger.rollback(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.rollback(); + } + }); + } + }); + flow(new NoRollbackFlow() { + String __name__ = String.format("post-process-for-attach-hardware-vxlan-on-host-%s", msg.getName()); + + @Override + public void run(FlowTrigger trigger, Map data) { + HardwareL2VxlanNetworkVO ovo = (HardwareL2VxlanNetworkVO)data.get(SdnControllerConstant.Params.VXLAN_NETWORK.toString()); + HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(ovo); + + controller.postAttachL2NetworkToCluster(vxlan, msg.getSystemTags(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + List clusterUuids = Q.New(L2NetworkClusterRefVO.class) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, amsg.getPoolUuid()) + .select(L2NetworkClusterRefVO_.clusterUuid).listValues(); + if (clusterUuids != null && !clusterUuids.isEmpty()) { + List refs = new ArrayList<>(); + for (String cluster: clusterUuids) { + L2NetworkClusterRefVO ref = new L2NetworkClusterRefVO(); + ref.setClusterUuid(cluster); + ref.setL2NetworkUuid(vo.getUuid()); + refs.add(ref); + } + + dbf.persistCollection(refs); + } + + completion.success(HardwareL2VxlanNetworkInventory.valueOf(dbf.findByUuid(vo.getUuid(), + HardwareL2VxlanNetworkVO.class))); + } + }); + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + dbf.removeByPrimaryKey(vo.getUuid(), HardwareL2VxlanNetworkVO.class); + completion.fail(errCode); + } + }); + } + }).start(); + } + + @Override + public L2Network getL2Network(L2NetworkVO vo) { + return new HardwareVxlanNetwork(vo); + } + + @Override + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { + List nics = inv.getVmNics(); + List l3vos = new ArrayList<>(); + /* FIXME: shixin need add ipv6 on vlxan network */ + nics.stream().forEach((nic -> l3vos.add(Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid ,nic.getL3NetworkUuid()).find()))); + + List vxlanUuids = new ArrayList<>(); + for (L3NetworkVO l3 : l3vos) { + String type = Q.New(L2NetworkVO.class).select(L2NetworkVO_.type).eq(L2NetworkVO_.uuid, l3.getL2NetworkUuid()).findValue(); + if (type.equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE)) { + vxlanUuids.add(l3.getL2NetworkUuid()); + } + } + + if (vxlanUuids.isEmpty()) { + completion.success(); + return; + } + + ErrorCodeList errList = new ErrorCodeList(); + + new While<>(vxlanUuids).all((uuid, completion1) -> { + PrepareL2NetworkOnHostMsg msg = new PrepareL2NetworkOnHostMsg(); + msg.setL2NetworkUuid(uuid); + msg.setHost(HostInventory.valueOf((HostVO) Q.New(HostVO.class).eq(HostVO_.uuid, destHostUuid).find())); + bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, uuid); + bus.send(msg, new CloudBusCallBack(completion1) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(reply.getError().toString()); + errList.getCauses().add(reply.getError()); + } else { + logger.debug(String.format("check and realize hardware vxlan network[uuid: %s] for vm[uuid: %s] successed", uuid, inv.getUuid())); + } + completion1.done(); + + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errList.getCauses().isEmpty()) { + completion.fail(operr("cannot configure hardware vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", + inv.getUuid(), destHostUuid).causedBy(errorCodeList.getCauses())); + return; + } + logger.info(String.format("check and realize hardware vxlan networks[uuid: %s] for vm[uuid: %s] done", vxlanUuids, inv.getUuid())); + completion.success(); + } + }); + } + + @Override + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { + } + + + @Override + public String getL2NetworkType() { + return type.toString(); + } + + @Override + public Integer getDefaultMtu(L2NetworkInventory inv) { + return rcf.getResourceConfigValue(NetworkServiceGlobalConfig.DHCP_MTU_VLAN, inv.getUuid(), Integer.class); + } + + @Override + public Integer getL2NetworkVni(String l2NetworkUuid, String hostUuid) { + HardwareL2VxlanNetworkVO vxlan = dbf.findByUuid(l2NetworkUuid, HardwareL2VxlanNetworkVO.class); + HostInventory host = HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class)); + + HardwareVxlanHelper.VxlanHostMappingStruct struct = HardwareVxlanHelper.getHardwareVxlanMappingVxlanId( + HardwareL2VxlanNetworkInventory.valueOf(vxlan), host); + + return struct.getVlanId(); + } + + @Override + public String getL2NetworkVniType() { + return type.toString(); + } + + @Override + public List filterL2NetworkCascade(List l2invs, CascadeAction action) { + if (ZoneVO.class.getSimpleName().equals(action.getParentIssuer())) { + return l2invs.stream() + .filter(l2inv -> !l2inv.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE)) + .collect(Collectors.toList()); + } else if (AccountVO.class.getSimpleName().equals(action.getParentIssuer())) { + List vxlans = l2invs.stream() + .filter(l2inv -> l2inv.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE)) + .collect(Collectors.toList()); + List poolUuids = l2invs.stream() + .filter(l2inv -> l2inv.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE)) + .map(l2inv -> l2inv.getUuid()) + .collect(Collectors.toList()); + if (vxlans.isEmpty()) { + return l2invs; + } + vxlans.forEach(vxlan ->{ + VxlanNetworkVO vxlanNetworkVO = dbf.findByUuid(vxlan.getUuid(), VxlanNetworkVO.class); + if(poolUuids.contains(vxlanNetworkVO.getPoolUuid())){ + l2invs.remove(vxlan); + } + }); + return l2invs; + } else { + return l2invs; + } + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPool.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPool.java new file mode 100644 index 00000000000..f16da37a90e --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPool.java @@ -0,0 +1,258 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.Q; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.exception.CloudRuntimeException; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostInventory; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.network.l2.vxlan.vtep.*; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO_; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.*; +import org.zstack.sdnController.SdnControllerFactory; +import org.zstack.sdnController.SdnControllerL2; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.*; + +import static org.zstack.core.Platform.operr; + +/** + * Created by shixin.ruan on 09/17/2019. + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class HardwareVxlanNetworkPool extends VxlanNetworkPool { + @Autowired + SdnControllerManager sdnControllerManager; + + private static final CLogger logger = Utils.getLogger(HardwareVxlanNetworkPool.class); + + public HardwareVxlanNetworkPool(L2NetworkVO vo) { + super(vo); + } + + private HardwareL2VxlanNetworkPoolVO getSelf1() { + return (HardwareL2VxlanNetworkPoolVO) self; + } + + @Override + protected HardwareL2VxlanNetworkPoolInventory getSelfInventory() { + return HardwareL2VxlanNetworkPoolInventory.valueOf(getSelf1()); + } + + @Override + protected void handle(final PopulateVtepPeersMsg msg) { + throw new CloudRuntimeException("HardwareVxlanNetworkPool don't need vtep"); + } + + @Override + protected void handle(CreateVtepMsg msg) { + throw new CloudRuntimeException("HardwareVxlanNetworkPool don't need vtep"); + } + + @Override + protected void handle(DeleteVtepMsg msg) { + throw new CloudRuntimeException("HardwareVxlanNetworkPool don't need vtep"); + } + + @Override + protected void handle(final APICreateVxlanVtepMsg msg) { + throw new CloudRuntimeException("HardwareVxlanNetworkPool don't need vtep"); + } + + @Override + protected void afterDetachVxlanPoolFromCluster(APIDetachL2NetworkFromClusterMsg msg) { + super.afterDetachVxlanPoolFromCluster(msg); + } + + @Override + public void prepareL2NetworkOnHosts(final String l2NetworkUuid, final List hosts, boolean applyToSdn, final Completion completion) { + List vxlanVos = Q.New(VxlanNetworkVO.class) + .eq(VxlanNetworkVO_.poolUuid, self.getUuid()).list(); + SdnControllerVO vo = dbf.findByUuid(getSelf1().getSdnControllerUuid(), SdnControllerVO.class); + SdnControllerFactory factory = sdnControllerManager.getSdnControllerFactory(vo.getVendorType()); + if (factory == null) { + completion.fail(operr("there is no sdn controller factory for sdn controller type:%s", vo.getVendorType())); + return; + } + + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("prepare-l2-%s-on-hosts", self.getUuid())); + chain.then(new NoRollbackFlow() { + String __name__ = "check-physical-interface"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + List cmsgs = new ArrayList(); + for (HostInventory h : hosts) { + CheckNetworkPhysicalInterfaceMsg cmsg = new CheckNetworkPhysicalInterfaceMsg(); + cmsg.setHostUuid(h.getUuid()); + cmsg.setPhysicalInterface(self.getPhysicalInterface()); + bus.makeTargetServiceIdByResourceUuid(cmsg, HostConstant.SERVICE_ID, h.getUuid()); + cmsgs.add(cmsg); + } + + if (cmsgs.isEmpty()) { + trigger.next(); + return; + } + + new While<>(cmsgs).step((msg, wcomp) -> { + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + wcomp.done(); + } else { + wcomp.addError(reply.getError()); + wcomp.allDone(); + } + } + }); + }, L2NetworkConstant.MAX_PARALLEL_HOST_MSG).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errorCodeList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errorCodeList.getCauses().get(0)); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "realize-vxlan-network"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + if (vxlanVos.isEmpty()) { + trigger.next(); + return; + } + + new While<>(vxlanVos).each((vxlan, whileCompletion) -> { + HardwareVxlanNetwork nw = new HardwareVxlanNetwork(vxlan); + nw.attachL2NetworkToHosts(L2VxlanNetworkInventory.valueOf(vxlan), + hosts, new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + } else { + trigger.next(); + } + } + + }); + } + + }).then(new NoRollbackFlow() { + String __name__ = "attach-vxlan-network-on-sdn"; + @Override + public void run(FlowTrigger trigger, Map data) { + if (vxlanVos.isEmpty()) { + trigger.next(); + return; + } + + if (!applyToSdn) { + trigger.next(); + return; + } + + SdnControllerL2 controller = factory.getSdnControllerL2(vo); + new While<>(vxlanVos).each((vxlan, whileCompletion) -> { + controller.attachL2NetworkToHosts(L2VxlanNetworkInventory.valueOf(vxlan), hosts, new ArrayList<>(), new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + } else { + trigger.next(); + } + } + + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + @Override + public void deleteHook(Completion completion) { + /* delete all l2 network of this pool */ + List vxlanUuids = Q.New(VxlanNetworkVO.class).eq(VxlanNetworkVO_.poolUuid, self.getUuid()) + .select(VxlanNetworkVO_.uuid).listValues(); + + new While<>(vxlanUuids).all((uuid, wcomp) -> { + DeleteL2NetworkMsg msg = new DeleteL2NetworkMsg(); + msg.setUuid(uuid); + bus.makeTargetServiceIdByResourceUuid(msg, L2NetworkConstant.SERVICE_ID, uuid); + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.info(String.format("delete hardware vxlan network[uuid:%s] failed, reason:%s", uuid, reply.getError().getDetails())); + } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.success(); + } + }); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java new file mode 100644 index 00000000000..e56adeeda2d --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/HardwareVxlanNetworkPoolFactory.java @@ -0,0 +1,172 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.message.APIMessage; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.APICreateL3NetworkMsg; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory; +import org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.APICreateL2VxlanNetworkMsg; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkChecker; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolVO; +import org.zstack.network.l3.L3NetworkHelper; +import org.zstack.sdnController.header.*; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; + +import java.util.*; + +import static org.zstack.core.Platform.argerr; + +/** + * Created by shixin.ruan on 09/17/2019. + */ +public class HardwareVxlanNetworkPoolFactory implements L2NetworkFactory, GlobalApiMessageInterceptor { + private static CLogger logger = Utils.getLogger(HardwareVxlanNetworkPoolFactory.class); + static L2NetworkType type = new L2NetworkType(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private VxlanNetworkChecker vxlanInterceptor; + + @Override + public L2NetworkType getType() { + return type; + } + + @Override + @Transactional + public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + APICreateL2HardwareVxlanNetworkPoolMsg vxlanMsg = (APICreateL2HardwareVxlanNetworkPoolMsg) msg; + HardwareL2VxlanNetworkPoolVO vo = new HardwareL2VxlanNetworkPoolVO(ovo); + vo.setAccountUuid(msg.getSession().getAccountUuid()); + vo.setSdnControllerUuid(vxlanMsg.getSdnControllerUuid()); + vo = dbf.persistAndRefresh(vo); + + HardwareL2VxlanNetworkPoolInventory inv = HardwareL2VxlanNetworkPoolInventory.valueOf(vo); + String info = String.format("successfully create HardwareVxlanNetworkPool, %s", JSONObjectUtil.toJsonString(inv)); + logger.debug(info); + completion.success(inv); + } + + @Override + public L2Network getL2Network(L2NetworkVO vo) { + return new HardwareVxlanNetworkPool(vo); + } + + + @Override + public List getMessageClassToIntercept() { + return Arrays.asList(APIAttachL2NetworkToClusterMsg.class, + APICreateL3NetworkMsg.class, + APICreateL2VxlanNetworkMsg.class, + APICreateL2HardwareVxlanNetworkMsg.class, + APICreateL2HardwareVxlanNetworkPoolMsg.class); + } + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIAttachL2NetworkToClusterMsg) { + validate((APIAttachL2NetworkToClusterMsg) msg); + } else if (msg instanceof APICreateL3NetworkMsg) { + validate((APICreateL3NetworkMsg) msg); + } else if (msg instanceof APICreateL2VxlanNetworkMsg) { + validate((APICreateL2VxlanNetworkMsg) msg); + } else if (msg instanceof APICreateL2HardwareVxlanNetworkMsg) { + validate((APICreateL2HardwareVxlanNetworkMsg) msg); + } else if (msg instanceof APICreateL2HardwareVxlanNetworkPoolMsg) { + validate((APICreateL2HardwareVxlanNetworkPoolMsg) msg); + } + + return msg; + } + + @Override + public InterceptorPosition getPosition() { + return InterceptorPosition.FRONT; + } + + private void validate(APIAttachL2NetworkToClusterMsg msg) { + L2NetworkVO l2NetworkVO = dbf.findByUuid(msg.getL2NetworkUuid(), L2NetworkVO.class); + if (!l2NetworkVO.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE)) { + return; + } + + if (msg.getSystemTags() != null) { + vxlanInterceptor.validateSystemTagFormat(msg.getSystemTags()); + } + + String sdnUuid = L3NetworkHelper.getSdnControllerUuidFromL2Uuid(msg.getL2NetworkUuid()); + if (sdnUuid == null) { + return; + } + + SdnControllerVO sdnControllerVO = dbf.findByUuid(sdnUuid, SdnControllerVO.class); + if (sdnControllerVO == null) { + logger.warn(String.format("skip VNI overlap validation: SDN controller[%s] not found", sdnUuid)); + return; + } + if (SdnControllerConstant.H3C_VCFC_CONTROLLER.equals(sdnControllerVO.getVendorType())) { + vxlanInterceptor.validateVniRangeOverlap(L2NetworkInventory.valueOf(l2NetworkVO), msg.getClusterUuid()); + } + } + + private void validate(APICreateL3NetworkMsg msg) { + String type = Q.New(L2NetworkVO.class).select(L2NetworkVO_.type).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).findValue(); + if (type.equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE)) { + throw new ApiMessageInterceptionException(argerr("hardware vxlan network pool doesn't support create l3 network")); + } + } + + private void validate(APICreateL2HardwareVxlanNetworkPoolMsg msg) { + if (msg.getPhysicalInterface() == null || msg.getPhysicalInterface().equals("")) { + throw new ApiMessageInterceptionException(argerr("hardware vxlan network pool must configure the physical interface")); + } + } + + private void validate(APICreateL2VxlanNetworkMsg msg) { + VxlanNetworkPoolVO poolVO = dbf.findByUuid(msg.getPoolUuid(), VxlanNetworkPoolVO.class); + if (poolVO.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE) + && !msg.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE)) { + throw new ApiMessageInterceptionException(argerr("ONLY hardware vxlan network can be created in hardware vxlan pool")); + } + + if (!poolVO.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE) + && msg.getType().equals(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE)) { + throw new ApiMessageInterceptionException(argerr("hardware vxlan network can ONLY be created in hardware vxlan pool")); + } + } + + private void validate(APICreateL2HardwareVxlanNetworkMsg msg) { + VxlanNetworkPoolVO poolVO = dbf.findByUuid(msg.getPoolUuid(), VxlanNetworkPoolVO.class); + if (msg.getZoneUuid() != null && !msg.getZoneUuid().equals(poolVO.getZoneUuid())) { + throw new ApiMessageInterceptionException(Platform.err(SysErrors.INVALID_ARGUMENT_ERROR, + String.format("the zone uuid provided not equals to zone uuid of pool [%s], please correct it or do not fill it", + msg.getPoolUuid()) + )); + } else if (msg.getZoneUuid() == null) { + msg.setZoneUuid(poolVO.getZoneUuid()); + } + + // FIXME: only support H3cSdnController who use vni as vlan id + // check interface name length + if (msg.getVni() != null && NetworkUtils.generateVlanDeviceName( + poolVO.getPhysicalInterface(), msg.getVni()).length() > L2NetworkConstant.LINUX_IF_NAME_MAX_SIZE) { + throw new ApiMessageInterceptionException(argerr("cannot create vlan-device on %s because it's too long" + , msg.getPhysicalInterface())); + } + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMConnectExtensionForHardwareVxlanNetwork.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMConnectExtensionForHardwareVxlanNetwork.java new file mode 100644 index 00000000000..2c90803b403 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMConnectExtensionForHardwareVxlanNetwork.java @@ -0,0 +1,166 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.Completion; +import org.zstack.header.core.FutureCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.*; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.CheckNetworkPhysicalInterfaceMsg; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.KVMHostConnectExtensionPoint; +import org.zstack.kvm.KVMHostConnectedContext; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; + +import javax.persistence.TypedQuery; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * Created by shixin.ruan on 10/15/2019. + */ +public class KVMConnectExtensionForHardwareVxlanNetwork implements KVMHostConnectExtensionPoint, HostConnectionReestablishExtensionPoint { + + @Autowired + private DatabaseFacade dbf; + @Autowired + private KVMRealizeHardwareVxlanNetworkBackend hardwareVxlanNetworkBackend; + @Autowired + private CloudBus bus; + + @Transactional(readOnly = true) + private List getL2Networks(String clusterUuid) { + String sql = "select l2.uuid from L2NetworkVO l2, L2NetworkClusterRefVO ref where l2.uuid = ref.l2NetworkUuid and ref.clusterUuid = :clusterUuid and l2.type = :type"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); + q.setParameter("clusterUuid", clusterUuid); + q.setParameter("type", SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE); + List l2uuids = q.getResultList(); + List ret = new ArrayList(l2uuids.size()); + for (String l2uuid : l2uuids) { + VxlanNetworkVO vxlanvo = dbf.getEntityManager().find(VxlanNetworkVO.class, l2uuid); + ret.add(L2VxlanNetworkInventory.valueOf(vxlanvo)); + } + return ret; + } + + private void prepareNetwork(final Iterator it, final HostInventory host, final Completion completion) { + if (!it.hasNext()) { + completion.success(); + return; + } + + final L2NetworkInventory l2 = it.next(); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("prepare-hareware-vxlan-%s-for-kvm-%s-connect", l2.getUuid(), host.getUuid())); + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + CheckNetworkPhysicalInterfaceMsg cmsg = new CheckNetworkPhysicalInterfaceMsg(); + cmsg.setHostUuid(host.getUuid()); + cmsg.setPhysicalInterface(l2.getPhysicalInterface()); + bus.makeTargetServiceIdByResourceUuid(cmsg, HostConstant.SERVICE_ID, host.getUuid()); + bus.send(cmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + } else { + trigger.next(); + } + } + }); + } + }); + + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + hardwareVxlanNetworkBackend.realize(l2, host.getUuid(), true, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + chain.done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + prepareNetwork(it, host, completion); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + @Override + public void connectionReestablished(HostInventory inv) throws HostException { + //TODO: make connect async + List l2s = getL2Networks(inv.getClusterUuid()); + if (l2s.isEmpty()) { + return; + } + + FutureCompletion completion = new FutureCompletion(null); + prepareNetwork(l2s.iterator(), inv, completion); + completion.await(TimeUnit.SECONDS.toMillis(600)); + if (!completion.isSuccess()) { + throw new OperationFailureException(completion.getErrorCode()); + } + } + + @Override + public HypervisorType getHypervisorTypeForReestablishExtensionPoint() { + return new HypervisorType(KVMConstant.KVM_HYPERVISOR_TYPE); + } + + @Override + public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { + return new NoRollbackFlow() { + String __name__ = "prepare-hardware-vxlan-network"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + List l2s = getL2Networks(context.getInventory().getClusterUuid()); + if (l2s.isEmpty()) { + trigger.next(); + return; + } + + prepareNetwork(l2s.iterator(), context.getInventory(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java new file mode 100644 index 00000000000..71ccb7db63d --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanNetworkBackend.java @@ -0,0 +1,251 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HypervisorType; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.kvm.*; +import org.zstack.kvm.KVMAgentCommands.CheckVlanBridgeResponse; +import org.zstack.kvm.KVMAgentCommands.CreateVlanBridgeCmd; +import org.zstack.kvm.KVMAgentCommands.CreateVlanBridgeResponse; +import org.zstack.kvm.KVMAgentCommands.NicTO; +import org.zstack.network.l2.L2NetworkManager; +import org.zstack.network.service.MtuGetter; +import org.zstack.sdnController.header.*; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +public class KVMRealizeHardwareVxlanNetworkBackend implements L2NetworkRealizationExtensionPoint, KVMCompleteNicInformationExtensionPoint { + private static final CLogger logger = Utils.getLogger(KVMRealizeHardwareVxlanNetworkBackend.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + private L2NetworkManager l2Mgr; + + private String makeBridgeName(String l2Uuid, int vlan) { + return KVMHostUtils.getNormalizedBridgeName(l2Uuid, "br_%s_" + vlan); + } + + @Override + public void realize(final L2NetworkInventory l2Network, final String hostUuid, boolean noStatusCheck, final Completion completion) { + HardwareL2VxlanNetworkVO vo = dbf.findByUuid(l2Network.getUuid(), HardwareL2VxlanNetworkVO.class); + final HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(vo); + HostInventory host = HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class)); + + HardwareVxlanHelper.VxlanHostMappingStruct struct = HardwareVxlanHelper.getHardwareVxlanMappingVxlanId(vxlan, host); + Integer vlanId = struct.getVlanId(); + String physicalInterface = struct.getPhysicalInterface(); + + final CreateVlanBridgeCmd cmd = new CreateVlanBridgeCmd(); + cmd.setPhysicalInterfaceName(physicalInterface); + cmd.setBridgeName(makeBridgeName(vxlan.getUuid(), vlanId)); + cmd.setVlan(vlanId); + cmd.setMtu(new MtuGetter().getL2Mtu(vxlan)); + cmd.setL2NetworkUuid(l2Network.getUuid()); + cmd.setIsolated(vxlan.getIsolated()); + + int finalVlanId = vlanId; + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setCommand(cmd); + msg.setNoStatusCheck(noStatusCheck); + msg.setPath(KVMConstant.KVM_REALIZE_L2VLAN_NETWORK_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply hreply = reply.castReply(); + CreateVlanBridgeResponse rsp = hreply.toResponse(CreateVlanBridgeResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to create bridge[%s] for hardwareVxlan[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", + cmd.getBridgeName(), l2Network.getUuid(), l2Network.getType(), finalVlanId, hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String info = String.format( + "successfully realize bridge[%s] for hardwareVxlan[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s]", cmd + .getBridgeName(), l2Network.getUuid(), l2Network.getType(), finalVlanId, hostUuid); + logger.debug(info); + + SystemTagCreator creator = KVMSystemTags.L2_BRIDGE_NAME.newSystemTagCreator(l2Network.getUuid()); + creator.inherent = true; + creator.ignoreIfExisting = true; + creator.setTagByTokens(map(e(KVMSystemTags.L2_BRIDGE_NAME_TOKEN, cmd.getBridgeName()))); + creator.create(); + + // + + completion.success(); + } + }); + } + + @Override + public void realize(final L2NetworkInventory l2Network, final String hostUuid, final Completion completion) { + realize(l2Network, hostUuid, false, completion); + } + + public void check(final L2NetworkInventory l2Network, final String hostUuid, boolean noStatusCheck, final Completion completion) { + HardwareL2VxlanNetworkVO vo = dbf.findByUuid(l2Network.getUuid(), HardwareL2VxlanNetworkVO.class); + final HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(vo); + + HostInventory host = HostInventory.valueOf(dbf.findByUuid(hostUuid, HostVO.class)); + HardwareVxlanHelper.VxlanHostMappingStruct struct = HardwareVxlanHelper.getHardwareVxlanMappingVxlanId(vxlan, host); + Integer vlanId = struct.getVlanId(); + String physicalInterface = struct.getPhysicalInterface(); + + final KVMAgentCommands.CheckVlanBridgeCmd cmd = new KVMAgentCommands.CheckVlanBridgeCmd(); + cmd.setVlan(vlanId); + cmd.setPhysicalInterfaceName(physicalInterface); + cmd.setBridgeName(makeBridgeName(l2Network.getUuid(), vlanId)); + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setCommand(cmd); + msg.setPath(KVMConstant.KVM_CHECK_L2VLAN_NETWORK_PATH); + msg.setNoStatusCheck(noStatusCheck); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply hreply = reply.castReply(); + CheckVlanBridgeResponse rsp = hreply.toResponse(CheckVlanBridgeResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to check bridge[%s] for hardwareVxlan[uuid:%s, name:%s] on kvm host[uuid:%s], %s", + cmd.getBridgeName(), vxlan.getUuid(), vxlan.getName(), hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String info = String.format("successfully checked bridge[%s] for hardwareVxlan[uuid:%s, name:%s] on kvm host[uuid:%s]", + cmd.getBridgeName(), vxlan.getUuid(), vxlan.getName(), hostUuid); + logger.debug(info); + completion.success(); + } + }); + } + + @Override + public void check(final L2NetworkInventory l2Network, final String hostUuid, final Completion completion) { + check(l2Network, hostUuid, false, completion); + } + + @Override + public L2NetworkType getSupportedL2NetworkType() { + return L2NetworkType.valueOf(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE); + } + + @Override + public HypervisorType getSupportedHypervisorType() { + return HypervisorType.valueOf(KVMConstant.KVM_HYPERVISOR_TYPE); + } + + @Override + public L2NetworkType getL2NetworkTypeVmNicOn() { + return getSupportedL2NetworkType(); + } + + @Override + public VSwitchType getSupportedVSwitchType() { + return VSwitchType.valueOf(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + } + + + @Override + public NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { + HardwareL2VxlanNetworkVO vo = dbf.findByUuid(l2Network.getUuid(), HardwareL2VxlanNetworkVO.class); + final HardwareL2VxlanNetworkInventory vxlan = HardwareL2VxlanNetworkInventory.valueOf(vo); + VmInstanceVO vm = dbf.findByUuid(nic.getVmInstanceUuid(), VmInstanceVO.class); + + /* TODO vm must have hostUuid */ + HostInventory host = HostInventory.valueOf(dbf.findByUuid(vm.getHostUuid(), HostVO.class)); + HardwareVxlanHelper.VxlanHostMappingStruct struct = HardwareVxlanHelper.getHardwareVxlanMappingVxlanId(vxlan, host); + Integer vlanId = struct.getVlanId(); + + NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); + to.setBridgeName(makeBridgeName(l2Network.getUuid(), vlanId)); + to.setMetaData(String.valueOf(vlanId)); + to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); + return to; + } + + @Override + public String getBridgeName(L2NetworkInventory l2Network) { + HardwareL2VxlanNetworkVO vo = dbf.findByUuid(l2Network.getUuid(), HardwareL2VxlanNetworkVO.class); + /* + * to be done */ + + return makeBridgeName(l2Network.getUuid(), vo.getVni()); + } + + public void delete(L2NetworkInventory l2Network, String hostUuid, Completion completion) { + HardwareL2VxlanNetworkVO vo = dbf.findByUuid(l2Network.getUuid(), HardwareL2VxlanNetworkVO.class); + HardwareL2VxlanNetworkInventory l2Vxlan = HardwareL2VxlanNetworkInventory.valueOf(vo); + KVMAgentCommands.DeleteVlanBridgeCmd cmd = new KVMAgentCommands.DeleteVlanBridgeCmd(); + cmd.setPhysicalInterfaceName(l2Network.getPhysicalInterface()); + cmd.setBridgeName(makeBridgeName(l2Vxlan.getUuid(), l2Vxlan.getVlan())); + cmd.setVlan(l2Vxlan.getVlan()); + cmd.setL2NetworkUuid(l2Network.getUuid()); + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setCommand(cmd); + msg.setPath(KVMConstant.KVM_DELETE_L2VLAN_NETWORK_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply hreply = reply.castReply(); + KVMAgentCommands.DeleteVlanBridgeResponse rsp = hreply.toResponse(KVMAgentCommands.DeleteVlanBridgeResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to delete bridge[%s] for l2Network[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s], because %s", + cmd.getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2Vxlan.getVlan(), hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String message = String.format( + "successfully delete bridge[%s] for l2Network[uuid:%s, type:%s, vlan:%s] on kvm host[uuid:%s]", cmd + .getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2Vxlan.getVlan(), hostUuid); + logger.debug(message); + + completion.success(); + } + }); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java new file mode 100644 index 00000000000..df44da2ee64 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/hardwareVxlan/KVMRealizeHardwareVxlanPoolNetworkBackend.java @@ -0,0 +1,119 @@ +package org.zstack.sdnController.hardwareVxlan; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.timeout.ApiTimeoutManager; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HypervisorType; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.rest.RESTFacade; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.kvm.KVMAgentCommands; +import org.zstack.kvm.KVMAgentCommands.NicTO; +import org.zstack.kvm.KVMCompleteNicInformationExtensionPoint; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.KVMHostUtils; +import org.zstack.network.service.MtuGetter; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import static org.zstack.core.Platform.operr; + +public class KVMRealizeHardwareVxlanPoolNetworkBackend implements L2NetworkRealizationExtensionPoint, KVMCompleteNicInformationExtensionPoint { + private static final CLogger logger = Utils.getLogger(KVMRealizeHardwareVxlanPoolNetworkBackend.class); + + @Autowired + private RESTFacade restf; + @Autowired + private ErrorFacade errf; + @Autowired + private CloudBus bus; + @Autowired + private ApiTimeoutManager timeoutMgr; + + private String makeBridgeName(String l2Uuid) { + return KVMHostUtils.getNormalizedBridgeName(l2Uuid, "br_%s"); + } + + @Override + public void realize(final L2NetworkInventory l2Network, final String hostUuid, final Completion completion) { + completion.success(); + } + + public void check(final L2NetworkInventory l2Network, final String hostUuid, boolean noStatusCheck, final Completion completion) { + CheckNetworkPhysicalInterfaceMsg msg = new CheckNetworkPhysicalInterfaceMsg(); + msg.setHostUuid(hostUuid); + msg.setPhysicalInterface(l2Network.getPhysicalInterface()); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + CheckNetworkPhysicalInterfaceReply rsp = reply.castReply(); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to check physical interface for HardwareVxlanPool[uuid:%s, name:%s] on kvm host[uuid: %s], %s", + l2Network.getUuid(), l2Network.getName(), hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String info = String.format("successfully checked physical interface for HardwareVxlanPool[uuid:%s, name:%s] on kvm host[uuid: %s]", + l2Network.getUuid(), l2Network.getName(), hostUuid); + logger.debug(info); + completion.success(); + } + }); + } + + @Override + public void check(final L2NetworkInventory l2Network, final String hostUuid, final Completion completion) { + check(l2Network, hostUuid, false, completion); + } + + @Override + public L2NetworkType getSupportedL2NetworkType() { + return L2NetworkType.valueOf(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE); + } + + @Override + public HypervisorType getSupportedHypervisorType() { + return HypervisorType.valueOf(KVMConstant.KVM_HYPERVISOR_TYPE); + } + + @Override + public VSwitchType getSupportedVSwitchType() { + return VSwitchType.valueOf(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + } + + @Override + public L2NetworkType getL2NetworkTypeVmNicOn() { + return L2NetworkType.valueOf(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE); + } + @Override + public NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { + NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); + to.setBridgeName(makeBridgeName(l2Network.getUuid())); + to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); + return to; + } + + @Override + public String getBridgeName(L2NetworkInventory l2Network) { + return null; + } + + public void delete(L2NetworkInventory l2Network, String hostUuid, Completion completion) { + completion.success(); + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerEvent.java new file mode 100644 index 00000000000..8e8ffdffbc9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerEvent.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIAddSdnControllerEvent extends APIEvent { + /** + * @desc see :ref:`SdnControllerInventory` + */ + private SdnControllerInventory inventory; + + public APIAddSdnControllerEvent(String apiId) { + super(apiId); + } + + public SdnControllerInventory getInventory() { + return inventory; + } + + public APIAddSdnControllerEvent() { + super(null); + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public static APIAddSdnControllerEvent __example__() { + APIAddSdnControllerEvent event = new APIAddSdnControllerEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + inventory.setName("sdn-1"); + inventory.setDescription("sdn controller from vendor"); + inventory.setIp("192.168.1.1"); + inventory.setUsername("admin"); + inventory.setPassword("password"); + + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..3973ff9b695 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.errorcode.ErrorCode +import org.zstack.header.network.sdncontroller.SdnControllerInventory + +doc { + + title "SDN控制器清单" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIAddSdnControllerEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7" + clz ErrorCode.class + } + ref { + name "inventory" + path "org.zstack.sdnController.header.APIAddSdnControllerEvent.inventory" + desc "null" + type "SdnControllerInventory" + since "3.7" + clz SdnControllerInventory.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerMsg.java new file mode 100644 index 00000000000..2f544dd627a --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerMsg.java @@ -0,0 +1,117 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.*; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; + +@TagResourceType(SdnControllerVO.class) +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +@RestRequest( + path = "/sdn-controllers", + method = HttpMethod.POST, + responseClass = APIAddSdnControllerEvent.class, + parameterName = "params" +) +public class APIAddSdnControllerMsg extends APICreateMessage implements APIAuditor { + @APIParam(maxLength = 255) + private String vendorType; + + @APIParam(required = false, maxLength = 255) + private String vendorVersion; + + @APIParam(maxLength = 255) + private String name; + + @APIParam(required = false, maxLength = 2048) + private String description; + + @APIParam(maxLength = 255) + private String ip; + + @APIParam(required = false, maxLength = 255) + private String userName; + + @APIParam(required = false, maxLength = 255) + @NoLogging + private String password; + + public String getVendorType() { + return vendorType; + } + + public void setVendorType(String vendorType) { + this.vendorType = vendorType; + } + + public String getVendorVersion() { + return vendorVersion; + } + + public void setVendorVersion(String vendorVersion) { + this.vendorVersion = vendorVersion; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new Result(rsp.isSuccess() ? ((APIAddSdnControllerEvent)rsp).getInventory().getUuid() : "", SdnControllerVO.class); + } + + public static APIAddSdnControllerMsg __example__() { + APIAddSdnControllerMsg msg = new APIAddSdnControllerMsg(); + + msg.setVendorType("vendor"); + msg.setName("sdn-1"); + msg.setDescription("sdn controller from vendor"); + msg.setIp("192.168.1.1"); + msg.setUserName("admin"); + msg.setPassword("password"); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..8c2c6af8e7c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIAddSdnControllerMsgDoc_zh_cn.groovy @@ -0,0 +1,130 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIAddSdnControllerEvent + +doc { + title "AddSdnController" + + category "SdnController" + + desc """添加SDN控制器""" + + rest { + request { + url "POST /v1/sdn-controllers" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAddSdnControllerMsg.class + + desc """""" + + params { + + column { + name "vendorType" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "ip" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "userName" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "password" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "systemTags" + enclosedIn "" + desc "" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "userTags" + enclosedIn "" + desc "" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "zoneUuid" + enclosedIn "params" + desc "区域UUID" + location "body" + type "String" + optional true + since "5.3.0" + } + } + } + + response { + clz APIAddSdnControllerEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerEvent.java new file mode 100644 index 00000000000..a0852ec4ce9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerEvent.java @@ -0,0 +1,51 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +/** + * API event for changing SDN controller configuration + */ +@RestResponse(allTo = "inventory") +public class APIChangeSdnControllerEvent extends APIEvent { + + /** + * @desc see :ref:`SdnControllerInventory` + */ + private SdnControllerInventory inventory; + + public APIChangeSdnControllerEvent() { + super(null); + } + + public APIChangeSdnControllerEvent(String apiId) { + super(apiId); + } + + public SdnControllerInventory getInventory() { + return inventory; + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public static APIChangeSdnControllerEvent __example__() { + APIChangeSdnControllerEvent event = new APIChangeSdnControllerEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType("H3C-VCFC"); + inventory.setName("updated-sdn-controller"); + inventory.setDescription("Updated SDN controller configuration"); + inventory.setIp("192.168.1.100"); + inventory.setUsername("admin"); + inventory.setPassword("newpassword"); + inventory.setCreateDate(new java.sql.Timestamp(org.zstack.header.message.DocUtils.date)); + inventory.setLastOpDate(new java.sql.Timestamp(org.zstack.header.message.DocUtils.date)); + + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..e13d620d737 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.network.sdncontroller.SdnControllerInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "Upate SDN Controller" + + ref { + name "inventory" + path "org.zstack.sdnController.header.APIChangeSdnControllerEvent.inventory" + desc "Updated SDN controller inventory after change operation" + type "SdnControllerInventory" + since "5.3.28" + clz SdnControllerInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.28" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIChangeSdnControllerEvent.error" + desc "Error code, null if operation succeeds, non-null if operation fails",false + type "ErrorCode" + since "5.3.28" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerMsg.java new file mode 100644 index 00000000000..cd57adda7d9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerMsg.java @@ -0,0 +1,87 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.log.NoLogging; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * API message for changing SDN controller configuration + */ +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +@RestRequest( + path = "/sdn-controllers/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIChangeSdnControllerEvent.class, + isAction = true +) +@DefaultTimeout(timeunit = TimeUnit.MINUTES, value = 30) +public class APIChangeSdnControllerMsg extends APIMessage implements SdnControllerMessage { + + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String uuid; + + @APIParam(required = false, maxLength = 255) + private String userName; + + @APIParam(required = false, maxLength = 255) + @NoLogging + private String password; + + @APIParam(required = false, maxLength = 255) + private List vlanRanges; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getSdnControllerUuid() { + return uuid; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public List getVlanRanges() { + return vlanRanges; + } + + public void setVlanRanges(List vlanRanges) { + this.vlanRanges = vlanRanges; + } + + public static APIChangeSdnControllerMsg __example__() { + APIChangeSdnControllerMsg msg = new APIChangeSdnControllerMsg(); + msg.setUuid(uuid()); + msg.setUserName("sdnuser"); + msg.setPassword("newpassword"); + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..dcfc216e75f --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIChangeSdnControllerMsgDoc_zh_cn.groovy @@ -0,0 +1,85 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIChangeSdnControllerEvent + +doc { + title "ChangeSdnController" + + category "SdnController" + + desc """Changes SDN controller""" + + rest { + request { + url "PUT /v1/sdn-controllers/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeSdnControllerMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "changeSdnController" + desc "UUID of the SDN controller resource" + location "url" + type "String" + optional false + since "5.3.28" + } + column { + name "userName" + enclosedIn "changeSdnController" + desc "New user name for the SDN controller" + location "body" + type "String" + optional true + since "5.3.28" + } + column { + name "password" + enclosedIn "changeSdnController" + desc "New password for the SDN controller" + location "body" + type "String" + optional true + since "5.3.28" + } + column { + name "systemTags" + enclosedIn "" + desc "System tags" + location "body" + type "List" + optional true + since "5.3.28" + } + column { + name "userTags" + enclosedIn "" + desc "User tags" + location "body" + type "List" + optional true + since "5.3.28" + } + column { + name "vlanRanges" + enclosedIn "changeSdnController" + desc "" + location "body" + type "List" + optional true + since "5.3.28" + } + } + } + + response { + clz APIChangeSdnControllerEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkEvent.java new file mode 100644 index 00000000000..2cad28a735b --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkEvent.java @@ -0,0 +1,31 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l2.APICreateL2NetworkEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; + +@RestResponse(allTo = "inventory") +public class APICreateL2HardwareVxlanNetworkEvent extends APICreateL2NetworkEvent { + public APICreateL2HardwareVxlanNetworkEvent(String apiId) { + super(apiId); + } + + public APICreateL2HardwareVxlanNetworkEvent() { + super(null); + } + + public static APICreateL2HardwareVxlanNetworkEvent __example__() { + APICreateL2HardwareVxlanNetworkEvent event = new APICreateL2HardwareVxlanNetworkEvent(); + L2VxlanNetworkInventory net = new L2VxlanNetworkInventory(); + + net.setName("Test-Net"); + net.setVni(10); + net.setDescription("Test"); + net.setZoneUuid(uuid()); + net.setPoolUuid(uuid()); + net.setType("L2VxlanNetwork"); + + event.setInventory(net); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..d87fbe0fbef --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.errorcode.ErrorCode +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory + +doc { + + title "VXLAN网路清单" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7" + clz ErrorCode.class + } + ref { + name "inventory" + path "org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkEvent.inventory" + desc "null" + type "L2VxlanNetworkInventory" + since "3.7" + clz L2VxlanNetworkInventory.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkMsg.java new file mode 100644 index 00000000000..55f71c8f8e5 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkMsg.java @@ -0,0 +1,89 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.OverriddenApiParam; +import org.zstack.header.message.OverriddenApiParams; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; +import org.zstack.header.zone.ZoneVO; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolConstant; + +@TagResourceType(SdnControllerVO.class) +@Action(category = VxlanNetworkPoolConstant.ACTION_CATEGORY) +@OverriddenApiParams({ + @OverriddenApiParam(field = "physicalInterface", param = @APIParam(maxLength = 1024, required = false)), + @OverriddenApiParam(field = "zoneUuid", param = @APIParam(maxLength = 1024, required = false, resourceType = ZoneVO.class)) +}) +@RestRequest( + path = "/l2-networks/hardware-vxlan", + method = HttpMethod.POST, + responseClass = APICreateL2HardwareVxlanNetworkEvent.class, + parameterName = "params" +) +public class APICreateL2HardwareVxlanNetworkMsg extends APICreateL2NetworkMsg { + @APIParam(required = false, numberRange = {1, 16777214}) + private Integer vni; + + @APIParam(required = true, resourceType = HardwareL2VxlanNetworkPoolVO.class) + private String poolUuid; + + @APIParam(required = false, resourceType = H3cSdnControllerTenantVO.class) + private String h3cTenantUuid; + + @APIParam(required = false, numberRange = {1, 4095}) + private Integer vlan; + + public Integer getVni() { + return vni; + } + + @Override + public String getType() { + return SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE; + } + + public void setVni(int vni) { + this.vni = vni; + } + + public String getPoolUuid() { + return poolUuid; + } + + public void setPoolUuid(String poolUuid) { + this.poolUuid = poolUuid; + } + + public String getH3cTenantUuid() { + return h3cTenantUuid; + } + + public void setH3cTenantUuid(String h3cTenantUuid) { + this.h3cTenantUuid = h3cTenantUuid; + } + + public Integer getVlan() { + return vlan; + } + + public void setVlan(Integer vlan) { + this.vlan = vlan; + } + + public static APICreateL2HardwareVxlanNetworkMsg __example__() { + APICreateL2HardwareVxlanNetworkMsg msg = new APICreateL2HardwareVxlanNetworkMsg(); + + msg.setName("Test-Net"); + msg.setVni(10); + msg.setDescription("Test"); + msg.setZoneUuid(uuid()); + msg.setPoolUuid(uuid()); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..863f275cbe4 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkMsgDoc_zh_cn.groovy @@ -0,0 +1,176 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkEvent + +doc { + title "CreateL2HardwareVxlanNetwork" + + category "network.l2" + + desc """创建硬件VXLAN网络""" + + rest { + request { + url "POST /v1/l2-networks/hardware-vxlan" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateL2HardwareVxlanNetworkMsg.class + + desc """""" + + params { + + column { + name "vni" + enclosedIn "params" + desc "Vni号" + location "body" + type "Integer" + optional true + since "3.7" + } + column { + name "poolUuid" + enclosedIn "params" + desc "VXLAN资源池UUID" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "zoneUuid" + enclosedIn "params" + desc "区域UUID" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "physicalInterface" + enclosedIn "params" + desc "物理网卡" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "type" + enclosedIn "params" + desc "二层网络类型" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID。若指定,二层网络会使用该字段值作为UUID" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "vSwitchType" + enclosedIn "params" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "0.6" + values ("LinuxBridge","OvsDpdk","MacVlan") + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" + } + column { + name "h3cTenantUuid" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "5.3.28" + } + column { + name "vlan" + enclosedIn "params" + desc "" + location "body" + type "Integer" + optional true + since "5.4.0" + } + } + } + + response { + clz APICreateL2HardwareVxlanNetworkEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolEvent.java new file mode 100644 index 00000000000..5841ec9e943 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolEvent.java @@ -0,0 +1,33 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l2.APICreateL2NetworkEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.rest.RestResponse; + +/** + * Created by shixin.ruan on 09/30/2019. + */ +@RestResponse(allTo = "inventory") +public class APICreateL2HardwareVxlanNetworkPoolEvent extends APICreateL2NetworkEvent { + public APICreateL2HardwareVxlanNetworkPoolEvent(String apiId) { + super(apiId); + } + + public APICreateL2HardwareVxlanNetworkPoolEvent() { + super(null); + } + + public static APICreateL2HardwareVxlanNetworkPoolEvent __example__() { + APICreateL2HardwareVxlanNetworkPoolEvent event = new APICreateL2HardwareVxlanNetworkPoolEvent(); + HardwareL2VxlanNetworkPoolInventory net = new HardwareL2VxlanNetworkPoolInventory(); + + net.setName("Test-NetPool"); + net.setDescription("Test"); + net.setZoneUuid(uuid()); + net.setType(SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE); + net.setSdnControllerUuid(uuid()); + + event.setInventory(net); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..3047657d187 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolEventDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.sdnController.header + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "硬件VXLAN资源池清单" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkPoolEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7" + clz ErrorCode.class + } + ref { + name "inventory" + path "org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkPoolEvent.inventory" + desc "null" + type "HardwareL2VxlanNetworkPoolInventory" + since "3.7" + clz HardwareL2VxlanNetworkPoolInventory.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolMsg.java new file mode 100644 index 00000000000..17a9a7b3ea9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolMsg.java @@ -0,0 +1,44 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/l2-networks/hardware-vxlan-pool", + method = HttpMethod.POST, + responseClass = APICreateL2HardwareVxlanNetworkPoolEvent.class, + parameterName = "params" +) +public class APICreateL2HardwareVxlanNetworkPoolMsg extends APICreateL2NetworkMsg { + @APIParam(resourceType = SdnControllerVO.class) + private String sdnControllerUuid; + + @Override + public String getType() { + return SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public static APICreateL2HardwareVxlanNetworkPoolMsg __example__() { + APICreateL2HardwareVxlanNetworkPoolMsg msg = new APICreateL2HardwareVxlanNetworkPoolMsg(); + + msg.setName("Test-NetPool"); + msg.setDescription("Test"); + msg.setZoneUuid(uuid()); + msg.setSdnControllerUuid(uuid()); + msg.setPhysicalInterface("bond0"); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..ec4edea5cc7 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APICreateL2HardwareVxlanNetworkPoolMsgDoc_zh_cn.groovy @@ -0,0 +1,167 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APICreateL2HardwareVxlanNetworkPoolEvent + +doc { + title "CreateL2HardwareVxlanNetworkPool" + + category "network.l2" + + desc """创建硬件VXLAN资源池""" + + rest { + request { + url "POST /v1/l2-networks/hardware-vxlan-pool" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateL2HardwareVxlanNetworkPoolMsg.class + + desc """""" + + params { + + column { + name "sdnControllerUuid" + enclosedIn "params" + desc "SDN控制器UUID" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "zoneUuid" + enclosedIn "params" + desc "区域UUID" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "physicalInterface" + enclosedIn "params" + desc "物理网卡" + location "body" + type "String" + optional false + since "3.7" + } + column { + name "type" + enclosedIn "params" + desc "二层网络类型" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID。若指定,二层网络会使用该字段值作为UUID" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "vSwitchType" + enclosedIn "params" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "4.1.2" + values ("LinuxBridge","OvsDpdk","MacVlan") + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" + } + column { + name "startVlan" + enclosedIn "params" + desc "" + location "body" + type "Integer" + optional true + since "5.3.28" + } + column { + name "endVlan" + enclosedIn "params" + desc "" + location "body" + type "Integer" + optional true + since "5.3.28" + } + } + } + + response { + clz APICreateL2HardwareVxlanNetworkPoolEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantEvent.java new file mode 100644 index 00000000000..e0e536b323f --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantEvent.java @@ -0,0 +1,38 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by boce.wang on 06/13/2025. + */ + +@RestResponse(allTo = "inventories") +public class APIPullSdnControllerTenantEvent extends APIEvent { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public APIPullSdnControllerTenantEvent(){ + } + + public APIPullSdnControllerTenantEvent(String apiId) { + super(apiId); + } + + public static APIPullSdnControllerTenantEvent __example__() { + APIPullSdnControllerTenantEvent event = new APIPullSdnControllerTenantEvent(); + List inventories = new ArrayList<>(); + event.setInventories(inventories); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..a32bca97ab3 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.H3cSdnControllerTenantInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "拉取SDN控制器租户结果" + + ref { + name "inventories" + path "org.zstack.sdnController.header.APIPullSdnControllerTenantEvent.inventories" + desc "null" + type "List" + since "5.3.28" + clz H3cSdnControllerTenantInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.28" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIPullSdnControllerTenantEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.28" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantMsg.java new file mode 100644 index 00000000000..c2dbc23c40c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantMsg.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +/** + * Created by boce.wang on 06/13/2025. + */ + +@RestRequest( + path = "/sdn-controllers/{uuid}/tenant/actions", + method = HttpMethod.PUT, + responseClass = APIPullSdnControllerTenantEvent.class, + isAction = true +) +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +public class APIPullSdnControllerTenantMsg extends APIMessage implements SdnControllerMessage { + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getSdnControllerUuid() { + return uuid; + } + + public static APIPullSdnControllerTenantMsg __example__() { + APIPullSdnControllerTenantMsg msg = new APIPullSdnControllerTenantMsg(); + msg.setUuid(uuid()); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..420c5c2d677 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIPullSdnControllerTenantMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIPullSdnControllerTenantEvent + +doc { + title "PullSdnControllerTenant" + + category "SdnController" + + desc """拉取SDN控制器租户""" + + rest { + request { + url "PUT /v1/sdn-controllers/{uuid}/tenant/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIPullSdnControllerTenantMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "pullSdnControllerTenant" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "5.3.28" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.28" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.28" + } + } + } + + response { + clz APIPullSdnControllerTenantEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerMsg.java new file mode 100644 index 00000000000..bd092b0194b --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerMsg.java @@ -0,0 +1,35 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +/** + * Created with IntelliJ IDEA. + * User: frank + * Time: 8:34 PM + * To change this template use File | Settings | File Templates. + */ +@AutoQuery(replyClass = APIQuerySdnControllerReply.class, inventoryClass = SdnControllerInventory.class) +@Action(category = SdnControllerConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/sdn-controllers", + optionalPaths = {"/sdn-controllers/{uuid}"}, + method = HttpMethod.GET, + responseClass = APIQuerySdnControllerReply.class +) +public class APIQuerySdnControllerMsg extends APIQueryMessage { + + public static List __example__() { + return asList("uuid=" + uuid()); + } + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..c43c38a78b0 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIQuerySdnControllerReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QuerySdnController" + + category "SdnController" + + desc """查询SDN控制器""" + + rest { + request { + url "GET /v1/sdn-controllers" + url "GET /v1/sdn-controllers/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQuerySdnControllerMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQuerySdnControllerReply.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerReply.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerReply.java new file mode 100644 index 00000000000..e678c696c41 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerReply.java @@ -0,0 +1,45 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +import static org.zstack.utils.CollectionDSL.list; + +/** + * Created with IntelliJ IDEA. + * User: frank + * Time: 8:35 PM + * To change this template use File | Settings | File Templates. + */ +@RestResponse(allTo = "inventories") +public class APIQuerySdnControllerReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQuerySdnControllerReply __example__() { + APIQuerySdnControllerReply reply = new APIQuerySdnControllerReply(); + + SdnControllerInventory sdn = new SdnControllerInventory(); + sdn.setName("test-sdn"); + sdn.setUuid(uuid()); + sdn.setDescription("sdn for test"); + sdn.setIp("192.168.1.1"); + sdn.setUsername("admin"); + sdn.setPassword("password"); + + + reply.setInventories(list(sdn)); + return reply; + } + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerReplyDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..ddbc0982463 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIQuerySdnControllerReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.errorcode.ErrorCode +import org.zstack.header.network.sdncontroller.SdnControllerInventory + +doc { + + title "SDN控制器清单" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIQuerySdnControllerReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7" + clz ErrorCode.class + } + ref { + name "inventories" + path "org.zstack.sdnController.header.APIQuerySdnControllerReply.inventories" + desc "null" + type "List" + since "3.7" + clz SdnControllerInventory.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerEvent.java new file mode 100644 index 00000000000..8c8b350fc20 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerEvent.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +/** + * Created by shixin.ruan on 09/19/2019. + */ +@RestResponse(allTo = "inventory") +public class APIReconnectSdnControllerEvent extends APIEvent { + private SdnControllerInventory inventory; + + public SdnControllerInventory getInventory() { + return inventory; + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public APIReconnectSdnControllerEvent() { + } + + public APIReconnectSdnControllerEvent(String apiId) { + super(apiId); + } + + public static APIReconnectSdnControllerEvent __example__() { + APIReconnectSdnControllerEvent event = new APIReconnectSdnControllerEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + inventory.setName("sdn-1"); + inventory.setDescription("sdn controller from vendor"); + inventory.setIp("192.168.1.1"); + inventory.setUsername("admin"); + inventory.setPassword("password"); + + event.setInventory(inventory); + return event; + } + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..658780d216a --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.network.sdncontroller.SdnControllerInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "重连SDN控制器清单" + + ref { + name "inventory" + path "org.zstack.sdnController.header.APIReconnectSdnControllerEvent.inventory" + desc "null" + type "SdnControllerInventory" + since "5.3.0" + clz SdnControllerInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.0" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIReconnectSdnControllerEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.0" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerMsg.java new file mode 100644 index 00000000000..0ecdf5c9615 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerMsg.java @@ -0,0 +1,41 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +/** + * Created by shixin.ruan on 01/04/2024. + */ +@RestRequest( + path = "/sdn-controllers/{sdnControllerUuid}/actions", + method = HttpMethod.PUT, + responseClass = APIReconnectSdnControllerEvent.class, + isAction = true +) +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +public class APIReconnectSdnControllerMsg extends APIMessage implements SdnControllerMessage { + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String sdnControllerUuid; + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public static APIReconnectSdnControllerMsg __example__() { + APIReconnectSdnControllerMsg msg = new APIReconnectSdnControllerMsg(); + msg.setSdnControllerUuid(uuid()); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..4343981688d --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIReconnectSdnControllerMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIReconnectSdnControllerEvent + +doc { + title "ReconnectSdnController" + + category "SdnController" + + desc """重连SDN控制器""" + + rest { + request { + url "PUT /v1/sdn-controllers/{sdnControllerUuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIReconnectSdnControllerMsg.class + + desc """""" + + params { + + column { + name "sdnControllerUuid" + enclosedIn "reconnectSdnController" + desc "" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.0" + } + } + } + + response { + clz APIReconnectSdnControllerEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerEvent.java new file mode 100644 index 00000000000..702cdd0e3cb --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerEvent.java @@ -0,0 +1,22 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIRemoveSdnControllerEvent extends APIEvent { + + public APIRemoveSdnControllerEvent() { + super(null); + } + + public APIRemoveSdnControllerEvent(String apiId) { + super(apiId); + } + + public static APIRemoveSdnControllerEvent __example__() { + APIRemoveSdnControllerEvent event = new APIRemoveSdnControllerEvent(); + return event; + } + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..052e745f1bf --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.sdnController.header + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "SDN控制器清单" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIRemoveSdnControllerEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerMsg.java new file mode 100644 index 00000000000..78c805b44d0 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerMsg.java @@ -0,0 +1,42 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIDeleteMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +@RestRequest( + path = "/sdn-controllers/{uuid}", + method = HttpMethod.DELETE, + responseClass = APIRemoveSdnControllerEvent.class +) +public class APIRemoveSdnControllerMsg extends APIDeleteMessage implements SdnControllerMessage { + @APIParam(checkAccount = true, operationTarget = true, successIfResourceNotExisting = true, resourceType = SdnControllerVO.class) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getSdnControllerUuid() { + return uuid; + } + + public static APIRemoveSdnControllerMsg __example__() { + APIRemoveSdnControllerMsg msg = new APIRemoveSdnControllerMsg(); + + msg.setUuid(uuid()); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..071e93a6f3d --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIRemoveSdnControllerMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIRemoveSdnControllerEvent + +doc { + title "RemoveSdnController" + + category "SdnController" + + desc """删除SDN控制器""" + + rest { + request { + url "DELETE /v1/sdn-controllers/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIRemoveSdnControllerMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "3.7" + } + column { + name "deleteMode" + enclosedIn "" + desc "" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "systemTags" + enclosedIn "" + desc "" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "userTags" + enclosedIn "" + desc "" + location "body" + type "List" + optional true + since "3.7" + } + } + } + + response { + clz APIRemoveSdnControllerEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostEvent.java new file mode 100644 index 00000000000..4014d2a6d23 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostEvent.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APISdnControllerAddHostEvent extends APIEvent { + /** + * @desc see :ref:`SdnControllerInventory` + */ + private SdnControllerInventory inventory; + + public APISdnControllerAddHostEvent(String apiId) { + super(apiId); + } + + public SdnControllerInventory getInventory() { + return inventory; + } + + public APISdnControllerAddHostEvent() { + super(null); + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public static APISdnControllerAddHostEvent __example__() { + APISdnControllerAddHostEvent event = new APISdnControllerAddHostEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + inventory.setName("sdn-1"); + inventory.setDescription("sdn controller from vendor"); + inventory.setIp("192.168.1.1"); + inventory.setUsername("admin"); + inventory.setPassword("password"); + + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..b7a2ac7c56c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.network.sdncontroller.SdnControllerInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "SDN控制器添加物理机清单" + + ref { + name "inventory" + path "org.zstack.sdnController.header.APISdnControllerAddHostEvent.inventory" + desc "null" + type "SdnControllerInventory" + since "5.3.0" + clz SdnControllerInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.0" + } + ref { + name "error" + path "org.zstack.sdnController.header.APISdnControllerAddHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.0" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostMsg.java new file mode 100644 index 00000000000..a4d8b601cdd --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostMsg.java @@ -0,0 +1,152 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostVO; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +@RestRequest( + path = "/sdn-controllers/{sdnControllerUuid}/hosts/{hostUuid}", + method = HttpMethod.POST, + responseClass = APISdnControllerAddHostEvent.class, + parameterName = "null" +) +public class APISdnControllerAddHostMsg extends APIMessage implements SdnControllerMessage { + /** + * @desc l2Network uuid + */ + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String sdnControllerUuid; + /** + * @desc cluster uuid. See :ref:`ClusterInventory` + */ + @APIParam(resourceType = HostVO.class) + private String hostUuid; + + /** + * @desc vSwitch type + */ + @APIParam(required = false, validValues = {"OvnDpdk", "OvnKernel"}) + private String vSwitchType = "OvnDpdk"; + + /** + * @desc physical nics used by vSwitchType + */ + @APIParam(nonempty = true) + private List nicNames; + + /** + * @desc VTEP (VXLAN Tunnel End Point) IP address + */ + @APIParam(required = false) + private String vtepIp; + + /** + * @desc Netmask for the VTEP IP address + */ + @APIParam(required = false) + private String netmask; + + /** + * @desc bonding mode + */ + @APIParam(required = false) + private String bondMode; + + /** + * @desc lacp mode + */ + @APIParam(required = false) + private String lacpMode; + + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + + public List getNicNames() { + return nicNames; + } + + public void setNicNames(List nicNames) { + this.nicNames = nicNames; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + public String getBondMode() { + return bondMode; + } + + public void setBondMode(String bondMode) { + this.bondMode = bondMode; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getLacpMode() { + return lacpMode; + } + + public void setLacpMode(String lacpMode) { + this.lacpMode = lacpMode; + } + + + public static APISdnControllerAddHostMsg __example__() { + APISdnControllerAddHostMsg msg = new APISdnControllerAddHostMsg(); + + msg.setSdnControllerUuid(uuid()); + msg.setHostUuid(uuid()); + msg.setvSwitchType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + msg.setVtepIp("192.168.1.101"); + msg.setNetmask("255.255.255.0"); + msg.setNetmask("ens1 ens2"); + msg.setBondMode(L2NetworkConstant.BONDING_MODE_AB); + msg.setLacpMode(L2NetworkConstant.LACP_MODE_OFF); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..1183e68acac --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerAddHostMsgDoc_zh_cn.groovy @@ -0,0 +1,122 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APISdnControllerAddHostEvent + +doc { + title "SdnControllerAddHost" + + category "SdnController" + + desc """SDN控制器添加物理机""" + + rest { + request { + url "POST /v1/sdn-controllers/{sdnControllerUuid}/hosts/{hostUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APISdnControllerAddHostMsg.class + + desc """""" + + params { + + column { + name "sdnControllerUuid" + enclosedIn "" + desc "SDN控制器Uuid" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "hostUuid" + enclosedIn "" + desc "物理机UUID" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "vSwitchType" + enclosedIn "" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "5.3.0" + values ("OvsKernel","OvsDpdk","SRIOV") + } + column { + name "nicNames" + enclosedIn "" + desc "物理机网卡名称列表" + location "body" + type "List" + optional false + since "5.3.0" + } + column { + name "vtepIp" + enclosedIn "" + desc "物理机VTEP IP" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "netmask" + enclosedIn "" + desc "物理机VTEP IP掩码" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "bondMode" + enclosedIn "" + desc "物理机网卡bond模式" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "lacpMode" + enclosedIn "" + desc "物理机网卡LACP模式" + location "body" + type "String" + optional true + since "5.3.0" + } + } + } + + response { + clz APISdnControllerAddHostEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostEvent.java new file mode 100644 index 00000000000..ab86e2d07a9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostEvent.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APISdnControllerChangeHostEvent extends APIEvent { + /** + * @desc see :ref:`SdnControllerInventory` + */ + private SdnControllerInventory inventory; + + public APISdnControllerChangeHostEvent(String apiId) { + super(apiId); + } + + public SdnControllerInventory getInventory() { + return inventory; + } + + public APISdnControllerChangeHostEvent() { + super(null); + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public static APISdnControllerChangeHostEvent __example__() { + APISdnControllerChangeHostEvent event = new APISdnControllerChangeHostEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + inventory.setName("sdn-1"); + inventory.setDescription("sdn controller from vendor"); + inventory.setIp("192.168.1.1"); + inventory.setUsername("admin"); + inventory.setPassword("password"); + + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..a75ee6d301d --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.network.sdncontroller.SdnControllerInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "SDN控制器修改物理机清单" + + ref { + name "inventory" + path "org.zstack.sdnController.header.APISdnControllerChangeHostEvent.inventory" + desc "null" + type "SdnControllerInventory" + since "5.3.0" + clz SdnControllerInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.0" + } + ref { + name "error" + path "org.zstack.sdnController.header.APISdnControllerChangeHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.0" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostMsg.java new file mode 100644 index 00000000000..2dd5780b76c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostMsg.java @@ -0,0 +1,150 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostVO; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +@RestRequest( + path = "/sdn-controllers/{sdnControllerUuid}/hosts/{hostUuid}/actions", + method = HttpMethod.PUT, + responseClass = APISdnControllerChangeHostEvent.class, + isAction = true +) +public class APISdnControllerChangeHostMsg extends APIMessage implements SdnControllerMessage { + /** + * @desc l2Network uuid + */ + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String sdnControllerUuid; + /** + * @desc cluster uuid. See :ref:`ClusterInventory` + */ + @APIParam(resourceType = HostVO.class) + private String hostUuid; + + /** + * @desc vSwitch type + */ + @APIParam(required = false, validValues = {"OvnDpdk", "OvnKernel"}) + private String vSwitchType = "OvnDpdk"; + + /** + * @desc physical nics used by vSwitchType + */ + @APIParam(nonempty = true, required = false) + private List nicNames; + + /** + * @desc physical nics used by vSwitchType + */ + @APIParam(required = false) + private String vtepIp; + + /** + * @desc physical nics used by vSwitchType + */ + @APIParam(required = false) + private String netmask; + + /** + * @desc bonding mode + */ + @APIParam(required = false) + private String bondMode; + + /** + * @desc lacp mode + */ + @APIParam(required = false) + private String lacpMode; + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + + public List getNicNames() { + return nicNames; + } + + public void setNicNames(List nicNames) { + this.nicNames = nicNames; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + public String getBondMode() { + return bondMode; + } + + public void setBondMode(String bondMode) { + this.bondMode = bondMode; + } + + public String getNetmask() { + return netmask; + } + + public void setNetmask(String netmask) { + this.netmask = netmask; + } + + public String getLacpMode() { + return lacpMode; + } + + public void setLacpMode(String lacpMode) { + this.lacpMode = lacpMode; + } + + public static APISdnControllerChangeHostMsg __example__() { + APISdnControllerChangeHostMsg msg = new APISdnControllerChangeHostMsg(); + + msg.setSdnControllerUuid(uuid()); + msg.setHostUuid(uuid()); + msg.setvSwitchType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + msg.setVtepIp("192.168.1.101"); + msg.setNetmask("255.255.255.0"); + msg.setNetmask("ens1 ens2"); + msg.setBondMode(L2NetworkConstant.BONDING_MODE_AB); + msg.setLacpMode(L2NetworkConstant.LACP_MODE_OFF); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..829c5465372 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerChangeHostMsgDoc_zh_cn.groovy @@ -0,0 +1,122 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APISdnControllerChangeHostEvent + +doc { + title "SdnControllerChangeHost" + + category "SdnController" + + desc """SDN控制器修改物理机""" + + rest { + request { + url "PUT /v1/sdn-controllers/{sdnControllerUuid}/hosts/{hostUuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APISdnControllerChangeHostMsg.class + + desc """""" + + params { + + column { + name "sdnControllerUuid" + enclosedIn "sdnControllerChangeHost" + desc "SDN控制器Uuid" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "hostUuid" + enclosedIn "sdnControllerChangeHost" + desc "物理机UUID" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "vSwitchType" + enclosedIn "sdnControllerChangeHost" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "5.3.0" + values ("OvnDpdk","OvnKernel") + } + column { + name "nicNames" + enclosedIn "sdnControllerChangeHost" + desc "物理机网卡名称列表" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "vtepIp" + enclosedIn "sdnControllerChangeHost" + desc "物理机VTEP IP" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "netmask" + enclosedIn "sdnControllerChangeHost" + desc "物理机VTEP IP掩码" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "bondMode" + enclosedIn "sdnControllerChangeHost" + desc "物理机网卡bond模式" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "lacpMode" + enclosedIn "sdnControllerChangeHost" + desc "物理机网卡LACP模式" + location "body" + type "String" + optional true + since "5.3.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.0" + } + } + } + + response { + clz APISdnControllerChangeHostEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostEvent.java new file mode 100644 index 00000000000..8229b842df2 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostEvent.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APISdnControllerRemoveHostEvent extends APIEvent { + /** + * @desc see :ref:`SdnControllerInventory` + */ + private SdnControllerInventory inventory; + + public APISdnControllerRemoveHostEvent(String apiId) { + super(apiId); + } + + public SdnControllerInventory getInventory() { + return inventory; + } + + public APISdnControllerRemoveHostEvent() { + super(null); + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public static APISdnControllerRemoveHostEvent __example__() { + APISdnControllerRemoveHostEvent event = new APISdnControllerRemoveHostEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + inventory.setName("sdn-1"); + inventory.setDescription("sdn controller from vendor"); + inventory.setIp("192.168.1.1"); + inventory.setUsername("admin"); + inventory.setPassword("password"); + + event.setInventory(inventory); + return event; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..d84ebbca9cd --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.network.sdncontroller.SdnControllerInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "SDN控制器删除物理机清单" + + ref { + name "inventory" + path "org.zstack.sdnController.header.APISdnControllerRemoveHostEvent.inventory" + desc "null" + type "SdnControllerInventory" + since "5.3.0" + clz SdnControllerInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "5.3.0" + } + ref { + name "error" + path "org.zstack.sdnController.header.APISdnControllerRemoveHostEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "5.3.0" + clz ErrorCode.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostMsg.java new file mode 100644 index 00000000000..6606c033c09 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostMsg.java @@ -0,0 +1,72 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.host.HostVO; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + + +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +@RestRequest( + path = "/sdn-controllers/{sdnControllerUuid}/hosts/{hostUuid}", + method = HttpMethod.DELETE, + responseClass = APISdnControllerRemoveHostEvent.class +) +public class APISdnControllerRemoveHostMsg extends APIMessage implements SdnControllerMessage { + /** + * @desc l2Network uuid + */ + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String sdnControllerUuid; + /** + * @desc cluster uuid. See :ref:`ClusterInventory` + */ + @APIParam(resourceType = HostVO.class) + private String hostUuid; + + /** + * @desc vSwitch type + */ + @APIParam(required = false, validValues = {"OvnDpdk", "OvnKernel"}) + private String vSwitchType = "OvnDpdk"; + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + + public static APISdnControllerRemoveHostMsg __example__() { + APISdnControllerRemoveHostMsg msg = new APISdnControllerRemoveHostMsg(); + + msg.setSdnControllerUuid(uuid()); + msg.setHostUuid(uuid()); + msg.setvSwitchType("OvnDpdk"); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..6e52d34edad --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APISdnControllerRemoveHostMsgDoc_zh_cn.groovy @@ -0,0 +1,77 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APISdnControllerRemoveHostEvent + +doc { + title "SdnControllerRemoveHost" + + category "SdnController" + + desc """SDN控制器移除物理机""" + + rest { + request { + url "DELETE /v1/sdn-controllers/{sdnControllerUuid}/hosts/{hostUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APISdnControllerRemoveHostMsg.class + + desc """""" + + params { + + column { + name "sdnControllerUuid" + enclosedIn "" + desc "SDN控制器Uuid" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "hostUuid" + enclosedIn "" + desc "物理机UUID" + location "url" + type "String" + optional false + since "5.3.0" + } + column { + name "vSwitchType" + enclosedIn "" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "5.3.0" + values ("OvnDpdk","OvnKernel") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "5.3.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "5.3.0" + } + } + } + + response { + clz APISdnControllerRemoveHostEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerEvent.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerEvent.java new file mode 100644 index 00000000000..3d720302ef9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerEvent.java @@ -0,0 +1,46 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.rest.RestResponse; + +/** + * Created by shixin.ruan on 09/19/2019. + */ +@RestResponse(allTo = "inventory") +public class APIUpdateSdnControllerEvent extends APIEvent { + private SdnControllerInventory inventory; + + public SdnControllerInventory getInventory() { + return inventory; + } + + public void setInventory(SdnControllerInventory inventory) { + this.inventory = inventory; + } + + public APIUpdateSdnControllerEvent() { + } + + public APIUpdateSdnControllerEvent(String apiId) { + super(apiId); + } + + public static APIUpdateSdnControllerEvent __example__() { + APIUpdateSdnControllerEvent event = new APIUpdateSdnControllerEvent(); + SdnControllerInventory inventory = new SdnControllerInventory(); + + inventory.setUuid(uuid()); + inventory.setVendorType(SdnControllerConstant.H3C_VCFC_CONTROLLER); + inventory.setName("sdn-1"); + inventory.setDescription("sdn controller from vendor"); + inventory.setIp("192.168.1.1"); + inventory.setUsername("admin"); + inventory.setPassword("password"); + + event.setInventory(inventory); + return event; + } + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerEventDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..5977a9e0a92 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.sdnController.header + +import org.zstack.header.errorcode.ErrorCode +import org.zstack.header.network.sdncontroller.SdnControllerInventory + +doc { + + title "SDN控制器清单" + + field { + name "success" + desc "" + type "boolean" + since "0.6" + } + ref { + name "error" + path "org.zstack.sdnController.header.APIUpdateSdnControllerEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "3.7" + clz ErrorCode.class + } + ref { + name "inventory" + path "org.zstack.sdnController.header.APIUpdateSdnControllerEvent.inventory" + desc "null" + type "SdnControllerInventory" + since "3.7" + clz SdnControllerInventory.class + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerMsg.java new file mode 100644 index 00000000000..7ec4d9f4029 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerMsg.java @@ -0,0 +1,67 @@ +package org.zstack.sdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.rest.RestRequest; + +/** + * Created by shixin.ruan on 09/19/2019. + */ +@RestRequest( + path = "/sdn-controllers/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIUpdateSdnControllerEvent.class, + isAction = true +) +@Action(category = SdnControllerConstant.ACTION_CATEGORY) +public class APIUpdateSdnControllerMsg extends APIMessage implements SdnControllerMessage { + @APIParam(resourceType = SdnControllerVO.class, checkAccount = true, operationTarget = true) + private String uuid; + @APIParam(maxLength = 255, required = false) + private String name; + @APIParam(maxLength = 2048, required = false) + private String description; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String getSdnControllerUuid() { + return uuid; + } + + public static APIUpdateSdnControllerMsg __example__() { + APIUpdateSdnControllerMsg msg = new APIUpdateSdnControllerMsg(); + msg.setUuid(uuid()); + msg.setName("Test-Net"); + msg.setDescription("Test"); + + return msg; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerMsgDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..113ea612cf9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/APIUpdateSdnControllerMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.sdnController.header + +import org.zstack.sdnController.header.APIUpdateSdnControllerEvent + +doc { + title "UpdateSdnController" + + category "SdnController" + + desc """更新SDN控制器""" + + rest { + request { + url "PUT /v1/sdn-controllers/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateSdnControllerMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "updateSdnController" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "3.7" + } + column { + name "name" + enclosedIn "updateSdnController" + desc "资源名称" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "description" + enclosedIn "updateSdnController" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "3.7" + } + column { + name "systemTags" + enclosedIn "" + desc "" + location "body" + type "List" + optional true + since "3.7" + } + column { + name "userTags" + enclosedIn "" + desc "" + location "body" + type "List" + optional true + since "3.7" + } + } + } + + response { + clz APIUpdateSdnControllerEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantInventory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantInventory.java new file mode 100644 index 00000000000..787f93dbd9d --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantInventory.java @@ -0,0 +1,135 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created by boce.wang on 06/16/2025. + */ +@Inventory(mappingVOClass = H3cSdnControllerTenantVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "sdnController", inventoryClass = SdnControllerInventory.class, + foreignKey = "sdnControllerUuid", expandedInventoryKey = "uuid") +}) +public class H3cSdnControllerTenantInventory { + private String uuid; + private String sdnControllerUuid; + private String tenantUuid; + private String vdsUuid; + private String tenantName; + private String vdsName; + private String cloudDomainName; + private String state; + private Timestamp createDate; + private Timestamp lastOpDate; + + public static H3cSdnControllerTenantInventory valueOf(H3cSdnControllerTenantVO vo) { + H3cSdnControllerTenantInventory inv = new H3cSdnControllerTenantInventory(); + inv.setUuid(vo.getUuid()); + inv.setSdnControllerUuid(vo.getSdnControllerUuid()); + inv.setTenantUuid(vo.getTenantUuid()); + inv.setVdsUuid(vo.getVdsUuid()); + inv.setTenantName(vo.getTenantName()); + inv.setVdsName(vo.getVdsName()); + inv.setCloudDomainName(vo.getCloudDomainName()); + inv.setState(vo.getState()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList(); + for (H3cSdnControllerTenantVO vo : vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getTenantUuid() { + return tenantUuid; + } + + public void setTenantUuid(String tenantUuid) { + this.tenantUuid = tenantUuid; + } + + public String getVdsUuid() { + return vdsUuid; + } + + public void setVdsUuid(String vdsUuid) { + this.vdsUuid = vdsUuid; + } + + public String getTenantName() { + return tenantName; + } + + public void setTenantName(String tenantName) { + this.tenantName = tenantName; + } + + public String getVdsName() { + return vdsName; + } + + public void setVdsName(String vdsName) { + this.vdsName = vdsName; + } + + public String getCloudDomainName() { + return cloudDomainName; + } + + public void setCloudDomainName(String cloudDomainName) { + this.cloudDomainName = cloudDomainName; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantInventoryDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..f0232fe9282 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantInventoryDoc_zh_cn.groovy @@ -0,0 +1,69 @@ +package org.zstack.sdnController.header + +import java.sql.Timestamp + +doc { + + title "SDN控制器租户清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.3.28" + } + field { + name "sdnControllerUuid" + desc "" + type "String" + since "5.3.28" + } + field { + name "tenantUuid" + desc "" + type "String" + since "5.3.28" + } + field { + name "vdsUuid" + desc "" + type "String" + since "5.3.28" + } + field { + name "tenantName" + desc "" + type "String" + since "5.3.28" + } + field { + name "vdsName" + desc "" + type "String" + since "5.3.28" + } + field { + name "cloudDomainName" + desc "" + type "String" + since "5.3.28" + } + field { + name "status" + desc "" + type "String" + since "5.3.28" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.3.28" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.3.28" + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantVO.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantVO.java new file mode 100644 index 00000000000..3d50629bede --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantVO.java @@ -0,0 +1,133 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * Created by boce.wang on 06/13/2025. + */ +@Entity +@Table +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = SdnControllerVO.class, myField = "sdnControllerUuid", targetField = "uuid"), + } +) +public class H3cSdnControllerTenantVO { + + @Column + @Id + private String uuid; + + @Column + @ForeignKey(parentEntityClass = SdnControllerVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String sdnControllerUuid; + + @Column + private String tenantUuid; + @Column + private String vdsUuid; + @Column + private String tenantName; + @Column + private String vdsName; + @Column + private String cloudDomainName; + @Column + private String state; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getTenantUuid() { + return tenantUuid; + } + + public void setTenantUuid(String tenantUuid) { + this.tenantUuid = tenantUuid; + } + + public String getVdsUuid() { + return vdsUuid; + } + + public void setVdsUuid(String vdsUuid) { + this.vdsUuid = vdsUuid; + } + + public String getTenantName() { + return tenantName; + } + + public void setTenantName(String tenantName) { + this.tenantName = tenantName; + } + + public String getVdsName() { + return vdsName; + } + + public void setVdsName(String vdsName) { + this.vdsName = vdsName; + } + + public String getCloudDomainName() { + return cloudDomainName; + } + + public void setCloudDomainName(String cloudDomainName) { + this.cloudDomainName = cloudDomainName; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantVO_.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantVO_.java new file mode 100644 index 00000000000..e93073735b1 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnControllerTenantVO_.java @@ -0,0 +1,22 @@ +package org.zstack.sdnController.header; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by boce.wang on 06/16/2025. + */ +@StaticMetamodel(H3cSdnControllerTenantVO.class) +public class H3cSdnControllerTenantVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute sdnControllerUuid; + public static volatile SingularAttribute tenantUuid; + public static volatile SingularAttribute vdsUuid; + public static volatile SingularAttribute tenantName; + public static volatile SingularAttribute vdsName; + public static volatile SingularAttribute cloudDomainName; + public static volatile SingularAttribute state; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnSubnetIpRangeRefVO.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnSubnetIpRangeRefVO.java new file mode 100644 index 00000000000..4d7ef95fcfd --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnSubnetIpRangeRefVO.java @@ -0,0 +1,110 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l3.IpRangeEO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ForeignKey.ReferenceOption; + +import javax.persistence.*; +import java.sql.Timestamp; + +/** + * Created by boce.wang on 07/02/2025. + */ + +@Entity +@Table +@org.zstack.header.vo.EntityGraph( + friends = { + @EntityGraph.Neighbour(type = SdnControllerVO.class, myField = "sdnControllerUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = IpRangeEO.class, myField = "ipRangeUuid", targetField = "uuid") + } +) +public class H3cSdnSubnetIpRangeRefVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + @ForeignKey(parentEntityClass = SdnControllerVO.class, onDeleteAction = ReferenceOption.CASCADE) + private String sdnControllerUuid; + + @Column + @ForeignKey(parentEntityClass = IpRangeEO.class, onDeleteAction = ReferenceOption.CASCADE) + private String ipRangeUuid; + + @Column + private String subnetUuid; + + @Column + private String l2NetworkUuid; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getIpRangeUuid() { + return ipRangeUuid; + } + + public void setIpRangeUuid(String ipRangeUuid) { + this.ipRangeUuid = ipRangeUuid; + } + + public String getSubnetUuid() { + return subnetUuid; + } + + public void setSubnetUuid(String subnetUuid) { + this.subnetUuid = subnetUuid; + } + + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnSubnetIpRangeRefVO_.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnSubnetIpRangeRefVO_.java new file mode 100644 index 00000000000..a74ac66cee7 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/H3cSdnSubnetIpRangeRefVO_.java @@ -0,0 +1,19 @@ +package org.zstack.sdnController.header; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +/** + * Created by boce.wang on 07/02/2025. + */ +@StaticMetamodel(H3cSdnSubnetIpRangeRefVO.class) +public class H3cSdnSubnetIpRangeRefVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute sdnControllerUuid; + public static volatile SingularAttribute ipRangeUuid; + public static volatile SingularAttribute subnetUuid; + public static volatile SingularAttribute l2NetworkUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkInventory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkInventory.java new file mode 100644 index 00000000000..6820d8b9d89 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkInventory.java @@ -0,0 +1,54 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.search.Parent; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = HardwareL2VxlanNetworkVO.class, collectionValueOfMethod = "valueOf2", + parent = {@Parent(inventoryClass = L2NetworkInventory.class, type = SdnControllerConstant.HARDWARE_VXLAN_NETWORK_TYPE)}) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "sdnController", inventoryClass = SdnControllerInventory.class, + foreignKey = "sdnControllerUuid", expandedInventoryKey = "uuid"), +}) +public class HardwareL2VxlanNetworkInventory extends L2VxlanNetworkInventory { + private Integer vlan; + + public HardwareL2VxlanNetworkInventory() { + } + + protected HardwareL2VxlanNetworkInventory(HardwareL2VxlanNetworkVO vo) { + super(vo); + this.setVlan(vo.getVlan()); + } + + public static HardwareL2VxlanNetworkInventory valueOf(HardwareL2VxlanNetworkVO vo) { + return new HardwareL2VxlanNetworkInventory(vo); + } + + public static List valueOf2(Collection vos) { + List invs = new ArrayList(vos.size()); + for (HardwareL2VxlanNetworkVO vo : vos) { + invs.add(new HardwareL2VxlanNetworkInventory(vo)); + } + return invs; + } + + public Integer getVlan() { + return vlan; + } + + public void setVlan(Integer vlan) { + this.vlan = vlan; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolInventory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolInventory.java new file mode 100644 index 00000000000..2ede24d3e76 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolInventory.java @@ -0,0 +1,83 @@ +package org.zstack.sdnController.header; + +import org.zstack.core.db.Q; +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.search.Parent; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO_; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.*; + +import java.util.*; + +@PythonClassInventory +@Inventory(mappingVOClass = HardwareL2VxlanNetworkPoolVO.class, collectionValueOfMethod = "valueOf2", + parent = {@Parent(inventoryClass = L2NetworkInventory.class, type = SdnControllerConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE)}) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "vniRange", inventoryClass = VniRangeInventory.class, + foreignKey = "uuid", expandedInventoryKey = "l2NetworkUuid"), + @ExpandedQuery(expandedField = "l2VxlanNetwork", inventoryClass = L2VxlanNetworkInventory.class, + foreignKey = "uuid", expandedInventoryKey = "poolUuid"), + @ExpandedQuery(expandedField = "sdnController", inventoryClass = SdnControllerInventory.class, + foreignKey = "sdnControllerUuid", expandedInventoryKey = "uuid"), +}) +public class HardwareL2VxlanNetworkPoolInventory extends L2VxlanNetworkPoolInventory { + private String sdnControllerUuid; + private Integer startVlan; + private Integer endVlan; + + public HardwareL2VxlanNetworkPoolInventory() { + } + + protected HardwareL2VxlanNetworkPoolInventory(HardwareL2VxlanNetworkPoolVO vo) { + super(vo); + setSdnControllerUuid(vo.getSdnControllerUuid()); + setStartVlan(vo.getStartVlan()); + setEndVlan(vo.getEndVlan()); + setAttachedVniRanges(VniRangeInventory.valueOf(vo.getAttachedVniRanges())); + List networkVOS = Q.New(VxlanNetworkVO.class).eq(VxlanNetworkVO_.poolUuid, vo.getUuid()).list(); + setAttachedVxlanNetworkRefs(L2VxlanNetworkInventory.valueOf1(networkVOS)); + } + + public static HardwareL2VxlanNetworkPoolInventory valueOf(HardwareL2VxlanNetworkPoolVO vo) { + return new HardwareL2VxlanNetworkPoolInventory(vo); + } + + public static List valueOf2(Collection vos) { + List invs = new ArrayList(vos.size()); + for (HardwareL2VxlanNetworkPoolVO vo : vos) { + invs.add(new HardwareL2VxlanNetworkPoolInventory(vo)); + } + return invs; + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public Integer getStartVlan() { + return startVlan; + } + + public void setStartVlan(Integer startVlan) { + this.startVlan = startVlan; + } + + public Integer getEndVlan() { + return endVlan; + } + + public void setEndVlan(Integer endVlan) { + this.endVlan = endVlan; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolInventoryDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..3d003dec971 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolInventoryDoc_zh_cn.groovy @@ -0,0 +1,133 @@ +package org.zstack.sdnController.header +import org.zstack.network.l2.vxlan.vtep.VtepInventory +import org.zstack.network.l2.vxlan.vtep.RemoteVtepInventory +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VniRangeInventory + +doc { + + title "硬件VXLAN资源池清单" + + field { + name "sdnControllerUuid" + desc "" + type "String" + since "5.3.0" + } + ref { + name "attachedVtepRefs" + path "org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory.attachedVtepRefs" + desc "null" + type "List" + since "5.3.0" + clz VtepInventory.class + } + ref { + name "remoteVteps" + path "org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory.remoteVteps" + desc "null" + type "List" + since "5.3.0" + clz RemoteVtepInventory.class + } + ref { + name "attachedVxlanNetworkRefs" + path "org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory.attachedVxlanNetworkRefs" + desc "null" + type "List" + since "5.3.0" + clz L2VxlanNetworkInventory.class + } + ref { + name "attachedVniRanges" + path "org.zstack.sdnController.header.HardwareL2VxlanNetworkPoolInventory.attachedVniRanges" + desc "null" + type "List" + since "5.3.0" + clz VniRangeInventory.class + } + field { + name "attachedCidrs" + desc "" + type "Map" + since "5.3.0" + } + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "5.3.0" + } + field { + name "name" + desc "资源名称" + type "String" + since "5.3.0" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "5.3.0" + } + field { + name "zoneUuid" + desc "区域UUID" + type "String" + since "5.3.0" + } + field { + name "physicalInterface" + desc "" + type "String" + since "5.3.0" + } + field { + name "type" + desc "" + type "String" + since "5.3.0" + } + field { + name "vSwitchType" + desc "" + type "String" + since "5.3.0" + } + field { + name "virtualNetworkId" + desc "" + type "Integer" + since "5.3.0" + } + field { + name "isolated" + desc "" + type "Boolean" + since "5.3.0" + } + field { + name "pvlan" + desc "" + type "String" + since "5.3.0" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "5.3.0" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "5.3.0" + } + field { + name "attachedClusterUuids" + desc "" + type "List" + since "5.3.0" + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolVO.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolVO.java new file mode 100644 index 00000000000..20374e4b6e3 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolVO.java @@ -0,0 +1,62 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l2.L2NetworkEO; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.EO; +import org.zstack.header.vo.ForeignKey; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolVO; + +import javax.persistence.*; + +/** + * Created by shixin.ruan on 09/30/2019. + */ +@Entity +@Table +@PrimaryKeyJoinColumn(name = "uuid", referencedColumnName = "uuid") +@EO(EOClazz = L2NetworkEO.class, needView = false) +@AutoDeleteTag +public class HardwareL2VxlanNetworkPoolVO extends VxlanNetworkPoolVO { + @Column + @ForeignKey(parentEntityClass = SdnControllerVO.class, onDeleteAction = ForeignKey.ReferenceOption.RESTRICT) + private String sdnControllerUuid; + + @Column + private Integer startVlan; + + @Column + private Integer endVlan; + + public HardwareL2VxlanNetworkPoolVO() { + } + + public HardwareL2VxlanNetworkPoolVO(L2NetworkVO vo) { + super(vo); + } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public Integer getStartVlan() { + return startVlan; + } + + public void setStartVlan(Integer startVlan) { + this.startVlan = startVlan; + } + + public Integer getEndVlan() { + return endVlan; + } + + public void setEndVlan(Integer endVlan) { + this.endVlan = endVlan; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolVO_.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolVO_.java new file mode 100644 index 00000000000..d0363da0cef --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkPoolVO_.java @@ -0,0 +1,16 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l2.L2NetworkVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +/** + * Created by shixin.ruan on 09/20/2019. + */ +@StaticMetamodel(HardwareL2VxlanNetworkPoolVO.class) +public class HardwareL2VxlanNetworkPoolVO_ extends L2NetworkVO_ { + public static volatile SingularAttribute sdnControllerUuid; + public static volatile SingularAttribute startVlan; + public static volatile SingularAttribute endVlan; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkVO.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkVO.java new file mode 100644 index 00000000000..1f3e6b3d377 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkVO.java @@ -0,0 +1,40 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l2.L2NetworkEO; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.EO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +/** + * Created by shixin.ruan on 07/09/2027. + */ +@Entity +@Table +@PrimaryKeyJoinColumn(name = "uuid", referencedColumnName = "uuid") +@EO(EOClazz = L2NetworkEO.class, needView = false) +@AutoDeleteTag +public class HardwareL2VxlanNetworkVO extends VxlanNetworkVO { + @Column + private int vlan; + + public HardwareL2VxlanNetworkVO() { + } + + public HardwareL2VxlanNetworkVO(L2NetworkVO vo) { + super(vo); + } + + public int getVlan() { + return vlan; + } + + public void setVlan(int vlan) { + this.vlan = vlan; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkVO_.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkVO_.java new file mode 100644 index 00000000000..1098f3a5e28 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareL2VxlanNetworkVO_.java @@ -0,0 +1,15 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +/** + * Created by shixin.ruan on 09/20/2019. + */ +@StaticMetamodel(HardwareL2VxlanNetworkVO.class) +public class HardwareL2VxlanNetworkVO_ extends VxlanNetworkVO_ { + public static volatile SingularAttribute vlan; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareVxlanHelper.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareVxlanHelper.java new file mode 100644 index 00000000000..92d84e56cb3 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/HardwareVxlanHelper.java @@ -0,0 +1,73 @@ +package org.zstack.sdnController.header; + +import org.zstack.core.db.Q; +import org.zstack.header.host.HostInventory; + +public class HardwareVxlanHelper { + public static class VxlanHostMappingStruct { + Integer vlanId; + String physicalInterface; + + public VxlanHostMappingStruct() { + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + } + + public static VxlanHostMappingStruct getHardwareVxlanMappingVxlanId(HardwareL2VxlanNetworkInventory vxlan, HostInventory host) { + String phyNic = Q.New(HardwareL2VxlanNetworkPoolVO.class) + .eq(HardwareL2VxlanNetworkPoolVO_.uuid, vxlan.getPoolUuid()) + .select(HardwareL2VxlanNetworkPoolVO_.physicalInterface).findValue(); + + VxlanHostMappingStruct struct = new VxlanHostMappingStruct(); + VxlanHostMappingVO hvo = Q.New(VxlanHostMappingVO.class) + .eq(VxlanHostMappingVO_.vxlanUuid, vxlan.getUuid()) + .eq(VxlanHostMappingVO_.hostUuid, host.getUuid()) + .find(); + if (hvo != null) { + struct.setVlanId(hvo.getVlanId()); + if(hvo.getPhysicalInterface() != null) { + struct.setPhysicalInterface(hvo.getPhysicalInterface()); + } else { + struct.setPhysicalInterface(phyNic); + } + return struct; + } + + VxlanClusterMappingVO cvo = Q.New(VxlanClusterMappingVO.class) + .eq(VxlanClusterMappingVO_.clusterUuid, host.getClusterUuid()) + .eq(VxlanClusterMappingVO_.vxlanUuid, vxlan.getUuid()) + .find(); + if (cvo != null) { + struct.setVlanId(cvo.getVlanId()); + if(cvo.getPhysicalInterface() != null) { + struct.setPhysicalInterface(cvo.getPhysicalInterface()); + } else { + struct.setPhysicalInterface(phyNic); + } + return struct; + } + + if (vxlan.getVlan() != 0) { + struct.setVlanId(vxlan.getVlan()); + } else { + struct.setVlanId(vxlan.getVirtualNetworkId()); + } + struct.setPhysicalInterface(phyNic); + return struct; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/PullSdnControllerTenantMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/PullSdnControllerTenantMsg.java new file mode 100644 index 00000000000..64837cd2b58 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/PullSdnControllerTenantMsg.java @@ -0,0 +1,26 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; + +/** + * Created by boce.wang on 06/13/2025. + */ +public class PullSdnControllerTenantMsg extends NeedReplyMessage implements SdnControllerMessage { + private String sdnControllerUuid; + + public static PullSdnControllerTenantMsg fromApi(APIPullSdnControllerTenantMsg amsg) { + PullSdnControllerTenantMsg msg = new PullSdnControllerTenantMsg(); + msg.setSdnControllerUuid(amsg.getSdnControllerUuid()); + return msg; + } + + @Override + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/PullSdnControllerTenantReply.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/PullSdnControllerTenantReply.java new file mode 100644 index 00000000000..4332fc9d1df --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/PullSdnControllerTenantReply.java @@ -0,0 +1,20 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.MessageReply; + +import java.util.List; + +/** + * Created by boce.wang on 06/13/2025. + */ +public class PullSdnControllerTenantReply extends MessageReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/ReconnectSdnControllerMsg.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/ReconnectSdnControllerMsg.java new file mode 100644 index 00000000000..dffe66fa86b --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/ReconnectSdnControllerMsg.java @@ -0,0 +1,21 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.network.sdncontroller.SdnControllerMessage; + +public class ReconnectSdnControllerMsg extends NeedReplyMessage implements SdnControllerMessage { + private String controllerUuid; + + public String getControllerUuid() { + return controllerUuid; + } + + public void setControllerUuid(String controllerUuid) { + this.controllerUuid = controllerUuid; + } + + @Override + public String getSdnControllerUuid() { + return controllerUuid; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/ReconnectSdnControllerReply.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/ReconnectSdnControllerReply.java new file mode 100644 index 00000000000..0d980fa8632 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/ReconnectSdnControllerReply.java @@ -0,0 +1,6 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.MessageReply; + +public class ReconnectSdnControllerReply extends MessageReply { +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerCanonicalEvents.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerCanonicalEvents.java new file mode 100644 index 00000000000..1375de42ec2 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerCanonicalEvents.java @@ -0,0 +1,59 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.message.NeedJsonSchema; +import org.zstack.header.network.sdncontroller.SdnControllerInventory; + +public class SdnControllerCanonicalEvents { + public static final String SDNCONTROLLER_STATE_CHANGED_PATH = "/sdnController/state/change"; + public static final String SDNCONTROLLER_STATUS_CHANGED_PATH = "/sdnController/status/change"; + + @NeedJsonSchema + public static class SdnControllerStatusChangedData { + private String sdnControllerUuid; + private String sdnControllerType; + private String oldStatus; + private String newStatus; + private SdnControllerInventory inv; + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getSdnControllerType() { + return sdnControllerType; + } + + public void setSdnControllerType(String sdnControllerType) { + this.sdnControllerType = sdnControllerType; + } + + public String getOldStatus() { + return oldStatus; + } + + public void setOldStatus(String oldStatus) { + this.oldStatus = oldStatus; + } + + public String getNewStatus() { + return newStatus; + } + + public void setNewStatus(String newStatus) { + this.newStatus = newStatus; + } + + public SdnControllerInventory getInv() { + return inv; + } + + public void setInv(SdnControllerInventory inv) { + this.inv = inv; + } + } + +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerFlowDataParam.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerFlowDataParam.java new file mode 100644 index 00000000000..7682575f00c --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerFlowDataParam.java @@ -0,0 +1,8 @@ +package org.zstack.sdnController.header; + +public enum SdnControllerFlowDataParam { + SDN_CONTROLLER_UUID, + SDN_CONTROLLER_PASSWORD, + SDN_CONTROLLER_USERNAME, + SDN_CONTROLLER_CHANGED, +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerTableState.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerTableState.java new file mode 100644 index 00000000000..3352d966dce --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnControllerTableState.java @@ -0,0 +1,17 @@ +package org.zstack.sdnController.header; + +public enum SdnControllerTableState { + Enabled("Enabled"), + Disabled("Disabled"); + + public final String value; + private SdnControllerTableState(String value) { + this.value = value; + } + + + @Override + public String toString() { + return value; + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVlanRange.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVlanRange.java new file mode 100644 index 00000000000..10f720517a9 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVlanRange.java @@ -0,0 +1,6 @@ +package org.zstack.sdnController.header; + +public class SdnVlanRange { + public Integer startVlan; + public Integer endVlan; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVniRange.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVniRange.java new file mode 100644 index 00000000000..582648f2807 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVniRange.java @@ -0,0 +1,6 @@ +package org.zstack.sdnController.header; + +public class SdnVniRange { + public Integer startVni; + public Integer endVni; +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVniRangeDoc_zh_cn.groovy b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVniRangeDoc_zh_cn.groovy new file mode 100644 index 00000000000..8f7beb9ab16 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/SdnVniRangeDoc_zh_cn.groovy @@ -0,0 +1,21 @@ +package org.zstack.sdnController.header + +import java.lang.Integer + +doc { + + title "SDN控制Vni范围" + + field { + name "startVni" + desc "" + type "Integer" + since "3.7" + } + field { + name "endVni" + desc "" + type "Integer" + since "3.7" + } +} diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingInventory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingInventory.java new file mode 100644 index 00000000000..d5fe20f6018 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingInventory.java @@ -0,0 +1,105 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.*; + +@PythonClassInventory +@Inventory(mappingVOClass = VxlanClusterMappingVO.class, collectionValueOfMethod = "valueOf1") +public class VxlanClusterMappingInventory implements Serializable { + private String vxlanUuid; + private String clusterUuid; + private Integer vlanId; + private String physicalInterface; + private Timestamp createDate; + private Timestamp lastOpDate; + + public VxlanClusterMappingInventory() {} + + protected VxlanClusterMappingInventory(VxlanClusterMappingVO vo) { + this.vxlanUuid = vo.getVxlanUuid(); + this.clusterUuid = vo.getClusterUuid(); + this.vlanId = vo.getVlanId(); + this.physicalInterface = vo.getPhysicalInterface(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + } + + public static VxlanClusterMappingInventory valueOf(VxlanClusterMappingVO vo) { + return new VxlanClusterMappingInventory(vo); + } + + public static VxlanClusterMappingInventory valueOf2(Map keyMap, Map valueMap) { + VxlanClusterMappingInventory inv = new VxlanClusterMappingInventory(); + Optional> key = keyMap.entrySet().stream().findFirst(); + if (key.isPresent()) { + inv.setClusterUuid(key.get().getKey()); + inv.setPhysicalInterface(key.get().getValue()); + } + Optional> value = valueMap.entrySet().stream().findFirst(); + if (value.isPresent()) { + inv.setVlanId(value.get().getKey()); + inv.setPhysicalInterface(value.get().getValue()); + } + return inv; + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (VxlanClusterMappingVO vo : vos) { + invs.add(VxlanClusterMappingInventory.valueOf(vo)); + } + return invs; + } + public String getVxlanUuid() { + return vxlanUuid; + } + + public void setVxlanUuid(String vxlanUuid) { + this.vxlanUuid = vxlanUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} + diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingVO.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingVO.java new file mode 100644 index 00000000000..492ee462a1f --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingVO.java @@ -0,0 +1,100 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.cluster.ClusterEO; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = VxlanNetworkVO.class, myField = "vxlanUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = ClusterEO.class, myField = "clusterUuid", targetField = "uuid"), + } +) +public class VxlanClusterMappingVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + @ForeignKey(parentEntityClass = VxlanNetworkVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String vxlanUuid; + + @Column + @ForeignKey(parentEntityClass = ClusterEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String clusterUuid; + + @Column + private Integer vlanId; + + @Column + private String physicalInterface; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getVxlanUuid() { + return vxlanUuid; + } + + public void setVxlanUuid(String vxlanUuid) { + this.vxlanUuid = vxlanUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingVO_.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingVO_.java new file mode 100644 index 00000000000..49cde305d86 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanClusterMappingVO_.java @@ -0,0 +1,16 @@ +package org.zstack.sdnController.header; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(VxlanClusterMappingVO.class) +public class VxlanClusterMappingVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute vxlanUuid; + public static volatile SingularAttribute clusterUuid; + public static volatile SingularAttribute vlanId; + public static volatile SingularAttribute physicalInterface; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingInventory.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingInventory.java new file mode 100644 index 00000000000..45465c4a32f --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingInventory.java @@ -0,0 +1,106 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.search.Inventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.*; + +@PythonClassInventory +@Inventory(mappingVOClass = VxlanHostMappingVO.class, collectionValueOfMethod = "valueOf1") +public class VxlanHostMappingInventory implements Serializable { + private String vxlanUuid; + private String hostUuid; + private Integer vlanId; + private String physicalInterface; + private Timestamp createDate; + private Timestamp lastOpDate; + + public VxlanHostMappingInventory() {} + + protected VxlanHostMappingInventory(VxlanHostMappingVO vo) { + this.vxlanUuid = vo.getVxlanUuid(); + this.hostUuid = vo.getHostUuid(); + this.vlanId = vo.getVlanId(); + this.physicalInterface = vo.getPhysicalInterface(); + this.createDate = vo.getCreateDate(); + this.lastOpDate = vo.getLastOpDate(); + } + + public static VxlanHostMappingInventory valueOf(VxlanHostMappingVO vo) { + return new VxlanHostMappingInventory(vo); + } + + public static VxlanHostMappingInventory valueOf2(Map keyMap, Map valueMap) { + VxlanHostMappingInventory inv = new VxlanHostMappingInventory(); + Optional> key = keyMap.entrySet().stream().findFirst(); + if (key.isPresent()) { + inv.setHostUuid(key.get().getKey()); + inv.setPhysicalInterface(key.get().getValue()); + } + Optional> value = valueMap.entrySet().stream().findFirst(); + if (value.isPresent()) { + inv.setVlanId(value.get().getKey()); + inv.setPhysicalInterface(value.get().getValue()); + } + return inv; + } + + public static List valueOf1(Collection vos) { + List invs = new ArrayList(vos.size()); + for (VxlanHostMappingVO vo : vos) { + invs.add(VxlanHostMappingInventory.valueOf(vo)); + } + return invs; + } + + public String getVxlanUuid() { + return vxlanUuid; + } + + public void setVxlanUuid(String vxlanUuid) { + this.vxlanUuid = vxlanUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} + diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingVO.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingVO.java new file mode 100644 index 00000000000..17cd07dce49 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingVO.java @@ -0,0 +1,100 @@ +package org.zstack.sdnController.header; + +import org.zstack.header.host.HostEO; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = VxlanNetworkVO.class, myField = "vxlanUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = HostEO.class, myField = "hostUuid", targetField = "uuid"), + } +) +public class VxlanHostMappingVO { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private long id; + + @Column + @ForeignKey(parentEntityClass = VxlanNetworkVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String vxlanUuid; + + @Column + @ForeignKey(parentEntityClass = HostEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String hostUuid; + + @Column + private Integer vlanId; + + @Column + private String physicalInterface; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getVxlanUuid() { + return vxlanUuid; + } + + public void setVxlanUuid(String vxlanUuid) { + this.vxlanUuid = vxlanUuid; + } + + public String getHostUuid() { + return hostUuid; + } + + public void setHostUuid(String hostUuid) { + this.hostUuid = hostUuid; + } + + public Integer getVlanId() { + return vlanId; + } + + public void setVlanId(Integer vlanId) { + this.vlanId = vlanId; + } + + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; +} \ No newline at end of file diff --git a/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingVO_.java b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingVO_.java new file mode 100644 index 00000000000..511b0e53871 --- /dev/null +++ b/plugin/sdnController/src/main/java/org/zstack/sdnController/header/VxlanHostMappingVO_.java @@ -0,0 +1,16 @@ +package org.zstack.sdnController.header; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(VxlanHostMappingVO.class) +public class VxlanHostMappingVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute vxlanUuid; + public static volatile SingularAttribute hostUuid; + public static volatile SingularAttribute vlanId; + public static volatile SingularAttribute physicalInterface; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} \ No newline at end of file diff --git a/plugin/securityGroup/pom.xml b/plugin/securityGroup/pom.xml index 7e8248c502e..f3651c37eba 100755 --- a/plugin/securityGroup/pom.xml +++ b/plugin/securityGroup/pom.xml @@ -4,7 +4,7 @@ org.zstack plugin - 4.4.0 + 5.4.0 securityGroup diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsg.java index 32c4af738a1..62adf4db78e 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsg.java @@ -9,6 +9,7 @@ import org.zstack.header.rest.RestRequest; import java.util.List; +import java.util.Objects; import static java.util.Arrays.asList; @@ -26,20 +27,26 @@ * { "org.zstack.network.securitygroup.APIAddSecurityGroupRuleMsg": { "securityGroupUuid": "3904b4837f0c4f539063777ed463b648", +"priority": -1, +"type": "Ingress", "rules": [ { -"type": "Ingress", -"startPort": 22, -"endPort": 100, "protocol": "TCP", -"allowedCidr": "0.0.0.0/0" +"srcIpRange": "10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24", +"dstIpRange": "20.0.0.1,20.0.0.2-20.0.0.20,20.1.1.0/24", +"srcPortRange": "1000,1001,1002-1005,1008", +"dstPortRange": "2000,2001,2002-2005,2008", +"remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", +"defaultTarget": "RETURN" }, { -"type": "Ingress", -"startPort": 10, -"endPort": 10, "protocol": "UDP", -"allowedCidr": "192.168.0.1/0" +"srcIpRange": "10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24", +"dstIpRange": "20.0.0.1,20.0.0.2-20.0.0.20,20.1.1.0/24", +"srcPortRange": "1000,1001,1002-1005,1008", +"dstPortRange": "2000,2001,2002-2005,2008", +"remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", +"defaultTarget": "RETURN" } ], "session": { @@ -52,20 +59,30 @@ * { "org.zstack.network.securitygroup.APIAddSecurityGroupRuleMsg": { "securityGroupUuid": "3904b4837f0c4f539063777ed463b648", +"priority": -1, +"type": "Ingress", "rules": [ { -"type": "Ingress", -"startPort": 22, -"endPort": 100, +"ipVersion": "4", "protocol": "TCP", -"allowedCidr": "0.0.0.0/0" +"srcIpRange": "10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24", +"dstIpRange": "20.0.0.1,20.0.0.2-20.0.0.20,20.1.1.0/24", +"srcPortRange": "1000,1001,1002-1005,1008", +"dstPortRange": "2000,2001,2002-2005,2008", +"remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", +"action": "ACCEPT" }, { -"type": "Ingress", -"startPort": 10, -"endPort": 10, +"ipVersion": "4", "protocol": "UDP", -"allowedCidr": "192.168.0.1/0" +"srcIpRange": "10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24", +"dstIpRange": "20.0.0.1,20.0.0.2-20.0.0.20,20.1.1.0/24", +"srcPortRange": "1000,1001,1002-1005,1008", +"dstPortRange": "2000,2001,2002-2005,2008", +"remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", +"action": "ACCEPT" +} +], } ], "session": { @@ -98,16 +115,20 @@ public class APIAddSecurityGroupRuleMsg extends APIMessage implements AddSecurit * @example * *{ - "type": "Ingress", - "startPort": 10, - "endPort": 10, + "ipVersion": "4", "protocol": "UDP", - "allowedCidr": "192.168.0.1/0" + "srcIpRange": "1.1.1.1,1.1.1.2", + "dstIpRange": "2.2.2.1,2.2.2.2", + "srcPortRange": "1000,1001", + "dstPortRange": "2000,2001", + "remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", + "defaultTarget": "DROP" } * @since 0.1.0 */ @PythonClassInventory public static class SecurityGroupRuleAO { + /** * @desc * rule type @@ -118,12 +139,64 @@ public static class SecurityGroupRuleAO { * - Ingress * - Egress */ + @APIParam(required = true, validValues = {"Ingress", "Egress"}) private String type; + @APIParam(required = false, validValues = {"Enabled", "Disabled"}) + private String state = SecurityGroupRuleState.Enabled.toString(); + + @APIParam(required = false) + private String description; + + /** + * @desc remote security group uuid for rules between groups + */ + @APIParam(resourceType = SecurityGroupVO.class, required = false, nonempty = true) + private String remoteSecurityGroupUuid; + @APIParam(required = false, validValues = {"4", "6"}) private Integer ipVersion; /** + * @desc network protocol type + * @choices + * - TCP + * - UDP + * - ICMP + * - ALL + */ + private String protocol; + + /** + * @desc source ip address range + * @choices 10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24 + */ + @APIParam(required = false) + private String srcIpRange; + + /** + * @desc destination ip address range + * @choices 10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24 + */ + @APIParam(required = false) + private String dstIpRange; + + /** + * @desc destination ip port range + * @choices 1000,1001,1002-1005,1008 + */ + @APIParam(required = false) + private String dstPortRange; + + /** + * @desc rule default target + * @choices + * - ACCEPT / DROP + */ + @APIParam(required = false, validValues = {"ACCEPT", "DROP"}) + private String action = SecurityGroupRuleAction.ACCEPT.toString(); + + /** * @desc * start port * @choices 0 - 65535 @@ -136,14 +209,7 @@ public static class SecurityGroupRuleAO { * @nullable */ private Integer endPort; - /** - * @desc network protocol type - * @choices - * - TCP - * - UDP - * - ICMP - */ - private String protocol; + /** * @desc source CIDR the rule applies to. If set, the rule only applies to traffic from this CIDR. If omitted, the rule * applies to all traffic @@ -151,6 +217,22 @@ public static class SecurityGroupRuleAO { */ private String allowedCidr; + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + public String getType() { return type; } @@ -159,6 +241,38 @@ public void setType(String type) { this.type = type; } + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getSrcIpRange() { + return srcIpRange; + } + + public void setSrcIpRange(String srcIpRange) { + this.srcIpRange = srcIpRange; + } + + public String getDstIpRange() { + return dstIpRange; + } + + public void setDstIpRange(String dstIpRange) { + this.dstIpRange = dstIpRange; + } + + public String getDstPortRange() { + return dstPortRange; + } + + public void setDstPortRange(String dstPortRange) { + this.dstPortRange = dstPortRange; + } + public Integer getStartPort() { return startPort; } @@ -183,6 +297,14 @@ public void setProtocol(String protocol) { this.protocol = protocol; } + public String getRemoteSecurityGroupUuid() { + return remoteSecurityGroupUuid; + } + + public void setRemoteSecurityGroupUuid(String remoteSecurityGroupUuid) { + this.remoteSecurityGroupUuid = remoteSecurityGroupUuid; + } + public String getAllowedCidr() { return allowedCidr; } @@ -198,26 +320,44 @@ public Integer getIpVersion() { public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (!(o instanceof SecurityGroupRuleAO)) { + return false; + } + SecurityGroupRuleAO other = (SecurityGroupRuleAO) o; + return Objects.equals(type, other.type) && Objects.equals(remoteSecurityGroupUuid, other.remoteSecurityGroupUuid) + && Objects.equals(ipVersion, other.ipVersion) && Objects.equals(protocol, other.protocol) + && Objects.equals(srcIpRange, other.srcIpRange) && Objects.equals(dstIpRange, other.dstIpRange) + && Objects.equals(dstPortRange, other.dstPortRange) && Objects.equals(action, other.action); + } } - /** - * @desc security group uuid - */ - @APIParam(resourceType = SecurityGroupVO.class, checkAccount = true, operationTarget = true) + @APIParam(resourceType = SecurityGroupVO.class, checkAccount = true, operationTarget = true, nonempty = true, required = true) private String securityGroupUuid; /** * @desc a list of :ref:`SecurityGroupRuleAO` that describe rules */ - @APIParam(nonempty = true) + @APIParam(nonempty = true, required = true) private List rules; - /** - * @desc remote security group uuids for rules between groups - */ @APIParam(resourceType = SecurityGroupVO.class, required = false, nonempty = true) private List remoteSecurityGroupUuids; + /** + * @desc rules priority + * @choices + * - >1: defined by user + * - 1: lowest priority + */ + @APIParam(required = false) + private Integer priority = -1; + public String getSecurityGroupUuid() { return securityGroupUuid; } @@ -230,6 +370,14 @@ public void setRules(List rules) { this.rules = rules; } + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + public void setSecurityGroupUuid(String securityGroupUuid) { this.securityGroupUuid = securityGroupUuid; } @@ -245,14 +393,19 @@ public List getRemoteSecurityGroupUuids() { public static APIAddSecurityGroupRuleMsg __example__() { APIAddSecurityGroupRuleMsg msg = new APIAddSecurityGroupRuleMsg(); msg.setSecurityGroupUuid(uuid()); - msg.setRemoteSecurityGroupUuids(asList(uuid())); SecurityGroupRuleAO rule = new SecurityGroupRuleAO(); rule.setType("Ingress"); - rule.setAllowedCidr("0.0.0.0/0"); - rule.setStartPort(22); - rule.setEndPort(22); + rule.setState("Enabled"); + rule.setDescription("test"); + rule.setRemoteSecurityGroupUuid(uuid()); + rule.setIpVersion(4); + rule.setAction("ACCEPT"); + rule.setSrcIpRange("10.0.0.1,10.0.0.2-10.0.0.200,10.1.1.0/24"); + rule.setDstIpRange("10.0.0.1,10.0.0.2-10.0.0.200,10.1.1.0/24"); rule.setProtocol("TCP"); + rule.setDstPortRange("1000,1001,1002-1005,1008"); msg.setRules(asList(rule)); + msg.setPriority(-1); return msg; } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsgDoc_zh_cn.groovy index b81839fb2bf..87958ea3efd 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddSecurityGroupRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "rules" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "remoteSecurityGroupUuids" @@ -49,7 +47,15 @@ doc { type "List" optional true since "2.1" - + } + column { + name "priority" + enclosedIn "params" + desc "规则优先级" + location "body" + type "Integer" + optional true + since "4.7.21" } column { name "systemTags" @@ -59,7 +65,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +74,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddVmNicToSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddVmNicToSecurityGroupMsgDoc_zh_cn.groovy index 6a0a83119ac..0ce8daebce9 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddVmNicToSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAddVmNicToSecurityGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "vmNicUuids" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsg.java index 31b07953653..68738112440 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsg.java @@ -50,13 +50,16 @@ @RestRequest( path = "/security-groups/{securityGroupUuid}/l3-networks/{l3NetworkUuid}", method = HttpMethod.POST, + parameterName = "params", responseClass = APIAttachSecurityGroupToL3NetworkEvent.class ) -public class APIAttachSecurityGroupToL3NetworkMsg extends APIMessage { +public class APIAttachSecurityGroupToL3NetworkMsg extends APIMessage implements SecurityGroupMessage { @APIParam(resourceType=SecurityGroupVO.class, checkAccount = true, operationTarget = true) private String securityGroupUuid; @APIParam(resourceType = L3NetworkVO.class) private String l3NetworkUuid; + + @Override public String getSecurityGroupUuid() { return securityGroupUuid; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsgDoc_zh_cn.groovy index 5d8b7704332..1dd23ae0967 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIAttachSecurityGroupToL3NetworkMsgDoc_zh_cn.groovy @@ -23,23 +23,21 @@ doc { column { name "securityGroupUuid" - enclosedIn "" + enclosedIn "params" desc "安全组UUID" location "url" type "String" optional false since "0.6" - } column { name "l3NetworkUuid" - enclosedIn "" + enclosedIn "params" desc "三层网络UUID" location "url" type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleEvent.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleEvent.java new file mode 100644 index 00000000000..3b44ec369c2 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleEvent.java @@ -0,0 +1,73 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; + +/** + *@apiResult + * api event for :ref:`APIChangeSecurityGroupRuleMsg` + *@category security group + * + *@since 0.1.0 + * + *@example + * { +"org.zstack.network.securitygroup.APIChangeSecurityGroupRuleEvent": { +"inventory": { +"uuid": "02bc62abee88444ca3e2c434a1b8fdea", +"securityGroupUuid": "3904b4837f0c4f539063777ed463b648", +"type": "Ingress", +"srcIpRange": "10.10.10.1-10.10.10.10", +"dstPortRange": "10-100", +"protocol": "UDP", +"action": "DROP" +"createDate": "Jul 10, 2023 9:38:24 PM", +"lastOpDate": "Jul 10, 2023 9:38:24 PM", +"state": "Enabled", +}, +"success": true +} +} + */ +@RestResponse(allTo = "inventory") +public class APIChangeSecurityGroupRuleEvent extends APIEvent { + /** + * @desc :ref:`SecurityGroupRuleInventory` + */ + private SecurityGroupRuleInventory inventory; + + public APIChangeSecurityGroupRuleEvent() { + super(null); + } + + public APIChangeSecurityGroupRuleEvent(String apiId) { + super(apiId); + } + + public SecurityGroupRuleInventory getInventory() { + return inventory; + } + + public void setInventory(SecurityGroupRuleInventory inventory) { + this.inventory = inventory; + } + + public static APIChangeSecurityGroupRuleEvent __example__() { + APIChangeSecurityGroupRuleEvent event = new APIChangeSecurityGroupRuleEvent(); + SecurityGroupRuleInventory rule = new SecurityGroupRuleInventory(); + rule.setUuid(uuid()); + rule.setSecurityGroupUuid(uuid()); + rule.setProtocol("tcp"); + rule.setSrcIpRange("10.10.10.1-10.10.10.10"); + rule.setDstPortRange("2001-2023"); + rule.setAction("RETURN"); + rule.setType("ingress"); + rule.setState("enable"); + rule.setCreateDate(new Timestamp(System.currentTimeMillis())); + rule.setLastOpDate(new Timestamp(System.currentTimeMillis())); + event.setInventory(rule); + return event; + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleEventDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..3fb7d988465 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.SecurityGroupRuleInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组(Security Group)清单" + + ref { + name "inventory" + path "org.zstack.network.securitygroup.APIChangeSecurityGroupRuleEvent.inventory" + desc "null" + type "SecurityGroupRuleInventory" + since "4.7.21" + clz SecurityGroupRuleInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APIChangeSecurityGroupRuleEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleMsg.java new file mode 100644 index 00000000000..c28d184a718 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleMsg.java @@ -0,0 +1,143 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + + +@Action(category = SecurityGroupConstant.ACTION_CATEGORY) +@RestRequest( + path = "/security-groups/rules/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIChangeSecurityGroupRuleEvent.class, + isAction = true +) + +public class APIChangeSecurityGroupRuleMsg extends APIMessage{ + @APIParam(resourceType = SecurityGroupRuleVO.class, nonempty = true) + private String uuid; + + @APIParam(required = false, maxLength = 255) + private String description; + + @APIParam(required = false) + private String remoteSecurityGroupUuid; + + @APIParam(validValues = {"DROP", "ACCEPT"}, required = false, nonempty = true) + private String action; + + @APIParam(validValues = {"Enabled", "Disabled"}, required = false, nonempty = true) + private String state; + + @APIParam(maxLength = 4, required = false, nonempty = true) + private Integer priority; + + @APIParam(validValues = {"ALL", "TCP", "UDP", "ICMP"}, required = false, nonempty = true) + private String protocol; + + @APIParam(required = false, maxLength = 1024) + private String srcIpRange; + + @APIParam(required = false, maxLength = 1024) + private String dstIpRange; + + @APIParam(required = false, maxLength = 255) + private String dstPortRange; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getDescription(){ + return description; + } + + public void setDescription(String description){ + this.description = description; + } + + public String getRemoteSecurityGroupUuid() { + return remoteSecurityGroupUuid; + } + + public void setRemoteSecurityGroupUuid(String remoteSecurityGroupUuid) { + this.remoteSecurityGroupUuid = remoteSecurityGroupUuid; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getSrcIpRange() { + return srcIpRange; + } + + public void setSrcIpRange(String srcIpRange) { + this.srcIpRange = srcIpRange; + } + + public String getDstIpRange() { + return dstIpRange; + } + + public void setDstIpRange(String dstIpRange) { + this.dstIpRange = dstIpRange; + } + + public String getDstPortRange() { + return dstPortRange; + } + + public void setDstPortRange(String dstPortRange) { + this.dstPortRange = dstPortRange; + } + + public static APIChangeSecurityGroupRuleMsg __example__() { + APIChangeSecurityGroupRuleMsg msg = new APIChangeSecurityGroupRuleMsg(); + msg.setUuid(uuid()); + msg.setDescription("test"); + msg.setRemoteSecurityGroupUuid(uuid()); + msg.setAction(SecurityGroupRuleAction.DROP.toString()); + msg.setState(SecurityGroupRuleState.Enabled.toString()); + msg.setPriority(1); + msg.setProtocol(SecurityGroupRuleProtocolType.TCP.toString()); + msg.setSrcIpRange("1.1.1.1,2.2.2.0/24,3.3.3.1-3.3.3.10"); + msg.setDstPortRange("1001,2000-2023,6001"); + return msg; + } + +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..c7cc37ff571 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleMsgDoc_zh_cn.groovy @@ -0,0 +1,142 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APIChangeSecurityGroupRuleEvent + +doc { + title "ChangeSecurityGroupRule" + + category "securityGroup" + + desc """更改安全组规则""" + + rest { + request { + url "PUT /v1/security-groups/rules/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeSecurityGroupRuleMsg.class + + desc """更改安全组规则""" + + params { + + column { + name "uuid" + enclosedIn "changeSecurityGroupRule" + desc "安全组规则的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "description" + enclosedIn "changeSecurityGroupRule" + desc "规则的描述" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "remoteSecurityGroupUuid" + enclosedIn "changeSecurityGroupRule" + desc "应用组间策略的远端安全组UUID" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "action" + enclosedIn "changeSecurityGroupRule" + desc "规则的默认动作" + location "body" + type "String" + optional true + since "4.7.21" + values ("DROP","ACCEPT") + } + column { + name "state" + enclosedIn "changeSecurityGroupRule" + desc "规则的状态" + location "body" + type "String" + optional true + since "4.7.21" + values ("Enabled","Disabled") + } + column { + name "priority" + enclosedIn "changeSecurityGroupRule" + desc "规则的优先级" + location "body" + type "Integer" + optional true + since "4.7.21" + } + column { + name "protocol" + enclosedIn "changeSecurityGroupRule" + desc "规则的协议类型" + location "body" + type "String" + optional true + since "4.7.21" + values ("ALL","TCP","UDP","ICMP") + } + column { + name "srcIpRange" + enclosedIn "changeSecurityGroupRule" + desc "规则的源方向IP范围" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "dstIpRange" + enclosedIn "changeSecurityGroupRule" + desc "规则的目的方向IP范围" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "dstPortRange" + enclosedIn "changeSecurityGroupRule" + desc "规则的目的方向端口范围" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIChangeSecurityGroupRuleEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateEvent.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateEvent.java new file mode 100644 index 00000000000..81269285cb3 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateEvent.java @@ -0,0 +1,47 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; + + + + +@RestResponse(allTo = "inventory") +public class APIChangeSecurityGroupRuleStateEvent extends APIEvent { + /** + * @desc :ref:`SecurityGroupInventory` + */ + private SecurityGroupInventory inventory; + + public APIChangeSecurityGroupRuleStateEvent() { + super(null); + } + + public APIChangeSecurityGroupRuleStateEvent(String apiId) { + super(apiId); + } + + public SecurityGroupInventory getInventory() { + return inventory; + } + + public void setInventory(SecurityGroupInventory inventory) { + this.inventory = inventory; + } + + public static APIChangeSecurityGroupRuleStateEvent __example__() { + APIChangeSecurityGroupRuleStateEvent event = new APIChangeSecurityGroupRuleStateEvent(); + SecurityGroupInventory sec = new SecurityGroupInventory(); + sec.setUuid(uuid()); + sec.setName("web"); + sec.setDescription("for test"); + sec.setState("Enabled"); + sec.setCreateDate(new Timestamp(System.currentTimeMillis())); + sec.setLastOpDate(new Timestamp(System.currentTimeMillis())); + event.setInventory(sec); + event.setSuccess(true); + return event; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateEventDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..5ada01098f8 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.SecurityGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组(Security Group)清单" + + ref { + name "inventory" + path "org.zstack.network.securitygroup.APIChangeSecurityGroupRuleStateEvent.inventory" + desc "null" + type "SecurityGroupInventory" + since "4.7.21" + clz SecurityGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APIChangeSecurityGroupRuleStateEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateMsg.java new file mode 100644 index 00000000000..46cedd4bf9c --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateMsg.java @@ -0,0 +1,60 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +@Action(category = SecurityGroupConstant.ACTION_CATEGORY) +@RestRequest( + path = "/security-groups/{securityGroupUuid}/rules/state/actions", + method = HttpMethod.PUT, + responseClass = APIChangeSecurityGroupRuleStateEvent.class, + isAction = true +) +public class APIChangeSecurityGroupRuleStateMsg extends APIMessage implements SecurityGroupMessage { + @APIParam(required = true, nonempty = true, checkAccount = true, operationTarget = true) + private String securityGroupUuid; + + @APIParam(required = true, nonempty = true, checkAccount = true, operationTarget = true) + private List ruleUuids; + + @APIParam(required = true, validValues = {"Enabled", "Disabled"}) + private String state; + + @Override + public String getSecurityGroupUuid() { + return securityGroupUuid; + } + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; + } + + public List getRuleUuids() { + return ruleUuids; + } + public void setRuleUuids(List ruleUuids) { + this.ruleUuids = ruleUuids; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public static APIChangeSecurityGroupRuleStateMsg __example__() { + APIChangeSecurityGroupRuleStateMsg msg = new APIChangeSecurityGroupRuleStateMsg(); + msg.setSecurityGroupUuid(uuid()); + msg.setRuleUuids(asList(uuid())); + msg.setState("Enabled"); + return msg; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..fc4a3287f24 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupRuleStateMsgDoc_zh_cn.groovy @@ -0,0 +1,77 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APIChangeSecurityGroupRuleStateEvent + +doc { + title "ChangeSecurityGroupRuleState" + + category "securityGroup" + + desc """更改安全组规则状态""" + + rest { + request { + url "PUT /v1/security-groups/{securityGroupUuid}/rules/state/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeSecurityGroupRuleStateMsg.class + + desc """更改安全组规则状态""" + + params { + + column { + name "securityGroupUuid" + enclosedIn "changeSecurityGroupRuleState" + desc "安全组的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "ruleUuids" + enclosedIn "changeSecurityGroupRuleState" + desc "规则的UUID列表" + location "body" + type "List" + optional false + since "4.7.21" + } + column { + name "state" + enclosedIn "changeSecurityGroupRuleState" + desc "规则的状态" + location "body" + type "String" + optional false + since "4.7.21" + values ("Enabled","Disabled") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIChangeSecurityGroupRuleStateEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupStateMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupStateMsgDoc_zh_cn.groovy index ae4a5adc1d9..18d602537e7 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupStateMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeSecurityGroupStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyEvent.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyEvent.java new file mode 100644 index 00000000000..14fe5339df2 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyEvent.java @@ -0,0 +1,43 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; + +@RestResponse(allTo = "inventory") +public class APIChangeVmNicSecurityPolicyEvent extends APIEvent { + private VmNicSecurityPolicyInventory inventory; + + public APIChangeVmNicSecurityPolicyEvent() { + super(null); + } + + public APIChangeVmNicSecurityPolicyEvent(String apiId) { + super(apiId); + } + + public VmNicSecurityPolicyInventory getInventory() { + return inventory; + } + + public void setInventory(VmNicSecurityPolicyInventory inventory) { + this.inventory = inventory; + } + + public static APIChangeVmNicSecurityPolicyEvent __example__() { + APIChangeVmNicSecurityPolicyEvent event = new APIChangeVmNicSecurityPolicyEvent(); + VmNicSecurityPolicyInventory inventory = new VmNicSecurityPolicyInventory(); + inventory.setUuid(uuid()); + inventory.setVmNicUuid(uuid()); + inventory.setIngressPolicy("DENY"); + inventory.setEgressPolicy("ALLOW"); + inventory.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inventory.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + event.setInventory(inventory); + event.setSuccess(true); + return event; + } + + +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyEventDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..9752e25a858 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.VmNicSecurityPolicyInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组(Security Group)清单" + + ref { + name "inventory" + path "org.zstack.network.securitygroup.APIChangeVmNicSecurityPolicyEvent.inventory" + desc "null" + type "VmNicSecurityPolicyInventory" + since "4.7.21" + clz VmNicSecurityPolicyInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APIChangeVmNicSecurityPolicyEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyMsg.java new file mode 100644 index 00000000000..cead3379b3c --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyMsg.java @@ -0,0 +1,59 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vm.VmNicVO; + +@Action(category = SecurityGroupConstant.ACTION_CATEGORY) +@RestRequest( + path = "/security-groups/nics/{vmNicUuid}/security-policy/actions", + method = HttpMethod.PUT, + responseClass = APIChangeVmNicSecurityPolicyEvent.class, + isAction = true +) +public class APIChangeVmNicSecurityPolicyMsg extends APIMessage implements VmNicSecurityGroupMessage { + @APIParam(resourceType = VmNicVO.class, checkAccount = true, operationTarget = true) + private String vmNicUuid; + + @APIParam(required = false, validValues = {"DENY", "ALLOW"}) + private String ingressPolicy; + + @APIParam(required = false, validValues = {"DENY", "ALLOW"}) + private String egressPolicy; + + @Override + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public String getIngressPolicy() { + return ingressPolicy; + } + + public void setIngressPolicy(String ingressPolicy) { + this.ingressPolicy = ingressPolicy; + } + + public String getEgressPolicy() { + return egressPolicy; + } + + public void setEgressPolicy(String egressPolicy) { + this.egressPolicy = egressPolicy; + } + + public static APIChangeVmNicSecurityPolicyMsg __example__() { + APIChangeVmNicSecurityPolicyMsg msg = new APIChangeVmNicSecurityPolicyMsg(); + msg.vmNicUuid = uuid(); + msg.ingressPolicy = "ALLOW"; + msg.egressPolicy = "DENY"; + return msg; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..d19709986ff --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIChangeVmNicSecurityPolicyMsgDoc_zh_cn.groovy @@ -0,0 +1,78 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APIChangeVmNicSecurityPolicyEvent + +doc { + title "ChangeVmNicSecurityPolicy" + + category "securityGroup" + + desc """更改网卡的默认流量策略""" + + rest { + request { + url "PUT /v1/security-groups/nics/{vmNicUuid}/security-policy/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIChangeVmNicSecurityPolicyMsg.class + + desc """更改网卡的安全策略""" + + params { + + column { + name "vmNicUuid" + enclosedIn "changeVmNicSecurityPolicy" + desc "网卡的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "ingressPolicy" + enclosedIn "changeVmNicSecurityPolicy" + desc "网卡入方向安全策略" + location "body" + type "String" + optional true + since "4.7.21" + values ("DENY","ALLOW") + } + column { + name "egressPolicy" + enclosedIn "changeVmNicSecurityPolicy" + desc "网卡出方向安全策略" + location "body" + type "String" + optional true + since "4.7.21" + values ("DENY","ALLOW") + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIChangeVmNicSecurityPolicyEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsg.java index dfade9fe4de..aec49c60391 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsg.java @@ -6,8 +6,10 @@ import org.zstack.header.message.APIEvent; import org.zstack.header.message.APIMessage; import org.zstack.header.message.APIParam; +import org.zstack.header.network.l2.L2NetworkVO; import org.zstack.header.other.APIAuditor; import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; /** * @api @@ -45,6 +47,7 @@ * * see :ref:`APICreateSecurityGroupEvent` */ +@TagResourceType(SecurityGroupVO.class) @Action(category = SecurityGroupConstant.ACTION_CATEGORY) @RestRequest( path = "/security-groups", @@ -68,6 +71,20 @@ public class APICreateSecurityGroupMsg extends APICreateMessage implements APIAu @APIParam(required = false, validValues = {"4", "6"}) private Integer ipVersion; + /** + * @desc vSwitch type + */ + @APIParam(required = false, maxLength = 1024, validValues = {"LinuxBridge", "OvnDpdk"}) + private String vSwitchType = "LinuxBridge"; + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } + public String getName() { return name; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsgDoc_zh_cn.groovy index 25dece70dc1..556af7a2f0f 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APICreateSecurityGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "ipVersion" @@ -59,7 +57,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -69,7 +66,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -79,7 +75,25 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "vSwitchType" + enclosedIn "params" + desc "虚拟交换机类型,用于指定安全组所使用的网络虚拟化技术" + location "body" + type "String" + optional true + since "5.3.20" + values ("LinuxBridge","OvnDpdk") } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsg.java index 745c3c5b1b1..010755a2763 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsg.java @@ -52,7 +52,7 @@ method = HttpMethod.DELETE, responseClass = APIDeleteSecurityGroupEvent.class ) -public class APIDeleteSecurityGroupMsg extends APIDeleteMessage { +public class APIDeleteSecurityGroupMsg extends APIDeleteMessage implements SecurityGroupMessage { /** * @desc security group uuid */ @@ -66,6 +66,11 @@ public String getUuid() { public void setUuid(String securityGroupUuid) { this.uuid = securityGroupUuid; } + + @Override + public String getSecurityGroupUuid() { + return uuid; + } public static APIDeleteSecurityGroupMsg __example__() { APIDeleteSecurityGroupMsg msg = new APIDeleteSecurityGroupMsg(); diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsgDoc_zh_cn.groovy index 5fde9cfa506..a09b47a16e7 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleEvent.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleEvent.java index 4934df93e7c..e0aad3b0135 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleEvent.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleEvent.java @@ -28,10 +28,15 @@ "uuid": "4248355e4a534a2c8b0e9986ab0d00bc", "securityGroupUuid": "bb0538d800e54497b50710f449056a9f", "type": "Ingress", -"startPort": 22, -"endPort": 100, +"priority": 1, "protocol": "TCP", -"allowedCidr": "0.0.0.0/0", +"srcIpRange": "10.10.10.1,10.10.10.2", +"dstIpRange": "20.20.20.1,20.20.20.1", +"srcPortRange": "10,20", +"dstPortRange": "30,40", +"defaultTarget": "RETURN", +"state": "Enabled", +"remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", "createDate": "May 14, 2014 10:36:48 PM", "lastOpDate": "May 14, 2014 10:36:48 PM" } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsg.java index cb493de7fc0..a388e07979b 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsg.java @@ -25,6 +25,7 @@ * @httpMsg * { "org.zstack.network.securitygroup.APIDeleteSecurityGroupRuleMsg": { +"securityGroupUuid": "3904b4837f0c4f539063777ed463b648", "ruleUuids": [ "3f8e32673f2a429dbed7ea3e1041dd43" ], @@ -37,6 +38,7 @@ * @msg * { "org.zstack.network.securitygroup.APIDeleteSecurityGroupRuleMsg": { +"securityGroupUuid": "3904b4837f0c4f539063777ed463b648", "ruleUuids": [ "3f8e32673f2a429dbed7ea3e1041dd43" ], diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsgDoc_zh_cn.groovy index 63d2922b6c1..d5ae4c7d61a 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteSecurityGroupRuleMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteVmNicFromSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteVmNicFromSecurityGroupMsgDoc_zh_cn.groovy index 2829ce80e9b..d41f9b61c12 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteVmNicFromSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDeleteVmNicFromSecurityGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "vmNicUuids" @@ -39,7 +38,6 @@ doc { type "List" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsg.java index e2eafe887a9..3a56b38aa00 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsg.java @@ -45,7 +45,7 @@ method = HttpMethod.DELETE, responseClass = APIDetachSecurityGroupFromL3NetworkEvent.class ) -public class APIDetachSecurityGroupFromL3NetworkMsg extends APIMessage { +public class APIDetachSecurityGroupFromL3NetworkMsg extends APIMessage implements SecurityGroupMessage { /** * @desc security group uuid */ @@ -57,6 +57,7 @@ public class APIDetachSecurityGroupFromL3NetworkMsg extends APIMessage { @APIParam(resourceType = L3NetworkVO.class, checkAccount = true) private String l3NetworkUuid; + @Override public String getSecurityGroupUuid() { return securityGroupUuid; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsgDoc_zh_cn.groovy index 4cf0f08ef4c..9be50f9c800 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIDetachSecurityGroupFromL3NetworkMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "l3NetworkUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIGetCandidateVmNicForSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIGetCandidateVmNicForSecurityGroupMsgDoc_zh_cn.groovy index 00c67486b86..f69af466bd8 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIGetCandidateVmNicForSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIGetCandidateVmNicForSecurityGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupMsgDoc_zh_cn.groovy index d9817e2007e..fc2d47661e5 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.securitygroup import org.zstack.network.securitygroup.APIQuerySecurityGroupReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QuerySecurityGroup" diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleMsgDoc_zh_cn.groovy index 4eaba56b92e..664a82e9993 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.securitygroup import org.zstack.network.securitygroup.APIQuerySecurityGroupRuleReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QuerySecurityGroupRule" diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleReply.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleReply.java index 7b2b7b68233..762bfc6a430 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleReply.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQuerySecurityGroupRuleReply.java @@ -26,13 +26,18 @@ public static APIQuerySecurityGroupRuleReply __example__() { APIQuerySecurityGroupRuleReply reply = new APIQuerySecurityGroupRuleReply(); SecurityGroupRuleInventory rule = new SecurityGroupRuleInventory(); rule.setUuid(uuid()); - rule.setAllowedCidr("0.0.0.0/0"); - rule.setEndPort(22); - rule.setStartPort(22); + rule.setType("Ingress"); + rule.setIpVersion(4); + rule.setPriority(1); + rule.setState(SecurityGroupRuleState.Enabled.toString()); + rule.setSrcIpRange("1.1.1.1-1.1.1.10"); + rule.setDescription("test"); + rule.setAction(SecurityGroupRuleAction.ACCEPT.toString()); rule.setProtocol("TCP"); rule.setSecurityGroupUuid(uuid()); - rule.setState(SecurityGroupRuleState.Enabled.toString()); - rule.setType("Ingress"); + rule.setAllowedCidr("0.0.0.0/0"); + rule.setStartPort(-1); + rule.setEndPort(-1); rule.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); rule.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); reply.setInventories(asList(rule)); diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicInSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicInSecurityGroupMsgDoc_zh_cn.groovy index d6a53bf8546..d93b9a1a8c7 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicInSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicInSecurityGroupMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.securitygroup import org.zstack.network.securitygroup.APIQueryVmNicInSecurityGroupReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryVmNicInSecurityGroup" diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyMsg.java new file mode 100644 index 00000000000..c3a88c17790 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyMsg.java @@ -0,0 +1,26 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.List; + +import static java.util.Arrays.asList; + +@AutoQuery(replyClass = APIQueryVmNicSecurityPolicyReply.class, inventoryClass = VmNicSecurityPolicyInventory.class) +@Action(category = SecurityGroupConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/security-groups/nics/security-policy", + optionalPaths = {"/security-groups/nics/{uuid}/security-policy"}, + method = HttpMethod.GET, + responseClass = APIQueryVmNicSecurityPolicyReply.class +) + +public class APIQueryVmNicSecurityPolicyMsg extends APIQueryMessage { + public static List __example__() { + return asList("ingressPolicy=DROP", "egressPolicy=DROP"); + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..2ac0ab04fc3 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APIQueryVmNicSecurityPolicyReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QueryVmNicSecurityPolicy" + + category "securityGroup" + + desc """查询网卡的安全策略""" + + rest { + request { + url "GET /v1/security-groups/nics/security-policy" + url "GET /v1/security-groups/nics/{uuid}/security-policy" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQueryVmNicSecurityPolicyMsg.class + + desc """查询网卡的安全策略""" + + params APIQueryMessage.class + } + + response { + clz APIQueryVmNicSecurityPolicyReply.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyReply.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyReply.java new file mode 100644 index 00000000000..b78eb708f46 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyReply.java @@ -0,0 +1,35 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.sql.Timestamp; +import java.util.List; + +import static java.util.Arrays.asList; + +@RestResponse(allTo = "inventories") +public class APIQueryVmNicSecurityPolicyReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQueryVmNicSecurityPolicyReply __example__() { + APIQueryVmNicSecurityPolicyReply reply = new APIQueryVmNicSecurityPolicyReply(); + VmNicSecurityPolicyInventory inventory = new VmNicSecurityPolicyInventory(); + inventory.setVmNicUuid(uuid()); + inventory.setIngressPolicy("DROP"); + inventory.setEgressPolicy("ACCEPT"); + inventory.setCreateDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + inventory.setLastOpDate(new Timestamp(org.zstack.header.message.DocUtils.date)); + reply.setInventories(asList(inventory)); + reply.setSuccess(true); + return reply; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyReplyDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..ea326af2acf --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIQueryVmNicSecurityPolicyReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.VmNicSecurityPolicyInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组(Security Group)清单" + + ref { + name "inventories" + path "org.zstack.network.securitygroup.APIQueryVmNicSecurityPolicyReply.inventories" + desc "null" + type "List" + since "4.7.21" + clz VmNicSecurityPolicyInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APIQueryVmNicSecurityPolicyReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupEvent.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupEvent.java new file mode 100644 index 00000000000..9f0f05acdd7 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupEvent.java @@ -0,0 +1,40 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +import java.util.List; +import static java.util.Arrays.asList; + +@RestResponse(allTo = "inventory") +public class APISetVmNicSecurityGroupEvent extends APIEvent { + + private List inventory; + + public APISetVmNicSecurityGroupEvent() { + } + + public APISetVmNicSecurityGroupEvent(String apiId) { + super(apiId); + } + + public List getInventory() { + return inventory; + } + + public void setInventory(List inventory) { + this.inventory = inventory; + } + + public static APISetVmNicSecurityGroupEvent __example__() { + APISetVmNicSecurityGroupEvent event = new APISetVmNicSecurityGroupEvent(); + VmNicSecurityGroupRefInventory inv = new VmNicSecurityGroupRefInventory(); + inv.setUuid(uuid()); + inv.setPriority(1); + inv.setSecurityGroupUuid(uuid()); + event.setInventory(asList(inv)); + event.setSuccess(true); + return event; + } + +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupEventDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..cb1e720f775 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.VmNicSecurityGroupRefInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组(Security Group)清单" + + ref { + name "inventory" + path "org.zstack.network.securitygroup.APISetVmNicSecurityGroupEvent.inventory" + desc "null" + type "List" + since "4.7.21" + clz VmNicSecurityGroupRefInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APISetVmNicSecurityGroupEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupMsg.java new file mode 100644 index 00000000000..b5f5cf368ed --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupMsg.java @@ -0,0 +1,77 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vm.VmNicVO; + +import java.util.List; +import static java.util.Arrays.asList; + +@Action(category = SecurityGroupConstant.ACTION_CATEGORY) +@RestRequest( + path = "/security-groups/nics/{vmNicUuid}/actions", + method = HttpMethod.PUT, + responseClass = APISetVmNicSecurityGroupEvent.class, + isAction = true +) +public class APISetVmNicSecurityGroupMsg extends APIMessage implements VmNicSecurityGroupMessage { + @APIParam(resourceType = VmNicVO.class, nonempty = true, checkAccount = true, operationTarget = true, required = true) + private String vmNicUuid; + + @APIParam(required = true) + private List refs; + + public static class VmNicSecurityGroupRefAO { + @APIParam(resourceType = SecurityGroupVO.class, required = true, nonempty = true) + private String securityGroupUuid; + + @APIParam(required = true, nonempty = true) + private Integer priority; + + public String getSecurityGroupUuid() { + return securityGroupUuid; + } + + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + } + + @Override + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public List getRefs() { + return refs; + } + + public void setRefs(List refs) { + this.refs = refs; + } + + public static APISetVmNicSecurityGroupMsg __example__() { + APISetVmNicSecurityGroupMsg msg = new APISetVmNicSecurityGroupMsg(); + VmNicSecurityGroupRefAO ref = new VmNicSecurityGroupRefAO(); + ref.setSecurityGroupUuid(uuid()); + ref.setPriority(1); + msg.setVmNicUuid(uuid()); + msg.setRefs(asList(ref)); + return msg; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..5ec65d556de --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APISetVmNicSecurityGroupMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APISetVmNicSecurityGroupEvent + +doc { + title "SetVmNicSecurityGroup" + + category "securityGroup" + + desc """设置网卡的安全组""" + + rest { + request { + url "PUT /v1/security-groups/nics/{vmNicUuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APISetVmNicSecurityGroupMsg.class + + desc """设置网卡的安全组""" + + params { + + column { + name "vmNicUuid" + enclosedIn "setVmNicSecurityGroup" + desc "网卡的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "refs" + enclosedIn "setVmNicSecurityGroup" + desc "网卡挂载的安全组" + location "body" + type "List" + optional false + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APISetVmNicSecurityGroupEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsg.java index 4a47e182285..95eed780733 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsg.java @@ -18,6 +18,7 @@ responseClass = APIUpdateSecurityGroupEvent.class ) public class APIUpdateSecurityGroupMsg extends APIMessage implements SecurityGroupMessage { + @APIParam(resourceType = SecurityGroupVO.class, checkAccount = true, operationTarget = true) private String uuid; @APIParam(maxLength = 255, required = false) diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsgDoc_zh_cn.groovy index 955fa6b5835..6ff6ebbcb84 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsgDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityEvent.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityEvent.java new file mode 100644 index 00000000000..f0560c943c9 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityEvent.java @@ -0,0 +1,38 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + + +@RestResponse(allTo = "inventory") +public class APIUpdateSecurityGroupRulePriorityEvent extends APIEvent { + /** + * @desc :ref:`SecurityGroupInventory` + */ + private SecurityGroupInventory inventory; + public APIUpdateSecurityGroupRulePriorityEvent() { + } + + public APIUpdateSecurityGroupRulePriorityEvent(String apiId) { + super(apiId); + } + + public SecurityGroupInventory getInventory() { + return inventory; + } + + public void setInventory(SecurityGroupInventory inventory) { + this.inventory = inventory; + } + + public static APIUpdateSecurityGroupRulePriorityEvent __example__() { + APIUpdateSecurityGroupRulePriorityEvent event = new APIUpdateSecurityGroupRulePriorityEvent(); + SecurityGroupInventory inventory = new SecurityGroupInventory(); + inventory.setName("test"); + inventory.setUuid(uuid()); + event.setInventory(inventory); + event.setSuccess(true); + return event; + } + +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityEventDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..0f4fe014cd5 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.SecurityGroupInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组(Security Group)清单" + + ref { + name "inventory" + path "org.zstack.network.securitygroup.APIUpdateSecurityGroupRulePriorityEvent.inventory" + desc "null" + type "SecurityGroupInventory" + since "4.7.21" + clz SecurityGroupInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APIUpdateSecurityGroupRulePriorityEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityMsg.java new file mode 100644 index 00000000000..adacd9e695e --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityMsg.java @@ -0,0 +1,88 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +import java.util.List; +import static java.util.Arrays.asList; + +@Action(category = SecurityGroupConstant.ACTION_CATEGORY) +@RestRequest( + path = "/security-groups/{securityGroupUuid}/rules/priority/actions", + method = HttpMethod.PUT, + responseClass = APIUpdateSecurityGroupRulePriorityEvent.class, + isAction = true +) + +public class APIUpdateSecurityGroupRulePriorityMsg extends APIMessage implements SecurityGroupMessage { + public static class SecurityGroupRulePriorityAO { + @APIParam(resourceType = SecurityGroupRuleVO.class, checkAccount = true, operationTarget = true, nonempty = true, required = true) + private String ruleUuid; + @APIParam(required = true, nonempty = true) + private Integer priority; + + public String getRuleUuid() { + return ruleUuid; + } + + public void setRuleUuid(String ruleUuid) { + this.ruleUuid = ruleUuid; + } + + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + } + + @APIParam(resourceType = SecurityGroupVO.class, checkAccount = true, operationTarget = true, nonempty = true, required = true) + private String securityGroupUuid; + + @APIParam(required = true, validValues = {"Ingress", "Egress"}, nonempty = true) + private String type; + + @APIParam(required = true, nonempty = true) + private List rules; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } + + @Override + public String getSecurityGroupUuid() { + return securityGroupUuid; + } + + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; + } + + public static APIUpdateSecurityGroupRulePriorityMsg __example__() { + APIUpdateSecurityGroupRulePriorityMsg msg = new APIUpdateSecurityGroupRulePriorityMsg(); + msg.setSecurityGroupUuid(uuid()); + msg.setType("Ingress"); + SecurityGroupRulePriorityAO ao = new SecurityGroupRulePriorityAO(); + ao.setRuleUuid(uuid()); + ao.setPriority(1); + msg.setRules(asList(ao)); + return msg; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..df6640574c4 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIUpdateSecurityGroupRulePriorityMsgDoc_zh_cn.groovy @@ -0,0 +1,77 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APIUpdateSecurityGroupRulePriorityEvent + +doc { + title "UpdateSecurityGroupRulePriority" + + category "securityGroup" + + desc """更新安全组规则的优先级""" + + rest { + request { + url "PUT /v1/security-groups/{securityGroupUuid}/rules/priority/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateSecurityGroupRulePriorityMsg.class + + desc """更新安全组规则的优先级""" + + params { + + column { + name "securityGroupUuid" + enclosedIn "updateSecurityGroupRulePriority" + desc "安全组的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "type" + enclosedIn "updateSecurityGroupRulePriority" + desc "规则的类型" + location "body" + type "String" + optional false + since "4.7.21" + values ("Ingress","Egress") + } + column { + name "rules" + enclosedIn "updateSecurityGroupRulePriority" + desc "规则的优先级" + location "body" + type "List" + optional false + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.11" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIUpdateSecurityGroupRulePriorityEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleMsg.java new file mode 100644 index 00000000000..3d15432ecb4 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleMsg.java @@ -0,0 +1,162 @@ +package org.zstack.network.securitygroup; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.APISyncCallMessage; +import org.zstack.header.rest.RestRequest; + +@Action(category = SecurityGroupConstant.ACTION_CATEGORY, names = {"read"}) +@RestRequest( + path = "/security-groups/{securityGroupUuid}/rules/validation", + method = HttpMethod.GET, + responseClass = APIValidateSecurityGroupRuleReply.class +) +public class APIValidateSecurityGroupRuleMsg extends APISyncCallMessage { + + @APIParam(resourceType = SecurityGroupVO.class, checkAccount = true, operationTarget = true, required = true, nonempty = true) + private String securityGroupUuid; + + @APIParam(required = true, nonempty = true, validValues = {"Ingress", "Egress"}) + private String type; + + @APIParam(required = true, nonempty = true, validValues = {"TCP", "UDP", "ICMP", "ALL"}) + private String protocol; + + @APIParam(resourceType = SecurityGroupVO.class, required = false, nonempty = true) + private String remoteSecurityGroupUuid; + + @APIParam(required = false, validValues = {"4", "6"}) + private Integer ipVersion; + + @APIParam(required = false) + private String srcIpRange; + + @APIParam(required = false) + private String dstIpRange; + + @APIParam(required = false) + private String dstPortRange; + + @APIParam(required = false, nonempty = true, validValues = {"ACCEPT", "DROP"}) + private String action; + + @APIParam(required = false) + private Integer startPort; + + @APIParam(required = false) + private Integer endPort; + + @APIParam(required = false) + private String allowedCidr; + + public String getSecurityGroupUuid() { + return securityGroupUuid; + } + + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getRemoteSecurityGroupUuid() { + return remoteSecurityGroupUuid; + } + + public void setRemoteSecurityGroupUuid(String remoteSecurityGroupUuid) { + this.remoteSecurityGroupUuid = remoteSecurityGroupUuid; + } + + public Integer getIpVersion() { + return ipVersion; + } + + public void setIpVersion(Integer ipVersion) { + this.ipVersion = ipVersion; + } + + public String getSrcIpRange() { + return srcIpRange; + } + + public void setSrcIpRange(String srcIpRange) { + this.srcIpRange = srcIpRange; + } + + public String getDstIpRange() { + return dstIpRange; + } + + public void setDstIpRange(String dstIpRange) { + this.dstIpRange = dstIpRange; + } + + public String getDstPortRange() { + return dstPortRange; + } + + public void setDstPortRange(String dstPortRange) { + this.dstPortRange = dstPortRange; + } + + public String getAllowedCidr() { + return allowedCidr; + } + + public void setAllowedCidr(String allowedCidr) { + this.allowedCidr = allowedCidr; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public Integer getStartPort() { + return startPort; + } + + public void setStartPort(Integer startPort) { + this.startPort = startPort; + } + + public Integer getEndPort() { + return endPort; + } + + public void setEndPort(Integer endPort) { + this.endPort = endPort; + } + + public static APIValidateSecurityGroupRuleMsg __example__() { + APIValidateSecurityGroupRuleMsg msg = new APIValidateSecurityGroupRuleMsg(); + msg.setSecurityGroupUuid(uuid()); + msg.setType("Ingress"); + msg.setRemoteSecurityGroupUuid(uuid()); + msg.setIpVersion(4); + msg.setAction("ACCEPT"); + msg.setSrcIpRange("10.0.0.1,10.0.0.2-10.0.0.200,10.1.1.0/24"); + msg.setDstIpRange("10.0.0.1,10.0.0.2-10.0.0.200,10.1.1.0/24"); + msg.setProtocol("TCP"); + msg.setDstPortRange("1000,1001,1002-1005,1008"); + return msg; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleMsgDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..bbb37bec39f --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleMsgDoc_zh_cn.groovy @@ -0,0 +1,161 @@ +package org.zstack.network.securitygroup + +import org.zstack.network.securitygroup.APIValidateSecurityGroupRuleReply + +doc { + title "ValidateSecurityGroupRule" + + category "securityGroup" + + desc """检查安全组规则是否可用""" + + rest { + request { + url "GET /v1/security-groups/{securityGroupUuid}/rules/validation" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIValidateSecurityGroupRuleMsg.class + + desc """检查安全组规则是否可用""" + + params { + + column { + name "securityGroupUuid" + enclosedIn "" + desc "安全组的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "type" + enclosedIn "" + desc "安全组规则的方向" + location "query" + type "String" + optional false + since "4.7.21" + values ("Ingress","Egress") + } + column { + name "protocol" + enclosedIn "" + desc "安全组规则的协议类型" + location "query" + type "String" + optional false + since "4.7.21" + values ("TCP","UDP","ICMP","ALL") + } + column { + name "remoteSecurityGroupUuid" + enclosedIn "" + desc "远端安全组的UUID,唯一标示该资源" + location "query" + type "String" + optional true + since "4.7.21" + } + column { + name "ipVersion" + enclosedIn "" + desc "安全组规则的IP版本" + location "query" + type "Integer" + optional true + since "4.7.21" + values ("4","6") + } + column { + name "srcIpRange" + enclosedIn "" + desc "安全组规则的源ip范围" + location "query" + type "String" + optional true + since "4.7.21" + } + column { + name "dstIpRange" + enclosedIn "" + desc "安全组规则的目的ip范围" + location "query" + type "String" + optional true + since "4.7.21" + } + column { + name "dstPortRange" + enclosedIn "" + desc "安全组规则的目的端口范围" + location "query" + type "String" + optional true + since "4.7.21" + } + column { + name "action" + enclosedIn "" + desc "安全组规则的动作" + location "query" + type "String" + optional true + since "4.7.21" + values ("ACCEPT","DROP") + } + column { + name "startPort" + enclosedIn "" + desc "安全组规则的起始端口" + location "query" + type "Integer" + optional true + since "4.7.21" + } + column { + name "endPort" + enclosedIn "" + desc "安全组规则的结束端口" + location "query" + type "Integer" + optional true + since "4.7.21" + } + column { + name "allowedCidr" + enclosedIn "" + desc "安全组规则的ip范围" + location "query" + type "String" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIValidateSecurityGroupRuleReply.class + } + } +} \ No newline at end of file diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleReply.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleReply.java new file mode 100644 index 00000000000..5e71bb4c37c --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleReply.java @@ -0,0 +1,42 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +@RestResponse(fieldsTo = {"all"}) +public class APIValidateSecurityGroupRuleReply extends APIReply { + private boolean available; + private String code; + private String reason; + + public boolean isAvailable() { + return available; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public static APIValidateSecurityGroupRuleReply __example__() { + APIValidateSecurityGroupRuleReply reply = new APIValidateSecurityGroupRuleReply(); + reply.setAvailable(true); + reply.setCode(SecurityGroupErrors.RULE_CHECK_OK.toString()); + return reply; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleReplyDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..1d97bf3d481 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/APIValidateSecurityGroupRuleReplyDoc_zh_cn.groovy @@ -0,0 +1,41 @@ +package org.zstack.network.securitygroup + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "安全组规则可用性结果" + + field { + name "available" + desc "规则是否可用" + type "boolean" + since "4.7.21" + } + field { + name "code" + desc "规则检验错误码" + type "String" + since "4.7.21" + } + field { + name "reason" + desc "原因" + type "String" + since "4.7.21" + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.securitygroup.APIValidateSecurityGroupRuleReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMessage.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMessage.java index c49ff498a19..6bdd5518615 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMessage.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMessage.java @@ -10,5 +10,5 @@ public interface AddSecurityGroupRuleMessage { List getRules(); - List getRemoteSecurityGroupUuids(); + Integer getPriority(); } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMsg.java index e40f841a780..25c2312b611 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/AddSecurityGroupRuleMsg.java @@ -10,11 +10,12 @@ */ public class AddSecurityGroupRuleMsg extends NeedReplyMessage implements AddSecurityGroupRuleMessage { private String securityGroupUuid; + private String type; + private Integer priority = -1; /** * @desc a list of :ref:`SecurityGroupRuleAO` that describe rules */ private List rules; - private List remoteSecurityGroupUuids; public String getSecurityGroupUuid() { return securityGroupUuid; @@ -32,11 +33,19 @@ public void setRules(List rules) this.rules = rules; } - public List getRemoteSecurityGroupUuids() { - return remoteSecurityGroupUuids; + public Integer getPriority() { + return priority; } - public void setRemoteSecurityGroupUuids(List remoteSecurityGroupUuids) { - this.remoteSecurityGroupUuids = remoteSecurityGroupUuids; + public void setPriority(Integer priority) { + this.priority = priority; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/CreateSecurityGroupMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/CreateSecurityGroupMsg.java index 09288b5b55b..9d40e197548 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/CreateSecurityGroupMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/CreateSecurityGroupMsg.java @@ -9,6 +9,8 @@ public class CreateSecurityGroupMsg extends NeedReplyMessage { private String name; private String description; private String accountUuid; + private String vSwitchType = "LinuxBridge"; + private String sdnControllerUuid; public String getName() { return name; @@ -33,4 +35,20 @@ public String getAccountUuid() { public void setAccountUuid(String accountUuid) { this.accountUuid = accountUuid; } + + public String getSdnControllerUuid() { + return sdnControllerUuid; + } + + public void setSdnControllerUuid(String sdnControllerUuid) { + this.sdnControllerUuid = sdnControllerUuid; + } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/HostRuleTO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/HostRuleTO.java index 2ce9ae5ebdd..078e02bdc11 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/HostRuleTO.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/HostRuleTO.java @@ -1,29 +1,48 @@ package org.zstack.network.securitygroup; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.List; public class HostRuleTO { - private List rules; - private List ipv6Rules; + private List vmNics; + private Map> rules; + private Map> ip6Rules; private String hostUuid; private String hypervisorType; private boolean refreshHost; public HostRuleTO() { - rules = new ArrayList(); - ipv6Rules = new ArrayList(); + vmNics = new ArrayList(); + rules = new HashMap>(); + ip6Rules = new HashMap>(); + } + + public List getVmNics() { + return vmNics; + } + + public void setVmNics(List vmNics) { + this.vmNics = vmNics; } - public List getRules() { - if (rules == null) { - rules = new ArrayList(); - } + public Map> getRules() { return rules; } - public void setRules(List rules) { + + public void setRules(Map> rules) { this.rules = rules; } + + public Map> getIp6Rules() { + return ip6Rules; + } + + public void setIp6Rules(Map> ip6Rules) { + this.ip6Rules = ip6Rules; + } + public String getHostUuid() { return hostUuid; } @@ -42,24 +61,4 @@ public boolean isRefreshHost() { public void setRefreshHost(boolean refreshHost) { this.refreshHost = refreshHost; } - - public void setActionCodeForAllSecurityGroupRuleTOs(String actionCode) { - for (SecurityGroupRuleTO rto : rules) { - rto.setActionCode(actionCode); - } - for (SecurityGroupRuleTO rto : ipv6Rules) { - rto.setActionCode(actionCode); - } - } - - public List getIpv6Rules() { - if (ipv6Rules == null) { - ipv6Rules = new ArrayList(); - } - return ipv6Rules; - } - - public void setIpv6Rules(List ipv6Rules) { - this.ipv6Rules = ipv6Rules; - } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/PackageInfo.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/PackageInfo.java index 7e3413f2f14..0945ccfc937 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/PackageInfo.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "安全组") +@PackageAPIInfo( + APICategoryName = "安全组", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnHostMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnHostMsg.java index ffc82e6077d..7b08258f80b 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnHostMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnHostMsg.java @@ -1,8 +1,8 @@ package org.zstack.network.securitygroup; -import org.zstack.header.message.Message; +import org.zstack.header.message.NeedReplyMessage; -public class RefreshSecurityGroupRulesOnHostMsg extends Message { +public class RefreshSecurityGroupRulesOnHostMsg extends NeedReplyMessage { private String hostUuid; public String getHostUuid() { diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnVmMsg.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnVmMsg.java index 16ba4e342a8..506eed44bea 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnVmMsg.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RefreshSecurityGroupRulesOnVmMsg.java @@ -1,6 +1,7 @@ package org.zstack.network.securitygroup; import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.vm.VmInstanceConstant; import java.util.List; @@ -9,6 +10,8 @@ public class RefreshSecurityGroupRulesOnVmMsg extends NeedReplyMessage { private String hostUuid; private boolean deleteAllRules; private List vNicUuids; + private List sgUuids; + private VmInstanceConstant.VmOperation operation; public List getNicUuids() { return vNicUuids; } public void setNicUuids(List uuids) { this.vNicUuids = uuids; } @@ -36,4 +39,28 @@ public String getVmInstanceUuid() { public void setVmInstanceUuid(String vmInstanceUuid) { this.vmInstanceUuid = vmInstanceUuid; } + + public List getSgUuids() { + return sgUuids; + } + + public void setSgUuids(List sgUuids) { + this.sgUuids = sgUuids; + } + + public VmInstanceConstant.VmOperation getOperation() { + return operation; + } + + public void setOperation(VmInstanceConstant.VmOperation operation) { + this.operation = operation; + } + + public List getvNicUuids() { + return vNicUuids; + } + + public void setvNicUuids(List vNicUuids) { + this.vNicUuids = vNicUuids; + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RuleTO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RuleTO.java index 18fdb1a0bad..670e9934db2 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RuleTO.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/RuleTO.java @@ -1,18 +1,26 @@ package org.zstack.network.securitygroup; -import java.util.Collection; import java.util.List; public class RuleTO { private int ipVersion; + private int priority; + private String ruleType; + private String remoteGroupUuid; + private List remoteGroupVmIps; + private String state; private String protocol; - private String type; + private String srcIpRange; + private String dstIpRange; + private String dstPortRange; + private String action; + + @Deprecated private int startPort; + @Deprecated private int endPort; + @Deprecated private String allowedCidr; - private String securityGroupUuid; - private String remoteGroupUuid; - private List remoteGroupVmIps; public int getIpVersion() { return ipVersion; @@ -22,44 +30,67 @@ public void setIpVersion(int ipVersion) { this.ipVersion = ipVersion; } - public String getProtocol() { - return protocol; + public int getPriority() { + return priority; } - public void setProtocol(String protocol) { - this.protocol = protocol; + + public void setPriority(int priority) { + this.priority = priority; } - public String getType() { - return type; + + public String getState() { + return state; } - public void setType(String type) { - this.type = type; + + public void setState(String state) { + this.state = state; } - public int getStartPort() { - return startPort; + + public String getAction() { + return action; } - public void setStartPort(int startPort) { - this.startPort = startPort; + + public void setAction(String action) { + this.action = action; } - public int getEndPort() { - return endPort; + + public String getSrcIpRange() { + return srcIpRange; } - public void setEndPort(int endPort) { - this.endPort = endPort; + + public void setSrcIpRange(String srcIpRange) { + this.srcIpRange = srcIpRange == null ? null : srcIpRange.replaceAll("\\s+", ""); } - public String getAllowedCidr() { - return allowedCidr; + public String getDstIpRange() { + return dstIpRange; } - public void setAllowedCidr(String allowedCidr) { - this.allowedCidr = allowedCidr; + + public void setDstIpRange(String dstIpRange) { + this.dstIpRange = dstIpRange == null ? null : dstIpRange.replaceAll("\\s+", ""); } - public void setSecurityGroupUuid(String securityGroupUuid) { - this.securityGroupUuid = securityGroupUuid; + public String getDstPortRange() { + return dstPortRange; } - public String getSecurityGroupUuid() { - return securityGroupUuid; + public void setDstPortRange(String dstPortRange) { + this.dstPortRange = dstPortRange == null ? null : dstPortRange.replaceAll("\\s+", ""); + } + + public String getProtocol() { + return protocol; + } + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getRuleType() { + return ruleType; + } + + public void setRuleType(String ruleType) { + this.ruleType = ruleType; } public void setRemoteGroupVmIps(List remoteGroupVmIps) { @@ -78,16 +109,43 @@ public List getRemoteGroupVmIps() { return remoteGroupVmIps; } + @Deprecated + public int getStartPort() { + return startPort; + } + @Deprecated + public void setStartPort(int startPort) { + this.startPort = startPort; + } + @Deprecated + public int getEndPort() { + return endPort; + } + @Deprecated + public void setEndPort(int endPort) { + this.endPort = endPort; + } + @Deprecated + public String getAllowedCidr() { + return allowedCidr; + } + @Deprecated + public void setAllowedCidr(String allowedCidr) { + this.allowedCidr = allowedCidr; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format("ipVersion: %s,", this.ipVersion)); - sb.append(String.format("type: %s,", this.type)); + sb.append(String.format("type: %s,", this.ruleType)); + sb.append(String.format("state: %s,", this.state)); + sb.append(String.format("priority: %s,", this.priority)); + sb.append(String.format("action: %s,", this.action)); + sb.append(String.format("srcIpRange: %s,", this.srcIpRange)); + sb.append(String.format("dstIpRange: %s,", this.dstIpRange)); sb.append(String.format("protocol: %s,", this.protocol)); - sb.append(String.format("startPort: %s,", this.startPort)); - sb.append(String.format("endPort: %s,", this.endPort)); - sb.append(String.format("allowedCidr: %s,", this.allowedCidr)); - sb.append(String.format("securityGroupUuid: %s,", this.securityGroupUuid)); + sb.append(String.format("dstPortRange: %s,", this.dstPortRange)); sb.append(String.format("remoteGroupUuid: %s,", this.remoteGroupUuid)); sb.append(String.format("remoteGroupVmIps: %s", this.remoteGroupVmIps)); return sb.toString(); @@ -96,12 +154,14 @@ public String toString() { public String toFullString() { StringBuilder sb = new StringBuilder(); sb.append(String.format("ipVersion: %s,", this.ipVersion)); - sb.append(String.format("type: %s,", this.type)); + sb.append(String.format("type: %s,", this.ruleType)); + sb.append(String.format("state: %s,", this.state)); + sb.append(String.format("priority: %s", this.priority)); + sb.append(String.format("action: %s,", this.action)); + sb.append(String.format("srcIpRange: %s,", this.srcIpRange)); + sb.append(String.format("dstIpRange: %s,", this.dstIpRange)); sb.append(String.format("protocol: %s,", this.protocol)); - sb.append(String.format("startPort: %s,", this.startPort)); - sb.append(String.format("endPort: %s,", this.endPort)); - sb.append(String.format("allowedCidr: %s,", this.allowedCidr)); - sb.append(String.format("securityGroupUuid: %s", this.securityGroupUuid)); + sb.append(String.format("dstPortRange: %s,", this.dstPortRange)); sb.append(String.format("remoteGroupUuid: %s", this.remoteGroupUuid)); sb.append(String.format("remoteGroupVmIps: %s", this.remoteGroupVmIps)); return sb.toString(); diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java index a1b90d37e0d..3bd2f78aa36 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupApiInterceptor.java @@ -11,28 +11,50 @@ import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.apimediator.StopRoutingException; import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.identity.AccountConstant; +import org.zstack.header.identity.AccountResourceRefVO; +import org.zstack.header.identity.AccountResourceRefVO_; +import org.zstack.header.identity.APIChangeResourceOwnerMsg; +import org.zstack.identity.Account; +import org.zstack.identity.QuotaUtil; import org.zstack.header.message.APIMessage; -import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO; import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO_; +import org.zstack.header.vm.VmInstanceVO; import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; -import org.zstack.network.securitygroup.APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO; +import org.zstack.utils.Utils; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; +import org.zstack.utils.logging.CLogger; + +import org.apache.commons.lang.StringUtils; import javax.persistence.TypedQuery; + import java.util.ArrayList; +import java.util.Arrays; + +import static java.util.Arrays.asList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Comparator; +import java.util.stream.Stream; +import java.util.stream.Collectors; import static org.zstack.core.Platform.*; /** */ -public class SecurityGroupApiInterceptor implements ApiMessageInterceptor { +public class SecurityGroupApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { + private static CLogger logger = Utils.getLogger(SecurityGroupApiInterceptor.class); + @Autowired private CloudBus bus; @Autowired @@ -40,6 +62,32 @@ public class SecurityGroupApiInterceptor implements ApiMessageInterceptor { @Autowired private ErrorFacade errf; + private void setServiceId(APIMessage msg) { + if (msg instanceof AddSecurityGroupRuleMessage) { + AddSecurityGroupRuleMessage amsg = (AddSecurityGroupRuleMessage)msg; + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, amsg.getSecurityGroupUuid()); + } else if (msg instanceof SecurityGroupMessage) { + SecurityGroupMessage smsg = (SecurityGroupMessage)msg; + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, smsg.getSecurityGroupUuid()); + } else if (msg instanceof VmNicSecurityGroupMessage) { + VmNicSecurityGroupMessage vmsg = (VmNicSecurityGroupMessage)msg; + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, vmsg.getVmNicUuid()); + } + } + + + @Override + public List getMessageClassToIntercept() { + List ret = new ArrayList<>(); + ret.add(APIChangeResourceOwnerMsg.class); + return ret; + } + + @Override + public InterceptorPosition getPosition() { + return InterceptorPosition.END; + } + @Override public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { if (msg instanceof APIAddSecurityGroupRuleMsg) { @@ -58,11 +106,720 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIDetachSecurityGroupFromL3NetworkMsg) msg); } if (msg instanceof APICreateSecurityGroupMsg) { validate((APICreateSecurityGroupMsg) msg); + } else if (msg instanceof APIChangeSecurityGroupRuleMsg) { + validate((APIChangeSecurityGroupRuleMsg) msg); + } else if (msg instanceof APIUpdateSecurityGroupRulePriorityMsg) { + validate((APIUpdateSecurityGroupRulePriorityMsg) msg); + } else if (msg instanceof APIChangeVmNicSecurityPolicyMsg) { + validate((APIChangeVmNicSecurityPolicyMsg) msg); + } else if (msg instanceof APIChangeSecurityGroupRuleStateMsg) { + validate((APIChangeSecurityGroupRuleStateMsg) msg); + } else if (msg instanceof APISetVmNicSecurityGroupMsg) { + validate((APISetVmNicSecurityGroupMsg) msg); + } else if (msg instanceof APIValidateSecurityGroupRuleMsg) { + validate((APIValidateSecurityGroupRuleMsg) msg); + } else if (msg instanceof APIChangeResourceOwnerMsg) { + validate((APIChangeResourceOwnerMsg) msg); } + setServiceId(msg); + return msg; } + private String normalizeIpOrPort(String value) { + return value == null ? null : StringUtils.deleteWhitespace(value); + } + + private void validate(APIChangeResourceOwnerMsg msg) { + AccountResourceRefVO ref = Q.New(AccountResourceRefVO.class).eq(AccountResourceRefVO_.resourceUuid, msg.getResourceUuid()).find(); + if (ref == null) { + return; + } + + if (VmInstanceVO.class.getSimpleName().equals(ref.getResourceType())) { + List nics = SQL.New("select sgRef.vmNicUuid from VmInstanceVO vm, VmNicVO nic, VmNicSecurityGroupRefVO sgRef" + + " where vm.uuid = :vmUuid" + + " and nic.vmInstanceUuid = vm.uuid" + + " and sgRef.vmNicUuid = nic.uuid", String.class) + .param("vmUuid", ref.getResourceUuid()) + .list(); + if (!nics.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could not change resource owner, because the resource[uuid:%s, type:VmInstance] has already attached security group", msg.getResourceUuid())); + } + } + } + + private void validate(APIValidateSecurityGroupRuleMsg msg) { + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, msg.getSecurityGroupUuid()).isExists()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RESOURCE_NOT_EXIST_ERROR, "invalid security group rule, because security group[uuid:%s] not found", msg.getSecurityGroupUuid())); + } + + if (msg.getRemoteSecurityGroupUuid() != null) { + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, msg.getRemoteSecurityGroupUuid()).isExists()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RESOURCE_NOT_EXIST_ERROR, "invalid security group rule, because remote security group[uuid:%s] not found", msg.getRemoteSecurityGroupUuid())); + } + } + + if (msg.getIpVersion() == null) { + msg.setIpVersion(IPv6Constants.IPv4); + } + if (msg.getAction() == null) { + msg.setAction(SecurityGroupRuleAction.ACCEPT.toString()); + } + + if (msg.getAllowedCidr() == null) { + msg.setAllowedCidr(msg.getIpVersion() == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + } else { + //remove extra space characters + msg.setAllowedCidr(normalizeIpOrPort(msg.getAllowedCidr())); + validateIps(msg.getAllowedCidr(), msg.getIpVersion()); + } + + if (msg.getStartPort() == null) { + msg.setStartPort(-1); + } + + if (msg.getEndPort() == null) { + msg.setEndPort(-1); + } + + if (msg.getSrcIpRange() != null) { + msg.setSrcIpRange(normalizeIpOrPort(msg.getSrcIpRange()));; + validateIps(msg.getSrcIpRange(), msg.getIpVersion()); + } + + if (msg.getDstIpRange() != null) { + msg.setDstIpRange(normalizeIpOrPort(msg.getDstIpRange())); + validateIps(msg.getDstIpRange(), msg.getIpVersion()); + } + + if (msg.getDstPortRange() != null) { + msg.setDstPortRange(normalizeIpOrPort(msg.getDstPortRange())); + validatePorts(msg.getDstPortRange()); + } + + if (SecurityGroupRuleProtocolType.ALL.toString().equals(msg.getProtocol()) || SecurityGroupRuleProtocolType.ICMP.toString().equals(msg.getProtocol())) { + if (msg.getStartPort() != -1 || msg.getEndPort() != -1) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid security group rule, because startPort and endPort must be -1 when protocol is ALL or ICMP")); + } + } else { + if (msg.getStartPort() > msg.getEndPort()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid security group rule, because invalid endPort[%d], endPort must be greater than or equal to startPort[%d]", msg.getEndPort(), msg.getStartPort())); + } + if (msg.getStartPort() > 65535) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid security group rule, because startPort[%d] must less than 65535 when protocol is[%s]", msg.getStartPort(), msg.getProtocol())); + } + } + + if (msg.getRemoteSecurityGroupUuid() != null) { + if (msg.getSrcIpRange() != null || msg.getDstIpRange() != null) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_CONFLICT_ERROR, "remoteSecurityGroupUuid[%s] and srcIpRange/dstIpRange cannot be set at the same time", msg.getRemoteSecurityGroupUuid())); + } + if (!SecurityGroupConstant.WORLD_OPEN_CIDR.equals(msg.getAllowedCidr()) && !SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6.equals(msg.getAllowedCidr())) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_CONFLICT_ERROR, "remoteSecurityGroupUuid[%s] and allowedCidr[%s] cannot be set at the same time", msg.getRemoteSecurityGroupUuid(), msg.getAllowedCidr())); + } + } + + if (msg.getSrcIpRange() != null) { + if (msg.getDstIpRange() != null) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_CONFLICT_ERROR, "srcIpRange[%s] and dstIpRange[%s] cannot be set at the same time", msg.getSrcIpRange(), msg.getDstIpRange())); + } + if (SecurityGroupRuleType.Egress.toString().equals(msg.getType())) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_NOT_SUPPORT_ERROR, "srcIpRange cannot be set in Egress rule")); + } + } + + if (msg.getDstIpRange() != null) { + if (SecurityGroupRuleType.Ingress.toString().equals(msg.getType())) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_NOT_SUPPORT_ERROR, "dstIpRange cannot be set in Ingress rule")); + } + } + + if (msg.getDstPortRange() != null) { + if (SecurityGroupRuleProtocolType.ALL.toString().equals(msg.getProtocol()) || SecurityGroupRuleProtocolType.ICMP.toString().equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_NOT_SUPPORT_ERROR, "dstPortRange cannot be set when rule protocol is ALL or ICMP")); + } + + if (msg.getStartPort() != -1 || msg.getEndPort() != -1) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_CONFLICT_ERROR, "dstPortRange and startPort/endPort cannot be set at the same time")); + } + } else if (msg.getStartPort() >= 0) { + if (msg.getStartPort().equals(msg.getEndPort())) { + msg.setDstPortRange(String.valueOf(msg.getStartPort())); + } else { + msg.setDstPortRange(String.format("%s-%s", msg.getStartPort(), msg.getEndPort())); + } + } + + if (!SecurityGroupConstant.WORLD_OPEN_CIDR.equals(msg.getAllowedCidr()) && !SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6.equals(msg.getAllowedCidr())) { + if (msg.getSrcIpRange() != null || msg.getDstIpRange() != null) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_FILED_CONFLICT_ERROR, "allowCidr and srcIpRange/dstIpRange cannot be set at the same time")); + } + + if (SecurityGroupRuleType.Ingress.toString().equals(msg.getType())) { + msg.setSrcIpRange(msg.getAllowedCidr()); + } else { + msg.setDstIpRange(msg.getAllowedCidr()); + } + } + + APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO targetRule = new APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO(); + targetRule.setType(msg.getType()); + targetRule.setRemoteSecurityGroupUuid(msg.getRemoteSecurityGroupUuid()); + targetRule.setAction(msg.getAction()); + targetRule.setProtocol(msg.getProtocol()); + targetRule.setIpVersion(msg.getIpVersion()); + targetRule.setDstIpRange(msg.getDstIpRange()); + targetRule.setSrcIpRange(msg.getSrcIpRange()); + targetRule.setDstPortRange(msg.getDstPortRange()); + + // Deduplicate in DB + List vos = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getSecurityGroupUuid()).eq(SecurityGroupRuleVO_.type, SecurityGroupRuleType.valueOf(msg.getType())).list(); + + for (SecurityGroupRuleVO vo : vos) { + APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO ao = new APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO(); + ao.setType(vo.getType().toString()); + ao.setProtocol(vo.getProtocol().toString()); + ao.setIpVersion(vo.getIpVersion()); + ao.setRemoteSecurityGroupUuid(vo.getRemoteSecurityGroupUuid()); + ao.setAction(vo.getAction()); + ao.setSrcIpRange(vo.getSrcIpRange()); + ao.setDstIpRange(vo.getDstIpRange()); + ao.setDstPortRange(vo.getDstPortRange()); + if (ao.equals(targetRule)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_DUPLICATE_ERROR, "duplicated to rule[uuid:%s] in datebase", vo.getUuid())); + } + } + } + + private void validate(APISetVmNicSecurityGroupMsg msg) { + VmNicVO nic = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).find(); + if (nic == null) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because vm nic[uuid:%s] not found", msg.getVmNicUuid())); + } + + List refs = Q.New(VmNicSecurityGroupRefVO.class).eq(VmNicSecurityGroupRefVO_.vmNicUuid, msg.getVmNicUuid()).list(); + + if (msg.getRefs().isEmpty() && refs.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because the vm nic[uuid:%s] not attached to any security group", msg.getVmNicUuid())); + } + + Map aoMap = new HashMap(); + List adminIntegers = new ArrayList<>(); + final String vmAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(nic.getVmInstanceUuid()); + for (APISetVmNicSecurityGroupMsg.VmNicSecurityGroupRefAO ao : msg.getRefs()) { + + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, ao.getSecurityGroupUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because security group[uuid:%s] not found", ao.getSecurityGroupUuid())); + } + + Integer priority = ao.getPriority(); + if (priority < 1) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because invalid priority, priority[%d] cannot be less than 1", priority)); + } + + if (aoMap.containsKey(priority)) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because duplicate priority, both security group %s and %s have priority[%d]", aoMap.get(priority), ao.getSecurityGroupUuid(), priority)); + } + if (aoMap.containsValue(ao.getSecurityGroupUuid())) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because duplicate security group[uuid:%s]", ao.getSecurityGroupUuid())); + } + aoMap.put(priority, ao.getSecurityGroupUuid()); + + if (!refs.stream().anyMatch(r -> r.getSecurityGroupUuid().equals(ao.getSecurityGroupUuid()))) { + checkIfL3NetworkSupportSecurityGroup(asList(msg.getVmNicUuid())); + } + + String sgOwnerAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(ao.getSecurityGroupUuid()); + if (!AccountConstant.isAdminPermission(sgOwnerAccountUuid) && !AccountConstant.isAdminPermission(vmAccountUuid) && !sgOwnerAccountUuid.equals(vmAccountUuid)) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because security group[uuid:%s] is not owned by account[uuid:%s] or admin", ao.getSecurityGroupUuid(), vmAccountUuid)); + } + if (AccountConstant.isAdminPermission(sgOwnerAccountUuid)) { + adminIntegers.add(priority); + } + } + if (!aoMap.isEmpty()) { + Integer[] priorities = aoMap.keySet().toArray(new Integer[aoMap.size()]); + Arrays.sort(priorities); + if (priorities[0] != 1) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because invalid priority, priority expects to start at 1, but [%d]", priorities[0])); + } + for (int i = 0; i < priorities.length - 1; i++) { + if (priorities[i] + 1 != priorities[i + 1]) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because invalid priority, priority[%d] and priority[%d] expected to be consecutive", priorities[i], priorities[i + 1])); + } + } + } + + + if (!AccountConstant.isAdminPermission(msg.getSession())) { + List userRefs = new ArrayList<>(); + List otherRefs = new ArrayList<>(); + + for (VmNicSecurityGroupRefVO ref : refs) { + String sgOwnerAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(ref.getSecurityGroupUuid()); + if (sgOwnerAccountUuid.equals(vmAccountUuid)) { + userRefs.add(ref); + } else { + otherRefs.add(ref); + } + } + + List sortedOtherRefs = otherRefs.stream().sorted(Comparator.comparingInt(VmNicSecurityGroupRefVO::getPriority)).collect(Collectors.toList()); + List sortedUserAOs = msg.getRefs().stream().sorted(Comparator.comparingInt(APISetVmNicSecurityGroupMsg.VmNicSecurityGroupRefAO::getPriority)).collect(Collectors.toList()); + + if (!sortedOtherRefs.isEmpty()) { + int count = sortedOtherRefs.size(); + List newAOs = new ArrayList<>(); + sortedOtherRefs.forEach(r -> { + APISetVmNicSecurityGroupMsg.VmNicSecurityGroupRefAO ao = new APISetVmNicSecurityGroupMsg.VmNicSecurityGroupRefAO(); + ao.setPriority(sortedOtherRefs.indexOf(r) + 1); + ao.setSecurityGroupUuid(r.getSecurityGroupUuid()); + newAOs.add(ao); + }); + sortedUserAOs.forEach(a -> { + a.setPriority(sortedUserAOs.indexOf(a) + count + 1); + newAOs.add(a); + }); + + msg.setRefs(newAOs); + } + } else { + if (!adminIntegers.isEmpty()) { + Integer[] priorities = adminIntegers.toArray(new Integer[adminIntegers.size()]); + Arrays.sort(priorities); + if (priorities[0] != 1) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because admin security group priority[%d] must be higher than users", priorities[0])); + } + for (int i = 0; i < priorities.length - 1; i++) { + if (priorities[i] + 1 != priorities[i + 1]) { + throw new ApiMessageInterceptionException(argerr("could no set vm nic security group, because admin security group priority[%d] must be higher than users", priorities[i + 1])); + } + } + } + } + } + + private void validate(APIChangeSecurityGroupRuleStateMsg msg) { + if (msg.getRuleUuids().isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could no change security group rule state, because ruleUuids is empty")); + } + + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, msg.getSecurityGroupUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could no change security group rule state, because security group[uuid:%s] not found", msg.getSecurityGroupUuid())); + } + + List toChange = new ArrayList<>(); + List rvos = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getSecurityGroupUuid()).in(SecurityGroupRuleVO_.uuid, msg.getRuleUuids()).list(); + msg.getRuleUuids().stream().forEach(r -> { + SecurityGroupRuleVO vo = rvos.stream().filter(rvo -> rvo.getUuid().equals(r)).findAny().get(); + if (vo == null) { + throw new ApiMessageInterceptionException(argerr("could no change security group rule state, because security group rule[uuid:%s] not found", r)); + } + + if (!vo.getState().toString().equals(msg.getState())) { + toChange.add(r); + } + }); + + if (toChange.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could no change security group rule state, because no security group rule state need to change")); + } else { + msg.setRuleUuids(toChange); + } + } + + private void validate(APIChangeVmNicSecurityPolicyMsg msg) { + if (msg.getIngressPolicy() == null && msg.getEgressPolicy() == null) { + throw new ApiMessageInterceptionException(argerr("could no change vm nic security policy, because ingress policy and egress policy cannot be both null")); + } + if (msg.getIngressPolicy() != null && !VmNicSecurityPolicy.isValid(msg.getIngressPolicy())) { + throw new ApiMessageInterceptionException(argerr("could no change vm nic security policy, because invalid ingress policy[%s]", msg.getIngressPolicy())); + } + + if (msg.getEgressPolicy() != null && !VmNicSecurityPolicy.isValid(msg.getEgressPolicy())) { + throw new ApiMessageInterceptionException(argerr("could no change vm nic security policy, because invalid egress policy[%s]", msg.getEgressPolicy())); + } + + if (!Q.New(VmNicVO.class).eq(VmNicVO_.uuid, msg.getVmNicUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could no change vm nic security policy, because vm nic[uuid:%s] not found", msg.getVmNicUuid())); + } + + VmNicSecurityPolicyVO policy = Q.New(VmNicSecurityPolicyVO.class).eq(VmNicSecurityPolicyVO_.vmNicUuid, msg.getVmNicUuid()).find(); + if (policy == null) { + throw new ApiMessageInterceptionException(argerr("could no change vm nic security policy, because vm nic[uuid:%s] has no security policy", msg.getVmNicUuid())); + } + + if (policy.getIngressPolicy().equals(msg.getIngressPolicy())) { + msg.setIngressPolicy(null); + } + + if (policy.getEgressPolicy().equals(msg.getEgressPolicy())) { + msg.setEgressPolicy(null); + } + } + + private void validate(APIUpdateSecurityGroupRulePriorityMsg msg) { + if (!SecurityGroupRuleType.isValid(msg.getType())) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because invalid type[%s]", msg.getType())); + } + + SecurityGroupVO sgvo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + if (sgvo == null) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because security group[uuid:%s] is not exist", msg.getSecurityGroupUuid())); + } + + if (msg.getRules().isEmpty()) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because rules is empty")); + } + + HashMap priorityMap = new HashMap(); + List rvos = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getSecurityGroupUuid()) + .eq(SecurityGroupRuleVO_.type, SecurityGroupRuleType.valueOf(msg.getType())) + .notEq(SecurityGroupRuleVO_.priority, SecurityGroupConstant.DEFAULT_RULE_PRIORITY) + .list(); + if (rvos.size() != msg.getRules().size()) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because security group[uuid:%s] rules size not match", msg.getSecurityGroupUuid())); + } + + for (APIUpdateSecurityGroupRulePriorityMsg.SecurityGroupRulePriorityAO ao : msg.getRules()) { + if (ao.getPriority() == SecurityGroupConstant.DEFAULT_RULE_PRIORITY) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because rule priority[%d] is invalid", ao.getPriority())); + } + if (priorityMap.containsKey(ao.getPriority())) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because priority[%d] has duplicate", ao.getPriority())); + } else { + priorityMap.put(ao.getPriority(), ao.getRuleUuid()); + } + + rvos.stream().filter(rvo -> rvo.getUuid().equals(ao.getRuleUuid())).findFirst().orElseThrow(() -> + new ApiMessageInterceptionException(argerr("could not update security group rule priority, because rule[uuid:%s] not in security group[uuid:%s]", ao.getRuleUuid(), msg.getSecurityGroupUuid()))); + + rvos.stream().filter(rvo -> rvo.getPriority() == ao.getPriority()).findFirst().orElseThrow(() -> + new ApiMessageInterceptionException(argerr("could not update security group rule priority, because priority[%d] not in security group[uuid:%s]", ao.getPriority(), msg.getSecurityGroupUuid()))); + } + + List uuidList = new ArrayList<>(priorityMap.values()); + if ((int)uuidList.stream().distinct().count() != uuidList.size()) { + throw new ApiMessageInterceptionException(argerr("could not update security group rule priority, because rule uuid duplicate")); + } + } + + private void validate(APIChangeSecurityGroupRuleMsg msg) { + SecurityGroupRuleVO vo = Q.New(SecurityGroupRuleVO.class).eq((SecurityGroupRuleVO_.uuid), msg.getUuid()).find(); + if (vo == null) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule uuid[%s] is not exist", msg.getUuid())); + } + + if (vo.getPriority() == 0) { + if (msg.getProtocol() != null || msg.getAction() != null || msg.getRemoteSecurityGroupUuid() != null || msg.getSrcIpRange() != null + || msg.getDstIpRange() != null || msg.getDstPortRange() != null || msg.getPriority() != null) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule[%s] is default rule, only the description and status can be set", msg.getUuid())); + } + } + + if (msg.getPriority() != null) { + if (msg.getPriority() == SecurityGroupConstant.DEFAULT_RULE_PRIORITY) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule[%s] priority cannot be set to default rule priority[%d]", msg.getUuid(), SecurityGroupConstant.DEFAULT_RULE_PRIORITY)); + } + + Long count = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, vo.getSecurityGroupUuid()) + .eq(SecurityGroupRuleVO_.type, vo.getType()) + .notEq(SecurityGroupRuleVO_.priority, SecurityGroupConstant.DEFAULT_RULE_PRIORITY) + .count(); + if (count.intValue() > SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group %s rules number[%d] is out of max limit[%d]", vo.getType(), count.intValue(), SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class))); + } + if (msg.getPriority() > count.intValue()) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because the maximum priority of %s rule is [%d]", vo.getType().toString(), count.intValue())); + } + if (msg.getPriority() < 0) { + msg.setPriority(SecurityGroupConstant.LOWEST_RULE_PRIORITY); + } + } + + if (msg.getState() != null) { + if (!SecurityGroupRuleState.isValid(msg.getState())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because invalid state[%s]", msg.getState())); + } + } else { + msg.setState(vo.getState().toString()); + } + + if (msg.getAction() != null) { + if (!SecurityGroupRuleAction.isValid(msg.getAction())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because invalid action[%s]", msg.getAction())); + } + } else { + msg.setAction(vo.getAction()); + } + + if (msg.getProtocol() != null) { + if (!SecurityGroupRuleProtocolType.isValid(msg.getProtocol())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because invalid protocol[%s]", msg.getProtocol())); + } + } else { + msg.setProtocol(vo.getProtocol().toString()); + } + + if (msg.getDescription() != null) { + if (msg.getDescription().isEmpty()) { + msg.setDescription(null); + } + } else { + msg.setDescription(vo.getDescription()); + } + + if (StringUtils.isNotEmpty(msg.getSrcIpRange())) { + if (SecurityGroupRuleType.Egress.equals(vo.getType())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule[%s] type is Egress, srcIpRange[%s] cannot be set", msg.getUuid(), msg.getSrcIpRange())); + } + if (StringUtils.isNotEmpty(msg.getDstIpRange())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule[%s] type is Ingress, dstIpRange[%s] cannot be set", msg.getUuid(), msg.getDstIpRange())); + } + if (StringUtils.isNotEmpty(msg.getRemoteSecurityGroupUuid())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because srcIpRange[%s] is set, remoteSecurityGroupUuid[%s] must be empty", msg.getSrcIpRange(), msg.getRemoteSecurityGroupUuid())); + } + + msg.setSrcIpRange(normalizeIpOrPort(msg.getSrcIpRange())); + validateIps(msg.getSrcIpRange(), vo.getIpVersion()); + } + + if (StringUtils.isNotEmpty(msg.getDstIpRange())) { + if (SecurityGroupRuleType.Ingress.equals(vo.getType())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule[%s] type is Ingress, dstIpRange[%s] cannot be set", msg.getUuid(), msg.getDstIpRange())); + } + if (StringUtils.isNotEmpty(msg.getSrcIpRange())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because security group rule[%s] type is Egress, srcIpRange[%s] cannot be set", msg.getUuid(), msg.getSrcIpRange())); + } + if (StringUtils.isNotEmpty(msg.getRemoteSecurityGroupUuid())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because dstIpRange[%s] is set, remoteSecurityGroupUuid[%s] must be empty", msg.getDstIpRange(), msg.getRemoteSecurityGroupUuid())); + } + + msg.setDstIpRange(normalizeIpOrPort(msg.getDstIpRange())); + validateIps(msg.getDstIpRange(), vo.getIpVersion()); + } + + if (StringUtils.isNotEmpty(msg.getRemoteSecurityGroupUuid())) { + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, msg.getRemoteSecurityGroupUuid()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because remote security group[uuid:%s] not found", msg.getRemoteSecurityGroupUuid())); + } + if (StringUtils.isNotEmpty(msg.getSrcIpRange()) || StringUtils.isNotEmpty(msg.getDstIpRange())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because remote security group[uuid:%s] is set, srcIpRange and dstIpRange must be empty", msg.getRemoteSecurityGroupUuid())); + } + } + + if (StringUtils.isNotEmpty(msg.getSrcIpRange()) || StringUtils.isNotEmpty(msg.getDstIpRange()) || StringUtils.isNotEmpty(msg.getRemoteSecurityGroupUuid())) { + if (StringUtils.isNotEmpty(msg.getSrcIpRange())) { + msg.setRemoteSecurityGroupUuid(null); + msg.setDstIpRange(null); + } + if (StringUtils.isNotEmpty(msg.getDstIpRange())) { + msg.setRemoteSecurityGroupUuid(null); + msg.setSrcIpRange(null); + } + if (StringUtils.isNotEmpty(msg.getRemoteSecurityGroupUuid())) { + msg.setSrcIpRange(null); + msg.setDstIpRange(null); + } + } else { + if (msg.getSrcIpRange() != null && msg.getSrcIpRange().isEmpty()) { + msg.setSrcIpRange(null); + } else { + msg.setSrcIpRange(vo.getSrcIpRange()); + } + + if (msg.getDstIpRange() != null && msg.getDstIpRange().isEmpty()) { + msg.setDstIpRange(null); + } else { + msg.setDstIpRange(vo.getDstIpRange()); + } + + if (msg.getRemoteSecurityGroupUuid() != null && msg.getRemoteSecurityGroupUuid().isEmpty()) { + msg.setRemoteSecurityGroupUuid(null); + } else { + msg.setRemoteSecurityGroupUuid(vo.getRemoteSecurityGroupUuid()); + } + + } + + if (StringUtils.isNotEmpty(msg.getDstPortRange())) { + if (SecurityGroupRuleProtocolType.ICMP.toString().equals(msg.getProtocol()) || SecurityGroupRuleProtocolType.ALL.toString().equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because rule protocol is [%s], dstPortRange cannot be set", msg.getProtocol())); + } + msg.setDstPortRange(normalizeIpOrPort(msg.getDstPortRange())); + validatePorts(msg.getDstPortRange()); + } else if (msg.getDstPortRange() != null) { + if (SecurityGroupRuleProtocolType.TCP.toString().equals(msg.getProtocol()) || SecurityGroupRuleProtocolType.UDP.toString().equals(msg.getProtocol())) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because rule protocol is [%s], dstPortRange cannot be empty", msg.getProtocol())); + } + msg.setDstPortRange(null); + } else { + if (SecurityGroupRuleProtocolType.ICMP.toString().equals(msg.getProtocol()) || SecurityGroupRuleProtocolType.ALL.toString().equals(msg.getProtocol())) { + msg.setDstPortRange(null); + } else { + if (vo.getDstPortRange() == null) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because rule protocol is [%s], dstPortRange must be set", msg.getProtocol())); + } + msg.setDstPortRange(vo.getDstPortRange()); + } + } + + APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO sao = new APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO(); + sao.setType(vo.getType().toString()); + sao.setIpVersion(vo.getIpVersion()); + sao.setAction(msg.getAction()); + sao.setProtocol(msg.getProtocol()); + sao.setSrcIpRange(msg.getSrcIpRange()); + sao.setDstIpRange(msg.getDstIpRange()); + sao.setDstPortRange(msg.getDstPortRange()); + sao.setRemoteSecurityGroupUuid(msg.getRemoteSecurityGroupUuid()); + + // check duplicate in database + List others = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, vo.getSecurityGroupUuid()) + .eq(SecurityGroupRuleVO_.type, vo.getType()) + .notEq(SecurityGroupRuleVO_.uuid, vo.getUuid()).list(); + for (SecurityGroupRuleVO o : others) { + APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO ao = new APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO(); + ao.setType(o.getType().toString()); + ao.setIpVersion(o.getIpVersion()); + ao.setProtocol(o.getProtocol().toString()); + ao.setRemoteSecurityGroupUuid(o.getRemoteSecurityGroupUuid()); + ao.setAction(o.getAction()); + ao.setSrcIpRange(o.getSrcIpRange()); + ao.setDstIpRange(o.getDstIpRange()); + ao.setDstPortRange(o.getDstPortRange()); + if (sao.equals(ao)) { + throw new ApiMessageInterceptionException(argerr("could not change security group rule, because rule[%s] is duplicated to rule[uuid:%s] in datebase", JSONObjectUtil.toJsonString(sao), o.getUuid())); + } + } + } + + private void validatePorts(String ports) { + if (ports.isEmpty() || ports.startsWith(SecurityGroupConstant.IP_SPLIT) || ports.endsWith(SecurityGroupConstant.IP_SPLIT)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid ports[%s]", ports)); + } + String portArray[]; + if (ports.contains(SecurityGroupConstant.IP_SPLIT)) { + // The port range in iptables, such as 10-20, will occupy the number of two multiports + String[] tmpPorts = ports.split(String.format("%s|%s", SecurityGroupConstant.IP_SPLIT, SecurityGroupConstant.RANGE_SPLIT)); + if (tmpPorts.length > SecurityGroupGlobalProperty.PORT_GROUP_NUMBER_LIMIT) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid ports[%s], port range[%s] number[%d] is out of max limit[%d]", ports, Arrays.toString(tmpPorts), tmpPorts.length, SecurityGroupGlobalProperty.PORT_GROUP_NUMBER_LIMIT)); + } + + portArray = ports.split(SecurityGroupConstant.IP_SPLIT); + Stream stream = Stream.of(portArray).distinct(); + if (portArray.length != stream.count()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid ports[%s], port duplicate", ports)); + } + } else { + portArray = new String[]{ports}; + } + + for (String port : portArray) { + if (port.isEmpty()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid ports[%s]", ports)); + } + if (port.contains(SecurityGroupConstant.RANGE_SPLIT)) { + String portRange[] = port.split(SecurityGroupConstant.RANGE_SPLIT); + if (portRange.length != 2) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid port range[%s]", port)); + } + + try { + Integer startPort = Integer.valueOf(portRange[0]); + Integer endPort = Integer.valueOf(portRange[1]); + if (startPort >= endPort || startPort < SecurityGroupConstant.PORT_NUMBER_MIN + || endPort > SecurityGroupConstant.PORT_NUMBER_MAX) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid port range[%s]", port)); + } + } catch (NumberFormatException e) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid port range[%s]", port)); + } + } else { + try { + Integer.valueOf(port); + if (Integer.valueOf(port) < SecurityGroupConstant.PORT_NUMBER_MIN + || Integer.valueOf(port) > SecurityGroupConstant.PORT_NUMBER_MAX) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid port[%s]", port)); + } + } catch (NumberFormatException e) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_PORT_FIELD_ERROR, "invalid port[%s]", port)); + } + } + } + } + + private void validateIps(String ips, Integer ipVersion) { + if (ips.isEmpty() || ips.startsWith(SecurityGroupConstant.IP_SPLIT) || ips.endsWith(SecurityGroupConstant.IP_SPLIT)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ips[%s]", ips)); + } + String ipArray[]; + if (ips.contains(SecurityGroupConstant.IP_SPLIT)) { + ipArray = ips.split(SecurityGroupConstant.IP_SPLIT); + if (ipArray.length > SecurityGroupGlobalProperty.IP_GROUP_NUMBER_LIMIT) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ips[%s], ip number[%d] is out of max limit[%d]", ips, ipArray.length, SecurityGroupGlobalProperty.IP_GROUP_NUMBER_LIMIT)); + } + Stream stream = Stream.of(ipArray).distinct(); + if (ipArray.length != stream.count()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ips[%s], ip duplicate", ips)); + } + if (ipVersion == IPv6Constants.IPv6) { + List ipv6List = Stream.of(ipArray).filter(ip -> ip.contains(SecurityGroupConstant.RANGE_SPLIT)).collect(Collectors.toList()); + if (!ipv6List.isEmpty()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ips[%s], ip range cannot be used when specifying multiple ipv6 addresses", ips)); + } + } + } else { + ipArray = new String[]{ips}; + } + + for (String ip : ipArray) { + if (ip.isEmpty()) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ips[%s]", ips)); + } + if (ip.contains(SecurityGroupConstant.CIDR_SPLIT)) { + if (!NetworkUtils.isCidr(ip, ipVersion)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid cidr[%s], ipVersion[%d]", ip, ipVersion)); + } + if (ipVersion == IPv6Constants.IPv4 && NetworkUtils.isFullCidr(ip)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "ipv4 cidr can not be 0.0.0.0/0")); + } if (ipVersion == IPv6Constants.IPv6 && IPv6NetworkUtils.isFullCidr(ip)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "ipv6 cidr can not be ::/0")); + } + continue; + } + if (ip.contains(SecurityGroupConstant.RANGE_SPLIT)) { + String[] ipRangeArray = ip.split(SecurityGroupConstant.RANGE_SPLIT); + if (ipRangeArray.length != 2) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ip range[%s]", ip)); + } + String startIp = ipRangeArray[0]; + String endIp = ipRangeArray[1]; + if (ipVersion == IPv6Constants.IPv4) { + NetworkUtils.validateIpRange(startIp, endIp); + } else { + if (!IPv6NetworkUtils.isIpv6Address(startIp) || !IPv6NetworkUtils.isIpv6Address(endIp) || startIp.compareTo(endIp) > 0) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ip range[%s]", ip)); + } + } + continue; + } + if (ipVersion == IPv6Constants.IPv4) { + if (!NetworkUtils.isIpv4Address(ip)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ip[%s], ipVersion[%d]", ip, ipVersion)); + } + } else { + if (!IPv6NetworkUtils.isValidIpv6(ip)) { + throw new ApiMessageInterceptionException(err(SecurityGroupErrors.RULE_IP_FIELD_ERROR, "invalid ip[%s], ipVersion[%d]", ip, ipVersion)); + } + } + } + } + private void validate(APIDetachSecurityGroupFromL3NetworkMsg msg) { SimpleQuery q = dbf.createQuery(SecurityGroupL3NetworkRefVO.class); q.add(SecurityGroupL3NetworkRefVO_.l3NetworkUuid, Op.EQ, msg.getL3NetworkUuid()); @@ -100,6 +857,17 @@ private void validate(APIDeleteSecurityGroupRuleMsg msg) { throw new StopRoutingException(); } + List vos = Q.New(SecurityGroupRuleVO.class).in(SecurityGroupRuleVO_.uuid, uuids).list(); + String sguuid = vos.get(0).getSecurityGroupUuid(); + vos.stream().forEach(vo -> { + if (!sguuid.equals(vo.getSecurityGroupUuid())) { + throw new ApiMessageInterceptionException(argerr("can't delete rules of different security group")); + } + if (vo.getPriority() == SecurityGroupConstant.DEFAULT_RULE_PRIORITY) { + throw new ApiMessageInterceptionException(argerr("can't delete default rule[uuid:%s]", vo.getUuid())); + } + }); + msg.setRuleUuids(uuids); } @@ -140,11 +908,35 @@ private void validate(APIAddVmNicToSecurityGroupMsg msg) { )); } - checkIfVmNicFromAttachedL3Networks(msg.getSecurityGroupUuid(), uuids); + List refs = Q.New(VmNicSecurityGroupRefVO.class).eq(VmNicSecurityGroupRefVO_.securityGroupUuid, msg.getSecurityGroupUuid()).list(); + if (!refs.isEmpty()) { + refs.stream().forEach(ref -> { + if (uuids.contains(ref.getVmNicUuid())) { + throw new ApiMessageInterceptionException(argerr("vm nic[uuid:%s] has been attach to security group[uuid:%s]", ref.getVmNicUuid(), msg.getSecurityGroupUuid())); + } + }); + } + + checkIfL3NetworkSupportSecurityGroup(uuids); msg.setVmNicUuids(uuids); } + private void checkIfL3NetworkSupportSecurityGroup(List vmNicUuids) { + if (vmNicUuids.isEmpty()) { + return; + } + + List nics = Q.New(VmNicVO.class).in(VmNicVO_.uuid, vmNicUuids).list(); + + for(VmNicVO nic : nics) { + if (!Q.New(NetworkServiceL3NetworkRefVO.class).eq(NetworkServiceL3NetworkRefVO_.l3NetworkUuid, nic.getL3NetworkUuid()) + .eq(NetworkServiceL3NetworkRefVO_.networkServiceType, SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE).isExists()) { + throw new ApiMessageInterceptionException(argerr("the netwotk service[type:%s] not enabled on the l3Network[uuid:%s] of nic[uuid:%s]", SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE, nic.getL3NetworkUuid(), nic.getUuid())); + } + } + } + @Transactional(readOnly = true) private void checkIfVmNicFromAttachedL3Networks(String securityGroupUuid, List uuids) { String sql = "select nic.uuid from SecurityGroupL3NetworkRefVO ref, VmNicVO nic, UsedIpVO ip where ref.l3NetworkUuid = ip.l3NetworkUuid and ip.vmNicUuid = nic.uuid " + @@ -167,170 +959,249 @@ private void checkIfVmNicFromAttachedL3Networks(String securityGroupUuid, List SecurityGroupConstant.ONE_API_RULES_MAX_NUM) { - throw new ApiMessageInterceptionException(argerr("the amount of rules exceeds limit, maximum %s rules are allowed in one request", SecurityGroupConstant.ONE_API_RULES_MAX_NUM)); + String sgUuid = msg.getSecurityGroupUuid(); + List rules = msg.getRules(); + + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).isExists()) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because security group[uuid:%s] does not exist", sgUuid)); + } + if (rules.isEmpty() || rules.size() > SecurityGroupConstant.ONE_API_RULES_MAX_NUM) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the rules cannot be empty or exceed the max number %d", SecurityGroupConstant.ONE_API_RULES_MAX_NUM)); } - // Basic check - for (SecurityGroupRuleAO ao : msg.getRules()) { - if (ao.getType() == null) { - throw new ApiMessageInterceptionException(argerr("rule type can not be null. rule dump: %s", JSONObjectUtil.toJsonString(ao))); + if (msg.getRemoteSecurityGroupUuids() != null && !msg.getRemoteSecurityGroupUuids().isEmpty()) { + if (msg.getRemoteSecurityGroupUuids().stream().distinct().count() != msg.getRemoteSecurityGroupUuids().size()) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because duplicate uuid in remoteSecurityGroupUuids: %s", msg.getRemoteSecurityGroupUuids())); } - if (!ao.getType().equals(SecurityGroupRuleType.Egress.toString()) && - !ao.getType().equals(SecurityGroupRuleType.Ingress.toString())) { - throw new ApiMessageInterceptionException(argerr("unknown rule type[%s], rule can only be Ingress/Egress. rule dump: %s", - ao.getType(), JSONObjectUtil.toJsonString(ao))); + List sgUuids = Q.New(SecurityGroupVO.class).select(SecurityGroupVO_.uuid).in(SecurityGroupVO_.uuid, msg.getRemoteSecurityGroupUuids()).listValues(); + msg.getRemoteSecurityGroupUuids().stream().forEach(uuid -> { + sgUuids.stream().filter(s -> s.equals(uuid)).findFirst().orElseThrow(() -> + new ApiMessageInterceptionException(argerr("could not add security group rule, because security group[uuid:%s] does not exist", uuid))); + }); + + rules.stream().forEach(r -> { + if (r.getRemoteSecurityGroupUuid() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the remote security group uuid is conflict")); + } + }); + + List aos = new ArrayList(); + + msg.getRemoteSecurityGroupUuids().stream().forEach(uuid -> { + rules.stream().forEach(r -> { + APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO ao = new APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO(); + ao.setType(r.getType()); + ao.setState(r.getState()); + ao.setDescription(r.getDescription()); + ao.setRemoteSecurityGroupUuid(uuid); + ao.setIpVersion(r.getIpVersion()); + ao.setProtocol(r.getProtocol()); + ao.setSrcIpRange(r.getSrcIpRange()); + ao.setDstIpRange(r.getDstIpRange()); + ao.setDstPortRange(r.getDstPortRange()); + ao.setAction(r.getAction()); + ao.setAllowedCidr(r.getAllowedCidr()); + ao.setStartPort(r.getStartPort()); + ao.setEndPort(r.getEndPort()); + aos.add(ao); + }); + }); + + if (!aos.isEmpty()) { + msg.setRules(aos); } + } + + if (msg.getPriority() == null || msg.getPriority() < 0) { + msg.setPriority(SecurityGroupConstant.LOWEST_RULE_PRIORITY); + } + + if (msg.getPriority() == SecurityGroupConstant.DEFAULT_RULE_PRIORITY) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because rule priority must greater than %d or equals %d", SecurityGroupConstant.DEFAULT_RULE_PRIORITY, SecurityGroupConstant.LOWEST_RULE_PRIORITY)); + } + List newRules = msg.getRules(); - if (ao.getProtocol() == null) { - throw new ApiMessageInterceptionException(argerr("protocol can not be null. rule dump: %s", JSONObjectUtil.toJsonString(ao))); + // Basic check + for (APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO ao : newRules) { + if (!SecurityGroupRuleProtocolType.isValid(ao.getProtocol())) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because invalid rule protocol[%s], valid protocols are %s", ao.getProtocol(), SecurityGroupRuleProtocolType.getAllProtocol())); } - try { - SecurityGroupRuleProtocolType.valueOf(ao.getProtocol()); - } catch (Exception e) { - throw new ApiMessageInterceptionException(argerr("invalid protocol[%s]. Valid protocols are [TCP, UDP, ICMP, ALL]. rule dump: %s", - ao.getProtocol(), JSONObjectUtil.toJsonString(ao))); + if (ao.getAction() == null) { + ao.setAction(SecurityGroupRuleAction.ACCEPT.toString()); + } else { + if (!SecurityGroupRuleAction.isValid(ao.getAction())) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because invalid rule action[%s], valid actions are %s", ao.getAction(), SecurityGroupRuleAction.getAllAction())); + } } - if (ao.getStartPort() == null && !SecurityGroupRuleProtocolType.ALL.toString().equals(ao.getProtocol())) { - throw new ApiMessageInterceptionException(argerr("startPort can not be null. rule dump: %s", JSONObjectUtil.toJsonString(ao))); - } else if (ao.getStartPort() != null && SecurityGroupRuleProtocolType.ALL.toString().equals(ao.getProtocol())){ - throw new ApiMessageInterceptionException(argerr("can not set port for protocol [type:ALL]. rule dump: %s", JSONObjectUtil.toJsonString(ao))); + if (ao.getIpVersion() == null) { + ao.setIpVersion(IPv6Constants.IPv4); + } else { + if (ao.getIpVersion() != IPv6Constants.IPv4 && ao.getIpVersion() != IPv6Constants.IPv6) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because invalid rule ipVersion[%d], valid ipVersions are %d/%d", ao.getIpVersion(), IPv6Constants.IPv4, IPv6Constants.IPv6)); + } } - if (SecurityGroupRuleProtocolType.ICMP.toString().equals(ao.getProtocol())) { - if (ao.getStartPort() < -1 || ao.getStartPort() > 255) { - throw new ApiMessageInterceptionException(argerr("invalid ICMP type[%s]. Valid type is [-1, 255]. rule dump: %s", - ao.getStartPort(), JSONObjectUtil.toJsonString(ao))); + if (StringUtils.isEmpty(ao.getAllowedCidr())) { + ao.setAllowedCidr(ao.getIpVersion() == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + } + + if (SecurityGroupRuleType.Egress.toString().equals(ao.getType())) { + if (ao.getSrcIpRange() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the srcIpRange[%s] is not allowed to set for egress rule", ao.getSrcIpRange())); } - } else if(SecurityGroupRuleProtocolType.ALL.toString().equals(ao.getProtocol())){ - ao.setStartPort(-1); - } else{ - if (ao.getStartPort() < 0 || ao.getStartPort() > 65535) { - throw new ApiMessageInterceptionException(argerr("invalid startPort[%s]. Valid range is [0, 65535]. rule dump: %s", - ao.getStartPort(), JSONObjectUtil.toJsonString(ao))); + + if (checkAllowedCidrValid(ao.getAllowedCidr())) { + if (ao.getDstIpRange() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the allowedCidr[%s] and dstIpRange[%s] are in conflict", ao.getAllowedCidr(), ao.getDstIpRange())); + } + ao.setDstIpRange(ao.getAllowedCidr()); + } + + if (ao.getDstIpRange() != null) { + if (ao.getRemoteSecurityGroupUuid() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the ip range[%s] and remoteSecurityGroupUuid[%s] are in conflict", ao.getDstIpRange(), ao.getRemoteSecurityGroupUuid())); + } + ao.setDstIpRange(normalizeIpOrPort(ao.getDstIpRange())); + validateIps(ao.getDstIpRange(), ao.getIpVersion()); + } + } else { + if (ao.getDstIpRange() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the dstIpRange[%s] is not allowed to set for ingress rule", ao.getDstIpRange())); + } + + if (checkAllowedCidrValid(ao.getAllowedCidr())) { + if (ao.getSrcIpRange() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the allowedCidr[%s] and srcIpRange[%s] are in conflict", ao.getAllowedCidr(), ao.getSrcIpRange())); + } + ao.setSrcIpRange(ao.getAllowedCidr()); + } + + if (ao.getSrcIpRange() != null) { + if (ao.getRemoteSecurityGroupUuid() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the ip range[%s] and remoteSecurityGroupUuid[%s] are in conflict", ao.getSrcIpRange(), ao.getRemoteSecurityGroupUuid())); + } + ao.setSrcIpRange(normalizeIpOrPort(ao.getSrcIpRange())); + validateIps(ao.getSrcIpRange(), ao.getIpVersion()); } } + if (ao.getStartPort() == null) { + ao.setStartPort(-1); + } if (ao.getEndPort() == null) { - ao.setEndPort(ao.getStartPort()); + ao.setEndPort(-1); } - if (SecurityGroupRuleProtocolType.ICMP.toString().equals(ao.getProtocol())) { - if (ao.getEndPort() < -1 || ao.getEndPort() > 3) { - throw new ApiMessageInterceptionException(argerr("invalid ICMP code[%s]. Valid range is [-1, 3]. rule dump: %s", - ao.getEndPort(), JSONObjectUtil.toJsonString(ao))); + if (SecurityGroupRuleProtocolType.ALL.toString().equals(ao.getProtocol()) || SecurityGroupRuleProtocolType.ICMP.toString().equals(ao.getProtocol())) { + if (ao.getDstPortRange() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the protocol type ALL or ICMP cant not set dstPortRange[%s]", ao.getDstPortRange())); } - } else if(SecurityGroupRuleProtocolType.ALL.toString().equals(ao.getProtocol())){ - ao.setEndPort(-1); - } else { - if (ao.getEndPort() < 0 || ao.getEndPort() > 65535) { - throw new ApiMessageInterceptionException(argerr("invalid endPort[%s]. Valid range is [0, 65535]. rule dump: %s", - ao.getEndPort(), JSONObjectUtil.toJsonString(ao))); + if (ao.getStartPort() != -1 || ao.getEndPort() != -1) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the protocol type ALL or ICMP cant not set startPort or endPort")); } - } + } else { + if (ao.getStartPort() >= SecurityGroupConstant.PORT_NUMBER_MIN && ao.getEndPort() <= SecurityGroupConstant.PORT_NUMBER_MAX) { + if (ao.getStartPort() > ao.getEndPort()) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because invalid rule endPort[%d], endPort must be greater than or equal to startPort[%d]", ao.getEndPort(), ao.getStartPort())); + } + if (ao.getDstPortRange() != null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because dstPortRange[%s] and starPort[%s] are in conflict", ao.getDstPortRange(), ao.getStartPort())); + } - if (ao.getIpVersion() == null) { - ao.setIpVersion(IPv6Constants.IPv4); - } - if (ao.getAllowedCidr() != null && !NetworkUtils.isCidr(ao.getAllowedCidr(), ao.getIpVersion())) { - throw new ApiMessageInterceptionException(argerr("invalid CIDR[%s]. rule dump: %s", ao.getAllowedCidr(), JSONObjectUtil.toJsonString(ao))); + if (ao.getStartPort().equals(ao.getEndPort())) { + ao.setDstPortRange(String.valueOf(ao.getStartPort())); + } else { + ao.setDstPortRange(String.format("%s-%s", ao.getStartPort(), ao.getEndPort())); + } + } + + if (ao.getDstPortRange() == null) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because the protocol type TCP/UDP must set dstPortRange")); + } + ao.setDstPortRange(normalizeIpOrPort(ao.getDstPortRange())); + validatePorts(ao.getDstPortRange()); } } - // Deduplicate in msg - for (int i = 0; i < msg.getRules().size() - 1; i++) { - for (int j = msg.getRules().size() - 1; j > i; j--) { - if (checkSecurityGroupRuleEqual(msg.getRules().get(j), msg.getRules().get(i))) { - throw new ApiMessageInterceptionException(argerr("rule should not be duplicated. rule dump: %s", - JSONObjectUtil.toJsonString(msg.getRules().get(j)))); + // Deduplicate in API + for (int i = 0; i < newRules.size() - 1; i++) { + for (int j = newRules.size() - 1; j > i; j--) { + if (newRules.get(i).equals(newRules.get(j))) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because rule[%s] and rule[%s] are dupilicated", + JSONObjectUtil.toJsonString(newRules.get(i)), JSONObjectUtil.toJsonString(newRules.get(j)))); } } } - // Deduplicate in database - SimpleQuery lsquery = dbf.createQuery(SecurityGroupRuleVO.class); - lsquery.add(SecurityGroupRuleVO_.securityGroupUuid, Op.EQ, msg.getSecurityGroupUuid()); - List vos = lsquery.list(); - boolean hasRemoteGroups = msg.getRemoteSecurityGroupUuids() != null && !msg.getRemoteSecurityGroupUuids().isEmpty(); + // Deduplicate in DB + List vos = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, sgUuid).list(); - for (SecurityGroupRuleVO svo : vos) { - SecurityGroupRuleAO ao = new SecurityGroupRuleAO(); - ao.setType(svo.getType().toString()); - ao.setAllowedCidr(svo.getAllowedCidr()); - ao.setProtocol(svo.getProtocol().toString()); - ao.setStartPort(svo.getStartPort()); - ao.setEndPort(svo.getEndPort()); - ao.setIpVersion(svo.getIpVersion()); - String existRuleRemoteGroupUuid = svo.getRemoteSecurityGroupUuid(); - for (SecurityGroupRuleAO sao : msg.getRules()) { - if (checkSecurityGroupRuleEqual(ao, sao) && ( - !hasRemoteGroups && existRuleRemoteGroupUuid == null || - hasRemoteGroups && existRuleRemoteGroupUuid != null && - msg.getRemoteSecurityGroupUuids().contains(existRuleRemoteGroupUuid) - )) { - throw new ApiMessageInterceptionException(argerr("rule exist. rule dump: %s, remoteSecurityGroupUuid:[%s]", - JSONObjectUtil.toJsonString(sao), svo.getRemoteSecurityGroupUuid())); + for (SecurityGroupRuleVO vo : vos) { + APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO ao = new APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO(); + ao.setType(vo.getType().toString()); + ao.setAllowedCidr(vo.getAllowedCidr()); + ao.setProtocol(vo.getProtocol().toString()); + ao.setStartPort(vo.getStartPort()); + ao.setEndPort(vo.getEndPort()); + ao.setIpVersion(vo.getIpVersion()); + ao.setRemoteSecurityGroupUuid(vo.getRemoteSecurityGroupUuid()); + ao.setAction(vo.getAction()); + ao.setSrcIpRange(vo.getSrcIpRange()); + ao.setDstIpRange(vo.getDstIpRange()); + ao.setDstPortRange(vo.getDstPortRange()); + for (APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO sao : newRules) { + if (ao.equals(sao)) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because rule[%s] is duplicated to rule[uuid:%s] in datebase", JSONObjectUtil.toJsonString(sao), vo.getUuid())); } } - } - // fin - for (SecurityGroupRuleAO ao : msg.getRules()) { - int start = Math.min(ao.getStartPort(), ao.getEndPort()); - int end = Math.max(ao.getStartPort(), ao.getEndPort()); - ao.setStartPort(start); - ao.setEndPort(end); + int ingressRuleCount = vos.stream().filter(vo -> SecurityGroupRuleType.Ingress.equals(vo.getType()) && vo.getPriority() != SecurityGroupConstant.DEFAULT_RULE_PRIORITY).collect(Collectors.toList()).size(); + int egressRuleCount = vos.stream().filter(vo -> SecurityGroupRuleType.Egress.equals(vo.getType()) && vo.getPriority() != SecurityGroupConstant.DEFAULT_RULE_PRIORITY).collect(Collectors.toList()).size(); + int toCreateIngressRuleCount = newRules.stream().filter(ao -> SecurityGroupRuleType.Ingress.toString().equals(ao.getType())).collect(Collectors.toList()).size(); + int toCreateEgressRuleCount = newRules.stream().filter(ao -> SecurityGroupRuleType.Egress.toString().equals(ao.getType())).collect(Collectors.toList()).size(); - if (ao.getAllowedCidr() == null) { - if (ao.getIpVersion() == IPv6Constants.IPv4) { - ao.setAllowedCidr(SecurityGroupConstant.WORLD_OPEN_CIDR); - } else { - ao.setAllowedCidr(SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); - } - } + if (ingressRuleCount >= SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) && toCreateIngressRuleCount > 0) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because security group %s rules has reached the maximum limit[%d]", + SecurityGroupRuleType.Ingress, SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class))); + } + if (egressRuleCount >= SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class) && toCreateEgressRuleCount > 0) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because security group %s rules has reached the maximum limit[%d]", + SecurityGroupRuleType.Egress, SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class))); + } + if ((ingressRuleCount + toCreateIngressRuleCount) > SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because security group %s rules number[%d] is out of max limit[%d]", + SecurityGroupRuleType.Ingress, (ingressRuleCount + toCreateIngressRuleCount), SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class))); + } + if ((egressRuleCount + toCreateEgressRuleCount) > SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class)) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because security group %s rules number[%d] is out of max limit[%d]", + SecurityGroupRuleType.Egress, (egressRuleCount + toCreateEgressRuleCount), SecurityGroupGlobalConfig.SECURITY_GROUP_RULES_NUM_LIMIT.value(Integer.class))); + } + if (msg.getPriority() > (ingressRuleCount + 1) && toCreateIngressRuleCount > 0) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because priority[%d] must be consecutive, the ingress rule maximum priority is [%d]", msg.getPriority(), ingressRuleCount)); + } + if (msg.getPriority() > (egressRuleCount + 1) && toCreateEgressRuleCount > 0) { + throw new ApiMessageInterceptionException(argerr("could not add security group rule, because priority[%d] must be consecutive, the egress rule maximum priority is [%d]", msg.getPriority(), egressRuleCount)); } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupCascadeExtension.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupCascadeExtension.java index 1a6cb823c5a..b21fe374a7a 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupCascadeExtension.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupCascadeExtension.java @@ -9,6 +9,7 @@ import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.CloudBusListCallBack; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.db.SQLBatchWithReturn; import org.zstack.core.db.SimpleQuery; import org.zstack.header.core.Completion; @@ -40,7 +41,7 @@ public class SecurityGroupCascadeExtension extends AbstractAsyncCascadeExtension @Autowired private CloudBus bus; - private static String NAME = VmNicSecurityGroupRefVO.class.getSimpleName(); + private static String NAME = SecurityGroupVO.class.getSimpleName(); @Override public void asyncCascade(CascadeAction action, Completion completion) { @@ -64,103 +65,57 @@ private void handleDeletionCheck(CascadeAction action, Completion completion) { completion.success(); } - private void handleSecurityGroupRefDeletion(CascadeAction action, final Completion completion) { - List refs = refFromAction(action); - if (refs.isEmpty()) { + private void handleDeletion(CascadeAction action, final Completion completion) { + List sgInv = securityGroupUuidsFromAction(action); + if (sgInv == null || sgInv.isEmpty()) { completion.success(); return; } - Map> map = new HashMap>(); - for (VmNicSecurityGroupRefInventory ref : refs) { - List nicUuids = map.get(ref.getSecurityGroupUuid()); - if (nicUuids == null) { - nicUuids = new ArrayList(); - map.put(ref.getSecurityGroupUuid(), nicUuids); - } - nicUuids.add(ref.getVmNicUuid()); - } - - List msgs = new ArrayList(); - for (Map.Entry> e : map.entrySet()) { - RemoveVmNicFromSecurityGroupMsg msg = new RemoveVmNicFromSecurityGroupMsg(); - msg.setSecurityGroupUuid(e.getKey()); - msg.setVmNicUuids(e.getValue()); - bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, e.getKey()); - msgs.add(msg); - } - - bus.send(msgs, new CloudBusListCallBack(completion) { - @Override - public void run(List replies) { - for (MessageReply reply : replies) { + new While<>(sgInv).each((inv, wcomp) -> { + SecurityGroupDeletionMsg msg = new SecurityGroupDeletionMsg(); + msg.setUuid(inv.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, inv.getUuid()); + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { if (!reply.isSuccess()) { - logger.warn(String.format("failed to remove vm nic from some security group for some destroyed vm," + - "no worry, security group will catch it up later. %s", reply.getError())); + logger.warn(String.format("failed to delete security group[uuid:%s], %s", msg.getUuid(), reply.getError())); } - } + wcomp.done(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { completion.success(); } }); } - private void handleDeletion(CascadeAction action, final Completion completion) { - if (VmInstanceVO.class.getSimpleName().equals(action.getParentIssuer())) { - handleSecurityGroupRefDeletion(action, completion); - } else { - handleSecurityGroupDeletion(action, completion); - } - - } - - private void handleSecurityGroupDeletion(CascadeAction action, final Completion completion) { - List accounts = action.getParentIssuerContext(); - List accountUuids = accounts.stream().map(AccountInventory::getUuid).collect(Collectors.toList()); - - List msgs = new SQLBatchWithReturn>() { - @Override - protected List scripts() { - List uuids = q(AccountResourceRefVO.class) - .select(AccountResourceRefVO_.resourceUuid) - .eq(AccountResourceRefVO_.resourceType, SecurityGroupVO.class.getSimpleName()) - .in(AccountResourceRefVO_.ownerAccountUuid, accountUuids) - .listValues(); - - if (uuids.isEmpty()) { - return null; - } - - return uuids.stream().map(auuid -> { - SecurityGroupDeletionMsg msg = new SecurityGroupDeletionMsg(); - msg.setUuid(auuid); - bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, auuid); - return msg; - }).collect(Collectors.toList()); + private List securityGroupUuidsFromAction(CascadeAction action) { + List ret = null; + if (NAME.equals(action.getParentIssuer())) { + ret = action.getParentIssuerContext(); + } else if (AccountVO.class.getSimpleName().equals(action.getParentIssuer())) { + List accounts = action.getParentIssuerContext(); + List accountUuids = accounts.stream().map(AccountInventory::getUuid).collect(Collectors.toList()); + + List sgUuids= Q.New(AccountResourceRefVO.class) + .select(AccountResourceRefVO_.resourceUuid) + .eq(AccountResourceRefVO_.resourceType, SecurityGroupVO.class.getSimpleName()) + .in(AccountResourceRefVO_.ownerAccountUuid, accountUuids) + .listValues(); + if (sgUuids.isEmpty()) { + return null; } - }.execute(); - - if (msgs == null) { - completion.success(); - return; + List sgVos = Q.New(SecurityGroupVO.class) + .in(SecurityGroupVO_.uuid, sgUuids).list(); + ret = SecurityGroupInventory.valueOf(sgVos); } - - new While<>(msgs).all((msg, com) -> bus.send(msg, new CloudBusCallBack(com) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - logger.warn(String.format("failed to delete scheduler[uuid:%s], %s", msg.getUuid(), reply.getError())); - } - - com.done(); - } - })).run(new WhileDoneCompletion(completion) { - @Override - public void done(ErrorCodeList errorCodeList) { - completion.success(); - } - }); + return ret; } @Override @@ -173,44 +128,16 @@ public String getCascadeResourceName() { return NAME; } - private List refFromAction(CascadeAction action) { - List vms = action.getParentIssuerContext(); - List nicUuids = new ArrayList(); - for (VmDeletionStruct vm : vms) { - nicUuids.addAll(CollectionUtils.transformToList(vm.getInventory().getVmNics(), new Function() { - @Override - public String call(VmNicInventory arg) { - return arg.getUuid(); - } - })); - } - - - if (nicUuids.isEmpty()) { - return new ArrayList(); - } - - SimpleQuery q = dbf.createQuery(VmNicSecurityGroupRefVO.class); - q.add(VmNicSecurityGroupRefVO_.vmNicUuid, SimpleQuery.Op.IN, nicUuids); - List vos = q.list(); - return VmNicSecurityGroupRefInventory.valueOf(vos); - } - @Override public CascadeAction createActionForChildResource(CascadeAction action) { - if (CascadeConstant.DELETION_CLEANUP_CODE.equals(action.getActionCode())) { - return null; - } - - if (!action.getParentIssuer().equals(VmInstanceVO.class.getSimpleName())) { - return null; - } - - List refs = refFromAction(action); - if (refs.isEmpty()) { - return null; + if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { + List sgInvs = securityGroupUuidsFromAction(action); + if (sgInvs != null && !sgInvs.isEmpty()) { + return action.copy().setParentIssuer(NAME).setParentIssuerContext(sgInvs); + } + return action; } - return action.copy().setParentIssuer(NAME).setParentIssuerContext(refs); + return null; } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupConstant.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupConstant.java index f9056ef214c..9d306000580 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupConstant.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupConstant.java @@ -9,5 +9,24 @@ public interface SecurityGroupConstant { public static String SECURITY_GROUP_NETWORK_SERVICE_TYPE = "SecurityGroup"; public static String WORLD_OPEN_CIDR = "0.0.0.0/0"; public static String WORLD_OPEN_CIDR_IPV6 = "::/0"; - int ONE_API_RULES_MAX_NUM = 1000; + public static String IP_SPLIT = ","; + public static String CIDR_SPLIT = "/"; + public static String RANGE_SPLIT = "-"; + public static String DEFAULT_RULE_DESCRIPTION = "default rule"; + + public static int DEFAULT_RULE_PRIORITY = 0; + public static int LOWEST_RULE_PRIORITY = -1; + public static int IP_GROUP_NUMBER_LIMIT = 10; + public static int PORT_GROUP_NUMBER_LIMIT = 10; + public static int PORT_NUMBER_MAX = 65535; + public static int PORT_NUMBER_MIN = 0; + int ONE_API_RULES_MAX_NUM = 2000; + + public static enum Param { + SECURITY_GROUP_RULE_VO, + SECURITY_GROUP_VO, + SECURITY_GROUP_UUIDS, + SECURITY_GROUP_REFS, + VM_NIC_UUIDS, + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupErrors.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupErrors.java index 517b56346de..ed615ade58f 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupErrors.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupErrors.java @@ -2,8 +2,15 @@ /** */ -public enum SecurityGroupErrors { - ADD_NIC_ERROR(1000); +public enum SecurityGroupErrors { + ADD_NIC_ERROR(1000), + RESOURCE_NOT_EXIST_ERROR(1001), + RULE_DUPLICATE_ERROR(1002), + RULE_FILED_CONFLICT_ERROR(1003), + RULE_FILED_NOT_SUPPORT_ERROR(1004), + RULE_PORT_FIELD_ERROR(1005), + RULE_IP_FIELD_ERROR(1006), + RULE_CHECK_OK(2000); private String code; diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGetSdnBackendExtensionPoint.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGetSdnBackendExtensionPoint.java new file mode 100644 index 00000000000..9a1ef0524d0 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGetSdnBackendExtensionPoint.java @@ -0,0 +1,5 @@ +package org.zstack.network.securitygroup; + +public interface SecurityGroupGetSdnBackendExtensionPoint { + SecurityGroupSdnBackend getSecurityGroupSdnBackend(String sdnControllerUuid); +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalConfig.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalConfig.java index 550c4a76261..c0cf749bc73 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalConfig.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalConfig.java @@ -1,6 +1,7 @@ package org.zstack.network.securitygroup; import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; @@ -20,4 +21,16 @@ public class SecurityGroupGlobalConfig { public static GlobalConfig INGRESS_RULE_DEFAULT_POLICY = new GlobalConfig(CATEGORY, "ingress.defaultPolicy"); @GlobalConfigValidation(validValues = {"accept", "deny"}) public static GlobalConfig EGRESS_RULE_DEFAULT_POLICY = new GlobalConfig(CATEGORY, "egress.defaultPolicy"); + + @GlobalConfigValidation(inNumberRange = {100, 1000}) + @GlobalConfigDef(defaultValue = "100", type = Integer.class, description = "security group rules num limit") + public static GlobalConfig SECURITY_GROUP_RULES_NUM_LIMIT = new GlobalConfig(CATEGORY, "rules.num.limit"); + + @GlobalConfigValidation(inNumberRange = {10, 20}) + @GlobalConfigDef(defaultValue = "10", type = Integer.class, description = "security groups attached to vmnic num limit") + public static GlobalConfig VMNIC_SECURITY_GROUP_NUM_LIMIT = new GlobalConfig(CATEGORY, "vnic.sg.num.limit"); + + @GlobalConfigValidation(inNumberRange = {25000, 30000}) + @GlobalConfigDef(defaultValue = "30000", type = Integer.class, description = "security group rule max priority in ovn") + public static GlobalConfig OVN_ACL_MAX_PRIORITY = new GlobalConfig(CATEGORY, "ovn.max.priority"); } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalProperty.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalProperty.java new file mode 100644 index 00000000000..2c3537c7058 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupGlobalProperty.java @@ -0,0 +1,14 @@ +package org.zstack.network.securitygroup; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +@GlobalPropertyDefinition +public class SecurityGroupGlobalProperty { + @GlobalProperty(name="upgradeSecurityGroup", defaultValue = "false") + public static boolean UPGRADE_SECURITY_GROUP; + @GlobalProperty(name="SecurityGroupRuleIpLimit", defaultValue = "50") + public static int IP_GROUP_NUMBER_LIMIT; + @GlobalProperty(name="SecurityGroupRulePortLimit", defaultValue = "15") //The max number of multiport modes in iptables is 15 + public static int PORT_GROUP_NUMBER_LIMIT; +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupHelper.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupHelper.java new file mode 100644 index 00000000000..88b010dc382 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupHelper.java @@ -0,0 +1,23 @@ +package org.zstack.network.securitygroup; + +import java.util.List; + +public class SecurityGroupHelper { + public static String getSdnControllerUuid(List systemTags) { + if (systemTags == null) { + return null; + } + + for (String tag : systemTags) { + if (SecurityGroupSystemTags.SDN_CONTROLLER_UUID.isMatch(tag)) { + return SecurityGroupSystemTags.SDN_CONTROLLER_UUID.getTokenByTag(tag, SecurityGroupSystemTags.SDN_CONTROLLER_UUID_TOKEN); + } + } + + return null; + } + + public static String getSdnControllerUuid(String sgUuid) { + return SecurityGroupSystemTags.SDN_CONTROLLER_UUID.getTokenByResourceUuid(sgUuid, SecurityGroupSystemTags.SDN_CONTROLLER_UUID_TOKEN); + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupInventory.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupInventory.java index ec460dcb910..f99064771d2 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupInventory.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupInventory.java @@ -5,6 +5,7 @@ import org.zstack.header.rest.APINoSee; import org.zstack.header.search.Inventory; +import javax.persistence.Column; import javax.persistence.JoinColumn; import java.sql.Timestamp; import java.util.*; @@ -91,6 +92,8 @@ public class SecurityGroupInventory { @Deprecated private Integer ipVersion; + private String vSwitchType; + /** * @desc the time this resource gets created */ @@ -99,10 +102,8 @@ public class SecurityGroupInventory { * @desc last time this resource gets operated */ private Timestamp lastOpDate; - /** - * @ignore - */ - @APINoSee + + private long internalId; /** * @desc @@ -131,6 +132,7 @@ protected SecurityGroupInventory(SecurityGroupVO vo) { this.setLastOpDate(vo.getLastOpDate()); this.setRules(SecurityGroupRuleInventory.valueOf(vo.getRules())); this.setState(vo.getState().toString()); + this.setvSwitchType(vo.getvSwitchType()); Set l3Uuids= new HashSet(vo.getAttachedL3NetworkRefs().size()); for (SecurityGroupL3NetworkRefVO ref : vo.getAttachedL3NetworkRefs()) { l3Uuids.add(ref.getL3NetworkUuid()); @@ -231,4 +233,12 @@ public Integer getIpVersion() { public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManager.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManager.java index bfc1ccf1a4a..e02b5a6934e 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManager.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManager.java @@ -1,6 +1,7 @@ package org.zstack.network.securitygroup; -import org.zstack.header.Service; +import java.util.List; public interface SecurityGroupManager { + VmNicSecurityGroupTo getVmNicSecurityGroupRules(List sgUuids); } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java index 8425a63d766..ba7a4d41d7d 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupManagerImpl.java @@ -1,9 +1,16 @@ package org.zstack.network.securitygroup; import com.google.common.base.Joiner; + +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; +import static org.zstack.core.Platform.operr; + +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cascade.CascadeFacade; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.cloudbus.MessageSafe; @@ -12,32 +19,46 @@ import org.zstack.core.config.GlobalConfigUpdateExtensionPoint; import org.zstack.core.db.*; import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.core.defer.Defer; +import org.zstack.core.defer.Deferred; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.thread.AsyncThread; +import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.PeriodicTask; +import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; import org.zstack.header.AbstractService; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.core.Completion; +import org.zstack.header.core.NopeCompletion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HostStatus; import org.zstack.header.host.HostVO; import org.zstack.header.host.HostVO_; +import org.zstack.header.identity.APIChangeResourceOwnerMsg; +import org.zstack.header.identity.AccountConstant; import org.zstack.header.identity.Quota; -import org.zstack.header.identity.Quota.QuotaOperator; -import org.zstack.header.identity.Quota.QuotaPair; import org.zstack.header.identity.ReportQuotaExtensionPoint; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.header.message.APIDeleteMessage; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; -import org.zstack.header.message.NeedQuotaCheckMessage; -import org.zstack.header.network.l3.IpRangeInventory; -import org.zstack.header.network.l3.L3NetworkInventory; -import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l2.L2NetworkConstant; +import org.zstack.header.network.l2.SdnControllerDeleteExtensionPoint; +import org.zstack.header.network.l2.VSwitchType; +import org.zstack.header.network.l3.*; +import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO; +import org.zstack.header.network.service.NetworkServiceL3NetworkRefVO_; import org.zstack.header.query.AddExpandedQueryExtensionPoint; import org.zstack.header.query.ExpandedQueryAliasStruct; import org.zstack.header.query.ExpandedQueryStruct; @@ -45,8 +66,12 @@ import org.zstack.identity.AccountManager; import org.zstack.identity.QuotaUtil; import org.zstack.network.l3.IpRangeHelper; +import org.zstack.network.l3.L3NetworkHelper; +import org.zstack.network.securitygroup.APIUpdateSecurityGroupRulePriorityMsg.SecurityGroupRulePriorityAO; import org.zstack.network.securitygroup.APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO; +import org.zstack.network.securitygroup.APISetVmNicSecurityGroupMsg.VmNicSecurityGroupRefAO; import org.zstack.query.QueryFacade; +import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; @@ -63,15 +88,18 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import java.util.stream.Stream; import static java.util.Arrays.asList; import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.err; +import static org.zstack.network.securitygroup.SecurityGroupConstant.Param.*; import static org.zstack.network.securitygroup.SecurityGroupMembersTO.ACTION_CODE_DELETE_GROUP; -import static org.zstack.utils.CollectionDSL.list; +import static org.zstack.utils.CollectionDSL.*; public class SecurityGroupManagerImpl extends AbstractService implements SecurityGroupManager, ManagementNodeReadyExtensionPoint, - VmInstanceMigrateExtensionPoint, AddExpandedQueryExtensionPoint, ReportQuotaExtensionPoint, ValidateL3SecurityGroupExtensionPoint { + VmInstanceMigrateExtensionPoint, AddExpandedQueryExtensionPoint, ReportQuotaExtensionPoint, ValidateL3SecurityGroupExtensionPoint, + SdnControllerDeleteExtensionPoint { private static CLogger logger = Utils.getLogger(SecurityGroupManagerImpl.class); @Autowired @@ -92,68 +120,33 @@ public class SecurityGroupManagerImpl extends AbstractService implements Securit private TagManager tagMgr; @Autowired private ErrorFacade errf; + @Autowired + protected CascadeFacade casf; protected Map hypervisorBackends; private int failureHostWorkerInterval; private int failureHostEachTimeTake; private Future failureHostCopingThread; - @Override - public List reportQuota() { - QuotaOperator checker = new QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreateSecurityGroupMsg) { - check((APICreateSecurityGroupMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(SecurityGroupQuotaConstant.SG_NUM); - usage.setUsed(getUsedSg(accountUuid)); - return list(usage); - } - - @Transactional(readOnly = true) - private long getUsedSg(String accountUuid) { - String sql = "select count(sg) from SecurityGroupVO sg, AccountResourceRefVO ref where ref.resourceUuid = sg.uuid" + - " and ref.accountUuid = :auuid and ref.resourceType = :rtype"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", SecurityGroupVO.class.getSimpleName()); - Long sgn = q.getSingleResult(); - sgn = sgn == null ? 0 : sgn; - return sgn; - } - - private void check(APICreateSecurityGroupMsg msg, Map pairs) { - long sgNum = pairs.get(SecurityGroupQuotaConstant.SG_NUM).getValue(); - long sgn = getUsedSg(msg.getSession().getAccountUuid()); + private String getSecurityGroupSyncThreadName(String securityGroupUuid) { + return String.format("SecurityGroup-%s", securityGroupUuid); + } - if (sgn + 1 > sgNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), SecurityGroupQuotaConstant.SG_NUM, sgNum)); - } - } - }; + private String getVmNicSecurityGroupRefSyncThreadName() { + return String.format("SecurityGroup-VmNicSecurityGroupRef"); + } + @Override + public List reportQuota() { Quota quota = new Quota(); - quota.setOperator(checker); - quota.addMessageNeedValidation(APICreateSecurityGroupMsg.class); - - QuotaPair p = new QuotaPair(); - p.setName(SecurityGroupQuotaConstant.SG_NUM); - p.setValue(SecurityGroupQuotaGlobalConfig.SG_NUM.defaultValue(Long.class)); - quota.addPair(p); + quota.defineQuota(new SecurityGroupNumQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateSecurityGroupMsg.class) + .addCounterQuota(SecurityGroupQuotaConstant.SG_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(SecurityGroupVO.class) + .eq(SecurityGroupVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(SecurityGroupQuotaConstant.SG_NUM)); return list(quota); } @@ -166,15 +159,54 @@ public void managementNodeReady() { @Override public void validateSystemtagL3SecurityGroup(String l3Uuid, List securityGroupUuids) { - for(String uuid : securityGroupUuids) { - if (!Q.New(SecurityGroupL3NetworkRefVO.class) - .eq(SecurityGroupL3NetworkRefVO_.l3NetworkUuid, l3Uuid) - .eq(SecurityGroupL3NetworkRefVO_.securityGroupUuid, uuid) - .isExists()) { - throw new ApiMessageInterceptionException(argerr( - "l3NetWorkVO[uuid:%s] is not attach SecurityGroupVO[uuid:%s]", l3Uuid, uuid)); + if (!Q.New(NetworkServiceL3NetworkRefVO.class).eq(NetworkServiceL3NetworkRefVO_.l3NetworkUuid, l3Uuid) + .eq(NetworkServiceL3NetworkRefVO_.networkServiceType, SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE).isExists()) { + throw new ApiMessageInterceptionException(argerr("the netwotk service[type:%s] not enabled on the l3Network[uuid:%s]", SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE, l3Uuid)); + } + } + + private List getVmIpsBySecurityGroup(String sgUuid, int ipVersion){ + List ret = new ArrayList<>(); + String sql = "select ip.ip" + + " from VmNicVO nic, VmNicSecurityGroupRefVO ref, SecurityGroupVO sg, UsedIpVO ip" + + " where sg.uuid = ref.securityGroupUuid and ref.vmNicUuid = nic.uuid" + + " and ref.securityGroupUuid = :sgUuid" + + " and nic.uuid = ip.vmNicUuid and ip.ipVersion = :ipVersion"; + TypedQuery internalIpQuery = dbf.getEntityManager().createQuery(sql, String.class); + internalIpQuery.setParameter("sgUuid", sgUuid); + internalIpQuery.setParameter("ipVersion", ipVersion); + + List ips = internalIpQuery.getResultList(); + if (ips != null) { + ret.addAll(ips); + } + + /* add gateway address to group list */ + List attachedL3Uuids = Q.New(SecurityGroupL3NetworkRefVO.class).select(SecurityGroupL3NetworkRefVO_.l3NetworkUuid) + .eq(SecurityGroupL3NetworkRefVO_.securityGroupUuid, sgUuid).listValues(); + + List nicL3Uuids = SQL.New("select distinct l3.uuid from VmNicVO nic, VmNicSecurityGroupRefVO ref, L3NetworkVO l3" + + " where ref.securityGroupUuid = :sgUuid" + + " and ref.vmNicUuid = nic.uuid" + + " and l3.uuid = nic.l3NetworkUuid", String.class) + .param("sgUuid", sgUuid) + .list(); + + List resultL3Uuids = Stream.concat(attachedL3Uuids.stream(), nicL3Uuids.stream()).distinct().collect(Collectors.toList()); + + for (String uuid: resultL3Uuids) { + L3NetworkInventory inv = L3NetworkInventory.valueOf(dbf.findByUuid(uuid, L3NetworkVO.class)); + List iprs = IpRangeHelper.getNormalIpRanges(inv, ipVersion); + if (!iprs.isEmpty()) { + ret.add(iprs.get(0).getGateway()); } } + + for (SecurityGroupGetDefaultRuleExtensionPoint exp : pluginRgty.getExtensionList(SecurityGroupGetDefaultRuleExtensionPoint.class)) { + ret.addAll(exp.getGroupMembers(sgUuid, ipVersion)); + } + + return ret.stream().distinct().collect(Collectors.toList()); } private class RuleCalculator { @@ -184,12 +216,16 @@ private class RuleCalculator { private List hostUuids; private List vmStates; private List sgStates; + private boolean isDelete = false; List calculate() { if (sgStates == null) { - sgStates = new ArrayList(); - sgStates.add(SecurityGroupState.Enabled); + sgStates = asList(SecurityGroupState.Enabled); + } + if (vmStates == null) { + vmStates = asList(VmInstanceState.Running); } + if (vmNicUuids != null) { return calculateByVmNic(); } else if (l3NetworkUuids != null && securityGroupUuids != null) { @@ -215,7 +251,7 @@ HostSecurityGroupMembersTO returnHostSecurityGroupMember(String sgUuid){ hto.setGroupMembersTO(gto); Set hostUuids = new HashSet<>(); - List ts = SQL.New("select vm.hostUuid, vm.hypervisorType" + + List ts = SQL.New("select distinct vm.hostUuid, vm.hypervisorType" + " from VmNicVO nic, VmInstanceVO vm, VmNicSecurityGroupRefVO ref" + " where vm.uuid = nic.vmInstanceUuid" + " and nic.uuid = ref.vmNicUuid" + @@ -239,11 +275,13 @@ private List calculateByHost() { String sql = "select nic.uuid from VmNicVO nic, VmInstanceVO vm, VmNicSecurityGroupRefVO ref, SecurityGroupVO sg" + " where nic.uuid = ref.vmNicUuid and nic.vmInstanceUuid = vm.uuid"+ " and ref.securityGroupUuid = sg.uuid and sg.state in (:sgState)" + + " and sg.vSwitchType = :vSwitchType" + " and vm.hostUuid in (:hostUuids) and vm.state in (:vmStates)"; TypedQuery insgQuery = dbf.getEntityManager().createQuery(sql, String.class); insgQuery.setParameter("hostUuids", hostUuids); insgQuery.setParameter("vmStates", vmStates); insgQuery.setParameter("sgState", sgStates); + insgQuery.setParameter("vSwitchType", L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); List nicsInSg = insgQuery.getResultList(); sql = "select nic.uuid from VmNicVO nic, VmInstanceVO vm where nic.vmInstanceUuid = vm.uuid" + @@ -253,31 +291,23 @@ private List calculateByHost() { allq.setParameter("vmStates", vmStates); List allNics = allq.getResultList(); allNics.removeAll(nicsInSg); - List nicsOutSg = allNics; List ret = new ArrayList(); if (!nicsInSg.isEmpty()) { vmNicUuids = nicsInSg.stream().distinct().collect(Collectors.toList()); ret.addAll(calculateByVmNic()); } - if (!nicsOutSg.isEmpty()) { - Collection toRemove = createRulePlaceHolder(nicsOutSg, null); - for (HostRuleTO hto : toRemove) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); - } - //ret.addAll(toRemove); - ret = mergeMultiHostRuleTO(ret, toRemove); - } return ret; } @Transactional(readOnly = true) private List calculateBySecurityGroup() { - String sql = "select ref.vmNicUuid from VmNicSecurityGroupRefVO ref where ref.securityGroupUuid in (:sgUuids)"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); - q.setParameter("sgUuids", securityGroupUuids); - vmNicUuids = q.getResultList(); + vmNicUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .in(VmNicSecurityGroupRefVO_.securityGroupUuid, securityGroupUuids) + .listValues(); + vmNicUuids = vmNicUuids.stream().distinct().collect(Collectors.toList()); return calculateByVmNic(); } @@ -285,76 +315,57 @@ private List calculateByL3Network() { return null; } - List mergeMultiHostRuleTO(Collection... htos) { - Map hostRuleTOMap = new HashMap(); - for (Collection lst : htos) { - for (HostRuleTO hto : lst) { - HostRuleTO old = hostRuleTOMap.get(hto.getHostUuid()); - if (old == null) { - hostRuleTOMap.put(hto.getHostUuid(), hto); - } else { - old.getRules().addAll(hto.getRules()); - old.getIpv6Rules().addAll(hto.getIpv6Rules()); - } - } - } - - List ret = new ArrayList(hostRuleTOMap.size()); - ret.addAll(hostRuleTOMap.values()); - return ret; - } - private List calculateByL3NetworkAndSecurityGroup() { - String sql = "select ref.vmNicUuid from VmNicSecurityGroupRefVO ref, SecurityGroupL3NetworkRefVO l3ref, VmNicVO nic, UsedIpVO ip, SecurityGroupVO sg" + - " where l3ref.securityGroupUuid = ref.securityGroupUuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = l3ref.l3NetworkUuid" + - " and ref.securityGroupUuid in (:sgUuids) and l3ref.l3NetworkUuid in (:l3Uuids)" + - " and ref.securityGroupUuid = sg.uuid and sg.state in (:sgStates)"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); - q.setParameter("sgUuids", securityGroupUuids); - q.setParameter("l3Uuids", l3NetworkUuids); - q.setParameter("sgStates", sgStates); - vmNicUuids = q.getResultList().stream().distinct().collect(Collectors.toList()); + List targetNicUuids = SQL.New("select ref.vmNicUuid from VmNicSecurityGroupRefVO ref, VmNicVO nic, SecurityGroupVO sg" + + " where nic.l3NetworkUuid in (:l3Uuids)" + + " and ref.vmNicUuid = nic.uuid" + + " and ref.securityGroupUuid in (:sgUuids)" + + " and sg.state in (:sgStates)", String.class) + .param("l3Uuids", l3NetworkUuids) + .param("sgUuids", securityGroupUuids) + .param("sgStates", sgStates) + .list(); + vmNicUuids = targetNicUuids.stream().distinct().collect(Collectors.toList()); return calculateByVmNic(); } - private List calculateRuleTOBySecurityGroup(List sgUuids, List l3Uuids, int ipVersion) { + private List calculateRuleTOBySecurityGroup(String sgUuid, String l3Uuid, int ipVersion) { List ret = new ArrayList<>(); + List rules = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, sgUuid) + .eq(SecurityGroupRuleVO_.ipVersion, ipVersion) + .eq(SecurityGroupRuleVO_.state, SecurityGroupRuleState.Enabled) + .list(); - for (String sgUuid : sgUuids) { - if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).in(SecurityGroupVO_.state, sgStates).isExists()) { - continue; - } - List rules = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, sgUuid) - .eq(SecurityGroupRuleVO_.ipVersion, ipVersion) - .isNull(SecurityGroupRuleVO_.remoteSecurityGroupUuid).list(); - if (rules.isEmpty()) { - continue; - } + if (rules.isEmpty()) { + return ret; + } - for (SecurityGroupRuleVO r : rules) { - if ( r.getRemoteSecurityGroupUuid() != null) { - SecurityGroupVO remoteSg = Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, r.getRemoteSecurityGroupUuid()).in(SecurityGroupVO_.state, sgStates).find(); - if (remoteSg == null) { - continue; - } + for (SecurityGroupRuleVO r : rules) { + if (r.getRemoteSecurityGroupUuid() != null) { + if (!Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, r.getRemoteSecurityGroupUuid()).in(SecurityGroupVO_.state, sgStates).isExists()) { + continue; } - RuleTO rto = new RuleTO(); - rto.setIpVersion(r.getIpVersion()); - rto.setAllowedCidr(r.getAllowedCidr()); - rto.setEndPort(r.getEndPort()); - rto.setProtocol(r.getProtocol().toString()); - rto.setStartPort(r.getStartPort()); - rto.setType(r.getType().toString()); - rto.setSecurityGroupUuid(r.getSecurityGroupUuid()); - ret.add(rto); } + RuleTO rto = new RuleTO(); + rto.setIpVersion(r.getIpVersion()); + rto.setPriority(r.getPriority()); + rto.setRuleType(r.getType().toString()); + rto.setState(r.getState().toString()); + rto.setRemoteGroupUuid(r.getRemoteSecurityGroupUuid()); + rto.setRemoteGroupVmIps(getVmIpsBySecurityGroup(r.getRemoteSecurityGroupUuid(), r.getIpVersion())); + rto.setProtocol(r.getProtocol().toString()); + rto.setSrcIpRange(r.getSrcIpRange()); + rto.setDstIpRange(r.getDstIpRange()); + rto.setDstPortRange(r.getDstPortRange()); + rto.setAction(r.getAction()); + ret.add(rto); } if (logger.isTraceEnabled()) { StringBuilder sb = new StringBuilder(); sb.append(String.format("\n-------------- begin calculateRuleTOBySecurityGroupUuid ---------------------")); - sb.append(String.format("\ninput security group uuids: %s for ipv%d", sgUuids, ipVersion)); + sb.append(String.format("\ninput security group uuid: %s for ipv%d", sgUuid, ipVersion)); sb.append(String.format("\nresult: %s", JSONObjectUtil.toJsonString(ret))); sb.append(String.format("\n-------------- end calculateRuleTOBySecurityGroupUuid ---------------------")); logger.trace(sb.toString()); @@ -363,278 +374,230 @@ private List calculateRuleTOBySecurityGroup(List sgUuids, List calculateSecurityGroupBaseRule(List sgUuids, List l3Uuids, int ipVersion){ - List rules = new ArrayList<>(); - for(String sgUuid : sgUuids){ - String sql = "select r from SecurityGroupRuleVO r,SecurityGroupVO sg where r.securityGroupUuid = :sgUuid and r.ipVersion = :ipVersion" + - " and r.remoteSecurityGroupUuid is not null and r.remoteSecurityGroupUuid = sg.uuid and sg.state in (:sgStates)"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, SecurityGroupRuleVO.class); - q.setParameter("sgUuid", sgUuid); - q.setParameter("sgStates", sgStates); - q.setParameter("ipVersion", ipVersion); - List remoteRules = q.getResultList(); - - for(SecurityGroupRuleVO r : remoteRules){ - RuleTO rule = new RuleTO(); - rule.setIpVersion(r.getIpVersion()); - rule.setStartPort(r.getStartPort()); - rule.setEndPort(r.getEndPort()); - rule.setProtocol(r.getProtocol().toString()); - rule.setType(r.getType().toString()); - rule.setAllowedCidr(r.getAllowedCidr()); - rule.setSecurityGroupUuid(sgUuid); - rule.setRemoteGroupUuid(r.getRemoteSecurityGroupUuid()); - // TODO: the same group only transport once - rule.setRemoteGroupVmIps(getVmIpsBySecurityGroup(r.getRemoteSecurityGroupUuid(), r.getIpVersion())); - rules.add(rule); - } + @Transactional(readOnly = true) + public VmNicSecurityGroupTo calculateVmNicSecurityGroupTO() { + if (sgStates == null) { + sgStates = asList(SecurityGroupState.Enabled); } - return rules; - } + VmNicSecurityGroupTo to = new VmNicSecurityGroupTo(); + if (vmNicUuids != null && !vmNicUuids.isEmpty()) { + // calculate nic security group priority + List ts = SQL.New("select nic.uuid, nic.internalName, nic.mac" + + " from VmInstanceVO vm, VmNicVO nic" + + " where nic.uuid in (:vmNicUuids) and nic.vmInstanceUuid = vm.uuid", Tuple.class) + .param("vmNicUuids", vmNicUuids) + .list(); + if (ts.isEmpty()) { + logger.debug(String.format("security group calculateVmNicSecurityGroupTO: no match nics[%s] ", vmNicUuids)); + return to; + } + + List usedIps = Q.New(UsedIpVO.class).in(UsedIpVO_.vmNicUuid, vmNicUuids).list(); + List policies = Q.New(VmNicSecurityPolicyVO.class).in(VmNicSecurityPolicyVO_.vmNicUuid, vmNicUuids).list(); + List refs = SQL.New("select ref.vmNicUuid, ref.priority, sg.uuid, sg.state" + + " from VmNicSecurityGroupRefVO ref, SecurityGroupVO sg" + + " where ref.vmNicUuid in (:vmNicUuids)" + + " and ref.securityGroupUuid = sg.uuid" + + " and sg.state in (:sgStates)", Tuple.class) + .param("vmNicUuids", vmNicUuids) + .param("sgStates", sgStates) + .list(); + ; + + for (Tuple t : ts) { + String nicUuid = t.get(0, String.class); + String nicName = t.get(1, String.class); + String mac = t.get(2, String.class); + + VmNicSecurityPolicyVO policy = policies.stream().filter(p -> p.getVmNicUuid().equals(nicUuid)).findFirst().orElse(null); + if (policy == null) { + continue; + } - private List getVmIpsBySecurityGroup(String sgUuid, int ipVersion){ - List ret = new ArrayList<>(); - // TODO: if two L3 network which have same ip segment attached same sg, it might has a problem - String sql = "select ip.ip" + - " from VmNicVO nic, VmNicSecurityGroupRefVO ref, SecurityGroupVO sg, UsedIpVO ip" + - " where sg.uuid = ref.securityGroupUuid and ref.vmNicUuid = nic.uuid" + - " and ref.securityGroupUuid = :sgUuid" + - " and nic.uuid = ip.vmNicUuid and ip.ipVersion = :ipVersion"; - TypedQuery internalIpQuery = dbf.getEntityManager().createQuery(sql, String.class); - internalIpQuery.setParameter("sgUuid", sgUuid); - internalIpQuery.setParameter("ipVersion", ipVersion); + VmNicSecurityTO nicTo = new VmNicSecurityTO(); + nicTo.setVmNicUuid(nicUuid); + nicTo.setInternalName(nicName); + nicTo.setMac(mac); + nicTo.setIngressPolicy(policy.getIngressPolicy()); + nicTo.setEgressPolicy(policy.getEgressPolicy()); + + List ips = usedIps.stream().filter(i -> i.getVmNicUuid().equals(nicUuid)).collect(Collectors.toList()); + for (UsedIpVO ip : ips) { + String ipAddr = ip.getIp(); + nicTo.getVmNicIps().add(ipAddr); + } + List sgRefs = refs.stream() + .filter(r -> r.get(0, String.class).equals(nicUuid) && + r.get(3, SecurityGroupState.class) == SecurityGroupState.Enabled) + .collect(Collectors.toList()); + if (sgRefs.isEmpty()) { + nicTo.setActionCode(VmNicSecurityTO.ACTION_CODE_DELETE_CHAIN); + } + for (Tuple sgRef : sgRefs) { + int priority = sgRef.get(1, Integer.class); + String sgUuid = sgRef.get(2, String.class); + if (securityGroupUuids != null && securityGroupUuids.contains(sgUuid)) { + nicTo.getSecurityGroupRefs().put(sgUuid, priority); + } + } - List ips = internalIpQuery.getResultList(); - if (ips != null) { - ret.addAll(ips); + to.getVmNics().add(nicTo); + } } - /* add gateway address to group list */ - List l3Uuids = Q.New(SecurityGroupL3NetworkRefVO.class).select(SecurityGroupL3NetworkRefVO_.l3NetworkUuid) - .eq(SecurityGroupL3NetworkRefVO_.securityGroupUuid, sgUuid).listValues(); - for (String uuid: l3Uuids) { - L3NetworkInventory inv = L3NetworkInventory.valueOf(dbf.findByUuid(uuid, L3NetworkVO.class)); - List iprs = IpRangeHelper.getNormalIpRanges(inv, ipVersion); - if (!iprs.isEmpty()) { - ret.add(iprs.get(0).getGateway()); + // calculate security group rules + if (securityGroupUuids != null && !securityGroupUuids.isEmpty()) { + for (String uuid : securityGroupUuids) { + SecurityGroupTo group = new SecurityGroupTo(); + + SecurityGroupVO vo = dbf.findByUuid(uuid, SecurityGroupVO.class); + group.setSecurityGroupUuid(uuid); + group.setSecurityGroupName(vo.getName()); + int internalId = (int)vo.getInternalId(); + group.setInternalId(internalId); + group.setSecurityGroupVmIps(getVmIpsBySecurityGroup(uuid, IPv6Constants.IPv4)); + group.setSecurityGroupVmIp6s(getVmIpsBySecurityGroup(uuid, IPv6Constants.IPv6)); + + List rules = vo.getRules().stream() + .filter(r -> r.getState() == SecurityGroupRuleState.Enabled) + .collect(Collectors.toList()); + for (SecurityGroupRuleVO r : rules) { + RuleTO rto = new RuleTO(); + rto.setIpVersion(r.getIpVersion()); + rto.setPriority(r.getPriority()); + rto.setRuleType(r.getType().toString()); + rto.setState(r.getState().toString()); + rto.setRemoteGroupUuid(r.getRemoteSecurityGroupUuid()); + rto.setProtocol(r.getProtocol().toString()); + rto.setSrcIpRange(r.getSrcIpRange()); + rto.setDstIpRange(r.getDstIpRange()); + rto.setDstPortRange(r.getDstPortRange()); + rto.setAction(r.getAction()); + group.getRules().add(rto); + } + + to.getGroups().add(group); } } - for (SecurityGroupGetDefaultRuleExtensionPoint exp : pluginRgty.getExtensionList(SecurityGroupGetDefaultRuleExtensionPoint.class)) { - ret.addAll(exp.getGroupMembers(sgUuid, ipVersion)); + if (logger.isTraceEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("\n=================== begin calculateVmNicSecurityGroupTO ======================")); + sb.append(String.format("\ninput vmNic uuids: %s", vmNicUuids)); + sb.append(String.format("\nresult: %s", JSONObjectUtil.toJsonString(to))); + sb.append(String.format("\n=================== end calculateVmNicSecurityGroupTO ========================")); + logger.trace(sb.toString()); } - return ret; + return to; } - /* calculate the default rules for nics which are not bound to sg */ @Transactional(readOnly = true) - Collection createRulePlaceHolder(List nicUuids, Integer ipVersion) { - List tuples; - if (ipVersion != null) { - /* there are multiple ips on same nic */ - String sql = "select nic.uuid, vm.hostUuid, vm.hypervisorType, nic.internalName, nic.mac, ip.ip, ip.ipVersion" + - " from VmInstanceVO vm, VmNicVO nic, UsedIpVO ip" + - " where nic.vmInstanceUuid = vm.uuid and vm.hostUuid is not null and nic.uuid in (:nicUuids)" + - " and ip.vmNicUuid = nic.uuid and ip.ipVersion = :ipversion"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); - q.setParameter("nicUuids", nicUuids).setParameter("ipversion", ipVersion); - tuples = q.getResultList(); - - sql = "select nic.uuid, vm.lastHostUuid, vm.hypervisorType, nic.internalName, nic.mac, ip.ip, ip.ipVersion" + - " from VmInstanceVO vm, VmNicVO nic, UsedIpVO ip" + - " where nic.vmInstanceUuid = vm.uuid and vm.hostUuid is null and vm.lastHostUuid is not null" + - " and nic.uuid in (:nicUuids) and ip.vmNicUuid = nic.uuid and ip.ipVersion = :ipversion"; - q = dbf.getEntityManager().createQuery(sql, Tuple.class); - q.setParameter("nicUuids", nicUuids).setParameter("ipversion", ipVersion); - tuples.addAll(q.getResultList()); - } else { - /* there are multiple ips on same nic */ - String sql = "select nic.uuid, vm.hostUuid, vm.hypervisorType, nic.internalName, nic.mac, ip.ip, ip.ipVersion" + - " from VmInstanceVO vm, VmNicVO nic, UsedIpVO ip" + - " where nic.vmInstanceUuid = vm.uuid and vm.hostUuid is not null and nic.uuid in (:nicUuids)" + - " and ip.vmNicUuid = nic.uuid"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); - q.setParameter("nicUuids", nicUuids); - tuples = q.getResultList(); - - sql = "select nic.uuid, vm.lastHostUuid, vm.hypervisorType, nic.internalName, nic.mac, ip.ip, ip.ipVersion" + - " from VmInstanceVO vm, VmNicVO nic, UsedIpVO ip" + - " where nic.vmInstanceUuid = vm.uuid and vm.hostUuid is null and vm.lastHostUuid is not null" + - " and nic.uuid in (:nicUuids) and ip.vmNicUuid = nic.uuid"; - q = dbf.getEntityManager().createQuery(sql, Tuple.class); - q.setParameter("nicUuids", nicUuids); - tuples.addAll(q.getResultList()); - } - - Map hostRuleTOMap = new HashMap(); - for (Tuple t : tuples) { - String nicUuid = t.get(0, String.class); - String hostUuid = t.get(1, String.class); - String hvType = t.get(2, String.class); + private List calculateByVmNic() { + Map htoMap = new HashMap(); + + if (vmNicUuids == null || vmNicUuids.isEmpty()) { + return new ArrayList<>(htoMap.values()); + } + + List ts = SQL.New("select vm.hostUuid, vm.hypervisorType, nic.uuid, nic.internalName, nic.mac" + + " from VmInstanceVO vm, VmNicVO nic" + + " where nic.uuid in (:vmNicUuids) and nic.vmInstanceUuid = vm.uuid and vm.state in (:vmStates)", Tuple.class) + .param("vmNicUuids", vmNicUuids) + .param("vmStates", vmStates) + .list(); + + if (ts.isEmpty()) { + logger.debug(String.format("security group calcuateByVmNic: no match nics[%s] ", vmNicUuids)); + return new ArrayList<>(htoMap.values()); + } + + List usedIps = Q.New(UsedIpVO.class).in(UsedIpVO_.vmNicUuid, vmNicUuids).list(); + List policies = Q.New(VmNicSecurityPolicyVO.class).in(VmNicSecurityPolicyVO_.vmNicUuid, vmNicUuids).list(); + + List refs = SQL.New("select ref.vmNicUuid, ref.priority, sg.uuid" + + " from VmNicSecurityGroupRefVO ref, SecurityGroupVO sg" + + " where ref.vmNicUuid in (:vmNicUuids)" + + " and ref.securityGroupUuid = sg.uuid" + + " and sg.state in (:sgStates)", Tuple.class) + .param("vmNicUuids", vmNicUuids) + .param("sgStates", sgStates) + .list(); + + for (Tuple t : ts) { + String hostUuid = t.get(0, String.class); + String hvType = t.get(1, String.class); + String nicUuid = t.get(2, String.class); String nicName = t.get(3, String.class); String mac = t.get(4, String.class); - String ip = t.get(5, String.class); - Integer version = t.get(6, Integer.class); - HostRuleTO hto = hostRuleTOMap.get(hostUuid); + VmNicSecurityPolicyVO policy = policies.stream().filter(p -> p.getVmNicUuid().equals(nicUuid)).findFirst().orElse(null); + if (policy == null) { + continue; + } + + HostRuleTO hto = htoMap.get(hostUuid); if (hto == null) { hto = new HostRuleTO(); - hto.setHostUuid(hostUuid); hto.setHypervisorType(hvType); - hostRuleTOMap.put(hto.getHostUuid(), hto); + hto.setHostUuid(hostUuid); + htoMap.put(hostUuid, hto); } - Optional sgRule; - if (version == IPv6Constants.IPv4) { - sgRule = hto.getRules().stream().filter(r -> r.getVmNicUuid().equals(nicUuid)).findFirst(); - } else { - sgRule = hto.getIpv6Rules().stream().filter(r -> r.getVmNicUuid().equals(nicUuid)).findFirst(); + VmNicSecurityTO nicTo = new VmNicSecurityTO(); + nicTo = new VmNicSecurityTO(); + nicTo.setVmNicUuid(nicUuid); + nicTo.setInternalName(nicName); + nicTo.setMac(mac); + nicTo.setIngressPolicy(policy.getIngressPolicy()); + nicTo.setEgressPolicy(policy.getEgressPolicy()); + if (isDelete) { + nicTo.setActionCode(VmNicSecurityTO.ACTION_CODE_DELETE_CHAIN); + hto.getVmNics().add(nicTo); + continue; } + nicTo.setActionCode(VmNicSecurityTO.ACTION_CODE_APPLY_CHAIN); + hto.getVmNics().add(nicTo); - if (sgRule.isPresent()) { - sgRule.get().getVmNicIp().add(ip); - } else { - SecurityGroupRuleTO sgto = new SecurityGroupRuleTO(); - sgto.setEgressDefaultPolicy(SecurityGroupGlobalConfig.EGRESS_RULE_DEFAULT_POLICY.value(String.class)); - sgto.setIngressDefaultPolicy(SecurityGroupGlobalConfig.INGRESS_RULE_DEFAULT_POLICY.value(String.class)); - sgto.setRules(new ArrayList()); - sgto.setSecurityGroupBaseRules(new ArrayList()); - sgto.setVmNicUuid(nicUuid); - sgto.setVmNicInternalName(nicName); - sgto.setVmNicMac(mac); - sgto.setVmNicIp(new ArrayList<>()); - sgto.getVmNicIp().add(ip); - if (version == IPv6Constants.IPv4) { - hto.getRules().add(sgto); - } else { - hto.getIpv6Rules().add(sgto); - } + List ips = usedIps.stream().filter(i -> i.getVmNicUuid().equals(nicUuid)).collect(Collectors.toList()); + List sgRefs = refs.stream().filter(r -> r.get(0, String.class).equals(nicUuid)).collect(Collectors.toList()); + if (ips.isEmpty() || sgRefs.isEmpty()) { + continue; } - } - - return hostRuleTOMap.values(); - } - @Transactional(readOnly = true) - private List calculateByVmNic() { - Map hostRuleMap = new HashMap(); - List htos = new ArrayList(); - - for (String nicUuid : vmNicUuids) { - List tuples; - if (vmStates != null && !vmStates.isEmpty()) { - String sql = "select ref.securityGroupUuid, vm.hostUuid, vm.hypervisorType, nic.internalName, ip.l3NetworkUuid, nic.mac, ip.ip, ip.ipVersion" + - " from VmNicSecurityGroupRefVO ref, VmInstanceVO vm, VmNicVO nic, SecurityGroupVO sg, UsedIpVO ip" + - " where ref.vmNicUuid = nic.uuid and nic.vmInstanceUuid = vm.uuid and ref.vmNicUuid = :nicUuid " + - " and vm.state in (:vmStates) and ref.securityGroupUuid = sg.uuid and sg.state in (:sgStates) " + - " and nic.uuid = ip.vmNicUuid"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); - q.setParameter("nicUuid", nicUuid); - q.setParameter("vmStates", vmStates); - q.setParameter("sgStates", sgStates); - tuples = q.getResultList(); - } else { - String sql = "select ref.securityGroupUuid, vm.hostUuid, vm.hypervisorType, nic.internalName, ip.l3NetworkUuid, nic.mac, ip.ip, ip.ipVersion" + - " from VmNicSecurityGroupRefVO ref, VmInstanceVO vm, VmNicVO nic, SecurityGroupVO sg, UsedIpVO ip" + - " where ref.vmNicUuid = nic.uuid and nic.vmInstanceUuid = vm.uuid and ref.vmNicUuid = :nicUuid " + - " and ref.securityGroupUuid = sg.uuid and sg.state in (:sgStates) and nic.uuid = ip.vmNicUuid"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); - q.setParameter("nicUuid", nicUuid); - q.setParameter("sgStates", sgStates); - tuples = q.getResultList(); - } + for (UsedIpVO ip : ips) { + String l3Uuid = ip.getL3NetworkUuid(); + String ipAddr = ip.getIp(); + int ipVersion = ip.getIpVersion(); - if (tuples.isEmpty()) { - // vm is not in vmStates or not in security group - continue; - } + nicTo.getVmNicIps().add(ipAddr); + // get security group rules if actionCode == "applyChain" + Map> sgRules = ipVersion == IPv6Constants.IPv4 ? hto.getRules() : hto.getIp6Rules(); + for (Tuple sgRef : sgRefs) { + int priority = sgRef.get(1, Integer.class); + String sgUuid = sgRef.get(2, String.class); - List sgUuids = new ArrayList(); - String hostUuid = null; - String hypervisorType = null; - String nicName = null; - List l3Uuids = new ArrayList(); - String mac = null; - List ips = new ArrayList(); - List ip6s = new ArrayList(); - for (Tuple t : tuples) { - sgUuids.add(t.get(0, String.class)); - hostUuid = t.get(1, String.class); - hypervisorType = t.get(2, String.class); - nicName = t.get(3, String.class); - l3Uuids.add(t.get(4, String.class)); - mac = t.get(5, String.class); - Integer version = t.get(7, Integer.class); - if (version == IPv6Constants.IPv4) { - ips.add(t.get(6, String.class)); - } else { - ip6s.add(t.get(6, String.class)); - } - } + nicTo.getSecurityGroupRefs().put(sgUuid, priority); - /* calculate all sg rules for a single nic, including ipv4 rules and ipv6 rules */ - sgUuids = sgUuids.stream().distinct().collect(Collectors.toList()); - l3Uuids = l3Uuids.stream().distinct().collect(Collectors.toList()); - if (!sgUuids.isEmpty()) { - HostRuleTO hto = hostRuleMap.get(hostUuid); - if (hto == null) { - hto = new HostRuleTO(); - hto.setHostUuid(hostUuid); - hto.setHypervisorType(hypervisorType); - hostRuleMap.put(hto.getHostUuid(), hto); - } - - if (!ips.isEmpty()) { - List rtos = calculateRuleTOBySecurityGroup(sgUuids, l3Uuids, IPv6Constants.IPv4); - List securityGroupBaseRules = calculateSecurityGroupBaseRule(sgUuids, l3Uuids, IPv6Constants.IPv4); - SecurityGroupRuleTO sgto = new SecurityGroupRuleTO(); - sgto.setEgressDefaultPolicy(SecurityGroupGlobalConfig.EGRESS_RULE_DEFAULT_POLICY.value(String.class)); - sgto.setIngressDefaultPolicy(SecurityGroupGlobalConfig.INGRESS_RULE_DEFAULT_POLICY.value(String.class)); - sgto.setRules(rtos); - sgto.setVmNicUuid(nicUuid); - sgto.setVmNicInternalName(nicName); - sgto.setVmNicMac(mac); - sgto.setVmNicIp(ips); - sgto.setSecurityGroupBaseRules(securityGroupBaseRules); - sgto.setIpVersion(IPv6Constants.IPv4); - hto.getRules().add(sgto); - } - - /* caculate ipv6 rules */ - if (!ip6s.isEmpty()) { - List rtos6 = calculateRuleTOBySecurityGroup(sgUuids, l3Uuids, IPv6Constants.IPv6); - List securityGroupBaseRules6 = calculateSecurityGroupBaseRule(sgUuids, l3Uuids, IPv6Constants.IPv6); - SecurityGroupRuleTO sgto6 = new SecurityGroupRuleTO(); - sgto6.setEgressDefaultPolicy(SecurityGroupGlobalConfig.EGRESS_RULE_DEFAULT_POLICY.value(String.class)); - sgto6.setIngressDefaultPolicy(SecurityGroupGlobalConfig.INGRESS_RULE_DEFAULT_POLICY.value(String.class)); - sgto6.setRules(rtos6); - sgto6.setVmNicUuid(nicUuid); - sgto6.setVmNicInternalName(nicName); - sgto6.setVmNicMac(mac); - sgto6.setVmNicIp(ip6s); - sgto6.setSecurityGroupBaseRules(securityGroupBaseRules6); - sgto6.setIpVersion(IPv6Constants.IPv6); - - hto.getIpv6Rules().add(sgto6); + if (!sgRules.containsKey(sgUuid)) { + List rule = calculateRuleTOBySecurityGroup(sgUuid, l3Uuid, ipVersion); + sgRules.put(sgUuid, rule); + } } } } - htos.addAll(hostRuleMap.values()); - if (logger.isTraceEnabled()) { StringBuilder sb = new StringBuilder(); sb.append(String.format("\n=================== begin rulesByNicUuids ======================")); sb.append(String.format("\ninput vmNic uuids: %s", vmNicUuids)); - sb.append(String.format("\nresult: %s", JSONObjectUtil.toJsonString(htos))); + sb.append(String.format("\nresult: %s", JSONObjectUtil.toJsonString(htoMap.values()))); sb.append(String.format("\n=================== end rulesByNicUuids ========================")); logger.trace(sb.toString()); } - return htos; + return htoMap.values().stream().collect(Collectors.toList()); } } @@ -668,218 +631,1285 @@ private void handleLocalMessage(Message msg) { } } - private void handle(CreateSecurityGroupMsg msg) { - CreateSecurityGroupReply reply = new CreateSecurityGroupReply(); - SecurityGroupVO vo = new SecurityGroupVO(); - vo.setUuid(Platform.getUuid()); - vo.setName(msg.getName()); - vo.setDescription(msg.getDescription()); - vo.setState(SecurityGroupState.Enabled); - vo.setInternalId(dbf.generateSequenceNumber(SecurityGroupSequenceNumberVO.class)); - vo.setAccountUuid(msg.getAccountUuid()); - vo = dbf.persistAndRefresh(vo); - - createDefaultRule(vo.getUuid(), IPv6Constants.IPv4); - createDefaultRule(vo.getUuid(), IPv6Constants.IPv6); - - reply.setInventory(SecurityGroupInventory.valueOf(vo)); - bus.reply(msg, reply); - } + @Override + public VmNicSecurityGroupTo getVmNicSecurityGroupRules(List sgUuids) { + RuleCalculator cal = new RuleCalculator(); + cal.sgStates = Collections.singletonList(SecurityGroupState.Enabled); + cal.securityGroupUuids = sgUuids; + cal.vmNicUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .in(VmNicSecurityGroupRefVO_.securityGroupUuid, sgUuids) + .listValues(); + cal.vmNicUuids = cal.vmNicUuids.stream().distinct().collect(Collectors.toList()); + if (cal.vmNicUuids.isEmpty()) { + VmNicSecurityGroupTo nicTo = cal.calculateVmNicSecurityGroupTO(); + return nicTo; + } - private void handle(AddSecurityGroupRuleMsg msg) { - AddSecurityGroupRuleReply reply = new AddSecurityGroupRuleReply(); - SecurityGroupVO securityGroupVO = addRuleToSecurityGroup(msg); - reply.setInventory(SecurityGroupInventory.valueOf(securityGroupVO)); - bus.reply(msg, reply); + return cal.calculateVmNicSecurityGroupTO(); } - private void handle(SecurityGroupDeletionMsg msg) { - SecurityGroupDeletionReply reply = new SecurityGroupDeletionReply(); - dbf.removeByPrimaryKey(msg.getUuid(), SecurityGroupVO.class); - bus.reply(msg, reply); - } + private void sdnRefreshVmNicsDefaultRule(SecurityGroupSdnBackend sdnBackend, List vmNicUuids, Completion completion) { + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = vmNicUuids; - private void handle(RemoveVmNicFromSecurityGroupMsg msg) { - RemoveVmNicFromSecurityGroupReply reply = new RemoveVmNicFromSecurityGroupReply(); - removeNicFromSecurityGroup(msg.getSecurityGroupUuid(), msg.getVmNicUuids()); - bus.reply(msg, reply); + VmNicSecurityGroupTo nicTo = cal.calculateVmNicSecurityGroupTO(); + sdnBackend.updateSecurityGroup(nicTo, completion); } - private void handle(RefreshSecurityGroupRulesOnVmMsg msg) { - RefreshSecurityGroupRulesOnVmReply reply = new RefreshSecurityGroupRulesOnVmReply(); - List nicUuids = msg.getNicUuids(); - if (nicUuids == null || nicUuids.isEmpty()) { - SimpleQuery q = dbf.createQuery(VmNicSecurityGroupRefVO.class); - q.select(VmNicSecurityGroupRefVO_.vmNicUuid); - q.add(VmNicSecurityGroupRefVO_.vmInstanceUuid, Op.EQ, msg.getVmInstanceUuid()); - nicUuids = q.listValue(); - } - - if (nicUuids.isEmpty()) { - checkDefaultRulesOnHost(msg.getHostUuid()); - logger.debug(String.format("no nic of vm[uuid:%s] needs to refresh security group rule", msg.getVmInstanceUuid())); - bus.reply(msg, reply); - return; - } - - nicUuids = nicUuids.stream().distinct().collect(Collectors.toList()); - Collection htos; + private void sdnRefreshVmNics(SecurityGroupSdnBackend sdnBackend, List vmNicUuids, Completion completion) { RuleCalculator cal = new RuleCalculator(); - if (msg.isDeleteAllRules()) { - htos = cal.createRulePlaceHolder(nicUuids, null); - for (HostRuleTO hto : htos) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); - } - } else { - cal.vmNicUuids = nicUuids; - htos = cal.calculate(); - } - - for (HostRuleTO hto : htos) { - if (hto.getHostUuid() == null) { - hto.setHostUuid(msg.getHostUuid()); - } + cal.sgStates = Collections.singletonList(SecurityGroupState.Enabled);; + cal.securityGroupUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.securityGroupUuid) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids) + .listValues(); + if (cal.securityGroupUuids.isEmpty()) { + completion.success(); + return; } + cal.securityGroupUuids = cal.securityGroupUuids.stream().distinct().collect(Collectors.toList()); + cal.vmNicUuids = vmNicUuids; - applyRules(htos); - - if (htos.isEmpty()) { - checkDefaultRulesOnHost(msg.getHostUuid()); + VmNicSecurityGroupTo nicTo = cal.calculateVmNicSecurityGroupTO(); + for (VmNicSecurityTO to : nicTo.vmNics) { + to.setSync(true); } - logger.debug(String.format("refreshed security group rule for vm[uuid:%s] vNicuuids[%s]", - msg.getVmInstanceUuid(), Joiner.on(",").join(nicUuids))); - bus.reply(msg, reply); - } - - private void createFailureHostTask(String huuid) { - SecurityGroupFailureHostVO fvo = new SecurityGroupFailureHostVO(); - fvo.setHostUuid(huuid); - dbf.persist(fvo); + sdnBackend.updateSecurityGroup(nicTo, completion); } - private void handle(RefreshSecurityGroupRulesOnHostMsg msg) { + private void sdnRemoveSecurityGroupFromVmNic(SecurityGroupSdnBackend sdnBackend, + List sgUuids, List vmNicUuids, Completion completion) { RuleCalculator cal = new RuleCalculator(); - cal.hostUuids = asList(msg.getHostUuid()); - // refreshing may happen when host is reconnecting; at that time VMs' states are Unknown - cal.vmStates = asList(VmInstanceState.Unknown, VmInstanceState.Running); - List htos = cal.calculate(); - for (HostRuleTO hto : htos) { - hto.setRefreshHost(true); + cal.securityGroupUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.securityGroupUuid) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids) + .listValues(); + cal.securityGroupUuids.addAll(sgUuids); + cal.securityGroupUuids = cal.securityGroupUuids.stream().distinct().collect(Collectors.toList()); + cal.vmNicUuids = vmNicUuids; + + VmNicSecurityGroupTo nicTo = cal.calculateVmNicSecurityGroupTO(); + for (VmNicSecurityTO to : nicTo.vmNics) { + to.setSync(true); } - logger.debug(String.format("required to refresh rules on host[uuid:%s]", msg.getHostUuid())); - applyRules(htos); + sdnBackend.updateSecurityGroup(nicTo, completion); } - private void handleApiMessage(APIMessage msg) { - if (msg instanceof APICreateSecurityGroupMsg) { - handle((APICreateSecurityGroupMsg) msg); - } else if (msg instanceof APIAddSecurityGroupRuleMsg) { - handle((APIAddSecurityGroupRuleMsg) msg); - } else if (msg instanceof APIAddVmNicToSecurityGroupMsg) { - handle((APIAddVmNicToSecurityGroupMsg) msg); - } else if (msg instanceof APIDeleteSecurityGroupRuleMsg) { - handle((APIDeleteSecurityGroupRuleMsg) msg); - } else if (msg instanceof APIDeleteSecurityGroupMsg) { - handle((APIDeleteSecurityGroupMsg) msg); - } else if (msg instanceof APIDeleteVmNicFromSecurityGroupMsg) { - handle((APIDeleteVmNicFromSecurityGroupMsg) msg); - } else if (msg instanceof APIAttachSecurityGroupToL3NetworkMsg) { - handle((APIAttachSecurityGroupToL3NetworkMsg) msg); - } else if (msg instanceof APIChangeSecurityGroupStateMsg) { - handle((APIChangeSecurityGroupStateMsg) msg); - } else if (msg instanceof APIDetachSecurityGroupFromL3NetworkMsg) { - handle((APIDetachSecurityGroupFromL3NetworkMsg) msg); - } else if (msg instanceof APIGetCandidateVmNicForSecurityGroupMsg) { - handle((APIGetCandidateVmNicForSecurityGroupMsg) msg); - } else if (msg instanceof APIUpdateSecurityGroupMsg) { - handle((APIUpdateSecurityGroupMsg) msg); + private void sdnDeleteSecurityGroup(SecurityGroupSdnBackend sdnBackend, List vmNicUuids, + String sgUuid,Completion completion) { + RuleCalculator cal = new RuleCalculator(); + if (!vmNicUuids.isEmpty()) { + cal.securityGroupUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.securityGroupUuid) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids) + .listValues(); } else { - bus.dealWithUnknownMessage(msg); + cal.securityGroupUuids = new ArrayList<>(); } - } + cal.securityGroupUuids.add(sgUuid); + cal.securityGroupUuids = cal.securityGroupUuids.stream().distinct().collect(Collectors.toList()); + cal.vmNicUuids = vmNicUuids; - private void handle(APIUpdateSecurityGroupMsg msg) { - boolean update = false; - SecurityGroupVO vo = dbf.findByUuid(msg.getUuid(), SecurityGroupVO.class); - if (msg.getName() != null) { - vo.setName(msg.getName()); - update = true; - } - if (msg.getDescription() != null) { - vo.setDescription(msg.getDescription()); - update = true; + VmNicSecurityGroupTo nicTo = cal.calculateVmNicSecurityGroupTO(); + for (SecurityGroupTo group : nicTo.groups) { + if (group.getSecurityGroupUuid().equals(sgUuid)) { + group.setActionCode(SecurityGroupTo.ACTION_CODE_DELETE_CHAIN); + } } - if (update) { - vo = dbf.updateAndRefresh(vo); + for (VmNicSecurityTO nic : nicTo.vmNics) { + nic.setSync(true); } - APIUpdateSecurityGroupEvent evt = new APIUpdateSecurityGroupEvent(msg.getId()); - evt.setInventory(SecurityGroupInventory.valueOf(vo)); - bus.publish(evt); + sdnBackend.updateSecurityGroup(nicTo, completion); } - @Transactional(readOnly = true) - private List getCandidateVmNic(String sgId, String accountUuid) { - List nicUuidsToInclude = acntMgr.getResourceUuidsCanAccessByAccount(accountUuid, VmNicVO.class); - if (nicUuidsToInclude != null && nicUuidsToInclude.isEmpty()) { - return new ArrayList(); + private void sdnRefreshSecurityGroup(SecurityGroupSdnBackend sdnBackend, String sgUuid,Completion completion) { + SecurityGroupVO groupVO = dbf.findByUuid(sgUuid, SecurityGroupVO.class); + if (groupVO.getState() == SecurityGroupState.Disabled) { + completion.success(); + return; } - String sql = "select ref.vmNicUuid from VmNicSecurityGroupRefVO ref where ref.securityGroupUuid = :sgUuid"; - TypedQuery nq = dbf.getEntityManager().createQuery(sql, String.class); - nq.setParameter("sgUuid", sgId); - List nicUuidsToExclued = nq.getResultList(); - - TypedQuery q; - if (nicUuidsToInclude == null) { - // accessed by an admin - if (nicUuidsToExclued.isEmpty()) { - sql = "select nic from VmNicVO nic, VmInstanceVO vm, SecurityGroupVO sg, SecurityGroupL3NetworkRefVO ref, UsedIpVO ip " + - "where nic.vmInstanceUuid = vm.uuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = ref.l3NetworkUuid and ref.securityGroupUuid = sg.uuid " + - " and sg.uuid = :sgUuid and vm.type = :vmType and vm.state in (:vmStates) group by nic.uuid"; - q = dbf.getEntityManager().createQuery(sql, VmNicVO.class); - } else { - sql = "select nic from VmNicVO nic, VmInstanceVO vm, SecurityGroupVO sg, SecurityGroupL3NetworkRefVO ref, UsedIpVO ip" + - " where nic.vmInstanceUuid = vm.uuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = ref.l3NetworkUuid and ref.securityGroupUuid = sg.uuid " + - " and sg.uuid = :sgUuid and vm.type = :vmType and vm.state in (:vmStates) and nic.uuid not in (:nicUuids) group by nic.uuid"; - q = dbf.getEntityManager().createQuery(sql, VmNicVO.class); - q.setParameter("nicUuids", nicUuidsToExclued); - } - } else { - // accessed by a normal account - if (nicUuidsToExclued.isEmpty()) { - sql = "select nic from VmNicVO nic, VmInstanceVO vm, SecurityGroupVO sg, SecurityGroupL3NetworkRefVO ref, UsedIpVO ip " + - " where nic.vmInstanceUuid = vm.uuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = ref.l3NetworkUuid and ref.securityGroupUuid = sg.uuid " + - " and sg.uuid = :sgUuid and vm.type = :vmType and vm.state in (:vmStates) and nic.uuid in (:iuuids) group by nic.uuid"; - q = dbf.getEntityManager().createQuery(sql, VmNicVO.class); - q.setParameter("iuuids", nicUuidsToInclude); - } else { - sql = "select nic from VmNicVO nic, VmInstanceVO vm, SecurityGroupVO sg, SecurityGroupL3NetworkRefVO ref, UsedIpVO ip " + - " where nic.vmInstanceUuid = vm.uuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = ref.l3NetworkUuid and ref.securityGroupUuid = sg.uuid " + - " and sg.uuid = :sgUuid and vm.type = :vmType and vm.state in (:vmStates) and nic.uuid not in (:nicUuids) and nic.uuid in (:iuuids) group by nic.uuid"; - q = dbf.getEntityManager().createQuery(sql, VmNicVO.class); - q.setParameter("nicUuids", nicUuidsToExclued); - q.setParameter("iuuids", nicUuidsToInclude); - } + List vmNicUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .eq(VmNicSecurityGroupRefVO_.securityGroupUuid, sgUuid) + .listValues(); + if (vmNicUuids.isEmpty()) { + completion.success(); + return; } + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = Collections.singletonList(sgUuid); + cal.vmNicUuids = vmNicUuids; + + VmNicSecurityGroupTo nicTo = cal.calculateVmNicSecurityGroupTO(); + //security group is not attached to vm + if (nicTo.getVmNics().isEmpty()) { + completion.success(); + return; + } - q.setParameter("sgUuid", sgId); - q.setParameter("vmType", VmInstanceConstant.USER_VM_TYPE); - q.setParameter("vmStates", list(VmInstanceState.Running, VmInstanceState.Stopped)); - return q.getResultList(); + sdnBackend.updateSecurityGroup(nicTo, completion); } - private void handle(APIGetCandidateVmNicForSecurityGroupMsg msg) { - APIGetCandidateVmNicForSecurityGroupReply reply = new APIGetCandidateVmNicForSecurityGroupReply(); - reply.setInventories(VmNicInventory.valueOf(getCandidateVmNic(msg.getSecurityGroupUuid(), msg.getSession().getAccountUuid()))); + private void handle(CreateSecurityGroupMsg msg) { + CreateSecurityGroupReply reply = new CreateSecurityGroupReply(); + SecurityGroupVO vo = new SecurityGroupVO(); + vo.setUuid(Platform.getUuid()); + vo.setName(msg.getName()); + vo.setDescription(msg.getDescription()); + vo.setState(SecurityGroupState.Enabled); + vo.setvSwitchType(msg.getvSwitchType()); + vo.setInternalId(dbf.generateSequenceNumber(SecurityGroupSequenceNumberVO.class)); + vo.setAccountUuid(msg.getAccountUuid()); + vo = dbf.persistAndRefresh(vo); + + createDefaultRule(vo.getUuid(), IPv6Constants.IPv4); + createDefaultRule(vo.getUuid(), IPv6Constants.IPv6); + + SecurityGroupSdnBackend sdnBackend = getSdnBackend(msg.getSdnControllerUuid()); + if (sdnBackend == null) { + reply.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.reply(msg, reply); + return; + } + + final SecurityGroupInventory inv = SecurityGroupInventory.valueOf(vo); + sdnBackend.createSecurityGroup(inv, new Completion(msg) { + @Override + public void success() { + reply.setInventory(SecurityGroupInventory.valueOf( + dbf.findByUuid(inv.getUuid(), SecurityGroupVO.class))); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(AddSecurityGroupRuleMsg msg) { + for (APIAddSecurityGroupRuleMsg.SecurityGroupRuleAO ao : msg.getRules()) { + if (ao.getAllowedCidr() == null) { + ao.setAllowedCidr(ao.getIpVersion() == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + } + if (ao.getStartPort() == null || ao.getEndPort() == null) { + ao.setStartPort(-1); + ao.setEndPort(-1); + } + if (!SecurityGroupConstant.WORLD_OPEN_CIDR.equals(ao.getAllowedCidr()) && !SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6.equals(ao.getAllowedCidr())) { + if (ao.getType().equals(SecurityGroupRuleType.Egress.toString())) { + ao.setDstIpRange(ao.getAllowedCidr()); + } else { + ao.setSrcIpRange(ao.getAllowedCidr()); + } + } + if (ao.getStartPort() != -1) { + if (ao.getStartPort().equals(ao.getEndPort())) { + ao.setDstPortRange(String.valueOf(ao.getStartPort())); + } else { + ao.setDstPortRange(String.format("%s-%s", ao.getStartPort(), ao.getEndPort())); + } + } + } + + AddSecurityGroupRuleReply reply = new AddSecurityGroupRuleReply(); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + doAddSecurityGroupRule(msg, new Completion(msg, chain) { + @Override + public void success() { + reply.setInventory(SecurityGroupInventory.valueOf(dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class))); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("add-security-group-%s-rule", msg.getSecurityGroupUuid()); + } + }); + } + + private void handle(SecurityGroupDeletionMsg msg) { + SecurityGroupDeletionReply reply = new SecurityGroupDeletionReply(); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + deleteSecurityGroup(msg.getUuid(), new Completion(msg, chain) { + @Override + public void success() { + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("delete-security-group-%s", msg.getUuid()); + } + }); + } + + private void handle(RemoveVmNicFromSecurityGroupMsg msg) { + RemoveVmNicFromSecurityGroupReply reply = new RemoveVmNicFromSecurityGroupReply(); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getVmNicSecurityGroupRefSyncThreadName(); + } + + @Override + public void run(SyncTaskChain chain) { + removeNicFromSecurityGroup(msg.getSecurityGroupUuid(), msg.getVmNicUuids(), new Completion(msg, chain) { + @Override + public void success() { + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + bus.reply(msg, reply); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("remove-vm-nic-from-security-group-%s", msg.getSecurityGroupUuid()); + } + }); + } + + private void refreshVmSecurityGroupRulesBySdn(Map> sdnNicUuidsMap, + RefreshSecurityGroupRulesOnVmMsg msg, Completion completion) { + if (msg.getOperation() != VmInstanceConstant.VmOperation.NewCreate + && msg.getOperation() != VmInstanceConstant.VmOperation.Destroy + && msg.getOperation() != VmInstanceConstant.VmOperation.AttachNic + && msg.getOperation() != VmInstanceConstant.VmOperation.DetachNic + && msg.getOperation() != VmInstanceConstant.VmOperation.ChangeNicNetwork) { + completion.success(); + return; + } + + new While<>(sdnNicUuidsMap.entrySet()).each((entry, wcomp) -> { + SecurityGroupSdnBackend backend = entry.getKey(); + List vmNicUuids = entry.getValue(); + if (vmNicUuids.isEmpty()) { + wcomp.done(); + return; + } + + vmNicUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids) + .listValues(); + if (vmNicUuids.isEmpty()) { + wcomp.done(); + return; + } + + if (msg.isDeleteAllRules()) { + List sgUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.securityGroupUuid) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids) + .listValues(); + SQL.New(VmNicSecurityGroupRefVO.class).in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids).delete(); + sdnRemoveSecurityGroupFromVmNic(backend, sgUuids,vmNicUuids, new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.addError(errorCode); + wcomp.allDone(); + } + }); + } else { + sdnRefreshVmNics(backend, vmNicUuids, new Completion(wcomp) { + @Override + public void success() { + wcomp.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + wcomp.addError(errorCode); + wcomp.allDone(); + } + }); + } + }).run(new WhileDoneCompletion(new NopeCompletion()) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList); + } else { + completion.success(); + } + } + }); + } + + private void refreshVmSecurityGroupRules(List nicUuids, RefreshSecurityGroupRulesOnVmMsg msg) { + nicUuids = nicUuids.stream().distinct().collect(Collectors.toList()); + Collection htos; + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = nicUuids; + cal.vmStates = asList(VmInstanceState.values()); + cal.isDelete = msg.isDeleteAllRules(); + htos = cal.calculate(); + + applyRules(htos); + + if (msg.getSgUuids() != null && !msg.getSgUuids().isEmpty()) { + Q.New(SecurityGroupVO.class) + .select(SecurityGroupVO_.uuid) + .eq(SecurityGroupVO_.vSwitchType, L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE) + .in(SecurityGroupVO_.uuid, msg.getSgUuids()) + .eq(SecurityGroupVO_.state, SecurityGroupState.Enabled) + .listValues().forEach(sgUuid -> { + HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember((String) sgUuid); + if (!groupMemberTO.getHostUuids().isEmpty()) { + updateGroupMembers(groupMemberTO); + } + }); + } + + if (htos.isEmpty()) { + checkDefaultRulesOnHost(msg.getHostUuid()); + } + + logger.debug(String.format("refreshed security group rule for vm[uuid:%s] vNicuuids[%s]", + msg.getVmInstanceUuid(), Joiner.on(",").join(nicUuids))); + } + + private void handle(RefreshSecurityGroupRulesOnVmMsg msg) { + RefreshSecurityGroupRulesOnVmReply reply = new RefreshSecurityGroupRulesOnVmReply(); + List nicUuids = msg.getNicUuids(); + if (nicUuids == null || nicUuids.isEmpty()) { + SimpleQuery q = dbf.createQuery(VmNicSecurityGroupRefVO.class); + q.select(VmNicSecurityGroupRefVO_.vmNicUuid); + q.add(VmNicSecurityGroupRefVO_.vmInstanceUuid, Op.EQ, msg.getVmInstanceUuid()); + nicUuids = q.listValue(); + } + if (msg.getHostUuid() == null ||msg.getHostUuid().isEmpty()) { + String HostUuid = Q.New(VmInstanceVO.class) + .eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()) + .select(VmInstanceVO_.hostUuid) + .findValue(); + + msg.setHostUuid(HostUuid); + } + + if (nicUuids.isEmpty()) { + checkDefaultRulesOnHost(msg.getHostUuid()); + logger.debug(String.format("no nic of vm[uuid:%s] needs to refresh security group rule", msg.getVmInstanceUuid())); + bus.reply(msg, reply); + return; + } + + List otherNicUuids = new ArrayList<>(); + Map> sdnNicUuidsMap = new HashMap<>(); + List vmNicVOS = Q.New(VmNicVO.class).in(VmNicVO_.uuid, nicUuids).list(); + for (VmNicVO nicvo : vmNicVOS) { + SecurityGroupSdnBackend backend = getSdnBackendFroL3Uuid(nicvo.getL3NetworkUuid()); + if (backend == null) { + otherNicUuids.add(nicvo.getUuid()); + } else { + sdnNicUuidsMap.computeIfAbsent(backend, k -> new ArrayList<>()); + sdnNicUuidsMap.get(backend).add(nicvo.getUuid()); + } + } + + refreshVmSecurityGroupRulesBySdn(sdnNicUuidsMap, msg, new Completion(new NopeCompletion()) { + @Override + public void success() { + refreshVmSecurityGroupRules(otherNicUuids, msg); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void createFailureHostTask(String huuid) { + SecurityGroupFailureHostVO fvo = new SecurityGroupFailureHostVO(); + fvo.setHostUuid(huuid); + dbf.persist(fvo); + } + + private void handle(RefreshSecurityGroupRulesOnHostMsg msg) { + // this message is sent after host reconnected, sdn controller will not handle it + RuleCalculator cal = new RuleCalculator(); + cal.hostUuids = Collections.singletonList(msg.getHostUuid()); + // refreshing may happen when host is reconnecting; at that time VMs' states are Unknown + cal.vmStates = asList(VmInstanceState.Unknown, VmInstanceState.Running); + List htos = cal.calculate(); + for (HostRuleTO hto : htos) { + hto.setRefreshHost(true); + } + logger.debug(String.format("required to refresh rules on host[uuid:%s]", msg.getHostUuid())); + applyRules(htos); + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APICreateSecurityGroupMsg) { + handle((APICreateSecurityGroupMsg) msg); + } else if (msg instanceof APIAddSecurityGroupRuleMsg) { + handle((APIAddSecurityGroupRuleMsg) msg); + } else if (msg instanceof APIAddVmNicToSecurityGroupMsg) { + handle((APIAddVmNicToSecurityGroupMsg) msg); + } else if (msg instanceof APIDeleteSecurityGroupRuleMsg) { + handle((APIDeleteSecurityGroupRuleMsg) msg); + } else if (msg instanceof APIDeleteSecurityGroupMsg) { + handle((APIDeleteSecurityGroupMsg) msg); + } else if (msg instanceof APIDeleteVmNicFromSecurityGroupMsg) { + handle((APIDeleteVmNicFromSecurityGroupMsg) msg); + } else if (msg instanceof APIAttachSecurityGroupToL3NetworkMsg) { + handle((APIAttachSecurityGroupToL3NetworkMsg) msg); + } else if (msg instanceof APIChangeSecurityGroupStateMsg) { + handle((APIChangeSecurityGroupStateMsg) msg); + } else if (msg instanceof APIDetachSecurityGroupFromL3NetworkMsg) { + handle((APIDetachSecurityGroupFromL3NetworkMsg) msg); + } else if (msg instanceof APIGetCandidateVmNicForSecurityGroupMsg) { + handle((APIGetCandidateVmNicForSecurityGroupMsg) msg); + } else if (msg instanceof APIUpdateSecurityGroupMsg) { + handle((APIUpdateSecurityGroupMsg) msg); + } else if (msg instanceof APIChangeSecurityGroupRuleMsg) { + handle((APIChangeSecurityGroupRuleMsg) msg); + } else if (msg instanceof APIUpdateSecurityGroupRulePriorityMsg) { + handle((APIUpdateSecurityGroupRulePriorityMsg) msg); + } else if (msg instanceof APIChangeVmNicSecurityPolicyMsg) { + handle((APIChangeVmNicSecurityPolicyMsg) msg); + } else if (msg instanceof APIChangeSecurityGroupRuleStateMsg) { + handle((APIChangeSecurityGroupRuleStateMsg) msg); + } else if (msg instanceof APISetVmNicSecurityGroupMsg) { + handle((APISetVmNicSecurityGroupMsg) msg); + } else if (msg instanceof APIValidateSecurityGroupRuleMsg) { + handle((APIValidateSecurityGroupRuleMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIValidateSecurityGroupRuleMsg msg) { + APIValidateSecurityGroupRuleReply reply = new APIValidateSecurityGroupRuleReply(); + reply.setAvailable(true); + reply.setCode(SecurityGroupErrors.RULE_CHECK_OK.toString()); + bus.reply(msg, reply); + } + + + private void setVmNicSecurityGroup(APISetVmNicSecurityGroupMsg msg, Completion completion) { + VmNicVO nic = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); + SecurityGroupSdnBackend backend = getSdnBackendFroL3Uuid(nic.getL3NetworkUuid()); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "set-vm-nic-security-group-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + List toCreate = new ArrayList<>(); + List toDelete = new ArrayList<>(); + List toUpdate = new ArrayList<>(); + List sgUuids = new ArrayList<>(); + Map refMap = new HashMap<>(); + List refs = Q.New(VmNicSecurityGroupRefVO.class).eq(VmNicSecurityGroupRefVO_.vmNicUuid, msg.getVmNicUuid()).list(); + refs.forEach(ref -> { + refMap.put(ref.getSecurityGroupUuid(), ref); + }); + + for (VmNicSecurityGroupRefAO ao : msg.getRefs()) { + if (!refMap.containsKey(ao.getSecurityGroupUuid())) { + // to create + VmNicSecurityGroupRefVO vo = new VmNicSecurityGroupRefVO(); + vo.setUuid(Platform.getUuid()); + vo.setVmNicUuid(nic.getUuid()); + vo.setPriority(ao.getPriority()); + vo.setVmInstanceUuid(nic.getVmInstanceUuid()); + vo.setSecurityGroupUuid(ao.getSecurityGroupUuid()); + toCreate.add(vo); + sgUuids.add(ao.getSecurityGroupUuid()); + } else { + // to update + VmNicSecurityGroupRefVO vo = refMap.get(ao.getSecurityGroupUuid()); + vo.setPriority(ao.getPriority()); + toUpdate.add(vo); + refMap.remove(ao.getSecurityGroupUuid()); + } + } + + // to delete + toDelete.addAll(refMap.values()); + refMap.values().forEach(ref -> sgUuids.add(ref.getSecurityGroupUuid())); + + if (!toCreate.isEmpty()) { + dbf.persistCollection(toCreate); + } + if (!toDelete.isEmpty()) { + dbf.removeCollection(toDelete, VmNicSecurityGroupRefVO.class); + } + if (!toUpdate.isEmpty()) { + dbf.updateCollection(toUpdate); + } + + if (!toCreate.isEmpty() || !toUpdate.isEmpty()) { + if (!Q.New(VmNicSecurityPolicyVO.class).eq(VmNicSecurityPolicyVO_.vmNicUuid, msg.getVmNicUuid()).isExists()) { + VmNicSecurityPolicyVO vo = new VmNicSecurityPolicyVO(); + vo.setUuid(Platform.getUuid()); + vo.setVmNicUuid(msg.getVmNicUuid()); + vo.setIngressPolicy(VmNicSecurityPolicy.DENY.toString()); + vo.setEgressPolicy(VmNicSecurityPolicy.ALLOW.toString()); + dbf.persist(vo); + } + } + + data.put(SecurityGroupConstant.Param.SECURITY_GROUP_UUIDS, sgUuids); + data.put(SecurityGroupConstant.Param.SECURITY_GROUP_REFS, toDelete); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public boolean skip(Map data) { + return backend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = asList(msg.getVmNicUuid()); + List rhtos = cal.calculate(); + applyRules(rhtos); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "update-group-members"; + + @Override + public boolean skip(Map data) { + return backend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + List sgUuids = (List)data.get(SecurityGroupConstant.Param.SECURITY_GROUP_UUIDS); + for (String sgUuid : sgUuids) { + RuleCalculator cal = new RuleCalculator(); + HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(sgUuid); + if(!groupMemberTO.getHostUuids().isEmpty()){ + if (Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).eq(SecurityGroupVO_.state, SecurityGroupState.Disabled).isExists()) { + groupMemberTO.getGroupMembersTO().setActionCode(ACTION_CODE_DELETE_GROUP); + } + updateGroupMembers(groupMemberTO); + } + } + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "update-sdn-controller"; + + @Override + public boolean skip(Map data) { + return backend == null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + List toDelete = (List) data.get(SecurityGroupConstant.Param.SECURITY_GROUP_REFS); + List sgUuids = toDelete.stream().map(VmNicSecurityGroupRefVO::getSecurityGroupUuid).distinct().collect(Collectors.toList()); + sdnRemoveSecurityGroupFromVmNic(backend, sgUuids, Collections.singletonList(msg.getVmNicUuid()), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); + } + + private void handle(APISetVmNicSecurityGroupMsg msg) { + APISetVmNicSecurityGroupEvent evt = new APISetVmNicSecurityGroupEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getVmNicSecurityGroupRefSyncThreadName(); + } + + @Override + public void run(SyncTaskChain chain) { + setVmNicSecurityGroup(msg, new Completion(msg, chain) { + @Override + public void success() { + List refs = Q.New(VmNicSecurityGroupRefVO.class).eq(VmNicSecurityGroupRefVO_.vmNicUuid, msg.getVmNicUuid()).list(); + evt.setInventory(VmNicSecurityGroupRefInventory.valueOf(refs)); + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("set-vm-nic-%s-security-group", msg.getVmNicUuid()); + } + }); + } + + private void doChangeSecurityGroupRuleState(APIChangeSecurityGroupRuleStateMsg msg, Completion completion) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(msg.getSecurityGroupUuid()); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.setName(String.format("change-security-group-%s-rule-state", msg.getSecurityGroupUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "change-security-group-rule-state-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + + List rvos = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getSecurityGroupUuid()) + .in(SecurityGroupRuleVO_.uuid, msg.getRuleUuids()) + .list(); + + rvos.forEach(rvo -> { + rvo.setState(SecurityGroupRuleState.valueOf(msg.getState())); + }); + dbf.updateCollection(rvos); + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = asList(msg.getSecurityGroupUuid()); + List htos = cal.calculate(); + applyRules(htos); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnBackend == null) { + trigger.next(); + return; + } + + sdnRefreshSecurityGroup(sdnBackend, msg.getSecurityGroupUuid(), + new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); + } + + private void handle(APIChangeSecurityGroupRuleStateMsg msg) { + APIChangeSecurityGroupRuleStateEvent evt = new APIChangeSecurityGroupRuleStateEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + doChangeSecurityGroupRuleState(msg, new Completion(msg, chain) { + @Override + public void success() { + SecurityGroupVO vo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + evt.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("change-security-group-%s-rule-state", msg.getSecurityGroupUuid()); + } + }); + } + + private void handle(APIChangeVmNicSecurityPolicyMsg msg) { + APIChangeVmNicSecurityPolicyEvent evt = new APIChangeVmNicSecurityPolicyEvent(msg.getId()); + VmNicSecurityPolicyVO pvo = Q.New(VmNicSecurityPolicyVO.class).eq(VmNicSecurityPolicyVO_.vmNicUuid, msg.getVmNicUuid()).find(); + + if (msg.getIngressPolicy() == null && msg.getEgressPolicy() == null) { + logger.debug(String.format("vm nic[uuid:%s] security policy not change", msg.getVmNicUuid())); + evt.setInventory(VmNicSecurityPolicyInventory.valueOf(pvo)); + bus.publish(evt); + + return; + } + + + if (msg.getIngressPolicy() != null) { + pvo.setIngressPolicy(msg.getIngressPolicy()); + } + + if (msg.getEgressPolicy() != null) { + pvo.setEgressPolicy(msg.getEgressPolicy()); + } + + pvo = dbf.updateAndRefresh(pvo); + VmNicSecurityPolicyInventory pinv = VmNicSecurityPolicyInventory.valueOf(pvo); + VmNicVO nicVO = dbf.findByUuid(msg.getVmNicUuid(), VmNicVO.class); + SecurityGroupSdnBackend backend = getSdnBackendFroL3Uuid(nicVO.getL3NetworkUuid()); + if (backend == null) { + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = asList(msg.getVmNicUuid()); + List htos = cal.calculate(); + applyRules(htos); + + evt.setInventory(pinv); + bus.publish(evt); + return; + } + + sdnRefreshVmNicsDefaultRule(backend, Collections.singletonList(msg.getVmNicUuid()), new Completion(msg) { + @Override + public void success() { + evt.setInventory(pinv); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); + } + + private void doUpdateSecurityGroupRulePriority(APIUpdateSecurityGroupRulePriorityMsg msg, Completion completion) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(msg.getSecurityGroupUuid()); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.setName(String.format("update-security-group-%s-rule-priority", msg.getSecurityGroupUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "update-security-group-rule-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + + List toUpdate = new ArrayList(); + + List rvos = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getSecurityGroupUuid()) + .eq(SecurityGroupRuleVO_.type, SecurityGroupRuleType.valueOf(msg.getType())) + .notEq(SecurityGroupRuleVO_.priority, SecurityGroupConstant.DEFAULT_RULE_PRIORITY) + .list(); + for (SecurityGroupRulePriorityAO ao : msg.getRules()) { + SecurityGroupRuleVO vo = rvos.stream().filter(r -> r.getUuid().equals(ao.getRuleUuid())).findFirst().orElse(null); + if (vo == null) { + throw new OperationFailureException(operr("failed to chenge rule[uuid:%s] priority, beacuse it's not found", ao.getRuleUuid())); + } + if (ao.getPriority() != vo.getPriority()) { + vo.setPriority(ao.getPriority()); + toUpdate.add(vo); + } + } + + dbf.updateCollection(toUpdate); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = asList(msg.getSecurityGroupUuid()); + cal.vmStates = asList(VmInstanceState.Running); + List rhtos = cal.calculate(); + applyRules(rhtos); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnBackend == null) { + trigger.next(); + return; + } + + sdnRefreshSecurityGroup(sdnBackend, msg.getSecurityGroupUuid(), + new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); + } + + private void handle(APIUpdateSecurityGroupRulePriorityMsg msg) { + APIUpdateSecurityGroupRulePriorityEvent evt = new APIUpdateSecurityGroupRulePriorityEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + doUpdateSecurityGroupRulePriority(msg, new Completion(msg, chain) { + @Override + public void success() { + SecurityGroupVO vo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + evt.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("update-security-group-%s-%s-rule-priority", msg.getSecurityGroupUuid(), msg.getType()); + } + }); + } + + private void handle(APIChangeSecurityGroupRuleMsg msg) { + APIChangeSecurityGroupRuleEvent evt = new APIChangeSecurityGroupRuleEvent(msg.getId()); + + String sgUuid = Q.New(SecurityGroupRuleVO.class).select(SecurityGroupRuleVO_.securityGroupUuid).eq(SecurityGroupRuleVO_.uuid, msg.getUuid()).findValue(); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(sgUuid); + } + + @Override + public void run(SyncTaskChain chain) { + doChangeSecurityGroupRule(msg, sgUuid, new Completion(msg, chain) { + @Override + public void success() { + SecurityGroupRuleVO vo = dbf.findByUuid(msg.getUuid(), SecurityGroupRuleVO.class); + evt.setInventory(SecurityGroupRuleInventory.valueOf(vo)); + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("change-security-group-%s-rule-%s", sgUuid, msg.getUuid()); + } + }); + } + + private void doChangeSecurityGroupRule(APIChangeSecurityGroupRuleMsg msg, String sgUuid, Completion completion) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(sgUuid); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "change-security-group-rule-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + SecurityGroupRuleVO vo = dbf.findByUuid(msg.getUuid(), SecurityGroupRuleVO.class); + vo.setDescription(msg.getDescription()); + vo.setState(SecurityGroupRuleState.valueOf(msg.getState())); + vo.setAction(msg.getAction()); + vo.setProtocol(SecurityGroupRuleProtocolType.valueOf(msg.getProtocol())); + vo.setRemoteSecurityGroupUuid(msg.getRemoteSecurityGroupUuid()); + vo.setSrcIpRange(msg.getSrcIpRange()); + vo.setDstIpRange(msg.getDstIpRange()); + vo.setDstPortRange(msg.getDstPortRange()); + + if (StringUtils.isNotEmpty(msg.getSrcIpRange()) || StringUtils.isNotEmpty(msg.getDstIpRange()) || StringUtils.isNotEmpty(msg.getRemoteSecurityGroupUuid())) { + vo.setAllowedCidr(vo.getIpVersion() == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + } + if (StringUtils.isNotEmpty(msg.getDstPortRange())) { + vo.setStartPort(-1); + vo.setEndPort(-1); + } + + if (msg.getPriority() != null && msg.getPriority() != vo.getPriority()) { + List others = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, vo.getSecurityGroupUuid()) + .eq(SecurityGroupRuleVO_.type, vo.getType()) + .notEq(SecurityGroupRuleVO_.uuid, vo.getUuid()) + .notEq(SecurityGroupRuleVO_.priority, SecurityGroupConstant.DEFAULT_RULE_PRIORITY) + .list(); + final int finalPriority = msg.getPriority() == -1 ? others.size() + 1 : msg.getPriority(); + + if (vo.getPriority() > finalPriority) { + List toUpdate = others.stream().filter(r -> r.getPriority() >= finalPriority && r.getPriority() < vo.getPriority()).collect(Collectors.toList()); + + toUpdate.stream().forEach(r -> r.setPriority(r.getPriority() + 1)); + dbf.updateCollection(toUpdate); + } else { + List toUpdate = others.stream().filter(r -> r.getPriority() <= finalPriority && r.getPriority() > vo.getPriority()).collect(Collectors.toList()); + + toUpdate.stream().forEach(r -> r.setPriority(r.getPriority() - 1)); + dbf.updateCollection(toUpdate); + } + + vo.setPriority(finalPriority); + } + + dbf.update(vo); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = asList(sgUuid); + cal.vmStates = asList(VmInstanceState.Running); + List htos = cal.calculate(); + applyRules(htos); + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnBackend == null) { + trigger.next(); + return; + } + + sdnRefreshSecurityGroup(sdnBackend, sgUuid, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); + } + + private void handle(APIUpdateSecurityGroupMsg msg) { + boolean update = false; + SecurityGroupVO vo = dbf.findByUuid(msg.getUuid(), SecurityGroupVO.class); + if (msg.getName() != null) { + vo.setName(msg.getName()); + update = true; + } + if (msg.getDescription() != null) { + vo.setDescription(msg.getDescription()); + update = true; + } + if (update) { + vo = dbf.updateAndRefresh(vo); + } + APIUpdateSecurityGroupEvent evt = new APIUpdateSecurityGroupEvent(msg.getId()); + evt.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.publish(evt); + } + + @Transactional(readOnly = true) + private List getCandidateVmNic(String sgId, String accountUuid) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(sgId); + if (sdnBackend != null) { + return sdnBackend.getCandidateVmNic(sgId, accountUuid); + } + + List nicUuidsToInclude = acntMgr.getResourceUuidsCanAccessByAccount(accountUuid, VmNicVO.class); + if (nicUuidsToInclude != null && nicUuidsToInclude.isEmpty()) { + return new ArrayList(); + } + + List nicUuidsToExclued = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .eq(VmNicSecurityGroupRefVO_.securityGroupUuid, sgId) + .listValues(); + + List candidateNics = new ArrayList<>(); + List allNics = SQL.New("select nic from VmNicVO nic, VmInstanceVO vm" + + " where nic.vmInstanceUuid = vm.uuid" + + " and nic.type = :nicType " + + " and vm.type = :vmType" + + " and vm.state in (:vmStates)", VmNicVO.class) + .param("nicType", VmInstanceConstant.VIRTUAL_NIC_TYPE) + .param("vmType", VmInstanceConstant.USER_VM_TYPE) + .param("vmStates", list(VmInstanceState.Running, VmInstanceState.Stopped)) + .list(); + if (allNics.isEmpty()) { + return allNics; + } + + if (!nicUuidsToExclued.isEmpty()) { + if (nicUuidsToInclude != null && !nicUuidsToInclude.isEmpty()) { + // accessed by a normal account + allNics.stream().forEach(nic -> { + if (!nicUuidsToExclued.contains(nic.getUuid()) && nicUuidsToInclude.contains(nic.getUuid())) { + candidateNics.add(nic); + } + }); + } else { + // accessed by an admin + allNics.stream().forEach(nic -> { + if (!nicUuidsToExclued.contains(nic.getUuid())) { + candidateNics.add(nic); + } + }); + } + } else { + if (nicUuidsToInclude != null && !nicUuidsToInclude.isEmpty()) { + // accessed by a normal account + allNics.stream().forEach(nic -> { + if (nicUuidsToInclude.contains(nic.getUuid())) { + candidateNics.add(nic); + } + }); + } else { + // accessed by an admin + return allNics; + } + } + + return candidateNics; + } + + private void handle(APIGetCandidateVmNicForSecurityGroupMsg msg) { + APIGetCandidateVmNicForSecurityGroupReply reply = new APIGetCandidateVmNicForSecurityGroupReply(); + reply.setInventories(VmNicInventory.valueOf(getCandidateVmNic(msg.getSecurityGroupUuid(), msg.getSession().getAccountUuid()))); bus.reply(msg, reply); } @Transactional private void detachSecurityGroupFromL3Network(String sgUuid, String l3Uuid) { - String sql = "select distinct ref.uuid from VmNicSecurityGroupRefVO ref, VmNicVO nic, UsedIpVO ip, SecurityGroupVO sg" + - " where nic.uuid = ref.vmNicUuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = :l3Uuid and ref.securityGroupUuid = :sgUuid"; + String sql = "select distinct ref.uuid from VmNicSecurityGroupRefVO ref, VmNicVO nic, SecurityGroupVO sg" + + " where nic.uuid = ref.vmNicUuid and nic.l3NetworkUuid = :l3Uuid and ref.securityGroupUuid = :sgUuid"; TypedQuery tq = dbf.getEntityManager().createQuery(sql, String.class); tq.setParameter("l3Uuid", l3Uuid); tq.setParameter("sgUuid", sgUuid); @@ -900,371 +1930,1057 @@ private void detachSecurityGroupFromL3Network(String sgUuid, String l3Uuid) { @Transactional(readOnly = true) private List getVmNicUuidsToRemoveForDetachSecurityGroup(String sgUuid, String l3Uuid) { - String sql = "select distinct nic.uuid from VmNicVO nic, VmNicSecurityGroupRefVO ref, UsedIpVO ip, SecurityGroupVO sg" + - " where ref.vmNicUuid = nic.uuid and nic.uuid = ip.vmNicUuid and ip.l3NetworkUuid = :l3Uuid and ref.securityGroupUuid = :sgUuid"; + String sql = "select distinct nic.uuid from VmNicVO nic, VmNicSecurityGroupRefVO ref, SecurityGroupVO sg" + + " where ref.vmNicUuid = nic.uuid and nic.l3NetworkUuid = :l3Uuid and ref.securityGroupUuid = :sgUuid"; TypedQuery tq = dbf.getEntityManager().createQuery(sql, String.class); tq.setParameter("l3Uuid", l3Uuid); tq.setParameter("sgUuid", sgUuid); return tq.getResultList(); } - private void handle(APIDetachSecurityGroupFromL3NetworkMsg msg) { - List vmNicUuids = getVmNicUuidsToRemoveForDetachSecurityGroup(msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); + private void handle(APIDetachSecurityGroupFromL3NetworkMsg msg) { + APIDetachSecurityGroupFromL3NetworkEvent evt = new APIDetachSecurityGroupFromL3NetworkEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + List vmNicUuids = getVmNicUuidsToRemoveForDetachSecurityGroup(msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); + if (!vmNicUuids.isEmpty()) { + RemoveVmNicFromSecurityGroupMsg rmsg = new RemoveVmNicFromSecurityGroupMsg(); + rmsg.setSecurityGroupUuid(msg.getSecurityGroupUuid()); + rmsg.setVmNicUuids(vmNicUuids); + bus.makeTargetServiceIdByResourceUuid(rmsg, SecurityGroupConstant.SERVICE_ID, msg.getSecurityGroupUuid()); + + bus.send(rmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + } + + detachSecurityGroupFromL3Network(msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); + SecurityGroupVO vo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + evt.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.publish(evt); + chain.next(); + } + }); + } else { + detachSecurityGroupFromL3Network(msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); + SecurityGroupVO vo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + evt.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.publish(evt); + chain.next(); + } + } + + @Override + public String getName() { + return String.format("detach-security-group-%s-from-l3Network-%s", msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); + } + }); + } + + private void handle(APIChangeSecurityGroupStateMsg msg) { + APIChangeSecurityGroupStateEvent evt = new APIChangeSecurityGroupStateEvent(msg.getId()); + SecurityGroupStateEvent sevt = SecurityGroupStateEvent.valueOf(msg.getStateEvent()); + SecurityGroupVO vo = dbf.findByUuid(msg.getUuid(), SecurityGroupVO.class); + SecurityGroupState oldState = vo.getState(); + SecurityGroupState sgState = SecurityGroupStateEvent.enable.equals(sevt) ? SecurityGroupState.Enabled : SecurityGroupState.Disabled; + + if (oldState == sgState) { + evt.setInventory(SecurityGroupInventory.valueOf(vo)); + bus.publish(evt); + return; + } + + vo.setState(sgState); + vo = dbf.updateAndRefresh(vo); + + final SecurityGroupVO finalVO = vo; + SecurityGroupSdnBackend sdnBackend = getSdnBackend(msg.getUuid()); + if (sdnBackend != null) { + List vmNicUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .eq(VmNicSecurityGroupRefVO_.securityGroupUuid, msg.getUuid()) + .listValues(); + if (vmNicUuids.isEmpty()) { + evt.setInventory(SecurityGroupInventory.valueOf(finalVO)); + bus.publish(evt); + return; + } + + List sgStates = new ArrayList<>(); + sgStates.add(SecurityGroupState.Enabled); + if (sgState == SecurityGroupState.Disabled) { + sgStates.add(SecurityGroupState.Disabled); + } + sdnRefreshVmNics(sdnBackend, vmNicUuids, new Completion(msg) { + @Override + public void success() { + evt.setInventory(SecurityGroupInventory.valueOf(finalVO)); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + finalVO.setState(oldState); + dbf.persist(finalVO); + evt.setError(errorCode); + bus.publish(evt); + } + }); + return; + } + + List sgUuids = Q.New(SecurityGroupRuleVO.class).select(SecurityGroupRuleVO_.securityGroupUuid) + .eq(SecurityGroupRuleVO_.remoteSecurityGroupUuid, msg.getUuid()).listValues(); + sgUuids.add(msg.getUuid()); + sgUuids = sgUuids.stream().distinct().collect(Collectors.toList()); + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = sgUuids; + cal.vmStates = asList(VmInstanceState.Running); + List htos = cal.calculate(); + applyRules(htos); - if (!vmNicUuids.isEmpty()) { - removeNicFromSecurityGroup(msg.getSecurityGroupUuid(), vmNicUuids); + HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(msg.getUuid()); + if (!groupMemberTO.getHostUuids().isEmpty()){ + if (!SecurityGroupStateEvent.enable.equals(sevt)) { + groupMemberTO.getGroupMembersTO().setActionCode(ACTION_CODE_DELETE_GROUP); + } + updateGroupMembers(groupMemberTO); } - detachSecurityGroupFromL3Network(msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); - - APIDetachSecurityGroupFromL3NetworkEvent evt = new APIDetachSecurityGroupFromL3NetworkEvent(msg.getId()); - SecurityGroupVO vo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); evt.setInventory(SecurityGroupInventory.valueOf(vo)); bus.publish(evt); } - private void handle(APIChangeSecurityGroupStateMsg msg) { - SecurityGroupStateEvent sevt = SecurityGroupStateEvent.valueOf(msg.getStateEvent()); - SecurityGroupVO vo = dbf.findByUuid(msg.getUuid(), SecurityGroupVO.class); - if (sevt == SecurityGroupStateEvent.enable) { - vo.setState(SecurityGroupState.Enabled); - List rvos = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getUuid()).list(); - for (SecurityGroupRuleVO rvo : rvos) { - rvo.setState(SecurityGroupRuleState.Enabled); + private void handle(APIAttachSecurityGroupToL3NetworkMsg msg) { + APIAttachSecurityGroupToL3NetworkEvent evt = new APIAttachSecurityGroupToL3NetworkEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); } - dbf.updateCollection(rvos); - vo = dbf.updateAndRefresh(vo); - List sgUuids = Q.New(SecurityGroupRuleVO.class).select(SecurityGroupRuleVO_.securityGroupUuid).eq(SecurityGroupRuleVO_.remoteSecurityGroupUuid, msg.getUuid()).listValues(); - sgUuids.add(msg.getUuid()); - RuleCalculator cal = new RuleCalculator(); - cal.securityGroupUuids = sgUuids; - cal.vmStates = asList(VmInstanceState.Running); - List htos = cal.calculate(); + @Override + public void run(SyncTaskChain chain) { + SimpleQuery q = dbf.createQuery(SecurityGroupL3NetworkRefVO.class); + q.add(SecurityGroupL3NetworkRefVO_.l3NetworkUuid, Op.EQ, msg.getL3NetworkUuid()); + q.add(SecurityGroupL3NetworkRefVO_.securityGroupUuid, Op.EQ, msg.getSecurityGroupUuid()); + SecurityGroupL3NetworkRefVO ref = q.find(); + if (ref == null) { + ref = new SecurityGroupL3NetworkRefVO(); + ref.setUuid(Platform.getUuid()); + ref.setL3NetworkUuid(msg.getL3NetworkUuid()); + ref.setSecurityGroupUuid(msg.getSecurityGroupUuid()); + dbf.persist(ref); + } - applyRules(htos); - HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(msg.getUuid()); - if (!groupMemberTO.getHostUuids().isEmpty()) { - updateGroupMembers(groupMemberTO); + SecurityGroupVO sgvo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + SecurityGroupInventory sginv = SecurityGroupInventory.valueOf(sgvo); + evt.setInventory(sginv); + bus.publish(evt); + chain.next(); } - } else { - List rvos = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getUuid()).list(); - for (SecurityGroupRuleVO rvo : rvos) { - rvo.setState(SecurityGroupRuleState.Disabled); + + @Override + public String getName() { + return String.format("attach-security-group-%s-to-l3Network-%s", msg.getSecurityGroupUuid(), msg.getL3NetworkUuid()); } - dbf.updateCollection(rvos); + }); + } - vo.setState(SecurityGroupState.Disabled); - vo = dbf.updateAndRefresh(vo); + private void removeNicFromSecurityGroup(String sgUuid, List vmNicUuids, Completion completion) { + SecurityGroupSdnBackend backend = getSdnBackend(sgUuid); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.setName( String.format("remove-vm-nic-from-security-group-%s", sgUuid)); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "remove-nic-from-security-group-in-db"; - disableSecurityGroup(msg.getUuid()); - } + @Override + public void run(FlowTrigger trigger, Map data) { + if (vmNicUuids.isEmpty()) { + trigger.next(); + return; + } - APIChangeSecurityGroupStateEvent evt = new APIChangeSecurityGroupStateEvent(msg.getId()); - evt.setInventory(SecurityGroupInventory.valueOf(vo)); - bus.publish(evt); - } + List refs = Q.New(VmNicSecurityGroupRefVO.class).in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids).list(); + List toRemove = refs.stream().filter(ref -> ref.getSecurityGroupUuid().equals(sgUuid)).collect(Collectors.toList()); + dbf.removeCollection(toRemove, VmNicSecurityGroupRefVO.class); + refs.removeAll(toRemove); + + for (String nicUuid : vmNicUuids) { + List toUpdate = refs.stream().filter(ref -> ref.getVmNicUuid().equals(nicUuid)).sorted(Comparator.comparingInt(VmNicSecurityGroupRefVO::getPriority)).collect(Collectors.toList()); + if (!toUpdate.isEmpty()) { + toUpdate.stream().forEach(ref ->{ + ref.setPriority(toUpdate.indexOf(ref) + 1); + }); + dbf.updateCollection(toUpdate); + } + } - private void handle(APIAttachSecurityGroupToL3NetworkMsg msg) { - APIAttachSecurityGroupToL3NetworkEvent evt = new APIAttachSecurityGroupToL3NetworkEvent(msg.getId()); - SimpleQuery q = dbf.createQuery(SecurityGroupL3NetworkRefVO.class); - q.add(SecurityGroupL3NetworkRefVO_.l3NetworkUuid, Op.EQ, msg.getL3NetworkUuid()); - q.add(SecurityGroupL3NetworkRefVO_.securityGroupUuid, Op.EQ, msg.getSecurityGroupUuid()); - SecurityGroupL3NetworkRefVO ref = q.find(); - if (ref == null) { - ref = new SecurityGroupL3NetworkRefVO(); - ref.setUuid(Platform.getUuid()); - ref.setL3NetworkUuid(msg.getL3NetworkUuid()); - ref.setSecurityGroupUuid(msg.getSecurityGroupUuid()); - dbf.persist(ref); - } - SecurityGroupVO sgvo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); - SecurityGroupInventory sginv = SecurityGroupInventory.valueOf(sgvo); - evt.setInventory(sginv); - bus.publish(evt); - } + trigger.next(); + } + }); - private void removeNicFromSecurityGroup(String sgUuid, List vmNicUuids) { - SimpleQuery q = dbf.createQuery(VmNicSecurityGroupRefVO.class); - q.add(VmNicSecurityGroupRefVO_.securityGroupUuid, Op.EQ, sgUuid); - q.add(VmNicSecurityGroupRefVO_.vmNicUuid, Op.IN, vmNicUuids); - List refVOs = q.list(); + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; - dbf.removeCollection(refVOs, VmNicSecurityGroupRefVO.class); + @Override + public boolean skip(Map data) { + return backend != null; + } - SecurityGroupVO sgvo = dbf.findByUuid(sgUuid, SecurityGroupVO.class); - if (SecurityGroupState.Disabled == sgvo.getState()) { - return; - } + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = vmNicUuids; + List htos = cal.calculate(); + applyRules(htos); - // nics may be in other security group - RuleCalculator cal = new RuleCalculator(); - cal.vmNicUuids = vmNicUuids; - List htos1 = cal.calculate(); + trigger.next(); + } + }); - // create deleting chain action for nics no longer in any security group - List nicUuidsIn = SQL.New("select ref.vmNicUuid from VmNicSecurityGroupRefVO ref, SecurityGroupVO sg" + - " where ref.securityGroupUuid = sg.uuid and sg.state = :sgState", String.class) - .param("sgState", SecurityGroupState.Enabled).list(); - List nicsUuidsCopy = new ArrayList(); - nicsUuidsCopy.addAll(vmNicUuids); - nicsUuidsCopy.removeAll(nicUuidsIn); - if (!nicsUuidsCopy.isEmpty()) { - Collection toDeleted = cal.createRulePlaceHolder(nicsUuidsCopy, IPv6Constants.IPv4); - for (HostRuleTO hto : toDeleted) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); - } - htos1 = cal.mergeMultiHostRuleTO(htos1, toDeleted); + flow(new NoRollbackFlow() { + String __name__ = "update-group-numbers"; - toDeleted = cal.createRulePlaceHolder(nicsUuidsCopy, IPv6Constants.IPv6); - for (HostRuleTO hto : toDeleted) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); - } - htos1 = cal.mergeMultiHostRuleTO(htos1, toDeleted); - } + @Override + public boolean skip(Map data) { + return backend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(sgUuid); + if(!groupMemberTO.getHostUuids().isEmpty()){ + if (Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).eq(SecurityGroupVO_.state, SecurityGroupState.Disabled).isExists()) { + groupMemberTO.getGroupMembersTO().setActionCode(ACTION_CODE_DELETE_GROUP); + } + updateGroupMembers(groupMemberTO); + } - List finalHtos = htos1; + trigger.next(); + } + }); - applyRules(finalHtos); + flow(new NoRollbackFlow() { + String __name__ = "update-sdn-controller"; - // update security group member - HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(sgUuid); - if(!groupMemberTO.getHostUuids().isEmpty()){ - updateGroupMembers(groupMemberTO); - } + @Override + public boolean skip(Map data) { + return backend == null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + if (backend == null || vmNicUuids.isEmpty()) { + trigger.next(); + return; + } + + sdnRemoveSecurityGroupFromVmNic(backend, Collections.singletonList(sgUuid), vmNicUuids, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); } private void handle(APIDeleteVmNicFromSecurityGroupMsg msg) { - removeNicFromSecurityGroup(msg.getSecurityGroupUuid(), msg.getVmNicUuids()); APIDeleteVmNicFromSecurityGroupEvent evt = new APIDeleteVmNicFromSecurityGroupEvent(msg.getId()); - bus.publish(evt); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + RemoveVmNicFromSecurityGroupMsg rmsg = new RemoveVmNicFromSecurityGroupMsg(); + rmsg.setSecurityGroupUuid(msg.getSecurityGroupUuid()); + rmsg.setVmNicUuids(msg.getVmNicUuids()); + bus.makeTargetServiceIdByResourceUuid(rmsg, SecurityGroupConstant.SERVICE_ID, msg.getSecurityGroupUuid()); + + bus.send(rmsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + } + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("remove-vm-nic-from-security-group-%s", msg.getSecurityGroupUuid()); + } + }); } - private void disableSecurityGroup(String uuid) { - SimpleQuery q = dbf.createQuery(VmNicSecurityGroupRefVO.class); - q.select(VmNicSecurityGroupRefVO_.vmNicUuid); - q.add(VmNicSecurityGroupRefVO_.securityGroupUuid, Op.EQ, uuid); - List vmNicUuids = q.listValue(); + private List updateRelatedSecurityGroupRules(String sgUuid) { + List rules = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.remoteSecurityGroupUuid, sgUuid) + .notEq(SecurityGroupRuleVO_.securityGroupUuid, sgUuid).list(); + if (rules.isEmpty()) { + return new ArrayList<>(); + } - RuleCalculator cal = new RuleCalculator(); - SecurityGroupVO sgvo = dbf.findByUuid(uuid, SecurityGroupVO.class); + Map> toDelete = new HashMap<>(); + rules.forEach(r -> { + toDelete.computeIfAbsent(r.getSecurityGroupUuid(), k -> new ArrayList<>()); + toDelete.get(r.getSecurityGroupUuid()).add(r.getUuid()); + }); - if (!vmNicUuids.isEmpty()) { - cal.vmNicUuids = vmNicUuids; - cal.vmStates = asList(VmInstanceState.Running); - /* if vmnics are still in other sg, calcalue the rules */ - List htos = cal.calculate(); + for (Map.Entry> entry : toDelete.entrySet()) { + doDeleteSecurityGroupRule(entry.getKey(), entry.getValue()); + } - List nicUuidsIn = SQL.New("select ref.vmNicUuid from VmNicSecurityGroupRefVO ref, SecurityGroupVO sg" + - " where ref.vmNicUuid in (:vmNicUuids) and ref.securityGroupUuid = sg.uuid and sg.state = :sgState", String.class) - .param("vmNicUuids", vmNicUuids).param("sgState", SecurityGroupState.Enabled).list(); + return new ArrayList<>(toDelete.keySet()); + } - vmNicUuids.removeAll(nicUuidsIn); - if (!vmNicUuids.isEmpty()) { - // these vm nics are no longer in any security group, delete their chains on host - Collection toRemove = cal.createRulePlaceHolder(vmNicUuids, IPv6Constants.IPv4); - for (HostRuleTO hto : toRemove) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); - } + private void deleteSecurityGroupFromSdn(SecurityGroupSdnBackend backend, String sgUuid, Completion completion) { + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("sdn-backend-delete-security-group-%s", sgUuid)); + chain.setData(data); + chain.then(new NoRollbackFlow() { + String __name__ = "update-security-group-db"; - htos = cal.mergeMultiHostRuleTO(htos, toRemove); + @Override + public void run(FlowTrigger trigger, Map data) { + // step 1, update vmnic + VmNicSecurityGroupTo delNicTo = new VmNicSecurityGroupTo(); + List vmNicUuids = Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .eq(VmNicSecurityGroupRefVO_.securityGroupUuid, sgUuid).listValues(); + if (!vmNicUuids.isEmpty()) { + //step 1.1, delete vmnic <--> security group ref + SQL.New(VmNicSecurityGroupRefVO.class) + .eq(VmNicSecurityGroupRefVO_.securityGroupUuid, sgUuid) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids).delete(); + + //step 1.2, update remain security group priority + for (String uuid : vmNicUuids) { + List refs = Q.New(VmNicSecurityGroupRefVO.class) + .eq(VmNicSecurityGroupRefVO_.vmNicUuid, uuid) + .orderBy(VmNicSecurityGroupRefVO_.priority, SimpleQuery.Od.ASC).list(); + if (!refs.isEmpty()) { + refs.forEach(ref ->{ + ref.setPriority(refs.indexOf(ref) + 1); + }); + dbf.updateCollection(refs); + } + } + } - toRemove = cal.createRulePlaceHolder(vmNicUuids, IPv6Constants.IPv6); - for (HostRuleTO hto : toRemove) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); + // step 2, update related security group + List relatedSgUuids = updateRelatedSecurityGroupRules(sgUuid); + if (!relatedSgUuids.isEmpty()) { + vmNicUuids.addAll(Q.New(VmNicSecurityGroupRefVO.class) + .select(VmNicSecurityGroupRefVO_.vmNicUuid) + .in(VmNicSecurityGroupRefVO_.securityGroupUuid, relatedSgUuids) + .listValues()); } - htos = cal.mergeMultiHostRuleTO(htos, toRemove); + vmNicUuids = vmNicUuids.stream().distinct().collect(Collectors.toList()); + + data.put(VM_NIC_UUIDS, vmNicUuids); + + trigger.next(); } - applyRules(htos); - } + }).then(new NoRollbackFlow() { + String __name__ = "delete-from-sdn"; - List sgUuids = Q.New(SecurityGroupRuleVO.class).select(SecurityGroupRuleVO_.securityGroupUuid).eq(SecurityGroupRuleVO_.remoteSecurityGroupUuid, uuid).listValues(); - sgUuids = sgUuids.stream().distinct().collect(Collectors.toList()); - sgUuids.remove(uuid); - if (!sgUuids.isEmpty()) { - RuleCalculator rcal = new RuleCalculator(); - rcal.securityGroupUuids = sgUuids; - rcal.vmStates = asList(VmInstanceState.Running); - List rhtos = rcal.calculate(); - applyRules(rhtos); - } - - HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(uuid); - if(!groupMemberTO.getHostUuids().isEmpty()){ - groupMemberTO.getGroupMembersTO().setActionCode(ACTION_CODE_DELETE_GROUP); - updateGroupMembers(groupMemberTO); - } + @Override + public void run(FlowTrigger trigger, Map data) { + List vmNicUuids = (List) data.get(VM_NIC_UUIDS); + sdnDeleteSecurityGroup(backend, vmNicUuids, sgUuid, new Completion(trigger) { + @Override + public void success() { + // step 3, remove security group + SQL.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).delete(); + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + // step 3, remove security group + SQL.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).delete(); + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); } - private void handle(APIDeleteSecurityGroupMsg msg) { - SecurityGroupVO sgVo = dbf.findByUuid(msg.getUuid(), SecurityGroupVO.class); - SimpleQuery q = dbf.createQuery(VmNicSecurityGroupRefVO.class); - q.select(VmNicSecurityGroupRefVO_.vmNicUuid); - q.add(VmNicSecurityGroupRefVO_.securityGroupUuid, Op.EQ, msg.getUuid()); - List vmNicUuids = q.listValue(); + private void deleteSecurityGroup(String sgUuid, Completion completion) { + SecurityGroupSdnBackend backend = getSdnBackend(sgUuid); + if (backend != null) { + deleteSecurityGroupFromSdn(backend, sgUuid, completion); + return; + } - RuleCalculator cal = new RuleCalculator(); - HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(msg.getUuid()); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "dettach-nic-from-security-group-in-db"; + + // this flow will refresh vmnic attached by current sg: sgUuid + @Override + public void run(FlowTrigger trigger, Map data) { + List attachedNicUuids = Q.New(VmNicSecurityGroupRefVO.class).select(VmNicSecurityGroupRefVO_.vmNicUuid).eq(VmNicSecurityGroupRefVO_.securityGroupUuid, sgUuid).listValues(); + + RemoveVmNicFromSecurityGroupMsg rmsg = new RemoveVmNicFromSecurityGroupMsg(); + rmsg.setSecurityGroupUuid(sgUuid); + rmsg.setVmNicUuids(attachedNicUuids); + bus.makeTargetServiceIdByResourceUuid(rmsg, SecurityGroupConstant.SERVICE_ID, sgUuid); + + bus.send(rmsg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + } else { + trigger.next(); + } + } + }); + } + }); + flow(new NoRollbackFlow() { + String __name__ = "delete-all-associated-security-group-rules-in-db"; - dbf.removeByPrimaryKey(msg.getUuid(), SecurityGroupVO.class); + // this flow will find other sgs related to current sg by SecurityGroupRuleVO_.remoteSecurityGroupUuid + // action: 1. delete related rules + // 2. re-calculate the remain rules priority + // 3. find the vmnics related to the other sgs - if (!vmNicUuids.isEmpty()) { - cal.vmNicUuids = vmNicUuids; - cal.vmStates = asList(VmInstanceState.Running); - List htos = cal.calculate(); + @Override + public void run(FlowTrigger trigger, Map data) { + List rules = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.remoteSecurityGroupUuid, sgUuid) + .notEq(SecurityGroupRuleVO_.securityGroupUuid, sgUuid).list(); + if (rules.isEmpty()) { + dbf.removeByPrimaryKey(sgUuid, SecurityGroupVO.class); + trigger.next(); + return; + } + + Map> toDelete = new HashMap<>(); + rules.forEach(r -> { + if (!toDelete.containsKey(r.getSecurityGroupUuid())) { + toDelete.put(r.getSecurityGroupUuid(), new ArrayList()); + } + + toDelete.get(r.getSecurityGroupUuid()).add(r.getUuid()); + }); + + List otherNicUuids = new ArrayList<>(); + for (Map.Entry> entry : toDelete.entrySet()) { + List nicUuids = Q.New(VmNicSecurityGroupRefVO.class).select(VmNicSecurityGroupRefVO_.vmNicUuid).eq(VmNicSecurityGroupRefVO_.securityGroupUuid, entry.getKey()).listValues(); + otherNicUuids.addAll(nicUuids); + doDeleteSecurityGroupRule(entry.getKey(), entry.getValue()); + } + dbf.removeByPrimaryKey(sgUuid, SecurityGroupVO.class); + + data.put(VM_NIC_UUIDS, otherNicUuids); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + // this flow will refresh the other nic found by previous flow + + @Override + public void run(FlowTrigger trigger, Map data) { + List vmNicUuids = (List)data.getOrDefault(VM_NIC_UUIDS, new ArrayList<>()); + if (!vmNicUuids.isEmpty()) { + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = vmNicUuids; + cal.vmStates = asList(VmInstanceState.Running); + List htos = cal.calculate(); + applyRules(htos); + } + + trigger.next(); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); + } + + private void handle(APIDeleteSecurityGroupMsg msg) { + APIDeleteSecurityGroupEvent evt = new APIDeleteSecurityGroupEvent(msg.getId()); + final String issuer = SecurityGroupVO.class.getSimpleName(); + SecurityGroupInventory inv = SecurityGroupInventory.valueOf(dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class)); + final List ctx = Collections.singletonList(inv); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("delete-security-group-%s", msg.getUuid())); + if (msg.getDeletionMode() == APIDeleteMessage.DeletionMode.Permissive) { + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + casf.asyncCascade(CascadeConstant.DELETION_CHECK_CODE, issuer, ctx, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } - List nicUuidsIn = SQL.New("select ref.vmNicUuid from VmNicSecurityGroupRefVO ref, SecurityGroupVO sg " + - " where ref.vmNicUuid in (:vmNicUuids) and ref.securityGroupUuid = sg.uuid and sg.state = :sgState", String.class) - .param("vmNicUuids", vmNicUuids).param("sgState", SecurityGroupState.Enabled).list(); + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }).then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + casf.asyncCascade(CascadeConstant.DELETION_DELETE_CODE, issuer, ctx, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } - vmNicUuids.removeAll(nicUuidsIn); - if (!vmNicUuids.isEmpty()) { - // these vm nics are no longer in any security group, delete their chains on host - Collection toRemove = cal.createRulePlaceHolder(vmNicUuids, IPv6Constants.IPv4); - for (HostRuleTO hto : toRemove) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); } - htos = cal.mergeMultiHostRuleTO(htos, toRemove); + }); + } else { + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + casf.asyncCascade(CascadeConstant.DELETION_FORCE_DELETE_CODE, issuer, ctx, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } - toRemove = cal.createRulePlaceHolder(vmNicUuids, IPv6Constants.IPv6); - for (HostRuleTO hto : toRemove) { - hto.setActionCodeForAllSecurityGroupRuleTOs(SecurityGroupRuleTO.ACTION_CODE_DELETE_CHAIN); + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); } + }); + } + chain.done(new FlowDoneHandler(msg) { + @Override + public void handle(Map data) { + casf.asyncCascadeFull(CascadeConstant.DELETION_CLEANUP_CODE, issuer, ctx, new NopeCompletion()); + bus.publish(evt); + } + }).error(new FlowErrorHandler(msg) { + @Override + public void handle(ErrorCode errCode, Map data) { + evt.setError(errCode); + bus.publish(evt); + } + }).start(); + } - htos = cal.mergeMultiHostRuleTO(htos, toRemove); + private void handle(APIDeleteSecurityGroupRuleMsg msg) { + String sgUuid = Q.New(SecurityGroupRuleVO.class).select(SecurityGroupRuleVO_.securityGroupUuid).eq(SecurityGroupRuleVO_.uuid, msg.getRuleUuids().get(0)).findValue(); + APIDeleteSecurityGroupRuleEvent evt = new APIDeleteSecurityGroupRuleEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(sgUuid); } - applyRules(htos); + + @Override + public void run(SyncTaskChain chain) { + deleteSecurityGroupRule(msg, sgUuid, new Completion(msg, chain) { + @Override + public void success() { + SecurityGroupVO sgvo = dbf.findByUuid(sgUuid, SecurityGroupVO.class); + evt.setInventory(SecurityGroupInventory.valueOf(sgvo)); + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("delete-security-group-%s-rules-%s", sgUuid, Arrays.toString(msg.getRuleUuids().toArray())); + } + }); + } + + private void doDeleteSecurityGroupRule(String sgUuid, List ruleUuids) { + if (ruleUuids.isEmpty()) { + return; } - if(!groupMemberTO.getHostUuids().isEmpty()){ - groupMemberTO.getGroupMembersTO().setActionCode(ACTION_CODE_DELETE_GROUP); - updateGroupMembers(groupMemberTO); + List rvos = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, sgUuid) + .notEq(SecurityGroupRuleVO_.priority, SecurityGroupConstant.DEFAULT_RULE_PRIORITY) + .list(); + + boolean isUpdateIngress = false, isUpdateEgress = false; + List toUpdate = new ArrayList<>(); + for (SecurityGroupRuleVO rvo : rvos) { + if (ruleUuids.contains(rvo.getUuid())) { + if (SecurityGroupRuleType.Ingress.equals(rvo.getType())) { + isUpdateIngress = true; + } else { + isUpdateEgress = true; + } + } else { + toUpdate.add(rvo); + } } - APIDeleteSecurityGroupEvent evt = new APIDeleteSecurityGroupEvent(msg.getId()); - logger.debug(String.format("successfully deleted security group[uuid:%s]", msg.getUuid())); - bus.publish(evt); + dbf.removeByPrimaryKeys(ruleUuids, SecurityGroupRuleVO.class); + + if (isUpdateIngress) { + List ingressToUpdate = toUpdate.stream() + .filter(rvo -> SecurityGroupRuleType.Ingress.equals(rvo.getType())) + .sorted(Comparator.comparingInt(SecurityGroupRuleVO::getPriority)).collect(Collectors.toList()); + ingressToUpdate.stream().forEach(r -> { + r.setPriority(ingressToUpdate.indexOf(r) + 1); + }); + dbf.updateCollection(ingressToUpdate); + } + + if (isUpdateEgress) { + List egressToUpdate = toUpdate.stream() + .filter(rvo -> SecurityGroupRuleType.Egress.equals(rvo.getType())) + .sorted(Comparator.comparingInt(SecurityGroupRuleVO::getPriority)).collect(Collectors.toList()); + egressToUpdate.stream().forEach(r -> { + r.setPriority(egressToUpdate.indexOf(r) + 1); + }); + dbf.updateCollection(egressToUpdate); + } + + return; } - private void handle(APIDeleteSecurityGroupRuleMsg msg) { - SimpleQuery q = dbf.createQuery(SecurityGroupRuleVO.class); - q.select(SecurityGroupRuleVO_.securityGroupUuid); - q.add(SecurityGroupRuleVO_.uuid, Op.EQ, msg.getRuleUuids().get(0)); - String sgUuid = q.findValue(); + private void deleteSecurityGroupRule(APIDeleteSecurityGroupRuleMsg msg, String sgUuid, Completion completion) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(sgUuid); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "delete-security-group-rules-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + doDeleteSecurityGroupRule(sgUuid, msg.getRuleUuids()); + trigger.next(); + } + }); - dbf.removeByPrimaryKeys(msg.getRuleUuids(), SecurityGroupRuleVO.class); - SecurityGroupVO sgvo = dbf.findByUuid(sgUuid, SecurityGroupVO.class); + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; - if (SecurityGroupState.Enabled == sgvo.getState()) { - RuleCalculator cal = new RuleCalculator(); - cal.securityGroupUuids = asList(sgUuid); - cal.vmStates = asList(VmInstanceState.Running); + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + SecurityGroupVO sgvo = dbf.findByUuid(sgUuid, SecurityGroupVO.class); + if (SecurityGroupState.Enabled.equals(sgvo.getState())) { + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = asList(sgUuid); + cal.vmStates = asList(VmInstanceState.Running); + + List htos = cal.calculate(); + applyRules(htos); + } + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnBackend == null) { + trigger.next(); + return; + } + + sdnRefreshSecurityGroup(sdnBackend, sgUuid, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); - List htos = cal.calculate(); - applyRules(htos); - } + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); - APIDeleteSecurityGroupRuleEvent evt = new APIDeleteSecurityGroupRuleEvent(msg.getId()); - evt.setInventory(SecurityGroupInventory.valueOf(sgvo)); - bus.publish(evt); + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); } private void validate(AddVmNicToSecurityGroupMsg msg) { - String securityGroupUuid = msg.getSecurityGroupUuid(); List uuids = Q.New(VmNicVO.class) .select(VmNicVO_.uuid) .in(VmNicVO_.uuid, msg.getVmNicUuids()) .listValues(); - if (!uuids.containsAll(msg.getVmNicUuids())) { + if (!new HashSet<>(uuids).containsAll(msg.getVmNicUuids())) { msg.getVmNicUuids().removeAll(uuids); throw new OperationFailureException(err(SysErrors.RESOURCE_NOT_FOUND, "cannot find vm nics[uuids:%s]", msg.getVmNicUuids() )); } - List nicUuids = SQL.New("select nic.uuid from SecurityGroupL3NetworkRefVO ref, VmNicVO nic, UsedIpVO ip" + - " where ref.l3NetworkUuid = ip.l3NetworkUuid and ip.vmNicUuid = nic.uuid" + - " and ref.securityGroupUuid = :sgUuid and nic.uuid in (:nicUuids)") - .param("nicUuids", uuids) - .param("sgUuid", securityGroupUuid) - .list(); + List refs = Q.New(VmNicSecurityGroupRefVO.class).eq(VmNicSecurityGroupRefVO_.securityGroupUuid, msg.getSecurityGroupUuid()).list(); + if (!refs.isEmpty()) { + refs.stream().forEach(ref -> { + if (uuids.contains(ref.getVmNicUuid())) { + throw new OperationFailureException(argerr("vm nic[uuid:%s] has been attach to security group[uuid:%s]", ref.getVmNicUuid(), msg.getSecurityGroupUuid())); + } + }); + } - List wrongUuids = new ArrayList<>(); - for (String uuid : uuids) { - if (!nicUuids.contains(uuid)) { - wrongUuids.add(uuid); + String sgOwnerAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(msg.getSecurityGroupUuid()); + List nics = Q.New(VmNicVO.class).in(VmNicVO_.uuid, uuids).list(); + for(VmNicVO nic : nics) { + if (!Q.New(NetworkServiceL3NetworkRefVO.class).eq(NetworkServiceL3NetworkRefVO_.l3NetworkUuid, nic.getL3NetworkUuid()) + .eq(NetworkServiceL3NetworkRefVO_.networkServiceType, SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE).isExists()) { + throw new OperationFailureException(argerr("the netwotk service[type:%s] not enabled on the l3Network[uuid:%s] of nic[uuid:%s]", SecurityGroupConstant.SECURITY_GROUP_NETWORK_SERVICE_TYPE, nic.getL3NetworkUuid(), nic.getUuid())); } - } - if (!wrongUuids.isEmpty()) { - throw new OperationFailureException(argerr("VM nics[uuids:%s] are not on L3 networks that have been attached to the security group[uuid:%s]", - wrongUuids, securityGroupUuid)); + String vmAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(nic.getVmInstanceUuid()); + if (!AccountConstant.isAdminPermission(sgOwnerAccountUuid) && !AccountConstant.isAdminPermission(vmAccountUuid) && !sgOwnerAccountUuid.equals(vmAccountUuid)) { + throw new OperationFailureException(argerr("security group[uuid:%s] is not owned by account[uuid:%s] or admin", msg.getSecurityGroupUuid(), vmAccountUuid)); + } } msg.setVmNicUuids(uuids); } - private void handle(AddVmNicToSecurityGroupMsg msg) { - AddVmNicToSecurityGroupReply reply = new AddVmNicToSecurityGroupReply(); + private void doAddVmNicToSecurityGroup(String sgUuid, List vmNicUuids) { + if (vmNicUuids.isEmpty()) { + return; + } + List nicvos = Q.New(VmNicVO.class).in(VmNicVO_.uuid, vmNicUuids).list(); + List refs = Q.New(VmNicSecurityGroupRefVO.class).in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids).list(); - validate(msg); + List toCreateRefs = new ArrayList(); + List toCreatePolicies = new ArrayList(); - SimpleQuery q = dbf.createQuery(VmNicVO.class); - q.add(VmNicVO_.uuid, Op.IN, msg.getVmNicUuids()); - List nicvos = q.list(); + String sgOwnerAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(sgUuid); - List vmUuids = new ArrayList(); - List refs = new ArrayList(); for (VmNicVO nic : nicvos) { VmNicSecurityGroupRefVO vo = new VmNicSecurityGroupRefVO(); - vo.setSecurityGroupUuid(msg.getSecurityGroupUuid()); + + String vmAccountUuid = new QuotaUtil().getResourceOwnerAccountUuid(nic.getVmInstanceUuid()); + if (AccountConstant.isAdminPermission(sgOwnerAccountUuid) && !vmAccountUuid.equals(sgOwnerAccountUuid)) { + List toUpdate = refs.stream().filter(ref -> ref.getVmNicUuid().equals(nic.getUuid())).collect(Collectors.toList()); + if (!toUpdate.isEmpty()) { + toUpdate.stream().forEach(r ->{ + r.setPriority(r.getPriority() + 1); + }); + dbf.updateCollection(toUpdate); + } + vo.setPriority(1); + } else { + Long count = refs.stream().filter(r -> r.getVmNicUuid().equals(nic.getUuid())).count(); + if (count > 0) { + vo.setPriority(count.intValue() + 1); + } else { + vo.setPriority(1); + } + } + + vo.setSecurityGroupUuid(sgUuid); vo.setVmInstanceUuid(nic.getVmInstanceUuid()); vo.setVmNicUuid(nic.getUuid()); vo.setUuid(Platform.getUuid()); - refs.add(vo); - vmUuids.add(nic.getVmInstanceUuid()); + toCreateRefs.add(vo); + + if (!Q.New(VmNicSecurityPolicyVO.class).eq(VmNicSecurityPolicyVO_.vmNicUuid, nic.getUuid()).isExists()) { + VmNicSecurityPolicyVO pvo = new VmNicSecurityPolicyVO(); + pvo.setUuid(Platform.getUuid()); + pvo.setVmNicUuid(nic.getUuid()); + pvo.setIngressPolicy(VmNicSecurityPolicy.DENY.toString()); + pvo.setEgressPolicy(VmNicSecurityPolicy.ALLOW.toString()); + toCreatePolicies.add(pvo); + } } - dbf.persistCollection(refs); - boolean triggerApplyRules = Q.New(VmInstanceVO.class) - .in(VmInstanceVO_.uuid, vmUuids) - .eq(VmInstanceVO_.state, VmInstanceState.Running) - .isExists(); + dbf.persistCollection(toCreateRefs); + dbf.persistCollection(toCreatePolicies); + } - SecurityGroupVO sgvo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); - if (SecurityGroupState.Enabled == sgvo.getState()) { - RuleCalculator cal = new RuleCalculator(); - if (triggerApplyRules) { - cal.vmNicUuids = msg.getVmNicUuids(); - List htos = cal.calculate(); - applyRules(htos); + private void addVmNicToSecurityGroup(String sgUuid, List vmNicUuids, Completion completion) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(sgUuid); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "add-vm-nic-to-security-group-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + doAddVmNicToSecurityGroup(sgUuid, vmNicUuids); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.vmNicUuids = vmNicUuids; + List htos = cal.calculate(); + applyRules(htos); + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "update-group-numbers"; + + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(sgUuid); + if(!groupMemberTO.getHostUuids().isEmpty()){ + if (Q.New(SecurityGroupVO.class).eq(SecurityGroupVO_.uuid, sgUuid).eq(SecurityGroupVO_.state, SecurityGroupState.Disabled).isExists()) { + groupMemberTO.getGroupMembersTO().setActionCode(ACTION_CODE_DELETE_GROUP); + } + updateGroupMembers(groupMemberTO); + } + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnBackend == null) { + trigger.next(); + return; + } + + sdnRefreshVmNics(sdnBackend, vmNicUuids, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + private void handle(AddVmNicToSecurityGroupMsg msg) { + AddVmNicToSecurityGroupReply reply = new AddVmNicToSecurityGroupReply(); + + validate(msg); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getVmNicSecurityGroupRefSyncThreadName(); } - HostSecurityGroupMembersTO groupMemberTO = cal.returnHostSecurityGroupMember(msg.getSecurityGroupUuid()); - if (!groupMemberTO.getHostUuids().isEmpty()) { - updateGroupMembers(groupMemberTO); + @Override + public void run(SyncTaskChain chain) { + addVmNicToSecurityGroup(msg.getSecurityGroupUuid(), msg.getVmNicUuids(), new Completion(msg, chain) { + @Override + public void success() { + logger.debug(String.format("successfully added vm nics%s to security group[uuid:%s]", msg.getVmNicUuids(), msg.getSecurityGroupUuid())); + bus.reply(msg, reply); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + chain.next(); + } + }); } - } - logger.debug(String.format("successfully added vm nics%s to security group[uuid:%s]", msg.getVmNicUuids(), msg.getSecurityGroupUuid())); - bus.reply(msg, reply); + @Override + public String getName() { + return String.format("add-vm-nic-to-security-group-%s", msg.getSecurityGroupUuid()); + } + }); } private void handle(final APIAddVmNicToSecurityGroupMsg msg) { APIAddVmNicToSecurityGroupEvent evt = new APIAddVmNicToSecurityGroupEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); + } - AddVmNicToSecurityGroupMsg addVmNicToSecurityGroupMsg = new AddVmNicToSecurityGroupMsg(); - addVmNicToSecurityGroupMsg.setSecurityGroupUuid(msg.getSecurityGroupUuid()); - addVmNicToSecurityGroupMsg.setVmNicUuids(msg.getVmNicUuids()); - bus.makeTargetServiceIdByResourceUuid(addVmNicToSecurityGroupMsg, SecurityGroupConstant.SERVICE_ID, msg.getSecurityGroupUuid()); + @Override + public void run(SyncTaskChain chain) { + AddVmNicToSecurityGroupMsg amsg = new AddVmNicToSecurityGroupMsg(); + amsg.setSecurityGroupUuid(msg.getSecurityGroupUuid()); + amsg.setVmNicUuids(msg.getVmNicUuids()); + bus.makeTargetServiceIdByResourceUuid(amsg, SecurityGroupConstant.SERVICE_ID, msg.getSecurityGroupUuid()); + bus.send(amsg, new CloudBusCallBack(msg) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + evt.setError(reply.getError()); + } + bus.publish(evt); + chain.next(); + } + }); + } - bus.send(addVmNicToSecurityGroupMsg, new CloudBusCallBack(msg) { @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - evt.setError(reply.getError()); - } - bus.publish(evt); + public String getName() { + return String.format("add-vm-nic-to-security-group-%s", msg.getSecurityGroupUuid()); } }); } @@ -1333,64 +3049,181 @@ public void fail(ErrorCode errorCode) { private void handle(APIAddSecurityGroupRuleMsg msg) { APIAddSecurityGroupRuleEvent evt = new APIAddSecurityGroupRuleEvent(msg.getId()); - SecurityGroupVO securityGroupVO = addRuleToSecurityGroup(msg); - evt.setInventory(SecurityGroupInventory.valueOf(securityGroupVO)); - logger.debug(String.format("successfully add rules to security group[uuid:%s, name:%s]:\n%s", securityGroupVO.getUuid(), securityGroupVO.getName(), JSONObjectUtil.toJsonString(msg.getRules()))); - bus.publish(evt); - } - private SecurityGroupVO addRuleToSecurityGroup(AddSecurityGroupRuleMessage message) { - SecurityGroupVO sgvo = dbf.findByUuid(message.getSecurityGroupUuid(), SecurityGroupVO.class); - - List vos = new ArrayList(); - for (SecurityGroupRuleAO ao : message.getRules()) { - if (message.getRemoteSecurityGroupUuids() != null) { - for (String remoteGroupUuid : message.getRemoteSecurityGroupUuids()) { - SecurityGroupRuleVO vo = new SecurityGroupRuleVO(); - vo.setUuid(Platform.getUuid()); - vo.setIpVersion(ao.getIpVersion()); - vo.setAllowedCidr(ao.getAllowedCidr()); - vo.setEndPort(ao.getEndPort()); - vo.setStartPort(ao.getStartPort()); - vo.setProtocol(SecurityGroupRuleProtocolType.valueOf(ao.getProtocol())); - vo.setType(SecurityGroupRuleType.valueOf(ao.getType())); - vo.setSecurityGroupUuid(message.getSecurityGroupUuid()); - vo.setRemoteSecurityGroupUuid(remoteGroupUuid); - if (SecurityGroupState.Disabled == sgvo.getState()) { - vo.setState(SecurityGroupRuleState.Disabled); - } - vos.add(vo); - } - } else { - SecurityGroupRuleVO vo = new SecurityGroupRuleVO(); - vo.setUuid(Platform.getUuid()); - vo.setIpVersion(ao.getIpVersion()); - vo.setAllowedCidr(ao.getAllowedCidr()); - vo.setEndPort(ao.getEndPort()); - vo.setStartPort(ao.getStartPort()); - vo.setProtocol(SecurityGroupRuleProtocolType.valueOf(ao.getProtocol())); - vo.setType(SecurityGroupRuleType.valueOf(ao.getType())); - vo.setSecurityGroupUuid(message.getSecurityGroupUuid()); - if (SecurityGroupState.Disabled == sgvo.getState()) { - vo.setState(SecurityGroupRuleState.Disabled); - } - vos.add(vo); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return getSecurityGroupSyncThreadName(msg.getSecurityGroupUuid()); } - } - dbf.persistCollection(vos); - if (SecurityGroupState.Enabled == sgvo.getState()) { - RuleCalculator cal = new RuleCalculator(); - cal.securityGroupUuids = asList(message.getSecurityGroupUuid()); - cal.vmStates = asList(VmInstanceState.Running); - List htos = cal.calculate(); - applyRules(htos); - } + @Override + public void run(SyncTaskChain chain) { + doAddSecurityGroupRule(msg, new Completion(msg, chain) { + @Override + public void success() { + SecurityGroupVO sgvo = dbf.findByUuid(msg.getSecurityGroupUuid(), SecurityGroupVO.class); + evt.setInventory(SecurityGroupInventory.valueOf(sgvo)); + logger.debug(String.format("successfully add rules to security group[uuid:%s, name:%s]:\n%s", sgvo.getUuid(), sgvo.getName(), JSONObjectUtil.toJsonString(msg.getRules()))); + bus.publish(evt); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + chain.next(); + } + }); + } + + @Override + public String getName() { + return String.format("add-security-group-%s-rule", msg.getSecurityGroupUuid()); + } + }); + } + + private void doAddSecurityGroupRule(AddSecurityGroupRuleMessage msg, Completion completion) { + SecurityGroupSdnBackend sdnBackend = getSdnBackend(msg.getSecurityGroupUuid()); + Map data = new HashMap(); + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setData(data); + chain.setName(String.format("add-security-group[%s]-rules", msg.getSecurityGroupUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "add-security-group-rule-in-db"; + + @Override + public void run(FlowTrigger trigger, Map data) { + Integer priority = msg.getPriority(); + List ruleVOs = Q.New(SecurityGroupRuleVO.class) + .eq(SecurityGroupRuleVO_.securityGroupUuid, msg.getSecurityGroupUuid()) + .notEq(SecurityGroupRuleVO_.priority, SecurityGroupConstant.DEFAULT_RULE_PRIORITY).list(); + List ingressRuleVOs = ruleVOs.stream().filter(r -> SecurityGroupRuleType.Ingress.equals(r.getType())).collect(Collectors.toList()); + List egressRuleVOs = ruleVOs.stream().filter(r -> SecurityGroupRuleType.Egress.equals(r.getType())).collect(Collectors.toList()); + List ingressToCreate = new ArrayList(); + List egressToCreate = new ArrayList(); + for (SecurityGroupRuleAO ao : msg.getRules()) { + SecurityGroupRuleVO vo = new SecurityGroupRuleVO(); + vo.setUuid(Platform.getUuid()); + vo.setSecurityGroupUuid(msg.getSecurityGroupUuid()); + vo.setDescription(ao.getDescription()); + vo.setType(SecurityGroupRuleType.valueOf(ao.getType())); + vo.setState(SecurityGroupRuleState.valueOf(ao.getState())); + vo.setIpVersion(ao.getIpVersion()); + vo.setPriority(-1); + vo.setSrcIpRange(ao.getSrcIpRange()); + vo.setDstIpRange(ao.getDstIpRange()); + vo.setDstPortRange(ao.getDstPortRange()); + vo.setProtocol(SecurityGroupRuleProtocolType.valueOf(ao.getProtocol())); + vo.setRemoteSecurityGroupUuid(ao.getRemoteSecurityGroupUuid()); + vo.setAllowedCidr(ao.getAllowedCidr()); + vo.setStartPort(ao.getStartPort()); + vo.setEndPort(ao.getEndPort()); + vo.setAction(ao.getAction()); + if (ao.getType().equals(SecurityGroupRuleType.Egress.toString())) { + egressToCreate.add(vo); + } else { + ingressToCreate.add(vo); + } + } + + if (!ingressToCreate.isEmpty()) { + if (priority == -1) { + ingressToCreate.stream().forEach(r -> r.setPriority(ingressRuleVOs.size() + ingressToCreate.indexOf(r) + 1)); + dbf.persistCollection(ingressToCreate); + } else { + ingressToCreate.stream().forEach(r -> r.setPriority(priority + ingressToCreate.indexOf(r))); + dbf.persistCollection(ingressToCreate); + List toUpdate = ingressRuleVOs.stream().filter(r -> r.getPriority() >= priority).collect(Collectors.toList()); + toUpdate.stream().forEach(r -> r.setPriority(r.getPriority() + ingressToCreate.size())); + dbf.updateCollection(toUpdate); + } + } + if (!egressToCreate.isEmpty()) { + if (priority == -1) { + egressToCreate.stream().forEach(r -> r.setPriority(egressRuleVOs.size() + egressToCreate.indexOf(r) + 1)); + dbf.persistCollection(egressToCreate); + } else { + egressToCreate.stream().forEach(r -> r.setPriority(priority + egressToCreate.indexOf(r))); + dbf.persistCollection(egressToCreate); + List toUpdate = egressRuleVOs.stream().filter(r -> r.getPriority() >= priority).collect(Collectors.toList()); + toUpdate.stream().forEach(r -> r.setPriority(r.getPriority() + egressToCreate.size())); + dbf.updateCollection(toUpdate); + } + } + + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-hosts"; + + @Override + public boolean skip(Map data) { + return sdnBackend != null; + } + + @Override + public void run(FlowTrigger trigger, Map data) { + RuleCalculator cal = new RuleCalculator(); + cal.securityGroupUuids = asList(msg.getSecurityGroupUuid()); + cal.vmStates = asList(VmInstanceState.Running); + List htos = cal.calculate(); + applyRules(htos); + trigger.next(); + } + }); + + flow(new NoRollbackFlow() { + String __name__ = "apply-rules-on-sdn-controller"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (sdnBackend == null) { + trigger.next(); + return; + } + + sdnRefreshSecurityGroup(sdnBackend, msg.getSecurityGroupUuid(), new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); - return dbf.reload(sgvo); + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + + } + }).start(); } private void handle(APICreateSecurityGroupMsg msg) { + APICreateSecurityGroupEvent evt = new APICreateSecurityGroupEvent(msg.getId()); + SecurityGroupVO vo = new SecurityGroupVO(); if (msg.getResourceUuid() != null) { vo.setUuid(msg.getResourceUuid()); @@ -1400,6 +3233,7 @@ private void handle(APICreateSecurityGroupMsg msg) { vo.setName(msg.getName()); vo.setDescription(msg.getDescription()); vo.setState(SecurityGroupState.Enabled); + vo.setvSwitchType(msg.getvSwitchType()); vo.setInternalId(dbf.generateSequenceNumber(SecurityGroupSequenceNumberVO.class)); vo.setAccountUuid(msg.getSession().getAccountUuid()); @@ -1419,10 +3253,28 @@ protected SecurityGroupVO scripts() { vo = dbf.reload(vo); SecurityGroupInventory inv = SecurityGroupInventory.valueOf(vo); - APICreateSecurityGroupEvent evt = new APICreateSecurityGroupEvent(msg.getId()); - evt.setInventory(inv); - logger.debug(String.format("successfully created security group[uuid:%s, name:%s]", vo.getUuid(), vo.getName())); - bus.publish(evt); + SecurityGroupSdnBackend sdnBackend = getSdnBackend(vo.getUuid()); + if (sdnBackend == null) { + evt.setInventory(inv); + logger.debug(String.format("successfully created security group[uuid:%s, name:%s]", vo.getUuid(), vo.getName())); + bus.publish(evt); + return; + } + + sdnBackend.createSecurityGroup(inv, new Completion(msg) { + @Override + public void success() { + evt.setInventory(inv); + logger.debug(String.format("successfully created security group[uuid:%s, name:%s]", inv.getUuid(), inv.getName())); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); } public String getId() { @@ -1434,34 +3286,34 @@ private void createDefaultRule(String sgUuid, int ipVersion){ SecurityGroupRuleVO ingressRuleVo = new SecurityGroupRuleVO(); ingressRuleVo.setUuid(Platform.getUuid()); + ingressRuleVo.setSecurityGroupUuid(sgUuid); + ingressRuleVo.setDescription(SecurityGroupConstant.DEFAULT_RULE_DESCRIPTION); + ingressRuleVo.setState(SecurityGroupRuleState.Enabled); ingressRuleVo.setIpVersion(ipVersion); - if (ipVersion == IPv6Constants.IPv4) { - ingressRuleVo.setAllowedCidr("0.0.0.0/0"); - } else { - ingressRuleVo.setAllowedCidr("::/0"); - } - ingressRuleVo.setEndPort(-1); - ingressRuleVo.setStartPort(-1); - ingressRuleVo.setProtocol(SecurityGroupRuleProtocolType.ALL); ingressRuleVo.setType(SecurityGroupRuleType.Ingress); - ingressRuleVo.setSecurityGroupUuid(sgUuid); + ingressRuleVo.setPriority(SecurityGroupConstant.DEFAULT_RULE_PRIORITY); + ingressRuleVo.setAction(SecurityGroupRuleAction.ACCEPT.toString()); + ingressRuleVo.setProtocol(SecurityGroupRuleProtocolType.ALL); ingressRuleVo.setRemoteSecurityGroupUuid(sgUuid); + ingressRuleVo.setAllowedCidr(ipVersion == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + ingressRuleVo.setStartPort(-1); + ingressRuleVo.setEndPort(-1); vos.add(ingressRuleVo); SecurityGroupRuleVO egressRuleVo = new SecurityGroupRuleVO(); egressRuleVo.setUuid(Platform.getUuid()); + egressRuleVo.setRemoteSecurityGroupUuid(sgUuid); + egressRuleVo.setDescription(SecurityGroupConstant.DEFAULT_RULE_DESCRIPTION); + egressRuleVo.setState(SecurityGroupRuleState.Enabled); egressRuleVo.setIpVersion(ipVersion); - if (ipVersion == IPv6Constants.IPv4) { - egressRuleVo.setAllowedCidr("0.0.0.0/0"); - } else { - egressRuleVo.setAllowedCidr("::/0"); - } - egressRuleVo.setEndPort(-1); - egressRuleVo.setStartPort(-1); - egressRuleVo.setProtocol(SecurityGroupRuleProtocolType.ALL); egressRuleVo.setType(SecurityGroupRuleType.Egress); + egressRuleVo.setPriority(SecurityGroupConstant.DEFAULT_RULE_PRIORITY); + egressRuleVo.setAction(SecurityGroupRuleAction.ACCEPT.toString()); + egressRuleVo.setProtocol(SecurityGroupRuleProtocolType.ALL); egressRuleVo.setSecurityGroupUuid(sgUuid); - egressRuleVo.setRemoteSecurityGroupUuid(sgUuid); + egressRuleVo.setAllowedCidr(ipVersion == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + egressRuleVo.setStartPort(-1); + egressRuleVo.setEndPort(-1); vos.add(egressRuleVo); dbf.persistCollection(vos); @@ -1484,7 +3336,7 @@ private void startFailureHostCopingThread() { logger.debug(String.format("security group failureHostCopingThread starts[failureHostEachTimeTake: %s, failureHostWorkerInterval: %ss]", failureHostEachTimeTake, failureHostWorkerInterval)); } - private void restartFailureHostCopingThread() { + private synchronized void restartFailureHostCopingThread() { if (failureHostCopingThread != null) { failureHostCopingThread.cancel(true); } @@ -1531,10 +3383,6 @@ public SecurityGroupHypervisorBackend getHypervisorBackend(String hypervisorType return backend; } - @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } - @Override public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { } @@ -1545,10 +3393,22 @@ public void afterMigrateVm(final VmInstanceInventory inv, final String srcHostUu cal.vmNicUuids = CollectionUtils.transformToList(inv.getVmNics(), new Function() { @Override public String call(VmNicInventory arg) { - return arg.getUuid(); + // security group for ovn network does not care vm migration + String vswitchType = L3NetworkHelper.getL3networkVSwitchType(arg.getL3NetworkUuid()); + if (VSwitchType.valueOf(vswitchType).isAttachToCluster()) { + return arg.getUuid(); + } else { + return null; + } } }); - cal.vmStates = asList(VmInstanceState.Running); + + if (cal.vmNicUuids.isEmpty()) { + return; + } + + // if migrate vm with Storage,the vm stat is migrating + cal.vmStates = asList(VmInstanceState.Running, VmInstanceState.Migrating); List htos = cal.calculate(); applyRules(htos); @@ -1584,9 +3444,19 @@ public void failedToMigrateVm(final VmInstanceInventory inv, final String destHo cal.vmNicUuids = CollectionUtils.transformToList(inv.getVmNics(), new Function() { @Override public String call(VmNicInventory arg) { - return arg.getUuid(); + // security group for ovn network does not care vm migration + String vswitchType = L3NetworkHelper.getL3networkVSwitchType(arg.getL3NetworkUuid()); + if (VSwitchType.valueOf(vswitchType).isAttachToCluster()) { + return arg.getUuid(); + } else { + return null; + } } }); + if (cal.vmNicUuids.isEmpty()) { + return; + } + cal.vmStates = asList(VmInstanceState.Unknown); List htos = cal.calculate(); @@ -1709,4 +3579,79 @@ public String getName() { return FailureHostWorker.class.getName(); } } + + private SecurityGroupSdnBackend getSdnBackend(String sgUuid) { + String sdnControllerUuid = SecurityGroupHelper.getSdnControllerUuid(sgUuid); + if (sdnControllerUuid == null) { + return null; + } + + for (SecurityGroupGetSdnBackendExtensionPoint exp : pluginRgty.getExtensionList(SecurityGroupGetSdnBackendExtensionPoint.class)) { + SecurityGroupSdnBackend backend = exp.getSecurityGroupSdnBackend(sdnControllerUuid); + if (backend != null) { + return backend; + } + } + + throw new CloudRuntimeException(String.format("can not find security backend for sdn controller[uuid:%s]", sdnControllerUuid)); + } + + private SecurityGroupSdnBackend getSdnBackendFroL3Uuid(String l3Uuid) { + String sdnControllerUuid = L3NetworkHelper.getSdnControllerUuidFromL3Uuid(l3Uuid); + if (sdnControllerUuid == null) { + return null; + } + + for (SecurityGroupGetSdnBackendExtensionPoint exp : pluginRgty.getExtensionList(SecurityGroupGetSdnBackendExtensionPoint.class)) { + SecurityGroupSdnBackend backend = exp.getSecurityGroupSdnBackend(sdnControllerUuid); + if (backend != null) { + return backend; + } + } + + return null; + } + + @Override + public void deleteNetworkServiceOfSdnController(String sdnControllerUuid, Completion completion) { + List sgUuids = Q.New(SecurityGroupVO.class) + .select(SecurityGroupVO_.uuid).listValues(); + if (sgUuids.isEmpty()) { + completion.success(); + return; + } + + List sdnSgUuids = new ArrayList<>(); + for (String uuid : sgUuids) { + String controllerUuid = SecurityGroupHelper.getSdnControllerUuid(uuid); + if (sdnControllerUuid.equals(controllerUuid)) { + sdnSgUuids.add(uuid); + } + } + if (sdnControllerUuid.isEmpty()) { + completion.success(); + return; + } + + new While<>(sdnSgUuids).step((uuid, wcomp) -> { + SecurityGroupDeletionMsg msg = new SecurityGroupDeletionMsg(); + msg.setUuid(uuid); + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, uuid); + bus.send(msg, new CloudBusCallBack(wcomp) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to security group [uuid:%s], %s", msg.getUuid(), reply.getError())); + } + + wcomp.done(); + } + }); + }, 10).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + completion.success(); + } + }); + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNetworkServiceExtension.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNetworkServiceExtension.java index aea28baabf4..e8ab05e84c3 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNetworkServiceExtension.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNetworkServiceExtension.java @@ -1,5 +1,6 @@ package org.zstack.network.securitygroup; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.zstack.compute.vm.VmSystemTags; @@ -7,10 +8,18 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.asyncbatch.While; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.Completion; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.service.NetworkServiceProviderType; import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.vm.*; @@ -19,11 +28,13 @@ import org.zstack.utils.logging.CLogger; import java.util.*; +import java.util.stream.Collectors; import javax.persistence.Query; +import static org.zstack.core.Platform.operr; /** */ -public class SecurityGroupNetworkServiceExtension extends AbstractNetworkServiceExtension { +public class SecurityGroupNetworkServiceExtension extends AbstractNetworkServiceExtension implements VmAfterAttachNicExtensionPoint { private static final CLogger logger = Utils.getLogger(SecurityGroupNetworkServiceExtension.class); @Autowired @@ -39,37 +50,74 @@ public NetworkServiceType getNetworkServiceType() { return SecurityGroupProviderFactory.networkServiceType; } - private void syncSystemTagToVmNicSecurityGroup(String vmUuid) { + private List syncSystemTagToVmNicSecurityGroup(String vmUuid) { + final List sgUuids = new ArrayList<>(); List tags = VmSystemTags.L3_NETWORK_SECURITY_GROUP_UUIDS_REF.getTags(vmUuid); - List refVOS = new ArrayList<>(); + for (String tag : tags) { Map tokens = VmSystemTags.L3_NETWORK_SECURITY_GROUP_UUIDS_REF.getTokensByTag(tag); String l3Uuid = tokens.get(VmSystemTags.L3_UUID_TOKEN); List securityGroupUuids = Arrays.asList(tokens.get(VmSystemTags.SECURITY_GROUP_UUIDS_TOKEN).split(",")); + sgUuids.addAll(securityGroupUuids); String vmNicUuid = Q.New(VmNicVO.class) .eq(VmNicVO_.l3NetworkUuid, l3Uuid) .eq(VmNicVO_.vmInstanceUuid, vmUuid) .select(VmNicVO_.uuid) .findValue(); - for (String securityGroupUuid : securityGroupUuids) { - if (!Q.New(VmNicSecurityGroupRefVO.class) - .eq(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuid) - .eq(VmNicSecurityGroupRefVO_.securityGroupUuid, securityGroupUuid) - .eq(VmNicSecurityGroupRefVO_.vmNicUuid, vmUuid) - .isExists()) { + List refs = Q.New(VmNicSecurityGroupRefVO.class).eq(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuid).eq(VmNicSecurityGroupRefVO_.vmInstanceUuid, vmUuid).list(); + List toCreate = new ArrayList<>(); + for (String sgUuid : securityGroupUuids) { + refs.stream().filter(ref -> ref.getSecurityGroupUuid().equals(sgUuid)).findAny().orElseGet(() -> { VmNicSecurityGroupRefVO refVO = new VmNicSecurityGroupRefVO(); refVO.setUuid(Platform.getUuid()); - refVO.setSecurityGroupUuid(securityGroupUuid); + refVO.setSecurityGroupUuid(sgUuid); refVO.setVmInstanceUuid(vmUuid); refVO.setVmNicUuid(vmNicUuid); - refVOS.add(refVO); + toCreate.add(refVO); + return refVO; + }); + } + if (!toCreate.isEmpty()) { + toCreate.stream().forEach(ref -> { + ref.setPriority(refs.size() + toCreate.indexOf(ref) + 1); + }); + + dbf.persistCollection(toCreate); + + if (!Q.New(VmNicSecurityPolicyVO.class).eq(VmNicSecurityPolicyVO_.vmNicUuid, vmNicUuid).isExists()) { + VmNicSecurityPolicyVO policyVO = new VmNicSecurityPolicyVO(); + policyVO.setUuid(Platform.getUuid()); + policyVO.setVmNicUuid(vmNicUuid); + policyVO.setIngressPolicy(VmNicSecurityPolicy.DENY.toString()); + policyVO.setEgressPolicy(VmNicSecurityPolicy.ALLOW.toString()); + dbf.persist(policyVO); } } } - - dbf.persistCollection(refVOS); VmSystemTags.L3_NETWORK_SECURITY_GROUP_UUIDS_REF.delete(vmUuid); + + tags = VmSystemTags.SECURITY_GROUP_POLICY.getTags(vmUuid); + for (String tag : tags) { + Map tokens = VmSystemTags.SECURITY_GROUP_POLICY.getTokensByTag(tag); + String l3Uuid = tokens.get(VmSystemTags.L3_UUID_TOKEN); + String ingressPolicy = tokens.get(VmSystemTags.SECURITY_GROUP_INGRESS_POLICY_TOKEN); + String egressPolicy = tokens.get(VmSystemTags.SECURITY_GROUP_EGRESS_POLICY_TOKEN); + + String vmNicUuid = Q.New(VmNicVO.class) + .eq(VmNicVO_.l3NetworkUuid, l3Uuid) + .eq(VmNicVO_.vmInstanceUuid, vmUuid) + .select(VmNicVO_.uuid) + .findValue(); + + SQL.New(VmNicSecurityPolicyVO.class).eq(VmNicSecurityPolicyVO_.vmNicUuid, vmNicUuid) + .set(VmNicSecurityPolicyVO_.ingressPolicy, ingressPolicy) + .set(VmNicSecurityPolicyVO_.egressPolicy, egressPolicy).update(); + } + VmSystemTags.SECURITY_GROUP_POLICY.delete(vmUuid); + + + return sgUuids.stream().distinct().collect(Collectors.toList()); } @@ -77,27 +125,159 @@ private void syncSystemTagToVmNicSecurityGroup(String vmUuid) { public void applyNetworkService(VmInstanceSpec servedVm, Map data, final Completion completion) { syncSystemTagToVmNicSecurityGroup(servedVm.getVmInventory().getUuid()); - Map> map = getNetworkServiceProviderMap(SecurityGroupProviderFactory.networkServiceType, - VmNicSpec.getL3NetworkInventoryOfSpec(servedVm.getL3Networks())); + Map> map = getNetworkServiceProviderMap( + SecurityGroupProviderFactory.networkServiceType, + VmNicSpec.getL3NetworkInventoryOfSpec(servedVm.getL3Networks()) + ); if (map.isEmpty()) { completion.success(); return; } - RefreshSecurityGroupRulesOnVmMsg msg = new RefreshSecurityGroupRulesOnVmMsg(); - msg.setVmInstanceUuid(servedVm.getVmInventory().getUuid()); - msg.setHostUuid(servedVm.getDestHost().getUuid()); - bus.makeLocalServiceId(msg, SecurityGroupConstant.SERVICE_ID); - bus.send(msg, new CloudBusCallBack(completion) { + List destNics = servedVm.getDestNics(); + + List vmNicUuids = destNics.stream() + .map(VmNicInventory::getUuid) + .collect(Collectors.toList()); + + List sgUuids = Q.New(VmNicSecurityGroupRefVO.class) + .in(VmNicSecurityGroupRefVO_.vmNicUuid, vmNicUuids) + .select(VmNicSecurityGroupRefVO_.securityGroupUuid) + .listValues(); + + if (sgUuids == null || sgUuids.isEmpty()) { + logger.warn(String.format("No security groups found for vmNics: " + vmNicUuids)); + completion.success(); + return; + } + + Set allRelatedSgUuids = new HashSet<>(sgUuids); + + List remoteSGUuids = Q.New(SecurityGroupRuleVO.class) + .in(SecurityGroupRuleVO_.remoteSecurityGroupUuid, sgUuids) + .select(SecurityGroupRuleVO_.securityGroupUuid) + .listValues(); + + allRelatedSgUuids.addAll(remoteSGUuids); + + Set vmUuidsToRefresh = new HashSet<>(); + + vmUuidsToRefresh.add(servedVm.getVmInventory().getUuid()); + + List vmUuids = Q.New(VmNicSecurityGroupRefVO.class) + .in(VmNicSecurityGroupRefVO_.securityGroupUuid, new ArrayList<>(allRelatedSgUuids)) + .select(VmNicSecurityGroupRefVO_.vmInstanceUuid) + .listValues(); + + vmUuidsToRefresh.addAll(vmUuids); + + FlowChain schain = FlowChainBuilder.newSimpleFlowChain().setName(String.format("apply-security-group-to-vm-%s", servedVm.getVmInventory().getUuid())); + schain.allowEmptyFlow(); + + Flow applyToCurrentVmFlow = new Flow() { + String __name__ = "apply-security-group-rules-to-current-vm"; + @Override - public void run(MessageReply reply) { - if (reply.isSuccess()) { - completion.success(); - } else { - completion.fail(reply.getError()); + public void run(FlowTrigger trigger, Map data) { + logger.debug(String.format("Applying security group rules to current VM[uuid:%s]", servedVm.getVmInventory().getUuid())); + + RefreshSecurityGroupRulesOnVmMsg msg = new RefreshSecurityGroupRulesOnVmMsg(); + msg.setVmInstanceUuid(servedVm.getVmInventory().getUuid()); + msg.setHostUuid(servedVm.getDestHost().getUuid()); + msg.setSgUuids(sgUuids); + msg.setOperation(servedVm.getCurrentVmOperation()); + bus.makeLocalServiceId(msg, SecurityGroupConstant.SERVICE_ID); + + bus.send(msg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + trigger.next(); + } else { + trigger.fail(operr("Failed to apply security group rules to current VM[uuid:%s]", + servedVm.getVmInventory().getUuid()) + .causedBy(reply.getError())); + } + } + }); + } + + @Override + public void rollback(FlowRollback rollback, Map data) { + logger.debug(String.format("No rollback needed for applying security group rules to current VM[uuid:%s]", servedVm.getVmInventory().getUuid())); + rollback.rollback(); + } + }; + + schain.then(applyToCurrentVmFlow); + + Flow applyToOtherVmsFlow = new Flow() { + String __name__ = "apply-security-group-rules-to-other-vms"; + + @Override + public void run(FlowTrigger trigger, Map data) { + Set otherVmUuids = new HashSet<>(vmUuidsToRefresh); + otherVmUuids.remove(servedVm.getVmInventory().getUuid()); + + if (otherVmUuids.isEmpty()) { + trigger.next(); + return; } + + List errs = Collections.synchronizedList(new ArrayList<>()); + + logger.debug(String.format("Applying security group rules to %d other VMs: %s", otherVmUuids.size(), otherVmUuids)); + + new While<>(otherVmUuids) + .each((vmUuid, wcompl) -> { + RefreshSecurityGroupRulesOnVmMsg msg = new RefreshSecurityGroupRulesOnVmMsg(); + msg.setVmInstanceUuid(vmUuid); + bus.makeTargetServiceIdByResourceUuid(msg, SecurityGroupConstant.SERVICE_ID, vmUuid); + + bus.send(msg, new CloudBusCallBack(wcompl) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("Failed to refresh security group rules for VM[uuid:%s]: %s", + vmUuid, reply.getError())); + errs.add(reply.getError()); + } + wcompl.done(); + } + }); + }) + .run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errs.isEmpty()) { + trigger.next(); + } else { + trigger.fail(operr("Failed to apply security group rules to some VMs")); + } + } + }); } - }); + + @Override + public void rollback(FlowRollback rollback, Map data) { + logger.debug("Rolling back security group application to other VMs... (no-op)"); + rollback.rollback(); + } + }; + + schain.then(applyToOtherVmsFlow); + + schain.error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode err, Map data) { + completion.fail(err); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).start(); } @Override @@ -115,6 +295,7 @@ public void releaseNetworkService(final VmInstanceSpec servedVm, Map sgUuids = syncSystemTagToVmNicSecurityGroup(vmInstanceInventory.getUuid()); + if (StringUtils.isEmpty(vmInstanceInventory.getHostUuid())) { + completion.success(); + return; + } + RefreshSecurityGroupRulesOnVmMsg msg = new RefreshSecurityGroupRulesOnVmMsg(); + msg.setVmInstanceUuid(vmInstanceInventory.getUuid()); + msg.setHostUuid(vmInstanceInventory.getHostUuid()); + msg.setSgUuids(sgUuids); + msg.setOperation(VmInstanceConstant.VmOperation.AttachNic); + bus.makeLocalServiceId(msg, SecurityGroupConstant.SERVICE_ID); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + completion.success(); + } else { + completion.fail(reply.getError()); + } + } + }); + } + + @Override + public void afterAttachNicRollback(String nicUuid, VmInstanceInventory vmInstanceInventory, NoErrorCompletion completion) { + logger.debug(String.format("securityGroupNetworkServiceExtension after attach nic starting rollback, hardDelete VmNicSecurityGroupRefVO data")); + SQL.New(VmNicSecurityGroupRefVO.class) + .eq(VmNicSecurityGroupRefVO_.vmNicUuid, nicUuid) + .eq(VmNicSecurityGroupRefVO_.vmNicUuid, vmInstanceInventory.getUuid()).hardDelete(); + completion.done(); + } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, NetworkServiceProviderType providerType, Completion completion) { + completion.success(); + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNumQuotaDefinition.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNumQuotaDefinition.java new file mode 100644 index 00000000000..5ae38e86c99 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupNumQuotaDefinition.java @@ -0,0 +1,26 @@ +package org.zstack.network.securitygroup; + +import org.zstack.core.db.Q; +import org.zstack.header.identity.AccountResourceRefVO; +import org.zstack.header.identity.AccountResourceRefVO_; +import org.zstack.header.identity.quota.QuotaDefinition; + +public class SecurityGroupNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return SecurityGroupQuotaConstant.SG_NUM; + } + + @Override + public Long getDefaultValue() { + return SecurityGroupQuotaGlobalConfig.SG_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + return Q.New(AccountResourceRefVO.class) + .eq(AccountResourceRefVO_.accountUuid, accountUuid) + .eq(AccountResourceRefVO_.resourceType, SecurityGroupVO.class.getSimpleName()) + .count(); + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupOwner.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupOwner.java new file mode 100644 index 00000000000..3321c3a7030 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupOwner.java @@ -0,0 +1,12 @@ +package org.zstack.network.securitygroup; + +public enum SecurityGroupOwner { + USER("user"), + IAM2("iam2"); + + public final String name; + + SecurityGroupOwner(String owner) { + name = owner; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupProviderFactory.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupProviderFactory.java index 4472ba0c80c..8359f0a4de3 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupProviderFactory.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupProviderFactory.java @@ -11,6 +11,7 @@ import org.zstack.header.network.l2.APICreateL2NetworkMsg; import org.zstack.header.network.l2.L2NetworkCreateExtensionPoint; import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.VSwitchType; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.service.*; @@ -56,6 +57,11 @@ public void afterCreateL2Network(L2NetworkInventory l2Network) { if (!supportedL2NetworkTypes.contains(l2Network.getType())) { return; } + + VSwitchType vSwitchType = VSwitchType.valueOf(l2Network.getvSwitchType()); + if (vSwitchType.getSdnControllerType() != null) { + return; + } SimpleQuery q = dbf.createQuery(NetworkServiceProviderVO.class); q.add(NetworkServiceProviderVO_.type, Op.EQ, SecurityGroupConstant.SECURITY_GROUP_PROVIDER_TYPE); diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleAction.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleAction.java new file mode 100644 index 00000000000..41d6b203e7a --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleAction.java @@ -0,0 +1,22 @@ +package org.zstack.network.securitygroup; + +public enum SecurityGroupRuleAction { + DROP, ACCEPT; + + public static Boolean isValid(String value) { + if (value == null) { + return false; + } + + try { + SecurityGroupRuleAction.valueOf(value); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + public static String getAllAction() { + return String.format("%s/%s", DROP.toString(), ACCEPT.toString()); + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventory.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventory.java index 5fa5e051e0a..7e777771cdb 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventory.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventory.java @@ -21,10 +21,16 @@ "uuid": "02bc62abee88444ca3e2c434a1b8fdea", "securityGroupUuid": "3904b4837f0c4f539063777ed463b648", "type": "Ingress", -"startPort": 10, -"endPort": 10, -"protocol": "UDP", -"allowedCidr": "192.168.0.1/0", +"priority": 1, +"ipVersion": 4, +"protocol": "TCP", +"srcIpRange": "10.10.10.1,10.10.10.2", +"dstIpRange": "20.20.20.1,20.20.20.1", +"srcPortRange": "10,20", +"dstPortRange": "30,40", +"action": "RETURN", +"state": "Enabled, +"remoteSecurityGroupUuid": "7c224d3f5ad74520ac4dd6c81def0d8e", "createDate": "May 14, 2014 9:38:24 PM", "lastOpDate": "May 14, 2014 9:38:24 PM" } @@ -60,18 +66,6 @@ public class SecurityGroupRuleInventory { private Integer ipVersion; - /** - * @desc - * start port - * @choices 0 - 65535 - */ - private Integer startPort; - /** - * @desc - * end port - * @choices 0 - 65535 - */ - private Integer endPort; /** * @desc * network protocol type @@ -83,12 +77,42 @@ public class SecurityGroupRuleInventory { private String protocol; private String state; + + private Integer priority; + + private String description; + /** - * @desc source CIDR the rule applies to. If set, the rule only applies to traffic from this CIDR. If omitted, the rule - * applies to all traffic - * @nullable + * @desc source ip address range + * @choices 10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24 */ - private String allowedCidr; + private String srcIpRange; + + /** + * @desc destination ip address range + * @choices 10.0.0.1,10.0.0.2-10.0.0.20,10.1.1.0/24 + */ + private String dstIpRange; + + /** + * @desc source ip port range + * @choices 1000,1001,1002-1005,1008 + */ + private String srcPortRange; + + /** + * @desc destination ip port range + * @choices 1000,1001,1002-1005,1008 + */ + private String dstPortRange; + + /** + * @desc rule default target + * @choices + * - RETURN / DROP + */ + private String action; + /** * @desc remote security group uuids for rules between groups */ @@ -96,6 +120,13 @@ public class SecurityGroupRuleInventory { /** * @desc the time this resource gets created */ + + private String allowedCidr; + + private Integer startPort; + + private Integer endPort; + private Timestamp createDate; /** * @desc last time this resource gets operated @@ -106,18 +137,25 @@ public SecurityGroupRuleInventory() { } protected SecurityGroupRuleInventory(SecurityGroupRuleVO vo) { - this.setState(vo.getState().toString()); this.setUuid(vo.getUuid()); this.setSecurityGroupUuid(vo.getSecurityGroupUuid()); + this.setState(vo.getState().toString()); + this.setRemoteSecurityGroupUuid(vo.getRemoteSecurityGroupUuid()); + this.setDescription(vo.getDescription()); this.setType(vo.getType().toString()); - this.setStartPort(vo.getStartPort()); - this.setEndPort(vo.getEndPort()); + this.setIpVersion(vo.getIpVersion()); this.setProtocol(vo.getProtocol().toString()); + this.setPriority(vo.getPriority()); + this.setSrcIpRange(vo.getSrcIpRange()); + this.setDstIpRange(vo.getDstIpRange()); + this.setSrcPortRange(vo.getSrcPortRange()); + this.setDstPortRange(vo.getDstPortRange()); + this.setAction(vo.getAction().toString()); this.setAllowedCidr(vo.getAllowedCidr()); - this.setRemoteSecurityGroupUuid(vo.getRemoteSecurityGroupUuid()); + this.setStartPort(vo.getStartPort()); + this.setEndPort(vo.getEndPort()); this.setCreateDate(vo.getCreateDate()); this.setLastOpDate(vo.getLastOpDate()); - this.setIpVersion(vo.getIpVersion()); } public static SecurityGroupRuleInventory valueOf(SecurityGroupRuleVO vo) { @@ -165,20 +203,12 @@ public void setType(String type) { this.type = type; } - public int getStartPort() { - return startPort; + public String getDescription() { + return description; } - public void setStartPort(int startPort) { - this.startPort = startPort; - } - - public int getEndPort() { - return endPort; - } - - public void setEndPort(int endPort) { - this.endPort = endPort; + public void setDescription(String description) { + this.description = description; } public String getProtocol() { @@ -189,12 +219,52 @@ public void setProtocol(String protocol) { this.protocol = protocol; } - public String getAllowedCidr() { - return allowedCidr; + public Integer getPriority() { + return priority; } - public void setAllowedCidr(String allowedCidr) { - this.allowedCidr = allowedCidr; + public void setPriority(Integer priority) { + this.priority = priority; + } + + public String getSrcIpRange() { + return srcIpRange; + } + + public void setSrcIpRange(String srcIpRange) { + this.srcIpRange = srcIpRange; + } + + public String getDstIpRange() { + return dstIpRange; + } + + public void setDstIpRange(String dstIpRange) { + this.dstIpRange = dstIpRange; + } + + public String getDstPortRange() { + return dstPortRange; + } + + public String getSrcPortRange() { + return srcPortRange; + } + + public void setSrcPortRange(String srcPortRange) { + this.srcPortRange = srcPortRange; + } + + public void setDstPortRange(String dstPortRange) { + this.dstPortRange = dstPortRange; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; } public void setRemoteSecurityGroupUuid(String remoteSecurityGroupUuid) { @@ -229,15 +299,49 @@ public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + public String getAllowedCidr() { + return allowedCidr; + } + + public void setAllowedCidr(String allowedCidr) { + this.allowedCidr = allowedCidr; + } + + public Integer getStartPort() { + return startPort; + } + + public void setStartPort(Integer startPort) { + this.startPort = startPort; + } + + public Integer getEndPort() { + return endPort; + } + + public void setEndPort(Integer endPort) { + this.endPort = endPort; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); + sb.append(String.format("uuid: %s,", this.uuid)); + sb.append(String.format("securityGroupUuid: %s,", this.securityGroupUuid)); + sb.append(String.format("remoteSecurityGroupUuid: %s,", this.remoteSecurityGroupUuid)); + sb.append(String.format("description: %s,", this.description)); sb.append(String.format("type: %s,", this.type)); + sb.append(String.format("priority: %d,", this.priority)); sb.append(String.format("ipVersion: %d,", this.ipVersion)); sb.append(String.format("protocol: %s,", this.protocol)); - sb.append(String.format("startPort: %s,", this.startPort)); - sb.append(String.format("endPort: %s,", this.endPort)); + sb.append(String.format("srcIpRange: %s,", this.srcIpRange)); + sb.append(String.format("dstIpRange: %s,", this.dstIpRange)); + sb.append(String.format("srcPortRange: %s,", this.srcPortRange)); + sb.append(String.format("dstPortRange: %s,", this.dstPortRange)); + sb.append(String.format("action: %s,", this.action)); sb.append(String.format("allowedCidr: %s", this.allowedCidr)); + sb.append(String.format("startPort: %s", this.startPort)); + sb.append(String.format("endPort: %s", this.endPort)); return sb.toString(); } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventoryDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventoryDoc_zh_cn.groovy index 7fcd2d3eca1..04bff940ddc 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventoryDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleInventoryDoc_zh_cn.groovy @@ -1,9 +1,6 @@ package org.zstack.network.securitygroup import java.lang.Integer -import java.lang.Integer -import java.lang.Integer -import java.sql.Timestamp import java.sql.Timestamp doc { @@ -35,26 +32,62 @@ doc { since "3.1" } field { - name "startPort" - desc "如果协议是TCP/UDP, 它是端口范围(port range)的起始端口号; 如果协议是ICMP, 它是ICMP类型(type)" - type "Integer" - since "0.6" + name "protocol" + desc "流量协议类型" + type "String" + since "0.6" + } + field { + name "state" + desc "规则的可用状态" + type "String" + since "0.6" + } + field { + name "priority" + desc "规则优先级" + type "Integer" + since "4.7.21" + } + field { + name "description" + desc "规则描述" + type "String" + since "4.7.21" + } + field { + name "srcIpRange" + desc "源IP范围" + type "String" + since "4.7.21" } field { - name "endPort" - desc "如果协议是TCP/UDP, 它是端口范围(port range)的起始端口号; 如果协议是ICMP, 它是ICMP类型(type)" - type "Integer" - since "0.6" + name "dstIpRange" + desc "目的IP范围" + type "String" + since "4.7.21" } field { - name "protocol" - desc "流量协议类型" + name "srcPortRange" + desc "源端口范围,当前版本未实现" type "String" - since "0.6" + since "4.7.21" + } + field { + name "dstPortRange" + desc "目的端口范围" + type "String" + since "4.7.21" + } + field { + name "action" + desc "规则的默认动作" + type "String" + since "4.7.21" } field { - name "state" - desc "规则的可用状态, 当前版本未实现" + name "remoteSecurityGroupUuid" + desc "" type "String" since "0.6" } @@ -65,9 +98,15 @@ doc { since "0.6" } field { - name "remoteSecurityGroupUuid" - desc "" - type "String" + name "startPort" + desc "如果协议是TCP/UDP, 它是端口范围(port range)的起始端口号; 如果协议是ICMP, 它是ICMP类型(type)" + type "Integer" + since "0.6" + } + field { + name "endPort" + desc "如果协议是TCP/UDP, 它是端口范围(port range)的起始端口号; 如果协议是ICMP, 它是ICMP类型(type)" + type "Integer" since "0.6" } field { diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleProtocolType.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleProtocolType.java index 8ab56040890..379c68bfb31 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleProtocolType.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleProtocolType.java @@ -7,5 +7,22 @@ public enum SecurityGroupRuleProtocolType { TCP, UDP, ICMP, - ALL + ALL; + + public static Boolean isValid(String value) { + if (value == null) { + return false; + } + + try { + SecurityGroupRuleProtocolType.valueOf(value); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + public static String getAllProtocol() { + return String.format("%s/%s/%s/%s", TCP.toString(), UDP.toString(), ICMP.toString(), ALL.toString()); + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleState.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleState.java index 37975840094..348415dcc4a 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleState.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleState.java @@ -4,5 +4,22 @@ */ public enum SecurityGroupRuleState { Enabled, - Disabled + Disabled; + + public static Boolean isValid(String value) { + if (value == null) { + return false; + } + + try { + SecurityGroupRuleState.valueOf(value); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + public static String getAllState() { + return String.format("%s/%s", Enabled.toString(), Disabled.toString()); + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleTO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleTO.java index bf8bd463bd4..29f559c5aff 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleTO.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleTO.java @@ -5,74 +5,24 @@ import java.util.List; public class SecurityGroupRuleTO { - public static final String ACTION_CODE_APPLY_RULE = "applyRule"; - public static final String ACTION_CODE_DELETE_CHAIN = "deleteChain"; + // public static final String ACTION_CODE_APPLY_RULE = "applyRule"; + // public static final String ACTION_CODE_DELETE_CHAIN = "deleteChain"; + // public static final String ACTION_CODE_DELETE_RULE = "deleteRule"; + // public static final String ACTION_CODE_REFRESH_RULE = "refreshRule"; - private String vmNicInternalName; + private String securityGroupUuid; private List rules; - private String ingressDefaultPolicy; - private String egressDefaultPolicy; - private String vmNicUuid; - private String vmNicMac; - private List vmNicIp; - private List securityGroupBaseRules; - private String actionCode = ACTION_CODE_APPLY_RULE; - private Integer ipVersion; + // private String actionCode = ACTION_CODE_APPLY_RULE; - public String getVmNicMac() { - return vmNicMac; - } - - public void setVmNicMac(String vmNicMac) { - this.vmNicMac = vmNicMac; - } - - public List getVmNicIp() { - return vmNicIp; - } - - public void setVmNicIp(List vmNicIp) { - this.vmNicIp = vmNicIp; - } - - public String getActionCode() { - return actionCode; - } - - public void setActionCode(String actionCode) { - this.actionCode = actionCode; - } - - public String getVmNicUuid() { - return vmNicUuid; - } - - public void setVmNicUuid(String vmNicUuid) { - this.vmNicUuid = vmNicUuid; - } - - public String getIngressDefaultPolicy() { - return ingressDefaultPolicy; - } - - public void setIngressDefaultPolicy(String ingressDefaultPolicy) { - this.ingressDefaultPolicy = ingressDefaultPolicy; - } - public String getEgressDefaultPolicy() { - return egressDefaultPolicy; + public String getSecurityGroupUuid() { + return securityGroupUuid; } - public void setEgressDefaultPolicy(String egressDefaultPolicy) { - this.egressDefaultPolicy = egressDefaultPolicy; + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; } - public String getVmNicInternalName() { - return vmNicInternalName; - } - public void setVmNicInternalName(String vmNicInternalName) { - this.vmNicInternalName = vmNicInternalName; - } public List getRules() { if (rules == null) { rules = new ArrayList(); @@ -84,44 +34,35 @@ public void setRules(List rules) { this.rules = rules; } - public void setSecurityGroupBaseRules(List securityGroupBaseRules) { - this.securityGroupBaseRules = securityGroupBaseRules; - } - - public List getSecurityGroupBaseRules() { - return securityGroupBaseRules; - } - - public Integer getIpVersion() { - return ipVersion; - } - - public void setIpVersion(Integer ipVersion) { - this.ipVersion = ipVersion; - } - @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append(String.format("\nvmNicInternalName: %s", vmNicInternalName)); - for (RuleTO to : rules) { - sb.append(String.format("\n%s", to.toFullString())); - } + sb.append(String.format("\nrules: %s", rules)); return sb.toString(); } + + // @Override + // public String toString() { + // StringBuilder sb = new StringBuilder(); + // sb.append(String.format("\nvmNicInternalName: %s", vmNicInternalName)); + // for (RuleTO to : rules) { + // sb.append(String.format("\n%s", to.toFullString())); + // } + // return sb.toString(); + // } - @Override - public int hashCode() { - return vmNicInternalName.hashCode(); - } + // @Override + // public int hashCode() { + // return vmNicInternalName.hashCode(); + // } - @Override - public boolean equals(Object obj) { - if (!(obj instanceof SecurityGroupRuleTO)) { - return false; - } - - SecurityGroupRuleTO rto = (SecurityGroupRuleTO)obj; - return rto.getVmNicInternalName().equals(this.getVmNicInternalName()); - } + // @Override + // public boolean equals(Object obj) { + // if (!(obj instanceof SecurityGroupRuleTO)) { + // return false; + // } + + // SecurityGroupRuleTO rto = (SecurityGroupRuleTO)obj; + // return rto.getVmNicInternalName().equals(this.getVmNicInternalName()); + // } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleType.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleType.java index b8358b7b69e..f92d1af8d56 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleType.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleType.java @@ -5,5 +5,22 @@ @PythonClass public enum SecurityGroupRuleType { Ingress, - Egress, + Egress; + + public static Boolean isValid(String value) { + if (value == null) { + return false; + } + + try { + SecurityGroupRuleType.valueOf(value); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + public static String getAllType() { + return String.format("%s/%s", Ingress.toString(), Egress.toString()); + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO.java index c0bb3de727e..911f5d310a4 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO.java @@ -28,12 +28,27 @@ public class SecurityGroupRuleVO extends ResourceVO { @Column private Integer ipVersion; - + @Column - private int startPort; - + private int priority; + @Column - private int endPort; + private String description; + + @Column + private String action; + + @Column + private String srcIpRange; + + @Column + private String dstIpRange; + + @Column + private String srcPortRange; + + @Column + private String dstPortRange; @Column @Enumerated(EnumType.STRING) @@ -43,9 +58,6 @@ public class SecurityGroupRuleVO extends ResourceVO { @Enumerated(EnumType.STRING) private SecurityGroupRuleState state = SecurityGroupRuleState.Enabled; - @Column - private String allowedCidr; - @Column @ForeignKey(parentEntityClass = SecurityGroupVO.class, onDeleteAction = ReferenceOption.CASCADE) private String remoteSecurityGroupUuid; @@ -56,11 +68,75 @@ public class SecurityGroupRuleVO extends ResourceVO { @Column private Timestamp lastOpDate; + @Column + private int startPort; + + @Column + private int endPort; + + @Column + private String allowedCidr; + @PreUpdate private void preUpdate() { lastOpDate = null; } + public int getPriority() { + return priority; + } + public void setPriority(int priority) { + this.priority = priority; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getSrcIpRange() { + return srcIpRange; + } + + public void setSrcIpRange(String srcIpRange) { + this.srcIpRange = srcIpRange; + } + + public String getDstIpRange() { + return dstIpRange; + } + + public void setDstIpRange(String dstIprange) { + this.dstIpRange = dstIprange; + } + + public String getSrcPortRange() { + return srcPortRange; + } + + public void setSrcPortRange(String srcPortRange) { + this.srcPortRange = srcPortRange; + } + + public String getDstPortRange() { + return dstPortRange; + } + + public void setDstPortRange(String dstPortRange) { + this.dstPortRange = dstPortRange; + } + public SecurityGroupRuleState getState() { return state; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO_.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO_.java index 4d8acee42d4..3f011bb5e16 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO_.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupRuleVO_.java @@ -5,7 +5,6 @@ import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.StaticMetamodel; import java.sql.Timestamp; -import java.util.Date; @StaticMetamodel(SecurityGroupRuleVO.class) public class SecurityGroupRuleVO_ extends ResourceVO_ { @@ -13,11 +12,18 @@ public class SecurityGroupRuleVO_ extends ResourceVO_ { public static volatile SingularAttribute type; public static volatile SingularAttribute state; public static volatile SingularAttribute ipVersion; + public static volatile SingularAttribute protocol; + public static volatile SingularAttribute remoteSecurityGroupUuid; + public static volatile SingularAttribute description; + public static volatile SingularAttribute priority; + public static volatile SingularAttribute action; + public static volatile SingularAttribute srcIpRange; + public static volatile SingularAttribute dstIpRange; + public static volatile SingularAttribute srcPortRange; + public static volatile SingularAttribute dstPortRange; public static volatile SingularAttribute startPort; public static volatile SingularAttribute endPort; - public static volatile SingularAttribute protocol; public static volatile SingularAttribute allowedCidr; - public static volatile SingularAttribute remoteSecurityGroupUuid; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupSdnBackend.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupSdnBackend.java new file mode 100644 index 00000000000..c134674f9a9 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupSdnBackend.java @@ -0,0 +1,14 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.core.Completion; +import org.zstack.header.vm.VmNicVO; + +import java.util.List; + +public interface SecurityGroupSdnBackend { + void createSecurityGroup(SecurityGroupInventory sg, Completion completion); + + void updateSecurityGroup(VmNicSecurityGroupTo to, Completion completion); + + List getCandidateVmNic(String sgId, String accountUuid); +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupState.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupState.java index 0cd6ac1bafe..228bfa0f89e 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupState.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupState.java @@ -8,5 +8,18 @@ */ public enum SecurityGroupState { Enabled, - Disabled + Disabled; + + public static Boolean isValid(String value) { + if (value == null) { + return false; + } + + try { + SecurityGroupState.valueOf(value); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupSystemTags.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupSystemTags.java new file mode 100644 index 00000000000..a15583881c2 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupSystemTags.java @@ -0,0 +1,11 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.tag.TagDefinition; +import org.zstack.tag.PatternedSystemTag; + +@TagDefinition +public class SecurityGroupSystemTags { + public static String SDN_CONTROLLER_UUID_TOKEN = "SdnControllerUuid"; + public static PatternedSystemTag SDN_CONTROLLER_UUID = new PatternedSystemTag( + String.format("SdnControllerUuid::{%s}", SDN_CONTROLLER_UUID_TOKEN), SecurityGroupVO.class); +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupTo.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupTo.java new file mode 100644 index 00000000000..141e53798c8 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupTo.java @@ -0,0 +1,72 @@ +package org.zstack.network.securitygroup; + +import java.util.ArrayList; +import java.util.List; + +public class SecurityGroupTo { + public static final String ACTION_CODE_APPLY_CHAIN = "applyChain"; + public static final String ACTION_CODE_DELETE_CHAIN = "deleteChain"; + private String securityGroupUuid; + private String securityGroupName; + private Integer internalId; + private List securityGroupVmIps = new ArrayList<>(); + private List securityGroupVmIp6s = new ArrayList<>(); + private String actionCode; + private List rules = new ArrayList<>(); + + public String getSecurityGroupUuid() { + return securityGroupUuid; + } + + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; + } + + public String getSecurityGroupName() { + return securityGroupName; + } + + public void setSecurityGroupName(String securityGroupName) { + this.securityGroupName = securityGroupName; + } + + public Integer getInternalId() { + return internalId; + } + + public void setInternalId(Integer internalId) { + this.internalId = internalId; + } + + public List getSecurityGroupVmIps() { + return securityGroupVmIps; + } + + public void setSecurityGroupVmIps(List securityGroupVmIps) { + this.securityGroupVmIps = securityGroupVmIps; + } + + public List getSecurityGroupVmIp6s() { + return securityGroupVmIp6s; + } + + public void setSecurityGroupVmIp6s(List securityGroupVmIp6s) { + this.securityGroupVmIp6s = securityGroupVmIp6s; + } + + public String getActionCode() { + return actionCode; + } + + public void setActionCode(String actionCode) { + this.actionCode = actionCode; + } + + public List getRules() { + return rules; + } + + public void setRules(List rules) { + this.rules = rules; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupUpgradeExtension.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupUpgradeExtension.java new file mode 100644 index 00000000000..5e5e3597ac7 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupUpgradeExtension.java @@ -0,0 +1,244 @@ +package org.zstack.network.securitygroup; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.Component; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; + +public class SecurityGroupUpgradeExtension implements Component { + private static final CLogger logger = Utils.getLogger(SecurityGroupUpgradeExtension.class); + + @Autowired + DatabaseFacade dbf; + + private void upgradeSecurityGroup() { + + upgradeSecurityGroupRef(); + + List sgs = dbf.listAll(SecurityGroupVO.class); + if (sgs.isEmpty()) { + return; + } + + sgs.forEach(sg -> { + List rules = Q.New(SecurityGroupRuleVO.class).eq(SecurityGroupRuleVO_.securityGroupUuid, sg.getUuid()).list(); + + List ingressRules = rules.stream().filter(r -> r.getType().equals(SecurityGroupRuleType.Ingress)).collect(Collectors.toList()); + List egressRules = rules.stream().filter(r -> r.getType().equals(SecurityGroupRuleType.Egress)).collect(Collectors.toList()); + + upgradeSecurityGroupRules(sg.getUuid(), ingressRules, SecurityGroupRuleType.Ingress); + upgradeSecurityGroupRules(sg.getUuid(), egressRules, SecurityGroupRuleType.Egress); + }); + } + + private SecurityGroupRuleVO getDefaultSecurityGroupRule(List rules, SecurityGroupRuleType type, Integer ipVersion) { + String cidr = ipVersion == IPv6Constants.IPv4 ? SecurityGroupConstant.WORLD_OPEN_CIDR : SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6; + + for (SecurityGroupRuleVO r : rules) { + if (r.getRemoteSecurityGroupUuid() == null || r.getIpVersion() == null) { + continue; + } + if (r.getType().equals(type) && r.getIpVersion().equals(ipVersion) && r.getAllowedCidr().equals(cidr) + && r.getStartPort() == -1 && r.getEndPort() == -1 && r.getProtocol().equals(SecurityGroupRuleProtocolType.ALL) + && r.getRemoteSecurityGroupUuid().equals(r.getSecurityGroupUuid())) { + + return r; + } + } + + return null; + } + + private void upgradeSecurityGroupRules(String sgUuid, List rules, SecurityGroupRuleType type) { + List defaultRules = new ArrayList<>(); + SecurityGroupRuleVO ip4DefaultRule = getDefaultSecurityGroupRule(rules, type, IPv6Constants.IPv4); + SecurityGroupRuleVO ip6DefaultRule = getDefaultSecurityGroupRule(rules, type, IPv6Constants.IPv6); + + if (ip4DefaultRule == null) { + SecurityGroupRuleVO rule = new SecurityGroupRuleVO(); + rule.setUuid(Platform.getUuid()); + rule.setPriority(SecurityGroupConstant.DEFAULT_RULE_PRIORITY); + rule.setDescription(SecurityGroupConstant.DEFAULT_RULE_DESCRIPTION); + rule.setAllowedCidr(SecurityGroupConstant.WORLD_OPEN_CIDR); + rule.setSecurityGroupUuid(sgUuid); + rule.setStartPort(-1); + rule.setEndPort(-1); + rule.setProtocol(SecurityGroupRuleProtocolType.ALL); + rule.setType(type); + rule.setIpVersion(IPv6Constants.IPv4); + rule.setRemoteSecurityGroupUuid(sgUuid); + rule.setAction(SecurityGroupRuleAction.ACCEPT.toString()); + rule.setState(SecurityGroupRuleState.Disabled); + dbf.persist(rule); + } else { + ip4DefaultRule.setPriority(SecurityGroupConstant.DEFAULT_RULE_PRIORITY); + ip4DefaultRule.setDescription(SecurityGroupConstant.DEFAULT_RULE_DESCRIPTION); + defaultRules.add(ip4DefaultRule); + } + + if (ip6DefaultRule == null) { + SecurityGroupRuleVO rule = new SecurityGroupRuleVO(); + rule.setUuid(Platform.getUuid()); + rule.setPriority(SecurityGroupConstant.DEFAULT_RULE_PRIORITY); + rule.setDescription(SecurityGroupConstant.DEFAULT_RULE_DESCRIPTION); + rule.setAllowedCidr(SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6); + rule.setSecurityGroupUuid(sgUuid); + rule.setStartPort(-1); + rule.setEndPort(-1); + rule.setProtocol(SecurityGroupRuleProtocolType.ALL); + rule.setType(type); + rule.setIpVersion(IPv6Constants.IPv6); + rule.setRemoteSecurityGroupUuid(sgUuid); + rule.setAction(SecurityGroupRuleAction.ACCEPT.toString()); + rule.setState(SecurityGroupRuleState.Disabled); + dbf.persist(rule); + } else { + ip6DefaultRule.setPriority(SecurityGroupConstant.DEFAULT_RULE_PRIORITY); + ip6DefaultRule.setDescription(SecurityGroupConstant.DEFAULT_RULE_DESCRIPTION); + defaultRules.add(ip6DefaultRule); + } + + if (!defaultRules.isEmpty()) { + dbf.updateCollection(defaultRules); + } + + boolean isUpdate = rules.stream().anyMatch(r -> r.getPriority() == SecurityGroupConstant.LOWEST_RULE_PRIORITY); + if (!isUpdate) { + return; + } + + List userRules = rules.stream().filter(r -> r.getPriority() != SecurityGroupConstant.DEFAULT_RULE_PRIORITY) + .sorted(Comparator.comparing(SecurityGroupRuleVO::getCreateDate)).collect(Collectors.toList()); + if (userRules.isEmpty()) { + return; + } + + if (SecurityGroupRuleType.Egress.equals(type)) { + List pvos = SQL.New("select policy from VmNicSecurityPolicyVO policy, VmNicVO nic, VmNicSecurityGroupRefVO ref" + + " where policy.vmNicUuid = nic.uuid" + + " and ref.securityGroupUuid = :sgUuid" + + " and ref.vmNicUuid = nic.uuid", VmNicSecurityPolicyVO.class) + .param("sgUuid", sgUuid) + .list(); + pvos.forEach(pvo -> { + pvo.setEgressPolicy(VmNicSecurityPolicy.DENY.toString()); + }); + + dbf.updateCollection(pvos); + } + + userRules.forEach(r -> { + r.setPriority(userRules.indexOf(r) + 1); + if (!SecurityGroupConstant.WORLD_OPEN_CIDR.equals(r.getAllowedCidr()) && !SecurityGroupConstant.WORLD_OPEN_CIDR_IPV6.equals(r.getAllowedCidr())) { + if (SecurityGroupRuleType.Ingress.equals(type)) { + r.setSrcIpRange(r.getAllowedCidr()); + } else { + r.setDstIpRange(r.getAllowedCidr()); + } + } + + if (r.getStartPort() != -1) { + if (r.getStartPort() == r.getEndPort()) { + r.setDstPortRange(String.valueOf(r.getStartPort())); + } else { + r.setDstPortRange(String.format("%d-%d", r.getStartPort(), r.getEndPort())); + } + } + }); + + dbf.updateCollection(userRules); + } + + private void upgradeSecurityGroupRef() { + List refs = Q.New(VmNicSecurityGroupRefVO.class).list(); + if (refs.isEmpty()) { + return; + } + + List pvos = Q.New(VmNicSecurityPolicyVO.class).list(); + + Map> nicMap = new HashMap<>(); + List toCreate = new ArrayList<>(); + + for (VmNicSecurityGroupRefVO ref : refs) { + if (!nicMap.containsKey(ref.getVmNicUuid())) { + nicMap.put(ref.getVmNicUuid(), new ArrayList<>()); + } + nicMap.get(ref.getVmNicUuid()).add(ref); + } + + nicMap.keySet().stream().forEach(nicUuid -> { + if (pvos.stream().anyMatch(pvo -> pvo.getVmNicUuid().equals(nicUuid))) { + return; + } + VmNicSecurityPolicyVO vo = new VmNicSecurityPolicyVO(); + vo.setUuid(Platform.getUuid()); + vo.setVmNicUuid(nicUuid); + vo.setIngressPolicy(VmNicSecurityPolicy.DENY.toString()); + vo.setEgressPolicy(VmNicSecurityPolicy.ALLOW.toString()); + toCreate.add(vo); + }); + + if (!toCreate.isEmpty()) { + dbf.persistCollection(toCreate); + } + + nicMap.values().forEach(refsOfNic -> { + boolean isUpdate = refsOfNic.stream().anyMatch(r -> r.getPriority() == -1); + if (!isUpdate) { + return; + } + + Map sgMap = new HashMap<>(); + List toDeleteDuplicate = new ArrayList<>(); + List toUpdate = new ArrayList<>(); + refsOfNic.forEach(ref -> { + if (!sgMap.containsKey(ref.getSecurityGroupUuid())) { + sgMap.put(ref.getSecurityGroupUuid(), ref.getSecurityGroupUuid()); + toUpdate.add(ref); + } else { + toDeleteDuplicate.add(ref); + } + }); + + if (!toDeleteDuplicate.isEmpty()) { + dbf.removeCollection(toDeleteDuplicate, VmNicSecurityGroupRefVO.class); + } + + if (!toUpdate.isEmpty()) { + List sortedRefs = toUpdate.stream().sorted(Comparator.comparing(VmNicSecurityGroupRefVO::getCreateDate)).collect(Collectors.toList()); + sortedRefs.forEach(ref -> { + ref.setPriority(sortedRefs.indexOf(ref) + 1); + }); + dbf.updateCollection(sortedRefs); + } + }); + } + + @Override + public boolean start() { + + if (SecurityGroupGlobalProperty.UPGRADE_SECURITY_GROUP) { + upgradeSecurityGroup(); + } + + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO.java index ba7ebc473ab..cb5fa5fcbc1 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO.java @@ -2,7 +2,6 @@ import org.zstack.header.identity.OwnedByAccount; import org.zstack.header.vo.BaseResource; -import org.zstack.header.vo.EntityGraph; import org.zstack.header.vo.Index; import org.zstack.header.vo.ResourceVO; @@ -33,6 +32,9 @@ public class SecurityGroupVO extends ResourceVO implements OwnedByAccount { @Deprecated private Integer ipVersion; + @Column + private String vSwitchType; + @Column private Timestamp createDate; @@ -138,4 +140,12 @@ public Integer getIpVersion() { public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + + public String getvSwitchType() { + return vSwitchType; + } + + public void setvSwitchType(String vSwitchType) { + this.vSwitchType = vSwitchType; + } } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO_.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO_.java index 98cf7f31abe..18072ff7279 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO_.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/SecurityGroupVO_.java @@ -13,6 +13,7 @@ public class SecurityGroupVO_ extends ResourceVO_ { public static volatile SingularAttribute state; public static volatile SingularAttribute internalId; public static volatile SingularAttribute ipVersion; + public static volatile SingularAttribute vSwitchType; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupMessage.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupMessage.java new file mode 100644 index 00000000000..7ae3948208e --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupMessage.java @@ -0,0 +1,5 @@ +package org.zstack.network.securitygroup; + +public interface VmNicSecurityGroupMessage { + String getVmNicUuid(); +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventory.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventory.java index 4da3487f5e8..06ba7f37e02 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventory.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventory.java @@ -30,6 +30,7 @@ public class VmNicSecurityGroupRefInventory { @APINoSee private String uuid; + private Integer priority; private String vmNicUuid; private String securityGroupUuid; private String vmInstanceUuid; @@ -38,6 +39,7 @@ public class VmNicSecurityGroupRefInventory { protected VmNicSecurityGroupRefInventory(VmNicSecurityGroupRefVO vo) { this.setUuid(vo.getUuid()); + this.setPriority(vo.getPriority()); this.setVmNicUuid(vo.getVmNicUuid()); this.setSecurityGroupUuid(vo.getSecurityGroupUuid()); this.setCreateDate(vo.getCreateDate()); @@ -68,6 +70,14 @@ public void setUuid(String uuid) { this.uuid = uuid; } + public Integer getPriority() { + return priority; + } + + public void setPriority(Integer priority) { + this.priority = priority; + } + public String getVmNicUuid() { return vmNicUuid; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventoryDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventoryDoc_zh_cn.groovy index 3f1a5da95f5..c01dbebf176 100644 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventoryDoc_zh_cn.groovy +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefInventoryDoc_zh_cn.groovy @@ -1,12 +1,18 @@ package org.zstack.network.securitygroup -import java.sql.Timestamp +import java.lang.Integer import java.sql.Timestamp doc { title "安全组下的网卡清单" + field { + name "priority" + desc "安全组优先级" + type "Integer" + since "4.7.21" + } field { name "vmNicUuid" desc "云主机网卡UUID" diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefTO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefTO.java new file mode 100644 index 00000000000..3ee782fdba1 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefTO.java @@ -0,0 +1,22 @@ +package org.zstack.network.securitygroup; + +public class VmNicSecurityGroupRefTO { + private String securityGroupUuid; + private int priority; + + public String getSecurityGroupUuid() { + return securityGroupUuid; + } + + public void setSecurityGroupUuid(String securityGroupUuid) { + this.securityGroupUuid = securityGroupUuid; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO.java index cdeb126ceb7..00524b125e5 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO.java @@ -35,6 +35,9 @@ public class VmNicSecurityGroupRefVO { @ForeignKey(parentEntityClass = SecurityGroupVO.class, onDeleteAction = ReferenceOption.CASCADE) private String securityGroupUuid; + @Column + private int priority; + @Column private Timestamp createDate; @@ -70,6 +73,14 @@ public void setSecurityGroupUuid(String securityGroupUuid) { this.securityGroupUuid = securityGroupUuid; } + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } + public Timestamp getCreateDate() { return createDate; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO_.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO_.java index 6466f2a56ea..3d6d225b0a0 100755 --- a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO_.java +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupRefVO_.java @@ -10,6 +10,7 @@ public class VmNicSecurityGroupRefVO_ { public static volatile SingularAttribute vmNicUuid; public static volatile SingularAttribute vmInstanceUuid; public static volatile SingularAttribute securityGroupUuid; + public static volatile SingularAttribute priority; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupTo.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupTo.java new file mode 100644 index 00000000000..18e716a20c4 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityGroupTo.java @@ -0,0 +1,25 @@ +package org.zstack.network.securitygroup; + +import java.util.ArrayList; +import java.util.List; + +public class VmNicSecurityGroupTo { + List vmNics = new ArrayList<>(); + List groups = new ArrayList<>(); + + public List getVmNics() { + return vmNics; + } + + public void setVmNics(List vmNics) { + this.vmNics = vmNics; + } + + public List getGroups() { + return groups; + } + + public void setGroups(List groups) { + this.groups = groups; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicy.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicy.java new file mode 100644 index 00000000000..911c37d833e --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicy.java @@ -0,0 +1,20 @@ +package org.zstack.network.securitygroup; + +public enum VmNicSecurityPolicy { + ALLOW, + DENY; + + public static Boolean isValid(String value) { + if (value == null) { + return false; + } + + try { + VmNicSecurityPolicy.valueOf(value); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyInventory.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyInventory.java new file mode 100644 index 00000000000..b666ad01a41 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyInventory.java @@ -0,0 +1,102 @@ +package org.zstack.network.securitygroup; +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.rest.APINoSee; +import org.zstack.header.search.Inventory; +import org.zstack.header.vm.VmNicInventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = VmNicSecurityPolicyVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "vmNic", inventoryClass = VmNicInventory.class, + foreignKey = "vmNicUuid", expandedInventoryKey = "uuid"), +}) + +public class VmNicSecurityPolicyInventory { + @APINoSee + private String uuid; + private String vmNicUuid; + private String ingressPolicy; + private String egressPolicy; + private Timestamp createDate; + private Timestamp lastOpDate; + + protected VmNicSecurityPolicyInventory(VmNicSecurityPolicyVO vo) { + this.setUuid(vo.getUuid()); + this.setVmNicUuid(vo.getVmNicUuid()); + this.setIngressPolicy(vo.getIngressPolicy()); + this.setEgressPolicy(vo.getEgressPolicy()); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + } + + public VmNicSecurityPolicyInventory() { + + } + + public static VmNicSecurityPolicyInventory valueOf(VmNicSecurityPolicyVO vo) { + return new VmNicSecurityPolicyInventory(vo); + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList(vos.size()); + for (VmNicSecurityPolicyVO vo : vos) { + invs.add(VmNicSecurityPolicyInventory.valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid= uuid; + } + + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public String getIngressPolicy() { + return ingressPolicy; + } + + public void setIngressPolicy(String ingressPolicy) { + this.ingressPolicy = ingressPolicy; + } + + public String getEgressPolicy() { + return egressPolicy; + } + + public void setEgressPolicy(String egressPolicy) { + this.egressPolicy = egressPolicy; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate= createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate= lastOpDate; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyInventoryDoc_zh_cn.groovy b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..caa12324c62 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyInventoryDoc_zh_cn.groovy @@ -0,0 +1,39 @@ +package org.zstack.network.securitygroup + +import java.sql.Timestamp + +doc { + + title "网卡的安全策略" + + field { + name "vmNicUuid" + desc "云主机网卡UUID" + type "String" + since "4.7.21" + } + field { + name "ingressPolicy" + desc "网卡入方向安全策略" + type "String" + since "4.7.21" + } + field { + name "egressPolicy" + desc "网卡出方向安全策略" + type "String" + since "4.7.21" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.7.21" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.7.21" + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyVO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyVO.java new file mode 100644 index 00000000000..e787ed24cbb --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyVO.java @@ -0,0 +1,86 @@ +package org.zstack.network.securitygroup; + +import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ForeignKey.ReferenceOption; + +import javax.persistence.*; +import java.sql.Timestamp; + + +@Entity +@Table +public class VmNicSecurityPolicyVO { + @Id + @Column + private String uuid; + + @Column + @ForeignKey(parentEntityClass = VmNicVO.class, onDeleteAction = ReferenceOption.CASCADE) + private String vmNicUuid; + + @Column + private String ingressPolicy; + + @Column + private String egressPolicy; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public String getIngressPolicy() { + return ingressPolicy; + } + + public void setIngressPolicy(String ingressPolicy) { + this.ingressPolicy = ingressPolicy; + } + + public String getEgressPolicy() { + return egressPolicy; + } + + public void setEgressPolicy(String egressPolicy) { + this.egressPolicy = egressPolicy; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyVO_.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyVO_.java new file mode 100644 index 00000000000..0ce25618cc8 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityPolicyVO_.java @@ -0,0 +1,15 @@ +package org.zstack.network.securitygroup; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(VmNicSecurityPolicyVO.class) +public class VmNicSecurityPolicyVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute vmNicUuid; + public static volatile SingularAttribute ingressPolicy; + public static volatile SingularAttribute egressPolicy; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityTO.java b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityTO.java new file mode 100644 index 00000000000..16cd5279e82 --- /dev/null +++ b/plugin/securityGroup/src/main/java/org/zstack/network/securitygroup/VmNicSecurityTO.java @@ -0,0 +1,97 @@ +package org.zstack.network.securitygroup; + +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; + +public class VmNicSecurityTO { + public static final String ACTION_CODE_APPLY_CHAIN = "applyChain"; + public static final String ACTION_CODE_DELETE_CHAIN = "deleteChain"; + private String vmNicUuid; + private String internalName; + private String mac; + private List vmNicIps; + private String ingressPolicy; + private String egressPolicy; + private String actionCode = ACTION_CODE_APPLY_CHAIN; + private Map securityGroupRefs; + private boolean sync = false; + + public VmNicSecurityTO() { + securityGroupRefs = new HashMap(); + vmNicIps = new ArrayList<>(); + } + + public String getVmNicUuid() { + return vmNicUuid; + } + + public void setVmNicUuid(String vmNicUuid) { + this.vmNicUuid = vmNicUuid; + } + + public String getInternalName() { + return internalName; + } + + public void setInternalName(String internalName) { + this.internalName = internalName == null ? "" : internalName; + } + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac == null ? "" : mac; + } + + public List getVmNicIps(){ + return vmNicIps; + } + + public void setVmNicIps(List vmNicIps) { + this.vmNicIps = vmNicIps; + } + + public String getIngressPolicy() { + return ingressPolicy; + } + + public void setIngressPolicy(String ingressPolicy) { + this.ingressPolicy = ingressPolicy; + } + + public String getEgressPolicy() { + return egressPolicy; + } + + public void setEgressPolicy(String egressPolicy) { + this.egressPolicy = egressPolicy; + } + + public String getActionCode() { + return actionCode; + } + + public void setActionCode(String actionCode) { + this.actionCode = actionCode; + } + + public Map getSecurityGroupRefs() { + return securityGroupRefs; + } + + public void setSecurityGroupRefs(Map securityGroupRefs) { + this.securityGroupRefs = securityGroupRefs; + } + + public boolean isSync() { + return sync; + } + + public void setSync(boolean sync) { + this.sync = sync; + } +} diff --git a/plugin/sftpBackupStorage/pom.xml b/plugin/sftpBackupStorage/pom.xml index 3ed5998dfc1..94f4a9a2b3a 100755 --- a/plugin/sftpBackupStorage/pom.xml +++ b/plugin/sftpBackupStorage/pom.xml @@ -4,7 +4,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 .. sftpBackupStorage diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageEvent.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageEvent.java index c2604f5c253..a2424b72e81 100755 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageEvent.java +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageEvent.java @@ -8,21 +8,11 @@ public class APIAddSftpBackupStorageEvent extends APIAddBackupStorageEvent { public APIAddSftpBackupStorageEvent(String apiId) { super(apiId); } - + public APIAddSftpBackupStorageEvent() { super(null); } - private SftpBackupStorageInventory inventory; - - public SftpBackupStorageInventory getInventory() { - return inventory; - } - - public void setInventory(SftpBackupStorageInventory inventory) { - this.inventory = inventory; - } - public static APIAddSftpBackupStorageEvent __example__() { APIAddSftpBackupStorageEvent event = new APIAddSftpBackupStorageEvent(); SftpBackupStorageInventory ssInventory = new SftpBackupStorageInventory(); diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageMsgDoc_zh_cn.groovy b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageMsgDoc_zh_cn.groovy index a2299d71efc..928432fcedd 100644 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIAddSftpBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "username" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "password" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "sshPort" @@ -59,7 +56,6 @@ doc { type "int" optional true since "0.6" - } column { name "url" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -79,7 +74,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -99,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "importImages" @@ -109,7 +101,6 @@ doc { type "boolean" optional true since "0.6" - } column { name "resourceUuid" @@ -119,7 +110,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -129,7 +119,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -139,7 +128,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIQuerySftpBackupStorageMsgDoc_zh_cn.groovy b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIQuerySftpBackupStorageMsgDoc_zh_cn.groovy index 03d7fefc8fc..d469d5686be 100644 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIQuerySftpBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIQuerySftpBackupStorageMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.storage.backup.sftp import org.zstack.storage.backup.sftp.APIQuerySftpBackupStorageReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询Sftp镜像服务器(QuerySftpBackupStorage)" diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIReconnectSftpBackupStorageMsgDoc_zh_cn.groovy b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIReconnectSftpBackupStorageMsgDoc_zh_cn.groovy index 386f5fd1d04..3c6c14c5efa 100644 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIReconnectSftpBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIReconnectSftpBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIUpdateSftpBackupStorageMsgDoc_zh_cn.groovy b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIUpdateSftpBackupStorageMsgDoc_zh_cn.groovy index e9700c21686..a74656439f0 100644 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIUpdateSftpBackupStorageMsgDoc_zh_cn.groovy +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/APIUpdateSftpBackupStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional true since "0.6" - } column { name "password" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "hostname" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "sshPort" @@ -59,7 +56,6 @@ doc { type "Integer" optional true since "0.6" - } column { name "uuid" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -99,7 +92,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +101,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/PackageInfo.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/PackageInfo.java index 0f158d82778..9aa51322ea6 100755 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/PackageInfo.java +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "SFTP镜像存储") +@PackageAPIInfo( + APICategoryName = "SFTP镜像存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java index dafbe154b70..e6cc338873a 100755 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorage.java @@ -10,6 +10,7 @@ import org.zstack.core.cloudbus.CloudBusGlobalProperty; import org.zstack.core.db.Q; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.thread.SyncThread; import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; @@ -23,7 +24,6 @@ import org.zstack.header.rest.JsonAsyncRESTCallback; import org.zstack.header.rest.RESTFacade; import org.zstack.header.storage.backup.*; -import org.zstack.header.storage.backup.BackupStorageErrors.Opaque; import org.zstack.storage.backup.BackupStorageBase; import org.zstack.storage.backup.BackupStoragePathMaker; import org.zstack.storage.backup.sftp.SftpBackupStorageCommands.*; @@ -42,6 +42,7 @@ import static org.zstack.core.Platform.err; import static org.zstack.core.Platform.operr; +import static org.zstack.header.storage.backup.BackupStorageConstant.RESTORE_IMAGES_BACKUP_STORAGE_METADATA_TO_DATABASE; public class SftpBackupStorage extends BackupStorageBase { private static final CLogger logger = Utils.getLogger(SftpBackupStorage.class); @@ -312,7 +313,6 @@ public void success(PingResponse ret) { ErrorCode err = operr("the uuid of sftpBackupStorage agent changed[expected:%s, actual:%s], it's most likely" + " the agent was manually restarted. Issue a reconnect to sync the status", self.getUuid(), ret.getUuid()); - err.putToOpaque(Opaque.RECONNECT_AGENT.toString(), true); completion.fail(err); } else if (ret.isSuccess()) { completion.success(); @@ -405,14 +405,7 @@ private void connect(final Completion complete) { runner.setSshPort(getSelf().getSshPort()); runner.setAgentPort(SftpBackupStorageGlobalProperty.AGENT_PORT); runner.setPlayBookName(SftpBackupStorageConstant.ANSIBLE_PLAYBOOK_NAME); - runner.putArgument("pkg_sftpbackupstorage", agentPackageName); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - complete.fail(operr("chrony server not configured!")); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } + runner.setDeployArguments(new SftpBackupStorageDeployArguments()); runner.run(new ReturnValueCompletion(complete) { @Override public void success(Boolean deployed) { @@ -689,6 +682,27 @@ protected BackupStorageVO updateBackupStorage(APIUpdateBackupStorageMsg msg) { return vo; } + @Override + protected void handle(RestoreImagesBackupStorageMetadataToDatabaseMsg msg) { + RestoreImagesBackupStorageMetadataToDatabaseReply reply = new RestoreImagesBackupStorageMetadataToDatabaseReply(); + doRestoreImagesBackupStorageMetadataToDatabase(msg); + bus.reply(msg, reply); + } + + @Override + protected void handle(CalculateImageHashOnBackupStorageMsg msg) { + CalculateImageHashOnBackupStorageReply reply = new CalculateImageHashOnBackupStorageReply(); + reply.setError(operr("sftp backup storage do not support calculate image hash")); + } + protected void handle(GetBackupStorageManagerHostnameMsg msg) { + GetBackupStorageManagerHostnameReply reply = new GetBackupStorageManagerHostnameReply(); + reply.setHostname(getSelf().getHostname()); + bus.reply(msg, reply); + } + @SyncThread(signature = RESTORE_IMAGES_BACKUP_STORAGE_METADATA_TO_DATABASE) + private void doRestoreImagesBackupStorageMetadataToDatabase(RestoreImagesBackupStorageMetadataToDatabaseMsg msg) { + metaDataMaker.restoreImagesBackupStorageMetadataToDatabase(msg.getImagesMetadata(), msg.getBackupStorageUuid()); + } } diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageCommands.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageCommands.java index 5e0b6caefc7..d6d049e5820 100755 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageCommands.java +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageCommands.java @@ -216,7 +216,7 @@ public static class GetLocalFileSizeRsp extends AgentResponse { public long size; } - public static class GetImageSizeCmd extends AgentCommand { + public static class GetImageSizeCmd extends AgentCommand { public String imageUuid; public String installPath; } diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageDeployArguments.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageDeployArguments.java new file mode 100644 index 00000000000..420ad0abd3f --- /dev/null +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageDeployArguments.java @@ -0,0 +1,14 @@ +package org.zstack.storage.backup.sftp; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; + +public class SftpBackupStorageDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_sftpbackupstorage") + private final String packageName = SftpBackupStorageGlobalProperty.AGENT_PACKAGE_NAME; + + @Override + public String getPackageName() { + return packageName; + } +} diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageGlobalProperty.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageGlobalProperty.java index 2e4c9bfadfa..ec01923a4fd 100755 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageGlobalProperty.java +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageGlobalProperty.java @@ -10,7 +10,7 @@ @GlobalPropertyDefinition public class SftpBackupStorageGlobalProperty { - @GlobalProperty(name="SftpBackupStorage.agentPackageName", defaultValue = "sftpbackupstorage-4.4.0.tar.gz") + @GlobalProperty(name="SftpBackupStorage.agentPackageName", defaultValue = "sftpbackupstorage-5.4.0.tar.gz") public static String AGENT_PACKAGE_NAME; @GlobalProperty(name="SftpBackupStorage.agentPort", defaultValue = "7171") public static int AGENT_PORT; diff --git a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java index d1251ebef94..d14e57c8c1f 100755 --- a/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java +++ b/plugin/sftpBackupStorage/src/main/java/org/zstack/storage/backup/sftp/SftpBackupStorageMetaDataMaker.java @@ -4,6 +4,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.util.UriComponentsBuilder; import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SQL; @@ -23,6 +24,8 @@ import org.zstack.header.rest.RESTFacade; import org.zstack.header.storage.backup.AddBackupStorageExtensionPoint; import org.zstack.header.storage.backup.AddBackupStorageStruct; +import org.zstack.header.storage.backup.BackupStorageConstant; +import org.zstack.header.storage.backup.RestoreImagesBackupStorageMetadataToDatabaseMsg; import org.zstack.header.tag.SystemTagInventory; import org.zstack.header.tag.SystemTagVO; import org.zstack.header.tag.SystemTagVO_; @@ -37,6 +40,7 @@ import java.util.stream.Collectors; import static org.zstack.core.Platform.operr; +import static org.zstack.header.storage.backup.BackupStorageConstant.IMPORT_IMAGES_FAKE_RESOURCE_UUID; /** * Created by Mei Lei on 11/3/16. @@ -52,6 +56,8 @@ public class SftpBackupStorageMetaDataMaker implements AddImageExtensionPoint, A private ErrorFacade errf; @Autowired private SftpBackupStorageDumpMetadataInfo dumpInfo; + @Autowired + private CloudBus bus; private String buildUrl(String subPath, String hostName) { UriComponentsBuilder ub = UriComponentsBuilder.newInstance(); @@ -115,8 +121,7 @@ private void setAllImagesSystemTags(List imageInventories) { imageInventories.forEach(img -> img.setSystemTags(listMap.get(img.getUuid()))); } - - private void restoreImagesBackupStorageMetadataToDatabase(String imagesMetadata, String backupStorageUuid) { + public void restoreImagesBackupStorageMetadataToDatabase(String imagesMetadata, String backupStorageUuid) { List imageVOs = new ArrayList(); List backupStorageRefVOs = new ArrayList(); List systemTagVOs = new ArrayList<>(); @@ -124,6 +129,7 @@ private void restoreImagesBackupStorageMetadataToDatabase(String imagesMetadata, for (String metadata : metadatas) { if (metadata.contains("backupStorageRefs")) { ImageInventory imageInventory = JSONObjectUtil.toObject(metadata, ImageInventory.class); + ImageHelper.updateImageIfVirtioIsNull(imageInventory); if (!imageInventory.getStatus().equals(ImageStatus.Ready.toString()) || imageVOs.stream().anyMatch(image -> image.getUuid().equals(imageInventory.getUuid()))) { @@ -164,7 +170,10 @@ private void restoreImagesBackupStorageMetadataToDatabase(String imagesMetadata, imageVO.setMd5Sum(imageInventory.getMd5Sum()); imageVO.setMediaType(ImageConstant.ImageMediaType.valueOf(imageInventory.getMediaType())); imageVO.setName(imageInventory.getName()); - imageVO.setPlatform(ImagePlatform.valueOf(imageInventory.getPlatform())); + if (imageInventory.getPlatform() != null) { + imageVO.setPlatform(ImagePlatform.valueOf(imageInventory.getPlatform())); + } + imageVO.setArchitecture(imageInventory.getArchitecture()); imageVO.setSize(imageInventory.getSize()); imageVO.setState(ImageState.valueOf(imageInventory.getState())); imageVO.setSystem(imageInventory.isSystem()); @@ -239,14 +248,11 @@ private String getHostNameFromImageInventory(ImageInventory img) { } @Transactional - private String getBackupStorageTypeFromImageInventory(ImageInventory img) { + protected String getBackupStorageTypeFromImageInventory(ImageInventory img) { String sql = "select bs.type from BackupStorageVO bs, ImageBackupStorageRefVO refVo where " + "bs.uuid = refVo.backupStorageUuid and refVo.imageUuid = :uuid"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); - q.setParameter("uuid", img.getUuid()); - String type = q.getSingleResult(); - DebugUtils.Assert(type != null, String.format("cannot find backupStorage type for image [uuid:%s]", img.getUuid())); - return type; + + return SQL.New(sql, String.class).param("uuid", img.getUuid()).find(); } private String getBackupStorageUuidFromImageInventory(ImageInventory img) { @@ -435,7 +441,7 @@ public void handle(Map data) { @Override public void afterAddImage(ImageInventory img) { - if (!getBackupStorageTypeFromImageInventory(img).equals(SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE)) { + if (!SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE.equals(getBackupStorageTypeFromImageInventory(img))) { return; } @@ -481,7 +487,11 @@ public void success(SftpBackupStorageCommands.GetImagesMetaDataRsp rsp) { logger.error(String.format("get images metadata: %s failed", rsp.getImagesMetaData())); } else { logger.info(String.format("get images metadata: %s success", rsp.getImagesMetaData())); - restoreImagesBackupStorageMetadataToDatabase(rsp.getImagesMetaData(), backupStorage.getBackupStorageInventory().getUuid()); + RestoreImagesBackupStorageMetadataToDatabaseMsg rmsg = new RestoreImagesBackupStorageMetadataToDatabaseMsg(); + rmsg.setImagesMetadata(rsp.getImagesMetaData()); + rmsg.setBackupStorageUuid(backupStorage.getBackupStorageInventory().getUuid()); + bus.makeTargetServiceIdByResourceUuid(rmsg, BackupStorageConstant.SERVICE_ID, IMPORT_IMAGES_FAKE_RESOURCE_UUID); + bus.send(rmsg); } } @@ -623,7 +633,7 @@ public void failedToExpungeImage(ImageInventory img, ErrorCode err) { @Override public void afterCreateTemplate(ImageInventory inv) { - if (!getBackupStorageTypeFromImageInventory(inv).equals(SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE)) { + if (!SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE.equals(getBackupStorageTypeFromImageInventory(inv))) { return; } diff --git a/plugin/sharedMountPointPrimaryStorage/pom.xml b/plugin/sharedMountPointPrimaryStorage/pom.xml index 3dbd2000d1a..20695c58859 100755 --- a/plugin/sharedMountPointPrimaryStorage/pom.xml +++ b/plugin/sharedMountPointPrimaryStorage/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/APIAddSharedMountPointPrimaryStorageMsgDoc_zh_cn.groovy b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/APIAddSharedMountPointPrimaryStorageMsgDoc_zh_cn.groovy index 3ad1139d457..9b0ba710982 100644 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/APIAddSharedMountPointPrimaryStorageMsgDoc_zh_cn.groovy +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/APIAddSharedMountPointPrimaryStorageMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "type" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -69,7 +65,6 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" @@ -79,7 +74,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -99,7 +92,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorBackend.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorBackend.java index 24b02cff5ef..c78d3b89172 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorBackend.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorBackend.java @@ -4,7 +4,11 @@ import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.storage.primary.*; +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageMsg; +import org.zstack.storage.primary.EstimateVolumeTemplateSizeOnPrimaryStorageReply; /** * Created by frank on 6/30/2015. @@ -47,7 +51,7 @@ public HypervisorBackend(PrimaryStorageVO self) { abstract void handle(CreateVolumeFromVolumeSnapshotOnPrimaryStorageMsg msg, ReturnValueCompletion completion); - abstract void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract void stream(VolumeSnapshotInventory from, VolumeInventory to, boolean fullRebase, Completion completion); abstract void handle(DownloadBitsFromKVMHostToPrimaryStorageMsg msg, ReturnValueCompletion completion); @@ -73,6 +77,8 @@ public HypervisorBackend(PrimaryStorageVO self) { abstract void handle(SyncVolumeSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract void handle(CreateTemporaryVolumeFromSnapshotMsg msg, ReturnValueCompletion completion); abstract void handle(BackupVolumeSnapshotFromPrimaryStorageToBackupStorageMsg msg, ReturnValueCompletion completion); @@ -81,7 +87,19 @@ public HypervisorBackend(PrimaryStorageVO self) { abstract void handle(ChangeVolumeTypeOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract void handle(UnlinkBitsOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + abstract void downloadImageToCache(VmInstanceSpec.ImageSpec img, final ReturnValueCompletion completion); abstract void handle(GetVolumeSnapshotEncryptedOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + + abstract void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg, ReturnValueCompletion returnValueCompletion); + + abstract void handle(ResizeVolumeOnPrimaryStorageMsg msg, ReturnValueCompletion returnValueCompletion); + + abstract void handle(CommitVolumeSnapshotOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + + abstract void handle(PullVolumeSnapshotOnPrimaryStorageMsg msg, ReturnValueCompletion completion); + + abstract void createEmptyVolumeWithBackingFile(final VolumeInventory volume, String hostUuid, String backingFile, final ReturnValueCompletion completion); } diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorFactory.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorFactory.java index 67b71db480f..97ffbd2ce4b 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorFactory.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/HypervisorFactory.java @@ -9,4 +9,6 @@ public interface HypervisorFactory { String getHypervisorType(); HypervisorBackend getHypervisorBackend(PrimaryStorageVO vo); + + default String getExtensionType() {return null;} } diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmAgentCommandDispatcher.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmAgentCommandDispatcher.java new file mode 100644 index 00000000000..f4757ed1230 --- /dev/null +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmAgentCommandDispatcher.java @@ -0,0 +1,173 @@ +package org.zstack.storage.primary.smp; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.timeout.ApiTimeoutManager; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostErrors; +import org.zstack.header.host.HostStatus; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.primary.PrimaryStorageCapacityUpdaterRunnable; +import org.zstack.header.storage.primary.PrimaryStorageCapacityVO; +import org.zstack.header.storage.primary.PrimaryStorageVO; +import org.zstack.header.storage.primary.PrimaryStorageVO_; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.KVMHostAsyncHttpCallMsg; +import org.zstack.kvm.KVMHostAsyncHttpCallReply; +import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import static org.zstack.core.Platform.operr; + +import javax.persistence.TypedQuery; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * Created by david on 7/22/16. + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = true) +public class KvmAgentCommandDispatcher { + private static final CLogger logger = Utils.getLogger(KvmAgentCommandDispatcher.class); + + @Autowired + protected CloudBus bus; + @Autowired + protected DatabaseFacade dbf; + @Autowired + protected ErrorFacade errf; + @Autowired + protected ApiTimeoutManager timeoutManager; + + private List hostUuids; + private List errors = new ArrayList(); + private String primaryStorageUuid; + + public KvmAgentCommandDispatcher(String psUuid, String hostUuid) { + hostUuids = new ArrayList(); + hostUuids.add(hostUuid); + this.primaryStorageUuid = psUuid; + } + + public KvmAgentCommandDispatcher(String psUuid) { + this.primaryStorageUuid = psUuid; + hostUuids = findConnectedHosts(50); + if (hostUuids.isEmpty()) { + throw new OperationFailureException(operr("cannot find any connected host to perform the operation, it seems all KVM hosts" + + " in the clusters attached with the shared mount point storage[uuid:%s] are disconnected", + this.primaryStorageUuid)); + } + } + + private void httpCall(String path, final String hostUuid, KvmBackend.AgentCmd cmd, final Class rspType, final ReturnValueCompletion completion) { + httpCall(path, hostUuid, cmd, false, rspType, completion); + } + + private void httpCall(String path, final String hostUuid, KvmBackend.AgentCmd cmd, boolean noCheckStatus, final Class rspType, final ReturnValueCompletion completion) { + cmd.mountPoint = Q.New(PrimaryStorageVO.class). + select(PrimaryStorageVO_.mountPath). + eq(PrimaryStorageVO_.uuid, this.primaryStorageUuid). + findValue(); + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(hostUuid); + msg.setPath(path); + msg.setNoStatusCheck(noCheckStatus); + msg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply r = reply.castReply(); + final T rsp = r.toResponse(rspType); + if (!rsp.success) { + completion.fail(operr("operation error, because:%s", rsp.error)); + return; + } + + if (rsp.totalCapacity != null && rsp.availableCapacity != null) { + new PrimaryStorageCapacityUpdater(primaryStorageUuid).run(new PrimaryStorageCapacityUpdaterRunnable() { + @Override + public PrimaryStorageCapacityVO call(PrimaryStorageCapacityVO cap) { + if (cap.getTotalCapacity() == 0 || cap.getAvailableCapacity() == 0) { + cap.setAvailableCapacity(rsp.availableCapacity); + } + + cap.setTotalCapacity(rsp.totalCapacity); + cap.setTotalPhysicalCapacity(rsp.totalCapacity); + cap.setAvailablePhysicalCapacity(rsp.availableCapacity); + + return cap; + } + }); + } + + completion.success(rsp); + } + }); + } + + @Transactional(readOnly = true) + private List findConnectedHosts(int num) { + String sql = "select h.uuid from HostVO h, PrimaryStorageClusterRefVO ref where ref.clusterUuid = h.clusterUuid and" + + " ref.primaryStorageUuid = :psUuid and h.status = :status and h.hypervisorType = :htype"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); + q.setParameter("psUuid", this.primaryStorageUuid); + q.setParameter("status", HostStatus.Connected); + q.setParameter("htype", KVMConstant.KVM_HYPERVISOR_TYPE); + q.setMaxResults(num); + List hostUuids = q.getResultList(); + Collections.shuffle(hostUuids); + return hostUuids; + } + + public void go(String path, KvmBackend.AgentCmd cmd, Class rspType, ReturnValueCompletion completion) { + doCommand(hostUuids.iterator(), path, cmd, rspType, completion); + } + + private void doCommand(final Iterator it, final String path, final KvmBackend.AgentCmd cmd, final Class rspType, final ReturnValueCompletion completion) { + if (!it.hasNext()) { + completion.fail(errf.stringToOperationError("an operation failed on all hosts", errors)); + return; + } + + final String hostUuid = it.next(); + httpCall(path, hostUuid, cmd, rspType, new ReturnValueCompletion(completion) { + @Override + public void success(final T rsp) { + completion.success(rsp); + } + + @Override + public void fail(ErrorCode errorCode) { + if (!errorCode.isError(HostErrors.OPERATION_FAILURE_GC_ELIGIBLE)) { + completion.fail(errorCode); + return; + } + + errors.add(errorCode); + logger.warn(String.format("failed to do the command[%s] on the kvm host[uuid:%s], %s, try next one", + cmd.getClass(), hostUuid, errorCode)); + doCommand(it, path, cmd, rspType, completion); + } + }); + } +} diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmBackend.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmBackend.java index 2137e6e501d..1a0351c76af 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmBackend.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmBackend.java @@ -3,6 +3,8 @@ import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.compute.vm.ImageBackupStorageSelector; +import org.zstack.core.Platform; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.Q; @@ -12,6 +14,8 @@ import org.zstack.core.thread.ChainTask; import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.timeout.ApiTimeoutManager; +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.core.upgrade.UpgradeChecker; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.HasThreadContext; @@ -21,6 +25,7 @@ import org.zstack.header.core.validation.Validation; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.*; @@ -43,16 +48,9 @@ import org.zstack.header.volume.VolumeType; import org.zstack.header.volume.VolumeVO; import org.zstack.kvm.*; -import org.zstack.storage.backup.sftp.GetSftpBackupStorageDownloadCredentialMsg; -import org.zstack.storage.backup.sftp.GetSftpBackupStorageDownloadCredentialReply; -import org.zstack.storage.backup.sftp.SftpBackupStorageConstant; -import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; -import org.zstack.storage.primary.PrimaryStoragePathMaker; -import org.zstack.storage.primary.PrimaryStoragePhysicalCapacityManager; -import org.zstack.storage.primary.PrimaryStorageSystemTags; -import org.zstack.storage.snapshot.VolumeSnapshotSystemTags; +import org.zstack.storage.primary.*; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; -import org.zstack.tag.SystemTagCreator; import org.zstack.utils.CollectionUtils; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; @@ -63,6 +61,7 @@ import javax.persistence.Tuple; import java.io.File; import java.util.*; +import java.util.stream.Collectors; import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; @@ -84,11 +83,14 @@ public class KvmBackend extends HypervisorBackend { protected PluginRegistry pluginRgty; @Autowired protected SMPPrimaryStorageFactory primaryStorageFactory; + @Autowired + protected UpgradeChecker upgradeChecker; public KvmBackend() { } public static class AgentCmd extends KVMAgentCommands.PrimaryStorageCommand { + @GrayVersion(value = "5.0.0") public String mountPoint; } @@ -97,10 +99,73 @@ public static class AgentRsp { public String error; public Long totalCapacity; public Long availableCapacity; + protected ErrorCode buildErrorCode() { + if (success) { + return null; + } + return operr("operation error, because:%s", error); + } + } + + public static class ResizeVolumeCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") + private String installPath; + @GrayVersion(value = "5.0.0") + private long size; + @GrayVersion(value = "5.0.0") + private boolean force; + + public String getInstallPath() { + return installPath; + } + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public boolean isForce() { + return force; + } + + public void setForce(boolean force) { + this.force = force; + } + } + + public static class ResizeVolumeRsp extends AgentRsp { + private long size; + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + } + + public static class DeleteRsp extends AgentRsp { + public boolean inUse; + public ErrorCode buildErrorCode() { + if (inUse) { + return Platform.err(VolumeErrors.VOLUME_IN_USE, error); + } + return super.buildErrorCode(); + } } public static class ConnectCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String uuid; + @GrayVersion(value = "5.0.0") public List existUuids; } @@ -109,14 +174,27 @@ public static class ConnectRsp extends AgentRsp { } public static class CreateVolumeFromCacheCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String templatePathInCache; + @GrayVersion(value = "5.0.0") public String installPath; + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") + public long virtualSize; + } + + public static class CreateVolumeFromCacheRsp extends AgentRsp { + public Long actualSize; + public Long size; } public static class CreateVolumeWithBackingCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String templatePathInCache; + @GrayVersion(value = "5.0.0") public String installPath; + @GrayVersion(value = "5.0.0") public String volumeUuid; } @@ -126,15 +204,19 @@ public static class CreateVolumeWithBackingRsp extends AgentRsp { } public static class CreateFolderCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String installPath; } public static class DeleteBitsCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String path; + @GrayVersion(value = "5.0.0") public boolean folder = false; } public static class GetSubPathCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String path; } @@ -142,8 +224,10 @@ public static class GetSubPathRsp extends AgentRsp { public List paths; } - public static class CreateTemplateFromVolumeCmd extends AgentCmd implements HasThreadContext{ + public static class CreateTemplateFromVolumeCmd extends AgentCmd implements HasThreadContext { + @GrayVersion(value = "5.0.0") public String installPath; + @GrayVersion(value = "5.0.0") public String volumePath; } @@ -152,35 +236,61 @@ public static class CreateTemplateFromVolumeRsp extends AgentRsp { public long size; } + public static class EstimateTemplateSizeCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") + public String volumePath; + } + + public static class EstimateTemplateSizeRsp extends AgentRsp { + public long actualSize; + public long size; + } + public static class SftpUploadBitsCmd extends AgentCmd implements HasThreadContext{ + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; + @GrayVersion(value = "5.0.0") public String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") public String hostname; + @GrayVersion(value = "5.0.0") public String username; + @GrayVersion(value = "5.0.0") public String sshKey; + @GrayVersion(value = "5.0.0") public int sshPort; } public static class SftpDownloadBitsCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String sshKey; + @GrayVersion(value = "5.0.0") public int sshPort; + @GrayVersion(value = "5.0.0") public String hostname; + @GrayVersion(value = "5.0.0") public String username; + @GrayVersion(value = "5.0.0") public String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; } public static class ReInitImageCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String volumeInstallPath; + @GrayVersion(value = "5.0.0") public String imageInstallPath; } public static class RevertVolumeFromSnapshotCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String snapshotInstallPath; } public static class ReInitImageRsp extends AgentRsp { @Validation + @GrayVersion(value = "5.0.0") public String newVolumeInstallPath; } @@ -193,8 +303,11 @@ public static class RevertVolumeFromSnapshotRsp extends AgentRsp { } public static class MergeSnapshotCmd extends AgentCmd implements HasThreadContext { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String snapshotInstallPath; + @GrayVersion(value = "5.0.0") public String workspaceInstallPath; } @@ -204,27 +317,78 @@ public static class MergeSnapshotRsp extends AgentRsp { } public static class GetDownloadBitsFromKVMHostProgressCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public List volumePaths; } public static class GetDownloadBitsFromKVMHostProgressRsp extends AgentRsp { + @GrayVersion(value = "5.0.0") public long totalSize; } public static class OfflineMergeSnapshotCmd extends AgentCmd implements HasThreadContext { + @GrayVersion(value = "5.0.0") public String srcPath; + @GrayVersion(value = "5.0.0") public String destPath; + @GrayVersion(value = "5.0.0") public boolean fullRebase; } + public static class OfflineMergeSnapshotRsp extends AgentRsp { + @GrayVersion(value = "5.4.0") + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + } + + public static class OfflineCommitSnapshotCmd extends AgentCmd implements HasThreadContext { + @GrayVersion(value = "5.4.0") + public String top; + @GrayVersion(value = "5.4.0") + public String base; + @GrayVersion(value = "5.4.0") + public List topChildrenInstallPathInDb = new ArrayList<>(); + } + + public static class OfflineCommitSnapshotRsp extends AgentRsp { + @GrayVersion(value = "5.4.0") + private long actualSize; + + public long getActualSize() { + return actualSize; + } + + public void setActualSize(long actualSize) { + this.actualSize = actualSize; + } + } + public static class CreateEmptyVolumeCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String installPath; + @GrayVersion(value = "5.0.0") public long size; + @GrayVersion(value = "5.0.0") public String name; + @GrayVersion(value = "5.0.0") public String volumeUuid; + public String backingFile; + } + + public static class CreateEmptyVolumeRsp extends AgentRsp { + public Long actualSize; + public Long size; } public static class CheckBitsCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String path; } @@ -233,7 +397,9 @@ public static class CheckBitsRsp extends AgentRsp { } public static class GetVolumeSizeCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String installPath; } @@ -247,31 +413,54 @@ public static class DownloadBitsFromKVMHostRsp extends AgentRsp { } public static class DownloadBitsFromKVMHostCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String hostname; + @GrayVersion(value = "5.0.0") public String username; + @GrayVersion(value = "5.0.0") public String sshKey; + @GrayVersion(value = "5.0.0") public int sshPort; // it's file path on kvm host actually + @GrayVersion(value = "5.0.0") public String backupStorageInstallPath; + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; + @GrayVersion(value = "5.0.0") public Long bandWidth; + @GrayVersion(value = "5.0.0") public String identificationCode; } public static class CancelDownloadBitsFromKVMHostCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String primaryStorageInstallPath; } public static class LinkVolumeNewDirCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") public String volumeUuid; + @GrayVersion(value = "5.0.0") public String srcDir; + @GrayVersion(value = "5.0.0") public String dstDir; } public static class LinkVolumeNewDirRsp extends AgentRsp { } + public static class UnlinkBitsCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") + public String installPath; + @GrayVersion(value = "5.0.0") + public boolean onlyLinkedFile = true; + } + + public static class UnlinkBitsRsp extends AgentRsp { + } + public static class GetQcow2HashValueCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") private String installPath; public String getInstallPath() { @@ -295,17 +484,30 @@ public void setHashValue(String hashValue) { } } + public static class GetBackingChainCmd extends AgentCmd { + @GrayVersion(value = "5.0.0") + public String volumeUuid; + @GrayVersion(value = "5.0.0") + public String installPath; + } + + public static class GetBackingChainRsp extends AgentRsp { + public List backingChain; + public long totalSize; + } + public static final String CONNECT_PATH = "/sharedmountpointprimarystorage/connect"; public static final String CREATE_VOLUME_FROM_CACHE_PATH = "/sharedmountpointprimarystorage/createrootvolume"; public static final String CREATE_VOLUME_WITH_BACKING_PATH = "/sharedmountpointprimarystorage/createvolumewithbacking"; public static final String DELETE_BITS_PATH = "/sharedmountpointprimarystorage/bits/delete"; + public static final String UNLINK_BITS_PATH = "/sharedmountpointprimarystorage/bits/unlink"; public static final String CREATE_TEMPLATE_FROM_VOLUME_PATH = "/sharedmountpointprimarystorage/createtemplatefromvolume"; - public static final String UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH = "/sharedmountpointprimarystorage/sftp/upload"; - public static final String DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH = "/sharedmountpointprimarystorage/sftp/download"; + public static final String ESTIMATE_TEMPLATE_SIZE_PATH = "/sharedmountpointprimarystorage/estimatetemplatesize"; public static final String REVERT_VOLUME_FROM_SNAPSHOT_PATH = "/sharedmountpointprimarystorage/volume/revertfromsnapshot"; public static final String REINIT_IMAGE_PATH = "/sharedmountpointprimarystorage/volume/reinitimage"; public static final String MERGE_SNAPSHOT_PATH = "/sharedmountpointprimarystorage/snapshot/merge"; public static final String OFFLINE_MERGE_SNAPSHOT_PATH = "/sharedmountpointprimarystorage/snapshot/offlinemerge"; + public static final String OFFLINE_COMMIT_SNAPSHOT_PATH = "/sharedmountpointprimarystorage/snapshot/offlinecommit"; public static final String CREATE_EMPTY_VOLUME_PATH = "/sharedmountpointprimarystorage/volume/createempty"; public static final String CREATE_FOLDER_PATH = "/sharedmountpointprimarystorage/volume/createfolder"; public static final String CHECK_BITS_PATH = "/sharedmountpointprimarystorage/bits/check"; @@ -315,6 +517,8 @@ public void setHashValue(String hashValue) { public static final String CANCEL_DOWNLOAD_BITS_FROM_KVM_HOST_PATH = "/sharedmountpointprimarystorage/kvmhost/download/cancel"; public static final String GET_DOWNLOAD_BITS_FROM_KVM_HOST_PROGRESS_PATH = "/sharedmountpointprimarystorage/kvmhost/download/progress"; public static final String GET_QCOW2_HASH_VALUE_PATH = "/sharedmountpointprimarystorage/getqcow2hash"; + public static final String GET_BACKING_CHAIN_PATH = "/sharedmountpointprimarystorage/volume/getbackingchain"; + public static final String RESIZE_VOLUME_PATH = "/sharedmountpointprimarystorage/volume/resize"; public KvmBackend(PrimaryStorageVO self) { super(self); @@ -357,8 +561,9 @@ public void run(MessageReply reply) { KVMHostAsyncHttpCallReply r = reply.castReply(); final T rsp = r.toResponse(rspType); - if (!rsp.success) { - completion.fail(operr("operation error, because:%s", rsp.error)); + ErrorCode errorCode = rsp.buildErrorCode(); + if (errorCode != null) { + completion.fail(errorCode); return; } @@ -483,7 +688,7 @@ public String makeMemoryVolumeInstallUrl(VolumeInventory vol) { } public String makeCachedImageInstallUrl(ImageInventory iminv) { - return PathUtil.join(self.getMountPath(), PrimaryStoragePathMaker.makeCachedImageInstallPath(iminv)); + return ImageCacheUtil.getImageCachePath(iminv, it -> PathUtil.join(self.getMountPath(), PrimaryStoragePathMaker.makeCachedImageInstallPath(iminv))); } public String makeCachedImageInstallUrlFromImageUuidForTemplate(String imageUuid) { @@ -534,6 +739,7 @@ class ImageCache { String primaryStorageInstallPath; String backupStorageInstallPath; String volumeResourceInstallPath; + boolean incremental; void download(final ReturnValueCompletion completion) { DebugUtils.Assert(image != null, "image cannot be null"); @@ -606,12 +812,37 @@ public void rollback(FlowRollback trigger, Map data) { @Override public void run(final FlowTrigger trigger, Map data) { if (volumeResourceInstallPath != null) { - downloadFromVolumeResource(trigger); + if (incremental) { + incrementalDownloadFromVolume(trigger); + } else { + downloadFromVolumeResource(trigger); + } } else { downloadFromBackupStorage(trigger); } } + private void incrementalDownloadFromVolume(FlowTrigger trigger) { + CreateVolumeWithBackingCmd cmd = new CreateVolumeWithBackingCmd(); + cmd.installPath = primaryStorageInstallPath; + cmd.templatePathInCache = volumeResourceInstallPath; + + new Do().go(CREATE_VOLUME_WITH_BACKING_PATH, cmd, CreateVolumeWithBackingRsp.class, + new ReturnValueCompletion(trigger) { + @Override + public void success(AgentRsp r) { + CreateVolumeWithBackingRsp rsp = (CreateVolumeWithBackingRsp) r; + actualSize = rsp.actualSize; + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + private void downloadFromVolumeResource(FlowTrigger trigger) { CreateTemplateFromVolumeCmd cmd = new CreateTemplateFromVolumeCmd(); cmd.volumePath = volumeResourceInstallPath; @@ -663,11 +894,29 @@ public void handle(Map data) { logger.debug(String.format("downloaded image[uuid:%s, name:%s] to the image cache of local shared mount point storage[uuid: %s, installPath: %s]", image.getUuid(), image.getName(), self.getUuid(), primaryStorageInstallPath)); - pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class) - .forEach(exp -> exp.saveEncryptAfterCreateImageCache(null, ImageCacheInventory.valueOf(vo))); + new While<>(pluginRgty.getExtensionList(AfterCreateImageCacheExtensionPoint.class)).each((ext, whileCompletion) -> { + ext.saveEncryptAfterCreateImageCache(null, ImageCacheInventory.valueOf(vo), new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } - completion.success(ImageCacheInventory.valueOf(vo)); - chain.next(); + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + logger.warn(String.format("failed to saveEncryptAfterCreateImageCache: %s", errorCodeList.getCauses().get(0))); + } + completion.success(ImageCacheInventory.valueOf(vo)); + chain.next(); + } + }); } }); @@ -808,12 +1057,18 @@ private void createEmptyVolume(final VolumeInventory volume, String hostUuid, fi cmd.size = volume.getSize(); cmd.volumeUuid = volume.getUuid(); - new Do(hostUuid).go(CREATE_EMPTY_VOLUME_PATH, cmd, new ReturnValueCompletion(completion) { + new Do(hostUuid).go(CREATE_EMPTY_VOLUME_PATH, cmd, CreateEmptyVolumeRsp.class, new ReturnValueCompletion(completion) { @Override public void success(AgentRsp returnValue) { + CreateEmptyVolumeRsp rsp = (CreateEmptyVolumeRsp) returnValue; InstantiateVolumeOnPrimaryStorageReply reply = new InstantiateVolumeOnPrimaryStorageReply(); volume.setInstallPath(cmd.installPath); volume.setFormat(VolumeConstant.VOLUME_FORMAT_QCOW2); + volume.setActualSize(rsp.actualSize); + if (rsp.size != null) { + volume.setSize(rsp.size); + } + reply.setVolume(volume); completion.success(reply); } @@ -849,6 +1104,7 @@ private void createRootVolume(InstantiateRootVolumeFromTemplateOnPrimaryStorageM String pathInCache = makeCachedImageInstallUrl(image); String installPath = StringUtils.isNotEmpty(volume.getInstallPath()) ? volume.getInstallPath() : makeRootVolumeInstallUrl(volume) ; + Long actualSize; @Override public void setup() { @@ -886,10 +1142,19 @@ public void run(final FlowTrigger trigger, Map data) { cmd.installPath = installPath; cmd.templatePathInCache = makeCachedImageInstallUrl(image); cmd.volumeUuid = volume.getUuid(); + if (image.getSize() < volume.getSize()) { + cmd.virtualSize = volume.getSize(); + } - httpCall(CREATE_VOLUME_FROM_CACHE_PATH, hostUuid, cmd, AgentRsp.class, new ReturnValueCompletion(trigger) { + httpCall(CREATE_VOLUME_FROM_CACHE_PATH, hostUuid, cmd, CreateVolumeFromCacheRsp.class, + new ReturnValueCompletion(trigger) { @Override - public void success(AgentRsp rsp) { + public void success(CreateVolumeFromCacheRsp rsp) { + actualSize = rsp.actualSize; + if (rsp.size != null) { + volume.setSize(rsp.size); + } + trigger.next(); } @@ -907,6 +1172,7 @@ public void handle(Map data) { InstantiateVolumeOnPrimaryStorageReply reply = new InstantiateVolumeOnPrimaryStorageReply(); volume.setInstallPath(installPath); volume.setFormat(VolumeConstant.VOLUME_FORMAT_QCOW2); + volume.setActualSize(actualSize); reply.setVolume(volume); completion.success(reply); } @@ -965,7 +1231,7 @@ public void success(AgentRsp rsp) { @Override public void fail(ErrorCode errorCode) { - if (!errorCode.isError(HostErrors.OPERATION_FAILURE_GC_ELIGIBLE)) { + if (!errorCode.isError(HostErrors.OPERATION_FAILURE_GC_ELIGIBLE) || errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { completion.fail(errorCode); return; } @@ -1329,7 +1595,7 @@ public void success(AgentRsp returnValue) { reply.setActualSize(rsp.actualSize); reply.setInstallPath(installPath); reply.setSize(rsp.size); - createProtectTag(); + reply.setIncremental(true); completion.success(reply); } @@ -1337,17 +1603,10 @@ public void success(AgentRsp returnValue) { public void fail(ErrorCode errorCode) { completion.fail(errorCode); } - - private void createProtectTag() { - SystemTagCreator creator = VolumeSnapshotSystemTags.BACKING_TO_VOLUME.newSystemTagCreator(latest.getUuid()); - creator.unique = false; - creator.setTagByTokens(Collections.singletonMap(VolumeSnapshotSystemTags.BACKING_VOLUME_TOKEN, volumeUuid)); - creator.create(); - } }); } - @Override + @Override void handle(GetDownloadBitsFromKVMHostProgressMsg msg, final ReturnValueCompletion completion) { GetDownloadBitsFromKVMHostProgressCmd cmd = new GetDownloadBitsFromKVMHostProgressCmd(); cmd.volumePaths = msg.getVolumePaths(); @@ -1368,18 +1627,17 @@ public void fail(ErrorCode errorCode) { }); } - - void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg, final ReturnValueCompletion completion) { + @Override + void stream(VolumeSnapshotInventory from, VolumeInventory to, boolean fullRebase, final Completion completion) { boolean offline = true; - VolumeInventory volume = msg.getTo(); + VolumeInventory volume = to; + fullRebase |= from == null; - final MergeVolumeSnapshotOnPrimaryStorageReply reply = new MergeVolumeSnapshotOnPrimaryStorageReply(); if (volume.getType().equals(VolumeType.Memory.toString())) { - completion.success(reply); + completion.success(); return; } - VolumeSnapshotInventory sp = msg.getFrom(); String hostUuid = null; if (volume.getVmInstanceUuid() != null) { SimpleQuery q = dbf.createQuery(VmInstanceVO.class); @@ -1400,14 +1658,14 @@ void handle(MergeVolumeSnapshotOnPrimaryStorageMsg msg, final ReturnValueComplet if (offline) { OfflineMergeSnapshotCmd cmd = new OfflineMergeSnapshotCmd(); - cmd.fullRebase = msg.isFullRebase(); - cmd.srcPath = sp.getPrimaryStorageInstallPath(); + cmd.fullRebase = fullRebase; + cmd.srcPath = from != null ? from.getPrimaryStorageInstallPath() : null; cmd.destPath = volume.getInstallPath(); new Do().go(OFFLINE_MERGE_SNAPSHOT_PATH, cmd, new ReturnValueCompletion(completion) { @Override public void success(AgentRsp returnValue) { - completion.success(reply); + completion.success(); } @Override @@ -1417,16 +1675,16 @@ public void fail(ErrorCode errorCode) { }); } else { MergeVolumeSnapshotOnKvmMsg kmsg = new MergeVolumeSnapshotOnKvmMsg(); - kmsg.setFullRebase(msg.isFullRebase()); + kmsg.setFullRebase(fullRebase); kmsg.setHostUuid(hostUuid); - kmsg.setFrom(sp); + kmsg.setFrom(from); kmsg.setTo(volume); bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, hostUuid); bus.send(kmsg, new CloudBusCallBack(completion) { @Override public void run(MessageReply r) { if (r.isSuccess()) { - completion.success(reply); + completion.success(); } else { completion.fail(r.getError()); } @@ -1583,6 +1841,66 @@ public void fail(ErrorCode errorCode) { }); } + @Override + void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg, ReturnValueCompletion completion) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + new While<>(msg.getRootInstallPaths()).each((installPath, compl) -> { + GetBackingChainCmd cmd = new GetBackingChainCmd(); + cmd.installPath = installPath; + cmd.volumeUuid = msg.getVolumeUuid(); + new Do().go(GET_BACKING_CHAIN_PATH, cmd, GetBackingChainRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp r) { + GetBackingChainRsp rsp = (GetBackingChainRsp) r; + if (CollectionUtils.isEmpty(rsp.backingChain)) { + reply.putBackingChainInstallPath(installPath, Collections.emptyList()); + reply.putBackingChainSize(installPath, 0L); + } else { + reply.putBackingChainInstallPath(installPath, rsp.backingChain); + reply.putBackingChainSize(installPath, rsp.totalSize); + } + compl.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + compl.addError(errorCode); + compl.done(); + } + }); + }).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList err) { + if (!err.getCauses().isEmpty()) { + completion.fail(err.getCauses().get(0)); + } else { + completion.success(reply); + } + } + }); + } + + void createEmptyVolumeWithBackingFile(final VolumeInventory volume, String hostUuid, String backingFile, final ReturnValueCompletion completion) { + final CreateEmptyVolumeCmd cmd = new CreateEmptyVolumeCmd(); + cmd.installPath = volume.getInstallPath(); + cmd.name = volume.getName(); + cmd.size = volume.getSize(); + cmd.volumeUuid = volume.getUuid(); + cmd.backingFile = backingFile; + + new Do(hostUuid).go(CREATE_EMPTY_VOLUME_PATH, cmd, AgentRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp rsp) { + completion.success(rsp); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + @Override void deleteBits(String path, final Completion completion) { deleteBits(path, false, completion); @@ -1593,7 +1911,7 @@ void deleteBits(String path, boolean folder, final Completion completion) { DeleteBitsCmd cmd = new DeleteBitsCmd(); cmd.path = path; cmd.folder = folder; - new Do().go(DELETE_BITS_PATH, cmd, new ReturnValueCompletion(completion) { + new Do().go(DELETE_BITS_PATH, cmd, DeleteRsp.class, new ReturnValueCompletion(completion) { @Override public void success(AgentRsp rsp) { completion.success(); @@ -1631,14 +1949,26 @@ public void fail(ErrorCode errorCode) { void handle(CreateImageCacheFromVolumeSnapshotOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply reply = new CreateImageCacheFromVolumeSnapshotOnPrimaryStorageReply(); + boolean incremental = msg.hasSystemTag(VolumeSystemTags.FAST_CREATE.getTagFormat()); + if (incremental && PrimaryStorageGlobalProperty.USE_SNAPSHOT_AS_INCREMENTAL_CACHE) { + ImageCacheVO cache = createTemporaryImageCacheFromVolumeSnapshot(msg.getImageInventory(), msg.getVolumeSnapshot()); + dbf.persist(cache); + reply.setInventory(cache.toInventory()); + reply.setIncremental(true); + completion.success(reply); + return; + } + final ImageCache cache = new ImageCache(); cache.image = msg.getImageInventory(); cache.primaryStorageInstallPath = makeCachedImageInstallUrl(msg.getImageInventory()); cache.volumeResourceInstallPath = msg.getVolumeSnapshot().getPrimaryStorageInstallPath(); + cache.incremental = msg.hasSystemTag(VolumeSystemTags.FAST_CREATE.getTagFormat()); cache.download(new ReturnValueCompletion(completion) { @Override - public void success(ImageCacheInventory cache) { - reply.setActualSize(cache.getSize()); + public void success(ImageCacheInventory inv) { + reply.setInventory(inv); + reply.setIncremental(cache.incremental); completion.success(reply); } @@ -1798,8 +2128,8 @@ public void handle(ErrorCode errCode, Map data) { @Override public void handle(UploadBitsToBackupStorageMsg msg, final ReturnValueCompletion completion) { - SftpBackupStorageKvmUploader uploader = new SftpBackupStorageKvmUploader(msg.getBackupStorageUuid()); - uploader.uploadBits(null, msg.getBackupStorageInstallPath(), msg.getPrimaryStorageInstallPath(), new ReturnValueCompletion(completion) { + BackupStorageKvmUploader uploader = getBackupStorageKvmUploader(msg.getBackupStorageUuid()); + uploader.uploadBits(msg.getImageUuid(), msg.getBackupStorageInstallPath(), msg.getPrimaryStorageInstallPath(), new ReturnValueCompletion(completion) { @Override public void success(String bsPath) { UploadBitsToBackupStorageReply reply = new UploadBitsToBackupStorageReply(); @@ -1814,113 +2144,18 @@ public void fail(ErrorCode errorCode) { }); } - class SftpBackupStorageKvmDownloader extends BackupStorageKvmDownloader { - private final String bsUuid; - - public SftpBackupStorageKvmDownloader(String backupStorageUuid) { - bsUuid = backupStorageUuid; - } - - @Override - public void downloadBits(final String bsPath, final String psPath, boolean isData, final Completion completion) { - GetSftpBackupStorageDownloadCredentialMsg gmsg = new GetSftpBackupStorageDownloadCredentialMsg(); - gmsg.setBackupStorageUuid(bsUuid); - bus.makeTargetServiceIdByResourceUuid(gmsg, BackupStorageConstant.SERVICE_ID, bsUuid); - - bus.send(gmsg, new CloudBusCallBack(completion) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - completion.fail(reply.getError()); - return; - } - - final GetSftpBackupStorageDownloadCredentialReply greply = reply.castReply(); - SftpDownloadBitsCmd cmd = new SftpDownloadBitsCmd(); - cmd.hostname = greply.getHostname(); - cmd.username = greply.getUsername(); - cmd.sshKey = greply.getSshKey(); - cmd.sshPort = greply.getSshPort(); - cmd.backupStorageInstallPath = bsPath; - cmd.primaryStorageInstallPath = psPath; - - new Do().go(DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH, cmd, new ReturnValueCompletion(completion) { - @Override - public void success(AgentRsp returnValue) { - completion.success(); - } - - @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); - } - }); - } - }); - } - } - - class SftpBackupStorageKvmUploader extends BackupStorageKvmUploader { - private final String bsUuid; - - public SftpBackupStorageKvmUploader(String backupStorageUuid) { - bsUuid = backupStorageUuid; - } - - @Override - public void uploadBits(final String imageUuid, final String bsPath, final String psPath, final ReturnValueCompletion completion) { - GetSftpBackupStorageDownloadCredentialMsg gmsg = new GetSftpBackupStorageDownloadCredentialMsg(); - gmsg.setBackupStorageUuid(bsUuid); - bus.makeTargetServiceIdByResourceUuid(gmsg, BackupStorageConstant.SERVICE_ID, bsUuid); - bus.send(gmsg, new CloudBusCallBack(completion) { - @Override - public void run(MessageReply reply) { - if (!reply.isSuccess()) { - completion.fail(reply.getError()); - return; - } - - final GetSftpBackupStorageDownloadCredentialReply r = reply.castReply(); - SftpUploadBitsCmd cmd = new SftpUploadBitsCmd(); - cmd.primaryStorageInstallPath = psPath; - cmd.backupStorageInstallPath = bsPath; - cmd.hostname = r.getHostname(); - cmd.username = r.getUsername(); - cmd.sshKey = r.getSshKey(); - cmd.sshPort = r.getSshPort(); - - new Do().go(UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH, cmd, new ReturnValueCompletion(completion) { - @Override - public void success(AgentRsp returnValue) { - completion.success(bsPath); - } - - @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); - } - }); - } - }); - } - } - private BackupStorageKvmDownloader getBackupStorageKvmDownloader(String backupStorageUuid) { SimpleQuery q = dbf.createQuery(BackupStorageVO.class); q.select(BackupStorageVO_.type); q.add(BackupStorageVO_.uuid, Op.EQ, backupStorageUuid); String bsType = q.findValue(); - if (SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE.equals(bsType)) { - return new SftpBackupStorageKvmDownloader(backupStorageUuid); - } else { - for (BackupStorageKvmFactory f : pluginRgty.getExtensionList(BackupStorageKvmFactory.class)) { - if (bsType.equals(f.getBackupStorageType())) { - return f.createDownloader(getSelfInventory(), backupStorageUuid); - } + for (BackupStorageKvmFactory f : pluginRgty.getExtensionList(BackupStorageKvmFactory.class)) { + if (bsType.equals(f.getBackupStorageType())) { + return f.createDownloader(getSelfInventory(), backupStorageUuid); } - throw new CloudRuntimeException(String.format("cannot find any BackupStorageKvmFactory for the type[%s]", bsType)); } + throw new CloudRuntimeException(String.format("cannot find any BackupStorageKvmFactory for the type[%s]", bsType)); } @@ -1934,24 +2169,21 @@ private BackupStorageKvmUploader getBackupStorageKvmUploader(String backupStorag throw new OperationFailureException(operr("cannot find backup storage[uuid:%s]", backupStorageUuid)); } - if (SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE.equals(bsType)) { - return new SftpBackupStorageKvmUploader(backupStorageUuid); - } else { - for (BackupStorageKvmFactory f : pluginRgty.getExtensionList(BackupStorageKvmFactory.class)) { - if (bsType.equals(f.getBackupStorageType())) { - return f.createUploader(getSelfInventory(), backupStorageUuid); - } - } - throw new CloudRuntimeException(String.format("cannot find any BackupStorageKvmFactory for the type[%s]", bsType)); + for (BackupStorageKvmFactory f : pluginRgty.getExtensionList(BackupStorageKvmFactory.class)) { + if (bsType.equals(f.getBackupStorageType())) { + return f.createUploader(getSelfInventory(), backupStorageUuid); + } } + + throw new CloudRuntimeException(String.format("cannot find any BackupStorageKvmFactory for the type[%s]", bsType)); } @Override void handleHypervisorSpecificMessage(SMPPrimaryStorageHypervisorSpecificMessage msg) { if (msg instanceof InitKvmHostMsg) { - handle((InitKvmHostMsg) msg); + stream((InitKvmHostMsg) msg); } else { bus.dealWithUnknownMessage((Message) msg); } @@ -1984,6 +2216,16 @@ void connectByClusterUuid(final String clusterUuid, final ReturnValueCompletion< return; } + huuids = huuids.stream() + .filter(uuid -> !upgradeChecker + .skipInnerDeployOrInitOnCurrentAgent(uuid)) + .collect(Collectors.toList()); + if (huuids.isEmpty()) { + // no host in the cluster + completion.success(ClusterConnectionStatus.FullyConnected); + return; + } + class Result { Set errorCodes = new HashSet<>(); List huuids = Collections.synchronizedList(new ArrayList()); @@ -2076,6 +2318,28 @@ public void fail(ErrorCode errorCode) { } + @Override + void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { + EstimateTemplateSizeCmd cmd = new EstimateTemplateSizeCmd(); + cmd.volumePath = msg.getInstallPath(); + + new Do().go(ESTIMATE_TEMPLATE_SIZE_PATH, cmd, EstimateTemplateSizeRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp r) { + EstimateTemplateSizeRsp rsp = (EstimateTemplateSizeRsp) r; + EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + reply.setActualSize(rsp.actualSize); + reply.setSize(rsp.size); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + @Override void handle(CreateTemporaryVolumeFromSnapshotMsg msg, final ReturnValueCompletion completion) { final String installPath = makeTemplateFromVolumeInWorkspacePath(msg.getTemporaryVolumeUuid()); @@ -2138,7 +2402,7 @@ public void fail(ErrorCode errorCode) { }); } - private void handle(final InitKvmHostMsg msg) { + private void stream(final InitKvmHostMsg msg) { final InitKvmHostReply reply = new InitKvmHostReply(); thdf.chainSubmit(new ChainTask(msg) { @Override @@ -2234,4 +2498,92 @@ public void fail(ErrorCode errorCode) { } }); } + + @Override + void handle(UnlinkBitsOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { + UnlinkBitsCmd cmd = new UnlinkBitsCmd(); + cmd.installPath = msg.getInstallPath(); + new Do().go(UNLINK_BITS_PATH, cmd, LinkVolumeNewDirRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp rsp) { + completion.success(new UnlinkBitsOnPrimaryStorageReply()); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + void handle(ResizeVolumeOnPrimaryStorageMsg msg, ReturnValueCompletion completion) { + VolumeInventory volume = msg.getVolume(); + final ResizeVolumeOnPrimaryStorageReply reply = new ResizeVolumeOnPrimaryStorageReply(); + + String hostUuid = primaryStorageFactory.getConnectedHostForOperation(getSelfInventory()).get(0).getUuid(); + + ResizeVolumeCmd cmd = new ResizeVolumeCmd(); + cmd.setInstallPath(volume.getInstallPath()); + cmd.setSize(msg.getSize()); + cmd.setForce(msg.isForce()); + httpCall(RESIZE_VOLUME_PATH, hostUuid, cmd, ResizeVolumeRsp.class, new ReturnValueCompletion(msg) { + @Override + public void success(ResizeVolumeRsp rsp) { + volume.setSize(rsp.getSize()); + reply.setVolume(volume); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + void handle(CommitVolumeSnapshotOnPrimaryStorageMsg msg, final ReturnValueCompletion completion) { + OfflineCommitSnapshotCmd cmd = new OfflineCommitSnapshotCmd(); + cmd.top = msg.getSrcSnapshot().getPrimaryStorageInstallPath(); + cmd.base = msg.getDstSnapshot().getPrimaryStorageInstallPath(); + cmd.topChildrenInstallPathInDb = msg.getSrcChildrenInstallPathInDb(); + new Do().go(OFFLINE_COMMIT_SNAPSHOT_PATH, cmd, OfflineCommitSnapshotRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp returnValue) { + OfflineCommitSnapshotRsp rsp = (OfflineCommitSnapshotRsp) returnValue; + + CommitVolumeSnapshotOnPrimaryStorageReply reply = new CommitVolumeSnapshotOnPrimaryStorageReply(); + reply.setSize(rsp.getActualSize()); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + void handle(PullVolumeSnapshotOnPrimaryStorageMsg msg, final ReturnValueCompletion completion) { + PullVolumeSnapshotOnPrimaryStorageReply reply = new PullVolumeSnapshotOnPrimaryStorageReply(); + OfflineMergeSnapshotCmd cmd = new OfflineMergeSnapshotCmd(); + cmd.srcPath = msg.getSrcSnapshotParentPath(); + cmd.destPath = msg.getDstSnapshot().getPrimaryStorageInstallPath(); + cmd.fullRebase = cmd.srcPath == null; + new Do().go(OFFLINE_MERGE_SNAPSHOT_PATH, cmd, OfflineMergeSnapshotRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(AgentRsp returnValue) { + OfflineMergeSnapshotRsp rsp = (OfflineMergeSnapshotRsp) returnValue; + reply.setSize(rsp.getActualSize()); + completion.success(reply); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } } diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmFactory.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmFactory.java index 5fff9076292..19065d35197 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmFactory.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/KvmFactory.java @@ -16,11 +16,9 @@ import org.zstack.header.storage.snapshot.VolumeSnapshotVO; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.kvm.*; -import org.zstack.storage.primary.ChangePrimaryStorageStatusMsg; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; -import javax.persistence.TypedQuery; import java.util.List; import java.util.Map; diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/PackageInfo.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/PackageInfo.java index d2025f2ebcd..d7831d652e3 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/PackageInfo.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "SMP主存储") +@PackageAPIInfo( + APICategoryName = "SMP主存储", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPDeleteVolumeGC.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPDeleteVolumeGC.java index 13178dcd55b..30ddec63045 100644 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPDeleteVolumeGC.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPDeleteVolumeGC.java @@ -1,5 +1,6 @@ package org.zstack.storage.primary.smp; +import org.apache.commons.lang.StringUtils; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.gc.GC; import org.zstack.core.gc.GCCompletion; @@ -10,6 +11,9 @@ import org.zstack.header.storage.primary.PrimaryStorageVO; import org.zstack.header.volume.VolumeInventory; import org.zstack.header.volume.VolumeType; +import org.zstack.storage.volume.VolumeErrors; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; /** * Created by AlanJager on 2017/3/14. @@ -22,12 +26,18 @@ public class SMPDeleteVolumeGC extends TimeBasedGarbageCollector { @GC public VolumeInventory volume; + private static final CLogger logger = Utils.getLogger(SMPDeleteVolumeGC.class); + @Override protected void triggerNow(GCCompletion completion) { if (!dbf.isExist(primaryStorageUuid, PrimaryStorageVO.class)) { completion.cancel(); return; } + if (StringUtils.isEmpty(volume.getInstallPath())) { + completion.cancel(); + return; + } DeleteVolumeBitsOnPrimaryStorageMsg msg = new DeleteVolumeBitsOnPrimaryStorageMsg(); msg.setInstallPath(volume.getInstallPath()); @@ -40,6 +50,11 @@ protected void triggerNow(GCCompletion completion) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { + if (reply.getError().isError(VolumeErrors.VOLUME_IN_USE)) { + logger.warn(String.format("unable to delete path:%s right now, cancel this GC job because it's in use", msg.getInstallPath())); + completion.cancel(); + return; + } completion.fail(reply.getError()); } else { completion.success(); diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java index c7303a733c1..38aeef95cc1 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageBase.java @@ -34,9 +34,13 @@ import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; import org.zstack.header.storage.snapshot.VolumeSnapshotVO; import org.zstack.header.volume.*; +import org.zstack.kvm.KVMAgentCommands; import org.zstack.kvm.KVMConstant; -import org.zstack.storage.primary.PrimaryStorageBase; -import org.zstack.storage.primary.PrimaryStorageCapacityUpdater; +import org.zstack.kvm.KVMHostInventory; +import org.zstack.kvm.KVMTakeSnapshotExtensionPoint; +import org.zstack.storage.primary.*; +import org.zstack.storage.snapshot.reference.VolumeSnapshotReferenceUtils; +import org.zstack.storage.volume.VolumeErrors; import org.zstack.storage.volume.VolumeSystemTags; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.Utils; @@ -51,6 +55,7 @@ import static org.zstack.core.Platform.err; import static org.zstack.core.Platform.operr; +import static org.zstack.storage.primary.smp.SMPPrimaryStorageFactory.type; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -58,7 +63,7 @@ * Created by xing5 on 2016/3/26. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) -public class SMPPrimaryStorageBase extends PrimaryStorageBase { +public class SMPPrimaryStorageBase extends PrimaryStorageBase implements KVMTakeSnapshotExtensionPoint { private static final CLogger logger = Utils.getLogger(SMPPrimaryStorageBase.class); @Autowired @@ -74,13 +79,17 @@ public SMPPrimaryStorageBase(PrimaryStorageVO self) { } private HypervisorFactory getHypervisorFactoryByHypervisorType(String hvType) { + return getHypervisorFactoryByHypervisorAndExtensionType(hvType, null); + } + + protected HypervisorFactory getHypervisorFactoryByHypervisorAndExtensionType(String hvType, String extensionType) { for (HypervisorFactory f : pluginRgty.getExtensionList(HypervisorFactory.class)) { - if (hvType.equals(f.getHypervisorType())) { + if (hvType.equals(f.getHypervisorType()) && Objects.equals(f.getExtensionType(), extensionType)) { return f; } } - throw new CloudRuntimeException(String.format("cannot find HypervisorFactory[type = %s]", hvType)); + throw new CloudRuntimeException(String.format("cannot find HypervisorFactory[hypervisroType = %s, extensionType = %s]", hvType, extensionType)); } protected HypervisorFactory getHypervisorFactoryByHostUuid(String huuid) { @@ -91,12 +100,15 @@ protected HypervisorFactory getHypervisorFactoryByHostUuid(String huuid) { return getHypervisorFactoryByHypervisorType(hvType); } - protected HypervisorFactory getHypervisorFactoryByClusterUuid(String cuuid) { + protected String getHypervisorTypeByClusterUuid(String cuuid) { SimpleQuery q = dbf.createQuery(ClusterVO.class); q.select(ClusterVO_.hypervisorType); q.add(ClusterVO_.uuid, Op.EQ, cuuid); - String hvType = q.findValue(); + return q.findValue(); + } + protected HypervisorFactory getHypervisorFactoryByClusterUuid(String cuuid) { + String hvType = getHypervisorTypeByClusterUuid(cuuid); return getHypervisorFactoryByHypervisorType(hvType); } @@ -169,6 +181,14 @@ public void success(DeleteVolumeOnPrimaryStorageReply reply) { @Override public void fail(ErrorCode errorCode) { + DeleteVolumeOnPrimaryStorageReply reply = new DeleteVolumeOnPrimaryStorageReply(); + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete path:%s right now, skip this GC job because it's in use", msg.getVolume().getInstallPath())); + reply.setError(errorCode); + bus.reply(msg, reply); + return; + } + logger.debug( String.format("can't delete volume[uuid:%s] right now, add a GC job", msg.getVolume().getUuid())); SMPDeleteVolumeGC gc = new SMPDeleteVolumeGC(); gc.NAME = String.format("gc-smp-%s-volume-%s", self.getUuid(), msg.getVolume().getUuid()); @@ -177,7 +197,6 @@ public void fail(ErrorCode errorCode) { gc.volume = msg.getVolume(); gc.deduplicateSubmit(SMPPrimaryStorageGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); - DeleteVolumeOnPrimaryStorageReply reply = new DeleteVolumeOnPrimaryStorageReply(); bus.reply(msg, reply); } }); @@ -377,6 +396,7 @@ protected void handle(AskVolumeSnapshotCapabilityMsg msg) { String volumeType = msg.getVolume().getType(); if (VolumeType.Data.toString().equals(volumeType) || VolumeType.Root.toString().equals(volumeType)) { capability.setArrangementType(VolumeSnapshotArrangementType.CHAIN); + capability.setPlacementType(VolumeSnapshotCapability.VolumeSnapshotPlacementType.EXTERNAL); } else if (VolumeType.Memory.toString().equals(volumeType)) { capability.setArrangementType(VolumeSnapshotArrangementType.INDIVIDUAL); } else { @@ -413,6 +433,38 @@ public void fail(ErrorCode errorCode) { }); } + @Override + protected void handle(EstimateVolumeTemplateSizeOnPrimaryStorageMsg msg) { + SimpleQuery q = dbf.createQuery(VolumeVO.class); + q.select(VolumeVO_.format); + q.add(VolumeVO_.uuid, Op.EQ, msg.getVolumeUuid()); + String format = q.findValue(); + + HypervisorType type = VolumeFormat.getMasterHypervisorTypeByVolumeFormat(format); + HypervisorFactory f = getHypervisorFactoryByHypervisorType(type.toString()); + HypervisorBackend bkd = f.getHypervisorBackend(self); + bkd.handle(msg, new ReturnValueCompletion(msg) { + @Override + public void success(EstimateVolumeTemplateSizeOnPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + EstimateVolumeTemplateSizeOnPrimaryStorageReply reply = new EstimateVolumeTemplateSizeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(BatchSyncVolumeSizeOnPrimaryStorageMsg msg) { + BatchSyncVolumeSizeOnPrimaryStorageReply reply = new BatchSyncVolumeSizeOnPrimaryStorageReply(); + bus.reply(msg, reply); + logger.warn("Not supported at current edition"); + } + protected void saveVolumeProvisioningStrategy(String volumeUuid, VolumeProvisioningStrategy strategy) { if (!VolumeSystemTags.VOLUME_PROVISIONING_STRATEGY.hasTag(volumeUuid)) { SystemTagCreator tagCreator = VolumeSystemTags.VOLUME_PROVISIONING_STRATEGY.newSystemTagCreator(volumeUuid); @@ -605,11 +657,18 @@ public void handleLocalMessage(Message msg) { handle((CancelDownloadBitsFromKVMHostToPrimaryStorageMsg) msg); } else if ((msg instanceof GetDownloadBitsFromKVMHostProgressMsg)) { handle((GetDownloadBitsFromKVMHostProgressMsg) msg); + } else if (msg instanceof GetVolumeBackingChainFromPrimaryStorageMsg) { + handle((GetVolumeBackingChainFromPrimaryStorageMsg) msg); + } else if (msg instanceof ResizeVolumeOnPrimaryStorageMsg) { + handle((ResizeVolumeOnPrimaryStorageMsg) msg); + } else if (msg instanceof CommitVolumeSnapshotOnPrimaryStorageMsg) { + handle((CommitVolumeSnapshotOnPrimaryStorageMsg) msg); + } else if (msg instanceof PullVolumeSnapshotOnPrimaryStorageMsg) { + handle((PullVolumeSnapshotOnPrimaryStorageMsg) msg); } else { super.handleLocalMessage(msg); } } - private void handle(final DownloadBitsFromKVMHostToPrimaryStorageMsg msg) { HypervisorFactory f = getHypervisorFactoryByHostUuid(msg.getDestHostUuid()); HypervisorBackend bkd = f.getHypervisorBackend(self); @@ -665,6 +724,48 @@ public void fail(ErrorCode errorCode) { }); } + private void handle(GetVolumeBackingChainFromPrimaryStorageMsg msg) { + HypervisorBackend bkd; + if (msg.getHostUuid() == null) { + bkd = getHypervisorBackendByVolumeUuid(msg.getVolumeUuid()); + } else { + HypervisorFactory f = getHypervisorFactoryByHostUuid(msg.getHostUuid()); + bkd = f.getHypervisorBackend(self); + } + + bkd.handle(msg, new ReturnValueCompletion(msg) { + public void success(GetVolumeBackingChainFromPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + GetVolumeBackingChainFromPrimaryStorageReply reply = new GetVolumeBackingChainFromPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(ResizeVolumeOnPrimaryStorageMsg msg) { + HypervisorBackend bkd = getHypervisorBackendByVolumeUuid(msg.getVolume().getUuid()); + bkd.handle(msg, new ReturnValueCompletion(msg) { + + @Override + public void success(ResizeVolumeOnPrimaryStorageReply returnValue) { + bus.reply(msg, returnValue); + } + + @Override + public void fail(ErrorCode errorCode) { + ResizeVolumeOnPrimaryStorageReply reply = new ResizeVolumeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(final DeleteImageCacheOnPrimaryStorageMsg msg) { DeleteImageCacheOnPrimaryStorageReply sreply = new DeleteImageCacheOnPrimaryStorageReply(); @@ -714,7 +815,7 @@ public void handle(ErrorCode errCode, Map data) { @Override protected void handle(APICleanUpImageCacheOnPrimaryStorageMsg msg) { APICleanUpImageCacheOnPrimaryStorageEvent evt = new APICleanUpImageCacheOnPrimaryStorageEvent(msg.getId()); - imageCacheCleaner.cleanup(msg.getUuid(), false); + imageCacheCleaner.cleanup(msg.getUuid(), new ImageCacheCleanParam(true, msg.isForce())); bus.publish(evt); } @@ -788,15 +889,33 @@ private void handle(SMPPrimaryStorageHypervisorSpecificMessage msg) { protected void handle(final MergeVolumeSnapshotOnPrimaryStorageMsg msg) { HypervisorBackend bkd = getHypervisorBackendByVolumeUuid(msg.getTo().getUuid()); - bkd.handle(msg, new ReturnValueCompletion(msg) { + MergeVolumeSnapshotOnPrimaryStorageReply reply = new MergeVolumeSnapshotOnPrimaryStorageReply(); + bkd.stream(msg.getFrom(), msg.getTo(), msg.isFullRebase(), new Completion(msg) { @Override - public void success(MergeVolumeSnapshotOnPrimaryStorageReply returnValue) { - bus.reply(msg, returnValue); + public void success() { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + @Override + protected void handle(FlattenVolumeOnPrimaryStorageMsg msg) { + HypervisorBackend bkd = getHypervisorBackendByVolumeUuid(msg.getVolume().getUuid()); + FlattenVolumeOnPrimaryStorageReply reply = new FlattenVolumeOnPrimaryStorageReply(); + bkd.stream(null, msg.getVolume(), true, new Completion(msg) { + @Override + public void success() { + bus.reply(msg, reply); } @Override public void fail(ErrorCode errorCode) { - MergeVolumeSnapshotOnPrimaryStorageReply reply = new MergeVolumeSnapshotOnPrimaryStorageReply(); reply.setError(errorCode); bus.reply(msg, reply); } @@ -1030,8 +1149,38 @@ protected void handle(CheckVolumeSnapshotOperationOnPrimaryStorageMsg msg) { bus.reply(msg, reply); } + private ErrorCode checkChangeVolumeType(String volumeUuid) { + List refVols = VolumeSnapshotReferenceUtils.getReferenceVolume(volumeUuid); + if (refVols.isEmpty()) { + return null; + } + + List infos = refVols.stream().map(v -> String.format("uuid:%s, name:%s", v.getUuid(), v.getName())).collect(Collectors.toList()); + return operr("volume[uuid:%s] has reference volume[%s], can not change volume type before flatten " + + "them and their descendants", volumeUuid, infos.toString()); + } + + @Override + protected void handle(CheckChangeVolumeTypeOnPrimaryStorageMsg msg) { + CheckChangeVolumeTypeOnPrimaryStorageReply reply = new CheckChangeVolumeTypeOnPrimaryStorageReply(); + ErrorCode errorCode = checkChangeVolumeType(msg.getVolume().getUuid()); + if (errorCode != null) { + reply.setError(errorCode);; + } + + bus.reply(msg, reply); + } + @Override protected void handle(ChangeVolumeTypeOnPrimaryStorageMsg msg) { + ErrorCode errorCode = checkChangeVolumeType(msg.getVolume().getUuid()); + if (errorCode != null) { + ChangeVolumeTypeOnPrimaryStorageReply reply = new ChangeVolumeTypeOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + return; + } + HypervisorBackend backend = getHypervisorBackendByVolumeUuid(msg.getVolume().getUuid()); backend.handle(msg, new ReturnValueCompletion(msg) { @Override @@ -1047,4 +1196,129 @@ public void fail(ErrorCode errorCode) { } }); } + + @Override + protected void handle(UnlinkBitsOnPrimaryStorageMsg msg) { + HypervisorBackend backend = getHypervisorBackendByVolumeUuid(msg.getResourceUuid()); + backend.handle(msg, new ReturnValueCompletion(msg) { + @Override + public void success(UnlinkBitsOnPrimaryStorageReply reply) { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + UnlinkBitsOnPrimaryStorageReply reply = new UnlinkBitsOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(final CommitVolumeSnapshotOnPrimaryStorageMsg msg) { + HypervisorBackend bkd = getHypervisorBackendByVolumeUuid(msg.getVolume().getUuid()); + bkd.handle(msg, new ReturnValueCompletion(msg) { + @Override + public void success(CommitVolumeSnapshotOnPrimaryStorageReply reply) { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + CommitVolumeSnapshotOnPrimaryStorageReply reply = new CommitVolumeSnapshotOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private void handle(final PullVolumeSnapshotOnPrimaryStorageMsg msg) { + HypervisorBackend bkd = getHypervisorBackendByVolumeUuid(msg.getVolume().getUuid()); + bkd.handle(msg, new ReturnValueCompletion(msg) { + @Override + public void success(PullVolumeSnapshotOnPrimaryStorageReply reply) { + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + PullVolumeSnapshotOnPrimaryStorageReply reply = new PullVolumeSnapshotOnPrimaryStorageReply(); + reply.setError(errorCode); + bus.reply(msg, reply); + } + }); + } + + private boolean isSharedMountPointPrimaryStorage(String psUuid) { + return psUuid != null && Q.New(PrimaryStorageVO.class) + .eq(PrimaryStorageVO_.uuid, psUuid) + .eq(PrimaryStorageVO_.type, type.toString()) + .isExists(); + } + + @Override + public void beforeTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd scmd, Completion completion) { + boolean needPreCreateVolume = scmd.isOnline(); + if (!needPreCreateVolume || !isSharedMountPointPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + completion.success(); + return; + } + + HypervisorFactory f = getHypervisorFactoryByHostUuid(msg.getHostUuid()); + HypervisorBackend bkd = f.getHypervisorBackend(dbf.findByUuid(msg.getVolume().getPrimaryStorageUuid(), PrimaryStorageVO.class)); + + VolumeInventory volumeInventory = new VolumeInventory(msg.getVolume()); + volumeInventory.setInstallPath(scmd.getInstallPath()); + volumeInventory.setName(msg.getSnapshotName()); + bkd.createEmptyVolumeWithBackingFile(volumeInventory, msg.getHostUuid(), msg.getVolume().getInstallPath(), new ReturnValueCompletion(completion) { + @Override + public void success(KvmBackend.AgentRsp rsp) { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + public void afterTakeSnapshot(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, KVMAgentCommands.TakeSnapshotResponse rsp) { + } + + @Override + public void afterTakeSnapshotFailed(KVMHostInventory host, TakeSnapshotOnHypervisorMsg msg, KVMAgentCommands.TakeSnapshotCmd cmd, KVMAgentCommands.TakeSnapshotResponse rsp, ErrorCode err) { + boolean needPreCreateVolume = cmd.isOnline(); + if (!needPreCreateVolume || !isSharedMountPointPrimaryStorage(msg.getVolume().getPrimaryStorageUuid())) { + return; + } + HypervisorFactory f = getHypervisorFactoryByHostUuid(msg.getHostUuid()); + HypervisorBackend bkd = f.getHypervisorBackend(dbf.findByUuid(msg.getVolume().getPrimaryStorageUuid(), PrimaryStorageVO.class)); + bkd.deleteBits(cmd.getInstallPath(), new Completion(msg) { + @Override + public void success() { + logger.debug(String.format("successfully cleaned garbage snapshot volume[name: %s, installpath:%s] for take snapshot on volume[%s]", + msg.getSnapshotName(), cmd.getInstallPath(), msg.getVolume().getUuid())); + } + + @Override + public void fail(ErrorCode errorCode) { + if (errorCode.isError(VolumeErrors.VOLUME_IN_USE)) { + logger.debug(String.format("unable to delete path:%s right now, skip this GC job because it's in use", cmd.getInstallPath())); + return; + } + logger.debug(String.format("failed to clean garbage snapshot volume[name: %s, installpath:%s] for failed taking snapshot on volume[%s], "+ + "create gc job to clean garbage late", msg.getSnapshotName(), cmd.getInstallPath(), msg.getVolume().getUuid())); + SMPDeleteVolumeGC gc = new SMPDeleteVolumeGC(); + gc.NAME = String.format("gc-smp-%s-snapshot-%s", msg.getVolume().getPrimaryStorageUuid(), cmd.getInstallPath()); + gc.primaryStorageUuid = msg.getVolume().getPrimaryStorageUuid(); + gc.hypervisorType = VolumeFormat.getMasterHypervisorTypeByVolumeFormat(msg.getVolume().getFormat()).toString(); + VolumeInventory inv = new VolumeInventory(msg.getVolume()); + inv.setInstallPath(cmd.getInstallPath()); + gc.volume = inv; + gc.submit(SMPPrimaryStorageGlobalConfig.GC_INTERVAL.value(Long.class), TimeUnit.SECONDS); + } + }); + } } diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java index 201e5e6ed68..76425ea21cb 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageFactory.java @@ -86,6 +86,11 @@ public PrimaryStorageInventory getInventory(String uuid) { return PrimaryStorageInventory.valueOf(dbf.findByUuid(uuid, PrimaryStorageVO.class)); } + @Override + public void validateStorageProtocol(String protocol) { + + } + @VmExpungeRootVolumeValidator.VmExpungeRootVolumeValidatorMethod static void vmExpungeRootVolumeValidator(String vmUuid, String volumeUuid) { new SQLBatch() { @@ -174,27 +179,27 @@ public void rollback(FlowRollback trigger, Map data) { public void run(final FlowTrigger trigger, Map data) { final ParamOut out = (ParamOut) data.get(ParamOut.class); - BackupStorageAskInstallPathMsg ask = new BackupStorageAskInstallPathMsg(); - ask.setImageUuid(paramIn.getImage().getUuid()); - ask.setBackupStorageUuid(paramIn.getBackupStorageUuid()); - ask.setImageMediaType(paramIn.getImage().getMediaType()); - bus.makeTargetServiceIdByResourceUuid(ask, BackupStorageConstant.SERVICE_ID, paramIn.getBackupStorageUuid()); - MessageReply ar = bus.call(ask); - if (!ar.isSuccess()) { - trigger.fail(ar.getError()); - return; - } + BackupStorageAskInstallPathMsg ask = new BackupStorageAskInstallPathMsg(); + ask.setImageUuid(paramIn.getImage().getUuid()); + ask.setBackupStorageUuid(paramIn.getBackupStorageUuid()); + ask.setImageMediaType(paramIn.getImage().getMediaType()); + bus.makeTargetServiceIdByResourceUuid(ask, BackupStorageConstant.SERVICE_ID, paramIn.getBackupStorageUuid()); + MessageReply ar = bus.call(ask); + if (!ar.isSuccess()) { + trigger.fail(ar.getError()); + return; + } - String bsInstallPath = ((BackupStorageAskInstallPathReply)ar).getInstallPath(); + String bsInstallPath = ((BackupStorageAskInstallPathReply)ar).getInstallPath(); - UploadBitsToBackupStorageMsg msg = new UploadBitsToBackupStorageMsg(); - msg.setImageUuid(paramIn.getImage().getUuid()); - msg.setPrimaryStorageUuid(paramIn.getPrimaryStorageUuid()); - msg.setHypervisorType(hvType.toString()); - msg.setPrimaryStorageInstallPath(ctx.temporaryInstallPath); - msg.setBackupStorageUuid(paramIn.getBackupStorageUuid()); - msg.setBackupStorageInstallPath(bsInstallPath); - bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, paramIn.getPrimaryStorageUuid()); + UploadBitsToBackupStorageMsg msg = new UploadBitsToBackupStorageMsg(); + msg.setImageUuid(paramIn.getImage().getUuid()); + msg.setPrimaryStorageUuid(paramIn.getPrimaryStorageUuid()); + msg.setHypervisorType(hvType.toString()); + msg.setPrimaryStorageInstallPath(ctx.temporaryInstallPath); + msg.setBackupStorageUuid(paramIn.getBackupStorageUuid()); + msg.setBackupStorageInstallPath(bsInstallPath); + bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, paramIn.getPrimaryStorageUuid()); bus.send(msg, new CloudBusCallBack(trigger) { diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageSimulator.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageSimulator.java index 6dc8ed33cdb..84134edb8b3 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageSimulator.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPPrimaryStorageSimulator.java @@ -5,7 +5,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; -import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @@ -14,6 +13,9 @@ import org.zstack.storage.primary.smp.KvmBackend.*; import org.zstack.utils.gson.JSONObjectUtil; +import static org.zstack.storage.primary.smp.SftpBackupStorageKvmDownloader.DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH; +import static org.zstack.storage.primary.smp.SftpBackupStorageKvmUploader.UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH; + /** * Created by xing5 on 2016/3/27. */ @@ -61,7 +63,7 @@ String createRootVolume(HttpEntity entity) { String deleteBits(HttpEntity entity) { DeleteBitsCmd cmd = JSONObjectUtil.toObject(entity.getBody(), DeleteBitsCmd.class); config.deleteBitsCmds.add(cmd); - reply(entity, new AgentRsp()); + reply(entity, new DeleteRsp()); return null; } @@ -74,7 +76,7 @@ String createTemplateFromVolume(HttpEntity entity) { return null; } - @RequestMapping(value=KvmBackend.UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH, method= RequestMethod.POST) + @RequestMapping(value=UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH, method= RequestMethod.POST) public @ResponseBody String uploadBitsToSftp(HttpEntity entity) { SftpUploadBitsCmd cmd = JSONObjectUtil.toObject(entity.getBody(), SftpUploadBitsCmd.class); @@ -83,7 +85,7 @@ String uploadBitsToSftp(HttpEntity entity) { return null; } - @RequestMapping(value=KvmBackend.DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH, method= RequestMethod.POST) + @RequestMapping(value=DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH, method= RequestMethod.POST) public @ResponseBody String downloadBitsFromSftp(HttpEntity entity) { SftpDownloadBitsCmd cmd = JSONObjectUtil.toObject(entity.getBody(), SftpDownloadBitsCmd.class); diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPSnapshotDeletionProtector.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPSnapshotDeletionProtector.java index 375e0b58fee..31286f96c51 100755 --- a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPSnapshotDeletionProtector.java +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SMPSnapshotDeletionProtector.java @@ -19,14 +19,6 @@ public String getPrimaryStorageType() { @Override public void protect(VolumeSnapshotInventory snapshot, Completion completion) { - String backingToVolumeUuid = VolumeSnapshotSystemTags.BACKING_TO_VOLUME.getTokenByResourceUuid( - snapshot.getUuid(), VolumeSnapshotSystemTags.BACKING_VOLUME_TOKEN); - if (backingToVolumeUuid != null) { - completion.fail(operr("snapshot[uuid:%s] is backing file of volume[uuid:%s], cannot delete.", - snapshot.getUuid(), backingToVolumeUuid)); - return; - } - Path path = Paths.get(snapshot.getPrimaryStorageInstallPath()); if (!path.getParent().toString().contains(snapshot.getVolumeUuid())) { completion.fail(inerr("the snapshot[name:%s, uuid:%s, path: %s] seems not belong to the volume[uuid:%s]", diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmDownloader.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmDownloader.java new file mode 100644 index 00000000000..12b4f78dc07 --- /dev/null +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmDownloader.java @@ -0,0 +1,81 @@ +package org.zstack.storage.primary.smp; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.backup.BackupStorageConstant; +import org.zstack.header.storage.primary.PrimaryStorageInventory; +import org.zstack.storage.backup.sftp.GetSftpBackupStorageDownloadCredentialMsg; +import org.zstack.storage.backup.sftp.GetSftpBackupStorageDownloadCredentialReply; + +/** + * @ Author : yh.w + * @ Date : Created in 17:14 2023/7/7 + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = true) +public class SftpBackupStorageKvmDownloader extends BackupStorageKvmDownloader { + @Autowired + private CloudBus bus; + @Autowired + protected DatabaseFacade dbf; + + private PrimaryStorageInventory pinv; + private String bsUuid; + + public static final String DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH = "/sharedmountpointprimarystorage/sftp/download"; + + public SftpBackupStorageKvmDownloader(PrimaryStorageInventory ps, String backupStorageUuid) { + pinv = ps; + bsUuid = backupStorageUuid; + } + + public static SftpBackupStorageKvmDownloader createDownloader(PrimaryStorageInventory ps, String bsUuid) { + return new SftpBackupStorageKvmDownloader(ps, bsUuid); + } + + @Override + public void downloadBits(final String bsPath, final String psPath, boolean isData, final Completion completion) { + GetSftpBackupStorageDownloadCredentialMsg gmsg = new GetSftpBackupStorageDownloadCredentialMsg(); + gmsg.setBackupStorageUuid(bsUuid); + bus.makeTargetServiceIdByResourceUuid(gmsg, BackupStorageConstant.SERVICE_ID, bsUuid); + + bus.send(gmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + final GetSftpBackupStorageDownloadCredentialReply greply = reply.castReply(); + KvmBackend.SftpDownloadBitsCmd cmd = new KvmBackend.SftpDownloadBitsCmd(); + cmd.hostname = greply.getHostname(); + cmd.username = greply.getUsername(); + cmd.sshKey = greply.getSshKey(); + cmd.sshPort = greply.getSshPort(); + cmd.backupStorageInstallPath = bsPath; + cmd.primaryStorageInstallPath = psPath; + cmd.primaryStorageUuid = pinv.getUuid(); + + new KvmAgentCommandDispatcher(pinv.getUuid()).go(DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH, cmd, KvmBackend.AgentRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(KvmBackend.AgentRsp returnValue) { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + }); + } +} diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmFactory.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmFactory.java new file mode 100644 index 00000000000..ddceae9c26f --- /dev/null +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmFactory.java @@ -0,0 +1,25 @@ +package org.zstack.storage.primary.smp; + +import org.zstack.header.storage.primary.PrimaryStorageInventory; +import org.zstack.storage.backup.sftp.SftpBackupStorageConstant; + +/** + * @ Author : yh.w + * @ Date : Created in 17:04 2023/7/7 + */ +public class SftpBackupStorageKvmFactory implements BackupStorageKvmFactory { + @Override + public String getBackupStorageType() { + return SftpBackupStorageConstant.SFTP_BACKUP_STORAGE_TYPE; + } + + @Override + public BackupStorageKvmUploader createUploader(PrimaryStorageInventory ps, String bsUuid) { + return SftpBackupStorageKvmUploader.createUploader(ps, bsUuid); + } + + @Override + public BackupStorageKvmDownloader createDownloader(PrimaryStorageInventory ps, String bsUuid) { + return SftpBackupStorageKvmDownloader.createDownloader(ps, bsUuid); + } +} diff --git a/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmUploader.java b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmUploader.java new file mode 100644 index 00000000000..e2a8111b595 --- /dev/null +++ b/plugin/sharedMountPointPrimaryStorage/src/main/java/org/zstack/storage/primary/smp/SftpBackupStorageKvmUploader.java @@ -0,0 +1,80 @@ +package org.zstack.storage.primary.smp; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.message.MessageReply; +import org.zstack.header.storage.backup.BackupStorageConstant; +import org.zstack.header.storage.primary.PrimaryStorageInventory; +import org.zstack.storage.backup.sftp.GetSftpBackupStorageDownloadCredentialMsg; +import org.zstack.storage.backup.sftp.GetSftpBackupStorageDownloadCredentialReply; + +/** + * @ Author : yh.w + * @ Date : Created in 17:08 2023/7/7 + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE, dependencyCheck = true) +public class SftpBackupStorageKvmUploader extends BackupStorageKvmUploader { + @Autowired + private CloudBus bus; + @Autowired + protected DatabaseFacade dbf; + + private PrimaryStorageInventory pinv; + private String bsUuid; + + public static final String UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH = "/sharedmountpointprimarystorage/sftp/upload"; + + public SftpBackupStorageKvmUploader(PrimaryStorageInventory ps, String backupStorageUuid) { + pinv = ps; + bsUuid = backupStorageUuid; + } + + public static SftpBackupStorageKvmUploader createUploader(PrimaryStorageInventory ps, String bsUuid) { + return new SftpBackupStorageKvmUploader(ps, bsUuid); + } + + @Override + public void uploadBits(final String imageUuid, final String bsPath, final String psPath, final ReturnValueCompletion completion) { + GetSftpBackupStorageDownloadCredentialMsg gmsg = new GetSftpBackupStorageDownloadCredentialMsg(); + gmsg.setBackupStorageUuid(bsUuid); + bus.makeTargetServiceIdByResourceUuid(gmsg, BackupStorageConstant.SERVICE_ID, bsUuid); + bus.send(gmsg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + final GetSftpBackupStorageDownloadCredentialReply r = reply.castReply(); + KvmBackend.SftpUploadBitsCmd cmd = new KvmBackend.SftpUploadBitsCmd(); + cmd.primaryStorageInstallPath = psPath; + cmd.backupStorageInstallPath = bsPath; + cmd.hostname = r.getHostname(); + cmd.username = r.getUsername(); + cmd.sshKey = r.getSshKey(); + cmd.sshPort = r.getSshPort(); + cmd.primaryStorageUuid = pinv.getUuid(); + + new KvmAgentCommandDispatcher(pinv.getUuid()).go(UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH, cmd, KvmBackend.AgentRsp.class, new ReturnValueCompletion(completion) { + @Override + public void success(KvmBackend.AgentRsp returnValue) { + completion.success(bsPath); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + }); + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/pom.xml b/plugin/sshKeyPair/pom.xml new file mode 100644 index 00000000000..51e8e74c9a0 --- /dev/null +++ b/plugin/sshKeyPair/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + org.zstack + plugin + 5.4.0 + + + sshKeyPair + + + org.zstack + kvm + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + com.jcraft + jsch + 0.1.55 + + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceEvent.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceEvent.java new file mode 100644 index 00000000000..0fe038b174e --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceEvent.java @@ -0,0 +1,33 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIAttachSshKeyPairToVmInstanceEvent extends APIEvent { + private SshKeyPairInventory inventory; + + public APIAttachSshKeyPairToVmInstanceEvent() { + } + + public APIAttachSshKeyPairToVmInstanceEvent(String msgId){ super(msgId); } + + public SshKeyPairInventory getInventory() { + return inventory; + } + public void setInventory(SshKeyPairInventory inventory) { + this.inventory = inventory; + } + + public static APIAttachSshKeyPairToVmInstanceEvent __example__() { + APIAttachSshKeyPairToVmInstanceEvent event = new APIAttachSshKeyPairToVmInstanceEvent(); + SshKeyPairInventory inv = new SshKeyPairInventory(); + + inv.setUuid(uuid()); + inv.setName("ssh-key-pair"); + inv.setUuid(uuid()); + inv.setPublicKey(""); + event.setInventory(inv); + return event; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceEventDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..eaa4207d351 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.SshKeyPairInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "云主机挂载密钥对返回" + + ref { + name "inventory" + path "org.zstack.header.sshkeypair.APIAttachSshKeyPairToVmInstanceEvent.inventory" + desc "null" + type "SshKeyPairInventory" + since "4.7.21" + clz SshKeyPairInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APIAttachSshKeyPairToVmInstanceEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceMsg.java new file mode 100644 index 00000000000..535689b1325 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceMsg.java @@ -0,0 +1,46 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vm.VmInstanceVO; + +@RestRequest( + path = "/ssh-key-pair/{sshKeyPairUuid}/vm-instance/{vmInstanceUuid}", + method = HttpMethod.POST, + responseClass = APIAttachSshKeyPairToVmInstanceEvent.class, + parameterName = "params" +) +public class APIAttachSshKeyPairToVmInstanceMsg extends APIMessage implements SshKeyPairMessage { + @APIParam(resourceType = VmInstanceVO.class, checkAccount = true, operationTarget = true) + private String vmInstanceUuid; + + @APIParam(resourceType = SshKeyPairVO.class, checkAccount = true, operationTarget = true) + private String sshKeyPairUuid; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + @Override + public String getSshKeyPairUuid() { + return sshKeyPairUuid; + } + + public void setSshKeyPairUuid(String sshKeyPairUuid) { + this.sshKeyPairUuid = sshKeyPairUuid; + } + + public static APIAttachSshKeyPairToVmInstanceMsg __example__() { + APIAttachSshKeyPairToVmInstanceMsg msg = new APIAttachSshKeyPairToVmInstanceMsg(); + msg.setVmInstanceUuid(uuid()); + msg.setSshKeyPairUuid(uuid()); + + return msg; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..6fdeaf02f57 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIAttachSshKeyPairToVmInstanceMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APIAttachSshKeyPairToVmInstanceEvent + +doc { + title "AttachSshKeyPairToVmInstance" + + category "sshKeyPair" + + desc """云主机挂载密钥对""" + + rest { + request { + url "POST /v1/ssh-key-pair/{sshKeyPairUuid}/vm-instance/{vmInstanceUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIAttachSshKeyPairToVmInstanceMsg.class + + desc """""" + + params { + + column { + name "vmInstanceUuid" + enclosedIn "params" + desc "云主机UUID" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "sshKeyPairUuid" + enclosedIn "params" + desc "" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIAttachSshKeyPairToVmInstanceEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairEvent.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairEvent.java new file mode 100644 index 00000000000..a3ac6ac831e --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairEvent.java @@ -0,0 +1,33 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APICreateSshKeyPairEvent extends APIEvent { + private SshKeyPairInventory inventory; + + public APICreateSshKeyPairEvent() { + } + + public APICreateSshKeyPairEvent(String msgId){ super(msgId); } + + public SshKeyPairInventory getInventory() { + return inventory; + } + public void setInventory(SshKeyPairInventory inventory) { + this.inventory = inventory; + } + + public static APICreateSshKeyPairEvent __example__() { + APICreateSshKeyPairEvent event = new APICreateSshKeyPairEvent(); + SshKeyPairInventory inv = new SshKeyPairInventory(); + + inv.setUuid(uuid()); + inv.setName("ssh-key-pair"); + inv.setUuid(uuid()); + inv.setPublicKey(""); + event.setInventory(inv); + return event; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairEventDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..0944a07bd98 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.SshKeyPairInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "创建密钥对返回" + + ref { + name "inventory" + path "org.zstack.header.sshkeypair.APICreateSshKeyPairEvent.inventory" + desc "null" + type "SshKeyPairInventory" + since "4.7.21" + clz SshKeyPairInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APICreateSshKeyPairEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairMsg.java new file mode 100644 index 00000000000..0f3b67ecc49 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairMsg.java @@ -0,0 +1,61 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; +import org.zstack.header.volume.VolumeVO; +import org.zstack.sshkeypair.SshKeyPairConstant; + +@TagResourceType(VolumeVO.class) +@RestRequest( + path = "/ssh-key-pair", + method = HttpMethod.POST, + responseClass = APICreateSshKeyPairEvent.class, + parameterName = "params" +) +public class APICreateSshKeyPairMsg extends APICreateMessage { + @APIParam(maxLength = 255, validRegexValues = SshKeyPairConstant.SSH_KEY_PAIR_NAME_REGEX) + private String name; + + @APIParam(maxLength = 2048, required = false) + private String description; + + @APIParam(maxLength = 4096) + private String publicKey; + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public static APICreateSshKeyPairMsg __example__() { + APICreateSshKeyPairMsg ret = new APICreateSshKeyPairMsg(); + ret.name = "ssh-key-pair"; + ret.description = "description"; + ret.publicKey = ""; + return ret; + } + +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..55839ece2f5 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APICreateSshKeyPairMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APICreateSshKeyPairEvent + +doc { + title "CreateSshKeyPair" + + category "sshKeyPair" + + desc """创建密钥对""" + + rest { + request { + url "POST /v1/ssh-key-pair" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateSshKeyPairMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "4.7.21" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "publicKey" + enclosedIn "params" + desc "" + location "body" + type "String" + optional false + since "4.7.21" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APICreateSshKeyPairEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairEvent.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairEvent.java new file mode 100644 index 00000000000..6d3b709df31 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairEvent.java @@ -0,0 +1,17 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDeleteSshKeyPairEvent extends APIEvent { + public APIDeleteSshKeyPairEvent(){} + + public APIDeleteSshKeyPairEvent(String msgId) { super(msgId); } + + public static APIDeleteSshKeyPairEvent __example__() { + APIDeleteSshKeyPairEvent event = new APIDeleteSshKeyPairEvent(); + event.setSuccess(true); + return event; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairEventDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..b8c7ecf30a0 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "删除密钥对返回" + + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APIDeleteSshKeyPairEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairMsg.java new file mode 100644 index 00000000000..5c4e544ad7d --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairMsg.java @@ -0,0 +1,41 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/ssh-key-pair/{uuid}", + method = HttpMethod.DELETE, + responseClass = APIDeleteSshKeyPairEvent.class +) +public class APIDeleteSshKeyPairMsg extends APIMessage implements SshKeyPairMessage, APIAuditor { + @APIParam(resourceType = SshKeyPairVO.class, operationTarget = true, checkAccount = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + @Override + public String getSshKeyPairUuid() { return uuid; } + + public static APIDeleteSshKeyPairMsg __example__() { + APIDeleteSshKeyPairMsg msg = new APIDeleteSshKeyPairMsg(); + + msg.setUuid(uuid()); + return msg; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new APIAuditor.Result(((APIDeleteSshKeyPairMsg)msg).getUuid(), SshKeyPairVO.class); + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..01c6998229d --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDeleteSshKeyPairMsgDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APIDeleteSshKeyPairEvent + +doc { + title "DeleteSshKeyPair" + + category "sshKeyPair" + + desc """删除密钥对""" + + rest { + request { + url "DELETE /v1/ssh-key-pair/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeleteSshKeyPairMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIDeleteSshKeyPairEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceEvent.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceEvent.java new file mode 100644 index 00000000000..317d3a988bc --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceEvent.java @@ -0,0 +1,17 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDetachSshKeyPairFromVmInstanceEvent extends APIEvent { + public APIDetachSshKeyPairFromVmInstanceEvent() {} + + public APIDetachSshKeyPairFromVmInstanceEvent(String msgId) { super(msgId); } + + public static APIDetachSshKeyPairFromVmInstanceEvent __example__() { + APIDetachSshKeyPairFromVmInstanceEvent event = new APIDetachSshKeyPairFromVmInstanceEvent(); + event.setSuccess(true); + return event; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceEventDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..45970f516af --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "云主机卸载密钥对返回" + + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APIDetachSshKeyPairFromVmInstanceEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceMsg.java new file mode 100644 index 00000000000..b45f13183cf --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceMsg.java @@ -0,0 +1,45 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.vm.VmInstanceVO; + +@RestRequest( + path = "/ssh-key-pair/{sshKeyPairUuid}/vm-instance/{vmInstanceUuid}", + method = HttpMethod.DELETE, + responseClass = APIDetachSshKeyPairFromVmInstanceEvent.class +) +public class APIDetachSshKeyPairFromVmInstanceMsg extends APIMessage implements SshKeyPairMessage { + @APIParam(resourceType = VmInstanceVO.class, checkAccount = true, operationTarget = true) + private String vmInstanceUuid; + + @APIParam(resourceType = SshKeyPairVO.class, checkAccount = true, operationTarget = true) + private String sshKeyPairUuid; + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + @Override + public String getSshKeyPairUuid() { + return sshKeyPairUuid; + } + + public void setSshKeyPairUuid(String sshKeyPairUuid) { + this.sshKeyPairUuid = sshKeyPairUuid; + } + + public static APIDetachSshKeyPairFromVmInstanceMsg __example__() { + APIDetachSshKeyPairFromVmInstanceMsg msg = new APIDetachSshKeyPairFromVmInstanceMsg(); + msg.setVmInstanceUuid(uuid()); + msg.setSshKeyPairUuid(uuid()); + + return msg; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..bf5cc2f78fc --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIDetachSshKeyPairFromVmInstanceMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APIDetachSshKeyPairFromVmInstanceEvent + +doc { + title "DetachSshKeyPairFromVmInstance" + + category "sshKeyPair" + + desc """云主机卸载密钥对""" + + rest { + request { + url "DELETE /v1/ssh-key-pair/{sshKeyPairUuid}/vm-instance/{vmInstanceUuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDetachSshKeyPairFromVmInstanceMsg.class + + desc """""" + + params { + + column { + name "vmInstanceUuid" + enclosedIn "" + desc "云主机UUID" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "sshKeyPairUuid" + enclosedIn "" + desc "" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIDetachSshKeyPairFromVmInstanceEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairMsg.java new file mode 100644 index 00000000000..1e3e368d59d --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairMsg.java @@ -0,0 +1,46 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.*; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; +import org.zstack.header.volume.VolumeVO; +import org.zstack.sshkeypair.SshKeyPairConstant; + +@TagResourceType(VolumeVO.class) +@RestRequest( + path = "/ssh-key-pair/generate", + method = HttpMethod.POST, + responseClass = APIGenerateSshKeyPairReply.class, + parameterName = "params" +) +public class APIGenerateSshKeyPairMsg extends APISyncCallMessage { + @APIParam(maxLength = 255, validRegexValues = SshKeyPairConstant.SSH_KEY_PAIR_NAME_REGEX) + private String name; + + @APIParam(maxLength = 2048, required = false) + private String description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public static APIGenerateSshKeyPairMsg __example__() { + APIGenerateSshKeyPairMsg ret = new APIGenerateSshKeyPairMsg(); + ret.name = "ssh-key-pair"; + ret.description = "description"; + return ret; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..d9ecbe5798b --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairMsgDoc_zh_cn.groovy @@ -0,0 +1,67 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APIGenerateSshKeyPairReply + +doc { + title "GenerateSshKeyPair" + + category "sshKeyPair" + + desc """生成密钥对""" + + rest { + request { + url "POST /v1/ssh-key-pair/generate" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGenerateSshKeyPairMsg.class + + desc """""" + + params { + + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "4.7.21" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIGenerateSshKeyPairReply.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairReply.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairReply.java new file mode 100644 index 00000000000..dc1c9260dd5 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairReply.java @@ -0,0 +1,31 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.message.APIReply; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIGenerateSshKeyPairReply extends APIReply { + + private SshPrivateKeyPairInventory inventory; + + public SshPrivateKeyPairInventory getInventory() { + return inventory; + } + public void setInventory(SshPrivateKeyPairInventory inventory) { + this.inventory = inventory; + } + + + public static APIGenerateSshKeyPairReply __example__() { + APIGenerateSshKeyPairReply event = new APIGenerateSshKeyPairReply(); + SshPrivateKeyPairInventory inv = new SshPrivateKeyPairInventory(); + + inv.setUuid(uuid()); + inv.setName("ssh-key-pair"); + inv.setUuid(uuid()); + inv.setPublicKey("ssh-public-key"); + inv.setPrivateKey("ssh-private-key"); + event.setInventory(inv); + return event; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairReplyDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..50f52c9c27c --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIGenerateSshKeyPairReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.SshPrivateKeyPairInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "生成密钥对返回" + + ref { + name "inventory" + path "org.zstack.header.sshkeypair.APIGenerateSshKeyPairReply.inventory" + desc "null" + type "SshPrivateKeyPairInventory" + since "4.7.21" + clz SshPrivateKeyPairInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APIGenerateSshKeyPairReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairMsg.java new file mode 100644 index 00000000000..fafb3949bfd --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairMsg.java @@ -0,0 +1,22 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; + +import java.util.Collections; +import java.util.List; + +@AutoQuery(replyClass = APIQuerySshKeyPairReply.class, inventoryClass = SshKeyPairInventory.class) +@RestRequest( + path = "/ssh-key-pair", + optionalPaths = {"/ssh-key-pair/{uuid}"}, + responseClass = APIQuerySshKeyPairReply.class, + method = HttpMethod.GET +) +public class APIQuerySshKeyPairMsg extends APIQueryMessage { + public static List __example__() { + return Collections.singletonList("uuid=" + uuid()); + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..646fc37dad8 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairMsgDoc_zh_cn.groovy @@ -0,0 +1,31 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APIQuerySshKeyPairReply +import org.zstack.header.query.APIQueryMessage + +doc { + title "QuerySshKeyPair" + + category "sshKeyPair" + + desc """查询密钥对""" + + rest { + request { + url "GET /v1/ssh-key-pair" + url "GET /v1/ssh-key-pair/{uuid}" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIQuerySshKeyPairMsg.class + + desc """""" + + params APIQueryMessage.class + } + + response { + clz APIQuerySshKeyPairReply.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairReply.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairReply.java new file mode 100644 index 00000000000..12eb252a2ac --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairReply.java @@ -0,0 +1,33 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.query.APIQueryReply; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +import static org.zstack.utils.CollectionDSL.list; + +@RestResponse(allTo = "inventories") +public class APIQuerySshKeyPairReply extends APIQueryReply { + private List inventories; + + public List getInventories() { + return inventories; + } + + public void setInventories(List inventories) { + this.inventories = inventories; + } + + public static APIQuerySshKeyPairReply __example__() { + APIQuerySshKeyPairReply reply = new APIQuerySshKeyPairReply(); + SshKeyPairInventory inv = new SshKeyPairInventory(); + + inv.setUuid(uuid()); + inv.setName("ssh-key-pair"); + inv.setUuid(uuid()); + inv.setPublicKey(""); + reply.setInventories(list(inv)); + return reply; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairReplyDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..03afb94a5a2 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIQuerySshKeyPairReplyDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.SshKeyPairInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "查询密钥对返回" + + ref { + name "inventories" + path "org.zstack.header.sshkeypair.APIQuerySshKeyPairReply.inventories" + desc "null" + type "List" + since "4.7.21" + clz SshKeyPairInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APIQuerySshKeyPairReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairEvent.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairEvent.java new file mode 100644 index 00000000000..dab234b3a13 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairEvent.java @@ -0,0 +1,33 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIUpdateSshKeyPairEvent extends APIEvent { + private SshKeyPairInventory inventory; + + public APIUpdateSshKeyPairEvent() { + } + + public APIUpdateSshKeyPairEvent(String msgId){ super(msgId); } + + public SshKeyPairInventory getInventory() { + return inventory; + } + public void setInventory(SshKeyPairInventory inventory) { + this.inventory = inventory; + } + + public static APIUpdateSshKeyPairEvent __example__() { + APIUpdateSshKeyPairEvent event = new APIUpdateSshKeyPairEvent(); + SshKeyPairInventory inv = new SshKeyPairInventory(); + + inv.setUuid(uuid()); + inv.setName("ssh-key-pair"); + inv.setUuid(uuid()); + inv.setPublicKey(""); + event.setInventory(inv); + return event; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairEventDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..6a2a26cabcb --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.SshKeyPairInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "更新密钥对返回" + + ref { + name "inventory" + path "org.zstack.header.sshkeypair.APIUpdateSshKeyPairEvent.inventory" + desc "null" + type "SshKeyPairInventory" + since "4.7.21" + clz SshKeyPairInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.header.sshkeypair.APIUpdateSshKeyPairEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairMsg.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairMsg.java new file mode 100644 index 00000000000..a5c9c4607bb --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairMsg.java @@ -0,0 +1,69 @@ +package org.zstack.header.sshkeypair; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.sshkeypair.SshKeyPairConstant; + +@RestRequest( + path = "/ssh-key-pair/{uuid}/actions", + method = HttpMethod.PUT, + responseClass = APIUpdateSshKeyPairEvent.class, + isAction = true +) +public class APIUpdateSshKeyPairMsg extends APIMessage implements SshKeyPairMessage, APIAuditor { + @APIParam(resourceType = SshKeyPairVO.class, maxLength = 32, operationTarget = true, checkAccount = true) + private String uuid; + + @APIParam(maxLength = 255, required = false, validRegexValues = SshKeyPairConstant.SSH_KEY_PAIR_NAME_REGEX) + private String name; + + @APIParam(maxLength = 2048, required = false) + private String description; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + + public static APIUpdateSshKeyPairMsg __example__() { + APIUpdateSshKeyPairMsg ret = new APIUpdateSshKeyPairMsg(); + ret.name = "ssh-key-pair"; + ret.description = "description"; + ret.uuid = uuid(); + return ret; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new APIAuditor.Result(((APIUpdateSshKeyPairMsg)msg).getUuid(), SshKeyPairVO.class); + } + + @Override + public String getSshKeyPairUuid() { + return uuid; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairMsgDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..edfad80e2ed --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/APIUpdateSshKeyPairMsgDoc_zh_cn.groovy @@ -0,0 +1,76 @@ +package org.zstack.header.sshkeypair + +import org.zstack.header.sshkeypair.APIUpdateSshKeyPairEvent + +doc { + title "UpdateSshKeyPair" + + category "sshKeyPair" + + desc """更新密钥对""" + + rest { + request { + url "PUT /v1/ssh-key-pair/{uuid}/actions" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIUpdateSshKeyPairMsg.class + + desc """""" + + params { + + column { + name "uuid" + enclosedIn "updateSshKeyPair" + desc "资源的UUID,唯一标示该资源" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "name" + enclosedIn "updateSshKeyPair" + desc "资源名称" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "description" + enclosedIn "updateSshKeyPair" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIUpdateSshKeyPairEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairGlobalProperty.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairGlobalProperty.java new file mode 100644 index 00000000000..397c5745c7c --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairGlobalProperty.java @@ -0,0 +1,14 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +/** + * @Author: ya.wang + * @Date: 8/11/23 4:17 PM + */ +@GlobalPropertyDefinition +public class SshKeyPairGlobalProperty { + @GlobalProperty(name="upgradeSshKeyPairFromSystemTag", defaultValue = "false") + public static boolean UPGRADE_SSH_KEY_PAIR_FROM_SYSTEM_TAG; +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairInventory.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairInventory.java new file mode 100644 index 00000000000..8a1551d2929 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairInventory.java @@ -0,0 +1,90 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.zone.ZoneInventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = SshKeyPairVO.class) +public class SshKeyPairInventory implements Serializable { + private String uuid; + private String name; + private String description; + private String publicKey; + + private Timestamp createDate; + private Timestamp lastOpDate; + + public static SshKeyPairInventory valueOf(SshKeyPairVO vo) { + SshKeyPairInventory inv = new SshKeyPairInventory(); + inv.setName(vo.getName()); + inv.setUuid(vo.getUuid()); + inv.setDescription(vo.getDescription()); + inv.setPublicKey(vo.getPublicKey()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (SshKeyPairVO vo: vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairInventoryDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..0833c0d5e88 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairInventoryDoc_zh_cn.groovy @@ -0,0 +1,45 @@ +package org.zstack.header.sshkeypair + +import java.sql.Timestamp + +doc { + + title "密钥对" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.7.21" + } + field { + name "name" + desc "资源名称" + type "String" + since "4.7.21" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "4.7.21" + } + field { + name "publicKey" + desc "" + type "String" + since "4.7.21" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.7.21" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.7.21" + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairMessage.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairMessage.java new file mode 100644 index 00000000000..ed9f46b7cff --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairMessage.java @@ -0,0 +1,5 @@ +package org.zstack.header.sshkeypair; + +public interface SshKeyPairMessage { + String getSshKeyPairUuid(); +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefInventory.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefInventory.java new file mode 100644 index 00000000000..dca664754fa --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefInventory.java @@ -0,0 +1,86 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.vm.VmInstanceInventory; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = SshKeyPairRefVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "vmInstance", inventoryClass = VmInstanceInventory.class, + foreignKey = "vmInstanceUuid", expandedInventoryKey = "uuid"), + @ExpandedQuery(expandedField = "sshKeyPair", inventoryClass = SshKeyPairInventory.class, + foreignKey = "sshKeyPairUuid", expandedInventoryKey = "uuid") +}) +public class SshKeyPairRefInventory { + private long id; + private String resourceUuid; + private String sshKeyPairUuid; + private Timestamp createDate; + + public static SshKeyPairRefInventory valueOf(SshKeyPairRefVO vo) { + SshKeyPairRefInventory inv = new SshKeyPairRefInventory(); + inv.setId(vo.getId()); + inv.setResourceUuid(vo.getResourceUuid()); + inv.setSshKeyPairUuid(vo.getSshKeyPairUuid()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (SshKeyPairRefVO vo: vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getSshKeyPairUuid() { + return sshKeyPairUuid; + } + + public void setSshKeyPairUuid(String sshKeyPairUuid) { + this.sshKeyPairUuid = sshKeyPairUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + private Timestamp lastOpDate; + +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefVO.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefVO.java new file mode 100644 index 00000000000..0b7c087c4c7 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefVO.java @@ -0,0 +1,90 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.vo.*; +import org.zstack.header.vo.ForeignKey; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = ResourceVO.class, joinColumn = "resourceUuid"), + @SoftDeletionCascade(parent = SshKeyPairVO.class, joinColumn = "sshKeyPairUuid") +}) +public class SshKeyPairRefVO implements ToInventory { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private Long id; + + @Column + @ForeignKey(parentEntityClass = ResourceVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String resourceUuid; + + @Column + @ForeignKey(parentEntityClass = SshKeyPairVO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String sshKeyPairUuid; + + @Column + private String resourceType; + + public String getResourceUuid() { + return resourceUuid; + } + + public void setResourceUuid(String resourceUuid) { + this.resourceUuid = resourceUuid; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getSshKeyPairUuid() { + return sshKeyPairUuid; + } + + public void setSshKeyPairUuid(String sshKeyPairUuid) { + this.sshKeyPairUuid = sshKeyPairUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @PreUpdate + private void preUpdate() { + lastOpDate = null; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefVO_.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefVO_.java new file mode 100644 index 00000000000..80a7b50d26c --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairRefVO_.java @@ -0,0 +1,15 @@ +package org.zstack.header.sshkeypair; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(SshKeyPairVO.class) +public class SshKeyPairRefVO_ { + public static volatile SingularAttribute id; + public static volatile SingularAttribute sshKeyPairUuid; + public static volatile SingularAttribute resourceUuid; + public static volatile SingularAttribute resourceType; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairVO.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairVO.java new file mode 100644 index 00000000000..191a027dd0b --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairVO.java @@ -0,0 +1,80 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.identity.OwnedByAccount; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ToInventory; +import org.zstack.header.zone.ZoneVO; + +import javax.persistence.*; +import java.sql.Timestamp; + +@Entity +@Table +public class SshKeyPairVO extends ResourceVO implements OwnedByAccount, ToInventory { + @Column + private String name; + @Column + private String description; + @Column + private String publicKey; + @Column + private Timestamp createDate; + @Column + private Timestamp lastOpDate; + @Transient + private String accountUuid; + + @PreUpdate + private void preUpdate() {lastOpDate = null; } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String keyPair) { + this.publicKey = keyPair; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + @Override + public String getAccountUuid() { + return accountUuid; + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairVO_.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairVO_.java new file mode 100644 index 00000000000..ab248745069 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshKeyPairVO_.java @@ -0,0 +1,17 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.directory.DirectoryVO; +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(SshKeyPairVO.class) +public class SshKeyPairVO_ extends ResourceVO_ { + public static volatile SingularAttribute name; + public static volatile SingularAttribute description; + public static volatile SingularAttribute publicKey; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshPrivateKeyPairInventory.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshPrivateKeyPairInventory.java new file mode 100644 index 00000000000..20be7b5b7c2 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshPrivateKeyPairInventory.java @@ -0,0 +1,99 @@ +package org.zstack.header.sshkeypair; + +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; +import org.zstack.header.zone.ZoneInventory; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = SshKeyPairVO.class) +public class SshPrivateKeyPairInventory implements Serializable { + private String uuid; + private String name; + private String description; + private String publicKey; + private Timestamp createDate; + private Timestamp lastOpDate; + + private String privateKey; + + public static SshPrivateKeyPairInventory valueOf(SshKeyPairVO vo) { + SshPrivateKeyPairInventory inv = new SshPrivateKeyPairInventory(); + inv.setName(vo.getName()); + inv.setUuid(vo.getUuid()); + inv.setDescription(vo.getDescription()); + inv.setPublicKey(vo.getPublicKey()); + inv.setCreateDate(vo.getCreateDate()); + inv.setLastOpDate(vo.getLastOpDate()); + return inv; + } + + public String getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(); + for (SshKeyPairVO vo: vos) { + invs.add(valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshPrivateKeyPairInventoryDoc_zh_cn.groovy b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshPrivateKeyPairInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..1613a5c26a6 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/SshPrivateKeyPairInventoryDoc_zh_cn.groovy @@ -0,0 +1,51 @@ +package org.zstack.header.sshkeypair + +import java.sql.Timestamp + +doc { + + title "密钥对" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.7.21" + } + field { + name "name" + desc "资源名称" + type "String" + since "4.7.21" + } + field { + name "description" + desc "资源的详细描述" + type "String" + since "4.7.21" + } + field { + name "publicKey" + desc "" + type "String" + since "4.7.21" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.7.21" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.7.21" + } + field { + name "privateKey" + desc "" + type "String" + since "4.7.21" + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaConstant.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaConstant.java new file mode 100644 index 00000000000..a4b1346f3af --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaConstant.java @@ -0,0 +1,6 @@ +package org.zstack.header.sshkeypair.quota; + +public interface SshKeyPairQuotaConstant { + String SSH_KEY_PAIR_NUM = "ssh_key_pair.num"; + +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaDefinition.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaDefinition.java new file mode 100644 index 00000000000..52004a5d9b3 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaDefinition.java @@ -0,0 +1,33 @@ +package org.zstack.header.sshkeypair.quota; + +import org.zstack.core.db.Q; +import org.zstack.header.identity.AccountResourceRefVO; +import org.zstack.header.identity.AccountResourceRefVO_; +import org.zstack.header.identity.quota.QuotaDefinition; +import org.zstack.header.sshkeypair.SshKeyPairVO; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class SshKeyPairQuotaDefinition implements QuotaDefinition { + private static final CLogger logger = Utils.getLogger(SshKeyPairQuotaDefinition.class); + + @Override + public String getName() { + return SshKeyPairQuotaConstant.SSH_KEY_PAIR_NUM; + } + + @Override + public Long getDefaultValue() { + return SshKeyPairQuotaGlobalConfig.SSH_KEY_PAIR_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + + Long count = Q.New(AccountResourceRefVO.class) + .eq(AccountResourceRefVO_.accountUuid, accountUuid) + .eq(AccountResourceRefVO_.resourceType, SshKeyPairVO.class.getSimpleName()) + .count(); + return count; + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaGlobalConfig.java b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaGlobalConfig.java new file mode 100644 index 00000000000..a5c8d2c95f9 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/header/sshkeypair/quota/SshKeyPairQuotaGlobalConfig.java @@ -0,0 +1,15 @@ +package org.zstack.header.sshkeypair.quota; + +import org.zstack.core.config.GlobalConfig; +import org.zstack.core.config.GlobalConfigDef; +import org.zstack.core.config.GlobalConfigDefinition; +import org.zstack.core.config.GlobalConfigValidation; +import org.zstack.identity.QuotaGlobalConfig; + +@GlobalConfigDefinition +public class SshKeyPairQuotaGlobalConfig extends QuotaGlobalConfig { + + @GlobalConfigValidation(numberGreaterThan = 0) + @GlobalConfigDef(type = Integer.class, defaultValue = "20", description = "default ssh key pair quota") + public static GlobalConfig SSH_KEY_PAIR_NUM = new GlobalConfig(CATEGORY, SshKeyPairQuotaConstant.SSH_KEY_PAIR_NUM); +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/RBACInfo.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/RBACInfo.java new file mode 100644 index 00000000000..de503574171 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/RBACInfo.java @@ -0,0 +1,36 @@ +package org.zstack.sshkeypair; + +import org.zstack.header.identity.rbac.RBACDescription; +import org.zstack.header.sshkeypair.SshKeyPairVO; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .name("sshKeyPair") + .normalAPIs( + "org.zstack.sshkeypair.**", + "org.zstack.header.sshkeypair.**") + .targetResources(SshKeyPairVO.class) + .build(); + } + + @Override + public void contributeToRoles() { + + } + + @Override + public void roles() { + roleBuilder() + .uuid("2ae2f3bdb0ff4296bda2447aa7b334e7") + .name("sshKeyPair") + .permissionsByName("sshKeyPair") + .build(); + } + + @Override + public void globalReadableResources() { + + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairAPIInterceptor.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairAPIInterceptor.java new file mode 100644 index 00000000000..421044ef306 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairAPIInterceptor.java @@ -0,0 +1,132 @@ +package org.zstack.sshkeypair; + +import org.apache.lucene.util.packed.PagedGrowableWriter; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.identity.AccountResourceRefVO; +import org.zstack.header.identity.AccountResourceRefVO_; +import org.zstack.header.message.APIMessage; +import org.zstack.header.sshkeypair.*; +import org.zstack.header.vm.VmInstanceState; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vm.VmInstanceVO_; +import org.zstack.header.vo.ResourceVO; +import org.zstack.header.vo.ResourceVO_; +import org.zstack.utils.CharacterUtils; + +import java.util.List; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.argerr; + +public class SshKeyPairAPIInterceptor implements ApiMessageInterceptor { + + @Autowired + private CloudBus bus; + + private static final List ALLOW_RESOURCE_TYPES = asList(VmInstanceVO.class.getSimpleName()); + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APICreateSshKeyPairMsg) { + validate((APICreateSshKeyPairMsg) msg); + } else if (msg instanceof APIDeleteSshKeyPairMsg) { + validate((APIDeleteSshKeyPairMsg) msg); + } else if (msg instanceof APIAttachSshKeyPairToVmInstanceMsg) { + validate((APIAttachSshKeyPairToVmInstanceMsg) msg); + } else if (msg instanceof APIDetachSshKeyPairFromVmInstanceMsg) { + validate((APIDetachSshKeyPairFromVmInstanceMsg) msg); + } + + setServiceId(msg); + return msg; + } + + private void setServiceId(APIMessage msg) { + if (msg instanceof SshKeyPairMessage) { + SshKeyPairMessage smsg = (SshKeyPairMessage) msg; + bus.makeTargetServiceIdByResourceUuid(msg, SshKeyPairManager.SERVICE_ID, smsg.getSshKeyPairUuid()); + } + } + + private void validate(APICreateSshKeyPairMsg msg) { + List sshKeyPairUuids = Q.New(SshKeyPairVO.class) + .select(SshKeyPairVO_.uuid) + .eq(SshKeyPairVO_.publicKey, msg.getPublicKey()) + .listValues(); + if (sshKeyPairUuids.isEmpty()) { + return; + } + boolean isExist = Q.New(AccountResourceRefVO.class) + .eq(AccountResourceRefVO_.accountUuid, msg.getSession().getAccountUuid()) + .eq(AccountResourceRefVO_.resourceType, SshKeyPairVO.class.getSimpleName()) + .in(AccountResourceRefVO_.resourceUuid, sshKeyPairUuids) + .isExists(); + if (isExist) { + throw new ApiMessageInterceptionException(argerr("The sshKeyPair already upload")); + } + } + + private void validate(APIDeleteSshKeyPairMsg msg) { + boolean exists = Q.New(SshKeyPairRefVO.class) + .eq(SshKeyPairRefVO_.sshKeyPairUuid, msg.getUuid()) + .isExists(); + if (exists) { + throw new ApiMessageInterceptionException((argerr("The sshKeyPair[uuid:%s] was in using.", msg.getSshKeyPairUuid()))); + } + } + + private void validate(APIAttachSshKeyPairToVmInstanceMsg msg) { + String resourceType = Q.New(ResourceVO.class) + .eq(ResourceVO_.uuid, msg.getVmInstanceUuid()) + .select(ResourceVO_.resourceType) + .findValue(); + checkType(resourceType); + + boolean isExist = Q.New(SshKeyPairRefVO.class) + .eq(SshKeyPairRefVO_.sshKeyPairUuid, msg.getSshKeyPairUuid()) + .eq(SshKeyPairRefVO_.resourceUuid, msg.getVmInstanceUuid()) + .eq(SshKeyPairRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .isExists(); + if (isExist) { + throw new ApiMessageInterceptionException((argerr("The sshKeyPair[uuid:%s] was already attached on vm[uuid:].", + msg.getSshKeyPairUuid(), msg.getVmInstanceUuid()))); + } + validateVmInstanceRunning(Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).find()); + } + + private void validate(APIDetachSshKeyPairFromVmInstanceMsg msg) { + String resourceType = Q.New(ResourceVO.class) + .eq(ResourceVO_.uuid, msg.getVmInstanceUuid()) + .select(ResourceVO_.resourceType) + .findValue(); + checkType(resourceType); + + boolean isExist = Q.New(SshKeyPairRefVO.class) + .eq(SshKeyPairRefVO_.sshKeyPairUuid, msg.getSshKeyPairUuid()) + .eq(SshKeyPairRefVO_.resourceUuid, msg.getVmInstanceUuid()) + .eq(SshKeyPairRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .isExists(); + if (!isExist) { + throw new ApiMessageInterceptionException((argerr("The sshKeyPair[uuid:%s] was not attached on vm[uuid:%s].", + msg.getSshKeyPairUuid(), msg.getVmInstanceUuid()))); + } + validateVmInstanceRunning(Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, msg.getVmInstanceUuid()).find()); + } + + private void validateVmInstanceRunning(VmInstanceVO vmInstanceVO) { + if (!vmInstanceVO.getState().equals(VmInstanceState.Running)) { + throw new ApiMessageInterceptionException((argerr( + "The vmInstance[uuid:%s] not in running state.", vmInstanceVO.getUuid()))); + } + } + + private void checkType(String type) { + if (!ALLOW_RESOURCE_TYPES.contains(type)) { + throw new ApiMessageInterceptionException(argerr("resource types %s are not supported to attach sshKeyPair, allowed types are %s", type, ALLOW_RESOURCE_TYPES)); + } + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairBase.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairBase.java new file mode 100644 index 00000000000..2a638bb703d --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairBase.java @@ -0,0 +1,354 @@ +package org.zstack.sshkeypair; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostConstant; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.message.MessageReply; +import org.zstack.header.sshkeypair.*; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.kvm.KVMAgentCommands; +import org.zstack.kvm.KVMHostAsyncHttpCallMsg; +import org.zstack.kvm.KVMHostAsyncHttpCallReply; + +import java.sql.Timestamp; +import java.util.Date; + +import static org.zstack.core.Platform.operr; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class SshKeyPairBase { + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + protected ThreadFacade thdf; + + protected SshKeyPairVO self; + + public SshKeyPairBase(SshKeyPairVO self) { + this.self = self; + } + + @MessageSafe + void handleMessage(Message msg) { + if (msg instanceof APIMessage) { + handleAPIMessage((APIMessage) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handleAPIMessage(APIMessage msg) { + if (msg instanceof APIUpdateSshKeyPairMsg) { + handle((APIUpdateSshKeyPairMsg) msg); + } else if (msg instanceof APIDeleteSshKeyPairMsg) { + handle((APIDeleteSshKeyPairMsg) msg); + } else if (msg instanceof APIAttachSshKeyPairToVmInstanceMsg) { + handle((APIAttachSshKeyPairToVmInstanceMsg) msg); + } else if (msg instanceof APIDetachSshKeyPairFromVmInstanceMsg) { + handle((APIDetachSshKeyPairFromVmInstanceMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + public void handle(APIUpdateSshKeyPairMsg msg) { + APIUpdateSshKeyPairEvent event = new APIUpdateSshKeyPairEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + updateSshKeyPair(msg, event, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + @Override + public String getSyncSignature() { + return String.format("%s-%s", SshKeyPairConstant.OPERATE_SSH_KEY_PAIR_THREAD_NAME, msg.getSshKeyPairUuid()); + } + + @Override + public String getName() { + return String.format("update-sshKeyPair-%s", msg.getSshKeyPairUuid()); + } + }); + } + + private void updateSshKeyPair(APIUpdateSshKeyPairMsg msg, APIUpdateSshKeyPairEvent event, Completion completion) { + SshKeyPairVO vo = dbf.findByUuid(msg.getUuid(), SshKeyPairVO.class); + + boolean updated = false; + + if (msg.getName() != null) { + vo.setName(msg.getName()); + updated = true; + } + if (msg.getDescription() != null) { + vo.setDescription(msg.getDescription()); + updated = true; + } + + if (updated) { + vo = dbf.updateAndRefresh(vo); + } + event.setInventory(SshKeyPairInventory.valueOf(vo)); + completion.success(); + } + + public void handle(APIDeleteSshKeyPairMsg msg) { + APIDeleteSshKeyPairEvent event = new APIDeleteSshKeyPairEvent(msg.getId()); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + deleteSshKeyPair(msg, event, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + @Override + public String getSyncSignature() { + return String.format("%s-%s", SshKeyPairConstant.OPERATE_SSH_KEY_PAIR_THREAD_NAME, msg.getSshKeyPairUuid()); + } + + @Override + public String getName() { + return String.format("delete-sshKeyPair-%s", msg.getUuid()); + } + }); + } + + private void deleteSshKeyPair(APIDeleteSshKeyPairMsg msg, APIDeleteSshKeyPairEvent event, Completion completion) { + SshKeyPairVO vo = dbf.findByUuid(msg.getUuid(), SshKeyPairVO.class); + + dbf.remove(vo); + + completion.success(); + } + + public void handle(APIAttachSshKeyPairToVmInstanceMsg msg) { + APIAttachSshKeyPairToVmInstanceEvent event = new APIAttachSshKeyPairToVmInstanceEvent(msg.getId()); + + SshKeyPairVO keyPair = dbf.findByUuid(msg.getSshKeyPairUuid(), SshKeyPairVO.class); + VmInstanceVO instance = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + AttachSshKeyPairToVmInstanceCommand cmd = new AttachSshKeyPairToVmInstanceCommand(); + cmd.setSshKeyPairUuid(keyPair.getUuid()); + cmd.setVmInstanceUuid(instance.getUuid()); + cmd.setPublicKey(keyPair.getPublicKey()); + + KVMHostAsyncHttpCallMsg smsg = new KVMHostAsyncHttpCallMsg(); + smsg.setCommand(cmd); + smsg.setHostUuid(instance.getHostUuid()); + smsg.setPath(SshKeyPairConstant.SSH_KEY_PAIR_ATTACH_TO_VM); + + bus.makeTargetServiceIdByResourceUuid(smsg, HostConstant.SERVICE_ID, instance.getHostUuid()); + bus.send(smsg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + KVMHostAsyncHttpCallReply r = reply.castReply(); + AttachSshKeyPairToVmInstanceRsp rsp = r.toResponse(AttachSshKeyPairToVmInstanceRsp.class); + if (rsp.isSuccess()) { + attachSshKeyPairToVmInDB(); + } else { + reply.setError(operr("operation error, because: %s", rsp.getError())); + event.setError(reply.getError()); + } + } else { + event.setError(reply.getError()); + } + bus.publish(event); + chain.next(); + } + void attachSshKeyPairToVmInDB() { + SshKeyPairRefVO vo = new SshKeyPairRefVO(); + vo.setSshKeyPairUuid(msg.getSshKeyPairUuid()); + vo.setResourceUuid(msg.getVmInstanceUuid()); + vo.setResourceType(VmInstanceVO.class.getSimpleName()); + vo.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(vo); + } + }); + } + + @Override + public String getSyncSignature() { + return String.format("%s-%s", SshKeyPairConstant.OPERATE_SSH_KEY_PAIR_THREAD_NAME, msg.getSshKeyPairUuid()); + } + + @Override + public String getName() { + return String.format("attach-sshKeyPair-%s", msg.getSshKeyPairUuid()); + } + }); + } + + public static class AttachSshKeyPairToVmInstanceCommand extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + public String sshKeyPairUuid; + @GrayVersion(value = "5.0.0") + public String vmInstanceUuid; + @GrayVersion(value = "5.0.0") + public String publicKey; + + public String getSshKeyPairUuid() { + return sshKeyPairUuid; + } + + public void setSshKeyPairUuid(String sshKeyPairUuid) { + this.sshKeyPairUuid = sshKeyPairUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + } + + public static class AttachSshKeyPairToVmInstanceRsp extends KVMAgentCommands.AgentResponse { + } + + public void handle(APIDetachSshKeyPairFromVmInstanceMsg msg) { + APIDetachSshKeyPairFromVmInstanceEvent event = new APIDetachSshKeyPairFromVmInstanceEvent(msg.getId()); + + SshKeyPairVO keyPair = dbf.findByUuid(msg.getSshKeyPairUuid(), SshKeyPairVO.class); + VmInstanceVO instance = dbf.findByUuid(msg.getVmInstanceUuid(), VmInstanceVO.class); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + DetachSshKeyPairFromVmInstanceCommand cmd = new DetachSshKeyPairFromVmInstanceCommand(); + cmd.setSshKeyPairUuid(keyPair.getUuid()); + cmd.setVmInstanceUuid(instance.getUuid()); + cmd.setPublicKey(keyPair.getPublicKey()); + + KVMHostAsyncHttpCallMsg smsg = new KVMHostAsyncHttpCallMsg(); + smsg.setCommand(cmd); + smsg.setHostUuid(instance.getHostUuid()); + smsg.setPath(SshKeyPairConstant.SSH_KEY_PAIR_DETACH_FROM_VM); + + bus.makeTargetServiceIdByResourceUuid(smsg, HostConstant.SERVICE_ID, instance.getHostUuid()); + bus.send(smsg, new CloudBusCallBack(chain) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + KVMHostAsyncHttpCallReply r = reply.castReply(); + DetachSshKeyPairFromVmInstanceRsp rsp = r.toResponse(DetachSshKeyPairFromVmInstanceRsp.class); + if (rsp.isSuccess()) { + detachSshKeyPairFromVmInDB(); + } else { + reply.setError(operr("operation error, because: %s", rsp.getError())); + event.setError(reply.getError()); + } + } else { + event.setError(reply.getError()); + } + bus.publish(event); + chain.next(); + } + void detachSshKeyPairFromVmInDB() { + SQL.New(SshKeyPairRefVO.class) + .eq(SshKeyPairRefVO_.sshKeyPairUuid, msg.getSshKeyPairUuid()) + .eq(SshKeyPairRefVO_.resourceUuid, msg.getVmInstanceUuid()) + .eq(SshKeyPairRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .delete(); + } + }); + } + + @Override + public String getSyncSignature() { + return String.format("%s-%s", SshKeyPairConstant.OPERATE_SSH_KEY_PAIR_THREAD_NAME, msg.getSshKeyPairUuid()); + } + + @Override + public String getName() { + return String.format("detach-sshKeyPair-%s", msg.getSshKeyPairUuid()); + } + }); + } + + public static class DetachSshKeyPairFromVmInstanceCommand extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + public String sshKeyPairUuid; + @GrayVersion(value = "5.0.0") + public String vmInstanceUuid; + @GrayVersion(value = "5.0.0") + public String publicKey; + + public String getSshKeyPairUuid() { + return sshKeyPairUuid; + } + + public void setSshKeyPairUuid(String sshKeyPairUuid) { + this.sshKeyPairUuid = sshKeyPairUuid; + } + + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + } + + public static class DetachSshKeyPairFromVmInstanceRsp extends KVMAgentCommands.AgentResponse { + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairConstant.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairConstant.java new file mode 100644 index 00000000000..fa9b213da32 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairConstant.java @@ -0,0 +1,11 @@ +package org.zstack.sshkeypair; + +public interface SshKeyPairConstant { + String OPERATE_SSH_KEY_PAIR_THREAD_NAME = "create-update-delete-attach-detach-ssh-key"; + + String SSH_KEY_PAIR_ATTACH_TO_VM = "/sshkeypair/attach"; + + String SSH_KEY_PAIR_DETACH_FROM_VM = "/sshkeypair/detach"; + + String SSH_KEY_PAIR_NAME_REGEX = "^[\\u4e00-\\u9fa5a-zA-Z0-9\\s()()【】@._+-]+$"; +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairManager.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairManager.java new file mode 100644 index 00000000000..bb570b502d1 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairManager.java @@ -0,0 +1,8 @@ +package org.zstack.sshkeypair; + +import org.zstack.header.message.Message; + +public interface SshKeyPairManager { + String SERVICE_ID = "sshKeyPair"; + void handleMessage(Message msg); +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairManagerImpl.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairManagerImpl.java new file mode 100644 index 00000000000..5a0fc16d9d6 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairManagerImpl.java @@ -0,0 +1,275 @@ +package org.zstack.sshkeypair; + +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.KeyPair; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.header.vm.SshKeyPairAssociateExtensionPoint; +import org.zstack.core.Platform; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.MessageSafe; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.AbstractService; +import org.zstack.header.Component; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.identity.APIChangeResourceOwnerMsg; +import org.zstack.header.identity.Quota; +import org.zstack.header.identity.ReportQuotaExtensionPoint; +import org.zstack.header.identity.quota.QuotaMessageHandler; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.sshkeypair.*; +import org.zstack.header.sshkeypair.quota.SshKeyPairQuotaConstant; +import org.zstack.header.sshkeypair.quota.SshKeyPairQuotaDefinition; +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.volume.VolumeVO; +import org.zstack.tag.TagManager; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.io.ByteArrayOutputStream; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.zstack.core.Platform.err; +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.list; + +public class SshKeyPairManagerImpl extends AbstractService implements + SshKeyPairManager, + ReportQuotaExtensionPoint, + SshKeyPairAssociateExtensionPoint, + Component { + private static final CLogger logger = Utils.getLogger(SshKeyPairManagerImpl.class); + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + private ThreadFacade thdf; + @Autowired + private TagManager tagMgr; + + @Override + @MessageSafe + public void handleMessage(Message msg) { + if (msg instanceof SshKeyPairMessage) { + passThrough((SshKeyPairMessage) msg); + } else if (msg instanceof APIMessage) { + handleAPIMessage((APIMessage) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + public void handleAPIMessage(APIMessage msg) { + if (msg instanceof APICreateSshKeyPairMsg) { + handle((APICreateSshKeyPairMsg) msg); + } else if (msg instanceof APIGenerateSshKeyPairMsg) { + handle((APIGenerateSshKeyPairMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + public void passThrough(SshKeyPairMessage msg) { + SshKeyPairVO vo = dbf.findByUuid(msg.getSshKeyPairUuid(), SshKeyPairVO.class); + if (vo == null) { + bus.replyErrorByMessageType((Message) msg, err(SysErrors.RESOURCE_NOT_FOUND, "unable to find sshKeyPair[uuid=%s]", msg.getSshKeyPairUuid())); + return; + } + + new SshKeyPairBase(vo).handleMessage((Message) msg); + } + + public void handle(APICreateSshKeyPairMsg msg){ + APICreateSshKeyPairEvent event = new APICreateSshKeyPairEvent(msg.getId()); + + thdf.chainSubmit(new ChainTask(msg) { + @Override + public void run(SyncTaskChain chain) { + createSshKeyPair(msg, event, new Completion(chain) { + @Override + public void success() { + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getSyncSignature() { + return String.format("%s-%s", SshKeyPairConstant.OPERATE_SSH_KEY_PAIR_THREAD_NAME, msg.getName()); + } + + @Override + public String getName() { + return String.format("create-sshKeyPair-name-%s", msg.getName()); + } + }); + } + + + public void handle(APIGenerateSshKeyPairMsg msg) { + APIGenerateSshKeyPairReply reply = new APIGenerateSshKeyPairReply(); + + ByteArrayOutputStream privKey = new ByteArrayOutputStream(); + ByteArrayOutputStream pubKey = new ByteArrayOutputStream(); + try { + JSch jsch = new JSch(); + KeyPair jschKeyPair = KeyPair.genKeyPair(jsch, KeyPair.RSA, 2048); + + jschKeyPair.writePrivateKey(privKey); + jschKeyPair.writePublicKey(pubKey, null); + } catch (JSchException e) { + bus.replyErrorByMessageType((Message) msg, err( + SysErrors.INTERNAL, + "Cannot generate sshKeyPair, error: %s", e.toString())); + } + + SshKeyPairVO keyPair = new SshKeyPairVO(); + keyPair.setUuid(Platform.getUuid()); + keyPair.setName(msg.getName()); + keyPair.setDescription(msg.getDescription()); + keyPair.setPublicKey(pubKey.toString()); + keyPair.setAccountUuid(msg.getSession().getAccountUuid()); + keyPair.setCreateDate(new Timestamp(new Date().getTime())); + keyPair = dbf.persistAndRefresh(keyPair); + + tagMgr.createTags(msg.getSystemTags(), msg.getUserTags(), keyPair.getUuid(), SshKeyPairVO.class.getSimpleName()); + + SshPrivateKeyPairInventory inv = SshPrivateKeyPairInventory.valueOf(keyPair); + inv.setPrivateKey(privKey.toString()); + + reply.setInventory(inv); + bus.reply(msg, reply); + } + + public void createSshKeyPair(APICreateSshKeyPairMsg msg, APICreateSshKeyPairEvent event, Completion completion){ + String keyContent = msg.getPublicKey(); + logger.warn(keyContent); + try { + JSch jsch = new JSch(); + KeyPair publicKey = KeyPair.load(jsch, null, keyContent.getBytes()); + String fg = publicKey.getFingerPrint(); + } catch (Exception e) { + completion.fail(operr("failed to load the public key: %s, err: %s", keyContent, e.toString())); + return; + } + + SshKeyPairVO keyPair = new SshKeyPairVO(); + keyPair.setUuid(msg.getResourceUuid() == null ? Platform.getUuid() : msg.getResourceUuid()); + keyPair.setName(msg.getName()); + keyPair.setDescription(msg.getDescription()); + keyPair.setPublicKey(msg.getPublicKey()); + keyPair.setAccountUuid(msg.getSession().getAccountUuid()); + keyPair.setCreateDate(new Timestamp(new Date().getTime())); + keyPair = dbf.persistAndRefresh(keyPair); + + tagMgr.createTagsFromAPICreateMessage(msg, keyPair.getUuid(), VolumeVO.class.getSimpleName()); + + event.setInventory(SshKeyPairInventory.valueOf(keyPair)); + completion.success(); + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getId() { + return bus.makeLocalServiceId(SshKeyPairManager.SERVICE_ID); + } + + @Override + public List reportQuota() { + Quota quota = new Quota(); + quota.defineQuota(new SshKeyPairQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateSshKeyPairMsg.class). + addCounterQuota(SshKeyPairQuotaConstant.SSH_KEY_PAIR_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIGenerateSshKeyPairMsg.class). + addCounterQuota(SshKeyPairQuotaConstant.SSH_KEY_PAIR_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(SshKeyPairVO.class) + .eq(SshKeyPairVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(SshKeyPairQuotaConstant.SSH_KEY_PAIR_NUM)); + return list(quota); + } + + @Override + public ErrorCode associateSshKeyPair(String vmUuid, List keyPairUuids) { + for (String uuid: keyPairUuids) { + boolean isExist = Q.New(SshKeyPairVO.class) + .eq(SshKeyPairVO_.uuid, uuid) + .isExists(); + if(!isExist) { + return operr("ssh key pair[uuid:%s] can not associated to vm[uuid:%s] due to the key not found", + uuid, vmUuid); + } + SshKeyPairRefVO refVo = new SshKeyPairRefVO(); + refVo.setSshKeyPairUuid(uuid); + refVo.setResourceUuid(vmUuid); + refVo.setResourceType(VmInstanceVO.class.getSimpleName()); + refVo.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(refVo); + } + return null; + } + + @Override + public List fetchAssociatedSshKeyPairs(String vmUuid) { + List sshKeyPairs = new ArrayList<>(); + List uuids = Q.New(SshKeyPairRefVO.class) + .eq(SshKeyPairRefVO_.resourceUuid, vmUuid) + .eq(SshKeyPairRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .select(SshKeyPairRefVO_.sshKeyPairUuid) + .listValues(); + if (!uuids.isEmpty()) { + sshKeyPairs = Q.New(SshKeyPairVO.class) + .in(SshKeyPairVO_.uuid, uuids) + .select(SshKeyPairVO_.publicKey) + .listValues(); + } + return sshKeyPairs; + } + + @Override + public void cloneSshKeyPairsToVm(String originVmUuid, String destVmUuid) { + List sshKeyPairUuids = Q.New(SshKeyPairRefVO.class) + .select(SshKeyPairRefVO_.sshKeyPairUuid) + .eq(SshKeyPairRefVO_.resourceUuid, originVmUuid) + .eq(SshKeyPairRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .listValues(); + for (String sshKeyPairUuid: sshKeyPairUuids) { + SshKeyPairRefVO refVo = new SshKeyPairRefVO(); + refVo.setSshKeyPairUuid(sshKeyPairUuid); + refVo.setResourceUuid(destVmUuid); + refVo.setResourceType(VmInstanceVO.class.getSimpleName()); + refVo.setCreateDate(new Timestamp(new Date().getTime())); + dbf.persist(refVo); + } + } +} diff --git a/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairUpgradeExtension.java b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairUpgradeExtension.java new file mode 100644 index 00000000000..348ce357bf2 --- /dev/null +++ b/plugin/sshKeyPair/src/main/java/org/zstack/sshkeypair/SshKeyPairUpgradeExtension.java @@ -0,0 +1,130 @@ +package org.zstack.sshkeypair; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.vm.VmSystemTags; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.Component; +import org.zstack.header.identity.AccountResourceRefVO; +import org.zstack.header.identity.AccountResourceRefVO_; +import org.zstack.header.sshkeypair.*; +import org.zstack.header.vm.VmInstanceVO; + +import javax.persistence.Tuple; +import java.sql.Timestamp; +import java.util.*; + +public class SshKeyPairUpgradeExtension implements Component { + @Autowired + DatabaseFacade dbf; + private void upgradeVmInstanceSshKey() { + Map> accountVmInstanceMap = new HashMap>(); + + Long count = Q.New(AccountResourceRefVO.class) + .eq(AccountResourceRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .count(); + + SQL.New("select ref.accountUuid, ref.resourceUuid " + + "from AccountResourceRefVO ref where ref.resourceType = :resourceType", Tuple.class) + .param("resourceType", VmInstanceVO.class.getSimpleName()) + .limit(1000) + .paginate(count, (List vmResources) -> { + for (Tuple vmResource : vmResources) { + String accountUuid = (String) vmResource.get(0); + String vmInstanceUuid = (String) vmResource.get(1); + accountVmInstanceMap.computeIfAbsent(accountUuid, k -> new ArrayList<>()).add(vmInstanceUuid); + } + }); + + for (Map.Entry> entry : accountVmInstanceMap.entrySet()) { + String accountUuid = entry.getKey(); + List vmInstanceUuids = entry.getValue(); + upgradeSshKeyByAccount(accountUuid, vmInstanceUuids); + } + } + + private void upgradeSshKeyByAccount(String accountUuid, List vmInstanceUuids) { + List sshKeyPairVOS = new ArrayList<>(); + List sshKeyPairRefVOS = new ArrayList<>(); + + Map> sshKeyVmInstanceMap = new HashMap>(); + vmInstanceUuids.forEach(vmInstanceUuid -> { + String sshKey = VmSystemTags.SSHKEY.getTokenByResourceUuid(vmInstanceUuid, VmSystemTags.SSHKEY_TOKEN); + if (sshKey != null) { + sshKeyVmInstanceMap.computeIfAbsent(sshKey, k -> new ArrayList<>()).add(vmInstanceUuid); + } + }); + + Integer sshKeyIndex = 0; + for (Map.Entry> entry : sshKeyVmInstanceMap.entrySet()) { + String sshKey = entry.getKey(); + List vmUuids = entry.getValue(); + + // NOTE(ywang): Check the ssh key pair was uploaded by the account + String sshKeyPairUuid = null; + List sshKeyPairUuids = Q.New(AccountResourceRefVO.class) + .select(AccountResourceRefVO_.resourceUuid) + .eq(AccountResourceRefVO_.accountUuid, accountUuid) + .eq(AccountResourceRefVO_.resourceType, SshKeyPairVO.class.getSimpleName()) + .listValues(); + if (!sshKeyPairUuids.isEmpty()) { + sshKeyPairUuid = Q.New(SshKeyPairVO.class) + .select(SshKeyPairVO_.uuid) + .in(SshKeyPairVO_.uuid, sshKeyPairUuids) + .eq(SshKeyPairVO_.publicKey, sshKey) + .findValue(); + } + + if (sshKeyPairUuid == null) { + sshKeyIndex += 1; + sshKeyPairUuid = Platform.getUuid(); + SshKeyPairVO sshKeyPairVO = new SshKeyPairVO(); + sshKeyPairVO.setName(String.format("ssh_key_%s", sshKeyIndex)); + sshKeyPairVO.setUuid(sshKeyPairUuid); + sshKeyPairVO.setAccountUuid(accountUuid); + sshKeyPairVO.setPublicKey(sshKey); + sshKeyPairVO.setCreateDate(new Timestamp(new Date().getTime())); + sshKeyPairVOS.add(sshKeyPairVO); + } + + for (String vmUuid : vmUuids) { + // NOTE(ywang): Check the key was already associated to the vm + boolean isExist = Q.New(SshKeyPairRefVO.class) + .eq(SshKeyPairRefVO_.sshKeyPairUuid, sshKeyPairUuid) + .eq(SshKeyPairRefVO_.resourceUuid, vmUuid) + .eq(SshKeyPairRefVO_.resourceType, VmInstanceVO.class.getSimpleName()) + .isExists(); + if (!isExist) { + SshKeyPairRefVO sshKeyPairRefVO = new SshKeyPairRefVO(); + sshKeyPairRefVO.setSshKeyPairUuid(sshKeyPairUuid); + sshKeyPairRefVO.setResourceUuid(vmUuid); + sshKeyPairRefVO.setResourceType(VmInstanceVO.class.getSimpleName()); + sshKeyPairRefVO.setCreateDate(new Timestamp(new Date().getTime())); + sshKeyPairRefVOS.add(sshKeyPairRefVO); + } + } + } + + if (!sshKeyPairVOS.isEmpty()) { + dbf.persistCollection(sshKeyPairVOS); + } + if (!sshKeyPairRefVOS.isEmpty()) { + dbf.persistCollection(sshKeyPairRefVOS); + } + } + + @Override + public boolean start() { + if (SshKeyPairGlobalProperty.UPGRADE_SSH_KEY_PAIR_FROM_SYSTEM_TAG) { + upgradeVmInstanceSshKey(); + } + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/sugonSdnController/pom.xml b/plugin/sugonSdnController/pom.xml new file mode 100644 index 00000000000..a45fbb7638f --- /dev/null +++ b/plugin/sugonSdnController/pom.xml @@ -0,0 +1,109 @@ + + + + plugin + org.zstack + 5.4.0 + + 4.0.0 + + sugonSdnController + + + + org.zstack + compute + ${project.version} + + + org.zstack + network + ${project.version} + + + org.zstack + kvm + ${project.version} + + + org.zstack + configuration + ${project.version} + + + org.zstack + sdnController + ${project.version} + + + org.zstack + flatNetworkProvider + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/PackageInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/PackageInfo.java new file mode 100644 index 00000000000..a82583c7508 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/PackageInfo.java @@ -0,0 +1,12 @@ +package org.zstack.sugonSdnController; + +import org.zstack.header.PackageAPIInfo; + +/** + * Created by shixin on 09/19/2019. + */ +@PackageAPIInfo( + APICategoryName = "SugonSdnController" +) +public class PackageInfo { +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/RBACInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/RBACInfo.java new file mode 100644 index 00000000000..d9762b9f155 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/RBACInfo.java @@ -0,0 +1,26 @@ +package org.zstack.sugonSdnController; + +import org.zstack.header.identity.rbac.RBACDescription; + +public class RBACInfo implements RBACDescription { + @Override + public void permissions() { + permissionBuilder() + .name("sugonSdnController") + .adminOnlyAPIs("org.zstack.sugonSdnController.**") + .build(); + } + + @Override + public void contributeToRoles() { + } + + @Override + public void roles() { + + } + + @Override + public void globalReadableResources() { + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java new file mode 100644 index 00000000000..1ffaf20178e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java @@ -0,0 +1,57 @@ +package org.zstack.sugonSdnController.account; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.sdnController.SdnController; +import org.zstack.sugonSdnController.controller.SugonSdnController; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.core.db.Q; +import org.zstack.header.identity.AccountInventory; +import org.zstack.header.identity.BeforeCreateAccountExtensionPoint; +import org.zstack.header.identity.BeforeDeleteAccountExtensionPoint; +import org.zstack.header.identity.BeforeUpdateAccountExtensionPoint; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO_; + +/** + * @description: + * @author: liupt@sugon.com + * @create: 2022-10-09 + **/ +public class AccountSync implements BeforeCreateAccountExtensionPoint, BeforeUpdateAccountExtensionPoint, BeforeDeleteAccountExtensionPoint { + @Autowired + SdnControllerManager sdnControllerManager; + + @Override + public void beforeCreateAccount(AccountInventory account) { + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + if (sdn == null) { + return; + } + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + SugonSdnController sugonSdnController = (SugonSdnController) sdnController; + sugonSdnController.createAccount(account); + } + + @Override + public void beforeDeleteAccount(AccountInventory account) { + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + if (sdn == null) { + return; + } + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + SugonSdnController sugonSdnController = (SugonSdnController) sdnController; + sugonSdnController.deleteAccount(account); + } + + @Override + public void beforeUpdateAccount(AccountInventory account) { + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + if (sdn == null) { + return; + } + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + SugonSdnController sugonSdnController = (SugonSdnController) sdnController; + sugonSdnController.updateAccount(account); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java new file mode 100644 index 00000000000..45a68537e38 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java @@ -0,0 +1,702 @@ +package org.zstack.sugonSdnController.controller; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.net.util.SubnetUtils; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.header.identity.AccountInventory; +import org.zstack.header.identity.AccountVO; +import org.zstack.header.identity.AccountVO_; +import org.zstack.header.message.Message; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l3.*; +import org.zstack.header.network.sdncontroller.*; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; +import org.zstack.network.l3.L3NetworkSystemTags; +import org.zstack.sdnController.SdnController; +import org.zstack.sdnController.SdnControllerL2; +import org.zstack.sdnController.header.*; +import org.zstack.sugonSdnController.controller.api.*; +import org.zstack.sugonSdnController.controller.api.types.*; +import org.zstack.sugonSdnController.header.APICreateL2TfNetworkMsg; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; + +import java.util.*; + +import static org.zstack.core.Platform.operr; +import static org.zstack.utils.network.NetworkUtils.getSubnetInfo; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class SugonSdnController implements TfSdnController, SdnController, SdnControllerL2 { + private static final CLogger logger = Utils.getLogger(SugonSdnController.class); + + @Autowired + CloudBus bus; + @Autowired + DatabaseFacade dbf; + + private SdnControllerVO sdnControllerVO; + private TfHttpClient client; + + + public SugonSdnController(SdnControllerVO vo) { + sdnControllerVO = vo; + client = new TfHttpClient(vo.getIp()); + } + + @Override + public void handleMessage(SdnControllerMessage msg) { + bus.dealWithUnknownMessage((Message) msg); + } + + @Override + public void preInitSdnController(APIAddSdnControllerMsg msg, Completion completion) { + try { + long count = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).count(); + if(count > 0) { + completion.fail(operr("tf sdn controller already exists.")); + return; + } + AccountVO accountVO = Q.New(AccountVO.class).eq(AccountVO_.name, SugonSdnControllerConstant.ZSTACK_DEFAULT_ACCOUNT).find(); + if(accountVO == null) { + completion.fail(operr("get default admin account from zstack db failed")); + return; + } + String accountUuid = StringDSL.transToTfUuid(accountVO.getUuid()); + client = new TfHttpClient(msg.getIp()); + Domain domain = (Domain) client.getDomain(); + if(domain == null){ + completion.fail(operr("get default domain on tf controller failed")); + return; + } + Project defaultProject = (Project) client.findById(Project.class, accountUuid); + if(defaultProject == null){ + Project project = new Project(); + project.setParent(domain); + project.setDisplayName(SugonSdnControllerConstant.ZSTACK_DEFAULT_ACCOUNT); + project.setName(accountUuid); + project.setUuid(accountUuid); + Status status = client.create(project); + if(status.isSuccess()){ + logger.info("create tf project for zstack admin success"); + completion.success(); + }else{ + completion.fail(operr("create tf project for zstack admin on tf controller failed")); + } + }else{ + logger.warn("tf project for zstack admin already exists: " + accountUuid); + completion.success(); + } + } catch (Exception e) { + String message = String.format("create tf project for zstack admin on tf controller failed due to: %s", e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void createSdnControllerDb(APIAddSdnControllerMsg msg, SdnControllerVO vo, Completion completion) { + dbf.persist(vo); + completion.success(); + } + + @Override + public void deleteSdnControllerDb(SdnControllerVO vo) { + dbf.removeByPrimaryKey(vo.getUuid(), SdnControllerVO.class); + } + + @Override + public void initSdnController(APIAddSdnControllerMsg msg, Completion completion) { + completion.success(); + } + + @Override + public void postInitSdnController(SdnControllerVO vo, Completion completion){ + completion.success(); + } + + @Override + public void preCreateVxlanNetwork(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void createL2Network(L2NetworkInventory inv, APICreateL2NetworkMsg msg, Completion completion) { + completion.success(); + } + + @Override + public void postCreateVxlanNetwork(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void preAttachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + + @Override + public void attachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List clusterUuids, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void postAttachL2NetworkToCluster(L2VxlanNetworkInventory vxlan, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void createL2Network(L2NetworkVO l2NetworkVO, APICreateL2NetworkMsg msg, List systemTags, Completion completion) { + String accountUuid = StringDSL.transToTfUuid(l2NetworkVO.getAccountUuid()); + String uuid = StringDSL.transToTfUuid(l2NetworkVO.getUuid()); + String name = l2NetworkVO.getName(); + try { + APICreateL2TfNetworkMsg l2TfNetworkMsg = (APICreateL2TfNetworkMsg) msg; + Project project = (Project) client.findById(Project.class, accountUuid); + if(project == null) { + completion.fail(operr("get project[uuid:%s] on tf controller failed ", accountUuid)); + }else{ + VirtualNetwork virtualNetwork = new VirtualNetwork(); + virtualNetwork.setParent(project); + virtualNetwork.setDisplayName(l2NetworkVO.getName()); + virtualNetwork.setName(uuid); + virtualNetwork.setUuid(uuid); + if(l2TfNetworkMsg.getIpPrefix() != null) { + IPSegmentType ipSegmentType = new IPSegmentType(l2TfNetworkMsg.getIpPrefix(), l2TfNetworkMsg.getIpPrefixLength()); + virtualNetwork.setIpSegment(ipSegmentType); + } + Status status = client.create(virtualNetwork); + if(status.isSuccess()){ + logger.info("create tf l2 network success, name:" + name); + completion.success(); + }else{ + completion.fail(operr("create tf l2 network[name:%s] on tf controller failed ", name)); + } + } + } catch (Exception e) { + String message = String.format("create tf l2 network[name:%s] on tf controller failed due to: %s", name, e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void updateL2Network(L2NetworkVO l2NetworkVO, List systemTags, Completion completion) { + String uuid = StringDSL.transToTfUuid(l2NetworkVO.getUuid()); + String name = l2NetworkVO.getName(); + try { + VirtualNetwork virtualNetwork = (VirtualNetwork) client.findById(VirtualNetwork.class, uuid); + if(virtualNetwork == null){ + completion.fail(operr("get virtual network[uuid:%s] on tf controller failed ", uuid)); + }else{ + virtualNetwork.setDisplayName(name); + Status status = client.update(virtualNetwork); + if(status.isSuccess()){ + logger.info("update tf l2 network success, name:" + name); + completion.success(); + }else{ + completion.fail(operr("update tf l2 network[name:%s] on tf controller failed ", name)); + } + } + } catch (Exception e) { + String message = String.format("update tf l2 network[name:%s] on tf controller failed due to: %s ", name, e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void deleteL2Network(L2NetworkVO l2NetworkVO, List systemTags, Completion completion) { + String uuid = StringDSL.transToTfUuid(l2NetworkVO.getUuid()); + try { + Status status = client.delete(VirtualNetwork.class, uuid); + if(status.isSuccess()){ + logger.info("delete tf l2 network success, uuid:" + uuid); + completion.success(); + }else{ + completion.fail(operr("delete tf l2 network[uuid:%s] on tf controller failed ", uuid)); + } + } catch (Exception e) { + String message = String.format("delete tf l2 network[uuid:%s] on tf controller failed due to: %s", uuid, e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void deleteSdnController(SdnControllerDeletionMsg msg, SdnControllerInventory sdn, Completion completion) { + completion.success(); + } + + @Override + public void detachL2NetworkFromCluster(L2VxlanNetworkInventory vxlan, List clusterUuid, Completion completion) { + completion.success(); + } + + @Override + public void deleteL2Network(L2NetworkInventory vxlan, Completion completion) { + completion.success(); + } + + @Override + public List getVniRange(SdnControllerInventory controller) { + return Collections.emptyList(); + } + + @Override + public List getVlanRange(SdnControllerInventory controller) { + return Collections.emptyList(); + } + + @Override + public void createAccount(AccountInventory account) { + try { + ApiConnector apiConnector = ApiConnectorFactory.build(sdnControllerVO.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT); + Domain domain = (Domain) apiConnector.findByFQN(Domain.class, SugonSdnControllerConstant.TF_DEFAULT_DOMAIN); + Project project = new Project(); + project.setParent(domain); + project.setUuid(StringDSL.transToTfUuid(account.getUuid())); + project.setDisplayName(account.getName()); + project.setName(StringDSL.transToTfUuid(account.getUuid())); + Status status = apiConnector.create(project); + if (!status.isSuccess()) { + String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), status.getMsg()); +// String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); + logger.error(message); + } + } catch (Exception e){ + String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), e.getMessage()); + logger.error(message, e); + } + } + + @Override + public void deleteAccount(AccountInventory account) { + try { + ApiConnector apiConnector = ApiConnectorFactory.build(sdnControllerVO.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT); + Project project = new Project(); + project.setUuid(StringDSL.transToTfUuid(account.getUuid())); + Status status = apiConnector.delete(project); + if (!status.isSuccess()) { + String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), status.getMsg()); +// String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); + logger.error(message); + } + } catch (Exception e){ + String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), e.getMessage()); + logger.error(message, e); + } + } + + @Override + public void updateAccount(AccountInventory account) { + try { + ApiConnector apiConnector = ApiConnectorFactory.build(sdnControllerVO.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT); + Project project = new Project(); + project.setUuid(StringDSL.transToTfUuid(account.getUuid())); + project.setDisplayName(account.getName()); + Status status = apiConnector.update(project); + if (!status.isSuccess()) { + String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), status.getMsg()); +// String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed"); + logger.error(message); + } + } catch (Exception e){ + String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), e.getMessage()); + logger.error(message, e); + } + } + + @Override + public void deleteL3Network(L3NetworkVO l3NetworkVO, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork)client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + if(vn!=null){ + // 判断tf网络是否存在 + if(vn.getNetworkIpam()!=null) { + Optional opCheck = vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().stream() + .filter(k->k.getSubnetUuid().equals(StringDSL.transToTfUuid(l3NetworkVO.getUuid()))) + .findFirst(); + if (opCheck.isPresent()) { + // 移除指定的三层子网 + vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().remove(opCheck.get()); + if(vn.getNetworkIpam().get(0).getAttr().getIpamSubnets()==null||vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().size()==0){ + vn.getNetworkIpam().clear(); + } + } + // 更新 tf 网络信息 + Status status = client.update(vn); + if(!status.isSuccess()){ + completion.fail(operr("delete tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("delete tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + } else{ + completion.success(); + } + } else{ + String message = String.format("delete tf l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf network-ipam is missing"); + logger.info(message); + completion.success(); + } + } else{ + String message = String.format("delete tf l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("delete tf l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + + } + + @Override + public void updateL3Network(L3NetworkVO l3NetworkVO, APIUpdateL3NetworkMsg msg, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork)client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + // 判断tf网络是否存在 + if(vn!=null){ + if(vn.getNetworkIpam()!=null) { + // 判断子网是否存在 + Optional checkOp = vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().stream() + .filter(m->StringDSL.transToTfUuid(l3NetworkVO.getUuid()).equals(m.getSubnetUuid())) + .findFirst(); + if(checkOp.isPresent()){ + if(StringUtils.isNotBlank(msg.getName())&&StringUtils.isNotEmpty(msg.getName())){ + checkOp.get().setSubnetName(msg.getName()); + } + if(StringUtils.isNotBlank(msg.getDnsDomain())&&StringUtils.isNotEmpty(msg.getDnsDomain())){ + if(checkOp.get().getDnsNameservers()!=null) { + checkOp.get().getDnsNameservers().clear(); + } + checkOp.get().addDnsNameservers(msg.getDnsDomain()); + } + // 更新 tf 网络信息 + Status status = client.update(vn); + if(!status.isSuccess()){ + completion.fail(operr("update tf l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); + } else{ + completion.success(); + } + } + // 未找到指定的子网,继续执行后续的zstack逻辑 + completion.success(); + } else{ + String message = String.format("update tf l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf network-ipam is missing"); + logger.info(message); + completion.success(); + } + } else{ + String message = String.format("update tf l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("update tf l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void addL3IpRangeByCidr(L3NetworkVO l3NetworkVO, APIAddIpRangeByNetworkCidrMsg msg, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork) client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + if(vn!=null){ + IpamSubnetType ipamSubnetType = new IpamSubnetType(); + // subnet_uuid + ipamSubnetType.setSubnetUuid(StringDSL.transToTfUuid(l3NetworkVO.getUuid())); + // subnet:IP Range + SubnetType subnetType = new SubnetType(); + subnetType.setIpPrefix(msg.getNetworkCidr().split("/")[0]); + subnetType.setIpPrefixLen(Integer.parseInt(msg.getNetworkCidr().split("/")[1])); + ipamSubnetType.setSubnet(subnetType); + // subnet_name + ipamSubnetType.setSubnetName(l3NetworkVO.getName()); + // 特殊IP定义 + SubnetUtils.SubnetInfo subnetInfo = getSubnetInfo(new SubnetUtils(msg.getNetworkCidr())); + String gatewayIp = subnetInfo.getLowAddress(); + String serviceIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getLowAddress())+1); + String startIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getLowAddress())+2); + String endIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getHighAddress())-1); + // DNS -> 查询zstack数据库 + List dns = Q.New(L3NetworkDnsVO.class).eq(L3NetworkDnsVO_.l3NetworkUuid, l3NetworkVO.getUuid()).list(); + if(dns!=null&&dns.size()>0){ + ipamSubnetType.setDnsServerAddress(dns.get(0).getDns()); + } else{ + // 设置默认DnsServerAddress + ipamSubnetType.setDnsServerAddress(serviceIp); + } + // host_route -> 查询zstack数据库 + List hostRoutes = Q.New(L3NetworkHostRouteVO.class).eq(L3NetworkHostRouteVO_.l3NetworkUuid, l3NetworkVO.getUuid()).list(); + RouteTableType routeTableType = new RouteTableType(); + if(hostRoutes!=null&&hostRoutes.size()>0){ + hostRoutes.stream().forEach(k->{ + routeTableType.addRoute(new RouteType(k.getPrefix(),k.getNexthop(),null)); + }); + ipamSubnetType.setHostRoutes(routeTableType); + } + ipamSubnetType.setEnableDhcp(getEnableDHCPFlag(l3NetworkVO.getUuid())); + + // 设置默认网关 + ipamSubnetType.setDefaultGateway(gatewayIp); + // 设置可分配IP池范围 + AllocationPoolType allocationPoolType = new AllocationPoolType(startIp,endIp); + ipamSubnetType.addAllocationPools(allocationPoolType); + // 设置分配IP从小到大 + ipamSubnetType.setAddrFromStart(true); + VnSubnetsType vnSubnetsType = new VnSubnetsType(); + vnSubnetsType.addIpamSubnets(ipamSubnetType); + if(vn.getNetworkIpam()!=null){ + vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().add(ipamSubnetType); + } else{ + NetworkIpam networkIpam = new NetworkIpam(); + networkIpam.setName("default-network-ipam"); + vn.setNetworkIpam(networkIpam,vnSubnetsType); + } + // 更新 tf 网络信息 + Status status = client.update(vn); + if(!status.isSuccess()){ + completion.fail(operr("add tf l3 subnet[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("add tf l3 subnet[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + } else{ + completion.success(); + } + } else{ + String message = String.format("add tf l3 subnet[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("add tf l3 subnet[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void addL3HostRoute(L3NetworkVO l3NetworkVO, APIAddHostRouteToL3NetworkMsg msg, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork)client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + if(vn!=null){ + // 判断tf网络是否存在 + if(vn.getNetworkIpam()!=null) { + // 判断子网是否存在 + Optional checkOp = vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().stream() + .filter(m->StringDSL.transToTfUuid(l3NetworkVO.getUuid()).equals(m.getSubnetUuid())) + .findFirst(); + if(checkOp.isPresent()){ + // 子网存在 + Set hostRouters =l3NetworkVO.getHostRoutes(); + RouteTableType routeTableType = new RouteTableType(); + if(hostRouters!=null&&hostRouters.size()>0){ + hostRouters.stream().forEach(k->{ + routeTableType.addRoute(new RouteType(k.getPrefix(),k.getNexthop(),null)); + }); + } + routeTableType.addRoute(new RouteType(msg.getPrefix(),msg.getNexthop(),null)); + // 替换host route + checkOp.get().setHostRoutes(routeTableType); + // 更新 tf 网络信息 + Status status = client.update(vn); + if(!status.isSuccess()){ + completion.fail(operr("add host router to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("add host router to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + } else{ + completion.success(); + } + } else{ + completion.success(); + } + } else{ + String message = String.format("add host router to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf network-ipam is missing"); + logger.error(message); + completion.success(); + } + } else{ + String message = String.format("add host router to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("add host router to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void deleteL3HostRoute(L3NetworkVO l3NetworkVO, APIRemoveHostRouteFromL3NetworkMsg msg, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork)client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + if(vn!=null){ + // 判断tf网络是否存在 + if(vn.getNetworkIpam()!=null) { + Optional checkOp = vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().stream() + .filter(m->StringDSL.transToTfUuid(l3NetworkVO.getUuid()).equals(m.getSubnetUuid())) + .findFirst(); + if(checkOp.isPresent()){ + // 子网存在 + Set hostRouters =l3NetworkVO.getHostRoutes(); + RouteTableType routeTableType = new RouteTableType(); + if(hostRouters!=null&&hostRouters.size()>0){ + hostRouters.stream().forEach(k->{ + // prefix相同的主机路由不再通知tf + if(!k.getPrefix().equals(msg.getPrefix())) { + routeTableType.addRoute(new RouteType(k.getPrefix(), k.getNexthop(), null)); + } + }); + } + // 替换host route + checkOp.get().setHostRoutes(routeTableType); + // 更新 tf 网络信息 + Status status = client.update(vn); + if(!status.isSuccess()){ + completion.fail(operr("delete host route from l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("delete host route from l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + } else{ + completion.success(); + } + } else{ + completion.success(); + } + } else{ + String message = String.format("delete host route from l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf network-ipam is missing"); + logger.info(message); + completion.success(); + } + } else{ + String message = String.format("delete host route from l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("delete host route from l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void addL3Dns(L3NetworkVO l3NetworkVO, APIAddDnsToL3NetworkMsg msg, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork)client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + // 判断tf网络是否存在 + if(vn!=null){ + if(vn.getNetworkIpam()!=null) { + // 判断子网是否存在 + Optional checkOp = vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().stream() + .filter(m->StringDSL.transToTfUuid(l3NetworkVO.getUuid()).equals(m.getSubnetUuid())) + .findFirst(); + if(checkOp.isPresent()){ + DhcpOptionsListType type = checkOp.get().getDhcpOptionList(); + if(type!=null){ + String currDhcpValue = type.getDhcpOption().get(0).getDhcpOptionValue(); + if(StringUtils.isNotEmpty(currDhcpValue)){ + type.getDhcpOption().get(0).setDhcpOptionValue(currDhcpValue+" "+ msg.getDns()); + } else{ + type.getDhcpOption().get(0).setDhcpOptionValue(msg.getDns()); + } + } else{ + DhcpOptionsListType dhcpOptionsListType = new DhcpOptionsListType(); + DhcpOptionType dhcpOptionType = new DhcpOptionType(); + dhcpOptionType.setDhcpOptionValue(msg.getDns()); + dhcpOptionType.setDhcpOptionName("6"); + dhcpOptionsListType.addDhcpOption(dhcpOptionType); + checkOp.get().setDhcpOptionList(dhcpOptionsListType); + } + // 更新 tf 网络信息 + Status status = client.update(vn); + if(!status.isSuccess()){ + completion.fail(operr("add dns to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("add dns to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + } else{ + completion.success(); + } + } + // 未找到指定的子网,继续执行后续的zstack逻辑 + completion.success(); + } else{ + String message = String.format("add dns to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf network-ipam is missing"); + logger.info(message); + completion.success(); + } + } else{ + String message = String.format("add dns to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("add dns to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + @Override + public void deleteL3Dns(L3NetworkVO l3NetworkVO, APIRemoveDnsFromL3NetworkMsg msg, Completion completion) { + try { + // 获取 tf 网络信息 + VirtualNetwork vn = (VirtualNetwork)client.findById(VirtualNetwork.class, StringDSL.transToTfUuid(l3NetworkVO.getL2NetworkUuid())); + if(vn!=null){ + // 判断tf网络是否存在 + if(vn.getNetworkIpam()!=null) { + Optional checkOp = vn.getNetworkIpam().get(0).getAttr().getIpamSubnets().stream() + .filter(m->StringDSL.transToTfUuid(l3NetworkVO.getUuid()).equals(m.getSubnetUuid())) + .findFirst(); + if(checkOp.isPresent()){ + // 子网存在 + String dnsValue = checkOp.get().getDhcpOptionList().getDhcpOption().get(0).getDhcpOptionValue(); + List dnsValues = new ArrayList<>(Arrays.asList(dnsValue.split(" "))); + dnsValues.remove(msg.getDns()); + checkOp.get().getDhcpOptionList().getDhcpOption().get(0).setDhcpOptionValue(StringUtils.join(dnsValues, " ")); + // 更新 tf 网络信息 + Status status = client.update(vn); + if (!status.isSuccess()) { + completion.fail(operr("delete dns from to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),status.getMsg())); +// completion.fail(operr("delete dns from to l3 network[name:%s] on tf controller failed due to:%s", l3NetworkVO.getName(),"tf api call failed")); + } else { + completion.success(); + } + } + // 未找到指定的子网,继续执行后续的zstack逻辑 + completion.success(); + } else{ + String message = String.format("delete dns from to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf network-ipam is missing"); + logger.info(message); + completion.success(); + } + } else{ + String message = String.format("delete dns from to l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), "tf virtual network is missing"); + logger.error(message); + completion.fail(operr(message)); + } + } catch (Exception e){ + String message = String.format("delete dns from l3 network[name:%s] on tf controller failed due to: %s ",l3NetworkVO.getName(), e.getMessage()); + logger.error(message, e); + completion.fail(operr(message)); + } + } + + private boolean getEnableDHCPFlag(String l3Uuid){ + String enableDHCP = L3NetworkSystemTags.ENABLE_DHCP.getTokenByResourceUuid(l3Uuid, L3NetworkSystemTags.ENABLE_DHCP_TOKEN); + return Boolean.parseBoolean(enableDHCP); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerConstant.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerConstant.java new file mode 100644 index 00000000000..807bafed469 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerConstant.java @@ -0,0 +1,13 @@ +package org.zstack.sugonSdnController.controller; + +public class SugonSdnControllerConstant { + private SugonSdnControllerConstant() { + throw new IllegalStateException("Constant class"); + } + public static final String TF_CONTROLLER = "TF"; + public static final String L2_TF_NETWORK_TYPE = "TfL2Network"; + public static final String TF_DEFAULT_DOMAIN = "default-domain"; + public static final String ZSTACK_DEFAULT_ACCOUNT = "admin"; + + public static final String L3_TF_NETWORK_TYPE = "TfL3Network"; +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerFactory.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerFactory.java new file mode 100644 index 00000000000..b277a336c3d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerFactory.java @@ -0,0 +1,44 @@ +package org.zstack.sugonSdnController.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.network.securitygroup.SecurityGroupSdnBackend; +import org.zstack.sdnController.SdnController; +import org.zstack.sdnController.SdnControllerFactory; +import org.zstack.sdnController.SdnControllerL2; +import org.zstack.sdnController.SdnControllerType; +import org.zstack.header.network.sdncontroller.SdnControllerVO; + +public class SugonSdnControllerFactory implements SdnControllerFactory { + + SdnControllerType sdnControllerType = new SdnControllerType(SugonSdnControllerConstant.TF_CONTROLLER); + + @Autowired + private DatabaseFacade dbf; + + @Override + public SdnControllerType getVendorType() { + return sdnControllerType; + } + + @Override + public SdnControllerVO persistSdnController(SdnControllerVO vo) { + vo = dbf.persistAndRefresh(vo); + return vo; + } + + @Override + public SdnController getSdnController(SdnControllerVO vo) { + return new SugonSdnController(vo); + } + + @Override + public SdnControllerL2 getSdnControllerL2(SdnControllerVO vo) { + return new SugonSdnController(vo); + } + + @Override + public SecurityGroupSdnBackend getSdnControllerSecurityGroup(SdnControllerVO vo) { + return null; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerGlobalProperty.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerGlobalProperty.java new file mode 100644 index 00000000000..7f068619e4d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnControllerGlobalProperty.java @@ -0,0 +1,13 @@ +package org.zstack.sugonSdnController.controller; + +import org.zstack.core.GlobalProperty; +import org.zstack.core.GlobalPropertyDefinition; + +@GlobalPropertyDefinition +public class SugonSdnControllerGlobalProperty { + @GlobalProperty(name="Tf.Scheme", defaultValue = "http") + public static String TF_CONTROLLER_SCHEME; + + @GlobalProperty(name="Tf.Port", defaultValue = "8082") + public static int TF_CONTROLLER_PORT; +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java new file mode 100644 index 00000000000..d278b476b38 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java @@ -0,0 +1,36 @@ +package org.zstack.sugonSdnController.controller; + +import org.zstack.header.core.Completion; +import org.zstack.header.identity.AccountInventory; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l3.*; + +import java.util.List; + +public interface TfSdnController { + + void createL2Network(L2NetworkVO l2NetworkVO, APICreateL2NetworkMsg msg, List systemTags, Completion completion); + void updateL2Network(L2NetworkVO l2NetworkVO, List systemTags, Completion completion); + void deleteL2Network(L2NetworkVO l2NetworkVO, List systemTags, Completion completion); + + // 账号同步:zstack->tf + void createAccount(AccountInventory account); + void deleteAccount(AccountInventory account); + void updateAccount(AccountInventory account); + + // L3网络:zstack->tf + void deleteL3Network(L3NetworkVO l3NetworkVO, Completion completion); + + void updateL3Network(L3NetworkVO l3NetworkVO, APIUpdateL3NetworkMsg msg, Completion completion); + + void addL3IpRangeByCidr(L3NetworkVO l3NetworkVO, APIAddIpRangeByNetworkCidrMsg msg, Completion completion); + + void addL3HostRoute(L3NetworkVO l3NetworkVO, APIAddHostRouteToL3NetworkMsg msg, Completion completion); + + void deleteL3HostRoute(L3NetworkVO l3NetworkVO, APIRemoveHostRouteFromL3NetworkMsg msg, Completion completion); + + void addL3Dns(L3NetworkVO l3NetworkVO, APIAddDnsToL3NetworkMsg msg, Completion completion); + + void deleteL3Dns(L3NetworkVO l3NetworkVO, APIRemoveDnsFromL3NetworkMsg msg, Completion completion); +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiBuilder.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiBuilder.java new file mode 100644 index 00000000000..9385dfd8895 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiBuilder.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +package org.zstack.sugonSdnController.controller.api; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +class ApiBuilder { + private static final CLogger s_logger = Utils.getLogger(ApiBuilder.class); + ApiBuilder() { + } + + public String getTypename(Class cls) { + String clsname = cls.getName(); + int loc = clsname.lastIndexOf('.'); + if (loc > 0) { + clsname = clsname.substring(loc + 1); + } + String typename = new String(); + for (int i = 0; i < clsname.length(); i++) { + char ch = clsname.charAt(i); + if (Character.isUpperCase(ch)) { + if (i > 0) { + typename += "-"; + } + ch = Character.toLowerCase(ch); + } + typename += ch; + } + return typename; + } + + public ApiObjectBase jsonToApiObject(String data, Class cls) { + if (data == null) { + return null; + } + final String typename = getTypename(cls); + final JsonParser parser = new JsonParser(); + final JsonObject js_obj = parser.parse(data).getAsJsonObject(); + if (js_obj == null) { + s_logger.warn("Unable to parse response"); + return null; + } + JsonElement element = null; + if (cls.getGenericSuperclass() == VRouterApiObjectBase.class) { + element = js_obj; + } else { + element = js_obj.get(typename); + } + if (element == null) { + s_logger.warn("Element " + typename + ": not found"); + return null; + } + ApiObjectBase resp = ApiSerializer.deserialize(element.toString(), cls); + return resp; + } + + // body: {"type": class, "fq_name": [parent..., name]} + public String buildFqnJsonString(Class cls, List name_list) { + Gson json = new Gson(); + JsonObject js_dict = new JsonObject(); + js_dict.add("type", json.toJsonTree(getTypename(cls))); + js_dict.add("fq_name", json.toJsonTree(name_list)); + return js_dict.toString(); + } + + public String getUuid(String data) { + if (data == null) { + return null; + } + final JsonParser parser = new JsonParser(); + final JsonObject js_obj= parser.parse(data).getAsJsonObject(); + if (js_obj == null) { + s_logger.warn("Unable to parse response"); + return null; + } + final JsonElement element = js_obj.get("uuid"); + if (element == null) { + s_logger.warn("Element \"uuid\": not found"); + return null; + } + return element.getAsString(); + } + + public List jsonToApiObjects(String data, Class cls, boolean withDetail) throws IOException { + if (data == null) { + return null; + } + final String typename = getTypename(cls); + List list = new ArrayList(); + final JsonParser parser = new JsonParser(); + final JsonObject js_obj= parser.parse(data).getAsJsonObject(); + if (js_obj == null) { + s_logger.warn("Unable to parse response"); + return null; + } + final JsonArray array = js_obj.getAsJsonArray(typename + "s"); + if (array == null) { + s_logger.warn("Element " + typename + ": not found"); + return null; + } + Gson json = ApiSerializer.getDeserializer(); + for (JsonElement element : array) { + ApiObjectBase obj; + if (withDetail) { + obj = jsonToApiObject(element.toString(), cls); + } else { + obj = json.fromJson(element.toString(), cls); + } + + if (obj == null) { + s_logger.warn("Unable to decode list element"); + continue; + } + list.add(obj); + } + return list; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnector.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnector.java new file mode 100644 index 00000000000..3df48003c56 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnector.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +package org.zstack.sugonSdnController.controller.api; + +import java.io.IOException; +import java.util.List; + +public interface ApiConnector { + ApiConnector credentials(String username, String password); + ApiConnector tenantName(String tenantName); + ApiConnector authToken(String token); + ApiConnector authServer(String type, String url); + + Status commitDrafts(ApiObjectBase obj) throws IOException; + Status discardDrafts(ApiObjectBase obj) throws IOException; + Status create(ApiObjectBase obj) throws IOException; + Status read(ApiObjectBase obj) throws IOException; + Status update(ApiObjectBase obj) throws IOException; + Status delete(ApiObjectBase obj) throws IOException; + Status delete(Class cls, String uuid) throws IOException; + ApiObjectBase findById(Class cls, String uuid) throws IOException; + /** + * Query the api-server name-to-uuid mappings. + * + * @param cls the class of the api object. + * @param parent parent object. If null the default parent for this object type is used. + * @param name unqualified object name. + * @return the uuid of the specified object, if found. + * @throws IOException + */ + String findByName(Class cls, ApiObjectBase parent, String name) throws IOException; + /** + * Query the api-server name-to-uuid mappings. + * + * @param cls the class of the api object. + * @param fqn fully qualified name as a list of strings. + * @return the uuid of the specified object, if found. + */ + String findByName(Class cls, List fqn) throws IOException; + ApiObjectBase find(Class cls, ApiObjectBase parent, String name) throws IOException; + ApiObjectBase findByFQN(Class cls, String fullName) throws IOException; + List list(Class cls, List parent) throws IOException; + List listWithDetail(Class cls, String fields, String filters) throws IOException; + List getObjects(Class cls, + List> refList) throws IOException; + + Status sync(String uri) throws IOException; + + public void dispose(); +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorFactory.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorFactory.java new file mode 100644 index 00000000000..d2acda7b5a2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +package org.zstack.sugonSdnController.controller.api; + +import java.lang.reflect.Constructor; + +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class ApiConnectorFactory { + private static final CLogger s_logger = + Utils.getLogger(ApiConnectorFactory.class); + static private ApiConnectorFactory _singleton; + private Class _cls; + + private ApiConnectorFactory() { + _cls = ApiConnectorImpl.class; + } + + private Constructor getConstructor() throws NoSuchMethodException { + return _cls.getConstructor(String.class, Integer.TYPE); + } + + private static synchronized ApiConnectorFactory getInstance() { + if (_singleton == null) { + _singleton = new ApiConnectorFactory(); + } + return _singleton; + } + + /** + * Create an ApiConnector object. + * @param hostname name or IP address of contrail VNC api server. + * @port api server port. + * @return ApiConnector implementation. + */ + public static ApiConnector build(String hostname, int port) { + ApiConnectorFactory factory = getInstance(); + try { + Constructor constructor = factory.getConstructor(); + return constructor.newInstance(hostname, port); + } catch (Exception ex) { + s_logger.error("Unable to create object", ex); + } + return null; + } + + public static void setImplementation(Class cls) { + ApiConnectorFactory factory = getInstance(); + factory._cls = cls; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java new file mode 100644 index 00000000000..ef88f3c9109 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorImpl.java @@ -0,0 +1,712 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +package org.zstack.sugonSdnController.controller.api; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + +import com.google.common.io.ByteStreams; +import com.google.gson.JsonObject; +import org.apache.commons.lang.StringUtils; +import org.apache.http.ConnectionReuseStrategy; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.HttpVersion; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.DefaultHttpClientConnection; +import org.apache.http.message.BasicHttpEntityEnclosingRequest; +import org.apache.http.params.HttpParams; +import org.apache.http.params.HttpProtocolParams; +import org.apache.http.params.SyncBasicHttpParams; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.BasicHttpProcessor; +import org.apache.http.protocol.ExecutionContext; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.HttpRequestExecutor; +import org.apache.http.protocol.ImmutableHttpProcessor; +import org.apache.http.protocol.RequestConnControl; +import org.apache.http.protocol.RequestContent; +import org.apache.http.protocol.RequestDate; +import org.apache.http.protocol.RequestExpectContinue; +import org.apache.http.protocol.RequestTargetHost; +import org.apache.http.protocol.RequestUserAgent; +import org.apache.http.util.EntityUtils; +import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableList; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +@SuppressWarnings("deprecation") +class ApiConnectorImpl implements ApiConnector { + private static final CLogger s_logger = + Utils.getLogger(ApiConnector.class); + + private String _api_hostname; + private int _api_port; + private ApiBuilder _apiBuilder; + + private String _username; + private String _password; + private String _tenant; + private boolean _has_input_authtoken; + private String _authtoken; + private String _authtype; + private String _authurl; + + // HTTP Connection parameters + private HttpParams _params; + private HttpProcessor _httpproc; + private HttpRequestExecutor _httpexecutor; + private HttpContext _httpcontext; + private HttpHost _httphost; + private DefaultHttpClientConnection _connection; + private ConnectionReuseStrategy _connectionStrategy; + public final static int MAX_RETRIES = 5; + public final int clientId = 2; + + public ApiConnectorImpl(String hostname, int port) { + _api_hostname = hostname; + _api_port = port; + _has_input_authtoken = true; + initHttpClient(); + initHttpServerParams(hostname, port); + _apiBuilder = new ApiBuilder(); + } + + private void initHttpClient() { + _params = new SyncBasicHttpParams(); + HttpProtocolParams.setVersion(_params, HttpVersion.HTTP_1_1); + HttpProtocolParams.setContentCharset(_params, "UTF-8"); + HttpProtocolParams.setUseExpectContinue(_params, false); + HttpProtocolParams.setHttpElementCharset(_params, "UTF-8"); + + _httpproc = new ImmutableHttpProcessor( + // Required protocol interceptors + new BasicHttpProcessor(), + new RequestConnControl(), + new RequestContent(), + new RequestDate(), + new RequestTargetHost(), + // Recommended protocol interceptors + new RequestUserAgent(), + new RequestExpectContinue() + ); + _httpexecutor = new HttpRequestExecutor(); + _httpcontext = new BasicHttpContext(null); + _connection = new DefaultHttpClientConnection(); + _connectionStrategy = new DefaultConnectionReuseStrategy(); + } + + private void initHttpServerParams(String hostname, int port) { + + _httphost = new HttpHost(hostname, port); + _httpcontext.setAttribute(ExecutionContext.HTTP_CONNECTION, _connection); + _httpcontext.setAttribute(ExecutionContext.HTTP_TARGET_HOST, _httphost); + + } + + @Override + public ApiConnector credentials(String username, String password) { + _username = username; + _password = password; + return this; + } + @Override + public ApiConnector tenantName(String tenant) { + _tenant = tenant; + return this; + } + @Override + public ApiConnector authToken(String token) { + _has_input_authtoken = true; + _authtoken = token; + return this; + } + @Override + public ApiConnector authServer(String type, String url) { + _has_input_authtoken = false; + _authtype = type; + _authurl = url; + return this; + } + + private void checkResponseKeepAliveStatus(HttpResponse response) throws IOException { + + if (!_connectionStrategy.keepAlive(response, _httpcontext)) { + _connection.close(); + } + } + + private void checkConnection() throws IOException { + if (!_connection.isOpen()) { + s_logger.info("http connection <" + _httphost.getHostName() + ", " + + _httphost.getPort() + "> does not exit"); + Socket socket = new Socket(_httphost.getHostName(), _httphost.getPort()); + _connection.bind(socket, _params); + s_logger.info("http connection <" + _httphost.getHostName() + ", " + + _httphost.getPort() + "> established"); + } + } + + @Override + protected void finalize() { + dispose(); + } + + + public String getHostName() { + return _api_hostname; + } + + public int getPort() { + return _api_port; + } + + // return value indicates whether the token changed + private boolean authenticate() { + /* + if (_has_input_authtoken) { + return false; + } + + _authtoken = null; + if ("keystone".equals(_authtype)) { + try { + OSClient os = OSFactory.builder().endpoint(_authurl) + .credentials(_username, _password).tenantName(_tenant).authenticate(); + _authtoken = os.getToken().getId(); + return true; + } + catch (AuthenticationException authe) { + s_logger.warn("authenticate to keystone " + _authurl + "failed: " + authe); + return false; + } + } + */ + // authenticate type unknown + return false; + + } + + private HttpResponse execute(String method, String uri, StringEntity entity) throws IOException { + return execute_doauth(method, uri, entity, MAX_RETRIES); + } + + private HttpResponse execute_doauth(String method, String uri, StringEntity entity, + int retry_count) throws IOException { + + checkConnection(); + + BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(method, uri); + if (entity != null) { + request.setEntity(entity); + s_logger.debug(">> Request: " + method + ", " + request.getRequestLine().getUri() + + ", " + EntityUtils.toString(entity)); + } else { + s_logger.debug(">> Request: " + method + ", " + request.getRequestLine().getUri()); + } + HttpResponse response = null; + request.setParams(_params); + if (_authtoken != null) { + request.setHeader("X-AUTH-TOKEN", _authtoken); + } + try { + _connection.setSocketTimeout(6000); + _httpexecutor.preProcess(request, _httpproc, _httpcontext); + response = _httpexecutor.execute(request, _connection, _httpcontext); + response.setParams(_params); + _httpexecutor.postProcess(response, _httpproc, _httpcontext); + } catch (Exception e) { + if (retry_count == 0) { + s_logger.error("<< Received exception from the Api server, max retries exhausted: " + e); + s_logger.error(Throwables.getStackTraceAsString(e)); + return null; + } + s_logger.info("<< Api server connection timed out, retrying " + retry_count + " more times"); + return execute_doauth(method, uri, entity, --retry_count); + } + + s_logger.debug("<< Response Status: " + response.getStatusLine()); + if ((response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED + && retry_count > 0)) { + if (authenticate()) { + getResponseData(response); + checkResponseKeepAliveStatus(response); + s_logger.error("<< Received \"unauthorized response from the Api server, retrying " + + retry_count + " more times after authentication"); + return execute_doauth(method, uri, entity, --retry_count); + } + } + + return response; + } + + private String getResponseData(HttpResponse response) { + HttpEntity entity = response.getEntity(); + if (entity == null) { + return null; + } + String data; + try { + data = EntityUtils.toString(entity); + EntityUtils.consumeQuietly(entity); + } catch (Exception ex) { + s_logger.warn("Unable to read http response", ex); + return null; + } + return data; + } + + private void updateObject(ApiObjectBase obj, ApiObjectBase resp) { + Class cls = obj.getClass(); + + // getDeclaredFields doesn't return fields from parent class (ApiObjectBase) + // go up the hierarchy until ApiObjectBase inclusively + do { + updateFields(obj, resp, cls); + cls = cls.getSuperclass(); + } while (cls != Object.class); + } + + private void updateFields(ApiObjectBase obj, ApiObjectBase resp, Class cls) { + for (Field f : cls.getDeclaredFields()) { + f.setAccessible(true); + final Object nv; + try { + nv = f.get(resp); + } catch (Exception ex) { + s_logger.warn("Unable to read new value for " + f.getName() + ": " + ex.getMessage()); + continue; + } + final Object value; + try { + value = f.get(obj); + } catch (Exception ex) { + s_logger.warn("Unable to read current value of " + f.getName() + ": " + ex.getMessage()); + continue; + } + if (value == null && nv != null) { + try { + f.set(obj, nv); + } catch (Exception ex) { + s_logger.warn("Unable to set " + f.getName() + ": " + ex.getMessage()); + } + } + } + } + + private Status noResponseStatus() { + return Status.failure("No response from API server."); + } + + @Override + public synchronized Status commitDrafts(ApiObjectBase obj) throws IOException { + return draftOperation("commit", obj.getUuid()); + } + + @Override + public synchronized Status discardDrafts(ApiObjectBase obj) throws IOException { + return draftOperation("discard", obj.getUuid()); + } + + private Status draftOperation(String action, String scopeUuid) throws IOException { + String jsdata = buildDraftActionJson(action, scopeUuid); + + HttpResponse response = execute(HttpPost.METHOD_NAME, "/security-policy-draft", + new StringEntity(jsdata, ContentType.APPLICATION_JSON)); + + if (response == null || response.getStatusLine() == null) { + return noResponseStatus(); + } + + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_OK + && status != HttpStatus.SC_ACCEPTED ) { +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); + s_logger.warn("<< Response:" + reason); + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + + EntityUtils.consumeQuietly(response.getEntity()); + checkResponseKeepAliveStatus(response); + return Status.success(); + } + + private String buildDraftActionJson(String action, String scopeUuid) { + JsonObject jsDict = new JsonObject(); + jsDict.addProperty("scope_uuid", scopeUuid); + jsDict.addProperty("action", action); + return jsDict.toString(); + } + + @Override + public synchronized Status create(ApiObjectBase obj) throws IOException { + final String typename = _apiBuilder.getTypename(obj.getClass()); + final String jsdata = ApiSerializer.serializeObject(typename, obj); + + HttpResponse response; + if (obj instanceof VRouterApiObjectBase) { + response = execute(HttpPost.METHOD_NAME, "/" + typename, + new StringEntity(jsdata, ContentType.APPLICATION_JSON)); + } else { + obj.updateQualifiedName(); + response = execute(HttpPost.METHOD_NAME, "/" + typename + "s", + new StringEntity(jsdata, ContentType.APPLICATION_JSON)); + } + + if (response == null || response.getStatusLine() == null) { + return noResponseStatus(); + } + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_OK + && status != HttpStatus.SC_CREATED + && status != HttpStatus.SC_ACCEPTED ) { + +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); + s_logger.error("create api request failed: " + reason); + if (status != HttpStatus.SC_NOT_FOUND) { + s_logger.error("Failure message: " + getResponseData(response)); + } + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + + ApiObjectBase resp = _apiBuilder.jsonToApiObject(getResponseData(response), obj.getClass()); + if (resp == null) { + String reason = "Unable to decode Create response"; + s_logger.error(reason); + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + + String uuid = obj.getUuid(); + if (uuid == null) { + obj.setUuid(resp.getUuid()); + } else if (!uuid.equals(resp.getUuid()) + && !(obj instanceof VRouterApiObjectBase)) { + s_logger.warn("Response contains unexpected uuid: " + resp.getUuid()); + checkResponseKeepAliveStatus(response); + return Status.success(); + } + s_logger.debug("Create " + typename + " uuid: " + obj.getUuid()); + checkResponseKeepAliveStatus(response); + return Status.success(); + } + + @Override + public synchronized Status update(ApiObjectBase obj) throws IOException { + final String typename = _apiBuilder.getTypename(obj.getClass()); + final String jsdata = ApiSerializer.serializeObject(typename, obj); + final HttpResponse response = execute(HttpPut.METHOD_NAME, "/" + typename + '/' + obj.getUuid(), + new StringEntity(jsdata, ContentType.APPLICATION_JSON)); + + if (response == null || response.getStatusLine() == null) { + return noResponseStatus(); + } + + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_OK + && status != HttpStatus.SC_ACCEPTED ) { +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); + s_logger.warn("<< Response:" + reason); + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + + EntityUtils.consumeQuietly(response.getEntity()); + checkResponseKeepAliveStatus(response); + return Status.success(); + } + + @Override + public synchronized Status read(ApiObjectBase obj) throws IOException { + final String typename = _apiBuilder.getTypename(obj.getClass()); + final HttpResponse response = execute(HttpGet.METHOD_NAME, + "/" + typename + '/' + obj.getUuid(), null); + + if (response == null || response.getStatusLine() == null) { + return noResponseStatus(); + } + + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_OK) { +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); + s_logger.warn("GET failed: " + reason); + if (status != HttpStatus.SC_NOT_FOUND) { + s_logger.error("Failure message: " + getResponseData(response)); + } + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + s_logger.debug("Response: " + response); + ApiObjectBase resp = _apiBuilder.jsonToApiObject(getResponseData(response), obj.getClass()); + if (resp == null) { + String message = "Unable to decode GET response."; + s_logger.warn(message); + checkResponseKeepAliveStatus(response); + return Status.failure(message); + } + updateObject(obj, resp); + checkResponseKeepAliveStatus(response); + return Status.success(); + } + + @Override + public Status delete(ApiObjectBase obj) throws IOException { + return delete(obj.getClass(), obj.getUuid()); + } + + @Override + public synchronized Status delete(Class cls, String uuid) throws IOException { + if (findById(cls, uuid) == null) { + // object does not exist so we are ok + return Status.success(); + } + + final String typename = _apiBuilder.getTypename(cls); + final HttpResponse response = execute(HttpDelete.METHOD_NAME, + "/" + typename + '/' + uuid, null); + + if (response == null || response.getStatusLine() == null) { + return Status.failure("No response from API server."); + } + + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_OK + && status != HttpStatus.SC_NO_CONTENT + && status != HttpStatus.SC_ACCEPTED ) { +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); + s_logger.warn("Delete failed: " + reason); + if (status != HttpStatus.SC_NOT_FOUND) { + s_logger.error("Failure message: " + getResponseData(response)); + } + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + EntityUtils.consumeQuietly(response.getEntity()); + checkResponseKeepAliveStatus(response); + return Status.success(); + } + + @Override + public synchronized ApiObjectBase find(Class cls, ApiObjectBase parent, String name) throws IOException { + String uuid = findByName(cls, parent, name); + if (uuid == null) { + return null; + } + return findById(cls, uuid); + } + + @Override + public ApiObjectBase findByFQN(Class cls, String fullName) throws IOException { + List fqn = ImmutableList.copyOf(StringUtils.split(fullName, ':')); + String uuid = findByName(cls, fqn); + if (uuid == null) { + return null; + } + return findById(cls, uuid); + } + + @Override + public synchronized ApiObjectBase findById(Class cls, String uuid) throws IOException { + final String typename = _apiBuilder.getTypename(cls); + final HttpResponse response = execute(HttpGet.METHOD_NAME, + '/' + typename + '/' + uuid, null); + + if (response == null || response.getStatusLine() == null) { + return null; + } + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + EntityUtils.consumeQuietly(response.getEntity()); + checkResponseKeepAliveStatus(response); + return null; + } + ApiObjectBase object = _apiBuilder.jsonToApiObject(getResponseData(response), cls); + if (object == null) { + s_logger.warn("Unable to decode find response"); + } + + checkResponseKeepAliveStatus(response); + return object; + } + + @Override + public String findByName(Class cls, ApiObjectBase parent, String name) throws IOException { + List name_list = new ArrayList(); + if (parent != null) { + name_list.addAll(parent.getQualifiedName()); + } else { + try { + name_list.addAll(cls.newInstance().getDefaultParent()); + } catch (Exception ex) { + // Instantiation or IllegalAccess + s_logger.error("Failed to instantiate object of class " + cls.getName(), ex); + return null; + } + } + name_list.add(name); + return findByName(cls, name_list); + } + + @Override + // POST http://hostname:port/fqname-to-id + // body: {"type": class, "fq_name": [parent..., name]} + public synchronized String findByName(Class cls, List name_list) throws IOException { + String jsonStr = _apiBuilder.buildFqnJsonString(cls, name_list); + final HttpResponse response = execute(HttpPost.METHOD_NAME, "/fqname-to-id", + new StringEntity(jsonStr, ContentType.APPLICATION_JSON)); + + if (response == null || response.getStatusLine() == null) { + return null; + } + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + EntityUtils.consumeQuietly(response.getEntity()); + checkResponseKeepAliveStatus(response); + return null; + } + + String data = getResponseData(response); + if (data == null) { + checkResponseKeepAliveStatus(response); + return null; + } + s_logger.debug("<< Response Data: " + data); + + String uuid = _apiBuilder.getUuid(data); + if (uuid == null) { + s_logger.warn("Unable to parse response"); + checkResponseKeepAliveStatus(response); + return null; + } + checkResponseKeepAliveStatus(response); + return uuid; + } + + private synchronized List listResult(Class cls, HttpResponse response, boolean withDetail) throws IOException { + if (response == null || response.getStatusLine() == null) { + return null; + } + + if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { + s_logger.warn("list failed with :" + response.getStatusLine().getReasonPhrase()); + EntityUtils.consumeQuietly(response.getEntity()); + checkResponseKeepAliveStatus(response); + return null; + } + + String data = getResponseData(response); + if (data == null) { + checkResponseKeepAliveStatus(response); + return null; + } + List list = _apiBuilder.jsonToApiObjects(data, cls, withDetail); + if (list == null) { + s_logger.warn("Unable to parse/deserialize response: " + data); + } + checkResponseKeepAliveStatus(response); + return list; + } + + @Override + public synchronized List list(Class cls, List parent) throws IOException { + final String typename = _apiBuilder.getTypename(cls); + final HttpResponse response = execute(HttpGet.METHOD_NAME, '/' + typename + 's', null); + return listResult(cls, response, false); + } + + @Override + public synchronized List listWithDetail(Class cls, + String fields, + String filters) throws IOException { + final String typename = _apiBuilder.getTypename(cls); + String uri = '/' + typename + "s?detail=true"; + if (fields != null) { + uri = uri + "&fields=" + fields; + } + if (filters != null) { + uri = uri + "&filters=" + filters; + } + final HttpResponse response = execute(HttpGet.METHOD_NAME, uri, null); + + return listResult(cls, response, true); + } + + + @Override + public List + getObjects(Class cls, List> refList) throws IOException { + + List list = new ArrayList(); + for (ObjectReference ref : refList) { + ApiObjectBase obj = findById(cls, ref.getUuid()); + if (obj == null) { + s_logger.warn("Unable to find element with uuid: " + ref.getUuid()); + continue; + } + list.add(obj); + } + return list; + } + + @Override + public Status sync(String uri) throws IOException { + HttpResponse response; + String jsdata = "{\"type\":" + clientId + "}"; + response = execute(HttpPost.METHOD_NAME, uri, + new StringEntity(jsdata, ContentType.APPLICATION_JSON)); + + if (response == null || response.getStatusLine() == null) { + return noResponseStatus(); + } + + int status = response.getStatusLine().getStatusCode(); + if (status != HttpStatus.SC_OK + && status != HttpStatus.SC_CREATED + && status != HttpStatus.SC_ACCEPTED + && status != HttpStatus.SC_NO_CONTENT ) { +// String reason = response.getStatusLine().getReasonPhrase(); + String reason = new String(ByteStreams.toByteArray(response.getEntity().getContent())); + s_logger.error("sync request failed: " + reason); + if (status != HttpStatus.SC_NOT_FOUND) { + s_logger.error("Failure message: " + getResponseData(response)); + } + checkResponseKeepAliveStatus(response); + return Status.failure(reason); + } + + return Status.success(); + } + + @Override + public void dispose() { + try { + if (_connection.isOpen()) { + _connection.close(); // close server connection + } + } catch (IOException ex) { + s_logger.warn("Exception while closing server connection: " + ex.getMessage()); + } + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorMock.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorMock.java new file mode 100644 index 00000000000..8278226c4c9 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiConnectorMock.java @@ -0,0 +1,734 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +package org.zstack.sugonSdnController.controller.api; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.Iterator; +import java.util.Random; +import java.lang.reflect.Field; +import java.io.ObjectInputStream; +import java.io.InputStream; +import org.zstack.sugonSdnController.controller.api.types.VirtualMachine; +import org.zstack.sugonSdnController.controller.api.types.VirtualMachineInterface; +import org.zstack.sugonSdnController.controller.api.types.MacAddressesType; +import org.zstack.sugonSdnController.controller.api.types.VirtualNetwork; +import org.zstack.sugonSdnController.controller.api.types.NetworkPolicy; +import org.zstack.sugonSdnController.controller.api.types.Project; +import org.zstack.sugonSdnController.controller.api.types.Domain; +import org.zstack.sugonSdnController.controller.api.types.SecurityGroup; +import org.zstack.sugonSdnController.controller.api.types.InstanceIp; +import org.zstack.sugonSdnController.controller.api.types.FloatingIp; +import org.zstack.sugonSdnController.controller.api.types.FloatingIpPool; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.RandomStringUtils; +import com.google.common.net.InetAddresses; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class ApiConnectorMock implements ApiConnector { + private static final CLogger s_logger = + Utils.getLogger(ApiConnector.class); + + private ApiBuilder _apiBuilder; + private HashMap>> _map; + private static final HashMap, Class> _parentMap; + static { + HashMap, Class> parentMap = new HashMap, Class>(); + parentMap.put(Domain.class, Domain.class); + parentMap.put(Project.class, Domain.class); + parentMap.put(VirtualNetwork.class, Project.class); + parentMap.put(VirtualMachineInterface.class, VirtualMachine.class); + parentMap.put(NetworkPolicy.class, Project.class); + parentMap.put(SecurityGroup.class, Project.class); + parentMap.put(FloatingIp.class, FloatingIpPool.class); + parentMap.put(FloatingIpPool.class, VirtualNetwork.class); + _parentMap = parentMap; + } + + private static void assignAutoProperty(ApiObjectBase obj) { + if (obj.getClass() == VirtualMachineInterface.class) { + if (((VirtualMachineInterface)obj).getMacAddresses() != null) { + return; + } + String addr = RandomStringUtils.random(17, false, true); + char[] charArray = addr.toCharArray(); + charArray[2] = charArray[5] = charArray[5] = ':'; + charArray[8] = charArray[11] = charArray[14] = ':'; + addr = new String(charArray); + + MacAddressesType macs = new MacAddressesType(); + macs.addMacAddress(addr); + s_logger.debug("Assigned auto property mac address : " + addr); + ((VirtualMachineInterface)obj).setMacAddresses(macs); + } else if (obj.getClass() == InstanceIp.class) { + if (((InstanceIp)obj).getAddress() != null) { + return; + } + Random random = new Random(); + String ipString = InetAddresses.fromInteger(random.nextInt()).getHostAddress(); + s_logger.debug("Assigned auto property ip address : " + ipString); + ((InstanceIp)obj).setAddress(ipString); + } + } + + private static Class getVncClass(String clsname) { + String typename = new String(); + for (int i = 0; i < clsname.length(); i++) { + char ch = clsname.charAt(i); + if (i == 0) { + ch = Character.toUpperCase(ch); + } else if (ch == '_') { + ch = clsname.charAt(++i); + ch = Character.toUpperCase(ch); + } + typename += ch; + } + try { + Class cls = (Class)Class.forName("net.juniper.contrail.api.types." + typename); + return cls; + } catch (Exception e) { + s_logger.debug("Class not found " + e); + } + return null; + } + + private static HashMap, ApiObjectBase> _defaultObjectMap; + + ApiConnectorMock() { + _apiBuilder = new ApiBuilder(); + initConfig(); + } + + public ApiConnectorMock(String hostname, int port) { + this(); + } + + public void initConfig() { + _map = new HashMap>>(); + buildDefaultConfig(); + buildDefaultObjectMap(); + } + + void buildDefaultConfig() { + try { + InputStream fin = getClass().getResourceAsStream("/default_config"); + ObjectInputStream ois = new ObjectInputStream(fin); + HashMap, List>> defaultConfigMap = (HashMap, List>>) ois.readObject(); + Iterator it = defaultConfigMap.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pairs = (Map.Entry)it.next(); + Class cls = (Class)pairs.getKey(); + s_logger.debug("buildDefaultConfig: " + _apiBuilder.getTypename(cls)); + _map.put(_apiBuilder.getTypename(cls), (List>)pairs.getValue()); + } + } catch (Exception e) { + s_logger.debug("buildDefaultConfig: " + e); + } + } + + void buildDefaultObjectMap() { + _defaultObjectMap = new HashMap, ApiObjectBase>(); + try { + _defaultObjectMap.put(Domain.class, findByFQN(Domain.class, "default-domain")); + _defaultObjectMap.put(Project.class, findByFQN(Project.class, "default-domain:default-project")); + } catch (Exception e) { + s_logger.debug(e.getMessage()); + } + } + + List getClassData(Class cls) { + final String typename = _apiBuilder.getTypename(cls); + return _map.get(typename); + } + + void setClassData(Class cls, List clsData) { + final String typename = _apiBuilder.getTypename(cls); + _map.put(typename, clsData); + } + + HashMap getFqnMap(List clsData) { + if (clsData != null) { + return (HashMap)clsData.get(1); + } + return null; + } + + HashMap getUuidMap(List clsData) { + if (clsData != null) { + return (HashMap)clsData.get(0); + } + return null; + } + + private String getFqnString(List name_list) { + return StringUtils.join(name_list, ':'); + } + + private boolean validate(ApiObjectBase obj) throws IOException { + String uuid = obj.getUuid(); + if (uuid == null) { + uuid = UUID.randomUUID().toString(); + obj.setUuid(uuid); + } + String fqn = getFqnString(obj.getQualifiedName()); + List clsData = getClassData(obj.getClass()); + HashMap uuidMap = null; + HashMap fqnMap = null; + if (clsData != null) { + uuidMap = getUuidMap(clsData); + fqnMap = getFqnMap(clsData); + if (uuidMap.get(uuid) != null || fqnMap.get(fqn) != null) { + s_logger.warn("api object: " + obj.getName() + " already exists"); + return false; + } + } + //check for parent child references and backrefs + ApiObjectBase parent = obj.getParent(); + if (parent == null) { + parent = getDefaultParent(obj); + } + if (parent != null) { + try { + s_logger.debug("Verify establish parent(" + _apiBuilder.getTypename(parent.getClass()) + ", " + parent.getName() + + ") => child (" + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName()); + /* update parent object with new child info */ + updateObjectVerify(parent, obj, getRefname(obj.getClass()) + "s"); + /* update child object back reference to its parent */ + s_logger.debug("Verify Establish child(" + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName() + + ") => backref to parent(" + _apiBuilder.getTypename(parent.getClass()) + ", " + parent.getName() + ")"); + } catch (Exception e) { + s_logger.debug("Exception in updateObject : " + e); + return false; + } + } else { + s_logger.debug("no default parent for : " + obj.getName()); + } + try { + /* update object references it has with associated back refs */ + updateRefsVerify(obj); + } catch (Exception e) { + return false; + } + return true; + } + + @Override + public ApiConnector credentials(String username, String password) { + return this; + } + @Override + public ApiConnector tenantName(String tenant) { + return this; + } + @Override + public ApiConnector authToken(String token) { + return this; + } + @Override + public ApiConnector authServer(String type, String url) { + return this; + } + @Override + public synchronized Status create(ApiObjectBase obj) throws IOException { + s_logger.debug("create(cls, obj): " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName()); + if (!validate(obj)) { + s_logger.error("can not create (cls, obj): " + _apiBuilder.getTypename(obj.getClass()) + ", " + + obj.getName() + ", validate failed"); + return Status.failure("Validation failed"); + } + String uuid = obj.getUuid(); + if (uuid == null) { + uuid = UUID.randomUUID().toString(); + obj.setUuid(uuid); + } + String fqn = getFqnString(obj.getQualifiedName()); + List clsData = getClassData(obj.getClass()); + HashMap uuidMap = null; + HashMap fqnMap = null; + if (clsData == null) { + clsData = new ArrayList>(); + uuidMap = new HashMap(); + fqnMap = new HashMap(); + clsData.add(uuidMap); + clsData.add(fqnMap); + setClassData(obj.getClass(), clsData); + } else { + uuidMap = getUuidMap(clsData); + fqnMap = getFqnMap(clsData); + } + if (uuidMap.get(uuid) != null || fqnMap.get(fqn) != null) { + s_logger.warn("api object: " + obj.getName() + " already exists"); + return Status.failure("Object already exists"); + } + uuidMap.put(uuid, obj); + fqnMap.put(fqn, obj); + + //update parent child references and backrefs + ApiObjectBase parent = obj.getParent(); + if (parent == null) { + parent = getDefaultParent(obj); + } + if (parent != null) { + try { + s_logger.debug("Establish parent(" + _apiBuilder.getTypename(parent.getClass()) + ", " + parent.getName() + + ") => child (" + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName() + ")"); + /* update parent object with new child info */ + updateObject(parent, obj, getRefname(obj.getClass()) + "s"); + obj.setParent(parent); + } catch (Exception e) { + s_logger.debug("Exception in updateObject : " + e); + } + } else { + s_logger.debug("no default parent for : " + obj.getName()); + } + /* update object references it has with associated back refs */ + updateRefs(obj); + /* assign auto property, if any */ + assignAutoProperty(obj); + return Status.success(); + } + + ApiObjectBase getDefaultParent(ApiObjectBase obj) { + if (obj.getClass() == Domain.class) { + return null; + } + if (obj.getName().equals("default-domain")) return null; + Class parentCls = _parentMap.get(obj.getClass()); + return _defaultObjectMap.get(parentCls); + } + + @Override + public synchronized Status commitDrafts(ApiObjectBase obj) throws IOException { + s_logger.debug("commit drafts: " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getUuid()); + return Status.success(); + } + + @Override + public synchronized Status discardDrafts(ApiObjectBase obj) throws IOException { + s_logger.debug("discard drafts: " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getUuid()); + return Status.success(); + } + + @Override + public synchronized Status update(ApiObjectBase obj) throws IOException { + s_logger.debug("update(cls, obj): " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName()); + String fqn = getFqnString(obj.getQualifiedName()); + if (fqn == null) { + return Status.failure("Object does not have qualified name."); + } + List clsData = getClassData(obj.getClass()); + if (clsData == null) { + return Status.failure("No class data."); + } + HashMap uuidMap = getUuidMap(clsData); + HashMap fqnMap = getFqnMap(clsData); + ApiObjectBase old = fqnMap.get(fqn); + String uuid = old.getUuid(); + fqnMap.put(fqn, obj); + uuidMap.put(uuid, obj); + return Status.success(); + } + + @Override + public synchronized Status read(ApiObjectBase obj) throws IOException { + s_logger.debug("read(cls, obj): " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName()); + String fqn = getFqnString(obj.getQualifiedName()); + if (fqn == null) { + return Status.failure("Object does not have qualified name."); + } + List clsData = getClassData(obj.getClass()); + if (clsData == null) { + return Status.failure("No class data."); + } + HashMap fqnMap = getFqnMap(clsData); + if (fqnMap == null || fqnMap.get(fqn) == null) { + return Status.failure("No qualified name."); + } + obj = fqnMap.get(fqn); + return Status.success(); + } + + @Override + public Status delete(ApiObjectBase obj) throws IOException { + s_logger.debug("delete(cls, obj): " + _apiBuilder.getTypename(obj.getClass()) + "," + obj.getName()); + if (isChildrenExists(obj)) { + s_logger.warn("children exist, can not delete"); + return Status.failure("Object already exists."); + } + String uuid = obj.getUuid(); + String fqn = getFqnString(obj.getQualifiedName()); + if (fqn == null || uuid == null) { + s_logger.debug("can not delete - no uuid/fqn"); + return Status.failure("UUID or FQN not specified."); + } + List clsData = getClassData(obj.getClass()); + if (clsData == null) { + s_logger.debug("can not delete - not exists"); + return Status.success(); + } + HashMap uuidMap = getUuidMap(clsData); + HashMap fqnMap = getFqnMap(clsData); + fqnMap.remove(fqn); + uuidMap.remove(uuid); + return Status.success(); + } + + @Override + public synchronized Status delete(Class cls, String uuid) throws IOException { + s_logger.debug("delete(cls, uuid): " + _apiBuilder.getTypename(cls) + ", " + uuid); + List clsData = getClassData(cls); + if (clsData == null) { + s_logger.debug("can not delete - not exists"); + return Status.success(); + } + HashMap uuidMap = getUuidMap(clsData); + HashMap fqnMap = getFqnMap(clsData); + + ApiObjectBase obj = uuidMap.get(uuid); + if (obj != null && isChildrenExists(obj)) { + String reason = "Cannot delete object having children."; + s_logger.warn(reason); + return Status.failure(reason); + } + uuidMap.remove(uuid); + if (obj != null) { + fqnMap.remove(getFqnString(obj.getQualifiedName())); + } + return Status.success(); + } + + @Override + public synchronized ApiObjectBase find(Class cls, ApiObjectBase parent, String name) throws IOException { + s_logger.debug("find(cls, parent, name) : " + _apiBuilder.getTypename(cls) + ", " + parent.getName() + ", " + name); + List clsData = getClassData(cls); + if (clsData == null) { + s_logger.debug("not found"); + return null; + } + String fqn = getFqnString(parent.getQualifiedName()) + ":" + name; + HashMap fqnMap = getFqnMap(clsData); + return fqnMap.get(fqn); + } + + @Override + public ApiObjectBase findByFQN(Class cls, String fullName) throws IOException { + s_logger.debug("findFQN(cls, fqn) : " + _apiBuilder.getTypename(cls) + ", " + fullName); + List clsData = getClassData(cls); + if (clsData == null) { + s_logger.debug("not found"); + return null; + } + HashMap fqnMap = getFqnMap(clsData); + return fqnMap.get(fullName); + } + + @Override + public synchronized ApiObjectBase findById(Class cls, String uuid) throws IOException { + s_logger.debug("findById(cls, uuid) : " + _apiBuilder.getTypename(cls) + ", " + uuid); + List clsData = getClassData(cls); + if (clsData == null) { + s_logger.debug("not found"); + return null; + } + HashMap uuidMap = getUuidMap(clsData); + return uuidMap.get(uuid); + } + + @Override + public String findByName(Class cls, ApiObjectBase parent, String name) throws IOException { + s_logger.debug("findByName(cls, parent, name) : " + _apiBuilder.getTypename(cls) + ", " + name); + List name_list = new ArrayList(); + if (parent != null) { + name_list.addAll(parent.getQualifiedName()); + } else { + try { + name_list.addAll(cls.newInstance().getDefaultParent()); + } catch (Exception e) { + s_logger.warn(e.getMessage()); + } + } + name_list.add(name); + return findByName(cls, name_list); + } + + @Override + // POST http://hostname:port/fqname-to-id + // body: {"type": class, "fq_name": [parent..., name]} + public synchronized String findByName(Class cls, List name_list) throws IOException { + String fqn = StringUtils.join(name_list, ':'); + s_logger.debug("findByName(cls, name_list) : " + _apiBuilder.getTypename(cls) + ", " + fqn); + List clsData = getClassData(cls); + if (clsData == null) { + s_logger.debug("cls not found"); + return null; + } + HashMap fqnMap = getFqnMap(clsData); + ApiObjectBase obj = fqnMap.get(fqn); + if (obj != null) { + return obj.getUuid(); + } + s_logger.debug("not found"); + return null; + } + + @Override + public synchronized List list(Class cls, List parent) throws IOException { + String fqnParent = null; + if (parent != null) { + fqnParent = StringUtils.join(parent, ':'); + s_logger.debug("list(cls, parent_name_list) : " + _apiBuilder.getTypename(cls) + ", " + fqnParent); + } else { + s_logger.debug("list(cls, parent_name_list) : " + _apiBuilder.getTypename(cls) + ", null"); + } + List clsData = getClassData(cls); + if (clsData == null) { + s_logger.debug("cls not found"); + return null; + } + HashMap fqnMap = getFqnMap(clsData); + ArrayList arr = new ArrayList(fqnMap.values()); + List list = new ArrayList(); + for (ApiObjectBase obj:arr) { + if (fqnParent != null && getFqnString(obj.getQualifiedName()).startsWith(fqnParent + ":")) { + list.add(obj); + } else { + list.add(obj); + } + } + return list; + } + + @Override + public List listWithDetail(Class cls, String fields, String filters) throws IOException { + return null; + } + + private boolean isChildrenExists(ApiObjectBase parent) { + String fqnParent = getFqnString(parent.getQualifiedName()); + ArrayList>> clsDataList = new ArrayList>>(_map.values()); + for (List> clsData:clsDataList) { + HashMap fqnMap = getFqnMap(clsData); + ArrayList arr = new ArrayList(fqnMap.values()); + List list = new ArrayList(); + for (ApiObjectBase obj:arr) { + if (getFqnString(obj.getQualifiedName()).startsWith(fqnParent + ":")) { + if (obj.getParent() == parent) { + return true; + } + } + } + } + return false; + } + + @Override + public List + getObjects(Class cls, List> refList) throws IOException { + s_logger.debug("getObjects(cls, refList): " + _apiBuilder.getTypename(cls)); + List list = new ArrayList(); + for (ObjectReference ref : refList) { + ApiObjectBase obj = findById(cls, ref.getUuid()); + if (obj == null) { + s_logger.warn("Unable to find element with uuid: " + ref.getUuid()); + continue; + } + list.add(obj); + } + return list; + } + + public String getRefname(Class cls) { + String clsname = cls.getName(); + int loc = clsname.lastIndexOf('.'); + if (loc > 0) { + clsname = clsname.substring(loc + 1); + } + String typename = new String(); + for (int i = 0; i < clsname.length(); i++) { + char ch = clsname.charAt(i); + if (Character.isUpperCase(ch)) { + if (i > 0) { + typename += "_"; + } + ch = Character.toLowerCase(ch); + } + typename += ch; + } + return typename; + } + + private void updateRefsVerify(ApiObjectBase obj) throws IOException { + Class cls = obj.getClass(); + s_logger.debug("updateRefsVerify: " + obj.getName() + ", class: " + _apiBuilder.getTypename(cls)); + for (Field f : cls.getDeclaredFields()) { + f.setAccessible(true); + if (!f.getName().endsWith("_refs") || f.getName().endsWith("_back_refs")) { + continue; + } + List> nv; + try { + nv = (List>)f.get(obj); + } catch (Exception ex) { + s_logger.warn("Unable to read value for " + f.getName() + ": " + ex.getMessage()); + throw new IOException("Unable to read value for " + f.getName() + ": " + ex.getMessage()); + } + + if (nv == null || nv.isEmpty()) { + continue; + } + + String refName = f.getName().substring(0, f.getName().lastIndexOf("_refs")); + Class refCls = getVncClass(refName); + for (ObjectReference ref: nv) { + String uuid = findByName(refCls, ref.getReferredName()); + ApiObjectBase refObj = findById(refCls, uuid); + if (refObj == null) { + s_logger.debug("Can not find obj for class: " + _apiBuilder.getTypename(refCls) + + ", uuid: " + ref.getUuid() +" , href: " + ref.getHRef()); + throw new IOException("Obj " + obj.getName() + " has a reference of type<" + _apiBuilder.getTypename(refCls) + ", but object does not exist"); + } + s_logger.debug("Verify establish backref on(cls, obj) : " + _apiBuilder.getTypename(refCls) + " => " + refObj.getName() + " with ref(cls, obj): " + _apiBuilder.getTypename(cls) + ", " + obj.getName()); + updateObjectVerify(refObj, obj, getRefname(obj.getClass()) + "_back_refs"); + } + } + return; + } + private void updateRefs(ApiObjectBase obj) throws IOException { + Class cls = obj.getClass(); + s_logger.debug("updateRefs: " + obj.getName() + ", class: " + _apiBuilder.getTypename(cls)); + for (Field f : cls.getDeclaredFields()) { + f.setAccessible(true); + if (!f.getName().endsWith("_refs") || f.getName().endsWith("_back_refs")) { + continue; + } + List> nv; + try { + nv = (List>)f.get(obj); + } catch (Exception ex) { + s_logger.warn("Unable to read value for " + f.getName() + ": " + ex.getMessage()); + continue; + } + + if (nv == null || nv.isEmpty()) { + s_logger.debug("no refs of type: " + f.getName()); + continue; + } + + String refName = f.getName().substring(0, f.getName().lastIndexOf("_refs")); + s_logger.debug("ref name: " + refName); + Class refCls = getVncClass(refName); + for (ObjectReference ref: nv) { + String uuid = findByName(refCls, ref.getReferredName()); + updateField(ref, "uuid", uuid); + ApiObjectBase refObj = findById(refCls, uuid); + if (refObj == null) { + s_logger.debug("Can not find obj for class: " + _apiBuilder.getTypename(refCls) + + ", uuid: " + ref.getUuid() +" , href: " + ref.getHRef()); + throw new IOException("Obj " + obj.getName() + " has a reference of type<" + _apiBuilder.getTypename(refCls) + ", but object does not exist"); + } + s_logger.debug("Establish backref on(cls, obj) : " + _apiBuilder.getTypename(refCls) + " => " + refObj.getName() + " with ref(cls, obj): " + _apiBuilder.getTypename(cls) + ", " + obj.getName()); + updateObject(refObj, obj, getRefname(obj.getClass()) + "_back_refs"); + } + } + return; + } + + private void updateField(ObjectReference obj, String fieldName, String value) + { + Class cls = obj.getClass(); + + Field field = null; + try { + field = cls.getDeclaredField(fieldName); + field.setAccessible(true); + } catch (Exception e) { + s_logger.debug("no field " + fieldName + ", \n" + e); + return; + } + try { + field.set(obj, value); + } catch (Exception ex) { + s_logger.warn("Unable to set " + field.getName() + ": " + ex.getMessage()); + } + s_logger.debug("Updated " + fieldName + " to " + value + " \n" ); + } + private void updateObjectVerify(ApiObjectBase obj, ApiObjectBase other, String fieldName) throws IOException { + s_logger.debug("updateObjectVerify(cls, obj, other-cls, other, field): " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName() + "," + _apiBuilder.getTypename(other.getClass()) + ", " + other.getName() + "," + fieldName); + Class cls = obj.getClass(); + + Field fRefs = null; + try { + fRefs = cls.getDeclaredField(fieldName); + fRefs.setAccessible(true); + } catch (Exception e) { + s_logger.debug("no field " + fieldName + ", \n" + e); + throw new IOException("no field " + fieldName + ", \n" + e); + } + List> nv; + try { + nv = (List>)fRefs.get(obj); + } catch (Exception ex) { + s_logger.warn("Unable to read new value for " + fRefs.getName() + ": " + ex.getMessage()); + throw new IOException("Unable to read new value for " + fRefs.getName() + ": " + ex.getMessage()); + } + return; + } + + private void updateObject(ApiObjectBase obj, ApiObjectBase other, String fieldName) throws IOException { + s_logger.debug("updateObject(cls, obj, other-cls, other, field): " + _apiBuilder.getTypename(obj.getClass()) + ", " + obj.getName() + "," + _apiBuilder.getTypename(other.getClass()) + ", " + other.getName() + "," + fieldName); + Class cls = obj.getClass(); + + Field fRefs = null; + try { + fRefs = cls.getDeclaredField(fieldName); + fRefs.setAccessible(true); + } catch (Exception e) { + s_logger.debug("no field " + fieldName + ", \n" + e); + return; + } + List> nv; + try { + nv = (List>)fRefs.get(obj); + } catch (Exception ex) { + s_logger.warn("Unable to read new value for " + fRefs.getName() + ": " + ex.getMessage()); + return; + } + + if (nv == null) { + nv = new ArrayList>(); + } + + String href = "http://localhost:8082/" + _apiBuilder.getTypename(other.getClass()) + '/' + other.getUuid(); + ObjectReference objRef = new ObjectReference(other.getQualifiedName(), null, href, other.getUuid()); + nv.add(objRef); + try { + fRefs.set(obj, nv); + } catch (Exception ex) { + s_logger.warn("Unable to set " + fRefs.getName() + ": " + ex.getMessage()); + } + } + + public void dumpConfig(Class cls) throws Exception { + List list = list(cls, null); + for (ApiObjectBase obj:list) { + s_logger.debug("Class : " + _apiBuilder.getTypename(cls) + ", name: " + obj.getName()); + } + } + + @Override + public Status sync(String uri) throws IOException { + return Status.success(); + } + + @Override + public void dispose() { + } +} + diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiObjectBase.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiObjectBase.java new file mode 100644 index 00000000000..727b33d1c99 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiObjectBase.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ +package org.zstack.sugonSdnController.controller.api; + +import java.util.ArrayList; +import java.util.List; +import java.io.Serializable; + +public abstract class ApiObjectBase implements Serializable { + private String name; + private String uuid; + private List fq_name; + private transient ApiObjectBase parent; + private String parent_type; + private String parent_uuid; + + public String getName() { + if (name == null && fq_name != null) { + name = fq_name.get(fq_name.size() - 1); + } + return name; + } + + /** + * Retrieves a parent object that may be cached in the object due to a setParent operation. + * + * @return parent + */ + public ApiObjectBase getParent() { + return parent; + } + + protected void setParent(ApiObjectBase parent) { + this.parent = parent; + this.fq_name = null; + if (parent != null) { + parent_type = parent.getObjectType(); + parent_uuid = parent.getUuid(); + } else { + parent_type = null; + parent_uuid = null; + } + } + + public void setName(String name) { + this.name = name; + if (fq_name != null) { + fq_name.set(fq_name.size() - 1, name); + } + } + + public String getUuid() { + return uuid; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getParentUuid() { + return parent_uuid; + } + + public String getParentType() { + return parent_type; + } + + protected void updateQualifiedName() { + if (fq_name == null) { + List parent_qn; + if (parent != null) { + parent_qn = parent.getQualifiedName(); + parent_type = parent.getObjectType(); + } else { + parent_qn = getDefaultParent(); + parent_type = getDefaultParentType(); + if (parent_qn == null) + throw new IllegalStateException("Parent of type " + getClass().getSimpleName() + " has to be specified explicitly."); + } + parent_qn.add(name); + fq_name = parent_qn; + } + } + + public List getQualifiedName() { + if ("config-root".equals(getObjectType())) + return new ArrayList(); + + updateQualifiedName(); + return new ArrayList(fq_name); + } + + public abstract String getObjectType(); + public abstract List getDefaultParent(); + public abstract String getDefaultParentType(); +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiPropertyBase.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiPropertyBase.java new file mode 100644 index 00000000000..d869f272fcd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiPropertyBase.java @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ +package org.zstack.sugonSdnController.controller.api; + +public abstract class ApiPropertyBase { + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiSerializer.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiSerializer.java new file mode 100644 index 00000000000..295e63a8e64 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ApiSerializer.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +package org.zstack.sugonSdnController.controller.api; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonNull; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.TypeAdapter; +import com.google.gson.TypeAdapterFactory; +import com.google.gson.internal.bind.TypeAdapters; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.math.BigInteger; + +public class ApiSerializer { + private static class ReferenceSerializer implements JsonSerializer> { + @Override + public JsonElement serialize(ObjectReference objref, Type type, + JsonSerializationContext context) { + JsonObject obj = new JsonObject(); + obj.add("to", context.serialize(objref.getReferredName())); + JsonElement js_attr; + if (objref.getAttr() == null) { + js_attr = JsonNull.INSTANCE; + } else { + js_attr = context.serialize(objref.getAttr()); + } + obj.add("attr", js_attr); + if (objref.getUuid() != null) { + obj.addProperty("uuid", objref.getUuid()); + } + return obj; + } + } + + private static class NullWritingTypeAdapterFactory implements TypeAdapterFactory { + @Override public TypeAdapter create(Gson gson, TypeToken type) { + if(type.getRawType() != ObjectReference.class) + return null; + final TypeAdapter delegate = gson.getDelegateAdapter(this, type); + return new TypeAdapter() { + @Override + public void write(JsonWriter out, T value) throws IOException { + boolean writeNulls = out.getSerializeNulls(); + out.setSerializeNulls(true); + delegate.write(out, value); + out.setSerializeNulls(writeNulls); + } + + @Override + public T read(JsonReader in) throws IOException { + return delegate.read(in); + } + }; + } + } + + private static final TypeAdapter UNSIGNED_LONG = new UnsignedLongAdapter(); + + private static class UnsignedLongAdapter extends TypeAdapter { + private final static BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); + private final static BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE); + private final static BigInteger MAX_UNSIGNED = MAX_LONG.subtract(MIN_LONG); + + @Override + public Number read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + + BigInteger value = new BigInteger(in.nextString()); + + if(value.compareTo(MAX_UNSIGNED) > 0 || value.compareTo(BigInteger.ZERO) < 0) + return value; + + if(value.compareTo(MAX_LONG) > 0) { + BigInteger overflow = value.subtract(MAX_LONG); + return MIN_LONG.add(overflow.subtract(BigInteger.ONE)).longValue(); + } else { + return value.longValue(); + } + } + + @Override + public void write(JsonWriter out, Number value) throws IOException { + if(value instanceof Long) { + long l = value.longValue(); + if(l >= 0L) { + out.value(value); + } else { + BigInteger bi = BigInteger.valueOf(l); + BigInteger overflow = bi.subtract(MIN_LONG); + BigInteger unsigned = MAX_LONG.add(overflow).add(BigInteger.ONE); + out.value(unsigned); + } + } + else { + out.value(value); + } + } + } + + static Gson getDeserializer() { + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapterFactory(TypeAdapters.newFactory(long.class, Long.class, UNSIGNED_LONG)); + // Do not attempt to deserialize ApiObjectBase.parent + return builder.excludeFieldsWithModifiers(Modifier.VOLATILE).setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").create(); + } + + static Gson getSerializer() { + GsonBuilder builder = new GsonBuilder(); + builder.registerTypeAdapter(ObjectReference.class, new ReferenceSerializer()); + builder.registerTypeAdapterFactory(new NullWritingTypeAdapterFactory()); + builder.registerTypeAdapterFactory(TypeAdapters.newFactory(long.class, Long.class, UNSIGNED_LONG)); + return builder.create(); + } + + static ApiObjectBase deserialize(String str, Class cls) { + Gson json = getDeserializer(); + return json.fromJson(str, cls); + } + + static String serializeObject(String typename, ApiObjectBase obj) { + Gson json = getSerializer(); + obj.updateQualifiedName(); + if (obj instanceof VRouterApiObjectBase) { + JsonElement el = json.toJsonTree(obj); + return el.toString(); + } + JsonObject js_dict = new JsonObject(); + js_dict.add(typename, json.toJsonTree(obj)); + + return js_dict.toString(); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/DisablePort.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/DisablePort.java new file mode 100644 index 00000000000..99fe37e72cc --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/DisablePort.java @@ -0,0 +1,55 @@ +package org.zstack.sugonSdnController.controller.api; + +import java.util.List; +import com.google.common.collect.Lists; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("serial") +public class DisablePort extends VRouterApiObjectBase { + + private static final String NONE = "None"; + + @SerializedName("id") private String id = NONE; // VMI id + private String display_name = NONE; // VM display name + private String system_name = NONE; // tap interface name, required + + @Override + public String getObjectType() { + return "Disable-port"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDisplay_name() { + return display_name; + } + + public void setDisplay_name(String display_name) { + this.display_name = display_name; + } + + public String getSystem_name() { + return system_name; + } + + public void setSystem_name(String system_name) { + this.system_name = system_name; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/EnablePort.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/EnablePort.java new file mode 100644 index 00000000000..0e8122d75c6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/EnablePort.java @@ -0,0 +1,55 @@ +package org.zstack.sugonSdnController.controller.api; + +import java.util.List; +import com.google.common.collect.Lists; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("serial") +public class EnablePort extends VRouterApiObjectBase { + + private static final String NONE = "None"; + + @SerializedName("id") private String id = NONE; // VMI id + private String display_name = NONE; // VM display name + private String system_name = NONE; // tap interface name, required + + @Override + public String getObjectType() { + return "enable-port"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDisplay_name() { + return display_name; + } + + public void setDisplay_name(String display_name) { + this.display_name = display_name; + } + + public String getSystem_name() { + return system_name; + } + + public void setSystem_name(String system_name) { + this.system_name = system_name; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ObjectReference.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ObjectReference.java new file mode 100644 index 00000000000..d4c51ca2a18 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/ObjectReference.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ +package org.zstack.sugonSdnController.controller.api; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.io.Serializable; + +public class ObjectReference implements Serializable { + private final List to; + private final AttrType attr; + private final String href; + private final String uuid; + + public ObjectReference(List to, AttrType attr) { + this(to, attr, null, null); + } + public ObjectReference(String uuid) { + this(null, null, null, uuid); + } + public ObjectReference(List to, AttrType attr, String href, String uuid) { + this.to = Collections.unmodifiableList(new ArrayList(to)); + this.attr = attr; + this.href = href; + this.uuid = uuid; + } + public String getHRef() { + return href; + } + public String getUuid() { + return uuid; + } + public List getReferredName() { + return to; + } + public AttrType getAttr() { + return attr; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ObjectReference)) return false; + + ObjectReference that = (ObjectReference) o; + + if (to != null && that.to != null) + return to.equals(that.to); + return uuid != null ? uuid.equals(that.uuid) : that.uuid == null; + } + + @Override + public int hashCode() { + int result = to != null ? to.hashCode() : 0; + result = 31 * result + (uuid != null ? uuid.hashCode() : 0); + return result; + } + + public static String getReferenceListUuid(List> reflist) { + if (reflist != null && !reflist.isEmpty()) { + ObjectReference ref = reflist.get(0); + return ref.getUuid(); + } + return null; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Port.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Port.java new file mode 100644 index 00000000000..63facfebf12 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Port.java @@ -0,0 +1,134 @@ +package org.zstack.sugonSdnController.controller.api; + +import java.util.List; +import com.google.common.collect.Lists; +import com.google.gson.annotations.SerializedName; + +@SuppressWarnings("serial") +public class Port extends VRouterApiObjectBase { + + private static final String NONE = "None"; + + @SerializedName("id") private String id = NONE; // VMI id + @SerializedName("instance-id") private String instance_id = NONE ; // VM id + @SerializedName("display-name") private String display_name = NONE; // VM display name + @SerializedName("vn-id") private String vn_id = NONE; // VN id + @SerializedName("ip-address") private String ip_address = NONE; + @SerializedName("mac-address") private String mac_address = NONE; + @SerializedName("vm-project-id") private String vm_project_id = NONE; + @SerializedName("rx-vlan-id") private short rx_vlan_id = -1; + @SerializedName("tx-vlan-id") private short tx_vlan_id = -1; + @SerializedName("system-name") private String system_name = NONE; // tap interface name, required + @SerializedName("type") private int type = 2; // must be set to 2 for Vcenter port + @SerializedName("ip6-address") private String ip6_address = NONE; + + @Override + public String getObjectType() { + return "port"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getInstance_id() { + return instance_id; + } + + public void setInstance_id(String instance_id) { + this.instance_id = instance_id; + } + + public String getDisplay_name() { + return display_name; + } + + public void setDisplay_name(String display_name) { + this.display_name = display_name; + } + + public String getVn_id() { + return vn_id; + } + + public void setVn_id(String vn_id) { + this.vn_id = vn_id; + } + + public String getIp_address() { + return ip_address; + } + + public void setIp_address(String ip_address) { + this.ip_address = ip_address; + } + public String getMac_address() { + return mac_address; + } + + public void setMac_address(String mac_address) { + this.mac_address = mac_address; + } + public String getVm_project_id() { + return vm_project_id; + } + + public void setVm_project_id(String vm_project_id) { + this.vm_project_id = vm_project_id; + } + + public short getRx_vlan_id() { + return rx_vlan_id; + } + + public void setRx_vlan_id(short rx_vlan_id) { + this.rx_vlan_id = rx_vlan_id; + } + + public short getTx_vlan_id() { + return tx_vlan_id; + } + + public void setTx_vlan_id(short tx_vlan_id) { + this.tx_vlan_id = tx_vlan_id; + } + + public String getSystem_name() { + return system_name; + } + + public void setSystem_name(String system_name) { + this.system_name = system_name; + } + + public String getIp6_address() { + return ip6_address; + } + + public void setIp6_address(String ip6_address) { + this.ip6_address = ip6_address; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java new file mode 100644 index 00000000000..fc460e3c5ca --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/Status.java @@ -0,0 +1,66 @@ +package org.zstack.sugonSdnController.controller.api; + +public abstract class Status { + private Status() { + } + + public abstract boolean isSuccess(); + public abstract void ifFailure(ErrorHandler handler); + public abstract String getMsg(); + + private final static Status success = new Success(); + + public static Status success() { + return success; + } + + public static Status failure(String message) { + return new Failure(message); + } + + private static class Success extends Status { + @Override + public boolean isSuccess() { + return true; + } + + @Override + public void ifFailure(ErrorHandler handler) { + // do nothing + } + + @Override + public String getMsg() { + // do nothing + return "success"; + } + + } + + private static class Failure extends Status { + private final String message; + + private Failure(String message) { + this.message = message; + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public void ifFailure(ErrorHandler handler) { + handler.handle(message); + } + + @Override + public String getMsg() { + return message; + } + } + + public interface ErrorHandler { + void handle(String errorMessage); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/TfCommands.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/TfCommands.java new file mode 100644 index 00000000000..849c26f4059 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/TfCommands.java @@ -0,0 +1,48 @@ +package org.zstack.sugonSdnController.controller.api; + +import org.zstack.utils.gson.JSONObjectUtil; + +import java.util.ArrayList; +import java.util.List; + +public class TfCommands { + public static final String TF_GET_DAEMON = "/fqname-to-id"; + public static final String TF_GET_DAEMON_DETAIL = "/domain/.*"; + public static final String TF_GET_PROJECT = "/project/.*"; + public static final String TF_CREATE_PROJECT = "/projects"; + public static final String TF_GET_NETWORK = "/virtual-network/.*"; + public static final String TF_CREATE_NETWORK = "/virtual-networks"; + public static final String TF_GET_VM = "/virtual-machine/.*"; + public static final String TF_CREATE_VM = "/virtual-machines"; + public static final String TF_GET_VMI = "/virtual-machine-interface/.*"; + public static final String TF_CREATE_VMI = "/virtual-machine-interfaces"; + public static final String TEST_DOMAIN_UUID = "cf8107ad-eee6-4a54-be5e-c05c96a9d552"; + public static final String TEST_PROJECT_UUID = "36c27e8f-f05c-4780-bf6d-2fa65700f22e"; + public static final String TEST_L2_UUID = "1eca756e-b935-45ed-a2bc-a3ebba535f7f"; + public static final String TEST_VM_UUID = "35c27fde-7f67-4c78-b80a-56ae1eefcb5b"; + public static final String TEST_VMI_UUID = "a581ee83-f5a5-4755-bedf-8d51f235da52"; + + public static class TfCmd { + public String toString() { + return JSONObjectUtil.toJsonString(this); + } + } + + public static class TfRsp { + } + + public static class GetDomainCmd extends TfCmd { + public String type; + public List fq_name = new ArrayList<>(); + } + + public static class GetDomainRsp extends TfRsp { + public String uuid; + } + + public static class GetProjectCmd extends TfCmd { + public String uuid; + } + +} + diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/TfHttpClient.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/TfHttpClient.java new file mode 100644 index 00000000000..00ae9db4429 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/TfHttpClient.java @@ -0,0 +1,403 @@ +package org.zstack.sugonSdnController.controller.api; + +import com.google.common.collect.ImmutableList; +import com.google.gson.*; +import org.apache.commons.lang.StringUtils; +import org.springframework.http.*; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.web.util.UriComponentsBuilder; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.MessageCommandRecorder; +import org.zstack.header.rest.RESTFacade; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.SugonSdnControllerGlobalProperty; +import org.zstack.sugonSdnController.controller.api.types.Domain; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class TfHttpClient { + private static final CLogger logger = Utils.getLogger(TfHttpClient.class); + @Autowired + private RESTFacade restf; + private TimeUnit unit; + private Long timeout; + private String tf_ip; + private Map headers = new HashMap() { + { + put("Content-Type", "application/json; charset=UTF-8"); + } + }; + + public TfHttpClient(String ip) { + this.tf_ip = ip; + this.unit = TimeUnit.MILLISECONDS; + this.timeout = 30000l; + } + + public String getTypename(Class cls) { + String clsname = cls.getName(); + int loc = clsname.lastIndexOf('.'); + if (loc > 0) { + clsname = clsname.substring(loc + 1); + } + String typename = new String(); + for (int i = 0; i < clsname.length(); i++) { + char ch = clsname.charAt(i); + if (Character.isUpperCase(ch)) { + if (i > 0) { + typename += "-"; + } + ch = Character.toLowerCase(ch); + } + typename += ch; + } + return typename; + } + + public ApiObjectBase jsonToApiObject(String data, Class cls) { + if (data == null) { + return null; + } + final String typename = getTypename(cls); + final JsonParser parser = new JsonParser(); + final JsonObject js_obj = parser.parse(data).getAsJsonObject(); + if (js_obj == null) { + logger.warn("Unable to parse response"); + return null; + } + JsonElement element = null; + if (cls.getGenericSuperclass() == VRouterApiObjectBase.class) { + element = js_obj; + } else { + element = js_obj.get(typename); + } + if (element == null) { + logger.warn("Element " + typename + ": not found"); + return null; + } + ApiObjectBase resp = ApiSerializer.deserialize(element.toString(), cls); + return resp; + } + + public List jsonToApiObjects(String data, Class cls, boolean withDetail) { + if (data == null) { + return null; + } + final String typename = getTypename(cls); + List list = new ArrayList(); + final JsonParser parser = new JsonParser(); + final JsonObject js_obj= parser.parse(data).getAsJsonObject(); + if (js_obj == null) { + logger.warn("Unable to parse response"); + return null; + } + final JsonArray array = js_obj.getAsJsonArray(typename + "s"); + if (array == null) { + logger.warn("Element " + typename + ": not found"); + return null; + } + Gson json = ApiSerializer.getDeserializer(); + for (JsonElement element : array) { + ApiObjectBase obj; + if (withDetail) { + obj = jsonToApiObject(element.toString(), cls); + } else { + obj = json.fromJson(element.toString(), cls); + } + + if (obj == null) { + logger.warn("Unable to decode list element"); + continue; + } + list.add(obj); + } + return list; + } + + private String buildUrl(String ip, String path) { + UriComponentsBuilder ub = UriComponentsBuilder.newInstance(); + ub.scheme("http"); + if (CoreGlobalProperty.UNIT_TEST_ON) { + ub.host("localhost"); + ub.port(8989); + } else { + ub.host(ip); + ub.port(SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT); + } + + ub.path(path); + return ub.build().toUriString(); + } + + public String buildFqnJsonString(Class cls, List name_list) { + Gson json = new Gson(); + JsonObject js_dict = new JsonObject(); + js_dict.add("type", json.toJsonTree(getTypename(cls))); + js_dict.add("fq_name", json.toJsonTree(name_list)); + return js_dict.toString(); + } + + public String getUuid(String data) { + if (data == null) { + return null; + } + final JsonParser parser = new JsonParser(); + final JsonObject js_obj= parser.parse(data).getAsJsonObject(); + if (js_obj == null) { + logger.warn("Unable to parse response"); + return null; + } + final JsonElement element = js_obj.get("uuid"); + if (element == null) { + logger.warn("Element \"uuid\": not found"); + return null; + } + return element.getAsString(); + } + + private ResponseEntity execute(String url, HttpMethod method, String body) { + HttpHeaders requestHeaders = new HttpHeaders(); + if (headers != null) { + requestHeaders.setAll(headers); + } + requestHeaders.setContentType(MediaType.APPLICATION_JSON); + HttpEntity req = new HttpEntity(body, requestHeaders); + ResponseEntity response; + try { + response = restf.syncRawJson(buildUrl(tf_ip, url), req, method, unit, timeout); + } catch (Exception e){ + logger.warn(String.format("Execute http requests:%s failed, reason:%s", url, e.getMessage())); + return null; + } + + return response; + } + + public ApiObjectBase getDomain() { + TfCommands.GetDomainCmd getDomainCmd = new TfCommands.GetDomainCmd(); + getDomainCmd.type = getTypename(Domain.class); + List fqName = new ArrayList<>(); + fqName.add(SugonSdnControllerConstant.TF_DEFAULT_DOMAIN); + getDomainCmd.fq_name = fqName; + MessageCommandRecorder.record(getDomainCmd.getClass()); + String httpBody = JSONObjectUtil.toJsonString(getDomainCmd); + TfCommands.GetDomainRsp rsp = restf.syncJsonPost(buildUrl(tf_ip, TfCommands.TF_GET_DAEMON), httpBody, headers, TfCommands.GetDomainRsp.class, unit, timeout); + return findById(Domain.class, rsp.uuid); + } + + public synchronized ApiObjectBase findById(Class cls, String uuid) { + final String typename = getTypename(cls); + String url = String.format("/%s/%s", typename, uuid); + ResponseEntity response = execute(url, HttpMethod.GET, ""); + + if (response == null) { + return null; + } + + if (response.getStatusCode() != HttpStatus.OK) { + return null; + } + ApiObjectBase object = jsonToApiObject(response.getBody(), cls); + if (object == null) { + logger.warn("Unable to decode find response"); + } + + return object; + } + + public synchronized List listWithDetail(Class cls, + String fields, + String filters) { + final String typename = getTypename(cls); + String url = String.format("/%ss?detail=true", typename); + if (fields != null) { + url = url + "&fields=" + fields; + } + if (filters != null) { + url = url + "&filters=" + filters; + } + ResponseEntity response = execute(url, HttpMethod.GET, ""); + if (response == null) { + return null; + } + + if (response.getStatusCode() != HttpStatus.OK) { + logger.warn("list failed with :" + response.getBody()); + return null; + } + + String data = response.getBody(); + if (data == null) { + return null; + } + List list = jsonToApiObjects(data, cls, true); + if (list == null) { + logger.warn("Unable to parse/deserialize response: " + data); + } + return list; + } + + public List + getObjects(Class cls, List> refList) { + + List list = new ArrayList(); + for (ObjectReference ref : refList) { + ApiObjectBase obj = findById(cls, ref.getUuid()); + if (obj == null) { + logger.warn("Unable to find element with uuid: " + ref.getUuid()); + continue; + } + list.add(obj); + } + return list; + } + + public ApiObjectBase findByFQN(Class cls, String fullName) { + List fqn = ImmutableList.copyOf(StringUtils.split(fullName, ':')); + String uuid = findByName(cls, fqn); + if (uuid == null) { + return null; + } + return findById(cls, uuid); + } + + public synchronized String findByName(Class cls, List name_list) { + String jsonStr = buildFqnJsonString(cls, name_list); + ResponseEntity response = execute("/fqname-to-id", HttpMethod.POST, jsonStr); + + if (response == null) { + return null; + } + + if (response.getStatusCode() != HttpStatus.OK) { + return null; + } + + String data = response.getBody(); + if (data == null) { + return null; + } + logger.debug("<< Response Data: " + data); + + String uuid = getUuid(data); + if (uuid == null) { + logger.warn("Unable to parse response"); + return null; + } + return uuid; + } + + public synchronized Status create(ApiObjectBase obj) { + final String typename = getTypename(obj.getClass()); + final String jsdata = ApiSerializer.serializeObject(typename, obj); + String url; + + ResponseEntity response; + if (obj instanceof VRouterApiObjectBase) { + url = String.format("/%s", typename); + } else { + obj.updateQualifiedName(); + url = String.format("/%ss", typename); + } + response = execute(url, HttpMethod.POST, jsdata); + + if (response == null) { + return Status.failure("No response from API server."); + } + HttpStatus status = response.getStatusCode(); + if (status != HttpStatus.OK + && status != HttpStatus.CREATED + && status != HttpStatus.ACCEPTED ) { + + String reason = response.getBody(); + logger.error("create api request failed: " + reason); + if (status != HttpStatus.NOT_FOUND) { + logger.error("Failure message: " + reason); + } + return Status.failure(reason); + } + + ApiObjectBase resp = jsonToApiObject(response.getBody(), obj.getClass()); + if (resp == null) { + String reason = "Unable to decode Create response"; + logger.error(reason); + return Status.failure(reason); + } + + String uuid = obj.getUuid(); + if (uuid == null) { + obj.setUuid(resp.getUuid()); + } else if (!uuid.equals(resp.getUuid()) + && !(obj instanceof VRouterApiObjectBase)) { + logger.warn("Response contains unexpected uuid: " + resp.getUuid()); + return Status.success(); + } + logger.debug("Create " + typename + " uuid: " + obj.getUuid()); + return Status.success(); + } + + public synchronized Status update(ApiObjectBase obj) { + final String typename = getTypename(obj.getClass()); + final String jsdata = ApiSerializer.serializeObject(typename, obj); + String url = String.format("/%s/%s", typename, obj.getUuid()); + + ResponseEntity response = execute(url, HttpMethod.PUT, jsdata); + + if (response == null) { + return Status.failure("No response from API server."); + } + + HttpStatus status = response.getStatusCode(); + if (status != HttpStatus.OK + && status != HttpStatus.ACCEPTED ) { + String reason = response.getBody(); + logger.warn("<< Response:" + reason); + return Status.failure(reason); + } + + return Status.success(); + } + + public synchronized Status delete(Class cls, String uuid) { + if (findById(cls, uuid) == null) { + // object does not exist so we are ok + return Status.success(); + } + + final String typename = getTypename(cls); + String url = String.format("/%s/%s", typename, uuid); + ResponseEntity response = execute(url, HttpMethod.DELETE, ""); + + if (response == null) { + return Status.failure("No response from API server."); + } + + HttpStatus status = response.getStatusCode(); + if (status != HttpStatus.OK + && status != HttpStatus.NO_CONTENT + && status != HttpStatus.ACCEPTED ) { + String reason = response.getBody(); + logger.warn("Delete failed: " + reason); + if (status != HttpStatus.NOT_FOUND) { + logger.error("Failure message: " + response); + } + return Status.failure(reason); + } + return Status.success(); + } + + public Status delete(ApiObjectBase obj) throws IOException { + return delete(obj.getClass(), obj.getUuid()); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/VRouterApiObjectBase.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/VRouterApiObjectBase.java new file mode 100644 index 00000000000..8425683cdc6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/VRouterApiObjectBase.java @@ -0,0 +1,5 @@ +package org.zstack.sugonSdnController.controller.api; + +@SuppressWarnings("serial") +public abstract class VRouterApiObjectBase extends ApiObjectBase { +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AccessControlList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AccessControlList.java new file mode 100644 index 00000000000..6f84d9d0765 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AccessControlList.java @@ -0,0 +1,128 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AccessControlList extends ApiObjectBase { + private AclEntriesType access_control_list_entries; + private Long access_control_list_hash; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "access-control-list"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(VirtualNetwork parent) { + super.setParent(parent); + } + + public void setParent(SecurityGroup parent) { + super.setParent(parent); + } + + public AclEntriesType getEntries() { + return access_control_list_entries; + } + + public void setEntries(AclEntriesType access_control_list_entries) { + this.access_control_list_entries = access_control_list_entries; + } + + + public Long getHash() { + return access_control_list_hash; + } + + public void setHash(Long access_control_list_hash) { + this.access_control_list_hash = access_control_list_hash; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AclEntriesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AclEntriesType.java new file mode 100644 index 00000000000..b1b8a5961cc --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AclEntriesType.java @@ -0,0 +1,55 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AclEntriesType extends ApiPropertyBase { + Boolean dynamic; + List acl_rule; + public AclEntriesType() { + } + public AclEntriesType(Boolean dynamic, List acl_rule) { + this.dynamic = dynamic; + this.acl_rule = acl_rule; + } + public AclEntriesType(Boolean dynamic) { + this(dynamic, null); } + + public Boolean getDynamic() { + return dynamic; + } + + public void setDynamic(Boolean dynamic) { + this.dynamic = dynamic; + } + + + public List getAclRule() { + return acl_rule; + } + + + public void addAclRule(AclRuleType obj) { + if (acl_rule == null) { + acl_rule = new ArrayList(); + } + acl_rule.add(obj); + } + public void clearAclRule() { + acl_rule = null; + } + + + public void addAclRule(MatchConditionType match_condition, ActionListType action_list, String rule_uuid, String direction) { + if (acl_rule == null) { + acl_rule = new ArrayList(); + } + acl_rule.add(new AclRuleType(match_condition, action_list, rule_uuid, direction)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AclRuleType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AclRuleType.java new file mode 100644 index 00000000000..4ed3fd07ce3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AclRuleType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AclRuleType extends ApiPropertyBase { + MatchConditionType match_condition; + ActionListType action_list; + String rule_uuid; + String direction; + public AclRuleType() { + } + public AclRuleType(MatchConditionType match_condition, ActionListType action_list, String rule_uuid, String direction) { + this.match_condition = match_condition; + this.action_list = action_list; + this.rule_uuid = rule_uuid; + this.direction = direction; + } + public AclRuleType(MatchConditionType match_condition) { + this(match_condition, null, null, null); } + public AclRuleType(MatchConditionType match_condition, ActionListType action_list) { + this(match_condition, action_list, null, null); } + public AclRuleType(MatchConditionType match_condition, ActionListType action_list, String rule_uuid) { + this(match_condition, action_list, rule_uuid, null); } + + public MatchConditionType getMatchCondition() { + return match_condition; + } + + public void setMatchCondition(MatchConditionType match_condition) { + this.match_condition = match_condition; + } + + + public ActionListType getActionList() { + return action_list; + } + + public void setActionList(ActionListType action_list) { + this.action_list = action_list; + } + + + public String getRuleUuid() { + return rule_uuid; + } + + public void setRuleUuid(String rule_uuid) { + this.rule_uuid = rule_uuid; + } + + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ActionListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ActionListType.java new file mode 100644 index 00000000000..94931df7fc4 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ActionListType.java @@ -0,0 +1,151 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ActionListType extends ApiPropertyBase { + String simple_action; + String gateway_name; + List apply_service; + ServicePropertiesType service_properties; + MirrorActionType mirror_to; + String assign_routing_instance; + Boolean log; + Boolean alert; + String qos_action; + Boolean host_based_service; + public ActionListType() { + } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties, MirrorActionType mirror_to, String assign_routing_instance, Boolean log, Boolean alert, String qos_action, Boolean host_based_service) { + this.simple_action = simple_action; + this.gateway_name = gateway_name; + this.apply_service = apply_service; + this.service_properties = service_properties; + this.mirror_to = mirror_to; + this.assign_routing_instance = assign_routing_instance; + this.log = log; + this.alert = alert; + this.qos_action = qos_action; + this.host_based_service = host_based_service; + } + public ActionListType(String simple_action) { + this(simple_action, null, null, null, null, null, false, false, null, false); } + public ActionListType(String simple_action, String gateway_name) { + this(simple_action, gateway_name, null, null, null, null, false, false, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service) { + this(simple_action, gateway_name, apply_service, null, null, null, false, false, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties) { + this(simple_action, gateway_name, apply_service, service_properties, null, null, false, false, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties, MirrorActionType mirror_to) { + this(simple_action, gateway_name, apply_service, service_properties, mirror_to, null, false, false, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties, MirrorActionType mirror_to, String assign_routing_instance) { + this(simple_action, gateway_name, apply_service, service_properties, mirror_to, assign_routing_instance, false, false, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties, MirrorActionType mirror_to, String assign_routing_instance, Boolean log) { + this(simple_action, gateway_name, apply_service, service_properties, mirror_to, assign_routing_instance, log, false, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties, MirrorActionType mirror_to, String assign_routing_instance, Boolean log, Boolean alert) { + this(simple_action, gateway_name, apply_service, service_properties, mirror_to, assign_routing_instance, log, alert, null, false); } + public ActionListType(String simple_action, String gateway_name, List apply_service, ServicePropertiesType service_properties, MirrorActionType mirror_to, String assign_routing_instance, Boolean log, Boolean alert, String qos_action) { + this(simple_action, gateway_name, apply_service, service_properties, mirror_to, assign_routing_instance, log, alert, qos_action, false); } + + public String getSimpleAction() { + return simple_action; + } + + public void setSimpleAction(String simple_action) { + this.simple_action = simple_action; + } + + + public String getGatewayName() { + return gateway_name; + } + + public void setGatewayName(String gateway_name) { + this.gateway_name = gateway_name; + } + + + public ServicePropertiesType getServiceProperties() { + return service_properties; + } + + public void setServiceProperties(ServicePropertiesType service_properties) { + this.service_properties = service_properties; + } + + + public MirrorActionType getMirrorTo() { + return mirror_to; + } + + public void setMirrorTo(MirrorActionType mirror_to) { + this.mirror_to = mirror_to; + } + + + public String getAssignRoutingInstance() { + return assign_routing_instance; + } + + public void setAssignRoutingInstance(String assign_routing_instance) { + this.assign_routing_instance = assign_routing_instance; + } + + + public Boolean getLog() { + return log; + } + + public void setLog(Boolean log) { + this.log = log; + } + + + public Boolean getAlert() { + return alert; + } + + public void setAlert(Boolean alert) { + this.alert = alert; + } + + + public String getQosAction() { + return qos_action; + } + + public void setQosAction(String qos_action) { + this.qos_action = qos_action; + } + + + public Boolean getHostBasedService() { + return host_based_service; + } + + public void setHostBasedService(Boolean host_based_service) { + this.host_based_service = host_based_service; + } + + + public List getApplyService() { + return apply_service; + } + + + public void addApplyService(String obj) { + if (apply_service == null) { + apply_service = new ArrayList(); + } + apply_service.add(obj); + } + public void clearApplyService() { + apply_service = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AddressGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AddressGroup.java new file mode 100644 index 00000000000..1993b729a75 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AddressGroup.java @@ -0,0 +1,133 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AddressGroup extends ApiObjectBase { + private String draft_mode_state; + private SubnetListType address_group_prefix; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> firewall_rule_back_refs; + + @Override + public String getObjectType() { + return "address-group"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(PolicyManagement parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getDraftModeState() { + return draft_mode_state; + } + + public void setDraftModeState(String draft_mode_state) { + this.draft_mode_state = draft_mode_state; + } + + + public SubnetListType getPrefix() { + return address_group_prefix; + } + + public void setPrefix(SubnetListType address_group_prefix) { + this.address_group_prefix = address_group_prefix; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getFirewallRuleBackRefs() { + return firewall_rule_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AddressType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AddressType.java new file mode 100644 index 00000000000..e6bb33c261d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AddressType.java @@ -0,0 +1,94 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AddressType extends ApiPropertyBase { + SubnetType subnet; + String virtual_network; + String security_group; + String network_policy; + List subnet_list; + public AddressType() { + } + public AddressType(SubnetType subnet, String virtual_network, String security_group, String network_policy, List subnet_list) { + this.subnet = subnet; + this.virtual_network = virtual_network; + this.security_group = security_group; + this.network_policy = network_policy; + this.subnet_list = subnet_list; + } + public AddressType(SubnetType subnet) { + this(subnet, null, null, null, null); } + public AddressType(SubnetType subnet, String virtual_network) { + this(subnet, virtual_network, null, null, null); } + public AddressType(SubnetType subnet, String virtual_network, String security_group) { + this(subnet, virtual_network, security_group, null, null); } + public AddressType(SubnetType subnet, String virtual_network, String security_group, String network_policy) { + this(subnet, virtual_network, security_group, network_policy, null); } + + public SubnetType getSubnet() { + return subnet; + } + + public void setSubnet(SubnetType subnet) { + this.subnet = subnet; + } + + + public String getVirtualNetwork() { + return virtual_network; + } + + public void setVirtualNetwork(String virtual_network) { + this.virtual_network = virtual_network; + } + + + public String getSecurityGroup() { + return security_group; + } + + public void setSecurityGroup(String security_group) { + this.security_group = security_group; + } + + + public String getNetworkPolicy() { + return network_policy; + } + + public void setNetworkPolicy(String network_policy) { + this.network_policy = network_policy; + } + + + public List getSubnetList() { + return subnet_list; + } + + + public void addSubnet(SubnetType obj) { + if (subnet_list == null) { + subnet_list = new ArrayList(); + } + subnet_list.add(obj); + } + public void clearSubnet() { + subnet_list = null; + } + + + public void addSubnet(String ip_prefix, Integer ip_prefix_len) { + if (subnet_list == null) { + subnet_list = new ArrayList(); + } + subnet_list.add(new SubnetType(ip_prefix, ip_prefix_len)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Alarm.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Alarm.java new file mode 100644 index 00000000000..ac85f323ad2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Alarm.java @@ -0,0 +1,138 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Alarm extends ApiObjectBase { + private UveKeysType uve_keys; + private Integer alarm_severity; + private AlarmOrList alarm_rules; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "alarm"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public UveKeysType getUveKeys() { + return uve_keys; + } + + public void setUveKeys(UveKeysType uve_keys) { + this.uve_keys = uve_keys; + } + + + public Integer getSeverity() { + return alarm_severity; + } + + public void setSeverity(Integer alarm_severity) { + this.alarm_severity = alarm_severity; + } + + + public AlarmOrList getRules() { + return alarm_rules; + } + + public void setRules(AlarmOrList alarm_rules) { + this.alarm_rules = alarm_rules; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmAndList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmAndList.java new file mode 100644 index 00000000000..57813cf6c47 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmAndList.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AlarmAndList extends ApiPropertyBase { + List and_list; + public AlarmAndList() { + } + public AlarmAndList(List and_list) { + this.and_list = and_list; + } + + public List getAndList() { + return and_list; + } + + + public void addAnd(AlarmExpression obj) { + if (and_list == null) { + and_list = new ArrayList(); + } + and_list.add(obj); + } + public void clearAnd() { + and_list = null; + } + + + public void addAnd(String operation, String operand1, AlarmOperand2 operand2, List variables) { + if (and_list == null) { + and_list = new ArrayList(); + } + and_list.add(new AlarmExpression(operation, operand1, operand2, variables)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmExpression.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmExpression.java new file mode 100644 index 00000000000..641eefac7fd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmExpression.java @@ -0,0 +1,73 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AlarmExpression extends ApiPropertyBase { + String operation; + String operand1; + AlarmOperand2 operand2; + List variables; + public AlarmExpression() { + } + public AlarmExpression(String operation, String operand1, AlarmOperand2 operand2, List variables) { + this.operation = operation; + this.operand1 = operand1; + this.operand2 = operand2; + this.variables = variables; + } + public AlarmExpression(String operation) { + this(operation, null, null, null); } + public AlarmExpression(String operation, String operand1) { + this(operation, operand1, null, null); } + public AlarmExpression(String operation, String operand1, AlarmOperand2 operand2) { + this(operation, operand1, operand2, null); } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } + + + public String getOperand1() { + return operand1; + } + + public void setOperand1(String operand1) { + this.operand1 = operand1; + } + + + public AlarmOperand2 getOperand2() { + return operand2; + } + + public void setOperand2(AlarmOperand2 operand2) { + this.operand2 = operand2; + } + + + public List getVariables() { + return variables; + } + + + public void addVariables(String obj) { + if (variables == null) { + variables = new ArrayList(); + } + variables.add(obj); + } + public void clearVariables() { + variables = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmOperand2.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmOperand2.java new file mode 100644 index 00000000000..e63fafecb77 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmOperand2.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AlarmOperand2 extends ApiPropertyBase { + String uve_attribute; + String json_value; + public AlarmOperand2() { + } + public AlarmOperand2(String uve_attribute, String json_value) { + this.uve_attribute = uve_attribute; + this.json_value = json_value; + } + public AlarmOperand2(String uve_attribute) { + this(uve_attribute, null); } + + public String getUveAttribute() { + return uve_attribute; + } + + public void setUveAttribute(String uve_attribute) { + this.uve_attribute = uve_attribute; + } + + + public String getJsonValue() { + return json_value; + } + + public void setJsonValue(String json_value) { + this.json_value = json_value; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmOrList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmOrList.java new file mode 100644 index 00000000000..b6b243a9371 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AlarmOrList.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AlarmOrList extends ApiPropertyBase { + List or_list; + public AlarmOrList() { + } + public AlarmOrList(List or_list) { + this.or_list = or_list; + } + + public List getOrList() { + return or_list; + } + + + public void addOr(AlarmAndList obj) { + if (or_list == null) { + or_list = new ArrayList(); + } + or_list.add(obj); + } + public void clearOr() { + or_list = null; + } + + + public void addOr(List and_list) { + if (or_list == null) { + or_list = new ArrayList(); + } + or_list.add(new AlarmAndList(and_list)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AliasIp.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AliasIp.java new file mode 100644 index 00000000000..3a7b139e1d3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AliasIp.java @@ -0,0 +1,187 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AliasIp extends ApiObjectBase { + private String alias_ip_address; + private String alias_ip_address_family; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> project_refs; + private List> virtual_machine_interface_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "alias-ip"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-virtual-network", "default-alias-ip-pool"); + } + + @Override + public String getDefaultParentType() { + return "alias-ip-pool"; + } + + public void setParent(AliasIpPool parent) { + super.setParent(parent); + } + + public String getAddress() { + return alias_ip_address; + } + + public void setAddress(String alias_ip_address) { + this.alias_ip_address = alias_ip_address; + } + + + public String getAddressFamily() { + return alias_ip_address_family; + } + + public void setAddressFamily(String alias_ip_address_family) { + this.alias_ip_address_family = alias_ip_address_family; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getProject() { + return project_refs; + } + + public void setProject(Project obj) { + project_refs = new ArrayList>(); + project_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addProject(Project obj) { + if (project_refs == null) { + project_refs = new ArrayList>(); + } + project_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeProject(Project obj) { + if (project_refs != null) { + project_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearProject() { + if (project_refs != null) { + project_refs.clear(); + return; + } + project_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AliasIpPool.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AliasIpPool.java new file mode 100644 index 00000000000..5bf66b61f85 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AliasIpPool.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AliasIpPool extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> alias_ips; + private List> tag_refs; + private transient List> project_back_refs; + + @Override + public String getObjectType() { + return "alias-ip-pool"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-virtual-network"); + } + + @Override + public String getDefaultParentType() { + return "virtual-network"; + } + + public void setParent(VirtualNetwork parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getAliasIps() { + return alias_ips; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getProjectBackRefs() { + return project_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllocationPoolType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllocationPoolType.java new file mode 100644 index 00000000000..c68e7dcfdd8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllocationPoolType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AllocationPoolType extends ApiPropertyBase { + String start; + String end; + Boolean vrouter_specific_pool; + public AllocationPoolType() { + } + public AllocationPoolType(String start, String end, Boolean vrouter_specific_pool) { + this.start = start; + this.end = end; + this.vrouter_specific_pool = vrouter_specific_pool; + } + public AllocationPoolType(String start) { + this(start, null, null); } + public AllocationPoolType(String start, String end) { + this(start, end, null); } + + public String getStart() { + return start; + } + + public void setStart(String start) { + this.start = start; + } + + + public String getEnd() { + return end; + } + + public void setEnd(String end) { + this.end = end; + } + + + public Boolean getVrouterSpecificPool() { + return vrouter_specific_pool; + } + + public void setVrouterSpecificPool(Boolean vrouter_specific_pool) { + this.vrouter_specific_pool = vrouter_specific_pool; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllowedAddressPair.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllowedAddressPair.java new file mode 100644 index 00000000000..83c67e364eb --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllowedAddressPair.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AllowedAddressPair extends ApiPropertyBase { + SubnetType ip; + String mac; + String address_mode; + public AllowedAddressPair() { + } + public AllowedAddressPair(SubnetType ip, String mac, String address_mode) { + this.ip = ip; + this.mac = mac; + this.address_mode = address_mode; + } + public AllowedAddressPair(SubnetType ip) { + this(ip, null, null); } + public AllowedAddressPair(SubnetType ip, String mac) { + this(ip, mac, null); } + + public SubnetType getIp() { + return ip; + } + + public void setIp(SubnetType ip) { + this.ip = ip; + } + + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + + public String getAddressMode() { + return address_mode; + } + + public void setAddressMode(String address_mode) { + this.address_mode = address_mode; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllowedAddressPairs.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllowedAddressPairs.java new file mode 100644 index 00000000000..0e4c65a4cfa --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AllowedAddressPairs.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AllowedAddressPairs extends ApiPropertyBase { + List allowed_address_pair; + public AllowedAddressPairs() { + } + public AllowedAddressPairs(List allowed_address_pair) { + this.allowed_address_pair = allowed_address_pair; + } + + public List getAllowedAddressPair() { + return allowed_address_pair; + } + + + public void addAllowedAddressPair(AllowedAddressPair obj) { + if (allowed_address_pair == null) { + allowed_address_pair = new ArrayList(); + } + allowed_address_pair.add(obj); + } + public void clearAllowedAddressPair() { + allowed_address_pair = null; + } + + + public void addAllowedAddressPair(SubnetType ip, String mac, String address_mode) { + if (allowed_address_pair == null) { + allowed_address_pair = new ArrayList(); + } + allowed_address_pair.add(new AllowedAddressPair(ip, mac, address_mode)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsAlarmNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsAlarmNode.java new file mode 100644 index 00000000000..1a89c1d8aa5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsAlarmNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AnalyticsAlarmNode extends ApiObjectBase { + private String analytics_alarm_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "analytics-alarm-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return analytics_alarm_node_ip_address; + } + + public void setIpAddress(String analytics_alarm_node_ip_address) { + this.analytics_alarm_node_ip_address = analytics_alarm_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsNode.java new file mode 100644 index 00000000000..d36510d7187 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AnalyticsNode extends ApiObjectBase { + private String analytics_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "analytics-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return analytics_node_ip_address; + } + + public void setIpAddress(String analytics_node_ip_address) { + this.analytics_node_ip_address = analytics_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsSnmpNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsSnmpNode.java new file mode 100644 index 00000000000..ff1386ca1e2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AnalyticsSnmpNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class AnalyticsSnmpNode extends ApiObjectBase { + private String analytics_snmp_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "analytics-snmp-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return analytics_snmp_node_ip_address; + } + + public void setIpAddress(String analytics_snmp_node_ip_address) { + this.analytics_snmp_node_ip_address = analytics_snmp_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ApiAccessList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ApiAccessList.java new file mode 100644 index 00000000000..a2002a6425d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ApiAccessList.java @@ -0,0 +1,122 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ApiAccessList extends ApiObjectBase { + private RbacRuleEntriesType api_access_list_entries; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "api-access-list"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(Domain parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public RbacRuleEntriesType getEntries() { + return api_access_list_entries; + } + + public void setEntries(RbacRuleEntriesType api_access_list_entries) { + this.api_access_list_entries = api_access_list_entries; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ApplicationPolicySet.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ApplicationPolicySet.java new file mode 100644 index 00000000000..92c7b52141c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ApplicationPolicySet.java @@ -0,0 +1,196 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ApplicationPolicySet extends ApiObjectBase { + private String draft_mode_state; + private Boolean all_applications; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> firewall_policy_refs; + private List> global_vrouter_config_refs; + private List> tag_refs; + private transient List> project_back_refs; + + @Override + public String getObjectType() { + return "application-policy-set"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(PolicyManagement parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getDraftModeState() { + return draft_mode_state; + } + + public void setDraftModeState(String draft_mode_state) { + this.draft_mode_state = draft_mode_state; + } + + + public Boolean getAllApplications() { + return all_applications; + } + + public void setAllApplications(Boolean all_applications) { + this.all_applications = all_applications; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getFirewallPolicy() { + return firewall_policy_refs; + } + + public void setFirewallPolicy(FirewallPolicy obj, FirewallSequence data) { + firewall_policy_refs = new ArrayList>(); + firewall_policy_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addFirewallPolicy(FirewallPolicy obj, FirewallSequence data) { + if (firewall_policy_refs == null) { + firewall_policy_refs = new ArrayList>(); + } + firewall_policy_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeFirewallPolicy(FirewallPolicy obj, FirewallSequence data) { + if (firewall_policy_refs != null) { + firewall_policy_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearFirewallPolicy() { + if (firewall_policy_refs != null) { + firewall_policy_refs.clear(); + return; + } + firewall_policy_refs = null; + } + + + public List> getGlobalVrouterConfig() { + return global_vrouter_config_refs; + } + + public void setGlobalVrouterConfig(GlobalVrouterConfig obj) { + global_vrouter_config_refs = new ArrayList>(); + global_vrouter_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addGlobalVrouterConfig(GlobalVrouterConfig obj) { + if (global_vrouter_config_refs == null) { + global_vrouter_config_refs = new ArrayList>(); + } + global_vrouter_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeGlobalVrouterConfig(GlobalVrouterConfig obj) { + if (global_vrouter_config_refs != null) { + global_vrouter_config_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearGlobalVrouterConfig() { + if (global_vrouter_config_refs != null) { + global_vrouter_config_refs.clear(); + return; + } + global_vrouter_config_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getProjectBackRefs() { + return project_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AsnRangeType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AsnRangeType.java new file mode 100644 index 00000000000..988258fa921 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AsnRangeType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AsnRangeType extends ApiPropertyBase { + Integer asn_min; + Integer asn_max; + public AsnRangeType() { + } + public AsnRangeType(Integer asn_min, Integer asn_max) { + this.asn_min = asn_min; + this.asn_max = asn_max; + } + public AsnRangeType(Integer asn_min) { + this(asn_min, null); } + + public Integer getAsnMin() { + return asn_min; + } + + public void setAsnMin(Integer asn_min) { + this.asn_min = asn_min; + } + + + public Integer getAsnMax() { + return asn_max; + } + + public void setAsnMax(Integer asn_max) { + this.asn_max = asn_max; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AutonomousSystemsType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AutonomousSystemsType.java new file mode 100644 index 00000000000..4ad3b3e2489 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/AutonomousSystemsType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class AutonomousSystemsType extends ApiPropertyBase { + List asn; + public AutonomousSystemsType() { + } + public AutonomousSystemsType(List asn) { + this.asn = asn; + } + + public List getAsn() { + return asn; + } + + + public void addAsn(Integer obj) { + if (asn == null) { + asn = new ArrayList(); + } + asn.add(obj); + } + public void clearAsn() { + asn = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BGPaaSControlNodeZoneAttributes.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BGPaaSControlNodeZoneAttributes.java new file mode 100644 index 00000000000..fa0e2a63861 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BGPaaSControlNodeZoneAttributes.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BGPaaSControlNodeZoneAttributes extends ApiPropertyBase { + String bgpaas_control_node_zone_type; + public BGPaaSControlNodeZoneAttributes() { + } + public BGPaaSControlNodeZoneAttributes(String bgpaas_control_node_zone_type) { + this.bgpaas_control_node_zone_type = bgpaas_control_node_zone_type; + } + + public String getBgpaasControlNodeZoneType() { + return bgpaas_control_node_zone_type; + } + + public void setBgpaasControlNodeZoneType(String bgpaas_control_node_zone_type) { + this.bgpaas_control_node_zone_type = bgpaas_control_node_zone_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BGPaaServiceParametersType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BGPaaServiceParametersType.java new file mode 100644 index 00000000000..ec79b2ff005 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BGPaaServiceParametersType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BGPaaServiceParametersType extends ApiPropertyBase { + Integer port_start; + Integer port_end; + public BGPaaServiceParametersType() { + } + public BGPaaServiceParametersType(Integer port_start, Integer port_end) { + this.port_start = port_start; + this.port_end = port_end; + } + public BGPaaServiceParametersType(Integer port_start) { + this(port_start, 50512); } + + public Integer getPortStart() { + return port_start; + } + + public void setPortStart(Integer port_start) { + this.port_start = port_start; + } + + + public Integer getPortEnd() { + return port_end; + } + + public void setPortEnd(Integer port_end) { + this.port_end = port_end; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalPortGroupInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalPortGroupInfo.java new file mode 100644 index 00000000000..57487f812d0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalPortGroupInfo.java @@ -0,0 +1,76 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BaremetalPortGroupInfo extends ApiPropertyBase { + Boolean standalone_ports_supported; + String node_uuid; + PortGroupProperties properties; + String address; + String mode; + public BaremetalPortGroupInfo() { + } + public BaremetalPortGroupInfo(Boolean standalone_ports_supported, String node_uuid, PortGroupProperties properties, String address, String mode) { + this.standalone_ports_supported = standalone_ports_supported; + this.node_uuid = node_uuid; + this.properties = properties; + this.address = address; + this.mode = mode; + } + public BaremetalPortGroupInfo(Boolean standalone_ports_supported) { + this(standalone_ports_supported, null, null, null, null); } + public BaremetalPortGroupInfo(Boolean standalone_ports_supported, String node_uuid) { + this(standalone_ports_supported, node_uuid, null, null, null); } + public BaremetalPortGroupInfo(Boolean standalone_ports_supported, String node_uuid, PortGroupProperties properties) { + this(standalone_ports_supported, node_uuid, properties, null, null); } + public BaremetalPortGroupInfo(Boolean standalone_ports_supported, String node_uuid, PortGroupProperties properties, String address) { + this(standalone_ports_supported, node_uuid, properties, address, null); } + + public Boolean getStandalonePortsSupported() { + return standalone_ports_supported; + } + + public void setStandalonePortsSupported(Boolean standalone_ports_supported) { + this.standalone_ports_supported = standalone_ports_supported; + } + + + public String getNodeUuid() { + return node_uuid; + } + + public void setNodeUuid(String node_uuid) { + this.node_uuid = node_uuid; + } + + + public PortGroupProperties getProperties() { + return properties; + } + + public void setProperties(PortGroupProperties properties) { + this.properties = properties; + } + + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalPortInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalPortInfo.java new file mode 100644 index 00000000000..273ddb48d22 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalPortInfo.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BaremetalPortInfo extends ApiPropertyBase { + Boolean pxe_enabled; + LocalLinkConnection local_link_connection; + String node_uuid; + String address; + public BaremetalPortInfo() { + } + public BaremetalPortInfo(Boolean pxe_enabled, LocalLinkConnection local_link_connection, String node_uuid, String address) { + this.pxe_enabled = pxe_enabled; + this.local_link_connection = local_link_connection; + this.node_uuid = node_uuid; + this.address = address; + } + public BaremetalPortInfo(Boolean pxe_enabled) { + this(pxe_enabled, null, null, null); } + public BaremetalPortInfo(Boolean pxe_enabled, LocalLinkConnection local_link_connection) { + this(pxe_enabled, local_link_connection, null, null); } + public BaremetalPortInfo(Boolean pxe_enabled, LocalLinkConnection local_link_connection, String node_uuid) { + this(pxe_enabled, local_link_connection, node_uuid, null); } + + public Boolean getPxeEnabled() { + return pxe_enabled; + } + + public void setPxeEnabled(Boolean pxe_enabled) { + this.pxe_enabled = pxe_enabled; + } + + + public LocalLinkConnection getLocalLinkConnection() { + return local_link_connection; + } + + public void setLocalLinkConnection(LocalLinkConnection local_link_connection) { + this.local_link_connection = local_link_connection; + } + + + public String getNodeUuid() { + return node_uuid; + } + + public void setNodeUuid(String node_uuid) { + this.node_uuid = node_uuid; + } + + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalProperties.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalProperties.java new file mode 100644 index 00000000000..4602914b542 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalProperties.java @@ -0,0 +1,76 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BaremetalProperties extends ApiPropertyBase { + Integer memory_mb; + String cpu_arch; + Integer local_gb; + Integer cpus; + String capabilities; + public BaremetalProperties() { + } + public BaremetalProperties(Integer memory_mb, String cpu_arch, Integer local_gb, Integer cpus, String capabilities) { + this.memory_mb = memory_mb; + this.cpu_arch = cpu_arch; + this.local_gb = local_gb; + this.cpus = cpus; + this.capabilities = capabilities; + } + public BaremetalProperties(Integer memory_mb) { + this(memory_mb, null, null, null, null); } + public BaremetalProperties(Integer memory_mb, String cpu_arch) { + this(memory_mb, cpu_arch, null, null, null); } + public BaremetalProperties(Integer memory_mb, String cpu_arch, Integer local_gb) { + this(memory_mb, cpu_arch, local_gb, null, null); } + public BaremetalProperties(Integer memory_mb, String cpu_arch, Integer local_gb, Integer cpus) { + this(memory_mb, cpu_arch, local_gb, cpus, null); } + + public Integer getMemoryMb() { + return memory_mb; + } + + public void setMemoryMb(Integer memory_mb) { + this.memory_mb = memory_mb; + } + + + public String getCpuArch() { + return cpu_arch; + } + + public void setCpuArch(String cpu_arch) { + this.cpu_arch = cpu_arch; + } + + + public Integer getLocalGb() { + return local_gb; + } + + public void setLocalGb(Integer local_gb) { + this.local_gb = local_gb; + } + + + public Integer getCpus() { + return cpus; + } + + public void setCpus(Integer cpus) { + this.cpus = cpus; + } + + + public String getCapabilities() { + return capabilities; + } + + public void setCapabilities(String capabilities) { + this.capabilities = capabilities; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalServerInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalServerInfo.java new file mode 100644 index 00000000000..2c7d125de77 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BaremetalServerInfo.java @@ -0,0 +1,76 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BaremetalServerInfo extends ApiPropertyBase { + String network_interface; + String driver; + BaremetalProperties properties; + DriverInfo driver_info; + String name; + public BaremetalServerInfo() { + } + public BaremetalServerInfo(String network_interface, String driver, BaremetalProperties properties, DriverInfo driver_info, String name) { + this.network_interface = network_interface; + this.driver = driver; + this.properties = properties; + this.driver_info = driver_info; + this.name = name; + } + public BaremetalServerInfo(String network_interface) { + this(network_interface, null, null, null, null); } + public BaremetalServerInfo(String network_interface, String driver) { + this(network_interface, driver, null, null, null); } + public BaremetalServerInfo(String network_interface, String driver, BaremetalProperties properties) { + this(network_interface, driver, properties, null, null); } + public BaremetalServerInfo(String network_interface, String driver, BaremetalProperties properties, DriverInfo driver_info) { + this(network_interface, driver, properties, driver_info, null); } + + public String getNetworkInterface() { + return network_interface; + } + + public void setNetworkInterface(String network_interface) { + this.network_interface = network_interface; + } + + + public String getDriver() { + return driver; + } + + public void setDriver(String driver) { + this.driver = driver; + } + + + public BaremetalProperties getProperties() { + return properties; + } + + public void setProperties(BaremetalProperties properties) { + this.properties = properties; + } + + + public DriverInfo getDriverInfo() { + return driver_info; + } + + public void setDriverInfo(DriverInfo driver_info) { + this.driver_info = driver_info; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BfdParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BfdParameters.java new file mode 100644 index 00000000000..98298bcc4ac --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BfdParameters.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BfdParameters extends ApiPropertyBase { + Integer time_interval; + Integer detection_time_multiplier; + public BfdParameters() { + } + public BfdParameters(Integer time_interval, Integer detection_time_multiplier) { + this.time_interval = time_interval; + this.detection_time_multiplier = detection_time_multiplier; + } + public BfdParameters(Integer time_interval) { + this(time_interval, null); } + + public Integer getTimeInterval() { + return time_interval; + } + + public void setTimeInterval(Integer time_interval) { + this.time_interval = time_interval; + } + + + public Integer getDetectionTimeMultiplier() { + return detection_time_multiplier; + } + + public void setDetectionTimeMultiplier(Integer detection_time_multiplier) { + this.detection_time_multiplier = detection_time_multiplier; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpAsAService.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpAsAService.java new file mode 100644 index 00000000000..185973fe918 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpAsAService.java @@ -0,0 +1,259 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class BgpAsAService extends ApiObjectBase { + private Integer autonomous_system; + private Boolean bgpaas_shared; + private String bgpaas_ip_address; + private String bgpaas_session_attributes; + private Boolean bgpaas_ipv4_mapped_ipv6_nexthop; + private Boolean bgpaas_suppress_route_advertisement; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> control_node_zone_refs; + private List> virtual_machine_interface_refs; + private List> service_health_check_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "bgp-as-a-service"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Integer getAutonomousSystem() { + return autonomous_system; + } + + public void setAutonomousSystem(Integer autonomous_system) { + this.autonomous_system = autonomous_system; + } + + + public Boolean getBgpaasShared() { + return bgpaas_shared; + } + + public void setBgpaasShared(Boolean bgpaas_shared) { + this.bgpaas_shared = bgpaas_shared; + } + + + public String getBgpaasIpAddress() { + return bgpaas_ip_address; + } + + public void setBgpaasIpAddress(String bgpaas_ip_address) { + this.bgpaas_ip_address = bgpaas_ip_address; + } + + + public String getBgpaasSessionAttributes() { + return bgpaas_session_attributes; + } + + public void setBgpaasSessionAttributes(String bgpaas_session_attributes) { + this.bgpaas_session_attributes = bgpaas_session_attributes; + } + + + public Boolean getBgpaasIpv4MappedIpv6Nexthop() { + return bgpaas_ipv4_mapped_ipv6_nexthop; + } + + public void setBgpaasIpv4MappedIpv6Nexthop(Boolean bgpaas_ipv4_mapped_ipv6_nexthop) { + this.bgpaas_ipv4_mapped_ipv6_nexthop = bgpaas_ipv4_mapped_ipv6_nexthop; + } + + + public Boolean getBgpaasSuppressRouteAdvertisement() { + return bgpaas_suppress_route_advertisement; + } + + public void setBgpaasSuppressRouteAdvertisement(Boolean bgpaas_suppress_route_advertisement) { + this.bgpaas_suppress_route_advertisement = bgpaas_suppress_route_advertisement; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getControlNodeZone() { + return control_node_zone_refs; + } + + public void setControlNodeZone(ControlNodeZone obj, BGPaaSControlNodeZoneAttributes data) { + control_node_zone_refs = new ArrayList>(); + control_node_zone_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addControlNodeZone(ControlNodeZone obj, BGPaaSControlNodeZoneAttributes data) { + if (control_node_zone_refs == null) { + control_node_zone_refs = new ArrayList>(); + } + control_node_zone_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeControlNodeZone(ControlNodeZone obj, BGPaaSControlNodeZoneAttributes data) { + if (control_node_zone_refs != null) { + control_node_zone_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearControlNodeZone() { + if (control_node_zone_refs != null) { + control_node_zone_refs.clear(); + return; + } + control_node_zone_refs = null; + } + + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getServiceHealthCheck() { + return service_health_check_refs; + } + + public void setServiceHealthCheck(ServiceHealthCheck obj) { + service_health_check_refs = new ArrayList>(); + service_health_check_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceHealthCheck(ServiceHealthCheck obj) { + if (service_health_check_refs == null) { + service_health_check_refs = new ArrayList>(); + } + service_health_check_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceHealthCheck(ServiceHealthCheck obj) { + if (service_health_check_refs != null) { + service_health_check_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceHealthCheck() { + if (service_health_check_refs != null) { + service_health_check_refs.clear(); + return; + } + service_health_check_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpParameters.java new file mode 100644 index 00000000000..a701e542ab2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpParameters.java @@ -0,0 +1,112 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BgpParameters extends ApiPropertyBase { + Integer peer_autonomous_system; + String peer_ip_address; + List peer_ip_address_list; + String hold_time; + String auth_data; + Integer local_autonomous_system; + Integer multihop_ttl; + public BgpParameters() { + } + public BgpParameters(Integer peer_autonomous_system, String peer_ip_address, List peer_ip_address_list, String hold_time, String auth_data, Integer local_autonomous_system, Integer multihop_ttl) { + this.peer_autonomous_system = peer_autonomous_system; + this.peer_ip_address = peer_ip_address; + this.peer_ip_address_list = peer_ip_address_list; + this.hold_time = hold_time; + this.auth_data = auth_data; + this.local_autonomous_system = local_autonomous_system; + this.multihop_ttl = multihop_ttl; + } + public BgpParameters(Integer peer_autonomous_system) { + this(peer_autonomous_system, null, null, "0", null, null, null); } + public BgpParameters(Integer peer_autonomous_system, String peer_ip_address) { + this(peer_autonomous_system, peer_ip_address, null, "0", null, null, null); } + public BgpParameters(Integer peer_autonomous_system, String peer_ip_address, List peer_ip_address_list) { + this(peer_autonomous_system, peer_ip_address, peer_ip_address_list, "0", null, null, null); } + public BgpParameters(Integer peer_autonomous_system, String peer_ip_address, List peer_ip_address_list, String hold_time) { + this(peer_autonomous_system, peer_ip_address, peer_ip_address_list, hold_time, null, null, null); } + public BgpParameters(Integer peer_autonomous_system, String peer_ip_address, List peer_ip_address_list, String hold_time, String auth_data) { + this(peer_autonomous_system, peer_ip_address, peer_ip_address_list, hold_time, auth_data, null, null); } + public BgpParameters(Integer peer_autonomous_system, String peer_ip_address, List peer_ip_address_list, String hold_time, String auth_data, Integer local_autonomous_system) { + this(peer_autonomous_system, peer_ip_address, peer_ip_address_list, hold_time, auth_data, local_autonomous_system, null); } + + public Integer getPeerAutonomousSystem() { + return peer_autonomous_system; + } + + public void setPeerAutonomousSystem(Integer peer_autonomous_system) { + this.peer_autonomous_system = peer_autonomous_system; + } + + + public String getPeerIpAddress() { + return peer_ip_address; + } + + public void setPeerIpAddress(String peer_ip_address) { + this.peer_ip_address = peer_ip_address; + } + + + public String getHoldTime() { + return hold_time; + } + + public void setHoldTime(String hold_time) { + this.hold_time = hold_time; + } + + + public String getAuthData() { + return auth_data; + } + + public void setAuthData(String auth_data) { + this.auth_data = auth_data; + } + + + public Integer getLocalAutonomousSystem() { + return local_autonomous_system; + } + + public void setLocalAutonomousSystem(Integer local_autonomous_system) { + this.local_autonomous_system = local_autonomous_system; + } + + + public Integer getMultihopTtl() { + return multihop_ttl; + } + + public void setMultihopTtl(Integer multihop_ttl) { + this.multihop_ttl = multihop_ttl; + } + + + public List getPeerIpAddressList() { + return peer_ip_address_list; + } + + + public void addPeerIpAddress(String obj) { + if (peer_ip_address_list == null) { + peer_ip_address_list = new ArrayList(); + } + peer_ip_address_list.add(obj); + } + public void clearPeerIpAddress() { + peer_ip_address_list = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpRouter.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpRouter.java new file mode 100644 index 00000000000..6346cb081e3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BgpRouter.java @@ -0,0 +1,147 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class BgpRouter extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> control_node_zone_refs; + private List> tag_refs; + private transient List> global_system_config_back_refs; + private transient List> physical_router_back_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "bgp-router"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getControlNodeZone() { + return control_node_zone_refs; + } + + public void setControlNodeZone(ControlNodeZone obj) { + control_node_zone_refs = new ArrayList>(); + control_node_zone_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addControlNodeZone(ControlNodeZone obj) { + if (control_node_zone_refs == null) { + control_node_zone_refs = new ArrayList>(); + } + control_node_zone_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeControlNodeZone(ControlNodeZone obj) { + if (control_node_zone_refs != null) { + control_node_zone_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearControlNodeZone() { + if (control_node_zone_refs != null) { + control_node_zone_refs.clear(); + return; + } + control_node_zone_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getGlobalSystemConfigBackRefs() { + return global_system_config_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Bgpvpn.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Bgpvpn.java new file mode 100644 index 00000000000..4969c82e47b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Bgpvpn.java @@ -0,0 +1,155 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Bgpvpn extends ApiObjectBase { + private RouteTargetList route_target_list; + private RouteTargetList import_route_target_list; + private RouteTargetList export_route_target_list; + private String bgpvpn_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> virtual_network_back_refs; + private transient List> logical_router_back_refs; + + @Override + public String getObjectType() { + return "bgpvpn"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public RouteTargetList getRouteTargetList() { + return route_target_list; + } + + public void setRouteTargetList(RouteTargetList route_target_list) { + this.route_target_list = route_target_list; + } + + + public RouteTargetList getImportRouteTargetList() { + return import_route_target_list; + } + + public void setImportRouteTargetList(RouteTargetList import_route_target_list) { + this.import_route_target_list = import_route_target_list; + } + + + public RouteTargetList getExportRouteTargetList() { + return export_route_target_list; + } + + public void setExportRouteTargetList(RouteTargetList export_route_target_list) { + this.export_route_target_list = export_route_target_list; + } + + + public String getType() { + return bgpvpn_type; + } + + public void setType(String bgpvpn_type) { + this.bgpvpn_type = bgpvpn_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BridgeDomain.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BridgeDomain.java new file mode 100644 index 00000000000..443d8e88499 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BridgeDomain.java @@ -0,0 +1,160 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class BridgeDomain extends ApiObjectBase { + private Boolean mac_learning_enabled; + private MACLimitControlType mac_limit_control; + private MACMoveLimitControlType mac_move_control; + private Integer mac_aging_time; + private Integer isid; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "bridge-domain"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-virtual-network"); + } + + @Override + public String getDefaultParentType() { + return "virtual-network"; + } + + public void setParent(VirtualNetwork parent) { + super.setParent(parent); + } + + public Boolean getMacLearningEnabled() { + return mac_learning_enabled; + } + + public void setMacLearningEnabled(Boolean mac_learning_enabled) { + this.mac_learning_enabled = mac_learning_enabled; + } + + + public MACLimitControlType getMacLimitControl() { + return mac_limit_control; + } + + public void setMacLimitControl(MACLimitControlType mac_limit_control) { + this.mac_limit_control = mac_limit_control; + } + + + public MACMoveLimitControlType getMacMoveControl() { + return mac_move_control; + } + + public void setMacMoveControl(MACMoveLimitControlType mac_move_control) { + this.mac_move_control = mac_move_control; + } + + + public Integer getMacAgingTime() { + return mac_aging_time; + } + + public void setMacAgingTime(Integer mac_aging_time) { + this.mac_aging_time = mac_aging_time; + } + + + public Integer getIsid() { + return isid; + } + + public void setIsid(Integer isid) { + this.isid = isid; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BridgeDomainMembershipType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BridgeDomainMembershipType.java new file mode 100644 index 00000000000..be7123b8d77 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/BridgeDomainMembershipType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class BridgeDomainMembershipType extends ApiPropertyBase { + Integer vlan_tag; + public BridgeDomainMembershipType() { + } + public BridgeDomainMembershipType(Integer vlan_tag) { + this.vlan_tag = vlan_tag; + } + + public Integer getVlanTag() { + return vlan_tag; + } + + public void setVlanTag(Integer vlan_tag) { + this.vlan_tag = vlan_tag; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Card.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Card.java new file mode 100644 index 00000000000..4d3bb2124dd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Card.java @@ -0,0 +1,116 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Card extends ApiObjectBase { + private InterfaceMapType interface_map; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> hardware_back_refs; + + @Override + public String getObjectType() { + return "card"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public InterfaceMapType getInterfaceMap() { + return interface_map; + } + + public void setInterfaceMap(InterfaceMapType interface_map) { + this.interface_map = interface_map; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getHardwareBackRefs() { + return hardware_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliConfig.java new file mode 100644 index 00000000000..0efea702b82 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliConfig.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class CliConfig extends ApiObjectBase { + private String accepted_cli_config; + private CliDiffListType commit_diff_list; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "cli-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-physical-router"); + } + + @Override + public String getDefaultParentType() { + return "physical-router"; + } + + public void setParent(PhysicalRouter parent) { + super.setParent(parent); + } + + public String getAcceptedCliConfig() { + return accepted_cli_config; + } + + public void setAcceptedCliConfig(String accepted_cli_config) { + this.accepted_cli_config = accepted_cli_config; + } + + + public CliDiffListType getCommitDiffList() { + return commit_diff_list; + } + + public void setCommitDiffList(CliDiffListType commit_diff_list) { + this.commit_diff_list = commit_diff_list; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliDiffInfoType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliDiffInfoType.java new file mode 100644 index 00000000000..414e573f8b3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliDiffInfoType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class CliDiffInfoType extends ApiPropertyBase { + String username; + String time; + String config_changes; + public CliDiffInfoType() { + } + public CliDiffInfoType(String username, String time, String config_changes) { + this.username = username; + this.time = time; + this.config_changes = config_changes; + } + public CliDiffInfoType(String username) { + this(username, null, null); } + public CliDiffInfoType(String username, String time) { + this(username, time, null); } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + + public String getConfigChanges() { + return config_changes; + } + + public void setConfigChanges(String config_changes) { + this.config_changes = config_changes; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliDiffListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliDiffListType.java new file mode 100644 index 00000000000..924d7415985 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CliDiffListType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class CliDiffListType extends ApiPropertyBase { + List commit_diff_info; + public CliDiffListType() { + } + public CliDiffListType(List commit_diff_info) { + this.commit_diff_info = commit_diff_info; + } + + public List getCommitDiffInfo() { + return commit_diff_info; + } + + + public void addCommitDiffInfo(CliDiffInfoType obj) { + if (commit_diff_info == null) { + commit_diff_info = new ArrayList(); + } + commit_diff_info.add(obj); + } + public void clearCommitDiffInfo() { + commit_diff_info = null; + } + + + public void addCommitDiffInfo(String username, String time, String config_changes) { + if (commit_diff_info == null) { + commit_diff_info = new ArrayList(); + } + commit_diff_info.add(new CliDiffInfoType(username, time, config_changes)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CloudInstanceInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CloudInstanceInfo.java new file mode 100644 index 00000000000..831614f32c8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CloudInstanceInfo.java @@ -0,0 +1,112 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class CloudInstanceInfo extends ApiPropertyBase { + String os_version; + String operating_system; + List roles; + String availability_zone; + String instance_type; + String machine_id; + Integer volume_size; + public CloudInstanceInfo() { + } + public CloudInstanceInfo(String os_version, String operating_system, List roles, String availability_zone, String instance_type, String machine_id, Integer volume_size) { + this.os_version = os_version; + this.operating_system = operating_system; + this.roles = roles; + this.availability_zone = availability_zone; + this.instance_type = instance_type; + this.machine_id = machine_id; + this.volume_size = volume_size; + } + public CloudInstanceInfo(String os_version) { + this(os_version, null, null, null, null, null, null); } + public CloudInstanceInfo(String os_version, String operating_system) { + this(os_version, operating_system, null, null, null, null, null); } + public CloudInstanceInfo(String os_version, String operating_system, List roles) { + this(os_version, operating_system, roles, null, null, null, null); } + public CloudInstanceInfo(String os_version, String operating_system, List roles, String availability_zone) { + this(os_version, operating_system, roles, availability_zone, null, null, null); } + public CloudInstanceInfo(String os_version, String operating_system, List roles, String availability_zone, String instance_type) { + this(os_version, operating_system, roles, availability_zone, instance_type, null, null); } + public CloudInstanceInfo(String os_version, String operating_system, List roles, String availability_zone, String instance_type, String machine_id) { + this(os_version, operating_system, roles, availability_zone, instance_type, machine_id, null); } + + public String getOsVersion() { + return os_version; + } + + public void setOsVersion(String os_version) { + this.os_version = os_version; + } + + + public String getOperatingSystem() { + return operating_system; + } + + public void setOperatingSystem(String operating_system) { + this.operating_system = operating_system; + } + + + public String getAvailabilityZone() { + return availability_zone; + } + + public void setAvailabilityZone(String availability_zone) { + this.availability_zone = availability_zone; + } + + + public String getInstanceType() { + return instance_type; + } + + public void setInstanceType(String instance_type) { + this.instance_type = instance_type; + } + + + public String getMachineId() { + return machine_id; + } + + public void setMachineId(String machine_id) { + this.machine_id = machine_id; + } + + + public Integer getVolumeSize() { + return volume_size; + } + + public void setVolumeSize(Integer volume_size) { + this.volume_size = volume_size; + } + + + public List getRoles() { + return roles; + } + + + public void addRoles(String obj) { + if (roles == null) { + roles = new ArrayList(); + } + roles.add(obj); + } + public void clearRoles() { + roles = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CommunityAttributes.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CommunityAttributes.java new file mode 100644 index 00000000000..e6a57d14d34 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CommunityAttributes.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class CommunityAttributes extends ApiPropertyBase { + List community_attribute; + public CommunityAttributes() { + } + public CommunityAttributes(List community_attribute) { + this.community_attribute = community_attribute; + } + + public List getCommunityAttribute() { + return community_attribute; + } + + + public void addCommunityAttribute(String obj) { + if (community_attribute == null) { + community_attribute = new ArrayList(); + } + community_attribute.add(obj); + } + public void clearCommunityAttribute() { + community_attribute = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigDatabaseNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigDatabaseNode.java new file mode 100644 index 00000000000..792a6a53556 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigDatabaseNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ConfigDatabaseNode extends ApiObjectBase { + private String config_database_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "config-database-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return config_database_node_ip_address; + } + + public void setIpAddress(String config_database_node_ip_address) { + this.config_database_node_ip_address = config_database_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigNode.java new file mode 100644 index 00000000000..ed10f138f28 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ConfigNode extends ApiObjectBase { + private String config_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "config-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return config_node_ip_address; + } + + public void setIpAddress(String config_node_ip_address) { + this.config_node_ip_address = config_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigProperties.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigProperties.java new file mode 100644 index 00000000000..23dd352a562 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigProperties.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ConfigProperties extends ApiObjectBase { + private KeyValuePairs properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "config-properties"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public KeyValuePairs getProperties() { + return properties; + } + + public void setProperties(KeyValuePairs properties) { + this.properties = properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigRoot.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigRoot.java new file mode 100644 index 00000000000..d7a5bd6f01c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ConfigRoot.java @@ -0,0 +1,121 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ConfigRoot extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> global_system_configs; + private List> domains; + private List> policy_managements; + private List> tags; + private List> tag_refs; + + @Override + public String getObjectType() { + return "config-root"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getGlobalSystemConfigs() { + return global_system_configs; + } + + public List> getDomains() { + return domains; + } + + public List> getPolicyManagements() { + return policy_managements; + } + + public List> getTags() { + return tags; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ControlNodeZone.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ControlNodeZone.java new file mode 100644 index 00000000000..2562eb5ea59 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ControlNodeZone.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ControlNodeZone extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> bgp_as_a_service_back_refs; + private transient List> bgp_router_back_refs; + + @Override + public String getObjectType() { + return "control-node-zone"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getBgpAsAServiceBackRefs() { + return bgp_as_a_service_back_refs; + } + + public List> getBgpRouterBackRefs() { + return bgp_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ControlTrafficDscpType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ControlTrafficDscpType.java new file mode 100644 index 00000000000..b5098a39952 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ControlTrafficDscpType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ControlTrafficDscpType extends ApiPropertyBase { + Integer control; + Integer analytics; + Integer dns; + public ControlTrafficDscpType() { + } + public ControlTrafficDscpType(Integer control, Integer analytics, Integer dns) { + this.control = control; + this.analytics = analytics; + this.dns = dns; + } + public ControlTrafficDscpType(Integer control) { + this(control, null, null); } + public ControlTrafficDscpType(Integer control, Integer analytics) { + this(control, analytics, null); } + + public Integer getControl() { + return control; + } + + public void setControl(Integer control) { + this.control = control; + } + + + public Integer getAnalytics() { + return analytics; + } + + public void setAnalytics(Integer analytics) { + this.analytics = analytics; + } + + + public Integer getDns() { + return dns; + } + + public void setDns(Integer dns) { + this.dns = dns; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CustomerAttachment.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CustomerAttachment.java new file mode 100644 index 00000000000..f7cca065d90 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/CustomerAttachment.java @@ -0,0 +1,163 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class CustomerAttachment extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_machine_interface_refs; + private List> floating_ip_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "customer-attachment"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getFloatingIp() { + return floating_ip_refs; + } + + public void setFloatingIp(FloatingIp obj) { + floating_ip_refs = new ArrayList>(); + floating_ip_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFloatingIp(FloatingIp obj) { + if (floating_ip_refs == null) { + floating_ip_refs = new ArrayList>(); + } + floating_ip_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFloatingIp(FloatingIp obj) { + if (floating_ip_refs != null) { + floating_ip_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFloatingIp() { + if (floating_ip_refs != null) { + floating_ip_refs.clear(); + return; + } + floating_ip_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DataCenterInterconnect.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DataCenterInterconnect.java new file mode 100644 index 00000000000..905021c00f7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DataCenterInterconnect.java @@ -0,0 +1,289 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DataCenterInterconnect extends ApiObjectBase { + private String data_center_interconnect_bgp_hold_time; + private String data_center_interconnect_mode; + private String data_center_interconnect_bgp_address_families; + private RouteTargetList data_center_interconnect_configured_route_target_list; + private String data_center_interconnect_type; + private LogicalRouterPRListType destination_physical_router_list; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> logical_router_refs; + private List> virtual_network_refs; + private List> routing_policy_refs; + private List> fabric_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "data-center-interconnect"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getBgpHoldTime() { + return data_center_interconnect_bgp_hold_time; + } + + public void setBgpHoldTime(String data_center_interconnect_bgp_hold_time) { + this.data_center_interconnect_bgp_hold_time = data_center_interconnect_bgp_hold_time; + } + + + public String getMode() { + return data_center_interconnect_mode; + } + + public void setMode(String data_center_interconnect_mode) { + this.data_center_interconnect_mode = data_center_interconnect_mode; + } + + + public String getBgpAddressFamilies() { + return data_center_interconnect_bgp_address_families; + } + + public void setBgpAddressFamilies(String data_center_interconnect_bgp_address_families) { + this.data_center_interconnect_bgp_address_families = data_center_interconnect_bgp_address_families; + } + + + public RouteTargetList getConfiguredRouteTargetList() { + return data_center_interconnect_configured_route_target_list; + } + + public void setConfiguredRouteTargetList(RouteTargetList data_center_interconnect_configured_route_target_list) { + this.data_center_interconnect_configured_route_target_list = data_center_interconnect_configured_route_target_list; + } + + + public String getType() { + return data_center_interconnect_type; + } + + public void setType(String data_center_interconnect_type) { + this.data_center_interconnect_type = data_center_interconnect_type; + } + + + public LogicalRouterPRListType getDestinationPhysicalRouterList() { + return destination_physical_router_list; + } + + public void setDestinationPhysicalRouterList(LogicalRouterPRListType destination_physical_router_list) { + this.destination_physical_router_list = destination_physical_router_list; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getLogicalRouter() { + return logical_router_refs; + } + + public void setLogicalRouter(LogicalRouter obj) { + logical_router_refs = new ArrayList>(); + logical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLogicalRouter(LogicalRouter obj) { + if (logical_router_refs == null) { + logical_router_refs = new ArrayList>(); + } + logical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLogicalRouter(LogicalRouter obj) { + if (logical_router_refs != null) { + logical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLogicalRouter() { + if (logical_router_refs != null) { + logical_router_refs.clear(); + return; + } + logical_router_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getRoutingPolicy() { + return routing_policy_refs; + } + + public void setRoutingPolicy(RoutingPolicy obj) { + routing_policy_refs = new ArrayList>(); + routing_policy_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addRoutingPolicy(RoutingPolicy obj) { + if (routing_policy_refs == null) { + routing_policy_refs = new ArrayList>(); + } + routing_policy_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeRoutingPolicy(RoutingPolicy obj) { + if (routing_policy_refs != null) { + routing_policy_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearRoutingPolicy() { + if (routing_policy_refs != null) { + routing_policy_refs.clear(); + return; + } + routing_policy_refs = null; + } + + public List> getFabric() { + return fabric_refs; + } + + public void setFabric(Fabric obj) { + fabric_refs = new ArrayList>(); + fabric_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFabric(Fabric obj) { + if (fabric_refs == null) { + fabric_refs = new ArrayList>(); + } + fabric_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFabric(Fabric obj) { + if (fabric_refs != null) { + fabric_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFabric() { + if (fabric_refs != null) { + fabric_refs.clear(); + return; + } + fabric_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DatabaseNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DatabaseNode.java new file mode 100644 index 00000000000..f5d90e0c85f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DatabaseNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DatabaseNode extends ApiObjectBase { + private String database_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "database-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return database_node_ip_address; + } + + public void setIpAddress(String database_node_ip_address) { + this.database_node_ip_address = database_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceChassis.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceChassis.java new file mode 100644 index 00000000000..8eefd1c98ec --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceChassis.java @@ -0,0 +1,116 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DeviceChassis extends ApiObjectBase { + private String device_chassis_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> physical_router_back_refs; + + @Override + public String getObjectType() { + return "device-chassis"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public String getType() { + return device_chassis_type; + } + + public void setType(String device_chassis_type) { + this.device_chassis_type = device_chassis_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceCredential.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceCredential.java new file mode 100644 index 00000000000..53e4e995975 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceCredential.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DeviceCredential extends ApiPropertyBase { + UserCredentials credential; + String vendor; + String device_family; + public DeviceCredential() { + } + public DeviceCredential(UserCredentials credential, String vendor, String device_family) { + this.credential = credential; + this.vendor = vendor; + this.device_family = device_family; + } + public DeviceCredential(UserCredentials credential) { + this(credential, null, null); } + public DeviceCredential(UserCredentials credential, String vendor) { + this(credential, vendor, null); } + + public UserCredentials getCredential() { + return credential; + } + + public void setCredential(UserCredentials credential) { + this.credential = credential; + } + + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + + public String getDeviceFamily() { + return device_family; + } + + public void setDeviceFamily(String device_family) { + this.device_family = device_family; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceCredentialList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceCredentialList.java new file mode 100644 index 00000000000..5afc1bb8c1c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceCredentialList.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DeviceCredentialList extends ApiPropertyBase { + List device_credential; + public DeviceCredentialList() { + } + public DeviceCredentialList(List device_credential) { + this.device_credential = device_credential; + } + + public List getDeviceCredential() { + return device_credential; + } + + + public void addDeviceCredential(DeviceCredential obj) { + if (device_credential == null) { + device_credential = new ArrayList(); + } + device_credential.add(obj); + } + public void clearDeviceCredential() { + device_credential = null; + } + + + public void addDeviceCredential(UserCredentials credential, String vendor, String device_family) { + if (device_credential == null) { + device_credential = new ArrayList(); + } + device_credential.add(new DeviceCredential(credential, vendor, device_family)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceFamilyListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceFamilyListType.java new file mode 100644 index 00000000000..3d8954d331b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceFamilyListType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DeviceFamilyListType extends ApiPropertyBase { + List device_family; + public DeviceFamilyListType() { + } + public DeviceFamilyListType(List device_family) { + this.device_family = device_family; + } + + public List getDeviceFamily() { + return device_family; + } + + + public void addDeviceFamily(String obj) { + if (device_family == null) { + device_family = new ArrayList(); + } + device_family.add(obj); + } + public void clearDeviceFamily() { + device_family = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceFunctionalGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceFunctionalGroup.java new file mode 100644 index 00000000000..b427eb16c39 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceFunctionalGroup.java @@ -0,0 +1,171 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DeviceFunctionalGroup extends ApiObjectBase { + private String device_functional_group_description; + private String device_functional_group_os_version; + private RoutingBridgingRolesType device_functional_group_routing_bridging_roles; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> physical_role_refs; + private List> tag_refs; + private transient List> physical_router_back_refs; + + @Override + public String getObjectType() { + return "device-functional-group"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getDescription() { + return device_functional_group_description; + } + + public void setDescription(String device_functional_group_description) { + this.device_functional_group_description = device_functional_group_description; + } + + + public String getOsVersion() { + return device_functional_group_os_version; + } + + public void setOsVersion(String device_functional_group_os_version) { + this.device_functional_group_os_version = device_functional_group_os_version; + } + + + public RoutingBridgingRolesType getRoutingBridgingRoles() { + return device_functional_group_routing_bridging_roles; + } + + public void setRoutingBridgingRoles(RoutingBridgingRolesType device_functional_group_routing_bridging_roles) { + this.device_functional_group_routing_bridging_roles = device_functional_group_routing_bridging_roles; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPhysicalRole() { + return physical_role_refs; + } + + public void setPhysicalRole(PhysicalRole obj) { + physical_role_refs = new ArrayList>(); + physical_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRole(PhysicalRole obj) { + if (physical_role_refs == null) { + physical_role_refs = new ArrayList>(); + } + physical_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRole(PhysicalRole obj) { + if (physical_role_refs != null) { + physical_role_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRole() { + if (physical_role_refs != null) { + physical_role_refs.clear(); + return; + } + physical_role_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceImage.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceImage.java new file mode 100644 index 00000000000..f5840495d0f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DeviceImage.java @@ -0,0 +1,231 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DeviceImage extends ApiObjectBase { + private String device_image_file_name; + private String device_image_vendor_name; + private String device_image_device_family; + private DevicePlatformListType device_image_supported_platforms; + private String device_image_os_version; + private String device_image_file_uri; + private Integer device_image_size; + private String device_image_md5; + private String device_image_sha1; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> hardware_refs; + private List> tag_refs; + private transient List> physical_router_back_refs; + + @Override + public String getObjectType() { + return "device-image"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getFileName() { + return device_image_file_name; + } + + public void setFileName(String device_image_file_name) { + this.device_image_file_name = device_image_file_name; + } + + + public String getVendorName() { + return device_image_vendor_name; + } + + public void setVendorName(String device_image_vendor_name) { + this.device_image_vendor_name = device_image_vendor_name; + } + + + public String getDeviceFamily() { + return device_image_device_family; + } + + public void setDeviceFamily(String device_image_device_family) { + this.device_image_device_family = device_image_device_family; + } + + + public DevicePlatformListType getSupportedPlatforms() { + return device_image_supported_platforms; + } + + public void setSupportedPlatforms(DevicePlatformListType device_image_supported_platforms) { + this.device_image_supported_platforms = device_image_supported_platforms; + } + + + public String getOsVersion() { + return device_image_os_version; + } + + public void setOsVersion(String device_image_os_version) { + this.device_image_os_version = device_image_os_version; + } + + + public String getFileUri() { + return device_image_file_uri; + } + + public void setFileUri(String device_image_file_uri) { + this.device_image_file_uri = device_image_file_uri; + } + + + public Integer getSize() { + return device_image_size; + } + + public void setSize(Integer device_image_size) { + this.device_image_size = device_image_size; + } + + + public String getMd5() { + return device_image_md5; + } + + public void setMd5(String device_image_md5) { + this.device_image_md5 = device_image_md5; + } + + + public String getSha1() { + return device_image_sha1; + } + + public void setSha1(String device_image_sha1) { + this.device_image_sha1 = device_image_sha1; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getHardware() { + return hardware_refs; + } + + public void setHardware(Hardware obj) { + hardware_refs = new ArrayList>(); + hardware_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addHardware(Hardware obj) { + if (hardware_refs == null) { + hardware_refs = new ArrayList>(); + } + hardware_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeHardware(Hardware obj) { + if (hardware_refs != null) { + hardware_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearHardware() { + if (hardware_refs != null) { + hardware_refs.clear(); + return; + } + hardware_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DevicePlatformListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DevicePlatformListType.java new file mode 100644 index 00000000000..646c7db8872 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DevicePlatformListType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DevicePlatformListType extends ApiPropertyBase { + List platform_name; + public DevicePlatformListType() { + } + public DevicePlatformListType(List platform_name) { + this.platform_name = platform_name; + } + + public List getPlatformName() { + return platform_name; + } + + + public void addPlatformName(String obj) { + if (platform_name == null) { + platform_name = new ArrayList(); + } + platform_name.add(obj); + } + public void clearPlatformName() { + platform_name = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DevicemgrNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DevicemgrNode.java new file mode 100644 index 00000000000..0b9f8218e13 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DevicemgrNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DevicemgrNode extends ApiObjectBase { + private String devicemgr_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "devicemgr-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return devicemgr_node_ip_address; + } + + public void setIpAddress(String devicemgr_node_ip_address) { + this.devicemgr_node_ip_address = devicemgr_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DhcpOptionType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DhcpOptionType.java new file mode 100644 index 00000000000..358749c6d54 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DhcpOptionType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DhcpOptionType extends ApiPropertyBase { + String dhcp_option_name; + String dhcp_option_value; + String dhcp_option_value_bytes; + public DhcpOptionType() { + } + public DhcpOptionType(String dhcp_option_name, String dhcp_option_value, String dhcp_option_value_bytes) { + this.dhcp_option_name = dhcp_option_name; + this.dhcp_option_value = dhcp_option_value; + this.dhcp_option_value_bytes = dhcp_option_value_bytes; + } + public DhcpOptionType(String dhcp_option_name) { + this(dhcp_option_name, null, null); } + public DhcpOptionType(String dhcp_option_name, String dhcp_option_value) { + this(dhcp_option_name, dhcp_option_value, null); } + + public String getDhcpOptionName() { + return dhcp_option_name; + } + + public void setDhcpOptionName(String dhcp_option_name) { + this.dhcp_option_name = dhcp_option_name; + } + + + public String getDhcpOptionValue() { + return dhcp_option_value; + } + + public void setDhcpOptionValue(String dhcp_option_value) { + this.dhcp_option_value = dhcp_option_value; + } + + + public String getDhcpOptionValueBytes() { + return dhcp_option_value_bytes; + } + + public void setDhcpOptionValueBytes(String dhcp_option_value_bytes) { + this.dhcp_option_value_bytes = dhcp_option_value_bytes; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DhcpOptionsListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DhcpOptionsListType.java new file mode 100644 index 00000000000..747b0e21cd5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DhcpOptionsListType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DhcpOptionsListType extends ApiPropertyBase { + List dhcp_option; + public DhcpOptionsListType() { + } + public DhcpOptionsListType(List dhcp_option) { + this.dhcp_option = dhcp_option; + } + + public List getDhcpOption() { + return dhcp_option; + } + + + public void addDhcpOption(DhcpOptionType obj) { + if (dhcp_option == null) { + dhcp_option = new ArrayList(); + } + dhcp_option.add(obj); + } + public void clearDhcpOption() { + dhcp_option = null; + } + + + public void addDhcpOption(String dhcp_option_name, String dhcp_option_value, String dhcp_option_value_bytes) { + if (dhcp_option == null) { + dhcp_option = new ArrayList(); + } + dhcp_option.add(new DhcpOptionType(dhcp_option_name, dhcp_option_value, dhcp_option_value_bytes)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryPubSubEndPointType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryPubSubEndPointType.java new file mode 100644 index 00000000000..f9d6ccde46d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryPubSubEndPointType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DiscoveryPubSubEndPointType extends ApiPropertyBase { + String ep_type; + String ep_id; + SubnetType ep_prefix; + String ep_version; + public DiscoveryPubSubEndPointType() { + } + public DiscoveryPubSubEndPointType(String ep_type, String ep_id, SubnetType ep_prefix, String ep_version) { + this.ep_type = ep_type; + this.ep_id = ep_id; + this.ep_prefix = ep_prefix; + this.ep_version = ep_version; + } + public DiscoveryPubSubEndPointType(String ep_type) { + this(ep_type, null, null, null); } + public DiscoveryPubSubEndPointType(String ep_type, String ep_id) { + this(ep_type, ep_id, null, null); } + public DiscoveryPubSubEndPointType(String ep_type, String ep_id, SubnetType ep_prefix) { + this(ep_type, ep_id, ep_prefix, null); } + + public String getEpType() { + return ep_type; + } + + public void setEpType(String ep_type) { + this.ep_type = ep_type; + } + + + public String getEpId() { + return ep_id; + } + + public void setEpId(String ep_id) { + this.ep_id = ep_id; + } + + + public SubnetType getEpPrefix() { + return ep_prefix; + } + + public void setEpPrefix(SubnetType ep_prefix) { + this.ep_prefix = ep_prefix; + } + + + public String getEpVersion() { + return ep_version; + } + + public void setEpVersion(String ep_version) { + this.ep_version = ep_version; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryServiceAssignment.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryServiceAssignment.java new file mode 100644 index 00000000000..3828571c732 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryServiceAssignment.java @@ -0,0 +1,106 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DiscoveryServiceAssignment extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> dsa_rules; + private List> tag_refs; + + @Override + public String getObjectType() { + return "discovery-service-assignment"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getDsaRules() { + return dsa_rules; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryServiceAssignmentType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryServiceAssignmentType.java new file mode 100644 index 00000000000..b5847277142 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DiscoveryServiceAssignmentType.java @@ -0,0 +1,55 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DiscoveryServiceAssignmentType extends ApiPropertyBase { + DiscoveryPubSubEndPointType publisher; + List subscriber; + public DiscoveryServiceAssignmentType() { + } + public DiscoveryServiceAssignmentType(DiscoveryPubSubEndPointType publisher, List subscriber) { + this.publisher = publisher; + this.subscriber = subscriber; + } + public DiscoveryServiceAssignmentType(DiscoveryPubSubEndPointType publisher) { + this(publisher, null); } + + public DiscoveryPubSubEndPointType getPublisher() { + return publisher; + } + + public void setPublisher(DiscoveryPubSubEndPointType publisher) { + this.publisher = publisher; + } + + + public List getSubscriber() { + return subscriber; + } + + + public void addSubscriber(DiscoveryPubSubEndPointType obj) { + if (subscriber == null) { + subscriber = new ArrayList(); + } + subscriber.add(obj); + } + public void clearSubscriber() { + subscriber = null; + } + + + public void addSubscriber(String ep_type, String ep_id, SubnetType ep_prefix, String ep_version) { + if (subscriber == null) { + subscriber = new ArrayList(); + } + subscriber.add(new DiscoveryPubSubEndPointType(ep_type, ep_id, ep_prefix, ep_version)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DnsSoaRecordType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DnsSoaRecordType.java new file mode 100644 index 00000000000..f3dd57719f8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DnsSoaRecordType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DnsSoaRecordType extends ApiPropertyBase { + Integer negative_cache_ttl_seconds; + public DnsSoaRecordType() { + } + public DnsSoaRecordType(Integer negative_cache_ttl_seconds) { + this.negative_cache_ttl_seconds = negative_cache_ttl_seconds; + } + + public Integer getNegativeCacheTtlSeconds() { + return negative_cache_ttl_seconds; + } + + public void setNegativeCacheTtlSeconds(Integer negative_cache_ttl_seconds) { + this.negative_cache_ttl_seconds = negative_cache_ttl_seconds; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DnsmasqLeaseParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DnsmasqLeaseParameters.java new file mode 100644 index 00000000000..3681f04b8b1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DnsmasqLeaseParameters.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DnsmasqLeaseParameters extends ApiPropertyBase { + Integer lease_expiry_time; + String client_id; + public DnsmasqLeaseParameters() { + } + public DnsmasqLeaseParameters(Integer lease_expiry_time, String client_id) { + this.lease_expiry_time = lease_expiry_time; + this.client_id = client_id; + } + public DnsmasqLeaseParameters(Integer lease_expiry_time) { + this(lease_expiry_time, null); } + + public Integer getLeaseExpiryTime() { + return lease_expiry_time; + } + + public void setLeaseExpiryTime(Integer lease_expiry_time) { + this.lease_expiry_time = lease_expiry_time; + } + + + public String getClientId() { + return client_id; + } + + public void setClientId(String client_id) { + this.client_id = client_id; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Domain.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Domain.java new file mode 100644 index 00000000000..b498f7e9198 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Domain.java @@ -0,0 +1,140 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Domain extends ApiObjectBase { + private DomainLimitsType domain_limits; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> projects; + private List> namespaces; + private List> service_templates; + private List> virtual_DNSs; + private List> api_access_lists; + private List> tag_refs; + + @Override + public String getObjectType() { + return "domain"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return "config-root"; + } + + public void setParent(ConfigRoot parent) { + super.setParent(parent); + } + + public DomainLimitsType getLimits() { + return domain_limits; + } + + public void setLimits(DomainLimitsType domain_limits) { + this.domain_limits = domain_limits; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getProjects() { + return projects; + } + + public List> getNamespaces() { + return namespaces; + } + + public List> getServiceTemplates() { + return service_templates; + } + + public List> getVirtualDnss() { + return virtual_DNSs; + } + + public List> getApiAccessLists() { + return api_access_lists; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DomainLimitsType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DomainLimitsType.java new file mode 100644 index 00000000000..c9fa72dd07b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DomainLimitsType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DomainLimitsType extends ApiPropertyBase { + Integer project_limit; + Integer virtual_network_limit; + Integer security_group_limit; + public DomainLimitsType() { + } + public DomainLimitsType(Integer project_limit, Integer virtual_network_limit, Integer security_group_limit) { + this.project_limit = project_limit; + this.virtual_network_limit = virtual_network_limit; + this.security_group_limit = security_group_limit; + } + public DomainLimitsType(Integer project_limit) { + this(project_limit, null, null); } + public DomainLimitsType(Integer project_limit, Integer virtual_network_limit) { + this(project_limit, virtual_network_limit, null); } + + public Integer getProjectLimit() { + return project_limit; + } + + public void setProjectLimit(Integer project_limit) { + this.project_limit = project_limit; + } + + + public Integer getVirtualNetworkLimit() { + return virtual_network_limit; + } + + public void setVirtualNetworkLimit(Integer virtual_network_limit) { + this.virtual_network_limit = virtual_network_limit; + } + + + public Integer getSecurityGroupLimit() { + return security_group_limit; + } + + public void setSecurityGroupLimit(Integer security_group_limit) { + this.security_group_limit = security_group_limit; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DriverInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DriverInfo.java new file mode 100644 index 00000000000..9ea560289b7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DriverInfo.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class DriverInfo extends ApiPropertyBase { + String ipmi_address; + String deploy_ramdisk; + String ipmi_password; + String ipmi_port; + String ipmi_username; + String deploy_kernel; + public DriverInfo() { + } + public DriverInfo(String ipmi_address, String deploy_ramdisk, String ipmi_password, String ipmi_port, String ipmi_username, String deploy_kernel) { + this.ipmi_address = ipmi_address; + this.deploy_ramdisk = deploy_ramdisk; + this.ipmi_password = ipmi_password; + this.ipmi_port = ipmi_port; + this.ipmi_username = ipmi_username; + this.deploy_kernel = deploy_kernel; + } + public DriverInfo(String ipmi_address) { + this(ipmi_address, null, null, null, null, null); } + public DriverInfo(String ipmi_address, String deploy_ramdisk) { + this(ipmi_address, deploy_ramdisk, null, null, null, null); } + public DriverInfo(String ipmi_address, String deploy_ramdisk, String ipmi_password) { + this(ipmi_address, deploy_ramdisk, ipmi_password, null, null, null); } + public DriverInfo(String ipmi_address, String deploy_ramdisk, String ipmi_password, String ipmi_port) { + this(ipmi_address, deploy_ramdisk, ipmi_password, ipmi_port, null, null); } + public DriverInfo(String ipmi_address, String deploy_ramdisk, String ipmi_password, String ipmi_port, String ipmi_username) { + this(ipmi_address, deploy_ramdisk, ipmi_password, ipmi_port, ipmi_username, null); } + + public String getIpmiAddress() { + return ipmi_address; + } + + public void setIpmiAddress(String ipmi_address) { + this.ipmi_address = ipmi_address; + } + + + public String getDeployRamdisk() { + return deploy_ramdisk; + } + + public void setDeployRamdisk(String deploy_ramdisk) { + this.deploy_ramdisk = deploy_ramdisk; + } + + + public String getIpmiPassword() { + return ipmi_password; + } + + public void setIpmiPassword(String ipmi_password) { + this.ipmi_password = ipmi_password; + } + + + public String getIpmiPort() { + return ipmi_port; + } + + public void setIpmiPort(String ipmi_port) { + this.ipmi_port = ipmi_port; + } + + + public String getIpmiUsername() { + return ipmi_username; + } + + public void setIpmiUsername(String ipmi_username) { + this.ipmi_username = ipmi_username; + } + + + public String getDeployKernel() { + return deploy_kernel; + } + + public void setDeployKernel(String deploy_kernel) { + this.deploy_kernel = deploy_kernel; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DsaRule.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DsaRule.java new file mode 100644 index 00000000000..274a10e4db1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/DsaRule.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class DsaRule extends ApiObjectBase { + private DiscoveryServiceAssignmentType dsa_rule_entry; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "dsa-rule"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-discovery-service-assignment"); + } + + @Override + public String getDefaultParentType() { + return "discovery-service-assignment"; + } + + public void setParent(DiscoveryServiceAssignment parent) { + super.setParent(parent); + } + + public DiscoveryServiceAssignmentType getEntry() { + return dsa_rule_entry; + } + + public void setEntry(DiscoveryServiceAssignmentType dsa_rule_entry) { + this.dsa_rule_entry = dsa_rule_entry; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/E2ServiceProvider.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/E2ServiceProvider.java new file mode 100644 index 00000000000..b5b15e97afd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/E2ServiceProvider.java @@ -0,0 +1,173 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class E2ServiceProvider extends ApiObjectBase { + private Boolean e2_service_provider_promiscuous; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> peering_policy_refs; + private List> physical_router_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "e2-service-provider"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public Boolean getPromiscuous() { + return e2_service_provider_promiscuous; + } + + public void setPromiscuous(Boolean e2_service_provider_promiscuous) { + this.e2_service_provider_promiscuous = e2_service_provider_promiscuous; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPeeringPolicy() { + return peering_policy_refs; + } + + public void setPeeringPolicy(PeeringPolicy obj) { + peering_policy_refs = new ArrayList>(); + peering_policy_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPeeringPolicy(PeeringPolicy obj) { + if (peering_policy_refs == null) { + peering_policy_refs = new ArrayList>(); + } + peering_policy_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePeeringPolicy(PeeringPolicy obj) { + if (peering_policy_refs != null) { + peering_policy_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPeeringPolicy() { + if (peering_policy_refs != null) { + peering_policy_refs.clear(); + return; + } + peering_policy_refs = null; + } + + public List> getPhysicalRouter() { + return physical_router_refs; + } + + public void setPhysicalRouter(PhysicalRouter obj) { + physical_router_refs = new ArrayList>(); + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs == null) { + physical_router_refs = new ArrayList>(); + } + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs != null) { + physical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRouter() { + if (physical_router_refs != null) { + physical_router_refs.clear(); + return; + } + physical_router_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ESXIHostInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ESXIHostInfo.java new file mode 100644 index 00000000000..6437461b2c2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ESXIHostInfo.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ESXIHostInfo extends ApiPropertyBase { + String username; + String datacenter; + String esxi_name; + String cluster; + String mac; + String datastore; + String password; + String vcenter_server; + public ESXIHostInfo() { + } + public ESXIHostInfo(String username, String datacenter, String esxi_name, String cluster, String mac, String datastore, String password, String vcenter_server) { + this.username = username; + this.datacenter = datacenter; + this.esxi_name = esxi_name; + this.cluster = cluster; + this.mac = mac; + this.datastore = datastore; + this.password = password; + this.vcenter_server = vcenter_server; + } + public ESXIHostInfo(String username) { + this(username, null, null, null, null, null, null, null); } + public ESXIHostInfo(String username, String datacenter) { + this(username, datacenter, null, null, null, null, null, null); } + public ESXIHostInfo(String username, String datacenter, String esxi_name) { + this(username, datacenter, esxi_name, null, null, null, null, null); } + public ESXIHostInfo(String username, String datacenter, String esxi_name, String cluster) { + this(username, datacenter, esxi_name, cluster, null, null, null, null); } + public ESXIHostInfo(String username, String datacenter, String esxi_name, String cluster, String mac) { + this(username, datacenter, esxi_name, cluster, mac, null, null, null); } + public ESXIHostInfo(String username, String datacenter, String esxi_name, String cluster, String mac, String datastore) { + this(username, datacenter, esxi_name, cluster, mac, datastore, null, null); } + public ESXIHostInfo(String username, String datacenter, String esxi_name, String cluster, String mac, String datastore, String password) { + this(username, datacenter, esxi_name, cluster, mac, datastore, password, null); } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + + public String getDatacenter() { + return datacenter; + } + + public void setDatacenter(String datacenter) { + this.datacenter = datacenter; + } + + + public String getEsxiName() { + return esxi_name; + } + + public void setEsxiName(String esxi_name) { + this.esxi_name = esxi_name; + } + + + public String getCluster() { + return cluster; + } + + public void setCluster(String cluster) { + this.cluster = cluster; + } + + + public String getMac() { + return mac; + } + + public void setMac(String mac) { + this.mac = mac; + } + + + public String getDatastore() { + return datastore; + } + + public void setDatastore(String datastore) { + this.datastore = datastore; + } + + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + + public String getVcenterServer() { + return vcenter_server; + } + + public void setVcenterServer(String vcenter_server) { + this.vcenter_server = vcenter_server; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ESXIProperties.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ESXIProperties.java new file mode 100644 index 00000000000..4c60bca2f22 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ESXIProperties.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ESXIProperties extends ApiPropertyBase { + String dvs_name; + String dvs_id; + public ESXIProperties() { + } + public ESXIProperties(String dvs_name, String dvs_id) { + this.dvs_name = dvs_name; + this.dvs_id = dvs_id; + } + public ESXIProperties(String dvs_name) { + this(dvs_name, null); } + + public String getDvsName() { + return dvs_name; + } + + public void setDvsName(String dvs_name) { + this.dvs_name = dvs_name; + } + + + public String getDvsId() { + return dvs_id; + } + + public void setDvsId(String dvs_id) { + this.dvs_id = dvs_id; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EcmpHashingIncludeFields.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EcmpHashingIncludeFields.java new file mode 100644 index 00000000000..bda16d4caca --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EcmpHashingIncludeFields.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class EcmpHashingIncludeFields extends ApiPropertyBase { + Boolean hashing_configured; + Boolean source_ip; + Boolean destination_ip; + Boolean ip_protocol; + Boolean source_port; + Boolean destination_port; + public EcmpHashingIncludeFields() { + } + public EcmpHashingIncludeFields(Boolean hashing_configured, Boolean source_ip, Boolean destination_ip, Boolean ip_protocol, Boolean source_port, Boolean destination_port) { + this.hashing_configured = hashing_configured; + this.source_ip = source_ip; + this.destination_ip = destination_ip; + this.ip_protocol = ip_protocol; + this.source_port = source_port; + this.destination_port = destination_port; + } + public EcmpHashingIncludeFields(Boolean hashing_configured) { + this(hashing_configured, true, true, true, true, true); } + public EcmpHashingIncludeFields(Boolean hashing_configured, Boolean source_ip) { + this(hashing_configured, source_ip, true, true, true, true); } + public EcmpHashingIncludeFields(Boolean hashing_configured, Boolean source_ip, Boolean destination_ip) { + this(hashing_configured, source_ip, destination_ip, true, true, true); } + public EcmpHashingIncludeFields(Boolean hashing_configured, Boolean source_ip, Boolean destination_ip, Boolean ip_protocol) { + this(hashing_configured, source_ip, destination_ip, ip_protocol, true, true); } + public EcmpHashingIncludeFields(Boolean hashing_configured, Boolean source_ip, Boolean destination_ip, Boolean ip_protocol, Boolean source_port) { + this(hashing_configured, source_ip, destination_ip, ip_protocol, source_port, true); } + + public Boolean getHashingConfigured() { + return hashing_configured; + } + + public void setHashingConfigured(Boolean hashing_configured) { + this.hashing_configured = hashing_configured; + } + + + public Boolean getSourceIp() { + return source_ip; + } + + public void setSourceIp(Boolean source_ip) { + this.source_ip = source_ip; + } + + + public Boolean getDestinationIp() { + return destination_ip; + } + + public void setDestinationIp(Boolean destination_ip) { + this.destination_ip = destination_ip; + } + + + public Boolean getIpProtocol() { + return ip_protocol; + } + + public void setIpProtocol(Boolean ip_protocol) { + this.ip_protocol = ip_protocol; + } + + + public Boolean getSourcePort() { + return source_port; + } + + public void setSourcePort(Boolean source_port) { + this.source_port = source_port; + } + + + public Boolean getDestinationPort() { + return destination_port; + } + + public void setDestinationPort(Boolean destination_port) { + this.destination_port = destination_port; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EnabledInterfaceParams.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EnabledInterfaceParams.java new file mode 100644 index 00000000000..83a64c833b7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EnabledInterfaceParams.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class EnabledInterfaceParams extends ApiPropertyBase { + String name; + StatsCollectionFrequency stats_collection_frequency; + public EnabledInterfaceParams() { + } + public EnabledInterfaceParams(String name, StatsCollectionFrequency stats_collection_frequency) { + this.name = name; + this.stats_collection_frequency = stats_collection_frequency; + } + public EnabledInterfaceParams(String name) { + this(name, null); } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public StatsCollectionFrequency getStatsCollectionFrequency() { + return stats_collection_frequency; + } + + public void setStatsCollectionFrequency(StatsCollectionFrequency stats_collection_frequency) { + this.stats_collection_frequency = stats_collection_frequency; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EnabledSensorParams.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EnabledSensorParams.java new file mode 100644 index 00000000000..dd72f752550 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EnabledSensorParams.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class EnabledSensorParams extends ApiPropertyBase { + Boolean physical_health; + Boolean interface_health; + Boolean control_plane_health; + Boolean service_layer_health; + public EnabledSensorParams() { + } + public EnabledSensorParams(Boolean physical_health, Boolean interface_health, Boolean control_plane_health, Boolean service_layer_health) { + this.physical_health = physical_health; + this.interface_health = interface_health; + this.control_plane_health = control_plane_health; + this.service_layer_health = service_layer_health; + } + public EnabledSensorParams(Boolean physical_health) { + this(physical_health, true, true, true); } + public EnabledSensorParams(Boolean physical_health, Boolean interface_health) { + this(physical_health, interface_health, true, true); } + public EnabledSensorParams(Boolean physical_health, Boolean interface_health, Boolean control_plane_health) { + this(physical_health, interface_health, control_plane_health, true); } + + public Boolean getPhysicalHealth() { + return physical_health; + } + + public void setPhysicalHealth(Boolean physical_health) { + this.physical_health = physical_health; + } + + + public Boolean getInterfaceHealth() { + return interface_health; + } + + public void setInterfaceHealth(Boolean interface_health) { + this.interface_health = interface_health; + } + + + public Boolean getControlPlaneHealth() { + return control_plane_health; + } + + public void setControlPlaneHealth(Boolean control_plane_health) { + this.control_plane_health = control_plane_health; + } + + + public Boolean getServiceLayerHealth() { + return service_layer_health; + } + + public void setServiceLayerHealth(Boolean service_layer_health) { + this.service_layer_health = service_layer_health; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncapsulationPrioritiesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncapsulationPrioritiesType.java new file mode 100644 index 00000000000..01a33b080c8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncapsulationPrioritiesType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class EncapsulationPrioritiesType extends ApiPropertyBase { + List encapsulation; + public EncapsulationPrioritiesType() { + } + public EncapsulationPrioritiesType(List encapsulation) { + this.encapsulation = encapsulation; + } + + public List getEncapsulation() { + return encapsulation; + } + + + public void addEncapsulation(String obj) { + if (encapsulation == null) { + encapsulation = new ArrayList(); + } + encapsulation.add(obj); + } + public void clearEncapsulation() { + encapsulation = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncryptionTunnelEndpoint.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncryptionTunnelEndpoint.java new file mode 100644 index 00000000000..4c20547cff4 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncryptionTunnelEndpoint.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class EncryptionTunnelEndpoint extends ApiPropertyBase { + String tunnel_remote_ip_address; + public EncryptionTunnelEndpoint() { + } + public EncryptionTunnelEndpoint(String tunnel_remote_ip_address) { + this.tunnel_remote_ip_address = tunnel_remote_ip_address; + } + + public String getTunnelRemoteIpAddress() { + return tunnel_remote_ip_address; + } + + public void setTunnelRemoteIpAddress(String tunnel_remote_ip_address) { + this.tunnel_remote_ip_address = tunnel_remote_ip_address; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncryptionTunnelEndpointList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncryptionTunnelEndpointList.java new file mode 100644 index 00000000000..96ac78349f2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/EncryptionTunnelEndpointList.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class EncryptionTunnelEndpointList extends ApiPropertyBase { + List endpoint; + public EncryptionTunnelEndpointList() { + } + public EncryptionTunnelEndpointList(List endpoint) { + this.endpoint = endpoint; + } + + public List getEndpoint() { + return endpoint; + } + + + public void addEndpoint(EncryptionTunnelEndpoint obj) { + if (endpoint == null) { + endpoint = new ArrayList(); + } + endpoint.add(obj); + } + public void clearEndpoint() { + endpoint = null; + } + + + public void addEndpoint(String tunnel_remote_ip_address) { + if (endpoint == null) { + endpoint = new ArrayList(); + } + endpoint.add(new EncryptionTunnelEndpoint(tunnel_remote_ip_address)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ExecutableInfoListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ExecutableInfoListType.java new file mode 100644 index 00000000000..94a9e9a3a8b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ExecutableInfoListType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ExecutableInfoListType extends ApiPropertyBase { + List executable_info; + public ExecutableInfoListType() { + } + public ExecutableInfoListType(List executable_info) { + this.executable_info = executable_info; + } + + public List getExecutableInfo() { + return executable_info; + } + + + public void addExecutableInfo(ExecutableInfoType obj) { + if (executable_info == null) { + executable_info = new ArrayList(); + } + executable_info.add(obj); + } + public void clearExecutableInfo() { + executable_info = null; + } + + + public void addExecutableInfo(String executable_path, String executable_args, Integer job_completion_weightage) { + if (executable_info == null) { + executable_info = new ArrayList(); + } + executable_info.add(new ExecutableInfoType(executable_path, executable_args, job_completion_weightage)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ExecutableInfoType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ExecutableInfoType.java new file mode 100644 index 00000000000..3d814a9f5dc --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ExecutableInfoType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ExecutableInfoType extends ApiPropertyBase { + String executable_path; + String executable_args; + Integer job_completion_weightage; + public ExecutableInfoType() { + } + public ExecutableInfoType(String executable_path, String executable_args, Integer job_completion_weightage) { + this.executable_path = executable_path; + this.executable_args = executable_args; + this.job_completion_weightage = job_completion_weightage; + } + public ExecutableInfoType(String executable_path) { + this(executable_path, null, 100); } + public ExecutableInfoType(String executable_path, String executable_args) { + this(executable_path, executable_args, 100); } + + public String getExecutablePath() { + return executable_path; + } + + public void setExecutablePath(String executable_path) { + this.executable_path = executable_path; + } + + + public String getExecutableArgs() { + return executable_args; + } + + public void setExecutableArgs(String executable_args) { + this.executable_args = executable_args; + } + + + public Integer getJobCompletionWeightage() { + return job_completion_weightage; + } + + public void setJobCompletionWeightage(Integer job_completion_weightage) { + this.job_completion_weightage = job_completion_weightage; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Fabric.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Fabric.java new file mode 100644 index 00000000000..e3e869299fd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Fabric.java @@ -0,0 +1,275 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Fabric extends ApiObjectBase { + private Boolean fabric_ztp; + private String fabric_os_version; + private DeviceCredentialList fabric_credentials; + private Boolean fabric_enterprise_style; + private Boolean disable_vlan_vn_uniqueness_check; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> intent_map_refs; + private List> virtual_network_refs; + private List> fabric_namespaces; + private List> node_profile_refs; + private List> virtual_port_groups; + private List> tag_refs; + private transient List> logical_router_back_refs; + private transient List> data_center_interconnect_back_refs; + private transient List> physical_router_back_refs; + + @Override + public String getObjectType() { + return "fabric"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public Boolean getZtp() { + return fabric_ztp; + } + + public void setZtp(Boolean fabric_ztp) { + this.fabric_ztp = fabric_ztp; + } + + + public String getOsVersion() { + return fabric_os_version; + } + + public void setOsVersion(String fabric_os_version) { + this.fabric_os_version = fabric_os_version; + } + + + public DeviceCredentialList getCredentials() { + return fabric_credentials; + } + + public void setCredentials(DeviceCredentialList fabric_credentials) { + this.fabric_credentials = fabric_credentials; + } + + + public Boolean getEnterpriseStyle() { + return fabric_enterprise_style; + } + + public void setEnterpriseStyle(Boolean fabric_enterprise_style) { + this.fabric_enterprise_style = fabric_enterprise_style; + } + + + public Boolean getDisableVlanVnUniquenessCheck() { + return disable_vlan_vn_uniqueness_check; + } + + public void setDisableVlanVnUniquenessCheck(Boolean disable_vlan_vn_uniqueness_check) { + this.disable_vlan_vn_uniqueness_check = disable_vlan_vn_uniqueness_check; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getIntentMap() { + return intent_map_refs; + } + + public void setIntentMap(IntentMap obj) { + intent_map_refs = new ArrayList>(); + intent_map_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addIntentMap(IntentMap obj) { + if (intent_map_refs == null) { + intent_map_refs = new ArrayList>(); + } + intent_map_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeIntentMap(IntentMap obj) { + if (intent_map_refs != null) { + intent_map_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearIntentMap() { + if (intent_map_refs != null) { + intent_map_refs.clear(); + return; + } + intent_map_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj, FabricNetworkTag data) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addVirtualNetwork(VirtualNetwork obj, FabricNetworkTag data) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeVirtualNetwork(VirtualNetwork obj, FabricNetworkTag data) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + + public List> getFabricNamespaces() { + return fabric_namespaces; + } + + public List> getNodeProfile() { + return node_profile_refs; + } + + public void setNodeProfile(NodeProfile obj, SerialNumListType data) { + node_profile_refs = new ArrayList>(); + node_profile_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addNodeProfile(NodeProfile obj, SerialNumListType data) { + if (node_profile_refs == null) { + node_profile_refs = new ArrayList>(); + } + node_profile_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeNodeProfile(NodeProfile obj, SerialNumListType data) { + if (node_profile_refs != null) { + node_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearNodeProfile() { + if (node_profile_refs != null) { + node_profile_refs.clear(); + return; + } + node_profile_refs = null; + } + + + public List> getVirtualPortGroups() { + return virtual_port_groups; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } + + public List> getDataCenterInterconnectBackRefs() { + return data_center_interconnect_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FabricNamespace.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FabricNamespace.java new file mode 100644 index 00000000000..f7f44b3980b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FabricNamespace.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FabricNamespace extends ApiObjectBase { + private String fabric_namespace_type; + private NamespaceValue fabric_namespace_value; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "fabric-namespace"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-fabric"); + } + + @Override + public String getDefaultParentType() { + return "fabric"; + } + + public void setParent(Fabric parent) { + super.setParent(parent); + } + + public String getType() { + return fabric_namespace_type; + } + + public void setType(String fabric_namespace_type) { + this.fabric_namespace_type = fabric_namespace_type; + } + + + public NamespaceValue getValue() { + return fabric_namespace_value; + } + + public void setValue(NamespaceValue fabric_namespace_value) { + this.fabric_namespace_value = fabric_namespace_value; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FabricNetworkTag.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FabricNetworkTag.java new file mode 100644 index 00000000000..dc850fcff22 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FabricNetworkTag.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FabricNetworkTag extends ApiPropertyBase { + String network_type; + public FabricNetworkTag() { + } + public FabricNetworkTag(String network_type) { + this.network_type = network_type; + } + + public String getNetworkType() { + return network_type; + } + + public void setNetworkType(String network_type) { + this.network_type = network_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FastConvergenceParametersType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FastConvergenceParametersType.java new file mode 100644 index 00000000000..a043ff12a1d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FastConvergenceParametersType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FastConvergenceParametersType extends ApiPropertyBase { + Boolean enable; + Boolean nh_reachability_check; + Integer xmpp_hold_time; + public FastConvergenceParametersType() { + } + public FastConvergenceParametersType(Boolean enable, Boolean nh_reachability_check, Integer xmpp_hold_time) { + this.enable = enable; + this.nh_reachability_check = nh_reachability_check; + this.xmpp_hold_time = xmpp_hold_time; + } + public FastConvergenceParametersType(Boolean enable) { + this(enable, false, 90); } + public FastConvergenceParametersType(Boolean enable, Boolean nh_reachability_check) { + this(enable, nh_reachability_check, 90); } + + public Boolean getEnable() { + return enable; + } + + public void setEnable(Boolean enable) { + this.enable = enable; + } + + + public Boolean getNhReachabilityCheck() { + return nh_reachability_check; + } + + public void setNhReachabilityCheck(Boolean nh_reachability_check) { + this.nh_reachability_check = nh_reachability_check; + } + + + public Integer getXmppHoldTime() { + return xmpp_hold_time; + } + + public void setXmppHoldTime(Integer xmpp_hold_time) { + this.xmpp_hold_time = xmpp_hold_time; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FatFlowProtocols.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FatFlowProtocols.java new file mode 100644 index 00000000000..f0b86f3a55f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FatFlowProtocols.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FatFlowProtocols extends ApiPropertyBase { + List fat_flow_protocol; + public FatFlowProtocols() { + } + public FatFlowProtocols(List fat_flow_protocol) { + this.fat_flow_protocol = fat_flow_protocol; + } + + public List getFatFlowProtocol() { + return fat_flow_protocol; + } + + + public void addFatFlowProtocol(ProtocolType obj) { + if (fat_flow_protocol == null) { + fat_flow_protocol = new ArrayList(); + } + fat_flow_protocol.add(obj); + } + public void clearFatFlowProtocol() { + fat_flow_protocol = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Feature.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Feature.java new file mode 100644 index 00000000000..41b466acda5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Feature.java @@ -0,0 +1,146 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Feature extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> feature_refs; + private List> tag_refs; + private transient List> feature_back_refs; + private transient List> role_definition_back_refs; + + @Override + public String getObjectType() { + return "feature"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getFeature() { + return feature_refs; + } + + public void setFeature(Feature obj) { + feature_refs = new ArrayList>(); + feature_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFeature(Feature obj) { + if (feature_refs == null) { + feature_refs = new ArrayList>(); + } + feature_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFeature(Feature obj) { + if (feature_refs != null) { + feature_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFeature() { + if (feature_refs != null) { + feature_refs.clear(); + return; + } + feature_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getFeatureBackRefs() { + return feature_back_refs; + } + + public List> getRoleDefinitionBackRefs() { + return role_definition_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FeatureConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FeatureConfig.java new file mode 100644 index 00000000000..358b46b3e88 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FeatureConfig.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FeatureConfig extends ApiObjectBase { + private KeyValuePairs feature_config_additional_params; + private KeyValuePairs feature_config_vendor_config; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "feature-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-role-definition"); + } + + @Override + public String getDefaultParentType() { + return "role-definition"; + } + + public void setParent(RoleDefinition parent) { + super.setParent(parent); + } + + public KeyValuePairs getAdditionalParams() { + return feature_config_additional_params; + } + + public void setAdditionalParams(KeyValuePairs feature_config_additional_params) { + this.feature_config_additional_params = feature_config_additional_params; + } + + + public KeyValuePairs getVendorConfig() { + return feature_config_vendor_config; + } + + public void setVendorConfig(KeyValuePairs feature_config_vendor_config) { + this.feature_config_vendor_config = feature_config_vendor_config; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallPolicy.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallPolicy.java new file mode 100644 index 00000000000..146160b92ac --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallPolicy.java @@ -0,0 +1,187 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FirewallPolicy extends ApiObjectBase { + private String draft_mode_state; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> firewall_rule_refs; + private List> security_logging_object_refs; + private List> tag_refs; + private transient List> application_policy_set_back_refs; + + @Override + public String getObjectType() { + return "firewall-policy"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(PolicyManagement parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getDraftModeState() { + return draft_mode_state; + } + + public void setDraftModeState(String draft_mode_state) { + this.draft_mode_state = draft_mode_state; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getFirewallRule() { + return firewall_rule_refs; + } + + public void setFirewallRule(FirewallRule obj, FirewallSequence data) { + firewall_rule_refs = new ArrayList>(); + firewall_rule_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addFirewallRule(FirewallRule obj, FirewallSequence data) { + if (firewall_rule_refs == null) { + firewall_rule_refs = new ArrayList>(); + } + firewall_rule_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeFirewallRule(FirewallRule obj, FirewallSequence data) { + if (firewall_rule_refs != null) { + firewall_rule_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearFirewallRule() { + if (firewall_rule_refs != null) { + firewall_rule_refs.clear(); + return; + } + firewall_rule_refs = null; + } + + + public List> getSecurityLoggingObject() { + return security_logging_object_refs; + } + + public void setSecurityLoggingObject(SecurityLoggingObject obj, SloRateType data) { + security_logging_object_refs = new ArrayList>(); + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addSecurityLoggingObject(SecurityLoggingObject obj, SloRateType data) { + if (security_logging_object_refs == null) { + security_logging_object_refs = new ArrayList>(); + } + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeSecurityLoggingObject(SecurityLoggingObject obj, SloRateType data) { + if (security_logging_object_refs != null) { + security_logging_object_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearSecurityLoggingObject() { + if (security_logging_object_refs != null) { + security_logging_object_refs.clear(); + return; + } + security_logging_object_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getApplicationPolicySetBackRefs() { + return application_policy_set_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRule.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRule.java new file mode 100644 index 00000000000..39f0aad43ee --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRule.java @@ -0,0 +1,318 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FirewallRule extends ApiObjectBase { + private String draft_mode_state; + private ActionListType action_list; + private FirewallServiceType service; + private FirewallRuleEndpointType endpoint_1; + private FirewallRuleEndpointType endpoint_2; + private FirewallRuleMatchTagsType match_tags; + private FirewallRuleMatchTagsTypeIdList match_tag_types; + private String direction; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_group_refs; + private List> address_group_refs; + private List> virtual_network_refs; + private List> security_logging_object_refs; + private List> tag_refs; + private transient List> firewall_policy_back_refs; + + @Override + public String getObjectType() { + return "firewall-rule"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(PolicyManagement parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getDraftModeState() { + return draft_mode_state; + } + + public void setDraftModeState(String draft_mode_state) { + this.draft_mode_state = draft_mode_state; + } + + + public ActionListType getActionList() { + return action_list; + } + + public void setActionList(ActionListType action_list) { + this.action_list = action_list; + } + + + public FirewallServiceType getService() { + return service; + } + + public void setService(FirewallServiceType service) { + this.service = service; + } + + + public FirewallRuleEndpointType getEndpoint1() { + return endpoint_1; + } + + public void setEndpoint1(FirewallRuleEndpointType endpoint_1) { + this.endpoint_1 = endpoint_1; + } + + + public FirewallRuleEndpointType getEndpoint2() { + return endpoint_2; + } + + public void setEndpoint2(FirewallRuleEndpointType endpoint_2) { + this.endpoint_2 = endpoint_2; + } + + + public FirewallRuleMatchTagsType getMatchTags() { + return match_tags; + } + + public void setMatchTags(FirewallRuleMatchTagsType match_tags) { + this.match_tags = match_tags; + } + + + public FirewallRuleMatchTagsTypeIdList getMatchTagTypes() { + return match_tag_types; + } + + public void setMatchTagTypes(FirewallRuleMatchTagsTypeIdList match_tag_types) { + this.match_tag_types = match_tag_types; + } + + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceGroup() { + return service_group_refs; + } + + public void setServiceGroup(ServiceGroup obj) { + service_group_refs = new ArrayList>(); + service_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceGroup(ServiceGroup obj) { + if (service_group_refs == null) { + service_group_refs = new ArrayList>(); + } + service_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceGroup(ServiceGroup obj) { + if (service_group_refs != null) { + service_group_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceGroup() { + if (service_group_refs != null) { + service_group_refs.clear(); + return; + } + service_group_refs = null; + } + + public List> getAddressGroup() { + return address_group_refs; + } + + public void setAddressGroup(AddressGroup obj) { + address_group_refs = new ArrayList>(); + address_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addAddressGroup(AddressGroup obj) { + if (address_group_refs == null) { + address_group_refs = new ArrayList>(); + } + address_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeAddressGroup(AddressGroup obj) { + if (address_group_refs != null) { + address_group_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearAddressGroup() { + if (address_group_refs != null) { + address_group_refs.clear(); + return; + } + address_group_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getSecurityLoggingObject() { + return security_logging_object_refs; + } + + public void setSecurityLoggingObject(SecurityLoggingObject obj, SloRateType data) { + security_logging_object_refs = new ArrayList>(); + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addSecurityLoggingObject(SecurityLoggingObject obj, SloRateType data) { + if (security_logging_object_refs == null) { + security_logging_object_refs = new ArrayList>(); + } + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeSecurityLoggingObject(SecurityLoggingObject obj, SloRateType data) { + if (security_logging_object_refs != null) { + security_logging_object_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearSecurityLoggingObject() { + if (security_logging_object_refs != null) { + security_logging_object_refs.clear(); + return; + } + security_logging_object_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getFirewallPolicyBackRefs() { + return firewall_policy_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleEndpointType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleEndpointType.java new file mode 100644 index 00000000000..92d82392425 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleEndpointType.java @@ -0,0 +1,106 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FirewallRuleEndpointType extends ApiPropertyBase { + SubnetType subnet; + String virtual_network; + String address_group; + List tags; + List tag_ids; + Boolean any; + public FirewallRuleEndpointType() { + } + public FirewallRuleEndpointType(SubnetType subnet, String virtual_network, String address_group, List tags, List tag_ids, Boolean any) { + this.subnet = subnet; + this.virtual_network = virtual_network; + this.address_group = address_group; + this.tags = tags; + this.tag_ids = tag_ids; + this.any = any; + } + public FirewallRuleEndpointType(SubnetType subnet) { + this(subnet, null, null, null, null, null); } + public FirewallRuleEndpointType(SubnetType subnet, String virtual_network) { + this(subnet, virtual_network, null, null, null, null); } + public FirewallRuleEndpointType(SubnetType subnet, String virtual_network, String address_group) { + this(subnet, virtual_network, address_group, null, null, null); } + public FirewallRuleEndpointType(SubnetType subnet, String virtual_network, String address_group, List tags) { + this(subnet, virtual_network, address_group, tags, null, null); } + public FirewallRuleEndpointType(SubnetType subnet, String virtual_network, String address_group, List tags, List tag_ids) { + this(subnet, virtual_network, address_group, tags, tag_ids, null); } + + public SubnetType getSubnet() { + return subnet; + } + + public void setSubnet(SubnetType subnet) { + this.subnet = subnet; + } + + + public String getVirtualNetwork() { + return virtual_network; + } + + public void setVirtualNetwork(String virtual_network) { + this.virtual_network = virtual_network; + } + + + public String getAddressGroup() { + return address_group; + } + + public void setAddressGroup(String address_group) { + this.address_group = address_group; + } + + + public Boolean getAny() { + return any; + } + + public void setAny(Boolean any) { + this.any = any; + } + + + public List getTags() { + return tags; + } + + + public void addTags(String obj) { + if (tags == null) { + tags = new ArrayList(); + } + tags.add(obj); + } + public void clearTags() { + tags = null; + } + + + public List getTagIds() { + return tag_ids; + } + + + public void addTagIds(Integer obj) { + if (tag_ids == null) { + tag_ids = new ArrayList(); + } + tag_ids.add(obj); + } + public void clearTagIds() { + tag_ids = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleMatchTagsType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleMatchTagsType.java new file mode 100644 index 00000000000..1e7bb51310b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleMatchTagsType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FirewallRuleMatchTagsType extends ApiPropertyBase { + List tag_list; + public FirewallRuleMatchTagsType() { + } + public FirewallRuleMatchTagsType(List tag_list) { + this.tag_list = tag_list; + } + + public List getTagList() { + return tag_list; + } + + + public void addTag(String obj) { + if (tag_list == null) { + tag_list = new ArrayList(); + } + tag_list.add(obj); + } + public void clearTag() { + tag_list = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleMatchTagsTypeIdList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleMatchTagsTypeIdList.java new file mode 100644 index 00000000000..4332931968b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallRuleMatchTagsTypeIdList.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FirewallRuleMatchTagsTypeIdList extends ApiPropertyBase { + List tag_type; + public FirewallRuleMatchTagsTypeIdList() { + } + public FirewallRuleMatchTagsTypeIdList(List tag_type) { + this.tag_type = tag_type; + } + + public List getTagType() { + return tag_type; + } + + + public void addTagType(Integer obj) { + if (tag_type == null) { + tag_type = new ArrayList(); + } + tag_type.add(obj); + } + public void clearTagType() { + tag_type = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallSequence.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallSequence.java new file mode 100644 index 00000000000..2da34d998a4 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallSequence.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FirewallSequence extends ApiPropertyBase { + String sequence; + public FirewallSequence() { + } + public FirewallSequence(String sequence) { + this.sequence = sequence; + } + + public String getSequence() { + return sequence; + } + + public void setSequence(String sequence) { + this.sequence = sequence; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallServiceGroupType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallServiceGroupType.java new file mode 100644 index 00000000000..037cab7ae8b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallServiceGroupType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FirewallServiceGroupType extends ApiPropertyBase { + List firewall_service; + public FirewallServiceGroupType() { + } + public FirewallServiceGroupType(List firewall_service) { + this.firewall_service = firewall_service; + } + + public List getFirewallService() { + return firewall_service; + } + + + public void addFirewallService(FirewallServiceType obj) { + if (firewall_service == null) { + firewall_service = new ArrayList(); + } + firewall_service.add(obj); + } + public void clearFirewallService() { + firewall_service = null; + } + + + public void addFirewallService(String protocol, Integer protocol_id, PortType src_ports, PortType dst_ports) { + if (firewall_service == null) { + firewall_service = new ArrayList(); + } + firewall_service.add(new FirewallServiceType(protocol, protocol_id, src_ports, dst_ports)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallServiceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallServiceType.java new file mode 100644 index 00000000000..0b47c2b51ff --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FirewallServiceType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FirewallServiceType extends ApiPropertyBase { + String protocol; + Integer protocol_id; + PortType src_ports; + PortType dst_ports; + public FirewallServiceType() { + } + public FirewallServiceType(String protocol, Integer protocol_id, PortType src_ports, PortType dst_ports) { + this.protocol = protocol; + this.protocol_id = protocol_id; + this.src_ports = src_ports; + this.dst_ports = dst_ports; + } + public FirewallServiceType(String protocol) { + this(protocol, null, null, null); } + public FirewallServiceType(String protocol, Integer protocol_id) { + this(protocol, protocol_id, null, null); } + public FirewallServiceType(String protocol, Integer protocol_id, PortType src_ports) { + this(protocol, protocol_id, src_ports, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Integer getProtocolId() { + return protocol_id; + } + + public void setProtocolId(Integer protocol_id) { + this.protocol_id = protocol_id; + } + + + public PortType getSrcPorts() { + return src_ports; + } + + public void setSrcPorts(PortType src_ports) { + this.src_ports = src_ports; + } + + + public PortType getDstPorts() { + return dst_ports; + } + + public void setDstPorts(PortType dst_ports) { + this.dst_ports = dst_ports; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIp.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIp.java new file mode 100644 index 00000000000..f28862891f1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIp.java @@ -0,0 +1,245 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FloatingIp extends ApiObjectBase { + private String floating_ip_address; + private Boolean floating_ip_is_virtual_ip; + private String floating_ip_fixed_ip_address; + private String floating_ip_address_family; + private Boolean floating_ip_port_mappings_enable; + private PortMappings floating_ip_port_mappings; + private String floating_ip_traffic_direction; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> project_refs; + private List> virtual_machine_interface_refs; + private List> tag_refs; + private transient List> customer_attachment_back_refs; + + @Override + public String getObjectType() { + return "floating-ip"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(FloatingIpPool parent) { + super.setParent(parent); + } + + public void setParent(InstanceIp parent) { + super.setParent(parent); + } + + public String getAddress() { + return floating_ip_address; + } + + public void setAddress(String floating_ip_address) { + this.floating_ip_address = floating_ip_address; + } + + + public Boolean getIsVirtualIp() { + return floating_ip_is_virtual_ip; + } + + public void setIsVirtualIp(Boolean floating_ip_is_virtual_ip) { + this.floating_ip_is_virtual_ip = floating_ip_is_virtual_ip; + } + + + public String getFixedIpAddress() { + return floating_ip_fixed_ip_address; + } + + public void setFixedIpAddress(String floating_ip_fixed_ip_address) { + this.floating_ip_fixed_ip_address = floating_ip_fixed_ip_address; + } + + + public String getAddressFamily() { + return floating_ip_address_family; + } + + public void setAddressFamily(String floating_ip_address_family) { + this.floating_ip_address_family = floating_ip_address_family; + } + + + public Boolean getPortMappingsEnable() { + return floating_ip_port_mappings_enable; + } + + public void setPortMappingsEnable(Boolean floating_ip_port_mappings_enable) { + this.floating_ip_port_mappings_enable = floating_ip_port_mappings_enable; + } + + + public PortMappings getPortMappings() { + return floating_ip_port_mappings; + } + + public void setPortMappings(PortMappings floating_ip_port_mappings) { + this.floating_ip_port_mappings = floating_ip_port_mappings; + } + + + public String getTrafficDirection() { + return floating_ip_traffic_direction; + } + + public void setTrafficDirection(String floating_ip_traffic_direction) { + this.floating_ip_traffic_direction = floating_ip_traffic_direction; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getProject() { + return project_refs; + } + + public void setProject(Project obj) { + project_refs = new ArrayList>(); + project_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addProject(Project obj) { + if (project_refs == null) { + project_refs = new ArrayList>(); + } + project_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeProject(Project obj) { + if (project_refs != null) { + project_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearProject() { + if (project_refs != null) { + project_refs.clear(); + return; + } + project_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getCustomerAttachmentBackRefs() { + return customer_attachment_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIpPool.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIpPool.java new file mode 100644 index 00000000000..d111ad09ad5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIpPool.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FloatingIpPool extends ApiObjectBase { + private FloatingIpPoolSubnetType floating_ip_pool_subnets; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> floating_ips; + private List> tag_refs; + private transient List> project_back_refs; + + @Override + public String getObjectType() { + return "floating-ip-pool"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-virtual-network"); + } + + @Override + public String getDefaultParentType() { + return "virtual-network"; + } + + public void setParent(VirtualNetwork parent) { + super.setParent(parent); + } + + public FloatingIpPoolSubnetType getSubnets() { + return floating_ip_pool_subnets; + } + + public void setSubnets(FloatingIpPoolSubnetType floating_ip_pool_subnets) { + this.floating_ip_pool_subnets = floating_ip_pool_subnets; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getFloatingIps() { + return floating_ips; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getProjectBackRefs() { + return project_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIpPoolSubnetType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIpPoolSubnetType.java new file mode 100644 index 00000000000..dc7aac37a14 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FloatingIpPoolSubnetType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FloatingIpPoolSubnetType extends ApiPropertyBase { + List subnet_uuid; + public FloatingIpPoolSubnetType() { + } + public FloatingIpPoolSubnetType(List subnet_uuid) { + this.subnet_uuid = subnet_uuid; + } + + public List getSubnetUuid() { + return subnet_uuid; + } + + + public void addSubnetUuid(String obj) { + if (subnet_uuid == null) { + subnet_uuid = new ArrayList(); + } + subnet_uuid.add(obj); + } + public void clearSubnetUuid() { + subnet_uuid = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowAgingTimeout.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowAgingTimeout.java new file mode 100644 index 00000000000..d23185fcd22 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowAgingTimeout.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FlowAgingTimeout extends ApiPropertyBase { + String protocol; + Integer port; + Integer timeout_in_seconds; + public FlowAgingTimeout() { + } + public FlowAgingTimeout(String protocol, Integer port, Integer timeout_in_seconds) { + this.protocol = protocol; + this.port = port; + this.timeout_in_seconds = timeout_in_seconds; + } + public FlowAgingTimeout(String protocol) { + this(protocol, null, null); } + public FlowAgingTimeout(String protocol, Integer port) { + this(protocol, port, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + + public Integer getTimeoutInSeconds() { + return timeout_in_seconds; + } + + public void setTimeoutInSeconds(Integer timeout_in_seconds) { + this.timeout_in_seconds = timeout_in_seconds; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowAgingTimeoutList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowAgingTimeoutList.java new file mode 100644 index 00000000000..2ecc2f93543 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowAgingTimeoutList.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class FlowAgingTimeoutList extends ApiPropertyBase { + List flow_aging_timeout; + public FlowAgingTimeoutList() { + } + public FlowAgingTimeoutList(List flow_aging_timeout) { + this.flow_aging_timeout = flow_aging_timeout; + } + + public List getFlowAgingTimeout() { + return flow_aging_timeout; + } + + + public void addFlowAgingTimeout(FlowAgingTimeout obj) { + if (flow_aging_timeout == null) { + flow_aging_timeout = new ArrayList(); + } + flow_aging_timeout.add(obj); + } + public void clearFlowAgingTimeout() { + flow_aging_timeout = null; + } + + + public void addFlowAgingTimeout(String protocol, Integer port, Integer timeout_in_seconds) { + if (flow_aging_timeout == null) { + flow_aging_timeout = new ArrayList(); + } + flow_aging_timeout.add(new FlowAgingTimeout(protocol, port, timeout_in_seconds)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowNode.java new file mode 100644 index 00000000000..8ef1f6f4abf --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/FlowNode.java @@ -0,0 +1,171 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class FlowNode extends ApiObjectBase { + private String flow_node_ip_address; + private String flow_node_load_balancer_ip; + private String flow_node_inband_interface; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_network_refs; + private List> tag_refs; + private transient List> instance_ip_back_refs; + + @Override + public String getObjectType() { + return "flow-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return flow_node_ip_address; + } + + public void setIpAddress(String flow_node_ip_address) { + this.flow_node_ip_address = flow_node_ip_address; + } + + + public String getLoadBalancerIp() { + return flow_node_load_balancer_ip; + } + + public void setLoadBalancerIp(String flow_node_load_balancer_ip) { + this.flow_node_load_balancer_ip = flow_node_load_balancer_ip; + } + + + public String getInbandInterface() { + return flow_node_inband_interface; + } + + public void setInbandInterface(String flow_node_inband_interface) { + this.flow_node_inband_interface = flow_node_inband_interface; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ForwardingClass.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ForwardingClass.java new file mode 100644 index 00000000000..9c4180e89cd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ForwardingClass.java @@ -0,0 +1,176 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ForwardingClass extends ApiObjectBase { + private Integer forwarding_class_id; + private Integer forwarding_class_dscp; + private Integer forwarding_class_vlan_priority; + private Integer forwarding_class_mpls_exp; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> qos_queue_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "forwarding-class"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-global-qos-config"); + } + + @Override + public String getDefaultParentType() { + return "global-qos-config"; + } + + public void setParent(GlobalQosConfig parent) { + super.setParent(parent); + } + + public Integer getId() { + return forwarding_class_id; + } + + public void setId(Integer forwarding_class_id) { + this.forwarding_class_id = forwarding_class_id; + } + + + public Integer getDscp() { + return forwarding_class_dscp; + } + + public void setDscp(Integer forwarding_class_dscp) { + this.forwarding_class_dscp = forwarding_class_dscp; + } + + + public Integer getVlanPriority() { + return forwarding_class_vlan_priority; + } + + public void setVlanPriority(Integer forwarding_class_vlan_priority) { + this.forwarding_class_vlan_priority = forwarding_class_vlan_priority; + } + + + public Integer getMplsExp() { + return forwarding_class_mpls_exp; + } + + public void setMplsExp(Integer forwarding_class_mpls_exp) { + this.forwarding_class_mpls_exp = forwarding_class_mpls_exp; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getQosQueue() { + return qos_queue_refs; + } + + public void setQosQueue(QosQueue obj) { + qos_queue_refs = new ArrayList>(); + qos_queue_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addQosQueue(QosQueue obj) { + if (qos_queue_refs == null) { + qos_queue_refs = new ArrayList>(); + } + qos_queue_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeQosQueue(QosQueue obj) { + if (qos_queue_refs != null) { + qos_queue_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearQosQueue() { + if (qos_queue_refs != null) { + qos_queue_refs.clear(); + return; + } + qos_queue_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalQosConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalQosConfig.java new file mode 100644 index 00000000000..4534896c61e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalQosConfig.java @@ -0,0 +1,130 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class GlobalQosConfig extends ApiObjectBase { + private ControlTrafficDscpType control_traffic_dscp; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> qos_configs; + private List> forwarding_classs; + private List> qos_queues; + private List> tag_refs; + + @Override + public String getObjectType() { + return "global-qos-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public ControlTrafficDscpType getControlTrafficDscp() { + return control_traffic_dscp; + } + + public void setControlTrafficDscp(ControlTrafficDscpType control_traffic_dscp) { + this.control_traffic_dscp = control_traffic_dscp; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getQosConfigs() { + return qos_configs; + } + + public List> getForwardingClasss() { + return forwarding_classs; + } + + public List> getQosQueues() { + return qos_queues; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalSystemConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalSystemConfig.java new file mode 100644 index 00000000000..e5e006f233f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalSystemConfig.java @@ -0,0 +1,516 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class GlobalSystemConfig extends ApiObjectBase { + private Integer autonomous_system; + private Boolean enable_4byte_as; + private String config_version; + private GracefulRestartParametersType graceful_restart_parameters; + private FastConvergenceParametersType fast_convergence_parameters; + private PluginProperties plugin_tuning; + private SubnetListType data_center_interconnect_loopback_namespace; + private AsnRangeType data_center_interconnect_asn_namespace; + private Boolean ibgp_auto_mesh; + private Boolean bgp_always_compare_med; + private Integer rd_cluster_seed; + private SubnetListType ip_fabric_subnets; + private DeviceFamilyListType supported_device_families; + private VendorHardwaresType supported_vendor_hardwares; + private BGPaaServiceParametersType bgpaas_parameters; + private MACLimitControlType mac_limit_control; + private MACMoveLimitControlType mac_move_control; + private Integer mac_aging_time; + private Boolean igmp_enable; + private Boolean alarm_enable; + private UserDefinedLogStatList user_defined_log_statistics; + private Boolean enable_security_policy_draft; + private KeyValuePairs supported_fabric_annotations; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> bgp_router_refs; + private List> control_node_zones; + private List> global_vrouter_configs; + private List> global_qos_configs; + private List> virtual_routers; + private List> config_nodes; + private List> analytics_nodes; + private List> flow_nodes; + private List> devicemgr_nodes; + private List> database_nodes; + private List> webui_nodes; + private List> config_database_nodes; + private List> analytics_alarm_nodes; + private List> analytics_snmp_nodes; + private List> service_appliance_sets; + private List> api_access_lists; + private List> alarms; + private List> config_propertiess; + private List> job_templates; + private List> data_center_interconnects; + private List> intent_maps; + private List> fabrics; + private List> node_profiles; + private List> physical_routers; + private List> device_images; + private List> nodes; + private List> features; + private List> physical_roles; + private List> overlay_roles; + private List> role_definitions; + private List> tag_refs; + private transient List> qos_config_back_refs; + + @Override + public String getObjectType() { + return "global-system-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return "config-root"; + } + + public void setParent(ConfigRoot parent) { + super.setParent(parent); + } + + public Integer getAutonomousSystem() { + return autonomous_system; + } + + public void setAutonomousSystem(Integer autonomous_system) { + this.autonomous_system = autonomous_system; + } + + + public Boolean getEnable4byteAs() { + return enable_4byte_as; + } + + public void setEnable4byteAs(Boolean enable_4byte_as) { + this.enable_4byte_as = enable_4byte_as; + } + + + public String getConfigVersion() { + return config_version; + } + + public void setConfigVersion(String config_version) { + this.config_version = config_version; + } + + + public GracefulRestartParametersType getGracefulRestartParameters() { + return graceful_restart_parameters; + } + + public void setGracefulRestartParameters(GracefulRestartParametersType graceful_restart_parameters) { + this.graceful_restart_parameters = graceful_restart_parameters; + } + + + public FastConvergenceParametersType getFastConvergenceParameters() { + return fast_convergence_parameters; + } + + public void setFastConvergenceParameters(FastConvergenceParametersType fast_convergence_parameters) { + this.fast_convergence_parameters = fast_convergence_parameters; + } + + + public PluginProperties getPluginTuning() { + return plugin_tuning; + } + + public void setPluginTuning(PluginProperties plugin_tuning) { + this.plugin_tuning = plugin_tuning; + } + + + public SubnetListType getDataCenterInterconnectLoopbackNamespace() { + return data_center_interconnect_loopback_namespace; + } + + public void setDataCenterInterconnectLoopbackNamespace(SubnetListType data_center_interconnect_loopback_namespace) { + this.data_center_interconnect_loopback_namespace = data_center_interconnect_loopback_namespace; + } + + + public AsnRangeType getDataCenterInterconnectAsnNamespace() { + return data_center_interconnect_asn_namespace; + } + + public void setDataCenterInterconnectAsnNamespace(AsnRangeType data_center_interconnect_asn_namespace) { + this.data_center_interconnect_asn_namespace = data_center_interconnect_asn_namespace; + } + + + public Boolean getIbgpAutoMesh() { + return ibgp_auto_mesh; + } + + public void setIbgpAutoMesh(Boolean ibgp_auto_mesh) { + this.ibgp_auto_mesh = ibgp_auto_mesh; + } + + + public Boolean getBgpAlwaysCompareMed() { + return bgp_always_compare_med; + } + + public void setBgpAlwaysCompareMed(Boolean bgp_always_compare_med) { + this.bgp_always_compare_med = bgp_always_compare_med; + } + + + public Integer getRdClusterSeed() { + return rd_cluster_seed; + } + + public void setRdClusterSeed(Integer rd_cluster_seed) { + this.rd_cluster_seed = rd_cluster_seed; + } + + + public SubnetListType getIpFabricSubnets() { + return ip_fabric_subnets; + } + + public void setIpFabricSubnets(SubnetListType ip_fabric_subnets) { + this.ip_fabric_subnets = ip_fabric_subnets; + } + + + public DeviceFamilyListType getSupportedDeviceFamilies() { + return supported_device_families; + } + + public void setSupportedDeviceFamilies(DeviceFamilyListType supported_device_families) { + this.supported_device_families = supported_device_families; + } + + + public VendorHardwaresType getSupportedVendorHardwares() { + return supported_vendor_hardwares; + } + + public void setSupportedVendorHardwares(VendorHardwaresType supported_vendor_hardwares) { + this.supported_vendor_hardwares = supported_vendor_hardwares; + } + + + public BGPaaServiceParametersType getBgpaasParameters() { + return bgpaas_parameters; + } + + public void setBgpaasParameters(BGPaaServiceParametersType bgpaas_parameters) { + this.bgpaas_parameters = bgpaas_parameters; + } + + + public MACLimitControlType getMacLimitControl() { + return mac_limit_control; + } + + public void setMacLimitControl(MACLimitControlType mac_limit_control) { + this.mac_limit_control = mac_limit_control; + } + + + public MACMoveLimitControlType getMacMoveControl() { + return mac_move_control; + } + + public void setMacMoveControl(MACMoveLimitControlType mac_move_control) { + this.mac_move_control = mac_move_control; + } + + + public Integer getMacAgingTime() { + return mac_aging_time; + } + + public void setMacAgingTime(Integer mac_aging_time) { + this.mac_aging_time = mac_aging_time; + } + + + public Boolean getIgmpEnable() { + return igmp_enable; + } + + public void setIgmpEnable(Boolean igmp_enable) { + this.igmp_enable = igmp_enable; + } + + + public Boolean getAlarmEnable() { + return alarm_enable; + } + + public void setAlarmEnable(Boolean alarm_enable) { + this.alarm_enable = alarm_enable; + } + + + public UserDefinedLogStatList getUserDefinedLogStatistics() { + return user_defined_log_statistics; + } + + public void setUserDefinedLogStatistics(UserDefinedLogStatList user_defined_log_statistics) { + this.user_defined_log_statistics = user_defined_log_statistics; + } + + + public Boolean getEnableSecurityPolicyDraft() { + return enable_security_policy_draft; + } + + public void setEnableSecurityPolicyDraft(Boolean enable_security_policy_draft) { + this.enable_security_policy_draft = enable_security_policy_draft; + } + + + public KeyValuePairs getSupportedFabricAnnotations() { + return supported_fabric_annotations; + } + + public void setSupportedFabricAnnotations(KeyValuePairs supported_fabric_annotations) { + this.supported_fabric_annotations = supported_fabric_annotations; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getBgpRouter() { + return bgp_router_refs; + } + + public void setBgpRouter(BgpRouter obj) { + bgp_router_refs = new ArrayList>(); + bgp_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addBgpRouter(BgpRouter obj) { + if (bgp_router_refs == null) { + bgp_router_refs = new ArrayList>(); + } + bgp_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeBgpRouter(BgpRouter obj) { + if (bgp_router_refs != null) { + bgp_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearBgpRouter() { + if (bgp_router_refs != null) { + bgp_router_refs.clear(); + return; + } + bgp_router_refs = null; + } + + public List> getControlNodeZones() { + return control_node_zones; + } + + public List> getGlobalVrouterConfigs() { + return global_vrouter_configs; + } + + public List> getGlobalQosConfigs() { + return global_qos_configs; + } + + public List> getVirtualRouters() { + return virtual_routers; + } + + public List> getConfigNodes() { + return config_nodes; + } + + public List> getAnalyticsNodes() { + return analytics_nodes; + } + + public List> getFlowNodes() { + return flow_nodes; + } + + public List> getDevicemgrNodes() { + return devicemgr_nodes; + } + + public List> getDatabaseNodes() { + return database_nodes; + } + + public List> getWebuiNodes() { + return webui_nodes; + } + + public List> getConfigDatabaseNodes() { + return config_database_nodes; + } + + public List> getAnalyticsAlarmNodes() { + return analytics_alarm_nodes; + } + + public List> getAnalyticsSnmpNodes() { + return analytics_snmp_nodes; + } + + public List> getServiceApplianceSets() { + return service_appliance_sets; + } + + public List> getApiAccessLists() { + return api_access_lists; + } + + public List> getAlarms() { + return alarms; + } + + public List> getConfigPropertiess() { + return config_propertiess; + } + + public List> getJobTemplates() { + return job_templates; + } + + public List> getDataCenterInterconnects() { + return data_center_interconnects; + } + + public List> getIntentMaps() { + return intent_maps; + } + + public List> getFabrics() { + return fabrics; + } + + public List> getNodeProfiles() { + return node_profiles; + } + + public List> getPhysicalRouters() { + return physical_routers; + } + + public List> getDeviceImages() { + return device_images; + } + + public List> getNodes() { + return nodes; + } + + public List> getFeatures() { + return features; + } + + public List> getPhysicalRoles() { + return physical_roles; + } + + public List> getOverlayRoles() { + return overlay_roles; + } + + public List> getRoleDefinitions() { + return role_definitions; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getQosConfigBackRefs() { + return qos_config_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalVrouterConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalVrouterConfig.java new file mode 100644 index 00000000000..0194feb30cd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GlobalVrouterConfig.java @@ -0,0 +1,225 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class GlobalVrouterConfig extends ApiObjectBase { + private EcmpHashingIncludeFields ecmp_hashing_include_fields; + private LinklocalServicesTypes linklocal_services; + private EncapsulationPrioritiesType encapsulation_priorities; + private String vxlan_network_identifier_mode; + private Integer flow_export_rate; + private FlowAgingTimeoutList flow_aging_timeout_list; + private Boolean enable_security_logging; + private String encryption_mode; + private EncryptionTunnelEndpointList encryption_tunnel_endpoints; + private String forwarding_mode; + private PortTranslationPools port_translation_pools; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> security_logging_objects; + private List> tag_refs; + private transient List> application_policy_set_back_refs; + + @Override + public String getObjectType() { + return "global-vrouter-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public EcmpHashingIncludeFields getEcmpHashingIncludeFields() { + return ecmp_hashing_include_fields; + } + + public void setEcmpHashingIncludeFields(EcmpHashingIncludeFields ecmp_hashing_include_fields) { + this.ecmp_hashing_include_fields = ecmp_hashing_include_fields; + } + + + public LinklocalServicesTypes getLinklocalServices() { + return linklocal_services; + } + + public void setLinklocalServices(LinklocalServicesTypes linklocal_services) { + this.linklocal_services = linklocal_services; + } + + + public EncapsulationPrioritiesType getEncapsulationPriorities() { + return encapsulation_priorities; + } + + public void setEncapsulationPriorities(EncapsulationPrioritiesType encapsulation_priorities) { + this.encapsulation_priorities = encapsulation_priorities; + } + + + public String getVxlanNetworkIdentifierMode() { + return vxlan_network_identifier_mode; + } + + public void setVxlanNetworkIdentifierMode(String vxlan_network_identifier_mode) { + this.vxlan_network_identifier_mode = vxlan_network_identifier_mode; + } + + + public Integer getFlowExportRate() { + return flow_export_rate; + } + + public void setFlowExportRate(Integer flow_export_rate) { + this.flow_export_rate = flow_export_rate; + } + + + public FlowAgingTimeoutList getFlowAgingTimeoutList() { + return flow_aging_timeout_list; + } + + public void setFlowAgingTimeoutList(FlowAgingTimeoutList flow_aging_timeout_list) { + this.flow_aging_timeout_list = flow_aging_timeout_list; + } + + + public Boolean getEnableSecurityLogging() { + return enable_security_logging; + } + + public void setEnableSecurityLogging(Boolean enable_security_logging) { + this.enable_security_logging = enable_security_logging; + } + + + public String getEncryptionMode() { + return encryption_mode; + } + + public void setEncryptionMode(String encryption_mode) { + this.encryption_mode = encryption_mode; + } + + + public EncryptionTunnelEndpointList getEncryptionTunnelEndpoints() { + return encryption_tunnel_endpoints; + } + + public void setEncryptionTunnelEndpoints(EncryptionTunnelEndpointList encryption_tunnel_endpoints) { + this.encryption_tunnel_endpoints = encryption_tunnel_endpoints; + } + + + public String getForwardingMode() { + return forwarding_mode; + } + + public void setForwardingMode(String forwarding_mode) { + this.forwarding_mode = forwarding_mode; + } + + + public PortTranslationPools getPortTranslationPools() { + return port_translation_pools; + } + + public void setPortTranslationPools(PortTranslationPools port_translation_pools) { + this.port_translation_pools = port_translation_pools; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getSecurityLoggingObjects() { + return security_logging_objects; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getApplicationPolicySetBackRefs() { + return application_policy_set_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GracefulRestartParametersType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GracefulRestartParametersType.java new file mode 100644 index 00000000000..7d1675cb2e7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GracefulRestartParametersType.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class GracefulRestartParametersType extends ApiPropertyBase { + Boolean enable; + Integer restart_time; + Integer long_lived_restart_time; + Integer end_of_rib_timeout; + Boolean bgp_helper_enable; + Boolean xmpp_helper_enable; + public GracefulRestartParametersType() { + } + public GracefulRestartParametersType(Boolean enable, Integer restart_time, Integer long_lived_restart_time, Integer end_of_rib_timeout, Boolean bgp_helper_enable, Boolean xmpp_helper_enable) { + this.enable = enable; + this.restart_time = restart_time; + this.long_lived_restart_time = long_lived_restart_time; + this.end_of_rib_timeout = end_of_rib_timeout; + this.bgp_helper_enable = bgp_helper_enable; + this.xmpp_helper_enable = xmpp_helper_enable; + } + public GracefulRestartParametersType(Boolean enable) { + this(enable, 300, 300, 300, false, false); } + public GracefulRestartParametersType(Boolean enable, Integer restart_time) { + this(enable, restart_time, 300, 300, false, false); } + public GracefulRestartParametersType(Boolean enable, Integer restart_time, Integer long_lived_restart_time) { + this(enable, restart_time, long_lived_restart_time, 300, false, false); } + public GracefulRestartParametersType(Boolean enable, Integer restart_time, Integer long_lived_restart_time, Integer end_of_rib_timeout) { + this(enable, restart_time, long_lived_restart_time, end_of_rib_timeout, false, false); } + public GracefulRestartParametersType(Boolean enable, Integer restart_time, Integer long_lived_restart_time, Integer end_of_rib_timeout, Boolean bgp_helper_enable) { + this(enable, restart_time, long_lived_restart_time, end_of_rib_timeout, bgp_helper_enable, false); } + + public Boolean getEnable() { + return enable; + } + + public void setEnable(Boolean enable) { + this.enable = enable; + } + + + public Integer getRestartTime() { + return restart_time; + } + + public void setRestartTime(Integer restart_time) { + this.restart_time = restart_time; + } + + + public Integer getLongLivedRestartTime() { + return long_lived_restart_time; + } + + public void setLongLivedRestartTime(Integer long_lived_restart_time) { + this.long_lived_restart_time = long_lived_restart_time; + } + + + public Integer getEndOfRibTimeout() { + return end_of_rib_timeout; + } + + public void setEndOfRibTimeout(Integer end_of_rib_timeout) { + this.end_of_rib_timeout = end_of_rib_timeout; + } + + + public Boolean getBgpHelperEnable() { + return bgp_helper_enable; + } + + public void setBgpHelperEnable(Boolean bgp_helper_enable) { + this.bgp_helper_enable = bgp_helper_enable; + } + + + public Boolean getXmppHelperEnable() { + return xmpp_helper_enable; + } + + public void setXmppHelperEnable(Boolean xmpp_helper_enable) { + this.xmpp_helper_enable = xmpp_helper_enable; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GrpcParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GrpcParameters.java new file mode 100644 index 00000000000..97dec177409 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GrpcParameters.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class GrpcParameters extends ApiPropertyBase { + SubnetListType allow_clients; + EnabledSensorParams enabled_sensor_params; + String secure_mode; + public GrpcParameters() { + } + public GrpcParameters(SubnetListType allow_clients, EnabledSensorParams enabled_sensor_params, String secure_mode) { + this.allow_clients = allow_clients; + this.enabled_sensor_params = enabled_sensor_params; + this.secure_mode = secure_mode; + } + public GrpcParameters(SubnetListType allow_clients) { + this(allow_clients, null, null); } + public GrpcParameters(SubnetListType allow_clients, EnabledSensorParams enabled_sensor_params) { + this(allow_clients, enabled_sensor_params, null); } + + public SubnetListType getAllowClients() { + return allow_clients; + } + + public void setAllowClients(SubnetListType allow_clients) { + this.allow_clients = allow_clients; + } + + + public EnabledSensorParams getEnabledSensorParams() { + return enabled_sensor_params; + } + + public void setEnabledSensorParams(EnabledSensorParams enabled_sensor_params) { + this.enabled_sensor_params = enabled_sensor_params; + } + + + public String getSecureMode() { + return secure_mode; + } + + public void setSecureMode(String secure_mode) { + this.secure_mode = secure_mode; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GrpcProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GrpcProfile.java new file mode 100644 index 00000000000..81c3ecda768 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/GrpcProfile.java @@ -0,0 +1,130 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class GrpcProfile extends ApiObjectBase { + private Boolean grpc_profile_is_default; + private GrpcParameters grpc_parameters; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> telemetry_profile_back_refs; + + @Override + public String getObjectType() { + return "grpc-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Boolean getIsDefault() { + return grpc_profile_is_default; + } + + public void setIsDefault(Boolean grpc_profile_is_default) { + this.grpc_profile_is_default = grpc_profile_is_default; + } + + + public GrpcParameters getGrpcParameters() { + return grpc_parameters; + } + + public void setGrpcParameters(GrpcParameters grpc_parameters) { + this.grpc_parameters = grpc_parameters; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getTelemetryProfileBackRefs() { + return telemetry_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Hardware.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Hardware.java new file mode 100644 index 00000000000..5b5277ed4a3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Hardware.java @@ -0,0 +1,142 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Hardware extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> card_refs; + private List> tag_refs; + private transient List> node_profile_back_refs; + private transient List> device_image_back_refs; + + @Override + public String getObjectType() { + return "hardware"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getCard() { + return card_refs; + } + + public void setCard(Card obj) { + card_refs = new ArrayList>(); + card_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addCard(Card obj) { + if (card_refs == null) { + card_refs = new ArrayList>(); + } + card_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeCard(Card obj) { + if (card_refs != null) { + card_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearCard() { + if (card_refs != null) { + card_refs.clear(); + return; + } + card_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getNodeProfileBackRefs() { + return node_profile_back_refs; + } + + public List> getDeviceImageBackRefs() { + return device_image_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/HardwareInventory.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/HardwareInventory.java new file mode 100644 index 00000000000..5c331ee1ae0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/HardwareInventory.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class HardwareInventory extends ApiObjectBase { + private String hardware_inventory_inventory_info; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "hardware-inventory"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-physical-router"); + } + + @Override + public String getDefaultParentType() { + return "physical-router"; + } + + public void setParent(PhysicalRouter parent) { + super.setParent(parent); + } + + public String getInventoryInfo() { + return hardware_inventory_inventory_info; + } + + public void setInventoryInfo(String hardware_inventory_inventory_info) { + this.hardware_inventory_inventory_info = hardware_inventory_inventory_info; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/HostBasedService.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/HostBasedService.java new file mode 100644 index 00000000000..d41a71c1cb0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/HostBasedService.java @@ -0,0 +1,147 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class HostBasedService extends ApiObjectBase { + private String host_based_service_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_network_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "host-based-service"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getType() { + return host_based_service_type; + } + + public void setType(String host_based_service_type) { + this.host_based_service_type = host_based_service_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj, ServiceVirtualNetworkType data) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addVirtualNetwork(VirtualNetwork obj, ServiceVirtualNetworkType data) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeVirtualNetwork(VirtualNetwork obj, ServiceVirtualNetworkType data) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IPSegmentType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IPSegmentType.java new file mode 100644 index 00000000000..2769d39244a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IPSegmentType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IPSegmentType extends ApiPropertyBase { + String ip_prefix; + Integer ip_prefix_len; + public IPSegmentType() { + } + public IPSegmentType(String ip_prefix, Integer ip_prefix_len) { + this.ip_prefix = ip_prefix; + this.ip_prefix_len = ip_prefix_len; + } + public IPSegmentType(String ip_prefix) { + this(ip_prefix, 8); } + + public String getIpPrefix() { + return ip_prefix; + } + + public void setIpPrefix(String ip_prefix) { + this.ip_prefix = ip_prefix; + } + + + public Integer getIpPrefixLen() { + return ip_prefix_len; + } + + public void setIpPrefixLen(Integer ip_prefix_len) { + this.ip_prefix_len = ip_prefix_len; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IdPermsType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IdPermsType.java new file mode 100644 index 00000000000..1f90f40669c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IdPermsType.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IdPermsType extends ApiPropertyBase { + PermType permissions; + UuidType uuid; + Boolean enable; + volatile java.util.Date created; + volatile java.util.Date last_modified; + String description; + Boolean user_visible; + String creator; + public IdPermsType() { + } + public IdPermsType(PermType permissions, UuidType uuid, Boolean enable, java.util.Date created, java.util.Date last_modified, String description, Boolean user_visible, String creator) { + this.permissions = permissions; + this.uuid = uuid; + this.enable = enable; + this.created = created; + this.last_modified = last_modified; + this.description = description; + this.user_visible = user_visible; + this.creator = creator; + } + public IdPermsType(PermType permissions) { + this(permissions, null, null, null, null, null, true, null); } + public IdPermsType(PermType permissions, UuidType uuid) { + this(permissions, uuid, null, null, null, null, true, null); } + public IdPermsType(PermType permissions, UuidType uuid, Boolean enable) { + this(permissions, uuid, enable, null, null, null, true, null); } + public IdPermsType(PermType permissions, UuidType uuid, Boolean enable, java.util.Date created) { + this(permissions, uuid, enable, created, null, null, true, null); } + public IdPermsType(PermType permissions, UuidType uuid, Boolean enable, java.util.Date created, java.util.Date last_modified) { + this(permissions, uuid, enable, created, last_modified, null, true, null); } + public IdPermsType(PermType permissions, UuidType uuid, Boolean enable, java.util.Date created, java.util.Date last_modified, String description) { + this(permissions, uuid, enable, created, last_modified, description, true, null); } + public IdPermsType(PermType permissions, UuidType uuid, Boolean enable, java.util.Date created, java.util.Date last_modified, String description, Boolean user_visible) { + this(permissions, uuid, enable, created, last_modified, description, user_visible, null); } + + public PermType getPermissions() { + return permissions; + } + + public void setPermissions(PermType permissions) { + this.permissions = permissions; + } + + + public UuidType getUuid() { + return uuid; + } + + public void setUuid(UuidType uuid) { + this.uuid = uuid; + } + + + public Boolean getEnable() { + return enable; + } + + public void setEnable(Boolean enable) { + this.enable = enable; + } + + + public java.util.Date getCreated() { + return created; + } + + public void setCreated(java.util.Date created) { + this.created = created; + } + + + public java.util.Date getLastModified() { + return last_modified; + } + + public void setLastModified(java.util.Date last_modified) { + this.last_modified = last_modified; + } + + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + + public Boolean getUserVisible() { + return user_visible; + } + + public void setUserVisible(Boolean user_visible) { + this.user_visible = user_visible; + } + + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InstanceIp.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InstanceIp.java new file mode 100644 index 00000000000..250eb0be103 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InstanceIp.java @@ -0,0 +1,438 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class InstanceIp extends ApiObjectBase { + private String instance_ip_address; + private String instance_ip_family; + private String instance_ip_mode; + private SubnetType secondary_ip_tracking_ip; + private String subnet_uuid; + private String instance_ip_subscriber_tag; + private Boolean instance_ip_secondary; + private Boolean instance_ip_local_ip; + private Boolean service_instance_ip; + private Boolean service_health_check_ip; + private SubnetType instance_ip_subnet; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_network_refs; + private List> network_ipam_refs; + private List> virtual_machine_interface_refs; + private List> physical_router_refs; + private List> virtual_router_refs; + private List> logical_interface_refs; + private List> flow_node_refs; + private List> floating_ips; + private List> tag_refs; + private transient List> service_instance_back_refs; + + @Override + public String getObjectType() { + return "instance-ip"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public String getAddress() { + return instance_ip_address; + } + + public void setAddress(String instance_ip_address) { + this.instance_ip_address = instance_ip_address; + } + + + public String getFamily() { + return instance_ip_family; + } + + public void setFamily(String instance_ip_family) { + this.instance_ip_family = instance_ip_family; + } + + + public String getMode() { + return instance_ip_mode; + } + + public void setMode(String instance_ip_mode) { + this.instance_ip_mode = instance_ip_mode; + } + + + public SubnetType getSecondaryIpTrackingIp() { + return secondary_ip_tracking_ip; + } + + public void setSecondaryIpTrackingIp(SubnetType secondary_ip_tracking_ip) { + this.secondary_ip_tracking_ip = secondary_ip_tracking_ip; + } + + + public String getSubnetUuid() { + return subnet_uuid; + } + + public void setSubnetUuid(String subnet_uuid) { + this.subnet_uuid = subnet_uuid; + } + + + public String getSubscriberTag() { + return instance_ip_subscriber_tag; + } + + public void setSubscriberTag(String instance_ip_subscriber_tag) { + this.instance_ip_subscriber_tag = instance_ip_subscriber_tag; + } + + + public Boolean getSecondary() { + return instance_ip_secondary; + } + + public void setSecondary(Boolean instance_ip_secondary) { + this.instance_ip_secondary = instance_ip_secondary; + } + + + public Boolean getLocalIp() { + return instance_ip_local_ip; + } + + public void setLocalIp(Boolean instance_ip_local_ip) { + this.instance_ip_local_ip = instance_ip_local_ip; + } + + + public Boolean getServiceInstanceIp() { + return service_instance_ip; + } + + public void setServiceInstanceIp(Boolean service_instance_ip) { + this.service_instance_ip = service_instance_ip; + } + + + public Boolean getServiceHealthCheckIp() { + return service_health_check_ip; + } + + public void setServiceHealthCheckIp(Boolean service_health_check_ip) { + this.service_health_check_ip = service_health_check_ip; + } + + + public SubnetType getSubnet() { + return instance_ip_subnet; + } + + public void setSubnet(SubnetType instance_ip_subnet) { + this.instance_ip_subnet = instance_ip_subnet; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getNetworkIpam() { + return network_ipam_refs; + } + + public void setNetworkIpam(NetworkIpam obj) { + network_ipam_refs = new ArrayList>(); + network_ipam_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addNetworkIpam(NetworkIpam obj) { + if (network_ipam_refs == null) { + network_ipam_refs = new ArrayList>(); + } + network_ipam_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeNetworkIpam(NetworkIpam obj) { + if (network_ipam_refs != null) { + network_ipam_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearNetworkIpam() { + if (network_ipam_refs != null) { + network_ipam_refs.clear(); + return; + } + network_ipam_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getPhysicalRouter() { + return physical_router_refs; + } + + public void setPhysicalRouter(PhysicalRouter obj) { + physical_router_refs = new ArrayList>(); + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs == null) { + physical_router_refs = new ArrayList>(); + } + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs != null) { + physical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRouter() { + if (physical_router_refs != null) { + physical_router_refs.clear(); + return; + } + physical_router_refs = null; + } + + public List> getVirtualRouter() { + return virtual_router_refs; + } + + public void setVirtualRouter(VirtualRouter obj) { + virtual_router_refs = new ArrayList>(); + virtual_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualRouter(VirtualRouter obj) { + if (virtual_router_refs == null) { + virtual_router_refs = new ArrayList>(); + } + virtual_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualRouter(VirtualRouter obj) { + if (virtual_router_refs != null) { + virtual_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualRouter() { + if (virtual_router_refs != null) { + virtual_router_refs.clear(); + return; + } + virtual_router_refs = null; + } + + public List> getLogicalInterface() { + return logical_interface_refs; + } + + public void setLogicalInterface(LogicalInterface obj) { + logical_interface_refs = new ArrayList>(); + logical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLogicalInterface(LogicalInterface obj) { + if (logical_interface_refs == null) { + logical_interface_refs = new ArrayList>(); + } + logical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLogicalInterface(LogicalInterface obj) { + if (logical_interface_refs != null) { + logical_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLogicalInterface() { + if (logical_interface_refs != null) { + logical_interface_refs.clear(); + return; + } + logical_interface_refs = null; + } + + public List> getFlowNode() { + return flow_node_refs; + } + + public void setFlowNode(FlowNode obj) { + flow_node_refs = new ArrayList>(); + flow_node_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFlowNode(FlowNode obj) { + if (flow_node_refs == null) { + flow_node_refs = new ArrayList>(); + } + flow_node_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFlowNode(FlowNode obj) { + if (flow_node_refs != null) { + flow_node_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFlowNode() { + if (flow_node_refs != null) { + flow_node_refs.clear(); + return; + } + flow_node_refs = null; + } + + public List> getFloatingIps() { + return floating_ips; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceInstanceBackRefs() { + return service_instance_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IntentMap.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IntentMap.java new file mode 100644 index 00000000000..c79a6e75bf9 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IntentMap.java @@ -0,0 +1,130 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class IntentMap extends ApiObjectBase { + private String intent_map_intent_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> physical_router_back_refs; + private transient List> virtual_network_back_refs; + private transient List> fabric_back_refs; + + @Override + public String getObjectType() { + return "intent-map"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIntentType() { + return intent_map_intent_type; + } + + public void setIntentType(String intent_map_intent_type) { + this.intent_map_intent_type = intent_map_intent_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getFabricBackRefs() { + return fabric_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceMapType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceMapType.java new file mode 100644 index 00000000000..39d3a7949ea --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceMapType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class InterfaceMapType extends ApiPropertyBase { + List port_info; + public InterfaceMapType() { + } + public InterfaceMapType(List port_info) { + this.port_info = port_info; + } + + public List getPortInfo() { + return port_info; + } + + + public void addPortInfo(PortInfoType obj) { + if (port_info == null) { + port_info = new ArrayList(); + } + port_info.add(obj); + } + public void clearPortInfo() { + port_info = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceMirrorType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceMirrorType.java new file mode 100644 index 00000000000..2f788bdb82e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceMirrorType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class InterfaceMirrorType extends ApiPropertyBase { + String traffic_direction; + MirrorActionType mirror_to; + public InterfaceMirrorType() { + } + public InterfaceMirrorType(String traffic_direction, MirrorActionType mirror_to) { + this.traffic_direction = traffic_direction; + this.mirror_to = mirror_to; + } + public InterfaceMirrorType(String traffic_direction) { + this(traffic_direction, null); } + + public String getTrafficDirection() { + return traffic_direction; + } + + public void setTrafficDirection(String traffic_direction) { + this.traffic_direction = traffic_direction; + } + + + public MirrorActionType getMirrorTo() { + return mirror_to; + } + + public void setMirrorTo(MirrorActionType mirror_to) { + this.mirror_to = mirror_to; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceRouteTable.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceRouteTable.java new file mode 100644 index 00000000000..194df1ff061 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/InterfaceRouteTable.java @@ -0,0 +1,157 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class InterfaceRouteTable extends ApiObjectBase { + private RouteTableType interface_route_table_routes; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_instance_refs; + private List> tag_refs; + private transient List> routing_policy_back_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "interface-route-table"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public RouteTableType getRoutes() { + return interface_route_table_routes; + } + + public void setRoutes(RouteTableType interface_route_table_routes) { + this.interface_route_table_routes = interface_route_table_routes; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getRoutingPolicyBackRefs() { + return routing_policy_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpAddressesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpAddressesType.java new file mode 100644 index 00000000000..6c38deec63d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpAddressesType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IpAddressesType extends ApiPropertyBase { + List ip_address; + public IpAddressesType() { + } + public IpAddressesType(List ip_address) { + this.ip_address = ip_address; + } + + public List getIpAddress() { + return ip_address; + } + + + public void addIpAddress(String obj) { + if (ip_address == null) { + ip_address = new ArrayList(); + } + ip_address.add(obj); + } + public void clearIpAddress() { + ip_address = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamDnsAddressType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamDnsAddressType.java new file mode 100644 index 00000000000..68eda646433 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamDnsAddressType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IpamDnsAddressType extends ApiPropertyBase { + IpAddressesType tenant_dns_server_address; + String virtual_dns_server_name; + public IpamDnsAddressType() { + } + public IpamDnsAddressType(IpAddressesType tenant_dns_server_address, String virtual_dns_server_name) { + this.tenant_dns_server_address = tenant_dns_server_address; + this.virtual_dns_server_name = virtual_dns_server_name; + } + public IpamDnsAddressType(IpAddressesType tenant_dns_server_address) { + this(tenant_dns_server_address, null); } + + public IpAddressesType getTenantDnsServerAddress() { + return tenant_dns_server_address; + } + + public void setTenantDnsServerAddress(IpAddressesType tenant_dns_server_address) { + this.tenant_dns_server_address = tenant_dns_server_address; + } + + + public String getVirtualDnsServerName() { + return virtual_dns_server_name; + } + + public void setVirtualDnsServerName(String virtual_dns_server_name) { + this.virtual_dns_server_name = virtual_dns_server_name; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamSubnetType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamSubnetType.java new file mode 100644 index 00000000000..f6d4582d17c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamSubnetType.java @@ -0,0 +1,264 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IpamSubnetType extends ApiPropertyBase { + SubnetType subnet; + String default_gateway; + String dns_server_address; + String subnet_uuid; + Boolean enable_dhcp; + List dns_nameservers; + List allocation_pools; + Boolean addr_from_start; + DhcpOptionsListType dhcp_option_list; + RouteTableType host_routes; + String subnet_name; + Integer alloc_unit; + volatile java.util.Date created; + volatile java.util.Date last_modified; + String subscriber_tag; + Integer vlan_tag; + List dhcp_relay_server; + public IpamSubnetType() { + } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name, Integer alloc_unit, java.util.Date created, java.util.Date last_modified, String subscriber_tag, Integer vlan_tag, List dhcp_relay_server) { + this.subnet = subnet; + this.default_gateway = default_gateway; + this.dns_server_address = dns_server_address; + this.subnet_uuid = subnet_uuid; + this.enable_dhcp = enable_dhcp; + this.dns_nameservers = dns_nameservers; + this.allocation_pools = allocation_pools; + this.addr_from_start = addr_from_start; + this.dhcp_option_list = dhcp_option_list; + this.host_routes = host_routes; + this.subnet_name = subnet_name; + this.alloc_unit = alloc_unit; + this.created = created; + this.last_modified = last_modified; + this.subscriber_tag = subscriber_tag; + this.vlan_tag = vlan_tag; + this.dhcp_relay_server = dhcp_relay_server; + } + public IpamSubnetType(SubnetType subnet) { + this(subnet, null, null, null, true, null, null, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway) { + this(subnet, default_gateway, null, null, true, null, null, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address) { + this(subnet, default_gateway, dns_server_address, null, true, null, null, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, true, null, null, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, null, null, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, null, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, null, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, null, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, null, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, null, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, subnet_name, 1, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name, Integer alloc_unit) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, subnet_name, alloc_unit, null, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name, Integer alloc_unit, java.util.Date created) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, subnet_name, alloc_unit, created, null, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name, Integer alloc_unit, java.util.Date created, java.util.Date last_modified) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, subnet_name, alloc_unit, created, last_modified, null, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name, Integer alloc_unit, java.util.Date created, java.util.Date last_modified, String subscriber_tag) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, subnet_name, alloc_unit, created, last_modified, subscriber_tag, null, null); } + public IpamSubnetType(SubnetType subnet, String default_gateway, String dns_server_address, String subnet_uuid, Boolean enable_dhcp, List dns_nameservers, List allocation_pools, Boolean addr_from_start, DhcpOptionsListType dhcp_option_list, RouteTableType host_routes, String subnet_name, Integer alloc_unit, java.util.Date created, java.util.Date last_modified, String subscriber_tag, Integer vlan_tag) { + this(subnet, default_gateway, dns_server_address, subnet_uuid, enable_dhcp, dns_nameservers, allocation_pools, addr_from_start, dhcp_option_list, host_routes, subnet_name, alloc_unit, created, last_modified, subscriber_tag, vlan_tag, null); } + + public SubnetType getSubnet() { + return subnet; + } + + public void setSubnet(SubnetType subnet) { + this.subnet = subnet; + } + + + public String getDefaultGateway() { + return default_gateway; + } + + public void setDefaultGateway(String default_gateway) { + this.default_gateway = default_gateway; + } + + + public String getDnsServerAddress() { + return dns_server_address; + } + + public void setDnsServerAddress(String dns_server_address) { + this.dns_server_address = dns_server_address; + } + + + public String getSubnetUuid() { + return subnet_uuid; + } + + public void setSubnetUuid(String subnet_uuid) { + this.subnet_uuid = subnet_uuid; + } + + + public Boolean getEnableDhcp() { + return enable_dhcp; + } + + public void setEnableDhcp(Boolean enable_dhcp) { + this.enable_dhcp = enable_dhcp; + } + + + public Boolean getAddrFromStart() { + return addr_from_start; + } + + public void setAddrFromStart(Boolean addr_from_start) { + this.addr_from_start = addr_from_start; + } + + + public DhcpOptionsListType getDhcpOptionList() { + return dhcp_option_list; + } + + public void setDhcpOptionList(DhcpOptionsListType dhcp_option_list) { + this.dhcp_option_list = dhcp_option_list; + } + + + public RouteTableType getHostRoutes() { + return host_routes; + } + + public void setHostRoutes(RouteTableType host_routes) { + this.host_routes = host_routes; + } + + + public String getSubnetName() { + return subnet_name; + } + + public void setSubnetName(String subnet_name) { + this.subnet_name = subnet_name; + } + + + public Integer getAllocUnit() { + return alloc_unit; + } + + public void setAllocUnit(Integer alloc_unit) { + this.alloc_unit = alloc_unit; + } + + + public java.util.Date getCreated() { + return created; + } + + public void setCreated(java.util.Date created) { + this.created = created; + } + + + public java.util.Date getLastModified() { + return last_modified; + } + + public void setLastModified(java.util.Date last_modified) { + this.last_modified = last_modified; + } + + + public String getSubscriberTag() { + return subscriber_tag; + } + + public void setSubscriberTag(String subscriber_tag) { + this.subscriber_tag = subscriber_tag; + } + + + public Integer getVlanTag() { + return vlan_tag; + } + + public void setVlanTag(Integer vlan_tag) { + this.vlan_tag = vlan_tag; + } + + + public List getDnsNameservers() { + return dns_nameservers; + } + + + public void addDnsNameservers(String obj) { + if (dns_nameservers == null) { + dns_nameservers = new ArrayList(); + } + dns_nameservers.add(obj); + } + public void clearDnsNameservers() { + dns_nameservers = null; + } + + + public List getAllocationPools() { + return allocation_pools; + } + + + public void addAllocationPools(AllocationPoolType obj) { + if (allocation_pools == null) { + allocation_pools = new ArrayList(); + } + allocation_pools.add(obj); + } + public void clearAllocationPools() { + allocation_pools = null; + } + + + public void addAllocationPools(String start, String end, Boolean vrouter_specific_pool) { + if (allocation_pools == null) { + allocation_pools = new ArrayList(); + } + allocation_pools.add(new AllocationPoolType(start, end, vrouter_specific_pool)); + } + + + public List getDhcpRelayServer() { + return dhcp_relay_server; + } + + + public void addDhcpRelayServer(String obj) { + if (dhcp_relay_server == null) { + dhcp_relay_server = new ArrayList(); + } + dhcp_relay_server.add(obj); + } + public void clearDhcpRelayServer() { + dhcp_relay_server = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamSubnets.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamSubnets.java new file mode 100644 index 00000000000..e1e71c9dac3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamSubnets.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IpamSubnets extends ApiPropertyBase { + List subnets; + public IpamSubnets() { + } + public IpamSubnets(List subnets) { + this.subnets = subnets; + } + + public List getSubnets() { + return subnets; + } + + + public void addSubnets(IpamSubnetType obj) { + if (subnets == null) { + subnets = new ArrayList(); + } + subnets.add(obj); + } + public void clearSubnets() { + subnets = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamType.java new file mode 100644 index 00000000000..0ab66ad8fdc --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/IpamType.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class IpamType extends ApiPropertyBase { + String ipam_method; + String ipam_dns_method; + IpamDnsAddressType ipam_dns_server; + DhcpOptionsListType dhcp_option_list; + SubnetType cidr_block; + RouteTableType host_routes; + public IpamType() { + } + public IpamType(String ipam_method, String ipam_dns_method, IpamDnsAddressType ipam_dns_server, DhcpOptionsListType dhcp_option_list, SubnetType cidr_block, RouteTableType host_routes) { + this.ipam_method = ipam_method; + this.ipam_dns_method = ipam_dns_method; + this.ipam_dns_server = ipam_dns_server; + this.dhcp_option_list = dhcp_option_list; + this.cidr_block = cidr_block; + this.host_routes = host_routes; + } + public IpamType(String ipam_method) { + this(ipam_method, null, null, null, null, null); } + public IpamType(String ipam_method, String ipam_dns_method) { + this(ipam_method, ipam_dns_method, null, null, null, null); } + public IpamType(String ipam_method, String ipam_dns_method, IpamDnsAddressType ipam_dns_server) { + this(ipam_method, ipam_dns_method, ipam_dns_server, null, null, null); } + public IpamType(String ipam_method, String ipam_dns_method, IpamDnsAddressType ipam_dns_server, DhcpOptionsListType dhcp_option_list) { + this(ipam_method, ipam_dns_method, ipam_dns_server, dhcp_option_list, null, null); } + public IpamType(String ipam_method, String ipam_dns_method, IpamDnsAddressType ipam_dns_server, DhcpOptionsListType dhcp_option_list, SubnetType cidr_block) { + this(ipam_method, ipam_dns_method, ipam_dns_server, dhcp_option_list, cidr_block, null); } + + public String getIpamMethod() { + return ipam_method; + } + + public void setIpamMethod(String ipam_method) { + this.ipam_method = ipam_method; + } + + + public String getIpamDnsMethod() { + return ipam_dns_method; + } + + public void setIpamDnsMethod(String ipam_dns_method) { + this.ipam_dns_method = ipam_dns_method; + } + + + public IpamDnsAddressType getIpamDnsServer() { + return ipam_dns_server; + } + + public void setIpamDnsServer(IpamDnsAddressType ipam_dns_server) { + this.ipam_dns_server = ipam_dns_server; + } + + + public DhcpOptionsListType getDhcpOptionList() { + return dhcp_option_list; + } + + public void setDhcpOptionList(DhcpOptionsListType dhcp_option_list) { + this.dhcp_option_list = dhcp_option_list; + } + + + public SubnetType getCidrBlock() { + return cidr_block; + } + + public void setCidrBlock(SubnetType cidr_block) { + this.cidr_block = cidr_block; + } + + + public RouteTableType getHostRoutes() { + return host_routes; + } + + public void setHostRoutes(RouteTableType host_routes) { + this.host_routes = host_routes; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/JobTemplate.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/JobTemplate.java new file mode 100644 index 00000000000..ad478f57d9a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/JobTemplate.java @@ -0,0 +1,220 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class JobTemplate extends ApiObjectBase { + private Boolean job_template_synchronous_job; + private String job_template_type; + private String job_template_concurrency_level; + private PlaybookInfoListType job_template_playbooks; + private PlaybookInfoListType job_template_recovery_playbooks; + private ExecutableInfoListType job_template_executables; + private String job_template_input_schema; + private String job_template_output_schema; + private String job_template_input_ui_schema; + private String job_template_output_ui_schema; + private String job_template_description; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> node_profile_back_refs; + + @Override + public String getObjectType() { + return "job-template"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public Boolean getSynchronousJob() { + return job_template_synchronous_job; + } + + public void setSynchronousJob(Boolean job_template_synchronous_job) { + this.job_template_synchronous_job = job_template_synchronous_job; + } + + + public String getType() { + return job_template_type; + } + + public void setType(String job_template_type) { + this.job_template_type = job_template_type; + } + + + public String getConcurrencyLevel() { + return job_template_concurrency_level; + } + + public void setConcurrencyLevel(String job_template_concurrency_level) { + this.job_template_concurrency_level = job_template_concurrency_level; + } + + + public PlaybookInfoListType getPlaybooks() { + return job_template_playbooks; + } + + public void setPlaybooks(PlaybookInfoListType job_template_playbooks) { + this.job_template_playbooks = job_template_playbooks; + } + + + public PlaybookInfoListType getRecoveryPlaybooks() { + return job_template_recovery_playbooks; + } + + public void setRecoveryPlaybooks(PlaybookInfoListType job_template_recovery_playbooks) { + this.job_template_recovery_playbooks = job_template_recovery_playbooks; + } + + + public ExecutableInfoListType getExecutables() { + return job_template_executables; + } + + public void setExecutables(ExecutableInfoListType job_template_executables) { + this.job_template_executables = job_template_executables; + } + + + public String getInputSchema() { + return job_template_input_schema; + } + + public void setInputSchema(String job_template_input_schema) { + this.job_template_input_schema = job_template_input_schema; + } + + + public String getOutputSchema() { + return job_template_output_schema; + } + + public void setOutputSchema(String job_template_output_schema) { + this.job_template_output_schema = job_template_output_schema; + } + + + public String getInputUiSchema() { + return job_template_input_ui_schema; + } + + public void setInputUiSchema(String job_template_input_ui_schema) { + this.job_template_input_ui_schema = job_template_input_ui_schema; + } + + + public String getOutputUiSchema() { + return job_template_output_ui_schema; + } + + public void setOutputUiSchema(String job_template_output_ui_schema) { + this.job_template_output_ui_schema = job_template_output_ui_schema; + } + + + public String getDescription() { + return job_template_description; + } + + public void setDescription(String job_template_description) { + this.job_template_description = job_template_description; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getNodeProfileBackRefs() { + return node_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/JunosServicePorts.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/JunosServicePorts.java new file mode 100644 index 00000000000..0df8e6963c5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/JunosServicePorts.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class JunosServicePorts extends ApiPropertyBase { + List service_port; + public JunosServicePorts() { + } + public JunosServicePorts(List service_port) { + this.service_port = service_port; + } + + public List getServicePort() { + return service_port; + } + + + public void addServicePort(String obj) { + if (service_port == null) { + service_port = new ArrayList(); + } + service_port.add(obj); + } + public void clearServicePort() { + service_port = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/KeyValuePair.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/KeyValuePair.java new file mode 100644 index 00000000000..89cf7e02a6a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/KeyValuePair.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class KeyValuePair extends ApiPropertyBase { + String key; + String value; + public KeyValuePair() { + } + public KeyValuePair(String key, String value) { + this.key = key; + this.value = value; + } + public KeyValuePair(String key) { + this(key, null); } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/KeyValuePairs.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/KeyValuePairs.java new file mode 100644 index 00000000000..a415b851c43 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/KeyValuePairs.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class KeyValuePairs extends ApiPropertyBase { + List key_value_pair; + public KeyValuePairs() { + } + public KeyValuePairs(List key_value_pair) { + this.key_value_pair = key_value_pair; + } + + public List getKeyValuePair() { + return key_value_pair; + } + + + public void addKeyValuePair(KeyValuePair obj) { + if (key_value_pair == null) { + key_value_pair = new ArrayList(); + } + key_value_pair.add(obj); + } + public void clearKeyValuePair() { + key_value_pair = null; + } + + + public void addKeyValuePair(String key, String value) { + if (key_value_pair == null) { + key_value_pair = new ArrayList(); + } + key_value_pair.add(new KeyValuePair(key, value)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LacpParams.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LacpParams.java new file mode 100644 index 00000000000..67dd799e63a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LacpParams.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LacpParams extends ApiPropertyBase { + Boolean lacp_enable; + String lacp_interval; + String lacp_mode; + public LacpParams() { + } + public LacpParams(Boolean lacp_enable, String lacp_interval, String lacp_mode) { + this.lacp_enable = lacp_enable; + this.lacp_interval = lacp_interval; + this.lacp_mode = lacp_mode; + } + public LacpParams(Boolean lacp_enable) { + this(lacp_enable, null, null); } + public LacpParams(Boolean lacp_enable, String lacp_interval) { + this(lacp_enable, lacp_interval, null); } + + public Boolean getLacpEnable() { + return lacp_enable; + } + + public void setLacpEnable(Boolean lacp_enable) { + this.lacp_enable = lacp_enable; + } + + + public String getLacpInterval() { + return lacp_interval; + } + + public void setLacpInterval(String lacp_interval) { + this.lacp_interval = lacp_interval; + } + + + public String getLacpMode() { + return lacp_mode; + } + + public void setLacpMode(String lacp_mode) { + this.lacp_mode = lacp_mode; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinkAggregationGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinkAggregationGroup.java new file mode 100644 index 00000000000..a2c34655a65 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinkAggregationGroup.java @@ -0,0 +1,177 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LinkAggregationGroup extends ApiObjectBase { + private Boolean link_aggregation_group_lacp_enabled; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> physical_interface_refs; + private List> virtual_machine_interface_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "link-aggregation-group"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-physical-router"); + } + + @Override + public String getDefaultParentType() { + return "physical-router"; + } + + public void setParent(PhysicalRouter parent) { + super.setParent(parent); + } + + public Boolean getLacpEnabled() { + return link_aggregation_group_lacp_enabled; + } + + public void setLacpEnabled(Boolean link_aggregation_group_lacp_enabled) { + this.link_aggregation_group_lacp_enabled = link_aggregation_group_lacp_enabled; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPhysicalInterface() { + return physical_interface_refs; + } + + public void setPhysicalInterface(PhysicalInterface obj) { + physical_interface_refs = new ArrayList>(); + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalInterface(PhysicalInterface obj) { + if (physical_interface_refs == null) { + physical_interface_refs = new ArrayList>(); + } + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalInterface(PhysicalInterface obj) { + if (physical_interface_refs != null) { + physical_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalInterface() { + if (physical_interface_refs != null) { + physical_interface_refs.clear(); + return; + } + physical_interface_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinklocalServiceEntryType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinklocalServiceEntryType.java new file mode 100644 index 00000000000..9622b40e267 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinklocalServiceEntryType.java @@ -0,0 +1,99 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LinklocalServiceEntryType extends ApiPropertyBase { + String linklocal_service_name; + String linklocal_service_ip; + Integer linklocal_service_port; + String ip_fabric_DNS_service_name; + Integer ip_fabric_service_port; + List ip_fabric_service_ip; + public LinklocalServiceEntryType() { + } + public LinklocalServiceEntryType(String linklocal_service_name, String linklocal_service_ip, Integer linklocal_service_port, String ip_fabric_DNS_service_name, Integer ip_fabric_service_port, List ip_fabric_service_ip) { + this.linklocal_service_name = linklocal_service_name; + this.linklocal_service_ip = linklocal_service_ip; + this.linklocal_service_port = linklocal_service_port; + this.ip_fabric_DNS_service_name = ip_fabric_DNS_service_name; + this.ip_fabric_service_port = ip_fabric_service_port; + this.ip_fabric_service_ip = ip_fabric_service_ip; + } + public LinklocalServiceEntryType(String linklocal_service_name) { + this(linklocal_service_name, null, null, null, null, null); } + public LinklocalServiceEntryType(String linklocal_service_name, String linklocal_service_ip) { + this(linklocal_service_name, linklocal_service_ip, null, null, null, null); } + public LinklocalServiceEntryType(String linklocal_service_name, String linklocal_service_ip, Integer linklocal_service_port) { + this(linklocal_service_name, linklocal_service_ip, linklocal_service_port, null, null, null); } + public LinklocalServiceEntryType(String linklocal_service_name, String linklocal_service_ip, Integer linklocal_service_port, String ip_fabric_DNS_service_name) { + this(linklocal_service_name, linklocal_service_ip, linklocal_service_port, ip_fabric_DNS_service_name, null, null); } + public LinklocalServiceEntryType(String linklocal_service_name, String linklocal_service_ip, Integer linklocal_service_port, String ip_fabric_DNS_service_name, Integer ip_fabric_service_port) { + this(linklocal_service_name, linklocal_service_ip, linklocal_service_port, ip_fabric_DNS_service_name, ip_fabric_service_port, null); } + + public String getLinklocalServiceName() { + return linklocal_service_name; + } + + public void setLinklocalServiceName(String linklocal_service_name) { + this.linklocal_service_name = linklocal_service_name; + } + + + public String getLinklocalServiceIp() { + return linklocal_service_ip; + } + + public void setLinklocalServiceIp(String linklocal_service_ip) { + this.linklocal_service_ip = linklocal_service_ip; + } + + + public Integer getLinklocalServicePort() { + return linklocal_service_port; + } + + public void setLinklocalServicePort(Integer linklocal_service_port) { + this.linklocal_service_port = linklocal_service_port; + } + + + public String getIpFabricDnsServiceName() { + return ip_fabric_DNS_service_name; + } + + public void setIpFabricDnsServiceName(String ip_fabric_DNS_service_name) { + this.ip_fabric_DNS_service_name = ip_fabric_DNS_service_name; + } + + + public Integer getIpFabricServicePort() { + return ip_fabric_service_port; + } + + public void setIpFabricServicePort(Integer ip_fabric_service_port) { + this.ip_fabric_service_port = ip_fabric_service_port; + } + + + public List getIpFabricServiceIp() { + return ip_fabric_service_ip; + } + + + public void addIpFabricServiceIp(String obj) { + if (ip_fabric_service_ip == null) { + ip_fabric_service_ip = new ArrayList(); + } + ip_fabric_service_ip.add(obj); + } + public void clearIpFabricServiceIp() { + ip_fabric_service_ip = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinklocalServicesTypes.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinklocalServicesTypes.java new file mode 100644 index 00000000000..edab4cb77ae --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LinklocalServicesTypes.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LinklocalServicesTypes extends ApiPropertyBase { + List linklocal_service_entry; + public LinklocalServicesTypes() { + } + public LinklocalServicesTypes(List linklocal_service_entry) { + this.linklocal_service_entry = linklocal_service_entry; + } + + public List getLinklocalServiceEntry() { + return linklocal_service_entry; + } + + + public void addLinklocalServiceEntry(LinklocalServiceEntryType obj) { + if (linklocal_service_entry == null) { + linklocal_service_entry = new ArrayList(); + } + linklocal_service_entry.add(obj); + } + public void clearLinklocalServiceEntry() { + linklocal_service_entry = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Loadbalancer.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Loadbalancer.java new file mode 100644 index 00000000000..5b213d006f5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Loadbalancer.java @@ -0,0 +1,223 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Loadbalancer extends ApiObjectBase { + private LoadbalancerType loadbalancer_properties; + private String loadbalancer_provider; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_appliance_set_refs; + private List> service_instance_refs; + private List> virtual_machine_interface_refs; + private List> tag_refs; + private transient List> loadbalancer_listener_back_refs; + + @Override + public String getObjectType() { + return "loadbalancer"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public LoadbalancerType getProperties() { + return loadbalancer_properties; + } + + public void setProperties(LoadbalancerType loadbalancer_properties) { + this.loadbalancer_properties = loadbalancer_properties; + } + + + public String getProvider() { + return loadbalancer_provider; + } + + public void setProvider(String loadbalancer_provider) { + this.loadbalancer_provider = loadbalancer_provider; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceApplianceSet() { + return service_appliance_set_refs; + } + + public void setServiceApplianceSet(ServiceApplianceSet obj) { + service_appliance_set_refs = new ArrayList>(); + service_appliance_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceApplianceSet(ServiceApplianceSet obj) { + if (service_appliance_set_refs == null) { + service_appliance_set_refs = new ArrayList>(); + } + service_appliance_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceApplianceSet(ServiceApplianceSet obj) { + if (service_appliance_set_refs != null) { + service_appliance_set_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceApplianceSet() { + if (service_appliance_set_refs != null) { + service_appliance_set_refs.clear(); + return; + } + service_appliance_set_refs = null; + } + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceInstance(ServiceInstance obj) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceInstance(ServiceInstance obj) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getLoadbalancerListenerBackRefs() { + return loadbalancer_listener_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerHealthmonitor.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerHealthmonitor.java new file mode 100644 index 00000000000..5f6501445ae --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerHealthmonitor.java @@ -0,0 +1,120 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LoadbalancerHealthmonitor extends ApiObjectBase { + private LoadbalancerHealthmonitorType loadbalancer_healthmonitor_properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> loadbalancer_pool_back_refs; + + @Override + public String getObjectType() { + return "loadbalancer-healthmonitor"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public LoadbalancerHealthmonitorType getProperties() { + return loadbalancer_healthmonitor_properties; + } + + public void setProperties(LoadbalancerHealthmonitorType loadbalancer_healthmonitor_properties) { + this.loadbalancer_healthmonitor_properties = loadbalancer_healthmonitor_properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getLoadbalancerPoolBackRefs() { + return loadbalancer_pool_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerHealthmonitorType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerHealthmonitorType.java new file mode 100644 index 00000000000..6db39262782 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerHealthmonitorType.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LoadbalancerHealthmonitorType extends ApiPropertyBase { + Boolean admin_state; + String monitor_type; + Integer delay; + Integer timeout; + Integer max_retries; + String http_method; + String url_path; + String expected_codes; + public LoadbalancerHealthmonitorType() { + } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type, Integer delay, Integer timeout, Integer max_retries, String http_method, String url_path, String expected_codes) { + this.admin_state = admin_state; + this.monitor_type = monitor_type; + this.delay = delay; + this.timeout = timeout; + this.max_retries = max_retries; + this.http_method = http_method; + this.url_path = url_path; + this.expected_codes = expected_codes; + } + public LoadbalancerHealthmonitorType(Boolean admin_state) { + this(admin_state, null, null, null, null, null, null, null); } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type) { + this(admin_state, monitor_type, null, null, null, null, null, null); } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type, Integer delay) { + this(admin_state, monitor_type, delay, null, null, null, null, null); } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type, Integer delay, Integer timeout) { + this(admin_state, monitor_type, delay, timeout, null, null, null, null); } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type, Integer delay, Integer timeout, Integer max_retries) { + this(admin_state, monitor_type, delay, timeout, max_retries, null, null, null); } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type, Integer delay, Integer timeout, Integer max_retries, String http_method) { + this(admin_state, monitor_type, delay, timeout, max_retries, http_method, null, null); } + public LoadbalancerHealthmonitorType(Boolean admin_state, String monitor_type, Integer delay, Integer timeout, Integer max_retries, String http_method, String url_path) { + this(admin_state, monitor_type, delay, timeout, max_retries, http_method, url_path, null); } + + public Boolean getAdminState() { + return admin_state; + } + + public void setAdminState(Boolean admin_state) { + this.admin_state = admin_state; + } + + + public String getMonitorType() { + return monitor_type; + } + + public void setMonitorType(String monitor_type) { + this.monitor_type = monitor_type; + } + + + public Integer getDelay() { + return delay; + } + + public void setDelay(Integer delay) { + this.delay = delay; + } + + + public Integer getTimeout() { + return timeout; + } + + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } + + + public Integer getMaxRetries() { + return max_retries; + } + + public void setMaxRetries(Integer max_retries) { + this.max_retries = max_retries; + } + + + public String getHttpMethod() { + return http_method; + } + + public void setHttpMethod(String http_method) { + this.http_method = http_method; + } + + + public String getUrlPath() { + return url_path; + } + + public void setUrlPath(String url_path) { + this.url_path = url_path; + } + + + public String getExpectedCodes() { + return expected_codes; + } + + public void setExpectedCodes(String expected_codes) { + this.expected_codes = expected_codes; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerListener.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerListener.java new file mode 100644 index 00000000000..6173910224f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerListener.java @@ -0,0 +1,151 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LoadbalancerListener extends ApiObjectBase { + private LoadbalancerListenerType loadbalancer_listener_properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> loadbalancer_refs; + private List> tag_refs; + private transient List> loadbalancer_pool_back_refs; + + @Override + public String getObjectType() { + return "loadbalancer-listener"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public LoadbalancerListenerType getProperties() { + return loadbalancer_listener_properties; + } + + public void setProperties(LoadbalancerListenerType loadbalancer_listener_properties) { + this.loadbalancer_listener_properties = loadbalancer_listener_properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getLoadbalancer() { + return loadbalancer_refs; + } + + public void setLoadbalancer(Loadbalancer obj) { + loadbalancer_refs = new ArrayList>(); + loadbalancer_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLoadbalancer(Loadbalancer obj) { + if (loadbalancer_refs == null) { + loadbalancer_refs = new ArrayList>(); + } + loadbalancer_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLoadbalancer(Loadbalancer obj) { + if (loadbalancer_refs != null) { + loadbalancer_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLoadbalancer() { + if (loadbalancer_refs != null) { + loadbalancer_refs.clear(); + return; + } + loadbalancer_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getLoadbalancerPoolBackRefs() { + return loadbalancer_pool_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerListenerType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerListenerType.java new file mode 100644 index 00000000000..50f0d6fcc4c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerListenerType.java @@ -0,0 +1,99 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LoadbalancerListenerType extends ApiPropertyBase { + String protocol; + Integer protocol_port; + Boolean admin_state; + Integer connection_limit; + String default_tls_container; + List sni_containers; + public LoadbalancerListenerType() { + } + public LoadbalancerListenerType(String protocol, Integer protocol_port, Boolean admin_state, Integer connection_limit, String default_tls_container, List sni_containers) { + this.protocol = protocol; + this.protocol_port = protocol_port; + this.admin_state = admin_state; + this.connection_limit = connection_limit; + this.default_tls_container = default_tls_container; + this.sni_containers = sni_containers; + } + public LoadbalancerListenerType(String protocol) { + this(protocol, null, true, null, null, null); } + public LoadbalancerListenerType(String protocol, Integer protocol_port) { + this(protocol, protocol_port, true, null, null, null); } + public LoadbalancerListenerType(String protocol, Integer protocol_port, Boolean admin_state) { + this(protocol, protocol_port, admin_state, null, null, null); } + public LoadbalancerListenerType(String protocol, Integer protocol_port, Boolean admin_state, Integer connection_limit) { + this(protocol, protocol_port, admin_state, connection_limit, null, null); } + public LoadbalancerListenerType(String protocol, Integer protocol_port, Boolean admin_state, Integer connection_limit, String default_tls_container) { + this(protocol, protocol_port, admin_state, connection_limit, default_tls_container, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Integer getProtocolPort() { + return protocol_port; + } + + public void setProtocolPort(Integer protocol_port) { + this.protocol_port = protocol_port; + } + + + public Boolean getAdminState() { + return admin_state; + } + + public void setAdminState(Boolean admin_state) { + this.admin_state = admin_state; + } + + + public Integer getConnectionLimit() { + return connection_limit; + } + + public void setConnectionLimit(Integer connection_limit) { + this.connection_limit = connection_limit; + } + + + public String getDefaultTlsContainer() { + return default_tls_container; + } + + public void setDefaultTlsContainer(String default_tls_container) { + this.default_tls_container = default_tls_container; + } + + + public List getSniContainers() { + return sni_containers; + } + + + public void addSniContainers(String obj) { + if (sni_containers == null) { + sni_containers = new ArrayList(); + } + sni_containers.add(obj); + } + public void clearSniContainers() { + sni_containers = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerMember.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerMember.java new file mode 100644 index 00000000000..d5e2104ba9e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerMember.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LoadbalancerMember extends ApiObjectBase { + private LoadbalancerMemberType loadbalancer_member_properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "loadbalancer-member"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-loadbalancer-pool"); + } + + @Override + public String getDefaultParentType() { + return "loadbalancer-pool"; + } + + public void setParent(LoadbalancerPool parent) { + super.setParent(parent); + } + + public LoadbalancerMemberType getProperties() { + return loadbalancer_member_properties; + } + + public void setProperties(LoadbalancerMemberType loadbalancer_member_properties) { + this.loadbalancer_member_properties = loadbalancer_member_properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerMemberType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerMemberType.java new file mode 100644 index 00000000000..2216a44bc31 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerMemberType.java @@ -0,0 +1,102 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LoadbalancerMemberType extends ApiPropertyBase { + Boolean admin_state; + String status; + String status_description; + Integer protocol_port; + Integer weight; + String address; + String subnet_id; + public LoadbalancerMemberType() { + } + public LoadbalancerMemberType(Boolean admin_state, String status, String status_description, Integer protocol_port, Integer weight, String address, String subnet_id) { + this.admin_state = admin_state; + this.status = status; + this.status_description = status_description; + this.protocol_port = protocol_port; + this.weight = weight; + this.address = address; + this.subnet_id = subnet_id; + } + public LoadbalancerMemberType(Boolean admin_state) { + this(admin_state, null, null, null, 1, null, null); } + public LoadbalancerMemberType(Boolean admin_state, String status) { + this(admin_state, status, null, null, 1, null, null); } + public LoadbalancerMemberType(Boolean admin_state, String status, String status_description) { + this(admin_state, status, status_description, null, 1, null, null); } + public LoadbalancerMemberType(Boolean admin_state, String status, String status_description, Integer protocol_port) { + this(admin_state, status, status_description, protocol_port, 1, null, null); } + public LoadbalancerMemberType(Boolean admin_state, String status, String status_description, Integer protocol_port, Integer weight) { + this(admin_state, status, status_description, protocol_port, weight, null, null); } + public LoadbalancerMemberType(Boolean admin_state, String status, String status_description, Integer protocol_port, Integer weight, String address) { + this(admin_state, status, status_description, protocol_port, weight, address, null); } + + public Boolean getAdminState() { + return admin_state; + } + + public void setAdminState(Boolean admin_state) { + this.admin_state = admin_state; + } + + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + public String getStatusDescription() { + return status_description; + } + + public void setStatusDescription(String status_description) { + this.status_description = status_description; + } + + + public Integer getProtocolPort() { + return protocol_port; + } + + public void setProtocolPort(Integer protocol_port) { + this.protocol_port = protocol_port; + } + + + public Integer getWeight() { + return weight; + } + + public void setWeight(Integer weight) { + this.weight = weight; + } + + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + + public String getSubnetId() { + return subnet_id; + } + + public void setSubnetId(String subnet_id) { + this.subnet_id = subnet_id; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerPool.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerPool.java new file mode 100644 index 00000000000..11a851f90f9 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerPool.java @@ -0,0 +1,300 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LoadbalancerPool extends ApiObjectBase { + private LoadbalancerPoolType loadbalancer_pool_properties; + private String loadbalancer_pool_provider; + private KeyValuePairs loadbalancer_pool_custom_attributes; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_instance_refs; + private List> virtual_machine_interface_refs; + private List> loadbalancer_listener_refs; + private List> service_appliance_set_refs; + private List> loadbalancer_members; + private List> loadbalancer_healthmonitor_refs; + private List> tag_refs; + private transient List> virtual_ip_back_refs; + + @Override + public String getObjectType() { + return "loadbalancer-pool"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public LoadbalancerPoolType getProperties() { + return loadbalancer_pool_properties; + } + + public void setProperties(LoadbalancerPoolType loadbalancer_pool_properties) { + this.loadbalancer_pool_properties = loadbalancer_pool_properties; + } + + + public String getProvider() { + return loadbalancer_pool_provider; + } + + public void setProvider(String loadbalancer_pool_provider) { + this.loadbalancer_pool_provider = loadbalancer_pool_provider; + } + + + public KeyValuePairs getCustomAttributes() { + return loadbalancer_pool_custom_attributes; + } + + public void setCustomAttributes(KeyValuePairs loadbalancer_pool_custom_attributes) { + this.loadbalancer_pool_custom_attributes = loadbalancer_pool_custom_attributes; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceInstance(ServiceInstance obj) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceInstance(ServiceInstance obj) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getLoadbalancerListener() { + return loadbalancer_listener_refs; + } + + public void setLoadbalancerListener(LoadbalancerListener obj) { + loadbalancer_listener_refs = new ArrayList>(); + loadbalancer_listener_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLoadbalancerListener(LoadbalancerListener obj) { + if (loadbalancer_listener_refs == null) { + loadbalancer_listener_refs = new ArrayList>(); + } + loadbalancer_listener_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLoadbalancerListener(LoadbalancerListener obj) { + if (loadbalancer_listener_refs != null) { + loadbalancer_listener_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLoadbalancerListener() { + if (loadbalancer_listener_refs != null) { + loadbalancer_listener_refs.clear(); + return; + } + loadbalancer_listener_refs = null; + } + + public List> getServiceApplianceSet() { + return service_appliance_set_refs; + } + + public void setServiceApplianceSet(ServiceApplianceSet obj) { + service_appliance_set_refs = new ArrayList>(); + service_appliance_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceApplianceSet(ServiceApplianceSet obj) { + if (service_appliance_set_refs == null) { + service_appliance_set_refs = new ArrayList>(); + } + service_appliance_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceApplianceSet(ServiceApplianceSet obj) { + if (service_appliance_set_refs != null) { + service_appliance_set_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceApplianceSet() { + if (service_appliance_set_refs != null) { + service_appliance_set_refs.clear(); + return; + } + service_appliance_set_refs = null; + } + + public List> getLoadbalancerMembers() { + return loadbalancer_members; + } + + public List> getLoadbalancerHealthmonitor() { + return loadbalancer_healthmonitor_refs; + } + + public void setLoadbalancerHealthmonitor(LoadbalancerHealthmonitor obj) { + loadbalancer_healthmonitor_refs = new ArrayList>(); + loadbalancer_healthmonitor_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLoadbalancerHealthmonitor(LoadbalancerHealthmonitor obj) { + if (loadbalancer_healthmonitor_refs == null) { + loadbalancer_healthmonitor_refs = new ArrayList>(); + } + loadbalancer_healthmonitor_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLoadbalancerHealthmonitor(LoadbalancerHealthmonitor obj) { + if (loadbalancer_healthmonitor_refs != null) { + loadbalancer_healthmonitor_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLoadbalancerHealthmonitor() { + if (loadbalancer_healthmonitor_refs != null) { + loadbalancer_healthmonitor_refs.clear(); + return; + } + loadbalancer_healthmonitor_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualIpBackRefs() { + return virtual_ip_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerPoolType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerPoolType.java new file mode 100644 index 00000000000..0e215781f4c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerPoolType.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LoadbalancerPoolType extends ApiPropertyBase { + String status; + String status_description; + Boolean admin_state; + String protocol; + String loadbalancer_method; + String subnet_id; + String session_persistence; + String persistence_cookie_name; + public LoadbalancerPoolType() { + } + public LoadbalancerPoolType(String status, String status_description, Boolean admin_state, String protocol, String loadbalancer_method, String subnet_id, String session_persistence, String persistence_cookie_name) { + this.status = status; + this.status_description = status_description; + this.admin_state = admin_state; + this.protocol = protocol; + this.loadbalancer_method = loadbalancer_method; + this.subnet_id = subnet_id; + this.session_persistence = session_persistence; + this.persistence_cookie_name = persistence_cookie_name; + } + public LoadbalancerPoolType(String status) { + this(status, null, true, null, null, null, null, null); } + public LoadbalancerPoolType(String status, String status_description) { + this(status, status_description, true, null, null, null, null, null); } + public LoadbalancerPoolType(String status, String status_description, Boolean admin_state) { + this(status, status_description, admin_state, null, null, null, null, null); } + public LoadbalancerPoolType(String status, String status_description, Boolean admin_state, String protocol) { + this(status, status_description, admin_state, protocol, null, null, null, null); } + public LoadbalancerPoolType(String status, String status_description, Boolean admin_state, String protocol, String loadbalancer_method) { + this(status, status_description, admin_state, protocol, loadbalancer_method, null, null, null); } + public LoadbalancerPoolType(String status, String status_description, Boolean admin_state, String protocol, String loadbalancer_method, String subnet_id) { + this(status, status_description, admin_state, protocol, loadbalancer_method, subnet_id, null, null); } + public LoadbalancerPoolType(String status, String status_description, Boolean admin_state, String protocol, String loadbalancer_method, String subnet_id, String session_persistence) { + this(status, status_description, admin_state, protocol, loadbalancer_method, subnet_id, session_persistence, null); } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + public String getStatusDescription() { + return status_description; + } + + public void setStatusDescription(String status_description) { + this.status_description = status_description; + } + + + public Boolean getAdminState() { + return admin_state; + } + + public void setAdminState(Boolean admin_state) { + this.admin_state = admin_state; + } + + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public String getLoadbalancerMethod() { + return loadbalancer_method; + } + + public void setLoadbalancerMethod(String loadbalancer_method) { + this.loadbalancer_method = loadbalancer_method; + } + + + public String getSubnetId() { + return subnet_id; + } + + public void setSubnetId(String subnet_id) { + this.subnet_id = subnet_id; + } + + + public String getSessionPersistence() { + return session_persistence; + } + + public void setSessionPersistence(String session_persistence) { + this.session_persistence = session_persistence; + } + + + public String getPersistenceCookieName() { + return persistence_cookie_name; + } + + public void setPersistenceCookieName(String persistence_cookie_name) { + this.persistence_cookie_name = persistence_cookie_name; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerType.java new file mode 100644 index 00000000000..c4a401ae719 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LoadbalancerType.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LoadbalancerType extends ApiPropertyBase { + String status; + String provisioning_status; + String operating_status; + String vip_subnet_id; + String vip_address; + Boolean admin_state; + public LoadbalancerType() { + } + public LoadbalancerType(String status, String provisioning_status, String operating_status, String vip_subnet_id, String vip_address, Boolean admin_state) { + this.status = status; + this.provisioning_status = provisioning_status; + this.operating_status = operating_status; + this.vip_subnet_id = vip_subnet_id; + this.vip_address = vip_address; + this.admin_state = admin_state; + } + public LoadbalancerType(String status) { + this(status, null, null, null, null, true); } + public LoadbalancerType(String status, String provisioning_status) { + this(status, provisioning_status, null, null, null, true); } + public LoadbalancerType(String status, String provisioning_status, String operating_status) { + this(status, provisioning_status, operating_status, null, null, true); } + public LoadbalancerType(String status, String provisioning_status, String operating_status, String vip_subnet_id) { + this(status, provisioning_status, operating_status, vip_subnet_id, null, true); } + public LoadbalancerType(String status, String provisioning_status, String operating_status, String vip_subnet_id, String vip_address) { + this(status, provisioning_status, operating_status, vip_subnet_id, vip_address, true); } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + public String getProvisioningStatus() { + return provisioning_status; + } + + public void setProvisioningStatus(String provisioning_status) { + this.provisioning_status = provisioning_status; + } + + + public String getOperatingStatus() { + return operating_status; + } + + public void setOperatingStatus(String operating_status) { + this.operating_status = operating_status; + } + + + public String getVipSubnetId() { + return vip_subnet_id; + } + + public void setVipSubnetId(String vip_subnet_id) { + this.vip_subnet_id = vip_subnet_id; + } + + + public String getVipAddress() { + return vip_address; + } + + public void setVipAddress(String vip_address) { + this.vip_address = vip_address; + } + + + public Boolean getAdminState() { + return admin_state; + } + + public void setAdminState(Boolean admin_state) { + this.admin_state = admin_state; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LocalLinkConnection.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LocalLinkConnection.java new file mode 100644 index 00000000000..cd6461fbcea --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LocalLinkConnection.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LocalLinkConnection extends ApiPropertyBase { + String switch_info; + String port_index; + String port_id; + String switch_id; + public LocalLinkConnection() { + } + public LocalLinkConnection(String switch_info, String port_index, String port_id, String switch_id) { + this.switch_info = switch_info; + this.port_index = port_index; + this.port_id = port_id; + this.switch_id = switch_id; + } + public LocalLinkConnection(String switch_info) { + this(switch_info, null, null, null); } + public LocalLinkConnection(String switch_info, String port_index) { + this(switch_info, port_index, null, null); } + public LocalLinkConnection(String switch_info, String port_index, String port_id) { + this(switch_info, port_index, port_id, null); } + + public String getSwitchInfo() { + return switch_info; + } + + public void setSwitchInfo(String switch_info) { + this.switch_info = switch_info; + } + + + public String getPortIndex() { + return port_index; + } + + public void setPortIndex(String port_index) { + this.port_index = port_index; + } + + + public String getPortId() { + return port_id; + } + + public void setPortId(String port_id) { + this.port_id = port_id; + } + + + public String getSwitchId() { + return switch_id; + } + + public void setSwitchId(String switch_id) { + this.switch_id = switch_id; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalInterface.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalInterface.java new file mode 100644 index 00000000000..52de6a1b033 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalInterface.java @@ -0,0 +1,174 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LogicalInterface extends ApiObjectBase { + private Integer logical_interface_vlan_tag; + private PortParameters logical_interface_port_params; + private String logical_interface_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_machine_interface_refs; + private List> tag_refs; + private transient List> instance_ip_back_refs; + + @Override + public String getObjectType() { + return "logical-interface"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(PhysicalRouter parent) { + super.setParent(parent); + } + + public void setParent(PhysicalInterface parent) { + super.setParent(parent); + } + + public Integer getVlanTag() { + return logical_interface_vlan_tag; + } + + public void setVlanTag(Integer logical_interface_vlan_tag) { + this.logical_interface_vlan_tag = logical_interface_vlan_tag; + } + + + public PortParameters getPortParams() { + return logical_interface_port_params; + } + + public void setPortParams(PortParameters logical_interface_port_params) { + this.logical_interface_port_params = logical_interface_port_params; + } + + + public String getType() { + return logical_interface_type; + } + + public void setType(String logical_interface_type) { + this.logical_interface_type = logical_interface_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouter.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouter.java new file mode 100644 index 00000000000..fe1ae3af9f1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouter.java @@ -0,0 +1,414 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class LogicalRouter extends ApiObjectBase { + private RouteTargetList configured_route_target_list; + private String vxlan_network_identifier; + private IpAddressesType logical_router_dhcp_relay_server; + private Boolean logical_router_gateway_external; + private String logical_router_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_machine_interface_refs; + private List> route_target_refs; + private List> route_table_refs; + private List> virtual_network_refs; + private List> service_instance_refs; + private List> physical_router_refs; + private List> fabric_refs; + private List> bgpvpn_refs; + private List> tag_refs; + private transient List> port_tuple_back_refs; + private transient List> data_center_interconnect_back_refs; + + @Override + public String getObjectType() { + return "logical-router"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public RouteTargetList getConfiguredRouteTargetList() { + return configured_route_target_list; + } + + public void setConfiguredRouteTargetList(RouteTargetList configured_route_target_list) { + this.configured_route_target_list = configured_route_target_list; + } + + + public String getVxlanNetworkIdentifier() { + return vxlan_network_identifier; + } + + public void setVxlanNetworkIdentifier(String vxlan_network_identifier) { + this.vxlan_network_identifier = vxlan_network_identifier; + } + + + public IpAddressesType getDhcpRelayServer() { + return logical_router_dhcp_relay_server; + } + + public void setDhcpRelayServer(IpAddressesType logical_router_dhcp_relay_server) { + this.logical_router_dhcp_relay_server = logical_router_dhcp_relay_server; + } + + + public Boolean getGatewayExternal() { + return logical_router_gateway_external; + } + + public void setGatewayExternal(Boolean logical_router_gateway_external) { + this.logical_router_gateway_external = logical_router_gateway_external; + } + + + public String getType() { + return logical_router_type; + } + + public void setType(String logical_router_type) { + this.logical_router_type = logical_router_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getRouteTarget() { + return route_target_refs; + } + + public void setRouteTarget(RouteTarget obj) { + route_target_refs = new ArrayList>(); + route_target_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addRouteTarget(RouteTarget obj) { + if (route_target_refs == null) { + route_target_refs = new ArrayList>(); + } + route_target_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeRouteTarget(RouteTarget obj) { + if (route_target_refs != null) { + route_target_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearRouteTarget() { + if (route_target_refs != null) { + route_target_refs.clear(); + return; + } + route_target_refs = null; + } + + public List> getRouteTable() { + return route_table_refs; + } + + public void setRouteTable(RouteTable obj) { + route_table_refs = new ArrayList>(); + route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addRouteTable(RouteTable obj) { + if (route_table_refs == null) { + route_table_refs = new ArrayList>(); + } + route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeRouteTable(RouteTable obj) { + if (route_table_refs != null) { + route_table_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearRouteTable() { + if (route_table_refs != null) { + route_table_refs.clear(); + return; + } + route_table_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj, LogicalRouterVirtualNetworkType data) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addVirtualNetwork(VirtualNetwork obj, LogicalRouterVirtualNetworkType data) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeVirtualNetwork(VirtualNetwork obj, LogicalRouterVirtualNetworkType data) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceInstance(ServiceInstance obj) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceInstance(ServiceInstance obj) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + public List> getPhysicalRouter() { + return physical_router_refs; + } + + public void setPhysicalRouter(PhysicalRouter obj) { + physical_router_refs = new ArrayList>(); + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs == null) { + physical_router_refs = new ArrayList>(); + } + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs != null) { + physical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRouter() { + if (physical_router_refs != null) { + physical_router_refs.clear(); + return; + } + physical_router_refs = null; + } + + public List> getFabric() { + return fabric_refs; + } + + public void setFabric(Fabric obj) { + fabric_refs = new ArrayList>(); + fabric_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFabric(Fabric obj) { + if (fabric_refs == null) { + fabric_refs = new ArrayList>(); + } + fabric_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFabric(Fabric obj) { + if (fabric_refs != null) { + fabric_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFabric() { + if (fabric_refs != null) { + fabric_refs.clear(); + return; + } + fabric_refs = null; + } + + public List> getBgpvpn() { + return bgpvpn_refs; + } + + public void setBgpvpn(Bgpvpn obj) { + bgpvpn_refs = new ArrayList>(); + bgpvpn_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addBgpvpn(Bgpvpn obj) { + if (bgpvpn_refs == null) { + bgpvpn_refs = new ArrayList>(); + } + bgpvpn_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeBgpvpn(Bgpvpn obj) { + if (bgpvpn_refs != null) { + bgpvpn_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearBgpvpn() { + if (bgpvpn_refs != null) { + bgpvpn_refs.clear(); + return; + } + bgpvpn_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPortTupleBackRefs() { + return port_tuple_back_refs; + } + + public List> getDataCenterInterconnectBackRefs() { + return data_center_interconnect_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterPRListParams.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterPRListParams.java new file mode 100644 index 00000000000..df5baa31aaa --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterPRListParams.java @@ -0,0 +1,47 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LogicalRouterPRListParams extends ApiPropertyBase { + String logical_router_uuid; + List physical_router_uuid_list; + public LogicalRouterPRListParams() { + } + public LogicalRouterPRListParams(String logical_router_uuid, List physical_router_uuid_list) { + this.logical_router_uuid = logical_router_uuid; + this.physical_router_uuid_list = physical_router_uuid_list; + } + public LogicalRouterPRListParams(String logical_router_uuid) { + this(logical_router_uuid, null); } + + public String getLogicalRouterUuid() { + return logical_router_uuid; + } + + public void setLogicalRouterUuid(String logical_router_uuid) { + this.logical_router_uuid = logical_router_uuid; + } + + + public List getPhysicalRouterUuidList() { + return physical_router_uuid_list; + } + + + public void addPhysicalRouterUuid(String obj) { + if (physical_router_uuid_list == null) { + physical_router_uuid_list = new ArrayList(); + } + physical_router_uuid_list.add(obj); + } + public void clearPhysicalRouterUuid() { + physical_router_uuid_list = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterPRListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterPRListType.java new file mode 100644 index 00000000000..f72ec2a5f57 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterPRListType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LogicalRouterPRListType extends ApiPropertyBase { + List logical_router_list; + public LogicalRouterPRListType() { + } + public LogicalRouterPRListType(List logical_router_list) { + this.logical_router_list = logical_router_list; + } + + public List getLogicalRouterList() { + return logical_router_list; + } + + + public void addLogicalRouter(LogicalRouterPRListParams obj) { + if (logical_router_list == null) { + logical_router_list = new ArrayList(); + } + logical_router_list.add(obj); + } + public void clearLogicalRouter() { + logical_router_list = null; + } + + + public void addLogicalRouter(String logical_router_uuid, List physical_router_uuid_list) { + if (logical_router_list == null) { + logical_router_list = new ArrayList(); + } + logical_router_list.add(new LogicalRouterPRListParams(logical_router_uuid, physical_router_uuid_list)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterVirtualNetworkType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterVirtualNetworkType.java new file mode 100644 index 00000000000..add1a5bef73 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/LogicalRouterVirtualNetworkType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class LogicalRouterVirtualNetworkType extends ApiPropertyBase { + String logical_router_virtual_network_type; + public LogicalRouterVirtualNetworkType() { + } + public LogicalRouterVirtualNetworkType(String logical_router_virtual_network_type) { + this.logical_router_virtual_network_type = logical_router_virtual_network_type; + } + + public String getLogicalRouterVirtualNetworkType() { + return logical_router_virtual_network_type; + } + + public void setLogicalRouterVirtualNetworkType(String logical_router_virtual_network_type) { + this.logical_router_virtual_network_type = logical_router_virtual_network_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MACLimitControlType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MACLimitControlType.java new file mode 100644 index 00000000000..a75fb0837b6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MACLimitControlType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MACLimitControlType extends ApiPropertyBase { + Integer mac_limit; + String mac_limit_action; + public MACLimitControlType() { + } + public MACLimitControlType(Integer mac_limit, String mac_limit_action) { + this.mac_limit = mac_limit; + this.mac_limit_action = mac_limit_action; + } + public MACLimitControlType(Integer mac_limit) { + this(mac_limit, "log"); } + + public Integer getMacLimit() { + return mac_limit; + } + + public void setMacLimit(Integer mac_limit) { + this.mac_limit = mac_limit; + } + + + public String getMacLimitAction() { + return mac_limit_action; + } + + public void setMacLimitAction(String mac_limit_action) { + this.mac_limit_action = mac_limit_action; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MACMoveLimitControlType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MACMoveLimitControlType.java new file mode 100644 index 00000000000..9d058da4cde --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MACMoveLimitControlType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MACMoveLimitControlType extends ApiPropertyBase { + Integer mac_move_limit; + Integer mac_move_time_window; + String mac_move_limit_action; + public MACMoveLimitControlType() { + } + public MACMoveLimitControlType(Integer mac_move_limit, Integer mac_move_time_window, String mac_move_limit_action) { + this.mac_move_limit = mac_move_limit; + this.mac_move_time_window = mac_move_time_window; + this.mac_move_limit_action = mac_move_limit_action; + } + public MACMoveLimitControlType(Integer mac_move_limit) { + this(mac_move_limit, 10, "log"); } + public MACMoveLimitControlType(Integer mac_move_limit, Integer mac_move_time_window) { + this(mac_move_limit, mac_move_time_window, "log"); } + + public Integer getMacMoveLimit() { + return mac_move_limit; + } + + public void setMacMoveLimit(Integer mac_move_limit) { + this.mac_move_limit = mac_move_limit; + } + + + public Integer getMacMoveTimeWindow() { + return mac_move_time_window; + } + + public void setMacMoveTimeWindow(Integer mac_move_time_window) { + this.mac_move_time_window = mac_move_time_window; + } + + + public String getMacMoveLimitAction() { + return mac_move_limit_action; + } + + public void setMacMoveLimitAction(String mac_move_limit_action) { + this.mac_move_limit_action = mac_move_limit_action; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MacAddressesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MacAddressesType.java new file mode 100644 index 00000000000..7677f7a5ec0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MacAddressesType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MacAddressesType extends ApiPropertyBase { + List mac_address; + public MacAddressesType() { + } + public MacAddressesType(List mac_address) { + this.mac_address = mac_address; + } + + public List getMacAddress() { + return mac_address; + } + + + public void addMacAddress(String obj) { + if (mac_address == null) { + mac_address = new ArrayList(); + } + mac_address.add(obj); + } + public void clearMacAddress() { + mac_address = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MatchConditionType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MatchConditionType.java new file mode 100644 index 00000000000..ade6da854ad --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MatchConditionType.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MatchConditionType extends ApiPropertyBase { + String protocol; + AddressType src_address; + PortType src_port; + AddressType dst_address; + PortType dst_port; + String ethertype; + public MatchConditionType() { + } + public MatchConditionType(String protocol, AddressType src_address, PortType src_port, AddressType dst_address, PortType dst_port, String ethertype) { + this.protocol = protocol; + this.src_address = src_address; + this.src_port = src_port; + this.dst_address = dst_address; + this.dst_port = dst_port; + this.ethertype = ethertype; + } + public MatchConditionType(String protocol) { + this(protocol, null, null, null, null, null); } + public MatchConditionType(String protocol, AddressType src_address) { + this(protocol, src_address, null, null, null, null); } + public MatchConditionType(String protocol, AddressType src_address, PortType src_port) { + this(protocol, src_address, src_port, null, null, null); } + public MatchConditionType(String protocol, AddressType src_address, PortType src_port, AddressType dst_address) { + this(protocol, src_address, src_port, dst_address, null, null); } + public MatchConditionType(String protocol, AddressType src_address, PortType src_port, AddressType dst_address, PortType dst_port) { + this(protocol, src_address, src_port, dst_address, dst_port, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public AddressType getSrcAddress() { + return src_address; + } + + public void setSrcAddress(AddressType src_address) { + this.src_address = src_address; + } + + + public PortType getSrcPort() { + return src_port; + } + + public void setSrcPort(PortType src_port) { + this.src_port = src_port; + } + + + public AddressType getDstAddress() { + return dst_address; + } + + public void setDstAddress(AddressType dst_address) { + this.dst_address = dst_address; + } + + + public PortType getDstPort() { + return dst_port; + } + + public void setDstPort(PortType dst_port) { + this.dst_port = dst_port; + } + + + public String getEthertype() { + return ethertype; + } + + public void setEthertype(String ethertype) { + this.ethertype = ethertype; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MirrorActionType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MirrorActionType.java new file mode 100644 index 00000000000..e599f5d6f23 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MirrorActionType.java @@ -0,0 +1,154 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MirrorActionType extends ApiPropertyBase { + String analyzer_name; + String encapsulation; + String analyzer_ip_address; + String analyzer_mac_address; + String routing_instance; + Integer udp_port; + Boolean juniper_header; + String nh_mode; + StaticMirrorNhType static_nh_header; + Boolean nic_assisted_mirroring; + Integer nic_assisted_mirroring_vlan; + public MirrorActionType() { + } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance, Integer udp_port, Boolean juniper_header, String nh_mode, StaticMirrorNhType static_nh_header, Boolean nic_assisted_mirroring, Integer nic_assisted_mirroring_vlan) { + this.analyzer_name = analyzer_name; + this.encapsulation = encapsulation; + this.analyzer_ip_address = analyzer_ip_address; + this.analyzer_mac_address = analyzer_mac_address; + this.routing_instance = routing_instance; + this.udp_port = udp_port; + this.juniper_header = juniper_header; + this.nh_mode = nh_mode; + this.static_nh_header = static_nh_header; + this.nic_assisted_mirroring = nic_assisted_mirroring; + this.nic_assisted_mirroring_vlan = nic_assisted_mirroring_vlan; + } + public MirrorActionType(String analyzer_name) { + this(analyzer_name, null, null, null, null, null, true, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation) { + this(analyzer_name, encapsulation, null, null, null, null, true, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address) { + this(analyzer_name, encapsulation, analyzer_ip_address, null, null, null, true, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, null, null, true, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, routing_instance, null, true, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance, Integer udp_port) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, routing_instance, udp_port, true, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance, Integer udp_port, Boolean juniper_header) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, routing_instance, udp_port, juniper_header, null, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance, Integer udp_port, Boolean juniper_header, String nh_mode) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, routing_instance, udp_port, juniper_header, nh_mode, null, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance, Integer udp_port, Boolean juniper_header, String nh_mode, StaticMirrorNhType static_nh_header) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, routing_instance, udp_port, juniper_header, nh_mode, static_nh_header, false, null); } + public MirrorActionType(String analyzer_name, String encapsulation, String analyzer_ip_address, String analyzer_mac_address, String routing_instance, Integer udp_port, Boolean juniper_header, String nh_mode, StaticMirrorNhType static_nh_header, Boolean nic_assisted_mirroring) { + this(analyzer_name, encapsulation, analyzer_ip_address, analyzer_mac_address, routing_instance, udp_port, juniper_header, nh_mode, static_nh_header, nic_assisted_mirroring, null); } + + public String getAnalyzerName() { + return analyzer_name; + } + + public void setAnalyzerName(String analyzer_name) { + this.analyzer_name = analyzer_name; + } + + + public String getEncapsulation() { + return encapsulation; + } + + public void setEncapsulation(String encapsulation) { + this.encapsulation = encapsulation; + } + + + public String getAnalyzerIpAddress() { + return analyzer_ip_address; + } + + public void setAnalyzerIpAddress(String analyzer_ip_address) { + this.analyzer_ip_address = analyzer_ip_address; + } + + + public String getAnalyzerMacAddress() { + return analyzer_mac_address; + } + + public void setAnalyzerMacAddress(String analyzer_mac_address) { + this.analyzer_mac_address = analyzer_mac_address; + } + + + public String getRoutingInstance() { + return routing_instance; + } + + public void setRoutingInstance(String routing_instance) { + this.routing_instance = routing_instance; + } + + + public Integer getUdpPort() { + return udp_port; + } + + public void setUdpPort(Integer udp_port) { + this.udp_port = udp_port; + } + + + public Boolean getJuniperHeader() { + return juniper_header; + } + + public void setJuniperHeader(Boolean juniper_header) { + this.juniper_header = juniper_header; + } + + + public String getNhMode() { + return nh_mode; + } + + public void setNhMode(String nh_mode) { + this.nh_mode = nh_mode; + } + + + public StaticMirrorNhType getStaticNhHeader() { + return static_nh_header; + } + + public void setStaticNhHeader(StaticMirrorNhType static_nh_header) { + this.static_nh_header = static_nh_header; + } + + + public Boolean getNicAssistedMirroring() { + return nic_assisted_mirroring; + } + + public void setNicAssistedMirroring(Boolean nic_assisted_mirroring) { + this.nic_assisted_mirroring = nic_assisted_mirroring; + } + + + public Integer getNicAssistedMirroringVlan() { + return nic_assisted_mirroring_vlan; + } + + public void setNicAssistedMirroringVlan(Integer nic_assisted_mirroring_vlan) { + this.nic_assisted_mirroring_vlan = nic_assisted_mirroring_vlan; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastPolicy.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastPolicy.java new file mode 100644 index 00000000000..2ca15745728 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastPolicy.java @@ -0,0 +1,120 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class MulticastPolicy extends ApiObjectBase { + private MulticastSourceGroups multicast_source_groups; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> virtual_network_back_refs; + + @Override + public String getObjectType() { + return "multicast-policy"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public MulticastSourceGroups getMulticastSourceGroups() { + return multicast_source_groups; + } + + public void setMulticastSourceGroups(MulticastSourceGroups multicast_source_groups) { + this.multicast_source_groups = multicast_source_groups; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastSourceGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastSourceGroup.java new file mode 100644 index 00000000000..acf10ff36ba --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastSourceGroup.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MulticastSourceGroup extends ApiPropertyBase { + String source_address; + String group_address; + String action; + public MulticastSourceGroup() { + } + public MulticastSourceGroup(String source_address, String group_address, String action) { + this.source_address = source_address; + this.group_address = group_address; + this.action = action; + } + public MulticastSourceGroup(String source_address) { + this(source_address, null, null); } + public MulticastSourceGroup(String source_address, String group_address) { + this(source_address, group_address, null); } + + public String getSourceAddress() { + return source_address; + } + + public void setSourceAddress(String source_address) { + this.source_address = source_address; + } + + + public String getGroupAddress() { + return group_address; + } + + public void setGroupAddress(String group_address) { + this.group_address = group_address; + } + + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastSourceGroups.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastSourceGroups.java new file mode 100644 index 00000000000..b97a83082b0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/MulticastSourceGroups.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class MulticastSourceGroups extends ApiPropertyBase { + List multicast_source_group; + public MulticastSourceGroups() { + } + public MulticastSourceGroups(List multicast_source_group) { + this.multicast_source_group = multicast_source_group; + } + + public List getMulticastSourceGroup() { + return multicast_source_group; + } + + + public void addMulticastSourceGroup(MulticastSourceGroup obj) { + if (multicast_source_group == null) { + multicast_source_group = new ArrayList(); + } + multicast_source_group.add(obj); + } + public void clearMulticastSourceGroup() { + multicast_source_group = null; + } + + + public void addMulticastSourceGroup(String source_address, String group_address, String action) { + if (multicast_source_group == null) { + multicast_source_group = new ArrayList(); + } + multicast_source_group.add(new MulticastSourceGroup(source_address, group_address, action)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Namespace.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Namespace.java new file mode 100644 index 00000000000..d6e073f4be3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Namespace.java @@ -0,0 +1,120 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Namespace extends ApiObjectBase { + private SubnetType namespace_cidr; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> project_back_refs; + + @Override + public String getObjectType() { + return "namespace"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain"); + } + + @Override + public String getDefaultParentType() { + return "domain"; + } + + public void setParent(Domain parent) { + super.setParent(parent); + } + + public SubnetType getCidr() { + return namespace_cidr; + } + + public void setCidr(SubnetType namespace_cidr) { + this.namespace_cidr = namespace_cidr; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getProjectBackRefs() { + return project_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NamespaceValue.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NamespaceValue.java new file mode 100644 index 00000000000..d7dbd0b5bda --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NamespaceValue.java @@ -0,0 +1,101 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class NamespaceValue extends ApiPropertyBase { + SubnetListType ipv4_cidr; + AutonomousSystemsType asn; + MacAddressesType mac_addr; + List asn_ranges; + List serial_nums; + public NamespaceValue() { + } + public NamespaceValue(SubnetListType ipv4_cidr, AutonomousSystemsType asn, MacAddressesType mac_addr, List asn_ranges, List serial_nums) { + this.ipv4_cidr = ipv4_cidr; + this.asn = asn; + this.mac_addr = mac_addr; + this.asn_ranges = asn_ranges; + this.serial_nums = serial_nums; + } + public NamespaceValue(SubnetListType ipv4_cidr) { + this(ipv4_cidr, null, null, null, null); } + public NamespaceValue(SubnetListType ipv4_cidr, AutonomousSystemsType asn) { + this(ipv4_cidr, asn, null, null, null); } + public NamespaceValue(SubnetListType ipv4_cidr, AutonomousSystemsType asn, MacAddressesType mac_addr) { + this(ipv4_cidr, asn, mac_addr, null, null); } + public NamespaceValue(SubnetListType ipv4_cidr, AutonomousSystemsType asn, MacAddressesType mac_addr, List asn_ranges) { + this(ipv4_cidr, asn, mac_addr, asn_ranges, null); } + + public SubnetListType getIpv4Cidr() { + return ipv4_cidr; + } + + public void setIpv4Cidr(SubnetListType ipv4_cidr) { + this.ipv4_cidr = ipv4_cidr; + } + + + public AutonomousSystemsType getAsn() { + return asn; + } + + public void setAsn(AutonomousSystemsType asn) { + this.asn = asn; + } + + + public MacAddressesType getMacAddr() { + return mac_addr; + } + + public void setMacAddr(MacAddressesType mac_addr) { + this.mac_addr = mac_addr; + } + + + public List getAsnRanges() { + return asn_ranges; + } + + + public void addAsnRanges(AsnRangeType obj) { + if (asn_ranges == null) { + asn_ranges = new ArrayList(); + } + asn_ranges.add(obj); + } + public void clearAsnRanges() { + asn_ranges = null; + } + + + public void addAsnRanges(Integer asn_min, Integer asn_max) { + if (asn_ranges == null) { + asn_ranges = new ArrayList(); + } + asn_ranges.add(new AsnRangeType(asn_min, asn_max)); + } + + + public List getSerialNums() { + return serial_nums; + } + + + public void addSerialNums(String obj) { + if (serial_nums == null) { + serial_nums = new ArrayList(); + } + serial_nums.add(obj); + } + public void clearSerialNums() { + serial_nums = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetconfParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetconfParameters.java new file mode 100644 index 00000000000..514f348c19a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetconfParameters.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class NetconfParameters extends ApiPropertyBase { + EnabledSensorParams enabled_sensor_params; + public NetconfParameters() { + } + public NetconfParameters(EnabledSensorParams enabled_sensor_params) { + this.enabled_sensor_params = enabled_sensor_params; + } + + public EnabledSensorParams getEnabledSensorParams() { + return enabled_sensor_params; + } + + public void setEnabledSensorParams(EnabledSensorParams enabled_sensor_params) { + this.enabled_sensor_params = enabled_sensor_params; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetconfProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetconfProfile.java new file mode 100644 index 00000000000..902afeb46a5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetconfProfile.java @@ -0,0 +1,130 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class NetconfProfile extends ApiObjectBase { + private Boolean netconf_profile_is_default; + private NetconfParameters netconf_parameters; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> telemetry_profile_back_refs; + + @Override + public String getObjectType() { + return "netconf-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Boolean getIsDefault() { + return netconf_profile_is_default; + } + + public void setIsDefault(Boolean netconf_profile_is_default) { + this.netconf_profile_is_default = netconf_profile_is_default; + } + + + public NetconfParameters getNetconfParameters() { + return netconf_parameters; + } + + public void setNetconfParameters(NetconfParameters netconf_parameters) { + this.netconf_parameters = netconf_parameters; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getTelemetryProfileBackRefs() { + return telemetry_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkDeviceConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkDeviceConfig.java new file mode 100644 index 00000000000..16188b1f736 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkDeviceConfig.java @@ -0,0 +1,132 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class NetworkDeviceConfig extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> physical_router_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "network-device-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPhysicalRouter() { + return physical_router_refs; + } + + public void setPhysicalRouter(PhysicalRouter obj) { + physical_router_refs = new ArrayList>(); + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs == null) { + physical_router_refs = new ArrayList>(); + } + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs != null) { + physical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRouter() { + if (physical_router_refs != null) { + physical_router_refs.clear(); + return; + } + physical_router_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkIpam.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkIpam.java new file mode 100644 index 00000000000..b817c2afc6f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkIpam.java @@ -0,0 +1,191 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class NetworkIpam extends ApiObjectBase { + private IpamType network_ipam_mgmt; + private IpamSubnets ipam_subnets; + private String ipam_subnet_method; + private Boolean ipam_subnetting; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_DNS_refs; + private List> tag_refs; + private transient List> virtual_network_back_refs; + private transient List> virtual_router_back_refs; + private transient List> instance_ip_back_refs; + + @Override + public String getObjectType() { + return "network-ipam"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public IpamType getMgmt() { + return network_ipam_mgmt; + } + + public void setMgmt(IpamType network_ipam_mgmt) { + this.network_ipam_mgmt = network_ipam_mgmt; + } + + + public IpamSubnets getIpamSubnets() { + return ipam_subnets; + } + + public void setIpamSubnets(IpamSubnets ipam_subnets) { + this.ipam_subnets = ipam_subnets; + } + + + public String getIpamSubnetMethod() { + return ipam_subnet_method; + } + + public void setIpamSubnetMethod(String ipam_subnet_method) { + this.ipam_subnet_method = ipam_subnet_method; + } + + + public Boolean getIpamSubnetting() { + return ipam_subnetting; + } + + public void setIpamSubnetting(Boolean ipam_subnetting) { + this.ipam_subnetting = ipam_subnetting; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualDns() { + return virtual_DNS_refs; + } + + public void setVirtualDns(VirtualDns obj) { + virtual_DNS_refs = new ArrayList>(); + virtual_DNS_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualDns(VirtualDns obj) { + if (virtual_DNS_refs == null) { + virtual_DNS_refs = new ArrayList>(); + } + virtual_DNS_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualDns(VirtualDns obj) { + if (virtual_DNS_refs != null) { + virtual_DNS_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualDns() { + if (virtual_DNS_refs != null) { + virtual_DNS_refs.clear(); + return; + } + virtual_DNS_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getVirtualRouterBackRefs() { + return virtual_router_back_refs; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkPolicy.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkPolicy.java new file mode 100644 index 00000000000..3a1fc98adfe --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NetworkPolicy.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class NetworkPolicy extends ApiObjectBase { + private PolicyEntriesType network_policy_entries; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> security_logging_object_back_refs; + private transient List> virtual_network_back_refs; + + @Override + public String getObjectType() { + return "network-policy"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public PolicyEntriesType getEntries() { + return network_policy_entries; + } + + public void setEntries(PolicyEntriesType network_policy_entries) { + this.network_policy_entries = network_policy_entries; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getSecurityLoggingObjectBackRefs() { + return security_logging_object_back_refs; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Node.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Node.java new file mode 100644 index 00000000000..d5f6a2a0277 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Node.java @@ -0,0 +1,236 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Node extends ApiObjectBase { + private String node_type; + private ESXIHostInfo esxi_info; + private String ip_address; + private String hostname; + private BaremetalServerInfo bms_info; + private String mac_address; + private String disk_partition; + private String interface_name; + private CloudInstanceInfo cloud_info; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> node_profile_refs; + private List> ports; + private List> port_groups; + private List> tag_refs; + + @Override + public String getObjectType() { + return "node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getType() { + return node_type; + } + + public void setType(String node_type) { + this.node_type = node_type; + } + + + public ESXIHostInfo getEsxiInfo() { + return esxi_info; + } + + public void setEsxiInfo(ESXIHostInfo esxi_info) { + this.esxi_info = esxi_info; + } + + + public String getIpAddress() { + return ip_address; + } + + public void setIpAddress(String ip_address) { + this.ip_address = ip_address; + } + + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + + public BaremetalServerInfo getBmsInfo() { + return bms_info; + } + + public void setBmsInfo(BaremetalServerInfo bms_info) { + this.bms_info = bms_info; + } + + + public String getMacAddress() { + return mac_address; + } + + public void setMacAddress(String mac_address) { + this.mac_address = mac_address; + } + + + public String getDiskPartition() { + return disk_partition; + } + + public void setDiskPartition(String disk_partition) { + this.disk_partition = disk_partition; + } + + + public String getInterfaceName() { + return interface_name; + } + + public void setInterfaceName(String interface_name) { + this.interface_name = interface_name; + } + + + public CloudInstanceInfo getCloudInfo() { + return cloud_info; + } + + public void setCloudInfo(CloudInstanceInfo cloud_info) { + this.cloud_info = cloud_info; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getNodeProfile() { + return node_profile_refs; + } + + public void setNodeProfile(NodeProfile obj) { + node_profile_refs = new ArrayList>(); + node_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addNodeProfile(NodeProfile obj) { + if (node_profile_refs == null) { + node_profile_refs = new ArrayList>(); + } + node_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeNodeProfile(NodeProfile obj) { + if (node_profile_refs != null) { + node_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearNodeProfile() { + if (node_profile_refs != null) { + node_profile_refs.clear(); + return; + } + node_profile_refs = null; + } + + public List> getPorts() { + return ports; + } + + public List> getPortGroups() { + return port_groups; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfile.java new file mode 100644 index 00000000000..e4356dfe6ff --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfile.java @@ -0,0 +1,268 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class NodeProfile extends ApiObjectBase { + private String node_profile_type; + private String node_profile_vendor; + private String node_profile_device_family; + private Boolean node_profile_hitless_upgrade; + private NodeProfileRolesType node_profile_roles; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> job_template_refs; + private List> hardware_refs; + private List> role_definition_refs; + private List> role_configs; + private List> tag_refs; + private transient List> fabric_back_refs; + private transient List> physical_router_back_refs; + private transient List> node_back_refs; + + @Override + public String getObjectType() { + return "node-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getType() { + return node_profile_type; + } + + public void setType(String node_profile_type) { + this.node_profile_type = node_profile_type; + } + + + public String getVendor() { + return node_profile_vendor; + } + + public void setVendor(String node_profile_vendor) { + this.node_profile_vendor = node_profile_vendor; + } + + + public String getDeviceFamily() { + return node_profile_device_family; + } + + public void setDeviceFamily(String node_profile_device_family) { + this.node_profile_device_family = node_profile_device_family; + } + + + public Boolean getHitlessUpgrade() { + return node_profile_hitless_upgrade; + } + + public void setHitlessUpgrade(Boolean node_profile_hitless_upgrade) { + this.node_profile_hitless_upgrade = node_profile_hitless_upgrade; + } + + + public NodeProfileRolesType getRoles() { + return node_profile_roles; + } + + public void setRoles(NodeProfileRolesType node_profile_roles) { + this.node_profile_roles = node_profile_roles; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getJobTemplate() { + return job_template_refs; + } + + public void setJobTemplate(JobTemplate obj) { + job_template_refs = new ArrayList>(); + job_template_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addJobTemplate(JobTemplate obj) { + if (job_template_refs == null) { + job_template_refs = new ArrayList>(); + } + job_template_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeJobTemplate(JobTemplate obj) { + if (job_template_refs != null) { + job_template_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearJobTemplate() { + if (job_template_refs != null) { + job_template_refs.clear(); + return; + } + job_template_refs = null; + } + + public List> getHardware() { + return hardware_refs; + } + + public void setHardware(Hardware obj) { + hardware_refs = new ArrayList>(); + hardware_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addHardware(Hardware obj) { + if (hardware_refs == null) { + hardware_refs = new ArrayList>(); + } + hardware_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeHardware(Hardware obj) { + if (hardware_refs != null) { + hardware_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearHardware() { + if (hardware_refs != null) { + hardware_refs.clear(); + return; + } + hardware_refs = null; + } + + public List> getRoleDefinition() { + return role_definition_refs; + } + + public void setRoleDefinition(RoleDefinition obj) { + role_definition_refs = new ArrayList>(); + role_definition_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addRoleDefinition(RoleDefinition obj) { + if (role_definition_refs == null) { + role_definition_refs = new ArrayList>(); + } + role_definition_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeRoleDefinition(RoleDefinition obj) { + if (role_definition_refs != null) { + role_definition_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearRoleDefinition() { + if (role_definition_refs != null) { + role_definition_refs.clear(); + return; + } + role_definition_refs = null; + } + + public List> getRoleConfigs() { + return role_configs; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getFabricBackRefs() { + return fabric_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getNodeBackRefs() { + return node_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfileRoleType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfileRoleType.java new file mode 100644 index 00000000000..4cceb4c5aa9 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfileRoleType.java @@ -0,0 +1,47 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class NodeProfileRoleType extends ApiPropertyBase { + String physical_role; + List rb_roles; + public NodeProfileRoleType() { + } + public NodeProfileRoleType(String physical_role, List rb_roles) { + this.physical_role = physical_role; + this.rb_roles = rb_roles; + } + public NodeProfileRoleType(String physical_role) { + this(physical_role, null); } + + public String getPhysicalRole() { + return physical_role; + } + + public void setPhysicalRole(String physical_role) { + this.physical_role = physical_role; + } + + + public List getRbRoles() { + return rb_roles; + } + + + public void addRbRoles(String obj) { + if (rb_roles == null) { + rb_roles = new ArrayList(); + } + rb_roles.add(obj); + } + public void clearRbRoles() { + rb_roles = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfileRolesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfileRolesType.java new file mode 100644 index 00000000000..876ad11e8a8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/NodeProfileRolesType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class NodeProfileRolesType extends ApiPropertyBase { + List role_mappings; + public NodeProfileRolesType() { + } + public NodeProfileRolesType(List role_mappings) { + this.role_mappings = role_mappings; + } + + public List getRoleMappings() { + return role_mappings; + } + + + public void addRoleMappings(NodeProfileRoleType obj) { + if (role_mappings == null) { + role_mappings = new ArrayList(); + } + role_mappings.add(obj); + } + public void clearRoleMappings() { + role_mappings = null; + } + + + public void addRoleMappings(String physical_role, List rb_roles) { + if (role_mappings == null) { + role_mappings = new ArrayList(); + } + role_mappings.add(new NodeProfileRoleType(physical_role, rb_roles)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/OspfParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/OspfParameters.java new file mode 100644 index 00000000000..83cc4acce2f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/OspfParameters.java @@ -0,0 +1,102 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class OspfParameters extends ApiPropertyBase { + String auth_data; + Integer hello_interval; + Integer dead_interval; + String area_id; + String area_type; + Boolean advertise_loopback; + Boolean orignate_summary_lsa; + public OspfParameters() { + } + public OspfParameters(String auth_data, Integer hello_interval, Integer dead_interval, String area_id, String area_type, Boolean advertise_loopback, Boolean orignate_summary_lsa) { + this.auth_data = auth_data; + this.hello_interval = hello_interval; + this.dead_interval = dead_interval; + this.area_id = area_id; + this.area_type = area_type; + this.advertise_loopback = advertise_loopback; + this.orignate_summary_lsa = orignate_summary_lsa; + } + public OspfParameters(String auth_data) { + this(auth_data, 10, 40, null, null, null, null); } + public OspfParameters(String auth_data, Integer hello_interval) { + this(auth_data, hello_interval, 40, null, null, null, null); } + public OspfParameters(String auth_data, Integer hello_interval, Integer dead_interval) { + this(auth_data, hello_interval, dead_interval, null, null, null, null); } + public OspfParameters(String auth_data, Integer hello_interval, Integer dead_interval, String area_id) { + this(auth_data, hello_interval, dead_interval, area_id, null, null, null); } + public OspfParameters(String auth_data, Integer hello_interval, Integer dead_interval, String area_id, String area_type) { + this(auth_data, hello_interval, dead_interval, area_id, area_type, null, null); } + public OspfParameters(String auth_data, Integer hello_interval, Integer dead_interval, String area_id, String area_type, Boolean advertise_loopback) { + this(auth_data, hello_interval, dead_interval, area_id, area_type, advertise_loopback, null); } + + public String getAuthData() { + return auth_data; + } + + public void setAuthData(String auth_data) { + this.auth_data = auth_data; + } + + + public Integer getHelloInterval() { + return hello_interval; + } + + public void setHelloInterval(Integer hello_interval) { + this.hello_interval = hello_interval; + } + + + public Integer getDeadInterval() { + return dead_interval; + } + + public void setDeadInterval(Integer dead_interval) { + this.dead_interval = dead_interval; + } + + + public String getAreaId() { + return area_id; + } + + public void setAreaId(String area_id) { + this.area_id = area_id; + } + + + public String getAreaType() { + return area_type; + } + + public void setAreaType(String area_type) { + this.area_type = area_type; + } + + + public Boolean getAdvertiseLoopback() { + return advertise_loopback; + } + + public void setAdvertiseLoopback(Boolean advertise_loopback) { + this.advertise_loopback = advertise_loopback; + } + + + public Boolean getOrignateSummaryLsa() { + return orignate_summary_lsa; + } + + public void setOrignateSummaryLsa(Boolean orignate_summary_lsa) { + this.orignate_summary_lsa = orignate_summary_lsa; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/OverlayRole.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/OverlayRole.java new file mode 100644 index 00000000000..14408cfa6ec --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/OverlayRole.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class OverlayRole extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> physical_router_back_refs; + private transient List> role_definition_back_refs; + + @Override + public String getObjectType() { + return "overlay-role"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getRoleDefinitionBackRefs() { + return role_definition_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PeeringPolicy.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PeeringPolicy.java new file mode 100644 index 00000000000..b7ab05415f7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PeeringPolicy.java @@ -0,0 +1,116 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PeeringPolicy extends ApiObjectBase { + private String peering_service; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> e2_service_provider_back_refs; + + @Override + public String getObjectType() { + return "peering-policy"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public String getPeeringService() { + return peering_service; + } + + public void setPeeringService(String peering_service) { + this.peering_service = peering_service; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getE2ServiceProviderBackRefs() { + return e2_service_provider_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PermType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PermType.java new file mode 100644 index 00000000000..8f0ebb6c089 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PermType.java @@ -0,0 +1,76 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PermType extends ApiPropertyBase { + String owner; + Integer owner_access; + String group; + Integer group_access; + Integer other_access; + public PermType() { + } + public PermType(String owner, Integer owner_access, String group, Integer group_access, Integer other_access) { + this.owner = owner; + this.owner_access = owner_access; + this.group = group; + this.group_access = group_access; + this.other_access = other_access; + } + public PermType(String owner) { + this(owner, null, null, null, null); } + public PermType(String owner, Integer owner_access) { + this(owner, owner_access, null, null, null); } + public PermType(String owner, Integer owner_access, String group) { + this(owner, owner_access, group, null, null); } + public PermType(String owner, Integer owner_access, String group, Integer group_access) { + this(owner, owner_access, group, group_access, null); } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + + public Integer getOwnerAccess() { + return owner_access; + } + + public void setOwnerAccess(Integer owner_access) { + this.owner_access = owner_access; + } + + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + + public Integer getGroupAccess() { + return group_access; + } + + public void setGroupAccess(Integer group_access) { + this.group_access = group_access; + } + + + public Integer getOtherAccess() { + return other_access; + } + + public void setOtherAccess(Integer other_access) { + this.other_access = other_access; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PermType2.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PermType2.java new file mode 100644 index 00000000000..f9c8228dfde --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PermType2.java @@ -0,0 +1,81 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PermType2 extends ApiPropertyBase { + String owner; + Integer owner_access; + Integer global_access; + List share; + public PermType2() { + } + public PermType2(String owner, Integer owner_access, Integer global_access, List share) { + this.owner = owner; + this.owner_access = owner_access; + this.global_access = global_access; + this.share = share; + } + public PermType2(String owner) { + this(owner, 7, 0, null); } + public PermType2(String owner, Integer owner_access) { + this(owner, owner_access, 0, null); } + public PermType2(String owner, Integer owner_access, Integer global_access) { + this(owner, owner_access, global_access, null); } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + + public Integer getOwnerAccess() { + return owner_access; + } + + public void setOwnerAccess(Integer owner_access) { + this.owner_access = owner_access; + } + + + public Integer getGlobalAccess() { + return global_access; + } + + public void setGlobalAccess(Integer global_access) { + this.global_access = global_access; + } + + + public List getShare() { + return share; + } + + + public void addShare(ShareType obj) { + if (share == null) { + share = new ArrayList(); + } + share.add(obj); + } + public void clearShare() { + share = null; + } + + + public void addShare(String tenant, Integer tenant_access) { + if (share == null) { + share = new ArrayList(); + } + share.add(new ShareType(tenant, tenant_access)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalInterface.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalInterface.java new file mode 100644 index 00000000000..f2a32c3742d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalInterface.java @@ -0,0 +1,267 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PhysicalInterface extends ApiObjectBase { + private String ethernet_segment_identifier; + private String physical_interface_type; + private MacAddressesType physical_interface_mac_addresses; + private String physical_interface_port_id; + private Boolean physical_interface_flow_control; + private Boolean physical_interface_lacp_force_up; + private PortParameters physical_interface_port_params; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> physical_interface_refs; + private List> logical_interfaces; + private List> port_refs; + private List> tag_refs; + private transient List> service_appliance_back_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> physical_interface_back_refs; + private transient List> link_aggregation_group_back_refs; + private transient List> virtual_port_group_back_refs; + + @Override + public String getObjectType() { + return "physical-interface"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-physical-router"); + } + + @Override + public String getDefaultParentType() { + return "physical-router"; + } + + public void setParent(PhysicalRouter parent) { + super.setParent(parent); + } + + public String getEthernetSegmentIdentifier() { + return ethernet_segment_identifier; + } + + public void setEthernetSegmentIdentifier(String ethernet_segment_identifier) { + this.ethernet_segment_identifier = ethernet_segment_identifier; + } + + + public String getType() { + return physical_interface_type; + } + + public void setType(String physical_interface_type) { + this.physical_interface_type = physical_interface_type; + } + + + public MacAddressesType getMacAddresses() { + return physical_interface_mac_addresses; + } + + public void setMacAddresses(MacAddressesType physical_interface_mac_addresses) { + this.physical_interface_mac_addresses = physical_interface_mac_addresses; + } + + + public String getPortId() { + return physical_interface_port_id; + } + + public void setPortId(String physical_interface_port_id) { + this.physical_interface_port_id = physical_interface_port_id; + } + + + public Boolean getFlowControl() { + return physical_interface_flow_control; + } + + public void setFlowControl(Boolean physical_interface_flow_control) { + this.physical_interface_flow_control = physical_interface_flow_control; + } + + + public Boolean getLacpForceUp() { + return physical_interface_lacp_force_up; + } + + public void setLacpForceUp(Boolean physical_interface_lacp_force_up) { + this.physical_interface_lacp_force_up = physical_interface_lacp_force_up; + } + + + public PortParameters getPortParams() { + return physical_interface_port_params; + } + + public void setPortParams(PortParameters physical_interface_port_params) { + this.physical_interface_port_params = physical_interface_port_params; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPhysicalInterface() { + return physical_interface_refs; + } + + public void setPhysicalInterface(PhysicalInterface obj) { + physical_interface_refs = new ArrayList>(); + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalInterface(PhysicalInterface obj) { + if (physical_interface_refs == null) { + physical_interface_refs = new ArrayList>(); + } + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalInterface(PhysicalInterface obj) { + if (physical_interface_refs != null) { + physical_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalInterface() { + if (physical_interface_refs != null) { + physical_interface_refs.clear(); + return; + } + physical_interface_refs = null; + } + + public List> getLogicalInterfaces() { + return logical_interfaces; + } + + public List> getPort() { + return port_refs; + } + + public void setPort(Port obj) { + port_refs = new ArrayList>(); + port_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPort(Port obj) { + if (port_refs == null) { + port_refs = new ArrayList>(); + } + port_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePort(Port obj) { + if (port_refs != null) { + port_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPort() { + if (port_refs != null) { + port_refs.clear(); + return; + } + port_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceApplianceBackRefs() { + return service_appliance_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getPhysicalInterfaceBackRefs() { + return physical_interface_back_refs; + } + + public List> getLinkAggregationGroupBackRefs() { + return link_aggregation_group_back_refs; + } + + public List> getVirtualPortGroupBackRefs() { + return virtual_port_group_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalRole.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalRole.java new file mode 100644 index 00000000000..246775da87e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalRole.java @@ -0,0 +1,120 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PhysicalRole extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> device_functional_group_back_refs; + private transient List> physical_router_back_refs; + private transient List> role_definition_back_refs; + + @Override + public String getObjectType() { + return "physical-role"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getDeviceFunctionalGroupBackRefs() { + return device_functional_group_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getRoleDefinitionBackRefs() { + return role_definition_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalRouter.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalRouter.java new file mode 100644 index 00000000000..bc68b8f533a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PhysicalRouter.java @@ -0,0 +1,817 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PhysicalRouter extends ApiObjectBase { + private JunosServicePorts physical_router_junos_service_ports; + private TelemetryStateInfo telemetry_info; + private String physical_router_device_family; + private String physical_router_os_version; + private String physical_router_hostname; + private String physical_router_management_ip; + private String physical_router_management_mac; + private String physical_router_dataplane_ip; + private String physical_router_loopback_ip; + private String physical_router_replicator_loopback_ip; + private String physical_router_vendor_name; + private String physical_router_product_name; + private String physical_router_serial_number; + private Boolean physical_router_vnc_managed; + private Boolean physical_router_underlay_managed; + private String physical_router_role; + private RoutingBridgingRolesType routing_bridging_roles; + private Boolean physical_router_snmp; + private Boolean physical_router_lldp; + private UserCredentials physical_router_user_credentials; + private String physical_router_encryption_type; + private SNMPCredentials physical_router_snmp_credentials; + private DnsmasqLeaseParameters physical_router_dhcp_parameters; + private String physical_router_cli_commit_state; + private String physical_router_managed_state; + private String physical_router_onboarding_state; + private String physical_router_underlay_config; + private String physical_router_supplemental_config; + private AutonomousSystemsType physical_router_autonomous_system; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_router_refs; + private List> bgp_router_refs; + private List> virtual_network_refs; + private List> intent_map_refs; + private List> fabric_refs; + private List> node_profile_refs; + private List> device_functional_group_refs; + private List> device_chassis_refs; + private List> device_image_refs; + private List> link_aggregation_groups; + private List> physical_role_refs; + private List> overlay_role_refs; + private List> hardware_inventorys; + private List> cli_configs; + private List> physical_interfaces; + private List> logical_interfaces; + private List> telemetry_profile_refs; + private List> tag_refs; + private transient List> instance_ip_back_refs; + private transient List> logical_router_back_refs; + private transient List> service_endpoint_back_refs; + private transient List> network_device_config_back_refs; + private transient List> e2_service_provider_back_refs; + + @Override + public String getObjectType() { + return "physical-router"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public JunosServicePorts getJunosServicePorts() { + return physical_router_junos_service_ports; + } + + public void setJunosServicePorts(JunosServicePorts physical_router_junos_service_ports) { + this.physical_router_junos_service_ports = physical_router_junos_service_ports; + } + + + public TelemetryStateInfo getTelemetryInfo() { + return telemetry_info; + } + + public void setTelemetryInfo(TelemetryStateInfo telemetry_info) { + this.telemetry_info = telemetry_info; + } + + + public String getDeviceFamily() { + return physical_router_device_family; + } + + public void setDeviceFamily(String physical_router_device_family) { + this.physical_router_device_family = physical_router_device_family; + } + + + public String getOsVersion() { + return physical_router_os_version; + } + + public void setOsVersion(String physical_router_os_version) { + this.physical_router_os_version = physical_router_os_version; + } + + + public String getHostname() { + return physical_router_hostname; + } + + public void setHostname(String physical_router_hostname) { + this.physical_router_hostname = physical_router_hostname; + } + + + public String getManagementIp() { + return physical_router_management_ip; + } + + public void setManagementIp(String physical_router_management_ip) { + this.physical_router_management_ip = physical_router_management_ip; + } + + + public String getManagementMac() { + return physical_router_management_mac; + } + + public void setManagementMac(String physical_router_management_mac) { + this.physical_router_management_mac = physical_router_management_mac; + } + + + public String getDataplaneIp() { + return physical_router_dataplane_ip; + } + + public void setDataplaneIp(String physical_router_dataplane_ip) { + this.physical_router_dataplane_ip = physical_router_dataplane_ip; + } + + + public String getLoopbackIp() { + return physical_router_loopback_ip; + } + + public void setLoopbackIp(String physical_router_loopback_ip) { + this.physical_router_loopback_ip = physical_router_loopback_ip; + } + + + public String getReplicatorLoopbackIp() { + return physical_router_replicator_loopback_ip; + } + + public void setReplicatorLoopbackIp(String physical_router_replicator_loopback_ip) { + this.physical_router_replicator_loopback_ip = physical_router_replicator_loopback_ip; + } + + + public String getVendorName() { + return physical_router_vendor_name; + } + + public void setVendorName(String physical_router_vendor_name) { + this.physical_router_vendor_name = physical_router_vendor_name; + } + + + public String getProductName() { + return physical_router_product_name; + } + + public void setProductName(String physical_router_product_name) { + this.physical_router_product_name = physical_router_product_name; + } + + + public String getSerialNumber() { + return physical_router_serial_number; + } + + public void setSerialNumber(String physical_router_serial_number) { + this.physical_router_serial_number = physical_router_serial_number; + } + + + public Boolean getVncManaged() { + return physical_router_vnc_managed; + } + + public void setVncManaged(Boolean physical_router_vnc_managed) { + this.physical_router_vnc_managed = physical_router_vnc_managed; + } + + + public Boolean getUnderlayManaged() { + return physical_router_underlay_managed; + } + + public void setUnderlayManaged(Boolean physical_router_underlay_managed) { + this.physical_router_underlay_managed = physical_router_underlay_managed; + } + + + public String getRole() { + return physical_router_role; + } + + public void setRole(String physical_router_role) { + this.physical_router_role = physical_router_role; + } + + + public RoutingBridgingRolesType getRoutingBridgingRoles() { + return routing_bridging_roles; + } + + public void setRoutingBridgingRoles(RoutingBridgingRolesType routing_bridging_roles) { + this.routing_bridging_roles = routing_bridging_roles; + } + + + public Boolean getSnmp() { + return physical_router_snmp; + } + + public void setSnmp(Boolean physical_router_snmp) { + this.physical_router_snmp = physical_router_snmp; + } + + + public Boolean getLldp() { + return physical_router_lldp; + } + + public void setLldp(Boolean physical_router_lldp) { + this.physical_router_lldp = physical_router_lldp; + } + + + public UserCredentials getUserCredentials() { + return physical_router_user_credentials; + } + + public void setUserCredentials(UserCredentials physical_router_user_credentials) { + this.physical_router_user_credentials = physical_router_user_credentials; + } + + + public String getEncryptionType() { + return physical_router_encryption_type; + } + + public void setEncryptionType(String physical_router_encryption_type) { + this.physical_router_encryption_type = physical_router_encryption_type; + } + + + public SNMPCredentials getSnmpCredentials() { + return physical_router_snmp_credentials; + } + + public void setSnmpCredentials(SNMPCredentials physical_router_snmp_credentials) { + this.physical_router_snmp_credentials = physical_router_snmp_credentials; + } + + + public DnsmasqLeaseParameters getDhcpParameters() { + return physical_router_dhcp_parameters; + } + + public void setDhcpParameters(DnsmasqLeaseParameters physical_router_dhcp_parameters) { + this.physical_router_dhcp_parameters = physical_router_dhcp_parameters; + } + + + public String getCliCommitState() { + return physical_router_cli_commit_state; + } + + public void setCliCommitState(String physical_router_cli_commit_state) { + this.physical_router_cli_commit_state = physical_router_cli_commit_state; + } + + + public String getManagedState() { + return physical_router_managed_state; + } + + public void setManagedState(String physical_router_managed_state) { + this.physical_router_managed_state = physical_router_managed_state; + } + + + public String getOnboardingState() { + return physical_router_onboarding_state; + } + + public void setOnboardingState(String physical_router_onboarding_state) { + this.physical_router_onboarding_state = physical_router_onboarding_state; + } + + + public String getUnderlayConfig() { + return physical_router_underlay_config; + } + + public void setUnderlayConfig(String physical_router_underlay_config) { + this.physical_router_underlay_config = physical_router_underlay_config; + } + + + public String getSupplementalConfig() { + return physical_router_supplemental_config; + } + + public void setSupplementalConfig(String physical_router_supplemental_config) { + this.physical_router_supplemental_config = physical_router_supplemental_config; + } + + + public AutonomousSystemsType getAutonomousSystem() { + return physical_router_autonomous_system; + } + + public void setAutonomousSystem(AutonomousSystemsType physical_router_autonomous_system) { + this.physical_router_autonomous_system = physical_router_autonomous_system; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualRouter() { + return virtual_router_refs; + } + + public void setVirtualRouter(VirtualRouter obj) { + virtual_router_refs = new ArrayList>(); + virtual_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualRouter(VirtualRouter obj) { + if (virtual_router_refs == null) { + virtual_router_refs = new ArrayList>(); + } + virtual_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualRouter(VirtualRouter obj) { + if (virtual_router_refs != null) { + virtual_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualRouter() { + if (virtual_router_refs != null) { + virtual_router_refs.clear(); + return; + } + virtual_router_refs = null; + } + + public List> getBgpRouter() { + return bgp_router_refs; + } + + public void setBgpRouter(BgpRouter obj) { + bgp_router_refs = new ArrayList>(); + bgp_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addBgpRouter(BgpRouter obj) { + if (bgp_router_refs == null) { + bgp_router_refs = new ArrayList>(); + } + bgp_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeBgpRouter(BgpRouter obj) { + if (bgp_router_refs != null) { + bgp_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearBgpRouter() { + if (bgp_router_refs != null) { + bgp_router_refs.clear(); + return; + } + bgp_router_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getIntentMap() { + return intent_map_refs; + } + + public void setIntentMap(IntentMap obj) { + intent_map_refs = new ArrayList>(); + intent_map_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addIntentMap(IntentMap obj) { + if (intent_map_refs == null) { + intent_map_refs = new ArrayList>(); + } + intent_map_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeIntentMap(IntentMap obj) { + if (intent_map_refs != null) { + intent_map_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearIntentMap() { + if (intent_map_refs != null) { + intent_map_refs.clear(); + return; + } + intent_map_refs = null; + } + + public List> getFabric() { + return fabric_refs; + } + + public void setFabric(Fabric obj) { + fabric_refs = new ArrayList>(); + fabric_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFabric(Fabric obj) { + if (fabric_refs == null) { + fabric_refs = new ArrayList>(); + } + fabric_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFabric(Fabric obj) { + if (fabric_refs != null) { + fabric_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFabric() { + if (fabric_refs != null) { + fabric_refs.clear(); + return; + } + fabric_refs = null; + } + + public List> getNodeProfile() { + return node_profile_refs; + } + + public void setNodeProfile(NodeProfile obj) { + node_profile_refs = new ArrayList>(); + node_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addNodeProfile(NodeProfile obj) { + if (node_profile_refs == null) { + node_profile_refs = new ArrayList>(); + } + node_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeNodeProfile(NodeProfile obj) { + if (node_profile_refs != null) { + node_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearNodeProfile() { + if (node_profile_refs != null) { + node_profile_refs.clear(); + return; + } + node_profile_refs = null; + } + + public List> getDeviceFunctionalGroup() { + return device_functional_group_refs; + } + + public void setDeviceFunctionalGroup(DeviceFunctionalGroup obj) { + device_functional_group_refs = new ArrayList>(); + device_functional_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addDeviceFunctionalGroup(DeviceFunctionalGroup obj) { + if (device_functional_group_refs == null) { + device_functional_group_refs = new ArrayList>(); + } + device_functional_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeDeviceFunctionalGroup(DeviceFunctionalGroup obj) { + if (device_functional_group_refs != null) { + device_functional_group_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearDeviceFunctionalGroup() { + if (device_functional_group_refs != null) { + device_functional_group_refs.clear(); + return; + } + device_functional_group_refs = null; + } + + public List> getDeviceChassis() { + return device_chassis_refs; + } + + public void setDeviceChassis(DeviceChassis obj) { + device_chassis_refs = new ArrayList>(); + device_chassis_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addDeviceChassis(DeviceChassis obj) { + if (device_chassis_refs == null) { + device_chassis_refs = new ArrayList>(); + } + device_chassis_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeDeviceChassis(DeviceChassis obj) { + if (device_chassis_refs != null) { + device_chassis_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearDeviceChassis() { + if (device_chassis_refs != null) { + device_chassis_refs.clear(); + return; + } + device_chassis_refs = null; + } + + public List> getDeviceImage() { + return device_image_refs; + } + + public void setDeviceImage(DeviceImage obj) { + device_image_refs = new ArrayList>(); + device_image_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addDeviceImage(DeviceImage obj) { + if (device_image_refs == null) { + device_image_refs = new ArrayList>(); + } + device_image_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeDeviceImage(DeviceImage obj) { + if (device_image_refs != null) { + device_image_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearDeviceImage() { + if (device_image_refs != null) { + device_image_refs.clear(); + return; + } + device_image_refs = null; + } + + public List> getLinkAggregationGroups() { + return link_aggregation_groups; + } + + public List> getPhysicalRole() { + return physical_role_refs; + } + + public void setPhysicalRole(PhysicalRole obj) { + physical_role_refs = new ArrayList>(); + physical_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRole(PhysicalRole obj) { + if (physical_role_refs == null) { + physical_role_refs = new ArrayList>(); + } + physical_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRole(PhysicalRole obj) { + if (physical_role_refs != null) { + physical_role_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRole() { + if (physical_role_refs != null) { + physical_role_refs.clear(); + return; + } + physical_role_refs = null; + } + + public List> getOverlayRole() { + return overlay_role_refs; + } + + public void setOverlayRole(OverlayRole obj) { + overlay_role_refs = new ArrayList>(); + overlay_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addOverlayRole(OverlayRole obj) { + if (overlay_role_refs == null) { + overlay_role_refs = new ArrayList>(); + } + overlay_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeOverlayRole(OverlayRole obj) { + if (overlay_role_refs != null) { + overlay_role_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearOverlayRole() { + if (overlay_role_refs != null) { + overlay_role_refs.clear(); + return; + } + overlay_role_refs = null; + } + + public List> getHardwareInventorys() { + return hardware_inventorys; + } + + public List> getCliConfigs() { + return cli_configs; + } + + public List> getPhysicalInterfaces() { + return physical_interfaces; + } + + public List> getLogicalInterfaces() { + return logical_interfaces; + } + + public List> getTelemetryProfile() { + return telemetry_profile_refs; + } + + public void setTelemetryProfile(TelemetryProfile obj) { + telemetry_profile_refs = new ArrayList>(); + telemetry_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTelemetryProfile(TelemetryProfile obj) { + if (telemetry_profile_refs == null) { + telemetry_profile_refs = new ArrayList>(); + } + telemetry_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTelemetryProfile(TelemetryProfile obj) { + if (telemetry_profile_refs != null) { + telemetry_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTelemetryProfile() { + if (telemetry_profile_refs != null) { + telemetry_profile_refs.clear(); + return; + } + telemetry_profile_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } + + public List> getServiceEndpointBackRefs() { + return service_endpoint_back_refs; + } + + public List> getNetworkDeviceConfigBackRefs() { + return network_device_config_back_refs; + } + + public List> getE2ServiceProviderBackRefs() { + return e2_service_provider_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PimParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PimParameters.java new file mode 100644 index 00000000000..86d58dc0527 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PimParameters.java @@ -0,0 +1,60 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PimParameters extends ApiPropertyBase { + List rp_ip_address; + String mode; + Boolean enable_all_interfaces; + public PimParameters() { + } + public PimParameters(List rp_ip_address, String mode, Boolean enable_all_interfaces) { + this.rp_ip_address = rp_ip_address; + this.mode = mode; + this.enable_all_interfaces = enable_all_interfaces; + } + public PimParameters(List rp_ip_address) { + this(rp_ip_address, "sparse-dense", null); } + public PimParameters(List rp_ip_address, String mode) { + this(rp_ip_address, mode, null); } + + public String getMode() { + return mode; + } + + public void setMode(String mode) { + this.mode = mode; + } + + + public Boolean getEnableAllInterfaces() { + return enable_all_interfaces; + } + + public void setEnableAllInterfaces(Boolean enable_all_interfaces) { + this.enable_all_interfaces = enable_all_interfaces; + } + + + public List getRpIpAddress() { + return rp_ip_address; + } + + + public void addRpIpAddress(String obj) { + if (rp_ip_address == null) { + rp_ip_address = new ArrayList(); + } + rp_ip_address.add(obj); + } + public void clearRpIpAddress() { + rp_ip_address = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PlaybookInfoListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PlaybookInfoListType.java new file mode 100644 index 00000000000..a8cf80d27e2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PlaybookInfoListType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PlaybookInfoListType extends ApiPropertyBase { + List playbook_info; + public PlaybookInfoListType() { + } + public PlaybookInfoListType(List playbook_info) { + this.playbook_info = playbook_info; + } + + public List getPlaybookInfo() { + return playbook_info; + } + + + public void addPlaybookInfo(PlaybookInfoType obj) { + if (playbook_info == null) { + playbook_info = new ArrayList(); + } + playbook_info.add(obj); + } + public void clearPlaybookInfo() { + playbook_info = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PlaybookInfoType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PlaybookInfoType.java new file mode 100644 index 00000000000..8e9d660e901 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PlaybookInfoType.java @@ -0,0 +1,89 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PlaybookInfoType extends ApiPropertyBase { + String playbook_uri; + Boolean multi_device_playbook; + String vendor; + String device_family; + Integer job_completion_weightage; + Integer sequence_no; + public PlaybookInfoType() { + } + public PlaybookInfoType(String playbook_uri, Boolean multi_device_playbook, String vendor, String device_family, Integer job_completion_weightage, Integer sequence_no) { + this.playbook_uri = playbook_uri; + this.multi_device_playbook = multi_device_playbook; + this.vendor = vendor; + this.device_family = device_family; + this.job_completion_weightage = job_completion_weightage; + this.sequence_no = sequence_no; + } + public PlaybookInfoType(String playbook_uri) { + this(playbook_uri, false, null, null, 100, null); } + public PlaybookInfoType(String playbook_uri, Boolean multi_device_playbook) { + this(playbook_uri, multi_device_playbook, null, null, 100, null); } + public PlaybookInfoType(String playbook_uri, Boolean multi_device_playbook, String vendor) { + this(playbook_uri, multi_device_playbook, vendor, null, 100, null); } + public PlaybookInfoType(String playbook_uri, Boolean multi_device_playbook, String vendor, String device_family) { + this(playbook_uri, multi_device_playbook, vendor, device_family, 100, null); } + public PlaybookInfoType(String playbook_uri, Boolean multi_device_playbook, String vendor, String device_family, Integer job_completion_weightage) { + this(playbook_uri, multi_device_playbook, vendor, device_family, job_completion_weightage, null); } + + public String getPlaybookUri() { + return playbook_uri; + } + + public void setPlaybookUri(String playbook_uri) { + this.playbook_uri = playbook_uri; + } + + + public Boolean getMultiDevicePlaybook() { + return multi_device_playbook; + } + + public void setMultiDevicePlaybook(Boolean multi_device_playbook) { + this.multi_device_playbook = multi_device_playbook; + } + + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + + public String getDeviceFamily() { + return device_family; + } + + public void setDeviceFamily(String device_family) { + this.device_family = device_family; + } + + + public Integer getJobCompletionWeightage() { + return job_completion_weightage; + } + + public void setJobCompletionWeightage(Integer job_completion_weightage) { + this.job_completion_weightage = job_completion_weightage; + } + + + public Integer getSequenceNo() { + return sequence_no; + } + + public void setSequenceNo(Integer sequence_no) { + this.sequence_no = sequence_no; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PluginProperties.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PluginProperties.java new file mode 100644 index 00000000000..f85c51ce1c6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PluginProperties.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PluginProperties extends ApiPropertyBase { + List plugin_property; + public PluginProperties() { + } + public PluginProperties(List plugin_property) { + this.plugin_property = plugin_property; + } + + public List getPluginProperty() { + return plugin_property; + } + + + public void addPluginProperty(PluginProperty obj) { + if (plugin_property == null) { + plugin_property = new ArrayList(); + } + plugin_property.add(obj); + } + public void clearPluginProperty() { + plugin_property = null; + } + + + public void addPluginProperty(String property, String value) { + if (plugin_property == null) { + plugin_property = new ArrayList(); + } + plugin_property.add(new PluginProperty(property, value)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PluginProperty.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PluginProperty.java new file mode 100644 index 00000000000..8270f1966f3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PluginProperty.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PluginProperty extends ApiPropertyBase { + String property; + String value; + public PluginProperty() { + } + public PluginProperty(String property, String value) { + this.property = property; + this.value = value; + } + public PluginProperty(String property) { + this(property, null); } + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyBasedForwardingRuleType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyBasedForwardingRuleType.java new file mode 100644 index 00000000000..a650a5988e3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyBasedForwardingRuleType.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PolicyBasedForwardingRuleType extends ApiPropertyBase { + String direction; + Integer vlan_tag; + String src_mac; + String dst_mac; + Integer mpls_label; + String service_chain_address; + String ipv6_service_chain_address; + String protocol; + public PolicyBasedForwardingRuleType() { + } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag, String src_mac, String dst_mac, Integer mpls_label, String service_chain_address, String ipv6_service_chain_address, String protocol) { + this.direction = direction; + this.vlan_tag = vlan_tag; + this.src_mac = src_mac; + this.dst_mac = dst_mac; + this.mpls_label = mpls_label; + this.service_chain_address = service_chain_address; + this.ipv6_service_chain_address = ipv6_service_chain_address; + this.protocol = protocol; + } + public PolicyBasedForwardingRuleType(String direction) { + this(direction, null, null, null, null, null, null, null); } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag) { + this(direction, vlan_tag, null, null, null, null, null, null); } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag, String src_mac) { + this(direction, vlan_tag, src_mac, null, null, null, null, null); } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag, String src_mac, String dst_mac) { + this(direction, vlan_tag, src_mac, dst_mac, null, null, null, null); } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag, String src_mac, String dst_mac, Integer mpls_label) { + this(direction, vlan_tag, src_mac, dst_mac, mpls_label, null, null, null); } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag, String src_mac, String dst_mac, Integer mpls_label, String service_chain_address) { + this(direction, vlan_tag, src_mac, dst_mac, mpls_label, service_chain_address, null, null); } + public PolicyBasedForwardingRuleType(String direction, Integer vlan_tag, String src_mac, String dst_mac, Integer mpls_label, String service_chain_address, String ipv6_service_chain_address) { + this(direction, vlan_tag, src_mac, dst_mac, mpls_label, service_chain_address, ipv6_service_chain_address, null); } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + + public Integer getVlanTag() { + return vlan_tag; + } + + public void setVlanTag(Integer vlan_tag) { + this.vlan_tag = vlan_tag; + } + + + public String getSrcMac() { + return src_mac; + } + + public void setSrcMac(String src_mac) { + this.src_mac = src_mac; + } + + + public String getDstMac() { + return dst_mac; + } + + public void setDstMac(String dst_mac) { + this.dst_mac = dst_mac; + } + + + public Integer getMplsLabel() { + return mpls_label; + } + + public void setMplsLabel(Integer mpls_label) { + this.mpls_label = mpls_label; + } + + + public String getServiceChainAddress() { + return service_chain_address; + } + + public void setServiceChainAddress(String service_chain_address) { + this.service_chain_address = service_chain_address; + } + + + public String getIpv6ServiceChainAddress() { + return ipv6_service_chain_address; + } + + public void setIpv6ServiceChainAddress(String ipv6_service_chain_address) { + this.ipv6_service_chain_address = ipv6_service_chain_address; + } + + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyEntriesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyEntriesType.java new file mode 100644 index 00000000000..c2e590428cd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyEntriesType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PolicyEntriesType extends ApiPropertyBase { + List policy_rule; + public PolicyEntriesType() { + } + public PolicyEntriesType(List policy_rule) { + this.policy_rule = policy_rule; + } + + public List getPolicyRule() { + return policy_rule; + } + + + public void addPolicyRule(PolicyRuleType obj) { + if (policy_rule == null) { + policy_rule = new ArrayList(); + } + policy_rule.add(obj); + } + public void clearPolicyRule() { + policy_rule = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyManagement.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyManagement.java new file mode 100644 index 00000000000..b07a332933f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyManagement.java @@ -0,0 +1,133 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PolicyManagement extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_groups; + private List> address_groups; + private List> firewall_rules; + private List> firewall_policys; + private List> application_policy_sets; + private List> tag_refs; + + @Override + public String getObjectType() { + return "policy-management"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(ConfigRoot parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceGroups() { + return service_groups; + } + + public List> getAddressGroups() { + return address_groups; + } + + public List> getFirewallRules() { + return firewall_rules; + } + + public List> getFirewallPolicys() { + return firewall_policys; + } + + public List> getApplicationPolicySets() { + return application_policy_sets; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyRuleType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyRuleType.java new file mode 100644 index 00000000000..b7ff0a5f49a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PolicyRuleType.java @@ -0,0 +1,234 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PolicyRuleType extends ApiPropertyBase { + SequenceType rule_sequence; + String rule_uuid; + String direction; + String protocol; + List src_addresses; + List src_ports; + List application; + List dst_addresses; + List dst_ports; + ActionListType action_list; + String ethertype; + volatile java.util.Date created; + volatile java.util.Date last_modified; + public PolicyRuleType() { + } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application, List dst_addresses, List dst_ports, ActionListType action_list, String ethertype, java.util.Date created, java.util.Date last_modified) { + this.rule_sequence = rule_sequence; + this.rule_uuid = rule_uuid; + this.direction = direction; + this.protocol = protocol; + this.src_addresses = src_addresses; + this.src_ports = src_ports; + this.application = application; + this.dst_addresses = dst_addresses; + this.dst_ports = dst_ports; + this.action_list = action_list; + this.ethertype = ethertype; + this.created = created; + this.last_modified = last_modified; + } + public PolicyRuleType(SequenceType rule_sequence) { + this(rule_sequence, null, null, null, null, null, null, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid) { + this(rule_sequence, rule_uuid, null, null, null, null, null, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction) { + this(rule_sequence, rule_uuid, direction, null, null, null, null, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol) { + this(rule_sequence, rule_uuid, direction, protocol, null, null, null, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, null, null, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, null, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, application, null, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application, List dst_addresses) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, application, dst_addresses, null, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application, List dst_addresses, List dst_ports) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, application, dst_addresses, dst_ports, null, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application, List dst_addresses, List dst_ports, ActionListType action_list) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, application, dst_addresses, dst_ports, action_list, null, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application, List dst_addresses, List dst_ports, ActionListType action_list, String ethertype) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, application, dst_addresses, dst_ports, action_list, ethertype, null, null); } + public PolicyRuleType(SequenceType rule_sequence, String rule_uuid, String direction, String protocol, List src_addresses, List src_ports, List application, List dst_addresses, List dst_ports, ActionListType action_list, String ethertype, java.util.Date created) { + this(rule_sequence, rule_uuid, direction, protocol, src_addresses, src_ports, application, dst_addresses, dst_ports, action_list, ethertype, created, null); } + + public SequenceType getRuleSequence() { + return rule_sequence; + } + + public void setRuleSequence(SequenceType rule_sequence) { + this.rule_sequence = rule_sequence; + } + + + public String getRuleUuid() { + return rule_uuid; + } + + public void setRuleUuid(String rule_uuid) { + this.rule_uuid = rule_uuid; + } + + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public ActionListType getActionList() { + return action_list; + } + + public void setActionList(ActionListType action_list) { + this.action_list = action_list; + } + + + public String getEthertype() { + return ethertype; + } + + public void setEthertype(String ethertype) { + this.ethertype = ethertype; + } + + + public java.util.Date getCreated() { + return created; + } + + public void setCreated(java.util.Date created) { + this.created = created; + } + + + public java.util.Date getLastModified() { + return last_modified; + } + + public void setLastModified(java.util.Date last_modified) { + this.last_modified = last_modified; + } + + + public List getSrcAddresses() { + return src_addresses; + } + + + public void addSrcAddresses(AddressType obj) { + if (src_addresses == null) { + src_addresses = new ArrayList(); + } + src_addresses.add(obj); + } + public void clearSrcAddresses() { + src_addresses = null; + } + + + public List getSrcPorts() { + return src_ports; + } + + + public void addSrcPorts(PortType obj) { + if (src_ports == null) { + src_ports = new ArrayList(); + } + src_ports.add(obj); + } + public void clearSrcPorts() { + src_ports = null; + } + + + public void addSrcPorts(Integer start_port, Integer end_port) { + if (src_ports == null) { + src_ports = new ArrayList(); + } + src_ports.add(new PortType(start_port, end_port)); + } + + + public List getApplication() { + return application; + } + + + public void addApplication(String obj) { + if (application == null) { + application = new ArrayList(); + } + application.add(obj); + } + public void clearApplication() { + application = null; + } + + + public List getDstAddresses() { + return dst_addresses; + } + + + public void addDstAddresses(AddressType obj) { + if (dst_addresses == null) { + dst_addresses = new ArrayList(); + } + dst_addresses.add(obj); + } + public void clearDstAddresses() { + dst_addresses = null; + } + + + public List getDstPorts() { + return dst_ports; + } + + + public void addDstPorts(PortType obj) { + if (dst_ports == null) { + dst_ports = new ArrayList(); + } + dst_ports.add(obj); + } + public void clearDstPorts() { + dst_ports = null; + } + + + public void addDstPorts(Integer start_port, Integer end_port) { + if (dst_ports == null) { + dst_ports = new ArrayList(); + } + dst_ports.add(new PortType(start_port, end_port)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Port.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Port.java new file mode 100644 index 00000000000..f9c5395d722 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Port.java @@ -0,0 +1,155 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Port extends ApiObjectBase { + private String port_group_uuid; + private BaremetalPortInfo bms_port_info; + private ESXIProperties esxi_port_info; + private String label; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> port_group_back_refs; + private transient List> physical_interface_back_refs; + + @Override + public String getObjectType() { + return "port"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-node"); + } + + @Override + public String getDefaultParentType() { + return "node"; + } + + public void setParent(Node parent) { + super.setParent(parent); + } + + public String getGroupUuid() { + return port_group_uuid; + } + + public void setGroupUuid(String port_group_uuid) { + this.port_group_uuid = port_group_uuid; + } + + + public BaremetalPortInfo getBmsPortInfo() { + return bms_port_info; + } + + public void setBmsPortInfo(BaremetalPortInfo bms_port_info) { + this.bms_port_info = bms_port_info; + } + + + public ESXIProperties getEsxiPortInfo() { + return esxi_port_info; + } + + public void setEsxiPortInfo(ESXIProperties esxi_port_info) { + this.esxi_port_info = esxi_port_info; + } + + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPortGroupBackRefs() { + return port_group_back_refs; + } + + public List> getPhysicalInterfaceBackRefs() { + return physical_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortGroup.java new file mode 100644 index 00000000000..81e37dd6381 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortGroup.java @@ -0,0 +1,146 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PortGroup extends ApiObjectBase { + private BaremetalPortGroupInfo bms_port_group_info; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> port_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "port-group"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-node"); + } + + @Override + public String getDefaultParentType() { + return "node"; + } + + public void setParent(Node parent) { + super.setParent(parent); + } + + public BaremetalPortGroupInfo getBmsPortGroupInfo() { + return bms_port_group_info; + } + + public void setBmsPortGroupInfo(BaremetalPortGroupInfo bms_port_group_info) { + this.bms_port_group_info = bms_port_group_info; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPort() { + return port_refs; + } + + public void setPort(Port obj) { + port_refs = new ArrayList>(); + port_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPort(Port obj) { + if (port_refs == null) { + port_refs = new ArrayList>(); + } + port_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePort(Port obj) { + if (port_refs != null) { + port_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPort() { + if (port_refs != null) { + port_refs.clear(); + return; + } + port_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortGroupProperties.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortGroupProperties.java new file mode 100644 index 00000000000..927777342c5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortGroupProperties.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortGroupProperties extends ApiPropertyBase { + Integer miimon; + String xmit_hash_policy; + public PortGroupProperties() { + } + public PortGroupProperties(Integer miimon, String xmit_hash_policy) { + this.miimon = miimon; + this.xmit_hash_policy = xmit_hash_policy; + } + public PortGroupProperties(Integer miimon) { + this(miimon, null); } + + public Integer getMiimon() { + return miimon; + } + + public void setMiimon(Integer miimon) { + this.miimon = miimon; + } + + + public String getXmitHashPolicy() { + return xmit_hash_policy; + } + + public void setXmitHashPolicy(String xmit_hash_policy) { + this.xmit_hash_policy = xmit_hash_policy; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortInfoType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortInfoType.java new file mode 100644 index 00000000000..994b68028cc --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortInfoType.java @@ -0,0 +1,112 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortInfoType extends ApiPropertyBase { + String name; + String type_; + String port_speed; + Boolean channelized; + String channelized_port_speed; + String port_group; + List labels; + public PortInfoType() { + } + public PortInfoType(String name, String type_, String port_speed, Boolean channelized, String channelized_port_speed, String port_group, List labels) { + this.name = name; + this.type_ = type_; + this.port_speed = port_speed; + this.channelized = channelized; + this.channelized_port_speed = channelized_port_speed; + this.port_group = port_group; + this.labels = labels; + } + public PortInfoType(String name) { + this(name, null, null, false, null, null, null); } + public PortInfoType(String name, String type_) { + this(name, type_, null, false, null, null, null); } + public PortInfoType(String name, String type_, String port_speed) { + this(name, type_, port_speed, false, null, null, null); } + public PortInfoType(String name, String type_, String port_speed, Boolean channelized) { + this(name, type_, port_speed, channelized, null, null, null); } + public PortInfoType(String name, String type_, String port_speed, Boolean channelized, String channelized_port_speed) { + this(name, type_, port_speed, channelized, channelized_port_speed, null, null); } + public PortInfoType(String name, String type_, String port_speed, Boolean channelized, String channelized_port_speed, String port_group) { + this(name, type_, port_speed, channelized, channelized_port_speed, port_group, null); } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public String getType() { + return type_; + } + + public void setType(String type_) { + this.type_ = type_; + } + + + public String getPortSpeed() { + return port_speed; + } + + public void setPortSpeed(String port_speed) { + this.port_speed = port_speed; + } + + + public Boolean getChannelized() { + return channelized; + } + + public void setChannelized(Boolean channelized) { + this.channelized = channelized; + } + + + public String getChannelizedPortSpeed() { + return channelized_port_speed; + } + + public void setChannelizedPortSpeed(String channelized_port_speed) { + this.channelized_port_speed = channelized_port_speed; + } + + + public String getPortGroup() { + return port_group; + } + + public void setPortGroup(String port_group) { + this.port_group = port_group; + } + + + public List getLabels() { + return labels; + } + + + public void addLabels(String obj) { + if (labels == null) { + labels = new ArrayList(); + } + labels.add(obj); + } + public void clearLabels() { + labels = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortMap.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortMap.java new file mode 100644 index 00000000000..c3911ad4c99 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortMap.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortMap extends ApiPropertyBase { + String protocol; + Integer src_port; + Integer dst_port; + public PortMap() { + } + public PortMap(String protocol, Integer src_port, Integer dst_port) { + this.protocol = protocol; + this.src_port = src_port; + this.dst_port = dst_port; + } + public PortMap(String protocol) { + this(protocol, null, null); } + public PortMap(String protocol, Integer src_port) { + this(protocol, src_port, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Integer getSrcPort() { + return src_port; + } + + public void setSrcPort(Integer src_port) { + this.src_port = src_port; + } + + + public Integer getDstPort() { + return dst_port; + } + + public void setDstPort(Integer dst_port) { + this.dst_port = dst_port; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortMappings.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortMappings.java new file mode 100644 index 00000000000..42456113c79 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortMappings.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortMappings extends ApiPropertyBase { + List port_mappings; + public PortMappings() { + } + public PortMappings(List port_mappings) { + this.port_mappings = port_mappings; + } + + public List getPortMappings() { + return port_mappings; + } + + + public void addPortMappings(PortMap obj) { + if (port_mappings == null) { + port_mappings = new ArrayList(); + } + port_mappings.add(obj); + } + public void clearPortMappings() { + port_mappings = null; + } + + + public void addPortMappings(String protocol, Integer src_port, Integer dst_port) { + if (port_mappings == null) { + port_mappings = new ArrayList(); + } + port_mappings.add(new PortMap(protocol, src_port, dst_port)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortParameters.java new file mode 100644 index 00000000000..5f6bc584eee --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortParameters.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortParameters extends ApiPropertyBase { + Boolean port_disable; + Integer port_mtu; + String port_description; + public PortParameters() { + } + public PortParameters(Boolean port_disable, Integer port_mtu, String port_description) { + this.port_disable = port_disable; + this.port_mtu = port_mtu; + this.port_description = port_description; + } + public PortParameters(Boolean port_disable) { + this(port_disable, null, null); } + public PortParameters(Boolean port_disable, Integer port_mtu) { + this(port_disable, port_mtu, null); } + + public Boolean getPortDisable() { + return port_disable; + } + + public void setPortDisable(Boolean port_disable) { + this.port_disable = port_disable; + } + + + public Integer getPortMtu() { + return port_mtu; + } + + public void setPortMtu(Integer port_mtu) { + this.port_mtu = port_mtu; + } + + + public String getPortDescription() { + return port_description; + } + + public void setPortDescription(String port_description) { + this.port_description = port_description; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortProfile.java new file mode 100644 index 00000000000..a6fa06766ea --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortProfile.java @@ -0,0 +1,156 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PortProfile extends ApiObjectBase { + private PortProfileParameters port_profile_params; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> storm_control_profile_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> virtual_port_group_back_refs; + + @Override + public String getObjectType() { + return "port-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public PortProfileParameters getParams() { + return port_profile_params; + } + + public void setParams(PortProfileParameters port_profile_params) { + this.port_profile_params = port_profile_params; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getStormControlProfile() { + return storm_control_profile_refs; + } + + public void setStormControlProfile(StormControlProfile obj) { + storm_control_profile_refs = new ArrayList>(); + storm_control_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addStormControlProfile(StormControlProfile obj) { + if (storm_control_profile_refs == null) { + storm_control_profile_refs = new ArrayList>(); + } + storm_control_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeStormControlProfile(StormControlProfile obj) { + if (storm_control_profile_refs != null) { + storm_control_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearStormControlProfile() { + if (storm_control_profile_refs != null) { + storm_control_profile_refs.clear(); + return; + } + storm_control_profile_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getVirtualPortGroupBackRefs() { + return virtual_port_group_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortProfileParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortProfileParameters.java new file mode 100644 index 00000000000..b952fb0542a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortProfileParameters.java @@ -0,0 +1,76 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortProfileParameters extends ApiPropertyBase { + PortParameters port_params; + Boolean flow_control; + LacpParams lacp_params; + Boolean bpdu_loop_protection; + Boolean port_cos_untrust; + public PortProfileParameters() { + } + public PortProfileParameters(PortParameters port_params, Boolean flow_control, LacpParams lacp_params, Boolean bpdu_loop_protection, Boolean port_cos_untrust) { + this.port_params = port_params; + this.flow_control = flow_control; + this.lacp_params = lacp_params; + this.bpdu_loop_protection = bpdu_loop_protection; + this.port_cos_untrust = port_cos_untrust; + } + public PortProfileParameters(PortParameters port_params) { + this(port_params, false, null, false, false); } + public PortProfileParameters(PortParameters port_params, Boolean flow_control) { + this(port_params, flow_control, null, false, false); } + public PortProfileParameters(PortParameters port_params, Boolean flow_control, LacpParams lacp_params) { + this(port_params, flow_control, lacp_params, false, false); } + public PortProfileParameters(PortParameters port_params, Boolean flow_control, LacpParams lacp_params, Boolean bpdu_loop_protection) { + this(port_params, flow_control, lacp_params, bpdu_loop_protection, false); } + + public PortParameters getPortParams() { + return port_params; + } + + public void setPortParams(PortParameters port_params) { + this.port_params = port_params; + } + + + public Boolean getFlowControl() { + return flow_control; + } + + public void setFlowControl(Boolean flow_control) { + this.flow_control = flow_control; + } + + + public LacpParams getLacpParams() { + return lacp_params; + } + + public void setLacpParams(LacpParams lacp_params) { + this.lacp_params = lacp_params; + } + + + public Boolean getBpduLoopProtection() { + return bpdu_loop_protection; + } + + public void setBpduLoopProtection(Boolean bpdu_loop_protection) { + this.bpdu_loop_protection = bpdu_loop_protection; + } + + + public Boolean getPortCosUntrust() { + return port_cos_untrust; + } + + public void setPortCosUntrust(Boolean port_cos_untrust) { + this.port_cos_untrust = port_cos_untrust; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTranslationPool.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTranslationPool.java new file mode 100644 index 00000000000..4c665c7e3ed --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTranslationPool.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortTranslationPool extends ApiPropertyBase { + String protocol; + PortType port_range; + String port_count; + public PortTranslationPool() { + } + public PortTranslationPool(String protocol, PortType port_range, String port_count) { + this.protocol = protocol; + this.port_range = port_range; + this.port_count = port_count; + } + public PortTranslationPool(String protocol) { + this(protocol, null, null); } + public PortTranslationPool(String protocol, PortType port_range) { + this(protocol, port_range, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public PortType getPortRange() { + return port_range; + } + + public void setPortRange(PortType port_range) { + this.port_range = port_range; + } + + + public String getPortCount() { + return port_count; + } + + public void setPortCount(String port_count) { + this.port_count = port_count; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTranslationPools.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTranslationPools.java new file mode 100644 index 00000000000..89b24d69ef3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTranslationPools.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortTranslationPools extends ApiPropertyBase { + List port_translation_pool; + public PortTranslationPools() { + } + public PortTranslationPools(List port_translation_pool) { + this.port_translation_pool = port_translation_pool; + } + + public List getPortTranslationPool() { + return port_translation_pool; + } + + + public void addPortTranslationPool(PortTranslationPool obj) { + if (port_translation_pool == null) { + port_translation_pool = new ArrayList(); + } + port_translation_pool.add(obj); + } + public void clearPortTranslationPool() { + port_translation_pool = null; + } + + + public void addPortTranslationPool(String protocol, PortType port_range, String port_count) { + if (port_translation_pool == null) { + port_translation_pool = new ArrayList(); + } + port_translation_pool.add(new PortTranslationPool(protocol, port_range, port_count)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTuple.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTuple.java new file mode 100644 index 00000000000..93cd6a7aede --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortTuple.java @@ -0,0 +1,172 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class PortTuple extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> logical_router_refs; + private List> virtual_network_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "port-tuple"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-service-instance"); + } + + @Override + public String getDefaultParentType() { + return "service-instance"; + } + + public void setParent(ServiceInstance parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getLogicalRouter() { + return logical_router_refs; + } + + public void setLogicalRouter(LogicalRouter obj) { + logical_router_refs = new ArrayList>(); + logical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLogicalRouter(LogicalRouter obj) { + if (logical_router_refs == null) { + logical_router_refs = new ArrayList>(); + } + logical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLogicalRouter(LogicalRouter obj) { + if (logical_router_refs != null) { + logical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLogicalRouter() { + if (logical_router_refs != null) { + logical_router_refs.clear(); + return; + } + logical_router_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortType.java new file mode 100644 index 00000000000..a476a8d2afd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/PortType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class PortType extends ApiPropertyBase { + Integer start_port; + Integer end_port; + public PortType() { + } + public PortType(Integer start_port, Integer end_port) { + this.start_port = start_port; + this.end_port = end_port; + } + public PortType(Integer start_port) { + this(start_port, 65535); } + + public Integer getStartPort() { + return start_port; + } + + public void setStartPort(Integer start_port) { + this.start_port = start_port; + } + + + public Integer getEndPort() { + return end_port; + } + + public void setEndPort(Integer end_port) { + this.end_port = end_port; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Project.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Project.java new file mode 100644 index 00000000000..cd35c09a4cd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Project.java @@ -0,0 +1,485 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Project extends ApiObjectBase { + private QuotaType quota; + private Boolean vxlan_routing; + private Boolean alarm_enable; + private Boolean enable_security_policy_draft; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> security_logging_objects; + private List> namespace_refs; + private List> security_groups; + private List> virtual_networks; + private List> qos_configs; + private List> network_ipams; + private List> network_policys; + private List> virtual_machine_interfaces; + private List> floating_ip_pool_refs; + private List> alias_ip_pool_refs; + private List> bgp_as_a_services; + private List> routing_policys; + private List> route_aggregates; + private List> service_instances; + private List> service_health_checks; + private List> route_tables; + private List> interface_route_tables; + private List> logical_routers; + private List> api_access_lists; + private List> multicast_policys; + private List> loadbalancer_pools; + private List> loadbalancer_healthmonitors; + private List> virtual_ips; + private List> loadbalancer_listeners; + private List> loadbalancers; + private List> bgpvpns; + private List> alarms; + private List> policy_managements; + private List> service_groups; + private List> address_groups; + private List> firewall_rules; + private List> firewall_policys; + private List> application_policy_sets; + private List> application_policy_set_refs; + private List> tags; + private List> device_functional_groups; + private List> virtual_port_groups; + private List> telemetry_profiles; + private List> sflow_profiles; + private List> grpc_profiles; + private List> snmp_profiles; + private List> netconf_profiles; + private List> storm_control_profiles; + private List> port_profiles; + private List> host_based_services; + private List> tag_refs; + private transient List> floating_ip_back_refs; + private transient List> alias_ip_back_refs; + + @Override + public String getObjectType() { + return "project"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain"); + } + + @Override + public String getDefaultParentType() { + return "domain"; + } + + public void setParent(Domain parent) { + super.setParent(parent); + } + + public QuotaType getQuota() { + return quota; + } + + public void setQuota(QuotaType quota) { + this.quota = quota; + } + + + public Boolean getVxlanRouting() { + return vxlan_routing; + } + + public void setVxlanRouting(Boolean vxlan_routing) { + this.vxlan_routing = vxlan_routing; + } + + + public Boolean getAlarmEnable() { + return alarm_enable; + } + + public void setAlarmEnable(Boolean alarm_enable) { + this.alarm_enable = alarm_enable; + } + + + public Boolean getEnableSecurityPolicyDraft() { + return enable_security_policy_draft; + } + + public void setEnableSecurityPolicyDraft(Boolean enable_security_policy_draft) { + this.enable_security_policy_draft = enable_security_policy_draft; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getSecurityLoggingObjects() { + return security_logging_objects; + } + + public List> getNamespace() { + return namespace_refs; + } + + public void setNamespace(Namespace obj, SubnetType data) { + namespace_refs = new ArrayList>(); + namespace_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addNamespace(Namespace obj, SubnetType data) { + if (namespace_refs == null) { + namespace_refs = new ArrayList>(); + } + namespace_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeNamespace(Namespace obj, SubnetType data) { + if (namespace_refs != null) { + namespace_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearNamespace() { + if (namespace_refs != null) { + namespace_refs.clear(); + return; + } + namespace_refs = null; + } + + + public List> getSecurityGroups() { + return security_groups; + } + + public List> getVirtualNetworks() { + return virtual_networks; + } + + public List> getQosConfigs() { + return qos_configs; + } + + public List> getNetworkIpams() { + return network_ipams; + } + + public List> getNetworkPolicys() { + return network_policys; + } + + public List> getVirtualMachineInterfaces() { + return virtual_machine_interfaces; + } + + public List> getFloatingIpPool() { + return floating_ip_pool_refs; + } + + public void setFloatingIpPool(FloatingIpPool obj) { + floating_ip_pool_refs = new ArrayList>(); + floating_ip_pool_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFloatingIpPool(FloatingIpPool obj) { + if (floating_ip_pool_refs == null) { + floating_ip_pool_refs = new ArrayList>(); + } + floating_ip_pool_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFloatingIpPool(FloatingIpPool obj) { + if (floating_ip_pool_refs != null) { + floating_ip_pool_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFloatingIpPool() { + if (floating_ip_pool_refs != null) { + floating_ip_pool_refs.clear(); + return; + } + floating_ip_pool_refs = null; + } + + public List> getAliasIpPool() { + return alias_ip_pool_refs; + } + + public void setAliasIpPool(AliasIpPool obj) { + alias_ip_pool_refs = new ArrayList>(); + alias_ip_pool_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addAliasIpPool(AliasIpPool obj) { + if (alias_ip_pool_refs == null) { + alias_ip_pool_refs = new ArrayList>(); + } + alias_ip_pool_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeAliasIpPool(AliasIpPool obj) { + if (alias_ip_pool_refs != null) { + alias_ip_pool_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearAliasIpPool() { + if (alias_ip_pool_refs != null) { + alias_ip_pool_refs.clear(); + return; + } + alias_ip_pool_refs = null; + } + + public List> getBgpAsAServices() { + return bgp_as_a_services; + } + + public List> getRoutingPolicys() { + return routing_policys; + } + + public List> getRouteAggregates() { + return route_aggregates; + } + + public List> getServiceInstances() { + return service_instances; + } + + public List> getServiceHealthChecks() { + return service_health_checks; + } + + public List> getRouteTables() { + return route_tables; + } + + public List> getInterfaceRouteTables() { + return interface_route_tables; + } + + public List> getLogicalRouters() { + return logical_routers; + } + + public List> getApiAccessLists() { + return api_access_lists; + } + + public List> getMulticastPolicys() { + return multicast_policys; + } + + public List> getLoadbalancerPools() { + return loadbalancer_pools; + } + + public List> getLoadbalancerHealthmonitors() { + return loadbalancer_healthmonitors; + } + + public List> getVirtualIps() { + return virtual_ips; + } + + public List> getLoadbalancerListeners() { + return loadbalancer_listeners; + } + + public List> getLoadbalancers() { + return loadbalancers; + } + + public List> getBgpvpns() { + return bgpvpns; + } + + public List> getAlarms() { + return alarms; + } + + public List> getPolicyManagements() { + return policy_managements; + } + + public List> getServiceGroups() { + return service_groups; + } + + public List> getAddressGroups() { + return address_groups; + } + + public List> getFirewallRules() { + return firewall_rules; + } + + public List> getFirewallPolicys() { + return firewall_policys; + } + + public List> getApplicationPolicySets() { + return application_policy_sets; + } + + public List> getApplicationPolicySet() { + return application_policy_set_refs; + } + + public void setApplicationPolicySet(ApplicationPolicySet obj) { + application_policy_set_refs = new ArrayList>(); + application_policy_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addApplicationPolicySet(ApplicationPolicySet obj) { + if (application_policy_set_refs == null) { + application_policy_set_refs = new ArrayList>(); + } + application_policy_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeApplicationPolicySet(ApplicationPolicySet obj) { + if (application_policy_set_refs != null) { + application_policy_set_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearApplicationPolicySet() { + if (application_policy_set_refs != null) { + application_policy_set_refs.clear(); + return; + } + application_policy_set_refs = null; + } + + public List> getTags() { + return tags; + } + + public List> getDeviceFunctionalGroups() { + return device_functional_groups; + } + + public List> getVirtualPortGroups() { + return virtual_port_groups; + } + + public List> getTelemetryProfiles() { + return telemetry_profiles; + } + + public List> getSflowProfiles() { + return sflow_profiles; + } + + public List> getGrpcProfiles() { + return grpc_profiles; + } + + public List> getSnmpProfiles() { + return snmp_profiles; + } + + public List> getNetconfProfiles() { + return netconf_profiles; + } + + public List> getStormControlProfiles() { + return storm_control_profiles; + } + + public List> getPortProfiles() { + return port_profiles; + } + + public List> getHostBasedServices() { + return host_based_services; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getFloatingIpBackRefs() { + return floating_ip_back_refs; + } + + public List> getAliasIpBackRefs() { + return alias_ip_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProtocolType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProtocolType.java new file mode 100644 index 00000000000..073c8b9cdc4 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProtocolType.java @@ -0,0 +1,102 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ProtocolType extends ApiPropertyBase { + String protocol; + Integer port; + String ignore_address; + SubnetType source_prefix; + Integer source_aggregate_prefix_length; + SubnetType destination_prefix; + Integer destination_aggregate_prefix_length; + public ProtocolType() { + } + public ProtocolType(String protocol, Integer port, String ignore_address, SubnetType source_prefix, Integer source_aggregate_prefix_length, SubnetType destination_prefix, Integer destination_aggregate_prefix_length) { + this.protocol = protocol; + this.port = port; + this.ignore_address = ignore_address; + this.source_prefix = source_prefix; + this.source_aggregate_prefix_length = source_aggregate_prefix_length; + this.destination_prefix = destination_prefix; + this.destination_aggregate_prefix_length = destination_aggregate_prefix_length; + } + public ProtocolType(String protocol) { + this(protocol, null, null, null, null, null, null); } + public ProtocolType(String protocol, Integer port) { + this(protocol, port, null, null, null, null, null); } + public ProtocolType(String protocol, Integer port, String ignore_address) { + this(protocol, port, ignore_address, null, null, null, null); } + public ProtocolType(String protocol, Integer port, String ignore_address, SubnetType source_prefix) { + this(protocol, port, ignore_address, source_prefix, null, null, null); } + public ProtocolType(String protocol, Integer port, String ignore_address, SubnetType source_prefix, Integer source_aggregate_prefix_length) { + this(protocol, port, ignore_address, source_prefix, source_aggregate_prefix_length, null, null); } + public ProtocolType(String protocol, Integer port, String ignore_address, SubnetType source_prefix, Integer source_aggregate_prefix_length, SubnetType destination_prefix) { + this(protocol, port, ignore_address, source_prefix, source_aggregate_prefix_length, destination_prefix, null); } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + + public String getIgnoreAddress() { + return ignore_address; + } + + public void setIgnoreAddress(String ignore_address) { + this.ignore_address = ignore_address; + } + + + public SubnetType getSourcePrefix() { + return source_prefix; + } + + public void setSourcePrefix(SubnetType source_prefix) { + this.source_prefix = source_prefix; + } + + + public Integer getSourceAggregatePrefixLength() { + return source_aggregate_prefix_length; + } + + public void setSourceAggregatePrefixLength(Integer source_aggregate_prefix_length) { + this.source_aggregate_prefix_length = source_aggregate_prefix_length; + } + + + public SubnetType getDestinationPrefix() { + return destination_prefix; + } + + public void setDestinationPrefix(SubnetType destination_prefix) { + this.destination_prefix = destination_prefix; + } + + + public Integer getDestinationAggregatePrefixLength() { + return destination_aggregate_prefix_length; + } + + public void setDestinationAggregatePrefixLength(Integer destination_aggregate_prefix_length) { + this.destination_aggregate_prefix_length = destination_aggregate_prefix_length; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProviderAttachment.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProviderAttachment.java new file mode 100644 index 00000000000..4988054cebd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProviderAttachment.java @@ -0,0 +1,132 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ProviderAttachment extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_router_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "provider-attachment"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualRouter() { + return virtual_router_refs; + } + + public void setVirtualRouter(VirtualRouter obj) { + virtual_router_refs = new ArrayList>(); + virtual_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualRouter(VirtualRouter obj) { + if (virtual_router_refs == null) { + virtual_router_refs = new ArrayList>(); + } + virtual_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualRouter(VirtualRouter obj) { + if (virtual_router_refs != null) { + virtual_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualRouter() { + if (virtual_router_refs != null) { + virtual_router_refs.clear(); + return; + } + virtual_router_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProviderDetails.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProviderDetails.java new file mode 100644 index 00000000000..f896e3e2dac --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ProviderDetails.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ProviderDetails extends ApiPropertyBase { + Integer segmentation_id; + String physical_network; + public ProviderDetails() { + } + public ProviderDetails(Integer segmentation_id, String physical_network) { + this.segmentation_id = segmentation_id; + this.physical_network = physical_network; + } + public ProviderDetails(Integer segmentation_id) { + this(segmentation_id, null); } + + public Integer getSegmentationId() { + return segmentation_id; + } + + public void setSegmentationId(Integer segmentation_id) { + this.segmentation_id = segmentation_id; + } + + + public String getPhysicalNetwork() { + return physical_network; + } + + public void setPhysicalNetwork(String physical_network) { + this.physical_network = physical_network; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosConfig.java new file mode 100644 index 00000000000..c38be56de97 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosConfig.java @@ -0,0 +1,199 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class QosConfig extends ApiObjectBase { + private String qos_config_type; + private QosIdForwardingClassPairs dscp_entries; + private QosIdForwardingClassPairs vlan_priority_entries; + private QosIdForwardingClassPairs mpls_exp_entries; + private Integer default_forwarding_class_id; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> global_system_config_refs; + private List> tag_refs; + private transient List> virtual_network_back_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "qos-config"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(GlobalQosConfig parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getType() { + return qos_config_type; + } + + public void setType(String qos_config_type) { + this.qos_config_type = qos_config_type; + } + + + public QosIdForwardingClassPairs getDscpEntries() { + return dscp_entries; + } + + public void setDscpEntries(QosIdForwardingClassPairs dscp_entries) { + this.dscp_entries = dscp_entries; + } + + + public QosIdForwardingClassPairs getVlanPriorityEntries() { + return vlan_priority_entries; + } + + public void setVlanPriorityEntries(QosIdForwardingClassPairs vlan_priority_entries) { + this.vlan_priority_entries = vlan_priority_entries; + } + + + public QosIdForwardingClassPairs getMplsExpEntries() { + return mpls_exp_entries; + } + + public void setMplsExpEntries(QosIdForwardingClassPairs mpls_exp_entries) { + this.mpls_exp_entries = mpls_exp_entries; + } + + + public Integer getDefaultForwardingClassId() { + return default_forwarding_class_id; + } + + public void setDefaultForwardingClassId(Integer default_forwarding_class_id) { + this.default_forwarding_class_id = default_forwarding_class_id; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getGlobalSystemConfig() { + return global_system_config_refs; + } + + public void setGlobalSystemConfig(GlobalSystemConfig obj) { + global_system_config_refs = new ArrayList>(); + global_system_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addGlobalSystemConfig(GlobalSystemConfig obj) { + if (global_system_config_refs == null) { + global_system_config_refs = new ArrayList>(); + } + global_system_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeGlobalSystemConfig(GlobalSystemConfig obj) { + if (global_system_config_refs != null) { + global_system_config_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearGlobalSystemConfig() { + if (global_system_config_refs != null) { + global_system_config_refs.clear(); + return; + } + global_system_config_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosIdForwardingClassPair.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosIdForwardingClassPair.java new file mode 100644 index 00000000000..037b1e7ffbb --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosIdForwardingClassPair.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class QosIdForwardingClassPair extends ApiPropertyBase { + Integer key; + Integer forwarding_class_id; + public QosIdForwardingClassPair() { + } + public QosIdForwardingClassPair(Integer key, Integer forwarding_class_id) { + this.key = key; + this.forwarding_class_id = forwarding_class_id; + } + public QosIdForwardingClassPair(Integer key) { + this(key, null); } + + public Integer getKey() { + return key; + } + + public void setKey(Integer key) { + this.key = key; + } + + + public Integer getForwardingClassId() { + return forwarding_class_id; + } + + public void setForwardingClassId(Integer forwarding_class_id) { + this.forwarding_class_id = forwarding_class_id; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosIdForwardingClassPairs.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosIdForwardingClassPairs.java new file mode 100644 index 00000000000..b2389cea8b8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosIdForwardingClassPairs.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class QosIdForwardingClassPairs extends ApiPropertyBase { + List qos_id_forwarding_class_pair; + public QosIdForwardingClassPairs() { + } + public QosIdForwardingClassPairs(List qos_id_forwarding_class_pair) { + this.qos_id_forwarding_class_pair = qos_id_forwarding_class_pair; + } + + public List getQosIdForwardingClassPair() { + return qos_id_forwarding_class_pair; + } + + + public void addQosIdForwardingClassPair(QosIdForwardingClassPair obj) { + if (qos_id_forwarding_class_pair == null) { + qos_id_forwarding_class_pair = new ArrayList(); + } + qos_id_forwarding_class_pair.add(obj); + } + public void clearQosIdForwardingClassPair() { + qos_id_forwarding_class_pair = null; + } + + + public void addQosIdForwardingClassPair(Integer key, Integer forwarding_class_id) { + if (qos_id_forwarding_class_pair == null) { + qos_id_forwarding_class_pair = new ArrayList(); + } + qos_id_forwarding_class_pair.add(new QosIdForwardingClassPair(key, forwarding_class_id)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosQueue.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosQueue.java new file mode 100644 index 00000000000..422a6c2f4b3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QosQueue.java @@ -0,0 +1,140 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class QosQueue extends ApiObjectBase { + private Integer min_bandwidth; + private Integer max_bandwidth; + private Integer qos_queue_identifier; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> forwarding_class_back_refs; + + @Override + public String getObjectType() { + return "qos-queue"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-global-qos-config"); + } + + @Override + public String getDefaultParentType() { + return "global-qos-config"; + } + + public void setParent(GlobalQosConfig parent) { + super.setParent(parent); + } + + public Integer getMinBandwidth() { + return min_bandwidth; + } + + public void setMinBandwidth(Integer min_bandwidth) { + this.min_bandwidth = min_bandwidth; + } + + + public Integer getMaxBandwidth() { + return max_bandwidth; + } + + public void setMaxBandwidth(Integer max_bandwidth) { + this.max_bandwidth = max_bandwidth; + } + + + public Integer getIdentifier() { + return qos_queue_identifier; + } + + public void setIdentifier(Integer qos_queue_identifier) { + this.qos_queue_identifier = qos_queue_identifier; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getForwardingClassBackRefs() { + return forwarding_class_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QuotaType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QuotaType.java new file mode 100644 index 00000000000..928f2de3450 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/QuotaType.java @@ -0,0 +1,427 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class QuotaType extends ApiPropertyBase { + Integer defaults; + Integer floating_ip; + Integer instance_ip; + Integer virtual_machine_interface; + Integer virtual_network; + Integer virtual_router; + Integer virtual_DNS; + Integer virtual_DNS_record; + Integer bgp_router; + Integer network_ipam; + Integer access_control_list; + Integer network_policy; + Integer floating_ip_pool; + Integer service_template; + Integer service_instance; + Integer logical_router; + Integer security_group; + Integer security_group_rule; + Integer subnet; + Integer global_vrouter_config; + Integer loadbalancer; + Integer loadbalancer_listener; + Integer loadbalancer_pool; + Integer loadbalancer_member; + Integer loadbalancer_healthmonitor; + Integer virtual_ip; + Integer security_logging_object; + Integer route_table; + Integer firewall_group; + Integer firewall_policy; + Integer firewall_rule; + Integer host_based_service; + public QuotaType() { + } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip, Integer security_logging_object, Integer route_table, Integer firewall_group, Integer firewall_policy, Integer firewall_rule, Integer host_based_service) { + this.defaults = defaults; + this.floating_ip = floating_ip; + this.instance_ip = instance_ip; + this.virtual_machine_interface = virtual_machine_interface; + this.virtual_network = virtual_network; + this.virtual_router = virtual_router; + this.virtual_DNS = virtual_DNS; + this.virtual_DNS_record = virtual_DNS_record; + this.bgp_router = bgp_router; + this.network_ipam = network_ipam; + this.access_control_list = access_control_list; + this.network_policy = network_policy; + this.floating_ip_pool = floating_ip_pool; + this.service_template = service_template; + this.service_instance = service_instance; + this.logical_router = logical_router; + this.security_group = security_group; + this.security_group_rule = security_group_rule; + this.subnet = subnet; + this.global_vrouter_config = global_vrouter_config; + this.loadbalancer = loadbalancer; + this.loadbalancer_listener = loadbalancer_listener; + this.loadbalancer_pool = loadbalancer_pool; + this.loadbalancer_member = loadbalancer_member; + this.loadbalancer_healthmonitor = loadbalancer_healthmonitor; + this.virtual_ip = virtual_ip; + this.security_logging_object = security_logging_object; + this.route_table = route_table; + this.firewall_group = firewall_group; + this.firewall_policy = firewall_policy; + this.firewall_rule = firewall_rule; + this.host_based_service = host_based_service; + } + public QuotaType(Integer defaults) { + this(defaults, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip) { + this(defaults, floating_ip, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip) { + this(defaults, floating_ip, instance_ip, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, null, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, null, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, null, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, null, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, null, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, null, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, null, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, null, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, virtual_ip, null, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip, Integer security_logging_object) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, virtual_ip, security_logging_object, null, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip, Integer security_logging_object, Integer route_table) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, virtual_ip, security_logging_object, route_table, null, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip, Integer security_logging_object, Integer route_table, Integer firewall_group) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, virtual_ip, security_logging_object, route_table, firewall_group, null, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip, Integer security_logging_object, Integer route_table, Integer firewall_group, Integer firewall_policy) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, virtual_ip, security_logging_object, route_table, firewall_group, firewall_policy, null, 0); } + public QuotaType(Integer defaults, Integer floating_ip, Integer instance_ip, Integer virtual_machine_interface, Integer virtual_network, Integer virtual_router, Integer virtual_DNS, Integer virtual_DNS_record, Integer bgp_router, Integer network_ipam, Integer access_control_list, Integer network_policy, Integer floating_ip_pool, Integer service_template, Integer service_instance, Integer logical_router, Integer security_group, Integer security_group_rule, Integer subnet, Integer global_vrouter_config, Integer loadbalancer, Integer loadbalancer_listener, Integer loadbalancer_pool, Integer loadbalancer_member, Integer loadbalancer_healthmonitor, Integer virtual_ip, Integer security_logging_object, Integer route_table, Integer firewall_group, Integer firewall_policy, Integer firewall_rule) { + this(defaults, floating_ip, instance_ip, virtual_machine_interface, virtual_network, virtual_router, virtual_DNS, virtual_DNS_record, bgp_router, network_ipam, access_control_list, network_policy, floating_ip_pool, service_template, service_instance, logical_router, security_group, security_group_rule, subnet, global_vrouter_config, loadbalancer, loadbalancer_listener, loadbalancer_pool, loadbalancer_member, loadbalancer_healthmonitor, virtual_ip, security_logging_object, route_table, firewall_group, firewall_policy, firewall_rule, 0); } + + public Integer getDefaults() { + return defaults; + } + + public void setDefaults(Integer defaults) { + this.defaults = defaults; + } + + + public Integer getFloatingIp() { + return floating_ip; + } + + public void setFloatingIp(Integer floating_ip) { + this.floating_ip = floating_ip; + } + + + public Integer getInstanceIp() { + return instance_ip; + } + + public void setInstanceIp(Integer instance_ip) { + this.instance_ip = instance_ip; + } + + + public Integer getVirtualMachineInterface() { + return virtual_machine_interface; + } + + public void setVirtualMachineInterface(Integer virtual_machine_interface) { + this.virtual_machine_interface = virtual_machine_interface; + } + + + public Integer getVirtualNetwork() { + return virtual_network; + } + + public void setVirtualNetwork(Integer virtual_network) { + this.virtual_network = virtual_network; + } + + + public Integer getVirtualRouter() { + return virtual_router; + } + + public void setVirtualRouter(Integer virtual_router) { + this.virtual_router = virtual_router; + } + + + public Integer getVirtualDns() { + return virtual_DNS; + } + + public void setVirtualDns(Integer virtual_DNS) { + this.virtual_DNS = virtual_DNS; + } + + + public Integer getVirtualDnsRecord() { + return virtual_DNS_record; + } + + public void setVirtualDnsRecord(Integer virtual_DNS_record) { + this.virtual_DNS_record = virtual_DNS_record; + } + + + public Integer getBgpRouter() { + return bgp_router; + } + + public void setBgpRouter(Integer bgp_router) { + this.bgp_router = bgp_router; + } + + + public Integer getNetworkIpam() { + return network_ipam; + } + + public void setNetworkIpam(Integer network_ipam) { + this.network_ipam = network_ipam; + } + + + public Integer getAccessControlList() { + return access_control_list; + } + + public void setAccessControlList(Integer access_control_list) { + this.access_control_list = access_control_list; + } + + + public Integer getNetworkPolicy() { + return network_policy; + } + + public void setNetworkPolicy(Integer network_policy) { + this.network_policy = network_policy; + } + + + public Integer getFloatingIpPool() { + return floating_ip_pool; + } + + public void setFloatingIpPool(Integer floating_ip_pool) { + this.floating_ip_pool = floating_ip_pool; + } + + + public Integer getServiceTemplate() { + return service_template; + } + + public void setServiceTemplate(Integer service_template) { + this.service_template = service_template; + } + + + public Integer getServiceInstance() { + return service_instance; + } + + public void setServiceInstance(Integer service_instance) { + this.service_instance = service_instance; + } + + + public Integer getLogicalRouter() { + return logical_router; + } + + public void setLogicalRouter(Integer logical_router) { + this.logical_router = logical_router; + } + + + public Integer getSecurityGroup() { + return security_group; + } + + public void setSecurityGroup(Integer security_group) { + this.security_group = security_group; + } + + + public Integer getSecurityGroupRule() { + return security_group_rule; + } + + public void setSecurityGroupRule(Integer security_group_rule) { + this.security_group_rule = security_group_rule; + } + + + public Integer getSubnet() { + return subnet; + } + + public void setSubnet(Integer subnet) { + this.subnet = subnet; + } + + + public Integer getGlobalVrouterConfig() { + return global_vrouter_config; + } + + public void setGlobalVrouterConfig(Integer global_vrouter_config) { + this.global_vrouter_config = global_vrouter_config; + } + + + public Integer getLoadbalancer() { + return loadbalancer; + } + + public void setLoadbalancer(Integer loadbalancer) { + this.loadbalancer = loadbalancer; + } + + + public Integer getLoadbalancerListener() { + return loadbalancer_listener; + } + + public void setLoadbalancerListener(Integer loadbalancer_listener) { + this.loadbalancer_listener = loadbalancer_listener; + } + + + public Integer getLoadbalancerPool() { + return loadbalancer_pool; + } + + public void setLoadbalancerPool(Integer loadbalancer_pool) { + this.loadbalancer_pool = loadbalancer_pool; + } + + + public Integer getLoadbalancerMember() { + return loadbalancer_member; + } + + public void setLoadbalancerMember(Integer loadbalancer_member) { + this.loadbalancer_member = loadbalancer_member; + } + + + public Integer getLoadbalancerHealthmonitor() { + return loadbalancer_healthmonitor; + } + + public void setLoadbalancerHealthmonitor(Integer loadbalancer_healthmonitor) { + this.loadbalancer_healthmonitor = loadbalancer_healthmonitor; + } + + + public Integer getVirtualIp() { + return virtual_ip; + } + + public void setVirtualIp(Integer virtual_ip) { + this.virtual_ip = virtual_ip; + } + + + public Integer getSecurityLoggingObject() { + return security_logging_object; + } + + public void setSecurityLoggingObject(Integer security_logging_object) { + this.security_logging_object = security_logging_object; + } + + + public Integer getRouteTable() { + return route_table; + } + + public void setRouteTable(Integer route_table) { + this.route_table = route_table; + } + + + public Integer getFirewallGroup() { + return firewall_group; + } + + public void setFirewallGroup(Integer firewall_group) { + this.firewall_group = firewall_group; + } + + + public Integer getFirewallPolicy() { + return firewall_policy; + } + + public void setFirewallPolicy(Integer firewall_policy) { + this.firewall_policy = firewall_policy; + } + + + public Integer getFirewallRule() { + return firewall_rule; + } + + public void setFirewallRule(Integer firewall_rule) { + this.firewall_rule = firewall_rule; + } + + + public Integer getHostBasedService() { + return host_based_service; + } + + public void setHostBasedService(Integer host_based_service) { + this.host_based_service = host_based_service; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacPermType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacPermType.java new file mode 100644 index 00000000000..b0bf50da0b8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacPermType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RbacPermType extends ApiPropertyBase { + String role_name; + String role_crud; + public RbacPermType() { + } + public RbacPermType(String role_name, String role_crud) { + this.role_name = role_name; + this.role_crud = role_crud; + } + public RbacPermType(String role_name) { + this(role_name, null); } + + public String getRoleName() { + return role_name; + } + + public void setRoleName(String role_name) { + this.role_name = role_name; + } + + + public String getRoleCrud() { + return role_crud; + } + + public void setRoleCrud(String role_crud) { + this.role_crud = role_crud; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacRuleEntriesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacRuleEntriesType.java new file mode 100644 index 00000000000..a7773f6e120 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacRuleEntriesType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RbacRuleEntriesType extends ApiPropertyBase { + List rbac_rule; + public RbacRuleEntriesType() { + } + public RbacRuleEntriesType(List rbac_rule) { + this.rbac_rule = rbac_rule; + } + + public List getRbacRule() { + return rbac_rule; + } + + + public void addRbacRule(RbacRuleType obj) { + if (rbac_rule == null) { + rbac_rule = new ArrayList(); + } + rbac_rule.add(obj); + } + public void clearRbacRule() { + rbac_rule = null; + } + + + public void addRbacRule(String rule_object, String rule_field, List rule_perms) { + if (rbac_rule == null) { + rbac_rule = new ArrayList(); + } + rbac_rule.add(new RbacRuleType(rule_object, rule_field, rule_perms)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacRuleType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacRuleType.java new file mode 100644 index 00000000000..ddc8f7e8224 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RbacRuleType.java @@ -0,0 +1,68 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RbacRuleType extends ApiPropertyBase { + String rule_object; + String rule_field; + List rule_perms; + public RbacRuleType() { + } + public RbacRuleType(String rule_object, String rule_field, List rule_perms) { + this.rule_object = rule_object; + this.rule_field = rule_field; + this.rule_perms = rule_perms; + } + public RbacRuleType(String rule_object) { + this(rule_object, null, null); } + public RbacRuleType(String rule_object, String rule_field) { + this(rule_object, rule_field, null); } + + public String getRuleObject() { + return rule_object; + } + + public void setRuleObject(String rule_object) { + this.rule_object = rule_object; + } + + + public String getRuleField() { + return rule_field; + } + + public void setRuleField(String rule_field) { + this.rule_field = rule_field; + } + + + public List getRulePerms() { + return rule_perms; + } + + + public void addRulePerms(RbacPermType obj) { + if (rule_perms == null) { + rule_perms = new ArrayList(); + } + rule_perms.add(obj); + } + public void clearRulePerms() { + rule_perms = null; + } + + + public void addRulePerms(String role_name, String role_crud) { + if (rule_perms == null) { + rule_perms = new ArrayList(); + } + rule_perms.add(new RbacPermType(role_name, role_crud)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoleConfig.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoleConfig.java new file mode 100644 index 00000000000..a369744c90e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoleConfig.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RoleConfig extends ApiObjectBase { + private String role_config_config; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "role-config"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-node-profile"); + } + + @Override + public String getDefaultParentType() { + return "node-profile"; + } + + public void setParent(NodeProfile parent) { + super.setParent(parent); + } + + public String getConfig() { + return role_config_config; + } + + public void setConfig(String role_config_config) { + this.role_config_config = role_config_config; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoleDefinition.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoleDefinition.java new file mode 100644 index 00000000000..953b5bff68c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoleDefinition.java @@ -0,0 +1,208 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RoleDefinition extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> feature_refs; + private List> physical_role_refs; + private List> overlay_role_refs; + private List> feature_configs; + private List> tag_refs; + private transient List> node_profile_back_refs; + + @Override + public String getObjectType() { + return "role-definition"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getFeature() { + return feature_refs; + } + + public void setFeature(Feature obj) { + feature_refs = new ArrayList>(); + feature_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addFeature(Feature obj) { + if (feature_refs == null) { + feature_refs = new ArrayList>(); + } + feature_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeFeature(Feature obj) { + if (feature_refs != null) { + feature_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearFeature() { + if (feature_refs != null) { + feature_refs.clear(); + return; + } + feature_refs = null; + } + + public List> getPhysicalRole() { + return physical_role_refs; + } + + public void setPhysicalRole(PhysicalRole obj) { + physical_role_refs = new ArrayList>(); + physical_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRole(PhysicalRole obj) { + if (physical_role_refs == null) { + physical_role_refs = new ArrayList>(); + } + physical_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRole(PhysicalRole obj) { + if (physical_role_refs != null) { + physical_role_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRole() { + if (physical_role_refs != null) { + physical_role_refs.clear(); + return; + } + physical_role_refs = null; + } + + public List> getOverlayRole() { + return overlay_role_refs; + } + + public void setOverlayRole(OverlayRole obj) { + overlay_role_refs = new ArrayList>(); + overlay_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addOverlayRole(OverlayRole obj) { + if (overlay_role_refs == null) { + overlay_role_refs = new ArrayList>(); + } + overlay_role_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeOverlayRole(OverlayRole obj) { + if (overlay_role_refs != null) { + overlay_role_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearOverlayRole() { + if (overlay_role_refs != null) { + overlay_role_refs.clear(); + return; + } + overlay_role_refs = null; + } + + public List> getFeatureConfigs() { + return feature_configs; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getNodeProfileBackRefs() { + return node_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteAggregate.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteAggregate.java new file mode 100644 index 00000000000..ec19b572564 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteAggregate.java @@ -0,0 +1,137 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RouteAggregate extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_instance_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "route-aggregate"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTable.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTable.java new file mode 100644 index 00000000000..5de1a98eff7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTable.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RouteTable extends ApiObjectBase { + private RouteTableType routes; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> virtual_network_back_refs; + private transient List> logical_router_back_refs; + + @Override + public String getObjectType() { + return "route-table"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public RouteTableType getRoutes() { + return routes; + } + + public void setRoutes(RouteTableType routes) { + this.routes = routes; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTableType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTableType.java new file mode 100644 index 00000000000..ee5cf1e31e7 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTableType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RouteTableType extends ApiPropertyBase { + List route; + public RouteTableType() { + } + public RouteTableType(List route) { + this.route = route; + } + + public List getRoute() { + return route; + } + + + public void addRoute(RouteType obj) { + if (route == null) { + route = new ArrayList(); + } + route.add(obj); + } + public void clearRoute() { + route = null; + } + + + public void addRoute(String prefix, String next_hop, String next_hop_type, CommunityAttributes community_attributes) { + if (route == null) { + route = new ArrayList(); + } + route.add(new RouteType(prefix, next_hop, next_hop_type, community_attributes)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTarget.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTarget.java new file mode 100644 index 00000000000..146c0898d1e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTarget.java @@ -0,0 +1,106 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RouteTarget extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> logical_router_back_refs; + + @Override + public String getObjectType() { + return "route-target"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTargetList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTargetList.java new file mode 100644 index 00000000000..7d35e60f351 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteTargetList.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RouteTargetList extends ApiPropertyBase { + List route_target; + public RouteTargetList() { + } + public RouteTargetList(List route_target) { + this.route_target = route_target; + } + + public List getRouteTarget() { + return route_target; + } + + + public void addRouteTarget(String obj) { + if (route_target == null) { + route_target = new ArrayList(); + } + route_target.add(obj); + } + public void clearRouteTarget() { + route_target = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteType.java new file mode 100644 index 00000000000..624b2fb846d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RouteType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RouteType extends ApiPropertyBase { + String prefix; + String next_hop; + String next_hop_type; + CommunityAttributes community_attributes; + public RouteType() { + } + public RouteType(String prefix, String next_hop, String next_hop_type, CommunityAttributes community_attributes) { + this.prefix = prefix; + this.next_hop = next_hop; + this.next_hop_type = next_hop_type; + this.community_attributes = community_attributes; + } + public RouteType(String prefix) { + this(prefix, null, null, null); } + public RouteType(String prefix, String next_hop) { + this(prefix, next_hop, null, null); } + public RouteType(String prefix, String next_hop, String next_hop_type) { + this(prefix, next_hop, next_hop_type, null); } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + + public String getNextHop() { + return next_hop; + } + + public void setNextHop(String next_hop) { + this.next_hop = next_hop; + } + + + public String getNextHopType() { + return next_hop_type; + } + + public void setNextHopType(String next_hop_type) { + this.next_hop_type = next_hop_type; + } + + + public CommunityAttributes getCommunityAttributes() { + return community_attributes; + } + + public void setCommunityAttributes(CommunityAttributes community_attributes) { + this.community_attributes = community_attributes; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutedProperties.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutedProperties.java new file mode 100644 index 00000000000..884afb581ad --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutedProperties.java @@ -0,0 +1,154 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RoutedProperties extends ApiPropertyBase { + String physical_router_uuid; + String logical_router_uuid; + String routed_interface_ip_address; + String loopback_ip_address; + String routing_protocol; + BgpParameters bgp_params; + OspfParameters ospf_params; + PimParameters pim_params; + StaticRouteParameters static_route_params; + BfdParameters bfd_params; + RoutingPolicyParameters routing_policy_params; + public RoutedProperties() { + } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol, BgpParameters bgp_params, OspfParameters ospf_params, PimParameters pim_params, StaticRouteParameters static_route_params, BfdParameters bfd_params, RoutingPolicyParameters routing_policy_params) { + this.physical_router_uuid = physical_router_uuid; + this.logical_router_uuid = logical_router_uuid; + this.routed_interface_ip_address = routed_interface_ip_address; + this.loopback_ip_address = loopback_ip_address; + this.routing_protocol = routing_protocol; + this.bgp_params = bgp_params; + this.ospf_params = ospf_params; + this.pim_params = pim_params; + this.static_route_params = static_route_params; + this.bfd_params = bfd_params; + this.routing_policy_params = routing_policy_params; + } + public RoutedProperties(String physical_router_uuid) { + this(physical_router_uuid, null, null, null, null, null, null, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid) { + this(physical_router_uuid, logical_router_uuid, null, null, null, null, null, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, null, null, null, null, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, null, null, null, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, routing_protocol, null, null, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol, BgpParameters bgp_params) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, routing_protocol, bgp_params, null, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol, BgpParameters bgp_params, OspfParameters ospf_params) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, routing_protocol, bgp_params, ospf_params, null, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol, BgpParameters bgp_params, OspfParameters ospf_params, PimParameters pim_params) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, routing_protocol, bgp_params, ospf_params, pim_params, null, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol, BgpParameters bgp_params, OspfParameters ospf_params, PimParameters pim_params, StaticRouteParameters static_route_params) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, routing_protocol, bgp_params, ospf_params, pim_params, static_route_params, null, null); } + public RoutedProperties(String physical_router_uuid, String logical_router_uuid, String routed_interface_ip_address, String loopback_ip_address, String routing_protocol, BgpParameters bgp_params, OspfParameters ospf_params, PimParameters pim_params, StaticRouteParameters static_route_params, BfdParameters bfd_params) { + this(physical_router_uuid, logical_router_uuid, routed_interface_ip_address, loopback_ip_address, routing_protocol, bgp_params, ospf_params, pim_params, static_route_params, bfd_params, null); } + + public String getPhysicalRouterUuid() { + return physical_router_uuid; + } + + public void setPhysicalRouterUuid(String physical_router_uuid) { + this.physical_router_uuid = physical_router_uuid; + } + + + public String getLogicalRouterUuid() { + return logical_router_uuid; + } + + public void setLogicalRouterUuid(String logical_router_uuid) { + this.logical_router_uuid = logical_router_uuid; + } + + + public String getRoutedInterfaceIpAddress() { + return routed_interface_ip_address; + } + + public void setRoutedInterfaceIpAddress(String routed_interface_ip_address) { + this.routed_interface_ip_address = routed_interface_ip_address; + } + + + public String getLoopbackIpAddress() { + return loopback_ip_address; + } + + public void setLoopbackIpAddress(String loopback_ip_address) { + this.loopback_ip_address = loopback_ip_address; + } + + + public String getRoutingProtocol() { + return routing_protocol; + } + + public void setRoutingProtocol(String routing_protocol) { + this.routing_protocol = routing_protocol; + } + + + public BgpParameters getBgpParams() { + return bgp_params; + } + + public void setBgpParams(BgpParameters bgp_params) { + this.bgp_params = bgp_params; + } + + + public OspfParameters getOspfParams() { + return ospf_params; + } + + public void setOspfParams(OspfParameters ospf_params) { + this.ospf_params = ospf_params; + } + + + public PimParameters getPimParams() { + return pim_params; + } + + public void setPimParams(PimParameters pim_params) { + this.pim_params = pim_params; + } + + + public StaticRouteParameters getStaticRouteParams() { + return static_route_params; + } + + public void setStaticRouteParams(StaticRouteParameters static_route_params) { + this.static_route_params = static_route_params; + } + + + public BfdParameters getBfdParams() { + return bfd_params; + } + + public void setBfdParams(BfdParameters bfd_params) { + this.bfd_params = bfd_params; + } + + + public RoutingPolicyParameters getRoutingPolicyParams() { + return routing_policy_params; + } + + public void setRoutingPolicyParams(RoutingPolicyParameters routing_policy_params) { + this.routing_policy_params = routing_policy_params; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingBridgingRolesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingBridgingRolesType.java new file mode 100644 index 00000000000..ca324ce829a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingBridgingRolesType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RoutingBridgingRolesType extends ApiPropertyBase { + List rb_roles; + public RoutingBridgingRolesType() { + } + public RoutingBridgingRolesType(List rb_roles) { + this.rb_roles = rb_roles; + } + + public List getRbRoles() { + return rb_roles; + } + + + public void addRbRoles(String obj) { + if (rb_roles == null) { + rb_roles = new ArrayList(); + } + rb_roles.add(obj); + } + public void clearRbRoles() { + rb_roles = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingInstance.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingInstance.java new file mode 100644 index 00000000000..b580ab974f5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingInstance.java @@ -0,0 +1,110 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RoutingInstance extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "routing-instance"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project", "default-virtual-network"); + } + + @Override + public String getDefaultParentType() { + return "virtual-network"; + } + + public void setParent(VirtualNetwork parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicy.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicy.java new file mode 100644 index 00000000000..8a8f7935212 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicy.java @@ -0,0 +1,173 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class RoutingPolicy extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> interface_route_table_refs; + private List> service_instance_refs; + private List> tag_refs; + private transient List> data_center_interconnect_back_refs; + + @Override + public String getObjectType() { + return "routing-policy"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getInterfaceRouteTable() { + return interface_route_table_refs; + } + + public void setInterfaceRouteTable(InterfaceRouteTable obj) { + interface_route_table_refs = new ArrayList>(); + interface_route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addInterfaceRouteTable(InterfaceRouteTable obj) { + if (interface_route_table_refs == null) { + interface_route_table_refs = new ArrayList>(); + } + interface_route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeInterfaceRouteTable(InterfaceRouteTable obj) { + if (interface_route_table_refs != null) { + interface_route_table_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearInterfaceRouteTable() { + if (interface_route_table_refs != null) { + interface_route_table_refs.clear(); + return; + } + interface_route_table_refs = null; + } + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj, RoutingPolicyServiceInstanceType data) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addServiceInstance(ServiceInstance obj, RoutingPolicyServiceInstanceType data) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeServiceInstance(ServiceInstance obj, RoutingPolicyServiceInstanceType data) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getDataCenterInterconnectBackRefs() { + return data_center_interconnect_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicyParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicyParameters.java new file mode 100644 index 00000000000..dec8f80f275 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicyParameters.java @@ -0,0 +1,54 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RoutingPolicyParameters extends ApiPropertyBase { + List import_routing_policy_uuid; + List export_routing_policy_uuid; + public RoutingPolicyParameters() { + } + public RoutingPolicyParameters(List import_routing_policy_uuid, List export_routing_policy_uuid) { + this.import_routing_policy_uuid = import_routing_policy_uuid; + this.export_routing_policy_uuid = export_routing_policy_uuid; + } + public RoutingPolicyParameters(List import_routing_policy_uuid) { + this(import_routing_policy_uuid, null); } + + public List getImportRoutingPolicyUuid() { + return import_routing_policy_uuid; + } + + + public void addImportRoutingPolicyUuid(String obj) { + if (import_routing_policy_uuid == null) { + import_routing_policy_uuid = new ArrayList(); + } + import_routing_policy_uuid.add(obj); + } + public void clearImportRoutingPolicyUuid() { + import_routing_policy_uuid = null; + } + + + public List getExportRoutingPolicyUuid() { + return export_routing_policy_uuid; + } + + + public void addExportRoutingPolicyUuid(String obj) { + if (export_routing_policy_uuid == null) { + export_routing_policy_uuid = new ArrayList(); + } + export_routing_policy_uuid.add(obj); + } + public void clearExportRoutingPolicyUuid() { + export_routing_policy_uuid = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicyServiceInstanceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicyServiceInstanceType.java new file mode 100644 index 00000000000..7d285da88ad --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/RoutingPolicyServiceInstanceType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class RoutingPolicyServiceInstanceType extends ApiPropertyBase { + String left_sequence; + String right_sequence; + public RoutingPolicyServiceInstanceType() { + } + public RoutingPolicyServiceInstanceType(String left_sequence, String right_sequence) { + this.left_sequence = left_sequence; + this.right_sequence = right_sequence; + } + public RoutingPolicyServiceInstanceType(String left_sequence) { + this(left_sequence, null); } + + public String getLeftSequence() { + return left_sequence; + } + + public void setLeftSequence(String left_sequence) { + this.left_sequence = left_sequence; + } + + + public String getRightSequence() { + return right_sequence; + } + + public void setRightSequence(String right_sequence) { + this.right_sequence = right_sequence; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SNMPCredentials.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SNMPCredentials.java new file mode 100644 index 00000000000..4b9c25de3a1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SNMPCredentials.java @@ -0,0 +1,232 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SNMPCredentials extends ApiPropertyBase { + Integer version; + Integer local_port; + Integer retries; + Integer timeout; + String v2_community; + String v3_security_name; + String v3_security_level; + String v3_security_engine_id; + String v3_context; + String v3_context_engine_id; + String v3_authentication_protocol; + String v3_authentication_password; + String v3_privacy_protocol; + String v3_privacy_password; + String v3_engine_id; + Integer v3_engine_boots; + Integer v3_engine_time; + public SNMPCredentials() { + } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol, String v3_authentication_password, String v3_privacy_protocol, String v3_privacy_password, String v3_engine_id, Integer v3_engine_boots, Integer v3_engine_time) { + this.version = version; + this.local_port = local_port; + this.retries = retries; + this.timeout = timeout; + this.v2_community = v2_community; + this.v3_security_name = v3_security_name; + this.v3_security_level = v3_security_level; + this.v3_security_engine_id = v3_security_engine_id; + this.v3_context = v3_context; + this.v3_context_engine_id = v3_context_engine_id; + this.v3_authentication_protocol = v3_authentication_protocol; + this.v3_authentication_password = v3_authentication_password; + this.v3_privacy_protocol = v3_privacy_protocol; + this.v3_privacy_password = v3_privacy_password; + this.v3_engine_id = v3_engine_id; + this.v3_engine_boots = v3_engine_boots; + this.v3_engine_time = v3_engine_time; + } + public SNMPCredentials(Integer version) { + this(version, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port) { + this(version, local_port, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries) { + this(version, local_port, retries, null, null, null, null, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout) { + this(version, local_port, retries, timeout, null, null, null, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community) { + this(version, local_port, retries, timeout, v2_community, null, null, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, null, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, null, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, null, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, null, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, null, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, v3_authentication_protocol, null, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol, String v3_authentication_password) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, v3_authentication_protocol, v3_authentication_password, null, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol, String v3_authentication_password, String v3_privacy_protocol) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, v3_authentication_protocol, v3_authentication_password, v3_privacy_protocol, null, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol, String v3_authentication_password, String v3_privacy_protocol, String v3_privacy_password) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, v3_authentication_protocol, v3_authentication_password, v3_privacy_protocol, v3_privacy_password, null, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol, String v3_authentication_password, String v3_privacy_protocol, String v3_privacy_password, String v3_engine_id) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, v3_authentication_protocol, v3_authentication_password, v3_privacy_protocol, v3_privacy_password, v3_engine_id, null, null); } + public SNMPCredentials(Integer version, Integer local_port, Integer retries, Integer timeout, String v2_community, String v3_security_name, String v3_security_level, String v3_security_engine_id, String v3_context, String v3_context_engine_id, String v3_authentication_protocol, String v3_authentication_password, String v3_privacy_protocol, String v3_privacy_password, String v3_engine_id, Integer v3_engine_boots) { + this(version, local_port, retries, timeout, v2_community, v3_security_name, v3_security_level, v3_security_engine_id, v3_context, v3_context_engine_id, v3_authentication_protocol, v3_authentication_password, v3_privacy_protocol, v3_privacy_password, v3_engine_id, v3_engine_boots, null); } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + + public Integer getLocalPort() { + return local_port; + } + + public void setLocalPort(Integer local_port) { + this.local_port = local_port; + } + + + public Integer getRetries() { + return retries; + } + + public void setRetries(Integer retries) { + this.retries = retries; + } + + + public Integer getTimeout() { + return timeout; + } + + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } + + + public String getV2Community() { + return v2_community; + } + + public void setV2Community(String v2_community) { + this.v2_community = v2_community; + } + + + public String getV3SecurityName() { + return v3_security_name; + } + + public void setV3SecurityName(String v3_security_name) { + this.v3_security_name = v3_security_name; + } + + + public String getV3SecurityLevel() { + return v3_security_level; + } + + public void setV3SecurityLevel(String v3_security_level) { + this.v3_security_level = v3_security_level; + } + + + public String getV3SecurityEngineId() { + return v3_security_engine_id; + } + + public void setV3SecurityEngineId(String v3_security_engine_id) { + this.v3_security_engine_id = v3_security_engine_id; + } + + + public String getV3Context() { + return v3_context; + } + + public void setV3Context(String v3_context) { + this.v3_context = v3_context; + } + + + public String getV3ContextEngineId() { + return v3_context_engine_id; + } + + public void setV3ContextEngineId(String v3_context_engine_id) { + this.v3_context_engine_id = v3_context_engine_id; + } + + + public String getV3AuthenticationProtocol() { + return v3_authentication_protocol; + } + + public void setV3AuthenticationProtocol(String v3_authentication_protocol) { + this.v3_authentication_protocol = v3_authentication_protocol; + } + + + public String getV3AuthenticationPassword() { + return v3_authentication_password; + } + + public void setV3AuthenticationPassword(String v3_authentication_password) { + this.v3_authentication_password = v3_authentication_password; + } + + + public String getV3PrivacyProtocol() { + return v3_privacy_protocol; + } + + public void setV3PrivacyProtocol(String v3_privacy_protocol) { + this.v3_privacy_protocol = v3_privacy_protocol; + } + + + public String getV3PrivacyPassword() { + return v3_privacy_password; + } + + public void setV3PrivacyPassword(String v3_privacy_password) { + this.v3_privacy_password = v3_privacy_password; + } + + + public String getV3EngineId() { + return v3_engine_id; + } + + public void setV3EngineId(String v3_engine_id) { + this.v3_engine_id = v3_engine_id; + } + + + public Integer getV3EngineBoots() { + return v3_engine_boots; + } + + public void setV3EngineBoots(Integer v3_engine_boots) { + this.v3_engine_boots = v3_engine_boots; + } + + + public Integer getV3EngineTime() { + return v3_engine_time; + } + + public void setV3EngineTime(Integer v3_engine_time) { + this.v3_engine_time = v3_engine_time; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityGroup.java new file mode 100644 index 00000000000..2c4f3847208 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityGroup.java @@ -0,0 +1,155 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class SecurityGroup extends ApiObjectBase { + private Integer security_group_id; + private Integer configured_security_group_id; + private PolicyEntriesType security_group_entries; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> access_control_lists; + private List> tag_refs; + private transient List> security_logging_object_back_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> virtual_port_group_back_refs; + + @Override + public String getObjectType() { + return "security-group"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Integer getId() { + return security_group_id; + } + + public void setId(Integer security_group_id) { + this.security_group_id = security_group_id; + } + + + public Integer getConfiguredSecurityGroupId() { + return configured_security_group_id; + } + + public void setConfiguredSecurityGroupId(Integer configured_security_group_id) { + this.configured_security_group_id = configured_security_group_id; + } + + + public PolicyEntriesType getEntries() { + return security_group_entries; + } + + public void setEntries(PolicyEntriesType security_group_entries) { + this.security_group_entries = security_group_entries; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getAccessControlLists() { + return access_control_lists; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getSecurityLoggingObjectBackRefs() { + return security_logging_object_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getVirtualPortGroupBackRefs() { + return virtual_port_group_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObject.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObject.java new file mode 100644 index 00000000000..1620e038ef9 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObject.java @@ -0,0 +1,212 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class SecurityLoggingObject extends ApiObjectBase { + private SecurityLoggingObjectRuleListType security_logging_object_rules; + private Integer security_logging_object_rate; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> network_policy_refs; + private List> security_group_refs; + private List> tag_refs; + private transient List> virtual_network_back_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> firewall_policy_back_refs; + private transient List> firewall_rule_back_refs; + + @Override + public String getObjectType() { + return "security-logging-object"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(GlobalVrouterConfig parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public SecurityLoggingObjectRuleListType getRules() { + return security_logging_object_rules; + } + + public void setRules(SecurityLoggingObjectRuleListType security_logging_object_rules) { + this.security_logging_object_rules = security_logging_object_rules; + } + + + public Integer getRate() { + return security_logging_object_rate; + } + + public void setRate(Integer security_logging_object_rate) { + this.security_logging_object_rate = security_logging_object_rate; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getNetworkPolicy() { + return network_policy_refs; + } + + public void setNetworkPolicy(NetworkPolicy obj, SecurityLoggingObjectRuleListType data) { + network_policy_refs = new ArrayList>(); + network_policy_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addNetworkPolicy(NetworkPolicy obj, SecurityLoggingObjectRuleListType data) { + if (network_policy_refs == null) { + network_policy_refs = new ArrayList>(); + } + network_policy_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeNetworkPolicy(NetworkPolicy obj, SecurityLoggingObjectRuleListType data) { + if (network_policy_refs != null) { + network_policy_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearNetworkPolicy() { + if (network_policy_refs != null) { + network_policy_refs.clear(); + return; + } + network_policy_refs = null; + } + + + public List> getSecurityGroup() { + return security_group_refs; + } + + public void setSecurityGroup(SecurityGroup obj, SecurityLoggingObjectRuleListType data) { + security_group_refs = new ArrayList>(); + security_group_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addSecurityGroup(SecurityGroup obj, SecurityLoggingObjectRuleListType data) { + if (security_group_refs == null) { + security_group_refs = new ArrayList>(); + } + security_group_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeSecurityGroup(SecurityGroup obj, SecurityLoggingObjectRuleListType data) { + if (security_group_refs != null) { + security_group_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearSecurityGroup() { + if (security_group_refs != null) { + security_group_refs.clear(); + return; + } + security_group_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getFirewallPolicyBackRefs() { + return firewall_policy_back_refs; + } + + public List> getFirewallRuleBackRefs() { + return firewall_rule_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObjectRuleEntryType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObjectRuleEntryType.java new file mode 100644 index 00000000000..8459dfa8bad --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObjectRuleEntryType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SecurityLoggingObjectRuleEntryType extends ApiPropertyBase { + String rule_uuid; + Integer rate; + public SecurityLoggingObjectRuleEntryType() { + } + public SecurityLoggingObjectRuleEntryType(String rule_uuid, Integer rate) { + this.rule_uuid = rule_uuid; + this.rate = rate; + } + public SecurityLoggingObjectRuleEntryType(String rule_uuid) { + this(rule_uuid, 100); } + + public String getRuleUuid() { + return rule_uuid; + } + + public void setRuleUuid(String rule_uuid) { + this.rule_uuid = rule_uuid; + } + + + public Integer getRate() { + return rate; + } + + public void setRate(Integer rate) { + this.rate = rate; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObjectRuleListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObjectRuleListType.java new file mode 100644 index 00000000000..3a8ccbf2d4f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SecurityLoggingObjectRuleListType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SecurityLoggingObjectRuleListType extends ApiPropertyBase { + List rule; + public SecurityLoggingObjectRuleListType() { + } + public SecurityLoggingObjectRuleListType(List rule) { + this.rule = rule; + } + + public List getRule() { + return rule; + } + + + public void addRule(SecurityLoggingObjectRuleEntryType obj) { + if (rule == null) { + rule = new ArrayList(); + } + rule.add(obj); + } + public void clearRule() { + rule = null; + } + + + public void addRule(String rule_uuid, Integer rate) { + if (rule == null) { + rule = new ArrayList(); + } + rule.add(new SecurityLoggingObjectRuleEntryType(rule_uuid, rate)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SequenceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SequenceType.java new file mode 100644 index 00000000000..a3c3a90fb57 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SequenceType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SequenceType extends ApiPropertyBase { + Integer major; + Integer minor; + public SequenceType() { + } + public SequenceType(Integer major, Integer minor) { + this.major = major; + this.minor = minor; + } + public SequenceType(Integer major) { + this(major, null); } + + public Integer getMajor() { + return major; + } + + public void setMajor(Integer major) { + this.major = major; + } + + + public Integer getMinor() { + return minor; + } + + public void setMinor(Integer minor) { + this.minor = minor; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SerialNumListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SerialNumListType.java new file mode 100644 index 00000000000..f88c5629d2c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SerialNumListType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SerialNumListType extends ApiPropertyBase { + List serial_num; + public SerialNumListType() { + } + public SerialNumListType(List serial_num) { + this.serial_num = serial_num; + } + + public List getSerialNum() { + return serial_num; + } + + + public void addSerialNum(String obj) { + if (serial_num == null) { + serial_num = new ArrayList(); + } + serial_num.add(obj); + } + public void clearSerialNum() { + serial_num = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceAppliance.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceAppliance.java new file mode 100644 index 00000000000..74499001c0b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceAppliance.java @@ -0,0 +1,177 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceAppliance extends ApiObjectBase { + private UserCredentials service_appliance_user_credentials; + private String service_appliance_ip_address; + private String service_appliance_virtualization_type; + private KeyValuePairs service_appliance_properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> physical_interface_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "service-appliance"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config", "default-service-appliance-set"); + } + + @Override + public String getDefaultParentType() { + return "service-appliance-set"; + } + + public void setParent(ServiceApplianceSet parent) { + super.setParent(parent); + } + + public UserCredentials getUserCredentials() { + return service_appliance_user_credentials; + } + + public void setUserCredentials(UserCredentials service_appliance_user_credentials) { + this.service_appliance_user_credentials = service_appliance_user_credentials; + } + + + public String getIpAddress() { + return service_appliance_ip_address; + } + + public void setIpAddress(String service_appliance_ip_address) { + this.service_appliance_ip_address = service_appliance_ip_address; + } + + + public String getVirtualizationType() { + return service_appliance_virtualization_type; + } + + public void setVirtualizationType(String service_appliance_virtualization_type) { + this.service_appliance_virtualization_type = service_appliance_virtualization_type; + } + + + public KeyValuePairs getProperties() { + return service_appliance_properties; + } + + public void setProperties(KeyValuePairs service_appliance_properties) { + this.service_appliance_properties = service_appliance_properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPhysicalInterface() { + return physical_interface_refs; + } + + public void setPhysicalInterface(PhysicalInterface obj, ServiceApplianceInterfaceType data) { + physical_interface_refs = new ArrayList>(); + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addPhysicalInterface(PhysicalInterface obj, ServiceApplianceInterfaceType data) { + if (physical_interface_refs == null) { + physical_interface_refs = new ArrayList>(); + } + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removePhysicalInterface(PhysicalInterface obj, ServiceApplianceInterfaceType data) { + if (physical_interface_refs != null) { + physical_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearPhysicalInterface() { + if (physical_interface_refs != null) { + physical_interface_refs.clear(); + return; + } + physical_interface_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceApplianceInterfaceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceApplianceInterfaceType.java new file mode 100644 index 00000000000..4a7e50a3cda --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceApplianceInterfaceType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceApplianceInterfaceType extends ApiPropertyBase { + String interface_type; + public ServiceApplianceInterfaceType() { + } + public ServiceApplianceInterfaceType(String interface_type) { + this.interface_type = interface_type; + } + + public String getInterfaceType() { + return interface_type; + } + + public void setInterfaceType(String interface_type) { + this.interface_type = interface_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceApplianceSet.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceApplianceSet.java new file mode 100644 index 00000000000..508a07ef23e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceApplianceSet.java @@ -0,0 +1,165 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceApplianceSet extends ApiObjectBase { + private String service_appliance_set_virtualization_type; + private KeyValuePairs service_appliance_set_properties; + private String service_appliance_driver; + private String service_appliance_ha_mode; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_appliances; + private List> tag_refs; + private transient List> service_template_back_refs; + private transient List> loadbalancer_pool_back_refs; + private transient List> loadbalancer_back_refs; + + @Override + public String getObjectType() { + return "service-appliance-set"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getVirtualizationType() { + return service_appliance_set_virtualization_type; + } + + public void setVirtualizationType(String service_appliance_set_virtualization_type) { + this.service_appliance_set_virtualization_type = service_appliance_set_virtualization_type; + } + + + public KeyValuePairs getProperties() { + return service_appliance_set_properties; + } + + public void setProperties(KeyValuePairs service_appliance_set_properties) { + this.service_appliance_set_properties = service_appliance_set_properties; + } + + + public String getServiceApplianceDriver() { + return service_appliance_driver; + } + + public void setServiceApplianceDriver(String service_appliance_driver) { + this.service_appliance_driver = service_appliance_driver; + } + + + public String getServiceApplianceHaMode() { + return service_appliance_ha_mode; + } + + public void setServiceApplianceHaMode(String service_appliance_ha_mode) { + this.service_appliance_ha_mode = service_appliance_ha_mode; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceAppliances() { + return service_appliances; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceTemplateBackRefs() { + return service_template_back_refs; + } + + public List> getLoadbalancerPoolBackRefs() { + return loadbalancer_pool_back_refs; + } + + public List> getLoadbalancerBackRefs() { + return loadbalancer_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceConnectionModule.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceConnectionModule.java new file mode 100644 index 00000000000..6078d7e75b2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceConnectionModule.java @@ -0,0 +1,157 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceConnectionModule extends ApiObjectBase { + private String e2_service; + private String service_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_object_refs; + private List> tag_refs; + private transient List> service_endpoint_back_refs; + + @Override + public String getObjectType() { + return "service-connection-module"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public String getE2Service() { + return e2_service; + } + + public void setE2Service(String e2_service) { + this.e2_service = e2_service; + } + + + public String getServiceType() { + return service_type; + } + + public void setServiceType(String service_type) { + this.service_type = service_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceObject() { + return service_object_refs; + } + + public void setServiceObject(ServiceObject obj) { + service_object_refs = new ArrayList>(); + service_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceObject(ServiceObject obj) { + if (service_object_refs == null) { + service_object_refs = new ArrayList>(); + } + service_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceObject(ServiceObject obj) { + if (service_object_refs != null) { + service_object_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceObject() { + if (service_object_refs != null) { + service_object_refs.clear(); + return; + } + service_object_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceEndpointBackRefs() { + return service_endpoint_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceEndpoint.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceEndpoint.java new file mode 100644 index 00000000000..0b5917fbcc2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceEndpoint.java @@ -0,0 +1,199 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceEndpoint extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_connection_module_refs; + private List> physical_router_refs; + private List> service_object_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "service-endpoint"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceConnectionModule() { + return service_connection_module_refs; + } + + public void setServiceConnectionModule(ServiceConnectionModule obj) { + service_connection_module_refs = new ArrayList>(); + service_connection_module_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceConnectionModule(ServiceConnectionModule obj) { + if (service_connection_module_refs == null) { + service_connection_module_refs = new ArrayList>(); + } + service_connection_module_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceConnectionModule(ServiceConnectionModule obj) { + if (service_connection_module_refs != null) { + service_connection_module_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceConnectionModule() { + if (service_connection_module_refs != null) { + service_connection_module_refs.clear(); + return; + } + service_connection_module_refs = null; + } + + public List> getPhysicalRouter() { + return physical_router_refs; + } + + public void setPhysicalRouter(PhysicalRouter obj) { + physical_router_refs = new ArrayList>(); + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs == null) { + physical_router_refs = new ArrayList>(); + } + physical_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalRouter(PhysicalRouter obj) { + if (physical_router_refs != null) { + physical_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalRouter() { + if (physical_router_refs != null) { + physical_router_refs.clear(); + return; + } + physical_router_refs = null; + } + + public List> getServiceObject() { + return service_object_refs; + } + + public void setServiceObject(ServiceObject obj) { + service_object_refs = new ArrayList>(); + service_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceObject(ServiceObject obj) { + if (service_object_refs == null) { + service_object_refs = new ArrayList>(); + } + service_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceObject(ServiceObject obj) { + if (service_object_refs != null) { + service_object_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceObject() { + if (service_object_refs != null) { + service_object_refs.clear(); + return; + } + service_object_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceGroup.java new file mode 100644 index 00000000000..d942da91221 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceGroup.java @@ -0,0 +1,133 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceGroup extends ApiObjectBase { + private String draft_mode_state; + private FirewallServiceGroupType service_group_firewall_service_list; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> firewall_rule_back_refs; + + @Override + public String getObjectType() { + return "service-group"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(PolicyManagement parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getDraftModeState() { + return draft_mode_state; + } + + public void setDraftModeState(String draft_mode_state) { + this.draft_mode_state = draft_mode_state; + } + + + public FirewallServiceGroupType getFirewallServiceList() { + return service_group_firewall_service_list; + } + + public void setFirewallServiceList(FirewallServiceGroupType service_group_firewall_service_list) { + this.service_group_firewall_service_list = service_group_firewall_service_list; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getFirewallRuleBackRefs() { + return firewall_rule_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceHealthCheck.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceHealthCheck.java new file mode 100644 index 00000000000..3d8970b8cca --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceHealthCheck.java @@ -0,0 +1,162 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceHealthCheck extends ApiObjectBase { + private ServiceHealthCheckType service_health_check_properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_instance_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> bgp_as_a_service_back_refs; + private transient List> virtual_network_back_refs; + + @Override + public String getObjectType() { + return "service-health-check"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public ServiceHealthCheckType getProperties() { + return service_health_check_properties; + } + + public void setProperties(ServiceHealthCheckType service_health_check_properties) { + this.service_health_check_properties = service_health_check_properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeServiceInstance(ServiceInstance obj, ServiceInterfaceTag data) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getBgpAsAServiceBackRefs() { + return bgp_as_a_service_back_refs; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceHealthCheckType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceHealthCheckType.java new file mode 100644 index 00000000000..e36f1fc478d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceHealthCheckType.java @@ -0,0 +1,180 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceHealthCheckType extends ApiPropertyBase { + Boolean enabled; + String health_check_type; + String monitor_type; + Integer delay; + Integer delayUsecs; + Integer timeout; + Integer timeoutUsecs; + Integer max_retries; + String http_method; + String url_path; + String expected_codes; + Boolean target_ip_all; + IpAddressesType target_ip_list; + public ServiceHealthCheckType() { + } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs, Integer max_retries, String http_method, String url_path, String expected_codes, Boolean target_ip_all, IpAddressesType target_ip_list) { + this.enabled = enabled; + this.health_check_type = health_check_type; + this.monitor_type = monitor_type; + this.delay = delay; + this.delayUsecs = delayUsecs; + this.timeout = timeout; + this.timeoutUsecs = timeoutUsecs; + this.max_retries = max_retries; + this.http_method = http_method; + this.url_path = url_path; + this.expected_codes = expected_codes; + this.target_ip_all = target_ip_all; + this.target_ip_list = target_ip_list; + } + public ServiceHealthCheckType(Boolean enabled) { + this(enabled, null, null, null, 0, null, 0, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type) { + this(enabled, health_check_type, null, null, 0, null, 0, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type) { + this(enabled, health_check_type, monitor_type, null, 0, null, 0, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay) { + this(enabled, health_check_type, monitor_type, delay, 0, null, 0, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, null, 0, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, 0, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, timeoutUsecs, null, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs, Integer max_retries) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, timeoutUsecs, max_retries, null, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs, Integer max_retries, String http_method) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, timeoutUsecs, max_retries, http_method, null, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs, Integer max_retries, String http_method, String url_path) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, timeoutUsecs, max_retries, http_method, url_path, null, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs, Integer max_retries, String http_method, String url_path, String expected_codes) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, timeoutUsecs, max_retries, http_method, url_path, expected_codes, false, null); } + public ServiceHealthCheckType(Boolean enabled, String health_check_type, String monitor_type, Integer delay, Integer delayUsecs, Integer timeout, Integer timeoutUsecs, Integer max_retries, String http_method, String url_path, String expected_codes, Boolean target_ip_all) { + this(enabled, health_check_type, monitor_type, delay, delayUsecs, timeout, timeoutUsecs, max_retries, http_method, url_path, expected_codes, target_ip_all, null); } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + + public String getHealthCheckType() { + return health_check_type; + } + + public void setHealthCheckType(String health_check_type) { + this.health_check_type = health_check_type; + } + + + public String getMonitorType() { + return monitor_type; + } + + public void setMonitorType(String monitor_type) { + this.monitor_type = monitor_type; + } + + + public Integer getDelay() { + return delay; + } + + public void setDelay(Integer delay) { + this.delay = delay; + } + + + public Integer getDelayusecs() { + return delayUsecs; + } + + public void setDelayusecs(Integer delayUsecs) { + this.delayUsecs = delayUsecs; + } + + + public Integer getTimeout() { + return timeout; + } + + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } + + + public Integer getTimeoutusecs() { + return timeoutUsecs; + } + + public void setTimeoutusecs(Integer timeoutUsecs) { + this.timeoutUsecs = timeoutUsecs; + } + + + public Integer getMaxRetries() { + return max_retries; + } + + public void setMaxRetries(Integer max_retries) { + this.max_retries = max_retries; + } + + + public String getHttpMethod() { + return http_method; + } + + public void setHttpMethod(String http_method) { + this.http_method = http_method; + } + + + public String getUrlPath() { + return url_path; + } + + public void setUrlPath(String url_path) { + this.url_path = url_path; + } + + + public String getExpectedCodes() { + return expected_codes; + } + + public void setExpectedCodes(String expected_codes) { + this.expected_codes = expected_codes; + } + + + public Boolean getTargetIpAll() { + return target_ip_all; + } + + public void setTargetIpAll(Boolean target_ip_all) { + this.target_ip_all = target_ip_all; + } + + + public IpAddressesType getTargetIpList() { + return target_ip_list; + } + + public void setTargetIpList(IpAddressesType target_ip_list) { + this.target_ip_list = target_ip_list; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstance.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstance.java new file mode 100644 index 00000000000..9918476beae --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstance.java @@ -0,0 +1,243 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceInstance extends ApiObjectBase { + private ServiceInstanceType service_instance_properties; + private KeyValuePairs service_instance_bindings; + private Boolean service_instance_bgp_enabled; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_template_refs; + private List> instance_ip_refs; + private List> port_tuples; + private List> tag_refs; + private transient List> virtual_machine_back_refs; + private transient List> service_health_check_back_refs; + private transient List> interface_route_table_back_refs; + private transient List> routing_policy_back_refs; + private transient List> route_aggregate_back_refs; + private transient List> logical_router_back_refs; + private transient List> loadbalancer_pool_back_refs; + private transient List> loadbalancer_back_refs; + + @Override + public String getObjectType() { + return "service-instance"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public ServiceInstanceType getProperties() { + return service_instance_properties; + } + + public void setProperties(ServiceInstanceType service_instance_properties) { + this.service_instance_properties = service_instance_properties; + } + + + public KeyValuePairs getBindings() { + return service_instance_bindings; + } + + public void setBindings(KeyValuePairs service_instance_bindings) { + this.service_instance_bindings = service_instance_bindings; + } + + + public Boolean getBgpEnabled() { + return service_instance_bgp_enabled; + } + + public void setBgpEnabled(Boolean service_instance_bgp_enabled) { + this.service_instance_bgp_enabled = service_instance_bgp_enabled; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceTemplate() { + return service_template_refs; + } + + public void setServiceTemplate(ServiceTemplate obj) { + service_template_refs = new ArrayList>(); + service_template_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceTemplate(ServiceTemplate obj) { + if (service_template_refs == null) { + service_template_refs = new ArrayList>(); + } + service_template_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceTemplate(ServiceTemplate obj) { + if (service_template_refs != null) { + service_template_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceTemplate() { + if (service_template_refs != null) { + service_template_refs.clear(); + return; + } + service_template_refs = null; + } + + public List> getInstanceIp() { + return instance_ip_refs; + } + + public void setInstanceIp(InstanceIp obj, ServiceInterfaceTag data) { + instance_ip_refs = new ArrayList>(); + instance_ip_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addInstanceIp(InstanceIp obj, ServiceInterfaceTag data) { + if (instance_ip_refs == null) { + instance_ip_refs = new ArrayList>(); + } + instance_ip_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeInstanceIp(InstanceIp obj, ServiceInterfaceTag data) { + if (instance_ip_refs != null) { + instance_ip_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearInstanceIp() { + if (instance_ip_refs != null) { + instance_ip_refs.clear(); + return; + } + instance_ip_refs = null; + } + + + public List> getPortTuples() { + return port_tuples; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineBackRefs() { + return virtual_machine_back_refs; + } + + public List> getServiceHealthCheckBackRefs() { + return service_health_check_back_refs; + } + + public List> getInterfaceRouteTableBackRefs() { + return interface_route_table_back_refs; + } + + public List> getRoutingPolicyBackRefs() { + return routing_policy_back_refs; + } + + public List> getRouteAggregateBackRefs() { + return route_aggregate_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } + + public List> getLoadbalancerPoolBackRefs() { + return loadbalancer_pool_back_refs; + } + + public List> getLoadbalancerBackRefs() { + return loadbalancer_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstanceInterfaceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstanceInterfaceType.java new file mode 100644 index 00000000000..f7b70e001fa --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstanceInterfaceType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceInstanceInterfaceType extends ApiPropertyBase { + String virtual_network; + String ip_address; + RouteTableType static_routes; + AllowedAddressPairs allowed_address_pairs; + public ServiceInstanceInterfaceType() { + } + public ServiceInstanceInterfaceType(String virtual_network, String ip_address, RouteTableType static_routes, AllowedAddressPairs allowed_address_pairs) { + this.virtual_network = virtual_network; + this.ip_address = ip_address; + this.static_routes = static_routes; + this.allowed_address_pairs = allowed_address_pairs; + } + public ServiceInstanceInterfaceType(String virtual_network) { + this(virtual_network, null, null, null); } + public ServiceInstanceInterfaceType(String virtual_network, String ip_address) { + this(virtual_network, ip_address, null, null); } + public ServiceInstanceInterfaceType(String virtual_network, String ip_address, RouteTableType static_routes) { + this(virtual_network, ip_address, static_routes, null); } + + public String getVirtualNetwork() { + return virtual_network; + } + + public void setVirtualNetwork(String virtual_network) { + this.virtual_network = virtual_network; + } + + + public String getIpAddress() { + return ip_address; + } + + public void setIpAddress(String ip_address) { + this.ip_address = ip_address; + } + + + public RouteTableType getStaticRoutes() { + return static_routes; + } + + public void setStaticRoutes(RouteTableType static_routes) { + this.static_routes = static_routes; + } + + + public AllowedAddressPairs getAllowedAddressPairs() { + return allowed_address_pairs; + } + + public void setAllowedAddressPairs(AllowedAddressPairs allowed_address_pairs) { + this.allowed_address_pairs = allowed_address_pairs; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstanceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstanceType.java new file mode 100644 index 00000000000..3ad71e1e909 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInstanceType.java @@ -0,0 +1,185 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceInstanceType extends ApiPropertyBase { + Boolean auto_policy; + String availability_zone; + String management_virtual_network; + String left_virtual_network; + String left_ip_address; + String right_virtual_network; + String right_ip_address; + List interface_list; + ServiceScaleOutType scale_out; + String ha_mode; + String virtual_router_id; + String service_virtualization_type; + public ServiceInstanceType() { + } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network, String right_ip_address, List interface_list, ServiceScaleOutType scale_out, String ha_mode, String virtual_router_id, String service_virtualization_type) { + this.auto_policy = auto_policy; + this.availability_zone = availability_zone; + this.management_virtual_network = management_virtual_network; + this.left_virtual_network = left_virtual_network; + this.left_ip_address = left_ip_address; + this.right_virtual_network = right_virtual_network; + this.right_ip_address = right_ip_address; + this.interface_list = interface_list; + this.scale_out = scale_out; + this.ha_mode = ha_mode; + this.virtual_router_id = virtual_router_id; + this.service_virtualization_type = service_virtualization_type; + } + public ServiceInstanceType(Boolean auto_policy) { + this(auto_policy, null, null, null, null, null, null, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone) { + this(auto_policy, availability_zone, null, null, null, null, null, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network) { + this(auto_policy, availability_zone, management_virtual_network, null, null, null, null, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, null, null, null, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, null, null, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, right_virtual_network, null, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network, String right_ip_address) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, right_virtual_network, right_ip_address, null, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network, String right_ip_address, List interface_list) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, right_virtual_network, right_ip_address, interface_list, null, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network, String right_ip_address, List interface_list, ServiceScaleOutType scale_out) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, right_virtual_network, right_ip_address, interface_list, scale_out, null, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network, String right_ip_address, List interface_list, ServiceScaleOutType scale_out, String ha_mode) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, right_virtual_network, right_ip_address, interface_list, scale_out, ha_mode, null, null); } + public ServiceInstanceType(Boolean auto_policy, String availability_zone, String management_virtual_network, String left_virtual_network, String left_ip_address, String right_virtual_network, String right_ip_address, List interface_list, ServiceScaleOutType scale_out, String ha_mode, String virtual_router_id) { + this(auto_policy, availability_zone, management_virtual_network, left_virtual_network, left_ip_address, right_virtual_network, right_ip_address, interface_list, scale_out, ha_mode, virtual_router_id, null); } + + public Boolean getAutoPolicy() { + return auto_policy; + } + + public void setAutoPolicy(Boolean auto_policy) { + this.auto_policy = auto_policy; + } + + + public String getAvailabilityZone() { + return availability_zone; + } + + public void setAvailabilityZone(String availability_zone) { + this.availability_zone = availability_zone; + } + + + public String getManagementVirtualNetwork() { + return management_virtual_network; + } + + public void setManagementVirtualNetwork(String management_virtual_network) { + this.management_virtual_network = management_virtual_network; + } + + + public String getLeftVirtualNetwork() { + return left_virtual_network; + } + + public void setLeftVirtualNetwork(String left_virtual_network) { + this.left_virtual_network = left_virtual_network; + } + + + public String getLeftIpAddress() { + return left_ip_address; + } + + public void setLeftIpAddress(String left_ip_address) { + this.left_ip_address = left_ip_address; + } + + + public String getRightVirtualNetwork() { + return right_virtual_network; + } + + public void setRightVirtualNetwork(String right_virtual_network) { + this.right_virtual_network = right_virtual_network; + } + + + public String getRightIpAddress() { + return right_ip_address; + } + + public void setRightIpAddress(String right_ip_address) { + this.right_ip_address = right_ip_address; + } + + + public ServiceScaleOutType getScaleOut() { + return scale_out; + } + + public void setScaleOut(ServiceScaleOutType scale_out) { + this.scale_out = scale_out; + } + + + public String getHaMode() { + return ha_mode; + } + + public void setHaMode(String ha_mode) { + this.ha_mode = ha_mode; + } + + + public String getVirtualRouterId() { + return virtual_router_id; + } + + public void setVirtualRouterId(String virtual_router_id) { + this.virtual_router_id = virtual_router_id; + } + + + public String getServiceVirtualizationType() { + return service_virtualization_type; + } + + public void setServiceVirtualizationType(String service_virtualization_type) { + this.service_virtualization_type = service_virtualization_type; + } + + + public List getInterfaceList() { + return interface_list; + } + + + public void addInterface(ServiceInstanceInterfaceType obj) { + if (interface_list == null) { + interface_list = new ArrayList(); + } + interface_list.add(obj); + } + public void clearInterface() { + interface_list = null; + } + + + public void addInterface(String virtual_network, String ip_address, RouteTableType static_routes, AllowedAddressPairs allowed_address_pairs) { + if (interface_list == null) { + interface_list = new ArrayList(); + } + interface_list.add(new ServiceInstanceInterfaceType(virtual_network, ip_address, static_routes, allowed_address_pairs)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInterfaceTag.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInterfaceTag.java new file mode 100644 index 00000000000..24bafbecdb3 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceInterfaceTag.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceInterfaceTag extends ApiPropertyBase { + String interface_type; + public ServiceInterfaceTag() { + } + public ServiceInterfaceTag(String interface_type) { + this.interface_type = interface_type; + } + + public String getInterfaceType() { + return interface_type; + } + + public void setInterfaceType(String interface_type) { + this.interface_type = interface_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceObject.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceObject.java new file mode 100644 index 00000000000..8038ff413e2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceObject.java @@ -0,0 +1,111 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceObject extends ApiObjectBase { + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> service_endpoint_back_refs; + private transient List> service_connection_module_back_refs; + + @Override + public String getObjectType() { + return "service-object"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceEndpointBackRefs() { + return service_endpoint_back_refs; + } + + public List> getServiceConnectionModuleBackRefs() { + return service_connection_module_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServicePropertiesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServicePropertiesType.java new file mode 100644 index 00000000000..19fe33ffdae --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServicePropertiesType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServicePropertiesType extends ApiPropertyBase { + Boolean retain_as_path; + public ServicePropertiesType() { + } + public ServicePropertiesType(Boolean retain_as_path) { + this.retain_as_path = retain_as_path; + } + + public Boolean getRetainAsPath() { + return retain_as_path; + } + + public void setRetainAsPath(Boolean retain_as_path) { + this.retain_as_path = retain_as_path; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceScaleOutType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceScaleOutType.java new file mode 100644 index 00000000000..2e7c5305b7b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceScaleOutType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceScaleOutType extends ApiPropertyBase { + Integer max_instances; + Boolean auto_scale; + public ServiceScaleOutType() { + } + public ServiceScaleOutType(Integer max_instances, Boolean auto_scale) { + this.max_instances = max_instances; + this.auto_scale = auto_scale; + } + public ServiceScaleOutType(Integer max_instances) { + this(max_instances, false); } + + public Integer getMaxInstances() { + return max_instances; + } + + public void setMaxInstances(Integer max_instances) { + this.max_instances = max_instances; + } + + + public Boolean getAutoScale() { + return auto_scale; + } + + public void setAutoScale(Boolean auto_scale) { + this.auto_scale = auto_scale; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplate.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplate.java new file mode 100644 index 00000000000..01f88386080 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplate.java @@ -0,0 +1,161 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class ServiceTemplate extends ApiObjectBase { + private ServiceTemplateType service_template_properties; + private Boolean service_config_managed; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> service_appliance_set_refs; + private List> tag_refs; + private transient List> service_instance_back_refs; + + @Override + public String getObjectType() { + return "service-template"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain"); + } + + @Override + public String getDefaultParentType() { + return "domain"; + } + + public void setParent(Domain parent) { + super.setParent(parent); + } + + public ServiceTemplateType getProperties() { + return service_template_properties; + } + + public void setProperties(ServiceTemplateType service_template_properties) { + this.service_template_properties = service_template_properties; + } + + + public Boolean getServiceConfigManaged() { + return service_config_managed; + } + + public void setServiceConfigManaged(Boolean service_config_managed) { + this.service_config_managed = service_config_managed; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getServiceApplianceSet() { + return service_appliance_set_refs; + } + + public void setServiceApplianceSet(ServiceApplianceSet obj) { + service_appliance_set_refs = new ArrayList>(); + service_appliance_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceApplianceSet(ServiceApplianceSet obj) { + if (service_appliance_set_refs == null) { + service_appliance_set_refs = new ArrayList>(); + } + service_appliance_set_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceApplianceSet(ServiceApplianceSet obj) { + if (service_appliance_set_refs != null) { + service_appliance_set_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceApplianceSet() { + if (service_appliance_set_refs != null) { + service_appliance_set_refs.clear(); + return; + } + service_appliance_set_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceInstanceBackRefs() { + return service_instance_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplateInterfaceType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplateInterfaceType.java new file mode 100644 index 00000000000..7c141a27981 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplateInterfaceType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceTemplateInterfaceType extends ApiPropertyBase { + String service_interface_type; + Boolean shared_ip; + Boolean static_route_enable; + public ServiceTemplateInterfaceType() { + } + public ServiceTemplateInterfaceType(String service_interface_type, Boolean shared_ip, Boolean static_route_enable) { + this.service_interface_type = service_interface_type; + this.shared_ip = shared_ip; + this.static_route_enable = static_route_enable; + } + public ServiceTemplateInterfaceType(String service_interface_type) { + this(service_interface_type, false, false); } + public ServiceTemplateInterfaceType(String service_interface_type, Boolean shared_ip) { + this(service_interface_type, shared_ip, false); } + + public String getServiceInterfaceType() { + return service_interface_type; + } + + public void setServiceInterfaceType(String service_interface_type) { + this.service_interface_type = service_interface_type; + } + + + public Boolean getSharedIp() { + return shared_ip; + } + + public void setSharedIp(Boolean shared_ip) { + this.shared_ip = shared_ip; + } + + + public Boolean getStaticRouteEnable() { + return static_route_enable; + } + + public void setStaticRouteEnable(Boolean static_route_enable) { + this.static_route_enable = static_route_enable; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplateType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplateType.java new file mode 100644 index 00000000000..11678594fa8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceTemplateType.java @@ -0,0 +1,185 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceTemplateType extends ApiPropertyBase { + Integer version; + String service_mode; + String service_type; + String image_name; + Boolean service_scaling; + List interface_type; + String flavor; + Boolean ordered_interfaces; + String service_virtualization_type; + Boolean availability_zone_enable; + String vrouter_instance_type; + String instance_data; + public ServiceTemplateType() { + } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type, String flavor, Boolean ordered_interfaces, String service_virtualization_type, Boolean availability_zone_enable, String vrouter_instance_type, String instance_data) { + this.version = version; + this.service_mode = service_mode; + this.service_type = service_type; + this.image_name = image_name; + this.service_scaling = service_scaling; + this.interface_type = interface_type; + this.flavor = flavor; + this.ordered_interfaces = ordered_interfaces; + this.service_virtualization_type = service_virtualization_type; + this.availability_zone_enable = availability_zone_enable; + this.vrouter_instance_type = vrouter_instance_type; + this.instance_data = instance_data; + } + public ServiceTemplateType(Integer version) { + this(version, null, null, null, false, null, null, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode) { + this(version, service_mode, null, null, false, null, null, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type) { + this(version, service_mode, service_type, null, false, null, null, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name) { + this(version, service_mode, service_type, image_name, false, null, null, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling) { + this(version, service_mode, service_type, image_name, service_scaling, null, null, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type) { + this(version, service_mode, service_type, image_name, service_scaling, interface_type, null, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type, String flavor) { + this(version, service_mode, service_type, image_name, service_scaling, interface_type, flavor, false, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type, String flavor, Boolean ordered_interfaces) { + this(version, service_mode, service_type, image_name, service_scaling, interface_type, flavor, ordered_interfaces, null, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type, String flavor, Boolean ordered_interfaces, String service_virtualization_type) { + this(version, service_mode, service_type, image_name, service_scaling, interface_type, flavor, ordered_interfaces, service_virtualization_type, false, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type, String flavor, Boolean ordered_interfaces, String service_virtualization_type, Boolean availability_zone_enable) { + this(version, service_mode, service_type, image_name, service_scaling, interface_type, flavor, ordered_interfaces, service_virtualization_type, availability_zone_enable, null, null); } + public ServiceTemplateType(Integer version, String service_mode, String service_type, String image_name, Boolean service_scaling, List interface_type, String flavor, Boolean ordered_interfaces, String service_virtualization_type, Boolean availability_zone_enable, String vrouter_instance_type) { + this(version, service_mode, service_type, image_name, service_scaling, interface_type, flavor, ordered_interfaces, service_virtualization_type, availability_zone_enable, vrouter_instance_type, null); } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + + public String getServiceMode() { + return service_mode; + } + + public void setServiceMode(String service_mode) { + this.service_mode = service_mode; + } + + + public String getServiceType() { + return service_type; + } + + public void setServiceType(String service_type) { + this.service_type = service_type; + } + + + public String getImageName() { + return image_name; + } + + public void setImageName(String image_name) { + this.image_name = image_name; + } + + + public Boolean getServiceScaling() { + return service_scaling; + } + + public void setServiceScaling(Boolean service_scaling) { + this.service_scaling = service_scaling; + } + + + public String getFlavor() { + return flavor; + } + + public void setFlavor(String flavor) { + this.flavor = flavor; + } + + + public Boolean getOrderedInterfaces() { + return ordered_interfaces; + } + + public void setOrderedInterfaces(Boolean ordered_interfaces) { + this.ordered_interfaces = ordered_interfaces; + } + + + public String getServiceVirtualizationType() { + return service_virtualization_type; + } + + public void setServiceVirtualizationType(String service_virtualization_type) { + this.service_virtualization_type = service_virtualization_type; + } + + + public Boolean getAvailabilityZoneEnable() { + return availability_zone_enable; + } + + public void setAvailabilityZoneEnable(Boolean availability_zone_enable) { + this.availability_zone_enable = availability_zone_enable; + } + + + public String getVrouterInstanceType() { + return vrouter_instance_type; + } + + public void setVrouterInstanceType(String vrouter_instance_type) { + this.vrouter_instance_type = vrouter_instance_type; + } + + + public String getInstanceData() { + return instance_data; + } + + public void setInstanceData(String instance_data) { + this.instance_data = instance_data; + } + + + public List getInterfaceType() { + return interface_type; + } + + + public void addInterfaceType(ServiceTemplateInterfaceType obj) { + if (interface_type == null) { + interface_type = new ArrayList(); + } + interface_type.add(obj); + } + public void clearInterfaceType() { + interface_type = null; + } + + + public void addInterfaceType(String service_interface_type, Boolean shared_ip, Boolean static_route_enable) { + if (interface_type == null) { + interface_type = new ArrayList(); + } + interface_type.add(new ServiceTemplateInterfaceType(service_interface_type, shared_ip, static_route_enable)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceVirtualNetworkType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceVirtualNetworkType.java new file mode 100644 index 00000000000..b7055d68ff8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ServiceVirtualNetworkType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ServiceVirtualNetworkType extends ApiPropertyBase { + String virtual_network_type; + public ServiceVirtualNetworkType() { + } + public ServiceVirtualNetworkType(String virtual_network_type) { + this.virtual_network_type = virtual_network_type; + } + + public String getVirtualNetworkType() { + return virtual_network_type; + } + + public void setVirtualNetworkType(String virtual_network_type) { + this.virtual_network_type = virtual_network_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SflowParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SflowParameters.java new file mode 100644 index 00000000000..5346eda9427 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SflowParameters.java @@ -0,0 +1,94 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SflowParameters extends ApiPropertyBase { + StatsCollectionFrequency stats_collection_frequency; + String agent_id; + Integer adaptive_sample_rate; + String enabled_interface_type; + List enabled_interface_params; + public SflowParameters() { + } + public SflowParameters(StatsCollectionFrequency stats_collection_frequency, String agent_id, Integer adaptive_sample_rate, String enabled_interface_type, List enabled_interface_params) { + this.stats_collection_frequency = stats_collection_frequency; + this.agent_id = agent_id; + this.adaptive_sample_rate = adaptive_sample_rate; + this.enabled_interface_type = enabled_interface_type; + this.enabled_interface_params = enabled_interface_params; + } + public SflowParameters(StatsCollectionFrequency stats_collection_frequency) { + this(stats_collection_frequency, null, 300, null, null); } + public SflowParameters(StatsCollectionFrequency stats_collection_frequency, String agent_id) { + this(stats_collection_frequency, agent_id, 300, null, null); } + public SflowParameters(StatsCollectionFrequency stats_collection_frequency, String agent_id, Integer adaptive_sample_rate) { + this(stats_collection_frequency, agent_id, adaptive_sample_rate, null, null); } + public SflowParameters(StatsCollectionFrequency stats_collection_frequency, String agent_id, Integer adaptive_sample_rate, String enabled_interface_type) { + this(stats_collection_frequency, agent_id, adaptive_sample_rate, enabled_interface_type, null); } + + public StatsCollectionFrequency getStatsCollectionFrequency() { + return stats_collection_frequency; + } + + public void setStatsCollectionFrequency(StatsCollectionFrequency stats_collection_frequency) { + this.stats_collection_frequency = stats_collection_frequency; + } + + + public String getAgentId() { + return agent_id; + } + + public void setAgentId(String agent_id) { + this.agent_id = agent_id; + } + + + public Integer getAdaptiveSampleRate() { + return adaptive_sample_rate; + } + + public void setAdaptiveSampleRate(Integer adaptive_sample_rate) { + this.adaptive_sample_rate = adaptive_sample_rate; + } + + + public String getEnabledInterfaceType() { + return enabled_interface_type; + } + + public void setEnabledInterfaceType(String enabled_interface_type) { + this.enabled_interface_type = enabled_interface_type; + } + + + public List getEnabledInterfaceParams() { + return enabled_interface_params; + } + + + public void addEnabledInterfaceParams(EnabledInterfaceParams obj) { + if (enabled_interface_params == null) { + enabled_interface_params = new ArrayList(); + } + enabled_interface_params.add(obj); + } + public void clearEnabledInterfaceParams() { + enabled_interface_params = null; + } + + + public void addEnabledInterfaceParams(String name, StatsCollectionFrequency stats_collection_frequency) { + if (enabled_interface_params == null) { + enabled_interface_params = new ArrayList(); + } + enabled_interface_params.add(new EnabledInterfaceParams(name, stats_collection_frequency)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SflowProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SflowProfile.java new file mode 100644 index 00000000000..f4ab23f119a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SflowProfile.java @@ -0,0 +1,130 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class SflowProfile extends ApiObjectBase { + private Boolean sflow_profile_is_default; + private SflowParameters sflow_parameters; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> telemetry_profile_back_refs; + + @Override + public String getObjectType() { + return "sflow-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Boolean getIsDefault() { + return sflow_profile_is_default; + } + + public void setIsDefault(Boolean sflow_profile_is_default) { + this.sflow_profile_is_default = sflow_profile_is_default; + } + + + public SflowParameters getSflowParameters() { + return sflow_parameters; + } + + public void setSflowParameters(SflowParameters sflow_parameters) { + this.sflow_parameters = sflow_parameters; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getTelemetryProfileBackRefs() { + return telemetry_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ShareType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ShareType.java new file mode 100644 index 00000000000..b7fddc1d237 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/ShareType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class ShareType extends ApiPropertyBase { + String tenant; + Integer tenant_access; + public ShareType() { + } + public ShareType(String tenant, Integer tenant_access) { + this.tenant = tenant; + this.tenant_access = tenant_access; + } + public ShareType(String tenant) { + this(tenant, null); } + + public String getTenant() { + return tenant; + } + + public void setTenant(String tenant) { + this.tenant = tenant; + } + + + public Integer getTenantAccess() { + return tenant_access; + } + + public void setTenantAccess(Integer tenant_access) { + this.tenant_access = tenant_access; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SloRateType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SloRateType.java new file mode 100644 index 00000000000..ac697088297 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SloRateType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SloRateType extends ApiPropertyBase { + Integer rate; + public SloRateType() { + } + public SloRateType(Integer rate) { + this.rate = rate; + } + + public Integer getRate() { + return rate; + } + + public void setRate(Integer rate) { + this.rate = rate; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SnmpParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SnmpParameters.java new file mode 100644 index 00000000000..536dbfcdfe6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SnmpParameters.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SnmpParameters extends ApiPropertyBase { + EnabledSensorParams enabled_sensor_params; + public SnmpParameters() { + } + public SnmpParameters(EnabledSensorParams enabled_sensor_params) { + this.enabled_sensor_params = enabled_sensor_params; + } + + public EnabledSensorParams getEnabledSensorParams() { + return enabled_sensor_params; + } + + public void setEnabledSensorParams(EnabledSensorParams enabled_sensor_params) { + this.enabled_sensor_params = enabled_sensor_params; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SnmpProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SnmpProfile.java new file mode 100644 index 00000000000..1646ec20b82 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SnmpProfile.java @@ -0,0 +1,130 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class SnmpProfile extends ApiObjectBase { + private Boolean snmp_profile_is_default; + private SnmpParameters snmp_parameters; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> telemetry_profile_back_refs; + + @Override + public String getObjectType() { + return "snmp-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Boolean getIsDefault() { + return snmp_profile_is_default; + } + + public void setIsDefault(Boolean snmp_profile_is_default) { + this.snmp_profile_is_default = snmp_profile_is_default; + } + + + public SnmpParameters getSnmpParameters() { + return snmp_parameters; + } + + public void setSnmpParameters(SnmpParameters snmp_parameters) { + this.snmp_parameters = snmp_parameters; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getTelemetryProfileBackRefs() { + return telemetry_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StaticMirrorNhType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StaticMirrorNhType.java new file mode 100644 index 00000000000..44f8d83fd02 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StaticMirrorNhType.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class StaticMirrorNhType extends ApiPropertyBase { + String vtep_dst_ip_address; + String vtep_dst_mac_address; + Integer vni; + public StaticMirrorNhType() { + } + public StaticMirrorNhType(String vtep_dst_ip_address, String vtep_dst_mac_address, Integer vni) { + this.vtep_dst_ip_address = vtep_dst_ip_address; + this.vtep_dst_mac_address = vtep_dst_mac_address; + this.vni = vni; + } + public StaticMirrorNhType(String vtep_dst_ip_address) { + this(vtep_dst_ip_address, null, null); } + public StaticMirrorNhType(String vtep_dst_ip_address, String vtep_dst_mac_address) { + this(vtep_dst_ip_address, vtep_dst_mac_address, null); } + + public String getVtepDstIpAddress() { + return vtep_dst_ip_address; + } + + public void setVtepDstIpAddress(String vtep_dst_ip_address) { + this.vtep_dst_ip_address = vtep_dst_ip_address; + } + + + public String getVtepDstMacAddress() { + return vtep_dst_mac_address; + } + + public void setVtepDstMacAddress(String vtep_dst_mac_address) { + this.vtep_dst_mac_address = vtep_dst_mac_address; + } + + + public Integer getVni() { + return vni; + } + + public void setVni(Integer vni) { + this.vni = vni; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StaticRouteParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StaticRouteParameters.java new file mode 100644 index 00000000000..635797009c8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StaticRouteParameters.java @@ -0,0 +1,54 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class StaticRouteParameters extends ApiPropertyBase { + List interface_route_table_uuid; + List next_hop_ip_address; + public StaticRouteParameters() { + } + public StaticRouteParameters(List interface_route_table_uuid, List next_hop_ip_address) { + this.interface_route_table_uuid = interface_route_table_uuid; + this.next_hop_ip_address = next_hop_ip_address; + } + public StaticRouteParameters(List interface_route_table_uuid) { + this(interface_route_table_uuid, null); } + + public List getInterfaceRouteTableUuid() { + return interface_route_table_uuid; + } + + + public void addInterfaceRouteTableUuid(String obj) { + if (interface_route_table_uuid == null) { + interface_route_table_uuid = new ArrayList(); + } + interface_route_table_uuid.add(obj); + } + public void clearInterfaceRouteTableUuid() { + interface_route_table_uuid = null; + } + + + public List getNextHopIpAddress() { + return next_hop_ip_address; + } + + + public void addNextHopIpAddress(String obj) { + if (next_hop_ip_address == null) { + next_hop_ip_address = new ArrayList(); + } + next_hop_ip_address.add(obj); + } + public void clearNextHopIpAddress() { + next_hop_ip_address = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StatsCollectionFrequency.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StatsCollectionFrequency.java new file mode 100644 index 00000000000..305a702501f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StatsCollectionFrequency.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class StatsCollectionFrequency extends ApiPropertyBase { + Integer sample_rate; + Integer polling_interval; + String direction; + public StatsCollectionFrequency() { + } + public StatsCollectionFrequency(Integer sample_rate, Integer polling_interval, String direction) { + this.sample_rate = sample_rate; + this.polling_interval = polling_interval; + this.direction = direction; + } + public StatsCollectionFrequency(Integer sample_rate) { + this(sample_rate, 0, null); } + public StatsCollectionFrequency(Integer sample_rate, Integer polling_interval) { + this(sample_rate, polling_interval, null); } + + public Integer getSampleRate() { + return sample_rate; + } + + public void setSampleRate(Integer sample_rate) { + this.sample_rate = sample_rate; + } + + + public Integer getPollingInterval() { + return polling_interval; + } + + public void setPollingInterval(Integer polling_interval) { + this.polling_interval = polling_interval; + } + + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StormControlParameters.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StormControlParameters.java new file mode 100644 index 00000000000..b50e73bb8c0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StormControlParameters.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class StormControlParameters extends ApiPropertyBase { + List storm_control_actions; + Integer recovery_timeout; + Boolean no_unregistered_multicast; + Boolean no_registered_multicast; + Boolean no_unknown_unicast; + Boolean no_multicast; + Boolean no_broadcast; + Integer bandwidth_percent; + public StormControlParameters() { + } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout, Boolean no_unregistered_multicast, Boolean no_registered_multicast, Boolean no_unknown_unicast, Boolean no_multicast, Boolean no_broadcast, Integer bandwidth_percent) { + this.storm_control_actions = storm_control_actions; + this.recovery_timeout = recovery_timeout; + this.no_unregistered_multicast = no_unregistered_multicast; + this.no_registered_multicast = no_registered_multicast; + this.no_unknown_unicast = no_unknown_unicast; + this.no_multicast = no_multicast; + this.no_broadcast = no_broadcast; + this.bandwidth_percent = bandwidth_percent; + } + public StormControlParameters(List storm_control_actions) { + this(storm_control_actions, null, false, false, false, false, false, null); } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout) { + this(storm_control_actions, recovery_timeout, false, false, false, false, false, null); } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout, Boolean no_unregistered_multicast) { + this(storm_control_actions, recovery_timeout, no_unregistered_multicast, false, false, false, false, null); } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout, Boolean no_unregistered_multicast, Boolean no_registered_multicast) { + this(storm_control_actions, recovery_timeout, no_unregistered_multicast, no_registered_multicast, false, false, false, null); } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout, Boolean no_unregistered_multicast, Boolean no_registered_multicast, Boolean no_unknown_unicast) { + this(storm_control_actions, recovery_timeout, no_unregistered_multicast, no_registered_multicast, no_unknown_unicast, false, false, null); } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout, Boolean no_unregistered_multicast, Boolean no_registered_multicast, Boolean no_unknown_unicast, Boolean no_multicast) { + this(storm_control_actions, recovery_timeout, no_unregistered_multicast, no_registered_multicast, no_unknown_unicast, no_multicast, false, null); } + public StormControlParameters(List storm_control_actions, Integer recovery_timeout, Boolean no_unregistered_multicast, Boolean no_registered_multicast, Boolean no_unknown_unicast, Boolean no_multicast, Boolean no_broadcast) { + this(storm_control_actions, recovery_timeout, no_unregistered_multicast, no_registered_multicast, no_unknown_unicast, no_multicast, no_broadcast, null); } + + public Integer getRecoveryTimeout() { + return recovery_timeout; + } + + public void setRecoveryTimeout(Integer recovery_timeout) { + this.recovery_timeout = recovery_timeout; + } + + + public Boolean getNoUnregisteredMulticast() { + return no_unregistered_multicast; + } + + public void setNoUnregisteredMulticast(Boolean no_unregistered_multicast) { + this.no_unregistered_multicast = no_unregistered_multicast; + } + + + public Boolean getNoRegisteredMulticast() { + return no_registered_multicast; + } + + public void setNoRegisteredMulticast(Boolean no_registered_multicast) { + this.no_registered_multicast = no_registered_multicast; + } + + + public Boolean getNoUnknownUnicast() { + return no_unknown_unicast; + } + + public void setNoUnknownUnicast(Boolean no_unknown_unicast) { + this.no_unknown_unicast = no_unknown_unicast; + } + + + public Boolean getNoMulticast() { + return no_multicast; + } + + public void setNoMulticast(Boolean no_multicast) { + this.no_multicast = no_multicast; + } + + + public Boolean getNoBroadcast() { + return no_broadcast; + } + + public void setNoBroadcast(Boolean no_broadcast) { + this.no_broadcast = no_broadcast; + } + + + public Integer getBandwidthPercent() { + return bandwidth_percent; + } + + public void setBandwidthPercent(Integer bandwidth_percent) { + this.bandwidth_percent = bandwidth_percent; + } + + + public List getStormControlActions() { + return storm_control_actions; + } + + + public void addStormControlActions(String obj) { + if (storm_control_actions == null) { + storm_control_actions = new ArrayList(); + } + storm_control_actions.add(obj); + } + public void clearStormControlActions() { + storm_control_actions = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StormControlProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StormControlProfile.java new file mode 100644 index 00000000000..61e35a934a6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/StormControlProfile.java @@ -0,0 +1,120 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class StormControlProfile extends ApiObjectBase { + private StormControlParameters storm_control_parameters; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> port_profile_back_refs; + + @Override + public String getObjectType() { + return "storm-control-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public StormControlParameters getStormControlParameters() { + return storm_control_parameters; + } + + public void setStormControlParameters(StormControlParameters storm_control_parameters) { + this.storm_control_parameters = storm_control_parameters; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPortProfileBackRefs() { + return port_profile_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubCluster.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubCluster.java new file mode 100644 index 00000000000..14a9358fe18 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubCluster.java @@ -0,0 +1,126 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class SubCluster extends ApiObjectBase { + private Integer sub_cluster_asn; + private Integer sub_cluster_id; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> virtual_router_back_refs; + + @Override + public String getObjectType() { + return "sub-cluster"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public Integer getAsn() { + return sub_cluster_asn; + } + + public void setAsn(Integer sub_cluster_asn) { + this.sub_cluster_asn = sub_cluster_asn; + } + + + public Integer getId() { + return sub_cluster_id; + } + + public void setId(Integer sub_cluster_id) { + this.sub_cluster_id = sub_cluster_id; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualRouterBackRefs() { + return virtual_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Subnet.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Subnet.java new file mode 100644 index 00000000000..0b3432cdec6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Subnet.java @@ -0,0 +1,142 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Subnet extends ApiObjectBase { + private SubnetType subnet_ip_prefix; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_machine_interface_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "subnet"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public SubnetType getIpPrefix() { + return subnet_ip_prefix; + } + + public void setIpPrefix(SubnetType subnet_ip_prefix) { + this.subnet_ip_prefix = subnet_ip_prefix; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubnetListType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubnetListType.java new file mode 100644 index 00000000000..466fdd0252a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubnetListType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SubnetListType extends ApiPropertyBase { + List subnet; + public SubnetListType() { + } + public SubnetListType(List subnet) { + this.subnet = subnet; + } + + public List getSubnet() { + return subnet; + } + + + public void addSubnet(SubnetType obj) { + if (subnet == null) { + subnet = new ArrayList(); + } + subnet.add(obj); + } + public void clearSubnet() { + subnet = null; + } + + + public void addSubnet(String ip_prefix, Integer ip_prefix_len) { + if (subnet == null) { + subnet = new ArrayList(); + } + subnet.add(new SubnetType(ip_prefix, ip_prefix_len)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubnetType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubnetType.java new file mode 100644 index 00000000000..2d276dd8c8a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/SubnetType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class SubnetType extends ApiPropertyBase { + String ip_prefix; + Integer ip_prefix_len; + public SubnetType() { + } + public SubnetType(String ip_prefix, Integer ip_prefix_len) { + this.ip_prefix = ip_prefix; + this.ip_prefix_len = ip_prefix_len; + } + public SubnetType(String ip_prefix) { + this(ip_prefix, null); } + + public String getIpPrefix() { + return ip_prefix; + } + + public void setIpPrefix(String ip_prefix) { + this.ip_prefix = ip_prefix; + } + + + public Integer getIpPrefixLen() { + return ip_prefix_len; + } + + public void setIpPrefixLen(Integer ip_prefix_len) { + this.ip_prefix_len = ip_prefix_len; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Tag.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Tag.java new file mode 100644 index 00000000000..f2b055f8444 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/Tag.java @@ -0,0 +1,769 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class Tag extends ApiObjectBase { + private String tag_type_name; + private String tag_value; + private Boolean tag_predefined; + private String tag_id; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_type_refs; + private List> tag_refs; + private transient List> service_endpoint_back_refs; + private transient List> instance_ip_back_refs; + private transient List> service_appliance_set_back_refs; + private transient List> route_target_back_refs; + private transient List> loadbalancer_listener_back_refs; + private transient List> floating_ip_pool_back_refs; + private transient List> physical_router_back_refs; + private transient List> config_root_back_refs; + private transient List> service_template_back_refs; + private transient List> hardware_inventory_back_refs; + private transient List> firewall_policy_back_refs; + private transient List> route_table_back_refs; + private transient List> provider_attachment_back_refs; + private transient List> overlay_role_back_refs; + private transient List> multicast_policy_back_refs; + private transient List> network_device_config_back_refs; + private transient List> virtual_DNS_record_back_refs; + private transient List> control_node_zone_back_refs; + private transient List> dsa_rule_back_refs; + private transient List> discovery_service_assignment_back_refs; + private transient List> logical_interface_back_refs; + private transient List> flow_node_back_refs; + private transient List> port_group_back_refs; + private transient List> route_aggregate_back_refs; + private transient List> logical_router_back_refs; + private transient List> domain_back_refs; + private transient List> service_instance_back_refs; + private transient List> node_profile_back_refs; + private transient List> bridge_domain_back_refs; + private transient List> alias_ip_back_refs; + private transient List> webui_node_back_refs; + private transient List> port_back_refs; + private transient List> bgp_as_a_service_back_refs; + private transient List> subnet_back_refs; + private transient List> global_system_config_back_refs; + private transient List> sub_cluster_back_refs; + private transient List> forwarding_class_back_refs; + private transient List> service_group_back_refs; + private transient List> address_group_back_refs; + private transient List> application_policy_set_back_refs; + private transient List> virtual_ip_back_refs; + private transient List> intent_map_back_refs; + private transient List> port_tuple_back_refs; + private transient List> analytics_alarm_node_back_refs; + private transient List> netconf_profile_back_refs; + private transient List> qos_queue_back_refs; + private transient List> physical_role_back_refs; + private transient List> card_back_refs; + private transient List> security_logging_object_back_refs; + private transient List> qos_config_back_refs; + private transient List> analytics_snmp_node_back_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> cli_config_back_refs; + private transient List> service_object_back_refs; + private transient List> loadbalancer_back_refs; + private transient List> peering_policy_back_refs; + private transient List> global_vrouter_config_back_refs; + private transient List> floating_ip_back_refs; + private transient List> link_aggregation_group_back_refs; + private transient List> virtual_router_back_refs; + private transient List> port_profile_back_refs; + private transient List> policy_management_back_refs; + private transient List> e2_service_provider_back_refs; + private transient List> fabric_back_refs; + private transient List> job_template_back_refs; + private transient List> routing_policy_back_refs; + private transient List> role_config_back_refs; + private transient List> tag_type_back_refs; + private transient List> loadbalancer_pool_back_refs; + private transient List> device_chassis_back_refs; + private transient List> global_qos_config_back_refs; + private transient List> analytics_node_back_refs; + private transient List> virtual_DNS_back_refs; + private transient List> config_database_node_back_refs; + private transient List> config_node_back_refs; + private transient List> device_functional_group_back_refs; + private transient List> firewall_rule_back_refs; + private transient List> bgpvpn_back_refs; + private transient List> role_definition_back_refs; + private transient List> service_connection_module_back_refs; + private transient List> security_group_back_refs; + private transient List> database_node_back_refs; + private transient List> loadbalancer_healthmonitor_back_refs; + private transient List> devicemgr_node_back_refs; + private transient List> project_back_refs; + private transient List> fabric_namespace_back_refs; + private transient List> network_ipam_back_refs; + private transient List> config_properties_back_refs; + private transient List> network_policy_back_refs; + private transient List> sflow_profile_back_refs; + private transient List> hardware_back_refs; + private transient List> tag_back_refs; + private transient List> feature_config_back_refs; + private transient List> telemetry_profile_back_refs; + private transient List> bgp_router_back_refs; + private transient List> virtual_network_back_refs; + private transient List> virtual_port_group_back_refs; + private transient List> service_appliance_back_refs; + private transient List> namespace_back_refs; + private transient List> feature_back_refs; + private transient List> storm_control_profile_back_refs; + private transient List> device_image_back_refs; + private transient List> physical_interface_back_refs; + private transient List> access_control_list_back_refs; + private transient List> snmp_profile_back_refs; + private transient List> node_back_refs; + private transient List> grpc_profile_back_refs; + private transient List> customer_attachment_back_refs; + private transient List> host_based_service_back_refs; + private transient List> virtual_machine_back_refs; + private transient List> interface_route_table_back_refs; + private transient List> loadbalancer_member_back_refs; + private transient List> service_health_check_back_refs; + private transient List> alarm_back_refs; + private transient List> api_access_list_back_refs; + private transient List> routing_instance_back_refs; + private transient List> alias_ip_pool_back_refs; + private transient List> data_center_interconnect_back_refs; + + @Override + public String getObjectType() { + return "tag"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(ConfigRoot parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public String getTypeName() { + return tag_type_name; + } + + public void setTypeName(String tag_type_name) { + this.tag_type_name = tag_type_name; + } + + + public String getValue() { + return tag_value; + } + + public void setValue(String tag_value) { + this.tag_value = tag_value; + } + + + public Boolean getPredefined() { + return tag_predefined; + } + + public void setPredefined(Boolean tag_predefined) { + this.tag_predefined = tag_predefined; + } + + + public String getId() { + return tag_id; + } + + public void setId(String tag_id) { + this.tag_id = tag_id; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTagType() { + return tag_type_refs; + } + + public void setTagType(TagType obj) { + tag_type_refs = new ArrayList>(); + tag_type_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTagType(TagType obj) { + if (tag_type_refs == null) { + tag_type_refs = new ArrayList>(); + } + tag_type_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTagType(TagType obj) { + if (tag_type_refs != null) { + tag_type_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTagType() { + if (tag_type_refs != null) { + tag_type_refs.clear(); + return; + } + tag_type_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getServiceEndpointBackRefs() { + return service_endpoint_back_refs; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } + + public List> getServiceApplianceSetBackRefs() { + return service_appliance_set_back_refs; + } + + public List> getRouteTargetBackRefs() { + return route_target_back_refs; + } + + public List> getLoadbalancerListenerBackRefs() { + return loadbalancer_listener_back_refs; + } + + public List> getFloatingIpPoolBackRefs() { + return floating_ip_pool_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getConfigRootBackRefs() { + return config_root_back_refs; + } + + public List> getServiceTemplateBackRefs() { + return service_template_back_refs; + } + + public List> getHardwareInventoryBackRefs() { + return hardware_inventory_back_refs; + } + + public List> getFirewallPolicyBackRefs() { + return firewall_policy_back_refs; + } + + public List> getRouteTableBackRefs() { + return route_table_back_refs; + } + + public List> getProviderAttachmentBackRefs() { + return provider_attachment_back_refs; + } + + public List> getOverlayRoleBackRefs() { + return overlay_role_back_refs; + } + + public List> getMulticastPolicyBackRefs() { + return multicast_policy_back_refs; + } + + public List> getNetworkDeviceConfigBackRefs() { + return network_device_config_back_refs; + } + + public List> getVirtualDnsRecordBackRefs() { + return virtual_DNS_record_back_refs; + } + + public List> getControlNodeZoneBackRefs() { + return control_node_zone_back_refs; + } + + public List> getDsaRuleBackRefs() { + return dsa_rule_back_refs; + } + + public List> getDiscoveryServiceAssignmentBackRefs() { + return discovery_service_assignment_back_refs; + } + + public List> getLogicalInterfaceBackRefs() { + return logical_interface_back_refs; + } + + public List> getFlowNodeBackRefs() { + return flow_node_back_refs; + } + + public List> getPortGroupBackRefs() { + return port_group_back_refs; + } + + public List> getRouteAggregateBackRefs() { + return route_aggregate_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } + + public List> getDomainBackRefs() { + return domain_back_refs; + } + + public List> getServiceInstanceBackRefs() { + return service_instance_back_refs; + } + + public List> getNodeProfileBackRefs() { + return node_profile_back_refs; + } + + public List> getBridgeDomainBackRefs() { + return bridge_domain_back_refs; + } + + public List> getAliasIpBackRefs() { + return alias_ip_back_refs; + } + + public List> getWebuiNodeBackRefs() { + return webui_node_back_refs; + } + + public List> getPortBackRefs() { + return port_back_refs; + } + + public List> getBgpAsAServiceBackRefs() { + return bgp_as_a_service_back_refs; + } + + public List> getSubnetBackRefs() { + return subnet_back_refs; + } + + public List> getGlobalSystemConfigBackRefs() { + return global_system_config_back_refs; + } + + public List> getSubClusterBackRefs() { + return sub_cluster_back_refs; + } + + public List> getForwardingClassBackRefs() { + return forwarding_class_back_refs; + } + + public List> getServiceGroupBackRefs() { + return service_group_back_refs; + } + + public List> getAddressGroupBackRefs() { + return address_group_back_refs; + } + + public List> getApplicationPolicySetBackRefs() { + return application_policy_set_back_refs; + } + + public List> getVirtualIpBackRefs() { + return virtual_ip_back_refs; + } + + public List> getIntentMapBackRefs() { + return intent_map_back_refs; + } + + public List> getPortTupleBackRefs() { + return port_tuple_back_refs; + } + + public List> getAnalyticsAlarmNodeBackRefs() { + return analytics_alarm_node_back_refs; + } + + public List> getNetconfProfileBackRefs() { + return netconf_profile_back_refs; + } + + public List> getQosQueueBackRefs() { + return qos_queue_back_refs; + } + + public List> getPhysicalRoleBackRefs() { + return physical_role_back_refs; + } + + public List> getCardBackRefs() { + return card_back_refs; + } + + public List> getSecurityLoggingObjectBackRefs() { + return security_logging_object_back_refs; + } + + public List> getQosConfigBackRefs() { + return qos_config_back_refs; + } + + public List> getAnalyticsSnmpNodeBackRefs() { + return analytics_snmp_node_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getCliConfigBackRefs() { + return cli_config_back_refs; + } + + public List> getServiceObjectBackRefs() { + return service_object_back_refs; + } + + public List> getLoadbalancerBackRefs() { + return loadbalancer_back_refs; + } + + public List> getPeeringPolicyBackRefs() { + return peering_policy_back_refs; + } + + public List> getGlobalVrouterConfigBackRefs() { + return global_vrouter_config_back_refs; + } + + public List> getFloatingIpBackRefs() { + return floating_ip_back_refs; + } + + public List> getLinkAggregationGroupBackRefs() { + return link_aggregation_group_back_refs; + } + + public List> getVirtualRouterBackRefs() { + return virtual_router_back_refs; + } + + public List> getPortProfileBackRefs() { + return port_profile_back_refs; + } + + public List> getPolicyManagementBackRefs() { + return policy_management_back_refs; + } + + public List> getE2ServiceProviderBackRefs() { + return e2_service_provider_back_refs; + } + + public List> getFabricBackRefs() { + return fabric_back_refs; + } + + public List> getJobTemplateBackRefs() { + return job_template_back_refs; + } + + public List> getRoutingPolicyBackRefs() { + return routing_policy_back_refs; + } + + public List> getRoleConfigBackRefs() { + return role_config_back_refs; + } + + public List> getTagTypeBackRefs() { + return tag_type_back_refs; + } + + public List> getLoadbalancerPoolBackRefs() { + return loadbalancer_pool_back_refs; + } + + public List> getDeviceChassisBackRefs() { + return device_chassis_back_refs; + } + + public List> getGlobalQosConfigBackRefs() { + return global_qos_config_back_refs; + } + + public List> getAnalyticsNodeBackRefs() { + return analytics_node_back_refs; + } + + public List> getVirtualDnsBackRefs() { + return virtual_DNS_back_refs; + } + + public List> getConfigDatabaseNodeBackRefs() { + return config_database_node_back_refs; + } + + public List> getConfigNodeBackRefs() { + return config_node_back_refs; + } + + public List> getDeviceFunctionalGroupBackRefs() { + return device_functional_group_back_refs; + } + + public List> getFirewallRuleBackRefs() { + return firewall_rule_back_refs; + } + + public List> getBgpvpnBackRefs() { + return bgpvpn_back_refs; + } + + public List> getRoleDefinitionBackRefs() { + return role_definition_back_refs; + } + + public List> getServiceConnectionModuleBackRefs() { + return service_connection_module_back_refs; + } + + public List> getSecurityGroupBackRefs() { + return security_group_back_refs; + } + + public List> getDatabaseNodeBackRefs() { + return database_node_back_refs; + } + + public List> getLoadbalancerHealthmonitorBackRefs() { + return loadbalancer_healthmonitor_back_refs; + } + + public List> getDevicemgrNodeBackRefs() { + return devicemgr_node_back_refs; + } + + public List> getProjectBackRefs() { + return project_back_refs; + } + + public List> getFabricNamespaceBackRefs() { + return fabric_namespace_back_refs; + } + + public List> getNetworkIpamBackRefs() { + return network_ipam_back_refs; + } + + public List> getConfigPropertiesBackRefs() { + return config_properties_back_refs; + } + + public List> getNetworkPolicyBackRefs() { + return network_policy_back_refs; + } + + public List> getSflowProfileBackRefs() { + return sflow_profile_back_refs; + } + + public List> getHardwareBackRefs() { + return hardware_back_refs; + } + + public List> getTagBackRefs() { + return tag_back_refs; + } + + public List> getFeatureConfigBackRefs() { + return feature_config_back_refs; + } + + public List> getTelemetryProfileBackRefs() { + return telemetry_profile_back_refs; + } + + public List> getBgpRouterBackRefs() { + return bgp_router_back_refs; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getVirtualPortGroupBackRefs() { + return virtual_port_group_back_refs; + } + + public List> getServiceApplianceBackRefs() { + return service_appliance_back_refs; + } + + public List> getNamespaceBackRefs() { + return namespace_back_refs; + } + + public List> getFeatureBackRefs() { + return feature_back_refs; + } + + public List> getStormControlProfileBackRefs() { + return storm_control_profile_back_refs; + } + + public List> getDeviceImageBackRefs() { + return device_image_back_refs; + } + + public List> getPhysicalInterfaceBackRefs() { + return physical_interface_back_refs; + } + + public List> getAccessControlListBackRefs() { + return access_control_list_back_refs; + } + + public List> getSnmpProfileBackRefs() { + return snmp_profile_back_refs; + } + + public List> getNodeBackRefs() { + return node_back_refs; + } + + public List> getGrpcProfileBackRefs() { + return grpc_profile_back_refs; + } + + public List> getCustomerAttachmentBackRefs() { + return customer_attachment_back_refs; + } + + public List> getHostBasedServiceBackRefs() { + return host_based_service_back_refs; + } + + public List> getVirtualMachineBackRefs() { + return virtual_machine_back_refs; + } + + public List> getInterfaceRouteTableBackRefs() { + return interface_route_table_back_refs; + } + + public List> getLoadbalancerMemberBackRefs() { + return loadbalancer_member_back_refs; + } + + public List> getServiceHealthCheckBackRefs() { + return service_health_check_back_refs; + } + + public List> getAlarmBackRefs() { + return alarm_back_refs; + } + + public List> getApiAccessListBackRefs() { + return api_access_list_back_refs; + } + + public List> getRoutingInstanceBackRefs() { + return routing_instance_back_refs; + } + + public List> getAliasIpPoolBackRefs() { + return alias_ip_pool_back_refs; + } + + public List> getDataCenterInterconnectBackRefs() { + return data_center_interconnect_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TagType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TagType.java new file mode 100644 index 00000000000..2858a4018ab --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TagType.java @@ -0,0 +1,116 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class TagType extends ApiObjectBase { + private String tag_type_id; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + private transient List> tag_back_refs; + + @Override + public String getObjectType() { + return "tag-type"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public String getId() { + return tag_type_id; + } + + public void setId(String tag_type_id) { + this.tag_type_id = tag_type_id; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getTagBackRefs() { + return tag_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryProfile.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryProfile.java new file mode 100644 index 00000000000..d5a2e30484a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryProfile.java @@ -0,0 +1,244 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class TelemetryProfile extends ApiObjectBase { + private Boolean telemetry_profile_is_default; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> sflow_profile_refs; + private List> grpc_profile_refs; + private List> netconf_profile_refs; + private List> snmp_profile_refs; + private List> tag_refs; + private transient List> physical_router_back_refs; + + @Override + public String getObjectType() { + return "telemetry-profile"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Boolean getIsDefault() { + return telemetry_profile_is_default; + } + + public void setIsDefault(Boolean telemetry_profile_is_default) { + this.telemetry_profile_is_default = telemetry_profile_is_default; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getSflowProfile() { + return sflow_profile_refs; + } + + public void setSflowProfile(SflowProfile obj) { + sflow_profile_refs = new ArrayList>(); + sflow_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSflowProfile(SflowProfile obj) { + if (sflow_profile_refs == null) { + sflow_profile_refs = new ArrayList>(); + } + sflow_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSflowProfile(SflowProfile obj) { + if (sflow_profile_refs != null) { + sflow_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSflowProfile() { + if (sflow_profile_refs != null) { + sflow_profile_refs.clear(); + return; + } + sflow_profile_refs = null; + } + + public List> getGrpcProfile() { + return grpc_profile_refs; + } + + public void setGrpcProfile(GrpcProfile obj) { + grpc_profile_refs = new ArrayList>(); + grpc_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addGrpcProfile(GrpcProfile obj) { + if (grpc_profile_refs == null) { + grpc_profile_refs = new ArrayList>(); + } + grpc_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeGrpcProfile(GrpcProfile obj) { + if (grpc_profile_refs != null) { + grpc_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearGrpcProfile() { + if (grpc_profile_refs != null) { + grpc_profile_refs.clear(); + return; + } + grpc_profile_refs = null; + } + + public List> getNetconfProfile() { + return netconf_profile_refs; + } + + public void setNetconfProfile(NetconfProfile obj) { + netconf_profile_refs = new ArrayList>(); + netconf_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addNetconfProfile(NetconfProfile obj) { + if (netconf_profile_refs == null) { + netconf_profile_refs = new ArrayList>(); + } + netconf_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeNetconfProfile(NetconfProfile obj) { + if (netconf_profile_refs != null) { + netconf_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearNetconfProfile() { + if (netconf_profile_refs != null) { + netconf_profile_refs.clear(); + return; + } + netconf_profile_refs = null; + } + + public List> getSnmpProfile() { + return snmp_profile_refs; + } + + public void setSnmpProfile(SnmpProfile obj) { + snmp_profile_refs = new ArrayList>(); + snmp_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSnmpProfile(SnmpProfile obj) { + if (snmp_profile_refs == null) { + snmp_profile_refs = new ArrayList>(); + } + snmp_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSnmpProfile(SnmpProfile obj) { + if (snmp_profile_refs != null) { + snmp_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSnmpProfile() { + if (snmp_profile_refs != null) { + snmp_profile_refs.clear(); + return; + } + snmp_profile_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryResourceInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryResourceInfo.java new file mode 100644 index 00000000000..6d4d2cb2ab5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryResourceInfo.java @@ -0,0 +1,50 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class TelemetryResourceInfo extends ApiPropertyBase { + String name; + String path; + String rate; + public TelemetryResourceInfo() { + } + public TelemetryResourceInfo(String name, String path, String rate) { + this.name = name; + this.path = path; + this.rate = rate; + } + public TelemetryResourceInfo(String name) { + this(name, null, null); } + public TelemetryResourceInfo(String name, String path) { + this(name, path, null); } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + + public String getRate() { + return rate; + } + + public void setRate(String rate) { + this.rate = rate; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryStateInfo.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryStateInfo.java new file mode 100644 index 00000000000..3a83a2d9c8c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TelemetryStateInfo.java @@ -0,0 +1,68 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class TelemetryStateInfo extends ApiPropertyBase { + List resource; + String server_ip; + Integer server_port; + public TelemetryStateInfo() { + } + public TelemetryStateInfo(List resource, String server_ip, Integer server_port) { + this.resource = resource; + this.server_ip = server_ip; + this.server_port = server_port; + } + public TelemetryStateInfo(List resource) { + this(resource, null, null); } + public TelemetryStateInfo(List resource, String server_ip) { + this(resource, server_ip, null); } + + public String getServerIp() { + return server_ip; + } + + public void setServerIp(String server_ip) { + this.server_ip = server_ip; + } + + + public Integer getServerPort() { + return server_port; + } + + public void setServerPort(Integer server_port) { + this.server_port = server_port; + } + + + public List getResource() { + return resource; + } + + + public void addResource(TelemetryResourceInfo obj) { + if (resource == null) { + resource = new ArrayList(); + } + resource.add(obj); + } + public void clearResource() { + resource = null; + } + + + public void addResource(String name, String path, String rate) { + if (resource == null) { + resource = new ArrayList(); + } + resource.add(new TelemetryResourceInfo(name, path, rate)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TimerType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TimerType.java new file mode 100644 index 00000000000..45cff071e16 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/TimerType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class TimerType extends ApiPropertyBase { + volatile java.util.Date start_time; + Long on_interval; + Long off_interval; + volatile java.util.Date end_time; + public TimerType() { + } + public TimerType(java.util.Date start_time, Long on_interval, Long off_interval, java.util.Date end_time) { + this.start_time = start_time; + this.on_interval = on_interval; + this.off_interval = off_interval; + this.end_time = end_time; + } + public TimerType(java.util.Date start_time) { + this(start_time, null, null, null); } + public TimerType(java.util.Date start_time, Long on_interval) { + this(start_time, on_interval, null, null); } + public TimerType(java.util.Date start_time, Long on_interval, Long off_interval) { + this(start_time, on_interval, off_interval, null); } + + public java.util.Date getStartTime() { + return start_time; + } + + public void setStartTime(java.util.Date start_time) { + this.start_time = start_time; + } + + + public Long getOnInterval() { + return on_interval; + } + + public void setOnInterval(Long on_interval) { + this.on_interval = on_interval; + } + + + public Long getOffInterval() { + return off_interval; + } + + public void setOffInterval(Long off_interval) { + this.off_interval = off_interval; + } + + + public java.util.Date getEndTime() { + return end_time; + } + + public void setEndTime(java.util.Date end_time) { + this.end_time = end_time; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserCredentials.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserCredentials.java new file mode 100644 index 00000000000..8ae604e991c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserCredentials.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class UserCredentials extends ApiPropertyBase { + String username; + String password; + public UserCredentials() { + } + public UserCredentials(String username, String password) { + this.username = username; + this.password = password; + } + public UserCredentials(String username) { + this(username, null); } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserDefinedLogStat.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserDefinedLogStat.java new file mode 100644 index 00000000000..3856fd8c691 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserDefinedLogStat.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class UserDefinedLogStat extends ApiPropertyBase { + String name; + String pattern; + public UserDefinedLogStat() { + } + public UserDefinedLogStat(String name, String pattern) { + this.name = name; + this.pattern = pattern; + } + public UserDefinedLogStat(String name) { + this(name, null); } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserDefinedLogStatList.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserDefinedLogStatList.java new file mode 100644 index 00000000000..24001176d19 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UserDefinedLogStatList.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class UserDefinedLogStatList extends ApiPropertyBase { + List statlist; + public UserDefinedLogStatList() { + } + public UserDefinedLogStatList(List statlist) { + this.statlist = statlist; + } + + public List getStatlist() { + return statlist; + } + + + public void addStatlist(UserDefinedLogStat obj) { + if (statlist == null) { + statlist = new ArrayList(); + } + statlist.add(obj); + } + public void clearStatlist() { + statlist = null; + } + + + public void addStatlist(String name, String pattern) { + if (statlist == null) { + statlist = new ArrayList(); + } + statlist.add(new UserDefinedLogStat(name, pattern)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UuidType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UuidType.java new file mode 100644 index 00000000000..959f435ec18 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UuidType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class UuidType extends ApiPropertyBase { + Long uuid_mslong; + Long uuid_lslong; + public UuidType() { + } + public UuidType(Long uuid_mslong, Long uuid_lslong) { + this.uuid_mslong = uuid_mslong; + this.uuid_lslong = uuid_lslong; + } + public UuidType(Long uuid_mslong) { + this(uuid_mslong, null); } + + public Long getUuidMslong() { + return uuid_mslong; + } + + public void setUuidMslong(Long uuid_mslong) { + this.uuid_mslong = uuid_mslong; + } + + + public Long getUuidLslong() { + return uuid_lslong; + } + + public void setUuidLslong(Long uuid_lslong) { + this.uuid_lslong = uuid_lslong; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UveKeysType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UveKeysType.java new file mode 100644 index 00000000000..fe328108a70 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/UveKeysType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class UveKeysType extends ApiPropertyBase { + List uve_key; + public UveKeysType() { + } + public UveKeysType(List uve_key) { + this.uve_key = uve_key; + } + + public List getUveKey() { + return uve_key; + } + + + public void addUveKey(String obj) { + if (uve_key == null) { + uve_key = new ArrayList(); + } + uve_key.add(obj); + } + public void clearUveKey() { + uve_key = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VMIVirtualPortGroupAttributes.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VMIVirtualPortGroupAttributes.java new file mode 100644 index 00000000000..662cf96f3a1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VMIVirtualPortGroupAttributes.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VMIVirtualPortGroupAttributes extends ApiPropertyBase { + Integer vlan_tag; + Integer native_vlan_tag; + public VMIVirtualPortGroupAttributes() { + } + public VMIVirtualPortGroupAttributes(Integer vlan_tag, Integer native_vlan_tag) { + this.vlan_tag = vlan_tag; + this.native_vlan_tag = native_vlan_tag; + } + public VMIVirtualPortGroupAttributes(Integer vlan_tag) { + this(vlan_tag, null); } + + public Integer getVlanTag() { + return vlan_tag; + } + + public void setVlanTag(Integer vlan_tag) { + this.vlan_tag = vlan_tag; + } + + + public Integer getNativeVlanTag() { + return native_vlan_tag; + } + + public void setNativeVlanTag(Integer native_vlan_tag) { + this.native_vlan_tag = native_vlan_tag; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VendorHardwaresType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VendorHardwaresType.java new file mode 100644 index 00000000000..650c8de3051 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VendorHardwaresType.java @@ -0,0 +1,34 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VendorHardwaresType extends ApiPropertyBase { + List vendor_hardware; + public VendorHardwaresType() { + } + public VendorHardwaresType(List vendor_hardware) { + this.vendor_hardware = vendor_hardware; + } + + public List getVendorHardware() { + return vendor_hardware; + } + + + public void addVendorHardware(String obj) { + if (vendor_hardware == null) { + vendor_hardware = new ArrayList(); + } + vendor_hardware.add(obj); + } + public void clearVendorHardware() { + vendor_hardware = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDns.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDns.java new file mode 100644 index 00000000000..2fd1a12fc2d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDns.java @@ -0,0 +1,125 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualDns extends ApiObjectBase { + private VirtualDnsType virtual_DNS_data; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_DNS_records; + private List> tag_refs; + private transient List> network_ipam_back_refs; + + @Override + public String getObjectType() { + return "virtual-DNS"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain"); + } + + @Override + public String getDefaultParentType() { + return "domain"; + } + + public void setParent(Domain parent) { + super.setParent(parent); + } + + public VirtualDnsType getData() { + return virtual_DNS_data; + } + + public void setData(VirtualDnsType virtual_DNS_data) { + this.virtual_DNS_data = virtual_DNS_data; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualDnsRecords() { + return virtual_DNS_records; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getNetworkIpamBackRefs() { + return network_ipam_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsRecord.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsRecord.java new file mode 100644 index 00000000000..327fe669e61 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsRecord.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualDnsRecord extends ApiObjectBase { + private VirtualDnsRecordType virtual_DNS_record_data; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "virtual-DNS-record"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-virtual-DNS"); + } + + @Override + public String getDefaultParentType() { + return "virtual-DNS"; + } + + public void setParent(VirtualDns parent) { + super.setParent(parent); + } + + public VirtualDnsRecordType getData() { + return virtual_DNS_record_data; + } + + public void setData(VirtualDnsRecordType virtual_DNS_record_data) { + this.virtual_DNS_record_data = virtual_DNS_record_data; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsRecordType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsRecordType.java new file mode 100644 index 00000000000..27d2ffaf8ea --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsRecordType.java @@ -0,0 +1,102 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualDnsRecordType extends ApiPropertyBase { + String record_name; + String record_type; + String record_class; + String record_data; + Integer record_ttl_seconds; + Integer record_mx_preference; + String record_source_name; + public VirtualDnsRecordType() { + } + public VirtualDnsRecordType(String record_name, String record_type, String record_class, String record_data, Integer record_ttl_seconds, Integer record_mx_preference, String record_source_name) { + this.record_name = record_name; + this.record_type = record_type; + this.record_class = record_class; + this.record_data = record_data; + this.record_ttl_seconds = record_ttl_seconds; + this.record_mx_preference = record_mx_preference; + this.record_source_name = record_source_name; + } + public VirtualDnsRecordType(String record_name) { + this(record_name, null, null, null, null, null, null); } + public VirtualDnsRecordType(String record_name, String record_type) { + this(record_name, record_type, null, null, null, null, null); } + public VirtualDnsRecordType(String record_name, String record_type, String record_class) { + this(record_name, record_type, record_class, null, null, null, null); } + public VirtualDnsRecordType(String record_name, String record_type, String record_class, String record_data) { + this(record_name, record_type, record_class, record_data, null, null, null); } + public VirtualDnsRecordType(String record_name, String record_type, String record_class, String record_data, Integer record_ttl_seconds) { + this(record_name, record_type, record_class, record_data, record_ttl_seconds, null, null); } + public VirtualDnsRecordType(String record_name, String record_type, String record_class, String record_data, Integer record_ttl_seconds, Integer record_mx_preference) { + this(record_name, record_type, record_class, record_data, record_ttl_seconds, record_mx_preference, null); } + + public String getRecordName() { + return record_name; + } + + public void setRecordName(String record_name) { + this.record_name = record_name; + } + + + public String getRecordType() { + return record_type; + } + + public void setRecordType(String record_type) { + this.record_type = record_type; + } + + + public String getRecordClass() { + return record_class; + } + + public void setRecordClass(String record_class) { + this.record_class = record_class; + } + + + public String getRecordData() { + return record_data; + } + + public void setRecordData(String record_data) { + this.record_data = record_data; + } + + + public Integer getRecordTtlSeconds() { + return record_ttl_seconds; + } + + public void setRecordTtlSeconds(Integer record_ttl_seconds) { + this.record_ttl_seconds = record_ttl_seconds; + } + + + public Integer getRecordMxPreference() { + return record_mx_preference; + } + + public void setRecordMxPreference(Integer record_mx_preference) { + this.record_mx_preference = record_mx_preference; + } + + + public String getRecordSourceName() { + return record_source_name; + } + + public void setRecordSourceName(String record_source_name) { + this.record_source_name = record_source_name; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsType.java new file mode 100644 index 00000000000..b82a0428b09 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualDnsType.java @@ -0,0 +1,128 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualDnsType extends ApiPropertyBase { + String domain_name; + Boolean dynamic_records_from_client; + String record_order; + Integer default_ttl_seconds; + String next_virtual_DNS; + String floating_ip_record; + Boolean external_visible; + Boolean reverse_resolution; + DnsSoaRecordType soa_record; + public VirtualDnsType() { + } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order, Integer default_ttl_seconds, String next_virtual_DNS, String floating_ip_record, Boolean external_visible, Boolean reverse_resolution, DnsSoaRecordType soa_record) { + this.domain_name = domain_name; + this.dynamic_records_from_client = dynamic_records_from_client; + this.record_order = record_order; + this.default_ttl_seconds = default_ttl_seconds; + this.next_virtual_DNS = next_virtual_DNS; + this.floating_ip_record = floating_ip_record; + this.external_visible = external_visible; + this.reverse_resolution = reverse_resolution; + this.soa_record = soa_record; + } + public VirtualDnsType(String domain_name) { + this(domain_name, null, "random", null, null, null, false, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client) { + this(domain_name, dynamic_records_from_client, "random", null, null, null, false, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order) { + this(domain_name, dynamic_records_from_client, record_order, null, null, null, false, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order, Integer default_ttl_seconds) { + this(domain_name, dynamic_records_from_client, record_order, default_ttl_seconds, null, null, false, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order, Integer default_ttl_seconds, String next_virtual_DNS) { + this(domain_name, dynamic_records_from_client, record_order, default_ttl_seconds, next_virtual_DNS, null, false, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order, Integer default_ttl_seconds, String next_virtual_DNS, String floating_ip_record) { + this(domain_name, dynamic_records_from_client, record_order, default_ttl_seconds, next_virtual_DNS, floating_ip_record, false, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order, Integer default_ttl_seconds, String next_virtual_DNS, String floating_ip_record, Boolean external_visible) { + this(domain_name, dynamic_records_from_client, record_order, default_ttl_seconds, next_virtual_DNS, floating_ip_record, external_visible, false, null); } + public VirtualDnsType(String domain_name, Boolean dynamic_records_from_client, String record_order, Integer default_ttl_seconds, String next_virtual_DNS, String floating_ip_record, Boolean external_visible, Boolean reverse_resolution) { + this(domain_name, dynamic_records_from_client, record_order, default_ttl_seconds, next_virtual_DNS, floating_ip_record, external_visible, reverse_resolution, null); } + + public String getDomainName() { + return domain_name; + } + + public void setDomainName(String domain_name) { + this.domain_name = domain_name; + } + + + public Boolean getDynamicRecordsFromClient() { + return dynamic_records_from_client; + } + + public void setDynamicRecordsFromClient(Boolean dynamic_records_from_client) { + this.dynamic_records_from_client = dynamic_records_from_client; + } + + + public String getRecordOrder() { + return record_order; + } + + public void setRecordOrder(String record_order) { + this.record_order = record_order; + } + + + public Integer getDefaultTtlSeconds() { + return default_ttl_seconds; + } + + public void setDefaultTtlSeconds(Integer default_ttl_seconds) { + this.default_ttl_seconds = default_ttl_seconds; + } + + + public String getNextVirtualDns() { + return next_virtual_DNS; + } + + public void setNextVirtualDns(String next_virtual_DNS) { + this.next_virtual_DNS = next_virtual_DNS; + } + + + public String getFloatingIpRecord() { + return floating_ip_record; + } + + public void setFloatingIpRecord(String floating_ip_record) { + this.floating_ip_record = floating_ip_record; + } + + + public Boolean getExternalVisible() { + return external_visible; + } + + public void setExternalVisible(Boolean external_visible) { + this.external_visible = external_visible; + } + + + public Boolean getReverseResolution() { + return reverse_resolution; + } + + public void setReverseResolution(Boolean reverse_resolution) { + this.reverse_resolution = reverse_resolution; + } + + + public DnsSoaRecordType getSoaRecord() { + return soa_record; + } + + public void setSoaRecord(DnsSoaRecordType soa_record) { + this.soa_record = soa_record; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualIp.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualIp.java new file mode 100644 index 00000000000..f01956a1ca0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualIp.java @@ -0,0 +1,177 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualIp extends ApiObjectBase { + private VirtualIpType virtual_ip_properties; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> loadbalancer_pool_refs; + private List> virtual_machine_interface_refs; + private List> tag_refs; + + @Override + public String getObjectType() { + return "virtual-ip"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public VirtualIpType getProperties() { + return virtual_ip_properties; + } + + public void setProperties(VirtualIpType virtual_ip_properties) { + this.virtual_ip_properties = virtual_ip_properties; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getLoadbalancerPool() { + return loadbalancer_pool_refs; + } + + public void setLoadbalancerPool(LoadbalancerPool obj) { + loadbalancer_pool_refs = new ArrayList>(); + loadbalancer_pool_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addLoadbalancerPool(LoadbalancerPool obj) { + if (loadbalancer_pool_refs == null) { + loadbalancer_pool_refs = new ArrayList>(); + } + loadbalancer_pool_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeLoadbalancerPool(LoadbalancerPool obj) { + if (loadbalancer_pool_refs != null) { + loadbalancer_pool_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearLoadbalancerPool() { + if (loadbalancer_pool_refs != null) { + loadbalancer_pool_refs.clear(); + return; + } + loadbalancer_pool_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualIpType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualIpType.java new file mode 100644 index 00000000000..7d4b4e0932c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualIpType.java @@ -0,0 +1,141 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualIpType extends ApiPropertyBase { + String address; + String status; + String status_description; + Boolean admin_state; + String protocol; + Integer protocol_port; + Integer connection_limit; + String subnet_id; + String persistence_cookie_name; + String persistence_type; + public VirtualIpType() { + } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state, String protocol, Integer protocol_port, Integer connection_limit, String subnet_id, String persistence_cookie_name, String persistence_type) { + this.address = address; + this.status = status; + this.status_description = status_description; + this.admin_state = admin_state; + this.protocol = protocol; + this.protocol_port = protocol_port; + this.connection_limit = connection_limit; + this.subnet_id = subnet_id; + this.persistence_cookie_name = persistence_cookie_name; + this.persistence_type = persistence_type; + } + public VirtualIpType(String address) { + this(address, null, null, true, null, null, null, null, null, null); } + public VirtualIpType(String address, String status) { + this(address, status, null, true, null, null, null, null, null, null); } + public VirtualIpType(String address, String status, String status_description) { + this(address, status, status_description, true, null, null, null, null, null, null); } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state) { + this(address, status, status_description, admin_state, null, null, null, null, null, null); } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state, String protocol) { + this(address, status, status_description, admin_state, protocol, null, null, null, null, null); } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state, String protocol, Integer protocol_port) { + this(address, status, status_description, admin_state, protocol, protocol_port, null, null, null, null); } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state, String protocol, Integer protocol_port, Integer connection_limit) { + this(address, status, status_description, admin_state, protocol, protocol_port, connection_limit, null, null, null); } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state, String protocol, Integer protocol_port, Integer connection_limit, String subnet_id) { + this(address, status, status_description, admin_state, protocol, protocol_port, connection_limit, subnet_id, null, null); } + public VirtualIpType(String address, String status, String status_description, Boolean admin_state, String protocol, Integer protocol_port, Integer connection_limit, String subnet_id, String persistence_cookie_name) { + this(address, status, status_description, admin_state, protocol, protocol_port, connection_limit, subnet_id, persistence_cookie_name, null); } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + + public String getStatusDescription() { + return status_description; + } + + public void setStatusDescription(String status_description) { + this.status_description = status_description; + } + + + public Boolean getAdminState() { + return admin_state; + } + + public void setAdminState(Boolean admin_state) { + this.admin_state = admin_state; + } + + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + + public Integer getProtocolPort() { + return protocol_port; + } + + public void setProtocolPort(Integer protocol_port) { + this.protocol_port = protocol_port; + } + + + public Integer getConnectionLimit() { + return connection_limit; + } + + public void setConnectionLimit(Integer connection_limit) { + this.connection_limit = connection_limit; + } + + + public String getSubnetId() { + return subnet_id; + } + + public void setSubnetId(String subnet_id) { + this.subnet_id = subnet_id; + } + + + public String getPersistenceCookieName() { + return persistence_cookie_name; + } + + public void setPersistenceCookieName(String persistence_cookie_name) { + this.persistence_cookie_name = persistence_cookie_name; + } + + + public String getPersistenceType() { + return persistence_type; + } + + public void setPersistenceType(String persistence_type) { + this.persistence_type = persistence_type; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachine.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachine.java new file mode 100644 index 00000000000..c3ea90dee7d --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachine.java @@ -0,0 +1,157 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualMachine extends ApiObjectBase { + private String server_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> virtual_machine_interfaces; + private List> service_instance_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> virtual_router_back_refs; + + @Override + public String getObjectType() { + return "virtual-machine"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList(); + } + + @Override + public String getDefaultParentType() { + return null; + } + + public String getServerType() { + return server_type; + } + + public void setServerType(String server_type) { + this.server_type = server_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getVirtualMachineInterfaces() { + return virtual_machine_interfaces; + } + + public List> getServiceInstance() { + return service_instance_refs; + } + + public void setServiceInstance(ServiceInstance obj) { + service_instance_refs = new ArrayList>(); + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceInstance(ServiceInstance obj) { + if (service_instance_refs == null) { + service_instance_refs = new ArrayList>(); + } + service_instance_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceInstance(ServiceInstance obj) { + if (service_instance_refs != null) { + service_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceInstance() { + if (service_instance_refs != null) { + service_instance_refs.clear(); + return; + } + service_instance_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getVirtualRouterBackRefs() { + return virtual_router_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachineInterface.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachineInterface.java new file mode 100644 index 00000000000..dc6f54adf7c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachineInterface.java @@ -0,0 +1,821 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualMachineInterface extends ApiObjectBase { + private EcmpHashingIncludeFields ecmp_hashing_include_fields; + private Boolean port_security_enabled; + private MacAddressesType virtual_machine_interface_mac_addresses; + private DhcpOptionsListType virtual_machine_interface_dhcp_option_list; + private RouteTableType virtual_machine_interface_host_routes; + private AllowedAddressPairs virtual_machine_interface_allowed_address_pairs; + private VrfAssignTableType vrf_assign_table; + private String virtual_machine_interface_device_owner; + private Boolean virtual_machine_interface_disable_policy; + private VirtualMachineInterfacePropertiesType virtual_machine_interface_properties; + private KeyValuePairs virtual_machine_interface_bindings; + private FatFlowProtocols virtual_machine_interface_fat_flow_protocols; + private Boolean vlan_tag_based_bridge_domain; + private Boolean igmp_enable; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> security_logging_object_refs; + private List> qos_config_refs; + private List> security_group_refs; + private List> virtual_machine_interface_refs; + private List> virtual_machine_refs; + private List> virtual_network_refs; + private List> routing_instance_refs; + private List> bgp_router_refs; + private List> port_tuple_refs; + private List> service_health_check_refs; + private List> interface_route_table_refs; + private List> physical_interface_refs; + private List> bridge_domain_refs; + private List> service_endpoint_refs; + private List> virtual_port_group_refs; + private List> port_profile_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> instance_ip_back_refs; + private transient List> subnet_back_refs; + private transient List> floating_ip_back_refs; + private transient List> alias_ip_back_refs; + private transient List> logical_interface_back_refs; + private transient List> bgp_as_a_service_back_refs; + private transient List> customer_attachment_back_refs; + private transient List> logical_router_back_refs; + private transient List> loadbalancer_pool_back_refs; + private transient List> virtual_ip_back_refs; + private transient List> loadbalancer_back_refs; + private transient List> virtual_port_group_back_refs; + private transient List> link_aggregation_group_back_refs; + + @Override + public String getObjectType() { + return "virtual-machine-interface"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(VirtualMachine parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public void setParent(VirtualRouter parent) { + super.setParent(parent); + } + + public EcmpHashingIncludeFields getEcmpHashingIncludeFields() { + return ecmp_hashing_include_fields; + } + + public void setEcmpHashingIncludeFields(EcmpHashingIncludeFields ecmp_hashing_include_fields) { + this.ecmp_hashing_include_fields = ecmp_hashing_include_fields; + } + + + public Boolean getPortSecurityEnabled() { + return port_security_enabled; + } + + public void setPortSecurityEnabled(Boolean port_security_enabled) { + this.port_security_enabled = port_security_enabled; + } + + + public MacAddressesType getMacAddresses() { + return virtual_machine_interface_mac_addresses; + } + + public void setMacAddresses(MacAddressesType virtual_machine_interface_mac_addresses) { + this.virtual_machine_interface_mac_addresses = virtual_machine_interface_mac_addresses; + } + + + public DhcpOptionsListType getDhcpOptionList() { + return virtual_machine_interface_dhcp_option_list; + } + + public void setDhcpOptionList(DhcpOptionsListType virtual_machine_interface_dhcp_option_list) { + this.virtual_machine_interface_dhcp_option_list = virtual_machine_interface_dhcp_option_list; + } + + + public RouteTableType getHostRoutes() { + return virtual_machine_interface_host_routes; + } + + public void setHostRoutes(RouteTableType virtual_machine_interface_host_routes) { + this.virtual_machine_interface_host_routes = virtual_machine_interface_host_routes; + } + + + public AllowedAddressPairs getAllowedAddressPairs() { + return virtual_machine_interface_allowed_address_pairs; + } + + public void setAllowedAddressPairs(AllowedAddressPairs virtual_machine_interface_allowed_address_pairs) { + this.virtual_machine_interface_allowed_address_pairs = virtual_machine_interface_allowed_address_pairs; + } + + + public VrfAssignTableType getVrfAssignTable() { + return vrf_assign_table; + } + + public void setVrfAssignTable(VrfAssignTableType vrf_assign_table) { + this.vrf_assign_table = vrf_assign_table; + } + + + public String getDeviceOwner() { + return virtual_machine_interface_device_owner; + } + + public void setDeviceOwner(String virtual_machine_interface_device_owner) { + this.virtual_machine_interface_device_owner = virtual_machine_interface_device_owner; + } + + + public Boolean getDisablePolicy() { + return virtual_machine_interface_disable_policy; + } + + public void setDisablePolicy(Boolean virtual_machine_interface_disable_policy) { + this.virtual_machine_interface_disable_policy = virtual_machine_interface_disable_policy; + } + + + public VirtualMachineInterfacePropertiesType getProperties() { + return virtual_machine_interface_properties; + } + + public void setProperties(VirtualMachineInterfacePropertiesType virtual_machine_interface_properties) { + this.virtual_machine_interface_properties = virtual_machine_interface_properties; + } + + + public KeyValuePairs getBindings() { + return virtual_machine_interface_bindings; + } + + public void setBindings(KeyValuePairs virtual_machine_interface_bindings) { + this.virtual_machine_interface_bindings = virtual_machine_interface_bindings; + } + + + public FatFlowProtocols getFatFlowProtocols() { + return virtual_machine_interface_fat_flow_protocols; + } + + public void setFatFlowProtocols(FatFlowProtocols virtual_machine_interface_fat_flow_protocols) { + this.virtual_machine_interface_fat_flow_protocols = virtual_machine_interface_fat_flow_protocols; + } + + + public Boolean getVlanTagBasedBridgeDomain() { + return vlan_tag_based_bridge_domain; + } + + public void setVlanTagBasedBridgeDomain(Boolean vlan_tag_based_bridge_domain) { + this.vlan_tag_based_bridge_domain = vlan_tag_based_bridge_domain; + } + + + public Boolean getIgmpEnable() { + return igmp_enable; + } + + public void setIgmpEnable(Boolean igmp_enable) { + this.igmp_enable = igmp_enable; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getSecurityLoggingObject() { + return security_logging_object_refs; + } + + public void setSecurityLoggingObject(SecurityLoggingObject obj) { + security_logging_object_refs = new ArrayList>(); + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSecurityLoggingObject(SecurityLoggingObject obj) { + if (security_logging_object_refs == null) { + security_logging_object_refs = new ArrayList>(); + } + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSecurityLoggingObject(SecurityLoggingObject obj) { + if (security_logging_object_refs != null) { + security_logging_object_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSecurityLoggingObject() { + if (security_logging_object_refs != null) { + security_logging_object_refs.clear(); + return; + } + security_logging_object_refs = null; + } + + public List> getQosConfig() { + return qos_config_refs; + } + + public void setQosConfig(QosConfig obj) { + qos_config_refs = new ArrayList>(); + qos_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addQosConfig(QosConfig obj) { + if (qos_config_refs == null) { + qos_config_refs = new ArrayList>(); + } + qos_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeQosConfig(QosConfig obj) { + if (qos_config_refs != null) { + qos_config_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearQosConfig() { + if (qos_config_refs != null) { + qos_config_refs.clear(); + return; + } + qos_config_refs = null; + } + + public List> getSecurityGroup() { + return security_group_refs; + } + + public void setSecurityGroup(SecurityGroup obj) { + security_group_refs = new ArrayList>(); + security_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSecurityGroup(SecurityGroup obj) { + if (security_group_refs == null) { + security_group_refs = new ArrayList>(); + } + security_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSecurityGroup(SecurityGroup obj) { + if (security_group_refs != null) { + security_group_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSecurityGroup() { + if (security_group_refs != null) { + security_group_refs.clear(); + return; + } + security_group_refs = null; + } + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getVirtualMachine() { + return virtual_machine_refs; + } + + public void setVirtualMachine(VirtualMachine obj) { + virtual_machine_refs = new ArrayList>(); + virtual_machine_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachine(VirtualMachine obj) { + if (virtual_machine_refs == null) { + virtual_machine_refs = new ArrayList>(); + } + virtual_machine_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachine(VirtualMachine obj) { + if (virtual_machine_refs != null) { + virtual_machine_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachine() { + if (virtual_machine_refs != null) { + virtual_machine_refs.clear(); + return; + } + virtual_machine_refs = null; + } + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getRoutingInstance() { + return routing_instance_refs; + } + + public void setRoutingInstance(RoutingInstance obj, PolicyBasedForwardingRuleType data) { + routing_instance_refs = new ArrayList>(); + routing_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addRoutingInstance(RoutingInstance obj, PolicyBasedForwardingRuleType data) { + if (routing_instance_refs == null) { + routing_instance_refs = new ArrayList>(); + } + routing_instance_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeRoutingInstance(RoutingInstance obj, PolicyBasedForwardingRuleType data) { + if (routing_instance_refs != null) { + routing_instance_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearRoutingInstance() { + if (routing_instance_refs != null) { + routing_instance_refs.clear(); + return; + } + routing_instance_refs = null; + } + + + public List> getBgpRouter() { + return bgp_router_refs; + } + + public void setBgpRouter(BgpRouter obj) { + bgp_router_refs = new ArrayList>(); + bgp_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addBgpRouter(BgpRouter obj) { + if (bgp_router_refs == null) { + bgp_router_refs = new ArrayList>(); + } + bgp_router_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeBgpRouter(BgpRouter obj) { + if (bgp_router_refs != null) { + bgp_router_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearBgpRouter() { + if (bgp_router_refs != null) { + bgp_router_refs.clear(); + return; + } + bgp_router_refs = null; + } + + public List> getPortTuple() { + return port_tuple_refs; + } + + public void setPortTuple(PortTuple obj) { + port_tuple_refs = new ArrayList>(); + port_tuple_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPortTuple(PortTuple obj) { + if (port_tuple_refs == null) { + port_tuple_refs = new ArrayList>(); + } + port_tuple_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePortTuple(PortTuple obj) { + if (port_tuple_refs != null) { + port_tuple_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPortTuple() { + if (port_tuple_refs != null) { + port_tuple_refs.clear(); + return; + } + port_tuple_refs = null; + } + + public List> getServiceHealthCheck() { + return service_health_check_refs; + } + + public void setServiceHealthCheck(ServiceHealthCheck obj) { + service_health_check_refs = new ArrayList>(); + service_health_check_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceHealthCheck(ServiceHealthCheck obj) { + if (service_health_check_refs == null) { + service_health_check_refs = new ArrayList>(); + } + service_health_check_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceHealthCheck(ServiceHealthCheck obj) { + if (service_health_check_refs != null) { + service_health_check_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceHealthCheck() { + if (service_health_check_refs != null) { + service_health_check_refs.clear(); + return; + } + service_health_check_refs = null; + } + + public List> getInterfaceRouteTable() { + return interface_route_table_refs; + } + + public void setInterfaceRouteTable(InterfaceRouteTable obj) { + interface_route_table_refs = new ArrayList>(); + interface_route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addInterfaceRouteTable(InterfaceRouteTable obj) { + if (interface_route_table_refs == null) { + interface_route_table_refs = new ArrayList>(); + } + interface_route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeInterfaceRouteTable(InterfaceRouteTable obj) { + if (interface_route_table_refs != null) { + interface_route_table_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearInterfaceRouteTable() { + if (interface_route_table_refs != null) { + interface_route_table_refs.clear(); + return; + } + interface_route_table_refs = null; + } + + public List> getPhysicalInterface() { + return physical_interface_refs; + } + + public void setPhysicalInterface(PhysicalInterface obj) { + physical_interface_refs = new ArrayList>(); + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPhysicalInterface(PhysicalInterface obj) { + if (physical_interface_refs == null) { + physical_interface_refs = new ArrayList>(); + } + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePhysicalInterface(PhysicalInterface obj) { + if (physical_interface_refs != null) { + physical_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPhysicalInterface() { + if (physical_interface_refs != null) { + physical_interface_refs.clear(); + return; + } + physical_interface_refs = null; + } + + public List> getBridgeDomain() { + return bridge_domain_refs; + } + + public void setBridgeDomain(BridgeDomain obj, BridgeDomainMembershipType data) { + bridge_domain_refs = new ArrayList>(); + bridge_domain_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addBridgeDomain(BridgeDomain obj, BridgeDomainMembershipType data) { + if (bridge_domain_refs == null) { + bridge_domain_refs = new ArrayList>(); + } + bridge_domain_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeBridgeDomain(BridgeDomain obj, BridgeDomainMembershipType data) { + if (bridge_domain_refs != null) { + bridge_domain_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearBridgeDomain() { + if (bridge_domain_refs != null) { + bridge_domain_refs.clear(); + return; + } + bridge_domain_refs = null; + } + + + public List> getServiceEndpoint() { + return service_endpoint_refs; + } + + public void setServiceEndpoint(ServiceEndpoint obj) { + service_endpoint_refs = new ArrayList>(); + service_endpoint_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceEndpoint(ServiceEndpoint obj) { + if (service_endpoint_refs == null) { + service_endpoint_refs = new ArrayList>(); + } + service_endpoint_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceEndpoint(ServiceEndpoint obj) { + if (service_endpoint_refs != null) { + service_endpoint_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceEndpoint() { + if (service_endpoint_refs != null) { + service_endpoint_refs.clear(); + return; + } + service_endpoint_refs = null; + } + + public List> getVirtualPortGroup() { + return virtual_port_group_refs; + } + + public void setVirtualPortGroup(VirtualPortGroup obj, VMIVirtualPortGroupAttributes data) { + virtual_port_group_refs = new ArrayList>(); + virtual_port_group_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addVirtualPortGroup(VirtualPortGroup obj, VMIVirtualPortGroupAttributes data) { + if (virtual_port_group_refs == null) { + virtual_port_group_refs = new ArrayList>(); + } + virtual_port_group_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeVirtualPortGroup(VirtualPortGroup obj, VMIVirtualPortGroupAttributes data) { + if (virtual_port_group_refs != null) { + virtual_port_group_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearVirtualPortGroup() { + if (virtual_port_group_refs != null) { + virtual_port_group_refs.clear(); + return; + } + virtual_port_group_refs = null; + } + + + public List> getPortProfile() { + return port_profile_refs; + } + + public void setPortProfile(PortProfile obj) { + port_profile_refs = new ArrayList>(); + port_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPortProfile(PortProfile obj) { + if (port_profile_refs == null) { + port_profile_refs = new ArrayList>(); + } + port_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePortProfile(PortProfile obj) { + if (port_profile_refs != null) { + port_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPortProfile() { + if (port_profile_refs != null) { + port_profile_refs.clear(); + return; + } + port_profile_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } + + public List> getSubnetBackRefs() { + return subnet_back_refs; + } + + public List> getFloatingIpBackRefs() { + return floating_ip_back_refs; + } + + public List> getAliasIpBackRefs() { + return alias_ip_back_refs; + } + + public List> getLogicalInterfaceBackRefs() { + return logical_interface_back_refs; + } + + public List> getBgpAsAServiceBackRefs() { + return bgp_as_a_service_back_refs; + } + + public List> getCustomerAttachmentBackRefs() { + return customer_attachment_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } + + public List> getLoadbalancerPoolBackRefs() { + return loadbalancer_pool_back_refs; + } + + public List> getVirtualIpBackRefs() { + return virtual_ip_back_refs; + } + + public List> getLoadbalancerBackRefs() { + return loadbalancer_back_refs; + } + + public List> getVirtualPortGroupBackRefs() { + return virtual_port_group_back_refs; + } + + public List> getLinkAggregationGroupBackRefs() { + return link_aggregation_group_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachineInterfacePropertiesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachineInterfacePropertiesType.java new file mode 100644 index 00000000000..f6fb36618a5 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualMachineInterfacePropertiesType.java @@ -0,0 +1,76 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualMachineInterfacePropertiesType extends ApiPropertyBase { + String service_interface_type; + InterfaceMirrorType interface_mirror; + Integer local_preference; + Integer sub_interface_vlan_tag; + Integer max_flows; + public VirtualMachineInterfacePropertiesType() { + } + public VirtualMachineInterfacePropertiesType(String service_interface_type, InterfaceMirrorType interface_mirror, Integer local_preference, Integer sub_interface_vlan_tag, Integer max_flows) { + this.service_interface_type = service_interface_type; + this.interface_mirror = interface_mirror; + this.local_preference = local_preference; + this.sub_interface_vlan_tag = sub_interface_vlan_tag; + this.max_flows = max_flows; + } + public VirtualMachineInterfacePropertiesType(String service_interface_type) { + this(service_interface_type, null, null, null, 0); } + public VirtualMachineInterfacePropertiesType(String service_interface_type, InterfaceMirrorType interface_mirror) { + this(service_interface_type, interface_mirror, null, null, 0); } + public VirtualMachineInterfacePropertiesType(String service_interface_type, InterfaceMirrorType interface_mirror, Integer local_preference) { + this(service_interface_type, interface_mirror, local_preference, null, 0); } + public VirtualMachineInterfacePropertiesType(String service_interface_type, InterfaceMirrorType interface_mirror, Integer local_preference, Integer sub_interface_vlan_tag) { + this(service_interface_type, interface_mirror, local_preference, sub_interface_vlan_tag, 0); } + + public String getServiceInterfaceType() { + return service_interface_type; + } + + public void setServiceInterfaceType(String service_interface_type) { + this.service_interface_type = service_interface_type; + } + + + public InterfaceMirrorType getInterfaceMirror() { + return interface_mirror; + } + + public void setInterfaceMirror(InterfaceMirrorType interface_mirror) { + this.interface_mirror = interface_mirror; + } + + + public Integer getLocalPreference() { + return local_preference; + } + + public void setLocalPreference(Integer local_preference) { + this.local_preference = local_preference; + } + + + public Integer getSubInterfaceVlanTag() { + return sub_interface_vlan_tag; + } + + public void setSubInterfaceVlanTag(Integer sub_interface_vlan_tag) { + this.sub_interface_vlan_tag = sub_interface_vlan_tag; + } + + + public Integer getMaxFlows() { + return max_flows; + } + + public void setMaxFlows(Integer max_flows) { + this.max_flows = max_flows; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetwork.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetwork.java new file mode 100644 index 00000000000..8178c102e46 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetwork.java @@ -0,0 +1,787 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualNetwork extends ApiObjectBase { + private EcmpHashingIncludeFields ecmp_hashing_include_fields; + private String virtual_network_category; + private VirtualNetworkType virtual_network_properties; + private VirtualNetworkRoutedPropertiesType virtual_network_routed_properties; + private ProviderDetails provider_properties; + private Integer virtual_network_network_id; + private Boolean is_provider_network; + private Boolean port_security_enabled; + private Boolean fabric_snat; + private RouteTargetList route_target_list; + private RouteTargetList import_route_target_list; + private RouteTargetList export_route_target_list; + private Boolean router_external; + private Boolean is_shared; + private Boolean external_ipam; + private Boolean flood_unknown_unicast; + private Boolean multi_policy_service_chains_enabled; + private String address_allocation_mode; + private IPSegmentType ip_segment; + private FatFlowProtocols virtual_network_fat_flow_protocols; + private Boolean mac_learning_enabled; + private MACLimitControlType mac_limit_control; + private MACMoveLimitControlType mac_move_control; + private Integer mac_aging_time; + private Boolean pbb_evpn_enable; + private Boolean pbb_etree_enable; + private Boolean layer2_control_word; + private Boolean igmp_enable; + private Boolean mac_ip_learning_enable; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> security_logging_object_refs; + private List> qos_config_refs; + private List> network_ipam_refs; + private List> network_policy_refs; + private List> virtual_network_refs; + private List> access_control_lists; + private List> floating_ip_pools; + private List> alias_ip_pools; + private List> routing_instances; + private List> service_health_check_refs; + private List> route_table_refs; + private List> bridge_domains; + private List> multicast_policy_refs; + private List> bgpvpn_refs; + private List> intent_map_refs; + private List> tag_refs; + private transient List> virtual_network_back_refs; + private transient List> virtual_machine_interface_back_refs; + private transient List> instance_ip_back_refs; + private transient List> physical_router_back_refs; + private transient List> port_tuple_back_refs; + private transient List> logical_router_back_refs; + private transient List> flow_node_back_refs; + private transient List> firewall_rule_back_refs; + private transient List> data_center_interconnect_back_refs; + private transient List> fabric_back_refs; + private transient List> host_based_service_back_refs; + + @Override + public String getObjectType() { + return "virtual-network"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-domain", "default-project"); + } + + @Override + public String getDefaultParentType() { + return "project"; + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public EcmpHashingIncludeFields getEcmpHashingIncludeFields() { + return ecmp_hashing_include_fields; + } + + public void setEcmpHashingIncludeFields(EcmpHashingIncludeFields ecmp_hashing_include_fields) { + this.ecmp_hashing_include_fields = ecmp_hashing_include_fields; + } + + + public String getCategory() { + return virtual_network_category; + } + + public void setCategory(String virtual_network_category) { + this.virtual_network_category = virtual_network_category; + } + + + public VirtualNetworkType getProperties() { + return virtual_network_properties; + } + + public void setProperties(VirtualNetworkType virtual_network_properties) { + this.virtual_network_properties = virtual_network_properties; + } + + + public VirtualNetworkRoutedPropertiesType getRoutedProperties() { + return virtual_network_routed_properties; + } + + public void setRoutedProperties(VirtualNetworkRoutedPropertiesType virtual_network_routed_properties) { + this.virtual_network_routed_properties = virtual_network_routed_properties; + } + + + public ProviderDetails getProviderProperties() { + return provider_properties; + } + + public void setProviderProperties(ProviderDetails provider_properties) { + this.provider_properties = provider_properties; + } + + + public Integer getNetworkId() { + return virtual_network_network_id; + } + + public void setNetworkId(Integer virtual_network_network_id) { + this.virtual_network_network_id = virtual_network_network_id; + } + + + public Boolean getIsProviderNetwork() { + return is_provider_network; + } + + public void setIsProviderNetwork(Boolean is_provider_network) { + this.is_provider_network = is_provider_network; + } + + + public Boolean getPortSecurityEnabled() { + return port_security_enabled; + } + + public void setPortSecurityEnabled(Boolean port_security_enabled) { + this.port_security_enabled = port_security_enabled; + } + + + public Boolean getFabricSnat() { + return fabric_snat; + } + + public void setFabricSnat(Boolean fabric_snat) { + this.fabric_snat = fabric_snat; + } + + + public RouteTargetList getRouteTargetList() { + return route_target_list; + } + + public void setRouteTargetList(RouteTargetList route_target_list) { + this.route_target_list = route_target_list; + } + + + public RouteTargetList getImportRouteTargetList() { + return import_route_target_list; + } + + public void setImportRouteTargetList(RouteTargetList import_route_target_list) { + this.import_route_target_list = import_route_target_list; + } + + + public RouteTargetList getExportRouteTargetList() { + return export_route_target_list; + } + + public void setExportRouteTargetList(RouteTargetList export_route_target_list) { + this.export_route_target_list = export_route_target_list; + } + + + public Boolean getRouterExternal() { + return router_external; + } + + public void setRouterExternal(Boolean router_external) { + this.router_external = router_external; + } + + + public Boolean getIsShared() { + return is_shared; + } + + public void setIsShared(Boolean is_shared) { + this.is_shared = is_shared; + } + + + public Boolean getExternalIpam() { + return external_ipam; + } + + public void setExternalIpam(Boolean external_ipam) { + this.external_ipam = external_ipam; + } + + + public Boolean getFloodUnknownUnicast() { + return flood_unknown_unicast; + } + + public void setFloodUnknownUnicast(Boolean flood_unknown_unicast) { + this.flood_unknown_unicast = flood_unknown_unicast; + } + + + public Boolean getMultiPolicyServiceChainsEnabled() { + return multi_policy_service_chains_enabled; + } + + public void setMultiPolicyServiceChainsEnabled(Boolean multi_policy_service_chains_enabled) { + this.multi_policy_service_chains_enabled = multi_policy_service_chains_enabled; + } + + + public String getAddressAllocationMode() { + return address_allocation_mode; + } + + public void setAddressAllocationMode(String address_allocation_mode) { + this.address_allocation_mode = address_allocation_mode; + } + + + public IPSegmentType getIpSegment() { + return ip_segment; + } + + public void setIpSegment(IPSegmentType ip_segment) { + this.ip_segment = ip_segment; + } + + + public FatFlowProtocols getFatFlowProtocols() { + return virtual_network_fat_flow_protocols; + } + + public void setFatFlowProtocols(FatFlowProtocols virtual_network_fat_flow_protocols) { + this.virtual_network_fat_flow_protocols = virtual_network_fat_flow_protocols; + } + + + public Boolean getMacLearningEnabled() { + return mac_learning_enabled; + } + + public void setMacLearningEnabled(Boolean mac_learning_enabled) { + this.mac_learning_enabled = mac_learning_enabled; + } + + + public MACLimitControlType getMacLimitControl() { + return mac_limit_control; + } + + public void setMacLimitControl(MACLimitControlType mac_limit_control) { + this.mac_limit_control = mac_limit_control; + } + + + public MACMoveLimitControlType getMacMoveControl() { + return mac_move_control; + } + + public void setMacMoveControl(MACMoveLimitControlType mac_move_control) { + this.mac_move_control = mac_move_control; + } + + + public Integer getMacAgingTime() { + return mac_aging_time; + } + + public void setMacAgingTime(Integer mac_aging_time) { + this.mac_aging_time = mac_aging_time; + } + + + public Boolean getPbbEvpnEnable() { + return pbb_evpn_enable; + } + + public void setPbbEvpnEnable(Boolean pbb_evpn_enable) { + this.pbb_evpn_enable = pbb_evpn_enable; + } + + + public Boolean getPbbEtreeEnable() { + return pbb_etree_enable; + } + + public void setPbbEtreeEnable(Boolean pbb_etree_enable) { + this.pbb_etree_enable = pbb_etree_enable; + } + + + public Boolean getLayer2ControlWord() { + return layer2_control_word; + } + + public void setLayer2ControlWord(Boolean layer2_control_word) { + this.layer2_control_word = layer2_control_word; + } + + + public Boolean getIgmpEnable() { + return igmp_enable; + } + + public void setIgmpEnable(Boolean igmp_enable) { + this.igmp_enable = igmp_enable; + } + + + public Boolean getMacIpLearningEnable() { + return mac_ip_learning_enable; + } + + public void setMacIpLearningEnable(Boolean mac_ip_learning_enable) { + this.mac_ip_learning_enable = mac_ip_learning_enable; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getSecurityLoggingObject() { + return security_logging_object_refs; + } + + public void setSecurityLoggingObject(SecurityLoggingObject obj) { + security_logging_object_refs = new ArrayList>(); + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSecurityLoggingObject(SecurityLoggingObject obj) { + if (security_logging_object_refs == null) { + security_logging_object_refs = new ArrayList>(); + } + security_logging_object_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSecurityLoggingObject(SecurityLoggingObject obj) { + if (security_logging_object_refs != null) { + security_logging_object_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSecurityLoggingObject() { + if (security_logging_object_refs != null) { + security_logging_object_refs.clear(); + return; + } + security_logging_object_refs = null; + } + + public List> getQosConfig() { + return qos_config_refs; + } + + public void setQosConfig(QosConfig obj) { + qos_config_refs = new ArrayList>(); + qos_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addQosConfig(QosConfig obj) { + if (qos_config_refs == null) { + qos_config_refs = new ArrayList>(); + } + qos_config_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeQosConfig(QosConfig obj) { + if (qos_config_refs != null) { + qos_config_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearQosConfig() { + if (qos_config_refs != null) { + qos_config_refs.clear(); + return; + } + qos_config_refs = null; + } + + public List> getNetworkIpam() { + return network_ipam_refs; + } + + public void setNetworkIpam(NetworkIpam obj, VnSubnetsType data) { + network_ipam_refs = new ArrayList>(); + network_ipam_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addNetworkIpam(NetworkIpam obj, VnSubnetsType data) { + if (network_ipam_refs == null) { + network_ipam_refs = new ArrayList>(); + } + network_ipam_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeNetworkIpam(NetworkIpam obj, VnSubnetsType data) { + if (network_ipam_refs != null) { + network_ipam_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearNetworkIpam() { + if (network_ipam_refs != null) { + network_ipam_refs.clear(); + return; + } + network_ipam_refs = null; + } + + + public List> getNetworkPolicy() { + return network_policy_refs; + } + + public void setNetworkPolicy(NetworkPolicy obj, VirtualNetworkPolicyType data) { + network_policy_refs = new ArrayList>(); + network_policy_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addNetworkPolicy(NetworkPolicy obj, VirtualNetworkPolicyType data) { + if (network_policy_refs == null) { + network_policy_refs = new ArrayList>(); + } + network_policy_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeNetworkPolicy(NetworkPolicy obj, VirtualNetworkPolicyType data) { + if (network_policy_refs != null) { + network_policy_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearNetworkPolicy() { + if (network_policy_refs != null) { + network_policy_refs.clear(); + return; + } + network_policy_refs = null; + } + + + public List> getVirtualNetwork() { + return virtual_network_refs; + } + + public void setVirtualNetwork(VirtualNetwork obj) { + virtual_network_refs = new ArrayList>(); + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs == null) { + virtual_network_refs = new ArrayList>(); + } + virtual_network_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualNetwork(VirtualNetwork obj) { + if (virtual_network_refs != null) { + virtual_network_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualNetwork() { + if (virtual_network_refs != null) { + virtual_network_refs.clear(); + return; + } + virtual_network_refs = null; + } + + public List> getAccessControlLists() { + return access_control_lists; + } + + public List> getFloatingIpPools() { + return floating_ip_pools; + } + + public List> getAliasIpPools() { + return alias_ip_pools; + } + + public List> getRoutingInstances() { + return routing_instances; + } + + public List> getServiceHealthCheck() { + return service_health_check_refs; + } + + public void setServiceHealthCheck(ServiceHealthCheck obj) { + service_health_check_refs = new ArrayList>(); + service_health_check_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addServiceHealthCheck(ServiceHealthCheck obj) { + if (service_health_check_refs == null) { + service_health_check_refs = new ArrayList>(); + } + service_health_check_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeServiceHealthCheck(ServiceHealthCheck obj) { + if (service_health_check_refs != null) { + service_health_check_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearServiceHealthCheck() { + if (service_health_check_refs != null) { + service_health_check_refs.clear(); + return; + } + service_health_check_refs = null; + } + + public List> getRouteTable() { + return route_table_refs; + } + + public void setRouteTable(RouteTable obj) { + route_table_refs = new ArrayList>(); + route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addRouteTable(RouteTable obj) { + if (route_table_refs == null) { + route_table_refs = new ArrayList>(); + } + route_table_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeRouteTable(RouteTable obj) { + if (route_table_refs != null) { + route_table_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearRouteTable() { + if (route_table_refs != null) { + route_table_refs.clear(); + return; + } + route_table_refs = null; + } + + public List> getBridgeDomains() { + return bridge_domains; + } + + public List> getMulticastPolicy() { + return multicast_policy_refs; + } + + public void setMulticastPolicy(MulticastPolicy obj) { + multicast_policy_refs = new ArrayList>(); + multicast_policy_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addMulticastPolicy(MulticastPolicy obj) { + if (multicast_policy_refs == null) { + multicast_policy_refs = new ArrayList>(); + } + multicast_policy_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeMulticastPolicy(MulticastPolicy obj) { + if (multicast_policy_refs != null) { + multicast_policy_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearMulticastPolicy() { + if (multicast_policy_refs != null) { + multicast_policy_refs.clear(); + return; + } + multicast_policy_refs = null; + } + + public List> getBgpvpn() { + return bgpvpn_refs; + } + + public void setBgpvpn(Bgpvpn obj) { + bgpvpn_refs = new ArrayList>(); + bgpvpn_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addBgpvpn(Bgpvpn obj) { + if (bgpvpn_refs == null) { + bgpvpn_refs = new ArrayList>(); + } + bgpvpn_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeBgpvpn(Bgpvpn obj) { + if (bgpvpn_refs != null) { + bgpvpn_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearBgpvpn() { + if (bgpvpn_refs != null) { + bgpvpn_refs.clear(); + return; + } + bgpvpn_refs = null; + } + + public List> getIntentMap() { + return intent_map_refs; + } + + public void setIntentMap(IntentMap obj) { + intent_map_refs = new ArrayList>(); + intent_map_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addIntentMap(IntentMap obj) { + if (intent_map_refs == null) { + intent_map_refs = new ArrayList>(); + } + intent_map_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeIntentMap(IntentMap obj) { + if (intent_map_refs != null) { + intent_map_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearIntentMap() { + if (intent_map_refs != null) { + intent_map_refs.clear(); + return; + } + intent_map_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualNetworkBackRefs() { + return virtual_network_back_refs; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getPortTupleBackRefs() { + return port_tuple_back_refs; + } + + public List> getLogicalRouterBackRefs() { + return logical_router_back_refs; + } + + public List> getFlowNodeBackRefs() { + return flow_node_back_refs; + } + + public List> getFirewallRuleBackRefs() { + return firewall_rule_back_refs; + } + + public List> getDataCenterInterconnectBackRefs() { + return data_center_interconnect_back_refs; + } + + public List> getFabricBackRefs() { + return fabric_back_refs; + } + + public List> getHostBasedServiceBackRefs() { + return host_based_service_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkPolicyType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkPolicyType.java new file mode 100644 index 00000000000..87cf067707a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkPolicyType.java @@ -0,0 +1,37 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualNetworkPolicyType extends ApiPropertyBase { + SequenceType sequence; + TimerType timer; + public VirtualNetworkPolicyType() { + } + public VirtualNetworkPolicyType(SequenceType sequence, TimerType timer) { + this.sequence = sequence; + this.timer = timer; + } + public VirtualNetworkPolicyType(SequenceType sequence) { + this(sequence, null); } + + public SequenceType getSequence() { + return sequence; + } + + public void setSequence(SequenceType sequence) { + this.sequence = sequence; + } + + + public TimerType getTimer() { + return timer; + } + + public void setTimer(TimerType timer) { + this.timer = timer; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkRoutedPropertiesType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkRoutedPropertiesType.java new file mode 100644 index 00000000000..6810cfe72d2 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkRoutedPropertiesType.java @@ -0,0 +1,47 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualNetworkRoutedPropertiesType extends ApiPropertyBase { + List routed_properties; + Boolean shared_across_all_lrs; + public VirtualNetworkRoutedPropertiesType() { + } + public VirtualNetworkRoutedPropertiesType(List routed_properties, Boolean shared_across_all_lrs) { + this.routed_properties = routed_properties; + this.shared_across_all_lrs = shared_across_all_lrs; + } + public VirtualNetworkRoutedPropertiesType(List routed_properties) { + this(routed_properties, false); } + + public Boolean getSharedAcrossAllLrs() { + return shared_across_all_lrs; + } + + public void setSharedAcrossAllLrs(Boolean shared_across_all_lrs) { + this.shared_across_all_lrs = shared_across_all_lrs; + } + + + public List getRoutedProperties() { + return routed_properties; + } + + + public void addRoutedProperties(RoutedProperties obj) { + if (routed_properties == null) { + routed_properties = new ArrayList(); + } + routed_properties.add(obj); + } + public void clearRoutedProperties() { + routed_properties = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkType.java new file mode 100644 index 00000000000..41dffd78b49 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualNetworkType.java @@ -0,0 +1,102 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualNetworkType extends ApiPropertyBase { + Boolean allow_transit; + Integer network_id; + Integer vxlan_network_identifier; + String forwarding_mode; + String rpf; + Boolean mirror_destination; + Integer max_flows; + public VirtualNetworkType() { + } + public VirtualNetworkType(Boolean allow_transit, Integer network_id, Integer vxlan_network_identifier, String forwarding_mode, String rpf, Boolean mirror_destination, Integer max_flows) { + this.allow_transit = allow_transit; + this.network_id = network_id; + this.vxlan_network_identifier = vxlan_network_identifier; + this.forwarding_mode = forwarding_mode; + this.rpf = rpf; + this.mirror_destination = mirror_destination; + this.max_flows = max_flows; + } + public VirtualNetworkType(Boolean allow_transit) { + this(allow_transit, null, null, null, null, false, 0); } + public VirtualNetworkType(Boolean allow_transit, Integer network_id) { + this(allow_transit, network_id, null, null, null, false, 0); } + public VirtualNetworkType(Boolean allow_transit, Integer network_id, Integer vxlan_network_identifier) { + this(allow_transit, network_id, vxlan_network_identifier, null, null, false, 0); } + public VirtualNetworkType(Boolean allow_transit, Integer network_id, Integer vxlan_network_identifier, String forwarding_mode) { + this(allow_transit, network_id, vxlan_network_identifier, forwarding_mode, null, false, 0); } + public VirtualNetworkType(Boolean allow_transit, Integer network_id, Integer vxlan_network_identifier, String forwarding_mode, String rpf) { + this(allow_transit, network_id, vxlan_network_identifier, forwarding_mode, rpf, false, 0); } + public VirtualNetworkType(Boolean allow_transit, Integer network_id, Integer vxlan_network_identifier, String forwarding_mode, String rpf, Boolean mirror_destination) { + this(allow_transit, network_id, vxlan_network_identifier, forwarding_mode, rpf, mirror_destination, 0); } + + public Boolean getAllowTransit() { + return allow_transit; + } + + public void setAllowTransit(Boolean allow_transit) { + this.allow_transit = allow_transit; + } + + + public Integer getNetworkId() { + return network_id; + } + + public void setNetworkId(Integer network_id) { + this.network_id = network_id; + } + + + public Integer getVxlanNetworkIdentifier() { + return vxlan_network_identifier; + } + + public void setVxlanNetworkIdentifier(Integer vxlan_network_identifier) { + this.vxlan_network_identifier = vxlan_network_identifier; + } + + + public String getForwardingMode() { + return forwarding_mode; + } + + public void setForwardingMode(String forwarding_mode) { + this.forwarding_mode = forwarding_mode; + } + + + public String getRpf() { + return rpf; + } + + public void setRpf(String rpf) { + this.rpf = rpf; + } + + + public Boolean getMirrorDestination() { + return mirror_destination; + } + + public void setMirrorDestination(Boolean mirror_destination) { + this.mirror_destination = mirror_destination; + } + + + public Integer getMaxFlows() { + return max_flows; + } + + public void setMaxFlows(Integer max_flows) { + this.max_flows = max_flows; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualPortGroup.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualPortGroup.java new file mode 100644 index 00000000000..e2cb3124557 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualPortGroup.java @@ -0,0 +1,278 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualPortGroup extends ApiObjectBase { + private Boolean virtual_port_group_lacp_enabled; + private String virtual_port_group_trunk_port_id; + private Boolean virtual_port_group_user_created; + private String virtual_port_group_type; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> physical_interface_refs; + private List> virtual_machine_interface_refs; + private List> security_group_refs; + private List> port_profile_refs; + private List> tag_refs; + private transient List> virtual_machine_interface_back_refs; + + @Override + public String getObjectType() { + return "virtual-port-group"; + } + + @Override + public List getDefaultParent() { + return null; + } + + @Override + public String getDefaultParentType() { + return null; + } + + public void setParent(Fabric parent) { + super.setParent(parent); + } + + public void setParent(Project parent) { + super.setParent(parent); + } + + public Boolean getLacpEnabled() { + return virtual_port_group_lacp_enabled; + } + + public void setLacpEnabled(Boolean virtual_port_group_lacp_enabled) { + this.virtual_port_group_lacp_enabled = virtual_port_group_lacp_enabled; + } + + + public String getTrunkPortId() { + return virtual_port_group_trunk_port_id; + } + + public void setTrunkPortId(String virtual_port_group_trunk_port_id) { + this.virtual_port_group_trunk_port_id = virtual_port_group_trunk_port_id; + } + + + public Boolean getUserCreated() { + return virtual_port_group_user_created; + } + + public void setUserCreated(Boolean virtual_port_group_user_created) { + this.virtual_port_group_user_created = virtual_port_group_user_created; + } + + + public String getType() { + return virtual_port_group_type; + } + + public void setType(String virtual_port_group_type) { + this.virtual_port_group_type = virtual_port_group_type; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getPhysicalInterface() { + return physical_interface_refs; + } + + public void setPhysicalInterface(PhysicalInterface obj, VpgInterfaceParametersType data) { + physical_interface_refs = new ArrayList>(); + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addPhysicalInterface(PhysicalInterface obj, VpgInterfaceParametersType data) { + if (physical_interface_refs == null) { + physical_interface_refs = new ArrayList>(); + } + physical_interface_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removePhysicalInterface(PhysicalInterface obj, VpgInterfaceParametersType data) { + if (physical_interface_refs != null) { + physical_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearPhysicalInterface() { + if (physical_interface_refs != null) { + physical_interface_refs.clear(); + return; + } + physical_interface_refs = null; + } + + + public List> getVirtualMachineInterface() { + return virtual_machine_interface_refs; + } + + public void setVirtualMachineInterface(VirtualMachineInterface obj) { + virtual_machine_interface_refs = new ArrayList>(); + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs == null) { + virtual_machine_interface_refs = new ArrayList>(); + } + virtual_machine_interface_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachineInterface(VirtualMachineInterface obj) { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachineInterface() { + if (virtual_machine_interface_refs != null) { + virtual_machine_interface_refs.clear(); + return; + } + virtual_machine_interface_refs = null; + } + + public List> getSecurityGroup() { + return security_group_refs; + } + + public void setSecurityGroup(SecurityGroup obj) { + security_group_refs = new ArrayList>(); + security_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSecurityGroup(SecurityGroup obj) { + if (security_group_refs == null) { + security_group_refs = new ArrayList>(); + } + security_group_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSecurityGroup(SecurityGroup obj) { + if (security_group_refs != null) { + security_group_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSecurityGroup() { + if (security_group_refs != null) { + security_group_refs.clear(); + return; + } + security_group_refs = null; + } + + public List> getPortProfile() { + return port_profile_refs; + } + + public void setPortProfile(PortProfile obj) { + port_profile_refs = new ArrayList>(); + port_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addPortProfile(PortProfile obj) { + if (port_profile_refs == null) { + port_profile_refs = new ArrayList>(); + } + port_profile_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removePortProfile(PortProfile obj) { + if (port_profile_refs != null) { + port_profile_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearPortProfile() { + if (port_profile_refs != null) { + port_profile_refs.clear(); + return; + } + port_profile_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getVirtualMachineInterfaceBackRefs() { + return virtual_machine_interface_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualRouter.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualRouter.java new file mode 100644 index 00000000000..f8af509edf9 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualRouter.java @@ -0,0 +1,259 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class VirtualRouter extends ApiObjectBase { + private String virtual_router_type; + private Boolean virtual_router_dpdk_enabled; + private KeyValuePairs virtual_router_sriov_physical_networks; + private String virtual_router_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> network_ipam_refs; + private List> virtual_machine_interfaces; + private List> sub_cluster_refs; + private List> virtual_machine_refs; + private List> tag_refs; + private transient List> instance_ip_back_refs; + private transient List> physical_router_back_refs; + private transient List> provider_attachment_back_refs; + + @Override + public String getObjectType() { + return "virtual-router"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getType() { + return virtual_router_type; + } + + public void setType(String virtual_router_type) { + this.virtual_router_type = virtual_router_type; + } + + + public Boolean getDpdkEnabled() { + return virtual_router_dpdk_enabled; + } + + public void setDpdkEnabled(Boolean virtual_router_dpdk_enabled) { + this.virtual_router_dpdk_enabled = virtual_router_dpdk_enabled; + } + + + public KeyValuePairs getSriovPhysicalNetworks() { + return virtual_router_sriov_physical_networks; + } + + public void setSriovPhysicalNetworks(KeyValuePairs virtual_router_sriov_physical_networks) { + this.virtual_router_sriov_physical_networks = virtual_router_sriov_physical_networks; + } + + + public String getIpAddress() { + return virtual_router_ip_address; + } + + public void setIpAddress(String virtual_router_ip_address) { + this.virtual_router_ip_address = virtual_router_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getNetworkIpam() { + return network_ipam_refs; + } + + public void setNetworkIpam(NetworkIpam obj, VirtualRouterNetworkIpamType data) { + network_ipam_refs = new ArrayList>(); + network_ipam_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void addNetworkIpam(NetworkIpam obj, VirtualRouterNetworkIpamType data) { + if (network_ipam_refs == null) { + network_ipam_refs = new ArrayList>(); + } + network_ipam_refs.add(new ObjectReference(obj.getQualifiedName(), data)); + } + + public void removeNetworkIpam(NetworkIpam obj, VirtualRouterNetworkIpamType data) { + if (network_ipam_refs != null) { + network_ipam_refs.remove(new ObjectReference(obj.getQualifiedName(), data)); + } + } + + public void clearNetworkIpam() { + if (network_ipam_refs != null) { + network_ipam_refs.clear(); + return; + } + network_ipam_refs = null; + } + + + public List> getVirtualMachineInterfaces() { + return virtual_machine_interfaces; + } + + public List> getSubCluster() { + return sub_cluster_refs; + } + + public void setSubCluster(SubCluster obj) { + sub_cluster_refs = new ArrayList>(); + sub_cluster_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addSubCluster(SubCluster obj) { + if (sub_cluster_refs == null) { + sub_cluster_refs = new ArrayList>(); + } + sub_cluster_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeSubCluster(SubCluster obj) { + if (sub_cluster_refs != null) { + sub_cluster_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearSubCluster() { + if (sub_cluster_refs != null) { + sub_cluster_refs.clear(); + return; + } + sub_cluster_refs = null; + } + + public List> getVirtualMachine() { + return virtual_machine_refs; + } + + public void setVirtualMachine(VirtualMachine obj) { + virtual_machine_refs = new ArrayList>(); + virtual_machine_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addVirtualMachine(VirtualMachine obj) { + if (virtual_machine_refs == null) { + virtual_machine_refs = new ArrayList>(); + } + virtual_machine_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeVirtualMachine(VirtualMachine obj) { + if (virtual_machine_refs != null) { + virtual_machine_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearVirtualMachine() { + if (virtual_machine_refs != null) { + virtual_machine_refs.clear(); + return; + } + virtual_machine_refs = null; + } + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } + + public List> getInstanceIpBackRefs() { + return instance_ip_back_refs; + } + + public List> getPhysicalRouterBackRefs() { + return physical_router_back_refs; + } + + public List> getProviderAttachmentBackRefs() { + return provider_attachment_back_refs; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualRouterNetworkIpamType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualRouterNetworkIpamType.java new file mode 100644 index 00000000000..fb080fa061a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VirtualRouterNetworkIpamType.java @@ -0,0 +1,70 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VirtualRouterNetworkIpamType extends ApiPropertyBase { + List allocation_pools; + List subnet; + public VirtualRouterNetworkIpamType() { + } + public VirtualRouterNetworkIpamType(List allocation_pools, List subnet) { + this.allocation_pools = allocation_pools; + this.subnet = subnet; + } + public VirtualRouterNetworkIpamType(List allocation_pools) { + this(allocation_pools, null); } + + public List getAllocationPools() { + return allocation_pools; + } + + + public void addAllocationPools(AllocationPoolType obj) { + if (allocation_pools == null) { + allocation_pools = new ArrayList(); + } + allocation_pools.add(obj); + } + public void clearAllocationPools() { + allocation_pools = null; + } + + + public void addAllocationPools(String start, String end, Boolean vrouter_specific_pool) { + if (allocation_pools == null) { + allocation_pools = new ArrayList(); + } + allocation_pools.add(new AllocationPoolType(start, end, vrouter_specific_pool)); + } + + + public List getSubnet() { + return subnet; + } + + + public void addSubnet(SubnetType obj) { + if (subnet == null) { + subnet = new ArrayList(); + } + subnet.add(obj); + } + public void clearSubnet() { + subnet = null; + } + + + public void addSubnet(String ip_prefix, Integer ip_prefix_len) { + if (subnet == null) { + subnet = new ArrayList(); + } + subnet.add(new SubnetType(ip_prefix, ip_prefix_len)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VnSubnetsType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VnSubnetsType.java new file mode 100644 index 00000000000..43544569229 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VnSubnetsType.java @@ -0,0 +1,47 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VnSubnetsType extends ApiPropertyBase { + List ipam_subnets; + RouteTableType host_routes; + public VnSubnetsType() { + } + public VnSubnetsType(List ipam_subnets, RouteTableType host_routes) { + this.ipam_subnets = ipam_subnets; + this.host_routes = host_routes; + } + public VnSubnetsType(List ipam_subnets) { + this(ipam_subnets, null); } + + public RouteTableType getHostRoutes() { + return host_routes; + } + + public void setHostRoutes(RouteTableType host_routes) { + this.host_routes = host_routes; + } + + + public List getIpamSubnets() { + return ipam_subnets; + } + + + public void addIpamSubnets(IpamSubnetType obj) { + if (ipam_subnets == null) { + ipam_subnets = new ArrayList(); + } + ipam_subnets.add(obj); + } + public void clearIpamSubnets() { + ipam_subnets = null; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VpgInterfaceParametersType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VpgInterfaceParametersType.java new file mode 100644 index 00000000000..00f619ff866 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VpgInterfaceParametersType.java @@ -0,0 +1,24 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VpgInterfaceParametersType extends ApiPropertyBase { + Integer ae_num; + public VpgInterfaceParametersType() { + } + public VpgInterfaceParametersType(Integer ae_num) { + this.ae_num = ae_num; + } + + public Integer getAeNum() { + return ae_num; + } + + public void setAeNum(Integer ae_num) { + this.ae_num = ae_num; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VrfAssignRuleType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VrfAssignRuleType.java new file mode 100644 index 00000000000..aa5f3ecf5e8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VrfAssignRuleType.java @@ -0,0 +1,63 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VrfAssignRuleType extends ApiPropertyBase { + MatchConditionType match_condition; + Integer vlan_tag; + String routing_instance; + Boolean ignore_acl; + public VrfAssignRuleType() { + } + public VrfAssignRuleType(MatchConditionType match_condition, Integer vlan_tag, String routing_instance, Boolean ignore_acl) { + this.match_condition = match_condition; + this.vlan_tag = vlan_tag; + this.routing_instance = routing_instance; + this.ignore_acl = ignore_acl; + } + public VrfAssignRuleType(MatchConditionType match_condition) { + this(match_condition, null, null, null); } + public VrfAssignRuleType(MatchConditionType match_condition, Integer vlan_tag) { + this(match_condition, vlan_tag, null, null); } + public VrfAssignRuleType(MatchConditionType match_condition, Integer vlan_tag, String routing_instance) { + this(match_condition, vlan_tag, routing_instance, null); } + + public MatchConditionType getMatchCondition() { + return match_condition; + } + + public void setMatchCondition(MatchConditionType match_condition) { + this.match_condition = match_condition; + } + + + public Integer getVlanTag() { + return vlan_tag; + } + + public void setVlanTag(Integer vlan_tag) { + this.vlan_tag = vlan_tag; + } + + + public String getRoutingInstance() { + return routing_instance; + } + + public void setRoutingInstance(String routing_instance) { + this.routing_instance = routing_instance; + } + + + public Boolean getIgnoreAcl() { + return ignore_acl; + } + + public void setIgnoreAcl(Boolean ignore_acl) { + this.ignore_acl = ignore_acl; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VrfAssignTableType.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VrfAssignTableType.java new file mode 100644 index 00000000000..19af9584008 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/VrfAssignTableType.java @@ -0,0 +1,42 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; + +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; + +public class VrfAssignTableType extends ApiPropertyBase { + List vrf_assign_rule; + public VrfAssignTableType() { + } + public VrfAssignTableType(List vrf_assign_rule) { + this.vrf_assign_rule = vrf_assign_rule; + } + + public List getVrfAssignRule() { + return vrf_assign_rule; + } + + + public void addVrfAssignRule(VrfAssignRuleType obj) { + if (vrf_assign_rule == null) { + vrf_assign_rule = new ArrayList(); + } + vrf_assign_rule.add(obj); + } + public void clearVrfAssignRule() { + vrf_assign_rule = null; + } + + + public void addVrfAssignRule(MatchConditionType match_condition, Integer vlan_tag, String routing_instance, Boolean ignore_acl) { + if (vrf_assign_rule == null) { + vrf_assign_rule = new ArrayList(); + } + vrf_assign_rule.add(new VrfAssignRuleType(match_condition, vlan_tag, routing_instance, ignore_acl)); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/WebuiNode.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/WebuiNode.java new file mode 100644 index 00000000000..e6203e047cc --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/api/types/WebuiNode.java @@ -0,0 +1,115 @@ +// +// Automatically generated. +// +package org.zstack.sugonSdnController.controller.api.types; + +import java.util.List; +import java.util.ArrayList; +import com.google.common.collect.Lists; + +import org.zstack.sugonSdnController.controller.api.ApiObjectBase; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; + +public class WebuiNode extends ApiObjectBase { + private String webui_node_ip_address; + private IdPermsType id_perms; + private PermType2 perms2; + private KeyValuePairs annotations; + private String display_name; + private List> tag_refs; + + @Override + public String getObjectType() { + return "webui-node"; + } + + @Override + public List getDefaultParent() { + return Lists.newArrayList("default-global-system-config"); + } + + @Override + public String getDefaultParentType() { + return "global-system-config"; + } + + public void setParent(GlobalSystemConfig parent) { + super.setParent(parent); + } + + public String getIpAddress() { + return webui_node_ip_address; + } + + public void setIpAddress(String webui_node_ip_address) { + this.webui_node_ip_address = webui_node_ip_address; + } + + + public IdPermsType getIdPerms() { + return id_perms; + } + + public void setIdPerms(IdPermsType id_perms) { + this.id_perms = id_perms; + } + + + public PermType2 getPerms2() { + return perms2; + } + + public void setPerms2(PermType2 perms2) { + this.perms2 = perms2; + } + + + public KeyValuePairs getAnnotations() { + return annotations; + } + + public void setAnnotations(KeyValuePairs annotations) { + this.annotations = annotations; + } + + + public String getDisplayName() { + return display_name; + } + + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + + + public List> getTag() { + return tag_refs; + } + + public void setTag(Tag obj) { + tag_refs = new ArrayList>(); + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void addTag(Tag obj) { + if (tag_refs == null) { + tag_refs = new ArrayList>(); + } + tag_refs.add(new ObjectReference(obj.getQualifiedName(), null)); + } + + public void removeTag(Tag obj) { + if (tag_refs != null) { + tag_refs.remove(new ObjectReference(obj.getQualifiedName(), null)); + } + } + + public void clearTag() { + if (tag_refs != null) { + tag_refs.clear(); + return; + } + tag_refs = null; + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java new file mode 100644 index 00000000000..1054f708696 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortClient.java @@ -0,0 +1,512 @@ +package org.zstack.sugonSdnController.controller.neutronClient; + +import org.apache.commons.collections.CollectionUtils; +import org.bouncycastle.util.IPAddress; +import org.zstack.core.db.Q; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.network.sdncontroller.SdnControllerConstant; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO_; +import org.zstack.sugonSdnController.controller.api.*; +import org.zstack.sugonSdnController.controller.api.types.*; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.io.IOException; +import java.util.*; + + +public class TfPortClient { + private static final CLogger logger = Utils.getLogger(TfPortClient.class); + + private TfHttpClient client; + + private String tenantId; + + public TfPortClient(){ + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq( + SdnControllerVO_.vendorType, + SdnControllerConstant.TF_CONTROLLER).find(); + if (sdn == null){ + throw new RuntimeException("Can not find a tf sdn controller."); + } + client = new TfHttpClient(sdn.getIp()); + tenantId = StringDSL.transToTfUuid(sdn.getAccountUuid()); + } + + private boolean getVMType(KeyValuePairs bindInfo) { + List bindings = bindInfo.getKeyValuePair(); + for (KeyValuePair item : bindings) { + if (Objects.equals(item.getKey(), "vnic_type") && Objects.equals(item.getValue(), "baremetal")) { + return true; + } + } + return false; + } + + public TfPortResponse createPort(String l2Id, String l3Id, String mac, String ip, + String vmInventeryId, String tfPortUuid, String vmName, KeyValuePairs bindInfo) { + TfPortRequestResource requestPortResourceEntity = new TfPortRequestResource(); + requestPortResourceEntity.setNetworkId(l2Id); + requestPortResourceEntity.setSubnetId(l3Id); + requestPortResourceEntity.setTenantId(tenantId); + requestPortResourceEntity.setMacAddress(mac); + requestPortResourceEntity.setDeviceId(vmInventeryId); + + TfPortIpEntity ipEntity = new TfPortIpEntity(); + ipEntity.setIpAddress(ip); + ipEntity.setSubnetId(l3Id); + List ipEntities = new ArrayList<>(); + ipEntities.add(ipEntity); + requestPortResourceEntity.setFixdIps(ipEntities); + try { + VirtualNetwork netObj = (VirtualNetwork) client.findById(VirtualNetwork.class, l2Id); + if (netObj == null) { + throw new RuntimeException(String.format("Can not find tf virtualnetwork: %s.", l2Id)); + } + //if mac-address is specified, check against the exisitng ports + //to see if there exists a port with the same mac-address + if (!Objects.isNull(mac)) { + List ports = (List) client.listWithDetail( + VirtualMachineInterface.class, null, null); + + for (VirtualMachineInterface port : ports) { + MacAddressesType macAddressesType = null; + if (port != null && port.getMacAddresses() != null) { + macAddressesType = port.getMacAddresses(); + List macAddresses = macAddressesType.getMacAddress(); + for (String macAddress : macAddresses) { + if (macAddress.equals(mac)) { + throw new RuntimeException("MacAddressInUse: " + mac); + } + } + } + } + } + // initialize port object + VirtualMachineInterface port; + try { + port = getTfPortObject(requestPortResourceEntity, netObj, tfPortUuid); + } catch (IOException e) { + throw new RuntimeException(e); + } + // set binding info + if (bindInfo != null) { + port.setBindings(bindInfo); + if (getVMType(bindInfo)) { + port.setDeviceOwner("BMS"); + } + } + PermType2 perms2 = new PermType2(); + perms2.setOwner(tenantId); + port.setPerms2(perms2); + port.setDisplayName(vmName); + // always request for v4 and v6 ip object and handle the failure + // create the object + Status result = client.create(port); + if (!result.isSuccess()) { + throw new RuntimeException(String.format("Failed to create tf VirtualMachineInterface: %s, reason: %s", + port.getUuid(), result.getMsg())); + } + // add support, nova boot --nic subnet-id=subnet_uuid + VirtualMachineInterface realPort = (VirtualMachineInterface) client.findById( + VirtualMachineInterface.class, port.getUuid()); + + if (ip != null) { + try { + portCreateInstanceIp(netObj, realPort, l3Id, ip); + } catch (Exception e) { + try { + client.delete(realPort); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + throw new RuntimeException(e); + } + } else if (netObj.getNetworkIpam() != null && netObj.getNetworkIpam().size() > 0) { + String errmsg = "Bad request trying to create IP instance."; + boolean ipv4PortDelete = false; + try { + Status ip_result = portCreateInstanceIp(netObj, realPort, l3Id, ip); + if (!ip_result.isSuccess()) { + ipv4PortDelete = true; + logger.error("Tf instance ip create failed."); + } + } catch (Exception e) { + ipv4PortDelete = true; + // failure in creating the instance ip. Roll back. + try { + client.delete(realPort); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + throw new RuntimeException(errmsg); + } + if (ipv4PortDelete) { + try { + client.delete(realPort); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + VirtualMachineInterface newestPort = (VirtualMachineInterface) client.findById( + VirtualMachineInterface.class, realPort.getUuid()); + return getPortResponse(newestPort); + } catch (Exception e) { + throw new RuntimeException("TF api call failed: " + e); + } + } + + private TfPortResponse getPortResponse(VirtualMachineInterface portObj) { + TfPortResponse tfPortResponse = new TfPortResponse(); + tfPortResponse.setPortId(portObj.getUuid()); + tfPortResponse.setCode(200); + tfPortResponse.setMacAddress(portObj.getMacAddresses().getMacAddress().get(0)); + TfPortIpEntity ipEntity = new TfPortIpEntity(); + List> ipBackRefs = portObj.getInstanceIpBackRefs(); + if (ipBackRefs != null && ipBackRefs.size() > 0) { + for (ObjectReference ipBackRef : ipBackRefs) { + InstanceIp ipObj = (InstanceIp) client.findById(InstanceIp.class, ipBackRef.getUuid()); + String ipAddr = ipObj != null ? ipObj.getAddress() : null; + String subnetId = Objects.requireNonNull(ipObj).getSubnetUuid(); + ipEntity.setIpAddress(ipAddr); + ipEntity.setSubnetId(subnetId); + } + } + tfPortResponse.setFixedIps(Collections.singletonList(ipEntity)); + + return tfPortResponse; + } + + private Status portCreateInstanceIp(VirtualNetwork virtualNetwork, VirtualMachineInterface port, + String subnetId, String ip) { + InstanceIp ipObj = new InstanceIp(); + String ipFamily = "v4"; + if (ip != null) { + if (IPAddress.isValidIPv6(ip)) { + ipFamily = "v6"; + } + ipObj.setAddress(ip); + } + + String ipName = String.valueOf(UUID.randomUUID()); + ipObj.setUuid(ipName); + ipObj.setName(ipName); + ipObj.setSubnetUuid(subnetId); + ipObj.setVirtualMachineInterface(port); + List fqName = virtualNetwork.getQualifiedName(); + fqName.add(ipName); + ipObj.setVirtualNetwork(virtualNetwork); + ipObj.setFamily(ipFamily); + // set instance ip ownership to real tenant + PermType2 permType2 = new PermType2(); + permType2.setOwner(tenantId); + ipObj.setPerms2(permType2); + return client.create(ipObj); + } + + private VirtualMachineInterface getTfPortObject(TfPortRequestResource requestPortResourceEntity, VirtualNetwork virtualNetwork, String tfPortUUid) throws IOException { + String projectId = requestPortResourceEntity.getTenantId(); + Project projectObj = (Project) client.findById(Project.class, projectId); + IdPermsType idPermsType = new IdPermsType(); + idPermsType.setEnable(true); + String portUuid = String.valueOf(UUID.randomUUID()); + if (Objects.nonNull(tfPortUUid)){ + portUuid = tfPortUUid; + } + VirtualMachineInterface portObj = new VirtualMachineInterface(); + portObj.setUuid(portUuid); + portObj.setName(portUuid); + portObj.setIdPerms(idPermsType); + portObj.setParent(projectObj); + portObj.setVirtualNetwork(virtualNetwork); + if (requestPortResourceEntity.getMacAddress() != null) { + MacAddressesType macAddressesType = new MacAddressesType(); + macAddressesType.addMacAddress(requestPortResourceEntity.getMacAddress()); + portObj.setMacAddresses(macAddressesType); + } + if (requestPortResourceEntity.getDeviceId() != null) { + VirtualMachine instanceObj = ensureInstanceExists(requestPortResourceEntity.getDeviceId(), projectId, false); + portObj.setVirtualMachine(instanceObj); + } + String fixIp = requestPortResourceEntity.getFixdIps() == null ? null: requestPortResourceEntity.getFixdIps().get(0).getIpAddress(); + if (Objects.nonNull(fixIp)) { + String netId = requestPortResourceEntity.getNetworkId(); + + if (ipInUseCheck(fixIp, netId)) { + throw new RuntimeException("IpAddressInUse: " + fixIp); + } + } + return portObj; + } + + public boolean ipInUseCheck(String ipAddr, String netId) throws IOException { + VirtualNetwork virtualNetwork = (VirtualNetwork) client.findById(VirtualNetwork.class, netId); + if (virtualNetwork != null) { + List> instanceIpBackRefs = virtualNetwork.getInstanceIpBackRefs(); + if (instanceIpBackRefs != null) { + List ipObjects = (List) client.getObjects(InstanceIp.class, instanceIpBackRefs); + if (ipObjects != null) { + for (InstanceIp ipObj : ipObjects) { + if (ipObj.getAddress().equals(ipAddr)) { + return true; + } + } + } + } + } + + return false; + } + + private VirtualMachine ensureInstanceExists(String deviceId, String projectId, boolean baremeetal) throws IOException { + VirtualMachine instanceObj = null; + try { + instanceObj = (VirtualMachine) client.findById(VirtualMachine.class, deviceId); + if (instanceObj != null) { + return instanceObj; + } + instanceObj = new VirtualMachine(); + instanceObj.setName(deviceId); + instanceObj.setUuid(deviceId); + PermType2 permType2 = new PermType2(); + permType2.setOwner(projectId); + instanceObj.setPerms2(permType2); + if (baremeetal) { + instanceObj.setServerType("baremetal-server"); + } else { + instanceObj.setServerType("virtual-server"); + } + client.create(instanceObj); + } catch (Exception e) { // Exception...... + VirtualMachine dbInstanceObj = null; + if (instanceObj.getUuid() != null) { + dbInstanceObj = (VirtualMachine) client.findById(VirtualMachine.class, instanceObj.getUuid()); + } else { + dbInstanceObj = (VirtualMachine) client.findByFQN(VirtualMachine.class, instanceObj.getName()); + + } + if (dbInstanceObj != null) { + if (baremeetal && !Objects.equals(dbInstanceObj.getServerType(), "baremetal-server")) { + client.update(instanceObj); + } else { + instanceObj = dbInstanceObj; + } + } + } + return instanceObj; + } + + public TfPortResponse getVirtualMachineInterface(String portId) { + try { + VirtualMachineInterface port = (VirtualMachineInterface) client.findById( + VirtualMachineInterface.class, portId); + if (port != null){ + return getPortResponse(port); + }else { + return null; + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public List getVirtualMachineInterfaceDetail() { + try { + List ports = (List) client.listWithDetail( + VirtualMachineInterface.class, null, null); + return ports; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public TfPortResponse deletePort(String portId) { + TfPortResponse response = new TfPortResponse(); + try { + VirtualMachineInterface portObj = (VirtualMachineInterface) client.findById(VirtualMachineInterface.class, portId); + if (portObj == null) { + response.setCode(200); + return response; + } + // release instance IP address + List> iipBackRefs = portObj.getInstanceIpBackRefs(); + if (iipBackRefs != null && iipBackRefs.size() > 0) { + for (ObjectReference iipBackRef : iipBackRefs) { + InstanceIp iipObj = (InstanceIp) client.findById(InstanceIp.class, iipBackRef.getUuid()); + // in case of shared ip only delete the link to the VMI + if (iipObj != null) { + iipObj.removeVirtualMachineInterface(portObj); + List> virtualMachineInterface = iipObj.getVirtualMachineInterface(); + if (virtualMachineInterface == null || virtualMachineInterface.size() == 0) { + Status delResult = client.delete(InstanceIp.class, iipBackRef.getUuid()); + if (!delResult.isSuccess()) { + throw new RuntimeException("Tf instance ip delete failed: " + iipBackRef.getUuid()); + } + } else { + client.update(iipObj); + } + } + } + } + // disassociate any floating IP used by instance + List> fipBackRefs = portObj.getFloatingIpBackRefs(); + if (CollectionUtils.isNotEmpty(fipBackRefs)) { + for (ObjectReference fipBackRef : fipBackRefs) { + FloatingIp fipObj = getTfFloatingipObject(fipBackRef.getUuid()); + if (fipObj != null) { + client.update(fipObj); + } + } + } + + client.delete(VirtualMachineInterface.class, portId); + // delete VirtualMachine if this was the last port + String instanceId; + if (Objects.equals(portObj.getParentType(), "virtual-machine")) { + instanceId = portObj.getParentUuid(); + } else { + List> vmRefs = portObj.getVirtualMachine(); + if (vmRefs != null && vmRefs.size() > 0) { + instanceId = vmRefs.get(0).getUuid(); + } else { + instanceId = null; + } + } + if (instanceId != null) { + VirtualMachine vm = (VirtualMachine) client.findById(VirtualMachine.class, instanceId); + if (CollectionUtils.isEmpty(vm.getVirtualMachineInterfaceBackRefs())) { + client.delete(VirtualMachine.class, instanceId); + } + } + response.setCode(200); + return response; + + } catch (Exception e) { + response.setCode(500); + response.setMsg(String.format("Delete tf virtualMachineInterface %s failed, reason: %s", + portId, e.getMessage())); + return response; + } + } + + private FloatingIp getTfFloatingipObject(String uuid) { + FloatingIp fipObj = (FloatingIp) client.findById(FloatingIp.class, uuid); + if (fipObj == null) { + return null; + } + fipObj.clearVirtualMachineInterface(); + fipObj.setFixedIpAddress(null); + return fipObj; + } + + /** + * 检查ip是否在已经被占用 + * + * @param ipAddr IPv4地址 + * @param subnetId (三层网络)的UUID + * @return 占用-true; 未占用-false + */ + public boolean checkTfIpAvailability(String ipAddr, String subnetId) throws IOException { + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, subnetId).find(); + VirtualNetwork virtualNetwork = (VirtualNetwork) client.findById( + VirtualNetwork.class, StringDSL.transToTfUuid(l3Network.getL2NetworkUuid())); + + if (Objects.isNull(virtualNetwork)) { + return false; + } + List> instanceIpBackRefs = virtualNetwork.getInstanceIpBackRefs(); + List> subnetListRefs = virtualNetwork.getNetworkIpam(); + + if (Objects.nonNull(virtualNetwork.getRouterExternal()) && virtualNetwork.getRouterExternal()) { + // if external network, floating ips. + List> floatingIpPools = virtualNetwork.getFloatingIpPools(); + if (CollectionUtils.isNotEmpty(floatingIpPools)) { + for (ObjectReference floatingIpPool : floatingIpPools) { + FloatingIpPool floatingIpPoolObj = (FloatingIpPool) client.findById(FloatingIpPool.class, floatingIpPool.getUuid()); + List> floatingIps = floatingIpPoolObj.getFloatingIps(); + if (CollectionUtils.isNotEmpty(floatingIps)) { + for (ObjectReference fip : floatingIps) { + FloatingIp fipObj = (FloatingIp) client.findById(FloatingIp.class, fip.getUuid()); + if (fipObj.getAddress() != null && fipObj.getAddress().equals(ipAddr)) { + return true; + } + } + } + } + } + } else { // else instance ips. + if (CollectionUtils.isNotEmpty(instanceIpBackRefs)) { + List ipObjects = (List) client.getObjects(InstanceIp.class, instanceIpBackRefs); + // check all instance ips. + if (CollectionUtils.isNotEmpty(ipObjects)) { + for (InstanceIp ipObj : ipObjects) { + if (ipObj.getAddress().equals(ipAddr)) { + return true; + } + } + } + } + } + + // check all subnets' gateway/dns service address/host routes/dhcp relay servers .eg + if (CollectionUtils.isNotEmpty(subnetListRefs)) { + for (ObjectReference subnetListRef : subnetListRefs) { + List ipamSubnets = subnetListRef.getAttr().getIpamSubnets(); + if (CollectionUtils.isNotEmpty(ipamSubnets)) { + for (IpamSubnetType ipamSubnet : ipamSubnets) { + List ipamSubnetIpUseList = new ArrayList<>(); + ipamSubnetIpUseList.add(ipamSubnet.getDefaultGateway()); + ipamSubnetIpUseList.add(ipamSubnet.getDnsServerAddress()); + List dnsNameservers = ipamSubnet.getDnsNameservers(); + if (CollectionUtils.isNotEmpty(dnsNameservers)) { + ipamSubnetIpUseList.addAll(dnsNameservers); + } + List dhcpRelayServer = ipamSubnet.getDhcpRelayServer(); + if (CollectionUtils.isNotEmpty(dhcpRelayServer)) { + ipamSubnetIpUseList.addAll(dhcpRelayServer); + } + RouteTableType routeTableType = ipamSubnet.getHostRoutes(); + if (Objects.nonNull(routeTableType)) { + List routeTypes = routeTableType.getRoute(); + if (CollectionUtils.isNotEmpty(routeTypes)) { + for (RouteType routeType : routeTypes) { + String ip = routeType.getNextHop(); + if (Objects.nonNull(ip)) { + ipamSubnetIpUseList.add(ip); + } + } + } + } + if (ipamSubnetIpUseList.contains(ipAddr)) { + return true; + } + } + } + } + } + return false; + } + + public Status updateTfPort(String tfPortUUid, String accountId, String deviceId, KeyValuePairs bindInfo) { + try { + VirtualMachineInterface port = (VirtualMachineInterface) client.findById( + VirtualMachineInterface.class, tfPortUUid); + boolean isBms = false; + if (bindInfo != null) { + port.setBindings(bindInfo); + isBms = getVMType(bindInfo); + } + VirtualMachine vm = ensureInstanceExists(deviceId, accountId, isBms); + port.setVirtualMachine(vm); + return client.update(port); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} + + diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortIpEntity.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortIpEntity.java new file mode 100644 index 00000000000..0808ccd6090 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortIpEntity.java @@ -0,0 +1,46 @@ +package org.zstack.sugonSdnController.controller.neutronClient; + + +import com.google.gson.annotations.SerializedName; + +public class TfPortIpEntity { + @SerializedName("subnet_id") + private String subnetId; + + @SerializedName("ip_address") + private String ipAddress; + + private String workType; + + public String getWorkType() { + return workType; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public String getSubnetId() { + return subnetId; + } + + public void setSubnetId(String subnetId) { + this.subnetId = subnetId; + } + + public String getIpAddress() { + return ipAddress; + } + + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + @Override + public String toString() { + return "IpEntity{" + + "subnetId='" + subnetId + '\'' + + ", subnetId='" + ipAddress + '\'' + + '}'; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestBody.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestBody.java new file mode 100644 index 00000000000..e7adb54ae9c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestBody.java @@ -0,0 +1,22 @@ +package org.zstack.sugonSdnController.controller.neutronClient; +public class TfPortRequestBody { + private TfPortRequestData data; + + private TfPortRequestContext context; + + public TfPortRequestData getData() { + return data; + } + + public void setData(TfPortRequestData data) { + this.data = data; + } + + public TfPortRequestContext getContext() { + return context; + } + + public void setContext(TfPortRequestContext context) { + this.context = context; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestContext.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestContext.java new file mode 100644 index 00000000000..d8b0a46b8fa --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestContext.java @@ -0,0 +1,31 @@ +package org.zstack.sugonSdnController.controller.neutronClient; + +public class TfPortRequestContext { + private String is_admin; + private String tenant_id; + private String operation; + + public String getIs_admin() { + return is_admin; + } + + public void setIs_admin(String is_admin) { + this.is_admin = is_admin; + } + + public String getTenant_id() { + return tenant_id; + } + + public void setTenant_id(String tenant_id) { + this.tenant_id = tenant_id; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestData.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestData.java new file mode 100644 index 00000000000..b29c8beb444 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestData.java @@ -0,0 +1,22 @@ +package org.zstack.sugonSdnController.controller.neutronClient; +public class TfPortRequestData { + private TfPortRequestResource resource; + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public TfPortRequestResource getResource() { + return resource; + } + + public void setResource(TfPortRequestResource resource) { + this.resource = resource; + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestResource.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestResource.java new file mode 100644 index 00000000000..13cb1485e3b --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortRequestResource.java @@ -0,0 +1,65 @@ +package org.zstack.sugonSdnController.controller.neutronClient; + +import java.util.List; + +public class TfPortRequestResource { + private String tenant_id; + + private String network_id; + + private String subnet_id; + + private List fixed_ips; + + private String mac_address; + + private String device_id; + + public String getDeviceId() { + return device_id; + } + + public void setDeviceId(String device_id) { + this.device_id = device_id; + } + + public String getMacAddress() { + return mac_address; + } + + public void setMacAddress(String mac_address) { + this.mac_address = mac_address; + } + + public String getTenantId() { + return tenant_id; + } + + public void setTenantId(String tenantId) { + this.tenant_id = tenantId; + } + + public String getNetworkId() { + return network_id; + } + + public void setNetworkId(String networkId) { + this.network_id = networkId; + } + + public String getSubnetId() { + return subnet_id; + } + + public void setSubnetId(String subnetId) { + this.subnet_id = subnetId; + } + + public List getFixdIps() { + return fixed_ips; + } + + public void setFixdIps(List fixdIps) { + this.fixed_ips = fixdIps; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortResponse.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortResponse.java new file mode 100644 index 00000000000..370406c5c75 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/neutronClient/TfPortResponse.java @@ -0,0 +1,83 @@ +package org.zstack.sugonSdnController.controller.neutronClient; + + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public class TfPortResponse { + private String msg; + private int code; + private String macAddress; + private List fixedIps; + private String exception; + + @SerializedName("id") + private String portId; + + @Override + public String toString() { + return "TfPortResponse{" + + "msg='" + msg + '\'' + + ", code=" + code + + ", macAddress='" + macAddress + '\'' + + ", fixedIps=" + fixedIps + + ", exception='" + exception + '\'' + + ", portId='" + portId + '\'' + + '}'; + } + + public String getPortId() { + return portId; + } + + public void setPortId(String portId) { + this.portId = portId; + } + + public TfPortResponse(String msg){ + this.msg = msg; + } + + public TfPortResponse(){} + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMacAddress() { + return macAddress; + } + + public void setMacAddress(String macAddress) { + this.macAddress = macAddress; + } + + public List getFixedIps() { + return fixedIps; + } + + public void setFixedIps(List fixedIps) { + this.fixedIps = fixedIps; + } + + public String getException() { + return exception; + } + + public void setException(String exception) { + this.exception = exception; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/APICreateL2TfNetworkMsg.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/APICreateL2TfNetworkMsg.java new file mode 100644 index 00000000000..85a9c2b08f6 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/APICreateL2TfNetworkMsg.java @@ -0,0 +1,59 @@ +package org.zstack.sugonSdnController.header; + +import org.springframework.http.HttpMethod; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.OverriddenApiParam; +import org.zstack.header.message.OverriddenApiParams; +import org.zstack.header.network.l2.APICreateL2NetworkEvent; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.zone.ZoneVO; + +@OverriddenApiParams({ + @OverriddenApiParam(field = "physicalInterface", param = @APIParam(maxLength = 1024, required = false)), + @OverriddenApiParam(field = "zoneUuid", param = @APIParam(maxLength = 1024, required = false, resourceType = ZoneVO.class)) +}) +@RestRequest( + path = "/l2-networks/tf", + method = HttpMethod.POST, + responseClass = APICreateL2NetworkEvent.class, + parameterName = "params" +) +public class APICreateL2TfNetworkMsg extends APICreateL2NetworkMsg { + + @APIParam(required = false, maxLength = 255) + private String ipPrefix; + + @APIParam(required = false, numberRange = {1, 32}) + private Integer ipPrefixLength; + + public String getIpPrefix() { + return ipPrefix; + } + + public void setIpPrefix(String ipPrefix) { + this.ipPrefix = ipPrefix; + } + + public Integer getIpPrefixLength() { + return ipPrefixLength; + } + + public void setIpPrefixLength(Integer ipPrefixLength) { + this.ipPrefixLength = ipPrefixLength; + } + + @Override + public String getType() { + return SugonSdnControllerConstant.L2_TF_NETWORK_TYPE; + } + + public static APICreateL2TfNetworkMsg __example__() { + APICreateL2TfNetworkMsg msg = new APICreateL2TfNetworkMsg(); + msg.setName("Tf-L2-Network"); + msg.setDescription("Test"); + msg.setZoneUuid(uuid()); + return msg; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/APICreateL2TfNetworkMsgDoc_zh_cn.groovy b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/APICreateL2TfNetworkMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..b734b2d83bd --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/APICreateL2TfNetworkMsgDoc_zh_cn.groovy @@ -0,0 +1,158 @@ +package org.zstack.sugonSdnController.header + +import org.zstack.header.network.l2.APICreateL2NetworkEvent + +doc { + title "创建tungsten fabric二层网络(CreateL2TfNetwork)" + + category "network.l2" + + desc """创建tungsten fabric二层网络""" + + rest { + request { + url "POST /v1/l2-networks/tf" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateL2TfNetworkMsg.class + + desc """""" + + params { + + column { + name "ipPrefix" + enclosedIn "params" + desc "IP地址前缀" + location "body" + type "String" + optional true + since "4.8.0" + } + column { + name "ipPrefixLength" + enclosedIn "params" + desc "IP地址前缀长度" + location "body" + type "Integer" + optional true + since "4.8.0" + } + column { + name "name" + enclosedIn "params" + desc "资源名称" + location "body" + type "String" + optional false + since "4.8.0" + } + column { + name "description" + enclosedIn "params" + desc "资源的详细描述" + location "body" + type "String" + optional true + since "4.8.0" + } + column { + name "zoneUuid" + enclosedIn "params" + desc "区域UUID" + location "body" + type "String" + optional false + since "4.8.0" + } + column { + name "physicalInterface" + enclosedIn "params" + desc "物理网卡" + location "body" + type "String" + optional false + since "4.8.0" + } + column { + name "type" + enclosedIn "params" + desc "二层网络类型" + location "body" + type "String" + optional true + since "4.8.0" + } + column { + name "vSwitchType" + enclosedIn "params" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "4.8.0" + values ("LinuxBridge","OvsDpdk","MacVlan") + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "4.8.0" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "4.8.0" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.8.0" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.8.0" + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" + } + } + } + + response { + clz APICreateL2NetworkEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/SugonApiInterceptor.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/SugonApiInterceptor.java new file mode 100644 index 00000000000..18294d7463a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/header/SugonApiInterceptor.java @@ -0,0 +1,89 @@ +package org.zstack.sugonSdnController.header; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.Q; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; +import org.zstack.header.apimediator.StopRoutingException; +import org.zstack.header.message.APIMessage; +import org.zstack.header.network.l2.*; +import org.zstack.header.network.l3.*; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vm.VmNicVO_; +import org.zstack.sdnController.header.APIRemoveSdnControllerEvent; +import org.zstack.sdnController.header.APIRemoveSdnControllerMsg; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; + +import java.util.ArrayList; +import java.util.List; + +import static org.zstack.core.Platform.operr; + + +public class SugonApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { + @Autowired + private CloudBus bus; + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + if (msg instanceof APIDeleteL2NetworkMsg) { + validate((APIDeleteL2NetworkMsg) msg); + } else if (msg instanceof APIDeleteL3NetworkMsg) { + validate((APIDeleteL3NetworkMsg) msg); + } else if (msg instanceof APIRemoveSdnControllerMsg) { + validate((APIRemoveSdnControllerMsg) msg); + } + + return msg; + } + + private void validate(APIDeleteL2NetworkMsg msg) { + APIDeleteL2NetworkEvent evt = new APIDeleteL2NetworkEvent(msg.getId()); + if(Q.New(L3NetworkVO.class).eq(L3NetworkVO_.l2NetworkUuid, msg.getL2NetworkUuid()) + .eq(L3NetworkVO_.type, SugonSdnControllerConstant.L3_TF_NETWORK_TYPE).count() > 0){ + String error = String.format("L2Network[%s] still has some L3Networks, please delete L3Networks first.", + msg.getL2NetworkUuid()); + evt.setError(operr(error)); + bus.publish(evt); + throw new StopRoutingException(); + } + } + + private void validate(APIDeleteL3NetworkMsg msg) { + APIDeleteL3NetworkEvent evt = new APIDeleteL3NetworkEvent(msg.getId()); + if(Q.New(VmNicVO.class).eq(VmNicVO_.l3NetworkUuid, msg.getL3NetworkUuid()) + .eq(VmNicVO_.type, VmInstanceConstant.TF_VIRTUAL_NIC_TYPE).count() > 0){ + String error = String.format("L3Network[%s] still has some Nics, please delete all Nics first.", + msg.getId()); + evt.setError(operr(error)); + bus.publish(evt); + throw new StopRoutingException(); + } + } + + private void validate(APIRemoveSdnControllerMsg msg) { + APIRemoveSdnControllerEvent evt = new APIRemoveSdnControllerEvent(msg.getId()); + if(Q.New(L2NetworkVO.class).eq(L2NetworkVO_.type, SugonSdnControllerConstant.L2_TF_NETWORK_TYPE).count() > 0){ + String error = String.format("There are some TfL2Networks exists, please delete all TfL2Networks first.", + msg.getId()); + evt.setError(operr(error)); + bus.publish(evt); + throw new StopRoutingException(); + } + } + + public List getMessageClassToIntercept() { + List ret = new ArrayList<>(); + ret.add(APIDeleteL2NetworkMsg.class); + ret.add(APIDeleteL3NetworkMsg.class); + ret.add(APIRemoveSdnControllerMsg.class); + return ret; + } + + public InterceptorPosition getPosition() { + return InterceptorPosition.END; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/InstanceBeforeAllocateIpExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/InstanceBeforeAllocateIpExtensionPointImpl.java new file mode 100644 index 00000000000..7b075043274 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/InstanceBeforeAllocateIpExtensionPointImpl.java @@ -0,0 +1,79 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.allocator.BeforeAllocateIpExtensionPoint; +import org.zstack.header.network.l3.AllocateIpMsg; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.api.Status; +import org.zstack.sugonSdnController.controller.api.types.KeyValuePairs; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.sugonSdnController.network.TfPortService; + +import java.util.Objects; + +public class InstanceBeforeAllocateIpExtensionPointImpl implements BeforeAllocateIpExtensionPoint { + @Autowired + private TfPortService tfPortService; + @Autowired + protected DatabaseFacade dbf; + @Override + public String allocateIpBySdn(AllocateIpMsg msg, String bmUuid, String mac, String switchInfo) { + if (switchInfo == null || switchInfo.length() == 0) { + return null; + } + L3NetworkInventory l3 = L3NetworkInventory.valueOf(dbf.findByUuid(msg.getL3NetworkUuid(), L3NetworkVO.class)); + if (!Objects.equals(l3.getType(), SugonSdnControllerConstant.L3_TF_NETWORK_TYPE)) { + return null; + } + String portUuid = Platform.getUuid(); + String switchs = ""; + String interfaces = ""; + String[] switchList = switchInfo.split("-"); + for (String swInfo : switchList) { + String[] swInfoList = swInfo.split(","); + switchs += (swInfoList[0] + ','); + interfaces += (swInfoList[1] + ','); + } + switchs = switchs.substring(0, switchs.length() - 1); + interfaces = interfaces.substring(0, interfaces.length() - 1); + String swInfo = String.format("{\"switch_ip\": \"%s\", \"switch_interface\": \"%s\"}", switchs, interfaces); + KeyValuePairs bindInfo = new KeyValuePairs(); + bindInfo.addKeyValuePair("vnic_type", "baremetal"); + + TfPortResponse port = tfPortService.createTfPort(l3, portUuid, msg.getRequiredIp(), mac, bindInfo); + if (port.getFixedIps().size() == 0) { + tfPortService.deleteTfPort(port.getPortId()); + throw new RuntimeException(String.format("Can not allocate ip address from tf for baremetal's nic[mac:%s].", mac)); + } + msg.setRequiredIp(port.getFixedIps().get(0).getIpAddress()); + try { + //swInfo example: {"profile", "{\"switch_ip\": \"1.1.1.1,2.2.2.2\", \"switch_interface\":\"0/0/1,0/0/2\"}} + bindInfo.addKeyValuePair("profile", swInfo); + Status result = tfPortService.updateTfPort(portUuid, bmUuid, bindInfo); + if (!result.isSuccess()) { + throw new RuntimeException(String.format("Update tf port [%s] failed.", portUuid)); + } + } catch (Exception e) { + tfPortService.deleteTfPort(portUuid); + throw new RuntimeException(e.getMessage()); + } + + return portUuid; + } + + @Override + public void releaseIpFromSdn(String nicUuid, String l3NetworkUuid) { + if (l3NetworkUuid == null || l3NetworkUuid.isEmpty()) { + return; + } + L3NetworkInventory l3 = L3NetworkInventory.valueOf(dbf.findByUuid(l3NetworkUuid, L3NetworkVO.class)); + if (!Objects.equals(l3.getType(), SugonSdnControllerConstant.L3_TF_NETWORK_TYPE)) { + return; + } + tfPortService.deleteTfPort(nicUuid); + } +} \ No newline at end of file diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/RecoverVmExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/RecoverVmExtensionPointImpl.java new file mode 100644 index 00000000000..cad1a64dd31 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/RecoverVmExtensionPointImpl.java @@ -0,0 +1,66 @@ +package org.zstack.sugonSdnController.network; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.vm.CustomNicOperator; +import org.zstack.compute.vm.VmSystemTags; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.vm.RecoverVmExtensionPoint; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.sugonSdnController.controller.SugonSdnController; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.StringDSL; + +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +public class RecoverVmExtensionPointImpl implements RecoverVmExtensionPoint { + @Autowired + private DatabaseFacade dbf; + @Autowired + private TfPortService tfPortService; + + @Override + public void preRecoverVm(VmInstanceInventory vm) { + } + + @Override + public void afterRecoverVm(VmInstanceInventory vm) { + + for (VmNicInventory vmNic : vm.getVmNics()) { + L3NetworkVO l3NetworkVO = dbf.findByUuid(vmNic.getL3NetworkUuid(), L3NetworkVO.class); + if (!l3NetworkVO.getType().equals(SugonSdnControllerConstant.L3_TF_NETWORK_TYPE)) { + continue; + } + + // recover mac tag + String mac = vmNic.getMac(); + if (StringUtils.isNotEmpty(mac)) { + SystemTagCreator macCreator = VmSystemTags.CUSTOM_MAC.newSystemTagCreator(vm.getUuid()); + macCreator.ignoreIfExisting = true; + macCreator.inherent = false; + macCreator.setTagByTokens(map( + e(VmSystemTags.STATIC_IP_L3_UUID_TOKEN, vmNic.getL3NetworkUuid()), + e(VmSystemTags.MAC_TOKEN, mac) + )); + macCreator.create(); + } + CustomNicOperator customNicOperator = new CustomNicOperator(vm.getUuid(), vmNic.getL3NetworkUuid()); + TfPortResponse port = tfPortService.createTfPort(StringDSL.transToTfUuid(customNicOperator.getCustomNicId()), vm, L3NetworkInventory.valueOf(l3NetworkVO)); + String finalMac = port.getMacAddress(); + String finalIp = port.getFixedIps().get(0).getIpAddress(); + String nicUuid = StringDSL.transToZstackUuid(port.getPortId()); + customNicOperator.updateNicTags(finalMac, finalIp, nicUuid); + } + } + + @Override + public void beforeRecoverVm(VmInstanceInventory vm) { + + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfCompleteNicInformationExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfCompleteNicInformationExtensionPointImpl.java new file mode 100644 index 00000000000..140a72f5844 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfCompleteNicInformationExtensionPointImpl.java @@ -0,0 +1,38 @@ +package org.zstack.sugonSdnController.network; + +import org.zstack.compute.vm.VmGlobalConfig; +import org.zstack.kvm.KVMAgentCommands; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.L2NetworkType; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.kvm.KVMAgentCommands.NicTO; +import org.zstack.kvm.KVMCompleteNicInformationExtensionPoint; +import org.zstack.network.service.MtuGetter; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.Arrays; + +public class TfCompleteNicInformationExtensionPointImpl implements KVMCompleteNicInformationExtensionPoint { + private static final CLogger logger = Utils.getLogger(TfCompleteNicInformationExtensionPointImpl.class); + @Override + public NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { + NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); + to.setIpForTf(nic.getIp()); + to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); + to.setL2NetworkUuid(l2Network.getUuid()); + logger.debug("Complete nic information for TfL2Network"); + return to; + } + @Override + public String getBridgeName(L2NetworkInventory l2Network) { + return null; + } + @Override + public L2NetworkType getL2NetworkTypeVmNicOn(){ + return L2NetworkType.valueOf(SugonSdnControllerConstant.L2_TF_NETWORK_TYPE); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java new file mode 100644 index 00000000000..1855c797a32 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2Network.java @@ -0,0 +1,235 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.sdnController.SdnController; +import org.zstack.sugonSdnController.controller.SugonSdnController; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.Message; +import org.zstack.header.network.l2.*; +import org.zstack.network.l2.L2NoVlanNetwork; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO_; + +import static org.zstack.core.Platform.err; +import static org.zstack.core.Platform.operr; + +public class TfL2Network extends L2NoVlanNetwork implements TfL2NetworkExtensionPoint{ + + @Autowired + SdnControllerManager sdnControllerManager; + + public TfL2Network(L2NetworkVO self) { + super(self); + } + + @Override + public void handleMessage(Message msg) { + try { + if (msg instanceof APIMessage) { + handleApiMessage((APIMessage) msg); + } else { + handleLocalMessage(msg); + } + } catch (Exception e) { + bus.logExceptionWithMessageDump(msg, e); + bus.replyErrorByMessageType(msg, e); + } + } + + private void handleLocalMessage(Message msg) { + if (msg instanceof L2NetworkDeletionMsg) { + handle((L2NetworkDeletionMsg) msg); + } else if (msg instanceof CheckL2NetworkOnHostMsg) { + handle((CheckL2NetworkOnHostMsg) msg); + } else if (msg instanceof PrepareL2NetworkOnHostMsg) { + handle((PrepareL2NetworkOnHostMsg) msg); + } else if (msg instanceof DetachL2NetworkFromClusterMsg) { + handle((DetachL2NetworkFromClusterMsg) msg); + } else if (msg instanceof DeleteL2NetworkMsg) { + handle((DeleteL2NetworkMsg) msg); + } else if (msg instanceof L2NetworkDetachFromClusterMsg) { + handle((L2NetworkDetachFromClusterMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(L2NetworkDetachFromClusterMsg msg) { + L2NetworkDetachFromClusterReply reply = new L2NetworkDetachFromClusterReply(); + SQL.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()).delete(); + self = dbf.reload(self); + bus.reply(msg, reply); + } + + private void handle(DeleteL2NetworkMsg msg) { + DeleteL2NetworkReply reply = new DeleteL2NetworkReply(); + deleteTfL2NetworkOnSdnController(self, new Completion(msg) { + @Override + public void success() { + SQL.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).delete(); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.reply(msg, reply); + } + }); + } + + private void handle(DetachL2NetworkFromClusterMsg msg) { + DetachL2NetworkFromClusterReply reply = new DetachL2NetworkFromClusterReply(); + SQL.New(L2NetworkClusterRefVO.class) + .eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()) + .delete(); + self = dbf.reload(self); + bus.reply(msg, reply); + } + + private void handle(PrepareL2NetworkOnHostMsg msg) { + PrepareL2NetworkOnHostReply reply = new PrepareL2NetworkOnHostReply(); + bus.reply(msg, reply); + } + + private void handle(CheckL2NetworkOnHostMsg msg) { + CheckL2NetworkOnHostReply reply = new CheckL2NetworkOnHostReply(); + bus.reply(msg, reply); + } + + private void handle(L2NetworkDeletionMsg msg) { + L2NetworkDeletionReply reply = new L2NetworkDeletionReply(); + deleteTfL2NetworkOnSdnController(self, new Completion(msg) { + @Override + public void success() { + SQL.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).delete(); + bus.reply(msg, reply); + } + + @Override + public void fail(ErrorCode errorCode) { + reply.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.reply(msg, reply); + } + }); + } + + private void handleApiMessage(APIMessage msg) { + if (msg instanceof APIDeleteL2NetworkMsg) { + handle((APIDeleteL2NetworkMsg) msg); + } else if (msg instanceof APIUpdateL2NetworkMsg) { + handle((APIUpdateL2NetworkMsg) msg); + } else if (msg instanceof APIAttachL2NetworkToClusterMsg) { + handle((APIAttachL2NetworkToClusterMsg) msg); + } else if (msg instanceof APIDetachL2NetworkFromClusterMsg) { + handle((APIDetachL2NetworkFromClusterMsg) msg); + } else { + bus.dealWithUnknownMessage(msg); + } + } + + private void handle(APIDetachL2NetworkFromClusterMsg msg) { + APIDetachL2NetworkFromClusterEvent evt = new APIDetachL2NetworkFromClusterEvent(msg.getId()); + SQL.New(L2NetworkClusterRefVO.class).eq(L2NetworkClusterRefVO_.clusterUuid, msg.getClusterUuid()) + .eq(L2NetworkClusterRefVO_.l2NetworkUuid, msg.getL2NetworkUuid()).delete(); + self = dbf.reload(self); + evt.setInventory(self.toInventory()); + bus.publish(evt); + } + + private void handle(APIAttachL2NetworkToClusterMsg msg){ + APIAttachL2NetworkToClusterEvent evt = new APIAttachL2NetworkToClusterEvent(msg.getId()); + L2NetworkClusterRefVO vo = new L2NetworkClusterRefVO(); + vo.setL2NetworkUuid(msg.getL2NetworkUuid()); + vo.setClusterUuid(msg.getClusterUuid()); + dbf.persist(vo); + self = dbf.findByUuid(self.getUuid(), L2NetworkVO.class); + evt.setInventory(self.toInventory()); + bus.publish(evt); + } + + private void handle(APIUpdateL2NetworkMsg msg){ + boolean update = false; + if (msg.getName() != null) { + self.setName(msg.getName()); + update = true; + } + if (msg.getDescription() != null) { + self.setDescription(msg.getDescription()); + update = true; + } + if (!update) { + return; + } + APIUpdateL2NetworkEvent evt = new APIUpdateL2NetworkEvent(msg.getId()); + updateTfL2NetworkOnSdnController(self, new Completion(msg) { + @Override + public void success() { + self = dbf.updateAndRefresh(self); + evt.setInventory(getSelfInventory()); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(errorCode); + bus.publish(evt); + } + }); + + + } + + private void handle(APIDeleteL2NetworkMsg msg) { + APIDeleteL2NetworkEvent evt = new APIDeleteL2NetworkEvent(msg.getId()); + deleteTfL2NetworkOnSdnController(self, new Completion(msg) { + @Override + public void success() { + SQL.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).delete(); + bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + } + + @Override + public void createTfL2NetworkOnSdnController(L2NetworkVO l2NetworkVO, APICreateL2NetworkMsg msg, Completion completion) { + if(l2NetworkVO.getPhysicalInterface() == null){ + l2NetworkVO.setPhysicalInterface(l2NetworkVO.getUuid()); + } + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + SugonSdnController sugonSdnController = (SugonSdnController) sdnController; + sugonSdnController.createL2Network(l2NetworkVO, msg, null, completion); + } + + @Override + public void deleteTfL2NetworkOnSdnController(L2NetworkVO l2NetworkVO, Completion completion) { + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + SugonSdnController sugonSdnController = (SugonSdnController) sdnController; + sugonSdnController.deleteL2Network(l2NetworkVO, null, completion); + } + + @Override + public void updateTfL2NetworkOnSdnController(L2NetworkVO l2NetworkVO, Completion completion) { + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + SugonSdnController sugonSdnController = (SugonSdnController) sdnController; + sugonSdnController.updateL2Network(l2NetworkVO, null, completion); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2NetworkExtensionPoint.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2NetworkExtensionPoint.java new file mode 100644 index 00000000000..f6354fdc4c4 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2NetworkExtensionPoint.java @@ -0,0 +1,11 @@ +package org.zstack.sugonSdnController.network; + +import org.zstack.header.core.Completion; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkVO; + +public interface TfL2NetworkExtensionPoint { + void createTfL2NetworkOnSdnController(L2NetworkVO vo, APICreateL2NetworkMsg msg, Completion completion); + void deleteTfL2NetworkOnSdnController(L2NetworkVO vo, Completion completion); + void updateTfL2NetworkOnSdnController(L2NetworkVO vo, Completion completion); +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2NetworkFactory.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2NetworkFactory.java new file mode 100644 index 00000000000..1b660bfb34c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL2NetworkFactory.java @@ -0,0 +1,46 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.network.l2.*; + +public class TfL2NetworkFactory implements L2NetworkFactory { + private static final L2NetworkType type = new L2NetworkType(SugonSdnControllerConstant.L2_TF_NETWORK_TYPE); + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + + @Override + public L2NetworkType getType() { + return type; + } + + @Override + public void createL2Network(L2NetworkVO vo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + TfL2Network tfL2Network = new TfL2Network(vo); + tfL2Network.createTfL2NetworkOnSdnController(vo, msg, new Completion(msg) { + @Override + public void success() { + dbf.persist(vo); + completion.success(L2NetworkInventory.valueOf(dbf.findByUuid(vo.getUuid(), L2NetworkVO.class))); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + public L2Network getL2Network(L2NetworkVO vo) { + return new TfL2Network(vo); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java new file mode 100644 index 00000000000..8d9531ede52 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3Network.java @@ -0,0 +1,334 @@ +package org.zstack.sugonSdnController.network; + +import org.apache.commons.net.util.SubnetUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.message.Message; +import org.zstack.header.network.l3.*; +import org.zstack.network.l3.L3BasicNetwork; +import org.zstack.sdnController.SdnController; +import org.zstack.sdnController.SdnControllerManager; +import org.zstack.header.network.sdncontroller.SdnControllerVO; +import org.zstack.header.network.sdncontroller.SdnControllerVO_; +import org.zstack.sugonSdnController.controller.SugonSdnController; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortClient; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.NetworkUtils; +import java.io.IOException; +import static org.zstack.core.Platform.err; +import static org.zstack.utils.network.NetworkUtils.getSubnetInfo; + +/** + * @description: + * @author: liupt@sugon.com + * @create: 2022-10-11 + **/ +public class TfL3Network extends L3BasicNetwork { + private static final CLogger logger = Utils.getLogger(TfL3Network.class); + @Autowired + SdnControllerManager sdnControllerManager; + + @Autowired + protected DatabaseFacade dbf; + + SugonSdnController sugonSdnController; + + public TfL3Network(L3NetworkVO self) { + super(self); + } + + private SugonSdnController getSugonSdnController() { + if (sugonSdnController != null){ + return sugonSdnController; + } + SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find(); + SdnController sdnController = sdnControllerManager.getSdnController(sdn); + return (SugonSdnController) sdnController; + } + + @Override + public void handleMessage(Message msg) { + if (msg instanceof APIDeleteL3NetworkMsg) { + handle((APIDeleteL3NetworkMsg) msg); + } else if (msg instanceof APIUpdateL3NetworkMsg) { + handle((APIUpdateL3NetworkMsg) msg); + } else if (msg instanceof APIAddDnsToL3NetworkMsg) { + handle((APIAddDnsToL3NetworkMsg) msg); + } else if (msg instanceof APIRemoveDnsFromL3NetworkMsg) { + handle((APIRemoveDnsFromL3NetworkMsg) msg); + } else if (msg instanceof APIAddIpRangeByNetworkCidrMsg) { + handle((APIAddIpRangeByNetworkCidrMsg) msg); + } else if (msg instanceof APIDeleteIpRangeMsg) { + handle((APIDeleteIpRangeMsg) msg); + } else if (msg instanceof APIAddHostRouteToL3NetworkMsg) { + handle((APIAddHostRouteToL3NetworkMsg) msg); + } else if (msg instanceof APIRemoveHostRouteFromL3NetworkMsg) { + handle((APIRemoveHostRouteFromL3NetworkMsg) msg); + } else if (msg instanceof APICheckIpAvailabilityMsg) { + handle((APICheckIpAvailabilityMsg) msg); + } else { + super.handleMessage(msg); + } + } + + private void handle(APICheckIpAvailabilityMsg msg) { + APICheckIpAvailabilityReply reply = new APICheckIpAvailabilityReply(); + CheckIpAvailabilityReply r = new CheckIpAvailabilityReply(); + TfPortClient tfPortClient = new TfPortClient(); + try { + boolean availability = tfPortClient.checkTfIpAvailability(msg.getIp(), msg.getL3NetworkUuid()); + r.setAvailable(!availability); + if (availability){ + r.setReason("IP address is already in use."); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + reply.setAvailable(r.isAvailable()); + reply.setReason(r.getReason()); + bus.reply(msg, reply); + } + + private void handle(APIDeleteL3NetworkMsg msg){ + APIDeleteL3NetworkEvent evt = new APIDeleteL3NetworkEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().deleteL3Network(l3Network, new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void handle(APIUpdateL3NetworkMsg msg){ + APIUpdateL3NetworkEvent evt = new APIUpdateL3NetworkEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().updateL3Network(l3Network,msg, new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + + } + + private void handle(APIAddIpRangeByNetworkCidrMsg msg){ + APIAddIpRangeByNetworkCidrEvent evt = new APIAddIpRangeByNetworkCidrEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().addL3IpRangeByCidr(l3Network,msg, new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + procReservedIP(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + } else{ + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void handle(APIDeleteIpRangeMsg msg){ + APIDeleteIpRangeEvent evt = new APIDeleteIpRangeEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().deleteL3Network(l3Network, new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void handle(APIAddDnsToL3NetworkMsg msg){ + APIAddDnsToL3NetworkEvent evt = new APIAddDnsToL3NetworkEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().addL3Dns(l3Network, msg,new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void handle(APIRemoveDnsFromL3NetworkMsg msg){ + APIRemoveDnsFromL3NetworkEvent evt = new APIRemoveDnsFromL3NetworkEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().deleteL3Dns(l3Network, msg,new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void handle(APIAddHostRouteToL3NetworkMsg msg){ + APIAddHostRouteToL3NetworkEvent evt = new APIAddHostRouteToL3NetworkEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().addL3HostRoute(l3Network, msg,new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.CREATE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void handle(APIRemoveHostRouteFromL3NetworkMsg msg){ + APIRemoveHostRouteFromL3NetworkEvent evt = new APIRemoveHostRouteFromL3NetworkEvent(msg.getId()); + // Get L3 Network from zstack db + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if(l3Network!=null){ + getSugonSdnController().deleteL3HostRoute(l3Network, msg,new Completion(msg){ + @Override + public void success() { + // zstack business processing + TfL3Network.super.handleMessage(msg); +// bus.publish(evt); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + + } else{ + evt.setError(err(SysErrors.DELETE_RESOURCE_ERROR, "L3 Network is missing")); + bus.publish(evt); + } + } + + private void procReservedIP(APIAddIpRangeByNetworkCidrMsg msg){ + SubnetUtils.SubnetInfo subnetInfo = getSubnetInfo(new SubnetUtils(msg.getNetworkCidr())); + // Reserved for service + String servIp = NetworkUtils.longToIpv4String(NetworkUtils.ipv4StringToLong(subnetInfo.getLowAddress())+1); + // Reserved for edge + String edgeIp = subnetInfo.getHighAddress(); + // Get IP Range + IpRangeVO ipRangeVO = Q.New(IpRangeVO.class).eq(IpRangeVO_.l3NetworkUuid, msg.getL3NetworkUuid()).find(); + // Set Used Ip + UsedIpVO servIpInfo = new UsedIpVO(); + servIpInfo.setUuid(Platform.getUuid()); + servIpInfo.setIpRangeUuid(ipRangeVO.getUuid()); + servIpInfo.setL3NetworkUuid(ipRangeVO.getL3NetworkUuid()); + servIpInfo.setIp(servIp); + servIpInfo.setIpInLong(NetworkUtils.ipv4StringToLong(servIp)); + servIpInfo.setIpInBinary(NetworkUtils.ipStringToBytes(servIpInfo.getIp())); + servIpInfo.setGateway(ipRangeVO.getGateway()); + servIpInfo.setNetmask(ipRangeVO.getNetmask()); + servIpInfo.setIpVersion(IPv6Constants.IPv4); + servIpInfo.setLastOpDate(ipRangeVO.getLastOpDate()); + servIpInfo.setCreateDate(ipRangeVO.getCreateDate()); + dbf.persist(servIpInfo); + UsedIpVO edgeIpInfo = new UsedIpVO(); + BeanUtils.copyProperties(servIpInfo,edgeIpInfo); + edgeIpInfo.setUuid(Platform.getUuid()); + edgeIpInfo.setIp(edgeIp); + edgeIpInfo.setIpInLong(NetworkUtils.ipv4StringToLong(edgeIp)); + edgeIpInfo.setIpInBinary(NetworkUtils.ipStringToBytes(edgeIpInfo.getIp())); + dbf.persist(edgeIpInfo); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3NetworkFactory.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3NetworkFactory.java new file mode 100644 index 00000000000..be71fded04e --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfL3NetworkFactory.java @@ -0,0 +1,41 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.network.l3.*; + +/** + * @description: + * @author: liupt@sugon.com + * @create: 2022-10-11 + **/ +public class TfL3NetworkFactory implements L3NetworkFactory { + private static final L3NetworkType type = new L3NetworkType(SugonSdnControllerConstant.L3_TF_NETWORK_TYPE); + @Autowired + private DatabaseFacade dbf; + + @Override + public L3Network getL3Network(L3NetworkVO vo) { + return new TfL3Network(vo); + } + + @Override + public L3NetworkType getType() { + return type; + } + + @Override + public L3NetworkInventory createL3Network(L3NetworkVO l3vo, APICreateL3NetworkMsg msg) { + l3vo.setType(type.toString()); + dbf.getEntityManager().persist(l3vo); + dbf.getEntityManager().flush(); + dbf.getEntityManager().refresh(l3vo); + return L3NetworkInventory.valueOf(l3vo); + } + + @Override + public boolean applyNetworkServiceWhenVmStateChange() { + return false; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfMigrateVmBackend.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfMigrateVmBackend.java new file mode 100644 index 00000000000..a470ea272af --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfMigrateVmBackend.java @@ -0,0 +1,184 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.HostConstant; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.vm.*; +import org.zstack.identity.AccountManager; +import org.zstack.kvm.*; +import org.zstack.network.service.MtuGetter; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.List; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + + +public class TfMigrateVmBackend implements VmInstanceMigrateExtensionPoint, VmPreMigrationExtensionPoint { + private static final CLogger logger = Utils.getLogger(TfMigrateVmBackend.class); + public static final String NOTIFY_TF_NIC = "/vm/nodifytfnic"; + @Autowired + private CloudBus bus; + @Autowired + private AccountManager accountMgr; + @Autowired + protected DatabaseFacade dbf; + + public static class SugonNicNotifyCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + private String sugonSdnAction; + @GrayVersion(value = "5.0.0") + private List nics; + @GrayVersion(value = "5.0.0") + private String vmInstanceUuid; + @GrayVersion(value = "5.0.0") + private String accountUuid; + public String getSugonSdnAction() { + return sugonSdnAction; + } + + public void setSugonSdnAction(String sugonSdnAction) { + this.sugonSdnAction = sugonSdnAction; + } + + public List getNics() { + return nics; + } + + public void setNics(List nics) { + this.nics = nics; + } + public String getVmInstanceUuid() { + return vmInstanceUuid; + } + + public void setVmInstanceUuid(String vmInstanceUuid) { + this.vmInstanceUuid = vmInstanceUuid; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + } + + public static class SugonNicNotifyCmdRsp extends KVMAgentCommands.AgentResponse { + + } + + + @Override + public void preVmMigration(VmInstanceInventory vm, VmMigrationType type, String dstHostUuid, Completion completion) { + try { + notifySugonSdn(vm, dstHostUuid, "add"); + completion.success(); + } catch (OperationFailureException e) { + completion.fail(e.getErrorCode()); + } + } + + @Override + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { + // pre支持物理机+本地存储迁移,以及物理机+共享存储迁移,before不支持物理机+共享存储的迁移 + notifySugonSdn(inv, destHostUuid, "add"); + } + + @Override + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { + + } + + @Override + public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { + notifySugonSdn(inv, srcHostUuid, "delete"); + } + + @Override + public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) { + notifySugonSdn(inv, destHostUuid, "delete"); + } + + private boolean needNotiySugonSdn(VmInstanceInventory inv) { + for (VmNicInventory nic : inv.getVmNics()) { + if (VmInstanceConstant.TF_VIRTUAL_NIC_TYPE.equalsIgnoreCase(nic.getType())) { + return true; + } + } + return false; + } + + private void notifySugonSdn(VmInstanceInventory inv, String destHostUuid, String operate) { + if (!needNotiySugonSdn(inv)) { + return; + } + logger.info(String.format("notifySugonSdn: start to notify sugon sdn to %s vrouter for vm[uuid:%s] in success flow", operate, inv.getUuid())); + SugonNicNotifyCmd cmd = new SugonNicNotifyCmd(); + cmd.setSugonSdnAction(operate); + cmd.setVmInstanceUuid(inv.getUuid()); + cmd.setAccountUuid(accountMgr.getOwnerAccountUuidOfResource(cmd.getVmInstanceUuid())); + List nics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, inv.getUuid()).list(); + List nicInvs = VmNicInventory.valueOf(nics); + if (nicInvs == null || nicInvs.isEmpty()) { + logger.info(String.format("notifySugonSdn: nic count is zero, will not call sugon sdn")); + return; + } + cmd.setNics(nicInvs.stream().filter(vmNic -> VmInstanceConstant.TF_VIRTUAL_NIC_TYPE.equalsIgnoreCase(vmNic.getType())) + .map(this::completeNicInfo).collect(Collectors.toList())); + logger.info(String.format("after completeNicInfo:nic count: %s", cmd.getNics().size())); + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(destHostUuid); + msg.setCommand(cmd); + msg.setPath(NOTIFY_TF_NIC); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, destHostUuid); + MessageReply reply = bus.call(msg); + if (!reply.isSuccess()) { + logger.error(String.format("notifySugonSdn: failed to notify sugon sdn to %s vrouter for vm [uuid:%s], %s", operate, inv.getUuid(), + reply.getError())); + throw new OperationFailureException(operr("notifySugonSdn: failed to notify sugon sdn to %s vrouter for vm [uuid:%s], on the destination host[uuid:%s]", + operate, inv.getUuid(), destHostUuid).causedBy(reply.getError())); + } + + KVMHostAsyncHttpCallReply r = reply.castReply(); + TfMigrateVmBackend.SugonNicNotifyCmdRsp rsp = r.toResponse(TfMigrateVmBackend.SugonNicNotifyCmdRsp.class); + if (!rsp.isSuccess()) { + logger.error(String.format("notifySugonSdn: failed to notify sugon sdn to %s vrouter for vm [uuid:%s], %s", operate, inv.getUuid(), + rsp.getError())); + throw new OperationFailureException(operr("notifySugonSdn: failed to notify sugon sdn to %s vrouter for vm [uuid:%s], on the destination host[uuid:%s], error is:%s", + operate, inv.getUuid(), destHostUuid, rsp.getError())); + } + logger.info(String.format("notifySugonSdn: successfully to notify sugon sdn to %s vrouter for vm[uuid:%s]", operate, inv.getUuid())); + } + + @Transactional(readOnly = true) + private KVMAgentCommands.NicTO completeNicInfo(VmNicInventory nic) { + L3NetworkVO l3NetworkVO = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, nic.getL3NetworkUuid()).find(); + L2NetworkVO l2NetworkVO = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, l3NetworkVO.getL2NetworkUuid()).find(); + L2NetworkInventory l2inv = L2NetworkInventory.valueOf(l2NetworkVO); + KVMAgentCommands.NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); + to.setIpForTf(nic.getIp()); + to.setMtu(new MtuGetter().getMtu(l3NetworkVO.getUuid())); + to.setL2NetworkUuid(l2inv.getUuid()); + to.setResourceUuid(nic.getUuid()); + logger.debug("notifySugonSdn: Complete nic information for TfL2Network"); + return to; + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java new file mode 100644 index 00000000000..f979bc6d3a0 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfNicManageExtensionPointImpl.java @@ -0,0 +1,75 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.db.Q; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.L3NetworkVO_; +import org.zstack.header.vm.APICreateVmNicMsg; +import org.zstack.header.vm.NicManageExtensionPoint; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortIpEntity; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + + +public class TfNicManageExtensionPointImpl implements NicManageExtensionPoint { + private static final CLogger logger = Utils.getLogger(TfNicManageExtensionPointImpl.class); + + @Autowired + private TfPortService tfPortService; + + @Override + public void beforeCreateNic(VmNicInventory nic, APICreateVmNicMsg msg) { + L3NetworkVO l3Network = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, msg.getL3NetworkUuid()).find(); + if (!SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3Network.getType())) { + return; + } + nic.setType(VmInstanceConstant.TF_VIRTUAL_NIC_TYPE); + TfPortResponse port = null; + String portUuid = msg.getResourceUuid(); + String tfPortUuid = null; + if (portUuid != null){ + tfPortUuid = StringDSL.transToTfUuid(portUuid); + port = tfPortService.getTfPort(tfPortUuid); + if (port != null){ + String ipAddr = null; + for (TfPortIpEntity ipEntrty: port.getFixedIps()) { + if (ipEntrty.getSubnetId().equals(StringDSL.transToTfUuid(msg.getL3NetworkUuid()))) { + ipAddr = ipEntrty.getIpAddress(); + } + } + if (ipAddr == null) { + throw new RuntimeException(String.format("Tf port with uuid[%s] exists, " + + "but it's subnet id not equal with the l3NetworkUuid in param.", msg.getResourceUuid())); + } + msg.setIp(ipAddr); + nic.setMac(port.getMacAddress()); + logger.debug(String.format("Tf port with uuid[%s] exists, just save ip info to zstack db.", + msg.getResourceUuid())); + } + } + if (port == null) { + String l2NetworkUuid = l3Network.getL2NetworkUuid(); + port = tfPortService.createTfPort(tfPortUuid, l2NetworkUuid, msg.getL3NetworkUuid(), + nic.getMac(), msg.getIp()); + if (port.getFixedIps().size() > 0) { + nic.setIp(port.getFixedIps().get(0).getIpAddress()); + } + logger.debug("Create a new tf port success."); + } + nic.setUuid(StringDSL.transToZstackUuid(port.getPortId())); + } + + @Override + public void beforeDeleteNic(VmNicInventory nic) { + if (!VmInstanceConstant.TF_VIRTUAL_NIC_TYPE.equals(nic.getType())) { + return; + } + tfPortService.deleteTfPort(nic.getUuid()); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java new file mode 100644 index 00000000000..c4767689bd1 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfPortService.java @@ -0,0 +1,126 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.zstack.compute.vm.MacOperator; +import org.zstack.compute.vm.StaticIpOperator; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.identity.AccountManager; +import org.zstack.sugonSdnController.controller.api.Status; +import org.zstack.sugonSdnController.controller.api.types.KeyValuePair; +import org.zstack.sugonSdnController.controller.api.types.KeyValuePairs; +import org.zstack.sugonSdnController.controller.api.types.VirtualMachineInterface; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortClient; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.utils.StringDSL; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class TfPortService { + @Autowired + protected AccountManager acntMgr; + + public TfPortResponse getTfPort(String tfPortUUid) { + TfPortClient tfPortClient = new TfPortClient(); + return tfPortClient.getVirtualMachineInterface(tfPortUUid); + } + + public List getTfPortsDetail() { + TfPortClient tfPortClient = new TfPortClient(); + return tfPortClient.getVirtualMachineInterfaceDetail(); + } + + public TfPortResponse createTfPort(String tfPortUUid, String l2NetworkUuid, String l3NetworkUuid, String mac, String ip) { + //invoke tf rest interface to retrieve real ip and mac and portId + TfPortClient tfPortClient = new TfPortClient(); + String tfL2NetworkId = StringDSL.transToTfUuid(l2NetworkUuid); + String tfL3NetworkId = StringDSL.transToTfUuid(l3NetworkUuid); + TfPortResponse port = tfPortClient.createPort(tfL2NetworkId, tfL3NetworkId, mac, ip, null, + tfPortUUid, null, null); + if (port.getCode() != HttpStatus.OK.value()) { + // fail to rollback the flowchain + throw new RuntimeException("failed to invoke creating tf port: " + port); + } + return port; + } + + public TfPortResponse createTfPort(String tfPortUUid, VmInstanceInventory vm, L3NetworkInventory l3) { + MacOperator mo = new MacOperator(); + String customMac = mo.getMac(vm.getUuid(), l3.getUuid()); + Map> vmStaticIps = new StaticIpOperator().getStaticIpbyVmUuid(vm.getUuid()); + Map nicStaticIpMap = new StaticIpOperator().getNicStaticIpMap(vmStaticIps.get(l3.getUuid())); + + // ignoring ipv6 now , so if the user didn't assign ip on the webpage,then useTf Ip; + String customIp = nicStaticIpMap.get(4); + + //invoke tf rest interface to retrieve real ip and mac and portId + TfPortClient tfPortClient = new TfPortClient(); + String tfL2NetworkId = StringDSL.transToTfUuid(l3.getL2NetworkUuid()); + String tfL3NetworkId = StringDSL.transToTfUuid(l3.getUuid()); + String vmiUuid = StringDSL.transToTfUuid(vm.getUuid()); + String vmName = vm.getName(); + + try { + if (customIp != null && !customIp.isEmpty()) { + boolean availability = tfPortClient.checkTfIpAvailability(customIp, l3.getUuid()); + if (availability){ + throw new RuntimeException(String.format("Can not allocate IP[%s] from tf.", customIp)); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + TfPortResponse port = tfPortClient.createPort(tfL2NetworkId, tfL3NetworkId, customMac, customIp, vmiUuid, + tfPortUUid, vmName, null); + if (port.getCode() != HttpStatus.OK.value()) { + // fail to rollback the flowchain + throw new RuntimeException("failed to invoke creating tf port: " + port); + } + return port; + } + + public TfPortResponse createTfPort(L3NetworkInventory l3, String portUuid, String ip, String mac, KeyValuePairs bindInfo) { + //invoke tf rest interface to retrieve real ip and mac and portId + TfPortClient tfPortClient = new TfPortClient(); + String tfL2NetworkId = StringDSL.transToTfUuid(l3.getL2NetworkUuid()); + String tfL3NetworkId = StringDSL.transToTfUuid(l3.getUuid()); + String tfPortUuid = StringDSL.transToTfUuid(portUuid); + + try { + if (ip != null && !ip.isEmpty()) { + boolean availability = tfPortClient.checkTfIpAvailability(ip, l3.getUuid()); + if (availability){ + throw new RuntimeException(String.format("Can not allocate IP[%s] from tf.", ip)); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + TfPortResponse port = tfPortClient.createPort(tfL2NetworkId, tfL3NetworkId, mac, ip, null, tfPortUuid, null, bindInfo); + if (port.getCode() != HttpStatus.OK.value()) { + // fail to rollback the flowchain + throw new RuntimeException("failed to invoke creating tf port: " + port); + } + return port; + } + + public TfPortResponse deleteTfPort(String portUUid) { + String tfPortUUid = StringDSL.transToTfUuid(portUUid); + TfPortClient tfPortClient = new TfPortClient(); + return tfPortClient.deletePort(tfPortUUid); + } + + public Status updateTfPort(String portUUid, String bmUuid, KeyValuePairs bindInfo) { + String accountId = StringDSL.transToTfUuid(acntMgr.getOwnerAccountUuidOfResource(bmUuid)); + String tfBmUUid = StringDSL.transToTfUuid(bmUuid); + String tfPortUUid = StringDSL.transToTfUuid(portUUid); + TfPortClient tfPortClient = new TfPortClient(); + return tfPortClient.updateTfPort(tfPortUUid, accountId, tfBmUUid, bindInfo); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfZstackPortSync.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfZstackPortSync.java new file mode 100644 index 00000000000..184b2e721ed --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/TfZstackPortSync.java @@ -0,0 +1,119 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.db.Q; +import org.zstack.core.thread.PeriodicTask; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.managementnode.ManagementNodeReadyExtensionPoint; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.network.l2.L2NetworkVO_; +import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vm.VmNicVO_; +import org.zstack.sugonSdnController.controller.api.ApiPropertyBase; +import org.zstack.sugonSdnController.controller.api.ObjectReference; +import org.zstack.sugonSdnController.controller.api.types.VirtualMachineInterface; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public class TfZstackPortSync implements ManagementNodeReadyExtensionPoint { + + @Autowired + protected ThreadFacade thdf; + private Future trackerThread = null; + @Autowired + private TfPortService tfPortService; + private final static CLogger logger = Utils.getLogger(TfZstackPortSync.class); + private final List excludeTypes = new ArrayList(Arrays.asList("neutron:LOADBALANCER", "VIP", "BMS")); + + @Override + public void managementNodeReady() { + if (trackerThread != null) { + trackerThread.cancel(true); + } + trackerThread = thdf.submitPeriodicTask(new SyncPort()); + } + + private class SyncPort implements PeriodicTask { + + @Override + public TimeUnit getTimeUnit() { + return TimeUnit.DAYS; + } + + @Override + public long getInterval() { + return 1; + } + + @Override + public String getName() { + return "Period-Task-for-sync-port-between-tf-and-zstack"; + } + + private HashSet getPortToDelete() { + List zstackPortsUuid = Q.New(VmNicVO.class).select(VmNicVO_.uuid).listValues(); + List zstackL2NetworksUuid = Q.New(L2NetworkVO.class).select(L2NetworkVO_.uuid).listValues(); + List tfPortsUuid = new ArrayList<>(); + try{ + List tfPorts = tfPortService.getTfPortsDetail(); + for (VirtualMachineInterface vmi : tfPorts) { + // skip port if it's network not in zstack + List> tfNetworks = vmi.getVirtualNetwork(); + if (!zstackL2NetworksUuid.contains(StringDSL.transToZstackUuid(tfNetworks.get(0).getUuid()))) { + continue; + } + // exclude the virtualmachineinterface + if (excludeTypes.contains(vmi.getDeviceOwner())) { + continue; + } + // exclude the virtualmachineinterface of tf lb + if (vmi.getName().startsWith("default-domain__")) { + continue; + } + tfPortsUuid.add(StringDSL.transToZstackUuid(vmi.getUuid())); + } + } catch (Exception e) { + logger.error(String.format("Port_Sync_Task: Fetch tf VirtualMachineInterface failed: %s.", e)); + return null; + } + HashSet result = new HashSet<>(tfPortsUuid); + result.removeAll(zstackPortsUuid); + logger.debug(String.format("Port_Sync_Task: Fetch tf VirtualMachineInterface (%s) to delete.", result)); + return result; + } + + @Override + public void run() { + logger.info("Port_Sync_Task: begin."); + try { + HashSet portsToDelete = getPortToDelete(); + int maxDeleteCount = 10; + for (String portUuid: portsToDelete) { + TfPortResponse response = tfPortService.deleteTfPort(portUuid); + if (response.getCode() == 200) { + logger.info(String.format("Port_Sync_Task: VirtualMachineInterface: %s delete success.", + portUuid)); + } else { + logger.warn(String.format("Port_Sync_Task: VirtualMachineInterface: %s delete failed," + + " reason: %s.", portUuid, response.getMsg())); + } + maxDeleteCount --; + if (maxDeleteCount == 0) { + break; + } + } + } catch (Exception e) { + logger.error(String.format("Port_Sync_Task failed: %s.", e)); + } + } + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java new file mode 100644 index 00000000000..e01eeb21f6f --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmDetachNicExtensionPointImpl.java @@ -0,0 +1,75 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.zstack.compute.vm.CustomNicOperator; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.vm.VmDetachNicExtensionPoint; +import org.zstack.header.vm.VmFailToAttachL3NetworkExtensionPoint; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.identity.AccountManager; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortClient; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +public class VmDetachNicExtensionPointImpl implements VmDetachNicExtensionPoint, VmFailToAttachL3NetworkExtensionPoint { + private static final CLogger logger = Utils.getLogger(VmDetachNicExtensionPointImpl.class); + @Autowired + private DatabaseFacade dbf; + @Autowired + private AccountManager accountMgr; + + @Override + public void preDetachNic(VmNicInventory nic) { + } + + @Override + public void beforeDetachNic(VmNicInventory nic) { + L3NetworkVO l3nw = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + if (SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3nw.getType())) { + // bug fix: delete nic tags before detachL3Network, but won't delete nic tags when destroy vm + CustomNicOperator nicOperator = new CustomNicOperator(nic.getVmInstanceUuid(), l3nw.getUuid()); + nicOperator.deleteNicTags(); + } + } + + @Override + public void afterDetachNic(VmNicInventory nic) { + L3NetworkVO l3nw = dbf.findByUuid(nic.getL3NetworkUuid(), L3NetworkVO.class); + if (SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3nw.getType())) { + // bug fix: won't delete nic related tags, because recovery flow will use them + deleteTfPort(nic.getUuid()); + } + } + + @Override + public void failedToDetachNic(VmNicInventory nic, ErrorCode error) { + } + + @Override + public void vmFailToAttachL3Network(VmInstanceInventory vm, L3NetworkInventory l3, ErrorCode error) { + if (SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3.getType())) { + CustomNicOperator nicOperator = new CustomNicOperator(vm.getUuid(), l3.getUuid()); + String customNicId = nicOperator.getCustomNicId(); + nicOperator.deleteNicTags(); + deleteTfPort(customNicId); + } + } + + + + private void deleteTfPort(String nicUuid) { + TfPortClient client = new TfPortClient(); + TfPortResponse response = client.deletePort(StringDSL.transToTfUuid(nicUuid)); + if (response.getCode() != HttpStatus.OK.value()) { + throw new RuntimeException("failed to invoke deleting tf port: " + response); + } + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java new file mode 100644 index 00000000000..ac9bc51ef6c --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/network/VmPreAttachL3NetworkExtensionPointImpl.java @@ -0,0 +1,57 @@ +package org.zstack.sugonSdnController.network; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.compute.vm.CustomNicOperator; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.vm.VmPreAttachL3NetworkExtensionPoint; +import org.zstack.identity.AccountManager; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.sugonSdnController.controller.neutronClient.TfPortResponse; +import org.zstack.utils.StringDSL; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +/* + request tf sdn controller to create a port and set the returned ip & mac & portId to system tag for later use + */ +public class VmPreAttachL3NetworkExtensionPointImpl implements VmPreAttachL3NetworkExtensionPoint { + private static final CLogger logger = Utils.getLogger(VmPreAttachL3NetworkExtensionPointImpl.class); + @Autowired + protected AccountManager acntMgr; + @Autowired + private TfPortService tfPortService; + + @Override + public void vmPreAttachL3Network(VmInstanceInventory vm, L3NetworkInventory l3) { + if (!SugonSdnControllerConstant.L3_TF_NETWORK_TYPE.equals(l3.getType())) { + return; + } + String tfPortUuid = null; + VmNicInventory nicAttach = null; + for (VmNicInventory nic : vm.getVmNics()) { + String metadata = nic.getMetaData(); + if (metadata != null && metadata.equals("attachNic")) { + nicAttach = nic; + } + } + if (nicAttach != null) { + tfPortUuid = StringDSL.transToTfUuid(nicAttach.getUuid()); + TfPortResponse port = tfPortService.getTfPort(tfPortUuid); + if (port != null) { + tfPortService.updateTfPort(nicAttach.getUuid(), vm.getUuid(), null); + return; + } + } + TfPortResponse port = tfPortService.createTfPort(tfPortUuid, vm, l3); + + String finalMac = port.getMacAddress(); + String finalIp = port.getFixedIps().get(0).getIpAddress(); + String nicUuid = StringDSL.transToZstackUuid(port.getPortId()); + + CustomNicOperator nicOperator = new CustomNicOperator(vm.getUuid(), l3.getUuid()); + nicOperator.updateNicTags(finalMac,finalIp,nicUuid); + } + +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfNetworkServiceConstant.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfNetworkServiceConstant.java new file mode 100644 index 00000000000..1cfb34d7953 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfNetworkServiceConstant.java @@ -0,0 +1,11 @@ +package org.zstack.sugonSdnController.userdata; + +import org.zstack.header.network.service.NetworkServiceProviderType; + +/** + * Created by fuwei on 11/15/2022. + */ +public class TfNetworkServiceConstant { + public static final String TF_NETWORK_SERVICE_TYPE_STRING = "TF"; + public static final NetworkServiceProviderType TF_NETWORK_SERVICE_TYPE = new NetworkServiceProviderType(TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE_STRING); +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfProvider.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfProvider.java new file mode 100644 index 00000000000..d5eaf5198c8 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfProvider.java @@ -0,0 +1,37 @@ +package org.zstack.sugonSdnController.userdata; + +import org.zstack.header.message.Message; +import org.zstack.header.network.NetworkException; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.service.APIAttachNetworkServiceProviderToL2NetworkMsg; +import org.zstack.header.network.service.APIDetachNetworkServiceProviderFromL2NetworkMsg; +import org.zstack.header.network.service.NetworkServiceProvider; +import org.zstack.header.network.service.NetworkServiceProviderVO; + +/** + * Created by fuwei on 11/15/2022. + */ +public class TfProvider implements NetworkServiceProvider { + private NetworkServiceProviderVO self; + + public TfProvider(NetworkServiceProviderVO self) { + this.self = self; + } + + public TfProvider() { + } + + @Override + public void handleMessage(Message msg) { + } + + @Override + public void attachToL2Network(L2NetworkInventory l2Network, APIAttachNetworkServiceProviderToL2NetworkMsg msg) throws NetworkException { + + } + + @Override + public void detachFromL2Network(L2NetworkInventory l2Network, APIDetachNetworkServiceProviderFromL2NetworkMsg msg) throws NetworkException { + + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfProviderFactory.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfProviderFactory.java new file mode 100644 index 00000000000..72358bccc63 --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfProviderFactory.java @@ -0,0 +1,105 @@ +package org.zstack.sugonSdnController.userdata; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.Platform; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.SimpleQuery; +import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; +import org.zstack.header.network.NetworkException; +import org.zstack.header.network.l2.APICreateL2NetworkMsg; +import org.zstack.header.network.l2.L2NetworkCreateExtensionPoint; +import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.service.*; +import org.zstack.network.service.userdata.UserdataConstant; +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Created by fuwei on 11/15/2022. + */ +public class TfProviderFactory implements NetworkServiceProviderFactory, PrepareDbInitialValueExtensionPoint, + L2NetworkCreateExtensionPoint { + private static final CLogger logger = Utils.getLogger(TfProviderFactory.class); + + @Autowired + private DatabaseFacade dbf; + + private NetworkServiceProviderInventory tfProvider; + + @Override + public NetworkServiceProviderType getType() { + return TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE; + } + + @Override + public void createNetworkServiceProvider(APIAddNetworkServiceProviderMsg msg, NetworkServiceProviderVO vo) { + + } + + @Override + public NetworkServiceProvider getNetworkServiceProvider(NetworkServiceProviderVO vo) { + return new TfProvider(vo); + } + + @Override + public void prepareDbInitialValue() { + SimpleQuery query = dbf.createQuery(NetworkServiceProviderVO.class); + query.add(NetworkServiceProviderVO_.type, Op.EQ, TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE_STRING); + NetworkServiceProviderVO rpvo = query.find(); + if (rpvo != null) { + tfProvider = NetworkServiceProviderInventory.valueOf(rpvo); + + // check if any network service type missing, if any, complement them + SimpleQuery q = dbf.createQuery(NetworkServiceTypeVO.class); + q.add(NetworkServiceTypeVO_.networkServiceProviderUuid, Op.EQ, tfProvider.getUuid()); + List refs = q.list(); + Set types = new HashSet(); + for (NetworkServiceTypeVO ref : refs) { + types.add(ref.getType()); + } + + if (!types.contains(UserdataConstant.USERDATA_TYPE_STRING)) { + NetworkServiceTypeVO ref = new NetworkServiceTypeVO(); + ref.setNetworkServiceProviderUuid(tfProvider.getUuid()); + ref.setType(UserdataConstant.USERDATA_TYPE_STRING); + dbf.persist(ref); + } + + return; + } + + rpvo = new NetworkServiceProviderVO(); + rpvo.setUuid(Platform.getUuid()); + rpvo.setName("Tf Network Service Provider"); + rpvo.setDescription("Tf Network Service Provider"); + rpvo.getNetworkServiceTypes().add(UserdataConstant.USERDATA_TYPE_STRING); + rpvo.setType(TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE_STRING); + rpvo = dbf.persistAndRefresh(rpvo); + tfProvider = NetworkServiceProviderInventory.valueOf(rpvo); + logger.info("Success create Tf Network Service Provider"); + } + + @Override + public void beforeCreateL2Network(APICreateL2NetworkMsg msg) throws NetworkException { + + } + + @Override + public void afterCreateL2Network(L2NetworkInventory l2Network) { + if (!SugonSdnControllerConstant.L2_TF_NETWORK_TYPE.equals(l2Network.getType())){ + return; + } + NetworkServiceProviderL2NetworkRefVO ref = new NetworkServiceProviderL2NetworkRefVO(); + ref.setL2NetworkUuid(l2Network.getUuid()); + ref.setNetworkServiceProviderUuid(tfProvider.getUuid()); + dbf.persist(ref); + logger.debug(String.format("successfully attach flat network service provider[uuid:%s] to the L2 network[uuid:%s, name:%s]", + tfProvider.getUuid(), l2Network.getUuid(), l2Network.getName())); + } +} diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfUserdataBackend.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfUserdataBackend.java new file mode 100644 index 00000000000..ff2c5189a0a --- /dev/null +++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/userdata/TfUserdataBackend.java @@ -0,0 +1,564 @@ +package org.zstack.sugonSdnController.userdata; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import org.zstack.compute.vm.UserdataBuilder; +import org.zstack.compute.vm.VmSystemTags; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.gc.GC; +import org.zstack.core.gc.GCCompletion; +import org.zstack.core.gc.TimeBasedGarbageCollector; +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.core.workflow.FlowChainBuilder; +import org.zstack.core.workflow.ShareFlow; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.host.HostConstant; +import org.zstack.header.host.HostStatus; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.service.NetworkServiceProviderType; +import org.zstack.header.vm.*; +import org.zstack.kvm.*; +import org.zstack.kvm.KVMAgentCommands.AgentResponse; +import org.zstack.network.service.NetworkProviderFinder; +import org.zstack.network.service.NetworkServiceFilter; +import org.zstack.network.service.NetworkServiceManager; +import org.zstack.network.service.userdata.*; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; + +import javax.persistence.Tuple; +import javax.persistence.TypedQuery; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +/** + * Created by fuwei on 11/15/2022. + */ +public class TfUserdataBackend implements UserdataBackend, KVMHostConnectExtensionPoint, + VmInstanceMigrateExtensionPoint { + private static final CLogger logger = Utils.getLogger(TfUserdataBackend.class); + + @Autowired + private CloudBus bus; + @Autowired + private DatabaseFacade dbf; + @Autowired + private NetworkServiceManager nsMgr; + + public static final String APPLY_USER_DATA = "/tfnetworkprovider/userdata/apply"; + public static final String BATCH_APPLY_USER_DATA = "/tfnetworkprovider/userdata/batchapply"; + public static final String RELEASE_USER_DATA = "/tfnetworkprovider/userdata/release"; + + @Override + public Flow createKvmHostConnectingFlow(final KVMHostConnectedContext context) { + return new NoRollbackFlow() { + String __name__ = "prepare-userdata"; + + @Transactional(readOnly = true) + private List getVmsNeedUserdataOnHost() { + String sql = "select vm.uuid from VmInstanceVO vm where vm.hostUuid = :huuid and vm.state = :state and vm.type = :type"; + TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); + q.setParameter("state", VmInstanceState.Running); + q.setParameter("huuid", context.getInventory().getUuid()); + q.setParameter("type", VmInstanceConstant.USER_VM_TYPE); + List vmUuids = q.getResultList(); + if (vmUuids.isEmpty()) { + return null; + } + + vmUuids = new NetworkServiceFilter().filterVmByServiceTypeAndProviderType(vmUuids, UserdataConstant.USERDATA_TYPE_STRING, TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE_STRING); + if (vmUuids.isEmpty()) { + return null; + } + + return vmUuids; + } + + class VmIpL3Uuid { + String vmIp; + String netmask; + String l3Uuid; + } + + @Transactional(readOnly = true) + private Map getVmIpL3Uuid(List vmUuids) { + String sql = "select vm.uuid, ip.ip, ip.l3NetworkUuid, ip.netmask from VmInstanceVO vm," + + "VmNicVO nic, NetworkServiceL3NetworkRefVO ref," + + "NetworkServiceProviderVO pro, UsedIpVO ip where " + + " vm.uuid = nic.vmInstanceUuid and vm.uuid in (:uuids)" + + " and nic.uuid = ip.vmNicUuid " + + " and ip.l3NetworkUuid = vm.defaultL3NetworkUuid and ip.ipVersion = :ipversion" + + " and ref.networkServiceProviderUuid = pro.uuid" + + " and ref.l3NetworkUuid = vm.defaultL3NetworkUuid" + + " and pro.type = :proType"; + + TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); + q.setParameter("uuids", vmUuids); + q.setParameter("proType", TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE_STRING); + /* current only ipv4 has userdata */ + q.setParameter("ipversion", IPv6Constants.IPv4); + List ts = q.getResultList(); + + Map ret = new HashMap(); + for (Tuple t : ts) { + String vmUuid = t.get(0, String.class); + VmIpL3Uuid v = new VmIpL3Uuid(); + v.vmIp = t.get(1, String.class); + v.l3Uuid = t.get(2, String.class); + v.netmask = t.get(3, String.class); + ret.put(vmUuid, v); + } + + return ret; + } + + private List getUserData() { + List vmUuids = getVmsNeedUserdataOnHost(); + if (vmUuids == null) { + return null; + } + + Map vmipl3 = getVmIpL3Uuid(vmUuids); + if (vmipl3.isEmpty()) { + return null; + } + + // filter out vm that not using tf network provider + vmUuids = vmUuids.stream().filter(vmipl3::containsKey).collect(Collectors.toList()); + if (vmUuids.isEmpty()) { + return null; + } + + Map> userdata = new UserdataBuilder().buildByVmUuids(vmUuids); + + List tos = new ArrayList(); + for (String vmuuid : vmUuids) { + UserdataTO to = new UserdataTO(); + MetadataTO mto = new MetadataTO(); + mto.vmUuid = vmuuid; + mto.vmHostname = VmSystemTags.HOSTNAME.getTokenByResourceUuid(vmuuid, VmSystemTags.HOSTNAME_TOKEN); + to.metadata = mto; + + VmIpL3Uuid l = vmipl3.get(vmuuid); + if (l.vmIp == null) { + continue; + } + + to.vmIp = l.vmIp; + to.netmask = l.netmask; + if (userdata.get(vmuuid) != null) { + to.userdataList.addAll(userdata.get(vmuuid)); + } + to.port = UserdataGlobalProperty.HOST_PORT; + to.l3NetworkUuid = l.l3Uuid; + to.agentConfig = new HashMap<>(); + tos.add(to); + } + + return tos; + } + + @Override + public void run(final FlowTrigger trigger, Map data) { + List tos = getUserData(); + if (tos == null) { + trigger.next(); + return; + } + + BatchApplyUserdataCmd cmd = new BatchApplyUserdataCmd(); + cmd.userdata = tos; + cmd.rebuild = true; + + new KvmCommandSender(context.getInventory().getUuid(), true).send(cmd, BATCH_APPLY_USER_DATA, new KvmCommandFailureChecker() { + @Override + public ErrorCode getError(KvmResponseWrapper wrapper) { + AgentResponse rsp = wrapper.getResponse(AgentResponse.class); + return rsp.isSuccess() ? null : operr("operation error, because:%s", rsp.getError()); + } + }, new ReturnValueCompletion(trigger) { + @Override + public void success(KvmResponseWrapper returnValue) { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + }; + } + + private UserdataStruct makeUserdataStructForMigratingVm(VmInstanceInventory inv, String hostUuid) { + if (!nsMgr.isVmNeedNetworkService(inv.getType(), UserdataConstant.USERDATA_TYPE)) { + return null; + } + + String providerType = new NetworkProviderFinder().getNetworkProviderTypeByNetworkServiceType(inv.getDefaultL3NetworkUuid(), UserdataConstant.USERDATA_TYPE_STRING); + if (!TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE_STRING.equals(providerType)) { + return null; + } + + List userdataList = new UserdataBuilder().buildByVmUuid(inv.getUuid()); + if (userdataList == null) { + // Apply userdata anyway after migrating VM to redeploy lighttpd server + // so that the VM can still send metric data to pushgateway through lighttpd + userdataList = Collections.emptyList(); + } + + UserdataStruct struct = new UserdataStruct(); + struct.setParametersFromVmInventory(inv); + struct.setHostUuid(hostUuid); + struct.setL3NetworkUuid(inv.getDefaultL3NetworkUuid()); + struct.setUserdataList(userdataList); + return struct; + } + + + @Override + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { + UserdataStruct struct = makeUserdataStructForMigratingVm(inv, destHostUuid); + if (struct == null) { + completion.success(); + return; + } + + applyUserdata(struct, completion); + } + + @Override + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { + } + + public static class UserdataReleseGC extends TimeBasedGarbageCollector { + public static long INTERVAL = 300; + + @GC + public UserdataStruct struct; + + @Override + protected void triggerNow(GCCompletion completion) { + + HostStatus status = Q.New(HostVO.class).select(HostVO_.status).eq(HostVO_.uuid, struct.getHostUuid()).findValue(); + if (status == null) { + // host deleted + completion.cancel(); + return; + } + + if (status != HostStatus.Connected) { + completion.fail(operr("host[uuid:%s] is not connected", struct.getHostUuid())); + return; + } + + ReleaseUserdataCmd cmd = new ReleaseUserdataCmd(); + cmd.hostUuid = struct.getHostUuid(); + cmd.vmIp = CollectionUtils.find(struct.getVmNics(), arg -> arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null); + cmd.vmUuid = struct.getVmUuid(); + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(struct.getHostUuid()); + msg.setCommand(cmd); + msg.setPath(RELEASE_USER_DATA); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, struct.getHostUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply r = reply.castReply(); + ReleaseUserdataRsp rsp = r.toResponse(ReleaseUserdataRsp.class); + if (!rsp.isSuccess()) { + completion.fail(operr("operation error, because:%s", rsp.getError())); + return; + } + + completion.success(); + } + }); + } + } + + @Override + public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { + UserdataStruct struct = makeUserdataStructForMigratingVm(inv, srcHostUuid); + if (struct == null) { + return; + } + + releaseUserdata(struct, new Completion(null) { + @Override + public void success() { + // nothing + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("failed to release userdata on the source host[uuid:%s]" + + " for the migrated VM[uuid: %s, name:%s], %s. GC will take care it", srcHostUuid, inv.getUuid(), inv.getName(), errorCode)); + UserdataReleseGC gc = new UserdataReleseGC(); + gc.struct = struct; + gc.submit(UserdataReleseGC.INTERVAL, TimeUnit.SECONDS); + } + }); + } + + @Override + public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) { + if (destHostUuid == null) { + return; + } + + UserdataStruct struct = makeUserdataStructForMigratingVm(inv, destHostUuid); + if (struct == null) { + return; + } + + // clean the userdata that set on the dest host + releaseUserdata(struct, new Completion(null) { + @Override + public void success() { + // nothing + } + + @Override + public void fail(ErrorCode errorCode) { + UserdataReleseGC gc = new UserdataReleseGC(); + gc.struct = struct; + gc.submit(UserdataReleseGC.INTERVAL, TimeUnit.SECONDS); + } + }); + } + + public static class UserdataTO { + public MetadataTO metadata; + public List userdataList = new ArrayList<>(); + public String vmIp; + public String netmask; + public String l3NetworkUuid; + public Map agentConfig; + public int port; + } + + public static class MetadataTO { + public String vmUuid; + public String vmHostname; + } + + public static class BatchApplyUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + public List userdata; + @GrayVersion(value = "5.0.0") + public boolean rebuild; + } + + public static class ApplyUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + public String hostUuid; + @GrayVersion(value = "5.0.0") + public UserdataTO userdata; + } + + public static class ApplyUserdataRsp extends AgentResponse { + + } + + public static class ReleaseUserdataCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + public String hostUuid; + @GrayVersion(value = "5.0.0") + public String vmIp; + @GrayVersion(value = "5.0.0") + public String vmUuid; + } + + public static class ReleaseUserdataRsp extends AgentResponse { + } + + @Override + public NetworkServiceProviderType getProviderType() { + return TfNetworkServiceConstant.TF_NETWORK_SERVICE_TYPE; + } + + private boolean hasMetedata(UserdataStruct struct) { + return VmSystemTags.HOSTNAME.getTokenByResourceUuid(struct.getVmUuid(), VmSystemTags.HOSTNAME_TOKEN) != null; + } + + private boolean hasUserdata(UserdataStruct struct) { + return struct.getUserdataList() != null && !struct.getUserdataList().isEmpty(); + } + + @Override + public void applyUserdata(final UserdataStruct struct, final Completion completion) { + if (!UserdataGlobalConfig.OPEN_USERDATA_SERVICE_BY_DEFAULT.value(Boolean.class)) { + if ( !hasMetedata(struct) && !hasUserdata(struct)) { + completion.success(); + return; + } + } + + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("tf-network-userdata-set-for-vm-%s", struct.getVmUuid())); + chain.then(new ShareFlow() { + + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "apply-user-data"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + ApplyUserdataCmd cmd = new ApplyUserdataCmd(); + cmd.hostUuid = struct.getHostUuid(); + + MetadataTO to = new MetadataTO(); + to.vmUuid = struct.getVmUuid(); + to.vmHostname = VmSystemTags.HOSTNAME.getTokenByResourceUuid(struct.getVmUuid(), VmSystemTags.HOSTNAME_TOKEN); + UserdataTO uto = new UserdataTO(); + uto.metadata = to; + uto.userdataList = struct.getUserdataList(); + uto.vmIp = CollectionUtils.find(struct.getVmNics(), new Function() { + @Override + public String call(VmNicInventory arg) { + return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null; + } + }); + uto.netmask = CollectionUtils.find(struct.getVmNics(), new Function() { + @Override + public String call(VmNicInventory arg) { + return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getNetmask() : null; + } + }); + uto.port = UserdataGlobalProperty.HOST_PORT; + uto.l3NetworkUuid = struct.getL3NetworkUuid(); + uto.agentConfig = new HashMap<>(); + cmd.userdata = uto; + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(struct.getHostUuid()); + msg.setCommand(cmd); + msg.setPath(APPLY_USER_DATA); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, struct.getHostUuid()); + bus.send(msg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply r = reply.castReply(); + ApplyUserdataRsp rsp = r.toResponse(ApplyUserdataRsp.class); + if (!rsp.isSuccess()) { + trigger.fail(operr("operation error, because:%s", rsp.getError())); + return; + } + + trigger.next(); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + @Override + public void releaseUserdata(final UserdataStruct struct, final Completion completion) { + + FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("tf-network-userdata-release-for-vm-%s", struct.getVmUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + flow(new NoRollbackFlow() { + String __name__ = "release-user-data"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + ReleaseUserdataCmd cmd = new ReleaseUserdataCmd(); + cmd.hostUuid = struct.getHostUuid(); + cmd.vmIp = CollectionUtils.find(struct.getVmNics(), new Function() { + @Override + public String call(VmNicInventory arg) { + return arg.getL3NetworkUuid().equals(struct.getL3NetworkUuid()) ? arg.getIp() : null; + } + }); + cmd.vmUuid = struct.getVmUuid(); + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setHostUuid(struct.getHostUuid()); + msg.setCommand(cmd); + msg.setPath(RELEASE_USER_DATA); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, struct.getHostUuid()); + bus.send(msg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + trigger.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply r = reply.castReply(); + ReleaseUserdataRsp rsp = r.toResponse(ReleaseUserdataRsp.class); + if (!rsp.isSuccess()) { + trigger.fail(operr("operation error, because:%s", rsp.getError())); + return; + } + + trigger.next(); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } +} diff --git a/plugin/vhost/pom.xml b/plugin/vhost/pom.xml new file mode 100644 index 00000000000..a132e6b2567 --- /dev/null +++ b/plugin/vhost/pom.xml @@ -0,0 +1,89 @@ + + + + plugin + org.zstack + 5.4.0 + + 4.0.0 + + vhost + + + + org.zstack + kvm + ${project.version} + + + org.zstack + storage + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + diff --git a/plugin/vhost/src/main/java/org/zstack/vhost/kvm/KvmVhostNodeServer.java b/plugin/vhost/src/main/java/org/zstack/vhost/kvm/KvmVhostNodeServer.java new file mode 100644 index 00000000000..5b9cf5623e6 --- /dev/null +++ b/plugin/vhost/src/main/java/org/zstack/vhost/kvm/KvmVhostNodeServer.java @@ -0,0 +1,147 @@ +package org.zstack.vhost.kvm; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.Component; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.HostInventory; +import org.zstack.header.storage.addon.primary.BaseVolumeInfo; +import org.zstack.header.storage.addon.primary.PrimaryStorageNodeSvc; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeProtocol; +import org.zstack.header.volume.VolumeProtocolCapability; +import org.zstack.kvm.*; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.zstack.core.Platform.argerr; + +public class KvmVhostNodeServer implements Component, KVMStartVmExtensionPoint, + KVMConvertVolumeExtensionPoint, KVMDetachVolumeExtensionPoint, KVMAttachVolumeExtensionPoint { + @Autowired + private ExternalPrimaryStorageFactory extPsFactory; + + private PluginRegistry pluginRgty; + + private static final VolumeProtocolCapability capability = VolumeProtocolCapability + .register(VolumeProtocol.Vhost.name(), KVMConstant.KVM_HYPERVISOR_TYPE); + + static { + capability.setSupportQosOnHypervisor(false); + capability.setSupportResizeOnHypervisor(false); + capability.setSupportReadonly(false); + } + + + @Override + public void beforeStartVmOnKvm(KVMHostInventory host, VmInstanceSpec spec, KVMAgentCommands.StartVmCmd cmd) { + cmd.setRootVolume(convertVolumeIfNeeded(spec.getDestRootVolume(), host, cmd.getRootVolume())); + + List dtos = new ArrayList<>(); + for (VolumeTO to : cmd.getDataVolumes()) { + for (VolumeInventory vol : spec.getDestDataVolumes()) { + if (vol.getUuid().equals(to.getVolumeUuid())) { + dtos.add(convertVolumeIfNeeded(vol, host, to)); + break; + } + } + } + + cmd.setDataVolumes(dtos); + if (VolumeProtocol.Vhost.name().equals(spec.getDestRootVolume().getProtocol()) || + spec.getDestDataVolumes().stream().anyMatch(v -> VolumeProtocol.Vhost.name().equals(v.getProtocol()))) { + cmd.setUseHugePage(true); + cmd.setMemAccess("shared"); + } + + // vhostuser disk not support readonly mode, so no iso. + } + + @Override + public void startVmOnKvmSuccess(KVMHostInventory host, VmInstanceSpec spec) { + + } + + @Override + public void startVmOnKvmFailed(KVMHostInventory host, VmInstanceSpec spec, ErrorCode err) { + + } + + + private PrimaryStorageNodeSvc getNodeService(VolumeInventory volumeInventory) { + String identity = volumeInventory.getInstallPath().split("://")[0]; + if (!extPsFactory.support(identity)) { + return null; + } + + return extPsFactory.getNodeSvc(volumeInventory.getPrimaryStorageUuid()); + } + + private VolumeTO convertVolumeIfNeeded(VolumeInventory volumeInventory, HostInventory host, VolumeTO volumeTO) { + if (!VolumeProtocol.Vhost.name().equals(volumeInventory.getProtocol())) { + return volumeTO; + } + + if (!volumeTO.isUseVirtio()) { + throw new OperationFailureException( + argerr("vhostuser disk only support virtio mode, check image platform has virtio driver or not")); + } + + if (volumeTO.isUseVirtioSCSI()) { + throw new OperationFailureException( + argerr("vhostuser disk not support virtio-scsi mode, please turn off virtio-scsi mode")); + } + + PrimaryStorageNodeSvc nodeSvc = getNodeService(volumeInventory); + if (nodeSvc == null) { + return volumeTO; + } + + String path = nodeSvc.getActivePath(BaseVolumeInfo.valueOf(volumeInventory), host,false); + volumeTO.setInstallPath(path); + return volumeTO; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return false; + } + + @Override + public VolumeTO convertVolumeIfNeed(KVMHostInventory host, VolumeInventory inventory, VolumeTO to) { + return convertVolumeIfNeeded(inventory, host, to); + } + + @Override + public void beforeDetachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.DetachDataVolumeCmd cmd) { + cmd.setVolume(convertVolumeIfNeeded(volume, host, cmd.getVolume())); + } + + @Override + public void afterDetachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.DetachDataVolumeCmd cmd) { } + + @Override + public void detachVolumeFailed(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.DetachDataVolumeCmd cmd, ErrorCode err) { } + + @Override + public void beforeAttachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.AttachDataVolumeCmd cmd, Map data) { + cmd.setVolume(convertVolumeIfNeeded(volume, host, cmd.getVolume())); + } + + @Override + public void afterAttachVolume(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.AttachDataVolumeCmd cmd) {} + @Override + public void attachVolumeFailed(KVMHostInventory host, VmInstanceInventory vm, VolumeInventory volume, KVMAgentCommands.AttachDataVolumeCmd cmd, ErrorCode err, Map data) {} +} diff --git a/plugin/vhost/src/main/java/org/zstack/vhost/kvm/VhostVolumeTO.java b/plugin/vhost/src/main/java/org/zstack/vhost/kvm/VhostVolumeTO.java new file mode 100644 index 00000000000..6ae1157d629 --- /dev/null +++ b/plugin/vhost/src/main/java/org/zstack/vhost/kvm/VhostVolumeTO.java @@ -0,0 +1,10 @@ +package org.zstack.vhost.kvm; + +import org.zstack.header.storage.addon.primary.ActiveVolumeTO; +import org.zstack.header.volume.VolumeProtocol; + +public class VhostVolumeTO extends ActiveVolumeTO { + { + protocol = VolumeProtocol.Vhost.name(); + } +} diff --git a/plugin/vip/pom.xml b/plugin/vip/pom.xml index 49a57d310cd..ec953869f29 100755 --- a/plugin/vip/pom.xml +++ b/plugin/vip/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIChangeVipStateMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIChangeVipStateMsgDoc_zh_cn.groovy index cee7151cec3..4eaa931bc11 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIChangeVipStateMsgDoc_zh_cn.groovy +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIChangeVipStateMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "stateEvent" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityMsg.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityMsg.java new file mode 100755 index 00000000000..7f8b31e29a0 --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityMsg.java @@ -0,0 +1,59 @@ +package org.zstack.network.service.vip; +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.message.APIGetMessage; +import org.zstack.network.service.vip.*; + +@RestRequest( + path = "/vips/{vipUuid}/check-port-availability", + method = HttpMethod.GET, + responseClass = APICheckVipPortAvailabilityReply.class +) +public class APICheckVipPortAvailabilityMsg extends APIGetMessage { + + @APIParam(resourceType = VipVO.class) + private String vipUuid; + + @APIParam(numberRange = {1, 65535}) + private int port; + + @APIParam(validValues = {"TCP", "UDP"}) + private String protocolType; + + public String getVipUuid() { + return vipUuid; + } + + public void setVipUuid(String vipUuid) { + this.vipUuid = vipUuid; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } + + + public static APICheckVipPortAvailabilityMsg __example__() { + APICheckVipPortAvailabilityMsg msg = new APICheckVipPortAvailabilityMsg(); + msg.setVipUuid(uuid()); + msg.setPort(5); + msg.setProtocolType("TCP"); + return msg; + } +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..3cc1a2bebc3 --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityMsgDoc_zh_cn.groovy @@ -0,0 +1,95 @@ +package org.zstack.network.service.vip + +import org.zstack.network.service.vip.APICheckVipPortAvailabilityReply + +doc { + title "CheckVipPortAvailability" + + category "vip" + + desc """检查VIP端口是否空闲""" + + rest { + request { + url "GET /v1/vips/{vipUuid}/check-port-availability" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICheckVipPortAvailabilityMsg.class + + desc """""" + + params { + + column { + name "vipUuid" + enclosedIn "" + desc "VIP UUID" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "port" + enclosedIn "" + desc "" + location "query" + type "int" + optional false + since "4.7.21" + } + column { + name "protocolType" + enclosedIn "" + desc "" + location "query" + type "String" + optional false + since "4.7.21" + values ("TCP","UDP") + } + column { + name "limit" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.7.21" + } + column { + name "start" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APICheckVipPortAvailabilityReply.class + } + } +} \ No newline at end of file diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityReply.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityReply.java new file mode 100755 index 00000000000..fefd82d475b --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityReply.java @@ -0,0 +1,28 @@ +package org.zstack.network.service.vip; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import java.util.ArrayList; +import java.sql.Timestamp; +import org.zstack.header.message.APIReply; +import java.util.List; + +@RestResponse(fieldsTo = {"all"}) +public class APICheckVipPortAvailabilityReply extends APIReply { + + private boolean available; + + public boolean isAvailable() { + return available; + } + + public void setAvailable(boolean available) { + this.available = available; + } + + public static APICheckVipPortAvailabilityReply __example__() { + APICheckVipPortAvailabilityReply reply = new APICheckVipPortAvailabilityReply(); + reply.setAvailable(true); + return reply; + } + +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityReplyDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..233d5e8d358 --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICheckVipPortAvailabilityReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.network.service.vip + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "检查VIP端口是否空闲" + + field { + name "available" + desc "" + type "boolean" + since "4.7.21" + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.service.vip.APICheckVipPortAvailabilityReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsg.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsg.java index 487d83cb6d3..dbc77bac1d7 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsg.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsg.java @@ -88,7 +88,7 @@ public class APICreateVipMsg extends APICreateMessage implements L3NetworkMessag @APINoSee private boolean system; - @APINoSee + @APIParam(required = false) private Integer ipVersion; public String getRequiredIp() { diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsgDoc_zh_cn.groovy index 5932098738f..733654d0a2c 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsgDoc_zh_cn.groovy +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APICreateVipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "l3NetworkUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "ipRangeUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "3.9" - } column { name "allocatorStrategy" @@ -69,7 +65,15 @@ doc { type "String" optional true since "0.6" - + } + column { + name "ipVersion" + enclosedIn "params" + desc "IP版本" + location "body" + type "Integer" + optional true + since "5.1" } column { name "requiredIp" @@ -79,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -89,7 +92,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -99,7 +101,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -109,7 +110,15 @@ doc { type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIDeleteVipMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIDeleteVipMsgDoc_zh_cn.groovy index a0bda6333dc..167ba657b5e 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIDeleteVipMsgDoc_zh_cn.groovy +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIDeleteVipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortMsg.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortMsg.java new file mode 100755 index 00000000000..c984efedd66 --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortMsg.java @@ -0,0 +1,48 @@ +package org.zstack.network.service.vip; +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.message.APIGetMessage; +import org.zstack.network.service.vip.*; + +@RestRequest( + path = "/vips/{vipUuid}/get-port-availability", + method = HttpMethod.GET, + responseClass = APIGetVipAvailablePortReply.class +) +public class APIGetVipAvailablePortMsg extends APIGetMessage { + + @APIParam(resourceType = VipVO.class) + private String vipUuid; + + @APIParam(validValues = {"TCP", "UDP"}) + private String protocolType; + + public String getVipUuid() { + return vipUuid; + } + + public void setVipUuid(String vipUuid) { + this.vipUuid = vipUuid; + } + + public String getProtocolType() { + return protocolType; + } + + public void setProtocolType(String protocolType) { + this.protocolType = protocolType; + } + + public static APIGetVipAvailablePortMsg __example__() { + APIGetVipAvailablePortMsg msg = new APIGetVipAvailablePortMsg(); + msg.setVipUuid(uuid()); + msg.setProtocolType("UDP"); + msg.setStart(1); + msg.setLimit(10); + return msg; + } +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..353f964e28e --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortMsgDoc_zh_cn.groovy @@ -0,0 +1,86 @@ +package org.zstack.network.service.vip + +import org.zstack.network.service.vip.APIGetVipAvailablePortReply + +doc { + title "GetVipAvailablePort" + + category "vip" + + desc """获取VIP空闲端口""" + + rest { + request { + url "GET /v1/vips/{vipUuid}/get-port-availability" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIGetVipAvailablePortMsg.class + + desc """""" + + params { + + column { + name "vipUuid" + enclosedIn "" + desc "VIP UUID" + location "url" + type "String" + optional false + since "4.7.21" + } + column { + name "protocolType" + enclosedIn "" + desc "" + location "query" + type "String" + optional false + since "4.7.21" + values ("TCP","UDP") + } + column { + name "limit" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.7.21" + } + column { + name "start" + enclosedIn "" + desc "" + location "query" + type "Integer" + optional true + since "4.7.21" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "query" + type "List" + optional true + since "4.7.21" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "query" + type "List" + optional true + since "4.7.21" + } + } + } + + response { + clz APIGetVipAvailablePortReply.class + } + } +} \ No newline at end of file diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortReply.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortReply.java new file mode 100755 index 00000000000..8071cc1f0d8 --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortReply.java @@ -0,0 +1,31 @@ +package org.zstack.network.service.vip; +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import java.util.ArrayList; +import java.sql.Timestamp; +import org.zstack.header.message.APIReply; +import java.util.List; + +@RestResponse(fieldsTo = {"all"}) +public class APIGetVipAvailablePortReply extends APIReply { + private List availablePort; + + public List getAvailablePort() { + return availablePort; + } + + public void setAvailablePort(List availablePort) { + this.availablePort = availablePort; + } + + public static APIGetVipAvailablePortReply __example__() { + APIGetVipAvailablePortReply reply = new APIGetVipAvailablePortReply(); + List availablePort = new ArrayList(); + availablePort.add(1); + availablePort.add(2); + + reply.setAvailablePort(availablePort); + return reply; + } + +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortReplyDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortReplyDoc_zh_cn.groovy new file mode 100644 index 00000000000..7b6bf8c8355 --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIGetVipAvailablePortReplyDoc_zh_cn.groovy @@ -0,0 +1,29 @@ +package org.zstack.network.service.vip + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "获取VIP空闲端口" + + field { + name "availablePort" + desc "" + type "List" + since "4.7.21" + } + field { + name "success" + desc "" + type "boolean" + since "4.7.21" + } + ref { + name "error" + path "org.zstack.network.service.vip.APIGetVipAvailablePortReply.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.21" + clz ErrorCode.class + } +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIQueryVipMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIQueryVipMsgDoc_zh_cn.groovy index ffe305950bc..dffb8ec49ca 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIQueryVipMsgDoc_zh_cn.groovy +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIQueryVipMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.vip import org.zstack.network.service.vip.APIQueryVipReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "QueryVip" diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIUpdateVipMsgDoc_zh_cn.groovy b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIUpdateVipMsgDoc_zh_cn.groovy index 526be834bcb..96b1fa16b34 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/APIUpdateVipMsgDoc_zh_cn.groovy +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/APIUpdateVipMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -49,7 +47,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -69,7 +65,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/AfterAcquireVipExtensionPoint.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/AfterAcquireVipExtensionPoint.java index 7032f10b3ae..b712d514766 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/AfterAcquireVipExtensionPoint.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/AfterAcquireVipExtensionPoint.java @@ -1,5 +1,7 @@ package org.zstack.network.service.vip; +import java.util.List; + public interface AfterAcquireVipExtensionPoint { - void afterAcquireVip(VipInventory vipInventory); + void afterAcquireVip(List vipList); } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/CreateVipMsg.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/CreateVipMsg.java index fbec72f24f9..18cef71e4ed 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/CreateVipMsg.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/CreateVipMsg.java @@ -1,13 +1,14 @@ package org.zstack.network.service.vip; import org.zstack.header.identity.SessionInventory; +import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.message.NeedReplyMessage; import org.zstack.identity.Session; /** * Created by shixin on 2019/05/17. */ -public class CreateVipMsg extends NeedReplyMessage { +public class CreateVipMsg extends NeedReplyMessage implements NeedQuotaCheckMessage { private String name; private String description; private String l3NetworkUuid; @@ -16,6 +17,7 @@ public class CreateVipMsg extends NeedReplyMessage { private SessionInventory session; private boolean system; private Integer ipVersion; + private String accountUuid; public String getName() { return name; @@ -80,4 +82,18 @@ public Integer getIpVersion() { public void setIpVersion(Integer ipVersion) { this.ipVersion = ipVersion; } + + @Override + public String getAccountUuid() { + if (session == null) { + return accountUuid; + } + + return session.getAccountUuid(); + } + + @Override + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/GetProviderUuidOfNetworkServiceUseTheVip.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/GetProviderUuidOfNetworkServiceUseTheVip.java new file mode 100644 index 00000000000..2ea6ea3914a --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/GetProviderUuidOfNetworkServiceUseTheVip.java @@ -0,0 +1,5 @@ +package org.zstack.network.service.vip; + +public interface GetProviderUuidOfNetworkServiceUseTheVip { + String getProviderUuidOfNetworkServiceUseTheVip(String serviceUuid); +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/PackageInfo.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/PackageInfo.java index e2fde82bc54..8f40b7ab0d8 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/PackageInfo.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "虚拟IP") +@PackageAPIInfo( + APICategoryName = "虚拟IP", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java index fd9d06a09e2..b4ca7a267c0 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipApiInterceptor.java @@ -7,21 +7,32 @@ import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.errorcode.SysErrors; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; import org.zstack.header.apimediator.StopRoutingException; import org.zstack.header.message.APIMessage; import org.zstack.header.network.l3.*; +import org.zstack.header.vm.APIAttachL3NetworkToVmMsg; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; import static org.zstack.core.Platform.argerr; import static org.zstack.core.Platform.operr; +import org.apache.commons.collections.CollectionUtils; +import org.zstack.identity.AccountManager; +import org.zstack.header.identity.AccountConstant; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; /** */ -public class VipApiInterceptor implements ApiMessageInterceptor { +public class VipApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { @Autowired private ErrorFacade errf; @Autowired @@ -30,17 +41,70 @@ public class VipApiInterceptor implements ApiMessageInterceptor { private CloudBus bus; @Autowired private VipManager vipMgr; + @Autowired + private AccountManager acntMgr; + + @Override + public List getMessageClassToIntercept() { + List ret = new ArrayList<>(); + ret.add(APIDeleteIpAddressMsg.class); + return ret; + } + + @Override + public InterceptorPosition getPosition() { + return InterceptorPosition.END; + } @Override public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { if (msg instanceof APICreateVipMsg) { validate((APICreateVipMsg) msg); + } else if (msg instanceof APIGetVipAvailablePortMsg) { + validate((APIGetVipAvailablePortMsg) msg); + } else if (msg instanceof APICheckVipPortAvailabilityMsg) { + validate((APICheckVipPortAvailabilityMsg) msg); } else if (msg instanceof APIDeleteVipMsg) { validate((APIDeleteVipMsg) msg); + } else if (msg instanceof APIDeleteIpAddressMsg) { + validate((APIDeleteIpAddressMsg) msg); } return msg; } + private void checkVipBelongToAccount(String vipUuid, String accountUuid) { + + if (!accountUuid.equals(AccountConstant.INITIAL_SYSTEM_ADMIN_UUID)) { + List accessibleUuids = acntMgr.getResourceUuidsCanAccessByAccount(accountUuid, VipVO.class); + + if (accessibleUuids == null || accessibleUuids.isEmpty()) { + throw new ApiMessageInterceptionException(argerr("account have no vips")); + } + if (!accessibleUuids.contains(vipUuid)) { + throw new ApiMessageInterceptionException(argerr("vip can not be accessed by this account")); + } + } + } + + private void validate(APICheckVipPortAvailabilityMsg msg) { + String accountUuid = msg.getSession().getAccountUuid(); + checkVipBelongToAccount(msg.getVipUuid(), accountUuid); + } + + private void validate(APIGetVipAvailablePortMsg msg) { + String accountUuid = msg.getSession().getAccountUuid(); + checkVipBelongToAccount(msg.getVipUuid(), accountUuid); + } + + private void validate(APIDeleteIpAddressMsg msg) { + for (String uuid : msg.getUsedIpUuids()) { + UsedIpVO ip = dbf.findByUuid(uuid, UsedIpVO.class); + if (Q.New(VipVO.class).eq(VipVO_.l3NetworkUuid, ip.getL3NetworkUuid()) + .eq(VipVO_.ip, ip.getIp()).isExists()) { + throw new ApiMessageInterceptionException(argerr("could delete ip, because ip[uuid:%s] is a vip", ip.getIp())); + } + } + } private void validate(APIDeleteVipMsg msg) { VipVO vipVO = dbf.findByUuid(msg.getVipUuid(), VipVO.class); diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBase.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBase.java index a3da3797245..866c5220760 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBase.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBase.java @@ -1,5 +1,6 @@ package org.zstack.network.service.vip; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; @@ -36,6 +37,7 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkConstant; import org.zstack.header.network.l3.ReturnIpMsg; +import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.network.service.VirtualRouterHaGroupExtensionPoint; import org.zstack.header.vm.VmNicVO; import org.zstack.header.vm.VmNicVO_; @@ -465,7 +467,15 @@ protected void acquireVip(ModifyVipAttributesStruct s, Completion completion) { VipFactory f = vipMgr.getVipFactory(self.getServiceProvider()); VipBaseBackend vip = f.getVip(getSelf()); - vip.acquireVipOnBackend(new Completion(completion) { + String providerUuid = null; + for (GetProviderUuidOfNetworkServiceUseTheVip ext : pluginRgty.getExtensionList(GetProviderUuidOfNetworkServiceUseTheVip.class)) { + providerUuid = ext.getProviderUuidOfNetworkServiceUseTheVip(s.getServiceUuid()); + if (!StringUtils.isEmpty(providerUuid)) { + break; + } + } + + vip.acquireVipOnSpecificBackend(providerUuid, new Completion(completion) { @Override public void success() { logger.debug(String.format("successfully acquired vip[uuid:%s, name:%s, ip:%s] on service[%s]", @@ -964,7 +974,10 @@ public void clearPeerL3Network() { private void addServicesRef(String uuid, String type) { VipNetworkServicesRefVO vipRef = new VipNetworkServicesRefVO(); - if (dbf.isExist(uuid, VipNetworkServicesRefVO.class)) { + if (Q.New(VipNetworkServicesRefVO.class) + .eq(VipNetworkServicesRefVO_.uuid, uuid) + .eq(VipNetworkServicesRefVO_.vipUuid, self.getUuid()) + .eq(VipNetworkServicesRefVO_.serviceType, type).isExists()) { logger.debug(String.format("repeat to add the servicesRef [type:%s:uuid:%s] with vip[uuid:%s]", type, uuid, self.getUuid())); return; @@ -989,8 +1002,11 @@ private void addServicesRef(String uuid, String type) { private void delServicesRef(String uuid, String type) { DebugUtils.Assert((uuid != null) && (type != null), "the parameter can't be null"); - VipNetworkServicesRefVO vipRef = dbf.findByUuid(uuid, VipNetworkServicesRefVO.class); - if ( vipRef == null) { + VipNetworkServicesRefVO vipRef = Q.New(VipNetworkServicesRefVO.class) + .eq(VipNetworkServicesRefVO_.uuid, uuid) + .eq(VipNetworkServicesRefVO_.serviceType, type) + .eq(VipNetworkServicesRefVO_.vipUuid, self.getUuid()).find(); + if ( vipRef == null ) { logger.error(String.format("the servicesRef [type:%s:uuid:%s] with vip[uuid:%s] doesn't exist", type, uuid, self.getUuid())); return; @@ -1011,4 +1027,15 @@ private void delServicesRef(String uuid, String type) { type, uuid, self.getUuid())); } + public void delSystemServiceRef() { + self.setSystem(false); + dbf.update(self); + if (self.getServicesTypes().contains(NetworkServiceType.SNAT.toString())) { + VipNetworkServicesRefVO vipRef = Q.New(VipNetworkServicesRefVO.class).eq(VipNetworkServicesRefVO_.vipUuid, self.getUuid()) + .eq(VipNetworkServicesRefVO_.serviceType, NetworkServiceType.SNAT.toString()).find(); + if(vipRef != null) { + delServicesRef(vipRef.getUuid(), vipRef.getServiceType()); + } + } + } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBaseBackend.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBaseBackend.java index 6da441e2d05..123e6fa7fa2 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBaseBackend.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipBaseBackend.java @@ -13,4 +13,5 @@ public VipBaseBackend(VipVO self) { protected abstract void releaseVipOnBackend(Completion completion); protected abstract void acquireVipOnBackend(Completion completion); protected abstract void handleBackendSpecificMessage(Message msg); + protected abstract void acquireVipOnSpecificBackend(String specificBackendUuid,Completion completion); } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipConstant.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipConstant.java index b370811edca..fa78cfbeb73 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipConstant.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipConstant.java @@ -6,6 +6,12 @@ public interface VipConstant { public static final String SERVICE_ID = "vip"; public static final String ACTION_CATEGORY = "vip"; + + public static final String PROTOCOL_TCP = "TCP"; + public static final String PROTOCOL_UDP = "UDP"; + public static final int MAX_PORT = 65535; + + public static enum Params { VIP, VIP_USE_FOR, diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipInventory.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipInventory.java index 10092341b95..965a8714d85 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipInventory.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipInventory.java @@ -12,9 +12,7 @@ import javax.persistence.Column; import java.io.Serializable; import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; /** @@ -212,10 +210,12 @@ public void setServicesRefs(List servicesRefs) { this.servicesRefs = servicesRefs; } + @Deprecated public String getUseFor() { return useFor; } + @Deprecated public void setUseFor(String useFor) { this.useFor = useFor; } @@ -306,4 +306,15 @@ public List getCandidateIpversion() { } return ipVersions; } + + public Set getServicesTypes() { + if (getServicesRefs() != null && !getServicesRefs().isEmpty()) { + return getServicesRefs().stream() + .map(VipNetworkServicesRefInventory::getServiceType) + .collect(Collectors.toSet()); + } + + return new HashSet<>(); + } + } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipManagerImpl.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipManagerImpl.java index 1b3998fbbbb..f363dadb162 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipManagerImpl.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipManagerImpl.java @@ -1,7 +1,16 @@ package org.zstack.network.service.vip; +import java.util.ArrayList; +import org.zstack.utils.VipUseForList; +import org.zstack.header.network.l3.IpRangeVO; + +import java.util.stream.Stream; +import org.zstack.utils.network.NetworkUtils; +import org.zstack.utils.RangeSet; +import org.zstack.utils.Utils; +import java.util.*; +import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.transaction.annotation.Transactional; import org.zstack.core.Platform; import org.zstack.core.cascade.CascadeFacade; import org.zstack.core.cloudbus.CloudBus; @@ -17,9 +26,6 @@ import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.AbstractService; -import org.zstack.header.apimediator.ApiMessageInterceptionException; -import org.zstack.header.core.Completion; -import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.ReturnValueCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; @@ -28,30 +34,25 @@ import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.identity.APIChangeResourceOwnerMsg; import org.zstack.header.identity.Quota; -import org.zstack.header.identity.Quota.QuotaOperator; -import org.zstack.header.identity.Quota.QuotaPair; import org.zstack.header.identity.ReportQuotaExtensionPoint; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; -import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.network.l3.*; import org.zstack.header.network.service.NetworkServiceType; -import org.zstack.header.vm.*; import org.zstack.identity.AccountManager; -import org.zstack.identity.QuotaUtil; import org.zstack.tag.TagManager; import org.zstack.utils.DebugUtils; -import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; -import org.zstack.utils.network.NetworkUtils; -import javax.persistence.TypedQuery; -import java.util.*; -import java.util.stream.Collectors; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import static org.zstack.core.Platform.err; import static org.zstack.utils.CollectionDSL.list; @@ -102,7 +103,8 @@ private void populateExtensions() { VipBackend old = vipBackends.get(extp.getServiceProviderTypeForVip()); if (old != null) { throw new CloudRuntimeException( - String.format("duplicate VipBackend[%s, %s] for provider type[%s]", old.getClass().getName(), extp.getClass().getName(), extp.getServiceProviderTypeForVip()) + String.format("duplicate VipBackend[%s, %s] for provider type[%s]", + old.getClass().getName(), extp.getClass().getName(), extp.getServiceProviderTypeForVip()) ); } vipBackends.put(extp.getServiceProviderTypeForVip(), extp); @@ -174,11 +176,113 @@ private void handleLocalMessage(Message msg) { private void handleApiMessage(APIMessage msg) { if (msg instanceof APICreateVipMsg) { handle((APICreateVipMsg) msg); + } else if (msg instanceof APIGetVipAvailablePortMsg) { + handle((APIGetVipAvailablePortMsg) msg); + } else if (msg instanceof APICheckVipPortAvailabilityMsg) { + handle((APICheckVipPortAvailabilityMsg) msg); } else { bus.dealWithUnknownMessage(msg); } } + private boolean checkVipAvailablePort(APICheckVipPortAvailabilityMsg msg, String protocol) { + RangeSet portRangeList = getVipPortRangeList(msg.getVipUuid(), protocol); + portRangeList.sort(); + + Iterator it = portRangeList.getRanges().iterator(); + while (it.hasNext()){ + RangeSet.Range cur = it.next(); + if (msg.getPort() >=cur.getStart() && msg.getPort() <= cur.getEnd()) { + return false; + } + } + return true; + } + + private void handle(APICheckVipPortAvailabilityMsg msg) { + APICheckVipPortAvailabilityReply reply = new APICheckVipPortAvailabilityReply(); + + VipVO vip = dbf.findByUuid(msg.getVipUuid(), VipVO.class); + + //vip used for Eip and Performance Exclusive Slb + if (!vip.getServicesTypes().isEmpty() && + (vip.getServicesTypes().contains(VipUseForList.EIP_NETWORK_SERVICE_TYPE) + || vip.getServicesTypes().contains(VipUseForList.SLB_NETWORK_SERVICE_TYPE))) { + reply.setAvailable(false); + bus.reply(msg, reply); + return; + } + + reply.setAvailable(checkVipAvailablePort(msg, msg.getProtocolType())); + bus.reply(msg, reply); + } + + + + private RangeSet getVipPortRangeList(String vipUuid, String protocol){ + List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, vipUuid).listValues(); + VipUseForList useForList = new VipUseForList(useFor); + + List portRangeList = new ArrayList(); + for (VipGetUsedPortRangeExtensionPoint ext : pluginRgty.getExtensionList(VipGetUsedPortRangeExtensionPoint.class)){ + RangeSet range = ext.getVipUsePortRange(vipUuid, protocol, useForList); + portRangeList.addAll(range.getRanges()); + } + + RangeSet portRange = new RangeSet(); + portRange.setRanges(portRangeList); + portRange.sort(); + return portRange; + } + + private void getVipFreePortList(List freeList, APIGetVipAvailablePortMsg msg, String protocol) { + RangeSet portRangeList = getVipPortRangeList(msg.getVipUuid(), protocol); + portRangeList.sort(); + + for (RangeSet.Range cur : portRangeList.getRanges()) { + for (long i = cur.getStart(); i <= cur.getEnd(); i++) { + freeList.remove(Integer.valueOf((int) i)); + } + } + } + + private void handle(APIGetVipAvailablePortMsg msg) { + final APIGetVipAvailablePortReply reply = new APIGetVipAvailablePortReply(); + List availablePort = new ArrayList(); + + VipVO vip = dbf.findByUuid(msg.getVipUuid(), VipVO.class); + //vip used for Eip and Performance Exclusive Slb + if (!vip.getServicesTypes().isEmpty() && + (vip.getServicesTypes().contains(VipUseForList.EIP_NETWORK_SERVICE_TYPE) + || vip.getServicesTypes().contains(VipUseForList.SLB_NETWORK_SERVICE_TYPE))) { + reply.setAvailablePort(availablePort); + bus.reply(msg, reply); + return; + } + //vip uesd for others + availablePort = Stream.iterate(1, item -> item+1).limit(VipConstant.MAX_PORT).collect(Collectors.toList()); + getVipFreePortList(availablePort, msg, msg.getProtocolType()); + reply.setAvailablePort(getFreePortListPage(availablePort, msg.getStart(), msg.getLimit())); + + bus.reply(msg, reply); + + } + + private List getFreePortListPage(List freeList, Integer start, Integer limit) { + if (freeList.isEmpty()) { + return freeList; + } + + if (start >= freeList.size()) { + freeList.clear(); + return freeList; + } + if ((start + limit) > freeList.size()) { + return freeList.subList(start, freeList.size()); + } + return freeList.subList(start, start + limit); + } + private void handle(CreateVipMsg msg) { CreateVipReply reply = new CreateVipReply(); @@ -247,16 +351,10 @@ public void run(final FlowTrigger trigger, Map data) { } String strategyType = msg.getAllocatorStrategy(); - if (strategyType == null) { - if (msg.getIpVersion() == IPv6Constants.IPv4) { - strategyType = L3NetworkConstant.RANDOM_IP_ALLOCATOR_STRATEGY; - } else { - strategyType = L3NetworkConstant.RANDOM_IPV6_ALLOCATOR_STRATEGY; - } - } AllocateIpMsg amsg = new AllocateIpMsg(); amsg.setL3NetworkUuid(msg.getL3NetworkUuid()); amsg.setAllocateStrategy(strategyType); + amsg.setIpVersion(msg.getIpVersion()); amsg.setRequiredIp(msg.getRequiredIp()); if (msg.getIpRangeUuid() != null) { amsg.setIpRangeUuid(msg.getIpRangeUuid()); @@ -416,76 +514,17 @@ public void setReleaseVipByApiFlowNames(List releaseVipByApiFlowNames) { @Override public List reportQuota() { - QuotaOperator checker = new QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreateVipMsg) { - check((APICreateVipMsg) msg, pairs); - } - } - - if (msg instanceof APIChangeResourceOwnerMsg) { - check((APIChangeResourceOwnerMsg) msg, pairs); - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setUsed(getUsedVip(accountUuid)); - usage.setName(VipQuotaConstant.VIP_NUM); - return list(usage); - } - - @Transactional(readOnly = true) - private long getUsedVip(String accountUuid) { - String sql = "select count(vip) from VipVO vip, AccountResourceRefVO ref where ref.resourceUuid = vip.uuid" + - " and ref.accountUuid = :auuid and ref.resourceType = :rtype"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, Long.class); - q.setParameter("auuid", accountUuid); - q.setParameter("rtype", VipVO.class.getSimpleName()); - Long vn = q.getSingleResult(); - vn = vn == null ? 0 : vn; - return vn; - } - - private void check(APIChangeResourceOwnerMsg msg, Map pairs) { - long vipNum = pairs.get(VipQuotaConstant.VIP_NUM).getValue(); - long vn = getUsedVip(msg.getAccountUuid()); - - if (vn + 1 > vipNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getAccountUuid(), VipQuotaConstant.VIP_NUM, vipNum)); - } - } - - private void check(APICreateVipMsg msg, Map pairs) { - long vipNum = pairs.get(VipQuotaConstant.VIP_NUM).getValue(); - long vn = getUsedVip(msg.getSession().getAccountUuid()); - - if (vn + 1 > vipNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), VipQuotaConstant.VIP_NUM, vipNum)); - } - } - }; - Quota quota = new Quota(); - quota.addMessageNeedValidation(APICreateVipMsg.class); - quota.addMessageNeedValidation(APIChangeResourceOwnerMsg.class); - quota.setOperator(checker); - - QuotaPair p = new QuotaPair(); - p.setName(VipQuotaConstant.VIP_NUM); - p.setValue(VipQuotaGlobalConfig.VIP_NUM.defaultValue(Long.class)); - quota.addPair(p); - + quota.defineQuota(new VipNumQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateVipMsg.class) + .addCounterQuota(VipQuotaConstant.VIP_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(CreateVipMsg.class) + .addCounterQuota(VipQuotaConstant.VIP_NUM)); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APIChangeResourceOwnerMsg.class) + .addCheckCondition((msg) -> Q.New(VipVO.class) + .eq(VipVO_.uuid, msg.getResourceUuid()) + .isExists()) + .addCounterQuota(VipQuotaConstant.VIP_NUM)); return list(quota); } @@ -493,7 +532,7 @@ private void check(APICreateVipMsg msg, Map pairs) { public void prepareDbInitialValue() { List vipVOS = Q.New(VipVO.class).isNull(VipVO_.prefixLen).list(); for (VipVO vip : vipVOS) { - vip.setPrefixLen(NetworkUtils.getPrefixLengthFromNetwork(vip.getNetmask())); + vip.setPrefixLen(NetworkUtils.getPrefixLengthFromNetmask(vip.getNetmask())); } if (!vipVOS.isEmpty()) { dbf.updateCollection(vipVOS); diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNetworkServicesRefVO.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNetworkServicesRefVO.java index c8d2e24aeb8..b4a2b1af818 100644 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNetworkServicesRefVO.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNetworkServicesRefVO.java @@ -5,6 +5,7 @@ import org.zstack.header.vo.ForeignKey.ReferenceOption; import javax.persistence.*; +import java.io.Serializable; import java.sql.Timestamp; /** @@ -18,14 +19,46 @@ @EntityGraph.Neighbour(type = VipVO.class, myField = "vipUuid", targetField = "uuid") } ) +@IdClass(VipNetworkServicesRefVO.CompositeID.class) public class VipNetworkServicesRefVO { + static class CompositeID implements Serializable { + private String uuid; + private String serviceType; + private String vipUuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getServiceType() { + return serviceType; + } + + public void setServiceType(String serviceType) { + this.serviceType = serviceType; + } + + public String getVipUuid() { + return vipUuid; + } + + public void setVipUuid(String vipUuid) { + this.vipUuid = vipUuid; + } + } @Id @Column private String uuid; + @Id @Column private String serviceType; + @Id @Column @ForeignKey(parentEntityClass = VipVO.class, onDeleteAction = ReferenceOption.CASCADE) private String vipUuid; @@ -36,6 +69,16 @@ public class VipNetworkServicesRefVO { @Column private Timestamp lastOpDate; + @Override + public boolean equals(Object r) { + if (!(r instanceof VipNetworkServicesRefVO)) { + return false; + } + + VipNetworkServicesRefVO ref = (VipNetworkServicesRefVO) r; + return ref.getUuid().equals(uuid)&&ref.getServiceType().equals(serviceType)&&ref.getVipUuid().equals(vipUuid); + } + @PreUpdate private void preUpdate() { lastOpDate = null; @@ -80,4 +123,9 @@ public Timestamp getLastOpDate() { public void setLastOpDate(Timestamp lastOpDate) { this.lastOpDate = lastOpDate; } + + @Override + public int hashCode() { + return super.hashCode(); + } } diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNumQuotaDefinition.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNumQuotaDefinition.java new file mode 100644 index 00000000000..57959645fdf --- /dev/null +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipNumQuotaDefinition.java @@ -0,0 +1,28 @@ +package org.zstack.network.service.vip; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; + +public class VipNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VipQuotaConstant.VIP_NUM; + } + + @Override + public Long getDefaultValue() { + return VipQuotaGlobalConfig.VIP_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + String sql = "select count(vip) from VipVO vip, AccountResourceRefVO ref where ref.resourceUuid = vip.uuid" + + " and ref.accountUuid = :auuid and ref.resourceType = :rtype"; + SQL q = SQL.New(sql, Long.class); + q.param("auuid", accountUuid); + q.param("rtype", VipVO.class.getSimpleName()); + Long vn = q.find(); + vn = vn == null ? 0 : vn; + return vn; + } +} diff --git a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipVO.java b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipVO.java index 30320675d47..19aba29c507 100755 --- a/plugin/vip/src/main/java/org/zstack/network/service/vip/VipVO.java +++ b/plugin/vip/src/main/java/org/zstack/network/service/vip/VipVO.java @@ -1,5 +1,6 @@ package org.zstack.network.service.vip; +import org.apache.commons.lang.StringUtils; import org.zstack.header.identity.OwnedByAccount; import org.zstack.header.network.l3.*; import org.zstack.header.vo.*; @@ -157,7 +158,7 @@ public void setServicesRefs(Set servicesRefs) { public Set getServicesTypes() { if (getServicesRefs() != null && !getServicesRefs().isEmpty()) { return getServicesRefs().stream() - .map(ref -> ref.getServiceType()) + .map(VipNetworkServicesRefVO::getServiceType) .collect(Collectors.toSet()); } @@ -172,10 +173,16 @@ public void setServiceProvider(String serviceProvider) { this.serviceProvider = serviceProvider; } + @Deprecated public String getUseFor() { - return useFor; + if (getServicesTypes() != null && !getServicesTypes().isEmpty()) { + return StringUtils.join(getServicesTypes(), ','); + } + + return null; } + @Deprecated public void setUseFor(String useFor) { this.useFor = useFor; } diff --git a/plugin/virtualRouterProvider/pom.xml b/plugin/virtualRouterProvider/pom.xml index 2a754cf18d2..a8eb705f54f 100755 --- a/plugin/virtualRouterProvider/pom.xml +++ b/plugin/virtualRouterProvider/pom.xml @@ -4,7 +4,7 @@ org.zstack plugin - 4.4.0 + 5.4.0 virtualRouterProvider diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APICreateVirtualRouterOfferingMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APICreateVirtualRouterOfferingMsgDoc_zh_cn.groovy index 7a65176f63f..0ee9c42803d 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APICreateVirtualRouterOfferingMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APICreateVirtualRouterOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "managementNetworkUuid" @@ -39,7 +38,6 @@ doc { type "String" optional false since "0.6" - } column { name "imageUuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "publicNetworkUuid" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "isDefault" @@ -69,7 +65,6 @@ doc { type "Boolean" optional true since "0.6" - } column { name "name" @@ -79,7 +74,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -89,7 +83,6 @@ doc { type "String" optional true since "0.6" - } column { name "cpuNum" @@ -99,7 +92,6 @@ doc { type "int" optional false since "0.6" - } column { name "cpuSpeed" @@ -109,7 +101,6 @@ doc { type "int" optional false since "0.6" - } column { name "memorySize" @@ -119,7 +110,6 @@ doc { type "long" optional false since "0.6" - } column { name "allocatorStrategy" @@ -129,7 +119,6 @@ doc { type "String" optional true since "0.6" - } column { name "sortKey" @@ -139,7 +128,6 @@ doc { type "int" optional true since "0.6" - } column { name "type" @@ -149,7 +137,6 @@ doc { type "String" optional true since "0.6" - } column { name "resourceUuid" @@ -159,7 +146,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -169,7 +155,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -179,7 +164,24 @@ doc { type "List" optional true since "0.6" - + } + column { + name "reservedMemorySize" + enclosedIn "params" + desc "" + location "body" + type "long" + optional true + since "4.7.21" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "4.7.21" } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetAttachablePublicL3ForVRouterMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetAttachablePublicL3ForVRouterMsgDoc_zh_cn.groovy index 108e117246d..e23c3a13879 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetAttachablePublicL3ForVRouterMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetAttachablePublicL3ForVRouterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "2.2" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "2.2" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "2.2" - } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetVipUsedPortsMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetVipUsedPortsMsgDoc_zh_cn.groovy index c6851242e8f..41d3a939ac6 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetVipUsedPortsMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIGetVipUsedPortsMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "protocol" @@ -49,7 +48,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -59,7 +57,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIProvisionVirtualRouterConfigMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIProvisionVirtualRouterConfigMsgDoc_zh_cn.groovy index 9b6c3cbf9cc..356b187f6dc 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIProvisionVirtualRouterConfigMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIProvisionVirtualRouterConfigMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "3.10" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "3.10" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.10" - } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterOfferingMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterOfferingMsgDoc_zh_cn.groovy index be8faad867a..a62f435c5da 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterOfferingMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterOfferingMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.virtualrouter import org.zstack.network.service.virtualrouter.APIQueryVirtualRouterOfferingReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询虚拟路由器规格(QueryVirtualRouterOffering)" diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterVmMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterVmMsgDoc_zh_cn.groovy index 2aa5725fd8a..7bb359fb0f6 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterVmMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIQueryVirtualRouterVmMsgDoc_zh_cn.groovy @@ -2,7 +2,6 @@ package org.zstack.network.service.virtualrouter import org.zstack.appliancevm.APIQueryApplianceVmReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { title "查询虚拟路由器云主机(QueryVirtualRouterVm)" diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIReconnectVirtualRouterMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIReconnectVirtualRouterMsgDoc_zh_cn.groovy index 4e63a8cab67..51d875b64f5 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIReconnectVirtualRouterMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIReconnectVirtualRouterMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "systemTags" @@ -39,7 +38,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "0.6" - } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterMsgDoc_zh_cn.groovy index da77c687836..94cd27e9f5b 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterMsgDoc_zh_cn.groovy @@ -25,11 +25,10 @@ doc { name "vmInstanceUuid" enclosedIn "updateVirtualRouter" desc "资源的UUID,唯一标示该资源" - location "body" + location "url" type "String" optional false since "3.8" - } column { name "defaultRouteL3NetworkUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "3.8" - } column { name "systemTags" @@ -49,7 +47,6 @@ doc { type "List" optional true since "3.8" - } column { name "userTags" @@ -59,7 +56,6 @@ doc { type "List" optional true since "3.8" - } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterOfferingMsgDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterOfferingMsgDoc_zh_cn.groovy index 3995dfc890a..060cc9ee460 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterOfferingMsgDoc_zh_cn.groovy +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/APIUpdateVirtualRouterOfferingMsgDoc_zh_cn.groovy @@ -29,7 +29,6 @@ doc { type "Boolean" optional true since "0.6" - } column { name "imageUuid" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "uuid" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "name" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "description" @@ -69,7 +65,6 @@ doc { type "String" optional true since "0.6" - } column { name "systemTags" @@ -79,7 +74,6 @@ doc { type "List" optional true since "0.6" - } column { name "userTags" @@ -89,7 +83,6 @@ doc { type "List" optional true since "0.6" - } column { name "allocatorStrategy" @@ -99,7 +92,6 @@ doc { type "String" optional true since "2.3.1" - } } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PackageInfo.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PackageInfo.java index d388d0d0bfe..3a1d030baf7 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PackageInfo.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PackageInfo.java @@ -2,6 +2,9 @@ import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "云路由") +@PackageAPIInfo( + APICategoryName = "云路由", + permissions = {PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE, PackageAPIInfo.PERMISSION_ZSV_BASIC_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PingVirtualRouterVmReply.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PingVirtualRouterVmReply.java index d308d30a8ee..aa7cd80de27 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PingVirtualRouterVmReply.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/PingVirtualRouterVmReply.java @@ -2,6 +2,9 @@ import org.zstack.header.message.MessageReply; +import java.util.HashMap; +import java.util.List; + /** * Created by frank on 6/29/2015. */ @@ -10,6 +13,8 @@ public class PingVirtualRouterVmReply extends MessageReply { private boolean doReconnect; private String haStatus; private String vrUuid; + private HashMap> serviceHealthList; + public PingVirtualRouterVmReply(String vrUuid) { this.vrUuid = vrUuid; @@ -46,4 +51,12 @@ public String getVrUuid() { public void setVrUuid(String vrUuid) { this.vrUuid = vrUuid; } + + public HashMap> getServiceHealthList() { + return serviceHealthList; + } + + public void setServiceHealthList(HashMap> serviceHealthList) { + this.serviceHealthList = serviceHealthList; + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java index 210162ea782..85287633e0c 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouter.java @@ -6,6 +6,8 @@ import org.springframework.transaction.annotation.Transactional; import org.zstack.appliancevm.*; import org.zstack.appliancevm.ApplianceVmConstant.Params; +import org.zstack.core.upgrade.UpgradeChecker; +import org.zstack.core.upgrade.UpgradeGlobalConfig; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.Q; @@ -81,6 +83,8 @@ public class VirtualRouter extends ApplianceVmBase { protected VirtualRouterHaBackend haBackend; @Autowired protected VirutalRouterDefaultL3ConfigProxy defaultL3ConfigProxy; + @Autowired + protected UpgradeChecker upgradeChecker; protected VirtualRouterVmInventory vr; @@ -203,7 +207,15 @@ public void success(PingRsp ret) { if (!ret.isSuccess()) { logger.warn(String.format("failed to ping the virtual router vm[uuid:%s], %s. We will reconnect it soon", self.getUuid(), ret.getError())); reply.setConnected(false); + + if (UpgradeGlobalConfig.GRAYSCALE_UPGRADE.value(Boolean.class)) { + changeApplianceVmStatus(ApplianceVmStatus.Disconnected); + } + } else { + // update vyos agent version when open grayScaleUpgrade + upgradeChecker.updateAgentVersion(self.getUuid(), VirtualRouterConstant.VIRTUAL_ROUTER_PROVIDER_TYPE, new VirtualRouterMetadataOperator().getManagementVersion(), ret.getVersion()); + boolean connected = self.getUuid().equals(ret.getUuid()); if (!connected) { logger.warn(String.format("a signature lost on the virtual router vm[uuid:%s] changed, it's probably caused by the agent restart. We will issue a reconnect soon", self.getUuid())); @@ -217,6 +229,7 @@ public void success(PingRsp ret) { } else { fireServicehealthyCanonicalEvent(); } + reply.setServiceHealthList(ret.getServiceHealthList()); } completion.success(reply); } @@ -292,7 +305,10 @@ public void fail(ErrorCode errorCode) { } private void handle(final APIAttachL3NetworkToVmMsg msg) { - if (vr.getHaStatus().equals(ApplianceVmHaStatus.NoHa.toString())) { + ApplianceVmType aType = ApplianceVmType.valueOf(vr.getApplianceVmType()); + + if (!aType.isNeedOverlay() || + vr.getHaStatus().equals(ApplianceVmHaStatus.NoHa.toString())) { super.handleApiMessage(msg); return; } @@ -388,7 +404,7 @@ private void handle(final PingVirtualRouterVmMsg msg) { thdf.chainSubmit(new ChainTask(msg) { @Override public String getSyncSignature() { - return String.format("ping-virtualrouter-%s", self.getUuid()); + return syncThreadName; } @Override @@ -396,6 +412,10 @@ public void run(final SyncTaskChain chain) { final PingVirtualRouterVmReply reply = new PingVirtualRouterVmReply(self.getUuid()); if ((VmInstanceState.Running != self.getState() && VmInstanceState.Unknown != self.getState()) || ApplianceVmStatus.Connecting == getSelf().getStatus()) { + if (VmInstanceState.Stopped == self.getState() + && ApplianceVmStatus.Disconnected != getSelf().getStatus()) { + changeApplianceVmStatus(ApplianceVmStatus.Disconnected); + } reply.setDoReconnect(false); bus.reply(msg, reply); chain.next(); @@ -446,6 +466,11 @@ public void done(ErrorCodeList errorCodeList) { reply1.setConnected(true); replies.add(reply1); } + + if (replies.size() == steps.size()) { + changeApplianceVmStatus(ApplianceVmStatus.Disconnected); + } + bus.reply(msg, replies.get(0)); chain.next(); } @@ -486,6 +511,7 @@ private void provisionConfig(Message msg, final Completion completion) { chain.done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { + changeApplianceVmStatus(ApplianceVmStatus.Connected); self = dbf.reload(self); completion.success(); } @@ -569,7 +595,7 @@ public String getName() { } }); } - + private void handle(final ReconnectVirtualRouterVmMsg msg) { thdf.chainSubmit(new ChainTask(msg) { @Override @@ -581,6 +607,12 @@ public String getSyncSignature() { public void run(final SyncTaskChain chain) { final ReconnectVirtualRouterVmReply reply = new ReconnectVirtualRouterVmReply(); + if (upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(self.getUuid())) { + bus.reply(msg, reply); + chain.next(); + return; + } + refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), SysErrors.OPERATION_ERROR); if (allowed != null) { @@ -631,6 +663,11 @@ public String getSyncSignature() { public void run(final SyncTaskChain chain) { refreshVO(); + ErrorCode errorCode = upgradeChecker.checkAgentHttpParamChanges(self.getUuid(), msg.getCommandClassName(), msg.getCommand()); + if (errorCode != null) { + throw new OperationFailureException(errorCode); + } + final VirtualRouterAsyncHttpCallReply reply = new VirtualRouterAsyncHttpCallReply(); if (msg.isCheckStatus() && getSelf().getState() != VmInstanceState.Running) { throw new OperationFailureException(operr("the virtual router[name:%s, uuid:%s, current state:%s] is not running," + @@ -754,160 +791,6 @@ public void rollback(FlowRollback trigger, Map data) { vrVO.getDefaultRouteL3NetworkUuid()); trigger.rollback(); } - }).then(new Flow() { - String __name__ = "release-old-snat-of-vip"; - - @Override - public void run(FlowTrigger trigger, Map data) { - VmNicVO oldNic = null; - for (VmNicVO nic: vrVO.getVmNics()) { - if (nic.getL3NetworkUuid().equals(vrVO.getDefaultRouteL3NetworkUuid())) { - oldNic = nic; - break; - } - } - - if (oldNic == null) { - trigger.next(); - return; - } - - String vipIp = oldNic.getIp(); - if (vrVO.getDefaultRouteL3NetworkUuid().equals(vrVO.getManagementNetworkUuid())) { - VmNicInventory publicNic = vrMgr.getSnatPubicInventory(VirtualRouterVmInventory.valueOf(vrVO)); - vipIp = publicNic.getIp(); - } - - VipVO vipVO = Q.New(VipVO.class).eq(VipVO_.ip, vipIp) - .eq(VipVO_.l3NetworkUuid, oldNic.getL3NetworkUuid()).find(); - if (vipVO == null) { - trigger.next(); - return; - } - - data.put("oldVip", vipVO); - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(NetworkServiceType.SNAT.toString()); - struct.setServiceUuid(vrVO.getUuid()); - Vip vip = new Vip(vipVO.getUuid()); - vip.setStruct(struct); - vip.release(new Completion(trigger) { - @Override - public void success() { - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - - @Override - public void rollback(FlowRollback trigger, Map data) { - VipVO vipVO = (VipVO) data.get("oldVip"); - if (vipVO == null) { - trigger.rollback(); - return; - } - - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(NetworkServiceType.SNAT.toString()); - struct.setServiceUuid(vrVO.getUuid()); - Vip vip = new Vip(vipVO.getUuid()); - vip.setStruct(struct); - vip.acquire(new Completion(trigger) { - @Override - public void success() { - trigger.rollback(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.rollback(); - } - }); - } - }).then(new Flow() { - String __name__ = "apply-new-snat-of-vip"; - - @Override - public void run(FlowTrigger trigger, Map data) { - VmNicVO newNic = null; - for (VmNicVO nic: vrVO.getVmNics()) { - if (nic.getL3NetworkUuid().equals(msg.getDefaultRouteL3NetworkUuid())) { - newNic = nic; - break; - } - } - - if (newNic == null) { - trigger.fail(argerr("virtual router [uuid:%s] does not has nic in l3 network [uuid:s]", vrVO.getUuid(), - msg.getDefaultRouteL3NetworkUuid())); - return; - } - - String vipIp = newNic.getIp(); - if (msg.getDefaultRouteL3NetworkUuid().equals(vrVO.getManagementNetworkUuid())) { - VirtualRouterVmInventory vrInv = VirtualRouterVmInventory.valueOf(vrVO); - vrInv.setDefaultRouteL3NetworkUuid(msg.getDefaultRouteL3NetworkUuid()); - VmNicInventory publicNic = vrMgr.getSnatPubicInventory(vrInv); - vipIp = publicNic.getIp(); - } - - VipVO vipVO = Q.New(VipVO.class).eq(VipVO_.ip, vipIp) - .eq(VipVO_.l3NetworkUuid, newNic.getL3NetworkUuid()).find(); - if (vipVO == null) { - trigger.fail(argerr("there is no vip [ip:%s] in l3 network [uuid:%s]", vipIp, - msg.getDefaultRouteL3NetworkUuid())); - return; - } - - data.put("newVip", vipVO); - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(NetworkServiceType.SNAT.toString()); - struct.setServiceUuid(vrVO.getUuid()); - Vip vip = new Vip(vipVO.getUuid()); - vip.setStruct(struct); - vip.acquire(new Completion(trigger) { - @Override - public void success() { - trigger.next(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.fail(errorCode); - } - }); - } - - @Override - public void rollback(FlowRollback trigger, Map data) { - VipVO vipVO = (VipVO) data.get("newVip"); - if (vipVO == null) { - trigger.rollback(); - return; - } - - ModifyVipAttributesStruct struct = new ModifyVipAttributesStruct(); - struct.setUseFor(NetworkServiceType.SNAT.toString()); - struct.setServiceUuid(vrVO.getUuid()); - Vip vip = new Vip(vipVO.getUuid()); - vip.setStruct(struct); - vip.release(new Completion(trigger) { - @Override - public void success() { - trigger.rollback(); - } - - @Override - public void fail(ErrorCode errorCode) { - trigger.rollback(); - } - }); - } }).then(new NoRollbackFlow() { String __name__ = "update-virtual-router-backend"; @@ -965,7 +848,7 @@ public void run(final SyncTaskChain chain) { return; } - reconnect(new Completion(msg, chain) { + reconnect(true, new Completion(msg, chain) { @Override public void success() { evt.setInventory((ApplianceVmInventory) getSelfInventory()); @@ -990,6 +873,10 @@ public String getName() { } private void reconnect(final Completion completion) { + reconnect(false, completion); + } + + private void reconnect(Boolean fromApi, final Completion completion) { ApplianceVmStatus oldStatus = getSelf().getStatus(); FlowChain chain = getReconnectChain(); @@ -999,6 +886,7 @@ private void reconnect(final Completion completion) { chain.getData().put(Params.isReconnect.toString(), Boolean.TRUE.toString()); chain.getData().put(Params.managementNicIp.toString(), vr.getManagementNic().getIp()); chain.getData().put(Params.applianceVmUuid.toString(), self.getUuid()); + chain.getData().put(Params.fromApi.toString(), fromApi.toString()); SimpleQuery q = dbf.createQuery(ApplianceVmFirewallRuleVO.class); q.add(ApplianceVmFirewallRuleVO_.applianceVmUuid, Op.EQ, getSelf().getUuid()); @@ -1008,6 +896,8 @@ private void reconnect(final Completion completion) { chain.insert(new Flow() { String __name__ = "change-appliancevm-status-to-connecting"; + ApplianceVmStatus originStatus = getSelf().getStatus(); + @Override public void run(FlowTrigger trigger, Map data) { changeApplianceVmStatus(ApplianceVmStatus.Connecting); @@ -1017,8 +907,6 @@ public void run(FlowTrigger trigger, Map data) { @Override public void rollback(FlowRollback trigger, Map data) { changeApplianceVmStatus(ApplianceVmStatus.Disconnected); - fireDisconnectedCanonicalEvent(operr("appliance vm %s reconnect failed", - getSelf().getUuid())); trigger.rollback(); } }).then(new NoRollbackFlow() { @@ -1038,10 +926,6 @@ public void handle(Map data) { }).error(new FlowErrorHandler(completion) { @Override public void handle(ErrorCode errCode, Map data) { - if (oldStatus == ApplianceVmStatus.Connected) { - fireDisconnectedCanonicalEvent(errCode); - } - completion.fail(errCode); } }).start(); @@ -1102,6 +986,7 @@ public void run(FlowTrigger trigger, Map data) { } } info.setMtu(new MtuGetter().getMtu(l3NetworkVO.getUuid())); + info.setState(nicInventory.getState()); cmd.setNics(Arrays.asList(info)); VirtualRouterAsyncHttpCallMsg cmsg = new VirtualRouterAsyncHttpCallMsg(); @@ -1121,12 +1006,12 @@ public void run(MessageReply reply) { VirtualRouterAsyncHttpCallReply re = reply.castReply(); VirtualRouterCommands.ConfigureNicRsp rsp = re.toResponse(VirtualRouterCommands.ConfigureNicRsp.class); if (rsp.isSuccess()) { - logger.debug(String.format("successfully add nic[ip:%s, mac:%s] to virtual router vm[uuid:%s, ip:%s]", - info.getIp(), info.getMac(), vr.getUuid(), vr.getManagementNic().getIp())); + logger.debug(String.format("successfully add nic[ip:%s, ip6:%s, mac:%s] to virtual router vm[uuid:%s, ip:%s]", + info.getIp(), info.getIp6(), info.getMac(), vr.getUuid(), vr.getManagementNic().getIp())); trigger.next(); } else { - ErrorCode err = operr("unable to add nic[ip:%s, mac:%s] to virtual router vm[uuid:%s ip:%s], because %s", - info.getIp(), info.getMac(), vr.getUuid(), vr.getManagementNic().getIp(), rsp.getError()); + ErrorCode err = operr("unable to add nic[ip:%s, ip6:%s, mac:%s] to virtual router vm[uuid:%s ip:%s], because %s", + info.getIp(), info.getIp6(), info.getMac(), vr.getUuid(), vr.getManagementNic().getIp(), rsp.getError()); trigger.fail(err); } } @@ -1231,7 +1116,27 @@ protected void afterAttachNic(VmNicInventory nicInventory, boolean applyToBacken usedIpVO.setMetaData(GUEST_NIC_MASK.toString()); dbf.updateAndRefresh(usedIpVO); } else { - vo.setMetaData(ADDITIONAL_PUBLIC_NIC_MASK.toString()); + VirtualRouterVmVO vrVO = Q.New(VirtualRouterVmVO.class) + .eq(VirtualRouterVmVO_.uuid, self.getUuid()) + .find(); + boolean isOfferingPubNic = vrVO.getPublicNetworkUuid() != null && + vrVO.getPublicNetworkUuid().equals(l3NetworkVO.getUuid()); + if (isOfferingPubNic) { + VirtualRouterOfferingVO offering = Q.New(VirtualRouterOfferingVO.class) + .eq(VirtualRouterOfferingVO_.uuid, vrVO.getInstanceOfferingUuid()) + .find(); + if (offering == null) { + vo.setMetaData(VirtualRouterNicMetaData.PUBLIC_NIC_MASK.toString()); + } else { + boolean hasSeparatePublic = offering.getPublicNetworkUuid() != null && + !offering.getManagementNetworkUuid().equals(offering.getPublicNetworkUuid()); + vo.setMetaData(hasSeparatePublic + ? VirtualRouterNicMetaData.PUBLIC_NIC_MASK.toString() + : VirtualRouterNicMetaData.PUBLIC_AND_MANAGEMENT_NIC_MASK.toString()); + } + } else { + vo.setMetaData(ADDITIONAL_PUBLIC_NIC_MASK.toString()); + } } vo = dbf.updateAndRefresh(vo); logger.debug(String.format("updated metadata of vmnic[uuid: %s]", vo.getUuid())); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java index bac45e55530..e448363b030 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterApiInterceptor.java @@ -7,8 +7,10 @@ import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.apimediator.ApiMessageInterceptionException; import org.zstack.header.apimediator.ApiMessageInterceptor; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; import org.zstack.header.identity.IdentityErrors; import org.zstack.header.image.ImageConstant; import org.zstack.header.image.ImageConstant.ImageMediaType; @@ -21,17 +23,23 @@ import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.query.QueryCondition; import org.zstack.header.query.QueryOp; -import org.zstack.header.vm.VmInstanceConstant; -import org.zstack.header.vm.VmInstanceMessage; -import org.zstack.header.vm.VmNicHelper; -import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vm.*; import org.zstack.identity.QuotaUtil; import org.zstack.network.l3.IpRangeHelper; +import org.zstack.network.service.lb.APIAddBackendServerToServerGroupMsg; +import org.zstack.network.service.lb.LoadBalancerType; +import org.zstack.network.service.lb.LoadBalancerVO; +import org.zstack.network.service.lb.LoadBalancerVO_; +import org.zstack.network.service.virtualrouter.lb.VirtualRouterLoadBalancerRefVO; +import org.zstack.network.service.virtualrouter.lb.VirtualRouterLoadBalancerRefVO_; +import org.zstack.utils.ShellResult; +import org.zstack.utils.ShellUtils; import org.zstack.utils.network.IPv6Constants; import org.zstack.utils.network.IPv6NetworkUtils; import org.zstack.utils.network.NetworkUtils; import javax.persistence.Tuple; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -40,10 +48,12 @@ /** */ -public class VirtualRouterApiInterceptor implements ApiMessageInterceptor { +public class VirtualRouterApiInterceptor implements ApiMessageInterceptor, GlobalApiMessageInterceptor { @Autowired private DatabaseFacade dbf; @Autowired + private ErrorFacade errf; + @Autowired private CloudBus bus; private void setServiceId(APIMessage msg) { @@ -74,6 +84,8 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIUpdateVirtualRouterOfferingMsg) msg); } else if (msg instanceof APIUpdateVirtualRouterMsg) { validate((APIUpdateVirtualRouterMsg) msg); + } else if (msg instanceof APIAddBackendServerToServerGroupMsg) { + validate((APIAddBackendServerToServerGroupMsg)msg); } setServiceId(msg); @@ -81,6 +93,20 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti return msg; } + private void validate(APIAddBackendServerToServerGroupMsg msg) { + String type = Q.New(LoadBalancerVO.class).eq(LoadBalancerVO_.uuid, msg.getLoadBalancerUuid()).select(LoadBalancerVO_.type).findValue(); + if (!(type == LoadBalancerType.Shared.toString())) { + return; + } + + if (msg.getVmNics().isEmpty()) { + boolean vrExist = Q.New(VirtualRouterLoadBalancerRefVO.class).eq(VirtualRouterLoadBalancerRefVO_.loadBalancerUuid, msg.getLoadBalancerUuid()).isExists(); + if (!vrExist) { + throw new ApiMessageInterceptionException(argerr("could not add server ip to load balancer server group, because share lb has no service provider, please add vmnic first")); + } + } + } + private void validate(APIUpdateVirtualRouterMsg msg) { VirtualRouterVmVO vrVO = dbf.findByUuid(msg.getVmInstanceUuid(), VirtualRouterVmVO.class); @@ -108,10 +134,6 @@ private void validate(APIUpdateVirtualRouterMsg msg) { throw new ApiMessageInterceptionException(argerr("could not set the default network, because l3 uuid[:%s] is not public network", msg.getDefaultRouteL3NetworkUuid())); } } - - if (VirtualRouterGlobalProperty.ENABLE_MULTI_SNAT) { - throw new ApiMessageInterceptionException(operr("Could not update virtualRouter default public network, due to multi snat feature is enabled")); - } } private void validate(APIUpdateVirtualRouterOfferingMsg msg) { @@ -190,7 +212,7 @@ private void validate(APICreateVirtualRouterOfferingMsg msg) { msg.getManagementNetworkUuid(), msg.getZoneUuid())); } /* mgt network does not support ipv6 yet, TODO, will be implemented soon */ - if (mgtL3.getIpVersions().contains(IPv6Constants.IPv6)) { + if (mgtL3.getIpVersions().contains(IPv6Constants.IPv6) && !mgtL3.getIpVersions().contains(IPv6Constants.IPv4)) { throw new ApiMessageInterceptionException(argerr("can not create virtual router offering, because management network doesn't support ipv6 yet")); } @@ -262,6 +284,11 @@ private void checkIfManagementNetworkReachable(String managementNetworkUuid) { if (NetworkUtils.isReachable(gateway, 2000)) { return; } + + ShellResult ret = ShellUtils.runAndReturn(String.format("ping -c 1 -W 2 %s", gateway)); + if (ret.isReturnCode(0)) { + return; + } } throw new ApiMessageInterceptionException(argerr("the management network[uuid:%s, gateway:%s] is not reachable", managementNetworkUuid, gateway)); @@ -282,4 +309,9 @@ private void validate(APIQueryVirtualRouterOfferingMsg msg) { msg.addQueryCondition("type", QueryOp.EQ, VirtualRouterConstant.VIRTUAL_ROUTER_OFFERING_TYPE); } } + + @Override + public List getMessageClassToIntercept() { + return Arrays.asList(APIAddBackendServerToServerGroupMsg.class); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterCommands.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterCommands.java index a9175e53084..3d9f9636058 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterCommands.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterCommands.java @@ -1,23 +1,27 @@ package org.zstack.network.service.virtualrouter; +import org.zstack.core.upgrade.GrayUpgradeAgent; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.header.vm.VmNicInventory; import org.zstack.network.service.vip.VipInventory; import org.zstack.network.service.virtualrouter.eip.EipTO; import org.zstack.network.service.virtualrouter.portforwarding.PortForwardingRuleTO; import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.network.NetworkUtils; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; public class VirtualRouterCommands { - public static class AgentCommand implements Serializable { + public static class AgentCommand extends GrayUpgradeAgent implements Serializable { } - public static class AgentResponse { - private boolean success = true; - private String error; + public static class AgentResponse extends GrayUpgradeAgent { + public boolean success = true; + public String error; public boolean isSuccess() { return success; } @@ -32,12 +36,44 @@ public void setError(String error) { } } + public static class GetTypeCommand extends AgentCommand{ + @GrayVersion(value = "5.0.0") + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + } + + public static class GetTypeRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") + private boolean isVyos; + + public boolean isVyos() { + return isVyos; + } + + public void setVyos(boolean vyos) { + isVyos = vyos; + } + } + public static class InitCommand extends AgentCommand { + @GrayVersion(value = "5.0.0") private String uuid; + @GrayVersion(value = "5.0.0") private int restartDnsmasqAfterNumberOfSIGUSER1; + @GrayVersion(value = "5.0.0") private String mgtCidr; + @GrayVersion(value = "5.0.0") private String logLevel; + @GrayVersion(value = "5.0.0") private List timeServers; + @GrayVersion(value = "5.0.0") private Map parms; public String getUuid() { @@ -90,9 +126,16 @@ public void setParms(Map parms) { } public static class InitRsp extends AgentResponse { + @GrayVersion(value = "5.0.0") private String zvrVersion; + @GrayVersion(value = "5.0.0") private String vyosVersion; + @GrayVersion(value = "5.0.0") private String kernelVersion; + @GrayVersion(value = "5.0.0") + private String ipsecCurrentVersion; + @GrayVersion(value = "5.0.0") + private String ipsecLatestVersion; public String getZvrVersion() { return zvrVersion; @@ -117,6 +160,23 @@ public String getKernelVersion() { public void setKernelVersion(String kernelVersion) { this.kernelVersion = kernelVersion; } + + public String getIpsecCurrentVersion() { + return ipsecCurrentVersion; + } + + public void setIpsecCurrentVersion(String ipsecCurrentVersion) { + this.ipsecCurrentVersion = ipsecCurrentVersion; + } + + public String getIpsecLatestVersion() { + return ipsecLatestVersion; + } + + public void setIpsecLatestVersion(String ipsecLatestVersion) { + this.ipsecLatestVersion = ipsecLatestVersion; + } + } public static class NicInfo { @@ -135,6 +195,7 @@ public static class NicInfo { private Integer prefixLength; private String gateway6; private String addressMode; + private String state; public String getIp() { return ip; @@ -246,9 +307,18 @@ public String getAddressMode() { public void setAddressMode(String addressMode) { this.addressMode = addressMode; } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } } public static class ConfigureNicCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List nics; public List getNics() { @@ -264,6 +334,7 @@ public static class ConfigureNicRsp extends AgentResponse { } public static class ConfigureNicFirewallDefaultActionCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List nics; public List getNics() { @@ -279,6 +350,7 @@ public static class ConfigureNicFirewallDefaultActionRsp extends AgentResponse { } public static class RemoveNicCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List nics; public List getNics() { @@ -450,6 +522,7 @@ public void setDnsServer(String dnsServer) { } public static class RemoveDhcpEntryCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List dhcpEntries; public List getDhcpEntries() { @@ -465,7 +538,9 @@ public static class RemoveDhcpEntryRsp extends AgentResponse { } public static class AddDhcpEntryCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List dhcpEntries; + @GrayVersion(value = "5.0.0") private boolean rebuild; public List getDhcpEntries() { @@ -492,6 +567,7 @@ public static class AddDhcpEntryRsp extends AgentResponse { } public static class RefreshDHCPServerCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List dhcpServers; public List getDhcpServers() { @@ -511,6 +587,7 @@ public static class SNATInfo { private String publicIp; private String privateNicMac; private String privateNicIp; + private String privateGatewayIp; private String snatNetmask; private Boolean state; @@ -552,10 +629,20 @@ public Boolean getState() { public void setState(Boolean state) { this.state = state; } + + public String getPrivateGatewayIp() { + return privateGatewayIp; + } + + public void setPrivateGatewayIp(String privateGatewayIp) { + this.privateGatewayIp = privateGatewayIp; + } } public static class SyncSNATCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List snats; + @GrayVersion(value = "5.0.0") private Boolean enable; public List getSnats() { @@ -578,6 +665,7 @@ public static class SyncSNATRsp extends AgentResponse { } public static class SetSNATCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private SNATInfo snat; public SNATInfo getSnat() { @@ -593,6 +681,7 @@ public static class SetSNATRsp extends AgentResponse { } public static class RemoveSNATCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List natInfo; public List getNatInfo() { @@ -608,6 +697,7 @@ public static class RemoveSNATRsp extends AgentResponse { } public static class SyncPortForwardingRuleCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List rules; public List getRules() { @@ -622,6 +712,7 @@ public static class SyncPortForwardingRuleRsp extends AgentResponse { } public static class CreatePortForwardingRuleCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List rules; public List getRules() { @@ -636,6 +727,7 @@ public static class CreatePortForwardingRuleRsp extends AgentResponse { } public static class RevokePortForwardingRuleCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List rules; public List getRules() { @@ -671,6 +763,7 @@ public void setDnsAddress(String dnsAddress) { } public static class SetDnsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List dns; public List getDns() { @@ -686,10 +779,15 @@ public static class SetDnsRsp extends AgentResponse { } public static class SetForwardDnsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String dns; + @GrayVersion(value = "5.0.0") private String mac; + @GrayVersion(value = "5.0.0") private String bridgeName; + @GrayVersion(value = "5.0.0") private String nameSpace; + @GrayVersion(value = "5.0.0") private List wrongDns; public String getNameSpace() { @@ -737,8 +835,11 @@ public static class SetForwardDnsRsp extends AgentResponse { } public static class RemoveForwardDnsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private String mac; + @GrayVersion(value = "5.0.0") private String bridgeName; + @GrayVersion(value = "5.0.0") private String nameSpace; public String getNameSpace() { @@ -771,6 +872,7 @@ public static class RemoveForwardDnsRsp extends AgentResponse { } public static class RemoveDnsCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List dns; public List getDns() { @@ -792,6 +894,9 @@ public static class VipTO { private String ip; private String netmask; private String gateway; + private String ip6; + private int prefixLength; + private String gateway6; private String ownerEthernetMac; private String vipUuid; private boolean isSystem; @@ -799,9 +904,16 @@ public static class VipTO { public static VipTO valueOf(VipInventory inv, String ownerMac) { VipTO to = new VipTO(); - to.setIp(inv.getIp()); - to.setNetmask(inv.getNetmask()); - to.setGateway(inv.getGateway()); + if (NetworkUtils.isIpv4Address(inv.getIp())) { + to.setIp(inv.getIp()); + to.setNetmask(inv.getNetmask()); + to.setGateway(inv.getGateway()); + } else { + to.setIp6(inv.getIp()); + to.setNetmask(inv.getNetmask()); + to.setGateway6(inv.getGateway()); + to.setPrefixLength(inv.getPrefixLen()); + } to.setOwnerEthernetMac(ownerMac); to.setVipUuid(inv.getUuid()); to.setSystem(inv.isSystem()); @@ -860,6 +972,30 @@ public boolean isSystem() { public void setSystem(boolean system) { isSystem = system; } + + public String getIp6() { + return ip6; + } + + public void setIp6(String ip6) { + this.ip6 = ip6; + } + + public int getPrefixLength() { + return prefixLength; + } + + public void setPrefixLength(int prefixLength) { + this.prefixLength = prefixLength; + } + + public String getGateway6() { + return gateway6; + } + + public void setGateway6(String gateway6) { + this.gateway6 = gateway6; + } } public static class NicIpTO { @@ -907,10 +1043,15 @@ public void setOwnerEthernetMac(String ownerEthernetMac) { } public static class CreateVipCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private Boolean syncVip; + @GrayVersion(value = "5.0.0") private List vips; /* sync all vips to virtual router together with nic ips*/ + @GrayVersion(value = "5.0.0") private List nicIps; + @GrayVersion(value = "5.3.0") + private Boolean resetQosRules; public Boolean getSyncVip() { return syncVip; @@ -935,9 +1076,18 @@ public List getNicIps() { public void setNicIps(List nicIps) { this.nicIps = nicIps; } + + public Boolean getResetQosRules() { + return resetQosRules; + } + + public void setResetQosRules(Boolean resetQosRules) { + this.resetQosRules = resetQosRules; + } } public static class RemoveVipCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List vips; public List getVips() { @@ -954,6 +1104,7 @@ public static class RemoveVipRsp extends AgentResponse { } public static class CreateEipCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private EipTO eip; public EipTO getEip() { @@ -969,6 +1120,7 @@ public static class CreateEipRsp extends AgentResponse { } public static class RemoveEipCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private EipTO eip; public EipTO getEip() { @@ -984,6 +1136,7 @@ public static class RemoveEipRsp extends AgentResponse { } public static class SyncEipCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List eips; public List getEips() { @@ -1016,6 +1169,7 @@ public static class PingRsp extends AgentResponse { private String haStatus; private Boolean healthy; private String healthDetail; + private HashMap> serviceHealthList; public String getUuid() { return uuid; @@ -1056,10 +1210,20 @@ public String getHealthDetail() { public void setHealthDetail(String healthDetail) { this.healthDetail = healthDetail; } + + public HashMap> getServiceHealthList() { + return serviceHealthList; + } + + public void setServiceHealthList(HashMap> serviceHealthList) { + this.serviceHealthList = serviceHealthList; + } } public static class ChangeDefaultNicCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private NicInfo newNic; + @GrayVersion(value = "5.0.0") private List snats; public NicInfo getNewNic() { @@ -1084,6 +1248,7 @@ public static class ChangeDefaultNicRsp extends AgentResponse { } public static class ConfigureNtpCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") private List timeServers; public List getTimeServers() { @@ -1099,4 +1264,28 @@ public void setTimeServers(List timeServers) { public static class ConfigureNtpRsp extends AgentResponse { } + + public static class ConfigPromtailCmd extends AgentCommand { + @GrayVersion(value = "5.3.28") + private boolean enable; + + @GrayVersion(value = "5.3.28") + private String logTarget; + + public boolean isEnable() { + return enable; + } + + public void setEnable(boolean enable) { + this.enable = enable; + } + + public String getLogTarget() { + return logTarget; + } + + public void setLogTarget(String logTarget) { + this.logTarget = logTarget; + } + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterConstant.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterConstant.java index e7ff5e71cde..01a7899fecc 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterConstant.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterConstant.java @@ -22,6 +22,7 @@ public interface VirtualRouterConstant { public static final String SERVICE_ID = "virtualRouter"; public static final String VR_ECHO_PATH = "/echo"; + public static final String VR_GET_TYPE_PATH = "/type"; public static final String VR_CONFIGURE_NIC_PATH = "/configurenic"; public static final String VR_REMOVE_NIC_PATH = "/removenic"; public static final String VR_CONFIGURE_NIC_FIREWALL_DEFAULT_ACTION_PATH = "/configurenicdefaultaction"; @@ -48,6 +49,8 @@ public interface VirtualRouterConstant { public static final String VR_CREATE_VIP = "/createvip"; public static final String VR_REMOVE_VIP = "/removevip"; + public static final String VR_CONFIG_PROMTAIL = "/promtail/config"; + public static final String VR_KVM_CREATE_BOOTSTRAP_ISO_PATH = "/virtualrouter/createbootstrapiso"; public static final String VR_KVM_DELETE_BOOTSTRAP_ISO_PATH = "/virtualrouter/deletebootstrapiso"; @@ -57,6 +60,10 @@ public interface VirtualRouterConstant { public static final String ANSIBLE_PLAYBOOK_NAME = "virtualrouter.py"; public static final String ANSIBLE_MODULE_PATH = "ansible/virtualrouter"; public static final String SNAT_NETWORK_SERVICE_TYPE = "SNAT"; + public static final String IPSEC_NETWORK_SERVICE_TYPE = "IPsec"; + public static final String IPSEC_NETWORK_SERVICE_LATEST_VERSION = "5.9.4"; + public static final String IPSEC_NETWORK_SERVICE_EULER_2203 = "5.9.7"; + public static final String IPSEC_NETWORK_SERVICE_OLD_VERSION = "4.5.2"; public static final String VR_CHANGE_DEFAULT_ROUTE_JOB = "changeDefaultNic"; public static final String VR_DEFAULT_ROUTE_NETWORK = "defaultNetwork"; @@ -65,6 +72,11 @@ public interface VirtualRouterConstant { public static final String TC_FOR_VIPQOS = "ConfigTcForVipQos"; + public static final String VR_KERNEL_VERSION = "5.4.80"; + public static final String VR_OLD_KERNEL_VERSION = "3.13.11"; + + public static final String VR_HA_MASTER_DEMOTE = "/keepalived/demote"; + public static enum Param { VR, VR_UUID, @@ -79,4 +91,11 @@ public static enum Param { IS_HA_ROUTER, APPLY_TO_VIRTUALROUTER, } + + public static final String X86_VPC_EULER_GUEST_OS_TYPE = "openEuler 22.03"; + public static final String X86_VPC_EULER_GUEST_OS_USER = "zstack"; + public static final String X86_VPC_VYOS_GUEST_OS_TYPE = "VyOS 1.1.7"; + public static final String X86_VPC_VYOS_GUEST_OS_USER = "vyos"; + public static final String ARM_VPC_VYOS_GUEST_OS_TYPE = "VyOS 1.2.0"; + public static final String ARM_VPC_VYOS_GUEST_OS_USER = "vyos"; } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterGlobalProperty.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterGlobalProperty.java index f9c4dfefc8e..7dad8ffaf39 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterGlobalProperty.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterGlobalProperty.java @@ -9,7 +9,7 @@ */ @GlobalPropertyDefinition public class VirtualRouterGlobalProperty { - @GlobalProperty(name="VirtualRouter.agentPackageName", defaultValue = "virtualrouter-4.4.0.tar.gz") + @GlobalProperty(name="VirtualRouter.agentPackageName", defaultValue = "virtualrouter-5.4.0.tar.gz") public static String AGENT_PACKAGE_NAME; @GlobalProperty(name="VirtualRouter.agentPort", defaultValue = "7272") public static int AGENT_PORT; @@ -21,6 +21,6 @@ public class VirtualRouterGlobalProperty { public static List TCP_PORTS_ON_MGMT_NIC; @GlobalProperty(name="VirtualRouter.portsOpenOnManagementNic.udp.") public static List UDP_PORTS_ON_MGMT_NIC; - @GlobalProperty(name="VirtualRouter.enableMultiSnat", defaultValue = "false") + @GlobalProperty(name="VirtualRouter.enableMultiSnat", defaultValue = "true") public static boolean ENABLE_MULTI_SNAT; } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackendCommands.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackendCommands.java index 5d1748b1298..c6ec94fd75b 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackendCommands.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterKvmBackendCommands.java @@ -1,5 +1,6 @@ package org.zstack.network.service.virtualrouter; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.kvm.KVMAgentCommands; import java.util.List; @@ -73,7 +74,9 @@ public void setDns(List dns) { } public static class CreateVritualRouterBootstrapIsoCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") private BootstrapIsoInfo isoInfo; + @GrayVersion(value = "5.0.0") private String isoPath; public BootstrapIsoInfo getIsoInfo() { return isoInfo; @@ -93,6 +96,7 @@ public static class CreateVritualRouterBootstrapIsoRsp extends KVMAgentCommands. } public static class DeleteVirtualRouterBootstrapIsoCmd extends KVMAgentCommands.AgentCommand { + @GrayVersion(value = "5.0.0") public String isoPath; public String getIsoPath() { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java index 9ab916c9670..ca14cc78996 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterManagerImpl.java @@ -1,11 +1,11 @@ package org.zstack.network.service.virtualrouter; -import com.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.util.UriComponentsBuilder; import org.zstack.appliancevm.*; import org.zstack.compute.vm.VmNicExtensionPoint; +import org.zstack.compute.vm.VmSystemTags; import org.zstack.core.CoreGlobalProperty; import org.zstack.core.Platform; import org.zstack.core.ansible.AnsibleFacade; @@ -29,9 +29,7 @@ import org.zstack.header.configuration.InstanceOfferingState; import org.zstack.header.configuration.InstanceOfferingVO; import org.zstack.header.core.*; -import org.zstack.header.core.workflow.Flow; -import org.zstack.header.core.workflow.FlowChain; -import org.zstack.header.core.workflow.FlowException; +import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; @@ -45,10 +43,7 @@ import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; import org.zstack.header.network.NetworkException; -import org.zstack.header.network.l2.APICreateL2NetworkMsg; -import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l2.L2NetworkCreateExtensionPoint; -import org.zstack.header.network.l2.L2NetworkInventory; +import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.*; import org.zstack.header.network.service.*; import org.zstack.header.query.AddExpandedQueryExtensionPoint; @@ -60,7 +55,6 @@ import org.zstack.identity.Account; import org.zstack.identity.AccountManager; import org.zstack.image.ImageSystemTags; -import org.zstack.kvm.KVMConstant; import org.zstack.network.l3.IpRangeHelper; import org.zstack.network.l3.L3NetworkSystemTags; import org.zstack.network.service.NetworkServiceManager; @@ -78,6 +72,7 @@ import org.zstack.network.service.virtualrouter.vyos.VyosConstants; import org.zstack.network.service.virtualrouter.vyos.VyosVersionCheckResult; import org.zstack.network.service.virtualrouter.vyos.VyosVersionManager; +import org.zstack.network.service.virtualrouter.VirtualRouterCommands.*; import org.zstack.tag.SystemTagCreator; import org.zstack.tag.TagManager; import org.zstack.utils.*; @@ -96,6 +91,7 @@ import java.util.stream.Collectors; import static java.util.Arrays.asList; +import static org.zstack.compute.vm.VmSystemTags.MACHINE_TYPE_TOKEN; import static org.zstack.core.Platform.*; import static org.zstack.core.progress.ProgressReportService.createSubTaskProgress; import static org.zstack.network.service.virtualrouter.VirtualRouterConstant.VIRTUAL_ROUTER_PROVIDER_TYPE; @@ -110,7 +106,8 @@ public class VirtualRouterManagerImpl extends AbstractService implements Virtual PrepareDbInitialValueExtensionPoint, L2NetworkCreateExtensionPoint, GlobalApiMessageInterceptor, AddExpandedQueryExtensionPoint, GetCandidateVmNicsForLoadBalancerExtensionPoint, GetPeerL3NetworksForLoadBalancerExtensionPoint, FilterVmNicsForEipInVirtualRouterExtensionPoint, ApvmCascadeFilterExtensionPoint, ManagementNodeReadyExtensionPoint, - VipCleanupExtensionPoint, GetL3NetworkForEipInVirtualRouterExtensionPoint, VirtualRouterHaGetCallbackExtensionPoint, AfterAddIpRangeExtensionPoint, QueryBelongFilter { + VipCleanupExtensionPoint, GetL3NetworkForEipInVirtualRouterExtensionPoint, VirtualRouterHaGetCallbackExtensionPoint, AfterAddIpRangeExtensionPoint, QueryBelongFilter, + VmInstanceMigrateExtensionPoint, VmPreMigrationExtensionPoint { private final static CLogger logger = Utils.getLogger(VirtualRouterManagerImpl.class); private final static List supportedL2NetworkTypes = new ArrayList(); @@ -327,10 +324,18 @@ public String call() { aspec.setSshPort(VirtualRouterGlobalConfig.SSH_PORT.value(Integer.class)); aspec.setAgentPort(msg.getApplianceVmAgentPort()); + List tags = new ArrayList<>(); + if (msg.getSystemTags() != null && !msg.getSystemTags().isEmpty()) { + tags.addAll(msg.getSystemTags()); + } String imgBootMode = ImageSystemTags.BOOT_MODE.getTokenByResourceUuid(imgvo.getUuid(), ImageSystemTags.BOOT_MODE_TOKEN); if (ImageBootMode.UEFI.toString().equals(imgBootMode)) { - aspec.getInherentSystemTags().addAll(Lists.newArrayList(ImageSystemTags.BOOT_MODE.getTag(imgvo.getUuid()), "vmMachineType::q35")); + tags.addAll(Arrays.asList(ImageSystemTags.BOOT_MODE.getTag(imgvo.getUuid()), VmSystemTags.MACHINE_TYPE.instantiateTag(map(e(MACHINE_TYPE_TOKEN, VmMachineType.q35.toString()))))); + } + if (!tags.isEmpty()) { + aspec.setInherentSystemTags(tags); } + L3NetworkInventory mgmtNw = L3NetworkInventory.valueOf(dbf.findByUuid(offering.getManagementNetworkUuid(), L3NetworkVO.class)); ApplianceVmNicSpec mgmtNicSpec = new ApplianceVmNicSpec(); mgmtNicSpec.setL3NetworkUuid(mgmtNw.getUuid()); @@ -637,9 +642,14 @@ private void setupCanonicalEvents() { @Override protected void run(Map tokens, Object data) { VmCanonicalEvents.VmStateChangedData d = (VmCanonicalEvents.VmStateChangedData) data; - if (VmInstanceState.Paused.toString().equals(d.getNewState())) { + if (VmInstanceState.Paused.toString().equals(d.getNewState()) + || VmInstanceState.NoState.toString().equals(d.getNewState())) { ApplianceVmVO applianceVmVO = Q.New(ApplianceVmVO.class).eq(ApplianceVmVO_.uuid, d.getInventory().getUuid()).find(); - if (applianceVmVO != null) { + if (applianceVmVO == null) { + return; + } + + if (VmInstanceState.Paused.toString().equals(d.getNewState())) { ApplianceVmCanonicalEvents.ApplianceVmStateChangeData applianceVmStateChangeData = new ApplianceVmCanonicalEvents.ApplianceVmStateChangeData(); applianceVmStateChangeData.setOldState(d.getOldState()); applianceVmStateChangeData.setNewState(d.getNewState()); @@ -647,6 +657,19 @@ protected void run(Map tokens, Object data) { applianceVmStateChangeData.setInv(ApplianceVmInventory.valueOf(applianceVmVO)); evf.fire(ApplianceVmCanonicalEvents.APPLIANCEVM_STATE_CHANGED_PATH, applianceVmStateChangeData); } + + if (VmInstanceState.NoState.toString().equals(d.getNewState())) { + logger.debug(String.format("the virtual router vm[uuid: %s] is in NoState, stop it anyway", d.getInventory().getUuid())); + // NoState means we lost control of the vm, stop the vm and wait vm ha to start it + // Do not use reboot to make sure vm could be ha to another host. + // Only tries to stop vm once, if it failed, let ha to handle it. + StopVmInstanceMsg msg = new StopVmInstanceMsg(); + msg.setVmInstanceUuid(d.getInventory().getUuid()); + msg.setGcOnFailure(true); + msg.setType(StopVmType.force.toString()); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, d.getInventory().getUuid()); + bus.send(msg); + } } } }); @@ -877,6 +900,11 @@ public void afterCreateL2Network(L2NetworkInventory l2Network) { if (!supportedL2NetworkTypes.contains(l2Network.getType())) { return; } + + VSwitchType vSwitchType = VSwitchType.valueOf(l2Network.getvSwitchType()); + if (vSwitchType.getSdnControllerType() != null) { + return; + } NetworkServiceProviderVO vo = getRouterVO(); NetworkServiceProvider router = providerFactory.getNetworkServiceProvider(vo); @@ -1209,7 +1237,7 @@ public void success(VirtualRouterVmInventory returnValue) { @Override public void fail(ErrorCode errorCode) { lock.unlock(); - completion.fail(errorCode); + completion.fail(operr("Failed to start vr l3[uuid: %s]", struct.getL3Network().getUuid()).causedBy(errorCode)); chain.next(); } }); @@ -1568,6 +1596,11 @@ public List getExpandedQueryAliasesStructs() { return aliases; } + @Override + public List filterEipsForVmNicInVirtualRouter(VmNicInventory vmNic, List eips) { + return eips; + } + @Override @Transactional(readOnly = true) public List filterVmNicsForEipInVirtualRouter(VipInventory vip, List candidates) { @@ -1671,10 +1704,11 @@ public List filterVmNicsForEipInVirtualRouter(VipInventory vip, } private String getVipPeerL3NetworkAttachedVirtualRouter(VipInventory vip) { - for (String l3Uuid : vip.getPeerL3NetworkUuids()) { - List vrUuids = Q.New(VmNicVO.class).select(VmNicVO_.vmInstanceUuid).eq(VmNicVO_.l3NetworkUuid, l3Uuid).eq(VmNicVO_.metaData, GUEST_NIC_MASK).listValues(); - if (vrUuids == null || vrUuids.isEmpty()) { - return null; + String vrUuid = null; + for (String l3Uuid : vip.getPeerL3NetworkUuids()) { + List vrUuids = Q.New(VmNicVO.class).select(VmNicVO_.vmInstanceUuid).eq(VmNicVO_.l3NetworkUuid, l3Uuid).eq(VmNicVO_.metaData, GUEST_NIC_MASK).listValues(); + if (vrUuids == null || vrUuids.isEmpty()) { + return null; } vrUuids = Q.New(ApplianceVmVO.class).select(ApplianceVmVO_.uuid).in(ApplianceVmVO_.uuid, vrUuids) @@ -1683,10 +1717,10 @@ private String getVipPeerL3NetworkAttachedVirtualRouter(VipInventory vip) { return null; } - return vrUuids.get(0); + vrUuid = vrUuids.get(0); } - return null; + return vrUuid; } private String getDedicatedRoleVrUuidFromVrUuids(List uuids, String loadBalancerUuid) { @@ -1721,7 +1755,7 @@ private String getVirtualRouterVmAttachedLoadBalancer(String lbUuid) { final List peerL3NetworkUuids = SQL.New("select peer.l3NetworkUuid " + "from LoadBalancerVO lb, VipVO vip, VipPeerL3NetworkRefVO peer " + - "where lb.vipUuid = vip.uuid " + + "where (lb.vipUuid = vip.uuid or lb.ipv6VipUuid = vip.uuid) " + "and vip.uuid = peer.vipUuid " + "and lb.uuid = :lbUuid").param("lbUuid", lbUuid).list(); @@ -1744,9 +1778,9 @@ private String getVirtualRouterVmAttachedLoadBalancer(String lbUuid) { } VipVO lbVipVO = SQL.New("select vip from LoadBalancerVO lb, VipVO vip " + - "where lb.vipUuid = vip.uuid " + + "where (lb.vipUuid = vip.uuid or lb.ipv6VipUuid = vip.uuid) " + "and lb.uuid = :lbUuid") - .param("lbUuid", lbUuid).find(); + .param("lbUuid", lbUuid).limit(1).find(); if (lbVipVO != null) { List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, lbVipVO.getUuid()).listValues(); @@ -1786,9 +1820,9 @@ protected List scripts() { } /*get peer network of vip, vr has been deleted, so just return these peer networks*/ - final List peerL3NetworkUuids = SQL.New("select peer.l3NetworkUuid " + + final List peerL3NetworkUuids = SQL.New("select distinct peer.l3NetworkUuid " + "from LoadBalancerVO lb, VipVO vip, VipPeerL3NetworkRefVO peer " + - "where lb.vipUuid = vip.uuid " + + "where (lb.vipUuid = vip.uuid or lb.vipUuid = vip.uuid)" + "and vip.uuid = peer.vipUuid " + "and lb.uuid = :lbUuid").param("lbUuid", lbUuid).list(); @@ -1816,9 +1850,9 @@ protected List scripts() { } VipVO lbVipVO = SQL.New("select vip from LoadBalancerVO lb, VipVO vip " + - "where lb.vipUuid = vip.uuid " + + "where (lb.vipUuid = vip.uuid or lb.ipv6VipUuid = vip.uuid) " + "and lb.uuid = :lbUuid") - .param("lbUuid", lbUuid).find(); + .param("lbUuid", lbUuid).limit(1).find(); //2.check the l3 is peer l3 of the loadbalancer L3NetworkVO vipNetwork = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, lbVipVO.getL3NetworkUuid()).find(); @@ -1876,7 +1910,7 @@ public List getCandidateVmNicsForLoadBalancerInVirtualRouter(API final List peerL3NetworkUuids = SQL.New("select peer.l3NetworkUuid " + "from LoadBalancerVO lb, VipVO vip, VipPeerL3NetworkRefVO peer " + - "where lb.vipUuid = vip.uuid " + + "where (lb.vipUuid = vip.uuid or lb.ipv6VipUuid = vip.uuid) " + "and vip.uuid = peer.vipUuid " + "and lb.uuid = :lbUuid") .param("lbUuid", msg.getLoadBalancerUuid()) @@ -1890,10 +1924,10 @@ public List getCandidateVmNicsForLoadBalancerInVirtualRouter(API @Override protected List scripts() { - VipVO lbVipVO = SQL.New("select vip from LoadBalancerVO lb, VipVO vip " + - "where lb.vipUuid = vip.uuid " + + List lbVipVO = SQL.New("select vip from LoadBalancerVO lb, VipVO vip " + + "where (lb.vipUuid = vip.uuid or lb.ipv6VipUuid = vip.uuid) " + "and lb.uuid = :lbUuid") - .param("lbUuid", msg.getLoadBalancerUuid()).find(); + .param("lbUuid", msg.getLoadBalancerUuid()).list(); //1.get the l3 networks which has the vrouter lb network service. List inners = sql("select l3.uuid from L3NetworkVO l3, NetworkServiceL3NetworkRefVO ref, NetworkServiceProviderVO pro" + @@ -1909,7 +1943,7 @@ protected List scripts() { } //2.check the l3 of vm nic is peer l3 of the loadbalancer - L3NetworkVO vipNetwork = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, lbVipVO.getL3NetworkUuid()).find(); + L3NetworkVO vipNetwork = Q.New(L3NetworkVO.class).eq(L3NetworkVO_.uuid, lbVipVO.get(0).getL3NetworkUuid()).find(); List peerL3Uuids = SQL.New("select l3.uuid" + " from VmNicVO nic, L3NetworkVO l3" + " where nic.vmInstanceUuid in " + @@ -1999,7 +2033,7 @@ protected List scripts() { }.execute(); } - private List applianceVmsToBeDeleted(List applianceVmVOS, List deletedUuids) { + public List applianceVmsToBeDeleted(List applianceVmVOS, List deletedUuids) { List vos = new ArrayList<>(); for (ApplianceVmVO vo : applianceVmVOS) { VirtualRouterVmVO vo_dbf = dbf.findByUuid(vo.getUuid(), VirtualRouterVmVO.class); @@ -2023,7 +2057,7 @@ private List applianceVmsToBeDeleted(List applianc return vos; } - List applianceVmsAdditionalPublicNic(List applianceVmVOS, List parentIssuerUuids) { + public List applianceVmsAdditionalPublicNic(List applianceVmVOS, List parentIssuerUuids) { List toDeleteNics = new ArrayList<>(); for (ApplianceVmVO vo : applianceVmVOS) { VirtualRouterVmVO vr_dbf = dbf.findByUuid(vo.getUuid(), VirtualRouterVmVO.class); @@ -2098,7 +2132,7 @@ public void done(ErrorCodeList errorCodeList) { }); } - List applianceVmsToDeleteNicByIpRanges(List applianceVmVOS, List iprUuids) { + public List applianceVmsToDeleteNicByIpRanges(List applianceVmVOS, List iprUuids) { List toDeleteNics = new ArrayList<>(); for (ApplianceVmVO vo : applianceVmVOS) { for (VmNicVO nic : vo.getVmNics()) { @@ -2125,7 +2159,7 @@ List applianceVmsToDeleteNicByIpRanges(List applianceVmV return toDeleteNics; } - private List applianceVmsToBeDeletedByIpRanges(List applianceVmVOS, List iprUuids) { + public List applianceVmsToBeDeletedByIpRanges(List applianceVmVOS, List iprUuids) { List toDeleted = new ArrayList<>(); List l3Uuids = Q.New(IpRangeVO.class).in(IpRangeVO_.uuid, iprUuids).select(IpRangeVO_.l3NetworkUuid).listValues(); for (ApplianceVmVO vos : applianceVmVOS) { @@ -2157,7 +2191,11 @@ private List applianceVmsToBeDeletedByIpRanges(List filterApplianceVmCascade(List applianceVmVOS, CascadeAction action, String parentIssuer, List parentIssuerUuids, List toDeleteNics) { + public List filterApplianceVmCascade(List applianceVmVOS, CascadeAction action, + String parentIssuer, + List parentIssuerUuids, + List toDeleteNics, + List toDeleteIps) { logger.debug(String.format("filter appliance vm type with parentIssuer [type: %s, uuids: %s]", parentIssuer, parentIssuerUuids)); if (parentIssuer.equals(L3NetworkVO.class.getSimpleName())) { List vos = applianceVmsToBeDeleted(applianceVmVOS, parentIssuerUuids); @@ -2177,6 +2215,11 @@ public List filterApplianceVmCascade(List applianc } } + @Override + public ApplianceVmType getApplianceVmType() { + return ApplianceVmType.valueOf(VirtualRouterConstant.VIRTUAL_ROUTER_VM_TYPE); + } + private void reconenctVirtualRouter(String vrUUid, boolean statusChange) { ReconnectVirtualRouterVmMsg msg = new ReconnectVirtualRouterVmMsg(); msg.setVirtualRouterVmUuid(vrUUid); @@ -2351,6 +2394,7 @@ private List getSnatInfo(VirtualRouterVmInventor info.setPublicIp(publicNic.getIp()); info.setPublicNicMac(publicNic.getMac()); info.setSnatNetmask(vnic.getNetmask()); + info.setPrivateGatewayIp(vnic.getGateway()); snatInfo.add(info); } } @@ -2358,20 +2402,6 @@ private List getSnatInfo(VirtualRouterVmInventor return snatInfo; } - private void changeVirtualRouterSnatData(String vrUuid, String newL3Uuid, String oldL3Uuid){ - VirtualRouterVmVO vrVO = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, vrUuid).find(); - if (vrVO == null) { - return ; - } - ApplianceVmSubTypeFactory subTypeFactory = apvmFactory.getApplianceVmSubTypeFactory(vrVO.getApplianceVmType()); - ApplianceVm app = subTypeFactory.getSubApplianceVm(vrVO); - app.detachNetworkService(vrUuid, NetworkServiceType.SNAT.toString(), oldL3Uuid); - app.attachNetworkService(vrUuid, NetworkServiceType.SNAT.toString(), newL3Uuid); - String msg = String.format( - "virtual router[uuid:%s] successfully change snat for old default public l3[uuid:%s] to new default public l3[uuid:%s]", - vrUuid, oldL3Uuid, newL3Uuid); - logger.warn(msg); - } @Transactional protected void changeVirtualRouterNicMetaData(String vrUuid, String newL3Uuid, String oldL3Uuid) { @@ -2406,6 +2436,7 @@ public VmNicVO call(VmNicVO arg) { VirtualRouterCommands.NicInfo newNicInfo = new VirtualRouterCommands.NicInfo(); newNicInfo.setMac(newNic.getMac()); + newNicInfo.setState(newNic.getState().toString()); for (UsedIpVO ip : newNic.getUsedIps()) { if (ip.getIpVersion() == IPv6Constants.IPv4) { newNicInfo.setGateway(ip.getGateway()); @@ -2445,7 +2476,6 @@ public void run(MessageReply reply) { vrUuid, ret.getError()); completion.fail(err); } else { - changeVirtualRouterSnatData(vrUuid, newL3Uuid, oldL3Uuid); changeVirtualRouterNicMetaData(vrUuid, newL3Uuid, oldL3Uuid); completion.success(); } @@ -2475,6 +2505,10 @@ public void callBack(String vrUuid, VirtualRouterHaTask task, Completion complet @Override public void afterAddIpRange(IpRangeInventory ipr, List systemTags) { + if (!Q.New(NormalIpRangeVO.class).eq(NormalIpRangeVO_.uuid, ipr.getUuid()).isExists()) { + return; + } + /* when change a IPv4/IPv6 network to dual stack network, after add the ip range, allocate the gateway ip to virtual router, but only after reboot virtual router, virtual router will be configured with the gateway */ @@ -2603,4 +2637,188 @@ public List getPublicL3UuidsOfPrivateL3(L3NetworkVO privateL3) { .in(VmNicVO_.metaData, VirtualRouterNicMetaData.ALL_PUBLIC_NIC_MASK_STRING_LIST).listValues(); return l3Uuids; } + + @Override + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { + + } + + @Override + public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid, NoErrorCompletion completion) { + if (inv == null || srcHostUuid == null) { + completion.done(); + return; + } + if (VmInstanceConstant.USER_VM_TYPE.equals(inv.getType())) { + completion.done(); + return; + } + List vfNics = inv.getVmNics().stream() + .filter(nic -> !Objects.equals(nic.getType(), VmInstanceConstant.VIRTUAL_NIC_TYPE)) + .collect(Collectors.toList()); + logger.debug(String.format("virtual router[uuid:%s] has %s vf nics need to sync vip after hot migrate", + inv.getUuid(), vfNics.size())); + if (vfNics.isEmpty()) { + completion.done(); + return; + } + List vips = findVipsOnVirtualRouter(vfNics, inv.getUuid()); + if (vips.isEmpty()) { + completion.done(); + return; + } + List nicIps = new ArrayList<>(); + for (VmNicInventory nic : inv.getVmNics()) { + nicIps.add(NicIpTO.valueOf(nic)); + } + + + CreateVipCmd cmd = new CreateVipCmd(); + cmd.setSyncVip(true); + cmd.setVips(vips); + cmd.setNicIps(nicIps); + cmd.setResetQosRules(true); + + VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); + msg.setVmInstanceUuid(inv.getUuid()); + msg.setCommand(cmd); + msg.setPath(VirtualRouterConstant.VR_CREATE_VIP); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, inv.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(String.format("failed to sync vips on virtual router[uuid:%s] due to %s", + inv.getUuid(), reply.getError())); + completion.done(); + return; + } + + VirtualRouterAsyncHttpCallReply re = reply.castReply(); + CreateVipRsp ret = re.toResponse(CreateVipRsp.class); + if (!ret.isSuccess()) { + ErrorCode err = operr("failed to sync vips[ips: %s] on virtual router[uuid:%s]" + + " for vr hot mirage, because %s", + vips.stream().map(VipTO::getIp).collect(Collectors.toList()), + inv.getUuid(), ret.getError()); + logger.warn(err.toString()); + completion.done(); + } else { + List vipUuids = vips.stream().map(VipTO::getVipUuid).distinct().collect(Collectors.toList()); + vipProxy.attachNetworkService(inv.getUuid(), VipVO.class.getSimpleName(), vipUuids); + List vips = Q.New(VipVO.class).in(VipVO_.uuid, vipUuids).list(); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(AfterAcquireVipExtensionPoint.class), ext -> { + logger.debug(String.format("execute after acquire vip extension point %s", ext)); + ext.afterAcquireVip(VipInventory.valueOf(vips)); + }); + completion.done(); + } + } + }); + } + + private List findVipsOnVirtualRouter(List vfNics, String vrUuid) { + List vipUuids = SQL.New("select vip.uuid from VipVO vip, VipPeerL3NetworkRefVO ref " + + "where ref.vipUuid = vip.uuid " + + "and (ref.l3NetworkUuid in (:l3NetworkUuids) " + + "or vip.l3NetworkUuid in (:l3NetworkUuids))") + .param("l3NetworkUuids", vfNics.stream().map(VmNicInventory::getL3NetworkUuid).collect(Collectors.toList())) + .list(); + + vipUuids = getVirtualRouterVips(vrUuid, vipUuids); + if (vipUuids == null || vipUuids.isEmpty()) { + return new ArrayList<>(); + } + + List vips = Q.New(VipVO.class).in(VipVO_.uuid, vipUuids).list(); + VirtualRouterVmInventory vr = VirtualRouterVmInventory.valueOf((VirtualRouterVmVO) + Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, vrUuid).find()); + + List systemVip = vips.stream().filter(VipVO::isSystem).collect(Collectors.toList()); + List notSystemVip = vips.stream().filter(v -> !v.isSystem()).collect(Collectors.toList()); + List vipss = new ArrayList<>(); + vipss.addAll(systemVip); + vipss.addAll(notSystemVip); + + List vipTOS = new ArrayList<>(); + for (VipVO vip : vipss) { + if (vipTOS.stream().anyMatch(v -> v.getIp().equals(vip.getIp()))) { + logger.warn(String.format( + "found duplicate vip ip[uuid; %s, uuids: %s] for vr[uuid: %s]", + vip.getIp(), + vips.stream(). + filter(v -> v.getIp().equals(vip.getIp())) + .map(VipVO::getUuid) + .collect(Collectors.toSet()), + vrUuid)); + continue; + } + + VipTO to = new VipTO(); + to.setIp(vip.getIp()); + to.setGateway(vip.getGateway()); + to.setNetmask(vip.getNetmask()); + Optional pubNic = vr.getVmNics().stream() + .filter(n -> n.getL3NetworkUuid().equals(vip.getL3NetworkUuid())) + .findFirst(); + if (!pubNic.isPresent()) { + continue; + } + to.setOwnerEthernetMac(pubNic.get().getMac()); + to.setVipUuid(vip.getUuid()); + to.setSystem(vip.isSystem()); + vipTOS.add(to); + } + + return vipTOS; + } + + @Override + public void preVmMigration(VmInstanceInventory vm, VmMigrationType type, String dstHostUuid, Completion completion) { + if (ApplianceVmConstant.APPLIANCE_VM_TYPE.equals(vm.getType())) { + VirtualRouterVmVO vrVo = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, vm.getUuid()).find(); + if (vrVo == null) { + completion.success(); + return; + } + VirtualRouterVmInventory inv = VirtualRouterVmInventory.valueOf(vrVo); + List vfNics = inv.getVmNics().stream() + .filter(nic -> !Objects.equals(nic.getType(), VmInstanceConstant.VIRTUAL_NIC_TYPE)) + .collect(Collectors.toList()); + if (vrVo.isHaEnabled() && !vfNics.isEmpty()) { + List exps = pluginRgty.getExtensionList(VirtualRouterHaGroupExtensionPoint.class); + if (exps.isEmpty()) { + completion.success(); + return; + } + String peerUuid = exps.get(0).getPeerUuid(vrVo.getUuid()); + if (peerUuid == null) { + completion.success(); + return; + } + if (ApplianceVmHaStatus.Master.equals(vrVo.getHaStatus()) && + ApplianceVmStatus.Connected.equals(vrVo.getStatus()) && + Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.status, ApplianceVmStatus.Connected) + .eq(VirtualRouterVmVO_.uuid, peerUuid).isExists()) { + logger.debug(String.format("demote ha master before migrate, virtual router[uuid:%s]", vrVo.getUuid())); + VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); + msg.setVmInstanceUuid(vrVo.getUuid()); + msg.setCommand(new VirtualRouterCommands.AgentCommand()); + msg.setCheckStatus(true); + msg.setPath(VirtualRouterConstant.VR_HA_MASTER_DEMOTE); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vrVo.getUuid()); + bus.send(msg, new CloudBusCallBack(null) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(reply.getError().toString()); + } + completion.success(); + } + }); + } + } + } + completion.success(); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataInventory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataInventory.java new file mode 100644 index 00000000000..9c3be5b8e5c --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataInventory.java @@ -0,0 +1,71 @@ +package org.zstack.network.service.virtualrouter; + +import org.zstack.appliancevm.ApplianceVmInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = VirtualRouterMetadataVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "applianceVm", inventoryClass = ApplianceVmInventory.class, + foreignKey = "uuid", expandedInventoryKey = "uuid"), +}) +public class VirtualRouterMetadataInventory { + private String uuid; + private String zvrVersion; + private String vyosVersion; + private String kernelVersion; + + public static VirtualRouterMetadataInventory valueOf(VirtualRouterMetadataVO vo){ + VirtualRouterMetadataInventory inv = new VirtualRouterMetadataInventory(); + inv.setUuid(vo.getUuid()); + inv.setZvrVersion(vo.getZvrVersion()); + inv.setVyosVersion(vo.getVyosVersion()); + inv.setKernelVersion(vo.getKernelVersion()); + return inv; + } + + public static List valueOf(Collection vos){ + List invs = new ArrayList<>(vos.size()); + for (VirtualRouterMetadataVO vo : vos) { + invs.add(VirtualRouterMetadataInventory.valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getZvrVersion() { + return zvrVersion; + } + + public void setZvrVersion(String zvrVersion) { + this.zvrVersion = zvrVersion; + } + + public String getVyosVersion() { + return vyosVersion; + } + + public void setVyosVersion(String vyosVersion) { + this.vyosVersion = vyosVersion; + } + + public String getKernelVersion() { + return kernelVersion; + } + + public void setKernelVersion(String kernelVersion) { + this.kernelVersion = kernelVersion; + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataOperator.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataOperator.java index 10a0a508cd0..4e033f30528 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataOperator.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataOperator.java @@ -3,12 +3,23 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.CoreGlobalProperty; import org.zstack.core.db.DatabaseFacade; import org.zstack.network.service.virtualrouter.vyos.VyosConstants; +import org.zstack.network.service.virtualrouter.vyos.VyosVersionVersionManagerImpl; +import org.zstack.utils.Utils; import org.zstack.utils.VersionComparator; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.path.PathUtil; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VirtualRouterMetadataOperator { + private final static CLogger logger = Utils.getLogger(VyosVersionVersionManagerImpl.class); + @Autowired DatabaseFacade dbf; @@ -85,4 +96,33 @@ public static boolean zvrVersionCheck(String zvrVersion) { return false; } } + + public String getManagementVersion() { + if (CoreGlobalProperty.UNIT_TEST_ON) { + return "3.10.0.0"; + } + + String managementVersion = null; + String path = null; + try { + path = PathUtil.findFileOnClassPath(VyosConstants.VYOS_VERSION_PATH, true).getAbsolutePath(); + } catch (RuntimeException e) { + logger.error(String.format("vyos version file find file because %s", e.getMessage())); + return null; + } + + try (BufferedReader br = new BufferedReader(new FileReader(path))) { + managementVersion = br.readLine(); + } catch (IOException e) { + logger.error(String.format("vyos version file %s read error: %s", path, e.getMessage())); + return null; + } + + if (!(VirtualRouterMetadataOperator.zvrVersionCheck(managementVersion))) { + logger.error(String.format("vyos version file format error: %s", managementVersion)); + return null; + } + + return managementVersion; + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataStruct.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataStruct.java index 0daf3e30a98..08184317c78 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataStruct.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterMetadataStruct.java @@ -37,4 +37,5 @@ public String getKernelVersion() { public void setKernelVersion(String kernelVersion) { this.kernelVersion = kernelVersion; } + } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterNicMetaData.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterNicMetaData.java index 2a0ff3df632..9595aaf7ee6 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterNicMetaData.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterNicMetaData.java @@ -171,4 +171,22 @@ public static void addAdditionalPublicToNic(VmNicVO nic) { int mask = Integer.parseInt(meta) | ADDITIONAL_PUBLIC_NIC_MASK; nic.setMetaData(String.valueOf(mask)); } + + public static boolean isManagementNicOnly(VmNicInventory nic) { + String meta = nic.getMetaData(); + if (meta == null) { + return false; + } + + return Integer.parseInt(meta)== MANAGEMENT_NIC_MASK; + } + + public static boolean isManagementNicOnly(VmNicVO nic) { + String meta = nic.getMetaData(); + if (meta == null) { + return false; + } + + return Integer.parseInt(meta)== MANAGEMENT_NIC_MASK; + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterPingTracker.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterPingTracker.java index 03a1586d81e..860217ab831 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterPingTracker.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterPingTracker.java @@ -10,7 +10,7 @@ import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; -import org.zstack.core.tacker.PingTracker; +import org.zstack.core.tracker.PingTracker; import org.zstack.core.thread.AsyncThread; import org.zstack.header.managementnode.ManagementNodeChangeListener; import org.zstack.header.managementnode.ManagementNodeInventory; @@ -18,11 +18,13 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.message.NeedReplyMessage; import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceState; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; +import java.util.ArrayList; import java.util.List; /** @@ -81,6 +83,15 @@ public void handleReply(final String resourceUuid, MessageReply reply) { return; } + // virtual router is not running/unknow state, skip the reconnection + VmInstanceState state = Q.New(VirtualRouterVmVO.class) + .eq(VirtualRouterVmVO_.uuid, resourceUuid) + .select(VirtualRouterVmVO_.state).findValue(); + if (VmInstanceState.Running != state && VmInstanceState.Unknown != state) { + logger.debug(String.format("virtual router[uuid:%s] is in state: %s, skip the reconnection", resourceUuid, state)); + return; + } + logger.debug(String.format("[Virtual Router VM Tracker]: the virtual router vm[uuid:%s] is detected a reconnect is needed, issuing it...", resourceUuid)); ReconnectVirtualRouterVmMsg msg = new ReconnectVirtualRouterVmMsg(); msg.setVirtualRouterVmUuid(resourceUuid); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionInventory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionInventory.java new file mode 100644 index 00000000000..13cc321a853 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionInventory.java @@ -0,0 +1,72 @@ +package org.zstack.network.service.virtualrouter; + +import org.zstack.appliancevm.ApplianceVmInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.search.Inventory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Inventory(mappingVOClass = VirtualRouterSoftwareVersionVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "applianceVm", inventoryClass = ApplianceVmInventory.class, + foreignKey = "uuid", expandedInventoryKey = "uuid"), +}) +public class VirtualRouterSoftwareVersionInventory { + private String uuid; + private String softwareName; + private String currentVersion; + private String latestVersion; + + public static VirtualRouterSoftwareVersionInventory valueOf(VirtualRouterSoftwareVersionVO vo){ + VirtualRouterSoftwareVersionInventory inv = new VirtualRouterSoftwareVersionInventory(); + inv.setUuid(vo.getUuid()); + inv.setSoftwareName(vo.getSoftwareName()); + inv.setCurrentVersion(vo.getCurrentVersion()); + inv.setLatestVersion(vo.getLatestVersion()); + return inv; + } + + public static List valueOf(Collection vos){ + List invs = new ArrayList<>(vos.size()); + for (VirtualRouterSoftwareVersionVO vo : vos) { + invs.add(VirtualRouterSoftwareVersionInventory.valueOf(vo)); + } + return invs; + } + + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getSoftwareName() { + return softwareName; + } + + public void setSoftwareName(String softwareName) { + this.softwareName = softwareName; + } + + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(String currentVersion) { + this.currentVersion = currentVersion; + } + + public String getLatestVersion() { + return latestVersion; + } + + public void setLatestVersion(String latestVersion) { + this.latestVersion = latestVersion; + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionInventoryDoc_zh_cn.groovy b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..7fc77403702 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionInventoryDoc_zh_cn.groovy @@ -0,0 +1,33 @@ +package org.zstack.network.service.virtualrouter + + + +doc { + + title "VPC软件版本" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.5" + } + field { + name "softwareName" + desc "VPC软件名称" + type "String" + since "4.5" + } + field { + name "currentVersion" + desc "当前版本" + type "String" + since "4.5" + } + field { + name "latestVersion" + desc "最新版本" + type "String" + since "4.5" + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionOperator.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionOperator.java new file mode 100644 index 00000000000..3c0b094d7ff --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionOperator.java @@ -0,0 +1,54 @@ +package org.zstack.network.service.virtualrouter; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VirtualRouterSoftwareVersionOperator { + @Autowired + DatabaseFacade dbf; + + public void updateVirtualRouterSoftwareVersion(VirtualRouterSoftwareVersionStruct struct) { + VirtualRouterSoftwareVersionVO vo = Q.New(VirtualRouterSoftwareVersionVO.class) + .eq(VirtualRouterSoftwareVersionVO_.uuid, struct.getVrUuid()) + .eq(VirtualRouterSoftwareVersionVO_.softwareName, "IPsec") + .find(); + boolean update = false; + if (vo != null) { + if (struct.getCurrentVersion() != null && !struct.getCurrentVersion().equals(vo.getCurrentVersion())) { + vo.setCurrentVersion(struct.getCurrentVersion()); + update = true; + } + + if (struct.getLatestVersion() != null && !struct.getLatestVersion().equals(vo.getLatestVersion())) { + vo.setLatestVersion(struct.getLatestVersion()); + update = true; + } + + if (update) { + dbf.update(vo); + } + } else { + vo = new VirtualRouterSoftwareVersionVO(); + vo.setUuid(struct.getVrUuid()); + vo.setSoftwareName(struct.getSoftwareName()); + + if (struct.getCurrentVersion() != null) { + vo.setCurrentVersion(struct.getCurrentVersion()); + update = true; + } + + if (struct.getLatestVersion() != null) { + vo.setLatestVersion(struct.getLatestVersion()); + update = true; + } + + if (update) { + dbf.persist(vo); + } + } + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionStruct.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionStruct.java new file mode 100644 index 00000000000..6029a39f7ff --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionStruct.java @@ -0,0 +1,41 @@ +package org.zstack.network.service.virtualrouter; + +public class VirtualRouterSoftwareVersionStruct { + private String vrUuid; + private String softwareName; + private String currentVersion; + private String latestVersion; + + public String getVrUuid() { + return vrUuid; + } + + public void setVrUuid(String vrUuid) { + this.vrUuid = vrUuid; + } + + public String getSoftwareName() { + return softwareName; + } + + public void setSoftwareName(String softwareName) { + this.softwareName = softwareName; + } + + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(String currentVersion) { + this.currentVersion = currentVersion; + } + + public String getLatestVersion() { + return latestVersion; + } + + public void setLatestVersion(String latestVersion) { + this.latestVersion = latestVersion; + } + +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionVO.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionVO.java new file mode 100644 index 00000000000..44bd2127d27 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionVO.java @@ -0,0 +1,70 @@ +package org.zstack.network.service.virtualrouter; + +import org.zstack.header.vm.VmInstanceVO; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.SoftDeletionCascade; +import org.zstack.header.vo.SoftDeletionCascades; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table +@SoftDeletionCascades({ + @SoftDeletionCascade(parent = VirtualRouterVmVO.class, joinColumn = "uuid") +}) +@EntityGraph( + friends = { + @EntityGraph.Neighbour(type = VmInstanceVO.class, myField = "uuid", targetField = "uuid") + } +) +public class VirtualRouterSoftwareVersionVO { + @Id + @Column + @ForeignKey(parentEntityClass = VirtualRouterVmVO.class, onDeleteAction = ForeignKey.ReferenceOption.RESTRICT) + private String uuid; + + @Column + private String softwareName; + + @Column + private String currentVersion; + + @Column + private String latestVersion; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getSoftwareName() { + return softwareName; + } + + public void setSoftwareName(String softwareName) { + this.softwareName = softwareName; + } + + public String getCurrentVersion() { + return currentVersion; + } + + public void setCurrentVersion(String ipsecCurrentVersion) { + this.currentVersion = ipsecCurrentVersion; + } + + public String getLatestVersion() { + return latestVersion; + } + + public void setLatestVersion(String ipsecLatestVersion) { + this.latestVersion = ipsecLatestVersion; + } +} \ No newline at end of file diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionVO_.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionVO_.java new file mode 100644 index 00000000000..c2a6986b8b0 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSoftwareVersionVO_.java @@ -0,0 +1,12 @@ +package org.zstack.network.service.virtualrouter; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +@StaticMetamodel(VirtualRouterSoftwareVersionVO.class) +public class VirtualRouterSoftwareVersionVO_ { + public static volatile SingularAttribute uuid; + public static volatile SingularAttribute softwareName; + public static volatile SingularAttribute currentVersion; + public static volatile SingularAttribute latestVersion; +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSystemTags.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSystemTags.java index 4c2488e3c7d..57020ec08d6 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSystemTags.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/VirtualRouterSystemTags.java @@ -34,4 +34,9 @@ public class VirtualRouterSystemTags { public static String VIRTUAL_ROUTER_OFFERING_TOKEN = "routerOffering"; public static PatternedSystemTag VIRTUAL_ROUTER_OFFERING = new PatternedSystemTag(String.format("virtualRouterOffering::{%s}", VIRTUAL_ROUTER_OFFERING_TOKEN), L3NetworkVO.class); + + public static String VIRTUAL_ROUTER_LOGIN_USER_TOKEN = "loginUser"; + public static PatternedSystemTag VIRTUAL_ROUTER_LOGIN_USER = new PatternedSystemTag(String.format( + "loginUser::{%s}", VIRTUAL_ROUTER_LOGIN_USER_TOKEN ), + VirtualRouterVmVO.class); } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java index ef0bc4ec3ea..b8c7d8f0b21 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dhcp/VirtualRouterDhcpBackend.java @@ -15,6 +15,7 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkCategory; import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.service.*; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceInventory; @@ -433,4 +434,14 @@ public void done() { return structs; } + + @Override + public void enableNetworkService(L3NetworkVO l3VO, List systemTags, Completion completion) { + completion.success(); + } + + @Override + public void disableNetworkService(L3NetworkVO l3VO, Completion completion) { + completion.success(); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterCentralizedDnsBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterCentralizedDnsBackend.java index 9ac2555afda..a561aca6484 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterCentralizedDnsBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterCentralizedDnsBackend.java @@ -11,20 +11,27 @@ import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.core.Completion; import org.zstack.header.core.NoErrorCompletion; -import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.host.HostConstant; import org.zstack.header.message.MessageReply; -import org.zstack.header.network.l3.*; -import org.zstack.header.network.service.*; import org.zstack.header.network.l2.L2NetworkVO; -import org.zstack.header.vm.*; +import org.zstack.header.network.l3.IpRangeInventory; +import org.zstack.header.network.l3.L3NetworkConstant; +import org.zstack.header.network.l3.L3NetworkInventory; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.service.*; +import org.zstack.header.vm.VmInstanceInventory; +import org.zstack.header.vm.VmInstanceMigrateExtensionPoint; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.VmNicInventory; import org.zstack.kvm.KVMHostAsyncHttpCallMsg; import org.zstack.kvm.KVMHostAsyncHttpCallReply; import org.zstack.kvm.KVMSystemTags; import org.zstack.network.l3.IpRangeHelper; +import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.virtualrouter.*; import org.zstack.network.service.virtualrouter.vyos.VyosConstants; import org.zstack.network.service.virtualrouter.vyos.VyosOfferingSelector; @@ -42,7 +49,7 @@ * Created by AlanJager on 2017/7/8. */ public class VirtualRouterCentralizedDnsBackend extends AbstractVirtualRouterBackend implements NetworkServiceCentralizedDnsBackend, - VmInstanceMigrateExtensionPoint, FlatDhcpGetDnsAddressExtensionPoint { + VmInstanceMigrateExtensionPoint, DnsServiceExtensionPoint { private final CLogger logger = Utils.getLogger(VirtualRouterCentralizedDnsBackend.class); @Autowired @@ -54,6 +61,9 @@ public class VirtualRouterCentralizedDnsBackend extends AbstractVirtualRouterBac @Autowired private DatabaseFacade dbf; + @Autowired + private NetworkServiceManager nsMgr; + public static final String SET_DNS_FORWARD_PATH = "/dns/forward/set"; public static final String REMOVE_DNS_FORWARD_PATH = "/dns/forward/remove"; @@ -226,6 +236,17 @@ public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { return; } + NetworkServiceProviderType providerType = null; + try { + providerType = nsMgr.getTypeOfNetworkServiceProviderForService(defaultL3.getUuid(), NetworkServiceType.DHCP); + } catch (Throwable e){ + logger.warn(e.getMessage(), e); + return; + } + if (VyosConstants.PROVIDER_TYPE.equals(providerType)) { + return; + } + L3NetworkInventory defaultL3Inv = L3NetworkInventory.valueOf(defaultL3); /* install dns forward address for default network */ VirtualRouterCommands.SetForwardDnsCmd cmd = new VirtualRouterCommands.SetForwardDnsCmd(); @@ -266,11 +287,6 @@ public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { } - @Override - public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { - - } - @Override public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) { if (inv.getDefaultL3NetworkUuid() == null) { @@ -318,10 +334,6 @@ public List getDnsAddress(L3NetworkInventory inv) { return dns; } - if (!inv.getNetworkServiceTypes().contains(NetworkServiceType.Centralized_DNS.toString())) { - return dns; - } - /* only virtual router network will add gateway as dns address */ for (NetworkServiceL3NetworkRefInventory ref : inv.getNetworkServices()) { if (!ref.getNetworkServiceType().equals(NetworkServiceType.SNAT.toString())) { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java index 138df594478..d7e1b8131c1 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/dns/VirtualRouterSyncDnsOnStartFlow.java @@ -20,6 +20,7 @@ import org.zstack.header.network.l3.L3NetworkDnsVO_; import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmNicInventory; import org.zstack.network.service.virtualrouter.*; import org.zstack.network.service.virtualrouter.VirtualRouterCommands.DnsInfo; import org.zstack.network.service.virtualrouter.VirtualRouterCommands.SetDnsCmd; @@ -87,11 +88,13 @@ public void run(final FlowTrigger chain, final Map data) { for (L3NetworkDnsVO vo : l3NetworkDnsVOS) { DnsInfo dinfo = new DnsInfo(); dinfo.setDnsAddress(vo.getDns()); - dinfo.setNicMac(vr.getGuestNics() - .stream() - .filter(nic -> nic.getL3NetworkUuid().equals(vo.getL3NetworkUuid())) - .findFirst().get() - .getMac()); + Optional nic = vr.getGuestNics().stream() + .filter(n -> n.getL3NetworkUuid().equals(vo.getL3NetworkUuid())) + .findFirst(); + if (!nic.isPresent()) { + continue; + } + dinfo.setNicMac(nic.get().getMac()); dns.add(dinfo); } List lst = query.listValue(); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/EipTO.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/EipTO.java index 47f8b19b1ea..18294f8f401 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/EipTO.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/EipTO.java @@ -11,6 +11,7 @@ public class EipTO implements Serializable { private String guestIp; private boolean snatInboundTraffic; private boolean needCleanGuestIp; + private String ipVersion; public boolean isNeedCleanGuestIp() { return needCleanGuestIp; @@ -59,4 +60,13 @@ public String getPublicMac() { public void setPublicMac(String publicMac) { this.publicMac = publicMac; } + + public String getIpVersion() { + return ipVersion; + } + + public void setIpVersion(String ipVersion) { + this.ipVersion = ipVersion; + } + } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java index 5c14843146e..9c789ca1501 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterEipBackend.java @@ -19,10 +19,10 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.UsedIpInventory; +import org.zstack.header.network.l3.UsedIpVO; import org.zstack.header.network.service.*; -import org.zstack.header.vm.VmInstanceConstant; -import org.zstack.header.vm.VmInstanceState; -import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.vm.*; import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.eip.*; import org.zstack.network.service.virtualrouter.*; @@ -35,6 +35,7 @@ import org.zstack.utils.function.Function; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6NetworkUtils; import javax.persistence.Tuple; import java.util.*; @@ -134,11 +135,16 @@ public String call(VmNicInventory arg) { } }); to.setPrivateMac(priMac); - to.setPublicMac(vr.getVmNics().stream().filter( - nic -> nic.getL3NetworkUuid().equals(struct.getVip().getL3NetworkUuid())).findFirst().get().getMac()); + to.setPublicMac(vr.getVmNics().stream() + .filter(nic -> nic.getL3NetworkUuid().equals(struct.getVip().getL3NetworkUuid())) + .findFirst() + .map(VmNicInventory::getMac) + .orElse(null)); to.setVipIp(struct.getVip().getIp()); - to.setGuestIp(struct.getNic().getIp()); to.setSnatInboundTraffic(struct.isSnatInboundTraffic()); + to.setIpVersion(IPv6NetworkUtils.getIpVersion(to.getVipIp())); + to.setGuestIp(IPv6NetworkUtils.getIpByIpVersion(to.getIpVersion(), + struct.getNic().getUsedIps().stream().map(UsedIpInventory::getIp).collect(Collectors.toList()))); VirtualRouterCommands.CreateEipCmd cmd = new VirtualRouterCommands.CreateEipCmd(); cmd.setEip(to); @@ -280,19 +286,23 @@ public String call(VmNicInventory arg) { } }); - - to.setPublicMac(vr.getVmNics().stream().filter( - nic -> nic.getL3NetworkUuid().equals(struct.getVip().getL3NetworkUuid())).findFirst().get().getMac()); + to.setPublicMac(vr.getVmNics().stream() + .filter(nic -> nic.getL3NetworkUuid().equals(struct.getVip().getL3NetworkUuid())) + .findFirst() + .map(VmNicInventory::getMac) + .orElse(null)); to.setPrivateMac(priMac); to.setSnatInboundTraffic(struct.isSnatInboundTraffic()); to.setVipIp(struct.getVip().getIp()); - to.setGuestIp(struct.getNic().getIp()); to.setNeedCleanGuestIp(!Q.New(EipVO.class) .eq(EipVO_.guestIp, struct.getEip().getGuestIp()) .eq(EipVO_.vmNicUuid, struct.getEip().getVmNicUuid()) .notEq(EipVO_.vipIp, struct.getEip().getVipIp()) .isExists()); + to.setIpVersion(IPv6NetworkUtils.getIpVersion(to.getVipIp())); + to.setGuestIp(IPv6NetworkUtils.getIpByIpVersion(to.getIpVersion(), + struct.getNic().getUsedIps().stream().map(UsedIpInventory::getIp).collect(Collectors.toList()))); cmd.setEip(to); VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); @@ -539,10 +549,13 @@ private List findEipsOnVirtualRouter(VmNicInventory nic, boolean attach) EipTO to = new EipTO(); to.setVipIp(t.get(0, String.class)); to.setGuestIp(t.get(1, String.class)); - to.setPrivateMac( - vr.getVmNics().stream() - .filter(n -> n.getL3NetworkUuid().equals(t.get(2, String.class))) - .findFirst().get().getMac()); + Optional priNic = vr.getVmNics().stream() + .filter(n -> n.getL3NetworkUuid().equals(t.get(2, String.class))) + .findFirst(); + if (!priNic.isPresent()) { + continue; + } + to.setPrivateMac(priNic.get().getMac()); to.setSnatInboundTraffic(EipGlobalConfig.SNAT_INBOUND_TRAFFIC.value(Boolean.class)); Optional pubNic = vr.getVmNics().stream() .filter(n -> n.getL3NetworkUuid().equals(t.get(4, String.class))) @@ -551,6 +564,7 @@ private List findEipsOnVirtualRouter(VmNicInventory nic, boolean attach) continue; } to.setPublicMac(pubNic.get().getMac()); + to.setIpVersion(IPv6NetworkUtils.getIpVersion(to.getVipIp())); ret.add(to); } @@ -559,9 +573,8 @@ private List findEipsOnVirtualRouter(VmNicInventory nic, boolean attach) private List findEipTuplesOnVmNic(VmNicInventory nic) { List eips = SQL.New("select eip.vipIp, eip.guestIp, nic.l3NetworkUuid, nic.mac, vip.l3NetworkUuid, eip.uuid " + - "from EipVO eip, VmNicVO nic, VmInstanceVO vm, VipVO vip " + + "from EipVO eip, VmNicVO nic, VipVO vip " + "where eip.vmNicUuid = nic.uuid " + - "and nic.vmInstanceUuid = vm.uuid " + "and nic.l3NetworkUuid = :l3Uuid " + "and eip.vipUuid = vip.uuid " + "and eip.state = :enabledState", Tuple.class) diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java index cc914ef2aff..6fdb051df5b 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/eip/VirtualRouterSyncEipOnStartFlow.java @@ -7,6 +7,7 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.core.workflow.Flow; @@ -15,9 +16,8 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.message.MessageReply; -import org.zstack.header.vm.VmInstanceConstant; -import org.zstack.header.vm.VmInstanceState; -import org.zstack.header.vm.VmNicInventory; +import org.zstack.header.network.l3.UsedIpVO; +import org.zstack.header.vm.*; import org.zstack.network.service.eip.EipConstant; import org.zstack.network.service.eip.EipGlobalConfig; import org.zstack.network.service.eip.EipVO; @@ -30,13 +30,11 @@ import org.zstack.utils.Utils; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6NetworkUtils; import javax.persistence.Tuple; import javax.persistence.TypedQuery; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.Callable; import java.util.stream.Collectors; @@ -46,7 +44,7 @@ */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VirtualRouterSyncEipOnStartFlow implements Flow { - private static CLogger logger = Utils.getLogger(VirtualRouterSyncEipOnStartFlow.class); + private static final CLogger logger = Utils.getLogger(VirtualRouterSyncEipOnStartFlow.class); @Autowired private DatabaseFacade dbf; @@ -63,7 +61,7 @@ public class VirtualRouterSyncEipOnStartFlow implements Flow { @Transactional(readOnly = true) private List findEipOnThisRouter(VirtualRouterVmInventory vr, List eipUuids) { - String sql = "select vip.ip, nic.l3NetworkUuid, nic.ip, vip.l3NetworkUuid from EipVO eip, VipVO vip, VmNicVO nic " + + String sql = "select vip.ip, nic.l3NetworkUuid, nic.uuid, vip.l3NetworkUuid from EipVO eip, VipVO vip, VmNicVO nic " + " where eip.vipUuid = vip.uuid and vip.serviceProvider in (:providers) "+ " and eip.vmNicUuid = nic.uuid and eip.uuid in (:euuids)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, Tuple.class); @@ -75,7 +73,7 @@ private List findEipOnThisRouter(VirtualRouterVmInventory vr, List() { @Override @@ -96,15 +94,17 @@ public String call(VmNicInventory arg) { return null; } }); - + VmNicVO guestNicVo = Q.New(VmNicVO.class).eq(VmNicVO_.uuid, guestNicUuid).find(); + Set usedIps = guestNicVo.getUsedIps(); DebugUtils.Assert(privMac!=null, String.format("cannot find private nic[l3NetworkUuid:%s] on virtual router[uuid:%s]", l3Uuid, vr.getUuid())); EipTO to = new EipTO(); to.setVipIp(vipIp); to.setPublicMac(publicMac); - to.setGuestIp(guestIp); to.setPrivateMac(privMac); to.setSnatInboundTraffic(EipGlobalConfig.SNAT_INBOUND_TRAFFIC.value(Boolean.class)); + to.setIpVersion(IPv6NetworkUtils.getIpVersion(to.getVipIp())); + to.setGuestIp(IPv6NetworkUtils.getIpByIpVersion(to.getIpVersion(), usedIps.stream().map(UsedIpVO::getIp).collect(Collectors.toList()))); ret.add(to); } @@ -116,13 +116,15 @@ private List findEipOnThisRouter(final VirtualRouterVmInventory vr, Map guestNics = vr.getGuestNics(); List pubL3Uuids = new ArrayList<>(); - pubL3Uuids.add(vr.getPublicNic().getL3NetworkUuid()); + VmNicInventory publicNic = vr.getPublicNic(); pubL3Uuids.addAll(vr.getAdditionalPublicNics().stream().map(VmNicInventory::getL3NetworkUuid).collect(Collectors.toList())); - if (!vr.getPublicNic().getL3NetworkUuid().equals(vr.getManagementNetworkUuid())) { - /* in old code, eip can be configured on management nic */ - pubL3Uuids.add(vr.getManagementNetworkUuid()); + if (publicNic != null) { + pubL3Uuids.add(publicNic.getL3NetworkUuid()); + if (!publicNic.getL3NetworkUuid().equals(vr.getManagementNetworkUuid())) { + /* in old code, eip can be configured on management nic */ + pubL3Uuids.add(vr.getManagementNetworkUuid()); + } } - if (guestNics == null || guestNics.isEmpty()) { return new ArrayList<>(); } @@ -131,8 +133,8 @@ private List findEipOnThisRouter(final VirtualRouterVmInventory vr, Map call() { - String sql = "select eip.uuid from EipVO eip, VipVO vip, VmNicVO nic, VmInstanceVO vm where " + - " vm.uuid = nic.vmInstanceUuid and eip.vipUuid = vip.uuid " + + String sql = "select eip.uuid from EipVO eip, VipVO vip, VmNicVO nic where " + + " eip.vipUuid = vip.uuid " + " and eip.vmNicUuid = nic.uuid and vip.l3NetworkUuid in (:vipL3Uuids) and vip.serviceProvider in (:providers) " + " and nic.l3NetworkUuid in (:guestL3Uuid)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, String.class); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterCleanupHaOnDestroyFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterCleanupHaOnDestroyFlow.java index e67b6b1dc4c..c2bdfb28eb5 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterCleanupHaOnDestroyFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterCleanupHaOnDestroyFlow.java @@ -31,7 +31,7 @@ public class VirtualRouterCleanupHaOnDestroyFlow extends NoRollbackFlow { @Autowired protected VirtualRouterHaBackend haBackend; - private static CLogger logger = Utils.getLogger(VirtualRouterCleanupHaOnDestroyFlow.class); + private static final CLogger logger = Utils.getLogger(VirtualRouterCleanupHaOnDestroyFlow.class); @Override public void run(final FlowTrigger trigger, Map data) { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterConfigProxy.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterConfigProxy.java index 02827b39de1..f7f7448afbd 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterConfigProxy.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterConfigProxy.java @@ -79,20 +79,22 @@ final public List getServiceUuidsByRouterUuid(String vrUuid, String type if (!vrVo.isHaEnabled()) { return getServiceUuidsByNoHaVirtualRouter(vrUuid); } else { + List services = new ArrayList<>(); for (VirtualRouterHaGroupExtensionPoint ext : pluginRgty.getExtensionList(VirtualRouterHaGroupExtensionPoint.class)) { - return ext.getNetworkServicesFromHaVrUuid(type, vrUuid); + services = ext.getNetworkServicesFromHaVrUuid(type, vrUuid); } - return new ArrayList<>(); + return services; } } final public List getServiceUuidsByHaGrupUuid(String haGroupUuid, String type) { + List services = new ArrayList<>(); for (VirtualRouterHaGroupExtensionPoint ext : pluginRgty.getExtensionList(VirtualRouterHaGroupExtensionPoint.class)) { - return ext.getNetworkServicesFromHaGroupUuid(type, haGroupUuid); + services = ext.getNetworkServicesFromHaGroupUuid(type, haGroupUuid); } - return new ArrayList<>(); + return services; } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaSyncConfigToBackendFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaSyncConfigToBackendFlow.java index 854c0fd0491..e33c75a4f82 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaSyncConfigToBackendFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/ha/VirtualRouterHaSyncConfigToBackendFlow.java @@ -3,6 +3,7 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.appliancevm.ApplianceVmConstant; import org.zstack.core.asyncbatch.While; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; @@ -38,18 +39,12 @@ public void run(final FlowTrigger chain, Map data) { return; } - /* only when create a new vpc router, vyos ha config need to be updated to peer router */ - boolean syncPeer = false; - VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); - if (spec != null && spec.getCurrentVmOperation() == VmInstanceConstant.VmOperation.NewCreate) { - syncPeer = true; - } - - final boolean fSyncPeer = syncPeer; + /* sync config to peer all the time to make sure: both vroute has same config */ + final boolean syncPeer = true; List errs = new ArrayList<>(); List exts = pluginRgty.getExtensionList(VirtualRouterHaGroupExtensionPoint.class); new While<>(exts).each((ext, compl) -> { - ext.syncVirtualRouterHaConfigToBackend(vr.getUuid(), fSyncPeer, new Completion(compl) { + ext.syncVirtualRouterHaConfigToBackend(vr.getUuid(), syncPeer, new Completion(compl) { @Override public void success() { compl.done(); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/SharedLoadBalancerFactory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/SharedLoadBalancerFactory.java index e9c42800651..d3cbe63401a 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/SharedLoadBalancerFactory.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/SharedLoadBalancerFactory.java @@ -33,6 +33,7 @@ public LoadBalancerVO persistLoadBalancer(APICreateLoadBalancerMsg msg) { vo.setUuid(msg.getResourceUuid() == null ? Platform.getUuid() : msg.getResourceUuid()); vo.setDescription(msg.getDescription()); vo.setVipUuid(msg.getVipUuid()); + vo.setIpv6VipUuid(msg.getIpv6VipUuid()); vo.setState(LoadBalancerState.Enabled); vo.setType(LoadBalancerType.Shared); vo.setAccountUuid(msg.getSession().getAccountUuid()); @@ -82,14 +83,15 @@ public String getProviderTypeByVmNicUuid(String nicUuid) { } @Override - public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, LoadBalancerServerGroupVO groupVO) { + public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, + LoadBalancerServerGroupVO groupVO, int ipVersion) { String providerType = VyosConstants.VYOS_ROUTER_PROVIDER_TYPE; if (lbVO.getProviderType() != null) { providerType = lbVO.getProviderType(); } LoadBalancerBackend backend = lbMgr.getBackend(providerType); - return backend.getAttachableVmNicsForServerGroup(lbVO, groupVO); + return backend.getAttachableVmNicsForServerGroup(lbVO, groupVO, ipVersion); } @Override diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterCleanupLoadBalancerOnDestroyFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterCleanupLoadBalancerOnDestroyFlow.java index 9f65907275d..1ef8e3143b6 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterCleanupLoadBalancerOnDestroyFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterCleanupLoadBalancerOnDestroyFlow.java @@ -20,7 +20,7 @@ public class VirtualRouterCleanupLoadBalancerOnDestroyFlow extends NoRollbackFlow { @Autowired private DatabaseFacade dbf; - private static CLogger logger = Utils.getLogger(VirtualRouterCleanupLoadBalancerOnDestroyFlow.class); + private static final CLogger logger = Utils.getLogger(VirtualRouterCleanupLoadBalancerOnDestroyFlow.class); @Override public void run(FlowTrigger trigger, Map data) { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java index 94766d6793a..c08db611610 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterLoadBalancerBackend.java @@ -14,8 +14,10 @@ import org.zstack.core.db.SQL; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; +import org.zstack.core.workflow.SimpleFlowChain; import org.zstack.header.acl.AccessControlListEntryVO; import org.zstack.header.acl.AccessControlListEntryVO_; import org.zstack.header.apimediator.ApiMessageInterceptionException; @@ -34,6 +36,7 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.UsedIpInventory; import org.zstack.header.network.l3.UsedIpVO; import org.zstack.header.network.service.*; import org.zstack.header.tag.SystemTagVO; @@ -44,18 +47,23 @@ import org.zstack.network.service.lb.*; import org.zstack.network.service.vip.*; import org.zstack.network.service.virtualrouter.*; +import org.zstack.network.service.virtualrouter.vyos.VyosGlobalConfig; import org.zstack.network.service.virtualrouter.VirtualRouterCommands.AgentCommand; import org.zstack.network.service.virtualrouter.VirtualRouterCommands.AgentResponse; import org.zstack.network.service.virtualrouter.ha.VirtualRouterHaBackend; import org.zstack.network.service.virtualrouter.vip.VipConfigProxy; import org.zstack.network.service.virtualrouter.vip.VirtualRouterVipBackend; -import org.zstack.utils.CollectionUtils; -import org.zstack.utils.DebugUtils; -import org.zstack.utils.Utils; -import org.zstack.utils.VipUseForList; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.resourceconfig.ResourceConfigVO; +import org.zstack.resourceconfig.ResourceConfigVO_; +import org.zstack.utils.*; import org.zstack.utils.function.Function; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.IPv6Constants; +import org.zstack.utils.network.IPv6NetworkUtils; +import org.zstack.utils.network.NetworkUtils; import java.util.*; import java.util.stream.Collectors; @@ -92,6 +100,8 @@ public class VirtualRouterLoadBalancerBackend extends AbstractVirtualRouterBacke private LoadBalancerManager lbMgr; @Autowired private VipConfigProxy vipProxy; + @Autowired + private ResourceConfigFacade rcf; private static final String REFRESH_CERTIFICATE_TASK = "refreshCertificate"; private static final String DELETE_CERTIFICATE_TASK = "deleteCertificate"; @@ -147,14 +157,14 @@ private void validate(APIAddVmNicToLoadBalancerMsg msg) { .listValues()); boolean valid = true; - if (vrUuids.size() == 2 ) { + if (vrUuids.size() == 2) { if (LoadBalancerSystemTags.SEPARATE_VR.hasTag(msg.getLoadBalancerUuid()) && vrUuids.stream().anyMatch(uuid -> VirtualRouterSystemTags.DEDICATED_ROLE_VR.hasTag(uuid))) { logger.debug(String.format( "there are two virtual routers[uuids:%s] on l3 networks[uuids:%s] which vmnics[uuids:%s]" + "attached", vrUuids, l3NetworkUuids, attachedVmNicUuids)); valid = true; - } else if (isVirtualRouterHaPair(new ArrayList<>(vrUuids))){ + } else if (isVirtualRouterHaPair(new ArrayList<>(vrUuids))) { valid = true; } else { valid = false; @@ -168,11 +178,11 @@ private void validate(APIAddVmNicToLoadBalancerMsg msg) { "they are on vrouters[uuids:%s]", msg.getVmNicUuids(), vrUuids)); } - List peerL3NetworkUuids = SQL.New("select peer.l3NetworkUuid " + - "from LoadBalancerVO lb, VipVO vip, VipPeerL3NetworkRefVO peer " + - "where lb.vipUuid = vip.uuid " + - "and vip.uuid = peer.vipUuid " + - "and lb.uuid = :lbUuid") + List peerL3NetworkUuids = SQL.New("select distinct peer.l3NetworkUuid " + + "from LoadBalancerVO lb, VipVO vip, VipPeerL3NetworkRefVO peer " + + "where (lb.vipUuid = vip.uuid or lb.ipv6VipUuid = vip.uuid)" + + "and vip.uuid = peer.vipUuid " + + "and lb.uuid = :lbUuid") .param("lbUuid", msg.getLoadBalancerUuid()) .list(); @@ -218,10 +228,6 @@ private VirtualRouterVmInventory findVirtualRouterVm(String lbUuid) { @Transactional(readOnly = true) private VirtualRouterVmInventory findVirtualRouterVm(String lbUuid, List vmNics) { - if (vmNics.isEmpty()) { - return null; - } - List vrs = getAllVirtualRouters(lbUuid); if (LoadBalancerSystemTags.SEPARATE_VR.hasTag(lbUuid)) { @@ -254,18 +260,24 @@ public static class LbTO { String lbUuid; String listenerUuid; String vip; + String vip6; String publicNic; List nicIps; int instancePort; int loadBalancerPort; String mode; List parameters; - String certificateUuid; + String certificateUuid; String securityPolicyType; List serverGroups; List redirectRules; + String vipL3Uuid; - static class ServerGroup { + boolean enableFullLog; + + boolean enableStatsLog; + + public static class ServerGroup { private String name; private String serverGroupUuid; private List backendServers; @@ -304,7 +316,7 @@ public void setDefault(boolean aDefault) { } } - static class BackendServer { + public static class BackendServer { private String ip; private long weight; @@ -330,7 +342,7 @@ public void setWeight(long weight) { } } - static class RedirectRule { + public static class RedirectRule { private String redirectRuleUuid; private String aclUuid; private String redirectRule; @@ -401,6 +413,14 @@ public void setVip(String vip) { this.vip = vip; } + public String getVip6() { + return vip6; + } + + public void setVip6(String vip6) { + this.vip6 = vip6; + } + public List getNicIps() { return nicIps; } @@ -472,10 +492,37 @@ public List getRedirectRules() { public void setRedirectRules(List redirectRules) { this.redirectRules = redirectRules; } + + public boolean isEnableFullLog() { + return enableFullLog; + } + + public void setEnableFullLog(boolean enableFullLog) { + this.enableFullLog = enableFullLog; + } + + public boolean isEnableStatsLog() { + return enableStatsLog; + } + + public void setEnableStatsLog(boolean enableStatsLog) { + this.enableStatsLog = enableStatsLog; + } + + public String getVipL3Uuid() { + return vipL3Uuid; + } + + public void setVipL3Uuid(String vipL3Uuid) { + this.vipL3Uuid = vipL3Uuid; + } } public static class RefreshLbCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") List lbs; + @GrayVersion(value = "5.0.0") + public Boolean enableHaproxyLog; public List getLbs() { return lbs; @@ -487,6 +534,7 @@ public void setLbs(List lbs) { } public static class RefreshLbLogLevelCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") String level; public String getLevel() { @@ -505,7 +553,9 @@ public static class RefreshLbRsp extends AgentResponse { } public static class CertificateCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") String uuid; + @GrayVersion(value = "5.0.0") String certificate; public String getUuid() { @@ -528,7 +578,21 @@ public void setCertificate(String certificate) { public static class CertificateRsp extends AgentResponse { } + public static class CertificatesCmd extends AgentCommand { + @GrayVersion(value = "5.1.0") + Map certs;//uuid:cert map + + public Map getCerts() { + return certs; + } + + public void setCerts(Map certs) { + this.certs = certs; + } + } + public static class DeleteLbCmd extends AgentCommand { + @GrayVersion(value = "5.0.0") List lbs; public List getLbs() { @@ -548,19 +612,68 @@ public static class DeleteLbRsp extends AgentResponse { public static final String REFRESH_LB_LOG_LEVEL_PATH = "/lb/log/level"; public static final String CREATE_CERTIFICATE_PATH = "/certificate/create"; public static final String DELETE_CERTIFICATE_PATH = "/certificate/delete"; + public static final String CREATE_CERTIFICATES_PATH = "/certificates/create"; + + private String getListenerLogFlagValue(String resourceUuid) { + String value = Q.New(ResourceConfigVO.class).select(ResourceConfigVO_.value) + .eq(ResourceConfigVO_.name, VyosGlobalConfig.ENABLE_LOADBALANCER_FULL_LOG.getName()) + .eq(ResourceConfigVO_.category, VyosGlobalConfig.ENABLE_LOADBALANCER_FULL_LOG.getCategory()) + .eq(ResourceConfigVO_.resourceUuid, resourceUuid) + .findValue(); + return value; + } + + public boolean enableFullLog(LbTO to, VirtualRouterVmInventory vr) { + String enableLbListenerFullLog = getListenerLogFlagValue(to.getListenerUuid()); + if (!StringUtils.isEmpty(enableLbListenerFullLog)) { + return Boolean.TRUE.equals(TypeUtils.stringToValue(enableLbListenerFullLog, boolean.class)); + } + + String enableLbFullLog = getListenerLogFlagValue(to.getLbUuid()); + if (!StringUtils.isEmpty(enableLbFullLog)) { + return Boolean.TRUE.equals(TypeUtils.stringToValue(enableLbFullLog, boolean.class)); + } + + String enableVpcFullLog = getListenerLogFlagValue(vr.getUuid()); + if (!StringUtils.isEmpty(enableVpcFullLog)) { + return Boolean.TRUE.equals(TypeUtils.stringToValue(enableVpcFullLog, boolean.class)); + } else { + return VyosGlobalConfig.ENABLE_LOADBALANCER_FULL_LOG.value(boolean.class); + } + } + + public boolean enableStatsLog(LbTO to) { + ResourceConfig rc = rcf.getResourceConfig(VyosGlobalConfig.ENABLE_LOADBALANCER_STATS_LOG.getIdentity()); + if (rc != null) { + return rc.getResourceConfigValue(to.getLbUuid(), boolean.class); + } else { + return false; + } + } + + public List makeCommonLbTOs(final LoadBalancerStruct struct) { + return makeLbTOs(struct, null); + } private List makeLbTOs(final LoadBalancerStruct struct, VirtualRouterVmInventory vr) { VipInventory vip = struct.getVip(); - Optional publicNic = vr.getVmNics().stream() - .filter(n -> n.getL3NetworkUuid().equals(vip.getL3NetworkUuid())) - .findFirst(); - if (!publicNic.isPresent()) { - return new ArrayList<>(); + VipInventory vip6 = struct.getIpv6Vip(); + VipInventory vipInUsed = vip == null ? vip6 : vip; + VmNicInventory publicNic = null; + + if (vr != null) { + List nics = vr.getVmNics().stream() + .filter(n -> StringUtils.equals(n.getL3NetworkUuid(), vipInUsed.getL3NetworkUuid())) + .collect(Collectors.toList()); + if (!nics.isEmpty()) { + publicNic = nics.get(0); + } } + VmNicInventory finalPublicNic = publicNic; return CollectionUtils.transformToList(struct.getListeners(), new Function() { private List makeAcl(LoadBalancerListenerInventory listenerInv) { - String aclEntry = ""; + String aclEntry = ""; List aclRules = new ArrayList<>(); List refs = listenerInv.getAclRefs(); if (refs.isEmpty()) { @@ -577,7 +690,7 @@ private List makeAcl(LoadBalancerListenerInventory listenerInv) { List aclUuids = aclRefInventories.stream().map(LoadBalancerListenerACLRefInventory::getAclUuid).collect(Collectors.toList()); List entry = Q.New(AccessControlListEntryVO.class).select(AccessControlListEntryVO_.ipEntries) - .in(AccessControlListEntryVO_.aclUuid, aclUuids).listValues(); + .in(AccessControlListEntryVO_.aclUuid, aclUuids).listValues(); if (!entry.isEmpty()) { aclEntry = StringUtils.join(entry.toArray(), ','); } @@ -728,12 +841,12 @@ private List makeRedirectAcl(LoadBalancerListenerInventory li boolean isDefaultPort = false; // http 80;https 443 ArrayList formatRedirectRules = new ArrayList<>(); - if ( (lbTO.getMode().equals(LoadBalancerConstants.LB_PROTOCOL_HTTP) && lbTO.getLoadBalancerPort() == LoadBalancerConstants.PROTOCOL_HTTP_DEFAULT_PORT ) || (lbTO.getMode().equals(LoadBalancerConstants.LB_PROTOCOL_HTTPS) && lbTO.getLoadBalancerPort() == LoadBalancerConstants.PROTOCOL_HTTPS_DEFAULT_PORT) ){ + if ((lbTO.getMode().equals(LoadBalancerConstants.LB_PROTOCOL_HTTP) && lbTO.getLoadBalancerPort() == LoadBalancerConstants.PROTOCOL_HTTP_DEFAULT_PORT) || (lbTO.getMode().equals(LoadBalancerConstants.LB_PROTOCOL_HTTPS) && lbTO.getLoadBalancerPort() == LoadBalancerConstants.PROTOCOL_HTTPS_DEFAULT_PORT)) { formatRedirectRules.addAll(redirectRules); isDefaultPort = true; } - for(LbTO.RedirectRule rule:redirectRules){ + for (LbTO.RedirectRule rule : redirectRules) { LbTO.RedirectRule formatRule = new LbTO.RedirectRule(); formatRule.setRedirectRule(rule.getRedirectRule()); formatRule.setRedirectRuleUuid(rule.getRedirectRuleUuid()); @@ -741,12 +854,12 @@ private List makeRedirectAcl(LoadBalancerListenerInventory li formatRule.setServerGroupUuid(rule.getServerGroupUuid()); String matchMethod = Q.New(AccessControlListEntryVO.class).select(AccessControlListEntryVO_.matchMethod).eq(AccessControlListEntryVO_.uuid, rule.getRedirectRuleUuid()).findValue(); - boolean isSkipInsertPort = ( LoadBalancerConstants.MatchMethod.Domain.toString().equals(matchMethod) || LoadBalancerConstants.MatchMethod.Url.toString().equals(matchMethod) ); - if ( isSkipInsertPort && isDefaultPort ){ + boolean isSkipInsertPort = (LoadBalancerConstants.MatchMethod.Domain.toString().equals(matchMethod) || LoadBalancerConstants.MatchMethod.Url.toString().equals(matchMethod)); + if (isSkipInsertPort && isDefaultPort) { continue; - } else if( isSkipInsertPort){ + } else if (isSkipInsertPort) { formatRedirectRules.add(formatRule); - } else{ + } else { insertPortToRedirectRule(formatRule, lbTO); formatRedirectRules.add(formatRule); } @@ -754,13 +867,13 @@ private List makeRedirectAcl(LoadBalancerListenerInventory li return formatRedirectRules; } - private void insertPortToRedirectRule(LbTO.RedirectRule redirectRule,LbTO lbTO){ + private void insertPortToRedirectRule(LbTO.RedirectRule redirectRule, LbTO lbTO) { //add lbport after domain name StringBuffer rule = new StringBuffer(redirectRule.getRedirectRule()); String insertRule = ":" + lbTO.getLoadBalancerPort(); int index = rule.indexOf("/"); if (index != -1) { - rule.insert(index,insertRule); + rule.insert(index, insertRule); } redirectRule.setRedirectRule(rule.toString()); } @@ -773,7 +886,12 @@ public LbTO call(LoadBalancerListenerInventory l) { to.setLbUuid(l.getLoadBalancerUuid()); to.setListenerUuid(l.getUuid()); to.setMode(l.getProtocol()); - to.setVip(vip.getIp()); + if (vip != null) { + to.setVip(vip.getIp()); + } + if (vip6 != null) { + to.setVip6(vip6.getIp()); + } to.setSecurityPolicyType(l.getSecurityPolicyType()); if (l.getCertificateRefs() != null && !l.getCertificateRefs().isEmpty()) { to.setCertificateUuid(l.getCertificateRefs().get(0).getCertificateUuid()); @@ -790,6 +908,8 @@ public LbTO call(LoadBalancerListenerInventory l) { serverGroup.setServerGroupUuid(groupInv.getUuid()); List backendServers = new ArrayList<>(); serverGroup.setBackendServers(backendServers); + + //sort vmnic by the add to backend time List nicRefInventories = Optional.ofNullable(groupInv.getVmNicRefs()).orElse(new ArrayList<>()).stream() .sorted(new Comparator() { @Override @@ -804,6 +924,7 @@ public int compare(LoadBalancerServerGroupServerIpInventory r1, LoadBalancerServ return (int) (r1.getId() - r2.getId()); } }).collect(Collectors.toList()); + for (LoadBalancerServerGroupVmNicRefInventory nicRef : nicRefInventories) { if (nicRef.getStatus().equals(LoadBalancerVmNicStatus.Inactive.toString())) { continue; @@ -813,12 +934,30 @@ public int compare(LoadBalancerServerGroupServerIpInventory r1, LoadBalancerServ if (nic == null) { throw new CloudRuntimeException(String.format("cannot find nic[uuid:%s]", nicRef.getVmNicUuid())); } - if(nic.getIp() == null || nic.getIp().isEmpty()){ + if (CollectionUtils.isEmpty(nic.getUsedIps())) { continue; } - ips.add(nic.getIp()); - params.add(String.format("balancerWeight::%s::%s", nic.getIp(), nicRef.getWeight())); - backendServers.add(new LbTO.BackendServer(nic.getIp(), nicRef.getWeight())); + + //todo: order by ipversion: ipv4 priority is much important than ipv6? + for (UsedIpInventory usedIpInventory : nic.getUsedIps()) { + boolean addIp = false; + if (nicRef.getIpVersion() == IPv6Constants.DUAL_STACK) { + addIp = true; + } else if (nicRef.getIpVersion() == IPv6Constants.IPv4) { + if (NetworkUtils.isIpv4Address(usedIpInventory.getIp())) { + addIp = true; + } + } else if (nicRef.getIpVersion() == IPv6Constants.IPv6) { + if (IPv6NetworkUtils.isIpv6Address(usedIpInventory.getIp())) { + addIp = true; + } + } + if (addIp) { + ips.add(usedIpInventory.getIp()); + params.add(String.format("balancerWeight::%s::%s", usedIpInventory.getIp(), nicRef.getWeight())); + backendServers.add(new LbTO.BackendServer(usedIpInventory.getIp(), nicRef.getWeight())); + } + } } for (LoadBalancerServerGroupServerIpInventory ipRef : ipRefInventories) { @@ -826,11 +965,11 @@ public int compare(LoadBalancerServerGroupServerIpInventory r1, LoadBalancerServ continue; } - if(ipRef.getIpAddress() == null || ipRef.getIpAddress().isEmpty()){ + if (ipRef.getIpAddress() == null || ipRef.getIpAddress().isEmpty()) { continue; } ips.add(ipRef.getIpAddress()); - params.add(String.format("balancerWeight::%s::%s",ipRef.getIpAddress(), ipRef.getWeight())); + params.add(String.format("balancerWeight::%s::%s", ipRef.getIpAddress(), ipRef.getWeight())); backendServers.add(new LbTO.BackendServer(ipRef.getIpAddress(), ipRef.getWeight())); } @@ -840,16 +979,18 @@ public int compare(LoadBalancerServerGroupServerIpInventory r1, LoadBalancerServ } } to.setNicIps(ips.stream().sorted().collect(Collectors.toList())); - to.setPublicNic(publicNic.get().getMac()); + if (finalPublicNic != null) { + to.setPublicNic(finalPublicNic.getMac()); + } to.setServerGroups(serverGroups); params.addAll(CollectionUtils.transformToList(struct.getTags().get(l.getUuid()), new Function() { // vnicUuid::weight @Override public String call(String arg) { - if(LoadBalancerSystemTags.BALANCER_WEIGHT.isMatch(arg)) { + if (LoadBalancerSystemTags.BALANCER_WEIGHT.isMatch(arg)) { /* 4.0 lb server ip weight configuration from nicRefVO and serverIpVO,not systemTag - */ + Sy */ return null; } return arg; @@ -858,12 +999,16 @@ public String call(String arg) { to.setRedirectRules(makeRedirectAcl(l, to)); params.addAll(makeAcl(l)); to.setParameters(params); + if (vr != null) { + to.setEnableFullLog(enableFullLog(to, vr)); + to.setEnableStatsLog(enableStatsLog(to)); + } return to; } }); } - private List getCertificates(List structs) { + public List getCertificateUuids(List structs) { List certificateUuids = new ArrayList<>(); for (LoadBalancerStruct struct : structs) { for (LoadBalancerListenerInventory listenerInv : struct.getListeners()) { @@ -895,8 +1040,19 @@ private List getCertificates(List structs) { return certificateUuids; } - private void refreshCertificate(VirtualRouterVmInventory vr, boolean checkVrState, List struct, final Completion completion){ - List certificateUuids = getCertificates(struct); + public HashMap getListenerCertificates(LoadBalancerStruct struct) { + HashMap certs = new HashMap<>(); + List certificateUuids = getCertificateUuids(Collections.singletonList(struct)); + for (String uuid : certificateUuids) { + CertificateVO vo = dbf.findByUuid(uuid, CertificateVO.class); + certs.put(uuid, vo.getCertificate()); + } + + return certs; + } + + private void refreshCertificate(VirtualRouterVmInventory vr, boolean checkVrState, List struct, final Completion completion) { + List certificateUuids = getCertificateUuids(struct); List errors = new ArrayList<>(); new While<>(certificateUuids).each((uuid, wcmpl) -> { @@ -941,8 +1097,8 @@ public void done(ErrorCodeList errorCodeList) { }); } - private void rollbackCertificate(VirtualRouterVmInventory vr, boolean checkVrState, List struct, final NoErrorCompletion completion){ - List certificateUuids = getCertificates(struct); + private void rollbackCertificate(VirtualRouterVmInventory vr, boolean checkVrState, List struct, final NoErrorCompletion completion) { + List certificateUuids = getCertificateUuids(struct); new While<>(certificateUuids).each((uuid, wcmpl) -> { VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); @@ -981,6 +1137,7 @@ private void refreshLbToVirtualRouter(VirtualRouterVmInventory vr, LoadBalancerS completion.success(); return; } + cmd.enableHaproxyLog = rcf.getResourceConfigValue(VyosGlobalConfig.ENABLE_HAPROXY_LOG, vr.getUuid(), Boolean.class); msg.setCommand(cmd); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); @@ -1010,6 +1167,7 @@ public void refresh(VirtualRouterVmInventory vr, LoadBalancerStruct struct, fina public void setup() { flow(new Flow() { String __name__ = "refresh-lb-ceriticae-to-virtualRouter"; + @Override public void run(FlowTrigger trigger, Map data) { refreshCertificate(vr, true, Collections.singletonList(struct), new Completion(trigger) { @@ -1102,19 +1260,137 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } + public void refreshCertsAndListeners(VirtualRouterVmInventory vr, + Map certs, + List listeners, + boolean statusCheck, Completion completion) { + FlowChain chain = new SimpleFlowChain(); + chain.setName("refresh-lb-certs-listeners"); + chain.then(new NoRollbackFlow() { + String __name__ = "refresh-lb-certs"; + + @Override + public void run(FlowTrigger trigger, Map data) { + if (certs.isEmpty()) { + trigger.next(); + return; + } + + VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); + msg.setVmInstanceUuid(vr.getUuid()); + msg.setPath(CREATE_CERTIFICATES_PATH); + msg.setCheckStatus(statusCheck); + + CertificatesCmd cmd = new CertificatesCmd(); + cmd.setCerts(certs); + + msg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); + bus.send(msg, new CloudBusCallBack(trigger) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + CertificateRsp rsp = ((VirtualRouterAsyncHttpCallReply) reply).toResponse(CertificateRsp.class); + if (rsp.isSuccess()) { + trigger.next(); + } else { + trigger.fail(operr("refresh load balancer certificate, because:%s", rsp.getError())); + } + } else { + trigger.fail(reply.getError()); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "refresh-lb-listeners"; + + @Override + public void run(FlowTrigger trigger, Map data) { + RefreshLbCmd cmd = new RefreshLbCmd(); + VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); + msg.setVmInstanceUuid(vr.getUuid()); + msg.setPath(REFRESH_LB_PATH); + msg.setCheckStatus(statusCheck); + for (VirtualRouterLoadBalancerBackend.LbTO to: listeners) { + to.setEnableFullLog(enableFullLog(to, vr)); + to.setEnableStatsLog(enableStatsLog(to)); + } + cmd.setLbs(listeners); + cmd.enableHaproxyLog = rcf.getResourceConfigValue(VyosGlobalConfig.ENABLE_HAPROXY_LOG, vr.getUuid(), Boolean.class); + + msg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + RefreshLbRsp rsp = ((VirtualRouterAsyncHttpCallReply) reply).toResponse(RefreshLbRsp.class); + if (rsp.isSuccess()) { + trigger.next(); + } else { + trigger.fail(operr("refresh load balancer listener, because:%s", rsp.getError())); + } + } else { + trigger.fail(reply.getError()); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = "after-refresh-lb-listeners"; + + @Override + public void run(FlowTrigger trigger, Map data) { + new While<>(pluginRgty.getExtensionList(VirtualRouterLoadBalancerExtensionPoint.class)).each((ext, whileCompletion) -> { + ext.afterRefreshLoadBalancerListener(vr.getUuid(), new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + logger.warn(String.format("after refresh load balancer listener failed, because:%s", errorCodeList.getCauses().get(0))); + } + trigger.next(); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + private void stopVip(final LoadBalancerStruct struct, final List nics, final Completion completion) { LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(struct.getLb().getType()); - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - Set guestL3NetworkUuids = nics.stream() - .map(VmNicInventory::getL3NetworkUuid) - .collect(Collectors.toSet()); + .map(VmNicInventory::getL3NetworkUuid) + .collect(Collectors.toSet()); /*remove the l3networks still attached*/ Set vnicUuidsAttached = new HashSet<>(); for (LoadBalancerListenerInventory listener : struct.getListeners()) { + if (struct.getListenerServerGroupMap().get(listener.getUuid()) == null) { + continue; + } + for (LoadBalancerServerGroupInventory group : struct.getListenerServerGroupMap().get(listener.getUuid())) { vnicUuidsAttached.addAll(group.getVmNicRefs().stream().map(LoadBalancerServerGroupVmNicRefInventory::getVmNicUuid).collect(Collectors.toList())); } @@ -1130,43 +1406,153 @@ private void stopVip(final LoadBalancerStruct struct, final List completion.success(); return; } - vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); - Vip v = new Vip(struct.getLb().getVipUuid()); - v.setStruct(vipStruct); - v.stop(completion); + + new While<>(struct.getLb().getVipUuids()).step((vipUuid, whileCompletion) -> { + ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); + vipStruct.setUseFor(f.getNetworkServiceType()); + vipStruct.setServiceUuid(struct.getLb().getUuid()); + + vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); + vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); + Vip v = new Vip(vipUuid); + v.setStruct(vipStruct); + v.stop(new Completion(whileCompletion) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.done(); + } + }); + }, 2).run(new WhileDoneCompletion(completion) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList.getCauses().get(0)); + return; + } + completion.success(); + } + }); } - private void acquireVip(final VirtualRouterVmInventory vr, final LoadBalancerStruct struct, final List nics, final Completion completion) { + private void acquireVip(final VirtualRouterVmInventory vr, final LoadBalancerStruct struct, final List nics, final List acquiredVipUuids, final Completion completion) { + acquireSpecifyedVip(vr, struct, struct.getLb().getVipUuids(), nics, acquiredVipUuids, completion); + } + + private void acquireSpecifyedVip(final VirtualRouterVmInventory vr, final LoadBalancerStruct struct, final List specifyedVip , final List nics, final List acquiredVipUuids, final Completion completion) { + List vipUuidsAcquireSuccess = Collections.synchronizedList(new ArrayList<>()); + LoadBalancerVO loadBalancerVO = dbf.findByUuid(struct.getLb().getUuid(), LoadBalancerVO.class); LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(loadBalancerVO.getType().toString()); - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - Set guestL3NetworkUuids = nics.stream() - .map(VmNicInventory::getL3NetworkUuid) - .collect(Collectors.toSet()); + new While<>(specifyedVip).step((vipUuid, whileCompletion) -> { + if (StringUtils.isEmpty(vipUuid)) { + whileCompletion.done(); + return; + } + + ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); + vipStruct.setUseFor(f.getNetworkServiceType()); + vipStruct.setServiceUuid(struct.getLb().getUuid()); + Set guestL3NetworkUuids = nics.stream() + .map(VmNicInventory::getL3NetworkUuid) + .collect(Collectors.toSet()); - vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); - Vip v = new Vip(struct.getLb().getVipUuid()); - v.setStruct(vipStruct); - v.acquire(new Completion(completion) { + if (!guestL3NetworkUuids.isEmpty()) { + vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); + } + vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); + Vip v = new Vip(vipUuid); + v.setStruct(vipStruct); + + v.acquire(new Completion(whileCompletion) { + @Override + public void success() { + vipUuidsAcquireSuccess.add(vipUuid); + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + whileCompletion.addError(errorCode); + whileCompletion.allDone(); + } + }); + }, 2).run(new WhileDoneCompletion(completion) { @Override - public void success() { + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + if (!vipUuidsAcquireSuccess.isEmpty()) { + releaseVipForLoadBalancer(vr, struct, nics, vipUuidsAcquireSuccess, new Completion(completion) { + @Override + public void success() { + completion.fail(errorCodeList.getCauses().get(0)); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCodeList.getCauses().get(0)); + } + }); + return; + } + completion.fail(errorCodeList.getCauses().get(0)); + return; + } + acquiredVipUuids.addAll(vipUuidsAcquireSuccess); completion.success(); } + }); + } + + private void releaseVipForLoadBalancer(final VirtualRouterVmInventory vr, final LoadBalancerStruct struct, final List nics, List vipUuids, final Completion completion) { + LoadBalancerVO loadBalancerVO = dbf.findByUuid(struct.getLb().getUuid(), LoadBalancerVO.class); + LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(loadBalancerVO.getType().toString()); + // release acquired vip + new While<>(vipUuids).step((vipUuid, whileCompletion) -> { + ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); + vipStruct.setUseFor(f.getNetworkServiceType()); + vipStruct.setServiceUuid(struct.getLb().getUuid()); + Set guestL3NetworkUuids = nics.stream() + .map(VmNicInventory::getL3NetworkUuid) + .collect(Collectors.toSet()); + + vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); + vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); + + Vip v = new Vip(vipUuid); + v.setStruct(vipStruct); + v.release(new Completion(completion) { + @Override + public void success() { + whileCompletion.done(); + } + @Override + public void fail(ErrorCode errorCode) { + //TODO add GC + logger.warn(errorCode.toString()); + whileCompletion.done(); + } + }); + }, 2).run(new WhileDoneCompletion(completion) { @Override - public void fail(ErrorCode errorCode) { - completion.fail(errorCode); + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + completion.fail(errorCodeList.getCauses().get(0)); + return; + } + completion.success(); } }); } private void startVrIfNeededAndRefresh(final VirtualRouterVmInventory vr, final LoadBalancerStruct struct, List nics, final Completion completion) { - acquireVip(vr, struct, nics, new Completion(completion) { + acquireVip(vr, struct, nics, new ArrayList(), new Completion(completion) { @Override public void success() { startVrIfNeededAndRefresh(vr, struct, completion); @@ -1185,8 +1571,6 @@ private void startVrIfNeededAndRefresh(final VirtualRouterVmInventory vr, final return; } - final VipInventory vip = VipInventory.valueOf(dbf.findByUuid(struct.getLb().getVipUuid(), VipVO.class)); - LoadBalancerVO loadBalancerVO = dbf.findByUuid(struct.getLb().getUuid(), LoadBalancerVO.class); LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(loadBalancerVO.getType().toString()); @@ -1218,22 +1602,13 @@ public void run(MessageReply reply) { flow(new Flow() { String __name__ = "create-vip-on-vr"; - boolean success = false; + List vipUuidsAcquireSuccess = new ArrayList<>(); @Override public void run(final FlowTrigger trigger, Map data) { - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vr.getGuestL3Networks())); - vipStruct.setPeerL3NetworkUuids(vr.getGuestL3Networks()); - - Vip v = new Vip(struct.getLb().getVipUuid()); - v.setStruct(vipStruct); - v.acquire(new Completion(trigger) { + acquireVip(vr, struct, vr.getGuestNics(), vipUuidsAcquireSuccess, new Completion(trigger) { @Override public void success() { - success = true; trigger.next(); } @@ -1246,19 +1621,12 @@ public void fail(ErrorCode errorCode) { @Override public void rollback(final FlowRollback trigger, Map data) { - if (!success) { + if (vipUuidsAcquireSuccess.isEmpty()) { trigger.rollback(); return; } - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - vipStruct.setPeerL3NetworkUuids(vr.getGuestL3Networks()); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vr.getGuestL3Networks())); - Vip v = new Vip(vip.getUuid()); - v.setStruct(vipStruct); - v.stop(new Completion(trigger) { + releaseVipForLoadBalancer(vr, struct, vr.getGuestNics(), vipUuidsAcquireSuccess, new Completion(trigger) { @Override public void success() { trigger.rollback(); @@ -1327,12 +1695,23 @@ public void addVmNics(final LoadBalancerStruct struct, List nics nicL3 = L3NetworkInventory.valueOf(dbf.findByUuid(nics.get(0).getL3NetworkUuid(), L3NetworkVO.class)); } final L3NetworkInventory l3 = nicL3; - final VipInventory vip = VipInventory.valueOf(dbf.findByUuid(struct.getLb().getVipUuid(), VipVO.class)); - List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, struct.getLb().getVipUuid()).listValues(); - VipUseForList useForList = new VipUseForList(useFor); - if (!useForList.isIncluded(LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING)) { - logger.warn(String.format("the vip[uuid:%s, name:%s, ip:%s, useFor: %s] is not for load balancer", vip.getUuid(), - vip.getName(), vip.getIp(), vip.getUseFor())); + String vipUuidTemp = StringUtils.isEmpty(struct.getLb().getVipUuid()) ? struct.getLb().getIpv6VipUuid() : struct.getLb().getVipUuid(); + final VipInventory vip = VipInventory.valueOf(dbf.findByUuid(vipUuidTemp, VipVO.class)); + if (!StringUtils.isEmpty(struct.getLb().getVipUuid())) { + List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, struct.getLb().getVipUuid()).listValues(); + VipUseForList useForList = new VipUseForList(useFor); + if (!useForList.isIncluded(LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING)) { + logger.warn(String.format("the vip[uuid:%s, name:%s, ip:%s, useFor: %s] is not for load balancer", vip.getUuid(), + vip.getName(), vip.getIp(), vip.getUseFor())); + } + } + if (!StringUtils.isEmpty(struct.getLb().getIpv6VipUuid())) { + List useFor = Q.New(VipNetworkServicesRefVO.class).select(VipNetworkServicesRefVO_.serviceType).eq(VipNetworkServicesRefVO_.vipUuid, struct.getLb().getIpv6VipUuid()).listValues(); + VipUseForList useForList = new VipUseForList(useFor); + if (!useForList.isIncluded(LoadBalancerConstants.LB_NETWORK_SERVICE_TYPE_STRING)) { + logger.warn(String.format("the vip[uuid:%s, name:%s, ip:%s, useFor: %s] is not for load balancer", vip.getUuid(), + vip.getName(), vip.getIp(), vip.getUseFor())); + } } final boolean separateVr = LoadBalancerSystemTags.SEPARATE_VR.hasTag(struct.getLb().getUuid()); @@ -1363,8 +1742,8 @@ public void run(FlowTrigger trigger, Map data) { vipStruct.setUseFor(f.getNetworkServiceType()); vipStruct.setServiceUuid(struct.getLb().getUuid()); Set guestL3NetworkUuids = nics.stream() - .map(VmNicInventory::getL3NetworkUuid) - .collect(Collectors.toSet()); + .map(VmNicInventory::getL3NetworkUuid) + .collect(Collectors.toSet()); vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); @@ -1387,8 +1766,8 @@ public void fail(ErrorCode errorCode) { public void rollback(FlowRollback trigger, Map data) { List attachedVmNicUuids = struct.getActiveVmNics(); Set guestL3NetworkUuids = nics.stream() - .map(VmNicInventory::getL3NetworkUuid) - .collect(Collectors.toSet()); + .map(VmNicInventory::getL3NetworkUuid) + .collect(Collectors.toSet()); guestL3NetworkUuids.removeAll(attachedVmNicUuids); if (guestL3NetworkUuids.isEmpty()) { logger.debug(String.format("there are vmnics[uuids:%s] attached on loadbalancer[uuid:%s], " + @@ -1449,6 +1828,7 @@ public void fail(ErrorCode errorCode) { } }); } + @Override public void rollback(final FlowRollback trigger, Map data) { if (vr == null) { @@ -1543,7 +1923,7 @@ public void fail(ErrorCode errorCode) { flow(new Flow() { String __name__ = "acquire-vip"; boolean success = false; - + List vipAcquired = new ArrayList<>(); @Override public boolean skip(Map data) { return nics.isEmpty(); @@ -1551,18 +1931,7 @@ public boolean skip(Map data) { @Override public void run(final FlowTrigger trigger, Map data) { - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - Set guestL3NetworkUuids = nics.stream() - .map(VmNicInventory::getL3NetworkUuid) - .collect(Collectors.toSet()); - vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); - - Vip v = new Vip(vip.getUuid()); - v.setStruct(vipStruct); - v.acquire(new Completion(trigger) { + acquireVip(vr, struct, nics, vipAcquired, new Completion(trigger) { @Override public void success() { success = true; @@ -1585,8 +1954,8 @@ public void rollback(final FlowRollback trigger, Map data) { List attachedVmNicUuids = struct.getActiveVmNics(); Set guestL3NetworkUuids = nics.stream() - .map(VmNicInventory::getL3NetworkUuid) - .collect(Collectors.toSet()); + .map(VmNicInventory::getL3NetworkUuid) + .collect(Collectors.toSet()); guestL3NetworkUuids.removeAll(attachedVmNicUuids); if (guestL3NetworkUuids.isEmpty()) { logger.debug(String.format("there are vmnics[uuids:%s] attached on loadbalancer[uuid:%s], " + @@ -1594,29 +1963,37 @@ public void rollback(final FlowRollback trigger, Map data) { trigger.rollback(); return; } - - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); - Vip v = new Vip(vip.getUuid()); - v.setStruct(vipStruct); - v.stop(new Completion(trigger) { - @Override - public void success() { - trigger.rollback(); - } + new While<>(vipAcquired).step((vipUuid, whileCompletion) -> { + ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); + vipStruct.setUseFor(f.getNetworkServiceType()); + vipStruct.setServiceUuid(struct.getLb().getUuid()); + vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); + vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); + Vip v = new Vip(vip.getUuid()); + v.setStruct(vipStruct); + v.stop(new Completion(trigger) { + @Override + public void success() { + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.warn(String.format("failed to release vip[uuid:%s, ip:%s] on vr[uuid:%s], continue to rollback", + vip.getUuid(), vip.getIp(), vr.getUuid())); + whileCompletion.done(); + } + }); + }, 2).run(new WhileDoneCompletion(trigger) { @Override - public void fail(ErrorCode errorCode) { - logger.warn(String.format("failed to release vip[uuid:%s, ip:%s] on vr[uuid:%s], continue to rollback", - vip.getUuid(), vip.getIp(), vr.getUuid())); + public void done(ErrorCodeList errorCodeList) { trigger.rollback(); } }); + } }); } @@ -1673,7 +2050,7 @@ public void removeVmNics(LoadBalancerStruct struct, List nics, C VirtualRouterVmInventory vr = findVirtualRouterVm(struct.getLb().getUuid()); final boolean separateVr = LoadBalancerSystemTags.SEPARATE_VR.hasTag(struct.getLb().getUuid()); - if ( separateVr ) { + if (separateVr) { logger.error("not support the separate vrouter currently."); // no support the case completion.success(); @@ -1785,7 +2162,7 @@ public void removeListener(final LoadBalancerStruct struct, LoadBalancerListener } final boolean separateVr = LoadBalancerSystemTags.SEPARATE_VR.hasTag(struct.getLb().getUuid()); - if ( separateVr ) { + if (separateVr) { logger.error("not support the separate vrouter currently."); completion.success(); return; @@ -1827,35 +2204,14 @@ public void fail(ErrorCode errorCode) { @Override public void run(FlowTrigger trigger, Map data) { - ModifyVipAttributesStruct vipStruct = new ModifyVipAttributesStruct(); - vipStruct.setUseFor(f.getNetworkServiceType()); - vipStruct.setServiceUuid(struct.getLb().getUuid()); - List nicUuids = struct.getAllVmNicsOfListener(listener); if (nicUuids.isEmpty()) { trigger.next(); return; } - List guestL3NetworkUuids = Q.New(VmNicVO.class).select(VmNicVO_.l3NetworkUuid).in(VmNicVO_.uuid, nicUuids).listValues(); - - /*remove the l3networks still attached*/ - List vnicUuidsAttached = struct.getAllVmNics(); - if (!vnicUuidsAttached.isEmpty()) { - List l3Uuids = Q.New(VmNicVO.class).select(VmNicVO_.l3NetworkUuid).in(VmNicVO_.uuid, vnicUuidsAttached).listValues(); - if (l3Uuids != null && !l3Uuids.isEmpty()) { - guestL3NetworkUuids.removeAll(l3Uuids); - } - } - if (guestL3NetworkUuids.isEmpty()) { - trigger.next(); - return; - } + List nicVOs = Q.New(VmNicVO.class).in(VmNicVO_.uuid, nicUuids).list(); - vipStruct.setPeerL3NetworkUuids(new ArrayList<>(guestL3NetworkUuids)); - vipStruct.setServiceProvider(getLoadLancerServiceProvider(vipStruct.getPeerL3NetworkUuids())); - Vip v = new Vip(struct.getLb().getVipUuid()); - v.setStruct(vipStruct); - v.stop(new Completion(trigger) { + stopVip(struct, VmNicInventory.valueOf(nicVOs), new Completion(trigger) { @Override public void success() { trigger.next(); @@ -1914,13 +2270,13 @@ public void run(final FlowTrigger trigger, Map data) { msg.setVmInstanceUuid(vr.getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); bus.send(msg, new CloudBusCallBack(trigger) { - @Override + @Override public void run(MessageReply reply) { if (reply.isSuccess()) { trigger.next(); } else { trigger.fail(reply.getError()); - } + } } }); } else if (roles.size() > 1 && roles.contains(VirtualRouterSystemTags.VR_LB_ROLE.getTagFormat())) { @@ -1991,6 +2347,7 @@ public void syncOnStart(VirtualRouterVmInventory vr, boolean checkStatus, List getAllVirtualRouters(String lbUuid) { return Q.New(VirtualRouterVmVO.class).in(VirtualRouterVmVO_.uuid, vrUuids).list(); } + public void destroyLoadBalancer(VirtualRouterVmInventory vr, List listeners, Completion completion) { + DeleteLbCmd cmd = new DeleteLbCmd(); + cmd.setLbs(listeners); + if (cmd.lbs.isEmpty()) { + completion.success(); + return; + } + + VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); + msg.setVmInstanceUuid(vr.getUuid()); + msg.setPath(DELETE_LB_PATH); + msg.setCommand(cmd); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (reply.isSuccess()) { + DeleteLbRsp rsp = ((VirtualRouterAsyncHttpCallReply) reply).toResponse(DeleteLbRsp.class); + if (rsp.isSuccess()) { + completion.success(); + } else { + completion.fail(operr("operation error, because:%s", rsp.getError())); + } + } else { + completion.fail(reply.getError()); + } + } + }); + } + public void destroyLoadBalancerOnVirtualRouter(VirtualRouterVmInventory vr, LoadBalancerStruct struct, Completion completion) { DeleteLbCmd cmd = new DeleteLbCmd(); cmd.setLbs(makeLbTOs(struct, vr)); @@ -2105,7 +2493,7 @@ public void destroyLoadBalancerOnVirtualRouter(VirtualRouterVmInventory vr, Load @Override public void run(MessageReply reply) { if (reply.isSuccess()) { - DeleteLbRsp rsp = ((VirtualRouterAsyncHttpCallReply)reply).toResponse(DeleteLbRsp.class); + DeleteLbRsp rsp = ((VirtualRouterAsyncHttpCallReply) reply).toResponse(DeleteLbRsp.class); if (rsp.isSuccess()) { completion.success(); } else { @@ -2119,11 +2507,12 @@ public void run(MessageReply reply) { } private boolean isVirtualRouterHaPair(List vrUuids) { + boolean isVirtualRouterHaPair = false; for (VirtualRouterHaGroupExtensionPoint ext : pluginRgty.getExtensionList(VirtualRouterHaGroupExtensionPoint.class)) { - return ext.isVirtualRouterInSameHaPair(vrUuids); + isVirtualRouterHaPair = ext.isVirtualRouterInSameHaPair(vrUuids); } - return false; + return isVirtualRouterHaPair; } private void refreshCertificateOnHaRouter(String vrUuid, List structs, Completion completion) { @@ -2170,13 +2559,13 @@ private List getLoadBalancersByL3Networks(String l3Uuid, boo List listenerVOS = SQL.New(sql, LoadBalancerListenerVO.class).param("l3Uuid", l3Uuid) .param("lbType", LoadBalancerType.Shared) .param("status", asList(LoadBalancerVmNicStatus.Active, LoadBalancerVmNicStatus.Pending)).list(); - if (listenerVOS == null || listenerVOS.isEmpty()){ + if (listenerVOS == null || listenerVOS.isEmpty()) { return ret; } HashMap> listenerMap = new HashMap<>(); for (LoadBalancerListenerVO vo : listenerVOS) { - listenerMap.computeIfAbsent(vo.getLoadBalancerUuid(), k-> new ArrayList<>()).add(vo); + listenerMap.computeIfAbsent(vo.getLoadBalancerUuid(), k -> new ArrayList<>()).add(vo); } for (Map.Entry> e : listenerMap.entrySet()) { @@ -2220,7 +2609,7 @@ private List getLoadBalancersByL3Networks(String l3Uuid, boo Map> systemTags = new HashMap<>(); for (LoadBalancerListenerVO l : listenerVOS) { - SimpleQuery q = dbf.createQuery(SystemTagVO.class); + SimpleQuery q = dbf.createQuery(SystemTagVO.class); q.select(SystemTagVO_.tag); q.add(SystemTagVO_.resourceUuid, Op.EQ, l.getUuid()); q.add(SystemTagVO_.resourceType, Op.EQ, LoadBalancerListenerVO.class.getSimpleName()); @@ -2289,11 +2678,11 @@ public void afterAttachNicRollback(VmNicInventory nic, NoErrorCompletion complet @Override public void beforeDetachNic(VmNicInventory nic, Completion completion) { - /* ZSTAC-24726 for lb, it's not necessary to implement this interface - * delete network/detach user vm nic, under these cases, the removeVmNics extend point will be triggered - * that will remove the lb reference with nic first, and refresh lb to agent. - * */ - completion.success(); + /* ZSTAC-24726 for lb, it's not necessary to implement this interface + * delete network/detach user vm nic, under these cases, the removeVmNics extend point will be triggered + * that will remove the lb reference with nic first, and refresh lb to agent. + * */ + completion.success(); } @Override @@ -2390,7 +2779,8 @@ protected List getAttachableL3UuidsForVirtualRouter(VirtualRouterVmInven } @Override - public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, LoadBalancerServerGroupVO groupVO) { + public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, + LoadBalancerServerGroupVO groupVO, int ipVersion) { List attachedL3Uuids = new ArrayList<>(); if (groupVO != null) { attachedL3Uuids = LoadBalancerServerGroupInventory.valueOf(groupVO).getAttachedL3Uuids(); @@ -2415,7 +2805,7 @@ public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, Load if (vr != null) { l3NetworkUuids = getAttachableL3UuidsForVirtualRouter(vr, LoadBalancerInventory.valueOf(lbVO)); } else { - VipVO vipVO = dbf.findByUuid(lbVO.getVipUuid(), VipVO.class); + VipVO vipVO = dbf.findByUuid(lbVO.getVipUuids().get(0), VipVO.class); if (vipVO.isSystem()) { vrUuids = vipProxy.getVrUuidsByNetworkService(VipVO.class.getSimpleName(), vipVO.getUuid()); } else { @@ -2444,12 +2834,17 @@ public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, Load sql = "select nic from VmInstanceVO vm, VmNicVO nic " + " where vm.uuid=nic.vmInstanceUuid and vm.type in ('UserVM', 'baremetal2') and vm.state in (:vmStates) " + - " and nic.l3NetworkUuid in (:l3NetworkUuids) and nic.metaData is null "; + " and nic.l3NetworkUuid in (:l3NetworkUuids) and nic.metaData is null and nic.ip is not null"; List nicVOS = SQL.New(sql, VmNicVO.class) .param("l3NetworkUuids", l3NetworkUuids) .param("vmStates", asList(VmInstanceState.Running, VmInstanceState.Stopped)) .list(); - nicVOS = nicVOS.stream().filter(n -> !VmNicInventory.valueOf(n).isIpv6OnlyNic()).collect(Collectors.toList()); + + if (ipVersion == IPv6Constants.IPv4) { + nicVOS = nicVOS.stream().filter(n -> !VmNicInventory.valueOf(n).isIpv6OnlyNic()).collect(Collectors.toList()); + } else { + nicVOS = nicVOS.stream().filter(n -> !VmNicInventory.valueOf(n).isIpv4OnlyNic()).collect(Collectors.toList()); + } if (groupVO != null) { List attachedNicUuids = groupVO.getLoadBalancerServerGroupVmNicRefs().stream() @@ -2459,4 +2854,125 @@ public List getAttachableVmNicsForServerGroup(LoadBalancerVO lbVO, Load return nicVOS; } } + + @Override + public void detachVipFromLoadBalancer(LoadBalancerStruct struct, VipVO vip, Completion completion) { + VirtualRouterVmInventory vr = findVirtualRouterVm(struct.getLb().getUuid()); + if (vr == null) { + completion.success(); + return; + } + + //lb struct will has no vip will release + + LoadBalancerVO loadBalancerVO = dbf.findByUuid(struct.getLb().getUuid(), LoadBalancerVO.class); + LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(loadBalancerVO.getType().toString()); + + if (VmInstanceState.Stopped.toString().equals(vr.getState())) { + completion.success(); + return; + } + + refresh(vr, struct, new Completion(completion) { + @Override + public void success() { + completion.success(); + } + + @Override + public void fail(ErrorCode errorCode) { + completion.fail(errorCode); + } + }); + } + + @Override + public void attachVipToLoadBalancer(LoadBalancerStruct struct, VipVO vip, Completion completion) { + VirtualRouterVmInventory vr = findVirtualRouterVm(struct.getLb().getUuid()); + if (vr == null) { + completion.success(); + return; + } + + //lb struct will has no vip will release + + LoadBalancerVO loadBalancerVO = dbf.findByUuid(struct.getLb().getUuid(), LoadBalancerVO.class); + LoadBalancerFactory f = lbMgr.getLoadBalancerFactory(loadBalancerVO.getType().toString()); + + if (VmInstanceState.Stopped.toString().equals(vr.getState())) { + completion.success(); + return; + } + + SimpleFlowChain flowChain = new SimpleFlowChain(); + flowChain.setName("attach-vip-to-lb"); + ArrayList vipAcquire = new ArrayList<>(); + flowChain.then(new Flow() { + @Override + public void run(FlowTrigger trigger, Map data) { + acquireSpecifyedVip(vr, struct, Arrays.asList(vip.getUuid()) , struct.getAllVmNicsInventory(), vipAcquire, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.fail(errorCode); + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + if (vipAcquire.isEmpty()) { + trigger.rollback(); + return; + } + releaseVipForLoadBalancer(vr, struct, vr.getGuestNics(), vipAcquire, new Completion(trigger) { + @Override + public void success() { + trigger.rollback(); + } + + @Override + public void fail(ErrorCode errorCode) { + //todo: add gc + trigger.rollback(); + } + }); + } + }).then(new NoRollbackFlow() { + @Override + public void run(FlowTrigger trigger, Map data) { + refresh(vr, struct, new Completion(trigger) { + @Override + public void success() { + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.debug(String.format("refresh lb failed when attach vip, because %s", errorCode.getCause())); + trigger.fail(errorCode); + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + @Override + public boolean canDetachVipFromLb(LoadBalancerStruct struct, VipVO vip) { + return true; + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterSyncLbOnStartFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterSyncLbOnStartFlow.java index 583bea10f47..eec6fbf809c 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterSyncLbOnStartFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lb/VirtualRouterSyncLbOnStartFlow.java @@ -1,10 +1,12 @@ package org.zstack.network.service.virtualrouter.lb; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.transaction.annotation.Transactional; +import org.stringtemplate.v4.ST; import org.zstack.compute.vm.VmInstanceManager; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.SimpleQuery; @@ -27,6 +29,7 @@ import org.zstack.network.service.virtualrouter.vyos.VyosConstants; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; +import org.zstack.utils.function.ListFunction; import javax.persistence.TypedQuery; import java.util.*; @@ -168,10 +171,17 @@ public void run(final FlowTrigger trigger, Map data) { } SimpleQuery q = dbf.createQuery(VipVO.class); - q.add(VipVO_.uuid, Op.IN, CollectionUtils.transformToList(finalLbs, new Function() { + q.add(VipVO_.uuid, Op.IN, CollectionUtils.transformToList(finalLbs, new ListFunction() { @Override - public String call(LoadBalancerVO arg) { - return arg.getVipUuid(); + public List call(LoadBalancerVO arg) { + ArrayList vipUuids = new ArrayList<>(); + if (!StringUtils.isEmpty(arg.getVipUuid())) { + vipUuids.add(arg.getVipUuid()); + } + if (!StringUtils.isEmpty(arg.getIpv6VipUuid())) { + vipUuids.add(arg.getIpv6VipUuid()); + } + return vipUuids; } })); List vipvos = q.list(); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java index c888c27d1ae..8d9f6b176ee 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployAgentFlow.java @@ -11,6 +11,7 @@ import org.zstack.core.ansible.AnsibleRunner; import org.zstack.core.ansible.SshFileMd5Checker; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.upgrade.UpgradeChecker; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; import org.zstack.header.core.Completion; @@ -50,8 +51,10 @@ public class VirtualRouterDeployAgentFlow extends NoRollbackFlow { private RESTFacade restf; @Autowired private ErrorFacade errf; + @Autowired + private UpgradeChecker upgradeChecker; - private String agentPackageName = VirtualRouterGlobalProperty.AGENT_PACKAGE_NAME; + private final String agentPackageName = VirtualRouterGlobalProperty.AGENT_PACKAGE_NAME; private void continueConnect(final VmNicInventory mgmtNic, final Map data, final FlowTrigger completion) { final VirtualRouterVmInventory vr = (VirtualRouterVmInventory) data.get(VirtualRouterConstant.Param.VR.toString()); @@ -154,6 +157,11 @@ public Class getReturnClass() { done(new FlowDoneHandler(completion) { @Override public void handle(Map data) { + if (CoreGlobalProperty.UNIT_TEST_ON) { + // update vyos agent version when open grayScaleUpgrade + upgradeChecker.updateAgentVersion(vr.getUuid(), VirtualRouterConstant.VIRTUAL_ROUTER_PROVIDER_TYPE, new VirtualRouterMetadataOperator().getManagementVersion(), new VirtualRouterMetadataOperator().getManagementVersion()); + } + completion.next(); } }); @@ -219,15 +227,8 @@ public VmNicInventory call(VmNicInventory arg) { runner.setPrivateKey(privKey); runner.setAgentPort(VirtualRouterGlobalProperty.AGENT_PORT); runner.setTargetIp(mgmtIp); - runner.putArgument("pkg_virtualrouter", agentPackageName); - if (CoreGlobalProperty.SYNC_NODE_TIME) { - if (CoreGlobalProperty.CHRONY_SERVERS == null || CoreGlobalProperty.CHRONY_SERVERS.isEmpty()) { - chain.fail(operr("chrony server not configured!")); - return; - } - runner.putArgument("chrony_servers", String.join(",", CoreGlobalProperty.CHRONY_SERVERS)); - } final VmNicInventory fmgmtNic = mgmtNic; + runner.setDeployArguments(new VirtualRouterDeployArguments()); runner.run(new ReturnValueCompletion(chain) { @Override public void success(Boolean deployed) { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployArguments.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployArguments.java new file mode 100644 index 00000000000..e9f769a5946 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/lifecycle/VirtualRouterDeployArguments.java @@ -0,0 +1,15 @@ +package org.zstack.network.service.virtualrouter.lifecycle; + +import com.google.gson.annotations.SerializedName; +import org.zstack.core.ansible.SyncTimeRequestedDeployArguments; +import org.zstack.network.service.virtualrouter.VirtualRouterGlobalProperty; + +public class VirtualRouterDeployArguments extends SyncTimeRequestedDeployArguments { + @SerializedName("pkg_virtualrouter") + private final String packageName = VirtualRouterGlobalProperty.AGENT_PACKAGE_NAME; + + @Override + public String getPackageName() { + return packageName; + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java index ec7f0b1b87f..73439479aa4 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSnatBackend.java @@ -46,7 +46,8 @@ * To change this template use File | Settings | File Templates. */ public class VirtualRouterSnatBackend extends AbstractVirtualRouterBackend implements - NetworkServiceSnatBackend, VirtualRouterAfterAttachNicExtensionPoint, VirtualRouterBeforeDetachNicExtensionPoint { + NetworkServiceSnatBackend, VirtualRouterAfterAttachNicExtensionPoint, VirtualRouterBeforeDetachNicExtensionPoint, + VirtualRouterAfterDetachNicExtensionPoint { private static final CLogger logger = Utils.getLogger(VirtualRouterSnatBackend.class); @Autowired @@ -153,7 +154,10 @@ private void releasePrivateNicSnat(String vrUuid, VmNicInventory privateNic, Com final List snatInfo = new ArrayList(); List pubNics = new ArrayList<>(); - pubNics.add(vr.getPublicNic()); + VmNicInventory publicNic = vr.getPublicNic(); + if (publicNic != null) { + pubNics.add(publicNic); + } pubNics.addAll(vr.getAdditionalPublicNics()); for (VmNicInventory pubNic : pubNics) { @@ -172,6 +176,7 @@ private void releasePrivateNicSnat(String vrUuid, VmNicInventory privateNic, Com info.setPublicIp(pubNic.getIp()); info.setPublicNicMac(pubNic.getMac()); info.setSnatNetmask(privateNic.getNetmask()); + info.setPrivateGatewayIp(privateNic.getGateway()); snatInfo.add(info); } @@ -242,7 +247,9 @@ private void releasePublicNicSnat(String vrUuid, VmNicInventory publicNic, Compl ApplianceVmSubTypeFactory subTypeFactory = apvmFactory.getApplianceVmSubTypeFactory(vrVO.getApplianceVmType()); ApplianceVm app = subTypeFactory.getSubApplianceVm(vrVO); List snatL3Uuids = app.getSnatL3NetworkOnRouter(vrUuid); - if (!snatL3Uuids.contains(publicNic.getL3NetworkUuid())) { + if (!snatL3Uuids.contains(publicNic.getL3NetworkUuid()) && !vr.isHaEnabled()) { + // for ha router, first router will detach snat service, it will cause second router can not remove snat + // so remove snat for ha router no matter snat is enabled completion.success(); return; } @@ -260,6 +267,7 @@ private void releasePublicNicSnat(String vrUuid, VmNicInventory publicNic, Compl info.setPublicIp(publicNic.getIp()); info.setPublicNicMac(publicNic.getMac()); info.setSnatNetmask(priNic.getNetmask()); + info.setPrivateGatewayIp(priNic.getGateway()); snatInfo.add(info); } @@ -299,7 +307,8 @@ public void run(MessageReply reply) { String msg = String.format( "virtual router[uuid:%s, ip:%s] successfully released snat for public l3[uuid:%s]", vr.getUuid(), vr.getManagementNic().getIp(), finalNic.getL3NetworkUuid()); - app.detachNetworkService(vr.getUuid(), NetworkServiceType.SNAT.toString(), finalNic.getL3NetworkUuid()); + //has moved to afterDetachNic to avoid delete data too early + //app.detachNetworkService(vr.getUuid(), NetworkServiceType.SNAT.toString(), finalNic.getL3NetworkUuid()); logger.warn(msg); } } @@ -358,7 +367,10 @@ public void afterAttachNic(VmNicInventory nic, Completion completion) { final List snatInfo = new ArrayList(); List pubNics = new ArrayList<>(); - pubNics.add(vr.getPublicNic()); + VmNicInventory publicNic = vr.getPublicNic(); + if (publicNic != null) { + pubNics.add(publicNic); + } pubNics.addAll(vr.getAdditionalPublicNics()); for (VmNicInventory pubnic : pubNics) { @@ -378,6 +390,7 @@ public void afterAttachNic(VmNicInventory nic, Completion completion) { info.setPublicIp(pubnic.getIp()); info.setPublicNicMac(pubnic.getMac()); info.setSnatNetmask(priNic.getNetmask()); + info.setPrivateGatewayIp(priNic.getGateway()); if (snatL3Uuids.contains(pubnic.getL3NetworkUuid())) { info.setState(Boolean.TRUE); } else { @@ -470,4 +483,52 @@ private Vip getVipWithSnatService(VirtualRouterVmInventory vr, VmNicInventory ni public void afterAttachNicRollback(VmNicInventory nic, NoErrorCompletion completion) { completion.done(); } + + @Override + public void afterDetachVirtualRouterNic(VmNicInventory nic, Completion completion) { + VirtualRouterVmVO vrVO = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, nic.getVmInstanceUuid()).find(); + if (vrVO == null) { + completion.success(); + return; + } + final VirtualRouterVmInventory vr = VirtualRouterVmInventory.valueOf(vrVO); + ApplianceVmSubTypeFactory subTypeFactory = apvmFactory.getApplianceVmSubTypeFactory(vrVO.getApplianceVmType()); + ApplianceVm app = subTypeFactory.getSubApplianceVm(vrVO); + + if ( ! (VirtualRouterNicMetaData.isPublicNic(nic) || VirtualRouterNicMetaData.isAddinitionalPublicNic(nic))) { + completion.success(); + return; + } + + String peerVrUuid = haBackend.getVirtualRouterPeerUuid(vr.getUuid()); + if (peerVrUuid == null) { + logger.info(String.format("No peer VR found for VR[uuid:%s], detaching SNAT service for L3[uuid:%s]", + vr.getUuid(), nic.getL3NetworkUuid())); + app.detachNetworkService(vr.getUuid(), NetworkServiceType.SNAT.toString(), nic.getL3NetworkUuid()); + completion.success(); + return; + } + + VirtualRouterVmVO peerVrVO = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, peerVrUuid).find(); + if (peerVrVO == null) { + logger.warn(String.format("Peer VR[uuid:%s] not found, proceeding with detach", peerVrUuid)); + app.detachNetworkService(vr.getUuid(), NetworkServiceType.SNAT.toString(), nic.getL3NetworkUuid()); + completion.success(); + return; + } + + VirtualRouterVmInventory peerVr = VirtualRouterVmInventory.valueOf(peerVrVO); + List allL3Uuids = peerVr.getAllL3Networks(); + if (allL3Uuids != null && allL3Uuids.contains(nic.getL3NetworkUuid())) { + logger.info(String.format("Peer VR[uuid:%s] still has L3[uuid:%s], skipping detach", + peerVrUuid, nic.getL3NetworkUuid())); + completion.success(); + return; + } + + logger.info(String.format("Detaching SNAT service for VR[uuid:%s] L3[uuid:%s]", + vr.getUuid(), nic.getL3NetworkUuid())); + app.detachNetworkService(vr.getUuid(), NetworkServiceType.SNAT.toString(), nic.getL3NetworkUuid()); + completion.success(); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java index 9ea4d2a4377..037c12098f3 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/nat/VirtualRouterSyncSNATOnStartFlow.java @@ -90,13 +90,17 @@ public void run(final FlowTrigger chain, Map data) { final List snatInfo = new ArrayList(); List pubNics = new ArrayList<>(); - pubNics.add(vr.getPublicNic()); + VmNicInventory publicNic = vr.getPublicNic(); + if (publicNic != null) { + pubNics.add(publicNic); + } pubNics.addAll(vr.getAdditionalPublicNics()); for (VmNicInventory pubNic : pubNics) { if (pubNic.isIpv6OnlyNic()) { continue; } + pubNic = vrMgr.getSnatPubicInventory(vr, pubNic.getL3NetworkUuid()); for (VmNicInventory priNic : vr.getGuestNics()) { if (nwServed.contains(priNic.getL3NetworkUuid()) && !priNic.isIpv6OnlyNic()) { SNATInfo info = new SNATInfo(); @@ -105,6 +109,7 @@ public void run(final FlowTrigger chain, Map data) { info.setPublicIp(pubNic.getIp()); info.setPublicNicMac(pubNic.getMac()); info.setSnatNetmask(priNic.getNetmask()); + info.setPrivateGatewayIp(priNic.getGateway()); if (snatL3Uuids.contains(pubNic.getL3NetworkUuid())) { info.setState(Boolean.TRUE); } else { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java index f475449f5f8..6451b4b781d 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterPortForwardingBackend.java @@ -46,7 +46,7 @@ public class VirtualRouterPortForwardingBackend extends AbstractVirtualRouterBackend implements PortForwardingBackend, Component, VirtualRouterAfterAttachNicExtensionPoint, VirtualRouterBeforeDetachNicExtensionPoint, - VirtualRouterHaGetCallbackExtensionPoint { + VirtualRouterHaGetCallbackExtensionPoint, VirtualRouterAfterDetachNicExtensionPoint { private static final CLogger logger = Utils.getLogger(VirtualRouterPortForwardingBackend.class); @Autowired @@ -315,10 +315,15 @@ private List findPortforwardingsOnVmNic(VmNicInventory nic to.setUuid(pf.getUuid()); to.setAllowedCidr(pf.getAllowedCidr()); to.setPrivateIp(t.get(1, String.class)); - to.setPrivateMac( - vr.getVmNics().stream() - .filter(n -> n.getL3NetworkUuid().equals(nic.getL3NetworkUuid())) - .findFirst().get().getMac()); + + Optional priNic = vr.getVmNics().stream() + .filter(n -> n.getL3NetworkUuid().equals(nic.getL3NetworkUuid())) + .findFirst(); + if (!priNic.isPresent()) { + continue; + } + to.setPrivateMac(priNic.get().getMac()); + Optional publicNic = vr.getVmNics().stream() .filter(n -> n.getL3NetworkUuid().equals(vipVO.getL3NetworkUuid())) .findFirst(); @@ -341,9 +346,8 @@ private List findPortforwardingsOnVmNic(VmNicInventory nic private List findPortForwardingTuplesOnVmNic(VmNicInventory nic) { return SQL.New("select pf, nic.ip, nic.mac " + - "from PortForwardingRuleVO pf, VmNicVO nic, VmInstanceVO vm " + + "from PortForwardingRuleVO pf, VmNicVO nic " + "where pf.vmNicUuid = nic.uuid " + - "and nic.vmInstanceUuid = vm.uuid " + "and nic.l3NetworkUuid = :l3Uuid " + "and pf.state = :enabledState", Tuple.class) .param("l3Uuid", nic.getL3NetworkUuid()) @@ -480,6 +484,7 @@ public void run(MessageReply reply) { vrVO.getUuid(), ret.getError()); completion.fail(err); } else { + /* move clean up db to afterDetachNic List pfs = findPortForwardingTuplesOnVmNic(nic); List ruleUuids = pfs.stream().map(p -> p.get(0, PortForwardingRuleVO.class).getUuid()).collect(Collectors.toList()); proxy.detachNetworkService(vr.getUuid(), PortForwardingRuleVO.class.getSimpleName(), ruleUuids); @@ -493,6 +498,7 @@ protected void scripts() { } }.execute(); } + */ String info = String.format("sync port forwardings on virtual router[uuid:%s] successfully", vrVO.getUuid()); @@ -569,4 +575,73 @@ public void callBack(String vrUuid, VirtualRouterHaTask task, Completion complet return structs; } + + @Override + public void afterDetachVirtualRouterNic(VmNicInventory nic, Completion completion) { + if (!VirtualRouterNicMetaData.GUEST_NIC_MASK_STRING_LIST.contains(nic.getMetaData())) { + completion.success(); + return; + } + + if (VirtualRouterSystemTags.DEDICATED_ROLE_VR.hasTag(nic.getVmInstanceUuid())) { + completion.success(); + return; + } + + try { + nwServiceMgr.getTypeOfNetworkServiceProviderForService(nic.getL3NetworkUuid(), PortForwardingConstant.PORTFORWARDING_TYPE); + } catch (OperationFailureException e) { + completion.success(); + return; + } + + VirtualRouterVmVO vrVO = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, nic.getVmInstanceUuid()).find(); + if (vrVO == null) { + completion.success(); + return; + } + final VirtualRouterVmInventory vr = VirtualRouterVmInventory.valueOf(vrVO); + + class DbCleaner { + void run() { + List pfs = findPortForwardingTuplesOnVmNic(nic); + List ruleUuids = pfs.stream().map(p -> p.get(0, PortForwardingRuleVO.class).getUuid()).collect(Collectors.toList()); + proxy.detachNetworkService(vr.getUuid(), PortForwardingRuleVO.class.getSimpleName(), ruleUuids); + for (Tuple t : pfs) { + PortForwardingRuleVO rule = t.get(0, PortForwardingRuleVO.class); + new SQLBatch() { + @Override + protected void scripts() { + sql(PortForwardingRuleVO.class).eq(PortForwardingRuleVO_.uuid, rule.getUuid()) + .set(PortForwardingRuleVO_.guestIp, null).set(PortForwardingRuleVO_.vmNicUuid, null).update(); + } + }.execute(); + } + } + } + DbCleaner cleaner = new DbCleaner(); + + String peerVrUuid = haBackend.getVirtualRouterPeerUuid(vr.getUuid()); + if (peerVrUuid == null || peerVrUuid.isEmpty()) { + cleaner.run(); + completion.success(); + return; + } + + VirtualRouterVmVO peerVrVO = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, peerVrUuid).find(); + if (peerVrVO == null) { + cleaner.run(); + completion.success(); + return; + } + VirtualRouterVmInventory peerVr = VirtualRouterVmInventory.valueOf(peerVrVO); + List allL3Uuids = peerVr.getAllL3Networks(); + if (allL3Uuids != null && allL3Uuids.contains(nic.getL3NetworkUuid())) { + completion.success(); + return; + } + + cleaner.run(); + completion.success(); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java index 9d6b1982eef..c0bac709904 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/portforwarding/VirtualRouterSyncPortForwardingRulesOnStartFlow.java @@ -7,6 +7,7 @@ import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.core.workflow.Flow; @@ -15,7 +16,6 @@ import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.message.MessageReply; import org.zstack.header.vm.VmInstanceConstant; -import org.zstack.header.vm.VmInstanceState; import org.zstack.header.vm.VmNicInventory; import org.zstack.network.service.portforwarding.*; import org.zstack.network.service.virtualrouter.*; @@ -34,7 +34,7 @@ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VirtualRouterSyncPortForwardingRulesOnStartFlow implements Flow { - private static CLogger logger = Utils.getLogger(VirtualRouterSyncPortForwardingRulesOnStartFlow.class); + private static final CLogger logger = Utils.getLogger(VirtualRouterSyncPortForwardingRulesOnStartFlow.class); @Autowired private DatabaseFacade dbf; @@ -57,27 +57,25 @@ private List findRulesForThisRouter(VirtualRouterVmInvento return new ArrayList<>(); } - String sql = "select rule from PortForwardingRuleVO rule, VmNicVO nic, VmInstanceVO vm where" + - " nic.vmInstanceUuid = vm.uuid and rule.vmNicUuid = nic.uuid and rule.uuid in (:pfUuids)"; - TypedQuery q = dbf.getEntityManager().createQuery(sql, PortForwardingRuleVO.class); - q.setParameter("pfUuids", pfUuids); - return q.getResultList(); + return Q.New(PortForwardingRuleVO.class).in(PortForwardingRuleVO_.uuid, pfUuids).list(); } else { - VmNicInventory publicNic = vr.getPublicNic(); List guestNics = vr.getGuestNics(); if (guestNics == null || guestNics.isEmpty()) { return new ArrayList(0); } List pubL3Uuids = new ArrayList<>(); - pubL3Uuids.add(vr.getPublicNic().getL3NetworkUuid()); + VmNicInventory publicNic = vr.getPublicNic(); pubL3Uuids.addAll(vr.getAdditionalPublicNics().stream().map(VmNicInventory::getL3NetworkUuid).collect(Collectors.toList())); - if (!vr.getPublicNic().getL3NetworkUuid().equals(vr.getManagementNetworkUuid())) { - /* in old code, pf can be configured on management nic */ - pubL3Uuids.add(vr.getManagementNetworkUuid()); + if (publicNic != null) { + pubL3Uuids.add(publicNic.getL3NetworkUuid()); + if (!publicNic.getL3NetworkUuid().equals(vr.getManagementNetworkUuid())) { + /* in old code, pf can be configured on management nic */ + pubL3Uuids.add(vr.getManagementNetworkUuid()); + } } - String sql = "select rule from PortForwardingRuleVO rule, VipVO vip, VmNicVO nic, VmInstanceVO vm where vm.uuid = nic.vmInstanceUuid and " + + String sql = "select rule from PortForwardingRuleVO rule, VipVO vip, VmNicVO nic where " + " rule.vipUuid = vip.uuid and rule.vmNicUuid = nic.uuid and vip.l3NetworkUuid in (:vipL3Uuids) and nic.l3NetworkUuid in (:guestL3Uuid)"; TypedQuery q = dbf.getEntityManager().createQuery(sql, PortForwardingRuleVO.class); q.setParameter("vipL3Uuids", pubL3Uuids); @@ -119,9 +117,13 @@ private Collection calculateAllRules(Map pubNic = vr.getVmNics().stream() .filter(n -> n.getL3NetworkUuid().equals(publicL3Uuid)) - .findFirst().get().getMac()); + .findFirst(); + if (!pubNic.isPresent()) { + continue; + } + to.setPublicMac(pubNic.get().getMac()); tos.put(ruleUuid, to); } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VipConfigProxy.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VipConfigProxy.java index e54a73b252c..802857b6706 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VipConfigProxy.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VipConfigProxy.java @@ -1,18 +1,22 @@ package org.zstack.network.service.virtualrouter.vip; +import org.springframework.beans.factory.annotation.Autowired; import org.zstack.appliancevm.ApplianceVmInventory; import org.zstack.appliancevm.ApplianceVmSyncConfigToHaGroupExtensionPoint; -import org.zstack.core.db.Q; -import org.zstack.core.db.SQL; +import org.zstack.appliancevm.ApplianceVmType; +import org.zstack.core.db.DatabaseFacade; import org.zstack.header.core.NoErrorCompletion; -import org.zstack.network.service.virtualrouter.ha.VirtualRouterConfigProxy; +import org.zstack.network.service.virtualrouter.VirtualRouterVmVO; import java.util.ArrayList; import java.util.List; -import static java.util.Arrays.asList; +public class VipConfigProxy implements ApplianceVmSyncConfigToHaGroupExtensionPoint { + @Autowired + DatabaseFacade dbf; + @Autowired + private VirtualRouterVipConfigManager vrVipConfigMgr; -public class VipConfigProxy extends VirtualRouterConfigProxy implements ApplianceVmSyncConfigToHaGroupExtensionPoint { @Override public void applianceVmSyncConfigToHa(ApplianceVmInventory inv, String haUuid) { @@ -28,42 +32,50 @@ public void applianceVmSyncConfigAfterAddToHaGroup(ApplianceVmInventory inv, Str completion.done(); } - @Override - protected void attachNetworkServiceToNoHaVirtualRouter(String vrUuid, String type, List serviceUuids) { - List refs = new ArrayList<>(); - for (String uuid : serviceUuids) { - if (dbf.isExist(uuid, VirtualRouterVipVO.class)) { - continue; - } + public void attachNetworkService(String vrUuid, String type, List serviceUuids) { + VirtualRouterVmVO vrVo = dbf.findByUuid(vrUuid, VirtualRouterVmVO.class); + VirtualRouterVipConfigFactory factory = vrVipConfigMgr.getVirtualRouterVipConfigFactory(vrVo.getApplianceVmType()); + factory.attachNetworkService(vrUuid, serviceUuids); + } - VirtualRouterVipVO ref = new VirtualRouterVipVO(); - ref.setUuid(uuid); - ref.setVirtualRouterVmUuid(vrUuid); - refs.add(ref); - } + final public void detachNetworkService(String vrUuid, String type, List serviceUuids) { + VirtualRouterVmVO vrVo = dbf.findByUuid(vrUuid, VirtualRouterVmVO.class); + VirtualRouterVipConfigFactory factory = vrVipConfigMgr.getVirtualRouterVipConfigFactory(vrVo.getApplianceVmType()); + factory.detachNetworkService(vrUuid, serviceUuids); + } - if (!refs.isEmpty()) { - dbf.persistCollection(refs); + final public List getAllVrUuidsByNetworkService(String type, String serviceUuid) { + for (ApplianceVmType atype : ApplianceVmType.values()) { + VirtualRouterVipConfigFactory factory = vrVipConfigMgr.getVirtualRouterVipConfigFactory(atype.toString()); + if (factory != null) { + List vrUuids = factory.getAllVrUuidsByNetworkService(serviceUuid); + if (!vrUuids.isEmpty()) { + return vrUuids; + } + } } - } - @Override - protected void detachNetworkServiceFromNoHaVirtualRouter(String vrUuid, String type, List serviceUuids) { - SQL.New(VirtualRouterVipVO.class).in(VirtualRouterVipVO_.uuid, serviceUuids) - .eq(VirtualRouterVipVO_.virtualRouterVmUuid, vrUuid).delete(); + return new ArrayList<>(); } - @Override - protected List getNoHaVirtualRouterUuidsByNetworkService(String serviceUuid) { - VirtualRouterVipVO vipVo = dbf.findByUuid(serviceUuid, VirtualRouterVipVO.class); - if (vipVo == null) { - return null; + final public List getVrUuidsByNetworkService(String type, String serviceUuid) { + for (ApplianceVmType atype : ApplianceVmType.values()) { + VirtualRouterVipConfigFactory factory = vrVipConfigMgr.getVirtualRouterVipConfigFactory(atype.toString()); + if (factory != null) { + List vrUuids = factory.getVrUuidsByNetworkService(serviceUuid); + if (!vrUuids.isEmpty()) { + return vrUuids; + } + } } - return asList(vipVo.getVirtualRouterVmUuid()); + + return new ArrayList<>(); } - @Override - protected List getServiceUuidsByNoHaVirtualRouter(String vrUuid) { - return Q.New(VirtualRouterVipVO.class).eq(VirtualRouterVipVO_.virtualRouterVmUuid, vrUuid).select(VirtualRouterVipVO_.uuid).listValues(); + + final public List getServiceUuidsByRouterUuid(String vrUuid, String type) { + VirtualRouterVmVO vrVo = dbf.findByUuid(vrUuid, VirtualRouterVmVO.class); + VirtualRouterVipConfigFactory factory = vrVipConfigMgr.getVirtualRouterVipConfigFactory(vrVo.getApplianceVmType()); + return factory.getVipUuidsByRouterUuid(vrUuid); } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCleanupVipOnDestroyFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCleanupVipOnDestroyFlow.java index edb5f3f6120..cf54d466037 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCleanupVipOnDestroyFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCleanupVipOnDestroyFlow.java @@ -13,10 +13,8 @@ import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.message.MessageReply; -import org.zstack.network.service.vip.VipConstant; -import org.zstack.network.service.vip.VipDeletionMsg; -import org.zstack.network.service.vip.VipVO; -import org.zstack.network.service.vip.VipVO_; +import org.zstack.header.network.service.NetworkServiceType; +import org.zstack.network.service.vip.*; import org.zstack.network.service.virtualrouter.VirtualRouterConstant; import org.zstack.network.service.virtualrouter.VirtualRouterConstant.Param; import org.zstack.utils.Utils; @@ -35,7 +33,7 @@ public class VirtualRouterCleanupVipOnDestroyFlow extends NoRollbackFlow { @Autowired protected VipConfigProxy vipConfigProxy; - private static CLogger logger = Utils.getLogger(VirtualRouterCleanupVipOnDestroyFlow.class); + private static final CLogger logger = Utils.getLogger(VirtualRouterCleanupVipOnDestroyFlow.class); @Override public void run(final FlowTrigger trigger, Map data) { @@ -56,8 +54,19 @@ public void run(final FlowTrigger trigger, Map data) { } List vips = Q.New(VipVO.class).in(VipVO_.uuid, vipUuids).eq(VipVO_.system, true).list(); - if (!vips.isEmpty()) { - new While<>(vips).each((vip, compl) -> { + List vipUsedForService = new ArrayList<>(); + List vipNotUsedForService = new ArrayList<>(); + vips.forEach( v -> { + if (v.getServicesTypes().isEmpty() || + (v.getServicesTypes().size() == 1 && v.getServicesTypes().contains(NetworkServiceType.SNAT.toString()))){ + vipNotUsedForService.add(v); + } else { + vipUsedForService.add(v); + } + }); + + if (!vipNotUsedForService.isEmpty()) { + new While<>(vipNotUsedForService).each((vip, compl) -> { VipDeletionMsg msg = new VipDeletionMsg(); msg.setVipUuid(vip.getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, VipConstant.SERVICE_ID, msg.getVipUuid()); @@ -78,11 +87,13 @@ public void run(MessageReply reply) { }).run(new WhileDoneCompletion(trigger) { @Override public void done(ErrorCodeList errorCodeList) { + vipUsedForService.forEach(v -> new VipBase(v).delSystemServiceRef()); vipConfigProxy.detachNetworkService(vrUuid, VipVO.class.getSimpleName(), vipUuids); trigger.next(); } }); } else { + vipUsedForService.forEach(v -> new VipBase(v).delSystemServiceRef()); vipConfigProxy.detachNetworkService(vrUuid, VipVO.class.getSimpleName(), vipUuids); trigger.next(); } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreatePublicVipFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreatePublicVipFlow.java index 45296c1d9b9..c5eb3cb43d8 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreatePublicVipFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterCreatePublicVipFlow.java @@ -20,6 +20,8 @@ import org.zstack.header.message.MessageReply; import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.l3.UsedIpInventory; +import org.zstack.header.network.l3.UsedIpVO; +import org.zstack.header.network.l3.UsedIpVO_; import org.zstack.header.network.service.NetworkServiceProviderType; import org.zstack.header.network.service.NetworkServiceType; import org.zstack.header.vm.VmNicInventory; @@ -94,9 +96,23 @@ public void run(final FlowTrigger chain, Map data) { boolean vip6Created = true; if (vipIp != null) { vip4Created = Q.New(VipVO.class).eq(VipVO_.ip, vipIp).eq(VipVO_.l3NetworkUuid, nic.getL3NetworkUuid()).isExists(); + if (vip4Created) { + VipVO vip = Q.New(VipVO.class).eq(VipVO_.ip, vipIp).eq(VipVO_.l3NetworkUuid, nic.getL3NetworkUuid()).find(); + vip.setSystem(true); + vip.setUsedIpUuid(publicNic.getUsedIpUuid()); + dbf.updateAndRefresh(vip); + vipConfigProxy.attachNetworkService(vr.getUuid(), VipVO.class.getSimpleName(), Arrays.asList(vip.getUuid())); + } } if (vipIp6 != null) { vip6Created = Q.New(VipVO.class).eq(VipVO_.ip, vipIp6).eq(VipVO_.l3NetworkUuid, nic.getL3NetworkUuid()).isExists(); + if (vip6Created) { + VipVO vip = Q.New(VipVO.class).eq(VipVO_.ip, vipIp6).eq(VipVO_.l3NetworkUuid, nic.getL3NetworkUuid()).find(); + vip.setSystem(true); + vip.setUsedIpUuid(publicNic.getUsedIpUuid()); + dbf.updateAndRefresh(vip); + vipConfigProxy.attachNetworkService(vr.getUuid(), VipVO.class.getSimpleName(), Arrays.asList(vip.getUuid())); + } } if (vip4Created && vip6Created) { logger.debug(String.format("vip [ip:%s] in l3 network [uuid:%s] already created", vipIp, nic.getL3NetworkUuid())); @@ -137,7 +153,6 @@ public void run(final FlowTrigger chain, Map data) { msgs.add(cmsg); } - List errs = new ArrayList<>(); List vips = new ArrayList<>(); /* use for rollback */ data.put(VirtualRouterConstant.Param.PUB_VIP_UUID.toString(), vips); @@ -146,7 +161,7 @@ public void run(final FlowTrigger chain, Map data) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { - errs.add(reply.getError()); + wcoml.addError(reply.getError()); wcoml.allDone(); return; } @@ -161,6 +176,11 @@ public void run(MessageReply reply) { }).run(new WhileDoneCompletion(chain) { @Override public void done(ErrorCodeList errorCodeList) { + if (errorCodeList != null && !errorCodeList.getCauses().isEmpty()) { + chain.fail(errorCodeList.getCauses().get(0)); + return; + } + if (snat != null && !snat) { logger.debug(String.format("SNAT is not enabled on virtual router [uuid:%s]", vr.getUuid())); chain.next(); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterSyncVipForNewCreateFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterSyncVipForNewCreateFlow.java index 1eb3772a672..713f33ff4d1 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterSyncVipForNewCreateFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterSyncVipForNewCreateFlow.java @@ -46,7 +46,7 @@ public void run(final FlowTrigger chain, Map data) { final VmNicInventory publicNic = vr.getPublicNic(); List l3Uuids = guestNics.stream().map(n -> n.getL3NetworkUuid()).collect(Collectors.toList()); List vipUuids = new ArrayList(); - if (vrMgr.isL3NetworksNeedingNetworkServiceByVirtualRouter(l3Uuids, EipConstant.EIP_NETWORK_SERVICE_TYPE) && + if (publicNic != null && vrMgr.isL3NetworksNeedingNetworkServiceByVirtualRouter(l3Uuids, EipConstant.EIP_NETWORK_SERVICE_TYPE) && !(VirtualRouterSystemTags.DEDICATED_ROLE_VR.hasTag(vr.getUuid()) && !VirtualRouterSystemTags.VR_EIP_ROLE.hasTag(vr.getUuid()))) { vipUuids.addAll(new Callable>() { @Override diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java index 3f047af13dd..e672e1ed4fa 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBackend.java @@ -1,6 +1,7 @@ package org.zstack.network.service.virtualrouter.vip; import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.appliancevm.ApplianceVmType; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; @@ -22,10 +23,11 @@ import org.zstack.network.service.vip.*; import org.zstack.network.service.virtualrouter.*; import org.zstack.network.service.virtualrouter.VirtualRouterCommands.*; +import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; +import org.zstack.utils.function.ForEachFunction; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; -import org.zstack.utils.network.NetworkUtils; import java.util.*; import java.util.stream.Collectors; @@ -36,7 +38,7 @@ public class VirtualRouterVipBackend extends AbstractVirtualRouterBackend implements VirtualRouterHaGetCallbackExtensionPoint, VipBackend, VirtualRouterAfterAttachNicExtensionPoint, VirtualRouterBeforeDetachNicExtensionPoint, PreVipReleaseExtensionPoint, - ReleaseNetworkServiceOnDetachingNicExtensionPoint { + ReleaseNetworkServiceOnDetachingNicExtensionPoint, VirtualRouterVipConfigFactory { private static final CLogger logger = Utils.getLogger(VirtualRouterVipBackend.class); @Autowired @@ -51,6 +53,8 @@ public class VirtualRouterVipBackend extends AbstractVirtualRouterBackend implem private VipConfigProxy proxy; @Autowired VirtualRouterManager vrMgr; + @Autowired + VirtualRouterVipConfigManager vipConfigMgr; public static String RELEASE_VIP_TASK = "releaseVip"; public static String APPLY_VIP_TASK = "applyVip"; @@ -72,19 +76,11 @@ public void createVipOnVirtualRouterVm(final VirtualRouterVmInventory vr, List notSystemVip = vips.stream().filter(v -> !v.isSystem()).collect(Collectors.toList()); for (VipInventory vip : systemVip) { - /* TODO: not support ipv6 vip */ - if (!NetworkUtils.isIpv4Address(vip.getIp())) { - continue; - } String mac = getOwnerMac(vr, vip); VipTO to = VipTO.valueOf(vip, mac); tos.add(to); } for (VipInventory vip : notSystemVip) { - /* TODO: not support ipv6 vip */ - if (!NetworkUtils.isIpv4Address(vip.getIp())) { - continue; - } String mac = getOwnerMac(vr, vip); VipTO to = VipTO.valueOf(vip, mac); tos.add(to); @@ -93,10 +89,6 @@ public void createVipOnVirtualRouterVm(final VirtualRouterVmInventory vr, List nicIps = new ArrayList<>(); if (syncVip) { for (VmNicInventory nic : vr.getVmNics()) { - /* TODO: not support ipv6 vip */ - if (!NetworkUtils.isIpv4Address(nic.getIp())) { - continue; - } nicIps.add(NicIpTO.valueOf(nic)); } } @@ -250,6 +242,11 @@ public void run(MessageReply reply) { } else { List vipUuids = vips.stream().map(VipTO::getVipUuid).distinct().collect(Collectors.toList()); proxy.attachNetworkService(nic.getVmInstanceUuid(), VipVO.class.getSimpleName(), vipUuids); + List vips = Q.New(VipVO.class).in(VipVO_.uuid, vipUuids).list(); + CollectionUtils.safeForEach(pluginRgty.getExtensionList(AfterAcquireVipExtensionPoint.class), ext -> { + logger.debug(String.format("execute after acquire vip extension point %s", ext)); + ext.afterAcquireVip(VipInventory.valueOf(vips)); + }); completion.success(); } } @@ -468,4 +465,55 @@ public void releaseResourceOnDetachingNic(VmInstanceSpec spec, VmNicInventory ni completion.done(); } + + @Override + public ApplianceVmType getApplianceVmType() { + return ApplianceVmType.valueOf(VirtualRouterConstant.VIRTUAL_ROUTER_VM_TYPE); + } + + @Override + public void attachNetworkService(String vrUuid, List vipUuids) { + List refs = new ArrayList<>(); + for (String uuid : vipUuids) { + if (dbf.isExist(uuid, VirtualRouterVipVO.class)) { + continue; + } + + VirtualRouterVipVO ref = new VirtualRouterVipVO(); + ref.setUuid(uuid); + ref.setVirtualRouterVmUuid(vrUuid); + refs.add(ref); + } + + if (!refs.isEmpty()) { + dbf.persistCollection(refs); + } + } + + @Override + public void detachNetworkService(String vrUuid, List vipUuids) { + SQL.New(VirtualRouterVipVO.class).in(VirtualRouterVipVO_.uuid, vipUuids) + .eq(VirtualRouterVipVO_.virtualRouterVmUuid, vrUuid).delete(); + } + + @Override + public List getAllVrUuidsByNetworkService(String vipUuid) { + return getVrUuidsByNetworkService(vipUuid); + } + + @Override + public List getVrUuidsByNetworkService(String vipUuid) { + VirtualRouterVipVO vipVo = dbf.findByUuid(vipUuid, VirtualRouterVipVO.class); + if (vipVo == null) { + return new ArrayList<>(); + } + return Collections.singletonList(vipVo.getVirtualRouterVmUuid()); + } + + @Override + public List getVipUuidsByRouterUuid(String vrUuid) { + return Q.New(VirtualRouterVipVO.class) + .eq(VirtualRouterVipVO_.virtualRouterVmUuid, vrUuid) + .select(VirtualRouterVipVO_.uuid).listValues(); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java index f8539acba41..614b565ee3b 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipBaseBackend.java @@ -1,10 +1,12 @@ package org.zstack.network.service.virtualrouter.vip; +import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.core.db.Q; import org.zstack.core.db.SimpleQuery; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.core.Completion; @@ -224,6 +226,15 @@ public void run(MessageReply reply) { @Override protected void acquireVipOnBackend(Completion completion) { + acquireVip(StringUtils.EMPTY, completion); + } + + @Override + protected void acquireVipOnSpecificBackend(String specificBackendUuid, Completion completion) { + acquireVip(specificBackendUuid, completion); + } + + private void acquireVip(String specificVrUuid, Completion completion) { refresh(); List vrs = proxy.getVrUuidsByNetworkService(VipVO.class.getSimpleName(), self.getUuid()); @@ -245,7 +256,7 @@ protected void acquireVipOnBackend(Completion completion) { @Override public void run(AfterAcquireVipExtensionPoint ext) { logger.debug(String.format("execute after acquire vip extension point %s", ext)); - ext.afterAcquireVip(VipInventory.valueOf(getSelf())); + ext.afterAcquireVip(asList(VipInventory.valueOf(getSelf()))); } }); @@ -262,6 +273,13 @@ public void run(AfterAcquireVipExtensionPoint ext) { public void run(final FlowTrigger trigger, final Map data) { DebugUtils.Assert(self.getPeerL3NetworkUuids() != null, "peerL3NetworkUuid cannot be null"); + if (!StringUtils.isEmpty(specificVrUuid)) { + VirtualRouterVmVO virtualRouterVmVO = Q.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, specificVrUuid).find(); + data.put(VirtualRouterConstant.Param.VR.toString(), VirtualRouterVmInventory.valueOf(virtualRouterVmVO)); + trigger.next(); + return; + } + VirtualRouterStruct s = new VirtualRouterStruct(); s.setL3Network(L3NetworkInventory.valueOf(dbf.findByUuid(self.getPeerL3NetworkUuids().iterator().next(), L3NetworkVO.class))); @@ -324,7 +342,7 @@ public void handle(Map data) { @Override public void run(AfterAcquireVipExtensionPoint ext) { logger.debug(String.format("execute after acquire vip extension point %s", ext)); - ext.afterAcquireVip(VipInventory.valueOf(getSelf())); + ext.afterAcquireVip(asList(VipInventory.valueOf(getSelf()))); } }); diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigFactory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigFactory.java new file mode 100644 index 00000000000..eb2732c4fba --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigFactory.java @@ -0,0 +1,14 @@ +package org.zstack.network.service.virtualrouter.vip; + +import org.zstack.appliancevm.ApplianceVmType; + +import java.util.List; + +public interface VirtualRouterVipConfigFactory { + ApplianceVmType getApplianceVmType(); + void attachNetworkService(String vrUuid, List vipUuids); + void detachNetworkService(String vrUuid, List vipUuids); + List getVrUuidsByNetworkService(String vipUuid); + List getAllVrUuidsByNetworkService(String vipUuid); + List getVipUuidsByRouterUuid(String vrUuid); +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigManager.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigManager.java new file mode 100644 index 00000000000..8481368db84 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigManager.java @@ -0,0 +1,5 @@ +package org.zstack.network.service.virtualrouter.vip; + +public interface VirtualRouterVipConfigManager { + VirtualRouterVipConfigFactory getVirtualRouterVipConfigFactory(String type); +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigManagerImpl.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigManagerImpl.java new file mode 100644 index 00000000000..2d9188f8217 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipConfigManagerImpl.java @@ -0,0 +1,38 @@ +package org.zstack.network.service.virtualrouter.vip; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.componentloader.PluginRegistry; +import org.zstack.header.Component; +import org.zstack.header.exception.CloudRuntimeException; + +import java.util.HashMap; + +public class VirtualRouterVipConfigManagerImpl implements VirtualRouterVipConfigManager, Component { + @Autowired + protected PluginRegistry pluginRgty; + + private HashMap vipConfigFactoryHashMap = new HashMap<>(); + + @Override + public VirtualRouterVipConfigFactory getVirtualRouterVipConfigFactory(String type) { + return vipConfigFactoryHashMap.get(type); + } + + @Override + public boolean start() { + for (VirtualRouterVipConfigFactory factory : pluginRgty.getExtensionList(VirtualRouterVipConfigFactory.class)) { + VirtualRouterVipConfigFactory old = vipConfigFactoryHashMap.get(factory.getApplianceVmType().toString()); + if (old != null) { + throw new CloudRuntimeException(String.format("duplicate VirtualRouterVipConfigFactory[%s, %s] for applianceVm type[%s]", + old.getClass().getName(), factory.getClass().getName(), factory.getApplianceVmType().toString())); + } + vipConfigFactoryHashMap.put(factory.getApplianceVmType().toString(), factory); + } + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipVO.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipVO.java index a8c62810ab6..c97ade5bd28 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipVO.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vip/VirtualRouterVipVO.java @@ -30,6 +30,8 @@ public class VirtualRouterVipVO { @ForeignKey(parentEntityClass = VipVO.class, onDeleteAction = ReferenceOption.RESTRICT) private String uuid; + + @Column @ForeignKey(parentEntityClass = VmInstanceEO.class, onDeleteAction = ReferenceOption.CASCADE) private String virtualRouterVmUuid; diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java index 4b688b1982c..e94a8d2b5f1 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConfigSshFlow.java @@ -19,6 +19,8 @@ import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmNicInventory; import org.zstack.network.service.virtualrouter.VirtualRouterGlobalConfig; +import org.zstack.network.service.virtualrouter.VirtualRouterSystemTags; +import org.zstack.network.service.virtualrouter.VirtualRouterVmVO; import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; import org.zstack.utils.function.Function; @@ -55,6 +57,10 @@ public void run(FlowTrigger trigger, Map data) { } boolean isReconnect = Boolean.parseBoolean((String) data.get(Params.isReconnect.toString())); + final String vrUuid = (String) data.get(VmInstanceConstant.Params.vmInstanceUuid.toString()); + String vrUserTag = VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER.getTokenByResourceUuid( + vrUuid, VirtualRouterVmVO.class, VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER_TOKEN); + String sshUser = vrUserTag != null ? vrUserTag : "vyos"; //old vpc vrouter has no tag, that's vyos. String mgmtNicIp; if (!isReconnect) { @@ -89,7 +95,7 @@ public boolean run() { long now = System.currentTimeMillis(); if (now > timeout) { trigger.fail(err(ApplianceVmErrors.UNABLE_TO_START, "the SSH port is not" + - " open after %s seconds. Failed to login the vyos router[ip:%s]", timeoutInSeconds, mgmtNicIp)); + " open after %s seconds. Failed to login the virtual router[ip:%s]", timeoutInSeconds, mgmtNicIp)); return true; } @@ -108,25 +114,26 @@ public boolean run() { private void configAgentSsh() { Boolean passwordAuth = VirtualRouterGlobalConfig.SSH_LOGIN_PASSWORD.value(Boolean.class); String password = VirtualRouterGlobalConfig.VYOS_PASSWORD.value(); + String restartSshCmd = sshUser.equals("vyos") ? "service ssh restart" : "systemctl restart sshd"; String script; if (!passwordAuth) { - script = "sudo sed -i \"/PasswordAuthentication /c PasswordAuthentication no\" /etc/ssh/sshd_config\n"+ - "sudo service ssh restart\n"; + script = String.format("sudo sed -i \"/PasswordAuthentication /c PasswordAuthentication no\" /etc/ssh/sshd_config\n"+ + "sudo %s\n", restartSshCmd); } else { - script = " sudo sed -i \"/PasswordAuthentication /c PasswordAuthentication yes\" /etc/ssh/sshd_config\n"+ - "sudo service ssh restart\n"; + script = String.format("sudo sed -i \"/PasswordAuthentication /c PasswordAuthentication yes\" /etc/ssh/sshd_config\n"+ + "sudo %s\n", restartSshCmd); } script = String.format("echo \"%s\" > .ssh/authorized_keys\n %s", asf.getPublicKey(), script); try { new Ssh().shell(script - ).setTimeout(300).setPrivateKey(asf.getPrivateKey()).setUsername("vyos").setHostname(mgmtNicIp).setPort(sshPort).runErrorByExceptionAndClose(); + ).setTimeout(300).setPrivateKey(asf.getPrivateKey()).setUsername(sshUser).setHostname(mgmtNicIp).setPort(sshPort).runErrorByExceptionAndClose(); } catch (SshException e ) { /* ZSTAC-18352, try again with password when key fail */ new Ssh().shell(script - ).setTimeout(300).setPassword(password).setUsername("vyos").setHostname(mgmtNicIp).setPort(sshPort).runErrorByExceptionAndClose(); + ).setTimeout(300).setPassword(password).setUsername(sshUser).setHostname(mgmtNicIp).setPort(sshPort).runErrorByExceptionAndClose(); } try { @@ -139,14 +146,14 @@ protected Boolean call() { if (NetworkUtils.isRemotePortOpen(mgmtNicIp, sshPort, 2000)) { return true; } else { - throw new RuntimeException(String.format("unable to ssh in to the vyos[%s]", mgmtNicIp)); + throw new RuntimeException(String.format("unable to ssh in to the virtual router[%s]", mgmtNicIp)); } } }.run(); trigger.next(); } catch (Exception e) { - trigger.fail(operr("unable to ssh in to the vyos[%s] after configure ssh", mgmtNicIp)); + trigger.fail(operr("unable to ssh in to the virtual router[%s] after configure ssh", mgmtNicIp)); } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java index 10e6a8f25ba..d890e10ed33 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConnectFlow.java @@ -10,6 +10,7 @@ import org.zstack.core.asyncbatch.While; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; import org.zstack.core.thread.ThreadFacade; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.core.workflow.ShareFlow; @@ -29,6 +30,7 @@ import org.zstack.network.service.virtualrouter.lb.VirtualRouterLoadBalancerRefVO; import org.zstack.network.service.virtualrouter.lb.VirtualRouterLoadBalancerRefVO_; import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.tag.SystemTagCreator; import org.zstack.utils.DebugUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -43,6 +45,8 @@ import java.util.concurrent.TimeUnit; import static org.zstack.core.Platform.operr; +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; /** * Created by xing5 on 2016/10/31. @@ -64,27 +68,27 @@ public class VyosConnectFlow extends NoRollbackFlow { @Autowired private AnsibleFacade asf; - private void debug (String vrMgtIp, int timeout) { + private void debug (String vrMgtIp, String sshUser, int timeout) { int sshPort = VirtualRouterGlobalConfig.SSH_PORT.value(Integer.class); if (!NetworkUtils.isRemotePortOpen(vrMgtIp, sshPort, timeout)) { - logger.debug(String.format("vyos agent port %s is not opened on managment nic %s", + logger.debug(String.format("virtual router agent port %s is not opened on managment nic %s", sshPort, vrMgtIp)); return; } Ssh ssh1 = new Ssh(); - ssh1.setUsername("vyos").setPrivateKey(asf.getPrivateKey()).setPort(sshPort) + ssh1.setUsername(sshUser).setPrivateKey(asf.getPrivateKey()).setPort(sshPort) .setHostname(vrMgtIp).setTimeout(timeout); - SshResult ret1 = ssh1.command("sudo tail -n 300 /home/vyos/zvr/zvrboot.log").runAndClose(); + SshResult ret1 = ssh1.command(String.format("sudo tail -n 300 /home/%s/zvr/zvrboot.log", sshUser)).runAndClose(); if (ret1.getReturnCode() == 0) { - logger.debug(String.format("vyos bootup log %s", ret1.getStdout())); + logger.debug(String.format("virtual router bootup log %s", ret1.getStdout())); } else { - logger.debug(String.format("get vyos bootup log failed: %s", ret1.getStderr())); + logger.debug(String.format("get virtual router bootup log failed: %s", ret1.getStderr())); } Ssh ssh2 = new Ssh(); - ssh2.setUsername("vyos").setPrivateKey(asf.getPrivateKey()).setPort(sshPort) + ssh2.setUsername(sshUser).setPrivateKey(asf.getPrivateKey()).setPort(sshPort) .setHostname(vrMgtIp).setTimeout(timeout); - SshResult ret2 = ssh2.command("sudo tail -n 300 /home/vyos/zvr/zvrstartup.log").runAndClose(); + SshResult ret2 = ssh2.command(String.format("sudo tail -n 300 /home/%s/zvr/zvrstartup.log", sshUser)).runAndClose(); if (ret2.getReturnCode() == 0) { logger.debug(String.format("zvr startup log %s", ret2.getStdout())); } else { @@ -92,9 +96,9 @@ private void debug (String vrMgtIp, int timeout) { } Ssh ssh3 = new Ssh(); - ssh3.setUsername("vyos").setPrivateKey(asf.getPrivateKey()).setPort(sshPort) + ssh3.setUsername(sshUser).setPrivateKey(asf.getPrivateKey()).setPort(sshPort) .setHostname(vrMgtIp).setTimeout(timeout); - SshResult ret3 = ssh3.command("sudo tail -n 300 /home/vyos/zvr/zvr.log").runAndClose(); + SshResult ret3 = ssh3.command(String.format("sudo tail -n 300 /home/%s/zvr/zvr.log", sshUser)).runAndClose(); if (ret3.getReturnCode() == 0) { logger.debug(String.format("zvr log %s", ret3.getStdout())); } else { @@ -102,7 +106,7 @@ private void debug (String vrMgtIp, int timeout) { } Ssh ssh4 = new Ssh(); - ssh4.setUsername("vyos").setPrivateKey(asf.getPrivateKey()).setPort(sshPort) + ssh4.setUsername(sshUser).setPrivateKey(asf.getPrivateKey()).setPort(sshPort) .setHostname(vrMgtIp).setTimeout(timeout); SshResult ret4 = ssh4.command("ps aux | grep zvr").runAndClose(); if (ret4.getReturnCode() == 0) { @@ -161,10 +165,10 @@ public void run(final FlowTrigger trigger, Map data) { String url = vrMgr.buildUrl(mgmtNic.getIp(), VirtualRouterConstant.VR_INIT); int timeoutInSeconds = ApplianceVmGlobalConfig.CONNECT_TIMEOUT.value(Integer.class); - int interval = 30 ; /* seonds*/ + int interval = 120 ; /* seonds*/ List steps = new ArrayList<>(timeoutInSeconds/interval); - for (int i = 0; i < timeoutInSeconds/interval; i++) { + for (int i = 0; i <= timeoutInSeconds/interval; i++) { steps.add(i); } List errs = new ArrayList<>(); @@ -196,12 +200,44 @@ public void fail(ErrorCode err) { @Override public void success(InitRsp ret) { if (ret.isSuccess()) { - VirtualRouterMetadataStruct struct = new VirtualRouterMetadataStruct(); - struct.setVrUuid(vrUuid); - struct.setKernelVersion(ret.getKernelVersion()); - struct.setVyosVersion(ret.getVyosVersion()); - struct.setZvrVersion(ret.getZvrVersion()); - new VirtualRouterMetadataOperator().updateVirtualRouterMetadata(struct); + VirtualRouterMetadataStruct metadataStruct = new VirtualRouterMetadataStruct(); + VirtualRouterSoftwareVersionStruct versionStruct = new VirtualRouterSoftwareVersionStruct(); + metadataStruct.setVrUuid(vrUuid); + metadataStruct.setKernelVersion(ret.getKernelVersion()); + metadataStruct.setVyosVersion(ret.getVyosVersion()); + metadataStruct.setZvrVersion(ret.getZvrVersion()); + versionStruct.setVrUuid(vrUuid); + versionStruct.setSoftwareName("IPsec"); + versionStruct.setCurrentVersion(ret.getIpsecCurrentVersion()); + versionStruct.setLatestVersion(ret.getIpsecLatestVersion()); + if (ret.getVyosVersion() != null) { + String userName = null; + if (ret.getVyosVersion().equalsIgnoreCase(VirtualRouterConstant.X86_VPC_EULER_GUEST_OS_TYPE)) { + SQL.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, vrUuid) + .set(VirtualRouterVmVO_.guestOsType, VirtualRouterConstant.X86_VPC_EULER_GUEST_OS_TYPE).update(); + userName = VirtualRouterConstant.X86_VPC_EULER_GUEST_OS_USER; + } else if (ret.getVyosVersion().equalsIgnoreCase(VirtualRouterConstant.X86_VPC_VYOS_GUEST_OS_TYPE)) { + SQL.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, vrUuid) + .set(VirtualRouterVmVO_.guestOsType, VirtualRouterConstant.X86_VPC_VYOS_GUEST_OS_TYPE).update(); + userName = VirtualRouterConstant.X86_VPC_VYOS_GUEST_OS_USER; + } + if (ret.getVyosVersion().equalsIgnoreCase(VirtualRouterConstant.ARM_VPC_VYOS_GUEST_OS_TYPE)) { + SQL.New(VirtualRouterVmVO.class).eq(VirtualRouterVmVO_.uuid, vrUuid) + .set(VirtualRouterVmVO_.guestOsType, VirtualRouterConstant.ARM_VPC_VYOS_GUEST_OS_TYPE).update(); + userName = VirtualRouterConstant.ARM_VPC_VYOS_GUEST_OS_USER; + } + if(userName != null) { + SystemTagCreator creator = VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER.newSystemTagCreator(vrUuid); + creator.setTagByTokens(map( + e(VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER_TOKEN, userName) + )); + creator.inherent = true; + creator.recreate = true; + creator.create(); + } + } + new VirtualRouterMetadataOperator().updateVirtualRouterMetadata(metadataStruct); + new VirtualRouterSoftwareVersionOperator().updateVirtualRouterSoftwareVersion(versionStruct); errs.clear(); wcompl.allDone(); } else { @@ -248,17 +284,22 @@ public void handle(ErrorCode errCode, Map data) { @Override public void rollback(FlowRollback trigger, Map data) { final VirtualRouterVmInventory vr = (VirtualRouterVmInventory) data.get(VirtualRouterConstant.Param.VR.toString()); + final String vrUuid; VmNicInventory mgmtNic; if (vr != null) { mgmtNic = vr.getManagementNic(); + vrUuid = vr.getUuid(); } else { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); ApplianceVmInventory applianceVm = ApplianceVmInventory.valueOf(dbf.findByUuid(spec.getVmInventory().getUuid(), ApplianceVmVO.class)); mgmtNic = applianceVm.getManagementNic(); + vrUuid = spec.getVmInventory().getUuid(); DebugUtils.Assert(mgmtNic!=null, String.format("cannot find management nic for virtual router[uuid:%s, name:%s]", spec.getVmInventory().getUuid(), spec.getVmInventory().getName())); } - - debug(mgmtNic.getIp(), 30); + String vrUserTag = VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER.getTokenByResourceUuid( + vrUuid, VirtualRouterVmVO.class, VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER_TOKEN); + String sshUser = vrUserTag != null ? vrUserTag : "vyos"; //old vpc vrouter has no tag, that's vyos. + debug(mgmtNic.getIp(), sshUser, 30); trigger.rollback(); } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConstants.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConstants.java index 993cfd2d4e7..93941c5dacc 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConstants.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosConstants.java @@ -26,6 +26,9 @@ enum BootstrapInfoKey { String REPLACE_FIREWALL_WITH_IPTBALES = "SkipVyosIptables"; String HA_STATUS = "haStatus"; + String CONFIG_ENABLE_VYOS = "EnableVyosCmd"; + String HA_GROUP_UUID = "haGroupUuid"; + String ALLOW_PASSWORD_AUTH = "allowPasswordAuth"; /* in old version, vpc snat is disabled in mn node, but it's not delete in vyos node, which is fix in http://jira.zstack.io/browse/ZSTAC-27851 * so when upgrade before 3.9.0.0, mn will reconnect virtual router, during reconnection, the snat rules should be deleted*/ diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDeployAgentFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDeployAgentFlow.java index 89b0ce71521..7437e6728ab 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDeployAgentFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosDeployAgentFlow.java @@ -10,6 +10,7 @@ import org.zstack.core.db.DatabaseFacade; import org.zstack.core.thread.CancelablePeriodicTask; import org.zstack.core.thread.ThreadFacade; +import org.zstack.core.upgrade.UpgradeChecker; import org.zstack.header.core.workflow.FlowRollback; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; @@ -17,7 +18,7 @@ import org.zstack.header.vm.VmInstanceConstant.VmOperation; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmNicInventory; -import org.zstack.network.service.virtualrouter.VirtualRouterGlobalConfig; +import org.zstack.network.service.virtualrouter.*; import org.zstack.utils.*; import org.zstack.utils.function.Function; import org.zstack.utils.logging.CLogger; @@ -47,20 +48,69 @@ public class VyosDeployAgentFlow extends NoRollbackFlow { private DatabaseFacade dbf; @Autowired private ThreadFacade thdf; + @Autowired + private UpgradeChecker upgradeChecker; + + + private final String REMOTE_USER = "REMOTE_USER"; + private final String REMOTE_PASS = VirtualRouterGlobalConfig.VYOS_PASSWORD.value(); + private final int REMOTE_PORT = VirtualRouterGlobalConfig.SSH_PORT.value(Integer.class); + + private final String REMOTE_ZVR_DIR = "REMOTE_ZVR_DIR"; + private final String REMOTE_ZVR_BIN_PATH = "REMOTE_ZVR_BIN_PATH"; + private final String REMOTE_ZVRBOOT_BIN_PATH = "REMOTE_ZVRBOOT_BIN_PATH"; + + private String storeDataToMap(Map map, String key, String value) { + map.put(key, value); + return value; + } + + private String getRemoteUser(Map data) { + return (String) data.get(REMOTE_USER); + } + + private String getRemoteZvrDir(Map data) { + return (String) data.get(REMOTE_ZVR_DIR); + } + + private String getRemoteZvrBinPath(Map data) { + return (String) data.get(REMOTE_ZVR_BIN_PATH); + } + + private String getRemoteZvrbootBinPath(Map data) { + return (String) data.get(REMOTE_ZVRBOOT_BIN_PATH); + } + - private final static String REMOTE_ZVR_PATH = "/home/vyos/zvr.bin"; - private final static String REMOTE_ZVRBOOT_PATH = "/home/vyos/zvrboot.bin"; @Override public void run(FlowTrigger trigger, Map data) { + final String vrUuid = (String) data.get(VmInstanceConstant.Params.vmInstanceUuid.toString()); if (CoreGlobalProperty.UNIT_TEST_ON) { + // update vyos agent version when open grayScaleUpgrade + upgradeChecker.updateAgentVersion(vrUuid, VirtualRouterConstant.VIRTUAL_ROUTER_PROVIDER_TYPE, new VirtualRouterMetadataOperator().getManagementVersion(), new VirtualRouterMetadataOperator().getManagementVersion()); trigger.next(); return; } - boolean isReconnect = Boolean.parseBoolean((String) data.get(Params.isReconnect.toString())); + boolean fromApi = Boolean.parseBoolean(String.valueOf(data.get(Params.fromApi.toString()))); + boolean isReconnect = Boolean.parseBoolean(String.valueOf(data.get(Params.isReconnect.toString()))); + if (!fromApi && upgradeChecker.skipInnerDeployOrInitOnCurrentAgent(vrUuid)) { + trigger.next(); + return; + } + + String vrUserTag = VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER.getTokenByResourceUuid( + vrUuid, VirtualRouterVmVO.class, VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER_TOKEN); + String remoteUser = storeDataToMap(data, REMOTE_USER, vrUserTag != null ? vrUserTag : "vyos"); //old vpc vrouter has no tag, that's vyos. + String remoteZvrDir = storeDataToMap(data, REMOTE_ZVR_DIR, String.format("/home/%s/zvr", remoteUser)); + String remoteZvrBinPath = storeDataToMap(data, REMOTE_ZVR_BIN_PATH, String.format("/home/%s/zvr.bin", remoteUser)); + String remoteZvrBootBinPath = storeDataToMap(data, REMOTE_ZVRBOOT_BIN_PATH, String.format("/home/%s/zvrboot.bin", remoteUser)); - if (!isReconnect && !ApplianceVmGlobalConfig.DEPLOY_AGENT_ON_START.value(Boolean.class)) { + + if (!isReconnect && + !ApplianceVmGlobalConfig.DEPLOY_AGENT_ON_START.value(Boolean.class) && + !ApplianceVmSystemTags.APPLIANCEVM_DEPLOY_AGENT_ON_START.hasTag(vrUuid)) { // no need to deploy agent trigger.next(); return; @@ -90,33 +140,38 @@ public VmNicInventory call(VmNicInventory arg) { int timeoutInSeconds = ApplianceVmGlobalConfig.CONNECT_TIMEOUT.value(Integer.class); long timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(timeoutInSeconds); - int sshPort = VirtualRouterGlobalConfig.SSH_PORT.value(Integer.class); List errors = new ArrayList<>(); thdf.submitCancelablePeriodicTask(new CancelablePeriodicTask() { @Override public boolean run() { try { + boolean forceReboot = false; long now = System.currentTimeMillis(); if (now > timeout) { - trigger.fail(err(ApplianceVmErrors.UNABLE_TO_START, "vyos deploy agent failed, because %s", + trigger.fail(err(ApplianceVmErrors.UNABLE_TO_START, "virtual router deploy agent failed, because %s", errors.get(errors.size() -1))); return true; } - if (NetworkUtils.isRemotePortOpen(mgmtNicIp, sshPort, 2000)) { - if(isZvrMd5Changed(mgmtNicIp,sshPort)){ - deployAgent(sshPort); + if (NetworkUtils.isRemotePortOpen(mgmtNicIp, REMOTE_PORT, 2000)) { + if(isZvrMd5Changed(mgmtNicIp, REMOTE_PORT, data)){ + logger.debug(String.format("will deploy virtual router agent by remote user[%s] from management", remoteUser)); + deployAgent(REMOTE_PORT); + forceReboot = true; + } + rebootAgent(REMOTE_PORT, forceReboot); + if (ApplianceVmSystemTags.APPLIANCEVM_DEPLOY_AGENT_ON_START.hasTag(vrUuid)) { + ApplianceVmSystemTags.APPLIANCEVM_DEPLOY_AGENT_ON_START.deleteInherentTag(vrUuid); } - rebootAgent(sshPort); trigger.next(); return true; } else { - errors.add(new Throwable(String.format("vyos agent port %s is not opened on managment nic %s", sshPort, mgmtNicIp))); + errors.add(new Throwable(String.format("virtual router agent port %s is not opened on managment nic %s", REMOTE_PORT, mgmtNicIp))); return false; } } catch (Throwable t) { - logger.warn("vyos deploy agent failed", t); + logger.warn("virtual router deploy agent failed", t); errors.add(t); return false; } @@ -126,48 +181,50 @@ private void deployAgent(int port) { try { new Ssh().setTimeout(300).scpUpload( PathUtil.findFileOnClassPath("ansible/zvr/zvr.bin", true).getAbsolutePath(), - "/home/vyos/zvr.bin" + remoteZvrBinPath ).scpUpload( PathUtil.findFileOnClassPath("ansible/zvr/zvrboot.bin", true).getAbsolutePath(), - "/home/vyos/zvrboot.bin" + remoteZvrBootBinPath ).scpUpload( PathUtil.findFileOnClassPath("ansible/zvr/version", true).getAbsolutePath(), - "/home/vyos/zvr/mn_zvr_version" - ).setPrivateKey(asf.getPrivateKey()).setUsername("vyos").setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); + String.format("%s/mn_zvr_version", remoteZvrDir) + ).setPrivateKey(asf.getPrivateKey()).setUsername(remoteUser).setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); } catch (SshException e ) { /* ZSTAC-18352, try again with password when key fail */ - String password = VirtualRouterGlobalConfig.VYOS_PASSWORD.value(); new Ssh().setTimeout(300).scpUpload( PathUtil.findFileOnClassPath("ansible/zvr/zvr.bin", true).getAbsolutePath(), - "/home/vyos/zvr.bin" + remoteZvrBinPath ).scpUpload( PathUtil.findFileOnClassPath("ansible/zvr/zvrboot.bin", true).getAbsolutePath(), - "/home/vyos/zvrboot.bin" + remoteZvrBootBinPath ).scpUpload( PathUtil.findFileOnClassPath("ansible/zvr/version", true).getAbsolutePath(), - "/home/vyos/zvr/mn_zvr_version" - ).setPassword(password).setUsername("vyos").setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); + String.format("%s/mn_zvr_version", remoteZvrDir) + ).setPassword(REMOTE_PASS).setUsername(remoteUser).setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); } + + // update vyos agent version when open grayScaleUpgrade + upgradeChecker.updateAgentVersion(vrUuid, VirtualRouterConstant.VIRTUAL_ROUTER_PROVIDER_TYPE, new VirtualRouterMetadataOperator().getManagementVersion(), new VirtualRouterMetadataOperator().getManagementVersion()); } - private void rebootAgent(int port) { - String script = "sudo bash /home/vyos/zvrboot.bin\n" + - "sudo bash /home/vyos/zvr.bin\n" + - "sudo bash /home/vyos/zvr/ssh/zvr-reboot.sh\n"; + private void rebootAgent(int port, boolean forceReboot) { + String script = String.format("sudo bash %s\n" + + "sudo bash %s\n" + + "sudo bash %s/ssh/zvr-reboot.sh %s\n", + remoteZvrBootBinPath, remoteZvrBinPath, remoteZvrDir, forceReboot); try { new Ssh().shell(script - ).setTimeout(300).setPrivateKey(asf.getPrivateKey()).setUsername("vyos").setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); + ).setTimeout(300).setPrivateKey(asf.getPrivateKey()).setUsername(remoteUser).setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); } catch (SshException e ) { /* ZSTAC-18352, try again with password when key fail */ - String password = VirtualRouterGlobalConfig.VYOS_PASSWORD.value(); new Ssh().shell(script - ).setTimeout(300).setPassword(password).setUsername("vyos").setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); + ).setTimeout(300).setPassword(REMOTE_PASS).setUsername(remoteUser).setHostname(mgmtNicIp).setPort(port).runErrorByExceptionAndClose(); } } @@ -189,10 +246,10 @@ public String getName() { }); } - private boolean isZvrMd5Changed(String ip, int port){ + private boolean isZvrMd5Changed(String ip, int port, Map data){ int interval = 30 ; Ssh ssh = new Ssh(); - ssh.setUsername("vyos") + ssh.setUsername(getRemoteUser(data)) .setPrivateKey(asf.getPrivateKey()) .setPort(port) .setHostname(ip) @@ -206,7 +263,7 @@ private boolean isZvrMd5Changed(String ip, int port){ try { - ssh.command(String.format("sudo -S md5sum %s 2>/dev/null", REMOTE_ZVR_PATH)); + ssh.command(String.format("sudo -S md5sum %s 2>/dev/null", getRemoteZvrBinPath(data))); SshResult ret = ssh.run(); if (ret.getReturnCode() == 0) { remoteZvrMd5 = ret.getStdout().split(" ")[0]; @@ -219,11 +276,11 @@ private boolean isZvrMd5Changed(String ip, int port){ if (!remoteZvrMd5.equals(localZvrMd5)) { logger.debug(String.format("file MD5 changed, local[%s, md5:%s] remote[%s, md5: %s]", localZvrPath, - localZvrMd5, REMOTE_ZVR_PATH, remoteZvrMd5)); + localZvrMd5, getRemoteZvrBinPath(data), remoteZvrMd5)); return true; } - ssh.command(String.format("sudo -S md5sum %s 2>/dev/null", REMOTE_ZVRBOOT_PATH)); + ssh.command(String.format("sudo -S md5sum %s", getRemoteZvrbootBinPath(data))); ret = ssh.run(); if (ret.getReturnCode() == 0) { remoteZvrbootMd5 = ret.getStdout().split(" ")[0]; @@ -236,12 +293,12 @@ private boolean isZvrMd5Changed(String ip, int port){ if (!remoteZvrbootMd5.equals(localZvrbootMd5)) { logger.debug(String.format("file MD5 changed, local[%s, md5:%s] remote[%s, md5: %s]", localZvrBootPath, - localZvrbootMd5, REMOTE_ZVRBOOT_PATH, remoteZvrbootMd5)); + localZvrbootMd5, getRemoteZvrbootBinPath(data), remoteZvrbootMd5)); return true; } }catch (SshException e ) { - logger.debug(String.format("unable to check vyos[ip:%s, port:%s] zvr md5", ip, port, e.getMessage())); + logger.debug(String.format("unable to check virtual router[ip:%s, port:%s] zvr md5", ip, port, e.getMessage())); }finally { ssh.close(); } @@ -275,29 +332,28 @@ public VmNicInventory call(VmNicInventory arg) { mgmtNicIp = (String) data.get(Params.managementNicIp.toString()); } - debug(mgmtNicIp, 30); + debug(mgmtNicIp, 30, data); trigger.rollback(); } - private void debug (String vrMgtIp, int timeout) { - int sshPort = VirtualRouterGlobalConfig.SSH_PORT.value(Integer.class); - if (!NetworkUtils.isRemotePortOpen(vrMgtIp, sshPort, timeout)) { - logger.debug(String.format("vyos agent port %s is not opened on managment nic %s", - sshPort, vrMgtIp)); + private void debug (String vrMgtIp, int timeout, Map data) { + if (!NetworkUtils.isRemotePortOpen(vrMgtIp, REMOTE_PORT, timeout)) { + logger.debug(String.format("virtual router agent port %s is not opened on managment nic %s", + REMOTE_PORT, vrMgtIp)); return; } Ssh ssh1 = new Ssh(); - ssh1.setUsername("vyos").setPrivateKey(asf.getPrivateKey()).setPort(sshPort) + ssh1.setUsername(getRemoteUser(data)).setPrivateKey(asf.getPrivateKey()).setPort(REMOTE_PORT) .setHostname(vrMgtIp).setTimeout(timeout); - SshResult ret1 = ssh1.command("sudo tail -n 300 /home/vyos/zvr/zvrReboot.log").runAndClose(); + SshResult ret1 = ssh1.command(String.format("sudo tail -n 300 %s/zvrReboot.log", getRemoteZvrDir(data))).runAndClose(); if (ret1.getReturnCode() == 0) { - logger.debug(String.format("vyos reboot log %s", ret1.getStdout())); + logger.debug(String.format("virtual router reboot log %s", ret1.getStdout())); } else { - logger.debug(String.format("get vyos reboot log failed: %s", ret1.getStderr())); + logger.debug(String.format("get virtual router reboot log failed: %s", ret1.getStderr())); } Ssh ssh2 = new Ssh(); - ssh2.setUsername("vyos").setPrivateKey(asf.getPrivateKey()).setPort(sshPort) + ssh2.setUsername(getRemoteUser(data)).setPrivateKey(asf.getPrivateKey()).setPort(REMOTE_PORT) .setHostname(vrMgtIp).setTimeout(timeout); SshResult ret2 = ssh2.command("sudo tail -n 300 /tmp/agentRestart.log").runAndClose(); if (ret2.getReturnCode() == 0) { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosEipBackend.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosEipBackend.java index c813eb438ca..d88a2603947 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosEipBackend.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosEipBackend.java @@ -11,17 +11,11 @@ import org.zstack.header.network.l3.L3NetworkVO; import org.zstack.header.network.l3.L3NetworkVO_; import org.zstack.header.network.service.NetworkServiceProviderType; -import org.zstack.header.vm.VmInstanceVO; -import org.zstack.header.vm.VmInstanceVO_; -import org.zstack.header.vm.VmNicInventory; -import org.zstack.header.vm.VmNicVO; +import org.zstack.header.vm.*; import org.zstack.network.service.NetworkServiceManager; import org.zstack.network.service.eip.EipConstant; import org.zstack.network.service.eip.GetEipAttachableL3UuidsForVmNicExtensionPoint; -import org.zstack.network.service.virtualrouter.VirtualRouterGlobalProperty; -import org.zstack.network.service.virtualrouter.VirtualRouterManager; -import org.zstack.network.service.virtualrouter.VirtualRouterStruct; -import org.zstack.network.service.virtualrouter.VirtualRouterVmInventory; +import org.zstack.network.service.virtualrouter.*; import org.zstack.network.service.virtualrouter.eip.VirtualRouterEipBackend; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGetVersionFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGetVersionFlow.java index 02bffd7ad6e..c5e8adc8bc7 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGetVersionFlow.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGetVersionFlow.java @@ -76,6 +76,7 @@ public VmNicInventory call(VmNicInventory arg) { } } + flowData.put(VmInstanceConstant.Params.vmInstanceUuid.toString(), vrUuid); vyosVersionManager.vyosRouterVersionCheck(vrUuid, new ReturnValueCompletion(flowTrigger) { @Override public void fail(ErrorCode errorCode) { diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGlobalConfig.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGlobalConfig.java index c3604f3da19..8d91aab7231 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGlobalConfig.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosGlobalConfig.java @@ -4,8 +4,10 @@ import org.zstack.core.config.GlobalConfigDefinition; import org.zstack.core.config.GlobalConfigValidation; import org.zstack.header.vm.VmInstanceVO; +import org.zstack.network.service.lb.LoadBalancerListenerVO; import org.zstack.resourceconfig.BindResourceConfig; import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.network.service.lb.LoadBalancerVO; /** * Created by shixin.ruan on 18/03/09. @@ -24,4 +26,21 @@ public class VyosGlobalConfig { @GlobalConfigValidation @BindResourceConfig({VmInstanceVO.class}) public static GlobalConfig AUTO_RESTART_IPSEC = new GlobalConfig(CATEGORY, "auto.restart.ipsec"); + + @GlobalConfigValidation + @BindResourceConfig({LoadBalancerVO.class}) + public static GlobalConfig ENABLE_HAPROXY_LOG = new GlobalConfig(CATEGORY, "enable.haproxy.log"); + + // the priority: listener > loadbalancer > vpc + @GlobalConfigValidation + @BindResourceConfig({VmInstanceVO.class, LoadBalancerVO.class, LoadBalancerListenerVO.class}) + public static GlobalConfig ENABLE_LOADBALANCER_FULL_LOG = new GlobalConfig(CATEGORY, "enable.loadbalancer.full.log"); + + @GlobalConfigValidation + @BindResourceConfig({LoadBalancerVO.class}) + public static GlobalConfig ENABLE_LOADBALANCER_STATS_LOG = new GlobalConfig(CATEGORY, "enable.loadbalancer.stats.log"); + + @GlobalConfigValidation + @BindResourceConfig({VmInstanceVO.class}) + public static GlobalConfig ENABLE_VYOS_CMD = new GlobalConfig(CATEGORY, "enable.vyos.cmd"); } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKeepalivedCommands.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKeepalivedCommands.java new file mode 100644 index 00000000000..2dd9d4051ed --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKeepalivedCommands.java @@ -0,0 +1,148 @@ +package org.zstack.network.service.virtualrouter.vyos; + +import org.zstack.core.upgrade.GrayVersion; +import org.zstack.network.service.virtualrouter.VirtualRouterCommands; + +import java.util.List; + +public class VyosKeepalivedCommands { + public static String VYOS_HA_ENABLE_PATH = "/enableVyosha"; + public static String SYNC_VPC_ROUTER_HA_PATH = "/syncVpcRouterHa"; + public static String RESTART_KEEPALIVED_PATH = "/restartKeepalived"; + + static public class VyosHaVip{ + @GrayVersion(value = "5.0.0") + public String nicMac; + @GrayVersion(value = "5.0.0") + public String nicVip; + @GrayVersion(value = "5.0.0") + public String netmask; + @GrayVersion(value = "5.0.0") + public String category; + @GrayVersion(value = "5.1.0") + public Integer prefixLen; + } + + public static class VyosHaEnableCmd extends VirtualRouterCommands.AgentCommand { + @GrayVersion(value = "5.0.0") + public Integer keepalive; + @GrayVersion(value = "5.0.0") + public String heartbeatNic; + @GrayVersion(value = "5.0.0") + public String peerIp; + @GrayVersion(value = "5.1.0") + public String peerIpV6; + @GrayVersion(value = "5.0.0") + public String localIp; + @GrayVersion(value = "5.1.0") + public String localIpV6; + @GrayVersion(value = "5.0.0") + public List monitors; + @GrayVersion(value = "5.0.0") + public List vips; + @GrayVersion(value = "5.0.0") + public String callbackUrl; + + public Integer getKeepalive() { + return keepalive; + } + + public void setKeepalive(Integer keepalive) { + this.keepalive = keepalive; + } + + public String getHeartbeatNic() { + return heartbeatNic; + } + + public void setHeartbeatNic(String heartbeatNic) { + this.heartbeatNic = heartbeatNic; + } + + public String getPeerIp() { + return peerIp; + } + + public void setPeerIp(String peerIp) { + this.peerIp = peerIp; + } + + public String getPeerIpV6 () { + return peerIpV6; + } + + public void setPeerIpV6(String peerIpV6) { + this.peerIpV6 = peerIpV6; + } + + public List getMonitors() { + return monitors; + } + + public void setMonitors(List monitors) { + this.monitors = monitors; + } + + public List getVips() { + return vips; + } + + public void setVips(List vips) { + this.vips = vips; + } + + public String getLocalIp() { + return localIp; + } + + public void setLocalIp(String localIp) { + this.localIp = localIp; + } + + public String getLocalIpV6() { + return localIpV6; + } + + public void setLocalIpV6(String localIpV6) { + this.localIpV6 = localIpV6; + } + + public String getCallbackUrl() { + return callbackUrl; + } + + public void setCallbackUrl(String callbackUrl) { + this.callbackUrl = callbackUrl; + } + } + + public static class VpcRouterHaStatusCmd { + public String virtualRouterUuid; + public String haStatus; + } + + public static class SyncVpcRouterHaCmd extends VirtualRouterCommands.AgentCommand { + } + + public static class RestartKeepalivedCmd extends VirtualRouterCommands.AgentCommand { + } + + public static class VyosHaEnableRsp extends VirtualRouterCommands.AgentResponse { + } + + public static class SyncVpcRouterHaRsp extends VirtualRouterCommands.AgentResponse { + @GrayVersion(value = "5.0.0") + private String haStatus; + + public String getHaStatus() { + return haStatus; + } + + public void setHaStatus(String haStatus) { + this.haStatus = haStatus; + } + } + + public static class RestartKeepalivedRsp extends VirtualRouterCommands.AgentResponse { + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKvmVmBaseFactory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKvmVmBaseFactory.java new file mode 100644 index 00000000000..a02127f0cb7 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKvmVmBaseFactory.java @@ -0,0 +1,32 @@ +package org.zstack.network.service.virtualrouter.vyos; + +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.appliancevm.ApplianceVmType; +import org.zstack.appliancevm.kvm.KvmApplianceVmSubTypeFactory; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.kvm.KVMConstant; +import org.zstack.kvm.KVMGlobalConfig; +import org.zstack.network.service.virtualrouter.VirtualRouterApplianceVmFactory; +import org.zstack.resourceconfig.ResourceConfig; +import org.zstack.resourceconfig.ResourceConfigFacade; + +public class VyosKvmVmBaseFactory implements KvmApplianceVmSubTypeFactory { + @Autowired + private ResourceConfigFacade rcf; + + @Override + public ApplianceVmType getApplianceVmType() { + return VirtualRouterApplianceVmFactory.type; + } + + @Override + public void createHypervisorBasedConfigurations(VmInstanceSpec spec) { + // set VPC router's CPU mode to default NONE + ResourceConfig rc = rcf.getResourceConfig(KVMGlobalConfig.NESTED_VIRTUALIZATION.getIdentity()); + rc.updateValue(spec.getVmInventory().getUuid(), KVMConstant.CPU_MODE_NONE); + + // set VPC log to File + rc = rcf.getResourceConfig(KVMGlobalConfig.REDIRECT_CONSOLE_LOG_TO_FILE.getIdentity()); + rc.updateValue(spec.getVmInventory().getUuid(), Boolean.TRUE.toString()); + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKvmVmFactory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKvmVmFactory.java new file mode 100644 index 00000000000..9f5e91d6ed0 --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosKvmVmFactory.java @@ -0,0 +1,10 @@ +package org.zstack.network.service.virtualrouter.vyos; + +import org.zstack.appliancevm.ApplianceVmType; + +public class VyosKvmVmFactory extends VyosKvmVmBaseFactory { + @Override + public ApplianceVmType getApplianceVmType() { + return VyosVmFactory.applianceVmType; + } +} diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java index 849f77749eb..33eec9f32fd 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVersionVersionManagerImpl.java @@ -1,19 +1,10 @@ package org.zstack.network.service.virtualrouter.vyos; -import org.springframework.beans.factory.annotation.Autowired; -import org.zstack.core.CoreGlobalProperty; -import org.zstack.core.cloudbus.CloudBus; -import org.zstack.core.db.DatabaseFacade; -import org.zstack.core.timeout.ApiTimeoutManager; import org.zstack.header.core.ReturnValueCompletion; -import org.zstack.header.rest.RESTFacade; import org.zstack.network.service.virtualrouter.*; import org.zstack.utils.Utils; import org.zstack.utils.VersionComparator; import org.zstack.utils.logging.CLogger; -import org.zstack.utils.path.PathUtil; - -import java.io.*; public class VyosVersionVersionManagerImpl implements VyosVersionManager { private final static CLogger logger = Utils.getLogger(VyosVersionVersionManagerImpl.class); @@ -22,7 +13,7 @@ public class VyosVersionVersionManagerImpl implements VyosVersionManager { public void vyosRouterVersionCheck(String vrUuid, ReturnValueCompletion completion) { VyosVersionCheckResult result = new VyosVersionCheckResult(); - String managementVersion = getManagementVersion(); + String managementVersion = new VirtualRouterMetadataOperator().getManagementVersion(); if (managementVersion == null) { completion.success(result); return; @@ -60,33 +51,4 @@ public void vyosRouterVersionCheck(String vrUuid, ReturnValueCompletion completion) { struct.setApplianceVmType(VyosConstants.VYOS_VM_TYPE); @@ -23,4 +28,34 @@ protected void acquireVirtualRouterVm(VirtualRouterStruct struct, ReturnValueCom public String getServiceProviderTypeForVip() { return VyosConstants.VYOS_ROUTER_PROVIDER_TYPE; } + + @Override + public ApplianceVmType getApplianceVmType() { + return ApplianceVmType.valueOf(VyosConstants.VYOS_VM_TYPE); + } + + @Override + public void attachNetworkService(String vrUuid, List vipUuids) { + super.attachNetworkService(vrUuid, vipUuids); + } + + @Override + public void detachNetworkService(String vrUuid, List vipUuids) { + super.detachNetworkService(vrUuid, vipUuids); + } + + @Override + public List getVrUuidsByNetworkService(String vipUuid) { + return super.getVrUuidsByNetworkService(vipUuid); + } + + @Override + public List getAllVrUuidsByNetworkService(String vipUuid) { + return super.getAllVrUuidsByNetworkService(vipUuid); + } + + @Override + public List getVipUuidsByRouterUuid(String vrUuid) { + return super.getVipUuidsByRouterUuid(vrUuid); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVm.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVm.java index fa0fc324393..8dc1e4a947d 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVm.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVm.java @@ -5,20 +5,35 @@ import org.zstack.appliancevm.ApplianceVmRefreshFirewallMsg; import org.zstack.appliancevm.ApplianceVmRefreshFirewallReply; import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.Q; +import org.zstack.header.core.Completion; import org.zstack.header.core.workflow.Flow; import org.zstack.header.core.workflow.FlowChain; +import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; import org.zstack.header.host.HypervisorType; -import org.zstack.network.service.virtualrouter.VirtualRouter; -import org.zstack.network.service.virtualrouter.VirtualRouterVmVO; +import org.zstack.header.message.MessageReply; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmNicVO; +import org.zstack.network.service.vip.VipVO; +import org.zstack.network.service.vip.VipVO_; +import org.zstack.network.service.virtualrouter.*; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.network.NetworkUtils; import java.util.ArrayList; import java.util.List; +import static org.zstack.core.Platform.operr; + /** * Created by xing5 on 2016/10/31. */ public class VyosVm extends VirtualRouter { + private static final CLogger logger = Utils.getLogger(VyosVm.class); + @Autowired private VyosVmFactory vyosf; @@ -32,6 +47,7 @@ protected List createBootstrapFlows(HypervisorType hvType) { flows.add(apvmf.createBootstrapFlow(hvType)); if (!CoreGlobalProperty.UNIT_TEST_ON) { flows.add(new VyosGetVersionFlow()); + flows.add(new VyosWaitAgentStartFlow()); flows.add(new VyosDeployAgentFlow()); } @@ -90,4 +106,37 @@ protected void handle(final ApplianceVmAsyncHttpCallMsg msg) { // vyos doesn't need appliance vm throw new CloudRuntimeException("should not be called"); } + + public void configureKeepalived(VyosKeepalivedCommands.VyosHaEnableCmd cmd, + Completion completion) { + if (!vr.isHaEnabled()) { + completion.success(); + } + + VirtualRouterAsyncHttpCallMsg msg = new VirtualRouterAsyncHttpCallMsg(); + msg.setPath(VyosKeepalivedCommands.VYOS_HA_ENABLE_PATH); + msg.setCommand(cmd); + msg.setVmInstanceUuid(vr.getUuid()); + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vr.getUuid()); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + VirtualRouterAsyncHttpCallReply re = reply.castReply(); + VyosKeepalivedCommands.VyosHaEnableRsp ret = re.toResponse(VyosKeepalivedCommands.VyosHaEnableRsp.class); + if (!ret.isSuccess()) { + ErrorCode err = operr("failed to enable ha on virtual router[uuid:%s], %s", + vr.getUuid(), ret.getError()); + completion.fail(err); + } else { + logger.debug(String.format("enable ha on virtual router[uuid:%s] successfully", vr)); + completion.success(); + } + } + }); + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmBaseFactory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmBaseFactory.java index 801948fca1f..63db32086b4 100755 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmBaseFactory.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmBaseFactory.java @@ -2,11 +2,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.appliancevm.*; +import org.zstack.appliancevm.ApplianceVmConstant.BootstrapParams; import org.zstack.core.Platform; import org.zstack.core.ansible.AnsibleFacade; import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.config.GlobalConfigException; import org.zstack.core.config.GlobalConfigValidatorExtensionPoint; +import org.zstack.header.network.l2.*; import org.zstack.network.service.virtualrouter.VirtualRouterConstant; import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.core.db.DatabaseFacade; @@ -18,10 +20,6 @@ import org.zstack.header.core.workflow.FlowChain; import org.zstack.header.managementnode.PrepareDbInitialValueExtensionPoint; import org.zstack.header.network.NetworkException; -import org.zstack.header.network.l2.APICreateL2NetworkMsg; -import org.zstack.header.network.l2.L2NetworkConstant; -import org.zstack.header.network.l2.L2NetworkCreateExtensionPoint; -import org.zstack.header.network.l2.L2NetworkInventory; import org.zstack.header.network.service.NetworkServiceProviderL2NetworkRefVO; import org.zstack.header.network.service.NetworkServiceProviderVO; import org.zstack.header.network.service.NetworkServiceProviderVO_; @@ -174,7 +172,7 @@ public ApplianceVm getSubApplianceVm(ApplianceVmVO apvm) { return new VyosVm(vr); } - private void buildWorkFlowBuilder() { + protected void buildWorkFlowBuilder() { postCreateFlowsBuilder = FlowChainBuilder.newBuilder().setFlowClassNames(vyosPostCreateFlows).construct(); postStartFlowsBuilder = FlowChainBuilder.newBuilder().setFlowClassNames(vyosPostStartFlows).construct(); postRebootFlowsBuilder = FlowChainBuilder.newBuilder().setFlowClassNames(vyosPostRebootFlows).construct(); @@ -255,6 +253,11 @@ public void afterCreateL2Network(L2NetworkInventory l2Network) { return; } + VSwitchType vSwitchType = VSwitchType.valueOf(l2Network.getvSwitchType()); + if (vSwitchType.getSdnControllerType() != null) { + return; + } + NetworkServiceProviderL2NetworkRefVO ref = new NetworkServiceProviderL2NetworkRefVO(); ref.setNetworkServiceProviderUuid(providerVO.getUuid()); ref.setL2NetworkUuid(l2Network.getUuid()); @@ -278,12 +281,23 @@ public void applianceVmPrepareBootstrapInfo(VmInstanceSpec spec, Map l3Uuids = (List)info.get(ApplianceVmConstant.BootstrapParams.additionalL3Uuids.toString()); if (rcf.getResourceConfigValue(VyosGlobalConfig.CONFIG_FIREWALL_WITH_IPTABLES, l3Uuids.get(0), Boolean.class)) { info.put(VyosConstants.REPLACE_FIREWALL_WITH_IPTBALES, true); } + + if (rcf.getResourceConfigValue(VyosGlobalConfig.ENABLE_VYOS_CMD, spec.getVmInventory().getUuid(), Boolean.class)) { + info.put(VyosConstants.CONFIG_ENABLE_VYOS, true); + } else { + info.put(VyosConstants.CONFIG_ENABLE_VYOS, false); + } + + Boolean passwordAuth = VirtualRouterGlobalConfig.SSH_LOGIN_PASSWORD.value(Boolean.class); + info.put(VyosConstants.ALLOW_PASSWORD_AUTH, passwordAuth ? "yes" : "no"); info.put(VirtualRouterConstant.TC_FOR_VIPQOS, rcf.getResourceConfigValue(VirtualRouterGlobalConfig.TC_FOR_VIPQOS, spec.getVmInventory().getUuid(), Boolean.class)); + info.put(ApplianceVmConstant.ABNORMAL_FILE_MAX_SIZE, ApplianceVmGlobalConfig.ABNORMAL_FILE_MAX_SIZE.value(Integer.class)); } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmFactory.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmFactory.java index ec21492c1bd..69aa5b0155e 100644 --- a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmFactory.java +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosVmFactory.java @@ -2,12 +2,21 @@ import org.springframework.beans.factory.annotation.Autowired; import org.zstack.appliancevm.ApplianceVmType; +import org.zstack.appliancevm.ApplianceVmVO; +import org.zstack.appliancevm.ApvmCascadeFilterExtensionPoint; +import org.zstack.core.cascade.CascadeAction; import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.network.l3.IpRangeVO; +import org.zstack.header.network.l3.L3NetworkVO; +import org.zstack.header.network.l3.UsedIpInventory; +import org.zstack.header.network.service.NetworkServiceType; +import org.zstack.header.vm.VmNicInventory; import org.zstack.network.service.lb.LoadBalancerConstants; import org.zstack.network.service.vip.VipGetUsedPortRangeExtensionPoint; import org.zstack.network.service.vip.VipVO; import org.zstack.network.service.virtualrouter.VirtualRouterGlobalConfig; import org.zstack.network.service.virtualrouter.VirtualRouterGlobalProperty; +import org.zstack.network.service.virtualrouter.VirtualRouterManagerImpl; import org.zstack.utils.RangeSet; import org.zstack.utils.Utils; import org.zstack.utils.VipUseForList; @@ -19,12 +28,14 @@ /** * Created by weiwang on 19/09/2017 */ -public class VyosVmFactory extends VyosVmBaseFactory implements VipGetUsedPortRangeExtensionPoint { +public class VyosVmFactory extends VyosVmBaseFactory implements VipGetUsedPortRangeExtensionPoint, ApvmCascadeFilterExtensionPoint { private static final CLogger logger = Utils.getLogger(VyosVmFactory.class); public static ApplianceVmType applianceVmType = new ApplianceVmType(VyosConstants.VYOS_VM_TYPE); @Autowired private DatabaseFacade dbf; + @Autowired + private VirtualRouterManagerImpl vrMgr; @Override public ApplianceVmType getApplianceVmType() { @@ -39,13 +50,14 @@ public RangeSet getVipUsePortRange(String vipUuid, String protocol, VipUseForLis VipVO vipVO = dbf.findByUuid(vipUuid, VipVO.class); /* system vip is the vip of public ip of vpc or vpc ha group */ + boolean hasSnat = vipVO.getServicesTypes().contains(NetworkServiceType.SNAT.toString()); if (vipVO.isSystem()) { - if (protocol.equalsIgnoreCase(LoadBalancerConstants.LB_PROTOCOL_UDP)){ + if (protocol.equalsIgnoreCase(LoadBalancerConstants.LB_PROTOCOL_UDP) && hasSnat){ portRanges.add(new RangeSet.Range(VyosConstants.DNS_PORT, VyosConstants.DNS_PORT, true)); portRanges.add(new RangeSet.Range(VyosConstants.NTP_PORT, VyosConstants.NTP_PORT, true)); } - if (protocol.equalsIgnoreCase(LoadBalancerConstants.LB_PROTOCOL_TCP)){ + if (protocol.equalsIgnoreCase(LoadBalancerConstants.LB_PROTOCOL_TCP) && hasSnat){ portRanges.add(new RangeSet.Range(VyosConstants.DNS_PORT, VyosConstants.DNS_PORT, true)); int sshPort = VirtualRouterGlobalConfig.SSH_PORT.value(Integer.class); @@ -58,4 +70,31 @@ public RangeSet getVipUsePortRange(String vipUuid, String protocol, VipUseForLis return portRangeList; } + + @Override + public List filterApplianceVmCascade(List applianceVmVOS, CascadeAction action, + String parentIssuer, + List parentIssuerUuids, + List toDeleteNics, + List toDeleteIps) { + logger.debug(String.format("filter appliance vm type %s with parentIssuer [type: %s, uuids: %s]", + VyosConstants.VYOS_VM_TYPE, parentIssuer, parentIssuerUuids)); + + if (parentIssuer.equals(L3NetworkVO.class.getSimpleName())) { + List vos = vrMgr.applianceVmsToBeDeleted(applianceVmVOS, parentIssuerUuids); + + applianceVmVOS.removeAll(vos); + toDeleteNics.addAll(vrMgr.applianceVmsAdditionalPublicNic(applianceVmVOS, parentIssuerUuids)); + + return vos; + } else if (parentIssuer.equals(IpRangeVO.class.getSimpleName())) { + List vos = vrMgr.applianceVmsToBeDeletedByIpRanges(applianceVmVOS, parentIssuerUuids); + applianceVmVOS.removeAll(vos); + toDeleteNics.addAll(VmNicInventory.valueOf(vrMgr.applianceVmsToDeleteNicByIpRanges(applianceVmVOS, parentIssuerUuids))); + + return vos; + } else { + return applianceVmVOS; + } + } } diff --git a/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosWaitAgentStartFlow.java b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosWaitAgentStartFlow.java new file mode 100644 index 00000000000..d861105cd5d --- /dev/null +++ b/plugin/virtualRouterProvider/src/main/java/org/zstack/network/service/virtualrouter/vyos/VyosWaitAgentStartFlow.java @@ -0,0 +1,108 @@ +package org.zstack.network.service.virtualrouter.vyos; + +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.appliancevm.ApplianceVmInventory; +import org.zstack.appliancevm.ApplianceVmVO; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.core.workflow.*; +import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.rest.RESTFacade; +import org.zstack.header.vm.VmInstanceConstant; +import org.zstack.header.vm.VmInstanceSpec; +import org.zstack.header.vm.VmNicInventory; +import org.zstack.network.service.virtualrouter.*; +import org.zstack.tag.SystemTagCreator; +import org.zstack.utils.DebugUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import static org.zstack.utils.CollectionDSL.e; +import static org.zstack.utils.CollectionDSL.map; + +/** + * Created by shixin on 2022/06/15. + */ +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class VyosWaitAgentStartFlow extends NoRollbackFlow { + private static final CLogger logger = Utils.getLogger(VyosWaitAgentStartFlow.class); + + @Autowired + private VirtualRouterManager vrMgr; + @Autowired + private RESTFacade restf; + @Autowired + private DatabaseFacade dbf; + + public void updateVrLoginUser(String vrUuid, boolean isVyos){ + SystemTagCreator creator = VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER.newSystemTagCreator(vrUuid); + creator.setTagByTokens(map( + e(VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER_TOKEN, isVyos ? "vyos" : "zstack") + )); + creator.inherent = true; + creator.recreate = true; + creator.create(); + logger.debug("creator done"); + } + + /* this flow is called before VyosDeployAgentFlow, because: + * 1. vyos vm startup, zvrboot will reboot vyos agent + * 2. VyosDeployAgentFlow may also reboot vyos agent, + * 3. we must keep #1 finished before #2 + * */ + @Override + public void run(FlowTrigger trigger, Map data) { + final VirtualRouterVmInventory vr = (VirtualRouterVmInventory) data.get(VirtualRouterConstant.Param.VR.toString()); + String vrUuid; + VmNicInventory mgmtNic; + if (vr != null) { + mgmtNic = vr.getManagementNic(); + vrUuid = vr.getUuid(); + } else { + final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); + vrUuid = spec.getVmInventory().getUuid(); + ApplianceVmInventory applianceVm = ApplianceVmInventory.valueOf(dbf.findByUuid(vrUuid, ApplianceVmVO.class)); + mgmtNic = applianceVm.getManagementNic(); + DebugUtils.Assert(mgmtNic!=null, String.format("cannot find management nic for virtual router[uuid:%s, name:%s]", spec.getVmInventory().getUuid(), spec.getVmInventory().getName())); + } + + String url = vrMgr.buildUrl(mgmtNic.getIp(), VirtualRouterConstant.VR_ECHO_PATH); + restf.echo(url, new Completion(trigger) { + @Override + public void success() { + String vrUserTag = VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER.getTokenByResourceUuid( + vrUuid, VirtualRouterVmVO.class, VirtualRouterSystemTags.VIRTUAL_ROUTER_LOGIN_USER_TOKEN); + if (vrUserTag != null) { + /* get user name only happened after create virtual router */ + trigger.next(); + return; + } + + String url = vrMgr.buildUrl(mgmtNic.getIp(), VirtualRouterConstant.VR_GET_TYPE_PATH); + VirtualRouterCommands.GetTypeCommand cmd = new VirtualRouterCommands.GetTypeCommand(); + cmd.setUuid(vrUuid); + try { + VirtualRouterCommands.GetTypeRsp rsp = restf.syncJsonPost(url, cmd, VirtualRouterCommands.GetTypeRsp.class, TimeUnit.SECONDS, 10); + if (rsp.isSuccess()) { + updateVrLoginUser(vrUuid, rsp.isVyos()); + } + }catch (OperationFailureException e){ + // old zvr will return 404 + updateVrLoginUser(vrUuid, true); + } + trigger.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + trigger.next(); + } + }, TimeUnit.SECONDS.toMillis(1), TimeUnit.SECONDS.toMillis(Long.parseLong(VirtualRouterGlobalConfig.VYOS_ECHO_TIMEOUT.value()))); + } +} diff --git a/plugin/vxlan/pom.xml b/plugin/vxlan/pom.xml index e7fe6ee3835..8d601d112a6 100755 --- a/plugin/vxlan/pom.xml +++ b/plugin/vxlan/pom.xml @@ -5,7 +5,7 @@ plugin org.zstack - 4.4.0 + 5.4.0 4.0.0 diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/PackageInfo.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/PackageInfo.java index 3a5e20149da..4700e79db2c 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/PackageInfo.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/PackageInfo.java @@ -1,6 +1,10 @@ package org.zstack.network.l2.vxlan; import org.zstack.header.PackageAPIInfo; -@PackageAPIInfo(APICategoryName = "VXLAN") + +@PackageAPIInfo( + APICategoryName = "VXLAN", + permissions = {PackageAPIInfo.PERMISSION_ZSV_ADVANCED_AVAILABLE, PackageAPIInfo.PERMISSION_COMMUNITY_AVAILABLE} +) public class PackageInfo { } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepEventDoc_zh_cn.groovy index de6c2135fcc..f98c681650e 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepEventDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepEventDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vtep.VtepInventory doc { - title "vxlan隧道端点清单" + title "VXLAN隧道端点清单" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepMsgDoc_zh_cn.groovy index 4647c9f662e..8851bb2c4e3 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APICreateVxlanVtepMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.network.l2.vxlan.vtep import org.zstack.network.l2.vxlan.vtep.APICreateVxlanVtepEvent doc { - title "CreateVxlanVtep" + title "创建VXLAN隧道端点(CreateVxlanVtep)" category "network.l2" - desc """创建vxlan隧道端点""" + desc """创建VXLAN隧道端点""" rest { request { @@ -29,57 +29,60 @@ doc { type "String" optional false since "3.0" - } column { name "poolUuid" enclosedIn "params" - desc "" + desc "VXLAN资源池UUID" location "body" type "String" optional false since "3.0" - } column { name "vtepIp" enclosedIn "params" - desc "" + desc "隧道端点IP地址" location "body" type "String" optional true since "3.0" - } column { name "resourceUuid" enclosedIn "params" - desc "" + desc "资源UUID" location "body" type "String" optional true since "3.0" - } column { name "systemTags" enclosedIn "" - desc "" + desc "系统标签" location "body" type "List" optional true since "3.0" - } column { name "userTags" enclosedIn "" - desc "" + desc "用户标签" location "body" type "List" optional true since "3.0" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepMsgDoc_zh_cn.groovy index 5a5ecdabb9a..bc74521ddc9 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepMsgDoc_zh_cn.groovy @@ -2,14 +2,13 @@ package org.zstack.network.l2.vxlan.vtep import org.zstack.network.l2.vxlan.vtep.APIQueryVtepReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { - title "QueryVtep" + title "查询VXLAN隧道端点(QueryVtep)" category "network.l2" - desc """在这里填写API描述""" + desc """查询隧道端点""" rest { request { diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepReplyDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepReplyDoc_zh_cn.groovy index 44cf29e73b6..3b18681694b 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepReplyDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/APIQueryVtepReplyDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vtep.VtepInventory doc { - title "在这里输入结构的名称" + title "VXLAN隧道端点清单" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/CreateVtepMsg.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/CreateVtepMsg.java index 8b42ce81ec2..b01dea1430c 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/CreateVtepMsg.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/CreateVtepMsg.java @@ -13,6 +13,7 @@ public class CreateVtepMsg extends NeedReplyMessage implements L2NetworkMessage private Integer port; private String type; private String poolUuid; + private String physicalInterface; public String getPoolUuid() { return poolUuid; @@ -62,6 +63,14 @@ public void setPort(Integer port) { this.port = port; } + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + @Override public String getL2NetworkUuid() { return getPoolUuid(); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepCascadeExtension.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepCascadeExtension.java new file mode 100644 index 00000000000..0d77d072173 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepCascadeExtension.java @@ -0,0 +1,129 @@ +package org.zstack.network.l2.vxlan.vtep; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.core.asyncbatch.While; +import org.zstack.core.cascade.AbstractAsyncCascadeExtension; +import org.zstack.core.cascade.CascadeAction; +import org.zstack.core.cascade.CascadeConstant; +import org.zstack.core.cloudbus.CloudBus; +import org.zstack.core.cloudbus.CloudBusCallBack; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.errorcode.ErrorCodeList; +import org.zstack.header.message.MessageReply; +import org.zstack.header.network.l2.*; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; + +import java.util.*; + +public class RemoteVtepCascadeExtension extends AbstractAsyncCascadeExtension { + private static final CLogger logger = Utils.getLogger(RemoteVtepCascadeExtension.class); + + @Override + public void asyncCascade(CascadeAction action, Completion completion) { + if (action.isActionCode(CascadeConstant.DELETION_DELETE_CODE, CascadeConstant.DELETION_FORCE_DELETE_CODE)) { + handleDeletion(action, completion); + } else if (action.isActionCode(CascadeConstant.DELETION_CLEANUP_CODE)) { + handleDeletionCleanup(action, completion); + } else if (action.isActionCode(L2NetworkConstant.DETACH_L2NETWORK_CODE)) { + handleDetach(action, completion); + } else { + completion.success(); + } + } + + @Autowired + private DatabaseFacade dbf; + @Autowired + private CloudBus bus; + @Autowired + private ErrorFacade errf; + + private static final String NAME = RemoteVtepVO.class.getSimpleName(); + + @Override + public List getEdgeNames() { + return Arrays.asList(L2NetworkVO.class.getSimpleName()); + } + + @Override + public String getCascadeResourceName() { + return NAME; + } + + private void handleDetach(CascadeAction action, final Completion completion) { + List structs = action.getParentIssuerContext(); + List vteps = new ArrayList<>(); + for (L2NetworkDetachStruct s : structs) { + vteps.addAll(Q.New(RemoteVtepVO.class).eq(RemoteVtepVO_.poolUuid, s.getL2NetworkUuid()).eq(RemoteVtepVO_.clusterUuid, s.getClusterUuid()).list()); + } + + if (vteps.isEmpty()) { + completion.success(); + return; + } + for (RemoteVtepVO vtep : vteps) { + RemoteVtepVO vo = dbf.findByUuid(vtep.getUuid(), RemoteVtepVO.class); + dbf.remove(vo); + } + completion.success(); + } + + private void handleDeletionCleanup(CascadeAction action, Completion completion) { + dbf.eoCleanup(RemoteVtepVO.class); + completion.success(); + } + + private void handleDeletion(final CascadeAction action, final Completion completion) { + List vteps = vtepFromAction(action); + + if (vteps == null) { + completion.success(); + return; + } + + for (RemoteVtepInventory vtep : vteps) { + RemoteVtepVO vo = dbf.findByUuid(vtep.getUuid(), RemoteVtepVO.class); + dbf.remove(vo); + } + completion.success(); + } + + private List vtepFromAction(CascadeAction action) { + List ret = null; + if (L2NetworkVO.class.getSimpleName().equals(action.getParentIssuer())) { + List l2uuids = CollectionUtils.transformToList((List)action.getParentIssuerContext(), new Function() { + @Override + public String call(L2NetworkInventory arg) { + return arg.getUuid(); + } + }); + + List vos = Q.New(RemoteVtepVO.class).in(RemoteVtepVO_.poolUuid, l2uuids).list(); + if (!vos.isEmpty()) { + ret = RemoteVtepInventory.valueOf(vos); + } + } else if (NAME.equals(action.getParentIssuer())) { + ret = action.getParentIssuerContext(); + } + + return ret; + } + + @Override + public CascadeAction createActionForChildResource(CascadeAction action) { + if (CascadeConstant.DELETION_CODES.contains(action.getActionCode())) { + List ctx = vtepFromAction(action); + if (ctx != null) { + return action.copy().setParentIssuer(NAME).setParentIssuerContext(ctx); + } + } + + return null; + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepInventory.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepInventory.java new file mode 100644 index 00000000000..0f3bf367a32 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepInventory.java @@ -0,0 +1,129 @@ +package org.zstack.network.l2.vxlan.vtep; + +import org.zstack.header.configuration.PythonClassInventory; +import org.zstack.header.query.ExpandedQueries; +import org.zstack.header.query.ExpandedQuery; +import org.zstack.header.query.Queryable; +import org.zstack.header.search.Inventory; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.L2VxlanNetworkPoolInventory; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolVO; + +import javax.persistence.JoinColumn; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@PythonClassInventory +@Inventory(mappingVOClass = RemoteVtepVO.class) +@ExpandedQueries({ + @ExpandedQuery(expandedField = "vxlanPool", inventoryClass = L2VxlanNetworkPoolInventory.class, + foreignKey = "poolUuid", expandedInventoryKey = "uuid") +}) +public class RemoteVtepInventory { + private String uuid; + + private String clusterUuid; + + private String vtepIp; + + private Integer port; + + private String type; + + private Timestamp createDate; + + private Timestamp lastOpDate; + + private String poolUuid; + + public RemoteVtepInventory() { + } + + protected RemoteVtepInventory(RemoteVtepVO vo) { + this.setUuid(vo.getUuid()); + this.setClusterUuid(vo.getClusterUuid()); + this.setVtepIp(vo.getVtepIp()); + this.setPort(vo.getPort()); + this.setPoolUuid(vo.getPoolUuid()); + this.setType(vo.getType()); + this.setCreateDate(vo.getCreateDate()); + this.setLastOpDate(vo.getLastOpDate()); + } + + public static RemoteVtepInventory valueOf(RemoteVtepVO vo) { + return new RemoteVtepInventory(vo); + } + + public static List valueOf(Collection vos) { + List invs = new ArrayList<>(vos.size()); + for (RemoteVtepVO vo : vos) { + invs.add(RemoteVtepInventory.valueOf(vo)); + } + return invs; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getPoolUuid() { + return poolUuid; + } + + public void setPoolUuid(String poolUuid) { + this.poolUuid = poolUuid; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepInventoryDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepInventoryDoc_zh_cn.groovy new file mode 100644 index 00000000000..76251ae7493 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepInventoryDoc_zh_cn.groovy @@ -0,0 +1,58 @@ +package org.zstack.network.l2.vxlan.vtep + +import java.lang.Integer +import java.sql.Timestamp + +doc { + + title "远端VXLAN隧道端点清单" + + field { + name "uuid" + desc "资源的UUID,唯一标示该资源" + type "String" + since "4.7.11" + } + field { + name "clusterUuid" + desc "集群UUID" + type "String" + since "5.3.0" + } + field { + name "vtepIp" + desc "隧道端点IP地址" + type "String" + since "4.7.11" + } + field { + name "port" + desc "端口" + type "Integer" + since "4.7.11" + } + field { + name "type" + desc "类型" + type "String" + since "4.7.11" + } + field { + name "createDate" + desc "创建时间" + type "Timestamp" + since "4.7.11" + } + field { + name "lastOpDate" + desc "最后一次修改时间" + type "Timestamp" + since "4.7.11" + } + field { + name "poolUuid" + desc "VXLAN资源池UUID" + type "String" + since "4.7.11" + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepVO.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepVO.java new file mode 100755 index 00000000000..5acc55e58cd --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepVO.java @@ -0,0 +1,109 @@ +package org.zstack.network.l2.vxlan.vtep; + +import org.zstack.header.cluster.ClusterEO; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.host.HostEO; +import org.zstack.header.host.HostVO; +import org.zstack.header.network.l2.L2NetworkEO; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.tag.AutoDeleteTag; +import org.zstack.header.vo.EntityGraph; +import org.zstack.header.vo.ForeignKey; +import org.zstack.header.vo.ResourceVO; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolVO; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.sql.Timestamp; + +@Entity +@Table +@EntityGraph( + parents = { + @EntityGraph.Neighbour(type = ClusterVO.class, myField = "clusterUuid", targetField = "uuid"), + @EntityGraph.Neighbour(type = VxlanNetworkPoolVO.class, myField = "poolUuid", targetField = "uuid"), + } +) +public class RemoteVtepVO extends ResourceVO { + + @Column + @ForeignKey(parentEntityClass = ClusterEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String clusterUuid; + + @Column + private String vtepIp; + + @Column + private Integer port; + + @Column + @ForeignKey(parentEntityClass = L2NetworkEO.class, onDeleteAction = ForeignKey.ReferenceOption.CASCADE) + private String poolUuid; + + @Column + private String type; + + @Column + private Timestamp createDate; + + @Column + private Timestamp lastOpDate; + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getPoolUuid() { + return poolUuid; + } + + public void setPoolUuid(String poolUuid) { + this.poolUuid = poolUuid; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepVO_.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepVO_.java new file mode 100755 index 00000000000..3261af35560 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/RemoteVtepVO_.java @@ -0,0 +1,18 @@ +package org.zstack.network.l2.vxlan.vtep; + +import org.zstack.header.vo.ResourceVO_; + +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; +import java.sql.Timestamp; + +@StaticMetamodel(RemoteVtepVO.class) +public class RemoteVtepVO_ extends ResourceVO_ { + public static volatile SingularAttribute vtepIp; + public static volatile SingularAttribute port; + public static volatile SingularAttribute clusterUuid; + public static volatile SingularAttribute type; + public static volatile SingularAttribute poolUuid; + public static volatile SingularAttribute createDate; + public static volatile SingularAttribute lastOpDate; +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventory.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventory.java index 3133761129b..f6676cfdb67 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventory.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventory.java @@ -34,6 +34,8 @@ public class VtepInventory { private String type; + private String physicalInterface; + private Timestamp createDate; private Timestamp lastOpDate; @@ -50,6 +52,7 @@ protected VtepInventory(VtepVO vo) { this.setPort(vo.getPort()); this.setPoolUuid(vo.getPoolUuid()); this.setType(vo.getType()); + this.setPhysicalInterface(vo.getPhysicalInterface()); this.setCreateDate(vo.getCreateDate()); this.setLastOpDate(vo.getLastOpDate()); } @@ -114,6 +117,14 @@ public void setPoolUuid(String poolUuid) { this.poolUuid = poolUuid; } + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } + public Timestamp getCreateDate() { return createDate; } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventoryDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventoryDoc_zh_cn.groovy index 4d1746cd1b6..d0ef4ef0863 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventoryDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepInventoryDoc_zh_cn.groovy @@ -2,11 +2,10 @@ package org.zstack.network.l2.vxlan.vtep import java.lang.Integer import java.sql.Timestamp -import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "VXLAN隧道端点清单" field { name "uuid" @@ -22,22 +21,28 @@ doc { } field { name "vtepIp" - desc "" + desc "隧道端点IP地址" type "String" since "0.6" } field { name "port" - desc "" + desc "端口" type "Integer" since "0.6" } field { name "type" - desc "" + desc "类型" type "String" since "0.6" } + field { + name "physicalInterface" + desc "" + type "String" + since "5.3.28" + } field { name "createDate" desc "创建时间" @@ -52,7 +57,7 @@ doc { } field { name "poolUuid" - desc "" + desc "VXLAN资源池UUID" type "String" since "0.6" } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO.java index 43b846cf6bf..82e17e75253 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO.java @@ -52,6 +52,9 @@ public class VtepVO extends ResourceVO { @Column private String type; + @Column + private String physicalInterface; + @Column private Timestamp createDate; @@ -121,4 +124,12 @@ public String getType() { public void setType(String type) { this.type = type; } + + public String getPhysicalInterface() { + return physicalInterface; + } + + public void setPhysicalInterface(String physicalInterface) { + this.physicalInterface = physicalInterface; + } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO_.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO_.java index d9459ffeee4..899f3f797dd 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO_.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vtep/VtepVO_.java @@ -17,6 +17,7 @@ public class VtepVO_ extends ResourceVO_ { public static volatile SingularAttribute clusterUuid; public static volatile SingularAttribute type; public static volatile SingularAttribute poolUuid; + public static volatile SingularAttribute physicalInterface; public static volatile SingularAttribute createDate; public static volatile SingularAttribute lastOpDate; } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEvent.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEvent.java index f1389a3f5e1..c987ef25382 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEvent.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEvent.java @@ -5,27 +5,14 @@ @RestResponse(allTo = "inventory") public class APICreateL2VxlanNetworkEvent extends APICreateL2NetworkEvent { - /** - * @desc see :ref:`L2VlanNetworkInventory` - */ - private L2VxlanNetworkInventory inventory; - public APICreateL2VxlanNetworkEvent(String apiId) { super(apiId); } - public L2VxlanNetworkInventory getInventory() { - return inventory; - } - public APICreateL2VxlanNetworkEvent() { super(null); } - public void setInventory(L2VxlanNetworkInventory inventory) { - this.inventory = inventory; - } - public static APICreateL2VxlanNetworkEvent __example__() { APICreateL2VxlanNetworkEvent event = new APICreateL2VxlanNetworkEvent(); L2VxlanNetworkInventory net = new L2VxlanNetworkInventory(); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEventDoc_zh_cn.groovy index 6e488ef4de3..2b5b4e94cc0 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEventDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkEventDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory doc { - title "在这里输入结构的名称" + title "二层VXLAN网路清单" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkMsgDoc_zh_cn.groovy index 331921e5a31..f492e83d31b 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APICreateL2VxlanNetworkMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.network.l2.vxlan.vxlanNetwork import org.zstack.network.l2.vxlan.vxlanNetwork.APICreateL2VxlanNetworkEvent doc { - title "CreateL2VxlanNetwork" + title "创建二层VXLAN网络(CreateL2VxlanNetwork)" category "network.l2" - desc """在这里填写API描述""" + desc """创建二层VXLAN网络""" rest { request { @@ -24,22 +24,20 @@ doc { column { name "vni" enclosedIn "params" - desc "" + desc "Vni号" location "body" type "Integer" optional true since "0.6" - } column { name "poolUuid" enclosedIn "params" - desc "" + desc "VXLAN资源池UUID" location "body" type "String" optional false since "0.6" - } column { name "name" @@ -49,7 +47,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -59,7 +56,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -69,57 +65,88 @@ doc { type "String" optional false since "0.6" - } column { name "physicalInterface" enclosedIn "params" - desc "" + desc "物理网卡" location "body" type "String" optional false since "0.6" - } column { name "type" enclosedIn "params" - desc "" + desc "二层网络类型" location "body" type "String" optional true since "0.6" - } column { name "resourceUuid" enclosedIn "params" - desc "" + desc "资源UUID。若指定,二层网络会使用该字段值作为UUID" location "body" type "String" optional true since "0.6" - } column { name "systemTags" enclosedIn "" - desc "" + desc "系统标签" location "body" type "List" optional true since "0.6" - } column { name "userTags" enclosedIn "" - desc "" + desc "用户标签" location "body" type "List" optional true since "0.6" - + } + column { + name "vSwitchType" + enclosedIn "params" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "0.6" + values ("LinuxBridge","OvsDpdk","MacVlan") + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" } } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIDeleteVxlanL2Network.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIDeleteVxlanL2Network.java index 6fb0b51b636..70cb8240802 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIDeleteVxlanL2Network.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIDeleteVxlanL2Network.java @@ -1,6 +1,7 @@ package org.zstack.network.l2.vxlan.vxlanNetwork; import org.springframework.http.HttpMethod; +import org.zstack.header.core.NoDoc; import org.zstack.header.network.l2.APIDeleteL2NetworkEvent; import org.zstack.header.network.l2.APIDeleteL2NetworkMsg; import org.zstack.header.rest.NoSDK; @@ -12,6 +13,7 @@ responseClass = APIDeleteL2NetworkEvent.class ) @NoSDK +@NoDoc public class APIDeleteVxlanL2Network extends APIDeleteL2NetworkMsg { public static APIDeleteL2NetworkMsg __example__() { APIDeleteL2NetworkMsg msg = new APIDeleteL2NetworkMsg(); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkMsgDoc_zh_cn.groovy index a5b6e5a758d..5b80628d3f6 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkMsgDoc_zh_cn.groovy @@ -2,14 +2,13 @@ package org.zstack.network.l2.vxlan.vxlanNetwork import org.zstack.network.l2.vxlan.vxlanNetwork.APIQueryL2VxlanNetworkReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { - title "QueryL2VxlanNetwork" + title "查询二层VXLAN网络(QueryL2VxlanNetwork)" category "network.l2" - desc """在这里填写API描述""" + desc """查询二层VXLAN网络""" rest { request { diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkReplyDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkReplyDoc_zh_cn.groovy index 6e931b6d515..f4ce2a43782 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkReplyDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/APIQueryL2VxlanNetworkReplyDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory doc { - title "在这里输入结构的名称" + title "二层VXLAN网络清单列表" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/L2VxlanNetworkInventoryDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/L2VxlanNetworkInventoryDoc_zh_cn.groovy index a6e40a8c52c..4ba1679e22a 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/L2VxlanNetworkInventoryDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/L2VxlanNetworkInventoryDoc_zh_cn.groovy @@ -1,22 +1,22 @@ package org.zstack.network.l2.vxlan.vxlanNetwork import java.lang.Integer -import java.sql.Timestamp +import java.lang.Boolean import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "二层VXLAN网络清单" field { name "vni" - desc "" + desc "Vni号" type "Integer" since "0.6" } field { name "poolUuid" - desc "" + desc "VXLAN资源池UUID" type "String" since "0.6" } @@ -46,16 +46,40 @@ doc { } field { name "physicalInterface" - desc "" + desc "物理网卡" type "String" since "0.6" } field { name "type" - desc "" + desc "二层网络类型" type "String" since "0.6" } + field { + name "vSwitchType" + desc "" + type "String" + since "5.3.0" + } + field { + name "virtualNetworkId" + desc "" + type "Integer" + since "5.3.0" + } + field { + name "isolated" + desc "" + type "Boolean" + since "5.3.0" + } + field { + name "pvlan" + desc "" + type "String" + since "5.3.0" + } field { name "createDate" desc "创建时间" @@ -70,7 +94,7 @@ doc { } field { name "attachedClusterUuids" - desc "" + desc "挂载集群的UUID列表" type "List" since "0.6" } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetwork.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetwork.java index 9ddf4b5f8ee..0be8bb9aefa 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetwork.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetwork.java @@ -3,42 +3,41 @@ import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; -import org.springframework.transaction.annotation.Transactional; +import org.zstack.core.asyncbatch.While; import org.zstack.core.cascade.CascadeFacade; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusListCallBack; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; -import org.zstack.core.db.SQL; import org.zstack.core.errorcode.ErrorFacade; +import org.zstack.core.thread.ChainTask; +import org.zstack.core.thread.SyncTaskChain; import org.zstack.core.workflow.FlowChainBuilder; -import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.core.workflow.ShareFlow; import org.zstack.header.core.Completion; -import org.zstack.header.core.NoErrorCompletion; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.exception.CloudRuntimeException; -import org.zstack.header.host.HostInventory; -import org.zstack.header.host.HostVO; -import org.zstack.header.host.HostVO_; -import org.zstack.header.host.HypervisorType; +import org.zstack.header.host.*; import org.zstack.header.identity.Quota; import org.zstack.header.identity.ReportQuotaExtensionPoint; +import org.zstack.header.identity.quota.QuotaMessageHandler; import org.zstack.header.message.APIMessage; import org.zstack.header.message.Message; import org.zstack.header.message.MessageReply; -import org.zstack.header.message.NeedQuotaCheckMessage; import org.zstack.header.network.l2.*; -import org.zstack.identity.QuotaUtil; -import org.zstack.network.l2.L2NetworkExtensionPointEmitter; -import org.zstack.network.l2.L2NetworkGlobalConfig; -import org.zstack.network.l2.L2NetworkManager; -import org.zstack.network.l2.L2NoVlanNetwork; +import org.zstack.network.l2.*; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; +import javax.transaction.Transactional; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import static java.util.Arrays.asList; import static org.zstack.utils.CollectionDSL.list; /** @@ -75,7 +74,8 @@ private VxlanNetworkVO getSelf() { @Override public void deleteHook(Completion completion) { - if (L2NetworkGlobalConfig.DeleteL2BridgePhysically.value(Boolean.class)) { + if (L2NetworkGlobalConfig.DeleteL2BridgePhysically.value(Boolean.class) + && getVSwitchType().isAttachToCluster()) { deleteL2Bridge(completion); } else { completion.success(); @@ -83,7 +83,7 @@ public void deleteHook(Completion completion) { } @Override - protected L2NetworkInventory getSelfInventory() { + protected L2VxlanNetworkInventory getSelfInventory() { return L2VxlanNetworkInventory.valueOf(getSelf()); } @@ -119,7 +119,7 @@ private void handleLocalMessage(Message msg) { private void handle(final PrepareL2NetworkOnHostMsg msg) { final PrepareL2NetworkOnHostReply reply = new PrepareL2NetworkOnHostReply(); - prepareL2NetworkOnHosts(Arrays.asList(msg.getHost()), new Completion(msg) { + prepareL2NetworkOnHosts(asList(msg.getHost()), new Completion(msg) { @Override public void success() { bus.reply(msg, reply); @@ -150,6 +150,122 @@ public void fail(ErrorCode errorCode) { }); } + + @Transactional + private void changeL2NetworkVniInDb(final APIChangeL2NetworkVlanIdMsg msg) { + if (!self.getVirtualNetworkId().equals(msg.getVlan())) { + VxlanNetworkVO vo = getSelf(); + vo.setVirtualNetworkId(msg.getVlan()); + vo.setVni(msg.getVlan()); + dbf.updateAndRefresh(vo); + } + } + + private void changeL2NetworkVni(final APIChangeL2NetworkVlanIdMsg msg, final Completion completion) { + final FlowChain chain = FlowChainBuilder.newShareFlowChain(); + chain.setName(String.format("change-l2-%s-vni-on-hosts", self.getUuid())); + chain.then(new ShareFlow() { + @Override + public void setup() { + final Map updatedHosts = new ConcurrentHashMap<>(); + L2NetworkInventory oldInv = self.toInventory(); + L2NetworkInventory newInv = self.toInventory(); + if (msg.getVlan() != null) { + newInv.setVirtualNetworkId(msg.getVlan()); + } + + flow(new Flow() { + String __name__ = "update-l2-network-vni"; + + @Override + public void run(final FlowTrigger trigger, Map data) { + new While<>(L2NetworkHostHelper.getHostsByL2NetworkAttachedCluster(newInv)).step((host, whileCompletion) -> { + updateVxlanNetwork(oldInv, newInv, host.getUuid(), host.getHypervisorType(), new Completion(whileCompletion) { + @Override + public void success() { + logger.debug(String.format("Successfully updated VXLAN network on host[uuid:%s]", host.getUuid())); + updatedHosts.put(host, true); + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("Failed to update VXLAN network on host[uuid:%s], error: %s", host.getUuid(), errorCode)); + updatedHosts.put(host, false); + whileCompletion.addError(errorCode); + whileCompletion.done(); + } + }); + }, 5).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errorCodeList.getCauses().isEmpty()) { + trigger.fail(errorCodeList.getCauses().get(0)); + } else { + trigger.next(); + } + } + }); + } + + @Override + public void rollback(FlowRollback trigger, Map data) { + List successfulHosts = updatedHosts.entrySet().stream() + .filter(Map.Entry::getValue) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + + if (successfulHosts.isEmpty()) { + logger.debug("No successful hosts to rollback, skipping rollback step."); + trigger.rollback(); + return; + } + + logger.debug(String.format("Rolling back VXLAN network changes on %d hosts", successfulHosts.size())); + new While<>(successfulHosts).step((host, whileCompletion) -> { + logger.debug(String.format("Rolling back VXLAN network on host[uuid:%s]", host.getUuid())); + updateVxlanNetwork(newInv, oldInv, host.getUuid(), host.getHypervisorType(), new Completion(whileCompletion) { + @Override + public void success() { + logger.debug(String.format("Successfully rolled back VXLAN network on host[uuid:%s]", host.getUuid())); + whileCompletion.done(); + } + + @Override + public void fail(ErrorCode errorCode) { + logger.error(String.format("failed to rollback VXLAN network on host[uuid:%s], because %s", + host.getUuid(), errorCode.toString())); + whileCompletion.done(); + } + }); + }, updatedHosts.size()).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + logger.debug("finished rolling back l2 network vni changes"); + trigger.rollback(); + } + }); + } + }); + + done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }); + + error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }); + } + }).start(); + } + + private void prepareL2NetworkOnHosts(final List hosts, final Completion completion) { FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); chain.setName(String.format("prepare-l2-%s-on-hosts", self.getUuid())); @@ -222,11 +338,20 @@ public void handle(ErrorCode errCode, Map data) { }).start(); } + protected void updateVxlanNetwork(L2NetworkInventory oldInv, L2NetworkInventory newInv, String hostUuid, String htype, Completion completion) { + final HypervisorType hvType = HypervisorType.valueOf(htype); + final L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); + final VSwitchType vSwitchType = VSwitchType.valueOf(self.getvSwitchType()); + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, vSwitchType, hvType); + ext.update(oldInv, newInv, hostUuid, completion); + } + protected void realizeNetwork(String hostUuid, String htype, Completion completion) { final HypervisorType hvType = HypervisorType.valueOf(htype); final L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); + final VSwitchType vSwitchType = VSwitchType.valueOf(self.getvSwitchType()); - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, hvType); + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, vSwitchType, hvType); ext.realize(getSelfInventory(), hostUuid, completion); } @@ -260,6 +385,8 @@ private void handleApiMessage(APIMessage msg) { handle((APIAttachL2NetworkToClusterMsg) msg); } else if (msg instanceof APIDetachL2NetworkFromClusterMsg) { handle((APIDetachL2NetworkFromClusterMsg) msg); + } else if (msg instanceof APIChangeL2NetworkVlanIdMsg) { + handle((APIChangeL2NetworkVlanIdMsg) msg); } else if (msg instanceof L2NetworkMessage) { superHandle((L2NetworkMessage) msg); } else { @@ -267,6 +394,48 @@ private void handleApiMessage(APIMessage msg) { } } + protected void handle(final APIChangeL2NetworkVlanIdMsg msg) { + APIChangeL2NetworkVlanIdEvent event = new APIChangeL2NetworkVlanIdEvent(msg.getId()); + if (self.getVirtualNetworkId().equals(msg.getVlan())) { + event.setInventory(getSelfInventory()); + bus.publish(event); + return; + } + thdf.chainSubmit(new ChainTask(msg) { + @Override + public String getSyncSignature() { + return String.format("change-l2-network-%s-vlan", msg.getL2NetworkUuid()); + } + + @Override + public void run(SyncTaskChain chain) { + changeL2NetworkVni(msg, new Completion(chain) { + @Override + public void success() { + changeL2NetworkVniInDb(msg); + extpEmitter.afterUpdate(getSelfInventory()); + event.setInventory(getSelfInventory()); + bus.publish(event); + chain.next(); + } + + @Override + public void fail(ErrorCode errorCode) { + event.setError(errorCode); + event.setInventory(getSelfInventory()); + bus.publish(event); + chain.next(); + } + }); + } + + @Override + public String getName() { + return getSyncSignature(); + } + }); + } + protected void handle(final APIDetachL2NetworkFromClusterMsg msg) { throw new CloudRuntimeException("VxlanNetwork can not detach from cluster which VxlanNetworkPool should be used"); } @@ -281,56 +450,10 @@ private void superHandle(L2NetworkMessage msg) { @Override public List reportQuota() { - Quota.QuotaOperator checker = new Quota.QuotaOperator() { - @Override - public void checkQuota(APIMessage msg, Map pairs) { - if (!new QuotaUtil().isAdminAccount(msg.getSession().getAccountUuid())) { - if (msg instanceof APICreateL2VxlanNetworkMsg) { - check((APICreateL2VxlanNetworkMsg) msg, pairs); - } - } - } - - @Override - public void checkQuota(NeedQuotaCheckMessage msg, Map pairs) { - - } - - @Override - public List getQuotaUsageByAccount(String accountUuid) { - Quota.QuotaUsage usage = new Quota.QuotaUsage(); - usage.setName(VxlanNetworkQuotaConstant.VXLAN_NUM); - usage.setUsed(getUsedVxlan(accountUuid)); - return list(usage); - } - - @Transactional(readOnly = true) - private long getUsedVxlan(String accountUuid) { - long cnt = SQL.New("select count(vxlan) from VxlanNetworkVO vxlan, AccountResourceRefVO ref " + - "where vxlan.uuid = ref.resourceUuid and ref.accountUuid = :auuid", Long.class) - .param("auuid", accountUuid).find(); - return cnt; - } - - private void check(APICreateL2VxlanNetworkMsg msg, Map pairs) { - long vxlanNum = pairs.get(VxlanNetworkQuotaConstant.VXLAN_NUM).getValue(); - long vxlan = getUsedVxlan(msg.getSession().getAccountUuid()); - - if (vxlan + 1 > vxlanNum) { - throw new ApiMessageInterceptionException(new QuotaUtil().buildQuataExceedError( - msg.getSession().getAccountUuid(), VxlanNetworkQuotaConstant.VXLAN_NUM, vxlanNum)); - } - } - }; - Quota quota = new Quota(); - quota.setOperator(checker); - quota.addMessageNeedValidation(APICreateL2VxlanNetworkMsg.class); - - Quota.QuotaPair p = new Quota.QuotaPair(); - p.setName(VxlanNetworkQuotaConstant.VXLAN_NUM); - p.setValue(VxlanNetworkQuotaGlobalConfig.VXLAN_NUM.defaultValue(Long.class)); - quota.addPair(p); + quota.defineQuota(new VxlanNumQuotaDefinition()); + quota.addQuotaMessageChecker(new QuotaMessageHandler<>(APICreateL2VxlanNetworkMsg.class) + .addCounterQuota(VxlanNetworkQuotaConstant.VXLAN_NUM)); return list(quota); } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkConstant.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkConstant.java index 87e1f48880d..4ab04c033cb 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkConstant.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkConstant.java @@ -9,4 +9,12 @@ public class VxlanNetworkConstant { @PythonClass public static final String VXLAN_NETWORK_TYPE = "VxlanNetwork"; + + //vlxan id range + public static final int MIN_VNI = 1; + public static final int MAX_VNI = 16777215; + + //vlan id range + public static final int MIN_VLAN = 1; + public static final int MAX_VLAN = 4095; } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java index a6b205c7fc4..101ac6cbdd4 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkFactory.java @@ -11,18 +11,19 @@ import org.zstack.core.db.SQLBatchWithReturn; import org.zstack.core.db.SimpleQuery; import org.zstack.header.Component; -import org.zstack.header.core.FutureCompletion; -import org.zstack.header.core.WhileDoneCompletion; +import org.zstack.header.apimediator.ApiMessageInterceptionException; +import org.zstack.header.apimediator.GlobalApiMessageInterceptor; +import org.zstack.header.core.Completion; import org.zstack.header.core.ReturnValueCompletion; -import org.zstack.header.errorcode.ErrorCode; +import org.zstack.header.core.WhileDoneCompletion; import org.zstack.header.errorcode.ErrorCodeList; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.host.HostInventory; import org.zstack.header.host.HostStatus; import org.zstack.header.host.HostVO; import org.zstack.header.host.HostVO_; -import org.zstack.header.identity.AccountInventory; import org.zstack.header.identity.AccountVO; +import org.zstack.header.message.APIMessage; import org.zstack.header.message.MessageReply; import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.L3NetworkVO; @@ -36,19 +37,18 @@ import org.zstack.network.l2.L2NetworkDefaultMtu; import org.zstack.network.l2.vxlan.vxlanNetworkPool.AllocateVniMsg; import org.zstack.network.l2.vxlan.vxlanNetworkPool.AllocateVniReply; +import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkChecker; import org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolConstant; import org.zstack.network.service.NetworkServiceGlobalConfig; import org.zstack.query.QueryFacade; import org.zstack.resourceconfig.ResourceConfigFacade; -import org.zstack.utils.CollectionUtils; import org.zstack.utils.Utils; -import org.zstack.utils.function.Function; import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.zstack.core.Platform.operr; @@ -56,7 +56,7 @@ /** * Created by weiwang on 02/03/2017. */ -public class VxlanNetworkFactory implements L2NetworkFactory, Component, VmInstanceMigrateExtensionPoint, L2NetworkDefaultMtu, L2NetworkGetVniExtensionPoint, L2NetworkCascadeFilterExtensionPoint { +public class VxlanNetworkFactory implements L2NetworkFactory, Component, VmInstanceMigrateExtensionPoint, L2NetworkDefaultMtu, L2NetworkGetVniExtensionPoint, L2NetworkCascadeFilterExtensionPoint, GlobalApiMessageInterceptor { private static CLogger logger = Utils.getLogger(VxlanNetworkFactory.class); public static L2NetworkType type = new L2NetworkType(VxlanNetworkConstant.VXLAN_NETWORK_TYPE); @@ -70,6 +70,8 @@ public class VxlanNetworkFactory implements L2NetworkFactory, Component, VmInsta protected AccountManager acntMgr; @Autowired private ResourceConfigFacade rcf; + @Autowired + private VxlanNetworkChecker vxlanInterceptor; @Override public L2NetworkType getType() { @@ -77,7 +79,7 @@ public L2NetworkType getType() { } @Override - public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { APICreateL2VxlanNetworkMsg amsg = (APICreateL2VxlanNetworkMsg) msg; AllocateVniMsg vniMsg = new AllocateVniMsg(); @@ -97,6 +99,7 @@ protected VxlanNetworkVO scripts() { String uuid = msg.getResourceUuid() == null ? Platform.getUuid() : msg.getResourceUuid(); vo.setUuid(uuid); vo.setVni(r.getVni()); + vo.setVirtualNetworkId(r.getVni()); vo.setAccountUuid(msg.getSession().getAccountUuid()); vo.setPoolUuid((amsg.getPoolUuid())); if (vo.getPhysicalInterface() == null) { @@ -174,7 +177,7 @@ public boolean stop() { @Override - public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { + public void preMigrateVm(VmInstanceInventory inv, String destHostUuid, Completion completion) { List nics = inv.getVmNics(); List l3vos = new ArrayList<>(); /* FIXME: shixin need add ipv6 on vlxan network */ @@ -189,11 +192,11 @@ public void preMigrateVm(VmInstanceInventory inv, String destHostUuid) { } if (vxlanUuids.isEmpty()) { + completion.success(); return; } ErrorCodeList errList = new ErrorCodeList(); - FutureCompletion completion = new FutureCompletion(null); new While<>(vxlanUuids).all((uuid, completion1) -> { PrepareL2NetworkOnHostMsg msg = new PrepareL2NetworkOnHostMsg(); @@ -217,31 +220,18 @@ public void run(MessageReply reply) { @Override public void done(ErrorCodeList errorCodeList) { if (!errList.getCauses().isEmpty()) { - completion.fail(errList.getCauses().get(0)); + completion.fail(operr("cannot configure vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", + inv.getUuid(), destHostUuid).causedBy(errList.getCauses())); return; } logger.info(String.format("check and realize vxlan networks[uuid: %s] for vm[uuid: %s] done", vxlanUuids, inv.getUuid())); completion.success(); } }); - - completion.await(TimeUnit.MINUTES.toMillis(30)); - if (!completion.isSuccess()) { - throw new OperationFailureException(operr("cannot configure vxlan network for vm[uuid:%s] on the destination host[uuid:%s]", - inv.getUuid(), destHostUuid).causedBy(completion.getErrorCode())); - } - } - - @Override - public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { - } - - @Override - public void afterMigrateVm(VmInstanceInventory inv, String srcHostUuid) { } @Override - public void failedToMigrateVm(VmInstanceInventory inv, String destHostUuid, ErrorCode reason) { + public void beforeMigrateVm(VmInstanceInventory inv, String destHostUuid) { } @Override @@ -257,7 +247,7 @@ public Integer getDefaultMtu(L2NetworkInventory inv) { @Override public Integer getL2NetworkVni(String l2NetworkUuid, String hostUuid) { VxlanNetworkVO vxlanNetworkVO = Q.New(VxlanNetworkVO.class).eq(VxlanNetworkVO_.uuid, l2NetworkUuid).find(); - return vxlanNetworkVO.getVni(); + return vxlanNetworkVO.getVirtualNetworkId(); } @Override @@ -293,4 +283,20 @@ public List filterL2NetworkCascade(List return l2invs; } } + + @Override + public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException { + vxlanInterceptor.intercept(msg); + return msg; + } + + @Override + public List getMessageClassToIntercept() { + return Collections.singletonList(APIChangeL2NetworkVlanIdMsg.class); + } + + @Override + public InterceptorPosition getPosition() { + return InterceptorPosition.FRONT; + } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkHelper.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkHelper.java new file mode 100644 index 00000000000..f40f557c1e1 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNetworkHelper.java @@ -0,0 +1,35 @@ +package org.zstack.network.l2.vxlan.vxlanNetwork; + +public class VxlanNetworkHelper { + public static boolean isValidVniRange(int startVni, int endVni) { + if (startVni < VxlanNetworkConstant.MIN_VNI || endVni < VxlanNetworkConstant.MIN_VNI) { + return false; + } + + if (startVni > VxlanNetworkConstant.MAX_VNI || endVni > VxlanNetworkConstant.MAX_VNI) { + return false; + } + + if (startVni > endVni) { + return false; + } + + return true; + } + + public static boolean isValidVlanRange(int startVlan, int endVlan) { + if (startVlan < VxlanNetworkConstant.MIN_VLAN || endVlan < VxlanNetworkConstant.MIN_VLAN) { + return false; + } + + if (startVlan > VxlanNetworkConstant.MAX_VLAN || endVlan > VxlanNetworkConstant.MAX_VLAN) { + return false; + } + + if (startVlan > endVlan) { + return false; + } + + return true; + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNumQuotaDefinition.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNumQuotaDefinition.java new file mode 100644 index 00000000000..a9d6bad387f --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetwork/VxlanNumQuotaDefinition.java @@ -0,0 +1,24 @@ +package org.zstack.network.l2.vxlan.vxlanNetwork; + +import org.zstack.core.db.SQL; +import org.zstack.header.identity.quota.QuotaDefinition; + +public class VxlanNumQuotaDefinition implements QuotaDefinition { + @Override + public String getName() { + return VxlanNetworkQuotaConstant.VXLAN_NUM; + } + + @Override + public Long getDefaultValue() { + return VxlanNetworkQuotaGlobalConfig.VXLAN_NUM.defaultValue(Long.class); + } + + @Override + public Long getQuotaUsage(String accountUuid) { + long cnt = SQL.New("select count(vxlan) from VxlanNetworkVO vxlan, AccountResourceRefVO ref " + + "where vxlan.uuid = ref.resourceUuid and ref.accountUuid = :auuid", Long.class) + .param("auuid", accountUuid).find(); + return cnt; + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEvent.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEvent.java index 398735feaf4..894dcd516ad 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEvent.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEvent.java @@ -1,6 +1,5 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; -import org.zstack.header.message.APIEvent; import org.zstack.header.network.l2.APICreateL2NetworkEvent; import org.zstack.header.rest.RestResponse; @@ -9,24 +8,14 @@ */ @RestResponse(allTo = "inventory") public class APICreateL2VxlanNetworkPoolEvent extends APICreateL2NetworkEvent { - private L2VxlanNetworkPoolInventory inventory; - public APICreateL2VxlanNetworkPoolEvent(String apiId) { super(apiId); } - public L2VxlanNetworkPoolInventory getInventory() { - return inventory; - } - public APICreateL2VxlanNetworkPoolEvent() { super(null); } - public void setInventory(L2VxlanNetworkPoolInventory inventory) { - this.inventory = inventory; - } - public static APICreateL2VxlanNetworkPoolEvent __example__() { APICreateL2VxlanNetworkPoolEvent event = new APICreateL2VxlanNetworkPoolEvent(); L2VxlanNetworkPoolInventory net = new L2VxlanNetworkPoolInventory(); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEventDoc_zh_cn.groovy index f86a4e13991..280cef1cc3f 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEventDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolEventDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vxlanNetworkPool.L2VxlanNetworkPoolInventory doc { - title "在这里输入结构的名称" + title "VXLAN资源池清单" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsg.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsg.java index 65460598086..9ccac6077d0 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsg.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsg.java @@ -1,7 +1,6 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; import org.springframework.http.HttpMethod; -import org.zstack.header.identity.Action; import org.zstack.header.message.APIParam; import org.zstack.header.message.OverriddenApiParam; import org.zstack.header.message.OverriddenApiParams; @@ -33,5 +32,4 @@ public static APICreateL2VxlanNetworkPoolMsg __example__() { return msg; } - } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsgDoc_zh_cn.groovy index 1456ccb9036..d9a7174559b 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateL2VxlanNetworkPoolMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateL2VxlanNetworkPoolEvent doc { - title "CreateL2VxlanNetworkPool" + title "创建VXLAN资源池(CreateL2VxlanNetworkPool)" category "network.l2" - desc """在这里填写API描述""" + desc """创建VXLAN资源池""" rest { request { @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,7 +38,6 @@ doc { type "String" optional true since "0.6" - } column { name "zoneUuid" @@ -49,57 +47,88 @@ doc { type "String" optional false since "0.6" - } column { name "physicalInterface" enclosedIn "params" - desc "" + desc "物理网卡" location "body" type "String" optional false since "0.6" - } column { name "type" enclosedIn "params" - desc "" + desc "二层网络类型" location "body" type "String" optional true since "0.6" - } column { name "resourceUuid" enclosedIn "params" - desc "" + desc "资源UUID。若指定,二层网络会使用该字段值作为UUID" location "body" type "String" optional true since "0.6" - } column { name "systemTags" enclosedIn "" - desc "" + desc "系统标签" location "body" type "List" optional true since "0.6" - } column { name "userTags" enclosedIn "" - desc "" + desc "用户标签" location "body" type "List" optional true since "0.6" - + } + column { + name "vSwitchType" + enclosedIn "params" + desc "虚拟交换机类型" + location "body" + type "String" + optional true + since "4.1.2" + values ("LinuxBridge","OvsDpdk","MacVlan") + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" + } + column { + name "isolated" + enclosedIn "params" + desc "" + location "body" + type "Boolean" + optional true + since "4.8.0" + } + column { + name "pvlan" + enclosedIn "params" + desc "" + location "body" + type "String" + optional true + since "4.8.0" } } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeEventDoc_zh_cn.groovy index 731563d117c..cb5bc0f4b75 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeEventDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeEventDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vxlanNetworkPool.VniRangeInventory doc { - title "在这里输入结构的名称" + title "VNI范围清单" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeMsgDoc_zh_cn.groovy index f4e36808f90..a76b7fde1e5 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVniRangeMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVniRangeEvent doc { - title "CreateVniRange" + title "创建VNI范围(CreateVniRange)d" category "network.l2" - desc """在这里填写API描述""" + desc """创建VNI范围""" rest { request { @@ -29,7 +29,6 @@ doc { type "String" optional false since "0.6" - } column { name "description" @@ -39,27 +38,24 @@ doc { type "String" optional true since "0.6" - } column { name "startVni" enclosedIn "params" - desc "" + desc "起始VNI" location "body" type "Integer" optional false since "0.6" - } column { name "endVni" enclosedIn "params" - desc "" + desc "结束VNI" location "body" type "Integer" optional false since "0.6" - } column { name "l2NetworkUuid" @@ -69,37 +65,42 @@ doc { type "String" optional false since "0.6" - } column { name "resourceUuid" enclosedIn "params" - desc "" + desc "资源UUID" location "body" type "String" optional true since "0.6" - } column { name "systemTags" enclosedIn "" - desc "" + desc "系统标签" location "body" type "List" optional true since "0.6" - } column { name "userTags" enclosedIn "" - desc "" + desc "用户标签" location "body" type "List" optional true since "0.6" - + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "3.4.0" } } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepEvent.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepEvent.java new file mode 100644 index 00000000000..4f71c0d6b00 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepEvent.java @@ -0,0 +1,42 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepInventory; + +@RestResponse(allTo = "inventory") +public class APICreateVxlanPoolRemoteVtepEvent extends APIEvent { + + private RemoteVtepInventory inventory; + + public APICreateVxlanPoolRemoteVtepEvent(String apiId) { + super(apiId); + } + + public APICreateVxlanPoolRemoteVtepEvent() { + super(null); + } + + public RemoteVtepInventory getInventory() { + return inventory; + } + + public void setInventory(RemoteVtepInventory inventory) { + this.inventory = inventory; + } + + public static APICreateVxlanPoolRemoteVtepEvent __example__() { + APICreateVxlanPoolRemoteVtepEvent event = new APICreateVxlanPoolRemoteVtepEvent(); + RemoteVtepInventory vtep = new RemoteVtepInventory(); + + vtep.setUuid(uuid()); + vtep.setVtepIp("10.10.1.1"); + vtep.setPort(8472); + vtep.setPoolUuid(uuid()); + vtep.setType("KVM_HOST_VXLAN"); + + event.setInventory(vtep); + return event; + } + +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..99cc170ad01 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepEventDoc_zh_cn.groovy @@ -0,0 +1,32 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool + +import org.zstack.network.l2.vxlan.vtep.RemoteVtepInventory +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "远端VXLAN隧道端点清单" + + ref { + name "inventory" + path "org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVxlanPoolRemoteVtepEvent.inventory" + desc "null" + type "RemoteVtepInventory" + since "4.7.11" + clz RemoteVtepInventory.class + } + field { + name "success" + desc "" + type "boolean" + since "4.7.11" + } + ref { + name "error" + path "org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVxlanPoolRemoteVtepEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.11" + clz ErrorCode.class + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepMsg.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepMsg.java new file mode 100644 index 00000000000..56343f9f2c7 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepMsg.java @@ -0,0 +1,68 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l2.L2NetworkMessage; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.network.l2.L2NetworkVO; + + +@RestRequest( + path = "/l2-networks/{l2NetworkUuid}/clusters/{clusterUuid}/remote-vtep-ip", + method = HttpMethod.POST, + responseClass = APICreateVxlanPoolRemoteVtepEvent.class, + parameterName = "params" +) +public class APICreateVxlanPoolRemoteVtepMsg extends APICreateMessage implements L2NetworkMessage { + + @APIParam + private String l2NetworkUuid; + + @APIParam + private String clusterUuid; + + @APIParam(maxLength = 15) + private String remoteVtepIp; + + @Override + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public String getRemoteVtepIp() { + return remoteVtepIp; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public void setRemoteVtepIp(String remoteVtepIp) { + this.remoteVtepIp = remoteVtepIp; + } + + public static APICreateVxlanPoolRemoteVtepMsg __example__() { + APICreateVxlanPoolRemoteVtepMsg msg = new APICreateVxlanPoolRemoteVtepMsg(); + + msg.setL2NetworkUuid(uuid()); + msg.setClusterUuid(uuid()); + msg.setRemoteVtepIp("10.10.1.1"); + + return msg; + } + +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..b08f42a7d81 --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APICreateVxlanPoolRemoteVtepMsgDoc_zh_cn.groovy @@ -0,0 +1,94 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool + +import org.zstack.network.l2.vxlan.vxlanNetworkPool.APICreateVxlanPoolRemoteVtepEvent + +doc { + title "创建远端VXLAN隧道端点(CreateVxlanPoolRemoteVtep)" + + category "network.l2" + + desc """创建远端VXLAN隧道端点""" + + rest { + request { + url "POST /v1/l2-networks/{l2NetworkUuid}/clusters/{clusterUuid}/remote-vtep-ip" + + header (Authorization: 'OAuth the-session-uuid') + + clz APICreateVxlanPoolRemoteVtepMsg.class + + desc """""" + + params { + + column { + name "l2NetworkUuid" + enclosedIn "params" + desc "二层网络UUID" + location "url" + type "String" + optional false + since "4.7.11" + } + column { + name "clusterUuid" + enclosedIn "params" + desc "集群UUID" + location "url" + type "String" + optional false + since "4.7.11" + } + column { + name "remoteVtepIp" + enclosedIn "params" + desc "远端隧道端点IP地址" + location "body" + type "String" + optional false + since "4.7.11" + } + column { + name "resourceUuid" + enclosedIn "params" + desc "资源UUID" + location "body" + type "String" + optional true + since "4.7.11" + } + column { + name "tagUuids" + enclosedIn "params" + desc "标签UUID列表" + location "body" + type "List" + optional true + since "4.7.11" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.11" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.11" + } + } + } + + response { + clz APICreateVxlanPoolRemoteVtepEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeEventDoc_zh_cn.groovy index fea1184e07f..eb90902f091 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeEventDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeEventDoc_zh_cn.groovy @@ -4,7 +4,7 @@ import org.zstack.header.errorcode.ErrorCode doc { - title "在这里输入结构的名称" + title "操作返回结果" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeMsgDoc_zh_cn.groovy index af5a91633d7..2e08c4889b8 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVniRangeMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import org.zstack.network.l2.vxlan.vxlanNetworkPool.APIDeleteVniRangeEvent doc { - title "DeleteVniRange" + title "删除VNI范围(DeleteVniRange)" category "network.l2" - desc """在这里填写API描述""" + desc """删除VNI范围""" rest { request { @@ -29,37 +29,33 @@ doc { type "String" optional false since "0.6" - } column { name "deleteMode" enclosedIn "" - desc "" + desc "删除模式" location "body" type "String" optional true since "0.6" - } column { name "systemTags" enclosedIn "" - desc "" + desc "系统标签" location "body" type "List" optional true since "0.6" - } column { name "userTags" enclosedIn "" - desc "" + desc "用户标签" location "body" type "List" optional true since "0.6" - } } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepEvent.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepEvent.java new file mode 100644 index 00000000000..65cfd1da6bf --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepEvent.java @@ -0,0 +1,24 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepInventory; +@RestResponse +public class APIDeleteVxlanPoolRemoteVtepEvent extends APIEvent { + + + public APIDeleteVxlanPoolRemoteVtepEvent(String apiId) { + super(apiId); + } + + public APIDeleteVxlanPoolRemoteVtepEvent() { + super(null); + } + + + public static APIDeleteVxlanPoolRemoteVtepEvent __example__() { + APIDeleteVxlanPoolRemoteVtepEvent event = new APIDeleteVxlanPoolRemoteVtepEvent(); + return event; + } + +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepEventDoc_zh_cn.groovy new file mode 100644 index 00000000000..96e1a3a76fd --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepEventDoc_zh_cn.groovy @@ -0,0 +1,23 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool + +import org.zstack.header.errorcode.ErrorCode + +doc { + + title "操作范围结果" + + field { + name "success" + desc "" + type "boolean" + since "4.7.11" + } + ref { + name "error" + path "org.zstack.network.l2.vxlan.vxlanNetworkPool.APIDeleteVxlanPoolRemoteVtepEvent.error" + desc "错误码,若不为null,则表示操作失败, 操作成功时该字段为null",false + type "ErrorCode" + since "4.7.11" + clz ErrorCode.class + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepMsg.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepMsg.java new file mode 100644 index 00000000000..23a8c6320dd --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepMsg.java @@ -0,0 +1,68 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool; + +import org.springframework.http.HttpMethod; +import org.zstack.header.identity.Action; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIEvent; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.network.l2.L2NetworkMessage; +import org.zstack.header.other.APIAuditor; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.network.l2.L2NetworkVO; +import org.zstack.header.message.APIDeleteMessage; + +@RestRequest( + path = "/l2-networks/{l2NetworkUuid}/clusters/{clusterUuid}/delete/remote-vtep-ip", + method = HttpMethod.DELETE, + responseClass = APIDeleteVxlanPoolRemoteVtepEvent.class +) +public class APIDeleteVxlanPoolRemoteVtepMsg extends APIDeleteMessage implements L2NetworkMessage { + + @APIParam + private String l2NetworkUuid; + + @APIParam + private String clusterUuid; + + @APIParam(maxLength = 15) + private String remoteVtepIp; + + @Override + public String getL2NetworkUuid() { + return l2NetworkUuid; + } + + public String getClusterUuid() { + return clusterUuid; + } + + public String getRemoteVtepIp() { + return remoteVtepIp; + } + + public void setClusterUuid(String clusterUuid) { + this.clusterUuid = clusterUuid; + } + + public void setL2NetworkUuid(String l2NetworkUuid) { + this.l2NetworkUuid = l2NetworkUuid; + } + + public void setRemoteVtepIp(String remoteVtepIp) { + this.remoteVtepIp = remoteVtepIp; + } + + public static APIDeleteVxlanPoolRemoteVtepMsg __example__() { + APIDeleteVxlanPoolRemoteVtepMsg msg = new APIDeleteVxlanPoolRemoteVtepMsg(); + + msg.setL2NetworkUuid(uuid()); + msg.setClusterUuid(uuid()); + msg.setRemoteVtepIp("10.10.1.1"); + + return msg; + } + + +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepMsgDoc_zh_cn.groovy new file mode 100644 index 00000000000..9670203582d --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIDeleteVxlanPoolRemoteVtepMsgDoc_zh_cn.groovy @@ -0,0 +1,85 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool + +import org.zstack.network.l2.vxlan.vxlanNetworkPool.APIDeleteVxlanPoolRemoteVtepEvent + +doc { + title "删除远端VXLAN隧道端点(DeleteVxlanPoolRemoteVtep)" + + category "network.l2" + + desc """删除远端VXLAN隧道端点""" + + rest { + request { + url "DELETE /v1/l2-networks/{l2NetworkUuid}/clusters/{clusterUuid}/delete/remote-vtep-ip" + + header (Authorization: 'OAuth the-session-uuid') + + clz APIDeleteVxlanPoolRemoteVtepMsg.class + + desc """""" + + params { + + column { + name "l2NetworkUuid" + enclosedIn "" + desc "二层网络UUID" + location "url" + type "String" + optional false + since "4.7.11" + } + column { + name "clusterUuid" + enclosedIn "" + desc "集群UUID" + location "url" + type "String" + optional false + since "4.7.11" + } + column { + name "remoteVtepIp" + enclosedIn "" + desc "远端隧道端点IP地址" + location "body" + type "String" + optional false + since "4.7.11" + } + column { + name "deleteMode" + enclosedIn "" + desc "删除模式(Permissive / Enforcing,Permissive)" + location "body" + type "String" + optional true + since "4.7.11" + } + column { + name "systemTags" + enclosedIn "" + desc "系统标签" + location "body" + type "List" + optional true + since "4.7.11" + } + column { + name "userTags" + enclosedIn "" + desc "用户标签" + location "body" + type "List" + optional true + since "4.7.11" + } + } + } + + response { + clz APIDeleteVxlanPoolRemoteVtepEvent.class + } + } +} \ No newline at end of file diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolMsgDoc_zh_cn.groovy index 807076317e5..c4bc2777d4a 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolMsgDoc_zh_cn.groovy @@ -2,14 +2,13 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import org.zstack.network.l2.vxlan.vxlanNetworkPool.APIQueryL2VxlanNetworkPoolReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { - title "QueryL2VxlanNetworkPool" + title "查询VXLAN资源池(QueryL2VxlanNetworkPool)" category "network.l2" - desc """在这里填写API描述""" + desc """查询VXLAN资源池""" rest { request { diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolReplyDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolReplyDoc_zh_cn.groovy index 06336d17df7..2c3325d1c8a 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolReplyDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryL2VxlanNetworkPoolReplyDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vxlanNetworkPool.L2VxlanNetworkPoolInventory doc { - title "在这里输入结构的名称" + title "VXLAN资源池清单列表" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeMsgDoc_zh_cn.groovy index 645ea1dfacf..ccfad83c4dc 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeMsgDoc_zh_cn.groovy @@ -2,14 +2,13 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import org.zstack.network.l2.vxlan.vxlanNetworkPool.APIQueryVniRangeReply import org.zstack.header.query.APIQueryMessage -import org.zstack.header.query.APIQueryMessage doc { - title "QueryVniRange" + title "查询VNI范围(QueryVniRange)" category "network.l2" - desc """在这里填写API描述""" + desc """查询VNI范围""" rest { request { diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeReplyDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeReplyDoc_zh_cn.groovy index a0338843ce8..6c46a822e4f 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeReplyDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIQueryVniRangeReplyDoc_zh_cn.groovy @@ -5,7 +5,7 @@ import org.zstack.network.l2.vxlan.vxlanNetworkPool.VniRangeInventory doc { - title "在这里输入结构的名称" + title "VNI范围清单列表" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeEventDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeEventDoc_zh_cn.groovy index 7839e77e07c..eb530b434a2 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeEventDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeEventDoc_zh_cn.groovy @@ -4,7 +4,7 @@ import org.zstack.header.errorcode.ErrorCode doc { - title "修改 Vni Range" + title "操作返回结果" field { name "success" diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeMsgDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeMsgDoc_zh_cn.groovy index ce0d2aa26ed..cc5a6aefcc6 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeMsgDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/APIUpdateVniRangeMsgDoc_zh_cn.groovy @@ -3,11 +3,11 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import org.zstack.network.l2.vxlan.vxlanNetworkPool.APIUpdateVniRangeEvent doc { - title "UpdateVniRange" + title "修改VNI范围(UpdateVniRange)" category "network.l2" - desc """修改 Vni Range""" + desc """修改VNI范围""" rest { request { @@ -15,7 +15,6 @@ doc { header (Authorization: 'OAuth the-session-uuid') - clz APIUpdateVniRangeMsg.class desc """""" @@ -24,38 +23,35 @@ doc { column { name "uuid" - enclosedIn "" + enclosedIn "updateVniRange" desc "资源的UUID,唯一标示该资源" location "url" type "String" optional false since "3.3.0" } - column { name "name" - enclosedIn "" - desc "" + enclosedIn "updateVniRange" + desc "资源名称" location "body" type "String" - optional true + optional false since "3.3.0" } - column { name "systemTags" enclosedIn "" - desc "" + desc "系统标签" location "body" type "List" optional true since "3.3.0" } - column { name "userTags" enclosedIn "" - desc "" + desc "用户标签" location "body" type "List" optional true diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java index 951e215148a..0fba2988fcf 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkBackend.java @@ -1,5 +1,8 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; +import org.zstack.network.l2.L2NetworkGlobalConfig; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepVO; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepVO_; import org.springframework.beans.factory.annotation.Autowired; import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; @@ -58,6 +61,7 @@ public class KVMRealizeL2VxlanNetworkBackend implements L2NetworkRealizationExte private CloudBus bus; private static String VTEP_IP = "vtepIp"; + private static String PHYSICAL_INTERFACE = "physicalInterface"; private static String NEED_POPULATE = "needPopulate"; public static String makeBridgeName(int vxlan) { @@ -92,9 +96,18 @@ public void realize(final L2NetworkInventory l2Network, final String hostUuid, b peers.clear(); peers.addAll(p); + //add remote vtep ip + String clusterUuid = Q.New(HostVO.class).select(HostVO_.clusterUuid).eq(HostVO_.uuid, hostUuid).findValue(); + + List gwpeers = Q.New(RemoteVtepVO.class).select(RemoteVtepVO_.vtepIp).eq(RemoteVtepVO_.poolUuid, l2vxlan.getPoolUuid()).eq(RemoteVtepVO_.clusterUuid, clusterUuid).listValues(); + if (gwpeers.size() > 0) { + Set gwp = new HashSet(gwpeers); + peers.addAll(gwp); + } + String info = String.format( "get vtep peers [%s] and vtep ip [%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s]", peers, - vtepIp, l2Network.getUuid(), l2Network.getType(), l2vxlan.getVni(), hostUuid); + vtepIp, l2Network.getUuid(), l2Network.getType(), l2vxlan.getVirtualNetworkId(), hostUuid); logger.debug(info); List dstports = Q.New(VtepVO.class).select(VtepVO_.port) @@ -106,12 +119,14 @@ public void realize(final L2NetworkInventory l2Network, final String hostUuid, b final VxlanKvmAgentCommands.CreateVxlanBridgeCmd cmd = new VxlanKvmAgentCommands.CreateVxlanBridgeCmd(); cmd.setVtepIp(vtepIp); - cmd.setBridgeName(makeBridgeName(l2vxlan.getVni())); - cmd.setVni(l2vxlan.getVni()); + cmd.setBridgeName(getBridgeName(l2vxlan)); + cmd.setVni(l2vxlan.getVirtualNetworkId()); cmd.setL2NetworkUuid(l2Network.getUuid()); cmd.setPeers(peers); cmd.setDstport(dstport); cmd.setMtu(new MtuGetter().getL2Mtu(l2Network)); + cmd.setIgmpVersion(L2NetworkGlobalConfig.IGMPVersion.value(Integer.class)); + cmd.setMldVersion(L2NetworkGlobalConfig.MLDVersion.value(Integer.class)); KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(hostUuid); @@ -131,14 +146,14 @@ public void run(MessageReply reply) { VxlanKvmAgentCommands.CreateVxlanBridgeResponse rsp = hreply.toResponse(VxlanKvmAgentCommands.CreateVxlanBridgeResponse.class); if (!rsp.isSuccess()) { ErrorCode err = operr("failed to create bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s], because %s", - cmd.getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVni(), hostUuid, rsp.getError()); + cmd.getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVirtualNetworkId(), hostUuid, rsp.getError()); completion.fail(err); return; } String info = String.format( "successfully realize bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s]", cmd - .getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVni(), hostUuid); + .getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVirtualNetworkId(), hostUuid); logger.debug(info); SystemTagCreator creator = KVMSystemTags.L2_BRIDGE_NAME.newSystemTagCreator(l2Network.getUuid()); @@ -152,6 +167,56 @@ public void run(MessageReply reply) { }); } + @Override + public void update(L2NetworkInventory oldL2, L2NetworkInventory newL2, String hostUuid, Completion completion) { + final KVMAgentCommands.UpdateL2NetworkCmd cmd = new KVMAgentCommands.UpdateL2NetworkCmd(); + + String vxlanPoolUuid = Q.New(VxlanNetworkVO.class).select(VxlanNetworkVO_.poolUuid) + .eq(VxlanNetworkVO_.uuid, oldL2.getUuid()).findValue(); + List vteps = Q.New(VtepVO.class).eq(VtepVO_.poolUuid, vxlanPoolUuid).list(); + List peers = vteps.stream() + .filter(v -> !v.getHostUuid().equals(hostUuid)) + .map(VtepVO::getVtepIp) + .collect(Collectors.toList()); + cmd.setL2NetworkUuid(newL2.getUuid()); + cmd.setBridgeName(getBridgeName(oldL2)); + cmd.setPhysicalInterfaceName(newL2.getPhysicalInterface()); + cmd.setOldVlan(String.valueOf(oldL2.getVirtualNetworkId())); + cmd.setNewVlan(newL2.getVirtualNetworkId().toString()); + cmd.setPeers(peers); + + KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); + msg.setNoStatusCheck(false); + msg.setCommand(cmd); + msg.setHostUuid(hostUuid); + msg.setPath(KVMConstant.KVM_UPDATE_L2VXLAN_NETWORK_PATH); + bus.makeTargetServiceIdByResourceUuid(msg, HostConstant.SERVICE_ID, hostUuid); + bus.send(msg, new CloudBusCallBack(completion) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + completion.fail(reply.getError()); + return; + } + + KVMHostAsyncHttpCallReply hreply = reply.castReply(); + KVMAgentCommands.UpdateL2NetworkResponse rsp = hreply.toResponse(KVMAgentCommands.UpdateL2NetworkResponse.class); + if (!rsp.isSuccess()) { + ErrorCode err = operr("failed to update bridge[%s] for l2Network[uuid:%s, name:%s] on kvm host[uuid: %s], %s", + cmd.getBridgeName(), newL2.getUuid(), newL2.getName(), hostUuid, rsp.getError()); + completion.fail(err); + return; + } + + String info = String.format("successfully update bridge[%s] for l2Network[uuid:%s, name:%s] on kvm host[uuid: %s]", + cmd.getBridgeName(), newL2.getUuid(), newL2.getName(), hostUuid); + logger.debug(info); + completion.success(); + } + }); + + } + @Override public void check(final L2NetworkInventory l2Network, final String hostUuid, final Completion completion) { check(l2Network, hostUuid, false, completion); @@ -204,6 +269,7 @@ public void run(MessageReply reply) { cmd.getCidr(), l2vxlan.getUuid(), l2vxlan.getName(), hostUuid); logger.debug(info); data.put(VTEP_IP, rsp.getVtepIp()); + data.put(PHYSICAL_INTERFACE, rsp.getPhysicalInterfaceName()); trigger.next(); } @@ -225,6 +291,11 @@ public void run(FlowTrigger trigger, Map data) { vtepVOS.stream().map(v -> v.getVtepIp()).collect(Collectors.toSet()), hostUuid)); } else if (vtepVOS.get(0).getVtepIp().equals(data.get(VTEP_IP))) { /* vtep is already created */ + if (data.get(PHYSICAL_INTERFACE) != null && + !data.get(PHYSICAL_INTERFACE).equals(vtepVOS.get(0).getPhysicalInterface())) { + vtepVOS.get(0).setPhysicalInterface((String) data.get(PHYSICAL_INTERFACE)); + dbf.update(vtepVOS.get(0)); + } logger.debug(String.format( "vtep[ip:%s] from host[uuid:%s] for l2 vxlan network pool[uuid:%s] checks successfully", vtepVOS.get(0).getVtepIp(), hostUuid, l2Network.getUuid())); @@ -246,6 +317,7 @@ public void run(FlowTrigger trigger, Map data) { cmsg.setHostUuid(hostUuid); cmsg.setPort(VXLAN_PORT); cmsg.setVtepIp((String) data.get(VTEP_IP)); + cmsg.setPhysicalInterface((String) data.get(PHYSICAL_INTERFACE)); cmsg.setType(KVM_VXLAN_TYPE); bus.makeTargetServiceIdByResourceUuid(cmsg, L2NetworkConstant.SERVICE_ID, l2vxlan.getPoolUuid()); @@ -292,7 +364,7 @@ public void run(FlowTrigger trigger, Map data) { VxlanKvmAgentCommands.PopulateVxlanFdbCmd cmd = new VxlanKvmAgentCommands.PopulateVxlanFdbCmd(); cmd.setPeers(peers); - cmd.setVni(l2vxlan.getVni()); + cmd.setVni(l2vxlan.getVirtualNetworkId()); KVMHostAsyncHttpCallMsg msg = new KVMHostAsyncHttpCallMsg(); msg.setHostUuid(vtep.getHostUuid()); @@ -339,6 +411,11 @@ public HypervisorType getSupportedHypervisorType() { return HypervisorType.valueOf(KVMConstant.KVM_HYPERVISOR_TYPE); } + @Override + public VSwitchType getSupportedVSwitchType() { + return VSwitchType.valueOf(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + } + @Override public L2NetworkType getL2NetworkTypeVmNicOn() { return getSupportedL2NetworkType(); @@ -346,13 +423,9 @@ public L2NetworkType getL2NetworkTypeVmNicOn() { @Override public KVMAgentCommands.NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { - final Integer vni = getVni(l2Network.getUuid()); - KVMAgentCommands.NicTO to = new KVMAgentCommands.NicTO(); - to.setMac(nic.getMac()); - to.setUuid(nic.getUuid()); - to.setBridgeName(makeBridgeName(vni)); - to.setDeviceId(nic.getDeviceId()); - to.setNicInternalName(nic.getInternalName()); + final Integer vni = getVirtualNetworkId(l2Network.getUuid()); + KVMAgentCommands.NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); + to.setBridgeName(getBridgeName(l2Network)); to.setMetaData(String.valueOf(vni)); to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); return to; @@ -360,7 +433,10 @@ public KVMAgentCommands.NicTO completeNicInformation(L2NetworkInventory l2Networ @Override public String getBridgeName(L2NetworkInventory l2Network) { - final Integer vni = getVni(l2Network.getUuid()); + if (KVMSystemTags.L2_BRIDGE_NAME.hasTag(l2Network.getUuid(), L2NetworkVO.class)) { + return KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2Network.getUuid(), KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + } + final Integer vni = getVirtualNetworkId(l2Network.getUuid()); return makeBridgeName(vni); } @@ -375,10 +451,10 @@ public Map getAttachedCidrs(String l2NetworkUuid) { return attachedClusters; } - private Integer getVni(String l2NetworkUuid) { + private Integer getVirtualNetworkId(String l2NetworkUuid) { return Q.New(VxlanNetworkVO.class) .eq(VxlanNetworkVO_.uuid, l2NetworkUuid) - .select(VxlanNetworkVO_.vni) + .select(VxlanNetworkVO_.virtualNetworkId) .findValue(); } @@ -447,8 +523,8 @@ public void delete(L2NetworkInventory l2Network, String hostUuid, Completion com L2VxlanNetworkInventory l2vxlan = (L2VxlanNetworkInventory) l2Network; final VxlanKvmAgentCommands.DeleteVxlanBridgeCmd cmd = new VxlanKvmAgentCommands.DeleteVxlanBridgeCmd(); - cmd.setBridgeName(makeBridgeName(l2vxlan.getVni())); - cmd.setVni(l2vxlan.getVni()); + cmd.setBridgeName(getBridgeName(l2vxlan)); + cmd.setVni(l2vxlan.getVirtualNetworkId()); cmd.setL2NetworkUuid(l2Network.getUuid()); final List vtepIps = Q.New(VtepVO.class).select(VtepVO_.vtepIp).eq(VtepVO_.hostUuid, hostUuid).eq(VtepVO_.poolUuid, l2vxlan.getPoolUuid()).listValues(); @@ -472,14 +548,14 @@ public void run(MessageReply reply) { VxlanKvmAgentCommands.DeleteVxlanBridgeResponse rsp = hreply.toResponse(VxlanKvmAgentCommands.DeleteVxlanBridgeResponse.class); if (!rsp.isSuccess()) { ErrorCode err = operr("failed to delete bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s], because %s", - cmd.getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVni(), hostUuid, rsp.getError()); + cmd.getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVirtualNetworkId(), hostUuid, rsp.getError()); completion.fail(err); return; } String message = String.format( "successfully delete bridge[%s] for l2Network[uuid:%s, type:%s, vni:%s] on kvm host[uuid:%s]", cmd - .getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVni(), hostUuid); + .getBridgeName(), l2Network.getUuid(), l2Network.getType(), l2vxlan.getVirtualNetworkId(), hostUuid); logger.debug(message); completion.success(); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java index 371f2d1df1f..728e49bff18 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/KVMRealizeL2VxlanNetworkPoolBackend.java @@ -1,16 +1,13 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; import org.springframework.beans.factory.annotation.Autowired; -import org.zstack.core.asyncbatch.While; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; -import org.zstack.core.componentloader.PluginRegistry; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.Q; import org.zstack.core.db.SQL; import org.zstack.core.workflow.FlowChainBuilder; import org.zstack.header.core.Completion; -import org.zstack.header.core.NoErrorCompletion; import org.zstack.header.core.workflow.*; import org.zstack.header.errorcode.ErrorCode; import org.zstack.header.exception.CloudRuntimeException; @@ -23,15 +20,12 @@ import org.zstack.header.network.l3.L3NetworkInventory; import org.zstack.header.vm.VmNicInventory; import org.zstack.kvm.*; -import org.zstack.network.l2.L2NetworkDefaultMtu; -import org.zstack.network.l2.L2NetworkManager; +import org.zstack.network.l2.L2NetworkGlobalConfig; import org.zstack.network.l2.vxlan.vtep.CreateVtepMsg; import org.zstack.network.l2.vxlan.vtep.VtepVO; import org.zstack.network.l2.vxlan.vtep.VtepVO_; import org.zstack.network.l2.vxlan.vxlanNetwork.*; import org.zstack.network.service.MtuGetter; -import org.zstack.network.service.NetworkServiceGlobalConfig; -import org.zstack.resourceconfig.ResourceConfigFacade; import org.zstack.tag.SystemTagCreator; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; @@ -58,6 +52,7 @@ public class KVMRealizeL2VxlanNetworkPoolBackend implements L2NetworkRealization private VxlanNetworkFactory VxlanNetworkFactory; private static String VTEP_IP = "vtepIp"; + private static String PHYSICAL_INTERFACE = "physicalInterface"; private static String NEED_POPULATE = "needPopulate"; @Override @@ -115,6 +110,7 @@ public void run(MessageReply reply) { } data.put(VTEP_IP, rsp.getVtepIp()); + data.put(PHYSICAL_INTERFACE, rsp.getPhysicalInterfaceName()); String info = String.format("successfully checked cidr[%s] for l2VxlanNetworkPool[uuid:%s, name:%s] on kvm host[uuid:%s]", cmd.getCidr(), vxlanPool.getUuid(), vxlanPool.getName(), hostUuid); logger.debug(info); @@ -147,6 +143,11 @@ public void run(FlowTrigger trigger, Map data) { vtepVOS.stream().map(VtepVO::getVtepIp).collect(Collectors.toSet()), hostUuid)); } else if (vtepVOS.get(0).getVtepIp().equals(data.get(VTEP_IP))) { + if (data.get(PHYSICAL_INTERFACE) != null && + !data.get(PHYSICAL_INTERFACE).equals(vtepVOS.get(0).getPhysicalInterface())) { + vtepVOS.get(0).setPhysicalInterface((String) data.get(PHYSICAL_INTERFACE)); + dbf.update(vtepVOS.get(0)); + } logger.debug(String.format( "vtep[ip:%s] from host[uuid:%s] for l2 vxlan network pool[uuid:%s] checks successfully", vtepVOS.get(0).getVtepIp(), hostUuid, l2Network.getUuid())); @@ -169,6 +170,7 @@ public void run(FlowTrigger trigger, Map data) { cmsg.setHostUuid(hostUuid); cmsg.setPort(VXLAN_PORT); cmsg.setVtepIp((String) data.get(VTEP_IP)); + cmsg.setPhysicalInterface((String) data.get(PHYSICAL_INTERFACE)); cmsg.setType(KVM_VXLAN_TYPE); bus.makeTargetServiceIdByResourceUuid(cmsg, L2NetworkConstant.SERVICE_ID, l2Network.getUuid()); @@ -233,11 +235,13 @@ public void run(FlowTrigger trigger, Map data) { for (VxlanNetworkVO vo : vxlanNetworkVOS) { VxlanKvmAgentCommands.CreateVxlanBridgeCmd bridgeCmd = new VxlanKvmAgentCommands.CreateVxlanBridgeCmd(); bridgeCmd.setVtepIp((String) data.get(VTEP_IP)); - bridgeCmd.setBridgeName(KVMRealizeL2VxlanNetworkBackend.makeBridgeName(vo.getVni())); - bridgeCmd.setVni(vo.getVni()); + bridgeCmd.setBridgeName(getBridgeName(vo.toInventory())); + bridgeCmd.setVni(vo.getVirtualNetworkId()); bridgeCmd.setDstport(dstport); bridgeCmd.setL2NetworkUuid(vo.getUuid()); bridgeCmd.setMtu(new MtuGetter().getL2Mtu(L2VxlanNetworkInventory.valueOf(vo))); + bridgeCmd.setIgmpVersion(L2NetworkGlobalConfig.IGMPVersion.value(Integer.class)); + bridgeCmd.setMldVersion(L2NetworkGlobalConfig.MLDVersion.value(Integer.class)); cmd.getBridgeCmds().add(bridgeCmd); } @@ -274,7 +278,7 @@ public void run(MessageReply reply) { creator.inherent = true; creator.ignoreIfExisting = true; creator.setTagByTokens(map(e(KVMSystemTags.L2_BRIDGE_NAME_TOKEN, - KVMRealizeL2VxlanNetworkBackend.makeBridgeName(vo.getVni())))); + getBridgeName(vo.toInventory())))); creator.create(); } trigger.next(); @@ -304,6 +308,11 @@ public HypervisorType getSupportedHypervisorType() { return HypervisorType.valueOf("KVM"); } + @Override + public VSwitchType getSupportedVSwitchType() { + return VSwitchType.valueOf(L2NetworkConstant.VSWITCH_TYPE_LINUX_BRIDGE); + } + @Override public L2NetworkType getL2NetworkTypeVmNicOn() { return getSupportedL2NetworkType(); @@ -311,18 +320,18 @@ public L2NetworkType getL2NetworkTypeVmNicOn() { @Override public KVMAgentCommands.NicTO completeNicInformation(L2NetworkInventory l2Network, L3NetworkInventory l3Network, VmNicInventory nic) { - KVMAgentCommands.NicTO to = new KVMAgentCommands.NicTO(); - to.setMac(nic.getMac()); - to.setUuid(nic.getUuid()); - to.setDeviceId(nic.getDeviceId()); - to.setNicInternalName(nic.getInternalName()); + KVMAgentCommands.NicTO to = KVMAgentCommands.NicTO.fromVmNicInventory(nic); to.setMtu(new MtuGetter().getMtu(l3Network.getUuid())); return to; } @Override public String getBridgeName(L2NetworkInventory l2Network) { - return null; + VxlanNetworkVO vo = dbf.findByUuid(l2Network.getUuid(), VxlanNetworkVO.class); + if (KVMSystemTags.L2_BRIDGE_NAME.hasTag(l2Network.getUuid(), L2NetworkVO.class)) { + return KVMSystemTags.L2_BRIDGE_NAME.getTokenByResourceUuid(l2Network.getUuid(), KVMSystemTags.L2_BRIDGE_NAME_TOKEN); + } + return KVMRealizeL2VxlanNetworkBackend.makeBridgeName(vo.getVirtualNetworkId()); } public Map getAttachedCidrs(String l2NetworkUuid) { diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventory.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventory.java index 5184542e19a..183f029cc34 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventory.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventory.java @@ -1,5 +1,7 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepInventory; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepVO; import org.zstack.core.db.Q; import org.zstack.header.configuration.PythonClassInventory; import org.zstack.header.message.NoJsonSchema; @@ -29,6 +31,8 @@ foreignKey = "uuid", expandedInventoryKey = "l2NetworkUuid"), @ExpandedQuery(expandedField = "l2VxlanNetwork", inventoryClass = L2VxlanNetworkInventory.class, foreignKey = "uuid", expandedInventoryKey = "poolUuid"), + @ExpandedQuery(expandedField = "remotevtep", inventoryClass = RemoteVtepInventory.class, + foreignKey = "uuid", expandedInventoryKey = "poolUuid"), @ExpandedQuery(expandedField = "vtep", inventoryClass = VtepInventory.class, foreignKey = "uuid", expandedInventoryKey = "poolUuid") }) @@ -37,6 +41,10 @@ public class L2VxlanNetworkPoolInventory extends L2NetworkInventory { joinColumn = @JoinColumn(name = "poolUuid")) private List attachedVtepRefs; + @Queryable(mappingClass = RemoteVtepInventory.class, + joinColumn = @JoinColumn(name = "poolUuid")) + private List remoteVteps; + @Queryable(mappingClass = L2VxlanNetworkInventory.class, joinColumn = @JoinColumn(name = "poolUuid")) private List attachedVxlanNetworkRefs; @@ -64,6 +72,7 @@ protected L2VxlanNetworkPoolInventory(VxlanNetworkPoolVO vo) { } setAttachedCidrs(attachedCidrs); setAttachedVniRanges(VniRangeInventory.valueOf(vo.getAttachedVniRanges())); + setRemoteVteps(RemoteVtepInventory.valueOf(vo.getRemoteVteps())); setAttachedVtepRefs(VtepInventory.valueOf(vo.getAttachedVtepRefs())); List networkVOS = Q.New(VxlanNetworkVO.class).eq(VxlanNetworkVO_.poolUuid, vo.getUuid()).list(); setAttachedVxlanNetworkRefs(L2VxlanNetworkInventory.valueOf1(networkVOS)); @@ -81,6 +90,14 @@ public static List valueOf1(Collection getRemoteVteps() { + return remoteVteps; + } + + public void setRemoteVteps(List remoteVteps) { + this.remoteVteps = remoteVteps; + } + public List getAttachedVtepRefs() { return attachedVtepRefs; } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventoryDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventoryDoc_zh_cn.groovy index 833b0ca2096..277e6126ecf 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventoryDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/L2VxlanNetworkPoolInventoryDoc_zh_cn.groovy @@ -8,7 +8,7 @@ import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "VXLAN资源池清单" ref { name "attachedVtepRefs" @@ -36,7 +36,7 @@ doc { } field { name "attachedCidrs" - desc "" + desc "已加载CIDR映射表" type "Map" since "0.6" } @@ -66,13 +66,13 @@ doc { } field { name "physicalInterface" - desc "" + desc "物理网卡" type "String" since "0.6" } field { name "type" - desc "" + desc "二层网络类型" type "String" since "0.6" } @@ -90,7 +90,7 @@ doc { } field { name "attachedClusterUuids" - desc "" + desc "挂载集群的UUID列表" type "List" since "0.6" } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/PopulateRemoteVtepPeersMsg.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/PopulateRemoteVtepPeersMsg.java new file mode 100644 index 00000000000..fa1e0633a4c --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/PopulateRemoteVtepPeersMsg.java @@ -0,0 +1,43 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool; + +import org.zstack.header.host.HostInventory; +import org.zstack.header.message.NeedReplyMessage; +import org.zstack.header.network.l2.L2NetworkMessage; + +import java.util.ArrayList; +import java.util.List; + +public class PopulateRemoteVtepPeersMsg extends NeedReplyMessage implements L2NetworkMessage { + private String poolUuid; + private String vtepIp; + private List hosts = new ArrayList<>(); + + public String getPoolUuid() { + return poolUuid; + } + + public String getVtepIp() { + return vtepIp; + } + + public void setPoolUuid(String poolUuid) { + this.poolUuid = poolUuid; + } + + public void setVtepIp(String vtepIp) { + this.vtepIp = vtepIp; + } + + @Override + public String getL2NetworkUuid() { + return getPoolUuid(); + } + + public List getHosts() { + return hosts; + } + + public void setHosts(List hosts) { + this.hosts = hosts; + } +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/PopulateRemoteVtepPeersReply.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/PopulateRemoteVtepPeersReply.java new file mode 100644 index 00000000000..48a995e17dc --- /dev/null +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/PopulateRemoteVtepPeersReply.java @@ -0,0 +1,6 @@ +package org.zstack.network.l2.vxlan.vxlanNetworkPool; + +import org.zstack.header.message.MessageReply; + +public class PopulateRemoteVtepPeersReply extends MessageReply { +} diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/RandomVniAllocatorStrategy.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/RandomVniAllocatorStrategy.java index 7e5df60ab1c..b9cc6c26a07 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/RandomVniAllocatorStrategy.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/RandomVniAllocatorStrategy.java @@ -17,6 +17,7 @@ public class RandomVniAllocatorStrategy extends AbstractVniAllocatorStrategy { private static final CLogger logger = Utils.getLogger(RandomVniAllocatorStrategy.class); public static final VniAllocatorType type = new VniAllocatorType(VxlanNetworkPoolConstant.RANDOM_VNI_ALLOCATOR_STRATEGY); + private static final Random random = new Random(); @Override public VniAllocatorType getType() { @@ -57,7 +58,6 @@ public Integer allocateVni(VniAllocateMessage msg) { private Integer allocateVni(VniRangeVO vo) { int total = vo.size(); - Random random = new Random(); Integer s = random.nextInt(total) + vo.getStartVni(); Integer e = vo.getEndVni(); Integer ret = steppingAllocate(s, e, total, vo.getUuid(), vo.getL2NetworkUuid()); @@ -128,7 +128,6 @@ private static Integer randomAllocateVni(Integer startVni, Integer endVni, List< full.set(alloc - startVni); } - Random random = new Random(); int next = random.nextInt(total); int a = full.nextClearBit(next); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VniRangeInventoryDoc_zh_cn.groovy b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VniRangeInventoryDoc_zh_cn.groovy index 54b192b1988..a7fcb7220d5 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VniRangeInventoryDoc_zh_cn.groovy +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VniRangeInventoryDoc_zh_cn.groovy @@ -1,13 +1,11 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool import java.lang.Integer -import java.lang.Integer -import java.sql.Timestamp import java.sql.Timestamp doc { - title "在这里输入结构的名称" + title "vni范围清单" field { name "uuid" @@ -29,13 +27,13 @@ doc { } field { name "startVni" - desc "" + desc "起始VNI" type "Integer" since "0.6" } field { name "endVni" - desc "" + desc "结束VNI" type "Integer" since "0.6" } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanKvmAgentCommands.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanKvmAgentCommands.java index f76152f38fc..00d623a0e2d 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanKvmAgentCommands.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanKvmAgentCommands.java @@ -1,5 +1,6 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; +import org.zstack.core.upgrade.GrayVersion; import org.zstack.core.validation.ConditionalValidation; import org.zstack.kvm.KVMAgentCommands; @@ -103,13 +104,24 @@ public static class DeleteVxlanBridgesResponse extends AgentResponse { public static class CreateVxlanBridgeCmd extends AgentCommand { + @GrayVersion(value = "5.3.0") private String bridgeName; + @GrayVersion(value = "5.3.0") private String vtepIp; + @GrayVersion(value = "5.3.0") private Integer vni; + @GrayVersion(value = "5.3.0") private Integer dstport; + @GrayVersion(value = "5.3.0") private String l2NetworkUuid; + @GrayVersion(value = "5.3.0") private List peers; + @GrayVersion(value = "5.3.0") private Integer mtu; + @GrayVersion(value = "5.3.0") + private Integer igmpVersion; + @GrayVersion(value = "5.3.0") + private Integer mldVersion; public Integer getDstport() { return dstport; @@ -166,6 +178,22 @@ public Integer getMtu() { public void setMtu(Integer mtu) { this.mtu = mtu; } + + public Integer getIgmpVersion() { + return igmpVersion; + } + + public void setIgmpVersion(Integer igmpVersion) { + this.igmpVersion = igmpVersion; + } + + public Integer getMldVersion() { + return mldVersion; + } + + public void setMldVersion(Integer mldVersion) { + this.mldVersion = mldVersion; + } } public static class CreateVxlanBridgeResponse extends CreateBridgeResponse { @@ -234,6 +262,30 @@ public void setPeers(List peers) { public static class PopulateVxlanNetworksFdbResponse extends AgentResponse { } + public static class DeleteVxlanNetworksFdbCmd extends AgentCommand { + private List networkUuids; + private List peers; + + public List getNetworkUuids() { + return networkUuids; + } + + public void setNetworkUuids(List networkUuids) { + this.networkUuids = networkUuids; + } + + public List getPeers() { + return peers; + } + + public void setPeers(List peers) { + this.peers = peers; + } + } + + public static class DeleteVxlanNetworksFdbResponse extends AgentResponse { + } + public static class CheckVxlanCidrCmd extends AgentCommand { private String cidr; private String vtepip; @@ -268,6 +320,8 @@ public void setVtepip(String vtepip) { public static class CheckVxlanCidrResponse extends AgentResponse { private String vtepIp; + private String physicalInterfaceName; + public String getVtepIp() { return vtepIp; } @@ -275,6 +329,14 @@ public String getVtepIp() { public void setVtepIp(String vtepIp) { this.vtepIp = vtepIp; } + + public String getPhysicalInterfaceName() { + return physicalInterfaceName; + } + + public void setPhysicalInterfaceName(String physicalInterfaceName) { + this.physicalInterfaceName = physicalInterfaceName; + } } public static class NicTO { diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkChecker.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkChecker.java index 39bde28ebde..49fc3caff54 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkChecker.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkChecker.java @@ -4,10 +4,13 @@ import org.zstack.header.message.APIMessage; import org.zstack.header.network.l2.L2NetworkInventory; +import java.util.List; + /** * Created by weiwang on 02/05/2017. */ public interface VxlanNetworkChecker { APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionException; - String getOverlapVniRangePool(L2NetworkInventory inv, String clusterUuid); + void validateSystemTagFormat(List systemTags); + void validateVniRangeOverlap(L2NetworkInventory inv, String clusterUuid); } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java index 4480a88b710..00513d4342a 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkCheckerImpl.java @@ -3,18 +3,21 @@ import org.zstack.core.Platform; import org.zstack.core.db.Q; import org.zstack.header.apimediator.ApiMessageInterceptionException; -import org.zstack.header.errorcode.SysErrors; +import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.message.APIMessage; import org.zstack.header.network.l2.*; import org.zstack.header.network.l3.APICreateL3NetworkMsg; -import org.zstack.network.l2.vxlan.vtep.VtepVO; -import org.zstack.network.l2.vxlan.vtep.VtepVO_; +import org.zstack.network.l2.vxlan.vxlanNetwork.L2VxlanNetworkInventory; import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkConstant; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; +import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO_; import org.zstack.utils.network.NetworkUtils; +import java.util.Arrays; import java.util.List; -import java.util.StringTokenizer; -import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.*; /** * Created by weiwang on 02/05/2017. @@ -26,53 +29,72 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIAttachL2NetworkToClusterMsg) msg); } else if (msg instanceof APICreateL3NetworkMsg) { validate((APICreateL3NetworkMsg) msg); + } else if (msg instanceof APIChangeL2NetworkVlanIdMsg) { + validate((APIChangeL2NetworkVlanIdMsg) msg); } return msg; } + private void validate(APIChangeL2NetworkVlanIdMsg msg) { + if (!msg.getType().equals(VxlanNetworkConstant.VXLAN_NETWORK_TYPE)){ + return; + } + if (!NetworkUtils.isValidVni(msg.getVlan())) { + throw new ApiMessageInterceptionException(argerr("vlan[%s] is not a valid vni", msg.getVlan())); + } + VxlanNetworkVO vxlanVO = Q.New(VxlanNetworkVO.class).eq(VxlanNetworkVO_.uuid, msg.getL2NetworkUuid()).find(); + if (vxlanVO == null || !vxlanVO.getType().equals(VxlanNetworkConstant.VXLAN_NETWORK_TYPE)) { + throw new ApiMessageInterceptionException(argerr("L2Network[uuid:%s] is not L2VxlanNetwork type", + msg.getL2NetworkUuid())); + } + + List duplicate = Q.New(VxlanNetworkVO.class).select(VxlanNetworkVO_.uuid) + .eq(VxlanNetworkVO_.vni, msg.getVlan()).eq(VxlanNetworkVO_.poolUuid, vxlanVO.getPoolUuid()).listValues(); + duplicate = duplicate.stream().filter(d -> !d.equals(msg.getL2NetworkUuid())).collect(Collectors.toList()); + if (!duplicate.isEmpty()) { + throw new OperationFailureException(Platform.err(L2Errors.ALLOCATE_VNI_ERROR, + "cannot allocate vni[%s] in l2Network[uuid:%s], duplicate with l2Network[uuid:%s]", + msg.getVlan(), msg.getL2NetworkUuid(), duplicate.get(0))); + } + } + private void validate(APIAttachL2NetworkToClusterMsg msg) { L2NetworkVO l2NetworkVO = Q.New(L2NetworkVO.class).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).find(); if (!l2NetworkVO.getType().equals(VxlanNetworkPoolConstant.VXLAN_NETWORK_POOL_TYPE)) { return; } - String pattern = ".*cidr::\\{.*\\}"; - if (msg.getSystemTags() == null) { - throw new ApiMessageInterceptionException(Platform.err(SysErrors.INVALID_ARGUMENT_ERROR, - String.format("need to input one system tag like : l2NetworkUuid::XXX::clusterUuid::XXX::cidr::{X.X.X.X/Y}") - )); + throw new ApiMessageInterceptionException(argerr("need to input one system tag like : [%s]", + VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat())); } - for (String tag : msg.getSystemTags()) { - if (!Pattern.matches(pattern, tag)) { - throw new ApiMessageInterceptionException(Platform.err(SysErrors.INVALID_ARGUMENT_ERROR, - String.format("wrong system tag format, shoud be like : l2NetworkUuid::XXX::clusterUuid::XXX::cidr::{X.X.X.X/Y}") - )); - } + validateSystemTagFormat(msg.getSystemTags()); - StringTokenizer st = new StringTokenizer(tag, "::"); - while (st.hasMoreElements()) { - String t = st.nextToken(); - if (Pattern.matches("\\{.*\\}", t)) { - if (!NetworkUtils.isCidr(t.replaceAll("\\{|\\}", ""))) { - throw new ApiMessageInterceptionException(Platform.err(SysErrors.INVALID_ARGUMENT_ERROR, - String.format("wrong cidr format in system tag") - )); - } - } + validateVniRangeOverlap(L2NetworkInventory.valueOf(l2NetworkVO), msg.getClusterUuid()); + } + + public void validateSystemTagFormat(List systemTags) { + for (String tag : systemTags) { + if (!VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.isMatch(tag)) { + throw new ApiMessageInterceptionException(argerr("wrong system tag [%s], should be like : [%s]", + tag, VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTagFormat())); + } + List cidr = Arrays.asList(VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTokenByTag(tag, VxlanSystemTags.VTEP_CIDR_TOKEN).split("[{}]")); + boolean isCidr = cidr.size() > 1 && NetworkUtils.isCidr(cidr.get(1)); + if (!isCidr) { + throw new ApiMessageInterceptionException(argerr("wrong cidr format in system tag [%s]", tag)); } } + } - String overlapedPool = getOverlapVniRangePool(L2NetworkInventory.valueOf(l2NetworkVO), msg.getClusterUuid()); - if (overlapedPool != null) { - throw new ApiMessageInterceptionException(Platform.err(SysErrors.INVALID_ARGUMENT_ERROR, - String.format("overlap vni range with vxlan network pool [%s]", overlapedPool) - )); + public void validateVniRangeOverlap(L2NetworkInventory inv, String clusterUuid) { + String overlappedPool = getOverlapVniRangePool(inv, clusterUuid); + if (overlappedPool != null) { + throw new ApiMessageInterceptionException(argerr("overlap vni range with %s [%s]", inv.getType(), overlappedPool)); } - } public String getOverlapVniRangePool(L2NetworkInventory inv, String clusterUuid) { @@ -88,8 +110,8 @@ public String getOverlapVniRangePool(L2NetworkInventory inv, String clusterUuid) List ranges = Q.New(VniRangeVO.class).eq(VniRangeVO_.l2NetworkUuid, l2Uuid).list(); for (VniRangeVO range : ranges) { - for (VniRangeVO crange: checkRanges) { - if (isVniRangeOverlap(range.getStartVni(), range.getEndVni(), crange.getStartVni(), crange.getEndVni())) { + for (VniRangeVO cRange: checkRanges) { + if (isVniRangeOverlap(range.getStartVni(), range.getEndVni(), cRange.getStartVni(), cRange.getEndVni())) { return l2Uuid; } } @@ -99,19 +121,14 @@ public String getOverlapVniRangePool(L2NetworkInventory inv, String clusterUuid) return null; } - public static boolean isVniRangeOverlap(Integer startVni1, Integer endVni1, Integer startVni2, Integer endVni2) { - if ((startVni1 >= startVni2 && startVni1 <= endVni2) || (startVni1 <= startVni2 && startVni2 <= endVni1)) { - return true; - } - return false; + private static boolean isVniRangeOverlap(Integer startVni1, Integer endVni1, Integer startVni2, Integer endVni2) { + return (startVni1 >= startVni2 && startVni1 <= endVni2) || (startVni1 <= startVni2 && startVni2 <= endVni1); } private void validate(APICreateL3NetworkMsg msg) { String type = Q.New(L2NetworkVO.class).select(L2NetworkVO_.type).eq(L2NetworkVO_.uuid, msg.getL2NetworkUuid()).findValue(); if (type.equals(VxlanNetworkPoolConstant.VXLAN_NETWORK_POOL_TYPE)) { - throw new ApiMessageInterceptionException(Platform.err(SysErrors.INVALID_ARGUMENT_ERROR, - String.format("vxlan network pool doesn't support create l3 network") - )); + throw new ApiMessageInterceptionException(argerr("vxlan network pool doesn't support create l3 network")); } } } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPool.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPool.java index 68f82d49cba..68d20f08df8 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPool.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPool.java @@ -1,5 +1,11 @@ package org.zstack.network.l2.vxlan.vxlanNetworkPool; +import static org.zstack.network.l2.vxlan.vxlanNetworkPool.VxlanNetworkPoolConstant.*; +import org.zstack.header.errorcode.SysErrors; +import org.zstack.network.l2.vxlan.vxlanNetwork.*; +import org.zstack.utils.network.NetworkUtils; +import org.zstack.header.cluster.ClusterVO; +import org.zstack.header.cluster.ClusterVO_; import org.hibernate.exception.ConstraintViolationException; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; @@ -129,6 +135,8 @@ private void handleLocalMessage(Message msg) { handle((DeleteVtepMsg) msg); } else if (msg instanceof PopulateVtepPeersMsg){ handle((PopulateVtepPeersMsg) msg); + } else if (msg instanceof PopulateRemoteVtepPeersMsg){ + handle((PopulateRemoteVtepPeersMsg) msg); } else if (msg instanceof L2NetworkMessage) { superHandle((L2NetworkMessage) msg); } else { @@ -136,6 +144,70 @@ private void handleLocalMessage(Message msg) { } } + protected void handle(final PopulateRemoteVtepPeersMsg msg) { + final PopulateRemoteVtepPeersReply reply = new PopulateRemoteVtepPeersReply(); + + List vteps = Q.New(VtepVO.class).eq(VtepVO_.poolUuid, msg.getPoolUuid()).list(); + if (vteps == null || vteps.size() < 1) { + logger.debug("no need to populate fdb since there are only one vtep or less"); + bus.reply(msg, reply); + return; + } + + List targets = msg.getHosts(); + if (targets.isEmpty()) { + List hostUuids = vteps.stream().map(VtepVO::getHostUuid).collect(Collectors.toList()); + Set clusterUuids = vteps.stream().map(VtepVO::getClusterUuid).collect(Collectors.toSet()); + targets = HostInventory.valueOf(Q.New(HostVO.class) + .in(HostVO_.uuid, hostUuids).in(HostVO_.clusterUuid, clusterUuids).list()); + } + + List vxlanNetworkUuids = Q.New(VxlanNetworkVO.class) + .select(VxlanNetworkVO_.uuid) + .eq(VxlanNetworkVO_.poolUuid, msg.getPoolUuid()) + .listValues(); + if(vxlanNetworkUuids.isEmpty()){ + logger.debug("no need to populate fdb because there is no vxlannetwork"); + bus.reply(msg, reply); + return; + } + + ErrorCodeList errList = new ErrorCodeList(); + new While<>(targets).step((host, completion1) -> { + List peers = new ArrayList<>(); + peers.add(msg.getVtepIp()); + + VxlanKvmAgentCommands.PopulateVxlanNetworksFdbCmd cmd = new VxlanKvmAgentCommands.PopulateVxlanNetworksFdbCmd(); + cmd.setPeers(peers); + cmd.setNetworkUuids(vxlanNetworkUuids); + + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setHostUuid(host.getUuid()); + kmsg.setCommand(cmd); + kmsg.setPath(VXLAN_KVM_POPULATE_FDB_L2VXLAN_NETWORKS_PATH); + kmsg.setNoStatusCheck(true); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, host.getUuid()); + bus.send(kmsg, new CloudBusCallBack(completion1) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(reply.getError().toString()); + errList.getCauses().add(reply.getError()); + } + completion1.done(); + } + }); + }, 5).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errList.getCauses().isEmpty()) { + reply.setError(errList.getCauses().get(0)); + } + bus.reply(msg, reply); + } + }); + } + protected void handle(final PopulateVtepPeersMsg msg) { final PopulateVtepPeersReply reply = new PopulateVtepPeersReply(); @@ -175,6 +247,14 @@ protected void handle(final PopulateVtepPeersMsg msg) { host.getManagementIp(), msg.getPoolUuid(), vxlanNetworkUuids, host.getUuid())); VxlanKvmAgentCommands.PopulateVxlanNetworksFdbCmd cmd = new VxlanKvmAgentCommands.PopulateVxlanNetworksFdbCmd(); + // if remote vtep ip exist ,add it + String clusterUuid = Q.New(HostVO.class).select(HostVO_.clusterUuid).eq(HostVO_.uuid, host.getUuid()).findValue(); + List gwpeers = Q.New(RemoteVtepVO.class).select(RemoteVtepVO_.vtepIp).eq(RemoteVtepVO_.poolUuid, msg.getPoolUuid()).eq(RemoteVtepVO_.clusterUuid, clusterUuid).listValues(); + if (gwpeers.size() > 0) { + Set gwp = new HashSet(gwpeers); + peers.addAll(gwp); + } + cmd.setPeers(new ArrayList<>(peers)); cmd.setNetworkUuids(vxlanNetworkUuids); @@ -201,9 +281,9 @@ public void done(ErrorCodeList errorCodeList) { }); } - private void handle(final PrepareL2NetworkOnHostMsg msg) { + protected void handle(final PrepareL2NetworkOnHostMsg msg) { final PrepareL2NetworkOnHostReply reply = new PrepareL2NetworkOnHostReply(); - prepareL2NetworkOnHosts(msg.getL2NetworkUuid(), Arrays.asList(msg.getHost()), new Completion(msg) { + prepareL2NetworkOnHosts(msg.getL2NetworkUuid(), Arrays.asList(msg.getHost()), false, new Completion(msg) { @Override public void success() { bus.reply(msg, reply); @@ -268,7 +348,8 @@ public void fail(ErrorCode errorCode) { protected void handle(CreateVtepMsg msg) { List vteps = Q.New(VtepVO.class).eq(VtepVO_.poolUuid, msg.getPoolUuid()).eq(VtepVO_.vtepIp, msg.getVtepIp()).list(); - for (VtepVO vtep: vteps) { + if (vteps.size() != 0) { + VtepVO vtep = vteps.get(0); if (!vtep.getHostUuid().equals(msg.getHostUuid())) { logger.warn(String.format("same vtepip[%s] in host[%s] and host[%s], which in same cluster[%s]", msg.getVtepIp(), vtep.getHostUuid(), msg.getHostUuid(), msg.getClusterUuid())); @@ -292,6 +373,7 @@ protected void handle(CreateVtepMsg msg) { vo.setPort(msg.getPort()); vo.setType(msg.getType()); vo.setVtepIp(msg.getVtepIp()); + vo.setPhysicalInterface(msg.getPhysicalInterface()); vo.setPoolUuid(msg.getPoolUuid()); try { vo = dbf.persistAndRefresh(vo); @@ -334,6 +416,10 @@ private void handleApiMessage(APIMessage msg) { handle((APIUpdateVniRangeMsg) msg); } else if (msg instanceof APICreateVxlanVtepMsg) { handle((APICreateVxlanVtepMsg) msg); + } else if (msg instanceof APICreateVxlanPoolRemoteVtepMsg) { + handle((APICreateVxlanPoolRemoteVtepMsg) msg); + } else if (msg instanceof APIDeleteVxlanPoolRemoteVtepMsg) { + handle((APIDeleteVxlanPoolRemoteVtepMsg) msg); } else if (msg instanceof L2NetworkMessage) { superHandle((L2NetworkMessage) msg); } else { @@ -341,6 +427,256 @@ private void handleApiMessage(APIMessage msg) { } } + + private void handle(final APIDeleteVxlanPoolRemoteVtepMsg msg) { + APIDeleteVxlanPoolRemoteVtepEvent evt = new APIDeleteVxlanPoolRemoteVtepEvent(msg.getId()); + + SimpleQuery rq = dbf.createQuery(L2NetworkClusterRefVO.class); + rq.add(L2NetworkClusterRefVO_.clusterUuid, SimpleQuery.Op.EQ, msg.getClusterUuid()); + rq.add(L2NetworkClusterRefVO_.l2NetworkUuid, SimpleQuery.Op.EQ, msg.getL2NetworkUuid()); + long count = rq.count(); + if (count == 0) { + bus.publish(evt); + return; + } + + + List ips = Q.New(RemoteVtepVO.class) + .select(RemoteVtepVO_.vtepIp).eq(RemoteVtepVO_.poolUuid, msg.getL2NetworkUuid()) + .eq(RemoteVtepVO_.clusterUuid, msg.getClusterUuid()) + .eq(RemoteVtepVO_.vtepIp, msg.getRemoteVtepIp()).listValues(); + + if (ips.isEmpty()) { + logger.info(String.format("there are no remote vtep ip for vxlanpool:[%s]", msg.getL2NetworkUuid())); + bus.publish(evt); + return; + } + logger.info(String.format("delete remote vtep ip for vxlanpool:[%s]", msg.getL2NetworkUuid())); + RemoteVtepVO vo = Q.New(RemoteVtepVO.class).eq(RemoteVtepVO_.poolUuid, msg.getL2NetworkUuid()) + .eq(RemoteVtepVO_.clusterUuid, msg.getClusterUuid()) + .eq(RemoteVtepVO_.vtepIp, msg.getRemoteVtepIp()).find(); + + List vxlanNetworkUuids = Q.New(VxlanNetworkVO.class) + .select(VxlanNetworkVO_.uuid) + .eq(VxlanNetworkVO_.poolUuid, msg.getL2NetworkUuid()) + .listValues(); + // no br based vxlan, delete db only + if (vxlanNetworkUuids.size() == 0) { + dbf.remove(vo); + bus.publish(evt); + return; + } + // delete based vxlan bridge remote vtep ip info + SimpleQuery query = dbf.createQuery(HostVO.class); + query.add(HostVO_.clusterUuid, SimpleQuery.Op.EQ, msg.getClusterUuid()); + query.add(HostVO_.state, SimpleQuery.Op.NOT_IN, HostState.PreMaintenance, HostState.Maintenance); + query.add(HostVO_.status, SimpleQuery.Op.EQ, HostStatus.Connected); + final List hosts = query.list(); + List hvinvs = HostInventory.valueOf(hosts); + // cluster no hosts, only remove db + if (hvinvs == null || hvinvs.isEmpty()) { + dbf.remove(vo); + bus.publish(evt); + logger.debug(String.format("clusterUuid:[%s] no host", msg.getClusterUuid())); + return; + } + + ErrorCodeList errList = new ErrorCodeList(); + new While<>(hvinvs).step((host, completion1) -> { + + VxlanKvmAgentCommands.DeleteVxlanNetworksFdbCmd cmd = new VxlanKvmAgentCommands.DeleteVxlanNetworksFdbCmd(); + List peers = new ArrayList<>(); + peers.add(msg.getRemoteVtepIp()); + + cmd.setPeers(peers); + cmd.setNetworkUuids(vxlanNetworkUuids); + + KVMHostAsyncHttpCallMsg kmsg = new KVMHostAsyncHttpCallMsg(); + kmsg.setHostUuid(host.getUuid()); + kmsg.setCommand(cmd); + kmsg.setPath(VXLAN_KVM_DELETE_FDB_L2VXLAN_NETWORKS_PATH); + kmsg.setNoStatusCheck(true); + bus.makeTargetServiceIdByResourceUuid(kmsg, HostConstant.SERVICE_ID, host.getUuid()); + bus.send(kmsg, new CloudBusCallBack(completion1) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.warn(reply.getError().toString()); + errList.getCauses().add(reply.getError()); + } + completion1.done(); + } + }); + }, 5).run(new WhileDoneCompletion(msg) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (!errList.getCauses().isEmpty()) { + evt.setError(errList.getCauses().get(0)); + } else { + dbf.remove(vo); + } + } + }); + + bus.publish(evt); + } + + private void syncVxlanPoolRemoteVtepDataBase(final APICreateVxlanPoolRemoteVtepMsg msg, APICreateVxlanPoolRemoteVtepEvent evt) { + String uuid; + if (msg.getResourceUuid() != null) { + uuid = msg.getResourceUuid(); + } else { + uuid = Platform.getUuid(); + } + + RemoteVtepInventory inv; + RemoteVtepVO vvo = new RemoteVtepVO(); + + vvo.setUuid(uuid);; + vvo.setVtepIp(msg.getRemoteVtepIp()); + vvo.setClusterUuid(msg.getClusterUuid()); + vvo.setPoolUuid(msg.getL2NetworkUuid()); + vvo.setPort(VXLAN_PORT); + vvo.setType(KVM_VXLAN_TYPE); + vvo = dbf.persistAndRefresh(vvo); + + inv = RemoteVtepInventory.valueOf(vvo); + evt.setInventory(inv); + bus.publish(evt); + return; + } + + private void handle(final APICreateVxlanPoolRemoteVtepMsg msg) { + APICreateVxlanPoolRemoteVtepEvent evt = new APICreateVxlanPoolRemoteVtepEvent(msg.getId()); + + SimpleQuery rq = dbf.createQuery(L2NetworkClusterRefVO.class); + rq.add(L2NetworkClusterRefVO_.clusterUuid, SimpleQuery.Op.EQ, msg.getClusterUuid()); + rq.add(L2NetworkClusterRefVO_.l2NetworkUuid, SimpleQuery.Op.EQ, msg.getL2NetworkUuid()); + long count = rq.count(); + if (count == 0) { + evt.setError(err(SysErrors.RESOURCE_NOT_FOUND, "Cannot find L2NetworkClusterRefVO item for l2NetworkUuid[%s] clusterUuid[%s]", msg.getL2NetworkUuid(), msg.getClusterUuid())); + bus.publish(evt); + return; + } + + SimpleQuery rqVtep = dbf.createQuery(RemoteVtepVO.class); + rqVtep.add(RemoteVtepVO_.clusterUuid, SimpleQuery.Op.EQ, msg.getClusterUuid()); + rqVtep.add(RemoteVtepVO_.poolUuid, SimpleQuery.Op.EQ, msg.getL2NetworkUuid()); + rqVtep.add(RemoteVtepVO_.vtepIp, SimpleQuery.Op.EQ, msg.getRemoteVtepIp()); + count = rqVtep.count(); + if (count > 0) { + evt.setError(err(SysErrors.OPERATION_ERROR, "ip[%s] l2NetworkUuid[%s] clusterUuid[%s] exist", msg.getRemoteVtepIp(), msg.getL2NetworkUuid(), msg.getClusterUuid())); + bus.publish(evt); + return; + } + + List vxlanNetworkVOS; + vxlanNetworkVOS = Q.New(VxlanNetworkVO.class).eq(VxlanNetworkVO_.poolUuid, msg.getL2NetworkUuid()).list(); + // no br based vxlan, add db only + // when add br based vxlan, will add gw ip to bridge fdb + if (vxlanNetworkVOS == null || vxlanNetworkVOS.isEmpty()) { + syncVxlanPoolRemoteVtepDataBase(msg, evt); + return; + } + //based vxlan br already exist, add gw ip to bridge fdb + SimpleQuery query = dbf.createQuery(HostVO.class); + query.add(HostVO_.clusterUuid, SimpleQuery.Op.EQ, msg.getClusterUuid()); + query.add(HostVO_.state, SimpleQuery.Op.NOT_IN, HostState.PreMaintenance, HostState.Maintenance); + query.add(HostVO_.status, SimpleQuery.Op.EQ, HostStatus.Connected); + final List hosts = query.list(); + List hvinvs = HostInventory.valueOf(hosts); + // cluster no hosts, only add db + if (hvinvs == null || hvinvs.isEmpty()) { + logger.debug(String.format("clusterUuid:[%s] no host", msg.getClusterUuid())); + syncVxlanPoolRemoteVtepDataBase(msg, evt); + return; + } + + prepareL2NetworkVxlanRemoteVtepOnHosts(msg, hvinvs, new Completion(msg) { + @Override + public void success() { + syncVxlanPoolRemoteVtepDataBase(msg, evt); + logger.debug(String.format("successfully attached L2VxlanNetworkPool[uuid:%s] to cluster [uuid:%s]", msg.getL2NetworkUuid(), msg.getClusterUuid())); + } + + @Override + public void fail(ErrorCode errorCode) { + evt.setError(err(L2Errors.ATTACH_ERROR, errorCode, errorCode.getDetails())); + bus.publish(evt); + } + }); + } + + + private void prepareL2NetworkVxlanRemoteVtepOnHosts(final APICreateVxlanPoolRemoteVtepMsg msg, final List hosts, final Completion completion) { + final String l2NetworkUuid = msg.getL2NetworkUuid(); + FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); + chain.setName(String.format("prepare-l2-vxlan-gateway-%s-on-hosts", l2NetworkUuid)); + chain.then(new NoRollbackFlow() { + @Override + public void run(final FlowTrigger trigger, Map data) { + ErrorCodeList errList = new ErrorCodeList(); + + new While<>(hosts).step((h, completion1) -> { + CheckL2NetworkOnHostMsg cmsg = new CheckL2NetworkOnHostMsg(); + cmsg.setHostUuid(h.getUuid()); + cmsg.setL2NetworkUuid(l2NetworkUuid); + bus.makeTargetServiceIdByResourceUuid(cmsg, L2NetworkConstant.SERVICE_ID, l2NetworkUuid); + bus.send(cmsg, new CloudBusCallBack(completion1) { + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + errList.getCauses().add(reply.getError()); + } + completion1.done(); + } + }); + }, 5).run(new WhileDoneCompletion(trigger) { + @Override + public void done(ErrorCodeList errorCodeList) { + if (errList.getCauses().isEmpty()) { + trigger.next(); + } else { + trigger.fail(errList.getCauses().get(0)); + } + } + }); + } + }).then(new NoRollbackFlow() { + String __name__ = String.format("populate-remote-vtep-for-l2-vxlan-pool-%s", l2NetworkUuid); + @Override + public void run(FlowTrigger trigger, Map data) { + PopulateRemoteVtepPeersMsg pmsg = new PopulateRemoteVtepPeersMsg(); + pmsg.setHosts(hosts); + pmsg.setVtepIp(msg.getRemoteVtepIp()); + pmsg.setPoolUuid(l2NetworkUuid); + bus.makeTargetServiceIdByResourceUuid(pmsg, L2NetworkConstant.SERVICE_ID, l2NetworkUuid); + bus.send(pmsg, new CloudBusCallBack(pmsg){ + @Override + public void run(MessageReply reply) { + if (!reply.isSuccess()) { + logger.debug(String.format("fail to populate remote vtep for l2 vxlan pool %s", l2NetworkUuid)); + trigger.fail(reply.getError()); + } else { + trigger.next(); + } + } + }); + } + }).done(new FlowDoneHandler(completion) { + @Override + public void handle(Map data) { + completion.success(); + } + }).error(new FlowErrorHandler(completion) { + @Override + public void handle(ErrorCode errCode, Map data) { + completion.fail(errCode); + } + }).start(); + } + + protected void handle(final APICreateVxlanVtepMsg msg) { APICreateVxlanVtepEvent evt = new APICreateVxlanVtepEvent(msg.getId()); HostVO host = Q.New(HostVO.class).eq(HostVO_.uuid, msg.getHostUuid()).find(); @@ -441,6 +777,8 @@ public void run(MessageReply reply) { }); } }).then(new NoRollbackFlow() { + String __name__ = "after-detach-l2-vxlan-pool"; + @Override public void run(FlowTrigger trigger, Map data) { afterDetachVxlanPoolFromCluster(msg); @@ -486,11 +824,34 @@ private void handle(final APICreateVniRangeMsg msg) { } protected void afterAttachVxlanPoolFromClusterFailed(APIAttachL2NetworkToClusterMsg msg) { + if (msg.getSystemTags() == null) { + return; + } + for (String tag : msg.getSystemTags()) { VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.delete(msg.getL2NetworkUuid(), tag); } } + private void addVxlanNetworkClusterRefs(String clusterUuid, String l2Uuid) { + List refs = new ArrayList<>(); + L2NetworkClusterRefVO rvo = new L2NetworkClusterRefVO(); + rvo.setClusterUuid(clusterUuid); + rvo.setL2NetworkUuid(l2Uuid); + refs.add(rvo); + + List uuids = Q.New(VxlanNetworkVO.class) + .select(VxlanNetworkVO_.uuid).eq(VxlanNetworkVO_.poolUuid, l2Uuid).listValues(); + for (String uuid : uuids) { + rvo = new L2NetworkClusterRefVO(); + rvo.setClusterUuid(clusterUuid); + rvo.setL2NetworkUuid(uuid); + refs.add(rvo); + } + + dbf.persistCollection(refs); + } + private void handle(final APIAttachL2NetworkToClusterMsg msg) { final APIAttachL2NetworkToClusterEvent evt = new APIAttachL2NetworkToClusterEvent(msg.getId()); SimpleQuery rq = dbf.createQuery(L2NetworkClusterRefVO.class); @@ -514,25 +875,20 @@ private void handle(final APIAttachL2NetworkToClusterMsg msg) { query.add(HostVO_.state, SimpleQuery.Op.NOT_IN, HostState.PreMaintenance, HostState.Maintenance); query.add(HostVO_.status, SimpleQuery.Op.EQ, HostStatus.Connected); final List hosts = query.list(); + if (hosts.isEmpty()) { + addVxlanNetworkClusterRefs(msg.getClusterUuid(), msg.getL2NetworkUuid()); + self = dbf.reload(self); + evt.setInventory(self.toInventory()); + bus.publish(evt); + return; + } + List hvinvs = HostInventory.valueOf(hosts); - prepareL2NetworkOnHosts(msg.getL2NetworkUuid(), hvinvs, new Completion(msg) { + prepareL2NetworkOnHosts(msg.getL2NetworkUuid(), hvinvs, true, new Completion(msg) { @Override public void success() { - L2NetworkClusterRefVO rvo = new L2NetworkClusterRefVO(); - rvo.setClusterUuid(msg.getClusterUuid()); - rvo.setL2NetworkUuid(self.getUuid()); - dbf.persist(rvo); - - List uuids = Q.New(VxlanNetworkVO.class) - .select(VxlanNetworkVO_.uuid).eq(VxlanNetworkVO_.poolUuid, msg.getL2NetworkUuid()).listValues(); - for (String uuid : uuids) { - rvo = new L2NetworkClusterRefVO(); - rvo.setClusterUuid(msg.getClusterUuid()); - rvo.setL2NetworkUuid(uuid); - dbf.persist(rvo); - } - + addVxlanNetworkClusterRefs(msg.getClusterUuid(), msg.getL2NetworkUuid()); logger.debug(String.format("successfully attached L2VxlanNetworkPool[uuid:%s] to cluster [uuid:%s]", self.getUuid(), msg.getClusterUuid())); self = dbf.findByUuid(self.getUuid(), L2NetworkVO.class); @@ -651,11 +1007,13 @@ private void handle(final APIUpdateVniRangeMsg msg) { logger.info(String.format("update l2 vxlan vni range[%s] name[%s]", msg.getUuid(), msg.getName())); } - private void prepareL2NetworkOnHosts(final String l2NetworkUuid, final List hosts, final Completion completion) { + public void prepareL2NetworkOnHosts(final String l2NetworkUuid, final List hosts, boolean applyToSdn, final Completion completion) { FlowChain chain = FlowChainBuilder.newSimpleFlowChain(); List vtepIpChanged = new ArrayList<>(); chain.setName(String.format("prepare-l2-%s-on-hosts", self.getUuid())); chain.then(new NoRollbackFlow() { + String __name__ = "check-vtep-ip"; + @Override public void run(final FlowTrigger trigger, Map data) { ErrorCodeList errList = new ErrorCodeList(); @@ -716,6 +1074,8 @@ public void run(MessageReply reply) { }); } }).then(new NoRollbackFlow() { + String __name__ = "realize-l2-network"; + private void realize(final Iterator it, final FlowTrigger trigger) { if (!it.hasNext()) { trigger.next(); @@ -756,8 +1116,9 @@ public void handle(ErrorCode errCode, Map data) { protected void realizeNetwork(String hostUuid, String htype, Completion completion) { final HypervisorType hvType = HypervisorType.valueOf(htype); final L2NetworkType l2Type = L2NetworkType.valueOf(self.getType()); + final VSwitchType vSwitchType = VSwitchType.valueOf(self.getvSwitchType()); - L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, hvType); + L2NetworkRealizationExtensionPoint ext = l2Mgr.getRealizationExtension(l2Type, vSwitchType, hvType); ext.realize(getSelfInventory(), hostUuid, completion); } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolConstant.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolConstant.java index e88cb96ead8..9a3cc65656d 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolConstant.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolConstant.java @@ -23,5 +23,6 @@ public class VxlanNetworkPoolConstant { public static final String VXLAN_KVM_REALIZE_L2VXLAN_NETWORKS_PATH = "/network/l2vxlan/createbridges"; public static final String VXLAN_KVM_POPULATE_FDB_L2VXLAN_NETWORK_PATH = "/network/l2vxlan/populatefdb"; public static final String VXLAN_KVM_POPULATE_FDB_L2VXLAN_NETWORKS_PATH = "/network/l2vxlan/populatefdbs"; + public static final String VXLAN_KVM_DELETE_FDB_L2VXLAN_NETWORKS_PATH = "/network/l2vxlan/deletefdbs"; public static final String VXLAN_KVM_DELETE_L2VXLAN_NETWORK_PATH = "/network/l2vxlan/deletebridge"; } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolFactory.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolFactory.java index b89560441f4..24e4aa2123c 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolFactory.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolFactory.java @@ -52,7 +52,7 @@ public L2NetworkType getType() { @Override @Transactional - public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { + public void createL2Network(L2NetworkVO ovo, APICreateL2NetworkMsg msg, ReturnValueCompletion completion) { VxlanNetworkPoolVO vo = new VxlanNetworkPoolVO(ovo); if (vo.getPhysicalInterface() == null) { vo.setPhysicalInterface(""); diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolVO.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolVO.java index a60e46b0ec8..8f71b885a69 100755 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolVO.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanNetworkPoolVO.java @@ -6,6 +6,7 @@ import org.zstack.header.vo.EO; import org.zstack.header.vo.NoView; import org.zstack.network.l2.vxlan.vtep.VtepVO; +import org.zstack.network.l2.vxlan.vtep.RemoteVtepVO; import org.zstack.network.l2.vxlan.vxlanNetwork.VxlanNetworkVO; import javax.persistence.*; @@ -26,6 +27,11 @@ public class VxlanNetworkPoolVO extends L2NetworkVO { @NoView private Set attachedVtepRefs = new HashSet(); + @OneToMany(fetch = FetchType.EAGER) + @JoinColumn(name = "poolUuid", insertable = false, updatable = false) + @NoView + private Set remoteVteps = new HashSet(); + @OneToMany(fetch = FetchType.EAGER) @JoinColumn(name = "l2NetworkUuid", insertable = false, updatable = false) @NoView @@ -38,6 +44,14 @@ public VxlanNetworkPoolVO(L2NetworkVO vo) { super(vo); } + public Set getRemoteVteps() { + return remoteVteps; + } + + public void setRemoteVteps(Set remoteVteps) { + this.remoteVteps = remoteVteps; + } + public Set getAttachedVtepRefs() { return attachedVtepRefs; } diff --git a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java index 196a46a7ae6..0ce7e3ae9ff 100644 --- a/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java +++ b/plugin/vxlan/src/main/java/org/zstack/network/l2/vxlan/vxlanNetworkPool/VxlanPoolApiInterceptor.java @@ -10,6 +10,7 @@ import org.zstack.header.errorcode.SysErrors; import org.zstack.header.message.APIMessage; import org.zstack.header.network.l2.L2NetworkClusterRefVO; +import org.zstack.header.network.l2.L2NetworkConstant; import org.zstack.network.l2.vxlan.vtep.APICreateVxlanVtepMsg; import org.zstack.network.l2.vxlan.vtep.VtepVO; import org.zstack.network.l2.vxlan.vtep.VtepVO_; @@ -22,7 +23,7 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; - +import org.zstack.core.db.SimpleQuery; import static org.zstack.core.Platform.argerr; /** @@ -45,10 +46,39 @@ public APIMessage intercept(APIMessage msg) throws ApiMessageInterceptionExcepti validate((APIUpdateVniRangeMsg) msg); } else if (msg instanceof APICreateVxlanVtepMsg) { validate((APICreateVxlanVtepMsg) msg); + } else if (msg instanceof APICreateVxlanPoolRemoteVtepMsg) { + validate((APICreateVxlanPoolRemoteVtepMsg) msg); + } else if (msg instanceof APIDeleteVxlanPoolRemoteVtepMsg) { + validate((APIDeleteVxlanPoolRemoteVtepMsg) msg); } return msg; } + private void validate(APICreateVxlanPoolRemoteVtepMsg msg) { + boolean isIpv4 = NetworkUtils.isIpv4Address(msg.getRemoteVtepIp()); + if (!isIpv4) { + throw new ApiMessageInterceptionException(argerr("%s:is not ipv4", msg.getRemoteVtepIp())); + } + + SimpleQuery rqv = dbf.createQuery(VtepVO.class); + rqv.add(VtepVO_.clusterUuid, SimpleQuery.Op.EQ, msg.getClusterUuid()); + rqv.add(VtepVO_.poolUuid, SimpleQuery.Op.EQ, msg.getL2NetworkUuid()); + rqv.add(VtepVO_.vtepIp, SimpleQuery.Op.EQ, msg.getRemoteVtepIp()); + long count = rqv.count(); + if (count > 0) { + throw new ApiMessageInterceptionException(argerr("ip[%s] l2NetworkUuid[%s] clusterUuid[%s] ip exist in local vtep", msg.getRemoteVtepIp(), msg.getL2NetworkUuid(), msg.getClusterUuid())); + } + + } + + private void validate(APIDeleteVxlanPoolRemoteVtepMsg msg) { + boolean isIpv4 = NetworkUtils.isIpv4Address(msg.getRemoteVtepIp()); + if (!isIpv4) { + throw new ApiMessageInterceptionException(argerr("%s:is not ipv4", msg.getRemoteVtepIp())); + } + + } + private void validate(APICreateVxlanVtepMsg msg) { long count = Q.New(VtepVO.class).eq(VtepVO_.hostUuid, msg.getHostUuid()).eq(VtepVO_.poolUuid, msg.getPoolUuid()).count(); if (count > 0) { @@ -108,20 +138,24 @@ private void validate(APICreateVniRangeMsg msg) { .collect(Collectors.toList())).list(); for (VxlanNetworkPoolVO p : pools) { - - boolean sameCidr = false; - List> list = VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTokensOfTagsByResourceUuid(p.getUuid()); - for (Map tokens : list) { - String clusterUuid = tokens.get(VxlanSystemTags.CLUSTER_UUID_TOKEN); - String cidr = tokens.get(VxlanSystemTags.VTEP_CIDR_TOKEN).split("[{}]")[1]; - if (NetworkUtils.isSameCidr(cidr, attachedClusters.get(clusterUuid))) { - sameCidr = true; - break; + if (!p.getType().equals(L2NetworkConstant.HARDWARE_VXLAN_NETWORK_POOL_TYPE)) { + + boolean sameCidr = false; + List> list = VxlanSystemTags.VXLAN_POOL_CLUSTER_VTEP_CIDR.getTokensOfTagsByResourceUuid(p.getUuid()); + for (Map tokens : list) { + String clusterUuid = tokens.get(VxlanSystemTags.CLUSTER_UUID_TOKEN); + String cidr = tokens.get(VxlanSystemTags.VTEP_CIDR_TOKEN).split("[{}]")[1]; + if (attachedClusters.get(clusterUuid) != null) { + if (NetworkUtils.isSameCidr(cidr, attachedClusters.get(clusterUuid))) { + sameCidr = true; + break; + } + } } - } - if (!sameCidr) { - continue; + if (!sameCidr) { + continue; + } } for (VniRangeVO e : p.getAttachedVniRanges()) { diff --git a/plugin/xinfini/pom.xml b/plugin/xinfini/pom.xml new file mode 100644 index 00000000000..ae8dd2713b4 --- /dev/null +++ b/plugin/xinfini/pom.xml @@ -0,0 +1,109 @@ + + + + plugin + org.zstack + 5.4.0 + + 4.0.0 + + xinfini + + + + org.zstack + kvm + ${project.version} + + + javax.servlet + javax.servlet-api + 3.1.0 + + + com.squareup.okhttp3 + okhttp + 4.9.3 + + + org.zstack + vhost + ${project.version} + + + org.zstack + iscsi + ${project.version} + + + org.zstack + externalStorage + ${project.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${project.compiler.version} + + groovy-eclipse-compiler + ${project.java.version} + ${project.java.version} + lines,vars,source + true + + + + org.codehaus.groovy + groovy-eclipse-compiler + ${groovy.eclipse.compiler} + + + org.codehaus.groovy + groovy-eclipse-batch + ${groovy.eclipse.batch} + + + + + org.codehaus.mojo + aspectj-maven-plugin + ${aspectj.plugin.version} + + + + compile + test-compile + + + + + ${project.java.version} + ${project.java.version} + ${project.java.version} + true + + + org.springframework + spring-aspects + + + org.zstack + core + + + org.zstack + header + + + + + + + + diff --git a/plugin/xinfini/src/main/java/org/zstack/header/xinfini/XInfiniConstants.java b/plugin/xinfini/src/main/java/org/zstack/header/xinfini/XInfiniConstants.java new file mode 100644 index 00000000000..f941b632086 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/header/xinfini/XInfiniConstants.java @@ -0,0 +1,19 @@ +package org.zstack.header.xinfini; + +import okhttp3.MediaType; + +/** + * @ Author : yh.w + * @ Date : Created in 11:12 2024/5/28 + */ +public interface XInfiniConstants { + String DEFAULT_CREATOR = "AFA"; + String IDENTITY = "xinfini"; + + String XINFINI_MANUFACTURER = "xinfini"; + String HEADER_TOKEN = "x-sddc-token"; + + MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + int DEFAULT_POLLING_INTERVAL_IN_SECOND = 1; + int DEFAULT_POLLING_TIMES = 1800; +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/NodeStatus.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/NodeStatus.java new file mode 100644 index 00000000000..3afd26e19d9 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/NodeStatus.java @@ -0,0 +1,10 @@ +package org.zstack.xinfini; + +/** + * @ Author : yh.w + * @ Date : Created in 16:41 2024/5/28 + */ +public enum NodeStatus { + Connected, + Disconnected +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniAddonInfo.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniAddonInfo.java new file mode 100644 index 00000000000..e522a99fd38 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniAddonInfo.java @@ -0,0 +1,207 @@ +package org.zstack.xinfini; + +import org.zstack.xinfini.sdk.node.NodeModule; +import org.zstack.xinfini.sdk.pool.BsPolicyModule; +import org.zstack.xinfini.sdk.pool.PoolCapacity; +import org.zstack.xinfini.sdk.pool.PoolModule; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +public class XInfiniAddonInfo { + private List nodes; + + private List pools = new ArrayList<>(); + + private String currentIscsiTargetId; + private int currentIscsiTargetIndex; + + private String currentImageIscsiTargetId; + private int currentImageIscsiTargetIndex; + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public List getPools() { + return pools; + } + + public void setPools(List pools) { + this.pools = pools; + } + + public String getCurrentIscsiTargetId() { + return currentIscsiTargetId; + } + + public void setCurrentIscsiTargetId(String currentIscsiTargetId) { + this.currentIscsiTargetId = currentIscsiTargetId; + } + + public int getCurrentIscsiTargetIndex() { + return currentIscsiTargetIndex; + } + + public void setCurrentIscsiTargetIndex(int currentIscsiTargetIndex) { + this.currentIscsiTargetIndex = currentIscsiTargetIndex; + } + + public String getCurrentImageIscsiTargetId() { + return currentImageIscsiTargetId; + } + + public void setCurrentImageIscsiTargetId(String currentImageIscsiTargetId) { + this.currentImageIscsiTargetId = currentImageIscsiTargetId; + } + + public int getCurrentImageIscsiTargetIndex() { + return currentImageIscsiTargetIndex; + } + + public void setCurrentImageIscsiTargetIndex(int currentImageIscsiTargetIndex) { + this.currentImageIscsiTargetIndex = currentImageIscsiTargetIndex; + } + + public static class Node { + private int id; + private String ip; + private String state; + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public static Node valueOf(NodeModule nodeModule) { + Node node = new Node(); + node.setIp(nodeModule.getSpec().getAdminIp()); + node.setId(nodeModule.getSpec().getId()); + node.setState(nodeModule.getMetadata().getState().getState()); + return node; + } + } + + public static class Pool { + private int id; + private String name; + private long availableCapacity; + private long totalCapacity; + private String healthStatus; + private String redundancyPolicy; + private int replicatedSize; + private Timestamp createDate; + private Timestamp lastOpDate; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getAvailableCapacity() { + return availableCapacity; + } + + public void setAvailableCapacity(long availableCapacity) { + this.availableCapacity = availableCapacity; + } + + public long getTotalCapacity() { + return totalCapacity; + } + + public void setTotalCapacity(long totalCapacity) { + this.totalCapacity = totalCapacity; + } + + public Timestamp getCreateDate() { + return createDate; + } + + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; + } + + public String getHealthStatus() { + return healthStatus; + } + + public void setHealthStatus(String healthStatus) { + this.healthStatus = healthStatus; + } + + public static Pool valueOf(PoolModule poolModule, BsPolicyModule policy, PoolCapacity poolCapacity) { + PoolModule.PoolSpec poolSpec = poolModule.getSpec(); + Pool pool = new Pool(); + pool.setId(poolSpec.getId()); + pool.setName(poolSpec.getName()); + pool.setAvailableCapacity(poolCapacity.getAvailableCapacity()); + pool.setTotalCapacity(poolCapacity.getTotalCapacity()); + pool.setHealthStatus(poolModule.getMetadata().getState().getState()); + pool.setRedundancyPolicy(policy.getSpec().getDataReplicaType()); + pool.setReplicatedSize(policy.getSpec().getDataReplicaNum()); + pool.setCreateDate(XInfiniTimeUtil.translateToTimeStamp(poolSpec.getCreatedAt())); + pool.setLastOpDate(XInfiniTimeUtil.translateToTimeStamp(poolSpec.getUpdatedAt())); + return pool; + } + + public Timestamp getLastOpDate() { + return lastOpDate; + } + + public void setLastOpDate(Timestamp lastOpDate) { + this.lastOpDate = lastOpDate; + } + + public String getRedundancyPolicy() { + return redundancyPolicy; + } + + public void setRedundancyPolicy(String redundancyPolicy) { + this.redundancyPolicy = redundancyPolicy; + } + + public int getReplicatedSize() { + return replicatedSize; + } + + public void setReplicatedSize(int replicatedSize) { + this.replicatedSize = replicatedSize; + } + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniApiCategory.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniApiCategory.java new file mode 100644 index 00000000000..e6bf218982b --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniApiCategory.java @@ -0,0 +1,17 @@ +package org.zstack.xinfini; + +public enum XInfiniApiCategory { + AFA("afa"), + SDDC("sddc"); + + XInfiniApiCategory(String category) { + this.category = category; + } + + private String category; + + @Override + public String toString() { + return category; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniApiHelper.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniApiHelper.java new file mode 100644 index 00000000000..3a90db3b043 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniApiHelper.java @@ -0,0 +1,782 @@ +package org.zstack.xinfini; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.Maps; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.db.Q; +import org.zstack.core.retry.Retry; +import org.zstack.core.retry.RetryCondition; +import org.zstack.header.core.Completion; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.volume.VolumeConfigs; +import org.zstack.header.volume.VolumeVO; +import org.zstack.header.volume.VolumeVO_; +import org.zstack.header.xinfini.XInfiniConstants; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.data.SizeUnit; +import org.zstack.utils.function.Function; +import org.zstack.utils.logging.CLogger; +import org.zstack.xinfini.sdk.*; +import org.zstack.xinfini.sdk.cluster.QueryClusterRequest; +import org.zstack.xinfini.sdk.cluster.QueryClusterResponse; +import org.zstack.xinfini.sdk.iscsi.*; +import org.zstack.xinfini.sdk.metric.PoolMetrics; +import org.zstack.xinfini.sdk.metric.QueryMetricRequest; +import org.zstack.xinfini.sdk.metric.QueryMetricResponse; +import org.zstack.xinfini.sdk.node.*; +import org.zstack.xinfini.sdk.pool.*; +import org.zstack.xinfini.sdk.vhost.*; +import org.zstack.xinfini.sdk.volume.*; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; + +public class XInfiniApiHelper { + + private static CLogger logger = Utils.getLogger(XInfiniApiHelper.class); + XInfiniClient client; + + private final static double POOL_RESERVED_SIZE_RATIO = 0.15; + + private static final Cache snapshotClientCache = CacheBuilder.newBuilder() + .maximumSize(1000) + .build(); + + XInfiniApiHelper(XInfiniClient client) { + this.client = client; + } + + public T callWithNode(XInfiniRequest req, Class clz, XInfiniConfig.Node node) { + return client.call(req, clz, node); + } + + public T callErrorOut(XInfiniRequest req, Class clz) { + T rsp = client.call(req, clz); + errorOut(rsp); + return rsp; + } + + public T callErrorOutWithRetry(XInfiniRequest req, Class clz, int retryTimes) { + while (retryTimes-- > 0) { + T rsp = client.call(req, clz); + if (!rsp.isSuccess()) { + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException ignore) {} + } else { + return rsp; + } + } + + throw new OperationFailureException(operr("xinfini request failed, message: %s.", + req.getClass().getSimpleName())); + } + + public T call(XInfiniRequest req, Class clz) { + return client.call(req, clz); + } + + public void call(XInfiniRequest req, Completion completion) { + client.call(req, result -> { + if (result.getMessage() == null) { + completion.success(); + return; + } + + completion.fail(operr("xinfini request failed, message: %s.", result.getMessage())); + }); + } + + public void errorOut(XInfiniResponse rsp) { + if (!rsp.isSuccess()) { + throw new OperationFailureException(operr("xinfini request failed, message: %s.", rsp.getMessage())); + } + } + + public T query(XInfiniQueryRequest req, Class clz) { + return call(req, clz); + } + + public T queryErrorOut(XInfiniQueryRequest req, Class clz) { + return callErrorOut(req, clz); + } + public List queryPools() { + QueryPoolRequest req = new QueryPoolRequest(); + return queryErrorOut(req, QueryPoolResponse.class).getItems(); + } + + public PoolModule getPool(int id) { + GetPoolRequest req = new GetPoolRequest(); + req.setId(id); + return callErrorOut(req, GetPoolResponse.class).toModule(); + } + + public String getClusterUuid() { + QueryClusterRequest req = new QueryClusterRequest(); + return queryErrorOut(req, QueryClusterResponse.class).toModule().getUuid(); + } + + public Map checkNodesConnection(List nodes) { + Map nodesStatus = Maps.newConcurrentMap(); + for (XInfiniConfig.Node node : nodes) { + try { + QueryClusterRequest req = new QueryClusterRequest(); + QueryClusterResponse rsp = callWithNode(req, QueryClusterResponse.class, node); + nodesStatus.put(node.getIp(), rsp.isSuccess() ? NodeStatus.Connected : NodeStatus.Disconnected); + } catch (Exception e) { + logger.warn(String.format("get node %s connection failed, change node status to disconnected, %s", + node.getIp(), e.getMessage())); + nodesStatus.put(node.getIp(), NodeStatus.Disconnected); + } + } + + return nodesStatus; + } + + public List queryNodes() { + QueryNodeRequest req = new QueryNodeRequest(); + return queryErrorOut(req, QueryNodeResponse.class).getItems(); + } + + public NodeModule getNode(int id) { + GetNodeRequest req = new GetNodeRequest(); + req.setId(id); + return callErrorOut(req, GetNodeResponse.class).toModule(); + } + + public List queryBdcs() { + QueryBdcRequest req = new QueryBdcRequest(); + return queryErrorOut(req, QueryBdcResponse.class).getItems(); + } + + public BdcModule queryBdcByIp(String ip, boolean errorIfNotExist) { + QueryBdcRequest req = new QueryBdcRequest(); + if (CoreGlobalProperty.UNIT_TEST_ON) { + req.sortBy = "spec.id:desc"; + } else { + req.q = String.format("spec.ip:%s", ip); + } + + QueryBdcResponse rsp = queryErrorOut(req, QueryBdcResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + if (errorIfNotExist) { + throw new OperationFailureException(operr("bdc with ip %s not found.", ip)); + } + + return null; + } + + return rsp.getItems().get(0); + } + + public BdcModule queryBdcByIp(String ip) { + return queryBdcByIp(ip, true); + } + + public BdcModule getBdc(int id) { + GetBdcRequest req = new GetBdcRequest(); + req.setId(id); + return callErrorOut(req, GetBdcResponse.class).toModule(); + } + + public BsPolicyModule getBsPolicy(int id) { + GetBsPolicyRequest req = new GetBsPolicyRequest(); + req.setId(id); + return callErrorOut(req, GetBsPolicyResponse.class).toModule(); + } + + public PoolCapacity getPoolCapacity(PoolModule pool) { + PoolCapacity capacity = new PoolCapacity(); + long usedCapacity = SizeUnit.KILOBYTE.toByte(getPoolMetricValue(PoolMetrics.DATA_KBYTES, pool)); + long totalCapacity = SizeUnit.KILOBYTE.toByte(getPoolMetricValue(PoolMetrics.ACTUAL_KBYTES, pool)); + long reservedCapacity = (long) (totalCapacity * POOL_RESERVED_SIZE_RATIO); + capacity.setTotalCapacity(totalCapacity); + capacity.setAvailableCapacity(totalCapacity - usedCapacity - reservedCapacity); + return capacity; + } + + public long getPoolMetricValue(String metricName, PoolModule pool) { + QueryMetricRequest req = new QueryMetricRequest(); + req.metric = metricName; + req.lables = String.format("pool_id=%s", pool.getSpec().getId()); + QueryMetricResponse rsp = callErrorOut(req, QueryMetricResponse.class); + if (rsp.getData() == null || CollectionUtils.isEmpty(rsp.getData().getResult())) { + logger.warn(String.format("get pool[id=%s, name=%s] metric %s value failed", pool.getSpec().getId(), pool.getSpec().getName(), metricName)); + return 0; + } + + return rsp.getData().getResult().get(0).getValue(); + } + + public VolumeModule queryVolumeByName(String name) { + QueryVolumeRequest req = new QueryVolumeRequest(); + req.q = String.format("spec.name:%s", name); + QueryVolumeResponse rsp = queryErrorOut(req, QueryVolumeResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public VolumeModule queryVolumeByNameAndSnapId(String name, int snapId) { + QueryVolumeRequest req = new QueryVolumeRequest(); + req.q = String.format("((spec.name:%s) AND (spec.bs_snap_id:%s))", name, snapId); + QueryVolumeResponse rsp = queryErrorOut(req, QueryVolumeResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public VolumeModule queryVolumeById(int id) { + QueryVolumeRequest req = new QueryVolumeRequest(); + req.q = String.format("spec.id:%s", id); + QueryVolumeResponse rsp = queryErrorOut(req, QueryVolumeResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public VolumeModule getVolume(int id) { + GetVolumeRequest req = new GetVolumeRequest(); + req.setId(id); + return callErrorOut(req, GetVolumeResponse.class).toModule(); + } + + public VolumeModule createVolume(String name, int poolId, long size) { + CreateVolumeRequest req = new CreateVolumeRequest(); + req.setName(name); + req.setPoolId(poolId); + req.setSizeMb(size); + CreateVolumeResponse rsp = callErrorOut(req, CreateVolumeResponse.class); + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(rsp.getSpec().getId()); + return retryUtilStateActive(gReq, GetVolumeResponse.class, + (GetVolumeResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public VolumeSnapshotModule getVolumeSnapshot(int id) { + GetVolumeSnapshotRequest req = new GetVolumeSnapshotRequest(); + req.setId(id); + return callErrorOut(req, GetVolumeSnapshotResponse.class).toModule(); + } + + public VolumeSnapshotModule createVolumeSnapshot(int volumeId, String name) { + CreateVolumeSnapshotRequest req = new CreateVolumeSnapshotRequest(); + req.setName(name); + req.setBsVolumeId(volumeId); + CreateVolumeSnapshotResponse rsp = callErrorOut(req, CreateVolumeSnapshotResponse.class); + GetVolumeSnapshotRequest gReq = new GetVolumeSnapshotRequest(); + gReq.setId(rsp.getSpec().getId()); + return retryUtilStateActive(gReq, GetVolumeSnapshotResponse.class, + (GetVolumeSnapshotResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public VolumeModule cloneVolume(int snapId, String name, String desc, boolean flatten, XinfiniVolumeQos qos) { + CloneVolumeRequest req = new CloneVolumeRequest(); + req.setName(name); + req.setDescription(desc); + req.setBsSnapId(snapId); + req.setFlatten(flatten); + if (qos != null) { + req.setQos(qos); + } + + CloneVolumeResponse rsp = callErrorOut(req, CloneVolumeResponse.class); + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(rsp.getSpec().getId()); + return retryUtilStateActive(gReq, GetVolumeResponse.class, + (GetVolumeResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public VolumeModule flattenVolume(int volId) { + FlattenVolumeRequest req = new FlattenVolumeRequest(); + req.setId(volId); + req.setCreator(XInfiniConstants.DEFAULT_CREATOR); + callErrorOut(req, FlattenVolumeResponse.class); + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(volId); + return retryUtilStateActive(gReq, GetVolumeResponse.class, + (GetVolumeResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public VolumeModule expandVolume(int volId, long size) { + UpdateVolumeRequest req = new UpdateVolumeRequest(); + req.setCreator(XInfiniConstants.DEFAULT_CREATOR); + req.setId(volId); + req.setSizeMb(size); + callErrorOut(req, UpdateVolumeResponse.class); + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(volId); + return retryUtilStateActive(gReq, GetVolumeResponse.class, + (GetVolumeResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public VolumeModule setVolumeQos(int volId, XinfiniVolumeQos qos) { + UpdateVolumeRequest req = new UpdateVolumeRequest(); + req.setCreator(XInfiniConstants.DEFAULT_CREATOR); + req.setId(volId); + req.setQos(qos); + callErrorOut(req, UpdateVolumeResponse.class); + return getVolume(volId); + } + + public VolumeModule deleteVolumeQos(int volId) { + UpdateVolumeRequest req = new UpdateVolumeRequest(); + req.setCreator(XInfiniConstants.DEFAULT_CREATOR); + req.setId(volId); + req.setQos(new XinfiniVolumeQos()); + callErrorOut(req, UpdateVolumeResponse.class); + return getVolume(volId); + } + + private void retryUtilResourceDeletedIn10Secs(XInfiniRequest req, + Class rsp) { + new Retry() { + @Override + @RetryCondition(times = 5, interval = 2) + protected Void call() { + T r = XInfiniApiHelper.this.call(req, rsp); + if (!r.resourceIsDeleted()) { + throw new RetryException("resource not deleted yet"); + } + + return null; + } + + @Override + // not error out if delete failed + protected boolean onFailure(Throwable t) { + return false; + } + }.run(); + } + + private void retryUtilResourceDeleted(XInfiniRequest req, + Class rsp) { + new Retry() { + @Override + @RetryCondition(times = 150, interval = 2) + protected Void call() { + T r = XInfiniApiHelper.this.call(req, rsp); + if (!r.resourceIsDeleted()) { + throw new RetryException("resource not deleted yet"); + } + + return null; + } + + @Override + // not error out if delete failed + protected boolean onFailure(Throwable t) { + return false; + } + }.run(); + } + + private T retryUtilStateActive(XInfiniRequest req, + Class rsp, + Function activeGetter) { + return new Retry() { + @Override + @RetryCondition(onExceptions = {RetryException.class}, + times = XInfiniConstants.DEFAULT_POLLING_TIMES) + protected T call() { + T r = callErrorOut(req, rsp); + if (!activeGetter.call(r).equals(MetadataState.active.toString())) { + throw new RetryException("state not active yet"); + } + return r; + } + }.run(); + } + + public BdcBdevModule createBdcBdev(int bdcId, int volumeId, String name, VolumeConfigs vcfs) { + CreateBdcBdevRequest req = new CreateBdcBdevRequest(); + req.setName(name); + req.setBdcId(bdcId); + req.setBsVolumeId(volumeId); + req.setQueueNum(vcfs.getQueueNum()); + CreateBdcBdevResponse rsp = callErrorOutWithRetry(req, CreateBdcBdevResponse.class, 3); + GetBdcBdevRequest gReq = new GetBdcBdevRequest(); + gReq.setId(rsp.getSpec().getId()); + return retryUtilStateActive(gReq, GetBdcBdevResponse.class, + (GetBdcBdevResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public BdcBdevModule queryBdcBdevByVolumeIdAndBdcId(int volId, int bdcId) { + QueryBdcBdevRequest req = new QueryBdcBdevRequest(); + req.q = String.format("((spec.bdc_id:%s) AND (spec.bs_volume_id:%s))", bdcId, volId); + QueryBdcBdevResponse rsp = queryErrorOut(req, QueryBdcBdevResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public BdcBdevModule getOrCreateBdcBdevByVolumeIdAndBdcId(int volId, int bdcId, String bdevName, VolumeConfigs vcfs) { + QueryBdcBdevRequest req = new QueryBdcBdevRequest(); + req.q = String.format("((spec.bdc_id:%s) AND (spec.bs_volume_id:%s))", bdcId, volId); + QueryBdcBdevResponse rsp = queryErrorOut(req, QueryBdcBdevResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return createBdcBdev(bdcId, volId, bdevName, vcfs); + } + + return rsp.getItems().get(0); + } + + public List queryBdcBdevByVolumeId(int volId) { + QueryBdcBdevRequest req = new QueryBdcBdevRequest(); + req.q = String.format("spec.bs_volume_id:%s", volId); + return queryErrorOut(req, QueryBdcBdevResponse.class).getItems(); + } + + public BdcBdevModule getBdcBdev(int id) { + GetBdcBdevRequest req = new GetBdcBdevRequest(); + req.setId(id); + return callErrorOut(req, GetBdcBdevResponse.class).toModule(); + } + + public void deleteBdcBdev(int bdevId, int bdcId) { + DeleteBdcBdevRequest req = new DeleteBdcBdevRequest(); + req.setId(bdevId); + DeleteBdcBdevResponse rsp = call(req, DeleteBdcBdevResponse.class); + if (!rsp.isSuccess()) { + if (rsp.resourceIsDeleted()) { + logger.info(String.format("bdev %s has been deleted, skip send delete req", bdevId)); + return; + } + + throw new OperationFailureException(operr("delete bdev failed %s", rsp.getMessage())); + } + + GetBdcBdevRequest gReq = new GetBdcBdevRequest(); + gReq.setId(bdevId); + BdcModule bdc = getBdc(bdcId); + if (!BdcRunState.Active.toString().equals(bdc.getStatus().getRunState())) { + logger.info(String.format("bdc %s is not active, current %s, check bdev deleted in 30s", + bdcId, bdc.getStatus().getRunState())); + retryUtilResourceDeletedIn10Secs(gReq, GetBdcBdevResponse.class); + } else { + retryUtilResourceDeleted(gReq, GetBdcBdevResponse.class); + } + } + + public VolumeModule rollbackSnapshot(int volId, int snapId) { + RollbackSnapshotRequest req = new RollbackSnapshotRequest(); + req.setId(volId); + req.setBsSnapId(snapId); + callErrorOut(req, RollbackSnapshotResponse.class); + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(volId); + return retryUtilStateActive(gReq, GetVolumeResponse.class, + (GetVolumeResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public void deleteVolume(int volId, boolean force) { + List mappings = queryVolumeClientGroupMappingByVolId(volId); + if (!CollectionUtils.isEmpty(mappings)) { + logger.info(String.format("find volume %s has %s related client group mappings, delete mappings", volId, mappings.size())); + for (VolumeClientGroupMappingModule mapping : mappings) { + deleteVolumeClientGroupMapping(mapping.getSpec().getId()); + } + } + + DeleteVolumeRequest req = new DeleteVolumeRequest(); + req.setId(volId); + DeleteVolumeResponse rsp = call(req, DeleteVolumeResponse.class); + if (!rsp.isSuccess()) { + if (rsp.resourceIsDeleted()) { + logger.info(String.format("volume %s has been deleted, skip send delete req", volId)); + return; + } + + throw new OperationFailureException(operr("delete volume failed %s", rsp.getMessage())); + } + + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(volId); + retryUtilResourceDeleted(gReq, GetVolumeResponse.class); + } + + public void deleteVolumeAndSnapshot(int volId) { + for (VolumeSnapshotModule mod : queryVolumeSnapshotByVolumeId(volId)) { + deleteVolumeSnapshot(mod.getSpec().getId()); + } + deleteVolume(volId, true); + } + + public void deleteVolumeSnapshot(int snapShotId) { + // check snapshot cloned volume + QueryVolumeRequest vReq = new QueryVolumeRequest(); + vReq.q = String.format("spec.bs_snap_id:%s", snapShotId); + QueryVolumeResponse vRsp = queryErrorOut(vReq, QueryVolumeResponse.class); + if (vRsp.getMetadata().getPagination().getCount() > 0) { + List volNames = vRsp.getItems().stream().map(VolumeModule::getSpec).map(VolumeModule.VolumeSpec::getName).collect(Collectors.toList()); + List installPaths = vRsp.getItems().stream() + .map(v -> XInfiniPathHelper.buildXInfiniPath(v.getSpec().getPoolId(), v.getSpec().getId())) + .collect(Collectors.toList()); + + logger.info(String.format("find cloned volumes paths: %s", installPaths)); + + boolean exist = Q.New(VolumeVO.class) + .in(VolumeVO_.installPath, installPaths) + .isExists(); + + if (exist) { + VolumeSnapshotModule snap = getVolumeSnapshot(snapShotId); + throw new OperationFailureException(operr("snapshot [id:%s, name:%s] has %d cloned volumes, volumes names: %s", snapShotId, snap.getSpec().getName(), vRsp.getMetadata().getPagination().getCount(), volNames)); + } + logger.info("all cloned volumes not exist in database, try to delete them"); + // try to delete cloned volumes if not exist in db + for (VolumeModule v : vRsp.getItems()) { + deleteVolumeAndSnapshot(v.getSpec().getId()); + } + } + + DeleteVolumeSnapshotRequest req = new DeleteVolumeSnapshotRequest(); + req.setId(snapShotId); + DeleteVolumeSnapshotResponse rsp = call(req, DeleteVolumeSnapshotResponse.class); + + if (!rsp.isSuccess()) { + if (rsp.resourceIsDeleted()) { + logger.info(String.format("volume snapshot %s has been deleted, skip send delete req", snapShotId)); + return; + } + + throw new OperationFailureException(operr("delete volume snapshot failed %s", rsp.getMessage())); + } + GetVolumeSnapshotRequest gReq = new GetVolumeSnapshotRequest(); + gReq.setId(snapShotId); + retryUtilResourceDeleted(gReq, GetVolumeSnapshotResponse.class); + } + + public boolean snapshotHasClonedVolume(int snapId) { + QueryVolumeRequest req = new QueryVolumeRequest(); + req.q = String.format("spec.bs_snap_id:%s", snapId); + QueryVolumeResponse rsp = queryErrorOut(req, QueryVolumeResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return false; + } + + List volNames = rsp.getItems().stream().map(VolumeModule::getSpec).map(VolumeModule.VolumeSpec::getName).collect(Collectors.toList()); + + logger.info(String.format("snapshot %s has %d cloned volume, volume names: %s", snapId, rsp.getMetadata().getPagination().getCount(), volNames)); + return true; + } + + public List queryVolumeSnapshotByVolumeId(int volId) { + QueryVolumeSnapshotRequest req = new QueryVolumeSnapshotRequest(); + req.q = String.format("spec.bs_volume_id:%s", volId); + return queryErrorOut(req, QueryVolumeSnapshotResponse.class).getItems(); + } + + public VolumeSnapshotModule queryVolumeSnapshotByName(String name) { + QueryVolumeSnapshotRequest req = new QueryVolumeSnapshotRequest(); + req.q = String.format("spec.name:%s", name); + QueryVolumeSnapshotResponse rsp = queryErrorOut(req, QueryVolumeSnapshotResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + return rsp.getItems().get(0); + } + + public List queryIscsiGateways() { + QueryIscsiGatewayRequest req = new QueryIscsiGatewayRequest(); + return queryErrorOut(req, QueryIscsiGatewayResponse.class).getItems(); + } + + public List queryIscsiGatewaysByIds(List ids) { + QueryIscsiGatewayRequest req = new QueryIscsiGatewayRequest(); + req.q = String.format("spec.id:(%s)", ids.stream().map(String::valueOf).collect(Collectors.joining(" "))); + return queryErrorOut(req, QueryIscsiGatewayResponse.class).getItems(); + } + + public List queryIscsiClientGroups() { + QueryIscsiClientGroupRequest req = new QueryIscsiClientGroupRequest(); + return queryErrorOut(req, QueryIscsiClientGroupResponse.class).getItems(); + } + + public IscsiClientGroupModule queryIscsiClientGroupByName(String name) { + QueryIscsiClientGroupRequest req = new QueryIscsiClientGroupRequest(); + req.q = String.format("spec.name:%s", name); + QueryIscsiClientGroupResponse rsp = queryErrorOut(req, QueryIscsiClientGroupResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public IscsiClientModule createIscsiClient(String name, String code, int iscsiClientGroupId) { + CreateIscsiClientRequest req = new CreateIscsiClientRequest(); + req.setName(name); + req.setCode(code); + req.setIscsiClientGroupId(iscsiClientGroupId); + CreateIscsiClientResponse rsp = callErrorOut(req, CreateIscsiClientResponse.class); + GetIscsiClientRequest gReq = new GetIscsiClientRequest(); + gReq.setId(rsp.getSpec().getId()); + return retryUtilStateActive(gReq, GetIscsiClientResponse.class, + (GetIscsiClientResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public IscsiClientModule getIscsiClient(int id) { + GetIscsiClientRequest req = new GetIscsiClientRequest(); + req.setId(id); + return callErrorOut(req, GetIscsiClientResponse.class).toModule(); + } + + public void addVolumeClientGroupMapping(int volumeId, int iscsiClientGroupId) { + QueryVolumeClientGroupMappingRequest qReq = new QueryVolumeClientGroupMappingRequest(); + qReq.q = String.format("((spec.iscsi_client_group_id:%s) AND (spec.bs_volume_id:%s))", iscsiClientGroupId, volumeId); + if (queryErrorOut(qReq, QueryVolumeClientGroupMappingResponse.class).getMetadata().getPagination().getCount() > 0) { + logger.info(String.format("volume %s has already been mapped to iscsi client group %s, skip add", volumeId, iscsiClientGroupId)); + return; + } + + AddVolumeClientGroupMappingRequest req = new AddVolumeClientGroupMappingRequest(); + req.setId(volumeId); + req.setIscsiClientGroupIds(Collections.singletonList(iscsiClientGroupId)); + callErrorOut(req, AddVolumeClientGroupMappingResponse.class); + + GetVolumeRequest gReq = new GetVolumeRequest(); + gReq.setId(volumeId); + retryUtilStateActive(gReq, GetVolumeResponse.class, + (GetVolumeResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public void deleteVolumeClientGroupMapping(int mapId) { + DeleteVolumeClientGroupMappingRequest req = new DeleteVolumeClientGroupMappingRequest(); + req.setId(mapId); + DeleteVolumeClientGroupMappingResponse rsp = call(req, DeleteVolumeClientGroupMappingResponse.class); + if (!rsp.isSuccess()) { + if (rsp.resourceIsDeleted()) { + logger.info(String.format("volume-client-group-mapping %s has been deleted, skip send delete req", mapId)); + return; + } + + throw new OperationFailureException(operr("delete volume-client-group-mapping failed %s", rsp.getMessage())); + } + + GetVolumeClientGroupMappingRequest gReq = new GetVolumeClientGroupMappingRequest(); + gReq.setId(mapId); + retryUtilResourceDeleted(gReq, GetVolumeClientGroupMappingResponse.class); + } + + public List queryIscsiGatewayClientGroupMappingByGroupId(int groupId) { + QueryIscsiGatewayClientGroupMappingRequest req = new QueryIscsiGatewayClientGroupMappingRequest(); + req.q = String.format("spec.iscsi_client_group_id:%s", groupId); + return queryErrorOut(req, QueryIscsiGatewayClientGroupMappingResponse.class).getItems(); + } + + public List queryIscsiClientByGroupId(int groupId) { + QueryIscsiClientRequest req = new QueryIscsiClientRequest(); + req.q = String.format("spec.iscsi_client_group_id:%s", groupId); + return queryErrorOut(req, QueryIscsiClientResponse.class).getItems(); + } + + public List queryIscsiClientByIds(List ids) { + QueryIscsiClientRequest req = new QueryIscsiClientRequest(); + req.q = String.format("spec.id:(%s)", ids.stream().map(String::valueOf).collect(Collectors.joining(" "))); + return queryErrorOut(req, QueryIscsiClientResponse.class).getItems(); + } + + public IscsiClientModule queryIscsiClientByIqn(String code) { + QueryIscsiClientRequest req = new QueryIscsiClientRequest(); + req.q = String.format("spec.code:%s", code); + QueryIscsiClientResponse rsp = queryErrorOut(req, QueryIscsiClientResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public void deleteIscsiClient(int iscsiClientId) { + DeleteIscsiClientRequest req = new DeleteIscsiClientRequest(); + req.setId(iscsiClientId); + DeleteIscsiClientResponse rsp = call(req, DeleteIscsiClientResponse.class); + if (!rsp.isSuccess()) { + if (rsp.resourceIsDeleted()) { + logger.info(String.format("iscsi-client %s has been deleted, skip send delete req", iscsiClientId)); + return; + } + + throw new OperationFailureException(operr("delete iscsi client failed %s", rsp.getMessage())); + } + + GetIscsiClientRequest gReq = new GetIscsiClientRequest(); + gReq.setId(iscsiClientId); + retryUtilResourceDeleted(gReq, GetIscsiClientResponse.class); + } + + public IscsiClientGroupModule createIscsiClientGroup(String name, List iscsiGatewayIds, List iscsiClientCodes) { + CreateIscsiClientGroupRequest req = new CreateIscsiClientGroupRequest(); + req.setName(name); + req.setIscsiGatewayIds(iscsiGatewayIds); + req.setIscsiClientCodes(iscsiClientCodes); + CreateIscsiClientGroupResponse rsp = callErrorOut(req, CreateIscsiClientGroupResponse.class); + + GetIscsiClientGroupRequest gReq = new GetIscsiClientGroupRequest(); + gReq.setId(rsp.getSpec().getId()); + return retryUtilStateActive(gReq, GetIscsiClientGroupResponse.class,(GetIscsiClientGroupResponse gvp) -> gvp.toModule().getMetadata().getState().getState()).toModule(); + } + + public IscsiClientGroupModule getIscsiClientGroup(int id) { + GetIscsiClientGroupRequest req = new GetIscsiClientGroupRequest(); + req.setId(id); + return call(req, GetIscsiClientGroupResponse.class).toModule(); + } + + public VolumeClientGroupMappingModule queryVolumeClientGroupMappingByGroupIdAndVolId(int groupId, int volId) { + QueryVolumeClientGroupMappingRequest req = new QueryVolumeClientGroupMappingRequest(); + req.q = String.format("((spec.iscsi_client_group_id:%s) AND (spec.bs_volume_id:%s))", groupId, volId); + QueryVolumeClientGroupMappingResponse rsp = queryErrorOut(req, QueryVolumeClientGroupMappingResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return rsp.getItems().get(0); + } + + public List queryVolumeClientGroupMappingByVolId(int volId) { + QueryVolumeClientGroupMappingRequest req = new QueryVolumeClientGroupMappingRequest(); + req.q = String.format("spec.bs_volume_id:%s", volId); + return queryErrorOut(req, QueryVolumeClientGroupMappingResponse.class).getItems(); + } + + public List queryVolumeClientMappingByVolId(int volId) { + QueryVolumeClientMappingRequest req = new QueryVolumeClientMappingRequest(); + req.q = String.format("spec.bs_volume_id:%s", volId); + return queryErrorOut(req, QueryVolumeClientMappingResponse.class).getItems(); + } + + + public List queryVolumeClientGroupMappings() { + QueryVolumeClientGroupMappingRequest req = new QueryVolumeClientGroupMappingRequest(); + return queryErrorOut(req, QueryVolumeClientGroupMappingResponse.class).getItems(); + } + + public IscsiClientGroupModule queryIscsiClientGroupByVolumeId(int volId) { + QueryVolumeClientGroupMappingRequest req = new QueryVolumeClientGroupMappingRequest(); + req.q = String.format("spec.bs_volume_id:%s", volId); + QueryVolumeClientGroupMappingResponse rsp = queryErrorOut(req, QueryVolumeClientGroupMappingResponse.class); + if (rsp.getMetadata().getPagination().getCount() == 0) { + return null; + } + + return getIscsiClientGroup(rsp.getItems().get(0).getSpec().getIscsiClientGroupId()); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniConfig.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniConfig.java new file mode 100644 index 00000000000..88b498ce9ef --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniConfig.java @@ -0,0 +1,113 @@ +package org.zstack.xinfini; + +import org.zstack.header.log.NoLogging; + +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @example + * {"pools":[{"id": 1, "name":"pool", "aliasName":"test"}]. + * "token": "sddc-xxxxx", + * "nodes":[{"ip": 10.0.0.1, "port":"80", "status":"active"}]} + */ +public class XInfiniConfig { + @NoLogging + private String token; + private List pools; + private List nodes; + + public static class Pool { + private int id; + private String name; + private String aliasName; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAliasName() { + return aliasName; + } + + public void setAliasName(String aliasName) { + this.aliasName = aliasName; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + } + + public static class Node { + private String ip; + private int port; + private NodeStatus status = NodeStatus.Connected; + + public NodeStatus getStatus() { + return status; + } + + public void setStatus(NodeStatus status) { + this.status = status; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + } + + public List getNodes() { + return nodes; + } + + public void setNodes(List nodes) { + this.nodes = nodes; + } + + public void setPools(List pools) { + this.pools = pools; + } + + public List getPools() { + return pools; + } + + public Set getPoolNames() { + return pools == null ? Collections.emptySet() : pools.stream().map(Pool::getName).collect(Collectors.toSet()); + } + + public Set getPoolIds() { + return pools == null ? Collections.emptySet() : pools.stream().map(Pool::getId).collect(Collectors.toSet()); + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniIscsiHelper.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniIscsiHelper.java new file mode 100644 index 00000000000..b9e1155719c --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniIscsiHelper.java @@ -0,0 +1,9 @@ +package org.zstack.xinfini; + +public class XInfiniIscsiHelper { + + static String iscsiHeartbeatVolumeName = "iscsi_zstack_heartbeat"; + static String buildIscsiClientGroupName(String clientIp) { + return "iscsi_" + clientIp.replace(".", "_"); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniPathHelper.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniPathHelper.java new file mode 100644 index 00000000000..0d057986f71 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniPathHelper.java @@ -0,0 +1,48 @@ +package org.zstack.xinfini; + +import org.zstack.header.errorcode.OperationFailureException; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.zstack.core.Platform.operr; + +/** + * xinfini volume path like : + * xinfini://1/2, + * 1: pool id, 2: volume id + **/ +public class XInfiniPathHelper { + + public static String buildBdevName(String zsVolumeUuid) { + return "volume-" + zsVolumeUuid; + } + + public static String buildXInfiniPath(Integer poolId, Integer volId) { + return String.format("xinfini://%s/%s", poolId, volId); + } + + public static String buildXInfiniSnapshotPath(String volPath, Integer snapId) { + return volPath + "@" + snapId; + } + + public static String buildXInfiniSnapshotPath(Integer poolId, Integer volId, Integer snapId) { + return String.format("xinfini://%s/%s@%s", poolId, volId, snapId); + } + + public static int getPoolIdFromPath(String url) { + return Integer.parseInt(url.replace("xinfini://", "").split("/")[0]); + } + + public static int getVolIdFromPath(String url) { + return Integer.parseInt(url.replace("xinfini://", "").split("/")[1].split("@")[0]); + } + + public static int getSnapIdFromPath(String url) { + return Integer.parseInt(url.replace("xinfini://", "").split("/")[1].split("@")[1]); + } + + public static String buildSnapshotExportVolumeName(int snapId) { + return String.format("for-snapshot-%s-iscsi-export", snapId); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniStorageController.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniStorageController.java new file mode 100644 index 00000000000..267d55f4039 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniStorageController.java @@ -0,0 +1,1053 @@ +package org.zstack.xinfini; + +import org.apache.commons.lang.StringUtils; +import org.apache.lucene.util.packed.DirectMonotonicReader; +import org.springframework.beans.factory.annotation.Autowire; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.zstack.core.CoreGlobalProperty; +import org.zstack.core.db.DatabaseFacade; +import org.zstack.core.db.Q; +import org.zstack.core.db.SQL; +import org.zstack.core.thread.ThreadFacade; +import org.zstack.header.core.Completion; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.header.host.HostInventory; +import org.zstack.header.host.HostVO; +import org.zstack.header.host.HostVO_; +import org.zstack.header.storage.addon.*; +import org.zstack.header.storage.addon.primary.*; +import org.zstack.header.storage.primary.VolumeSnapshotCapability; +import org.zstack.header.storage.snapshot.VolumeSnapshotStats; +import org.zstack.header.volume.*; +import org.zstack.header.xinfini.XInfiniConstants; +import org.zstack.iscsi.IscsiUtils; +import org.zstack.iscsi.kvm.IscsiHeartbeatVolumeTO; +import org.zstack.iscsi.kvm.IscsiVolumeTO; +import org.zstack.kvm.KVMConstant; +import org.zstack.resourceconfig.ResourceConfigFacade; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; +import org.zstack.storage.volume.VolumeConfigsGetter; +import org.zstack.utils.CollectionUtils; +import org.zstack.utils.DebugUtils; +import org.zstack.utils.Utils; +import org.zstack.utils.data.SizeUnit; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.path.PathUtil; +import org.zstack.vhost.kvm.VhostVolumeTO; +import org.zstack.xinfini.sdk.MetadataState; +import org.zstack.xinfini.sdk.XInfiniClient; +import org.zstack.xinfini.sdk.XInfiniConnectConfig; +import org.zstack.xinfini.sdk.iscsi.*; +import org.zstack.xinfini.sdk.node.NodeModule; +import org.zstack.xinfini.sdk.pool.BsPolicyModule; +import org.zstack.xinfini.sdk.pool.PoolCapacity; +import org.zstack.xinfini.sdk.pool.PoolModule; +import org.zstack.xinfini.sdk.vhost.BdcBdevModule; +import org.zstack.xinfini.sdk.vhost.BdcModule; +import org.zstack.xinfini.sdk.vhost.BdcRunState; +import org.zstack.xinfini.sdk.volume.VolumeModule; +import org.zstack.xinfini.sdk.volume.VolumeSnapshotModule; +import org.zstack.xinfini.sdk.volume.XinfiniVolumeQos; + +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import static org.zstack.core.Platform.operr; +import static org.zstack.iscsi.IscsiUtils.getHostMnIpFromInitiatorName; +import static org.zstack.storage.addon.primary.ExternalPrimaryStorageNameHelper.buildImageName; +import static org.zstack.storage.addon.primary.ExternalPrimaryStorageNameHelper.buildVolumeName; +import static org.zstack.xinfini.XInfiniIscsiHelper.buildIscsiClientGroupName; +import static org.zstack.xinfini.XInfiniIscsiHelper.iscsiHeartbeatVolumeName; +import static org.zstack.xinfini.XInfiniPathHelper.*; + +@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) +public class XInfiniStorageController implements PrimaryStorageControllerSvc, PrimaryStorageNodeSvc { + private static CLogger logger = Utils.getLogger(XInfiniStorageController.class); + + @Autowired + private DatabaseFacade dbf; + @Autowired + private ThreadFacade thdf; + private ExternalPrimaryStorageVO self; + private XInfiniConfig config; + private XInfiniAddonInfo addonInfo; + private final XInfiniApiHelper apiHelper; + @Autowired + private ResourceConfigFacade rcf; + + private String vhostSocketDir; + + private String getVhostSocketDir() { + if (vhostSocketDir == null) { + vhostSocketDir = String.format("/var/run/bdc-%s/", apiHelper.getClusterUuid()); + } + + return vhostSocketDir; + } + + private static final StorageCapabilities capabilities = new StorageCapabilities(); + + private final static long MIN_SIZE = 1024 * 1024 * 1024L; + + static { + VolumeSnapshotCapability scap = new VolumeSnapshotCapability(); + scap.setSupport(true); + scap.setArrangementType(VolumeSnapshotCapability.VolumeSnapshotArrangementType.INDIVIDUAL); + scap.setPlacementType(VolumeSnapshotCapability.VolumeSnapshotPlacementType.INTERNAL); + scap.setSupportCreateOnHypervisor(false); + scap.setSupportLazyDelete(false); + scap.setVolumePathFromInternalSnapshotRegex("^[^@]+"); + capabilities.setSnapshotCapability(scap); + capabilities.setSupportCloneFromVolume(false); + capabilities.setSupportStorageQos(false); + capabilities.setSupportLiveExpandVolume(false); + capabilities.setSupportExportVolumeSnapshot(false); + capabilities.setSupportedImageFormats(Collections.singletonList("raw")); + } + + enum LunType { + Volume, + Snapshot + } + + public XInfiniStorageController(ExternalPrimaryStorageVO self) { + this(self.getConfig()); + this.self = self; + this.reloadDbInfo(); + } + + public XInfiniStorageController(String configStr) { + config = JSONObjectUtil.toObject(configStr, XInfiniConfig.class); + XInfiniConnectConfig clientConfig = new XInfiniConnectConfig(); + clientConfig.readTimeout = TimeUnit.MINUTES.toMillis(10); + clientConfig.writeTimeout = TimeUnit.MINUTES.toMillis(10); + clientConfig.token = config.getToken(); + clientConfig.xInfiniConfig = config; + XInfiniClient client = new XInfiniClient(); + client.configure(clientConfig); + + apiHelper = new XInfiniApiHelper(client); + } + + private String protocolToString(VolumeProtocol protocol) { + if (protocol == VolumeProtocol.NVMEoF) { + return "nvmf"; + } else if (protocol == VolumeProtocol.Vhost) { + return "vhost"; + } else if (protocol == VolumeProtocol.iSCSI) { + return "iscsi"; + } else { + throw new RuntimeException("not supported protocol " + protocol); + } + } + + @Override + public void activate(BaseVolumeInfo v, HostInventory h, boolean shareable, ReturnValueCompletion comp) { + ActiveVolumeTO to; + if (VolumeProtocol.Vhost.toString().equals(v.getProtocol())) { + to = activeVhostVolume(h, v); + comp.success(to); + return; + } else if (VolumeProtocol.iSCSI.toString().equals(v.getProtocol())) { + to = activeIscsiVolume(h, v, shareable); + comp.success(to); + return; + } + + comp.fail(operr("not supported protocol[%s]", v.getProtocol())); + } + + private ActiveVolumeTO activeVhostVolume(HostInventory h, BaseVolumeInfo vol) { + String vhostName = buildBdevName(vol.getUuid()); + BdcModule bdc = apiHelper.queryBdcByIp(h.getManagementIp()); + VolumeModule volModule = getVolumeModule(vol); + if (volModule == null) { + throw new OperationFailureException(operr("cannot get volume[%s] details, maybe it has been deleted", vol.getInstallPath())); + } + + VhostVolumeTO to = new VhostVolumeTO(); + BdcBdevModule bdev = apiHelper.queryBdcBdevByVolumeIdAndBdcId(volModule.getSpec().getId(), bdc.getSpec().getId()); + if (bdev != null && MetadataState.active.toString().equals(bdev.getMetadata().getState().getState())) { + logger.info("dest bdc bdev has been created, skip active"); + to.setInstallPath(bdev.getSpec().getSocketPath()); + return to; + } + + VolumeConfigs vcfs = new VolumeConfigsGetter().getConfigs(vol.getUuid()); + bdev = apiHelper.createBdcBdev(bdc.getSpec().getId(), volModule.getSpec().getId(), vhostName, vcfs); + to.setInstallPath(bdev.getSpec().getSocketPath()); + return to; + } + + private synchronized ActiveVolumeTO activeIscsiVolume(HostInventory h, BaseVolumeInfo vol, boolean shareable) { + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (clientIqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + return activeIscsiVolume(h.getManagementIp(), clientIqn, vol, shareable); + } + + public synchronized ActiveVolumeTO activeIscsiVolume(String clientIp, String clientIqn, BaseVolumeInfo vol, boolean shareable) { + IscsiVolumeTO to = new IscsiVolumeTO(); + IscsiRemoteTarget target = createIscsiRemoteTarget(clientIp, clientIqn, vol.getInstallPath()); + to.setInstallPath(target.getResourceURI()); + return to; + } + + @Override + public void deactivate(String installPath, String protocol, HostInventory h, Completion comp) { + logger.debug(String.format("deactivating volume[path: %s, protocol:%s] on host[uuid:%s, ip:%s]", + installPath, protocol, h.getUuid(), h.getManagementIp())); + if (VolumeProtocol.Vhost.toString().equals(protocol)) { + deactivateVhost(installPath, h); + comp.success(); + return; + } else if (VolumeProtocol.iSCSI.toString().equals(protocol)) { + // iscsi target is shared by all hosts, we cannot control one volume on one host for now. + deactivateIscsi(installPath, h); + comp.success(); + return; + } + + comp.fail(operr("not supported protocol[%s] for deactivate", protocol)); + } + + private void deactivateIscsi(String installPath, HostInventory h) { + String iqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (iqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + deactivateIscsi(installPath, iqn); + } + + public void deactivateIscsi(String installPath, String clientIqn) { + int volId = getVolIdFromPath(installPath); + IscsiClientModule client = apiHelper.queryIscsiClientByIqn(clientIqn); + if (client == null) { + logger.info(String.format("cannot find client with code %s, skip deactive", clientIqn)); + return; + } + + IscsiClientGroupModule group = apiHelper.getIscsiClientGroup(client.getSpec().getIscsiClientGroupId()); + VolumeClientGroupMappingModule map = apiHelper.queryVolumeClientGroupMappingByGroupIdAndVolId(group.getSpec().getId(), volId); + if (map == null) { + logger.info(String.format("vol %s not related to client group %s, skip deactive", volId, group.getSpec().getId())); + return; + } + + retry(() -> apiHelper.deleteVolumeClientGroupMapping(map.getSpec().getId())); + } + + private void deactivateVhost(String installPath, HostInventory h) { + int volId = getVolIdFromPath(installPath); + VolumeModule vol = apiHelper.getVolume(volId); + BdcModule bdc = apiHelper.queryBdcByIp(h.getManagementIp(), false); + if (bdc == null) { + return; + } + + BdcBdevModule bdev = apiHelper.queryBdcBdevByVolumeIdAndBdcId(vol.getSpec().getId(), bdc.getSpec().getId()); + if (bdev == null) { + return; + } + + retry(() -> apiHelper.deleteBdcBdev(bdev.getSpec().getId(), bdc.getSpec().getId())); + } + + @Override + public void deactivate(String installPath, String protocol, ActiveVolumeClient client, Completion comp) { + HostVO host = Q.New(HostVO.class).eq(HostVO_.managementIp, client.getManagerIp()).find(); + if (host != null) { + deactivate(installPath, protocol, HostInventory.valueOf(host), comp); + } else { + // bm instance InitiatorName + deactivateIscsi(installPath, client.getQualifiedName()); + comp.success(); + } + } + + @Override + public void blacklist(String installPath, String protocol, HostInventory h, Completion comp) { + // todo + comp.success(); + } + + @Override + public String getActivePath(BaseVolumeInfo v, HostInventory h, boolean shareable) { + if (VolumeProtocol.Vhost.toString().equals(v.getProtocol())) { + String bdevName = buildBdevName(v.getUuid()); + BdcModule bdc = apiHelper.queryBdcByIp(h.getManagementIp()); + VolumeModule volModule = getVolumeModule(v); + VolumeConfigs vcfs = new VolumeConfigsGetter().getConfigs(v.getUuid()); + BdcBdevModule bdev = apiHelper.getOrCreateBdcBdevByVolumeIdAndBdcId(volModule.getSpec().getId(), + bdc.getSpec().getId(), bdevName, vcfs); + return bdev.getSpec().getSocketPath(); + } else if (VolumeProtocol.iSCSI.toString().equals(v.getProtocol())) { + int volId; + if (v.getInstallPath().contains("@")) { + int snapId = getSnapIdFromPath(v.getInstallPath()); + VolumeModule vol = apiHelper.queryVolumeByNameAndSnapId(buildSnapshotExportVolumeName(snapId), snapId); + if (vol == null) { + logger.info(String.format("can not find exported volume for snapshot %s", snapId)); + return null; + } + volId = vol.getSpec().getId(); + } else { + volId = getVolIdFromPath(v.getInstallPath()); + } + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + IscsiClientModule client = apiHelper.queryIscsiClientByIqn(clientIqn); + IscsiClientGroupModule group = apiHelper.getIscsiClientGroup(client.getSpec().getIscsiClientGroupId()); + VolumeClientGroupMappingModule map = apiHelper.queryVolumeClientGroupMappingByGroupIdAndVolId(group.getSpec().getId(), volId); + if (map == null) { + logger.info(String.format("vol %s not related to client group %s, skip get installPath", volId, group.getSpec().getId())); + return null; + } + + List iscsiGateways = apiHelper.queryIscsiGateways(); + List mappings = apiHelper.queryIscsiGatewayClientGroupMappingByGroupId(group.getSpec().getId()); + List gatewayIds = mappings.stream() + .map(IscsiGatewayClientGroupMappingModule::getSpec) + .map(IscsiGatewayClientGroupMappingModule.IscsiGatewayClientGroupMappingSpec::getIscsiGatewayId) + .collect(Collectors.toList()); + List groupRelatedGateways = iscsiGateways + .stream() + .filter(it -> gatewayIds.contains(it.getSpec().getId())) + .collect(Collectors.toList()); + + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(groupRelatedGateways.get(0).getSpec().getPort()); + target.setTransport("tcp"); + target.setIqn(client.getStatus().getTargetIqns().get(0)); + target.setIp(groupRelatedGateways.stream().map(it -> it.getSpec().getIps().get(0)).collect(Collectors.joining(","))); + target.setDiskId(apiHelper.getVolume(volId).getSpec().getSerial()); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.serial.toString()); + return target.getResourceURI(); + } + + throw new OperationFailureException(operr("not supported protocol[%s]", v.getProtocol())); + } + + @Override + public BaseVolumeInfo getActiveVolumeInfo(String activePath, HostInventory h, boolean shareable) { + BaseVolumeInfo info = new BaseVolumeInfo(); + String volUuid; + if (activePath.startsWith(getVhostSocketDir())) { + volUuid = activePath.replace(String.format("%svolume-", getVhostSocketDir()), ""); + info.setUuid(volUuid); + info.setProtocol(VolumeProtocol.Vhost.toString()); + info.setShareable(shareable); + } else { + // TODO support other protocols + throw new OperationFailureException(operr("not supported get volume info from [%s]", activePath)); + } + + VolumeModule vol = apiHelper.queryVolumeByName(buildVolumeName(volUuid)); + if (vol == null) { + return info; + } + + info.setInstallPath(buildXInfiniPath(vol.getSpec().getPoolId(), vol.getSpec().getId())); + return info; + } + + @Override + public List getActiveClients(String installPath, String protocol) { + if (VolumeProtocol.Vhost.toString().equals(protocol)) { + VolumeModule vol = apiHelper.queryVolumeById(getVolIdFromPath(installPath)); + if (vol == null) { + return Collections.emptyList(); + } + + List bdcBdevs = apiHelper.queryBdcBdevByVolumeId(vol.getSpec().getId()); + return bdcBdevs.stream().map(it -> { + ActiveVolumeClient c = new ActiveVolumeClient(); + if (CoreGlobalProperty.UNIT_TEST_ON) { + c.setManagerIp("127.0.0.1"); + } else { + c.setManagerIp(it.getSpec().getNodeIp()); + } + return c; + }).collect(Collectors.toList()); + } else if (VolumeProtocol.iSCSI.toString().equals(protocol)) { + VolumeModule vol = apiHelper.queryVolumeById(getVolIdFromPath(installPath)); + if (vol == null) { + return Collections.emptyList(); + } + + List mappings = apiHelper.queryVolumeClientMappingByVolId(vol.getSpec().getId()); + if (mappings.isEmpty()) { + return Collections.emptyList(); + } + + List clientIds = mappings.stream().map(it -> it.getSpec().getIscsiClientId()).collect(Collectors.toList()); + List clients = apiHelper.queryIscsiClientByIds(clientIds); + return clients.stream().map(it -> { + String clientIqn = it.getSpec().getCode(); + ActiveVolumeClient c = new ActiveVolumeClient(); + if (clientIqn.contains("iqn")) { + c.setQualifiedName(clientIqn); + c.setManagerIp(getHostMnIpFromInitiatorName(clientIqn)); + } else { + c.setManagerIp(clientIqn); + } + + return c; + }).collect(Collectors.toList()); + } else { + throw new OperationFailureException(operr("not supported protocol[%s] for active", protocol)); + } + } + + @Override + public List getActiveVolumesLocation(HostInventory h) { + return Collections.singletonList("file://" + PathUtil.join(getVhostSocketDir(), "volume-*")); + } + + @Override + public void deployClient(HostInventory h, Completion comp) { + comp.success(); + } + + @Override + public synchronized void activateHeartbeatVolume(HostInventory h, ReturnValueCompletion comp) { + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (clientIqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + VolumeModule heartbeatVol = apiHelper.queryVolumeByName(iscsiHeartbeatVolumeName); + if (heartbeatVol == null) { + long size = SizeUnit.GIGABYTE.toMegaByte(2); + heartbeatVol = apiHelper.createVolume(iscsiHeartbeatVolumeName, allocateFreePool(size).getSpec().getId(), size); + } + IscsiRemoteTarget target = createIscsiRemoteTarget(h.getManagementIp(), clientIqn, buildXInfiniPath(heartbeatVol.getSpec().getPoolId(), heartbeatVol.getSpec().getId())); + + IscsiHeartbeatVolumeTO to = new IscsiHeartbeatVolumeTO(); + to.setInstallPath(target.getResourceURI()); + to.setHostId(apiHelper.queryBdcByIp(h.getManagementIp()).getSpec().getId()); + to.setHeartbeatRequiredSpace(SizeUnit.MEGABYTE.toByte(1)); + to.setCoveringPaths(Collections.singletonList(getVhostSocketDir())); + comp.success(to); + } + + @Override + public void deactivateHeartbeatVolume(HostInventory h, Completion comp) { + VolumeModule heartbeatVol = apiHelper.queryVolumeByName(iscsiHeartbeatVolumeName); + if (heartbeatVol == null) { + comp.success(); + return; + } + + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + IscsiClientModule client = apiHelper.queryIscsiClientByIqn(clientIqn); + if (client == null) { + logger.info(String.format("cannot find client with code %s, skip deactive heartbeat volume", clientIqn)); + return; + } + + IscsiClientGroupModule group = apiHelper.getIscsiClientGroup(client.getSpec().getIscsiClientGroupId()); + VolumeClientGroupMappingModule map = apiHelper.queryVolumeClientGroupMappingByGroupIdAndVolId(group.getSpec().getId(), heartbeatVol.getSpec().getId()); + if (map == null) { + logger.info(String.format("vol %s not related to client group %s, skip deactive heartbeat volume", heartbeatVol.getSpec().getId(), group.getSpec().getId())); + return; + } + + retry(() -> apiHelper.deleteVolumeClientGroupMapping(map.getSpec().getId())); + } + + @Override + public HeartbeatVolumeTO getHeartbeatVolumeActiveInfo(HostInventory h) { + VolumeModule heartbeatVol = apiHelper.queryVolumeByName(iscsiHeartbeatVolumeName); + if (heartbeatVol == null) { + throw new RuntimeException("heartbeat volume not found"); + } + + String clientIqn = IscsiUtils.getHostInitiatorName(h.getUuid()); + if (clientIqn == null) { + throw new RuntimeException(String.format("cannot get host[uuid:%s] initiator name", h.getUuid())); + } + + IscsiHeartbeatVolumeTO to = new IscsiHeartbeatVolumeTO(); + IscsiRemoteTarget target = createIscsiRemoteTarget(h.getManagementIp(), clientIqn, buildXInfiniPath(heartbeatVol.getSpec().getPoolId(), heartbeatVol.getSpec().getId())); + to.setInstallPath(target.getResourceURI()); + to.setHostId(apiHelper.queryBdcByIp(h.getManagementIp()).getSpec().getId()); + to.setHeartbeatRequiredSpace(SizeUnit.MEGABYTE.toByte(1)); + to.setCoveringPaths(Collections.singletonList(getVhostSocketDir())); + return to; + } + + private VolumeModule getVolumeModule(BaseVolumeInfo vol) { + if (vol.getInstallPath() != null) { + int volId = getVolIdFromPath(vol.getInstallPath()); + return apiHelper.getVolume(volId); + } + + if ("image".equals(vol.getType())) { + return apiHelper.queryVolumeByName(buildImageName(vol.getUuid())); + } else { + return apiHelper.queryVolumeByName(buildVolumeName(vol.getUuid())); + } + } + + @Override + public String getIdentity() { + return XInfiniConstants.IDENTITY; + } + + @Override + public void ping(Completion completion) { + reloadDbInfo(); + Map nodesStatus = apiHelper.checkNodesConnection(config.getNodes()); + logger.info(String.format("get nodes status: %s", nodesStatus)); + + config.getNodes().forEach(it -> it.setStatus(nodesStatus.getOrDefault(it.getIp(), NodeStatus.Disconnected))); + SQL.New(ExternalPrimaryStorageVO.class).eq(ExternalPrimaryStorageVO_.uuid, self.getUuid()) + .set(ExternalPrimaryStorageVO_.config, JSONObjectUtil.toJsonString(config)) + .update(); + completion.success(); + } + + @Override + public void connect(String config, String url, ReturnValueCompletion comp) { + DebugUtils.Assert(StringUtils.isNotEmpty(config), "config cannot be none"); + XInfiniAddonInfo info = new XInfiniAddonInfo(); + XInfiniConfig xConfig = JSONObjectUtil.toObject(config, XInfiniConfig.class); + + List nodes = apiHelper.queryNodes(); + if (CollectionUtils.isEmpty(nodes)) { + comp.fail(operr("no node found")); + return; + } + + xConfig.getNodes().forEach(it -> nodes.stream() + .filter(it1 -> it1.getSpec().getAdminIp().equals(it.getIp()) && it1.getSpec().isRoleAfaAdmin()) + .findAny() + .orElseThrow(() -> new OperationFailureException(operr("fail to get node %s details, check ip address and role config", it.getIp())))); + info.setNodes(nodes.stream().map(XInfiniAddonInfo.Node::valueOf).collect(Collectors.toList())); + + List pools = apiHelper.queryPools(); + if (CollectionUtils.isEmpty(pools)) { + comp.fail(operr("no pool found")); + return; + } + + if (!CollectionUtils.isEmpty(xConfig.getPools())) { + xConfig.getPools().forEach(it -> pools.stream() + .filter(it1 -> it1.getSpec().getId() == it.getId()) + .findAny() + .orElseThrow(() -> new OperationFailureException(operr("fail to get pool[id:%d, name:%s] %s details", it.getId(), it.getName())))); + } + info.setPools(pools.stream().map(this::getPoolAddonInfo).collect(Collectors.toList())); + vhostSocketDir = String.format("/var/run/bdc-%s/", apiHelper.getClusterUuid()); + comp.success(JSONObjectUtil.rehashObject(info, LinkedHashMap.class)); + } + + private XInfiniAddonInfo.Pool getPoolAddonInfo(PoolModule pool) { + BsPolicyModule bsPolicy = apiHelper.getBsPolicy(pool.getSpec().getDefaultBsPolicyId()); + PoolCapacity capacity = apiHelper.getPoolCapacity(pool); + return XInfiniAddonInfo.Pool.valueOf(pool, bsPolicy, capacity); + } + + private void reloadDbInfo() { + self = dbf.reload(self); + addonInfo = StringUtils.isEmpty(self.getAddonInfo()) ? new XInfiniAddonInfo() : JSONObjectUtil.toObject(self.getAddonInfo(), XInfiniAddonInfo.class); + config = StringUtils.isEmpty(self.getConfig()) ? new XInfiniConfig() : JSONObjectUtil.toObject(self.getConfig(), XInfiniConfig.class); + } + + @Override + public void reportCapacity(ReturnValueCompletion comp) { + reloadDbInfo(); + List pools = refreshPoolCapacity() + .stream() + .filter(it -> config.getPoolIds().contains(it.getId())) + .collect(Collectors.toList()); + + long total = pools.stream().mapToLong(XInfiniAddonInfo.Pool::getTotalCapacity).sum(); + long avail = pools.stream().mapToLong(XInfiniAddonInfo.Pool::getAvailableCapacity).sum(); + StorageCapacity cap = new StorageCapacity(); + cap.setHealthy(getHealthy(getSelfPools())); + cap.setAvailableCapacity(avail); + cap.setTotalCapacity(total); + comp.success(cap); + } + + private List refreshPoolCapacity() { + addonInfo.setPools(apiHelper.queryPools().stream().map(this::getPoolAddonInfo).collect(Collectors.toList())); + SQL.New(ExternalPrimaryStorageVO.class).eq(ExternalPrimaryStorageVO_.uuid, self.getUuid()) + .set(ExternalPrimaryStorageVO_.addonInfo, JSONObjectUtil.toJsonString(addonInfo)) + .update(); + + return addonInfo.getPools(); + } + + private StorageHealthy getHealthy(List pools) { + if (pools.stream().allMatch(it -> it.getMetadata().getState().getState().equals(MetadataState.active.toString()))) { + return StorageHealthy.Ok; + } else if (pools.stream().noneMatch(it -> it.getMetadata().getState().getState().equals(MetadataState.active.toString()))) { + return StorageHealthy.Failed; + } else { + return StorageHealthy.Warn; + } + } + + @Override + public void reportHealthy(ReturnValueCompletion comp) { + self = dbf.reload(self); + addonInfo = JSONObjectUtil.toObject(self.getAddonInfo(), XInfiniAddonInfo.class); + config = JSONObjectUtil.toObject(self.getConfig(), XInfiniConfig.class); + + List pools = getSelfPools(); + comp.success(getHealthy(pools)); + } + + @Override + public void reportNodeHealthy(HostInventory host, ReturnValueCompletion comp) { + String hostProtocol = getProtocolByHypervisorType(host.getHypervisorType()); + NodeHealthy healthy = new NodeHealthy(); + if (VolumeProtocol.Vhost.toString().equals(hostProtocol)) { + setNodeHealthyByVhost(host, healthy); + } + + if (VolumeProtocol.iSCSI.toString().equals(hostProtocol)) { + setNodeHealthyByIscsi(host, healthy); + } + comp.success(healthy); + } + + private void setNodeHealthyByIscsi(HostInventory host, NodeHealthy healthy) { + VolumeProtocol protocol = VolumeProtocol.iSCSI; + IscsiClientModule client = apiHelper.queryIscsiClientByIqn(IscsiUtils.getHostInitiatorName(host.getUuid())); + if (client != null && client.getMetadata().getState().getState().equals(MetadataState.active.toString())) { + healthy.setHealthy(protocol, StorageHealthy.Ok); + } else { + healthy.setHealthy(protocol, StorageHealthy.Failed); + } + } + + private void setNodeHealthyByVhost(HostInventory host, NodeHealthy healthy) { + VolumeProtocol protocol = VolumeProtocol.Vhost; + BdcModule bdc = apiHelper.queryBdcByIp(host.getManagementIp()); + if (bdc.getStatus().getRunState().equals(BdcRunState.Active.toString())) { + healthy.setHealthy(protocol, StorageHealthy.Ok); + } else { + healthy.setHealthy(protocol, StorageHealthy.Failed); + } + } + + private String getProtocolByHypervisorType(String type) { + if (!KVMConstant.KVM_HYPERVISOR_TYPE.equals(type)) { + return VolumeProtocol.iSCSI.toString(); + } + return VolumeProtocol.Vhost.toString(); + } + + private List getSelfPools() { + Set configPoolIds = config.getPoolIds(); + + List pools = apiHelper.queryPools(); + pools.removeIf(it -> !configPoolIds.contains(it.getSpec().getId())); + return pools; + } + + private int getPoolId(String name) { + return addonInfo.getPools().stream().filter(it -> it.getName().equals(name)).findFirst() + .orElseThrow(() -> new RuntimeException(String.format("cannot find pool[name:%s]", name))).getId(); + } + + @Override + public StorageCapabilities reportCapabilities() { + return capabilities; + } + + @Override + public String allocateSpace(AllocateSpaceSpec aspec) { + PoolModule pool = allocateFreePool(aspec.getSize()); + if (pool == null) { + throw new OperationFailureException(operr("no available pool with enough space[%d] and healthy status", aspec.getSize())); + } + + return buildXInfiniPath(pool.getSpec().getId(), null); + } + + private PoolModule allocateFreePool(long size) { + List pools = getSelfPools(); + return pools.stream() + .filter(it -> { + PoolCapacity poolCapacity = apiHelper.getPoolCapacity(it); + return it.getMetadata().getState().getState().equals(MetadataState.active.toString()) && poolCapacity.getAvailableCapacity() > size;}) + .findAny() + .orElse(null); + } + + @Override + public void createVolume(CreateVolumeSpec v, ReturnValueCompletion comp) { + int poolId; + v.setSize(Math.max(v.getSize(), MIN_SIZE)); + + if (v.getAllocatedUrl() == null) { + PoolModule pool = allocateFreePool(v.getSize()); + if (pool == null) { + comp.fail(operr("no available pool with enough space[%d] and healthy status", v.getSize())); + return; + } + poolId = pool.getSpec().getId(); + } else { + poolId = getPoolIdFromPath(v.getAllocatedUrl()); + } + + VolumeModule volModule = apiHelper.createVolume(v.getName(), poolId, convertBytesToMegaBytes(v.getSize())); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildXInfiniPath(poolId, volModule.getSpec().getId())); + stats.setSize(SizeUnit.MEGABYTE.toByte(volModule.getSpec().getSizeMb())); + stats.setActualSize(volModule.getStatus().getAllocatedSizeByte()); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + stats.setRunStatus(volModule.getMetadata().getState().getState()); + comp.success(stats); + } + + private long convertBytesToMegaBytes(long bytes) { + if (bytes < 0) { + throw new IllegalArgumentException("Byte count cannot be negative"); + } + + return (long) Math.ceil(bytes / (1024.0 * 1024.0)); + } + + @Override + public void deleteVolume(String installPath, Completion comp) { + // xinfini must delete snapshot before deleting volume + deleteVolumeAndSnapshot(installPath, comp); + } + + @Override + public void deleteVolumeAndSnapshot(String installPath, Completion comp) { + int volId = getVolIdFromPath(installPath); + apiHelper.deleteVolumeAndSnapshot(volId); + comp.success(); + } + + @Override + public void trashVolume(String installPath, Completion comp) { + // xinfini not support trash yet + deleteVolume(installPath, comp); + } + + @Override + public void cloneVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletion comp) { + cloneVolume(srcInstallPath, dst, comp, false); + } + + private void cloneVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletion comp, boolean flatten) { + int snapId = getSnapIdFromPath(srcInstallPath); + VolumeModule vol = apiHelper.cloneVolume(snapId, dst.getName(), null, flatten, XinfiniVolumeQos.valueOf(dst.getQos())); + + if (SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb()) < dst.getSize()) { + vol = apiHelper.expandVolume(vol.getSpec().getId(), convertBytesToMegaBytes(dst.getSize())); + } + + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildXInfiniPath(getPoolIdFromPath(srcInstallPath), vol.getSpec().getId())); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + stats.setSize(SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb())); + stats.setActualSize(vol.getStatus().getAllocatedSizeByte()); + stats.setParentUri(srcInstallPath); + comp.success(stats); + } + + @Override + public void copyVolume(String srcInstallPath, CreateVolumeSpec dst, ReturnValueCompletion comp) { + cloneVolume(srcInstallPath, dst, comp, true); + } + + @Override + public void flattenVolume(String installPath, ReturnValueCompletion comp) { + VolumeModule vol = apiHelper.getVolume(getVolIdFromPath(installPath)); + if (vol.getSpec().getBsSnapId() == 0) { + logger.info(String.format("volume[%s] has no related snapshot, no need to flatten", installPath)); + } else { + vol = apiHelper.flattenVolume(getVolIdFromPath(installPath)); + } + + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(installPath); + stats.setSize(SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb())); + stats.setActualSize(vol.getStatus().getAllocatedSizeByte()); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + comp.success(stats); + } + + @Override + public void stats(String installPath, ReturnValueCompletion comp) { + VolumeModule vol = apiHelper.getVolume(getVolIdFromPath(installPath)); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(installPath); + stats.setSize(SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb())); + stats.setActualSize(vol.getStatus().getAllocatedSizeByte()); + stats.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + stats.setParentUri(getParentUri(vol)); + comp.success(stats); + } + + private String getParentUri(VolumeModule vol) { + if (vol.getSpec().getBsSnapId() == 0) { + return null; + } + + VolumeSnapshotModule vss = apiHelper.getVolumeSnapshot(vol.getSpec().getBsSnapId()); + return buildXInfiniSnapshotPath(vss.getSpec().getPoolId(), vss.getSpec().getBsVolumeId(), vss.getSpec().getId()); + } + + @Override + public void batchStats(Collection installPath, ReturnValueCompletion> comp) { + List stats = installPath.stream().map(it -> { + VolumeModule vol = apiHelper.getVolume(getVolIdFromPath(it)); + VolumeStats s = new VolumeStats(); + s.setInstallPath(it); + s.setSize(SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb())); + s.setActualSize(vol.getStatus().getAllocatedSizeByte()); + s.setFormat(VolumeConstant.VOLUME_FORMAT_RAW); + return s; + }).collect(Collectors.toList()); + comp.success(stats); + } + + @Override + public void expandVolume(String installPath, long size, ReturnValueCompletion comp) { + int id = getVolIdFromPath(installPath); + + VolumeModule vol = apiHelper.expandVolume(id, convertBytesToMegaBytes(size)); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(installPath); + stats.setSize(SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb())); + comp.success(stats); + } + + @Override + public void setVolumeQos(BaseVolumeInfo v, Completion comp) { + if (v.getQos() == null) { + comp.success(); + return; + } + + if ((v.getQos().getReadBandwidth() != null && v.getQos().getReadBandwidth() > 0) + || (v.getQos().getWriteBandwidth() != null && v.getQos().getWriteBandwidth() > 0) + || (v.getQos().getReadIOPS() != null && v.getQos().getReadIOPS() > 0) + || v.getQos().getWriteIOPS() != null && v.getQos().getWriteIOPS() > 0) { + throw new OperationFailureException(operr("xinfini only support set total qos")); + } + + apiHelper.setVolumeQos(getVolIdFromPath(v.getInstallPath()), XinfiniVolumeQos.valueOf(v.getQos())); + comp.success(); + } + + @Override + public void deleteVolumeQos(BaseVolumeInfo v, Completion comp) { + apiHelper.deleteVolumeQos(getVolIdFromPath(v.getInstallPath())); + comp.success(); + } + + @Override + public void export(ExportSpec espec, VolumeProtocol protocol, ReturnValueCompletion comp) { + if (protocol == VolumeProtocol.NVMEoF) { + // TODO + comp.fail(operr("not support export nvmeof yet")); + } else if (protocol == VolumeProtocol.iSCSI) { + IscsiRemoteTarget target = exportIscsi(espec); + comp.success(target); + } else { + throw new RuntimeException("unsupport target " + protocol.name()); + } + } + + + synchronized IscsiRemoteTarget exportIscsi(ExportSpec espec) { + return createIscsiRemoteTarget(espec.getClientMnIp(), espec.getClientQualifiedName(), espec.getInstallPath()); + } + + private VolumeModule cloneVolumeIfNotExist(int snapId, String dstVolumeName) { + VolumeModule vol = apiHelper.queryVolumeByNameAndSnapId(dstVolumeName, snapId); + if (vol != null) { + return vol; + } + vol = apiHelper.cloneVolume(snapId, dstVolumeName, null, false, null); + return vol; + } + + private IscsiRemoteTarget createIscsiRemoteTarget(String clientIp, String clientIqn, String installPath) { + int volId; + if (installPath.contains("@")) { + int snapId = getSnapIdFromPath(installPath); + VolumeModule vol = cloneVolumeIfNotExist(snapId, buildSnapshotExportVolumeName(snapId)); + volId = vol.getSpec().getId(); + } else { + volId = getVolIdFromPath(installPath); + } + IscsiClientGroupModule group; + IscsiClientModule clientModule; + clientModule = apiHelper.queryIscsiClientByIqn(clientIqn); + if (clientModule != null) { + group = apiHelper.getIscsiClientGroup(clientModule.getSpec().getIscsiClientGroupId()); + logger.info(String.format("iscsi client[code:%s] exist, use related client group[name:%s]", + clientModule.getSpec().getCode(), group.getSpec().getName())); + } else { + // create group and client together + List iscsiGateways = apiHelper.queryIscsiGateways(); + List gatewayIds = iscsiGateways.stream() + .map(IscsiGatewayModule::getSpec) + .map(IscsiGatewayModule.IscsiGatewaySpec::getId) + .collect(Collectors.toList()); + + group = apiHelper.createIscsiClientGroup(buildIscsiClientGroupName(clientIp), gatewayIds, Collections.singletonList(clientIqn)); + } + + apiHelper.addVolumeClientGroupMapping(volId, group.getSpec().getId()); + List mappings = apiHelper.queryIscsiGatewayClientGroupMappingByGroupId(group.getSpec().getId()); + List gatewayIds = mappings.stream() + .map(IscsiGatewayClientGroupMappingModule::getSpec) + .map(IscsiGatewayClientGroupMappingModule.IscsiGatewayClientGroupMappingSpec::getIscsiGatewayId) + .collect(Collectors.toList()); + List groupRelatedGateways = apiHelper.queryIscsiGatewaysByIds(gatewayIds) + .stream() + .filter(v -> IscsiNodeState.ACTIVE.toString().equals(v.getStatus().getNodeState())) + .collect(Collectors.toList()); + + if (groupRelatedGateways.isEmpty()) { + throw new OperationFailureException(operr("no active gateway found for client[%s]", clientIqn)); + } + + // refresh client + clientModule = apiHelper.queryIscsiClientByIqn(clientIqn); + + IscsiRemoteTarget target = new IscsiRemoteTarget(); + target.setPort(groupRelatedGateways.get(0).getSpec().getPort()); + target.setTransport("tcp"); + target.setIqn(clientModule.getStatus().getTargetIqns().get(0)); + target.setIp(groupRelatedGateways.stream().map(it -> it.getSpec().getIps().get(0)).collect(Collectors.joining(","))); + target.setDiskId(apiHelper.getVolume(volId).getSpec().getSerial()); + target.setDiskIdType(IscsiRemoteTarget.DiskIdType.serial.toString()); + return target; + } + + @Override + public void unexport(ExportSpec espec, RemoteTarget remoteTarget, VolumeProtocol protocol, Completion comp) { + if (protocol == VolumeProtocol.NVMEoF) { + comp.fail(operr("not support unexport nvmeof yet")); + } else if (protocol == VolumeProtocol.iSCSI) { + unexportIscsi(espec.getInstallPath(), espec.getClientQualifiedName()); + } else { + comp.fail(operr("unsupported protocol %s", protocol.name())); + return; + } + comp.success(); + } + + private synchronized void unexportIscsi(String source, String clientIqn) { + int volId; + if (source.contains("@")) { + int snapId = getSnapIdFromPath(source); + VolumeModule vol = apiHelper.queryVolumeByNameAndSnapId(buildSnapshotExportVolumeName(snapId), snapId); + if (vol == null) { + return; + } + + volId = vol.getSpec().getId(); + } else { + volId = getVolIdFromPath(source); + } + + IscsiClientModule clientModule = apiHelper.queryIscsiClientByIqn(clientIqn); + if (clientModule == null) { + return; + } + + VolumeClientGroupMappingModule mapping = apiHelper.queryVolumeClientGroupMappingByGroupIdAndVolId(clientModule.getSpec().getIscsiClientGroupId(), volId); + if (mapping == null) { + return; + } + + retry(() -> apiHelper.deleteVolumeClientGroupMapping(mapping.getSpec().getId())); + + if (source.contains("@")) { + apiHelper.deleteVolume(volId, true); + } + } + + @Override + public void createSnapshot(CreateVolumeSnapshotSpec spec, ReturnValueCompletion comp) { + VolumeSnapshotModule snapshot = apiHelper.createVolumeSnapshot(getVolIdFromPath(spec.getVolumeInstallPath()), spec.getName()); + VolumeSnapshotStats stats = new VolumeSnapshotStats(); + stats.setInstallPath(buildXInfiniSnapshotPath(spec.getVolumeInstallPath(), snapshot.getSpec().getId())); + stats.setActualSize(SizeUnit.MEGABYTE.toByte(snapshot.getSpec().getSizeMb())); + comp.success(stats); + } + + @Override + public void deleteSnapshot(String installPath, Completion comp) { + apiHelper.deleteVolumeSnapshot(getSnapIdFromPath(installPath)); + comp.success(); + } + + @Override + public void expungeSnapshot(String installPath, Completion comp) { + deleteSnapshot(installPath, comp); + } + + @Override + public void revertVolumeSnapshot(String snapshotInstallPath, ReturnValueCompletion comp) { + int volId = getVolIdFromPath(snapshotInstallPath); + int snapId = getSnapIdFromPath(snapshotInstallPath); + VolumeModule vol = apiHelper.rollbackSnapshot(volId, snapId); + VolumeStats stats = new VolumeStats(); + stats.setInstallPath(buildXInfiniPath(vol.getSpec().getPoolId(), vol.getSpec().getId())); + stats.setSize(SizeUnit.MEGABYTE.toByte(vol.getSpec().getSizeMb())); + stats.setActualSize(vol.getStatus().getAllocatedSizeByte()); + comp.success(stats); + } + + @Override + public void validateConfig(String config) { + + } + + @Override + public void setTrashExpireTime(int timeInSeconds, Completion completion) { + //TODO + completion.success(); + } + + @Override + public void onFirstAdditionConfigure(Completion completion) { + completion.success(); + } + + @Override + public long alignSize(long size) { + return SizeUnit.MEGABYTE.toByte(convertBytesToMegaBytes(size)); + } + + public void cleanActiveRecord(VolumeInventory vol) { + + } + private void retry(Runnable r) { + retry(r, 3); + } + + + private void retry(Runnable r, int retry) { + while (retry-- > 0) { + try { + r.run(); + return; + } catch (Exception e) { + logger.warn("runnable failed, try ", e); + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException ignore) {} + } + } + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniStorageFactory.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniStorageFactory.java new file mode 100644 index 00000000000..4faa1988e18 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniStorageFactory.java @@ -0,0 +1,74 @@ +package org.zstack.xinfini; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.zstack.externalStorage.primary.ExternalStorageFencerType; +import org.zstack.header.core.ReturnValueCompletion; +import org.zstack.header.storage.addon.primary.*; +import org.zstack.header.volume.VolumeAfterExpungeExtensionPoint; +import org.zstack.header.volume.VolumeInventory; +import org.zstack.header.volume.VolumeProtocol; +import org.zstack.header.xinfini.XInfiniConstants; +import org.zstack.storage.addon.primary.ExternalPrimaryStorageFactory; + +import java.util.LinkedHashMap; +import java.util.List; + +import static org.zstack.core.Platform.operr; + +public class XInfiniStorageFactory implements ExternalPrimaryStorageSvcBuilder, BackupStorageSelector, VolumeAfterExpungeExtensionPoint { + + public static final ExternalStorageFencerType fencerType = new ExternalStorageFencerType(XInfiniConstants.IDENTITY, VolumeProtocol.iSCSI.toString()); + + private List preferBackupStorageTypes; + + @Autowired + private ExternalPrimaryStorageFactory extPsFactory; + + @Override + public PrimaryStorageControllerSvc buildControllerSvc(ExternalPrimaryStorageVO vo) { + return new XInfiniStorageController(vo); + } + + @Override + public PrimaryStorageNodeSvc buildNodeSvc(ExternalPrimaryStorageVO vo) { + return new XInfiniStorageController(vo); + } + + @Override + public void discover(String url, String config, ReturnValueCompletion completion) { + // xinfini must set config + if (StringUtils.isEmpty(config)) { + completion.fail(operr("empty config, cannot discover xinfini")); + return; + } + + XInfiniStorageController controller = new XInfiniStorageController(config); + controller.connect(config, url, completion); + } + + @Override + public String getIdentity() { + return XInfiniConstants.IDENTITY; + } + + @Override + public List getPreferBackupStorageTypes() { + return preferBackupStorageTypes; + } + + public void setPreferBackupStorageTypes(List preferBackupStorageTypes) { + this.preferBackupStorageTypes = preferBackupStorageTypes; + } + + // TODO: hard code for less http call. + @Override + public void volumeAfterExpunge(VolumeInventory volume) { + if (volume.getInstallPath() == null || !volume.getInstallPath().startsWith("xinfini://")) { + return; + } + + PrimaryStorageControllerSvc controller = extPsFactory.getControllerSvc(volume.getPrimaryStorageUuid()); + ((XInfiniStorageController) controller).cleanActiveRecord(volume); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniTimeUtil.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniTimeUtil.java new file mode 100644 index 00000000000..05d10018dfe --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/XInfiniTimeUtil.java @@ -0,0 +1,14 @@ +package org.zstack.xinfini; + +import java.sql.Timestamp; +import java.time.OffsetDateTime; + +/** + * @ Author : yh.w + * @ Date : Created in 11:42 2024/5/29 + */ +public class XInfiniTimeUtil { + public static Timestamp translateToTimeStamp(String time) { + return Timestamp.from(OffsetDateTime.parse(time).toInstant()); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseResource.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseResource.java new file mode 100644 index 00000000000..84a8a349a4f --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseResource.java @@ -0,0 +1,59 @@ +package org.zstack.xinfini.sdk; + +/** + * @ Author : yh.w + * @ Date : Created in 18:10 2024/5/27 + */ +public class BaseResource { + private Metadata metadata; + + public Metadata getMetadata() { + return metadata; + } + + public void setMetadata(Metadata metadata) { + this.metadata = metadata; + } + + public static class Metadata { + private int id; + private String name; + private State state; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public static class State { + private String state; + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + } + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseSpec.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseSpec.java new file mode 100644 index 00000000000..d2c5ebf17b4 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseSpec.java @@ -0,0 +1,125 @@ +package org.zstack.xinfini.sdk; + +/** + * @ Author : yh.w + * @ Date : Created in 11:41 2024/5/28 + */ +public class BaseSpec { + private int id; + private String etag; + private String name; + private String description; + private String uuid; + private String creator; + private String createdAt; + private String updatedAt; + private String deletedAt; + private String creationFinish; + private String deletionBegin; + private String deletionFinish; + private String creationTimeoutAt; + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getCreationTimeoutAt() { + return creationTimeoutAt; + } + + public void setCreationTimeoutAt(String creationTimeoutAt) { + this.creationTimeoutAt = creationTimeoutAt; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getEtag() { + return etag; + } + + public void setEtag(String etag) { + this.etag = etag; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + public String getDeletedAt() { + return deletedAt; + } + + public void setDeletedAt(String deletedAt) { + this.deletedAt = deletedAt; + } + + public String getCreationFinish() { + return creationFinish; + } + + public void setCreationFinish(String creationFinish) { + this.creationFinish = creationFinish; + } + + public String getDeletionBegin() { + return deletionBegin; + } + + public void setDeletionBegin(String deletionBegin) { + this.deletionBegin = deletionBegin; + } + + public String getDeletionFinish() { + return deletionFinish; + } + + public void setDeletionFinish(String deletionFinish) { + this.deletionFinish = deletionFinish; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseStatus.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseStatus.java new file mode 100644 index 00000000000..be588d574b0 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/BaseStatus.java @@ -0,0 +1,62 @@ +package org.zstack.xinfini.sdk; + +/** + * @ Author : yh.w + * @ Date : Created in 11:43 2024/5/28 + */ +public class BaseStatus { + private int id; + private String createdAt; + private String updatedAt; + private String creationTimeoutAt; + private String deletedAt; + private String etag; + + public String getCreationTimeoutAt() { + return creationTimeoutAt; + } + + public void setCreationTimeoutAt(String creationTimeoutAt) { + this.creationTimeoutAt = creationTimeoutAt; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public String getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(String updatedAt) { + this.updatedAt = updatedAt; + } + + public String getDeletedAt() { + return deletedAt; + } + + public void setDeletedAt(String deletedAt) { + this.deletedAt = deletedAt; + } + + public String getEtag() { + return etag; + } + + public void setEtag(String etag) { + this.etag = etag; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/MetadataState.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/MetadataState.java new file mode 100644 index 00000000000..4215709c199 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/MetadataState.java @@ -0,0 +1,8 @@ +package org.zstack.xinfini.sdk; + +public enum MetadataState { + active, + creating, + deleting, + reconciling, +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniApiCompletion.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniApiCompletion.java new file mode 100644 index 00000000000..876a66b1449 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniApiCompletion.java @@ -0,0 +1,5 @@ +package org.zstack.xinfini.sdk; + +public interface XInfiniApiCompletion { + void complete(XinfiniApiResult result); +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniApiException.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniApiException.java new file mode 100644 index 00000000000..036477e7b83 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniApiException.java @@ -0,0 +1,11 @@ +package org.zstack.xinfini.sdk; + +public class XInfiniApiException extends RuntimeException { + public XInfiniApiException(String format) { + super(format); + } + + public XInfiniApiException(Exception e) { + super(e); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniClient.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniClient.java new file mode 100644 index 00000000000..8b486289dc7 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniClient.java @@ -0,0 +1,395 @@ +package org.zstack.xinfini.sdk; + +import com.google.common.base.CaseFormat; +import okhttp3.*; +import org.apache.commons.lang.StringEscapeUtils; +import org.springframework.http.HttpMethod; +import org.zstack.core.Platform; +import org.zstack.externalStorage.sdk.ExternalStorageApiClient; +import org.zstack.externalStorage.sdk.ExternalStorageParam; +import org.zstack.header.rest.DefaultSSLVerifier; +import org.zstack.header.xinfini.XInfiniConstants; +import org.zstack.utils.Utils; +import org.zstack.utils.gson.JSONObjectUtil; +import org.zstack.utils.logging.CLogger; +import org.zstack.xinfini.NodeStatus; +import org.zstack.xinfini.XInfiniConfig; +import org.zstack.xinfini.sdk.volume.FlattenVolumeRequest; + +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.X509TrustManager; +import java.io.EOFException; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class XInfiniClient extends ExternalStorageApiClient { + private static final CLogger logger = Utils.getLogger(XInfiniClient.class); + + private final List validHttpStatus = Arrays.asList(200, 201, 202, 404); + private XInfiniConnectConfig config; + + public XInfiniConnectConfig getConfig() { + return config; + } + + public void configure(XInfiniConnectConfig c) { + config = c; + + if (c.readTimeout != null || c.writeTimeout != null) { + OkHttpClient.Builder b = new OkHttpClient.Builder(); + + if (c.readTimeout != null) { + b.readTimeout(c.readTimeout, TimeUnit.MILLISECONDS); + } + if (c.writeTimeout != null) { + b.writeTimeout(c.writeTimeout, TimeUnit.MILLISECONDS); + } + + SSLSocketFactory factory = DefaultSSLVerifier.getSSLFactory(DefaultSSLVerifier.trustAllCerts); + if (factory != null) { + http = b.sslSocketFactory(factory, (X509TrustManager) DefaultSSLVerifier.trustAllCerts[0]) + .hostnameVerifier(DefaultSSLVerifier::verify) + .followRedirects(true) + .followSslRedirects(true) + .build(); + } else { + http = b.followRedirects(true) + .followSslRedirects(true) + .build(); + } + } + } + + public T call(XInfiniRequest req, Class clz, XInfiniConfig.Node node) { + errorIfNotConfigured(); + XinfiniApiResult ret = new Api(req).callWithNode(node); + + if (ret.getMessage() != null) { + XInfiniResponse rsp = new XInfiniResponse(); + rsp.setReturnCode(ret.getReturnCode()); + rsp.setMessage(ret.getMessage()); + return JSONObjectUtil.rehashObject(rsp, clz); + } + + return ret.getResult(clz); + } + + public T call(XInfiniRequest req, Class clz) { + return call(req, clz, null); + } + + public void call(XInfiniRequest req, XInfiniApiCompletion completion) { + errorIfNotConfigured(); + new Api(req).call(completion); + } + + class Api { + XInfiniRequest action; + XInfiniRestRequest restInfo; + + XInfiniApiCompletion completion; + + final String taskIdForLog = Platform.getUuid(); + String reqBody; // for log + + Api(XInfiniRequest action) { + this.action = action; + this.restInfo = action.getClass().getAnnotation(XInfiniRestRequest.class); + } + + private List getVarNamesFromUrl(String url) { + Pattern pattern = Pattern.compile("\\{(.+?)\\}"); + Matcher matcher = pattern.matcher(url); + + List urlVars = new ArrayList<>(); + while (matcher.find()) { + urlVars.add(matcher.group(1)); + } + + return urlVars; + } + + class WrappedRequest { + private Map spec; + + public WrappedRequest(Map spec) { + this.spec = spec; + } + + public Map getSpec() { + return spec; + } + + public void setSpec(Map spec) { + this.spec = spec; + } + } + + XinfiniApiResult doCall() { + return doCallWithNode(null); + } + + XinfiniApiResult doCallWithNode(XInfiniConfig.Node withNode) { + XInfiniConfig.Node node; + Request.Builder reqBuilder = new Request.Builder(); + action.checkParameters(); + if (withNode != null) { + node = withNode; + } else { + node = config.xInfiniConfig + .getNodes() + .stream() + .filter(it -> it.getStatus() == NodeStatus.Connected) + .findAny() + .orElseThrow(() -> new XInfiniApiException("No connected node found")); + } + + try { + if (action instanceof XInfiniQueryRequest) { + fillQueryApiRequestBuilder(reqBuilder, node); + } else { + fillNonQueryApiRequestBuilder(reqBuilder, node); + } + } catch (Exception e) { + throw new XInfiniApiException(e); + } + + Request request = reqBuilder.build(); + + int retryCount = 0; + while (retryCount <= 2) { + try { + logger.debug(String.format("call request[%s: %s]: %s, body: %s", action.getClass().getSimpleName(), taskIdForLog, request, reqBody)); + try (Response response = http.newCall(request).execute()) { + if (!response.isSuccessful()) { + if (response.body() == null) { + return httpError(response.code(), null); + } else { + return httpError(response.code(), response.body().string()); + } + } + + if (!validHttpStatus.contains(response.code())) { + throw new XInfiniApiException(String.format("[Internal Error] the server returns an unknown status code[%s]", response.code())); + } + + return writeApiResult(response); + } + } catch (IOException e) { + if (isEOFException(e) && retryCount < 1) { + retryCount++; + try { + TimeUnit.SECONDS.sleep(3); + } catch (InterruptedException ex) { + logger.warn("EOFException sleep failed"); + } + continue; + } + throw new XInfiniApiException(e); + } + } + throw new XInfiniApiException("Max retry attempts reached"); + } + + private boolean isEOFException(IOException e) { + // only retry on query api + if (!(action instanceof XInfiniQueryRequest)) { + return false; + } + + return e instanceof EOFException || + (e.getMessage() != null && e.getMessage().contains("EOF")); + } + + private void fillQueryApiRequestBuilder(Request.Builder reqBuilder, XInfiniConfig.Node node) throws Exception { + XInfiniQueryRequest qaction = (XInfiniQueryRequest) action; + + HttpUrl.Builder urlBuilder = new HttpUrl.Builder().scheme("http") + .host(node.getIp()) + .port(node.getPort()); + + urlBuilder.addPathSegments(restInfo.category().toString()); + urlBuilder.addPathSegment(restInfo.version()); + urlBuilder.addPathSegments(restInfo.path().replaceFirst("/", "")); + if (qaction.q != null) { + urlBuilder.addQueryParameter("q", String.format("%s", qaction.q)); + } + if (qaction.metric != null) { + urlBuilder.addQueryParameter("metric", String.format("%s", qaction.metric)); + } + if (qaction.lables != null) { + urlBuilder.addQueryParameter("labels", String.format("%s", qaction.lables)); + } + if (qaction.limit != null) { + urlBuilder.addQueryParameter("limit", String.format("%s", qaction.limit)); + } + if (qaction.offset != null) { + urlBuilder.addQueryParameter("index", String.format("%s", qaction.offset)); + } + if (qaction.sortBy != null) { + urlBuilder.addQueryParameter("sort", String.format("%s", qaction.sortBy)); + } + + reqBuilder.addHeader(XInfiniConstants.HEADER_TOKEN, config.token); + + reqBuilder.url(urlBuilder.build()).get(); + } + + private String substituteUrl(String url, Map tokens) { + Pattern pattern = Pattern.compile("\\{(.+?)\\}"); + Matcher matcher = pattern.matcher(url); + StringBuffer buffer = new StringBuffer(); + while (matcher.find()) { + String varName = matcher.group(1); + Object replacement = tokens.get(varName); + if (replacement == null) { + throw new XInfiniApiException(String.format("cannot find value for URL variable[%s]", varName)); + } + + matcher.appendReplacement(buffer, ""); + buffer.append(replacement.toString()); + } + + matcher.appendTail(buffer); + return buffer.toString(); + } + + private void fillNonQueryApiRequestBuilder(Request.Builder reqBuilder, XInfiniConfig.Node node) throws Exception { + HttpUrl.Builder builder = new HttpUrl.Builder() + .scheme("http") + .host(node.getIp()) + .port(node.getPort()); + builder.addPathSegments(restInfo.category().toString()); + builder.addPathSegment(restInfo.version()); + + List varNames = getVarNamesFromUrl(restInfo.path()); + String path = restInfo.path(); + if (!varNames.isEmpty()) { + Map vars = new HashMap<>(); + for (String vname : varNames) { + Object value = action.getParameterValue(vname); + + if (value == null) { + throw new XInfiniApiException(String.format("missing required field[%s]", vname)); + } + + vars.put(vname, value); + } + + path = substituteUrl(path, vars); + builder.addPathSegments(path.replaceFirst("/", "")); + } else { + builder.addPathSegments(path.replaceFirst("/", "")); + } + + final Map params = new HashMap<>(); + final Map queryableParams = new HashMap<>(); + + for (String pname : action.getAllParameterNames()) { + if (varNames.contains(pname)) { + // the field is set in URL variables + continue; + } + + Object value = action.getParameterValue(pname); + if (value == null) { + continue; + } + + if (action.isQueryableParam(pname)) { + queryableParams.put(pname, value.toString()); + } else { + params.put(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pname), value); + } + } + + if (restInfo.method().equals(HttpMethod.GET)) { + reqBuilder.url(builder.build()).get(); + } else if (restInfo.method().equals(HttpMethod.DELETE) && !restInfo.hasBody()) { + params.forEach((k, v) -> builder.addQueryParameter(k, v.toString())); + reqBuilder.url(builder.build()).delete(); + } else if (!queryableParams.isEmpty()) { + for (Map.Entry entry : queryableParams.entrySet()) { + builder.addQueryParameter(entry.getKey(), entry.getValue()); + } + reqBody = gson.toJson(new WrappedRequest(params)); + reqBuilder.url(builder.build()).method(restInfo.method().toString(), RequestBody.create(XInfiniConstants.JSON, reqBody)); + } else { + reqBody = gson.toJson(new WrappedRequest(params)); + reqBuilder.url(builder.build()).method(restInfo.method().toString(), RequestBody.create(XInfiniConstants.JSON, reqBody)); + } + + reqBuilder.addHeader(XInfiniConstants.HEADER_TOKEN, config.token); + } + + private XinfiniApiResult writeApiResult(Response response) throws IOException { + XinfiniApiResult res = new XinfiniApiResult(); + + if (validHttpStatus.contains(response.code())) { + res.setReturnCode(response.code()); + String body = response.body().string(); + XInfiniResponse rsp = gson.fromJson(body, XInfiniResponse.class); + if (rsp.isSuccess()) { + res.setResultString(body); + } else { + res.setMessage(StringEscapeUtils.unescapeJava(rsp.getMessage())); + } + } else { + throw new XInfiniApiException(String.format("unknown status code: %s", response.code())); + } + return res; + } + + private XinfiniApiResult httpError(int code, String details) { + XinfiniApiResult res = new XinfiniApiResult(); + res.setReturnCode(code); + if (details != null && details.startsWith("{")) { + XInfiniResponse rsp = gson.fromJson(details, XInfiniResponse.class); + if (rsp.getMessage() != null) { + res.setMessage(StringEscapeUtils.unescapeJava(rsp.getMessage())); + return res; + } + } + + res.setMessage(String.format("the http status code[%s] details[%s] indicates a failure happened", code, details)); + return res; + } + + XinfiniApiResult callWithNode(XInfiniConfig.Node node) { + XinfiniApiResult ret = doCallWithNode(node); + if (ret.getMessage() != null) { + logger.debug(String.format("request[%s: %s] error: %s result: %s code: %s", action.getClass().getSimpleName(), + taskIdForLog, gson.toJson(ret.getMessage()), ret.getResultString(), ret.getReturnCode())); + } else { + logger.debug(String.format("request[%s: %s] result: %s", action.getClass().getSimpleName(), + taskIdForLog, ret.getResultString())); + } + return ret; + } + + void call(XInfiniApiCompletion completion) { + this.completion = completion; + XinfiniApiResult res = doCall(); + if (res != null) { + completion.complete(res); + } + } + + private long getTimeout() { + return action.timeout == ACTION_DEFAULT_TIMEOUT ? config.getDefaultPollingTimeout(): action.timeout; + } + + private long getInterval(){ + return config.getDefaultPollingInterval(); + } + } + + private void errorIfNotConfigured() { + if (config == null) { + throw new RuntimeException("setConfig() must be called before any methods"); + } + } +} \ No newline at end of file diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniConnectConfig.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniConnectConfig.java new file mode 100644 index 00000000000..43668787513 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniConnectConfig.java @@ -0,0 +1,40 @@ +package org.zstack.xinfini.sdk; + +import org.zstack.xinfini.XInfiniConfig; + +import java.util.concurrent.TimeUnit; + +public class XInfiniConnectConfig { + public String hostname = "localhost"; + public int port = 443; + long defaultPollingTimeout = TimeUnit.HOURS.toMillis(3); + long defaultPollingInterval = TimeUnit.SECONDS.toMillis(1); + public Long readTimeout; + public Long writeTimeout; + public String token; + public XInfiniConfig xInfiniConfig; + + public void setPort(int port) { + this.port = port; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getHostname() { + return hostname; + } + + public int getPort() { + return port; + } + + public long getDefaultPollingTimeout() { + return defaultPollingTimeout; + } + + public long getDefaultPollingInterval() { + return defaultPollingInterval; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniParam.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniParam.java new file mode 100644 index 00000000000..d8a5fc583c1 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniParam.java @@ -0,0 +1,7 @@ +package org.zstack.xinfini.sdk; + +import org.zstack.externalStorage.sdk.ExternalStorageParam; + +public interface XInfiniParam extends ExternalStorageParam { + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQuery.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQuery.java new file mode 100644 index 00000000000..4a012878d5b --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQuery.java @@ -0,0 +1,14 @@ +package org.zstack.xinfini.sdk; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface XInfiniQuery { + Class replyClass(); + + Class inventoryClass(); +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQueryRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQueryRequest.java new file mode 100644 index 00000000000..85a6ee3003a --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQueryRequest.java @@ -0,0 +1,16 @@ +package org.zstack.xinfini.sdk; + +/** + * {"q": "((spec.name:~\".*1.*\") AND (spec.description:~\".*1.*\"))", + * "sort": "spec.created_at:asc", + * "limit": 100, + * "offset": 0} + */ +public abstract class XInfiniQueryRequest extends XInfiniRequest { + public String q; + public Long limit; + public Long offset; + public String sortBy; + public String metric; + public String lables; +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQueryResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQueryResponse.java new file mode 100644 index 00000000000..7fc47723456 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniQueryResponse.java @@ -0,0 +1,64 @@ +package org.zstack.xinfini.sdk; + +public class XInfiniQueryResponse extends XInfiniResponse { + private QueryResponseMetadata metadata; + + public QueryResponseMetadata getMetadata() { + return metadata; + } + + public void setMetadata(QueryResponseMetadata metadata) { + this.metadata = metadata; + } + + public static class QueryResponseMetadata { + private Pagination pagination; + + public Pagination getPagination() { + return pagination; + } + + public void setPagination(Pagination pagination) { + this.pagination = pagination; + } + + public static class Pagination { + protected long totalCount; + protected long count; + protected int offset; + protected int limit; + + public long getTotalCount() { + return totalCount; + } + + public void setTotalCount(long totalCount) { + this.totalCount = totalCount; + } + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } + } + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniRequest.java new file mode 100644 index 00000000000..534fbf6d2cd --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniRequest.java @@ -0,0 +1,8 @@ +package org.zstack.xinfini.sdk; + +/** + * Created by xing5 on 2016/12/9. + */ +public abstract class XInfiniRequest implements XInfiniParam { + long timeout = -1; +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniResponse.java new file mode 100644 index 00000000000..dd24e94ec9e --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniResponse.java @@ -0,0 +1,39 @@ +package org.zstack.xinfini.sdk; + +import org.apache.commons.lang.StringUtils; +import org.zstack.header.errorcode.ErrorCode; + +import static org.zstack.core.Platform.operr; + +public class XInfiniResponse { + protected String message; + protected int returnCode; + + public int getReturnCode() { + return returnCode; + } + + public void setReturnCode(int returnCode) { + this.returnCode = returnCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return StringUtils.isEmpty(message); + } + + public ErrorCode getError() { + return operr(message); + } + + public boolean resourceIsDeleted() { + return returnCode == 404; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniRestRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniRestRequest.java new file mode 100644 index 00000000000..576f3c019a6 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XInfiniRestRequest.java @@ -0,0 +1,18 @@ +package org.zstack.xinfini.sdk; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface XInfiniRestRequest { + String path(); + HttpMethod method(); + Class responseClass(); + XInfiniApiCategory category(); + String version() default "v1"; + boolean sync() default true; + boolean hasBody() default false; +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XinfiniApiResult.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XinfiniApiResult.java new file mode 100644 index 00000000000..a3304c22667 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/XinfiniApiResult.java @@ -0,0 +1,116 @@ +package org.zstack.xinfini.sdk; + +import org.apache.commons.beanutils.PropertyUtils; +import org.zstack.header.errorcode.OperationFailureException; +import org.zstack.utils.Utils; +import org.zstack.utils.logging.CLogger; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.util.Arrays.asList; +import static org.zstack.core.Platform.operr; + +public class XinfiniApiResult { + private static final CLogger logger = Utils.getLogger(XinfiniApiResult.class); + private String resultString; + private String message; + private int returnCode; + + public int getReturnCode() { + return returnCode; + } + + public void setReturnCode(int returnCode) { + this.returnCode = returnCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setResultString(String resultString) { + this.resultString = resultString; + } + + private static Object getProperty(Object bean, Iterator it) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + String path = it.next(); + if (bean instanceof Map) { + Pattern re = Pattern.compile("(.*)\\[(\\d+)]"); + Matcher m = re.matcher(path); + if (m.find()) { + path = String.format("(%s)[%s]", m.group(1), m.group(2)); + } + } + + Object val = PropertyUtils.getProperty(bean, path); + + if (it.hasNext()) { + return getProperty(val, it); + } else { + return val; + } + } + + public static Object getProperty(Object bean, String path) { + List paths = asList(path.split("\\.")); + try { + return getProperty(bean, paths.iterator()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static void setProperty(Object bean, Iterator it, String fieldName, Object val) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { + if (it.hasNext()) { + bean = getProperty(bean, it); + } + + if (bean instanceof Map) { + Pattern re = Pattern.compile("(.*)\\[(\\d+)]"); + Matcher m = re.matcher(fieldName); + if (m.find()) { + fieldName = String.format("(%s)[%s]", m.group(1), m.group(2)); + } + } + + PropertyUtils.setProperty(bean, fieldName, val); + } + + public static void setProperty(Object bean, String path, Object val) { + List paths = asList(path.split("\\.")); + String fieldName = paths.get(paths.size()-1); + paths = paths.subList(0, paths.size()-1); + + try { + setProperty(bean, paths.iterator(), fieldName, val); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public T getResult(Class clz) { + if (resultString == null || resultString.isEmpty()) { + return null; + } + T ret; + try { + ret = XInfiniClient.gson.fromJson(resultString, clz); + } catch (Exception e) { + throw new OperationFailureException(operr("format api result to class[%s] failed, resultString: %s, exception: %s", clz.getName(), resultString, e.getMessage())); + } + return ret; + } + + public String getResultString() { + return resultString; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/ClusterModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/ClusterModule.java new file mode 100644 index 00000000000..3f4eb271ca6 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/ClusterModule.java @@ -0,0 +1,121 @@ +package org.zstack.xinfini.sdk.cluster; + +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class ClusterModule { + + public ClusterModule(String name, String uuid, VersionInfo versionInfo) { + this.name = name; + this.uuid = uuid; + this.versionInfo = versionInfo; + } + + private String name; + private String uuid; + private VersionInfo versionInfo; + + // Getters and Setters + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public VersionInfo getVersionInfo() { + return versionInfo; + } + + public void setVersionInfo(VersionInfo versionInfo) { + this.versionInfo = versionInfo; + } + + public class VersionInfo { + private String os; + private Map module; + private Map product; + private String version; + private String arch; + + public String getArch() { + return arch; + } + + public void setArch(String arch) { + this.arch = arch; + } + + // Getters and Setters + public String getOs() { + return os; + } + + public void setOs(String os) { + this.os = os; + } + + public Map getModule() { + return module; + } + + public void setModule(Map module) { + this.module = module; + } + + public Map getProduct() { + return product; + } + + public void setProduct(Map product) { + this.product = product; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } + + public static class ModuleVersion { + private String version; + + // Getter and Setter + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } + + public static class ProductVersion { + private String version; + + // Getter and Setter + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/QueryClusterRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/QueryClusterRequest.java new file mode 100644 index 00000000000..b884d6b21b9 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/QueryClusterRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.cluster; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/cluster", + method = HttpMethod.GET, + responseClass = QueryClusterResponse.class, + category = XInfiniApiCategory.SDDC +) +public class QueryClusterRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/QueryClusterResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/QueryClusterResponse.java new file mode 100644 index 00000000000..3bbc243f266 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/cluster/QueryClusterResponse.java @@ -0,0 +1,41 @@ +package org.zstack.xinfini.sdk.cluster; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryClusterResponse extends XInfiniQueryResponse { + private String name; + private String uuid; + private ClusterModule.VersionInfo versionInfo; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public ClusterModule.VersionInfo getVersionInfo() { + return versionInfo; + } + + public void setVersionInfo(ClusterModule.VersionInfo versionInfo) { + this.versionInfo = versionInfo; + } + + public ClusterModule toModule() { + return new ClusterModule(name, uuid, versionInfo); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/AddVolumeClientGroupMappingRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/AddVolumeClientGroupMappingRequest.java new file mode 100644 index 00000000000..876796a3f59 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/AddVolumeClientGroupMappingRequest.java @@ -0,0 +1,53 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/bs-volumes/{id}/:add-client-group-mappings", + method = HttpMethod.POST, + responseClass = AddVolumeClientGroupMappingResponse.class, + category = XInfiniApiCategory.AFA +) +public class AddVolumeClientGroupMappingRequest extends XInfiniRequest { + @Param + private int id; + + @Param + private List iscsiClientGroupIds; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public List getIscsiClientGroupIds() { + return iscsiClientGroupIds; + } + + public void setIscsiClientGroupIds(List iscsiClientGroupIds) { + this.iscsiClientGroupIds = iscsiClientGroupIds; + } + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/AddVolumeClientGroupMappingResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/AddVolumeClientGroupMappingResponse.java new file mode 100644 index 00000000000..a199a6ffc8e --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/AddVolumeClientGroupMappingResponse.java @@ -0,0 +1,43 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.XInfiniResponse; +import org.zstack.xinfini.sdk.volume.VolumeModule; + +/** + * @ Author : yh.w + * @ Date : Created in 19:28 2024/5/29 + */ +public class AddVolumeClientGroupMappingResponse extends XInfiniResponse { + private BaseResource.Metadata metadata; + private VolumeModule.VolumeSpec spec; + private VolumeModule.VolumeStatus status; + + public BaseResource.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(BaseResource.Metadata metadata) { + this.metadata = metadata; + } + + public VolumeModule.VolumeSpec getSpec() { + return spec; + } + + public void setSpec(VolumeModule.VolumeSpec spec) { + this.spec = spec; + } + + public VolumeModule.VolumeStatus getStatus() { + return status; + } + + public void setStatus(VolumeModule.VolumeStatus status) { + this.status = status; + } + + public VolumeModule toModule() { + return new VolumeModule(metadata, spec, status); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientGroupRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientGroupRequest.java new file mode 100644 index 00000000000..35c37bf449f --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientGroupRequest.java @@ -0,0 +1,77 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.header.xinfini.XInfiniConstants; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-client-groups", + method = HttpMethod.POST, + responseClass = CreateIscsiClientGroupResponse.class, + category = XInfiniApiCategory.AFA +) +public class CreateIscsiClientGroupRequest extends XInfiniRequest { + + @Param + private List iscsiGatewayIds; + + @Param + private List iscsiClientCodes; + + @Param + private String name; + + @Param + private String creator = XInfiniConstants.DEFAULT_CREATOR; + + public List getIscsiGatewayIds() { + return iscsiGatewayIds; + } + + public void setIscsiGatewayIds(List iscsiGatewayIds) { + this.iscsiGatewayIds = iscsiGatewayIds; + } + + public List getIscsiClientCodes() { + return iscsiClientCodes; + } + + public void setIscsiClientCodes(List iscsiClientCodes) { + this.iscsiClientCodes = iscsiClientCodes; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientGroupResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientGroupResponse.java new file mode 100644 index 00000000000..82726c6f772 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientGroupResponse.java @@ -0,0 +1,42 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 19:28 2024/5/29 + */ +public class CreateIscsiClientGroupResponse extends XInfiniResponse { + private BaseResource.Metadata metadata; + private IscsiClientGroupModule.IscsiClientGroupSpec spec; + private IscsiClientGroupModule.IscsiClientGroupStatus status; + + public BaseResource.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(BaseResource.Metadata metadata) { + this.metadata = metadata; + } + + public IscsiClientGroupModule.IscsiClientGroupSpec getSpec() { + return spec; + } + + public void setSpec(IscsiClientGroupModule.IscsiClientGroupSpec spec) { + this.spec = spec; + } + + public IscsiClientGroupModule.IscsiClientGroupStatus getStatus() { + return status; + } + + public void setStatus(IscsiClientGroupModule.IscsiClientGroupStatus status) { + this.status = status; + } + + public IscsiClientGroupModule toModule() { + return new IscsiClientGroupModule(metadata, spec, status); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientRequest.java new file mode 100644 index 00000000000..2ca03b16806 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientRequest.java @@ -0,0 +1,64 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-clients", + method = HttpMethod.POST, + responseClass = CreateIscsiClientResponse.class, + category = XInfiniApiCategory.AFA +) +public class CreateIscsiClientRequest extends XInfiniRequest { + + @Param + private Integer iscsiClientGroupId; + + @Param + private String name; + + @Param + private String code; + + public Integer getIscsiClientGroupId() { + return iscsiClientGroupId; + } + + public void setIscsiClientGroupId(Integer iscsiClientGroupId) { + this.iscsiClientGroupId = iscsiClientGroupId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientResponse.java new file mode 100644 index 00000000000..e32d541f3cb --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/CreateIscsiClientResponse.java @@ -0,0 +1,42 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 19:28 2024/5/29 + */ +public class CreateIscsiClientResponse extends XInfiniResponse { + private BaseResource.Metadata metadata; + private IscsiClientModule.IscsiClientSpec spec; + private IscsiClientModule.IscsiClientStatus status; + + public BaseResource.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(BaseResource.Metadata metadata) { + this.metadata = metadata; + } + + public IscsiClientModule.IscsiClientSpec getSpec() { + return spec; + } + + public void setSpec(IscsiClientModule.IscsiClientSpec spec) { + this.spec = spec; + } + + public IscsiClientModule.IscsiClientStatus getStatus() { + return status; + } + + public void setStatus(IscsiClientModule.IscsiClientStatus status) { + this.status = status; + } + + public IscsiClientModule toModule() { + return new IscsiClientModule(metadata, spec, status); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteIscsiClientRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteIscsiClientRequest.java new file mode 100644 index 00000000000..efab1974ea8 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteIscsiClientRequest.java @@ -0,0 +1,40 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-clients/{id}", + method = HttpMethod.DELETE, + responseClass = DeleteIscsiClientResponse.class, + category = XInfiniApiCategory.AFA +) +public class DeleteIscsiClientRequest extends XInfiniRequest { + @Param + private int id; + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteIscsiClientResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteIscsiClientResponse.java new file mode 100644 index 00000000000..60de80db3e0 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteIscsiClientResponse.java @@ -0,0 +1,10 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 19:28 2024/5/29 + */ +public class DeleteIscsiClientResponse extends XInfiniResponse { +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteVolumeClientGroupMappingRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteVolumeClientGroupMappingRequest.java new file mode 100644 index 00000000000..095b531b185 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteVolumeClientGroupMappingRequest.java @@ -0,0 +1,40 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/bs-volume-client-group-mappings/{id}", + method = HttpMethod.DELETE, + responseClass = DeleteVolumeClientGroupMappingResponse.class, + category = XInfiniApiCategory.AFA +) +public class DeleteVolumeClientGroupMappingRequest extends XInfiniRequest { + @Param + private int id; + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteVolumeClientGroupMappingResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteVolumeClientGroupMappingResponse.java new file mode 100644 index 00000000000..7058abda91a --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/DeleteVolumeClientGroupMappingResponse.java @@ -0,0 +1,10 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 19:28 2024/5/29 + */ +public class DeleteVolumeClientGroupMappingResponse extends XInfiniResponse { +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientGroupRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientGroupRequest.java new file mode 100644 index 00000000000..a04cc18a1a6 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientGroupRequest.java @@ -0,0 +1,40 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 11:49 2024/5/29 + */ +@XInfiniRestRequest( + path = "/iscsi-client-groups/{id}", + method = HttpMethod.GET, + responseClass = GetIscsiClientResponse.class, + category = XInfiniApiCategory.AFA +) +public class GetIscsiClientGroupRequest extends XInfiniRequest { + @Param + private int id; + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientGroupResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientGroupResponse.java new file mode 100644 index 00000000000..66ad1b5315a --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientGroupResponse.java @@ -0,0 +1,42 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class GetIscsiClientGroupResponse extends XInfiniResponse { + private BaseResource.Metadata metadata; + private IscsiClientGroupModule.IscsiClientGroupSpec spec; + private IscsiClientGroupModule.IscsiClientGroupStatus status; + + public BaseResource.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(BaseResource.Metadata metadata) { + this.metadata = metadata; + } + + public IscsiClientGroupModule.IscsiClientGroupSpec getSpec() { + return spec; + } + + public void setSpec(IscsiClientGroupModule.IscsiClientGroupSpec spec) { + this.spec = spec; + } + + public IscsiClientGroupModule.IscsiClientGroupStatus getStatus() { + return status; + } + + public void setStatus(IscsiClientGroupModule.IscsiClientGroupStatus status) { + this.status = status; + } + + public IscsiClientGroupModule toModule() { + return new IscsiClientGroupModule(metadata, spec, status); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientRequest.java new file mode 100644 index 00000000000..0711e114009 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientRequest.java @@ -0,0 +1,40 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 11:49 2024/5/29 + */ +@XInfiniRestRequest( + path = "/iscsi-clients/{id}", + method = HttpMethod.GET, + responseClass = GetIscsiClientResponse.class, + category = XInfiniApiCategory.AFA +) +public class GetIscsiClientRequest extends XInfiniRequest { + @Param + private int id; + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientResponse.java new file mode 100644 index 00000000000..c245b5c53de --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetIscsiClientResponse.java @@ -0,0 +1,42 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class GetIscsiClientResponse extends XInfiniResponse { + private BaseResource.Metadata metadata; + private IscsiClientModule.IscsiClientSpec spec; + private IscsiClientModule.IscsiClientStatus status; + + public BaseResource.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(BaseResource.Metadata metadata) { + this.metadata = metadata; + } + + public IscsiClientModule.IscsiClientSpec getSpec() { + return spec; + } + + public void setSpec(IscsiClientModule.IscsiClientSpec spec) { + this.spec = spec; + } + + public IscsiClientModule.IscsiClientStatus getStatus() { + return status; + } + + public void setStatus(IscsiClientModule.IscsiClientStatus status) { + this.status = status; + } + + public IscsiClientModule toModule() { + return new IscsiClientModule(metadata, spec, status); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetVolumeClientGroupMappingRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetVolumeClientGroupMappingRequest.java new file mode 100644 index 00000000000..1ac1f70d2ba --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetVolumeClientGroupMappingRequest.java @@ -0,0 +1,40 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.externalStorage.sdk.Param; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 11:49 2024/5/29 + */ +@XInfiniRestRequest( + path = "/bs-volume-client-group-mappings/{id}", + method = HttpMethod.GET, + responseClass = GetVolumeClientGroupMappingResponse.class, + category = XInfiniApiCategory.AFA +) +public class GetVolumeClientGroupMappingRequest extends XInfiniRequest { + @Param + private int id; + + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetVolumeClientGroupMappingResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetVolumeClientGroupMappingResponse.java new file mode 100644 index 00000000000..d35081fc89e --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/GetVolumeClientGroupMappingResponse.java @@ -0,0 +1,42 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.XInfiniResponse; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class GetVolumeClientGroupMappingResponse extends XInfiniResponse { + private BaseResource.Metadata metadata; + private VolumeClientGroupMappingModule.VolumeClientGroupMappingSpec spec; + private VolumeClientGroupMappingModule.VolumeClientGroupMappingStatus status; + + public BaseResource.Metadata getMetadata() { + return metadata; + } + + public void setMetadata(BaseResource.Metadata metadata) { + this.metadata = metadata; + } + + public VolumeClientGroupMappingModule.VolumeClientGroupMappingSpec getSpec() { + return spec; + } + + public void setSpec(VolumeClientGroupMappingModule.VolumeClientGroupMappingSpec spec) { + this.spec = spec; + } + + public VolumeClientGroupMappingModule.VolumeClientGroupMappingStatus getStatus() { + return status; + } + + public void setStatus(VolumeClientGroupMappingModule.VolumeClientGroupMappingStatus status) { + this.status = status; + } + + public VolumeClientGroupMappingModule toModule() { + return new VolumeClientGroupMappingModule(metadata, spec, status); + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiClientGroupModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiClientGroupModule.java new file mode 100644 index 00000000000..abe6bfdbe49 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiClientGroupModule.java @@ -0,0 +1,135 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.BaseSpec; +import org.zstack.xinfini.sdk.BaseStatus; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class IscsiClientGroupModule extends BaseResource { + + private IscsiClientGroupSpec spec; + + private IscsiClientGroupStatus status; + + public IscsiClientGroupModule(Metadata md, IscsiClientGroupSpec spec, IscsiClientGroupStatus status) { + this.spec = spec; + this.status = status; + this.setMetadata(md); + } + + public IscsiClientGroupSpec getSpec() { + return spec; + } + + public void setSpec(IscsiClientGroupSpec spec) { + this.spec = spec; + } + + public IscsiClientGroupStatus getStatus() { + return status; + } + + public void setStatus(IscsiClientGroupStatus status) { + this.status = status; + } + + public static class IscsiClientGroupSpec extends BaseSpec { + private Integer gatewayNumPerVolume; + private Integer targetGroupNum; + private Integer targetNumPerVolume; + private String chapState; + + public Integer getGatewayNumPerVolume() { + return gatewayNumPerVolume; + } + + public void setGatewayNumPerVolume(Integer gatewayNumPerVolume) { + this.gatewayNumPerVolume = gatewayNumPerVolume; + } + + public Integer getTargetGroupNum() { + return targetGroupNum; + } + + public void setTargetGroupNum(Integer targetGroupNum) { + this.targetGroupNum = targetGroupNum; + } + + public Integer getTargetNumPerVolume() { + return targetNumPerVolume; + } + + public void setTargetNumPerVolume(Integer targetNumPerVolume) { + this.targetNumPerVolume = targetNumPerVolume; + } + + public String getChapState() { + return chapState; + } + + public void setChapState(String chapState) { + this.chapState = chapState; + } + } + + public static class IscsiClientGroupStatus extends BaseStatus { + private Integer iscsiGatewayNum; + private Integer targetGroupNum; + private Integer targetNumPerVolume; + private String chapState; + private Integer bsVolumeNum; + private Integer iscsiClientNum; + + public Integer getIscsiGatewayNum() { + return iscsiGatewayNum; + } + + public void setIscsiGatewayNum(Integer iscsiGatewayNum) { + this.iscsiGatewayNum = iscsiGatewayNum; + } + + public Integer getTargetGroupNum() { + return targetGroupNum; + } + + public void setTargetGroupNum(Integer targetGroupNum) { + this.targetGroupNum = targetGroupNum; + } + + public Integer getTargetNumPerVolume() { + return targetNumPerVolume; + } + + public void setTargetNumPerVolume(Integer targetNumPerVolume) { + this.targetNumPerVolume = targetNumPerVolume; + } + + public String getChapState() { + return chapState; + } + + public void setChapState(String chapState) { + this.chapState = chapState; + } + + public Integer getBsVolumeNum() { + return bsVolumeNum; + } + + public void setBsVolumeNum(Integer bsVolumeNum) { + this.bsVolumeNum = bsVolumeNum; + } + + public Integer getIscsiClientNum() { + return iscsiClientNum; + } + + public void setIscsiClientNum(Integer iscsiClientNum) { + this.iscsiClientNum = iscsiClientNum; + } + } + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiClientModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiClientModule.java new file mode 100644 index 00000000000..73b67c3ab0d --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiClientModule.java @@ -0,0 +1,155 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.BaseSpec; +import org.zstack.xinfini.sdk.BaseStatus; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class IscsiClientModule extends BaseResource { + + private IscsiClientSpec spec; + + private IscsiClientStatus status; + + public IscsiClientModule(Metadata md, IscsiClientSpec spec, IscsiClientStatus status) { + this.spec = spec; + this.status = status; + this.setMetadata(md); + } + + public IscsiClientSpec getSpec() { + return spec; + } + + public void setSpec(IscsiClientSpec spec) { + this.spec = spec; + } + + public IscsiClientStatus getStatus() { + return status; + } + + public void setStatus(IscsiClientStatus status) { + this.status = status; + } + + public static class IscsiClientSpec extends BaseSpec { + private Integer iscsiClientGroupId; + private String code; + private Integer gatewayNumPerVolume; + private Integer targetGroupNum; + private Integer targetNumPerVolume; + private String chapState; + + public Integer getIscsiClientGroupId() { + return iscsiClientGroupId; + } + + public void setIscsiClientGroupId(Integer iscsiClientGroupId) { + this.iscsiClientGroupId = iscsiClientGroupId; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Integer getGatewayNumPerVolume() { + return gatewayNumPerVolume; + } + + public void setGatewayNumPerVolume(Integer gatewayNumPerVolume) { + this.gatewayNumPerVolume = gatewayNumPerVolume; + } + + public Integer getTargetGroupNum() { + return targetGroupNum; + } + + public void setTargetGroupNum(Integer targetGroupNum) { + this.targetGroupNum = targetGroupNum; + } + + public Integer getTargetNumPerVolume() { + return targetNumPerVolume; + } + + public void setTargetNumPerVolume(Integer targetNumPerVolume) { + this.targetNumPerVolume = targetNumPerVolume; + } + + public String getChapState() { + return chapState; + } + + public void setChapState(String chapState) { + this.chapState = chapState; + } + } + + public static class IscsiClientStatus extends BaseStatus { + private List targetIqns; + private Integer iscsiGatewayNum; + private Integer targetGroupNum; + private Integer targetNumPerVolume; + private String chapState; + private Integer bsVolumeNum; + + public List getTargetIqns() { + return targetIqns; + } + + public void setTargetIqns(List targetIqns) { + this.targetIqns = targetIqns; + } + + public Integer getIscsiGatewayNum() { + return iscsiGatewayNum; + } + + public void setIscsiGatewayNum(Integer iscsiGatewayNum) { + this.iscsiGatewayNum = iscsiGatewayNum; + } + + public Integer getTargetGroupNum() { + return targetGroupNum; + } + + public void setTargetGroupNum(Integer targetGroupNum) { + this.targetGroupNum = targetGroupNum; + } + + public Integer getTargetNumPerVolume() { + return targetNumPerVolume; + } + + public void setTargetNumPerVolume(Integer targetNumPerVolume) { + this.targetNumPerVolume = targetNumPerVolume; + } + + public String getChapState() { + return chapState; + } + + public void setChapState(String chapState) { + this.chapState = chapState; + } + + public Integer getBsVolumeNum() { + return bsVolumeNum; + } + + public void setBsVolumeNum(Integer bsVolumeNum) { + this.bsVolumeNum = bsVolumeNum; + } + } + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiGatewayClientGroupMappingModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiGatewayClientGroupMappingModule.java new file mode 100644 index 00000000000..56e46b82189 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiGatewayClientGroupMappingModule.java @@ -0,0 +1,73 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.BaseSpec; +import org.zstack.xinfini.sdk.BaseStatus; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class IscsiGatewayClientGroupMappingModule extends BaseResource { + public IscsiGatewayClientGroupMappingModule(Metadata md, IscsiGatewayClientGroupMappingSpec spec, IscsiGatewayClientGroupMappingStatus status) { + this.spec = spec; + this.status = status; + this.setMetadata(md); + } + + private IscsiGatewayClientGroupMappingSpec spec; + private IscsiGatewayClientGroupMappingStatus status; + + public IscsiGatewayClientGroupMappingSpec getSpec() { + return spec; + } + + public void setSpec(IscsiGatewayClientGroupMappingSpec spec) { + this.spec = spec; + } + + public IscsiGatewayClientGroupMappingStatus getStatus() { + return status; + } + + public void setStatus(IscsiGatewayClientGroupMappingStatus status) { + this.status = status; + } + + public static class IscsiGatewayClientGroupMappingStatus extends BaseStatus { + private int iscsiPathNum; + + public int getIscsiPathNum() { + return iscsiPathNum; + } + + public void setIscsiPathNum(int iscsiPathNum) { + this.iscsiPathNum = iscsiPathNum; + } + } + + public static class IscsiGatewayClientGroupMappingSpec extends BaseSpec { + + private Integer iscsiGatewayId; + + private Integer iscsiClientGroupId; + + public Integer getIscsiClientGroupId() { + return iscsiClientGroupId; + } + + public void setIscsiClientGroupId(Integer iscsiClientGroupId) { + this.iscsiClientGroupId = iscsiClientGroupId; + } + + public Integer getIscsiGatewayId() { + return iscsiGatewayId; + } + + public void setIscsiGatewayId(Integer iscsiGatewayId) { + this.iscsiGatewayId = iscsiGatewayId; + } + } + + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiGatewayModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiGatewayModule.java new file mode 100644 index 00000000000..54c49aa553c --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiGatewayModule.java @@ -0,0 +1,200 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.BaseSpec; +import org.zstack.xinfini.sdk.BaseStatus; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class IscsiGatewayModule extends BaseResource { + public IscsiGatewayModule(Metadata md, IscsiGatewaySpec spec, IscsiGatewayStatus status) { + this.spec = spec; + this.status = status; + this.setMetadata(md); + } + + private IscsiGatewaySpec spec; + private IscsiGatewayStatus status; + + public IscsiGatewaySpec getSpec() { + return spec; + } + + public void setSpec(IscsiGatewaySpec spec) { + this.spec = spec; + } + + public IscsiGatewayStatus getStatus() { + return status; + } + + public void setStatus(IscsiGatewayStatus status) { + this.status = status; + } + + public static class IscsiGatewayStatus extends BaseStatus { + private String configContent; + private String containerId; + private long pid; + private String setupContent; + private int iscsiClientNum; + private int iscsiClientGroupNum; + private int iscsiPathNum; + private String nodeState; + + public String getNodeState() { + return nodeState; + } + + public void setNodeState(String nodeState) { + this.nodeState = nodeState; + } + + public String getConfigContent() { + return configContent; + } + + public void setConfigContent(String configContent) { + this.configContent = configContent; + } + + public String getContainerId() { + return containerId; + } + + public void setContainerId(String containerId) { + this.containerId = containerId; + } + + public long getPid() { + return pid; + } + + public void setPid(long pid) { + this.pid = pid; + } + + public String getSetupContent() { + return setupContent; + } + + public void setSetupContent(String setupContent) { + this.setupContent = setupContent; + } + + public int getIscsiClientNum() { + return iscsiClientNum; + } + + public void setIscsiClientNum(int iscsiClientNum) { + this.iscsiClientNum = iscsiClientNum; + } + + public int getIscsiClientGroupNum() { + return iscsiClientGroupNum; + } + + public void setIscsiClientGroupNum(int iscsiClientGroupNum) { + this.iscsiClientGroupNum = iscsiClientGroupNum; + } + + public int getIscsiPathNum() { + return iscsiPathNum; + } + + public void setIscsiPathNum(int iscsiPathNum) { + this.iscsiPathNum = iscsiPathNum; + } + } + + public static class IscsiGatewaySpec extends BaseSpec { + + private int nodeId; + private List ips; + private int port; + private int adminPort; + private int metricPort; + private String configContent; + private String setupContent; + private int serviceId; + private int ioRetryCount; + + public int getNodeId() { + return nodeId; + } + + public void setNodeId(int nodeId) { + this.nodeId = nodeId; + } + + public List getIps() { + return ips; + } + + public void setIps(List ips) { + this.ips = ips; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public int getAdminPort() { + return adminPort; + } + + public void setAdminPort(int adminPort) { + this.adminPort = adminPort; + } + + public int getMetricPort() { + return metricPort; + } + + public void setMetricPort(int metricPort) { + this.metricPort = metricPort; + } + + public String getConfigContent() { + return configContent; + } + + public void setConfigContent(String configContent) { + this.configContent = configContent; + } + + public String getSetupContent() { + return setupContent; + } + + public void setSetupContent(String setupContent) { + this.setupContent = setupContent; + } + + public int getServiceId() { + return serviceId; + } + + public void setServiceId(int serviceId) { + this.serviceId = serviceId; + } + + public int getIoRetryCount() { + return ioRetryCount; + } + + public void setIoRetryCount(int ioRetryCount) { + this.ioRetryCount = ioRetryCount; + } + } + + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiNodeState.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiNodeState.java new file mode 100644 index 00000000000..a2d2875d574 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/IscsiNodeState.java @@ -0,0 +1,6 @@ +package org.zstack.xinfini.sdk.iscsi; + +public enum IscsiNodeState { + ACTIVE, + ERROR +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientGroupRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientGroupRequest.java new file mode 100644 index 00000000000..c3ec46456da --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientGroupRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-client-groups", + method = HttpMethod.GET, + responseClass = QueryIscsiClientGroupResponse.class, + category = XInfiniApiCategory.AFA +) +public class QueryIscsiClientGroupRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientGroupResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientGroupResponse.java new file mode 100644 index 00000000000..d9013b62d16 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientGroupResponse.java @@ -0,0 +1,21 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryIscsiClientGroupResponse extends XInfiniQueryResponse { + List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientRequest.java new file mode 100644 index 00000000000..95067e64ddb --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-clients", + method = HttpMethod.GET, + responseClass = QueryIscsiGatewayResponse.class, + category = XInfiniApiCategory.AFA +) +public class QueryIscsiClientRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientResponse.java new file mode 100644 index 00000000000..8addc963d07 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiClientResponse.java @@ -0,0 +1,21 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryIscsiClientResponse extends XInfiniQueryResponse { + List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayClientGroupMappingRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayClientGroupMappingRequest.java new file mode 100644 index 00000000000..2dd96cbdc1e --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayClientGroupMappingRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-gateway-client-group-mappings", + method = HttpMethod.GET, + responseClass = QueryIscsiGatewayClientGroupMappingResponse.class, + category = XInfiniApiCategory.AFA +) +public class QueryIscsiGatewayClientGroupMappingRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayClientGroupMappingResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayClientGroupMappingResponse.java new file mode 100644 index 00000000000..d295994e398 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayClientGroupMappingResponse.java @@ -0,0 +1,21 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryIscsiGatewayClientGroupMappingResponse extends XInfiniQueryResponse { + List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayRequest.java new file mode 100644 index 00000000000..7a766af9efd --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/iscsi-gateways", + method = HttpMethod.GET, + responseClass = QueryIscsiGatewayResponse.class, + category = XInfiniApiCategory.AFA +) +public class QueryIscsiGatewayRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayResponse.java new file mode 100644 index 00000000000..96d29c8713f --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryIscsiGatewayResponse.java @@ -0,0 +1,21 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryIscsiGatewayResponse extends XInfiniQueryResponse { + List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientGroupMappingRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientGroupMappingRequest.java new file mode 100644 index 00000000000..79278fe05b1 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientGroupMappingRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/bs-volume-client-group-mappings", + method = HttpMethod.GET, + responseClass = QueryVolumeClientGroupMappingResponse.class, + category = XInfiniApiCategory.AFA +) +public class QueryVolumeClientGroupMappingRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientGroupMappingResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientGroupMappingResponse.java new file mode 100644 index 00000000000..1bc619cfcb3 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientGroupMappingResponse.java @@ -0,0 +1,21 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryVolumeClientGroupMappingResponse extends XInfiniQueryResponse { + List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientMappingRequest.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientMappingRequest.java new file mode 100644 index 00000000000..30d18570ce6 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientMappingRequest.java @@ -0,0 +1,28 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.springframework.http.HttpMethod; +import org.zstack.xinfini.XInfiniApiCategory; +import org.zstack.xinfini.sdk.XInfiniQueryRequest; +import org.zstack.xinfini.sdk.XInfiniRestRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @ Author : yh.w + * @ Date : Created in 17:36 2024/5/27 + */ +@XInfiniRestRequest( + path = "/bs-volume-client-mappings", + method = HttpMethod.GET, + responseClass = QueryVolumeClientMappingResponse.class, + category = XInfiniApiCategory.AFA +) +public class QueryVolumeClientMappingRequest extends XInfiniQueryRequest { + private static final HashMap parameterMap = new HashMap<>(); + + @Override + public Map getParameterMap() { + return parameterMap; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientMappingResponse.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientMappingResponse.java new file mode 100644 index 00000000000..8cd01389141 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/QueryVolumeClientMappingResponse.java @@ -0,0 +1,21 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.XInfiniQueryResponse; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:51 2024/5/28 + */ +public class QueryVolumeClientMappingResponse extends XInfiniQueryResponse { + List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/VolumeClientGroupMappingModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/VolumeClientGroupMappingModule.java new file mode 100644 index 00000000000..bbf864b7abc --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/VolumeClientGroupMappingModule.java @@ -0,0 +1,72 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.BaseSpec; +import org.zstack.xinfini.sdk.BaseStatus; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class VolumeClientGroupMappingModule extends BaseResource { + public VolumeClientGroupMappingModule(Metadata md, VolumeClientGroupMappingSpec spec, VolumeClientGroupMappingStatus status) { + this.spec = spec; + this.status = status; + this.setMetadata(md); + } + + private VolumeClientGroupMappingSpec spec; + private VolumeClientGroupMappingStatus status; + + public VolumeClientGroupMappingSpec getSpec() { + return spec; + } + + public void setSpec(VolumeClientGroupMappingSpec spec) { + this.spec = spec; + } + + public VolumeClientGroupMappingStatus getStatus() { + return status; + } + + public void setStatus(VolumeClientGroupMappingStatus status) { + this.status = status; + } + + public static class VolumeClientGroupMappingStatus extends BaseStatus { + + } + + public static class VolumeClientGroupMappingSpec extends BaseSpec { + private Integer bsVolumeId; + private Integer iscsiClientGroupId; + private Integer lunId; + + public Integer getBsVolumeId() { + return bsVolumeId; + } + + public void setBsVolumeId(Integer bsVolumeId) { + this.bsVolumeId = bsVolumeId; + } + + public Integer getIscsiClientGroupId() { + return iscsiClientGroupId; + } + + public void setIscsiClientGroupId(Integer iscsiClientGroupId) { + this.iscsiClientGroupId = iscsiClientGroupId; + } + + public Integer getLunId() { + return lunId; + } + + public void setLunId(Integer lunId) { + this.lunId = lunId; + } + } + + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/VolumeClientMappingModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/VolumeClientMappingModule.java new file mode 100644 index 00000000000..b585d2e3013 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/iscsi/VolumeClientMappingModule.java @@ -0,0 +1,163 @@ +package org.zstack.xinfini.sdk.iscsi; + +import org.zstack.xinfini.sdk.BaseResource; +import org.zstack.xinfini.sdk.BaseSpec; +import org.zstack.xinfini.sdk.BaseStatus; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 11:29 2024/5/28 + */ +public class VolumeClientMappingModule extends BaseResource { + public VolumeClientMappingModule(Metadata md, VolumeClientMappingSpec spec, VolumeClientMappingStatus status) { + this.spec = spec; + this.status = status; + this.setMetadata(md); + } + + private VolumeClientMappingSpec spec; + private VolumeClientMappingStatus status; + + public VolumeClientMappingSpec getSpec() { + return spec; + } + + public void setSpec(VolumeClientMappingSpec spec) { + this.spec = spec; + } + + public VolumeClientMappingStatus getStatus() { + return status; + } + + public void setStatus(VolumeClientMappingStatus status) { + this.status = status; + } + + public static class VolumeClientMappingStatus extends BaseStatus { + private Integer pathNum; + private List iscsiTargetIds; + private List iscsiTargetGroupIds; + + public Integer getPathNum() { + return pathNum; + } + + public void setPathNum(Integer pathNum) { + this.pathNum = pathNum; + } + + public List getIscsiTargetIds() { + return iscsiTargetIds; + } + + public void setIscsiTargetIds(List iscsiTargetIds) { + this.iscsiTargetIds = iscsiTargetIds; + } + + public List getIscsiTargetGroupIds() { + return iscsiTargetGroupIds; + } + + public void setIscsiTargetGroupIds(List iscsiTargetGroupIds) { + this.iscsiTargetGroupIds = iscsiTargetGroupIds; + } + } + + public static class VolumeClientMappingSpec extends BaseSpec { + private Integer bsVolumeId; + private String protocol; + private Integer pathNum; + private Integer nvmeClientId; + private Integer nsId; + private Integer iscsiClientId; + private Integer iscsiClientGroupId; + private Integer lunId; + private List iscsiTargetIds; + private List iscsiTargetGroupIds; + + public Integer getBsVolumeId() { + return bsVolumeId; + } + + public void setBsVolumeId(Integer bsVolumeId) { + this.bsVolumeId = bsVolumeId; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public Integer getPathNum() { + return pathNum; + } + + public void setPathNum(Integer pathNum) { + this.pathNum = pathNum; + } + + public Integer getNvmeClientId() { + return nvmeClientId; + } + + public void setNvmeClientId(Integer nvmeClientId) { + this.nvmeClientId = nvmeClientId; + } + + public Integer getNsId() { + return nsId; + } + + public void setNsId(Integer nsId) { + this.nsId = nsId; + } + + public Integer getIscsiClientId() { + return iscsiClientId; + } + + public void setIscsiClientId(Integer iscsiClientId) { + this.iscsiClientId = iscsiClientId; + } + + public Integer getIscsiClientGroupId() { + return iscsiClientGroupId; + } + + public void setIscsiClientGroupId(Integer iscsiClientGroupId) { + this.iscsiClientGroupId = iscsiClientGroupId; + } + + public Integer getLunId() { + return lunId; + } + + public void setLunId(Integer lunId) { + this.lunId = lunId; + } + + public List getIscsiTargetIds() { + return iscsiTargetIds; + } + + public void setIscsiTargetIds(List iscsiTargetIds) { + this.iscsiTargetIds = iscsiTargetIds; + } + + public List getIscsiTargetGroupIds() { + return iscsiTargetGroupIds; + } + + public void setIscsiTargetGroupIds(List iscsiTargetGroupIds) { + this.iscsiTargetGroupIds = iscsiTargetGroupIds; + } + } + + +} diff --git a/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/metric/MetricModule.java b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/metric/MetricModule.java new file mode 100644 index 00000000000..b7ec1ffa322 --- /dev/null +++ b/plugin/xinfini/src/main/java/org/zstack/xinfini/sdk/metric/MetricModule.java @@ -0,0 +1,89 @@ +package org.zstack.xinfini.sdk.metric; + +import java.util.List; + +/** + * @ Author : yh.w + * @ Date : Created in 17:30 2024/5/29 + */ +public class MetricModule { + private String resultType; + private List result; + + public String getResultType() { + return resultType; + } + + public void setResultType(String resultType) { + this.resultType = resultType; + } + + public List getResult() { + return result; + } + + public void setResult(List result) { + this.result = result; + } + + public static class Value { + private String resource; + private List diff --git a/testlib/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollectorForTest.java b/testlib/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollectorForTest.java new file mode 100644 index 00000000000..a8d9f37b4b4 --- /dev/null +++ b/testlib/src/main/java/org/zstack/kvm/hypervisor/HypervisorMetadataCollectorForTest.java @@ -0,0 +1,83 @@ +package org.zstack.kvm.hypervisor; + +import org.zstack.header.host.CpuArchitecture; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +/** + * override function for scanning folder and reading from shell + * + * Created by Wenhao.Zhang on 23/03/01 + */ +public class HypervisorMetadataCollectorForTest extends HypervisorMetadataCollectorImpl { + public static final String QEMU_VERSION_FOR_TEST = "4.2.0-632.g6a6222b.el7"; + private Function> folderScannerSimulator; + private Function collectMetadataSimulator; + + { + cleanSimulators(); + } + + public void cleanSimulators() { + setFolderScannerSimulator(null); + setCollectMetadataSimulator(null); + } + + public void setFolderScannerSimulator(Function> simulator) { + this.folderScannerSimulator = simulator == null ? this::scanFolderForDefault : simulator; + } + + public void setCollectMetadataSimulator(Function simulator) { + this.collectMetadataSimulator = simulator == null ? this::collectMetadataForDefault : simulator; + } + + @Override + protected List scanFolder(Path rootPath) throws IOException { + return folderScannerSimulator.apply(rootPath); + } + + public List scanFolderForDefault(Path rootPath) { + HypervisorMetadataDefinitionForTest d1 = new HypervisorMetadataDefinitionForTest(); + d1.setArchitecture(CpuArchitecture.x86_64.name()); + d1.setOsReleaseSimpleVersion("c76"); + + HypervisorMetadataDefinitionForTest d2 = new HypervisorMetadataDefinitionForTest(); + d2.setArchitecture(CpuArchitecture.x86_64.name()); + d2.setOsReleaseSimpleVersion("c79"); + + return Arrays.asList(d1, d2); + } + + @Override + protected String collectHypervisorMetadataAsProperties(HypervisorMetadataDefinition definition) throws IOException { + return collectMetadataSimulator.apply(definition); + } + + public String collectMetadataForDefault(HypervisorMetadataDefinition definition) { + String[] osReleaseVersion; + switch (definition.getOsReleaseSimpleVersion()) { + case "ns10": osReleaseVersion = "kylin10 tercel 10".split(" "); break; + case "uos20": osReleaseVersion = "uniontech fou 20".split(" "); break; + case "uos1021a": osReleaseVersion = "uniontech kongzi 20".split(" "); break; + case "c79": osReleaseVersion = "centos Core 7.9.2009".split(" "); break; + case "c76": osReleaseVersion = "centos Core 7.6.1810".split(" "); break; + case "c74": osReleaseVersion = "centos Core 7.4.1708".split(" "); break; + default: osReleaseVersion = new String[] {"unknown", "unknown", "unknown"}; break; + } + + return String.format("qemu-kvm.version: %s\n" + + "platform.distname: %s\nplatform.id: %s\nplatform.version: %s\n", + QEMU_VERSION_FOR_TEST, osReleaseVersion[0], osReleaseVersion[1], osReleaseVersion[2]); + } + + public static class HypervisorMetadataDefinitionForTest extends HypervisorMetadataDefinition { + @Override + public boolean isValid() { + return true; + } + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy b/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy index 396ac8dff42..34cf02a9ff5 100644 --- a/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy +++ b/testlib/src/main/java/org/zstack/testlib/ApiHelper.groovy @@ -15,7 +15,34 @@ abstract class ApiHelper { } } - def createDataVolumeTemplateFromVolumeBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.heder.storage.volume.backup.CreateDataVolumeTemplateFromVolumeBackupAction.class) Closure c) { + def createDataVolumeFromVolumeBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.heder.storage.volume.backup.CreateDataVolumeFromVolumeBackupAction.class) Closure c) { + def a = new org.zstack.heder.storage.volume.backup.CreateDataVolumeFromVolumeBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createDataVolumeTemplateFromVolumeBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.heder.storage.volume.backup.CreateDataVolumeTemplateFromVolumeBackupAction.class) Closure c) { def a = new org.zstack.heder.storage.volume.backup.CreateDataVolumeTemplateFromVolumeBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST @@ -123,6 +150,33 @@ abstract class ApiHelper { } + def createVmFromVolumeBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.heder.storage.volume.backup.CreateVmFromVolumeBackupAction.class) Closure c) { + def a = new org.zstack.heder.storage.volume.backup.CreateVmFromVolumeBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def createVolumeBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.heder.storage.volume.backup.CreateVolumeBackupAction.class) Closure c) { def a = new org.zstack.heder.storage.volume.backup.CreateVolumeBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -908,6 +962,33 @@ abstract class ApiHelper { } + def addBlockPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddBlockPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddBlockPrimaryStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def addBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddBuildAppAction.class) Closure c) { def a = new org.zstack.sdk.AddBuildAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -1097,8 +1178,8 @@ abstract class ApiHelper { } - def addDataCenterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDataCenterFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.AddDataCenterFromRemoteAction() + def addContainerManagementEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddContainerManagementEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.AddContainerManagementEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1124,8 +1205,8 @@ abstract class ApiHelper { } - def addDisasterImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDisasterImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddDisasterImageStoreBackupStorageAction() + def addDataCenterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDataCenterFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.AddDataCenterFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1151,8 +1232,8 @@ abstract class ApiHelper { } - def addDnsToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDnsToL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.AddDnsToL3NetworkAction() + def addDisasterImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDisasterImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddDisasterImageStoreBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1178,8 +1259,8 @@ abstract class ApiHelper { } - def addDnsToVpcRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDnsToVpcRouterAction.class) Closure c) { - def a = new org.zstack.sdk.AddDnsToVpcRouterAction() + def addDnsToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDnsToL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.AddDnsToL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1205,8 +1286,8 @@ abstract class ApiHelper { } - def addHostRouteToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddHostRouteToL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.AddHostRouteToL3NetworkAction() + def addDnsToVpcRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddDnsToVpcRouterAction.class) Closure c) { + def a = new org.zstack.sdk.AddDnsToVpcRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1232,8 +1313,8 @@ abstract class ApiHelper { } - def addHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddHybridKeySecretAction.class) Closure c) { - def a = new org.zstack.sdk.AddHybridKeySecretAction() + def addExternalBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddExternalBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddExternalBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1259,8 +1340,8 @@ abstract class ApiHelper { } - def addIdentityZoneFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIdentityZoneFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.AddIdentityZoneFromRemoteAction() + def addExternalPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddExternalPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddExternalPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1286,8 +1367,8 @@ abstract class ApiHelper { } - def addImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddImageAction.class) Closure c) { - def a = new org.zstack.sdk.AddImageAction() + def addFiSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddFiSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.AddFiSecSecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1313,8 +1394,8 @@ abstract class ApiHelper { } - def addImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddImageStoreBackupStorageAction() + def addFlkSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddFlkSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.AddFlkSecSecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1340,8 +1421,8 @@ abstract class ApiHelper { } - def addInfoSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddInfoSecSecurityMachineAction.class) Closure c) { - def a = new org.zstack.sdk.AddInfoSecSecurityMachineAction() + def addHostRouteToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddHostRouteToL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.AddHostRouteToL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1367,8 +1448,8 @@ abstract class ApiHelper { } - def addIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpRangeAction.class) Closure c) { - def a = new org.zstack.sdk.AddIpRangeAction() + def addHostToHostSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddHostToHostSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddHostToHostSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1394,8 +1475,8 @@ abstract class ApiHelper { } - def addIpRangeByNetworkCidr(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpRangeByNetworkCidrAction.class) Closure c) { - def a = new org.zstack.sdk.AddIpRangeByNetworkCidrAction() + def addHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddHybridKeySecretAction.class) Closure c) { + def a = new org.zstack.sdk.AddHybridKeySecretAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1421,8 +1502,8 @@ abstract class ApiHelper { } - def addIpv6Range(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpv6RangeAction.class) Closure c) { - def a = new org.zstack.sdk.AddIpv6RangeAction() + def addIdentityZoneFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIdentityZoneFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.AddIdentityZoneFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1448,8 +1529,8 @@ abstract class ApiHelper { } - def addIpv6RangeByNetworkCidr(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpv6RangeByNetworkCidrAction.class) Closure c) { - def a = new org.zstack.sdk.AddIpv6RangeByNetworkCidrAction() + def addImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddImageAction.class) Closure c) { + def a = new org.zstack.sdk.AddImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1475,8 +1556,8 @@ abstract class ApiHelper { } - def addIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIscsiServerAction.class) Closure c) { - def a = new org.zstack.sdk.AddIscsiServerAction() + def addImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddImageStoreBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1502,8 +1583,8 @@ abstract class ApiHelper { } - def addKVMHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddKVMHostAction.class) Closure c) { - def a = new org.zstack.sdk.AddKVMHostAction() + def addInfoSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddInfoSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.AddInfoSecSecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1529,8 +1610,8 @@ abstract class ApiHelper { } - def addKVMHostFromConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddKVMHostFromConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.AddKVMHostFromConfigFileAction() + def addIntegrityResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIntegrityResourceAction.class) Closure c) { + def a = new org.zstack.sdk.AddIntegrityResourceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1556,8 +1637,8 @@ abstract class ApiHelper { } - def addLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLdapServerAction.class) Closure c) { - def a = new org.zstack.sdk.AddLdapServerAction() + def addIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.AddIpRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1583,8 +1664,8 @@ abstract class ApiHelper { } - def addLocalPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLocalPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddLocalPrimaryStorageAction() + def addIpRangeByNetworkCidr(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpRangeByNetworkCidrAction.class) Closure c) { + def a = new org.zstack.sdk.AddIpRangeByNetworkCidrAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1610,8 +1691,8 @@ abstract class ApiHelper { } - def addLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLogConfigurationAction.class) Closure c) { - def a = new org.zstack.sdk.AddLogConfigurationAction() + def addIpv6Range(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpv6RangeAction.class) Closure c) { + def a = new org.zstack.sdk.AddIpv6RangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1637,8 +1718,8 @@ abstract class ApiHelper { } - def addMdevDeviceSpecToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMdevDeviceSpecToVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.AddMdevDeviceSpecToVmInstanceAction() + def addIpv6RangeByNetworkCidr(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIpv6RangeByNetworkCidrAction.class) Closure c) { + def a = new org.zstack.sdk.AddIpv6RangeByNetworkCidrAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1664,8 +1745,8 @@ abstract class ApiHelper { } - def addMiniStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMiniStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddMiniStorageAction() + def addIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddIscsiServerAction.class) Closure c) { + def a = new org.zstack.sdk.AddIscsiServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1691,8 +1772,8 @@ abstract class ApiHelper { } - def addMonToCephBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMonToCephBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddMonToCephBackupStorageAction() + def addJitSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddJitSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.AddJitSecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1718,8 +1799,8 @@ abstract class ApiHelper { } - def addMonToCephPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMonToCephPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddMonToCephPrimaryStorageAction() + def addKVMHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddKVMHostAction.class) Closure c) { + def a = new org.zstack.sdk.AddKVMHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1745,8 +1826,8 @@ abstract class ApiHelper { } - def addNfsPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddNfsPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddNfsPrimaryStorageAction() + def addKVMHostFromConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddKVMHostFromConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.AddKVMHostFromConfigFileAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1772,8 +1853,8 @@ abstract class ApiHelper { } - def addOssBucketFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddOssBucketFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.AddOssBucketFromRemoteAction() + def addLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLdapServerAction.class) Closure c) { + def a = new org.zstack.sdk.AddLdapServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1799,8 +1880,8 @@ abstract class ApiHelper { } - def addPciDeviceSpecToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddPciDeviceSpecToVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.AddPciDeviceSpecToVmInstanceAction() + def addLocalPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLocalPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddLocalPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1826,8 +1907,8 @@ abstract class ApiHelper { } - def addPreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddPreconfigurationTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.AddPreconfigurationTemplateAction() + def addLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLogConfigurationAction.class) Closure c) { + def a = new org.zstack.sdk.AddLogConfigurationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1853,8 +1934,8 @@ abstract class ApiHelper { } - def addRemoteCidrsToIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddRemoteCidrsToIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.AddRemoteCidrsToIPsecConnectionAction() + def addLogServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddLogServerAction.class) Closure c) { + def a = new org.zstack.sdk.AddLogServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1880,8 +1961,8 @@ abstract class ApiHelper { } - def addRendezvousPointToMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddRendezvousPointToMulticastRouterAction.class) Closure c) { - def a = new org.zstack.sdk.AddRendezvousPointToMulticastRouterAction() + def addMdevDeviceSpecToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMdevDeviceSpecToVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.AddMdevDeviceSpecToVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1907,8 +1988,8 @@ abstract class ApiHelper { } - def addResourceStackVmPortMonitor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddResourceStackVmPortMonitorAction.class) Closure c) { - def a = new org.zstack.sdk.AddResourceStackVmPortMonitorAction() + def addMiniStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMiniStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddMiniStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1934,8 +2015,8 @@ abstract class ApiHelper { } - def addSchedulerJobGroupToSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSchedulerJobGroupToSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.AddSchedulerJobGroupToSchedulerTriggerAction() + def addModel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddModelAction.class) Closure c) { + def a = new org.zstack.sdk.AddModelAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1961,8 +2042,8 @@ abstract class ApiHelper { } - def addSchedulerJobToSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSchedulerJobToSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.AddSchedulerJobToSchedulerTriggerAction() + def addModelCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddModelCenterAction.class) Closure c) { + def a = new org.zstack.sdk.AddModelCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -1988,8 +2069,8 @@ abstract class ApiHelper { } - def addSchedulerJobsToSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSchedulerJobsToSchedulerJobGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AddSchedulerJobsToSchedulerJobGroupAction() + def addModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.AddModelServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2015,8 +2096,8 @@ abstract class ApiHelper { } - def addSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSdnControllerAction.class) Closure c) { - def a = new org.zstack.sdk.AddSdnControllerAction() + def addMonToCephBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMonToCephBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddMonToCephBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2042,8 +2123,8 @@ abstract class ApiHelper { } - def addSecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSecurityGroupRuleAction.class) Closure c) { - def a = new org.zstack.sdk.AddSecurityGroupRuleAction() + def addMonToCephPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddMonToCephPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddMonToCephPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2069,8 +2150,8 @@ abstract class ApiHelper { } - def addServerGroupToLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddServerGroupToLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.AddServerGroupToLoadBalancerListenerAction() + def addNfsPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddNfsPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddNfsPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2096,8 +2177,8 @@ abstract class ApiHelper { } - def addSftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSftpBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddSftpBackupStorageAction() + def addNvmeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddNvmeServerAction.class) Closure c) { + def a = new org.zstack.sdk.AddNvmeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2123,8 +2204,8 @@ abstract class ApiHelper { } - def addSharedBlockGroupPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSharedBlockGroupPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddSharedBlockGroupPrimaryStorageAction() + def addOssBucketFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddOssBucketFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.AddOssBucketFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2150,8 +2231,8 @@ abstract class ApiHelper { } - def addSharedBlockToSharedBlockGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSharedBlockToSharedBlockGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AddSharedBlockToSharedBlockGroupAction() + def addPciDeviceSpecToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddPciDeviceSpecToVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.AddPciDeviceSpecToVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2177,8 +2258,8 @@ abstract class ApiHelper { } - def addSharedMountPointPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSharedMountPointPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddSharedMountPointPrimaryStorageAction() + def addPreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddPreconfigurationTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.AddPreconfigurationTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2204,8 +2285,8 @@ abstract class ApiHelper { } - def addSimulatorBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSimulatorBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddSimulatorBackupStorageAction() + def addProxyToResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddProxyToResourceAction.class) Closure c) { + def a = new org.zstack.sdk.AddProxyToResourceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2231,8 +2312,8 @@ abstract class ApiHelper { } - def addSimulatorHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSimulatorHostAction.class) Closure c) { - def a = new org.zstack.sdk.AddSimulatorHostAction() + def addRemoteCidrsToIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddRemoteCidrsToIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.AddRemoteCidrsToIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2258,8 +2339,8 @@ abstract class ApiHelper { } - def addSimulatorPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSimulatorPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.AddSimulatorPrimaryStorageAction() + def addRendezvousPointToMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddRendezvousPointToMulticastRouterAction.class) Closure c) { + def a = new org.zstack.sdk.AddRendezvousPointToMulticastRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2285,8 +2366,8 @@ abstract class ApiHelper { } - def addStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddStackTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.AddStackTemplateAction() + def addReservedIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddReservedIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.AddReservedIpRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2312,8 +2393,8 @@ abstract class ApiHelper { } - def addUserToGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddUserToGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AddUserToGroupAction() + def addResourceStackVmPortMonitor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddResourceStackVmPortMonitorAction.class) Closure c) { + def a = new org.zstack.sdk.AddResourceStackVmPortMonitorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2339,8 +2420,8 @@ abstract class ApiHelper { } - def addV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddV2VConversionHostAction.class) Closure c) { - def a = new org.zstack.sdk.AddV2VConversionHostAction() + def addResourcesToDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddResourcesToDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.AddResourcesToDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2366,8 +2447,8 @@ abstract class ApiHelper { } - def addVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVCenterAction.class) Closure c) { - def a = new org.zstack.sdk.AddVCenterAction() + def addSanSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSanSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.AddSanSecSecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2393,8 +2474,8 @@ abstract class ApiHelper { } - def addVRouterNetworksToFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVRouterNetworksToFlowMeterAction.class) Closure c) { - def a = new org.zstack.sdk.AddVRouterNetworksToFlowMeterAction() + def addSchedulerJobGroupToSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSchedulerJobGroupToSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.AddSchedulerJobGroupToSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2420,8 +2501,8 @@ abstract class ApiHelper { } - def addVRouterNetworksToOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVRouterNetworksToOspfAreaAction.class) Closure c) { - def a = new org.zstack.sdk.AddVRouterNetworksToOspfAreaAction() + def addSchedulerJobToSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSchedulerJobToSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.AddSchedulerJobToSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2447,8 +2528,8 @@ abstract class ApiHelper { } - def addVRouterRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVRouterRouteEntryAction.class) Closure c) { - def a = new org.zstack.sdk.AddVRouterRouteEntryAction() + def addSchedulerJobsToSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSchedulerJobsToSchedulerJobGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddSchedulerJobsToSchedulerJobGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2474,8 +2555,8 @@ abstract class ApiHelper { } - def addVmNicToLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmNicToLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.AddVmNicToLoadBalancerAction() + def addSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSdnControllerAction.class) Closure c) { + def a = new org.zstack.sdk.AddSdnControllerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2501,8 +2582,8 @@ abstract class ApiHelper { } - def addVmNicToSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmNicToSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AddVmNicToSecurityGroupAction() + def addSecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSecurityGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.AddSecurityGroupRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2528,8 +2609,8 @@ abstract class ApiHelper { } - def addVmToAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmToAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AddVmToAffinityGroupAction() + def addServerGroupToLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddServerGroupToLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.AddServerGroupToLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2555,8 +2636,8 @@ abstract class ApiHelper { } - def addXDragonHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddXDragonHostAction.class) Closure c) { - def a = new org.zstack.sdk.AddXDragonHostAction() + def addSftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSftpBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddSftpBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2582,8 +2663,8 @@ abstract class ApiHelper { } - def addZBox(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddZBoxAction.class) Closure c) { - def a = new org.zstack.sdk.AddZBoxAction() + def addSharedBlockGroupPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSharedBlockGroupPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddSharedBlockGroupPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2609,8 +2690,8 @@ abstract class ApiHelper { } - def applyDRSAdvice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ApplyDRSAdviceAction.class) Closure c) { - def a = new org.zstack.sdk.ApplyDRSAdviceAction() + def addSharedBlockToSharedBlockGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSharedBlockToSharedBlockGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddSharedBlockToSharedBlockGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2636,8 +2717,8 @@ abstract class ApiHelper { } - def applyRuleSetChanges(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ApplyRuleSetChangesAction.class) Closure c) { - def a = new org.zstack.sdk.ApplyRuleSetChangesAction() + def addSharedMountPointPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSharedMountPointPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddSharedMountPointPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2663,8 +2744,8 @@ abstract class ApiHelper { } - def applyTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ApplyTemplateConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ApplyTemplateConfigAction() + def addSimulatorBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSimulatorBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddSimulatorBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2690,8 +2771,8 @@ abstract class ApiHelper { } - def attachAliyunDiskToEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAliyunDiskToEcsAction.class) Closure c) { - def a = new org.zstack.sdk.AttachAliyunDiskToEcsAction() + def addSimulatorHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSimulatorHostAction.class) Closure c) { + def a = new org.zstack.sdk.AddSimulatorHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2717,8 +2798,8 @@ abstract class ApiHelper { } - def attachAliyunKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAliyunKeyAction.class) Closure c) { - def a = new org.zstack.sdk.AttachAliyunKeyAction() + def addSimulatorPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddSimulatorPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.AddSimulatorPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2744,8 +2825,8 @@ abstract class ApiHelper { } - def attachAppBuildSystemToZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAppBuildSystemToZoneAction.class) Closure c) { - def a = new org.zstack.sdk.AttachAppBuildSystemToZoneAction() + def addStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddStackTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.AddStackTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2771,8 +2852,8 @@ abstract class ApiHelper { } - def attachAutoScalingTemplateToGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAutoScalingTemplateToGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AttachAutoScalingTemplateToGroupAction() + def addStorageProtocol(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddStorageProtocolAction.class) Closure c) { + def a = new org.zstack.sdk.AddStorageProtocolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2798,8 +2879,8 @@ abstract class ApiHelper { } - def attachBackupStorageToZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBackupStorageToZoneAction.class) Closure c) { - def a = new org.zstack.sdk.AttachBackupStorageToZoneAction() + def addUserToGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddUserToGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddUserToGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2825,8 +2906,8 @@ abstract class ApiHelper { } - def attachBareMetal2GatewayToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBareMetal2GatewayToClusterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachBareMetal2GatewayToClusterAction() + def addV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddV2VConversionHostAction.class) Closure c) { + def a = new org.zstack.sdk.AddV2VConversionHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2852,8 +2933,8 @@ abstract class ApiHelper { } - def attachBareMetal2ProvisionNetworkToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBareMetal2ProvisionNetworkToClusterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachBareMetal2ProvisionNetworkToClusterAction() + def addVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVCenterAction.class) Closure c) { + def a = new org.zstack.sdk.AddVCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2879,8 +2960,8 @@ abstract class ApiHelper { } - def attachBaremetalPxeServerToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBaremetalPxeServerToClusterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachBaremetalPxeServerToClusterAction() + def addVRouterNetworksToFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVRouterNetworksToFlowMeterAction.class) Closure c) { + def a = new org.zstack.sdk.AddVRouterNetworksToFlowMeterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2906,8 +2987,8 @@ abstract class ApiHelper { } - def attachCCSCertificateToUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachCCSCertificateToUserAction.class) Closure c) { - def a = new org.zstack.sdk.AttachCCSCertificateToUserAction() + def addVRouterNetworksToOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVRouterNetworksToOspfAreaAction.class) Closure c) { + def a = new org.zstack.sdk.AddVRouterNetworksToOspfAreaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2933,8 +3014,8 @@ abstract class ApiHelper { } - def attachDataVolumeToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachDataVolumeToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachDataVolumeToVmAction() + def addVRouterRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVRouterRouteEntryAction.class) Closure c) { + def a = new org.zstack.sdk.AddVRouterRouteEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2960,8 +3041,8 @@ abstract class ApiHelper { } - def attachEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachEipAction.class) Closure c) { - def a = new org.zstack.sdk.AttachEipAction() + def addVmNicToLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmNicToLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.AddVmNicToLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -2987,8 +3068,8 @@ abstract class ApiHelper { } - def attachFirewallRuleSetToL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachFirewallRuleSetToL3Action.class) Closure c) { - def a = new org.zstack.sdk.AttachFirewallRuleSetToL3Action() + def addVmNicToSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmNicToSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddVmNicToSecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3014,8 +3095,8 @@ abstract class ApiHelper { } - def attachGuestToolsIsoToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachGuestToolsIsoToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachGuestToolsIsoToVmAction() + def addVmToAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmToAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddVmToAffinityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3041,8 +3122,8 @@ abstract class ApiHelper { } - def attachHybridEipToEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachHybridEipToEcsAction.class) Closure c) { - def a = new org.zstack.sdk.AttachHybridEipToEcsAction() + def addVmToVmSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddVmToVmSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AddVmToVmSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3068,8 +3149,8 @@ abstract class ApiHelper { } - def attachHybridKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachHybridKeyAction.class) Closure c) { - def a = new org.zstack.sdk.AttachHybridKeyAction() + def addXDragonHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddXDragonHostAction.class) Closure c) { + def a = new org.zstack.sdk.AddXDragonHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3095,8 +3176,8 @@ abstract class ApiHelper { } - def attachIscsiServerToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachIscsiServerToClusterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachIscsiServerToClusterAction() + def addZBox(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AddZBoxAction.class) Closure c) { + def a = new org.zstack.sdk.AddZBoxAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3122,8 +3203,8 @@ abstract class ApiHelper { } - def attachIsoToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachIsoToVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.AttachIsoToVmInstanceAction() + def allocateHostResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AllocateHostResourceAction.class) Closure c) { + def a = new org.zstack.sdk.AllocateHostResourceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3149,8 +3230,8 @@ abstract class ApiHelper { } - def attachL2NetworkToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL2NetworkToClusterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachL2NetworkToClusterAction() + def applyDRSAdvice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ApplyDRSAdviceAction.class) Closure c) { + def a = new org.zstack.sdk.ApplyDRSAdviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3176,8 +3257,8 @@ abstract class ApiHelper { } - def attachL3NetworkToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL3NetworkToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachL3NetworkToVmAction() + def applyRuleSetChanges(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ApplyRuleSetChangesAction.class) Closure c) { + def a = new org.zstack.sdk.ApplyRuleSetChangesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3203,8 +3284,8 @@ abstract class ApiHelper { } - def attachL3NetworkToVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL3NetworkToVmNicAction.class) Closure c) { - def a = new org.zstack.sdk.AttachL3NetworkToVmNicAction() + def applyTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ApplyTemplateConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ApplyTemplateConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3230,8 +3311,8 @@ abstract class ApiHelper { } - def attachL3NetworksToIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL3NetworksToIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.AttachL3NetworksToIPsecConnectionAction() + def attachAliyunDiskToEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAliyunDiskToEcsAction.class) Closure c) { + def a = new org.zstack.sdk.AttachAliyunDiskToEcsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3257,8 +3338,8 @@ abstract class ApiHelper { } - def attachMdevDeviceToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachMdevDeviceToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachMdevDeviceToVmAction() + def attachAliyunKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAliyunKeyAction.class) Closure c) { + def a = new org.zstack.sdk.AttachAliyunKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3284,8 +3365,8 @@ abstract class ApiHelper { } - def attachMonitorTriggerToTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachMonitorTriggerActionToTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.AttachMonitorTriggerActionToTriggerAction() + def attachAppBuildSystemToZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAppBuildSystemToZoneAction.class) Closure c) { + def a = new org.zstack.sdk.AttachAppBuildSystemToZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3311,8 +3392,8 @@ abstract class ApiHelper { } - def attachNetworkServiceToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachNetworkServiceToL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.AttachNetworkServiceToL3NetworkAction() + def attachAutoScalingTemplateToGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachAutoScalingTemplateToGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AttachAutoScalingTemplateToGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3338,8 +3419,8 @@ abstract class ApiHelper { } - def attachOssBucketToEcsDataCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachOssBucketToEcsDataCenterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachOssBucketToEcsDataCenterAction() + def attachBackupStorageToZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBackupStorageToZoneAction.class) Closure c) { + def a = new org.zstack.sdk.AttachBackupStorageToZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3365,8 +3446,8 @@ abstract class ApiHelper { } - def attachPciDeviceToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPciDeviceToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPciDeviceToVmAction() + def attachBareMetal2GatewayToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBareMetal2GatewayToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachBareMetal2GatewayToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3392,8 +3473,8 @@ abstract class ApiHelper { } - def attachPoliciesToUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPoliciesToUserAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPoliciesToUserAction() + def attachBareMetal2ProvisionNetworkToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBareMetal2ProvisionNetworkToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachBareMetal2ProvisionNetworkToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3419,8 +3500,8 @@ abstract class ApiHelper { } - def attachPolicyRouteRuleSetToL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPolicyRouteRuleSetToL3Action.class) Closure c) { - def a = new org.zstack.sdk.AttachPolicyRouteRuleSetToL3Action() + def attachBaremetalPxeServerToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachBaremetalPxeServerToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachBaremetalPxeServerToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3446,8 +3527,8 @@ abstract class ApiHelper { } - def attachPolicyToUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPolicyToUserAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPolicyToUserAction() + def attachCCSCertificateToUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachCCSCertificateToUserAction.class) Closure c) { + def a = new org.zstack.sdk.AttachCCSCertificateToUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3473,8 +3554,8 @@ abstract class ApiHelper { } - def attachPolicyToUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPolicyToUserGroupAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPolicyToUserGroupAction() + def attachDataVolumeToHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachDataVolumeToHostAction.class) Closure c) { + def a = new org.zstack.sdk.AttachDataVolumeToHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3500,8 +3581,8 @@ abstract class ApiHelper { } - def attachPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPortForwardingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPortForwardingRuleAction() + def attachDataVolumeToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachDataVolumeToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachDataVolumeToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3527,8 +3608,8 @@ abstract class ApiHelper { } - def attachPriceTableToAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPriceTableToAccountAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPriceTableToAccountAction() + def attachEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachEipAction.class) Closure c) { + def a = new org.zstack.sdk.AttachEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3554,8 +3635,8 @@ abstract class ApiHelper { } - def attachPrimaryStorageToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPrimaryStorageToClusterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachPrimaryStorageToClusterAction() + def attachFirewallRuleSetToL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachFirewallRuleSetToL3Action.class) Closure c) { + def a = new org.zstack.sdk.AttachFirewallRuleSetToL3Action() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3581,8 +3662,8 @@ abstract class ApiHelper { } - def attachScsiLunToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachScsiLunToVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.AttachScsiLunToVmInstanceAction() + def attachGuestToolsIsoToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachGuestToolsIsoToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachGuestToolsIsoToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3608,8 +3689,8 @@ abstract class ApiHelper { } - def attachSecurityGroupToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachSecurityGroupToL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.AttachSecurityGroupToL3NetworkAction() + def attachHybridEipToEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachHybridEipToEcsAction.class) Closure c) { + def a = new org.zstack.sdk.AttachHybridEipToEcsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3635,8 +3716,8 @@ abstract class ApiHelper { } - def attachTagToResources(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachTagToResourcesAction.class) Closure c) { - def a = new org.zstack.sdk.AttachTagToResourcesAction() + def attachHybridKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachHybridKeyAction.class) Closure c) { + def a = new org.zstack.sdk.AttachHybridKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3662,8 +3743,8 @@ abstract class ApiHelper { } - def attachUsbDeviceToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachUsbDeviceToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachUsbDeviceToVmAction() + def attachIscsiServerToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachIscsiServerToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachIscsiServerToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3689,8 +3770,8 @@ abstract class ApiHelper { } - def attachVRouterRouteTableToVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachVRouterRouteTableToVRouterAction.class) Closure c) { - def a = new org.zstack.sdk.AttachVRouterRouteTableToVRouterAction() + def attachIsoToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachIsoToVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.AttachIsoToVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3716,8 +3797,8 @@ abstract class ApiHelper { } - def attachVmNicToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachVmNicToVmAction.class) Closure c) { - def a = new org.zstack.sdk.AttachVmNicToVmAction() + def attachL2NetworkToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL2NetworkToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachL2NetworkToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3743,8 +3824,8 @@ abstract class ApiHelper { } - def backupDatabaseToPublicCloud(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BackupDatabaseToPublicCloudAction.class) Closure c) { - def a = new org.zstack.sdk.BackupDatabaseToPublicCloudAction() + def attachL3NetworkToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL3NetworkToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachL3NetworkToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3770,8 +3851,8 @@ abstract class ApiHelper { } - def backupStorageMigrateImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BackupStorageMigrateImageAction.class) Closure c) { - def a = new org.zstack.sdk.BackupStorageMigrateImageAction() + def attachL3NetworkToVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL3NetworkToVmNicAction.class) Closure c) { + def a = new org.zstack.sdk.AttachL3NetworkToVmNicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3797,8 +3878,8 @@ abstract class ApiHelper { } - def batchAddBareMetal2IpmiChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchAddBareMetal2IpmiChassisAction.class) Closure c) { - def a = new org.zstack.sdk.BatchAddBareMetal2IpmiChassisAction() + def attachL3NetworksToIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachL3NetworksToIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.AttachL3NetworksToIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3824,8 +3905,8 @@ abstract class ApiHelper { } - def batchCreateBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchCreateBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.BatchCreateBaremetalChassisAction() + def attachMdevDeviceToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachMdevDeviceToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachMdevDeviceToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3851,8 +3932,8 @@ abstract class ApiHelper { } - def batchDeleteVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchDeleteVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.BatchDeleteVolumeSnapshotAction() + def attachMonitorTriggerToTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachMonitorTriggerActionToTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.AttachMonitorTriggerActionToTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3878,8 +3959,8 @@ abstract class ApiHelper { } - def batchQuery(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchQueryAction.class) Closure c) { - def a = new org.zstack.sdk.BatchQueryAction() + def attachNetworkServiceToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachNetworkServiceToL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.AttachNetworkServiceToL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3905,8 +3986,8 @@ abstract class ApiHelper { } - def bootstrapMiniHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BootstrapMiniHostAction.class) Closure c) { - def a = new org.zstack.sdk.BootstrapMiniHostAction() + def attachNicToBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachNicToBondingAction.class) Closure c) { + def a = new org.zstack.sdk.AttachNicToBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3932,8 +4013,8 @@ abstract class ApiHelper { } - def calculateAccountBillingSpending(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateAccountBillingSpendingAction.class) Closure c) { - def a = new org.zstack.sdk.CalculateAccountBillingSpendingAction() + def attachNvmeServerToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachNvmeServerToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachNvmeServerToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3959,8 +4040,8 @@ abstract class ApiHelper { } - def calculateAccountSpending(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateAccountSpendingAction.class) Closure c) { - def a = new org.zstack.sdk.CalculateAccountSpendingAction() + def attachOssBucketToEcsDataCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachOssBucketToEcsDataCenterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachOssBucketToEcsDataCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -3986,8 +4067,62 @@ abstract class ApiHelper { } - def calculateResourceSpending(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateResourceSpendingAction.class) Closure c) { - def a = new org.zstack.sdk.CalculateResourceSpendingAction() + def attachPciDeviceToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPciDeviceToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPciDeviceToVmAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def attachPoliciesToUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPoliciesToUserAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPoliciesToUserAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def attachPolicyRouteRuleSetToL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPolicyRouteRuleSetToL3Action.class) Closure c) { + def a = new org.zstack.sdk.AttachPolicyRouteRuleSetToL3Action() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4013,8 +4148,8 @@ abstract class ApiHelper { } - def cancelLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CancelLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.CancelLongJobAction() + def attachPolicyToUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPolicyToUserAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPolicyToUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4040,8 +4175,8 @@ abstract class ApiHelper { } - def changeAccessControlListRedirectRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccessControlListRedirectRuleAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAccessControlListRedirectRuleAction() + def attachPolicyToUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPolicyToUserGroupAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPolicyToUserGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4067,8 +4202,8 @@ abstract class ApiHelper { } - def changeAccessControlListServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccessControlListServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAccessControlListServerGroupAction() + def attachPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPortForwardingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPortForwardingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4094,8 +4229,8 @@ abstract class ApiHelper { } - def changeAccessKeyState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccessKeyStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAccessKeyStateAction() + def attachPriceTableToAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPriceTableToAccountAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPriceTableToAccountAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4121,8 +4256,8 @@ abstract class ApiHelper { } - def changeAccountPriceTableBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccountPriceTableBindingAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAccountPriceTableBindingAction() + def attachPrimaryStorageToCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachPrimaryStorageToClusterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachPrimaryStorageToClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4148,8 +4283,8 @@ abstract class ApiHelper { } - def changeAffinityGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAffinityGroupStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAffinityGroupStateAction() + def attachProvisionNicToBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachProvisionNicToBondingAction.class) Closure c) { + def a = new org.zstack.sdk.AttachProvisionNicToBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4175,8 +4310,8 @@ abstract class ApiHelper { } - def changeAppBuildSystemState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAppBuildSystemStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAppBuildSystemStateAction() + def attachScsiLunToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachScsiLunToVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.AttachScsiLunToVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4202,8 +4337,8 @@ abstract class ApiHelper { } - def changeAutoScalingGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAutoScalingGroupStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeAutoScalingGroupStateAction() + def attachSecurityGroupToL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachSecurityGroupToL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.AttachSecurityGroupToL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4229,8 +4364,8 @@ abstract class ApiHelper { } - def changeBackupStorageState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBackupStorageStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBackupStorageStateAction() + def attachServiceToObservabilityServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachServiceToObservabilityServerAction.class) Closure c) { + def a = new org.zstack.sdk.AttachServiceToObservabilityServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4256,8 +4391,8 @@ abstract class ApiHelper { } - def changeBareMetal2ChassisOfferingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2ChassisOfferingStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBareMetal2ChassisOfferingStateAction() + def attachSshKeyPairToVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachSshKeyPairToVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.AttachSshKeyPairToVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4283,8 +4418,8 @@ abstract class ApiHelper { } - def changeBareMetal2ChassisState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2ChassisStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBareMetal2ChassisStateAction() + def attachTagToResources(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachTagToResourcesAction.class) Closure c) { + def a = new org.zstack.sdk.AttachTagToResourcesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4310,8 +4445,8 @@ abstract class ApiHelper { } - def changeBareMetal2GatewayCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2GatewayClusterAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBareMetal2GatewayClusterAction() + def attachUsbDeviceToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachUsbDeviceToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachUsbDeviceToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4337,8 +4472,8 @@ abstract class ApiHelper { } - def changeBareMetal2GatewayState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2GatewayStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBareMetal2GatewayStateAction() + def attachUserDefinedXmlHookScriptToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachUserDefinedXmlHookScriptToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachUserDefinedXmlHookScriptToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4364,8 +4499,8 @@ abstract class ApiHelper { } - def changeBareMetal2InstancePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2InstancePasswordAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBareMetal2InstancePasswordAction() + def attachVRouterRouteTableToVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachVRouterRouteTableToVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.AttachVRouterRouteTableToVRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4391,8 +4526,8 @@ abstract class ApiHelper { } - def changeBareMetal2ProvisionNetworkState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2ProvisionNetworkStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBareMetal2ProvisionNetworkStateAction() + def attachVipToLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachVipToLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.AttachVipToLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4418,8 +4553,8 @@ abstract class ApiHelper { } - def changeBaremetalChassisState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBaremetalChassisStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeBaremetalChassisStateAction() + def attachVipToVpcSharedQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachVipToVpcSharedQosAction.class) Closure c) { + def a = new org.zstack.sdk.AttachVipToVpcSharedQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4445,8 +4580,8 @@ abstract class ApiHelper { } - def changeClusterState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeClusterStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeClusterStateAction() + def attachVmNicToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.AttachVmNicToVmAction.class) Closure c) { + def a = new org.zstack.sdk.AttachVmNicToVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4472,8 +4607,8 @@ abstract class ApiHelper { } - def changeDiskOfferingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeDiskOfferingStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeDiskOfferingStateAction() + def backupDatabaseToPublicCloud(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BackupDatabaseToPublicCloudAction.class) Closure c) { + def a = new org.zstack.sdk.BackupDatabaseToPublicCloudAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4499,8 +4634,8 @@ abstract class ApiHelper { } - def changeEipState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeEipStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeEipStateAction() + def backupStorageMigrateImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BackupStorageMigrateImageAction.class) Closure c) { + def a = new org.zstack.sdk.BackupStorageMigrateImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4526,8 +4661,8 @@ abstract class ApiHelper { } - def changeFirewallRuleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeFirewallRuleStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeFirewallRuleStateAction() + def batchAddBareMetal2IpmiChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchAddBareMetal2IpmiChassisAction.class) Closure c) { + def a = new org.zstack.sdk.BatchAddBareMetal2IpmiChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4553,8 +4688,8 @@ abstract class ApiHelper { } - def changeHostPassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostPasswordAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeHostPasswordAction() + def batchCreateBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchCreateBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.BatchCreateBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4580,8 +4715,8 @@ abstract class ApiHelper { } - def changeHostState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeHostStateAction() + def batchDeleteVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchDeleteVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.BatchDeleteVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4607,8 +4742,8 @@ abstract class ApiHelper { } - def changeIPSecConnectionState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeIPSecConnectionStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeIPSecConnectionStateAction() + def batchQuery(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchQueryAction.class) Closure c) { + def a = new org.zstack.sdk.BatchQueryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4634,8 +4769,8 @@ abstract class ApiHelper { } - def changeImageState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeImageStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeImageStateAction() + def batchSyncVolumeSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BatchSyncVolumeSizeAction.class) Closure c) { + def a = new org.zstack.sdk.BatchSyncVolumeSizeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4661,8 +4796,8 @@ abstract class ApiHelper { } - def changeInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeInstanceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeInstanceOfferingAction() + def bindModelToService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BindModelToServiceAction.class) Closure c) { + def a = new org.zstack.sdk.BindModelToServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4688,8 +4823,8 @@ abstract class ApiHelper { } - def changeInstanceOfferingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeInstanceOfferingStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeInstanceOfferingStateAction() + def bootstrapMiniHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.BootstrapMiniHostAction.class) Closure c) { + def a = new org.zstack.sdk.BootstrapMiniHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4715,8 +4850,8 @@ abstract class ApiHelper { } - def changeL3NetworkState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeL3NetworkStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeL3NetworkStateAction() + def calculateAccountBillingSpending(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateAccountBillingSpendingAction.class) Closure c) { + def a = new org.zstack.sdk.CalculateAccountBillingSpendingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4742,8 +4877,8 @@ abstract class ApiHelper { } - def changeLoadBalancerBackendServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeLoadBalancerBackendServerAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeLoadBalancerBackendServerAction() + def calculateAccountSpending(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateAccountSpendingAction.class) Closure c) { + def a = new org.zstack.sdk.CalculateAccountSpendingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4769,8 +4904,8 @@ abstract class ApiHelper { } - def changeLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeLoadBalancerListenerAction() + def calculateImageHash(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateImageHashAction.class) Closure c) { + def a = new org.zstack.sdk.CalculateImageHashAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4796,8 +4931,8 @@ abstract class ApiHelper { } - def changeMediaState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMediaStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeMediaStateAction() + def calculateResourceSpending(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CalculateResourceSpendingAction.class) Closure c) { + def a = new org.zstack.sdk.CalculateResourceSpendingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4823,8 +4958,8 @@ abstract class ApiHelper { } - def changeMonitorTriggerStateAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMonitorTriggerActionStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeMonitorTriggerActionStateAction() + def cancelLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CancelLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.CancelLongJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4850,8 +4985,8 @@ abstract class ApiHelper { } - def changeMonitorTriggerState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMonitorTriggerStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeMonitorTriggerStateAction() + def changeAccessControlListRedirectRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccessControlListRedirectRuleAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAccessControlListRedirectRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4877,8 +5012,8 @@ abstract class ApiHelper { } - def changeMulticastRouterState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMulticastRouterStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeMulticastRouterStateAction() + def changeAccessControlListServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccessControlListServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAccessControlListServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4904,8 +5039,8 @@ abstract class ApiHelper { } - def changePortForwardingRuleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePortForwardingRuleStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangePortForwardingRuleStateAction() + def changeAccessKeyState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccessKeyStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAccessKeyStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4931,8 +5066,8 @@ abstract class ApiHelper { } - def changePortMirrorState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePortMirrorStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangePortMirrorStateAction() + def changeAccountPriceTableBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAccountPriceTableBindingAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAccountPriceTableBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4958,8 +5093,8 @@ abstract class ApiHelper { } - def changePreconfigurationTemplateState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePreconfigurationTemplateStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangePreconfigurationTemplateStateAction() + def changeAffinityGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAffinityGroupStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAffinityGroupStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -4985,8 +5120,8 @@ abstract class ApiHelper { } - def changePrimaryStorageState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePrimaryStorageStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangePrimaryStorageStateAction() + def changeAppBuildSystemState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAppBuildSystemStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAppBuildSystemStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5012,8 +5147,8 @@ abstract class ApiHelper { } - def changeResourceOwner(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeResourceOwnerAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeResourceOwnerAction() + def changeAutoScalingGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeAutoScalingGroupStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeAutoScalingGroupStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5039,8 +5174,8 @@ abstract class ApiHelper { } - def changeSchedulerState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSchedulerStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeSchedulerStateAction() + def changeBackupStorageState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBackupStorageStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBackupStorageStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5066,8 +5201,8 @@ abstract class ApiHelper { } - def changeSecretResourcePoolState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecretResourcePoolStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeSecretResourcePoolStateAction() + def changeBareMetal2ChassisOfferingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2ChassisOfferingStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBareMetal2ChassisOfferingStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5093,8 +5228,8 @@ abstract class ApiHelper { } - def changeSecurityGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecurityGroupStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeSecurityGroupStateAction() + def changeBareMetal2ChassisState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2ChassisStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBareMetal2ChassisStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5120,8 +5255,8 @@ abstract class ApiHelper { } - def changeSecurityMachineState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecurityMachineStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeSecurityMachineStateAction() + def changeBareMetal2GatewayCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2GatewayClusterAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBareMetal2GatewayClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5147,8 +5282,8 @@ abstract class ApiHelper { } - def changeV2VConversionHostState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeV2VConversionHostStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeV2VConversionHostStateAction() + def changeBareMetal2GatewayState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2GatewayStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBareMetal2GatewayStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5174,8 +5309,8 @@ abstract class ApiHelper { } - def changeVipState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVipStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVipStateAction() + def changeBareMetal2InstancePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2InstancePasswordAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBareMetal2InstancePasswordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5201,8 +5336,8 @@ abstract class ApiHelper { } - def changeVmImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmImageAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVmImageAction() + def changeBareMetal2ProvisionNetworkState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBareMetal2ProvisionNetworkStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBareMetal2ProvisionNetworkStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5228,8 +5363,8 @@ abstract class ApiHelper { } - def changeVmNicNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmNicNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVmNicNetworkAction() + def changeBaremetalChassisState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeBaremetalChassisStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeBaremetalChassisStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5255,8 +5390,8 @@ abstract class ApiHelper { } - def changeVmNicType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmNicTypeAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVmNicTypeAction() + def changeClusterState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeClusterStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeClusterStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5282,8 +5417,8 @@ abstract class ApiHelper { } - def changeVmPassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmPasswordAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVmPasswordAction() + def changeDiskOfferingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeDiskOfferingStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeDiskOfferingStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5309,8 +5444,8 @@ abstract class ApiHelper { } - def changeVolumeState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVolumeStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVolumeStateAction() + def changeEipState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeEipStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeEipStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5336,8 +5471,8 @@ abstract class ApiHelper { } - def changeVpcHaGroupMonitorIps(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVpcHaGroupMonitorIpsAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeVpcHaGroupMonitorIpsAction() + def changeFirewallRuleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeFirewallRuleStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeFirewallRuleStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5363,8 +5498,8 @@ abstract class ApiHelper { } - def changeZoneState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeZoneStateAction.class) Closure c) { - def a = new org.zstack.sdk.ChangeZoneStateAction() + def changeHostNetworkInterfaceLldpMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostNetworkInterfaceLldpModeAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeHostNetworkInterfaceLldpModeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5390,8 +5525,8 @@ abstract class ApiHelper { } - def checkApiPermission(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckApiPermissionAction.class) Closure c) { - def a = new org.zstack.sdk.CheckApiPermissionAction() + def changeHostPassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostPasswordAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeHostPasswordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5417,8 +5552,8 @@ abstract class ApiHelper { } - def checkBareMetal2IpmiChassisConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBareMetal2IpmiChassisConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.CheckBareMetal2IpmiChassisConfigFileAction() + def changeHostState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeHostStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeHostStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5444,8 +5579,8 @@ abstract class ApiHelper { } - def checkBaremetalChassisConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBaremetalChassisConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.CheckBaremetalChassisConfigFileAction() + def changeIPSecConnectionState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeIPSecConnectionStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeIPSecConnectionStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5471,8 +5606,8 @@ abstract class ApiHelper { } - def checkBatchDataIntegrity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBatchDataIntegrityAction.class) Closure c) { - def a = new org.zstack.sdk.CheckBatchDataIntegrityAction() + def changeIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5498,8 +5633,8 @@ abstract class ApiHelper { } - def checkBuildAppParameters(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBuildAppParametersAction.class) Closure c) { - def a = new org.zstack.sdk.CheckBuildAppParametersAction() + def changeImageState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeImageStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeImageStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5525,8 +5660,8 @@ abstract class ApiHelper { } - def checkElaborationContent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckElaborationContentAction.class) Closure c) { - def a = new org.zstack.sdk.CheckElaborationContentAction() + def changeInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeInstanceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeInstanceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5552,8 +5687,8 @@ abstract class ApiHelper { } - def checkFirewallRuleConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckFirewallRuleConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.CheckFirewallRuleConfigFileAction() + def changeInstanceOfferingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeInstanceOfferingStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeInstanceOfferingStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5579,8 +5714,8 @@ abstract class ApiHelper { } - def checkIpAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckIpAvailabilityAction.class) Closure c) { - def a = new org.zstack.sdk.CheckIpAvailabilityAction() + def changeL2NetworkVlanId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeL2NetworkVlanIdAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeL2NetworkVlanIdAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5606,8 +5741,8 @@ abstract class ApiHelper { } - def checkKVMHostConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckKVMHostConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.CheckKVMHostConfigFileAction() + def changeL3NetworkDhcpIpAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeL3NetworkDhcpIpAddressAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeL3NetworkDhcpIpAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5633,8 +5768,8 @@ abstract class ApiHelper { } - def checkResourcePermission(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckResourcePermissionAction.class) Closure c) { - def a = new org.zstack.sdk.CheckResourcePermissionAction() + def changeL3NetworkState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeL3NetworkStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeL3NetworkStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5660,8 +5795,8 @@ abstract class ApiHelper { } - def checkScsiLunClusterStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckScsiLunClusterStatusAction.class) Closure c) { - def a = new org.zstack.sdk.CheckScsiLunClusterStatusAction() + def changeLoadBalancerBackendServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeLoadBalancerBackendServerAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeLoadBalancerBackendServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5687,8 +5822,8 @@ abstract class ApiHelper { } - def checkStackTemplateParameters(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckStackTemplateParametersAction.class) Closure c) { - def a = new org.zstack.sdk.CheckStackTemplateParametersAction() + def changeLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5714,8 +5849,8 @@ abstract class ApiHelper { } - def checkVolumeSnapshotGroupAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckVolumeSnapshotGroupAvailabilityAction.class) Closure c) { - def a = new org.zstack.sdk.CheckVolumeSnapshotGroupAvailabilityAction() + def changeMediaState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMediaStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeMediaStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5741,8 +5876,8 @@ abstract class ApiHelper { } - def cleanInvalidLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanInvalidLdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.CleanInvalidLdapBindingAction() + def changeMonitorTriggerStateAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMonitorTriggerActionStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeMonitorTriggerActionStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5768,8 +5903,8 @@ abstract class ApiHelper { } - def cleanInvalidLdapIAM2Binding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanInvalidLdapIAM2BindingAction.class) Closure c) { - def a = new org.zstack.sdk.CleanInvalidLdapIAM2BindingAction() + def changeMonitorTriggerState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMonitorTriggerStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeMonitorTriggerStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5795,8 +5930,8 @@ abstract class ApiHelper { } - def cleanLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.CleanLongJobAction() + def changeMulticastRouterState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeMulticastRouterStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeMulticastRouterStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5822,8 +5957,8 @@ abstract class ApiHelper { } - def cleanQueue(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanQueueAction.class) Closure c) { - def a = new org.zstack.sdk.CleanQueueAction() + def changePortForwardingRuleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePortForwardingRuleStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangePortForwardingRuleStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5849,8 +5984,8 @@ abstract class ApiHelper { } - def cleanUpBaremetalChassisBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpBaremetalChassisBondingAction.class) Closure c) { - def a = new org.zstack.sdk.CleanUpBaremetalChassisBondingAction() + def changePortMirrorState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePortMirrorStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangePortMirrorStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5876,8 +6011,8 @@ abstract class ApiHelper { } - def cleanUpImageCacheOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpImageCacheOnPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.CleanUpImageCacheOnPrimaryStorageAction() + def changePreconfigurationTemplateState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePreconfigurationTemplateStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangePreconfigurationTemplateStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5903,8 +6038,8 @@ abstract class ApiHelper { } - def cleanUpTrashOnBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpTrashOnBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.CleanUpTrashOnBackupStorageAction() + def changePrimaryStorageState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangePrimaryStorageStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangePrimaryStorageStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5930,8 +6065,8 @@ abstract class ApiHelper { } - def cleanUpTrashOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpTrashOnPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.CleanUpTrashOnPrimaryStorageAction() + def changeResourceOwner(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeResourceOwnerAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeResourceOwnerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5957,8 +6092,8 @@ abstract class ApiHelper { } - def cleanV2VConversionCache(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanV2VConversionCacheAction.class) Closure c) { - def a = new org.zstack.sdk.CleanV2VConversionCacheAction() + def changeSchedulerState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSchedulerStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSchedulerStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -5984,8 +6119,8 @@ abstract class ApiHelper { } - def cleanupBillingUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanupBillingUsageAction.class) Closure c) { - def a = new org.zstack.sdk.CleanupBillingUsageAction() + def changeSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSdnControllerAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSdnControllerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6011,8 +6146,8 @@ abstract class ApiHelper { } - def cloneVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CloneVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.CloneVmInstanceAction() + def changeSecretResourcePoolState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecretResourcePoolStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSecretResourcePoolStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6038,8 +6173,8 @@ abstract class ApiHelper { } - def convertVmFromForeignHypervisor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ConvertVmFromForeignHypervisorAction.class) Closure c) { - def a = new org.zstack.sdk.ConvertVmFromForeignHypervisorAction() + def changeSecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecurityGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSecurityGroupRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6065,8 +6200,8 @@ abstract class ApiHelper { } - def createAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAccessControlListAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAccessControlListAction() + def changeSecurityGroupRuleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecurityGroupRuleStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSecurityGroupRuleStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6092,8 +6227,8 @@ abstract class ApiHelper { } - def createAccessKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAccessKeyAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAccessKeyAction() + def changeSecurityGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecurityGroupStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSecurityGroupStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6119,8 +6254,8 @@ abstract class ApiHelper { } - def createAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAccountAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAccountAction() + def changeSecurityMachineState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSecurityMachineStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSecurityMachineStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6146,8 +6281,8 @@ abstract class ApiHelper { } - def createAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAffinityGroupAction() + def changeSlbGroupDeployType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSlbGroupDeployTypeAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSlbGroupDeployTypeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6173,8 +6308,8 @@ abstract class ApiHelper { } - def createAliyunDiskFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunDiskFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunDiskFromRemoteAction() + def changeSlbGroupMonitorIps(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeSlbGroupMonitorIpsAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeSlbGroupMonitorIpsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6200,8 +6335,8 @@ abstract class ApiHelper { } - def createAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasAccessGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunNasAccessGroupAction() + def changeV2VConversionHostState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeV2VConversionHostStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeV2VConversionHostStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6227,8 +6362,8 @@ abstract class ApiHelper { } - def createAliyunNasAccessGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasAccessGroupRuleAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunNasAccessGroupRuleAction() + def changeVfNicHaState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVfNicHaStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVfNicHaStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6254,8 +6389,8 @@ abstract class ApiHelper { } - def createAliyunNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasFileSystemAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunNasFileSystemAction() + def changeVipState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVipStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVipStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6281,8 +6416,8 @@ abstract class ApiHelper { } - def createAliyunNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasMountTargetAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunNasMountTargetAction() + def changeVmImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmImageAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6308,8 +6443,8 @@ abstract class ApiHelper { } - def createAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunProxyVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunProxyVSwitchAction() + def changeVmNicNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmNicNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmNicNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6335,8 +6470,8 @@ abstract class ApiHelper { } - def createAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunProxyVpcAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunProxyVpcAction() + def changeVmNicSecurityPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmNicSecurityPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmNicSecurityPolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6362,8 +6497,8 @@ abstract class ApiHelper { } - def createAliyunRouterInterfaceRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunRouterInterfaceRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunRouterInterfaceRemoteAction() + def changeVmNicState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmNicStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmNicStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6389,8 +6524,8 @@ abstract class ApiHelper { } - def createAliyunSnapshotRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunSnapshotRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunSnapshotRemoteAction() + def changeVmNicType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmNicTypeAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmNicTypeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6416,8 +6551,8 @@ abstract class ApiHelper { } - def createAliyunVpcVirtualRouterEntryRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunVpcVirtualRouterEntryRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAliyunVpcVirtualRouterEntryRemoteAction() + def changeVmPassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmPasswordAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmPasswordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6443,8 +6578,8 @@ abstract class ApiHelper { } - def createAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAutoScalingGroupAction() + def changeVmSchedulingRuleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVmSchedulingRuleStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVmSchedulingRuleStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6470,8 +6605,8 @@ abstract class ApiHelper { } - def createAutoScalingGroupAddingNewInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingGroupAddingNewInstanceRuleAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAutoScalingGroupAddingNewInstanceRuleAction() + def changeVolumeState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVolumeStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVolumeStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6497,8 +6632,8 @@ abstract class ApiHelper { } - def createAutoScalingGroupRemovalInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingGroupRemovalInstanceRuleAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAutoScalingGroupRemovalInstanceRuleAction() + def changeVpcHaGroupMonitorIps(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVpcHaGroupMonitorIpsAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVpcHaGroupMonitorIpsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6524,8 +6659,8 @@ abstract class ApiHelper { } - def createAutoScalingRuleAlarmTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingRuleAlarmTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAutoScalingRuleAlarmTriggerAction() + def changeVpcSharedQosBandwidth(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeVpcSharedQosBandwidthAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeVpcSharedQosBandwidthAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6551,8 +6686,8 @@ abstract class ApiHelper { } - def createAutoScalingRuleSchedulerJobTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingRuleSchedulerJobTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAutoScalingRuleSchedulerJobTriggerAction() + def changeZoneState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ChangeZoneStateAction.class) Closure c) { + def a = new org.zstack.sdk.ChangeZoneStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6578,8 +6713,8 @@ abstract class ApiHelper { } - def createAutoScalingVmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingVmTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.CreateAutoScalingVmTemplateAction() + def checkApiPermission(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckApiPermissionAction.class) Closure c) { + def a = new org.zstack.sdk.CheckApiPermissionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6605,8 +6740,8 @@ abstract class ApiHelper { } - def createBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2InstanceAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBareMetal2InstanceAction() + def checkBareMetal2IpmiChassisConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBareMetal2IpmiChassisConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.CheckBareMetal2IpmiChassisConfigFileAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6632,9 +6767,9 @@ abstract class ApiHelper { } - def createBareMetal2IpmiChassisHardwareInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2IpmiChassisHardwareInfoAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBareMetal2IpmiChassisHardwareInfoAction() - + def checkBaremetalChassisConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBaremetalChassisConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.CheckBaremetalChassisConfigFileAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -6659,8 +6794,8 @@ abstract class ApiHelper { } - def createBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2ProvisionNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBareMetal2ProvisionNetworkAction() + def checkBatchDataIntegrity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBatchDataIntegrityAction.class) Closure c) { + def a = new org.zstack.sdk.CheckBatchDataIntegrityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6686,8 +6821,8 @@ abstract class ApiHelper { } - def createBaremetalBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalBondingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBaremetalBondingAction() + def checkBuildAppParameters(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckBuildAppParametersAction.class) Closure c) { + def a = new org.zstack.sdk.CheckBuildAppParametersAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6713,8 +6848,8 @@ abstract class ApiHelper { } - def createBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBaremetalChassisAction() + def checkElaborationContent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckElaborationContentAction.class) Closure c) { + def a = new org.zstack.sdk.CheckElaborationContentAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6740,8 +6875,8 @@ abstract class ApiHelper { } - def createBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBaremetalInstanceAction() + def checkFirewallRuleConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckFirewallRuleConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.CheckFirewallRuleConfigFileAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6767,8 +6902,8 @@ abstract class ApiHelper { } - def createBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBaremetalPxeServerAction() + def checkIpAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckIpAvailabilityAction.class) Closure c) { + def a = new org.zstack.sdk.CheckIpAvailabilityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6794,8 +6929,8 @@ abstract class ApiHelper { } - def createBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBuildAppAction.class) Closure c) { - def a = new org.zstack.sdk.CreateBuildAppAction() + def checkKVMHostConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckKVMHostConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.CheckKVMHostConfigFileAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6821,8 +6956,8 @@ abstract class ApiHelper { } - def createCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCdpPolicyAction.class) Closure c) { - def a = new org.zstack.sdk.CreateCdpPolicyAction() + def checkNetworkReachable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckNetworkReachableAction.class) Closure c) { + def a = new org.zstack.sdk.CheckNetworkReachableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6848,8 +6983,8 @@ abstract class ApiHelper { } - def createCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCdpTaskAction.class) Closure c) { - def a = new org.zstack.sdk.CreateCdpTaskAction() + def checkResourcePermission(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckResourcePermissionAction.class) Closure c) { + def a = new org.zstack.sdk.CheckResourcePermissionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6875,8 +7010,8 @@ abstract class ApiHelper { } - def createCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCertificateAction.class) Closure c) { - def a = new org.zstack.sdk.CreateCertificateAction() + def checkScsiLunClusterStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckScsiLunClusterStatusAction.class) Closure c) { + def a = new org.zstack.sdk.CheckScsiLunClusterStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6902,8 +7037,8 @@ abstract class ApiHelper { } - def createCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateClusterAction.class) Closure c) { - def a = new org.zstack.sdk.CreateClusterAction() + def checkStackTemplateParameters(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckStackTemplateParametersAction.class) Closure c) { + def a = new org.zstack.sdk.CheckStackTemplateParametersAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6929,8 +7064,8 @@ abstract class ApiHelper { } - def createClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateClusterDRSAction.class) Closure c) { - def a = new org.zstack.sdk.CreateClusterDRSAction() + def checkStaticProvisionIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckStaticProvisionIpAction.class) Closure c) { + def a = new org.zstack.sdk.CheckStaticProvisionIpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6956,8 +7091,8 @@ abstract class ApiHelper { } - def createConnectionBetweenL3NetworkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateConnectionBetweenL3NetworkAndAliyunVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.CreateConnectionBetweenL3NetworkAndAliyunVSwitchAction() + def checkVipPortAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckVipPortAvailabilityAction.class) Closure c) { + def a = new org.zstack.sdk.CheckVipPortAvailabilityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -6983,8 +7118,8 @@ abstract class ApiHelper { } - def createDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.CreateDataVolumeAction() + def checkVolumeSnapshotGroupAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CheckVolumeSnapshotGroupAvailabilityAction.class) Closure c) { + def a = new org.zstack.sdk.CheckVolumeSnapshotGroupAvailabilityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7010,8 +7145,8 @@ abstract class ApiHelper { } - def createDataVolumeFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeFromVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateDataVolumeFromVolumeSnapshotAction() + def cleanInvalidLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanInvalidLdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.CleanInvalidLdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7037,8 +7172,8 @@ abstract class ApiHelper { } - def createDataVolumeFromVolumeTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeFromVolumeTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.CreateDataVolumeFromVolumeTemplateAction() + def cleanInvalidLdapIAM2Binding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanInvalidLdapIAM2BindingAction.class) Closure c) { + def a = new org.zstack.sdk.CleanInvalidLdapIAM2BindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7064,8 +7199,8 @@ abstract class ApiHelper { } - def createDataVolumeTemplateFromVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeTemplateFromVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.CreateDataVolumeTemplateFromVolumeAction() + def cleanLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.CleanLongJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7091,8 +7226,8 @@ abstract class ApiHelper { } - def createDataVolumeTemplateFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeTemplateFromVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateDataVolumeTemplateFromVolumeSnapshotAction() + def cleanQueue(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanQueueAction.class) Closure c) { + def a = new org.zstack.sdk.CleanQueueAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7118,8 +7253,8 @@ abstract class ApiHelper { } - def createDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDiskOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateDiskOfferingAction() + def cleanUpBareMetal2Bonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpBareMetal2BondingAction.class) Closure c) { + def a = new org.zstack.sdk.CleanUpBareMetal2BondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7145,8 +7280,8 @@ abstract class ApiHelper { } - def createEcsImageFromEcsSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsImageFromEcsSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsImageFromEcsSnapshotAction() + def cleanUpBaremetalChassisBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpBaremetalChassisBondingAction.class) Closure c) { + def a = new org.zstack.sdk.CleanUpBaremetalChassisBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7172,8 +7307,8 @@ abstract class ApiHelper { } - def createEcsImageFromLocalImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsImageFromLocalImageAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsImageFromLocalImageAction() + def cleanUpImageCacheOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpImageCacheOnPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.CleanUpImageCacheOnPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7199,8 +7334,8 @@ abstract class ApiHelper { } - def createEcsInstanceFromEcsImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsInstanceFromEcsImageAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsInstanceFromEcsImageAction() + def cleanUpStorageTrashOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpStorageTrashOnPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.CleanUpStorageTrashOnPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7226,8 +7361,8 @@ abstract class ApiHelper { } - def createEcsSecurityGroupRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsSecurityGroupRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsSecurityGroupRemoteAction() + def cleanUpTrashOnBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpTrashOnBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.CleanUpTrashOnBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7253,8 +7388,8 @@ abstract class ApiHelper { } - def createEcsSecurityGroupRuleRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsSecurityGroupRuleRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsSecurityGroupRuleRemoteAction() + def cleanUpTrashOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanUpTrashOnPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.CleanUpTrashOnPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7280,8 +7415,8 @@ abstract class ApiHelper { } - def createEcsVSwitchRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsVSwitchRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsVSwitchRemoteAction() + def cleanV2VConversionCache(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanV2VConversionCacheAction.class) Closure c) { + def a = new org.zstack.sdk.CleanV2VConversionCacheAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7307,8 +7442,8 @@ abstract class ApiHelper { } - def createEcsVpcRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsVpcRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEcsVpcRemoteAction() + def cleanupBillingUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CleanupBillingUsageAction.class) Closure c) { + def a = new org.zstack.sdk.CleanupBillingUsageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7334,8 +7469,8 @@ abstract class ApiHelper { } - def createEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEipAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEipAction() + def cloneImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CloneImageAction.class) Closure c) { + def a = new org.zstack.sdk.CloneImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7361,8 +7496,8 @@ abstract class ApiHelper { } - def createEmailMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEmailMediaAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEmailMediaAction() + def cloneModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CloneModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.CloneModelServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7388,8 +7523,8 @@ abstract class ApiHelper { } - def createEmailMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEmailMonitorTriggerActionAction.class) Closure c) { - def a = new org.zstack.sdk.CreateEmailMonitorTriggerActionAction() + def cloneVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CloneVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CloneVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7415,8 +7550,8 @@ abstract class ApiHelper { } - def createFaultToleranceVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFaultToleranceVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFaultToleranceVmInstanceAction() + def convertVmFromForeignHypervisor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ConvertVmFromForeignHypervisorAction.class) Closure c) { + def a = new org.zstack.sdk.ConvertVmFromForeignHypervisorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7442,8 +7577,8 @@ abstract class ApiHelper { } - def createFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallIpSetTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFirewallIpSetTemplateAction() + def createAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAccessControlListAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAccessControlListAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7469,8 +7604,8 @@ abstract class ApiHelper { } - def createFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFirewallRuleAction() + def createAccessKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAccessKeyAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAccessKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7496,8 +7631,8 @@ abstract class ApiHelper { } - def createFirewallRuleFromConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleFromConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFirewallRuleFromConfigFileAction() + def createAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAccountAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAccountAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7523,8 +7658,8 @@ abstract class ApiHelper { } - def createFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFirewallRuleSetAction() + def createAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAffinityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7550,8 +7685,8 @@ abstract class ApiHelper { } - def createFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFirewallRuleTemplateAction() + def createAiSiNoSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAiSiNoSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAiSiNoSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7577,8 +7712,8 @@ abstract class ApiHelper { } - def createFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFlowCollectorAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFlowCollectorAction() + def createAliyunDiskFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunDiskFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunDiskFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7604,8 +7739,8 @@ abstract class ApiHelper { } - def createFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFlowMeterAction.class) Closure c) { - def a = new org.zstack.sdk.CreateFlowMeterAction() + def createAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasAccessGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunNasAccessGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7631,8 +7766,8 @@ abstract class ApiHelper { } - def createHybridEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHybridEipAction.class) Closure c) { - def a = new org.zstack.sdk.CreateHybridEipAction() + def createAliyunNasAccessGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasAccessGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunNasAccessGroupRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7658,8 +7793,8 @@ abstract class ApiHelper { } - def createIAM2VirtualIDFromLdapUid(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateIAM2VirtualIDFromLdapUidAction.class) Closure c) { - def a = new org.zstack.sdk.CreateIAM2VirtualIDFromLdapUidAction() + def createAliyunNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasFileSystemAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunNasFileSystemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7685,8 +7820,8 @@ abstract class ApiHelper { } - def createIAM2VirtualIDLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateIAM2VirtualIDLdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateIAM2VirtualIDLdapBindingAction() + def createAliyunNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunNasMountTargetAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunNasMountTargetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7712,8 +7847,8 @@ abstract class ApiHelper { } - def createIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.CreateIPsecConnectionAction() + def createAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunProxyVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunProxyVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7739,8 +7874,8 @@ abstract class ApiHelper { } - def createImageReplicationGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateImageReplicationGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateImageReplicationGroupAction() + def createAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunProxyVpcAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunProxyVpcAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7766,8 +7901,8 @@ abstract class ApiHelper { } - def createInfoSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateInfoSecSecretResourcePoolAction.class) Closure c) { - def a = new org.zstack.sdk.CreateInfoSecSecretResourcePoolAction() + def createAliyunRouterInterfaceRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunRouterInterfaceRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunRouterInterfaceRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7793,8 +7928,8 @@ abstract class ApiHelper { } - def createInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateInstanceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateInstanceOfferingAction() + def createAliyunSnapshotRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunSnapshotRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunSnapshotRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7820,8 +7955,8 @@ abstract class ApiHelper { } - def createL2HardwareVxlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2HardwareVxlanNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL2HardwareVxlanNetworkAction() + def createAliyunVpcVirtualRouterEntryRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAliyunVpcVirtualRouterEntryRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAliyunVpcVirtualRouterEntryRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7847,8 +7982,8 @@ abstract class ApiHelper { } - def createL2HardwareVxlanNetworkPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2HardwareVxlanNetworkPoolAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL2HardwareVxlanNetworkPoolAction() + def createAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAutoScalingGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7874,8 +8009,8 @@ abstract class ApiHelper { } - def createL2NoVlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2NoVlanNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL2NoVlanNetworkAction() + def createAutoScalingGroupAddingNewInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingGroupAddingNewInstanceRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAutoScalingGroupAddingNewInstanceRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7901,8 +8036,8 @@ abstract class ApiHelper { } - def createL2VlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VlanNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL2VlanNetworkAction() + def createAutoScalingGroupRemovalInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingGroupRemovalInstanceRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAutoScalingGroupRemovalInstanceRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7928,8 +8063,8 @@ abstract class ApiHelper { } - def createL2VxlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VxlanNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL2VxlanNetworkAction() + def createAutoScalingRuleAlarmTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingRuleAlarmTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAutoScalingRuleAlarmTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7955,8 +8090,8 @@ abstract class ApiHelper { } - def createL2VxlanNetworkPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VxlanNetworkPoolAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL2VxlanNetworkPoolAction() + def createAutoScalingRuleSchedulerJobTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingRuleSchedulerJobTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAutoScalingRuleSchedulerJobTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -7982,8 +8117,8 @@ abstract class ApiHelper { } - def createL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.CreateL3NetworkAction() + def createAutoScalingVmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateAutoScalingVmTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.CreateAutoScalingVmTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8009,8 +8144,8 @@ abstract class ApiHelper { } - def createLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateLdapBindingAction() + def createBareMetal2Bonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2BondingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBareMetal2BondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8036,8 +8171,8 @@ abstract class ApiHelper { } - def createLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateLoadBalancerAction() + def createBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2InstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBareMetal2InstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8063,8 +8198,35 @@ abstract class ApiHelper { } - def createLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateLoadBalancerListenerAction() + def createBareMetal2IpmiChassisHardwareInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2IpmiChassisHardwareInfoAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBareMetal2IpmiChassisHardwareInfoAction() + + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBareMetal2ProvisionNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBareMetal2ProvisionNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8090,8 +8252,8 @@ abstract class ApiHelper { } - def createLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLoadBalancerServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateLoadBalancerServerGroupAction() + def createBaremetalBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalBondingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBaremetalBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8117,8 +8279,8 @@ abstract class ApiHelper { } - def createMiniCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateMiniClusterAction.class) Closure c) { - def a = new org.zstack.sdk.CreateMiniClusterAction() + def createBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8144,8 +8306,8 @@ abstract class ApiHelper { } - def createMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateMonitorTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateMonitorTriggerAction() + def createBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBaremetalInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8171,8 +8333,8 @@ abstract class ApiHelper { } - def createMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateMulticastRouterAction.class) Closure c) { - def a = new org.zstack.sdk.CreateMulticastRouterAction() + def createBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBaremetalPxeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8198,8 +8360,8 @@ abstract class ApiHelper { } - def createOssBackupBucketRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOssBackupBucketRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateOssBackupBucketRemoteAction() + def createBlockVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBlockVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBlockVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8225,8 +8387,8 @@ abstract class ApiHelper { } - def createOssBucketRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOssBucketRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateOssBucketRemoteAction() + def createBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBondingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8252,8 +8414,8 @@ abstract class ApiHelper { } - def createPciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePciDeviceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePciDeviceOfferingAction() + def createBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateBuildAppAction.class) Closure c) { + def a = new org.zstack.sdk.CreateBuildAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8279,8 +8441,8 @@ abstract class ApiHelper { } - def createPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePolicyAction() + def createCSPSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCSPSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateCSPSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8306,8 +8468,8 @@ abstract class ApiHelper { } - def createPolicyRouteRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteRuleAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePolicyRouteRuleAction() + def createCasClient(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCasClientAction.class) Closure c) { + def a = new org.zstack.sdk.CreateCasClientAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8333,8 +8495,8 @@ abstract class ApiHelper { } - def createPolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePolicyRouteRuleSetAction() + def createCbtTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCbtTaskAction.class) Closure c) { + def a = new org.zstack.sdk.CreateCbtTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8360,8 +8522,8 @@ abstract class ApiHelper { } - def createPolicyRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePolicyRouteTableAction() + def createCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCdpPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.CreateCdpPolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8387,8 +8549,8 @@ abstract class ApiHelper { } - def createPolicyRouteTableRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteTableRouteEntryAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePolicyRouteTableRouteEntryAction() + def createCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCdpTaskAction.class) Closure c) { + def a = new org.zstack.sdk.CreateCdpTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8414,8 +8576,8 @@ abstract class ApiHelper { } - def createPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePortForwardingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePortForwardingRuleAction() + def createCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateCertificateAction.class) Closure c) { + def a = new org.zstack.sdk.CreateCertificateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8441,8 +8603,8 @@ abstract class ApiHelper { } - def createPortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePortMirrorAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePortMirrorAction() + def createCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateClusterAction.class) Closure c) { + def a = new org.zstack.sdk.CreateClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8468,8 +8630,8 @@ abstract class ApiHelper { } - def createPortMirrorSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePortMirrorSessionAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePortMirrorSessionAction() + def createClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateClusterDRSAction.class) Closure c) { + def a = new org.zstack.sdk.CreateClusterDRSAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8495,8 +8657,8 @@ abstract class ApiHelper { } - def createPriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePriceTableAction.class) Closure c) { - def a = new org.zstack.sdk.CreatePriceTableAction() + def createConnectionBetweenL3NetworkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateConnectionBetweenL3NetworkAndAliyunVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.CreateConnectionBetweenL3NetworkAndAliyunVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8522,8 +8684,8 @@ abstract class ApiHelper { } - def createResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateResourcePriceAction.class) Closure c) { - def a = new org.zstack.sdk.CreateResourcePriceAction() + def createDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDataVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8549,8 +8711,8 @@ abstract class ApiHelper { } - def createResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.CreateResourceStackAction() + def createDataVolumeFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeFromVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDataVolumeFromVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8576,8 +8738,8 @@ abstract class ApiHelper { } - def createResourceStackFromApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateResourceStackFromAppAction.class) Closure c) { - def a = new org.zstack.sdk.CreateResourceStackFromAppAction() + def createDataVolumeFromVolumeTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeFromVolumeTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDataVolumeFromVolumeTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8603,8 +8765,8 @@ abstract class ApiHelper { } - def createRootVolumeTemplateFromRootVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateRootVolumeTemplateFromRootVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.CreateRootVolumeTemplateFromRootVolumeAction() + def createDataVolumeTemplateFromVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeTemplateFromVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDataVolumeTemplateFromVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8630,8 +8792,8 @@ abstract class ApiHelper { } - def createRootVolumeTemplateFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateRootVolumeTemplateFromVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateRootVolumeTemplateFromVolumeSnapshotAction() + def createDataVolumeTemplateFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDataVolumeTemplateFromVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDataVolumeTemplateFromVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8657,8 +8819,8 @@ abstract class ApiHelper { } - def createSchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSchedulerJobAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSchedulerJobAction() + def createDataset(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDatasetAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDatasetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8684,8 +8846,8 @@ abstract class ApiHelper { } - def createSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSchedulerJobGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSchedulerJobGroupAction() + def createDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8711,8 +8873,8 @@ abstract class ApiHelper { } - def createSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSchedulerTriggerAction() + def createDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateDiskOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateDiskOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8738,8 +8900,8 @@ abstract class ApiHelper { } - def createSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSecurityGroupAction() + def createEcsImageFromEcsSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsImageFromEcsSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsImageFromEcsSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8765,8 +8927,8 @@ abstract class ApiHelper { } - def createSlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSlbGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSlbGroupAction() + def createEcsImageFromLocalImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsImageFromLocalImageAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsImageFromLocalImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8792,8 +8954,8 @@ abstract class ApiHelper { } - def createSlbInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSlbInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSlbInstanceAction() + def createEcsInstanceFromEcsImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsInstanceFromEcsImageAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsInstanceFromEcsImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8819,8 +8981,8 @@ abstract class ApiHelper { } - def createSlbOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSlbOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSlbOfferingAction() + def createEcsSecurityGroupRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsSecurityGroupRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsSecurityGroupRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8846,8 +9008,8 @@ abstract class ApiHelper { } - def createSystemTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSystemTagAction.class) Closure c) { - def a = new org.zstack.sdk.CreateSystemTagAction() + def createEcsSecurityGroupRuleRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsSecurityGroupRuleRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsSecurityGroupRuleRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8873,8 +9035,8 @@ abstract class ApiHelper { } - def createTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateTagAction.class) Closure c) { - def a = new org.zstack.sdk.CreateTagAction() + def createEcsVSwitchRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsVSwitchRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsVSwitchRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8900,8 +9062,8 @@ abstract class ApiHelper { } - def createUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserAction.class) Closure c) { - def a = new org.zstack.sdk.CreateUserAction() + def createEcsVpcRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEcsVpcRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEcsVpcRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8927,8 +9089,8 @@ abstract class ApiHelper { } - def createUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateUserGroupAction() + def createEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEipAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8954,8 +9116,8 @@ abstract class ApiHelper { } - def createUserTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserTagAction.class) Closure c) { - def a = new org.zstack.sdk.CreateUserTagAction() + def createEmailMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEmailMediaAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEmailMediaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -8981,8 +9143,8 @@ abstract class ApiHelper { } - def createVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVRouterOspfAreaAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVRouterOspfAreaAction() + def createEmailMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateEmailMonitorTriggerActionAction.class) Closure c) { + def a = new org.zstack.sdk.CreateEmailMonitorTriggerActionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9008,8 +9170,8 @@ abstract class ApiHelper { } - def createVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVRouterRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVRouterRouteTableAction() + def createFaultToleranceVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFaultToleranceVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFaultToleranceVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9035,8 +9197,8 @@ abstract class ApiHelper { } - def createVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVipAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVipAction() + def createFiSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFiSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFiSecSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9062,8 +9224,8 @@ abstract class ApiHelper { } - def createVirtualRouterOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVirtualRouterOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVirtualRouterOfferingAction() + def createFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallIpSetTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFirewallIpSetTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9089,8 +9251,8 @@ abstract class ApiHelper { } - def createVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmCdRomAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmCdRomAction() + def createFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFirewallRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9116,8 +9278,8 @@ abstract class ApiHelper { } - def createVmFromCdpBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmFromCdpBackupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmFromCdpBackupAction() + def createFirewallRuleFromConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleFromConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFirewallRuleFromConfigFileAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9143,8 +9305,8 @@ abstract class ApiHelper { } - def createVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmInstanceAction() + def createFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFirewallRuleSetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9170,8 +9332,8 @@ abstract class ApiHelper { } - def createVmInstanceFromVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmInstanceFromVolumeAction() + def createFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFirewallRuleTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFirewallRuleTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9197,8 +9359,8 @@ abstract class ApiHelper { } - def createVmInstanceFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotAction() + def createFlkSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFlkSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFlkSecSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9224,8 +9386,8 @@ abstract class ApiHelper { } - def createVmInstanceFromVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotGroupAction() + def createFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFlowCollectorAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFlowCollectorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9251,8 +9413,8 @@ abstract class ApiHelper { } - def createVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmNicAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVmNicAction() + def createFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateFlowMeterAction.class) Closure c) { + def a = new org.zstack.sdk.CreateFlowMeterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9278,8 +9440,8 @@ abstract class ApiHelper { } - def createVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVniRangeAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVniRangeAction() + def createGuestVmScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateGuestVmScriptAction.class) Closure c) { + def a = new org.zstack.sdk.CreateGuestVmScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9305,8 +9467,8 @@ abstract class ApiHelper { } - def createVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVolumeSnapshotAction() + def createHaiTaiSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHaiTaiSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateHaiTaiSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9332,8 +9494,8 @@ abstract class ApiHelper { } - def createVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVolumeSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVolumeSnapshotGroupAction() + def createHostNetworkServiceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHostNetworkServiceTypeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateHostNetworkServiceTypeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9359,8 +9521,8 @@ abstract class ApiHelper { } - def createVolumesSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVolumesSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVolumesSnapshotAction() + def createHostSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHostSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateHostSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9386,8 +9548,8 @@ abstract class ApiHelper { } - def createVpcFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcFirewallAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpcFirewallAction() + def createHybridEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateHybridEipAction.class) Closure c) { + def a = new org.zstack.sdk.CreateHybridEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9413,8 +9575,8 @@ abstract class ApiHelper { } - def createVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcHaGroupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpcHaGroupAction() + def createIAM2VirtualIDFromLdapUid(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateIAM2VirtualIDFromLdapUidAction.class) Closure c) { + def a = new org.zstack.sdk.CreateIAM2VirtualIDFromLdapUidAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9440,8 +9602,8 @@ abstract class ApiHelper { } - def createVpcUserVpnGatewayRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcUserVpnGatewayRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpcUserVpnGatewayRemoteAction() + def createIAM2VirtualIDLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateIAM2VirtualIDLdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateIAM2VirtualIDLdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9467,8 +9629,8 @@ abstract class ApiHelper { } - def createVpcVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcVRouterAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpcVRouterAction() + def createIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.CreateIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9494,8 +9656,8 @@ abstract class ApiHelper { } - def createVpcVpnConnectionRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcVpnConnectionRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpcVpnConnectionRemoteAction() + def createImageGroupFromImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateImageGroupFromImageAction.class) Closure c) { + def a = new org.zstack.sdk.CreateImageGroupFromImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9521,8 +9683,8 @@ abstract class ApiHelper { } - def createVpnIkeConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpnIkeConfigAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpnIkeConfigAction() + def createImageGroupFromSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateImageGroupFromSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateImageGroupFromSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9548,8 +9710,8 @@ abstract class ApiHelper { } - def createVpnIpsecConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpnIpsecConfigAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVpnIpsecConfigAction() + def createImageGroupFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateImageGroupFromVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateImageGroupFromVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9575,8 +9737,8 @@ abstract class ApiHelper { } - def createVxlanVtep(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVxlanVtepAction.class) Closure c) { - def a = new org.zstack.sdk.CreateVxlanVtepAction() + def createImageReplicationGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateImageReplicationGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateImageReplicationGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9602,8 +9764,8 @@ abstract class ApiHelper { } - def createWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateWebhookAction.class) Closure c) { - def a = new org.zstack.sdk.CreateWebhookAction() + def createInfoSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateInfoSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateInfoSecSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9629,8 +9791,8 @@ abstract class ApiHelper { } - def createZBoxBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateZBoxBackupAction.class) Closure c) { - def a = new org.zstack.sdk.CreateZBoxBackupAction() + def createInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateInstanceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateInstanceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9656,8 +9818,8 @@ abstract class ApiHelper { } - def createZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateZoneAction.class) Closure c) { - def a = new org.zstack.sdk.CreateZoneAction() + def createJitSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateJitSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateJitSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9683,8 +9845,8 @@ abstract class ApiHelper { } - def debugSignal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DebugSignalAction.class) Closure c) { - def a = new org.zstack.sdk.DebugSignalAction() + def createKoAlSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateKoAlSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateKoAlSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9710,8 +9872,8 @@ abstract class ApiHelper { } - def decodeStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DecodeStackTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.DecodeStackTemplateAction() + def createL2HardwareVxlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2HardwareVxlanNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2HardwareVxlanNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9737,8 +9899,8 @@ abstract class ApiHelper { } - def deleteAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccessControlListAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAccessControlListAction() + def createL2HardwareVxlanNetworkPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2HardwareVxlanNetworkPoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2HardwareVxlanNetworkPoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9764,8 +9926,8 @@ abstract class ApiHelper { } - def deleteAccessControlRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccessControlRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAccessControlRuleAction() + def createL2NoVlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2NoVlanNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2NoVlanNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9791,8 +9953,8 @@ abstract class ApiHelper { } - def deleteAccessKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccessKeyAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAccessKeyAction() + def createL2PortGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2PortGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2PortGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9818,8 +9980,8 @@ abstract class ApiHelper { } - def deleteAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccountAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAccountAction() + def createL2TfNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2TfNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2TfNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9845,8 +10007,8 @@ abstract class ApiHelper { } - def deleteAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAffinityGroupAction() + def createL2VirtualSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VirtualSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2VirtualSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9872,8 +10034,8 @@ abstract class ApiHelper { } - def deleteAlert(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAlertAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAlertAction() + def createL2VlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VlanNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2VlanNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9899,8 +10061,8 @@ abstract class ApiHelper { } - def deleteAliyunDiskFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunDiskFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunDiskFromLocalAction() + def createL2VxlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VxlanNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2VxlanNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9926,8 +10088,8 @@ abstract class ApiHelper { } - def deleteAliyunDiskFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunDiskFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunDiskFromRemoteAction() + def createL2VxlanNetworkPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL2VxlanNetworkPoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL2VxlanNetworkPoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9953,8 +10115,8 @@ abstract class ApiHelper { } - def deleteAliyunKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunKeySecretAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunKeySecretAction() + def createL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.CreateL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -9980,8 +10142,8 @@ abstract class ApiHelper { } - def deleteAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunNasAccessGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunNasAccessGroupAction() + def createLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateLdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10007,8 +10169,8 @@ abstract class ApiHelper { } - def deleteAliyunNasAccessGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunNasAccessGroupRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunNasAccessGroupRuleAction() + def createLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10034,8 +10196,8 @@ abstract class ApiHelper { } - def deleteAliyunPanguPartition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunPanguPartitionAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunPanguPartitionAction() + def createLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10061,8 +10223,8 @@ abstract class ApiHelper { } - def deleteAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunProxyVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunProxyVSwitchAction() + def createLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateLoadBalancerServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateLoadBalancerServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10088,8 +10250,8 @@ abstract class ApiHelper { } - def deleteAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunProxyVpcAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunProxyVpcAction() + def createMiniCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateMiniClusterAction.class) Closure c) { + def a = new org.zstack.sdk.CreateMiniClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10115,8 +10277,8 @@ abstract class ApiHelper { } - def deleteAliyunRouteEntryRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunRouteEntryRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunRouteEntryRemoteAction() + def createMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateMonitorTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateMonitorTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10142,8 +10304,8 @@ abstract class ApiHelper { } - def deleteAliyunRouterInterfaceLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunRouterInterfaceLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunRouterInterfaceLocalAction() + def createMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateMulticastRouterAction.class) Closure c) { + def a = new org.zstack.sdk.CreateMulticastRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10169,8 +10331,8 @@ abstract class ApiHelper { } - def deleteAliyunRouterInterfaceRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunRouterInterfaceRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunRouterInterfaceRemoteAction() + def createOAuthClient(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOAuthClientAction.class) Closure c) { + def a = new org.zstack.sdk.CreateOAuthClientAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10196,8 +10358,8 @@ abstract class ApiHelper { } - def deleteAliyunSnapshotFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunSnapshotFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunSnapshotFromLocalAction() + def createObservabilityServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateObservabilityServerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateObservabilityServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10223,8 +10385,8 @@ abstract class ApiHelper { } - def deleteAliyunSnapshotFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunSnapshotFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAliyunSnapshotFromRemoteAction() + def createObservabilityServerOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateObservabilityServerOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateObservabilityServerOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10250,8 +10412,8 @@ abstract class ApiHelper { } - def deleteAllEcsInstancesFromDataCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAllEcsInstancesFromDataCenterAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAllEcsInstancesFromDataCenterAction() + def createOssBackupBucketRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOssBackupBucketRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateOssBackupBucketRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10277,8 +10439,8 @@ abstract class ApiHelper { } - def deleteAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAppBuildSystemAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAppBuildSystemAction() + def createOssBucketRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOssBucketRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateOssBucketRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10304,8 +10466,8 @@ abstract class ApiHelper { } - def deleteAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAutoScalingGroupAction() + def createOvnControllerOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOvnControllerOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateOvnControllerOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10331,8 +10493,8 @@ abstract class ApiHelper { } - def deleteAutoScalingGroupInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingGroupInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAutoScalingGroupInstanceAction() + def createOvnControllerVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateOvnControllerVmAction.class) Closure c) { + def a = new org.zstack.sdk.CreateOvnControllerVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10358,8 +10520,8 @@ abstract class ApiHelper { } - def deleteAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAutoScalingRuleAction() + def createPciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePciDeviceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePciDeviceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10385,8 +10547,8 @@ abstract class ApiHelper { } - def deleteAutoScalingRuleTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingRuleTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAutoScalingRuleTriggerAction() + def createPluginSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePluginSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePluginSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10412,8 +10574,8 @@ abstract class ApiHelper { } - def deleteAutoScalingTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteAutoScalingTemplateAction() + def createPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10439,8 +10601,8 @@ abstract class ApiHelper { } - def deleteBackupFileInPublic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBackupFileInPublicAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBackupFileInPublicAction() + def createPolicyRouteRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePolicyRouteRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10466,8 +10628,8 @@ abstract class ApiHelper { } - def deleteBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBackupStorageAction() + def createPolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePolicyRouteRuleSetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10493,8 +10655,8 @@ abstract class ApiHelper { } - def deleteBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBareMetal2ChassisAction() + def createPolicyRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePolicyRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10520,8 +10682,8 @@ abstract class ApiHelper { } - def deleteBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBareMetal2GatewayAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBareMetal2GatewayAction() + def createPolicyRouteTableRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePolicyRouteTableRouteEntryAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePolicyRouteTableRouteEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10547,8 +10709,8 @@ abstract class ApiHelper { } - def deleteBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBareMetal2ProvisionNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBareMetal2ProvisionNetworkAction() + def createPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePortForwardingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePortForwardingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10574,8 +10736,8 @@ abstract class ApiHelper { } - def deleteBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBaremetalChassisAction() + def createPortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePortMirrorAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePortMirrorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10601,8 +10763,8 @@ abstract class ApiHelper { } - def deleteBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBaremetalPxeServerAction() + def createPortMirrorSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePortMirrorSessionAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePortMirrorSessionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10628,8 +10790,8 @@ abstract class ApiHelper { } - def deleteBilling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBillingAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBillingAction() + def createPriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreatePriceTableAction.class) Closure c) { + def a = new org.zstack.sdk.CreatePriceTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10655,8 +10817,8 @@ abstract class ApiHelper { } - def deleteBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBuildAppAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBuildAppAction() + def createResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateResourcePriceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateResourcePriceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10682,8 +10844,8 @@ abstract class ApiHelper { } - def deleteBuildAppExportHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBuildAppExportHistoryAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteBuildAppExportHistoryAction() + def createResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.CreateResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10709,8 +10871,8 @@ abstract class ApiHelper { } - def deleteCCSCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCCSCertificateAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteCCSCertificateAction() + def createResourceStackFromApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateResourceStackFromAppAction.class) Closure c) { + def a = new org.zstack.sdk.CreateResourceStackFromAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10736,8 +10898,8 @@ abstract class ApiHelper { } - def deleteCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCdpPolicyAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteCdpPolicyAction() + def createRootVolumeTemplateFromRootVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateRootVolumeTemplateFromRootVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateRootVolumeTemplateFromRootVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10763,8 +10925,8 @@ abstract class ApiHelper { } - def deleteCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCdpTaskAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteCdpTaskAction() + def createRootVolumeTemplateFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateRootVolumeTemplateFromVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateRootVolumeTemplateFromVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10790,8 +10952,8 @@ abstract class ApiHelper { } - def deleteCdpTaskData(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCdpTaskDataAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteCdpTaskDataAction() + def createSAML2Client(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSAML2ClientAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSAML2ClientAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10817,8 +10979,8 @@ abstract class ApiHelper { } - def deleteCephPrimaryStoragePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCephPrimaryStoragePoolAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteCephPrimaryStoragePoolAction() + def createSSORedirectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSSORedirectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSSORedirectTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10844,8 +11006,8 @@ abstract class ApiHelper { } - def deleteCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCertificateAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteCertificateAction() + def createSanSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSanSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSanSecSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10871,8 +11033,8 @@ abstract class ApiHelper { } - def deleteCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteClusterAction() + def createSchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSchedulerJobAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSchedulerJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10898,8 +11060,8 @@ abstract class ApiHelper { } - def deleteClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteClusterDRSAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteClusterDRSAction() + def createSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSchedulerJobGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSchedulerJobGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10925,8 +11087,8 @@ abstract class ApiHelper { } - def deleteConnectionAccessPointLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteConnectionAccessPointLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteConnectionAccessPointLocalAction() + def createSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10952,8 +11114,8 @@ abstract class ApiHelper { } - def deleteConnectionBetweenL3NetWorkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteConnectionBetweenL3NetWorkAndAliyunVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteConnectionBetweenL3NetWorkAndAliyunVSwitchAction() + def createSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -10979,8 +11141,8 @@ abstract class ApiHelper { } - def deleteDataCenterInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDataCenterInLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteDataCenterInLocalAction() + def createSlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSlbGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSlbGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11006,8 +11168,8 @@ abstract class ApiHelper { } - def deleteDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDataVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteDataVolumeAction() + def createSlbInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSlbInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSlbInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11033,8 +11195,8 @@ abstract class ApiHelper { } - def deleteDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDiskOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteDiskOfferingAction() + def createSlbOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSlbOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSlbOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11060,8 +11222,8 @@ abstract class ApiHelper { } - def deleteEcsImageLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsImageLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsImageLocalAction() + def createSnmpAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSnmpAgentAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSnmpAgentAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11087,8 +11249,8 @@ abstract class ApiHelper { } - def deleteEcsImageRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsImageRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsImageRemoteAction() + def createSshKeyPair(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSshKeyPairAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSshKeyPairAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11114,8 +11276,8 @@ abstract class ApiHelper { } - def deleteEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsInstanceAction() + def createSystemTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSystemTagAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSystemTagAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11141,8 +11303,8 @@ abstract class ApiHelper { } - def deleteEcsInstanceLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsInstanceLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsInstanceLocalAction() + def createSystemTags(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateSystemTagsAction.class) Closure c) { + def a = new org.zstack.sdk.CreateSystemTagsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11168,8 +11330,8 @@ abstract class ApiHelper { } - def deleteEcsSecurityGroupInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsSecurityGroupInLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsSecurityGroupInLocalAction() + def createTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateTagAction.class) Closure c) { + def a = new org.zstack.sdk.CreateTagAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11195,8 +11357,8 @@ abstract class ApiHelper { } - def deleteEcsSecurityGroupRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsSecurityGroupRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsSecurityGroupRemoteAction() + def createUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserAction.class) Closure c) { + def a = new org.zstack.sdk.CreateUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11222,8 +11384,8 @@ abstract class ApiHelper { } - def deleteEcsSecurityGroupRuleRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsSecurityGroupRuleRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsSecurityGroupRuleRemoteAction() + def createUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateUserGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11249,8 +11411,8 @@ abstract class ApiHelper { } - def deleteEcsVSwitchInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVSwitchInLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsVSwitchInLocalAction() + def createUserProxyConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserProxyConfigAction.class) Closure c) { + def a = new org.zstack.sdk.CreateUserProxyConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11276,8 +11438,62 @@ abstract class ApiHelper { } - def deleteEcsVSwitchRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVSwitchRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsVSwitchRemoteAction() + def createUserTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateUserTagAction.class) Closure c) { + def a = new org.zstack.sdk.CreateUserTagAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVRouterOspfAreaAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVRouterOspfAreaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVRouterRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVRouterRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11303,8 +11519,8 @@ abstract class ApiHelper { } - def deleteEcsVpcInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVpcInLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsVpcInLocalAction() + def createVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVipAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11330,8 +11546,8 @@ abstract class ApiHelper { } - def deleteEcsVpcRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVpcRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEcsVpcRemoteAction() + def createVirtualRouterOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVirtualRouterOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVirtualRouterOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11357,8 +11573,8 @@ abstract class ApiHelper { } - def deleteEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEipAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteEipAction() + def createVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmCdRomAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmCdRomAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11384,8 +11600,8 @@ abstract class ApiHelper { } - def deleteExportedImageFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteExportedImageFromBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteExportedImageFromBackupStorageAction() + def createVmFromCdpBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmFromCdpBackupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmFromCdpBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11411,8 +11627,8 @@ abstract class ApiHelper { } - def deleteExternalBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteExternalBackupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteExternalBackupAction() + def createVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11438,8 +11654,8 @@ abstract class ApiHelper { } - def deleteFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFirewallAction() + def createVmInstanceFromOvf(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromOvfAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmInstanceFromOvfAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11465,8 +11681,8 @@ abstract class ApiHelper { } - def deleteFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallIpSetTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFirewallIpSetTemplateAction() + def createVmInstanceFromVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmInstanceFromVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11492,8 +11708,8 @@ abstract class ApiHelper { } - def deleteFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFirewallRuleAction() + def createVmInstanceFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11519,8 +11735,8 @@ abstract class ApiHelper { } - def deleteFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFirewallRuleSetAction() + def createVmInstanceFromVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmInstanceFromVolumeSnapshotGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11546,8 +11762,8 @@ abstract class ApiHelper { } - def deleteFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallRuleTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFirewallRuleTemplateAction() + def createVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmNicAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmNicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11573,8 +11789,8 @@ abstract class ApiHelper { } - def deleteFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFlowCollectorAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFlowCollectorAction() + def createVmSchedulingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmSchedulingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmSchedulingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11600,8 +11816,8 @@ abstract class ApiHelper { } - def deleteFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFlowMeterAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteFlowMeterAction() + def createVmSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11627,8 +11843,8 @@ abstract class ApiHelper { } - def deleteGCJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteGCJobAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteGCJobAction() + def createVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVmUserDefinedXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVmUserDefinedXmlHookScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11654,8 +11870,8 @@ abstract class ApiHelper { } - def deleteHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHostAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteHostAction() + def createVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVniRangeAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVniRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11681,8 +11897,8 @@ abstract class ApiHelper { } - def deleteHybridEipFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHybridEipFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteHybridEipFromLocalAction() + def createVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11708,8 +11924,8 @@ abstract class ApiHelper { } - def deleteHybridEipRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHybridEipRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteHybridEipRemoteAction() + def createVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVolumeSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVolumeSnapshotGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11735,8 +11951,8 @@ abstract class ApiHelper { } - def deleteHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHybridKeySecretAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteHybridKeySecretAction() + def createVolumesSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVolumesSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVolumesSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11762,8 +11978,8 @@ abstract class ApiHelper { } - def deleteIAM2VirtualIDLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIAM2VirtualIDLdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteIAM2VirtualIDLdapBindingAction() + def createVpcFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcFirewallAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpcFirewallAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11789,8 +12005,8 @@ abstract class ApiHelper { } - def deleteIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteIPsecConnectionAction() + def createVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcHaGroupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpcHaGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11816,8 +12032,8 @@ abstract class ApiHelper { } - def deleteIdentityZoneInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIdentityZoneInLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteIdentityZoneInLocalAction() + def createVpcSharedQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcSharedQosAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpcSharedQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11843,8 +12059,8 @@ abstract class ApiHelper { } - def deleteImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteImageAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteImageAction() + def createVpcUserVpnGatewayRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcUserVpnGatewayRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpcUserVpnGatewayRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11870,8 +12086,8 @@ abstract class ApiHelper { } - def deleteImageReplicationGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteImageReplicationGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteImageReplicationGroupAction() + def createVpcVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpcVRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11897,8 +12113,8 @@ abstract class ApiHelper { } - def deleteInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteInstanceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteInstanceOfferingAction() + def createVpcVpnConnectionRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpcVpnConnectionRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpcVpnConnectionRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11924,8 +12140,8 @@ abstract class ApiHelper { } - def deleteIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIpRangeAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteIpRangeAction() + def createVpnIkeConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpnIkeConfigAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpnIkeConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11951,8 +12167,8 @@ abstract class ApiHelper { } - def deleteIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIscsiServerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteIscsiServerAction() + def createVpnIpsecConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVpnIpsecConfigAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVpnIpsecConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -11978,8 +12194,8 @@ abstract class ApiHelper { } - def deleteL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteL2NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteL2NetworkAction() + def createVxlanPoolRemoteVtep(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVxlanPoolRemoteVtepAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVxlanPoolRemoteVtepAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12005,8 +12221,8 @@ abstract class ApiHelper { } - def deleteL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteL3NetworkAction() + def createVxlanVtep(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateVxlanVtepAction.class) Closure c) { + def a = new org.zstack.sdk.CreateVxlanVtepAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12032,8 +12248,8 @@ abstract class ApiHelper { } - def deleteLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLdapBindingAction() + def createWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateWebhookAction.class) Closure c) { + def a = new org.zstack.sdk.CreateWebhookAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12059,8 +12275,8 @@ abstract class ApiHelper { } - def deleteLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLdapServerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLdapServerAction() + def createZBoxBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateZBoxBackupAction.class) Closure c) { + def a = new org.zstack.sdk.CreateZBoxBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12086,8 +12302,8 @@ abstract class ApiHelper { } - def deleteLicense(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLicenseAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLicenseAction() + def createZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.CreateZoneAction.class) Closure c) { + def a = new org.zstack.sdk.CreateZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12113,8 +12329,8 @@ abstract class ApiHelper { } - def deleteLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLoadBalancerAction() + def debugSignal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DebugSignalAction.class) Closure c) { + def a = new org.zstack.sdk.DebugSignalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12140,8 +12356,8 @@ abstract class ApiHelper { } - def deleteLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLoadBalancerListenerAction() + def decodeStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DecodeStackTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DecodeStackTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12167,8 +12383,8 @@ abstract class ApiHelper { } - def deleteLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLoadBalancerServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLoadBalancerServerGroupAction() + def deleteAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccessControlListAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAccessControlListAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12194,8 +12410,8 @@ abstract class ApiHelper { } - def deleteLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLogConfigurationAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLogConfigurationAction() + def deleteAccessControlRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccessControlRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAccessControlRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12221,8 +12437,8 @@ abstract class ApiHelper { } - def deleteLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteLongJobAction() + def deleteAccessKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccessKeyAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAccessKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12248,8 +12464,8 @@ abstract class ApiHelper { } - def deleteMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMediaAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteMediaAction() + def deleteAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAccountAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAccountAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12275,8 +12491,8 @@ abstract class ApiHelper { } - def deleteMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMonitorTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteMonitorTriggerAction() + def deleteAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAffinityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12302,8 +12518,8 @@ abstract class ApiHelper { } - def deleteMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMonitorTriggerActionAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteMonitorTriggerActionAction() + def deleteAlert(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAlertAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAlertAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12329,8 +12545,8 @@ abstract class ApiHelper { } - def deleteMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMulticastRouterAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteMulticastRouterAction() + def deleteAliyunDiskFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunDiskFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunDiskFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12356,8 +12572,8 @@ abstract class ApiHelper { } - def deleteNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNasFileSystemAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteNasFileSystemAction() + def deleteAliyunDiskFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunDiskFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunDiskFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12383,8 +12599,8 @@ abstract class ApiHelper { } - def deleteNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNasMountTargetAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteNasMountTargetAction() + def deleteAliyunKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunKeySecretAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunKeySecretAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12410,8 +12626,8 @@ abstract class ApiHelper { } - def deleteNicQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNicQosAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteNicQosAction() + def deleteAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunNasAccessGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunNasAccessGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12437,8 +12653,8 @@ abstract class ApiHelper { } - def deleteOssBucketFileRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteOssBucketFileRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteOssBucketFileRemoteAction() + def deleteAliyunNasAccessGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunNasAccessGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunNasAccessGroupRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12464,8 +12680,8 @@ abstract class ApiHelper { } - def deleteOssBucketNameLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteOssBucketNameLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteOssBucketNameLocalAction() + def deleteAliyunPanguPartition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunPanguPartitionAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunPanguPartitionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12491,8 +12707,8 @@ abstract class ApiHelper { } - def deleteOssBucketRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteOssBucketRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteOssBucketRemoteAction() + def deleteAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunProxyVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunProxyVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12518,8 +12734,8 @@ abstract class ApiHelper { } - def deletePciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePciDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePciDeviceAction() + def deleteAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunProxyVpcAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunProxyVpcAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12545,8 +12761,8 @@ abstract class ApiHelper { } - def deletePciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePciDeviceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePciDeviceOfferingAction() + def deleteAliyunRouteEntryRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunRouteEntryRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunRouteEntryRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12572,8 +12788,8 @@ abstract class ApiHelper { } - def deletePolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePolicyAction() + def deleteAliyunRouterInterfaceLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunRouterInterfaceLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunRouterInterfaceLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12599,8 +12815,8 @@ abstract class ApiHelper { } - def deletePolicyRouteRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePolicyRouteRuleAction() + def deleteAliyunRouterInterfaceRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunRouterInterfaceRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunRouterInterfaceRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12626,8 +12842,8 @@ abstract class ApiHelper { } - def deletePolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePolicyRouteRuleSetAction() + def deleteAliyunSnapshotFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunSnapshotFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunSnapshotFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12653,8 +12869,8 @@ abstract class ApiHelper { } - def deletePolicyRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePolicyRouteTableAction() + def deleteAliyunSnapshotFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAliyunSnapshotFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAliyunSnapshotFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12680,8 +12896,8 @@ abstract class ApiHelper { } - def deletePolicyRouteTableRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteTableRouteEntryAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePolicyRouteTableRouteEntryAction() + def deleteAllEcsInstancesFromDataCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAllEcsInstancesFromDataCenterAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAllEcsInstancesFromDataCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12707,8 +12923,8 @@ abstract class ApiHelper { } - def deletePortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePortForwardingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePortForwardingRuleAction() + def deleteAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAppBuildSystemAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAppBuildSystemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12734,8 +12950,8 @@ abstract class ApiHelper { } - def deletePortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePortMirrorAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePortMirrorAction() + def deleteAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAutoScalingGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12761,8 +12977,8 @@ abstract class ApiHelper { } - def deletePortMirrorSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePortMirrorSessionAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePortMirrorSessionAction() + def deleteAutoScalingGroupInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingGroupInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAutoScalingGroupInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12788,8 +13004,8 @@ abstract class ApiHelper { } - def deletePreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePreconfigurationTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePreconfigurationTemplateAction() + def deleteAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAutoScalingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12815,8 +13031,8 @@ abstract class ApiHelper { } - def deletePriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePriceTableAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePriceTableAction() + def deleteAutoScalingRuleTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingRuleTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAutoScalingRuleTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12842,8 +13058,8 @@ abstract class ApiHelper { } - def deletePrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePrimaryStorageAction() + def deleteAutoScalingTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteAutoScalingTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteAutoScalingTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12869,8 +13085,8 @@ abstract class ApiHelper { } - def deletePublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePublishAppAction.class) Closure c) { - def a = new org.zstack.sdk.DeletePublishAppAction() + def deleteBackupFileInPublic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBackupFileInPublicAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBackupFileInPublicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12896,8 +13112,8 @@ abstract class ApiHelper { } - def deleteResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourceConfigAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteResourceConfigAction() + def deleteBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12923,8 +13139,8 @@ abstract class ApiHelper { } - def deleteResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourcePriceAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteResourcePriceAction() + def deleteBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBareMetal2ChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12950,8 +13166,8 @@ abstract class ApiHelper { } - def deleteResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteResourceStackAction() + def deleteBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBareMetal2GatewayAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBareMetal2GatewayAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -12977,8 +13193,8 @@ abstract class ApiHelper { } - def deleteResourceStackVmPortMonitor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourceStackVmPortMonitorAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteResourceStackVmPortMonitorAction() + def deleteBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBareMetal2ProvisionNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBareMetal2ProvisionNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13004,8 +13220,8 @@ abstract class ApiHelper { } - def deleteSchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSchedulerJobAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSchedulerJobAction() + def deleteBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13031,8 +13247,8 @@ abstract class ApiHelper { } - def deleteSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSchedulerJobGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSchedulerJobGroupAction() + def deleteBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBaremetalPxeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13058,8 +13274,8 @@ abstract class ApiHelper { } - def deleteSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSchedulerTriggerAction() + def deleteBilling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBillingAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBillingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13085,8 +13301,8 @@ abstract class ApiHelper { } - def deleteSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecretResourcePoolAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSecretResourcePoolAction() + def deleteBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBondingAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13112,8 +13328,8 @@ abstract class ApiHelper { } - def deleteSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSecurityGroupAction() + def deleteBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBuildAppAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBuildAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13139,8 +13355,8 @@ abstract class ApiHelper { } - def deleteSecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecurityGroupRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSecurityGroupRuleAction() + def deleteBuildAppExportHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteBuildAppExportHistoryAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteBuildAppExportHistoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13166,8 +13382,8 @@ abstract class ApiHelper { } - def deleteSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecurityMachineAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSecurityMachineAction() + def deleteCCSCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCCSCertificateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCCSCertificateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13193,8 +13409,8 @@ abstract class ApiHelper { } - def deleteSlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSlbGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteSlbGroupAction() + def deleteCbtTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCbtTaskAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCbtTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13220,8 +13436,8 @@ abstract class ApiHelper { } - def deleteStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteStackTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteStackTemplateAction() + def deleteCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCdpPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCdpPolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13247,8 +13463,8 @@ abstract class ApiHelper { } - def deleteTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteTagAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteTagAction() + def deleteCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCdpTaskAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCdpTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13274,8 +13490,8 @@ abstract class ApiHelper { } - def deleteUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteUserAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteUserAction() + def deleteCdpTaskData(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCdpTaskDataAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCdpTaskDataAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13301,8 +13517,8 @@ abstract class ApiHelper { } - def deleteUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteUserGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteUserGroupAction() + def deleteCephPrimaryStoragePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCephPrimaryStoragePoolAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCephPrimaryStoragePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13328,8 +13544,8 @@ abstract class ApiHelper { } - def deleteV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteV2VConversionHostAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteV2VConversionHostAction() + def deleteCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteCertificateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteCertificateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13355,8 +13571,8 @@ abstract class ApiHelper { } - def deleteVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVCenterAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVCenterAction() + def deleteCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13382,8 +13598,8 @@ abstract class ApiHelper { } - def deleteVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVRouterOspfAreaAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVRouterOspfAreaAction() + def deleteClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteClusterDRSAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteClusterDRSAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13409,8 +13625,8 @@ abstract class ApiHelper { } - def deleteVRouterRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVRouterRouteEntryAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVRouterRouteEntryAction() + def deleteConnectionAccessPointLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteConnectionAccessPointLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteConnectionAccessPointLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13436,8 +13652,8 @@ abstract class ApiHelper { } - def deleteVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVRouterRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVRouterRouteTableAction() + def deleteConnectionBetweenL3NetWorkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteConnectionBetweenL3NetWorkAndAliyunVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteConnectionBetweenL3NetWorkAndAliyunVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13463,8 +13679,8 @@ abstract class ApiHelper { } - def deleteVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVipAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVipAction() + def deleteContainerManagementEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteContainerManagementEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteContainerManagementEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13490,8 +13706,8 @@ abstract class ApiHelper { } - def deleteVipQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVipQosAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVipQosAction() + def deleteContainerResourceFromEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteContainerResourceFromEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteContainerResourceFromEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13517,8 +13733,8 @@ abstract class ApiHelper { } - def deleteVirtualBorderRouterLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVirtualBorderRouterLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVirtualBorderRouterLocalAction() + def deleteDataCenterInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDataCenterInLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteDataCenterInLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13544,8 +13760,8 @@ abstract class ApiHelper { } - def deleteVirtualRouterLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVirtualRouterLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVirtualRouterLocalAction() + def deleteDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDataVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteDataVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13571,8 +13787,8 @@ abstract class ApiHelper { } - def deleteVmBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmBootModeAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmBootModeAction() + def deleteDataset(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDatasetAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteDatasetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13598,8 +13814,8 @@ abstract class ApiHelper { } - def deleteVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmCdRomAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmCdRomAction() + def deleteDatasets(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDatasetsAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteDatasetsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13625,8 +13841,8 @@ abstract class ApiHelper { } - def deleteVmConsolePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmConsolePasswordAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmConsolePasswordAction() + def deleteDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13652,8 +13868,8 @@ abstract class ApiHelper { } - def deleteVmHostname(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmHostnameAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmHostnameAction() + def deleteDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteDiskOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteDiskOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13679,8 +13895,8 @@ abstract class ApiHelper { } - def deleteVmInstanceHaLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmInstanceHaLevelAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmInstanceHaLevelAction() + def deleteEcsImageLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsImageLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsImageLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13706,8 +13922,8 @@ abstract class ApiHelper { } - def deleteVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmNicAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmNicAction() + def deleteEcsImageRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsImageRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsImageRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13733,8 +13949,8 @@ abstract class ApiHelper { } - def deleteVmNicFromSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmNicFromSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmNicFromSecurityGroupAction() + def deleteEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13760,8 +13976,8 @@ abstract class ApiHelper { } - def deleteVmSshKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmSshKeyAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmSshKeyAction() + def deleteEcsInstanceLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsInstanceLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsInstanceLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13787,8 +14003,8 @@ abstract class ApiHelper { } - def deleteVmStaticIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmStaticIpAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmStaticIpAction() + def deleteEcsSecurityGroupInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsSecurityGroupInLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsSecurityGroupInLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13814,8 +14030,8 @@ abstract class ApiHelper { } - def deleteVmUserDefinedXml(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmUserDefinedXmlAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmUserDefinedXmlAction() + def deleteEcsSecurityGroupRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsSecurityGroupRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsSecurityGroupRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13841,8 +14057,8 @@ abstract class ApiHelper { } - def deleteVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmUserDefinedXmlHookScriptAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVmUserDefinedXmlHookScriptAction() + def deleteEcsSecurityGroupRuleRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsSecurityGroupRuleRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsSecurityGroupRuleRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13868,8 +14084,8 @@ abstract class ApiHelper { } - def deleteVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVniRangeAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVniRangeAction() + def deleteEcsVSwitchInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVSwitchInLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsVSwitchInLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13895,8 +14111,8 @@ abstract class ApiHelper { } - def deleteVolumeQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVolumeQosAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVolumeQosAction() + def deleteEcsVSwitchRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVSwitchRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsVSwitchRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13922,8 +14138,8 @@ abstract class ApiHelper { } - def deleteVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVolumeSnapshotAction() + def deleteEcsVpcInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVpcInLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsVpcInLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13949,8 +14165,8 @@ abstract class ApiHelper { } - def deleteVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVolumeSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVolumeSnapshotGroupAction() + def deleteEcsVpcRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEcsVpcRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEcsVpcRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -13976,8 +14192,8 @@ abstract class ApiHelper { } - def deleteVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcHaGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcHaGroupAction() + def deleteEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteEipAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14003,8 +14219,8 @@ abstract class ApiHelper { } - def deleteVpcIkeConfigLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcIkeConfigLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcIkeConfigLocalAction() + def deleteExportedImageFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteExportedImageFromBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteExportedImageFromBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14030,8 +14246,8 @@ abstract class ApiHelper { } - def deleteVpcIpSecConfigLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcIpSecConfigLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcIpSecConfigLocalAction() + def deleteExternalBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteExternalBackupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteExternalBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14057,8 +14273,8 @@ abstract class ApiHelper { } - def deleteVpcUserVpnGatewayLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcUserVpnGatewayLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcUserVpnGatewayLocalAction() + def deleteFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFirewallAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14084,8 +14300,8 @@ abstract class ApiHelper { } - def deleteVpcUserVpnGatewayRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcUserVpnGatewayRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcUserVpnGatewayRemoteAction() + def deleteFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallIpSetTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFirewallIpSetTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14111,8 +14327,8 @@ abstract class ApiHelper { } - def deleteVpcVpnConnectionLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcVpnConnectionLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcVpnConnectionLocalAction() + def deleteFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFirewallRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14138,8 +14354,8 @@ abstract class ApiHelper { } - def deleteVpcVpnConnectionRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcVpnConnectionRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcVpnConnectionRemoteAction() + def deleteFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFirewallRuleSetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14165,8 +14381,8 @@ abstract class ApiHelper { } - def deleteVpcVpnGatewayLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcVpnGatewayLocalAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVpcVpnGatewayLocalAction() + def deleteFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFirewallRuleTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFirewallRuleTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14192,8 +14408,8 @@ abstract class ApiHelper { } - def deleteVxlanL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVxlanL2NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteVxlanL2NetworkAction() + def deleteFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFlowCollectorAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFlowCollectorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14219,8 +14435,8 @@ abstract class ApiHelper { } - def deleteWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteWebhookAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteWebhookAction() + def deleteFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteFlowMeterAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteFlowMeterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14246,8 +14462,8 @@ abstract class ApiHelper { } - def deleteZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteZoneAction.class) Closure c) { - def a = new org.zstack.sdk.DeleteZoneAction() + def deleteGCJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteGCJobAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteGCJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14273,8 +14489,8 @@ abstract class ApiHelper { } - def destroyBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DestroyBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.DestroyBaremetalInstanceAction() + def deleteGuestVmScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteGuestVmScriptAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteGuestVmScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14300,8 +14516,8 @@ abstract class ApiHelper { } - def destroyVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DestroyVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.DestroyVmInstanceAction() + def deleteHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHostAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14327,8 +14543,8 @@ abstract class ApiHelper { } - def detachAliyunDiskFromEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAliyunDiskFromEcsAction.class) Closure c) { - def a = new org.zstack.sdk.DetachAliyunDiskFromEcsAction() + def deleteHostNetworkServiceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHostNetworkServiceTypeAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHostNetworkServiceTypeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14354,8 +14570,8 @@ abstract class ApiHelper { } - def detachAliyunKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAliyunKeyAction.class) Closure c) { - def a = new org.zstack.sdk.DetachAliyunKeyAction() + def deleteHostSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHostSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHostSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14381,8 +14597,8 @@ abstract class ApiHelper { } - def detachAppBuildSystemToZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAppBuildSystemToZoneAction.class) Closure c) { - def a = new org.zstack.sdk.DetachAppBuildSystemToZoneAction() + def deleteHybridEipFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHybridEipFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHybridEipFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14408,8 +14624,8 @@ abstract class ApiHelper { } - def detachAutoScalingTemplateFromGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAutoScalingTemplateFromGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DetachAutoScalingTemplateFromGroupAction() + def deleteHybridEipRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHybridEipRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHybridEipRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14435,8 +14651,8 @@ abstract class ApiHelper { } - def detachBackupStorageFromZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBackupStorageFromZoneAction.class) Closure c) { - def a = new org.zstack.sdk.DetachBackupStorageFromZoneAction() + def deleteHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteHybridKeySecretAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteHybridKeySecretAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14462,8 +14678,8 @@ abstract class ApiHelper { } - def detachBareMetal2GatewayFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBareMetal2GatewayFromClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachBareMetal2GatewayFromClusterAction() + def deleteIAM2VirtualIDLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIAM2VirtualIDLdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteIAM2VirtualIDLdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14489,8 +14705,8 @@ abstract class ApiHelper { } - def detachBareMetal2ProvisionNetworkFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBareMetal2ProvisionNetworkFromClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachBareMetal2ProvisionNetworkFromClusterAction() + def deleteIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14516,8 +14732,8 @@ abstract class ApiHelper { } - def detachBaremetalPxeServerFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBaremetalPxeServerFromClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachBaremetalPxeServerFromClusterAction() + def deleteIdentityZoneInLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIdentityZoneInLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteIdentityZoneInLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14543,8 +14759,8 @@ abstract class ApiHelper { } - def detachCCSCertificateFromUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachCCSCertificateFromUserAction.class) Closure c) { - def a = new org.zstack.sdk.DetachCCSCertificateFromUserAction() + def deleteImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteImageAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14570,8 +14786,8 @@ abstract class ApiHelper { } - def detachDataVolumeFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachDataVolumeFromVmAction.class) Closure c) { - def a = new org.zstack.sdk.DetachDataVolumeFromVmAction() + def deleteImagePackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteImagePackageAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteImagePackageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14597,8 +14813,8 @@ abstract class ApiHelper { } - def detachEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachEipAction.class) Closure c) { - def a = new org.zstack.sdk.DetachEipAction() + def deleteImageReplicationGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteImageReplicationGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteImageReplicationGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14624,8 +14840,8 @@ abstract class ApiHelper { } - def detachFirewallRuleSetFromL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachFirewallRuleSetFromL3Action.class) Closure c) { - def a = new org.zstack.sdk.DetachFirewallRuleSetFromL3Action() + def deleteInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteInstanceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteInstanceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14651,8 +14867,8 @@ abstract class ApiHelper { } - def detachHybridEipFromEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachHybridEipFromEcsAction.class) Closure c) { - def a = new org.zstack.sdk.DetachHybridEipFromEcsAction() + def deleteIpAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIpAddressAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteIpAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14678,8 +14894,8 @@ abstract class ApiHelper { } - def detachHybridKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachHybridKeyAction.class) Closure c) { - def a = new org.zstack.sdk.DetachHybridKeyAction() + def deleteIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteIpRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14705,8 +14921,8 @@ abstract class ApiHelper { } - def detachIscsiServerFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachIscsiServerFromClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachIscsiServerFromClusterAction() + def deleteIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteIscsiServerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteIscsiServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14732,8 +14948,8 @@ abstract class ApiHelper { } - def detachIsoFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachIsoFromVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.DetachIsoFromVmInstanceAction() + def deleteL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteL2NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteL2NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14759,8 +14975,8 @@ abstract class ApiHelper { } - def detachL2NetworkFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachL2NetworkFromClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachL2NetworkFromClusterAction() + def deleteL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14786,8 +15002,8 @@ abstract class ApiHelper { } - def detachL3NetworkFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachL3NetworkFromVmAction.class) Closure c) { - def a = new org.zstack.sdk.DetachL3NetworkFromVmAction() + def deleteLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14813,8 +15029,8 @@ abstract class ApiHelper { } - def detachL3NetworksFromIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachL3NetworksFromIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.DetachL3NetworksFromIPsecConnectionAction() + def deleteLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLdapServerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLdapServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14840,8 +15056,8 @@ abstract class ApiHelper { } - def detachMdevDeviceFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachMdevDeviceFromVmAction.class) Closure c) { - def a = new org.zstack.sdk.DetachMdevDeviceFromVmAction() + def deleteLicense(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLicenseAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLicenseAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14867,8 +15083,8 @@ abstract class ApiHelper { } - def detachMonitorTriggerFromTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachMonitorTriggerActionFromTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.DetachMonitorTriggerActionFromTriggerAction() + def deleteLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14894,8 +15110,8 @@ abstract class ApiHelper { } - def detachNetworkServiceFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachNetworkServiceFromL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.DetachNetworkServiceFromL3NetworkAction() + def deleteLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14921,8 +15137,8 @@ abstract class ApiHelper { } - def detachOssBucketFromEcsDataCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachOssBucketFromEcsDataCenterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachOssBucketFromEcsDataCenterAction() + def deleteLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLoadBalancerServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLoadBalancerServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14948,8 +15164,8 @@ abstract class ApiHelper { } - def detachPciDeviceFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPciDeviceFromVmAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPciDeviceFromVmAction() + def deleteLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLogConfigurationAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLogConfigurationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -14975,8 +15191,8 @@ abstract class ApiHelper { } - def detachPoliciesFromUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPoliciesFromUserAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPoliciesFromUserAction() + def deleteLogServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLogServerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLogServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15002,8 +15218,8 @@ abstract class ApiHelper { } - def detachPolicyFromUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPolicyFromUserAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPolicyFromUserAction() + def deleteLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteLongJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15029,8 +15245,8 @@ abstract class ApiHelper { } - def detachPolicyFromUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPolicyFromUserGroupAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPolicyFromUserGroupAction() + def deleteMdevDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMdevDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteMdevDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15056,8 +15272,8 @@ abstract class ApiHelper { } - def detachPolicyRouteRuleSetFromL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPolicyRouteRuleSetFromL3Action.class) Closure c) { - def a = new org.zstack.sdk.DetachPolicyRouteRuleSetFromL3Action() + def deleteMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMediaAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteMediaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15083,8 +15299,8 @@ abstract class ApiHelper { } - def detachPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPortForwardingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPortForwardingRuleAction() + def deleteModel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15110,8 +15326,8 @@ abstract class ApiHelper { } - def detachPriceTableFromAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPriceTableFromAccountAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPriceTableFromAccountAction() + def deleteModelCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelCenterAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15137,8 +15353,8 @@ abstract class ApiHelper { } - def detachPrimaryStorageFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPrimaryStorageFromClusterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachPrimaryStorageFromClusterAction() + def deleteModelEvaluationTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelEvaluationTaskAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelEvaluationTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15164,8 +15380,8 @@ abstract class ApiHelper { } - def detachScsiLunFromHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachScsiLunFromHostAction.class) Closure c) { - def a = new org.zstack.sdk.DetachScsiLunFromHostAction() + def deleteModelEvaluationTasks(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelEvaluationTasksAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelEvaluationTasksAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15191,8 +15407,8 @@ abstract class ApiHelper { } - def detachScsiLunFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachScsiLunFromVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.DetachScsiLunFromVmInstanceAction() + def deleteModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15218,8 +15434,8 @@ abstract class ApiHelper { } - def detachSecurityGroupFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachSecurityGroupFromL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.DetachSecurityGroupFromL3NetworkAction() + def deleteModelServiceInstanceGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelServiceInstanceGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelServiceInstanceGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15245,8 +15461,8 @@ abstract class ApiHelper { } - def detachTagFromResources(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachTagFromResourcesAction.class) Closure c) { - def a = new org.zstack.sdk.DetachTagFromResourcesAction() + def deleteModelServiceInstanceGroups(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelServiceInstanceGroupsAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelServiceInstanceGroupsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15272,8 +15488,8 @@ abstract class ApiHelper { } - def detachUsbDeviceFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachUsbDeviceFromVmAction.class) Closure c) { - def a = new org.zstack.sdk.DetachUsbDeviceFromVmAction() + def deleteModelServices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelServicesAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelServicesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15299,8 +15515,8 @@ abstract class ApiHelper { } - def detachVRouterRouteTableFromVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachVRouterRouteTableFromVRouterAction.class) Closure c) { - def a = new org.zstack.sdk.DetachVRouterRouteTableFromVRouterAction() + def deleteModels(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteModelsAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteModelsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15326,8 +15542,8 @@ abstract class ApiHelper { } - def disableCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DisableCdpTaskAction.class) Closure c) { - def a = new org.zstack.sdk.DisableCdpTaskAction() + def deleteMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMonitorTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteMonitorTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15353,8 +15569,8 @@ abstract class ApiHelper { } - def downloadBackupFileFromPublicCloud(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DownloadBackupFileFromPublicCloudAction.class) Closure c) { - def a = new org.zstack.sdk.DownloadBackupFileFromPublicCloudAction() + def deleteMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMonitorTriggerActionAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteMonitorTriggerActionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15380,8 +15596,8 @@ abstract class ApiHelper { } - def ejectZBox(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.EjectZBoxAction.class) Closure c) { - def a = new org.zstack.sdk.EjectZBoxAction() + def deleteMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteMulticastRouterAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteMulticastRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15407,8 +15623,8 @@ abstract class ApiHelper { } - def enableCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.EnableCdpTaskAction.class) Closure c) { - def a = new org.zstack.sdk.EnableCdpTaskAction() + def deleteNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNasFileSystemAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteNasFileSystemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15434,8 +15650,8 @@ abstract class ApiHelper { } - def executeAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteAutoScalingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.ExecuteAutoScalingRuleAction() + def deleteNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNasMountTargetAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteNasMountTargetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15461,8 +15677,8 @@ abstract class ApiHelper { } - def executeDRSScheduling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteDRSSchedulingAction.class) Closure c) { - def a = new org.zstack.sdk.ExecuteDRSSchedulingAction() + def deleteNicQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNicQosAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteNicQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15488,8 +15704,8 @@ abstract class ApiHelper { } - def exportBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExportBuildAppAction.class) Closure c) { - def a = new org.zstack.sdk.ExportBuildAppAction() + def deleteNvmeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteNvmeServerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteNvmeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15515,8 +15731,8 @@ abstract class ApiHelper { } - def exportImageFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExportImageFromBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.ExportImageFromBackupStorageAction() + def deleteOssBucketFileRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteOssBucketFileRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteOssBucketFileRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15542,8 +15758,8 @@ abstract class ApiHelper { } - def expungeBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.ExpungeBaremetalInstanceAction() + def deleteOssBucketNameLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteOssBucketNameLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteOssBucketNameLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15569,8 +15785,8 @@ abstract class ApiHelper { } - def expungeDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeDataVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.ExpungeDataVolumeAction() + def deleteOssBucketRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteOssBucketRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteOssBucketRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15596,8 +15812,8 @@ abstract class ApiHelper { } - def expungeImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeImageAction.class) Closure c) { - def a = new org.zstack.sdk.ExpungeImageAction() + def deletePciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePciDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePciDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15623,8 +15839,8 @@ abstract class ApiHelper { } - def expungeVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.ExpungeVmInstanceAction() + def deletePciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePciDeviceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePciDeviceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15650,8 +15866,8 @@ abstract class ApiHelper { } - def failoverFaultToleranceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.FailoverFaultToleranceVmAction.class) Closure c) { - def a = new org.zstack.sdk.FailoverFaultToleranceVmAction() + def deletePluginDrivers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePluginDriversAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePluginDriversAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15677,8 +15893,8 @@ abstract class ApiHelper { } - def gCAliyunSnapshotRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GCAliyunSnapshotRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GCAliyunSnapshotRemoteAction() + def deletePolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15704,8 +15920,8 @@ abstract class ApiHelper { } - def generateAccountBilling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateAccountBillingAction.class) Closure c) { - def a = new org.zstack.sdk.GenerateAccountBillingAction() + def deletePolicyRouteRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePolicyRouteRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15731,8 +15947,8 @@ abstract class ApiHelper { } - def generateMdevDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateMdevDevicesAction.class) Closure c) { - def a = new org.zstack.sdk.GenerateMdevDevicesAction() + def deletePolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePolicyRouteRuleSetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15758,8 +15974,8 @@ abstract class ApiHelper { } - def generateSriovPciDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateSriovPciDevicesAction.class) Closure c) { - def a = new org.zstack.sdk.GenerateSriovPciDevicesAction() + def deletePolicyRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePolicyRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15785,8 +16001,8 @@ abstract class ApiHelper { } - def getAccountPriceTableRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAccountPriceTableRefAction.class) Closure c) { - def a = new org.zstack.sdk.GetAccountPriceTableRefAction() + def deletePolicyRouteTableRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePolicyRouteTableRouteEntryAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePolicyRouteTableRouteEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15812,8 +16028,8 @@ abstract class ApiHelper { } - def getAccountQuotaUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAccountQuotaUsageAction.class) Closure c) { - def a = new org.zstack.sdk.GetAccountQuotaUsageAction() + def deletePortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePortForwardingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePortForwardingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15839,8 +16055,8 @@ abstract class ApiHelper { } - def getAliyunNasAccessGroupRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAliyunNasAccessGroupRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetAliyunNasAccessGroupRemoteAction() + def deletePortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePortMirrorAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePortMirrorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15866,8 +16082,8 @@ abstract class ApiHelper { } - def getAliyunNasFileSystemRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAliyunNasFileSystemRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetAliyunNasFileSystemRemoteAction() + def deletePortMirrorSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePortMirrorSessionAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePortMirrorSessionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15893,8 +16109,8 @@ abstract class ApiHelper { } - def getAliyunNasMountTargetRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAliyunNasMountTargetRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetAliyunNasMountTargetRemoteAction() + def deletePreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePreconfigurationTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePreconfigurationTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15920,8 +16136,8 @@ abstract class ApiHelper { } - def getAppBuildSystemCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAppBuildSystemCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetAppBuildSystemCapacityAction() + def deletePriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePriceTableAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePriceTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15947,8 +16163,8 @@ abstract class ApiHelper { } - def getAttachablePublicL3ForVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAttachablePublicL3ForVRouterAction.class) Closure c) { - def a = new org.zstack.sdk.GetAttachablePublicL3ForVRouterAction() + def deletePrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -15974,8 +16190,8 @@ abstract class ApiHelper { } - def getAttachableVpcL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAttachableVpcL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.GetAttachableVpcL3NetworkAction() + def deletePublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeletePublishAppAction.class) Closure c) { + def a = new org.zstack.sdk.DeletePublishAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16001,8 +16217,8 @@ abstract class ApiHelper { } - def getAvailableTriggers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAvailableTriggersAction.class) Closure c) { - def a = new org.zstack.sdk.GetAvailableTriggersAction() + def deleteReservedIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteReservedIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteReservedIpRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16028,8 +16244,8 @@ abstract class ApiHelper { } - def getBackupStorageCandidatesForImageMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageCandidatesForImageMigrationAction.class) Closure c) { - def a = new org.zstack.sdk.GetBackupStorageCandidatesForImageMigrationAction() + def deleteResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourceConfigAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteResourceConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16055,8 +16271,8 @@ abstract class ApiHelper { } - def getBackupStorageCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetBackupStorageCapacityAction() + def deleteResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourcePriceAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteResourcePriceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16082,8 +16298,8 @@ abstract class ApiHelper { } - def getBackupStorageForCreatingImageFromVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeAction() + def deleteResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16109,8 +16325,8 @@ abstract class ApiHelper { } - def getBackupStorageForCreatingImageFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeSnapshotAction() + def deleteResourceStackVmPortMonitor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteResourceStackVmPortMonitorAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteResourceStackVmPortMonitorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16136,8 +16352,8 @@ abstract class ApiHelper { } - def getBackupStorageTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetBackupStorageTypesAction() + def deleteSSOClient(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSSOClientAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSSOClientAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16163,8 +16379,8 @@ abstract class ApiHelper { } - def getBareMetal2ChassisPowerStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2ChassisPowerStatusAction.class) Closure c) { - def a = new org.zstack.sdk.GetBareMetal2ChassisPowerStatusAction() + def deleteSSORedirectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSSORedirectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSSORedirectTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16190,8 +16406,8 @@ abstract class ApiHelper { } - def getBareMetal2GatewayAllocatorStrategies(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2GatewayAllocatorStrategiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetBareMetal2GatewayAllocatorStrategiesAction() + def deleteSchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSchedulerJobAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSchedulerJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16217,8 +16433,8 @@ abstract class ApiHelper { } - def getBareMetal2ProvisionNetworkIpAddressCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2ProvisionNetworkIpAddressCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetBareMetal2ProvisionNetworkIpAddressCapacityAction() + def deleteSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSchedulerJobGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSchedulerJobGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16244,8 +16460,8 @@ abstract class ApiHelper { } - def getBareMetal2SupportedBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2SupportedBootModeAction.class) Closure c) { - def a = new org.zstack.sdk.GetBareMetal2SupportedBootModeAction() + def deleteSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16271,8 +16487,8 @@ abstract class ApiHelper { } - def getBaremetalChassisPowerStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBaremetalChassisPowerStatusAction.class) Closure c) { - def a = new org.zstack.sdk.GetBaremetalChassisPowerStatusAction() + def deleteSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16298,8 +16514,8 @@ abstract class ApiHelper { } - def getCandidateAffinityGroupForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateAffinityGroupForAttachingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateAffinityGroupForAttachingVmAction() + def deleteSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16325,8 +16541,8 @@ abstract class ApiHelper { } - def getCandidateAffinityGroupForCreatingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateAffinityGroupForCreatingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateAffinityGroupForCreatingVmAction() + def deleteSecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecurityGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSecurityGroupRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16352,8 +16568,8 @@ abstract class ApiHelper { } - def getCandidateBackupStorageForCreatingImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateBackupStorageForCreatingImageAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateBackupStorageForCreatingImageAction() + def deleteSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16379,8 +16595,8 @@ abstract class ApiHelper { } - def getCandidateClustersForAttachingL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateClustersForAttachingL2NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateClustersForAttachingL2NetworkAction() + def deleteSlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSlbGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSlbGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16406,8 +16622,8 @@ abstract class ApiHelper { } - def getCandidateIsoForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateIsoForAttachingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateIsoForAttachingVmAction() + def deleteSshKeyPair(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteSshKeyPairAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteSshKeyPairAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16433,8 +16649,8 @@ abstract class ApiHelper { } - def getCandidateL2NetworksForAttachingCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL2NetworksForAttachingClusterAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateL2NetworksForAttachingClusterAction() + def deleteStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteStackTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteStackTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16460,8 +16676,8 @@ abstract class ApiHelper { } - def getCandidateL3NetworksForChangeVmNicNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForChangeVmNicNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateL3NetworksForChangeVmNicNetworkAction() + def deleteTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteTagAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteTagAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16487,8 +16703,8 @@ abstract class ApiHelper { } - def getCandidateL3NetworksForIpSecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForIpSecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateL3NetworksForIpSecConnectionAction() + def deleteUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteUserAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16514,8 +16730,8 @@ abstract class ApiHelper { } - def getCandidateL3NetworksForLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateL3NetworksForLoadBalancerAction() + def deleteUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteUserGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteUserGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16541,8 +16757,8 @@ abstract class ApiHelper { } - def getCandidateL3NetworksForServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateL3NetworksForServerGroupAction() + def deleteUserProxyConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteUserProxyConfigAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteUserProxyConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16568,8 +16784,8 @@ abstract class ApiHelper { } - def getCandidateLdapEntryForBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateLdapEntryForBindingAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateLdapEntryForBindingAction() + def deleteV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteV2VConversionHostAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteV2VConversionHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16595,8 +16811,8 @@ abstract class ApiHelper { } - def getCandidateLdapEntryForIAM2Binding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateLdapEntryForIAM2BindingAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateLdapEntryForIAM2BindingAction() + def deleteVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVCenterAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16622,8 +16838,8 @@ abstract class ApiHelper { } - def getCandidateMiniHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateMiniHostsAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateMiniHostsAction() + def deleteVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVRouterOspfAreaAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVRouterOspfAreaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16649,8 +16865,8 @@ abstract class ApiHelper { } - def getCandidatePrimaryStoragesForCreatingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidatePrimaryStoragesForCreatingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidatePrimaryStoragesForCreatingVmAction() + def deleteVRouterRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVRouterRouteEntryAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVRouterRouteEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16676,8 +16892,8 @@ abstract class ApiHelper { } - def getCandidateVMForAttachingAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVMForAttachingAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateVMForAttachingAffinityGroupAction() + def deleteVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVRouterRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVRouterRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16703,8 +16919,8 @@ abstract class ApiHelper { } - def getCandidateVmForAttachingIso(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmForAttachingIsoAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateVmForAttachingIsoAction() + def deleteVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVipAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16730,8 +16946,8 @@ abstract class ApiHelper { } - def getCandidateVmNicForSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicForSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateVmNicForSecurityGroupAction() + def deleteVipQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVipQosAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVipQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16757,8 +16973,8 @@ abstract class ApiHelper { } - def getCandidateVmNicsForLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicsForLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateVmNicsForLoadBalancerAction() + def deleteVirtualBorderRouterLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVirtualBorderRouterLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVirtualBorderRouterLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16784,8 +17000,8 @@ abstract class ApiHelper { } - def getCandidateVmNicsForLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicsForLoadBalancerServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateVmNicsForLoadBalancerServerGroupAction() + def deleteVirtualRouterLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVirtualRouterLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVirtualRouterLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16811,8 +17027,8 @@ abstract class ApiHelper { } - def getCandidateVmNicsForPortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicsForPortMirrorAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateVmNicsForPortMirrorAction() + def deleteVmBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmBootModeAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmBootModeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16838,8 +17054,8 @@ abstract class ApiHelper { } - def getCandidateZonesClustersHostsForCreatingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateZonesClustersHostsForCreatingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetCandidateZonesClustersHostsForCreatingVmAction() + def deleteVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmCdRomAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmCdRomAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16865,8 +17081,8 @@ abstract class ApiHelper { } - def getClusterDRSStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetClusterDRSStatusAction.class) Closure c) { - def a = new org.zstack.sdk.GetClusterDRSStatusAction() + def deleteVmConsolePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmConsolePasswordAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmConsolePasswordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16892,8 +17108,8 @@ abstract class ApiHelper { } - def getClusterHostNetworkFacts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetClusterHostNetworkFactsAction.class) Closure c) { - def a = new org.zstack.sdk.GetClusterHostNetworkFactsAction() + def deleteVmHostname(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmHostnameAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmHostnameAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16919,8 +17135,8 @@ abstract class ApiHelper { } - def getConnectionAccessPointFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetConnectionAccessPointFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetConnectionAccessPointFromRemoteAction() + def deleteVmInstanceHaLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmInstanceHaLevelAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmInstanceHaLevelAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16946,8 +17162,8 @@ abstract class ApiHelper { } - def getConnectionBetweenL3NetworkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetConnectionBetweenL3NetworkAndAliyunVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.GetConnectionBetweenL3NetworkAndAliyunVSwitchAction() + def deleteVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmNicAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmNicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -16973,8 +17189,8 @@ abstract class ApiHelper { } - def getCpuMemoryCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCpuMemoryCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetCpuMemoryCapacityAction() + def deleteVmNicFromSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmNicFromSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmNicFromSecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17000,8 +17216,8 @@ abstract class ApiHelper { } - def getCreateEcsImageProgress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCreateEcsImageProgressAction.class) Closure c) { - def a = new org.zstack.sdk.GetCreateEcsImageProgressAction() + def deleteVmSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17027,9 +17243,9 @@ abstract class ApiHelper { } - def getCurrentTime(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCurrentTimeAction.class) Closure c) { - def a = new org.zstack.sdk.GetCurrentTimeAction() - + def deleteVmSshKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmSshKeyAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmSshKeyAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -17054,8 +17270,8 @@ abstract class ApiHelper { } - def getDataCenterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetDataCenterFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetDataCenterFromRemoteAction() + def deleteVmStaticIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmStaticIpAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmStaticIpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17081,8 +17297,8 @@ abstract class ApiHelper { } - def getDataVolumeAttachableVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetDataVolumeAttachableVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetDataVolumeAttachableVmAction() + def deleteVmUserDefinedXml(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmUserDefinedXmlAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmUserDefinedXmlAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17108,8 +17324,8 @@ abstract class ApiHelper { } - def getDebugSignal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetDebugSignalAction.class) Closure c) { - def a = new org.zstack.sdk.GetDebugSignalAction() + def deleteVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVmUserDefinedXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVmUserDefinedXmlHookScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17135,8 +17351,8 @@ abstract class ApiHelper { } - def getEcsInstanceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEcsInstanceTypeAction.class) Closure c) { - def a = new org.zstack.sdk.GetEcsInstanceTypeAction() + def deleteVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVniRangeAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVniRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17162,8 +17378,8 @@ abstract class ApiHelper { } - def getEcsInstanceVncUrl(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEcsInstanceVncUrlAction.class) Closure c) { - def a = new org.zstack.sdk.GetEcsInstanceVncUrlAction() + def deleteVolumeQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVolumeQosAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVolumeQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17189,8 +17405,8 @@ abstract class ApiHelper { } - def getEipAttachableVmNics(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEipAttachableVmNicsAction.class) Closure c) { - def a = new org.zstack.sdk.GetEipAttachableVmNicsAction() + def deleteVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17216,8 +17432,8 @@ abstract class ApiHelper { } - def getElaborationCategories(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetElaborationCategoriesAction.class) Closure c) { - def a = new org.zstack.sdk.GetElaborationCategoriesAction() + def deleteVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVolumeSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVolumeSnapshotGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17243,8 +17459,8 @@ abstract class ApiHelper { } - def getElaborations(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetElaborationsAction.class) Closure c) { - def a = new org.zstack.sdk.GetElaborationsAction() + def deleteVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcHaGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcHaGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17270,8 +17486,8 @@ abstract class ApiHelper { } - def getFactoryModeState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFactoryModeStateAction.class) Closure c) { - def a = new org.zstack.sdk.GetFactoryModeStateAction() + def deleteVpcIkeConfigLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcIkeConfigLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcIkeConfigLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17297,8 +17513,8 @@ abstract class ApiHelper { } - def getFaultToleranceVms(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFaultToleranceVmsAction.class) Closure c) { - def a = new org.zstack.sdk.GetFaultToleranceVmsAction() + def deleteVpcIpSecConfigLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcIpSecConfigLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcIpSecConfigLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17324,8 +17540,8 @@ abstract class ApiHelper { } - def getFlowMeterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFlowMeterRouterIdAction.class) Closure c) { - def a = new org.zstack.sdk.GetFlowMeterRouterIdAction() + def deleteVpcSharedQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcSharedQosAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcSharedQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17351,8 +17567,8 @@ abstract class ApiHelper { } - def getFreeIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFreeIpAction.class) Closure c) { - def a = new org.zstack.sdk.GetFreeIpAction() + def deleteVpcUserVpnGatewayLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcUserVpnGatewayLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcUserVpnGatewayLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17378,8 +17594,8 @@ abstract class ApiHelper { } - def getFreeIpOfIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFreeIpOfIpRangeAction.class) Closure c) { - def a = new org.zstack.sdk.GetFreeIpOfIpRangeAction() + def deleteVpcUserVpnGatewayRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcUserVpnGatewayRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcUserVpnGatewayRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17405,8 +17621,8 @@ abstract class ApiHelper { } - def getFreeIpOfL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFreeIpOfL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.GetFreeIpOfL3NetworkAction() + def deleteVpcVpnConnectionLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcVpnConnectionLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcVpnConnectionLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17432,8 +17648,8 @@ abstract class ApiHelper { } - def getGlobalConfigOptions(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetGlobalConfigOptionsAction.class) Closure c) { - def a = new org.zstack.sdk.GetGlobalConfigOptionsAction() + def deleteVpcVpnConnectionRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcVpnConnectionRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcVpnConnectionRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17459,8 +17675,8 @@ abstract class ApiHelper { } - def getHostAllocatorStrategies(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostAllocatorStrategiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostAllocatorStrategiesAction() + def deleteVpcVpnGatewayLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVpcVpnGatewayLocalAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVpcVpnGatewayLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17486,8 +17702,8 @@ abstract class ApiHelper { } - def getHostCandidatesForVmMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostCandidatesForVmMigrationAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostCandidatesForVmMigrationAction() + def deleteVxlanL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVxlanL2NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVxlanL2NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17513,8 +17729,8 @@ abstract class ApiHelper { } - def getHostIommuState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostIommuStateAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostIommuStateAction() + def deleteVxlanPoolRemoteVtep(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteVxlanPoolRemoteVtepAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteVxlanPoolRemoteVtepAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17540,8 +17756,8 @@ abstract class ApiHelper { } - def getHostIommuStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostIommuStatusAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostIommuStatusAction() + def deleteWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteWebhookAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteWebhookAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17567,8 +17783,8 @@ abstract class ApiHelper { } - def getHostNUMATopology(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostNUMATopologyAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostNUMATopologyAction() + def deleteZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeleteZoneAction.class) Closure c) { + def a = new org.zstack.sdk.DeleteZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17594,8 +17810,8 @@ abstract class ApiHelper { } - def getHostNetworkFacts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostNetworkFactsAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostNetworkFactsAction() + def deployAppDevelopmentService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeployAppDevelopmentServiceAction.class) Closure c) { + def a = new org.zstack.sdk.DeployAppDevelopmentServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17621,8 +17837,8 @@ abstract class ApiHelper { } - def getHostPhysicalMemoryFacts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostPhysicalMemoryFactsAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostPhysicalMemoryFactsAction() + def deployDistributedModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeployDistributedModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.DeployDistributedModelServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17648,8 +17864,8 @@ abstract class ApiHelper { } - def getHostResourceAllocation(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostResourceAllocationAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostResourceAllocationAction() + def deployModelEvalService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeployModelEvalServiceAction.class) Closure c) { + def a = new org.zstack.sdk.DeployModelEvalServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17675,8 +17891,8 @@ abstract class ApiHelper { } - def getHostTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostTaskAction.class) Closure c) { - def a = new org.zstack.sdk.GetHostTaskAction() + def deployModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DeployModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.DeployModelServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17702,8 +17918,8 @@ abstract class ApiHelper { } - def getHypervisorTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHypervisorTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetHypervisorTypesAction() + def describeVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DescribeVmInstanceRecoveryPointAction.class) Closure c) { + def a = new org.zstack.sdk.DescribeVmInstanceRecoveryPointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17729,8 +17945,8 @@ abstract class ApiHelper { } - def getIdentityZoneFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetIdentityZoneFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetIdentityZoneFromRemoteAction() + def destroyBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DestroyBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DestroyBaremetalInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17756,8 +17972,8 @@ abstract class ApiHelper { } - def getImageCandidatesForVmToChange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetImageCandidatesForVmToChangeAction.class) Closure c) { - def a = new org.zstack.sdk.GetImageCandidatesForVmToChangeAction() + def destroyVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DestroyVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DestroyVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17783,8 +17999,8 @@ abstract class ApiHelper { } - def getImageQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetImageQgaAction.class) Closure c) { - def a = new org.zstack.sdk.GetImageQgaAction() + def detachAliyunDiskFromEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAliyunDiskFromEcsAction.class) Closure c) { + def a = new org.zstack.sdk.DetachAliyunDiskFromEcsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17810,8 +18026,8 @@ abstract class ApiHelper { } - def getImagesFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetImagesFromImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.GetImagesFromImageStoreBackupStorageAction() + def detachAliyunKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAliyunKeyAction.class) Closure c) { + def a = new org.zstack.sdk.DetachAliyunKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17837,8 +18053,8 @@ abstract class ApiHelper { } - def getInterdependentL3NetworksImages(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetInterdependentL3NetworksImagesAction.class) Closure c) { - def a = new org.zstack.sdk.GetInterdependentL3NetworksImagesAction() + def detachAppBuildSystemToZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAppBuildSystemToZoneAction.class) Closure c) { + def a = new org.zstack.sdk.DetachAppBuildSystemToZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17864,8 +18080,8 @@ abstract class ApiHelper { } - def getIpAddressCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetIpAddressCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetIpAddressCapacityAction() + def detachAutoScalingTemplateFromGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachAutoScalingTemplateFromGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DetachAutoScalingTemplateFromGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17891,8 +18107,8 @@ abstract class ApiHelper { } - def getL2NetworkTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL2NetworkTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetL2NetworkTypesAction() + def detachBackupStorageFromZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBackupStorageFromZoneAction.class) Closure c) { + def a = new org.zstack.sdk.DetachBackupStorageFromZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17918,8 +18134,8 @@ abstract class ApiHelper { } - def getL3NetworkDhcpIpAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkDhcpIpAddressAction.class) Closure c) { - def a = new org.zstack.sdk.GetL3NetworkDhcpIpAddressAction() + def detachBareMetal2GatewayFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBareMetal2GatewayFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachBareMetal2GatewayFromClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17945,8 +18161,8 @@ abstract class ApiHelper { } - def getL3NetworkIpStatistic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkIpStatisticAction.class) Closure c) { - def a = new org.zstack.sdk.GetL3NetworkIpStatisticAction() + def detachBareMetal2ProvisionNetworkFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBareMetal2ProvisionNetworkFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachBareMetal2ProvisionNetworkFromClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17972,8 +18188,8 @@ abstract class ApiHelper { } - def getL3NetworkMtu(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkMtuAction.class) Closure c) { - def a = new org.zstack.sdk.GetL3NetworkMtuAction() + def detachBaremetalPxeServerFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachBaremetalPxeServerFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachBaremetalPxeServerFromClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -17999,8 +18215,8 @@ abstract class ApiHelper { } - def getL3NetworkRouterInterfaceIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkRouterInterfaceIpAction.class) Closure c) { - def a = new org.zstack.sdk.GetL3NetworkRouterInterfaceIpAction() + def detachCCSCertificateFromUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachCCSCertificateFromUserAction.class) Closure c) { + def a = new org.zstack.sdk.DetachCCSCertificateFromUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18026,8 +18242,8 @@ abstract class ApiHelper { } - def getL3NetworkTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetL3NetworkTypesAction() + def detachDataVolumeFromHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachDataVolumeFromHostAction.class) Closure c) { + def a = new org.zstack.sdk.DetachDataVolumeFromHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18053,8 +18269,8 @@ abstract class ApiHelper { } - def getLatestGuestToolsForVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLatestGuestToolsForVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetLatestGuestToolsForVmAction() + def detachDataVolumeFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachDataVolumeFromVmAction.class) Closure c) { + def a = new org.zstack.sdk.DetachDataVolumeFromVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18080,8 +18296,8 @@ abstract class ApiHelper { } - def getLdapEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLdapEntryAction.class) Closure c) { - def a = new org.zstack.sdk.GetLdapEntryAction() + def detachEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachEipAction.class) Closure c) { + def a = new org.zstack.sdk.DetachEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18107,8 +18323,8 @@ abstract class ApiHelper { } - def getLdapServerAvailableAttributes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLdapServerAvailableAttributesAction.class) Closure c) { - def a = new org.zstack.sdk.GetLdapServerAvailableAttributesAction() + def detachFirewallRuleSetFromL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachFirewallRuleSetFromL3Action.class) Closure c) { + def a = new org.zstack.sdk.DetachFirewallRuleSetFromL3Action() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18134,9 +18350,9 @@ abstract class ApiHelper { } - def getLicenseAddOns(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseAddOnsAction.class) Closure c) { - def a = new org.zstack.sdk.GetLicenseAddOnsAction() - + def detachHostFromHostSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachHostFromHostSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DetachHostFromHostSchedulingRuleGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -18161,8 +18377,8 @@ abstract class ApiHelper { } - def getLicenseCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseCapabilitiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetLicenseCapabilitiesAction() + def detachHybridEipFromEcs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachHybridEipFromEcsAction.class) Closure c) { + def a = new org.zstack.sdk.DetachHybridEipFromEcsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18188,9 +18404,9 @@ abstract class ApiHelper { } - def getLicenseInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseInfoAction.class) Closure c) { - def a = new org.zstack.sdk.GetLicenseInfoAction() - + def detachHybridKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachHybridKeyAction.class) Closure c) { + def a = new org.zstack.sdk.DetachHybridKeyAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -18215,9 +18431,9 @@ abstract class ApiHelper { } - def getLicenseRecords(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseRecordsAction.class) Closure c) { - def a = new org.zstack.sdk.GetLicenseRecordsAction() - + def detachIscsiServerFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachIscsiServerFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachIscsiServerFromClusterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -18242,8 +18458,8 @@ abstract class ApiHelper { } - def getLicenseUKeyStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseUKeyStatusAction.class) Closure c) { - def a = new org.zstack.sdk.GetLicenseUKeyStatusAction() + def detachIsoFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachIsoFromVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DetachIsoFromVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18269,8 +18485,8 @@ abstract class ApiHelper { } - def getLoadBalancerListenerACLEntries(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLoadBalancerListenerACLEntriesAction.class) Closure c) { - def a = new org.zstack.sdk.GetLoadBalancerListenerACLEntriesAction() + def detachL2NetworkFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachL2NetworkFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachL2NetworkFromClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18296,8 +18512,8 @@ abstract class ApiHelper { } - def getLocalRaidPhysicalDriveSmart(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLocalRaidPhysicalDriveSmartAction.class) Closure c) { - def a = new org.zstack.sdk.GetLocalRaidPhysicalDriveSmartAction() + def detachL3NetworkFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachL3NetworkFromVmAction.class) Closure c) { + def a = new org.zstack.sdk.DetachL3NetworkFromVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18323,8 +18539,8 @@ abstract class ApiHelper { } - def getLocalStorageHostDiskCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLocalStorageHostDiskCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetLocalStorageHostDiskCapacityAction() + def detachL3NetworksFromIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachL3NetworksFromIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.DetachL3NetworksFromIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18350,8 +18566,8 @@ abstract class ApiHelper { } - def getLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLogConfigurationAction.class) Closure c) { - def a = new org.zstack.sdk.GetLogConfigurationAction() + def detachMdevDeviceFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachMdevDeviceFromVmAction.class) Closure c) { + def a = new org.zstack.sdk.DetachMdevDeviceFromVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18377,9 +18593,9 @@ abstract class ApiHelper { } - def getLoginCaptcha(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLoginCaptchaAction.class) Closure c) { - def a = new org.zstack.sdk.GetLoginCaptchaAction() - + def detachMonitorTriggerFromTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachMonitorTriggerActionFromTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.DetachMonitorTriggerActionFromTriggerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -18404,9 +18620,9 @@ abstract class ApiHelper { } - def getManagementNodeArch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetManagementNodeArchAction.class) Closure c) { - def a = new org.zstack.sdk.GetManagementNodeArchAction() - + def detachNetworkServiceFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachNetworkServiceFromL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.DetachNetworkServiceFromL3NetworkAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -18431,9 +18647,36 @@ abstract class ApiHelper { } - def getManagementNodeOS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetManagementNodeOSAction.class) Closure c) { - def a = new org.zstack.sdk.GetManagementNodeOSAction() + def detachNicFromBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachNicFromBondingAction.class) Closure c) { + def a = new org.zstack.sdk.DetachNicFromBondingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + return out + } else { + return errorOut(a.call()) + } + } + + + def detachNvmeServerFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachNvmeServerFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachNvmeServerFromClusterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -18458,8 +18701,8 @@ abstract class ApiHelper { } - def getMdevDeviceCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMdevDeviceCandidatesAction.class) Closure c) { - def a = new org.zstack.sdk.GetMdevDeviceCandidatesAction() + def detachOssBucketFromEcsDataCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachOssBucketFromEcsDataCenterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachOssBucketFromEcsDataCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18485,8 +18728,8 @@ abstract class ApiHelper { } - def getMdevDeviceSpecCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMdevDeviceSpecCandidatesAction.class) Closure c) { - def a = new org.zstack.sdk.GetMdevDeviceSpecCandidatesAction() + def detachPciDeviceFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPciDeviceFromVmAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPciDeviceFromVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18512,8 +18755,8 @@ abstract class ApiHelper { } - def getMonitorItem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMonitorItemAction.class) Closure c) { - def a = new org.zstack.sdk.GetMonitorItemAction() + def detachPoliciesFromUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPoliciesFromUserAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPoliciesFromUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18539,8 +18782,8 @@ abstract class ApiHelper { } - def getNetworkServiceTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetNetworkServiceTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetNetworkServiceTypesAction() + def detachPolicyFromUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPolicyFromUserAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPolicyFromUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18566,8 +18809,8 @@ abstract class ApiHelper { } - def getNicQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetNicQosAction.class) Closure c) { - def a = new org.zstack.sdk.GetNicQosAction() + def detachPolicyFromUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPolicyFromUserGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPolicyFromUserGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18593,8 +18836,8 @@ abstract class ApiHelper { } - def getNoTriggerSchedulerJobs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetNoTriggerSchedulerJobsAction.class) Closure c) { - def a = new org.zstack.sdk.GetNoTriggerSchedulerJobsAction() + def detachPolicyRouteRuleSetFromL3(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPolicyRouteRuleSetFromL3Action.class) Closure c) { + def a = new org.zstack.sdk.DetachPolicyRouteRuleSetFromL3Action() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18620,8 +18863,8 @@ abstract class ApiHelper { } - def getOssBackupBucketFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOssBackupBucketFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetOssBackupBucketFromRemoteAction() + def detachPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPortForwardingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPortForwardingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18647,8 +18890,8 @@ abstract class ApiHelper { } - def getOssBucketFileFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOssBucketFileFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetOssBucketFileFromRemoteAction() + def detachPriceTableFromAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPriceTableFromAccountAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPriceTableFromAccountAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18674,8 +18917,8 @@ abstract class ApiHelper { } - def getOssBucketNameFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOssBucketNameFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetOssBucketNameFromRemoteAction() + def detachPrimaryStorageFromCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachPrimaryStorageFromClusterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachPrimaryStorageFromClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18701,8 +18944,8 @@ abstract class ApiHelper { } - def getPciDeviceCandidatesForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPciDeviceCandidatesForAttachingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetPciDeviceCandidatesForAttachingVmAction() + def detachProvisionNicFromBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachProvisionNicFromBondingAction.class) Closure c) { + def a = new org.zstack.sdk.DetachProvisionNicFromBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18728,8 +18971,8 @@ abstract class ApiHelper { } - def getPciDeviceCandidatesForNewCreateVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPciDeviceCandidatesForNewCreateVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetPciDeviceCandidatesForNewCreateVmAction() + def detachScsiLunFromHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachScsiLunFromHostAction.class) Closure c) { + def a = new org.zstack.sdk.DetachScsiLunFromHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18755,8 +18998,8 @@ abstract class ApiHelper { } - def getPciDeviceSpecCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPciDeviceSpecCandidatesAction.class) Closure c) { - def a = new org.zstack.sdk.GetPciDeviceSpecCandidatesAction() + def detachScsiLunFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachScsiLunFromVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DetachScsiLunFromVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18782,8 +19025,8 @@ abstract class ApiHelper { } - def getPlatformTimeZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPlatformTimeZoneAction.class) Closure c) { - def a = new org.zstack.sdk.GetPlatformTimeZoneAction() + def detachSecurityGroupFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachSecurityGroupFromL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.DetachSecurityGroupFromL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18809,8 +19052,8 @@ abstract class ApiHelper { } - def getPolicyRouteRuleSetFromVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPolicyRouteRuleSetFromVirtualRouterAction.class) Closure c) { - def a = new org.zstack.sdk.GetPolicyRouteRuleSetFromVirtualRouterAction() + def detachServiceFromObservabilityServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachServiceFromObservabilityServerAction.class) Closure c) { + def a = new org.zstack.sdk.DetachServiceFromObservabilityServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18836,8 +19079,8 @@ abstract class ApiHelper { } - def getPortForwardingAttachableVmNics(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPortForwardingAttachableVmNicsAction.class) Closure c) { - def a = new org.zstack.sdk.GetPortForwardingAttachableVmNicsAction() + def detachSshKeyPairFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachSshKeyPairFromVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.DetachSshKeyPairFromVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18863,8 +19106,8 @@ abstract class ApiHelper { } - def getPrimaryStorageAllocatorStrategies(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageAllocatorStrategiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetPrimaryStorageAllocatorStrategiesAction() + def detachTagFromResources(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachTagFromResourcesAction.class) Closure c) { + def a = new org.zstack.sdk.DetachTagFromResourcesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18890,8 +19133,8 @@ abstract class ApiHelper { } - def getPrimaryStorageCandidatesForVmMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageCandidatesForVmMigrationAction.class) Closure c) { - def a = new org.zstack.sdk.GetPrimaryStorageCandidatesForVmMigrationAction() + def detachUsbDeviceFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachUsbDeviceFromVmAction.class) Closure c) { + def a = new org.zstack.sdk.DetachUsbDeviceFromVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18917,8 +19160,8 @@ abstract class ApiHelper { } - def getPrimaryStorageCandidatesForVolumeMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageCandidatesForVolumeMigrationAction.class) Closure c) { - def a = new org.zstack.sdk.GetPrimaryStorageCandidatesForVolumeMigrationAction() + def detachUserDefinedXmlHookScriptFromVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachUserDefinedXmlHookScriptFromVmAction.class) Closure c) { + def a = new org.zstack.sdk.DetachUserDefinedXmlHookScriptFromVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18944,8 +19187,8 @@ abstract class ApiHelper { } - def getPrimaryStorageCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.GetPrimaryStorageCapacityAction() + def detachVRouterRouteTableFromVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachVRouterRouteTableFromVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.DetachVRouterRouteTableFromVRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18971,8 +19214,8 @@ abstract class ApiHelper { } - def getPrimaryStorageLicenseInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageLicenseInfoAction.class) Closure c) { - def a = new org.zstack.sdk.GetPrimaryStorageLicenseInfoAction() + def detachVipFromVpcSharedQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachVipFromVpcSharedQosAction.class) Closure c) { + def a = new org.zstack.sdk.DetachVipFromVpcSharedQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -18998,8 +19241,8 @@ abstract class ApiHelper { } - def getPrimaryStorageTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetPrimaryStorageTypesAction() + def detachVmFromVmSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DetachVmFromVmSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.DetachVmFromVmSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19025,8 +19268,8 @@ abstract class ApiHelper { } - def getResourceAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceAccountAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceAccountAction() + def disableCbtTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DisableCbtTaskAction.class) Closure c) { + def a = new org.zstack.sdk.DisableCbtTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19052,8 +19295,8 @@ abstract class ApiHelper { } - def getResourceBindableConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceBindableConfigAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceBindableConfigAction() + def disableCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DisableCdpTaskAction.class) Closure c) { + def a = new org.zstack.sdk.DisableCdpTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19079,8 +19322,8 @@ abstract class ApiHelper { } - def getResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceConfigAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceConfigAction() + def discoverExternalPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DiscoverExternalPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.DiscoverExternalPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19106,8 +19349,8 @@ abstract class ApiHelper { } - def getResourceFromPublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceFromPublishAppAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceFromPublishAppAction() + def downloadBackupFileFromPublicCloud(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.DownloadBackupFileFromPublicCloudAction.class) Closure c) { + def a = new org.zstack.sdk.DownloadBackupFileFromPublicCloudAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19133,8 +19376,8 @@ abstract class ApiHelper { } - def getResourceFromResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceFromResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceFromResourceStackAction() + def ejectZBox(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.EjectZBoxAction.class) Closure c) { + def a = new org.zstack.sdk.EjectZBoxAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19160,8 +19403,8 @@ abstract class ApiHelper { } - def getResourceNames(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceNamesAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceNamesAction() + def enableCbtTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.EnableCbtTaskAction.class) Closure c) { + def a = new org.zstack.sdk.EnableCbtTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19187,8 +19430,8 @@ abstract class ApiHelper { } - def getResourceStackFromResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceStackFromResourceAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceStackFromResourceAction() + def enableCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.EnableCdpTaskAction.class) Closure c) { + def a = new org.zstack.sdk.EnableCdpTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19214,8 +19457,8 @@ abstract class ApiHelper { } - def getResourceStackVmStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceStackVmStatusAction.class) Closure c) { - def a = new org.zstack.sdk.GetResourceStackVmStatusAction() + def executeAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteAutoScalingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.ExecuteAutoScalingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19241,8 +19484,8 @@ abstract class ApiHelper { } - def getRouteTableVpcVRouterCandidate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetRouteTableVpcVRouterCandidateAction.class) Closure c) { - def a = new org.zstack.sdk.GetRouteTableVpcVRouterCandidateAction() + def executeDRSScheduling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteDRSSchedulingAction.class) Closure c) { + def a = new org.zstack.sdk.ExecuteDRSSchedulingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19268,8 +19511,8 @@ abstract class ApiHelper { } - def getSchedulerExecutionReport(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSchedulerExecutionReportAction.class) Closure c) { - def a = new org.zstack.sdk.GetSchedulerExecutionReportAction() + def executeGuestVmCommand(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteGuestVmCommandAction.class) Closure c) { + def a = new org.zstack.sdk.ExecuteGuestVmCommandAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19295,8 +19538,8 @@ abstract class ApiHelper { } - def getScsiLunCandidatesForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetScsiLunCandidatesForAttachingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetScsiLunCandidatesForAttachingVmAction() + def executeGuestVmScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExecuteGuestVmScriptAction.class) Closure c) { + def a = new org.zstack.sdk.ExecuteGuestVmScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19322,8 +19565,8 @@ abstract class ApiHelper { } - def getSharedBlockCandidate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSharedBlockCandidateAction.class) Closure c) { - def a = new org.zstack.sdk.GetSharedBlockCandidateAction() + def exportBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExportBuildAppAction.class) Closure c) { + def a = new org.zstack.sdk.ExportBuildAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19349,8 +19592,8 @@ abstract class ApiHelper { } - def getSpiceCertificates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSpiceCertificatesAction.class) Closure c) { - def a = new org.zstack.sdk.GetSpiceCertificatesAction() + def exportImageFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExportImageFromBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.ExportImageFromBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19376,8 +19619,8 @@ abstract class ApiHelper { } - def getSupportedCloudFormationResources(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSupportedCloudFormationResourcesAction.class) Closure c) { - def a = new org.zstack.sdk.GetSupportedCloudFormationResourcesAction() + def exportNbdVolumes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExportNbdVolumesAction.class) Closure c) { + def a = new org.zstack.sdk.ExportNbdVolumesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19403,9 +19646,9 @@ abstract class ApiHelper { } - def getSupportedIdentityModels(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSupportedIdentityModelsAction.class) Closure c) { - def a = new org.zstack.sdk.GetSupportedIdentityModelsAction() - + def exportVmOvaPackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExportVmOvaPackageAction.class) Closure c) { + def a = new org.zstack.sdk.ExportVmOvaPackageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -19430,8 +19673,8 @@ abstract class ApiHelper { } - def getTaskProgress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTaskProgressAction.class) Closure c) { - def a = new org.zstack.sdk.GetTaskProgressAction() + def expungeBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.ExpungeBaremetalInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19457,8 +19700,8 @@ abstract class ApiHelper { } - def getTrashOnBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTrashOnBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.GetTrashOnBackupStorageAction() + def expungeDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeDataVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.ExpungeDataVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19484,8 +19727,8 @@ abstract class ApiHelper { } - def getTrashOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTrashOnPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.GetTrashOnPrimaryStorageAction() + def expungeImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeImageAction.class) Closure c) { + def a = new org.zstack.sdk.ExpungeImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19511,9 +19754,9 @@ abstract class ApiHelper { } - def getTwoFactorAuthenticationSecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTwoFactorAuthenticationSecretAction.class) Closure c) { - def a = new org.zstack.sdk.GetTwoFactorAuthenticationSecretAction() - + def expungeImageGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeImageGroupAction.class) Closure c) { + def a = new org.zstack.sdk.ExpungeImageGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -19538,9 +19781,9 @@ abstract class ApiHelper { } - def getTwoFactorAuthenticationState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTwoFactorAuthenticationStateAction.class) Closure c) { - def a = new org.zstack.sdk.GetTwoFactorAuthenticationStateAction() - + def expungeVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.ExpungeVmInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -19565,8 +19808,8 @@ abstract class ApiHelper { } - def getUploadImageJobDetails(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetUploadImageJobDetailsAction.class) Closure c) { - def a = new org.zstack.sdk.GetUploadImageJobDetailsAction() + def expungeVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ExpungeVmUserDefinedXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.ExpungeVmUserDefinedXmlHookScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19592,8 +19835,8 @@ abstract class ApiHelper { } - def getUsbDeviceCandidatesForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetUsbDeviceCandidatesForAttachingVmAction.class) Closure c) { - def a = new org.zstack.sdk.GetUsbDeviceCandidatesForAttachingVmAction() + def failoverFaultToleranceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.FailoverFaultToleranceVmAction.class) Closure c) { + def a = new org.zstack.sdk.FailoverFaultToleranceVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19619,8 +19862,8 @@ abstract class ApiHelper { } - def getVRouterFlowCounter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterFlowCounterAction.class) Closure c) { - def a = new org.zstack.sdk.GetVRouterFlowCounterAction() + def flattenVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.FlattenVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.FlattenVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19646,8 +19889,8 @@ abstract class ApiHelper { } - def getVRouterOspfNeighbor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterOspfNeighborAction.class) Closure c) { - def a = new org.zstack.sdk.GetVRouterOspfNeighborAction() + def flattenVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.FlattenVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.FlattenVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19673,8 +19916,8 @@ abstract class ApiHelper { } - def getVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.GetVRouterRouteTableAction() + def fstrimVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.FstrimVmAction.class) Closure c) { + def a = new org.zstack.sdk.FstrimVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19700,8 +19943,8 @@ abstract class ApiHelper { } - def getVRouterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterRouterIdAction.class) Closure c) { - def a = new org.zstack.sdk.GetVRouterRouterIdAction() + def gCAliyunSnapshotRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GCAliyunSnapshotRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GCAliyunSnapshotRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19727,8 +19970,8 @@ abstract class ApiHelper { } - def getVSwitchTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVSwitchTypesAction.class) Closure c) { - def a = new org.zstack.sdk.GetVSwitchTypesAction() + def generateAccountBilling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateAccountBillingAction.class) Closure c) { + def a = new org.zstack.sdk.GenerateAccountBillingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19754,9 +19997,36 @@ abstract class ApiHelper { } - def getVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVersionAction.class) Closure c) { - def a = new org.zstack.sdk.GetVersionAction() + def generateMdevDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateMdevDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.GenerateMdevDevicesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + return out + } else { + return errorOut(a.call()) + } + } + + + def generateModelMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateModelMetadataAction.class) Closure c) { + def a = new org.zstack.sdk.GenerateModelMetadataAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -19781,8 +20051,8 @@ abstract class ApiHelper { } - def getVipQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVipQosAction.class) Closure c) { - def a = new org.zstack.sdk.GetVipQosAction() + def generateSeMdevDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateSeMdevDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.GenerateSeMdevDevicesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19808,8 +20078,8 @@ abstract class ApiHelper { } - def getVipUsedPorts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVipUsedPortsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVipUsedPortsAction() + def generateSriovPciDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateSriovPciDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.GenerateSriovPciDevicesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19835,8 +20105,8 @@ abstract class ApiHelper { } - def getVmAttachableDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmAttachableDataVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmAttachableDataVolumeAction() + def generateSshKeyPair(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GenerateSshKeyPairAction.class) Closure c) { + def a = new org.zstack.sdk.GenerateSshKeyPairAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19862,8 +20132,8 @@ abstract class ApiHelper { } - def getVmAttachableL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmAttachableL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmAttachableL3NetworkAction() + def getAccessPath(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAccessPathAction.class) Closure c) { + def a = new org.zstack.sdk.GetAccessPathAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19889,8 +20159,8 @@ abstract class ApiHelper { } - def getVmBootOrder(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmBootOrderAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmBootOrderAction() + def getAccountPriceTableRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAccountPriceTableRefAction.class) Closure c) { + def a = new org.zstack.sdk.GetAccountPriceTableRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19916,8 +20186,8 @@ abstract class ApiHelper { } - def getVmCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmCapabilitiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmCapabilitiesAction() + def getAccountQuotaUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAccountQuotaUsageAction.class) Closure c) { + def a = new org.zstack.sdk.GetAccountQuotaUsageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19943,8 +20213,8 @@ abstract class ApiHelper { } - def getVmConsoleAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmConsoleAddressAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmConsoleAddressAction() + def getAliyunNasAccessGroupRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAliyunNasAccessGroupRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetAliyunNasAccessGroupRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19970,8 +20240,8 @@ abstract class ApiHelper { } - def getVmConsolePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmConsolePasswordAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmConsolePasswordAction() + def getAliyunNasFileSystemRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAliyunNasFileSystemRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetAliyunNasFileSystemRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -19997,8 +20267,8 @@ abstract class ApiHelper { } - def getVmDeviceAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmDeviceAddressAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmDeviceAddressAction() + def getAliyunNasMountTargetRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAliyunNasMountTargetRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetAliyunNasMountTargetRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20024,8 +20294,8 @@ abstract class ApiHelper { } - def getVmEmulatorPinning(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmEmulatorPinningAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmEmulatorPinningAction() + def getAppBuildSystemCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAppBuildSystemCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetAppBuildSystemCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20051,8 +20321,8 @@ abstract class ApiHelper { } - def getVmGuestToolsInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmGuestToolsInfoAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmGuestToolsInfoAction() + def getAttachablePublicL3ForVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAttachablePublicL3ForVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.GetAttachablePublicL3ForVRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20078,8 +20348,8 @@ abstract class ApiHelper { } - def getVmHostname(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmHostnameAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmHostnameAction() + def getAttachableVpcL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAttachableVpcL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetAttachableVpcL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20105,8 +20375,8 @@ abstract class ApiHelper { } - def getVmInstanceFirstBootDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceFirstBootDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmInstanceFirstBootDeviceAction() + def getAvailableTriggers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAvailableTriggersAction.class) Closure c) { + def a = new org.zstack.sdk.GetAvailableTriggersAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20132,8 +20402,8 @@ abstract class ApiHelper { } - def getVmInstanceHaLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceHaLevelAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmInstanceHaLevelAction() + def getAvailableVpcL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetAvailableVpcL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetAvailableVpcL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20159,8 +20429,8 @@ abstract class ApiHelper { } - def getVmInstanceProtectedRecoveryPoints(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceProtectedRecoveryPointsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmInstanceProtectedRecoveryPointsAction() + def getBackupStorageCandidatesForImageMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageCandidatesForImageMigrationAction.class) Closure c) { + def a = new org.zstack.sdk.GetBackupStorageCandidatesForImageMigrationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20186,8 +20456,8 @@ abstract class ApiHelper { } - def getVmInstanceRecoveryPoints(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceRecoveryPointsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmInstanceRecoveryPointsAction() + def getBackupStorageCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetBackupStorageCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20213,8 +20483,8 @@ abstract class ApiHelper { } - def getVmMigrationCandidateHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmMigrationCandidateHostsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmMigrationCandidateHostsAction() + def getBackupStorageForCreatingImageFromVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20240,8 +20510,8 @@ abstract class ApiHelper { } - def getVmMonitorNumber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmMonitorNumberAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmMonitorNumberAction() + def getBackupStorageForCreatingImageFromVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.GetBackupStorageForCreatingImageFromVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20267,8 +20537,8 @@ abstract class ApiHelper { } - def getVmNicAttachableEips(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmNicAttachableEipsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmNicAttachableEipsAction() + def getBackupStorageTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBackupStorageTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetBackupStorageTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20294,8 +20564,8 @@ abstract class ApiHelper { } - def getVmNicAttachedNetworkService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmNicAttachedNetworkServiceAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmNicAttachedNetworkServiceAction() + def getBareMetal2ChassisPowerStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2ChassisPowerStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetBareMetal2ChassisPowerStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20321,8 +20591,8 @@ abstract class ApiHelper { } - def getVmNuma(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmNumaAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmNumaAction() + def getBareMetal2GatewayAllocatorStrategies(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2GatewayAllocatorStrategiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetBareMetal2GatewayAllocatorStrategiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20348,8 +20618,8 @@ abstract class ApiHelper { } - def getVmQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmQgaAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmQgaAction() + def getBareMetal2ProvisionNetworkIpAddressCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2ProvisionNetworkIpAddressCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetBareMetal2ProvisionNetworkIpAddressCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20375,8 +20645,8 @@ abstract class ApiHelper { } - def getVmRDP(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmRDPAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmRDPAction() + def getBareMetal2SupportedBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBareMetal2SupportedBootModeAction.class) Closure c) { + def a = new org.zstack.sdk.GetBareMetal2SupportedBootModeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20402,8 +20672,8 @@ abstract class ApiHelper { } - def getVmSshKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmSshKeyAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmSshKeyAction() + def getBaremetalChassisPowerStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBaremetalChassisPowerStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetBaremetalChassisPowerStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20429,8 +20699,8 @@ abstract class ApiHelper { } - def getVmStartingCandidateClustersHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmStartingCandidateClustersHostsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmStartingCandidateClustersHostsAction() + def getBlockPrimaryStorageMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetBlockPrimaryStorageMetadataAction.class) Closure c) { + def a = new org.zstack.sdk.GetBlockPrimaryStorageMetadataAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20456,8 +20726,8 @@ abstract class ApiHelper { } - def getVmUsbRedirect(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmUsbRedirectAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmUsbRedirectAction() + def getCandidateAffinityGroupForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateAffinityGroupForAttachingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateAffinityGroupForAttachingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20483,8 +20753,8 @@ abstract class ApiHelper { } - def getVmXml(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmXmlAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmXmlAction() + def getCandidateAffinityGroupForCreatingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateAffinityGroupForCreatingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateAffinityGroupForCreatingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20510,8 +20780,8 @@ abstract class ApiHelper { } - def getVmXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmXmlHookScriptAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmXmlHookScriptAction() + def getCandidateBackupStorageForCreatingImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateBackupStorageForCreatingImageAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateBackupStorageForCreatingImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20537,8 +20807,8 @@ abstract class ApiHelper { } - def getVmsCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmsCapabilitiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmsCapabilitiesAction() + def getCandidateClustersForAttachingL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateClustersForAttachingL2NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateClustersForAttachingL2NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20564,8 +20834,8 @@ abstract class ApiHelper { } - def getVmvNUMATopology(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmvNUMATopologyAction.class) Closure c) { - def a = new org.zstack.sdk.GetVmvNUMATopologyAction() + def getCandidateInterfaceVlanIds(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateInterfaceVlanIdsAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateInterfaceVlanIdsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20591,8 +20861,8 @@ abstract class ApiHelper { } - def getVolumeCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeCapabilitiesAction.class) Closure c) { - def a = new org.zstack.sdk.GetVolumeCapabilitiesAction() + def getCandidateIsoForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateIsoForAttachingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateIsoForAttachingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20618,8 +20888,8 @@ abstract class ApiHelper { } - def getVolumeFormat(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeFormatAction.class) Closure c) { - def a = new org.zstack.sdk.GetVolumeFormatAction() + def getCandidateL2NetworksForAttachingCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL2NetworksForAttachingClusterAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateL2NetworksForAttachingClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20645,8 +20915,8 @@ abstract class ApiHelper { } - def getVolumeQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeQosAction.class) Closure c) { - def a = new org.zstack.sdk.GetVolumeQosAction() + def getCandidateL3NetworksForChangeVmNicNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForChangeVmNicNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateL3NetworksForChangeVmNicNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20672,8 +20942,8 @@ abstract class ApiHelper { } - def getVolumeSnapshotSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeSnapshotSizeAction.class) Closure c) { - def a = new org.zstack.sdk.GetVolumeSnapshotSizeAction() + def getCandidateL3NetworksForIpSecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForIpSecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateL3NetworksForIpSecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20699,8 +20969,8 @@ abstract class ApiHelper { } - def getVpcAttachedEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedEipAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedEipAction() + def getCandidateL3NetworksForLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateL3NetworksForLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20726,8 +20996,8 @@ abstract class ApiHelper { } - def getVpcAttachedIpsec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedIpsecAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedIpsecAction() + def getCandidateL3NetworksForServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateL3NetworksForServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateL3NetworksForServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20753,8 +21023,8 @@ abstract class ApiHelper { } - def getVpcAttachedLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedLoadBalancerAction() + def getCandidateLdapEntryForBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateLdapEntryForBindingAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateLdapEntryForBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20780,8 +21050,8 @@ abstract class ApiHelper { } - def getVpcAttachedNetflow(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedNetflowAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedNetflowAction() + def getCandidateLdapEntryForIAM2Binding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateLdapEntryForIAM2BindingAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateLdapEntryForIAM2BindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20807,8 +21077,8 @@ abstract class ApiHelper { } - def getVpcAttachedOspf(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedOspfAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedOspfAction() + def getCandidateMiniHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateMiniHostsAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateMiniHostsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20834,8 +21104,8 @@ abstract class ApiHelper { } - def getVpcAttachedPortForwardingRules(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedPortForwardingRulesAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedPortForwardingRulesAction() + def getCandidateNetworkInterfaces(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateNetworkInterfacesAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateNetworkInterfacesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20861,8 +21131,8 @@ abstract class ApiHelper { } - def getVpcAttachedVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedVipAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcAttachedVipAction() + def getCandidatePrimaryStoragesForCreatingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidatePrimaryStoragesForCreatingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidatePrimaryStoragesForCreatingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20888,8 +21158,8 @@ abstract class ApiHelper { } - def getVpcMulticastRoute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcMulticastRouteAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcMulticastRouteAction() + def getCandidateVMForAttachingAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVMForAttachingAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateVMForAttachingAffinityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20915,8 +21185,8 @@ abstract class ApiHelper { } - def getVpcVRouterDistributedRoutingConnections(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVRouterDistributedRoutingConnectionsAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcVRouterDistributedRoutingConnectionsAction() + def getCandidateVmForAttachingIso(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmForAttachingIsoAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateVmForAttachingIsoAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20942,8 +21212,8 @@ abstract class ApiHelper { } - def getVpcVRouterDistributedRoutingEnabled(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVRouterDistributedRoutingEnabledAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcVRouterDistributedRoutingEnabledAction() + def getCandidateVmNicForSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicForSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateVmNicForSecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20969,8 +21239,8 @@ abstract class ApiHelper { } - def getVpcVRouterNetworkServiceState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVRouterNetworkServiceStateAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcVRouterNetworkServiceStateAction() + def getCandidateVmNicsForLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicsForLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateVmNicsForLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -20996,8 +21266,8 @@ abstract class ApiHelper { } - def getVpcVpnConfigurationFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVpnConfigurationFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.GetVpcVpnConfigurationFromRemoteAction() + def getCandidateVmNicsForLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicsForLoadBalancerServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateVmNicsForLoadBalancerServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21023,8 +21293,8 @@ abstract class ApiHelper { } - def getZBoxBackupDetails(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetZBoxBackupDetailsAction.class) Closure c) { - def a = new org.zstack.sdk.GetZBoxBackupDetailsAction() + def getCandidateVmNicsForPortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateVmNicsForPortMirrorAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateVmNicsForPortMirrorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21050,8 +21320,8 @@ abstract class ApiHelper { } - def getZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetZoneAction.class) Closure c) { - def a = new org.zstack.sdk.GetZoneAction() + def getCandidateZonesClustersHostsForCreatingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCandidateZonesClustersHostsForCreatingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetCandidateZonesClustersHostsForCreatingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21077,8 +21347,8 @@ abstract class ApiHelper { } - def identifyHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IdentifyHostAction.class) Closure c) { - def a = new org.zstack.sdk.IdentifyHostAction() + def getCdpBackupStorageRequirement(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCdpBackupStorageRequirementAction.class) Closure c) { + def a = new org.zstack.sdk.GetCdpBackupStorageRequirementAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21104,8 +21374,8 @@ abstract class ApiHelper { } - def inspectBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.InspectBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.InspectBareMetal2ChassisAction() + def getChainTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetChainTaskAction.class) Closure c) { + def a = new org.zstack.sdk.GetChainTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21131,8 +21401,8 @@ abstract class ApiHelper { } - def inspectBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.InspectBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.InspectBaremetalChassisAction() + def getChronyServers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetChronyServersAction.class) Closure c) { + def a = new org.zstack.sdk.GetChronyServersAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21158,36 +21428,9 @@ abstract class ApiHelper { } - def isOpensourceVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IsOpensourceVersionAction.class) Closure c) { - def a = new org.zstack.sdk.IsOpensourceVersionAction() - - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def isReadyToGo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IsReadyToGoAction.class) Closure c) { - def a = new org.zstack.sdk.IsReadyToGoAction() - + def getClusterDRSStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetClusterDRSStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetClusterDRSStatusAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21212,8 +21455,8 @@ abstract class ApiHelper { } - def isVfNicAvailableInL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IsVfNicAvailableInL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.IsVfNicAvailableInL3NetworkAction() + def getClusterHostNetworkFacts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetClusterHostNetworkFactsAction.class) Closure c) { + def a = new org.zstack.sdk.GetClusterHostNetworkFactsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21239,8 +21482,8 @@ abstract class ApiHelper { } - def kvmRunShell(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.KvmRunShellAction.class) Closure c) { - def a = new org.zstack.sdk.KvmRunShellAction() + def getConnectionAccessPointFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetConnectionAccessPointFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetConnectionAccessPointFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21266,8 +21509,8 @@ abstract class ApiHelper { } - def listVMsFromKVMHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ListVMsFromKVMHostAction.class) Closure c) { - def a = new org.zstack.sdk.ListVMsFromKVMHostAction() + def getConnectionBetweenL3NetworkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetConnectionBetweenL3NetworkAndAliyunVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.GetConnectionBetweenL3NetworkAndAliyunVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21293,8 +21536,8 @@ abstract class ApiHelper { } - def localStorageGetVolumeMigratableHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocalStorageGetVolumeMigratableHostsAction.class) Closure c) { - def a = new org.zstack.sdk.LocalStorageGetVolumeMigratableHostsAction() + def getContainerUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetContainerUsageAction.class) Closure c) { + def a = new org.zstack.sdk.GetContainerUsageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21320,8 +21563,8 @@ abstract class ApiHelper { } - def localStorageMigrateVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocalStorageMigrateVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.LocalStorageMigrateVolumeAction() + def getCpuMemoryCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCpuMemoryCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetCpuMemoryCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21347,8 +21590,8 @@ abstract class ApiHelper { } - def locateHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocateHostNetworkInterfaceAction.class) Closure c) { - def a = new org.zstack.sdk.LocateHostNetworkInterfaceAction() + def getCreateEcsImageProgress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCreateEcsImageProgressAction.class) Closure c) { + def a = new org.zstack.sdk.GetCreateEcsImageProgressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21374,9 +21617,9 @@ abstract class ApiHelper { } - def locateLocalRaidPhysicalDrive(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocateLocalRaidPhysicalDriveAction.class) Closure c) { - def a = new org.zstack.sdk.LocateLocalRaidPhysicalDriveAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getCurrentTime(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetCurrentTimeAction.class) Closure c) { + def a = new org.zstack.sdk.GetCurrentTimeAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21401,9 +21644,9 @@ abstract class ApiHelper { } - def logInByAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInByAccountAction.class) Closure c) { - def a = new org.zstack.sdk.LogInByAccountAction() - + def getDataCenterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetDataCenterFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetDataCenterFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21428,9 +21671,9 @@ abstract class ApiHelper { } - def logInByLdap(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInByLdapAction.class) Closure c) { - def a = new org.zstack.sdk.LogInByLdapAction() - + def getDataVolumeAttachableVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetDataVolumeAttachableVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetDataVolumeAttachableVmAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21455,9 +21698,9 @@ abstract class ApiHelper { } - def logInByUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInByUserAction.class) Closure c) { - def a = new org.zstack.sdk.LogInByUserAction() - + def getDebugSignal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetDebugSignalAction.class) Closure c) { + def a = new org.zstack.sdk.GetDebugSignalAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21482,9 +21725,9 @@ abstract class ApiHelper { } - def logOut(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogOutAction.class) Closure c) { - def a = new org.zstack.sdk.LogOutAction() - + def getEcsInstanceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEcsInstanceTypeAction.class) Closure c) { + def a = new org.zstack.sdk.GetEcsInstanceTypeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21509,9 +21752,9 @@ abstract class ApiHelper { } - def loginByCas(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LoginByCasAction.class) Closure c) { - def a = new org.zstack.sdk.LoginByCasAction() - + def getEcsInstanceVncUrl(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEcsInstanceVncUrlAction.class) Closure c) { + def a = new org.zstack.sdk.GetEcsInstanceVncUrlAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21536,9 +21779,9 @@ abstract class ApiHelper { } - def loginIAM2VirtualIDWithLdap(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LoginIAM2VirtualIDWithLdapAction.class) Closure c) { - def a = new org.zstack.sdk.LoginIAM2VirtualIDWithLdapAction() - + def getEipAttachableVmNics(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEipAttachableVmNicsAction.class) Closure c) { + def a = new org.zstack.sdk.GetEipAttachableVmNicsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -21563,8 +21806,8 @@ abstract class ApiHelper { } - def migrateVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MigrateVmAction.class) Closure c) { - def a = new org.zstack.sdk.MigrateVmAction() + def getElaborationCategories(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetElaborationCategoriesAction.class) Closure c) { + def a = new org.zstack.sdk.GetElaborationCategoriesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21590,8 +21833,8 @@ abstract class ApiHelper { } - def mountVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MountVmInstanceRecoveryPointAction.class) Closure c) { - def a = new org.zstack.sdk.MountVmInstanceRecoveryPointAction() + def getElaborations(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetElaborationsAction.class) Closure c) { + def a = new org.zstack.sdk.GetElaborationsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21617,8 +21860,8 @@ abstract class ApiHelper { } - def pauseVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PauseVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.PauseVmInstanceAction() + def getEncryptedField(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetEncryptedFieldAction.class) Closure c) { + def a = new org.zstack.sdk.GetEncryptedFieldAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21644,8 +21887,8 @@ abstract class ApiHelper { } - def powerOffBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOffBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.PowerOffBareMetal2ChassisAction() + def getExternalServices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetExternalServicesAction.class) Closure c) { + def a = new org.zstack.sdk.GetExternalServicesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21671,8 +21914,8 @@ abstract class ApiHelper { } - def powerOffBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOffBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.PowerOffBaremetalChassisAction() + def getFactoryModeState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFactoryModeStateAction.class) Closure c) { + def a = new org.zstack.sdk.GetFactoryModeStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21698,8 +21941,8 @@ abstract class ApiHelper { } - def powerOffHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOffHostAction.class) Closure c) { - def a = new org.zstack.sdk.PowerOffHostAction() + def getFaultToleranceVms(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFaultToleranceVmsAction.class) Closure c) { + def a = new org.zstack.sdk.GetFaultToleranceVmsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21725,8 +21968,8 @@ abstract class ApiHelper { } - def powerOnBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOnBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.PowerOnBareMetal2ChassisAction() + def getFlowMeterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFlowMeterRouterIdAction.class) Closure c) { + def a = new org.zstack.sdk.GetFlowMeterRouterIdAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21752,8 +21995,8 @@ abstract class ApiHelper { } - def powerOnBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOnBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.PowerOnBaremetalChassisAction() + def getFreeIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFreeIpAction.class) Closure c) { + def a = new org.zstack.sdk.GetFreeIpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21779,8 +22022,8 @@ abstract class ApiHelper { } - def powerResetBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerResetBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.PowerResetBareMetal2ChassisAction() + def getFreeIpOfIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFreeIpOfIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.GetFreeIpOfIpRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21806,8 +22049,8 @@ abstract class ApiHelper { } - def powerResetBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerResetBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.PowerResetBaremetalChassisAction() + def getFreeIpOfL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetFreeIpOfL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetFreeIpOfL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21833,8 +22076,8 @@ abstract class ApiHelper { } - def previewResourceFromApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PreviewResourceFromAppAction.class) Closure c) { - def a = new org.zstack.sdk.PreviewResourceFromAppAction() + def getGlobalConfigOptions(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetGlobalConfigOptionsAction.class) Closure c) { + def a = new org.zstack.sdk.GetGlobalConfigOptionsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21860,8 +22103,8 @@ abstract class ApiHelper { } - def previewResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PreviewResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.PreviewResourceStackAction() + def getGpuDeviceSpecCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetGpuDeviceSpecCandidatesAction.class) Closure c) { + def a = new org.zstack.sdk.GetGpuDeviceSpecCandidatesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21887,8 +22130,8 @@ abstract class ApiHelper { } - def primaryStorageMigrateVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrimaryStorageMigrateVmAction.class) Closure c) { - def a = new org.zstack.sdk.PrimaryStorageMigrateVmAction() + def getGuestOsMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetGuestOsMetadataAction.class) Closure c) { + def a = new org.zstack.sdk.GetGuestOsMetadataAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21914,8 +22157,8 @@ abstract class ApiHelper { } - def primaryStorageMigrateVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrimaryStorageMigrateVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.PrimaryStorageMigrateVolumeAction() + def getHostAllocatorStrategies(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostAllocatorStrategiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostAllocatorStrategiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21941,8 +22184,8 @@ abstract class ApiHelper { } - def prometheusQueryLabelValues(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryLabelValuesAction.class) Closure c) { - def a = new org.zstack.sdk.PrometheusQueryLabelValuesAction() + def getHostCandidatesForVmMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostCandidatesForVmMigrationAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostCandidatesForVmMigrationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21968,8 +22211,8 @@ abstract class ApiHelper { } - def prometheusQueryMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryMetadataAction.class) Closure c) { - def a = new org.zstack.sdk.PrometheusQueryMetadataAction() + def getHostIommuState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostIommuStateAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostIommuStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -21995,8 +22238,8 @@ abstract class ApiHelper { } - def prometheusQueryPassThrough(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryPassThroughAction.class) Closure c) { - def a = new org.zstack.sdk.PrometheusQueryPassThroughAction() + def getHostIommuStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostIommuStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostIommuStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -22022,8 +22265,8 @@ abstract class ApiHelper { } - def prometheusQueryVmMonitoringData(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryVmMonitoringDataAction.class) Closure c) { - def a = new org.zstack.sdk.PrometheusQueryVmMonitoringDataAction() + def getHostMultipathTopology(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostMultipathTopologyAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostMultipathTopologyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -22049,8 +22292,8 @@ abstract class ApiHelper { } - def protectVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ProtectVmInstanceRecoveryPointAction.class) Closure c) { - def a = new org.zstack.sdk.ProtectVmInstanceRecoveryPointAction() + def getHostNUMATopology(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostNUMATopologyAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostNUMATopologyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -22076,8 +22319,8 @@ abstract class ApiHelper { } - def provisionVirtualRouterConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ProvisionVirtualRouterConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ProvisionVirtualRouterConfigAction() + def getHostNetworkFacts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostNetworkFactsAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostNetworkFactsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -22103,8 +22346,8 @@ abstract class ApiHelper { } - def publishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PublishAppAction.class) Closure c) { - def a = new org.zstack.sdk.PublishAppAction() + def getHostNetworkInterfaceLldp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostNetworkInterfaceLldpAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostNetworkInterfaceLldpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -22130,102 +22373,13 @@ abstract class ApiHelper { } - def queryAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccessControlListAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccessControlListAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - a.conditions = a.conditions.collect { it.toString() } - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def queryAccessControlRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccessControlRuleAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccessControlRuleAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - a.conditions = a.conditions.collect { it.toString() } - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def queryAccessKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccessKeyAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccessKeyAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - a.conditions = a.conditions.collect { it.toString() } - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def queryAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccountAction() + def getHostPhysicalMemoryFacts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostPhysicalMemoryFactsAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostPhysicalMemoryFactsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22246,15 +22400,13 @@ abstract class ApiHelper { } - def queryAccountBilling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountBillingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccountBillingAction() + def getHostPowerStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostPowerStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostPowerStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22275,15 +22427,13 @@ abstract class ApiHelper { } - def queryAccountPriceTableRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountPriceTableRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccountPriceTableRefAction() + def getHostResourceAllocation(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostResourceAllocationAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostResourceAllocationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22304,15 +22454,13 @@ abstract class ApiHelper { } - def queryAccountResourceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountResourceRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAccountResourceRefAction() + def getHostTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostTaskAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22333,15 +22481,13 @@ abstract class ApiHelper { } - def queryAddressPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAddressPoolAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAddressPoolAction() + def getHostWebSshUrl(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHostWebSshUrlAction.class) Closure c) { + def a = new org.zstack.sdk.GetHostWebSshUrlAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22362,15 +22508,13 @@ abstract class ApiHelper { } - def queryAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAffinityGroupAction() + def getHypervisorTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetHypervisorTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetHypervisorTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22391,15 +22535,13 @@ abstract class ApiHelper { } - def queryAlert(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAlertAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAlertAction() + def getIdentityZoneFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetIdentityZoneFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetIdentityZoneFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22420,15 +22562,13 @@ abstract class ApiHelper { } - def queryAliyunDiskFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunDiskFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunDiskFromLocalAction() + def getImageCandidatesForVmToChange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetImageCandidatesForVmToChangeAction.class) Closure c) { + def a = new org.zstack.sdk.GetImageCandidatesForVmToChangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22449,15 +22589,13 @@ abstract class ApiHelper { } - def queryAliyunEbsBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunEbsBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunEbsBackupStorageAction() + def getImageQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetImageQgaAction.class) Closure c) { + def a = new org.zstack.sdk.GetImageQgaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22478,15 +22616,13 @@ abstract class ApiHelper { } - def queryAliyunEbsPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunEbsPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunEbsPrimaryStorageAction() + def getImagesFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetImagesFromImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.GetImagesFromImageStoreBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22507,15 +22643,13 @@ abstract class ApiHelper { } - def queryAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunNasAccessGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunNasAccessGroupAction() + def getInterdependentL3NetworksBackupStorages(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetInterdependentL3NetworksBackupStoragesAction.class) Closure c) { + def a = new org.zstack.sdk.GetInterdependentL3NetworksBackupStoragesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22536,15 +22670,13 @@ abstract class ApiHelper { } - def queryAliyunPanguPartition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunPanguPartitionAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunPanguPartitionAction() + def getInterdependentL3NetworksImages(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetInterdependentL3NetworksImagesAction.class) Closure c) { + def a = new org.zstack.sdk.GetInterdependentL3NetworksImagesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22565,15 +22697,13 @@ abstract class ApiHelper { } - def queryAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunProxyVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunProxyVSwitchAction() + def getInterfaceServiceTypeStatistic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetInterfaceServiceTypeStatisticAction.class) Closure c) { + def a = new org.zstack.sdk.GetInterfaceServiceTypeStatisticAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22594,15 +22724,13 @@ abstract class ApiHelper { } - def queryAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunProxyVpcAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunProxyVpcAction() + def getInvocationRecords(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetInvocationRecordsAction.class) Closure c) { + def a = new org.zstack.sdk.GetInvocationRecordsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22623,15 +22751,13 @@ abstract class ApiHelper { } - def queryAliyunRouteEntryFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunRouteEntryFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunRouteEntryFromLocalAction() + def getIpAddressCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetIpAddressCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetIpAddressCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22652,15 +22778,13 @@ abstract class ApiHelper { } - def queryAliyunRouterInterfaceFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunRouterInterfaceFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunRouterInterfaceFromLocalAction() + def getL2NetworkTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL2NetworkTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetL2NetworkTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22681,15 +22805,13 @@ abstract class ApiHelper { } - def queryAliyunSnapshotFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunSnapshotFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunSnapshotFromLocalAction() + def getL3NetworkDhcpIpAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkDhcpIpAddressAction.class) Closure c) { + def a = new org.zstack.sdk.GetL3NetworkDhcpIpAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22710,15 +22832,13 @@ abstract class ApiHelper { } - def queryAliyunVirtualRouterFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunVirtualRouterFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAliyunVirtualRouterFromLocalAction() + def getL3NetworkIpStatistic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkIpStatisticAction.class) Closure c) { + def a = new org.zstack.sdk.GetL3NetworkIpStatisticAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22739,15 +22859,13 @@ abstract class ApiHelper { } - def queryAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAppBuildSystemAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAppBuildSystemAction() + def getL3NetworkMtu(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkMtuAction.class) Closure c) { + def a = new org.zstack.sdk.GetL3NetworkMtuAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22768,15 +22886,13 @@ abstract class ApiHelper { } - def queryApplianceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryApplianceVmAction.class) Closure c) { - def a = new org.zstack.sdk.QueryApplianceVmAction() + def getL3NetworkRouterInterfaceIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkRouterInterfaceIpAction.class) Closure c) { + def a = new org.zstack.sdk.GetL3NetworkRouterInterfaceIpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22797,15 +22913,13 @@ abstract class ApiHelper { } - def queryAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAutoScalingGroupAction() + def getL3NetworkTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetL3NetworkTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetL3NetworkTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22826,15 +22940,13 @@ abstract class ApiHelper { } - def queryAutoScalingGroupActivity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingGroupActivityAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAutoScalingGroupActivityAction() + def getLatestGuestToolsForVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLatestGuestToolsForVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetLatestGuestToolsForVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22855,15 +22967,13 @@ abstract class ApiHelper { } - def queryAutoScalingGroupInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingGroupInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAutoScalingGroupInstanceAction() + def getLdapEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLdapEntryAction.class) Closure c) { + def a = new org.zstack.sdk.GetLdapEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22884,15 +22994,13 @@ abstract class ApiHelper { } - def queryAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAutoScalingRuleAction() + def getLdapServerAvailableAttributes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLdapServerAvailableAttributesAction.class) Closure c) { + def a = new org.zstack.sdk.GetLdapServerAvailableAttributesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22913,44 +23021,13 @@ abstract class ApiHelper { } - def queryAutoScalingRuleTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingRuleTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAutoScalingRuleTriggerAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - a.conditions = a.conditions.collect { it.toString() } - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } + def getLicenseAddOns(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseAddOnsAction.class) Closure c) { + def a = new org.zstack.sdk.GetLicenseAddOnsAction() - return out - } else { - return errorOut(a.call()) - } - } - - - def queryAutoScalingVmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingVmTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryAutoScalingVmTemplateAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -22971,15 +23048,13 @@ abstract class ApiHelper { } - def queryBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBackupStorageAction() + def getLicenseCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseCapabilitiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetLicenseCapabilitiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23000,15 +23075,13 @@ abstract class ApiHelper { } - def queryBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBareMetal2ChassisAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getLicenseInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseInfoAction.class) Closure c) { + def a = new org.zstack.sdk.GetLicenseInfoAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23029,15 +23102,13 @@ abstract class ApiHelper { } - def queryBareMetal2ChassisOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ChassisOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBareMetal2ChassisOfferingAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getLicenseRecords(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseRecordsAction.class) Closure c) { + def a = new org.zstack.sdk.GetLicenseRecordsAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23058,15 +23129,13 @@ abstract class ApiHelper { } - def queryBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2GatewayAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBareMetal2GatewayAction() + def getLicenseUKeyStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLicenseUKeyStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetLicenseUKeyStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23087,15 +23156,13 @@ abstract class ApiHelper { } - def queryBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2InstanceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBareMetal2InstanceAction() + def getLoadBalancerListenerACLEntries(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLoadBalancerListenerACLEntriesAction.class) Closure c) { + def a = new org.zstack.sdk.GetLoadBalancerListenerACLEntriesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23116,15 +23183,13 @@ abstract class ApiHelper { } - def queryBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ProvisionNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBareMetal2ProvisionNetworkAction() + def getLoadBalancerOwner(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLoadBalancerOwnerAction.class) Closure c) { + def a = new org.zstack.sdk.GetLoadBalancerOwnerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23145,15 +23210,13 @@ abstract class ApiHelper { } - def queryBaremetalBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalBondingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBaremetalBondingAction() + def getLocalRaidPhysicalDriveSmart(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLocalRaidPhysicalDriveSmartAction.class) Closure c) { + def a = new org.zstack.sdk.GetLocalRaidPhysicalDriveSmartAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23174,15 +23237,13 @@ abstract class ApiHelper { } - def queryBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBaremetalChassisAction() + def getLocalStorageHostDiskCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLocalStorageHostDiskCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetLocalStorageHostDiskCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23203,15 +23264,13 @@ abstract class ApiHelper { } - def queryBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBaremetalInstanceAction() + def getLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLogConfigurationAction.class) Closure c) { + def a = new org.zstack.sdk.GetLogConfigurationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23232,15 +23291,13 @@ abstract class ApiHelper { } - def queryBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBaremetalPxeServerAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getLoginCaptcha(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLoginCaptchaAction.class) Closure c) { + def a = new org.zstack.sdk.GetLoginCaptchaAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23261,15 +23318,13 @@ abstract class ApiHelper { } - def queryBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBuildAppAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBuildAppAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getLoginProcedures(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetLoginProceduresAction.class) Closure c) { + def a = new org.zstack.sdk.GetLoginProceduresAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23290,15 +23345,13 @@ abstract class ApiHelper { } - def queryBuildAppExportHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBuildAppExportHistoryAction.class) Closure c) { - def a = new org.zstack.sdk.QueryBuildAppExportHistoryAction() + def getMaaSUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMaaSUsageAction.class) Closure c) { + def a = new org.zstack.sdk.GetMaaSUsageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23319,15 +23372,13 @@ abstract class ApiHelper { } - def queryCCSCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCCSCertificateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCCSCertificateAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getManagementNodeArch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetManagementNodeArchAction.class) Closure c) { + def a = new org.zstack.sdk.GetManagementNodeArchAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23348,15 +23399,13 @@ abstract class ApiHelper { } - def queryCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCdpPolicyAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCdpPolicyAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getManagementNodeOS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetManagementNodeOSAction.class) Closure c) { + def a = new org.zstack.sdk.GetManagementNodeOSAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23377,15 +23426,13 @@ abstract class ApiHelper { } - def queryCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCdpTaskAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCdpTaskAction() + def getMdevDeviceCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMdevDeviceCandidatesAction.class) Closure c) { + def a = new org.zstack.sdk.GetMdevDeviceCandidatesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23406,15 +23453,13 @@ abstract class ApiHelper { } - def queryCephBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCephBackupStorageAction() + def getMdevDeviceSpecCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMdevDeviceSpecCandidatesAction.class) Closure c) { + def a = new org.zstack.sdk.GetMdevDeviceSpecCandidatesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23435,15 +23480,13 @@ abstract class ApiHelper { } - def queryCephPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCephPrimaryStorageAction() + def getMemorySnapshotGroupReference(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMemorySnapshotGroupReferenceAction.class) Closure c) { + def a = new org.zstack.sdk.GetMemorySnapshotGroupReferenceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23464,15 +23507,13 @@ abstract class ApiHelper { } - def queryCephPrimaryStoragePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephPrimaryStoragePoolAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCephPrimaryStoragePoolAction() + def getModelCenterServices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetModelCenterServicesAction.class) Closure c) { + def a = new org.zstack.sdk.GetModelCenterServicesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23493,15 +23534,13 @@ abstract class ApiHelper { } - def queryCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCertificateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryCertificateAction() + def getMonitorItem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetMonitorItemAction.class) Closure c) { + def a = new org.zstack.sdk.GetMonitorItemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23522,15 +23561,13 @@ abstract class ApiHelper { } - def queryCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryClusterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryClusterAction() + def getNetworkServiceTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetNetworkServiceTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetNetworkServiceTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23551,15 +23588,13 @@ abstract class ApiHelper { } - def queryClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryClusterDRSAction.class) Closure c) { - def a = new org.zstack.sdk.QueryClusterDRSAction() + def getNicQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetNicQosAction.class) Closure c) { + def a = new org.zstack.sdk.GetNicQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23580,15 +23615,13 @@ abstract class ApiHelper { } - def queryConnectionAccessPointFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryConnectionAccessPointFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryConnectionAccessPointFromLocalAction() + def getNoTriggerSchedulerJobs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetNoTriggerSchedulerJobsAction.class) Closure c) { + def a = new org.zstack.sdk.GetNoTriggerSchedulerJobsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23609,15 +23642,13 @@ abstract class ApiHelper { } - def queryConnectionBetweenL3NetworkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryConnectionBetweenL3NetworkAndAliyunVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.QueryConnectionBetweenL3NetworkAndAliyunVSwitchAction() + def getOAuth2Token(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOAuth2TokenAction.class) Closure c) { + def a = new org.zstack.sdk.GetOAuth2TokenAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23638,15 +23669,13 @@ abstract class ApiHelper { } - def queryConsoleProxyAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryConsoleProxyAgentAction.class) Closure c) { - def a = new org.zstack.sdk.QueryConsoleProxyAgentAction() + def getObservabilityServerServiceData(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetObservabilityServerServiceDataAction.class) Closure c) { + def a = new org.zstack.sdk.GetObservabilityServerServiceDataAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23667,15 +23696,13 @@ abstract class ApiHelper { } - def queryDRSAdvice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDRSAdviceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryDRSAdviceAction() + def getOssBackupBucketFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOssBackupBucketFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetOssBackupBucketFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23696,15 +23723,13 @@ abstract class ApiHelper { } - def queryDRSVmMigrationActivity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDRSVmMigrationActivityAction.class) Closure c) { - def a = new org.zstack.sdk.QueryDRSVmMigrationActivityAction() + def getOssBucketFileFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOssBucketFileFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetOssBucketFileFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23725,15 +23750,13 @@ abstract class ApiHelper { } - def queryDataCenterFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDataCenterFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryDataCenterFromLocalAction() + def getOssBucketNameFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetOssBucketNameFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetOssBucketNameFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23754,15 +23777,13 @@ abstract class ApiHelper { } - def queryDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDiskOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryDiskOfferingAction() + def getPciDeviceCandidatesForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPciDeviceCandidatesForAttachingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetPciDeviceCandidatesForAttachingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23783,15 +23804,13 @@ abstract class ApiHelper { } - def queryEcsImageFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsImageFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEcsImageFromLocalAction() + def getPciDeviceCandidatesForNewCreateVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPciDeviceCandidatesForNewCreateVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetPciDeviceCandidatesForNewCreateVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23812,15 +23831,13 @@ abstract class ApiHelper { } - def queryEcsInstanceFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsInstanceFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEcsInstanceFromLocalAction() + def getPciDeviceSpecCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPciDeviceSpecCandidatesAction.class) Closure c) { + def a = new org.zstack.sdk.GetPciDeviceSpecCandidatesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23841,15 +23858,13 @@ abstract class ApiHelper { } - def queryEcsSecurityGroupFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsSecurityGroupFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEcsSecurityGroupFromLocalAction() + def getPlatformTimeZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPlatformTimeZoneAction.class) Closure c) { + def a = new org.zstack.sdk.GetPlatformTimeZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23870,15 +23885,13 @@ abstract class ApiHelper { } - def queryEcsSecurityGroupRuleFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsSecurityGroupRuleFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEcsSecurityGroupRuleFromLocalAction() + def getPolicyRouteRuleSetFromVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPolicyRouteRuleSetFromVirtualRouterAction.class) Closure c) { + def a = new org.zstack.sdk.GetPolicyRouteRuleSetFromVirtualRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23899,15 +23912,13 @@ abstract class ApiHelper { } - def queryEcsVSwitchFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsVSwitchFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEcsVSwitchFromLocalAction() + def getPortForwardingAttachableVmNics(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPortForwardingAttachableVmNicsAction.class) Closure c) { + def a = new org.zstack.sdk.GetPortForwardingAttachableVmNicsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23928,15 +23939,13 @@ abstract class ApiHelper { } - def queryEcsVpcFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsVpcFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEcsVpcFromLocalAction() + def getPrimaryStorageAllocatorStrategies(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageAllocatorStrategiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageAllocatorStrategiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23957,15 +23966,13 @@ abstract class ApiHelper { } - def queryEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEipAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEipAction() + def getPrimaryStorageCandidatesForVmMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageCandidatesForVmMigrationAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageCandidatesForVmMigrationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -23986,15 +23993,13 @@ abstract class ApiHelper { } - def queryEmailMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEmailMediaAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEmailMediaAction() + def getPrimaryStorageCandidatesForVolumeMigration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageCandidatesForVolumeMigrationAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageCandidatesForVolumeMigrationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24015,15 +24020,13 @@ abstract class ApiHelper { } - def queryEmailTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEmailTriggerActionAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEmailTriggerActionAction() + def getPrimaryStorageCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24044,15 +24047,13 @@ abstract class ApiHelper { } - def queryEventFromResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEventFromResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEventFromResourceStackAction() + def getPrimaryStorageLicenseInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageLicenseInfoAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageLicenseInfoAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24073,15 +24074,13 @@ abstract class ApiHelper { } - def queryEventLog(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEventLogAction.class) Closure c) { - def a = new org.zstack.sdk.QueryEventLogAction() + def getPrimaryStorageTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24102,15 +24101,13 @@ abstract class ApiHelper { } - def queryExternalBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryExternalBackupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryExternalBackupAction() + def getPrimaryStorageUsageReport(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetPrimaryStorageUsageReportAction.class) Closure c) { + def a = new org.zstack.sdk.GetPrimaryStorageUsageReportAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24131,15 +24128,13 @@ abstract class ApiHelper { } - def queryFaultToleranceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFaultToleranceVmAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFaultToleranceVmAction() + def getResourceAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceAccountAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceAccountAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24160,15 +24155,13 @@ abstract class ApiHelper { } - def queryFiberChannelLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFiberChannelLunAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFiberChannelLunAction() + def getResourceBindableConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceBindableConfigAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceBindableConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24189,15 +24182,13 @@ abstract class ApiHelper { } - def queryFiberChannelStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFiberChannelStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFiberChannelStorageAction() + def getResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceConfigAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24218,15 +24209,13 @@ abstract class ApiHelper { } - def queryFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallIpSetTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFirewallIpSetTemplateAction() + def getResourceConfigs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceConfigsAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceConfigsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24247,15 +24236,13 @@ abstract class ApiHelper { } - def queryFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFirewallRuleAction() + def getResourceFromPublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceFromPublishAppAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceFromPublishAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24276,15 +24263,13 @@ abstract class ApiHelper { } - def queryFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFirewallRuleSetAction() + def getResourceFromResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceFromResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceFromResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24305,15 +24290,13 @@ abstract class ApiHelper { } - def queryFirewallRuleSetL3Ref(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleSetL3RefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFirewallRuleSetL3RefAction() + def getResourceNames(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceNamesAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceNamesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24334,15 +24317,13 @@ abstract class ApiHelper { } - def queryFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFirewallRuleTemplateAction() + def getResourceStackFromResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceStackFromResourceAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceStackFromResourceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24363,15 +24344,13 @@ abstract class ApiHelper { } - def queryFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFlowCollectorAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFlowCollectorAction() + def getResourceStackVmStatus(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetResourceStackVmStatusAction.class) Closure c) { + def a = new org.zstack.sdk.GetResourceStackVmStatusAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24392,15 +24371,13 @@ abstract class ApiHelper { } - def queryFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFlowMeterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryFlowMeterAction() + def getRouteTableVpcVRouterCandidate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetRouteTableVpcVRouterCandidateAction.class) Closure c) { + def a = new org.zstack.sdk.GetRouteTableVpcVRouterCandidateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24421,15 +24398,13 @@ abstract class ApiHelper { } - def queryGCJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGCJobAction.class) Closure c) { - def a = new org.zstack.sdk.QueryGCJobAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getSSOClient(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSSOClientAction.class) Closure c) { + def a = new org.zstack.sdk.GetSSOClientAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24450,15 +24425,13 @@ abstract class ApiHelper { } - def queryGlobalConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGlobalConfigAction.class) Closure c) { - def a = new org.zstack.sdk.QueryGlobalConfigAction() + def getSchedulerExecutionReport(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSchedulerExecutionReportAction.class) Closure c) { + def a = new org.zstack.sdk.GetSchedulerExecutionReportAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24479,15 +24452,13 @@ abstract class ApiHelper { } - def queryGlobalConfigTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGlobalConfigTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryGlobalConfigTemplateAction() + def getScsiLunCandidatesForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetScsiLunCandidatesForAttachingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetScsiLunCandidatesForAttachingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24508,15 +24479,13 @@ abstract class ApiHelper { } - def queryHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostAction.class) Closure c) { - def a = new org.zstack.sdk.QueryHostAction() + def getSharedBlockCandidate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSharedBlockCandidateAction.class) Closure c) { + def a = new org.zstack.sdk.GetSharedBlockCandidateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24537,15 +24506,13 @@ abstract class ApiHelper { } - def queryHostNetworkBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostNetworkBondingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryHostNetworkBondingAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getSignatureServerEncryptPublicKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSignatureServerEncryptPublicKeyAction.class) Closure c) { + def a = new org.zstack.sdk.GetSignatureServerEncryptPublicKeyAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24566,15 +24533,13 @@ abstract class ApiHelper { } - def queryHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostNetworkInterfaceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryHostNetworkInterfaceAction() + def getSpiceCertificates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSpiceCertificatesAction.class) Closure c) { + def a = new org.zstack.sdk.GetSpiceCertificatesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24595,15 +24560,13 @@ abstract class ApiHelper { } - def queryHostPhysicalMemory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostPhysicalMemoryAction.class) Closure c) { - def a = new org.zstack.sdk.QueryHostPhysicalMemoryAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getSupportAPIs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSupportAPIsAction.class) Closure c) { + def a = new org.zstack.sdk.GetSupportAPIsAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24624,15 +24587,13 @@ abstract class ApiHelper { } - def queryHybridEipFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHybridEipFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryHybridEipFromLocalAction() + def getSupportedCloudFormationResources(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSupportedCloudFormationResourcesAction.class) Closure c) { + def a = new org.zstack.sdk.GetSupportedCloudFormationResourcesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24653,15 +24614,13 @@ abstract class ApiHelper { } - def queryHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHybridKeySecretAction.class) Closure c) { - def a = new org.zstack.sdk.QueryHybridKeySecretAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getSupportedIdentityModels(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetSupportedIdentityModelsAction.class) Closure c) { + def a = new org.zstack.sdk.GetSupportedIdentityModelsAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24682,15 +24641,13 @@ abstract class ApiHelper { } - def queryIAM2LdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIAM2LdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIAM2LdapBindingAction() + def getTaskProgress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTaskProgressAction.class) Closure c) { + def a = new org.zstack.sdk.GetTaskProgressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24711,15 +24668,13 @@ abstract class ApiHelper { } - def queryIPSecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIPSecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIPSecConnectionAction() + def getTrashOnBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTrashOnBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.GetTrashOnBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24740,15 +24695,13 @@ abstract class ApiHelper { } - def queryIdentityZoneFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIdentityZoneFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIdentityZoneFromLocalAction() + def getTrashOnPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTrashOnPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.GetTrashOnPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24769,15 +24722,13 @@ abstract class ApiHelper { } - def queryImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryImageAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getTwoFactorAuthenticationSecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTwoFactorAuthenticationSecretAction.class) Closure c) { + def a = new org.zstack.sdk.GetTwoFactorAuthenticationSecretAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24798,15 +24749,13 @@ abstract class ApiHelper { } - def queryImageCache(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageCacheAction.class) Closure c) { - def a = new org.zstack.sdk.QueryImageCacheAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getTwoFactorAuthenticationState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetTwoFactorAuthenticationStateAction.class) Closure c) { + def a = new org.zstack.sdk.GetTwoFactorAuthenticationStateAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24827,15 +24776,13 @@ abstract class ApiHelper { } - def queryImageReplicationGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageReplicationGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryImageReplicationGroupAction() + def getUploadImageJobDetails(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetUploadImageJobDetailsAction.class) Closure c) { + def a = new org.zstack.sdk.GetUploadImageJobDetailsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24856,15 +24803,13 @@ abstract class ApiHelper { } - def queryImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryImageStoreBackupStorageAction() + def getUsbDeviceCandidatesForAttachingVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetUsbDeviceCandidatesForAttachingVmAction.class) Closure c) { + def a = new org.zstack.sdk.GetUsbDeviceCandidatesForAttachingVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24885,15 +24830,13 @@ abstract class ApiHelper { } - def queryInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryInstanceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryInstanceOfferingAction() + def getVRouterFlowCounter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterFlowCounterAction.class) Closure c) { + def a = new org.zstack.sdk.GetVRouterFlowCounterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24914,15 +24857,13 @@ abstract class ApiHelper { } - def queryIpAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIpAddressAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIpAddressAction() + def getVRouterOspfNeighbor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterOspfNeighborAction.class) Closure c) { + def a = new org.zstack.sdk.GetVRouterOspfNeighborAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24943,15 +24884,13 @@ abstract class ApiHelper { } - def queryIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIpRangeAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIpRangeAction() + def getVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.GetVRouterRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -24972,15 +24911,13 @@ abstract class ApiHelper { } - def queryIscsiLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIscsiLunAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIscsiLunAction() + def getVRouterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVRouterRouterIdAction.class) Closure c) { + def a = new org.zstack.sdk.GetVRouterRouterIdAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25001,15 +24938,13 @@ abstract class ApiHelper { } - def queryIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIscsiServerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryIscsiServerAction() + def getVSwitchTypes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVSwitchTypesAction.class) Closure c) { + def a = new org.zstack.sdk.GetVSwitchTypesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25030,15 +24965,13 @@ abstract class ApiHelper { } - def queryL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryL2NetworkAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def getVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVersionAction.class) Closure c) { + def a = new org.zstack.sdk.GetVersionAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25059,15 +24992,13 @@ abstract class ApiHelper { } - def queryL2VlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VlanNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryL2VlanNetworkAction() + def getVfPciDeviceAvailableInL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVfPciDeviceAvailableInL2NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetVfPciDeviceAvailableInL2NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25088,15 +25019,13 @@ abstract class ApiHelper { } - def queryL2VxlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VxlanNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryL2VxlanNetworkAction() + def getVipAvailablePort(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVipAvailablePortAction.class) Closure c) { + def a = new org.zstack.sdk.GetVipAvailablePortAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25117,15 +25046,13 @@ abstract class ApiHelper { } - def queryL2VxlanNetworkPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VxlanNetworkPoolAction.class) Closure c) { - def a = new org.zstack.sdk.QueryL2VxlanNetworkPoolAction() + def getVipQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVipQosAction.class) Closure c) { + def a = new org.zstack.sdk.GetVipQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25146,15 +25073,13 @@ abstract class ApiHelper { } - def queryL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryL3NetworkAction() + def getVipUsedPorts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVipUsedPortsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVipUsedPortsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25175,15 +25100,13 @@ abstract class ApiHelper { } - def queryLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLdapBindingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLdapBindingAction() + def getVirtualRouterSoftwareVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVirtualRouterSoftwareVersionAction.class) Closure c) { + def a = new org.zstack.sdk.GetVirtualRouterSoftwareVersionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25204,15 +25127,13 @@ abstract class ApiHelper { } - def queryLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLdapServerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLdapServerAction() + def getVirtualizerInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVirtualizerInfoAction.class) Closure c) { + def a = new org.zstack.sdk.GetVirtualizerInfoAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25233,15 +25154,13 @@ abstract class ApiHelper { } - def queryLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLoadBalancerAction() + def getVmAttachableDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmAttachableDataVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmAttachableDataVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25262,15 +25181,13 @@ abstract class ApiHelper { } - def queryLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLoadBalancerListenerAction() + def getVmAttachableL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmAttachableL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmAttachableL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25291,15 +25208,13 @@ abstract class ApiHelper { } - def queryLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLoadBalancerServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLoadBalancerServerGroupAction() + def getVmBootOrder(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmBootOrderAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmBootOrderAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25320,15 +25235,13 @@ abstract class ApiHelper { } - def queryLocalRaidController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLocalRaidControllerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLocalRaidControllerAction() + def getVmCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmCapabilitiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmCapabilitiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25349,15 +25262,13 @@ abstract class ApiHelper { } - def queryLocalRaidPhysicalDrive(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLocalRaidPhysicalDriveAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLocalRaidPhysicalDriveAction() + def getVmConsoleAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmConsoleAddressAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmConsoleAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25378,15 +25289,13 @@ abstract class ApiHelper { } - def queryLocalStorageResourceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLocalStorageResourceRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLocalStorageResourceRefAction() + def getVmConsolePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmConsolePasswordAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmConsolePasswordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25407,15 +25316,13 @@ abstract class ApiHelper { } - def queryLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.QueryLongJobAction() + def getVmDeviceAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmDeviceAddressAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmDeviceAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25436,15 +25343,13 @@ abstract class ApiHelper { } - def queryManagementNode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryManagementNodeAction.class) Closure c) { - def a = new org.zstack.sdk.QueryManagementNodeAction() + def getVmEmulatorPinning(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmEmulatorPinningAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmEmulatorPinningAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25465,15 +25370,13 @@ abstract class ApiHelper { } - def queryMdevDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMdevDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMdevDeviceAction() + def getVmGuestToolsInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmGuestToolsInfoAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmGuestToolsInfoAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25494,15 +25397,13 @@ abstract class ApiHelper { } - def queryMdevDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMdevDeviceSpecAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMdevDeviceSpecAction() + def getVmHostname(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmHostnameAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmHostnameAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25523,15 +25424,13 @@ abstract class ApiHelper { } - def queryMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMediaAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMediaAction() + def getVmInstanceFirstBootDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceFirstBootDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmInstanceFirstBootDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25552,15 +25451,13 @@ abstract class ApiHelper { } - def queryMiniStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMiniStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMiniStorageAction() + def getVmInstanceHaLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceHaLevelAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmInstanceHaLevelAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25581,15 +25478,13 @@ abstract class ApiHelper { } - def queryMiniStorageHostRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMiniStorageHostRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMiniStorageHostRefAction() + def getVmInstanceProtectedRecoveryPoints(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceProtectedRecoveryPointsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmInstanceProtectedRecoveryPointsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25610,15 +25505,13 @@ abstract class ApiHelper { } - def queryMiniStorageResourceReplication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMiniStorageResourceReplicationAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMiniStorageResourceReplicationAction() + def getVmInstanceRecoveryPoints(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmInstanceRecoveryPointsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmInstanceRecoveryPointsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25639,15 +25532,13 @@ abstract class ApiHelper { } - def queryMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMonitorTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMonitorTriggerAction() + def getVmMigrationCandidateHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmMigrationCandidateHostsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmMigrationCandidateHostsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25668,15 +25559,13 @@ abstract class ApiHelper { } - def queryMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMonitorTriggerActionAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMonitorTriggerActionAction() + def getVmMonitorNumber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmMonitorNumberAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmMonitorNumberAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25697,15 +25586,13 @@ abstract class ApiHelper { } - def queryMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMulticastRouterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryMulticastRouterAction() + def getVmNicAttachableEips(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmNicAttachableEipsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmNicAttachableEipsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25726,15 +25613,13 @@ abstract class ApiHelper { } - def queryNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNasFileSystemAction.class) Closure c) { - def a = new org.zstack.sdk.QueryNasFileSystemAction() + def getVmNicAttachedNetworkService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmNicAttachedNetworkServiceAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmNicAttachedNetworkServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25755,15 +25640,13 @@ abstract class ApiHelper { } - def queryNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNasMountTargetAction.class) Closure c) { - def a = new org.zstack.sdk.QueryNasMountTargetAction() + def getVmNuma(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmNumaAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmNumaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25784,15 +25667,13 @@ abstract class ApiHelper { } - def queryNetworkServiceL3NetworkRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNetworkServiceL3NetworkRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryNetworkServiceL3NetworkRefAction() + def getVmQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmQgaAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmQgaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25813,15 +25694,13 @@ abstract class ApiHelper { } - def queryNetworkServiceProvider(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNetworkServiceProviderAction.class) Closure c) { - def a = new org.zstack.sdk.QueryNetworkServiceProviderAction() + def getVmRDP(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmRDPAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmRDPAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25842,15 +25721,13 @@ abstract class ApiHelper { } - def queryOssBucketFileName(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryOssBucketFileNameAction.class) Closure c) { - def a = new org.zstack.sdk.QueryOssBucketFileNameAction() + def getVmSchedulingRulesExecuteState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmSchedulingRulesExecuteStateAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmSchedulingRulesExecuteStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25871,15 +25748,13 @@ abstract class ApiHelper { } - def queryPciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPciDeviceAction() + def getVmSshKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmSshKeyAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmSshKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25900,15 +25775,13 @@ abstract class ApiHelper { } - def queryPciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDeviceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPciDeviceOfferingAction() + def getVmStartingCandidateClustersHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmStartingCandidateClustersHostsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmStartingCandidateClustersHostsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25929,15 +25802,13 @@ abstract class ApiHelper { } - def queryPciDevicePciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDevicePciDeviceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPciDevicePciDeviceOfferingAction() + def getVmTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmTaskAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25958,15 +25829,13 @@ abstract class ApiHelper { } - def queryPciDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDeviceSpecAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPciDeviceSpecAction() + def getVmUsbRedirect(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmUsbRedirectAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmUsbRedirectAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -25987,15 +25856,13 @@ abstract class ApiHelper { } - def queryPhysicalDriveSelfTestHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPhysicalDriveSelfTestHistoryAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPhysicalDriveSelfTestHistoryAction() + def getVmXml(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmXmlAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmXmlAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26016,15 +25883,13 @@ abstract class ApiHelper { } - def queryPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyAction() + def getVmXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmXmlHookScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26045,15 +25910,13 @@ abstract class ApiHelper { } - def queryPolicyRouteRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteRuleAction() + def getVmsCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmsCapabilitiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmsCapabilitiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26074,15 +25937,13 @@ abstract class ApiHelper { } - def queryPolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteRuleSetAction() + def getVmsSchedulingStateFromSchedulingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmsSchedulingStateFromSchedulingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmsSchedulingStateFromSchedulingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26103,15 +25964,13 @@ abstract class ApiHelper { } - def queryPolicyRouteRuleSetL3Ref(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleSetL3RefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteRuleSetL3RefAction() + def getVmvNUMATopology(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVmvNUMATopologyAction.class) Closure c) { + def a = new org.zstack.sdk.GetVmvNUMATopologyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26132,15 +25991,13 @@ abstract class ApiHelper { } - def queryPolicyRouteRuleSetVRouterRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleSetVRouterRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteRuleSetVRouterRefAction() + def getVolumeCapabilities(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeCapabilitiesAction.class) Closure c) { + def a = new org.zstack.sdk.GetVolumeCapabilitiesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26161,15 +26018,13 @@ abstract class ApiHelper { } - def queryPolicyRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteTableAction() + def getVolumeFormat(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeFormatAction.class) Closure c) { + def a = new org.zstack.sdk.GetVolumeFormatAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26190,15 +26045,13 @@ abstract class ApiHelper { } - def queryPolicyRouteTableRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteTableRouteEntryAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteTableRouteEntryAction() + def getVolumeIoThreadPin(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeIoThreadPinAction.class) Closure c) { + def a = new org.zstack.sdk.GetVolumeIoThreadPinAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26219,15 +26072,13 @@ abstract class ApiHelper { } - def queryPolicyRouteTableVRouterRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteTableVRouterRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPolicyRouteTableVRouterRefAction() + def getVolumeQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeQosAction.class) Closure c) { + def a = new org.zstack.sdk.GetVolumeQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26248,15 +26099,13 @@ abstract class ApiHelper { } - def queryPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortForwardingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPortForwardingRuleAction() + def getVolumeSnapshotSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVolumeSnapshotSizeAction.class) Closure c) { + def a = new org.zstack.sdk.GetVolumeSnapshotSizeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26277,15 +26126,13 @@ abstract class ApiHelper { } - def queryPortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortMirrorAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPortMirrorAction() + def getVpcAttachedEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedEipAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26306,15 +26153,13 @@ abstract class ApiHelper { } - def queryPortMirrorNetworkUsedIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortMirrorNetworkUsedIpAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPortMirrorNetworkUsedIpAction() + def getVpcAttachedIpsec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedIpsecAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedIpsecAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26335,15 +26180,13 @@ abstract class ApiHelper { } - def queryPortMirrorSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortMirrorSessionAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPortMirrorSessionAction() + def getVpcAttachedLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26364,15 +26207,13 @@ abstract class ApiHelper { } - def queryPreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPreconfigurationTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPreconfigurationTemplateAction() + def getVpcAttachedNetflow(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedNetflowAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedNetflowAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26393,15 +26234,13 @@ abstract class ApiHelper { } - def queryPriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPriceTableAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPriceTableAction() + def getVpcAttachedOspf(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedOspfAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedOspfAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26422,15 +26261,13 @@ abstract class ApiHelper { } - def queryPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPrimaryStorageAction() + def getVpcAttachedPortForwardingRules(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedPortForwardingRulesAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedPortForwardingRulesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26451,15 +26288,13 @@ abstract class ApiHelper { } - def queryPublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPublishAppAction.class) Closure c) { - def a = new org.zstack.sdk.QueryPublishAppAction() + def getVpcAttachedVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcAttachedVipAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcAttachedVipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26480,15 +26315,13 @@ abstract class ApiHelper { } - def queryQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryQuotaAction.class) Closure c) { - def a = new org.zstack.sdk.QueryQuotaAction() + def getVpcIPsecLog(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcIPsecLogAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcIPsecLogAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26509,15 +26342,13 @@ abstract class ApiHelper { } - def queryResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourceConfigAction.class) Closure c) { - def a = new org.zstack.sdk.QueryResourceConfigAction() + def getVpcMulticastRoute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcMulticastRouteAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcMulticastRouteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26538,15 +26369,13 @@ abstract class ApiHelper { } - def queryResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourcePriceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryResourcePriceAction() + def getVpcVRouterDistributedRoutingConnections(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVRouterDistributedRoutingConnectionsAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcVRouterDistributedRoutingConnectionsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26567,15 +26396,13 @@ abstract class ApiHelper { } - def queryResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.QueryResourceStackAction() + def getVpcVRouterDistributedRoutingEnabled(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVRouterDistributedRoutingEnabledAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcVRouterDistributedRoutingEnabledAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26596,15 +26423,13 @@ abstract class ApiHelper { } - def querySchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerJobAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySchedulerJobAction() + def getVpcVRouterNetworkServiceState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVRouterNetworkServiceStateAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcVRouterNetworkServiceStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26625,15 +26450,13 @@ abstract class ApiHelper { } - def querySchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerJobGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySchedulerJobGroupAction() + def getVpcVpnConfigurationFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetVpcVpnConfigurationFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.GetVpcVpnConfigurationFromRemoteAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26654,15 +26477,13 @@ abstract class ApiHelper { } - def querySchedulerJobHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerJobHistoryAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySchedulerJobHistoryAction() + def getZBoxBackupDetails(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetZBoxBackupDetailsAction.class) Closure c) { + def a = new org.zstack.sdk.GetZBoxBackupDetailsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26683,15 +26504,13 @@ abstract class ApiHelper { } - def querySchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySchedulerTriggerAction() + def getZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.GetZoneAction.class) Closure c) { + def a = new org.zstack.sdk.GetZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26712,15 +26531,13 @@ abstract class ApiHelper { } - def queryScsiLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryScsiLunAction.class) Closure c) { - def a = new org.zstack.sdk.QueryScsiLunAction() + def identifyHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IdentifyHostAction.class) Closure c) { + def a = new org.zstack.sdk.IdentifyHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26741,15 +26558,13 @@ abstract class ApiHelper { } - def querySdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySdnControllerAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySdnControllerAction() + def inspectBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.InspectBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.InspectBareMetal2ChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26770,15 +26585,13 @@ abstract class ApiHelper { } - def querySecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecretResourcePoolAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySecretResourcePoolAction() + def inspectBareMetal2ChassisByInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.InspectBareMetal2ChassisByInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.InspectBareMetal2ChassisByInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26799,15 +26612,13 @@ abstract class ApiHelper { } - def querySecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySecurityGroupAction() + def inspectBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.InspectBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.InspectBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26828,44 +26639,13 @@ abstract class ApiHelper { } - def querySecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecurityGroupRuleAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySecurityGroupRuleAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - a.conditions = a.conditions.collect { it.toString() } - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } + def isOpensourceVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IsOpensourceVersionAction.class) Closure c) { + def a = new org.zstack.sdk.IsOpensourceVersionAction() - return out - } else { - return errorOut(a.call()) - } - } - - - def querySecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecurityMachineAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySecurityMachineAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26886,44 +26666,13 @@ abstract class ApiHelper { } - def querySftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySftpBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySftpBackupStorageAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - - a.conditions = a.conditions.collect { it.toString() } - - - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } + def isReadyToGo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IsReadyToGoAction.class) Closure c) { + def a = new org.zstack.sdk.IsReadyToGoAction() - return out - } else { - return errorOut(a.call()) - } - } - - - def queryShareableVolumeVmInstanceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryShareableVolumeVmInstanceRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryShareableVolumeVmInstanceRefAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26944,15 +26693,13 @@ abstract class ApiHelper { } - def querySharedBlock(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedBlockAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySharedBlockAction() + def isVfNicAvailableInL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.IsVfNicAvailableInL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.IsVfNicAvailableInL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -26973,15 +26720,13 @@ abstract class ApiHelper { } - def querySharedBlockGroupPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageAction() + def kvmRunShell(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.KvmRunShellAction.class) Closure c) { + def a = new org.zstack.sdk.KvmRunShellAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27002,15 +26747,13 @@ abstract class ApiHelper { } - def querySharedBlockGroupPrimaryStorageHostRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageHostRefAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageHostRefAction() + def listVMsFromKVMHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ListVMsFromKVMHostAction.class) Closure c) { + def a = new org.zstack.sdk.ListVMsFromKVMHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27031,15 +26774,13 @@ abstract class ApiHelper { } - def querySharedResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedResourceAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySharedResourceAction() + def listVmSchedulingRulesFromExecuteState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ListVmSchedulingRulesFromExecuteStateAction.class) Closure c) { + def a = new org.zstack.sdk.ListVmSchedulingRulesFromExecuteStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27060,15 +26801,13 @@ abstract class ApiHelper { } - def querySlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySlbGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySlbGroupAction() + def listVmsFromSchedulingState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ListVmsFromSchedulingStateAction.class) Closure c) { + def a = new org.zstack.sdk.ListVmsFromSchedulingStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27089,15 +26828,13 @@ abstract class ApiHelper { } - def querySlbOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySlbOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySlbOfferingAction() + def localStorageGetVolumeMigratableHosts(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocalStorageGetVolumeMigratableHostsAction.class) Closure c) { + def a = new org.zstack.sdk.LocalStorageGetVolumeMigratableHostsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27118,15 +26855,13 @@ abstract class ApiHelper { } - def queryStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryStackTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.QueryStackTemplateAction() + def localStorageMigrateVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocalStorageMigrateVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.LocalStorageMigrateVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27147,15 +26882,13 @@ abstract class ApiHelper { } - def querySystemTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySystemTagAction.class) Closure c) { - def a = new org.zstack.sdk.QuerySystemTagAction() + def locateHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocateHostNetworkInterfaceAction.class) Closure c) { + def a = new org.zstack.sdk.LocateHostNetworkInterfaceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27176,15 +26909,13 @@ abstract class ApiHelper { } - def queryTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTagAction.class) Closure c) { - def a = new org.zstack.sdk.QueryTagAction() + def locateLocalRaidPhysicalDrive(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LocateLocalRaidPhysicalDriveAction.class) Closure c) { + def a = new org.zstack.sdk.LocateLocalRaidPhysicalDriveAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27205,15 +26936,13 @@ abstract class ApiHelper { } - def queryTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTemplateConfigAction.class) Closure c) { - def a = new org.zstack.sdk.QueryTemplateConfigAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def logIn(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInAction.class) Closure c) { + def a = new org.zstack.sdk.LogInAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27234,15 +26963,13 @@ abstract class ApiHelper { } - def queryTwoFactorAuthentication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTwoFactorAuthenticationAction.class) Closure c) { - def a = new org.zstack.sdk.QueryTwoFactorAuthenticationAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def logInByAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInByAccountAction.class) Closure c) { + def a = new org.zstack.sdk.LogInByAccountAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27263,15 +26990,13 @@ abstract class ApiHelper { } - def queryUsbDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUsbDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryUsbDeviceAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def logInByLdap(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInByLdapAction.class) Closure c) { + def a = new org.zstack.sdk.LogInByLdapAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27292,15 +27017,13 @@ abstract class ApiHelper { } - def queryUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserAction.class) Closure c) { - def a = new org.zstack.sdk.QueryUserAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def logInByUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogInByUserAction.class) Closure c) { + def a = new org.zstack.sdk.LogInByUserAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27321,15 +27044,13 @@ abstract class ApiHelper { } - def queryUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryUserGroupAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def logOut(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LogOutAction.class) Closure c) { + def a = new org.zstack.sdk.LogOutAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27350,15 +27071,13 @@ abstract class ApiHelper { } - def queryUserTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserTagAction.class) Closure c) { - def a = new org.zstack.sdk.QueryUserTagAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def loginByCas(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LoginByCasAction.class) Closure c) { + def a = new org.zstack.sdk.LoginByCasAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27379,15 +27098,13 @@ abstract class ApiHelper { } - def queryV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryV2VConversionHostAction.class) Closure c) { - def a = new org.zstack.sdk.QueryV2VConversionHostAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid + def loginIAM2VirtualIDWithLdap(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.LoginIAM2VirtualIDWithLdapAction.class) Closure c) { + def a = new org.zstack.sdk.LoginIAM2VirtualIDWithLdapAction() + c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27408,15 +27125,13 @@ abstract class ApiHelper { } - def queryVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVCenterAction() + def matchModelServiceTemplateWithModel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MatchModelServiceTemplateWithModelAction.class) Closure c) { + def a = new org.zstack.sdk.MatchModelServiceTemplateWithModelAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27437,15 +27152,13 @@ abstract class ApiHelper { } - def queryVCenterBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVCenterBackupStorageAction() + def mergeDataOnBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MergeDataOnBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.MergeDataOnBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27466,15 +27179,13 @@ abstract class ApiHelper { } - def queryVCenterCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterClusterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVCenterClusterAction() + def migrateVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MigrateVmAction.class) Closure c) { + def a = new org.zstack.sdk.MigrateVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27495,15 +27206,13 @@ abstract class ApiHelper { } - def queryVCenterDatacenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterDatacenterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVCenterDatacenterAction() + def mountVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MountVmInstanceRecoveryPointAction.class) Closure c) { + def a = new org.zstack.sdk.MountVmInstanceRecoveryPointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27524,15 +27233,13 @@ abstract class ApiHelper { } - def queryVCenterPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVCenterPrimaryStorageAction() + def moveDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MoveDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.MoveDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27553,15 +27260,13 @@ abstract class ApiHelper { } - def queryVCenterResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterResourcePoolAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVCenterResourcePoolAction() + def moveResourcesToDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.MoveResourcesToDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.MoveResourcesToDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27582,15 +27287,13 @@ abstract class ApiHelper { } - def queryVRouterFlowMeterNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterFlowMeterNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVRouterFlowMeterNetworkAction() + def parseOvf(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ParseOvfAction.class) Closure c) { + def a = new org.zstack.sdk.ParseOvfAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27611,15 +27314,13 @@ abstract class ApiHelper { } - def queryVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterOspfAreaAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVRouterOspfAreaAction() + def pauseVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PauseVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.PauseVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27640,15 +27341,13 @@ abstract class ApiHelper { } - def queryVRouterOspfNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterOspfNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVRouterOspfNetworkAction() + def powerOffBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOffBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.PowerOffBareMetal2ChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27669,15 +27368,13 @@ abstract class ApiHelper { } - def queryVRouterRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterRouteEntryAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVRouterRouteEntryAction() + def powerOffBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOffBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.PowerOffBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27698,15 +27395,13 @@ abstract class ApiHelper { } - def queryVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVRouterRouteTableAction() + def powerOffHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOffHostAction.class) Closure c) { + def a = new org.zstack.sdk.PowerOffHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27727,15 +27422,13 @@ abstract class ApiHelper { } - def queryVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVipAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVipAction() + def powerOnBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOnBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.PowerOnBareMetal2ChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27756,15 +27449,13 @@ abstract class ApiHelper { } - def queryVirtualBorderRouterFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualBorderRouterFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVirtualBorderRouterFromLocalAction() + def powerOnBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOnBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.PowerOnBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27785,15 +27476,13 @@ abstract class ApiHelper { } - def queryVirtualRouterOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualRouterOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVirtualRouterOfferingAction() + def powerOnHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerOnHostAction.class) Closure c) { + def a = new org.zstack.sdk.PowerOnHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27814,15 +27503,13 @@ abstract class ApiHelper { } - def queryVirtualRouterVRouterRouteTableRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualRouterVRouterRouteTableRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVirtualRouterVRouterRouteTableRefAction() + def powerResetBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerResetBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.PowerResetBareMetal2ChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27843,15 +27530,13 @@ abstract class ApiHelper { } - def queryVirtualRouterVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualRouterVmAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVirtualRouterVmAction() + def powerResetBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerResetBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.PowerResetBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27872,15 +27557,13 @@ abstract class ApiHelper { } - def queryVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmCdRomAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmCdRomAction() + def powerResetHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PowerResetHostAction.class) Closure c) { + def a = new org.zstack.sdk.PowerResetHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27901,15 +27584,13 @@ abstract class ApiHelper { } - def queryVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmInstanceAction() + def previewResourceFromApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PreviewResourceFromAppAction.class) Closure c) { + def a = new org.zstack.sdk.PreviewResourceFromAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27930,15 +27611,13 @@ abstract class ApiHelper { } - def queryVmInstanceMdevDeviceSpecRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstanceMdevDeviceSpecRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmInstanceMdevDeviceSpecRefAction() + def previewResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PreviewResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.PreviewResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27959,15 +27638,13 @@ abstract class ApiHelper { } - def queryVmInstancePciDeviceSpecRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstancePciDeviceSpecRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmInstancePciDeviceSpecRefAction() + def primaryStorageMigrateVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrimaryStorageMigrateVmAction.class) Closure c) { + def a = new org.zstack.sdk.PrimaryStorageMigrateVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -27988,15 +27665,13 @@ abstract class ApiHelper { } - def queryVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmNicAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmNicAction() + def primaryStorageMigrateVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrimaryStorageMigrateVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.PrimaryStorageMigrateVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28017,15 +27692,40 @@ abstract class ApiHelper { } - def queryVmNicInSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmNicInSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmNicInSecurityGroupAction() + def prometheusQueryLabelValues(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryLabelValuesAction.class) Closure c) { + def a = new org.zstack.sdk.PrometheusQueryLabelValuesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def prometheusQueryMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryMetadataAction.class) Closure c) { + def a = new org.zstack.sdk.PrometheusQueryMetadataAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28046,15 +27746,40 @@ abstract class ApiHelper { } - def queryVmPriorityConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmPriorityConfigAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVmPriorityConfigAction() + def prometheusQueryPassThrough(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryPassThroughAction.class) Closure c) { + def a = new org.zstack.sdk.PrometheusQueryPassThroughAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def prometheusQueryVmMonitoringData(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PrometheusQueryVmMonitoringDataAction.class) Closure c) { + def a = new org.zstack.sdk.PrometheusQueryVmMonitoringDataAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28075,15 +27800,40 @@ abstract class ApiHelper { } - def queryVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVniRangeAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVniRangeAction() + def protectVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ProtectVmInstanceRecoveryPointAction.class) Closure c) { + def a = new org.zstack.sdk.ProtectVmInstanceRecoveryPointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def provisionSlbInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ProvisionSlbInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.ProvisionSlbInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28104,15 +27854,40 @@ abstract class ApiHelper { } - def queryVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVolumeAction() + def provisionVirtualRouterConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ProvisionVirtualRouterConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ProvisionVirtualRouterConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def publishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PublishAppAction.class) Closure c) { + def a = new org.zstack.sdk.PublishAppAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28133,16 +27908,41 @@ abstract class ApiHelper { } - def queryVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVolumeSnapshotAction() + def pullSdnControllerTenant(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PullSdnControllerTenantAction.class) Closure c) { + def a = new org.zstack.sdk.PullSdnControllerTenantAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + def pushLicenseAddOnsUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.PushLicenseAddOnsUsageAction.class) Closure c) { + def a = new org.zstack.sdk.PushLicenseAddOnsUsageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + if (System.getProperty("apipath") != null) { if (a.apiId == null) { a.apiId = Platform.uuid @@ -28162,8 +27962,8 @@ abstract class ApiHelper { } - def queryVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVolumeSnapshotGroupAction() + def queryAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccessControlListAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccessControlListAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28191,8 +27991,8 @@ abstract class ApiHelper { } - def queryVolumeSnapshotTree(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeSnapshotTreeAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVolumeSnapshotTreeAction() + def queryAccessControlRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccessControlRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccessControlRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28220,8 +28020,8 @@ abstract class ApiHelper { } - def queryVpcFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcFirewallAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcFirewallAction() + def queryAccessKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccessKeyAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccessKeyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28249,8 +28049,8 @@ abstract class ApiHelper { } - def queryVpcFirewallVRouterRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcFirewallVRouterRefAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcFirewallVRouterRefAction() + def queryAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccountAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28278,8 +28078,8 @@ abstract class ApiHelper { } - def queryVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcHaGroupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcHaGroupAction() + def queryAccountBilling(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountBillingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccountBillingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28307,8 +28107,8 @@ abstract class ApiHelper { } - def queryVpcIkeConfigFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcIkeConfigFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcIkeConfigFromLocalAction() + def queryAccountPriceTableRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountPriceTableRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccountPriceTableRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28336,8 +28136,8 @@ abstract class ApiHelper { } - def queryVpcIpSecConfigFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcIpSecConfigFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcIpSecConfigFromLocalAction() + def queryAccountResourceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAccountResourceRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAccountResourceRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28365,8 +28165,8 @@ abstract class ApiHelper { } - def queryVpcRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcRouterAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcRouterAction() + def queryAddressPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAddressPoolAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAddressPoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28394,8 +28194,8 @@ abstract class ApiHelper { } - def queryVpcUserVpnGatewayFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcUserVpnGatewayFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcUserVpnGatewayFromLocalAction() + def queryAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAffinityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28423,8 +28223,8 @@ abstract class ApiHelper { } - def queryVpcVpnConnectionFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcVpnConnectionFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcVpnConnectionFromLocalAction() + def queryAgentVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAgentVersionAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAgentVersionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28452,8 +28252,8 @@ abstract class ApiHelper { } - def queryVpcVpnGatewayFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcVpnGatewayFromLocalAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVpcVpnGatewayFromLocalAction() + def queryAlert(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAlertAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAlertAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28481,8 +28281,8 @@ abstract class ApiHelper { } - def queryVtep(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVtepAction.class) Closure c) { - def a = new org.zstack.sdk.QueryVtepAction() + def queryAliyunDiskFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunDiskFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunDiskFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28510,8 +28310,8 @@ abstract class ApiHelper { } - def queryWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryWebhookAction.class) Closure c) { - def a = new org.zstack.sdk.QueryWebhookAction() + def queryAliyunEbsBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunEbsBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunEbsBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28539,8 +28339,8 @@ abstract class ApiHelper { } - def queryZBox(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZBoxAction.class) Closure c) { - def a = new org.zstack.sdk.QueryZBoxAction() + def queryAliyunEbsPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunEbsPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunEbsPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28568,8 +28368,8 @@ abstract class ApiHelper { } - def queryZBoxBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZBoxBackupAction.class) Closure c) { - def a = new org.zstack.sdk.QueryZBoxBackupAction() + def queryAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunNasAccessGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunNasAccessGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28597,8 +28397,8 @@ abstract class ApiHelper { } - def queryZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZoneAction.class) Closure c) { - def a = new org.zstack.sdk.QueryZoneAction() + def queryAliyunPanguPartition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunPanguPartitionAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunPanguPartitionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -28626,13 +28426,15 @@ abstract class ApiHelper { } - def rebootBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RebootBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RebootBaremetalInstanceAction() + def queryAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunProxyVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunProxyVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28653,13 +28455,15 @@ abstract class ApiHelper { } - def rebootEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RebootEcsInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RebootEcsInstanceAction() + def queryAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunProxyVpcAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunProxyVpcAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28680,13 +28484,15 @@ abstract class ApiHelper { } - def rebootVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RebootVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RebootVmInstanceAction() + def queryAliyunRouteEntryFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunRouteEntryFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunRouteEntryFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28707,13 +28513,15 @@ abstract class ApiHelper { } - def reclaimSpaceFromImageStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReclaimSpaceFromImageStoreAction.class) Closure c) { - def a = new org.zstack.sdk.ReclaimSpaceFromImageStoreAction() + def queryAliyunRouterInterfaceFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunRouterInterfaceFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunRouterInterfaceFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28734,13 +28542,15 @@ abstract class ApiHelper { } - def reconnectAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectAppBuildSystemAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectAppBuildSystemAction() + def queryAliyunSnapshotFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunSnapshotFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunSnapshotFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28761,13 +28571,15 @@ abstract class ApiHelper { } - def reconnectBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectBackupStorageAction() + def queryAliyunVirtualRouterFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAliyunVirtualRouterFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAliyunVirtualRouterFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28788,13 +28600,15 @@ abstract class ApiHelper { } - def reconnectBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBareMetal2GatewayAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectBareMetal2GatewayAction() + def queryAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAppBuildSystemAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAppBuildSystemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28815,13 +28629,15 @@ abstract class ApiHelper { } - def reconnectBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBareMetal2InstanceAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectBareMetal2InstanceAction() + def queryApplianceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryApplianceVmAction.class) Closure c) { + def a = new org.zstack.sdk.QueryApplianceVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28842,13 +28658,15 @@ abstract class ApiHelper { } - def reconnectBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectBaremetalPxeServerAction() + def queryApplicationDevelopmentService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryApplicationDevelopmentServiceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryApplicationDevelopmentServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28869,13 +28687,15 @@ abstract class ApiHelper { } - def reconnectConsoleProxyAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectConsoleProxyAgentAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectConsoleProxyAgentAction() + def queryAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAutoScalingGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28896,13 +28716,15 @@ abstract class ApiHelper { } - def reconnectHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectHostAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectHostAction() + def queryAutoScalingGroupActivity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingGroupActivityAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAutoScalingGroupActivityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28923,13 +28745,15 @@ abstract class ApiHelper { } - def reconnectImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectImageStoreBackupStorageAction() + def queryAutoScalingGroupInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingGroupInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAutoScalingGroupInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28950,13 +28774,15 @@ abstract class ApiHelper { } - def reconnectPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectPrimaryStorageAction() + def queryAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAutoScalingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -28977,13 +28803,15 @@ abstract class ApiHelper { } - def reconnectSftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectSftpBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectSftpBackupStorageAction() + def queryAutoScalingRuleTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingRuleTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAutoScalingRuleTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29004,13 +28832,15 @@ abstract class ApiHelper { } - def reconnectVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectVirtualRouterAction.class) Closure c) { - def a = new org.zstack.sdk.ReconnectVirtualRouterAction() + def queryAutoScalingVmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryAutoScalingVmTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryAutoScalingVmTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29031,13 +28861,15 @@ abstract class ApiHelper { } - def recoverBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RecoverBaremetalInstanceAction() + def queryBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29058,13 +28890,15 @@ abstract class ApiHelper { } - def recoverDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverDataVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.RecoverDataVolumeAction() + def queryBareMetal2Bonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2BondingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2BondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29085,13 +28919,15 @@ abstract class ApiHelper { } - def recoverImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverImageAction.class) Closure c) { - def a = new org.zstack.sdk.RecoverImageAction() + def queryBareMetal2BondingNicRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2BondingNicRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2BondingNicRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29112,13 +28948,15 @@ abstract class ApiHelper { } - def recoverResourceSplitBrain(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverResourceSplitBrainAction.class) Closure c) { - def a = new org.zstack.sdk.RecoverResourceSplitBrainAction() + def queryBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2ChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29139,13 +28977,15 @@ abstract class ApiHelper { } - def recoverVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RecoverVmInstanceAction() + def queryBareMetal2ChassisGpuDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ChassisGpuDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2ChassisGpuDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29166,13 +29006,15 @@ abstract class ApiHelper { } - def recoveryImageFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoveryImageFromImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.RecoveryImageFromImageStoreBackupStorageAction() + def queryBareMetal2ChassisOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ChassisOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2ChassisOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29193,13 +29035,15 @@ abstract class ApiHelper { } - def recoveryVirtualBorderRouterRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoveryVirtualBorderRouterRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.RecoveryVirtualBorderRouterRemoteAction() + def queryBareMetal2ChassisPciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ChassisPciDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2ChassisPciDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29220,13 +29064,15 @@ abstract class ApiHelper { } - def refreshCaptcha(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshCaptchaAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshCaptchaAction() - + def queryBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2GatewayAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2GatewayAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29247,13 +29093,15 @@ abstract class ApiHelper { } - def refreshFiberChannelStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshFiberChannelStorageAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshFiberChannelStorageAction() + def queryBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2InstanceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2InstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29274,13 +29122,15 @@ abstract class ApiHelper { } - def refreshFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshFirewallAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshFirewallAction() + def queryBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBareMetal2ProvisionNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBareMetal2ProvisionNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29301,13 +29151,15 @@ abstract class ApiHelper { } - def refreshIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshIscsiServerAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshIscsiServerAction() + def queryBaremetalBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalBondingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBaremetalBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29328,13 +29180,15 @@ abstract class ApiHelper { } - def refreshLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshLoadBalancerAction() + def queryBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBaremetalChassisAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29355,13 +29209,15 @@ abstract class ApiHelper { } - def refreshLocalRaid(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshLocalRaidAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshLocalRaidAction() + def queryBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBaremetalInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29382,13 +29238,15 @@ abstract class ApiHelper { } - def refreshSearchIndexes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshSearchIndexesAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshSearchIndexesAction() + def queryBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBaremetalPxeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29409,13 +29267,15 @@ abstract class ApiHelper { } - def refreshSharedblockDeviceCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshSharedblockDeviceCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.RefreshSharedblockDeviceCapacityAction() + def queryBlockPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBlockPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBlockPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29436,13 +29296,15 @@ abstract class ApiHelper { } - def reimageVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReimageVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.ReimageVmInstanceAction() + def queryBlockVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBlockVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBlockVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29463,13 +29325,15 @@ abstract class ApiHelper { } - def reloadElaboration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReloadElaborationAction.class) Closure c) { - def a = new org.zstack.sdk.ReloadElaborationAction() + def queryBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBuildAppAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBuildAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29490,13 +29354,15 @@ abstract class ApiHelper { } - def reloadLicense(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReloadLicenseAction.class) Closure c) { - def a = new org.zstack.sdk.ReloadLicenseAction() + def queryBuildAppExportHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryBuildAppExportHistoryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryBuildAppExportHistoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29517,13 +29383,15 @@ abstract class ApiHelper { } - def removeAccessControlListEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveAccessControlListEntryAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveAccessControlListEntryAction() + def queryCCSCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCCSCertificateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCCSCertificateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29544,13 +29412,15 @@ abstract class ApiHelper { } - def removeAccessControlListFromLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveAccessControlListFromLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveAccessControlListFromLoadBalancerAction() + def queryCbtTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCbtTaskAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCbtTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29571,13 +29441,15 @@ abstract class ApiHelper { } - def removeBackendServerFromServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveBackendServerFromServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveBackendServerFromServerGroupAction() + def queryCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCdpPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCdpPolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29598,13 +29470,15 @@ abstract class ApiHelper { } - def removeCertificateFromLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveCertificateFromLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveCertificateFromLoadBalancerListenerAction() + def queryCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCdpTaskAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCdpTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29625,13 +29499,15 @@ abstract class ApiHelper { } - def removeDnsFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveDnsFromL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveDnsFromL3NetworkAction() + def queryCephBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCephBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29652,13 +29528,15 @@ abstract class ApiHelper { } - def removeDnsFromVpcRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveDnsFromVpcRouterAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveDnsFromVpcRouterAction() + def queryCephOsdGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephOsdGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCephOsdGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29679,13 +29557,15 @@ abstract class ApiHelper { } - def removeHostRouteFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveHostRouteFromL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveHostRouteFromL3NetworkAction() + def queryCephPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCephPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29706,13 +29586,15 @@ abstract class ApiHelper { } - def removeMdevDeviceSpecFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveMdevDeviceSpecFromVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveMdevDeviceSpecFromVmInstanceAction() + def queryCephPrimaryStoragePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCephPrimaryStoragePoolAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCephPrimaryStoragePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29733,13 +29615,15 @@ abstract class ApiHelper { } - def removeMonFromCephBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveMonFromCephBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveMonFromCephBackupStorageAction() + def queryCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryCertificateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryCertificateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29760,13 +29644,15 @@ abstract class ApiHelper { } - def removeMonFromCephPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveMonFromCephPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveMonFromCephPrimaryStorageAction() + def queryCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryClusterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29787,13 +29673,15 @@ abstract class ApiHelper { } - def removePciDeviceSpecFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemovePciDeviceSpecFromVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.RemovePciDeviceSpecFromVmInstanceAction() + def queryClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryClusterDRSAction.class) Closure c) { + def a = new org.zstack.sdk.QueryClusterDRSAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29814,13 +29702,15 @@ abstract class ApiHelper { } - def removeRemoteCidrsFromIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveRemoteCidrsFromIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveRemoteCidrsFromIPsecConnectionAction() + def queryConnectionAccessPointFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryConnectionAccessPointFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryConnectionAccessPointFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29841,13 +29731,15 @@ abstract class ApiHelper { } - def removeRendezvousPointFromMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveRendezvousPointFromMulticastRouterAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveRendezvousPointFromMulticastRouterAction() + def queryConnectionBetweenL3NetworkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryConnectionBetweenL3NetworkAndAliyunVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.QueryConnectionBetweenL3NetworkAndAliyunVSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29868,13 +29760,15 @@ abstract class ApiHelper { } - def removeSchedulerJobFromSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSchedulerJobFromSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveSchedulerJobFromSchedulerTriggerAction() + def queryConsoleProxyAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryConsoleProxyAgentAction.class) Closure c) { + def a = new org.zstack.sdk.QueryConsoleProxyAgentAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29895,13 +29789,15 @@ abstract class ApiHelper { } - def removeSchedulerJobGroupFromSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSchedulerJobGroupFromSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveSchedulerJobGroupFromSchedulerTriggerAction() + def queryContainerImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryContainerImageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryContainerImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29922,40 +29818,15 @@ abstract class ApiHelper { } - def removeSchedulerJobsFromSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSchedulerJobsFromSchedulerJobGroupAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveSchedulerJobsFromSchedulerJobGroupAction() + def queryContainerManagementEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryContainerManagementEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.QueryContainerManagementEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def removeSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSdnControllerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveSdnControllerAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -29976,40 +29847,15 @@ abstract class ApiHelper { } - def removeServerGroupFromLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveServerGroupFromLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveServerGroupFromLoadBalancerListenerAction() + def queryDRSAdvice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDRSAdviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryDRSAdviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def removeUserFromGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveUserFromGroupAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveUserFromGroupAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30030,40 +29876,15 @@ abstract class ApiHelper { } - def removeVRouterNetworksFromFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVRouterNetworksFromFlowMeterAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveVRouterNetworksFromFlowMeterAction() + def queryDRSVmMigrationActivity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDRSVmMigrationActivityAction.class) Closure c) { + def a = new org.zstack.sdk.QueryDRSVmMigrationActivityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def removeVRouterNetworksFromOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVRouterNetworksFromOspfAreaAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveVRouterNetworksFromOspfAreaAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30084,40 +29905,15 @@ abstract class ApiHelper { } - def removeVmFromAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVmFromAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveVmFromAffinityGroupAction() + def queryDataCenterFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDataCenterFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryDataCenterFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def removeVmNicFromLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVmNicFromLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.RemoveVmNicFromLoadBalancerAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30138,40 +29934,15 @@ abstract class ApiHelper { } - def renewSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RenewSessionAction.class) Closure c) { - def a = new org.zstack.sdk.RenewSessionAction() + def queryDataset(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDatasetAction.class) Closure c) { + def a = new org.zstack.sdk.QueryDatasetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def requestConsoleAccess(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RequestConsoleAccessAction.class) Closure c) { - def a = new org.zstack.sdk.RequestConsoleAccessAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30192,13 +29963,15 @@ abstract class ApiHelper { } - def rerunLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RerunLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.RerunLongJobAction() + def queryDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30219,13 +29992,15 @@ abstract class ApiHelper { } - def resetGlobalConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResetGlobalConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ResetGlobalConfigAction() + def queryDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryDiskOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryDiskOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30246,13 +30021,15 @@ abstract class ApiHelper { } - def resetTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResetTemplateConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ResetTemplateConfigAction() + def queryEcsImageFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsImageFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEcsImageFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30273,13 +30050,15 @@ abstract class ApiHelper { } - def resetTwoFactorAuthenticationSecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResetTwoFactorAuthenticationSecretAction.class) Closure c) { - def a = new org.zstack.sdk.ResetTwoFactorAuthenticationSecretAction() + def queryEcsInstanceFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsInstanceFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEcsInstanceFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30300,13 +30079,15 @@ abstract class ApiHelper { } - def resizeDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResizeDataVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.ResizeDataVolumeAction() + def queryEcsSecurityGroupFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsSecurityGroupFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEcsSecurityGroupFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30327,13 +30108,15 @@ abstract class ApiHelper { } - def resizeRootVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResizeRootVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.ResizeRootVolumeAction() + def queryEcsSecurityGroupRuleFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsSecurityGroupRuleFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEcsSecurityGroupRuleFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30354,13 +30137,15 @@ abstract class ApiHelper { } - def restartResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RestartResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.RestartResourceStackAction() + def queryEcsVSwitchFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsVSwitchFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEcsVSwitchFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30381,13 +30166,15 @@ abstract class ApiHelper { } - def resumeLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResumeLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.ResumeLongJobAction() + def queryEcsVpcFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEcsVpcFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEcsVpcFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30408,13 +30195,15 @@ abstract class ApiHelper { } - def resumeVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResumeVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.ResumeVmInstanceAction() + def queryEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEipAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30435,13 +30224,15 @@ abstract class ApiHelper { } - def revertVmFromCdpBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertVmFromCdpBackupAction.class) Closure c) { - def a = new org.zstack.sdk.RevertVmFromCdpBackupAction() + def queryEmailMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEmailMediaAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEmailMediaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30462,13 +30253,15 @@ abstract class ApiHelper { } - def revertVmFromSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertVmFromSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.RevertVmFromSnapshotGroupAction() + def queryEmailTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEmailTriggerActionAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEmailTriggerActionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30489,13 +30282,15 @@ abstract class ApiHelper { } - def revertVolumeFromSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertVolumeFromSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.RevertVolumeFromSnapshotAction() + def queryEthernetVF(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEthernetVFAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEthernetVFAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30516,13 +30311,15 @@ abstract class ApiHelper { } - def revokeResourceSharing(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevokeResourceSharingAction.class) Closure c) { - def a = new org.zstack.sdk.RevokeResourceSharingAction() + def queryEventFromResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEventFromResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEventFromResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30543,13 +30340,15 @@ abstract class ApiHelper { } - def runIAM2Script(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RunIAM2ScriptAction.class) Closure c) { - def a = new org.zstack.sdk.RunIAM2ScriptAction() + def queryEventLog(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryEventLogAction.class) Closure c) { + def a = new org.zstack.sdk.QueryEventLogAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30570,13 +30369,15 @@ abstract class ApiHelper { } - def runSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RunSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.RunSchedulerTriggerAction() + def queryExponBlockVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryExponBlockVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryExponBlockVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30597,13 +30398,15 @@ abstract class ApiHelper { } - def securityMachineDetectSync(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SecurityMachineDetectSyncAction.class) Closure c) { - def a = new org.zstack.sdk.SecurityMachineDetectSyncAction() + def queryExternalBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryExternalBackupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryExternalBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30624,13 +30427,15 @@ abstract class ApiHelper { } - def securityMachineEncrypt(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SecurityMachineEncryptAction.class) Closure c) { - def a = new org.zstack.sdk.SecurityMachineEncryptAction() + def queryFaultToleranceVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFaultToleranceVmAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFaultToleranceVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30651,13 +30456,15 @@ abstract class ApiHelper { } - def selfTestLocalRaid(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SelfTestLocalRaidAction.class) Closure c) { - def a = new org.zstack.sdk.SelfTestLocalRaidAction() + def queryFcHbaDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFcHbaDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFcHbaDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30678,13 +30485,15 @@ abstract class ApiHelper { } - def setFlowMeterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetFlowMeterRouterIdAction.class) Closure c) { - def a = new org.zstack.sdk.SetFlowMeterRouterIdAction() + def queryFiberChannelLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFiberChannelLunAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFiberChannelLunAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30705,40 +30514,15 @@ abstract class ApiHelper { } - def setImageBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageBootModeAction.class) Closure c) { - def a = new org.zstack.sdk.SetImageBootModeAction() + def queryFiberChannelStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFiberChannelStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFiberChannelStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def setImageQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageQgaAction.class) Closure c) { - def a = new org.zstack.sdk.SetImageQgaAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30759,13 +30543,15 @@ abstract class ApiHelper { } - def setImageSecurityLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageSecurityLevelAction.class) Closure c) { - def a = new org.zstack.sdk.SetImageSecurityLevelAction() + def queryFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallIpSetTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFirewallIpSetTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30786,13 +30572,15 @@ abstract class ApiHelper { } - def setImageStoreBackupStorageQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageStoreBackupStorageQuotaAction.class) Closure c) { - def a = new org.zstack.sdk.SetImageStoreBackupStorageQuotaAction() + def queryFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFirewallRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30813,13 +30601,15 @@ abstract class ApiHelper { } - def setL3NetworkMtu(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetL3NetworkMtuAction.class) Closure c) { - def a = new org.zstack.sdk.SetL3NetworkMtuAction() + def queryFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFirewallRuleSetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30840,13 +30630,15 @@ abstract class ApiHelper { } - def setL3NetworkRouterInterfaceIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetL3NetworkRouterInterfaceIpAction.class) Closure c) { - def a = new org.zstack.sdk.SetL3NetworkRouterInterfaceIpAction() + def queryFirewallRuleSetL3Ref(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleSetL3RefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFirewallRuleSetL3RefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30867,13 +30659,15 @@ abstract class ApiHelper { } - def setNicQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetNicQosAction.class) Closure c) { - def a = new org.zstack.sdk.SetNicQosAction() + def queryFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFirewallRuleTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFirewallRuleTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30894,13 +30688,15 @@ abstract class ApiHelper { } - def setSecurityMachineKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetSecurityMachineKeyAction.class) Closure c) { - def a = new org.zstack.sdk.SetSecurityMachineKeyAction() + def queryFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFlowCollectorAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFlowCollectorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30921,13 +30717,15 @@ abstract class ApiHelper { } - def setVRouterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVRouterRouterIdAction.class) Closure c) { - def a = new org.zstack.sdk.SetVRouterRouterIdAction() + def queryFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryFlowMeterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryFlowMeterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30948,13 +30746,15 @@ abstract class ApiHelper { } - def setVipQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVipQosAction.class) Closure c) { - def a = new org.zstack.sdk.SetVipQosAction() + def queryGCJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGCJobAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGCJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -30975,13 +30775,15 @@ abstract class ApiHelper { } - def setVmBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmBootModeAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmBootModeAction() + def queryGlobalConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGlobalConfigAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGlobalConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31002,13 +30804,15 @@ abstract class ApiHelper { } - def setVmBootOrder(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmBootOrderAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmBootOrderAction() + def queryGlobalConfigTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGlobalConfigTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGlobalConfigTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31029,13 +30833,15 @@ abstract class ApiHelper { } - def setVmBootVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmBootVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmBootVolumeAction() + def queryGpuDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGpuDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGpuDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31056,13 +30862,15 @@ abstract class ApiHelper { } - def setVmCleanTraffic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmCleanTrafficAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmCleanTrafficAction() + def queryGuestToolsState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGuestToolsStateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGuestToolsStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31083,13 +30891,15 @@ abstract class ApiHelper { } - def setVmClockTrack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmClockTrackAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmClockTrackAction() + def queryGuestVmScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGuestVmScriptAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGuestVmScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31110,13 +30920,15 @@ abstract class ApiHelper { } - def setVmConsoleMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmConsoleModeAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmConsoleModeAction() + def queryGuestVmScriptExecutedRecord(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGuestVmScriptExecutedRecordAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGuestVmScriptExecutedRecordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31137,13 +30949,15 @@ abstract class ApiHelper { } - def setVmConsolePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmConsolePasswordAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmConsolePasswordAction() + def queryGuestVmScriptExecutedRecordDetail(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryGuestVmScriptExecutedRecordDetailAction.class) Closure c) { + def a = new org.zstack.sdk.QueryGuestVmScriptExecutedRecordDetailAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31164,13 +30978,15 @@ abstract class ApiHelper { } - def setVmEmulatorPinning(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmEmulatorPinningAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmEmulatorPinningAction() + def queryHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31191,13 +31007,15 @@ abstract class ApiHelper { } - def setVmHostname(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmHostnameAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmHostnameAction() + def queryHostNetworkBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostNetworkBondingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostNetworkBondingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31218,13 +31036,15 @@ abstract class ApiHelper { } - def setVmInstanceDefaultCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmInstanceDefaultCdRomAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmInstanceDefaultCdRomAction() + def queryHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostNetworkInterfaceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostNetworkInterfaceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31245,13 +31065,15 @@ abstract class ApiHelper { } - def setVmInstanceHaLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmInstanceHaLevelAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmInstanceHaLevelAction() + def queryHostNetworkInterfaceLldp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostNetworkInterfaceLldpAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostNetworkInterfaceLldpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31272,13 +31094,15 @@ abstract class ApiHelper { } - def setVmMonitorNumber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmMonitorNumberAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmMonitorNumberAction() + def queryHostOsCategory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostOsCategoryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostOsCategoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31299,13 +31123,15 @@ abstract class ApiHelper { } - def setVmNuma(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmNumaAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmNumaAction() + def queryHostPhysicalMemory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostPhysicalMemoryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostPhysicalMemoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31326,13 +31152,15 @@ abstract class ApiHelper { } - def setVmQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmQgaAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmQgaAction() + def queryHostSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHostSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHostSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31353,13 +31181,15 @@ abstract class ApiHelper { } - def setVmQxlMemory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmQxlMemoryAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmQxlMemoryAction() + def queryHybridEipFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHybridEipFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHybridEipFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31380,13 +31210,15 @@ abstract class ApiHelper { } - def setVmRDP(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmRDPAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmRDPAction() + def queryHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryHybridKeySecretAction.class) Closure c) { + def a = new org.zstack.sdk.QueryHybridKeySecretAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31407,13 +31239,15 @@ abstract class ApiHelper { } - def setVmSecurityLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmSecurityLevelAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmSecurityLevelAction() + def queryIAM2LdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIAM2LdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIAM2LdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31434,13 +31268,15 @@ abstract class ApiHelper { } - def setVmSoundType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmSoundTypeAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmSoundTypeAction() + def queryIPSecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIPSecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIPSecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31461,13 +31297,15 @@ abstract class ApiHelper { } - def setVmSshKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmSshKeyAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmSshKeyAction() + def queryIdentityZoneFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIdentityZoneFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIdentityZoneFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31488,13 +31326,15 @@ abstract class ApiHelper { } - def setVmStaticIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmStaticIpAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmStaticIpAction() + def queryImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31515,13 +31355,15 @@ abstract class ApiHelper { } - def setVmUsbRedirect(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmUsbRedirectAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmUsbRedirectAction() + def queryImageCache(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageCacheAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImageCacheAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31542,13 +31384,15 @@ abstract class ApiHelper { } - def setVmUserDefinedXml(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmUserDefinedXmlAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmUserDefinedXmlAction() + def queryImageGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImageGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31569,13 +31413,15 @@ abstract class ApiHelper { } - def setVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmUserDefinedXmlHookScriptAction.class) Closure c) { - def a = new org.zstack.sdk.SetVmUserDefinedXmlHookScriptAction() + def queryImageGroupRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageGroupRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImageGroupRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31596,13 +31442,15 @@ abstract class ApiHelper { } - def setVolumeQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVolumeQosAction.class) Closure c) { - def a = new org.zstack.sdk.SetVolumeQosAction() + def queryImagePackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImagePackageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImagePackageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31623,13 +31471,15 @@ abstract class ApiHelper { } - def setVpcVRouterDistributedRoutingEnabled(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVpcVRouterDistributedRoutingEnabledAction.class) Closure c) { - def a = new org.zstack.sdk.SetVpcVRouterDistributedRoutingEnabledAction() + def queryImageReplicationGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageReplicationGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImageReplicationGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31650,13 +31500,15 @@ abstract class ApiHelper { } - def setVpcVRouterNetworkServiceState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVpcVRouterNetworkServiceStateAction.class) Closure c) { - def a = new org.zstack.sdk.SetVpcVRouterNetworkServiceStateAction() + def queryImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryImageStoreBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31677,13 +31529,15 @@ abstract class ApiHelper { } - def shareResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ShareResourceAction.class) Closure c) { - def a = new org.zstack.sdk.ShareResourceAction() + def queryInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryInstanceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryInstanceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31704,13 +31558,15 @@ abstract class ApiHelper { } - def shrinkVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ShrinkVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.ShrinkVolumeSnapshotAction() + def queryIpAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIpAddressAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIpAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31731,13 +31587,15 @@ abstract class ApiHelper { } - def startBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartBareMetal2InstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StartBareMetal2InstanceAction() + def queryIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIpRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31758,13 +31616,15 @@ abstract class ApiHelper { } - def startBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StartBaremetalInstanceAction() + def queryIscsiLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIscsiLunAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIscsiLunAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31785,13 +31645,15 @@ abstract class ApiHelper { } - def startBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.StartBaremetalPxeServerAction() + def queryIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryIscsiServerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryIscsiServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31812,13 +31674,15 @@ abstract class ApiHelper { } - def startConnectionBetweenAliyunRouterInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartConnectionBetweenAliyunRouterInterfaceAction.class) Closure c) { - def a = new org.zstack.sdk.StartConnectionBetweenAliyunRouterInterfaceAction() + def queryKvmHypervisorInfo(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryKvmHypervisorInfoAction.class) Closure c) { + def a = new org.zstack.sdk.QueryKvmHypervisorInfoAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31839,13 +31703,15 @@ abstract class ApiHelper { } - def startDataProtection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartDataProtectionAction.class) Closure c) { - def a = new org.zstack.sdk.StartDataProtectionAction() + def queryL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL2NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31866,13 +31732,15 @@ abstract class ApiHelper { } - def startEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartEcsInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StartEcsInstanceAction() + def queryL2PortGroupNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2PortGroupNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL2PortGroupNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31893,40 +31761,15 @@ abstract class ApiHelper { } - def startVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StartVmInstanceAction() + def queryL2VirtualSwitchNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VirtualSwitchNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL2VirtualSwitchNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def stopBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StopBaremetalInstanceAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -31947,40 +31790,15 @@ abstract class ApiHelper { } - def stopBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.StopBaremetalPxeServerAction() + def queryL2VlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VlanNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL2VlanNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def stopEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopEcsInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StopEcsInstanceAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32001,40 +31819,15 @@ abstract class ApiHelper { } - def stopVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.StopVmInstanceAction() + def queryL2VxlanNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VxlanNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL2VxlanNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def submitLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SubmitLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.SubmitLongJobAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32055,40 +31848,15 @@ abstract class ApiHelper { } - def syncAliyunRouteEntryFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunRouteEntryFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncAliyunRouteEntryFromRemoteAction() + def queryL2VxlanNetworkPool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL2VxlanNetworkPoolAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL2VxlanNetworkPoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def syncAliyunRouterInterfaceFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunRouterInterfaceFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncAliyunRouterInterfaceFromRemoteAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32109,40 +31877,15 @@ abstract class ApiHelper { } - def syncAliyunSnapshotRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunSnapshotRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncAliyunSnapshotRemoteAction() + def queryL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def syncAliyunVirtualRouterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunVirtualRouterFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncAliyunVirtualRouterFromRemoteAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32163,13 +31906,15 @@ abstract class ApiHelper { } - def syncConnectionAccessPointFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncConnectionAccessPointFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncConnectionAccessPointFromRemoteAction() + def queryLdapBinding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLdapBindingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLdapBindingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32190,13 +31935,15 @@ abstract class ApiHelper { } - def syncDataCenterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncDataCenterFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncDataCenterFromRemoteAction() + def queryLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLdapServerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLdapServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32217,13 +31964,15 @@ abstract class ApiHelper { } - def syncDiskFromAliyunFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncDiskFromAliyunFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncDiskFromAliyunFromRemoteAction() + def queryLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32244,13 +31993,15 @@ abstract class ApiHelper { } - def syncEcsImageFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsImageFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncEcsImageFromRemoteAction() + def queryLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32271,13 +32022,15 @@ abstract class ApiHelper { } - def syncEcsInstanceFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsInstanceFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncEcsInstanceFromRemoteAction() + def queryLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLoadBalancerServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLoadBalancerServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32298,13 +32051,15 @@ abstract class ApiHelper { } - def syncEcsSecurityGroupFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsSecurityGroupFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncEcsSecurityGroupFromRemoteAction() + def queryLocalRaidController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLocalRaidControllerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLocalRaidControllerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32325,13 +32080,15 @@ abstract class ApiHelper { } - def syncEcsSecurityGroupRuleFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsSecurityGroupRuleFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncEcsSecurityGroupRuleFromRemoteAction() + def queryLocalRaidPhysicalDrive(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLocalRaidPhysicalDriveAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLocalRaidPhysicalDriveAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32352,13 +32109,15 @@ abstract class ApiHelper { } - def syncEcsVSwitchFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsVSwitchFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncEcsVSwitchFromRemoteAction() + def queryLocalStorageResourceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLocalStorageResourceRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLocalStorageResourceRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32379,13 +32138,15 @@ abstract class ApiHelper { } - def syncEcsVpcFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsVpcFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncEcsVpcFromRemoteAction() + def queryLogServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLogServerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLogServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32406,13 +32167,15 @@ abstract class ApiHelper { } - def syncHybridEipFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncHybridEipFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncHybridEipFromRemoteAction() + def queryLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.QueryLongJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32433,13 +32196,15 @@ abstract class ApiHelper { } - def syncIdentityFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncIdentityFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncIdentityFromRemoteAction() + def queryManagementNode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryManagementNodeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryManagementNodeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32460,13 +32225,15 @@ abstract class ApiHelper { } - def syncImageFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncImageFromImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.SyncImageFromImageStoreBackupStorageAction() + def queryMdevDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMdevDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMdevDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32487,13 +32254,15 @@ abstract class ApiHelper { } - def syncImageSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncImageSizeAction.class) Closure c) { - def a = new org.zstack.sdk.SyncImageSizeAction() + def queryMdevDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMdevDeviceSpecAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMdevDeviceSpecAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32514,13 +32283,15 @@ abstract class ApiHelper { } - def syncLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncLdapServerAction.class) Closure c) { - def a = new org.zstack.sdk.SyncLdapServerAction() + def queryMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMediaAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMediaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32541,13 +32312,15 @@ abstract class ApiHelper { } - def syncPrimaryStorageCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncPrimaryStorageCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.SyncPrimaryStorageCapacityAction() + def queryMiniStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMiniStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMiniStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32568,13 +32341,15 @@ abstract class ApiHelper { } - def syncVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVCenterAction.class) Closure c) { - def a = new org.zstack.sdk.SyncVCenterAction() + def queryMiniStorageHostRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMiniStorageHostRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMiniStorageHostRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32595,13 +32370,15 @@ abstract class ApiHelper { } - def syncVirtualBorderRouterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVirtualBorderRouterFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncVirtualBorderRouterFromRemoteAction() + def queryMiniStorageResourceReplication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMiniStorageResourceReplicationAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMiniStorageResourceReplicationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32622,13 +32399,15 @@ abstract class ApiHelper { } - def syncVolumeSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVolumeSizeAction.class) Closure c) { - def a = new org.zstack.sdk.SyncVolumeSizeAction() + def queryModel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryModelAction.class) Closure c) { + def a = new org.zstack.sdk.QueryModelAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32649,40 +32428,15 @@ abstract class ApiHelper { } - def syncVpcUserVpnGatewayFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVpcUserVpnGatewayFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncVpcUserVpnGatewayFromRemoteAction() + def queryModelCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryModelCenterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryModelCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def syncVpcVpnConnectionFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVpcVpnConnectionFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncVpcVpnConnectionFromRemoteAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32703,13 +32457,15 @@ abstract class ApiHelper { } - def syncVpcVpnGatewayFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVpcVpnGatewayFromRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.SyncVpcVpnGatewayFromRemoteAction() + def queryModelEvalServiceInstanceGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryModelEvalServiceInstanceGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryModelEvalServiceInstanceGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32730,13 +32486,15 @@ abstract class ApiHelper { } - def syncZBoxCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncZBoxCapacityAction.class) Closure c) { - def a = new org.zstack.sdk.SyncZBoxCapacityAction() + def queryModelEvaluationTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryModelEvaluationTaskAction.class) Closure c) { + def a = new org.zstack.sdk.QueryModelEvaluationTaskAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32757,13 +32515,15 @@ abstract class ApiHelper { } - def terminateVirtualBorderRouterRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.TerminateVirtualBorderRouterRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.TerminateVirtualBorderRouterRemoteAction() + def queryModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryModelServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32784,13 +32544,15 @@ abstract class ApiHelper { } - def triggerGCJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.TriggerGCJobAction.class) Closure c) { - def a = new org.zstack.sdk.TriggerGCJobAction() + def queryModelServiceInstanceGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryModelServiceInstanceGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryModelServiceInstanceGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32811,13 +32573,15 @@ abstract class ApiHelper { } - def ungenerateMdevDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngenerateMdevDevicesAction.class) Closure c) { - def a = new org.zstack.sdk.UngenerateMdevDevicesAction() + def queryMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMonitorTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMonitorTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32838,13 +32602,15 @@ abstract class ApiHelper { } - def ungenerateSriovPciDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngenerateSriovPciDevicesAction.class) Closure c) { - def a = new org.zstack.sdk.UngenerateSriovPciDevicesAction() + def queryMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMonitorTriggerActionAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMonitorTriggerActionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32865,13 +32631,15 @@ abstract class ApiHelper { } - def ungroupVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngroupVolumeSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UngroupVolumeSnapshotGroupAction() + def queryMttyDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMttyDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMttyDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32892,13 +32660,15 @@ abstract class ApiHelper { } - def unlockIdentity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnlockIdentityAction.class) Closure c) { - def a = new org.zstack.sdk.UnlockIdentityAction() + def queryMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryMulticastRouterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryMulticastRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32919,13 +32689,15 @@ abstract class ApiHelper { } - def unmountVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnmountVmInstanceRecoveryPointAction.class) Closure c) { - def a = new org.zstack.sdk.UnmountVmInstanceRecoveryPointAction() + def queryNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNasFileSystemAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNasFileSystemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32946,13 +32718,15 @@ abstract class ApiHelper { } - def unprotectVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnprotectVmInstanceRecoveryPointAction.class) Closure c) { - def a = new org.zstack.sdk.UnprotectVmInstanceRecoveryPointAction() + def queryNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNasMountTargetAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNasMountTargetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -32973,13 +32747,15 @@ abstract class ApiHelper { } - def updateAccessControlRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAccessControlRuleAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAccessControlRuleAction() + def queryNativeCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNativeClusterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNativeClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33000,13 +32776,15 @@ abstract class ApiHelper { } - def updateAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAccountAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAccountAction() + def queryNativeHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNativeHostAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNativeHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33027,13 +32805,15 @@ abstract class ApiHelper { } - def updateAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAffinityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAffinityGroupAction() + def queryNetworkServiceL3NetworkRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNetworkServiceL3NetworkRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNetworkServiceL3NetworkRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33054,13 +32834,15 @@ abstract class ApiHelper { } - def updateAliyunDisk(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunDiskAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunDiskAction() + def queryNetworkServiceProvider(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNetworkServiceProviderAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNetworkServiceProviderAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33081,13 +32863,15 @@ abstract class ApiHelper { } - def updateAliyunEbsBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunEbsBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunEbsBackupStorageAction() + def queryNvmeLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNvmeLunAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNvmeLunAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33108,13 +32892,15 @@ abstract class ApiHelper { } - def updateAliyunEbsPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunEbsPrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunEbsPrimaryStorageAction() + def queryNvmeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNvmeServerAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNvmeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33135,13 +32921,15 @@ abstract class ApiHelper { } - def updateAliyunKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunKeySecretAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunKeySecretAction() + def queryNvmeTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryNvmeTargetAction.class) Closure c) { + def a = new org.zstack.sdk.QueryNvmeTargetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33162,13 +32950,15 @@ abstract class ApiHelper { } - def updateAliyunMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunMountTargetAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunMountTargetAction() + def queryOssBucketFileName(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryOssBucketFileNameAction.class) Closure c) { + def a = new org.zstack.sdk.QueryOssBucketFileNameAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33189,13 +32979,15 @@ abstract class ApiHelper { } - def updateAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunNasAccessGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunNasAccessGroupAction() + def queryPciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPciDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33216,13 +33008,15 @@ abstract class ApiHelper { } - def updateAliyunPanguPartition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunPanguPartitionAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunPanguPartitionAction() + def queryPciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDeviceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPciDeviceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33243,13 +33037,15 @@ abstract class ApiHelper { } - def updateAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunProxyVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunProxyVSwitchAction() + def queryPciDevicePciDeviceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDevicePciDeviceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPciDevicePciDeviceOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33270,13 +33066,15 @@ abstract class ApiHelper { } - def updateAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunProxyVpcAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunProxyVpcAction() + def queryPciDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPciDeviceSpecAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPciDeviceSpecAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33297,13 +33095,15 @@ abstract class ApiHelper { } - def updateAliyunRouteInterfaceRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunRouteInterfaceRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunRouteInterfaceRemoteAction() + def queryPhysicalDriveSelfTestHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPhysicalDriveSelfTestHistoryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPhysicalDriveSelfTestHistoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33324,13 +33124,15 @@ abstract class ApiHelper { } - def updateAliyunSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunSnapshotAction() + def queryPhysicalSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPhysicalSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPhysicalSwitchAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33351,13 +33153,15 @@ abstract class ApiHelper { } - def updateAliyunVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunVirtualRouterAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAliyunVirtualRouterAction() + def queryPluginDrivers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPluginDriversAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPluginDriversAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33378,13 +33182,15 @@ abstract class ApiHelper { } - def updateAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAppBuildSystemAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAppBuildSystemAction() + def queryPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33405,13 +33211,15 @@ abstract class ApiHelper { } - def updateAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAutoScalingGroupAction() + def queryPolicyRouteRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33432,13 +33240,15 @@ abstract class ApiHelper { } - def updateAutoScalingGroupAddingNewInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupAddingNewInstanceRuleAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAutoScalingGroupAddingNewInstanceRuleAction() + def queryPolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteRuleSetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33459,13 +33269,15 @@ abstract class ApiHelper { } - def updateAutoScalingGroupInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAutoScalingGroupInstanceAction() + def queryPolicyRouteRuleSetL3Ref(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleSetL3RefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteRuleSetL3RefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33486,13 +33298,15 @@ abstract class ApiHelper { } - def updateAutoScalingGroupRemovalInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupRemovalInstanceRuleAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAutoScalingGroupRemovalInstanceRuleAction() + def queryPolicyRouteRuleSetVRouterRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteRuleSetVRouterRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteRuleSetVRouterRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33513,13 +33327,15 @@ abstract class ApiHelper { } - def updateAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAutoScalingRuleAction() + def queryPolicyRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33540,13 +33356,15 @@ abstract class ApiHelper { } - def updateAutoScalingVmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingVmTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateAutoScalingVmTemplateAction() + def queryPolicyRouteTableRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteTableRouteEntryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteTableRouteEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33567,13 +33385,15 @@ abstract class ApiHelper { } - def updateBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBackupStorageAction() + def queryPolicyRouteTableVRouterRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPolicyRouteTableVRouterRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPolicyRouteTableVRouterRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33594,13 +33414,15 @@ abstract class ApiHelper { } - def updateBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ChassisAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBareMetal2ChassisAction() + def queryPortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortForwardingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPortForwardingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33621,13 +33443,15 @@ abstract class ApiHelper { } - def updateBareMetal2ChassisOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ChassisOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBareMetal2ChassisOfferingAction() + def queryPortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortMirrorAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPortMirrorAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33648,13 +33472,15 @@ abstract class ApiHelper { } - def updateBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2GatewayAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBareMetal2GatewayAction() + def queryPortMirrorNetworkUsedIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortMirrorNetworkUsedIpAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPortMirrorNetworkUsedIpAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33675,13 +33501,15 @@ abstract class ApiHelper { } - def updateBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2InstanceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBareMetal2InstanceAction() + def queryPortMirrorSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPortMirrorSessionAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPortMirrorSessionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33702,13 +33530,15 @@ abstract class ApiHelper { } - def updateBareMetal2IpmiChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2IpmiChassisAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBareMetal2IpmiChassisAction() + def queryPreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPreconfigurationTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPreconfigurationTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33729,13 +33559,15 @@ abstract class ApiHelper { } - def updateBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ProvisionNetworkAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBareMetal2ProvisionNetworkAction() + def queryPriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPriceTableAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPriceTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33756,13 +33588,15 @@ abstract class ApiHelper { } - def updateBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBaremetalChassisAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBaremetalChassisAction() + def queryPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33783,13 +33617,15 @@ abstract class ApiHelper { } - def updateBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBaremetalInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBaremetalInstanceAction() + def queryPublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryPublishAppAction.class) Closure c) { + def a = new org.zstack.sdk.QueryPublishAppAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33810,13 +33646,15 @@ abstract class ApiHelper { } - def updateBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBaremetalPxeServerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBaremetalPxeServerAction() + def queryQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryQuotaAction.class) Closure c) { + def a = new org.zstack.sdk.QueryQuotaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33837,13 +33675,15 @@ abstract class ApiHelper { } - def updateBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBuildAppAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateBuildAppAction() + def queryResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourceConfigAction.class) Closure c) { + def a = new org.zstack.sdk.QueryResourceConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33864,13 +33704,15 @@ abstract class ApiHelper { } - def updateCCSCertificateUserState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCCSCertificateUserStateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCCSCertificateUserStateAction() + def queryResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourcePriceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryResourcePriceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33891,13 +33733,15 @@ abstract class ApiHelper { } - def updateCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCdpPolicyAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCdpPolicyAction() + def queryResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.QueryResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33918,13 +33762,15 @@ abstract class ApiHelper { } - def updateCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCdpTaskAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCdpTaskAction() + def querySchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerJobAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySchedulerJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33945,13 +33791,15 @@ abstract class ApiHelper { } - def updateCephBackupStorageMon(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCephBackupStorageMonAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCephBackupStorageMonAction() + def querySchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerJobGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySchedulerJobGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33972,13 +33820,15 @@ abstract class ApiHelper { } - def updateCephPrimaryStorageMon(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCephPrimaryStorageMonAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCephPrimaryStorageMonAction() + def querySchedulerJobHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerJobHistoryAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySchedulerJobHistoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -33999,13 +33849,15 @@ abstract class ApiHelper { } - def updateCephPrimaryStoragePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCephPrimaryStoragePoolAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCephPrimaryStoragePoolAction() + def querySchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34026,13 +33878,15 @@ abstract class ApiHelper { } - def updateCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCertificateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateCertificateAction() + def queryScsiLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryScsiLunAction.class) Closure c) { + def a = new org.zstack.sdk.QueryScsiLunAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34053,13 +33907,15 @@ abstract class ApiHelper { } - def updateCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateClusterAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateClusterAction() + def querySdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySdnControllerAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySdnControllerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34080,13 +33936,15 @@ abstract class ApiHelper { } - def updateClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateClusterDRSAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateClusterDRSAction() + def querySecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySecretResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34107,13 +33965,15 @@ abstract class ApiHelper { } - def updateClusterOS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateClusterOSAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateClusterOSAction() + def querySecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34134,13 +33994,15 @@ abstract class ApiHelper { } - def updateConnectionBetweenL3NetWorkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateConnectionBetweenL3NetWorkAndAliyunVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateConnectionBetweenL3NetWorkAndAliyunVSwitchAction() + def querySecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecurityGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySecurityGroupRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34161,13 +34023,15 @@ abstract class ApiHelper { } - def updateConsoleProxyAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateConsoleProxyAgentAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateConsoleProxyAgentAction() + def querySecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySecurityMachineAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34188,13 +34052,15 @@ abstract class ApiHelper { } - def updateDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateDiskOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateDiskOfferingAction() + def querySftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySftpBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySftpBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34215,13 +34081,15 @@ abstract class ApiHelper { } - def updateEcsImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsImageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEcsImageAction() + def queryShareableVolumeVmInstanceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryShareableVolumeVmInstanceRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryShareableVolumeVmInstanceRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34242,13 +34110,15 @@ abstract class ApiHelper { } - def updateEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEcsInstanceAction() + def querySharedBlock(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedBlockAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySharedBlockAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34269,13 +34139,15 @@ abstract class ApiHelper { } - def updateEcsInstanceVncPassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsInstanceVncPasswordAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEcsInstanceVncPasswordAction() + def querySharedBlockGroupPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34296,13 +34168,15 @@ abstract class ApiHelper { } - def updateEcsSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEcsSecurityGroupAction() + def querySharedBlockGroupPrimaryStorageHostRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageHostRefAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySharedBlockGroupPrimaryStorageHostRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34323,13 +34197,15 @@ abstract class ApiHelper { } - def updateEcsVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsVSwitchAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEcsVSwitchAction() + def querySharedResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySharedResourceAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySharedResourceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34350,13 +34226,15 @@ abstract class ApiHelper { } - def updateEcsVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsVpcAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEcsVpcAction() + def querySlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySlbGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySlbGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34377,13 +34255,15 @@ abstract class ApiHelper { } - def updateEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEipAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEipAction() + def querySlbOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySlbOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySlbOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34404,13 +34284,44 @@ abstract class ApiHelper { } - def updateEmailMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEmailMediaAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEmailMediaAction() + def querySlbVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySlbVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySlbVmInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def querySnmpAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySnmpAgentAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySnmpAgentAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34431,13 +34342,15 @@ abstract class ApiHelper { } - def updateEmailMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEmailMonitorTriggerActionAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateEmailMonitorTriggerActionAction() + def querySshKeyPair(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySshKeyPairAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySshKeyPairAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34458,13 +34371,15 @@ abstract class ApiHelper { } - def updateFactoryModeState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFactoryModeStateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFactoryModeStateAction() + def queryStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryStackTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryStackTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34485,13 +34400,15 @@ abstract class ApiHelper { } - def updateFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallIpSetTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFirewallIpSetTemplateAction() + def querySystemTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QuerySystemTagAction.class) Closure c) { + def a = new org.zstack.sdk.QuerySystemTagAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34512,13 +34429,15 @@ abstract class ApiHelper { } - def updateFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallRuleAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFirewallRuleAction() + def queryTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTagAction.class) Closure c) { + def a = new org.zstack.sdk.QueryTagAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34539,13 +34458,15 @@ abstract class ApiHelper { } - def updateFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFirewallRuleSetAction() + def queryTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTemplateConfigAction.class) Closure c) { + def a = new org.zstack.sdk.QueryTemplateConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34566,13 +34487,15 @@ abstract class ApiHelper { } - def updateFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallRuleTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFirewallRuleTemplateAction() + def queryTrainedModelRecord(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTrainedModelRecordAction.class) Closure c) { + def a = new org.zstack.sdk.QueryTrainedModelRecordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34593,13 +34516,15 @@ abstract class ApiHelper { } - def updateFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFlowCollectorAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFlowCollectorAction() + def queryTwoFactorAuthentication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryTwoFactorAuthenticationAction.class) Closure c) { + def a = new org.zstack.sdk.QueryTwoFactorAuthenticationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34620,13 +34545,15 @@ abstract class ApiHelper { } - def updateFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFlowMeterAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateFlowMeterAction() + def queryUsbDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUsbDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryUsbDeviceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34647,13 +34574,15 @@ abstract class ApiHelper { } - def updateGlobalConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateGlobalConfigAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateGlobalConfigAction() + def queryUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserAction.class) Closure c) { + def a = new org.zstack.sdk.QueryUserAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34674,13 +34603,15 @@ abstract class ApiHelper { } - def updateHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateHostAction() + def queryUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryUserGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34701,13 +34632,15 @@ abstract class ApiHelper { } - def updateHostIommuState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostIommuStateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateHostIommuStateAction() + def queryUserProxyConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserProxyConfigAction.class) Closure c) { + def a = new org.zstack.sdk.QueryUserProxyConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34728,13 +34661,15 @@ abstract class ApiHelper { } - def updateHybridEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHybridEipAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateHybridEipAction() + def queryUserTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryUserTagAction.class) Closure c) { + def a = new org.zstack.sdk.QueryUserTagAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34755,13 +34690,44 @@ abstract class ApiHelper { } - def updateHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHybridKeySecretAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateHybridKeySecretAction() + def queryV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryV2VConversionHostAction.class) Closure c) { + def a = new org.zstack.sdk.QueryV2VConversionHostAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVCenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34782,40 +34748,15 @@ abstract class ApiHelper { } - def updateIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateIPsecConnectionAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateIPsecConnectionAction() + def queryVCenterBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVCenterBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def updateImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateImageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateImageAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34836,40 +34777,15 @@ abstract class ApiHelper { } - def updateImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateImageStoreBackupStorageAction() + def queryVCenterCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterClusterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVCenterClusterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def updateInfoSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateInfoSecSecretResourcePoolAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateInfoSecSecretResourcePoolAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34890,13 +34806,15 @@ abstract class ApiHelper { } - def updateInfoSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateInfoSecSecurityMachineAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateInfoSecSecurityMachineAction() + def queryVCenterDatacenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterDatacenterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVCenterDatacenterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34917,13 +34835,15 @@ abstract class ApiHelper { } - def updateInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateInstanceOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateInstanceOfferingAction() + def queryVCenterPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVCenterPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34944,13 +34864,15 @@ abstract class ApiHelper { } - def updateIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateIpRangeAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateIpRangeAction() + def queryVCenterResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVCenterResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVCenterResourcePoolAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34971,13 +34893,15 @@ abstract class ApiHelper { } - def updateIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateIscsiServerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateIscsiServerAction() + def queryVRouterFlowMeterNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterFlowMeterNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVRouterFlowMeterNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -34998,13 +34922,15 @@ abstract class ApiHelper { } - def updateKVMHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateKVMHostAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateKVMHostAction() + def queryVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterOspfAreaAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVRouterOspfAreaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35025,13 +34951,15 @@ abstract class ApiHelper { } - def updateL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateL2NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateL2NetworkAction() + def queryVRouterOspfNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterOspfNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVRouterOspfNetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35052,13 +34980,15 @@ abstract class ApiHelper { } - def updateL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateL3NetworkAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateL3NetworkAction() + def queryVRouterRouteEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterRouteEntryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVRouterRouteEntryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35079,13 +35009,15 @@ abstract class ApiHelper { } - def updateLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLdapServerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLdapServerAction() + def queryVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVRouterRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVRouterRouteTableAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35106,13 +35038,15 @@ abstract class ApiHelper { } - def updateLicense(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLicenseAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLicenseAction() + def queryVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVipAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVipAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35133,13 +35067,15 @@ abstract class ApiHelper { } - def updateLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLoadBalancerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLoadBalancerAction() + def queryVirtualBorderRouterFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualBorderRouterFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVirtualBorderRouterFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35160,13 +35096,15 @@ abstract class ApiHelper { } - def updateLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLoadBalancerListenerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLoadBalancerListenerAction() + def queryVirtualRouterOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualRouterOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVirtualRouterOfferingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35187,13 +35125,15 @@ abstract class ApiHelper { } - def updateLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLoadBalancerServerGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLoadBalancerServerGroupAction() + def queryVirtualRouterVRouterRouteTableRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualRouterVRouterRouteTableRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVirtualRouterVRouterRouteTableRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35214,13 +35154,15 @@ abstract class ApiHelper { } - def updateLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLogConfigurationAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLogConfigurationAction() + def queryVirtualRouterVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVirtualRouterVmAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVirtualRouterVmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35241,13 +35183,15 @@ abstract class ApiHelper { } - def updateLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLongJobAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateLongJobAction() + def queryVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmCdRomAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmCdRomAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35268,13 +35212,15 @@ abstract class ApiHelper { } - def updateMdevDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateMdevDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateMdevDeviceAction() + def queryVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35295,13 +35241,15 @@ abstract class ApiHelper { } - def updateMdevDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateMdevDeviceSpecAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateMdevDeviceSpecAction() + def queryVmInstanceDeviceAddressArchive(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstanceDeviceAddressArchiveAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmInstanceDeviceAddressArchiveAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35322,13 +35270,15 @@ abstract class ApiHelper { } - def updateMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateMonitorTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateMonitorTriggerAction() + def queryVmInstanceDeviceAddressGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstanceDeviceAddressGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmInstanceDeviceAddressGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35349,13 +35299,15 @@ abstract class ApiHelper { } - def updateNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateNasFileSystemAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateNasFileSystemAction() + def queryVmInstanceMdevDeviceSpecRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstanceMdevDeviceSpecRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmInstanceMdevDeviceSpecRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35376,13 +35328,15 @@ abstract class ApiHelper { } - def updateNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateNasMountTargetAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateNasMountTargetAction() + def queryVmInstancePciDeviceSpecRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmInstancePciDeviceSpecRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmInstancePciDeviceSpecRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35403,13 +35357,15 @@ abstract class ApiHelper { } - def updateOssBucket(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateOssBucketAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateOssBucketAction() + def queryVmNic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmNicAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmNicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35430,13 +35386,15 @@ abstract class ApiHelper { } - def updatePciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePciDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePciDeviceAction() + def queryVmNicInSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmNicInSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmNicInSecurityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35457,13 +35415,15 @@ abstract class ApiHelper { } - def updatePciDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePciDeviceSpecAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePciDeviceSpecAction() + def queryVmNicSecurityPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmNicSecurityPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmNicSecurityPolicyAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35484,13 +35444,15 @@ abstract class ApiHelper { } - def updatePolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePolicyRouteRuleSetAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePolicyRouteRuleSetAction() + def queryVmPriorityConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmPriorityConfigAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmPriorityConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35511,13 +35473,15 @@ abstract class ApiHelper { } - def updatePortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePortForwardingRuleAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePortForwardingRuleAction() + def queryVmSchedHistory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmSchedHistoryAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmSchedHistoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35538,13 +35502,15 @@ abstract class ApiHelper { } - def updatePortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePortMirrorAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePortMirrorAction() + def queryVmSchedulingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmSchedulingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmSchedulingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35565,13 +35531,15 @@ abstract class ApiHelper { } - def updatePreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePreconfigurationTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePreconfigurationTemplateAction() + def queryVmSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmSchedulingRuleGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35592,13 +35560,15 @@ abstract class ApiHelper { } - def updatePriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePriceTableAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePriceTableAction() + def queryVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVmUserDefinedXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVmUserDefinedXmlHookScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35619,13 +35589,15 @@ abstract class ApiHelper { } - def updatePrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePrimaryStorageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePrimaryStorageAction() + def queryVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVniRangeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVniRangeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35646,13 +35618,15 @@ abstract class ApiHelper { } - def updatePriorityConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePriorityConfigAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePriorityConfigAction() + def queryVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35673,13 +35647,15 @@ abstract class ApiHelper { } - def updatePublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePublishAppAction.class) Closure c) { - def a = new org.zstack.sdk.UpdatePublishAppAction() + def queryVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVolumeSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35700,13 +35676,15 @@ abstract class ApiHelper { } - def updateQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateQuotaAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateQuotaAction() + def queryVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVolumeSnapshotGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35727,13 +35705,15 @@ abstract class ApiHelper { } - def updateResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourceConfigAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateResourceConfigAction() + def queryVolumeSnapshotTree(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVolumeSnapshotTreeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVolumeSnapshotTreeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35754,13 +35734,15 @@ abstract class ApiHelper { } - def updateResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourcePriceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateResourcePriceAction() + def queryVpcFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcFirewallAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcFirewallAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35781,13 +35763,15 @@ abstract class ApiHelper { } - def updateResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourceStackAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateResourceStackAction() + def queryVpcFirewallVRouterRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcFirewallVRouterRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcFirewallVRouterRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35808,13 +35792,15 @@ abstract class ApiHelper { } - def updateSchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSchedulerJobAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSchedulerJobAction() + def queryVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcHaGroupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcHaGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35835,13 +35821,15 @@ abstract class ApiHelper { } - def updateSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSchedulerJobGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSchedulerJobGroupAction() + def queryVpcHaGroupNetworkServiceRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcHaGroupNetworkServiceRefAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcHaGroupNetworkServiceRefAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35862,13 +35850,15 @@ abstract class ApiHelper { } - def updateSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSchedulerTriggerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSchedulerTriggerAction() + def queryVpcIkeConfigFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcIkeConfigFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcIkeConfigFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35889,13 +35879,15 @@ abstract class ApiHelper { } - def updateScsiLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateScsiLunAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateScsiLunAction() + def queryVpcIpSecConfigFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcIpSecConfigFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcIpSecConfigFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35916,13 +35908,15 @@ abstract class ApiHelper { } - def updateSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSdnControllerAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSdnControllerAction() + def queryVpcRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcRouterAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35943,13 +35937,15 @@ abstract class ApiHelper { } - def updateSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecretResourcePoolAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSecretResourcePoolAction() + def queryVpcSharedQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcSharedQosAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcSharedQosAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35970,13 +35966,15 @@ abstract class ApiHelper { } - def updateSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecurityGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSecurityGroupAction() + def queryVpcSnatState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcSnatStateAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcSnatStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -35997,13 +35995,15 @@ abstract class ApiHelper { } - def updateSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecurityMachineAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSecurityMachineAction() + def queryVpcUserVpnGatewayFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcUserVpnGatewayFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcUserVpnGatewayFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36024,13 +36024,15 @@ abstract class ApiHelper { } - def updateSftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSftpBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSftpBackupStorageAction() + def queryVpcVpnConnectionFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcVpnConnectionFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcVpnConnectionFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36051,13 +36053,15 @@ abstract class ApiHelper { } - def updateSharedBlock(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSharedBlockAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSharedBlockAction() + def queryVpcVpnGatewayFromLocal(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVpcVpnGatewayFromLocalAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVpcVpnGatewayFromLocalAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36078,13 +36082,15 @@ abstract class ApiHelper { } - def updateSlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSlbGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSlbGroupAction() + def queryVtep(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryVtepAction.class) Closure c) { + def a = new org.zstack.sdk.QueryVtepAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36105,13 +36111,15 @@ abstract class ApiHelper { } - def updateStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateStackTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateStackTemplateAction() + def queryWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryWebhookAction.class) Closure c) { + def a = new org.zstack.sdk.QueryWebhookAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36132,13 +36140,15 @@ abstract class ApiHelper { } - def updateSystemTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSystemTagAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateSystemTagAction() + def queryXskyBlockVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryXskyBlockVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.QueryXskyBlockVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36159,13 +36169,15 @@ abstract class ApiHelper { } - def updateTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateTagAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateTagAction() + def queryZBox(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZBoxAction.class) Closure c) { + def a = new org.zstack.sdk.QueryZBoxAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36186,13 +36198,15 @@ abstract class ApiHelper { } - def updateTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateTemplateConfigAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateTemplateConfigAction() + def queryZBoxBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZBoxBackupAction.class) Closure c) { + def a = new org.zstack.sdk.QueryZBoxBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36213,13 +36227,15 @@ abstract class ApiHelper { } - def updateUsbDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUsbDeviceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateUsbDeviceAction() + def queryZdfs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZdfsAction.class) Closure c) { + def a = new org.zstack.sdk.QueryZdfsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36240,13 +36256,15 @@ abstract class ApiHelper { } - def updateUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUserAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateUserAction() + def queryZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.QueryZoneAction.class) Closure c) { + def a = new org.zstack.sdk.QueryZoneAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -36267,8 +36285,8 @@ abstract class ApiHelper { } - def updateUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUserGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateUserGroupAction() + def rebootBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RebootBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RebootBaremetalInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36294,8 +36312,8 @@ abstract class ApiHelper { } - def updateV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateV2VConversionHostAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateV2VConversionHostAction() + def rebootEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RebootEcsInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RebootEcsInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36321,8 +36339,8 @@ abstract class ApiHelper { } - def updateVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVCenterAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVCenterAction() + def rebootVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RebootVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RebootVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36348,8 +36366,8 @@ abstract class ApiHelper { } - def updateVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVRouterOspfAreaAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVRouterOspfAreaAction() + def reclaimSpaceFromImageStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReclaimSpaceFromImageStoreAction.class) Closure c) { + def a = new org.zstack.sdk.ReclaimSpaceFromImageStoreAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36375,8 +36393,8 @@ abstract class ApiHelper { } - def updateVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVRouterRouteTableAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVRouterRouteTableAction() + def reconnectAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectAppBuildSystemAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectAppBuildSystemAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36402,8 +36420,8 @@ abstract class ApiHelper { } - def updateVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVipAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVipAction() + def reconnectBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36429,8 +36447,8 @@ abstract class ApiHelper { } - def updateVirtualBorderRouterRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualBorderRouterRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVirtualBorderRouterRemoteAction() + def reconnectBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBareMetal2GatewayAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectBareMetal2GatewayAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36456,8 +36474,8 @@ abstract class ApiHelper { } - def updateVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualRouterAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVirtualRouterAction() + def reconnectBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBareMetal2InstanceAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectBareMetal2InstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36483,8 +36501,8 @@ abstract class ApiHelper { } - def updateVirtualRouterOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualRouterOfferingAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVirtualRouterOfferingAction() + def reconnectBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectBaremetalPxeServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36510,8 +36528,8 @@ abstract class ApiHelper { } - def updateVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmCdRomAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVmCdRomAction() + def reconnectConsoleProxyAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectConsoleProxyAgentAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectConsoleProxyAgentAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36537,8 +36555,8 @@ abstract class ApiHelper { } - def updateVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmInstanceAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVmInstanceAction() + def reconnectHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectHostAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36564,8 +36582,8 @@ abstract class ApiHelper { } - def updateVmNicDriver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmNicDriverAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVmNicDriverAction() + def reconnectIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36591,8 +36609,8 @@ abstract class ApiHelper { } - def updateVmNicMac(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmNicMacAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVmNicMacAction() + def reconnectImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectImageStoreBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36618,8 +36636,8 @@ abstract class ApiHelper { } - def updateVmPriority(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmPriorityAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVmPriorityAction() + def reconnectPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36645,8 +36663,8 @@ abstract class ApiHelper { } - def updateVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVniRangeAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVniRangeAction() + def reconnectSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectSdnControllerAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectSdnControllerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36672,8 +36690,8 @@ abstract class ApiHelper { } - def updateVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVolumeAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVolumeAction() + def reconnectSftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectSftpBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectSftpBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36699,8 +36717,8 @@ abstract class ApiHelper { } - def updateVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVolumeSnapshotAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVolumeSnapshotAction() + def reconnectVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectVirtualRouterAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectVirtualRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36726,8 +36744,8 @@ abstract class ApiHelper { } - def updateVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVolumeSnapshotGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVolumeSnapshotGroupAction() + def reconnectZdfs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReconnectZdfsAction.class) Closure c) { + def a = new org.zstack.sdk.ReconnectZdfsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36753,8 +36771,8 @@ abstract class ApiHelper { } - def updateVpcFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcFirewallAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVpcFirewallAction() + def recoverBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RecoverBaremetalInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36780,8 +36798,8 @@ abstract class ApiHelper { } - def updateVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcHaGroupAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVpcHaGroupAction() + def recoverDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverDataVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.RecoverDataVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36807,8 +36825,8 @@ abstract class ApiHelper { } - def updateVpcUserVpnGateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcUserVpnGatewayAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVpcUserVpnGatewayAction() + def recoverImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverImageAction.class) Closure c) { + def a = new org.zstack.sdk.RecoverImageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36834,8 +36852,8 @@ abstract class ApiHelper { } - def updateVpcVpnConnectionRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcVpnConnectionRemoteAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVpcVpnConnectionRemoteAction() + def recoverResourceSplitBrain(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverResourceSplitBrainAction.class) Closure c) { + def a = new org.zstack.sdk.RecoverResourceSplitBrainAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36861,8 +36879,8 @@ abstract class ApiHelper { } - def updateVpcVpnGateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcVpnGatewayAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateVpcVpnGatewayAction() + def recoverVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoverVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RecoverVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36888,8 +36906,89 @@ abstract class ApiHelper { } - def updateWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateWebhookAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateWebhookAction() + def recoveryImageFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoveryImageFromImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.RecoveryImageFromImageStoreBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def recoveryVirtualBorderRouterRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RecoveryVirtualBorderRouterRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.RecoveryVirtualBorderRouterRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def refreshCaptcha(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshCaptchaAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshCaptchaAction() + + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def refreshFiberChannelStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshFiberChannelStorageAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshFiberChannelStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36915,8 +37014,8 @@ abstract class ApiHelper { } - def updateZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateZoneAction.class) Closure c) { - def a = new org.zstack.sdk.UpdateZoneAction() + def refreshFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshFirewallAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshFirewallAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36942,8 +37041,8 @@ abstract class ApiHelper { } - def validateClusterSupportDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateClusterSupportDRSAction.class) Closure c) { - def a = new org.zstack.sdk.ValidateClusterSupportDRSAction() + def refreshGuestOsMetadata(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshGuestOsMetadataAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshGuestOsMetadataAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36969,8 +37068,8 @@ abstract class ApiHelper { } - def validateDiskOfferingUserConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateDiskOfferingUserConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ValidateDiskOfferingUserConfigAction() + def refreshIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshIscsiServerAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshIscsiServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -36996,8 +37095,8 @@ abstract class ApiHelper { } - def validateInstanceOfferingUserConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateInstanceOfferingUserConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ValidateInstanceOfferingUserConfigAction() + def refreshLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37023,9 +37122,9 @@ abstract class ApiHelper { } - def validatePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidatePasswordAction.class) Closure c) { - def a = new org.zstack.sdk.ValidatePasswordAction() - + def refreshLocalRaid(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshLocalRaidAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshLocalRaidAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -37050,8 +37149,8 @@ abstract class ApiHelper { } - def validatePriceUserConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidatePriceUserConfigAction.class) Closure c) { - def a = new org.zstack.sdk.ValidatePriceUserConfigAction() + def refreshNvmeTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshNvmeTargetAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshNvmeTargetAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37077,9 +37176,9 @@ abstract class ApiHelper { } - def validateSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateSessionAction.class) Closure c) { - def a = new org.zstack.sdk.ValidateSessionAction() - + def refreshPluginDrivers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshPluginDriversAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshPluginDriversAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() @@ -37104,8 +37203,8 @@ abstract class ApiHelper { } - def validateVolumeSnapshotChain(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateVolumeSnapshotChainAction.class) Closure c) { - def a = new org.zstack.sdk.ValidateVolumeSnapshotChainAction() + def refreshSSOServerToken(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshSSOServerTokenAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshSSOServerTokenAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37131,8 +37230,8 @@ abstract class ApiHelper { } - def zQLQuery(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ZQLQueryAction.class) Closure c) { - def a = new org.zstack.sdk.ZQLQueryAction() + def refreshSearchIndexes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshSearchIndexesAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshSearchIndexesAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37158,8 +37257,8 @@ abstract class ApiHelper { } - def createDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.CreateDatabaseBackupAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.CreateDatabaseBackupAction() + def refreshSharedblockDeviceCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RefreshSharedblockDeviceCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.RefreshSharedblockDeviceCapacityAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37185,8 +37284,8 @@ abstract class ApiHelper { } - def deleteDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.DeleteDatabaseBackupAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.DeleteDatabaseBackupAction() + def registerLicenseRequestedApplication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RegisterLicenseRequestedApplicationAction.class) Closure c) { + def a = new org.zstack.sdk.RegisterLicenseRequestedApplicationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37212,8 +37311,8 @@ abstract class ApiHelper { } - def deleteExportedDatabaseBackupFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.DeleteExportedDatabaseBackupFromBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.DeleteExportedDatabaseBackupFromBackupStorageAction() + def reimageVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReimageVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.ReimageVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37239,8 +37338,8 @@ abstract class ApiHelper { } - def exportDatabaseBackupFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.ExportDatabaseBackupFromBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.ExportDatabaseBackupFromBackupStorageAction() + def reloadElaboration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReloadElaborationAction.class) Closure c) { + def a = new org.zstack.sdk.ReloadElaborationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37266,8 +37365,8 @@ abstract class ApiHelper { } - def getDatabaseBackupFromImageStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.GetDatabaseBackupFromImageStoreAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.GetDatabaseBackupFromImageStoreAction() + def reloadExternalService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReloadExternalServiceAction.class) Closure c) { + def a = new org.zstack.sdk.ReloadExternalServiceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37293,15 +37392,40 @@ abstract class ApiHelper { } - def queryDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.QueryDatabaseBackupAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.QueryDatabaseBackupAction() + def reloadLicense(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ReloadLicenseAction.class) Closure c) { + def a = new org.zstack.sdk.ReloadLicenseAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeAccessControlListEntry(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveAccessControlListEntryAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveAccessControlListEntryAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -37322,8 +37446,8 @@ abstract class ApiHelper { } - def recoverDatabaseFromBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.RecoverDatabaseFromBackupAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.RecoverDatabaseFromBackupAction() + def removeAccessControlListFromLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveAccessControlListFromLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveAccessControlListFromLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37349,8 +37473,8 @@ abstract class ApiHelper { } - def syncDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.SyncDatabaseBackupAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.SyncDatabaseBackupAction() + def removeBackendServerFromServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveBackendServerFromServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveBackendServerFromServerGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37376,8 +37500,8 @@ abstract class ApiHelper { } - def syncDatabaseBackupFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.SyncDatabaseBackupFromImageStoreBackupStorageAction.class) Closure c) { - def a = new org.zstack.sdk.databasebackup.SyncDatabaseBackupFromImageStoreBackupStorageAction() + def removeCertificateFromLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveCertificateFromLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveCertificateFromLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37403,8 +37527,8 @@ abstract class ApiHelper { } - def addAttributesToIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2OrganizationAction() + def removeDnsFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveDnsFromL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveDnsFromL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37430,8 +37554,8 @@ abstract class ApiHelper { } - def addAttributesToIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2ProjectAction() + def removeDnsFromVpcRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveDnsFromVpcRouterAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveDnsFromVpcRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37457,8 +37581,8 @@ abstract class ApiHelper { } - def addAttributesToIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDAction() + def removeHostRouteFromL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveHostRouteFromL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveHostRouteFromL3NetworkAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37484,8 +37608,8 @@ abstract class ApiHelper { } - def addAttributesToIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDGroupAction() + def removeMdevDeviceSpecFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveMdevDeviceSpecFromVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveMdevDeviceSpecFromVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37511,8 +37635,8 @@ abstract class ApiHelper { } - def addIAM2VirtualIDGroupToProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDGroupToProjectsAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDGroupToProjectsAction() + def removeMonFromCephBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveMonFromCephBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveMonFromCephBackupStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37538,8 +37662,8 @@ abstract class ApiHelper { } - def addIAM2VirtualIDsToGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToGroupAction() + def removeMonFromCephPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveMonFromCephPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveMonFromCephPrimaryStorageAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37565,8 +37689,8 @@ abstract class ApiHelper { } - def addIAM2VirtualIDsToOrganization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToOrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToOrganizationAction() + def removePciDeviceSpecFromVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemovePciDeviceSpecFromVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.RemovePciDeviceSpecFromVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37592,8 +37716,8 @@ abstract class ApiHelper { } - def addIAM2VirtualIDsToProject(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectAction() + def removeRemoteCidrsFromIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveRemoteCidrsFromIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveRemoteCidrsFromIPsecConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37619,8 +37743,8 @@ abstract class ApiHelper { } - def addIAM2VirtualIDsToProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectsAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectsAction() + def removeRendezvousPointFromMulticastRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveRendezvousPointFromMulticastRouterAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveRendezvousPointFromMulticastRouterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37646,8 +37770,8 @@ abstract class ApiHelper { } - def addResourceToIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddResourceToIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddResourceToIAM2ProjectAction() + def removeResourcesFromDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveResourcesFromDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveResourcesFromDirectoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37673,8 +37797,8 @@ abstract class ApiHelper { } - def addRolesToIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDAction() + def removeSchedulerJobFromSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSchedulerJobFromSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveSchedulerJobFromSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37700,8 +37824,8 @@ abstract class ApiHelper { } - def addRolesToIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDGroupAction() + def removeSchedulerJobGroupFromSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSchedulerJobGroupFromSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveSchedulerJobGroupFromSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37727,8 +37851,8 @@ abstract class ApiHelper { } - def attachIAM2ProjectToIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AttachIAM2ProjectToIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.AttachIAM2ProjectToIAM2OrganizationAction() + def removeSchedulerJobsFromSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSchedulerJobsFromSchedulerJobGroupAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveSchedulerJobsFromSchedulerJobGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37754,8 +37878,8 @@ abstract class ApiHelper { } - def batchCreateIAM2VirtualIDFromConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.BatchCreateIAM2VirtualIDFromConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.BatchCreateIAM2VirtualIDFromConfigFileAction() + def removeSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveSdnControllerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveSdnControllerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37781,8 +37905,8 @@ abstract class ApiHelper { } - def changeIAM2OrganizationParent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2OrganizationParentAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ChangeIAM2OrganizationParentAction() + def removeServerGroupFromLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveServerGroupFromLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveServerGroupFromLoadBalancerListenerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37808,8 +37932,8 @@ abstract class ApiHelper { } - def changeIAM2OrganizationState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2OrganizationStateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ChangeIAM2OrganizationStateAction() + def removeUserFromGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveUserFromGroupAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveUserFromGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37835,8 +37959,8 @@ abstract class ApiHelper { } - def changeIAM2ProjectState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2ProjectStateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ChangeIAM2ProjectStateAction() + def removeVRouterNetworksFromFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVRouterNetworksFromFlowMeterAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveVRouterNetworksFromFlowMeterAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37862,8 +37986,8 @@ abstract class ApiHelper { } - def changeIAM2VirtualIDGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDGroupStateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDGroupStateAction() + def removeVRouterNetworksFromOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVRouterNetworksFromOspfAreaAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveVRouterNetworksFromOspfAreaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37889,8 +38013,8 @@ abstract class ApiHelper { } - def changeIAM2VirtualIDState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDStateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDStateAction() + def removeVmFromAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVmFromAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveVmFromAffinityGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37916,8 +38040,8 @@ abstract class ApiHelper { } - def changeIAM2VirtualIDType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDTypeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDTypeAction() + def removeVmNicFromLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVmNicFromLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveVmNicFromLoadBalancerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37943,8 +38067,8 @@ abstract class ApiHelper { } - def checkIAM2OrganizationAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CheckIAM2OrganizationAvailabilityAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CheckIAM2OrganizationAvailabilityAction() + def removeVmSchedulingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RemoveVmSchedulingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.RemoveVmSchedulingRuleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37970,8 +38094,8 @@ abstract class ApiHelper { } - def checkIAM2VirtualIDConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CheckIAM2VirtualIDConfigFileAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CheckIAM2VirtualIDConfigFileAction() + def renewSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RenewSessionAction.class) Closure c) { + def a = new org.zstack.sdk.RenewSessionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -37997,8 +38121,8 @@ abstract class ApiHelper { } - def createIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2OrganizationAction() + def requestConsoleAccess(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RequestConsoleAccessAction.class) Closure c) { + def a = new org.zstack.sdk.RequestConsoleAccessAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38024,8 +38148,8 @@ abstract class ApiHelper { } - def createIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectAction() + def rerunLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RerunLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.RerunLongJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38051,8 +38175,8 @@ abstract class ApiHelper { } - def createIAM2ProjectFromTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectFromTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectFromTemplateAction() + def resetGlobalConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResetGlobalConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ResetGlobalConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38078,8 +38202,8 @@ abstract class ApiHelper { } - def createIAM2ProjectRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectRoleAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectRoleAction() + def resetTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResetTemplateConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ResetTemplateConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38105,8 +38229,8 @@ abstract class ApiHelper { } - def createIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateAction() + def resetTwoFactorAuthenticationSecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResetTwoFactorAuthenticationSecretAction.class) Closure c) { + def a = new org.zstack.sdk.ResetTwoFactorAuthenticationSecretAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38132,8 +38256,8 @@ abstract class ApiHelper { } - def createIAM2ProjectTemplateFromProject(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateFromProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateFromProjectAction() + def resizeDataVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResizeDataVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.ResizeDataVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38159,8 +38283,8 @@ abstract class ApiHelper { } - def createIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2VirtualIDAction() + def resizeRootVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResizeRootVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.ResizeRootVolumeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38186,8 +38310,8 @@ abstract class ApiHelper { } - def createIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.CreateIAM2VirtualIDGroupAction() + def restartModelServiceGroups(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RestartModelServiceGroupsAction.class) Closure c) { + def a = new org.zstack.sdk.RestartModelServiceGroupsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38213,8 +38337,8 @@ abstract class ApiHelper { } - def deleteIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.DeleteIAM2OrganizationAction() + def restartResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RestartResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.RestartResourceStackAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38240,8 +38364,8 @@ abstract class ApiHelper { } - def deleteIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.DeleteIAM2ProjectAction() + def resumeLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResumeLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.ResumeLongJobAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38267,8 +38391,8 @@ abstract class ApiHelper { } - def deleteIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2ProjectTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.DeleteIAM2ProjectTemplateAction() + def resumeVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ResumeVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.ResumeVmInstanceAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38294,8 +38418,8 @@ abstract class ApiHelper { } - def deleteIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDAction() + def revertTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertTemplateConfigAction.class) Closure c) { + def a = new org.zstack.sdk.RevertTemplateConfigAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38321,8 +38445,8 @@ abstract class ApiHelper { } - def deleteIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDGroupAction() + def revertVmFromCdpBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertVmFromCdpBackupAction.class) Closure c) { + def a = new org.zstack.sdk.RevertVmFromCdpBackupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38348,8 +38472,8 @@ abstract class ApiHelper { } - def detachIAM2ProjectFromIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DetachIAM2ProjectFromIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.DetachIAM2ProjectFromIAM2OrganizationAction() + def revertVmFromSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertVmFromSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.RevertVmFromSnapshotGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38375,8 +38499,8 @@ abstract class ApiHelper { } - def expungeIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ExpungeIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.ExpungeIAM2ProjectAction() + def revertVolumeFromSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevertVolumeFromSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.RevertVolumeFromSnapshotAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38402,8 +38526,8 @@ abstract class ApiHelper { } - def getIAM2OrganizationVirtualIDNumber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2OrganizationVirtualIDNumberAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.GetIAM2OrganizationVirtualIDNumberAction() + def revokeResourceSharing(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RevokeResourceSharingAction.class) Closure c) { + def a = new org.zstack.sdk.RevokeResourceSharingAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38429,8 +38553,8 @@ abstract class ApiHelper { } - def getIAM2ProjectsOfVirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2ProjectsOfVirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.GetIAM2ProjectsOfVirtualIDAction() + def runIAM2Script(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RunIAM2ScriptAction.class) Closure c) { + def a = new org.zstack.sdk.RunIAM2ScriptAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38456,8 +38580,8 @@ abstract class ApiHelper { } - def getIAM2SystemAttributes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2SystemAttributesAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.GetIAM2SystemAttributesAction() + def runSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.RunSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.RunSchedulerTriggerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38483,8 +38607,8 @@ abstract class ApiHelper { } - def getIAM2VirtualIDAPIPermission(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2VirtualIDAPIPermissionAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.GetIAM2VirtualIDAPIPermissionAction() + def sdnControllerAddHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SdnControllerAddHostAction.class) Closure c) { + def a = new org.zstack.sdk.SdnControllerAddHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38510,8 +38634,8 @@ abstract class ApiHelper { } - def getIAM2VirtualIDInGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2VirtualIDInGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.GetIAM2VirtualIDInGroupAction() + def sdnControllerChangeHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SdnControllerChangeHostAction.class) Closure c) { + def a = new org.zstack.sdk.SdnControllerChangeHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38537,8 +38661,8 @@ abstract class ApiHelper { } - def getOrganizationQuotaUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetOrganizationQuotaUsageAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.GetOrganizationQuotaUsageAction() + def sdnControllerRemoveHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SdnControllerRemoveHostAction.class) Closure c) { + def a = new org.zstack.sdk.SdnControllerRemoveHostAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38564,8 +38688,8 @@ abstract class ApiHelper { } - def loginIAM2Platform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.LoginIAM2PlatformAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.LoginIAM2PlatformAction() + def securityMachineDetectSync(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SecurityMachineDetectSyncAction.class) Closure c) { + def a = new org.zstack.sdk.SecurityMachineDetectSyncAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38591,8 +38715,10332 @@ abstract class ApiHelper { } - def loginIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.LoginIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.LoginIAM2ProjectAction() + def securityMachineEncrypt(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SecurityMachineEncryptAction.class) Closure c) { + def a = new org.zstack.sdk.SecurityMachineEncryptAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def selfTestLocalRaid(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SelfTestLocalRaidAction.class) Closure c) { + def a = new org.zstack.sdk.SelfTestLocalRaidAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setFlowMeterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetFlowMeterRouterIdAction.class) Closure c) { + def a = new org.zstack.sdk.SetFlowMeterRouterIdAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setImageBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageBootModeAction.class) Closure c) { + def a = new org.zstack.sdk.SetImageBootModeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setImageQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageQgaAction.class) Closure c) { + def a = new org.zstack.sdk.SetImageQgaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setImageSecurityLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageSecurityLevelAction.class) Closure c) { + def a = new org.zstack.sdk.SetImageSecurityLevelAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setImageStoreBackupStorageQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetImageStoreBackupStorageQuotaAction.class) Closure c) { + def a = new org.zstack.sdk.SetImageStoreBackupStorageQuotaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setIpOnHostNetworkBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetIpOnHostNetworkBondingAction.class) Closure c) { + def a = new org.zstack.sdk.SetIpOnHostNetworkBondingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setIpOnHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetIpOnHostNetworkInterfaceAction.class) Closure c) { + def a = new org.zstack.sdk.SetIpOnHostNetworkInterfaceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setL3NetworkMtu(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetL3NetworkMtuAction.class) Closure c) { + def a = new org.zstack.sdk.SetL3NetworkMtuAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setL3NetworkRouterInterfaceIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetL3NetworkRouterInterfaceIpAction.class) Closure c) { + def a = new org.zstack.sdk.SetL3NetworkRouterInterfaceIpAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setNicQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetNicQosAction.class) Closure c) { + def a = new org.zstack.sdk.SetNicQosAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setSecurityMachineKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetSecurityMachineKeyAction.class) Closure c) { + def a = new org.zstack.sdk.SetSecurityMachineKeyAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setServiceTypeOnHostNetworkBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetServiceTypeOnHostNetworkBondingAction.class) Closure c) { + def a = new org.zstack.sdk.SetServiceTypeOnHostNetworkBondingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setServiceTypeOnHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetServiceTypeOnHostNetworkInterfaceAction.class) Closure c) { + def a = new org.zstack.sdk.SetServiceTypeOnHostNetworkInterfaceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVRouterRouterId(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVRouterRouterIdAction.class) Closure c) { + def a = new org.zstack.sdk.SetVRouterRouterIdAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVipQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVipQosAction.class) Closure c) { + def a = new org.zstack.sdk.SetVipQosAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmBootMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmBootModeAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmBootModeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmBootOrder(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmBootOrderAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmBootOrderAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmBootVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmBootVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmBootVolumeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmCleanTraffic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmCleanTrafficAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmCleanTrafficAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmClockTrack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmClockTrackAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmClockTrackAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmConsoleMode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmConsoleModeAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmConsoleModeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmConsolePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmConsolePasswordAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmConsolePasswordAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmEmulatorPinning(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmEmulatorPinningAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmEmulatorPinningAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmHostname(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmHostnameAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmHostnameAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmInstanceDefaultCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmInstanceDefaultCdRomAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmInstanceDefaultCdRomAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmInstanceHaLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmInstanceHaLevelAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmInstanceHaLevelAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmMonitorNumber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmMonitorNumberAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmMonitorNumberAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmNicSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmNicSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmNicSecurityGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmNuma(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmNumaAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmNumaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmQga(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmQgaAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmQgaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmQxlMemory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmQxlMemoryAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmQxlMemoryAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmRDP(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmRDPAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmRDPAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmSecurityLevel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmSecurityLevelAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmSecurityLevelAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmSoundType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmSoundTypeAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmSoundTypeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmSshKey(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmSshKeyAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmSshKeyAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmStaticIp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmStaticIpAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmStaticIpAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmUsbRedirect(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmUsbRedirectAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmUsbRedirectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmUserDefinedXml(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmUserDefinedXmlAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmUserDefinedXmlAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVmUserDefinedXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.SetVmUserDefinedXmlHookScriptAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVolumeIoThreadPin(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVolumeIoThreadPinAction.class) Closure c) { + def a = new org.zstack.sdk.SetVolumeIoThreadPinAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVolumeQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVolumeQosAction.class) Closure c) { + def a = new org.zstack.sdk.SetVolumeQosAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVpcVRouterDistributedRoutingEnabled(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVpcVRouterDistributedRoutingEnabledAction.class) Closure c) { + def a = new org.zstack.sdk.SetVpcVRouterDistributedRoutingEnabledAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setVpcVRouterNetworkServiceState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SetVpcVRouterNetworkServiceStateAction.class) Closure c) { + def a = new org.zstack.sdk.SetVpcVRouterNetworkServiceStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def shareResource(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ShareResourceAction.class) Closure c) { + def a = new org.zstack.sdk.ShareResourceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def shrinkVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ShrinkVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.ShrinkVolumeSnapshotAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def shutdownHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ShutdownHostAction.class) Closure c) { + def a = new org.zstack.sdk.ShutdownHostAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def ssoClientPushData(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SsoClientPushDataAction.class) Closure c) { + def a = new org.zstack.sdk.SsoClientPushDataAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartBareMetal2InstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StartBareMetal2InstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StartBaremetalInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.StartBaremetalPxeServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startConnectionBetweenAliyunRouterInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartConnectionBetweenAliyunRouterInterfaceAction.class) Closure c) { + def a = new org.zstack.sdk.StartConnectionBetweenAliyunRouterInterfaceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startDataProtection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartDataProtectionAction.class) Closure c) { + def a = new org.zstack.sdk.StartDataProtectionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartEcsInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StartEcsInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startSnmpAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartSnmpAgentAction.class) Closure c) { + def a = new org.zstack.sdk.StartSnmpAgentAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def startVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StartVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StartVmInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def stopBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StopBaremetalInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def stopBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.StopBaremetalPxeServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def stopEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopEcsInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StopEcsInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def stopSnmpAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopSnmpAgentAction.class) Closure c) { + def a = new org.zstack.sdk.StopSnmpAgentAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def stopVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.StopVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.StopVmInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def submitLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SubmitLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.SubmitLongJobAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncAINginxConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAINginxConfigurationAction.class) Closure c) { + def a = new org.zstack.sdk.SyncAINginxConfigurationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncAliyunRouteEntryFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunRouteEntryFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncAliyunRouteEntryFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncAliyunRouterInterfaceFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunRouterInterfaceFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncAliyunRouterInterfaceFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncAliyunSnapshotRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunSnapshotRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncAliyunSnapshotRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncAliyunVirtualRouterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncAliyunVirtualRouterFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncAliyunVirtualRouterFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncChronyServers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncChronyServersAction.class) Closure c) { + def a = new org.zstack.sdk.SyncChronyServersAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncConnectionAccessPointFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncConnectionAccessPointFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncConnectionAccessPointFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncContainerManagementEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncContainerManagementEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.SyncContainerManagementEndpointAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncDataCenterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncDataCenterFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncDataCenterFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncDiskFromAliyunFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncDiskFromAliyunFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncDiskFromAliyunFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncEcsImageFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsImageFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncEcsImageFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncEcsInstanceFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsInstanceFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncEcsInstanceFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncEcsSecurityGroupFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsSecurityGroupFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncEcsSecurityGroupFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncEcsSecurityGroupRuleFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsSecurityGroupRuleFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncEcsSecurityGroupRuleFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncEcsVSwitchFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsVSwitchFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncEcsVSwitchFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncEcsVpcFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncEcsVpcFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncEcsVpcFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncHybridEipFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncHybridEipFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncHybridEipFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncIdentityFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncIdentityFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncIdentityFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncImageAction.class) Closure c) { + def a = new org.zstack.sdk.SyncImageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncImageFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncImageFromImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.SyncImageFromImageStoreBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncImageSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncImageSizeAction.class) Closure c) { + def a = new org.zstack.sdk.SyncImageSizeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncLdapServerAction.class) Closure c) { + def a = new org.zstack.sdk.SyncLdapServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncPrimaryStorageCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncPrimaryStorageCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.SyncPrimaryStorageCapacityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVCenterAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVCenterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVirtualBorderRouterFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVirtualBorderRouterFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVirtualBorderRouterFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVmClock(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVmClockAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVmClockAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVolumeSize(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVolumeSizeAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVolumeSizeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVpcUserVpnGatewayFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVpcUserVpnGatewayFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVpcUserVpnGatewayFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVpcVpnConnectionFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVpcVpnConnectionFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVpcVpnConnectionFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncVpcVpnGatewayFromRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncVpcVpnGatewayFromRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.SyncVpcVpnGatewayFromRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncZBoxCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.SyncZBoxCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.SyncZBoxCapacityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def takeVmConsoleScreenshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.TakeVmConsoleScreenshotAction.class) Closure c) { + def a = new org.zstack.sdk.TakeVmConsoleScreenshotAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def terminateVirtualBorderRouterRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.TerminateVirtualBorderRouterRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.TerminateVirtualBorderRouterRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def tokenIntrospection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.TokenIntrospectionAction.class) Closure c) { + def a = new org.zstack.sdk.TokenIntrospectionAction() + + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def triggerGCJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.TriggerGCJobAction.class) Closure c) { + def a = new org.zstack.sdk.TriggerGCJobAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def unbindModelFromService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnbindModelFromServiceAction.class) Closure c) { + def a = new org.zstack.sdk.UnbindModelFromServiceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def undoSnapshotCreation(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UndoSnapshotCreationAction.class) Closure c) { + def a = new org.zstack.sdk.UndoSnapshotCreationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def unexportNbdVolumes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnexportNbdVolumesAction.class) Closure c) { + def a = new org.zstack.sdk.UnexportNbdVolumesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def ungenerateMdevDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngenerateMdevDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.UngenerateMdevDevicesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def ungenerateSeMdevDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngenerateSeMdevDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.UngenerateSeMdevDevicesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def ungenerateSriovPciDevices(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngenerateSriovPciDevicesAction.class) Closure c) { + def a = new org.zstack.sdk.UngenerateSriovPciDevicesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def ungroupVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UngroupVolumeSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UngroupVolumeSnapshotGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def unlockIdentity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnlockIdentityAction.class) Closure c) { + def a = new org.zstack.sdk.UnlockIdentityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def unmountVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnmountVmInstanceRecoveryPointAction.class) Closure c) { + def a = new org.zstack.sdk.UnmountVmInstanceRecoveryPointAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def unprotectVmInstanceRecoveryPoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UnprotectVmInstanceRecoveryPointAction.class) Closure c) { + def a = new org.zstack.sdk.UnprotectVmInstanceRecoveryPointAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAccessControlList(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAccessControlListAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAccessControlListAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAccessControlRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAccessControlRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAccessControlRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAccountAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAccountAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAffinityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAffinityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAffinityGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunDisk(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunDiskAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunDiskAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunEbsBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunEbsBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunEbsBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunEbsPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunEbsPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunEbsPrimaryStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunKeySecretAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunKeySecretAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunMountTargetAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunMountTargetAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunNasAccessGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunNasAccessGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunNasAccessGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunPanguPartition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunPanguPartitionAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunPanguPartitionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunProxyVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunProxyVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunProxyVSwitchAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunProxyVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunProxyVpcAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunProxyVpcAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunRouteInterfaceRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunRouteInterfaceRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunRouteInterfaceRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunSnapshotAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAliyunVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAliyunVirtualRouterAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAliyunVirtualRouterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAppBuildSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAppBuildSystemAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAppBuildSystemAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAutoScalingGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAutoScalingGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAutoScalingGroupAddingNewInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupAddingNewInstanceRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAutoScalingGroupAddingNewInstanceRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAutoScalingGroupInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAutoScalingGroupInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAutoScalingGroupRemovalInstanceRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingGroupRemovalInstanceRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAutoScalingGroupRemovalInstanceRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAutoScalingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAutoScalingRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateAutoScalingVmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateAutoScalingVmTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateAutoScalingVmTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2Chassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ChassisAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2ChassisAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2ChassisOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ChassisOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2ChassisOfferingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2ChassisPciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ChassisPciDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2ChassisPciDeviceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2Gateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2GatewayAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2GatewayAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2Instance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2InstanceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2InstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2IpmiChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2IpmiChassisAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2IpmiChassisAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBareMetal2ProvisionNetwork(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBareMetal2ProvisionNetworkAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBareMetal2ProvisionNetworkAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBaremetalChassis(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBaremetalChassisAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBaremetalChassisAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBaremetalInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBaremetalInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBaremetalInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBaremetalPxeServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBaremetalPxeServerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBaremetalPxeServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBlockPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBlockPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBlockPrimaryStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBlockVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBlockVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBlockVolumeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBonding(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBondingAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBondingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateBuildApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateBuildAppAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateBuildAppAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCCSCertificateUserState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCCSCertificateUserStateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCCSCertificateUserStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCSPSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCSPSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCSPSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCasClient(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCasClientAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCasClientAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCdpPolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCdpPolicyAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCdpPolicyAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCdpTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCdpTaskAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCdpTaskAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCephBackupStorageMon(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCephBackupStorageMonAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCephBackupStorageMonAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCephPrimaryStorageMon(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCephPrimaryStorageMonAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCephPrimaryStorageMonAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCephPrimaryStoragePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCephPrimaryStoragePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCephPrimaryStoragePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCertificate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateCertificateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateCertificateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateChronyServers(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateChronyServersAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateChronyServersAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateClusterAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateClusterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateClusterDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateClusterDRSAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateClusterDRSAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateClusterOS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateClusterOSAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateClusterOSAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateConnectionBetweenL3NetWorkAndAliyunVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateConnectionBetweenL3NetWorkAndAliyunVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateConnectionBetweenL3NetWorkAndAliyunVSwitchAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateConsoleProxyAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateConsoleProxyAgentAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateConsoleProxyAgentAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateContainerManagementEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateContainerManagementEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateContainerManagementEndpointAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateDataset(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateDatasetAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateDatasetAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateDatasets(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateDatasetsAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateDatasetsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateDirectory(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateDirectoryAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateDirectoryAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateDiskOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateDiskOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateDiskOfferingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEcsImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsImageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEcsImageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEcsInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEcsInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEcsInstanceVncPassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsInstanceVncPasswordAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEcsInstanceVncPasswordAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEcsSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEcsSecurityGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEcsVSwitch(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsVSwitchAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEcsVSwitchAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEcsVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEcsVpcAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEcsVpcAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEipAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEipAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEmailMedia(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEmailMediaAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEmailMediaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateEmailMonitorTriggerAction(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateEmailMonitorTriggerActionAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateEmailMonitorTriggerActionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateExternalPrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateExternalPrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateExternalPrimaryStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFactoryModeState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFactoryModeStateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFactoryModeStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFiSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFiSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFiSecSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFiSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFiSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFiSecSecurityMachineAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFirewallIpSetTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallIpSetTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFirewallIpSetTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFirewallRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFirewallRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFirewallRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFirewallRuleSetAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFirewallRuleTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFirewallRuleTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFirewallRuleTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFlkSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFlkSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFlkSecSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFlkSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFlkSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFlkSecSecurityMachineAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFlowCollector(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFlowCollectorAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFlowCollectorAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateFlowMeter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateFlowMeterAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateFlowMeterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateGlobalConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateGlobalConfigAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateGlobalConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateGuestToolsState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateGuestToolsStateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateGuestToolsStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateGuestVmScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateGuestVmScriptAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateGuestVmScriptAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHaStrategyCondition(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHaStrategyConditionAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHaStrategyConditionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHostIommuState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostIommuStateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostIommuStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHostIpmi(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostIpmiAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostIpmiAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHostNetworkInterface(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostNetworkInterfaceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostNetworkInterfaceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHostNetworkServiceType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostNetworkServiceTypeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostNetworkServiceTypeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHostSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHostSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHostSchedulingRuleGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHybridEip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHybridEipAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHybridEipAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateHybridKeySecret(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateHybridKeySecretAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateHybridKeySecretAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIPsecConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateIPsecConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateIPsecConnectionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateImage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateImageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateImageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateImagePackage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateImagePackageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateImagePackageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateImageStoreBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateInfoSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateInfoSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateInfoSecSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateInfoSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateInfoSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateInfoSecSecurityMachineAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateInstanceOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateInstanceOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateInstanceOfferingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIpRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateIpRangeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateIpRangeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIscsiServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateIscsiServerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateIscsiServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateJitSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateJitSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateJitSecurityMachineAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateKVMHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateKVMHostAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateKVMHostAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateKoAlSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateKoAlSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateKoAlSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateL2Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateL2NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateL2NetworkAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateL3Network(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateL3NetworkAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateL3NetworkAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLdapServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLdapServerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLdapServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLicense(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLicenseAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLicenseAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLoadBalancer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLoadBalancerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLoadBalancerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLoadBalancerListener(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLoadBalancerListenerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLoadBalancerListenerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLoadBalancerServerGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLoadBalancerServerGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLoadBalancerServerGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLogConfiguration(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLogConfigurationAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLogConfigurationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLogServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLogServerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLogServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateLongJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateLongJobAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateLongJobAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateMdevDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateMdevDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateMdevDeviceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateMdevDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateMdevDeviceSpecAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateMdevDeviceSpecAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateModel(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateModelAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateModelAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateModelCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateModelCenterAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateModelCenterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateModelEvaluationTask(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateModelEvaluationTaskAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateModelEvaluationTaskAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateModelService(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateModelServiceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateModelServiceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateModelServiceInstanceGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateModelServiceInstanceGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateModelServiceInstanceGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateMonitorTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateMonitorTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateMonitorTriggerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateNasFileSystem(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateNasFileSystemAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateNasFileSystemAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateNasMountTarget(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateNasMountTargetAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateNasMountTargetAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateOAuthClient(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateOAuthClientAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateOAuthClientAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateOssBucket(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateOssBucketAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateOssBucketAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePciDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePciDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePciDeviceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePciDeviceSpec(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePciDeviceSpecAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePciDeviceSpecAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePluginSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePluginSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePluginSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePolicyRouteRuleSet(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePolicyRouteRuleSetAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePolicyRouteRuleSetAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePortForwardingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePortForwardingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePortForwardingRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePortMirror(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePortMirrorAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePortMirrorAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePreconfigurationTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePreconfigurationTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePreconfigurationTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePriceTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePriceTableAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePriceTableAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePrimaryStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePrimaryStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePrimaryStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePriorityConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePriorityConfigAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePriorityConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updatePublishApp(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdatePublishAppAction.class) Closure c) { + def a = new org.zstack.sdk.UpdatePublishAppAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateQuotaAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateQuotaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateResourceConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourceConfigAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateResourceConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateResourceConfigs(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourceConfigsAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateResourceConfigsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateResourcePrice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourcePriceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateResourcePriceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateResourceStack(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateResourceStackAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateResourceStackAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSAML2Client(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSAML2ClientAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSAML2ClientAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSSOClientAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSSOClientAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSSOClientAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSSORedirectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSSORedirectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSSORedirectTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSanSecSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSanSecSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSanSecSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSanSecSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSanSecSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSanSecSecurityMachineAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSchedulerJob(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSchedulerJobAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSchedulerJobAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSchedulerJobGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSchedulerJobGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSchedulerJobGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSchedulerTrigger(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSchedulerTriggerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSchedulerTriggerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateScsiLun(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateScsiLunAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateScsiLunAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSdnController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSdnControllerAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSdnControllerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSecretResourcePool(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecretResourcePoolAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSecretResourcePoolAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSecurityGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecurityGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSecurityGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSecurityGroupRulePriority(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecurityGroupRulePriorityAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSecurityGroupRulePriorityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSecurityMachine(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSecurityMachineAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSecurityMachineAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSftpBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSftpBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSftpBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSharedBlock(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSharedBlockAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSharedBlockAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSlbGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSlbGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSlbGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSnmpAgent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSnmpAgentAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSnmpAgentAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSshKeyPair(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSshKeyPairAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSshKeyPairAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateStackTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateStackTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateStackTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateSystemTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateSystemTagAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateSystemTagAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateTag(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateTagAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateTagAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateTemplateConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateTemplateConfigAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateTemplateConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateUsbDevice(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUsbDeviceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateUsbDeviceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateUser(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUserAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateUserAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateUserGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUserGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateUserGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateUserProxyConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateUserProxyConfigAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateUserProxyConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateV2VConversionHost(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateV2VConversionHostAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateV2VConversionHostAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVCenter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVCenterAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVCenterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVRouterOspfArea(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVRouterOspfAreaAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVRouterOspfAreaAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVRouterRouteTable(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVRouterRouteTableAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVRouterRouteTableAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVip(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVipAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVipAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVirtualBorderRouterRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualBorderRouterRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVirtualBorderRouterRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVirtualRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualRouterAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVirtualRouterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVirtualRouterOffering(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualRouterOfferingAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVirtualRouterOfferingAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVirtualRouterSoftwareVersion(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVirtualRouterSoftwareVersionAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVirtualRouterSoftwareVersionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmCdRom(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmCdRomAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmCdRomAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmInstance(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmInstanceAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmInstanceAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmNetworkConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmNetworkConfigAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmNetworkConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmNicDriver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmNicDriverAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmNicDriverAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmNicMac(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmNicMacAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmNicMacAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmPriority(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmPriorityAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmPriorityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmSchedulingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmSchedulingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmSchedulingRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmSchedulingRuleGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmSchedulingRuleGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmSchedulingRuleGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVmUserDefinedXmlHookScript(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVmUserDefinedXmlHookScriptAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVmUserDefinedXmlHookScriptAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVniRange(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVniRangeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVniRangeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVolumeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVolumeSnapshot(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVolumeSnapshotAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVolumeSnapshotAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVolumeSnapshotGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVolumeSnapshotGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVolumeSnapshotGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVpcFirewall(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcFirewallAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVpcFirewallAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVpcHaGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcHaGroupAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVpcHaGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVpcSharedQos(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcSharedQosAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVpcSharedQosAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVpcUserVpnGateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcUserVpnGatewayAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVpcUserVpnGatewayAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVpcVpnConnectionRemote(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcVpnConnectionRemoteAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVpcVpnConnectionRemoteAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateVpcVpnGateway(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateVpcVpnGatewayAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateVpcVpnGatewayAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateWebhook(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateWebhookAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateWebhookAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateXskyBlockVolume(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateXskyBlockVolumeAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateXskyBlockVolumeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateZone(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpdateZoneAction.class) Closure c) { + def a = new org.zstack.sdk.UpdateZoneAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def upgradeBackupStorageCdpTasks(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UpgradeBackupStorageCdpTasksAction.class) Closure c) { + def a = new org.zstack.sdk.UpgradeBackupStorageCdpTasksAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def uploadFileToVm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.UploadFileToVmAction.class) Closure c) { + def a = new org.zstack.sdk.UploadFileToVmAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateClusterSupportDRS(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateClusterSupportDRSAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateClusterSupportDRSAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateDiskOfferingUserConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateDiskOfferingUserConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateDiskOfferingUserConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateInstanceOfferingUserConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateInstanceOfferingUserConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateInstanceOfferingUserConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validatePassword(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidatePasswordAction.class) Closure c) { + def a = new org.zstack.sdk.ValidatePasswordAction() + + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validatePriceUserConfig(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidatePriceUserConfigAction.class) Closure c) { + def a = new org.zstack.sdk.ValidatePriceUserConfigAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateSecurityGroupRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateSecurityGroupRuleAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateSecurityGroupRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateSession(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateSessionAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateSessionAction() + + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateVmSchedulingRule(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateVmSchedulingRuleAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateVmSchedulingRuleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def validateVolumeSnapshotChain(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ValidateVolumeSnapshotChainAction.class) Closure c) { + def a = new org.zstack.sdk.ValidateVolumeSnapshotChainAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def zQLQuery(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.ZQLQueryAction.class) Closure c) { + def a = new org.zstack.sdk.ZQLQueryAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.CreateDatabaseBackupAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.CreateDatabaseBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.DeleteDatabaseBackupAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.DeleteDatabaseBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteExportedDatabaseBackupFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.DeleteExportedDatabaseBackupFromBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.DeleteExportedDatabaseBackupFromBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def exportDatabaseBackupFromBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.ExportDatabaseBackupFromBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.ExportDatabaseBackupFromBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getDatabaseBackupFromImageStore(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.GetDatabaseBackupFromImageStoreAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.GetDatabaseBackupFromImageStoreAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.QueryDatabaseBackupAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.QueryDatabaseBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def recoverDatabaseFromBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.RecoverDatabaseFromBackupAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.RecoverDatabaseFromBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncDatabaseBackup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.SyncDatabaseBackupAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.SyncDatabaseBackupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncDatabaseBackupFromImageStoreBackupStorage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.databasebackup.SyncDatabaseBackupFromImageStoreBackupStorageAction.class) Closure c) { + def a = new org.zstack.sdk.databasebackup.SyncDatabaseBackupFromImageStoreBackupStorageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createHuaweiIMasterVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.CreateHuaweiIMasterVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.CreateHuaweiIMasterVRouterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteHuaweiIMasterFabric(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterFabricAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterFabricAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteHuaweiIMasterTenant(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterTenantAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterTenantAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteHuaweiIMasterVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterVRouterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteHuaweiIMasterVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterVpcAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.DeleteHuaweiIMasterVpcAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def pullHuaweiIMasterController(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.PullHuaweiIMasterControllerAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.PullHuaweiIMasterControllerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryHuaweiIMasterFabric(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterFabricAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterFabricAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryHuaweiIMasterTenant(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterTenantAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterTenantAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryHuaweiIMasterVRouter(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterVRouterAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterVRouterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryHuaweiIMasterVpc(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterVpcAction.class) Closure c) { + def a = new org.zstack.sdk.huawei.imaster.QueryHuaweiIMasterVpcAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addAttributesToIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addAttributesToIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addAttributesToIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addAttributesToIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddAttributesToIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addIAM2VirtualIDGroupToProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDGroupToProjectsAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDGroupToProjectsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addIAM2VirtualIDsToGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addIAM2VirtualIDsToOrganization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToOrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToOrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addIAM2VirtualIDsToProject(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addIAM2VirtualIDsToProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectsAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddIAM2VirtualIDsToProjectsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addResourceToIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddResourceToIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddResourceToIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addRolesToIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addRolesToIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AddRolesToIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def attachIAM2ProjectToIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.AttachIAM2ProjectToIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.AttachIAM2ProjectToIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def batchCreateIAM2VirtualIDFromConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.BatchCreateIAM2VirtualIDFromConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.BatchCreateIAM2VirtualIDFromConfigFileAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def changeIAM2OrganizationParent(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2OrganizationParentAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ChangeIAM2OrganizationParentAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def changeIAM2OrganizationState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2OrganizationStateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ChangeIAM2OrganizationStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def changeIAM2ProjectState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2ProjectStateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ChangeIAM2ProjectStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def changeIAM2VirtualIDGroupState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDGroupStateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDGroupStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def changeIAM2VirtualIDState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDStateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def changeIAM2VirtualIDType(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDTypeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ChangeIAM2VirtualIDTypeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def checkIAM2OrganizationAvailability(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CheckIAM2OrganizationAvailabilityAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CheckIAM2OrganizationAvailabilityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def checkIAM2VirtualIDConfigFile(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CheckIAM2VirtualIDConfigFileAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CheckIAM2VirtualIDConfigFileAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2ProjectFromTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectFromTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectFromTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2ProjectRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectRoleAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2ProjectTemplateFromProject(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateFromProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2ProjectTemplateFromProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.CreateIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.CreateIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.DeleteIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.DeleteIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2ProjectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.DeleteIAM2ProjectTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def deleteIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.DeleteIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def detachIAM2ProjectFromIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.DetachIAM2ProjectFromIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.DetachIAM2ProjectFromIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def expungeIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.ExpungeIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.ExpungeIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getIAM2OrganizationVirtualIDNumber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2OrganizationVirtualIDNumberAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.GetIAM2OrganizationVirtualIDNumberAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getIAM2ProjectsOfVirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2ProjectsOfVirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.GetIAM2ProjectsOfVirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getIAM2SystemAttributes(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2SystemAttributesAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.GetIAM2SystemAttributesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getIAM2VirtualIDAPIPermission(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2VirtualIDAPIPermissionAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.GetIAM2VirtualIDAPIPermissionAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getIAM2VirtualIDInGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetIAM2VirtualIDInGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.GetIAM2VirtualIDInGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getOrganizationQuotaUsage(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.GetOrganizationQuotaUsageAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.GetOrganizationQuotaUsageAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def loginIAM2Platform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.LoginIAM2PlatformAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.LoginIAM2PlatformAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def loginIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.LoginIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.LoginIAM2ProjectAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38645,15 +49093,1063 @@ abstract class ApiHelper { } - def queryIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2OrganizationAction() + def queryIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2OrganizationAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2OrganizationAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2OrganizationAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2OrganizationProjectRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2OrganizationProjectRefAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2OrganizationProjectRefAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2ProjectAccountRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectAccountRefAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectAccountRefAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2ProjectAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2ProjectRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectRoleAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2VirtualIDAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryIAM2VirtualIDGroupAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def recoverIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RecoverIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RecoverIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeAttributesFromIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeAttributesFromIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeAttributesFromIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeAttributesFromIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeIAM2ProjectLoginExpired(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2ProjectLoginExpiredAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveIAM2ProjectLoginExpiredAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeIAM2VirtualIDGroupFromProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDGroupFromProjectsAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDGroupFromProjectsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeIAM2VirtualIDsFromGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeIAM2VirtualIDsFromOrganization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromOrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromOrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeIAM2VirtualIDsFromProject(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeIAM2VirtualIDsFromProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectsAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectsAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeRolesFromIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def removeRolesFromIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDGroupAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setIAM2ProjectLoginExpired(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetIAM2ProjectLoginExpiredAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.SetIAM2ProjectLoginExpiredAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setIAM2ProjectRetirePolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetIAM2ProjectRetirePolicyAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.SetIAM2ProjectRetirePolicyAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setOrganizationOperation(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetOrganizationOperationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.SetOrganizationOperationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setOrganizationSupervisor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetOrganizationSupervisorAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.SetOrganizationSupervisorAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def stopAllResourcesInIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.StopAllResourcesInIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.StopAllResourcesInIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2OrganizationAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2ProjectAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2ProjectAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2ProjectAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2ProjectAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2ProjectAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2ProjectTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2ProjectTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2VirtualIDAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateIAM2VirtualIDGroupAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAttributeAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAttributeAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38674,16 +50170,41 @@ abstract class ApiHelper { } - def queryIAM2OrganizationAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2OrganizationAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2OrganizationAttributeAction() + def updateOrganizationQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateOrganizationQuotaAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.api.UpdateOrganizationQuotaAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + def getIAM2ProjectContainerClusterCandidates(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.container.GetIAM2ProjectContainerClusterCandidatesAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.container.GetIAM2ProjectContainerClusterCandidatesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + if (System.getProperty("apipath") != null) { if (a.apiId == null) { a.apiId = Platform.uuid @@ -38703,15 +50224,40 @@ abstract class ApiHelper { } - def queryIAM2OrganizationProjectRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2OrganizationProjectRefAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2OrganizationProjectRefAction() + def getIAM2ProjectContainerImageTags(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.container.GetIAM2ProjectContainerImageTagsAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.container.GetIAM2ProjectContainerImageTagsAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getIAM2ProjectContainerImages(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.container.GetIAM2ProjectContainerImagesAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.container.GetIAM2ProjectContainerImagesAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38732,15 +50278,67 @@ abstract class ApiHelper { } - def queryIAM2ProjectAccountRef(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectAccountRefAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectAccountRefAction() + def getIAM2ProjectRepository(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.container.GetIAM2ProjectRepositoryAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.container.GetIAM2ProjectRepositoryAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def setIAM2ProjectContainerCluster(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.container.SetIAM2ProjectContainerClusterAction.class) Closure c) { + def a = new org.zstack.sdk.iam2.container.SetIAM2ProjectContainerClusterAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def addPolicyStatementsToRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.AddPolicyStatementsToRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.AddPolicyStatementsToRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38761,15 +50359,40 @@ abstract class ApiHelper { } - def queryIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectAction() + def attachPolicyToRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.AttachPolicyToRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.AttachPolicyToRoleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def attachRoleToAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.AttachRoleToAccountAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.AttachRoleToAccountAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38790,15 +50413,40 @@ abstract class ApiHelper { } - def queryIAM2ProjectAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectAttributeAction() + def changeRoleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.ChangeRoleStateAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.ChangeRoleStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.CreateRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.CreateRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38819,8 +50467,89 @@ abstract class ApiHelper { } - def queryIAM2ProjectRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectRoleAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectRoleAction() + def deleteRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.DeleteRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.DeleteRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def detachPolicyFromRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.DetachPolicyFromRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.DetachPolicyFromRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def detachRoleFromAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.DetachRoleFromAccountAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.DetachRoleFromAccountAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.QueryRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.QueryRoleAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38848,8 +50577,143 @@ abstract class ApiHelper { } - def queryIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2ProjectTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2ProjectTemplateAction() + def removePolicyStatementsFromRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.RemovePolicyStatementsFromRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.RemovePolicyStatementsFromRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def updateRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.UpdateRoleAction.class) Closure c) { + def a = new org.zstack.sdk.identity.role.api.UpdateRoleAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def degradeFromLicenseServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.DegradeFromLicenseServerAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.DegradeFromLicenseServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def getLicenseAuthorizedCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.GetLicenseAuthorizedCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.GetLicenseAuthorizedCapacityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def isLicenseServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.IsLicenseServerAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.IsLicenseServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def queryLicenseAuthorizedNode(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.QueryLicenseAuthorizedNodeAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.QueryLicenseAuthorizedNodeAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -38877,15 +50741,94 @@ abstract class ApiHelper { } - def queryIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAction() + def registerLicenseServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.RegisterLicenseServerAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.RegisterLicenseServerAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def requestLicenseCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.RequestLicenseCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.RequestLicenseCapacityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def syncLicenseCapacity(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.SyncLicenseCapacityAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.SyncLicenseCapacityAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def unregisterLicenseRequestedApplication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.UnregisterLicenseRequestedApplicationAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.UnregisterLicenseRequestedApplicationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38906,15 +50849,13 @@ abstract class ApiHelper { } - def queryIAM2VirtualIDAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDAttributeAction() + def unregisterLicenseServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.UnregisterLicenseServerAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.UnregisterLicenseServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38935,15 +50876,13 @@ abstract class ApiHelper { } - def queryIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAction() + def upgradeToLicenseServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.UpgradeToLicenseServerAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.UpgradeToLicenseServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38964,15 +50903,13 @@ abstract class ApiHelper { } - def queryIAM2VirtualIDGroupAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.QueryIAM2VirtualIDGroupAttributeAction() + def verifyLicenseServer(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.VerifyLicenseServerAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.VerifyLicenseServerAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -38993,8 +50930,8 @@ abstract class ApiHelper { } - def recoverIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RecoverIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RecoverIAM2ProjectAction() + def withdrawLicenseCapacityApplication(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.license.api.server.WithdrawLicenseCapacityApplicationAction.class) Closure c) { + def a = new org.zstack.sdk.license.api.server.WithdrawLicenseCapacityApplicationAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39020,8 +50957,8 @@ abstract class ApiHelper { } - def removeAttributesFromIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2OrganizationAction() + def addSNSSmsReceiver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.AddSNSSmsReceiverAction.class) Closure c) { + def a = new org.zstack.sdk.sns.AddSNSSmsReceiverAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39047,8 +50984,8 @@ abstract class ApiHelper { } - def removeAttributesFromIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2ProjectAction() + def changeSNSApplicationEndpointState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.ChangeSNSApplicationEndpointStateAction.class) Closure c) { + def a = new org.zstack.sdk.sns.ChangeSNSApplicationEndpointStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39074,8 +51011,8 @@ abstract class ApiHelper { } - def removeAttributesFromIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDAction() + def changeSNSApplicationPlatformState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.ChangeSNSApplicationPlatformStateAction.class) Closure c) { + def a = new org.zstack.sdk.sns.ChangeSNSApplicationPlatformStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39101,8 +51038,8 @@ abstract class ApiHelper { } - def removeAttributesFromIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveAttributesFromIAM2VirtualIDGroupAction() + def changeSNSTopicState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.ChangeSNSTopicStateAction.class) Closure c) { + def a = new org.zstack.sdk.sns.ChangeSNSTopicStateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39128,8 +51065,8 @@ abstract class ApiHelper { } - def removeIAM2ProjectLoginExpired(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2ProjectLoginExpiredAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveIAM2ProjectLoginExpiredAction() + def createSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.CreateSNSTopicAction.class) Closure c) { + def a = new org.zstack.sdk.sns.CreateSNSTopicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39155,8 +51092,8 @@ abstract class ApiHelper { } - def removeIAM2VirtualIDGroupFromProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDGroupFromProjectsAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDGroupFromProjectsAction() + def deleteSNSApplicationEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.DeleteSNSApplicationEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.DeleteSNSApplicationEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39182,8 +51119,8 @@ abstract class ApiHelper { } - def removeIAM2VirtualIDsFromGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromGroupAction() + def deleteSNSApplicationPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.DeleteSNSApplicationPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.DeleteSNSApplicationPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39209,8 +51146,8 @@ abstract class ApiHelper { } - def removeIAM2VirtualIDsFromOrganization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromOrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromOrganizationAction() + def deleteSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.DeleteSNSTopicAction.class) Closure c) { + def a = new org.zstack.sdk.sns.DeleteSNSTopicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39236,40 +51173,15 @@ abstract class ApiHelper { } - def removeIAM2VirtualIDsFromProject(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectAction() + def querySNSApplicationEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSApplicationEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.QuerySNSApplicationEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def removeIAM2VirtualIDsFromProjects(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectsAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveIAM2VirtualIDsFromProjectsAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39290,40 +51202,15 @@ abstract class ApiHelper { } - def removeRolesFromIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDAction() + def querySNSApplicationPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSApplicationPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.QuerySNSApplicationPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def removeRolesFromIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.RemoveRolesFromIAM2VirtualIDGroupAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39344,13 +51231,15 @@ abstract class ApiHelper { } - def setIAM2ProjectLoginExpired(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetIAM2ProjectLoginExpiredAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.SetIAM2ProjectLoginExpiredAction() + def querySNSSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.QuerySNSSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39371,13 +51260,15 @@ abstract class ApiHelper { } - def setIAM2ProjectRetirePolicy(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetIAM2ProjectRetirePolicyAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.SetIAM2ProjectRetirePolicyAction() + def querySNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSTopicAction.class) Closure c) { + def a = new org.zstack.sdk.sns.QuerySNSTopicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39398,13 +51289,15 @@ abstract class ApiHelper { } - def setOrganizationOperation(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetOrganizationOperationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.SetOrganizationOperationAction() + def querySNSTopicSubscriber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSTopicSubscriberAction.class) Closure c) { + def a = new org.zstack.sdk.sns.QuerySNSTopicSubscriberAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39425,8 +51318,8 @@ abstract class ApiHelper { } - def setOrganizationSupervisor(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.SetOrganizationSupervisorAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.SetOrganizationSupervisorAction() + def removeSNSSmsReceiver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.RemoveSNSSmsReceiverAction.class) Closure c) { + def a = new org.zstack.sdk.sns.RemoveSNSSmsReceiverAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39452,8 +51345,8 @@ abstract class ApiHelper { } - def stopAllResourcesInIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.StopAllResourcesInIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.StopAllResourcesInIAM2ProjectAction() + def subscribeSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.SubscribeSNSTopicAction.class) Closure c) { + def a = new org.zstack.sdk.sns.SubscribeSNSTopicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39479,8 +51372,8 @@ abstract class ApiHelper { } - def updateIAM2Organization(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAction() + def unsubscribeSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UnsubscribeSNSTopicAction.class) Closure c) { + def a = new org.zstack.sdk.sns.UnsubscribeSNSTopicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39506,8 +51399,8 @@ abstract class ApiHelper { } - def updateIAM2OrganizationAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2OrganizationAttributeAction() + def updateSNSApplicationEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UpdateSNSApplicationEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.UpdateSNSApplicationEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39533,8 +51426,8 @@ abstract class ApiHelper { } - def updateIAM2Project(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2ProjectAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2ProjectAction() + def updateSNSApplicationPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UpdateSNSApplicationPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.UpdateSNSApplicationPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39560,8 +51453,8 @@ abstract class ApiHelper { } - def updateIAM2ProjectAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2ProjectAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2ProjectAttributeAction() + def updateSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UpdateSNSTopicAction.class) Closure c) { + def a = new org.zstack.sdk.sns.UpdateSNSTopicAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39587,8 +51480,8 @@ abstract class ApiHelper { } - def updateIAM2ProjectTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2ProjectTemplateAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2ProjectTemplateAction() + def createSNSAliyunSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.aliyunsms.CreateSNSAliyunSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.aliyunsms.CreateSNSAliyunSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39614,8 +51507,8 @@ abstract class ApiHelper { } - def updateIAM2VirtualID(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAction() + def validateSNSAliyunSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.aliyunsms.ValidateSNSAliyunSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.aliyunsms.ValidateSNSAliyunSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39641,8 +51534,8 @@ abstract class ApiHelper { } - def updateIAM2VirtualIDAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDAttributeAction() + def addSNSDingTalkAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.AddSNSDingTalkAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.AddSNSDingTalkAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39668,8 +51561,8 @@ abstract class ApiHelper { } - def updateIAM2VirtualIDGroup(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAction() + def createSNSDingTalkEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.CreateSNSDingTalkEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.CreateSNSDingTalkEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39695,13 +51588,15 @@ abstract class ApiHelper { } - def updateIAM2VirtualIDGroupAttribute(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAttributeAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateIAM2VirtualIDGroupAttributeAction() + def querySNSDingTalkAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.QuerySNSDingTalkAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.QuerySNSDingTalkAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39722,13 +51617,15 @@ abstract class ApiHelper { } - def updateOrganizationQuota(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.iam2.api.UpdateOrganizationQuotaAction.class) Closure c) { - def a = new org.zstack.sdk.iam2.api.UpdateOrganizationQuotaAction() + def querySNSDingTalkEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.QuerySNSDingTalkEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.QuerySNSDingTalkEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -39749,8 +51646,8 @@ abstract class ApiHelper { } - def addPolicyStatementsToRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.AddPolicyStatementsToRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.AddPolicyStatementsToRoleAction() + def removeSNSDingTalkAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.RemoveSNSDingTalkAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.RemoveSNSDingTalkAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39776,8 +51673,8 @@ abstract class ApiHelper { } - def attachPolicyToRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.AttachPolicyToRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.AttachPolicyToRoleAction() + def sNSDingTalkTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.SNSDingTalkTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.SNSDingTalkTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39803,8 +51700,8 @@ abstract class ApiHelper { } - def attachRoleToAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.AttachRoleToAccountAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.AttachRoleToAccountAction() + def updateAtPersonOfAtDingTalkEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.UpdateAtPersonOfAtDingTalkEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.UpdateAtPersonOfAtDingTalkEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39830,8 +51727,8 @@ abstract class ApiHelper { } - def changeRoleState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.ChangeRoleStateAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.ChangeRoleStateAction() + def updateSNSDingTalkEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.UpdateSNSDingTalkEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.dingtalk.UpdateSNSDingTalkEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39857,8 +51754,8 @@ abstract class ApiHelper { } - def createRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.CreateRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.CreateRoleAction() + def addEmailAddressToSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.AddEmailAddressToSNSEmailEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.AddEmailAddressToSNSEmailEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39884,8 +51781,8 @@ abstract class ApiHelper { } - def deleteRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.DeleteRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.DeleteRoleAction() + def createSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.CreateSNSEmailEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.CreateSNSEmailEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39911,8 +51808,8 @@ abstract class ApiHelper { } - def detachPolicyFromRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.DetachPolicyFromRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.DetachPolicyFromRoleAction() + def createSNSEmailPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.CreateSNSEmailPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.CreateSNSEmailPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39938,8 +51835,8 @@ abstract class ApiHelper { } - def detachRoleFromAccount(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.DetachRoleFromAccountAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.DetachRoleFromAccountAction() + def deleteEmailAddressOfSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.DeleteEmailAddressOfSNSEmailEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.DeleteEmailAddressOfSNSEmailEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39965,8 +51862,8 @@ abstract class ApiHelper { } - def queryRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.QueryRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.QueryRoleAction() + def querySNSEmailAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.QuerySNSEmailAddressAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.QuerySNSEmailAddressAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -39994,40 +51891,15 @@ abstract class ApiHelper { } - def removePolicyStatementsFromRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.RemovePolicyStatementsFromRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.RemovePolicyStatementsFromRoleAction() + def querySNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.QuerySNSEmailEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.QuerySNSEmailEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { - if (a.apiId == null) { - a.apiId = Platform.uuid - } - - def tracker = new ApiPathTracker(a.apiId) - def out = errorOut(a.call()) - def path = tracker.getApiPath() - if (!path.isEmpty()) { - Test.apiPaths[a.class.name] = path.join(" --->\n") - } - - return out - } else { - return errorOut(a.call()) - } - } - - - def updateRole(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.identity.role.api.UpdateRoleAction.class) Closure c) { - def a = new org.zstack.sdk.identity.role.api.UpdateRoleAction() - a.sessionId = Test.currentEnvSpec?.session?.uuid - c.resolveStrategy = Closure.OWNER_FIRST - c.delegate = a - c() - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40048,13 +51920,15 @@ abstract class ApiHelper { } - def addSNSSmsReceiver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.AddSNSSmsReceiverAction.class) Closure c) { - def a = new org.zstack.sdk.sns.AddSNSSmsReceiverAction() + def querySNSEmailPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.QuerySNSEmailPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.QuerySNSEmailPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40075,8 +51949,8 @@ abstract class ApiHelper { } - def changeSNSApplicationEndpointState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.ChangeSNSApplicationEndpointStateAction.class) Closure c) { - def a = new org.zstack.sdk.sns.ChangeSNSApplicationEndpointStateAction() + def sNSEmailTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.SNSEmailTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.SNSEmailTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40102,8 +51976,8 @@ abstract class ApiHelper { } - def changeSNSApplicationPlatformState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.ChangeSNSApplicationPlatformStateAction.class) Closure c) { - def a = new org.zstack.sdk.sns.ChangeSNSApplicationPlatformStateAction() + def updateEmailAddressOfSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.UpdateEmailAddressOfSNSEmailEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.UpdateEmailAddressOfSNSEmailEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40129,8 +52003,8 @@ abstract class ApiHelper { } - def changeSNSTopicState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.ChangeSNSTopicStateAction.class) Closure c) { - def a = new org.zstack.sdk.sns.ChangeSNSTopicStateAction() + def validateSNSEmailPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.ValidateSNSEmailPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.email.ValidateSNSEmailPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40156,8 +52030,8 @@ abstract class ApiHelper { } - def createSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.CreateSNSTopicAction.class) Closure c) { - def a = new org.zstack.sdk.sns.CreateSNSTopicAction() + def addSNSFeiShuAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.AddSNSFeiShuAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.AddSNSFeiShuAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40183,8 +52057,8 @@ abstract class ApiHelper { } - def deleteSNSApplicationEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.DeleteSNSApplicationEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.DeleteSNSApplicationEndpointAction() + def createSNSFeiShuEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.CreateSNSFeiShuEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.CreateSNSFeiShuEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40210,13 +52084,15 @@ abstract class ApiHelper { } - def deleteSNSApplicationPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.DeleteSNSApplicationPlatformAction.class) Closure c) { - def a = new org.zstack.sdk.sns.DeleteSNSApplicationPlatformAction() + def querySNSFeiShuAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.QuerySNSFeiShuAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.QuerySNSFeiShuAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40237,13 +52113,15 @@ abstract class ApiHelper { } - def deleteSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.DeleteSNSTopicAction.class) Closure c) { - def a = new org.zstack.sdk.sns.DeleteSNSTopicAction() + def querySNSFeiShuEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.QuerySNSFeiShuEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.QuerySNSFeiShuEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40264,15 +52142,13 @@ abstract class ApiHelper { } - def querySNSApplicationEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSApplicationEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.QuerySNSApplicationEndpointAction() + def removeSNSFeiShuAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.RemoveSNSFeiShuAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.RemoveSNSFeiShuAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40293,15 +52169,13 @@ abstract class ApiHelper { } - def querySNSApplicationPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSApplicationPlatformAction.class) Closure c) { - def a = new org.zstack.sdk.sns.QuerySNSApplicationPlatformAction() + def sNSFeiShuTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.SNSFeiShuTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.SNSFeiShuTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40322,15 +52196,13 @@ abstract class ApiHelper { } - def querySNSSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSSmsEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.QuerySNSSmsEndpointAction() + def updateAtPersonOfAtFeiShuEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.UpdateAtPersonOfAtFeiShuEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.UpdateAtPersonOfAtFeiShuEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40351,15 +52223,40 @@ abstract class ApiHelper { } - def querySNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSTopicAction.class) Closure c) { - def a = new org.zstack.sdk.sns.QuerySNSTopicAction() + def updateSNSFeiShuEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.feishu.UpdateSNSFeiShuEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.feishu.UpdateSNSFeiShuEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + + def createSNSHttpEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.http.CreateSNSHttpEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.http.CreateSNSHttpEndpointAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40380,8 +52277,8 @@ abstract class ApiHelper { } - def querySNSTopicSubscriber(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.QuerySNSTopicSubscriberAction.class) Closure c) { - def a = new org.zstack.sdk.sns.QuerySNSTopicSubscriberAction() + def querySNSHttpEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.http.QuerySNSHttpEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.http.QuerySNSHttpEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40409,8 +52306,8 @@ abstract class ApiHelper { } - def removeSNSSmsReceiver(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.RemoveSNSSmsReceiverAction.class) Closure c) { - def a = new org.zstack.sdk.sns.RemoveSNSSmsReceiverAction() + def sNSHttpTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.http.SNSHttpTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.http.SNSHttpTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40436,8 +52333,8 @@ abstract class ApiHelper { } - def subscribeSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.SubscribeSNSTopicAction.class) Closure c) { - def a = new org.zstack.sdk.sns.SubscribeSNSTopicAction() + def updateSNSHttpEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.http.UpdateSNSHttpEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.http.UpdateSNSHttpEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40463,8 +52360,8 @@ abstract class ApiHelper { } - def unsubscribeSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UnsubscribeSNSTopicAction.class) Closure c) { - def a = new org.zstack.sdk.sns.UnsubscribeSNSTopicAction() + def createSNSMicrosoftTeamsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.microsoftteams.CreateSNSMicrosoftTeamsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.microsoftteams.CreateSNSMicrosoftTeamsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40490,13 +52387,15 @@ abstract class ApiHelper { } - def updateSNSApplicationEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UpdateSNSApplicationEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.UpdateSNSApplicationEndpointAction() + def querySNSMicrosoftTeamsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.microsoftteams.QuerySNSMicrosoftTeamsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.microsoftteams.QuerySNSMicrosoftTeamsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40517,8 +52416,8 @@ abstract class ApiHelper { } - def updateSNSApplicationPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UpdateSNSApplicationPlatformAction.class) Closure c) { - def a = new org.zstack.sdk.sns.UpdateSNSApplicationPlatformAction() + def sNSMicrosoftTeamsTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.microsoftteams.SNSMicrosoftTeamsTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.microsoftteams.SNSMicrosoftTeamsTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40544,8 +52443,8 @@ abstract class ApiHelper { } - def updateSNSTopic(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.UpdateSNSTopicAction.class) Closure c) { - def a = new org.zstack.sdk.sns.UpdateSNSTopicAction() + def updateSNSMicrosoftTeamsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.microsoftteams.UpdateSNSMicrosoftTeamsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.microsoftteams.UpdateSNSMicrosoftTeamsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40571,8 +52470,8 @@ abstract class ApiHelper { } - def createSNSAliyunSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.aliyunsms.CreateSNSAliyunSmsEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.aliyunsms.CreateSNSAliyunSmsEndpointAction() + def createSNSPluginEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.plugin.CreateSNSPluginEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.plugin.CreateSNSPluginEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40598,13 +52497,15 @@ abstract class ApiHelper { } - def validateSNSAliyunSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.aliyunsms.ValidateSNSAliyunSmsEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.aliyunsms.ValidateSNSAliyunSmsEndpointAction() + def querySNSPluginEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.plugin.QuerySNSPluginEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.plugin.QuerySNSPluginEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40625,8 +52526,8 @@ abstract class ApiHelper { } - def addSNSDingTalkAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.AddSNSDingTalkAtPersonAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.dingtalk.AddSNSDingTalkAtPersonAction() + def createSNSSnmpEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.snmp.CreateSNSSnmpEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.snmp.CreateSNSSnmpEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40652,8 +52553,8 @@ abstract class ApiHelper { } - def createSNSDingTalkEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.CreateSNSDingTalkEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.dingtalk.CreateSNSDingTalkEndpointAction() + def createSNSSnmpPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.snmp.CreateSNSSnmpPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.snmp.CreateSNSSnmpPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40679,8 +52580,8 @@ abstract class ApiHelper { } - def querySNSDingTalkEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.QuerySNSDingTalkEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.dingtalk.QuerySNSDingTalkEndpointAction() + def querySNSSnmpPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.snmp.QuerySNSSnmpPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.snmp.QuerySNSSnmpPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40708,8 +52609,8 @@ abstract class ApiHelper { } - def removeSNSDingTalkAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.dingtalk.RemoveSNSDingTalkAtPersonAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.dingtalk.RemoveSNSDingTalkAtPersonAction() + def sNSSnmpTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.snmp.SNSSnmpTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.snmp.SNSSnmpTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40735,8 +52636,8 @@ abstract class ApiHelper { } - def addEmailAddressToSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.AddEmailAddressToSNSEmailEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.AddEmailAddressToSNSEmailEndpointAction() + def updateSNSSnmpPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.snmp.UpdateSNSSnmpPlatformAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.snmp.UpdateSNSSnmpPlatformAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40762,8 +52663,8 @@ abstract class ApiHelper { } - def createSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.CreateSNSEmailEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.CreateSNSEmailEndpointAction() + def createSNSUniversalSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.universalsms.CreateSNSUniversalSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.universalsms.CreateSNSUniversalSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40789,13 +52690,15 @@ abstract class ApiHelper { } - def createSNSEmailPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.CreateSNSEmailPlatformAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.CreateSNSEmailPlatformAction() + def querySNSUniversalSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.universalsms.QuerySNSUniversalSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.universalsms.QuerySNSUniversalSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40816,8 +52719,8 @@ abstract class ApiHelper { } - def deleteEmailAddressOfSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.DeleteEmailAddressOfSNSEmailEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.DeleteEmailAddressOfSNSEmailEndpointAction() + def updateSNSUniversalSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.universalsms.UpdateSNSUniversalSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.universalsms.UpdateSNSUniversalSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -40843,15 +52746,13 @@ abstract class ApiHelper { } - def querySNSEmailAddress(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.QuerySNSEmailAddressAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.QuerySNSEmailAddressAction() + def validateSNSUniversalSmsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.universalsms.ValidateSNSUniversalSmsEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.universalsms.ValidateSNSUniversalSmsEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40872,15 +52773,13 @@ abstract class ApiHelper { } - def querySNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.QuerySNSEmailEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.QuerySNSEmailEndpointAction() + def addSNSWeComAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.AddSNSWeComAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.AddSNSWeComAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40901,15 +52800,13 @@ abstract class ApiHelper { } - def querySNSEmailPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.QuerySNSEmailPlatformAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.QuerySNSEmailPlatformAction() + def createSNSWeComEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.CreateSNSWeComEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.CreateSNSWeComEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40930,13 +52827,15 @@ abstract class ApiHelper { } - def updateEmailAddressOfSNSEmailEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.UpdateEmailAddressOfSNSEmailEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.UpdateEmailAddressOfSNSEmailEndpointAction() + def querySNSWeComAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.QuerySNSWeComAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.QuerySNSWeComAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40957,13 +52856,15 @@ abstract class ApiHelper { } - def validateSNSEmailPlatform(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.email.ValidateSNSEmailPlatformAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.email.ValidateSNSEmailPlatformAction() + def querySNSWeComEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.QuerySNSWeComEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.QuerySNSWeComEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() + a.conditions = a.conditions.collect { it.toString() } + if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -40984,8 +52885,8 @@ abstract class ApiHelper { } - def createSNSHttpEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.http.CreateSNSHttpEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.http.CreateSNSHttpEndpointAction() + def removeSNSWeComAtPerson(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.RemoveSNSWeComAtPersonAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.RemoveSNSWeComAtPersonAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -41011,15 +52912,13 @@ abstract class ApiHelper { } - def querySNSHttpEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.http.QuerySNSHttpEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.http.QuerySNSHttpEndpointAction() + def sNSWeComTestConnection(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.SNSWeComTestConnectionAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.SNSWeComTestConnectionAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -41040,8 +52939,8 @@ abstract class ApiHelper { } - def createSNSMicrosoftTeamsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.microsoftteams.CreateSNSMicrosoftTeamsEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.microsoftteams.CreateSNSMicrosoftTeamsEndpointAction() + def updateAtPersonOfAtWeComEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.UpdateAtPersonOfAtWeComEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.UpdateAtPersonOfAtWeComEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a @@ -41067,15 +52966,13 @@ abstract class ApiHelper { } - def querySNSMicrosoftTeamsEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.microsoftteams.QuerySNSMicrosoftTeamsEndpointAction.class) Closure c) { - def a = new org.zstack.sdk.sns.platform.microsoftteams.QuerySNSMicrosoftTeamsEndpointAction() + def updateSNSWeComEndpoint(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.sns.platform.wecom.UpdateSNSWeComEndpointAction.class) Closure c) { + def a = new org.zstack.sdk.sns.platform.wecom.UpdateSNSWeComEndpointAction() a.sessionId = Test.currentEnvSpec?.session?.uuid c.resolveStrategy = Closure.OWNER_FIRST c.delegate = a c() - a.conditions = a.conditions.collect { it.toString() } - if (System.getProperty("apipath") != null) { if (a.apiId == null) { @@ -41839,6 +53736,33 @@ abstract class ApiHelper { } + def changeEventSubscriptionState(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.ChangeEventSubscriptionStateAction.class) Closure c) { + def a = new org.zstack.sdk.zwatch.alarm.ChangeEventSubscriptionStateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def createAlarm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.CreateAlarmAction.class) Closure c) { def a = new org.zstack.sdk.zwatch.alarm.CreateAlarmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -41893,6 +53817,33 @@ abstract class ApiHelper { } + def getTextTemplateArg(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.GetTextTemplateArgAction.class) Closure c) { + def a = new org.zstack.sdk.zwatch.alarm.GetTextTemplateArgAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def queryAlarm(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.QueryAlarmAction.class) Closure c) { def a = new org.zstack.sdk.zwatch.alarm.QueryAlarmAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -42389,6 +54340,33 @@ abstract class ApiHelper { } + def updateActiveAlarmTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.activealarm.api.UpdateActiveAlarmTemplateAction.class) Closure c) { + def a = new org.zstack.sdk.zwatch.alarm.activealarm.api.UpdateActiveAlarmTemplateAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def createSNSTextTemplate(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.alarm.sns.CreateSNSTextTemplateAction.class) Closure c) { def a = new org.zstack.sdk.zwatch.alarm.sns.CreateSNSTextTemplateAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -42933,6 +54911,33 @@ abstract class ApiHelper { } + def getPrometheusMetricLabelValue(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.api.GetPrometheusMetricLabelValueAction.class) Closure c) { + def a = new org.zstack.sdk.zwatch.api.GetPrometheusMetricLabelValueAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def getZWatchAlertHistogram(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.api.GetZWatchAlertHistogramAction.class) Closure c) { def a = new org.zstack.sdk.zwatch.api.GetZWatchAlertHistogramAction() a.sessionId = Test.currentEnvSpec?.session?.uuid @@ -43016,6 +55021,35 @@ abstract class ApiHelper { } + def queryAudit(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.api.QueryAuditAction.class) Closure c) { + def a = new org.zstack.sdk.zwatch.api.QueryAuditAction() + a.sessionId = Test.currentEnvSpec?.session?.uuid + c.resolveStrategy = Closure.OWNER_FIRST + c.delegate = a + c() + + a.conditions = a.conditions.collect { it.toString() } + + + if (System.getProperty("apipath") != null) { + if (a.apiId == null) { + a.apiId = Platform.uuid + } + + def tracker = new ApiPathTracker(a.apiId) + def out = errorOut(a.call()) + def path = tracker.getApiPath() + if (!path.isEmpty()) { + Test.apiPaths[a.class.name] = path.join(" --->\n") + } + + return out + } else { + return errorOut(a.call()) + } + } + + def queryEventRecord(@DelegatesTo(strategy = Closure.OWNER_FIRST, value = org.zstack.sdk.zwatch.api.QueryEventRecordAction.class) Closure c) { def a = new org.zstack.sdk.zwatch.api.QueryEventRecordAction() a.sessionId = Test.currentEnvSpec?.session?.uuid diff --git a/testlib/src/main/java/org/zstack/testlib/BeanConstructor.groovy b/testlib/src/main/java/org/zstack/testlib/BeanConstructor.groovy index 800b610d3a1..853fbd7ec3e 100755 --- a/testlib/src/main/java/org/zstack/testlib/BeanConstructor.groovy +++ b/testlib/src/main/java/org/zstack/testlib/BeanConstructor.groovy @@ -35,7 +35,9 @@ class BeanConstructor { "rest.xml", "eventlog.xml", "Progress.xml", - "externalService.xml" + "externalService.xml", + "cas.xml", + "upgrade.xml" ] private List xmls = [] diff --git a/testlib/src/main/java/org/zstack/testlib/BeanConstructorFactory.groovy b/testlib/src/main/java/org/zstack/testlib/BeanConstructorFactory.groovy new file mode 100644 index 00000000000..71f52677a22 --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/BeanConstructorFactory.groovy @@ -0,0 +1,19 @@ +package org.zstack.testlib + +import org.zstack.core.StartMode + +class BeanConstructorFactory { + + static BeanConstructor getBeanConstructor(StartMode mode) { + if (mode == null) { + return null + } + if (mode == StartMode.SIMULATOR) { + return new BeanConstructor() + }else if (mode == StartMode.MINIMAL) { + return new MinimalBeanConstructor() + }else { + return new WebBeanConstructor() + } + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy index d24664f2f54..8b678003075 100755 --- a/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/CephBackupStorageSpec.groovy @@ -11,10 +11,8 @@ import org.zstack.storage.ceph.backup.CephBackupStorageBase import org.zstack.storage.ceph.backup.CephBackupStorageMonBase import org.zstack.storage.ceph.backup.CephBackupStorageMonVO import org.zstack.storage.ceph.backup.CephBackupStorageMonVO_ -import org.zstack.storage.ceph.primary.CephPrimaryStorageBase import org.zstack.testlib.vfs.VFS import org.zstack.utils.gson.JSONObjectUtil - /** * Created by xing5 on 2017/2/20. */ @@ -134,7 +132,8 @@ class CephBackupStorageSpec extends BackupStorageSpec { totalCapacity: bspec.totalCapacity, replicatedSize: 3, diskUtilization: 0.67, - securityPolicy: DataSecurityPolicy.ErasureCode.toString() + securityPolicy: DataSecurityPolicy.ErasureCode.toString(), + relatedOsds: "osd.1" ) ] rsp.poolCapacities = poolCapacities @@ -222,10 +221,15 @@ class CephBackupStorageSpec extends BackupStorageSpec { } simulator(CephBackupStorageMonBase.ECHO_PATH) { HttpEntity entity -> - Spec.checkHttpCallType(entity, true) + checkHttpCallType(entity, true) return [:] } + simulator(CephBackupStorageMonBase.CONNECT_PATH) { HttpEntity entity -> + checkHttpCallType(entity, false) + return new CephBackupStorageMonBase.ConnectRsp() + } + simulator(CephBackupStorageBase.CEPH_TO_CEPH_MIGRATE_IMAGE_PATH) { HttpEntity entity -> return new CephBackupStorageBase.StorageMigrationRsp() } diff --git a/testlib/src/main/java/org/zstack/testlib/CephPrimaryStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/CephPrimaryStorageSpec.groovy index 5e1b8a5246b..e8f90f1d110 100755 --- a/testlib/src/main/java/org/zstack/testlib/CephPrimaryStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/CephPrimaryStorageSpec.groovy @@ -4,29 +4,23 @@ import org.apache.commons.lang.StringEscapeUtils import org.springframework.http.HttpEntity import org.zstack.core.Platform import org.zstack.core.db.Q -import org.zstack.header.storage.primary.PrimaryStorageVO import org.zstack.header.volume.VolumeVO import org.zstack.header.volume.VolumeVO_ import org.zstack.kvm.KVMAgentCommands import org.zstack.sdk.PrimaryStorageInventory import org.zstack.storage.ceph.CephConstants +import org.zstack.storage.ceph.CephMonSystemTags import org.zstack.storage.ceph.CephPoolCapacity +import org.zstack.storage.ceph.CephSystemTags import org.zstack.storage.ceph.DataSecurityPolicy -import org.zstack.storage.ceph.primary.CephPrimaryStorageBase -import org.zstack.storage.ceph.primary.CephPrimaryStorageMonBase -import org.zstack.storage.ceph.primary.CephPrimaryStorageMonVO -import org.zstack.storage.ceph.primary.CephPrimaryStorageMonVO_ -import org.zstack.storage.ceph.primary.CephPrimaryStorageVO -import org.zstack.storage.ceph.primary.CephPrimaryStorageVO_ +import org.zstack.storage.ceph.primary.* import org.zstack.testlib.vfs.CephRaw import org.zstack.testlib.vfs.VFS import org.zstack.testlib.vfs.VFSFile import org.zstack.utils.data.SizeUnit import org.zstack.utils.gson.JSONObjectUtil -import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO -import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolVO_ -import org.zstack.storage.ceph.primary.CephPrimaryStoragePoolType -import org.zstack.storage.ceph.CephSystemTags + +import javax.persistence.Tuple import java.nio.file.Path /** @@ -40,11 +34,11 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { @SpecParam Map monAddrs = [:] @SpecParam - String rootVolumePoolName = "pri-c-" + Platform.getUuid() + String rootVolumePoolName = "pri-v-r-" + Platform.getUuid() @SpecParam String dataVolumePoolName = "pri-v-d-" + Platform.getUuid() @SpecParam - String imageCachePoolName = "pri-v-r-" + Platform.getUuid() + String imageCachePoolName = "pri-c-" + Platform.getUuid() CephPrimaryStorageSpec(EnvSpec envSpec) { super(envSpec) @@ -72,6 +66,17 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { return str.startsWith("/") ? str : "/" + str } + + static List getSnapshotPaths(VFS VFS, String volumePath) { + List ret = new ArrayList<>() + VFS.walkFileSystem({ vfile -> + if (vfile.pathString().contains(volumePath) && vfile.pathString() != volumePath) { + ret.add(vfile) + } + }) + return ret + } + class CephPrimaryStorageStruct { String rootVolumePoolName String dataVolumePoolName @@ -133,7 +138,8 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { totalCapacity: rootSize, securityPolicy: DataSecurityPolicy.Copy.toString(), replicatedSize: 3, - diskUtilization: 0.33 + diskUtilization: 0.33, + relatedOsds: 'osd.1' ), new CephPoolCapacity( name: cspec.dataVolumePoolName, @@ -142,7 +148,8 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { totalCapacity: dataSize, securityPolicy: DataSecurityPolicy.Copy.toString(), replicatedSize: 3, - diskUtilization: 0.33 + diskUtilization: 0.33, + relatedOsds: 'osd.2' ), new CephPoolCapacity( name: cspec.imageCachePoolName, @@ -151,7 +158,8 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { totalCapacity: cacheSize, securityPolicy: DataSecurityPolicy.Copy.toString(), replicatedSize: 3, - diskUtilization: 0.33 + diskUtilization: 0.33, + relatedOsds: 'osd.3' ), ] rsp.poolCapacities = poolCapacities @@ -284,10 +292,15 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(CephPrimaryStorageMonBase.ECHO_PATH) { HttpEntity entity -> - Spec.checkHttpCallType(entity, true) + checkHttpCallType(entity, true) return [:] } + simulator(CephPrimaryStorageMonBase.CONNECT_PATH) { HttpEntity entity -> + checkHttpCallType(entity, false) + return new CephPrimaryStorageMonBase.ConnectRsp() + } + simulator(CephPrimaryStorageBase.CREATE_SNAPSHOT_PATH) { HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.CreateSnapshotCmd) assert !cmd.snapshotPath.contains("null") @@ -302,6 +315,9 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { VFS vfs = vfs(cmd, spec) String snapPath = cephPathToVFSPath(cmd.snapshotPath) + String volumePath = snapPath.split("@")[0] + vfs.Assert(vfs.exists(volumePath), "cannot find file[${volumePath}]") + if (!(cmd.skipOnExisting && vfs.exists(snapPath))) { vfs.createCephRaw(snapPath, 0L) } @@ -366,9 +382,11 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(CephPrimaryStorageBase.CLONE_PATH) { HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.CloneCmd.class) def rsp = new CephPrimaryStorageBase.CloneRsp() rsp.size = 0 rsp.actualSize = 0 + rsp.installPath = cmd.dstPath return rsp } @@ -417,6 +435,10 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } + simulator(CephPrimaryStorageBase.BATCH_GET_VOLUME_SIZE_PATH) { + return new CephPrimaryStorageBase.GetBatchVolumeSizeRsp() + } + VFS.vfsHook(CephPrimaryStorageBase.CP_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.CpCmd.class) VFS vfs = vfs(cmd, spec) @@ -432,7 +454,11 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { vfs.Assert(vfs.isFile(cephPathToVFSPath(cmd.installPath)), "cannot find the volume[${cmd.installPath}]") CephRaw f = vfs.getFile(cephPathToVFSPath(cmd.installPath)) rsp.size = f.getVirtualSize() - rsp.actualSize = f.getActualSize() + if (rsp.type == CephConstants.CEPH_MANUFACTURER_OPENSOURCE) { + rsp.actualSize = null + } else { + rsp.actualSize = f.getActualSize() + } return rsp } @@ -442,6 +468,8 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(CephPrimaryStorageBase.ROLLBACK_SNAPSHOT_PATH) { HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.RollbackSnapshotCmd.class) + assert cmd.capacityThreshold > 0 return new CephPrimaryStorageBase.RollbackSnapshotRsp() } @@ -468,13 +496,49 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { return new CephPrimaryStorageBase.AgentResponse() } - simulator(CephPrimaryStorageBase.ADD_POOL_PATH) { HttpEntity entity -> + simulator(CephPrimaryStorageBase.ADD_POOL_PATH) { HttpEntity entity, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(entity.body, CephPrimaryStorageBase.AddPoolCmd.class) + CephPrimaryStorageSpec cspec = spec.specByUuid(cmd.uuid) CephPrimaryStorageBase.AddPoolRsp rsp = new CephPrimaryStorageBase.AddPoolRsp() + rsp.totalCapacity = cspec.totalCapacity + rsp.availableCapacity = cspec.availableCapacity + long rootSize = cspec.availableCapacity / 3 + long dataSize = cspec.availableCapacity / 3 + long cacheSize = cspec.totalCapacity - rootSize - dataSize rsp.setAvailableCapacity(SizeUnit.GIGABYTE.toByte(100)) rsp.setTotalCapacity(SizeUnit.GIGABYTE.toByte(100)) List poolCapacities = [ + new CephPoolCapacity( + name: cspec.rootVolumePoolName, + availableCapacity: rootSize, + usedCapacity: cspec.totalCapacity - cspec.availableCapacity, + totalCapacity: rootSize, + securityPolicy: DataSecurityPolicy.Copy.toString(), + replicatedSize: 3, + diskUtilization: 0.33, + relatedOsds: 'osd.1' + ), + new CephPoolCapacity( + name: cspec.dataVolumePoolName, + availableCapacity: dataSize, + usedCapacity: 0, + totalCapacity: dataSize, + securityPolicy: DataSecurityPolicy.Copy.toString(), + replicatedSize: 3, + diskUtilization: 0.33, + relatedOsds: 'osd.2' + ), + new CephPoolCapacity( + name: cspec.imageCachePoolName, + availableCapacity: cacheSize, + usedCapacity: 0, + totalCapacity: cacheSize, + securityPolicy: DataSecurityPolicy.Copy.toString(), + replicatedSize: 3, + diskUtilization: 0.33, + relatedOsds: 'osd.3' + ), new CephPoolCapacity( name: cmd.poolName, availableCapacity: SizeUnit.GIGABYTE.toByte(100), @@ -482,7 +546,8 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { totalCapacity: SizeUnit.GIGABYTE.toByte(100), securityPolicy: DataSecurityPolicy.Copy.toString(), replicatedSize: 3, - diskUtilization: 0.33 + diskUtilization: 0.33, + relatedOsds: "osd.4" ) ] rsp.setPoolCapacities(poolCapacities) @@ -503,7 +568,7 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { return } - if (f.parent?.pathString() == snapshotPath) { + if (f.parent?.setVolumeChainInstallPaths() == snapshotPath) { children.add(f.pathString()) } } @@ -602,6 +667,18 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { .select(CephPrimaryStorageMonVO_.primaryStorageUuid) .eq(CephPrimaryStorageMonVO_.hostname, cmd.dstMonHostname) .findValue() + if (dstPrimaryStorageUuid == null) { + List ts = Q.New(CephPrimaryStorageMonVO.class) + .select(CephPrimaryStorageMonVO_.uuid, CephPrimaryStorageMonVO_.primaryStorageUuid) + .listTuple() + for (final def t in ts) { + String extraIp = CephMonSystemTags.EXTRA_IPS.getTokenByResourceUuid(t.get(0, String.class), CephMonSystemTags.EXTRA_IPS_TOKEN) + if (extraIp != null && extraIp.split(",").contains(cmd.dstMonHostname)) { + dstPrimaryStorageUuid = t.get(1, String.class) + break + } + } + } String dstFsid = Q.New(CephPrimaryStorageVO.class) .select(CephPrimaryStorageVO_.fsid) .eq(CephPrimaryStorageVO_.uuid, dstPrimaryStorageUuid) @@ -609,12 +686,11 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { VFS dstVfs = vfs1(dstFsid, spec, true) // confirm dst volume created String dstInstallPath = cephPathToVFSPath(cmd.dstInstallPath) + vfs.Assert(dstVfs.exists(dstInstallPath), "dst volume not found") if (srcInstallPath.contains("@")) { dstInstallPath = String.format("%s@%s", dstInstallPath, cmd.resourceUuid) - } - - if (dstVfs.exists(dstInstallPath)) { + } else { dstVfs.delete(dstInstallPath) } @@ -633,12 +709,7 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { VFS vfs = vfs(cmd, spec) String vfsPath = cephPathToVFSPath(cmd.volumePath) vfs.Assert(vfs.exists(vfsPath), "cannot find the volume[${cmd.volumePath}]") - List files = [] - vfs.walkFileSystem({ vfile -> - if (vfile.pathString().contains(vfsPath) && vfile.pathString() != vfsPath) { - files.add(vfile) - } - }) + List files = getSnapshotPaths(vfs, vfsPath) rsp.setSnapInfos(new ArrayList()) files.each { file -> @@ -656,6 +727,80 @@ class CephPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } + + simulator(CephPrimaryStorageBase.GET_BACKING_CHAIN_PATH) { HttpEntity e, EnvSpec spec -> + return new CephPrimaryStorageBase.GetBackingChainRsp() + } + + VFS.vfsHook(CephPrimaryStorageBase.GET_BACKING_CHAIN_PATH, espec) { CephPrimaryStorageBase.GetBackingChainRsp rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.GetBackingChainCmd.class) + VFS vfs = vfs(cmd, spec) + String vfsPath = cephPathToVFSPath(cmd.volumePath) + vfs.Assert(vfs.exists(vfsPath), "cannot find the volume[${cmd.volumePath}]") + + CephRaw file = vfs.getFile(vfsPath) + + while (file.parent != null) { + rsp.backingChain.add("ceph:/" + file.pathString()) + String parentPath = file.parent.pathString().split("@")[0] + vfs.Assert(vfs.exists(parentPath), "cannot find the parent[${file}]") + file = vfs.getFile(parentPath) + } + + return rsp + } + + simulator(CephPrimaryStorageBase.DELETE_VOLUME_CHAIN_PATH) { HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.DeleteVolumeChainCmd.class) + def rsp = new CephPrimaryStorageBase.DeleteVolumeChainRsp() + rsp.undeletedInstallPaths = [] + return rsp + } + + // TODO Need to implement ceph trash in VFS + VFS.vfsHook(CephPrimaryStorageBase.DELETE_VOLUME_CHAIN_PATH, espec) { CephPrimaryStorageBase.DeleteVolumeChainRsp rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.DeleteVolumeChainCmd.class) + VFS vfs = vfs(cmd, spec) + rsp.undeletedInstallPaths = [] + + for (String path : cmd.installPaths) { + String vfsPath = cephPathToVFSPath(path) + vfs.Assert(vfs.exists(vfsPath), "cannot find the volume[${vfsPath}]") + + if (vfsPath.contains("@")) { + vfs.delete(vfsPath) + String volPath = vfsPath.split("@")[0] + assert getSnapshotPaths(vfs, volPath).isEmpty() : "the volume[%s] has snapshots, cannot delete it".format(volPath) + vfs.delete(volPath) + } else { + assert getSnapshotPaths(vfs, vfsPath).isEmpty() : "the volume[%s] has snapshots, cannot delete it".format(vfsPath) + vfs.delete(vfsPath) + } + } + return rsp + } + + simulator(CephPrimaryStorageBase.CLAEN_TRASH_PATH) { HttpEntity e, EnvSpec spec -> + return new CephPrimaryStorageBase.CleanTrashRsp() + } + + simulator(CephPrimaryStorageBase.DOWNLOAD_BITS_FROM_REMOTE_TARGET_PATH) { HttpEntity e, EnvSpec spec -> + return new CephPrimaryStorageBase.DownloadBitsFromRemoteTargetRsp() + } + + VFS.vfsHook(CephPrimaryStorageBase.DOWNLOAD_BITS_FROM_REMOTE_TARGET_PATH, espec) { CephPrimaryStorageBase.AgentResponse rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, CephPrimaryStorageBase.DownloadBitsFromRemoteTargetCmd.class) + VFS vfs = vfs(cmd, spec) + + def pool = cephPathToVFSPath(cmd.primaryStorageInstallPath).split("/")[1] + def dir = cephPathToVFSPath(pool) + if (!vfs.exists(dir)) { + vfs.createDirectories(dir) + } + + vfs.createCephRaw(cephPathToVFSPath(cmd.primaryStorageInstallPath), 0L) + return rsp + } } } diff --git a/testlib/src/main/java/org/zstack/testlib/ConsoleProxySimulator.groovy b/testlib/src/main/java/org/zstack/testlib/ConsoleProxySimulator.groovy new file mode 100644 index 00000000000..851d9c0ca43 --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/ConsoleProxySimulator.groovy @@ -0,0 +1,39 @@ +package org.zstack.testlib + +import org.springframework.http.HttpEntity +import org.zstack.header.console.ConsoleConstants +import org.zstack.header.console.ConsoleProxyCommands +import org.zstack.utils.gson.JSONObjectUtil + +class ConsoleProxySimulator implements Simulator { + @Override + void registerSimulators(EnvSpec xspec) { + def simulator = { arg1, arg2 -> + xspec.simulator(arg1, arg2) + } + + simulator(ConsoleConstants.CONSOLE_PROXY_ESTABLISH_PROXY_PATH) { HttpEntity e -> + def cmd = JSONObjectUtil.toObject(e.body, ConsoleProxyCommands.EstablishProxyCmd.class) + def rsp = new ConsoleProxyCommands.EstablishProxyRsp() + return rsp + } + + simulator(ConsoleConstants.CONSOLE_PROXY_CHECK_PROXY_PATH) { HttpEntity e -> + def cmd = JSONObjectUtil.toObject(e.body, ConsoleProxyCommands.CheckAvailabilityCmd.class) + def rsp = new ConsoleProxyCommands.CheckAvailabilityRsp() + return rsp + } + + simulator(ConsoleConstants.CONSOLE_PROXY_DELETE_PROXY_PATH) { HttpEntity e -> + def cmd = JSONObjectUtil.toObject(e.body, ConsoleProxyCommands.DeleteProxyCmd.class) + def rsp = new ConsoleProxyCommands.DeleteProxyRsp() + return rsp + } + + simulator(ConsoleConstants.CONSOLE_PROXY_PING_PATH) { HttpEntity e -> + def cmd = JSONObjectUtil.toObject(e.body, ConsoleProxyCommands.PingCmd.class) + def rsp = new ConsoleProxyCommands.PingRsp() + return rsp + } + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy b/testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy index ba0bea02326..5491d321f1b 100755 --- a/testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/EnvSpec.groovy @@ -26,6 +26,7 @@ import org.zstack.header.image.ImageDeletionPolicyManager import org.zstack.header.message.Message import org.zstack.header.rest.RESTConstant import org.zstack.header.vm.VmInstanceDeletionPolicyManager +import org.zstack.header.vm.VmSchedHistoryVO import org.zstack.header.vo.EO import org.zstack.header.volume.VolumeDeletionPolicyManager import org.zstack.image.ImageGlobalConfig @@ -41,6 +42,9 @@ import org.zstack.sdk.sns.platform.dingtalk.CreateSNSDingTalkEndpointAction import org.zstack.sdk.sns.platform.email.CreateSNSEmailEndpointAction import org.zstack.sdk.sns.platform.email.CreateSNSEmailPlatformAction import org.zstack.sdk.sns.platform.http.CreateSNSHttpEndpointAction +import org.zstack.sdk.sns.platform.snmp.CreateSNSSnmpEndpointAction +import org.zstack.sdk.sns.platform.snmp.CreateSNSSnmpPlatformAction +import org.zstack.sdk.sns.platform.universalsms.CreateSNSUniversalSmsEndpointAction import org.zstack.sdk.zwatch.alarm.CreateAlarmAction import org.zstack.sdk.zwatch.alarm.DeleteAlarmAction import org.zstack.sdk.zwatch.alarm.SubscribeEventAction @@ -98,7 +102,7 @@ class EnvSpec extends ApiHelper implements Node { private ConcurrentHashMap defaultHttpPostHandlers = [:] protected ConcurrentHashMap> messageHandlers = [:] protected ConcurrentHashMap messageHandlerCounters = [:] - protected ConcurrentHashMap> notifiersOfReceivedMessages = [:] + protected ConcurrentHashMap> notifiersOfReceivedMessages = [:] protected ConcurrentHashMap> messagesWithoutReplies = [:] private ConcurrentHashMap> defaultMessageHandlers = [:] private ConcurrentHashMap> httpConditionHandlers = [:] @@ -160,6 +164,7 @@ class EnvSpec extends ApiHelper implements Node { [CreateSNSHttpEndpointAction.metaClass, CreateSNSHttpEndpointAction.Result.metaClass, DeleteSNSApplicationEndpointAction.class], [CreateSNSDingTalkEndpointAction.metaClass, CreateSNSDingTalkEndpointAction.Result.metaClass, DeleteSNSApplicationEndpointAction.class], [CreateSNSAliyunSmsEndpointAction.metaClass, CreateSNSAliyunSmsEndpointAction.Result.metaClass, DeleteSNSApplicationEndpointAction.class], + [CreateSNSUniversalSmsEndpointAction.metaClass, CreateSNSUniversalSmsEndpointAction.Result.metaClass, DeleteSNSApplicationEndpointAction.class], [CreateSNSTextTemplateAction.metaClass, CreateSNSTextTemplateAction.Result.metaClass, DeleteSNSTextTemplateAction.class], [CreateAliyunSmsSNSTextTemplateAction.metaClass, CreateAliyunSmsSNSTextTemplateAction.Result.metaClass, DeleteSNSTextTemplateAction.class], [CreateEmailMonitorTriggerActionAction.metaClass, CreateEmailMonitorTriggerActionAction.Result.metaClass, DeleteMonitorTriggerActionAction.class], @@ -175,6 +180,9 @@ class EnvSpec extends ApiHelper implements Node { [CreateAliyunProxyVSwitchAction.metaClass, CreateAliyunProxyVSwitchAction.Result.metaClass, DeleteAliyunProxyVSwitchAction.class], [CreateMonitorGroupAction.metaClass, CreateMonitorGroupAction.Result.metaClass, DeleteMonitorGroupAction.class], [CreateMonitorTemplateAction.metaClass, CreateMonitorTemplateAction.Result.metaClass, DeleteMonitorTemplateAction.class], + [CreateDirectoryAction.metaClass, CreateDirectoryAction.Result.metaClass, DeleteDirectoryAction.class], + [CreateSNSSnmpPlatformAction.metaClass, CreateSNSSnmpPlatformAction.Result.metaClass, DeleteSNSApplicationPlatformAction.class], + [CreateSNSSnmpEndpointAction.metaClass, CreateSNSSnmpEndpointAction.Result.metaClass, DeleteSNSApplicationEndpointAction.class], ] static Closure GLOBAL_DELETE_HOOK @@ -214,6 +222,10 @@ class EnvSpec extends ApiHelper implements Node { dclasses.each { def action = it.getConstructor().newInstance() + if (delegate.value.inventory == null) { + return + } + logger.debug("auto-deleting resource by ${it} uuid:${delegate.value.inventory.uuid}") action.uuid = delegate.value.inventory.uuid action.sessionId = session.uuid @@ -532,7 +544,7 @@ class EnvSpec extends ApiHelper implements Node { logger.debug("Reset all global config started") CountDownLatch latch = new CountDownLatch(1) List errors = [] - new While<>(getChangedConfig()).all(new While.Do() { + new While<>(getChangedConfig()).each(new While.Do() { @Override void accept(GlobalConfigInventory config, WhileCompletion completion) { def ua = new UpdateGlobalConfigAction() @@ -686,13 +698,16 @@ class EnvSpec extends ApiHelper implements Node { "NetworkServiceTypeVO", "VmInstanceSequenceNumberVO", "BaremetalInstanceSequenceNumberVO", "BaremetalImageCacheVO", "GarbageCollectorVO", + "GuestOsCategoryVO", "TaskProgressVO", "TaskStepVO", - "ResourceVO","SecurityGroupSequenceNumberVO", "MediaVO", + "ResourceVO", "SecurityGroupSequenceNumberVO", "MediaVO", "CaptchaVO", "LoginAttemptsVO", "SchedulerJobHistoryVO", - "HistoricalPasswordVO", "BuildAppExportHistoryVO", "InstallPathRecycleVO", - "PortMirrorSessionSequenceNumberVO", "LicenseHistoryVO", "EventLogVO", - "EventRecordsVO", "AuditsVO", "AlarmRecordsVO", "VmCrashHistoryVO", "EncryptionIntegrityVO"]) { - // those tables will continue having entries during running a test suite + "HistoricalPasswordVO", "BuildAppExportHistoryVO", "InstallPathRecycleVO", + "PortMirrorSessionSequenceNumberVO", "LicenseHistoryVO", "EventLogVO", "VmSchedHistoryVO", + "EventRecordsVO", "AuditsVO", "AlarmRecordsVO", "VmCrashHistoryVO", "EncryptionIntegrityVO", "FileIntegrityVerificationVO", + "EncryptEntityMetadataVO", "VmInstanceDeviceAddressGroupVO", "HostOsCategoryVO", "KvmHostHypervisorMetadataVO", + "HaStrategyConditionVO", "SystemTagVO", "ConsoleProxyAgentVO", "ConsoleProxyVO", "XmlHookVO", "SSOServerTokenVO", + "HostNetworkLabelVO", "L3NetworkSequenceNumberVO"]) { return } @@ -837,9 +852,9 @@ class EnvSpec extends ApiHelper implements Node { callDeleteOnResourcesNeedDeletion() SQL.New(EventLogVO.class).hardDelete() + SQL.New(VmSchedHistoryVO).hardDelete() SQL.New(TaskProgressVO.class).hardDelete() SQL.New(SessionVO.class).hardDelete() - SQL.New(GuestOsCategoryVO.class).hardDelete() if (GLOBAL_DELETE_HOOK != null) { GLOBAL_DELETE_HOOK() @@ -1034,6 +1049,8 @@ class EnvSpec extends ApiHelper implements Node { ret = handler() } else if (handler.maximumNumberOfParameters == 1) { ret = handler(entity) + } else if (handler.maximumNumberOfParameters >= 3) { + ret = handler(req, entity, this) } else { ret = handler(entity, this) } @@ -1041,7 +1058,8 @@ class EnvSpec extends ApiHelper implements Node { Closure postHandler = httpPostHandlers[url] if (postHandler == null) { - for (String httpUrl : httpPostHandlers.keys()) { + List keys = (httpHandlers.keySet() as List).sort {a, b -> b.size() - a.size() } + for (String httpUrl : keys) { if (Pattern.matches(httpUrl, url)) { postHandler = httpPostHandlers.get(httpUrl) break @@ -1106,7 +1124,8 @@ class EnvSpec extends ApiHelper implements Node { def handler = httpHandlers[url] if (handler == null) { - for (String httpUrl : httpHandlers.keys()) { + List keys = (httpHandlers.keySet() as List).sort {a, b -> b.size() - a.size() } + for (String httpUrl : keys) { if (Pattern.matches(httpUrl, url)) { handler = httpHandlers.get(httpUrl) break diff --git a/testlib/src/main/java/org/zstack/testlib/ExternalPrimaryStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/ExternalPrimaryStorageSpec.groovy new file mode 100644 index 00000000000..19dedb00cce --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/ExternalPrimaryStorageSpec.groovy @@ -0,0 +1,258 @@ +package org.zstack.testlib + +import org.springframework.http.HttpEntity +import org.zstack.cbd.LogicalPoolInfo +import org.zstack.cbd.kvm.KvmCbdCommands +import org.zstack.kvm.KVMAgentCommands +import org.zstack.sdk.PrimaryStorageInventory +import org.zstack.storage.zbs.ZbsPrimaryStorageMdsBase +import org.zstack.storage.zbs.ZbsStorageController +import org.zstack.utils.Utils +import org.zstack.utils.data.SizeUnit +import org.zstack.utils.logging.CLogger +import org.zstack.utils.gson.JSONObjectUtil + +/** + * @author Xingwei Yu + * @date 2024/4/19 下午2:28 + */ +class ExternalPrimaryStorageSpec extends PrimaryStorageSpec { + private static final CLogger logger = Utils.getLogger(ExternalPrimaryStorageSpec.class); + + @SpecParam(required = true) + String identity + @SpecParam(required = true) + String defaultOutputProtocol + @SpecParam(required = true) + String config + @SpecParam(required = true) + String url + + ExternalPrimaryStorageSpec(EnvSpec envSpec) { + super(envSpec) + } + + static class Simulators implements Simulator { + @Override + void registerSimulators(EnvSpec espec) { + def simulator = { arg1, arg2 -> + espec.simulator(arg1, arg2) + } + + def actualSize = SizeUnit.GIGABYTE.toByte(1) + def targetSize = SizeUnit.GIGABYTE.toByte(2) + + simulator(ZbsPrimaryStorageMdsBase.ECHO_PATH) { HttpEntity entity -> + checkHttpCallType(entity, true) + return [:] + } + + simulator(ZbsPrimaryStorageMdsBase.PING_PATH) { + ZbsPrimaryStorageMdsBase.PingRsp rsp = new ZbsPrimaryStorageMdsBase.PingRsp() + rsp.success = true + return rsp + } + + simulator(ZbsPrimaryStorageMdsBase.SYNC_METADATA_PATH) { + ZbsPrimaryStorageMdsBase.SyncMetadataRsp rsp = new ZbsPrimaryStorageMdsBase.SyncMetadataRsp() + rsp.success = true + rsp.externalAddr = "127.0.0.1" + return rsp + } + + simulator(ZbsStorageController.DEPLOY_CLIENT_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.DeployClientCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.DeployClientCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.DeployClientRsp() + rsp.success = true + + return rsp + } + + simulator(ZbsStorageController.UPDATE_HOST_DEPENDENCY_PATH) { HttpEntity e, EnvSpec spec -> + def rsp = new ZbsStorageController.UpdateHostDependencyRsp() + rsp.success = true + + return rsp + } + + simulator(ZbsStorageController.GET_FACTS_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.GetFactsCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.GetFactsCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.GetFactsRsp() + rsp.uuid = "123456789" + rsp.version = "1.6.1-for-test" + rsp.success = true + + return rsp + } + + simulator(ZbsStorageController.CHECK_HOST_STORAGE_CONNECTION_PATH) { HttpEntity e -> + ZbsStorageController.CheckHostStorageConnectionCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.CheckHostStorageConnectionCmd) + assert cmd.hostUuid != null + + def rsp = new ZbsStorageController.CheckHostStorageConnectionRsp() + rsp.success = true + + return rsp + } + + simulator(ZbsStorageController.GET_CAPACITY_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.GetCapacityCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.GetCapacityCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + LogicalPoolInfo.RedundanceAndPlaceMentPolicy redundanceAndPlaceMentPolicy = new LogicalPoolInfo.RedundanceAndPlaceMentPolicy() + redundanceAndPlaceMentPolicy.setCopysetNum(300) + redundanceAndPlaceMentPolicy.setReplicaNum(3) + redundanceAndPlaceMentPolicy.setZoneNum(3) + + LogicalPoolInfo logicalPoolInfo = new LogicalPoolInfo() + logicalPoolInfo.setPhysicalPoolID(1); + logicalPoolInfo.setRedundanceAndPlaceMentPolicy(redundanceAndPlaceMentPolicy); + logicalPoolInfo.setLogicalPoolID(1); + logicalPoolInfo.setUsedSize(322961408); + logicalPoolInfo.setQuota(0); + logicalPoolInfo.setCreateTime(1735875794); + logicalPoolInfo.setType(0); + logicalPoolInfo.setRawWalUsedSize(0); + logicalPoolInfo.setAllocateStatus(0); + logicalPoolInfo.setRawUsedSize(968884224); + logicalPoolInfo.setPhysicalPoolName("pool1"); + logicalPoolInfo.setCapacity(579933831168); + logicalPoolInfo.setLogicalPoolName(cmd.logicalPool); + logicalPoolInfo.setUserPolicy("eyJwb2xpY3kiIDogMX0="); + logicalPoolInfo.setAllocatedSize(3221225472); + + List logicalPoolInfos = new ArrayList<>() + logicalPoolInfos.add(logicalPoolInfo) + + def rsp = new ZbsStorageController.GetCapacityRsp() + rsp.setLogicalPoolInfos(logicalPoolInfos) + + return rsp + } + + simulator(ZbsStorageController.CREATE_VOLUME_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.CreateVolumeCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.CreateVolumeCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.CreateVolumeRsp() + rsp.setSize(actualSize) + rsp.setActualSize(actualSize) + rsp.setInstallPath(String.format("cbd:pool1/%s/%s", cmd.logicalPool, cmd.volume)) + + return rsp + } + + simulator(ZbsStorageController.DELETE_VOLUME_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.DeleteVolumeCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.DeleteVolumeCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + return new ZbsStorageController.DeleteVolumeRsp() + } + + simulator(ZbsStorageController.CREATE_SNAPSHOT_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.CreateSnapshotCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.CreateSnapshotCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.CreateSnapshotRsp() + rsp.setSize(actualSize) + rsp.setInstallPath(cmd.path + "@" + cmd.snapshot) + + return rsp + } + + simulator(ZbsStorageController.CLONE_VOLUME_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.CloneVolumeCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.CloneVolumeCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.CloneVolumeRsp() + rsp.setSize(actualSize) + // replace volume name + rsp.setInstallPath(cmd.path.replaceAll("([^/]+)\$", cmd.dstVolume)) + return rsp + } + + simulator(ZbsStorageController.QUERY_VOLUME_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.QueryVolumeCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.QueryVolumeCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.QueryVolumeRsp() + rsp.setSize(actualSize) + + return rsp + } + + simulator(ZbsStorageController.EXPAND_VOLUME_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.ExpandVolumeCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.ExpandVolumeCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.ExpandVolumeRsp() + rsp.setSize(targetSize) + + return rsp + } + + simulator(ZbsStorageController.COPY_PATH) { HttpEntity e, EnvSpec spec -> + ZbsStorageController.CopyCmd cmd = JSONObjectUtil.toObject(e.body, ZbsStorageController.CopyCmd.class) + ExternalPrimaryStorageSpec zspec = spec.specByUuid(cmd.uuid) + assert zspec != null: "cannot found zbs primary storage[uuid:${cmd.uuid}], check your environment()." + + def rsp = new ZbsStorageController.CopyRsp() + rsp.setInstallPath(cmd.path.replaceAll("([^/]+)\$", cmd.dstVolume)) + rsp.setSize(actualSize) + + return rsp + } + + + simulator(ZbsStorageController.GET_VOLUME_CLIENTS_PATH) { HttpEntity e, EnvSpec spec -> + return new ZbsStorageController.GetVolumeClientsRsp() + } + + simulator(KvmCbdCommands.SETUP_CBD_SELF_FENCER_PATH) { + return new KvmCbdCommands.AgentRsp() + } + + simulator(KvmCbdCommands.CANCEL_CBD_SELF_FENCER_PATH) { + return new KvmCbdCommands.AgentRsp() + } + } + } + + @Override + SpecID create(String uuid, String sessionId) { + inventory = addExternalPrimaryStorage { + delegate.resourceUuid = uuid + delegate.name = name + delegate.description = description + delegate.url = url + delegate.sessionId = sessionId + delegate.zoneUuid = (parent as ZoneSpec).inventory.uuid + delegate.userTags = userTags + delegate.systemTags = systemTags + delegate.identity = identity + delegate.config = config + delegate.defaultOutputProtocol = defaultOutputProtocol + } as PrimaryStorageInventory + + postCreate { + inventory = queryPrimaryStorage { + conditions=["uuid=${inventory.uuid}".toString()] + }[0] + } + + return id(name, inventory.uuid) + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/FlatnetworkSimualtor.groovy b/testlib/src/main/java/org/zstack/testlib/FlatnetworkSimualtor.groovy index 79d2043f53b..6e01809ebba 100755 --- a/testlib/src/main/java/org/zstack/testlib/FlatnetworkSimualtor.groovy +++ b/testlib/src/main/java/org/zstack/testlib/FlatnetworkSimualtor.groovy @@ -41,6 +41,17 @@ class FlatnetworkSimualtor implements Simulator { return new FlatDhcpBackend.DeleteNamespaceRsp() } + spec.simulator(FlatDhcpBackend.DHCP_FLUSH_NAMESPACE_PATH) { + return new FlatDhcpBackend.FlushDhcpNamespaceRsp() + } + + spec.simulator(FlatDhcpBackend.ARPING_NAMESPACE_PATH) { + Map> result = new HashMap<>() + FlatDhcpBackend.ArpingRsp rsp = new FlatDhcpBackend.ArpingRsp() + rsp.result = result + return rsp + } + spec.simulator(FlatDhcpBackend.DHCP_CONNECT_PATH) { return new FlatDhcpBackend.ConnectRsp() } diff --git a/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy b/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy index 07e04f92c35..6e77c2dfeda 100755 --- a/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy +++ b/testlib/src/main/java/org/zstack/testlib/KVMSimulator.groovy @@ -1,33 +1,26 @@ package org.zstack.testlib -import com.google.common.collect.ImmutableMap import org.springframework.http.HttpEntity import org.zstack.core.db.Q import org.zstack.core.db.SQL +import org.zstack.core.db.SQLBatch import org.zstack.header.Constants -import org.zstack.header.host.HostNUMANode import org.zstack.header.storage.primary.PrimaryStorageVO import org.zstack.header.storage.primary.PrimaryStorageVO_ import org.zstack.header.storage.snapshot.TakeSnapshotsOnKvmJobStruct import org.zstack.header.storage.snapshot.TakeSnapshotsOnKvmResultStruct -import org.zstack.header.storage.snapshot.VolumeSnapshotVO -import org.zstack.header.storage.snapshot.VolumeSnapshotVO_ -import org.zstack.header.vm.VmInstanceState -import org.zstack.header.vm.VmInstanceVO -import org.zstack.header.vm.VmInstanceVO_ -import org.zstack.core.db.SQLBatch -import org.zstack.header.Constants -import org.zstack.header.storage.primary.PrimaryStorageVO -import org.zstack.header.storage.primary.PrimaryStorageVO_ import org.zstack.header.vm.VmInstanceState import org.zstack.header.vm.VmInstanceVO import org.zstack.header.vm.VmInstanceVO_ +import org.zstack.header.vm.devices.DeviceAddress +import org.zstack.header.vm.devices.VirtualDeviceInfo import org.zstack.header.volume.VolumeInventory import org.zstack.header.volume.VolumeVO import org.zstack.header.volume.VolumeVO_ import org.zstack.kvm.KVMAgentCommands import org.zstack.kvm.KVMConstant import org.zstack.kvm.VolumeTO +import org.zstack.testlib.vfs.Qcow2 import org.zstack.testlib.vfs.VFS import org.zstack.testlib.vfs.extensions.VFSPrimaryStorageTakeSnapshotBackend import org.zstack.testlib.vfs.extensions.VFSSnapshot @@ -38,6 +31,7 @@ import org.zstack.utils.gson.JSONObjectUtil import javax.persistence.Tuple import java.util.concurrent.ConcurrentHashMap +import static org.zstack.kvm.KVMAgentCommands.* /** * Created by xing5 on 2017/6/6. */ @@ -141,6 +135,54 @@ class KVMSimulator implements Simulator { return rsp } + spec.simulator(KVMConstant.GET_VIRTUALIZER_INFO_PATH) { HttpEntity e -> + def rsp = new GetVirtualizerInfoRsp() + rsp.hostInfo = new VirtualizerInfoTO() + rsp.hostInfo.version = "4.2.0-627.g36ee592.el7" + rsp.hostInfo.virtualizer = "qemu-kvm" + String hostUuid = e.getHeaders().getFirst(Constants.AGENT_HTTP_HEADER_RESOURCE_UUID) + rsp.hostInfo.uuid = hostUuid + + def cmd = JSONObjectUtil.toObject(e.body, GetVirtualizerInfoCmd.class) + rsp.vmInfoList = cmd.vmUuids.collect { vmUuid -> + def to = new VirtualizerInfoTO() + to.uuid = vmUuid + to.version = "4.2.0-627.g36ee592.el7" + to.virtualizer = "qemu-kvm" + return to + } + + return rsp + } + + spec.simulator(KVMConstant.KVM_HOST_FACT_PATH) { HttpEntity e -> + def hostUuid = e.getHeaders().getFirst(Constants.AGENT_HTTP_HEADER_RESOURCE_UUID) + def rsp = new HostFactResponse() + + rsp.osDistribution = "zstack" + rsp.osRelease = "kvmSimulator" + rsp.osVersion = "0.1" + rsp.qemuImgVersion = "2.0.0" + rsp.libvirtVersion = "1.2.9" + rsp.cpuModelName = "Broadwell" + rsp.cpuProcessorNum = "10" + rsp.cpuGHz = "2.10" + rsp.hostCpuModelName = "Broadwell @ 2.10GHz" + rsp.ipmiAddress = "None" + rsp.eptFlag = "ept" + rsp.libvirtCapabilities = ["incrementaldrivemirror", "blockcopynetworktarget"] + rsp.powerSupplyModelName = "" + rsp.powerSupplyManufacturer = "" + rsp.hvmCpuFlag = "" + rsp.cpuCache = "64.0,4096.0,16384.0" + rsp.iscsiInitiatorName = "iqn.1994-05.com.redhat:" + hostUuid.substring(0, 12) + + rsp.virtualizerInfo = new VirtualizerInfoTO() + rsp.virtualizerInfo.version = "4.2.0-627.g36ee592.el7" + rsp.virtualizerInfo.virtualizer = "qemu-kvm" + return rsp + } + spec.simulator(KVMConstant.KVM_VM_UPDATE_PRIORITY_PATH) { return new KVMAgentCommands.UpdateVmPriorityRsp() } @@ -162,8 +204,13 @@ class KVMSimulator implements Simulator { return rsp } - spec.simulator(KVMConstant.KVM_ATTACH_NIC_PATH) { - return new KVMAgentCommands.AttachNicResponse() + spec.simulator(KVMConstant.KVM_ATTACH_NIC_PATH) { HttpEntity e -> + KVMAgentCommands.AttachNicCommand cmd = JSONObjectUtil.toObject(e.body, KVMAgentCommands.AttachNicCommand.class) + KVMAgentCommands.AttachNicResponse rsp = new KVMAgentCommands.AttachNicResponse() + VirtualDeviceInfo deviceInfo = new VirtualDeviceInfo() + deviceInfo.setResourceUuid(cmd.nic.getUuid()) + rsp.setVirtualDeviceInfoList(Arrays.asList(deviceInfo)) + return rsp } spec.simulator(KVMConstant.KVM_DETACH_NIC_PATH) { @@ -261,7 +308,6 @@ class KVMSimulator implements Simulator { rsp.success = true rsp.libvirtVersion = "1.0.0" rsp.qemuVersion = "1.3.0" - rsp.iptablesSucc = true return rsp } @@ -299,6 +345,10 @@ class KVMSimulator implements Simulator { return rsp } + spec.simulator(KVMConstant.KVM_VOLUME_SYNC_PATH) { + return new VolumeSyncRsp() + } + spec.simulator(KVMConstant.KVM_ATTACH_VOLUME) { HttpEntity e -> def cmd = JSONObjectUtil.toObject(e.body, KVMAgentCommands.AttachDataVolumeCmd.class) // assume all data volumes has same deviceType. @@ -326,6 +376,22 @@ class KVMSimulator implements Simulator { return new KVMAgentCommands.MigrateVmResponse() } + spec.simulator(KVMConstant.KVM_GET_CPU_XML_PATH) { + return new KVMAgentCommands.VmGetCpuXmlResponse() + } + + spec.simulator(KVMConstant.KVM_COMPARE_CPU_FUNCTION_PATH) { + return new KVMAgentCommands.VmCompareCpuFunctionResponse() + } + + spec.simulator(KVMConstant.KVM_UPDATE_L2VLAN_NETWORK_PATH) { + return new KVMAgentCommands.UpdateL2NetworkResponse() + } + + spec.simulator(KVMConstant.KVM_UPDATE_L2VXLAN_NETWORK_PATH) { + return new KVMAgentCommands.UpdateL2NetworkResponse() + } + spec.simulator(KVMConstant.KVM_CHECK_L2NOVLAN_NETWORK_PATH) { return new KVMAgentCommands.CheckBridgeResponse() } @@ -365,10 +431,80 @@ class KVMSimulator implements Simulator { return new KVMAgentCommands.AgentResponse() } + spec.simulator(KVMConstant.KVM_GENERATE_VHOST_USER_CLIENT_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_DELETE_VHOST_USER_CLIENT_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_INSTALL_OVS_PACKAGE_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_UNINSTALL_OVS_PACKAGE_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_START_OVS_SERVICE_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_STOP_OVS_SERVICE_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_OVS_ADD_PORT_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_OVS_DEL_PORT_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_SYNC_VM_DEVICEINFO_PATH) { HttpEntity e -> + SyncVmDeviceInfoCmd cmd = JSONObjectUtil.toObject(e.body, SyncVmDeviceInfoCmd.class) + def rsp = new SyncVmDeviceInfoResponse() + + rsp.virtualizerInfo = new VirtualizerInfoTO() + rsp.virtualizerInfo.uuid = cmd.vmInstanceUuid + rsp.virtualizerInfo.virtualizer = "qemu-kvm" + rsp.virtualizerInfo.version = "4.2.0-632.g6a6222b.el7" + + return rsp + } + spec.simulator(KVMConstant.KVM_START_VM_PATH) { HttpEntity e -> - KVMAgentCommands.StartVmCmd cmd = JSONObjectUtil.toObject(e.body, KVMAgentCommands.StartVmCmd.class) + StartVmCmd cmd = JSONObjectUtil.toObject(e.body, StartVmCmd.class) assert new HashSet<>(cmd.dataVolumes.deviceId).size() == cmd.dataVolumes.size() - return new KVMAgentCommands.StartVmResponse() + StartVmResponse rsp = new StartVmResponse() + rsp.virtualDeviceInfoList = [] + List pciInfo = new ArrayList() + pciInfo.add(cmd.rootVolume) + pciInfo.addAll(cmd.dataVolumes) + + Integer counter = 0 + pciInfo.each { to -> + VirtualDeviceInfo info = new VirtualDeviceInfo() + info.resourceUuid = to.volumeUuid + info.deviceAddress = new DeviceAddress() + info.deviceAddress.domain = "0000" + info.deviceAddress.bus = "00" + info.deviceAddress.slot = Integer.toHexString(counter) + info.deviceAddress.function = "0" + + counter++ + + rsp.virtualDeviceInfoList.add(info) + } + + rsp.virtualizerInfo = new VirtualizerInfoTO() + rsp.virtualizerInfo.uuid = cmd.vmInstanceUuid + rsp.virtualizerInfo.virtualizer = "qemu-kvm" + rsp.virtualizerInfo.version = "4.2.0-632.g6a6222b.el7" + + return rsp } spec.simulator(KVMConstant.KVM_STOP_VM_PATH) { @@ -464,5 +600,80 @@ class KVMSimulator implements Simulator { def rsp = new KVMAgentCommands.GetHostNUMATopologyResponse() return rsp } + + spec.simulator(KVMConstant.KVM_HOST_ATTACH_VOLUME_PATH) { + def rsp = new KVMAgentCommands.AttachVolumeRsp() + rsp.device = "/dev/nbd0" + return rsp + } + + spec.simulator(KVMConstant.KVM_HOST_DETACH_VOLUME_PATH) { + def rsp = new KVMAgentCommands.DetachVolumeRsp() + return rsp + } + + spec.simulator(KVMConstant.KVM_BLOCK_COMMIT_VOLUME_PATH) { HttpEntity e -> + def rsp = new BlockCommitResponse() + rsp.size = 1 + return rsp + } + + VFS.vfsHook(KVMConstant.KVM_BLOCK_COMMIT_VOLUME_PATH, spec) { rsp, HttpEntity e, EnvSpec espec -> + BlockCommitCmd cmd = JSONObjectUtil.toObject(e.body, BlockCommitCmd.class) + + VolumeVO volume = Q.New(VolumeVO.class).eq(VolumeVO_.uuid, cmd.volume.getVolumeUuid()).find() + assert volume : "cannot find volume[uuid: ${cmd.volume.getVolumeUuid()}]" + + String primaryStorageType = Q.New(PrimaryStorageVO.class).select(PrimaryStorageVO_.type) + .eq(PrimaryStorageVO_.uuid, volume.primaryStorageUuid).findValue() + assert primaryStorageType : "cannot find primary storage[uuid: ${volume.primaryStorageUuid}] " + + "from volume[uuid: ${volume.uuid}, name: ${volume.name}]" + + VFSPrimaryStorageTakeSnapshotBackend bkd = getVFSPrimaryStorageTakeSnapshotBackend(primaryStorageType) + bkd.blockCommit(e, espec, cmd, volume.toInventory() as VolumeInventory) + return rsp + } + + spec.simulator(KVMConstant.KVM_BLOCK_PULL_VOLUME_PATH) { HttpEntity e -> + def rsp = new BlockPullResponse() + rsp.size = 1 + return rsp + } + + VFS.vfsHook(KVMConstant.KVM_BLOCK_PULL_VOLUME_PATH, spec) { BlockPullResponse rsp, HttpEntity e, EnvSpec espec -> + BlockPullCmd cmd = JSONObjectUtil.toObject(e.body, BlockPullCmd.class) + + VolumeVO volume = Q.New(VolumeVO.class).eq(VolumeVO_.uuid, cmd.volume.getVolumeUuid()).find() + assert volume : "cannot find volume[uuid: ${cmd.getVolume().getVolumeUuid()}]" + + String primaryStorageType = Q.New(PrimaryStorageVO.class).select(PrimaryStorageVO_.type) + .eq(PrimaryStorageVO_.uuid, volume.primaryStorageUuid).findValue() + assert primaryStorageType : "cannot find primary storage[uuid: ${volume.primaryStorageUuid}] " + + "from volume[uuid: ${volume.uuid}, name: ${volume.name}]" + + VFSPrimaryStorageTakeSnapshotBackend bkd = getVFSPrimaryStorageTakeSnapshotBackend(primaryStorageType) + + Qcow2 newInstallPath = bkd.blockPull(e, espec, cmd, volume.toInventory() as VolumeInventory) + rsp.size = newInstallPath.actualSize == 0 ? 1 : newInstallPath.actualSize + return rsp + } + + spec.simulator(KVMConstant.TAKE_VM_CONSOLE_SCREENSHOT_PATH) { + def rsp = new KVMAgentCommands.TakeVmConsoleScreenshotRsp() + rsp.imageData = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAABECAIAAADFvmZTAAACA0lEQVR4nO3VMYviQBQH8Hkvk5hE2ZUEU+juFlbKauH3/wYWNhYWKiiIRBDcZDckJJmZK6Zb7q44uJW7/f+qCcOQzP89XoSAL0FPT09VVTFzEARhGKZp2rat67qO4xhjlFJ5nidJcr1eHx8fPc+r65qZ27Zt2zbP83t//z9DRlFUVRURGWN83/c8z/O8Xq/HzFEUvb29aa211sxsgxZCKKWIKMuyPM9tSWypHMdRSmmtP72DmTudTlmWRCSl1Forpe5x2XuSSZJcLpeiKPr9flEUdV0LIZqm+fj4GI/H+/1+Npsdj8fX11chRFVV5/N5MBgIIZg5juP5fN7tdpfL5WAwiKJovV4Ph8MgCDabzWQyKcvycDgsFoskSVarlZTy+fl5t9udz2db2jvf/gsRETGz1tp13bZtbT8yszHGdqiNw66Z2W4ZY7TWUkqbl5TSGGOPSymFEHb+2Oa1u47jEFHTNFrrbxWxRQ8PD1LKuq7Lsux2u8zcNE1d10EQFEXR6XRc1yWiPM9937cxua6rlPrplIBfkS8vL2EYZlmWpul0OvV9/3Q6vb+/j0aj4/EYx3EYhkqp7XY7HA6TJDHG3G43IjocDnbsfsP2/OuIyP4P4U8Q0W8eAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgf/QDviYImvcayGAAAAAASUVORK5CYII=" + return rsp + } + + spec.simulator(KVMConstant.KVM_HOST_IPSET_ATTACH_NIC_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_HOST_IPSET_DETACH_NIC_PATH) { + return new KVMAgentCommands.AgentResponse() + } + + spec.simulator(KVMConstant.KVM_HOST_IPSET_SYNC_PATH) { + return new KVMAgentCommands.AgentResponse() + } } } diff --git a/testlib/src/main/java/org/zstack/testlib/L2NetworkSpec.groovy b/testlib/src/main/java/org/zstack/testlib/L2NetworkSpec.groovy index ff89d30beec..fabd5040c61 100755 --- a/testlib/src/main/java/org/zstack/testlib/L2NetworkSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/L2NetworkSpec.groovy @@ -14,6 +14,10 @@ abstract class L2NetworkSpec extends Spec { String physicalInterface @SpecParam String vSwitchType + @SpecParam + Boolean isolated = Boolean.FALSE + @SpecParam + String pvlan L2NetworkInventory inventory diff --git a/testlib/src/main/java/org/zstack/testlib/L2NoVlanNetworkSpec.groovy b/testlib/src/main/java/org/zstack/testlib/L2NoVlanNetworkSpec.groovy index 7fb056a7107..c33fc8be36c 100755 --- a/testlib/src/main/java/org/zstack/testlib/L2NoVlanNetworkSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/L2NoVlanNetworkSpec.groovy @@ -28,6 +28,8 @@ class L2NoVlanNetworkSpec extends L2NetworkSpec implements Simulator{ delegate.systemTags = systemTags delegate.zoneUuid = (parent as ZoneSpec).inventory.uuid delegate.vSwitchType = vSwitchType + delegate.isolated = isolated + delegate.pvlan = pvlan } postCreate { diff --git a/testlib/src/main/java/org/zstack/testlib/L2VlanNetworkSpec.groovy b/testlib/src/main/java/org/zstack/testlib/L2VlanNetworkSpec.groovy index e3313f0b162..005ab755f5c 100755 --- a/testlib/src/main/java/org/zstack/testlib/L2VlanNetworkSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/L2VlanNetworkSpec.groovy @@ -28,6 +28,8 @@ class L2VlanNetworkSpec extends L2NetworkSpec implements Simulator{ delegate.sessionId = sessionId delegate.zoneUuid = (parent as ZoneSpec).inventory.uuid delegate.vSwitchType = vSwitchType + delegate.isolated = isolated + delegate.pvlan = pvlan } as L2NetworkInventory postCreate { diff --git a/testlib/src/main/java/org/zstack/testlib/L3NetworkSpec.groovy b/testlib/src/main/java/org/zstack/testlib/L3NetworkSpec.groovy index 1e3ec9f72b6..cf84188e4ac 100755 --- a/testlib/src/main/java/org/zstack/testlib/L3NetworkSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/L3NetworkSpec.groovy @@ -15,6 +15,8 @@ class L3NetworkSpec extends Spec implements HasSession { String type = "L3BasicNetwork" @SpecParam Integer ipVersion = 4 + @SpecParam + Boolean enableIPAM = Boolean.TRUE L3NetworkInventory inventory @@ -35,6 +37,7 @@ class L3NetworkSpec extends Spec implements HasSession { delegate.type = type delegate.l2NetworkUuid = (parent as L2NetworkSpec).inventory.uuid delegate.ipVersion = ipVersion + delegate.enableIPAM = enableIPAM } postCreate { diff --git a/testlib/src/main/java/org/zstack/testlib/LocalStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/LocalStorageSpec.groovy index 82f3c889f7a..747ca4388b1 100755 --- a/testlib/src/main/java/org/zstack/testlib/LocalStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/LocalStorageSpec.groovy @@ -1,8 +1,6 @@ package org.zstack.testlib import org.springframework.http.HttpEntity -import org.zstack.core.Platform -import org.zstack.core.db.Q import org.zstack.compute.host.HostSystemTags import org.zstack.core.Platform import org.zstack.core.db.Q @@ -25,9 +23,7 @@ import org.zstack.testlib.vfs.VFSFile import org.zstack.testlib.vfs.Volume import org.zstack.utils.gson.JSONObjectUtil -import java.nio.file.Files import java.nio.file.Path - /** * Created by xing5 on 2017/2/20. */ @@ -78,31 +74,40 @@ class LocalStorageSpec extends PrimaryStorageSpec { simulator(LocalStorageKvmBackend.GET_BASE_IMAGE_PATH) { def rsp = new LocalStorageKvmBackend.GetVolumeBaseImagePathRsp() - rsp.path = "/some/patch" return rsp } VFS.vfsHook(LocalStorageKvmBackend.GET_BASE_IMAGE_PATH, espec) { LocalStorageKvmBackend.GetVolumeBaseImagePathRsp rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.GetVolumeBaseImagePathCmd.class) - Qcow2 file = vfs(e, cmd, spec).findFile { it.pathString().contains(cmd.volumeInstallDir) } + VFS vfs = vfs(e, cmd, spec) - if (file == null) { - rsp.path = null - rsp.size = 0 - } else { - Qcow2 baseImage = file.getBaseImage(file) - - if (baseImage == null) { - rsp.path = null - rsp.size = 0 - } else { - assert baseImage.pathString().contains(cmd.imageCacheDir) - rsp.path = baseImage.pathString() - rsp.size = baseImage.actualSize + Qcow2 qfile = vfs.getFile(cmd.volumeInstallPath) + if (qfile == null) { + logger.debug("Dump of whole VFS:\\n${vfs.dumpAsString()}") + } + assert qfile != null : "cannot find file[${cmd.volumeInstallPath}]" + while (qfile.backingFile != null) { + if (qfile.backingFile.toAbsolutePath().toString().startsWith(cmd.imageCacheDir)) { + rsp.path = qfile.backingFile.toAbsolutePath().toString() + rsp.size = qfile.backingQcow2().actualSize + break + } + + qfile = qfile.backingQcow2() + } + + rsp.otherPaths = [] + vfs.walkFileSystem { vfile -> + if (vfile.pathString().contains(cmd.volumeInstallDir)) { + qfile = vfile as Qcow2 + if (qfile.backingFile != null && qfile.backingFile.toAbsolutePath().toString().startsWith(cmd.imageCacheDir)) { + rsp.otherPaths.add(qfile.backingFile.toAbsolutePath().toString()) + } } } + rsp.otherPaths.remove(rsp.path) return rsp } @@ -115,13 +120,37 @@ class LocalStorageSpec extends PrimaryStorageSpec { Qcow2 file = vfs(e, cmd, spec).findFile { it.pathString() == cmd.path } assert file : "cannot find file[${cmd.path}]" - assert file.backingFile != null : "qcow2[${cmd.path}] has no backing file, ${file}" - rsp.backingFilePath = file.backingFile.toAbsolutePath().toString() + if (file.backingFile != null) { + rsp.backingFilePath = file.backingFile.toAbsolutePath().toString() + } rsp.size = 0 return rsp } + simulator(LocalStorageKvmBackend.GET_BACKING_CHAIN_PATH) { HttpEntity e, EnvSpec spec -> + return new LocalStorageKvmBackend.GetBackingChainRsp() + } + + VFS.vfsHook(LocalStorageKvmBackend.GET_BACKING_CHAIN_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.GetBackingChainCmd.class) + + List chain = [] + VFS vfs = vfs(e, cmd, spec) + Qcow2 file = vfs.getFile(cmd.installPath) + if (file == null) { + logger.debug("Dump of whole VFS:\\n${vfs.dumpAsString()}") + } + assert file != null : "cannot find file[${cmd.installPath}]" + while (file.backingQcow2() != null) { + chain.add(file.backingQcow2().pathString()) + file = file.backingQcow2() + } + + rsp.backingChain = chain + return rsp + } + simulator(LocalStorageKvmBackend.GET_MD5_PATH) {HttpEntity e -> def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.GetMd5Cmd.class) def rsp = new LocalStorageKvmBackend.GetMd5Rsp() @@ -266,6 +295,15 @@ class LocalStorageSpec extends PrimaryStorageSpec { return new LocalStorageKvmBackend.CreateVolumeWithBackingRsp() } + VFS.vfsHook(LocalStorageKvmBackend.CREATE_VOLUME_WITH_BACKING_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.CreateVolumeWithBackingCmd.class) + VFS vfs = vfs(e, cmd, spec) + + Volume image = vfs.getFile(cmd.templatePathInCache, true) + vfs.createQcow2(cmd.installPath, image.actualSize, image.virtualSize, cmd.templatePathInCache) + return rsp + } + simulator(LocalStorageKvmBackend.CREATE_EMPTY_VOLUME_PATH) { HttpEntity e, EnvSpec spec -> return new LocalStorageKvmBackend.CreateEmptyVolumeRsp() } @@ -326,6 +364,18 @@ class LocalStorageSpec extends PrimaryStorageSpec { return rsp } + simulator(LocalStorageKvmBackend.UNLINK_BITS_PATH) { + return new LocalStorageKvmBackend.UnlinkBitsRsp() + } + + VFS.vfsHook(LocalStorageKvmBackend.UNLINK_BITS_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.UnlinkBitsCmd.class) + VFS vfs = vfs(e, cmd, spec) + assert vfs.exists(cmd.installPath) + vfs.unlink(cmd.installPath, cmd.onlyLinkedFile) + return rsp + } + // simulator(LocalStorageKvmBackend.GET_LIST_PATH) { HttpEntity e, EnvSpec spec -> // return new LocalStorageKvmBackend.ListPathRsp(paths: []) // } @@ -369,6 +419,22 @@ class LocalStorageSpec extends PrimaryStorageSpec { return rsp } + simulator(LocalStorageKvmBackend.ESTIMATE_TEMPLATE_SIZE_PATH) { + def rsp = new LocalStorageKvmBackend.EstimateTemplateSizeRsp() + rsp.size = 0 + rsp.actualSize = 0 + return rsp + } + + VFS.vfsHook(LocalStorageKvmBackend.ESTIMATE_TEMPLATE_SIZE_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.EstimateTemplateSizeCmd.class) + VFS srcVFS = vfs(e, cmd, spec) + Qcow2 qcow2 = srcVFS.getFile(cmd.volumePath) + rsp.size = qcow2.virtualSize + rsp.actualSize = qcow2.actualSize + return rsp + } + simulator(LocalStorageKvmBackend.REVERT_SNAPSHOT_PATH) { HttpEntity e -> def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.RevertVolumeFromSnapshotCmd.class) def rsp = new LocalStorageKvmBackend.RevertVolumeFromSnapshotRsp() @@ -443,11 +509,43 @@ class LocalStorageSpec extends PrimaryStorageSpec { Qcow2 snapshot = vfs.getFile(cmd.snapshotInstallPath) assert snapshot : "cannot find snapshot[${cmd.snapshotInstallPath}]" vfs.createQcow2(cmd.workspaceInstallPath, 0L, 0L, null) + rsp.actualSize = 1 return rsp } simulator(LocalStorageKvmBackend.OFFLINE_MERGE_PATH) { HttpEntity e, EnvSpec spec -> - return new LocalStorageKvmBackend.OfflineMergeSnapshotRsp() + def rsp = new LocalStorageKvmBackend.OfflineMergeSnapshotRsp() + rsp.actualSize = 1 + return rsp + } + + VFS.vfsHook(LocalStorageKvmBackend.OFFLINE_MERGE_PATH, espec) { LocalStorageKvmBackend.OfflineMergeSnapshotRsp rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.OfflineMergeSnapshotCmd.class) + VFS vfs = vfs(e, cmd, spec) + Qcow2 dst = vfs.getFile(cmd.destPath, true) + if (cmd.fullRebase) { + dst.rebase((String) null) + } else { + dst.rebase(cmd.srcPath) + } + rsp.actualSize = 1 + return rsp + } + + simulator(LocalStorageKvmBackend.OFFLINE_COMMIT_PATH) { HttpEntity e, EnvSpec spec -> + def rsp = new LocalStorageKvmBackend.OfflineCommitSnapshotRsp() + rsp.actualSize = 1 + return rsp + } + + VFS.vfsHook(LocalStorageKvmBackend.OFFLINE_COMMIT_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.OfflineCommitSnapshotCmd.class) + VFS vfs = vfs(e, cmd, spec) + Qcow2 src = vfs.getFile(cmd.top) + Qcow2 dst = vfs.getFile(cmd.base) + Qcow2 qcow2 = Qcow2.commit(vfs, src, dst) + rsp.actualSize = qcow2.actualSize == 0 ? 1 : qcow2.actualSize + return rsp } simulator(LocalStorageKvmBackend.CHECK_INITIALIZED_FILE) { @@ -473,6 +571,23 @@ class LocalStorageSpec extends PrimaryStorageSpec { return new LocalStorageKvmBackend.LinkVolumeNewDirRsp() } + VFS.vfsHook(LocalStorageKvmBackend.HARD_LINK_VOLUME, espec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.LinkVolumeNewDirCmd.class) + VFS vfs = vfs(e, cmd, spec) + def links = vfs.link(cmd.dstDir, cmd.srcDir) + for (link in links) { + Qcow2 qf = vfs.getFile(link, true) + if (qf.backingFile != null) { + qf.rebase(qf.backingFile.toString().replace(cmd.srcDir, cmd.dstDir)) + } + // TODO multi paths + qf.path = link + qf.update() + } + + return rsp + } + simulator(LocalStorageKvmBackend.GET_DOWNLOAD_BITS_FROM_KVM_HOST_PROGRESS_PATH) { LocalStorageKvmBackend.GetDownloadBitsFromKVMHostProgressRsp rsp = new LocalStorageKvmBackend.GetDownloadBitsFromKVMHostProgressRsp() rsp.totalSize = 1L @@ -485,23 +600,6 @@ class LocalStorageSpec extends PrimaryStorageSpec { rsp.hashValue = cmd.installPath return rsp } - - VFS.vfsHook(LocalStorageKvmBackend.OFFLINE_MERGE_PATH, espec) { rsp, HttpEntity e, EnvSpec spec -> - def cmd = JSONObjectUtil.toObject(e.body, LocalStorageKvmBackend.OfflineMergeSnapshotCmd.class) - VFS vfs = vfs(e, cmd, spec) - - Qcow2 src = vfs.getFile(cmd.srcPath) - assert src : "cannot find source file[${cmd.srcPath}]" - - Qcow2 dst = vfs.getFile(cmd.destPath) - assert dst : "cannot find destination file[${cmd.destPath}]" - if (cmd.fullRebase) { - dst.rebase((String) null) - } else { - dst.rebase(cmd.srcPath) - } - return rsp - } } } diff --git a/testlib/src/main/java/org/zstack/testlib/MinimalBeanConstructor.groovy b/testlib/src/main/java/org/zstack/testlib/MinimalBeanConstructor.groovy new file mode 100644 index 00000000000..17f44709e29 --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/MinimalBeanConstructor.groovy @@ -0,0 +1,15 @@ +package org.zstack.testlib + +import org.zstack.core.CoreGlobalProperty +import org.zstack.core.StartMode + +class MinimalBeanConstructor extends WebBeanConstructor{ + + private String MINIMAL_XML_NAME = "zstack-minimal.xml" + + @Override + void generateSpringConfig() { + CoreGlobalProperty.BEAN_CONF = MINIMAL_XML_NAME + CoreGlobalProperty.START_MODE = StartMode.MINIMAL + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/NfsPrimaryStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/NfsPrimaryStorageSpec.groovy index 01274f517cd..0dbe59bfc01 100755 --- a/testlib/src/main/java/org/zstack/testlib/NfsPrimaryStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/NfsPrimaryStorageSpec.groovy @@ -4,7 +4,6 @@ import org.springframework.http.HttpEntity import org.zstack.core.Platform import org.zstack.core.cloudbus.CloudBus import org.zstack.core.db.Q -import org.zstack.header.exception.CloudRuntimeException import org.zstack.header.message.MessageReply import org.zstack.header.storage.primary.PingPrimaryStorageMsg import org.zstack.header.storage.primary.PrimaryStorageVO @@ -15,7 +14,6 @@ import org.zstack.header.volume.VolumeVO import org.zstack.header.volume.VolumeVO_ import org.zstack.kvm.KVMAgentCommands import org.zstack.sdk.PrimaryStorageInventory -import org.zstack.storage.primary.local.LocalStorageKvmBackend import org.zstack.storage.primary.nfs.NfsPrimaryStorageKVMBackend import org.zstack.storage.primary.nfs.NfsPrimaryStorageKVMBackendCommands import org.zstack.storage.primary.nfs.NfsPrimaryToSftpBackupKVMBackend @@ -23,18 +21,17 @@ import org.zstack.testlib.vfs.Qcow2 import org.zstack.testlib.vfs.VFS import org.zstack.testlib.vfs.VFSFile import org.zstack.testlib.vfs.Volume +import org.zstack.utils.Utils import org.zstack.utils.gson.JSONObjectUtil -import org.zstack.utils.path.PathUtil -import org.zstack.utils.path.PathUtils +import org.zstack.utils.logging.CLogger import java.nio.file.Path import java.nio.file.Paths -import java.nio.file.StandardCopyOption - /** * Created by xing5 on 2017/2/13. */ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { + private static final CLogger logger = Utils.getLogger(NfsPrimaryStorageSpec.class); NfsPrimaryStorageSpec(EnvSpec envSpec) { super(envSpec) @@ -52,6 +49,7 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { } static VFS vfs(String uuid, EnvSpec spec) { + assert uuid != null return spec.getVirtualFileSystem("nfs-${uuid}") } @@ -67,26 +65,63 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(NfsPrimaryStorageKVMBackend.GET_VOLUME_BASE_IMAGE_PATH) { - def rsp = new LocalStorageKvmBackend.GetVolumeBaseImagePathRsp() - rsp.path = "/some/fake/path" + def rsp = new NfsPrimaryStorageKVMBackendCommands.GetVolumeBaseImagePathRsp() return rsp } VFS.vfsHook(NfsPrimaryStorageKVMBackend.GET_VOLUME_BASE_IMAGE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.getBody(), NfsPrimaryStorageKVMBackendCommands.GetVolumeBaseImagePathCmd.class) + rsp.otherPaths = [] + VFS vfs = vfs(cmd, spec) - List backingFiles = [] + Qcow2 qfile = vfs.getFile(cmd.volumeInstallPath) + if (qfile == null) { + logger.debug("Dump of whole VFS:\\n${vfs.dumpAsString()}") + } + assert qfile != null : "cannot find file[${cmd.volumeInstallPath}]" + while (qfile.backingFile != null) { + if (qfile.backingFile.toAbsolutePath().toString().startsWith(cmd.imageCacheDir)) { + rsp.path = qfile.backingFile.toAbsolutePath().toString() + break + } + + qfile = qfile.backingQcow2() + + } + vfs.walkFileSystem { vfile -> if (vfile.pathString().contains(cmd.volumeInstallDir)) { - Qcow2 qfile = vfile as Qcow2 + qfile = vfile as Qcow2 if (qfile.backingFile != null && qfile.backingFile.toAbsolutePath().toString().startsWith(cmd.imageCacheDir)) { - backingFiles.add(qfile.backingFile.toAbsolutePath().toString()) + rsp.otherPaths.add(qfile.backingFile.toAbsolutePath().toString()) } } } - assert backingFiles.size() == 1 : "zero or more than one backing file found. ${backingFiles}" - rsp.path = backingFiles[0] + rsp.otherPaths.remove(rsp.path) + return rsp + } + + simulator(NfsPrimaryStorageKVMBackend.GET_BACKING_CHAIN_PATH) { HttpEntity e, EnvSpec spec -> + return new NfsPrimaryStorageKVMBackendCommands.GetBackingChainRsp() + } + + VFS.vfsHook(NfsPrimaryStorageKVMBackend.GET_BACKING_CHAIN_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.GetBackingChainCmd.class) + + List chain = [] + VFS vfs = NfsPrimaryStorageSpec.vfs(cmd, spec) + Qcow2 file = vfs.getFile(cmd.installPath) + if (file == null) { + logger.debug("Dump of whole VFS:\\n${vfs.dumpAsString()}") + } + assert file != null : "cannot find file[${cmd.installPath}]" + while (file.backingQcow2() != null) { + chain.add(file.backingQcow2().pathString()) + file = file.backingQcow2() + } + + rsp.backingChain = chain return rsp } @@ -115,7 +150,7 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(NfsPrimaryStorageKVMBackend.CREATE_EMPTY_VOLUME_PATH) { - return new NfsPrimaryStorageKVMBackendCommands.CreateRootVolumeFromTemplateResponse() + return new NfsPrimaryStorageKVMBackendCommands.CreateEmptyVolumeResponse() } VFS.vfsHook(NfsPrimaryStorageKVMBackend.CREATE_EMPTY_VOLUME_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> @@ -162,9 +197,18 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } -// simulator(NfsPrimaryStorageKVMBackend.LIST_PATH) { -// return new NfsPrimaryStorageKVMBackendCommands.ListDirectionResponse() -// } + simulator(NfsPrimaryStorageKVMBackend.UNLINK_PATH) { + return new NfsPrimaryStorageKVMBackendCommands.UnlinkBitsRsp() + } + + VFS.vfsHook(NfsPrimaryStorageKVMBackend.UNLINK_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.UnlinkBitsCmd.class) + VFS vfs = vfs(cmd, spec) + assert vfs.exists(cmd.installPath) + vfs.unlink(cmd.installPath, cmd.onlyLinkedFile) + return rsp + } + simulator(NfsPrimaryStorageKVMBackend.MOVE_BITS_PATH) { return new NfsPrimaryStorageKVMBackendCommands.MoveBitsRsp() @@ -189,21 +233,28 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { VFS.vfsHook(NfsPrimaryStorageKVMBackend.OFFLINE_SNAPSHOT_MERGE, xspec) { rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.OfflineMergeSnapshotCmd.class) VFS vfs = vfs(cmd, spec) - - Qcow2 src = vfs.getFile(cmd.srcPath) - if (!cmd.fullRebase) { - src.rebase(cmd.destPath) + Qcow2 dst = vfs.getFile(cmd.destPath, true) + if (cmd.fullRebase) { + dst.rebase((String) null) } else { - // when full rebase requested - // general steps for offline Qcow2 merge operation has following steps: - // 1. create a temp Qcow2 file - // 2. convert Qcow2 on destPath to temp Qcow2 - // 3. replace Qcow2 on destPath with temp file - if (!vfs.exists(cmd.destPath)) { - vfs.createQcow2(cmd.destPath, 0, 0) - } + dst.rebase(cmd.srcPath) } + return rsp + } + + simulator(NfsPrimaryStorageKVMBackend.OFFLINE_SNAPSHOT_COMMIT) { + def rsp = new NfsPrimaryStorageKVMBackendCommands.OfflineCommitSnapshotRsp() + rsp.actualSize = 1 + return rsp + } + VFS.vfsHook(NfsPrimaryStorageKVMBackend.OFFLINE_SNAPSHOT_COMMIT, xspec) { NfsPrimaryStorageKVMBackendCommands.OfflineCommitSnapshotRsp rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.OfflineCommitSnapshotCmd.class) + VFS vfs = vfs(cmd, spec) + Qcow2 src = vfs.getFile(cmd.top) + Qcow2 dst = vfs.getFile(cmd.base) + Qcow2 qcow2 = Qcow2.commit(vfs, src, dst) + rsp.actualSize = qcow2.actualSize == 0 ? 1 : qcow2.actualSize return rsp } @@ -233,6 +284,22 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } + simulator(NfsPrimaryStorageKVMBackend.ESTIMATE_TEMPLATE_SIZE_PATH) { + def rsp = new NfsPrimaryStorageKVMBackendCommands.EstimateTemplateSizeRsp() + rsp.size = 0 + rsp.actualSize = 0 + return rsp + } + + VFS.vfsHook(NfsPrimaryStorageKVMBackend.ESTIMATE_TEMPLATE_SIZE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.EstimateTemplateSizeCmd.class) + VFS srcVFS = vfs(cmd, spec) + Qcow2 qcow2 = srcVFS.getFile(cmd.volumePath) + rsp.size = qcow2.virtualSize + rsp.actualSize = qcow2.actualSize + return rsp + } + simulator(NfsPrimaryStorageKVMBackend.REINIT_IMAGE_PATH) { def rsp = new NfsPrimaryStorageKVMBackendCommands.ReInitImageRsp() rsp.newVolumeInstallPath = "/new/volume/install/path" @@ -272,10 +339,6 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } - simulator(NfsPrimaryStorageKVMBackend.CREATE_VOLUME_WITH_BACKING_PATH) { - return new NfsPrimaryStorageKVMBackendCommands.CreateVolumeWithBackingRsp() - } - simulator(NfsPrimaryStorageKVMBackend.GET_VOLUME_SIZE_PATH) { HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.GetVolumeActualSizeCmd.class) NfsPrimaryStorageKVMBackendCommands.GetVolumeActualSizeRsp rsp = new NfsPrimaryStorageKVMBackendCommands.GetVolumeActualSizeRsp() @@ -378,13 +441,28 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } - simulator(NfsPrimaryStorageKVMBackend.NFS_TO_NFS_MIGRATE_BITS_PATH) { + simulator(NfsPrimaryStorageKVMBackend.CREATE_VOLUME_WITH_BACKING_PATH) { + return new NfsPrimaryStorageKVMBackendCommands.CreateVolumeWithBackingRsp() + } + + VFS.vfsHook(NfsPrimaryStorageKVMBackend.CREATE_VOLUME_WITH_BACKING_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.CreateVolumeWithBackingCmd.class) + VFS vfs = vfs(cmd, xspec) + Volume image = vfs.getFile(cmd.templatePathInCache, true) + vfs.createQcow2(cmd.installUrl, image.actualSize, image.virtualSize, cmd.templatePathInCache) + return rsp + } + + simulator(NfsPrimaryStorageKVMBackend.NFS_TO_NFS_MIGRATE_BITS_PATH) { HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.NfsToNfsMigrateBitsCmd.class) + // all fast clone case must be mock by itself + assert cmd.independentPath == null return new NfsPrimaryStorageKVMBackendCommands.NfsToNfsMigrateBitsRsp() } VFS.vfsHook(NfsPrimaryStorageKVMBackend.NFS_TO_NFS_MIGRATE_BITS_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.NfsToNfsMigrateBitsCmd.class) - VFS srcVfs = vfs(cmd, spec) + VFS srcVfs = vfs(cmd.srcPrimaryStorageUuid, spec) PrimaryStorageVO dstNFS = Q.New(PrimaryStorageVO.class).eq(PrimaryStorageVO_.url, cmd.url).find() assert dstNFS : "cannot find NFS primary storage[url: ${cmd.url}]" @@ -393,7 +471,12 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { srcVfs.walkFileSystem { VFSFile f -> if (f.pathString().contains(cmd.srcFolderPath)) { String newPath = f.pathString().replace(cmd.srcFolderPath, cmd.dstFolderPath) - dstVfs.createFileFrom(Paths.get(newPath), f) + def dstFile = dstVfs.createFileFrom(Paths.get(newPath), f) + if (dstFile instanceof Qcow2 && + dstFile.backingFile != null && + f.pathString() == cmd.independentPath) { + dstFile.rebase(null) + } } } @@ -412,6 +495,20 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { return new NfsPrimaryStorageKVMBackendCommands.LinkVolumeNewDirRsp() } + VFS.vfsHook(NfsPrimaryStorageKVMBackend.HARD_LINK_VOLUME, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.LinkVolumeNewDirCmd.class) + VFS vfs = vfs(cmd, spec) + def links = vfs.link(cmd.dstDir, cmd.srcDir) + for (link in links) { + Qcow2 qf = vfs.getFile(link, true) + if (qf.backingFile != null) { + qf.rebase(qf.backingFile.toString().replace(cmd.srcDir, cmd.dstDir)) + } + } + + return rsp + } + simulator(NfsPrimaryStorageKVMBackend.GET_DOWNLOAD_BITS_FROM_KVM_HOST_PROGRESS_PATH) { def rsp = new NfsPrimaryStorageKVMBackendCommands.GetDownloadBitsFromKVMHostProgressRsp() rsp.totalSize = 1L @@ -427,33 +524,23 @@ class NfsPrimaryStorageSpec extends PrimaryStorageSpec { VFS.vfsHook(NfsPrimaryStorageKVMBackend.NFS_REBASE_VOLUME_BACKING_FILE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, NfsPrimaryStorageKVMBackendCommands.NfsRebaseVolumeBackingFileCmd.class) -// String dstPrimaryStorageUuid = getPrimaryStorageFromPath(cmd.dstPsMountPath) -// VFS dstVfs = vfs(dstPrimaryStorageUuid, spec) - //TODO: for guoyi -// List fileList = new ArrayList<>() -// if (cmd.dstImageCacheTemplateFolderPath == null) { -// dstVfs.walkFileSystem { f -> -// if (f.pathString().contains(cmd.dstVolumeFolderPath)) { -// fileList.add(f) -// } -// } -// } else { -// dstVfs.walkFileSystem { f -> -// if (f.pathString().contains(cmd.dstVolumeFolderPath) -// || f.pathString().contains(cmd.dstImageCacheTemplateFolderPath)) { -// fileList.add(f) -// } -// } -// } -// -// fileList.each { file -> -// if (file.backingFile == null) { -// return -// } -// -// file.backingFile = Paths.get(file.backingFile.toAbsolutePath().toString().replace(cmd.srcPsMountPath, cmd.dstPsMountPath)) -// dstVfs.write(file.path, file.asJSONString()) -// } + + VFS dstVfs = vfs(cmd, spec) + List fileList = new ArrayList<>() + dstVfs.walkFileSystem { f -> + if (f.pathString().contains(cmd.dstVolumeFolderPath) + || (cmd.dstImageCacheTemplateFolderPath != null && + f.pathString().contains(cmd.dstImageCacheTemplateFolderPath))) { + fileList.add(f) + } + } + + fileList.each { file -> + if (file instanceof Qcow2 && file.backingFile != null) { + String newBackingFile = file.backingFile.toAbsolutePath().toString().replace(cmd.srcPsMountPath, cmd.dstPsMountPath) + file.rebase(newBackingFile) + } + } return rsp } diff --git a/testlib/src/main/java/org/zstack/testlib/ReplyDroppedMessageNotifierExtensionPoint.java b/testlib/src/main/java/org/zstack/testlib/ReplyDroppedMessageNotifierExtensionPoint.java index dcf40a98863..e5da0616498 100644 --- a/testlib/src/main/java/org/zstack/testlib/ReplyDroppedMessageNotifierExtensionPoint.java +++ b/testlib/src/main/java/org/zstack/testlib/ReplyDroppedMessageNotifierExtensionPoint.java @@ -43,6 +43,18 @@ private void handleMessageWithoutReply(NeedReplyMessage msg) { } } }); + + Test.getCurrentEnvSpec().notifiersOfReceivedMessages.forEach((msgClz, cs) -> { + if (msg.getClass() == msgClz) { + logger.debug("class matched, execute closure " + cs.size()); + synchronized (cs) { + for (Test.MessageNotifier notifier : cs) { + notifier.getC().call(msg); + notifier.getCounter().incrementAndGet(); + } + } + } + }); } @Override @@ -64,8 +76,9 @@ private void handleReplyMessage(Message replyOrEvent, NeedReplyMessage msg) { if (replyOrEvent.getClass() == msgClz) { logger.debug("class matched, execute closure " + cs.size()); synchronized (cs) { - for (Closure c : cs) { - c.call(replyOrEvent); + for (Test.MessageNotifier notifier : cs) { + notifier.getC().call(replyOrEvent); + notifier.getCounter().incrementAndGet(); } } } diff --git a/testlib/src/main/java/org/zstack/testlib/SdnControllerSpec.groovy b/testlib/src/main/java/org/zstack/testlib/SdnControllerSpec.groovy new file mode 100644 index 00000000000..25b24d7f412 --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/SdnControllerSpec.groovy @@ -0,0 +1,306 @@ +package org.zstack.testlib + +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.zstack.sdk.SdnControllerInventory +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.LoginReply +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.LoginRsp +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.CreateH3cNetworksRsp +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.NetworkCmd +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.GetH3cVniRangeRsp +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.H3cVniRangeStruct +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.VniRangeStruct +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.GetH3cTenantsRsp +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.H3cTenantStruct +import org.zstack.sdnController.h3cVcfc.H3cVcfcCommands.GetH3cTeamLederIpReply +import org.zstack.sdnController.h3cVcfc.H3cVcfcV2Commands +import org.springframework.http.HttpEntity +import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant +import org.zstack.sugonSdnController.controller.api.ApiSerializer +import org.zstack.sugonSdnController.controller.api.TfCommands +import org.zstack.sugonSdnController.controller.api.types.Domain +import org.zstack.sugonSdnController.controller.api.types.MacAddressesType +import org.zstack.sugonSdnController.controller.api.types.Project +import org.zstack.sugonSdnController.controller.api.types.VirtualMachine +import org.zstack.sugonSdnController.controller.api.types.VirtualMachineInterface +import org.zstack.sugonSdnController.controller.api.types.VirtualNetwork + +/** + * Created by shixin.ruan on 2019/09/26. + */ +class SdnControllerSpec extends Spec implements HasSession { + String vendorType + String name + String description + String ip + String userName + String password + List systemTags + + SdnControllerInventory inventory + + SdnControllerSpec(EnvSpec envSpec) { + super(envSpec) + } + + SpecID create(String uuid, String sessionId) { + inventory = addSdnController { + delegate.resourceUuid = uuid + delegate.sessionId = sessionId + delegate.vendorType = vendorType + delegate.name = name + delegate.description = description + delegate.ip = ip + delegate.userName = userName + delegate.password = password + delegate.systemTags = systemTags + } + + postCreate { + inventory = querySdnController { + conditions=["uuid=${inventory.uuid}".toString()] + }[0] + } + + return id(name, inventory.uuid) + } + + class Simulators implements Simulator { + @Override + void registerSimulators(EnvSpec xspec) { + def simulator = { arg1, arg2 -> + xspec.simulator(arg1, arg2) + } + + simulator(H3cVcfcCommands.H3C_VCFC_GET_TOKEN) { + LoginReply reply = new LoginReply() + LoginRsp login = new LoginRsp() + reply.token = "token1" + login.record = reply + return login + } + + simulator(H3cVcfcCommands.H3C_VCFC_L2_NETWORKS) { + CreateH3cNetworksRsp rsp = new CreateH3cNetworksRsp() + rsp.networks = new ArrayList() + + NetworkCmd cmd = new NetworkCmd() + cmd.id = "123456" + rsp.networks.add(cmd) + + return rsp + } + + simulator(H3cVcfcCommands.H3C_VCFC_VNI_RANGES) { + GetH3cVniRangeRsp rsp = new GetH3cVniRangeRsp() + rsp.domains = new ArrayList<>() + + H3cVniRangeStruct ranges = new H3cVniRangeStruct() + ranges.vlan_map_list = new ArrayList<>() + + VniRangeStruct s1 = new VniRangeStruct() + s1.start_vxlan = "100" + s1.end_vxlan = "200" + ranges.vlan_map_list.add(s1) + + VniRangeStruct s2 = new VniRangeStruct() + s2.start_vxlan = "300" + s2.end_vxlan = "400" + ranges.vlan_map_list.add(s2) + + rsp.domains.add(ranges) + + return rsp + } + + simulator(H3cVcfcCommands.H3C_VCFC_TENANTS) { + H3cVcfcV2Commands.GetH3cTenantsRsp rsp = new H3cVcfcV2Commands.GetH3cTenantsRsp() + rsp.tenants = new ArrayList<>() + + H3cVcfcV2Commands.H3cTenantStruct t1 = new H3cVcfcV2Commands.H3cTenantStruct() + t1.id = "03e01b37-8440-471a-aa8f-8d1fb8cc1381" + t1.name = "Test" + t1.type = "local-create" + t1.vds_list = ["eb32cf5e-04e9-42ad-b64c-2c3f9bacd3cc"] + t1.cloud_region_name = null + t1.cloud_domain_name = null + rsp.tenants.add(t1) + + H3cVcfcV2Commands.H3cTenantStruct t2 = new H3cVcfcV2Commands.H3cTenantStruct() + t2.id = "ffffffff-0000-0000-0000-000000000001" + t2.name = "default" + t2.type = "default" + t2.vds_list = ["ffffffff-0000-0000-0000-000000000001"] + t2.cloud_region_name = null + t2.cloud_domain_name = null + rsp.tenants.add(t2) + + H3cVcfcV2Commands.H3cTenantStruct t3 = new H3cVcfcV2Commands.H3cTenantStruct() + t3.id = "c9d49b6f-d2cd-4636-b9d4-be0f9c9c7783" + t3.name = "sr" + t3.type = "local-create" + t3.vds_list = ["ffffffff-0000-0000-0000-000000000001"] + t3.cloud_region_name = null + t3.cloud_domain_name = null + rsp.tenants.add(t3) + + return rsp + } + + simulator(H3cVcfcCommands.H3C_VCFC_TEAM_LEADERIP) { + GetH3cTeamLederIpReply rsp = new GetH3cTeamLederIpReply() + rsp.ip = "127.1.1.1" + return rsp + } + + simulator(H3cVcfcV2Commands.H3C_VCFC_VDS) { + H3cVcfcV2Commands.GetH3cVdsRsp rsp = new H3cVcfcV2Commands.GetH3cVdsRsp() + rsp.vds = new ArrayList<>() + + H3cVcfcV2Commands.H3cVdsStruct vds1 = new H3cVcfcV2Commands.H3cVdsStruct() + vds1.uuid = "eb32cf5e-04e9-42ad-b64c-2c3f9bacd3cc" + vds1.name = "Test_VDS" + vds1.bridge = "Test_VDS-br" + vds1.status = "UP" + vds1.openflow_hard_age = "300" + vds1.vxlan_tunnel_name = "vxlan_Test_VDS-br" + vds1.vxlan_range = "1-16777215" + vds1.virtual_mac = "00:00:00:00:00:01" + vds1.forwarding_mode = "mac-forwarding" + rsp.vds.add(vds1) + + H3cVcfcV2Commands.H3cVdsStruct vds2 = new H3cVcfcV2Commands.H3cVdsStruct() + vds2.uuid = "ffffffff-0000-0000-0000-000000000001" + vds2.name = "Default_VDS" + vds2.bridge = "Default_VDS-br" + vds2.status = "UP" + vds2.openflow_hard_age = "300" + vds2.vxlan_tunnel_name = "vxlan_Default_VDS-br" + vds2.vxlan_range = "1-16777215" + vds2.virtual_mac = "00:00:00:00:00:02" + vds2.forwarding_mode = "mac-forwarding" + rsp.vds.add(vds2) + + return rsp + } + + simulator(TfCommands.TF_GET_DAEMON) { + TfCommands.GetDomainRsp rsp = new TfCommands.GetDomainRsp() + rsp.uuid = TfCommands.TEST_DOMAIN_UUID + return rsp + } + + simulator(TfCommands.TF_GET_DAEMON_DETAIL) { + Domain rsp = new Domain() + rsp.uuid = TfCommands.TEST_DOMAIN_UUID + rsp.name = SugonSdnControllerConstant.TF_DEFAULT_DOMAIN + String json = ApiSerializer.serializeObject("domain", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_GET_PROJECT) { + Project rsp = new Project(); + rsp.name = TfCommands.TEST_PROJECT_UUID + rsp.uuid = TfCommands.TEST_PROJECT_UUID + rsp.displayName = "admin"; + String json = ApiSerializer.serializeObject("project", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + + return response.getBody() + } + + simulator(TfCommands.TF_CREATE_PROJECT) { + Project rsp = new Project(); + rsp.name = TfCommands.TEST_PROJECT_UUID + rsp.uuid = TfCommands.TEST_PROJECT_UUID + rsp.displayName = "admin"; + String json = ApiSerializer.serializeObject("project", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_CREATE_NETWORK) { + VirtualNetwork rsp = new VirtualNetwork(); + rsp.name = TfCommands.TEST_L2_UUID + rsp.uuid = TfCommands.TEST_L2_UUID + String json = ApiSerializer.serializeObject("virtual-network", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_GET_NETWORK) { + VirtualNetwork rsp = new VirtualNetwork(); + rsp.name = TfCommands.TEST_L2_UUID + rsp.uuid = TfCommands.TEST_L2_UUID + String json = ApiSerializer.serializeObject("virtual-network", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_CREATE_VM) { + VirtualMachine rsp = new VirtualMachine(); + rsp.name = TfCommands.TEST_VM_UUID + rsp.uuid = TfCommands.TEST_VM_UUID + String json = ApiSerializer.serializeObject("virtual-machine", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_GET_VM) { + VirtualMachine rsp = new VirtualMachine(); + rsp.name = TfCommands.TEST_VM_UUID + rsp.uuid = TfCommands.TEST_VM_UUID + String json = ApiSerializer.serializeObject("virtual-machine", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_CREATE_VMI) { + VirtualMachineInterface rsp = new VirtualMachineInterface(); + rsp.name = TfCommands.TEST_VMI_UUID + rsp.uuid = TfCommands.TEST_VMI_UUID + Project project = new Project(); + project.name = TfCommands.TEST_PROJECT_UUID + project.uuid = TfCommands.TEST_PROJECT_UUID + project.displayName = "admin"; + rsp.setParent(project) + String json = ApiSerializer.serializeObject("virtual-machine-interface", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + + simulator(TfCommands.TF_GET_VMI) { + VirtualMachineInterface rsp = new VirtualMachineInterface(); + rsp.name = TfCommands.TEST_VMI_UUID + rsp.uuid = TfCommands.TEST_VMI_UUID + List macList = new ArrayList(); + macList.add("08:00:27:b4:e1:99"); + MacAddressesType macAddress = new MacAddressesType(macList); + rsp.setMacAddresses(macAddress); + Project project = new Project(); + project.name = TfCommands.TEST_PROJECT_UUID + project.uuid = TfCommands.TEST_PROJECT_UUID + project.displayName = "admin"; + rsp.parent = project + rsp.instance_ip_back_refs = null + String json = ApiSerializer.serializeObject("virtual-machine-interface", rsp); + ResponseEntity response = new ResponseEntity(json, HttpStatus.OK); + return response.getBody() + } + } + } + + @Override + void delete(String sessionId) { + if (inventory != null) { + removeSdnController { + delegate.uuid = inventory.uuid + delegate.sessionId = sessionId + } + + inventory = null + } + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/SftpBackupStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/SftpBackupStorageSpec.groovy index 7ee82273308..80c0771039f 100755 --- a/testlib/src/main/java/org/zstack/testlib/SftpBackupStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/SftpBackupStorageSpec.groovy @@ -47,19 +47,26 @@ class SftpBackupStorageSpec extends BackupStorageSpec { simulator(SftpBackupStorageConstant.DOWNLOAD_IMAGE_PATH) { HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.getBody(), SftpBackupStorageCommands.DownloadCmd.class) BackupStorageSpec bsSpec = spec.specByUuid(cmd.uuid) + ImageSpec imageSpec = spec.specByUuid(cmd.imageUuid) + + boolean useSpecSize = Boolean.valueOf(System.getProperty("useImageSpecSize")) def rsp = new SftpBackupStorageCommands.DownloadResponse() - rsp.size = 0 - rsp.actualSize = 0 + rsp.size = useSpecSize ? imageSpec.size : 0L + rsp.actualSize = useSpecSize ? imageSpec.actualSize : 0L rsp.availableCapacity = bsSpec.availableCapacity rsp.totalCapacity = bsSpec.totalCapacity return rsp } - simulator(SftpBackupStorageConstant.GET_IMAGE_SIZE) { + simulator(SftpBackupStorageConstant.GET_IMAGE_SIZE) {HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.getBody(), SftpBackupStorageCommands.GetImageSizeCmd.class) def rsp = new SftpBackupStorageCommands.GetImageSizeRsp() - rsp.actualSize = 0 - rsp.size = 0 + ImageSpec imageSpec = spec.specByUuid(cmd.imageUuid) + + boolean useSpecSize = Boolean.valueOf(System.getProperty("useImageSpecSize")) + rsp.size = useSpecSize ? imageSpec.size : 0L + rsp.actualSize = useSpecSize ? imageSpec.actualSize : 0L return rsp } diff --git a/testlib/src/main/java/org/zstack/testlib/SharedMountPointPrimaryStorageSpec.groovy b/testlib/src/main/java/org/zstack/testlib/SharedMountPointPrimaryStorageSpec.groovy index db356ce9419..2735e198f25 100755 --- a/testlib/src/main/java/org/zstack/testlib/SharedMountPointPrimaryStorageSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/SharedMountPointPrimaryStorageSpec.groovy @@ -11,6 +11,8 @@ import org.zstack.header.volume.VolumeVO import org.zstack.header.volume.VolumeVO_ import org.zstack.sdk.PrimaryStorageInventory import org.zstack.storage.primary.smp.KvmBackend +import org.zstack.storage.primary.smp.SftpBackupStorageKvmDownloader +import org.zstack.storage.primary.smp.SftpBackupStorageKvmUploader import org.zstack.testlib.vfs.Qcow2 import org.zstack.testlib.vfs.VFS import org.zstack.testlib.vfs.VFSFile @@ -18,7 +20,6 @@ import org.zstack.testlib.vfs.Volume import org.zstack.utils.gson.JSONObjectUtil import java.nio.file.Path - /** * Created by xing5 on 2017/2/20. */ @@ -61,7 +62,7 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(KvmBackend.CREATE_VOLUME_FROM_CACHE_PATH) { - return new KvmBackend.AgentRsp() + return new KvmBackend.CreateVolumeFromCacheRsp() } VFS.vfsHook(KvmBackend.CREATE_VOLUME_FROM_CACHE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> @@ -77,7 +78,7 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(KvmBackend.DELETE_BITS_PATH) { - return new KvmBackend.AgentRsp() + return new KvmBackend.DeleteRsp() } VFS.vfsHook(KvmBackend.DELETE_BITS_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> @@ -89,6 +90,18 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } + simulator(KvmBackend.UNLINK_BITS_PATH) { + return new KvmBackend.UnlinkBitsRsp() + } + + VFS.vfsHook(KvmBackend.UNLINK_BITS_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.UnlinkBitsCmd.class) + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) + assert vfs.exists(cmd.installPath) + vfs.unlink(cmd.installPath, cmd.onlyLinkedFile) + return rsp + } + simulator(KvmBackend.CREATE_TEMPLATE_FROM_VOLUME_PATH) { def rsp = new KvmBackend.CreateTemplateFromVolumeRsp() rsp.actualSize = 0 @@ -106,15 +119,31 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { return rsp } - simulator(KvmBackend.UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH) { + simulator(KvmBackend.ESTIMATE_TEMPLATE_SIZE_PATH) { + def rsp = new KvmBackend.EstimateTemplateSizeRsp() + rsp.size = 0 + rsp.actualSize = 0 + return rsp + } + + VFS.vfsHook(KvmBackend.ESTIMATE_TEMPLATE_SIZE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.EstimateTemplateSizeCmd.class) + VFS srcVFS = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) + Qcow2 qcow2 = srcVFS.getFile(cmd.volumePath) + rsp.size = qcow2.virtualSize + rsp.actualSize = qcow2.actualSize + return rsp + } + + simulator(SftpBackupStorageKvmUploader.UPLOAD_BITS_TO_SFTP_BACKUPSTORAGE_PATH) { return new KvmBackend.AgentRsp() } - simulator(KvmBackend.DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH) { + simulator(SftpBackupStorageKvmDownloader.DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH) { return new KvmBackend.AgentRsp() } - VFS.vfsHook(KvmBackend.DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + VFS.vfsHook(SftpBackupStorageKvmDownloader.DOWNLOAD_BITS_FROM_SFTP_BACKUPSTORAGE_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.SftpDownloadBitsCmd.class) VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) @@ -163,6 +192,15 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { return new KvmBackend.MergeSnapshotRsp() } + VFS.vfsHook(KvmBackend.MERGE_SNAPSHOT_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.MergeSnapshotCmd.class) + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) + Qcow2 snapshot = vfs.getFile(cmd.snapshotInstallPath) + assert snapshot : "cannot find snapshot[${cmd.snapshotInstallPath}]" + vfs.createQcow2(cmd.workspaceInstallPath, 0L, 0L, null) + return rsp + } + simulator(KvmBackend.GET_VOLUME_SIZE_PATH) { HttpEntity e, EnvSpec spec -> def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.GetVolumeSizeCmd.class) KvmBackend.GetVolumeSizeRsp rsp = new KvmBackend.GetVolumeSizeRsp() @@ -198,11 +236,42 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { } simulator(KvmBackend.OFFLINE_MERGE_SNAPSHOT_PATH) { - return new KvmBackend.AgentRsp() + def rsp = new KvmBackend.OfflineMergeSnapshotRsp() + rsp.actualSize = 1 + return rsp + } + + VFS.vfsHook(KvmBackend.OFFLINE_MERGE_SNAPSHOT_PATH, xspec) { KvmBackend.OfflineMergeSnapshotRsp rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.OfflineMergeSnapshotCmd.class) + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) + Qcow2 dst = vfs.getFile(cmd.destPath, true) + if (cmd.fullRebase) { + dst.rebase((String) null) + } else { + dst.rebase(cmd.srcPath) + } + rsp.actualSize = 1 + return rsp + } + + simulator(KvmBackend.OFFLINE_COMMIT_SNAPSHOT_PATH) { + def rsp = new KvmBackend.OfflineCommitSnapshotRsp() + rsp.actualSize = 1 + return rsp + } + + VFS.vfsHook(KvmBackend.OFFLINE_COMMIT_SNAPSHOT_PATH, xspec) { KvmBackend.OfflineCommitSnapshotRsp rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.OfflineCommitSnapshotCmd.class) + VFS vfs = vfs(cmd, spec) + Qcow2 src = vfs.getFile(cmd.top) + Qcow2 dst = vfs.getFile(cmd.base) + Qcow2 qcow2 = Qcow2.commit(vfs, src, dst) + rsp.actualSize = qcow2.actualSize == 0 ? 1 : qcow2.actualSize + return rsp } simulator(KvmBackend.CREATE_EMPTY_VOLUME_PATH) { - return new KvmBackend.AgentRsp() + return new KvmBackend.CreateEmptyVolumeRsp() } VFS.vfsHook(KvmBackend.CREATE_EMPTY_VOLUME_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> @@ -245,6 +314,20 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { return new KvmBackend.LinkVolumeNewDirRsp() } + VFS.vfsHook(KvmBackend.HARD_LINK_VOLUME, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.LinkVolumeNewDirCmd.class) + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) + def links = vfs.link(cmd.dstDir, cmd.srcDir) + for (link in links) { + Qcow2 qf = vfs.getFile(link, true) + if (qf.backingFile != null) { + qf.rebase(qf.backingFile.toString().replace(cmd.srcDir, cmd.dstDir)) + } + } + + return rsp + } + simulator(KvmBackend.GET_DOWNLOAD_BITS_FROM_KVM_HOST_PROGRESS_PATH) { def rsp = new KvmBackend.GetDownloadBitsFromKVMHostProgressRsp() rsp.totalSize = 1L @@ -257,6 +340,29 @@ class SharedMountPointPrimaryStorageSpec extends PrimaryStorageSpec { rsp.hashValue = cmd.installPath return rsp } + + simulator(KvmBackend.GET_BACKING_CHAIN_PATH) { HttpEntity e, EnvSpec spec -> + return new KvmBackend.GetBackingChainRsp() + } + + VFS.vfsHook(KvmBackend.GET_BACKING_CHAIN_PATH, xspec) { rsp, HttpEntity e, EnvSpec spec -> + def cmd = JSONObjectUtil.toObject(e.body, KvmBackend.GetBackingChainCmd.class) + + List chain = [] + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(cmd, spec) + Qcow2 file = vfs.getFile(cmd.installPath) + if (file == null) { + logger.debug("Dump of whole VFS:\\n${vfs.dumpAsString()}") + } + assert file != null : "cannot find file[${cmd.installPath}]" + while (file.backingQcow2() != null) { + chain.add(file.backingQcow2().pathString()) + file = file.backingQcow2() + } + + rsp.backingChain = chain + return rsp + } } } diff --git a/testlib/src/main/java/org/zstack/testlib/SpringSpec.groovy b/testlib/src/main/java/org/zstack/testlib/SpringSpec.groovy index 88255364aa3..6346b1cc68d 100755 --- a/testlib/src/main/java/org/zstack/testlib/SpringSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/SpringSpec.groovy @@ -17,9 +17,11 @@ class SpringSpec { "NetworkManager.xml", "VmInstanceManager.xml", "AccountManager.xml", + "identity.xml", "NetworkService.xml", "volumeSnapshot.xml", "tag.xml", + "core.xml", ] Set xmls = [] @@ -45,6 +47,10 @@ class SpringSpec { include("localStorage.xml") } + void externalPrimaryStorage() { + include("ExternalPrimaryStorage.xml") + } + void vyos() { include("ApplianceVmFacade.xml") include("VirtualRouter.xml") @@ -60,6 +66,8 @@ class SpringSpec { void flatNetwork() { include("flatNetworkProvider.xml") + include("sdnController.xml") + include("vxlan.xml") } void sftpBackupStorage() { @@ -91,6 +99,17 @@ class SpringSpec { include("ceph.xml") } + void expon() { + include("expon.xml") + include("vhost.xml") + include("iscsi.xml") + } + + void zbs() { + include("zbs.xml") + include("cbd.xml") + } + void smp() { include("sharedMountPointPrimaryStorage.xml") } diff --git a/testlib/src/main/java/org/zstack/testlib/StabilityTest.groovy b/testlib/src/main/java/org/zstack/testlib/StabilityTest.groovy index 2a111709b90..e700a42a5bc 100755 --- a/testlib/src/main/java/org/zstack/testlib/StabilityTest.groovy +++ b/testlib/src/main/java/org/zstack/testlib/StabilityTest.groovy @@ -7,8 +7,6 @@ import org.zstack.utils.ShellUtils */ abstract class StabilityTest extends Test implements Case{ - private static final String targetSubCaseParamKey = "cases" - private static final String subCaseExecutionTimesKey = "times" private List targetSubCaseList @@ -107,6 +105,8 @@ abstract class StabilityTest extends Test implements Case{ }catch (Throwable t){ logger.error("stability test fails, a sub case [${subCase.class}] fails, current execution times is ${index}, ${t.message}" ,t) throw t + } finally { + assert currentEnvSpec == null: "EnvSpec is not cleaned after execute ${this.class}." } long spendTime = (new Date().getTime() - startTime) / 1000 logger.info("stability test, a sub case [${subCase.class}] test pass, current execution times is ${index}, spend time is ${spendTime} secs") diff --git a/testlib/src/main/java/org/zstack/testlib/Test.groovy b/testlib/src/main/java/org/zstack/testlib/Test.groovy index 29ca2fcd7c1..553d3084959 100755 --- a/testlib/src/main/java/org/zstack/testlib/Test.groovy +++ b/testlib/src/main/java/org/zstack/testlib/Test.groovy @@ -1,8 +1,11 @@ package org.zstack.testlib +import com.google.gson.JsonParser +import com.google.gson.JsonSyntaxException import okhttp3.OkHttpClient import org.apache.commons.lang.StringUtils import org.zstack.core.Platform +import org.zstack.core.StartMode import org.zstack.core.cloudbus.CloudBus import org.zstack.core.cloudbus.CloudBusImpl2 import org.zstack.core.componentloader.ComponentLoader @@ -14,6 +17,8 @@ import org.zstack.header.message.AbstractBeforeDeliveryMessageInterceptor import org.zstack.header.message.AbstractBeforeSendMessageInterceptor import org.zstack.header.message.Event import org.zstack.header.message.Message +import org.zstack.sdk.ErrorCode +import org.zstack.sdk.ErrorCodeList import org.zstack.sdk.SessionInventory import org.zstack.sdk.ZQLQueryReturn import org.zstack.sdk.ZSClient @@ -38,6 +43,8 @@ import java.util.logging.Logger */ abstract class Test extends ApiHelper implements Retry { final CLogger logger = Utils.getLogger(this.getClass()) + static final String targetSubCaseParamKey = "cases" + static final String subCaseExecutionTimesKey = "times" static Object deployer static Map apiPaths = new ConcurrentHashMap<>() @@ -115,6 +122,45 @@ abstract class Test extends ApiHelper implements Retry { Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.FINE) } + static SpringSpec makeSpring() { + return makeSpring { + sftpBackupStorage() + localStorage() + virtualRouter() + securityGroup() + kvm() + vyos() + flatNetwork() + ceph() + lb() + nfsPrimaryStorage() + externalPrimaryStorage() + zbs() + eip() + portForwarding() + smp() + console() + + include("LdapManagerImpl.xml") + include("captcha.xml") + include("CloudBusAopProxy.xml") + include("ZoneManager.xml") + include("webhook.xml") + include("Progress.xml") + include("vip.xml") + include("vxlan.xml") + include("mediateApiValidator.xml") + include("LongJobManager.xml") + include("log.xml") + include("HostAllocateExtension.xml") + include("sdnController.xml") + include("sugonSdnController.xml") + include("TfPortAllocator.xml") + include("HostNetworkManager.xml") + } + } + + static EnvSpec makeEnv(@DelegatesTo(strategy=Closure.DELEGATE_FIRST, value=EnvSpec.class) Closure c) { def spec = new EnvSpec() c.delegate = spec @@ -364,6 +410,11 @@ abstract class Test extends ApiHelper implements Retry { }) bus.installBeforeDeliveryMessageInterceptor(new AbstractBeforeDeliveryMessageInterceptor() { + @Override + int orderOfBeforeDeliveryMessageInterceptor() { + return 999 + } + @Override void beforeDeliveryMessage(Message msg) { if (currentEnvSpec?.notifiersOfReceivedMessages != null) { @@ -371,7 +422,7 @@ abstract class Test extends ApiHelper implements Retry { if (msgClz.isAssignableFrom(msg.getClass())) { synchronized (cs) { cs.each { - it(msg) + it.getC()(msg) } } } @@ -381,12 +432,15 @@ abstract class Test extends ApiHelper implements Retry { }) } - void buildBeanConstructor(boolean useWeb = true) { - beanConstructor = useWeb ? new WebBeanConstructor() : new BeanConstructor() + void buildBeanConstructor() { + beanConstructor = BeanConstructorFactory.getBeanConstructor(this.getCaseMode()) if (_springSpec.all) { beanConstructor.loadAll = true } else { - _springSpec.xmls.each { beanConstructor.addXml(it) } + _springSpec.xmls.each {it -> + logger.debug("add xml to bean constructor ${it}") + beanConstructor.addXml(it) + } } componentLoader = beanConstructor.build() @@ -410,6 +464,7 @@ abstract class Test extends ApiHelper implements Retry { include("ManagementNodeManager.xml") include("ApiMediator.xml") include("AccountManager.xml") + include("identity.xml") } } @@ -423,7 +478,7 @@ abstract class Test extends ApiHelper implements Retry { deployDB() } - buildBeanConstructor(NEED_WEB_SERVER) + buildBeanConstructor() nextPhase() @@ -446,17 +501,80 @@ abstract class Test extends ApiHelper implements Retry { } } + class MessageNotifier { + Closure c + AtomicInteger counter = new AtomicInteger(0) + Closure cleanup + + void delete() { + cleanup() + } + + void resetNotifier() { + counter.set(0) + } + + void assertCalled() { + assert counter.get() > 0 + } + + void assertNotCalled() { + assert counter.get() == 0 + } + + void assertCalledOnce() { + assert counter.get() == 1 + } + + Closure getC() { + return c + } + + void setC(Closure c) { + this.c = c + } + + AtomicInteger getCounter() { + return counter + } + + void setCounter(AtomicInteger counter) { + this.counter = counter + } + } + + protected MessageNotifier notifyWhenReceivedMessage(Class msgClz) { + assert currentEnvSpec != null + + MessageNotifier notifier = new MessageNotifier() + notifier.c = {} + List cs = currentEnvSpec.notifiersOfReceivedMessages.computeIfAbsent(msgClz, { Collections.synchronizedList([]) }) + synchronized (cs) { + cs.add(notifier) + } + + notifier.cleanup = { + synchronized (cs) { + cs.remove(notifier) + } + } + + return notifier + } + protected Closure notifyWhenReceivedMessage(Class msgClz, Closure c) { assert currentEnvSpec != null - List cs = currentEnvSpec.notifiersOfReceivedMessages.computeIfAbsent(msgClz, { Collections.synchronizedList([]) }) + MessageNotifier notifier = new MessageNotifier() + notifier.c = c + List cs = currentEnvSpec.notifiersOfReceivedMessages.computeIfAbsent(msgClz, { Collections.synchronizedList([]) }) synchronized (cs) { - cs.add(c) + cs.add(notifier) } return { synchronized (cs) { - cs.remove(c) + cs.remove(notifier) } } } @@ -602,6 +720,8 @@ abstract class Test extends ApiHelper implements Retry { return } + System.setProperty("inTestSuite", "true") + if (caseTypes.isEmpty()) { return } @@ -693,6 +813,8 @@ mysqldump -u root zstack > ${failureLogDir.absolutePath}/dbdump.sql logger.info("write test result of a sub case[${c.class}] of suite[${this.class}] to $fname") logger.info(caseLogEndLine) + + assert currentEnvSpec == null: "EnvSpec is not cleaned after execute ${this.class}." } } @@ -892,6 +1014,56 @@ mysqldump -u root zstack > ${failureLogDir.absolutePath}/dbdump.sql } } + static void expectApiFailure(Closure c, @DelegatesTo(strategy = Closure.OWNER_FIRST, value = ErrorCodeList.class) Closure errorCodeChecker) { + AssertionError error = null + + try { + c() + } catch (AssertionError t) { + error = t + } catch (Throwable t) { + throw new Exception("expected to get a Throwable of AssertionError but got ${t.class.name}", t) + } + + if (error == null) { + throw new ExpectedException("expect AssertionError raised, but nothing happens") + } + + def message = error.message + if (!message.startsWith("API failure: ")) { + throw new Exception("unexpected API failure", error) + } + + ErrorCodeList code + try { + int startIndex = "API failure: ".length() + int endIndex = message.indexOf(". Expression: ") + code = JSONObjectUtil.toObject(message.substring(startIndex, endIndex), ErrorCodeList) + } catch (JsonSyntaxException | IndexOutOfBoundsException ignored) { + throw new Exception("unexpected API failure", error) + } + + if (code.code == "sdk.1000") { + code = extractOriginalErrorFromSDKError(code) + } + + errorCodeChecker.resolveStrategy = Closure.OWNER_FIRST + errorCodeChecker.delegate = code + errorCodeChecker.call() + } + + /** + * MN always return HTTP code 503 when MN raise Identity ErrorCode. + * ZStack SDK will warp true error code with sdk.1000. + * + * The function would extract original error code from SDKErrorCode. + */ + static ErrorCodeList extractOriginalErrorFromSDKError(ErrorCode sdkError) { + assert sdkError.code == "sdk.1000" + def errorCodeJson = JsonParser.parseString(sdkError.details).getAsJsonObject().get("error") + return JSONObjectUtil.rehashObject(errorCodeJson, ErrorCodeList.class) + } + protected void configProperty() { return } @@ -904,4 +1076,18 @@ mysqldump -u root zstack > ${failureLogDir.absolutePath}/dbdump.sql System.setProperty(Platform.SKIP_STOP, Boolean.TRUE.toString()) } } + + StartMode getStabilityTestStartMode() { + String targetCaseList = System.getProperty(targetSubCaseParamKey) + List caseClassNameList = targetCaseList.split(",") + def count = caseClassNameList.stream().map { it -> Class.forName(it).newInstance().getCaseMode() }.distinct().count() + if (count != 1) { + throw new Exception("All cases in the case list should use the same mode") + } + return Class.forName(caseClassNameList[0]).newInstance().getCaseMode() + } + + StartMode getCaseMode() { + return StartMode.DEFAULT + } } diff --git a/testlib/src/main/java/org/zstack/testlib/TestLibController.java b/testlib/src/main/java/org/zstack/testlib/TestLibController.java index 8ea200aa56a..3b8ac96d5f2 100755 --- a/testlib/src/main/java/org/zstack/testlib/TestLibController.java +++ b/testlib/src/main/java/org/zstack/testlib/TestLibController.java @@ -8,6 +8,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.util.Objects; /** * Created by xing5 on 2017/2/12. @@ -22,6 +23,11 @@ public class TestLibController { } ) public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + if (request.getMethod().equalsIgnoreCase(RequestMethod.HEAD.toString())) { + response.setStatus(200); + return; + } + Test.handleHttp(request, response); } } diff --git a/testlib/src/main/java/org/zstack/testlib/VirtualRouterOfferingSpec.groovy b/testlib/src/main/java/org/zstack/testlib/VirtualRouterOfferingSpec.groovy index c0e54a4939a..1279c3a47df 100755 --- a/testlib/src/main/java/org/zstack/testlib/VirtualRouterOfferingSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/VirtualRouterOfferingSpec.groovy @@ -133,6 +133,10 @@ class VirtualRouterOfferingSpec extends InstanceOfferingSpec { return new VirtualRouterLoadBalancerBackend.CertificateRsp() } + simulator(VirtualRouterLoadBalancerBackend.CREATE_CERTIFICATES_PATH) { + return new VirtualRouterLoadBalancerBackend.CertificateRsp() + } + simulator(VirtualRouterConstant.VR_SET_SNAT_PATH) { return new VirtualRouterCommands.SetSNATRsp() } @@ -172,6 +176,14 @@ class VirtualRouterOfferingSpec extends InstanceOfferingSpec { simulator(VirtualRouterConstant.VR_CHANGE_DEFAULT_ROUTE_NETWORK) { return new VirtualRouterCommands.ChangeDefaultNicRsp() } + + simulator(VirtualRouterConstant.VR_HA_MASTER_DEMOTE) { + return new VirtualRouterCommands.AgentResponse() + } + + simulator(VirtualRouterConstant.VR_CONFIG_PROMTAIL) { + return new VirtualRouterCommands.AgentResponse() + } } } diff --git a/testlib/src/main/java/org/zstack/testlib/VmSpec.groovy b/testlib/src/main/java/org/zstack/testlib/VmSpec.groovy index 0dfd82348d0..b40d90c6e74 100755 --- a/testlib/src/main/java/org/zstack/testlib/VmSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/VmSpec.groovy @@ -169,6 +169,7 @@ class VmSpec extends Spec implements HasSession { delegate.l3NetworkUuids = l3Networks() delegate.defaultL3NetworkUuid = defaultL3Network() delegate.systemTags = systemTags + delegate.timeout = 60000 } postCreate { diff --git a/testlib/src/main/java/org/zstack/testlib/ZoneSpec.groovy b/testlib/src/main/java/org/zstack/testlib/ZoneSpec.groovy index 3ef05e76935..9d78316d8d4 100755 --- a/testlib/src/main/java/org/zstack/testlib/ZoneSpec.groovy +++ b/testlib/src/main/java/org/zstack/testlib/ZoneSpec.groovy @@ -1,5 +1,8 @@ package org.zstack.testlib +import org.zstack.core.db.Q +import org.zstack.header.zone.ZoneVO +import org.zstack.header.zone.ZoneVO_ import org.zstack.sdk.AttachBackupStorageToZoneAction import org.zstack.sdk.ZoneInventory import org.zstack.utils.gson.JSONObjectUtil @@ -16,6 +19,7 @@ class ZoneSpec extends Spec { List primaryStorage = [] List l2Networks = [] List virtualRouterOfferingSpecs = [] + List sdnControllerSpecs = [] protected List backupStorageToAttach = [] @@ -65,6 +69,16 @@ class ZoneSpec extends Spec { return nspec } + PrimaryStorageSpec externalPrimaryStorage(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = ExternalPrimaryStorageSpec.class) Closure c) { + def nspec = new ExternalPrimaryStorageSpec(envSpec) + c.delegate = nspec + c.resolveStrategy = Closure.DELEGATE_FIRST + c() + addChild(nspec) + primaryStorage.add(nspec) + return nspec + } + PrimaryStorageSpec smpPrimaryStorage(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = SharedMountPointPrimaryStorageSpec.class) Closure c) { def nspec = new SharedMountPointPrimaryStorageSpec(envSpec) c.delegate = nspec @@ -152,12 +166,23 @@ class ZoneSpec extends Spec { return spec } + SdnControllerSpec sdnController(@DelegatesTo(strategy = Closure.DELEGATE_FIRST, value = SdnControllerSpec.class) Closure c) { + def nspec = new SdnControllerSpec(envSpec) + c.delegate = nspec + c.resolveStrategy = Closure.DELEGATE_FIRST + c() + addChild(nspec) + sdnControllerSpecs.add(nspec) + return nspec + } + SpecID create(String uuid, String sessionId) { inventory = createZone { delegate.resourceUuid = uuid delegate.name = name delegate.sessionId = sessionId delegate.description = description + delegate.isDefault = true delegate.userTags = userTags delegate.systemTags = systemTags } as ZoneInventory @@ -188,6 +213,12 @@ class ZoneSpec extends Spec { @Override void delete(String sessionId) { if (inventory != null) { + List zoneUuidList = Q.New(ZoneVO.class) + .select(ZoneVO_.uuid) + .eq(ZoneVO_.isDefault, true) + .listValues() + assert zoneUuidList.size() <= 1 : "duplicate default zone found ${zoneUuidList}" + deleteZone { delegate.uuid = inventory.uuid delegate.sessionId = sessionId diff --git a/testlib/src/main/java/org/zstack/testlib/tool/CodeGenerator.groovy b/testlib/src/main/java/org/zstack/testlib/tool/CodeGenerator.groovy new file mode 100644 index 00000000000..02833fe6480 --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/tool/CodeGenerator.groovy @@ -0,0 +1,721 @@ +package org.zstack.testlib.tool + +import org.reflections.Reflections +import org.reflections.scanners.Scanners +import org.reflections.util.ClasspathHelper +import org.reflections.util.ConfigurationBuilder +import org.reflections.util.FilterBuilder +import org.zstack.utils.BeanUtils +import org.zstack.utils.StringTemplateUtils + +import javax.persistence.* +import java.lang.reflect.Field + +/** + * Code generator for zstack to generate inventory, mysql schema and rest api + * from jpa vo entity class. + * + * @author kayo + */ +class CodeGenerator { + private static String PACKAGE_NAME = "PACKAGE_NAME" + private static String RESOURCE_NAME = "RESOURCE_NAME" + private static String LOWER_CASE_RESOURCE_NAME = "LOWER_CASE_RESOURCE_NAME" + private static String PRIVATE_FIELDS = "PRIVATE_FIELDS" + private static String GETTER_SETTER = "GETTER_SETTER" + private static String INVENTORY_CONSTRUCTOR = "INVENTORY_CONSTRUCTOR" + private static String IMPORT_PACKAGE = "IMPORT_PACKAGE" + private static String INVENTORY_NAME = "INVENTORY_NAME" + private static String ENTITY_CLASS = "ENTITY_CLASS" + /** + * Generate inventory, mysql schema and rest api from jpa vo entity class. + * + * @param entityClass the jpa vo entity class + */ + static void generateCodeFromJpaEntity(String entity) { + ConfigurationBuilder builder = ConfigurationBuilder.build() + .setUrls(ClasspathHelper.forPackage("org.zstack")) + .setScanners(Scanners.SubTypes, Scanners.MethodsAnnotated, + Scanners.FieldsAnnotated, Scanners.TypesAnnotated, + Scanners.MethodsParameter) + .setExpandSuperTypes(false) + .filterInputsBy(new FilterBuilder().includePackage("org.zstack")); + BeanUtils.reflections = new Reflections(builder) + Class entityClass = BeanUtils.reflections.forClass(entity) + if (!entityClass.isAnnotationPresent(Entity.class) && !entityClass.isAnnotationPresent(MappedSuperclass.class)) { + System.out.printf("%s is not a JPA entity class", entityClass.getName()) + return + } + + List fields = new ArrayList<>() + // collection column fields + for (Field field : entityClass.getDeclaredFields()) { + if (!field.isAnnotationPresent(Column.class)) { + continue + } + + fields.add(field) + } + + // transfer to pojo field + List pojoFields = new ArrayList<>() + for (Field field : fields) { + PojoField pojoField = new PojoField() + pojoField.fieldName = field.getName() + pojoField.fieldType = getJavaTypeFromFieldType(field.getType()) + pojoField.columnName = convert(pojoField.fieldName, field.getType()) + pojoField.field = field + pojoFields.add(pojoField) + } + + PojoClass pojoClass = createInventory(pojoFields, entityClass) + pojoClass.pojoFields = pojoFields + createSQL(fields, entityClass) + createRestAPI(pojoClass) + } + + private static String generateImportPackage(String packageName) { + return String.format("import %s;", packageName) + } + + private static String generateInventoryConstructor(PojoField field) { + String methodName = field.fieldName.substring(0, 1).toUpperCase() + field.fieldName.substring(1) + String getterName = String.format("get%s", methodName) + return String.format(" this.%s = vo.%s();", field.fieldName, getterName) + } + + private static String generateGetterAndSetter(PojoField field) { + String methodName = field.fieldName.substring(0, 1).toUpperCase() + field.fieldName.substring(1) + String getterName = String.format("get%s", methodName) + String setterName = String.format("set%s", methodName) + + return String.format(" public %s %s() {%n" + + " return %s;%n" + + " }%n" + + "%n" + + " public void %s(%s %s) {%n" + + " this.%s = %s;%n" + + " }%n", field.fieldType, + getterName, + field.fieldName, + setterName, + field.fieldType, + field.fieldName, + field.fieldName, + field.fieldName) + } + + static class PojoField { + String fieldName + String fieldType + String columnName + Field field + } + + static class PojoClass { + String className + String packageName + String inventoryClassName + + // transient fields contains field class of jpa entity + List pojoFields = new ArrayList<>() + + // fields for inventory + List privateFields = new ArrayList<>() + Set importPackages = new HashSet<>() + + // fields for rest api and inventory + List gettersAndSetters = new ArrayList<>() + + // constructor from vo for inventory + List constructorOfFieldsFromVO = new ArrayList<>() + } + + private static PojoClass createInventory(List fields, Class entityClass) { + PojoClass pojoClass = new PojoClass() + pojoClass.packageName = entityClass.getPackage().getName().replace("vo", "inventory") + pojoClass.className = entityClass.getName() + // if class extends ResourceVO add more fields + if (entityClass.getSuperclass().getName() == "org.zstack.header.vo.ResourceVO") { + pojoClass.privateFields.add("private String uuid;") + pojoClass.gettersAndSetters.add("public String getUuid() {\n" + + " return uuid;\n" + + " }\n" + + "\n" + + " public void setUuid(String uuid) {\n" + + " this.uuid = uuid;\n" + + " }") + pojoClass.constructorOfFieldsFromVO.add(" this.uuid = vo.getUuid();") + } + + pojoClass.importPackages.add("import java.io.Serializable;") + pojoClass.importPackages.add("import org.zstack.header.configuration.PythonClassInventory;") + pojoClass.importPackages.add("import org.zstack.header.search.Inventory;") + pojoClass.importPackages.add("import java.sql.Timestamp;") + + + for (PojoField field : fields) { + if (!field.field.getClass().isPrimitive()) { + pojoClass.importPackages.add(generateImportPackage(field.field.getClass().getCanonicalName())) + } + pojoClass.gettersAndSetters.add(generateGetterAndSetter(field)) + pojoClass.constructorOfFieldsFromVO.add(generateInventoryConstructor(field)) + pojoClass.privateFields.add(String.format(" private %s %s;", field.fieldType, field.fieldName)) + } + + if (entityClass.getSimpleName().endsWith("VO")) { + pojoClass.inventoryClassName = entityClass.getSimpleName().replace("VO", "Inventory") + } else if (entityClass.getSimpleName().endsWith("AO")) { + pojoClass.inventoryClassName = entityClass.getSimpleName().replace("AO", "Inventory") + } else { + pojoClass.inventoryClassName = entityClass.getSimpleName() + "Inventory" + } + + Map bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(PRIVATE_FIELDS, pojoClass.privateFields.join("\n")) + bindings.put(GETTER_SETTER, pojoClass.gettersAndSetters.join("\n")) + bindings.put(IMPORT_PACKAGE, pojoClass.importPackages.join("\n")) + bindings.put(INVENTORY_NAME, pojoClass.inventoryClassName) + bindings.put(ENTITY_CLASS, entityClass.getSimpleName()) + bindings.put(INVENTORY_CONSTRUCTOR, pojoClass.constructorOfFieldsFromVO.join("\n")) + + writeToFile(String.format("%s.java", pojoClass.inventoryClassName), + StringTemplateUtils.createStringFromTemplate(INVENTORY_TEMPLATE, bindings)) + + return pojoClass + } + + static class ColumnDefinition { + String columnName + String columnType + boolean isPrimaryKey = false + boolean needIndex = false + } + + private static String getJavaTypeFromFieldType(Class fieldTypeClass) { + if (fieldTypeClass.isEnum()) { + return "String" + } else { + return fieldTypeClass.getSimpleName() + } + } + + private static String convert(String fieldName, Class fieldType) { + String javaType = getJavaTypeFromFieldType(fieldType) + + if (javaType == "String") { + if (fieldName.toLowerCase().contains("uuid")) { + return "varchar(32)" + } else if (fieldName.toLowerCase().contains("description")) { + return "varchar(2048)" + } else { + return "varchar(255)" + } + } else if (javaType == "Integer" || javaType == "int") { + return "int" + } else if (javaType == "Long" || javaType == "long") { + return "bigint" + } else if (javaType == "Boolean" || javaType == "boolean") { + return "boolean" + } else if (javaType == "Timestamp") { + return "timestamp" + } else if (javaType == "Date") { + return "date" + } else if (javaType == "byte[]") { + return "blob" + } else { + throw new RuntimeException(String.format("unknown java type[%s]", javaType)) + } + } + + private static void createSQL(List fields, Class entityClass) { + List columnDefinitions = new ArrayList<>() + + // if class extends ResourceVO add more fields + if (entityClass.getSuperclass().getName() == "org.zstack.header.vo.ResourceVO") { + ColumnDefinition columnDefinition = new ColumnDefinition() + columnDefinition.columnName = "uuid" + columnDefinition.columnType = "varchar(32)" + columnDefinition.isPrimaryKey = true + columnDefinition.needIndex = true + columnDefinitions.add(columnDefinition) + } + + for (Field field : fields) { + String columnName = field.getName() + boolean needIndex = false + boolean isPrimaryKey = false + + if (field.isAnnotationPresent(Column.class)) { + Column column = field.getAnnotation(Column.class) + if (!column.name().isEmpty()) { + columnName = column.name() + } else { + columnName = field.getName() + } + + needIndex = column.unique() + } + + if (field.isAnnotationPresent(Id.class)) { + isPrimaryKey = true + } + + if (field.isAnnotationPresent(Index.class)) { + needIndex = true + } + + ColumnDefinition columnDefinition = new ColumnDefinition() + columnDefinition.columnName = columnName + columnDefinition.columnType = convert(columnName, field.getType()) + columnDefinition.isPrimaryKey = isPrimaryKey + columnDefinition.needIndex = needIndex + columnDefinitions.add(columnDefinition) + } + + // generate sql in mysql innodb syntax + String schemaContent = "" + String primaryKeySQL = "" + schemaContent += String.format("CREATE TABLE IF NOT EXISTS `zstack`.`%s` (%n", entityClass.getSimpleName()) + for (ColumnDefinition columnDefinition : columnDefinitions) { + String line = String.format(" `%s` %s", columnDefinition.columnName, columnDefinition.columnType) + if (columnDefinition.isPrimaryKey) { + line = String.format("%s NOT NULL", line) + primaryKeySQL = String.format(" PRIMARY KEY (`%s`)", columnDefinition.columnName) + } else { + line = String.format("%s NULL", line) + } + + if (columnDefinition.needIndex) { + line = String.format("%s UNIQUE", line) + } + + line = String.format("%s,", line) + schemaContent += String.format(" %s%n", line) + } + + if (!primaryKeySQL.isEmpty()) { + System.out.println(primaryKeySQL) + schemaContent += String.format("%s,%n", primaryKeySQL) + } + + schemaContent += String.format(") ENGINE=InnoDB DEFAULT CHARSET=utf8;") + writeToFile(String.format("%s.sql", entityClass.getSimpleName()), schemaContent) + } + + private static void createRestAPI(PojoClass pojoClass) { + String resourceName = pojoClass.inventoryClassName.replace("Inventory", "") + String[] r = resourceName.split("(?=\\p{Upper})") + String resourceNameInRest = r.join("-").toLowerCase() + + generateQueryAPI(pojoClass, resourceName, resourceNameInRest) + generateCreateAPI(pojoClass, resourceName, resourceNameInRest) + generateUpdateAPI(pojoClass, resourceName, resourceNameInRest) + generateDeleteAPI(pojoClass, resourceName, resourceNameInRest) + } + + private static void generateDeleteAPI(PojoClass pojoClass, String resourceName, String resourceNameInRest) { + println "############ generate delete api ############%n" + + Map bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(LOWER_CASE_RESOURCE_NAME, resourceName.toLowerCase()) + + writeToFile("APIDelete${resourceName}Msg.java", + StringTemplateUtils.createStringFromTemplate(DELETE_API_TEMPLATE, bindings)) + + System.out.printf("############ generate delete event ############%n") + + bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(LOWER_CASE_RESOURCE_NAME, resourceNameInRest) + + writeToFile("APIDelete${resourceName}Event.java", + StringTemplateUtils.createStringFromTemplate(DELETE_EVENT_TEMPLATE, bindings)) + } + + private static void generateUpdateAPI(PojoClass pojoClass, String resourceName, String resourceNameInRest) { + System.out.printf("############ generate update api ############%n") + + Map bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(LOWER_CASE_RESOURCE_NAME, resourceNameInRest) + + String allPrivateFields = pojoClass.pojoFields.collect { + String.format(API_PARAM_TEMPLATE, + it.field.getAnnotation(Column.class).length(), + it.fieldType, + it.fieldName, + ) + }.join("\n") + + bindings.put(PRIVATE_FIELDS, allPrivateFields) + + String allGetters = pojoClass.gettersAndSetters.join("\n") + bindings.put(GETTER_SETTER, allGetters) + + writeToFile(String.format("APIUpdate%sMsg.java", resourceName), + StringTemplateUtils.createStringFromTemplate(UPDATE_API_TEMPLATE, bindings)) + + System.out.printf("############ generate update event ############%n") + + bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(LOWER_CASE_RESOURCE_NAME, resourceName.toLowerCase()) + + writeToFile(String.format("APIUpdate%sEvent.java", resourceName), + StringTemplateUtils.createStringFromTemplate(UPDATE_EVENT_TEMPLATE, bindings)) + } + + private static void generateCreateAPI(PojoClass pojoClass, String resourceName, String resourceNameInRest) { + System.out.printf("############ generate create api ############%n") + + Map bindings = new HashMap<>() + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(LOWER_CASE_RESOURCE_NAME, resourceNameInRest) + + String allPrivateFields = pojoClass.pojoFields.collect { + String.format(API_PARAM_TEMPLATE, + it.field.getAnnotation(Column.class).length(), + it.fieldType, + it.fieldName, + ) + }.join("\n") + + bindings.put(PRIVATE_FIELDS, allPrivateFields) + + String allGetters = pojoClass.gettersAndSetters.join("\n") + bindings.put(GETTER_SETTER, allGetters) + + writeToFile(String.format("APICreate%sMsg.java", resourceName), + StringTemplateUtils.createStringFromTemplate(CREATE_API_TEMPLATE, bindings)) + + System.out.printf("############ generate create event ############%n") + + bindings = new HashMap<>() + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(PACKAGE_NAME, pojoClass.packageName) + + writeToFile(String.format("APICreate%sEvent.java", resourceName), + StringTemplateUtils.createStringFromTemplate(CREATE_EVENT_TEMPLATE, bindings)) + } + + private static void generateQueryAPI(PojoClass pojoClass, String resourceName, String resourceNameInRest) { + System.out.printf("############ generate query api ############%n") + + Map bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(RESOURCE_NAME, resourceName) + bindings.put(LOWER_CASE_RESOURCE_NAME, resourceNameInRest) + + writeToFile(String.format("APIQuery%sMsg.java", resourceName), + StringTemplateUtils.createStringFromTemplate(QUERY_API_TEMPLATE, bindings)) + + System.out.printf("############ generate query reply ############%n") + + bindings = new HashMap<>() + bindings.put(PACKAGE_NAME, pojoClass.packageName) + bindings.put(RESOURCE_NAME, resourceName) + + writeToFile(String.format("APIQuery%sReply.java", resourceName), + StringTemplateUtils.createStringFromTemplate(QUERY_REPLY_TEMPLATE, bindings)) + } + + private static void writeToFile(String path, String content) { + new File(path).write content + println "re-written a request doc template ${path}" + println "content: ${content}" + } + + static final String QUERY_API_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.springframework.http.HttpMethod; +import org.zstack.header.query.APIQueryMessage; +import org.zstack.header.query.AutoQuery; +import org.zstack.header.rest.RestRequest; +import ${PACKAGE_NAME}.${RESOURCE_NAME}Inventory; +import ${PACKAGE_NAME}.APIQuery${RESOURCE_NAME}Reply; + +import java.util.List; + +import static java.util.Arrays.asList; + +@AutoQuery(replyClass = APIQuery${RESOURCE_NAME}Reply.class, inventoryClass = ${RESOURCE_NAME}Inventory.class) +@RestRequest( + path = "/${LOWER_CASE_RESOURCE_NAME}s", + optionalPaths = {"/${LOWER_CASE_RESOURCE_NAME}s/{uuid}"}, + responseClass = APIQuery${RESOURCE_NAME}Reply.class, + method = HttpMethod.GET +) +public class APIQuery${RESOURCE_NAME}Msg extends APIQueryMessage { + public static List __example__() { + return asList("uuid=xxx", "name=xxx"); + } +} +''' + + static final String QUERY_REPLY_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.zstack.header.query.APIQueryReply; +import ${PACKAGE_NAME}.${RESOURCE_NAME}Inventory; +import org.zstack.header.rest.RestResponse; + +import java.util.List; + +@RestResponse(allTo = "inventories") +public class APIQuery${RESOURCE_NAME}Reply extends APIQueryReply { + private List<${RESOURCE_NAME}Inventory> inventories; + + public List<${RESOURCE_NAME}Inventory> getInventories() { + return inventories; + } + + public void setInventories(List<${RESOURCE_NAME}Inventory> inventories) { + this.inventories = inventories; + } + + public static APIQuery${RESOURCE_NAME}Reply __example__() { + APIQuery${RESOURCE_NAME}Reply reply = new APIQuery${RESOURCE_NAME}Reply(); + + return reply; + } +} +''' + + static final String CREATE_API_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APICreateMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.message.DefaultTimeout; +import org.zstack.header.rest.RestRequest; +import org.zstack.header.tag.TagResourceType; +import org.zstack.header.message.APIAuditor; + +import java.util.concurrent.TimeUnit; + +@TagResourceType(${RESOURCE_NAME}VO.class) +@RestRequest( + path = "/${LOWER_CASE_RESOURCE_NAME}s", + method = HttpMethod.POST, + responseClass = APICreate${RESOURCE_NAME}Event.class, + parameterName = "params" +) +@DefaultTimeout(timeunit = TimeUnit.HOURS, value = 12) +public class APICreate${RESOURCE_NAME}Msg extends APICreateMessage implements APIAuditor { + ${PRIVATE_FIELDS} + + ${GETTER_SETTER} + + public static APICreate${RESOURCE_NAME}Msg __example__() { + APICreate${RESOURCE_NAME}Msg msg = new APICreate${RESOURCE_NAME}Msg(); + msg.setName("example"); + + return msg; + } + + @Override + public Result audit(APIMessage msg, APIEvent rsp) { + return new Result(((APICreate${RESOURCE_NAME}Msg) msg).getName(), ${RESOURCE_NAME}VO.class); + } +} +''' + + static final String CREATE_EVENT_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APICreate${RESOURCE_NAME}Event extends APIEvent { + private ${RESOURCE_NAME}Inventory inventory; + + public APICreate${RESOURCE_NAME}Event() { + } + + public APICreate${RESOURCE_NAME}Event(String apiId) { + super(apiId); + } + + public ${RESOURCE_NAME}Inventory getInventory() { + return inventory; + } + + public void setInventory(${RESOURCE_NAME}Inventory inventory) { + this.inventory = inventory; + } + + public static APICreate${RESOURCE_NAME}Event __example__() { + APICreate${RESOURCE_NAME}Event event = new APICreate${RESOURCE_NAME}Event(); + ${RESOURCE_NAME}Inventory inventory = new ${RESOURCE_NAME}Inventory(); + event.setInventory(inventory); + return event; + } +} +''' + + static final String UPDATE_API_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/${LOWER_CASE_RESOURCE_NAME}s/{uuid}", + method = HttpMethod.PUT, + responseClass = APIUpdate${RESOURCE_NAME}Event.class, + isAction = true +) +public class APIUpdate${RESOURCE_NAME}Msg extends APIMessage { + @APIParam(resourceType = ${RESOURCE_NAME}VO.class, checkAccount = true, operationTarget = true) + private String uuid; + + ${PRIVATE_FIELDS} + + ${GETTER_SETTER} + + public static APIUpdate${RESOURCE_NAME}Msg __example__() { + APIUpdate${RESOURCE_NAME}Msg msg = new APIUpdate${RESOURCE_NAME}Msg(); + msg.setUuid(uuid()); + msg.setName("example"); + + return msg; + } +} +''' + + static final String UPDATE_EVENT_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse(allTo = "inventory") +public class APIUpdate${RESOURCE_NAME}Event extends APIEvent { + private ${RESOURCE_NAME}Inventory inventory; + + public APIUpdate${RESOURCE_NAME}Event() { + } + + public APIUpdate${RESOURCE_NAME}Event(String apiId) { + super(apiId); + } + + public ${RESOURCE_NAME}Inventory getInventory() { + return inventory; + } + + public void setInventory(${RESOURCE_NAME}Inventory inventory) { + this.inventory = inventory; + } + + public static APIUpdate${RESOURCE_NAME}Event __example__() { + APIUpdate${RESOURCE_NAME}Event event = new APIUpdate${RESOURCE_NAME}Event(); + return event; + } +} +''' + static final String DELETE_API_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.springframework.http.HttpMethod; +import org.zstack.header.message.APIMessage; +import org.zstack.header.message.APIParam; +import org.zstack.header.rest.RestRequest; + +@RestRequest( + path = "/${LOWER_CASE_RESOURCE_NAME}s/{uuid}", + method = HttpMethod.DELETE, + responseClass = APIDelete${RESOURCE_NAME}Event.class +) +public class APIDelete${RESOURCE_NAME}Msg extends APIMessage { + @APIParam(resourceType = ${RESOURCE_NAME}VO.class, checkAccount = true, operationTarget = true) + private String uuid; + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public static APIDelete${RESOURCE_NAME}Msg __example__() { + APIDelete${RESOURCE_NAME}Msg msg = new APIDelete${RESOURCE_NAME}Msg(); + msg.setUuid(uuid()); + return msg; + } +} +''' + + static final String DELETE_EVENT_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +import org.zstack.header.message.APIEvent; +import org.zstack.header.rest.RestResponse; + +@RestResponse +public class APIDelete${RESOURCE_NAME}Event extends APIEvent { + public APIDelete${RESOURCE_NAME}Event() { + } + + public APIDelete${RESOURCE_NAME}Event(String apiId) { + super(apiId); + } + + public static APIDelete${RESOURCE_NAME}Event __example__() { + APIDelete${RESOURCE_NAME}Event event = new APIDelete${RESOURCE_NAME}Event(); + return event; + } +} +''' + + static final String INVENTORY_TEMPLATE = ''' +package ${PACKAGE_NAME}; + +${IMPORT_PACKAGE} + +@Inventory(mappingVOClass = ${ENTITY_CLASS}.class) +@PythonClassInventory +public class ${INVENTORY_NAME} implements Serializable, Cloneable { + ${PRIVATE_FIELDS} + + ${GETTER_SETTER} + + public ${INVENTORY_NAME}() {} + + public ${INVENTORY_NAME}(${ENTITY_CLASS} vo) { +${INVENTORY_CONSTRUCTOR} + } + + public static ${INVENTORY_NAME} valueOf(${ENTITY_CLASS} vo) { + return new ${INVENTORY_NAME}(vo); + } + + public static List<${INVENTORY_NAME}> valueOf(Collection<${ENTITY_CLASS}> vos) { + List<${INVENTORY_NAME}> invs = new ArrayList<>(); + for (${ENTITY_CLASS} vo : vos) { + invs.add(valueOf(vo)); + } + + return invs; + } +} +''' + + static final String API_PARAM_TEMPLATE = ''' + @APIParam(maxLength = %s) + private %s %s;''' +} diff --git a/testlib/src/main/java/org/zstack/testlib/tool/TermsGenerator.groovy b/testlib/src/main/java/org/zstack/testlib/tool/TermsGenerator.groovy new file mode 100644 index 00000000000..9be49ec2ed9 --- /dev/null +++ b/testlib/src/main/java/org/zstack/testlib/tool/TermsGenerator.groovy @@ -0,0 +1,124 @@ +package org.zstack.testlib.tool + +import org.apache.logging.log4j.util.Strings +import org.zstack.core.Platform +import org.zstack.header.vo.EO +import org.zstack.header.vo.ResourceVO +import org.zstack.utils.path.PathUtil + +import javax.persistence.Entity + +class TermsGenerator { + static String termFileFormat = "terms_%s.properties" + + static String translationFileFormat = "translation_from_%s_to_%s.properties" + + static List generateTermsOfZStackVersion(String version) { + String outputDir = System.getProperty("user.home") + + Set resourceVOs = Platform.reflections.getSubTypesOf(ResourceVO.class) + resourceVOs = resourceVOs.findAll { return it.isAnnotationPresent(Entity.class) && !it.isAnnotationPresent(EO.class) } + + List linesFromProperties = loadFileFromResource(PathUtil.join(outputDir, String.format(termFileFormat, version))) + + List termKeysFromResourceConfig = resourceVOs.collect { + // VmInstanceVO -> VmInstance + return it.simpleName.replaceAll("VO\$", "").replaceAll("EO\$", "") + }.sort() + + List missingTerms = termKeysFromResourceConfig.findAll { termKey -> + return !linesFromProperties.any { it.term == termKey } + } + + List linesToWrite = linesFromProperties + missingTerms.collect { + return new TermTranslatePropertyLine(it, "") + } + + String content = linesToWrite.collect { it.toString() }.join("\n") + + new File(PathUtil.join(outputDir, String.format(termFileFormat, version))).write(content) + return linesToWrite + } + + static generateTermsFromJpaEntities(String replaceTo) { + List cloudTerms = generateTermsOfZStackVersion("cloud") + List zsvTerms = generateTermsOfZStackVersion("zsv") + + if (replaceTo == null) { + replaceTo = "cloud" + } + + Map replaceMap = [:] + if (replaceTo == "cloud") { + cloudTerms.each { + replaceMap.put(it.term, it) + } + + zsvTerms.each { + if (replaceMap.containsKey(it.term)) { + replaceMap.get(it.term).replaceTo = it.translation + } + } + } else if (replaceTo == "zsv") { + zsvTerms.each { + replaceMap.put(it.term, it) + } + + cloudTerms.each { + if (replaceMap.containsKey(it.term)) { + replaceMap.get(it.term).replaceTo = it.translation + } + } + } + + String outputDir = System.getProperty("user.home") + String content = replaceMap + .values() + .findAll { Strings.isNotBlank(it.translation) && Strings.isNotBlank(it.replaceTo) } + .collect { it.toTranslationString() } + .join("\n") + new File(PathUtil.join(outputDir, String.format(translationFileFormat, replaceTo, replaceTo == "cloud" ? "zsv" : "cloud"))).write(content) + } + + static List loadFileFromResource(String fileName) { + if (!PathUtil.exists(fileName)) { + return new ArrayList() + } + + InputStream is = new FileInputStream(fileName) + String content = new String(is.getBytes()) + is.close() + + return content.split("\n").collect { + String[] tokens = it.split("=") + + String token1 + if (tokens.size() > 1) + token1 = tokens[1].trim() + else + token1 = "" + + TermTranslatePropertyLine line = new TermTranslatePropertyLine(tokens[0].trim(), token1) + return line + } + } + + static class TermTranslatePropertyLine { + TermTranslatePropertyLine(String term, String translation) { + this.term = term + this.translation = translation + } + + String term + String translation + String replaceTo + + String toString() { + return String.format("%s=%s", term, translation) + } + + String toTranslationString() { + return String.format("%s=%s", translation, replaceTo) + } + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/util/TProxy.groovy b/testlib/src/main/java/org/zstack/testlib/util/TProxy.groovy index 77f2beeeec8..ce5442555cf 100755 --- a/testlib/src/main/java/org/zstack/testlib/util/TProxy.groovy +++ b/testlib/src/main/java/org/zstack/testlib/util/TProxy.groovy @@ -69,6 +69,33 @@ class TProxy { } } + TProxy(Object adaptee, Class[] argumentTypes, Object[] arguments) { + assert adaptee != null : "call TProxy(Class adapteeClass) instead" + + Enhancer enhancer = new Enhancer() + enhancer.setSuperclass(adaptee.getClass()) + enhancer.setCallback(new ProxyHandler()) + try { + proxyedObject = enhancer.create(argumentTypes, arguments) + if (adaptee != null) { + FieldUtils.getAllFields(adaptee.getClass()).each { f -> + if (Modifier.isStatic(f.modifiers) || Modifier.isFinal(f.modifiers)) { + return + } + + f.setAccessible(true) + f.set(proxyedObject, f.get(adaptee)) + } + } + } catch (IllegalArgumentException e) { + if (e.getMessage().contains("Superclass has no null constructors" )) { + throw new Exception("the class ${adaptee.getClass()} has no non-argument constructor", e) + } + + throw e + } + } + /** * * @param name: 要替换函数的名称 diff --git a/testlib/src/main/java/org/zstack/testlib/util/search/SDKQueryTestValidator.groovy b/testlib/src/main/java/org/zstack/testlib/util/search/SDKQueryTestValidator.groovy index 8dc15923376..87c92b0cb18 100755 --- a/testlib/src/main/java/org/zstack/testlib/util/search/SDKQueryTestValidator.groovy +++ b/testlib/src/main/java/org/zstack/testlib/util/search/SDKQueryTestValidator.groovy @@ -4,6 +4,7 @@ import junit.framework.Assert import org.zstack.header.exception.CloudRuntimeException import org.zstack.header.query.QueryOp import org.zstack.header.query.Unqueryable +import org.zstack.header.rest.APINoSee import org.zstack.sdk.QueryAction import org.zstack.testlib.Test import org.zstack.utils.FieldUtils @@ -32,7 +33,11 @@ class SDKQueryTestValidator { continue } - ret.add(f) + if (f.isAnnotationPresent(APINoSee.class)) { + continue + } + + ret.add(f) } return ret @@ -149,12 +154,14 @@ class SDKQueryTestValidator { String queryOp String queryValue queryName = f.name - if (value != null) { - queryOp = QueryOp.EQ.toString() - queryValue = value.toString() - } else { + if (value == null) { queryOp = " " + QueryOp.IS_NULL.toString() queryValue = "" + } else if (value instanceof String && ((String) value).isEmpty()) { + continue + } else { + queryOp = QueryOp.EQ.toString() + queryValue = value.toString() } action.conditions.add("${queryName}${queryOp}${queryValue}".toString()) } diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/CephRaw.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/CephRaw.groovy index 96d66f50822..a8315ebab25 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/CephRaw.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/CephRaw.groovy @@ -44,6 +44,7 @@ class CephRaw extends Raw { } parent = null + update() return this } } diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/Qcow2.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/Qcow2.groovy index 056a42ad335..74ccf075f4d 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/Qcow2.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/Qcow2.groovy @@ -168,5 +168,36 @@ class Qcow2 extends Volume { return baseImage } -} + List getChildren() { + List children = [] + vfs.walkFileSystem { vfile -> + if (vfile instanceof Qcow2 && vfile.backingFile != null && vfile.backingFile.toAbsolutePath().toString() == pathString()) { + children.add(vfile) + } + } + return children + } + + static Qcow2 commit(VFS vfs, Qcow2 top, Qcow2 base) { + assert top != null && base != null: "commit requires non-null top and base" + assert top.pathString() != base.pathString(): "top and base must differ" + + top.backingFile = null + top.update() + List childrenOfTop = top.getChildren() + childrenOfTop.forEach { children -> + children.backingFile = vfs.getPath(base.pathString()) + children.update() + } + return base + } + + static void pull(VFS vfs, String base, Qcow2 volumePath) { + if (base == null) { + volumePath.rebase((String) null) + } else { + volumePath.rebase(base) + } + } +} diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/VFS.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/VFS.groovy index fc9ee5ff495..b8751b8d5bb 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/VFS.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/VFS.groovy @@ -29,7 +29,9 @@ class VFS { } VFS() { - fileSystem = Jimfs.newFileSystem(Configuration.unix()) + fileSystem = Jimfs.newFileSystem(Configuration.unix().toBuilder() + .setAttributeViews("basic", "owner", "posix", "unix") + .build()) } static void vfsHook(String path, EnvSpec env, Closure func) { @@ -97,6 +99,55 @@ class VFS { return Files.move(from, to, options) } + List link(String linkPath, String existingPath) { + return link(getPath(linkPath), getPath(existingPath)) + } + + List link(Path link, Path existing) { + if (!isDir(existing)) { + logger.debug("[VFS(id: ${id}) LINK FILE]: EXISTING ${existing.toAbsolutePath().toString()} LINK ${link.toAbsolutePath().toString()}") + return [Files.createLink(link, existing)] + } + + List links = [] + Files.walk(existing).forEach {existingPath -> + String newPath = existingPath.toString().replace(existing.toString(), link.toString()) + if (isDir(existingPath)) { + Files.createDirectories(getPath(newPath)) + return + } + + if (Files.isSameFile(getPath(newPath), existingPath)) { + return + } + + logger.debug("[VFS(id: ${id}) LINK FILE]: EXISTING ${existing.toAbsolutePath().toString()} LINK ${link.toAbsolutePath().toString()}") + links.add(Files.createLink(getPath(newPath), existingPath)) + } + return links + } + + void unlink(String linkStr, boolean onlyLinkedPath) { + def f = getPath(linkStr) + if (!Files.isDirectory(f)) { + if (!onlyLinkedPath || Files.getAttribute(f, "unix:nlink") > 1) { + logger.debug("[VFS(id: ${id}) DELETE]: ${f.toAbsolutePath().toString()}") + Files.delete(f) + } + return + } + Files.walk(f).forEach { path -> + if (Files.isDirectory(path)) { + return + } + + if (!onlyLinkedPath || Files.getAttribute(f, "unix:nlink") > 1) { + logger.debug("[VFS(id: ${id}) DELETE]: ${path.toAbsolutePath().toString()}") + Files.delete(path) + } + } + } + boolean exists(String path) { return exists(getPath(path)) } @@ -170,13 +221,16 @@ class VFS { } static T getFile(String pathStr, VFS vfs) { - Path path = vfs.getPath(pathStr) + return getFile(vfs.getPath(pathStr), vfs) + } + + static T getFile(Path path, VFS vfs) { if (!Files.exists(path)) { return null } if (!Files.isRegularFile(path)) { - throw new FileNotFoundException("${pathStr} is not a file") + throw new FileNotFoundException("${path.toString()} is not a file") } String json = Files.readAllLines(path).join("\n") @@ -192,7 +246,21 @@ class VFS { return f } + def T getFile(Path path, boolean errorOnMissing=false) { + T f = getFile(path, this) + if (f == null && errorOnMissing) { + throw new FileNotFoundException("file[${path.toString()}] not found on VFS[id: ${id}]") + } + + return f + } + private static VFSFile doFindFile(VFS vfs, Path path, Function c) { + // check exists to prevent NoSuchFileException from requiredExist() in Files.list + if (!Files.exists(path)) { + return null + } + if (Files.isRegularFile(path)) { VFSFile f = vfs.getFile(path.toAbsolutePath().toString(), true) if (c.apply(f)) { @@ -251,9 +319,12 @@ class VFS { } createDirectories(p.getParent()) + def originPath = f.path f.path = p write(p, f.asJSONString()) - return getFile(f.pathString(), true) + VFSFile ret = getFile(f.pathString(), true) + f.path = originPath // restore original path + return ret } VFSFile createFileFrom(VFSFile f) { diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/extensions/VFSPrimaryStorageTakeSnapshotBackend.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/extensions/VFSPrimaryStorageTakeSnapshotBackend.groovy index 9570207a116..bdc327fc41f 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/extensions/VFSPrimaryStorageTakeSnapshotBackend.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/extensions/VFSPrimaryStorageTakeSnapshotBackend.groovy @@ -3,10 +3,10 @@ package org.zstack.testlib.vfs.extensions import org.springframework.http.HttpEntity import org.zstack.header.storage.snapshot.TakeSnapshotsOnKvmJobStruct import org.zstack.header.storage.snapshot.TakeSnapshotsOnKvmResultStruct -import org.zstack.header.storage.snapshot.VolumeSnapshotInventory import org.zstack.header.volume.VolumeInventory import org.zstack.kvm.KVMAgentCommands import org.zstack.testlib.EnvSpec +import org.zstack.testlib.vfs.Qcow2 interface VFSPrimaryStorageTakeSnapshotBackend { String getPrimaryStorageType() @@ -24,4 +24,8 @@ interface VFSPrimaryStorageTakeSnapshotBackend { List takeSnapshotsOnVolumes(String primaryStorageUuid, HttpEntity e, EnvSpec spec, List snapshotJobs) void blockStream(HttpEntity e, EnvSpec spec, VolumeInventory volume) + + Qcow2 blockCommit(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockCommitCmd cmd, VolumeInventory volume) + + Qcow2 blockPull(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockPullCmd cmd, VolumeInventory volume) } diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/storage/LocalStorageVFSPrimaryStorageTakeSnapshotBackend.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/storage/LocalStorageVFSPrimaryStorageTakeSnapshotBackend.groovy index f6ee6e62d3c..9d59b128586 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/storage/LocalStorageVFSPrimaryStorageTakeSnapshotBackend.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/storage/LocalStorageVFSPrimaryStorageTakeSnapshotBackend.groovy @@ -1,7 +1,6 @@ package org.zstack.testlib.vfs.storage import org.springframework.http.HttpEntity -import org.zstack.core.Platform import org.zstack.core.db.Q import org.zstack.core.db.SQL import org.zstack.header.storage.primary.PrimaryStorageVO @@ -39,6 +38,11 @@ class LocalStorageVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSy VFS vfs = LocalStorageSpec.vfs(LocalStorageSpec.hostUuidFromHTTPHeaders(e), storagePath, spec) + if (cmd.isOnline()) { + vfs.Assert(vfs.exists(cmd.installPath), "cannot find file[${cmd.installPath}]") + vfs.delete(cmd.installPath) + } + VFSSnapshot snapshot = new VFSSnapshot() if (cmd.fullSnapshot) { Qcow2 vol = vfs.getFile(cmd.volumeInstallPath) @@ -68,27 +72,26 @@ class LocalStorageVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSy .param("deviceId", cmd.volume.getDeviceId()) .find() - assert src : "cannot find source snapshot[path: ${cmd.srcPath}] of VM[uuid: ${cmd.vmUuid}] in database" - VolumeSnapshotInventory sp = src.toInventory() + assert src || cmd.fullRebase: "cannot find source snapshot[path: ${cmd.srcPath}] of VM[uuid: ${cmd.vmUuid}] in database" + VolumeSnapshotInventory sp = src?.toInventory() String storagePath = Q.New(PrimaryStorageVO.class) .select(PrimaryStorageVO_.mountPath) - .eq(PrimaryStorageVO_.uuid, sp.primaryStorageUuid) + .eq(PrimaryStorageVO_.uuid, volume.primaryStorageUuid) .findValue() VFS vfs = LocalStorageSpec.vfs(LocalStorageSpec.hostUuidFromHTTPHeaders(e), storagePath, spec) - vfs.Assert(vfs.exists(sp.primaryStorageInstallPath), "missing snapshot install ${sp.primaryStorageInstallPath}") - Qcow2 from = vfs.getFile(sp.primaryStorageInstallPath, true) - vfs.Assert(vfs.exists(volume.installPath), "missing snapshot install ${sp.primaryStorageInstallPath}") + + vfs.Assert(vfs.exists(volume.installPath), "missing snapshot install ${volume.installPath}") Qcow2 to = vfs.getFile(volume.installPath, true) assert to.backingFile != null : "the target[${to.pathString()}] volume has no backing file" - if (to.backingQcow2().pathString() == from.pathString()) { - assert cmd.fullRebase : "the snapshot is volume's backing file, this must be a fullRebase: ${e.body}" - } if (cmd.fullRebase) { to.rebase((String)null) } else { + vfs.Assert(vfs.exists(sp.primaryStorageInstallPath), "missing snapshot install ${sp.primaryStorageInstallPath}") + Qcow2 from = vfs.getFile(sp.primaryStorageInstallPath, true) + assert to.backingQcow2().pathString() != from.pathString() : "the snapshot is volume's backing file, this must be a fullRebase: ${e.body}" to.rebase(from.path) } } @@ -113,6 +116,34 @@ class LocalStorageVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSy .find() VFS vfs = LocalStorageSpec.vfs(LocalStorageSpec.hostUuidFromHTTPHeaders(e), storagePath, spec) + if (vfs.exists(volume.getInstallPath())) { + vfs.delete(volume.getInstallPath()) + } blockStream(vfs, volume) } + + @Override + Qcow2 blockCommit(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockCommitCmd cmd, VolumeInventory volume) { + String storagePath = Q.New(PrimaryStorageVO.class) + .select(PrimaryStorageVO_.mountPath) + .eq(PrimaryStorageVO_.uuid, volume.primaryStorageUuid) + .findValue() + VFS vfs = LocalStorageSpec.vfs(LocalStorageSpec.hostUuidFromHTTPHeaders(e), storagePath, spec) + Qcow2 top = vfs.getFile(cmd.top, true) + Qcow2 base = vfs.getFile(cmd.base, true) + Qcow2.commit(vfs, top, base) + return vfs.getFile(cmd.base, true) + } + + @Override + Qcow2 blockPull(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockPullCmd cmd, VolumeInventory volume) { + String storagePath = Q.New(PrimaryStorageVO.class) + .select(PrimaryStorageVO_.mountPath) + .eq(PrimaryStorageVO_.uuid, volume.primaryStorageUuid) + .findValue() + VFS vfs = LocalStorageSpec.vfs(LocalStorageSpec.hostUuidFromHTTPHeaders(e), storagePath, spec) + Qcow2 volumePath = vfs.getFile(volume.getInstallPath(), true) + Qcow2.pull(vfs, cmd.base, volumePath) + return vfs.getFile(volume.getInstallPath(), true) + } } diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/storage/NFSVFSPrimaryStorageTakeSnapshotBackend.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/storage/NFSVFSPrimaryStorageTakeSnapshotBackend.groovy index c79edefbe01..a5826b0d973 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/storage/NFSVFSPrimaryStorageTakeSnapshotBackend.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/storage/NFSVFSPrimaryStorageTakeSnapshotBackend.groovy @@ -11,6 +11,8 @@ import org.zstack.kvm.KVMAgentCommands import org.zstack.storage.primary.nfs.NfsPrimaryStorageConstant import org.zstack.testlib.EnvSpec import org.zstack.testlib.NfsPrimaryStorageSpec +import org.zstack.testlib.vfs.Qcow2 +import org.zstack.testlib.vfs.VFS import org.zstack.testlib.vfs.extensions.VFSPrimaryStorageTakeSnapshotBackend import org.zstack.testlib.vfs.extensions.VFSSnapshot @@ -26,7 +28,13 @@ class NFSVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSystemBased .select(VolumeVO_.primaryStorageUuid) .eq(VolumeVO_.uuid, cmd.volumeUuid) .findValue() - return doTakeSnapshot(NfsPrimaryStorageSpec.vfs(primaryStorageUuid, spec), cmd, volume) + VFS vfs = NfsPrimaryStorageSpec.vfs(primaryStorageUuid, spec) + if (cmd.isOnline()) { + vfs.Assert(vfs.exists(cmd.installPath), "cannot find file[${cmd.installPath}]") + vfs.delete(cmd.installPath) + } + + return doTakeSnapshot(vfs, cmd, volume) } @Override @@ -40,6 +48,27 @@ class NFSVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSystemBased @Override void blockStream(HttpEntity e, EnvSpec spec, VolumeInventory volume) { - blockStream(NfsPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec), volume) + VFS vfs = NfsPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + if (vfs.exists(volume.getInstallPath())) { + vfs.delete(volume.getInstallPath()) + } + blockStream(vfs, volume) + } + + @Override + Qcow2 blockCommit(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockCommitCmd cmd, VolumeInventory volume) { + VFS vfs = NfsPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + Qcow2 top = vfs.getFile(cmd.top, true) + Qcow2 base = vfs.getFile(cmd.base, true) + Qcow2.commit(vfs, top, base) + return vfs.getFile(cmd.base, true) + } + + @Override + Qcow2 blockPull(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockPullCmd cmd, VolumeInventory volume) { + VFS vfs = NfsPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + Qcow2 volumePath = vfs.getFile(volume.getInstallPath(), true) + Qcow2.pull(vfs, cmd.base, volumePath) + return vfs.getFile(volume.getInstallPath(), true) } } diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/storage/SMPVFSPrimaryStorageTakeSnapshotBackend.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/storage/SMPVFSPrimaryStorageTakeSnapshotBackend.groovy index 4e4f84b90a2..9cea533a330 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/storage/SMPVFSPrimaryStorageTakeSnapshotBackend.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/storage/SMPVFSPrimaryStorageTakeSnapshotBackend.groovy @@ -1,16 +1,18 @@ package org.zstack.testlib.vfs.storage import org.springframework.http.HttpEntity -import org.zstack.core.Platform +import org.zstack.core.db.Q import org.zstack.header.storage.snapshot.TakeSnapshotsOnKvmJobStruct import org.zstack.header.storage.snapshot.TakeSnapshotsOnKvmResultStruct import org.zstack.header.volume.VolumeInventory +import org.zstack.header.volume.VolumeVO +import org.zstack.header.volume.VolumeVO_ import org.zstack.kvm.KVMAgentCommands import org.zstack.storage.primary.smp.SMPConstants import org.zstack.testlib.EnvSpec -import org.zstack.testlib.NfsPrimaryStorageSpec import org.zstack.testlib.SharedMountPointPrimaryStorageSpec import org.zstack.testlib.vfs.Qcow2 +import org.zstack.testlib.vfs.VFS import org.zstack.testlib.vfs.extensions.VFSPrimaryStorageTakeSnapshotBackend import org.zstack.testlib.vfs.extensions.VFSSnapshot @@ -22,7 +24,12 @@ class SMPVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSystemBased @Override VFSSnapshot takeSnapshot(HttpEntity e, EnvSpec spec, KVMAgentCommands.TakeSnapshotCmd cmd, VolumeInventory volume) { - return doTakeSnapshot(SharedMountPointPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec), cmd, volume) + def vfs = SharedMountPointPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + if (cmd.isOnline()) { + vfs.Assert(vfs.exists(cmd.installPath), "cannot find file[${cmd.installPath}]") + vfs.delete(cmd.installPath) + } + return doTakeSnapshot(vfs, cmd, volume) } @Override @@ -37,6 +44,27 @@ class SMPVFSPrimaryStorageTakeSnapshotBackend implements AbstractFileSystemBased @Override void blockStream(HttpEntity e, EnvSpec spec, VolumeInventory volume) { - blockStream(SharedMountPointPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec), volume) + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + if (vfs.exists(volume.getInstallPath())) { + vfs.delete(volume.getInstallPath()) + } + blockStream(vfs, volume) + } + + @Override + Qcow2 blockCommit(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockCommitCmd cmd, VolumeInventory volume) { + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + Qcow2 top = vfs.getFile(cmd.top, true) + Qcow2 base = vfs.getFile(cmd.base, true) + Qcow2.commit(vfs, top, base) + return vfs.getFile(cmd.base, true) + } + + @Override + Qcow2 blockPull(HttpEntity e, EnvSpec spec, KVMAgentCommands.BlockPullCmd cmd, VolumeInventory volume) { + VFS vfs = SharedMountPointPrimaryStorageSpec.vfs(volume.getPrimaryStorageUuid(), spec) + Qcow2 volumePath = vfs.getFile(volume.getInstallPath(), true) + Qcow2.pull(vfs, cmd.base, volumePath) + return vfs.getFile(volume.getInstallPath(), true) } } diff --git a/testlib/src/main/java/org/zstack/testlib/vfs/tree/Qcow2Tree.groovy b/testlib/src/main/java/org/zstack/testlib/vfs/tree/Qcow2Tree.groovy index 1e00ef8e437..73365445c3b 100755 --- a/testlib/src/main/java/org/zstack/testlib/vfs/tree/Qcow2Tree.groovy +++ b/testlib/src/main/java/org/zstack/testlib/vfs/tree/Qcow2Tree.groovy @@ -60,11 +60,12 @@ class Qcow2Tree { Map allNodes = [:] - vfs.walkFileSystem { f -> - if (!(f instanceof Qcow2)) { + vfs.walkFileSystem { vf -> + if (!(vf instanceof Qcow2)) { return } + Qcow2 f = (Qcow2) vf Qcow2Node n = allNodes[f.pathString()] if (n == null) { n = new Qcow2Node(qcow2: f, children: []) diff --git a/utils/pom.xml b/utils/pom.xml index a02fe409e09..55be08113bb 100644 --- a/utils/pom.xml +++ b/utils/pom.xml @@ -4,7 +4,7 @@ zstack org.zstack - 4.4.0 + 5.4.0 .. utils @@ -32,10 +32,6 @@ com.google.code.gson gson - - org.springframework - spring-web - org.apache.logging.log4j log4j-api @@ -73,14 +69,10 @@ gentyref - com.jcraft + com.github.mwiede jsch - 0.1.55 + 0.2.9 - com.hierynomus sshj @@ -113,20 +105,15 @@ com.squareup.okhttp3 logging-interceptor - - org.apache.poi - poi - 4.1.2 - org.apache.poi poi-ooxml - 4.1.2 + 5.2.2 org.apache.commons commons-csv - 1.5 + 1.9.0 com.googlecode.java-ipv6 @@ -136,7 +123,7 @@ info.debatty java-string-similarity - RELEASE + 2.0.0 com.github.sisyphsu @@ -144,20 +131,12 @@ 1.0.4 - com.esotericsoftware - kryo - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - - - com.fasterxml.jackson.core - jackson-databind + org.yaml + snakeyaml - com.fasterxml.jackson.core - jackson-core + javax.servlet + servlet-api diff --git a/utils/src/main/java/org/zstack/utils/BeanUtils.java b/utils/src/main/java/org/zstack/utils/BeanUtils.java index c98fa906efe..be92060c261 100755 --- a/utils/src/main/java/org/zstack/utils/BeanUtils.java +++ b/utils/src/main/java/org/zstack/utils/BeanUtils.java @@ -4,6 +4,8 @@ import org.reflections.Reflections; import org.reflections.scanners.*; import org.reflections.util.ClasspathHelper; +import org.reflections.util.ConfigurationBuilder; +import org.reflections.util.FilterBuilder; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; @@ -17,9 +19,18 @@ /** */ public class BeanUtils { - public static Reflections reflections = new Reflections(ClasspathHelper.forPackage("org.zstack"), - new SubTypesScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner(), - new TypeAnnotationsScanner(), new MethodParameterScanner()); + public static Reflections reflections; + + static { + ConfigurationBuilder builder = ConfigurationBuilder.build() + .setUrls(ClasspathHelper.forPackage("org.zstack")) + .setScanners(Scanners.SubTypes, Scanners.MethodsAnnotated, + Scanners.FieldsAnnotated, Scanners.TypesAnnotated, + Scanners.MethodsParameter) + .setExpandSuperTypes(false) + .filterInputsBy(new FilterBuilder().includePackage("org.zstack")); + reflections = new Reflections(builder); + } private static Object getProperty(Object bean, Iterator it) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException { String path = it.next(); diff --git a/utils/src/main/java/org/zstack/utils/CharacterUtils.java b/utils/src/main/java/org/zstack/utils/CharacterUtils.java index 57cbad4dba8..1e2d3070283 100644 --- a/utils/src/main/java/org/zstack/utils/CharacterUtils.java +++ b/utils/src/main/java/org/zstack/utils/CharacterUtils.java @@ -2,12 +2,21 @@ import org.apache.commons.lang.CharUtils; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * @Author: fubang * @Date: 2018/6/25 */ public class CharacterUtils { - public static boolean checkCharacter(String s){ + public static boolean checkCharacter(String s) { return s.codePoints().allMatch(code -> CharUtils.isAsciiPrintable((char) code)); } + + public static boolean checkCharactersByRegex(String regex, String s) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(s); + return matcher.matches(); + } } diff --git a/utils/src/main/java/org/zstack/utils/CollectionDSL.java b/utils/src/main/java/org/zstack/utils/CollectionDSL.java index 8465f2a3ba0..fbfa8a8f5bb 100755 --- a/utils/src/main/java/org/zstack/utils/CollectionDSL.java +++ b/utils/src/main/java/org/zstack/utils/CollectionDSL.java @@ -40,4 +40,11 @@ public static List lists(List list, T...els) { Collections.addAll(lst, els); return lst; } + + public static List concat(List list, List list2) { + ArrayList lst = new ArrayList<>(list2.size() + list.size()); + lst.addAll(list); + lst.addAll(list2); + return lst; + } } diff --git a/utils/src/main/java/org/zstack/utils/CollectionUtils.java b/utils/src/main/java/org/zstack/utils/CollectionUtils.java index af90a890357..b04a0635668 100755 --- a/utils/src/main/java/org/zstack/utils/CollectionUtils.java +++ b/utils/src/main/java/org/zstack/utils/CollectionUtils.java @@ -8,6 +8,7 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; +import java.util.stream.Collectors; /** */ @@ -51,27 +52,36 @@ public static List transformToList(Collection from, Function return ret; } - public static Set transformToSet(Collection from, Function func) { - Set ret = new HashSet(); - for (V v : from) { - K k = func.call(v); - if (k == null) { - continue; - } - ret.add(k); - } + public static List transform(Collection from, java.util.function.Function mapper) { + return from.stream().map(mapper).collect(Collectors.toList()); + } - return ret; + public static List transformAndRemoveNull(Collection from, java.util.function.Function mapper) { + return from.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList()); + } + + public static List filter(Collection from, Predicate tester) { + return from.stream().filter(tester).collect(Collectors.toList()); + } + + public static T findOneOrNull(Collection from, Predicate tester) { + return from.stream().filter(tester).findFirst().orElse(null); } - public static Set transformToSet(Collection from, ListFunction func) { + public static Map toMap(Collection from, + java.util.function.Function keyMapper, + java.util.function.Function valueMapper) { + return from.stream().collect(Collectors.toMap(keyMapper, valueMapper)); + } + + public static Set transformToSet(Collection from, Function func) { Set ret = new HashSet(); for (V v : from) { - List k = func.call(v); + K k = func.call(v); if (k == null) { continue; } - ret.addAll(k); + ret.add(k); } return ret; @@ -130,4 +140,29 @@ public static void shuffleByKeySeed(List list, String keySeed, java.util. } list.addAll(result); } + + public static List merge(List listA, List listB) { + listA = org.apache.commons.collections.CollectionUtils.isNotEmpty(listA) ? listA : new ArrayList(); + listB = org.apache.commons.collections.CollectionUtils.isNotEmpty(listB) ? listB : new ArrayList(); + List list = new ArrayList(); + list.addAll(listA); + list.addAll(listB); + return list; + } + + public static boolean isEmpty(Collection coll) { + return coll == null || coll.isEmpty(); + } + + @SafeVarargs + public static boolean contains(T[] array, T... items) { + for (T a: array) { + for (T b: items) { + if (Objects.equals(a, b)) { + return true; + } + } + } + return false; + } } diff --git a/utils/src/main/java/org/zstack/utils/DomainUtils.java b/utils/src/main/java/org/zstack/utils/DomainUtils.java new file mode 100644 index 00000000000..c68b933dfd0 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/DomainUtils.java @@ -0,0 +1,28 @@ +package org.zstack.utils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DomainUtils { + private static final String regex = "(https?://)?([^:/]+)(:\\d+)?"; + + public static String getDomain(String url) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(url); + if (matcher.find()) { + return matcher.group(2); + } + return ""; + } + + public static Boolean curl(String url) { + String command = String.format("curl -sk --head --connect-timeout 5 %s", url); + ShellResult rst = ShellUtils.runAndReturn(command, true); + return rst.getRetCode() == 0; + } + + public static Boolean ping(String domain) { + ShellResult rst = ShellUtils.runAndReturn(String.format("ping %s -c 3 -W 2", domain), true); + return rst.getRetCode() == 0; + } +} diff --git a/utils/src/main/java/org/zstack/utils/GroovyUtils.java b/utils/src/main/java/org/zstack/utils/GroovyUtils.java index 977a3e54003..3347aab3e32 100755 --- a/utils/src/main/java/org/zstack/utils/GroovyUtils.java +++ b/utils/src/main/java/org/zstack/utils/GroovyUtils.java @@ -2,6 +2,7 @@ import groovy.lang.GroovyClassLoader; +import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -58,10 +59,11 @@ public static Class getClass(String scriptPath, ClassLoader parent) { return clz; } - GroovyClassLoader loader = new GroovyClassLoader(parent); - InputStream in = parent.getResourceAsStream(scriptPath); - String script = StringDSL.inputStreamToString(in); - clz = loader.parseClass(script); + try (GroovyClassLoader loader = new GroovyClassLoader(parent)) { + InputStream in = parent.getResourceAsStream(scriptPath); + String script = StringDSL.inputStreamToString(in); + clz = loader.parseClass(script); + } catch (IOException ignore) {} groovyClasses.put(scriptPath, clz); return clz; } diff --git a/utils/src/main/java/org/zstack/utils/HTTP.java b/utils/src/main/java/org/zstack/utils/HTTP.java index cff6ddc142f..327ac3030d9 100755 --- a/utils/src/main/java/org/zstack/utils/HTTP.java +++ b/utils/src/main/java/org/zstack/utils/HTTP.java @@ -5,6 +5,7 @@ import org.zstack.utils.gson.JSONObjectUtil; import org.zstack.utils.logging.CLogger; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -130,6 +131,8 @@ public static class Builder { private boolean build; + private MultipartBody.Builder multipartBody; + public Param getParam() { return param; } @@ -196,6 +199,32 @@ public Builder logging() { return this; } + public Builder formData(Map formFields) { + if (formFields == null) { + throw new IllegalArgumentException("formFields cannot be null"); + } + + if (param.body != null) { + throw new IllegalStateException("Cannot set both body and form data"); + } + + multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM); + formFields.forEach((k, v) -> { + if (k == null || v == null) { + return; // skip null entries + } + + if (v instanceof File) { + File file = (File) v; + RequestBody fileBody = RequestBody.create(file, MediaType.parse("application/octet-stream")); + multipartBody.addFormDataPart(k, file.getName(), fileBody); + } else { + multipartBody.addFormDataPart(k, v.toString()); + } + }); + return this; + } + public Response callWithException() throws IOException { build(); @@ -254,15 +283,23 @@ private void build() { } if ("POST".equals(param.method)) { - DebugUtils.Assert(param.body != null, "POST requires body"); - rb.post(RequestBody.create(MediaType.parse(contentType), param.body)); + if (multipartBody != null) { + rb.post(multipartBody.build()); + } else { + DebugUtils.Assert(param.body != null, "POST requires body"); + rb.post(RequestBody.create(param.body, MediaType.parse(contentType))); + } } else if ("GET".equals(param.method)) { rb.get(); } else if ("DELETE".equals(param.method)) { rb.delete(); } else if ("PUT".equals(param.method)) { - DebugUtils.Assert(param.body != null, "PUT requires body"); - rb.put(RequestBody.create(MediaType.parse(contentType), param.body)); + if (multipartBody != null) { + rb.put(multipartBody.build()); + } else { + DebugUtils.Assert(param.body != null, "PUT requires body"); + rb.put(RequestBody.create(param.body, MediaType.parse(contentType))); + } } else if ("HEAD".equals(param.method)) { rb.head(); } else { diff --git a/utils/src/main/java/org/zstack/utils/HttpServletRequestUtils.java b/utils/src/main/java/org/zstack/utils/HttpServletRequestUtils.java new file mode 100644 index 00000000000..ac78c1fe2bc --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/HttpServletRequestUtils.java @@ -0,0 +1,76 @@ +package org.zstack.utils; + +import org.apache.commons.lang.StringUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.function.Predicate; + +public class HttpServletRequestUtils { + public static String getClientIP(HttpServletRequest req) { + Predicate isEmptyOrUnknown = s -> s == null || s.isEmpty() || "unknown".equalsIgnoreCase(s); + + String ipAddress = req.getHeader("X-Forwarded-For"); + if (!isEmptyOrUnknown.test(ipAddress)) { + ipAddress = ipAddress.split(",")[0].trim(); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("X-Real-IP"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("Proxy-Client-IP"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("WL-Proxy-Client-IP"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("HTTP_X_FORWARDED"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("HTTP_X_CLUSTER_CLIENT_IP"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("HTTP_CLIENT_IP"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("HTTP_FORWARDED_FOR"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getHeader("HTTP_FORWARDED"); + } + if (isEmptyOrUnknown.test(ipAddress)) { + ipAddress = req.getRemoteAddr(); + } + return ipAddress; + } + + public static String getClientBrowser(HttpServletRequest req) { + String userAgent = req.getHeader("User-Agent"); + if (StringUtils.isBlank(userAgent)) return ""; + + userAgent = userAgent.toLowerCase(); + if (userAgent.contains("chrome")) { + return "Chrome"; + } else if (userAgent.contains("firefox")) { + return "Firefox"; + } else if (userAgent.contains("edge")) { + return "Edge"; + } else if (userAgent.contains("trident") || userAgent.contains("msie")) { + return "IE"; + } else if (userAgent.contains("360")) { + return "360"; + } else if (userAgent.contains("tencenttraveler")) { + return "Tencent Traveler"; + } else if (userAgent.contains("metas")) { + return "Sogou Explorer"; + } else if (userAgent.contains("safari")) { + return "Safari"; + } else if (userAgent.contains("cli")) { + return "cli"; + }else { + return "Other"; + } + } +} diff --git a/utils/src/main/java/org/zstack/utils/IptablesUtils.java b/utils/src/main/java/org/zstack/utils/IptablesUtils.java index 6ea065d756c..fc3e8500b30 100755 --- a/utils/src/main/java/org/zstack/utils/IptablesUtils.java +++ b/utils/src/main/java/org/zstack/utils/IptablesUtils.java @@ -22,4 +22,14 @@ public static void insertRuleToFilterTable(String rule) { ret = ShellUtils.runAndReturn(String.format("/sbin/iptables %s", rule.replace("-A", "-I"))); ret.raiseExceptionIfFail(); } + + public static void deleteRuleFromFilterTable(String rule) { + ShellResult ret = ShellUtils.runAndReturn(String.format("/sbin/iptables-save | grep -- '%s' > /dev/null", rule)); + if (ret.getRetCode() != 0) { + return; + } + + ret = ShellUtils.runAndReturn(String.format("/sbin/iptables %s", rule.replace("-A", "-D"))); + ret.raiseExceptionIfFail(); + } } diff --git a/utils/src/main/java/org/zstack/utils/Linux.java b/utils/src/main/java/org/zstack/utils/Linux.java index 9e81a097803..2b705bd6d48 100755 --- a/utils/src/main/java/org/zstack/utils/Linux.java +++ b/utils/src/main/java/org/zstack/utils/Linux.java @@ -61,6 +61,7 @@ public static ShellResult shell(List cmd) { ret.setStdout(IOUtils.toString(pro.getInputStream())); return ret; } catch (Exception e) { + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } diff --git a/utils/src/main/java/org/zstack/utils/MaskSensitiveRegexReplaces.java b/utils/src/main/java/org/zstack/utils/MaskSensitiveRegexReplaces.java deleted file mode 100644 index 6d8acd73f39..00000000000 --- a/utils/src/main/java/org/zstack/utils/MaskSensitiveRegexReplaces.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.zstack.utils; - -import groovy.util.logging.Slf4j; -import org.apache.logging.log4j.core.config.plugins.Plugin; -import org.apache.logging.log4j.core.config.plugins.PluginElement; -import org.apache.logging.log4j.core.config.plugins.PluginFactory; -import org.apache.logging.log4j.core.pattern.RegexReplacement; - -@Slf4j -@Plugin(name = "replaces", category = "Core", printObject = true) -public class MaskSensitiveRegexReplaces { - - private final RegexReplacement[] replaces; - - private MaskSensitiveRegexReplaces(RegexReplacement[] replaces) { - this.replaces = replaces; - } - - - public String format(String msg) { - if (msg.contains("Pass") || msg.contains("pass")) { - for (RegexReplacement replace : replaces) { - msg = replace.format(msg); - } - } - return msg; - } - - - @PluginFactory - public static MaskSensitiveRegexReplaces createRegexReplacement( - @PluginElement("replaces") final RegexReplacement[] replaces) { - if (replaces == null) { - return null; - } - - return new MaskSensitiveRegexReplaces(replaces); - } -} diff --git a/utils/src/main/java/org/zstack/utils/Masksensitivepatternlayout.java b/utils/src/main/java/org/zstack/utils/Masksensitivepatternlayout.java deleted file mode 100644 index 9417214743f..00000000000 --- a/utils/src/main/java/org/zstack/utils/Masksensitivepatternlayout.java +++ /dev/null @@ -1,245 +0,0 @@ -package org.zstack.utils; - -import org.apache.logging.log4j.core.Layout; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.DefaultConfiguration; -import org.apache.logging.log4j.core.config.Node; -import org.apache.logging.log4j.core.config.plugins.*; -import org.apache.logging.log4j.core.layout.AbstractStringLayout; -import org.apache.logging.log4j.core.pattern.LogEventPatternConverter; -import org.apache.logging.log4j.core.pattern.PatternFormatter; -import org.apache.logging.log4j.core.pattern.PatternParser; - -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Plugin(name = "Masksensitivepatternlayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true) -public class Masksensitivepatternlayout extends AbstractStringLayout { - private static final long serialVersionUID = 1L; - - - public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; - - public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %x - %m%n"; - - public static final String SIMPLE_CONVERSION_PATTERN = "%d [%t] %p %c - %m%n"; - - public static final String KEY = "Converter"; - - private final List formatters; - - private final String conversionPattern; - - private final Configuration config; - - private final MaskSensitiveRegexReplaces replace; - - private final boolean alwaysWriteExceptions; - - private final boolean noConsoleNoAnsi; - - - private Masksensitivepatternlayout(final Configuration config, final MaskSensitiveRegexReplaces replace, final String pattern, - final Charset charset, final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi, - final String header, final String footer) { - super(charset, toBytes(header, charset), toBytes(footer, charset)); - this.replace = replace; - this.conversionPattern = pattern; - this.config = config; - this.alwaysWriteExceptions = alwaysWriteExceptions; - this.noConsoleNoAnsi = noConsoleNoAnsi; - final PatternParser parser = createPatternParser(config); - this.formatters = parser.parse(pattern == null ? DEFAULT_CONVERSION_PATTERN : pattern, - this.alwaysWriteExceptions, this.noConsoleNoAnsi); - } - - private static byte[] toBytes(final String str, final Charset charset) { - if (str != null) { - return str.getBytes(charset != null ? charset : Charset.defaultCharset()); - } - return null; - } - - private byte[] strSubstitutorReplace(final byte... b) { - if (b != null && config != null) { - return getBytes(config.getStrSubstitutor().replace(new String(b, getCharset()))); - } - return b; - } - - @Override - public byte[] getHeader() { - return strSubstitutorReplace(super.getHeader()); - } - - @Override - public byte[] getFooter() { - return strSubstitutorReplace(super.getFooter()); - } - - public String getConversionPattern() { - return conversionPattern; - } - - - @Override - public Map getContentFormat() { - final Map result = new HashMap(); - result.put("structured", "false"); - result.put("formatType", "conversion"); - result.put("format", conversionPattern); - return result; - } - - - @Override - public String toSerializable(final LogEvent event) { - final StringBuilder buf = new StringBuilder(); - for (final PatternFormatter formatter : formatters) { - formatter.format(event, buf); - } - String str = buf.toString(); - if (replace != null) { - str = replace.format(str); - } - return str; - } - - - public static PatternParser createPatternParser(final Configuration config) { - if (config == null) { - return new PatternParser(config, KEY, LogEventPatternConverter.class); - } - PatternParser parser = config.getComponent(KEY); - if (parser == null) { - parser = new PatternParser(config, KEY, LogEventPatternConverter.class); - config.addComponent(KEY, parser); - parser = (PatternParser) config.getComponent(KEY); - } - return parser; - } - - @Override - public String toString() { - return conversionPattern; - } - - - @PluginFactory - public static Masksensitivepatternlayout createLayout( - @PluginAttribute(value = "pattern", defaultString = DEFAULT_CONVERSION_PATTERN) final String pattern, - @PluginConfiguration final Configuration config, - @PluginElement("Replaces") final MaskSensitiveRegexReplaces replace, - @PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charset, - @PluginAttribute(value = "alwaysWriteExceptions", defaultBoolean = true) final boolean alwaysWriteExceptions, - @PluginAttribute(value = "noConsoleNoAnsi", defaultBoolean = false) final boolean noConsoleNoAnsi, - @PluginAttribute("header") final String header, @PluginAttribute("footer") final String footer) { - System.out.println("=============="); - return newBuilder().withPattern(pattern).withConfiguration(config).withRegexReplacement(replace) - .withCharset(charset).withAlwaysWriteExceptions(alwaysWriteExceptions) - .withNoConsoleNoAnsi(noConsoleNoAnsi).withHeader(header).withFooter(footer).build(); - } - - public static Masksensitivepatternlayout createDefaultLayout() { - System.out.println("11111111"); - return newBuilder().build(); - } - - - @PluginBuilderFactory - public static Builder newBuilder() { - return new Builder(); - } - - - public static class Builder implements org.apache.logging.log4j.core.util.Builder { - - // FIXME: it seems rather redundant to repeat default values (same goes - // for field names) - // perhaps introduce a @PluginBuilderAttribute that has no values of its - // own and uses reflection? - - @PluginBuilderAttribute - private String pattern = Masksensitivepatternlayout.DEFAULT_CONVERSION_PATTERN; - - @PluginConfiguration - private Configuration configuration = null; - - @PluginElement("Replaces") - private MaskSensitiveRegexReplaces regexReplacement = null; - - // LOG4J2-783 use platform default by default - @PluginBuilderAttribute - private Charset charset = Charset.defaultCharset(); - - @PluginBuilderAttribute - private boolean alwaysWriteExceptions = true; - - @PluginBuilderAttribute - private boolean noConsoleNoAnsi = false; - - @PluginBuilderAttribute - private String header = null; - - @PluginBuilderAttribute - private String footer = null; - - private Builder() { - } - - // TODO: move javadocs from PluginFactory to here - - public Builder withPattern(final String pattern) { - this.pattern = pattern; - return this; - } - - public Builder withConfiguration(final Configuration configuration) { - this.configuration = configuration; - return this; - } - - public Builder withRegexReplacement(final MaskSensitiveRegexReplaces regexReplacement) { - this.regexReplacement = regexReplacement; - return this; - } - - public Builder withCharset(final Charset charset) { - this.charset = charset; - return this; - } - - public Builder withAlwaysWriteExceptions(final boolean alwaysWriteExceptions) { - this.alwaysWriteExceptions = alwaysWriteExceptions; - return this; - } - - public Builder withNoConsoleNoAnsi(final boolean noConsoleNoAnsi) { - this.noConsoleNoAnsi = noConsoleNoAnsi; - return this; - } - - public Builder withHeader(final String header) { - this.header = header; - return this; - } - - public Builder withFooter(final String footer) { - this.footer = footer; - return this; - } - - @Override - public Masksensitivepatternlayout build() { - // fall back to DefaultConfiguration - if (configuration == null) { - configuration = new DefaultConfiguration(); - } - return new Masksensitivepatternlayout(configuration, regexReplacement, pattern, charset, alwaysWriteExceptions, - noConsoleNoAnsi, header, footer); - } - } -} diff --git a/utils/src/main/java/org/zstack/utils/ObjectUtils.java b/utils/src/main/java/org/zstack/utils/ObjectUtils.java index 6792741ea8b..eb51bf02ad0 100755 --- a/utils/src/main/java/org/zstack/utils/ObjectUtils.java +++ b/utils/src/main/java/org/zstack/utils/ObjectUtils.java @@ -7,6 +7,8 @@ import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; +import java.util.Optional; +import java.util.function.Function; /** */ @@ -68,4 +70,18 @@ public static T serializableCopy(T object) throws IOException, ClassNotFound byte[] temp = SerializableHelper.writeObject(object); return SerializableHelper.readObject(temp); } + + /** + *
    +     * getOrNull("123", String::length) = 3
    +     * getOrNull("", String::length) = 0
    +     * getOrNull(null, String::length) = null
    +     *
    +     * getOrNull(vm, VmInstanceVO::getUuid) = "2b0f9a804b654e4b8ca56301878a7d51"
    +     * getOrNull(null, VmInstanceVO::getUuid) = null
    +     * 
    +     */
    +    public static  T getOrNull(O object, Function mapper) {
    +        return Optional.of(object).map(mapper).orElse(null);
    +    }
     }
    diff --git a/utils/src/main/java/org/zstack/utils/RangeSet.java b/utils/src/main/java/org/zstack/utils/RangeSet.java
    index a5807cdedd9..9f2c8378cf6 100755
    --- a/utils/src/main/java/org/zstack/utils/RangeSet.java
    +++ b/utils/src/main/java/org/zstack/utils/RangeSet.java
    @@ -1,5 +1,7 @@
     package org.zstack.utils;
     
    +import org.apache.logging.log4j.util.Strings;
    +
     import java.util.*;
     import java.util.stream.Collectors;
     
    @@ -69,6 +71,23 @@ public boolean is(long s, long e) {
             public String toString() {
                 return String.format("[%s, %s]", start, end);
             }
    +
    +        @Override
    +        public boolean equals(Object obj) {
    +            if (this == obj) {
    +                return true;
    +            }
    +            if (obj == null || getClass() != obj.getClass()) {
    +                return false;
    +            }
    +            Range range = (Range) obj;
    +            return start == range.start && end == range.end;
    +        }
    +
    +        @Override
    +        public int hashCode() {
    +            return Objects.hash(start, end);
    +        }
         }
     
         private List ranges = new ArrayList();
    @@ -120,13 +139,14 @@ public List merge() {
                 }
             }
             ret.add(r);
    +        ranges = ret;
             return ret;
         }
     
         public List mergeAndSort() {
    -        List ret = merge();
    +        merge();
             sort();
    -        return ret;
    +        return ranges;
         }
     
         public void sort(){
    @@ -178,6 +198,32 @@ public static RangeSet valueOf(Collection numbers) {
             return results;
         }
     
    +    public static RangeSet valueOf(String str) {
    +        RangeSet results = new RangeSet();
    +        if (str == null || str.isEmpty()) {
    +            return results;
    +        }
    +
    +        for (String s : str.split(",")) {
    +            if (Strings.isBlank(s)) {
    +                continue;
    +            }
    +            String[] range = s.split("-");
    +            try {
    +                if (range.length == 1) {
    +                    long value = Long.parseLong(range[0].trim());
    +                    results.closed(value, value);
    +                } else if (range.length == 2) {
    +                    String start = range[0].trim();
    +                    String end = range[1].trim();
    +                    results.closed(Long.parseLong(start), Long.parseLong(end));
    +                }
    +            } catch (NumberFormatException ignore) {}
    +        }
    +
    +        return results;
    +    }
    +
         public Set values(){
             Set result = new HashSet<>();
             for (Range range : ranges) {
    diff --git a/utils/src/main/java/org/zstack/utils/SHAUtils.java b/utils/src/main/java/org/zstack/utils/SHAUtils.java
    index eeaf1b5bcfe..5b6cc0842ab 100644
    --- a/utils/src/main/java/org/zstack/utils/SHAUtils.java
    +++ b/utils/src/main/java/org/zstack/utils/SHAUtils.java
    @@ -1,7 +1,13 @@
     package org.zstack.utils;
     
    +import org.apache.commons.codec.digest.DigestUtils;
    +
    +import java.io.FileInputStream;
    +import java.io.IOException;
     import java.io.UnsupportedEncodingException;
     import java.math.BigInteger;
    +import java.nio.file.Files;
    +import java.nio.file.Paths;
     import java.security.MessageDigest;
     import java.security.NoSuchAlgorithmException;
     
    @@ -20,4 +26,13 @@ public static String encrypt(String input, String algorithm) {
                 throw new RuntimeException(e);
             }
         }
    +
    +    public static String getFileMd5sum(String filePath) {
    +        try {
    +            FileInputStream srcIn = new FileInputStream(filePath);
    +            return DigestUtils.md5Hex(srcIn);
    +        } catch (Exception e) {
    +            throw new RuntimeException(e);
    +        }
    +    }
     }
    diff --git a/utils/src/main/java/org/zstack/utils/Serialization.java b/utils/src/main/java/org/zstack/utils/Serialization.java
    deleted file mode 100755
    index a02ea90690f..00000000000
    --- a/utils/src/main/java/org/zstack/utils/Serialization.java
    +++ /dev/null
    @@ -1,57 +0,0 @@
    -package org.zstack.utils;
    -
    -import com.esotericsoftware.kryo.Kryo;
    -import com.esotericsoftware.kryo.io.Input;
    -import com.esotericsoftware.kryo.io.Output;
    -import com.esotericsoftware.kryo.serializers.FieldSerializer;
    -import com.esotericsoftware.kryo.util.Pool;
    -
    -import java.util.ArrayList;
    -import java.util.List;
    -
    -public class Serialization {
    -    private static int SIZE = 30;
    -    private static Pool kryoPool = new Pool(true, false, SIZE) {
    -        protected Kryo create() {
    -            Kryo kryo = new Kryo();
    -            kryo.setRegistrationRequired(false);
    -            kryo.setDefaultSerializer(FieldSerializer.class);
    -            return kryo;
    -        }
    -    };
    -
    -    private static void fulfillPool() {
    -        List kryos = new ArrayList<>();
    -        for (int i=0; i kryoPool.free(k));
    -    }
    -
    -    static {
    -        fulfillPool();
    -    }
    -
    -    public static byte[] serialize(Object obj) {
    -        Kryo kryo = kryoPool.obtain();
    -        try {
    -            Output output = new Output(1024, -1);
    -            kryo.writeClassAndObject(output, obj);
    -            return output.getBuffer();
    -        } finally {
    -            kryoPool.free(kryo);
    -        }
    -    }
    -
    -    public static  T deserialize(byte[] bytes) {
    -        Kryo kryo = kryoPool.obtain();
    -        try {
    -            Input input = new Input(bytes);
    -            return (T) kryo.readClassAndObject(input);
    -        } finally {
    -            kryoPool.free(kryo);
    -        }
    -    }
    -}
    diff --git a/utils/src/main/java/org/zstack/utils/ShellUtils.java b/utils/src/main/java/org/zstack/utils/ShellUtils.java
    index 3ed6583a951..84d78f3811a 100755
    --- a/utils/src/main/java/org/zstack/utils/ShellUtils.java
    +++ b/utils/src/main/java/org/zstack/utils/ShellUtils.java
    @@ -258,6 +258,7 @@ public ShellResult run() {
                     StringBuilder sb = new StringBuilder();
                     sb.append("Shell command failed:\n");
                     sb.append(command);
    +                Thread.currentThread().interrupt();
                     throw new ShellException(sb.toString(), e);
                 } finally {
                     if (process != null) {
    diff --git a/utils/src/main/java/org/zstack/utils/SizeUtils.java b/utils/src/main/java/org/zstack/utils/SizeUtils.java
    index 1e071f40b8e..c160102cd37 100755
    --- a/utils/src/main/java/org/zstack/utils/SizeUtils.java
    +++ b/utils/src/main/java/org/zstack/utils/SizeUtils.java
    @@ -1,86 +1,145 @@
     package org.zstack.utils;
     
    +import org.zstack.utils.data.NumberUtils;
     import org.zstack.utils.data.SizeUnit;
    +import org.zstack.utils.data.UnitNumber;
     
     import java.util.Arrays;
    -import java.util.List;
    +import java.util.Collection;
     
     /**
      */
     public class SizeUtils {
         private static final String T_SUFFIX = "T";
         private static final String TB_SUFFIX = "TB";
    +    private static final String TIB_SUFFIX = "TiB";
         private static final String t_SUFFIX = "t";
         private static final String G_SUFFIX = "G";
         private static final String GB_SUFFIX = "GB";
    +    private static final String GIB_SUFFIX = "GiB";
         private static final String g_SUFFIX = "g";
         private static final String M_SUFFIX = "M";
         private static final String MB_SUFFIX = "MB";
    +    private static final String MIB_SUFFIX = "MiB";
         private static final String m_SUFFIX = "m";
         private static final String K_SUFFIX = "K";
         private static final String KB_SUFFIX = "KB";
    +    private static final String KIB_SUFFIX = "KiB";
         private static final String k_SUFFIX = "k";
         private static final String B_SUFFIX = "B";
         private static final String b_SUFFIX = "b";
     
    -    private static final List validSuffix = Arrays.asList(
    -            T_SUFFIX,
    -            TB_SUFFIX,
    -            t_SUFFIX,
    -            G_SUFFIX,
    -            GB_SUFFIX,
    -            g_SUFFIX,
    -            M_SUFFIX,
    -            MB_SUFFIX,
    -            m_SUFFIX,
    -            K_SUFFIX,
    -            KB_SUFFIX,
    -            k_SUFFIX,
    -            B_SUFFIX,
    -            b_SUFFIX
    -    );
    -
    -    private static boolean isPositiveNumber(String str) {
    -        return str.matches("\\d+");
    +    public static boolean isPositive(Number i){
    +        return NumberUtils.isPositive(i);
         }
     
    +    /**
    +     * 

    Check string is a valid size string with 2 characters size units

    + *

    Valid size units list below: + * {@link #TB_SUFFIX}, {@link #GB_SUFFIX}, {@link #MB_SUFFIX}, {@link #KB_SUFFIX}, {@link #B_SUFFIX}

    + *

    Example: + *

  • 1GB -> true + *
  • 2MB -> true + *
  • 3K -> false + *
  • 4T -> false + *
  • 5 -> false + *
  • -6GB -> false + *
  • + *

    + * + * @param str a string contains integer and size units + * @return if str is a valid size string with 2 characters size units. + * @see #isSizeString(String) + */ public static boolean isSizeString2(String str) { - String suffix = str.substring(str.length() - 2); - if (!validSuffix.contains(suffix)) { + final UnitNumber numeric = NumberUtils.ofUnitNumber(str); + return numeric != null && isSize2(numeric); + } + + /** + *

    Check string is a valid size string with 1 character size units, + * or simply the positive value

    + *

    Valid size units list below: + * {@link #T_SUFFIX}, {@link #t_SUFFIX}, {@link #G_SUFFIX}, {@link #g_SUFFIX}, + * {@link #M_SUFFIX}, {@link #m_SUFFIX}, {@link #K_SUFFIX}, {@link #k_SUFFIX}, + * {@link #B_SUFFIX}, {@link #b_SUFFIX}, ""

    + *

    Example: + *

  • 1GB -> false + *
  • 2MB -> false + *
  • 3K -> true + *
  • 4T -> true + *
  • 5 -> true + *
  • -6G -> false + *
  • + *

    + * + * @param str a string contains integer and size units + * @return if str is a valid size string with 1 character size units, or simply the positive value + * @see #isSizeString2(String) + */ + public static boolean isSizeString(String str) { + final UnitNumber numeric = NumberUtils.ofUnitNumber(str); + return numeric != null && isSize(numeric); + } + + public static boolean isSize2(UnitNumber numeric) { + return isSize(numeric, Arrays.asList(TB_SUFFIX, GB_SUFFIX, MB_SUFFIX, KB_SUFFIX, B_SUFFIX)); + } + + public static boolean isSize(UnitNumber numeric) { + return isSize(numeric, Arrays.asList( + T_SUFFIX, t_SUFFIX, G_SUFFIX, g_SUFFIX, M_SUFFIX, m_SUFFIX, K_SUFFIX, k_SUFFIX, B_SUFFIX, b_SUFFIX, "")); + } + + public static boolean isSize(UnitNumber numeric, Collection matchedUnits) { + if (numeric.number < 0) { return false; } - - String num = str.substring(0, str.length() - 2); - return isPositiveNumber(num); + return matchedUnits.contains(numeric.units); } - public static boolean isSizeString(String str) { - String suffix = str.substring(str.length() - 1); - if (!validSuffix.contains(suffix)) { - return isPositiveNumber(str); - } else { - String num = str.substring(0, str.length()-1); - return isPositiveNumber(num); + public static double sizeStringToBytes2(String str) { + final UnitNumber numeric = NumberUtils.ofUnitNumberOrThrow2(str); + String suffix = numeric.units; + double size = numeric.doubleFormatNumber; + if (suffix.isEmpty()) { + return size; } + + switch (suffix) { + case T_SUFFIX: case t_SUFFIX: case TB_SUFFIX: case TIB_SUFFIX: + return SizeUnit.TERABYTE.toByte(size); + case G_SUFFIX: case g_SUFFIX: case GB_SUFFIX: case GIB_SUFFIX: + return SizeUnit.GIGABYTE.toByte(size); + case M_SUFFIX: case m_SUFFIX: case MB_SUFFIX: case MIB_SUFFIX: + return SizeUnit.MEGABYTE.toByte(size); + case K_SUFFIX: case k_SUFFIX: case KB_SUFFIX: case KIB_SUFFIX: + return SizeUnit.KILOBYTE.toByte(size); + case B_SUFFIX: case b_SUFFIX: + return SizeUnit.BYTE.toByte(size); + } + + throw new RuntimeException(String.format("should not be here, input size string: %s, parsed size: %s, parsed unit: %s", str, size, suffix)); } public static long sizeStringToBytes(String str) { - String numStr = str.substring(0, str.length() - 1); - String suffix = str.substring(str.length() - 1); - if (!validSuffix.contains(suffix)) { - return Long.parseLong(str); + final UnitNumber numeric = NumberUtils.ofUnitNumberOrThrow(str); + String suffix = numeric.units; + long size = numeric.number; + if (suffix.isEmpty()) { + return size; } - long size = Long.parseLong(numStr); - if (suffix.equals(T_SUFFIX) || suffix.equals(t_SUFFIX)) { + switch (suffix) { + case T_SUFFIX: case t_SUFFIX: case TB_SUFFIX: case TIB_SUFFIX: return SizeUnit.TERABYTE.toByte(size); - } else if (suffix.equals(G_SUFFIX) || suffix.equals(g_SUFFIX)) { + case G_SUFFIX: case g_SUFFIX: case GB_SUFFIX: case GIB_SUFFIX: return SizeUnit.GIGABYTE.toByte(size); - } else if (suffix.equals(M_SUFFIX) || suffix.equals(m_SUFFIX)) { + case M_SUFFIX: case m_SUFFIX: case MB_SUFFIX: case MIB_SUFFIX: return SizeUnit.MEGABYTE.toByte(size); - } else if (suffix.equals(K_SUFFIX) || suffix.equals(k_SUFFIX)) { + case K_SUFFIX: case k_SUFFIX: case KB_SUFFIX: case KIB_SUFFIX: return SizeUnit.KILOBYTE.toByte(size); - } else if (suffix.equals(B_SUFFIX) || suffix.equals(b_SUFFIX)) { + case B_SUFFIX: case b_SUFFIX: return SizeUnit.BYTE.toByte(size); } diff --git a/utils/src/main/java/org/zstack/utils/StringDSL.java b/utils/src/main/java/org/zstack/utils/StringDSL.java index 98c0f3d6d0a..6cd30a8122f 100755 --- a/utils/src/main/java/org/zstack/utils/StringDSL.java +++ b/utils/src/main/java/org/zstack/utils/StringDSL.java @@ -156,4 +156,17 @@ private static int hashOXR(List lst) { public static boolean stringCompareInLineOrderIndpendent(String str1, String str2) { return hashOXR(Arrays.asList(str1.split("\n"))) == hashOXR(Arrays.asList(str2.split("\n"))); } + + public static String transToTfUuid(String zUuid){ + StringBuilder buffer = new StringBuilder(zUuid); + buffer.insert(20, '-'); + buffer.insert(16, '-'); + buffer.insert(12, '-'); + buffer.insert(8, '-'); + return buffer.toString(); + } + + public static String transToZstackUuid(String tfUuid){ + return tfUuid.replaceAll("-",""); + } } diff --git a/utils/src/main/java/org/zstack/utils/StringTemplateUtils.java b/utils/src/main/java/org/zstack/utils/StringTemplateUtils.java new file mode 100644 index 00000000000..28adeac56ab --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/StringTemplateUtils.java @@ -0,0 +1,32 @@ +package org.zstack.utils; + +import groovy.text.GStringTemplateEngine; +import groovy.text.Template; + +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; + +public class StringTemplateUtils { + private static final GStringTemplateEngine engine = new GStringTemplateEngine(); + + private static final Map stringTemplateMap = new HashMap<>(); + + public static String createStringFromTemplate(String template, Map bindings) { + Template t = stringTemplateMap.get(template.hashCode()); + + if (t != null) { + return t.make(bindings).toString(); + } + + try { + t = engine.createTemplate(new StringReader(template)); + } catch (ClassNotFoundException | IOException e) { + throw new RuntimeException(e); + } + + stringTemplateMap.put(template.hashCode(), t); + return t.make(bindings).toString(); + } +} diff --git a/utils/src/main/java/org/zstack/utils/TimeUtils.java b/utils/src/main/java/org/zstack/utils/TimeUtils.java index 446315319b9..0f2ee1e7b15 100755 --- a/utils/src/main/java/org/zstack/utils/TimeUtils.java +++ b/utils/src/main/java/org/zstack/utils/TimeUtils.java @@ -1,14 +1,19 @@ package org.zstack.utils; +import org.zstack.utils.data.NumberUtils; +import org.zstack.utils.data.UnitNumber; import org.zstack.utils.logging.CLogger; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Instant; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Calendar; +import java.util.Date; import java.util.TimeZone; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; @@ -40,6 +45,7 @@ public static boolean loopExecuteUntilTimeoutIgnoreExceptionAndReturn(long perio unit.sleep(interval); } catch (Throwable t) { logger.debug(String.format("%s, after %s ms timeout", t.getMessage(), period-count)); + Thread.currentThread().interrupt(); } count += interval; } @@ -63,49 +69,26 @@ public static boolean isValidTimeFormat(String time) { } public static long parseTimeInMillis(String time) { - try { - return Long.parseLong(time); - } catch (NumberFormatException e) { - if (time.endsWith("s")) { - time = StringDSL.stripEnd(time, "s"); - return TimeUnit.SECONDS.toMillis(Long.parseLong(time)); - } else if (time.endsWith("S")) { - time = StringDSL.stripEnd(time, "S"); - return TimeUnit.SECONDS.toMillis(Long.parseLong(time)); - } else if (time.endsWith("m")) { - time = StringDSL.stripEnd(time, "m"); - return TimeUnit.MINUTES.toMillis(Long.parseLong(time)); - } else if (time.endsWith("M")) { - time = StringDSL.stripEnd(time, "M"); - return TimeUnit.MINUTES.toMillis(Long.parseLong(time)); - } else if (time.endsWith("h")) { - time = StringDSL.stripEnd(time, "h"); - return TimeUnit.HOURS.toMillis(Long.parseLong(time)); - } else if (time.endsWith("H")) { - time = StringDSL.stripEnd(time, "H"); - return TimeUnit.HOURS.toMillis(Long.parseLong(time)); - } else if (time.endsWith("d")) { - time = StringDSL.stripEnd(time, "d"); - return TimeUnit.DAYS.toMillis(Long.parseLong(time)); - } else if (time.endsWith("D")) { - time = StringDSL.stripEnd(time, "D"); - return TimeUnit.DAYS.toMillis(Long.parseLong(time)); - } else if (time.endsWith("w")) { - time = StringDSL.stripEnd(time, "w"); - return TimeUnit.DAYS.toMillis(Long.parseLong(time) * 7); - } else if (time.endsWith("W")) { - time = StringDSL.stripEnd(time, "W"); - return TimeUnit.DAYS.toMillis(Long.parseLong(time) * 7); - } else if (time.endsWith("y")) { - time = StringDSL.stripEnd(time, "y"); - return TimeUnit.DAYS.toMillis(Long.parseLong(time) * 365); - } else if (time.endsWith("Y")) { - time = StringDSL.stripEnd(time, "Y"); - return TimeUnit.DAYS.toMillis(Long.parseLong(time) * 365); - } else { - throw new NumberFormatException(); - } + UnitNumber numeric = NumberUtils.ofUnitNumberOrThrow(time); + if ("".equals(numeric.units)) { + return numeric.number; } + + switch (numeric.units) { + case "s": case "S": + return TimeUnit.SECONDS.toMillis(numeric.number); + case "m": case "M": + return TimeUnit.MINUTES.toMillis(numeric.number); + case "h": case "H": + return TimeUnit.HOURS.toMillis(numeric.number); + case "d": case "D": + return TimeUnit.DAYS.toMillis(numeric.number); + case "w": case "W": + return TimeUnit.DAYS.toMillis(numeric.number * 7); + case "y": case "Y": + return TimeUnit.DAYS.toMillis(numeric.number * 365); + } + throw new NumberFormatException("unsupported time format: " + time); } public static long parseTimeToSeconds(String time){ @@ -129,6 +112,11 @@ public static long parseTimeToMillis(String time){ } private static final String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + private static final String SHORT_TIME_FORMAT = "yyMMdd"; + + public static String getShortDateFormat() { + return new SimpleDateFormat(SHORT_TIME_FORMAT).format(Date.from(Instant.now())); + } public static boolean isValidTimestampFormat(String timestamp) { try { @@ -231,4 +219,19 @@ public static String instantToString(Instant instant) { public static String instantToString(Instant instant, String format) { return DateTimeFormatter.ofPattern(format).withZone(ZoneId.systemDefault()).format(instant); } + + /** + * @param timestamp using milliseconds from the epoch of 1970-01-01T00:00:00Z + */ + public static LocalDateTime toLocalDateTime(long timestamp) { + return toLocalDateTime(Instant.ofEpochMilli(timestamp)); + } + + public static LocalDateTime toLocalDateTime(Instant instant) { + return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); + } + + public static OffsetDateTime offsetDateTimeOf(long timestampInMilli) { + return OffsetDateTime.ofInstant(Instant.ofEpochMilli(timestampInMilli), ZoneId.systemDefault()); + } } diff --git a/utils/src/main/java/org/zstack/utils/URLBuilder.java b/utils/src/main/java/org/zstack/utils/URLBuilder.java index 4f222ccdc0d..cc2ed0ddb4c 100755 --- a/utils/src/main/java/org/zstack/utils/URLBuilder.java +++ b/utils/src/main/java/org/zstack/utils/URLBuilder.java @@ -29,6 +29,25 @@ public static String buildUrlFromBase(String baseUrl, String...paths) { return ub.build().toString(); } + /** + *

    Encodes a URI by replacing each instance of certain characters by escape sequences.

    + * + *

    Example: + *

  • input: 123 qwe + *
  • output: 123%20qwe + *
  • input: A-Za-z0-9-_.@()!~*'$&:,_+= + *
  • output: A-Za-z0-9-_.@()!~*'$&:,_+= + *
  • input: #%^{}[]"<>?/ + *
  • output: %23%25%5E%7B%7D%5B%5D%22%3C%3E%3F%2F + *
  • input: http://9.9.9.9:9999/999#99 + *
  • output: http:%2F%2F9.9.9.9:9999%2F999%2399 + *
  • + *

    + */ + public static String buildUrlComponent(String uri) { + return UriComponentsBuilder.newInstance().pathSegment(uri).toUriString().substring(1); + } + public static String hideUrlPassword(String url){ UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url); UriComponents u = builder.build(); diff --git a/utils/src/main/java/org/zstack/utils/VersionComparator.java b/utils/src/main/java/org/zstack/utils/VersionComparator.java index a1e769d8704..7dbbc62a2a9 100755 --- a/utils/src/main/java/org/zstack/utils/VersionComparator.java +++ b/utils/src/main/java/org/zstack/utils/VersionComparator.java @@ -28,6 +28,14 @@ public int compare(String ver) { return compare(c); } + public boolean lessThan(String ver) { + return compare(ver) < 0; + } + + public boolean greaterThan(String ver) { + return compare(ver) > 0; + } + public int compare(VersionComparator v) { List him = new ArrayList(); him.addAll(v.elements); diff --git a/utils/src/main/java/org/zstack/utils/VipUseForList.java b/utils/src/main/java/org/zstack/utils/VipUseForList.java index 6b259383dcd..4892680c618 100644 --- a/utils/src/main/java/org/zstack/utils/VipUseForList.java +++ b/utils/src/main/java/org/zstack/utils/VipUseForList.java @@ -72,7 +72,7 @@ public String toString() { final String delimiter = ","; if (useForList.isEmpty()){ - return null; + return ""; } else { return String.join(delimiter, useForList); diff --git a/utils/src/main/java/org/zstack/utils/YamlUtils.java b/utils/src/main/java/org/zstack/utils/YamlUtils.java new file mode 100644 index 00000000000..c955402be39 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/YamlUtils.java @@ -0,0 +1,39 @@ +package org.zstack.utils; + +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.nodes.Tag; + +/** + * @Author: qiuyu.zhang + * @Date: 2024/4/8 14:17 + */ +public class YamlUtils { + + public static String dump(Object obj) { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN); + Yaml yaml = new Yaml(options); + return yaml.dump(obj); + } + + public static String dumpAs(Object obj, Tag tag) { + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN); + Yaml yaml = new Yaml(options); + return yaml.dumpAs(obj, tag, null); + } + + public static Object load(String str) { + Yaml yaml = new Yaml(); + return yaml.load(str); + } + + public static T load(String str, Class clazz) { + Yaml yaml = new Yaml(); + return yaml.loadAs(str, clazz); + } + +} diff --git a/utils/src/main/java/org/zstack/utils/ak/AccessKeyUtils.java b/utils/src/main/java/org/zstack/utils/ak/AccessKeyUtils.java new file mode 100644 index 00000000000..7851873e666 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/ak/AccessKeyUtils.java @@ -0,0 +1,64 @@ +package org.zstack.utils.ak; + +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Base64; +import java.util.Locale; + +public class AccessKeyUtils { + + public static String generateDate() { + ZonedDateTime now = ZonedDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH); + return now.format(formatter); + } + + public static String generateAuthorization(String accessKeyId, String accessKeySecret, String method, String date, String uriString) throws Exception { + int questionMarkIndex = uriString.indexOf('?'); + String path = (questionMarkIndex != -1) ? uriString.substring(0, questionMarkIndex) : uriString; + + String stringToSign = method + "\n" + date + "\n" + path; + + SecretKeySpec signingKey = new SecretKeySpec(accessKeySecret.getBytes(StandardCharsets.UTF_8), "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(signingKey); + + byte[] rawHmac = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)); + String signature = Base64.getEncoder().encodeToString(rawHmac); + + return "ZStack " + accessKeyId + ":" + signature; + } + + public static String encryptPassword(String password, String sk) throws Exception { + String md5KeyIv = md5Hash(sk); + byte[] key = md5KeyIv.getBytes(StandardCharsets.UTF_8); + byte[] iv = md5KeyIv.substring(0, 16).getBytes(StandardCharsets.UTF_8); + + SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES"); + IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); + + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); + + byte[] encryptedBytes = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8)); + return Base64.getEncoder().encodeToString(encryptedBytes); + } + + private static String md5Hash(String text) throws Exception { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] hashBytes = md.digest(text.getBytes(StandardCharsets.UTF_8)); + + StringBuilder sb = new StringBuilder(); + for (byte b : hashBytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +} + diff --git a/utils/src/main/java/org/zstack/utils/ctl/ConfigureCommand.java b/utils/src/main/java/org/zstack/utils/ctl/ConfigureCommand.java new file mode 100644 index 00000000000..0293157d00f --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/ctl/ConfigureCommand.java @@ -0,0 +1,20 @@ +package org.zstack.utils.ctl; + +/** + * @Author: DaoDao + * @Date: 2022/8/24 + */ +public class ConfigureCommand extends CtlCommandSpec { + String ctlName= "configure"; + @Override + String getCtlName() { + return ctlName; + } + + public ConfigureCommand Configure(String arguments) { + CtlCommandParam param = new CtlCommandParam(); + param.arguments = arguments; + addOption(param); + return this; + } +} diff --git a/utils/src/main/java/org/zstack/utils/ctl/CtlCommandSpec.java b/utils/src/main/java/org/zstack/utils/ctl/CtlCommandSpec.java index b3fb35cddf1..4d17bfb6ed9 100644 --- a/utils/src/main/java/org/zstack/utils/ctl/CtlCommandSpec.java +++ b/utils/src/main/java/org/zstack/utils/ctl/CtlCommandSpec.java @@ -24,8 +24,9 @@ String build() { StringBuilder sb = new StringBuilder(); sb.append(String.format("zstack-ctl %s", getCtlName())); for (CtlCommandParam param : params) { - if (param.arguments == null) { - sb.append(String.format(" %s", param.option)); + if (param.arguments == null || param.option == null) { + String args = param.arguments != null ? param.arguments : param.option; + sb.append(String.format(" %s", args)); continue; } sb.append(String.format(" %s %s", param.option, param.arguments)); diff --git a/utils/src/main/java/org/zstack/utils/ctl/ZStackCtlHelper.java b/utils/src/main/java/org/zstack/utils/ctl/ZStackCtlHelper.java index 0968f148f57..6cc57e69ba3 100644 --- a/utils/src/main/java/org/zstack/utils/ctl/ZStackCtlHelper.java +++ b/utils/src/main/java/org/zstack/utils/ctl/ZStackCtlHelper.java @@ -47,7 +47,7 @@ public ZStackCtlResult run() { ZStackCtlResult result = new ZStackCtlResult(); ShellResult shellResult = ShellUtils.runAndReturn(sb.toString()); - if (shellResult.isReturnCode(0)) { + if (!shellResult.isReturnCode(0)) { result.setError(shellResult.getStderr()); result.setSuccess(false); return result; diff --git a/utils/src/main/java/org/zstack/utils/data/ArrayHelper.java b/utils/src/main/java/org/zstack/utils/data/ArrayHelper.java index a504040ed9a..ea1551a26f3 100755 --- a/utils/src/main/java/org/zstack/utils/data/ArrayHelper.java +++ b/utils/src/main/java/org/zstack/utils/data/ArrayHelper.java @@ -36,7 +36,7 @@ public static T[] arrayFromField(K[] c, String fieldName, Class return } return lst.toArray((T[]) Array.newInstance(returnClassType, lst.size())); } catch (Exception e) { - throw new RuntimeException(String.format("Unable to extract field[%s] from array[%s] to array of type[%s]", fieldName, c.toString(), + throw new RuntimeException(String.format("Unable to extract field[%s] from array[%s] to array of type[%s]", fieldName, Arrays.toString(c), returnClassType.getName())); } } diff --git a/utils/src/main/java/org/zstack/utils/data/NumberUtils.java b/utils/src/main/java/org/zstack/utils/data/NumberUtils.java new file mode 100644 index 00000000000..a730517182e --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/data/NumberUtils.java @@ -0,0 +1,34 @@ +package org.zstack.utils.data; + +import javax.annotation.Nullable; + +/** + * Created by Wenhao.Zhang on 23/05/18 + */ +public class NumberUtils { + public static boolean isPowerOf2(long number) { + return number > 0 && (number & (number - 1)) == 0; + } + + public static boolean isPositive(Number i){ + return i != null && i.doubleValue() > 0; + } + + public static @Nullable UnitNumber ofUnitNumber(String text) { + return UnitNumber.valueOfOrNull(text); + } + + public static UnitNumber ofUnitNumberOrThrow(String text) throws NumberFormatException { + return UnitNumber.valueOf(text); + } + + /** + * support float type size string like: 12.39 GiB + * @param text size string + * @return UnitNumber instance + * @throws NumberFormatException + */ + public static UnitNumber ofUnitNumberOrThrow2(String text) throws NumberFormatException { + return UnitNumber.valueOfWithFloatResultOrNull(text); + } +} diff --git a/utils/src/main/java/org/zstack/utils/data/SizeUnit.java b/utils/src/main/java/org/zstack/utils/data/SizeUnit.java index 981e6623c46..46030d480d5 100755 --- a/utils/src/main/java/org/zstack/utils/data/SizeUnit.java +++ b/utils/src/main/java/org/zstack/utils/data/SizeUnit.java @@ -47,27 +47,27 @@ public double toByte(double s) { @Override public double toKiloByte(double s) { - return (s / (k / b)); + return (s / ((double) k / b)); } @Override public double toMegaByte(double s) { - return (s / (m / b)); + return (s / ((double) m / b)); } @Override public double toGigaByte(double s) { - return (s / (g / b)); + return (s / ((double) g / b)); } @Override public double toTeraByte(double s) { - return (s / (t / b)); + return (s / ((double) t / b)); } @Override public double toPetaByte(double s) { - return (s / (p / b)); + return (s / ((double) p / b)); } @Override @@ -131,7 +131,7 @@ public long convert(long s, SizeUnit src) { @Override public double toByte(double s) { - return (s * (k / b)); + return (s * ((double) k / b)); } @Override @@ -141,22 +141,22 @@ public double toKiloByte(double s) { @Override public double toMegaByte(double s) { - return (s / (m / k)); + return (s / ((double) m / k)); } @Override public double toGigaByte(double s) { - return (s / (g / k)); + return (s / ((double) g / k)); } @Override public double toTeraByte(double s) { - return (s / (t / k)); + return (s / ((double) t / k)); } @Override public double toPetaByte(double s) { - return (s / (p / k)); + return (s / ((double) p / k)); } @Override @@ -220,12 +220,12 @@ public long convert(long s, SizeUnit src) { @Override public double toByte(double s) { - return (s * (m / b)); + return (s * ((double) m / b)); } @Override public double toKiloByte(double s) { - return (s * (m / k)); + return (s * ((double) m / k)); } @Override @@ -235,17 +235,17 @@ public double toMegaByte(double s) { @Override public double toGigaByte(double s) { - return (s / (g / m)); + return (s / ((double) g / m)); } @Override public double toTeraByte(double s) { - return (s / (t / m)); + return (s / ((double) t / m)); } @Override public double toPetaByte(double s) { - return (s / (p / m)); + return (s / ((double) p / m)); } @Override @@ -310,17 +310,17 @@ public long convert(long s, SizeUnit src) { @Override public double toByte(double s) { - return (s * (g / b)); + return (s * ((double) g / b)); } @Override public double toKiloByte(double s) { - return (s * (g / k)); + return (s * ((double) g / k)); } @Override public double toMegaByte(double s) { - return (s * (g / m)); + return (s * ((double) g / m)); } @Override @@ -330,7 +330,7 @@ public double toGigaByte(double s) { @Override public double toTeraByte(double s) { - return (s / (t / g)); + return (s / ((double) t / g)); } @Override @@ -394,22 +394,22 @@ public long convert(long s, SizeUnit src) { @Override public double toByte(double s) { - return (s * (t / b)); + return (s * ((double) t / b)); } @Override public double toKiloByte(double s) { - return (s * (t / k)); + return (s * ((double) t / k)); } @Override public double toMegaByte(double s) { - return (s * (t / m)); + return (s * ((double) t / m)); } @Override public double toGigaByte(double s) { - return (s * (t / g)); + return (s * ((double) t / g)); } @Override @@ -419,7 +419,7 @@ public double toTeraByte(double s) { @Override public double toPetaByte(double s) { - return (s / (p / t)); + return (s / ((double) p / t)); } @Override @@ -453,27 +453,27 @@ public long toByte(long s) { @Override public double toByte(double s) { - return (s * (p / b)); + return (s * ((double) p / b)); } @Override public double toKiloByte(double s) { - return (s * (p / k)); + return (s * ((double) p / k)); } @Override public double toMegaByte(double s) { - return (s * (p / m)); + return (s * ((double) p / m)); } @Override public double toGigaByte(double s) { - return (s * (p / g)); + return (s * ((double) p / g)); } @Override public double toTeraByte(double s) { - return (s * (p / g)); + return (s * ((double) p / g)); } @Override diff --git a/utils/src/main/java/org/zstack/utils/data/UnitNumber.java b/utils/src/main/java/org/zstack/utils/data/UnitNumber.java new file mode 100644 index 00000000000..ed528313c5a --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/data/UnitNumber.java @@ -0,0 +1,99 @@ +package org.zstack.utils.data; + +import java.util.Objects; + +/** + * An integer number with unit. example, 50GB (number=50, units="GB") + * + * Created by Wenhao.Zhang on 23/05/18 + */ +public class UnitNumber { + public final long number; + public final Double doubleFormatNumber; + public final String units; + + public UnitNumber(long number, String units) { + this.number = number; + this.doubleFormatNumber = null; + this.units = units; + } + + public UnitNumber(double doubleFormatNumber, String units) { + this.number = 0L; + this.doubleFormatNumber = doubleFormatNumber; + this.units = units; + } + + /** + * @param text example: 50G / -60TB ... + */ + public static UnitNumber valueOf(String text) throws NumberFormatException { + UnitNumber numeric = valueOfOrNull(text); + if (numeric == null) { + throw new NumberFormatException(text + "can not parsed to UnitNumeric"); + } + return numeric; + } + + public static UnitNumber valueOfWithFloatResultOrNull(String text) { + return valueOfOrNull(text, true); + } + + /** + * @param text example: 50G / -60TB ... + */ + public static UnitNumber valueOfOrNull(String text) { + return valueOfOrNull(text, false); + } + + public static UnitNumber valueOfOrNull(String text, boolean withFloat) { + if (text.isEmpty()) { + return null; + } + + char[] chars = text.toCharArray(); + int i = 0; + if (chars[0] == '-') { + i++; + } + + for (; i < chars.length; i++) { + char ch = chars[i]; + if (!Character.isDigit(ch) && ch != '.') { + break; + } + } + + if (i == 0 || chars[0] == '-' && i == 1) { + return null; + } + + if (withFloat) { + return new UnitNumber(Double.parseDouble(text.substring(0, i)), text.substring(i).trim()); + } else { + return new UnitNumber(Long.parseLong(text.substring(0, i)), text.substring(i).trim()); + } + } + + public UnitNumber setNumber(long number) { + return new UnitNumber(number, this.units); + } + + @Override + public String toString() { + return number + units; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UnitNumber numeric = (UnitNumber) o; + return number == numeric.number && Objects.equals(units, numeric.units); + } + + @Override + public int hashCode() { + return Objects.hash(number, units); + } +} diff --git a/utils/src/main/java/org/zstack/utils/form/ExcelReader.java b/utils/src/main/java/org/zstack/utils/form/ExcelReader.java index 6c322d3fd2e..6da646e8c53 100644 --- a/utils/src/main/java/org/zstack/utils/form/ExcelReader.java +++ b/utils/src/main/java/org/zstack/utils/form/ExcelReader.java @@ -1,20 +1,19 @@ package org.zstack.utils.form; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; +import org.apache.poi.poifs.storage.HeaderBlockConstants; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.util.IOUtils; +import org.apache.poi.util.LongField; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Base64; import java.util.Optional; -import org.apache.poi.poifs.storage.HeaderBlockConstants; -import org.apache.poi.util.LongField; public class ExcelReader implements FormReader { private Sheet sheet; @@ -25,8 +24,7 @@ public ExcelReader(String base64Content) { byte[] decoded = Base64.getDecoder().decode(base64Content); InputStream input = new ByteArrayInputStream(decoded); - try { - Workbook workbook = WorkbookFactory.create(input); + try (Workbook workbook = WorkbookFactory.create(input)) { if (workbook.getNumberOfSheets() == 0) { workbook.createSheet(); } diff --git a/utils/src/main/java/org/zstack/utils/form/Form.java b/utils/src/main/java/org/zstack/utils/form/Form.java index 1f7e8128d71..abe47906f46 100644 --- a/utils/src/main/java/org/zstack/utils/form/Form.java +++ b/utils/src/main/java/org/zstack/utils/form/Form.java @@ -16,7 +16,7 @@ public class Form { private Map columnListConverter = new HashMap<>(); private Map> columnConsumer = new HashMap<>(); private List headerConverter = new ArrayList<>(); - private ValidateFunction validator = null; + private List> validators = null; private String[] columns; private final int limit; @@ -66,8 +66,8 @@ public Form addHeaderConverter(Converter converter) { return this; } - public Form withValidator(ValidateFunction validator) { - this.validator = validator; + public Form withValidator(List> validators) { + this.validators = validators; return this; } @@ -182,8 +182,10 @@ private T doLoadObject(String[] record) throws Exception { } } - if (validator != null) { - validator.validate(object); + if (validators != null) { + for (ValidateFunction validator : validators) { + validator.validate(object); + } } return object; } diff --git a/utils/src/main/java/org/zstack/utils/gson/GsonUtil.java b/utils/src/main/java/org/zstack/utils/gson/GsonUtil.java index 7741acbb1bb..7c5920bcc3b 100755 --- a/utils/src/main/java/org/zstack/utils/gson/GsonUtil.java +++ b/utils/src/main/java/org/zstack/utils/gson/GsonUtil.java @@ -41,6 +41,11 @@ public GsonUtil enableNullDecoder() { _gsonBuilder.serializeNulls(); return this; } + + public GsonUtil setDateFormat(String dateFormat) { + _gsonBuilder.setDateFormat(dateFormat); + return this; + } public Gson create() { //TODO: configuration database diff --git a/utils/src/main/java/org/zstack/utils/gson/JSONObjectUtil.java b/utils/src/main/java/org/zstack/utils/gson/JSONObjectUtil.java index 29cbf4d59b8..a6451ce35e4 100755 --- a/utils/src/main/java/org/zstack/utils/gson/JSONObjectUtil.java +++ b/utils/src/main/java/org/zstack/utils/gson/JSONObjectUtil.java @@ -6,6 +6,7 @@ import java.lang.reflect.Type; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.List; import static org.zstack.utils.CollectionDSL.e; import static org.zstack.utils.CollectionDSL.map; @@ -25,7 +26,9 @@ public Integer deserialize(JsonElement jsonElement, Type type, JsonDeserializati return l.intValue(); } } - }).disableHtmlEscaping().create(); + }).setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE) + .disableHtmlEscaping() + .create(); prettyGson = new GsonBuilder().setPrettyPrinting().create(); } @@ -54,6 +57,15 @@ public static T toObject(String content, Class clazz){ return gson.fromJson(content, clazz); } + public static T toObject(JsonElement content, Class clazz) { + return gson.fromJson(content, clazz); + } + + // Only supports converting content to List, for example: new TypeToken>() {}.getType() + public static List toList(String content, Type type){ + return gson.fromJson(content, type); + } + public static String toJsonString(Object obj) { return gson.toJson(obj); } diff --git a/utils/src/main/java/org/zstack/utils/linux/ServiceUtils.java b/utils/src/main/java/org/zstack/utils/linux/ServiceUtils.java new file mode 100644 index 00000000000..a1b57849ae8 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/linux/ServiceUtils.java @@ -0,0 +1,103 @@ +package org.zstack.utils.linux; + +import org.zstack.utils.Bash; +import org.zstack.utils.logging.CLogger; +import org.zstack.utils.logging.CLoggerImpl; + +import java.util.List; + +public class ServiceUtils { + private static final CLogger logger = CLoggerImpl.getLogger(ServiceUtils.class); + + /** + * 创建并安装Linux系统服务 + * + * @param serviceName 服务名称 + * @param description 服务描述 + * @param documentation 文档URL + * @param dependencies 依赖的其他服务 + * @param execStart 执行命令 + */ + public static void installService(String serviceName, String description, + String documentation, List dependencies, + String execStart) { + try { + StringBuilder serviceContent = new StringBuilder("[Unit]\n"); + serviceContent.append("Description=").append(description).append("\n"); + + if (documentation != null && !documentation.isEmpty()) { + serviceContent.append("Documentation=").append(documentation).append("\n"); + } + + if (dependencies != null && !dependencies.isEmpty()) { + serviceContent.append("After=").append(String.join(" ", dependencies)).append("\n"); + } + + serviceContent.append("\n[Service]\n"); + serviceContent.append("Type=forking\n"); + serviceContent.append("ExecStart=").append(execStart).append("\n"); + + serviceContent.append("\n[Install]\n"); + serviceContent.append("WantedBy=multi-user.target"); + + String tmpServicePath = "/tmp/" + serviceName + ".service"; + String servicePath = "/etc/systemd/system/" + serviceName + ".service"; + + new Bash() { + @Override + protected void scripts() { + run("echo '%s' > %s; sudo cp %s %s", serviceContent, tmpServicePath, tmpServicePath, servicePath); + run("sudo systemctl enable %s; sudo systemctl daemon-reload", serviceName); + } + }.execute(); + + } catch (Exception e) { + logger.debug("Failed to install service: " + e.getMessage(), e); + } + } + + /** + * 启动服务 + */ + public static void startService(String serviceName) { + new Bash() { + @Override + protected void scripts() { + setE(); + + run("sudo systemctl start %s", serviceName); + } + }.execute(); + } + + /** + * 停止服务 + */ + public static void stopService(String serviceName) { + new Bash() { + @Override + protected void scripts() { + setE(); + + run("sudo systemctl stop %s", serviceName); + } + }.execute(); + } + + /** + * 卸载服务 + */ + public static void uninstallService(String serviceName, String scriptPath) { + new Bash() { + @Override + protected void scripts() { + setE(); + + run("sudo systemctl disable %s" , serviceName); + run("sudo rm /etc/systemd/system/%s.service", serviceName); + run("sudo rm %s" + scriptPath, scriptPath); + run("sudo systemctl daemon-reload"); + } + }.execute(); + } +} diff --git a/utils/src/main/java/org/zstack/utils/message/OperationChecker.java b/utils/src/main/java/org/zstack/utils/message/OperationChecker.java index a87c2b72cb6..c44ef2e5fa3 100755 --- a/utils/src/main/java/org/zstack/utils/message/OperationChecker.java +++ b/utils/src/main/java/org/zstack/utils/message/OperationChecker.java @@ -38,7 +38,7 @@ public boolean isOperationAllowed(String operationName, String state, boolean ex Set ops = states.get(operationName); if (exceptionIfNoOperation) { if (ops == null) { - throw new IllegalArgumentException(String.format("Unable to find allowed states for operation[%s]", operationName)); + throw new IllegalArgumentException(String.format("Unable to find allowed states for operation[%s], current state is %s", operationName, state)); } } else { if (ops == null) { @@ -49,6 +49,14 @@ public boolean isOperationAllowed(String operationName, String state, boolean ex return allowedWhenHavingState == ops.contains(state); } + public boolean isOperationForbidden(String operationName, String state) { + Set ops = states.get(operationName); + if (ops == null) { + return false; + } + return ops.contains(state); + } + public Set getStatesForOperation(String operationName) { Set ops = states.get(operationName); if (ops == null) { diff --git a/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java b/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java index 5946ab6b450..50bbe6f195b 100644 --- a/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java +++ b/utils/src/main/java/org/zstack/utils/network/IPv6NetworkUtils.java @@ -9,10 +9,19 @@ import java.math.BigInteger; import java.util.Arrays; +import java.util.List; public class IPv6NetworkUtils { private final static CLogger logger = Utils.getLogger(IPv6NetworkUtils.class); + // IPv4 地址正则表达式 + private static String ipv4Regex = "^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"; + // MAC 地址正则表达式 + private static String macRegex = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$"; + + private static String IP_VERSION_4 = "ipv4"; + private static String IP_VERSION_6 = "ipv6"; + private static boolean isConsecutiveRange(BigInteger[] allocatedIps) { BigInteger first = allocatedIps[0]; BigInteger last = allocatedIps[allocatedIps.length - 1]; @@ -54,12 +63,14 @@ private static BigInteger findFirstHoleByDichotomy(BigInteger[] allocatedIps) { if (!isConsecutiveRange(part1)) { return findFirstHoleByDichotomy(part1); + } else if (part2[0].compareTo(part1[part1.length-1].add(BigInteger.ONE)) > 0) { + return part1[part1.length-1].add(BigInteger.ONE); } else { return findFirstHoleByDichotomy(part2); } } - private static String IPv6AddressToString(BigInteger ip) { + public static String IPv6AddressToString(BigInteger ip) { return IPv6Address.fromBigInteger(ip).toString(); } @@ -253,10 +264,11 @@ public static long getIpv6RangeSize(String startIp, String endIp) { } public static boolean isIpv6RangeFull(String startIp, String endIp, long used) { - BigInteger start = IPv6Address.fromString(startIp).toBigInteger(); - BigInteger end = IPv6Address.fromString(endIp).toBigInteger(); - - return end.subtract(start).compareTo(new BigInteger(String.valueOf(used))) <= 0; + IPv6Address start = IPv6Address.fromString(startIp); + IPv6Address end = IPv6Address.fromString(endIp); + IPv6AddressRange range = IPv6AddressRange.fromFirstAndLast(start, end); + + return range.size().compareTo(new BigInteger(String.valueOf(used))) <= 0; } public static BigInteger getBigIntegerFromString(String ip) { @@ -270,7 +282,7 @@ public static String getFormalCidrOfNetworkCidr(String cidr) { private static final String[] IP6MASK = new String[] { "8000", "c000", "e000", "f000", - "f800", "fc00", "fe00", "ff800", + "f800", "fc00", "fe00", "ff00", "ff80", "ffc0", "ffe0", "fff0", "fff8", "fffc", "fffe", "ffff" }; @@ -370,6 +382,122 @@ public static String ipv6AddessToHostname(String ip) { } public static String ipv6TagValueToAddress(String tag) { + if (tag == null){ + return null; + } return tag.replace("--", "::"); } + + public static String ipv6AddressToTagValue(String address) { + if (address == null){ + return null; + } + return address.replace("::", "--"); + } + + + public static boolean isValidGlobalIpv6(String ipv6) { + if (ipv6 == null) { + return false; + } + // Link-local addresses start with fe80 + if (ipv6.toLowerCase().startsWith("fe80")) { + return false; + } + // Unique-local addresses start with fd + if (ipv6.toLowerCase().startsWith("fd")) { + return false; + } + return isValidIpv6(ipv6); + } + + public static boolean isValidIpv6(String ipv6) { + if (ipv6.split(NetworkUtils.DEFAULT_IPV6_PREFIX_SPLIT).length == 2) { + return isIpv6Address(ipv6.split(NetworkUtils.DEFAULT_IPV6_PREFIX_SPLIT)[0]); + } else { + return isIpv6Address(ipv6); + } + } + + public static boolean isValidIpv4(String ipv4) { + if (ipv4.split(NetworkUtils.DEFAULT_IPV4_PREFIX_SPLIT).length == 2) { + return ipv4.split(NetworkUtils.DEFAULT_IPV4_PREFIX_SPLIT)[0].matches(IPv6NetworkUtils.ipv4Regex) && + Integer.parseInt(ipv4.split(NetworkUtils.DEFAULT_IPV4_PREFIX_SPLIT)[1]) >= 1 && + Integer.parseInt(ipv4.split(NetworkUtils.DEFAULT_IPV4_PREFIX_SPLIT)[1]) <= 32; + } else { + return ipv4.matches(IPv6NetworkUtils.ipv4Regex); + } + } + + public static boolean isValidMac(String mac) { + return mac.matches(IPv6NetworkUtils.macRegex); + } + + /** + * Check if the IP starts with the Link-Local prefix "fe80". + * Read vm ip to usedIp need avoid it + */ + public static Boolean isLinkLocalAddress(String ipv6) { + if (ipv6 == null || ipv6.isEmpty()) { + return false; + } + return ipv6.toLowerCase().startsWith("fe80"); + } + + public static boolean isValidIpRange(String startIp, String endIp) { + if (NetworkUtils.isIpv4Address(startIp) && NetworkUtils.isIpv4Address(endIp)) { + long s = NetworkUtils.ipv4StringToLong(startIp); + long e = NetworkUtils.ipv4StringToLong(endIp); + return e >= s; + } + + if (isValidIpv6(startIp) && isValidIpv6(endIp)) { + BigInteger s = IPv6Address.fromString(startIp).toBigInteger(); + BigInteger e = IPv6Address.fromString(endIp).toBigInteger(); + return e.compareTo(s) >= 0; + } + + return false; + } + + public static int compareIpv6Address(String ip1, String ip2) { + BigInteger s = IPv6Address.fromString(ip1).toBigInteger(); + BigInteger e = IPv6Address.fromString(ip2).toBigInteger(); + + return e.compareTo(s); + } + + public static int getPrefixLengthFromNetmask(String mask) { + if (isIpv6Address(mask)) { + IPv6Address netmask = IPv6Address.fromString(mask); + return netmask.numberOfLeadingOnes(); + } + + return 0; + } + + public static String getIpVersion(String ip) { + if (isValidIpv4(ip)) { + return IP_VERSION_4; + } else if (isValidIpv6(ip)) { + return IP_VERSION_6; + } + throw new IllegalArgumentException("Invalid IP address: " + ip); + } + + public static String getIpByIpVersion(String ipVersion, List ipList) { + if (ipList == null || ipList.isEmpty()) { + throw new IllegalArgumentException("The provided IP list cannot be null or empty."); + } + for (String ip : ipList) { + if (getIpVersion(ip).equals(ipVersion)) { + return ip; + } + } + throw new IllegalArgumentException("No IP address in the list matches the provided IP version: " + ipVersion); + } + + public static boolean isFullCidr(String cidr) { + return cidr.equals("::/0"); + } } diff --git a/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java b/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java index 2f5f55bbfaf..8ebb2f754d8 100755 --- a/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java +++ b/utils/src/main/java/org/zstack/utils/network/NetworkUtils.java @@ -27,6 +27,7 @@ public class NetworkUtils { private static final Map validNetmasks = new HashMap(); + private static final Random random = new Random(); static { validNetmasks.put("255.255.255.255", 32); @@ -65,13 +66,20 @@ public class NetworkUtils { } public static boolean isHostname(String hostname) { - String PATTERN = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"; + if (hostname == null) { + return false; + } + String PATTERN = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"; Pattern pattern = Pattern.compile(PATTERN); Matcher matcher = pattern.matcher(hostname); return matcher.matches(); } public static boolean isIpv4Address(String ip) { + if (ip == null) { + return false; + } + String PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + @@ -137,6 +145,16 @@ public static long bytesToLong(byte[] bytes) { return value; } + public static byte[] ipStringToBytes(String ip){ + validateIp(ip); + try { + InetAddress inetAddress = InetAddress.getByName(ip); + return inetAddress.getAddress(); + } catch (UnknownHostException e) { + throw new IllegalArgumentException(String.format("%s is not a valid ip address", ip), e); + } + } + public static long ipv4StringToLong(String ip) { validateIp(ip); @@ -173,8 +191,8 @@ public static int ipRangeLength(String startIp, String endIp) { } private static void validateIp(String ip) { - if (!isIpv4Address(ip)) { - throw new IllegalArgumentException(String.format("%s is not a valid ipv4 address", ip)); + if (!isIpv4Address(ip) && !isIpv6Address(ip)) { + throw new IllegalArgumentException(String.format("%s is not a valid ip address", ip)); } } @@ -188,6 +206,14 @@ public static void validateIpRange(String startIp, String endIp) { } } + public static boolean isValidIpv4Range(String startIp, String endIp) { + validateIp(startIp); + validateIp(endIp); + long s = ipv4StringToLong(startIp); + long e = ipv4StringToLong(endIp); + return e >= s; + } + public static boolean isIpv4RangeOverlap(String startIp1, String endIp1, String startIp2, String endIp2) { validateIpRange(startIp1, endIp1); validateIpRange(startIp2, endIp2); @@ -252,6 +278,8 @@ private static long findFirstHoleByDichotomy(Long[] allocatedIps) { if (!isConsecutiveRange(part1)) { return findFirstHoleByDichotomy(part1); + } else if (part2[0] - part1[part1.length-1] > 1) { + return part1[part1.length-1] + 1; } else { return findFirstHoleByDichotomy(part2); } @@ -317,7 +345,6 @@ public static String randomAllocateIpv4Address(Long startIp, Long endIp, List> findConsecutiveIpRange(Collection ips) { List> ret = new ArrayList>(); if (ips.isEmpty()) { @@ -637,7 +640,7 @@ public static List getCidrsFromIpRange(String startIp, String endIp, boo maxsize--; } - double x = Math.log(end - start + 1) / Math.log(2); + double x = Math.log((double) end - start + 1) / Math.log(2); byte maxdiff = (byte) (32 - Math.floor(x)); if (maxsize < maxdiff) { maxsize = maxdiff; @@ -759,7 +762,7 @@ public static Integer getIpversion(String ip) { } } - public static Integer getPrefixLengthFromNetwork(String mask) { + public static Integer getPrefixLengthFromNetmask(String mask) { if (isIpv4Address(mask)) { return validNetmasks.get(mask); } else { @@ -768,6 +771,22 @@ public static Integer getPrefixLengthFromNetwork(String mask) { } } + public static String convertNetmask(Integer prefix) { + int value = 0xffffffff << (32 - prefix); + byte[] bytes = new byte[]{ + (byte) (value >>> 24), + (byte) (value >> 16 & 0xff), + (byte) (value >> 8 & 0xff), + (byte) (value & 0xff) + }; + try { + return InetAddress.getByAddress(bytes).getHostAddress(); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + return null; + } + public static boolean isValidMacAddress(String macAddress) { final String MAC_REGEX = "^([A-Fa-f0-9]{2}[-,:]){5}[A-Fa-f0-9]{2}$"; return macAddress != null && !macAddress.isEmpty() && (macAddress.matches(MAC_REGEX)); @@ -864,7 +883,7 @@ public static boolean isHostReachable(String address, int port, int timeout) { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(address, port), timeout); return true; - } catch (IOException ignored) { + } catch (IOException exception) { return false; } } @@ -886,5 +905,71 @@ public static boolean isInIpv6Range(String startIp, String endIp, String ip) { return startIpv6Addresses.toBigInteger().compareTo(iPv6Addresses.toBigInteger()) <= 0 && endIpv6Addresses.toBigInteger().compareTo(iPv6Addresses.toBigInteger()) >= 0; } + + public static final String NETWORK_CFG_EMPTY = "none"; + + public static final String DEFAULT_IPV4_PREFIX = "32"; + public static final String DEFAULT_IPV6_PREFIX = "128"; + public static final String DEFAULT_IPV4_PREFIX_SPLIT = "/"; + public static final String DEFAULT_IPV6_PREFIX_SPLIT = "/"; + + public static String ipv4PrefixToNetmask(String prefix) { + return ipv4PrefixToNetmask(Integer.parseInt(prefix)); + } + public static String ipv4PrefixToNetmask(Integer prefixLength) { + if (prefixLength < 1 || prefixLength > 32) { + return String.format("255.255.255.255"); + } + + int mask = 0xFFFFFFFF << (32 - prefixLength); + int netmask1 = (mask >> 24) & 0xFF; + int netmask2 = (mask >> 16) & 0xFF; + int netmask3 = (mask >> 8) & 0xFF; + int netmask4 = mask & 0xFF; + + return String.format("%d.%d.%d.%d", netmask1, netmask2, netmask3, netmask4); + } + + /** + * Checks if the provided IP address is an Automatic Private IP Address (APIPA). + * Read vm ip to usedIp need avoid it + */ + public static Boolean isAutomaticPrivateIpAddr(String ipv4) { + if (ipv4 == null || ipv4.isEmpty()) { + return false; + } + String[] parts = ipv4.split("\\."); + if (parts.length != 4) { + return false; + } + try { + return Integer.parseInt(parts[0]) == 169 && Integer.parseInt(parts[1]) == 254; + } catch (NumberFormatException e) { + return false; + } + } + + public static Boolean isValidInternalAddress(String ip) { + if (isIpv4Address(ip)) { + return isAutomaticPrivateIpAddr(ip); + } else if (IPv6NetworkUtils.isIpv6Address(ip)) { + return IPv6NetworkUtils.isLinkLocalAddress(ip); + } else { + return Boolean.FALSE; + } + } + + public static Boolean isValidVlan(Integer vlanId) { + return vlanId != null && vlanId >= 1 && vlanId <= 4094; + } + + public static Boolean isValidVni(Integer vni){ + return vni != null && vni >= 1 && vni <= 16777214; + } + + public static int compareIpv4Address(String ip1, String ip2) { + long diff = NetworkUtils.ipv4StringToLong(ip1) - NetworkUtils.ipv4StringToLong(ip2); + return diff > 0 ? 1 : diff == 0 ? 0 : -1; + } } diff --git a/utils/src/main/java/org/zstack/utils/network/NicIpAddressInfo.java b/utils/src/main/java/org/zstack/utils/network/NicIpAddressInfo.java new file mode 100644 index 00000000000..9803946ee25 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/network/NicIpAddressInfo.java @@ -0,0 +1,19 @@ +package org.zstack.utils.network; + +public class NicIpAddressInfo { + public String ipv4Address; + public String ipv4Gateway; + public String ipv4Netmask; + public String ipv6Address; + public String ipv6Gateway; + public String ipv6Prefix; + + public NicIpAddressInfo(String ipv4Address, String ipv4Gateway, String ipv4Netmask, String ipv6Address, String ipv6Gateway, String ipv6Prefix) { + this.ipv4Address = ipv4Address; + this.ipv4Gateway = ipv4Gateway; + this.ipv4Netmask = ipv4Netmask; + this.ipv6Address = ipv6Address; + this.ipv6Gateway = ipv6Gateway; + this.ipv6Prefix = ipv6Prefix; + } +} diff --git a/utils/src/main/java/org/zstack/utils/path/PathUtil.java b/utils/src/main/java/org/zstack/utils/path/PathUtil.java index cd42bf9c4cb..fcabfffd20b 100755 --- a/utils/src/main/java/org/zstack/utils/path/PathUtil.java +++ b/utils/src/main/java/org/zstack/utils/path/PathUtil.java @@ -3,10 +3,12 @@ import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.zstack.utils.Utils; import org.zstack.utils.logging.CLogger; import java.io.*; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; @@ -127,8 +129,8 @@ public static File findFileOnClassPath(String fileName) { parentFile.mkdirs(); } - if (!file.exists()) { - file.createNewFile(); + if (!file.exists() && !file.createNewFile()) { + logger.error(String.format("fail to create new File[%s]", file)); } } catch (IOException e) { logger.error(String.format("create file error: %s", e.getMessage())); @@ -144,7 +146,9 @@ public static File findFileOnClassPath(String fileName) { } catch (IOException e) { logger.error(String.format("read jar resource error: %s", e.getMessage())); - file.delete(); + if (!file.delete()) { + logger.warn(String.format("failed to delete file[%s]", file)); + } return null; } } @@ -275,12 +279,22 @@ public static void copyFolderToFolder(String srcFolder, String dstFolder) { } } + /** + * @see #setFilePosixPermissions(File, String) + */ public static void setFilePosixPermissions(String path, String perms) { + setFilePosixPermissions(new File(path), perms); + } + + /** + * @param perms permission like: "rwxr-xr-x" "rw-------" + */ + public static void setFilePosixPermissions(File file, String perms) { try { Set s = PosixFilePermissions.fromString(perms); - Files.setPosixFilePermissions(new File(path).toPath(), s); + Files.setPosixFilePermissions(file.toPath(), s); } catch (IOException ex) { - logger.warn(String.format("set %s permission to %s: %s", path, perms, ex.getMessage())); + logger.warn(String.format("set %s permission to %s: %s", file, perms, ex.getMessage())); } } @@ -301,11 +315,19 @@ public static String createTempFile(String prefix, String suffix) { } public static void writeFile(String fpath, String content) throws IOException { - writeFile(fpath, content.getBytes(StandardCharsets.UTF_8)); + writeFile(new File(fpath), content.getBytes(StandardCharsets.UTF_8)); } public static void writeFile(String fpath, byte[] data) throws IOException { - try (FileOutputStream outputStream = new FileOutputStream(new File(fpath))) { + writeFile(new File(fpath), data); + } + + public static void writeFile(File file, String content) throws IOException { + writeFile(file, content.getBytes(StandardCharsets.UTF_8)); + } + + public static void writeFile(File file, byte[] data) throws IOException { + try (FileOutputStream outputStream = new FileOutputStream(file)) { outputStream.write(data); outputStream.flush(); } @@ -400,4 +422,47 @@ public static boolean isParentPath(String childPath, String parentPath) { return false; } } -} + + public static boolean isDir(String path) { + File file = new File(path); + if (file.exists()) { + return file.isDirectory(); + } else { + return false; + } + } + + public static Long getFileInode(String filePath) { + Path path = Paths.get(filePath); + try { + return (Long) Files.getAttribute(path, "unix:ino"); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static FileTime getFileLastModifiedTime(String filePath) { + Path path = Paths.get(filePath); + try { + return Files.getLastModifiedTime(path); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static String normalizePathWithoutQuery(String path) { + try { + String normalizedPath = path.replaceFirst( + "^([a-zA-Z]+:)(?!/{2})", + "$1//"); + final String query = new URI(normalizedPath).getQuery(); + if (query != null) { + return StringUtils.removeEnd(path, '?' + query); + } + } catch (URISyntaxException ignored) { + logger.warn(String.format("unexpected path: %s", path)); + } + + return path; + } +} \ No newline at end of file diff --git a/utils/src/main/java/org/zstack/utils/ssh/Ssh.java b/utils/src/main/java/org/zstack/utils/ssh/Ssh.java index b1b69ecfa11..69de299e258 100755 --- a/utils/src/main/java/org/zstack/utils/ssh/Ssh.java +++ b/utils/src/main/java/org/zstack/utils/ssh/Ssh.java @@ -23,6 +23,8 @@ import static org.zstack.utils.CollectionDSL.map; import static org.zstack.utils.StringDSL.ln; import static org.zstack.utils.StringDSL.s; +import static org.zstack.utils.path.PathUtil.setFilePosixPermissions; +import static org.zstack.utils.path.PathUtil.writeFile; /** */ @@ -210,6 +212,10 @@ public Ssh setSuppressException(boolean suppressException) { return this; } + /** + make sure user has permissions or use sudoCommand + */ + @Deprecated public Ssh command(String...cmds) { for (String cmd : cmds) { commands.add(createCommand(cmd)); @@ -217,6 +223,13 @@ public Ssh command(String...cmds) { return this; } + public Ssh sudoCommand(String...cmds) { + for (String cmd : cmds) { + commands.add(createCommand(SshCmdHelper.wrapSudoCmd(cmd, username, password))); + } + return this; + } + private SshRunner createCommand(final String cmdWithoutPrefix) { final String cmd = language + cmdWithoutPrefix; return new SshRunner() { @@ -278,7 +291,7 @@ public String getCommand() { @Override public String getCommandWithoutPassword() { - return cmd.replaceAll("echo .*?\\s*\\|\\s*sudo -S", "echo ****** | sudo -S"); + return SshCmdHelper.removeSensitiveInfoFromCmd(cmd); } }; } @@ -398,16 +411,16 @@ private void build() throws IOException { JSch jSch = new JSch(); if (privateKey != null) { privateKeyFile = File.createTempFile("zstack", "tmp"); - FileUtils.writeStringToFile(privateKeyFile, privateKey); + writeSecretFile(privateKeyFile, privateKey); jSch.addIdentity(privateKeyFile.getAbsolutePath()); } session = jSch.getSession(username, hostname, port); session.setConfig("StrictHostKeyChecking", "no"); session.setPassword(password); - if (privateKey == null) { - session.setConfig("PreferredAuthentications", "password"); - } + session.setConfig("PreferredAuthentications", privateKey == null ? "password" : "publickey,password"); + session.setConfig("server_host_key", session.getConfig("server_host_key") + ",ssh-rsa,ssh-dss"); + session.setConfig("PubkeyAcceptedKeyTypes", session.getConfig("PubkeyAcceptedKeyTypes") + ",ssh-rsa,ssh-dss"); session.setTimeout(getTimeoutInMilli(socketTimeout)/2); session.connect(getTimeoutInMilli(timeout)); } catch (JSchException ex) { @@ -572,4 +585,10 @@ public void runErrorByException() { throw e; } } + + private static void writeSecretFile(File file, String content) throws IOException { + writeFile(file, new byte[0]); + setFilePosixPermissions(file, "rw-------"); + writeFile(file, content); + } } diff --git a/utils/src/main/java/org/zstack/utils/ssh/SshCmdHelper.java b/utils/src/main/java/org/zstack/utils/ssh/SshCmdHelper.java new file mode 100644 index 00000000000..6c2fd3d5df1 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/ssh/SshCmdHelper.java @@ -0,0 +1,21 @@ +package org.zstack.utils.ssh; + +public class SshCmdHelper { + public static String wrapSudoCmd(String cmd, String username, String password) { + if ("root".equals(username)) { + return cmd; + } else if (password == null) { + return String.format("sudo %s", cmd); + } else { + return String.format("echo %s | sudo -S %s 2>/dev/null", shellQuote(password), cmd); + } + } + + public static String removeSensitiveInfoFromCmd(String cmd) { + return cmd.replaceAll("echo .*?\\s*\\|\\s*sudo -S", "echo ****** | sudo -S"); + } + + public static String shellQuote(String s) { + return "'" + s.replace("'", "'\\''") + "'"; + } +} diff --git a/utils/src/main/java/org/zstack/utils/ssh/SshShell.java b/utils/src/main/java/org/zstack/utils/ssh/SshShell.java index cada6079421..80ea35c94ce 100755 --- a/utils/src/main/java/org/zstack/utils/ssh/SshShell.java +++ b/utils/src/main/java/org/zstack/utils/ssh/SshShell.java @@ -15,6 +15,7 @@ import static org.zstack.utils.StringDSL.ln; import static org.zstack.utils.StringDSL.s; +import static org.zstack.utils.path.PathUtil.*; /** * Created by frank on 12/5/2015. @@ -25,14 +26,14 @@ public class SshShell { private String hostname; private String username; private String password; - private String privateKeyFile; + private String privateKey; private int port = 22; private Boolean withSudo = true; private void checkParams() { DebugUtils.Assert(hostname != null && !hostname.trim().equals(""), "hostname cannot be null"); DebugUtils.Assert(username != null && !username.trim().equals(""), "username cannot be null"); - DebugUtils.Assert(password != null || privateKeyFile != null, "password and privateKeyFile must have at least one set"); + DebugUtils.Assert(password != null || privateKey != null, "password and privateKey must have at least one set"); } public SshResult runCommand(String cmd) { @@ -41,12 +42,14 @@ public SshResult runCommand(String cmd) { File tempPasswordFile = null; try { - if (privateKeyFile != null) { + if (privateKey != null) { + tempPasswordFile = File.createTempFile("zstack", "tmp"); + writeSecretFile(tempPasswordFile, privateKey); ssh = String.format("ssh -q -i %s -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no -p %s %s@%s '%s'", - privateKeyFile, port, username, hostname, cmd); + tempPasswordFile.getAbsolutePath(), port, username, hostname, cmd); } else { tempPasswordFile = File.createTempFile("zstack", "tmp"); - FileUtils.writeStringToFile(tempPasswordFile, password); + writeSecretFile(tempPasswordFile, password); ssh = String.format("sshpass -f%s ssh -q -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o StrictHostKeyChecking=no -p %s %s@%s '%s'", tempPasswordFile.getAbsolutePath(), port, username, hostname, cmd); } @@ -61,17 +64,18 @@ public SshResult runCommand(String cmd) { sret.setReturnCode(ret.getRetCode()); sret.setStderr(ret.getStderr()); sret.setStdout(ret.getStdout()); - if (sret.getReturnCode() == 255 && privateKeyFile != null) { + if (sret.getReturnCode() == 255 && privateKey != null) { sret.setSshFailure(true); - } else if (sret.getReturnCode() == 5 && privateKeyFile == null) { + } else if ((sret.getReturnCode() == 5 || sret.getReturnCode() == 255) + && privateKey == null) { sret.setSshFailure(true); } return sret; } catch (Exception e) { throw new RuntimeException(e); } finally { - if (tempPasswordFile != null) { - tempPasswordFile.delete(); + if (tempPasswordFile != null && tempPasswordFile.delete()) { + logger.warn(String.format("failed to delete file[%s]", tempPasswordFile)); } } } @@ -81,7 +85,9 @@ public SshResult runScript(String script) { String ssh; File tempPasswordFile = null; try { - if (privateKeyFile != null) { + if (privateKey != null) { + tempPasswordFile = File.createTempFile("zstack", "tmp"); + writeSecretFile(tempPasswordFile, privateKey); ssh = ln( "ssh -q -i {0} -o UserKnownHostsFile=/dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no -p {1} -T {2}@{3} << 'EOF'", "s=`mktemp`", @@ -93,10 +99,10 @@ public SshResult runScript(String script) { "rm -f $s", "exit $ret", "EOF" - ).format(privateKeyFile, port, username, hostname, script); + ).format(tempPasswordFile.getAbsolutePath(), port, username, hostname, script); } else { tempPasswordFile = File.createTempFile("zstack", "tmp"); - FileUtils.writeStringToFile(tempPasswordFile, password); + writeSecretFile(tempPasswordFile, password); ssh = ln( "sshpass -f{0} ssh -q -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o StrictHostKeyChecking=no -p {1} -T {2}@{3} << 'EOF'", "s=`mktemp`", @@ -121,17 +127,17 @@ public SshResult runScript(String script) { sret.setReturnCode(ret.getRetCode()); sret.setStderr(ret.getStderr()); sret.setStdout(ret.getStdout()); - if (sret.getReturnCode() == 255 && privateKeyFile != null) { + if (sret.getReturnCode() == 255 && privateKey != null) { sret.setSshFailure(true); - } else if (sret.getReturnCode() == 5 && privateKeyFile == null) { + } else if (sret.getReturnCode() == 5 && privateKey == null) { sret.setSshFailure(true); } return sret; } catch (Exception e) { throw new RuntimeException(e); } finally { - if (tempPasswordFile != null) { - tempPasswordFile.delete(); + if (tempPasswordFile != null && tempPasswordFile.delete()) { + logger.warn(String.format("failed to delete file[%s]", tempPasswordFile)); } } } @@ -139,7 +145,7 @@ public SshResult runScript(String script) { public SshResult runScriptWithToken(String scriptName, Map token) { String scriptPath = PathUtil.findFileOnClassPath(scriptName, true).getAbsolutePath(); if (token == null) { - token = new HashMap(); + token = new HashMap<>(); } String contents = null; try { @@ -151,6 +157,11 @@ public SshResult runScriptWithToken(String scriptName, Map token) { return runScript(script); } + private static void writeSecretFile(File file, String content) throws IOException { + writeFile(file, new byte[0]); + setFilePosixPermissions(file, "rw-------"); + writeFile(file, content); + } public String getHostname() { return hostname; @@ -176,12 +187,12 @@ public void setPassword(String password) { this.password = password; } - public String getPrivateKeyFile() { - return privateKeyFile; + public String getPrivateKey() { + return privateKey; } - public void setPrivateKeyFile(String privateKeyFile) { - this.privateKeyFile = privateKeyFile; + public void setPrivateKey(String privateKey) { + this.privateKey = privateKey; } public int getPort() { diff --git a/utils/src/main/java/org/zstack/utils/string/ErrorCodeElaboration.java b/utils/src/main/java/org/zstack/utils/string/ErrorCodeElaboration.java index 1e45ed081bd..f48df1e370c 100644 --- a/utils/src/main/java/org/zstack/utils/string/ErrorCodeElaboration.java +++ b/utils/src/main/java/org/zstack/utils/string/ErrorCodeElaboration.java @@ -1,5 +1,7 @@ package org.zstack.utils.string; +import java.util.Locale; + /** * Created by mingjian.deng on 2018/11/28. */ @@ -17,19 +19,31 @@ public class ErrorCodeElaboration { public ErrorCodeElaboration() { } - public ErrorCodeElaboration(ErrorCodeElaboration other, Object...args) { + public ErrorCodeElaboration(ErrorCodeElaboration other, Locale locale, Object...args) { if (args != null) { this.message_en = String.format(other.message_en, args); - this.message_cn = String.format(other.message_cn, args); + this.message_cn = Locale.SIMPLIFIED_CHINESE.equals(locale) ? String.format(other.message_cn, args) : null; } else { this.message_en = other.message_en; - this.message_cn = other.message_cn; + this.message_cn = Locale.SIMPLIFIED_CHINESE.equals(locale) ? other.message_cn : null; } this.distance = other.distance; this.method = other.method; this.code = other.code; } + public ErrorCodeElaboration(ErrorCodeElaboration other, Locale locale) { + category = other.category; + code = other.code; + regex = other.regex; + message_en = other.message_en; + message_cn = Locale.SIMPLIFIED_CHINESE.equals(locale) ? other.message_cn : null; + source = other.source; + distance = other.distance; + formatSrcError = other.formatSrcError; + method = other.method; + } + public ErrorCodeElaboration(ErrorCodeElaboration other) { category = other.category; code = other.code; diff --git a/utils/src/main/java/org/zstack/utils/string/GetCPURangeMethod.java b/utils/src/main/java/org/zstack/utils/string/GetCPURangeMethod.java deleted file mode 100644 index 71d9a610499..00000000000 --- a/utils/src/main/java/org/zstack/utils/string/GetCPURangeMethod.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.zstack.utils.string; - -import java.util.*; - -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -public class GetCPURangeMethod { - public static String CPU_SEPARATOR = ","; - public static String CPU_BETWEEN_SEPARATOR = "-"; - public static String CPU_EXCLUDE_SEPARATOR = "^"; - - public static List getCPURange(String CPUString) { - Set result = new HashSet<>(); - if (CPUString == null || CPUString.isEmpty()) { - return new ArrayList<>(result); - } - - String[] temp = CPUString.split(GetCPURangeMethod.CPU_SEPARATOR); - for (String s: temp) { - if (s.contains(GetCPURangeMethod.CPU_BETWEEN_SEPARATOR)) { - String[] t = s.split(GetCPURangeMethod.CPU_BETWEEN_SEPARATOR); - result.addAll(IntStream.rangeClosed(Integer.parseInt(t[0]), Integer.parseInt(t[1])).boxed().collect(Collectors.toSet())); - } else if (s.startsWith(GetCPURangeMethod.CPU_EXCLUDE_SEPARATOR)) { - result.remove(Integer.parseInt(s.substring(1))); - } else { - result.add(Integer.parseInt(s)); - } - } - return new ArrayList<>(result); - } - - public static int getMaxCPUIDInString(String CPUString) { - List res = GetCPURangeMethod.getCPURange(CPUString); - if (res.isEmpty()) { - return -1; - } else { - return res.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0); - } - } -} diff --git a/utils/src/main/java/org/zstack/utils/string/GetCpuRangeMethod.java b/utils/src/main/java/org/zstack/utils/string/GetCpuRangeMethod.java new file mode 100644 index 00000000000..3f7b984f9ec --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/string/GetCpuRangeMethod.java @@ -0,0 +1,41 @@ +package org.zstack.utils.string; + +import java.util.*; + +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class GetCpuRangeMethod { + public static String CPU_SEPARATOR = ","; + public static String CPU_BETWEEN_SEPARATOR = "-"; + public static String CPU_EXCLUDE_SEPARATOR = "^"; + + public static List getCpuRange(String CpuString) { + Set result = new HashSet<>(); + if (CpuString == null || CpuString.isEmpty()) { + return new ArrayList<>(result); + } + + String[] temp = CpuString.split(GetCpuRangeMethod.CPU_SEPARATOR); + for (String s: temp) { + if (s.contains(GetCpuRangeMethod.CPU_BETWEEN_SEPARATOR)) { + String[] t = s.split(GetCpuRangeMethod.CPU_BETWEEN_SEPARATOR); + result.addAll(IntStream.rangeClosed(Integer.parseInt(t[0]), Integer.parseInt(t[1])).boxed().collect(Collectors.toSet())); + } else if (s.startsWith(GetCpuRangeMethod.CPU_EXCLUDE_SEPARATOR)) { + result.remove(Integer.parseInt(s.substring(1))); + } else { + result.add(Integer.parseInt(s)); + } + } + return new ArrayList<>(result); + } + + public static int getMaxCpuIdInString(String CpuString) { + List res = GetCpuRangeMethod.getCpuRange(CpuString); + if (res.isEmpty()) { + return -1; + } else { + return res.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).get(0); + } + } +} diff --git a/utils/src/main/java/org/zstack/utils/string/StringSimilarity.java b/utils/src/main/java/org/zstack/utils/string/StringSimilarity.java index 21fbbeb9efc..ee5257d1640 100644 --- a/utils/src/main/java/org/zstack/utils/string/StringSimilarity.java +++ b/utils/src/main/java/org/zstack/utils/string/StringSimilarity.java @@ -13,6 +13,7 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; @@ -25,7 +26,10 @@ public class StringSimilarity { public static final String elaborateFolder = "errorElaborations"; public static File classPathFolder = PathUtil.findFolderOnClassPath(StringSimilarity.elaborateFolder); + + // used for Jaro Similarity private static final double threshold = 0.1; + private static final int mapLength = 1500; public static int maxElaborationRegex = 8192; @@ -52,6 +56,14 @@ protected boolean removeEldestEntry(Map.Entry eldest) { // initial errors from json files private static List elaborations = initialElaborations(); + /** + * check if the elaboration matches + * 1. check if the error is matched by regex + * 2. check if the error's distance is less than threshold + * + * @param err error code elaboration + * @return true if the error is matched + */ public static boolean matched(ErrorCodeElaboration err) { if (err == null) { return false; @@ -59,13 +71,17 @@ public static boolean matched(ErrorCodeElaboration err) { if (ElaborationSearchMethod.regex == err.getMethod()) { return true; } - return !(err.getDistance() > threshold); + + return err.getDistance() < threshold; } public static List getElaborations() { return new ArrayList<>(elaborations); } + /** + * reset the cached errors and missed errors + */ public static void resetCachedErrors() { synchronized(errors) { errors.clear(); @@ -75,6 +91,12 @@ public static void resetCachedErrors() { } } + /** + * add the error code elaboration to the errors cache. + * + * @param key error code fmt string + * @param err error code elaboration + */ public static void addErrors(String key, ErrorCodeElaboration err) { if (err != null) { synchronized(errors) { @@ -83,12 +105,20 @@ public static void addErrors(String key, ErrorCodeElaboration err) { } } + /** + * add the error code fmt string to the missed cache. + * + * @param key error code fmt string + */ public static void addMissed(String key) { synchronized(missed){ missed.put(key, true); } } + /** + * refresh the error code elaborations from the json files. + */ public static void refreshErrorTemplates() { elaborations = initialElaborations(); } @@ -124,6 +154,7 @@ private static void pattern(List els) { } } + @SuppressWarnings("unchecked") private static List initialElaborations() { List errorTemplates = PathUtil.scanFolderOnClassPath(elaborateFolder); List els = Collections.synchronizedList(new ArrayList<>()); @@ -137,7 +168,7 @@ private static List initialElaborations() { } File templateFile = new File(errorTemplate); try { - String content = FileUtils.readFileToString(templateFile); + String content = FileUtils.readFileToString(templateFile, Charset.defaultCharset()); if (content == null || content.isEmpty()) { continue; } @@ -146,12 +177,9 @@ private static List initialElaborations() { ArrayList.class, ErrorCodeElaboration.class )); - els.sort(new Comparator() { - @Override - public int compare(ErrorCodeElaboration o1, ErrorCodeElaboration o2) { - return Integer.parseInt(o1.getCode()) - Integer.parseInt(o2.getCode()); - } - }); + els.sort(Comparator.comparingInt( + o -> Integer.parseInt(o.getCode()) + )); } catch (IOException e) { throw new RuntimeException(String.format("read error elaboration template files failed, due to: %s", e.getMessage())); } @@ -164,6 +192,12 @@ public int compare(ErrorCodeElaboration o1, ErrorCodeElaboration o2) { return els; } + /** + * check if the regex is contained in the elaborations. + * + * @param regex regex + * @return true if the regex is contained + */ public static boolean regexContained(String regex) { for (ErrorCodeElaboration e: elaborations) { if (e.getRegex().equals(regex)) { @@ -173,6 +207,12 @@ public static boolean regexContained(String regex) { return false; } + /** + * check if the error code is contained in the elaborations. + * + * @param code error code + * @return true if the error code is contained + */ public static boolean errorCodeContained(String code) { for (ErrorCodeElaboration e: elaborations) { String errCode = e.getCategory() + "." + e.getCode(); @@ -228,11 +268,11 @@ private static double metrics(String str, String sub) { return l.distance(str, sub); } - private static final List redundantStrs = CollectionDSL.list("unhandled exception happened when calling"); + private static final List redundantErrors = CollectionDSL.list("unhandled exception happened when calling"); private static boolean isRedundant(String sub) { - for (String redundantStr: redundantStrs) { - if (sub.startsWith(redundantStr)) { + for (String redundantError: redundantErrors) { + if (sub.startsWith(redundantError)) { return true; } } @@ -244,23 +284,41 @@ private static void logSearchSpend(String sub, long start, boolean found) { sub.length() > 50 ? sub.substring(0 , 50) + "..." : sub)); } + /** + * find the most similar error code elaboration for the given error message. + * + * @param sub error message or error message fmt + * @param args arguments + * @return the most similar error code elaboration + */ public static ErrorCodeElaboration findSimilar(String sub, Object...args) { if (sub == null || sub.isEmpty() || isRedundant(sub)) { return null; } long start = System.currentTimeMillis(); - if (errors.get(sub) != null) { + ErrorCodeElaboration err = errors.get(sub); + if (err != null && verifyElaboration(err, sub, args)) { logSearchSpend(sub, start, true); - return errors.get(sub); + return err; } - if (missed.get(sub) != null) { + // note: do not use another cache to support general error + // fmt, because we think during a period only errors with + // same cause will happen + // invalid cache, generate elaboration again + if (err != null) { + errors.remove(sub); + } + + if (args != null && missed.get(String.format(sub, args)) != null) { + logSearchSpend(sub, start, false); + return null; + } else if (missed.get(sub) != null) { logSearchSpend(sub, start, false); return null; } - ErrorCodeElaboration err; try { logger.trace(String.format("start to search elaboration for: %s", String.format(sub, args))); err = findMostSimilarRegex(String.format(sub, args)); @@ -269,6 +327,7 @@ public static ErrorCodeElaboration findSimilar(String sub, Object...args) { err = findMostSimilarRegex(sub); } + // find by distance is not reliable disable it for now if (err == null) { err = findSimilarDistance(sub); } @@ -278,52 +337,58 @@ public static ErrorCodeElaboration findSimilar(String sub, Object...args) { return err; } - // better precision, worse performance - private static ErrorCodeElaboration findMostSimilarRegex(String sub) { - if (!isRegexMatchedByRetrees(sub)) { - return null; - } - ErrorCodeElaboration matchE = null; - for (ErrorCodeElaboration elaboration: elaborations) { - if (ElaborationSearchMethod.distance == elaboration.getMethod()) { - continue; - } - if (isRegexMatched(elaboration.getRegex(), sub)) { - if (matchE == null) { - matchE = elaboration; - } else if (elaboration.getRegex().length() > matchE.getRegex().length()) { - matchE = elaboration; - } + private static boolean verifyElaboration(ErrorCodeElaboration elaboration, String sub, Object...args) { + try { + if (elaboration.getMethod() == ElaborationSearchMethod.regex) { + return isRegexMatched(elaboration.getRegex(), sub) + || isRegexMatched(elaboration.getRegex(), String.format(sub, args)); + } else if (elaboration.getMethod() == ElaborationSearchMethod.distance) { + return getSimilar(elaboration.getRegex(), sub) < threshold + || getSimilar(elaboration.getRegex(), String.format(sub, args)) < threshold; } + } catch (Exception e) { + return false; } - return matchE; + return true; } - private static ErrorCodeElaboration findSimilarDistance(String sub) { - ErrorCodeElaboration result = null; - for (ErrorCodeElaboration elaboration: elaborations) { - if (ElaborationSearchMethod.regex == elaboration.getMethod()) { - continue; - } - double distance = getSimilar(elaboration.getRegex(), sub); - if (result == null) { - result = new ErrorCodeElaboration(elaboration); - result.setDistance(distance); - } else { - if (distance < result.getDistance()) { - result = new ErrorCodeElaboration(elaboration); - result.setDistance(distance); - } - } + // better precision, worse performance + private static ErrorCodeElaboration findMostSimilarRegex(String sub) { + if (!isRegexMatchedByRetrees(sub)) { + return null; } - return result; + // find the most similar regex by compare matched regex length + return elaborations.stream() + .filter(ela -> ElaborationSearchMethod.regex == ela.getMethod()) + .filter(ela -> isRegexMatched(ela.getRegex(), sub)) + .max(Comparator.comparingInt(e -> e.getRegex().length())) + .orElse(null); } - public static String formatElaboration(String message_cn, Object...args) { + private static ErrorCodeElaboration findSimilarDistance(String sub) { + return elaborations.stream() + .filter(ela -> ElaborationSearchMethod.distance == ela.getMethod()) + .map(ela -> { + ErrorCodeElaboration result = new ErrorCodeElaboration(ela); + result.setDistance(getSimilar(ela.getRegex(), sub)); + return result; + }) + .min(Comparator.comparingDouble(ErrorCodeElaboration::getDistance)) + .orElse(null); + } + + /** + * format the error code elaboration message + * + * @param message error code elaboration message + * @param args arguments + * @return formatted error code elaboration message + */ + public static String formatElaboration(String message, Object...args) { StringBuilder buffer = new StringBuilder(); - buffer.append(String.format("错误信息: %s\n", message_cn)); + buffer.append(message); buffer.deleteCharAt(buffer.lastIndexOf("\n")); return String.format(buffer.toString(), args); @@ -333,6 +398,13 @@ private static boolean isRegexMatchedByRetrees(String sub) { return new ReMatcher(retrees, sub).find(); } + /** + * check if the given string is matched by the given regex. + * + * @param regex regex + * @param sub string + * @return true if the given string is matched by the given regex + */ public static boolean isRegexMatched(String regex, String sub) { if (patterns.get(regex) == null) { return false; @@ -340,6 +412,20 @@ public static boolean isRegexMatched(String regex, String sub) { return patterns.get(regex).matcher(sub).find(); } + /** + * Jaro Similarity is the measure of similarity between two strings. + * + * The value of Jaro distance ranges from 0 to 1. where 0 means the strings are equal + * and 1 means no similarity between the two strings. + * + * We need to check the result of Jaro Similarity is greater than the threshold value. + * + * In case of a very long sub, the result is not reliable + * + * @param str regex + * @param sub string + * @return Jaro Similarity value + */ private static double getSimilar(String str, String sub) { return getSimilar(str, sub, "jaroWinkler"); } diff --git a/utils/src/main/java/org/zstack/utils/tester/ZTester.java b/utils/src/main/java/org/zstack/utils/tester/ZTester.java index 422dfbd7a92..5ac9ad7b8c9 100644 --- a/utils/src/main/java/org/zstack/utils/tester/ZTester.java +++ b/utils/src/main/java/org/zstack/utils/tester/ZTester.java @@ -17,4 +17,6 @@ public interface ZTester { String KVM_LibvirtVersion = "kvm.libvirt.version"; String KVM_QemuImageVersion = "kvm.qemu.image.version"; String KVM_CpuModelName = "kvm.cpu.model.name"; + String KVM_CpuProcessorNum = "kvm.cpu.processor.num"; + String KVM_IpmiAddress = "kvm.ipmi.address"; } diff --git a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java index 03f2d8d227b..5e9d4b9a4dc 100644 --- a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java +++ b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Helper.java @@ -42,4 +42,19 @@ public static ZSha2Info getInfo(boolean checkZSha2Status) { "ip addr show %s | grep -q '[^0-9]%s[^0-9]'", info.getNic(), info.getDbvip())).isReturnCode(0)); return info; } + + public static ZSha2StatusJsonInfo getStatusInfo() { + ShellResult result; + + result = ShellUtils.runAndReturn("/usr/local/bin/zsha2 status -json"); + if (!result.isReturnCode(0)) { + throw new RuntimeException(String.format("cannot get zsha2 status json, because %s.", result.getStderr())); + } + + return JSONObjectUtil.toObject(result.getStdout(), ZSha2StatusJsonInfo.class); + } + + public static boolean checkConnectivityOfPeerNode() { + return getStatusInfo().isPeerReachable(); + } } diff --git a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Info.java b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Info.java index 8deb1af443b..3754b77abd9 100644 --- a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Info.java +++ b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2Info.java @@ -8,7 +8,9 @@ public class ZSha2Info { private String peerip; private String dbvip; private String nic; + private int peerport; private boolean isMaster; + private String execUser; public String getNodeip() { return nodeip; @@ -49,4 +51,16 @@ public boolean isMaster() { public void setMaster(boolean master) { isMaster = master; } + + public int getPeerport() {return peerport;} + + public void setPeerport(int peerport) {this.peerport = peerport;} + + public String getExecUser() { + return execUser; + } + + public void setExecUser(String execUser) { + this.execUser = execUser; + } } diff --git a/utils/src/main/java/org/zstack/utils/zsha2/ZSha2StatusJsonInfo.java b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2StatusJsonInfo.java new file mode 100644 index 00000000000..7d03e084b70 --- /dev/null +++ b/utils/src/main/java/org/zstack/utils/zsha2/ZSha2StatusJsonInfo.java @@ -0,0 +1,89 @@ +package org.zstack.utils.zsha2; + +/** + * @author hanyu.liang + * @date 2023/11/6 17:02 + */ +public class ZSha2StatusJsonInfo { + private boolean ownsVip; + private boolean peerReachable; + private boolean gwReachable; + private boolean vipReachable; + private String dbStatus; + private String mnStatus; + private String timeToSyncDB; + private boolean slaveIoRunning; + private boolean slaveSqlRuning; + + public boolean isOwnsVip() { + return ownsVip; + } + + public void setOwnsVip(boolean ownsVip) { + this.ownsVip = ownsVip; + } + + public boolean isPeerReachable() { + return peerReachable; + } + + public void setPeerReachable(boolean peerReachable) { + this.peerReachable = peerReachable; + } + + public boolean isGwReachable() { + return gwReachable; + } + + public void setGwReachable(boolean gwReachable) { + this.gwReachable = gwReachable; + } + + public boolean isVipReachable() { + return vipReachable; + } + + public void setVipReachable(boolean vipReachable) { + this.vipReachable = vipReachable; + } + + public String getDbStatus() { + return dbStatus; + } + + public void setDbStatus(String dbStatus) { + this.dbStatus = dbStatus; + } + + public String getMnStatus() { + return mnStatus; + } + + public void setMnStatus(String mnStatus) { + this.mnStatus = mnStatus; + } + + public String getTimeToSyncDB() { + return timeToSyncDB; + } + + public void setTimeToSyncDB(String timeToSyncDB) { + this.timeToSyncDB = timeToSyncDB; + } + + public boolean isSlaveIoRunning() { + return slaveIoRunning; + } + + public void setSlaveIoRunning(boolean slaveIoRunning) { + this.slaveIoRunning = slaveIoRunning; + } + + public boolean isSlaveSqlRuning() { + return slaveSqlRuning; + } + + public void setSlaveSqlRuning(boolean slaveSqlRuning) { + this.slaveSqlRuning = slaveSqlRuning; + } +} diff --git a/utils/src/test/java/org/zstack/utils/test/TestForm.java b/utils/src/test/java/org/zstack/utils/test/TestForm.java index 080d88ae92f..1f53f263e7b 100644 --- a/utils/src/test/java/org/zstack/utils/test/TestForm.java +++ b/utils/src/test/java/org/zstack/utils/test/TestForm.java @@ -20,6 +20,7 @@ import java.nio.charset.Charset; import java.util.Arrays; import java.util.Base64; +import java.util.Collections; import java.util.List; public class TestForm { @@ -60,7 +61,7 @@ public void test() throws Exception { private void testExcel() throws Exception { List results = Form.New(TestClass.class, createExcelContent(), 100) .addColumnConverter("test", it -> Arrays.asList(it.split(",")), TestClass::setValue) - .withValidator(ParamValidator::validate) + .withValidator(Collections.singletonList(ParamValidator::validate)) .load(); assert results.size() == 4; assert results.get(0).aBoolean && results.get(1).aBoolean; @@ -72,7 +73,7 @@ private void testExcel() throws Exception { private void testCsv() throws Exception { List results = Form.New(TestClass.class, createCsvContent(), 100) .addColumnConverter("test", it -> Arrays.asList(it.split(",")), TestClass::setValue) - .withValidator(ParamValidator::validate) + .withValidator(Collections.singletonList(ParamValidator::validate)) .load(); assert results.size() == 4; assert results.get(0).aBoolean && results.get(1).aBoolean; @@ -84,7 +85,7 @@ private void testCsv() throws Exception { private void testOtherCsv() throws Exception { List results = Form.New(TestClass.class, createOtherCsv(), 100) .addColumnConverter("test", it -> Arrays.asList(it.split("\\|")), TestClass::setValue) - .withValidator(ParamValidator::validate) + .withValidator(Collections.singletonList(ParamValidator::validate)) .load(); assert results.size() == 4; assert results.get(0).aBoolean && results.get(1).aBoolean; @@ -96,14 +97,14 @@ private void testOtherCsv() throws Exception { private void testLimit() throws Exception { List results = Form.New(TestClass.class, createOtherCsv(), 4) .addColumnConverter("test", it -> Arrays.asList(it.split("\\|")), TestClass::setValue) - .withValidator(ParamValidator::validate) + .withValidator(Collections.singletonList(ParamValidator::validate)) .load(); boolean called = false; try { Form.New(TestClass.class, createOtherCsv(), 3) .addColumnConverter("test", it -> Arrays.asList(it.split("\\|")), TestClass::setValue) - .withValidator(ParamValidator::validate) + .withValidator(Collections.singletonList(ParamValidator::validate)) .load(); } catch (Exception e) { called = true; @@ -128,7 +129,7 @@ private void testParam() throws Exception { String csv = "trimValue,noTrimValue,number\n,aa,1"; boolean failure = false; try { - Form.New(TestClass2.class, encodeToBase64(csv), 100).withValidator(ParamValidator::validate).load(); + Form.New(TestClass2.class, encodeToBase64(csv), 100).withValidator(Collections.singletonList(ParamValidator::validate)).load(); } catch (Exception e) { failure = true; } @@ -137,14 +138,14 @@ private void testParam() throws Exception { csv = "trimValue,noTrimValue,number\naa,aa,4\n , , \n"; failure = false; try { - Form.New(TestClass2.class, encodeToBase64(csv), 100).withValidator(ParamValidator::validate).load(); + Form.New(TestClass2.class, encodeToBase64(csv), 100).withValidator(Collections.singletonList(ParamValidator::validate)).load(); } catch (Exception e) { failure = true; } assert failure; csv = "trimValue,noTrimValue,number\naa , aa\n,,\n"; - List results = Form.New(TestClass2.class, encodeToBase64(csv), 100).withValidator(ParamValidator::validate).load(); + List results = Form.New(TestClass2.class, encodeToBase64(csv), 100).withValidator(Collections.singletonList(ParamValidator::validate)).load(); assert results.get(0).trimValue.equals("aa"); assert results.get(0).noTrimValue.equals(" aa"); } diff --git a/utils/src/test/java/org/zstack/utils/test/TestGetCPURangeMethodCase.java b/utils/src/test/java/org/zstack/utils/test/TestGetCPURangeMethodCase.java deleted file mode 100644 index 68081bd6616..00000000000 --- a/utils/src/test/java/org/zstack/utils/test/TestGetCPURangeMethodCase.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.zstack.utils.test; - -import org.apache.commons.collections4.Get; -import org.junit.Test; -import org.zstack.utils.string.GetCPURangeMethod; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -public class TestGetCPURangeMethodCase { - String betweenCPURangeString = "0-5"; - String eachCPURangeString = "6,8,9,11"; - String allString = "0-9,^7,11"; - String errorString = "1,^1"; - Integer maxCPUID = 11; - static List betweenCPURange = IntStream.rangeClosed(0, 5).boxed().sorted().collect(Collectors.toList()); - static List eachCPURange =Stream.of(6,8,9,11).sorted().collect(Collectors.toList()); - static List all = Stream.of(0,1,2,3,4,5,6,8,9,11).sorted().collect(Collectors.toList()); - - @Test - public void testBetweenCPURange() { - List result = GetCPURangeMethod.getCPURange(betweenCPURangeString); - result = result.stream().sorted().collect(Collectors.toList()); - assert betweenCPURange.size() == result.size(); - assert betweenCPURange.toString().equals(result.toString()); - } - - @Test - public void testEachCPURange() { - List result = GetCPURangeMethod.getCPURange(eachCPURangeString); - result = result.stream().sorted().collect(Collectors.toList()); - assert eachCPURange.size() == result.size(); - assert eachCPURange.toString().equals(result.toString()); - } - - @Test - public void testGetCPURange() { - List result = GetCPURangeMethod.getCPURange(allString); - result = result.stream().sorted().collect(Collectors.toList()); - - assert all.size() == result.size(); - assert all.toString().equals(result.toString()); - } - - @Test - public void testGetMaxCPUID() { - int maxID = GetCPURangeMethod.getMaxCPUIDInString(eachCPURangeString); - assert maxID == maxCPUID; - - maxID = GetCPURangeMethod.getMaxCPUIDInString(allString); - assert maxID == maxCPUID; - - - maxID = GetCPURangeMethod.getMaxCPUIDInString(betweenCPURangeString); - assert maxID == 5; - - } - - @Test - public void testGetErrorCPURange() { - List result = GetCPURangeMethod.getCPURange(errorString); - assert result.isEmpty(); - - int maxID = GetCPURangeMethod.getMaxCPUIDInString(errorString); - assert maxID == -1; - } -} diff --git a/utils/src/test/java/org/zstack/utils/test/TestGetCpuRangeMethodCase.java b/utils/src/test/java/org/zstack/utils/test/TestGetCpuRangeMethodCase.java new file mode 100644 index 00000000000..6051a303aad --- /dev/null +++ b/utils/src/test/java/org/zstack/utils/test/TestGetCpuRangeMethodCase.java @@ -0,0 +1,68 @@ +package org.zstack.utils.test; + +import org.junit.Test; +import org.zstack.utils.string.GetCpuRangeMethod; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public class TestGetCpuRangeMethodCase { + String betweenCPURangeString = "0-5"; + String eachCPURangeString = "6,8,9,11"; + String allString = "0-9,^7,11"; + String errorString = "1,^1"; + Integer maxCPUID = 11; + static List betweenCPURange = IntStream.rangeClosed(0, 5).boxed().sorted().collect(Collectors.toList()); + static List eachCPURange =Stream.of(6,8,9,11).sorted().collect(Collectors.toList()); + static List all = Stream.of(0,1,2,3,4,5,6,8,9,11).sorted().collect(Collectors.toList()); + + @Test + public void testBetweenCPURange() { + List result = GetCpuRangeMethod.getCpuRange(betweenCPURangeString); + result = result.stream().sorted().collect(Collectors.toList()); + assert betweenCPURange.size() == result.size(); + assert betweenCPURange.toString().equals(result.toString()); + } + + @Test + public void testEachCPURange() { + List result = GetCpuRangeMethod.getCpuRange(eachCPURangeString); + result = result.stream().sorted().collect(Collectors.toList()); + assert eachCPURange.size() == result.size(); + assert eachCPURange.toString().equals(result.toString()); + } + + @Test + public void testGetCPURange() { + List result = GetCpuRangeMethod.getCpuRange(allString); + result = result.stream().sorted().collect(Collectors.toList()); + + assert all.size() == result.size(); + assert all.toString().equals(result.toString()); + } + + @Test + public void testGetMaxCPUID() { + int maxID = GetCpuRangeMethod.getMaxCpuIdInString(eachCPURangeString); + assert maxID == maxCPUID; + + maxID = GetCpuRangeMethod.getMaxCpuIdInString(allString); + assert maxID == maxCPUID; + + + maxID = GetCpuRangeMethod.getMaxCpuIdInString(betweenCPURangeString); + assert maxID == 5; + + } + + @Test + public void testGetErrorCPURange() { + List result = GetCpuRangeMethod.getCpuRange(errorString); + assert result.isEmpty(); + + int maxID = GetCpuRangeMethod.getMaxCpuIdInString(errorString); + assert maxID == -1; + } +}